diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl new file mode 100644 index 0000000000000000000000000000000000000000..19a1210c2530681762b6d77b46901fa3374b54ec --- /dev/null +++ b/Documentation/DocBook/80211.tmpl @@ -0,0 +1,495 @@ + + + + + The 802.11 subsystems – for kernel developers + + Explaining wireless 802.11 networking in the Linux kernel + + + + 2007-2009 + Johannes Berg + + + + + Johannes + Berg + +
johannes@sipsolutions.net
+
+
+
+ + + + This documentation is free software; you can redistribute + it and/or modify it under the terms of the GNU General Public + License version 2 as published by the Free Software Foundation. + + + This documentation is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + + You should have received a copy of the GNU General Public + License along with this documentation; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + For more details see the file COPYING in the source + distribution of Linux. + + + + + + These books attempt to give a description of the + various subsystems that play a role in 802.11 wireless + networking in Linux. Since these books are for kernel + developers they attempts to document the structures + and functions used in the kernel as well as giving a + higher-level overview. + + + The reader is expected to be familiar with the 802.11 + standard as published by the IEEE in 802.11-2007 (or + possibly later versions). References to this standard + will be given as "802.11-2007 8.1.5". + + +
+ + + The cfg80211 subsystem + + +!Pinclude/net/cfg80211.h Introduction + + + + Device registration +!Pinclude/net/cfg80211.h Device registration +!Finclude/net/cfg80211.h ieee80211_band +!Finclude/net/cfg80211.h ieee80211_channel_flags +!Finclude/net/cfg80211.h ieee80211_channel +!Finclude/net/cfg80211.h ieee80211_rate_flags +!Finclude/net/cfg80211.h ieee80211_rate +!Finclude/net/cfg80211.h ieee80211_sta_ht_cap +!Finclude/net/cfg80211.h ieee80211_supported_band +!Finclude/net/cfg80211.h cfg80211_signal_type +!Finclude/net/cfg80211.h wiphy_params_flags +!Finclude/net/cfg80211.h wiphy_flags +!Finclude/net/cfg80211.h wiphy +!Finclude/net/cfg80211.h wireless_dev +!Finclude/net/cfg80211.h wiphy_new +!Finclude/net/cfg80211.h wiphy_register +!Finclude/net/cfg80211.h wiphy_unregister +!Finclude/net/cfg80211.h wiphy_free + +!Finclude/net/cfg80211.h wiphy_name +!Finclude/net/cfg80211.h wiphy_dev +!Finclude/net/cfg80211.h wiphy_priv +!Finclude/net/cfg80211.h priv_to_wiphy +!Finclude/net/cfg80211.h set_wiphy_dev +!Finclude/net/cfg80211.h wdev_priv + + + Actions and configuration +!Pinclude/net/cfg80211.h Actions and configuration +!Finclude/net/cfg80211.h cfg80211_ops +!Finclude/net/cfg80211.h vif_params +!Finclude/net/cfg80211.h key_params +!Finclude/net/cfg80211.h survey_info_flags +!Finclude/net/cfg80211.h survey_info +!Finclude/net/cfg80211.h beacon_parameters +!Finclude/net/cfg80211.h plink_actions +!Finclude/net/cfg80211.h station_parameters +!Finclude/net/cfg80211.h station_info_flags +!Finclude/net/cfg80211.h rate_info_flags +!Finclude/net/cfg80211.h rate_info +!Finclude/net/cfg80211.h station_info +!Finclude/net/cfg80211.h monitor_flags +!Finclude/net/cfg80211.h mpath_info_flags +!Finclude/net/cfg80211.h mpath_info +!Finclude/net/cfg80211.h bss_parameters +!Finclude/net/cfg80211.h ieee80211_txq_params +!Finclude/net/cfg80211.h cfg80211_crypto_settings +!Finclude/net/cfg80211.h cfg80211_auth_request +!Finclude/net/cfg80211.h cfg80211_assoc_request +!Finclude/net/cfg80211.h cfg80211_deauth_request +!Finclude/net/cfg80211.h cfg80211_disassoc_request +!Finclude/net/cfg80211.h cfg80211_ibss_params +!Finclude/net/cfg80211.h cfg80211_connect_params +!Finclude/net/cfg80211.h cfg80211_pmksa +!Finclude/net/cfg80211.h cfg80211_send_rx_auth +!Finclude/net/cfg80211.h cfg80211_send_auth_timeout +!Finclude/net/cfg80211.h __cfg80211_auth_canceled +!Finclude/net/cfg80211.h cfg80211_send_rx_assoc +!Finclude/net/cfg80211.h cfg80211_send_assoc_timeout +!Finclude/net/cfg80211.h cfg80211_send_deauth +!Finclude/net/cfg80211.h __cfg80211_send_deauth +!Finclude/net/cfg80211.h cfg80211_send_disassoc +!Finclude/net/cfg80211.h __cfg80211_send_disassoc +!Finclude/net/cfg80211.h cfg80211_ibss_joined +!Finclude/net/cfg80211.h cfg80211_connect_result +!Finclude/net/cfg80211.h cfg80211_roamed +!Finclude/net/cfg80211.h cfg80211_disconnected +!Finclude/net/cfg80211.h cfg80211_ready_on_channel +!Finclude/net/cfg80211.h cfg80211_remain_on_channel_expired +!Finclude/net/cfg80211.h cfg80211_new_sta +!Finclude/net/cfg80211.h cfg80211_rx_mgmt +!Finclude/net/cfg80211.h cfg80211_mgmt_tx_status +!Finclude/net/cfg80211.h cfg80211_cqm_rssi_notify +!Finclude/net/cfg80211.h cfg80211_michael_mic_failure + + + Scanning and BSS list handling +!Pinclude/net/cfg80211.h Scanning and BSS list handling +!Finclude/net/cfg80211.h cfg80211_ssid +!Finclude/net/cfg80211.h cfg80211_scan_request +!Finclude/net/cfg80211.h cfg80211_scan_done +!Finclude/net/cfg80211.h cfg80211_bss +!Finclude/net/cfg80211.h cfg80211_inform_bss_frame +!Finclude/net/cfg80211.h cfg80211_inform_bss +!Finclude/net/cfg80211.h cfg80211_unlink_bss +!Finclude/net/cfg80211.h cfg80211_find_ie +!Finclude/net/cfg80211.h ieee80211_bss_get_ie + + + Utility functions +!Pinclude/net/cfg80211.h Utility functions +!Finclude/net/cfg80211.h ieee80211_channel_to_frequency +!Finclude/net/cfg80211.h ieee80211_frequency_to_channel +!Finclude/net/cfg80211.h ieee80211_get_channel +!Finclude/net/cfg80211.h ieee80211_get_response_rate +!Finclude/net/cfg80211.h ieee80211_hdrlen +!Finclude/net/cfg80211.h ieee80211_get_hdrlen_from_skb +!Finclude/net/cfg80211.h ieee80211_radiotap_iterator + + + Data path helpers +!Pinclude/net/cfg80211.h Data path helpers +!Finclude/net/cfg80211.h ieee80211_data_to_8023 +!Finclude/net/cfg80211.h ieee80211_data_from_8023 +!Finclude/net/cfg80211.h ieee80211_amsdu_to_8023s +!Finclude/net/cfg80211.h cfg80211_classify8021d + + + Regulatory enforcement infrastructure +!Pinclude/net/cfg80211.h Regulatory enforcement infrastructure +!Finclude/net/cfg80211.h regulatory_hint +!Finclude/net/cfg80211.h wiphy_apply_custom_regulatory +!Finclude/net/cfg80211.h freq_reg_info + + + RFkill integration +!Pinclude/net/cfg80211.h RFkill integration +!Finclude/net/cfg80211.h wiphy_rfkill_set_hw_state +!Finclude/net/cfg80211.h wiphy_rfkill_start_polling +!Finclude/net/cfg80211.h wiphy_rfkill_stop_polling + + + Test mode +!Pinclude/net/cfg80211.h Test mode +!Finclude/net/cfg80211.h cfg80211_testmode_alloc_reply_skb +!Finclude/net/cfg80211.h cfg80211_testmode_reply +!Finclude/net/cfg80211.h cfg80211_testmode_alloc_event_skb +!Finclude/net/cfg80211.h cfg80211_testmode_event + + + + + The mac80211 subsystem + +!Pinclude/net/mac80211.h Introduction +!Pinclude/net/mac80211.h Warning + + + + + + + + + The basic mac80211 driver interface + + + You should read and understand the information contained + within this part of the book while implementing a driver. + In some chapters, advanced usage is noted, that may be + skipped at first. + + + This part of the book only covers station and monitor mode + functionality, additional information required to implement + the other modes is covered in the second part of the book. + + + + + Basic hardware handling + TBD + + This chapter shall contain information on getting a hw + struct allocated and registered with mac80211. + + + Since it is required to allocate rates/modes before registering + a hw struct, this chapter shall also contain information on setting + up the rate/mode structs. + + + Additionally, some discussion about the callbacks and + the general programming model should be in here, including + the definition of ieee80211_ops which will be referred to + a lot. + + + Finally, a discussion of hardware capabilities should be done + with references to other parts of the book. + + +!Finclude/net/mac80211.h ieee80211_hw +!Finclude/net/mac80211.h ieee80211_hw_flags +!Finclude/net/mac80211.h SET_IEEE80211_DEV +!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR +!Finclude/net/mac80211.h ieee80211_ops +!Finclude/net/mac80211.h ieee80211_alloc_hw +!Finclude/net/mac80211.h ieee80211_register_hw +!Finclude/net/mac80211.h ieee80211_get_tx_led_name +!Finclude/net/mac80211.h ieee80211_get_rx_led_name +!Finclude/net/mac80211.h ieee80211_get_assoc_led_name +!Finclude/net/mac80211.h ieee80211_get_radio_led_name +!Finclude/net/mac80211.h ieee80211_unregister_hw +!Finclude/net/mac80211.h ieee80211_free_hw + + + + PHY configuration + TBD + + This chapter should describe PHY handling including + start/stop callbacks and the various structures used. + +!Finclude/net/mac80211.h ieee80211_conf +!Finclude/net/mac80211.h ieee80211_conf_flags + + + + Virtual interfaces + TBD + + This chapter should describe virtual interface basics + that are relevant to the driver (VLANs, MGMT etc are not.) + It should explain the use of the add_iface/remove_iface + callbacks as well as the interface configuration callbacks. + + Things related to AP mode should be discussed there. + + Things related to supporting multiple interfaces should be + in the appropriate chapter, a BIG FAT note should be here about + this though and the recommendation to allow only a single + interface in STA mode at first! + +!Finclude/net/mac80211.h ieee80211_vif + + + + Receive and transmit processing + + what should be here + TBD + + This should describe the receive and transmit + paths in mac80211/the drivers as well as + transmit status handling. + + + + Frame format +!Pinclude/net/mac80211.h Frame format + + + Packet alignment +!Pnet/mac80211/rx.c Packet alignment + + + Calling into mac80211 from interrupts +!Pinclude/net/mac80211.h Calling mac80211 from interrupts + + + functions/definitions +!Finclude/net/mac80211.h ieee80211_rx_status +!Finclude/net/mac80211.h mac80211_rx_flags +!Finclude/net/mac80211.h ieee80211_tx_info +!Finclude/net/mac80211.h ieee80211_rx +!Finclude/net/mac80211.h ieee80211_rx_irqsafe +!Finclude/net/mac80211.h ieee80211_tx_status +!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe +!Finclude/net/mac80211.h ieee80211_rts_get +!Finclude/net/mac80211.h ieee80211_rts_duration +!Finclude/net/mac80211.h ieee80211_ctstoself_get +!Finclude/net/mac80211.h ieee80211_ctstoself_duration +!Finclude/net/mac80211.h ieee80211_generic_frame_duration +!Finclude/net/mac80211.h ieee80211_wake_queue +!Finclude/net/mac80211.h ieee80211_stop_queue +!Finclude/net/mac80211.h ieee80211_wake_queues +!Finclude/net/mac80211.h ieee80211_stop_queues + + + + + Frame filtering +!Pinclude/net/mac80211.h Frame filtering +!Finclude/net/mac80211.h ieee80211_filter_flags + + + + + Advanced driver interface + + + Information contained within this part of the book is + of interest only for advanced interaction of mac80211 + with drivers to exploit more hardware capabilities and + improve performance. + + + + + Hardware crypto acceleration +!Pinclude/net/mac80211.h Hardware crypto acceleration + +!Finclude/net/mac80211.h set_key_cmd +!Finclude/net/mac80211.h ieee80211_key_conf +!Finclude/net/mac80211.h ieee80211_key_flags + + + + Powersave support +!Pinclude/net/mac80211.h Powersave support + + + + Beacon filter support +!Pinclude/net/mac80211.h Beacon filter support +!Finclude/net/mac80211.h ieee80211_beacon_loss + + + + Multiple queues and QoS support + TBD +!Finclude/net/mac80211.h ieee80211_tx_queue_params + + + + Access point mode support + TBD + Some parts of the if_conf should be discussed here instead + + Insert notes about VLAN interfaces with hw crypto here or + in the hw crypto chapter. + +!Finclude/net/mac80211.h ieee80211_get_buffered_bc +!Finclude/net/mac80211.h ieee80211_beacon_get + + + + Supporting multiple virtual interfaces + TBD + + Note: WDS with identical MAC address should almost always be OK + + + Insert notes about having multiple virtual interfaces with + different MAC addresses here, note which configurations are + supported by mac80211, add notes about supporting hw crypto + with it. + + + + + Hardware scan offload + TBD +!Finclude/net/mac80211.h ieee80211_scan_completed + + + + + Rate control interface + + TBD + + This part of the book describes the rate control algorithm + interface and how it relates to mac80211 and drivers. + + + + dummy chapter + TBD + + + + + Internals + + TBD + + This part of the book describes mac80211 internals. + + + + + Key handling + + Key handling basics +!Pnet/mac80211/key.c Key handling basics + + + MORE TBD + TBD + + + + + Receive processing + TBD + + + + Transmit processing + TBD + + + + Station info handling + + Programming information +!Fnet/mac80211/sta_info.h sta_info +!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags + + + STA information lifetime rules +!Pnet/mac80211/sta_info.c STA information lifetime rules + + + + + Synchronisation + TBD + Locking, lots of RCU + + + +
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 34929f24c2846010bded3b426f20cdb54d4abc57..8b6e00a71034cbd7151ace7adbe3558f3cbb99bd 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -12,7 +12,7 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ - mac80211.xml debugobjects.xml sh.xml regulator.xml \ + 80211.xml debugobjects.xml sh.xml regulator.xml \ alsa-driver-api.xml writing-an-alsa-driver.xml \ tracepoint.xml media.xml drm.xml diff --git a/Documentation/DocBook/mac80211.tmpl b/Documentation/DocBook/mac80211.tmpl deleted file mode 100644 index affb15a344a16b5b99fb8830e9736ca166466812..0000000000000000000000000000000000000000 --- a/Documentation/DocBook/mac80211.tmpl +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - The mac80211 subsystem for kernel developers - - - - Johannes - Berg - -
johannes@sipsolutions.net
-
-
-
- - - 2007-2009 - Johannes Berg - - - - - This documentation is free software; you can redistribute - it and/or modify it under the terms of the GNU General Public - License version 2 as published by the Free Software Foundation. - - - - This documentation is distributed in the hope that it will be - useful, but WITHOUT ANY WARRANTY; without even the implied - warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more details. - - - - You should have received a copy of the GNU General Public - License along with this documentation; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, - MA 02111-1307 USA - - - - For more details see the file COPYING in the source - distribution of Linux. - - - - -!Pinclude/net/mac80211.h Introduction -!Pinclude/net/mac80211.h Warning - -
- - - - - - - The basic mac80211 driver interface - - - You should read and understand the information contained - within this part of the book while implementing a driver. - In some chapters, advanced usage is noted, that may be - skipped at first. - - - This part of the book only covers station and monitor mode - functionality, additional information required to implement - the other modes is covered in the second part of the book. - - - - - Basic hardware handling - TBD - - This chapter shall contain information on getting a hw - struct allocated and registered with mac80211. - - - Since it is required to allocate rates/modes before registering - a hw struct, this chapter shall also contain information on setting - up the rate/mode structs. - - - Additionally, some discussion about the callbacks and - the general programming model should be in here, including - the definition of ieee80211_ops which will be referred to - a lot. - - - Finally, a discussion of hardware capabilities should be done - with references to other parts of the book. - - -!Finclude/net/mac80211.h ieee80211_hw -!Finclude/net/mac80211.h ieee80211_hw_flags -!Finclude/net/mac80211.h SET_IEEE80211_DEV -!Finclude/net/mac80211.h SET_IEEE80211_PERM_ADDR -!Finclude/net/mac80211.h ieee80211_ops -!Finclude/net/mac80211.h ieee80211_alloc_hw -!Finclude/net/mac80211.h ieee80211_register_hw -!Finclude/net/mac80211.h ieee80211_get_tx_led_name -!Finclude/net/mac80211.h ieee80211_get_rx_led_name -!Finclude/net/mac80211.h ieee80211_get_assoc_led_name -!Finclude/net/mac80211.h ieee80211_get_radio_led_name -!Finclude/net/mac80211.h ieee80211_unregister_hw -!Finclude/net/mac80211.h ieee80211_free_hw - - - - PHY configuration - TBD - - This chapter should describe PHY handling including - start/stop callbacks and the various structures used. - -!Finclude/net/mac80211.h ieee80211_conf -!Finclude/net/mac80211.h ieee80211_conf_flags - - - - Virtual interfaces - TBD - - This chapter should describe virtual interface basics - that are relevant to the driver (VLANs, MGMT etc are not.) - It should explain the use of the add_iface/remove_iface - callbacks as well as the interface configuration callbacks. - - Things related to AP mode should be discussed there. - - Things related to supporting multiple interfaces should be - in the appropriate chapter, a BIG FAT note should be here about - this though and the recommendation to allow only a single - interface in STA mode at first! - -!Finclude/net/mac80211.h ieee80211_vif - - - - Receive and transmit processing - - what should be here - TBD - - This should describe the receive and transmit - paths in mac80211/the drivers as well as - transmit status handling. - - - - Frame format -!Pinclude/net/mac80211.h Frame format - - - Packet alignment -!Pnet/mac80211/rx.c Packet alignment - - - Calling into mac80211 from interrupts -!Pinclude/net/mac80211.h Calling mac80211 from interrupts - - - functions/definitions -!Finclude/net/mac80211.h ieee80211_rx_status -!Finclude/net/mac80211.h mac80211_rx_flags -!Finclude/net/mac80211.h ieee80211_tx_info -!Finclude/net/mac80211.h ieee80211_rx -!Finclude/net/mac80211.h ieee80211_rx_irqsafe -!Finclude/net/mac80211.h ieee80211_tx_status -!Finclude/net/mac80211.h ieee80211_tx_status_irqsafe -!Finclude/net/mac80211.h ieee80211_rts_get -!Finclude/net/mac80211.h ieee80211_rts_duration -!Finclude/net/mac80211.h ieee80211_ctstoself_get -!Finclude/net/mac80211.h ieee80211_ctstoself_duration -!Finclude/net/mac80211.h ieee80211_generic_frame_duration -!Finclude/net/mac80211.h ieee80211_wake_queue -!Finclude/net/mac80211.h ieee80211_stop_queue -!Finclude/net/mac80211.h ieee80211_wake_queues -!Finclude/net/mac80211.h ieee80211_stop_queues - - - - - Frame filtering -!Pinclude/net/mac80211.h Frame filtering -!Finclude/net/mac80211.h ieee80211_filter_flags - - - - - Advanced driver interface - - - Information contained within this part of the book is - of interest only for advanced interaction of mac80211 - with drivers to exploit more hardware capabilities and - improve performance. - - - - - Hardware crypto acceleration -!Pinclude/net/mac80211.h Hardware crypto acceleration - -!Finclude/net/mac80211.h set_key_cmd -!Finclude/net/mac80211.h ieee80211_key_conf -!Finclude/net/mac80211.h ieee80211_key_alg -!Finclude/net/mac80211.h ieee80211_key_flags - - - - Powersave support -!Pinclude/net/mac80211.h Powersave support - - - - Beacon filter support -!Pinclude/net/mac80211.h Beacon filter support -!Finclude/net/mac80211.h ieee80211_beacon_loss - - - - Multiple queues and QoS support - TBD -!Finclude/net/mac80211.h ieee80211_tx_queue_params - - - - Access point mode support - TBD - Some parts of the if_conf should be discussed here instead - - Insert notes about VLAN interfaces with hw crypto here or - in the hw crypto chapter. - -!Finclude/net/mac80211.h ieee80211_get_buffered_bc -!Finclude/net/mac80211.h ieee80211_beacon_get - - - - Supporting multiple virtual interfaces - TBD - - Note: WDS with identical MAC address should almost always be OK - - - Insert notes about having multiple virtual interfaces with - different MAC addresses here, note which configurations are - supported by mac80211, add notes about supporting hw crypto - with it. - - - - - Hardware scan offload - TBD -!Finclude/net/mac80211.h ieee80211_scan_completed - - - - - Rate control interface - - TBD - - This part of the book describes the rate control algorithm - interface and how it relates to mac80211 and drivers. - - - - dummy chapter - TBD - - - - - Internals - - TBD - - This part of the book describes mac80211 internals. - - - - - Key handling - - Key handling basics -!Pnet/mac80211/key.c Key handling basics - - - MORE TBD - TBD - - - - - Receive processing - TBD - - - - Transmit processing - TBD - - - - Station info handling - - Programming information -!Fnet/mac80211/sta_info.h sta_info -!Fnet/mac80211/sta_info.h ieee80211_sta_info_flags - - - STA information lifetime rules -!Pnet/mac80211/sta_info.c STA information lifetime rules - - - - - Synchronisation - TBD - Locking, lots of RCU - - -
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 5e2bc4ab897a1df72aa03849809747afa68ec142..9961f1564d22d8d546ec80ca592705573a40233e 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -536,3 +536,12 @@ Who: FUJITA Tomonori ---------------------------- +What: iwlwifi disable_hw_scan module parameters +When: 2.6.40 +Why: Hareware scan is the prefer method for iwlwifi devices for + scanning operation. Remove software scan support for all the + iwlwifi devices. + +Who: Wey-Yi Guy + +---------------------------- diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index d2b62b71b61753f0ffb272d7394d2532b160090e..5dc638791d975116bf1a1e590fdfc44a6ae5c33c 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt @@ -765,6 +765,14 @@ xmit_hash_policy does not exist, and the layer2 policy is the only policy. The layer2+3 value was added for bonding version 3.2.2. +resend_igmp + + Specifies the number of IGMP membership reports to be issued after + a failover event. One membership report is issued immediately after + the failover, subsequent packets are sent in each 200ms interval. + + The valid range is 0 - 255; the default value is 1. This option + was added for bonding version 3.7.0. 3. Configuring Bonding Devices ============================== diff --git a/Documentation/networking/can.txt b/Documentation/networking/can.txt index cd79735013f94728c15359f292f5fad4b1d0f838..5b04b67ddca2c3f2318cdd11c434a7cf9db981f3 100644 --- a/Documentation/networking/can.txt +++ b/Documentation/networking/can.txt @@ -22,6 +22,7 @@ This file contains 4.1.2 RAW socket option CAN_RAW_ERR_FILTER 4.1.3 RAW socket option CAN_RAW_LOOPBACK 4.1.4 RAW socket option CAN_RAW_RECV_OWN_MSGS + 4.1.5 RAW socket returned message flags 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) 4.3 connected transport protocols (SOCK_SEQPACKET) 4.4 unconnected transport protocols (SOCK_DGRAM) @@ -471,6 +472,17 @@ solution for a couple of reasons: setsockopt(s, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, &recv_own_msgs, sizeof(recv_own_msgs)); + 4.1.5 RAW socket returned message flags + + When using recvmsg() call, the msg->msg_flags may contain following flags: + + MSG_DONTROUTE: set when the received frame was created on the local host. + + MSG_CONFIRM: set when the frame was sent via the socket it is received on. + This flag can be interpreted as a 'transmission confirmation' when the + CAN driver supports the echo of frames on driver level, see 3.2 and 6.2. + In order to receive such messages, CAN_RAW_RECV_OWN_MSGS must be set. + 4.2 Broadcast Manager protocol sockets (SOCK_DGRAM) 4.3 connected transport protocols (SOCK_SEQPACKET) 4.4 unconnected transport protocols (SOCK_DGRAM) diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt index a62fdf7a6bffa2cfe2212a4b64d71b4dd9903531..271d524a4c8d53dc4fab4aa91fee28ea89fe4f62 100644 --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -1,18 +1,20 @@ DCCP protocol -============ +============= Contents ======== - - Introduction - Missing features - Socket options +- Sysctl variables +- IOCTLs +- Other tunables - Notes + Introduction ============ - Datagram Congestion Control Protocol (DCCP) is an unreliable, connection oriented protocol designed to solve issues present in UDP and TCP, particularly for real-time and multimedia (streaming) traffic. @@ -29,9 +31,9 @@ It has a base protocol and pluggable congestion control IDs (CCIDs). DCCP is a Proposed Standard (RFC 2026), and the homepage for DCCP as a protocol is at http://www.ietf.org/html.charters/dccp-charter.html + Missing features ================ - The Linux DCCP implementation does not currently support all the features that are specified in RFCs 4340...42. @@ -45,7 +47,6 @@ http://linux-net.osdl.org/index.php/DCCP_Testing#Experimental_DCCP_source_tree Socket options ============== - DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of service codes (RFC 4340, sec. 8.1.2); if this socket option is not set, the socket will fall back to 0 (which means that no meaningful service code @@ -112,6 +113,7 @@ DCCP_SOCKOPT_CCID_TX_INFO On unidirectional connections it is useful to close the unused half-connection via shutdown (SHUT_WR or SHUT_RD): this will reduce per-packet processing costs. + Sysctl variables ================ Several DCCP default parameters can be managed by the following sysctls @@ -155,15 +157,30 @@ sync_ratelimit = 125 ms sequence-invalid packets on the same socket (RFC 4340, 7.5.4). The unit of this parameter is milliseconds; a value of 0 disables rate-limiting. + IOCTLS ====== FIONREAD Works as in udp(7): returns in the `int' argument pointer the size of the next pending datagram in bytes, or 0 when no datagram is pending. + +Other tunables +============== +Per-route rto_min support + CCID-2 supports the RTAX_RTO_MIN per-route setting for the minimum value + of the RTO timer. This setting can be modified via the 'rto_min' option + of iproute2; for example: + > ip route change 10.0.0.0/24 rto_min 250j dev wlan0 + > ip route add 10.0.0.254/32 rto_min 800j dev wlan0 + > ip route show dev wlan0 + CCID-3 also supports the rto_min setting: it is used to define the lower + bound for the expiry of the nofeedback timer. This can be useful on LANs + with very low RTTs (e.g., loopback, Gbit ethernet). + + Notes ===== - DCCP does not travel through NAT successfully at present on many boxes. This is because the checksum covers the pseudo-header as per TCP and UDP. Linux NAT support for DCCP has been added. diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index f350c69b2bb4f807340416ffe7cf29cc8b02e662..c7165f4cb7927a152ec547caeecb393f5ad3c27e 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -1014,6 +1014,12 @@ conf/interface/*: accept_ra - BOOLEAN Accept Router Advertisements; autoconfigure using them. + Possible values are: + 0 Do not accept Router Advertisements. + 1 Accept Router Advertisements if forwarding is disabled. + 2 Overrule forwarding behaviour. Accept Router Advertisements + even if forwarding is enabled. + Functional default: enabled if local forwarding is disabled. disabled if local forwarding is enabled. @@ -1075,7 +1081,12 @@ forwarding - BOOLEAN Note: It is recommended to have the same setting on all interfaces; mixed router/host scenarios are rather uncommon. - FALSE: + Possible values are: + 0 Forwarding disabled + 1 Forwarding enabled + 2 Forwarding enabled (Hybrid Mode) + + FALSE (0): By default, Host behaviour is assumed. This means: @@ -1085,18 +1096,24 @@ forwarding - BOOLEAN Advertisements (and do autoconfiguration). 4. If accept_redirects is TRUE (default), accept Redirects. - TRUE: + TRUE (1): If local forwarding is enabled, Router behaviour is assumed. This means exactly the reverse from the above: 1. IsRouter flag is set in Neighbour Advertisements. 2. Router Solicitations are not sent. - 3. Router Advertisements are ignored. + 3. Router Advertisements are ignored unless accept_ra is 2. 4. Redirects are ignored. - Default: FALSE if global forwarding is disabled (default), - otherwise TRUE. + TRUE (2): + + Hybrid mode. Same behaviour as TRUE, except for: + + 2. Router Solicitations are being sent when necessary. + + Default: 0 (disabled) if global forwarding is disabled (default), + otherwise 1 (enabled). hop_limit - INTEGER Default Hop Limit to set. diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt index 6e8ce09f9c734e95f74d90c1ae11c5664b6d1ee4..24ad2adba6e5fe0d067d7882ce275048e56bd655 100644 --- a/Documentation/networking/phonet.txt +++ b/Documentation/networking/phonet.txt @@ -112,6 +112,22 @@ However, connect() and getpeername() are not supported, as they did not seem useful with Phonet usages (could be added easily). +Resource subscription +--------------------- + +A Phonet datagram socket can be subscribed to any number of 8-bits +Phonet resources, as follow: + + uint32_t res = 0xXX; + ioctl(fd, SIOCPNADDRESOURCE, &res); + +Subscription is similarly cancelled using the SIOCPNDELRESOURCE I/O +control request, or when the socket is closed. + +Note that no more than one socket can be subcribed to any given +resource at a time. If not, ioctl() will return EBUSY. + + Phonet Pipe protocol -------------------- @@ -166,6 +182,46 @@ The pipe protocol provides two socket options at the SOL_PNPIPE level: or zero if encapsulation is off. +Phonet Pipe-controller Implementation +------------------------------------- + +Phonet Pipe-controller is enabled by selecting the CONFIG_PHONET_PIPECTRLR Kconfig +option. It is useful when communicating with those Nokia Modems which do not +implement Pipe controller in them e.g. Nokia Slim Modem used in ST-Ericsson +U8500 platform. + +The implementation is based on the Data Connection Establishment Sequence +depicted in 'Nokia Wireless Modem API - Wireless_modem_user_guide.pdf' +document. + +It allows a phonet sequenced socket (host-pep) to initiate a Pipe connection +between itself and a remote pipe-end point (e.g. modem). + +The implementation adds socket options at SOL_PNPIPE level: + + PNPIPE_PIPE_HANDLE + It accepts an integer argument for setting value of pipe handle. + + PNPIPE_ENABLE accepts one integer value (int). If set to zero, the pipe + is disabled. If the value is non-zero, the pipe is enabled. If the pipe + is not (yet) connected, ENOTCONN is error is returned. + +The implementation also adds socket 'connect'. On calling the 'connect', pipe +will be created between the source socket and the destination, and the pipe +state will be set to PIPE_DISABLED. + +After a pipe has been created and enabled successfully, the Pipe data can be +exchanged between the host-pep and remote-pep (modem). + +User-space would typically follow below sequence with Pipe controller:- +-socket +-bind +-setsockopt for PNPIPE_PIPE_HANDLE +-connect +-setsockopt for PNPIPE_ENCAP_IP +-setsockopt for PNPIPE_ENABLE + + Authors ------- diff --git a/Documentation/networking/timestamping.txt b/Documentation/networking/timestamping.txt index e8c8f4f06c67f104523ae9c4f9bafbf659d5e139..98097d8cb910ba9d42f25e7860bec06e61a89faa 100644 --- a/Documentation/networking/timestamping.txt +++ b/Documentation/networking/timestamping.txt @@ -172,15 +172,19 @@ struct skb_shared_hwtstamps { }; Time stamps for outgoing packets are to be generated as follows: -- In hard_start_xmit(), check if skb_tx(skb)->hardware is set no-zero. - If yes, then the driver is expected to do hardware time stamping. +- In hard_start_xmit(), check if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) + is set no-zero. If yes, then the driver is expected to do hardware time + stamping. - If this is possible for the skb and requested, then declare - that the driver is doing the time stamping by setting the field - skb_tx(skb)->in_progress non-zero. You might want to keep a pointer - to the associated skb for the next step and not free the skb. A driver - not supporting hardware time stamping doesn't do that. A driver must - never touch sk_buff::tstamp! It is used to store software generated - time stamps by the network subsystem. + that the driver is doing the time stamping by setting the flag + SKBTX_IN_PROGRESS in skb_shinfo(skb)->tx_flags , e.g. with + + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; + + You might want to keep a pointer to the associated skb for the next step + and not free the skb. A driver not supporting hardware time stamping doesn't + do that. A driver must never touch sk_buff::tstamp! It is used to store + software generated time stamps by the network subsystem. - As soon as the driver has sent the packet and/or obtained a hardware time stamp for it, it passes the time stamp back by calling skb_hwtstamp_tx() with the original skb, the raw @@ -191,6 +195,6 @@ Time stamps for outgoing packets are to be generated as follows: this would occur at a later time in the processing pipeline than other software time stamping and therefore could lead to unexpected deltas between time stamps. -- If the driver did not call set skb_tx(skb)->in_progress, then +- If the driver did not set the SKBTX_IN_PROGRESS flag (see above), then dev_hard_start_xmit() checks whether software time stamping is wanted as fallback and potentially generates the time stamp. diff --git a/MAINTAINERS b/MAINTAINERS index 9a0432de91417ed7729f0cc5729c467954cc4e45..494e1a07366a86b8aaf649536fcadb9018e10e62 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1151,6 +1151,13 @@ W: http://wireless.kernel.org/en/users/Drivers/ar9170 S: Maintained F: drivers/net/wireless/ath/ar9170/ +CARL9170 LINUX COMMUNITY WIRELESS DRIVER +M: Christian Lamparter +L: linux-wireless@vger.kernel.org +W: http://wireless.kernel.org/en/users/Drivers/carl9170 +S: Maintained +F: drivers/net/wireless/ath/carl9170/ + ATK0110 HWMON DRIVER M: Luca Tettamanti L: lm-sensors@lm-sensors.org @@ -1375,16 +1382,19 @@ F: drivers/mtd/devices/block2mtd.c BLUETOOTH DRIVERS M: Marcel Holtmann +M: Gustavo F. Padovan L: linux-bluetooth@vger.kernel.org W: http://www.bluez.org/ +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git S: Maintained F: drivers/bluetooth/ BLUETOOTH SUBSYSTEM M: Marcel Holtmann +M: Gustavo F. Padovan L: linux-bluetooth@vger.kernel.org W: http://www.bluez.org/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluetooth-2.6.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git S: Maintained F: net/bluetooth/ F: include/net/bluetooth/ @@ -1429,6 +1439,13 @@ L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/bfa/ +BROCADE BNA 10 GIGABIT ETHERNET DRIVER +M: Rasesh Mody +M: Debashis Dutt +L: netdev@vger.kernel.org +S: Supported +F: drivers/net/bna/ + BSG (block layer generic sg v4 driver) M: FUJITA Tomonori L: linux-scsi@vger.kernel.org @@ -1586,9 +1603,9 @@ S: Supported F: scripts/checkpatch.pl CISCO VIC ETHERNET NIC DRIVER -M: Scott Feldman M: Vasanthy Kolluri M: Roopa Prabhu +M: David Wang S: Supported F: drivers/net/enic/ @@ -2922,6 +2939,12 @@ M: Brian King S: Supported F: drivers/scsi/ipr.* +IBM Power Virtual Ethernet Device Driver +M: Santiago Leon +L: netdev@vger.kernel.org +S: Supported +F: drivers/net/ibmveth.* + IBM ServeRAID RAID DRIVER P: Jack Hammer M: Dave Jeffery @@ -4392,13 +4415,12 @@ F: Documentation/filesystems/dlmfs.txt F: fs/ocfs2/ ORINOCO DRIVER -M: Pavel Roskin -M: David Gibson L: linux-wireless@vger.kernel.org L: orinoco-users@lists.sourceforge.net L: orinoco-devel@lists.sourceforge.net +W: http://linuxwireless.org/en/users/Drivers/orinoco W: http://www.nongnu.org/orinoco/ -S: Maintained +S: Orphan F: drivers/net/wireless/orinoco/ OSD LIBRARY and FILESYSTEM @@ -4586,6 +4608,14 @@ L: linux-abi-devel@lists.sourceforge.net S: Maintained F: include/linux/personality.h +PHONET PROTOCOL +M: Remi Denis-Courmont +S: Supported +F: Documentation/networking/phonet.txt +F: include/linux/phonet.h +F: include/net/phonet/ +F: net/phonet/ + PHRAM MTD DRIVER M: Joern Engel L: linux-mtd@lists.infradead.org @@ -6489,21 +6519,21 @@ S: Maintained F: drivers/input/misc/wistron_btns.c WL1251 WIRELESS DRIVER -M: Kalle Valo +M: Kalle Valo L: linux-wireless@vger.kernel.org W: http://wireless.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git S: Maintained -F: drivers/net/wireless/wl12xx/* -X: drivers/net/wireless/wl12xx/wl1271* +F: drivers/net/wireless/wl1251/* WL1271 WIRELESS DRIVER M: Luciano Coelho L: linux-wireless@vger.kernel.org W: http://wireless.kernel.org -T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git S: Maintained F: drivers/net/wireless/wl12xx/wl1271* +F: include/linux/wl12xx.h WL3501 WIRELESS PCMCIA CARD DRIVER M: Arnaldo Carvalho de Melo @@ -6650,6 +6680,20 @@ M: "Maciej W. Rozycki" S: Maintained F: drivers/serial/zs.* +GRE DEMULTIPLEXER DRIVER +M: Dmitry Kozlov +L: netdev@vger.kernel.org +S: Maintained +F: net/ipv4/gre.c +F: include/net/gre.h + +PPTP DRIVER +M: Dmitry Kozlov +L: netdev@vger.kernel.org +S: Maintained +F: drivers/net/pptp.c +W: http://sourceforge.net/projects/accel-pptp + THE REST M: Linus Torvalds L: linux-kernel@vger.kernel.org diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c index b7d6df4e3cf95aa3f553a126087ba59353c1c5b3..41d6f549070c55affca195e9fa218786d8cae676 100644 --- a/arch/arm/mach-omap2/board-omap3pandora.c +++ b/arch/arm/mach-omap2/board-omap3pandora.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 9a5eb87425fcf91dc3164acf3b1386e38e655be7..ce28a851dcd3f06f954ccd64a03e72c30e229854 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 6b3984964cc59696a98b21872f5f768eccac71d6..189a6d1600b208ef448ea210139d2d3faa056e29 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -27,6 +29,9 @@ #include "mux.h" #include "hsmmc.h" +#define OMAP_ZOOM_WLAN_PMENA_GPIO (101) +#define OMAP_ZOOM_WLAN_IRQ_GPIO (162) + /* Zoom2 has Qwerty keyboard*/ static int board_keymap[] = { KEY(0, 0, KEY_E), @@ -106,6 +111,11 @@ static struct regulator_consumer_supply zoom_vmmc2_supply = { .supply = "vmmc", }; +static struct regulator_consumer_supply zoom_vmmc3_supply = { + .supply = "vmmc", + .dev_name = "mmci-omap-hs.2", +}; + /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ static struct regulator_init_data zoom_vmmc1 = { .constraints = { @@ -151,6 +161,38 @@ static struct regulator_init_data zoom_vsim = { .consumer_supplies = &zoom_vsim_supply, }; +static struct regulator_init_data zoom_vmmc3 = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &zoom_vmmc3_supply, +}; + +static struct fixed_voltage_config zoom_vwlan = { + .supply_name = "vwl1271", + .microvolts = 1800000, /* 1.8V */ + .gpio = OMAP_ZOOM_WLAN_PMENA_GPIO, + .startup_delay = 70000, /* 70msec */ + .enable_high = 1, + .enabled_at_boot = 0, + .init_data = &zoom_vmmc3, +}; + +static struct platform_device omap_vwlan_device = { + .name = "reg-fixed-voltage", + .id = 1, + .dev = { + .platform_data = &zoom_vwlan, + }, +}; + +struct wl12xx_platform_data omap_zoom_wlan_data __initdata = { + .irq = OMAP_GPIO_IRQ(OMAP_ZOOM_WLAN_IRQ_GPIO), + /* ZOOM ref clock is 26 MHz */ + .board_ref_clock = 1, +}; + static struct omap2_hsmmc_info mmc[] __initdata = { { .name = "external", @@ -168,6 +210,14 @@ static struct omap2_hsmmc_info mmc[] __initdata = { .nonremovable = true, .power_saving = true, }, + { + .name = "wl1271", + .mmc = 3, + .caps = MMC_CAP_4_BIT_DATA, + .gpio_wp = -EINVAL, + .gpio_cd = -EINVAL, + .nonremovable = true, + }, {} /* Terminator */ }; @@ -279,7 +329,11 @@ static void enable_board_wakeup_source(void) void __init zoom_peripherals_init(void) { + if (wl12xx_set_platform_data(&omap_zoom_wlan_data)) + pr_err("error setting wl12xx data\n"); + omap_i2c_init(); + platform_device_register(&omap_vwlan_device); usb_musb_init(&musb_board_data); enable_board_wakeup_source(); } diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 2ba6302762957a20dc30779ebe01a27060a97f63..46e96bc1f5a155ea988961b0078ecbdc854c973e 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -360,6 +360,7 @@ struct qdio_initialize { unsigned int no_output_qs; qdio_handler_t *input_handler; qdio_handler_t *output_handler; + void (*queue_start_poll) (struct ccw_device *, int, unsigned long); unsigned long int_parm; void **input_sbal_addr_array; void **output_sbal_addr_array; @@ -377,11 +378,13 @@ struct qdio_initialize { extern int qdio_allocate(struct qdio_initialize *); extern int qdio_establish(struct qdio_initialize *); extern int qdio_activate(struct ccw_device *); - -extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags, - int q_nr, unsigned int bufnr, unsigned int count); -extern int qdio_shutdown(struct ccw_device*, int); +extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int, + unsigned int); +extern int qdio_start_irq(struct ccw_device *, int); +extern int qdio_stop_irq(struct ccw_device *, int); +extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *); +extern int qdio_shutdown(struct ccw_device *, int); extern int qdio_free(struct ccw_device *); -extern int qdio_get_ssqd_desc(struct ccw_device *dev, struct qdio_ssqd_desc*); +extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *); #endif /* __QDIO_H__ */ diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index 62c3cc1075ae9239349652d53c114d404e282347..c6c9ee9f5da285213e6a96be1565683520e42904 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -2,7 +2,7 @@ # Makefile for the Linux network (ATM) device drivers. # -fore_200e-objs := fore200e.o +fore_200e-y := fore200e.o obj-$(CONFIG_ATM_ZATM) += zatm.o uPD98402.o obj-$(CONFIG_ATM_NICSTAR) += nicstar.o diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 8717809787fb7af21069dd726e11abbdcff70ee5..5d86bb803e9493443659f49180b68c147066a166 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -444,8 +444,8 @@ static inline void fs_kfree_skb (struct sk_buff * skb) #define ROUND_NEAREST 3 /********** make rate (not quite as much fun as Horizon) **********/ -static unsigned int make_rate (unsigned int rate, int r, - u16 * bits, unsigned int * actual) +static int make_rate(unsigned int rate, int r, + u16 *bits, unsigned int *actual) { unsigned char exp = -1; /* hush gcc */ unsigned int man = -1; /* hush gcc */ diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 54720baa7363996203a9489a0bfae45e0fa4a7da..a95790452a685f3325ed64af5db2f2596f911236 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -1645,10 +1645,8 @@ static int hrz_send (struct atm_vcc * atm_vcc, struct sk_buff * skb) { unsigned short d = 0; char * s = skb->data; if (*s++ == 'D') { - for (i = 0; i < 4; ++i) { - d = (d<<4) | ((*s <= '9') ? (*s - '0') : (*s - 'a' + 10)); - ++s; - } + for (i = 0; i < 4; ++i) + d = (d << 4) | hex_to_bin(*s++); PRINTK (KERN_INFO, "debug bitmap is now %hx", debug = d); } } diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 1679cbf0c5840ace7e8e47f682601f7d35a1273a..bce57328ddde9addf376fe550a768194c4173c9b 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -3152,7 +3152,7 @@ deinit_card(struct idt77252_dev *card) } -static int __devinit +static void __devinit init_sram(struct idt77252_dev *card) { int i; @@ -3298,7 +3298,6 @@ init_sram(struct idt77252_dev *card) SAR_REG_RXFD); IPRINTK("%s: SRAM initialization complete.\n", card->name); - return 0; } static int __devinit @@ -3410,8 +3409,7 @@ init_card(struct atm_dev *dev) writel(readl(SAR_REG_CFG) | conf, SAR_REG_CFG); - if (init_sram(card) < 0) - return -1; + init_sram(card); /********************************************************************/ /* A L L O C R A M A N D S E T V A R I O U S T H I N G S */ diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 8cb0347dec2848e4d6c33f5276b9ba986a9f3fac..9309d4724e1322effe4010042dc0a3136a432ebb 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -220,7 +220,7 @@ static u16 get_desc (IADEV *dev, struct ia_vcc *iavcc) { while (!desc_num || (dev->desc_tbl[desc_num -1]).timestamp) { dev->ffL.tcq_rd += 2; if (dev->ffL.tcq_rd > dev->ffL.tcq_ed) - dev->ffL.tcq_rd = dev->ffL.tcq_st; + dev->ffL.tcq_rd = dev->ffL.tcq_st; if (dev->ffL.tcq_rd == dev->host_tcq_wr) return 0xFFFF; desc_num = *(u_short *)(dev->seg_ram + dev->ffL.tcq_rd); diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index 0d32ec82e9bfa5a72e847e43202830f91b2c26d0..548d1d9e4ddad7328c2ac9d68ec7d17de949d15a 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -117,8 +117,8 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) (event->data[2] == MODULE_ALREADY_UP)) ? "Bring-up succeed" : "Bring-up failed"); - if (event->length > 3) - priv->btmrvl_dev.dev_type = event->data[3]; + if (event->length > 3 && event->data[3]) + priv->btmrvl_dev.dev_type = HCI_AMP; else priv->btmrvl_dev.dev_type = HCI_BREDR; diff --git a/drivers/bluetooth/btsdio.c b/drivers/bluetooth/btsdio.c index 76e5127884f05bc948c3a6d2b306a07483dbd033..792e32d29a1de981c3bf84ad15a4e7899a94ec5a 100644 --- a/drivers/bluetooth/btsdio.c +++ b/drivers/bluetooth/btsdio.c @@ -46,6 +46,9 @@ static const struct sdio_device_id btsdio_table[] = { /* Generic Bluetooth Type-B SDIO device */ { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_B) }, + /* Generic Bluetooth AMP controller */ + { SDIO_DEVICE_CLASS(SDIO_CLASS_BT_AMP) }, + { } /* Terminating entry */ }; @@ -329,6 +332,11 @@ static int btsdio_probe(struct sdio_func *func, hdev->bus = HCI_SDIO; hdev->driver_data = data; + if (id->class == SDIO_CLASS_BT_AMP) + hdev->dev_type = HCI_AMP; + else + hdev->dev_type = HCI_BREDR; + data->hdev = hdev; SET_HCIDEV_DEV(hdev, &func->dev); diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index d22ce3cc611e7bb60f0377ff344fa41fb7bde2db..d120a5c1c0939b1061aae61b6c983da76cf37446 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -59,9 +59,15 @@ static struct usb_device_id btusb_table[] = { /* Generic Bluetooth USB device */ { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, + /* Apple MacBookPro 7,1 */ + { USB_DEVICE(0x05ac, 0x8213) }, + /* Apple iMac11,1 */ { USB_DEVICE(0x05ac, 0x8215) }, + /* Apple MacBookPro6,2 */ + { USB_DEVICE(0x05ac, 0x8218) }, + /* AVM BlueFRITZ! USB v2.0 */ { USB_DEVICE(0x057c, 0x3800) }, diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 17361bad46dd9e367a027c4506ceea7504d76af5..720148294e648473a1a82cc0c68f50ac1fd923c3 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -101,7 +101,7 @@ static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type) break; case HCI_SCODATA_PKT: - hdev->stat.cmd_tx++; + hdev->stat.sco_tx++; break; } } diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 33f8421c71cc05001c57bbf275b61679fded72eb..18fdd9703b483fbdaadbaec83cbbb956ffa669dd 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -1361,17 +1360,6 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu) return 0; } -static void fwnet_get_drvinfo(struct net_device *net, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, KBUILD_MODNAME); - strcpy(info->bus_info, "ieee1394"); -} - -static const struct ethtool_ops fwnet_ethtool_ops = { - .get_drvinfo = fwnet_get_drvinfo, -}; - static const struct net_device_ops fwnet_netdev_ops = { .ndo_open = fwnet_open, .ndo_stop = fwnet_stop, @@ -1390,7 +1378,6 @@ static void fwnet_init_dev(struct net_device *net) net->hard_header_len = FWNET_HLEN; net->type = ARPHRD_IEEE1394; net->tx_queue_len = 10; - SET_ETHTOOL_OPS(net, &fwnet_ethtool_ops); } /* caller must hold fwnet_device_mutex */ diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index bc289e367e30ec06a815224914ef5036ea9d9d41..63403822330eced0a2593f98f5025d9d5d136dd8 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -173,8 +172,6 @@ static netdev_tx_t ether1394_tx(struct sk_buff *skb, struct net_device *dev); static void ether1394_iso(struct hpsb_iso *iso); -static const struct ethtool_ops ethtool_ops; - static int ether1394_write(struct hpsb_host *host, int srcid, int destid, quadlet_t *data, u64 addr, size_t len, u16 flags); static void ether1394_add_host(struct hpsb_host *host); @@ -525,8 +522,6 @@ static void ether1394_init_dev(struct net_device *dev) dev->header_ops = ðer1394_header_ops; dev->netdev_ops = ðer1394_netdev_ops; - SET_ETHTOOL_OPS(dev, ðtool_ops); - dev->watchdog_timeo = ETHER1394_TIMEOUT; dev->flags = IFF_BROADCAST | IFF_MULTICAST; dev->features = NETIF_F_HIGHDMA; @@ -1695,17 +1690,6 @@ static netdev_tx_t ether1394_tx(struct sk_buff *skb, return NETDEV_TX_OK; } -static void ether1394_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, driver_name); - strcpy(info->bus_info, "ieee1394"); /* FIXME provide more detail? */ -} - -static const struct ethtool_ops ethtool_ops = { - .get_drvinfo = ether1394_get_drvinfo -}; - static int __init ether1394_init_module(void) { int err; diff --git a/drivers/infiniband/hw/mlx4/Kconfig b/drivers/infiniband/hw/mlx4/Kconfig index 4175a4bd0c78841e8d9e121a53a4481069195ef6..bd995b2b50d8da143d721aa4d04683844fda410a 100644 --- a/drivers/infiniband/hw/mlx4/Kconfig +++ b/drivers/infiniband/hw/mlx4/Kconfig @@ -1,5 +1,6 @@ config MLX4_INFINIBAND tristate "Mellanox ConnectX HCA support" + depends on NETDEVICES && NETDEV_10000 && PCI select MLX4_CORE ---help--- This driver provides low-level InfiniBand support for diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 61e0efd4ccfb5d9d4d6f6bdc50f765d365c07d0e..6220d9d75b582f468789c9680d1f01399d043792 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -2701,7 +2701,7 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt) nesibdev = nesvnic->nesibdev; nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", - atomic_read(&nesvnic->netdev->refcnt)); + netdev_refcnt_read(nesvnic->netdev)); if (nesqp->active_conn) { @@ -2791,7 +2791,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) atomic_inc(&cm_accepts); nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", - atomic_read(&nesvnic->netdev->refcnt)); + netdev_refcnt_read(nesvnic->netdev)); /* allocate the ietf frame and space for private data */ nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 9046e6675686c409a0d3035650ce1e8abda8c425..546fc22405fe315636cdf36a2207e5f14302497b 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c @@ -785,7 +785,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev, nes_debug(NES_DBG_PD, "nesvnic=%p, netdev=%p %s, ibdev=%p, context=%p, netdev refcnt=%u\n", nesvnic, nesdev->netdev[0], nesdev->netdev[0]->name, ibdev, context, - atomic_read(&nesvnic->netdev->refcnt)); + netdev_refcnt_read(nesvnic->netdev)); err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds, nesadapter->max_pd, &pd_num, &nesadapter->next_pd); @@ -1416,7 +1416,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, /* update the QP table */ nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", - atomic_read(&nesvnic->netdev->refcnt)); + netdev_refcnt_read(nesvnic->netdev)); return &nesqp->ibqp; } diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 2978bdaa6b8823473a029bce120237b94e133c2f..e54e79d4e2c124310e552f3daccb512d5cff25c2 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c @@ -1515,8 +1515,13 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep) while (*s) { int digit1 = 0; int digit2 = 0; - if (!isdigit(*s)) return -3; - while (isdigit(*s)) { digit1 = digit1*10 + (*s - '0'); s++; } + char *endp; + + digit1 = simple_strtoul(s, &endp, 10); + if (s == endp) + return -3; + s = endp; + if (digit1 <= 0 || digit1 > 30) return -4; if (*s == 0 || *s == ',' || *s == ' ') { bmask |= (1 << digit1); @@ -1526,8 +1531,12 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep) } if (*s != '-') return -5; s++; - if (!isdigit(*s)) return -3; - while (isdigit(*s)) { digit2 = digit2*10 + (*s - '0'); s++; } + + digit2 = simple_strtoul(s, &endp, 10); + if (s == endp) + return -3; + s = endp; + if (digit2 <= 0 || digit2 > 30) return -4; if (*s == 0 || *s == ',' || *s == ' ') { if (digit1 > digit2) diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index b054494df846958d99fdc45c4075dc57339981bd..3acf94cc5acda3f056db58b559a8af477f6ae76a 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -98,6 +98,16 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) return capi_controller[contr - 1]; } +static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) +{ + lockdep_assert_held(&capi_controller_lock); + + if (applid - 1 >= CAPI_MAXAPPL) + return NULL; + + return capi_applications[applid - 1]; +} + static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) { if (applid - 1 >= CAPI_MAXAPPL) @@ -185,10 +195,9 @@ static void notify_up(u32 contr) ctr->state = CAPI_CTR_RUNNING; for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { - ap = get_capi_appl_by_nr(applid); - if (!ap) - continue; - register_appl(ctr, applid, &ap->rparam); + ap = __get_capi_appl_by_nr(applid); + if (ap) + register_appl(ctr, applid, &ap->rparam); } wake_up_interruptible_all(&ctr->state_wait_queue); @@ -215,7 +224,7 @@ static void ctr_down(struct capi_ctr *ctr, int new_state) memset(ctr->serial, 0, sizeof(ctr->serial)); for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { - ap = get_capi_appl_by_nr(applid); + ap = __get_capi_appl_by_nr(applid); if (ap) capi_ctr_put(ctr); } diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c index 70cf6bac7a5aa1041cfa6067df7a62c1964debd5..48e6d220f62c4d56b9bd3a5830552ccb8d684039 100644 --- a/drivers/isdn/divert/isdn_divert.c +++ b/drivers/isdn/divert/isdn_divert.c @@ -77,7 +77,7 @@ static void deflect_timer_expire(ulong arg) case DEFLECT_ALERT: cs->ics.command = ISDN_CMD_REDIR; /* protocol */ - strcpy(cs->ics.parm.setup.phone,cs->deflect_dest); + strlcpy(cs->ics.parm.setup.phone, cs->deflect_dest, sizeof(cs->ics.parm.setup.phone)); strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed"); divert_if.ll_cmd(&cs->ics); spin_lock_irqsave(&divert_lock, flags); @@ -251,7 +251,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) case 2: /* redir */ del_timer(&cs->timer); - strcpy(cs->ics.parm.setup.phone, to_nr); + strlcpy(cs->ics.parm.setup.phone, to_nr, sizeof(cs->ics.parm.setup.phone)); strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual"); ic.command = ISDN_CMD_REDIR; if ((i = divert_if.ll_cmd(&ic))) @@ -480,7 +480,7 @@ static int isdn_divert_icall(isdn_ctrl *ic) if (!cs->timer.expires) { strcpy(ic->parm.setup.eazmsn,"Testtext direct"); ic->parm.setup.screen = dv->rule.screen; - strcpy(ic->parm.setup.phone,dv->rule.to_nr); + strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone)); cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); retval = 5; diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 707d9c94cf9e0ed475e108d9d3037402322c34cb..178942a2ee61fe50124e9e6ba84ab2d6470787ad 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -109,6 +109,9 @@ struct bas_cardstate { struct urb *urb_int_in; /* URB for interrupt pipe */ unsigned char *int_in_buf; + struct work_struct int_in_wq; /* for usb_clear_halt() */ + struct timer_list timer_int_in; /* int read retry delay */ + int retry_int_in; spinlock_t lock; /* locks all following */ int basstate; /* bitmap (BS_*) */ @@ -169,7 +172,7 @@ static char *get_usb_rcmsg(int rc) case -EAGAIN: return "start frame too early or too much scheduled"; case -EFBIG: - return "too many isochronous frames requested"; + return "too many isoc frames requested"; case -EPIPE: return "endpoint stalled"; case -EMSGSIZE: @@ -200,13 +203,13 @@ static char *get_usb_statmsg(int status) case -ENOENT: return "unlinked (sync)"; case -EINPROGRESS: - return "pending"; + return "URB still pending"; case -EPROTO: - return "bit stuffing error, timeout, or unknown USB error"; + return "bitstuff error, timeout, or unknown USB error"; case -EILSEQ: return "CRC mismatch, timeout, or unknown USB error"; case -ETIME: - return "timed out"; + return "USB response timeout"; case -EPIPE: return "endpoint stalled"; case -ECOMM: @@ -214,15 +217,15 @@ static char *get_usb_statmsg(int status) case -ENOSR: return "OUT buffer underrun"; case -EOVERFLOW: - return "too much data"; + return "endpoint babble"; case -EREMOTEIO: - return "short packet detected"; + return "short packet"; case -ENODEV: return "device removed"; case -EXDEV: - return "partial isochronous transfer"; + return "partial isoc transfer"; case -EINVAL: - return "invalid argument"; + return "ISO madness"; case -ECONNRESET: return "unlinked (async)"; case -ESHUTDOWN: @@ -350,7 +353,7 @@ static inline void error_hangup(struct bc_state *bcs) * reset Gigaset device because of an unrecoverable error * This function may be called from any context, and takes care of * scheduling the necessary actions for execution outside of interrupt context. - * cs->lock must not be held. + * cs->hw.bas->lock must not be held. * argument: * controller state structure */ @@ -358,7 +361,9 @@ static inline void error_reset(struct cardstate *cs) { /* reset interrupt pipe to recover (ignore errors) */ update_basstate(cs->hw.bas, BS_RESETTING, 0); - req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT); + if (req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT)) + /* submission failed, escalate to USB port reset */ + usb_queue_reset_device(cs->hw.bas->interface); } /* check_pending @@ -438,23 +443,27 @@ static void cmd_in_timeout(unsigned long data) return; } - if (ucs->retry_cmd_in++ < BAS_RETRY) { - dev_notice(cs->dev, "control read: timeout, retry %d\n", - ucs->retry_cmd_in); - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ - return; - } else { + if (ucs->retry_cmd_in++ >= BAS_RETRY) { dev_err(cs->dev, "control read: timeout, giving up after %d tries\n", ucs->retry_cmd_in); + kfree(ucs->rcvbuf); + ucs->rcvbuf = NULL; + ucs->rcvbuf_size = 0; + error_reset(cs); + return; + } + + gig_dbg(DEBUG_USBREQ, "%s: timeout, retry %d", + __func__, ucs->retry_cmd_in); + rc = atread_submit(cs, BAS_TIMEOUT); + if (rc < 0) { + kfree(ucs->rcvbuf); + ucs->rcvbuf = NULL; + ucs->rcvbuf_size = 0; + if (rc != -ENODEV) + error_reset(cs); } - kfree(ucs->rcvbuf); - ucs->rcvbuf = NULL; - ucs->rcvbuf_size = 0; - error_reset(cs); } /* read_ctrl_callback @@ -470,18 +479,11 @@ static void read_ctrl_callback(struct urb *urb) struct cardstate *cs = inbuf->cs; struct bas_cardstate *ucs = cs->hw.bas; int status = urb->status; - int have_data = 0; unsigned numbytes; int rc; update_basstate(ucs, 0, BS_ATRDPEND); wake_up(&ucs->waitqueue); - - if (!ucs->rcvbuf_size) { - dev_warn(cs->dev, "%s: no receive in progress\n", __func__); - return; - } - del_timer(&ucs->timer_cmd_in); switch (status) { @@ -495,19 +497,10 @@ static void read_ctrl_callback(struct urb *urb) numbytes = ucs->rcvbuf_size; } - /* copy received bytes to inbuf */ - have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); - - if (unlikely(numbytes < ucs->rcvbuf_size)) { - /* incomplete - resubmit for remaining bytes */ - ucs->rcvbuf_size -= numbytes; - ucs->retry_cmd_in = 0; - rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ - return; - error_reset(cs); + /* copy received bytes to inbuf, notify event layer */ + if (gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes)) { + gig_dbg(DEBUG_INTR, "%s-->BH", __func__); + gigaset_schedule_event(cs); } break; @@ -516,37 +509,32 @@ static void read_ctrl_callback(struct urb *urb) case -EINPROGRESS: /* pending */ case -ENODEV: /* device removed */ case -ESHUTDOWN: /* device shut down */ - /* no action necessary */ + /* no further action necessary */ gig_dbg(DEBUG_USBREQ, "%s: %s", __func__, get_usb_statmsg(status)); break; - default: /* severe trouble */ - dev_warn(cs->dev, "control read: %s\n", - get_usb_statmsg(status)); + default: /* other errors: retry */ if (ucs->retry_cmd_in++ < BAS_RETRY) { - dev_notice(cs->dev, "control read: retry %d\n", - ucs->retry_cmd_in); + gig_dbg(DEBUG_USBREQ, "%s: %s, retry %d", __func__, + get_usb_statmsg(status), ucs->retry_cmd_in); rc = atread_submit(cs, BAS_TIMEOUT); - if (rc >= 0 || rc == -ENODEV) - /* resubmitted or disconnected */ - /* - bypass regular exit block */ + if (rc >= 0) + /* successfully resubmitted, skip freeing */ return; - } else { - dev_err(cs->dev, - "control read: giving up after %d tries\n", - ucs->retry_cmd_in); + if (rc == -ENODEV) + /* disconnect, no further action necessary */ + break; } + dev_err(cs->dev, "control read: %s, giving up after %d tries\n", + get_usb_statmsg(status), ucs->retry_cmd_in); error_reset(cs); } + /* read finished, free buffer */ kfree(ucs->rcvbuf); ucs->rcvbuf = NULL; ucs->rcvbuf_size = 0; - if (have_data) { - gig_dbg(DEBUG_INTR, "%s-->BH", __func__); - gigaset_schedule_event(cs); - } } /* atread_submit @@ -605,14 +593,67 @@ static int atread_submit(struct cardstate *cs, int timeout) if (timeout > 0) { gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); - ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; - ucs->timer_cmd_in.data = (unsigned long) cs; - ucs->timer_cmd_in.function = cmd_in_timeout; - add_timer(&ucs->timer_cmd_in); + mod_timer(&ucs->timer_cmd_in, jiffies + timeout * HZ / 10); } return 0; } +/* int_in_work + * workqueue routine to clear halt on interrupt in endpoint + */ + +static void int_in_work(struct work_struct *work) +{ + struct bas_cardstate *ucs = + container_of(work, struct bas_cardstate, int_in_wq); + struct urb *urb = ucs->urb_int_in; + struct cardstate *cs = urb->context; + int rc; + + /* clear halt condition */ + rc = usb_clear_halt(ucs->udev, urb->pipe); + gig_dbg(DEBUG_USBREQ, "clear_halt: %s", get_usb_rcmsg(rc)); + if (rc == 0) + /* success, resubmit interrupt read URB */ + rc = usb_submit_urb(urb, GFP_ATOMIC); + if (rc != 0 && rc != -ENODEV) { + dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); + rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); + if (rc == 0) { + rc = usb_reset_device(ucs->udev); + usb_unlock_device(ucs->udev); + } + } + ucs->retry_int_in = 0; +} + +/* int_in_resubmit + * timer routine for interrupt read delayed resubmit + * argument: + * controller state structure + */ +static void int_in_resubmit(unsigned long data) +{ + struct cardstate *cs = (struct cardstate *) data; + struct bas_cardstate *ucs = cs->hw.bas; + int rc; + + if (ucs->retry_int_in++ >= BAS_RETRY) { + dev_err(cs->dev, "interrupt read: giving up after %d tries\n", + ucs->retry_int_in); + usb_queue_reset_device(ucs->interface); + return; + } + + gig_dbg(DEBUG_USBREQ, "%s: retry %d", __func__, ucs->retry_int_in); + rc = usb_submit_urb(ucs->urb_int_in, GFP_ATOMIC); + if (rc != 0 && rc != -ENODEV) { + dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", + get_usb_rcmsg(rc)); + usb_queue_reset_device(ucs->interface); + } +} + /* read_int_callback * USB completion handler for interrupt pipe input * called by the USB subsystem in interrupt context @@ -633,19 +674,29 @@ static void read_int_callback(struct urb *urb) switch (status) { case 0: /* success */ + ucs->retry_int_in = 0; break; + case -EPIPE: /* endpoint stalled */ + schedule_work(&ucs->int_in_wq); + /* fall through */ case -ENOENT: /* cancelled */ case -ECONNRESET: /* cancelled (async) */ case -EINPROGRESS: /* pending */ - /* ignore silently */ + case -ENODEV: /* device removed */ + case -ESHUTDOWN: /* device shut down */ + /* no further action necessary */ gig_dbg(DEBUG_USBREQ, "%s: %s", __func__, get_usb_statmsg(status)); return; - case -ENODEV: /* device removed */ - case -ESHUTDOWN: /* device shut down */ - gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__); + case -EPROTO: /* protocol error or unplug */ + case -EILSEQ: + case -ETIME: + /* resubmit after delay */ + gig_dbg(DEBUG_USBREQ, "%s: %s", + __func__, get_usb_statmsg(status)); + mod_timer(&ucs->timer_int_in, jiffies + HZ / 10); return; - default: /* severe trouble */ + default: /* other errors: just resubmit */ dev_warn(cs->dev, "interrupt read: %s\n", get_usb_statmsg(status)); goto resubmit; @@ -723,6 +774,13 @@ static void read_int_callback(struct urb *urb) break; } spin_lock_irqsave(&cs->lock, flags); + if (ucs->basstate & BS_ATRDPEND) { + spin_unlock_irqrestore(&cs->lock, flags); + dev_warn(cs->dev, + "HD_RECEIVEATDATA_ACK(%d) during HD_READ_ATMESSAGE(%d) ignored\n", + l, ucs->rcvbuf_size); + break; + } if (ucs->rcvbuf_size) { /* throw away previous buffer - we have no queue */ dev_err(cs->dev, @@ -735,7 +793,6 @@ static void read_int_callback(struct urb *urb) if (ucs->rcvbuf == NULL) { spin_unlock_irqrestore(&cs->lock, flags); dev_err(cs->dev, "out of memory receiving AT data\n"); - error_reset(cs); break; } ucs->rcvbuf_size = l; @@ -745,13 +802,10 @@ static void read_int_callback(struct urb *urb) kfree(ucs->rcvbuf); ucs->rcvbuf = NULL; ucs->rcvbuf_size = 0; - if (rc != -ENODEV) { - spin_unlock_irqrestore(&cs->lock, flags); - error_reset(cs); - break; - } } spin_unlock_irqrestore(&cs->lock, flags); + if (rc < 0 && rc != -ENODEV) + error_reset(cs); break; case HD_RESET_INTERRUPT_PIPE_ACK: @@ -818,6 +872,7 @@ static void read_iso_callback(struct urb *urb) tasklet_hi_schedule(&ubc->rcvd_tasklet); } else { /* tasklet still busy, drop data and resubmit URB */ + gig_dbg(DEBUG_ISO, "%s: overrun", __func__); ubc->loststatus = status; for (i = 0; i < BAS_NUMFRAMES; i++) { ubc->isoinlost += urb->iso_frame_desc[i].actual_length; @@ -833,13 +888,11 @@ static void read_iso_callback(struct urb *urb) urb->dev = bcs->cs->hw.bas->udev; urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = BAS_NUMFRAMES; - gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", - __func__); rc = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(rc != 0 && rc != -ENODEV)) { dev_err(bcs->cs->dev, - "could not resubmit isochronous read " - "URB: %s\n", get_usb_rcmsg(rc)); + "could not resubmit isoc read URB: %s\n", + get_usb_rcmsg(rc)); dump_urb(DEBUG_ISO, "isoc read", urb); error_hangup(bcs); } @@ -1081,7 +1134,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) gig_dbg(DEBUG_ISO, "%s: disconnected", __func__); else dev_err(ucx->bcs->cs->dev, - "could not submit isochronous write URB: %s\n", + "could not submit isoc write URB: %s\n", get_usb_rcmsg(rc)); return rc; } @@ -1126,7 +1179,7 @@ static void write_iso_tasklet(unsigned long data) ubc->isooutovfl = NULL; spin_unlock_irqrestore(&ubc->isooutlock, flags); if (ovfl) { - dev_err(cs->dev, "isochronous write buffer underrun\n"); + dev_err(cs->dev, "isoc write underrun\n"); error_hangup(bcs); break; } @@ -1151,7 +1204,7 @@ static void write_iso_tasklet(unsigned long data) if (next) { /* couldn't put it back */ dev_err(cs->dev, - "losing isochronous write URB\n"); + "losing isoc write URB\n"); error_hangup(bcs); } } @@ -1178,10 +1231,10 @@ static void write_iso_tasklet(unsigned long data) if (ifd->status || ifd->actual_length != ifd->length) { dev_warn(cs->dev, - "isochronous write: frame %d: %s, " - "only %d of %d bytes sent\n", - i, get_usb_statmsg(ifd->status), - ifd->actual_length, ifd->length); + "isoc write: frame %d[%d/%d]: %s\n", + i, ifd->actual_length, + ifd->length, + get_usb_statmsg(ifd->status)); offset = (ifd->offset + ifd->actual_length) % BAS_OUTBUFSIZE; @@ -1190,11 +1243,11 @@ static void write_iso_tasklet(unsigned long data) } break; case -EPIPE: /* stall - probably underrun */ - dev_err(cs->dev, "isochronous write stalled\n"); + dev_err(cs->dev, "isoc write: stalled\n"); error_hangup(bcs); break; - default: /* severe trouble */ - dev_warn(cs->dev, "isochronous write: %s\n", + default: /* other errors */ + dev_warn(cs->dev, "isoc write: %s\n", get_usb_statmsg(status)); } @@ -1250,6 +1303,7 @@ static void read_iso_tasklet(unsigned long data) struct cardstate *cs = bcs->cs; struct urb *urb; int status; + struct usb_iso_packet_descriptor *ifd; char *rcvbuf; unsigned long flags; int totleft, numbytes, offset, frame, rc; @@ -1267,8 +1321,7 @@ static void read_iso_tasklet(unsigned long data) ubc->isoindone = NULL; if (unlikely(ubc->loststatus != -EINPROGRESS)) { dev_warn(cs->dev, - "isochronous read overrun, " - "dropped URB with status: %s, %d bytes lost\n", + "isoc read overrun, URB dropped (status: %s, %d bytes)\n", get_usb_statmsg(ubc->loststatus), ubc->isoinlost); ubc->loststatus = -EINPROGRESS; @@ -1298,11 +1351,11 @@ static void read_iso_tasklet(unsigned long data) __func__, get_usb_statmsg(status)); continue; /* -> skip */ case -EPIPE: - dev_err(cs->dev, "isochronous read stalled\n"); + dev_err(cs->dev, "isoc read: stalled\n"); error_hangup(bcs); continue; /* -> skip */ - default: /* severe trouble */ - dev_warn(cs->dev, "isochronous read: %s\n", + default: /* other error */ + dev_warn(cs->dev, "isoc read: %s\n", get_usb_statmsg(status)); goto error; } @@ -1310,40 +1363,52 @@ static void read_iso_tasklet(unsigned long data) rcvbuf = urb->transfer_buffer; totleft = urb->actual_length; for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { - numbytes = urb->iso_frame_desc[frame].actual_length; - if (unlikely(urb->iso_frame_desc[frame].status)) + ifd = &urb->iso_frame_desc[frame]; + numbytes = ifd->actual_length; + switch (ifd->status) { + case 0: /* success */ + break; + case -EPROTO: /* protocol error or unplug */ + case -EILSEQ: + case -ETIME: + /* probably just disconnected, ignore */ + gig_dbg(DEBUG_ISO, + "isoc read: frame %d[%d]: %s\n", + frame, numbytes, + get_usb_statmsg(ifd->status)); + break; + default: /* other error */ + /* report, assume transferred bytes are ok */ dev_warn(cs->dev, - "isochronous read: frame %d[%d]: %s\n", + "isoc read: frame %d[%d]: %s\n", frame, numbytes, - get_usb_statmsg( - urb->iso_frame_desc[frame].status)); + get_usb_statmsg(ifd->status)); + } if (unlikely(numbytes > BAS_MAXFRAME)) dev_warn(cs->dev, - "isochronous read: frame %d: " - "numbytes (%d) > BAS_MAXFRAME\n", - frame, numbytes); + "isoc read: frame %d[%d]: %s\n", + frame, numbytes, + "exceeds max frame size"); if (unlikely(numbytes > totleft)) { dev_warn(cs->dev, - "isochronous read: frame %d: " - "numbytes (%d) > totleft (%d)\n", - frame, numbytes, totleft); + "isoc read: frame %d[%d]: %s\n", + frame, numbytes, + "exceeds total transfer length"); numbytes = totleft; } - offset = urb->iso_frame_desc[frame].offset; + offset = ifd->offset; if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { dev_warn(cs->dev, - "isochronous read: frame %d: " - "offset (%d) + numbytes (%d) " - "> BAS_INBUFSIZE\n", - frame, offset, numbytes); + "isoc read: frame %d[%d]: %s\n", + frame, numbytes, + "exceeds end of buffer"); numbytes = BAS_INBUFSIZE - offset; } gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); totleft -= numbytes; } if (unlikely(totleft > 0)) - dev_warn(cs->dev, - "isochronous read: %d data bytes missing\n", + dev_warn(cs->dev, "isoc read: %d data bytes missing\n", totleft); error: @@ -1359,9 +1424,9 @@ static void read_iso_tasklet(unsigned long data) rc = usb_submit_urb(urb, GFP_ATOMIC); if (unlikely(rc != 0 && rc != -ENODEV)) { dev_err(cs->dev, - "could not resubmit isochronous read URB: %s\n", + "could not resubmit isoc read URB: %s\n", get_usb_rcmsg(rc)); - dump_urb(DEBUG_ISO, "resubmit iso read", urb); + dump_urb(DEBUG_ISO, "resubmit isoc read", urb); error_hangup(bcs); } } @@ -1373,12 +1438,12 @@ static void read_iso_tasklet(unsigned long data) /* req_timeout * timeout routine for control output request * argument: - * B channel control structure + * controller state structure */ static void req_timeout(unsigned long data) { - struct bc_state *bcs = (struct bc_state *) data; - struct bas_cardstate *ucs = bcs->cs->hw.bas; + struct cardstate *cs = (struct cardstate *) data; + struct bas_cardstate *ucs = cs->hw.bas; int pending; unsigned long flags; @@ -1395,38 +1460,44 @@ static void req_timeout(unsigned long data) break; case HD_OPEN_ATCHANNEL: - dev_err(bcs->cs->dev, "timeout opening AT channel\n"); - error_reset(bcs->cs); + dev_err(cs->dev, "timeout opening AT channel\n"); + error_reset(cs); break; - case HD_OPEN_B2CHANNEL: case HD_OPEN_B1CHANNEL: - dev_err(bcs->cs->dev, "timeout opening channel %d\n", - bcs->channel + 1); - error_hangup(bcs); + dev_err(cs->dev, "timeout opening channel 1\n"); + error_hangup(&cs->bcs[0]); + break; + + case HD_OPEN_B2CHANNEL: + dev_err(cs->dev, "timeout opening channel 2\n"); + error_hangup(&cs->bcs[1]); break; case HD_CLOSE_ATCHANNEL: - dev_err(bcs->cs->dev, "timeout closing AT channel\n"); - error_reset(bcs->cs); + dev_err(cs->dev, "timeout closing AT channel\n"); + error_reset(cs); break; - case HD_CLOSE_B2CHANNEL: case HD_CLOSE_B1CHANNEL: - dev_err(bcs->cs->dev, "timeout closing channel %d\n", - bcs->channel + 1); - error_reset(bcs->cs); + dev_err(cs->dev, "timeout closing channel 1\n"); + error_reset(cs); + break; + + case HD_CLOSE_B2CHANNEL: + dev_err(cs->dev, "timeout closing channel 2\n"); + error_reset(cs); break; case HD_RESET_INTERRUPT_PIPE: /* error recovery escalation */ - dev_err(bcs->cs->dev, + dev_err(cs->dev, "reset interrupt pipe timeout, attempting USB reset\n"); - usb_queue_reset_device(bcs->cs->hw.bas->interface); + usb_queue_reset_device(ucs->interface); break; default: - dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", + dev_warn(cs->dev, "request 0x%02x timed out, clearing\n", pending); } @@ -1557,10 +1628,7 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) if (timeout > 0) { gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); - ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; - ucs->timer_ctrl.data = (unsigned long) bcs; - ucs->timer_ctrl.function = req_timeout; - add_timer(&ucs->timer_ctrl); + mod_timer(&ucs->timer_ctrl, jiffies + timeout * HZ / 10); } spin_unlock_irqrestore(&ucs->lock, flags); @@ -1590,21 +1658,20 @@ static int gigaset_init_bchannel(struct bc_state *bcs) if (cs->hw.bas->basstate & BS_SUSPEND) { dev_notice(cs->dev, - "not starting isochronous I/O, " - "suspend in progress\n"); + "not starting isoc I/O, suspend in progress\n"); spin_unlock_irqrestore(&cs->lock, flags); return -EHOSTUNREACH; } ret = starturbs(bcs); if (ret < 0) { + spin_unlock_irqrestore(&cs->lock, flags); dev_err(cs->dev, - "could not start isochronous I/O for channel B%d: %s\n", + "could not start isoc I/O for channel B%d: %s\n", bcs->channel + 1, ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); if (ret != -ENODEV) error_hangup(bcs); - spin_unlock_irqrestore(&cs->lock, flags); return ret; } @@ -1614,11 +1681,11 @@ static int gigaset_init_bchannel(struct bc_state *bcs) dev_err(cs->dev, "could not open channel B%d\n", bcs->channel + 1); stopurbs(bcs->hw.bas); - if (ret != -ENODEV) - error_hangup(bcs); } spin_unlock_irqrestore(&cs->lock, flags); + if (ret < 0 && ret != -ENODEV) + error_hangup(bcs); return ret; } @@ -1826,10 +1893,7 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) { gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", ATRDY_TIMEOUT); - ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; - ucs->timer_atrdy.data = (unsigned long) cs; - ucs->timer_atrdy.function = atrdy_timeout; - add_timer(&ucs->timer_atrdy); + mod_timer(&ucs->timer_atrdy, jiffies + ATRDY_TIMEOUT * HZ / 10); } return 0; } @@ -1914,6 +1978,28 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb) * The next command will reopen the AT channel automatically. */ if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) { + /* If an HD_RECEIVEATDATA_ACK message remains unhandled + * because of an error, the base never sends another one. + * The response channel is thus effectively blocked. + * Closing and reopening the AT channel does *not* clear + * this condition. + * As a stopgap measure, submit a zero-length AT read + * before closing the AT channel. This has the undocumented + * effect of triggering a new HD_RECEIVEATDATA_ACK message + * from the base if necessary. + * The subsequent AT channel close then discards any pending + * messages. + */ + spin_lock_irqsave(&cs->lock, flags); + if (!(cs->hw.bas->basstate & BS_ATRDPEND)) { + kfree(cs->hw.bas->rcvbuf); + cs->hw.bas->rcvbuf = NULL; + cs->hw.bas->rcvbuf_size = 0; + cs->hw.bas->retry_cmd_in = 0; + atread_submit(cs, 0); + } + spin_unlock_irqrestore(&cs->lock, flags); + rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); if (cb->wake_tasklet) tasklet_schedule(cb->wake_tasklet); @@ -2010,7 +2096,7 @@ static int gigaset_freebcshw(struct bc_state *bcs) /* kill URBs and tasklets before freeing - better safe than sorry */ ubc->running = 0; - gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__); + gig_dbg(DEBUG_INIT, "%s: killing isoc URBs", __func__); for (i = 0; i < BAS_OUTURBS; ++i) { usb_kill_urb(ubc->isoouturbs[i].urb); usb_free_urb(ubc->isoouturbs[i].urb); @@ -2131,10 +2217,12 @@ static int gigaset_initcshw(struct cardstate *cs) ucs->pending = 0; ucs->basstate = 0; - init_timer(&ucs->timer_ctrl); - init_timer(&ucs->timer_atrdy); - init_timer(&ucs->timer_cmd_in); + setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs); + setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs); + setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs); + setup_timer(&ucs->timer_int_in, int_in_resubmit, (unsigned long) cs); init_waitqueue_head(&ucs->waitqueue); + INIT_WORK(&ucs->int_in_wq, int_in_work); return 1; } @@ -2282,6 +2370,7 @@ static int gigaset_probe(struct usb_interface *interface, get_usb_rcmsg(rc)); goto error; } + ucs->retry_int_in = 0; /* tell the device that the driver is ready */ rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0); @@ -2334,10 +2423,12 @@ static void gigaset_disconnect(struct usb_interface *interface) /* stop driver (common part) */ gigaset_stop(cs); - /* stop timers and URBs, free ressources */ + /* stop delayed work and URBs, free ressources */ del_timer_sync(&ucs->timer_ctrl); del_timer_sync(&ucs->timer_atrdy); del_timer_sync(&ucs->timer_cmd_in); + del_timer_sync(&ucs->timer_int_in); + cancel_work_sync(&ucs->int_in_wq); freeurbs(cs); usb_set_intfdata(interface, NULL); kfree(ucs->rcvbuf); @@ -2400,10 +2491,14 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) /* in case of timeout, proceed anyway */ } - /* kill all URBs and timers that might still be pending */ + /* kill all URBs and delayed work that might still be pending */ usb_kill_urb(ucs->urb_ctrl); usb_kill_urb(ucs->urb_int_in); del_timer_sync(&ucs->timer_ctrl); + del_timer_sync(&ucs->timer_atrdy); + del_timer_sync(&ucs->timer_cmd_in); + del_timer_sync(&ucs->timer_int_in); + cancel_work_sync(&ucs->int_in_wq); gig_dbg(DEBUG_SUSPEND, "suspend complete"); return 0; @@ -2425,6 +2520,7 @@ static int gigaset_resume(struct usb_interface *intf) get_usb_rcmsg(rc)); return rc; } + ucs->retry_int_in = 0; /* clear suspend flag to reallow activity */ update_basstate(ucs, 0, BS_SUSPEND); diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 3ca561eccd9f68dc85ccc26c99f37a4562485392..db621db67f61935d593e65b5f5a34dd81acded15 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -1026,32 +1026,6 @@ struct cardstate *gigaset_get_cs_by_id(int id) return ret; } -void gigaset_debugdrivers(void) -{ - unsigned long flags; - static struct cardstate *cs; - struct gigaset_driver *drv; - unsigned i; - - spin_lock_irqsave(&driver_lock, flags); - list_for_each_entry(drv, &drivers, list) { - gig_dbg(DEBUG_DRIVER, "driver %p", drv); - spin_lock(&drv->lock); - for (i = 0; i < drv->minors; ++i) { - gig_dbg(DEBUG_DRIVER, " index %u", i); - cs = drv->cs + i; - gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); - gig_dbg(DEBUG_DRIVER, " flags 0x%02x", cs->flags); - gig_dbg(DEBUG_DRIVER, " minor_index %u", - cs->minor_index); - gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); - gig_dbg(DEBUG_DRIVER, " i4l id %d", cs->myid); - } - spin_unlock(&drv->lock); - } - spin_unlock_irqrestore(&driver_lock, flags); -} - static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) { unsigned long flags; diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index a69512fb11951d2930c97798c50c2c52acf7c069..6dd360734cfdf21e1af9a2e98fd817e9d77cc938 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -70,7 +70,6 @@ enum debuglevel { DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ DEBUG_LLDATA = 0x00100, /* sent/received LL data */ DEBUG_EVENT = 0x00200, /* event processing */ - DEBUG_DRIVER = 0x00400, /* driver structure */ DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ DEBUG_CHANNEL = 0x01000, /* channel allocation/deallocation */ DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ @@ -727,7 +726,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, /* Deallocate driver structure. */ void gigaset_freedriver(struct gigaset_driver *drv); -void gigaset_debugdrivers(void); + struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); struct cardstate *gigaset_get_cs_by_id(int id); void gigaset_blockdriver(struct gigaset_driver *drv); diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 34bca37d65b9b4a1cd15beb6d924f91a75a60dea..9bec8b96996466665aee48039508c96303068516 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c @@ -201,8 +201,6 @@ static int command_from_LL(isdn_ctrl *cntrl) int i; size_t l; - gigaset_debugdrivers(); - gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx", cntrl->driver, cntrl->command, cntrl->arg); diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 2dfd346fc889abe9f423873551647c21d319038e..f39ccdf87a17e816f92a43afd93484ad704a6f8c 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c @@ -842,13 +842,14 @@ static inline void trans_receive(unsigned char *src, unsigned count, if (unlikely(bcs->ignore)) { bcs->ignore--; - hdlc_flush(bcs); return; } skb = bcs->rx_skb; - if (skb == NULL) + if (skb == NULL) { skb = gigaset_new_rx_skb(bcs); - bcs->hw.bas->goodbytes += skb->len; + if (skb == NULL) + return; + } dobytes = bcs->rx_bufsize - skb->len; while (count > 0) { dst = skb_put(skb, count < dobytes ? count : dobytes); @@ -860,6 +861,7 @@ static inline void trans_receive(unsigned char *src, unsigned count, if (dobytes == 0) { dump_bytes(DEBUG_STREAM_DUMP, "rcv data", skb->data, skb->len); + bcs->hw.bas->goodbytes += skb->len; gigaset_skb_rcvd(bcs, skb); skb = gigaset_new_rx_skb(bcs); if (skb == NULL) diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c index 33ce89eed65bde2715ad1abab81c4ba7d6592673..3626401208866f54fcaa25cbdfc7a1f892133a43 100644 --- a/drivers/isdn/hardware/eicon/debug.c +++ b/drivers/isdn/hardware/eicon/debug.c @@ -862,7 +862,7 @@ void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) { diva_os_spin_lock_magic_t old_irql, old_irql1; dword sec, usec, logical, serial, org_mask; int id, best_id = 0, free_id = -1; - char tmp[256]; + char tmp[128]; diva_dbg_entry_head_t* pmsg = NULL; int len; word size; diff --git a/drivers/isdn/hardware/eicon/debuglib.h b/drivers/isdn/hardware/eicon/debuglib.h index 8ea587783e149f886b2bc140683a884fcd3099fc..02eed6b4354cf6333baf4a1f969366416238877b 100644 --- a/drivers/isdn/hardware/eicon/debuglib.h +++ b/drivers/isdn/hardware/eicon/debuglib.h @@ -249,7 +249,7 @@ typedef struct _DbgHandle_ } regTime ; /* timestamp for registration */ void *pIrp ; /* ptr to pending i/o request */ unsigned long dbgMask ; /* current debug mask */ - char drvName[16] ; /* ASCII name of registered driver */ + char drvName[128] ; /* ASCII name of registered driver */ char drvTag[64] ; /* revision string */ DbgEnd dbg_end ; /* function for debug closing */ DbgLog dbg_prt ; /* function for debug appending */ diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index be5faf4aa8689b7475485a6e25d9a3b606f2a65e..5aa138eb0b3c6a3cd45abfc2b3fb024f4b56d27a 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c @@ -234,13 +234,14 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) count++; if (count > trans_max) count = trans_max; /* limit length */ - if ((skb = dev_alloc_skb(count))) { - dst = skb_put(skb, count); - while (count--) + skb = dev_alloc_skb(count); + if (skb) { + dst = skb_put(skb, count); + while (count--) *dst++ = Read_hfc(cs, HFCSX_FIF_DRD); - return(skb); - } - else return(NULL); /* no memory */ + return skb; + } else + return NULL; /* no memory */ } do { diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 51dc60da333bcf17cadca7554283b60ce98b21d7..c463162843ba85adc648f3ec000272c85dc4f62d 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include "isdn_common.h" #include "isdn_tty.h" #ifdef CONFIG_ISDN_AUDIO @@ -28,6 +28,7 @@ /* Prototypes */ +static DEFINE_MUTEX(modem_info_mutex); static int isdn_tty_edit_at(const char *, int, modem_info *); static void isdn_tty_check_esc(const u_char *, u_char, int, int *, u_long *); static void isdn_tty_modem_reset_regs(modem_info *, int); @@ -1354,14 +1355,14 @@ isdn_tty_tiocmget(struct tty_struct *tty, struct file *file) if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; - lock_kernel(); + mutex_lock(&modem_info_mutex); #ifdef ISDN_DEBUG_MODEM_IOCTL printk(KERN_DEBUG "ttyI%d ioctl TIOCMGET\n", info->line); #endif control = info->mcr; status = info->msr; - unlock_kernel(); + mutex_unlock(&modem_info_mutex); return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) @@ -1385,7 +1386,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file, printk(KERN_DEBUG "ttyI%d ioctl TIOCMxxx: %x %x\n", info->line, set, clear); #endif - lock_kernel(); + mutex_lock(&modem_info_mutex); if (set & TIOCM_RTS) info->mcr |= UART_MCR_RTS; if (set & TIOCM_DTR) { @@ -1407,7 +1408,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file, isdn_tty_modem_hup(info, 1); } } - unlock_kernel(); + mutex_unlock(&modem_info_mutex); return 0; } @@ -3515,7 +3516,7 @@ isdn_tty_parse_at(modem_info * info) { atemu *m = &info->emu; char *p; - char ds[40]; + char ds[ISDN_MSNLEN]; #ifdef ISDN_DEBUG_AT printk(KERN_DEBUG "AT: '%s'\n", m->mdmcmd); @@ -3594,7 +3595,7 @@ isdn_tty_parse_at(modem_info * info) break; case '3': p++; - sprintf(ds, "\r\n%d", info->emu.charge); + snprintf(ds, sizeof(ds), "\r\n%d", info->emu.charge); isdn_tty_at_cout(ds, info); break; default:; diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 713ef2b805a2aabec1803b6f7607f9104517fc84..76d9e673b4e16af63e296f37418fd77411f5b1bf 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c @@ -1237,6 +1237,7 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb) if (dsp->cmx_delay) dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) & CMX_BUFF_MASK; + else dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1)) & CMX_BUFF_MASK; } else { diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 22f38e48ac4eddca6e27afa74df9c5122b940e4f..5b59796ed250f53ae4e3a261583cd60a525a0cc1 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -972,7 +972,7 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) if (debug & DEBUG_L1OIP_SOCKET) printk(KERN_DEBUG "%s: got new ip address from user " "space.\n", __func__); - l1oip_socket_open(hc); + l1oip_socket_open(hc); break; case MISDN_CTRL_UNSETPEER: if (debug & DEBUG_L1OIP_SOCKET) diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index b159bd59e64e1f65b898fb371ea3c73e85d81f64..a5b632e6755264bb33205f55cb62fc85a1f42b43 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "core.h" static u_int *debug; @@ -205,13 +204,7 @@ mISDNStackd(void *data) struct mISDNstack *st = data; int err = 0; -#ifdef CONFIG_SMP - lock_kernel(); -#endif sigfillset(¤t->blocked); -#ifdef CONFIG_SMP - unlock_kernel(); -#endif if (*debug & DEBUG_MSG_THREAD) printk(KERN_DEBUG "mISDNStackd %s started\n", dev_name(&st->dev->dev)); diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c index d5920ae22d730024f23c8f6175b8a260cebd94f9..80c9c16fd5ef3fdc1c07a2d0f63eefbbe2b28cfb 100644 --- a/drivers/isdn/pcbit/edss1.c +++ b/drivers/isdn/pcbit/edss1.c @@ -33,7 +33,7 @@ #include "callbacks.h" -char * isdn_state_table[] = { +const char * const isdn_state_table[] = { "Closed", "Call initiated", "Overlap sending", diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h index 0b64f97015d856e157af4fccb9885e8bf3a184a2..39f8346e28c593b90bca541aefacd86cb9b7effa 100644 --- a/drivers/isdn/pcbit/edss1.h +++ b/drivers/isdn/pcbit/edss1.h @@ -90,7 +90,7 @@ struct fsm_timer_entry { unsigned long timeout; /* in seconds */ }; -extern char * isdn_state_table[]; +extern const char * const isdn_state_table[]; void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *, unsigned short event, struct callb_data *); diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c index baac246561b9c99b6b1b15eaef7d8ddf5e5f1da9..4777a1cbcd8d6f7f7f9b032f9f1bbe385f1f6538 100644 --- a/drivers/net/3c503.c +++ b/drivers/net/3c503.c @@ -337,10 +337,10 @@ el2_probe1(struct net_device *dev, int ioaddr) /* Finish setting the board's parameters. */ ei_status.stop_page = EL2_MB1_STOP_PG; ei_status.word16 = wordlength; - ei_status.reset_8390 = &el2_reset_8390; - ei_status.get_8390_hdr = &el2_get_8390_hdr; - ei_status.block_input = &el2_block_input; - ei_status.block_output = &el2_block_output; + ei_status.reset_8390 = el2_reset_8390; + ei_status.get_8390_hdr = el2_get_8390_hdr; + ei_status.block_input = el2_block_input; + ei_status.block_output = el2_block_output; if (dev->irq == 2) dev->irq = 9; diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index 3bba835f1a214c875352c7335dd251b27e6286d6..cdf7226a7c43a775b0505b09ed1a0d3ba21a623e 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -662,7 +662,9 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr, pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n"); { - char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" }; + static const char * const ram_split[] = { + "5:3", "3:1", "1:1", "3:5" + }; __u32 config; EL3WINDOW(3); vp->available_media = inw(ioaddr + Wn3_Options); @@ -734,7 +736,7 @@ static int corkscrew_open(struct net_device *dev) init_timer(&vp->timer); vp->timer.expires = jiffies + media_tbl[dev->if_port].wait; vp->timer.data = (unsigned long) dev; - vp->timer.function = &corkscrew_timer; /* timer handler */ + vp->timer.function = corkscrew_timer; /* timer handler */ add_timer(&vp->timer); } else dev->if_port = vp->default_media; diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c index a7b0e5e43a529f6f5cb5ecf08f41d94ec97b5efb..de579d0431697b400dadeab44cb5d7126795054b 100644 --- a/drivers/net/3c523.c +++ b/drivers/net/3c523.c @@ -287,7 +287,7 @@ static int elmc_open(struct net_device *dev) elmc_id_attn586(); /* disable interrupts */ - ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, + ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED, dev->name, dev); if (ret) { pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq); @@ -463,7 +463,7 @@ static int __init do_elmc_probe(struct net_device *dev) /* we didn't find any 3c523 in the slots we checked for */ if (slot == MCA_NOTFOUND) - return ((base_addr || irq) ? -ENXIO : -ENODEV); + return (base_addr || irq) ? -ENXIO : -ENODEV; mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC"); mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev); diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c index eca55c52bdfdf2ae8c8445bfac2901cfd9d99bd3..013b7c396663737424bd718e9b42bf0864edcda3 100644 --- a/drivers/net/3c527.c +++ b/drivers/net/3c527.c @@ -443,7 +443,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot) * Grab the IRQ */ - err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev); + err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED, DRV_NAME, dev); if (err) { release_region(dev->base_addr, MC32_IO_EXTENT); pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq); diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 179871d9e71f9a1f111645f58c68b7fea55b0861..e1da258bbfb7bfd89c24354e7deb626f4da777f9 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -1742,7 +1742,7 @@ vortex_open(struct net_device *dev) /* Use the now-standard shared IRQ implementation. */ if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ? - &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) { + boomerang_interrupt : vortex_interrupt, IRQF_SHARED, dev->name, dev))) { pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq); goto err; } diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 4a4f6b81e32de9ae8c85f9dd6aa379927d0ffaa0..ac422cd332eadd687823fcc4db7ca2eaef997fea 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -561,7 +561,7 @@ static int cp_rx_poll(struct napi_struct *napi, int budget) if (cp_rx_csum_ok(status)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_put(skb, len); @@ -754,7 +754,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, } #if CP_VLAN_TAG_USED - if (cp->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = TxVlanTag | swab16(vlan_tx_tag_get(skb)); #endif diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 77efe462b9215914dd1071c8875635ebabff6d09..7ca1fc8a3a766c7def1cd1063b3f09af4ed7e85b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -180,6 +180,13 @@ config NET_SB1000 source "drivers/net/arcnet/Kconfig" +config MII + tristate "Generic Media Independent Interface device support" + help + Most ethernet controllers have MII transceiver either as an external + or internal device. It is safe to say Y or M here even if your + ethernet card lacks MII. + source "drivers/net/phy/Kconfig" # @@ -215,13 +222,6 @@ menuconfig NET_ETHERNET if NET_ETHERNET -config MII - tristate "Generic Media Independent Interface device support" - help - Most ethernet controllers have MII transceiver either as an external - or internal device. It is safe to say Y or M here even if your - ethernet card lack MII. - config MACB tristate "Atmel MACB support" depends on HAVE_NET_MACB @@ -2518,6 +2518,18 @@ config S6GMAC source "drivers/net/stmmac/Kconfig" +config PCH_GBE + tristate "PCH Gigabit Ethernet" + depends on PCI + ---help--- + This is a gigabit ethernet driver for Topcliff PCH. + Topcliff PCH is the platform controller hub that is used in Intel's + general embedded platform. + Topcliff PCH has Gigabit Ethernet interface. + Using this interface, it is able to access system devices connected + to Gigabit Ethernet. + This driver enables Gigabit Ethernet function. + endif # NETDEV_1000 # @@ -2872,6 +2884,20 @@ config QLGE To compile this driver as a module, choose M here: the module will be called qlge. +config BNA + tristate "Brocade 1010/1020 10Gb Ethernet Driver support" + depends on PCI + ---help--- + This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet + cards. + To compile this driver as a module, choose M here: the module + will be called bna. + + For general information and support, go to the Brocade support + website at: + + + source "drivers/net/sfc/Kconfig" source "drivers/net/benet/Kconfig" @@ -3205,6 +3231,17 @@ config PPPOE which contains instruction on how to use this driver (under the heading "Kernel mode PPPoE"). +config PPTP + tristate "PPP over IPv4 (PPTP) (EXPERIMENTAL)" + depends on EXPERIMENTAL && PPP && NET_IPGRE_DEMUX + help + Support for PPP over IPv4.(Point-to-Point Tunneling Protocol) + + This driver requires pppd plugin to work in client mode or + modified pptpd (poptop) to work in server mode. + See http://accel-pptp.sourceforge.net/ for information how to + utilize this module. + config PPPOATM tristate "PPP over ATM" depends on ATM && PPP diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 3e8f150c4b14b0034edb3632b9de33b1338b9635..b8bf93d4a132d2f28b2487f6986530b14edbfa9d 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_ENIC) += enic/ obj-$(CONFIG_JME) += jme.o obj-$(CONFIG_BE2NET) += benet/ obj-$(CONFIG_VMXNET3) += vmxnet3/ +obj-$(CONFIG_BNA) += bna/ gianfar_driver-objs := gianfar.o \ gianfar_ethtool.o \ @@ -162,6 +163,7 @@ obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o obj-$(CONFIG_PPP_MPPE) += ppp_mppe.o obj-$(CONFIG_PPPOE) += pppox.o pppoe.o obj-$(CONFIG_PPPOL2TP) += pppox.o +obj-$(CONFIG_PPTP) += pppox.o pptp.o obj-$(CONFIG_SLIP) += slip.o obj-$(CONFIG_SLHC) += slhc.o @@ -296,3 +298,4 @@ obj-$(CONFIG_WIMAX) += wimax/ obj-$(CONFIG_CAIF) += caif/ obj-$(CONFIG_OCTEON_MGMT_ETHERNET) += octeon/ +obj-$(CONFIG_PCH_GBE) += pch_gbe/ diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c index b9a591604e5b538b1d6c39bc8dea5abd82d13f01..41d9911202d01e4b721e7a2221a15f0dd8e82c3b 100644 --- a/drivers/net/acenic.c +++ b/drivers/net/acenic.c @@ -2033,7 +2033,7 @@ static void ace_rx_int(struct net_device *dev, u32 rxretprd, u32 rxretcsm) skb->csum = htons(csum); skb->ip_summed = CHECKSUM_COMPLETE; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } /* send it up */ diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index 585c25f4b60c27437043eacbea291d137a60a210..2ca880b4c0dbea4499b681c55a4f46d8331caadb 100644 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -396,7 +396,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod) event_count = coal_conf->rx_event_count; if( timeout > MAX_TIMEOUT || event_count > MAX_EVENT_COUNT ) - return -EINVAL; + return -EINVAL; timeout = timeout * DELAY_TIMER_CONV; writel(VAL0|STINTEN, mmio+INTEN0); @@ -409,7 +409,7 @@ static int amd8111e_set_coalesce(struct net_device * dev, enum coal_mode cmod) event_count = coal_conf->tx_event_count; if( timeout > MAX_TIMEOUT || event_count > MAX_EVENT_COUNT ) - return -EINVAL; + return -EINVAL; timeout = timeout * DELAY_TIMER_CONV; @@ -903,18 +903,18 @@ static int amd8111e_read_mib(void __iomem *mmio, u8 MIB_COUNTER) } /* -This function reads the mib registers and returns the hardware statistics. It updates previous internal driver statistics with new values. -*/ -static struct net_device_stats *amd8111e_get_stats(struct net_device * dev) + * This function reads the mib registers and returns the hardware statistics. + * It updates previous internal driver statistics with new values. + */ +static struct net_device_stats *amd8111e_get_stats(struct net_device *dev) { struct amd8111e_priv *lp = netdev_priv(dev); void __iomem *mmio = lp->mmio; unsigned long flags; - /* struct net_device_stats *prev_stats = &lp->prev_stats; */ - struct net_device_stats* new_stats = &lp->stats; + struct net_device_stats *new_stats = &dev->stats; - if(!lp->opened) - return &lp->stats; + if (!lp->opened) + return new_stats; spin_lock_irqsave (&lp->lock, flags); /* stats.rx_packets */ @@ -1315,7 +1315,7 @@ static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb, lp->tx_ring[tx_index].tx_flags = 0; #if AMD8111E_VLAN_TAG_USED - if((lp->vlgrp != NULL) && vlan_tx_tag_present(skb)){ + if (vlan_tx_tag_present(skb)) { lp->tx_ring[tx_index].tag_ctrl_cmd |= cpu_to_le16(TCC_VLAN_INSERT); lp->tx_ring[tx_index].tag_ctrl_info = diff --git a/drivers/net/amd8111e.h b/drivers/net/amd8111e.h index ac36eb6981e3ba12c06ee7f318699eb9db2e9717..b5926af03a7ef78905b90e62e7082f5e8dba6ba2 100644 --- a/drivers/net/amd8111e.h +++ b/drivers/net/amd8111e.h @@ -787,7 +787,6 @@ struct amd8111e_priv{ struct vlan_group *vlgrp; #endif char opened; - struct net_device_stats stats; unsigned int drv_rx_errors; struct amd8111e_coalesce_conf coal_conf; diff --git a/drivers/net/appletalk/ipddp.c b/drivers/net/appletalk/ipddp.c index 0362c8d31a08b629dbfc24d7f81235d94f7279f6..10d0dba572c2e319f630638e204ed8c12ae38b5e 100644 --- a/drivers/net/appletalk/ipddp.c +++ b/drivers/net/appletalk/ipddp.c @@ -244,7 +244,7 @@ static int ipddp_delete(struct ipddp_route *rt) } spin_unlock_bh(&ipddp_route_lock); - return (-ENOENT); + return -ENOENT; } /* @@ -259,10 +259,10 @@ static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt) if(f->ip == rt->ip && f->at.s_net == rt->at.s_net && f->at.s_node == rt->at.s_node) - return (f); + return f; } - return (NULL); + return NULL; } static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -279,7 +279,7 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) switch(cmd) { case SIOCADDIPDDPRT: - return (ipddp_create(&rcp)); + return ipddp_create(&rcp); case SIOCFINDIPDDPRT: spin_lock_bh(&ipddp_route_lock); @@ -297,7 +297,7 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return -ENOENT; case SIOCDELIPDDPRT: - return (ipddp_delete(&rcp)); + return ipddp_delete(&rcp); default: return -EINVAL; diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index adc07551739ec46cb123b00c040fd29581ffe071..e69eead12ec715cd7fb610218bee4129e0f88129 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c @@ -727,7 +727,7 @@ static int sendup_buffer (struct net_device *dev) if (ltc->command != LT_RCVLAP) { printk("unknown command 0x%02x from ltpc card\n",ltc->command); - return(-1); + return -1; } dnode = ltc->dnode; snode = ltc->snode; diff --git a/drivers/net/arm/am79c961a.c b/drivers/net/arm/am79c961a.c index 8c496fb1ac9e5fc17108d9b14ba5ac489030740c..62f21106efec224d3447f408439a55bb7d4743e3 100644 --- a/drivers/net/arm/am79c961a.c +++ b/drivers/net/arm/am79c961a.c @@ -300,8 +300,6 @@ am79c961_open(struct net_device *dev) struct dev_priv *priv = netdev_priv(dev); int ret; - memset (&priv->stats, 0, sizeof (priv->stats)); - ret = request_irq(dev->irq, am79c961_interrupt, 0, dev->name, dev); if (ret) return ret; @@ -347,8 +345,7 @@ am79c961_close(struct net_device *dev) */ static struct net_device_stats *am79c961_getstats (struct net_device *dev) { - struct dev_priv *priv = netdev_priv(dev); - return &priv->stats; + return &dev->stats; } static void am79c961_mc_hash(char *addr, unsigned short *hash) @@ -510,14 +507,14 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv) if ((status & (RMD_ERR|RMD_STP|RMD_ENP)) != (RMD_STP|RMD_ENP)) { am_writeword (dev, hdraddr + 2, RMD_OWN); - priv->stats.rx_errors ++; + dev->stats.rx_errors++; if (status & RMD_ERR) { if (status & RMD_FRAM) - priv->stats.rx_frame_errors ++; + dev->stats.rx_frame_errors++; if (status & RMD_CRC) - priv->stats.rx_crc_errors ++; + dev->stats.rx_crc_errors++; } else if (status & RMD_STP) - priv->stats.rx_length_errors ++; + dev->stats.rx_length_errors++; continue; } @@ -531,12 +528,12 @@ am79c961_rx(struct net_device *dev, struct dev_priv *priv) am_writeword(dev, hdraddr + 2, RMD_OWN); skb->protocol = eth_type_trans(skb, dev); netif_rx(skb); - priv->stats.rx_bytes += len; - priv->stats.rx_packets ++; + dev->stats.rx_bytes += len; + dev->stats.rx_packets++; } else { am_writeword (dev, hdraddr + 2, RMD_OWN); printk (KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name); - priv->stats.rx_dropped ++; + dev->stats.rx_dropped++; break; } } while (1); @@ -565,7 +562,7 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv) if (status & TMD_ERR) { u_int status2; - priv->stats.tx_errors ++; + dev->stats.tx_errors++; status2 = am_readword (dev, hdraddr + 6); @@ -575,18 +572,18 @@ am79c961_tx(struct net_device *dev, struct dev_priv *priv) am_writeword (dev, hdraddr + 6, 0); if (status2 & TST_RTRY) - priv->stats.collisions += 16; + dev->stats.collisions += 16; if (status2 & TST_LCOL) - priv->stats.tx_window_errors ++; + dev->stats.tx_window_errors++; if (status2 & TST_LCAR) - priv->stats.tx_carrier_errors ++; + dev->stats.tx_carrier_errors++; if (status2 & TST_UFLO) - priv->stats.tx_fifo_errors ++; + dev->stats.tx_fifo_errors++; continue; } - priv->stats.tx_packets ++; + dev->stats.tx_packets++; len = am_readword (dev, hdraddr + 4); - priv->stats.tx_bytes += -len; + dev->stats.tx_bytes += -len; } while (priv->txtail != priv->txhead); netif_wake_queue(dev); @@ -616,7 +613,7 @@ am79c961_interrupt(int irq, void *dev_id) } if (status & CSR0_MISS) { handled = 1; - priv->stats.rx_dropped ++; + dev->stats.rx_dropped++; } if (status & CSR0_CERR) { handled = 1; diff --git a/drivers/net/arm/am79c961a.h b/drivers/net/arm/am79c961a.h index 483009fe6ec2545010f9bb95fec9ac0ce9d981d9..fd634d32756bddcfcbe7b1d79f1b1b3105d32162 100644 --- a/drivers/net/arm/am79c961a.h +++ b/drivers/net/arm/am79c961a.h @@ -130,7 +130,6 @@ #define ISALED0_LNKST 0x8000 struct dev_priv { - struct net_device_stats stats; unsigned long rxbuffer[RX_BUFFERS]; unsigned long txbuffer[TX_BUFFERS]; unsigned char txhead; diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 4a5ec9470aa1fca56d2be28893e54e39bed346ee..5a77001b6d1053d4898b4635b0f1b9d1357e5868 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c @@ -175,8 +175,6 @@ struct ep93xx_priv struct net_device *dev; struct napi_struct napi; - struct net_device_stats stats; - struct mii_if_info mii; u8 mdc_divisor; }; @@ -230,12 +228,6 @@ static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int d pr_info("mdio write timed out\n"); } -static struct net_device_stats *ep93xx_get_stats(struct net_device *dev) -{ - struct ep93xx_priv *ep = netdev_priv(dev); - return &(ep->stats); -} - static int ep93xx_rx(struct net_device *dev, int processed, int budget) { struct ep93xx_priv *ep = netdev_priv(dev); @@ -267,15 +259,15 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget) pr_crit("entry mismatch %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_RWE)) { - ep->stats.rx_errors++; + dev->stats.rx_errors++; if (rstat0 & RSTAT0_OE) - ep->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; if (rstat0 & RSTAT0_FE) - ep->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (rstat0 & (RSTAT0_RUNT | RSTAT0_EDATA)) - ep->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (rstat0 & RSTAT0_CRCE) - ep->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; goto err; } @@ -300,10 +292,10 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget) netif_receive_skb(skb); - ep->stats.rx_packets++; - ep->stats.rx_bytes += length; + dev->stats.rx_packets++; + dev->stats.rx_bytes += length; } else { - ep->stats.rx_dropped++; + dev->stats.rx_dropped++; } err: @@ -359,7 +351,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev) int entry; if (unlikely(skb->len > MAX_PKT_SIZE)) { - ep->stats.tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -415,17 +407,17 @@ static void ep93xx_tx_complete(struct net_device *dev) if (tstat0 & TSTAT0_TXWE) { int length = ep->descs->tdesc[entry].tdesc1 & 0xfff; - ep->stats.tx_packets++; - ep->stats.tx_bytes += length; + dev->stats.tx_packets++; + dev->stats.tx_bytes += length; } else { - ep->stats.tx_errors++; + dev->stats.tx_errors++; } if (tstat0 & TSTAT0_OW) - ep->stats.tx_window_errors++; + dev->stats.tx_window_errors++; if (tstat0 & TSTAT0_TXU) - ep->stats.tx_fifo_errors++; - ep->stats.collisions += (tstat0 >> 16) & 0x1f; + dev->stats.tx_fifo_errors++; + dev->stats.collisions += (tstat0 >> 16) & 0x1f; ep->tx_clean_pointer = (entry + 1) & (TX_QUEUE_ENTRIES - 1); if (ep->tx_pending == TX_QUEUE_ENTRIES) @@ -758,7 +750,6 @@ static const struct net_device_ops ep93xx_netdev_ops = { .ndo_open = ep93xx_open, .ndo_stop = ep93xx_close, .ndo_start_xmit = ep93xx_xmit, - .ndo_get_stats = ep93xx_get_stats, .ndo_do_ioctl = ep93xx_ioctl, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = eth_change_mtu, diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index b17ab5153f51e5aca038cb7a32c9bde62a0496e5..b00781c02d5d40b8b2e1aece3bba6070f24872ea 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c @@ -68,7 +68,6 @@ static int ether1_open(struct net_device *dev); static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev); static irqreturn_t ether1_interrupt(int irq, void *dev_id); static int ether1_close(struct net_device *dev); -static struct net_device_stats *ether1_getstats(struct net_device *dev); static void ether1_setmulticastlist(struct net_device *dev); static void ether1_timeout(struct net_device *dev); @@ -649,8 +648,6 @@ ether1_open (struct net_device *dev) if (request_irq(dev->irq, ether1_interrupt, 0, "ether1", dev)) return -EAGAIN; - memset (&priv(dev)->stats, 0, sizeof (struct net_device_stats)); - if (ether1_init_for_open (dev)) { free_irq (dev->irq, dev); return -EAGAIN; @@ -673,7 +670,7 @@ ether1_timeout(struct net_device *dev) if (ether1_init_for_open (dev)) printk (KERN_ERR "%s: unable to restart interface\n", dev->name); - priv(dev)->stats.tx_errors++; + dev->stats.tx_errors++; netif_wake_queue(dev); } @@ -802,21 +799,21 @@ ether1_xmit_done (struct net_device *dev) while (nop.nop_status & STAT_COMPLETE) { if (nop.nop_status & STAT_OK) { - priv(dev)->stats.tx_packets ++; - priv(dev)->stats.collisions += (nop.nop_status & STAT_COLLISIONS); + dev->stats.tx_packets++; + dev->stats.collisions += (nop.nop_status & STAT_COLLISIONS); } else { - priv(dev)->stats.tx_errors ++; + dev->stats.tx_errors++; if (nop.nop_status & STAT_COLLAFTERTX) - priv(dev)->stats.collisions ++; + dev->stats.collisions++; if (nop.nop_status & STAT_NOCARRIER) - priv(dev)->stats.tx_carrier_errors ++; + dev->stats.tx_carrier_errors++; if (nop.nop_status & STAT_TXLOSTCTS) printk (KERN_WARNING "%s: cts lost\n", dev->name); if (nop.nop_status & STAT_TXSLOWDMA) - priv(dev)->stats.tx_fifo_errors ++; + dev->stats.tx_fifo_errors++; if (nop.nop_status & STAT_COLLEXCESSIVE) - priv(dev)->stats.collisions += 16; + dev->stats.collisions += 16; } if (nop.nop_link == caddr) { @@ -879,13 +876,13 @@ ether1_recv_done (struct net_device *dev) skb->protocol = eth_type_trans (skb, dev); netif_rx (skb); - priv(dev)->stats.rx_packets ++; + dev->stats.rx_packets++; } else - priv(dev)->stats.rx_dropped ++; + dev->stats.rx_dropped++; } else { printk(KERN_WARNING "%s: %s\n", dev->name, (rbd.rbd_status & RBD_EOF) ? "oversized packet" : "acnt not valid"); - priv(dev)->stats.rx_dropped ++; + dev->stats.rx_dropped++; } nexttail = ether1_readw(dev, priv(dev)->rx_tail, rfd_t, rfd_link, NORMALIRQS); @@ -939,7 +936,7 @@ ether1_interrupt (int irq, void *dev_id) printk (KERN_WARNING "%s: RU went not ready: RU suspended\n", dev->name); ether1_writew(dev, SCB_CMDRXRESUME, SCB_ADDR, scb_t, scb_command, NORMALIRQS); writeb(CTRL_CA, REG_CONTROL); - priv(dev)->stats.rx_dropped ++; /* we suspended due to lack of buffer space */ + dev->stats.rx_dropped++; /* we suspended due to lack of buffer space */ } else printk(KERN_WARNING "%s: RU went not ready: %04X\n", dev->name, ether1_readw(dev, SCB_ADDR, scb_t, scb_status, NORMALIRQS)); @@ -962,12 +959,6 @@ ether1_close (struct net_device *dev) return 0; } -static struct net_device_stats * -ether1_getstats (struct net_device *dev) -{ - return &priv(dev)->stats; -} - /* * Set or clear the multicast filter for this adaptor. * num_addrs == -1 Promiscuous mode, receive all packets. @@ -994,7 +985,6 @@ static const struct net_device_ops ether1_netdev_ops = { .ndo_open = ether1_open, .ndo_stop = ether1_close, .ndo_start_xmit = ether1_sendpacket, - .ndo_get_stats = ether1_getstats, .ndo_set_multicast_list = ether1_setmulticastlist, .ndo_tx_timeout = ether1_timeout, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/arm/ether1.h b/drivers/net/arm/ether1.h index c8a4b2389d854b5ff22ad59716888c4c2c2324a3..3a5830ab3dc7dd2aacb6229b10624921f7c05087 100644 --- a/drivers/net/arm/ether1.h +++ b/drivers/net/arm/ether1.h @@ -38,7 +38,6 @@ struct ether1_priv { void __iomem *base; - struct net_device_stats stats; unsigned int tx_link; unsigned int tx_head; volatile unsigned int tx_tail; diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index 1361b7367c28bd86f6bbd63ad3816186ec55eaf8..44a8746f4014b81f8f767a81c45c8826f8ac03cc 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c @@ -81,7 +81,6 @@ static int ether3_open (struct net_device *dev); static int ether3_sendpacket (struct sk_buff *skb, struct net_device *dev); static irqreturn_t ether3_interrupt (int irq, void *dev_id); static int ether3_close (struct net_device *dev); -static struct net_device_stats *ether3_getstats (struct net_device *dev); static void ether3_setmulticastlist (struct net_device *dev); static void ether3_timeout(struct net_device *dev); @@ -323,8 +322,6 @@ ether3_init_for_open(struct net_device *dev) { int i; - memset(&priv(dev)->stats, 0, sizeof(struct net_device_stats)); - /* Reset the chip */ ether3_outw(CFG2_RESET, REG_CONFIG2); udelay(4); @@ -441,15 +438,6 @@ ether3_close(struct net_device *dev) return 0; } -/* - * Get the current statistics. This may be called with the card open or - * closed. - */ -static struct net_device_stats *ether3_getstats(struct net_device *dev) -{ - return &priv(dev)->stats; -} - /* * Set or clear promiscuous/multicast mode filter for this adaptor. * @@ -490,7 +478,7 @@ static void ether3_timeout(struct net_device *dev) local_irq_restore(flags); priv(dev)->regs.config2 |= CFG2_CTRLO; - priv(dev)->stats.tx_errors += 1; + dev->stats.tx_errors += 1; ether3_outw(priv(dev)->regs.config2, REG_CONFIG2); priv(dev)->tx_head = priv(dev)->tx_tail = 0; @@ -509,7 +497,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) if (priv(dev)->broken) { dev_kfree_skb(skb); - priv(dev)->stats.tx_dropped ++; + dev->stats.tx_dropped++; netif_start_queue(dev); return NETDEV_TX_OK; } @@ -673,7 +661,7 @@ if (next_ptr < RX_START || next_ptr >= RX_END) { } else goto dropping; } else { - struct net_device_stats *stats = &priv(dev)->stats; + struct net_device_stats *stats = &dev->stats; ether3_outw(next_ptr >> 8, REG_RECVEND); if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++; if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++; @@ -685,14 +673,14 @@ if (next_ptr < RX_START || next_ptr >= RX_END) { while (-- maxcnt); done: - priv(dev)->stats.rx_packets += received; + dev->stats.rx_packets += received; priv(dev)->rx_head = next_ptr; /* * If rx went off line, then that means that the buffer may be full. We * have dropped at least one packet. */ if (!(ether3_inw(REG_STATUS) & STAT_RXON)) { - priv(dev)->stats.rx_dropped ++; + dev->stats.rx_dropped++; ether3_outw(next_ptr, REG_RECVPTR); ether3_outw(priv(dev)->regs.command | CMD_RXON, REG_COMMAND); } @@ -710,7 +698,7 @@ dropping:{ last_warned = jiffies; printk("%s: memory squeeze, dropping packet.\n", dev->name); } - priv(dev)->stats.rx_dropped ++; + dev->stats.rx_dropped++; goto done; } } @@ -743,13 +731,13 @@ static void ether3_tx(struct net_device *dev) * Update errors */ if (!(status & (TXSTAT_BABBLED | TXSTAT_16COLLISIONS))) - priv(dev)->stats.tx_packets++; + dev->stats.tx_packets++; else { - priv(dev)->stats.tx_errors ++; + dev->stats.tx_errors++; if (status & TXSTAT_16COLLISIONS) - priv(dev)->stats.collisions += 16; + dev->stats.collisions += 16; if (status & TXSTAT_BABBLED) - priv(dev)->stats.tx_fifo_errors ++; + dev->stats.tx_fifo_errors++; } tx_tail = (tx_tail + 1) & 15; @@ -773,7 +761,6 @@ static const struct net_device_ops ether3_netdev_ops = { .ndo_open = ether3_open, .ndo_stop = ether3_close, .ndo_start_xmit = ether3_sendpacket, - .ndo_get_stats = ether3_getstats, .ndo_set_multicast_list = ether3_setmulticastlist, .ndo_tx_timeout = ether3_timeout, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/net/arm/ether3.h b/drivers/net/arm/ether3.h index 1921a3a07da70d14892588da230c78fd4f142a9b..2db63b08bdf37885e0b97ec5a025ea5da3fb4013 100644 --- a/drivers/net/arm/ether3.h +++ b/drivers/net/arm/ether3.h @@ -164,7 +164,6 @@ struct dev_priv { unsigned char tx_head; /* buffer nr to insert next packet */ unsigned char tx_tail; /* buffer nr of transmitting packet */ unsigned int rx_head; /* address to fetch next packet from */ - struct net_device_stats stats; struct timer_list timer; int broken; /* 0 = ok, 1 = something went wrong */ }; diff --git a/drivers/net/atarilance.c b/drivers/net/atarilance.c index b57d7dee389a6b43d87c6556962270b0a1fead22..3134e53262314e7551910ea98fa488115ebaa7e7 100644 --- a/drivers/net/atarilance.c +++ b/drivers/net/atarilance.c @@ -362,7 +362,7 @@ static void *slow_memcpy( void *dst, const void *src, size_t len ) *cto++ = *cfrom++; MFPDELAY(); } - return( dst ); + return dst; } @@ -449,7 +449,7 @@ static noinline int __init addr_accessible(volatile void *regp, int wordflag, vbr[2] = save_berr; local_irq_restore(flags); - return( ret ); + return ret; } static const struct net_device_ops lance_netdev_ops = { @@ -526,7 +526,7 @@ static unsigned long __init lance_probe1( struct net_device *dev, goto probe_ok; probe_fail: - return( 0 ); + return 0; probe_ok: lp = netdev_priv(dev); @@ -556,7 +556,7 @@ static unsigned long __init lance_probe1( struct net_device *dev, if (request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO, "PAM/Riebl-ST Ethernet", dev)) { printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 ); - return( 0 ); + return 0; } dev->irq = (unsigned short)IRQ_AUTO_5; } @@ -568,12 +568,12 @@ static unsigned long __init lance_probe1( struct net_device *dev, unsigned long irq = atari_register_vme_int(); if (!irq) { printk( "Lance: request for VME interrupt failed\n" ); - return( 0 ); + return 0; } if (request_irq(irq, lance_interrupt, IRQ_TYPE_PRIO, "Riebl-VME Ethernet", dev)) { printk( "Lance: request for irq %ld failed\n", irq ); - return( 0 ); + return 0; } dev->irq = irq; } @@ -637,7 +637,7 @@ static unsigned long __init lance_probe1( struct net_device *dev, /* XXX MSch */ dev->watchdog_timeo = TX_TIMEOUT; - return( 1 ); + return 1; } @@ -666,7 +666,7 @@ static int lance_open( struct net_device *dev ) DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", dev->name, i, DREG )); DREG = CSR0_STOP; - return( -EIO ); + return -EIO; } DREG = CSR0_IDON; DREG = CSR0_STRT; @@ -676,7 +676,7 @@ static int lance_open( struct net_device *dev ) DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); - return( 0 ); + return 0; } @@ -1126,13 +1126,13 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) int i; if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL) - return( -EOPNOTSUPP ); + return -EOPNOTSUPP; if (netif_running(dev)) { /* Only possible while card isn't started */ DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n", dev->name )); - return( -EIO ); + return -EIO; } memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len ); @@ -1142,7 +1142,7 @@ static int lance_set_mac_address( struct net_device *dev, void *addr ) /* set also the magic for future sessions */ *RIEBL_MAGIC_ADDR = RIEBL_MAGIC; - return( 0 ); + return 0; } diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index 52abbbdf8a08c46df73b8e83d2566fe741f8043d..ef4115b897bf8d394b85e4123ca7160c73eaf134 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h @@ -559,7 +559,6 @@ struct atl1c_adapter { struct napi_struct napi; struct atl1c_hw hw; struct atl1c_hw_stats hw_stats; - struct net_device_stats net_stats; struct mii_if_info mii; /* MII interface info */ u16 rx_buffer_len; diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c index d8501f060957afac49afd7726158020aa96de4b2..919080b2c3a50eb48bea7311ac0db4e8d3e8103e 100644 --- a/drivers/net/atl1c/atl1c_hw.c +++ b/drivers/net/atl1c/atl1c_hw.c @@ -480,7 +480,7 @@ int atl1c_phy_reset(struct atl1c_hw *hw) atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x929D); } if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b2 - || hw->nic_type == athr_l2c || hw->nic_type == athr_l2c) { + || hw->nic_type == athr_l2c) { atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29); atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD); } diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index c7b8ef507ebd4d71fd653240c1a1f26183c4daf1..99ffcf667d1f7cc08287aa20a12f117e52a43432 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c @@ -1562,7 +1562,7 @@ static struct net_device_stats *atl1c_get_stats(struct net_device *netdev) { struct atl1c_adapter *adapter = netdev_priv(netdev); struct atl1c_hw_stats *hw_stats = &adapter->hw_stats; - struct net_device_stats *net_stats = &adapter->net_stats; + struct net_device_stats *net_stats = &netdev->stats; atl1c_update_hw_stats(adapter); net_stats->rx_packets = hw_stats->rx_ok; @@ -1590,7 +1590,7 @@ static struct net_device_stats *atl1c_get_stats(struct net_device *netdev) net_stats->tx_aborted_errors = hw_stats->tx_abort_col; net_stats->tx_window_errors = hw_stats->tx_late_col; - return &adapter->net_stats; + return net_stats; } static inline void atl1c_clear_phy_int(struct atl1c_adapter *adapter) @@ -1700,7 +1700,7 @@ static irqreturn_t atl1c_intr(int irq, void *data) /* link event */ if (status & (ISR_GPHY | ISR_MANUAL)) { - adapter->net_stats.tx_carrier_errors++; + netdev->stats.tx_carrier_errors++; atl1c_link_chg_event(adapter); break; } @@ -1719,7 +1719,7 @@ static inline void atl1c_rx_checksum(struct atl1c_adapter *adapter, * cannot figure out if the packet is fragmented or not, * so we tell the KERNEL CHECKSUM_NONE */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } static int atl1c_alloc_rx_buffer(struct atl1c_adapter *adapter, const int ringid) @@ -2243,7 +2243,7 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, return NETDEV_TX_OK; } - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { u16 vlan = vlan_tx_tag_get(skb); __le16 tag; diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 1acea5774e8936ed0b78352c871b8b0d9734b518..ef6349bf3b33e8f8ce328147826f8e890a16abf0 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -1331,7 +1331,7 @@ static inline void atl1e_rx_checksum(struct atl1e_adapter *adapter, u16 pkt_flags; u16 err_flags; - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); pkt_flags = prrs->pkt_flag; err_flags = prrs->err_flag; if (((pkt_flags & RRS_IS_IPV4) || (pkt_flags & RRS_IS_IPV6)) && @@ -1814,7 +1814,7 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, tpd = atl1e_get_tpd(adapter); - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { u16 vlan_tag = vlan_tx_tag_get(skb); u16 atl1e_vlan_tag; @@ -2316,7 +2316,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev, netif_napi_add(netdev, &adapter->napi, atl1e_clean, 64); init_timer(&adapter->phy_config_timer); - adapter->phy_config_timer.function = &atl1e_phy_config; + adapter->phy_config_timer.function = atl1e_phy_config; adapter->phy_config_timer.data = (unsigned long) adapter; /* get user settings */ diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index c73be2848319deecd38a3d6f5e8e45ed8637e6f9..dbd27b8e66bdac2f324e6b01fd53ac16cf9d41c9 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -1811,7 +1811,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, * the higher layers and let it be sorted out there. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) { if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC | @@ -2100,9 +2100,9 @@ static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring) { u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean); u16 next_to_use = atomic_read(&tpd_ring->next_to_use); - return ((next_to_clean > next_to_use) ? + return (next_to_clean > next_to_use) ? next_to_clean - next_to_use - 1 : - tpd_ring->count + next_to_clean - next_to_use - 1); + tpd_ring->count + next_to_clean - next_to_use - 1; } static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, @@ -2408,7 +2408,7 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb, (u16) atomic_read(&tpd_ring->next_to_use)); memset(ptpd, 0, sizeof(struct tx_packet_desc)); - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { vlan_tag = vlan_tx_tag_get(skb); vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | ((vlan_tag >> 9) & 0x8); @@ -3043,7 +3043,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev, netif_carrier_off(netdev); netif_stop_queue(netdev); - setup_timer(&adapter->phy_config_timer, &atl1_phy_config, + setup_timer(&adapter->phy_config_timer, atl1_phy_config, (unsigned long)adapter); adapter->phy_timer_pending = false; diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index 8da87383fb3938dc0fe8d9031ff3860a3f24ac97..35b14bec12078a1a8cf364da39290d56429339b5 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -51,10 +51,10 @@ #define ATL2_DRV_VERSION "2.2.3" -static char atl2_driver_name[] = "atl2"; +static const char atl2_driver_name[] = "atl2"; static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver"; -static char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation."; -static char atl2_driver_version[] = ATL2_DRV_VERSION; +static const char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation."; +static const char atl2_driver_version[] = ATL2_DRV_VERSION; MODULE_AUTHOR("Atheros Corporation , Chris Snook "); MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver"); @@ -870,7 +870,7 @@ static netdev_tx_t atl2_xmit_frame(struct sk_buff *skb, offset = ((u32)(skb->len-copy_len + 3) & ~3); } #ifdef NETIF_F_HW_VLAN_TX - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { u16 vlan_tag = vlan_tx_tag_get(skb); vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) | @@ -1444,11 +1444,11 @@ static int __devinit atl2_probe(struct pci_dev *pdev, atl2_check_options(adapter); init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &atl2_watchdog; + adapter->watchdog_timer.function = atl2_watchdog; adapter->watchdog_timer.data = (unsigned long) adapter; init_timer(&adapter->phy_config_timer); - adapter->phy_config_timer.function = &atl2_phy_config; + adapter->phy_config_timer.function = atl2_phy_config; adapter->phy_config_timer.data = (unsigned long) adapter; INIT_WORK(&adapter->reset_task, atl2_reset_task); diff --git a/drivers/net/atp.c b/drivers/net/atp.c index bd2f9d331dac79ee89d3729dce6b9072b91b6a0d..dfd96b20547f2caa362050897568468e904bd3b6 100644 --- a/drivers/net/atp.c +++ b/drivers/net/atp.c @@ -445,7 +445,7 @@ static int net_open(struct net_device *dev) init_timer(&lp->timer); lp->timer.expires = jiffies + TIMED_CHECKER; lp->timer.data = (unsigned long)dev; - lp->timer.function = &atp_timed_checker; /* timer handler */ + lp->timer.function = atp_timed_checker; /* timer handler */ add_timer(&lp->timer); netif_start_queue(dev); diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 15ae6df2ff00b89885e778f8b1a8241a1959ddc3..43489f89c142f7d10e25f0454287ef28939fd228 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -13,7 +13,7 @@ * converted to use linux-2.6.x's PHY framework * * Author: MontaVista Software, Inc. - * ppopov@mvista.com or source@mvista.com + * ppopov@mvista.com or source@mvista.com * * ######################################################################## * @@ -34,6 +34,8 @@ * * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -56,11 +58,11 @@ #include #include #include +#include +#include -#include #include #include -#include #include #include @@ -152,11 +154,11 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) spin_lock_irqsave(&aup->lock, flags); - if(force_reset || (!aup->mac_enabled)) { - *aup->enable = MAC_EN_CLOCK_ENABLE; + if (force_reset || (!aup->mac_enabled)) { + writel(MAC_EN_CLOCK_ENABLE, &aup->enable); au_sync_delay(2); - *aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 - | MAC_EN_CLOCK_ENABLE); + writel((MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2 + | MAC_EN_CLOCK_ENABLE), &aup->enable); au_sync_delay(2); aup->mac_enabled = 1; @@ -171,12 +173,12 @@ static void au1000_enable_mac(struct net_device *dev, int force_reset) static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg) { struct au1000_private *aup = netdev_priv(dev); - volatile u32 *const mii_control_reg = &aup->mac->mii_control; - volatile u32 *const mii_data_reg = &aup->mac->mii_data; + u32 *const mii_control_reg = &aup->mac->mii_control; + u32 *const mii_data_reg = &aup->mac->mii_data; u32 timedout = 20; u32 mii_control; - while (*mii_control_reg & MAC_MII_BUSY) { + while (readl(mii_control_reg) & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { netdev_err(dev, "read_MII busy timeout!!\n"); @@ -187,29 +189,29 @@ static int au1000_mdio_read(struct net_device *dev, int phy_addr, int reg) mii_control = MAC_SET_MII_SELECT_REG(reg) | MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_READ; - *mii_control_reg = mii_control; + writel(mii_control, mii_control_reg); timedout = 20; - while (*mii_control_reg & MAC_MII_BUSY) { + while (readl(mii_control_reg) & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { netdev_err(dev, "mdio_read busy timeout!!\n"); return -1; } } - return (int)*mii_data_reg; + return readl(mii_data_reg); } static void au1000_mdio_write(struct net_device *dev, int phy_addr, int reg, u16 value) { struct au1000_private *aup = netdev_priv(dev); - volatile u32 *const mii_control_reg = &aup->mac->mii_control; - volatile u32 *const mii_data_reg = &aup->mac->mii_data; + u32 *const mii_control_reg = &aup->mac->mii_control; + u32 *const mii_data_reg = &aup->mac->mii_data; u32 timedout = 20; u32 mii_control; - while (*mii_control_reg & MAC_MII_BUSY) { + while (readl(mii_control_reg) & MAC_MII_BUSY) { mdelay(1); if (--timedout == 0) { netdev_err(dev, "mdio_write busy timeout!!\n"); @@ -220,18 +222,22 @@ static void au1000_mdio_write(struct net_device *dev, int phy_addr, mii_control = MAC_SET_MII_SELECT_REG(reg) | MAC_SET_MII_SELECT_PHY(phy_addr) | MAC_MII_WRITE; - *mii_data_reg = value; - *mii_control_reg = mii_control; + writel(value, mii_data_reg); + writel(mii_control, mii_control_reg); } static int au1000_mdiobus_read(struct mii_bus *bus, int phy_addr, int regnum) { /* WARNING: bus->phy_map[phy_addr].attached_dev == dev does - * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) */ + * _NOT_ hold (e.g. when PHY is accessed through other MAC's MII bus) + */ struct net_device *const dev = bus->priv; - au1000_enable_mac(dev, 0); /* make sure the MAC associated with this - * mii_bus is enabled */ + /* make sure the MAC associated with this + * mii_bus is enabled + */ + au1000_enable_mac(dev, 0); + return au1000_mdio_read(dev, phy_addr, regnum); } @@ -240,8 +246,11 @@ static int au1000_mdiobus_write(struct mii_bus *bus, int phy_addr, int regnum, { struct net_device *const dev = bus->priv; - au1000_enable_mac(dev, 0); /* make sure the MAC associated with this - * mii_bus is enabled */ + /* make sure the MAC associated with this + * mii_bus is enabled + */ + au1000_enable_mac(dev, 0); + au1000_mdio_write(dev, phy_addr, regnum, value); return 0; } @@ -250,28 +259,37 @@ static int au1000_mdiobus_reset(struct mii_bus *bus) { struct net_device *const dev = bus->priv; - au1000_enable_mac(dev, 0); /* make sure the MAC associated with this - * mii_bus is enabled */ + /* make sure the MAC associated with this + * mii_bus is enabled + */ + au1000_enable_mac(dev, 0); + return 0; } static void au1000_hard_stop(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); + u32 reg; netif_dbg(aup, drv, dev, "hard stop\n"); - aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); + reg = readl(&aup->mac->control); + reg &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE); + writel(reg, &aup->mac->control); au_sync_delay(10); } static void au1000_enable_rx_tx(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); + u32 reg; netif_dbg(aup, hw, dev, "enable_rx_tx\n"); - aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE); + reg = readl(&aup->mac->control); + reg |= (MAC_RX_ENABLE | MAC_TX_ENABLE); + writel(reg, &aup->mac->control); au_sync_delay(10); } @@ -281,6 +299,7 @@ au1000_adjust_link(struct net_device *dev) struct au1000_private *aup = netdev_priv(dev); struct phy_device *phydev = aup->phy_dev; unsigned long flags; + u32 reg; int status_change = 0; @@ -312,14 +331,15 @@ au1000_adjust_link(struct net_device *dev) /* switching duplex mode requires to disable rx and tx! */ au1000_hard_stop(dev); - if (DUPLEX_FULL == phydev->duplex) - aup->mac->control = ((aup->mac->control - | MAC_FULL_DUPLEX) - & ~MAC_DISABLE_RX_OWN); - else - aup->mac->control = ((aup->mac->control - & ~MAC_FULL_DUPLEX) - | MAC_DISABLE_RX_OWN); + reg = readl(&aup->mac->control); + if (DUPLEX_FULL == phydev->duplex) { + reg |= MAC_FULL_DUPLEX; + reg &= ~MAC_DISABLE_RX_OWN; + } else { + reg &= ~MAC_FULL_DUPLEX; + reg |= MAC_DISABLE_RX_OWN; + } + writel(reg, &aup->mac->control); au_sync_delay(1); au1000_enable_rx_tx(dev); @@ -353,10 +373,11 @@ au1000_adjust_link(struct net_device *dev) } } -static int au1000_mii_probe (struct net_device *dev) +static int au1000_mii_probe(struct net_device *dev) { struct au1000_private *const aup = netdev_priv(dev); struct phy_device *phydev = NULL; + int phy_addr; if (aup->phy_static_config) { BUG_ON(aup->mac_id < 0 || aup->mac_id > 1); @@ -366,42 +387,46 @@ static int au1000_mii_probe (struct net_device *dev) else netdev_info(dev, "using PHY-less setup\n"); return 0; - } else { - int phy_addr; - - /* find the first (lowest address) PHY on the current MAC's MII bus */ - for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) - if (aup->mii_bus->phy_map[phy_addr]) { - phydev = aup->mii_bus->phy_map[phy_addr]; - if (!aup->phy_search_highest_addr) - break; /* break out with first one found */ - } - - if (aup->phy1_search_mac0) { - /* try harder to find a PHY */ - if (!phydev && (aup->mac_id == 1)) { - /* no PHY found, maybe we have a dual PHY? */ - dev_info(&dev->dev, ": no PHY found on MAC1, " - "let's see if it's attached to MAC0...\n"); - - /* find the first (lowest address) non-attached PHY on - * the MAC0 MII bus */ - for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { - struct phy_device *const tmp_phydev = - aup->mii_bus->phy_map[phy_addr]; - - if (aup->mac_id == 1) - break; - - if (!tmp_phydev) - continue; /* no PHY here... */ + } - if (tmp_phydev->attached_dev) - continue; /* already claimed by MAC0 */ + /* find the first (lowest address) PHY + * on the current MAC's MII bus + */ + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) + if (aup->mii_bus->phy_map[phy_addr]) { + phydev = aup->mii_bus->phy_map[phy_addr]; + if (!aup->phy_search_highest_addr) + /* break out with first one found */ + break; + } - phydev = tmp_phydev; - break; /* found it */ - } + if (aup->phy1_search_mac0) { + /* try harder to find a PHY */ + if (!phydev && (aup->mac_id == 1)) { + /* no PHY found, maybe we have a dual PHY? */ + dev_info(&dev->dev, ": no PHY found on MAC1, " + "let's see if it's attached to MAC0...\n"); + + /* find the first (lowest address) non-attached + * PHY on the MAC0 MII bus + */ + for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) { + struct phy_device *const tmp_phydev = + aup->mii_bus->phy_map[phy_addr]; + + if (aup->mac_id == 1) + break; + + /* no PHY here... */ + if (!tmp_phydev) + continue; + + /* already claimed by MAC0 */ + if (tmp_phydev->attached_dev) + continue; + + phydev = tmp_phydev; + break; /* found it */ } } } @@ -452,20 +477,20 @@ static int au1000_mii_probe (struct net_device *dev) * has the virtual and dma address of a buffer suitable for * both, receive and transmit operations. */ -static db_dest_t *au1000_GetFreeDB(struct au1000_private *aup) +static struct db_dest *au1000_GetFreeDB(struct au1000_private *aup) { - db_dest_t *pDB; + struct db_dest *pDB; pDB = aup->pDBfree; - if (pDB) { + if (pDB) aup->pDBfree = pDB->pnext; - } + return pDB; } -void au1000_ReleaseDB(struct au1000_private *aup, db_dest_t *pDB) +void au1000_ReleaseDB(struct au1000_private *aup, struct db_dest *pDB) { - db_dest_t *pDBfree = aup->pDBfree; + struct db_dest *pDBfree = aup->pDBfree; if (pDBfree) pDBfree->pnext = pDB; aup->pDBfree = pDB; @@ -478,9 +503,9 @@ static void au1000_reset_mac_unlocked(struct net_device *dev) au1000_hard_stop(dev); - *aup->enable = MAC_EN_CLOCK_ENABLE; + writel(MAC_EN_CLOCK_ENABLE, &aup->enable); au_sync_delay(2); - *aup->enable = 0; + writel(0, &aup->enable); au_sync_delay(2); aup->tx_full = 0; @@ -507,7 +532,7 @@ static void au1000_reset_mac(struct net_device *dev) spin_lock_irqsave(&aup->lock, flags); - au1000_reset_mac_unlocked (dev); + au1000_reset_mac_unlocked(dev); spin_unlock_irqrestore(&aup->lock, flags); } @@ -524,11 +549,13 @@ au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base) for (i = 0; i < NUM_RX_DMA; i++) { aup->rx_dma_ring[i] = - (volatile rx_dma_t *) (rx_base + sizeof(rx_dma_t)*i); + (struct rx_dma *) + (rx_base + sizeof(struct rx_dma)*i); } for (i = 0; i < NUM_TX_DMA; i++) { aup->tx_dma_ring[i] = - (volatile tx_dma_t *) (tx_base + sizeof(tx_dma_t)*i); + (struct tx_dma *) + (tx_base + sizeof(struct tx_dma)*i); } } @@ -616,18 +643,21 @@ static int au1000_init(struct net_device *dev) spin_lock_irqsave(&aup->lock, flags); - aup->mac->control = 0; + writel(0, &aup->mac->control); aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2; aup->tx_tail = aup->tx_head; aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2; - aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4]; - aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 | - dev->dev_addr[1]<<8 | dev->dev_addr[0]; + writel(dev->dev_addr[5]<<8 | dev->dev_addr[4], + &aup->mac->mac_addr_high); + writel(dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 | + dev->dev_addr[1]<<8 | dev->dev_addr[0], + &aup->mac->mac_addr_low); - for (i = 0; i < NUM_RX_DMA; i++) { + + for (i = 0; i < NUM_RX_DMA; i++) aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE; - } + au_sync(); control = MAC_RX_ENABLE | MAC_TX_ENABLE; @@ -643,8 +673,8 @@ static int au1000_init(struct net_device *dev) control |= MAC_FULL_DUPLEX; } - aup->mac->control = control; - aup->mac->vlan1_tag = 0x8100; /* activate vlan support */ + writel(control, &aup->mac->control); + writel(0x8100, &aup->mac->vlan1_tag); /* activate vlan support */ au_sync(); spin_unlock_irqrestore(&aup->lock, flags); @@ -681,9 +711,9 @@ static int au1000_rx(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); struct sk_buff *skb; - volatile rx_dma_t *prxd; + struct rx_dma *prxd; u32 buff_stat, status; - db_dest_t *pDB; + struct db_dest *pDB; u32 frmlen; netif_dbg(aup, rx_status, dev, "au1000_rx head %d\n", aup->rx_head); @@ -713,24 +743,26 @@ static int au1000_rx(struct net_device *dev) netif_rx(skb); /* pass the packet to upper layers */ } else { if (au1000_debug > 4) { + pr_err("rx_error(s):"); if (status & RX_MISSED_FRAME) - printk("rx miss\n"); + pr_cont(" miss"); if (status & RX_WDOG_TIMER) - printk("rx wdog\n"); + pr_cont(" wdog"); if (status & RX_RUNT) - printk("rx runt\n"); + pr_cont(" runt"); if (status & RX_OVERLEN) - printk("rx overlen\n"); + pr_cont(" overlen"); if (status & RX_COLL) - printk("rx coll\n"); + pr_cont(" coll"); if (status & RX_MII_ERROR) - printk("rx mii error\n"); + pr_cont(" mii error"); if (status & RX_CRC_ERROR) - printk("rx crc error\n"); + pr_cont(" crc error"); if (status & RX_LEN_ERROR) - printk("rx len error\n"); + pr_cont(" len error"); if (status & RX_U_CNTRL_FRAME) - printk("rx u control frame\n"); + pr_cont(" u control frame"); + pr_cont("\n"); } } prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE); @@ -753,7 +785,8 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status) if (!aup->phy_dev || (DUPLEX_FULL == aup->phy_dev->duplex)) { if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { /* any other tx errors are only valid - * in half duplex mode */ + * in half duplex mode + */ ps->tx_errors++; ps->tx_aborted_errors++; } @@ -774,7 +807,7 @@ static void au1000_update_tx_stats(struct net_device *dev, u32 status) static void au1000_tx_ack(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); - volatile tx_dma_t *ptxd; + struct tx_dma *ptxd; ptxd = aup->tx_dma_ring[aup->tx_tail]; @@ -854,7 +887,7 @@ static int au1000_close(struct net_device *dev) spin_lock_irqsave(&aup->lock, flags); - au1000_reset_mac_unlocked (dev); + au1000_reset_mac_unlocked(dev); /* stop the device */ netif_stop_queue(dev); @@ -873,9 +906,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); struct net_device_stats *ps = &dev->stats; - volatile tx_dma_t *ptxd; + struct tx_dma *ptxd; u32 buff_stat; - db_dest_t *pDB; + struct db_dest *pDB; int i; netif_dbg(aup, tx_queued, dev, "tx: aup %x len=%d, data=%p, head %d\n", @@ -902,9 +935,9 @@ static netdev_tx_t au1000_tx(struct sk_buff *skb, struct net_device *dev) pDB = aup->tx_db_inuse[aup->tx_head]; skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len); if (skb->len < ETH_ZLEN) { - for (i = skb->len; i < ETH_ZLEN; i++) { + for (i = skb->len; i < ETH_ZLEN; i++) ((char *)pDB->vaddr)[i] = 0; - } + ptxd->len = ETH_ZLEN; } else ptxd->len = skb->len; @@ -935,15 +968,16 @@ static void au1000_tx_timeout(struct net_device *dev) static void au1000_multicast_list(struct net_device *dev) { struct au1000_private *aup = netdev_priv(dev); + u32 reg; - netif_dbg(aup, drv, dev, "au1000_multicast_list: flags=%x\n", dev->flags); - + netif_dbg(aup, drv, dev, "%s: flags=%x\n", __func__, dev->flags); + reg = readl(&aup->mac->control); if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - aup->mac->control |= MAC_PROMISCUOUS; + reg |= MAC_PROMISCUOUS; } else if ((dev->flags & IFF_ALLMULTI) || netdev_mc_count(dev) > MULTICAST_FILTER_LIMIT) { - aup->mac->control |= MAC_PASS_ALL_MULTI; - aup->mac->control &= ~MAC_PROMISCUOUS; + reg |= MAC_PASS_ALL_MULTI; + reg &= ~MAC_PROMISCUOUS; netdev_info(dev, "Pass all multicast\n"); } else { struct netdev_hw_addr *ha; @@ -953,11 +987,12 @@ static void au1000_multicast_list(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) set_bit(ether_crc(ETH_ALEN, ha->addr)>>26, (long *)mc_filter); - aup->mac->multi_hash_high = mc_filter[1]; - aup->mac->multi_hash_low = mc_filter[0]; - aup->mac->control &= ~MAC_PROMISCUOUS; - aup->mac->control |= MAC_HASH_MODE; + writel(mc_filter[1], &aup->mac->multi_hash_high); + writel(mc_filter[0], &aup->mac->multi_hash_low); + reg &= ~MAC_PROMISCUOUS; + reg |= MAC_HASH_MODE; } + writel(reg, &aup->mac->control); } static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) @@ -991,7 +1026,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) struct au1000_private *aup = NULL; struct au1000_eth_platform_data *pd; struct net_device *dev = NULL; - db_dest_t *pDB, *pDBfree; + struct db_dest *pDB, *pDBfree; int irq, i, err = 0; struct resource *base, *macen; @@ -1016,13 +1051,15 @@ static int __devinit au1000_probe(struct platform_device *pdev) goto out; } - if (!request_mem_region(base->start, resource_size(base), pdev->name)) { + if (!request_mem_region(base->start, resource_size(base), + pdev->name)) { dev_err(&pdev->dev, "failed to request memory region for base registers\n"); err = -ENXIO; goto out; } - if (!request_mem_region(macen->start, resource_size(macen), pdev->name)) { + if (!request_mem_region(macen->start, resource_size(macen), + pdev->name)) { dev_err(&pdev->dev, "failed to request memory region for MAC enable register\n"); err = -ENXIO; goto err_request; @@ -1040,10 +1077,12 @@ static int __devinit au1000_probe(struct platform_device *pdev) aup = netdev_priv(dev); spin_lock_init(&aup->lock); - aup->msg_enable = (au1000_debug < 4 ? AU1000_DEF_MSG_ENABLE : au1000_debug); + aup->msg_enable = (au1000_debug < 4 ? + AU1000_DEF_MSG_ENABLE : au1000_debug); - /* Allocate the data buffers */ - /* Snooping works fine with eth on all au1xxx */ + /* Allocate the data buffers + * Snooping works fine with eth on all au1xxx + */ aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE * (NUM_TX_BUFFS + NUM_RX_BUFFS), &aup->dma_addr, 0); @@ -1054,15 +1093,17 @@ static int __devinit au1000_probe(struct platform_device *pdev) } /* aup->mac is the base address of the MAC's registers */ - aup->mac = (volatile mac_reg_t *)ioremap_nocache(base->start, resource_size(base)); + aup->mac = (struct mac_reg *) + ioremap_nocache(base->start, resource_size(base)); if (!aup->mac) { dev_err(&pdev->dev, "failed to ioremap MAC registers\n"); err = -ENXIO; goto err_remap1; } - /* Setup some variables for quick register address access */ - aup->enable = (volatile u32 *)ioremap_nocache(macen->start, resource_size(macen)); + /* Setup some variables for quick register address access */ + aup->enable = (u32 *)ioremap_nocache(macen->start, + resource_size(macen)); if (!aup->enable) { dev_err(&pdev->dev, "failed to ioremap MAC enable register\n"); err = -ENXIO; @@ -1078,12 +1119,13 @@ static int __devinit au1000_probe(struct platform_device *pdev) /* set a random MAC now in case platform_data doesn't provide one */ random_ether_addr(dev->dev_addr); - *aup->enable = 0; + writel(0, &aup->enable); aup->mac_enabled = 0; pd = pdev->dev.platform_data; if (!pd) { - dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n"); + dev_info(&pdev->dev, "no platform_data passed," + " PHY search on MAC0\n"); aup->phy1_search_mac0 = 1; } else { if (is_valid_ether_addr(pd->mac)) @@ -1098,8 +1140,7 @@ static int __devinit au1000_probe(struct platform_device *pdev) } if (aup->phy_busid && aup->phy_busid > 0) { - dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII" - "bus not supported yet\n"); + dev_err(&pdev->dev, "MAC0-associated PHY attached 2nd MACs MII bus not supported yet\n"); err = -ENODEV; goto err_mdiobus_alloc; } @@ -1151,17 +1192,17 @@ static int __devinit au1000_probe(struct platform_device *pdev) for (i = 0; i < NUM_RX_DMA; i++) { pDB = au1000_GetFreeDB(aup); - if (!pDB) { + if (!pDB) goto err_out; - } + aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; aup->rx_db_inuse[i] = pDB; } for (i = 0; i < NUM_TX_DMA; i++) { pDB = au1000_GetFreeDB(aup); - if (!pDB) { + if (!pDB) goto err_out; - } + aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr; aup->tx_dma_ring[i]->len = 0; aup->tx_db_inuse[i] = pDB; @@ -1188,7 +1229,8 @@ static int __devinit au1000_probe(struct platform_device *pdev) netdev_info(dev, "Au1xx0 Ethernet found at 0x%lx, irq %d\n", (unsigned long)base->start, irq); if (version_printed++ == 0) - printk("%s version %s %s\n", DRV_NAME, DRV_VERSION, DRV_AUTHOR); + pr_info("%s version %s %s\n", + DRV_NAME, DRV_VERSION, DRV_AUTHOR); return 0; @@ -1197,7 +1239,8 @@ static int __devinit au1000_probe(struct platform_device *pdev) mdiobus_unregister(aup->mii_bus); /* here we should have a valid dev plus aup-> register addresses - * so we can reset the mac properly.*/ + * so we can reset the mac properly. + */ au1000_reset_mac(dev); for (i = 0; i < NUM_RX_DMA; i++) { diff --git a/drivers/net/au1000_eth.h b/drivers/net/au1000_eth.h index d06ec008fbf1756dee1545225d26fe25902a4054..6229c774552cbe507c05866a8602a9a3e175ee72 100644 --- a/drivers/net/au1000_eth.h +++ b/drivers/net/au1000_eth.h @@ -44,34 +44,34 @@ * Data Buffer Descriptor. Data buffers must be aligned on 32 byte * boundary for both, receive and transmit. */ -typedef struct db_dest { +struct db_dest { struct db_dest *pnext; - volatile u32 *vaddr; + u32 *vaddr; dma_addr_t dma_addr; -} db_dest_t; +}; /* * The transmit and receive descriptors are memory * mapped registers. */ -typedef struct tx_dma { +struct tx_dma { u32 status; u32 buff_stat; u32 len; u32 pad; -} tx_dma_t; +}; -typedef struct rx_dma { +struct rx_dma { u32 status; u32 buff_stat; u32 pad[2]; -} rx_dma_t; +}; /* * MAC control registers, memory mapped. */ -typedef struct mac_reg { +struct mac_reg { u32 control; u32 mac_addr_high; u32 mac_addr_low; @@ -82,16 +82,16 @@ typedef struct mac_reg { u32 flow_control; u32 vlan1_tag; u32 vlan2_tag; -} mac_reg_t; +}; struct au1000_private { - db_dest_t *pDBfree; - db_dest_t db[NUM_RX_BUFFS+NUM_TX_BUFFS]; - volatile rx_dma_t *rx_dma_ring[NUM_RX_DMA]; - volatile tx_dma_t *tx_dma_ring[NUM_TX_DMA]; - db_dest_t *rx_db_inuse[NUM_RX_DMA]; - db_dest_t *tx_db_inuse[NUM_TX_DMA]; + struct db_dest *pDBfree; + struct db_dest db[NUM_RX_BUFFS+NUM_TX_BUFFS]; + struct rx_dma *rx_dma_ring[NUM_RX_DMA]; + struct tx_dma *tx_dma_ring[NUM_TX_DMA]; + struct db_dest *rx_db_inuse[NUM_RX_DMA]; + struct db_dest *tx_db_inuse[NUM_TX_DMA]; u32 rx_head; u32 tx_head; u32 tx_tail; @@ -99,7 +99,9 @@ struct au1000_private { int mac_id; - int mac_enabled; /* whether MAC is currently enabled and running (req. for mdio) */ + int mac_enabled; /* whether MAC is currently enabled and running + * (req. for mdio) + */ int old_link; /* used by au1000_adjust_link */ int old_speed; @@ -117,9 +119,11 @@ struct au1000_private { int phy_busid; int phy_irq; - /* These variables are just for quick access to certain regs addresses. */ - volatile mac_reg_t *mac; /* mac registers */ - volatile u32 *enable; /* address of MAC Enable Register */ + /* These variables are just for quick access + * to certain regs addresses. + */ + struct mac_reg *mac; /* mac registers */ + u32 *enable; /* address of MAC Enable Register */ u32 vaddr; /* virtual address of rx/tx buffers */ dma_addr_t dma_addr; /* dma address of rx/tx buffers */ diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index 20e946b1e744d9d0d4f4802969d05e8c640e5b17..b6da4cf3694baf89d988089642a9842c551d1d2f 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -864,6 +864,7 @@ static int ax_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { dev_err(&pdev->dev, "no IRQ specified\n"); + ret = -ENXIO; goto exit_mem; } diff --git a/drivers/net/b44.c b/drivers/net/b44.c index efeffdf9e5fab30d2bd97a07e5e866fec60ed595..c6e86315b3f8df37aa2ac1a767ac46fc1b5eba60 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c @@ -818,7 +818,7 @@ static int b44_rx(struct b44 *bp, int budget) copy_skb->data, len); skb = copy_skb; } - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, bp->dev); netif_receive_skb(skb); received++; @@ -2296,18 +2296,27 @@ static int b44_resume(struct ssb_device *sdev) if (!netif_running(dev)) return 0; + spin_lock_irq(&bp->lock); + b44_init_rings(bp); + b44_init_hw(bp, B44_FULL_RESET); + spin_unlock_irq(&bp->lock); + + /* + * As a shared interrupt, the handler can be called immediately. To be + * able to check the interrupt status the hardware must already be + * powered back on (b44_init_hw). + */ rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); if (rc) { netdev_err(dev, "request_irq failed\n"); + spin_lock_irq(&bp->lock); + b44_halt(bp); + b44_free_rings(bp); + spin_unlock_irq(&bp->lock); return rc; } - spin_lock_irq(&bp->lock); - - b44_init_rings(bp); - b44_init_hw(bp, B44_FULL_RESET); netif_device_attach(bp->dev); - spin_unlock_irq(&bp->lock); b44_enable_ints(bp); netif_wake_queue(dev); diff --git a/drivers/net/bcm63xx_enet.c b/drivers/net/bcm63xx_enet.c index 0d2c5da08937d33ad4a381e8a08ef04de378df86..ecfef240a303039390088f59b6425747377f1cdc 100644 --- a/drivers/net/bcm63xx_enet.c +++ b/drivers/net/bcm63xx_enet.c @@ -293,22 +293,22 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget) /* if the packet does not have start of packet _and_ * end of packet flag set, then just recycle it */ if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) { - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; continue; } /* recycle packet if it's marked as bad */ if (unlikely(len_stat & DMADESC_ERR_MASK)) { - priv->stats.rx_errors++; + dev->stats.rx_errors++; if (len_stat & DMADESC_OVSIZE_MASK) - priv->stats.rx_length_errors++; + dev->stats.rx_length_errors++; if (len_stat & DMADESC_CRC_MASK) - priv->stats.rx_crc_errors++; + dev->stats.rx_crc_errors++; if (len_stat & DMADESC_UNDER_MASK) - priv->stats.rx_frame_errors++; + dev->stats.rx_frame_errors++; if (len_stat & DMADESC_OV_MASK) - priv->stats.rx_fifo_errors++; + dev->stats.rx_fifo_errors++; continue; } @@ -324,7 +324,7 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget) nskb = netdev_alloc_skb_ip_align(dev, len); if (!nskb) { /* forget packet, just rearm desc */ - priv->stats.rx_dropped++; + dev->stats.rx_dropped++; continue; } @@ -342,8 +342,8 @@ static int bcm_enet_receive_queue(struct net_device *dev, int budget) skb_put(skb, len); skb->protocol = eth_type_trans(skb, dev); - priv->stats.rx_packets++; - priv->stats.rx_bytes += len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += len; netif_receive_skb(skb); } while (--budget > 0); @@ -403,7 +403,7 @@ static int bcm_enet_tx_reclaim(struct net_device *dev, int force) spin_unlock(&priv->tx_lock); if (desc->len_stat & DMADESC_UNDER_MASK) - priv->stats.tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); released++; @@ -563,8 +563,8 @@ static int bcm_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (!priv->tx_desc_count) netif_stop_queue(dev); - priv->stats.tx_bytes += skb->len; - priv->stats.tx_packets++; + dev->stats.tx_bytes += skb->len; + dev->stats.tx_packets++; ret = NETDEV_TX_OK; out_unlock: @@ -798,7 +798,7 @@ static int bcm_enet_open(struct net_device *dev) snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, priv->mac_id ? "1" : "0", priv->phy_id); - phydev = phy_connect(dev, phy_id, &bcm_enet_adjust_phy_link, 0, + phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(phydev)) { @@ -1140,17 +1140,6 @@ static int bcm_enet_stop(struct net_device *dev) return 0; } -/* - * core request to return device rx/tx stats - */ -static struct net_device_stats *bcm_enet_get_stats(struct net_device *dev) -{ - struct bcm_enet_priv *priv; - - priv = netdev_priv(dev); - return &priv->stats; -} - /* * ethtool callbacks */ @@ -1163,16 +1152,18 @@ struct bcm_enet_stats { #define GEN_STAT(m) sizeof(((struct bcm_enet_priv *)0)->m), \ offsetof(struct bcm_enet_priv, m) +#define DEV_STAT(m) sizeof(((struct net_device_stats *)0)->m), \ + offsetof(struct net_device_stats, m) static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = { - { "rx_packets", GEN_STAT(stats.rx_packets), -1 }, - { "tx_packets", GEN_STAT(stats.tx_packets), -1 }, - { "rx_bytes", GEN_STAT(stats.rx_bytes), -1 }, - { "tx_bytes", GEN_STAT(stats.tx_bytes), -1 }, - { "rx_errors", GEN_STAT(stats.rx_errors), -1 }, - { "tx_errors", GEN_STAT(stats.tx_errors), -1 }, - { "rx_dropped", GEN_STAT(stats.rx_dropped), -1 }, - { "tx_dropped", GEN_STAT(stats.tx_dropped), -1 }, + { "rx_packets", DEV_STAT(rx_packets), -1 }, + { "tx_packets", DEV_STAT(tx_packets), -1 }, + { "rx_bytes", DEV_STAT(rx_bytes), -1 }, + { "tx_bytes", DEV_STAT(tx_bytes), -1 }, + { "rx_errors", DEV_STAT(rx_errors), -1 }, + { "tx_errors", DEV_STAT(tx_errors), -1 }, + { "rx_dropped", DEV_STAT(rx_dropped), -1 }, + { "tx_dropped", DEV_STAT(tx_dropped), -1 }, { "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETH_MIB_RX_GD_OCTETS}, { "rx_good_pkts", GEN_STAT(mib.rx_gd_pkts), ETH_MIB_RX_GD_PKTS }, @@ -1328,7 +1319,11 @@ static void bcm_enet_get_ethtool_stats(struct net_device *netdev, char *p; s = &bcm_enet_gstrings_stats[i]; - p = (char *)priv + s->stat_offset; + if (s->mib_reg == -1) + p = (char *)&netdev->stats; + else + p = (char *)priv; + p += s->stat_offset; data[i] = (s->sizeof_stat == sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } @@ -1605,7 +1600,6 @@ static const struct net_device_ops bcm_enet_ops = { .ndo_open = bcm_enet_open, .ndo_stop = bcm_enet_stop, .ndo_start_xmit = bcm_enet_start_xmit, - .ndo_get_stats = bcm_enet_get_stats, .ndo_set_mac_address = bcm_enet_set_mac_address, .ndo_set_multicast_list = bcm_enet_set_multicast_list, .ndo_do_ioctl = bcm_enet_ioctl, diff --git a/drivers/net/bcm63xx_enet.h b/drivers/net/bcm63xx_enet.h index bd3684d42d748502760309dbdb6c0312c09d2267..0e3048b788c2c366595c9da160b344bbb6dd1fb0 100644 --- a/drivers/net/bcm63xx_enet.h +++ b/drivers/net/bcm63xx_enet.h @@ -274,7 +274,6 @@ struct bcm_enet_priv { int pause_tx; /* stats */ - struct net_device_stats stats; struct bcm_enet_mib_counters mib; /* after mib interrupt, mib registers update is done in this diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 53306bf3f401bee193fc89f5c6c4d1b35759ecb0..4594a28b1f665ef7923aa462739b96e39182ac5e 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h @@ -78,6 +78,8 @@ static inline char *nic_name(struct pci_dev *pdev) #define MCC_Q_LEN 128 /* total size not to exceed 8 pages */ #define MCC_CQ_LEN 256 +#define MAX_RSS_QS 4 /* BE limit is 4 queues/port */ +#define BE_MAX_MSIX_VECTORS (MAX_RSS_QS + 1 + 1)/* RSS qs + 1 def Rx + Tx */ #define BE_NAPI_WEIGHT 64 #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) @@ -157,10 +159,9 @@ struct be_mcc_obj { bool rearm_cq; }; -struct be_drvr_stats { +struct be_tx_stats { u32 be_tx_reqs; /* number of TX requests initiated */ u32 be_tx_stops; /* number of times TX Q was stopped */ - u32 be_fwd_reqs; /* number of send reqs through forwarding i/f */ u32 be_tx_wrbs; /* number of tx WRBs used */ u32 be_tx_events; /* number of tx completion events */ u32 be_tx_compl; /* number of tx completion entries processed */ @@ -169,35 +170,6 @@ struct be_drvr_stats { u64 be_tx_bytes_prev; u64 be_tx_pkts; u32 be_tx_rate; - - u32 cache_barrier[16]; - - u32 be_ethrx_post_fail;/* number of ethrx buffer alloc failures */ - u32 be_rx_polls; /* number of times NAPI called poll function */ - u32 be_rx_events; /* number of ucast rx completion events */ - u32 be_rx_compl; /* number of rx completion entries processed */ - ulong be_rx_jiffies; - u64 be_rx_bytes; - u64 be_rx_bytes_prev; - u64 be_rx_pkts; - u32 be_rx_rate; - u32 be_rx_mcast_pkt; - /* number of non ether type II frames dropped where - * frame len > length field of Mac Hdr */ - u32 be_802_3_dropped_frames; - /* number of non ether type II frames malformed where - * in frame len < length field of Mac Hdr */ - u32 be_802_3_malformed_frames; - u32 be_rxcp_err; /* Num rx completion entries w/ err set. */ - ulong rx_fps_jiffies; /* jiffies at last FPS calc */ - u32 be_rx_frags; - u32 be_prev_rx_frags; - u32 be_rx_fps; /* Rx frags per second */ -}; - -struct be_stats_obj { - struct be_drvr_stats drvr_stats; - struct be_dma_mem cmd; }; struct be_tx_obj { @@ -215,10 +187,34 @@ struct be_rx_page_info { bool last_page_user; }; +struct be_rx_stats { + u32 rx_post_fail;/* number of ethrx buffer alloc failures */ + u32 rx_polls; /* number of times NAPI called poll function */ + u32 rx_events; /* number of ucast rx completion events */ + u32 rx_compl; /* number of rx completion entries processed */ + ulong rx_jiffies; + u64 rx_bytes; + u64 rx_bytes_prev; + u64 rx_pkts; + u32 rx_rate; + u32 rx_mcast_pkts; + u32 rxcp_err; /* Num rx completion entries w/ err set. */ + ulong rx_fps_jiffies; /* jiffies at last FPS calc */ + u32 rx_frags; + u32 prev_rx_frags; + u32 rx_fps; /* Rx frags per second */ +}; + struct be_rx_obj { + struct be_adapter *adapter; struct be_queue_info q; struct be_queue_info cq; struct be_rx_page_info page_info_tbl[RX_Q_LEN]; + struct be_eq_obj rx_eq; + struct be_rx_stats stats; + u8 rss_id; + bool rx_post_starved; /* Zero rx frags have been posted to BE */ + u32 cache_line_barrier[16]; }; struct be_vf_cfg { @@ -229,7 +225,6 @@ struct be_vf_cfg { u32 vf_tx_rate; }; -#define BE_NUM_MSIX_VECTORS 2 /* 1 each for Tx and Rx */ #define BE_INVALID_PMAC_ID 0xffffffff struct be_adapter { struct pci_dev *pdev; @@ -249,29 +244,31 @@ struct be_adapter { spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ spinlock_t mcc_cq_lock; - struct msix_entry msix_entries[BE_NUM_MSIX_VECTORS]; + struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS]; bool msix_enabled; bool isr_registered; /* TX Rings */ struct be_eq_obj tx_eq; struct be_tx_obj tx_obj; + struct be_tx_stats tx_stats; u32 cache_line_break[8]; /* Rx rings */ - struct be_eq_obj rx_eq; - struct be_rx_obj rx_obj; + struct be_rx_obj rx_obj[MAX_RSS_QS + 1]; /* one default non-rss Q */ + u32 num_rx_qs; u32 big_page_size; /* Compounded page size shared by rx wrbs */ - bool rx_post_starved; /* Zero rx frags have been posted to BE */ struct vlan_group *vlan_grp; u16 vlans_added; u16 max_vlans; /* Number of vlans supported */ - u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; + u8 vlan_tag[VLAN_N_VID]; + u8 vlan_prio_bmap; /* Available Priority BitMap */ + u16 recommended_prio; /* Recommended Priority */ struct be_dma_mem mc_cmd_mem; - struct be_stats_obj stats; + struct be_dma_mem stats_cmd; /* Work queue used to perform periodic tasks like getting statistics */ struct delayed_work work; @@ -287,6 +284,7 @@ struct be_adapter { bool promiscuous; bool wol; u32 function_mode; + u32 function_caps; u32 rx_fc; /* Rx flow control */ u32 tx_fc; /* Tx flow control */ bool ue_detected; @@ -313,10 +311,20 @@ struct be_adapter { extern const struct ethtool_ops be_ethtool_ops; -#define drvr_stats(adapter) (&adapter->stats.drvr_stats) +#define tx_stats(adapter) (&adapter->tx_stats) +#define rx_stats(rxo) (&rxo->stats) #define BE_SET_NETDEV_OPS(netdev, ops) (netdev->netdev_ops = ops) +#define for_all_rx_queues(adapter, rxo, i) \ + for (i = 0, rxo = &adapter->rx_obj[i]; i < adapter->num_rx_qs; \ + i++, rxo++) + +/* Just skip the first default non-rss queue */ +#define for_all_rss_queues(adapter, rxo, i) \ + for (i = 0, rxo = &adapter->rx_obj[i+1]; i < (adapter->num_rx_qs - 1);\ + i++, rxo++) + #define PAGE_SHIFT_4K 12 #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) @@ -414,6 +422,20 @@ static inline void be_check_sriov_fn_type(struct be_adapter *adapter) adapter->is_virtfn = (data != 0xAA); } +static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac) +{ + u32 addr; + + addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0); + + mac[5] = (u8)(addr & 0xFF); + mac[4] = (u8)((addr >> 8) & 0xFF); + mac[3] = (u8)((addr >> 16) & 0xFF); + mac[2] = 0xC9; + mac[1] = 0x00; + mac[0] = 0x00; +} + extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped); extern void be_link_status_update(struct be_adapter *adapter, bool link_up); diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 34abcc9403d6b76428416412904b4c06ff8d593b..1e7f305ed00b310ea91aa73b40620f37794b739e 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c @@ -71,7 +71,7 @@ static int be_mcc_compl_process(struct be_adapter *adapter, if (compl_status == MCC_STATUS_SUCCESS) { if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) { struct be_cmd_resp_get_stats *resp = - adapter->stats.cmd.va; + adapter->stats_cmd.va; be_dws_le_to_cpu(&resp->hw_stats, sizeof(resp->hw_stats)); netdev_stats_update(adapter); @@ -96,11 +96,62 @@ static void be_async_link_state_process(struct be_adapter *adapter, evt->port_link_status == ASYNC_EVENT_LINK_UP); } +/* Grp5 CoS Priority evt */ +static void be_async_grp5_cos_priority_process(struct be_adapter *adapter, + struct be_async_event_grp5_cos_priority *evt) +{ + if (evt->valid) { + adapter->vlan_prio_bmap = evt->available_priority_bmap; + adapter->recommended_prio = + evt->reco_default_priority << VLAN_PRIO_SHIFT; + } +} + +/* Grp5 QOS Speed evt */ +static void be_async_grp5_qos_speed_process(struct be_adapter *adapter, + struct be_async_event_grp5_qos_link_speed *evt) +{ + if (evt->physical_port == adapter->port_num) { + /* qos_link_speed is in units of 10 Mbps */ + adapter->link_speed = evt->qos_link_speed * 10; + } +} + +static void be_async_grp5_evt_process(struct be_adapter *adapter, + u32 trailer, struct be_mcc_compl *evt) +{ + u8 event_type = 0; + + event_type = (trailer >> ASYNC_TRAILER_EVENT_TYPE_SHIFT) & + ASYNC_TRAILER_EVENT_TYPE_MASK; + + switch (event_type) { + case ASYNC_EVENT_COS_PRIORITY: + be_async_grp5_cos_priority_process(adapter, + (struct be_async_event_grp5_cos_priority *)evt); + break; + case ASYNC_EVENT_QOS_SPEED: + be_async_grp5_qos_speed_process(adapter, + (struct be_async_event_grp5_qos_link_speed *)evt); + break; + default: + dev_warn(&adapter->pdev->dev, "Unknown grp5 event!\n"); + break; + } +} + static inline bool is_link_state_evt(u32 trailer) +{ + return ((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & + ASYNC_TRAILER_EVENT_CODE_MASK) == + ASYNC_EVENT_CODE_LINK_STATE; +} + +static inline bool is_grp5_evt(u32 trailer) { return (((trailer >> ASYNC_TRAILER_EVENT_CODE_SHIFT) & ASYNC_TRAILER_EVENT_CODE_MASK) == - ASYNC_EVENT_CODE_LINK_STATE); + ASYNC_EVENT_CODE_GRP_5); } static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter) @@ -143,6 +194,9 @@ int be_process_mcc(struct be_adapter *adapter, int *status) if (is_link_state_evt(compl->flags)) be_async_link_state_process(adapter, (struct be_async_event_link_state *) compl); + else if (is_grp5_evt(compl->flags)) + be_async_grp5_evt_process(adapter, + compl->flags, compl); } else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) { *status = be_mcc_compl_process(adapter, compl); atomic_dec(&mcc_obj->q.used); @@ -677,10 +731,10 @@ int be_cmd_mccq_create(struct be_adapter *adapter, ctxt = &req->context; be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, - OPCODE_COMMON_MCC_CREATE); + OPCODE_COMMON_MCC_CREATE_EXT); be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, - OPCODE_COMMON_MCC_CREATE, sizeof(*req)); + OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req)); req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size)); @@ -688,7 +742,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter, AMAP_SET_BITS(struct amap_mcc_context, ring_size, ctxt, be_encoded_q_len(mccq->len)); AMAP_SET_BITS(struct amap_mcc_context, cq_id, ctxt, cq->id); - + /* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */ + req->async_event_bitmap[0] |= 0x00000022; be_dws_cpu_to_le(ctxt, sizeof(req->context)); be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem); @@ -754,7 +809,7 @@ int be_cmd_txq_create(struct be_adapter *adapter, /* Uses mbox */ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_queue_info *rxq, u16 cq_id, u16 frag_size, - u16 max_frame_size, u32 if_id, u32 rss) + u16 max_frame_size, u32 if_id, u32 rss, u8 *rss_id) { struct be_mcc_wrb *wrb; struct be_cmd_req_eth_rx_create *req; @@ -785,6 +840,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter, struct be_cmd_resp_eth_rx_create *resp = embedded_payload(wrb); rxq->id = le16_to_cpu(resp->id); rxq->created = true; + *rss_id = resp->rss_id; } spin_unlock(&adapter->mbox_lock); @@ -1259,7 +1315,8 @@ int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc) } /* Uses mbox */ -int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) +int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, + u32 *mode, u32 *caps) { struct be_mcc_wrb *wrb; struct be_cmd_req_query_fw_cfg *req; @@ -1281,6 +1338,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, u32 *mode) struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb); *port_num = le32_to_cpu(resp->phys_port); *mode = le32_to_cpu(resp->function_mode); + *caps = le32_to_cpu(resp->function_caps); } spin_unlock(&adapter->mbox_lock); @@ -1311,6 +1369,37 @@ int be_cmd_reset_function(struct be_adapter *adapter) return status; } +int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) +{ + struct be_mcc_wrb *wrb; + struct be_cmd_req_rss_config *req; + u32 myhash[10]; + int status; + + spin_lock(&adapter->mbox_lock); + + wrb = wrb_from_mbox(adapter); + req = embedded_payload(wrb); + + be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, + OPCODE_ETH_RSS_CONFIG); + + be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH, + OPCODE_ETH_RSS_CONFIG, sizeof(*req)); + + req->if_id = cpu_to_le32(adapter->if_handle); + req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4); + req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1); + memcpy(req->cpu_table, rsstable, table_size); + memcpy(req->hash, myhash, sizeof(myhash)); + be_dws_cpu_to_le(req->hash, sizeof(req->hash)); + + status = be_mbox_notify_wait(adapter); + + spin_unlock(&adapter->mbox_lock); + return status; +} + /* Uses sync mcc */ int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 bcn, u8 sts, u8 state) diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index ad1e6fac60c58869e074609cee3e363672bfecd9..c7f6cdfe1c73df85bc4faf251e05b19dd6602791 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h @@ -82,7 +82,12 @@ struct be_mcc_compl { */ #define ASYNC_TRAILER_EVENT_CODE_SHIFT 8 /* bits 8 - 15 */ #define ASYNC_TRAILER_EVENT_CODE_MASK 0xFF +#define ASYNC_TRAILER_EVENT_TYPE_SHIFT 16 +#define ASYNC_TRAILER_EVENT_TYPE_MASK 0xFF #define ASYNC_EVENT_CODE_LINK_STATE 0x1 +#define ASYNC_EVENT_CODE_GRP_5 0x5 +#define ASYNC_EVENT_QOS_SPEED 0x1 +#define ASYNC_EVENT_COS_PRIORITY 0x2 struct be_async_event_trailer { u32 code; }; @@ -105,6 +110,30 @@ struct be_async_event_link_state { struct be_async_event_trailer trailer; } __packed; +/* When the event code of an async trailer is GRP-5 and event_type is QOS_SPEED + * the mcc_compl must be interpreted as follows + */ +struct be_async_event_grp5_qos_link_speed { + u8 physical_port; + u8 rsvd[5]; + u16 qos_link_speed; + u32 event_tag; + struct be_async_event_trailer trailer; +} __packed; + +/* When the event code of an async trailer is GRP5 and event type is + * CoS-Priority, the mcc_compl must be interpreted as follows + */ +struct be_async_event_grp5_cos_priority { + u8 physical_port; + u8 available_priority_bmap; + u8 reco_default_priority; + u8 valid; + u8 rsvd0; + u8 event_tag; + struct be_async_event_trailer trailer; +} __packed; + struct be_mcc_mailbox { struct be_mcc_wrb wrb; struct be_mcc_compl compl; @@ -123,8 +152,9 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_WRITE_FLASHROM 7 #define OPCODE_COMMON_CQ_CREATE 12 #define OPCODE_COMMON_EQ_CREATE 13 -#define OPCODE_COMMON_MCC_CREATE 21 +#define OPCODE_COMMON_MCC_CREATE 21 #define OPCODE_COMMON_SET_QOS 28 +#define OPCODE_COMMON_MCC_CREATE_EXT 90 #define OPCODE_COMMON_SEEPROM_READ 30 #define OPCODE_COMMON_NTWK_RX_FILTER 34 #define OPCODE_COMMON_GET_FW_VERSION 35 @@ -147,6 +177,7 @@ struct be_mcc_mailbox { #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 #define OPCODE_COMMON_GET_PHY_DETAILS 102 +#define OPCODE_ETH_RSS_CONFIG 1 #define OPCODE_ETH_ACPI_CONFIG 2 #define OPCODE_ETH_PROMISCUOUS 3 #define OPCODE_ETH_GET_STATISTICS 4 @@ -337,6 +368,7 @@ struct be_cmd_req_mcc_create { struct be_cmd_req_hdr hdr; u16 num_pages; u16 rsvd0; + u32 async_event_bitmap[1]; u8 context[sizeof(struct amap_mcc_context) / 8]; struct phys_addr pages[8]; } __packed; @@ -409,7 +441,7 @@ struct be_cmd_req_eth_rx_create { struct be_cmd_resp_eth_rx_create { struct be_cmd_resp_hdr hdr; u16 id; - u8 cpu_id; + u8 rss_id; u8 rsvd0; } __packed; @@ -739,9 +771,10 @@ struct be_cmd_resp_modify_eq_delay { } __packed; /******************** Get FW Config *******************/ +#define BE_FUNCTION_CAPS_RSS 0x2 struct be_cmd_req_query_fw_cfg { struct be_cmd_req_hdr hdr; - u32 rsvd[30]; + u32 rsvd[31]; }; struct be_cmd_resp_query_fw_cfg { @@ -751,6 +784,26 @@ struct be_cmd_resp_query_fw_cfg { u32 phys_port; u32 function_mode; u32 rsvd[26]; + u32 function_caps; +}; + +/******************** RSS Config *******************/ +/* RSS types */ +#define RSS_ENABLE_NONE 0x0 +#define RSS_ENABLE_IPV4 0x1 +#define RSS_ENABLE_TCP_IPV4 0x2 +#define RSS_ENABLE_IPV6 0x4 +#define RSS_ENABLE_TCP_IPV6 0x8 + +struct be_cmd_req_rss_config { + struct be_cmd_req_hdr hdr; + u32 if_id; + u16 enable_rss; + u16 cpu_table_size_log2; + u32 hash[10]; + u8 cpu_table[128]; + u8 flush; + u8 rsvd0[3]; }; /******************** Port Beacon ***************************/ @@ -937,7 +990,7 @@ extern int be_cmd_txq_create(struct be_adapter *adapter, extern int be_cmd_rxq_create(struct be_adapter *adapter, struct be_queue_info *rxq, u16 cq_id, u16 frag_size, u16 max_frame_size, u32 if_id, - u32 rss); + u32 rss, u8 *rss_id); extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, int type); extern int be_cmd_link_status_query(struct be_adapter *adapter, @@ -960,8 +1013,10 @@ extern int be_cmd_set_flow_control(struct be_adapter *adapter, extern int be_cmd_get_flow_control(struct be_adapter *adapter, u32 *tx_fc, u32 *rx_fc); extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, - u32 *port_num, u32 *cap); + u32 *port_num, u32 *function_mode, u32 *function_caps); extern int be_cmd_reset_function(struct be_adapter *adapter); +extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, + u16 table_size); extern int be_process_mcc(struct be_adapter *adapter, int *status); extern int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon, u8 status, u8 state); diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 13f0abbc520550b0b22ef48d0ed2a4da56d69187..0f46366ecc48eee1c7a7999db0a067fead28c37f 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c @@ -26,14 +26,16 @@ struct be_ethtool_stat { int offset; }; -enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT, ERXSTAT}; +enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT}; #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \ offsetof(_struct, field) #define NETSTAT_INFO(field) #field, NETSTAT,\ FIELDINFO(struct net_device_stats,\ field) -#define DRVSTAT_INFO(field) #field, DRVSTAT,\ - FIELDINFO(struct be_drvr_stats, field) +#define DRVSTAT_TX_INFO(field) #field, DRVSTAT_TX,\ + FIELDINFO(struct be_tx_stats, field) +#define DRVSTAT_RX_INFO(field) #field, DRVSTAT_RX,\ + FIELDINFO(struct be_rx_stats, field) #define MISCSTAT_INFO(field) #field, MISCSTAT,\ FIELDINFO(struct be_rxf_stats, field) #define PORTSTAT_INFO(field) #field, PORTSTAT,\ @@ -51,21 +53,12 @@ static const struct be_ethtool_stat et_stats[] = { {NETSTAT_INFO(tx_errors)}, {NETSTAT_INFO(rx_dropped)}, {NETSTAT_INFO(tx_dropped)}, - {DRVSTAT_INFO(be_tx_reqs)}, - {DRVSTAT_INFO(be_tx_stops)}, - {DRVSTAT_INFO(be_fwd_reqs)}, - {DRVSTAT_INFO(be_tx_wrbs)}, - {DRVSTAT_INFO(be_rx_polls)}, - {DRVSTAT_INFO(be_tx_events)}, - {DRVSTAT_INFO(be_rx_events)}, - {DRVSTAT_INFO(be_tx_compl)}, - {DRVSTAT_INFO(be_rx_compl)}, - {DRVSTAT_INFO(be_rx_mcast_pkt)}, - {DRVSTAT_INFO(be_ethrx_post_fail)}, - {DRVSTAT_INFO(be_802_3_dropped_frames)}, - {DRVSTAT_INFO(be_802_3_malformed_frames)}, - {DRVSTAT_INFO(be_tx_rate)}, - {DRVSTAT_INFO(be_rx_rate)}, + {DRVSTAT_TX_INFO(be_tx_rate)}, + {DRVSTAT_TX_INFO(be_tx_reqs)}, + {DRVSTAT_TX_INFO(be_tx_wrbs)}, + {DRVSTAT_TX_INFO(be_tx_stops)}, + {DRVSTAT_TX_INFO(be_tx_events)}, + {DRVSTAT_TX_INFO(be_tx_compl)}, {PORTSTAT_INFO(rx_unicast_frames)}, {PORTSTAT_INFO(rx_multicast_frames)}, {PORTSTAT_INFO(rx_broadcast_frames)}, @@ -91,6 +84,9 @@ static const struct be_ethtool_stat et_stats[] = { {PORTSTAT_INFO(rx_non_rss_packets)}, {PORTSTAT_INFO(rx_ipv4_packets)}, {PORTSTAT_INFO(rx_ipv6_packets)}, + {PORTSTAT_INFO(rx_switched_unicast_packets)}, + {PORTSTAT_INFO(rx_switched_multicast_packets)}, + {PORTSTAT_INFO(rx_switched_broadcast_packets)}, {PORTSTAT_INFO(tx_unicastframes)}, {PORTSTAT_INFO(tx_multicastframes)}, {PORTSTAT_INFO(tx_broadcastframes)}, @@ -103,11 +99,24 @@ static const struct be_ethtool_stat et_stats[] = { {MISCSTAT_INFO(rx_drops_too_many_frags)}, {MISCSTAT_INFO(rx_drops_invalid_ring)}, {MISCSTAT_INFO(forwarded_packets)}, - {MISCSTAT_INFO(rx_drops_mtu)}, - {ERXSTAT_INFO(rx_drops_no_fragments)}, + {MISCSTAT_INFO(rx_drops_mtu)} }; #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats) +/* Stats related to multi RX queues */ +static const struct be_ethtool_stat et_rx_stats[] = { + {DRVSTAT_RX_INFO(rx_bytes)}, + {DRVSTAT_RX_INFO(rx_pkts)}, + {DRVSTAT_RX_INFO(rx_rate)}, + {DRVSTAT_RX_INFO(rx_polls)}, + {DRVSTAT_RX_INFO(rx_events)}, + {DRVSTAT_RX_INFO(rx_compl)}, + {DRVSTAT_RX_INFO(rx_mcast_pkts)}, + {DRVSTAT_RX_INFO(rx_post_fail)}, + {ERXSTAT_INFO(rx_drops_no_fragments)} +}; +#define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) + static const char et_self_tests[][ETH_GSTRING_LEN] = { "MAC Loopback test", "PHY Loopback test", @@ -140,7 +149,7 @@ static int be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; + struct be_eq_obj *rx_eq = &adapter->rx_obj[0].rx_eq; struct be_eq_obj *tx_eq = &adapter->tx_eq; coalesce->rx_coalesce_usecs = rx_eq->cur_eqd; @@ -164,25 +173,49 @@ static int be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; + struct be_rx_obj *rxo; + struct be_eq_obj *rx_eq; struct be_eq_obj *tx_eq = &adapter->tx_eq; u32 tx_max, tx_min, tx_cur; u32 rx_max, rx_min, rx_cur; - int status = 0; + int status = 0, i; if (coalesce->use_adaptive_tx_coalesce == 1) return -EINVAL; - /* if AIC is being turned on now, start with an EQD of 0 */ - if (rx_eq->enable_aic == 0 && - coalesce->use_adaptive_rx_coalesce == 1) { - rx_eq->cur_eqd = 0; + for_all_rx_queues(adapter, rxo, i) { + rx_eq = &rxo->rx_eq; + + if (!rx_eq->enable_aic && coalesce->use_adaptive_rx_coalesce) + rx_eq->cur_eqd = 0; + rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce; + + rx_max = coalesce->rx_coalesce_usecs_high; + rx_min = coalesce->rx_coalesce_usecs_low; + rx_cur = coalesce->rx_coalesce_usecs; + + if (rx_eq->enable_aic) { + if (rx_max > BE_MAX_EQD) + rx_max = BE_MAX_EQD; + if (rx_min > rx_max) + rx_min = rx_max; + rx_eq->max_eqd = rx_max; + rx_eq->min_eqd = rx_min; + if (rx_eq->cur_eqd > rx_max) + rx_eq->cur_eqd = rx_max; + if (rx_eq->cur_eqd < rx_min) + rx_eq->cur_eqd = rx_min; + } else { + if (rx_cur > BE_MAX_EQD) + rx_cur = BE_MAX_EQD; + if (rx_eq->cur_eqd != rx_cur) { + status = be_cmd_modify_eqd(adapter, rx_eq->q.id, + rx_cur); + if (!status) + rx_eq->cur_eqd = rx_cur; + } + } } - rx_eq->enable_aic = coalesce->use_adaptive_rx_coalesce; - - rx_max = coalesce->rx_coalesce_usecs_high; - rx_min = coalesce->rx_coalesce_usecs_low; - rx_cur = coalesce->rx_coalesce_usecs; tx_max = coalesce->tx_coalesce_usecs_high; tx_min = coalesce->tx_coalesce_usecs_low; @@ -196,27 +229,6 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) tx_eq->cur_eqd = tx_cur; } - if (rx_eq->enable_aic) { - if (rx_max > BE_MAX_EQD) - rx_max = BE_MAX_EQD; - if (rx_min > rx_max) - rx_min = rx_max; - rx_eq->max_eqd = rx_max; - rx_eq->min_eqd = rx_min; - if (rx_eq->cur_eqd > rx_max) - rx_eq->cur_eqd = rx_max; - if (rx_eq->cur_eqd < rx_min) - rx_eq->cur_eqd = rx_min; - } else { - if (rx_cur > BE_MAX_EQD) - rx_cur = BE_MAX_EQD; - if (rx_eq->cur_eqd != rx_cur) { - status = be_cmd_modify_eqd(adapter, rx_eq->q.id, - rx_cur); - if (!status) - rx_eq->cur_eqd = rx_cur; - } - } return 0; } @@ -244,32 +256,25 @@ be_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, uint64_t *data) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_drvr_stats *drvr_stats = &adapter->stats.drvr_stats; - struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); - struct be_rxf_stats *rxf_stats = &hw_stats->rxf; - struct be_port_rxf_stats *port_stats = - &rxf_stats->port[adapter->port_num]; - struct net_device_stats *net_stats = &netdev->stats; + struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va); struct be_erx_stats *erx_stats = &hw_stats->erx; + struct be_rx_obj *rxo; void *p = NULL; - int i; + int i, j; for (i = 0; i < ETHTOOL_STATS_NUM; i++) { switch (et_stats[i].type) { case NETSTAT: - p = net_stats; + p = &netdev->stats; break; - case DRVSTAT: - p = drvr_stats; + case DRVSTAT_TX: + p = &adapter->tx_stats; break; case PORTSTAT: - p = port_stats; + p = &hw_stats->rxf.port[adapter->port_num]; break; case MISCSTAT: - p = rxf_stats; - break; - case ERXSTAT: /* Currently only one ERX stat is provided */ - p = (u32 *)erx_stats + adapter->rx_obj.q.id; + p = &hw_stats->rxf; break; } @@ -277,19 +282,44 @@ be_get_ethtool_stats(struct net_device *netdev, data[i] = (et_stats[i].size == sizeof(u64)) ? *(u64 *)p: *(u32 *)p; } + + for_all_rx_queues(adapter, rxo, j) { + for (i = 0; i < ETHTOOL_RXSTATS_NUM; i++) { + switch (et_rx_stats[i].type) { + case DRVSTAT_RX: + p = (u8 *)&rxo->stats + et_rx_stats[i].offset; + break; + case ERXSTAT: + p = (u32 *)erx_stats + rxo->q.id; + break; + } + data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] = + (et_rx_stats[i].size == sizeof(u64)) ? + *(u64 *)p: *(u32 *)p; + } + } } static void be_get_stat_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) { - int i; + struct be_adapter *adapter = netdev_priv(netdev); + int i, j; + switch (stringset) { case ETH_SS_STATS: for (i = 0; i < ETHTOOL_STATS_NUM; i++) { memcpy(data, et_stats[i].desc, ETH_GSTRING_LEN); data += ETH_GSTRING_LEN; } + for (i = 0; i < adapter->num_rx_qs; i++) { + for (j = 0; j < ETHTOOL_RXSTATS_NUM; j++) { + sprintf(data, "rxq%d: %s", i, + et_rx_stats[j].desc); + data += ETH_GSTRING_LEN; + } + } break; case ETH_SS_TEST: for (i = 0; i < ETHTOOL_TESTS_NUM; i++) { @@ -302,11 +332,14 @@ be_get_stat_strings(struct net_device *netdev, uint32_t stringset, static int be_get_sset_count(struct net_device *netdev, int stringset) { + struct be_adapter *adapter = netdev_priv(netdev); + switch (stringset) { case ETH_SS_TEST: return ETHTOOL_TESTS_NUM; case ETH_SS_STATS: - return ETHTOOL_STATS_NUM; + return ETHTOOL_STATS_NUM + + adapter->num_rx_qs * ETHTOOL_RXSTATS_NUM; default: return -EINVAL; } @@ -421,10 +454,10 @@ be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct be_adapter *adapter = netdev_priv(netdev); - ring->rx_max_pending = adapter->rx_obj.q.len; + ring->rx_max_pending = adapter->rx_obj[0].q.len; ring->tx_max_pending = adapter->tx_obj.q.len; - ring->rx_pending = atomic_read(&adapter->rx_obj.q.used); + ring->rx_pending = atomic_read(&adapter->rx_obj[0].q.used); ring->tx_pending = atomic_read(&adapter->tx_obj.q.used); } diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 6eda7a02225623943a35293cada545b8d20d752b..45b1f6635282f8cc3bb07098f92d119b4e54f16e 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -32,6 +32,10 @@ module_param(num_vfs, uint, S_IRUGO); MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); +static bool multi_rxq = true; +module_param(multi_rxq, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(multi_rxq, "Multi Rx Queue support. Enabled by default"); + static DEFINE_PCI_DEVICE_TABLE(be_dev_ids) = { { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID2) }, @@ -111,6 +115,11 @@ static char *ue_status_hi_desc[] = { "Unknown" }; +static inline bool be_multi_rxq(struct be_adapter *adapter) +{ + return (adapter->num_rx_qs > 1); +} + static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q) { struct be_dma_mem *mem = &q->dma_mem; @@ -236,18 +245,27 @@ static int be_mac_addr_set(struct net_device *netdev, void *p) void netdev_stats_update(struct be_adapter *adapter) { - struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats.cmd.va); + struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va); struct be_rxf_stats *rxf_stats = &hw_stats->rxf; struct be_port_rxf_stats *port_stats = &rxf_stats->port[adapter->port_num]; struct net_device_stats *dev_stats = &adapter->netdev->stats; struct be_erx_stats *erx_stats = &hw_stats->erx; + struct be_rx_obj *rxo; + int i; + + memset(dev_stats, 0, sizeof(*dev_stats)); + for_all_rx_queues(adapter, rxo, i) { + dev_stats->rx_packets += rx_stats(rxo)->rx_pkts; + dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes; + dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts; + /* no space in linux buffers: best possible approximation */ + dev_stats->rx_dropped += + erx_stats->rx_drops_no_fragments[rxo->q.id]; + } - dev_stats->rx_packets = drvr_stats(adapter)->be_rx_pkts; - dev_stats->tx_packets = drvr_stats(adapter)->be_tx_pkts; - dev_stats->rx_bytes = drvr_stats(adapter)->be_rx_bytes; - dev_stats->tx_bytes = drvr_stats(adapter)->be_tx_bytes; - dev_stats->multicast = drvr_stats(adapter)->be_rx_mcast_pkt; + dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts; + dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes; /* bad pkts received */ dev_stats->rx_errors = port_stats->rx_crc_errors + @@ -264,18 +282,11 @@ void netdev_stats_update(struct be_adapter *adapter) port_stats->rx_ip_checksum_errs + port_stats->rx_udp_checksum_errs; - /* no space in linux buffers: best possible approximation */ - dev_stats->rx_dropped = - erx_stats->rx_drops_no_fragments[adapter->rx_obj.q.id]; - /* detailed rx errors */ dev_stats->rx_length_errors = port_stats->rx_in_range_errors + port_stats->rx_out_range_errors + port_stats->rx_frame_too_long; - /* receive ring buffer overflow */ - dev_stats->rx_over_errors = 0; - dev_stats->rx_crc_errors = port_stats->rx_crc_errors; /* frame alignment errors */ @@ -286,23 +297,6 @@ void netdev_stats_update(struct be_adapter *adapter) dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow + port_stats->rx_input_fifo_overflow + rxf_stats->rx_drops_no_pbuf; - /* receiver missed packetd */ - dev_stats->rx_missed_errors = 0; - - /* packet transmit problems */ - dev_stats->tx_errors = 0; - - /* no space available in linux */ - dev_stats->tx_dropped = 0; - - dev_stats->collisions = 0; - - /* detailed tx_errors */ - dev_stats->tx_aborted_errors = 0; - dev_stats->tx_carrier_errors = 0; - dev_stats->tx_fifo_errors = 0; - dev_stats->tx_heartbeat_errors = 0; - dev_stats->tx_window_errors = 0; } void be_link_status_update(struct be_adapter *adapter, bool link_up) @@ -326,10 +320,10 @@ void be_link_status_update(struct be_adapter *adapter, bool link_up) } /* Update the EQ delay n BE based on the RX frags consumed / sec */ -static void be_rx_eqd_update(struct be_adapter *adapter) +static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo) { - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_drvr_stats *stats = &adapter->stats.drvr_stats; + struct be_eq_obj *rx_eq = &rxo->rx_eq; + struct be_rx_stats *stats = &rxo->stats; ulong now = jiffies; u32 eqd; @@ -346,12 +340,12 @@ static void be_rx_eqd_update(struct be_adapter *adapter) if ((now - stats->rx_fps_jiffies) < HZ) return; - stats->be_rx_fps = (stats->be_rx_frags - stats->be_prev_rx_frags) / + stats->rx_fps = (stats->rx_frags - stats->prev_rx_frags) / ((now - stats->rx_fps_jiffies) / HZ); stats->rx_fps_jiffies = now; - stats->be_prev_rx_frags = stats->be_rx_frags; - eqd = stats->be_rx_fps / 110000; + stats->prev_rx_frags = stats->rx_frags; + eqd = stats->rx_fps / 110000; eqd = eqd << 3; if (eqd > rx_eq->max_eqd) eqd = rx_eq->max_eqd; @@ -365,11 +359,6 @@ static void be_rx_eqd_update(struct be_adapter *adapter) rx_eq->cur_eqd = eqd; } -static struct net_device_stats *be_get_stats(struct net_device *dev) -{ - return &dev->stats; -} - static u32 be_calc_rate(u64 bytes, unsigned long ticks) { u64 rate = bytes; @@ -383,7 +372,7 @@ static u32 be_calc_rate(u64 bytes, unsigned long ticks) static void be_tx_rate_update(struct be_adapter *adapter) { - struct be_drvr_stats *stats = drvr_stats(adapter); + struct be_tx_stats *stats = tx_stats(adapter); ulong now = jiffies; /* Wrapped around? */ @@ -405,7 +394,7 @@ static void be_tx_rate_update(struct be_adapter *adapter) static void be_tx_stats_update(struct be_adapter *adapter, u32 wrb_cnt, u32 copied, u32 gso_segs, bool stopped) { - struct be_drvr_stats *stats = drvr_stats(adapter); + struct be_tx_stats *stats = tx_stats(adapter); stats->be_tx_reqs++; stats->be_tx_wrbs += wrb_cnt; stats->be_tx_bytes += copied; @@ -440,9 +429,12 @@ static inline void wrb_fill(struct be_eth_wrb *wrb, u64 addr, int len) wrb->frag_len = len & ETH_WRB_FRAG_LEN_MASK; } -static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, - bool vlan, u32 wrb_cnt, u32 len) +static void wrb_fill_hdr(struct be_adapter *adapter, struct be_eth_hdr_wrb *hdr, + struct sk_buff *skb, u32 wrb_cnt, u32 len) { + u8 vlan_prio = 0; + u16 vlan_tag = 0; + memset(hdr, 0, sizeof(*hdr)); AMAP_SET_BITS(struct amap_eth_hdr_wrb, crc, hdr, 1); @@ -460,10 +452,15 @@ static void wrb_fill_hdr(struct be_eth_hdr_wrb *hdr, struct sk_buff *skb, AMAP_SET_BITS(struct amap_eth_hdr_wrb, udpcs, hdr, 1); } - if (vlan && vlan_tx_tag_present(skb)) { + if (adapter->vlan_grp && vlan_tx_tag_present(skb)) { AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan, hdr, 1); - AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, - hdr, vlan_tx_tag_get(skb)); + vlan_tag = vlan_tx_tag_get(skb); + vlan_prio = (vlan_tag & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT; + /* If vlan priority provided by OS is NOT in available bmap */ + if (!(adapter->vlan_prio_bmap & (1 << vlan_prio))) + vlan_tag = (vlan_tag & ~VLAN_PRIO_MASK) | + adapter->recommended_prio; + AMAP_SET_BITS(struct amap_eth_hdr_wrb, vlan_tag, hdr, vlan_tag); } AMAP_SET_BITS(struct amap_eth_hdr_wrb, event, hdr, 1); @@ -543,8 +540,7 @@ static int make_tx_wrbs(struct be_adapter *adapter, queue_head_inc(txq); } - wrb_fill_hdr(hdr, first_skb, adapter->vlan_grp ? true : false, - wrb_cnt, copied); + wrb_fill_hdr(adapter, hdr, first_skb, wrb_cnt, copied); be_dws_cpu_to_le(hdr, sizeof(*hdr)); return copied; @@ -637,7 +633,7 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) if (adapter->vlans_added <= adapter->max_vlans) { /* Construct VLAN Table to give to HW */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { if (adapter->vlan_tag[i]) { vtag[ntags] = cpu_to_le16(i); ntags++; @@ -656,14 +652,8 @@ static int be_vid_config(struct be_adapter *adapter, bool vf, u32 vf_num) static void be_vlan_register(struct net_device *netdev, struct vlan_group *grp) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; - struct be_eq_obj *tx_eq = &adapter->tx_eq; - be_eq_notify(adapter, rx_eq->q.id, false, false, 0); - be_eq_notify(adapter, tx_eq->q.id, false, false, 0); adapter->vlan_grp = grp; - be_eq_notify(adapter, rx_eq->q.id, true, false, 0); - be_eq_notify(adapter, tx_eq->q.id, true, false, 0); } static void be_vlan_add_vid(struct net_device *netdev, u16 vid) @@ -825,40 +815,38 @@ static int be_set_vf_tx_rate(struct net_device *netdev, return status; } -static void be_rx_rate_update(struct be_adapter *adapter) +static void be_rx_rate_update(struct be_rx_obj *rxo) { - struct be_drvr_stats *stats = drvr_stats(adapter); + struct be_rx_stats *stats = &rxo->stats; ulong now = jiffies; /* Wrapped around */ - if (time_before(now, stats->be_rx_jiffies)) { - stats->be_rx_jiffies = now; + if (time_before(now, stats->rx_jiffies)) { + stats->rx_jiffies = now; return; } /* Update the rate once in two seconds */ - if ((now - stats->be_rx_jiffies) < 2 * HZ) + if ((now - stats->rx_jiffies) < 2 * HZ) return; - stats->be_rx_rate = be_calc_rate(stats->be_rx_bytes - - stats->be_rx_bytes_prev, - now - stats->be_rx_jiffies); - stats->be_rx_jiffies = now; - stats->be_rx_bytes_prev = stats->be_rx_bytes; + stats->rx_rate = be_calc_rate(stats->rx_bytes - stats->rx_bytes_prev, + now - stats->rx_jiffies); + stats->rx_jiffies = now; + stats->rx_bytes_prev = stats->rx_bytes; } -static void be_rx_stats_update(struct be_adapter *adapter, +static void be_rx_stats_update(struct be_rx_obj *rxo, u32 pktsize, u16 numfrags, u8 pkt_type) { - struct be_drvr_stats *stats = drvr_stats(adapter); - - stats->be_rx_compl++; - stats->be_rx_frags += numfrags; - stats->be_rx_bytes += pktsize; - stats->be_rx_pkts++; + struct be_rx_stats *stats = &rxo->stats; + stats->rx_compl++; + stats->rx_frags += numfrags; + stats->rx_bytes += pktsize; + stats->rx_pkts++; if (pkt_type == BE_MULTICAST_PACKET) - stats->be_rx_mcast_pkt++; + stats->rx_mcast_pkts++; } static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) @@ -878,12 +866,14 @@ static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso) } static struct be_rx_page_info * -get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) +get_rx_page_info(struct be_adapter *adapter, + struct be_rx_obj *rxo, + u16 frag_idx) { struct be_rx_page_info *rx_page_info; - struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_queue_info *rxq = &rxo->q; - rx_page_info = &adapter->rx_obj.page_info_tbl[frag_idx]; + rx_page_info = &rxo->page_info_tbl[frag_idx]; BUG_ON(!rx_page_info->page); if (rx_page_info->last_page_user) { @@ -898,9 +888,10 @@ get_rx_page_info(struct be_adapter *adapter, u16 frag_idx) /* Throwaway the data in the Rx completion */ static void be_rx_compl_discard(struct be_adapter *adapter, - struct be_eth_rx_compl *rxcp) + struct be_rx_obj *rxo, + struct be_eth_rx_compl *rxcp) { - struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_queue_info *rxq = &rxo->q; struct be_rx_page_info *page_info; u16 rxq_idx, i, num_rcvd; @@ -908,7 +899,7 @@ static void be_rx_compl_discard(struct be_adapter *adapter, num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); for (i = 0; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxq_idx); put_page(page_info->page); memset(page_info, 0, sizeof(*page_info)); index_inc(&rxq_idx, rxq->len); @@ -919,11 +910,11 @@ static void be_rx_compl_discard(struct be_adapter *adapter, * skb_fill_rx_data forms a complete skb for an ether frame * indicated by rxcp. */ -static void skb_fill_rx_data(struct be_adapter *adapter, +static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, struct sk_buff *skb, struct be_eth_rx_compl *rxcp, u16 num_rcvd) { - struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_queue_info *rxq = &rxo->q; struct be_rx_page_info *page_info; u16 rxq_idx, i, j; u32 pktsize, hdr_len, curr_frag_len, size; @@ -934,7 +925,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); - page_info = get_rx_page_info(adapter, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxq_idx); start = page_address(page_info->page) + page_info->page_offset; prefetch(start); @@ -972,7 +963,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, for (i = 1, j = 0; i < num_rcvd; i++) { size -= curr_frag_len; index_inc(&rxq_idx, rxq->len); - page_info = get_rx_page_info(adapter, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxq_idx); curr_frag_len = min(size, rx_frag_size); @@ -998,11 +989,12 @@ static void skb_fill_rx_data(struct be_adapter *adapter, BUG_ON(j > MAX_SKB_FRAGS); done: - be_rx_stats_update(adapter, pktsize, num_rcvd, pkt_type); + be_rx_stats_update(rxo, pktsize, num_rcvd, pkt_type); } /* Process the RX completion indicated by rxcp when GRO is disabled */ static void be_rx_compl_process(struct be_adapter *adapter, + struct be_rx_obj *rxo, struct be_eth_rx_compl *rxcp) { struct sk_buff *skb; @@ -1019,14 +1011,14 @@ static void be_rx_compl_process(struct be_adapter *adapter, if (unlikely(!skb)) { if (net_ratelimit()) dev_warn(&adapter->pdev->dev, "skb alloc failed\n"); - be_rx_compl_discard(adapter, rxcp); + be_rx_compl_discard(adapter, rxo, rxcp); return; } - skb_fill_rx_data(adapter, skb, rxcp, num_rcvd); + skb_fill_rx_data(adapter, rxo, skb, rxcp, num_rcvd); if (do_pkt_csum(rxcp, adapter->rx_csum)) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); else skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -1056,12 +1048,13 @@ static void be_rx_compl_process(struct be_adapter *adapter, /* Process the RX completion indicated by rxcp when GRO is enabled */ static void be_rx_compl_process_gro(struct be_adapter *adapter, - struct be_eth_rx_compl *rxcp) + struct be_rx_obj *rxo, + struct be_eth_rx_compl *rxcp) { struct be_rx_page_info *page_info; struct sk_buff *skb = NULL; - struct be_queue_info *rxq = &adapter->rx_obj.q; - struct be_eq_obj *eq_obj = &adapter->rx_eq; + struct be_queue_info *rxq = &rxo->q; + struct be_eq_obj *eq_obj = &rxo->rx_eq; u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; u16 i, rxq_idx = 0, vid, j; u8 vtm; @@ -1085,13 +1078,13 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, skb = napi_get_frags(&eq_obj->napi); if (!skb) { - be_rx_compl_discard(adapter, rxcp); + be_rx_compl_discard(adapter, rxo, rxcp); return; } remaining = pkt_size; for (i = 0, j = -1; i < num_rcvd; i++) { - page_info = get_rx_page_info(adapter, rxq_idx); + page_info = get_rx_page_info(adapter, rxo, rxq_idx); curr_frag_len = min(remaining, rx_frag_size); @@ -1132,12 +1125,12 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); } - be_rx_stats_update(adapter, pkt_size, num_rcvd, pkt_type); + be_rx_stats_update(rxo, pkt_size, num_rcvd, pkt_type); } -static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) +static struct be_eth_rx_compl *be_rx_compl_get(struct be_rx_obj *rxo) { - struct be_eth_rx_compl *rxcp = queue_tail_node(&adapter->rx_obj.cq); + struct be_eth_rx_compl *rxcp = queue_tail_node(&rxo->cq); if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0) return NULL; @@ -1145,7 +1138,7 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter) rmb(); be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); - queue_tail_inc(&adapter->rx_obj.cq); + queue_tail_inc(&rxo->cq); return rxcp; } @@ -1171,22 +1164,23 @@ static inline struct page *be_alloc_pages(u32 size) * Allocate a page, split it to fragments of size rx_frag_size and post as * receive buffers to BE */ -static void be_post_rx_frags(struct be_adapter *adapter) +static void be_post_rx_frags(struct be_rx_obj *rxo) { - struct be_rx_page_info *page_info_tbl = adapter->rx_obj.page_info_tbl; + struct be_adapter *adapter = rxo->adapter; + struct be_rx_page_info *page_info_tbl = rxo->page_info_tbl; struct be_rx_page_info *page_info = NULL, *prev_page_info = NULL; - struct be_queue_info *rxq = &adapter->rx_obj.q; + struct be_queue_info *rxq = &rxo->q; struct page *pagep = NULL; struct be_eth_rx_d *rxd; u64 page_dmaaddr = 0, frag_dmaaddr; u32 posted, page_offset = 0; - page_info = &page_info_tbl[rxq->head]; + page_info = &rxo->page_info_tbl[rxq->head]; for (posted = 0; posted < MAX_RX_POST && !page_info->page; posted++) { if (!pagep) { pagep = be_alloc_pages(adapter->big_page_size); if (unlikely(!pagep)) { - drvr_stats(adapter)->be_ethrx_post_fail++; + rxo->stats.rx_post_fail++; break; } page_dmaaddr = pci_map_page(adapter->pdev, pagep, 0, @@ -1225,7 +1219,7 @@ static void be_post_rx_frags(struct be_adapter *adapter) be_rxq_notify(adapter, rxq->id, posted); } else if (atomic_read(&rxq->used) == 0) { /* Let be_worker replenish when memory is available */ - adapter->rx_post_starved = true; + rxo->rx_post_starved = true; } } @@ -1328,17 +1322,17 @@ static void be_eq_clean(struct be_adapter *adapter, be_eq_notify(adapter, eq_obj->q.id, false, true, num); } -static void be_rx_q_clean(struct be_adapter *adapter) +static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo) { struct be_rx_page_info *page_info; - struct be_queue_info *rxq = &adapter->rx_obj.q; - struct be_queue_info *rx_cq = &adapter->rx_obj.cq; + struct be_queue_info *rxq = &rxo->q; + struct be_queue_info *rx_cq = &rxo->cq; struct be_eth_rx_compl *rxcp; u16 tail; /* First cleanup pending rx completions */ - while ((rxcp = be_rx_compl_get(adapter)) != NULL) { - be_rx_compl_discard(adapter, rxcp); + while ((rxcp = be_rx_compl_get(rxo)) != NULL) { + be_rx_compl_discard(adapter, rxo, rxcp); be_rx_compl_reset(rxcp); be_cq_notify(adapter, rx_cq->id, true, 1); } @@ -1346,7 +1340,7 @@ static void be_rx_q_clean(struct be_adapter *adapter) /* Then free posted rx buffer that were not used */ tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len; for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) { - page_info = get_rx_page_info(adapter, tail); + page_info = get_rx_page_info(adapter, rxo, tail); put_page(page_info->page); memset(page_info, 0, sizeof(*page_info)); } @@ -1524,92 +1518,101 @@ static int be_tx_queues_create(struct be_adapter *adapter) static void be_rx_queues_destroy(struct be_adapter *adapter) { struct be_queue_info *q; - - q = &adapter->rx_obj.q; - if (q->created) { - be_cmd_q_destroy(adapter, q, QTYPE_RXQ); - - /* After the rxq is invalidated, wait for a grace time - * of 1ms for all dma to end and the flush compl to arrive - */ - mdelay(1); - be_rx_q_clean(adapter); + struct be_rx_obj *rxo; + int i; + + for_all_rx_queues(adapter, rxo, i) { + q = &rxo->q; + if (q->created) { + be_cmd_q_destroy(adapter, q, QTYPE_RXQ); + /* After the rxq is invalidated, wait for a grace time + * of 1ms for all dma to end and the flush compl to + * arrive + */ + mdelay(1); + be_rx_q_clean(adapter, rxo); + } + be_queue_free(adapter, q); + + q = &rxo->cq; + if (q->created) + be_cmd_q_destroy(adapter, q, QTYPE_CQ); + be_queue_free(adapter, q); + + /* Clear any residual events */ + q = &rxo->rx_eq.q; + if (q->created) { + be_eq_clean(adapter, &rxo->rx_eq); + be_cmd_q_destroy(adapter, q, QTYPE_EQ); + } + be_queue_free(adapter, q); } - be_queue_free(adapter, q); - - q = &adapter->rx_obj.cq; - if (q->created) - be_cmd_q_destroy(adapter, q, QTYPE_CQ); - be_queue_free(adapter, q); - - /* Clear any residual events */ - be_eq_clean(adapter, &adapter->rx_eq); - - q = &adapter->rx_eq.q; - if (q->created) - be_cmd_q_destroy(adapter, q, QTYPE_EQ); - be_queue_free(adapter, q); } static int be_rx_queues_create(struct be_adapter *adapter) { struct be_queue_info *eq, *q, *cq; - int rc; + struct be_rx_obj *rxo; + int rc, i; adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE; - adapter->rx_eq.max_eqd = BE_MAX_EQD; - adapter->rx_eq.min_eqd = 0; - adapter->rx_eq.cur_eqd = 0; - adapter->rx_eq.enable_aic = true; - - /* Alloc Rx Event queue */ - eq = &adapter->rx_eq.q; - rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, - sizeof(struct be_eq_entry)); - if (rc) - return rc; - - /* Ask BE to create Rx Event queue */ - rc = be_cmd_eq_create(adapter, eq, adapter->rx_eq.cur_eqd); - if (rc) - goto rx_eq_free; - - /* Alloc RX eth compl queue */ - cq = &adapter->rx_obj.cq; - rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, - sizeof(struct be_eth_rx_compl)); - if (rc) - goto rx_eq_destroy; - - /* Ask BE to create Rx eth compl queue */ - rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); - if (rc) - goto rx_cq_free; - - /* Alloc RX eth queue */ - q = &adapter->rx_obj.q; - rc = be_queue_alloc(adapter, q, RX_Q_LEN, sizeof(struct be_eth_rx_d)); - if (rc) - goto rx_cq_destroy; - - /* Ask BE to create Rx eth queue */ - rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size, - BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, false); - if (rc) - goto rx_q_free; + for_all_rx_queues(adapter, rxo, i) { + rxo->adapter = adapter; + rxo->rx_eq.max_eqd = BE_MAX_EQD; + rxo->rx_eq.enable_aic = true; + + /* EQ */ + eq = &rxo->rx_eq.q; + rc = be_queue_alloc(adapter, eq, EVNT_Q_LEN, + sizeof(struct be_eq_entry)); + if (rc) + goto err; + + rc = be_cmd_eq_create(adapter, eq, rxo->rx_eq.cur_eqd); + if (rc) + goto err; + + /* CQ */ + cq = &rxo->cq; + rc = be_queue_alloc(adapter, cq, RX_CQ_LEN, + sizeof(struct be_eth_rx_compl)); + if (rc) + goto err; + + rc = be_cmd_cq_create(adapter, cq, eq, false, false, 3); + if (rc) + goto err; + + /* Rx Q */ + q = &rxo->q; + rc = be_queue_alloc(adapter, q, RX_Q_LEN, + sizeof(struct be_eth_rx_d)); + if (rc) + goto err; + + rc = be_cmd_rxq_create(adapter, q, cq->id, rx_frag_size, + BE_MAX_JUMBO_FRAME_SIZE, adapter->if_handle, + (i > 0) ? 1 : 0/* rss enable */, &rxo->rss_id); + if (rc) + goto err; + } + + if (be_multi_rxq(adapter)) { + u8 rsstable[MAX_RSS_QS]; + + for_all_rss_queues(adapter, rxo, i) + rsstable[i] = rxo->rss_id; + + rc = be_cmd_rss_config(adapter, rsstable, + adapter->num_rx_qs - 1); + if (rc) + goto err; + } return 0; -rx_q_free: - be_queue_free(adapter, q); -rx_cq_destroy: - be_cmd_q_destroy(adapter, cq, QTYPE_CQ); -rx_cq_free: - be_queue_free(adapter, cq); -rx_eq_destroy: - be_cmd_q_destroy(adapter, eq, QTYPE_EQ); -rx_eq_free: - be_queue_free(adapter, eq); - return rc; +err: + be_rx_queues_destroy(adapter); + return -1; } /* There are 8 evt ids per func. Retruns the evt id's bit number */ @@ -1621,24 +1624,31 @@ static inline int be_evt_bit_get(struct be_adapter *adapter, u32 eq_id) static irqreturn_t be_intx(int irq, void *dev) { struct be_adapter *adapter = dev; - int isr; + struct be_rx_obj *rxo; + int isr, i; isr = ioread32(adapter->csr + CEV_ISR0_OFFSET + (adapter->tx_eq.q.id/ 8) * CEV_ISR_SIZE); if (!isr) return IRQ_NONE; - event_handle(adapter, &adapter->tx_eq); - event_handle(adapter, &adapter->rx_eq); + if ((1 << be_evt_bit_get(adapter, adapter->tx_eq.q.id) & isr)) + event_handle(adapter, &adapter->tx_eq); + + for_all_rx_queues(adapter, rxo, i) { + if ((1 << be_evt_bit_get(adapter, rxo->rx_eq.q.id) & isr)) + event_handle(adapter, &rxo->rx_eq); + } return IRQ_HANDLED; } static irqreturn_t be_msix_rx(int irq, void *dev) { - struct be_adapter *adapter = dev; + struct be_rx_obj *rxo = dev; + struct be_adapter *adapter = rxo->adapter; - event_handle(adapter, &adapter->rx_eq); + event_handle(adapter, &rxo->rx_eq); return IRQ_HANDLED; } @@ -1652,14 +1662,14 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev) return IRQ_HANDLED; } -static inline bool do_gro(struct be_adapter *adapter, +static inline bool do_gro(struct be_adapter *adapter, struct be_rx_obj *rxo, struct be_eth_rx_compl *rxcp) { int err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); if (err) - drvr_stats(adapter)->be_rxcp_err++; + rxo->stats.rxcp_err++; return (tcp_frame && !err) ? true : false; } @@ -1667,29 +1677,29 @@ static inline bool do_gro(struct be_adapter *adapter, int be_poll_rx(struct napi_struct *napi, int budget) { struct be_eq_obj *rx_eq = container_of(napi, struct be_eq_obj, napi); - struct be_adapter *adapter = - container_of(rx_eq, struct be_adapter, rx_eq); - struct be_queue_info *rx_cq = &adapter->rx_obj.cq; + struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq); + struct be_adapter *adapter = rxo->adapter; + struct be_queue_info *rx_cq = &rxo->cq; struct be_eth_rx_compl *rxcp; u32 work_done; - adapter->stats.drvr_stats.be_rx_polls++; + rxo->stats.rx_polls++; for (work_done = 0; work_done < budget; work_done++) { - rxcp = be_rx_compl_get(adapter); + rxcp = be_rx_compl_get(rxo); if (!rxcp) break; - if (do_gro(adapter, rxcp)) - be_rx_compl_process_gro(adapter, rxcp); + if (do_gro(adapter, rxo, rxcp)) + be_rx_compl_process_gro(adapter, rxo, rxcp); else - be_rx_compl_process(adapter, rxcp); + be_rx_compl_process(adapter, rxo, rxcp); be_rx_compl_reset(rxcp); } /* Refill the queue */ - if (atomic_read(&adapter->rx_obj.q.used) < RX_FRAGS_REFILL_WM) - be_post_rx_frags(adapter); + if (atomic_read(&rxo->q.used) < RX_FRAGS_REFILL_WM) + be_post_rx_frags(rxo); /* All consumed */ if (work_done < budget) { @@ -1743,8 +1753,8 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget) netif_wake_queue(adapter->netdev); } - drvr_stats(adapter)->be_tx_events++; - drvr_stats(adapter)->be_tx_compl += tx_compl; + tx_stats(adapter)->be_tx_events++; + tx_stats(adapter)->be_tx_compl += tx_compl; } return 1; @@ -1793,20 +1803,24 @@ static void be_worker(struct work_struct *work) { struct be_adapter *adapter = container_of(work, struct be_adapter, work.work); + struct be_rx_obj *rxo; + int i; if (!adapter->stats_ioctl_sent) - be_cmd_get_stats(adapter, &adapter->stats.cmd); - - /* Set EQ delay */ - be_rx_eqd_update(adapter); + be_cmd_get_stats(adapter, &adapter->stats_cmd); be_tx_rate_update(adapter); - be_rx_rate_update(adapter); - if (adapter->rx_post_starved) { - adapter->rx_post_starved = false; - be_post_rx_frags(adapter); + for_all_rx_queues(adapter, rxo, i) { + be_rx_rate_update(rxo); + be_rx_eqd_update(adapter, rxo); + + if (rxo->rx_post_starved) { + rxo->rx_post_starved = false; + be_post_rx_frags(rxo); + } } + if (!adapter->ue_detected) be_detect_dump_ue(adapter); @@ -1821,17 +1835,45 @@ static void be_msix_disable(struct be_adapter *adapter) } } +static int be_num_rxqs_get(struct be_adapter *adapter) +{ + if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) && + !adapter->sriov_enabled && !(adapter->function_mode & 0x400)) { + return 1 + MAX_RSS_QS; /* one default non-RSS queue */ + } else { + dev_warn(&adapter->pdev->dev, + "No support for multiple RX queues\n"); + return 1; + } +} + static void be_msix_enable(struct be_adapter *adapter) { +#define BE_MIN_MSIX_VECTORS (1 + 1) /* Rx + Tx */ int i, status; - for (i = 0; i < BE_NUM_MSIX_VECTORS; i++) + adapter->num_rx_qs = be_num_rxqs_get(adapter); + + for (i = 0; i < (adapter->num_rx_qs + 1); i++) adapter->msix_entries[i].entry = i; status = pci_enable_msix(adapter->pdev, adapter->msix_entries, - BE_NUM_MSIX_VECTORS); - if (status == 0) - adapter->msix_enabled = true; + adapter->num_rx_qs + 1); + if (status == 0) { + goto done; + } else if (status >= BE_MIN_MSIX_VECTORS) { + if (pci_enable_msix(adapter->pdev, adapter->msix_entries, + status) == 0) { + adapter->num_rx_qs = status - 1; + dev_warn(&adapter->pdev->dev, + "Could alloc only %d MSIx vectors. " + "Using %d RX Qs\n", status, adapter->num_rx_qs); + goto done; + } + } + return; +done: + adapter->msix_enabled = true; } static void be_sriov_enable(struct be_adapter *adapter) @@ -1865,38 +1907,50 @@ static inline int be_msix_vec_get(struct be_adapter *adapter, u32 eq_id) static int be_request_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj, - void *handler, char *desc) + void *handler, char *desc, void *context) { struct net_device *netdev = adapter->netdev; int vec; sprintf(eq_obj->desc, "%s-%s", netdev->name, desc); vec = be_msix_vec_get(adapter, eq_obj->q.id); - return request_irq(vec, handler, 0, eq_obj->desc, adapter); + return request_irq(vec, handler, 0, eq_obj->desc, context); } -static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj) +static void be_free_irq(struct be_adapter *adapter, struct be_eq_obj *eq_obj, + void *context) { int vec = be_msix_vec_get(adapter, eq_obj->q.id); - free_irq(vec, adapter); + free_irq(vec, context); } static int be_msix_register(struct be_adapter *adapter) { - int status; + struct be_rx_obj *rxo; + int status, i; + char qname[10]; - status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx"); + status = be_request_irq(adapter, &adapter->tx_eq, be_msix_tx_mcc, "tx", + adapter); if (status) goto err; - status = be_request_irq(adapter, &adapter->rx_eq, be_msix_rx, "rx"); - if (status) - goto free_tx_irq; + for_all_rx_queues(adapter, rxo, i) { + sprintf(qname, "rxq%d", i); + status = be_request_irq(adapter, &rxo->rx_eq, be_msix_rx, + qname, rxo); + if (status) + goto err_msix; + } return 0; -free_tx_irq: - be_free_irq(adapter, &adapter->tx_eq); +err_msix: + be_free_irq(adapter, &adapter->tx_eq, adapter); + + for (i--, rxo = &adapter->rx_obj[i]; i >= 0; i--, rxo--) + be_free_irq(adapter, &rxo->rx_eq, rxo); + err: dev_warn(&adapter->pdev->dev, "MSIX Request IRQ failed - err %d\n", status); @@ -1936,6 +1990,8 @@ static int be_irq_register(struct be_adapter *adapter) static void be_irq_unregister(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; + struct be_rx_obj *rxo; + int i; if (!adapter->isr_registered) return; @@ -1947,8 +2003,11 @@ static void be_irq_unregister(struct be_adapter *adapter) } /* MSIx */ - be_free_irq(adapter, &adapter->tx_eq); - be_free_irq(adapter, &adapter->rx_eq); + be_free_irq(adapter, &adapter->tx_eq, adapter); + + for_all_rx_queues(adapter, rxo, i) + be_free_irq(adapter, &rxo->rx_eq, rxo); + done: adapter->isr_registered = false; } @@ -1956,9 +2015,9 @@ static void be_irq_unregister(struct be_adapter *adapter) static int be_close(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; + struct be_rx_obj *rxo; struct be_eq_obj *tx_eq = &adapter->tx_eq; - int vec; + int vec, i; cancel_delayed_work_sync(&adapter->work); @@ -1973,14 +2032,19 @@ static int be_close(struct net_device *netdev) if (adapter->msix_enabled) { vec = be_msix_vec_get(adapter, tx_eq->q.id); synchronize_irq(vec); - vec = be_msix_vec_get(adapter, rx_eq->q.id); - synchronize_irq(vec); + + for_all_rx_queues(adapter, rxo, i) { + vec = be_msix_vec_get(adapter, rxo->rx_eq.q.id); + synchronize_irq(vec); + } } else { synchronize_irq(netdev->irq); } be_irq_unregister(adapter); - napi_disable(&rx_eq->napi); + for_all_rx_queues(adapter, rxo, i) + napi_disable(&rxo->rx_eq.napi); + napi_disable(&tx_eq->napi); /* Wait for all pending tx completions to arrive so that @@ -1994,17 +2058,17 @@ static int be_close(struct net_device *netdev) static int be_open(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); - struct be_eq_obj *rx_eq = &adapter->rx_eq; struct be_eq_obj *tx_eq = &adapter->tx_eq; + struct be_rx_obj *rxo; bool link_up; - int status; + int status, i; u8 mac_speed; u16 link_speed; - /* First time posting */ - be_post_rx_frags(adapter); - - napi_enable(&rx_eq->napi); + for_all_rx_queues(adapter, rxo, i) { + be_post_rx_frags(rxo); + napi_enable(&rxo->rx_eq.napi); + } napi_enable(&tx_eq->napi); be_irq_register(adapter); @@ -2012,12 +2076,12 @@ static int be_open(struct net_device *netdev) be_intr_set(adapter, true); /* The evt queues are created in unarmed state; arm them */ - be_eq_notify(adapter, rx_eq->q.id, true, false, 0); + for_all_rx_queues(adapter, rxo, i) { + be_eq_notify(adapter, rxo->rx_eq.q.id, true, false, 0); + be_cq_notify(adapter, rxo->cq.id, true, 0); + } be_eq_notify(adapter, tx_eq->q.id, true, false, 0); - /* Rx compl queue may be in unarmed state; rearm it */ - be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0); - /* Now that interrupts are on we can process async mcc */ be_async_mcc_enable(adapter); @@ -2084,6 +2148,47 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) return status; } +/* + * Generate a seed MAC address from the PF MAC Address using jhash. + * MAC Address for VFs are assigned incrementally starting from the seed. + * These addresses are programmed in the ASIC by the PF and the VF driver + * queries for the MAC address during its probe. + */ +static inline int be_vf_eth_addr_config(struct be_adapter *adapter) +{ + u32 vf = 0; + int status = 0; + u8 mac[ETH_ALEN]; + + be_vf_eth_addr_generate(adapter, mac); + + for (vf = 0; vf < num_vfs; vf++) { + status = be_cmd_pmac_add(adapter, mac, + adapter->vf_cfg[vf].vf_if_handle, + &adapter->vf_cfg[vf].vf_pmac_id); + if (status) + dev_err(&adapter->pdev->dev, + "Mac address add failed for VF %d\n", vf); + else + memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN); + + mac[5] += 1; + } + return status; +} + +static inline void be_vf_eth_addr_rem(struct be_adapter *adapter) +{ + u32 vf; + + for (vf = 0; vf < num_vfs; vf++) { + if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) + be_cmd_pmac_del(adapter, + adapter->vf_cfg[vf].vf_if_handle, + adapter->vf_cfg[vf].vf_pmac_id); + } +} + static int be_setup(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -2098,6 +2203,11 @@ static int be_setup(struct be_adapter *adapter) BE_IF_FLAGS_PROMISCUOUS | BE_IF_FLAGS_PASS_L3L4_ERRORS; en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS; + + if (be_multi_rxq(adapter)) { + cap_flags |= BE_IF_FLAGS_RSS; + en_flags |= BE_IF_FLAGS_RSS; + } } status = be_cmd_if_create(adapter, cap_flags, en_flags, @@ -2143,10 +2253,20 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto rx_qs_destroy; + if (be_physfn(adapter)) { + status = be_vf_eth_addr_config(adapter); + if (status) + goto mcc_q_destroy; + } + adapter->link_speed = -1; return 0; +mcc_q_destroy: + if (be_physfn(adapter)) + be_vf_eth_addr_rem(adapter); + be_mcc_queues_destroy(adapter); rx_qs_destroy: be_rx_queues_destroy(adapter); tx_qs_destroy: @@ -2163,6 +2283,9 @@ static int be_setup(struct be_adapter *adapter) static int be_clear(struct be_adapter *adapter) { + if (be_physfn(adapter)) + be_vf_eth_addr_rem(adapter); + be_mcc_queues_destroy(adapter); be_rx_queues_destroy(adapter); be_tx_queues_destroy(adapter); @@ -2390,7 +2513,6 @@ static struct net_device_ops be_netdev_ops = { .ndo_open = be_open, .ndo_stop = be_close, .ndo_start_xmit = be_xmit, - .ndo_get_stats = be_get_stats, .ndo_set_rx_mode = be_set_multicast_list, .ndo_set_mac_address = be_mac_addr_set, .ndo_change_mtu = be_change_mtu, @@ -2407,6 +2529,8 @@ static struct net_device_ops be_netdev_ops = { static void be_netdev_init(struct net_device *netdev) { struct be_adapter *adapter = netdev_priv(netdev); + struct be_rx_obj *rxo; + int i; netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_HW_CSUM | @@ -2428,8 +2552,10 @@ static void be_netdev_init(struct net_device *netdev) SET_ETHTOOL_OPS(netdev, &be_ethtool_ops); - netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx, - BE_NAPI_WEIGHT); + for_all_rx_queues(adapter, rxo, i) + netif_napi_add(netdev, &rxo->rx_eq.napi, be_poll_rx, + BE_NAPI_WEIGHT); + netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc, BE_NAPI_WEIGHT); @@ -2563,8 +2689,7 @@ static int be_ctrl_init(struct be_adapter *adapter) static void be_stats_cleanup(struct be_adapter *adapter) { - struct be_stats_obj *stats = &adapter->stats; - struct be_dma_mem *cmd = &stats->cmd; + struct be_dma_mem *cmd = &adapter->stats_cmd; if (cmd->va) pci_free_consistent(adapter->pdev, cmd->size, @@ -2573,8 +2698,7 @@ static void be_stats_cleanup(struct be_adapter *adapter) static int be_stats_init(struct be_adapter *adapter) { - struct be_stats_obj *stats = &adapter->stats; - struct be_dma_mem *cmd = &stats->cmd; + struct be_dma_mem *cmd = &adapter->stats_cmd; cmd->size = sizeof(struct be_cmd_req_get_stats); cmd->va = pci_alloc_consistent(adapter->pdev, cmd->size, &cmd->dma); @@ -2619,8 +2743,8 @@ static int be_get_config(struct be_adapter *adapter) if (status) return status; - status = be_cmd_query_fw_cfg(adapter, - &adapter->port_num, &adapter->function_mode); + status = be_cmd_query_fw_cfg(adapter, &adapter->port_num, + &adapter->function_mode, &adapter->function_caps); if (status) return status; @@ -2655,7 +2779,6 @@ static int __devinit be_probe(struct pci_dev *pdev, struct be_adapter *adapter; struct net_device *netdev; - status = pci_enable_device(pdev); if (status) goto do_none; @@ -2688,11 +2811,8 @@ static int __devinit be_probe(struct pci_dev *pdev, adapter->pdev = pdev; pci_set_drvdata(pdev, adapter); adapter->netdev = netdev; - be_netdev_init(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); - be_msix_enable(adapter); - status = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); if (!status) { netdev->features |= NETIF_F_HIGHDMA; @@ -2736,12 +2856,15 @@ static int __devinit be_probe(struct pci_dev *pdev, if (status) goto stats_clean; + be_msix_enable(adapter); + INIT_DELAYED_WORK(&adapter->work, be_worker); status = be_setup(adapter); if (status) - goto stats_clean; + goto msix_disable; + be_netdev_init(netdev); status = register_netdev(netdev); if (status != 0) goto unsetup; @@ -2751,12 +2874,13 @@ static int __devinit be_probe(struct pci_dev *pdev, unsetup: be_clear(adapter); +msix_disable: + be_msix_disable(adapter); stats_clean: be_stats_cleanup(adapter); ctrl_clean: be_ctrl_cleanup(adapter); free_netdev: - be_msix_disable(adapter); be_sriov_disable(adapter); free_netdev(adapter->netdev); pci_set_drvdata(pdev, NULL); diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 03d063554b7f46103cd4c9d20a7dacab215cafeb..f7233191162b93297ceaaad8525a893c8010aab7 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -804,15 +804,14 @@ static void bfin_dump_hwtamp(char *s, ktime_t *hw, ktime_t *ts, struct timecompa static void bfin_tx_hwtstamp(struct net_device *netdev, struct sk_buff *skb) { struct bfin_mac_local *lp = netdev_priv(netdev); - union skb_shared_tx *shtx = skb_tx(skb); - if (shtx->hardware) { + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) { int timeout_cnt = MAX_TIMEOUT_CNT; /* When doing time stamping, keep the connection to the socket * a while longer */ - shtx->in_progress = 1; + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; /* * The timestamping is done at the EMAC module's MII/RMII interface @@ -992,7 +991,6 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, struct bfin_mac_local *lp = netdev_priv(dev); u16 *data; u32 data_align = (unsigned long)(skb->data) & 0x3; - union skb_shared_tx *shtx = skb_tx(skb); current_tx_ptr->skb = skb; @@ -1006,7 +1004,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, * of this field are the length of the packet payload in bytes and the higher * 4 bits are the timestamping enable field. */ - if (shtx->hardware) + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) *data |= 0x1000; current_tx_ptr->desc_a.start_addr = (u32)data; @@ -1016,7 +1014,7 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb, } else { *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); /* enable timestamping for the sent packet */ - if (shtx->hardware) + if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) *((u16 *)(current_tx_ptr->packet)) |= 0x1000; memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, skb->len); diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 959add2410bf1787f8dff73ff786582be105831e..a1b8c8b8010b006f1781ea87af7a4cc20515198b 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1233,15 +1233,8 @@ static void bmac_reset_and_enable(struct net_device *dev) } spin_unlock_irqrestore(&bp->lock, flags); } -static void bmac_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - struct bmac_data *bp = netdev_priv(dev); - strcpy(info->driver, "bmac"); - strcpy(info->bus_info, dev_name(&bp->mdev->ofdev.dev)); -} static const struct ethtool_ops bmac_ethtool_ops = { - .get_drvinfo = bmac_get_drvinfo, .get_link = ethtool_op_get_link, }; @@ -1588,7 +1581,7 @@ bmac_proc_info(char *buffer, char **start, off_t offset, int length) int i; if (bmac_devs == NULL) - return (-ENOSYS); + return -ENOSYS; len += sprintf(buffer, "BMAC counters & registers\n"); diff --git a/drivers/net/bna/Makefile b/drivers/net/bna/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..a5d604de7fea7cad94af3306f9f5905b6972f743 --- /dev/null +++ b/drivers/net/bna/Makefile @@ -0,0 +1,11 @@ +# +# Copyright (c) 2005-2010 Brocade Communications Systems, Inc. +# All rights reserved. +# + +obj-$(CONFIG_BNA) += bna.o + +bna-objs := bnad.o bnad_ethtool.o bna_ctrl.o bna_txrx.o +bna-objs += bfa_ioc.o bfa_ioc_ct.o bfa_cee.o cna_fwimg.o + +EXTRA_CFLAGS := -Idrivers/net/bna diff --git a/drivers/net/bna/bfa_cee.c b/drivers/net/bna/bfa_cee.c new file mode 100644 index 0000000000000000000000000000000000000000..f7b789a3b217d9bae413bbfcb6970a90ec3a97a4 --- /dev/null +++ b/drivers/net/bna/bfa_cee.c @@ -0,0 +1,291 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#include "bfa_defs_cna.h" +#include "cna.h" +#include "bfa_cee.h" +#include "bfi_cna.h" +#include "bfa_ioc.h" + +#define bfa_ioc_portid(__ioc) ((__ioc)->port_id) +#define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc) + +static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg); +static void bfa_cee_format_cee_cfg(void *buffer); + +static void +bfa_cee_format_cee_cfg(void *buffer) +{ + struct bfa_cee_attr *cee_cfg = buffer; + bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote); +} + +static void +bfa_cee_stats_swap(struct bfa_cee_stats *stats) +{ + u32 *buffer = (u32 *)stats; + int i; + + for (i = 0; i < (sizeof(struct bfa_cee_stats) / sizeof(u32)); + i++) { + buffer[i] = ntohl(buffer[i]); + } +} + +static void +bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg *lldp_cfg) +{ + lldp_cfg->time_to_live = + ntohs(lldp_cfg->time_to_live); + lldp_cfg->enabled_system_cap = + ntohs(lldp_cfg->enabled_system_cap); +} + +/** + * bfa_cee_attr_meminfo() + * + * @brief Returns the size of the DMA memory needed by CEE attributes + * + * @param[in] void + * + * @return Size of DMA region + */ +static u32 +bfa_cee_attr_meminfo(void) +{ + return roundup(sizeof(struct bfa_cee_attr), BFA_DMA_ALIGN_SZ); +} +/** + * bfa_cee_stats_meminfo() + * + * @brief Returns the size of the DMA memory needed by CEE stats + * + * @param[in] void + * + * @return Size of DMA region + */ +static u32 +bfa_cee_stats_meminfo(void) +{ + return roundup(sizeof(struct bfa_cee_stats), BFA_DMA_ALIGN_SZ); +} + +/** + * bfa_cee_get_attr_isr() + * + * @brief CEE ISR for get-attributes responses from f/w + * + * @param[in] cee - Pointer to the CEE module + * status - Return status from the f/w + * + * @return void + */ +static void +bfa_cee_get_attr_isr(struct bfa_cee *cee, enum bfa_status status) +{ + cee->get_attr_status = status; + if (status == BFA_STATUS_OK) { + memcpy(cee->attr, cee->attr_dma.kva, + sizeof(struct bfa_cee_attr)); + bfa_cee_format_cee_cfg(cee->attr); + } + cee->get_attr_pending = false; + if (cee->cbfn.get_attr_cbfn) + cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status); +} + +/** + * bfa_cee_get_attr_isr() + * + * @brief CEE ISR for get-stats responses from f/w + * + * @param[in] cee - Pointer to the CEE module + * status - Return status from the f/w + * + * @return void + */ +static void +bfa_cee_get_stats_isr(struct bfa_cee *cee, enum bfa_status status) +{ + cee->get_stats_status = status; + if (status == BFA_STATUS_OK) { + memcpy(cee->stats, cee->stats_dma.kva, + sizeof(struct bfa_cee_stats)); + bfa_cee_stats_swap(cee->stats); + } + cee->get_stats_pending = false; + if (cee->cbfn.get_stats_cbfn) + cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status); +} + +/** + * bfa_cee_get_attr_isr() + * + * @brief CEE ISR for reset-stats responses from f/w + * + * @param[in] cee - Pointer to the CEE module + * status - Return status from the f/w + * + * @return void + */ +static void +bfa_cee_reset_stats_isr(struct bfa_cee *cee, enum bfa_status status) +{ + cee->reset_stats_status = status; + cee->reset_stats_pending = false; + if (cee->cbfn.reset_stats_cbfn) + cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status); +} +/** + * bfa_nw_cee_meminfo() + * + * @brief Returns the size of the DMA memory needed by CEE module + * + * @param[in] void + * + * @return Size of DMA region + */ +u32 +bfa_nw_cee_meminfo(void) +{ + return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo(); +} + +/** + * bfa_nw_cee_mem_claim() + * + * @brief Initialized CEE DMA Memory + * + * @param[in] cee CEE module pointer + * dma_kva Kernel Virtual Address of CEE DMA Memory + * dma_pa Physical Address of CEE DMA Memory + * + * @return void + */ +void +bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, u64 dma_pa) +{ + cee->attr_dma.kva = dma_kva; + cee->attr_dma.pa = dma_pa; + cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo(); + cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo(); + cee->attr = (struct bfa_cee_attr *) dma_kva; + cee->stats = (struct bfa_cee_stats *) + (dma_kva + bfa_cee_attr_meminfo()); +} + +/** + * bfa_cee_isrs() + * + * @brief Handles Mail-box interrupts for CEE module. + * + * @param[in] Pointer to the CEE module data structure. + * + * @return void + */ + +static void +bfa_cee_isr(void *cbarg, struct bfi_mbmsg *m) +{ + union bfi_cee_i2h_msg_u *msg; + struct bfi_cee_get_rsp *get_rsp; + struct bfa_cee *cee = (struct bfa_cee *) cbarg; + msg = (union bfi_cee_i2h_msg_u *) m; + get_rsp = (struct bfi_cee_get_rsp *) m; + switch (msg->mh.msg_id) { + case BFI_CEE_I2H_GET_CFG_RSP: + bfa_cee_get_attr_isr(cee, get_rsp->cmd_status); + break; + case BFI_CEE_I2H_GET_STATS_RSP: + bfa_cee_get_stats_isr(cee, get_rsp->cmd_status); + break; + case BFI_CEE_I2H_RESET_STATS_RSP: + bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status); + break; + default: + BUG_ON(1); + } +} + +/** + * bfa_cee_hbfail() + * + * @brief CEE module heart-beat failure handler. + * + * @param[in] Pointer to the CEE module data structure. + * + * @return void + */ + +static void +bfa_cee_hbfail(void *arg) +{ + struct bfa_cee *cee; + cee = (struct bfa_cee *) arg; + + if (cee->get_attr_pending == true) { + cee->get_attr_status = BFA_STATUS_FAILED; + cee->get_attr_pending = false; + if (cee->cbfn.get_attr_cbfn) { + cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, + BFA_STATUS_FAILED); + } + } + if (cee->get_stats_pending == true) { + cee->get_stats_status = BFA_STATUS_FAILED; + cee->get_stats_pending = false; + if (cee->cbfn.get_stats_cbfn) { + cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, + BFA_STATUS_FAILED); + } + } + if (cee->reset_stats_pending == true) { + cee->reset_stats_status = BFA_STATUS_FAILED; + cee->reset_stats_pending = false; + if (cee->cbfn.reset_stats_cbfn) { + cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, + BFA_STATUS_FAILED); + } + } +} + +/** + * bfa_nw_cee_attach() + * + * @brief CEE module-attach API + * + * @param[in] cee - Pointer to the CEE module data structure + * ioc - Pointer to the ioc module data structure + * dev - Pointer to the device driver module data structure + * The device driver specific mbox ISR functions have + * this pointer as one of the parameters. + * + * @return void + */ +void +bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, + void *dev) +{ + BUG_ON(!(cee != NULL)); + cee->dev = dev; + cee->ioc = ioc; + + bfa_nw_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee); + bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee); + bfa_nw_ioc_hbfail_register(cee->ioc, &cee->hbfail); +} diff --git a/drivers/net/bna/bfa_cee.h b/drivers/net/bna/bfa_cee.h new file mode 100644 index 0000000000000000000000000000000000000000..20543d15b64f5f49facb00f8114030130d634519 --- /dev/null +++ b/drivers/net/bna/bfa_cee.h @@ -0,0 +1,64 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFA_CEE_H__ +#define __BFA_CEE_H__ + +#include "bfa_defs_cna.h" +#include "bfa_ioc.h" + +typedef void (*bfa_cee_get_attr_cbfn_t) (void *dev, enum bfa_status status); +typedef void (*bfa_cee_get_stats_cbfn_t) (void *dev, enum bfa_status status); +typedef void (*bfa_cee_reset_stats_cbfn_t) (void *dev, enum bfa_status status); +typedef void (*bfa_cee_hbfail_cbfn_t) (void *dev, enum bfa_status status); + +struct bfa_cee_cbfn { + bfa_cee_get_attr_cbfn_t get_attr_cbfn; + void *get_attr_cbarg; + bfa_cee_get_stats_cbfn_t get_stats_cbfn; + void *get_stats_cbarg; + bfa_cee_reset_stats_cbfn_t reset_stats_cbfn; + void *reset_stats_cbarg; +}; + +struct bfa_cee { + void *dev; + bool get_attr_pending; + bool get_stats_pending; + bool reset_stats_pending; + enum bfa_status get_attr_status; + enum bfa_status get_stats_status; + enum bfa_status reset_stats_status; + struct bfa_cee_cbfn cbfn; + struct bfa_ioc_hbfail_notify hbfail; + struct bfa_cee_attr *attr; + struct bfa_cee_stats *stats; + struct bfa_dma attr_dma; + struct bfa_dma stats_dma; + struct bfa_ioc *ioc; + struct bfa_mbox_cmd get_cfg_mb; + struct bfa_mbox_cmd get_stats_mb; + struct bfa_mbox_cmd reset_stats_mb; +}; + +u32 bfa_nw_cee_meminfo(void); +void bfa_nw_cee_mem_claim(struct bfa_cee *cee, u8 *dma_kva, + u64 dma_pa); +void bfa_nw_cee_attach(struct bfa_cee *cee, struct bfa_ioc *ioc, void *dev); + +#endif /* __BFA_CEE_H__ */ diff --git a/drivers/net/bna/bfa_defs.h b/drivers/net/bna/bfa_defs.h new file mode 100644 index 0000000000000000000000000000000000000000..29c1b8de2c2d74477fd15227332563dc3c72418b --- /dev/null +++ b/drivers/net/bna/bfa_defs.h @@ -0,0 +1,243 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFA_DEFS_H__ +#define __BFA_DEFS_H__ + +#include "cna.h" +#include "bfa_defs_status.h" +#include "bfa_defs_mfg_comm.h" + +#define BFA_STRING_32 32 +#define BFA_VERSION_LEN 64 + +/** + * ---------------------- adapter definitions ------------ + */ + +/** + * BFA adapter level attributes. + */ +enum { + BFA_ADAPTER_SERIAL_NUM_LEN = STRSZ(BFA_MFG_SERIALNUM_SIZE), + /* + *!< adapter serial num length + */ + BFA_ADAPTER_MODEL_NAME_LEN = 16, /*!< model name length */ + BFA_ADAPTER_MODEL_DESCR_LEN = 128, /*!< model description length */ + BFA_ADAPTER_MFG_NAME_LEN = 8, /*!< manufacturer name length */ + BFA_ADAPTER_SYM_NAME_LEN = 64, /*!< adapter symbolic name length */ + BFA_ADAPTER_OS_TYPE_LEN = 64, /*!< adapter os type length */ +}; + +struct bfa_adapter_attr { + char manufacturer[BFA_ADAPTER_MFG_NAME_LEN]; + char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; + u32 card_type; + char model[BFA_ADAPTER_MODEL_NAME_LEN]; + char model_descr[BFA_ADAPTER_MODEL_DESCR_LEN]; + u64 pwwn; + char node_symname[FC_SYMNAME_MAX]; + char hw_ver[BFA_VERSION_LEN]; + char fw_ver[BFA_VERSION_LEN]; + char optrom_ver[BFA_VERSION_LEN]; + char os_type[BFA_ADAPTER_OS_TYPE_LEN]; + struct bfa_mfg_vpd vpd; + struct mac mac; + + u8 nports; + u8 max_speed; + u8 prototype; + char asic_rev; + + u8 pcie_gen; + u8 pcie_lanes_orig; + u8 pcie_lanes; + u8 cna_capable; + + u8 is_mezz; + u8 trunk_capable; +}; + +/** + * ---------------------- IOC definitions ------------ + */ + +enum { + BFA_IOC_DRIVER_LEN = 16, + BFA_IOC_CHIP_REV_LEN = 8, +}; + +/** + * Driver and firmware versions. + */ +struct bfa_ioc_driver_attr { + char driver[BFA_IOC_DRIVER_LEN]; /*!< driver name */ + char driver_ver[BFA_VERSION_LEN]; /*!< driver version */ + char fw_ver[BFA_VERSION_LEN]; /*!< firmware version */ + char bios_ver[BFA_VERSION_LEN]; /*!< bios version */ + char efi_ver[BFA_VERSION_LEN]; /*!< EFI version */ + char ob_ver[BFA_VERSION_LEN]; /*!< openboot version */ +}; + +/** + * IOC PCI device attributes + */ +struct bfa_ioc_pci_attr { + u16 vendor_id; /*!< PCI vendor ID */ + u16 device_id; /*!< PCI device ID */ + u16 ssid; /*!< subsystem ID */ + u16 ssvid; /*!< subsystem vendor ID */ + u32 pcifn; /*!< PCI device function */ + u32 rsvd; /* padding */ + char chip_rev[BFA_IOC_CHIP_REV_LEN]; /*!< chip revision */ +}; + +/** + * IOC states + */ +enum bfa_ioc_state { + BFA_IOC_RESET = 1, /*!< IOC is in reset state */ + BFA_IOC_SEMWAIT = 2, /*!< Waiting for IOC h/w semaphore */ + BFA_IOC_HWINIT = 3, /*!< IOC h/w is being initialized */ + BFA_IOC_GETATTR = 4, /*!< IOC is being configured */ + BFA_IOC_OPERATIONAL = 5, /*!< IOC is operational */ + BFA_IOC_INITFAIL = 6, /*!< IOC hardware failure */ + BFA_IOC_HBFAIL = 7, /*!< IOC heart-beat failure */ + BFA_IOC_DISABLING = 8, /*!< IOC is being disabled */ + BFA_IOC_DISABLED = 9, /*!< IOC is disabled */ + BFA_IOC_FWMISMATCH = 10, /*!< IOC f/w different from drivers */ +}; + +/** + * IOC firmware stats + */ +struct bfa_fw_ioc_stats { + u32 enable_reqs; + u32 disable_reqs; + u32 get_attr_reqs; + u32 dbg_sync; + u32 dbg_dump; + u32 unknown_reqs; +}; + +/** + * IOC driver stats + */ +struct bfa_ioc_drv_stats { + u32 ioc_isrs; + u32 ioc_enables; + u32 ioc_disables; + u32 ioc_hbfails; + u32 ioc_boots; + u32 stats_tmos; + u32 hb_count; + u32 disable_reqs; + u32 enable_reqs; + u32 disable_replies; + u32 enable_replies; +}; + +/** + * IOC statistics + */ +struct bfa_ioc_stats { + struct bfa_ioc_drv_stats drv_stats; /*!< driver IOC stats */ + struct bfa_fw_ioc_stats fw_stats; /*!< firmware IOC stats */ +}; + +enum bfa_ioc_type { + BFA_IOC_TYPE_FC = 1, + BFA_IOC_TYPE_FCoE = 2, + BFA_IOC_TYPE_LL = 3, +}; + +/** + * IOC attributes returned in queries + */ +struct bfa_ioc_attr { + enum bfa_ioc_type ioc_type; + enum bfa_ioc_state state; /*!< IOC state */ + struct bfa_adapter_attr adapter_attr; /*!< HBA attributes */ + struct bfa_ioc_driver_attr driver_attr; /*!< driver attr */ + struct bfa_ioc_pci_attr pci_attr; + u8 port_id; /*!< port number */ + u8 rsvd[7]; /*!< 64bit align */ +}; + +/** + * ---------------------- mfg definitions ------------ + */ + +/** + * Checksum size + */ +#define BFA_MFG_CHKSUM_SIZE 16 + +#define BFA_MFG_PARTNUM_SIZE 14 +#define BFA_MFG_SUPPLIER_ID_SIZE 10 +#define BFA_MFG_SUPPLIER_PARTNUM_SIZE 20 +#define BFA_MFG_SUPPLIER_SERIALNUM_SIZE 20 +#define BFA_MFG_SUPPLIER_REVISION_SIZE 4 + +#pragma pack(1) + +/** + * @brief BFA adapter manufacturing block definition. + * + * All numerical fields are in big-endian format. + */ +struct bfa_mfg_block { + u8 version; /*!< manufacturing block version */ + u8 mfg_sig[3]; /*!< characters 'M', 'F', 'G' */ + u16 mfgsize; /*!< mfg block size */ + u16 u16_chksum; /*!< old u16 checksum */ + char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; + char brcd_partnum[STRSZ(BFA_MFG_PARTNUM_SIZE)]; + u8 mfg_day; /*!< manufacturing day */ + u8 mfg_month; /*!< manufacturing month */ + u16 mfg_year; /*!< manufacturing year */ + u64 mfg_wwn; /*!< wwn base for this adapter */ + u8 num_wwn; /*!< number of wwns assigned */ + u8 mfg_speeds; /*!< speeds allowed for this adapter */ + u8 rsv[2]; + char supplier_id[STRSZ(BFA_MFG_SUPPLIER_ID_SIZE)]; + char supplier_partnum[STRSZ(BFA_MFG_SUPPLIER_PARTNUM_SIZE)]; + char + supplier_serialnum[STRSZ(BFA_MFG_SUPPLIER_SERIALNUM_SIZE)]; + char + supplier_revision[STRSZ(BFA_MFG_SUPPLIER_REVISION_SIZE)]; + mac_t mfg_mac; /*!< mac address */ + u8 num_mac; /*!< number of mac addresses */ + u8 rsv2; + u32 mfg_type; /*!< card type */ + u8 rsv3[108]; + u8 md5_chksum[BFA_MFG_CHKSUM_SIZE]; /*!< md5 checksum */ +}; + +#pragma pack() + +/** + * ---------------------- pci definitions ------------ + */ + +#define bfa_asic_id_ct(devid) \ + ((devid) == PCI_DEVICE_ID_BROCADE_CT || \ + (devid) == PCI_DEVICE_ID_BROCADE_CT_FC) + +#endif /* __BFA_DEFS_H__ */ diff --git a/drivers/net/bna/bfa_defs_cna.h b/drivers/net/bna/bfa_defs_cna.h new file mode 100644 index 0000000000000000000000000000000000000000..7e0a9187bdd52a7a9378ccaff106f64d9f5f95ce --- /dev/null +++ b/drivers/net/bna/bfa_defs_cna.h @@ -0,0 +1,223 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFA_DEFS_CNA_H__ +#define __BFA_DEFS_CNA_H__ + +#include "bfa_defs.h" + +/** + * @brief + * FC physical port statistics. + */ +struct bfa_port_fc_stats { + u64 secs_reset; /*!< Seconds since stats is reset */ + u64 tx_frames; /*!< Tx frames */ + u64 tx_words; /*!< Tx words */ + u64 tx_lip; /*!< Tx LIP */ + u64 tx_nos; /*!< Tx NOS */ + u64 tx_ols; /*!< Tx OLS */ + u64 tx_lr; /*!< Tx LR */ + u64 tx_lrr; /*!< Tx LRR */ + u64 rx_frames; /*!< Rx frames */ + u64 rx_words; /*!< Rx words */ + u64 lip_count; /*!< Rx LIP */ + u64 nos_count; /*!< Rx NOS */ + u64 ols_count; /*!< Rx OLS */ + u64 lr_count; /*!< Rx LR */ + u64 lrr_count; /*!< Rx LRR */ + u64 invalid_crcs; /*!< Rx CRC err frames */ + u64 invalid_crc_gd_eof; /*!< Rx CRC err good EOF frames */ + u64 undersized_frm; /*!< Rx undersized frames */ + u64 oversized_frm; /*!< Rx oversized frames */ + u64 bad_eof_frm; /*!< Rx frames with bad EOF */ + u64 error_frames; /*!< Errored frames */ + u64 dropped_frames; /*!< Dropped frames */ + u64 link_failures; /*!< Link Failure (LF) count */ + u64 loss_of_syncs; /*!< Loss of sync count */ + u64 loss_of_signals; /*!< Loss of signal count */ + u64 primseq_errs; /*!< Primitive sequence protocol err. */ + u64 bad_os_count; /*!< Invalid ordered sets */ + u64 err_enc_out; /*!< Encoding err nonframe_8b10b */ + u64 err_enc; /*!< Encoding err frame_8b10b */ +}; + +/** + * @brief + * Eth Physical Port statistics. + */ +struct bfa_port_eth_stats { + u64 secs_reset; /*!< Seconds since stats is reset */ + u64 frame_64; /*!< Frames 64 bytes */ + u64 frame_65_127; /*!< Frames 65-127 bytes */ + u64 frame_128_255; /*!< Frames 128-255 bytes */ + u64 frame_256_511; /*!< Frames 256-511 bytes */ + u64 frame_512_1023; /*!< Frames 512-1023 bytes */ + u64 frame_1024_1518; /*!< Frames 1024-1518 bytes */ + u64 frame_1519_1522; /*!< Frames 1519-1522 bytes */ + u64 tx_bytes; /*!< Tx bytes */ + u64 tx_packets; /*!< Tx packets */ + u64 tx_mcast_packets; /*!< Tx multicast packets */ + u64 tx_bcast_packets; /*!< Tx broadcast packets */ + u64 tx_control_frame; /*!< Tx control frame */ + u64 tx_drop; /*!< Tx drops */ + u64 tx_jabber; /*!< Tx jabber */ + u64 tx_fcs_error; /*!< Tx FCS errors */ + u64 tx_fragments; /*!< Tx fragments */ + u64 rx_bytes; /*!< Rx bytes */ + u64 rx_packets; /*!< Rx packets */ + u64 rx_mcast_packets; /*!< Rx multicast packets */ + u64 rx_bcast_packets; /*!< Rx broadcast packets */ + u64 rx_control_frames; /*!< Rx control frames */ + u64 rx_unknown_opcode; /*!< Rx unknown opcode */ + u64 rx_drop; /*!< Rx drops */ + u64 rx_jabber; /*!< Rx jabber */ + u64 rx_fcs_error; /*!< Rx FCS errors */ + u64 rx_alignment_error; /*!< Rx alignment errors */ + u64 rx_frame_length_error; /*!< Rx frame len errors */ + u64 rx_code_error; /*!< Rx code errors */ + u64 rx_fragments; /*!< Rx fragments */ + u64 rx_pause; /*!< Rx pause */ + u64 rx_zero_pause; /*!< Rx zero pause */ + u64 tx_pause; /*!< Tx pause */ + u64 tx_zero_pause; /*!< Tx zero pause */ + u64 rx_fcoe_pause; /*!< Rx FCoE pause */ + u64 rx_fcoe_zero_pause; /*!< Rx FCoE zero pause */ + u64 tx_fcoe_pause; /*!< Tx FCoE pause */ + u64 tx_fcoe_zero_pause; /*!< Tx FCoE zero pause */ +}; + +/** + * @brief + * Port statistics. + */ +union bfa_port_stats_u { + struct bfa_port_fc_stats fc; + struct bfa_port_eth_stats eth; +}; + +#pragma pack(1) + +#define BFA_CEE_LLDP_MAX_STRING_LEN (128) +#define BFA_CEE_DCBX_MAX_PRIORITY (8) +#define BFA_CEE_DCBX_MAX_PGID (8) + +#define BFA_CEE_LLDP_SYS_CAP_OTHER 0x0001 +#define BFA_CEE_LLDP_SYS_CAP_REPEATER 0x0002 +#define BFA_CEE_LLDP_SYS_CAP_MAC_BRIDGE 0x0004 +#define BFA_CEE_LLDP_SYS_CAP_WLAN_AP 0x0008 +#define BFA_CEE_LLDP_SYS_CAP_ROUTER 0x0010 +#define BFA_CEE_LLDP_SYS_CAP_TELEPHONE 0x0020 +#define BFA_CEE_LLDP_SYS_CAP_DOCSIS_CD 0x0040 +#define BFA_CEE_LLDP_SYS_CAP_STATION 0x0080 +#define BFA_CEE_LLDP_SYS_CAP_CVLAN 0x0100 +#define BFA_CEE_LLDP_SYS_CAP_SVLAN 0x0200 +#define BFA_CEE_LLDP_SYS_CAP_TPMR 0x0400 + +/* LLDP string type */ +struct bfa_cee_lldp_str { + u8 sub_type; + u8 len; + u8 rsvd[2]; + u8 value[BFA_CEE_LLDP_MAX_STRING_LEN]; +}; + +/* LLDP paramters */ +struct bfa_cee_lldp_cfg { + struct bfa_cee_lldp_str chassis_id; + struct bfa_cee_lldp_str port_id; + struct bfa_cee_lldp_str port_desc; + struct bfa_cee_lldp_str sys_name; + struct bfa_cee_lldp_str sys_desc; + struct bfa_cee_lldp_str mgmt_addr; + u16 time_to_live; + u16 enabled_system_cap; +}; + +enum bfa_cee_dcbx_version { + DCBX_PROTOCOL_PRECEE = 1, + DCBX_PROTOCOL_CEE = 2, +}; + +enum bfa_cee_lls { + /* LLS is down because the TLV not sent by the peer */ + CEE_LLS_DOWN_NO_TLV = 0, + /* LLS is down as advertised by the peer */ + CEE_LLS_DOWN = 1, + CEE_LLS_UP = 2, +}; + +/* CEE/DCBX parameters */ +struct bfa_cee_dcbx_cfg { + u8 pgid[BFA_CEE_DCBX_MAX_PRIORITY]; + u8 pg_percentage[BFA_CEE_DCBX_MAX_PGID]; + u8 pfc_primap; /* bitmap of priorties with PFC enabled */ + u8 fcoe_primap; /* bitmap of priorities used for FcoE traffic */ + u8 iscsi_primap; /* bitmap of priorities used for iSCSI traffic */ + u8 dcbx_version; /* operating version:CEE or preCEE */ + u8 lls_fcoe; /* FCoE Logical Link Status */ + u8 lls_lan; /* LAN Logical Link Status */ + u8 rsvd[2]; +}; + +/* CEE status */ +/* Making this to tri-state for the benefit of port list command */ +enum bfa_cee_status { + CEE_UP = 0, + CEE_PHY_UP = 1, + CEE_LOOPBACK = 2, + CEE_PHY_DOWN = 3, +}; + +/* CEE Query */ +struct bfa_cee_attr { + u8 cee_status; + u8 error_reason; + struct bfa_cee_lldp_cfg lldp_remote; + struct bfa_cee_dcbx_cfg dcbx_remote; + mac_t src_mac; + u8 link_speed; + u8 nw_priority; + u8 filler[2]; +}; + +/* LLDP/DCBX/CEE Statistics */ +struct bfa_cee_stats { + u32 lldp_tx_frames; /*!< LLDP Tx Frames */ + u32 lldp_rx_frames; /*!< LLDP Rx Frames */ + u32 lldp_rx_frames_invalid; /*!< LLDP Rx Frames invalid */ + u32 lldp_rx_frames_new; /*!< LLDP Rx Frames new */ + u32 lldp_tlvs_unrecognized; /*!< LLDP Rx unrecognized TLVs */ + u32 lldp_rx_shutdown_tlvs; /*!< LLDP Rx shutdown TLVs */ + u32 lldp_info_aged_out; /*!< LLDP remote info aged out */ + u32 dcbx_phylink_ups; /*!< DCBX phy link ups */ + u32 dcbx_phylink_downs; /*!< DCBX phy link downs */ + u32 dcbx_rx_tlvs; /*!< DCBX Rx TLVs */ + u32 dcbx_rx_tlvs_invalid; /*!< DCBX Rx TLVs invalid */ + u32 dcbx_control_tlv_error; /*!< DCBX control TLV errors */ + u32 dcbx_feature_tlv_error; /*!< DCBX feature TLV errors */ + u32 dcbx_cee_cfg_new; /*!< DCBX new CEE cfg rcvd */ + u32 cee_status_down; /*!< CEE status down */ + u32 cee_status_up; /*!< CEE status up */ + u32 cee_hw_cfg_changed; /*!< CEE hw cfg changed */ + u32 cee_rx_invalid_cfg; /*!< CEE invalid cfg */ +}; + +#pragma pack() + +#endif /* __BFA_DEFS_CNA_H__ */ diff --git a/drivers/net/bna/bfa_defs_mfg_comm.h b/drivers/net/bna/bfa_defs_mfg_comm.h new file mode 100644 index 0000000000000000000000000000000000000000..987978fcb3fe741a60beb98a4bdf17387540e082 --- /dev/null +++ b/drivers/net/bna/bfa_defs_mfg_comm.h @@ -0,0 +1,244 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BFA_DEFS_MFG_COMM_H__ +#define __BFA_DEFS_MFG_COMM_H__ + +#include "cna.h" + +/** + * Manufacturing block version + */ +#define BFA_MFG_VERSION 2 +#define BFA_MFG_VERSION_UNINIT 0xFF + +/** + * Manufacturing block encrypted version + */ +#define BFA_MFG_ENC_VER 2 + +/** + * Manufacturing block version 1 length + */ +#define BFA_MFG_VER1_LEN 128 + +/** + * Manufacturing block header length + */ +#define BFA_MFG_HDR_LEN 4 + +#define BFA_MFG_SERIALNUM_SIZE 11 +#define STRSZ(_n) (((_n) + 4) & ~3) + +/** + * Manufacturing card type + */ +enum { + BFA_MFG_TYPE_CB_MAX = 825, /*!< Crossbow card type max */ + BFA_MFG_TYPE_FC8P2 = 825, /*!< 8G 2port FC card */ + BFA_MFG_TYPE_FC8P1 = 815, /*!< 8G 1port FC card */ + BFA_MFG_TYPE_FC4P2 = 425, /*!< 4G 2port FC card */ + BFA_MFG_TYPE_FC4P1 = 415, /*!< 4G 1port FC card */ + BFA_MFG_TYPE_CNA10P2 = 1020, /*!< 10G 2port CNA card */ + BFA_MFG_TYPE_CNA10P1 = 1010, /*!< 10G 1port CNA card */ + BFA_MFG_TYPE_JAYHAWK = 804, /*!< Jayhawk mezz card */ + BFA_MFG_TYPE_WANCHESE = 1007, /*!< Wanchese mezz card */ + BFA_MFG_TYPE_ASTRA = 807, /*!< Astra mezz card */ + BFA_MFG_TYPE_LIGHTNING_P0 = 902, /*!< Lightning mezz card - old */ + BFA_MFG_TYPE_LIGHTNING = 1741, /*!< Lightning mezz card */ + BFA_MFG_TYPE_INVALID = 0, /*!< Invalid card type */ +}; + +#pragma pack(1) + +/** + * Check if 1-port card + */ +#define bfa_mfg_is_1port(type) (( \ + (type) == BFA_MFG_TYPE_FC8P1 || \ + (type) == BFA_MFG_TYPE_FC4P1 || \ + (type) == BFA_MFG_TYPE_CNA10P1)) + +/** + * Check if Mezz card + */ +#define bfa_mfg_is_mezz(type) (( \ + (type) == BFA_MFG_TYPE_JAYHAWK || \ + (type) == BFA_MFG_TYPE_WANCHESE || \ + (type) == BFA_MFG_TYPE_ASTRA || \ + (type) == BFA_MFG_TYPE_LIGHTNING_P0 || \ + (type) == BFA_MFG_TYPE_LIGHTNING)) + +/** + * Check if card type valid + */ +#define bfa_mfg_is_card_type_valid(type) (( \ + (type) == BFA_MFG_TYPE_FC8P2 || \ + (type) == BFA_MFG_TYPE_FC8P1 || \ + (type) == BFA_MFG_TYPE_FC4P2 || \ + (type) == BFA_MFG_TYPE_FC4P1 || \ + (type) == BFA_MFG_TYPE_CNA10P2 || \ + (type) == BFA_MFG_TYPE_CNA10P1 || \ + bfa_mfg_is_mezz(type))) + +/** + * Check if the card having old wwn/mac handling + */ +#define bfa_mfg_is_old_wwn_mac_model(type) (( \ + (type) == BFA_MFG_TYPE_FC8P2 || \ + (type) == BFA_MFG_TYPE_FC8P1 || \ + (type) == BFA_MFG_TYPE_FC4P2 || \ + (type) == BFA_MFG_TYPE_FC4P1 || \ + (type) == BFA_MFG_TYPE_CNA10P2 || \ + (type) == BFA_MFG_TYPE_CNA10P1 || \ + (type) == BFA_MFG_TYPE_JAYHAWK || \ + (type) == BFA_MFG_TYPE_WANCHESE)) + +#define bfa_mfg_increment_wwn_mac(m, i) \ +do { \ + u32 t = ((m)[0] << 16) | ((m)[1] << 8) | (m)[2]; \ + t += (i); \ + (m)[0] = (t >> 16) & 0xFF; \ + (m)[1] = (t >> 8) & 0xFF; \ + (m)[2] = t & 0xFF; \ +} while (0) + +#define bfa_mfg_adapter_prop_init_flash(card_type, prop) \ +do { \ + switch ((card_type)) { \ + case BFA_MFG_TYPE_FC8P2: \ + case BFA_MFG_TYPE_JAYHAWK: \ + case BFA_MFG_TYPE_ASTRA: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \ + BFI_ADAPTER_SETP(SPEED, 8); \ + break; \ + case BFA_MFG_TYPE_FC8P1: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \ + BFI_ADAPTER_SETP(SPEED, 8); \ + break; \ + case BFA_MFG_TYPE_FC4P2: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 2) | \ + BFI_ADAPTER_SETP(SPEED, 4); \ + break; \ + case BFA_MFG_TYPE_FC4P1: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 1) | \ + BFI_ADAPTER_SETP(SPEED, 4); \ + break; \ + case BFA_MFG_TYPE_CNA10P2: \ + case BFA_MFG_TYPE_WANCHESE: \ + case BFA_MFG_TYPE_LIGHTNING_P0: \ + case BFA_MFG_TYPE_LIGHTNING: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 2); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \ + break; \ + case BFA_MFG_TYPE_CNA10P1: \ + (prop) = BFI_ADAPTER_SETP(NPORTS, 1); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 10); \ + break; \ + default: \ + (prop) = BFI_ADAPTER_UNSUPP; \ + } \ +} while (0) + +enum { + CB_GPIO_TTV = (1), /*!< TTV debug capable cards */ + CB_GPIO_FC8P2 = (2), /*!< 8G 2port FC card */ + CB_GPIO_FC8P1 = (3), /*!< 8G 1port FC card */ + CB_GPIO_FC4P2 = (4), /*!< 4G 2port FC card */ + CB_GPIO_FC4P1 = (5), /*!< 4G 1port FC card */ + CB_GPIO_DFLY = (6), /*!< 8G 2port FC mezzanine card */ + CB_GPIO_PROTO = (1 << 7) /*!< 8G 2port FC prototypes */ +}; + +#define bfa_mfg_adapter_prop_init_gpio(gpio, card_type, prop) \ +do { \ + if ((gpio) & CB_GPIO_PROTO) { \ + (prop) |= BFI_ADAPTER_PROTO; \ + (gpio) &= ~CB_GPIO_PROTO; \ + } \ + switch ((gpio)) { \ + case CB_GPIO_TTV: \ + (prop) |= BFI_ADAPTER_TTV; \ + case CB_GPIO_DFLY: \ + case CB_GPIO_FC8P2: \ + (prop) |= BFI_ADAPTER_SETP(NPORTS, 2); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 8); \ + (card_type) = BFA_MFG_TYPE_FC8P2; \ + break; \ + case CB_GPIO_FC8P1: \ + (prop) |= BFI_ADAPTER_SETP(NPORTS, 1); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 8); \ + (card_type) = BFA_MFG_TYPE_FC8P1; \ + break; \ + case CB_GPIO_FC4P2: \ + (prop) |= BFI_ADAPTER_SETP(NPORTS, 2); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 4); \ + (card_type) = BFA_MFG_TYPE_FC4P2; \ + break; \ + case CB_GPIO_FC4P1: \ + (prop) |= BFI_ADAPTER_SETP(NPORTS, 1); \ + (prop) |= BFI_ADAPTER_SETP(SPEED, 4); \ + (card_type) = BFA_MFG_TYPE_FC4P1; \ + break; \ + default: \ + (prop) |= BFI_ADAPTER_UNSUPP; \ + (card_type) = BFA_MFG_TYPE_INVALID; \ + } \ +} while (0) + +/** + * VPD data length + */ +#define BFA_MFG_VPD_LEN 512 +#define BFA_MFG_VPD_LEN_INVALID 0 + +#define BFA_MFG_VPD_PCI_HDR_OFF 137 +#define BFA_MFG_VPD_PCI_VER_MASK 0x07 /*!< version mask 3 bits */ +#define BFA_MFG_VPD_PCI_VDR_MASK 0xf8 /*!< vendor mask 5 bits */ + +/** + * VPD vendor tag + */ +enum { + BFA_MFG_VPD_UNKNOWN = 0, /*!< vendor unknown */ + BFA_MFG_VPD_IBM = 1, /*!< vendor IBM */ + BFA_MFG_VPD_HP = 2, /*!< vendor HP */ + BFA_MFG_VPD_DELL = 3, /*!< vendor DELL */ + BFA_MFG_VPD_PCI_IBM = 0x08, /*!< PCI VPD IBM */ + BFA_MFG_VPD_PCI_HP = 0x10, /*!< PCI VPD HP */ + BFA_MFG_VPD_PCI_DELL = 0x20, /*!< PCI VPD DELL */ + BFA_MFG_VPD_PCI_BRCD = 0xf8, /*!< PCI VPD Brocade */ +}; + +/** + * @brief BFA adapter flash vpd data definition. + * + * All numerical fields are in big-endian format. + */ +struct bfa_mfg_vpd { + u8 version; /*!< vpd data version */ + u8 vpd_sig[3]; /*!< characters 'V', 'P', 'D' */ + u8 chksum; /*!< u8 checksum */ + u8 vendor; /*!< vendor */ + u8 len; /*!< vpd data length excluding header */ + u8 rsv; + u8 data[BFA_MFG_VPD_LEN]; /*!< vpd data */ +}; + +#pragma pack() + +#endif /* __BFA_DEFS_MFG_H__ */ diff --git a/drivers/net/bna/bfa_defs_status.h b/drivers/net/bna/bfa_defs_status.h new file mode 100644 index 0000000000000000000000000000000000000000..af951126375c80fe130e328e7e2f63fe6119412f --- /dev/null +++ b/drivers/net/bna/bfa_defs_status.h @@ -0,0 +1,216 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BFA_DEFS_STATUS_H__ +#define __BFA_DEFS_STATUS_H__ + +/** + * API status return values + * + * NOTE: The error msgs are auto generated from the comments. Only singe line + * comments are supported + */ +enum bfa_status { + BFA_STATUS_OK = 0, + BFA_STATUS_FAILED = 1, + BFA_STATUS_EINVAL = 2, + BFA_STATUS_ENOMEM = 3, + BFA_STATUS_ENOSYS = 4, + BFA_STATUS_ETIMER = 5, + BFA_STATUS_EPROTOCOL = 6, + BFA_STATUS_ENOFCPORTS = 7, + BFA_STATUS_NOFLASH = 8, + BFA_STATUS_BADFLASH = 9, + BFA_STATUS_SFP_UNSUPP = 10, + BFA_STATUS_UNKNOWN_VFID = 11, + BFA_STATUS_DATACORRUPTED = 12, + BFA_STATUS_DEVBUSY = 13, + BFA_STATUS_ABORTED = 14, + BFA_STATUS_NODEV = 15, + BFA_STATUS_HDMA_FAILED = 16, + BFA_STATUS_FLASH_BAD_LEN = 17, + BFA_STATUS_UNKNOWN_LWWN = 18, + BFA_STATUS_UNKNOWN_RWWN = 19, + BFA_STATUS_FCPT_LS_RJT = 20, + BFA_STATUS_VPORT_EXISTS = 21, + BFA_STATUS_VPORT_MAX = 22, + BFA_STATUS_UNSUPP_SPEED = 23, + BFA_STATUS_INVLD_DFSZ = 24, + BFA_STATUS_CNFG_FAILED = 25, + BFA_STATUS_CMD_NOTSUPP = 26, + BFA_STATUS_NO_ADAPTER = 27, + BFA_STATUS_LINKDOWN = 28, + BFA_STATUS_FABRIC_RJT = 29, + BFA_STATUS_UNKNOWN_VWWN = 30, + BFA_STATUS_NSLOGIN_FAILED = 31, + BFA_STATUS_NO_RPORTS = 32, + BFA_STATUS_NSQUERY_FAILED = 33, + BFA_STATUS_PORT_OFFLINE = 34, + BFA_STATUS_RPORT_OFFLINE = 35, + BFA_STATUS_TGTOPEN_FAILED = 36, + BFA_STATUS_BAD_LUNS = 37, + BFA_STATUS_IO_FAILURE = 38, + BFA_STATUS_NO_FABRIC = 39, + BFA_STATUS_EBADF = 40, + BFA_STATUS_EINTR = 41, + BFA_STATUS_EIO = 42, + BFA_STATUS_ENOTTY = 43, + BFA_STATUS_ENXIO = 44, + BFA_STATUS_EFOPEN = 45, + BFA_STATUS_VPORT_WWN_BP = 46, + BFA_STATUS_PORT_NOT_DISABLED = 47, + BFA_STATUS_BADFRMHDR = 48, + BFA_STATUS_BADFRMSZ = 49, + BFA_STATUS_MISSINGFRM = 50, + BFA_STATUS_LINKTIMEOUT = 51, + BFA_STATUS_NO_FCPIM_NEXUS = 52, + BFA_STATUS_CHECKSUM_FAIL = 53, + BFA_STATUS_GZME_FAILED = 54, + BFA_STATUS_SCSISTART_REQD = 55, + BFA_STATUS_IOC_FAILURE = 56, + BFA_STATUS_INVALID_WWN = 57, + BFA_STATUS_MISMATCH = 58, + BFA_STATUS_IOC_ENABLED = 59, + BFA_STATUS_ADAPTER_ENABLED = 60, + BFA_STATUS_IOC_NON_OP = 61, + BFA_STATUS_ADDR_MAP_FAILURE = 62, + BFA_STATUS_SAME_NAME = 63, + BFA_STATUS_PENDING = 64, + BFA_STATUS_8G_SPD = 65, + BFA_STATUS_4G_SPD = 66, + BFA_STATUS_AD_IS_ENABLE = 67, + BFA_STATUS_EINVAL_TOV = 68, + BFA_STATUS_EINVAL_QDEPTH = 69, + BFA_STATUS_VERSION_FAIL = 70, + BFA_STATUS_DIAG_BUSY = 71, + BFA_STATUS_BEACON_ON = 72, + BFA_STATUS_BEACON_OFF = 73, + BFA_STATUS_LBEACON_ON = 74, + BFA_STATUS_LBEACON_OFF = 75, + BFA_STATUS_PORT_NOT_INITED = 76, + BFA_STATUS_RPSC_ENABLED = 77, + BFA_STATUS_ENOFSAVE = 78, + BFA_STATUS_BAD_FILE = 79, + BFA_STATUS_RLIM_EN = 80, + BFA_STATUS_RLIM_DIS = 81, + BFA_STATUS_IOC_DISABLED = 82, + BFA_STATUS_ADAPTER_DISABLED = 83, + BFA_STATUS_BIOS_DISABLED = 84, + BFA_STATUS_AUTH_ENABLED = 85, + BFA_STATUS_AUTH_DISABLED = 86, + BFA_STATUS_ERROR_TRL_ENABLED = 87, + BFA_STATUS_ERROR_QOS_ENABLED = 88, + BFA_STATUS_NO_SFP_DEV = 89, + BFA_STATUS_MEMTEST_FAILED = 90, + BFA_STATUS_INVALID_DEVID = 91, + BFA_STATUS_QOS_ENABLED = 92, + BFA_STATUS_QOS_DISABLED = 93, + BFA_STATUS_INCORRECT_DRV_CONFIG = 94, + BFA_STATUS_REG_FAIL = 95, + BFA_STATUS_IM_INV_CODE = 96, + BFA_STATUS_IM_INV_VLAN = 97, + BFA_STATUS_IM_INV_ADAPT_NAME = 98, + BFA_STATUS_IM_LOW_RESOURCES = 99, + BFA_STATUS_IM_VLANID_IS_PVID = 100, + BFA_STATUS_IM_VLANID_EXISTS = 101, + BFA_STATUS_IM_FW_UPDATE_FAIL = 102, + BFA_STATUS_PORTLOG_ENABLED = 103, + BFA_STATUS_PORTLOG_DISABLED = 104, + BFA_STATUS_FILE_NOT_FOUND = 105, + BFA_STATUS_QOS_FC_ONLY = 106, + BFA_STATUS_RLIM_FC_ONLY = 107, + BFA_STATUS_CT_SPD = 108, + BFA_STATUS_LEDTEST_OP = 109, + BFA_STATUS_CEE_NOT_DN = 110, + BFA_STATUS_10G_SPD = 111, + BFA_STATUS_IM_INV_TEAM_NAME = 112, + BFA_STATUS_IM_DUP_TEAM_NAME = 113, + BFA_STATUS_IM_ADAPT_ALREADY_IN_TEAM = 114, + BFA_STATUS_IM_ADAPT_HAS_VLANS = 115, + BFA_STATUS_IM_PVID_MISMATCH = 116, + BFA_STATUS_IM_LINK_SPEED_MISMATCH = 117, + BFA_STATUS_IM_MTU_MISMATCH = 118, + BFA_STATUS_IM_RSS_MISMATCH = 119, + BFA_STATUS_IM_HDS_MISMATCH = 120, + BFA_STATUS_IM_OFFLOAD_MISMATCH = 121, + BFA_STATUS_IM_PORT_PARAMS = 122, + BFA_STATUS_IM_PORT_NOT_IN_TEAM = 123, + BFA_STATUS_IM_CANNOT_REM_PRI = 124, + BFA_STATUS_IM_MAX_PORTS_REACHED = 125, + BFA_STATUS_IM_LAST_PORT_DELETE = 126, + BFA_STATUS_IM_NO_DRIVER = 127, + BFA_STATUS_IM_MAX_VLANS_REACHED = 128, + BFA_STATUS_TOMCAT_SPD_NOT_ALLOWED = 129, + BFA_STATUS_NO_MINPORT_DRIVER = 130, + BFA_STATUS_CARD_TYPE_MISMATCH = 131, + BFA_STATUS_BAD_ASICBLK = 132, + BFA_STATUS_NO_DRIVER = 133, + BFA_STATUS_INVALID_MAC = 134, + BFA_STATUS_IM_NO_VLAN = 135, + BFA_STATUS_IM_ETH_LB_FAILED = 136, + BFA_STATUS_IM_PVID_REMOVE = 137, + BFA_STATUS_IM_PVID_EDIT = 138, + BFA_STATUS_CNA_NO_BOOT = 139, + BFA_STATUS_IM_PVID_NON_ZERO = 140, + BFA_STATUS_IM_INETCFG_LOCK_FAILED = 141, + BFA_STATUS_IM_GET_INETCFG_FAILED = 142, + BFA_STATUS_IM_NOT_BOUND = 143, + BFA_STATUS_INSUFFICIENT_PERMS = 144, + BFA_STATUS_IM_INV_VLAN_NAME = 145, + BFA_STATUS_CMD_NOTSUPP_CNA = 146, + BFA_STATUS_IM_PASSTHRU_EDIT = 147, + BFA_STATUS_IM_BIND_FAILED = 148, + BFA_STATUS_IM_UNBIND_FAILED = 149, + BFA_STATUS_IM_PORT_IN_TEAM = 150, + BFA_STATUS_IM_VLAN_NOT_FOUND = 151, + BFA_STATUS_IM_TEAM_NOT_FOUND = 152, + BFA_STATUS_IM_TEAM_CFG_NOT_ALLOWED = 153, + BFA_STATUS_PBC = 154, + BFA_STATUS_DEVID_MISSING = 155, + BFA_STATUS_BAD_FWCFG = 156, + BFA_STATUS_CREATE_FILE = 157, + BFA_STATUS_INVALID_VENDOR = 158, + BFA_STATUS_SFP_NOT_READY = 159, + BFA_STATUS_FLASH_UNINIT = 160, + BFA_STATUS_FLASH_EMPTY = 161, + BFA_STATUS_FLASH_CKFAIL = 162, + BFA_STATUS_TRUNK_UNSUPP = 163, + BFA_STATUS_TRUNK_ENABLED = 164, + BFA_STATUS_TRUNK_DISABLED = 165, + BFA_STATUS_TRUNK_ERROR_TRL_ENABLED = 166, + BFA_STATUS_BOOT_CODE_UPDATED = 167, + BFA_STATUS_BOOT_VERSION = 168, + BFA_STATUS_CARDTYPE_MISSING = 169, + BFA_STATUS_INVALID_CARDTYPE = 170, + BFA_STATUS_NO_TOPOLOGY_FOR_CNA = 171, + BFA_STATUS_IM_VLAN_OVER_TEAM_DELETE_FAILED = 172, + BFA_STATUS_ETHBOOT_ENABLED = 173, + BFA_STATUS_ETHBOOT_DISABLED = 174, + BFA_STATUS_IOPROFILE_OFF = 175, + BFA_STATUS_NO_PORT_INSTANCE = 176, + BFA_STATUS_BOOT_CODE_TIMEDOUT = 177, + BFA_STATUS_NO_VPORT_LOCK = 178, + BFA_STATUS_VPORT_NO_CNFG = 179, + BFA_STATUS_MAX_VAL +}; + +enum bfa_eproto_status { + BFA_EPROTO_BAD_ACCEPT = 0, + BFA_EPROTO_UNKNOWN_RSP = 1 +}; + +#endif /* __BFA_DEFS_STATUS_H__ */ diff --git a/drivers/net/bna/bfa_ioc.c b/drivers/net/bna/bfa_ioc.c new file mode 100644 index 0000000000000000000000000000000000000000..e94e5aa975150ba742909f70ef39129f1c48799a --- /dev/null +++ b/drivers/net/bna/bfa_ioc.c @@ -0,0 +1,1732 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#include "bfa_ioc.h" +#include "cna.h" +#include "bfi.h" +#include "bfi_ctreg.h" +#include "bfa_defs.h" + +/** + * IOC local definitions + */ + +#define bfa_ioc_timer_start(__ioc) \ + mod_timer(&(__ioc)->ioc_timer, jiffies + \ + msecs_to_jiffies(BFA_IOC_TOV)) +#define bfa_ioc_timer_stop(__ioc) del_timer(&(__ioc)->ioc_timer) + +#define bfa_ioc_recovery_timer_start(__ioc) \ + mod_timer(&(__ioc)->ioc_timer, jiffies + \ + msecs_to_jiffies(BFA_IOC_TOV_RECOVER)) + +#define bfa_sem_timer_start(__ioc) \ + mod_timer(&(__ioc)->sem_timer, jiffies + \ + msecs_to_jiffies(BFA_IOC_HWSEM_TOV)) +#define bfa_sem_timer_stop(__ioc) del_timer(&(__ioc)->sem_timer) + +#define bfa_hb_timer_start(__ioc) \ + mod_timer(&(__ioc)->hb_timer, jiffies + \ + msecs_to_jiffies(BFA_IOC_HB_TOV)) +#define bfa_hb_timer_stop(__ioc) del_timer(&(__ioc)->hb_timer) + +/** + * Asic specific macros : see bfa_hw_cb.c and bfa_hw_ct.c for details. + */ + +#define bfa_ioc_firmware_lock(__ioc) \ + ((__ioc)->ioc_hwif->ioc_firmware_lock(__ioc)) +#define bfa_ioc_firmware_unlock(__ioc) \ + ((__ioc)->ioc_hwif->ioc_firmware_unlock(__ioc)) +#define bfa_ioc_reg_init(__ioc) ((__ioc)->ioc_hwif->ioc_reg_init(__ioc)) +#define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) +#define bfa_ioc_notify_hbfail(__ioc) \ + ((__ioc)->ioc_hwif->ioc_notify_hbfail(__ioc)) + +#define bfa_ioc_is_optrom(__ioc) \ + (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(__ioc)) < BFA_IOC_FWIMG_MINSZ) + +#define bfa_ioc_mbox_cmd_pending(__ioc) \ + (!list_empty(&((__ioc)->mbox_mod.cmd_q)) || \ + readl((__ioc)->ioc_regs.hfn_mbox_cmd)) + +static bool bfa_nw_auto_recover = true; + +/* + * forward declarations + */ +static void bfa_ioc_hw_sem_get(struct bfa_ioc *ioc); +static void bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc); +static void bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force); +static void bfa_ioc_send_enable(struct bfa_ioc *ioc); +static void bfa_ioc_send_disable(struct bfa_ioc *ioc); +static void bfa_ioc_send_getattr(struct bfa_ioc *ioc); +static void bfa_ioc_hb_monitor(struct bfa_ioc *ioc); +static void bfa_ioc_hb_stop(struct bfa_ioc *ioc); +static void bfa_ioc_reset(struct bfa_ioc *ioc, bool force); +static void bfa_ioc_mbox_poll(struct bfa_ioc *ioc); +static void bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc); +static void bfa_ioc_recover(struct bfa_ioc *ioc); +static void bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc); +static void bfa_ioc_disable_comp(struct bfa_ioc *ioc); +static void bfa_ioc_lpu_stop(struct bfa_ioc *ioc); +static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, + u32 boot_param); +static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr); +static u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr); +static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, + char *serial_num); +static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, + char *fw_ver); +static void bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, + char *chip_rev); +static void bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, + char *optrom_ver); +static void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, + char *manufacturer); +static void bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model); +static u64 bfa_ioc_get_pwwn(struct bfa_ioc *ioc); +static mac_t bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc); + +/** + * IOC state machine events + */ +enum ioc_event { + IOC_E_ENABLE = 1, /*!< IOC enable request */ + IOC_E_DISABLE = 2, /*!< IOC disable request */ + IOC_E_TIMEOUT = 3, /*!< f/w response timeout */ + IOC_E_FWREADY = 4, /*!< f/w initialization done */ + IOC_E_FWRSP_GETATTR = 5, /*!< IOC get attribute response */ + IOC_E_FWRSP_ENABLE = 6, /*!< enable f/w response */ + IOC_E_FWRSP_DISABLE = 7, /*!< disable f/w response */ + IOC_E_HBFAIL = 8, /*!< heartbeat failure */ + IOC_E_HWERROR = 9, /*!< hardware error interrupt */ + IOC_E_SEMLOCKED = 10, /*!< h/w semaphore is locked */ + IOC_E_DETACH = 11, /*!< driver detach cleanup */ +}; + +bfa_fsm_state_decl(bfa_ioc, reset, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, fwcheck, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, mismatch, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, semwait, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, hwinit, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, enabling, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, getattr, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, op, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, initfail, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, hbfail, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, disabling, struct bfa_ioc, enum ioc_event); +bfa_fsm_state_decl(bfa_ioc, disabled, struct bfa_ioc, enum ioc_event); + +static struct bfa_sm_table ioc_sm_table[] = { + {BFA_SM(bfa_ioc_sm_reset), BFA_IOC_RESET}, + {BFA_SM(bfa_ioc_sm_fwcheck), BFA_IOC_FWMISMATCH}, + {BFA_SM(bfa_ioc_sm_mismatch), BFA_IOC_FWMISMATCH}, + {BFA_SM(bfa_ioc_sm_semwait), BFA_IOC_SEMWAIT}, + {BFA_SM(bfa_ioc_sm_hwinit), BFA_IOC_HWINIT}, + {BFA_SM(bfa_ioc_sm_enabling), BFA_IOC_HWINIT}, + {BFA_SM(bfa_ioc_sm_getattr), BFA_IOC_GETATTR}, + {BFA_SM(bfa_ioc_sm_op), BFA_IOC_OPERATIONAL}, + {BFA_SM(bfa_ioc_sm_initfail), BFA_IOC_INITFAIL}, + {BFA_SM(bfa_ioc_sm_hbfail), BFA_IOC_HBFAIL}, + {BFA_SM(bfa_ioc_sm_disabling), BFA_IOC_DISABLING}, + {BFA_SM(bfa_ioc_sm_disabled), BFA_IOC_DISABLED}, +}; + +/** + * Reset entry actions -- initialize state machine + */ +static void +bfa_ioc_sm_reset_entry(struct bfa_ioc *ioc) +{ + ioc->retry_count = 0; + ioc->auto_recover = bfa_nw_auto_recover; +} + +/** + * Beginning state. IOC is in reset state. + */ +static void +bfa_ioc_sm_reset(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck); + break; + + case IOC_E_DISABLE: + bfa_ioc_disable_comp(ioc); + break; + + case IOC_E_DETACH: + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * Semaphore should be acquired for version check. + */ +static void +bfa_ioc_sm_fwcheck_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_hw_sem_get(ioc); +} + +/** + * Awaiting h/w semaphore to continue with version check. + */ +static void +bfa_ioc_sm_fwcheck(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_SEMLOCKED: + if (bfa_ioc_firmware_lock(ioc)) { + ioc->retry_count = 0; + bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); + } else { + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_mismatch); + } + break; + + case IOC_E_DISABLE: + bfa_ioc_disable_comp(ioc); + /* fall through */ + + case IOC_E_DETACH: + bfa_ioc_hw_sem_get_cancel(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + case IOC_E_FWREADY: + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * Notify enable completion callback and generate mismatch AEN. + */ +static void +bfa_ioc_sm_mismatch_entry(struct bfa_ioc *ioc) +{ + /** + * Provide enable completion callback and AEN notification only once. + */ + if (ioc->retry_count == 0) + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + ioc->retry_count++; + bfa_ioc_timer_start(ioc); +} + +/** + * Awaiting firmware version match. + */ +static void +bfa_ioc_sm_mismatch(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_TIMEOUT: + bfa_fsm_set_state(ioc, bfa_ioc_sm_fwcheck); + break; + + case IOC_E_DISABLE: + bfa_ioc_disable_comp(ioc); + /* fall through */ + + case IOC_E_DETACH: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + case IOC_E_FWREADY: + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * Request for semaphore. + */ +static void +bfa_ioc_sm_semwait_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_hw_sem_get(ioc); +} + +/** + * Awaiting semaphore for h/w initialzation. + */ +static void +bfa_ioc_sm_semwait(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_SEMLOCKED: + ioc->retry_count = 0; + bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); + break; + + case IOC_E_DISABLE: + bfa_ioc_hw_sem_get_cancel(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_hwinit_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_timer_start(ioc); + bfa_ioc_reset(ioc, false); +} + +/** + * @brief + * Hardware is being initialized. Interrupts are enabled. + * Holding hardware semaphore lock. + */ +static void +bfa_ioc_sm_hwinit(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWREADY: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_enabling); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); + /* fall through */ + + case IOC_E_TIMEOUT: + ioc->retry_count++; + if (ioc->retry_count < BFA_IOC_HWINIT_MAX) { + bfa_ioc_timer_start(ioc); + bfa_ioc_reset(ioc, true); + break; + } + + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + break; + + case IOC_E_DISABLE: + bfa_nw_ioc_hw_sem_release(ioc); + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_enabling_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_timer_start(ioc); + bfa_ioc_send_enable(ioc); +} + +/** + * Host IOC function is being enabled, awaiting response from firmware. + * Semaphore is acquired. + */ +static void +bfa_ioc_sm_enabling(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWRSP_ENABLE: + bfa_ioc_timer_stop(ioc); + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_getattr); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); + /* fall through */ + + case IOC_E_TIMEOUT: + ioc->retry_count++; + if (ioc->retry_count < BFA_IOC_HWINIT_MAX) { + writel(BFI_IOC_UNINIT, + ioc->ioc_regs.ioc_fwstate); + bfa_fsm_set_state(ioc, bfa_ioc_sm_hwinit); + break; + } + + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + break; + + case IOC_E_DISABLE: + bfa_ioc_timer_stop(ioc); + bfa_nw_ioc_hw_sem_release(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_FWREADY: + bfa_ioc_send_enable(ioc); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_getattr_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_timer_start(ioc); + bfa_ioc_send_getattr(ioc); +} + +/** + * @brief + * IOC configuration in progress. Timer is active. + */ +static void +bfa_ioc_sm_getattr(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWRSP_GETATTR: + bfa_ioc_timer_stop(ioc); + bfa_ioc_check_attr_wwns(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_op); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); + /* fall through */ + + case IOC_E_TIMEOUT: + bfa_fsm_set_state(ioc, bfa_ioc_sm_initfail); + break; + + case IOC_E_DISABLE: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_op_entry(struct bfa_ioc *ioc) +{ + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); + bfa_ioc_hb_monitor(ioc); +} + +static void +bfa_ioc_sm_op(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + break; + + case IOC_E_DISABLE: + bfa_ioc_hb_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabling); + break; + + case IOC_E_HWERROR: + case IOC_E_FWREADY: + /** + * Hard error or IOC recovery by other function. + * Treat it same as heartbeat failure. + */ + bfa_ioc_hb_stop(ioc); + /* !!! fall through !!! */ + + case IOC_E_HBFAIL: + bfa_fsm_set_state(ioc, bfa_ioc_sm_hbfail); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_disabling_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_timer_start(ioc); + bfa_ioc_send_disable(ioc); +} + +/** + * IOC is being disabled + */ +static void +bfa_ioc_sm_disabling(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_FWRSP_DISABLE: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_HWERROR: + bfa_ioc_timer_stop(ioc); + /* + * !!! fall through !!! + */ + + case IOC_E_TIMEOUT: + writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * IOC disable completion entry. + */ +static void +bfa_ioc_sm_disabled_entry(struct bfa_ioc *ioc) +{ + bfa_ioc_disable_comp(ioc); +} + +static void +bfa_ioc_sm_disabled(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_ENABLE: + bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); + break; + + case IOC_E_DISABLE: + ioc->cbfn->disable_cbfn(ioc->bfa); + break; + + case IOC_E_FWREADY: + break; + + case IOC_E_DETACH: + bfa_ioc_firmware_unlock(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_initfail_entry(struct bfa_ioc *ioc) +{ + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + bfa_ioc_timer_start(ioc); +} + +/** + * @brief + * Hardware initialization failed. + */ +static void +bfa_ioc_sm_initfail(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + case IOC_E_DISABLE: + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_DETACH: + bfa_ioc_timer_stop(ioc); + bfa_ioc_firmware_unlock(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); + break; + + case IOC_E_TIMEOUT: + bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); + break; + + default: + bfa_sm_fault(ioc, event); + } +} + +static void +bfa_ioc_sm_hbfail_entry(struct bfa_ioc *ioc) +{ + struct list_head *qe; + struct bfa_ioc_hbfail_notify *notify; + + /** + * Mark IOC as failed in hardware and stop firmware. + */ + bfa_ioc_lpu_stop(ioc); + writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); + + /** + * Notify other functions on HB failure. + */ + bfa_ioc_notify_hbfail(ioc); + + /** + * Notify driver and common modules registered for notification. + */ + ioc->cbfn->hbfail_cbfn(ioc->bfa); + list_for_each(qe, &ioc->hb_notify_q) { + notify = (struct bfa_ioc_hbfail_notify *) qe; + notify->cbfn(notify->cbarg); + } + + /** + * Flush any queued up mailbox requests. + */ + bfa_ioc_mbox_hbfail(ioc); + + /** + * Trigger auto-recovery after a delay. + */ + if (ioc->auto_recover) + mod_timer(&ioc->ioc_timer, jiffies + + msecs_to_jiffies(BFA_IOC_TOV_RECOVER)); +} + +/** + * @brief + * IOC heartbeat failure. + */ +static void +bfa_ioc_sm_hbfail(struct bfa_ioc *ioc, enum ioc_event event) +{ + switch (event) { + + case IOC_E_ENABLE: + ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); + break; + + case IOC_E_DISABLE: + if (ioc->auto_recover) + bfa_ioc_timer_stop(ioc); + bfa_fsm_set_state(ioc, bfa_ioc_sm_disabled); + break; + + case IOC_E_TIMEOUT: + bfa_fsm_set_state(ioc, bfa_ioc_sm_semwait); + break; + + case IOC_E_FWREADY: + /** + * Recovery is already initiated by other function. + */ + break; + + case IOC_E_HWERROR: + /* + * HB failure notification, ignore. + */ + break; + default: + bfa_sm_fault(ioc, event); + } +} + +/** + * BFA IOC private functions + */ + +static void +bfa_ioc_disable_comp(struct bfa_ioc *ioc) +{ + struct list_head *qe; + struct bfa_ioc_hbfail_notify *notify; + + ioc->cbfn->disable_cbfn(ioc->bfa); + + /** + * Notify common modules registered for notification. + */ + list_for_each(qe, &ioc->hb_notify_q) { + notify = (struct bfa_ioc_hbfail_notify *) qe; + notify->cbfn(notify->cbarg); + } +} + +void +bfa_nw_ioc_sem_timeout(void *ioc_arg) +{ + struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; + + bfa_ioc_hw_sem_get(ioc); +} + +bool +bfa_nw_ioc_sem_get(void __iomem *sem_reg) +{ + u32 r32; + int cnt = 0; +#define BFA_SEM_SPINCNT 3000 + + r32 = readl(sem_reg); + + while (r32 && (cnt < BFA_SEM_SPINCNT)) { + cnt++; + udelay(2); + r32 = readl(sem_reg); + } + + if (r32 == 0) + return true; + + BUG_ON(!(cnt < BFA_SEM_SPINCNT)); + return false; +} + +void +bfa_nw_ioc_sem_release(void __iomem *sem_reg) +{ + writel(1, sem_reg); +} + +static void +bfa_ioc_hw_sem_get(struct bfa_ioc *ioc) +{ + u32 r32; + + /** + * First read to the semaphore register will return 0, subsequent reads + * will return 1. Semaphore is released by writing 1 to the register + */ + r32 = readl(ioc->ioc_regs.ioc_sem_reg); + if (r32 == 0) { + bfa_fsm_send_event(ioc, IOC_E_SEMLOCKED); + return; + } + + mod_timer(&ioc->sem_timer, jiffies + + msecs_to_jiffies(BFA_IOC_HWSEM_TOV)); +} + +void +bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc) +{ + writel(1, ioc->ioc_regs.ioc_sem_reg); +} + +static void +bfa_ioc_hw_sem_get_cancel(struct bfa_ioc *ioc) +{ + del_timer(&ioc->sem_timer); +} + +/** + * @brief + * Initialize LPU local memory (aka secondary memory / SRAM) + */ +static void +bfa_ioc_lmem_init(struct bfa_ioc *ioc) +{ + u32 pss_ctl; + int i; +#define PSS_LMEM_INIT_TIME 10000 + + pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); + pss_ctl &= ~__PSS_LMEM_RESET; + pss_ctl |= __PSS_LMEM_INIT_EN; + + /* + * i2c workaround 12.5khz clock + */ + pss_ctl |= __PSS_I2C_CLK_DIV(3UL); + writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); + + /** + * wait for memory initialization to be complete + */ + i = 0; + do { + pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); + i++; + } while (!(pss_ctl & __PSS_LMEM_INIT_DONE) && (i < PSS_LMEM_INIT_TIME)); + + /** + * If memory initialization is not successful, IOC timeout will catch + * such failures. + */ + BUG_ON(!(pss_ctl & __PSS_LMEM_INIT_DONE)); + + pss_ctl &= ~(__PSS_LMEM_INIT_DONE | __PSS_LMEM_INIT_EN); + writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); +} + +static void +bfa_ioc_lpu_start(struct bfa_ioc *ioc) +{ + u32 pss_ctl; + + /** + * Take processor out of reset. + */ + pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); + pss_ctl &= ~__PSS_LPU0_RESET; + + writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); +} + +static void +bfa_ioc_lpu_stop(struct bfa_ioc *ioc) +{ + u32 pss_ctl; + + /** + * Put processors in reset. + */ + pss_ctl = readl(ioc->ioc_regs.pss_ctl_reg); + pss_ctl |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); + + writel(pss_ctl, ioc->ioc_regs.pss_ctl_reg); +} + +/** + * Get driver and firmware versions. + */ +void +bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) +{ + u32 pgnum, pgoff; + u32 loff = 0; + int i; + u32 *fwsig = (u32 *) fwhdr; + + pgnum = bfa_ioc_smem_pgnum(ioc, loff); + pgoff = bfa_ioc_smem_pgoff(ioc, loff); + writel(pgnum, ioc->ioc_regs.host_page_num_fn); + + for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32)); + i++) { + fwsig[i] = + swab32(readl((loff) + (ioc->ioc_regs.smem_page_start))); + loff += sizeof(u32); + } +} + +/** + * Returns TRUE if same. + */ +bool +bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) +{ + struct bfi_ioc_image_hdr *drv_fwhdr; + int i; + + drv_fwhdr = (struct bfi_ioc_image_hdr *) + bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); + + for (i = 0; i < BFI_IOC_MD5SUM_SZ; i++) { + if (fwhdr->md5sum[i] != drv_fwhdr->md5sum[i]) + return false; + } + + return true; +} + +/** + * Return true if current running version is valid. Firmware signature and + * execution context (driver/bios) must match. + */ +static bool +bfa_ioc_fwver_valid(struct bfa_ioc *ioc) +{ + struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr; + + /** + * If bios/efi boot (flash based) -- return true + */ + if (bfa_ioc_is_optrom(ioc)) + return true; + + bfa_nw_ioc_fwver_get(ioc, &fwhdr); + drv_fwhdr = (struct bfi_ioc_image_hdr *) + bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), 0); + + if (fwhdr.signature != drv_fwhdr->signature) + return false; + + if (fwhdr.exec != drv_fwhdr->exec) + return false; + + return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr); +} + +/** + * Conditionally flush any pending message from firmware at start. + */ +static void +bfa_ioc_msgflush(struct bfa_ioc *ioc) +{ + u32 r32; + + r32 = readl(ioc->ioc_regs.lpu_mbox_cmd); + if (r32) + writel(1, ioc->ioc_regs.lpu_mbox_cmd); +} + +/** + * @img ioc_init_logic.jpg + */ +static void +bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) +{ + enum bfi_ioc_state ioc_fwstate; + bool fwvalid; + + ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); + + if (force) + ioc_fwstate = BFI_IOC_UNINIT; + + /** + * check if firmware is valid + */ + fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ? + false : bfa_ioc_fwver_valid(ioc); + + if (!fwvalid) { + bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id); + return; + } + + /** + * If hardware initialization is in progress (initialized by other IOC), + * just wait for an initialization completion interrupt. + */ + if (ioc_fwstate == BFI_IOC_INITING) { + ioc->cbfn->reset_cbfn(ioc->bfa); + return; + } + + /** + * If IOC function is disabled and firmware version is same, + * just re-enable IOC. + * + * If option rom, IOC must not be in operational state. With + * convergence, IOC will be in operational state when 2nd driver + * is loaded. + */ + if (ioc_fwstate == BFI_IOC_DISABLED || + (!bfa_ioc_is_optrom(ioc) && ioc_fwstate == BFI_IOC_OP)) { + /** + * When using MSI-X any pending firmware ready event should + * be flushed. Otherwise MSI-X interrupts are not delivered. + */ + bfa_ioc_msgflush(ioc); + ioc->cbfn->reset_cbfn(ioc->bfa); + bfa_fsm_send_event(ioc, IOC_E_FWREADY); + return; + } + + /** + * Initialize the h/w for any other states. + */ + bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id); +} + +void +bfa_nw_ioc_timeout(void *ioc_arg) +{ + struct bfa_ioc *ioc = (struct bfa_ioc *) ioc_arg; + + bfa_fsm_send_event(ioc, IOC_E_TIMEOUT); +} + +static void +bfa_ioc_mbox_send(struct bfa_ioc *ioc, void *ioc_msg, int len) +{ + u32 *msgp = (u32 *) ioc_msg; + u32 i; + + BUG_ON(!(len <= BFI_IOC_MSGLEN_MAX)); + + /* + * first write msg to mailbox registers + */ + for (i = 0; i < len / sizeof(u32); i++) + writel(cpu_to_le32(msgp[i]), + ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); + + for (; i < BFI_IOC_MSGLEN_MAX / sizeof(u32); i++) + writel(0, ioc->ioc_regs.hfn_mbox + i * sizeof(u32)); + + /* + * write 1 to mailbox CMD to trigger LPU event + */ + writel(1, ioc->ioc_regs.hfn_mbox_cmd); + (void) readl(ioc->ioc_regs.hfn_mbox_cmd); +} + +static void +bfa_ioc_send_enable(struct bfa_ioc *ioc) +{ + struct bfi_ioc_ctrl_req enable_req; + struct timeval tv; + + bfi_h2i_set(enable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_ENABLE_REQ, + bfa_ioc_portid(ioc)); + enable_req.ioc_class = ioc->ioc_mc; + do_gettimeofday(&tv); + enable_req.tv_sec = ntohl(tv.tv_sec); + bfa_ioc_mbox_send(ioc, &enable_req, sizeof(struct bfi_ioc_ctrl_req)); +} + +static void +bfa_ioc_send_disable(struct bfa_ioc *ioc) +{ + struct bfi_ioc_ctrl_req disable_req; + + bfi_h2i_set(disable_req.mh, BFI_MC_IOC, BFI_IOC_H2I_DISABLE_REQ, + bfa_ioc_portid(ioc)); + bfa_ioc_mbox_send(ioc, &disable_req, sizeof(struct bfi_ioc_ctrl_req)); +} + +static void +bfa_ioc_send_getattr(struct bfa_ioc *ioc) +{ + struct bfi_ioc_getattr_req attr_req; + + bfi_h2i_set(attr_req.mh, BFI_MC_IOC, BFI_IOC_H2I_GETATTR_REQ, + bfa_ioc_portid(ioc)); + bfa_dma_be_addr_set(attr_req.attr_addr, ioc->attr_dma.pa); + bfa_ioc_mbox_send(ioc, &attr_req, sizeof(attr_req)); +} + +void +bfa_nw_ioc_hb_check(void *cbarg) +{ + struct bfa_ioc *ioc = cbarg; + u32 hb_count; + + hb_count = readl(ioc->ioc_regs.heartbeat); + if (ioc->hb_count == hb_count) { + pr_crit("Firmware heartbeat failure at %d", hb_count); + bfa_ioc_recover(ioc); + return; + } else { + ioc->hb_count = hb_count; + } + + bfa_ioc_mbox_poll(ioc); + mod_timer(&ioc->hb_timer, jiffies + + msecs_to_jiffies(BFA_IOC_HB_TOV)); +} + +static void +bfa_ioc_hb_monitor(struct bfa_ioc *ioc) +{ + ioc->hb_count = readl(ioc->ioc_regs.heartbeat); + mod_timer(&ioc->hb_timer, jiffies + + msecs_to_jiffies(BFA_IOC_HB_TOV)); +} + +static void +bfa_ioc_hb_stop(struct bfa_ioc *ioc) +{ + del_timer(&ioc->hb_timer); +} + +/** + * @brief + * Initiate a full firmware download. + */ +static void +bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, + u32 boot_param) +{ + u32 *fwimg; + u32 pgnum, pgoff; + u32 loff = 0; + u32 chunkno = 0; + u32 i; + + /** + * Initialize LMEM first before code download + */ + bfa_ioc_lmem_init(ioc); + + /** + * Flash based firmware boot + */ + if (bfa_ioc_is_optrom(ioc)) + boot_type = BFI_BOOT_TYPE_FLASH; + fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno); + + pgnum = bfa_ioc_smem_pgnum(ioc, loff); + pgoff = bfa_ioc_smem_pgoff(ioc, loff); + + writel(pgnum, ioc->ioc_regs.host_page_num_fn); + + for (i = 0; i < bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)); i++) { + if (BFA_IOC_FLASH_CHUNK_NO(i) != chunkno) { + chunkno = BFA_IOC_FLASH_CHUNK_NO(i); + fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), + BFA_IOC_FLASH_CHUNK_ADDR(chunkno)); + } + + /** + * write smem + */ + writel((swab32(fwimg[BFA_IOC_FLASH_OFFSET_IN_CHUNK(i)])), + ((ioc->ioc_regs.smem_page_start) + (loff))); + + loff += sizeof(u32); + + /** + * handle page offset wrap around + */ + loff = PSS_SMEM_PGOFF(loff); + if (loff == 0) { + pgnum++; + writel(pgnum, + ioc->ioc_regs.host_page_num_fn); + } + } + + writel(bfa_ioc_smem_pgnum(ioc, 0), + ioc->ioc_regs.host_page_num_fn); + + /* + * Set boot type and boot param at the end. + */ + writel((swab32(swab32(boot_type))), ((ioc->ioc_regs.smem_page_start) + + (BFI_BOOT_TYPE_OFF))); + writel((swab32(swab32(boot_param))), ((ioc->ioc_regs.smem_page_start) + + (BFI_BOOT_PARAM_OFF))); +} + +static void +bfa_ioc_reset(struct bfa_ioc *ioc, bool force) +{ + bfa_ioc_hwinit(ioc, force); +} + +/** + * @brief + * Update BFA configuration from firmware configuration. + */ +static void +bfa_ioc_getattr_reply(struct bfa_ioc *ioc) +{ + struct bfi_ioc_attr *attr = ioc->attr; + + attr->adapter_prop = ntohl(attr->adapter_prop); + attr->card_type = ntohl(attr->card_type); + attr->maxfrsize = ntohs(attr->maxfrsize); + + bfa_fsm_send_event(ioc, IOC_E_FWRSP_GETATTR); +} + +/** + * Attach time initialization of mbox logic. + */ +static void +bfa_ioc_mbox_attach(struct bfa_ioc *ioc) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + int mc; + + INIT_LIST_HEAD(&mod->cmd_q); + for (mc = 0; mc < BFI_MC_MAX; mc++) { + mod->mbhdlr[mc].cbfn = NULL; + mod->mbhdlr[mc].cbarg = ioc->bfa; + } +} + +/** + * Mbox poll timer -- restarts any pending mailbox requests. + */ +static void +bfa_ioc_mbox_poll(struct bfa_ioc *ioc) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + struct bfa_mbox_cmd *cmd; + u32 stat; + + /** + * If no command pending, do nothing + */ + if (list_empty(&mod->cmd_q)) + return; + + /** + * If previous command is not yet fetched by firmware, do nothing + */ + stat = readl(ioc->ioc_regs.hfn_mbox_cmd); + if (stat) + return; + + /** + * Enqueue command to firmware. + */ + bfa_q_deq(&mod->cmd_q, &cmd); + bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); +} + +/** + * Cleanup any pending requests. + */ +static void +bfa_ioc_mbox_hbfail(struct bfa_ioc *ioc) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + struct bfa_mbox_cmd *cmd; + + while (!list_empty(&mod->cmd_q)) + bfa_q_deq(&mod->cmd_q, &cmd); +} + +/** + * IOC public + */ +static enum bfa_status +bfa_ioc_pll_init(struct bfa_ioc *ioc) +{ + /* + * Hold semaphore so that nobody can access the chip during init. + */ + bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg); + + bfa_ioc_pll_init_asic(ioc); + + ioc->pllinit = true; + /* + * release semaphore. + */ + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg); + + return BFA_STATUS_OK; +} + +/** + * Interface used by diag module to do firmware boot with memory test + * as the entry vector. + */ +static void +bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param) +{ + void __iomem *rb; + + bfa_ioc_stats(ioc, ioc_boots); + + if (bfa_ioc_pll_init(ioc) != BFA_STATUS_OK) + return; + + /** + * Initialize IOC state of all functions on a chip reset. + */ + rb = ioc->pcidev.pci_bar_kva; + if (boot_param == BFI_BOOT_TYPE_MEMTEST) { + writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG)); + writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG)); + } else { + writel(BFI_IOC_INITING, (rb + BFA_IOC0_STATE_REG)); + writel(BFI_IOC_INITING, (rb + BFA_IOC1_STATE_REG)); + } + + bfa_ioc_msgflush(ioc); + bfa_ioc_download_fw(ioc, boot_type, boot_param); + + /** + * Enable interrupts just before starting LPU + */ + ioc->cbfn->reset_cbfn(ioc->bfa); + bfa_ioc_lpu_start(ioc); +} + +/** + * Enable/disable IOC failure auto recovery. + */ +void +bfa_nw_ioc_auto_recover(bool auto_recover) +{ + bfa_nw_auto_recover = auto_recover; +} + +static void +bfa_ioc_msgget(struct bfa_ioc *ioc, void *mbmsg) +{ + u32 *msgp = mbmsg; + u32 r32; + int i; + + /** + * read the MBOX msg + */ + for (i = 0; i < (sizeof(union bfi_ioc_i2h_msg_u) / sizeof(u32)); + i++) { + r32 = readl(ioc->ioc_regs.lpu_mbox + + i * sizeof(u32)); + msgp[i] = htonl(r32); + } + + /** + * turn off mailbox interrupt by clearing mailbox status + */ + writel(1, ioc->ioc_regs.lpu_mbox_cmd); + readl(ioc->ioc_regs.lpu_mbox_cmd); +} + +static void +bfa_ioc_isr(struct bfa_ioc *ioc, struct bfi_mbmsg *m) +{ + union bfi_ioc_i2h_msg_u *msg; + + msg = (union bfi_ioc_i2h_msg_u *) m; + + bfa_ioc_stats(ioc, ioc_isrs); + + switch (msg->mh.msg_id) { + case BFI_IOC_I2H_HBEAT: + break; + + case BFI_IOC_I2H_READY_EVENT: + bfa_fsm_send_event(ioc, IOC_E_FWREADY); + break; + + case BFI_IOC_I2H_ENABLE_REPLY: + bfa_fsm_send_event(ioc, IOC_E_FWRSP_ENABLE); + break; + + case BFI_IOC_I2H_DISABLE_REPLY: + bfa_fsm_send_event(ioc, IOC_E_FWRSP_DISABLE); + break; + + case BFI_IOC_I2H_GETATTR_REPLY: + bfa_ioc_getattr_reply(ioc); + break; + + default: + BUG_ON(1); + } +} + +/** + * IOC attach time initialization and setup. + * + * @param[in] ioc memory for IOC + * @param[in] bfa driver instance structure + */ +void +bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, struct bfa_ioc_cbfn *cbfn) +{ + ioc->bfa = bfa; + ioc->cbfn = cbfn; + ioc->fcmode = false; + ioc->pllinit = false; + ioc->dbg_fwsave_once = true; + + bfa_ioc_mbox_attach(ioc); + INIT_LIST_HEAD(&ioc->hb_notify_q); + + bfa_fsm_set_state(ioc, bfa_ioc_sm_reset); +} + +/** + * Driver detach time IOC cleanup. + */ +void +bfa_nw_ioc_detach(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(ioc, IOC_E_DETACH); +} + +/** + * Setup IOC PCI properties. + * + * @param[in] pcidev PCI device information for this IOC + */ +void +bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, + enum bfi_mclass mc) +{ + ioc->ioc_mc = mc; + ioc->pcidev = *pcidev; + ioc->ctdev = bfa_asic_id_ct(ioc->pcidev.device_id); + ioc->cna = ioc->ctdev && !ioc->fcmode; + + bfa_nw_ioc_set_ct_hwif(ioc); + + bfa_ioc_map_port(ioc); + bfa_ioc_reg_init(ioc); +} + +/** + * Initialize IOC dma memory + * + * @param[in] dm_kva kernel virtual address of IOC dma memory + * @param[in] dm_pa physical address of IOC dma memory + */ +void +bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa) +{ + /** + * dma memory for firmware attribute + */ + ioc->attr_dma.kva = dm_kva; + ioc->attr_dma.pa = dm_pa; + ioc->attr = (struct bfi_ioc_attr *) dm_kva; +} + +/** + * Return size of dma memory required. + */ +u32 +bfa_nw_ioc_meminfo(void) +{ + return roundup(sizeof(struct bfi_ioc_attr), BFA_DMA_ALIGN_SZ); +} + +void +bfa_nw_ioc_enable(struct bfa_ioc *ioc) +{ + bfa_ioc_stats(ioc, ioc_enables); + ioc->dbg_fwsave_once = true; + + bfa_fsm_send_event(ioc, IOC_E_ENABLE); +} + +void +bfa_nw_ioc_disable(struct bfa_ioc *ioc) +{ + bfa_ioc_stats(ioc, ioc_disables); + bfa_fsm_send_event(ioc, IOC_E_DISABLE); +} + +static u32 +bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr) +{ + return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr); +} + +static u32 +bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr) +{ + return PSS_SMEM_PGOFF(fmaddr); +} + +/** + * Register mailbox message handler function, to be called by common modules + */ +void +bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, + bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + + mod->mbhdlr[mc].cbfn = cbfn; + mod->mbhdlr[mc].cbarg = cbarg; +} + +/** + * Queue a mailbox command request to firmware. Waits if mailbox is busy. + * Responsibility of caller to serialize + * + * @param[in] ioc IOC instance + * @param[i] cmd Mailbox command + */ +void +bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + u32 stat; + + /** + * If a previous command is pending, queue new command + */ + if (!list_empty(&mod->cmd_q)) { + list_add_tail(&cmd->qe, &mod->cmd_q); + return; + } + + /** + * If mailbox is busy, queue command for poll timer + */ + stat = readl(ioc->ioc_regs.hfn_mbox_cmd); + if (stat) { + list_add_tail(&cmd->qe, &mod->cmd_q); + return; + } + + /** + * mailbox is free -- queue command to firmware + */ + bfa_ioc_mbox_send(ioc, cmd->msg, sizeof(cmd->msg)); +} + +/** + * Handle mailbox interrupts + */ +void +bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc) +{ + struct bfa_ioc_mbox_mod *mod = &ioc->mbox_mod; + struct bfi_mbmsg m; + int mc; + + bfa_ioc_msgget(ioc, &m); + + /** + * Treat IOC message class as special. + */ + mc = m.mh.msg_class; + if (mc == BFI_MC_IOC) { + bfa_ioc_isr(ioc, &m); + return; + } + + if ((mc >= BFI_MC_MAX) || (mod->mbhdlr[mc].cbfn == NULL)) + return; + + mod->mbhdlr[mc].cbfn(mod->mbhdlr[mc].cbarg, &m); +} + +void +bfa_nw_ioc_error_isr(struct bfa_ioc *ioc) +{ + bfa_fsm_send_event(ioc, IOC_E_HWERROR); +} + +/** + * Add to IOC heartbeat failure notification queue. To be used by common + * modules such as cee, port, diag. + */ +void +bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, + struct bfa_ioc_hbfail_notify *notify) +{ + list_add_tail(¬ify->qe, &ioc->hb_notify_q); +} + +#define BFA_MFG_NAME "Brocade" +static void +bfa_ioc_get_adapter_attr(struct bfa_ioc *ioc, + struct bfa_adapter_attr *ad_attr) +{ + struct bfi_ioc_attr *ioc_attr; + + ioc_attr = ioc->attr; + + bfa_ioc_get_adapter_serial_num(ioc, ad_attr->serial_num); + bfa_ioc_get_adapter_fw_ver(ioc, ad_attr->fw_ver); + bfa_ioc_get_adapter_optrom_ver(ioc, ad_attr->optrom_ver); + bfa_ioc_get_adapter_manufacturer(ioc, ad_attr->manufacturer); + memcpy(&ad_attr->vpd, &ioc_attr->vpd, + sizeof(struct bfa_mfg_vpd)); + + ad_attr->nports = bfa_ioc_get_nports(ioc); + ad_attr->max_speed = bfa_ioc_speed_sup(ioc); + + bfa_ioc_get_adapter_model(ioc, ad_attr->model); + /* For now, model descr uses same model string */ + bfa_ioc_get_adapter_model(ioc, ad_attr->model_descr); + + ad_attr->card_type = ioc_attr->card_type; + ad_attr->is_mezz = bfa_mfg_is_mezz(ioc_attr->card_type); + + if (BFI_ADAPTER_IS_SPECIAL(ioc_attr->adapter_prop)) + ad_attr->prototype = 1; + else + ad_attr->prototype = 0; + + ad_attr->pwwn = bfa_ioc_get_pwwn(ioc); + ad_attr->mac = bfa_nw_ioc_get_mac(ioc); + + ad_attr->pcie_gen = ioc_attr->pcie_gen; + ad_attr->pcie_lanes = ioc_attr->pcie_lanes; + ad_attr->pcie_lanes_orig = ioc_attr->pcie_lanes_orig; + ad_attr->asic_rev = ioc_attr->asic_rev; + + bfa_ioc_get_pci_chip_rev(ioc, ad_attr->hw_ver); + + ad_attr->cna_capable = ioc->cna; + ad_attr->trunk_capable = (ad_attr->nports > 1) && !ioc->cna; +} + +static enum bfa_ioc_type +bfa_ioc_get_type(struct bfa_ioc *ioc) +{ + if (!ioc->ctdev || ioc->fcmode) + return BFA_IOC_TYPE_FC; + else if (ioc->ioc_mc == BFI_MC_IOCFC) + return BFA_IOC_TYPE_FCoE; + else if (ioc->ioc_mc == BFI_MC_LL) + return BFA_IOC_TYPE_LL; + else { + BUG_ON(!(ioc->ioc_mc == BFI_MC_LL)); + return BFA_IOC_TYPE_LL; + } +} + +static void +bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc, char *serial_num) +{ + memset(serial_num, 0, BFA_ADAPTER_SERIAL_NUM_LEN); + memcpy(serial_num, + (void *)ioc->attr->brcd_serialnum, + BFA_ADAPTER_SERIAL_NUM_LEN); +} + +static void +bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc, char *fw_ver) +{ + memset(fw_ver, 0, BFA_VERSION_LEN); + memcpy(fw_ver, ioc->attr->fw_version, BFA_VERSION_LEN); +} + +static void +bfa_ioc_get_pci_chip_rev(struct bfa_ioc *ioc, char *chip_rev) +{ + BUG_ON(!(chip_rev)); + + memset(chip_rev, 0, BFA_IOC_CHIP_REV_LEN); + + chip_rev[0] = 'R'; + chip_rev[1] = 'e'; + chip_rev[2] = 'v'; + chip_rev[3] = '-'; + chip_rev[4] = ioc->attr->asic_rev; + chip_rev[5] = '\0'; +} + +static void +bfa_ioc_get_adapter_optrom_ver(struct bfa_ioc *ioc, char *optrom_ver) +{ + memset(optrom_ver, 0, BFA_VERSION_LEN); + memcpy(optrom_ver, ioc->attr->optrom_version, + BFA_VERSION_LEN); +} + +static void +bfa_ioc_get_adapter_manufacturer(struct bfa_ioc *ioc, char *manufacturer) +{ + memset(manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); + memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); +} + +static void +bfa_ioc_get_adapter_model(struct bfa_ioc *ioc, char *model) +{ + struct bfi_ioc_attr *ioc_attr; + + BUG_ON(!(model)); + memset(model, 0, BFA_ADAPTER_MODEL_NAME_LEN); + + ioc_attr = ioc->attr; + + /** + * model name + */ + snprintf(model, BFA_ADAPTER_MODEL_NAME_LEN, "%s-%u", + BFA_MFG_NAME, ioc_attr->card_type); +} + +static enum bfa_ioc_state +bfa_ioc_get_state(struct bfa_ioc *ioc) +{ + return bfa_sm_to_state(ioc_sm_table, ioc->fsm); +} + +void +bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr) +{ + memset((void *)ioc_attr, 0, sizeof(struct bfa_ioc_attr)); + + ioc_attr->state = bfa_ioc_get_state(ioc); + ioc_attr->port_id = ioc->port_id; + + ioc_attr->ioc_type = bfa_ioc_get_type(ioc); + + bfa_ioc_get_adapter_attr(ioc, &ioc_attr->adapter_attr); + + ioc_attr->pci_attr.device_id = ioc->pcidev.device_id; + ioc_attr->pci_attr.pcifn = ioc->pcidev.pci_func; + bfa_ioc_get_pci_chip_rev(ioc, ioc_attr->pci_attr.chip_rev); +} + +/** + * WWN public + */ +static u64 +bfa_ioc_get_pwwn(struct bfa_ioc *ioc) +{ + return ioc->attr->pwwn; +} + +mac_t +bfa_nw_ioc_get_mac(struct bfa_ioc *ioc) +{ + /* + * Currently mfg mac is used as FCoE enode mac (not configured by PBC) + */ + if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_FCoE) + return bfa_ioc_get_mfg_mac(ioc); + else + return ioc->attr->mac; +} + +static mac_t +bfa_ioc_get_mfg_mac(struct bfa_ioc *ioc) +{ + mac_t m; + + m = ioc->attr->mfg_mac; + if (bfa_mfg_is_old_wwn_mac_model(ioc->attr->card_type)) + m.mac[MAC_ADDRLEN - 1] += bfa_ioc_pcifn(ioc); + else + bfa_mfg_increment_wwn_mac(&(m.mac[MAC_ADDRLEN-3]), + bfa_ioc_pcifn(ioc)); + + return m; +} + +/** + * Firmware failure detected. Start recovery actions. + */ +static void +bfa_ioc_recover(struct bfa_ioc *ioc) +{ + bfa_ioc_stats(ioc, ioc_hbfails); + bfa_fsm_send_event(ioc, IOC_E_HBFAIL); +} + +static void +bfa_ioc_check_attr_wwns(struct bfa_ioc *ioc) +{ + if (bfa_ioc_get_type(ioc) == BFA_IOC_TYPE_LL) + return; + +} diff --git a/drivers/net/bna/bfa_ioc.h b/drivers/net/bna/bfa_ioc.h new file mode 100644 index 0000000000000000000000000000000000000000..a73d84ec808c76391c3d37067079af54a68bbaa4 --- /dev/null +++ b/drivers/net/bna/bfa_ioc.h @@ -0,0 +1,300 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFA_IOC_H__ +#define __BFA_IOC_H__ + +#include "bfa_sm.h" +#include "bfi.h" +#include "cna.h" + +#define BFA_IOC_TOV 3000 /* msecs */ +#define BFA_IOC_HWSEM_TOV 500 /* msecs */ +#define BFA_IOC_HB_TOV 500 /* msecs */ +#define BFA_IOC_HWINIT_MAX 2 +#define BFA_IOC_TOV_RECOVER BFA_IOC_HB_TOV + +/** + * Generic Scatter Gather Element used by driver + */ +struct bfa_sge { + u32 sg_len; + void *sg_addr; +}; + +/** + * PCI device information required by IOC + */ +struct bfa_pcidev { + int pci_slot; + u8 pci_func; + u16 device_id; + void __iomem *pci_bar_kva; +}; + +/** + * Structure used to remember the DMA-able memory block's KVA and Physical + * Address + */ +struct bfa_dma { + void *kva; /* ! Kernel virtual address */ + u64 pa; /* ! Physical address */ +}; + +#define BFA_DMA_ALIGN_SZ 256 + +/** + * smem size for Crossbow and Catapult + */ +#define BFI_SMEM_CB_SIZE 0x200000U /* ! 2MB for crossbow */ +#define BFI_SMEM_CT_SIZE 0x280000U /* ! 2.5MB for catapult */ + +/** + * @brief BFA dma address assignment macro + */ +#define bfa_dma_addr_set(dma_addr, pa) \ + __bfa_dma_addr_set(&dma_addr, (u64)pa) + +static inline void +__bfa_dma_addr_set(union bfi_addr_u *dma_addr, u64 pa) +{ + dma_addr->a32.addr_lo = (u32) pa; + dma_addr->a32.addr_hi = (u32) (upper_32_bits(pa)); +} + +/** + * @brief BFA dma address assignment macro. (big endian format) + */ +#define bfa_dma_be_addr_set(dma_addr, pa) \ + __bfa_dma_be_addr_set(&dma_addr, (u64)pa) +static inline void +__bfa_dma_be_addr_set(union bfi_addr_u *dma_addr, u64 pa) +{ + dma_addr->a32.addr_lo = (u32) htonl(pa); + dma_addr->a32.addr_hi = (u32) htonl(upper_32_bits(pa)); +} + +struct bfa_ioc_regs { + void __iomem *hfn_mbox_cmd; + void __iomem *hfn_mbox; + void __iomem *lpu_mbox_cmd; + void __iomem *lpu_mbox; + void __iomem *pss_ctl_reg; + void __iomem *pss_err_status_reg; + void __iomem *app_pll_fast_ctl_reg; + void __iomem *app_pll_slow_ctl_reg; + void __iomem *ioc_sem_reg; + void __iomem *ioc_usage_sem_reg; + void __iomem *ioc_init_sem_reg; + void __iomem *ioc_usage_reg; + void __iomem *host_page_num_fn; + void __iomem *heartbeat; + void __iomem *ioc_fwstate; + void __iomem *ll_halt; + void __iomem *err_set; + void __iomem *shirq_isr_next; + void __iomem *shirq_msk_next; + void __iomem *smem_page_start; + u32 smem_pg0; +}; + +/** + * IOC Mailbox structures + */ +struct bfa_mbox_cmd { + struct list_head qe; + u32 msg[BFI_IOC_MSGSZ]; +}; + +/** + * IOC mailbox module + */ +typedef void (*bfa_ioc_mbox_mcfunc_t)(void *cbarg, struct bfi_mbmsg *m); +struct bfa_ioc_mbox_mod { + struct list_head cmd_q; /*!< pending mbox queue */ + int nmclass; /*!< number of handlers */ + struct { + bfa_ioc_mbox_mcfunc_t cbfn; /*!< message handlers */ + void *cbarg; + } mbhdlr[BFI_MC_MAX]; +}; + +/** + * IOC callback function interfaces + */ +typedef void (*bfa_ioc_enable_cbfn_t)(void *bfa, enum bfa_status status); +typedef void (*bfa_ioc_disable_cbfn_t)(void *bfa); +typedef void (*bfa_ioc_hbfail_cbfn_t)(void *bfa); +typedef void (*bfa_ioc_reset_cbfn_t)(void *bfa); +struct bfa_ioc_cbfn { + bfa_ioc_enable_cbfn_t enable_cbfn; + bfa_ioc_disable_cbfn_t disable_cbfn; + bfa_ioc_hbfail_cbfn_t hbfail_cbfn; + bfa_ioc_reset_cbfn_t reset_cbfn; +}; + +/** + * Heartbeat failure notification queue element. + */ +struct bfa_ioc_hbfail_notify { + struct list_head qe; + bfa_ioc_hbfail_cbfn_t cbfn; + void *cbarg; +}; + +/** + * Initialize a heartbeat failure notification structure + */ +#define bfa_ioc_hbfail_init(__notify, __cbfn, __cbarg) do { \ + (__notify)->cbfn = (__cbfn); \ + (__notify)->cbarg = (__cbarg); \ +} while (0) + +struct bfa_ioc { + bfa_fsm_t fsm; + struct bfa *bfa; + struct bfa_pcidev pcidev; + struct bfa_timer_mod *timer_mod; + struct timer_list ioc_timer; + struct timer_list sem_timer; + struct timer_list hb_timer; + u32 hb_count; + u32 retry_count; + struct list_head hb_notify_q; + void *dbg_fwsave; + int dbg_fwsave_len; + bool dbg_fwsave_once; + enum bfi_mclass ioc_mc; + struct bfa_ioc_regs ioc_regs; + struct bfa_ioc_drv_stats stats; + bool auto_recover; + bool fcmode; + bool ctdev; + bool cna; + bool pllinit; + bool stats_busy; /*!< outstanding stats */ + u8 port_id; + + struct bfa_dma attr_dma; + struct bfi_ioc_attr *attr; + struct bfa_ioc_cbfn *cbfn; + struct bfa_ioc_mbox_mod mbox_mod; + struct bfa_ioc_hwif *ioc_hwif; +}; + +struct bfa_ioc_hwif { + enum bfa_status (*ioc_pll_init) (void __iomem *rb, bool fcmode); + bool (*ioc_firmware_lock) (struct bfa_ioc *ioc); + void (*ioc_firmware_unlock) (struct bfa_ioc *ioc); + void (*ioc_reg_init) (struct bfa_ioc *ioc); + void (*ioc_map_port) (struct bfa_ioc *ioc); + void (*ioc_isr_mode_set) (struct bfa_ioc *ioc, + bool msix); + void (*ioc_notify_hbfail) (struct bfa_ioc *ioc); + void (*ioc_ownership_reset) (struct bfa_ioc *ioc); +}; + +#define bfa_ioc_pcifn(__ioc) ((__ioc)->pcidev.pci_func) +#define bfa_ioc_devid(__ioc) ((__ioc)->pcidev.device_id) +#define bfa_ioc_bar0(__ioc) ((__ioc)->pcidev.pci_bar_kva) +#define bfa_ioc_portid(__ioc) ((__ioc)->port_id) +#define bfa_ioc_fetch_stats(__ioc, __stats) \ + (((__stats)->drv_stats) = (__ioc)->stats) +#define bfa_ioc_clr_stats(__ioc) \ + memset(&(__ioc)->stats, 0, sizeof((__ioc)->stats)) +#define bfa_ioc_maxfrsize(__ioc) ((__ioc)->attr->maxfrsize) +#define bfa_ioc_rx_bbcredit(__ioc) ((__ioc)->attr->rx_bbcredit) +#define bfa_ioc_speed_sup(__ioc) \ + BFI_ADAPTER_GETP(SPEED, (__ioc)->attr->adapter_prop) +#define bfa_ioc_get_nports(__ioc) \ + BFI_ADAPTER_GETP(NPORTS, (__ioc)->attr->adapter_prop) + +#define bfa_ioc_stats(_ioc, _stats) ((_ioc)->stats._stats++) +#define BFA_IOC_FWIMG_MINSZ (16 * 1024) +#define BFA_IOC_FWIMG_TYPE(__ioc) \ + (((__ioc)->ctdev) ? \ + (((__ioc)->fcmode) ? BFI_IMAGE_CT_FC : BFI_IMAGE_CT_CNA) : \ + BFI_IMAGE_CB_FC) +#define BFA_IOC_FW_SMEM_SIZE(__ioc) \ + (((__ioc)->ctdev) ? BFI_SMEM_CT_SIZE : BFI_SMEM_CB_SIZE) +#define BFA_IOC_FLASH_CHUNK_NO(off) (off / BFI_FLASH_CHUNK_SZ_WORDS) +#define BFA_IOC_FLASH_OFFSET_IN_CHUNK(off) (off % BFI_FLASH_CHUNK_SZ_WORDS) +#define BFA_IOC_FLASH_CHUNK_ADDR(chunkno) (chunkno * BFI_FLASH_CHUNK_SZ_WORDS) + +/** + * IOC mailbox interface + */ +void bfa_nw_ioc_mbox_queue(struct bfa_ioc *ioc, struct bfa_mbox_cmd *cmd); +void bfa_nw_ioc_mbox_isr(struct bfa_ioc *ioc); +void bfa_nw_ioc_mbox_regisr(struct bfa_ioc *ioc, enum bfi_mclass mc, + bfa_ioc_mbox_mcfunc_t cbfn, void *cbarg); + +/** + * IOC interfaces + */ + +#define bfa_ioc_pll_init_asic(__ioc) \ + ((__ioc)->ioc_hwif->ioc_pll_init((__ioc)->pcidev.pci_bar_kva, \ + (__ioc)->fcmode)) + +#define bfa_ioc_isr_mode_set(__ioc, __msix) \ + ((__ioc)->ioc_hwif->ioc_isr_mode_set(__ioc, __msix)) +#define bfa_ioc_ownership_reset(__ioc) \ + ((__ioc)->ioc_hwif->ioc_ownership_reset(__ioc)) + +void bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc); + +void bfa_nw_ioc_attach(struct bfa_ioc *ioc, void *bfa, + struct bfa_ioc_cbfn *cbfn); +void bfa_nw_ioc_auto_recover(bool auto_recover); +void bfa_nw_ioc_detach(struct bfa_ioc *ioc); +void bfa_nw_ioc_pci_init(struct bfa_ioc *ioc, struct bfa_pcidev *pcidev, + enum bfi_mclass mc); +u32 bfa_nw_ioc_meminfo(void); +void bfa_nw_ioc_mem_claim(struct bfa_ioc *ioc, u8 *dm_kva, u64 dm_pa); +void bfa_nw_ioc_enable(struct bfa_ioc *ioc); +void bfa_nw_ioc_disable(struct bfa_ioc *ioc); + +void bfa_nw_ioc_error_isr(struct bfa_ioc *ioc); + +void bfa_nw_ioc_get_attr(struct bfa_ioc *ioc, struct bfa_ioc_attr *ioc_attr); +void bfa_nw_ioc_hbfail_register(struct bfa_ioc *ioc, + struct bfa_ioc_hbfail_notify *notify); +bool bfa_nw_ioc_sem_get(void __iomem *sem_reg); +void bfa_nw_ioc_sem_release(void __iomem *sem_reg); +void bfa_nw_ioc_hw_sem_release(struct bfa_ioc *ioc); +void bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, + struct bfi_ioc_image_hdr *fwhdr); +bool bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, + struct bfi_ioc_image_hdr *fwhdr); +mac_t bfa_nw_ioc_get_mac(struct bfa_ioc *ioc); + +/* + * Timeout APIs + */ +void bfa_nw_ioc_timeout(void *ioc); +void bfa_nw_ioc_hb_check(void *ioc); +void bfa_nw_ioc_sem_timeout(void *ioc); + +/* + * F/W Image Size & Chunk + */ +u32 *bfa_cb_image_get_chunk(int type, u32 off); +u32 bfa_cb_image_get_size(int type); + +#endif /* __BFA_IOC_H__ */ diff --git a/drivers/net/bna/bfa_ioc_ct.c b/drivers/net/bna/bfa_ioc_ct.c new file mode 100644 index 0000000000000000000000000000000000000000..121cfd6d48b1eb7fe8a5f15223e4f4b3d40cea76 --- /dev/null +++ b/drivers/net/bna/bfa_ioc_ct.c @@ -0,0 +1,392 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#include "bfa_ioc.h" +#include "cna.h" +#include "bfi.h" +#include "bfi_ctreg.h" +#include "bfa_defs.h" + +/* + * forward declarations + */ +static bool bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc); +static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc); +static void bfa_ioc_ct_reg_init(struct bfa_ioc *ioc); +static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc); +static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix); +static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc); +static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc); +static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode); + +static struct bfa_ioc_hwif nw_hwif_ct; + +/** + * Called from bfa_ioc_attach() to map asic specific calls. + */ +void +bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc) +{ + nw_hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init; + nw_hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock; + nw_hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock; + nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init; + nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port; + nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; + nw_hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail; + nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; + + ioc->ioc_hwif = &nw_hwif_ct; +} + +/** + * Return true if firmware of current driver matches the running firmware. + */ +static bool +bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc) +{ + enum bfi_ioc_state ioc_fwstate; + u32 usecnt; + struct bfi_ioc_image_hdr fwhdr; + + /** + * Firmware match check is relevant only for CNA. + */ + if (!ioc->cna) + return true; + + /** + * If bios boot (flash based) -- do not increment usage count + */ + if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) < + BFA_IOC_FWIMG_MINSZ) + return true; + + bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + usecnt = readl(ioc->ioc_regs.ioc_usage_reg); + + /** + * If usage count is 0, always return TRUE. + */ + if (usecnt == 0) { + writel(1, ioc->ioc_regs.ioc_usage_reg); + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + return true; + } + + ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); + + /** + * Use count cannot be non-zero and chip in uninitialized state. + */ + BUG_ON(!(ioc_fwstate != BFI_IOC_UNINIT)); + + /** + * Check if another driver with a different firmware is active + */ + bfa_nw_ioc_fwver_get(ioc, &fwhdr); + if (!bfa_nw_ioc_fwver_cmp(ioc, &fwhdr)) { + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + return false; + } + + /** + * Same firmware version. Increment the reference count. + */ + usecnt++; + writel(usecnt, ioc->ioc_regs.ioc_usage_reg); + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + return true; +} + +static void +bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc) +{ + u32 usecnt; + + /** + * Firmware lock is relevant only for CNA. + */ + if (!ioc->cna) + return; + + /** + * If bios boot (flash based) -- do not decrement usage count + */ + if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) < + BFA_IOC_FWIMG_MINSZ) + return; + + /** + * decrement usage count + */ + bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + usecnt = readl(ioc->ioc_regs.ioc_usage_reg); + BUG_ON(!(usecnt > 0)); + + usecnt--; + writel(usecnt, ioc->ioc_regs.ioc_usage_reg); + + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); +} + +/** + * Notify other functions on HB failure. + */ +static void +bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc) +{ + if (ioc->cna) { + writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt); + /* Wait for halt to take effect */ + readl(ioc->ioc_regs.ll_halt); + } else { + writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set); + readl(ioc->ioc_regs.err_set); + } +} + +/** + * Host to LPU mailbox message addresses + */ +static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = { + { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, + { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, + { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, + { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 } +}; + +/** + * Host <-> LPU mailbox command/status registers - port 0 + */ +static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = { + { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT }, + { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT }, + { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT }, + { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT } +}; + +/** + * Host <-> LPU mailbox command/status registers - port 1 + */ +static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = { + { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT }, + { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT }, + { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT }, + { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT } +}; + +static void +bfa_ioc_ct_reg_init(struct bfa_ioc *ioc) +{ + void __iomem *rb; + int pcifn = bfa_ioc_pcifn(ioc); + + rb = bfa_ioc_bar0(ioc); + + ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox; + ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox; + ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn; + + if (ioc->port_id == 0) { + ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; + ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; + ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn; + ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu; + ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; + } else { + ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); + ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); + ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn; + ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu; + ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; + } + + /* + * PSS control registers + */ + ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); + ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); + ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG); + ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG); + + /* + * IOC semaphore registers and serialization + */ + ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); + ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); + ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); + ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); + + /** + * sram memory access + */ + ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); + ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; + + /* + * err set reg : for notification of hb failure in fcmode + */ + ioc->ioc_regs.err_set = (rb + ERR_SET_REG); +} + +/** + * Initialize IOC to port mapping. + */ + +#define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) +static void +bfa_ioc_ct_map_port(struct bfa_ioc *ioc) +{ + void __iomem *rb = ioc->pcidev.pci_bar_kva; + u32 r32; + + /** + * For catapult, base port id on personality register and IOC type + */ + r32 = readl(rb + FNC_PERS_REG); + r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); + ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; + +} + +/** + * Set interrupt mode for a function: INTX or MSIX + */ +static void +bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix) +{ + void __iomem *rb = ioc->pcidev.pci_bar_kva; + u32 r32, mode; + + r32 = readl(rb + FNC_PERS_REG); + + mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & + __F0_INTX_STATUS; + + /** + * If already in desired mode, do not change anything + */ + if (!msix && mode) + return; + + if (msix) + mode = __F0_INTX_STATUS_MSIX; + else + mode = __F0_INTX_STATUS_INTA; + + r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); + r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); + + writel(r32, rb + FNC_PERS_REG); +} + +/** + * Cleanup hw semaphore and usecnt registers + */ +static void +bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc) +{ + if (ioc->cna) { + bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); + writel(0, ioc->ioc_regs.ioc_usage_reg); + bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg); + } + + /* + * Read the hw sem reg to make sure that it is locked + * before we clear it. If it is not locked, writing 1 + * will lock it instead of clearing it. + */ + readl(ioc->ioc_regs.ioc_sem_reg); + bfa_nw_ioc_hw_sem_release(ioc); +} + +static enum bfa_status +bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode) +{ + u32 pll_sclk, pll_fclk, r32; + + pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST | + __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) | + __APP_PLL_312_JITLMT0_1(3U) | + __APP_PLL_312_CNTLMT0_1(1U); + pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST | + __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) | + __APP_PLL_425_JITLMT0_1(3U) | + __APP_PLL_425_CNTLMT0_1(1U); + if (fcmode) { + writel(0, (rb + OP_MODE)); + writel(__APP_EMS_CMLCKSEL | + __APP_EMS_REFCKBUFEN2 | + __APP_EMS_CHANNEL_SEL, + (rb + ETH_MAC_SER_REG)); + } else { + writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE)); + writel(__APP_EMS_REFCKBUFEN1, + (rb + ETH_MAC_SER_REG)); + } + writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG)); + writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG)); + writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); + writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); + writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); + writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); + writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); + writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); + writel(pll_sclk | + __APP_PLL_312_LOGIC_SOFT_RESET, + rb + APP_PLL_312_CTL_REG); + writel(pll_fclk | + __APP_PLL_425_LOGIC_SOFT_RESET, + rb + APP_PLL_425_CTL_REG); + writel(pll_sclk | + __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE, + rb + APP_PLL_312_CTL_REG); + writel(pll_fclk | + __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE, + rb + APP_PLL_425_CTL_REG); + readl(rb + HOSTFN0_INT_MSK); + udelay(2000); + writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); + writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); + writel(pll_sclk | + __APP_PLL_312_ENABLE, + rb + APP_PLL_312_CTL_REG); + writel(pll_fclk | + __APP_PLL_425_ENABLE, + rb + APP_PLL_425_CTL_REG); + if (!fcmode) { + writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0)); + writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1)); + } + r32 = readl((rb + PSS_CTL_REG)); + r32 &= ~__PSS_LMEM_RESET; + writel(r32, (rb + PSS_CTL_REG)); + udelay(1000); + if (!fcmode) { + writel(0, (rb + PMM_1T_RESET_REG_P0)); + writel(0, (rb + PMM_1T_RESET_REG_P1)); + } + + writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG)); + udelay(1000); + r32 = readl((rb + MBIST_STAT_REG)); + writel(0, (rb + MBIST_CTL_REG)); + return BFA_STATUS_OK; +} diff --git a/drivers/net/bna/bfa_sm.h b/drivers/net/bna/bfa_sm.h new file mode 100644 index 0000000000000000000000000000000000000000..46462c49b6f9b1105ba21a6e2f1ec1e7438f318d --- /dev/null +++ b/drivers/net/bna/bfa_sm.h @@ -0,0 +1,88 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +/** + * @file bfasm.h State machine defines + */ + +#ifndef __BFA_SM_H__ +#define __BFA_SM_H__ + +#include "cna.h" + +typedef void (*bfa_sm_t)(void *sm, int event); + +/** + * oc - object class eg. bfa_ioc + * st - state, eg. reset + * otype - object type, eg. struct bfa_ioc + * etype - object type, eg. enum ioc_event + */ +#define bfa_sm_state_decl(oc, st, otype, etype) \ + static void oc ## _sm_ ## st(otype * fsm, etype event) + +#define bfa_sm_set_state(_sm, _state) ((_sm)->sm = (bfa_sm_t)(_state)) +#define bfa_sm_send_event(_sm, _event) ((_sm)->sm((_sm), (_event))) +#define bfa_sm_get_state(_sm) ((_sm)->sm) +#define bfa_sm_cmp_state(_sm, _state) ((_sm)->sm == (bfa_sm_t)(_state)) + +/** + * For converting from state machine function to state encoding. + */ +struct bfa_sm_table { + bfa_sm_t sm; /*!< state machine function */ + int state; /*!< state machine encoding */ + char *name; /*!< state name for display */ +}; +#define BFA_SM(_sm) ((bfa_sm_t)(_sm)) + +/** + * State machine with entry actions. + */ +typedef void (*bfa_fsm_t)(void *fsm, int event); + +/** + * oc - object class eg. bfa_ioc + * st - state, eg. reset + * otype - object type, eg. struct bfa_ioc + * etype - object type, eg. enum ioc_event + */ +#define bfa_fsm_state_decl(oc, st, otype, etype) \ + static void oc ## _sm_ ## st(otype * fsm, etype event); \ + static void oc ## _sm_ ## st ## _entry(otype * fsm) + +#define bfa_fsm_set_state(_fsm, _state) do { \ + (_fsm)->fsm = (bfa_fsm_t)(_state); \ + _state ## _entry(_fsm); \ +} while (0) + +#define bfa_fsm_send_event(_fsm, _event) ((_fsm)->fsm((_fsm), (_event))) +#define bfa_fsm_get_state(_fsm) ((_fsm)->fsm) +#define bfa_fsm_cmp_state(_fsm, _state) \ + ((_fsm)->fsm == (bfa_fsm_t)(_state)) + +static inline int +bfa_sm_to_state(const struct bfa_sm_table *smt, bfa_sm_t sm) +{ + int i = 0; + + while (smt[i].sm && smt[i].sm != sm) + i++; + return smt[i].state; +} +#endif diff --git a/drivers/net/bna/bfa_wc.h b/drivers/net/bna/bfa_wc.h new file mode 100644 index 0000000000000000000000000000000000000000..d0e4caee67b05f2546d7eb8e25991dec9e690e41 --- /dev/null +++ b/drivers/net/bna/bfa_wc.h @@ -0,0 +1,69 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +/** + * @file bfa_wc.h Generic wait counter. + */ + +#ifndef __BFA_WC_H__ +#define __BFA_WC_H__ + +typedef void (*bfa_wc_resume_t) (void *cbarg); + +struct bfa_wc { + bfa_wc_resume_t wc_resume; + void *wc_cbarg; + int wc_count; +}; + +static inline void +bfa_wc_up(struct bfa_wc *wc) +{ + wc->wc_count++; +} + +static inline void +bfa_wc_down(struct bfa_wc *wc) +{ + wc->wc_count--; + if (wc->wc_count == 0) + wc->wc_resume(wc->wc_cbarg); +} + +/** + * Initialize a waiting counter. + */ +static inline void +bfa_wc_init(struct bfa_wc *wc, bfa_wc_resume_t wc_resume, void *wc_cbarg) +{ + wc->wc_resume = wc_resume; + wc->wc_cbarg = wc_cbarg; + wc->wc_count = 0; + bfa_wc_up(wc); +} + +/** + * Wait for counter to reach zero + */ +static inline void +bfa_wc_wait(struct bfa_wc *wc) +{ + bfa_wc_down(wc); +} + +#endif diff --git a/drivers/net/bna/bfi.h b/drivers/net/bna/bfi.h new file mode 100644 index 0000000000000000000000000000000000000000..a97396811050eaccc1bcd31064c0088c29479413 --- /dev/null +++ b/drivers/net/bna/bfi.h @@ -0,0 +1,392 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __BFI_H__ +#define __BFI_H__ + +#include "bfa_defs.h" + +#pragma pack(1) + +/** + * BFI FW image type + */ +#define BFI_FLASH_CHUNK_SZ 256 /*!< Flash chunk size */ +#define BFI_FLASH_CHUNK_SZ_WORDS (BFI_FLASH_CHUNK_SZ/sizeof(u32)) +enum { + BFI_IMAGE_CB_FC, + BFI_IMAGE_CT_FC, + BFI_IMAGE_CT_CNA, + BFI_IMAGE_MAX, +}; + +/** + * Msg header common to all msgs + */ +struct bfi_mhdr { + u8 msg_class; /*!< @ref enum bfi_mclass */ + u8 msg_id; /*!< msg opcode with in the class */ + union { + struct { + u8 rsvd; + u8 lpu_id; /*!< msg destination */ + } h2i; + u16 i2htok; /*!< token in msgs to host */ + } mtag; +}; + +#define bfi_h2i_set(_mh, _mc, _op, _lpuid) do { \ + (_mh).msg_class = (_mc); \ + (_mh).msg_id = (_op); \ + (_mh).mtag.h2i.lpu_id = (_lpuid); \ +} while (0) + +#define bfi_i2h_set(_mh, _mc, _op, _i2htok) do { \ + (_mh).msg_class = (_mc); \ + (_mh).msg_id = (_op); \ + (_mh).mtag.i2htok = (_i2htok); \ +} while (0) + +/* + * Message opcodes: 0-127 to firmware, 128-255 to host + */ +#define BFI_I2H_OPCODE_BASE 128 +#define BFA_I2HM(_x) ((_x) + BFI_I2H_OPCODE_BASE) + +/** + **************************************************************************** + * + * Scatter Gather Element and Page definition + * + **************************************************************************** + */ + +#define BFI_SGE_INLINE 1 +#define BFI_SGE_INLINE_MAX (BFI_SGE_INLINE + 1) + +/** + * SG Flags + */ +enum { + BFI_SGE_DATA = 0, /*!< data address, not last */ + BFI_SGE_DATA_CPL = 1, /*!< data addr, last in current page */ + BFI_SGE_DATA_LAST = 3, /*!< data address, last */ + BFI_SGE_LINK = 2, /*!< link address */ + BFI_SGE_PGDLEN = 2, /*!< cumulative data length for page */ +}; + +/** + * DMA addresses + */ +union bfi_addr_u { + struct { + u32 addr_lo; + u32 addr_hi; + } a32; +}; + +/** + * Scatter Gather Element + */ +struct bfi_sge { +#ifdef __BIGENDIAN + u32 flags:2, + rsvd:2, + sg_len:28; +#else + u32 sg_len:28, + rsvd:2, + flags:2; +#endif + union bfi_addr_u sga; +}; + +/** + * Scatter Gather Page + */ +#define BFI_SGPG_DATA_SGES 7 +#define BFI_SGPG_SGES_MAX (BFI_SGPG_DATA_SGES + 1) +#define BFI_SGPG_RSVD_WD_LEN 8 +struct bfi_sgpg { + struct bfi_sge sges[BFI_SGPG_SGES_MAX]; + u32 rsvd[BFI_SGPG_RSVD_WD_LEN]; +}; + +/* + * Large Message structure - 128 Bytes size Msgs + */ +#define BFI_LMSG_SZ 128 +#define BFI_LMSG_PL_WSZ \ + ((BFI_LMSG_SZ - sizeof(struct bfi_mhdr)) / 4) + +struct bfi_msg { + struct bfi_mhdr mhdr; + u32 pl[BFI_LMSG_PL_WSZ]; +}; + +/** + * Mailbox message structure + */ +#define BFI_MBMSG_SZ 7 +struct bfi_mbmsg { + struct bfi_mhdr mh; + u32 pl[BFI_MBMSG_SZ]; +}; + +/** + * Message Classes + */ +enum bfi_mclass { + BFI_MC_IOC = 1, /*!< IO Controller (IOC) */ + BFI_MC_DIAG = 2, /*!< Diagnostic Msgs */ + BFI_MC_FLASH = 3, /*!< Flash message class */ + BFI_MC_CEE = 4, /*!< CEE */ + BFI_MC_FCPORT = 5, /*!< FC port */ + BFI_MC_IOCFC = 6, /*!< FC - IO Controller (IOC) */ + BFI_MC_LL = 7, /*!< Link Layer */ + BFI_MC_UF = 8, /*!< Unsolicited frame receive */ + BFI_MC_FCXP = 9, /*!< FC Transport */ + BFI_MC_LPS = 10, /*!< lport fc login services */ + BFI_MC_RPORT = 11, /*!< Remote port */ + BFI_MC_ITNIM = 12, /*!< I-T nexus (Initiator mode) */ + BFI_MC_IOIM_READ = 13, /*!< read IO (Initiator mode) */ + BFI_MC_IOIM_WRITE = 14, /*!< write IO (Initiator mode) */ + BFI_MC_IOIM_IO = 15, /*!< IO (Initiator mode) */ + BFI_MC_IOIM = 16, /*!< IO (Initiator mode) */ + BFI_MC_IOIM_IOCOM = 17, /*!< good IO completion */ + BFI_MC_TSKIM = 18, /*!< Initiator Task management */ + BFI_MC_SBOOT = 19, /*!< SAN boot services */ + BFI_MC_IPFC = 20, /*!< IP over FC Msgs */ + BFI_MC_PORT = 21, /*!< Physical port */ + BFI_MC_SFP = 22, /*!< SFP module */ + BFI_MC_MSGQ = 23, /*!< MSGQ */ + BFI_MC_ENET = 24, /*!< ENET commands/responses */ + BFI_MC_MAX = 32 +}; + +#define BFI_IOC_MAX_CQS 4 +#define BFI_IOC_MAX_CQS_ASIC 8 +#define BFI_IOC_MSGLEN_MAX 32 /* 32 bytes */ + +#define BFI_BOOT_TYPE_OFF 8 +#define BFI_BOOT_PARAM_OFF 12 + +#define BFI_BOOT_TYPE_NORMAL 0 /* param is device id */ +#define BFI_BOOT_TYPE_FLASH 1 +#define BFI_BOOT_TYPE_MEMTEST 2 + +#define BFI_BOOT_MEMTEST_RES_ADDR 0x900 +#define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3 + +/** + *---------------------------------------------------------------------- + * IOC + *---------------------------------------------------------------------- + */ + +enum bfi_ioc_h2i_msgs { + BFI_IOC_H2I_ENABLE_REQ = 1, + BFI_IOC_H2I_DISABLE_REQ = 2, + BFI_IOC_H2I_GETATTR_REQ = 3, + BFI_IOC_H2I_DBG_SYNC = 4, + BFI_IOC_H2I_DBG_DUMP = 5, +}; + +enum bfi_ioc_i2h_msgs { + BFI_IOC_I2H_ENABLE_REPLY = BFA_I2HM(1), + BFI_IOC_I2H_DISABLE_REPLY = BFA_I2HM(2), + BFI_IOC_I2H_GETATTR_REPLY = BFA_I2HM(3), + BFI_IOC_I2H_READY_EVENT = BFA_I2HM(4), + BFI_IOC_I2H_HBEAT = BFA_I2HM(5), +}; + +/** + * BFI_IOC_H2I_GETATTR_REQ message + */ +struct bfi_ioc_getattr_req { + struct bfi_mhdr mh; + union bfi_addr_u attr_addr; +}; + +struct bfi_ioc_attr { + u64 mfg_pwwn; /*!< Mfg port wwn */ + u64 mfg_nwwn; /*!< Mfg node wwn */ + mac_t mfg_mac; /*!< Mfg mac */ + u16 rsvd_a; + u64 pwwn; + u64 nwwn; + mac_t mac; /*!< PBC or Mfg mac */ + u16 rsvd_b; + mac_t fcoe_mac; + u16 rsvd_c; + char brcd_serialnum[STRSZ(BFA_MFG_SERIALNUM_SIZE)]; + u8 pcie_gen; + u8 pcie_lanes_orig; + u8 pcie_lanes; + u8 rx_bbcredit; /*!< receive buffer credits */ + u32 adapter_prop; /*!< adapter properties */ + u16 maxfrsize; /*!< max receive frame size */ + char asic_rev; + u8 rsvd_d; + char fw_version[BFA_VERSION_LEN]; + char optrom_version[BFA_VERSION_LEN]; + struct bfa_mfg_vpd vpd; + u32 card_type; /*!< card type */ +}; + +/** + * BFI_IOC_I2H_GETATTR_REPLY message + */ +struct bfi_ioc_getattr_reply { + struct bfi_mhdr mh; /*!< Common msg header */ + u8 status; /*!< cfg reply status */ + u8 rsvd[3]; +}; + +/** + * Firmware memory page offsets + */ +#define BFI_IOC_SMEM_PG0_CB (0x40) +#define BFI_IOC_SMEM_PG0_CT (0x180) + +/** + * Firmware statistic offset + */ +#define BFI_IOC_FWSTATS_OFF (0x6B40) +#define BFI_IOC_FWSTATS_SZ (4096) + +/** + * Firmware trace offset + */ +#define BFI_IOC_TRC_OFF (0x4b00) +#define BFI_IOC_TRC_ENTS 256 + +#define BFI_IOC_FW_SIGNATURE (0xbfadbfad) +#define BFI_IOC_MD5SUM_SZ 4 +struct bfi_ioc_image_hdr { + u32 signature; /*!< constant signature */ + u32 rsvd_a; + u32 exec; /*!< exec vector */ + u32 param; /*!< parameters */ + u32 rsvd_b[4]; + u32 md5sum[BFI_IOC_MD5SUM_SZ]; +}; + +/** + * BFI_IOC_I2H_READY_EVENT message + */ +struct bfi_ioc_rdy_event { + struct bfi_mhdr mh; /*!< common msg header */ + u8 init_status; /*!< init event status */ + u8 rsvd[3]; +}; + +struct bfi_ioc_hbeat { + struct bfi_mhdr mh; /*!< common msg header */ + u32 hb_count; /*!< current heart beat count */ +}; + +/** + * IOC hardware/firmware state + */ +enum bfi_ioc_state { + BFI_IOC_UNINIT = 0, /*!< not initialized */ + BFI_IOC_INITING = 1, /*!< h/w is being initialized */ + BFI_IOC_HWINIT = 2, /*!< h/w is initialized */ + BFI_IOC_CFG = 3, /*!< IOC configuration in progress */ + BFI_IOC_OP = 4, /*!< IOC is operational */ + BFI_IOC_DISABLING = 5, /*!< IOC is being disabled */ + BFI_IOC_DISABLED = 6, /*!< IOC is disabled */ + BFI_IOC_CFG_DISABLED = 7, /*!< IOC is being disabled;transient */ + BFI_IOC_FAIL = 8, /*!< IOC heart-beat failure */ + BFI_IOC_MEMTEST = 9, /*!< IOC is doing memtest */ +}; + +#define BFI_IOC_ENDIAN_SIG 0x12345678 + +enum { + BFI_ADAPTER_TYPE_FC = 0x01, /*!< FC adapters */ + BFI_ADAPTER_TYPE_MK = 0x0f0000, /*!< adapter type mask */ + BFI_ADAPTER_TYPE_SH = 16, /*!< adapter type shift */ + BFI_ADAPTER_NPORTS_MK = 0xff00, /*!< number of ports mask */ + BFI_ADAPTER_NPORTS_SH = 8, /*!< number of ports shift */ + BFI_ADAPTER_SPEED_MK = 0xff, /*!< adapter speed mask */ + BFI_ADAPTER_SPEED_SH = 0, /*!< adapter speed shift */ + BFI_ADAPTER_PROTO = 0x100000, /*!< prototype adapaters */ + BFI_ADAPTER_TTV = 0x200000, /*!< TTV debug capable */ + BFI_ADAPTER_UNSUPP = 0x400000, /*!< unknown adapter type */ +}; + +#define BFI_ADAPTER_GETP(__prop, __adap_prop) \ + (((__adap_prop) & BFI_ADAPTER_ ## __prop ## _MK) >> \ + BFI_ADAPTER_ ## __prop ## _SH) +#define BFI_ADAPTER_SETP(__prop, __val) \ + ((__val) << BFI_ADAPTER_ ## __prop ## _SH) +#define BFI_ADAPTER_IS_PROTO(__adap_type) \ + ((__adap_type) & BFI_ADAPTER_PROTO) +#define BFI_ADAPTER_IS_TTV(__adap_type) \ + ((__adap_type) & BFI_ADAPTER_TTV) +#define BFI_ADAPTER_IS_UNSUPP(__adap_type) \ + ((__adap_type) & BFI_ADAPTER_UNSUPP) +#define BFI_ADAPTER_IS_SPECIAL(__adap_type) \ + ((__adap_type) & (BFI_ADAPTER_TTV | BFI_ADAPTER_PROTO | \ + BFI_ADAPTER_UNSUPP)) + +/** + * BFI_IOC_H2I_ENABLE_REQ & BFI_IOC_H2I_DISABLE_REQ messages + */ +struct bfi_ioc_ctrl_req { + struct bfi_mhdr mh; + u8 ioc_class; + u8 rsvd[3]; + u32 tv_sec; +}; + +/** + * BFI_IOC_I2H_ENABLE_REPLY & BFI_IOC_I2H_DISABLE_REPLY messages + */ +struct bfi_ioc_ctrl_reply { + struct bfi_mhdr mh; /*!< Common msg header */ + u8 status; /*!< enable/disable status */ + u8 rsvd[3]; +}; + +#define BFI_IOC_MSGSZ 8 +/** + * H2I Messages + */ +union bfi_ioc_h2i_msg_u { + struct bfi_mhdr mh; + struct bfi_ioc_ctrl_req enable_req; + struct bfi_ioc_ctrl_req disable_req; + struct bfi_ioc_getattr_req getattr_req; + u32 mboxmsg[BFI_IOC_MSGSZ]; +}; + +/** + * I2H Messages + */ +union bfi_ioc_i2h_msg_u { + struct bfi_mhdr mh; + struct bfi_ioc_rdy_event rdy_event; + u32 mboxmsg[BFI_IOC_MSGSZ]; +}; + +#pragma pack() + +#endif /* __BFI_H__ */ diff --git a/drivers/net/bna/bfi_cna.h b/drivers/net/bna/bfi_cna.h new file mode 100644 index 0000000000000000000000000000000000000000..4eecabea397b74b6add61ba68064c18c91003e33 --- /dev/null +++ b/drivers/net/bna/bfi_cna.h @@ -0,0 +1,199 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BFI_CNA_H__ +#define __BFI_CNA_H__ + +#include "bfi.h" +#include "bfa_defs_cna.h" + +#pragma pack(1) + +enum bfi_port_h2i { + BFI_PORT_H2I_ENABLE_REQ = (1), + BFI_PORT_H2I_DISABLE_REQ = (2), + BFI_PORT_H2I_GET_STATS_REQ = (3), + BFI_PORT_H2I_CLEAR_STATS_REQ = (4), +}; + +enum bfi_port_i2h { + BFI_PORT_I2H_ENABLE_RSP = BFA_I2HM(1), + BFI_PORT_I2H_DISABLE_RSP = BFA_I2HM(2), + BFI_PORT_I2H_GET_STATS_RSP = BFA_I2HM(3), + BFI_PORT_I2H_CLEAR_STATS_RSP = BFA_I2HM(4), +}; + +/** + * Generic REQ type + */ +struct bfi_port_generic_req { + struct bfi_mhdr mh; /*!< msg header */ + u32 msgtag; /*!< msgtag for reply */ + u32 rsvd; +}; + +/** + * Generic RSP type + */ +struct bfi_port_generic_rsp { + struct bfi_mhdr mh; /*!< common msg header */ + u8 status; /*!< port enable status */ + u8 rsvd[3]; + u32 msgtag; /*!< msgtag for reply */ +}; + +/** + * @todo + * BFI_PORT_H2I_ENABLE_REQ + */ + +/** + * @todo + * BFI_PORT_I2H_ENABLE_RSP + */ + +/** + * BFI_PORT_H2I_DISABLE_REQ + */ + +/** + * BFI_PORT_I2H_DISABLE_RSP + */ + +/** + * BFI_PORT_H2I_GET_STATS_REQ + */ +struct bfi_port_get_stats_req { + struct bfi_mhdr mh; /*!< common msg header */ + union bfi_addr_u dma_addr; +}; + +/** + * BFI_PORT_I2H_GET_STATS_RSP + */ + +/** + * BFI_PORT_H2I_CLEAR_STATS_REQ + */ + +/** + * BFI_PORT_I2H_CLEAR_STATS_RSP + */ + +union bfi_port_h2i_msg_u { + struct bfi_mhdr mh; + struct bfi_port_generic_req enable_req; + struct bfi_port_generic_req disable_req; + struct bfi_port_get_stats_req getstats_req; + struct bfi_port_generic_req clearstats_req; +}; + +union bfi_port_i2h_msg_u { + struct bfi_mhdr mh; + struct bfi_port_generic_rsp enable_rsp; + struct bfi_port_generic_rsp disable_rsp; + struct bfi_port_generic_rsp getstats_rsp; + struct bfi_port_generic_rsp clearstats_rsp; +}; + +/* @brief Mailbox commands from host to (DCBX/LLDP) firmware */ +enum bfi_cee_h2i_msgs { + BFI_CEE_H2I_GET_CFG_REQ = 1, + BFI_CEE_H2I_RESET_STATS = 2, + BFI_CEE_H2I_GET_STATS_REQ = 3, +}; + +/* @brief Mailbox reply and AEN messages from DCBX/LLDP firmware to host */ +enum bfi_cee_i2h_msgs { + BFI_CEE_I2H_GET_CFG_RSP = BFA_I2HM(1), + BFI_CEE_I2H_RESET_STATS_RSP = BFA_I2HM(2), + BFI_CEE_I2H_GET_STATS_RSP = BFA_I2HM(3), +}; + +/* Data structures */ + +/* + * @brief H2I command structure for resetting the stats. + * BFI_CEE_H2I_RESET_STATS + */ +struct bfi_lldp_reset_stats { + struct bfi_mhdr mh; +}; + +/* + * @brief H2I command structure for resetting the stats. + * BFI_CEE_H2I_RESET_STATS + */ +struct bfi_cee_reset_stats { + struct bfi_mhdr mh; +}; + +/* + * @brief get configuration command from host + * BFI_CEE_H2I_GET_CFG_REQ + */ +struct bfi_cee_get_req { + struct bfi_mhdr mh; + union bfi_addr_u dma_addr; +}; + +/* + * @brief reply message from firmware + * BFI_CEE_I2H_GET_CFG_RSP + */ +struct bfi_cee_get_rsp { + struct bfi_mhdr mh; + u8 cmd_status; + u8 rsvd[3]; +}; + +/* + * @brief get configuration command from host + * BFI_CEE_H2I_GET_STATS_REQ + */ +struct bfi_cee_stats_req { + struct bfi_mhdr mh; + union bfi_addr_u dma_addr; +}; + +/* + * @brief reply message from firmware + * BFI_CEE_I2H_GET_STATS_RSP + */ +struct bfi_cee_stats_rsp { + struct bfi_mhdr mh; + u8 cmd_status; + u8 rsvd[3]; +}; + +/* @brief mailbox command structures from host to firmware */ +union bfi_cee_h2i_msg_u { + struct bfi_mhdr mh; + struct bfi_cee_get_req get_req; + struct bfi_cee_stats_req stats_req; +}; + +/* @brief mailbox message structures from firmware to host */ +union bfi_cee_i2h_msg_u { + struct bfi_mhdr mh; + struct bfi_cee_get_rsp get_rsp; + struct bfi_cee_stats_rsp stats_rsp; +}; + +#pragma pack() + +#endif /* __BFI_CNA_H__ */ diff --git a/drivers/net/bna/bfi_ctreg.h b/drivers/net/bna/bfi_ctreg.h new file mode 100644 index 0000000000000000000000000000000000000000..404ea351d4a164429a9b81eba74c33e1e2b89afa --- /dev/null +++ b/drivers/net/bna/bfi_ctreg.h @@ -0,0 +1,637 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +/* + * bfi_ctreg.h catapult host block register definitions + * + * !!! Do not edit. Auto generated. !!! + */ + +#ifndef __BFI_CTREG_H__ +#define __BFI_CTREG_H__ + +#define HOSTFN0_LPU_MBOX0_0 0x00019200 +#define HOSTFN1_LPU_MBOX0_8 0x00019260 +#define LPU_HOSTFN0_MBOX0_0 0x00019280 +#define LPU_HOSTFN1_MBOX0_8 0x000192e0 +#define HOSTFN2_LPU_MBOX0_0 0x00019400 +#define HOSTFN3_LPU_MBOX0_8 0x00019460 +#define LPU_HOSTFN2_MBOX0_0 0x00019480 +#define LPU_HOSTFN3_MBOX0_8 0x000194e0 +#define HOSTFN0_INT_STATUS 0x00014000 +#define __HOSTFN0_HALT_OCCURRED 0x01000000 +#define __HOSTFN0_INT_STATUS_LVL_MK 0x00f00000 +#define __HOSTFN0_INT_STATUS_LVL_SH 20 +#define __HOSTFN0_INT_STATUS_LVL(_v) ((_v) << __HOSTFN0_INT_STATUS_LVL_SH) +#define __HOSTFN0_INT_STATUS_P_MK 0x000f0000 +#define __HOSTFN0_INT_STATUS_P_SH 16 +#define __HOSTFN0_INT_STATUS_P(_v) ((_v) << __HOSTFN0_INT_STATUS_P_SH) +#define __HOSTFN0_INT_STATUS_F 0x0000ffff +#define HOSTFN0_INT_MSK 0x00014004 +#define HOST_PAGE_NUM_FN0 0x00014008 +#define __HOST_PAGE_NUM_FN 0x000001ff +#define HOST_MSIX_ERR_INDEX_FN0 0x0001400c +#define __MSIX_ERR_INDEX_FN 0x000001ff +#define HOSTFN1_INT_STATUS 0x00014100 +#define __HOSTFN1_HALT_OCCURRED 0x01000000 +#define __HOSTFN1_INT_STATUS_LVL_MK 0x00f00000 +#define __HOSTFN1_INT_STATUS_LVL_SH 20 +#define __HOSTFN1_INT_STATUS_LVL(_v) ((_v) << __HOSTFN1_INT_STATUS_LVL_SH) +#define __HOSTFN1_INT_STATUS_P_MK 0x000f0000 +#define __HOSTFN1_INT_STATUS_P_SH 16 +#define __HOSTFN1_INT_STATUS_P(_v) ((_v) << __HOSTFN1_INT_STATUS_P_SH) +#define __HOSTFN1_INT_STATUS_F 0x0000ffff +#define HOSTFN1_INT_MSK 0x00014104 +#define HOST_PAGE_NUM_FN1 0x00014108 +#define HOST_MSIX_ERR_INDEX_FN1 0x0001410c +#define APP_PLL_425_CTL_REG 0x00014204 +#define __P_425_PLL_LOCK 0x80000000 +#define __APP_PLL_425_SRAM_USE_100MHZ 0x00100000 +#define __APP_PLL_425_RESET_TIMER_MK 0x000e0000 +#define __APP_PLL_425_RESET_TIMER_SH 17 +#define __APP_PLL_425_RESET_TIMER(_v) ((_v) << __APP_PLL_425_RESET_TIMER_SH) +#define __APP_PLL_425_LOGIC_SOFT_RESET 0x00010000 +#define __APP_PLL_425_CNTLMT0_1_MK 0x0000c000 +#define __APP_PLL_425_CNTLMT0_1_SH 14 +#define __APP_PLL_425_CNTLMT0_1(_v) ((_v) << __APP_PLL_425_CNTLMT0_1_SH) +#define __APP_PLL_425_JITLMT0_1_MK 0x00003000 +#define __APP_PLL_425_JITLMT0_1_SH 12 +#define __APP_PLL_425_JITLMT0_1(_v) ((_v) << __APP_PLL_425_JITLMT0_1_SH) +#define __APP_PLL_425_HREF 0x00000800 +#define __APP_PLL_425_HDIV 0x00000400 +#define __APP_PLL_425_P0_1_MK 0x00000300 +#define __APP_PLL_425_P0_1_SH 8 +#define __APP_PLL_425_P0_1(_v) ((_v) << __APP_PLL_425_P0_1_SH) +#define __APP_PLL_425_Z0_2_MK 0x000000e0 +#define __APP_PLL_425_Z0_2_SH 5 +#define __APP_PLL_425_Z0_2(_v) ((_v) << __APP_PLL_425_Z0_2_SH) +#define __APP_PLL_425_RSEL200500 0x00000010 +#define __APP_PLL_425_ENARST 0x00000008 +#define __APP_PLL_425_BYPASS 0x00000004 +#define __APP_PLL_425_LRESETN 0x00000002 +#define __APP_PLL_425_ENABLE 0x00000001 +#define APP_PLL_312_CTL_REG 0x00014208 +#define __P_312_PLL_LOCK 0x80000000 +#define __ENABLE_MAC_AHB_1 0x00800000 +#define __ENABLE_MAC_AHB_0 0x00400000 +#define __ENABLE_MAC_1 0x00200000 +#define __ENABLE_MAC_0 0x00100000 +#define __APP_PLL_312_RESET_TIMER_MK 0x000e0000 +#define __APP_PLL_312_RESET_TIMER_SH 17 +#define __APP_PLL_312_RESET_TIMER(_v) ((_v) << __APP_PLL_312_RESET_TIMER_SH) +#define __APP_PLL_312_LOGIC_SOFT_RESET 0x00010000 +#define __APP_PLL_312_CNTLMT0_1_MK 0x0000c000 +#define __APP_PLL_312_CNTLMT0_1_SH 14 +#define __APP_PLL_312_CNTLMT0_1(_v) ((_v) << __APP_PLL_312_CNTLMT0_1_SH) +#define __APP_PLL_312_JITLMT0_1_MK 0x00003000 +#define __APP_PLL_312_JITLMT0_1_SH 12 +#define __APP_PLL_312_JITLMT0_1(_v) ((_v) << __APP_PLL_312_JITLMT0_1_SH) +#define __APP_PLL_312_HREF 0x00000800 +#define __APP_PLL_312_HDIV 0x00000400 +#define __APP_PLL_312_P0_1_MK 0x00000300 +#define __APP_PLL_312_P0_1_SH 8 +#define __APP_PLL_312_P0_1(_v) ((_v) << __APP_PLL_312_P0_1_SH) +#define __APP_PLL_312_Z0_2_MK 0x000000e0 +#define __APP_PLL_312_Z0_2_SH 5 +#define __APP_PLL_312_Z0_2(_v) ((_v) << __APP_PLL_312_Z0_2_SH) +#define __APP_PLL_312_RSEL200500 0x00000010 +#define __APP_PLL_312_ENARST 0x00000008 +#define __APP_PLL_312_BYPASS 0x00000004 +#define __APP_PLL_312_LRESETN 0x00000002 +#define __APP_PLL_312_ENABLE 0x00000001 +#define MBIST_CTL_REG 0x00014220 +#define __EDRAM_BISTR_START 0x00000004 +#define __MBIST_RESET 0x00000002 +#define __MBIST_START 0x00000001 +#define MBIST_STAT_REG 0x00014224 +#define __EDRAM_BISTR_STATUS 0x00000008 +#define __EDRAM_BISTR_DONE 0x00000004 +#define __MEM_BIT_STATUS 0x00000002 +#define __MBIST_DONE 0x00000001 +#define HOST_SEM0_REG 0x00014230 +#define __HOST_SEMAPHORE 0x00000001 +#define HOST_SEM1_REG 0x00014234 +#define HOST_SEM2_REG 0x00014238 +#define HOST_SEM3_REG 0x0001423c +#define HOST_SEM0_INFO_REG 0x00014240 +#define HOST_SEM1_INFO_REG 0x00014244 +#define HOST_SEM2_INFO_REG 0x00014248 +#define HOST_SEM3_INFO_REG 0x0001424c +#define ETH_MAC_SER_REG 0x00014288 +#define __APP_EMS_CKBUFAMPIN 0x00000020 +#define __APP_EMS_REFCLKSEL 0x00000010 +#define __APP_EMS_CMLCKSEL 0x00000008 +#define __APP_EMS_REFCKBUFEN2 0x00000004 +#define __APP_EMS_REFCKBUFEN1 0x00000002 +#define __APP_EMS_CHANNEL_SEL 0x00000001 +#define HOSTFN2_INT_STATUS 0x00014300 +#define __HOSTFN2_HALT_OCCURRED 0x01000000 +#define __HOSTFN2_INT_STATUS_LVL_MK 0x00f00000 +#define __HOSTFN2_INT_STATUS_LVL_SH 20 +#define __HOSTFN2_INT_STATUS_LVL(_v) ((_v) << __HOSTFN2_INT_STATUS_LVL_SH) +#define __HOSTFN2_INT_STATUS_P_MK 0x000f0000 +#define __HOSTFN2_INT_STATUS_P_SH 16 +#define __HOSTFN2_INT_STATUS_P(_v) ((_v) << __HOSTFN2_INT_STATUS_P_SH) +#define __HOSTFN2_INT_STATUS_F 0x0000ffff +#define HOSTFN2_INT_MSK 0x00014304 +#define HOST_PAGE_NUM_FN2 0x00014308 +#define HOST_MSIX_ERR_INDEX_FN2 0x0001430c +#define HOSTFN3_INT_STATUS 0x00014400 +#define __HALT_OCCURRED 0x01000000 +#define __HOSTFN3_INT_STATUS_LVL_MK 0x00f00000 +#define __HOSTFN3_INT_STATUS_LVL_SH 20 +#define __HOSTFN3_INT_STATUS_LVL(_v) ((_v) << __HOSTFN3_INT_STATUS_LVL_SH) +#define __HOSTFN3_INT_STATUS_P_MK 0x000f0000 +#define __HOSTFN3_INT_STATUS_P_SH 16 +#define __HOSTFN3_INT_STATUS_P(_v) ((_v) << __HOSTFN3_INT_STATUS_P_SH) +#define __HOSTFN3_INT_STATUS_F 0x0000ffff +#define HOSTFN3_INT_MSK 0x00014404 +#define HOST_PAGE_NUM_FN3 0x00014408 +#define HOST_MSIX_ERR_INDEX_FN3 0x0001440c +#define FNC_ID_REG 0x00014600 +#define __FUNCTION_NUMBER 0x00000007 +#define FNC_PERS_REG 0x00014604 +#define __F3_FUNCTION_ACTIVE 0x80000000 +#define __F3_FUNCTION_MODE 0x40000000 +#define __F3_PORT_MAP_MK 0x30000000 +#define __F3_PORT_MAP_SH 28 +#define __F3_PORT_MAP(_v) ((_v) << __F3_PORT_MAP_SH) +#define __F3_VM_MODE 0x08000000 +#define __F3_INTX_STATUS_MK 0x07000000 +#define __F3_INTX_STATUS_SH 24 +#define __F3_INTX_STATUS(_v) ((_v) << __F3_INTX_STATUS_SH) +#define __F2_FUNCTION_ACTIVE 0x00800000 +#define __F2_FUNCTION_MODE 0x00400000 +#define __F2_PORT_MAP_MK 0x00300000 +#define __F2_PORT_MAP_SH 20 +#define __F2_PORT_MAP(_v) ((_v) << __F2_PORT_MAP_SH) +#define __F2_VM_MODE 0x00080000 +#define __F2_INTX_STATUS_MK 0x00070000 +#define __F2_INTX_STATUS_SH 16 +#define __F2_INTX_STATUS(_v) ((_v) << __F2_INTX_STATUS_SH) +#define __F1_FUNCTION_ACTIVE 0x00008000 +#define __F1_FUNCTION_MODE 0x00004000 +#define __F1_PORT_MAP_MK 0x00003000 +#define __F1_PORT_MAP_SH 12 +#define __F1_PORT_MAP(_v) ((_v) << __F1_PORT_MAP_SH) +#define __F1_VM_MODE 0x00000800 +#define __F1_INTX_STATUS_MK 0x00000700 +#define __F1_INTX_STATUS_SH 8 +#define __F1_INTX_STATUS(_v) ((_v) << __F1_INTX_STATUS_SH) +#define __F0_FUNCTION_ACTIVE 0x00000080 +#define __F0_FUNCTION_MODE 0x00000040 +#define __F0_PORT_MAP_MK 0x00000030 +#define __F0_PORT_MAP_SH 4 +#define __F0_PORT_MAP(_v) ((_v) << __F0_PORT_MAP_SH) +#define __F0_VM_MODE 0x00000008 +#define __F0_INTX_STATUS 0x00000007 +enum { + __F0_INTX_STATUS_MSIX = 0x0, + __F0_INTX_STATUS_INTA = 0x1, + __F0_INTX_STATUS_INTB = 0x2, + __F0_INTX_STATUS_INTC = 0x3, + __F0_INTX_STATUS_INTD = 0x4, +}; +#define OP_MODE 0x0001460c +#define __APP_ETH_CLK_LOWSPEED 0x00000004 +#define __GLOBAL_CORECLK_HALFSPEED 0x00000002 +#define __GLOBAL_FCOE_MODE 0x00000001 +#define HOST_SEM4_REG 0x00014610 +#define HOST_SEM5_REG 0x00014614 +#define HOST_SEM6_REG 0x00014618 +#define HOST_SEM7_REG 0x0001461c +#define HOST_SEM4_INFO_REG 0x00014620 +#define HOST_SEM5_INFO_REG 0x00014624 +#define HOST_SEM6_INFO_REG 0x00014628 +#define HOST_SEM7_INFO_REG 0x0001462c +#define HOSTFN0_LPU0_MBOX0_CMD_STAT 0x00019000 +#define __HOSTFN0_LPU0_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN0_LPU0_MBOX0_INFO_SH 1 +#define __HOSTFN0_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU0_MBOX0_INFO_SH) +#define __HOSTFN0_LPU0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN0_LPU1_MBOX0_CMD_STAT 0x00019004 +#define __HOSTFN0_LPU1_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN0_LPU1_MBOX0_INFO_SH 1 +#define __HOSTFN0_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN0_LPU1_MBOX0_INFO_SH) +#define __HOSTFN0_LPU1_MBOX0_CMD_STATUS 0x00000001 +#define LPU0_HOSTFN0_MBOX0_CMD_STAT 0x00019008 +#define __LPU0_HOSTFN0_MBOX0_INFO_MK 0xfffffffe +#define __LPU0_HOSTFN0_MBOX0_INFO_SH 1 +#define __LPU0_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN0_MBOX0_INFO_SH) +#define __LPU0_HOSTFN0_MBOX0_CMD_STATUS 0x00000001 +#define LPU1_HOSTFN0_MBOX0_CMD_STAT 0x0001900c +#define __LPU1_HOSTFN0_MBOX0_INFO_MK 0xfffffffe +#define __LPU1_HOSTFN0_MBOX0_INFO_SH 1 +#define __LPU1_HOSTFN0_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN0_MBOX0_INFO_SH) +#define __LPU1_HOSTFN0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN1_LPU0_MBOX0_CMD_STAT 0x00019010 +#define __HOSTFN1_LPU0_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN1_LPU0_MBOX0_INFO_SH 1 +#define __HOSTFN1_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU0_MBOX0_INFO_SH) +#define __HOSTFN1_LPU0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN1_LPU1_MBOX0_CMD_STAT 0x00019014 +#define __HOSTFN1_LPU1_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN1_LPU1_MBOX0_INFO_SH 1 +#define __HOSTFN1_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN1_LPU1_MBOX0_INFO_SH) +#define __HOSTFN1_LPU1_MBOX0_CMD_STATUS 0x00000001 +#define LPU0_HOSTFN1_MBOX0_CMD_STAT 0x00019018 +#define __LPU0_HOSTFN1_MBOX0_INFO_MK 0xfffffffe +#define __LPU0_HOSTFN1_MBOX0_INFO_SH 1 +#define __LPU0_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN1_MBOX0_INFO_SH) +#define __LPU0_HOSTFN1_MBOX0_CMD_STATUS 0x00000001 +#define LPU1_HOSTFN1_MBOX0_CMD_STAT 0x0001901c +#define __LPU1_HOSTFN1_MBOX0_INFO_MK 0xfffffffe +#define __LPU1_HOSTFN1_MBOX0_INFO_SH 1 +#define __LPU1_HOSTFN1_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN1_MBOX0_INFO_SH) +#define __LPU1_HOSTFN1_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN2_LPU0_MBOX0_CMD_STAT 0x00019150 +#define __HOSTFN2_LPU0_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN2_LPU0_MBOX0_INFO_SH 1 +#define __HOSTFN2_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU0_MBOX0_INFO_SH) +#define __HOSTFN2_LPU0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN2_LPU1_MBOX0_CMD_STAT 0x00019154 +#define __HOSTFN2_LPU1_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN2_LPU1_MBOX0_INFO_SH 1 +#define __HOSTFN2_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN2_LPU1_MBOX0_INFO_SH) +#define __HOSTFN2_LPU1_MBOX0BOX0_CMD_STATUS 0x00000001 +#define LPU0_HOSTFN2_MBOX0_CMD_STAT 0x00019158 +#define __LPU0_HOSTFN2_MBOX0_INFO_MK 0xfffffffe +#define __LPU0_HOSTFN2_MBOX0_INFO_SH 1 +#define __LPU0_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN2_MBOX0_INFO_SH) +#define __LPU0_HOSTFN2_MBOX0_CMD_STATUS 0x00000001 +#define LPU1_HOSTFN2_MBOX0_CMD_STAT 0x0001915c +#define __LPU1_HOSTFN2_MBOX0_INFO_MK 0xfffffffe +#define __LPU1_HOSTFN2_MBOX0_INFO_SH 1 +#define __LPU1_HOSTFN2_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN2_MBOX0_INFO_SH) +#define __LPU1_HOSTFN2_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN3_LPU0_MBOX0_CMD_STAT 0x00019160 +#define __HOSTFN3_LPU0_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN3_LPU0_MBOX0_INFO_SH 1 +#define __HOSTFN3_LPU0_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU0_MBOX0_INFO_SH) +#define __HOSTFN3_LPU0_MBOX0_CMD_STATUS 0x00000001 +#define HOSTFN3_LPU1_MBOX0_CMD_STAT 0x00019164 +#define __HOSTFN3_LPU1_MBOX0_INFO_MK 0xfffffffe +#define __HOSTFN3_LPU1_MBOX0_INFO_SH 1 +#define __HOSTFN3_LPU1_MBOX0_INFO(_v) ((_v) << __HOSTFN3_LPU1_MBOX0_INFO_SH) +#define __HOSTFN3_LPU1_MBOX0_CMD_STATUS 0x00000001 +#define LPU0_HOSTFN3_MBOX0_CMD_STAT 0x00019168 +#define __LPU0_HOSTFN3_MBOX0_INFO_MK 0xfffffffe +#define __LPU0_HOSTFN3_MBOX0_INFO_SH 1 +#define __LPU0_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU0_HOSTFN3_MBOX0_INFO_SH) +#define __LPU0_HOSTFN3_MBOX0_CMD_STATUS 0x00000001 +#define LPU1_HOSTFN3_MBOX0_CMD_STAT 0x0001916c +#define __LPU1_HOSTFN3_MBOX0_INFO_MK 0xfffffffe +#define __LPU1_HOSTFN3_MBOX0_INFO_SH 1 +#define __LPU1_HOSTFN3_MBOX0_INFO(_v) ((_v) << __LPU1_HOSTFN3_MBOX0_INFO_SH) +#define __LPU1_HOSTFN3_MBOX0_CMD_STATUS 0x00000001 +#define FW_INIT_HALT_P0 0x000191ac +#define __FW_INIT_HALT_P 0x00000001 +#define FW_INIT_HALT_P1 0x000191bc +#define CPE_PI_PTR_Q0 0x00038000 +#define __CPE_PI_UNUSED_MK 0xffff0000 +#define __CPE_PI_UNUSED_SH 16 +#define __CPE_PI_UNUSED(_v) ((_v) << __CPE_PI_UNUSED_SH) +#define __CPE_PI_PTR 0x0000ffff +#define CPE_PI_PTR_Q1 0x00038040 +#define CPE_CI_PTR_Q0 0x00038004 +#define __CPE_CI_UNUSED_MK 0xffff0000 +#define __CPE_CI_UNUSED_SH 16 +#define __CPE_CI_UNUSED(_v) ((_v) << __CPE_CI_UNUSED_SH) +#define __CPE_CI_PTR 0x0000ffff +#define CPE_CI_PTR_Q1 0x00038044 +#define CPE_DEPTH_Q0 0x00038008 +#define __CPE_DEPTH_UNUSED_MK 0xf8000000 +#define __CPE_DEPTH_UNUSED_SH 27 +#define __CPE_DEPTH_UNUSED(_v) ((_v) << __CPE_DEPTH_UNUSED_SH) +#define __CPE_MSIX_VEC_INDEX_MK 0x07ff0000 +#define __CPE_MSIX_VEC_INDEX_SH 16 +#define __CPE_MSIX_VEC_INDEX(_v) ((_v) << __CPE_MSIX_VEC_INDEX_SH) +#define __CPE_DEPTH 0x0000ffff +#define CPE_DEPTH_Q1 0x00038048 +#define CPE_QCTRL_Q0 0x0003800c +#define __CPE_CTRL_UNUSED30_MK 0xfc000000 +#define __CPE_CTRL_UNUSED30_SH 26 +#define __CPE_CTRL_UNUSED30(_v) ((_v) << __CPE_CTRL_UNUSED30_SH) +#define __CPE_FUNC_INT_CTRL_MK 0x03000000 +#define __CPE_FUNC_INT_CTRL_SH 24 +#define __CPE_FUNC_INT_CTRL(_v) ((_v) << __CPE_FUNC_INT_CTRL_SH) +enum { + __CPE_FUNC_INT_CTRL_DISABLE = 0x0, + __CPE_FUNC_INT_CTRL_F2NF = 0x1, + __CPE_FUNC_INT_CTRL_3QUART = 0x2, + __CPE_FUNC_INT_CTRL_HALF = 0x3, +}; +#define __CPE_CTRL_UNUSED20_MK 0x00f00000 +#define __CPE_CTRL_UNUSED20_SH 20 +#define __CPE_CTRL_UNUSED20(_v) ((_v) << __CPE_CTRL_UNUSED20_SH) +#define __CPE_SCI_TH_MK 0x000f0000 +#define __CPE_SCI_TH_SH 16 +#define __CPE_SCI_TH(_v) ((_v) << __CPE_SCI_TH_SH) +#define __CPE_CTRL_UNUSED10_MK 0x0000c000 +#define __CPE_CTRL_UNUSED10_SH 14 +#define __CPE_CTRL_UNUSED10(_v) ((_v) << __CPE_CTRL_UNUSED10_SH) +#define __CPE_ACK_PENDING 0x00002000 +#define __CPE_CTRL_UNUSED40_MK 0x00001c00 +#define __CPE_CTRL_UNUSED40_SH 10 +#define __CPE_CTRL_UNUSED40(_v) ((_v) << __CPE_CTRL_UNUSED40_SH) +#define __CPE_PCIEID_MK 0x00000300 +#define __CPE_PCIEID_SH 8 +#define __CPE_PCIEID(_v) ((_v) << __CPE_PCIEID_SH) +#define __CPE_CTRL_UNUSED00_MK 0x000000fe +#define __CPE_CTRL_UNUSED00_SH 1 +#define __CPE_CTRL_UNUSED00(_v) ((_v) << __CPE_CTRL_UNUSED00_SH) +#define __CPE_ESIZE 0x00000001 +#define CPE_QCTRL_Q1 0x0003804c +#define __CPE_CTRL_UNUSED31_MK 0xfc000000 +#define __CPE_CTRL_UNUSED31_SH 26 +#define __CPE_CTRL_UNUSED31(_v) ((_v) << __CPE_CTRL_UNUSED31_SH) +#define __CPE_CTRL_UNUSED21_MK 0x00f00000 +#define __CPE_CTRL_UNUSED21_SH 20 +#define __CPE_CTRL_UNUSED21(_v) ((_v) << __CPE_CTRL_UNUSED21_SH) +#define __CPE_CTRL_UNUSED11_MK 0x0000c000 +#define __CPE_CTRL_UNUSED11_SH 14 +#define __CPE_CTRL_UNUSED11(_v) ((_v) << __CPE_CTRL_UNUSED11_SH) +#define __CPE_CTRL_UNUSED41_MK 0x00001c00 +#define __CPE_CTRL_UNUSED41_SH 10 +#define __CPE_CTRL_UNUSED41(_v) ((_v) << __CPE_CTRL_UNUSED41_SH) +#define __CPE_CTRL_UNUSED01_MK 0x000000fe +#define __CPE_CTRL_UNUSED01_SH 1 +#define __CPE_CTRL_UNUSED01(_v) ((_v) << __CPE_CTRL_UNUSED01_SH) +#define RME_PI_PTR_Q0 0x00038020 +#define __LATENCY_TIME_STAMP_MK 0xffff0000 +#define __LATENCY_TIME_STAMP_SH 16 +#define __LATENCY_TIME_STAMP(_v) ((_v) << __LATENCY_TIME_STAMP_SH) +#define __RME_PI_PTR 0x0000ffff +#define RME_PI_PTR_Q1 0x00038060 +#define RME_CI_PTR_Q0 0x00038024 +#define __DELAY_TIME_STAMP_MK 0xffff0000 +#define __DELAY_TIME_STAMP_SH 16 +#define __DELAY_TIME_STAMP(_v) ((_v) << __DELAY_TIME_STAMP_SH) +#define __RME_CI_PTR 0x0000ffff +#define RME_CI_PTR_Q1 0x00038064 +#define RME_DEPTH_Q0 0x00038028 +#define __RME_DEPTH_UNUSED_MK 0xf8000000 +#define __RME_DEPTH_UNUSED_SH 27 +#define __RME_DEPTH_UNUSED(_v) ((_v) << __RME_DEPTH_UNUSED_SH) +#define __RME_MSIX_VEC_INDEX_MK 0x07ff0000 +#define __RME_MSIX_VEC_INDEX_SH 16 +#define __RME_MSIX_VEC_INDEX(_v) ((_v) << __RME_MSIX_VEC_INDEX_SH) +#define __RME_DEPTH 0x0000ffff +#define RME_DEPTH_Q1 0x00038068 +#define RME_QCTRL_Q0 0x0003802c +#define __RME_INT_LATENCY_TIMER_MK 0xff000000 +#define __RME_INT_LATENCY_TIMER_SH 24 +#define __RME_INT_LATENCY_TIMER(_v) ((_v) << __RME_INT_LATENCY_TIMER_SH) +#define __RME_INT_DELAY_TIMER_MK 0x00ff0000 +#define __RME_INT_DELAY_TIMER_SH 16 +#define __RME_INT_DELAY_TIMER(_v) ((_v) << __RME_INT_DELAY_TIMER_SH) +#define __RME_INT_DELAY_DISABLE 0x00008000 +#define __RME_DLY_DELAY_DISABLE 0x00004000 +#define __RME_ACK_PENDING 0x00002000 +#define __RME_FULL_INTERRUPT_DISABLE 0x00001000 +#define __RME_CTRL_UNUSED10_MK 0x00000c00 +#define __RME_CTRL_UNUSED10_SH 10 +#define __RME_CTRL_UNUSED10(_v) ((_v) << __RME_CTRL_UNUSED10_SH) +#define __RME_PCIEID_MK 0x00000300 +#define __RME_PCIEID_SH 8 +#define __RME_PCIEID(_v) ((_v) << __RME_PCIEID_SH) +#define __RME_CTRL_UNUSED00_MK 0x000000fe +#define __RME_CTRL_UNUSED00_SH 1 +#define __RME_CTRL_UNUSED00(_v) ((_v) << __RME_CTRL_UNUSED00_SH) +#define __RME_ESIZE 0x00000001 +#define RME_QCTRL_Q1 0x0003806c +#define __RME_CTRL_UNUSED11_MK 0x00000c00 +#define __RME_CTRL_UNUSED11_SH 10 +#define __RME_CTRL_UNUSED11(_v) ((_v) << __RME_CTRL_UNUSED11_SH) +#define __RME_CTRL_UNUSED01_MK 0x000000fe +#define __RME_CTRL_UNUSED01_SH 1 +#define __RME_CTRL_UNUSED01(_v) ((_v) << __RME_CTRL_UNUSED01_SH) +#define PSS_CTL_REG 0x00018800 +#define __PSS_I2C_CLK_DIV_MK 0x007f0000 +#define __PSS_I2C_CLK_DIV_SH 16 +#define __PSS_I2C_CLK_DIV(_v) ((_v) << __PSS_I2C_CLK_DIV_SH) +#define __PSS_LMEM_INIT_DONE 0x00001000 +#define __PSS_LMEM_RESET 0x00000200 +#define __PSS_LMEM_INIT_EN 0x00000100 +#define __PSS_LPU1_RESET 0x00000002 +#define __PSS_LPU0_RESET 0x00000001 +#define PSS_ERR_STATUS_REG 0x00018810 +#define __PSS_LPU1_TCM_READ_ERR 0x00200000 +#define __PSS_LPU0_TCM_READ_ERR 0x00100000 +#define __PSS_LMEM5_CORR_ERR 0x00080000 +#define __PSS_LMEM4_CORR_ERR 0x00040000 +#define __PSS_LMEM3_CORR_ERR 0x00020000 +#define __PSS_LMEM2_CORR_ERR 0x00010000 +#define __PSS_LMEM1_CORR_ERR 0x00008000 +#define __PSS_LMEM0_CORR_ERR 0x00004000 +#define __PSS_LMEM5_UNCORR_ERR 0x00002000 +#define __PSS_LMEM4_UNCORR_ERR 0x00001000 +#define __PSS_LMEM3_UNCORR_ERR 0x00000800 +#define __PSS_LMEM2_UNCORR_ERR 0x00000400 +#define __PSS_LMEM1_UNCORR_ERR 0x00000200 +#define __PSS_LMEM0_UNCORR_ERR 0x00000100 +#define __PSS_BAL_PERR 0x00000080 +#define __PSS_DIP_IF_ERR 0x00000040 +#define __PSS_IOH_IF_ERR 0x00000020 +#define __PSS_TDS_IF_ERR 0x00000010 +#define __PSS_RDS_IF_ERR 0x00000008 +#define __PSS_SGM_IF_ERR 0x00000004 +#define __PSS_LPU1_RAM_ERR 0x00000002 +#define __PSS_LPU0_RAM_ERR 0x00000001 +#define ERR_SET_REG 0x00018818 +#define __PSS_ERR_STATUS_SET 0x003fffff +#define PMM_1T_RESET_REG_P0 0x0002381c +#define __PMM_1T_RESET_P 0x00000001 +#define PMM_1T_RESET_REG_P1 0x00023c1c +#define HQM_QSET0_RXQ_DRBL_P0 0x00038000 +#define __RXQ0_ADD_VECTORS_P 0x80000000 +#define __RXQ0_STOP_P 0x40000000 +#define __RXQ0_PRD_PTR_P 0x0000ffff +#define HQM_QSET1_RXQ_DRBL_P0 0x00038080 +#define __RXQ1_ADD_VECTORS_P 0x80000000 +#define __RXQ1_STOP_P 0x40000000 +#define __RXQ1_PRD_PTR_P 0x0000ffff +#define HQM_QSET0_RXQ_DRBL_P1 0x0003c000 +#define HQM_QSET1_RXQ_DRBL_P1 0x0003c080 +#define HQM_QSET0_TXQ_DRBL_P0 0x00038020 +#define __TXQ0_ADD_VECTORS_P 0x80000000 +#define __TXQ0_STOP_P 0x40000000 +#define __TXQ0_PRD_PTR_P 0x0000ffff +#define HQM_QSET1_TXQ_DRBL_P0 0x000380a0 +#define __TXQ1_ADD_VECTORS_P 0x80000000 +#define __TXQ1_STOP_P 0x40000000 +#define __TXQ1_PRD_PTR_P 0x0000ffff +#define HQM_QSET0_TXQ_DRBL_P1 0x0003c020 +#define HQM_QSET1_TXQ_DRBL_P1 0x0003c0a0 +#define HQM_QSET0_IB_DRBL_1_P0 0x00038040 +#define __IB1_0_ACK_P 0x80000000 +#define __IB1_0_DISABLE_P 0x40000000 +#define __IB1_0_COALESCING_CFG_P_MK 0x00ff0000 +#define __IB1_0_COALESCING_CFG_P_SH 16 +#define __IB1_0_COALESCING_CFG_P(_v) ((_v) << __IB1_0_COALESCING_CFG_P_SH) +#define __IB1_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff +#define HQM_QSET1_IB_DRBL_1_P0 0x000380c0 +#define __IB1_1_ACK_P 0x80000000 +#define __IB1_1_DISABLE_P 0x40000000 +#define __IB1_1_COALESCING_CFG_P_MK 0x00ff0000 +#define __IB1_1_COALESCING_CFG_P_SH 16 +#define __IB1_1_COALESCING_CFG_P(_v) ((_v) << __IB1_1_COALESCING_CFG_P_SH) +#define __IB1_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff +#define HQM_QSET0_IB_DRBL_1_P1 0x0003c040 +#define HQM_QSET1_IB_DRBL_1_P1 0x0003c0c0 +#define HQM_QSET0_IB_DRBL_2_P0 0x00038060 +#define __IB2_0_ACK_P 0x80000000 +#define __IB2_0_DISABLE_P 0x40000000 +#define __IB2_0_COALESCING_CFG_P_MK 0x00ff0000 +#define __IB2_0_COALESCING_CFG_P_SH 16 +#define __IB2_0_COALESCING_CFG_P(_v) ((_v) << __IB2_0_COALESCING_CFG_P_SH) +#define __IB2_0_NUM_OF_ACKED_EVENTS_P 0x0000ffff +#define HQM_QSET1_IB_DRBL_2_P0 0x000380e0 +#define __IB2_1_ACK_P 0x80000000 +#define __IB2_1_DISABLE_P 0x40000000 +#define __IB2_1_COALESCING_CFG_P_MK 0x00ff0000 +#define __IB2_1_COALESCING_CFG_P_SH 16 +#define __IB2_1_COALESCING_CFG_P(_v) ((_v) << __IB2_1_COALESCING_CFG_P_SH) +#define __IB2_1_NUM_OF_ACKED_EVENTS_P 0x0000ffff +#define HQM_QSET0_IB_DRBL_2_P1 0x0003c060 +#define HQM_QSET1_IB_DRBL_2_P1 0x0003c0e0 + +/* + * These definitions are either in error/missing in spec. Its auto-generated + * from hard coded values in regparse.pl. + */ +#define __EMPHPOST_AT_4G_MK_FIX 0x0000001c +#define __EMPHPOST_AT_4G_SH_FIX 0x00000002 +#define __EMPHPRE_AT_4G_FIX 0x00000003 +#define __SFP_TXRATE_EN_FIX 0x00000100 +#define __SFP_RXRATE_EN_FIX 0x00000080 + +/* + * These register definitions are auto-generated from hard coded values + * in regparse.pl. + */ + +/* + * These register mapping definitions are auto-generated from mapping tables + * in regparse.pl. + */ +#define BFA_IOC0_HBEAT_REG HOST_SEM0_INFO_REG +#define BFA_IOC0_STATE_REG HOST_SEM1_INFO_REG +#define BFA_IOC1_HBEAT_REG HOST_SEM2_INFO_REG +#define BFA_IOC1_STATE_REG HOST_SEM3_INFO_REG +#define BFA_FW_USE_COUNT HOST_SEM4_INFO_REG + +#define CPE_DEPTH_Q(__n) \ + (CPE_DEPTH_Q0 + (__n) * (CPE_DEPTH_Q1 - CPE_DEPTH_Q0)) +#define CPE_QCTRL_Q(__n) \ + (CPE_QCTRL_Q0 + (__n) * (CPE_QCTRL_Q1 - CPE_QCTRL_Q0)) +#define CPE_PI_PTR_Q(__n) \ + (CPE_PI_PTR_Q0 + (__n) * (CPE_PI_PTR_Q1 - CPE_PI_PTR_Q0)) +#define CPE_CI_PTR_Q(__n) \ + (CPE_CI_PTR_Q0 + (__n) * (CPE_CI_PTR_Q1 - CPE_CI_PTR_Q0)) +#define RME_DEPTH_Q(__n) \ + (RME_DEPTH_Q0 + (__n) * (RME_DEPTH_Q1 - RME_DEPTH_Q0)) +#define RME_QCTRL_Q(__n) \ + (RME_QCTRL_Q0 + (__n) * (RME_QCTRL_Q1 - RME_QCTRL_Q0)) +#define RME_PI_PTR_Q(__n) \ + (RME_PI_PTR_Q0 + (__n) * (RME_PI_PTR_Q1 - RME_PI_PTR_Q0)) +#define RME_CI_PTR_Q(__n) \ + (RME_CI_PTR_Q0 + (__n) * (RME_CI_PTR_Q1 - RME_CI_PTR_Q0)) +#define HQM_QSET_RXQ_DRBL_P0(__n) (HQM_QSET0_RXQ_DRBL_P0 + (__n) \ + * (HQM_QSET1_RXQ_DRBL_P0 - HQM_QSET0_RXQ_DRBL_P0)) +#define HQM_QSET_TXQ_DRBL_P0(__n) (HQM_QSET0_TXQ_DRBL_P0 + (__n) \ + * (HQM_QSET1_TXQ_DRBL_P0 - HQM_QSET0_TXQ_DRBL_P0)) +#define HQM_QSET_IB_DRBL_1_P0(__n) (HQM_QSET0_IB_DRBL_1_P0 + (__n) \ + * (HQM_QSET1_IB_DRBL_1_P0 - HQM_QSET0_IB_DRBL_1_P0)) +#define HQM_QSET_IB_DRBL_2_P0(__n) (HQM_QSET0_IB_DRBL_2_P0 + (__n) \ + * (HQM_QSET1_IB_DRBL_2_P0 - HQM_QSET0_IB_DRBL_2_P0)) +#define HQM_QSET_RXQ_DRBL_P1(__n) (HQM_QSET0_RXQ_DRBL_P1 + (__n) \ + * (HQM_QSET1_RXQ_DRBL_P1 - HQM_QSET0_RXQ_DRBL_P1)) +#define HQM_QSET_TXQ_DRBL_P1(__n) (HQM_QSET0_TXQ_DRBL_P1 + (__n) \ + * (HQM_QSET1_TXQ_DRBL_P1 - HQM_QSET0_TXQ_DRBL_P1)) +#define HQM_QSET_IB_DRBL_1_P1(__n) (HQM_QSET0_IB_DRBL_1_P1 + (__n) \ + * (HQM_QSET1_IB_DRBL_1_P1 - HQM_QSET0_IB_DRBL_1_P1)) +#define HQM_QSET_IB_DRBL_2_P1(__n) (HQM_QSET0_IB_DRBL_2_P1 + (__n) \ + * (HQM_QSET1_IB_DRBL_2_P1 - HQM_QSET0_IB_DRBL_2_P1)) + +#define CPE_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) +#define RME_Q_NUM(__fn, __q) (((__fn) << 2) + (__q)) +#define CPE_Q_MASK(__q) ((__q) & 0x3) +#define RME_Q_MASK(__q) ((__q) & 0x3) + +/* + * PCI MSI-X vector defines + */ +enum { + BFA_MSIX_CPE_Q0 = 0, + BFA_MSIX_CPE_Q1 = 1, + BFA_MSIX_CPE_Q2 = 2, + BFA_MSIX_CPE_Q3 = 3, + BFA_MSIX_RME_Q0 = 4, + BFA_MSIX_RME_Q1 = 5, + BFA_MSIX_RME_Q2 = 6, + BFA_MSIX_RME_Q3 = 7, + BFA_MSIX_LPU_ERR = 8, + BFA_MSIX_CT_MAX = 9, +}; + +/* + * And corresponding host interrupt status bit field defines + */ +#define __HFN_INT_CPE_Q0 0x00000001U +#define __HFN_INT_CPE_Q1 0x00000002U +#define __HFN_INT_CPE_Q2 0x00000004U +#define __HFN_INT_CPE_Q3 0x00000008U +#define __HFN_INT_CPE_Q4 0x00000010U +#define __HFN_INT_CPE_Q5 0x00000020U +#define __HFN_INT_CPE_Q6 0x00000040U +#define __HFN_INT_CPE_Q7 0x00000080U +#define __HFN_INT_RME_Q0 0x00000100U +#define __HFN_INT_RME_Q1 0x00000200U +#define __HFN_INT_RME_Q2 0x00000400U +#define __HFN_INT_RME_Q3 0x00000800U +#define __HFN_INT_RME_Q4 0x00001000U +#define __HFN_INT_RME_Q5 0x00002000U +#define __HFN_INT_RME_Q6 0x00004000U +#define __HFN_INT_RME_Q7 0x00008000U +#define __HFN_INT_ERR_EMC 0x00010000U +#define __HFN_INT_ERR_LPU0 0x00020000U +#define __HFN_INT_ERR_LPU1 0x00040000U +#define __HFN_INT_ERR_PSS 0x00080000U +#define __HFN_INT_MBOX_LPU0 0x00100000U +#define __HFN_INT_MBOX_LPU1 0x00200000U +#define __HFN_INT_MBOX1_LPU0 0x00400000U +#define __HFN_INT_MBOX1_LPU1 0x00800000U +#define __HFN_INT_LL_HALT 0x01000000U +#define __HFN_INT_CPE_MASK 0x000000ffU +#define __HFN_INT_RME_MASK 0x0000ff00U + +/* + * catapult memory map. + */ +#define LL_PGN_HQM0 0x0096 +#define LL_PGN_HQM1 0x0097 +#define PSS_SMEM_PAGE_START 0x8000 +#define PSS_SMEM_PGNUM(_pg0, _ma) ((_pg0) + ((_ma) >> 15)) +#define PSS_SMEM_PGOFF(_ma) ((_ma) & 0x7fff) + +/* + * End of catapult memory map + */ + +#endif /* __BFI_CTREG_H__ */ diff --git a/drivers/net/bna/bfi_ll.h b/drivers/net/bna/bfi_ll.h new file mode 100644 index 0000000000000000000000000000000000000000..bee4d054066a91a4afc60cc04205176eaf7cf237 --- /dev/null +++ b/drivers/net/bna/bfi_ll.h @@ -0,0 +1,438 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BFI_LL_H__ +#define __BFI_LL_H__ + +#include "bfi.h" + +#pragma pack(1) + +/** + * @brief + * "enums" for all LL mailbox messages other than IOC + */ +enum { + BFI_LL_H2I_MAC_UCAST_SET_REQ = 1, + BFI_LL_H2I_MAC_UCAST_ADD_REQ = 2, + BFI_LL_H2I_MAC_UCAST_DEL_REQ = 3, + + BFI_LL_H2I_MAC_MCAST_ADD_REQ = 4, + BFI_LL_H2I_MAC_MCAST_DEL_REQ = 5, + BFI_LL_H2I_MAC_MCAST_FILTER_REQ = 6, + BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ = 7, + + BFI_LL_H2I_PORT_ADMIN_REQ = 8, + BFI_LL_H2I_STATS_GET_REQ = 9, + BFI_LL_H2I_STATS_CLEAR_REQ = 10, + + BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ = 11, + BFI_LL_H2I_RXF_DEFAULT_SET_REQ = 12, + + BFI_LL_H2I_TXQ_STOP_REQ = 13, + BFI_LL_H2I_RXQ_STOP_REQ = 14, + + BFI_LL_H2I_DIAG_LOOPBACK_REQ = 15, + + BFI_LL_H2I_SET_PAUSE_REQ = 16, + BFI_LL_H2I_MTU_INFO_REQ = 17, + + BFI_LL_H2I_RX_REQ = 18, +} ; + +enum { + BFI_LL_I2H_MAC_UCAST_SET_RSP = BFA_I2HM(1), + BFI_LL_I2H_MAC_UCAST_ADD_RSP = BFA_I2HM(2), + BFI_LL_I2H_MAC_UCAST_DEL_RSP = BFA_I2HM(3), + + BFI_LL_I2H_MAC_MCAST_ADD_RSP = BFA_I2HM(4), + BFI_LL_I2H_MAC_MCAST_DEL_RSP = BFA_I2HM(5), + BFI_LL_I2H_MAC_MCAST_FILTER_RSP = BFA_I2HM(6), + BFI_LL_I2H_MAC_MCAST_DEL_ALL_RSP = BFA_I2HM(7), + + BFI_LL_I2H_PORT_ADMIN_RSP = BFA_I2HM(8), + BFI_LL_I2H_STATS_GET_RSP = BFA_I2HM(9), + BFI_LL_I2H_STATS_CLEAR_RSP = BFA_I2HM(10), + + BFI_LL_I2H_RXF_PROMISCUOUS_SET_RSP = BFA_I2HM(11), + BFI_LL_I2H_RXF_DEFAULT_SET_RSP = BFA_I2HM(12), + + BFI_LL_I2H_TXQ_STOP_RSP = BFA_I2HM(13), + BFI_LL_I2H_RXQ_STOP_RSP = BFA_I2HM(14), + + BFI_LL_I2H_DIAG_LOOPBACK_RSP = BFA_I2HM(15), + + BFI_LL_I2H_SET_PAUSE_RSP = BFA_I2HM(16), + + BFI_LL_I2H_MTU_INFO_RSP = BFA_I2HM(17), + BFI_LL_I2H_RX_RSP = BFA_I2HM(18), + + BFI_LL_I2H_LINK_DOWN_AEN = BFA_I2HM(19), + BFI_LL_I2H_LINK_UP_AEN = BFA_I2HM(20), + + BFI_LL_I2H_PORT_ENABLE_AEN = BFA_I2HM(21), + BFI_LL_I2H_PORT_DISABLE_AEN = BFA_I2HM(22), +} ; + +/** + * @brief bfi_ll_mac_addr_req is used by: + * BFI_LL_H2I_MAC_UCAST_SET_REQ + * BFI_LL_H2I_MAC_UCAST_ADD_REQ + * BFI_LL_H2I_MAC_UCAST_DEL_REQ + * BFI_LL_H2I_MAC_MCAST_ADD_REQ + * BFI_LL_H2I_MAC_MCAST_DEL_REQ + */ +struct bfi_ll_mac_addr_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 rxf_id; + u8 rsvd1[3]; + mac_t mac_addr; + u8 rsvd2[2]; +}; + +/** + * @brief bfi_ll_mcast_filter_req is used by: + * BFI_LL_H2I_MAC_MCAST_FILTER_REQ + */ +struct bfi_ll_mcast_filter_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 rxf_id; + u8 enable; + u8 rsvd[2]; +}; + +/** + * @brief bfi_ll_mcast_del_all is used by: + * BFI_LL_H2I_MAC_MCAST_DEL_ALL_REQ + */ +struct bfi_ll_mcast_del_all_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 rxf_id; + u8 rsvd[3]; +}; + +/** + * @brief bfi_ll_q_stop_req is used by: + * BFI_LL_H2I_TXQ_STOP_REQ + * BFI_LL_H2I_RXQ_STOP_REQ + */ +struct bfi_ll_q_stop_req { + struct bfi_mhdr mh; /*!< common msg header */ + u32 q_id_mask[2]; /* !< bit-mask for queue ids */ +}; + +/** + * @brief bfi_ll_stats_req is used by: + * BFI_LL_I2H_STATS_GET_REQ + * BFI_LL_I2H_STATS_CLEAR_REQ + */ +struct bfi_ll_stats_req { + struct bfi_mhdr mh; /*!< common msg header */ + u16 stats_mask; /* !< bit-mask for non-function statistics */ + u8 rsvd[2]; + u32 rxf_id_mask[2]; /* !< bit-mask for RxF Statistics */ + u32 txf_id_mask[2]; /* !< bit-mask for TxF Statistics */ + union bfi_addr_u host_buffer; /* !< where statistics are returned */ +}; + +/** + * @brief defines for "stats_mask" above. + */ +#define BFI_LL_STATS_MAC (1 << 0) /* !< MAC Statistics */ +#define BFI_LL_STATS_BPC (1 << 1) /* !< Pause Stats from BPC */ +#define BFI_LL_STATS_RAD (1 << 2) /* !< Rx Admission Statistics */ +#define BFI_LL_STATS_RX_FC (1 << 3) /* !< Rx FC Stats from RxA */ +#define BFI_LL_STATS_TX_FC (1 << 4) /* !< Tx FC Stats from TxA */ + +#define BFI_LL_STATS_ALL 0x1f + +/** + * @brief bfi_ll_port_admin_req + */ +struct bfi_ll_port_admin_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 up; + u8 rsvd[3]; +}; + +/** + * @brief bfi_ll_rxf_req is used by: + * BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ + * BFI_LL_H2I_RXF_DEFAULT_SET_REQ + */ +struct bfi_ll_rxf_req { + struct bfi_mhdr mh; /*!< common msg header */ + u8 rxf_id; + u8 enable; + u8 rsvd[2]; +}; + +/** + * @brief bfi_ll_rxf_multi_req is used by: + * BFI_LL_H2I_RX_REQ + */ +struct bfi_ll_rxf_multi_req { + struct bfi_mhdr mh; /*!< common msg header */ + u32 rxf_id_mask[2]; + u8 enable; + u8 rsvd[3]; +}; + +/** + * @brief enum for Loopback opmodes + */ +enum { + BFI_LL_DIAG_LB_OPMODE_EXT = 0, + BFI_LL_DIAG_LB_OPMODE_CBL = 1, +}; + +/** + * @brief bfi_ll_set_pause_req is used by: + * BFI_LL_H2I_SET_PAUSE_REQ + */ +struct bfi_ll_set_pause_req { + struct bfi_mhdr mh; + u8 tx_pause; /* 1 = enable, 0 = disable */ + u8 rx_pause; /* 1 = enable, 0 = disable */ + u8 rsvd[2]; +}; + +/** + * @brief bfi_ll_mtu_info_req is used by: + * BFI_LL_H2I_MTU_INFO_REQ + */ +struct bfi_ll_mtu_info_req { + struct bfi_mhdr mh; + u16 mtu; + u8 rsvd[2]; +}; + +/** + * @brief + * Response header format used by all responses + * For both responses and asynchronous notifications + */ +struct bfi_ll_rsp { + struct bfi_mhdr mh; /*!< common msg header */ + u8 error; + u8 rsvd[3]; +}; + +/** + * @brief bfi_ll_cee_aen is used by: + * BFI_LL_I2H_LINK_DOWN_AEN + * BFI_LL_I2H_LINK_UP_AEN + */ +struct bfi_ll_aen { + struct bfi_mhdr mh; /*!< common msg header */ + u32 reason; + u8 cee_linkup; + u8 prio_map; /*!< LL priority bit-map */ + u8 rsvd[2]; +}; + +/** + * @brief + * The following error codes can be returned + * by the mbox commands + */ +enum { + BFI_LL_CMD_OK = 0, + BFI_LL_CMD_FAIL = 1, + BFI_LL_CMD_DUP_ENTRY = 2, /* !< Duplicate entry in CAM */ + BFI_LL_CMD_CAM_FULL = 3, /* !< CAM is full */ + BFI_LL_CMD_NOT_OWNER = 4, /* !< Not permitted, b'cos not owner */ + BFI_LL_CMD_NOT_EXEC = 5, /* !< Was not sent to f/w at all */ + BFI_LL_CMD_WAITING = 6, /* !< Waiting for completion (VMware) */ + BFI_LL_CMD_PORT_DISABLED = 7, /* !< port in disabled state */ +} ; + +/* Statistics */ +#define BFI_LL_TXF_ID_MAX 64 +#define BFI_LL_RXF_ID_MAX 64 + +/* TxF Frame Statistics */ +struct bfi_ll_stats_txf { + u64 ucast_octets; + u64 ucast; + u64 ucast_vlan; + + u64 mcast_octets; + u64 mcast; + u64 mcast_vlan; + + u64 bcast_octets; + u64 bcast; + u64 bcast_vlan; + + u64 errors; + u64 filter_vlan; /* frames filtered due to VLAN */ + u64 filter_mac_sa; /* frames filtered due to SA check */ +}; + +/* RxF Frame Statistics */ +struct bfi_ll_stats_rxf { + u64 ucast_octets; + u64 ucast; + u64 ucast_vlan; + + u64 mcast_octets; + u64 mcast; + u64 mcast_vlan; + + u64 bcast_octets; + u64 bcast; + u64 bcast_vlan; + u64 frame_drops; +}; + +/* FC Tx Frame Statistics */ +struct bfi_ll_stats_fc_tx { + u64 txf_ucast_octets; + u64 txf_ucast; + u64 txf_ucast_vlan; + + u64 txf_mcast_octets; + u64 txf_mcast; + u64 txf_mcast_vlan; + + u64 txf_bcast_octets; + u64 txf_bcast; + u64 txf_bcast_vlan; + + u64 txf_parity_errors; + u64 txf_timeout; + u64 txf_fid_parity_errors; +}; + +/* FC Rx Frame Statistics */ +struct bfi_ll_stats_fc_rx { + u64 rxf_ucast_octets; + u64 rxf_ucast; + u64 rxf_ucast_vlan; + + u64 rxf_mcast_octets; + u64 rxf_mcast; + u64 rxf_mcast_vlan; + + u64 rxf_bcast_octets; + u64 rxf_bcast; + u64 rxf_bcast_vlan; +}; + +/* RAD Frame Statistics */ +struct bfi_ll_stats_rad { + u64 rx_frames; + u64 rx_octets; + u64 rx_vlan_frames; + + u64 rx_ucast; + u64 rx_ucast_octets; + u64 rx_ucast_vlan; + + u64 rx_mcast; + u64 rx_mcast_octets; + u64 rx_mcast_vlan; + + u64 rx_bcast; + u64 rx_bcast_octets; + u64 rx_bcast_vlan; + + u64 rx_drops; +}; + +/* BPC Tx Registers */ +struct bfi_ll_stats_bpc { + /* transmit stats */ + u64 tx_pause[8]; + u64 tx_zero_pause[8]; /*!< Pause cancellation */ + /*!timer_mod)) + +/* MBOX API for PORT, TX, RX */ +#define bna_mbox_qe_fill(_qe, _cmd, _cmd_len, _cbfn, _cbarg) \ +do { \ + memcpy(&((_qe)->cmd.msg[0]), (_cmd), (_cmd_len)); \ + (_qe)->cbfn = (_cbfn); \ + (_qe)->cbarg = (_cbarg); \ +} while (0) + +#define bna_is_small_rxq(rcb) ((rcb)->id == 1) + +#define BNA_MAC_IS_EQUAL(_mac1, _mac2) \ + (!memcmp((_mac1), (_mac2), sizeof(mac_t))) + +#define BNA_POWER_OF_2(x) (((x) & ((x) - 1)) == 0) + +#define BNA_TO_POWER_OF_2(x) \ +do { \ + int _shift = 0; \ + while ((x) && (x) != 1) { \ + (x) >>= 1; \ + _shift++; \ + } \ + (x) <<= _shift; \ +} while (0) + +#define BNA_TO_POWER_OF_2_HIGH(x) \ +do { \ + int n = 1; \ + while (n < (x)) \ + n <<= 1; \ + (x) = n; \ +} while (0) + +/* + * input : _addr-> os dma addr in host endian format, + * output : _bna_dma_addr-> pointer to hw dma addr + */ +#define BNA_SET_DMA_ADDR(_addr, _bna_dma_addr) \ +do { \ + u64 tmp_addr = \ + cpu_to_be64((u64)(_addr)); \ + (_bna_dma_addr)->msb = ((struct bna_dma_addr *)&tmp_addr)->msb; \ + (_bna_dma_addr)->lsb = ((struct bna_dma_addr *)&tmp_addr)->lsb; \ +} while (0) + +/* + * input : _bna_dma_addr-> pointer to hw dma addr + * output : _addr-> os dma addr in host endian format + */ +#define BNA_GET_DMA_ADDR(_bna_dma_addr, _addr) \ +do { \ + (_addr) = ((((u64)ntohl((_bna_dma_addr)->msb))) << 32) \ + | ((ntohl((_bna_dma_addr)->lsb) & 0xffffffff)); \ +} while (0) + +#define containing_rec(addr, type, field) \ + ((type *)((unsigned char *)(addr) - \ + (unsigned char *)(&((type *)0)->field))) + +#define BNA_TXQ_WI_NEEDED(_vectors) (((_vectors) + 3) >> 2) + +/* TxQ element is 64 bytes */ +#define BNA_TXQ_PAGE_INDEX_MAX (PAGE_SIZE >> 6) +#define BNA_TXQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 6) + +#define BNA_TXQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \ +{ \ + unsigned int page_index; /* index within a page */ \ + void *page_addr; \ + page_index = (_qe_idx) & (BNA_TXQ_PAGE_INDEX_MAX - 1); \ + (_qe_ptr_range) = (BNA_TXQ_PAGE_INDEX_MAX - page_index); \ + page_addr = (_qpt_ptr)[((_qe_idx) >> BNA_TXQ_PAGE_INDEX_MAX_SHIFT)];\ + (_qe_ptr) = &((struct bna_txq_entry *)(page_addr))[page_index]; \ +} + +/* RxQ element is 8 bytes */ +#define BNA_RXQ_PAGE_INDEX_MAX (PAGE_SIZE >> 3) +#define BNA_RXQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 3) + +#define BNA_RXQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \ +{ \ + unsigned int page_index; /* index within a page */ \ + void *page_addr; \ + page_index = (_qe_idx) & (BNA_RXQ_PAGE_INDEX_MAX - 1); \ + (_qe_ptr_range) = (BNA_RXQ_PAGE_INDEX_MAX - page_index); \ + page_addr = (_qpt_ptr)[((_qe_idx) >> \ + BNA_RXQ_PAGE_INDEX_MAX_SHIFT)]; \ + (_qe_ptr) = &((struct bna_rxq_entry *)(page_addr))[page_index]; \ +} + +/* CQ element is 16 bytes */ +#define BNA_CQ_PAGE_INDEX_MAX (PAGE_SIZE >> 4) +#define BNA_CQ_PAGE_INDEX_MAX_SHIFT (PAGE_SHIFT - 4) + +#define BNA_CQ_QPGE_PTR_GET(_qe_idx, _qpt_ptr, _qe_ptr, _qe_ptr_range) \ +{ \ + unsigned int page_index; /* index within a page */ \ + void *page_addr; \ + \ + page_index = (_qe_idx) & (BNA_CQ_PAGE_INDEX_MAX - 1); \ + (_qe_ptr_range) = (BNA_CQ_PAGE_INDEX_MAX - page_index); \ + page_addr = (_qpt_ptr)[((_qe_idx) >> \ + BNA_CQ_PAGE_INDEX_MAX_SHIFT)]; \ + (_qe_ptr) = &((struct bna_cq_entry *)(page_addr))[page_index];\ +} + +#define BNA_QE_INDX_2_PTR(_cast, _qe_idx, _q_base) \ + (&((_cast *)(_q_base))[(_qe_idx)]) + +#define BNA_QE_INDX_RANGE(_qe_idx, _q_depth) ((_q_depth) - (_qe_idx)) + +#define BNA_QE_INDX_ADD(_qe_idx, _qe_num, _q_depth) \ + ((_qe_idx) = ((_qe_idx) + (_qe_num)) & ((_q_depth) - 1)) + +#define BNA_Q_INDEX_CHANGE(_old_idx, _updated_idx, _q_depth) \ + (((_updated_idx) - (_old_idx)) & ((_q_depth) - 1)) + +#define BNA_QE_FREE_CNT(_q_ptr, _q_depth) \ + (((_q_ptr)->consumer_index - (_q_ptr)->producer_index - 1) & \ + ((_q_depth) - 1)) + +#define BNA_QE_IN_USE_CNT(_q_ptr, _q_depth) \ + ((((_q_ptr)->producer_index - (_q_ptr)->consumer_index)) & \ + (_q_depth - 1)) + +#define BNA_Q_GET_CI(_q_ptr) ((_q_ptr)->q.consumer_index) + +#define BNA_Q_GET_PI(_q_ptr) ((_q_ptr)->q.producer_index) + +#define BNA_Q_PI_ADD(_q_ptr, _num) \ + (_q_ptr)->q.producer_index = \ + (((_q_ptr)->q.producer_index + (_num)) & \ + ((_q_ptr)->q.q_depth - 1)) + +#define BNA_Q_CI_ADD(_q_ptr, _num) \ + (_q_ptr)->q.consumer_index = \ + (((_q_ptr)->q.consumer_index + (_num)) \ + & ((_q_ptr)->q.q_depth - 1)) + +#define BNA_Q_FREE_COUNT(_q_ptr) \ + (BNA_QE_FREE_CNT(&((_q_ptr)->q), (_q_ptr)->q.q_depth)) + +#define BNA_Q_IN_USE_COUNT(_q_ptr) \ + (BNA_QE_IN_USE_CNT(&(_q_ptr)->q, (_q_ptr)->q.q_depth)) + +/* These macros build the data portion of the TxQ/RxQ doorbell */ +#define BNA_DOORBELL_Q_PRD_IDX(_pi) (0x80000000 | (_pi)) +#define BNA_DOORBELL_Q_STOP (0x40000000) + +/* These macros build the data portion of the IB doorbell */ +#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \ + (0x80000000 | ((_timeout) << 16) | (_events)) +#define BNA_DOORBELL_IB_INT_DISABLE (0x40000000) + +/* Set the coalescing timer for the given ib */ +#define bna_ib_coalescing_timer_set(_i_dbell, _cls_timer) \ + ((_i_dbell)->doorbell_ack = BNA_DOORBELL_IB_INT_ACK((_cls_timer), 0)); + +/* Acks 'events' # of events for a given ib */ +#define bna_ib_ack(_i_dbell, _events) \ + (writel(((_i_dbell)->doorbell_ack | (_events)), \ + (_i_dbell)->doorbell_addr)); + +#define bna_txq_prod_indx_doorbell(_tcb) \ + (writel(BNA_DOORBELL_Q_PRD_IDX((_tcb)->producer_index), \ + (_tcb)->q_dbell)); + +#define bna_rxq_prod_indx_doorbell(_rcb) \ + (writel(BNA_DOORBELL_Q_PRD_IDX((_rcb)->producer_index), \ + (_rcb)->q_dbell)); + +#define BNA_LARGE_PKT_SIZE 1000 + +#define BNA_UPDATE_PKT_CNT(_pkt, _len) \ +do { \ + if ((_len) > BNA_LARGE_PKT_SIZE) { \ + (_pkt)->large_pkt_cnt++; \ + } else { \ + (_pkt)->small_pkt_cnt++; \ + } \ +} while (0) + +#define call_rxf_stop_cbfn(rxf, status) \ + if ((rxf)->stop_cbfn) { \ + (*(rxf)->stop_cbfn)((rxf)->stop_cbarg, (status)); \ + (rxf)->stop_cbfn = NULL; \ + (rxf)->stop_cbarg = NULL; \ + } + +#define call_rxf_start_cbfn(rxf, status) \ + if ((rxf)->start_cbfn) { \ + (*(rxf)->start_cbfn)((rxf)->start_cbarg, (status)); \ + (rxf)->start_cbfn = NULL; \ + (rxf)->start_cbarg = NULL; \ + } + +#define call_rxf_cam_fltr_cbfn(rxf, status) \ + if ((rxf)->cam_fltr_cbfn) { \ + (*(rxf)->cam_fltr_cbfn)((rxf)->cam_fltr_cbarg, rxf->rx, \ + (status)); \ + (rxf)->cam_fltr_cbfn = NULL; \ + (rxf)->cam_fltr_cbarg = NULL; \ + } + +#define call_rxf_pause_cbfn(rxf, status) \ + if ((rxf)->oper_state_cbfn) { \ + (*(rxf)->oper_state_cbfn)((rxf)->oper_state_cbarg, rxf->rx,\ + (status)); \ + (rxf)->rxf_flags &= ~BNA_RXF_FL_OPERSTATE_CHANGED; \ + (rxf)->oper_state_cbfn = NULL; \ + (rxf)->oper_state_cbarg = NULL; \ + } + +#define call_rxf_resume_cbfn(rxf, status) call_rxf_pause_cbfn(rxf, status) + +#define is_xxx_enable(mode, bitmask, xxx) ((bitmask & xxx) && (mode & xxx)) + +#define is_xxx_disable(mode, bitmask, xxx) ((bitmask & xxx) && !(mode & xxx)) + +#define xxx_enable(mode, bitmask, xxx) \ +do { \ + bitmask |= xxx; \ + mode |= xxx; \ +} while (0) + +#define xxx_disable(mode, bitmask, xxx) \ +do { \ + bitmask |= xxx; \ + mode &= ~xxx; \ +} while (0) + +#define xxx_inactive(mode, bitmask, xxx) \ +do { \ + bitmask &= ~xxx; \ + mode &= ~xxx; \ +} while (0) + +#define is_promisc_enable(mode, bitmask) \ + is_xxx_enable(mode, bitmask, BNA_RXMODE_PROMISC) + +#define is_promisc_disable(mode, bitmask) \ + is_xxx_disable(mode, bitmask, BNA_RXMODE_PROMISC) + +#define promisc_enable(mode, bitmask) \ + xxx_enable(mode, bitmask, BNA_RXMODE_PROMISC) + +#define promisc_disable(mode, bitmask) \ + xxx_disable(mode, bitmask, BNA_RXMODE_PROMISC) + +#define promisc_inactive(mode, bitmask) \ + xxx_inactive(mode, bitmask, BNA_RXMODE_PROMISC) + +#define is_default_enable(mode, bitmask) \ + is_xxx_enable(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define is_default_disable(mode, bitmask) \ + is_xxx_disable(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define default_enable(mode, bitmask) \ + xxx_enable(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define default_disable(mode, bitmask) \ + xxx_disable(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define default_inactive(mode, bitmask) \ + xxx_inactive(mode, bitmask, BNA_RXMODE_DEFAULT) + +#define is_allmulti_enable(mode, bitmask) \ + is_xxx_enable(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define is_allmulti_disable(mode, bitmask) \ + is_xxx_disable(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define allmulti_enable(mode, bitmask) \ + xxx_enable(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define allmulti_disable(mode, bitmask) \ + xxx_disable(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define allmulti_inactive(mode, bitmask) \ + xxx_inactive(mode, bitmask, BNA_RXMODE_ALLMULTI) + +#define GET_RXQS(rxp, q0, q1) do { \ + switch ((rxp)->type) { \ + case BNA_RXP_SINGLE: \ + (q0) = rxp->rxq.single.only; \ + (q1) = NULL; \ + break; \ + case BNA_RXP_SLR: \ + (q0) = rxp->rxq.slr.large; \ + (q1) = rxp->rxq.slr.small; \ + break; \ + case BNA_RXP_HDS: \ + (q0) = rxp->rxq.hds.data; \ + (q1) = rxp->rxq.hds.hdr; \ + break; \ + } \ +} while (0) + +/** + * + * Function prototypes + * + */ + +/** + * BNA + */ + +/* APIs for BNAD */ +void bna_res_req(struct bna_res_info *res_info); +void bna_init(struct bna *bna, struct bnad *bnad, + struct bfa_pcidev *pcidev, + struct bna_res_info *res_info); +void bna_uninit(struct bna *bna); +void bna_stats_get(struct bna *bna); +void bna_get_perm_mac(struct bna *bna, u8 *mac); + +/* APIs for Rx */ +int bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size); + +/* APIs for RxF */ +struct bna_mac *bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod); +void bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod, + struct bna_mac *mac); +struct bna_mac *bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod); +void bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod, + struct bna_mac *mac); +struct bna_rit_segment * +bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size); +void bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod, + struct bna_rit_segment *seg); + +/** + * DEVICE + */ + +/* APIs for BNAD */ +void bna_device_enable(struct bna_device *device); +void bna_device_disable(struct bna_device *device, + enum bna_cleanup_type type); + +/** + * MBOX + */ + +/* APIs for PORT, TX, RX */ +void bna_mbox_handler(struct bna *bna, u32 intr_status); +void bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe); + +/** + * PORT + */ + +/* API for RX */ +int bna_port_mtu_get(struct bna_port *port); +void bna_llport_admin_up(struct bna_llport *llport); +void bna_llport_admin_down(struct bna_llport *llport); + +/* API for BNAD */ +void bna_port_enable(struct bna_port *port); +void bna_port_disable(struct bna_port *port, enum bna_cleanup_type type, + void (*cbfn)(void *, enum bna_cb_status)); +void bna_port_pause_config(struct bna_port *port, + struct bna_pause_config *pause_config, + void (*cbfn)(struct bnad *, enum bna_cb_status)); +void bna_port_mtu_set(struct bna_port *port, int mtu, + void (*cbfn)(struct bnad *, enum bna_cb_status)); +void bna_port_mac_get(struct bna_port *port, mac_t *mac); + +/* Callbacks for TX, RX */ +void bna_port_cb_tx_stopped(struct bna_port *port, + enum bna_cb_status status); +void bna_port_cb_rx_stopped(struct bna_port *port, + enum bna_cb_status status); + +/** + * IB + */ + +/* APIs for BNA */ +void bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna, + struct bna_res_info *res_info); +void bna_ib_mod_uninit(struct bna_ib_mod *ib_mod); + +/** + * TX MODULE AND TX + */ + +/* APIs for BNA */ +void bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna, + struct bna_res_info *res_info); +void bna_tx_mod_uninit(struct bna_tx_mod *tx_mod); +int bna_tx_state_get(struct bna_tx *tx); + +/* APIs for PORT */ +void bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type); +void bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type); +void bna_tx_mod_fail(struct bna_tx_mod *tx_mod); +void bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio); +void bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link); + +/* APIs for BNAD */ +void bna_tx_res_req(int num_txq, int txq_depth, + struct bna_res_info *res_info); +struct bna_tx *bna_tx_create(struct bna *bna, struct bnad *bnad, + struct bna_tx_config *tx_cfg, + struct bna_tx_event_cbfn *tx_cbfn, + struct bna_res_info *res_info, void *priv); +void bna_tx_destroy(struct bna_tx *tx); +void bna_tx_enable(struct bna_tx *tx); +void bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type, + void (*cbfn)(void *, struct bna_tx *, + enum bna_cb_status)); +void bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo); + +/** + * RX MODULE, RX, RXF + */ + +/* Internal APIs */ +void rxf_cb_cam_fltr_mbox_cmd(void *arg, int status); +void rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd, + const struct bna_mac *mac_addr); +void __rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status); +void bna_rxf_adv_init(struct bna_rxf *rxf, + struct bna_rx *rx, + struct bna_rx_config *q_config); +int rxf_process_packet_filter_ucast(struct bna_rxf *rxf); +int rxf_process_packet_filter_promisc(struct bna_rxf *rxf); +int rxf_process_packet_filter_default(struct bna_rxf *rxf); +int rxf_process_packet_filter_allmulti(struct bna_rxf *rxf); +int rxf_clear_packet_filter_ucast(struct bna_rxf *rxf); +int rxf_clear_packet_filter_promisc(struct bna_rxf *rxf); +int rxf_clear_packet_filter_default(struct bna_rxf *rxf); +int rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf); +void rxf_reset_packet_filter_ucast(struct bna_rxf *rxf); +void rxf_reset_packet_filter_promisc(struct bna_rxf *rxf); +void rxf_reset_packet_filter_default(struct bna_rxf *rxf); +void rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf); + +/* APIs for BNA */ +void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna, + struct bna_res_info *res_info); +void bna_rx_mod_uninit(struct bna_rx_mod *rx_mod); +int bna_rx_state_get(struct bna_rx *rx); +int bna_rxf_state_get(struct bna_rxf *rxf); + +/* APIs for PORT */ +void bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type); +void bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type); +void bna_rx_mod_fail(struct bna_rx_mod *rx_mod); + +/* APIs for BNAD */ +void bna_rx_res_req(struct bna_rx_config *rx_config, + struct bna_res_info *res_info); +struct bna_rx *bna_rx_create(struct bna *bna, struct bnad *bnad, + struct bna_rx_config *rx_cfg, + struct bna_rx_event_cbfn *rx_cbfn, + struct bna_res_info *res_info, void *priv); +void bna_rx_destroy(struct bna_rx *rx); +void bna_rx_enable(struct bna_rx *rx); +void bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type, + void (*cbfn)(void *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo); +void bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX]); +void bna_rx_dim_update(struct bna_ccb *ccb); +enum bna_cb_status +bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_mcast_add(struct bna_rx *rx, u8 *mcmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mcmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +enum bna_cb_status +bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode rxmode, + enum bna_rxmode bitmask, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_vlan_add(struct bna_rx *rx, int vlan_id); +void bna_rx_vlan_del(struct bna_rx *rx, int vlan_id); +void bna_rx_vlanfilter_enable(struct bna_rx *rx); +void bna_rx_hds_enable(struct bna_rx *rx, struct bna_rxf_hds *hds_config, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); +void bna_rx_hds_disable(struct bna_rx *rx, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)); + +/** + * BNAD + */ + +/* Callbacks for BNA */ +void bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status, + struct bna_stats *stats); + +/* Callbacks for DEVICE */ +void bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status); +void bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status); +void bnad_cb_device_enable_mbox_intr(struct bnad *bnad); +void bnad_cb_device_disable_mbox_intr(struct bnad *bnad); + +/* Callbacks for port */ +void bnad_cb_port_link_status(struct bnad *bnad, + enum bna_link_status status); + +#endif /* __BNA_H__ */ diff --git a/drivers/net/bna/bna_ctrl.c b/drivers/net/bna/bna_ctrl.c new file mode 100644 index 0000000000000000000000000000000000000000..07b26598546e36c9bc46c0fe100ced62c7fb47c0 --- /dev/null +++ b/drivers/net/bna/bna_ctrl.c @@ -0,0 +1,3261 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#include "bna.h" +#include "bfa_sm.h" +#include "bfa_wc.h" + +static void bna_device_cb_port_stopped(void *arg, enum bna_cb_status status); + +static void +bna_port_cb_link_up(struct bna_port *port, struct bfi_ll_aen *aen, + int status) +{ + int i; + u8 prio_map; + + port->llport.link_status = BNA_LINK_UP; + if (aen->cee_linkup) + port->llport.link_status = BNA_CEE_UP; + + /* Compute the priority */ + prio_map = aen->prio_map; + if (prio_map) { + for (i = 0; i < 8; i++) { + if ((prio_map >> i) & 0x1) + break; + } + port->priority = i; + } else + port->priority = 0; + + /* Dispatch events */ + bna_tx_mod_cee_link_status(&port->bna->tx_mod, aen->cee_linkup); + bna_tx_mod_prio_changed(&port->bna->tx_mod, port->priority); + port->link_cbfn(port->bna->bnad, port->llport.link_status); +} + +static void +bna_port_cb_link_down(struct bna_port *port, int status) +{ + port->llport.link_status = BNA_LINK_DOWN; + + /* Dispatch events */ + bna_tx_mod_cee_link_status(&port->bna->tx_mod, BNA_LINK_DOWN); + port->link_cbfn(port->bna->bnad, BNA_LINK_DOWN); +} + +/** + * MBOX + */ +static int +bna_is_aen(u8 msg_id) +{ + return msg_id == BFI_LL_I2H_LINK_DOWN_AEN || + msg_id == BFI_LL_I2H_LINK_UP_AEN; +} + +static void +bna_mbox_aen_callback(struct bna *bna, struct bfi_mbmsg *msg) +{ + struct bfi_ll_aen *aen = (struct bfi_ll_aen *)(msg); + + switch (aen->mh.msg_id) { + case BFI_LL_I2H_LINK_UP_AEN: + bna_port_cb_link_up(&bna->port, aen, aen->reason); + break; + case BFI_LL_I2H_LINK_DOWN_AEN: + bna_port_cb_link_down(&bna->port, aen->reason); + break; + default: + break; + } +} + +static void +bna_ll_isr(void *llarg, struct bfi_mbmsg *msg) +{ + struct bna *bna = (struct bna *)(llarg); + struct bfi_ll_rsp *mb_rsp = (struct bfi_ll_rsp *)(msg); + struct bfi_mhdr *cmd_h, *rsp_h; + struct bna_mbox_qe *mb_qe = NULL; + int to_post = 0; + u8 aen = 0; + char message[BNA_MESSAGE_SIZE]; + + aen = bna_is_aen(mb_rsp->mh.msg_id); + + if (!aen) { + mb_qe = bfa_q_first(&bna->mbox_mod.posted_q); + cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]); + rsp_h = (struct bfi_mhdr *)(&mb_rsp->mh); + + if ((BFA_I2HM(cmd_h->msg_id) == rsp_h->msg_id) && + (cmd_h->mtag.i2htok == rsp_h->mtag.i2htok)) { + /* Remove the request from posted_q, update state */ + list_del(&mb_qe->qe); + bna->mbox_mod.msg_pending--; + if (list_empty(&bna->mbox_mod.posted_q)) + bna->mbox_mod.state = BNA_MBOX_FREE; + else + to_post = 1; + + /* Dispatch the cbfn */ + if (mb_qe->cbfn) + mb_qe->cbfn(mb_qe->cbarg, mb_rsp->error); + + /* Post the next entry, if needed */ + if (to_post) { + mb_qe = bfa_q_first(&bna->mbox_mod.posted_q); + bfa_nw_ioc_mbox_queue(&bna->device.ioc, + &mb_qe->cmd); + } + } else { + snprintf(message, BNA_MESSAGE_SIZE, + "No matching rsp for [%d:%d:%d]\n", + mb_rsp->mh.msg_class, mb_rsp->mh.msg_id, + mb_rsp->mh.mtag.i2htok); + pr_info("%s", message); + } + + } else + bna_mbox_aen_callback(bna, msg); +} + +static void +bna_err_handler(struct bna *bna, u32 intr_status) +{ + u32 init_halt; + + if (intr_status & __HALT_STATUS_BITS) { + init_halt = readl(bna->device.ioc.ioc_regs.ll_halt); + init_halt &= ~__FW_INIT_HALT_P; + writel(init_halt, bna->device.ioc.ioc_regs.ll_halt); + } + + bfa_nw_ioc_error_isr(&bna->device.ioc); +} + +void +bna_mbox_handler(struct bna *bna, u32 intr_status) +{ + if (BNA_IS_ERR_INTR(intr_status)) { + bna_err_handler(bna, intr_status); + return; + } + if (BNA_IS_MBOX_INTR(intr_status)) + bfa_nw_ioc_mbox_isr(&bna->device.ioc); +} + +void +bna_mbox_send(struct bna *bna, struct bna_mbox_qe *mbox_qe) +{ + struct bfi_mhdr *mh; + + mh = (struct bfi_mhdr *)(&mbox_qe->cmd.msg[0]); + + mh->mtag.i2htok = htons(bna->mbox_mod.msg_ctr); + bna->mbox_mod.msg_ctr++; + bna->mbox_mod.msg_pending++; + if (bna->mbox_mod.state == BNA_MBOX_FREE) { + list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q); + bfa_nw_ioc_mbox_queue(&bna->device.ioc, &mbox_qe->cmd); + bna->mbox_mod.state = BNA_MBOX_POSTED; + } else { + list_add_tail(&mbox_qe->qe, &bna->mbox_mod.posted_q); + } +} + +static void +bna_mbox_flush_q(struct bna *bna, struct list_head *q) +{ + struct bna_mbox_qe *mb_qe = NULL; + struct bfi_mhdr *cmd_h; + struct list_head *mb_q; + void (*cbfn)(void *arg, int status); + void *cbarg; + + mb_q = &bna->mbox_mod.posted_q; + + while (!list_empty(mb_q)) { + bfa_q_deq(mb_q, &mb_qe); + cbfn = mb_qe->cbfn; + cbarg = mb_qe->cbarg; + bfa_q_qe_init(mb_qe); + bna->mbox_mod.msg_pending--; + + cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]); + if (cbfn) + cbfn(cbarg, BNA_CB_NOT_EXEC); + } + + bna->mbox_mod.state = BNA_MBOX_FREE; +} + +static void +bna_mbox_mod_start(struct bna_mbox_mod *mbox_mod) +{ +} + +static void +bna_mbox_mod_stop(struct bna_mbox_mod *mbox_mod) +{ + bna_mbox_flush_q(mbox_mod->bna, &mbox_mod->posted_q); +} + +static void +bna_mbox_mod_init(struct bna_mbox_mod *mbox_mod, struct bna *bna) +{ + bfa_nw_ioc_mbox_regisr(&bna->device.ioc, BFI_MC_LL, bna_ll_isr, bna); + mbox_mod->state = BNA_MBOX_FREE; + mbox_mod->msg_ctr = mbox_mod->msg_pending = 0; + INIT_LIST_HEAD(&mbox_mod->posted_q); + mbox_mod->bna = bna; +} + +static void +bna_mbox_mod_uninit(struct bna_mbox_mod *mbox_mod) +{ + mbox_mod->bna = NULL; +} + +/** + * LLPORT + */ +#define call_llport_stop_cbfn(llport, status)\ +do {\ + if ((llport)->stop_cbfn)\ + (llport)->stop_cbfn(&(llport)->bna->port, status);\ + (llport)->stop_cbfn = NULL;\ +} while (0) + +static void bna_fw_llport_up(struct bna_llport *llport); +static void bna_fw_cb_llport_up(void *arg, int status); +static void bna_fw_llport_down(struct bna_llport *llport); +static void bna_fw_cb_llport_down(void *arg, int status); +static void bna_llport_start(struct bna_llport *llport); +static void bna_llport_stop(struct bna_llport *llport); +static void bna_llport_fail(struct bna_llport *llport); + +enum bna_llport_event { + LLPORT_E_START = 1, + LLPORT_E_STOP = 2, + LLPORT_E_FAIL = 3, + LLPORT_E_UP = 4, + LLPORT_E_DOWN = 5, + LLPORT_E_FWRESP_UP = 6, + LLPORT_E_FWRESP_DOWN = 7 +}; + +enum bna_llport_state { + BNA_LLPORT_STOPPED = 1, + BNA_LLPORT_DOWN = 2, + BNA_LLPORT_UP_RESP_WAIT = 3, + BNA_LLPORT_DOWN_RESP_WAIT = 4, + BNA_LLPORT_UP = 5, + BNA_LLPORT_LAST_RESP_WAIT = 6 +}; + +bfa_fsm_state_decl(bna_llport, stopped, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, down, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, up_resp_wait, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, down_resp_wait, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, up, struct bna_llport, + enum bna_llport_event); +bfa_fsm_state_decl(bna_llport, last_resp_wait, struct bna_llport, + enum bna_llport_event); + +static struct bfa_sm_table llport_sm_table[] = { + {BFA_SM(bna_llport_sm_stopped), BNA_LLPORT_STOPPED}, + {BFA_SM(bna_llport_sm_down), BNA_LLPORT_DOWN}, + {BFA_SM(bna_llport_sm_up_resp_wait), BNA_LLPORT_UP_RESP_WAIT}, + {BFA_SM(bna_llport_sm_down_resp_wait), BNA_LLPORT_DOWN_RESP_WAIT}, + {BFA_SM(bna_llport_sm_up), BNA_LLPORT_UP}, + {BFA_SM(bna_llport_sm_last_resp_wait), BNA_LLPORT_LAST_RESP_WAIT} +}; + +static void +bna_llport_sm_stopped_entry(struct bna_llport *llport) +{ + llport->bna->port.link_cbfn((llport)->bna->bnad, BNA_LINK_DOWN); + call_llport_stop_cbfn(llport, BNA_CB_SUCCESS); +} + +static void +bna_llport_sm_stopped(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_START: + bfa_fsm_set_state(llport, bna_llport_sm_down); + break; + + case LLPORT_E_STOP: + call_llport_stop_cbfn(llport, BNA_CB_SUCCESS); + break; + + case LLPORT_E_FAIL: + break; + + case LLPORT_E_DOWN: + /* This event is received due to Rx objects failing */ + /* No-op */ + break; + + case LLPORT_E_FWRESP_UP: + case LLPORT_E_FWRESP_DOWN: + /** + * These events are received due to flushing of mbox when + * device fails + */ + /* No-op */ + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_down_entry(struct bna_llport *llport) +{ + bnad_cb_port_link_status((llport)->bna->bnad, BNA_LINK_DOWN); +} + +static void +bna_llport_sm_down(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_STOP: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_UP: + bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait); + bna_fw_llport_up(llport); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_up_resp_wait_entry(struct bna_llport *llport) +{ + /** + * NOTE: Do not call bna_fw_llport_up() here. That will over step + * mbox due to down_resp_wait -> up_resp_wait transition on event + * LLPORT_E_UP + */ +} + +static void +bna_llport_sm_up_resp_wait(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_STOP: + bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait); + break; + + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_DOWN: + bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait); + break; + + case LLPORT_E_FWRESP_UP: + bfa_fsm_set_state(llport, bna_llport_sm_up); + break; + + case LLPORT_E_FWRESP_DOWN: + /* down_resp_wait -> up_resp_wait transition on LLPORT_E_UP */ + bna_fw_llport_up(llport); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_down_resp_wait_entry(struct bna_llport *llport) +{ + /** + * NOTE: Do not call bna_fw_llport_down() here. That will over step + * mbox due to up_resp_wait -> down_resp_wait transition on event + * LLPORT_E_DOWN + */ +} + +static void +bna_llport_sm_down_resp_wait(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_STOP: + bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait); + break; + + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_UP: + bfa_fsm_set_state(llport, bna_llport_sm_up_resp_wait); + break; + + case LLPORT_E_FWRESP_UP: + /* up_resp_wait->down_resp_wait transition on LLPORT_E_DOWN */ + bna_fw_llport_down(llport); + break; + + case LLPORT_E_FWRESP_DOWN: + bfa_fsm_set_state(llport, bna_llport_sm_down); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_up_entry(struct bna_llport *llport) +{ +} + +static void +bna_llport_sm_up(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_STOP: + bfa_fsm_set_state(llport, bna_llport_sm_last_resp_wait); + bna_fw_llport_down(llport); + break; + + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_DOWN: + bfa_fsm_set_state(llport, bna_llport_sm_down_resp_wait); + bna_fw_llport_down(llport); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_llport_sm_last_resp_wait_entry(struct bna_llport *llport) +{ +} + +static void +bna_llport_sm_last_resp_wait(struct bna_llport *llport, + enum bna_llport_event event) +{ + switch (event) { + case LLPORT_E_FAIL: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + case LLPORT_E_DOWN: + /** + * This event is received due to Rx objects stopping in + * parallel to llport + */ + /* No-op */ + break; + + case LLPORT_E_FWRESP_UP: + /* up_resp_wait->last_resp_wait transition on LLPORT_T_STOP */ + bna_fw_llport_down(llport); + break; + + case LLPORT_E_FWRESP_DOWN: + bfa_fsm_set_state(llport, bna_llport_sm_stopped); + break; + + default: + bfa_sm_fault(llport->bna, event); + } +} + +static void +bna_fw_llport_admin_up(struct bna_llport *llport) +{ + struct bfi_ll_port_admin_req ll_req; + + memset(&ll_req, 0, sizeof(ll_req)); + ll_req.mh.msg_class = BFI_MC_LL; + ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ; + ll_req.mh.mtag.h2i.lpu_id = 0; + + ll_req.up = BNA_STATUS_T_ENABLED; + + bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_llport_up, llport); + + bna_mbox_send(llport->bna, &llport->mbox_qe); +} + +static void +bna_fw_llport_up(struct bna_llport *llport) +{ + if (llport->type == BNA_PORT_T_REGULAR) + bna_fw_llport_admin_up(llport); +} + +static void +bna_fw_cb_llport_up(void *arg, int status) +{ + struct bna_llport *llport = (struct bna_llport *)arg; + + bfa_q_qe_init(&llport->mbox_qe.qe); + bfa_fsm_send_event(llport, LLPORT_E_FWRESP_UP); +} + +static void +bna_fw_llport_admin_down(struct bna_llport *llport) +{ + struct bfi_ll_port_admin_req ll_req; + + memset(&ll_req, 0, sizeof(ll_req)); + ll_req.mh.msg_class = BFI_MC_LL; + ll_req.mh.msg_id = BFI_LL_H2I_PORT_ADMIN_REQ; + ll_req.mh.mtag.h2i.lpu_id = 0; + + ll_req.up = BNA_STATUS_T_DISABLED; + + bna_mbox_qe_fill(&llport->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_llport_down, llport); + + bna_mbox_send(llport->bna, &llport->mbox_qe); +} + +static void +bna_fw_llport_down(struct bna_llport *llport) +{ + if (llport->type == BNA_PORT_T_REGULAR) + bna_fw_llport_admin_down(llport); +} + +static void +bna_fw_cb_llport_down(void *arg, int status) +{ + struct bna_llport *llport = (struct bna_llport *)arg; + + bfa_q_qe_init(&llport->mbox_qe.qe); + bfa_fsm_send_event(llport, LLPORT_E_FWRESP_DOWN); +} + +static void +bna_port_cb_llport_stopped(struct bna_port *port, + enum bna_cb_status status) +{ + bfa_wc_down(&port->chld_stop_wc); +} + +static void +bna_llport_init(struct bna_llport *llport, struct bna *bna) +{ + llport->flags |= BNA_LLPORT_F_ENABLED; + llport->type = BNA_PORT_T_REGULAR; + llport->bna = bna; + + llport->link_status = BNA_LINK_DOWN; + + llport->admin_up_count = 0; + + llport->stop_cbfn = NULL; + + bfa_q_qe_init(&llport->mbox_qe.qe); + + bfa_fsm_set_state(llport, bna_llport_sm_stopped); +} + +static void +bna_llport_uninit(struct bna_llport *llport) +{ + llport->flags &= ~BNA_LLPORT_F_ENABLED; + + llport->bna = NULL; +} + +static void +bna_llport_start(struct bna_llport *llport) +{ + bfa_fsm_send_event(llport, LLPORT_E_START); +} + +static void +bna_llport_stop(struct bna_llport *llport) +{ + llport->stop_cbfn = bna_port_cb_llport_stopped; + + bfa_fsm_send_event(llport, LLPORT_E_STOP); +} + +static void +bna_llport_fail(struct bna_llport *llport) +{ + bfa_fsm_send_event(llport, LLPORT_E_FAIL); +} + +static int +bna_llport_state_get(struct bna_llport *llport) +{ + return bfa_sm_to_state(llport_sm_table, llport->fsm); +} + +void +bna_llport_admin_up(struct bna_llport *llport) +{ + llport->admin_up_count++; + + if (llport->admin_up_count == 1) { + llport->flags |= BNA_LLPORT_F_RX_ENABLED; + if (llport->flags & BNA_LLPORT_F_ENABLED) + bfa_fsm_send_event(llport, LLPORT_E_UP); + } +} + +void +bna_llport_admin_down(struct bna_llport *llport) +{ + llport->admin_up_count--; + + if (llport->admin_up_count == 0) { + llport->flags &= ~BNA_LLPORT_F_RX_ENABLED; + if (llport->flags & BNA_LLPORT_F_ENABLED) + bfa_fsm_send_event(llport, LLPORT_E_DOWN); + } +} + +/** + * PORT + */ +#define bna_port_chld_start(port)\ +do {\ + enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\ + enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\ + bna_llport_start(&(port)->llport);\ + bna_tx_mod_start(&(port)->bna->tx_mod, tx_type);\ + bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\ +} while (0) + +#define bna_port_chld_stop(port)\ +do {\ + enum bna_tx_type tx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_TX_T_REGULAR : BNA_TX_T_LOOPBACK;\ + enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\ + bfa_wc_up(&(port)->chld_stop_wc);\ + bfa_wc_up(&(port)->chld_stop_wc);\ + bfa_wc_up(&(port)->chld_stop_wc);\ + bna_llport_stop(&(port)->llport);\ + bna_tx_mod_stop(&(port)->bna->tx_mod, tx_type);\ + bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\ +} while (0) + +#define bna_port_chld_fail(port)\ +do {\ + bna_llport_fail(&(port)->llport);\ + bna_tx_mod_fail(&(port)->bna->tx_mod);\ + bna_rx_mod_fail(&(port)->bna->rx_mod);\ +} while (0) + +#define bna_port_rx_start(port)\ +do {\ + enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\ + bna_rx_mod_start(&(port)->bna->rx_mod, rx_type);\ +} while (0) + +#define bna_port_rx_stop(port)\ +do {\ + enum bna_rx_type rx_type = ((port)->type == BNA_PORT_T_REGULAR) ?\ + BNA_RX_T_REGULAR : BNA_RX_T_LOOPBACK;\ + bfa_wc_up(&(port)->chld_stop_wc);\ + bna_rx_mod_stop(&(port)->bna->rx_mod, rx_type);\ +} while (0) + +#define call_port_stop_cbfn(port, status)\ +do {\ + if ((port)->stop_cbfn)\ + (port)->stop_cbfn((port)->stop_cbarg, status);\ + (port)->stop_cbfn = NULL;\ + (port)->stop_cbarg = NULL;\ +} while (0) + +#define call_port_pause_cbfn(port, status)\ +do {\ + if ((port)->pause_cbfn)\ + (port)->pause_cbfn((port)->bna->bnad, status);\ + (port)->pause_cbfn = NULL;\ +} while (0) + +#define call_port_mtu_cbfn(port, status)\ +do {\ + if ((port)->mtu_cbfn)\ + (port)->mtu_cbfn((port)->bna->bnad, status);\ + (port)->mtu_cbfn = NULL;\ +} while (0) + +static void bna_fw_pause_set(struct bna_port *port); +static void bna_fw_cb_pause_set(void *arg, int status); +static void bna_fw_mtu_set(struct bna_port *port); +static void bna_fw_cb_mtu_set(void *arg, int status); + +enum bna_port_event { + PORT_E_START = 1, + PORT_E_STOP = 2, + PORT_E_FAIL = 3, + PORT_E_PAUSE_CFG = 4, + PORT_E_MTU_CFG = 5, + PORT_E_CHLD_STOPPED = 6, + PORT_E_FWRESP_PAUSE = 7, + PORT_E_FWRESP_MTU = 8 +}; + +enum bna_port_state { + BNA_PORT_STOPPED = 1, + BNA_PORT_MTU_INIT_WAIT = 2, + BNA_PORT_PAUSE_INIT_WAIT = 3, + BNA_PORT_LAST_RESP_WAIT = 4, + BNA_PORT_STARTED = 5, + BNA_PORT_PAUSE_CFG_WAIT = 6, + BNA_PORT_RX_STOP_WAIT = 7, + BNA_PORT_MTU_CFG_WAIT = 8, + BNA_PORT_CHLD_STOP_WAIT = 9 +}; + +bfa_fsm_state_decl(bna_port, stopped, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, mtu_init_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, pause_init_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, last_resp_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, started, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, pause_cfg_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, rx_stop_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, mtu_cfg_wait, struct bna_port, + enum bna_port_event); +bfa_fsm_state_decl(bna_port, chld_stop_wait, struct bna_port, + enum bna_port_event); + +static struct bfa_sm_table port_sm_table[] = { + {BFA_SM(bna_port_sm_stopped), BNA_PORT_STOPPED}, + {BFA_SM(bna_port_sm_mtu_init_wait), BNA_PORT_MTU_INIT_WAIT}, + {BFA_SM(bna_port_sm_pause_init_wait), BNA_PORT_PAUSE_INIT_WAIT}, + {BFA_SM(bna_port_sm_last_resp_wait), BNA_PORT_LAST_RESP_WAIT}, + {BFA_SM(bna_port_sm_started), BNA_PORT_STARTED}, + {BFA_SM(bna_port_sm_pause_cfg_wait), BNA_PORT_PAUSE_CFG_WAIT}, + {BFA_SM(bna_port_sm_rx_stop_wait), BNA_PORT_RX_STOP_WAIT}, + {BFA_SM(bna_port_sm_mtu_cfg_wait), BNA_PORT_MTU_CFG_WAIT}, + {BFA_SM(bna_port_sm_chld_stop_wait), BNA_PORT_CHLD_STOP_WAIT} +}; + +static void +bna_port_sm_stopped_entry(struct bna_port *port) +{ + call_port_pause_cbfn(port, BNA_CB_SUCCESS); + call_port_mtu_cbfn(port, BNA_CB_SUCCESS); + call_port_stop_cbfn(port, BNA_CB_SUCCESS); +} + +static void +bna_port_sm_stopped(struct bna_port *port, enum bna_port_event event) +{ + switch (event) { + case PORT_E_START: + bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait); + break; + + case PORT_E_STOP: + call_port_stop_cbfn(port, BNA_CB_SUCCESS); + break; + + case PORT_E_FAIL: + /* No-op */ + break; + + case PORT_E_PAUSE_CFG: + call_port_pause_cbfn(port, BNA_CB_SUCCESS); + break; + + case PORT_E_MTU_CFG: + call_port_mtu_cbfn(port, BNA_CB_SUCCESS); + break; + + case PORT_E_CHLD_STOPPED: + /** + * This event is received due to LLPort, Tx and Rx objects + * failing + */ + /* No-op */ + break; + + case PORT_E_FWRESP_PAUSE: + case PORT_E_FWRESP_MTU: + /** + * These events are received due to flushing of mbox when + * device fails + */ + /* No-op */ + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_mtu_init_wait_entry(struct bna_port *port) +{ + bna_fw_mtu_set(port); +} + +static void +bna_port_sm_mtu_init_wait(struct bna_port *port, enum bna_port_event event) +{ + switch (event) { + case PORT_E_STOP: + bfa_fsm_set_state(port, bna_port_sm_last_resp_wait); + break; + + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + break; + + case PORT_E_PAUSE_CFG: + /* No-op */ + break; + + case PORT_E_MTU_CFG: + port->flags |= BNA_PORT_F_MTU_CHANGED; + break; + + case PORT_E_FWRESP_MTU: + if (port->flags & BNA_PORT_F_MTU_CHANGED) { + port->flags &= ~BNA_PORT_F_MTU_CHANGED; + bna_fw_mtu_set(port); + } else { + bfa_fsm_set_state(port, bna_port_sm_pause_init_wait); + } + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_pause_init_wait_entry(struct bna_port *port) +{ + bna_fw_pause_set(port); +} + +static void +bna_port_sm_pause_init_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_STOP: + bfa_fsm_set_state(port, bna_port_sm_last_resp_wait); + break; + + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + break; + + case PORT_E_PAUSE_CFG: + port->flags |= BNA_PORT_F_PAUSE_CHANGED; + break; + + case PORT_E_MTU_CFG: + port->flags |= BNA_PORT_F_MTU_CHANGED; + break; + + case PORT_E_FWRESP_PAUSE: + if (port->flags & BNA_PORT_F_PAUSE_CHANGED) { + port->flags &= ~BNA_PORT_F_PAUSE_CHANGED; + bna_fw_pause_set(port); + } else if (port->flags & BNA_PORT_F_MTU_CHANGED) { + port->flags &= ~BNA_PORT_F_MTU_CHANGED; + bfa_fsm_set_state(port, bna_port_sm_mtu_init_wait); + } else { + bfa_fsm_set_state(port, bna_port_sm_started); + bna_port_chld_start(port); + } + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_last_resp_wait_entry(struct bna_port *port) +{ +} + +static void +bna_port_sm_last_resp_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + case PORT_E_FWRESP_PAUSE: + case PORT_E_FWRESP_MTU: + bfa_fsm_set_state(port, bna_port_sm_stopped); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_started_entry(struct bna_port *port) +{ + /** + * NOTE: Do not call bna_port_chld_start() here, since it will be + * inadvertently called during pause_cfg_wait->started transition + * as well + */ + call_port_pause_cbfn(port, BNA_CB_SUCCESS); + call_port_mtu_cbfn(port, BNA_CB_SUCCESS); +} + +static void +bna_port_sm_started(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_STOP: + bfa_fsm_set_state(port, bna_port_sm_chld_stop_wait); + break; + + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_PAUSE_CFG: + bfa_fsm_set_state(port, bna_port_sm_pause_cfg_wait); + break; + + case PORT_E_MTU_CFG: + bfa_fsm_set_state(port, bna_port_sm_rx_stop_wait); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_pause_cfg_wait_entry(struct bna_port *port) +{ + bna_fw_pause_set(port); +} + +static void +bna_port_sm_pause_cfg_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_FWRESP_PAUSE: + bfa_fsm_set_state(port, bna_port_sm_started); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_rx_stop_wait_entry(struct bna_port *port) +{ + bna_port_rx_stop(port); +} + +static void +bna_port_sm_rx_stop_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_CHLD_STOPPED: + bfa_fsm_set_state(port, bna_port_sm_mtu_cfg_wait); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_mtu_cfg_wait_entry(struct bna_port *port) +{ + bna_fw_mtu_set(port); +} + +static void +bna_port_sm_mtu_cfg_wait(struct bna_port *port, enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_FWRESP_MTU: + bfa_fsm_set_state(port, bna_port_sm_started); + bna_port_rx_start(port); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_port_sm_chld_stop_wait_entry(struct bna_port *port) +{ + bna_port_chld_stop(port); +} + +static void +bna_port_sm_chld_stop_wait(struct bna_port *port, + enum bna_port_event event) +{ + switch (event) { + case PORT_E_FAIL: + bfa_fsm_set_state(port, bna_port_sm_stopped); + bna_port_chld_fail(port); + break; + + case PORT_E_CHLD_STOPPED: + bfa_fsm_set_state(port, bna_port_sm_stopped); + break; + + default: + bfa_sm_fault(port->bna, event); + } +} + +static void +bna_fw_pause_set(struct bna_port *port) +{ + struct bfi_ll_set_pause_req ll_req; + + memset(&ll_req, 0, sizeof(ll_req)); + ll_req.mh.msg_class = BFI_MC_LL; + ll_req.mh.msg_id = BFI_LL_H2I_SET_PAUSE_REQ; + ll_req.mh.mtag.h2i.lpu_id = 0; + + ll_req.tx_pause = port->pause_config.tx_pause; + ll_req.rx_pause = port->pause_config.rx_pause; + + bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_pause_set, port); + + bna_mbox_send(port->bna, &port->mbox_qe); +} + +static void +bna_fw_cb_pause_set(void *arg, int status) +{ + struct bna_port *port = (struct bna_port *)arg; + + bfa_q_qe_init(&port->mbox_qe.qe); + bfa_fsm_send_event(port, PORT_E_FWRESP_PAUSE); +} + +void +bna_fw_mtu_set(struct bna_port *port) +{ + struct bfi_ll_mtu_info_req ll_req; + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_MTU_INFO_REQ, 0); + ll_req.mtu = htons((u16)port->mtu); + + bna_mbox_qe_fill(&port->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_mtu_set, port); + bna_mbox_send(port->bna, &port->mbox_qe); +} + +void +bna_fw_cb_mtu_set(void *arg, int status) +{ + struct bna_port *port = (struct bna_port *)arg; + + bfa_q_qe_init(&port->mbox_qe.qe); + bfa_fsm_send_event(port, PORT_E_FWRESP_MTU); +} + +static void +bna_port_cb_chld_stopped(void *arg) +{ + struct bna_port *port = (struct bna_port *)arg; + + bfa_fsm_send_event(port, PORT_E_CHLD_STOPPED); +} + +static void +bna_port_init(struct bna_port *port, struct bna *bna) +{ + port->bna = bna; + port->flags = 0; + port->mtu = 0; + port->type = BNA_PORT_T_REGULAR; + + port->link_cbfn = bnad_cb_port_link_status; + + port->chld_stop_wc.wc_resume = bna_port_cb_chld_stopped; + port->chld_stop_wc.wc_cbarg = port; + port->chld_stop_wc.wc_count = 0; + + port->stop_cbfn = NULL; + port->stop_cbarg = NULL; + + port->pause_cbfn = NULL; + + port->mtu_cbfn = NULL; + + bfa_q_qe_init(&port->mbox_qe.qe); + + bfa_fsm_set_state(port, bna_port_sm_stopped); + + bna_llport_init(&port->llport, bna); +} + +static void +bna_port_uninit(struct bna_port *port) +{ + bna_llport_uninit(&port->llport); + + port->flags = 0; + + port->bna = NULL; +} + +static int +bna_port_state_get(struct bna_port *port) +{ + return bfa_sm_to_state(port_sm_table, port->fsm); +} + +static void +bna_port_start(struct bna_port *port) +{ + port->flags |= BNA_PORT_F_DEVICE_READY; + if (port->flags & BNA_PORT_F_ENABLED) + bfa_fsm_send_event(port, PORT_E_START); +} + +static void +bna_port_stop(struct bna_port *port) +{ + port->stop_cbfn = bna_device_cb_port_stopped; + port->stop_cbarg = &port->bna->device; + + port->flags &= ~BNA_PORT_F_DEVICE_READY; + bfa_fsm_send_event(port, PORT_E_STOP); +} + +static void +bna_port_fail(struct bna_port *port) +{ + port->flags &= ~BNA_PORT_F_DEVICE_READY; + bfa_fsm_send_event(port, PORT_E_FAIL); +} + +void +bna_port_cb_tx_stopped(struct bna_port *port, enum bna_cb_status status) +{ + bfa_wc_down(&port->chld_stop_wc); +} + +void +bna_port_cb_rx_stopped(struct bna_port *port, enum bna_cb_status status) +{ + bfa_wc_down(&port->chld_stop_wc); +} + +int +bna_port_mtu_get(struct bna_port *port) +{ + return port->mtu; +} + +void +bna_port_enable(struct bna_port *port) +{ + if (port->fsm != (bfa_sm_t)bna_port_sm_stopped) + return; + + port->flags |= BNA_PORT_F_ENABLED; + + if (port->flags & BNA_PORT_F_DEVICE_READY) + bfa_fsm_send_event(port, PORT_E_START); +} + +void +bna_port_disable(struct bna_port *port, enum bna_cleanup_type type, + void (*cbfn)(void *, enum bna_cb_status)) +{ + if (type == BNA_SOFT_CLEANUP) { + (*cbfn)(port->bna->bnad, BNA_CB_SUCCESS); + return; + } + + port->stop_cbfn = cbfn; + port->stop_cbarg = port->bna->bnad; + + port->flags &= ~BNA_PORT_F_ENABLED; + + bfa_fsm_send_event(port, PORT_E_STOP); +} + +void +bna_port_pause_config(struct bna_port *port, + struct bna_pause_config *pause_config, + void (*cbfn)(struct bnad *, enum bna_cb_status)) +{ + port->pause_config = *pause_config; + + port->pause_cbfn = cbfn; + + bfa_fsm_send_event(port, PORT_E_PAUSE_CFG); +} + +void +bna_port_mtu_set(struct bna_port *port, int mtu, + void (*cbfn)(struct bnad *, enum bna_cb_status)) +{ + port->mtu = mtu; + + port->mtu_cbfn = cbfn; + + bfa_fsm_send_event(port, PORT_E_MTU_CFG); +} + +void +bna_port_mac_get(struct bna_port *port, mac_t *mac) +{ + *mac = bfa_nw_ioc_get_mac(&port->bna->device.ioc); +} + +/** + * DEVICE + */ +#define enable_mbox_intr(_device)\ +do {\ + u32 intr_status;\ + bna_intr_status_get((_device)->bna, intr_status);\ + bnad_cb_device_enable_mbox_intr((_device)->bna->bnad);\ + bna_mbox_intr_enable((_device)->bna);\ +} while (0) + +#define disable_mbox_intr(_device)\ +do {\ + bna_mbox_intr_disable((_device)->bna);\ + bnad_cb_device_disable_mbox_intr((_device)->bna->bnad);\ +} while (0) + +static const struct bna_chip_regs_offset reg_offset[] = +{{HOST_PAGE_NUM_FN0, HOSTFN0_INT_STATUS, + HOSTFN0_INT_MASK, HOST_MSIX_ERR_INDEX_FN0}, +{HOST_PAGE_NUM_FN1, HOSTFN1_INT_STATUS, + HOSTFN1_INT_MASK, HOST_MSIX_ERR_INDEX_FN1}, +{HOST_PAGE_NUM_FN2, HOSTFN2_INT_STATUS, + HOSTFN2_INT_MASK, HOST_MSIX_ERR_INDEX_FN2}, +{HOST_PAGE_NUM_FN3, HOSTFN3_INT_STATUS, + HOSTFN3_INT_MASK, HOST_MSIX_ERR_INDEX_FN3}, +}; + +enum bna_device_event { + DEVICE_E_ENABLE = 1, + DEVICE_E_DISABLE = 2, + DEVICE_E_IOC_READY = 3, + DEVICE_E_IOC_FAILED = 4, + DEVICE_E_IOC_DISABLED = 5, + DEVICE_E_IOC_RESET = 6, + DEVICE_E_PORT_STOPPED = 7, +}; + +enum bna_device_state { + BNA_DEVICE_STOPPED = 1, + BNA_DEVICE_IOC_READY_WAIT = 2, + BNA_DEVICE_READY = 3, + BNA_DEVICE_PORT_STOP_WAIT = 4, + BNA_DEVICE_IOC_DISABLE_WAIT = 5, + BNA_DEVICE_FAILED = 6 +}; + +bfa_fsm_state_decl(bna_device, stopped, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, ioc_ready_wait, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, ready, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, port_stop_wait, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, ioc_disable_wait, struct bna_device, + enum bna_device_event); +bfa_fsm_state_decl(bna_device, failed, struct bna_device, + enum bna_device_event); + +static struct bfa_sm_table device_sm_table[] = { + {BFA_SM(bna_device_sm_stopped), BNA_DEVICE_STOPPED}, + {BFA_SM(bna_device_sm_ioc_ready_wait), BNA_DEVICE_IOC_READY_WAIT}, + {BFA_SM(bna_device_sm_ready), BNA_DEVICE_READY}, + {BFA_SM(bna_device_sm_port_stop_wait), BNA_DEVICE_PORT_STOP_WAIT}, + {BFA_SM(bna_device_sm_ioc_disable_wait), BNA_DEVICE_IOC_DISABLE_WAIT}, + {BFA_SM(bna_device_sm_failed), BNA_DEVICE_FAILED}, +}; + +static void +bna_device_sm_stopped_entry(struct bna_device *device) +{ + if (device->stop_cbfn) + device->stop_cbfn(device->stop_cbarg, BNA_CB_SUCCESS); + + device->stop_cbfn = NULL; + device->stop_cbarg = NULL; +} + +static void +bna_device_sm_stopped(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_ENABLE: + if (device->intr_type == BNA_INTR_T_MSIX) + bna_mbox_msix_idx_set(device); + bfa_nw_ioc_enable(&device->ioc); + bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait); + break; + + case DEVICE_E_DISABLE: + bfa_fsm_set_state(device, bna_device_sm_stopped); + break; + + case DEVICE_E_IOC_RESET: + enable_mbox_intr(device); + break; + + case DEVICE_E_IOC_FAILED: + bfa_fsm_set_state(device, bna_device_sm_failed); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_ioc_ready_wait_entry(struct bna_device *device) +{ + /** + * Do not call bfa_ioc_enable() here. It must be called in the + * previous state due to failed -> ioc_ready_wait transition. + */ +} + +static void +bna_device_sm_ioc_ready_wait(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_DISABLE: + if (device->ready_cbfn) + device->ready_cbfn(device->ready_cbarg, + BNA_CB_INTERRUPT); + device->ready_cbfn = NULL; + device->ready_cbarg = NULL; + bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait); + break; + + case DEVICE_E_IOC_READY: + bfa_fsm_set_state(device, bna_device_sm_ready); + break; + + case DEVICE_E_IOC_FAILED: + bfa_fsm_set_state(device, bna_device_sm_failed); + break; + + case DEVICE_E_IOC_RESET: + enable_mbox_intr(device); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_ready_entry(struct bna_device *device) +{ + bna_mbox_mod_start(&device->bna->mbox_mod); + bna_port_start(&device->bna->port); + + if (device->ready_cbfn) + device->ready_cbfn(device->ready_cbarg, + BNA_CB_SUCCESS); + device->ready_cbfn = NULL; + device->ready_cbarg = NULL; +} + +static void +bna_device_sm_ready(struct bna_device *device, enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_DISABLE: + bfa_fsm_set_state(device, bna_device_sm_port_stop_wait); + break; + + case DEVICE_E_IOC_FAILED: + bfa_fsm_set_state(device, bna_device_sm_failed); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_port_stop_wait_entry(struct bna_device *device) +{ + bna_port_stop(&device->bna->port); +} + +static void +bna_device_sm_port_stop_wait(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_PORT_STOPPED: + bna_mbox_mod_stop(&device->bna->mbox_mod); + bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait); + break; + + case DEVICE_E_IOC_FAILED: + disable_mbox_intr(device); + bna_port_fail(&device->bna->port); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_ioc_disable_wait_entry(struct bna_device *device) +{ + bfa_nw_ioc_disable(&device->ioc); +} + +static void +bna_device_sm_ioc_disable_wait(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_IOC_DISABLED: + disable_mbox_intr(device); + bfa_fsm_set_state(device, bna_device_sm_stopped); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +static void +bna_device_sm_failed_entry(struct bna_device *device) +{ + disable_mbox_intr(device); + bna_port_fail(&device->bna->port); + bna_mbox_mod_stop(&device->bna->mbox_mod); + + if (device->ready_cbfn) + device->ready_cbfn(device->ready_cbarg, + BNA_CB_FAIL); + device->ready_cbfn = NULL; + device->ready_cbarg = NULL; +} + +static void +bna_device_sm_failed(struct bna_device *device, + enum bna_device_event event) +{ + switch (event) { + case DEVICE_E_DISABLE: + bfa_fsm_set_state(device, bna_device_sm_ioc_disable_wait); + break; + + case DEVICE_E_IOC_RESET: + enable_mbox_intr(device); + bfa_fsm_set_state(device, bna_device_sm_ioc_ready_wait); + break; + + default: + bfa_sm_fault(device->bna, event); + } +} + +/* IOC callback functions */ + +static void +bna_device_cb_iocll_ready(void *dev, enum bfa_status error) +{ + struct bna_device *device = (struct bna_device *)dev; + + if (error) + bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED); + else + bfa_fsm_send_event(device, DEVICE_E_IOC_READY); +} + +static void +bna_device_cb_iocll_disabled(void *dev) +{ + struct bna_device *device = (struct bna_device *)dev; + + bfa_fsm_send_event(device, DEVICE_E_IOC_DISABLED); +} + +static void +bna_device_cb_iocll_failed(void *dev) +{ + struct bna_device *device = (struct bna_device *)dev; + + bfa_fsm_send_event(device, DEVICE_E_IOC_FAILED); +} + +static void +bna_device_cb_iocll_reset(void *dev) +{ + struct bna_device *device = (struct bna_device *)dev; + + bfa_fsm_send_event(device, DEVICE_E_IOC_RESET); +} + +static struct bfa_ioc_cbfn bfa_iocll_cbfn = { + bna_device_cb_iocll_ready, + bna_device_cb_iocll_disabled, + bna_device_cb_iocll_failed, + bna_device_cb_iocll_reset +}; + +/* device */ +static void +bna_adv_device_init(struct bna_device *device, struct bna *bna, + struct bna_res_info *res_info) +{ + u8 *kva; + u64 dma; + + device->bna = bna; + + kva = res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mdl[0].kva; + + /** + * Attach common modules (Diag, SFP, CEE, Port) and claim respective + * DMA memory. + */ + BNA_GET_DMA_ADDR( + &res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].dma, dma); + kva = res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mdl[0].kva; + + bfa_nw_cee_attach(&bna->cee, &device->ioc, bna); + bfa_nw_cee_mem_claim(&bna->cee, kva, dma); + kva += bfa_nw_cee_meminfo(); + dma += bfa_nw_cee_meminfo(); + +} + +static void +bna_device_init(struct bna_device *device, struct bna *bna, + struct bna_res_info *res_info) +{ + u64 dma; + + device->bna = bna; + + /** + * Attach IOC and claim: + * 1. DMA memory for IOC attributes + * 2. Kernel memory for FW trace + */ + bfa_nw_ioc_attach(&device->ioc, device, &bfa_iocll_cbfn); + bfa_nw_ioc_pci_init(&device->ioc, &bna->pcidev, BFI_MC_LL); + + BNA_GET_DMA_ADDR( + &res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].dma, dma); + bfa_nw_ioc_mem_claim(&device->ioc, + res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mdl[0].kva, + dma); + + bna_adv_device_init(device, bna, res_info); + /* + * Initialize mbox_mod only after IOC, so that mbox handler + * registration goes through + */ + device->intr_type = + res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type; + device->vector = + res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.idl[0].vector; + bna_mbox_mod_init(&bna->mbox_mod, bna); + + device->ready_cbfn = device->stop_cbfn = NULL; + device->ready_cbarg = device->stop_cbarg = NULL; + + bfa_fsm_set_state(device, bna_device_sm_stopped); +} + +static void +bna_device_uninit(struct bna_device *device) +{ + bna_mbox_mod_uninit(&device->bna->mbox_mod); + + bfa_nw_ioc_detach(&device->ioc); + + device->bna = NULL; +} + +static void +bna_device_cb_port_stopped(void *arg, enum bna_cb_status status) +{ + struct bna_device *device = (struct bna_device *)arg; + + bfa_fsm_send_event(device, DEVICE_E_PORT_STOPPED); +} + +static int +bna_device_status_get(struct bna_device *device) +{ + return device->fsm == (bfa_fsm_t)bna_device_sm_ready; +} + +void +bna_device_enable(struct bna_device *device) +{ + if (device->fsm != (bfa_fsm_t)bna_device_sm_stopped) { + bnad_cb_device_enabled(device->bna->bnad, BNA_CB_BUSY); + return; + } + + device->ready_cbfn = bnad_cb_device_enabled; + device->ready_cbarg = device->bna->bnad; + + bfa_fsm_send_event(device, DEVICE_E_ENABLE); +} + +void +bna_device_disable(struct bna_device *device, enum bna_cleanup_type type) +{ + if (type == BNA_SOFT_CLEANUP) { + bnad_cb_device_disabled(device->bna->bnad, BNA_CB_SUCCESS); + return; + } + + device->stop_cbfn = bnad_cb_device_disabled; + device->stop_cbarg = device->bna->bnad; + + bfa_fsm_send_event(device, DEVICE_E_DISABLE); +} + +static int +bna_device_state_get(struct bna_device *device) +{ + return bfa_sm_to_state(device_sm_table, device->fsm); +} + +const u32 bna_napi_dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX] = { + {12, 12}, + {6, 10}, + {5, 10}, + {4, 8}, + {3, 6}, + {3, 6}, + {2, 4}, + {1, 2}, +}; + +/* utils */ + +static void +bna_adv_res_req(struct bna_res_info *res_info) +{ + /* DMA memory for COMMON_MODULE */ + res_info[BNA_RES_MEM_T_COM].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_COM].res_u.mem_info.mem_type = BNA_MEM_T_DMA; + res_info[BNA_RES_MEM_T_COM].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_COM].res_u.mem_info.len = ALIGN( + bfa_nw_cee_meminfo(), PAGE_SIZE); + + /* Virtual memory for retreiving fw_trc */ + res_info[BNA_RES_MEM_T_FWTRC].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.mem_type = BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.num = 0; + res_info[BNA_RES_MEM_T_FWTRC].res_u.mem_info.len = 0; + + /* DMA memory for retreiving stats */ + res_info[BNA_RES_MEM_T_STATS].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mem_type = BNA_MEM_T_DMA; + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.len = + ALIGN(BFI_HW_STATS_SIZE, PAGE_SIZE); + + /* Virtual memory for soft stats */ + res_info[BNA_RES_MEM_T_SWSTATS].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mem_type = BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.len = + sizeof(struct bna_sw_stats); +} + +static void +bna_sw_stats_get(struct bna *bna, struct bna_sw_stats *sw_stats) +{ + struct bna_tx *tx; + struct bna_txq *txq; + struct bna_rx *rx; + struct bna_rxp *rxp; + struct list_head *qe; + struct list_head *txq_qe; + struct list_head *rxp_qe; + struct list_head *mac_qe; + int i; + + sw_stats->device_state = bna_device_state_get(&bna->device); + sw_stats->port_state = bna_port_state_get(&bna->port); + sw_stats->port_flags = bna->port.flags; + sw_stats->llport_state = bna_llport_state_get(&bna->port.llport); + sw_stats->priority = bna->port.priority; + + i = 0; + list_for_each(qe, &bna->tx_mod.tx_active_q) { + tx = (struct bna_tx *)qe; + sw_stats->tx_stats[i].tx_state = bna_tx_state_get(tx); + sw_stats->tx_stats[i].tx_flags = tx->flags; + + sw_stats->tx_stats[i].num_txqs = 0; + sw_stats->tx_stats[i].txq_bmap[0] = 0; + sw_stats->tx_stats[i].txq_bmap[1] = 0; + list_for_each(txq_qe, &tx->txq_q) { + txq = (struct bna_txq *)txq_qe; + if (txq->txq_id < 32) + sw_stats->tx_stats[i].txq_bmap[0] |= + ((u32)1 << txq->txq_id); + else + sw_stats->tx_stats[i].txq_bmap[1] |= + ((u32) + 1 << (txq->txq_id - 32)); + sw_stats->tx_stats[i].num_txqs++; + } + + sw_stats->tx_stats[i].txf_id = tx->txf.txf_id; + + i++; + } + sw_stats->num_active_tx = i; + + i = 0; + list_for_each(qe, &bna->rx_mod.rx_active_q) { + rx = (struct bna_rx *)qe; + sw_stats->rx_stats[i].rx_state = bna_rx_state_get(rx); + sw_stats->rx_stats[i].rx_flags = rx->rx_flags; + + sw_stats->rx_stats[i].num_rxps = 0; + sw_stats->rx_stats[i].num_rxqs = 0; + sw_stats->rx_stats[i].rxq_bmap[0] = 0; + sw_stats->rx_stats[i].rxq_bmap[1] = 0; + sw_stats->rx_stats[i].cq_bmap[0] = 0; + sw_stats->rx_stats[i].cq_bmap[1] = 0; + list_for_each(rxp_qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)rxp_qe; + + sw_stats->rx_stats[i].num_rxqs += 1; + + if (rxp->type == BNA_RXP_SINGLE) { + if (rxp->rxq.single.only->rxq_id < 32) { + sw_stats->rx_stats[i].rxq_bmap[0] |= + ((u32)1 << + rxp->rxq.single.only->rxq_id); + } else { + sw_stats->rx_stats[i].rxq_bmap[1] |= + ((u32)1 << + (rxp->rxq.single.only->rxq_id - 32)); + } + } else { + if (rxp->rxq.slr.large->rxq_id < 32) { + sw_stats->rx_stats[i].rxq_bmap[0] |= + ((u32)1 << + rxp->rxq.slr.large->rxq_id); + } else { + sw_stats->rx_stats[i].rxq_bmap[1] |= + ((u32)1 << + (rxp->rxq.slr.large->rxq_id - 32)); + } + + if (rxp->rxq.slr.small->rxq_id < 32) { + sw_stats->rx_stats[i].rxq_bmap[0] |= + ((u32)1 << + rxp->rxq.slr.small->rxq_id); + } else { + sw_stats->rx_stats[i].rxq_bmap[1] |= + ((u32)1 << + (rxp->rxq.slr.small->rxq_id - 32)); + } + sw_stats->rx_stats[i].num_rxqs += 1; + } + + if (rxp->cq.cq_id < 32) + sw_stats->rx_stats[i].cq_bmap[0] |= + (1 << rxp->cq.cq_id); + else + sw_stats->rx_stats[i].cq_bmap[1] |= + (1 << (rxp->cq.cq_id - 32)); + + sw_stats->rx_stats[i].num_rxps++; + } + + sw_stats->rx_stats[i].rxf_id = rx->rxf.rxf_id; + sw_stats->rx_stats[i].rxf_state = bna_rxf_state_get(&rx->rxf); + sw_stats->rx_stats[i].rxf_oper_state = rx->rxf.rxf_oper_state; + + sw_stats->rx_stats[i].num_active_ucast = 0; + if (rx->rxf.ucast_active_mac) + sw_stats->rx_stats[i].num_active_ucast++; + list_for_each(mac_qe, &rx->rxf.ucast_active_q) + sw_stats->rx_stats[i].num_active_ucast++; + + sw_stats->rx_stats[i].num_active_mcast = 0; + list_for_each(mac_qe, &rx->rxf.mcast_active_q) + sw_stats->rx_stats[i].num_active_mcast++; + + sw_stats->rx_stats[i].rxmode_active = rx->rxf.rxmode_active; + sw_stats->rx_stats[i].vlan_filter_status = + rx->rxf.vlan_filter_status; + memcpy(sw_stats->rx_stats[i].vlan_filter_table, + rx->rxf.vlan_filter_table, + sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32)); + + sw_stats->rx_stats[i].rss_status = rx->rxf.rss_status; + sw_stats->rx_stats[i].hds_status = rx->rxf.hds_status; + + i++; + } + sw_stats->num_active_rx = i; +} + +static void +bna_fw_cb_stats_get(void *arg, int status) +{ + struct bna *bna = (struct bna *)arg; + u64 *p_stats; + int i, count; + int rxf_count, txf_count; + u64 rxf_bmap, txf_bmap; + + bfa_q_qe_init(&bna->mbox_qe.qe); + + if (status == 0) { + p_stats = (u64 *)bna->stats.hw_stats; + count = sizeof(struct bfi_ll_stats) / sizeof(u64); + for (i = 0; i < count; i++) + p_stats[i] = cpu_to_be64(p_stats[i]); + + rxf_count = 0; + rxf_bmap = (u64)bna->stats.rxf_bmap[0] | + ((u64)bna->stats.rxf_bmap[1] << 32); + for (i = 0; i < BFI_LL_RXF_ID_MAX; i++) + if (rxf_bmap & ((u64)1 << i)) + rxf_count++; + + txf_count = 0; + txf_bmap = (u64)bna->stats.txf_bmap[0] | + ((u64)bna->stats.txf_bmap[1] << 32); + for (i = 0; i < BFI_LL_TXF_ID_MAX; i++) + if (txf_bmap & ((u64)1 << i)) + txf_count++; + + p_stats = (u64 *)&bna->stats.hw_stats->rxf_stats[0] + + ((rxf_count * sizeof(struct bfi_ll_stats_rxf) + + txf_count * sizeof(struct bfi_ll_stats_txf))/ + sizeof(u64)); + + /* Populate the TXF stats from the firmware DMAed copy */ + for (i = (BFI_LL_TXF_ID_MAX - 1); i >= 0; i--) + if (txf_bmap & ((u64)1 << i)) { + p_stats -= sizeof(struct bfi_ll_stats_txf)/ + sizeof(u64); + memcpy(&bna->stats.hw_stats->txf_stats[i], + p_stats, + sizeof(struct bfi_ll_stats_txf)); + } + + /* Populate the RXF stats from the firmware DMAed copy */ + for (i = (BFI_LL_RXF_ID_MAX - 1); i >= 0; i--) + if (rxf_bmap & ((u64)1 << i)) { + p_stats -= sizeof(struct bfi_ll_stats_rxf)/ + sizeof(u64); + memcpy(&bna->stats.hw_stats->rxf_stats[i], + p_stats, + sizeof(struct bfi_ll_stats_rxf)); + } + + bna_sw_stats_get(bna, bna->stats.sw_stats); + bnad_cb_stats_get(bna->bnad, BNA_CB_SUCCESS, &bna->stats); + } else + bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats); +} + +static void +bna_fw_stats_get(struct bna *bna) +{ + struct bfi_ll_stats_req ll_req; + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_GET_REQ, 0); + ll_req.stats_mask = htons(BFI_LL_STATS_ALL); + + ll_req.rxf_id_mask[0] = htonl(bna->rx_mod.rxf_bmap[0]); + ll_req.rxf_id_mask[1] = htonl(bna->rx_mod.rxf_bmap[1]); + ll_req.txf_id_mask[0] = htonl(bna->tx_mod.txf_bmap[0]); + ll_req.txf_id_mask[1] = htonl(bna->tx_mod.txf_bmap[1]); + + ll_req.host_buffer.a32.addr_hi = bna->hw_stats_dma.msb; + ll_req.host_buffer.a32.addr_lo = bna->hw_stats_dma.lsb; + + bna_mbox_qe_fill(&bna->mbox_qe, &ll_req, sizeof(ll_req), + bna_fw_cb_stats_get, bna); + bna_mbox_send(bna, &bna->mbox_qe); + + bna->stats.rxf_bmap[0] = bna->rx_mod.rxf_bmap[0]; + bna->stats.rxf_bmap[1] = bna->rx_mod.rxf_bmap[1]; + bna->stats.txf_bmap[0] = bna->tx_mod.txf_bmap[0]; + bna->stats.txf_bmap[1] = bna->tx_mod.txf_bmap[1]; +} + +void +bna_stats_get(struct bna *bna) +{ + if (bna_device_status_get(&bna->device)) + bna_fw_stats_get(bna); + else + bnad_cb_stats_get(bna->bnad, BNA_CB_FAIL, &bna->stats); +} + +/* IB */ +static void +bna_ib_coalescing_timeo_set(struct bna_ib *ib, u8 coalescing_timeo) +{ + ib->ib_config.coalescing_timeo = coalescing_timeo; + + if (ib->start_count) + ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK( + (u32)ib->ib_config.coalescing_timeo, 0); +} + +/* RxF */ +void +bna_rxf_adv_init(struct bna_rxf *rxf, + struct bna_rx *rx, + struct bna_rx_config *q_config) +{ + switch (q_config->rxp_type) { + case BNA_RXP_SINGLE: + /* No-op */ + break; + case BNA_RXP_SLR: + rxf->ctrl_flags |= BNA_RXF_CF_SM_LG_RXQ; + break; + case BNA_RXP_HDS: + rxf->hds_cfg.hdr_type = q_config->hds_config.hdr_type; + rxf->hds_cfg.header_size = + q_config->hds_config.header_size; + rxf->forced_offset = 0; + break; + default: + break; + } + + if (q_config->rss_status == BNA_STATUS_T_ENABLED) { + rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE; + rxf->rss_cfg.hash_type = q_config->rss_config.hash_type; + rxf->rss_cfg.hash_mask = q_config->rss_config.hash_mask; + memcpy(&rxf->rss_cfg.toeplitz_hash_key[0], + &q_config->rss_config.toeplitz_hash_key[0], + sizeof(rxf->rss_cfg.toeplitz_hash_key)); + } +} + +static void +rxf_fltr_mbox_cmd(struct bna_rxf *rxf, u8 cmd, enum bna_status status) +{ + struct bfi_ll_rxf_req req; + + bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0); + + req.rxf_id = rxf->rxf_id; + req.enable = status; + + bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req), + rxf_cb_cam_fltr_mbox_cmd, rxf); + + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static void +__rxf_default_function_config(struct bna_rxf *rxf, enum bna_status status) +{ + struct bna_rx_fndb_ram *rx_fndb_ram; + u32 ctrl_flags; + int i; + + rx_fndb_ram = (struct bna_rx_fndb_ram *) + BNA_GET_MEM_BASE_ADDR(rxf->rx->bna->pcidev.pci_bar_kva, + RX_FNDB_RAM_BASE_OFFSET); + + for (i = 0; i < BFI_MAX_RXF; i++) { + if (status == BNA_STATUS_T_ENABLED) { + if (i == rxf->rxf_id) + continue; + + ctrl_flags = + readl(&rx_fndb_ram[i].control_flags); + ctrl_flags |= BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE; + writel(ctrl_flags, + &rx_fndb_ram[i].control_flags); + } else { + ctrl_flags = + readl(&rx_fndb_ram[i].control_flags); + ctrl_flags &= ~BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE; + writel(ctrl_flags, + &rx_fndb_ram[i].control_flags); + } + } +} + +int +rxf_process_packet_filter_ucast(struct bna_rxf *rxf) +{ + struct bna_mac *mac = NULL; + struct list_head *qe; + + /* Add additional MAC entries */ + if (!list_empty(&rxf->ucast_pending_add_q)) { + bfa_q_deq(&rxf->ucast_pending_add_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_ADD_REQ, mac); + list_add_tail(&mac->qe, &rxf->ucast_active_q); + return 1; + } + + /* Delete MAC addresses previousely added */ + if (!list_empty(&rxf->ucast_pending_del_q)) { + bfa_q_deq(&rxf->ucast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + return 1; + } + + return 0; +} + +int +rxf_process_packet_filter_promisc(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* Enable/disable promiscuous mode */ + if (is_promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move promisc configuration from pending -> active */ + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active |= BNA_RXMODE_PROMISC; + + /* Disable VLAN filter to allow all VLANs */ + __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ, + BNA_STATUS_T_ENABLED); + return 1; + } else if (is_promisc_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move promisc configuration from pending -> active */ + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + bna->rxf_promisc_id = BFI_MAX_RXF; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_process_packet_filter_default(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* Enable/disable default mode */ + if (is_default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move default configuration from pending -> active */ + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active |= BNA_RXMODE_DEFAULT; + + /* Disable VLAN filter to allow all VLANs */ + __rxf_vlan_filter_set(rxf, BNA_STATUS_T_DISABLED); + /* Redirect all other RxF vlan filtering to this one */ + __rxf_default_function_config(rxf, BNA_STATUS_T_ENABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, + BNA_STATUS_T_ENABLED); + return 1; + } else if (is_default_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move default configuration from pending -> active */ + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + bna->rxf_default_id = BFI_MAX_RXF; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + /* Stop RxF vlan filter table redirection */ + __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_process_packet_filter_allmulti(struct bna_rxf *rxf) +{ + /* Enable/disable allmulti mode */ + if (is_allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move allmulti configuration from pending -> active */ + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active |= BNA_RXMODE_ALLMULTI; + + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ, + BNA_STATUS_T_ENABLED); + return 1; + } else if (is_allmulti_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move allmulti configuration from pending -> active */ + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_clear_packet_filter_ucast(struct bna_rxf *rxf) +{ + struct bna_mac *mac = NULL; + struct list_head *qe; + + /* 1. delete pending ucast entries */ + if (!list_empty(&rxf->ucast_pending_del_q)) { + bfa_q_deq(&rxf->ucast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + return 1; + } + + /* 2. clear active ucast entries; move them to pending_add_q */ + if (!list_empty(&rxf->ucast_active_q)) { + bfa_q_deq(&rxf->ucast_active_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_DEL_REQ, mac); + list_add_tail(&mac->qe, &rxf->ucast_pending_add_q); + return 1; + } + + return 0; +} + +int +rxf_clear_packet_filter_promisc(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* 6. Execute pending promisc mode disable command */ + if (is_promisc_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move promisc configuration from pending -> active */ + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + bna->rxf_promisc_id = BFI_MAX_RXF; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + /* 7. Clear active promisc mode; move it to pending enable */ + if (rxf->rxmode_active & BNA_RXMODE_PROMISC) { + /* move promisc configuration from active -> pending */ + promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_PROMISCUOUS_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_clear_packet_filter_default(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* 8. Execute pending default mode disable command */ + if (is_default_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move default configuration from pending -> active */ + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + bna->rxf_default_id = BFI_MAX_RXF; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + /* Stop RxF vlan filter table redirection */ + __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + /* 9. Clear active default mode; move it to pending enable */ + if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { + /* move default configuration from active -> pending */ + default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + + /* Revert VLAN filter */ + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + /* Stop RxF vlan filter table redirection */ + __rxf_default_function_config(rxf, BNA_STATUS_T_DISABLED); + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_RXF_DEFAULT_SET_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +int +rxf_clear_packet_filter_allmulti(struct bna_rxf *rxf) +{ + /* 10. Execute pending allmulti mode disable command */ + if (is_allmulti_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* move allmulti configuration from pending -> active */ + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + /* 11. Clear active allmulti mode; move it to pending enable */ + if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) { + /* move allmulti configuration from active -> pending */ + allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + rxf_fltr_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_FILTER_REQ, + BNA_STATUS_T_DISABLED); + return 1; + } + + return 0; +} + +void +rxf_reset_packet_filter_ucast(struct bna_rxf *rxf) +{ + struct list_head *qe; + struct bna_mac *mac; + + /* 1. Move active ucast entries to pending_add_q */ + while (!list_empty(&rxf->ucast_active_q)) { + bfa_q_deq(&rxf->ucast_active_q, &qe); + bfa_q_qe_init(qe); + list_add_tail(qe, &rxf->ucast_pending_add_q); + } + + /* 2. Throw away delete pending ucast entries */ + while (!list_empty(&rxf->ucast_pending_del_q)) { + bfa_q_deq(&rxf->ucast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + } +} + +void +rxf_reset_packet_filter_promisc(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* 6. Clear pending promisc mode disable */ + if (is_promisc_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + bna->rxf_promisc_id = BFI_MAX_RXF; + } + + /* 7. Move promisc mode config from active -> pending */ + if (rxf->rxmode_active & BNA_RXMODE_PROMISC) { + promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_PROMISC; + } + +} + +void +rxf_reset_packet_filter_default(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + + /* 8. Clear pending default mode disable */ + if (is_default_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + bna->rxf_default_id = BFI_MAX_RXF; + } + + /* 9. Move default mode config from active -> pending */ + if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { + default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_DEFAULT; + } +} + +void +rxf_reset_packet_filter_allmulti(struct bna_rxf *rxf) +{ + /* 10. Clear pending allmulti mode disable */ + if (is_allmulti_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + } + + /* 11. Move allmulti mode config from active -> pending */ + if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) { + allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + rxf->rxmode_active &= ~BNA_RXMODE_ALLMULTI; + } +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +static int +rxf_promisc_enable(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + int ret = 0; + + /* There can not be any pending disable command */ + + /* Do nothing if pending enable or already enabled */ + if (is_promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask) || + (rxf->rxmode_active & BNA_RXMODE_PROMISC)) { + /* Schedule enable */ + } else { + /* Promisc mode should not be active in the system */ + promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + bna->rxf_promisc_id = rxf->rxf_id; + ret = 1; + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +static int +rxf_promisc_disable(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + int ret = 0; + + /* There can not be any pending disable */ + + /* Turn off pending enable command , if any */ + if (is_promisc_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* Promisc mode should not be active */ + /* system promisc state should be pending */ + promisc_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + /* Remove the promisc state from the system */ + bna->rxf_promisc_id = BFI_MAX_RXF; + + /* Schedule disable */ + } else if (rxf->rxmode_active & BNA_RXMODE_PROMISC) { + /* Promisc mode should be active in the system */ + promisc_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + ret = 1; + + /* Do nothing if already disabled */ + } else { + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +static int +rxf_default_enable(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + int ret = 0; + + /* There can not be any pending disable command */ + + /* Do nothing if pending enable or already enabled */ + if (is_default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask) || + (rxf->rxmode_active & BNA_RXMODE_DEFAULT)) { + /* Schedule enable */ + } else { + /* Default mode should not be active in the system */ + default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + bna->rxf_default_id = rxf->rxf_id; + ret = 1; + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +static int +rxf_default_disable(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + int ret = 0; + + /* There can not be any pending disable */ + + /* Turn off pending enable command , if any */ + if (is_default_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* Promisc mode should not be active */ + /* system default state should be pending */ + default_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + /* Remove the default state from the system */ + bna->rxf_default_id = BFI_MAX_RXF; + + /* Schedule disable */ + } else if (rxf->rxmode_active & BNA_RXMODE_DEFAULT) { + /* Default mode should be active in the system */ + default_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + ret = 1; + + /* Do nothing if already disabled */ + } else { + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +static int +rxf_allmulti_enable(struct bna_rxf *rxf) +{ + int ret = 0; + + /* There can not be any pending disable command */ + + /* Do nothing if pending enable or already enabled */ + if (is_allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask) || + (rxf->rxmode_active & BNA_RXMODE_ALLMULTI)) { + /* Schedule enable */ + } else { + allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + ret = 1; + } + + return ret; +} + +/** + * Should only be called by bna_rxf_mode_set. + * Helps deciding if h/w configuration is needed or not. + * Returns: + * 0 = no h/w change + * 1 = need h/w change + */ +static int +rxf_allmulti_disable(struct bna_rxf *rxf) +{ + int ret = 0; + + /* There can not be any pending disable */ + + /* Turn off pending enable command , if any */ + if (is_allmulti_enable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask)) { + /* Allmulti mode should not be active */ + allmulti_inactive(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + + /* Schedule disable */ + } else if (rxf->rxmode_active & BNA_RXMODE_ALLMULTI) { + allmulti_disable(rxf->rxmode_pending, + rxf->rxmode_pending_bitmask); + ret = 1; + } + + return ret; +} + +/* RxF <- bnad */ +enum bna_cb_status +bna_rx_mode_set(struct bna_rx *rx, enum bna_rxmode new_mode, + enum bna_rxmode bitmask, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + int need_hw_config = 0; + + /* Error checks */ + + if (is_promisc_enable(new_mode, bitmask)) { + /* If promisc mode is already enabled elsewhere in the system */ + if ((rx->bna->rxf_promisc_id != BFI_MAX_RXF) && + (rx->bna->rxf_promisc_id != rxf->rxf_id)) + goto err_return; + + /* If default mode is already enabled in the system */ + if (rx->bna->rxf_default_id != BFI_MAX_RXF) + goto err_return; + + /* Trying to enable promiscuous and default mode together */ + if (is_default_enable(new_mode, bitmask)) + goto err_return; + } + + if (is_default_enable(new_mode, bitmask)) { + /* If default mode is already enabled elsewhere in the system */ + if ((rx->bna->rxf_default_id != BFI_MAX_RXF) && + (rx->bna->rxf_default_id != rxf->rxf_id)) { + goto err_return; + } + + /* If promiscuous mode is already enabled in the system */ + if (rx->bna->rxf_promisc_id != BFI_MAX_RXF) + goto err_return; + } + + /* Process the commands */ + + if (is_promisc_enable(new_mode, bitmask)) { + if (rxf_promisc_enable(rxf)) + need_hw_config = 1; + } else if (is_promisc_disable(new_mode, bitmask)) { + if (rxf_promisc_disable(rxf)) + need_hw_config = 1; + } + + if (is_default_enable(new_mode, bitmask)) { + if (rxf_default_enable(rxf)) + need_hw_config = 1; + } else if (is_default_disable(new_mode, bitmask)) { + if (rxf_default_disable(rxf)) + need_hw_config = 1; + } + + if (is_allmulti_enable(new_mode, bitmask)) { + if (rxf_allmulti_enable(rxf)) + need_hw_config = 1; + } else if (is_allmulti_disable(new_mode, bitmask)) { + if (rxf_allmulti_disable(rxf)) + need_hw_config = 1; + } + + /* Trigger h/w if needed */ + + if (need_hw_config) { + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } else if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + + return BNA_CB_SUCCESS; + +err_return: + return BNA_CB_FAIL; +} + +void +/* RxF <- bnad */ +bna_rx_vlanfilter_enable(struct bna_rx *rx) +{ + struct bna_rxf *rxf = &rx->rxf; + + if (rxf->vlan_filter_status == BNA_STATUS_T_DISABLED) { + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + rxf->vlan_filter_status = BNA_STATUS_T_ENABLED; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } +} + +/* Rx */ + +/* Rx <- bnad */ +void +bna_rx_coalescing_timeo_set(struct bna_rx *rx, int coalescing_timeo) +{ + struct bna_rxp *rxp; + struct list_head *qe; + + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + rxp->cq.ccb->rx_coalescing_timeo = coalescing_timeo; + bna_ib_coalescing_timeo_set(rxp->cq.ib, coalescing_timeo); + } +} + +/* Rx <- bnad */ +void +bna_rx_dim_reconfig(struct bna *bna, const u32 vector[][BNA_BIAS_T_MAX]) +{ + int i, j; + + for (i = 0; i < BNA_LOAD_T_MAX; i++) + for (j = 0; j < BNA_BIAS_T_MAX; j++) + bna->rx_mod.dim_vector[i][j] = vector[i][j]; +} + +/* Rx <- bnad */ +void +bna_rx_dim_update(struct bna_ccb *ccb) +{ + struct bna *bna = ccb->cq->rx->bna; + u32 load, bias; + u32 pkt_rt, small_rt, large_rt; + u8 coalescing_timeo; + + if ((ccb->pkt_rate.small_pkt_cnt == 0) && + (ccb->pkt_rate.large_pkt_cnt == 0)) + return; + + /* Arrive at preconfigured coalescing timeo value based on pkt rate */ + + small_rt = ccb->pkt_rate.small_pkt_cnt; + large_rt = ccb->pkt_rate.large_pkt_cnt; + + pkt_rt = small_rt + large_rt; + + if (pkt_rt < BNA_PKT_RATE_10K) + load = BNA_LOAD_T_LOW_4; + else if (pkt_rt < BNA_PKT_RATE_20K) + load = BNA_LOAD_T_LOW_3; + else if (pkt_rt < BNA_PKT_RATE_30K) + load = BNA_LOAD_T_LOW_2; + else if (pkt_rt < BNA_PKT_RATE_40K) + load = BNA_LOAD_T_LOW_1; + else if (pkt_rt < BNA_PKT_RATE_50K) + load = BNA_LOAD_T_HIGH_1; + else if (pkt_rt < BNA_PKT_RATE_60K) + load = BNA_LOAD_T_HIGH_2; + else if (pkt_rt < BNA_PKT_RATE_80K) + load = BNA_LOAD_T_HIGH_3; + else + load = BNA_LOAD_T_HIGH_4; + + if (small_rt > (large_rt << 1)) + bias = 0; + else + bias = 1; + + ccb->pkt_rate.small_pkt_cnt = 0; + ccb->pkt_rate.large_pkt_cnt = 0; + + coalescing_timeo = bna->rx_mod.dim_vector[load][bias]; + ccb->rx_coalescing_timeo = coalescing_timeo; + + /* Set it to IB */ + bna_ib_coalescing_timeo_set(ccb->cq->ib, coalescing_timeo); +} + +/* Tx */ +/* TX <- bnad */ +void +bna_tx_coalescing_timeo_set(struct bna_tx *tx, int coalescing_timeo) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_coalescing_timeo_set(txq->ib, coalescing_timeo); + } +} + +/* + * Private data + */ + +struct bna_ritseg_pool_cfg { + u32 pool_size; + u32 pool_entry_size; +}; +init_ritseg_pool(ritseg_pool_cfg); + +/* + * Private functions + */ +static void +bna_ucam_mod_init(struct bna_ucam_mod *ucam_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int i; + + ucam_mod->ucmac = (struct bna_mac *) + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mdl[0].kva; + + INIT_LIST_HEAD(&ucam_mod->free_q); + for (i = 0; i < BFI_MAX_UCMAC; i++) { + bfa_q_qe_init(&ucam_mod->ucmac[i].qe); + list_add_tail(&ucam_mod->ucmac[i].qe, &ucam_mod->free_q); + } + + ucam_mod->bna = bna; +} + +static void +bna_ucam_mod_uninit(struct bna_ucam_mod *ucam_mod) +{ + struct list_head *qe; + int i = 0; + + list_for_each(qe, &ucam_mod->free_q) + i++; + + ucam_mod->bna = NULL; +} + +static void +bna_mcam_mod_init(struct bna_mcam_mod *mcam_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int i; + + mcam_mod->mcmac = (struct bna_mac *) + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mdl[0].kva; + + INIT_LIST_HEAD(&mcam_mod->free_q); + for (i = 0; i < BFI_MAX_MCMAC; i++) { + bfa_q_qe_init(&mcam_mod->mcmac[i].qe); + list_add_tail(&mcam_mod->mcmac[i].qe, &mcam_mod->free_q); + } + + mcam_mod->bna = bna; +} + +static void +bna_mcam_mod_uninit(struct bna_mcam_mod *mcam_mod) +{ + struct list_head *qe; + int i = 0; + + list_for_each(qe, &mcam_mod->free_q) + i++; + + mcam_mod->bna = NULL; +} + +static void +bna_rit_mod_init(struct bna_rit_mod *rit_mod, + struct bna_res_info *res_info) +{ + int i; + int j; + int count; + int offset; + + rit_mod->rit = (struct bna_rit_entry *) + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mdl[0].kva; + rit_mod->rit_segment = (struct bna_rit_segment *) + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mdl[0].kva; + + count = 0; + offset = 0; + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + INIT_LIST_HEAD(&rit_mod->rit_seg_pool[i]); + for (j = 0; j < ritseg_pool_cfg[i].pool_size; j++) { + bfa_q_qe_init(&rit_mod->rit_segment[count].qe); + rit_mod->rit_segment[count].max_rit_size = + ritseg_pool_cfg[i].pool_entry_size; + rit_mod->rit_segment[count].rit_offset = offset; + rit_mod->rit_segment[count].rit = + &rit_mod->rit[offset]; + list_add_tail(&rit_mod->rit_segment[count].qe, + &rit_mod->rit_seg_pool[i]); + count++; + offset += ritseg_pool_cfg[i].pool_entry_size; + } + } +} + +static void +bna_rit_mod_uninit(struct bna_rit_mod *rit_mod) +{ + struct bna_rit_segment *rit_segment; + struct list_head *qe; + int i; + int j; + + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + j = 0; + list_for_each(qe, &rit_mod->rit_seg_pool[i]) { + rit_segment = (struct bna_rit_segment *)qe; + j++; + } + } +} + +/* + * Public functions + */ + +/* Called during probe(), before calling bna_init() */ +void +bna_res_req(struct bna_res_info *res_info) +{ + bna_adv_res_req(res_info); + + /* DMA memory for retrieving IOC attributes */ + res_info[BNA_RES_MEM_T_ATTR].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.mem_type = BNA_MEM_T_DMA; + res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_ATTR].res_u.mem_info.len = + ALIGN(bfa_nw_ioc_meminfo(), PAGE_SIZE); + + /* DMA memory for index segment of an IB */ + res_info[BNA_RES_MEM_T_IBIDX].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mem_type = BNA_MEM_T_DMA; + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.len = + BFI_IBIDX_SIZE * BFI_IBIDX_MAX_SEGSIZE; + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.num = BFI_MAX_IB; + + /* Virtual memory for IB objects - stored by IB module */ + res_info[BNA_RES_MEM_T_IB_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.len = + BFI_MAX_IB * sizeof(struct bna_ib); + + /* Virtual memory for intr objects - stored by IB module */ + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.len = + BFI_MAX_IB * sizeof(struct bna_intr); + + /* Virtual memory for idx_seg objects - stored by IB module */ + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.len = + BFI_IBIDX_TOTAL_SEGS * sizeof(struct bna_ibidx_seg); + + /* Virtual memory for Tx objects - stored by Tx module */ + res_info[BNA_RES_MEM_T_TX_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.len = + BFI_MAX_TXQ * sizeof(struct bna_tx); + + /* Virtual memory for TxQ - stored by Tx module */ + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.len = + BFI_MAX_TXQ * sizeof(struct bna_txq); + + /* Virtual memory for Rx objects - stored by Rx module */ + res_info[BNA_RES_MEM_T_RX_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.len = + BFI_MAX_RXQ * sizeof(struct bna_rx); + + /* Virtual memory for RxPath - stored by Rx module */ + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.len = + BFI_MAX_RXQ * sizeof(struct bna_rxp); + + /* Virtual memory for RxQ - stored by Rx module */ + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.len = + BFI_MAX_RXQ * sizeof(struct bna_rxq); + + /* Virtual memory for Unicast MAC address - stored by ucam module */ + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_UCMAC_ARRAY].res_u.mem_info.len = + BFI_MAX_UCMAC * sizeof(struct bna_mac); + + /* Virtual memory for Multicast MAC address - stored by mcam module */ + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_MCMAC_ARRAY].res_u.mem_info.len = + BFI_MAX_MCMAC * sizeof(struct bna_mac); + + /* Virtual memory for RIT entries */ + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RIT_ENTRY].res_u.mem_info.len = + BFI_MAX_RIT_SIZE * sizeof(struct bna_rit_entry); + + /* Virtual memory for RIT segment table */ + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_type = BNA_RES_T_MEM; + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.mem_type = + BNA_MEM_T_KVA; + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.num = 1; + res_info[BNA_RES_MEM_T_RIT_SEGMENT].res_u.mem_info.len = + BFI_RIT_TOTAL_SEGS * sizeof(struct bna_rit_segment); + + /* Interrupt resource for mailbox interrupt */ + res_info[BNA_RES_INTR_T_MBOX].res_type = BNA_RES_T_INTR; + res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.intr_type = + BNA_INTR_T_MSIX; + res_info[BNA_RES_INTR_T_MBOX].res_u.intr_info.num = 1; +} + +/* Called during probe() */ +void +bna_init(struct bna *bna, struct bnad *bnad, struct bfa_pcidev *pcidev, + struct bna_res_info *res_info) +{ + bna->bnad = bnad; + bna->pcidev = *pcidev; + + bna->stats.hw_stats = (struct bfi_ll_stats *) + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].kva; + bna->hw_stats_dma.msb = + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.msb; + bna->hw_stats_dma.lsb = + res_info[BNA_RES_MEM_T_STATS].res_u.mem_info.mdl[0].dma.lsb; + bna->stats.sw_stats = (struct bna_sw_stats *) + res_info[BNA_RES_MEM_T_SWSTATS].res_u.mem_info.mdl[0].kva; + + bna->regs.page_addr = bna->pcidev.pci_bar_kva + + reg_offset[bna->pcidev.pci_func].page_addr; + bna->regs.fn_int_status = bna->pcidev.pci_bar_kva + + reg_offset[bna->pcidev.pci_func].fn_int_status; + bna->regs.fn_int_mask = bna->pcidev.pci_bar_kva + + reg_offset[bna->pcidev.pci_func].fn_int_mask; + + if (bna->pcidev.pci_func < 3) + bna->port_num = 0; + else + bna->port_num = 1; + + /* Also initializes diag, cee, sfp, phy_port and mbox_mod */ + bna_device_init(&bna->device, bna, res_info); + + bna_port_init(&bna->port, bna); + + bna_tx_mod_init(&bna->tx_mod, bna, res_info); + + bna_rx_mod_init(&bna->rx_mod, bna, res_info); + + bna_ib_mod_init(&bna->ib_mod, bna, res_info); + + bna_rit_mod_init(&bna->rit_mod, res_info); + + bna_ucam_mod_init(&bna->ucam_mod, bna, res_info); + + bna_mcam_mod_init(&bna->mcam_mod, bna, res_info); + + bna->rxf_default_id = BFI_MAX_RXF; + bna->rxf_promisc_id = BFI_MAX_RXF; + + /* Mbox q element for posting stat request to f/w */ + bfa_q_qe_init(&bna->mbox_qe.qe); +} + +void +bna_uninit(struct bna *bna) +{ + bna_mcam_mod_uninit(&bna->mcam_mod); + + bna_ucam_mod_uninit(&bna->ucam_mod); + + bna_rit_mod_uninit(&bna->rit_mod); + + bna_ib_mod_uninit(&bna->ib_mod); + + bna_rx_mod_uninit(&bna->rx_mod); + + bna_tx_mod_uninit(&bna->tx_mod); + + bna_port_uninit(&bna->port); + + bna_device_uninit(&bna->device); + + bna->bnad = NULL; +} + +struct bna_mac * +bna_ucam_mod_mac_get(struct bna_ucam_mod *ucam_mod) +{ + struct list_head *qe; + + if (list_empty(&ucam_mod->free_q)) + return NULL; + + bfa_q_deq(&ucam_mod->free_q, &qe); + + return (struct bna_mac *)qe; +} + +void +bna_ucam_mod_mac_put(struct bna_ucam_mod *ucam_mod, struct bna_mac *mac) +{ + list_add_tail(&mac->qe, &ucam_mod->free_q); +} + +struct bna_mac * +bna_mcam_mod_mac_get(struct bna_mcam_mod *mcam_mod) +{ + struct list_head *qe; + + if (list_empty(&mcam_mod->free_q)) + return NULL; + + bfa_q_deq(&mcam_mod->free_q, &qe); + + return (struct bna_mac *)qe; +} + +void +bna_mcam_mod_mac_put(struct bna_mcam_mod *mcam_mod, struct bna_mac *mac) +{ + list_add_tail(&mac->qe, &mcam_mod->free_q); +} + +/** + * Note: This should be called in the same locking context as the call to + * bna_rit_mod_seg_get() + */ +int +bna_rit_mod_can_satisfy(struct bna_rit_mod *rit_mod, int seg_size) +{ + int i; + + /* Select the pool for seg_size */ + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + if (seg_size <= ritseg_pool_cfg[i].pool_entry_size) + break; + } + + if (i == BFI_RIT_SEG_TOTAL_POOLS) + return 0; + + if (list_empty(&rit_mod->rit_seg_pool[i])) + return 0; + + return 1; +} + +struct bna_rit_segment * +bna_rit_mod_seg_get(struct bna_rit_mod *rit_mod, int seg_size) +{ + struct bna_rit_segment *seg; + struct list_head *qe; + int i; + + /* Select the pool for seg_size */ + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + if (seg_size <= ritseg_pool_cfg[i].pool_entry_size) + break; + } + + if (i == BFI_RIT_SEG_TOTAL_POOLS) + return NULL; + + if (list_empty(&rit_mod->rit_seg_pool[i])) + return NULL; + + bfa_q_deq(&rit_mod->rit_seg_pool[i], &qe); + seg = (struct bna_rit_segment *)qe; + bfa_q_qe_init(&seg->qe); + seg->rit_size = seg_size; + + return seg; +} + +void +bna_rit_mod_seg_put(struct bna_rit_mod *rit_mod, + struct bna_rit_segment *seg) +{ + int i; + + /* Select the pool for seg->max_rit_size */ + for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) { + if (seg->max_rit_size == ritseg_pool_cfg[i].pool_entry_size) + break; + } + + seg->rit_size = 0; + list_add_tail(&seg->qe, &rit_mod->rit_seg_pool[i]); +} diff --git a/drivers/net/bna/bna_hw.h b/drivers/net/bna/bna_hw.h new file mode 100644 index 0000000000000000000000000000000000000000..806b224a4c63fcfaa9c5660581664f4317c11809 --- /dev/null +++ b/drivers/net/bna/bna_hw.h @@ -0,0 +1,1490 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + * + * File for interrupt macros and functions + */ + +#ifndef __BNA_HW_H__ +#define __BNA_HW_H__ + +#include "bfi_ctreg.h" + +/** + * + * SW imposed limits + * + */ + +#ifndef BNA_BIOS_BUILD + +#define BFI_MAX_TXQ 64 +#define BFI_MAX_RXQ 64 +#define BFI_MAX_RXF 64 +#define BFI_MAX_IB 128 +#define BFI_MAX_RIT_SIZE 256 +#define BFI_RSS_RIT_SIZE 64 +#define BFI_NONRSS_RIT_SIZE 1 +#define BFI_MAX_UCMAC 256 +#define BFI_MAX_MCMAC 512 +#define BFI_IBIDX_SIZE 4 +#define BFI_MAX_VLAN 4095 + +/** + * There are 2 free IB index pools: + * pool1: 120 segments of 1 index each + * pool8: 1 segment of 8 indexes + */ +#define BFI_IBIDX_POOL1_SIZE 116 +#define BFI_IBIDX_POOL1_ENTRY_SIZE 1 +#define BFI_IBIDX_POOL2_SIZE 2 +#define BFI_IBIDX_POOL2_ENTRY_SIZE 2 +#define BFI_IBIDX_POOL8_SIZE 1 +#define BFI_IBIDX_POOL8_ENTRY_SIZE 8 +#define BFI_IBIDX_TOTAL_POOLS 3 +#define BFI_IBIDX_TOTAL_SEGS 119 /* (POOL1 + POOL2 + POOL8)_SIZE */ +#define BFI_IBIDX_MAX_SEGSIZE 8 +#define init_ibidx_pool(name) \ +static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] = \ +{ \ + { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE }, \ + { BFI_IBIDX_POOL2_SIZE, BFI_IBIDX_POOL2_ENTRY_SIZE }, \ + { BFI_IBIDX_POOL8_SIZE, BFI_IBIDX_POOL8_ENTRY_SIZE } \ +} + +/** + * There are 2 free RIT segment pools: + * Pool1: 192 segments of 1 RIT entry each + * Pool2: 1 segment of 64 RIT entry + */ +#define BFI_RIT_SEG_POOL1_SIZE 192 +#define BFI_RIT_SEG_POOL1_ENTRY_SIZE 1 +#define BFI_RIT_SEG_POOLRSS_SIZE 1 +#define BFI_RIT_SEG_POOLRSS_ENTRY_SIZE 64 +#define BFI_RIT_SEG_TOTAL_POOLS 2 +#define BFI_RIT_TOTAL_SEGS 193 /* POOL1_SIZE + POOLRSS_SIZE */ +#define init_ritseg_pool(name) \ +static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \ +{ \ + { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE }, \ + { BFI_RIT_SEG_POOLRSS_SIZE, BFI_RIT_SEG_POOLRSS_ENTRY_SIZE } \ +} + +#else /* BNA_BIOS_BUILD */ + +#define BFI_MAX_TXQ 1 +#define BFI_MAX_RXQ 1 +#define BFI_MAX_RXF 1 +#define BFI_MAX_IB 2 +#define BFI_MAX_RIT_SIZE 2 +#define BFI_RSS_RIT_SIZE 64 +#define BFI_NONRSS_RIT_SIZE 1 +#define BFI_MAX_UCMAC 1 +#define BFI_MAX_MCMAC 8 +#define BFI_IBIDX_SIZE 4 +#define BFI_MAX_VLAN 4095 +/* There is one free pool: 2 segments of 1 index each */ +#define BFI_IBIDX_POOL1_SIZE 2 +#define BFI_IBIDX_POOL1_ENTRY_SIZE 1 +#define BFI_IBIDX_TOTAL_POOLS 1 +#define BFI_IBIDX_TOTAL_SEGS 2 /* POOL1_SIZE */ +#define BFI_IBIDX_MAX_SEGSIZE 1 +#define init_ibidx_pool(name) \ +static struct bna_ibidx_pool name[BFI_IBIDX_TOTAL_POOLS] = \ +{ \ + { BFI_IBIDX_POOL1_SIZE, BFI_IBIDX_POOL1_ENTRY_SIZE } \ +} + +#define BFI_RIT_SEG_POOL1_SIZE 1 +#define BFI_RIT_SEG_POOL1_ENTRY_SIZE 1 +#define BFI_RIT_SEG_TOTAL_POOLS 1 +#define BFI_RIT_TOTAL_SEGS 1 /* POOL1_SIZE */ +#define init_ritseg_pool(name) \ +static struct bna_ritseg_pool_cfg name[BFI_RIT_SEG_TOTAL_POOLS] = \ +{ \ + { BFI_RIT_SEG_POOL1_SIZE, BFI_RIT_SEG_POOL1_ENTRY_SIZE } \ +} + +#endif /* BNA_BIOS_BUILD */ + +#define BFI_RSS_HASH_KEY_LEN 10 + +#define BFI_COALESCING_TIMER_UNIT 5 /* 5us */ +#define BFI_MAX_COALESCING_TIMEO 0xFF /* in 5us units */ +#define BFI_MAX_INTERPKT_COUNT 0xFF +#define BFI_MAX_INTERPKT_TIMEO 0xF /* in 0.5us units */ +#define BFI_TX_COALESCING_TIMEO 20 /* 20 * 5 = 100us */ +#define BFI_TX_INTERPKT_COUNT 32 +#define BFI_RX_COALESCING_TIMEO 12 /* 12 * 5 = 60us */ +#define BFI_RX_INTERPKT_COUNT 6 /* Pkt Cnt = 6 */ +#define BFI_RX_INTERPKT_TIMEO 3 /* 3 * 0.5 = 1.5us */ + +#define BFI_TXQ_WI_SIZE 64 /* bytes */ +#define BFI_RXQ_WI_SIZE 8 /* bytes */ +#define BFI_CQ_WI_SIZE 16 /* bytes */ +#define BFI_TX_MAX_WRR_QUOTA 0xFFF + +#define BFI_TX_MAX_VECTORS_PER_WI 4 +#define BFI_TX_MAX_VECTORS_PER_PKT 0xFF +#define BFI_TX_MAX_DATA_PER_VECTOR 0xFFFF +#define BFI_TX_MAX_DATA_PER_PKT 0xFFFFFF + +/* Small Q buffer size */ +#define BFI_SMALL_RXBUF_SIZE 128 + +/* Defined separately since BFA_FLASH_DMA_BUF_SZ is in bfa_flash.c */ +#define BFI_FLASH_DMA_BUF_SZ 0x010000 /* 64K DMA */ +#define BFI_HW_STATS_SIZE 0x4000 /* 16K DMA */ + +/** + * + * HW register offsets, macros + * + */ + +/* DMA Block Register Host Window Start Address */ +#define DMA_BLK_REG_ADDR 0x00013000 + +/* DMA Block Internal Registers */ +#define DMA_CTRL_REG0 (DMA_BLK_REG_ADDR + 0x000) +#define DMA_CTRL_REG1 (DMA_BLK_REG_ADDR + 0x004) +#define DMA_ERR_INT_STATUS (DMA_BLK_REG_ADDR + 0x008) +#define DMA_ERR_INT_ENABLE (DMA_BLK_REG_ADDR + 0x00c) +#define DMA_ERR_INT_STATUS_SET (DMA_BLK_REG_ADDR + 0x010) + +/* APP Block Register Address Offset from BAR0 */ +#define APP_BLK_REG_ADDR 0x00014000 + +/* Host Function Interrupt Mask Registers */ +#define HOSTFN0_INT_MASK (APP_BLK_REG_ADDR + 0x004) +#define HOSTFN1_INT_MASK (APP_BLK_REG_ADDR + 0x104) +#define HOSTFN2_INT_MASK (APP_BLK_REG_ADDR + 0x304) +#define HOSTFN3_INT_MASK (APP_BLK_REG_ADDR + 0x404) + +/** + * Host Function PCIe Error Registers + * Duplicates "Correctable" & "Uncorrectable" + * registers in PCIe Config space. + */ +#define FN0_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x014) +#define FN1_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x114) +#define FN2_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x314) +#define FN3_PCIE_ERR_REG (APP_BLK_REG_ADDR + 0x414) + +/* Host Function Error Type Status Registers */ +#define FN0_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x018) +#define FN1_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x118) +#define FN2_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x318) +#define FN3_ERR_TYPE_STATUS_REG (APP_BLK_REG_ADDR + 0x418) + +/* Host Function Error Type Mask Registers */ +#define FN0_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x01c) +#define FN1_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x11c) +#define FN2_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x31c) +#define FN3_ERR_TYPE_MSK_STATUS_REG (APP_BLK_REG_ADDR + 0x41c) + +/* Catapult Host Semaphore Status Registers (App block) */ +#define HOST_SEM_STS0_REG (APP_BLK_REG_ADDR + 0x630) +#define HOST_SEM_STS1_REG (APP_BLK_REG_ADDR + 0x634) +#define HOST_SEM_STS2_REG (APP_BLK_REG_ADDR + 0x638) +#define HOST_SEM_STS3_REG (APP_BLK_REG_ADDR + 0x63c) +#define HOST_SEM_STS4_REG (APP_BLK_REG_ADDR + 0x640) +#define HOST_SEM_STS5_REG (APP_BLK_REG_ADDR + 0x644) +#define HOST_SEM_STS6_REG (APP_BLK_REG_ADDR + 0x648) +#define HOST_SEM_STS7_REG (APP_BLK_REG_ADDR + 0x64c) + +/* PCIe Misc Register */ +#define PCIE_MISC_REG (APP_BLK_REG_ADDR + 0x200) + +/* Temp Sensor Control Registers */ +#define TEMPSENSE_CNTL_REG (APP_BLK_REG_ADDR + 0x250) +#define TEMPSENSE_STAT_REG (APP_BLK_REG_ADDR + 0x254) + +/* APP Block local error registers */ +#define APP_LOCAL_ERR_STAT (APP_BLK_REG_ADDR + 0x258) +#define APP_LOCAL_ERR_MSK (APP_BLK_REG_ADDR + 0x25c) + +/* PCIe Link Error registers */ +#define PCIE_LNK_ERR_STAT (APP_BLK_REG_ADDR + 0x260) +#define PCIE_LNK_ERR_MSK (APP_BLK_REG_ADDR + 0x264) + +/** + * FCoE/FIP Ethertype Register + * 31:16 -- Chip wide value for FIP type + * 15:0 -- Chip wide value for FCoE type + */ +#define FCOE_FIP_ETH_TYPE (APP_BLK_REG_ADDR + 0x280) + +/** + * Reserved Ethertype Register + * 31:16 -- Reserved + * 15:0 -- Other ethertype + */ +#define RESV_ETH_TYPE (APP_BLK_REG_ADDR + 0x284) + +/** + * Host Command Status Registers + * Each set consists of 3 registers : + * clear, set, cmd + * 16 such register sets in all + * See catapult_spec.pdf for detailed functionality + * Put each type in a single macro accessed by _num ? + */ +#define HOST_CMDSTS0_CLR_REG (APP_BLK_REG_ADDR + 0x500) +#define HOST_CMDSTS0_SET_REG (APP_BLK_REG_ADDR + 0x504) +#define HOST_CMDSTS0_REG (APP_BLK_REG_ADDR + 0x508) +#define HOST_CMDSTS1_CLR_REG (APP_BLK_REG_ADDR + 0x510) +#define HOST_CMDSTS1_SET_REG (APP_BLK_REG_ADDR + 0x514) +#define HOST_CMDSTS1_REG (APP_BLK_REG_ADDR + 0x518) +#define HOST_CMDSTS2_CLR_REG (APP_BLK_REG_ADDR + 0x520) +#define HOST_CMDSTS2_SET_REG (APP_BLK_REG_ADDR + 0x524) +#define HOST_CMDSTS2_REG (APP_BLK_REG_ADDR + 0x528) +#define HOST_CMDSTS3_CLR_REG (APP_BLK_REG_ADDR + 0x530) +#define HOST_CMDSTS3_SET_REG (APP_BLK_REG_ADDR + 0x534) +#define HOST_CMDSTS3_REG (APP_BLK_REG_ADDR + 0x538) +#define HOST_CMDSTS4_CLR_REG (APP_BLK_REG_ADDR + 0x540) +#define HOST_CMDSTS4_SET_REG (APP_BLK_REG_ADDR + 0x544) +#define HOST_CMDSTS4_REG (APP_BLK_REG_ADDR + 0x548) +#define HOST_CMDSTS5_CLR_REG (APP_BLK_REG_ADDR + 0x550) +#define HOST_CMDSTS5_SET_REG (APP_BLK_REG_ADDR + 0x554) +#define HOST_CMDSTS5_REG (APP_BLK_REG_ADDR + 0x558) +#define HOST_CMDSTS6_CLR_REG (APP_BLK_REG_ADDR + 0x560) +#define HOST_CMDSTS6_SET_REG (APP_BLK_REG_ADDR + 0x564) +#define HOST_CMDSTS6_REG (APP_BLK_REG_ADDR + 0x568) +#define HOST_CMDSTS7_CLR_REG (APP_BLK_REG_ADDR + 0x570) +#define HOST_CMDSTS7_SET_REG (APP_BLK_REG_ADDR + 0x574) +#define HOST_CMDSTS7_REG (APP_BLK_REG_ADDR + 0x578) +#define HOST_CMDSTS8_CLR_REG (APP_BLK_REG_ADDR + 0x580) +#define HOST_CMDSTS8_SET_REG (APP_BLK_REG_ADDR + 0x584) +#define HOST_CMDSTS8_REG (APP_BLK_REG_ADDR + 0x588) +#define HOST_CMDSTS9_CLR_REG (APP_BLK_REG_ADDR + 0x590) +#define HOST_CMDSTS9_SET_REG (APP_BLK_REG_ADDR + 0x594) +#define HOST_CMDSTS9_REG (APP_BLK_REG_ADDR + 0x598) +#define HOST_CMDSTS10_CLR_REG (APP_BLK_REG_ADDR + 0x5A0) +#define HOST_CMDSTS10_SET_REG (APP_BLK_REG_ADDR + 0x5A4) +#define HOST_CMDSTS10_REG (APP_BLK_REG_ADDR + 0x5A8) +#define HOST_CMDSTS11_CLR_REG (APP_BLK_REG_ADDR + 0x5B0) +#define HOST_CMDSTS11_SET_REG (APP_BLK_REG_ADDR + 0x5B4) +#define HOST_CMDSTS11_REG (APP_BLK_REG_ADDR + 0x5B8) +#define HOST_CMDSTS12_CLR_REG (APP_BLK_REG_ADDR + 0x5C0) +#define HOST_CMDSTS12_SET_REG (APP_BLK_REG_ADDR + 0x5C4) +#define HOST_CMDSTS12_REG (APP_BLK_REG_ADDR + 0x5C8) +#define HOST_CMDSTS13_CLR_REG (APP_BLK_REG_ADDR + 0x5D0) +#define HOST_CMDSTS13_SET_REG (APP_BLK_REG_ADDR + 0x5D4) +#define HOST_CMDSTS13_REG (APP_BLK_REG_ADDR + 0x5D8) +#define HOST_CMDSTS14_CLR_REG (APP_BLK_REG_ADDR + 0x5E0) +#define HOST_CMDSTS14_SET_REG (APP_BLK_REG_ADDR + 0x5E4) +#define HOST_CMDSTS14_REG (APP_BLK_REG_ADDR + 0x5E8) +#define HOST_CMDSTS15_CLR_REG (APP_BLK_REG_ADDR + 0x5F0) +#define HOST_CMDSTS15_SET_REG (APP_BLK_REG_ADDR + 0x5F4) +#define HOST_CMDSTS15_REG (APP_BLK_REG_ADDR + 0x5F8) + +/** + * LPU0 Block Register Address Offset from BAR0 + * Range 0x18000 - 0x18033 + */ +#define LPU0_BLK_REG_ADDR 0x00018000 + +/** + * LPU0 Registers + * Should they be directly used from host, + * except for diagnostics ? + * CTL_REG : Control register + * CMD_REG : Triggers exec. of cmd. in + * Mailbox memory + */ +#define LPU0_MBOX_CTL_REG (LPU0_BLK_REG_ADDR + 0x000) +#define LPU0_MBOX_CMD_REG (LPU0_BLK_REG_ADDR + 0x004) +#define LPU0_MBOX_LINK_0REG (LPU0_BLK_REG_ADDR + 0x008) +#define LPU1_MBOX_LINK_0REG (LPU0_BLK_REG_ADDR + 0x00c) +#define LPU0_MBOX_STATUS_0REG (LPU0_BLK_REG_ADDR + 0x010) +#define LPU1_MBOX_STATUS_0REG (LPU0_BLK_REG_ADDR + 0x014) +#define LPU0_ERR_STATUS_REG (LPU0_BLK_REG_ADDR + 0x018) +#define LPU0_ERR_SET_REG (LPU0_BLK_REG_ADDR + 0x020) + +/** + * LPU1 Block Register Address Offset from BAR0 + * Range 0x18400 - 0x18433 + */ +#define LPU1_BLK_REG_ADDR 0x00018400 + +/** + * LPU1 Registers + * Same as LPU0 registers above + */ +#define LPU1_MBOX_CTL_REG (LPU1_BLK_REG_ADDR + 0x000) +#define LPU1_MBOX_CMD_REG (LPU1_BLK_REG_ADDR + 0x004) +#define LPU0_MBOX_LINK_1REG (LPU1_BLK_REG_ADDR + 0x008) +#define LPU1_MBOX_LINK_1REG (LPU1_BLK_REG_ADDR + 0x00c) +#define LPU0_MBOX_STATUS_1REG (LPU1_BLK_REG_ADDR + 0x010) +#define LPU1_MBOX_STATUS_1REG (LPU1_BLK_REG_ADDR + 0x014) +#define LPU1_ERR_STATUS_REG (LPU1_BLK_REG_ADDR + 0x018) +#define LPU1_ERR_SET_REG (LPU1_BLK_REG_ADDR + 0x020) + +/** + * PSS Block Register Address Offset from BAR0 + * Range 0x18800 - 0x188DB + */ +#define PSS_BLK_REG_ADDR 0x00018800 + +/** + * PSS Registers + * For details, see catapult_spec.pdf + * ERR_STATUS_REG : Indicates error in PSS module + * RAM_ERR_STATUS_REG : Indicates RAM module that detected error + */ +#define ERR_STATUS_SET (PSS_BLK_REG_ADDR + 0x018) +#define PSS_RAM_ERR_STATUS_REG (PSS_BLK_REG_ADDR + 0x01C) + +/** + * PSS Semaphore Lock Registers, total 16 + * First read when unlocked returns 0, + * and is set to 1, atomically. + * Subsequent reads returns 1. + * To clear set the value to 0. + * Range : 0x20 to 0x5c + */ +#define PSS_SEM_LOCK_REG(_num) \ + (PSS_BLK_REG_ADDR + 0x020 + ((_num) << 2)) + +/** + * PSS Semaphore Status Registers, + * corresponding to the lock registers above + */ +#define PSS_SEM_STATUS_REG(_num) \ + (PSS_BLK_REG_ADDR + 0x060 + ((_num) << 2)) + +/** + * Catapult CPQ Registers + * Defines for Mailbox Registers + * Used to send mailbox commands to firmware from + * host. The data part is written to the MBox + * memory, registers are used to indicate that + * a commnad is resident in memory. + * + * Note : LPU0<->LPU1 mailboxes are not listed here + */ +#define CPQ_BLK_REG_ADDR 0x00019000 + +#define HOSTFN0_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x130) +#define HOSTFN0_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x134) +#define LPU0_HOSTFN0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x138) +#define LPU1_HOSTFN0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x13C) + +#define HOSTFN1_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x140) +#define HOSTFN1_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x144) +#define LPU0_HOSTFN1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x148) +#define LPU1_HOSTFN1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x14C) + +#define HOSTFN2_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x170) +#define HOSTFN2_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x174) +#define LPU0_HOSTFN2_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x178) +#define LPU1_HOSTFN2_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x17C) + +#define HOSTFN3_LPU0_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x180) +#define HOSTFN3_LPU1_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x184) +#define LPU0_HOSTFN3_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x188) +#define LPU1_HOSTFN3_MBOX1_CMD_STAT (CPQ_BLK_REG_ADDR + 0x18C) + +/* Host Function Force Parity Error Registers */ +#define HOSTFN0_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x120) +#define HOSTFN1_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x124) +#define HOSTFN2_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x128) +#define HOSTFN3_LPU_FORCE_PERR (CPQ_BLK_REG_ADDR + 0x12C) + +/* LL Port[0|1] Halt Mask Registers */ +#define LL_HALT_MSK_P0 (CPQ_BLK_REG_ADDR + 0x1A0) +#define LL_HALT_MSK_P1 (CPQ_BLK_REG_ADDR + 0x1B0) + +/* LL Port[0|1] Error Mask Registers */ +#define LL_ERR_MSK_P0 (CPQ_BLK_REG_ADDR + 0x1D0) +#define LL_ERR_MSK_P1 (CPQ_BLK_REG_ADDR + 0x1D4) + +/* EMC FLI (Flash Controller) Block Register Address Offset from BAR0 */ +#define FLI_BLK_REG_ADDR 0x0001D000 + +/* EMC FLI Registers */ +#define FLI_CMD_REG (FLI_BLK_REG_ADDR + 0x000) +#define FLI_ADDR_REG (FLI_BLK_REG_ADDR + 0x004) +#define FLI_CTL_REG (FLI_BLK_REG_ADDR + 0x008) +#define FLI_WRDATA_REG (FLI_BLK_REG_ADDR + 0x00C) +#define FLI_RDDATA_REG (FLI_BLK_REG_ADDR + 0x010) +#define FLI_DEV_STATUS_REG (FLI_BLK_REG_ADDR + 0x014) +#define FLI_SIG_WD_REG (FLI_BLK_REG_ADDR + 0x018) + +/** + * RO register + * 31:16 -- Vendor Id + * 15:0 -- Device Id + */ +#define FLI_DEV_VENDOR_REG (FLI_BLK_REG_ADDR + 0x01C) +#define FLI_ERR_STATUS_REG (FLI_BLK_REG_ADDR + 0x020) + +/** + * RAD (RxAdm) Block Register Address Offset from BAR0 + * RAD0 Range : 0x20000 - 0x203FF + * RAD1 Range : 0x20400 - 0x207FF + */ +#define RAD0_BLK_REG_ADDR 0x00020000 +#define RAD1_BLK_REG_ADDR 0x00020400 + +/* RAD0 Registers */ +#define RAD0_CTL_REG (RAD0_BLK_REG_ADDR + 0x000) +#define RAD0_PE_PARM_REG (RAD0_BLK_REG_ADDR + 0x004) +#define RAD0_BCN_REG (RAD0_BLK_REG_ADDR + 0x008) + +/* Default function ID register */ +#define RAD0_DEFAULT_REG (RAD0_BLK_REG_ADDR + 0x00C) + +/* Default promiscuous ID register */ +#define RAD0_PROMISC_REG (RAD0_BLK_REG_ADDR + 0x010) + +#define RAD0_BCNQ_REG (RAD0_BLK_REG_ADDR + 0x014) + +/* + * This register selects 1 of 8 PM Q's using + * VLAN pri, for non-BCN packets without a VLAN tag + */ +#define RAD0_DEFAULTQ_REG (RAD0_BLK_REG_ADDR + 0x018) + +#define RAD0_ERR_STS (RAD0_BLK_REG_ADDR + 0x01C) +#define RAD0_SET_ERR_STS (RAD0_BLK_REG_ADDR + 0x020) +#define RAD0_ERR_INT_EN (RAD0_BLK_REG_ADDR + 0x024) +#define RAD0_FIRST_ERR (RAD0_BLK_REG_ADDR + 0x028) +#define RAD0_FORCE_ERR (RAD0_BLK_REG_ADDR + 0x02C) + +#define RAD0_IF_RCVD (RAD0_BLK_REG_ADDR + 0x030) +#define RAD0_IF_RCVD_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x034) +#define RAD0_IF_RCVD_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x038) +#define RAD0_IF_RCVD_VLAN (RAD0_BLK_REG_ADDR + 0x03C) +#define RAD0_IF_RCVD_UCAST (RAD0_BLK_REG_ADDR + 0x040) +#define RAD0_IF_RCVD_UCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x044) +#define RAD0_IF_RCVD_UCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x048) +#define RAD0_IF_RCVD_UCAST_VLAN (RAD0_BLK_REG_ADDR + 0x04C) +#define RAD0_IF_RCVD_MCAST (RAD0_BLK_REG_ADDR + 0x050) +#define RAD0_IF_RCVD_MCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x054) +#define RAD0_IF_RCVD_MCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x058) +#define RAD0_IF_RCVD_MCAST_VLAN (RAD0_BLK_REG_ADDR + 0x05C) +#define RAD0_IF_RCVD_BCAST (RAD0_BLK_REG_ADDR + 0x060) +#define RAD0_IF_RCVD_BCAST_OCTETS_HIGH (RAD0_BLK_REG_ADDR + 0x064) +#define RAD0_IF_RCVD_BCAST_OCTETS_LOW (RAD0_BLK_REG_ADDR + 0x068) +#define RAD0_IF_RCVD_BCAST_VLAN (RAD0_BLK_REG_ADDR + 0x06C) +#define RAD0_DROPPED_FRAMES (RAD0_BLK_REG_ADDR + 0x070) + +#define RAD0_MAC_MAN_1H (RAD0_BLK_REG_ADDR + 0x080) +#define RAD0_MAC_MAN_1L (RAD0_BLK_REG_ADDR + 0x084) +#define RAD0_MAC_MAN_2H (RAD0_BLK_REG_ADDR + 0x088) +#define RAD0_MAC_MAN_2L (RAD0_BLK_REG_ADDR + 0x08C) +#define RAD0_MAC_MAN_3H (RAD0_BLK_REG_ADDR + 0x090) +#define RAD0_MAC_MAN_3L (RAD0_BLK_REG_ADDR + 0x094) +#define RAD0_MAC_MAN_4H (RAD0_BLK_REG_ADDR + 0x098) +#define RAD0_MAC_MAN_4L (RAD0_BLK_REG_ADDR + 0x09C) + +#define RAD0_LAST4_IP (RAD0_BLK_REG_ADDR + 0x100) + +/* RAD1 Registers */ +#define RAD1_CTL_REG (RAD1_BLK_REG_ADDR + 0x000) +#define RAD1_PE_PARM_REG (RAD1_BLK_REG_ADDR + 0x004) +#define RAD1_BCN_REG (RAD1_BLK_REG_ADDR + 0x008) + +/* Default function ID register */ +#define RAD1_DEFAULT_REG (RAD1_BLK_REG_ADDR + 0x00C) + +/* Promiscuous function ID register */ +#define RAD1_PROMISC_REG (RAD1_BLK_REG_ADDR + 0x010) + +#define RAD1_BCNQ_REG (RAD1_BLK_REG_ADDR + 0x014) + +/* + * This register selects 1 of 8 PM Q's using + * VLAN pri, for non-BCN packets without a VLAN tag + */ +#define RAD1_DEFAULTQ_REG (RAD1_BLK_REG_ADDR + 0x018) + +#define RAD1_ERR_STS (RAD1_BLK_REG_ADDR + 0x01C) +#define RAD1_SET_ERR_STS (RAD1_BLK_REG_ADDR + 0x020) +#define RAD1_ERR_INT_EN (RAD1_BLK_REG_ADDR + 0x024) + +/** + * TXA Block Register Address Offset from BAR0 + * TXA0 Range : 0x21000 - 0x213FF + * TXA1 Range : 0x21400 - 0x217FF + */ +#define TXA0_BLK_REG_ADDR 0x00021000 +#define TXA1_BLK_REG_ADDR 0x00021400 + +/* TXA Registers */ +#define TXA0_CTRL_REG (TXA0_BLK_REG_ADDR + 0x000) +#define TXA1_CTRL_REG (TXA1_BLK_REG_ADDR + 0x000) + +/** + * TSO Sequence # Registers (RO) + * Total 8 (for 8 queues) + * Holds the last seq.# for TSO frames + * See catapult_spec.pdf for more details + */ +#define TXA0_TSO_TCP_SEQ_REG(_num) \ + (TXA0_BLK_REG_ADDR + 0x020 + ((_num) << 2)) + +#define TXA1_TSO_TCP_SEQ_REG(_num) \ + (TXA1_BLK_REG_ADDR + 0x020 + ((_num) << 2)) + +/** + * TSO IP ID # Registers (RO) + * Total 8 (for 8 queues) + * Holds the last IP ID for TSO frames + * See catapult_spec.pdf for more details + */ +#define TXA0_TSO_IP_INFO_REG(_num) \ + (TXA0_BLK_REG_ADDR + 0x040 + ((_num) << 2)) + +#define TXA1_TSO_IP_INFO_REG(_num) \ + (TXA1_BLK_REG_ADDR + 0x040 + ((_num) << 2)) + +/** + * RXA Block Register Address Offset from BAR0 + * RXA0 Range : 0x21800 - 0x21BFF + * RXA1 Range : 0x21C00 - 0x21FFF + */ +#define RXA0_BLK_REG_ADDR 0x00021800 +#define RXA1_BLK_REG_ADDR 0x00021C00 + +/* RXA Registers */ +#define RXA0_CTL_REG (RXA0_BLK_REG_ADDR + 0x040) +#define RXA1_CTL_REG (RXA1_BLK_REG_ADDR + 0x040) + +/** + * PPLB Block Register Address Offset from BAR0 + * PPLB0 Range : 0x22000 - 0x223FF + * PPLB1 Range : 0x22400 - 0x227FF + */ +#define PLB0_BLK_REG_ADDR 0x00022000 +#define PLB1_BLK_REG_ADDR 0x00022400 + +/** + * PLB Registers + * Holds RL timer used time stamps in RLT tagged frames + */ +#define PLB0_ECM_TIMER_REG (PLB0_BLK_REG_ADDR + 0x05C) +#define PLB1_ECM_TIMER_REG (PLB1_BLK_REG_ADDR + 0x05C) + +/* Controls the rate-limiter on each of the priority class */ +#define PLB0_RL_CTL (PLB0_BLK_REG_ADDR + 0x060) +#define PLB1_RL_CTL (PLB1_BLK_REG_ADDR + 0x060) + +/** + * Max byte register, total 8, 0-7 + * see catapult_spec.pdf for details + */ +#define PLB0_RL_MAX_BC(_num) \ + (PLB0_BLK_REG_ADDR + 0x064 + ((_num) << 2)) +#define PLB1_RL_MAX_BC(_num) \ + (PLB1_BLK_REG_ADDR + 0x064 + ((_num) << 2)) + +/** + * RL Time Unit Register for priority 0-7 + * 4 bits per priority + * (2^rl_unit)*1us is the actual time period + */ +#define PLB0_RL_TU_PRIO (PLB0_BLK_REG_ADDR + 0x084) +#define PLB1_RL_TU_PRIO (PLB1_BLK_REG_ADDR + 0x084) + +/** + * RL byte count register, + * bytes transmitted in (rl_unit*1)us time period + * 1 per priority, 8 in all, 0-7. + */ +#define PLB0_RL_BYTE_CNT(_num) \ + (PLB0_BLK_REG_ADDR + 0x088 + ((_num) << 2)) +#define PLB1_RL_BYTE_CNT(_num) \ + (PLB1_BLK_REG_ADDR + 0x088 + ((_num) << 2)) + +/** + * RL Min factor register + * 2 bits per priority, + * 4 factors possible: 1, 0.5, 0.25, 0 + * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1 + */ +#define PLB0_RL_MIN_REG (PLB0_BLK_REG_ADDR + 0x0A8) +#define PLB1_RL_MIN_REG (PLB1_BLK_REG_ADDR + 0x0A8) + +/** + * RL Max factor register + * 2 bits per priority, + * 4 factors possible: 1, 0.5, 0.25, 0 + * 2'b00 - 0; 2'b01 - 0.25; 2'b10 - 0.5; 2'b11 - 1 + */ +#define PLB0_RL_MAX_REG (PLB0_BLK_REG_ADDR + 0x0AC) +#define PLB1_RL_MAX_REG (PLB1_BLK_REG_ADDR + 0x0AC) + +/* MAC SERDES Address Paging register */ +#define PLB0_EMS_ADD_REG (PLB0_BLK_REG_ADDR + 0xD0) +#define PLB1_EMS_ADD_REG (PLB1_BLK_REG_ADDR + 0xD0) + +/* LL EMS Registers */ +#define LL_EMS0_BLK_REG_ADDR 0x00026800 +#define LL_EMS1_BLK_REG_ADDR 0x00026C00 + +/** + * BPC Block Register Address Offset from BAR0 + * BPC0 Range : 0x23000 - 0x233FF + * BPC1 Range : 0x23400 - 0x237FF + */ +#define BPC0_BLK_REG_ADDR 0x00023000 +#define BPC1_BLK_REG_ADDR 0x00023400 + +/** + * PMM Block Register Address Offset from BAR0 + * PMM0 Range : 0x23800 - 0x23BFF + * PMM1 Range : 0x23C00 - 0x23FFF + */ +#define PMM0_BLK_REG_ADDR 0x00023800 +#define PMM1_BLK_REG_ADDR 0x00023C00 + +/** + * HQM Block Register Address Offset from BAR0 + * HQM0 Range : 0x24000 - 0x243FF + * HQM1 Range : 0x24400 - 0x247FF + */ +#define HQM0_BLK_REG_ADDR 0x00024000 +#define HQM1_BLK_REG_ADDR 0x00024400 + +/** + * HQM Control Register + * Controls some aspects of IB + * See catapult_spec.pdf for details + */ +#define HQM0_CTL_REG (HQM0_BLK_REG_ADDR + 0x000) +#define HQM1_CTL_REG (HQM1_BLK_REG_ADDR + 0x000) + +/** + * HQM Stop Q Semaphore Registers. + * Only one Queue resource can be stopped at + * any given time. This register controls access + * to the single stop Q resource. + * See catapult_spec.pdf for details + */ +#define HQM0_RXQ_STOP_SEM (HQM0_BLK_REG_ADDR + 0x028) +#define HQM0_TXQ_STOP_SEM (HQM0_BLK_REG_ADDR + 0x02C) +#define HQM1_RXQ_STOP_SEM (HQM1_BLK_REG_ADDR + 0x028) +#define HQM1_TXQ_STOP_SEM (HQM1_BLK_REG_ADDR + 0x02C) + +/** + * LUT Block Register Address Offset from BAR0 + * LUT0 Range : 0x25800 - 0x25BFF + * LUT1 Range : 0x25C00 - 0x25FFF + */ +#define LUT0_BLK_REG_ADDR 0x00025800 +#define LUT1_BLK_REG_ADDR 0x00025C00 + +/** + * LUT Registers + * See catapult_spec.pdf for details + */ +#define LUT0_ERR_STS (LUT0_BLK_REG_ADDR + 0x000) +#define LUT1_ERR_STS (LUT1_BLK_REG_ADDR + 0x000) +#define LUT0_SET_ERR_STS (LUT0_BLK_REG_ADDR + 0x004) +#define LUT1_SET_ERR_STS (LUT1_BLK_REG_ADDR + 0x004) + +/** + * TRC (Debug/Trace) Register Offset from BAR0 + * Range : 0x26000 -- 0x263FFF + */ +#define TRC_BLK_REG_ADDR 0x00026000 + +/** + * TRC Registers + * See catapult_spec.pdf for details of each + */ +#define TRC_CTL_REG (TRC_BLK_REG_ADDR + 0x000) +#define TRC_MODS_REG (TRC_BLK_REG_ADDR + 0x004) +#define TRC_TRGC_REG (TRC_BLK_REG_ADDR + 0x008) +#define TRC_CNT1_REG (TRC_BLK_REG_ADDR + 0x010) +#define TRC_CNT2_REG (TRC_BLK_REG_ADDR + 0x014) +#define TRC_NXTS_REG (TRC_BLK_REG_ADDR + 0x018) +#define TRC_DIRR_REG (TRC_BLK_REG_ADDR + 0x01C) + +/** + * TRC Trigger match filters, total 10 + * Determines the trigger condition + */ +#define TRC_TRGM_REG(_num) \ + (TRC_BLK_REG_ADDR + 0x040 + ((_num) << 2)) + +/** + * TRC Next State filters, total 10 + * Determines the next state conditions + */ +#define TRC_NXTM_REG(_num) \ + (TRC_BLK_REG_ADDR + 0x080 + ((_num) << 2)) + +/** + * TRC Store Match filters, total 10 + * Determines the store conditions + */ +#define TRC_STRM_REG(_num) \ + (TRC_BLK_REG_ADDR + 0x0C0 + ((_num) << 2)) + +/* DOORBELLS ACCESS */ + +/** + * Catapult doorbells + * Each doorbell-queue set has + * 1 RxQ, 1 TxQ, 2 IBs in that order + * Size of each entry in 32 bytes, even though only 1 word + * is used. For Non-VM case each doorbell-q set is + * separated by 128 bytes, for VM case it is separated + * by 4K bytes + * Non VM case Range : 0x38000 - 0x39FFF + * VM case Range : 0x100000 - 0x11FFFF + * The range applies to both HQMs + */ +#define HQM_DOORBELL_BLK_BASE_ADDR 0x00038000 +#define HQM_DOORBELL_VM_BLK_BASE_ADDR 0x00100000 + +/* MEMORY ACCESS */ + +/** + * Catapult H/W Block Memory Access Address + * To the host a memory space of 32K (page) is visible + * at a time. The address range is from 0x08000 to 0x0FFFF + */ +#define HW_BLK_HOST_MEM_ADDR 0x08000 + +/** + * Catapult LUT Memory Access Page Numbers + * Range : LUT0 0xa0-0xa1 + * LUT1 0xa2-0xa3 + */ +#define LUT0_MEM_BLK_BASE_PG_NUM 0x000000A0 +#define LUT1_MEM_BLK_BASE_PG_NUM 0x000000A2 + +/** + * Catapult RxFn Database Memory Block Base Offset + * + * The Rx function database exists in LUT block. + * In PCIe space this is accessible as a 256x32 + * bit block. Each entry in this database is 4 + * (4 byte) words. Max. entries is 64. + * Address of an entry corresponding to a function + * = base_addr + (function_no. * 16) + */ +#define RX_FNDB_RAM_BASE_OFFSET 0x0000B400 + +/** + * Catapult TxFn Database Memory Block Base Offset Address + * + * The Tx function database exists in LUT block. + * In PCIe space this is accessible as a 64x32 + * bit block. Each entry in this database is 1 + * (4 byte) word. Max. entries is 64. + * Address of an entry corresponding to a function + * = base_addr + (function_no. * 4) + */ +#define TX_FNDB_RAM_BASE_OFFSET 0x0000B800 + +/** + * Catapult Unicast CAM Base Offset Address + * + * Exists in LUT memory space. + * Shared by both the LL & FCoE driver. + * Size is 256x48 bits; mapped to PCIe space + * 512x32 bit blocks. For each address, bits + * are written in the order : [47:32] and then + * [31:0]. + */ +#define UCAST_CAM_BASE_OFFSET 0x0000A800 + +/** + * Catapult Unicast RAM Base Offset Address + * + * Exists in LUT memory space. + * Shared by both the LL & FCoE driver. + * Size is 256x9 bits. + */ +#define UCAST_RAM_BASE_OFFSET 0x0000B000 + +/** + * Catapult Mulicast CAM Base Offset Address + * + * Exists in LUT memory space. + * Shared by both the LL & FCoE driver. + * Size is 256x48 bits; mapped to PCIe space + * 512x32 bit blocks. For each address, bits + * are written in the order : [47:32] and then + * [31:0]. + */ +#define MCAST_CAM_BASE_OFFSET 0x0000A000 + +/** + * Catapult VLAN RAM Base Offset Address + * + * Exists in LUT memory space. + * Size is 4096x66 bits; mapped to PCIe space as + * 8192x32 bit blocks. + * All the 4K entries are within the address range + * 0x0000 to 0x8000, so in the first LUT page. + */ +#define VLAN_RAM_BASE_OFFSET 0x00000000 + +/** + * Catapult Tx Stats RAM Base Offset Address + * + * Exists in LUT memory space. + * Size is 1024x33 bits; + * Each Tx function has 64 bytes of space + */ +#define TX_STATS_RAM_BASE_OFFSET 0x00009000 + +/** + * Catapult Rx Stats RAM Base Offset Address + * + * Exists in LUT memory space. + * Size is 1024x33 bits; + * Each Rx function has 64 bytes of space + */ +#define RX_STATS_RAM_BASE_OFFSET 0x00008000 + +/* Catapult RXA Memory Access Page Numbers */ +#define RXA0_MEM_BLK_BASE_PG_NUM 0x0000008C +#define RXA1_MEM_BLK_BASE_PG_NUM 0x0000008D + +/** + * Catapult Multicast Vector Table Base Offset Address + * + * Exists in RxA memory space. + * Organized as 512x65 bit block. + * However for each entry 16 bytes allocated (power of 2) + * Total size 512*16 bytes. + * There are two logical divisions, 256 entries each : + * a) Entries 0x00 to 0xff (256) -- Approx. MVT + * Offset 0x000 to 0xFFF + * b) Entries 0x100 to 0x1ff (256) -- Exact MVT + * Offsets 0x1000 to 0x1FFF + */ +#define MCAST_APPROX_MVT_BASE_OFFSET 0x00000000 +#define MCAST_EXACT_MVT_BASE_OFFSET 0x00001000 + +/** + * Catapult RxQ Translate Table (RIT) Base Offset Address + * + * Exists in RxA memory space + * Total no. of entries 64 + * Each entry is 1 (4 byte) word. + * 31:12 -- Reserved + * 11:0 -- Two 6 bit RxQ Ids + */ +#define FUNCTION_TO_RXQ_TRANSLATE 0x00002000 + +/* Catapult RxAdm (RAD) Memory Access Page Numbers */ +#define RAD0_MEM_BLK_BASE_PG_NUM 0x00000086 +#define RAD1_MEM_BLK_BASE_PG_NUM 0x00000087 + +/** + * Catapult RSS Table Base Offset Address + * + * Exists in RAD memory space. + * Each entry is 352 bits, but alligned on + * 64 byte (512 bit) boundary. Accessed + * 4 byte words, the whole entry can be + * broken into 11 word accesses. + */ +#define RSS_TABLE_BASE_OFFSET 0x00000800 + +/** + * Catapult CPQ Block Page Number + * This value is written to the page number registers + * to access the memory associated with the mailboxes. + */ +#define CPQ_BLK_PG_NUM 0x00000005 + +/** + * Clarification : + * LL functions are 2 & 3; can HostFn0/HostFn1 + * <-> LPU0/LPU1 memories be used ? + */ +/** + * Catapult HostFn0/HostFn1 to LPU0/LPU1 Mbox memory + * Per catapult_spec.pdf, the offset of the mbox + * memory is in the register space at an offset of 0x200 + */ +#define CPQ_BLK_REG_MBOX_ADDR (CPQ_BLK_REG_ADDR + 0x200) + +#define HOSTFN_LPU_MBOX (CPQ_BLK_REG_MBOX_ADDR + 0x000) + +/* Catapult LPU0/LPU1 to HostFn0/HostFn1 Mbox memory */ +#define LPU_HOSTFN_MBOX (CPQ_BLK_REG_MBOX_ADDR + 0x080) + +/** + * Catapult HQM Block Page Number + * This is written to the page number register for + * the appropriate function to access the memory + * associated with HQM + */ +#define HQM0_BLK_PG_NUM 0x00000096 +#define HQM1_BLK_PG_NUM 0x00000097 + +/** + * Note that TxQ and RxQ entries are interlaced + * the HQM memory, i.e RXQ0, TXQ0, RXQ1, TXQ1.. etc. + */ + +#define HQM_RXTX_Q_RAM_BASE_OFFSET 0x00004000 + +/** + * CQ Memory + * Exists in HQM Memory space + * Each entry is 16 (4 byte) words of which + * only 12 words are used for configuration + * Total 64 entries per HQM memory space + */ +#define HQM_CQ_RAM_BASE_OFFSET 0x00006000 + +/** + * Interrupt Block (IB) Memory + * Exists in HQM Memory space + * Each entry is 8 (4 byte) words of which + * only 5 words are used for configuration + * Total 128 entries per HQM memory space + */ +#define HQM_IB_RAM_BASE_OFFSET 0x00001000 + +/** + * Index Table (IT) Memory + * Exists in HQM Memory space + * Each entry is 1 (4 byte) word which + * is used for configuration + * Total 128 entries per HQM memory space + */ +#define HQM_INDX_TBL_RAM_BASE_OFFSET 0x00002000 + +/** + * PSS Block Memory Page Number + * This is written to the appropriate page number + * register to access the CPU memory. + * Also known as the PSS secondary memory (SMEM). + * Range : 0x180 to 0x1CF + * See catapult_spec.pdf for details + */ +#define PSS_BLK_PG_NUM 0x00000180 + +/** + * Offsets of different instances of PSS SMEM + * 2.5M of continuous 1T memory space : 2 blocks + * of 1M each (32 pages each, page=32KB) and 4 smaller + * blocks of 128K each (4 pages each, page=32KB) + * PSS_LMEM_INST0 is used for firmware download + */ +#define PSS_LMEM_INST0 0x00000000 +#define PSS_LMEM_INST1 0x00100000 +#define PSS_LMEM_INST2 0x00200000 +#define PSS_LMEM_INST3 0x00220000 +#define PSS_LMEM_INST4 0x00240000 +#define PSS_LMEM_INST5 0x00260000 + +#define BNA_PCI_REG_CT_ADDRSZ (0x40000) + +#define BNA_GET_PAGE_NUM(_base_page, _offset) \ + ((_base_page) + ((_offset) >> 15)) + +#define BNA_GET_PAGE_OFFSET(_offset) \ + ((_offset) & 0x7fff) + +#define BNA_GET_MEM_BASE_ADDR(_bar0, _base_offset) \ + ((_bar0) + HW_BLK_HOST_MEM_ADDR \ + + BNA_GET_PAGE_OFFSET((_base_offset))) + +#define BNA_GET_VLAN_MEM_ENTRY_ADDR(_bar0, _fn_id, _vlan_id)\ + (_bar0 + (HW_BLK_HOST_MEM_ADDR) \ + + (BNA_GET_PAGE_OFFSET(VLAN_RAM_BASE_OFFSET)) \ + + (((_fn_id) & 0x3f) << 9) \ + + (((_vlan_id) & 0xfe0) >> 3)) + +/** + * + * Interrupt related bits, flags and macros + * + */ + +#define __LPU02HOST_MBOX0_STATUS_BITS 0x00100000 +#define __LPU12HOST_MBOX0_STATUS_BITS 0x00200000 +#define __LPU02HOST_MBOX1_STATUS_BITS 0x00400000 +#define __LPU12HOST_MBOX1_STATUS_BITS 0x00800000 + +#define __LPU02HOST_MBOX0_MASK_BITS 0x00100000 +#define __LPU12HOST_MBOX0_MASK_BITS 0x00200000 +#define __LPU02HOST_MBOX1_MASK_BITS 0x00400000 +#define __LPU12HOST_MBOX1_MASK_BITS 0x00800000 + +#define __LPU2HOST_MBOX_MASK_BITS \ + (__LPU02HOST_MBOX0_MASK_BITS | __LPU02HOST_MBOX1_MASK_BITS | \ + __LPU12HOST_MBOX0_MASK_BITS | __LPU12HOST_MBOX1_MASK_BITS) + +#define __LPU2HOST_IB_STATUS_BITS 0x0000ffff + +#define BNA_IS_LPU0_MBOX_INTR(_intr_status) \ + ((_intr_status) & (__LPU02HOST_MBOX0_STATUS_BITS | \ + __LPU02HOST_MBOX1_STATUS_BITS)) + +#define BNA_IS_LPU1_MBOX_INTR(_intr_status) \ + ((_intr_status) & (__LPU12HOST_MBOX0_STATUS_BITS | \ + __LPU12HOST_MBOX1_STATUS_BITS)) + +#define BNA_IS_MBOX_INTR(_intr_status) \ + ((_intr_status) & \ + (__LPU02HOST_MBOX0_STATUS_BITS | \ + __LPU02HOST_MBOX1_STATUS_BITS | \ + __LPU12HOST_MBOX0_STATUS_BITS | \ + __LPU12HOST_MBOX1_STATUS_BITS)) + +#define __EMC_ERROR_STATUS_BITS 0x00010000 +#define __LPU0_ERROR_STATUS_BITS 0x00020000 +#define __LPU1_ERROR_STATUS_BITS 0x00040000 +#define __PSS_ERROR_STATUS_BITS 0x00080000 + +#define __HALT_STATUS_BITS 0x01000000 + +#define __EMC_ERROR_MASK_BITS 0x00010000 +#define __LPU0_ERROR_MASK_BITS 0x00020000 +#define __LPU1_ERROR_MASK_BITS 0x00040000 +#define __PSS_ERROR_MASK_BITS 0x00080000 + +#define __HALT_MASK_BITS 0x01000000 + +#define __ERROR_MASK_BITS \ + (__EMC_ERROR_MASK_BITS | __LPU0_ERROR_MASK_BITS | \ + __LPU1_ERROR_MASK_BITS | __PSS_ERROR_MASK_BITS | \ + __HALT_MASK_BITS) + +#define BNA_IS_ERR_INTR(_intr_status) \ + ((_intr_status) & \ + (__EMC_ERROR_STATUS_BITS | \ + __LPU0_ERROR_STATUS_BITS | \ + __LPU1_ERROR_STATUS_BITS | \ + __PSS_ERROR_STATUS_BITS | \ + __HALT_STATUS_BITS)) + +#define BNA_IS_MBOX_ERR_INTR(_intr_status) \ + (BNA_IS_MBOX_INTR((_intr_status)) | \ + BNA_IS_ERR_INTR((_intr_status))) + +#define BNA_IS_INTX_DATA_INTR(_intr_status) \ + ((_intr_status) & __LPU2HOST_IB_STATUS_BITS) + +#define BNA_INTR_STATUS_MBOX_CLR(_intr_status) \ +do { \ + (_intr_status) &= ~(__LPU02HOST_MBOX0_STATUS_BITS | \ + __LPU02HOST_MBOX1_STATUS_BITS | \ + __LPU12HOST_MBOX0_STATUS_BITS | \ + __LPU12HOST_MBOX1_STATUS_BITS); \ +} while (0) + +#define BNA_INTR_STATUS_ERR_CLR(_intr_status) \ +do { \ + (_intr_status) &= ~(__EMC_ERROR_STATUS_BITS | \ + __LPU0_ERROR_STATUS_BITS | \ + __LPU1_ERROR_STATUS_BITS | \ + __PSS_ERROR_STATUS_BITS | \ + __HALT_STATUS_BITS); \ +} while (0) + +#define bna_intx_disable(_bna, _cur_mask) \ +{ \ + (_cur_mask) = readl((_bna)->regs.fn_int_mask);\ + writel(0xffffffff, (_bna)->regs.fn_int_mask);\ +} + +#define bna_intx_enable(bna, new_mask) \ + writel((new_mask), (bna)->regs.fn_int_mask) + +#define bna_mbox_intr_disable(bna) \ + writel((readl((bna)->regs.fn_int_mask) | \ + (__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \ + (bna)->regs.fn_int_mask) + +#define bna_mbox_intr_enable(bna) \ + writel((readl((bna)->regs.fn_int_mask) & \ + ~(__LPU2HOST_MBOX_MASK_BITS | __ERROR_MASK_BITS)), \ + (bna)->regs.fn_int_mask) + +#define bna_intr_status_get(_bna, _status) \ +{ \ + (_status) = readl((_bna)->regs.fn_int_status); \ + if ((_status)) { \ + writel((_status) & ~(__LPU02HOST_MBOX0_STATUS_BITS |\ + __LPU02HOST_MBOX1_STATUS_BITS |\ + __LPU12HOST_MBOX0_STATUS_BITS |\ + __LPU12HOST_MBOX1_STATUS_BITS), \ + (_bna)->regs.fn_int_status);\ + } \ +} + +#define bna_intr_status_get_no_clr(_bna, _status) \ + (_status) = readl((_bna)->regs.fn_int_status) + +#define bna_intr_mask_get(bna, mask) \ + (*mask) = readl((bna)->regs.fn_int_mask) + +#define bna_intr_ack(bna, intr_bmap) \ + writel((intr_bmap), (bna)->regs.fn_int_status) + +#define bna_ib_intx_disable(bna, ib_id) \ + writel(readl((bna)->regs.fn_int_mask) | \ + (1 << (ib_id)), \ + (bna)->regs.fn_int_mask) + +#define bna_ib_intx_enable(bna, ib_id) \ + writel(readl((bna)->regs.fn_int_mask) & \ + ~(1 << (ib_id)), \ + (bna)->regs.fn_int_mask) + +#define bna_mbox_msix_idx_set(_device) \ +do {\ + writel(((_device)->vector & 0x000001FF), \ + (_device)->bna->pcidev.pci_bar_kva + \ + reg_offset[(_device)->bna->pcidev.pci_func].msix_idx);\ +} while (0) + +/** + * + * TxQ, RxQ, CQ related bits, offsets, macros + * + */ + +#define BNA_Q_IDLE_STATE 0x00008001 + +#define BNA_GET_DOORBELL_BASE_ADDR(_bar0) \ + ((_bar0) + HQM_DOORBELL_BLK_BASE_ADDR) + +#define BNA_GET_DOORBELL_ENTRY_OFFSET(_entry) \ + ((HQM_DOORBELL_BLK_BASE_ADDR) \ + + (_entry << 7)) + +#define BNA_DOORBELL_IB_INT_ACK(_timeout, _events) \ + (0x80000000 | ((_timeout) << 16) | (_events)) + +#define BNA_DOORBELL_IB_INT_DISABLE (0x40000000) + +/* TxQ Entry Opcodes */ +#define BNA_TXQ_WI_SEND (0x402) /* Single Frame Transmission */ +#define BNA_TXQ_WI_SEND_LSO (0x403) /* Multi-Frame Transmission */ +#define BNA_TXQ_WI_EXTENSION (0x104) /* Extension WI */ + +/* TxQ Entry Control Flags */ +#define BNA_TXQ_WI_CF_FCOE_CRC (1 << 8) +#define BNA_TXQ_WI_CF_IPID_MODE (1 << 5) +#define BNA_TXQ_WI_CF_INS_PRIO (1 << 4) +#define BNA_TXQ_WI_CF_INS_VLAN (1 << 3) +#define BNA_TXQ_WI_CF_UDP_CKSUM (1 << 2) +#define BNA_TXQ_WI_CF_TCP_CKSUM (1 << 1) +#define BNA_TXQ_WI_CF_IP_CKSUM (1 << 0) + +#define BNA_TXQ_WI_L4_HDR_N_OFFSET(_hdr_size, _offset) \ + (((_hdr_size) << 10) | ((_offset) & 0x3FF)) + +/* + * Completion Q defines + */ +/* CQ Entry Flags */ +#define BNA_CQ_EF_MAC_ERROR (1 << 0) +#define BNA_CQ_EF_FCS_ERROR (1 << 1) +#define BNA_CQ_EF_TOO_LONG (1 << 2) +#define BNA_CQ_EF_FC_CRC_OK (1 << 3) + +#define BNA_CQ_EF_RSVD1 (1 << 4) +#define BNA_CQ_EF_L4_CKSUM_OK (1 << 5) +#define BNA_CQ_EF_L3_CKSUM_OK (1 << 6) +#define BNA_CQ_EF_HDS_HEADER (1 << 7) + +#define BNA_CQ_EF_UDP (1 << 8) +#define BNA_CQ_EF_TCP (1 << 9) +#define BNA_CQ_EF_IP_OPTIONS (1 << 10) +#define BNA_CQ_EF_IPV6 (1 << 11) + +#define BNA_CQ_EF_IPV4 (1 << 12) +#define BNA_CQ_EF_VLAN (1 << 13) +#define BNA_CQ_EF_RSS (1 << 14) +#define BNA_CQ_EF_RSVD2 (1 << 15) + +#define BNA_CQ_EF_MCAST_MATCH (1 << 16) +#define BNA_CQ_EF_MCAST (1 << 17) +#define BNA_CQ_EF_BCAST (1 << 18) +#define BNA_CQ_EF_REMOTE (1 << 19) + +#define BNA_CQ_EF_LOCAL (1 << 20) + +/** + * + * Data structures + * + */ + +enum txf_flags { + BFI_TXF_CF_ENABLE = 1 << 0, + BFI_TXF_CF_VLAN_FILTER = 1 << 8, + BFI_TXF_CF_VLAN_ADMIT = 1 << 9, + BFI_TXF_CF_VLAN_INSERT = 1 << 10, + BFI_TXF_CF_RSVD1 = 1 << 11, + BFI_TXF_CF_MAC_SA_CHECK = 1 << 12, + BFI_TXF_CF_VLAN_WI_BASED = 1 << 13, + BFI_TXF_CF_VSWITCH_MCAST = 1 << 14, + BFI_TXF_CF_VSWITCH_UCAST = 1 << 15, + BFI_TXF_CF_RSVD2 = 0x7F << 1 +}; + +enum ib_flags { + BFI_IB_CF_MASTER_ENABLE = (1 << 0), + BFI_IB_CF_MSIX_MODE = (1 << 1), + BFI_IB_CF_COALESCING_MODE = (1 << 2), + BFI_IB_CF_INTER_PKT_ENABLE = (1 << 3), + BFI_IB_CF_INT_ENABLE = (1 << 4), + BFI_IB_CF_INTER_PKT_DMA = (1 << 5), + BFI_IB_CF_ACK_PENDING = (1 << 6), + BFI_IB_CF_RESERVED1 = (1 << 7) +}; + +enum rss_hash_type { + BFI_RSS_T_V4_TCP = (1 << 11), + BFI_RSS_T_V4_IP = (1 << 10), + BFI_RSS_T_V6_TCP = (1 << 9), + BFI_RSS_T_V6_IP = (1 << 8) +}; +enum hds_header_type { + BNA_HDS_T_V4_TCP = (1 << 11), + BNA_HDS_T_V4_UDP = (1 << 10), + BNA_HDS_T_V6_TCP = (1 << 9), + BNA_HDS_T_V6_UDP = (1 << 8), + BNA_HDS_FORCED = (1 << 7), +}; +enum rxf_flags { + BNA_RXF_CF_SM_LG_RXQ = (1 << 15), + BNA_RXF_CF_DEFAULT_VLAN = (1 << 14), + BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE = (1 << 13), + BNA_RXF_CF_VLAN_STRIP = (1 << 12), + BNA_RXF_CF_RSS_ENABLE = (1 << 8) +}; +struct bna_chip_regs_offset { + u32 page_addr; + u32 fn_int_status; + u32 fn_int_mask; + u32 msix_idx; +}; + +struct bna_chip_regs { + void __iomem *page_addr; + void __iomem *fn_int_status; + void __iomem *fn_int_mask; +}; + +struct bna_txq_mem { + u32 pg_tbl_addr_lo; + u32 pg_tbl_addr_hi; + u32 cur_q_entry_lo; + u32 cur_q_entry_hi; + u32 reserved1; + u32 reserved2; + u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */ + /* 15:0 ->producer pointer (index?) */ + u32 entry_n_pg_size; /* 31:16->entry size */ + /* 15:0 ->page size */ + u32 int_blk_n_cns_ptr; /* 31:24->Int Blk Id; */ + /* 23:16->Int Blk Offset */ + /* 15:0 ->consumer pointer(index?) */ + u32 cns_ptr2_n_q_state; /* 31:16->cons. ptr 2; 15:0-> Q state */ + u32 nxt_qid_n_fid_n_pri; /* 17:10->next */ + /* QId;9:3->FID;2:0->Priority */ + u32 wvc_n_cquota_n_rquota; /* 31:24->WI Vector Count; */ + /* 23:12->Cfg Quota; */ + /* 11:0 ->Run Quota */ + u32 reserved3[4]; +}; + +struct bna_rxq_mem { + u32 pg_tbl_addr_lo; + u32 pg_tbl_addr_hi; + u32 cur_q_entry_lo; + u32 cur_q_entry_hi; + u32 reserved1; + u32 reserved2; + u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */ + /* 15:0 ->producer pointer (index?) */ + u32 entry_n_pg_size; /* 31:16->entry size */ + /* 15:0 ->page size */ + u32 sg_n_cq_n_cns_ptr; /* 31:28->reserved; 27:24->sg count */ + /* 23:16->CQ; */ + /* 15:0->consumer pointer(index?) */ + u32 buf_sz_n_q_state; /* 31:16->buffer size; 15:0-> Q state */ + u32 next_qid; /* 17:10->next QId */ + u32 reserved3; + u32 reserved4[4]; +}; + +struct bna_rxtx_q_mem { + struct bna_rxq_mem rxq; + struct bna_txq_mem txq; +}; + +struct bna_cq_mem { + u32 pg_tbl_addr_lo; + u32 pg_tbl_addr_hi; + u32 cur_q_entry_lo; + u32 cur_q_entry_hi; + + u32 reserved1; + u32 reserved2; + u32 pg_cnt_n_prd_ptr; /* 31:16->total page count */ + /* 15:0 ->producer pointer (index?) */ + u32 entry_n_pg_size; /* 31:16->entry size */ + /* 15:0 ->page size */ + u32 int_blk_n_cns_ptr; /* 31:24->Int Blk Id; */ + /* 23:16->Int Blk Offset */ + /* 15:0 ->consumer pointer(index?) */ + u32 q_state; /* 31:16->reserved; 15:0-> Q state */ + u32 reserved3[2]; + u32 reserved4[4]; +}; + +struct bna_ib_blk_mem { + u32 host_addr_lo; + u32 host_addr_hi; + u32 clsc_n_ctrl_n_msix; /* 31:24->coalescing; */ + /* 23:16->coalescing cfg; */ + /* 15:8 ->control; */ + /* 7:0 ->msix; */ + u32 ipkt_n_ent_n_idxof; + u32 ipkt_cnt_cfg_n_unacked; + + u32 reserved[3]; +}; + +struct bna_idx_tbl_mem { + u32 idx; /* !< 31:16->res;15:0->idx; */ +}; + +struct bna_doorbell_qset { + u32 rxq[0x20 >> 2]; + u32 txq[0x20 >> 2]; + u32 ib0[0x20 >> 2]; + u32 ib1[0x20 >> 2]; +}; + +struct bna_rx_fndb_ram { + u32 rss_prop; + u32 size_routing_props; + u32 rit_hds_mcastq; + u32 control_flags; +}; + +struct bna_tx_fndb_ram { + u32 vlan_n_ctrl_flags; +}; + +/** + * @brief + * Structure which maps to RxFn Indirection Table (RIT) + * Size : 1 word + * See catapult_spec.pdf, RxA for details + */ +struct bna_rit_mem { + u32 rxq_ids; /* !< 31:12->res;11:0->two 6 bit RxQ Ids */ +}; + +/** + * @brief + * Structure which maps to RSS Table entry + * Size : 16 words + * See catapult_spec.pdf, RAD for details + */ +struct bna_rss_mem { + /* + * 31:12-> res + * 11:8 -> protocol type + * 7:0 -> hash index + */ + u32 type_n_hash; + u32 hash_key[10]; /* !< 40 byte Toeplitz hash key */ + u32 reserved[5]; +}; + +/* TxQ Vector (a.k.a. Tx-Buffer Descriptor) */ +struct bna_dma_addr { + u32 msb; + u32 lsb; +}; + +struct bna_txq_wi_vector { + u16 reserved; + u16 length; /* Only 14 LSB are valid */ + struct bna_dma_addr host_addr; /* Tx-Buf DMA addr */ +}; + +typedef u16 bna_txq_wi_opcode_t; + +typedef u16 bna_txq_wi_ctrl_flag_t; + +/** + * TxQ Entry Structure + * + * BEWARE: Load values into this structure with correct endianess. + */ +struct bna_txq_entry { + union { + struct { + u8 reserved; + u8 num_vectors; /* number of vectors present */ + bna_txq_wi_opcode_t opcode; /* Either */ + /* BNA_TXQ_WI_SEND or */ + /* BNA_TXQ_WI_SEND_LSO */ + bna_txq_wi_ctrl_flag_t flags; /* OR of all the flags */ + u16 l4_hdr_size_n_offset; + u16 vlan_tag; + u16 lso_mss; /* Only 14 LSB are valid */ + u32 frame_length; /* Only 24 LSB are valid */ + } wi; + + struct { + u16 reserved; + bna_txq_wi_opcode_t opcode; /* Must be */ + /* BNA_TXQ_WI_EXTENSION */ + u32 reserved2[3]; /* Place holder for */ + /* removed vector (12 bytes) */ + } wi_ext; + } hdr; + struct bna_txq_wi_vector vector[4]; +}; +#define wi_hdr hdr.wi +#define wi_ext_hdr hdr.wi_ext + +/* RxQ Entry Structure */ +struct bna_rxq_entry { /* Rx-Buffer */ + struct bna_dma_addr host_addr; /* Rx-Buffer DMA address */ +}; + +typedef u32 bna_cq_e_flag_t; + +/* CQ Entry Structure */ +struct bna_cq_entry { + bna_cq_e_flag_t flags; + u16 vlan_tag; + u16 length; + u32 rss_hash; + u8 valid; + u8 reserved1; + u8 reserved2; + u8 rxq_id; +}; + +#endif /* __BNA_HW_H__ */ diff --git a/drivers/net/bna/bna_txrx.c b/drivers/net/bna/bna_txrx.c new file mode 100644 index 0000000000000000000000000000000000000000..ad93fdb0f427a0b294b6c5575a3a8e2cc56ebd78 --- /dev/null +++ b/drivers/net/bna/bna_txrx.c @@ -0,0 +1,4172 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#include "bna.h" +#include "bfa_sm.h" +#include "bfi.h" + +/** + * IB + */ +#define bna_ib_find_free_ibidx(_mask, _pos)\ +do {\ + (_pos) = 0;\ + while (((_pos) < (BFI_IBIDX_MAX_SEGSIZE)) &&\ + ((1 << (_pos)) & (_mask)))\ + (_pos)++;\ +} while (0) + +#define bna_ib_count_ibidx(_mask, _count)\ +do {\ + int pos = 0;\ + (_count) = 0;\ + while (pos < (BFI_IBIDX_MAX_SEGSIZE)) {\ + if ((1 << pos) & (_mask))\ + (_count) = pos + 1;\ + pos++;\ + } \ +} while (0) + +#define bna_ib_select_segpool(_count, _q_idx)\ +do {\ + int i;\ + (_q_idx) = -1;\ + for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) {\ + if ((_count <= ibidx_pool[i].pool_entry_size)) {\ + (_q_idx) = i;\ + break;\ + } \ + } \ +} while (0) + +struct bna_ibidx_pool { + int pool_size; + int pool_entry_size; +}; +init_ibidx_pool(ibidx_pool); + +static struct bna_intr * +bna_intr_get(struct bna_ib_mod *ib_mod, enum bna_intr_type intr_type, + int vector) +{ + struct bna_intr *intr; + struct list_head *qe; + + list_for_each(qe, &ib_mod->intr_active_q) { + intr = (struct bna_intr *)qe; + + if ((intr->intr_type == intr_type) && + (intr->vector == vector)) { + intr->ref_count++; + return intr; + } + } + + if (list_empty(&ib_mod->intr_free_q)) + return NULL; + + bfa_q_deq(&ib_mod->intr_free_q, &intr); + bfa_q_qe_init(&intr->qe); + + intr->ref_count = 1; + intr->intr_type = intr_type; + intr->vector = vector; + + list_add_tail(&intr->qe, &ib_mod->intr_active_q); + + return intr; +} + +static void +bna_intr_put(struct bna_ib_mod *ib_mod, + struct bna_intr *intr) +{ + intr->ref_count--; + + if (intr->ref_count == 0) { + intr->ib = NULL; + list_del(&intr->qe); + bfa_q_qe_init(&intr->qe); + list_add_tail(&intr->qe, &ib_mod->intr_free_q); + } +} + +void +bna_ib_mod_init(struct bna_ib_mod *ib_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int i; + int j; + int count; + u8 offset; + struct bna_doorbell_qset *qset; + unsigned long off; + + ib_mod->bna = bna; + + ib_mod->ib = (struct bna_ib *) + res_info[BNA_RES_MEM_T_IB_ARRAY].res_u.mem_info.mdl[0].kva; + ib_mod->intr = (struct bna_intr *) + res_info[BNA_RES_MEM_T_INTR_ARRAY].res_u.mem_info.mdl[0].kva; + ib_mod->idx_seg = (struct bna_ibidx_seg *) + res_info[BNA_RES_MEM_T_IDXSEG_ARRAY].res_u.mem_info.mdl[0].kva; + + INIT_LIST_HEAD(&ib_mod->ib_free_q); + INIT_LIST_HEAD(&ib_mod->intr_free_q); + INIT_LIST_HEAD(&ib_mod->intr_active_q); + + for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) + INIT_LIST_HEAD(&ib_mod->ibidx_seg_pool[i]); + + for (i = 0; i < BFI_MAX_IB; i++) { + ib_mod->ib[i].ib_id = i; + + ib_mod->ib[i].ib_seg_host_addr_kva = + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].kva; + ib_mod->ib[i].ib_seg_host_addr.lsb = + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.lsb; + ib_mod->ib[i].ib_seg_host_addr.msb = + res_info[BNA_RES_MEM_T_IBIDX].res_u.mem_info.mdl[i].dma.msb; + + qset = (struct bna_doorbell_qset *)0; + off = (unsigned long)(&qset[i >> 1].ib0[(i & 0x1) + * (0x20 >> 2)]); + ib_mod->ib[i].door_bell.doorbell_addr = off + + BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva); + + bfa_q_qe_init(&ib_mod->ib[i].qe); + list_add_tail(&ib_mod->ib[i].qe, &ib_mod->ib_free_q); + + bfa_q_qe_init(&ib_mod->intr[i].qe); + list_add_tail(&ib_mod->intr[i].qe, &ib_mod->intr_free_q); + } + + count = 0; + offset = 0; + for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) { + for (j = 0; j < ibidx_pool[i].pool_size; j++) { + bfa_q_qe_init(&ib_mod->idx_seg[count]); + ib_mod->idx_seg[count].ib_seg_size = + ibidx_pool[i].pool_entry_size; + ib_mod->idx_seg[count].ib_idx_tbl_offset = offset; + list_add_tail(&ib_mod->idx_seg[count].qe, + &ib_mod->ibidx_seg_pool[i]); + count++; + offset += ibidx_pool[i].pool_entry_size; + } + } +} + +void +bna_ib_mod_uninit(struct bna_ib_mod *ib_mod) +{ + int i; + int j; + struct list_head *qe; + + i = 0; + list_for_each(qe, &ib_mod->ib_free_q) + i++; + + i = 0; + list_for_each(qe, &ib_mod->intr_free_q) + i++; + + for (i = 0; i < BFI_IBIDX_TOTAL_POOLS; i++) { + j = 0; + list_for_each(qe, &ib_mod->ibidx_seg_pool[i]) + j++; + } + + ib_mod->bna = NULL; +} + +static struct bna_ib * +bna_ib_get(struct bna_ib_mod *ib_mod, + enum bna_intr_type intr_type, + int vector) +{ + struct bna_ib *ib; + struct bna_intr *intr; + + if (intr_type == BNA_INTR_T_INTX) + vector = (1 << vector); + + intr = bna_intr_get(ib_mod, intr_type, vector); + if (intr == NULL) + return NULL; + + if (intr->ib) { + if (intr->ib->ref_count == BFI_IBIDX_MAX_SEGSIZE) { + bna_intr_put(ib_mod, intr); + return NULL; + } + intr->ib->ref_count++; + return intr->ib; + } + + if (list_empty(&ib_mod->ib_free_q)) { + bna_intr_put(ib_mod, intr); + return NULL; + } + + bfa_q_deq(&ib_mod->ib_free_q, &ib); + bfa_q_qe_init(&ib->qe); + + ib->ref_count = 1; + ib->start_count = 0; + ib->idx_mask = 0; + + ib->intr = intr; + ib->idx_seg = NULL; + intr->ib = ib; + + ib->bna = ib_mod->bna; + + return ib; +} + +static void +bna_ib_put(struct bna_ib_mod *ib_mod, struct bna_ib *ib) +{ + bna_intr_put(ib_mod, ib->intr); + + ib->ref_count--; + + if (ib->ref_count == 0) { + ib->intr = NULL; + ib->bna = NULL; + list_add_tail(&ib->qe, &ib_mod->ib_free_q); + } +} + +/* Returns index offset - starting from 0 */ +static int +bna_ib_reserve_idx(struct bna_ib *ib) +{ + struct bna_ib_mod *ib_mod = &ib->bna->ib_mod; + struct bna_ibidx_seg *idx_seg; + int idx; + int num_idx; + int q_idx; + + /* Find the first free index position */ + bna_ib_find_free_ibidx(ib->idx_mask, idx); + if (idx == BFI_IBIDX_MAX_SEGSIZE) + return -1; + + /* + * Calculate the total number of indexes held by this IB, + * including the index newly reserved above. + */ + bna_ib_count_ibidx((ib->idx_mask | (1 << idx)), num_idx); + + /* See if there is a free space in the index segment held by this IB */ + if (ib->idx_seg && (num_idx <= ib->idx_seg->ib_seg_size)) { + ib->idx_mask |= (1 << idx); + return idx; + } + + if (ib->start_count) + return -1; + + /* Allocate a new segment */ + bna_ib_select_segpool(num_idx, q_idx); + while (1) { + if (q_idx == BFI_IBIDX_TOTAL_POOLS) + return -1; + if (!list_empty(&ib_mod->ibidx_seg_pool[q_idx])) + break; + q_idx++; + } + bfa_q_deq(&ib_mod->ibidx_seg_pool[q_idx], &idx_seg); + bfa_q_qe_init(&idx_seg->qe); + + /* Free the old segment */ + if (ib->idx_seg) { + bna_ib_select_segpool(ib->idx_seg->ib_seg_size, q_idx); + list_add_tail(&ib->idx_seg->qe, &ib_mod->ibidx_seg_pool[q_idx]); + } + + ib->idx_seg = idx_seg; + + ib->idx_mask |= (1 << idx); + + return idx; +} + +static void +bna_ib_release_idx(struct bna_ib *ib, int idx) +{ + struct bna_ib_mod *ib_mod = &ib->bna->ib_mod; + struct bna_ibidx_seg *idx_seg; + int num_idx; + int cur_q_idx; + int new_q_idx; + + ib->idx_mask &= ~(1 << idx); + + if (ib->start_count) + return; + + bna_ib_count_ibidx(ib->idx_mask, num_idx); + + /* + * Free the segment, if there are no more indexes in the segment + * held by this IB + */ + if (!num_idx) { + bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx); + list_add_tail(&ib->idx_seg->qe, + &ib_mod->ibidx_seg_pool[cur_q_idx]); + ib->idx_seg = NULL; + return; + } + + /* See if we can move to a smaller segment */ + bna_ib_select_segpool(num_idx, new_q_idx); + bna_ib_select_segpool(ib->idx_seg->ib_seg_size, cur_q_idx); + while (new_q_idx < cur_q_idx) { + if (!list_empty(&ib_mod->ibidx_seg_pool[new_q_idx])) + break; + new_q_idx++; + } + if (new_q_idx < cur_q_idx) { + /* Select the new smaller segment */ + bfa_q_deq(&ib_mod->ibidx_seg_pool[new_q_idx], &idx_seg); + bfa_q_qe_init(&idx_seg->qe); + /* Free the old segment */ + list_add_tail(&ib->idx_seg->qe, + &ib_mod->ibidx_seg_pool[cur_q_idx]); + ib->idx_seg = idx_seg; + } +} + +static int +bna_ib_config(struct bna_ib *ib, struct bna_ib_config *ib_config) +{ + if (ib->start_count) + return -1; + + ib->ib_config.coalescing_timeo = ib_config->coalescing_timeo; + ib->ib_config.interpkt_timeo = ib_config->interpkt_timeo; + ib->ib_config.interpkt_count = ib_config->interpkt_count; + ib->ib_config.ctrl_flags = ib_config->ctrl_flags; + + ib->ib_config.ctrl_flags |= BFI_IB_CF_MASTER_ENABLE; + if (ib->intr->intr_type == BNA_INTR_T_MSIX) + ib->ib_config.ctrl_flags |= BFI_IB_CF_MSIX_MODE; + + return 0; +} + +static void +bna_ib_start(struct bna_ib *ib) +{ + struct bna_ib_blk_mem ib_cfg; + struct bna_ib_blk_mem *ib_mem; + u32 pg_num; + u32 intx_mask; + int i; + void __iomem *base_addr; + unsigned long off; + + ib->start_count++; + + if (ib->start_count > 1) + return; + + ib_cfg.host_addr_lo = (u32)(ib->ib_seg_host_addr.lsb); + ib_cfg.host_addr_hi = (u32)(ib->ib_seg_host_addr.msb); + + ib_cfg.clsc_n_ctrl_n_msix = (((u32) + ib->ib_config.coalescing_timeo << 16) | + ((u32)ib->ib_config.ctrl_flags << 8) | + (ib->intr->vector)); + ib_cfg.ipkt_n_ent_n_idxof = + ((u32) + (ib->ib_config.interpkt_timeo & 0xf) << 16) | + ((u32)ib->idx_seg->ib_seg_size << 8) | + (ib->idx_seg->ib_idx_tbl_offset); + ib_cfg.ipkt_cnt_cfg_n_unacked = ((u32) + ib->ib_config.interpkt_count << 24); + + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num, + HQM_IB_RAM_BASE_OFFSET); + writel(pg_num, ib->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva, + HQM_IB_RAM_BASE_OFFSET); + + ib_mem = (struct bna_ib_blk_mem *)0; + off = (unsigned long)&ib_mem[ib->ib_id].host_addr_lo; + writel(htonl(ib_cfg.host_addr_lo), base_addr + off); + + off = (unsigned long)&ib_mem[ib->ib_id].host_addr_hi; + writel(htonl(ib_cfg.host_addr_hi), base_addr + off); + + off = (unsigned long)&ib_mem[ib->ib_id].clsc_n_ctrl_n_msix; + writel(ib_cfg.clsc_n_ctrl_n_msix, base_addr + off); + + off = (unsigned long)&ib_mem[ib->ib_id].ipkt_n_ent_n_idxof; + writel(ib_cfg.ipkt_n_ent_n_idxof, base_addr + off); + + off = (unsigned long)&ib_mem[ib->ib_id].ipkt_cnt_cfg_n_unacked; + writel(ib_cfg.ipkt_cnt_cfg_n_unacked, base_addr + off); + + ib->door_bell.doorbell_ack = BNA_DOORBELL_IB_INT_ACK( + (u32)ib->ib_config.coalescing_timeo, 0); + + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + ib->bna->port_num, + HQM_INDX_TBL_RAM_BASE_OFFSET); + writel(pg_num, ib->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(ib->bna->pcidev.pci_bar_kva, + HQM_INDX_TBL_RAM_BASE_OFFSET); + for (i = 0; i < ib->idx_seg->ib_seg_size; i++) { + off = (unsigned long) + ((ib->idx_seg->ib_idx_tbl_offset + i) * BFI_IBIDX_SIZE); + writel(0, base_addr + off); + } + + if (ib->intr->intr_type == BNA_INTR_T_INTX) { + bna_intx_disable(ib->bna, intx_mask); + intx_mask &= ~(ib->intr->vector); + bna_intx_enable(ib->bna, intx_mask); + } +} + +static void +bna_ib_stop(struct bna_ib *ib) +{ + u32 intx_mask; + + ib->start_count--; + + if (ib->start_count == 0) { + writel(BNA_DOORBELL_IB_INT_DISABLE, + ib->door_bell.doorbell_addr); + if (ib->intr->intr_type == BNA_INTR_T_INTX) { + bna_intx_disable(ib->bna, intx_mask); + intx_mask |= (ib->intr->vector); + bna_intx_enable(ib->bna, intx_mask); + } + } +} + +static void +bna_ib_fail(struct bna_ib *ib) +{ + ib->start_count = 0; +} + +/** + * RXF + */ +static void rxf_enable(struct bna_rxf *rxf); +static void rxf_disable(struct bna_rxf *rxf); +static void __rxf_config_set(struct bna_rxf *rxf); +static void __rxf_rit_set(struct bna_rxf *rxf); +static void __bna_rxf_stat_clr(struct bna_rxf *rxf); +static int rxf_process_packet_filter(struct bna_rxf *rxf); +static int rxf_clear_packet_filter(struct bna_rxf *rxf); +static void rxf_reset_packet_filter(struct bna_rxf *rxf); +static void rxf_cb_enabled(void *arg, int status); +static void rxf_cb_disabled(void *arg, int status); +static void bna_rxf_cb_stats_cleared(void *arg, int status); +static void __rxf_enable(struct bna_rxf *rxf); +static void __rxf_disable(struct bna_rxf *rxf); + +bfa_fsm_state_decl(bna_rxf, stopped, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, start_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, cam_fltr_mod_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, started, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, cam_fltr_clr_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, stop_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, pause_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, resume_wait, struct bna_rxf, + enum bna_rxf_event); +bfa_fsm_state_decl(bna_rxf, stat_clr_wait, struct bna_rxf, + enum bna_rxf_event); + +static struct bfa_sm_table rxf_sm_table[] = { + {BFA_SM(bna_rxf_sm_stopped), BNA_RXF_STOPPED}, + {BFA_SM(bna_rxf_sm_start_wait), BNA_RXF_START_WAIT}, + {BFA_SM(bna_rxf_sm_cam_fltr_mod_wait), BNA_RXF_CAM_FLTR_MOD_WAIT}, + {BFA_SM(bna_rxf_sm_started), BNA_RXF_STARTED}, + {BFA_SM(bna_rxf_sm_cam_fltr_clr_wait), BNA_RXF_CAM_FLTR_CLR_WAIT}, + {BFA_SM(bna_rxf_sm_stop_wait), BNA_RXF_STOP_WAIT}, + {BFA_SM(bna_rxf_sm_pause_wait), BNA_RXF_PAUSE_WAIT}, + {BFA_SM(bna_rxf_sm_resume_wait), BNA_RXF_RESUME_WAIT}, + {BFA_SM(bna_rxf_sm_stat_clr_wait), BNA_RXF_STAT_CLR_WAIT} +}; + +static void +bna_rxf_sm_stopped_entry(struct bna_rxf *rxf) +{ + call_rxf_stop_cbfn(rxf, BNA_CB_SUCCESS); +} + +static void +bna_rxf_sm_stopped(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_START: + bfa_fsm_set_state(rxf, bna_rxf_sm_start_wait); + break; + + case RXF_E_STOP: + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_FAIL: + /* No-op */ + break; + + case RXF_E_CAM_FLTR_MOD: + call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS); + break; + + case RXF_E_STARTED: + case RXF_E_STOPPED: + case RXF_E_CAM_FLTR_RESP: + /** + * These events are received due to flushing of mbox + * when device fails + */ + /* No-op */ + break; + + case RXF_E_PAUSE: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED; + call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS); + break; + + case RXF_E_RESUME: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING; + call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS); + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_start_wait_entry(struct bna_rxf *rxf) +{ + __rxf_config_set(rxf); + __rxf_rit_set(rxf); + rxf_enable(rxf); +} + +static void +bna_rxf_sm_start_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_STOP: + /** + * STOP is originated from bnad. When this happens, + * it can not be waiting for filter update + */ + call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT); + bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait); + break; + + case RXF_E_FAIL: + call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS); + call_rxf_start_cbfn(rxf, BNA_CB_FAIL); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_CAM_FLTR_MOD: + /* No-op */ + break; + + case RXF_E_STARTED: + /** + * Force rxf_process_filter() to go through initial + * config + */ + if ((rxf->ucast_active_mac != NULL) && + (rxf->ucast_pending_set == 0)) + rxf->ucast_pending_set = 1; + + if (rxf->rss_status == BNA_STATUS_T_ENABLED) + rxf->rxf_flags |= BNA_RXF_FL_RSS_CONFIG_PENDING; + + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + + bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait); + break; + + case RXF_E_PAUSE: + case RXF_E_RESUME: + rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED; + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_cam_fltr_mod_wait_entry(struct bna_rxf *rxf) +{ + if (!rxf_process_packet_filter(rxf)) { + /* No more pending CAM entries to update */ + bfa_fsm_set_state(rxf, bna_rxf_sm_started); + } +} + +static void +bna_rxf_sm_cam_fltr_mod_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_STOP: + /** + * STOP is originated from bnad. When this happens, + * it can not be waiting for filter update + */ + call_rxf_start_cbfn(rxf, BNA_CB_INTERRUPT); + bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait); + break; + + case RXF_E_FAIL: + rxf_reset_packet_filter(rxf); + call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS); + call_rxf_start_cbfn(rxf, BNA_CB_FAIL); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_CAM_FLTR_MOD: + /* No-op */ + break; + + case RXF_E_CAM_FLTR_RESP: + if (!rxf_process_packet_filter(rxf)) { + /* No more pending CAM entries to update */ + call_rxf_cam_fltr_cbfn(rxf, BNA_CB_SUCCESS); + bfa_fsm_set_state(rxf, bna_rxf_sm_started); + } + break; + + case RXF_E_PAUSE: + case RXF_E_RESUME: + rxf->rxf_flags |= BNA_RXF_FL_OPERSTATE_CHANGED; + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_started_entry(struct bna_rxf *rxf) +{ + call_rxf_start_cbfn(rxf, BNA_CB_SUCCESS); + + if (rxf->rxf_flags & BNA_RXF_FL_OPERSTATE_CHANGED) { + if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) + bfa_fsm_send_event(rxf, RXF_E_PAUSE); + else + bfa_fsm_send_event(rxf, RXF_E_RESUME); + } + +} + +static void +bna_rxf_sm_started(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_STOP: + bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_clr_wait); + /* Hack to get FSM start clearing CAM entries */ + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP); + break; + + case RXF_E_FAIL: + rxf_reset_packet_filter(rxf); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_CAM_FLTR_MOD: + bfa_fsm_set_state(rxf, bna_rxf_sm_cam_fltr_mod_wait); + break; + + case RXF_E_PAUSE: + bfa_fsm_set_state(rxf, bna_rxf_sm_pause_wait); + break; + + case RXF_E_RESUME: + bfa_fsm_set_state(rxf, bna_rxf_sm_resume_wait); + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_cam_fltr_clr_wait_entry(struct bna_rxf *rxf) +{ + /** + * Note: Do not add rxf_clear_packet_filter here. + * It will overstep mbox when this transition happens: + * cam_fltr_mod_wait -> cam_fltr_clr_wait on RXF_E_STOP event + */ +} + +static void +bna_rxf_sm_cam_fltr_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + /** + * FSM was in the process of stopping, initiated by + * bnad. When this happens, no one can be waiting for + * start or filter update + */ + rxf_reset_packet_filter(rxf); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_CAM_FLTR_RESP: + if (!rxf_clear_packet_filter(rxf)) { + /* No more pending CAM entries to clear */ + bfa_fsm_set_state(rxf, bna_rxf_sm_stop_wait); + rxf_disable(rxf); + } + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_stop_wait_entry(struct bna_rxf *rxf) +{ + /** + * NOTE: Do not add rxf_disable here. + * It will overstep mbox when this transition happens: + * start_wait -> stop_wait on RXF_E_STOP event + */ +} + +static void +bna_rxf_sm_stop_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + /** + * FSM was in the process of stopping, initiated by + * bnad. When this happens, no one can be waiting for + * start or filter update + */ + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_STARTED: + /** + * This event is received due to abrupt transition from + * bna_rxf_sm_start_wait state on receiving + * RXF_E_STOP event + */ + rxf_disable(rxf); + break; + + case RXF_E_STOPPED: + /** + * FSM was in the process of stopping, initiated by + * bnad. When this happens, no one can be waiting for + * start or filter update + */ + bfa_fsm_set_state(rxf, bna_rxf_sm_stat_clr_wait); + break; + + case RXF_E_PAUSE: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED; + break; + + case RXF_E_RESUME: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING; + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_pause_wait_entry(struct bna_rxf *rxf) +{ + rxf->rxf_flags &= + ~(BNA_RXF_FL_OPERSTATE_CHANGED | BNA_RXF_FL_RXF_ENABLED); + __rxf_disable(rxf); +} + +static void +bna_rxf_sm_pause_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + /** + * FSM was in the process of disabling rxf, initiated by + * bnad. + */ + call_rxf_pause_cbfn(rxf, BNA_CB_FAIL); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_STOPPED: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_PAUSED; + call_rxf_pause_cbfn(rxf, BNA_CB_SUCCESS); + bfa_fsm_set_state(rxf, bna_rxf_sm_started); + break; + + /* + * Since PAUSE/RESUME can only be sent by bnad, we don't expect + * any other event during these states + */ + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_resume_wait_entry(struct bna_rxf *rxf) +{ + rxf->rxf_flags &= ~(BNA_RXF_FL_OPERSTATE_CHANGED); + rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED; + __rxf_enable(rxf); +} + +static void +bna_rxf_sm_resume_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + /** + * FSM was in the process of disabling rxf, initiated by + * bnad. + */ + call_rxf_resume_cbfn(rxf, BNA_CB_FAIL); + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + case RXF_E_STARTED: + rxf->rxf_oper_state = BNA_RXF_OPER_STATE_RUNNING; + call_rxf_resume_cbfn(rxf, BNA_CB_SUCCESS); + bfa_fsm_set_state(rxf, bna_rxf_sm_started); + break; + + /* + * Since PAUSE/RESUME can only be sent by bnad, we don't expect + * any other event during these states + */ + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +bna_rxf_sm_stat_clr_wait_entry(struct bna_rxf *rxf) +{ + __bna_rxf_stat_clr(rxf); +} + +static void +bna_rxf_sm_stat_clr_wait(struct bna_rxf *rxf, enum bna_rxf_event event) +{ + switch (event) { + case RXF_E_FAIL: + case RXF_E_STAT_CLEARED: + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); + break; + + default: + bfa_sm_fault(rxf->rx->bna, event); + } +} + +static void +__rxf_enable(struct bna_rxf *rxf) +{ + struct bfi_ll_rxf_multi_req ll_req; + u32 bm[2] = {0, 0}; + + if (rxf->rxf_id < 32) + bm[0] = 1 << rxf->rxf_id; + else + bm[1] = 1 << (rxf->rxf_id - 32); + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0); + ll_req.rxf_id_mask[0] = htonl(bm[0]); + ll_req.rxf_id_mask[1] = htonl(bm[1]); + ll_req.enable = 1; + + bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req), + rxf_cb_enabled, rxf); + + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static void +__rxf_disable(struct bna_rxf *rxf) +{ + struct bfi_ll_rxf_multi_req ll_req; + u32 bm[2] = {0, 0}; + + if (rxf->rxf_id < 32) + bm[0] = 1 << rxf->rxf_id; + else + bm[1] = 1 << (rxf->rxf_id - 32); + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RX_REQ, 0); + ll_req.rxf_id_mask[0] = htonl(bm[0]); + ll_req.rxf_id_mask[1] = htonl(bm[1]); + ll_req.enable = 0; + + bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req), + rxf_cb_disabled, rxf); + + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static void +__rxf_config_set(struct bna_rxf *rxf) +{ + u32 i; + struct bna_rss_mem *rss_mem; + struct bna_rx_fndb_ram *rx_fndb_ram; + struct bna *bna = rxf->rx->bna; + void __iomem *base_addr; + unsigned long off; + + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + RSS_TABLE_BASE_OFFSET); + + rss_mem = (struct bna_rss_mem *)0; + + /* Configure RSS if required */ + if (rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE) { + /* configure RSS Table */ + writel(BNA_GET_PAGE_NUM(RAD0_MEM_BLK_BASE_PG_NUM + + bna->port_num, RSS_TABLE_BASE_OFFSET), + bna->regs.page_addr); + + /* temporarily disable RSS, while hash value is written */ + off = (unsigned long)&rss_mem[0].type_n_hash; + writel(0, base_addr + off); + + for (i = 0; i < BFI_RSS_HASH_KEY_LEN; i++) { + off = (unsigned long) + &rss_mem[0].hash_key[(BFI_RSS_HASH_KEY_LEN - 1) - i]; + writel(htonl(rxf->rss_cfg.toeplitz_hash_key[i]), + base_addr + off); + } + + off = (unsigned long)&rss_mem[0].type_n_hash; + writel(rxf->rss_cfg.hash_type | rxf->rss_cfg.hash_mask, + base_addr + off); + } + + /* Configure RxF */ + writel(BNA_GET_PAGE_NUM( + LUT0_MEM_BLK_BASE_PG_NUM + (bna->port_num * 2), + RX_FNDB_RAM_BASE_OFFSET), + bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + RX_FNDB_RAM_BASE_OFFSET); + + rx_fndb_ram = (struct bna_rx_fndb_ram *)0; + + /* We always use RSS table 0 */ + off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rss_prop; + writel(rxf->ctrl_flags & BNA_RXF_CF_RSS_ENABLE, + base_addr + off); + + /* small large buffer enable/disable */ + off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].size_routing_props; + writel((rxf->ctrl_flags & BNA_RXF_CF_SM_LG_RXQ) | 0x80, + base_addr + off); + + /* RIT offset, HDS forced offset, multicast RxQ Id */ + off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].rit_hds_mcastq; + writel((rxf->rit_segment->rit_offset << 16) | + (rxf->forced_offset << 8) | + (rxf->hds_cfg.hdr_type & BNA_HDS_FORCED) | rxf->mcast_rxq_id, + base_addr + off); + + /* + * default vlan tag, default function enable, strip vlan bytes, + * HDS type, header size + */ + + off = (unsigned long)&rx_fndb_ram[rxf->rxf_id].control_flags; + writel(((u32)rxf->default_vlan_tag << 16) | + (rxf->ctrl_flags & + (BNA_RXF_CF_DEFAULT_VLAN | + BNA_RXF_CF_DEFAULT_FUNCTION_ENABLE | + BNA_RXF_CF_VLAN_STRIP)) | + (rxf->hds_cfg.hdr_type & ~BNA_HDS_FORCED) | + rxf->hds_cfg.header_size, + base_addr + off); +} + +void +__rxf_vlan_filter_set(struct bna_rxf *rxf, enum bna_status status) +{ + struct bna *bna = rxf->rx->bna; + int i; + + writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM + + (bna->port_num * 2), VLAN_RAM_BASE_OFFSET), + bna->regs.page_addr); + + if (status == BNA_STATUS_T_ENABLED) { + /* enable VLAN filtering on this function */ + for (i = 0; i <= BFI_MAX_VLAN / 32; i++) { + writel(rxf->vlan_filter_table[i], + BNA_GET_VLAN_MEM_ENTRY_ADDR + (bna->pcidev.pci_bar_kva, rxf->rxf_id, + i * 32)); + } + } else { + /* disable VLAN filtering on this function */ + for (i = 0; i <= BFI_MAX_VLAN / 32; i++) { + writel(0xffffffff, + BNA_GET_VLAN_MEM_ENTRY_ADDR + (bna->pcidev.pci_bar_kva, rxf->rxf_id, + i * 32)); + } + } +} + +static void +__rxf_rit_set(struct bna_rxf *rxf) +{ + struct bna *bna = rxf->rx->bna; + struct bna_rit_mem *rit_mem; + int i; + void __iomem *base_addr; + unsigned long off; + + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + FUNCTION_TO_RXQ_TRANSLATE); + + rit_mem = (struct bna_rit_mem *)0; + + writel(BNA_GET_PAGE_NUM(RXA0_MEM_BLK_BASE_PG_NUM + bna->port_num, + FUNCTION_TO_RXQ_TRANSLATE), + bna->regs.page_addr); + + for (i = 0; i < rxf->rit_segment->rit_size; i++) { + off = (unsigned long)&rit_mem[i + rxf->rit_segment->rit_offset]; + writel(rxf->rit_segment->rit[i].large_rxq_id << 6 | + rxf->rit_segment->rit[i].small_rxq_id, + base_addr + off); + } +} + +static void +__bna_rxf_stat_clr(struct bna_rxf *rxf) +{ + struct bfi_ll_stats_req ll_req; + u32 bm[2] = {0, 0}; + + if (rxf->rxf_id < 32) + bm[0] = 1 << rxf->rxf_id; + else + bm[1] = 1 << (rxf->rxf_id - 32); + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0); + ll_req.stats_mask = 0; + ll_req.txf_id_mask[0] = 0; + ll_req.txf_id_mask[1] = 0; + + ll_req.rxf_id_mask[0] = htonl(bm[0]); + ll_req.rxf_id_mask[1] = htonl(bm[1]); + + bna_mbox_qe_fill(&rxf->mbox_qe, &ll_req, sizeof(ll_req), + bna_rxf_cb_stats_cleared, rxf); + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static void +rxf_enable(struct bna_rxf *rxf) +{ + if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) + bfa_fsm_send_event(rxf, RXF_E_STARTED); + else { + rxf->rxf_flags |= BNA_RXF_FL_RXF_ENABLED; + __rxf_enable(rxf); + } +} + +static void +rxf_cb_enabled(void *arg, int status) +{ + struct bna_rxf *rxf = (struct bna_rxf *)arg; + + bfa_q_qe_init(&rxf->mbox_qe.qe); + bfa_fsm_send_event(rxf, RXF_E_STARTED); +} + +static void +rxf_disable(struct bna_rxf *rxf) +{ + if (rxf->rxf_oper_state == BNA_RXF_OPER_STATE_PAUSED) + bfa_fsm_send_event(rxf, RXF_E_STOPPED); + else + rxf->rxf_flags &= ~BNA_RXF_FL_RXF_ENABLED; + __rxf_disable(rxf); +} + +static void +rxf_cb_disabled(void *arg, int status) +{ + struct bna_rxf *rxf = (struct bna_rxf *)arg; + + bfa_q_qe_init(&rxf->mbox_qe.qe); + bfa_fsm_send_event(rxf, RXF_E_STOPPED); +} + +void +rxf_cb_cam_fltr_mbox_cmd(void *arg, int status) +{ + struct bna_rxf *rxf = (struct bna_rxf *)arg; + + bfa_q_qe_init(&rxf->mbox_qe.qe); + + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_RESP); +} + +static void +bna_rxf_cb_stats_cleared(void *arg, int status) +{ + struct bna_rxf *rxf = (struct bna_rxf *)arg; + + bfa_q_qe_init(&rxf->mbox_qe.qe); + bfa_fsm_send_event(rxf, RXF_E_STAT_CLEARED); +} + +void +rxf_cam_mbox_cmd(struct bna_rxf *rxf, u8 cmd, + const struct bna_mac *mac_addr) +{ + struct bfi_ll_mac_addr_req req; + + bfi_h2i_set(req.mh, BFI_MC_LL, cmd, 0); + + req.rxf_id = rxf->rxf_id; + memcpy(&req.mac_addr, (void *)&mac_addr->addr, ETH_ALEN); + + bna_mbox_qe_fill(&rxf->mbox_qe, &req, sizeof(req), + rxf_cb_cam_fltr_mbox_cmd, rxf); + + bna_mbox_send(rxf->rx->bna, &rxf->mbox_qe); +} + +static int +rxf_process_packet_filter_mcast(struct bna_rxf *rxf) +{ + struct bna_mac *mac = NULL; + struct list_head *qe; + + /* Add multicast entries */ + if (!list_empty(&rxf->mcast_pending_add_q)) { + bfa_q_deq(&rxf->mcast_pending_add_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_ADD_REQ, mac); + list_add_tail(&mac->qe, &rxf->mcast_active_q); + return 1; + } + + /* Delete multicast entries previousely added */ + if (!list_empty(&rxf->mcast_pending_del_q)) { + bfa_q_deq(&rxf->mcast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + return 1; + } + + return 0; +} + +static int +rxf_process_packet_filter_vlan(struct bna_rxf *rxf) +{ + /* Apply the VLAN filter */ + if (rxf->rxf_flags & BNA_RXF_FL_VLAN_CONFIG_PENDING) { + rxf->rxf_flags &= ~BNA_RXF_FL_VLAN_CONFIG_PENDING; + if (!(rxf->rxmode_active & BNA_RXMODE_PROMISC) && + !(rxf->rxmode_active & BNA_RXMODE_DEFAULT)) + __rxf_vlan_filter_set(rxf, rxf->vlan_filter_status); + } + + /* Apply RSS configuration */ + if (rxf->rxf_flags & BNA_RXF_FL_RSS_CONFIG_PENDING) { + rxf->rxf_flags &= ~BNA_RXF_FL_RSS_CONFIG_PENDING; + if (rxf->rss_status == BNA_STATUS_T_DISABLED) { + /* RSS is being disabled */ + rxf->ctrl_flags &= ~BNA_RXF_CF_RSS_ENABLE; + __rxf_rit_set(rxf); + __rxf_config_set(rxf); + } else { + /* RSS is being enabled or reconfigured */ + rxf->ctrl_flags |= BNA_RXF_CF_RSS_ENABLE; + __rxf_rit_set(rxf); + __rxf_config_set(rxf); + } + } + + return 0; +} + +/** + * Processes pending ucast, mcast entry addition/deletion and issues mailbox + * command. Also processes pending filter configuration - promiscuous mode, + * default mode, allmutli mode and issues mailbox command or directly applies + * to h/w + */ +static int +rxf_process_packet_filter(struct bna_rxf *rxf) +{ + /* Set the default MAC first */ + if (rxf->ucast_pending_set > 0) { + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_UCAST_SET_REQ, + rxf->ucast_active_mac); + rxf->ucast_pending_set--; + return 1; + } + + if (rxf_process_packet_filter_ucast(rxf)) + return 1; + + if (rxf_process_packet_filter_mcast(rxf)) + return 1; + + if (rxf_process_packet_filter_promisc(rxf)) + return 1; + + if (rxf_process_packet_filter_default(rxf)) + return 1; + + if (rxf_process_packet_filter_allmulti(rxf)) + return 1; + + if (rxf_process_packet_filter_vlan(rxf)) + return 1; + + return 0; +} + +static int +rxf_clear_packet_filter_mcast(struct bna_rxf *rxf) +{ + struct bna_mac *mac = NULL; + struct list_head *qe; + + /* 3. delete pending mcast entries */ + if (!list_empty(&rxf->mcast_pending_del_q)) { + bfa_q_deq(&rxf->mcast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + return 1; + } + + /* 4. clear active mcast entries; move them to pending_add_q */ + if (!list_empty(&rxf->mcast_active_q)) { + bfa_q_deq(&rxf->mcast_active_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + rxf_cam_mbox_cmd(rxf, BFI_LL_H2I_MAC_MCAST_DEL_REQ, mac); + list_add_tail(&mac->qe, &rxf->mcast_pending_add_q); + return 1; + } + + return 0; +} + +/** + * In the rxf stop path, processes pending ucast/mcast delete queue and issues + * the mailbox command. Moves the active ucast/mcast entries to pending add q, + * so that they are added to CAM again in the rxf start path. Moves the current + * filter settings - promiscuous, default, allmutli - to pending filter + * configuration + */ +static int +rxf_clear_packet_filter(struct bna_rxf *rxf) +{ + if (rxf_clear_packet_filter_ucast(rxf)) + return 1; + + if (rxf_clear_packet_filter_mcast(rxf)) + return 1; + + /* 5. clear active default MAC in the CAM */ + if (rxf->ucast_pending_set > 0) + rxf->ucast_pending_set = 0; + + if (rxf_clear_packet_filter_promisc(rxf)) + return 1; + + if (rxf_clear_packet_filter_default(rxf)) + return 1; + + if (rxf_clear_packet_filter_allmulti(rxf)) + return 1; + + return 0; +} + +static void +rxf_reset_packet_filter_mcast(struct bna_rxf *rxf) +{ + struct list_head *qe; + struct bna_mac *mac; + + /* 3. Move active mcast entries to pending_add_q */ + while (!list_empty(&rxf->mcast_active_q)) { + bfa_q_deq(&rxf->mcast_active_q, &qe); + bfa_q_qe_init(qe); + list_add_tail(qe, &rxf->mcast_pending_add_q); + } + + /* 4. Throw away delete pending mcast entries */ + while (!list_empty(&rxf->mcast_pending_del_q)) { + bfa_q_deq(&rxf->mcast_pending_del_q, &qe); + bfa_q_qe_init(qe); + mac = (struct bna_mac *)qe; + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + } +} + +/** + * In the rxf fail path, throws away the ucast/mcast entries pending for + * deletion, moves all active ucast/mcast entries to pending queue so that + * they are added back to CAM in the rxf start path. Also moves the current + * filter configuration to pending filter configuration. + */ +static void +rxf_reset_packet_filter(struct bna_rxf *rxf) +{ + rxf_reset_packet_filter_ucast(rxf); + + rxf_reset_packet_filter_mcast(rxf); + + /* 5. Turn off ucast set flag */ + rxf->ucast_pending_set = 0; + + rxf_reset_packet_filter_promisc(rxf); + + rxf_reset_packet_filter_default(rxf); + + rxf_reset_packet_filter_allmulti(rxf); +} + +static void +bna_rxf_init(struct bna_rxf *rxf, + struct bna_rx *rx, + struct bna_rx_config *q_config) +{ + struct list_head *qe; + struct bna_rxp *rxp; + + /* rxf_id is initialized during rx_mod init */ + rxf->rx = rx; + + INIT_LIST_HEAD(&rxf->ucast_pending_add_q); + INIT_LIST_HEAD(&rxf->ucast_pending_del_q); + rxf->ucast_pending_set = 0; + INIT_LIST_HEAD(&rxf->ucast_active_q); + rxf->ucast_active_mac = NULL; + + INIT_LIST_HEAD(&rxf->mcast_pending_add_q); + INIT_LIST_HEAD(&rxf->mcast_pending_del_q); + INIT_LIST_HEAD(&rxf->mcast_active_q); + + bfa_q_qe_init(&rxf->mbox_qe.qe); + + if (q_config->vlan_strip_status == BNA_STATUS_T_ENABLED) + rxf->ctrl_flags |= BNA_RXF_CF_VLAN_STRIP; + + rxf->rxf_oper_state = (q_config->paused) ? + BNA_RXF_OPER_STATE_PAUSED : BNA_RXF_OPER_STATE_RUNNING; + + bna_rxf_adv_init(rxf, rx, q_config); + + rxf->rit_segment = bna_rit_mod_seg_get(&rxf->rx->bna->rit_mod, + q_config->num_paths); + + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + if (q_config->rxp_type == BNA_RXP_SINGLE) + rxf->mcast_rxq_id = rxp->rxq.single.only->rxq_id; + else + rxf->mcast_rxq_id = rxp->rxq.slr.large->rxq_id; + break; + } + + rxf->vlan_filter_status = BNA_STATUS_T_DISABLED; + memset(rxf->vlan_filter_table, 0, + (sizeof(u32) * ((BFI_MAX_VLAN + 1) / 32))); + + bfa_fsm_set_state(rxf, bna_rxf_sm_stopped); +} + +static void +bna_rxf_uninit(struct bna_rxf *rxf) +{ + struct bna_mac *mac; + + bna_rit_mod_seg_put(&rxf->rx->bna->rit_mod, rxf->rit_segment); + rxf->rit_segment = NULL; + + rxf->ucast_pending_set = 0; + + while (!list_empty(&rxf->ucast_pending_add_q)) { + bfa_q_deq(&rxf->ucast_pending_add_q, &mac); + bfa_q_qe_init(&mac->qe); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, mac); + } + + if (rxf->ucast_active_mac) { + bfa_q_qe_init(&rxf->ucast_active_mac->qe); + bna_ucam_mod_mac_put(&rxf->rx->bna->ucam_mod, + rxf->ucast_active_mac); + rxf->ucast_active_mac = NULL; + } + + while (!list_empty(&rxf->mcast_pending_add_q)) { + bfa_q_deq(&rxf->mcast_pending_add_q, &mac); + bfa_q_qe_init(&mac->qe); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + } + + rxf->rx = NULL; +} + +static void +bna_rx_cb_rxf_started(struct bna_rx *rx, enum bna_cb_status status) +{ + bfa_fsm_send_event(rx, RX_E_RXF_STARTED); + if (rx->rxf.rxf_id < 32) + rx->bna->rx_mod.rxf_bmap[0] |= ((u32)1 << rx->rxf.rxf_id); + else + rx->bna->rx_mod.rxf_bmap[1] |= ((u32) + 1 << (rx->rxf.rxf_id - 32)); +} + +static void +bna_rxf_start(struct bna_rxf *rxf) +{ + rxf->start_cbfn = bna_rx_cb_rxf_started; + rxf->start_cbarg = rxf->rx; + rxf->rxf_flags &= ~BNA_RXF_FL_FAILED; + bfa_fsm_send_event(rxf, RXF_E_START); +} + +static void +bna_rx_cb_rxf_stopped(struct bna_rx *rx, enum bna_cb_status status) +{ + bfa_fsm_send_event(rx, RX_E_RXF_STOPPED); + if (rx->rxf.rxf_id < 32) + rx->bna->rx_mod.rxf_bmap[0] &= ~(u32)1 << rx->rxf.rxf_id; + else + rx->bna->rx_mod.rxf_bmap[1] &= ~(u32) + 1 << (rx->rxf.rxf_id - 32); +} + +static void +bna_rxf_stop(struct bna_rxf *rxf) +{ + rxf->stop_cbfn = bna_rx_cb_rxf_stopped; + rxf->stop_cbarg = rxf->rx; + bfa_fsm_send_event(rxf, RXF_E_STOP); +} + +static void +bna_rxf_fail(struct bna_rxf *rxf) +{ + rxf->rxf_flags |= BNA_RXF_FL_FAILED; + bfa_fsm_send_event(rxf, RXF_E_FAIL); +} + +int +bna_rxf_state_get(struct bna_rxf *rxf) +{ + return bfa_sm_to_state(rxf_sm_table, rxf->fsm); +} + +enum bna_cb_status +bna_rx_ucast_set(struct bna_rx *rx, u8 *ucmac, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + + if (rxf->ucast_active_mac == NULL) { + rxf->ucast_active_mac = + bna_ucam_mod_mac_get(&rxf->rx->bna->ucam_mod); + if (rxf->ucast_active_mac == NULL) + return BNA_CB_UCAST_CAM_FULL; + bfa_q_qe_init(&rxf->ucast_active_mac->qe); + } + + memcpy(rxf->ucast_active_mac->addr, ucmac, ETH_ALEN); + rxf->ucast_pending_set++; + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + + return BNA_CB_SUCCESS; +} + +enum bna_cb_status +bna_rx_mcast_add(struct bna_rx *rx, u8 *addr, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + struct list_head *qe; + struct bna_mac *mac; + + /* Check if already added */ + list_for_each(qe, &rxf->mcast_active_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + return BNA_CB_SUCCESS; + } + } + + /* Check if pending addition */ + list_for_each(qe, &rxf->mcast_pending_add_q) { + mac = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac->addr, addr)) { + if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + return BNA_CB_SUCCESS; + } + } + + mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod); + if (mac == NULL) + return BNA_CB_MCAST_LIST_FULL; + bfa_q_qe_init(&mac->qe); + memcpy(mac->addr, addr, ETH_ALEN); + list_add_tail(&mac->qe, &rxf->mcast_pending_add_q); + + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + + return BNA_CB_SUCCESS; +} + +enum bna_cb_status +bna_rx_mcast_listset(struct bna_rx *rx, int count, u8 *mclist, + void (*cbfn)(struct bnad *, struct bna_rx *, + enum bna_cb_status)) +{ + struct bna_rxf *rxf = &rx->rxf; + struct list_head list_head; + struct list_head *qe; + u8 *mcaddr; + struct bna_mac *mac; + struct bna_mac *mac1; + int skip; + int delete; + int need_hw_config = 0; + int i; + + /* Allocate nodes */ + INIT_LIST_HEAD(&list_head); + for (i = 0, mcaddr = mclist; i < count; i++) { + mac = bna_mcam_mod_mac_get(&rxf->rx->bna->mcam_mod); + if (mac == NULL) + goto err_return; + bfa_q_qe_init(&mac->qe); + memcpy(mac->addr, mcaddr, ETH_ALEN); + list_add_tail(&mac->qe, &list_head); + + mcaddr += ETH_ALEN; + } + + /* Schedule for addition */ + while (!list_empty(&list_head)) { + bfa_q_deq(&list_head, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + + skip = 0; + + /* Skip if already added */ + list_for_each(qe, &rxf->mcast_active_q) { + mac1 = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) { + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, + mac); + skip = 1; + break; + } + } + + if (skip) + continue; + + /* Skip if pending addition */ + list_for_each(qe, &rxf->mcast_pending_add_q) { + mac1 = (struct bna_mac *)qe; + if (BNA_MAC_IS_EQUAL(mac1->addr, mac->addr)) { + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, + mac); + skip = 1; + break; + } + } + + if (skip) + continue; + + need_hw_config = 1; + list_add_tail(&mac->qe, &rxf->mcast_pending_add_q); + } + + /** + * Delete the entries that are in the pending_add_q but not + * in the new list + */ + while (!list_empty(&rxf->mcast_pending_add_q)) { + bfa_q_deq(&rxf->mcast_pending_add_q, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) { + if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) { + delete = 0; + break; + } + mcaddr += ETH_ALEN; + } + if (delete) + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + else + list_add_tail(&mac->qe, &list_head); + } + while (!list_empty(&list_head)) { + bfa_q_deq(&list_head, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + list_add_tail(&mac->qe, &rxf->mcast_pending_add_q); + } + + /** + * Schedule entries for deletion that are in the active_q but not + * in the new list + */ + while (!list_empty(&rxf->mcast_active_q)) { + bfa_q_deq(&rxf->mcast_active_q, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + for (i = 0, mcaddr = mclist, delete = 1; i < count; i++) { + if (BNA_MAC_IS_EQUAL(mcaddr, mac->addr)) { + delete = 0; + break; + } + mcaddr += ETH_ALEN; + } + if (delete) { + list_add_tail(&mac->qe, &rxf->mcast_pending_del_q); + need_hw_config = 1; + } else { + list_add_tail(&mac->qe, &list_head); + } + } + while (!list_empty(&list_head)) { + bfa_q_deq(&list_head, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + list_add_tail(&mac->qe, &rxf->mcast_active_q); + } + + if (need_hw_config) { + rxf->cam_fltr_cbfn = cbfn; + rxf->cam_fltr_cbarg = rx->bna->bnad; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } else if (cbfn) + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + + return BNA_CB_SUCCESS; + +err_return: + while (!list_empty(&list_head)) { + bfa_q_deq(&list_head, &qe); + mac = (struct bna_mac *)qe; + bfa_q_qe_init(&mac->qe); + bna_mcam_mod_mac_put(&rxf->rx->bna->mcam_mod, mac); + } + + return BNA_CB_MCAST_LIST_FULL; +} + +void +bna_rx_vlan_add(struct bna_rx *rx, int vlan_id) +{ + struct bna_rxf *rxf = &rx->rxf; + int index = (vlan_id >> 5); + int bit = (1 << (vlan_id & 0x1F)); + + rxf->vlan_filter_table[index] |= bit; + if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) { + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } +} + +void +bna_rx_vlan_del(struct bna_rx *rx, int vlan_id) +{ + struct bna_rxf *rxf = &rx->rxf; + int index = (vlan_id >> 5); + int bit = (1 << (vlan_id & 0x1F)); + + rxf->vlan_filter_table[index] &= ~bit; + if (rxf->vlan_filter_status == BNA_STATUS_T_ENABLED) { + rxf->rxf_flags |= BNA_RXF_FL_VLAN_CONFIG_PENDING; + bfa_fsm_send_event(rxf, RXF_E_CAM_FLTR_MOD); + } +} + +/** + * RX + */ +#define RXQ_RCB_INIT(q, rxp, qdepth, bna, _id, unmapq_mem) do { \ + struct bna_doorbell_qset *_qset; \ + unsigned long off; \ + (q)->rcb->producer_index = (q)->rcb->consumer_index = 0; \ + (q)->rcb->q_depth = (qdepth); \ + (q)->rcb->unmap_q = unmapq_mem; \ + (q)->rcb->rxq = (q); \ + (q)->rcb->cq = &(rxp)->cq; \ + (q)->rcb->bnad = (bna)->bnad; \ + _qset = (struct bna_doorbell_qset *)0; \ + off = (unsigned long)&_qset[(q)->rxq_id].rxq[0]; \ + (q)->rcb->q_dbell = off + \ + BNA_GET_DOORBELL_BASE_ADDR((bna)->pcidev.pci_bar_kva); \ + (q)->rcb->id = _id; \ +} while (0) + +#define BNA_GET_RXQS(qcfg) (((qcfg)->rxp_type == BNA_RXP_SINGLE) ? \ + (qcfg)->num_paths : ((qcfg)->num_paths * 2)) + +#define SIZE_TO_PAGES(size) (((size) >> PAGE_SHIFT) + ((((size) &\ + (PAGE_SIZE - 1)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT)) + +#define call_rx_stop_callback(rx, status) \ + if ((rx)->stop_cbfn) { \ + (*(rx)->stop_cbfn)((rx)->stop_cbarg, rx, (status)); \ + (rx)->stop_cbfn = NULL; \ + (rx)->stop_cbarg = NULL; \ + } + +/* + * Since rx_enable is synchronous callback, there is no start_cbfn required. + * Instead, we'll call bnad_rx_post(rxp) so that bnad can post the buffers + * for each rxpath. + */ + +#define call_rx_disable_cbfn(rx, status) \ + if ((rx)->disable_cbfn) { \ + (*(rx)->disable_cbfn)((rx)->disable_cbarg, \ + status); \ + (rx)->disable_cbfn = NULL; \ + (rx)->disable_cbarg = NULL; \ + } \ + +#define rxqs_reqd(type, num_rxqs) \ + (((type) == BNA_RXP_SINGLE) ? (num_rxqs) : ((num_rxqs) * 2)) + +#define rx_ib_fail(rx) \ +do { \ + struct bna_rxp *rxp; \ + struct list_head *qe; \ + list_for_each(qe, &(rx)->rxp_q) { \ + rxp = (struct bna_rxp *)qe; \ + bna_ib_fail(rxp->cq.ib); \ + } \ +} while (0) + +static void __bna_multi_rxq_stop(struct bna_rxp *, u32 *); +static void __bna_rxq_start(struct bna_rxq *rxq); +static void __bna_cq_start(struct bna_cq *cq); +static void bna_rit_create(struct bna_rx *rx); +static void bna_rx_cb_multi_rxq_stopped(void *arg, int status); +static void bna_rx_cb_rxq_stopped_all(void *arg); + +bfa_fsm_state_decl(bna_rx, stopped, + struct bna_rx, enum bna_rx_event); +bfa_fsm_state_decl(bna_rx, rxf_start_wait, + struct bna_rx, enum bna_rx_event); +bfa_fsm_state_decl(bna_rx, started, + struct bna_rx, enum bna_rx_event); +bfa_fsm_state_decl(bna_rx, rxf_stop_wait, + struct bna_rx, enum bna_rx_event); +bfa_fsm_state_decl(bna_rx, rxq_stop_wait, + struct bna_rx, enum bna_rx_event); + +static const struct bfa_sm_table rx_sm_table[] = { + {BFA_SM(bna_rx_sm_stopped), BNA_RX_STOPPED}, + {BFA_SM(bna_rx_sm_rxf_start_wait), BNA_RX_RXF_START_WAIT}, + {BFA_SM(bna_rx_sm_started), BNA_RX_STARTED}, + {BFA_SM(bna_rx_sm_rxf_stop_wait), BNA_RX_RXF_STOP_WAIT}, + {BFA_SM(bna_rx_sm_rxq_stop_wait), BNA_RX_RXQ_STOP_WAIT}, +}; + +static void bna_rx_sm_stopped_entry(struct bna_rx *rx) +{ + struct bna_rxp *rxp; + struct list_head *qe_rxp; + + list_for_each(qe_rxp, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe_rxp; + rx->rx_cleanup_cbfn(rx->bna->bnad, rxp->cq.ccb); + } + + call_rx_stop_callback(rx, BNA_CB_SUCCESS); +} + +static void bna_rx_sm_stopped(struct bna_rx *rx, + enum bna_rx_event event) +{ + switch (event) { + case RX_E_START: + bfa_fsm_set_state(rx, bna_rx_sm_rxf_start_wait); + break; + case RX_E_STOP: + call_rx_stop_callback(rx, BNA_CB_SUCCESS); + break; + case RX_E_FAIL: + /* no-op */ + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } + +} + +static void bna_rx_sm_rxf_start_wait_entry(struct bna_rx *rx) +{ + struct bna_rxp *rxp; + struct list_head *qe_rxp; + struct bna_rxq *q0 = NULL, *q1 = NULL; + + /* Setup the RIT */ + bna_rit_create(rx); + + list_for_each(qe_rxp, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe_rxp; + bna_ib_start(rxp->cq.ib); + GET_RXQS(rxp, q0, q1); + q0->buffer_size = bna_port_mtu_get(&rx->bna->port); + __bna_rxq_start(q0); + rx->rx_post_cbfn(rx->bna->bnad, q0->rcb); + if (q1) { + __bna_rxq_start(q1); + rx->rx_post_cbfn(rx->bna->bnad, q1->rcb); + } + __bna_cq_start(&rxp->cq); + } + + bna_rxf_start(&rx->rxf); +} + +static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx, + enum bna_rx_event event) +{ + switch (event) { + case RX_E_STOP: + bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait); + break; + case RX_E_FAIL: + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + rx_ib_fail(rx); + bna_rxf_fail(&rx->rxf); + break; + case RX_E_RXF_STARTED: + bfa_fsm_set_state(rx, bna_rx_sm_started); + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } +} + +void +bna_rx_sm_started_entry(struct bna_rx *rx) +{ + struct bna_rxp *rxp; + struct list_head *qe_rxp; + + /* Start IB */ + list_for_each(qe_rxp, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe_rxp; + bna_ib_ack(&rxp->cq.ib->door_bell, 0); + } + + bna_llport_admin_up(&rx->bna->port.llport); +} + +void +bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event) +{ + switch (event) { + case RX_E_FAIL: + bna_llport_admin_down(&rx->bna->port.llport); + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + rx_ib_fail(rx); + bna_rxf_fail(&rx->rxf); + break; + case RX_E_STOP: + bna_llport_admin_down(&rx->bna->port.llport); + bfa_fsm_set_state(rx, bna_rx_sm_rxf_stop_wait); + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } +} + +void +bna_rx_sm_rxf_stop_wait_entry(struct bna_rx *rx) +{ + bna_rxf_stop(&rx->rxf); +} + +void +bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event) +{ + switch (event) { + case RX_E_RXF_STOPPED: + bfa_fsm_set_state(rx, bna_rx_sm_rxq_stop_wait); + break; + case RX_E_RXF_STARTED: + /** + * RxF was in the process of starting up when + * RXF_E_STOP was issued. Ignore this event + */ + break; + case RX_E_FAIL: + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + rx_ib_fail(rx); + bna_rxf_fail(&rx->rxf); + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } + +} + +void +bna_rx_sm_rxq_stop_wait_entry(struct bna_rx *rx) +{ + struct bna_rxp *rxp = NULL; + struct bna_rxq *q0 = NULL; + struct bna_rxq *q1 = NULL; + struct list_head *qe; + u32 rxq_mask[2] = {0, 0}; + + /* Only one call to multi-rxq-stop for all RXPs in this RX */ + bfa_wc_up(&rx->rxq_stop_wc); + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + GET_RXQS(rxp, q0, q1); + if (q0->rxq_id < 32) + rxq_mask[0] |= ((u32)1 << q0->rxq_id); + else + rxq_mask[1] |= ((u32)1 << (q0->rxq_id - 32)); + if (q1) { + if (q1->rxq_id < 32) + rxq_mask[0] |= ((u32)1 << q1->rxq_id); + else + rxq_mask[1] |= ((u32) + 1 << (q1->rxq_id - 32)); + } + } + + __bna_multi_rxq_stop(rxp, rxq_mask); +} + +void +bna_rx_sm_rxq_stop_wait(struct bna_rx *rx, enum bna_rx_event event) +{ + struct bna_rxp *rxp = NULL; + struct list_head *qe; + + switch (event) { + case RX_E_RXQ_STOPPED: + list_for_each(qe, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe; + bna_ib_stop(rxp->cq.ib); + } + /* Fall through */ + case RX_E_FAIL: + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + break; + default: + bfa_sm_fault(rx->bna, event); + break; + } +} + +void +__bna_multi_rxq_stop(struct bna_rxp *rxp, u32 * rxq_id_mask) +{ + struct bfi_ll_q_stop_req ll_req; + + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_RXQ_STOP_REQ, 0); + ll_req.q_id_mask[0] = htonl(rxq_id_mask[0]); + ll_req.q_id_mask[1] = htonl(rxq_id_mask[1]); + bna_mbox_qe_fill(&rxp->mbox_qe, &ll_req, sizeof(ll_req), + bna_rx_cb_multi_rxq_stopped, rxp); + bna_mbox_send(rxp->rx->bna, &rxp->mbox_qe); +} + +void +__bna_rxq_start(struct bna_rxq *rxq) +{ + struct bna_rxtx_q_mem *q_mem; + struct bna_rxq_mem rxq_cfg, *rxq_mem; + struct bna_dma_addr cur_q_addr; + /* struct bna_doorbell_qset *qset; */ + struct bna_qpt *qpt; + u32 pg_num; + struct bna *bna = rxq->rx->bna; + void __iomem *base_addr; + unsigned long off; + + qpt = &rxq->qpt; + cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr)); + + rxq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb; + rxq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb; + rxq_cfg.cur_q_entry_lo = cur_q_addr.lsb; + rxq_cfg.cur_q_entry_hi = cur_q_addr.msb; + + rxq_cfg.pg_cnt_n_prd_ptr = ((u32)qpt->page_count << 16) | 0x0; + rxq_cfg.entry_n_pg_size = ((u32)(BFI_RXQ_WI_SIZE >> 2) << 16) | + (qpt->page_size >> 2); + rxq_cfg.sg_n_cq_n_cns_ptr = + ((u32)(rxq->rxp->cq.cq_id & 0xff) << 16) | 0x0; + rxq_cfg.buf_sz_n_q_state = ((u32)rxq->buffer_size << 16) | + BNA_Q_IDLE_STATE; + rxq_cfg.next_qid = 0x0 | (0x3 << 8); + + /* Write the page number register */ + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num, + HQM_RXTX_Q_RAM_BASE_OFFSET); + writel(pg_num, bna->regs.page_addr); + + /* Write to h/w */ + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + HQM_RXTX_Q_RAM_BASE_OFFSET); + + q_mem = (struct bna_rxtx_q_mem *)0; + rxq_mem = &q_mem[rxq->rxq_id].rxq; + + off = (unsigned long)&rxq_mem->pg_tbl_addr_lo; + writel(htonl(rxq_cfg.pg_tbl_addr_lo), base_addr + off); + + off = (unsigned long)&rxq_mem->pg_tbl_addr_hi; + writel(htonl(rxq_cfg.pg_tbl_addr_hi), base_addr + off); + + off = (unsigned long)&rxq_mem->cur_q_entry_lo; + writel(htonl(rxq_cfg.cur_q_entry_lo), base_addr + off); + + off = (unsigned long)&rxq_mem->cur_q_entry_hi; + writel(htonl(rxq_cfg.cur_q_entry_hi), base_addr + off); + + off = (unsigned long)&rxq_mem->pg_cnt_n_prd_ptr; + writel(rxq_cfg.pg_cnt_n_prd_ptr, base_addr + off); + + off = (unsigned long)&rxq_mem->entry_n_pg_size; + writel(rxq_cfg.entry_n_pg_size, base_addr + off); + + off = (unsigned long)&rxq_mem->sg_n_cq_n_cns_ptr; + writel(rxq_cfg.sg_n_cq_n_cns_ptr, base_addr + off); + + off = (unsigned long)&rxq_mem->buf_sz_n_q_state; + writel(rxq_cfg.buf_sz_n_q_state, base_addr + off); + + off = (unsigned long)&rxq_mem->next_qid; + writel(rxq_cfg.next_qid, base_addr + off); + + rxq->rcb->producer_index = 0; + rxq->rcb->consumer_index = 0; +} + +void +__bna_cq_start(struct bna_cq *cq) +{ + struct bna_cq_mem cq_cfg, *cq_mem; + const struct bna_qpt *qpt; + struct bna_dma_addr cur_q_addr; + u32 pg_num; + struct bna *bna = cq->rx->bna; + void __iomem *base_addr; + unsigned long off; + + qpt = &cq->qpt; + cur_q_addr = *((struct bna_dma_addr *)(qpt->kv_qpt_ptr)); + + /* + * Fill out structure, to be subsequently written + * to hardware + */ + cq_cfg.pg_tbl_addr_lo = qpt->hw_qpt_ptr.lsb; + cq_cfg.pg_tbl_addr_hi = qpt->hw_qpt_ptr.msb; + cq_cfg.cur_q_entry_lo = cur_q_addr.lsb; + cq_cfg.cur_q_entry_hi = cur_q_addr.msb; + + cq_cfg.pg_cnt_n_prd_ptr = (qpt->page_count << 16) | 0x0; + cq_cfg.entry_n_pg_size = + ((u32)(BFI_CQ_WI_SIZE >> 2) << 16) | (qpt->page_size >> 2); + cq_cfg.int_blk_n_cns_ptr = ((((u32)cq->ib_seg_offset) << 24) | + ((u32)(cq->ib->ib_id & 0xff) << 16) | 0x0); + cq_cfg.q_state = BNA_Q_IDLE_STATE; + + /* Write the page number register */ + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + bna->port_num, + HQM_CQ_RAM_BASE_OFFSET); + + writel(pg_num, bna->regs.page_addr); + + /* H/W write */ + base_addr = BNA_GET_MEM_BASE_ADDR(bna->pcidev.pci_bar_kva, + HQM_CQ_RAM_BASE_OFFSET); + + cq_mem = (struct bna_cq_mem *)0; + + off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_lo; + writel(htonl(cq_cfg.pg_tbl_addr_lo), base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].pg_tbl_addr_hi; + writel(htonl(cq_cfg.pg_tbl_addr_hi), base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_lo; + writel(htonl(cq_cfg.cur_q_entry_lo), base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].cur_q_entry_hi; + writel(htonl(cq_cfg.cur_q_entry_hi), base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].pg_cnt_n_prd_ptr; + writel(cq_cfg.pg_cnt_n_prd_ptr, base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].entry_n_pg_size; + writel(cq_cfg.entry_n_pg_size, base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].int_blk_n_cns_ptr; + writel(cq_cfg.int_blk_n_cns_ptr, base_addr + off); + + off = (unsigned long)&cq_mem[cq->cq_id].q_state; + writel(cq_cfg.q_state, base_addr + off); + + cq->ccb->producer_index = 0; + *(cq->ccb->hw_producer_index) = 0; +} + +void +bna_rit_create(struct bna_rx *rx) +{ + struct list_head *qe_rxp; + struct bna *bna; + struct bna_rxp *rxp; + struct bna_rxq *q0 = NULL; + struct bna_rxq *q1 = NULL; + int offset; + + bna = rx->bna; + + offset = 0; + list_for_each(qe_rxp, &rx->rxp_q) { + rxp = (struct bna_rxp *)qe_rxp; + GET_RXQS(rxp, q0, q1); + rx->rxf.rit_segment->rit[offset].large_rxq_id = q0->rxq_id; + rx->rxf.rit_segment->rit[offset].small_rxq_id = + (q1 ? q1->rxq_id : 0); + offset++; + } +} + +static int +_rx_can_satisfy(struct bna_rx_mod *rx_mod, + struct bna_rx_config *rx_cfg) +{ + if ((rx_mod->rx_free_count == 0) || + (rx_mod->rxp_free_count == 0) || + (rx_mod->rxq_free_count == 0)) + return 0; + + if (rx_cfg->rxp_type == BNA_RXP_SINGLE) { + if ((rx_mod->rxp_free_count < rx_cfg->num_paths) || + (rx_mod->rxq_free_count < rx_cfg->num_paths)) + return 0; + } else { + if ((rx_mod->rxp_free_count < rx_cfg->num_paths) || + (rx_mod->rxq_free_count < (2 * rx_cfg->num_paths))) + return 0; + } + + if (!bna_rit_mod_can_satisfy(&rx_mod->bna->rit_mod, rx_cfg->num_paths)) + return 0; + + return 1; +} + +static struct bna_rxq * +_get_free_rxq(struct bna_rx_mod *rx_mod) +{ + struct bna_rxq *rxq = NULL; + struct list_head *qe = NULL; + + bfa_q_deq(&rx_mod->rxq_free_q, &qe); + if (qe) { + rx_mod->rxq_free_count--; + rxq = (struct bna_rxq *)qe; + } + return rxq; +} + +static void +_put_free_rxq(struct bna_rx_mod *rx_mod, struct bna_rxq *rxq) +{ + bfa_q_qe_init(&rxq->qe); + list_add_tail(&rxq->qe, &rx_mod->rxq_free_q); + rx_mod->rxq_free_count++; +} + +static struct bna_rxp * +_get_free_rxp(struct bna_rx_mod *rx_mod) +{ + struct list_head *qe = NULL; + struct bna_rxp *rxp = NULL; + + bfa_q_deq(&rx_mod->rxp_free_q, &qe); + if (qe) { + rx_mod->rxp_free_count--; + + rxp = (struct bna_rxp *)qe; + } + + return rxp; +} + +static void +_put_free_rxp(struct bna_rx_mod *rx_mod, struct bna_rxp *rxp) +{ + bfa_q_qe_init(&rxp->qe); + list_add_tail(&rxp->qe, &rx_mod->rxp_free_q); + rx_mod->rxp_free_count++; +} + +static struct bna_rx * +_get_free_rx(struct bna_rx_mod *rx_mod) +{ + struct list_head *qe = NULL; + struct bna_rx *rx = NULL; + + bfa_q_deq(&rx_mod->rx_free_q, &qe); + if (qe) { + rx_mod->rx_free_count--; + + rx = (struct bna_rx *)qe; + bfa_q_qe_init(qe); + list_add_tail(&rx->qe, &rx_mod->rx_active_q); + } + + return rx; +} + +static void +_put_free_rx(struct bna_rx_mod *rx_mod, struct bna_rx *rx) +{ + bfa_q_qe_init(&rx->qe); + list_add_tail(&rx->qe, &rx_mod->rx_free_q); + rx_mod->rx_free_count++; +} + +static void +_rx_init(struct bna_rx *rx, struct bna *bna) +{ + rx->bna = bna; + rx->rx_flags = 0; + + INIT_LIST_HEAD(&rx->rxp_q); + + rx->rxq_stop_wc.wc_resume = bna_rx_cb_rxq_stopped_all; + rx->rxq_stop_wc.wc_cbarg = rx; + rx->rxq_stop_wc.wc_count = 0; + + rx->stop_cbfn = NULL; + rx->stop_cbarg = NULL; +} + +static void +_rxp_add_rxqs(struct bna_rxp *rxp, + struct bna_rxq *q0, + struct bna_rxq *q1) +{ + switch (rxp->type) { + case BNA_RXP_SINGLE: + rxp->rxq.single.only = q0; + rxp->rxq.single.reserved = NULL; + break; + case BNA_RXP_SLR: + rxp->rxq.slr.large = q0; + rxp->rxq.slr.small = q1; + break; + case BNA_RXP_HDS: + rxp->rxq.hds.data = q0; + rxp->rxq.hds.hdr = q1; + break; + default: + break; + } +} + +static void +_rxq_qpt_init(struct bna_rxq *rxq, + struct bna_rxp *rxp, + u32 page_count, + u32 page_size, + struct bna_mem_descr *qpt_mem, + struct bna_mem_descr *swqpt_mem, + struct bna_mem_descr *page_mem) +{ + int i; + + rxq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; + rxq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb; + rxq->qpt.kv_qpt_ptr = qpt_mem->kva; + rxq->qpt.page_count = page_count; + rxq->qpt.page_size = page_size; + + rxq->rcb->sw_qpt = (void **) swqpt_mem->kva; + + for (i = 0; i < rxq->qpt.page_count; i++) { + rxq->rcb->sw_qpt[i] = page_mem[i].kva; + ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].lsb = + page_mem[i].dma.lsb; + ((struct bna_dma_addr *)rxq->qpt.kv_qpt_ptr)[i].msb = + page_mem[i].dma.msb; + + } +} + +static void +_rxp_cqpt_setup(struct bna_rxp *rxp, + u32 page_count, + u32 page_size, + struct bna_mem_descr *qpt_mem, + struct bna_mem_descr *swqpt_mem, + struct bna_mem_descr *page_mem) +{ + int i; + + rxp->cq.qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; + rxp->cq.qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb; + rxp->cq.qpt.kv_qpt_ptr = qpt_mem->kva; + rxp->cq.qpt.page_count = page_count; + rxp->cq.qpt.page_size = page_size; + + rxp->cq.ccb->sw_qpt = (void **) swqpt_mem->kva; + + for (i = 0; i < rxp->cq.qpt.page_count; i++) { + rxp->cq.ccb->sw_qpt[i] = page_mem[i].kva; + + ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].lsb = + page_mem[i].dma.lsb; + ((struct bna_dma_addr *)rxp->cq.qpt.kv_qpt_ptr)[i].msb = + page_mem[i].dma.msb; + + } +} + +static void +_rx_add_rxp(struct bna_rx *rx, struct bna_rxp *rxp) +{ + list_add_tail(&rxp->qe, &rx->rxp_q); +} + +static void +_init_rxmod_queues(struct bna_rx_mod *rx_mod) +{ + INIT_LIST_HEAD(&rx_mod->rx_free_q); + INIT_LIST_HEAD(&rx_mod->rxq_free_q); + INIT_LIST_HEAD(&rx_mod->rxp_free_q); + INIT_LIST_HEAD(&rx_mod->rx_active_q); + + rx_mod->rx_free_count = 0; + rx_mod->rxq_free_count = 0; + rx_mod->rxp_free_count = 0; +} + +static void +_rx_ctor(struct bna_rx *rx, int id) +{ + bfa_q_qe_init(&rx->qe); + INIT_LIST_HEAD(&rx->rxp_q); + rx->bna = NULL; + + rx->rxf.rxf_id = id; + + /* FIXME: mbox_qe ctor()?? */ + bfa_q_qe_init(&rx->mbox_qe.qe); + + rx->stop_cbfn = NULL; + rx->stop_cbarg = NULL; +} + +void +bna_rx_cb_multi_rxq_stopped(void *arg, int status) +{ + struct bna_rxp *rxp = (struct bna_rxp *)arg; + + bfa_wc_down(&rxp->rx->rxq_stop_wc); +} + +void +bna_rx_cb_rxq_stopped_all(void *arg) +{ + struct bna_rx *rx = (struct bna_rx *)arg; + + bfa_fsm_send_event(rx, RX_E_RXQ_STOPPED); +} + +static void +bna_rx_mod_cb_rx_stopped(void *arg, struct bna_rx *rx, + enum bna_cb_status status) +{ + struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg; + + bfa_wc_down(&rx_mod->rx_stop_wc); +} + +static void +bna_rx_mod_cb_rx_stopped_all(void *arg) +{ + struct bna_rx_mod *rx_mod = (struct bna_rx_mod *)arg; + + if (rx_mod->stop_cbfn) + rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS); + rx_mod->stop_cbfn = NULL; +} + +static void +bna_rx_start(struct bna_rx *rx) +{ + rx->rx_flags |= BNA_RX_F_PORT_ENABLED; + if (rx->rx_flags & BNA_RX_F_ENABLE) + bfa_fsm_send_event(rx, RX_E_START); +} + +static void +bna_rx_stop(struct bna_rx *rx) +{ + rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED; + if (rx->fsm == (bfa_fsm_t) bna_rx_sm_stopped) + bna_rx_mod_cb_rx_stopped(&rx->bna->rx_mod, rx, BNA_CB_SUCCESS); + else { + rx->stop_cbfn = bna_rx_mod_cb_rx_stopped; + rx->stop_cbarg = &rx->bna->rx_mod; + bfa_fsm_send_event(rx, RX_E_STOP); + } +} + +static void +bna_rx_fail(struct bna_rx *rx) +{ + /* Indicate port is not enabled, and failed */ + rx->rx_flags &= ~BNA_RX_F_PORT_ENABLED; + rx->rx_flags |= BNA_RX_F_PORT_FAILED; + bfa_fsm_send_event(rx, RX_E_FAIL); +} + +void +bna_rx_mod_start(struct bna_rx_mod *rx_mod, enum bna_rx_type type) +{ + struct bna_rx *rx; + struct list_head *qe; + + rx_mod->flags |= BNA_RX_MOD_F_PORT_STARTED; + if (type == BNA_RX_T_LOOPBACK) + rx_mod->flags |= BNA_RX_MOD_F_PORT_LOOPBACK; + + list_for_each(qe, &rx_mod->rx_active_q) { + rx = (struct bna_rx *)qe; + if (rx->type == type) + bna_rx_start(rx); + } +} + +void +bna_rx_mod_stop(struct bna_rx_mod *rx_mod, enum bna_rx_type type) +{ + struct bna_rx *rx; + struct list_head *qe; + + rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED; + rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK; + + rx_mod->stop_cbfn = bna_port_cb_rx_stopped; + + /** + * Before calling bna_rx_stop(), increment rx_stop_wc as many times + * as we are going to call bna_rx_stop + */ + list_for_each(qe, &rx_mod->rx_active_q) { + rx = (struct bna_rx *)qe; + if (rx->type == type) + bfa_wc_up(&rx_mod->rx_stop_wc); + } + + if (rx_mod->rx_stop_wc.wc_count == 0) { + rx_mod->stop_cbfn(&rx_mod->bna->port, BNA_CB_SUCCESS); + rx_mod->stop_cbfn = NULL; + return; + } + + list_for_each(qe, &rx_mod->rx_active_q) { + rx = (struct bna_rx *)qe; + if (rx->type == type) + bna_rx_stop(rx); + } +} + +void +bna_rx_mod_fail(struct bna_rx_mod *rx_mod) +{ + struct bna_rx *rx; + struct list_head *qe; + + rx_mod->flags &= ~BNA_RX_MOD_F_PORT_STARTED; + rx_mod->flags &= ~BNA_RX_MOD_F_PORT_LOOPBACK; + + list_for_each(qe, &rx_mod->rx_active_q) { + rx = (struct bna_rx *)qe; + bna_rx_fail(rx); + } +} + +void bna_rx_mod_init(struct bna_rx_mod *rx_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int index; + struct bna_rx *rx_ptr; + struct bna_rxp *rxp_ptr; + struct bna_rxq *rxq_ptr; + + rx_mod->bna = bna; + rx_mod->flags = 0; + + rx_mod->rx = (struct bna_rx *) + res_info[BNA_RES_MEM_T_RX_ARRAY].res_u.mem_info.mdl[0].kva; + rx_mod->rxp = (struct bna_rxp *) + res_info[BNA_RES_MEM_T_RXP_ARRAY].res_u.mem_info.mdl[0].kva; + rx_mod->rxq = (struct bna_rxq *) + res_info[BNA_RES_MEM_T_RXQ_ARRAY].res_u.mem_info.mdl[0].kva; + + /* Initialize the queues */ + _init_rxmod_queues(rx_mod); + + /* Build RX queues */ + for (index = 0; index < BFI_MAX_RXQ; index++) { + rx_ptr = &rx_mod->rx[index]; + _rx_ctor(rx_ptr, index); + list_add_tail(&rx_ptr->qe, &rx_mod->rx_free_q); + rx_mod->rx_free_count++; + } + + /* build RX-path queue */ + for (index = 0; index < BFI_MAX_RXQ; index++) { + rxp_ptr = &rx_mod->rxp[index]; + rxp_ptr->cq.cq_id = index; + bfa_q_qe_init(&rxp_ptr->qe); + list_add_tail(&rxp_ptr->qe, &rx_mod->rxp_free_q); + rx_mod->rxp_free_count++; + } + + /* build RXQ queue */ + for (index = 0; index < BFI_MAX_RXQ; index++) { + rxq_ptr = &rx_mod->rxq[index]; + rxq_ptr->rxq_id = index; + + bfa_q_qe_init(&rxq_ptr->qe); + list_add_tail(&rxq_ptr->qe, &rx_mod->rxq_free_q); + rx_mod->rxq_free_count++; + } + + rx_mod->rx_stop_wc.wc_resume = bna_rx_mod_cb_rx_stopped_all; + rx_mod->rx_stop_wc.wc_cbarg = rx_mod; + rx_mod->rx_stop_wc.wc_count = 0; +} + +void +bna_rx_mod_uninit(struct bna_rx_mod *rx_mod) +{ + struct list_head *qe; + int i; + + i = 0; + list_for_each(qe, &rx_mod->rx_free_q) + i++; + + i = 0; + list_for_each(qe, &rx_mod->rxp_free_q) + i++; + + i = 0; + list_for_each(qe, &rx_mod->rxq_free_q) + i++; + + rx_mod->bna = NULL; +} + +int +bna_rx_state_get(struct bna_rx *rx) +{ + return bfa_sm_to_state(rx_sm_table, rx->fsm); +} + +void +bna_rx_res_req(struct bna_rx_config *q_cfg, struct bna_res_info *res_info) +{ + u32 cq_size, hq_size, dq_size; + u32 cpage_count, hpage_count, dpage_count; + struct bna_mem_info *mem_info; + u32 cq_depth; + u32 hq_depth; + u32 dq_depth; + + dq_depth = q_cfg->q_depth; + hq_depth = ((q_cfg->rxp_type == BNA_RXP_SINGLE) ? 0 : q_cfg->q_depth); + cq_depth = dq_depth + hq_depth; + + BNA_TO_POWER_OF_2_HIGH(cq_depth); + cq_size = cq_depth * BFI_CQ_WI_SIZE; + cq_size = ALIGN(cq_size, PAGE_SIZE); + cpage_count = SIZE_TO_PAGES(cq_size); + + BNA_TO_POWER_OF_2_HIGH(dq_depth); + dq_size = dq_depth * BFI_RXQ_WI_SIZE; + dq_size = ALIGN(dq_size, PAGE_SIZE); + dpage_count = SIZE_TO_PAGES(dq_size); + + if (BNA_RXP_SINGLE != q_cfg->rxp_type) { + BNA_TO_POWER_OF_2_HIGH(hq_depth); + hq_size = hq_depth * BFI_RXQ_WI_SIZE; + hq_size = ALIGN(hq_size, PAGE_SIZE); + hpage_count = SIZE_TO_PAGES(hq_size); + } else { + hpage_count = 0; + } + + /* CCB structures */ + res_info[BNA_RX_RES_MEM_T_CCB].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = sizeof(struct bna_ccb); + mem_info->num = q_cfg->num_paths; + + /* RCB structures */ + res_info[BNA_RX_RES_MEM_T_RCB].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = sizeof(struct bna_rcb); + mem_info->num = BNA_GET_RXQS(q_cfg); + + /* Completion QPT */ + res_info[BNA_RX_RES_MEM_T_CQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = cpage_count * sizeof(struct bna_dma_addr); + mem_info->num = q_cfg->num_paths; + + /* Completion s/w QPT */ + res_info[BNA_RX_RES_MEM_T_CSWQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = cpage_count * sizeof(void *); + mem_info->num = q_cfg->num_paths; + + /* Completion QPT pages */ + res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = PAGE_SIZE; + mem_info->num = cpage_count * q_cfg->num_paths; + + /* Data QPTs */ + res_info[BNA_RX_RES_MEM_T_DQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = dpage_count * sizeof(struct bna_dma_addr); + mem_info->num = q_cfg->num_paths; + + /* Data s/w QPTs */ + res_info[BNA_RX_RES_MEM_T_DSWQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = dpage_count * sizeof(void *); + mem_info->num = q_cfg->num_paths; + + /* Data QPT pages */ + res_info[BNA_RX_RES_MEM_T_DPAGE].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = PAGE_SIZE; + mem_info->num = dpage_count * q_cfg->num_paths; + + /* Hdr QPTs */ + res_info[BNA_RX_RES_MEM_T_HQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = hpage_count * sizeof(struct bna_dma_addr); + mem_info->num = (hpage_count ? q_cfg->num_paths : 0); + + /* Hdr s/w QPTs */ + res_info[BNA_RX_RES_MEM_T_HSWQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = hpage_count * sizeof(void *); + mem_info->num = (hpage_count ? q_cfg->num_paths : 0); + + /* Hdr QPT pages */ + res_info[BNA_RX_RES_MEM_T_HPAGE].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = (hpage_count ? PAGE_SIZE : 0); + mem_info->num = (hpage_count ? (hpage_count * q_cfg->num_paths) : 0); + + /* RX Interrupts */ + res_info[BNA_RX_RES_T_INTR].res_type = BNA_RES_T_INTR; + res_info[BNA_RX_RES_T_INTR].res_u.intr_info.intr_type = BNA_INTR_T_MSIX; + res_info[BNA_RX_RES_T_INTR].res_u.intr_info.num = q_cfg->num_paths; +} + +struct bna_rx * +bna_rx_create(struct bna *bna, struct bnad *bnad, + struct bna_rx_config *rx_cfg, + struct bna_rx_event_cbfn *rx_cbfn, + struct bna_res_info *res_info, + void *priv) +{ + struct bna_rx_mod *rx_mod = &bna->rx_mod; + struct bna_rx *rx; + struct bna_rxp *rxp; + struct bna_rxq *q0; + struct bna_rxq *q1; + struct bna_intr_info *intr_info; + u32 page_count; + struct bna_mem_descr *ccb_mem; + struct bna_mem_descr *rcb_mem; + struct bna_mem_descr *unmapq_mem; + struct bna_mem_descr *cqpt_mem; + struct bna_mem_descr *cswqpt_mem; + struct bna_mem_descr *cpage_mem; + struct bna_mem_descr *hqpt_mem; /* Header/Small Q qpt */ + struct bna_mem_descr *dqpt_mem; /* Data/Large Q qpt */ + struct bna_mem_descr *hsqpt_mem; /* s/w qpt for hdr */ + struct bna_mem_descr *dsqpt_mem; /* s/w qpt for data */ + struct bna_mem_descr *hpage_mem; /* hdr page mem */ + struct bna_mem_descr *dpage_mem; /* data page mem */ + int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0, ret; + int dpage_count, hpage_count, rcb_idx; + struct bna_ib_config ibcfg; + /* Fail if we don't have enough RXPs, RXQs */ + if (!_rx_can_satisfy(rx_mod, rx_cfg)) + return NULL; + + /* Initialize resource pointers */ + intr_info = &res_info[BNA_RX_RES_T_INTR].res_u.intr_info; + ccb_mem = &res_info[BNA_RX_RES_MEM_T_CCB].res_u.mem_info.mdl[0]; + rcb_mem = &res_info[BNA_RX_RES_MEM_T_RCB].res_u.mem_info.mdl[0]; + unmapq_mem = &res_info[BNA_RX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[0]; + cqpt_mem = &res_info[BNA_RX_RES_MEM_T_CQPT].res_u.mem_info.mdl[0]; + cswqpt_mem = &res_info[BNA_RX_RES_MEM_T_CSWQPT].res_u.mem_info.mdl[0]; + cpage_mem = &res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.mdl[0]; + hqpt_mem = &res_info[BNA_RX_RES_MEM_T_HQPT].res_u.mem_info.mdl[0]; + dqpt_mem = &res_info[BNA_RX_RES_MEM_T_DQPT].res_u.mem_info.mdl[0]; + hsqpt_mem = &res_info[BNA_RX_RES_MEM_T_HSWQPT].res_u.mem_info.mdl[0]; + dsqpt_mem = &res_info[BNA_RX_RES_MEM_T_DSWQPT].res_u.mem_info.mdl[0]; + hpage_mem = &res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.mdl[0]; + dpage_mem = &res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.mdl[0]; + + /* Compute q depth & page count */ + page_count = res_info[BNA_RX_RES_MEM_T_CQPT_PAGE].res_u.mem_info.num / + rx_cfg->num_paths; + + dpage_count = res_info[BNA_RX_RES_MEM_T_DPAGE].res_u.mem_info.num / + rx_cfg->num_paths; + + hpage_count = res_info[BNA_RX_RES_MEM_T_HPAGE].res_u.mem_info.num / + rx_cfg->num_paths; + /* Get RX pointer */ + rx = _get_free_rx(rx_mod); + _rx_init(rx, bna); + rx->priv = priv; + rx->type = rx_cfg->rx_type; + + rx->rcb_setup_cbfn = rx_cbfn->rcb_setup_cbfn; + rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn; + rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn; + rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn; + /* Following callbacks are mandatory */ + rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn; + rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn; + + if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_STARTED) { + switch (rx->type) { + case BNA_RX_T_REGULAR: + if (!(rx->bna->rx_mod.flags & + BNA_RX_MOD_F_PORT_LOOPBACK)) + rx->rx_flags |= BNA_RX_F_PORT_ENABLED; + break; + case BNA_RX_T_LOOPBACK: + if (rx->bna->rx_mod.flags & BNA_RX_MOD_F_PORT_LOOPBACK) + rx->rx_flags |= BNA_RX_F_PORT_ENABLED; + break; + } + } + + for (i = 0, rcb_idx = 0; i < rx_cfg->num_paths; i++) { + rxp = _get_free_rxp(rx_mod); + rxp->type = rx_cfg->rxp_type; + rxp->rx = rx; + rxp->cq.rx = rx; + + /* Get required RXQs, and queue them to rx-path */ + q0 = _get_free_rxq(rx_mod); + if (BNA_RXP_SINGLE == rx_cfg->rxp_type) + q1 = NULL; + else + q1 = _get_free_rxq(rx_mod); + + /* Initialize IB */ + if (1 == intr_info->num) { + rxp->cq.ib = bna_ib_get(&bna->ib_mod, + intr_info->intr_type, + intr_info->idl[0].vector); + rxp->vector = intr_info->idl[0].vector; + } else { + rxp->cq.ib = bna_ib_get(&bna->ib_mod, + intr_info->intr_type, + intr_info->idl[i].vector); + + /* Map the MSI-x vector used for this RXP */ + rxp->vector = intr_info->idl[i].vector; + } + + rxp->cq.ib_seg_offset = bna_ib_reserve_idx(rxp->cq.ib); + + ibcfg.coalescing_timeo = BFI_RX_COALESCING_TIMEO; + ibcfg.interpkt_count = BFI_RX_INTERPKT_COUNT; + ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO; + ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE; + + ret = bna_ib_config(rxp->cq.ib, &ibcfg); + + /* Link rxqs to rxp */ + _rxp_add_rxqs(rxp, q0, q1); + + /* Link rxp to rx */ + _rx_add_rxp(rx, rxp); + + q0->rx = rx; + q0->rxp = rxp; + + /* Initialize RCB for the large / data q */ + q0->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva; + RXQ_RCB_INIT(q0, rxp, rx_cfg->q_depth, bna, 0, + (void *)unmapq_mem[rcb_idx].kva); + rcb_idx++; + (q0)->rx_packets = (q0)->rx_bytes = 0; + (q0)->rx_packets_with_error = (q0)->rxbuf_alloc_failed = 0; + + /* Initialize RXQs */ + _rxq_qpt_init(q0, rxp, dpage_count, PAGE_SIZE, + &dqpt_mem[i], &dsqpt_mem[i], &dpage_mem[dpage_idx]); + q0->rcb->page_idx = dpage_idx; + q0->rcb->page_count = dpage_count; + dpage_idx += dpage_count; + + /* Call bnad to complete rcb setup */ + if (rx->rcb_setup_cbfn) + rx->rcb_setup_cbfn(bnad, q0->rcb); + + if (q1) { + q1->rx = rx; + q1->rxp = rxp; + + q1->rcb = (struct bna_rcb *) rcb_mem[rcb_idx].kva; + RXQ_RCB_INIT(q1, rxp, rx_cfg->q_depth, bna, 1, + (void *)unmapq_mem[rcb_idx].kva); + rcb_idx++; + (q1)->buffer_size = (rx_cfg)->small_buff_size; + (q1)->rx_packets = (q1)->rx_bytes = 0; + (q1)->rx_packets_with_error = + (q1)->rxbuf_alloc_failed = 0; + + _rxq_qpt_init(q1, rxp, hpage_count, PAGE_SIZE, + &hqpt_mem[i], &hsqpt_mem[i], + &hpage_mem[hpage_idx]); + q1->rcb->page_idx = hpage_idx; + q1->rcb->page_count = hpage_count; + hpage_idx += hpage_count; + + /* Call bnad to complete rcb setup */ + if (rx->rcb_setup_cbfn) + rx->rcb_setup_cbfn(bnad, q1->rcb); + } + /* Setup RXP::CQ */ + rxp->cq.ccb = (struct bna_ccb *) ccb_mem[i].kva; + _rxp_cqpt_setup(rxp, page_count, PAGE_SIZE, + &cqpt_mem[i], &cswqpt_mem[i], &cpage_mem[cpage_idx]); + rxp->cq.ccb->page_idx = cpage_idx; + rxp->cq.ccb->page_count = page_count; + cpage_idx += page_count; + + rxp->cq.ccb->pkt_rate.small_pkt_cnt = 0; + rxp->cq.ccb->pkt_rate.large_pkt_cnt = 0; + + rxp->cq.ccb->producer_index = 0; + rxp->cq.ccb->q_depth = rx_cfg->q_depth + + ((rx_cfg->rxp_type == BNA_RXP_SINGLE) ? + 0 : rx_cfg->q_depth); + rxp->cq.ccb->i_dbell = &rxp->cq.ib->door_bell; + rxp->cq.ccb->rcb[0] = q0->rcb; + if (q1) + rxp->cq.ccb->rcb[1] = q1->rcb; + rxp->cq.ccb->cq = &rxp->cq; + rxp->cq.ccb->bnad = bna->bnad; + rxp->cq.ccb->hw_producer_index = + ((volatile u32 *)rxp->cq.ib->ib_seg_host_addr_kva + + (rxp->cq.ib_seg_offset * BFI_IBIDX_SIZE)); + *(rxp->cq.ccb->hw_producer_index) = 0; + rxp->cq.ccb->intr_type = intr_info->intr_type; + rxp->cq.ccb->intr_vector = (intr_info->num == 1) ? + intr_info->idl[0].vector : + intr_info->idl[i].vector; + rxp->cq.ccb->rx_coalescing_timeo = + rxp->cq.ib->ib_config.coalescing_timeo; + rxp->cq.ccb->id = i; + + /* Call bnad to complete CCB setup */ + if (rx->ccb_setup_cbfn) + rx->ccb_setup_cbfn(bnad, rxp->cq.ccb); + + } /* for each rx-path */ + + bna_rxf_init(&rx->rxf, rx, rx_cfg); + + bfa_fsm_set_state(rx, bna_rx_sm_stopped); + + return rx; +} + +void +bna_rx_destroy(struct bna_rx *rx) +{ + struct bna_rx_mod *rx_mod = &rx->bna->rx_mod; + struct bna_ib_mod *ib_mod = &rx->bna->ib_mod; + struct bna_rxq *q0 = NULL; + struct bna_rxq *q1 = NULL; + struct bna_rxp *rxp; + struct list_head *qe; + + bna_rxf_uninit(&rx->rxf); + + while (!list_empty(&rx->rxp_q)) { + bfa_q_deq(&rx->rxp_q, &rxp); + GET_RXQS(rxp, q0, q1); + /* Callback to bnad for destroying RCB */ + if (rx->rcb_destroy_cbfn) + rx->rcb_destroy_cbfn(rx->bna->bnad, q0->rcb); + q0->rcb = NULL; + q0->rxp = NULL; + q0->rx = NULL; + _put_free_rxq(rx_mod, q0); + if (q1) { + /* Callback to bnad for destroying RCB */ + if (rx->rcb_destroy_cbfn) + rx->rcb_destroy_cbfn(rx->bna->bnad, q1->rcb); + q1->rcb = NULL; + q1->rxp = NULL; + q1->rx = NULL; + _put_free_rxq(rx_mod, q1); + } + rxp->rxq.slr.large = NULL; + rxp->rxq.slr.small = NULL; + if (rxp->cq.ib) { + if (rxp->cq.ib_seg_offset != 0xff) + bna_ib_release_idx(rxp->cq.ib, + rxp->cq.ib_seg_offset); + bna_ib_put(ib_mod, rxp->cq.ib); + rxp->cq.ib = NULL; + } + /* Callback to bnad for destroying CCB */ + if (rx->ccb_destroy_cbfn) + rx->ccb_destroy_cbfn(rx->bna->bnad, rxp->cq.ccb); + rxp->cq.ccb = NULL; + rxp->rx = NULL; + _put_free_rxp(rx_mod, rxp); + } + + list_for_each(qe, &rx_mod->rx_active_q) { + if (qe == &rx->qe) { + list_del(&rx->qe); + bfa_q_qe_init(&rx->qe); + break; + } + } + + rx->bna = NULL; + rx->priv = NULL; + _put_free_rx(rx_mod, rx); +} + +void +bna_rx_enable(struct bna_rx *rx) +{ + if (rx->fsm != (bfa_sm_t)bna_rx_sm_stopped) + return; + + rx->rx_flags |= BNA_RX_F_ENABLE; + if (rx->rx_flags & BNA_RX_F_PORT_ENABLED) + bfa_fsm_send_event(rx, RX_E_START); +} + +void +bna_rx_disable(struct bna_rx *rx, enum bna_cleanup_type type, + void (*cbfn)(void *, struct bna_rx *, + enum bna_cb_status)) +{ + if (type == BNA_SOFT_CLEANUP) { + /* h/w should not be accessed. Treat we're stopped */ + (*cbfn)(rx->bna->bnad, rx, BNA_CB_SUCCESS); + } else { + rx->stop_cbfn = cbfn; + rx->stop_cbarg = rx->bna->bnad; + + rx->rx_flags &= ~BNA_RX_F_ENABLE; + + bfa_fsm_send_event(rx, RX_E_STOP); + } +} + +/** + * TX + */ +#define call_tx_stop_cbfn(tx, status)\ +do {\ + if ((tx)->stop_cbfn)\ + (tx)->stop_cbfn((tx)->stop_cbarg, (tx), status);\ + (tx)->stop_cbfn = NULL;\ + (tx)->stop_cbarg = NULL;\ +} while (0) + +#define call_tx_prio_change_cbfn(tx, status)\ +do {\ + if ((tx)->prio_change_cbfn)\ + (tx)->prio_change_cbfn((tx)->bna->bnad, (tx), status);\ + (tx)->prio_change_cbfn = NULL;\ +} while (0) + +static void bna_tx_mod_cb_tx_stopped(void *tx_mod, struct bna_tx *tx, + enum bna_cb_status status); +static void bna_tx_cb_txq_stopped(void *arg, int status); +static void bna_tx_cb_stats_cleared(void *arg, int status); +static void __bna_tx_stop(struct bna_tx *tx); +static void __bna_tx_start(struct bna_tx *tx); +static void __bna_txf_stat_clr(struct bna_tx *tx); + +enum bna_tx_event { + TX_E_START = 1, + TX_E_STOP = 2, + TX_E_FAIL = 3, + TX_E_TXQ_STOPPED = 4, + TX_E_PRIO_CHANGE = 5, + TX_E_STAT_CLEARED = 6, +}; + +enum bna_tx_state { + BNA_TX_STOPPED = 1, + BNA_TX_STARTED = 2, + BNA_TX_TXQ_STOP_WAIT = 3, + BNA_TX_PRIO_STOP_WAIT = 4, + BNA_TX_STAT_CLR_WAIT = 5, +}; + +bfa_fsm_state_decl(bna_tx, stopped, struct bna_tx, + enum bna_tx_event); +bfa_fsm_state_decl(bna_tx, started, struct bna_tx, + enum bna_tx_event); +bfa_fsm_state_decl(bna_tx, txq_stop_wait, struct bna_tx, + enum bna_tx_event); +bfa_fsm_state_decl(bna_tx, prio_stop_wait, struct bna_tx, + enum bna_tx_event); +bfa_fsm_state_decl(bna_tx, stat_clr_wait, struct bna_tx, + enum bna_tx_event); + +static struct bfa_sm_table tx_sm_table[] = { + {BFA_SM(bna_tx_sm_stopped), BNA_TX_STOPPED}, + {BFA_SM(bna_tx_sm_started), BNA_TX_STARTED}, + {BFA_SM(bna_tx_sm_txq_stop_wait), BNA_TX_TXQ_STOP_WAIT}, + {BFA_SM(bna_tx_sm_prio_stop_wait), BNA_TX_PRIO_STOP_WAIT}, + {BFA_SM(bna_tx_sm_stat_clr_wait), BNA_TX_STAT_CLR_WAIT}, +}; + +static void +bna_tx_sm_stopped_entry(struct bna_tx *tx) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb); + } + + call_tx_stop_cbfn(tx, BNA_CB_SUCCESS); +} + +static void +bna_tx_sm_stopped(struct bna_tx *tx, enum bna_tx_event event) +{ + switch (event) { + case TX_E_START: + bfa_fsm_set_state(tx, bna_tx_sm_started); + break; + + case TX_E_STOP: + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + case TX_E_FAIL: + /* No-op */ + break; + + case TX_E_PRIO_CHANGE: + call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS); + break; + + case TX_E_TXQ_STOPPED: + /** + * This event is received due to flushing of mbox when + * device fails + */ + /* No-op */ + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +bna_tx_sm_started_entry(struct bna_tx *tx) +{ + struct bna_txq *txq; + struct list_head *qe; + + __bna_tx_start(tx); + + /* Start IB */ + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_ack(&txq->ib->door_bell, 0); + } +} + +static void +bna_tx_sm_started(struct bna_tx *tx, enum bna_tx_event event) +{ + struct bna_txq *txq; + struct list_head *qe; + + switch (event) { + case TX_E_STOP: + bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait); + __bna_tx_stop(tx); + break; + + case TX_E_FAIL: + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_fail(txq->ib); + (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb); + } + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + case TX_E_PRIO_CHANGE: + bfa_fsm_set_state(tx, bna_tx_sm_prio_stop_wait); + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +bna_tx_sm_txq_stop_wait_entry(struct bna_tx *tx) +{ +} + +static void +bna_tx_sm_txq_stop_wait(struct bna_tx *tx, enum bna_tx_event event) +{ + struct bna_txq *txq; + struct list_head *qe; + + switch (event) { + case TX_E_FAIL: + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + case TX_E_TXQ_STOPPED: + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_stop(txq->ib); + } + bfa_fsm_set_state(tx, bna_tx_sm_stat_clr_wait); + break; + + case TX_E_PRIO_CHANGE: + /* No-op */ + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +bna_tx_sm_prio_stop_wait_entry(struct bna_tx *tx) +{ + __bna_tx_stop(tx); +} + +static void +bna_tx_sm_prio_stop_wait(struct bna_tx *tx, enum bna_tx_event event) +{ + struct bna_txq *txq; + struct list_head *qe; + + switch (event) { + case TX_E_STOP: + bfa_fsm_set_state(tx, bna_tx_sm_txq_stop_wait); + break; + + case TX_E_FAIL: + call_tx_prio_change_cbfn(tx, BNA_CB_FAIL); + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + case TX_E_TXQ_STOPPED: + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_stop(txq->ib); + (tx->tx_cleanup_cbfn)(tx->bna->bnad, txq->tcb); + } + call_tx_prio_change_cbfn(tx, BNA_CB_SUCCESS); + bfa_fsm_set_state(tx, bna_tx_sm_started); + break; + + case TX_E_PRIO_CHANGE: + /* No-op */ + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +bna_tx_sm_stat_clr_wait_entry(struct bna_tx *tx) +{ + __bna_txf_stat_clr(tx); +} + +static void +bna_tx_sm_stat_clr_wait(struct bna_tx *tx, enum bna_tx_event event) +{ + switch (event) { + case TX_E_FAIL: + case TX_E_STAT_CLEARED: + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + break; + + default: + bfa_sm_fault(tx->bna, event); + } +} + +static void +__bna_txq_start(struct bna_tx *tx, struct bna_txq *txq) +{ + struct bna_rxtx_q_mem *q_mem; + struct bna_txq_mem txq_cfg; + struct bna_txq_mem *txq_mem; + struct bna_dma_addr cur_q_addr; + u32 pg_num; + void __iomem *base_addr; + unsigned long off; + + /* Fill out structure, to be subsequently written to hardware */ + txq_cfg.pg_tbl_addr_lo = txq->qpt.hw_qpt_ptr.lsb; + txq_cfg.pg_tbl_addr_hi = txq->qpt.hw_qpt_ptr.msb; + cur_q_addr = *((struct bna_dma_addr *)(txq->qpt.kv_qpt_ptr)); + txq_cfg.cur_q_entry_lo = cur_q_addr.lsb; + txq_cfg.cur_q_entry_hi = cur_q_addr.msb; + + txq_cfg.pg_cnt_n_prd_ptr = (txq->qpt.page_count << 16) | 0x0; + + txq_cfg.entry_n_pg_size = ((u32)(BFI_TXQ_WI_SIZE >> 2) << 16) | + (txq->qpt.page_size >> 2); + txq_cfg.int_blk_n_cns_ptr = ((((u32)txq->ib_seg_offset) << 24) | + ((u32)(txq->ib->ib_id & 0xff) << 16) | 0x0); + + txq_cfg.cns_ptr2_n_q_state = BNA_Q_IDLE_STATE; + txq_cfg.nxt_qid_n_fid_n_pri = (((tx->txf.txf_id & 0x3f) << 3) | + (txq->priority & 0x3)); + txq_cfg.wvc_n_cquota_n_rquota = + ((((u32)BFI_TX_MAX_WRR_QUOTA & 0xfff) << 12) | + (BFI_TX_MAX_WRR_QUOTA & 0xfff)); + + /* Setup the page and write to H/W */ + + pg_num = BNA_GET_PAGE_NUM(HQM0_BLK_PG_NUM + tx->bna->port_num, + HQM_RXTX_Q_RAM_BASE_OFFSET); + writel(pg_num, tx->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva, + HQM_RXTX_Q_RAM_BASE_OFFSET); + q_mem = (struct bna_rxtx_q_mem *)0; + txq_mem = &q_mem[txq->txq_id].txq; + + /* + * The following 4 lines, is a hack b'cos the H/W needs to read + * these DMA addresses as little endian + */ + + off = (unsigned long)&txq_mem->pg_tbl_addr_lo; + writel(htonl(txq_cfg.pg_tbl_addr_lo), base_addr + off); + + off = (unsigned long)&txq_mem->pg_tbl_addr_hi; + writel(htonl(txq_cfg.pg_tbl_addr_hi), base_addr + off); + + off = (unsigned long)&txq_mem->cur_q_entry_lo; + writel(htonl(txq_cfg.cur_q_entry_lo), base_addr + off); + + off = (unsigned long)&txq_mem->cur_q_entry_hi; + writel(htonl(txq_cfg.cur_q_entry_hi), base_addr + off); + + off = (unsigned long)&txq_mem->pg_cnt_n_prd_ptr; + writel(txq_cfg.pg_cnt_n_prd_ptr, base_addr + off); + + off = (unsigned long)&txq_mem->entry_n_pg_size; + writel(txq_cfg.entry_n_pg_size, base_addr + off); + + off = (unsigned long)&txq_mem->int_blk_n_cns_ptr; + writel(txq_cfg.int_blk_n_cns_ptr, base_addr + off); + + off = (unsigned long)&txq_mem->cns_ptr2_n_q_state; + writel(txq_cfg.cns_ptr2_n_q_state, base_addr + off); + + off = (unsigned long)&txq_mem->nxt_qid_n_fid_n_pri; + writel(txq_cfg.nxt_qid_n_fid_n_pri, base_addr + off); + + off = (unsigned long)&txq_mem->wvc_n_cquota_n_rquota; + writel(txq_cfg.wvc_n_cquota_n_rquota, base_addr + off); + + txq->tcb->producer_index = 0; + txq->tcb->consumer_index = 0; + *(txq->tcb->hw_consumer_index) = 0; + +} + +static void +__bna_txq_stop(struct bna_tx *tx, struct bna_txq *txq) +{ + struct bfi_ll_q_stop_req ll_req; + u32 bit_mask[2] = {0, 0}; + if (txq->txq_id < 32) + bit_mask[0] = (u32)1 << txq->txq_id; + else + bit_mask[1] = (u32)1 << (txq->txq_id - 32); + + memset(&ll_req, 0, sizeof(ll_req)); + ll_req.mh.msg_class = BFI_MC_LL; + ll_req.mh.msg_id = BFI_LL_H2I_TXQ_STOP_REQ; + ll_req.mh.mtag.h2i.lpu_id = 0; + ll_req.q_id_mask[0] = htonl(bit_mask[0]); + ll_req.q_id_mask[1] = htonl(bit_mask[1]); + + bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req), + bna_tx_cb_txq_stopped, tx); + + bna_mbox_send(tx->bna, &tx->mbox_qe); +} + +static void +__bna_txf_start(struct bna_tx *tx) +{ + struct bna_tx_fndb_ram *tx_fndb; + struct bna_txf *txf = &tx->txf; + void __iomem *base_addr; + unsigned long off; + + writel(BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM + + (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET), + tx->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva, + TX_FNDB_RAM_BASE_OFFSET); + + tx_fndb = (struct bna_tx_fndb_ram *)0; + off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags; + + writel(((u32)txf->vlan << 16) | txf->ctrl_flags, + base_addr + off); + + if (tx->txf.txf_id < 32) + tx->bna->tx_mod.txf_bmap[0] |= ((u32)1 << tx->txf.txf_id); + else + tx->bna->tx_mod.txf_bmap[1] |= ((u32) + 1 << (tx->txf.txf_id - 32)); +} + +static void +__bna_txf_stop(struct bna_tx *tx) +{ + struct bna_tx_fndb_ram *tx_fndb; + u32 page_num; + u32 ctl_flags; + struct bna_txf *txf = &tx->txf; + void __iomem *base_addr; + unsigned long off; + + /* retrieve the running txf_flags & turn off enable bit */ + page_num = BNA_GET_PAGE_NUM(LUT0_MEM_BLK_BASE_PG_NUM + + (tx->bna->port_num * 2), TX_FNDB_RAM_BASE_OFFSET); + writel(page_num, tx->bna->regs.page_addr); + + base_addr = BNA_GET_MEM_BASE_ADDR(tx->bna->pcidev.pci_bar_kva, + TX_FNDB_RAM_BASE_OFFSET); + tx_fndb = (struct bna_tx_fndb_ram *)0; + off = (unsigned long)&tx_fndb[txf->txf_id].vlan_n_ctrl_flags; + + ctl_flags = readl(base_addr + off); + ctl_flags &= ~BFI_TXF_CF_ENABLE; + + writel(ctl_flags, base_addr + off); + + if (tx->txf.txf_id < 32) + tx->bna->tx_mod.txf_bmap[0] &= ~((u32)1 << tx->txf.txf_id); + else + tx->bna->tx_mod.txf_bmap[0] &= ~((u32) + 1 << (tx->txf.txf_id - 32)); +} + +static void +__bna_txf_stat_clr(struct bna_tx *tx) +{ + struct bfi_ll_stats_req ll_req; + u32 txf_bmap[2] = {0, 0}; + if (tx->txf.txf_id < 32) + txf_bmap[0] = ((u32)1 << tx->txf.txf_id); + else + txf_bmap[1] = ((u32)1 << (tx->txf.txf_id - 32)); + bfi_h2i_set(ll_req.mh, BFI_MC_LL, BFI_LL_H2I_STATS_CLEAR_REQ, 0); + ll_req.stats_mask = 0; + ll_req.rxf_id_mask[0] = 0; + ll_req.rxf_id_mask[1] = 0; + ll_req.txf_id_mask[0] = htonl(txf_bmap[0]); + ll_req.txf_id_mask[1] = htonl(txf_bmap[1]); + + bna_mbox_qe_fill(&tx->mbox_qe, &ll_req, sizeof(ll_req), + bna_tx_cb_stats_cleared, tx); + bna_mbox_send(tx->bna, &tx->mbox_qe); +} + +static void +__bna_tx_start(struct bna_tx *tx) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bna_ib_start(txq->ib); + __bna_txq_start(tx, txq); + } + + __bna_txf_start(tx); + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + txq->tcb->priority = txq->priority; + (tx->tx_resume_cbfn)(tx->bna->bnad, txq->tcb); + } +} + +static void +__bna_tx_stop(struct bna_tx *tx) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + (tx->tx_stall_cbfn)(tx->bna->bnad, txq->tcb); + } + + __bna_txf_stop(tx); + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + bfa_wc_up(&tx->txq_stop_wc); + } + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + __bna_txq_stop(tx, txq); + } +} + +static void +bna_txq_qpt_setup(struct bna_txq *txq, int page_count, int page_size, + struct bna_mem_descr *qpt_mem, + struct bna_mem_descr *swqpt_mem, + struct bna_mem_descr *page_mem) +{ + int i; + + txq->qpt.hw_qpt_ptr.lsb = qpt_mem->dma.lsb; + txq->qpt.hw_qpt_ptr.msb = qpt_mem->dma.msb; + txq->qpt.kv_qpt_ptr = qpt_mem->kva; + txq->qpt.page_count = page_count; + txq->qpt.page_size = page_size; + + txq->tcb->sw_qpt = (void **) swqpt_mem->kva; + + for (i = 0; i < page_count; i++) { + txq->tcb->sw_qpt[i] = page_mem[i].kva; + + ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].lsb = + page_mem[i].dma.lsb; + ((struct bna_dma_addr *)txq->qpt.kv_qpt_ptr)[i].msb = + page_mem[i].dma.msb; + + } +} + +static void +bna_tx_free(struct bna_tx *tx) +{ + struct bna_tx_mod *tx_mod = &tx->bna->tx_mod; + struct bna_txq *txq; + struct bna_ib_mod *ib_mod = &tx->bna->ib_mod; + struct list_head *qe; + + while (!list_empty(&tx->txq_q)) { + bfa_q_deq(&tx->txq_q, &txq); + bfa_q_qe_init(&txq->qe); + if (txq->ib) { + if (txq->ib_seg_offset != -1) + bna_ib_release_idx(txq->ib, + txq->ib_seg_offset); + bna_ib_put(ib_mod, txq->ib); + txq->ib = NULL; + } + txq->tcb = NULL; + txq->tx = NULL; + list_add_tail(&txq->qe, &tx_mod->txq_free_q); + } + + list_for_each(qe, &tx_mod->tx_active_q) { + if (qe == &tx->qe) { + list_del(&tx->qe); + bfa_q_qe_init(&tx->qe); + break; + } + } + + tx->bna = NULL; + tx->priv = NULL; + list_add_tail(&tx->qe, &tx_mod->tx_free_q); +} + +static void +bna_tx_cb_txq_stopped(void *arg, int status) +{ + struct bna_tx *tx = (struct bna_tx *)arg; + + bfa_q_qe_init(&tx->mbox_qe.qe); + bfa_wc_down(&tx->txq_stop_wc); +} + +static void +bna_tx_cb_txq_stopped_all(void *arg) +{ + struct bna_tx *tx = (struct bna_tx *)arg; + + bfa_fsm_send_event(tx, TX_E_TXQ_STOPPED); +} + +static void +bna_tx_cb_stats_cleared(void *arg, int status) +{ + struct bna_tx *tx = (struct bna_tx *)arg; + + bfa_q_qe_init(&tx->mbox_qe.qe); + + bfa_fsm_send_event(tx, TX_E_STAT_CLEARED); +} + +static void +bna_tx_start(struct bna_tx *tx) +{ + tx->flags |= BNA_TX_F_PORT_STARTED; + if (tx->flags & BNA_TX_F_ENABLED) + bfa_fsm_send_event(tx, TX_E_START); +} + +static void +bna_tx_stop(struct bna_tx *tx) +{ + tx->stop_cbfn = bna_tx_mod_cb_tx_stopped; + tx->stop_cbarg = &tx->bna->tx_mod; + + tx->flags &= ~BNA_TX_F_PORT_STARTED; + bfa_fsm_send_event(tx, TX_E_STOP); +} + +static void +bna_tx_fail(struct bna_tx *tx) +{ + tx->flags &= ~BNA_TX_F_PORT_STARTED; + bfa_fsm_send_event(tx, TX_E_FAIL); +} + +static void +bna_tx_prio_changed(struct bna_tx *tx, int prio) +{ + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + txq->priority = prio; + } + + bfa_fsm_send_event(tx, TX_E_PRIO_CHANGE); +} + +static void +bna_tx_cee_link_status(struct bna_tx *tx, int cee_link) +{ + if (cee_link) + tx->flags |= BNA_TX_F_PRIO_LOCK; + else + tx->flags &= ~BNA_TX_F_PRIO_LOCK; +} + +static void +bna_tx_mod_cb_tx_stopped(void *arg, struct bna_tx *tx, + enum bna_cb_status status) +{ + struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg; + + bfa_wc_down(&tx_mod->tx_stop_wc); +} + +static void +bna_tx_mod_cb_tx_stopped_all(void *arg) +{ + struct bna_tx_mod *tx_mod = (struct bna_tx_mod *)arg; + + if (tx_mod->stop_cbfn) + tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS); + tx_mod->stop_cbfn = NULL; +} + +void +bna_tx_res_req(int num_txq, int txq_depth, struct bna_res_info *res_info) +{ + u32 q_size; + u32 page_count; + struct bna_mem_info *mem_info; + + res_info[BNA_TX_RES_MEM_T_TCB].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = sizeof(struct bna_tcb); + mem_info->num = num_txq; + + q_size = txq_depth * BFI_TXQ_WI_SIZE; + q_size = ALIGN(q_size, PAGE_SIZE); + page_count = q_size >> PAGE_SHIFT; + + res_info[BNA_TX_RES_MEM_T_QPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = page_count * sizeof(struct bna_dma_addr); + mem_info->num = num_txq; + + res_info[BNA_TX_RES_MEM_T_SWQPT].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_KVA; + mem_info->len = page_count * sizeof(void *); + mem_info->num = num_txq; + + res_info[BNA_TX_RES_MEM_T_PAGE].res_type = BNA_RES_T_MEM; + mem_info = &res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info; + mem_info->mem_type = BNA_MEM_T_DMA; + mem_info->len = PAGE_SIZE; + mem_info->num = num_txq * page_count; + + res_info[BNA_TX_RES_INTR_T_TXCMPL].res_type = BNA_RES_T_INTR; + res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.intr_type = + BNA_INTR_T_MSIX; + res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info.num = num_txq; +} + +struct bna_tx * +bna_tx_create(struct bna *bna, struct bnad *bnad, + struct bna_tx_config *tx_cfg, + struct bna_tx_event_cbfn *tx_cbfn, + struct bna_res_info *res_info, void *priv) +{ + struct bna_intr_info *intr_info; + struct bna_tx_mod *tx_mod = &bna->tx_mod; + struct bna_tx *tx; + struct bna_txq *txq; + struct list_head *qe; + struct bna_ib_mod *ib_mod = &bna->ib_mod; + struct bna_doorbell_qset *qset; + struct bna_ib_config ib_config; + int page_count; + int page_size; + int page_idx; + int i; + unsigned long off; + + intr_info = &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info; + page_count = (res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.num) / + tx_cfg->num_txq; + page_size = res_info[BNA_TX_RES_MEM_T_PAGE].res_u.mem_info.len; + + /** + * Get resources + */ + + if ((intr_info->num != 1) && (intr_info->num != tx_cfg->num_txq)) + return NULL; + + /* Tx */ + + if (list_empty(&tx_mod->tx_free_q)) + return NULL; + bfa_q_deq(&tx_mod->tx_free_q, &tx); + bfa_q_qe_init(&tx->qe); + + /* TxQs */ + + INIT_LIST_HEAD(&tx->txq_q); + for (i = 0; i < tx_cfg->num_txq; i++) { + if (list_empty(&tx_mod->txq_free_q)) + goto err_return; + + bfa_q_deq(&tx_mod->txq_free_q, &txq); + bfa_q_qe_init(&txq->qe); + list_add_tail(&txq->qe, &tx->txq_q); + txq->ib = NULL; + txq->ib_seg_offset = -1; + txq->tx = tx; + } + + /* IBs */ + i = 0; + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + + if (intr_info->num == 1) + txq->ib = bna_ib_get(ib_mod, intr_info->intr_type, + intr_info->idl[0].vector); + else + txq->ib = bna_ib_get(ib_mod, intr_info->intr_type, + intr_info->idl[i].vector); + + if (txq->ib == NULL) + goto err_return; + + txq->ib_seg_offset = bna_ib_reserve_idx(txq->ib); + if (txq->ib_seg_offset == -1) + goto err_return; + + i++; + } + + /* + * Initialize + */ + + /* Tx */ + + tx->tcb_setup_cbfn = tx_cbfn->tcb_setup_cbfn; + tx->tcb_destroy_cbfn = tx_cbfn->tcb_destroy_cbfn; + /* Following callbacks are mandatory */ + tx->tx_stall_cbfn = tx_cbfn->tx_stall_cbfn; + tx->tx_resume_cbfn = tx_cbfn->tx_resume_cbfn; + tx->tx_cleanup_cbfn = tx_cbfn->tx_cleanup_cbfn; + + list_add_tail(&tx->qe, &tx_mod->tx_active_q); + tx->bna = bna; + tx->priv = priv; + tx->txq_stop_wc.wc_resume = bna_tx_cb_txq_stopped_all; + tx->txq_stop_wc.wc_cbarg = tx; + tx->txq_stop_wc.wc_count = 0; + + tx->type = tx_cfg->tx_type; + + tx->flags = 0; + if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_STARTED) { + switch (tx->type) { + case BNA_TX_T_REGULAR: + if (!(tx->bna->tx_mod.flags & + BNA_TX_MOD_F_PORT_LOOPBACK)) + tx->flags |= BNA_TX_F_PORT_STARTED; + break; + case BNA_TX_T_LOOPBACK: + if (tx->bna->tx_mod.flags & BNA_TX_MOD_F_PORT_LOOPBACK) + tx->flags |= BNA_TX_F_PORT_STARTED; + break; + } + } + if (tx->bna->tx_mod.cee_link) + tx->flags |= BNA_TX_F_PRIO_LOCK; + + /* TxQ */ + + i = 0; + page_idx = 0; + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + txq->priority = tx_mod->priority; + txq->tcb = (struct bna_tcb *) + res_info[BNA_TX_RES_MEM_T_TCB].res_u.mem_info.mdl[i].kva; + txq->tx_packets = 0; + txq->tx_bytes = 0; + + /* IB */ + + ib_config.coalescing_timeo = BFI_TX_COALESCING_TIMEO; + ib_config.interpkt_timeo = 0; /* Not used */ + ib_config.interpkt_count = BFI_TX_INTERPKT_COUNT; + ib_config.ctrl_flags = (BFI_IB_CF_INTER_PKT_DMA | + BFI_IB_CF_INT_ENABLE | + BFI_IB_CF_COALESCING_MODE); + bna_ib_config(txq->ib, &ib_config); + + /* TCB */ + + txq->tcb->producer_index = 0; + txq->tcb->consumer_index = 0; + txq->tcb->hw_consumer_index = (volatile u32 *) + ((volatile u8 *)txq->ib->ib_seg_host_addr_kva + + (txq->ib_seg_offset * BFI_IBIDX_SIZE)); + *(txq->tcb->hw_consumer_index) = 0; + txq->tcb->q_depth = tx_cfg->txq_depth; + txq->tcb->unmap_q = (void *) + res_info[BNA_TX_RES_MEM_T_UNMAPQ].res_u.mem_info.mdl[i].kva; + qset = (struct bna_doorbell_qset *)0; + off = (unsigned long)&qset[txq->txq_id].txq[0]; + txq->tcb->q_dbell = off + + BNA_GET_DOORBELL_BASE_ADDR(bna->pcidev.pci_bar_kva); + txq->tcb->i_dbell = &txq->ib->door_bell; + txq->tcb->intr_type = intr_info->intr_type; + txq->tcb->intr_vector = (intr_info->num == 1) ? + intr_info->idl[0].vector : + intr_info->idl[i].vector; + txq->tcb->txq = txq; + txq->tcb->bnad = bnad; + txq->tcb->id = i; + + /* QPT, SWQPT, Pages */ + bna_txq_qpt_setup(txq, page_count, page_size, + &res_info[BNA_TX_RES_MEM_T_QPT].res_u.mem_info.mdl[i], + &res_info[BNA_TX_RES_MEM_T_SWQPT].res_u.mem_info.mdl[i], + &res_info[BNA_TX_RES_MEM_T_PAGE]. + res_u.mem_info.mdl[page_idx]); + txq->tcb->page_idx = page_idx; + txq->tcb->page_count = page_count; + page_idx += page_count; + + /* Callback to bnad for setting up TCB */ + if (tx->tcb_setup_cbfn) + (tx->tcb_setup_cbfn)(bna->bnad, txq->tcb); + + i++; + } + + /* TxF */ + + tx->txf.ctrl_flags = BFI_TXF_CF_ENABLE | BFI_TXF_CF_VLAN_WI_BASED; + tx->txf.vlan = 0; + + /* Mbox element */ + bfa_q_qe_init(&tx->mbox_qe.qe); + + bfa_fsm_set_state(tx, bna_tx_sm_stopped); + + return tx; + +err_return: + bna_tx_free(tx); + return NULL; +} + +void +bna_tx_destroy(struct bna_tx *tx) +{ + /* Callback to bnad for destroying TCB */ + if (tx->tcb_destroy_cbfn) { + struct bna_txq *txq; + struct list_head *qe; + + list_for_each(qe, &tx->txq_q) { + txq = (struct bna_txq *)qe; + (tx->tcb_destroy_cbfn)(tx->bna->bnad, txq->tcb); + } + } + + bna_tx_free(tx); +} + +void +bna_tx_enable(struct bna_tx *tx) +{ + if (tx->fsm != (bfa_sm_t)bna_tx_sm_stopped) + return; + + tx->flags |= BNA_TX_F_ENABLED; + + if (tx->flags & BNA_TX_F_PORT_STARTED) + bfa_fsm_send_event(tx, TX_E_START); +} + +void +bna_tx_disable(struct bna_tx *tx, enum bna_cleanup_type type, + void (*cbfn)(void *, struct bna_tx *, enum bna_cb_status)) +{ + if (type == BNA_SOFT_CLEANUP) { + (*cbfn)(tx->bna->bnad, tx, BNA_CB_SUCCESS); + return; + } + + tx->stop_cbfn = cbfn; + tx->stop_cbarg = tx->bna->bnad; + + tx->flags &= ~BNA_TX_F_ENABLED; + + bfa_fsm_send_event(tx, TX_E_STOP); +} + +int +bna_tx_state_get(struct bna_tx *tx) +{ + return bfa_sm_to_state(tx_sm_table, tx->fsm); +} + +void +bna_tx_mod_init(struct bna_tx_mod *tx_mod, struct bna *bna, + struct bna_res_info *res_info) +{ + int i; + + tx_mod->bna = bna; + tx_mod->flags = 0; + + tx_mod->tx = (struct bna_tx *) + res_info[BNA_RES_MEM_T_TX_ARRAY].res_u.mem_info.mdl[0].kva; + tx_mod->txq = (struct bna_txq *) + res_info[BNA_RES_MEM_T_TXQ_ARRAY].res_u.mem_info.mdl[0].kva; + + INIT_LIST_HEAD(&tx_mod->tx_free_q); + INIT_LIST_HEAD(&tx_mod->tx_active_q); + + INIT_LIST_HEAD(&tx_mod->txq_free_q); + + for (i = 0; i < BFI_MAX_TXQ; i++) { + tx_mod->tx[i].txf.txf_id = i; + bfa_q_qe_init(&tx_mod->tx[i].qe); + list_add_tail(&tx_mod->tx[i].qe, &tx_mod->tx_free_q); + + tx_mod->txq[i].txq_id = i; + bfa_q_qe_init(&tx_mod->txq[i].qe); + list_add_tail(&tx_mod->txq[i].qe, &tx_mod->txq_free_q); + } + + tx_mod->tx_stop_wc.wc_resume = bna_tx_mod_cb_tx_stopped_all; + tx_mod->tx_stop_wc.wc_cbarg = tx_mod; + tx_mod->tx_stop_wc.wc_count = 0; +} + +void +bna_tx_mod_uninit(struct bna_tx_mod *tx_mod) +{ + struct list_head *qe; + int i; + + i = 0; + list_for_each(qe, &tx_mod->tx_free_q) + i++; + + i = 0; + list_for_each(qe, &tx_mod->txq_free_q) + i++; + + tx_mod->bna = NULL; +} + +void +bna_tx_mod_start(struct bna_tx_mod *tx_mod, enum bna_tx_type type) +{ + struct bna_tx *tx; + struct list_head *qe; + + tx_mod->flags |= BNA_TX_MOD_F_PORT_STARTED; + if (type == BNA_TX_T_LOOPBACK) + tx_mod->flags |= BNA_TX_MOD_F_PORT_LOOPBACK; + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + if (tx->type == type) + bna_tx_start(tx); + } +} + +void +bna_tx_mod_stop(struct bna_tx_mod *tx_mod, enum bna_tx_type type) +{ + struct bna_tx *tx; + struct list_head *qe; + + tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED; + tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK; + + tx_mod->stop_cbfn = bna_port_cb_tx_stopped; + + /** + * Before calling bna_tx_stop(), increment tx_stop_wc as many times + * as we are going to call bna_tx_stop + */ + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + if (tx->type == type) + bfa_wc_up(&tx_mod->tx_stop_wc); + } + + if (tx_mod->tx_stop_wc.wc_count == 0) { + tx_mod->stop_cbfn(&tx_mod->bna->port, BNA_CB_SUCCESS); + tx_mod->stop_cbfn = NULL; + return; + } + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + if (tx->type == type) + bna_tx_stop(tx); + } +} + +void +bna_tx_mod_fail(struct bna_tx_mod *tx_mod) +{ + struct bna_tx *tx; + struct list_head *qe; + + tx_mod->flags &= ~BNA_TX_MOD_F_PORT_STARTED; + tx_mod->flags &= ~BNA_TX_MOD_F_PORT_LOOPBACK; + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + bna_tx_fail(tx); + } +} + +void +bna_tx_mod_prio_changed(struct bna_tx_mod *tx_mod, int prio) +{ + struct bna_tx *tx; + struct list_head *qe; + + if (prio != tx_mod->priority) { + tx_mod->priority = prio; + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + bna_tx_prio_changed(tx, prio); + } + } +} + +void +bna_tx_mod_cee_link_status(struct bna_tx_mod *tx_mod, int cee_link) +{ + struct bna_tx *tx; + struct list_head *qe; + + tx_mod->cee_link = cee_link; + + list_for_each(qe, &tx_mod->tx_active_q) { + tx = (struct bna_tx *)qe; + bna_tx_cee_link_status(tx, cee_link); + } +} diff --git a/drivers/net/bna/bna_types.h b/drivers/net/bna/bna_types.h new file mode 100644 index 0000000000000000000000000000000000000000..6877310f6ef4acffbfca169a94258862f3d257eb --- /dev/null +++ b/drivers/net/bna/bna_types.h @@ -0,0 +1,1128 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BNA_TYPES_H__ +#define __BNA_TYPES_H__ + +#include "cna.h" +#include "bna_hw.h" +#include "bfa_cee.h" + +/** + * + * Forward declarations + * + */ + +struct bna_txq; +struct bna_tx; +struct bna_rxq; +struct bna_cq; +struct bna_rx; +struct bna_rxf; +struct bna_port; +struct bna; +struct bnad; + +/** + * + * Enums, primitive data types + * + */ + +enum bna_status { + BNA_STATUS_T_DISABLED = 0, + BNA_STATUS_T_ENABLED = 1 +}; + +enum bna_cleanup_type { + BNA_HARD_CLEANUP = 0, + BNA_SOFT_CLEANUP = 1 +}; + +enum bna_cb_status { + BNA_CB_SUCCESS = 0, + BNA_CB_FAIL = 1, + BNA_CB_INTERRUPT = 2, + BNA_CB_BUSY = 3, + BNA_CB_INVALID_MAC = 4, + BNA_CB_MCAST_LIST_FULL = 5, + BNA_CB_UCAST_CAM_FULL = 6, + BNA_CB_WAITING = 7, + BNA_CB_NOT_EXEC = 8 +}; + +enum bna_res_type { + BNA_RES_T_MEM = 1, + BNA_RES_T_INTR = 2 +}; + +enum bna_mem_type { + BNA_MEM_T_KVA = 1, + BNA_MEM_T_DMA = 2 +}; + +enum bna_intr_type { + BNA_INTR_T_INTX = 1, + BNA_INTR_T_MSIX = 2 +}; + +enum bna_res_req_type { + BNA_RES_MEM_T_COM = 0, + BNA_RES_MEM_T_ATTR = 1, + BNA_RES_MEM_T_FWTRC = 2, + BNA_RES_MEM_T_STATS = 3, + BNA_RES_MEM_T_SWSTATS = 4, + BNA_RES_MEM_T_IBIDX = 5, + BNA_RES_MEM_T_IB_ARRAY = 6, + BNA_RES_MEM_T_INTR_ARRAY = 7, + BNA_RES_MEM_T_IDXSEG_ARRAY = 8, + BNA_RES_MEM_T_TX_ARRAY = 9, + BNA_RES_MEM_T_TXQ_ARRAY = 10, + BNA_RES_MEM_T_RX_ARRAY = 11, + BNA_RES_MEM_T_RXP_ARRAY = 12, + BNA_RES_MEM_T_RXQ_ARRAY = 13, + BNA_RES_MEM_T_UCMAC_ARRAY = 14, + BNA_RES_MEM_T_MCMAC_ARRAY = 15, + BNA_RES_MEM_T_RIT_ENTRY = 16, + BNA_RES_MEM_T_RIT_SEGMENT = 17, + BNA_RES_INTR_T_MBOX = 18, + BNA_RES_T_MAX +}; + +enum bna_tx_res_req_type { + BNA_TX_RES_MEM_T_TCB = 0, + BNA_TX_RES_MEM_T_UNMAPQ = 1, + BNA_TX_RES_MEM_T_QPT = 2, + BNA_TX_RES_MEM_T_SWQPT = 3, + BNA_TX_RES_MEM_T_PAGE = 4, + BNA_TX_RES_INTR_T_TXCMPL = 5, + BNA_TX_RES_T_MAX, +}; + +enum bna_rx_mem_type { + BNA_RX_RES_MEM_T_CCB = 0, /* CQ context */ + BNA_RX_RES_MEM_T_RCB = 1, /* CQ context */ + BNA_RX_RES_MEM_T_UNMAPQ = 2, /* UnmapQ for RxQs */ + BNA_RX_RES_MEM_T_CQPT = 3, /* CQ QPT */ + BNA_RX_RES_MEM_T_CSWQPT = 4, /* S/W QPT */ + BNA_RX_RES_MEM_T_CQPT_PAGE = 5, /* CQPT page */ + BNA_RX_RES_MEM_T_HQPT = 6, /* RX QPT */ + BNA_RX_RES_MEM_T_DQPT = 7, /* RX QPT */ + BNA_RX_RES_MEM_T_HSWQPT = 8, /* RX s/w QPT */ + BNA_RX_RES_MEM_T_DSWQPT = 9, /* RX s/w QPT */ + BNA_RX_RES_MEM_T_DPAGE = 10, /* RX s/w QPT */ + BNA_RX_RES_MEM_T_HPAGE = 11, /* RX s/w QPT */ + BNA_RX_RES_T_INTR = 12, /* Rx interrupts */ + BNA_RX_RES_T_MAX = 13 +}; + +enum bna_mbox_state { + BNA_MBOX_FREE = 0, + BNA_MBOX_POSTED = 1 +}; + +enum bna_tx_type { + BNA_TX_T_REGULAR = 0, + BNA_TX_T_LOOPBACK = 1, +}; + +enum bna_tx_flags { + BNA_TX_F_PORT_STARTED = 1, + BNA_TX_F_ENABLED = 2, + BNA_TX_F_PRIO_LOCK = 4, +}; + +enum bna_tx_mod_flags { + BNA_TX_MOD_F_PORT_STARTED = 1, + BNA_TX_MOD_F_PORT_LOOPBACK = 2, +}; + +enum bna_rx_type { + BNA_RX_T_REGULAR = 0, + BNA_RX_T_LOOPBACK = 1, +}; + +enum bna_rxp_type { + BNA_RXP_SINGLE = 1, + BNA_RXP_SLR = 2, + BNA_RXP_HDS = 3 +}; + +enum bna_rxmode { + BNA_RXMODE_PROMISC = 1, + BNA_RXMODE_DEFAULT = 2, + BNA_RXMODE_ALLMULTI = 4 +}; + +enum bna_rx_event { + RX_E_START = 1, + RX_E_STOP = 2, + RX_E_FAIL = 3, + RX_E_RXF_STARTED = 4, + RX_E_RXF_STOPPED = 5, + RX_E_RXQ_STOPPED = 6, +}; + +enum bna_rx_state { + BNA_RX_STOPPED = 1, + BNA_RX_RXF_START_WAIT = 2, + BNA_RX_STARTED = 3, + BNA_RX_RXF_STOP_WAIT = 4, + BNA_RX_RXQ_STOP_WAIT = 5, +}; + +enum bna_rx_flags { + BNA_RX_F_ENABLE = 0x01, /* bnad enabled rxf */ + BNA_RX_F_PORT_ENABLED = 0x02, /* Port object is enabled */ + BNA_RX_F_PORT_FAILED = 0x04, /* Port in failed state */ +}; + +enum bna_rx_mod_flags { + BNA_RX_MOD_F_PORT_STARTED = 1, + BNA_RX_MOD_F_PORT_LOOPBACK = 2, +}; + +enum bna_rxf_oper_state { + BNA_RXF_OPER_STATE_RUNNING = 0x01, /* rxf operational */ + BNA_RXF_OPER_STATE_PAUSED = 0x02, /* rxf in PAUSED state */ +}; + +enum bna_rxf_flags { + BNA_RXF_FL_STOP_PENDING = 0x01, + BNA_RXF_FL_FAILED = 0x02, + BNA_RXF_FL_RSS_CONFIG_PENDING = 0x04, + BNA_RXF_FL_OPERSTATE_CHANGED = 0x08, + BNA_RXF_FL_RXF_ENABLED = 0x10, + BNA_RXF_FL_VLAN_CONFIG_PENDING = 0x20, +}; + +enum bna_rxf_event { + RXF_E_START = 1, + RXF_E_STOP = 2, + RXF_E_FAIL = 3, + RXF_E_CAM_FLTR_MOD = 4, + RXF_E_STARTED = 5, + RXF_E_STOPPED = 6, + RXF_E_CAM_FLTR_RESP = 7, + RXF_E_PAUSE = 8, + RXF_E_RESUME = 9, + RXF_E_STAT_CLEARED = 10, +}; + +enum bna_rxf_state { + BNA_RXF_STOPPED = 1, + BNA_RXF_START_WAIT = 2, + BNA_RXF_CAM_FLTR_MOD_WAIT = 3, + BNA_RXF_STARTED = 4, + BNA_RXF_CAM_FLTR_CLR_WAIT = 5, + BNA_RXF_STOP_WAIT = 6, + BNA_RXF_PAUSE_WAIT = 7, + BNA_RXF_RESUME_WAIT = 8, + BNA_RXF_STAT_CLR_WAIT = 9, +}; + +enum bna_port_type { + BNA_PORT_T_REGULAR = 0, + BNA_PORT_T_LOOPBACK_INTERNAL = 1, + BNA_PORT_T_LOOPBACK_EXTERNAL = 2, +}; + +enum bna_link_status { + BNA_LINK_DOWN = 0, + BNA_LINK_UP = 1, + BNA_CEE_UP = 2 +}; + +enum bna_llport_flags { + BNA_LLPORT_F_ENABLED = 1, + BNA_LLPORT_F_RX_ENABLED = 2 +}; + +enum bna_port_flags { + BNA_PORT_F_DEVICE_READY = 1, + BNA_PORT_F_ENABLED = 2, + BNA_PORT_F_PAUSE_CHANGED = 4, + BNA_PORT_F_MTU_CHANGED = 8 +}; + +enum bna_pkt_rates { + BNA_PKT_RATE_10K = 10000, + BNA_PKT_RATE_20K = 20000, + BNA_PKT_RATE_30K = 30000, + BNA_PKT_RATE_40K = 40000, + BNA_PKT_RATE_50K = 50000, + BNA_PKT_RATE_60K = 60000, + BNA_PKT_RATE_70K = 70000, + BNA_PKT_RATE_80K = 80000, +}; + +enum bna_dim_load_types { + BNA_LOAD_T_HIGH_4 = 0, /* 80K <= r */ + BNA_LOAD_T_HIGH_3 = 1, /* 60K <= r < 80K */ + BNA_LOAD_T_HIGH_2 = 2, /* 50K <= r < 60K */ + BNA_LOAD_T_HIGH_1 = 3, /* 40K <= r < 50K */ + BNA_LOAD_T_LOW_1 = 4, /* 30K <= r < 40K */ + BNA_LOAD_T_LOW_2 = 5, /* 20K <= r < 30K */ + BNA_LOAD_T_LOW_3 = 6, /* 10K <= r < 20K */ + BNA_LOAD_T_LOW_4 = 7, /* r < 10K */ + BNA_LOAD_T_MAX = 8 +}; + +enum bna_dim_bias_types { + BNA_BIAS_T_SMALL = 0, /* small pkts > (large pkts * 2) */ + BNA_BIAS_T_LARGE = 1, /* Not BNA_BIAS_T_SMALL */ + BNA_BIAS_T_MAX = 2 +}; + +struct bna_mac { + /* This should be the first one */ + struct list_head qe; + u8 addr[ETH_ALEN]; +}; + +struct bna_mem_descr { + u32 len; + void *kva; + struct bna_dma_addr dma; +}; + +struct bna_mem_info { + enum bna_mem_type mem_type; + u32 len; + u32 num; + u32 align_sz; /* 0/1 = no alignment */ + struct bna_mem_descr *mdl; + void *cookie; /* For bnad to unmap dma later */ +}; + +struct bna_intr_descr { + int vector; +}; + +struct bna_intr_info { + enum bna_intr_type intr_type; + int num; + struct bna_intr_descr *idl; +}; + +union bna_res_u { + struct bna_mem_info mem_info; + struct bna_intr_info intr_info; +}; + +struct bna_res_info { + enum bna_res_type res_type; + union bna_res_u res_u; +}; + +/* HW QPT */ +struct bna_qpt { + struct bna_dma_addr hw_qpt_ptr; + void *kv_qpt_ptr; + u32 page_count; + u32 page_size; +}; + +/** + * + * Device + * + */ + +struct bna_device { + bfa_fsm_t fsm; + struct bfa_ioc ioc; + + enum bna_intr_type intr_type; + int vector; + + void (*ready_cbfn)(struct bnad *bnad, enum bna_cb_status status); + struct bnad *ready_cbarg; + + void (*stop_cbfn)(struct bnad *bnad, enum bna_cb_status status); + struct bnad *stop_cbarg; + + struct bna *bna; +}; + +/** + * + * Mail box + * + */ + +struct bna_mbox_qe { + /* This should be the first one */ + struct list_head qe; + + struct bfa_mbox_cmd cmd; + u32 cmd_len; + /* Callback for port, tx, rx, rxf */ + void (*cbfn)(void *arg, int status); + void *cbarg; +}; + +struct bna_mbox_mod { + enum bna_mbox_state state; + struct list_head posted_q; + u32 msg_pending; + u32 msg_ctr; + struct bna *bna; +}; + +/** + * + * Port + * + */ + +/* Pause configuration */ +struct bna_pause_config { + enum bna_status tx_pause; + enum bna_status rx_pause; +}; + +struct bna_llport { + bfa_fsm_t fsm; + enum bna_llport_flags flags; + + enum bna_port_type type; + + enum bna_link_status link_status; + + int admin_up_count; + + void (*stop_cbfn)(struct bna_port *, enum bna_cb_status); + + struct bna_mbox_qe mbox_qe; + + struct bna *bna; +}; + +struct bna_port { + bfa_fsm_t fsm; + enum bna_port_flags flags; + + enum bna_port_type type; + + struct bna_llport llport; + + struct bna_pause_config pause_config; + u8 priority; + int mtu; + + /* Callback for bna_port_disable(), port_stop() */ + void (*stop_cbfn)(void *, enum bna_cb_status); + void *stop_cbarg; + + /* Callback for bna_port_pause_config() */ + void (*pause_cbfn)(struct bnad *, enum bna_cb_status); + + /* Callback for bna_port_mtu_set() */ + void (*mtu_cbfn)(struct bnad *, enum bna_cb_status); + + void (*link_cbfn)(struct bnad *, enum bna_link_status); + + struct bfa_wc chld_stop_wc; + + struct bna_mbox_qe mbox_qe; + + struct bna *bna; +}; + +/** + * + * Interrupt Block + * + */ + +/* IB index segment structure */ +struct bna_ibidx_seg { + /* This should be the first one */ + struct list_head qe; + + u8 ib_seg_size; + u8 ib_idx_tbl_offset; +}; + +/* Interrupt structure */ +struct bna_intr { + /* This should be the first one */ + struct list_head qe; + int ref_count; + + enum bna_intr_type intr_type; + int vector; + + struct bna_ib *ib; +}; + +/* Doorbell structure */ +struct bna_ib_dbell { + void *__iomem doorbell_addr; + u32 doorbell_ack; +}; + +/* Interrupt timer configuration */ +struct bna_ib_config { + u8 coalescing_timeo; /* Unit is 5usec. */ + + int interpkt_count; + int interpkt_timeo; + + enum ib_flags ctrl_flags; +}; + +/* IB structure */ +struct bna_ib { + /* This should be the first one */ + struct list_head qe; + + int ib_id; + + int ref_count; + int start_count; + + struct bna_dma_addr ib_seg_host_addr; + void *ib_seg_host_addr_kva; + u32 idx_mask; /* Size >= BNA_IBIDX_MAX_SEGSIZE */ + + struct bna_ibidx_seg *idx_seg; + + struct bna_ib_dbell door_bell; + + struct bna_intr *intr; + + struct bna_ib_config ib_config; + + struct bna *bna; +}; + +/* IB module - keeps track of IBs and interrupts */ +struct bna_ib_mod { + struct bna_ib *ib; /* BFI_MAX_IB entries */ + struct bna_intr *intr; /* BFI_MAX_IB entries */ + struct bna_ibidx_seg *idx_seg; /* BNA_IBIDX_TOTAL_SEGS */ + + struct list_head ib_free_q; + + struct list_head ibidx_seg_pool[BFI_IBIDX_TOTAL_POOLS]; + + struct list_head intr_free_q; + struct list_head intr_active_q; + + struct bna *bna; +}; + +/** + * + * Tx object + * + */ + +/* Tx datapath control structure */ +#define BNA_Q_NAME_SIZE 16 +struct bna_tcb { + /* Fast path */ + void **sw_qpt; + void *unmap_q; + u32 producer_index; + u32 consumer_index; + volatile u32 *hw_consumer_index; + u32 q_depth; + void *__iomem q_dbell; + struct bna_ib_dbell *i_dbell; + int page_idx; + int page_count; + /* Control path */ + struct bna_txq *txq; + struct bnad *bnad; + enum bna_intr_type intr_type; + int intr_vector; + u8 priority; /* Current priority */ + unsigned long flags; /* Used by bnad as required */ + int id; + char name[BNA_Q_NAME_SIZE]; +}; + +/* TxQ QPT and configuration */ +struct bna_txq { + /* This should be the first one */ + struct list_head qe; + + int txq_id; + + u8 priority; + + struct bna_qpt qpt; + struct bna_tcb *tcb; + struct bna_ib *ib; + int ib_seg_offset; + + struct bna_tx *tx; + + u64 tx_packets; + u64 tx_bytes; +}; + +/* TxF structure (hardware Tx Function) */ +struct bna_txf { + int txf_id; + enum txf_flags ctrl_flags; + u16 vlan; +}; + +/* Tx object */ +struct bna_tx { + /* This should be the first one */ + struct list_head qe; + + bfa_fsm_t fsm; + enum bna_tx_flags flags; + + enum bna_tx_type type; + + struct list_head txq_q; + struct bna_txf txf; + + /* Tx event handlers */ + void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *); + void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *); + + /* callback for bna_tx_disable(), bna_tx_stop() */ + void (*stop_cbfn)(void *arg, struct bna_tx *tx, + enum bna_cb_status status); + void *stop_cbarg; + + /* callback for bna_tx_prio_set() */ + void (*prio_change_cbfn)(struct bnad *bnad, struct bna_tx *tx, + enum bna_cb_status status); + + struct bfa_wc txq_stop_wc; + + struct bna_mbox_qe mbox_qe; + + struct bna *bna; + void *priv; /* bnad's cookie */ +}; + +struct bna_tx_config { + int num_txq; + int txq_depth; + enum bna_tx_type tx_type; +}; + +struct bna_tx_event_cbfn { + /* Optional */ + void (*tcb_setup_cbfn)(struct bnad *, struct bna_tcb *); + void (*tcb_destroy_cbfn)(struct bnad *, struct bna_tcb *); + /* Mandatory */ + void (*tx_stall_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_resume_cbfn)(struct bnad *, struct bna_tcb *); + void (*tx_cleanup_cbfn)(struct bnad *, struct bna_tcb *); +}; + +/* Tx module - keeps track of free, active tx objects */ +struct bna_tx_mod { + struct bna_tx *tx; /* BFI_MAX_TXQ entries */ + struct bna_txq *txq; /* BFI_MAX_TXQ entries */ + + struct list_head tx_free_q; + struct list_head tx_active_q; + + struct list_head txq_free_q; + + /* callback for bna_tx_mod_stop() */ + void (*stop_cbfn)(struct bna_port *port, + enum bna_cb_status status); + + struct bfa_wc tx_stop_wc; + + enum bna_tx_mod_flags flags; + + int priority; + int cee_link; + + u32 txf_bmap[2]; + + struct bna *bna; +}; + +/** + * + * Receive Indirection Table + * + */ + +/* One row of RIT table */ +struct bna_rit_entry { + u8 large_rxq_id; /* used for either large or data buffers */ + u8 small_rxq_id; /* used for either small or header buffers */ +}; + +/* RIT segment */ +struct bna_rit_segment { + struct list_head qe; + + u32 rit_offset; + u32 rit_size; + /** + * max_rit_size: Varies per RIT segment depending on how RIT is + * partitioned + */ + u32 max_rit_size; + + struct bna_rit_entry *rit; +}; + +struct bna_rit_mod { + struct bna_rit_entry *rit; + struct bna_rit_segment *rit_segment; + + struct list_head rit_seg_pool[BFI_RIT_SEG_TOTAL_POOLS]; +}; + +/** + * + * Rx object + * + */ + +/* Rx datapath control structure */ +struct bna_rcb { + /* Fast path */ + void **sw_qpt; + void *unmap_q; + u32 producer_index; + u32 consumer_index; + u32 q_depth; + void *__iomem q_dbell; + int page_idx; + int page_count; + /* Control path */ + struct bna_rxq *rxq; + struct bna_cq *cq; + struct bnad *bnad; + unsigned long flags; + int id; +}; + +/* RxQ structure - QPT, configuration */ +struct bna_rxq { + struct list_head qe; + int rxq_id; + + int buffer_size; + int q_depth; + + struct bna_qpt qpt; + struct bna_rcb *rcb; + + struct bna_rxp *rxp; + struct bna_rx *rx; + + u64 rx_packets; + u64 rx_bytes; + u64 rx_packets_with_error; + u64 rxbuf_alloc_failed; +}; + +/* RxQ pair */ +union bna_rxq_u { + struct { + struct bna_rxq *hdr; + struct bna_rxq *data; + } hds; + struct { + struct bna_rxq *small; + struct bna_rxq *large; + } slr; + struct { + struct bna_rxq *only; + struct bna_rxq *reserved; + } single; +}; + +/* Packet rate for Dynamic Interrupt Moderation */ +struct bna_pkt_rate { + u32 small_pkt_cnt; + u32 large_pkt_cnt; +}; + +/* Completion control structure */ +struct bna_ccb { + /* Fast path */ + void **sw_qpt; + u32 producer_index; + volatile u32 *hw_producer_index; + u32 q_depth; + struct bna_ib_dbell *i_dbell; + struct bna_rcb *rcb[2]; + void *ctrl; /* For bnad */ + struct bna_pkt_rate pkt_rate; + int page_idx; + int page_count; + + /* Control path */ + struct bna_cq *cq; + struct bnad *bnad; + enum bna_intr_type intr_type; + int intr_vector; + u8 rx_coalescing_timeo; /* For NAPI */ + int id; + char name[BNA_Q_NAME_SIZE]; +}; + +/* CQ QPT, configuration */ +struct bna_cq { + int cq_id; + + struct bna_qpt qpt; + struct bna_ccb *ccb; + + struct bna_ib *ib; + u8 ib_seg_offset; + + struct bna_rx *rx; +}; + +struct bna_rss_config { + enum rss_hash_type hash_type; + u8 hash_mask; + u32 toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN]; +}; + +struct bna_hds_config { + enum hds_header_type hdr_type; + int header_size; +}; + +/* This structure is used during RX creation */ +struct bna_rx_config { + enum bna_rx_type rx_type; + int num_paths; + enum bna_rxp_type rxp_type; + int paused; + int q_depth; + /* + * Small/Large (or Header/Data) buffer size to be configured + * for SLR and HDS queue type. Large buffer size comes from + * port->mtu. + */ + int small_buff_size; + + enum bna_status rss_status; + struct bna_rss_config rss_config; + + enum bna_status hds_status; + struct bna_hds_config hds_config; + + enum bna_status vlan_strip_status; +}; + +/* Rx Path structure - one per MSIX vector/CPU */ +struct bna_rxp { + /* This should be the first one */ + struct list_head qe; + + enum bna_rxp_type type; + union bna_rxq_u rxq; + struct bna_cq cq; + + struct bna_rx *rx; + + /* MSI-x vector number for configuring RSS */ + int vector; + + struct bna_mbox_qe mbox_qe; +}; + +/* HDS configuration structure */ +struct bna_rxf_hds { + enum hds_header_type hdr_type; + int header_size; +}; + +/* RSS configuration structure */ +struct bna_rxf_rss { + enum rss_hash_type hash_type; + u8 hash_mask; + u32 toeplitz_hash_key[BFI_RSS_HASH_KEY_LEN]; +}; + +/* RxF structure (hardware Rx Function) */ +struct bna_rxf { + bfa_fsm_t fsm; + int rxf_id; + enum rxf_flags ctrl_flags; + u16 default_vlan_tag; + enum bna_rxf_oper_state rxf_oper_state; + enum bna_status hds_status; + struct bna_rxf_hds hds_cfg; + enum bna_status rss_status; + struct bna_rxf_rss rss_cfg; + struct bna_rit_segment *rit_segment; + struct bna_rx *rx; + u32 forced_offset; + struct bna_mbox_qe mbox_qe; + int mcast_rxq_id; + + /* callback for bna_rxf_start() */ + void (*start_cbfn) (struct bna_rx *rx, enum bna_cb_status status); + struct bna_rx *start_cbarg; + + /* callback for bna_rxf_stop() */ + void (*stop_cbfn) (struct bna_rx *rx, enum bna_cb_status status); + struct bna_rx *stop_cbarg; + + /* callback for bna_rxf_receive_enable() / bna_rxf_receive_disable() */ + void (*oper_state_cbfn) (struct bnad *bnad, struct bna_rx *rx, + enum bna_cb_status status); + struct bnad *oper_state_cbarg; + + /** + * callback for: + * bna_rxf_ucast_set() + * bna_rxf_{ucast/mcast}_add(), + * bna_rxf_{ucast/mcast}_del(), + * bna_rxf_mode_set() + */ + void (*cam_fltr_cbfn)(struct bnad *bnad, struct bna_rx *rx, + enum bna_cb_status status); + struct bnad *cam_fltr_cbarg; + + enum bna_rxf_flags rxf_flags; + + /* List of unicast addresses yet to be applied to h/w */ + struct list_head ucast_pending_add_q; + struct list_head ucast_pending_del_q; + int ucast_pending_set; + /* ucast addresses applied to the h/w */ + struct list_head ucast_active_q; + struct bna_mac *ucast_active_mac; + + /* List of multicast addresses yet to be applied to h/w */ + struct list_head mcast_pending_add_q; + struct list_head mcast_pending_del_q; + /* multicast addresses applied to the h/w */ + struct list_head mcast_active_q; + + /* Rx modes yet to be applied to h/w */ + enum bna_rxmode rxmode_pending; + enum bna_rxmode rxmode_pending_bitmask; + /* Rx modes applied to h/w */ + enum bna_rxmode rxmode_active; + + enum bna_status vlan_filter_status; + u32 vlan_filter_table[(BFI_MAX_VLAN + 1) / 32]; +}; + +/* Rx object */ +struct bna_rx { + /* This should be the first one */ + struct list_head qe; + + bfa_fsm_t fsm; + + enum bna_rx_type type; + + /* list-head for RX path objects */ + struct list_head rxp_q; + + struct bna_rxf rxf; + + enum bna_rx_flags rx_flags; + + struct bna_mbox_qe mbox_qe; + + struct bfa_wc rxq_stop_wc; + + /* Rx event handlers */ + void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *); + void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *); + void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *); + void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *); + void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *); + void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *); + + /* callback for bna_rx_disable(), bna_rx_stop() */ + void (*stop_cbfn)(void *arg, struct bna_rx *rx, + enum bna_cb_status status); + void *stop_cbarg; + + struct bna *bna; + void *priv; /* bnad's cookie */ +}; + +struct bna_rx_event_cbfn { + /* Optional */ + void (*rcb_setup_cbfn)(struct bnad *, struct bna_rcb *); + void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *); + void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *); + void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *); + /* Mandatory */ + void (*rx_cleanup_cbfn)(struct bnad *, struct bna_ccb *); + void (*rx_post_cbfn)(struct bnad *, struct bna_rcb *); +}; + +/* Rx module - keeps track of free, active rx objects */ +struct bna_rx_mod { + struct bna *bna; /* back pointer to parent */ + struct bna_rx *rx; /* BFI_MAX_RXQ entries */ + struct bna_rxp *rxp; /* BFI_MAX_RXQ entries */ + struct bna_rxq *rxq; /* BFI_MAX_RXQ entries */ + + struct list_head rx_free_q; + struct list_head rx_active_q; + int rx_free_count; + + struct list_head rxp_free_q; + int rxp_free_count; + + struct list_head rxq_free_q; + int rxq_free_count; + + enum bna_rx_mod_flags flags; + + /* callback for bna_rx_mod_stop() */ + void (*stop_cbfn)(struct bna_port *port, + enum bna_cb_status status); + + struct bfa_wc rx_stop_wc; + u32 dim_vector[BNA_LOAD_T_MAX][BNA_BIAS_T_MAX]; + u32 rxf_bmap[2]; +}; + +/** + * + * CAM + * + */ + +struct bna_ucam_mod { + struct bna_mac *ucmac; /* BFI_MAX_UCMAC entries */ + struct list_head free_q; + + struct bna *bna; +}; + +struct bna_mcam_mod { + struct bna_mac *mcmac; /* BFI_MAX_MCMAC entries */ + struct list_head free_q; + + struct bna *bna; +}; + +/** + * + * Statistics + * + */ + +struct bna_tx_stats { + int tx_state; + int tx_flags; + int num_txqs; + u32 txq_bmap[2]; + int txf_id; +}; + +struct bna_rx_stats { + int rx_state; + int rx_flags; + int num_rxps; + int num_rxqs; + u32 rxq_bmap[2]; + u32 cq_bmap[2]; + int rxf_id; + int rxf_state; + int rxf_oper_state; + int num_active_ucast; + int num_active_mcast; + int rxmode_active; + int vlan_filter_status; + u32 vlan_filter_table[(BFI_MAX_VLAN + 1) / 32]; + int rss_status; + int hds_status; +}; + +struct bna_sw_stats { + int device_state; + int port_state; + int port_flags; + int llport_state; + int priority; + int num_active_tx; + int num_active_rx; + struct bna_tx_stats tx_stats[BFI_MAX_TXQ]; + struct bna_rx_stats rx_stats[BFI_MAX_RXQ]; +}; + +struct bna_stats { + u32 txf_bmap[2]; + u32 rxf_bmap[2]; + struct bfi_ll_stats *hw_stats; + struct bna_sw_stats *sw_stats; +}; + +/** + * + * BNA + * + */ + +struct bna { + struct bfa_pcidev pcidev; + + int port_num; + + struct bna_chip_regs regs; + + struct bna_dma_addr hw_stats_dma; + struct bna_stats stats; + + struct bna_device device; + struct bfa_cee cee; + + struct bna_mbox_mod mbox_mod; + + struct bna_port port; + + struct bna_tx_mod tx_mod; + + struct bna_rx_mod rx_mod; + + struct bna_ib_mod ib_mod; + + struct bna_ucam_mod ucam_mod; + struct bna_mcam_mod mcam_mod; + + struct bna_rit_mod rit_mod; + + int rxf_default_id; + int rxf_promisc_id; + + struct bna_mbox_qe mbox_qe; + + struct bnad *bnad; +}; + +#endif /* __BNA_TYPES_H__ */ diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c new file mode 100644 index 0000000000000000000000000000000000000000..7e839b9cec221758c69afe3871d7cd884207bb80 --- /dev/null +++ b/drivers/net/bna/bnad.c @@ -0,0 +1,3264 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bnad.h" +#include "bna.h" +#include "cna.h" + +static DEFINE_MUTEX(bnad_fwimg_mutex); + +/* + * Module params + */ +static uint bnad_msix_disable; +module_param(bnad_msix_disable, uint, 0444); +MODULE_PARM_DESC(bnad_msix_disable, "Disable MSIX mode"); + +static uint bnad_ioc_auto_recover = 1; +module_param(bnad_ioc_auto_recover, uint, 0444); +MODULE_PARM_DESC(bnad_ioc_auto_recover, "Enable / Disable auto recovery"); + +/* + * Global variables + */ +u32 bnad_rxqs_per_cq = 2; + +static const u8 bnad_bcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + +/* + * Local MACROS + */ +#define BNAD_TX_UNMAPQ_DEPTH (bnad->txq_depth * 2) + +#define BNAD_RX_UNMAPQ_DEPTH (bnad->rxq_depth) + +#define BNAD_GET_MBOX_IRQ(_bnad) \ + (((_bnad)->cfg_flags & BNAD_CF_MSIX) ? \ + ((_bnad)->msix_table[(_bnad)->msix_num - 1].vector) : \ + ((_bnad)->pcidev->irq)) + +#define BNAD_FILL_UNMAPQ_MEM_REQ(_res_info, _num, _depth) \ +do { \ + (_res_info)->res_type = BNA_RES_T_MEM; \ + (_res_info)->res_u.mem_info.mem_type = BNA_MEM_T_KVA; \ + (_res_info)->res_u.mem_info.num = (_num); \ + (_res_info)->res_u.mem_info.len = \ + sizeof(struct bnad_unmap_q) + \ + (sizeof(struct bnad_skb_unmap) * ((_depth) - 1)); \ +} while (0) + +/* + * Reinitialize completions in CQ, once Rx is taken down + */ +static void +bnad_cq_cmpl_init(struct bnad *bnad, struct bna_ccb *ccb) +{ + struct bna_cq_entry *cmpl, *next_cmpl; + unsigned int wi_range, wis = 0, ccb_prod = 0; + int i; + + BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt, cmpl, + wi_range); + + for (i = 0; i < ccb->q_depth; i++) { + wis++; + if (likely(--wi_range)) + next_cmpl = cmpl + 1; + else { + BNA_QE_INDX_ADD(ccb_prod, wis, ccb->q_depth); + wis = 0; + BNA_CQ_QPGE_PTR_GET(ccb_prod, ccb->sw_qpt, + next_cmpl, wi_range); + } + cmpl->valid = 0; + cmpl = next_cmpl; + } +} + +/* + * Frees all pending Tx Bufs + * At this point no activity is expected on the Q, + * so DMA unmap & freeing is fine. + */ +static void +bnad_free_all_txbufs(struct bnad *bnad, + struct bna_tcb *tcb) +{ + u16 unmap_cons; + struct bnad_unmap_q *unmap_q = tcb->unmap_q; + struct bnad_skb_unmap *unmap_array; + struct sk_buff *skb = NULL; + int i; + + unmap_array = unmap_q->unmap_array; + + unmap_cons = 0; + while (unmap_cons < unmap_q->q_depth) { + skb = unmap_array[unmap_cons].skb; + if (!skb) { + unmap_cons++; + continue; + } + unmap_array[unmap_cons].skb = NULL; + + pci_unmap_single(bnad->pcidev, + pci_unmap_addr(&unmap_array[unmap_cons], + dma_addr), skb_headlen(skb), + PCI_DMA_TODEVICE); + + pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); + unmap_cons++; + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + pci_unmap_page(bnad->pcidev, + pci_unmap_addr(&unmap_array[unmap_cons], + dma_addr), + skb_shinfo(skb)->frags[i].size, + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, + 0); + unmap_cons++; + } + dev_kfree_skb_any(skb); + } +} + +/* Data Path Handlers */ + +/* + * bnad_free_txbufs : Frees the Tx bufs on Tx completion + * Can be called in a) Interrupt context + * b) Sending context + * c) Tasklet context + */ +static u32 +bnad_free_txbufs(struct bnad *bnad, + struct bna_tcb *tcb) +{ + u32 sent_packets = 0, sent_bytes = 0; + u16 wis, unmap_cons, updated_hw_cons; + struct bnad_unmap_q *unmap_q = tcb->unmap_q; + struct bnad_skb_unmap *unmap_array; + struct sk_buff *skb; + int i; + + /* + * Just return if TX is stopped. This check is useful + * when bnad_free_txbufs() runs out of a tasklet scheduled + * before bnad_cb_tx_cleanup() cleared BNAD_RF_TX_STARTED bit + * but this routine runs actually after the cleanup has been + * executed. + */ + if (!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) + return 0; + + updated_hw_cons = *(tcb->hw_consumer_index); + + wis = BNA_Q_INDEX_CHANGE(tcb->consumer_index, + updated_hw_cons, tcb->q_depth); + + BUG_ON(!(wis <= BNA_QE_IN_USE_CNT(tcb, tcb->q_depth))); + + unmap_array = unmap_q->unmap_array; + unmap_cons = unmap_q->consumer_index; + + prefetch(&unmap_array[unmap_cons + 1]); + while (wis) { + skb = unmap_array[unmap_cons].skb; + + unmap_array[unmap_cons].skb = NULL; + + sent_packets++; + sent_bytes += skb->len; + wis -= BNA_TXQ_WI_NEEDED(1 + skb_shinfo(skb)->nr_frags); + + pci_unmap_single(bnad->pcidev, + pci_unmap_addr(&unmap_array[unmap_cons], + dma_addr), skb_headlen(skb), + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); + BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth); + + prefetch(&unmap_array[unmap_cons + 1]); + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + prefetch(&unmap_array[unmap_cons + 1]); + + pci_unmap_page(bnad->pcidev, + pci_unmap_addr(&unmap_array[unmap_cons], + dma_addr), + skb_shinfo(skb)->frags[i].size, + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, + 0); + BNA_QE_INDX_ADD(unmap_cons, 1, unmap_q->q_depth); + } + dev_kfree_skb_any(skb); + } + + /* Update consumer pointers. */ + tcb->consumer_index = updated_hw_cons; + unmap_q->consumer_index = unmap_cons; + + tcb->txq->tx_packets += sent_packets; + tcb->txq->tx_bytes += sent_bytes; + + return sent_packets; +} + +/* Tx Free Tasklet function */ +/* Frees for all the tcb's in all the Tx's */ +/* + * Scheduled from sending context, so that + * the fat Tx lock is not held for too long + * in the sending context. + */ +static void +bnad_tx_free_tasklet(unsigned long bnad_ptr) +{ + struct bnad *bnad = (struct bnad *)bnad_ptr; + struct bna_tcb *tcb; + u32 acked; + int i, j; + + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) { + tcb = bnad->tx_info[i].tcb[j]; + if (!tcb) + continue; + if (((u16) (*tcb->hw_consumer_index) != + tcb->consumer_index) && + (!test_and_set_bit(BNAD_TXQ_FREE_SENT, + &tcb->flags))) { + acked = bnad_free_txbufs(bnad, tcb); + bna_ib_ack(tcb->i_dbell, acked); + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); + } + } + } +} + +static u32 +bnad_tx(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct net_device *netdev = bnad->netdev; + u32 sent; + + if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) + return 0; + + sent = bnad_free_txbufs(bnad, tcb); + if (sent) { + if (netif_queue_stopped(netdev) && + netif_carrier_ok(netdev) && + BNA_QE_FREE_CNT(tcb, tcb->q_depth) >= + BNAD_NETIF_WAKE_THRESHOLD) { + netif_wake_queue(netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } + bna_ib_ack(tcb->i_dbell, sent); + } else + bna_ib_ack(tcb->i_dbell, 0); + + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); + + return sent; +} + +/* MSIX Tx Completion Handler */ +static irqreturn_t +bnad_msix_tx(int irq, void *data) +{ + struct bna_tcb *tcb = (struct bna_tcb *)data; + struct bnad *bnad = tcb->bnad; + + bnad_tx(bnad, tcb); + + return IRQ_HANDLED; +} + +static void +bnad_reset_rcb(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + + rcb->producer_index = 0; + rcb->consumer_index = 0; + + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; +} + +static void +bnad_free_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q; + struct sk_buff *skb; + + unmap_q = rcb->unmap_q; + while (BNA_QE_IN_USE_CNT(unmap_q, unmap_q->q_depth)) { + skb = unmap_q->unmap_array[unmap_q->consumer_index].skb; + BUG_ON(!(skb)); + unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL; + pci_unmap_single(bnad->pcidev, pci_unmap_addr(&unmap_q-> + unmap_array[unmap_q->consumer_index], + dma_addr), rcb->rxq->buffer_size + + NET_IP_ALIGN, PCI_DMA_FROMDEVICE); + dev_kfree_skb(skb); + BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth); + BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth); + } + + bnad_reset_rcb(bnad, rcb); +} + +static void +bnad_alloc_n_post_rxbufs(struct bnad *bnad, struct bna_rcb *rcb) +{ + u16 to_alloc, alloced, unmap_prod, wi_range; + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + struct bnad_skb_unmap *unmap_array; + struct bna_rxq_entry *rxent; + struct sk_buff *skb; + dma_addr_t dma_addr; + + alloced = 0; + to_alloc = + BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth); + + unmap_array = unmap_q->unmap_array; + unmap_prod = unmap_q->producer_index; + + BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, wi_range); + + while (to_alloc--) { + if (!wi_range) { + BNA_RXQ_QPGE_PTR_GET(unmap_prod, rcb->sw_qpt, rxent, + wi_range); + } + skb = alloc_skb(rcb->rxq->buffer_size + NET_IP_ALIGN, + GFP_ATOMIC); + if (unlikely(!skb)) { + BNAD_UPDATE_CTR(bnad, rxbuf_alloc_failed); + goto finishing; + } + skb->dev = bnad->netdev; + skb_reserve(skb, NET_IP_ALIGN); + unmap_array[unmap_prod].skb = skb; + dma_addr = pci_map_single(bnad->pcidev, skb->data, + rcb->rxq->buffer_size, PCI_DMA_FROMDEVICE); + pci_unmap_addr_set(&unmap_array[unmap_prod], dma_addr, + dma_addr); + BNA_SET_DMA_ADDR(dma_addr, &rxent->host_addr); + BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); + + rxent++; + wi_range--; + alloced++; + } + +finishing: + if (likely(alloced)) { + unmap_q->producer_index = unmap_prod; + rcb->producer_index = unmap_prod; + smp_mb(); + bna_rxq_prod_indx_doorbell(rcb); + } +} + +/* + * Locking is required in the enable path + * because it is called from a napi poll + * context, where the bna_lock is not held + * unlike the IRQ context. + */ +static void +bnad_enable_txrx_irqs(struct bnad *bnad) +{ + struct bna_tcb *tcb; + struct bna_ccb *ccb; + int i, j; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) { + tcb = bnad->tx_info[i].tcb[j]; + bna_ib_coalescing_timer_set(tcb->i_dbell, + tcb->txq->ib->ib_config.coalescing_timeo); + bna_ib_ack(tcb->i_dbell, 0); + } + } + + for (i = 0; i < bnad->num_rx; i++) { + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + ccb = bnad->rx_info[i].rx_ctrl[j].ccb; + bnad_enable_rx_irq_unsafe(ccb); + } + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static inline void +bnad_refill_rxq(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + + if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) { + if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth) + >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT) + bnad_alloc_n_post_rxbufs(bnad, rcb); + smp_mb__before_clear_bit(); + clear_bit(BNAD_RXQ_REFILL, &rcb->flags); + } +} + +static u32 +bnad_poll_cq(struct bnad *bnad, struct bna_ccb *ccb, int budget) +{ + struct bna_cq_entry *cmpl, *next_cmpl; + struct bna_rcb *rcb = NULL; + unsigned int wi_range, packets = 0, wis = 0; + struct bnad_unmap_q *unmap_q; + struct sk_buff *skb; + u32 flags; + u32 qid0 = ccb->rcb[0]->rxq->rxq_id; + struct bna_pkt_rate *pkt_rt = &ccb->pkt_rate; + + prefetch(bnad->netdev); + BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, cmpl, + wi_range); + BUG_ON(!(wi_range <= ccb->q_depth)); + while (cmpl->valid && packets < budget) { + packets++; + BNA_UPDATE_PKT_CNT(pkt_rt, ntohs(cmpl->length)); + + if (qid0 == cmpl->rxq_id) + rcb = ccb->rcb[0]; + else + rcb = ccb->rcb[1]; + + unmap_q = rcb->unmap_q; + + skb = unmap_q->unmap_array[unmap_q->consumer_index].skb; + BUG_ON(!(skb)); + unmap_q->unmap_array[unmap_q->consumer_index].skb = NULL; + pci_unmap_single(bnad->pcidev, + pci_unmap_addr(&unmap_q-> + unmap_array[unmap_q-> + consumer_index], + dma_addr), + rcb->rxq->buffer_size, + PCI_DMA_FROMDEVICE); + BNA_QE_INDX_ADD(unmap_q->consumer_index, 1, unmap_q->q_depth); + + /* Should be more efficient ? Performance ? */ + BNA_QE_INDX_ADD(rcb->consumer_index, 1, rcb->q_depth); + + wis++; + if (likely(--wi_range)) + next_cmpl = cmpl + 1; + else { + BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth); + wis = 0; + BNA_CQ_QPGE_PTR_GET(ccb->producer_index, ccb->sw_qpt, + next_cmpl, wi_range); + BUG_ON(!(wi_range <= ccb->q_depth)); + } + prefetch(next_cmpl); + + flags = ntohl(cmpl->flags); + if (unlikely + (flags & + (BNA_CQ_EF_MAC_ERROR | BNA_CQ_EF_FCS_ERROR | + BNA_CQ_EF_TOO_LONG))) { + dev_kfree_skb_any(skb); + rcb->rxq->rx_packets_with_error++; + goto next; + } + + skb_put(skb, ntohs(cmpl->length)); + if (likely + (bnad->rx_csum && + (((flags & BNA_CQ_EF_IPV4) && + (flags & BNA_CQ_EF_L3_CKSUM_OK)) || + (flags & BNA_CQ_EF_IPV6)) && + (flags & (BNA_CQ_EF_TCP | BNA_CQ_EF_UDP)) && + (flags & BNA_CQ_EF_L4_CKSUM_OK))) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb_checksum_none_assert(skb); + + rcb->rxq->rx_packets++; + rcb->rxq->rx_bytes += skb->len; + skb->protocol = eth_type_trans(skb, bnad->netdev); + + if (bnad->vlan_grp && (flags & BNA_CQ_EF_VLAN)) { + struct bnad_rx_ctrl *rx_ctrl = + (struct bnad_rx_ctrl *)ccb->ctrl; + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + vlan_gro_receive(&rx_ctrl->napi, bnad->vlan_grp, + ntohs(cmpl->vlan_tag), skb); + else + vlan_hwaccel_receive_skb(skb, + bnad->vlan_grp, + ntohs(cmpl->vlan_tag)); + + } else { /* Not VLAN tagged/stripped */ + struct bnad_rx_ctrl *rx_ctrl = + (struct bnad_rx_ctrl *)ccb->ctrl; + if (skb->ip_summed == CHECKSUM_UNNECESSARY) + napi_gro_receive(&rx_ctrl->napi, skb); + else + netif_receive_skb(skb); + } + +next: + cmpl->valid = 0; + cmpl = next_cmpl; + } + + BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth); + + if (likely(ccb)) { + bna_ib_ack(ccb->i_dbell, packets); + bnad_refill_rxq(bnad, ccb->rcb[0]); + if (ccb->rcb[1]) + bnad_refill_rxq(bnad, ccb->rcb[1]); + } else + bna_ib_ack(ccb->i_dbell, 0); + + return packets; +} + +static void +bnad_disable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb) +{ + bna_ib_coalescing_timer_set(ccb->i_dbell, 0); + bna_ib_ack(ccb->i_dbell, 0); +} + +static void +bnad_enable_rx_irq(struct bnad *bnad, struct bna_ccb *ccb) +{ + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); /* Because of polling context */ + bnad_enable_rx_irq_unsafe(ccb); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static void +bnad_netif_rx_schedule_poll(struct bnad *bnad, struct bna_ccb *ccb) +{ + struct bnad_rx_ctrl *rx_ctrl = (struct bnad_rx_ctrl *)(ccb->ctrl); + if (likely(napi_schedule_prep((&rx_ctrl->napi)))) { + bnad_disable_rx_irq(bnad, ccb); + __napi_schedule((&rx_ctrl->napi)); + } + BNAD_UPDATE_CTR(bnad, netif_rx_schedule); +} + +/* MSIX Rx Path Handler */ +static irqreturn_t +bnad_msix_rx(int irq, void *data) +{ + struct bna_ccb *ccb = (struct bna_ccb *)data; + struct bnad *bnad = ccb->bnad; + + bnad_netif_rx_schedule_poll(bnad, ccb); + + return IRQ_HANDLED; +} + +/* Interrupt handlers */ + +/* Mbox Interrupt Handlers */ +static irqreturn_t +bnad_msix_mbox_handler(int irq, void *data) +{ + u32 intr_status; + unsigned long flags; + struct net_device *netdev = data; + struct bnad *bnad; + + bnad = netdev_priv(netdev); + + /* BNA_ISR_GET(bnad); Inc Ref count */ + spin_lock_irqsave(&bnad->bna_lock, flags); + + bna_intr_status_get(&bnad->bna, intr_status); + + if (BNA_IS_MBOX_ERR_INTR(intr_status)) + bna_mbox_handler(&bnad->bna, intr_status); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* BNAD_ISR_PUT(bnad); Dec Ref count */ + return IRQ_HANDLED; +} + +static irqreturn_t +bnad_isr(int irq, void *data) +{ + int i, j; + u32 intr_status; + unsigned long flags; + struct net_device *netdev = data; + struct bnad *bnad = netdev_priv(netdev); + struct bnad_rx_info *rx_info; + struct bnad_rx_ctrl *rx_ctrl; + + if (unlikely(test_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags))) + return IRQ_NONE; + + bna_intr_status_get(&bnad->bna, intr_status); + + if (unlikely(!intr_status)) + return IRQ_NONE; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + if (BNA_IS_MBOX_ERR_INTR(intr_status)) { + bna_mbox_handler(&bnad->bna, intr_status); + if (!BNA_IS_INTX_DATA_INTR(intr_status)) { + spin_unlock_irqrestore(&bnad->bna_lock, flags); + goto done; + } + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Process data interrupts */ + for (i = 0; i < bnad->num_rx; i++) { + rx_info = &bnad->rx_info[i]; + if (!rx_info->rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + rx_ctrl = &rx_info->rx_ctrl[j]; + if (rx_ctrl->ccb) + bnad_netif_rx_schedule_poll(bnad, + rx_ctrl->ccb); + } + } +done: + return IRQ_HANDLED; +} + +/* + * Called in interrupt / callback context + * with bna_lock held, so cfg_flags access is OK + */ +static void +bnad_enable_mbox_irq(struct bnad *bnad) +{ + int irq = BNAD_GET_MBOX_IRQ(bnad); + + if (test_and_clear_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)) + if (bnad->cfg_flags & BNAD_CF_MSIX) + enable_irq(irq); + + BNAD_UPDATE_CTR(bnad, mbox_intr_enabled); +} + +/* + * Called with bnad->bna_lock held b'cos of + * bnad->cfg_flags access. + */ +static void +bnad_disable_mbox_irq(struct bnad *bnad) +{ + int irq = BNAD_GET_MBOX_IRQ(bnad); + + + if (!test_and_set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags)) + if (bnad->cfg_flags & BNAD_CF_MSIX) + disable_irq_nosync(irq); + + BNAD_UPDATE_CTR(bnad, mbox_intr_disabled); +} + +/* Control Path Handlers */ + +/* Callbacks */ +void +bnad_cb_device_enable_mbox_intr(struct bnad *bnad) +{ + bnad_enable_mbox_irq(bnad); +} + +void +bnad_cb_device_disable_mbox_intr(struct bnad *bnad) +{ + bnad_disable_mbox_irq(bnad); +} + +void +bnad_cb_device_enabled(struct bnad *bnad, enum bna_cb_status status) +{ + complete(&bnad->bnad_completions.ioc_comp); + bnad->bnad_completions.ioc_comp_status = status; +} + +void +bnad_cb_device_disabled(struct bnad *bnad, enum bna_cb_status status) +{ + complete(&bnad->bnad_completions.ioc_comp); + bnad->bnad_completions.ioc_comp_status = status; +} + +static void +bnad_cb_port_disabled(void *arg, enum bna_cb_status status) +{ + struct bnad *bnad = (struct bnad *)arg; + + complete(&bnad->bnad_completions.port_comp); + + netif_carrier_off(bnad->netdev); +} + +void +bnad_cb_port_link_status(struct bnad *bnad, + enum bna_link_status link_status) +{ + bool link_up = 0; + + link_up = (link_status == BNA_LINK_UP) || (link_status == BNA_CEE_UP); + + if (link_status == BNA_CEE_UP) { + set_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags); + BNAD_UPDATE_CTR(bnad, cee_up); + } else + clear_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags); + + if (link_up) { + if (!netif_carrier_ok(bnad->netdev)) { + pr_warn("bna: %s link up\n", + bnad->netdev->name); + netif_carrier_on(bnad->netdev); + BNAD_UPDATE_CTR(bnad, link_toggle); + if (test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) { + /* Force an immediate Transmit Schedule */ + pr_info("bna: %s TX_STARTED\n", + bnad->netdev->name); + netif_wake_queue(bnad->netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } else { + netif_stop_queue(bnad->netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_stop); + } + } + } else { + if (netif_carrier_ok(bnad->netdev)) { + pr_warn("bna: %s link down\n", + bnad->netdev->name); + netif_carrier_off(bnad->netdev); + BNAD_UPDATE_CTR(bnad, link_toggle); + } + } +} + +static void +bnad_cb_tx_disabled(void *arg, struct bna_tx *tx, + enum bna_cb_status status) +{ + struct bnad *bnad = (struct bnad *)arg; + + complete(&bnad->bnad_completions.tx_comp); +} + +static void +bnad_cb_tcb_setup(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct bnad_tx_info *tx_info = + (struct bnad_tx_info *)tcb->txq->tx->priv; + struct bnad_unmap_q *unmap_q = tcb->unmap_q; + + tx_info->tcb[tcb->id] = tcb; + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; + unmap_q->q_depth = BNAD_TX_UNMAPQ_DEPTH; +} + +static void +bnad_cb_tcb_destroy(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct bnad_tx_info *tx_info = + (struct bnad_tx_info *)tcb->txq->tx->priv; + + tx_info->tcb[tcb->id] = NULL; +} + +static void +bnad_cb_rcb_setup(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; + unmap_q->q_depth = BNAD_RX_UNMAPQ_DEPTH; +} + +static void +bnad_cb_ccb_setup(struct bnad *bnad, struct bna_ccb *ccb) +{ + struct bnad_rx_info *rx_info = + (struct bnad_rx_info *)ccb->cq->rx->priv; + + rx_info->rx_ctrl[ccb->id].ccb = ccb; + ccb->ctrl = &rx_info->rx_ctrl[ccb->id]; +} + +static void +bnad_cb_ccb_destroy(struct bnad *bnad, struct bna_ccb *ccb) +{ + struct bnad_rx_info *rx_info = + (struct bnad_rx_info *)ccb->cq->rx->priv; + + rx_info->rx_ctrl[ccb->id].ccb = NULL; +} + +static void +bnad_cb_tx_stall(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct bnad_tx_info *tx_info = + (struct bnad_tx_info *)tcb->txq->tx->priv; + + if (tx_info != &bnad->tx_info[0]) + return; + + clear_bit(BNAD_RF_TX_STARTED, &bnad->run_flags); + netif_stop_queue(bnad->netdev); + pr_info("bna: %s TX_STOPPED\n", bnad->netdev->name); +} + +static void +bnad_cb_tx_resume(struct bnad *bnad, struct bna_tcb *tcb) +{ + if (test_and_set_bit(BNAD_RF_TX_STARTED, &bnad->run_flags)) + return; + + if (netif_carrier_ok(bnad->netdev)) { + pr_info("bna: %s TX_STARTED\n", bnad->netdev->name); + netif_wake_queue(bnad->netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } +} + +static void +bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tcb *tcb) +{ + struct bnad_unmap_q *unmap_q; + + if (!tcb || (!tcb->unmap_q)) + return; + + unmap_q = tcb->unmap_q; + if (!unmap_q->unmap_array) + return; + + if (test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) + return; + + bnad_free_all_txbufs(bnad, tcb); + + unmap_q->producer_index = 0; + unmap_q->consumer_index = 0; + + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); +} + +static void +bnad_cb_rx_cleanup(struct bnad *bnad, + struct bna_ccb *ccb) +{ + bnad_cq_cmpl_init(bnad, ccb); + + bnad_free_rxbufs(bnad, ccb->rcb[0]); + clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags); + + if (ccb->rcb[1]) { + bnad_free_rxbufs(bnad, ccb->rcb[1]); + clear_bit(BNAD_RXQ_STARTED, &ccb->rcb[1]->flags); + } +} + +static void +bnad_cb_rx_post(struct bnad *bnad, struct bna_rcb *rcb) +{ + struct bnad_unmap_q *unmap_q = rcb->unmap_q; + + set_bit(BNAD_RXQ_STARTED, &rcb->flags); + + /* Now allocate & post buffers for this RCB */ + /* !!Allocation in callback context */ + if (!test_and_set_bit(BNAD_RXQ_REFILL, &rcb->flags)) { + if (BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth) + >> BNAD_RXQ_REFILL_THRESHOLD_SHIFT) + bnad_alloc_n_post_rxbufs(bnad, rcb); + smp_mb__before_clear_bit(); + clear_bit(BNAD_RXQ_REFILL, &rcb->flags); + } +} + +static void +bnad_cb_rx_disabled(void *arg, struct bna_rx *rx, + enum bna_cb_status status) +{ + struct bnad *bnad = (struct bnad *)arg; + + complete(&bnad->bnad_completions.rx_comp); +} + +static void +bnad_cb_rx_mcast_add(struct bnad *bnad, struct bna_rx *rx, + enum bna_cb_status status) +{ + bnad->bnad_completions.mcast_comp_status = status; + complete(&bnad->bnad_completions.mcast_comp); +} + +void +bnad_cb_stats_get(struct bnad *bnad, enum bna_cb_status status, + struct bna_stats *stats) +{ + if (status == BNA_CB_SUCCESS) + BNAD_UPDATE_CTR(bnad, hw_stats_updates); + + if (!netif_running(bnad->netdev) || + !test_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) + return; + + mod_timer(&bnad->stats_timer, + jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ)); +} + +/* Resource allocation, free functions */ + +static void +bnad_mem_free(struct bnad *bnad, + struct bna_mem_info *mem_info) +{ + int i; + dma_addr_t dma_pa; + + if (mem_info->mdl == NULL) + return; + + for (i = 0; i < mem_info->num; i++) { + if (mem_info->mdl[i].kva != NULL) { + if (mem_info->mem_type == BNA_MEM_T_DMA) { + BNA_GET_DMA_ADDR(&(mem_info->mdl[i].dma), + dma_pa); + pci_free_consistent(bnad->pcidev, + mem_info->mdl[i].len, + mem_info->mdl[i].kva, dma_pa); + } else + kfree(mem_info->mdl[i].kva); + } + } + kfree(mem_info->mdl); + mem_info->mdl = NULL; +} + +static int +bnad_mem_alloc(struct bnad *bnad, + struct bna_mem_info *mem_info) +{ + int i; + dma_addr_t dma_pa; + + if ((mem_info->num == 0) || (mem_info->len == 0)) { + mem_info->mdl = NULL; + return 0; + } + + mem_info->mdl = kcalloc(mem_info->num, sizeof(struct bna_mem_descr), + GFP_KERNEL); + if (mem_info->mdl == NULL) + return -ENOMEM; + + if (mem_info->mem_type == BNA_MEM_T_DMA) { + for (i = 0; i < mem_info->num; i++) { + mem_info->mdl[i].len = mem_info->len; + mem_info->mdl[i].kva = + pci_alloc_consistent(bnad->pcidev, + mem_info->len, &dma_pa); + + if (mem_info->mdl[i].kva == NULL) + goto err_return; + + BNA_SET_DMA_ADDR(dma_pa, + &(mem_info->mdl[i].dma)); + } + } else { + for (i = 0; i < mem_info->num; i++) { + mem_info->mdl[i].len = mem_info->len; + mem_info->mdl[i].kva = kzalloc(mem_info->len, + GFP_KERNEL); + if (mem_info->mdl[i].kva == NULL) + goto err_return; + } + } + + return 0; + +err_return: + bnad_mem_free(bnad, mem_info); + return -ENOMEM; +} + +/* Free IRQ for Mailbox */ +static void +bnad_mbox_irq_free(struct bnad *bnad, + struct bna_intr_info *intr_info) +{ + int irq; + unsigned long flags; + + if (intr_info->idl == NULL) + return; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bnad_disable_mbox_irq(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + irq = BNAD_GET_MBOX_IRQ(bnad); + free_irq(irq, bnad->netdev); + + kfree(intr_info->idl); +} + +/* + * Allocates IRQ for Mailbox, but keep it disabled + * This will be enabled once we get the mbox enable callback + * from bna + */ +static int +bnad_mbox_irq_alloc(struct bnad *bnad, + struct bna_intr_info *intr_info) +{ + int err; + unsigned long flags; + u32 irq; + irq_handler_t irq_handler; + + /* Mbox should use only 1 vector */ + + intr_info->idl = kzalloc(sizeof(*(intr_info->idl)), GFP_KERNEL); + if (!intr_info->idl) + return -ENOMEM; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (bnad->cfg_flags & BNAD_CF_MSIX) { + irq_handler = (irq_handler_t)bnad_msix_mbox_handler; + irq = bnad->msix_table[bnad->msix_num - 1].vector; + flags = 0; + intr_info->intr_type = BNA_INTR_T_MSIX; + intr_info->idl[0].vector = bnad->msix_num - 1; + } else { + irq_handler = (irq_handler_t)bnad_isr; + irq = bnad->pcidev->irq; + flags = IRQF_SHARED; + intr_info->intr_type = BNA_INTR_T_INTX; + /* intr_info->idl.vector = 0 ? */ + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); + + /* + * Set the Mbox IRQ disable flag, so that the IRQ handler + * called from request_irq() for SHARED IRQs do not execute + */ + set_bit(BNAD_RF_MBOX_IRQ_DISABLED, &bnad->run_flags); + + err = request_irq(irq, irq_handler, flags, + bnad->mbox_irq_name, bnad->netdev); + + if (err) { + kfree(intr_info->idl); + intr_info->idl = NULL; + return err; + } + + spin_lock_irqsave(&bnad->bna_lock, flags); + + if (bnad->cfg_flags & BNAD_CF_MSIX) + disable_irq_nosync(irq); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + return 0; +} + +static void +bnad_txrx_irq_free(struct bnad *bnad, struct bna_intr_info *intr_info) +{ + kfree(intr_info->idl); + intr_info->idl = NULL; +} + +/* Allocates Interrupt Descriptor List for MSIX/INT-X vectors */ +static int +bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src, + uint txrx_id, struct bna_intr_info *intr_info) +{ + int i, vector_start = 0; + u32 cfg_flags; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + cfg_flags = bnad->cfg_flags; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (cfg_flags & BNAD_CF_MSIX) { + intr_info->intr_type = BNA_INTR_T_MSIX; + intr_info->idl = kcalloc(intr_info->num, + sizeof(struct bna_intr_descr), + GFP_KERNEL); + if (!intr_info->idl) + return -ENOMEM; + + switch (src) { + case BNAD_INTR_TX: + vector_start = txrx_id; + break; + + case BNAD_INTR_RX: + vector_start = bnad->num_tx * bnad->num_txq_per_tx + + txrx_id; + break; + + default: + BUG(); + } + + for (i = 0; i < intr_info->num; i++) + intr_info->idl[i].vector = vector_start + i; + } else { + intr_info->intr_type = BNA_INTR_T_INTX; + intr_info->num = 1; + intr_info->idl = kcalloc(intr_info->num, + sizeof(struct bna_intr_descr), + GFP_KERNEL); + if (!intr_info->idl) + return -ENOMEM; + + switch (src) { + case BNAD_INTR_TX: + intr_info->idl[0].vector = 0x1; /* Bit mask : Tx IB */ + break; + + case BNAD_INTR_RX: + intr_info->idl[0].vector = 0x2; /* Bit mask : Rx IB */ + break; + } + } + return 0; +} + +/** + * NOTE: Should be called for MSIX only + * Unregisters Tx MSIX vector(s) from the kernel + */ +static void +bnad_tx_msix_unregister(struct bnad *bnad, struct bnad_tx_info *tx_info, + int num_txqs) +{ + int i; + int vector_num; + + for (i = 0; i < num_txqs; i++) { + if (tx_info->tcb[i] == NULL) + continue; + + vector_num = tx_info->tcb[i]->intr_vector; + free_irq(bnad->msix_table[vector_num].vector, tx_info->tcb[i]); + } +} + +/** + * NOTE: Should be called for MSIX only + * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel + */ +static int +bnad_tx_msix_register(struct bnad *bnad, struct bnad_tx_info *tx_info, + uint tx_id, int num_txqs) +{ + int i; + int err; + int vector_num; + + for (i = 0; i < num_txqs; i++) { + vector_num = tx_info->tcb[i]->intr_vector; + sprintf(tx_info->tcb[i]->name, "%s TXQ %d", bnad->netdev->name, + tx_id + tx_info->tcb[i]->id); + err = request_irq(bnad->msix_table[vector_num].vector, + (irq_handler_t)bnad_msix_tx, 0, + tx_info->tcb[i]->name, + tx_info->tcb[i]); + if (err) + goto err_return; + } + + return 0; + +err_return: + if (i > 0) + bnad_tx_msix_unregister(bnad, tx_info, (i - 1)); + return -1; +} + +/** + * NOTE: Should be called for MSIX only + * Unregisters Rx MSIX vector(s) from the kernel + */ +static void +bnad_rx_msix_unregister(struct bnad *bnad, struct bnad_rx_info *rx_info, + int num_rxps) +{ + int i; + int vector_num; + + for (i = 0; i < num_rxps; i++) { + if (rx_info->rx_ctrl[i].ccb == NULL) + continue; + + vector_num = rx_info->rx_ctrl[i].ccb->intr_vector; + free_irq(bnad->msix_table[vector_num].vector, + rx_info->rx_ctrl[i].ccb); + } +} + +/** + * NOTE: Should be called for MSIX only + * Registers Tx MSIX vector(s) and ISR(s), cookie with the kernel + */ +static int +bnad_rx_msix_register(struct bnad *bnad, struct bnad_rx_info *rx_info, + uint rx_id, int num_rxps) +{ + int i; + int err; + int vector_num; + + for (i = 0; i < num_rxps; i++) { + vector_num = rx_info->rx_ctrl[i].ccb->intr_vector; + sprintf(rx_info->rx_ctrl[i].ccb->name, "%s CQ %d", + bnad->netdev->name, + rx_id + rx_info->rx_ctrl[i].ccb->id); + err = request_irq(bnad->msix_table[vector_num].vector, + (irq_handler_t)bnad_msix_rx, 0, + rx_info->rx_ctrl[i].ccb->name, + rx_info->rx_ctrl[i].ccb); + if (err) + goto err_return; + } + + return 0; + +err_return: + if (i > 0) + bnad_rx_msix_unregister(bnad, rx_info, (i - 1)); + return -1; +} + +/* Free Tx object Resources */ +static void +bnad_tx_res_free(struct bnad *bnad, struct bna_res_info *res_info) +{ + int i; + + for (i = 0; i < BNA_TX_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + bnad_mem_free(bnad, &res_info[i].res_u.mem_info); + else if (res_info[i].res_type == BNA_RES_T_INTR) + bnad_txrx_irq_free(bnad, &res_info[i].res_u.intr_info); + } +} + +/* Allocates memory and interrupt resources for Tx object */ +static int +bnad_tx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info, + uint tx_id) +{ + int i, err = 0; + + for (i = 0; i < BNA_TX_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + err = bnad_mem_alloc(bnad, + &res_info[i].res_u.mem_info); + else if (res_info[i].res_type == BNA_RES_T_INTR) + err = bnad_txrx_irq_alloc(bnad, BNAD_INTR_TX, tx_id, + &res_info[i].res_u.intr_info); + if (err) + goto err_return; + } + return 0; + +err_return: + bnad_tx_res_free(bnad, res_info); + return err; +} + +/* Free Rx object Resources */ +static void +bnad_rx_res_free(struct bnad *bnad, struct bna_res_info *res_info) +{ + int i; + + for (i = 0; i < BNA_RX_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + bnad_mem_free(bnad, &res_info[i].res_u.mem_info); + else if (res_info[i].res_type == BNA_RES_T_INTR) + bnad_txrx_irq_free(bnad, &res_info[i].res_u.intr_info); + } +} + +/* Allocates memory and interrupt resources for Rx object */ +static int +bnad_rx_res_alloc(struct bnad *bnad, struct bna_res_info *res_info, + uint rx_id) +{ + int i, err = 0; + + /* All memory needs to be allocated before setup_ccbs */ + for (i = 0; i < BNA_RX_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + err = bnad_mem_alloc(bnad, + &res_info[i].res_u.mem_info); + else if (res_info[i].res_type == BNA_RES_T_INTR) + err = bnad_txrx_irq_alloc(bnad, BNAD_INTR_RX, rx_id, + &res_info[i].res_u.intr_info); + if (err) + goto err_return; + } + return 0; + +err_return: + bnad_rx_res_free(bnad, res_info); + return err; +} + +/* Timer callbacks */ +/* a) IOC timer */ +static void +bnad_ioc_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_nw_ioc_timeout((void *) &bnad->bna.device.ioc); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static void +bnad_ioc_hb_check(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_nw_ioc_hb_check((void *) &bnad->bna.device.ioc); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static void +bnad_ioc_sem_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_nw_ioc_sem_timeout((void *) &bnad->bna.device.ioc); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* + * All timer routines use bnad->bna_lock to protect against + * the following race, which may occur in case of no locking: + * Time CPU m CPU n + * 0 1 = test_bit + * 1 clear_bit + * 2 del_timer_sync + * 3 mod_timer + */ + +/* b) Dynamic Interrupt Moderation Timer */ +static void +bnad_dim_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + struct bnad_rx_info *rx_info; + struct bnad_rx_ctrl *rx_ctrl; + int i, j; + unsigned long flags; + + if (!netif_carrier_ok(bnad->netdev)) + return; + + spin_lock_irqsave(&bnad->bna_lock, flags); + for (i = 0; i < bnad->num_rx; i++) { + rx_info = &bnad->rx_info[i]; + if (!rx_info->rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + rx_ctrl = &rx_info->rx_ctrl[j]; + if (!rx_ctrl->ccb) + continue; + bna_rx_dim_update(rx_ctrl->ccb); + } + } + + /* Check for BNAD_CF_DIM_ENABLED, does not eleminate a race */ + if (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags)) + mod_timer(&bnad->dim_timer, + jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ)); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* c) Statistics Timer */ +static void +bnad_stats_timeout(unsigned long data) +{ + struct bnad *bnad = (struct bnad *)data; + unsigned long flags; + + if (!netif_running(bnad->netdev) || + !test_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) + return; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_stats_get(&bnad->bna); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* + * Set up timer for DIM + * Called with bnad->bna_lock held + */ +void +bnad_dim_timer_start(struct bnad *bnad) +{ + if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED && + !test_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags)) { + setup_timer(&bnad->dim_timer, bnad_dim_timeout, + (unsigned long)bnad); + set_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags); + mod_timer(&bnad->dim_timer, + jiffies + msecs_to_jiffies(BNAD_DIM_TIMER_FREQ)); + } +} + +/* + * Set up timer for statistics + * Called with mutex_lock(&bnad->conf_mutex) held + */ +static void +bnad_stats_timer_start(struct bnad *bnad) +{ + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (!test_and_set_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) { + setup_timer(&bnad->stats_timer, bnad_stats_timeout, + (unsigned long)bnad); + mod_timer(&bnad->stats_timer, + jiffies + msecs_to_jiffies(BNAD_STATS_TIMER_FREQ)); + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* + * Stops the stats timer + * Called with mutex_lock(&bnad->conf_mutex) held + */ +static void +bnad_stats_timer_stop(struct bnad *bnad) +{ + int to_del = 0; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (test_and_clear_bit(BNAD_RF_STATS_TIMER_RUNNING, &bnad->run_flags)) + to_del = 1; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (to_del) + del_timer_sync(&bnad->stats_timer); +} + +/* Utilities */ + +static void +bnad_netdev_mc_list_get(struct net_device *netdev, u8 *mc_list) +{ + int i = 1; /* Index 0 has broadcast address */ + struct netdev_hw_addr *mc_addr; + + netdev_for_each_mc_addr(mc_addr, netdev) { + memcpy(&mc_list[i * ETH_ALEN], &mc_addr->addr[0], + ETH_ALEN); + i++; + } +} + +static int +bnad_napi_poll_rx(struct napi_struct *napi, int budget) +{ + struct bnad_rx_ctrl *rx_ctrl = + container_of(napi, struct bnad_rx_ctrl, napi); + struct bna_ccb *ccb; + struct bnad *bnad; + int rcvd = 0; + + ccb = rx_ctrl->ccb; + + bnad = ccb->bnad; + + if (!netif_carrier_ok(bnad->netdev)) + goto poll_exit; + + rcvd = bnad_poll_cq(bnad, ccb, budget); + if (rcvd == budget) + return rcvd; + +poll_exit: + napi_complete((napi)); + + BNAD_UPDATE_CTR(bnad, netif_rx_complete); + + bnad_enable_rx_irq(bnad, ccb); + return rcvd; +} + +static int +bnad_napi_poll_txrx(struct napi_struct *napi, int budget) +{ + struct bnad_rx_ctrl *rx_ctrl = + container_of(napi, struct bnad_rx_ctrl, napi); + struct bna_ccb *ccb; + struct bnad *bnad; + int rcvd = 0; + int i, j; + + ccb = rx_ctrl->ccb; + + bnad = ccb->bnad; + + if (!netif_carrier_ok(bnad->netdev)) + goto poll_exit; + + /* Handle Tx Completions, if any */ + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) + bnad_tx(bnad, bnad->tx_info[i].tcb[j]); + } + + /* Handle Rx Completions */ + rcvd = bnad_poll_cq(bnad, ccb, budget); + if (rcvd == budget) + return rcvd; +poll_exit: + napi_complete((napi)); + + BNAD_UPDATE_CTR(bnad, netif_rx_complete); + + bnad_enable_txrx_irqs(bnad); + return rcvd; +} + +static void +bnad_napi_enable(struct bnad *bnad, u32 rx_id) +{ + int (*napi_poll) (struct napi_struct *, int); + struct bnad_rx_ctrl *rx_ctrl; + int i; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (bnad->cfg_flags & BNAD_CF_MSIX) + napi_poll = bnad_napi_poll_rx; + else + napi_poll = bnad_napi_poll_txrx; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Initialize & enable NAPI */ + for (i = 0; i < bnad->num_rxp_per_rx; i++) { + rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i]; + netif_napi_add(bnad->netdev, &rx_ctrl->napi, + napi_poll, 64); + napi_enable(&rx_ctrl->napi); + } +} + +static void +bnad_napi_disable(struct bnad *bnad, u32 rx_id) +{ + int i; + + /* First disable and then clean up */ + for (i = 0; i < bnad->num_rxp_per_rx; i++) { + napi_disable(&bnad->rx_info[rx_id].rx_ctrl[i].napi); + netif_napi_del(&bnad->rx_info[rx_id].rx_ctrl[i].napi); + } +} + +/* Should be held with conf_lock held */ +void +bnad_cleanup_tx(struct bnad *bnad, uint tx_id) +{ + struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id]; + struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0]; + unsigned long flags; + + if (!tx_info->tx) + return; + + init_completion(&bnad->bnad_completions.tx_comp); + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_tx_disable(tx_info->tx, BNA_HARD_CLEANUP, bnad_cb_tx_disabled); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + wait_for_completion(&bnad->bnad_completions.tx_comp); + + if (tx_info->tcb[0]->intr_type == BNA_INTR_T_MSIX) + bnad_tx_msix_unregister(bnad, tx_info, + bnad->num_txq_per_tx); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_tx_destroy(tx_info->tx); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + tx_info->tx = NULL; + + if (0 == tx_id) + tasklet_kill(&bnad->tx_free_tasklet); + + bnad_tx_res_free(bnad, res_info); +} + +/* Should be held with conf_lock held */ +int +bnad_setup_tx(struct bnad *bnad, uint tx_id) +{ + int err; + struct bnad_tx_info *tx_info = &bnad->tx_info[tx_id]; + struct bna_res_info *res_info = &bnad->tx_res_info[tx_id].res_info[0]; + struct bna_intr_info *intr_info = + &res_info[BNA_TX_RES_INTR_T_TXCMPL].res_u.intr_info; + struct bna_tx_config *tx_config = &bnad->tx_config[tx_id]; + struct bna_tx_event_cbfn tx_cbfn; + struct bna_tx *tx; + unsigned long flags; + + /* Initialize the Tx object configuration */ + tx_config->num_txq = bnad->num_txq_per_tx; + tx_config->txq_depth = bnad->txq_depth; + tx_config->tx_type = BNA_TX_T_REGULAR; + + /* Initialize the tx event handlers */ + tx_cbfn.tcb_setup_cbfn = bnad_cb_tcb_setup; + tx_cbfn.tcb_destroy_cbfn = bnad_cb_tcb_destroy; + tx_cbfn.tx_stall_cbfn = bnad_cb_tx_stall; + tx_cbfn.tx_resume_cbfn = bnad_cb_tx_resume; + tx_cbfn.tx_cleanup_cbfn = bnad_cb_tx_cleanup; + + /* Get BNA's resource requirement for one tx object */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_tx_res_req(bnad->num_txq_per_tx, + bnad->txq_depth, res_info); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Fill Unmap Q memory requirements */ + BNAD_FILL_UNMAPQ_MEM_REQ( + &res_info[BNA_TX_RES_MEM_T_UNMAPQ], + bnad->num_txq_per_tx, + BNAD_TX_UNMAPQ_DEPTH); + + /* Allocate resources */ + err = bnad_tx_res_alloc(bnad, res_info, tx_id); + if (err) + return err; + + /* Ask BNA to create one Tx object, supplying required resources */ + spin_lock_irqsave(&bnad->bna_lock, flags); + tx = bna_tx_create(&bnad->bna, bnad, tx_config, &tx_cbfn, res_info, + tx_info); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (!tx) + goto err_return; + tx_info->tx = tx; + + /* Register ISR for the Tx object */ + if (intr_info->intr_type == BNA_INTR_T_MSIX) { + err = bnad_tx_msix_register(bnad, tx_info, + tx_id, bnad->num_txq_per_tx); + if (err) + goto err_return; + } + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_tx_enable(tx); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + return 0; + +err_return: + bnad_tx_res_free(bnad, res_info); + return err; +} + +/* Setup the rx config for bna_rx_create */ +/* bnad decides the configuration */ +static void +bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config) +{ + rx_config->rx_type = BNA_RX_T_REGULAR; + rx_config->num_paths = bnad->num_rxp_per_rx; + + if (bnad->num_rxp_per_rx > 1) { + rx_config->rss_status = BNA_STATUS_T_ENABLED; + rx_config->rss_config.hash_type = + (BFI_RSS_T_V4_TCP | + BFI_RSS_T_V6_TCP | + BFI_RSS_T_V4_IP | + BFI_RSS_T_V6_IP); + rx_config->rss_config.hash_mask = + bnad->num_rxp_per_rx - 1; + get_random_bytes(rx_config->rss_config.toeplitz_hash_key, + sizeof(rx_config->rss_config.toeplitz_hash_key)); + } else { + rx_config->rss_status = BNA_STATUS_T_DISABLED; + memset(&rx_config->rss_config, 0, + sizeof(rx_config->rss_config)); + } + rx_config->rxp_type = BNA_RXP_SLR; + rx_config->q_depth = bnad->rxq_depth; + + rx_config->small_buff_size = BFI_SMALL_RXBUF_SIZE; + + rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED; +} + +/* Called with mutex_lock(&bnad->conf_mutex) held */ +void +bnad_cleanup_rx(struct bnad *bnad, uint rx_id) +{ + struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id]; + struct bna_rx_config *rx_config = &bnad->rx_config[rx_id]; + struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0]; + unsigned long flags; + int dim_timer_del = 0; + + if (!rx_info->rx) + return; + + if (0 == rx_id) { + spin_lock_irqsave(&bnad->bna_lock, flags); + dim_timer_del = bnad_dim_timer_running(bnad); + if (dim_timer_del) + clear_bit(BNAD_RF_DIM_TIMER_RUNNING, &bnad->run_flags); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (dim_timer_del) + del_timer_sync(&bnad->dim_timer); + } + + bnad_napi_disable(bnad, rx_id); + + init_completion(&bnad->bnad_completions.rx_comp); + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_disable(rx_info->rx, BNA_HARD_CLEANUP, bnad_cb_rx_disabled); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + wait_for_completion(&bnad->bnad_completions.rx_comp); + + if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX) + bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_destroy(rx_info->rx); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + rx_info->rx = NULL; + + bnad_rx_res_free(bnad, res_info); +} + +/* Called with mutex_lock(&bnad->conf_mutex) held */ +int +bnad_setup_rx(struct bnad *bnad, uint rx_id) +{ + int err; + struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id]; + struct bna_res_info *res_info = &bnad->rx_res_info[rx_id].res_info[0]; + struct bna_intr_info *intr_info = + &res_info[BNA_RX_RES_T_INTR].res_u.intr_info; + struct bna_rx_config *rx_config = &bnad->rx_config[rx_id]; + struct bna_rx_event_cbfn rx_cbfn; + struct bna_rx *rx; + unsigned long flags; + + /* Initialize the Rx object configuration */ + bnad_init_rx_config(bnad, rx_config); + + /* Initialize the Rx event handlers */ + rx_cbfn.rcb_setup_cbfn = bnad_cb_rcb_setup; + rx_cbfn.rcb_destroy_cbfn = NULL; + rx_cbfn.ccb_setup_cbfn = bnad_cb_ccb_setup; + rx_cbfn.ccb_destroy_cbfn = bnad_cb_ccb_destroy; + rx_cbfn.rx_cleanup_cbfn = bnad_cb_rx_cleanup; + rx_cbfn.rx_post_cbfn = bnad_cb_rx_post; + + /* Get BNA's resource requirement for one Rx object */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_res_req(rx_config, res_info); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Fill Unmap Q memory requirements */ + BNAD_FILL_UNMAPQ_MEM_REQ( + &res_info[BNA_RX_RES_MEM_T_UNMAPQ], + rx_config->num_paths + + ((rx_config->rxp_type == BNA_RXP_SINGLE) ? 0 : + rx_config->num_paths), BNAD_RX_UNMAPQ_DEPTH); + + /* Allocate resource */ + err = bnad_rx_res_alloc(bnad, res_info, rx_id); + if (err) + return err; + + /* Ask BNA to create one Rx object, supplying required resources */ + spin_lock_irqsave(&bnad->bna_lock, flags); + rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info, + rx_info); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + if (!rx) + goto err_return; + rx_info->rx = rx; + + /* Register ISR for the Rx object */ + if (intr_info->intr_type == BNA_INTR_T_MSIX) { + err = bnad_rx_msix_register(bnad, rx_info, rx_id, + rx_config->num_paths); + if (err) + goto err_return; + } + + /* Enable NAPI */ + bnad_napi_enable(bnad, rx_id); + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (0 == rx_id) { + /* Set up Dynamic Interrupt Moderation Vector */ + if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) + bna_rx_dim_reconfig(&bnad->bna, bna_napi_dim_vector); + + /* Enable VLAN filtering only on the default Rx */ + bna_rx_vlanfilter_enable(rx); + + /* Start the DIM timer */ + bnad_dim_timer_start(bnad); + } + + bna_rx_enable(rx); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + return 0; + +err_return: + bnad_cleanup_rx(bnad, rx_id); + return err; +} + +/* Called with conf_lock & bnad->bna_lock held */ +void +bnad_tx_coalescing_timeo_set(struct bnad *bnad) +{ + struct bnad_tx_info *tx_info; + + tx_info = &bnad->tx_info[0]; + if (!tx_info->tx) + return; + + bna_tx_coalescing_timeo_set(tx_info->tx, bnad->tx_coalescing_timeo); +} + +/* Called with conf_lock & bnad->bna_lock held */ +void +bnad_rx_coalescing_timeo_set(struct bnad *bnad) +{ + struct bnad_rx_info *rx_info; + int i; + + for (i = 0; i < bnad->num_rx; i++) { + rx_info = &bnad->rx_info[i]; + if (!rx_info->rx) + continue; + bna_rx_coalescing_timeo_set(rx_info->rx, + bnad->rx_coalescing_timeo); + } +} + +/* + * Called with bnad->bna_lock held + */ +static int +bnad_mac_addr_set_locked(struct bnad *bnad, u8 *mac_addr) +{ + int ret; + + if (!is_valid_ether_addr(mac_addr)) + return -EADDRNOTAVAIL; + + /* If datapath is down, pretend everything went through */ + if (!bnad->rx_info[0].rx) + return 0; + + ret = bna_rx_ucast_set(bnad->rx_info[0].rx, mac_addr, NULL); + if (ret != BNA_CB_SUCCESS) + return -EADDRNOTAVAIL; + + return 0; +} + +/* Should be called with conf_lock held */ +static int +bnad_enable_default_bcast(struct bnad *bnad) +{ + struct bnad_rx_info *rx_info = &bnad->rx_info[0]; + int ret; + unsigned long flags; + + init_completion(&bnad->bnad_completions.mcast_comp); + + spin_lock_irqsave(&bnad->bna_lock, flags); + ret = bna_rx_mcast_add(rx_info->rx, (u8 *)bnad_bcast_addr, + bnad_cb_rx_mcast_add); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (ret == BNA_CB_SUCCESS) + wait_for_completion(&bnad->bnad_completions.mcast_comp); + else + return -ENODEV; + + if (bnad->bnad_completions.mcast_comp_status != BNA_CB_SUCCESS) + return -ENODEV; + + return 0; +} + +/* Statistics utilities */ +void +bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats) +{ + int i, j; + + for (i = 0; i < bnad->num_rx; i++) { + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + if (bnad->rx_info[i].rx_ctrl[j].ccb) { + stats->rx_packets += bnad->rx_info[i]. + rx_ctrl[j].ccb->rcb[0]->rxq->rx_packets; + stats->rx_bytes += bnad->rx_info[i]. + rx_ctrl[j].ccb->rcb[0]->rxq->rx_bytes; + if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[1]->rxq) { + stats->rx_packets += + bnad->rx_info[i].rx_ctrl[j]. + ccb->rcb[1]->rxq->rx_packets; + stats->rx_bytes += + bnad->rx_info[i].rx_ctrl[j]. + ccb->rcb[1]->rxq->rx_bytes; + } + } + } + } + for (i = 0; i < bnad->num_tx; i++) { + for (j = 0; j < bnad->num_txq_per_tx; j++) { + if (bnad->tx_info[i].tcb[j]) { + stats->tx_packets += + bnad->tx_info[i].tcb[j]->txq->tx_packets; + stats->tx_bytes += + bnad->tx_info[i].tcb[j]->txq->tx_bytes; + } + } + } +} + +/* + * Must be called with the bna_lock held. + */ +void +bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats) +{ + struct bfi_ll_stats_mac *mac_stats; + u64 bmap; + int i; + + mac_stats = &bnad->stats.bna_stats->hw_stats->mac_stats; + stats->rx_errors = + mac_stats->rx_fcs_error + mac_stats->rx_alignment_error + + mac_stats->rx_frame_length_error + mac_stats->rx_code_error + + mac_stats->rx_undersize; + stats->tx_errors = mac_stats->tx_fcs_error + + mac_stats->tx_undersize; + stats->rx_dropped = mac_stats->rx_drop; + stats->tx_dropped = mac_stats->tx_drop; + stats->multicast = mac_stats->rx_multicast; + stats->collisions = mac_stats->tx_total_collision; + + stats->rx_length_errors = mac_stats->rx_frame_length_error; + + /* receive ring buffer overflow ?? */ + + stats->rx_crc_errors = mac_stats->rx_fcs_error; + stats->rx_frame_errors = mac_stats->rx_alignment_error; + /* recv'r fifo overrun */ + bmap = (u64)bnad->stats.bna_stats->rxf_bmap[0] | + ((u64)bnad->stats.bna_stats->rxf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { + if (bmap & 1) { + stats->rx_fifo_errors += + bnad->stats.bna_stats-> + hw_stats->rxf_stats[i].frame_drops; + break; + } + bmap >>= 1; + } +} + +static void +bnad_mbox_irq_sync(struct bnad *bnad) +{ + u32 irq; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (bnad->cfg_flags & BNAD_CF_MSIX) + irq = bnad->msix_table[bnad->msix_num - 1].vector; + else + irq = bnad->pcidev->irq; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + synchronize_irq(irq); +} + +/* Utility used by bnad_start_xmit, for doing TSO */ +static int +bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb) +{ + int err; + + /* SKB_GSO_TCPV4 and SKB_GSO_TCPV6 is defined since 2.6.18. */ + BUG_ON(!(skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4 || + skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)); + if (skb_header_cloned(skb)) { + err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); + if (err) { + BNAD_UPDATE_CTR(bnad, tso_err); + return err; + } + } + + /* + * For TSO, the TCP checksum field is seeded with pseudo-header sum + * excluding the length field. + */ + if (skb->protocol == htons(ETH_P_IP)) { + struct iphdr *iph = ip_hdr(skb); + + /* Do we really need these? */ + iph->tot_len = 0; + iph->check = 0; + + tcp_hdr(skb)->check = + ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0, + IPPROTO_TCP, 0); + BNAD_UPDATE_CTR(bnad, tso4); + } else { + struct ipv6hdr *ipv6h = ipv6_hdr(skb); + + BUG_ON(!(skb->protocol == htons(ETH_P_IPV6))); + ipv6h->payload_len = 0; + tcp_hdr(skb)->check = + ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, 0, + IPPROTO_TCP, 0); + BNAD_UPDATE_CTR(bnad, tso6); + } + + return 0; +} + +/* + * Initialize Q numbers depending on Rx Paths + * Called with bnad->bna_lock held, because of cfg_flags + * access. + */ +static void +bnad_q_num_init(struct bnad *bnad) +{ + int rxps; + + rxps = min((uint)num_online_cpus(), + (uint)(BNAD_MAX_RXS * BNAD_MAX_RXPS_PER_RX)); + + if (!(bnad->cfg_flags & BNAD_CF_MSIX)) + rxps = 1; /* INTx */ + + bnad->num_rx = 1; + bnad->num_tx = 1; + bnad->num_rxp_per_rx = rxps; + bnad->num_txq_per_tx = BNAD_TXQ_NUM; +} + +/* + * Adjusts the Q numbers, given a number of msix vectors + * Give preference to RSS as opposed to Tx priority Queues, + * in such a case, just use 1 Tx Q + * Called with bnad->bna_lock held b'cos of cfg_flags access + */ +static void +bnad_q_num_adjust(struct bnad *bnad, int msix_vectors) +{ + bnad->num_txq_per_tx = 1; + if ((msix_vectors >= (bnad->num_tx * bnad->num_txq_per_tx) + + bnad_rxqs_per_cq + BNAD_MAILBOX_MSIX_VECTORS) && + (bnad->cfg_flags & BNAD_CF_MSIX)) { + bnad->num_rxp_per_rx = msix_vectors - + (bnad->num_tx * bnad->num_txq_per_tx) - + BNAD_MAILBOX_MSIX_VECTORS; + } else + bnad->num_rxp_per_rx = 1; +} + +static void +bnad_set_netdev_perm_addr(struct bnad *bnad) +{ + struct net_device *netdev = bnad->netdev; + + memcpy(netdev->perm_addr, &bnad->perm_addr, netdev->addr_len); + if (is_zero_ether_addr(netdev->dev_addr)) + memcpy(netdev->dev_addr, &bnad->perm_addr, netdev->addr_len); +} + +/* Enable / disable device */ +static void +bnad_device_disable(struct bnad *bnad) +{ + unsigned long flags; + + init_completion(&bnad->bnad_completions.ioc_comp); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_device_disable(&bnad->bna.device, BNA_HARD_CLEANUP); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + wait_for_completion(&bnad->bnad_completions.ioc_comp); +} + +static int +bnad_device_enable(struct bnad *bnad) +{ + int err = 0; + unsigned long flags; + + init_completion(&bnad->bnad_completions.ioc_comp); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_device_enable(&bnad->bna.device); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + wait_for_completion(&bnad->bnad_completions.ioc_comp); + + if (bnad->bnad_completions.ioc_comp_status) + err = bnad->bnad_completions.ioc_comp_status; + + return err; +} + +/* Free BNA resources */ +static void +bnad_res_free(struct bnad *bnad) +{ + int i; + struct bna_res_info *res_info = &bnad->res_info[0]; + + for (i = 0; i < BNA_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + bnad_mem_free(bnad, &res_info[i].res_u.mem_info); + else + bnad_mbox_irq_free(bnad, &res_info[i].res_u.intr_info); + } +} + +/* Allocates memory and interrupt resources for BNA */ +static int +bnad_res_alloc(struct bnad *bnad) +{ + int i, err; + struct bna_res_info *res_info = &bnad->res_info[0]; + + for (i = 0; i < BNA_RES_T_MAX; i++) { + if (res_info[i].res_type == BNA_RES_T_MEM) + err = bnad_mem_alloc(bnad, &res_info[i].res_u.mem_info); + else + err = bnad_mbox_irq_alloc(bnad, + &res_info[i].res_u.intr_info); + if (err) + goto err_return; + } + return 0; + +err_return: + bnad_res_free(bnad); + return err; +} + +/* Interrupt enable / disable */ +static void +bnad_enable_msix(struct bnad *bnad) +{ + int i, ret; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (!(bnad->cfg_flags & BNAD_CF_MSIX)) { + spin_unlock_irqrestore(&bnad->bna_lock, flags); + return; + } + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (bnad->msix_table) + return; + + bnad->msix_table = + kcalloc(bnad->msix_num, sizeof(struct msix_entry), GFP_KERNEL); + + if (!bnad->msix_table) + goto intx_mode; + + for (i = 0; i < bnad->msix_num; i++) + bnad->msix_table[i].entry = i; + + ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, bnad->msix_num); + if (ret > 0) { + /* Not enough MSI-X vectors. */ + + spin_lock_irqsave(&bnad->bna_lock, flags); + /* ret = #of vectors that we got */ + bnad_q_num_adjust(bnad, ret); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx) + + (bnad->num_rx + * bnad->num_rxp_per_rx) + + BNAD_MAILBOX_MSIX_VECTORS; + + /* Try once more with adjusted numbers */ + /* If this fails, fall back to INTx */ + ret = pci_enable_msix(bnad->pcidev, bnad->msix_table, + bnad->msix_num); + if (ret) + goto intx_mode; + + } else if (ret < 0) + goto intx_mode; + return; + +intx_mode: + + kfree(bnad->msix_table); + bnad->msix_table = NULL; + bnad->msix_num = 0; + spin_lock_irqsave(&bnad->bna_lock, flags); + bnad->cfg_flags &= ~BNAD_CF_MSIX; + bnad_q_num_init(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +static void +bnad_disable_msix(struct bnad *bnad) +{ + u32 cfg_flags; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + cfg_flags = bnad->cfg_flags; + if (bnad->cfg_flags & BNAD_CF_MSIX) + bnad->cfg_flags &= ~BNAD_CF_MSIX; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + if (cfg_flags & BNAD_CF_MSIX) { + pci_disable_msix(bnad->pcidev); + kfree(bnad->msix_table); + bnad->msix_table = NULL; + } +} + +/* Netdev entry points */ +static int +bnad_open(struct net_device *netdev) +{ + int err; + struct bnad *bnad = netdev_priv(netdev); + struct bna_pause_config pause_config; + int mtu; + unsigned long flags; + + mutex_lock(&bnad->conf_mutex); + + /* Tx */ + err = bnad_setup_tx(bnad, 0); + if (err) + goto err_return; + + /* Rx */ + err = bnad_setup_rx(bnad, 0); + if (err) + goto cleanup_tx; + + /* Port */ + pause_config.tx_pause = 0; + pause_config.rx_pause = 0; + + mtu = ETH_HLEN + bnad->netdev->mtu + ETH_FCS_LEN; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_mtu_set(&bnad->bna.port, mtu, NULL); + bna_port_pause_config(&bnad->bna.port, &pause_config, NULL); + bna_port_enable(&bnad->bna.port); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Enable broadcast */ + bnad_enable_default_bcast(bnad); + + /* Set the UCAST address */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bnad_mac_addr_set_locked(bnad, netdev->dev_addr); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + /* Start the stats timer */ + bnad_stats_timer_start(bnad); + + mutex_unlock(&bnad->conf_mutex); + + return 0; + +cleanup_tx: + bnad_cleanup_tx(bnad, 0); + +err_return: + mutex_unlock(&bnad->conf_mutex); + return err; +} + +static int +bnad_stop(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + mutex_lock(&bnad->conf_mutex); + + /* Stop the stats timer */ + bnad_stats_timer_stop(bnad); + + init_completion(&bnad->bnad_completions.port_comp); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_disable(&bnad->bna.port, BNA_HARD_CLEANUP, + bnad_cb_port_disabled); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + wait_for_completion(&bnad->bnad_completions.port_comp); + + bnad_cleanup_tx(bnad, 0); + bnad_cleanup_rx(bnad, 0); + + /* Synchronize mailbox IRQ */ + bnad_mbox_irq_sync(bnad); + + mutex_unlock(&bnad->conf_mutex); + + return 0; +} + +/* TX */ +/* + * bnad_start_xmit : Netdev entry point for Transmit + * Called under lock held by net_device + */ +static netdev_tx_t +bnad_start_xmit(struct sk_buff *skb, struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + + u16 txq_prod, vlan_tag = 0; + u32 unmap_prod, wis, wis_used, wi_range; + u32 vectors, vect_id, i, acked; + u32 tx_id; + int err; + + struct bnad_tx_info *tx_info; + struct bna_tcb *tcb; + struct bnad_unmap_q *unmap_q; + dma_addr_t dma_addr; + struct bna_txq_entry *txqent; + bna_txq_wi_ctrl_flag_t flags; + + if (unlikely + (skb->len <= ETH_HLEN || skb->len > BFI_TX_MAX_DATA_PER_PKT)) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + /* + * Takes care of the Tx that is scheduled between clearing the flag + * and the netif_stop_queue() call. + */ + if (unlikely(!test_bit(BNAD_RF_TX_STARTED, &bnad->run_flags))) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + tx_id = 0; + + tx_info = &bnad->tx_info[tx_id]; + tcb = tx_info->tcb[tx_id]; + unmap_q = tcb->unmap_q; + + vectors = 1 + skb_shinfo(skb)->nr_frags; + if (vectors > BFI_TX_MAX_VECTORS_PER_PKT) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + wis = BNA_TXQ_WI_NEEDED(vectors); /* 4 vectors per work item */ + acked = 0; + if (unlikely + (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) || + vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) { + if ((u16) (*tcb->hw_consumer_index) != + tcb->consumer_index && + !test_and_set_bit(BNAD_TXQ_FREE_SENT, &tcb->flags)) { + acked = bnad_free_txbufs(bnad, tcb); + bna_ib_ack(tcb->i_dbell, acked); + smp_mb__before_clear_bit(); + clear_bit(BNAD_TXQ_FREE_SENT, &tcb->flags); + } else { + netif_stop_queue(netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_stop); + } + + smp_mb(); + /* + * Check again to deal with race condition between + * netif_stop_queue here, and netif_wake_queue in + * interrupt handler which is not inside netif tx lock. + */ + if (likely + (wis > BNA_QE_FREE_CNT(tcb, tcb->q_depth) || + vectors > BNA_QE_FREE_CNT(unmap_q, unmap_q->q_depth))) { + BNAD_UPDATE_CTR(bnad, netif_queue_stop); + return NETDEV_TX_BUSY; + } else { + netif_wake_queue(netdev); + BNAD_UPDATE_CTR(bnad, netif_queue_wakeup); + } + } + + unmap_prod = unmap_q->producer_index; + wis_used = 1; + vect_id = 0; + flags = 0; + + txq_prod = tcb->producer_index; + BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt, txqent, wi_range); + BUG_ON(!(wi_range <= tcb->q_depth)); + txqent->hdr.wi.reserved = 0; + txqent->hdr.wi.num_vectors = vectors; + txqent->hdr.wi.opcode = + htons((skb_is_gso(skb) ? BNA_TXQ_WI_SEND_LSO : + BNA_TXQ_WI_SEND)); + + if (vlan_tx_tag_present(skb)) { + vlan_tag = (u16) vlan_tx_tag_get(skb); + flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN); + } + if (test_bit(BNAD_RF_CEE_RUNNING, &bnad->run_flags)) { + vlan_tag = + (tcb->priority & 0x7) << 13 | (vlan_tag & 0x1fff); + flags |= (BNA_TXQ_WI_CF_INS_PRIO | BNA_TXQ_WI_CF_INS_VLAN); + } + + txqent->hdr.wi.vlan_tag = htons(vlan_tag); + + if (skb_is_gso(skb)) { + err = bnad_tso_prepare(bnad, skb); + if (err) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + txqent->hdr.wi.lso_mss = htons(skb_is_gso(skb)); + flags |= (BNA_TXQ_WI_CF_IP_CKSUM | BNA_TXQ_WI_CF_TCP_CKSUM); + txqent->hdr.wi.l4_hdr_size_n_offset = + htons(BNA_TXQ_WI_L4_HDR_N_OFFSET + (tcp_hdrlen(skb) >> 2, + skb_transport_offset(skb))); + } else if (skb->ip_summed == CHECKSUM_PARTIAL) { + u8 proto = 0; + + txqent->hdr.wi.lso_mss = 0; + + if (skb->protocol == htons(ETH_P_IP)) + proto = ip_hdr(skb)->protocol; + else if (skb->protocol == htons(ETH_P_IPV6)) { + /* nexthdr may not be TCP immediately. */ + proto = ipv6_hdr(skb)->nexthdr; + } + if (proto == IPPROTO_TCP) { + flags |= BNA_TXQ_WI_CF_TCP_CKSUM; + txqent->hdr.wi.l4_hdr_size_n_offset = + htons(BNA_TXQ_WI_L4_HDR_N_OFFSET + (0, skb_transport_offset(skb))); + + BNAD_UPDATE_CTR(bnad, tcpcsum_offload); + + BUG_ON(!(skb_headlen(skb) >= + skb_transport_offset(skb) + tcp_hdrlen(skb))); + + } else if (proto == IPPROTO_UDP) { + flags |= BNA_TXQ_WI_CF_UDP_CKSUM; + txqent->hdr.wi.l4_hdr_size_n_offset = + htons(BNA_TXQ_WI_L4_HDR_N_OFFSET + (0, skb_transport_offset(skb))); + + BNAD_UPDATE_CTR(bnad, udpcsum_offload); + + BUG_ON(!(skb_headlen(skb) >= + skb_transport_offset(skb) + + sizeof(struct udphdr))); + } else { + err = skb_checksum_help(skb); + BNAD_UPDATE_CTR(bnad, csum_help); + if (err) { + dev_kfree_skb(skb); + BNAD_UPDATE_CTR(bnad, csum_help_err); + return NETDEV_TX_OK; + } + } + } else { + txqent->hdr.wi.lso_mss = 0; + txqent->hdr.wi.l4_hdr_size_n_offset = 0; + } + + txqent->hdr.wi.flags = htons(flags); + + txqent->hdr.wi.frame_length = htonl(skb->len); + + unmap_q->unmap_array[unmap_prod].skb = skb; + BUG_ON(!(skb_headlen(skb) <= BFI_TX_MAX_DATA_PER_VECTOR)); + txqent->vector[vect_id].length = htons(skb_headlen(skb)); + dma_addr = pci_map_single(bnad->pcidev, skb->data, skb_headlen(skb), + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr, + dma_addr); + + BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr); + BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; + u32 size = frag->size; + + if (++vect_id == BFI_TX_MAX_VECTORS_PER_WI) { + vect_id = 0; + if (--wi_range) + txqent++; + else { + BNA_QE_INDX_ADD(txq_prod, wis_used, + tcb->q_depth); + wis_used = 0; + BNA_TXQ_QPGE_PTR_GET(txq_prod, tcb->sw_qpt, + txqent, wi_range); + BUG_ON(!(wi_range <= tcb->q_depth)); + } + wis_used++; + txqent->hdr.wi_ext.opcode = htons(BNA_TXQ_WI_EXTENSION); + } + + BUG_ON(!(size <= BFI_TX_MAX_DATA_PER_VECTOR)); + txqent->vector[vect_id].length = htons(size); + dma_addr = + pci_map_page(bnad->pcidev, frag->page, + frag->page_offset, size, + PCI_DMA_TODEVICE); + pci_unmap_addr_set(&unmap_q->unmap_array[unmap_prod], dma_addr, + dma_addr); + BNA_SET_DMA_ADDR(dma_addr, &txqent->vector[vect_id].host_addr); + BNA_QE_INDX_ADD(unmap_prod, 1, unmap_q->q_depth); + } + + unmap_q->producer_index = unmap_prod; + BNA_QE_INDX_ADD(txq_prod, wis_used, tcb->q_depth); + tcb->producer_index = txq_prod; + + smp_mb(); + bna_txq_prod_indx_doorbell(tcb); + + if ((u16) (*tcb->hw_consumer_index) != tcb->consumer_index) + tasklet_schedule(&bnad->tx_free_tasklet); + + return NETDEV_TX_OK; +} + +/* + * Used spin_lock to synchronize reading of stats structures, which + * is written by BNA under the same lock. + */ +static struct rtnl_link_stats64 * +bnad_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + bnad_netdev_qstats_fill(bnad, stats); + bnad_netdev_hwstats_fill(bnad, stats); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + return stats; +} + +static void +bnad_set_rx_mode(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + u32 new_mask, valid_mask; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + new_mask = valid_mask = 0; + + if (netdev->flags & IFF_PROMISC) { + if (!(bnad->cfg_flags & BNAD_CF_PROMISC)) { + new_mask = BNAD_RXMODE_PROMISC_DEFAULT; + valid_mask = BNAD_RXMODE_PROMISC_DEFAULT; + bnad->cfg_flags |= BNAD_CF_PROMISC; + } + } else { + if (bnad->cfg_flags & BNAD_CF_PROMISC) { + new_mask = ~BNAD_RXMODE_PROMISC_DEFAULT; + valid_mask = BNAD_RXMODE_PROMISC_DEFAULT; + bnad->cfg_flags &= ~BNAD_CF_PROMISC; + } + } + + if (netdev->flags & IFF_ALLMULTI) { + if (!(bnad->cfg_flags & BNAD_CF_ALLMULTI)) { + new_mask |= BNA_RXMODE_ALLMULTI; + valid_mask |= BNA_RXMODE_ALLMULTI; + bnad->cfg_flags |= BNAD_CF_ALLMULTI; + } + } else { + if (bnad->cfg_flags & BNAD_CF_ALLMULTI) { + new_mask &= ~BNA_RXMODE_ALLMULTI; + valid_mask |= BNA_RXMODE_ALLMULTI; + bnad->cfg_flags &= ~BNAD_CF_ALLMULTI; + } + } + + bna_rx_mode_set(bnad->rx_info[0].rx, new_mask, valid_mask, NULL); + + if (!netdev_mc_empty(netdev)) { + u8 *mcaddr_list; + int mc_count = netdev_mc_count(netdev); + + /* Index 0 holds the broadcast address */ + mcaddr_list = + kzalloc((mc_count + 1) * ETH_ALEN, + GFP_ATOMIC); + if (!mcaddr_list) + goto unlock; + + memcpy(&mcaddr_list[0], &bnad_bcast_addr[0], ETH_ALEN); + + /* Copy rest of the MC addresses */ + bnad_netdev_mc_list_get(netdev, mcaddr_list); + + bna_rx_mcast_listset(bnad->rx_info[0].rx, mc_count + 1, + mcaddr_list, NULL); + + /* Should we enable BNAD_CF_ALLMULTI for err != 0 ? */ + kfree(mcaddr_list); + } +unlock: + spin_unlock_irqrestore(&bnad->bna_lock, flags); +} + +/* + * bna_lock is used to sync writes to netdev->addr + * conf_lock cannot be used since this call may be made + * in a non-blocking context. + */ +static int +bnad_set_mac_address(struct net_device *netdev, void *mac_addr) +{ + int err; + struct bnad *bnad = netdev_priv(netdev); + struct sockaddr *sa = (struct sockaddr *)mac_addr; + unsigned long flags; + + spin_lock_irqsave(&bnad->bna_lock, flags); + + err = bnad_mac_addr_set_locked(bnad, sa->sa_data); + + if (!err) + memcpy(netdev->dev_addr, sa->sa_data, netdev->addr_len); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + return err; +} + +static int +bnad_change_mtu(struct net_device *netdev, int new_mtu) +{ + int mtu, err = 0; + unsigned long flags; + + struct bnad *bnad = netdev_priv(netdev); + + if (new_mtu + ETH_HLEN < ETH_ZLEN || new_mtu > BNAD_JUMBO_MTU) + return -EINVAL; + + mutex_lock(&bnad->conf_mutex); + + netdev->mtu = new_mtu; + + mtu = ETH_HLEN + new_mtu + ETH_FCS_LEN; + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_mtu_set(&bnad->bna.port, mtu, NULL); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); + return err; +} + +static void +bnad_vlan_rx_register(struct net_device *netdev, + struct vlan_group *vlan_grp) +{ + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + bnad->vlan_grp = vlan_grp; + mutex_unlock(&bnad->conf_mutex); +} + +static void +bnad_vlan_rx_add_vid(struct net_device *netdev, + unsigned short vid) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + if (!bnad->rx_info[0].rx) + return; + + mutex_lock(&bnad->conf_mutex); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_vlan_add(bnad->rx_info[0].rx, vid); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); +} + +static void +bnad_vlan_rx_kill_vid(struct net_device *netdev, + unsigned short vid) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + if (!bnad->rx_info[0].rx) + return; + + mutex_lock(&bnad->conf_mutex); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_rx_vlan_del(bnad->rx_info[0].rx, vid); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void +bnad_netpoll(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + struct bnad_rx_info *rx_info; + struct bnad_rx_ctrl *rx_ctrl; + u32 curr_mask; + int i, j; + + if (!(bnad->cfg_flags & BNAD_CF_MSIX)) { + bna_intx_disable(&bnad->bna, curr_mask); + bnad_isr(bnad->pcidev->irq, netdev); + bna_intx_enable(&bnad->bna, curr_mask); + } else { + for (i = 0; i < bnad->num_rx; i++) { + rx_info = &bnad->rx_info[i]; + if (!rx_info->rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + rx_ctrl = &rx_info->rx_ctrl[j]; + if (rx_ctrl->ccb) { + bnad_disable_rx_irq(bnad, + rx_ctrl->ccb); + bnad_netif_rx_schedule_poll(bnad, + rx_ctrl->ccb); + } + } + } + } +} +#endif + +static const struct net_device_ops bnad_netdev_ops = { + .ndo_open = bnad_open, + .ndo_stop = bnad_stop, + .ndo_start_xmit = bnad_start_xmit, + .ndo_get_stats64 = bnad_get_stats64, + .ndo_set_rx_mode = bnad_set_rx_mode, + .ndo_set_multicast_list = bnad_set_rx_mode, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_mac_address = bnad_set_mac_address, + .ndo_change_mtu = bnad_change_mtu, + .ndo_vlan_rx_register = bnad_vlan_rx_register, + .ndo_vlan_rx_add_vid = bnad_vlan_rx_add_vid, + .ndo_vlan_rx_kill_vid = bnad_vlan_rx_kill_vid, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = bnad_netpoll +#endif +}; + +static void +bnad_netdev_init(struct bnad *bnad, bool using_dac) +{ + struct net_device *netdev = bnad->netdev; + + netdev->features |= NETIF_F_IPV6_CSUM; + netdev->features |= NETIF_F_TSO; + netdev->features |= NETIF_F_TSO6; + + netdev->features |= NETIF_F_GRO; + pr_warn("bna: GRO enabled, using kernel stack GRO\n"); + + netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; + + if (using_dac) + netdev->features |= NETIF_F_HIGHDMA; + + netdev->features |= + NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; + + netdev->vlan_features = netdev->features; + netdev->mem_start = bnad->mmio_start; + netdev->mem_end = bnad->mmio_start + bnad->mmio_len - 1; + + netdev->netdev_ops = &bnad_netdev_ops; + bnad_set_ethtool_ops(netdev); +} + +/* + * 1. Initialize the bnad structure + * 2. Setup netdev pointer in pci_dev + * 3. Initialze Tx free tasklet + * 4. Initialize no. of TxQ & CQs & MSIX vectors + */ +static int +bnad_init(struct bnad *bnad, + struct pci_dev *pdev, struct net_device *netdev) +{ + unsigned long flags; + + SET_NETDEV_DEV(netdev, &pdev->dev); + pci_set_drvdata(pdev, netdev); + + bnad->netdev = netdev; + bnad->pcidev = pdev; + bnad->mmio_start = pci_resource_start(pdev, 0); + bnad->mmio_len = pci_resource_len(pdev, 0); + bnad->bar0 = ioremap_nocache(bnad->mmio_start, bnad->mmio_len); + if (!bnad->bar0) { + dev_err(&pdev->dev, "ioremap for bar0 failed\n"); + pci_set_drvdata(pdev, NULL); + return -ENOMEM; + } + pr_info("bar0 mapped to %p, len %llu\n", bnad->bar0, + (unsigned long long) bnad->mmio_len); + + spin_lock_irqsave(&bnad->bna_lock, flags); + if (!bnad_msix_disable) + bnad->cfg_flags = BNAD_CF_MSIX; + + bnad->cfg_flags |= BNAD_CF_DIM_ENABLED; + + bnad_q_num_init(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + bnad->msix_num = (bnad->num_tx * bnad->num_txq_per_tx) + + (bnad->num_rx * bnad->num_rxp_per_rx) + + BNAD_MAILBOX_MSIX_VECTORS; + + bnad->txq_depth = BNAD_TXQ_DEPTH; + bnad->rxq_depth = BNAD_RXQ_DEPTH; + bnad->rx_csum = true; + + bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO; + bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO; + + tasklet_init(&bnad->tx_free_tasklet, bnad_tx_free_tasklet, + (unsigned long)bnad); + + return 0; +} + +/* + * Must be called after bnad_pci_uninit() + * so that iounmap() and pci_set_drvdata(NULL) + * happens only after PCI uninitialization. + */ +static void +bnad_uninit(struct bnad *bnad) +{ + if (bnad->bar0) + iounmap(bnad->bar0); + pci_set_drvdata(bnad->pcidev, NULL); +} + +/* + * Initialize locks + a) Per device mutes used for serializing configuration + changes from OS interface + b) spin lock used to protect bna state machine + */ +static void +bnad_lock_init(struct bnad *bnad) +{ + spin_lock_init(&bnad->bna_lock); + mutex_init(&bnad->conf_mutex); +} + +static void +bnad_lock_uninit(struct bnad *bnad) +{ + mutex_destroy(&bnad->conf_mutex); +} + +/* PCI Initialization */ +static int +bnad_pci_init(struct bnad *bnad, + struct pci_dev *pdev, bool *using_dac) +{ + int err; + + err = pci_enable_device(pdev); + if (err) + return err; + err = pci_request_regions(pdev, BNAD_NAME); + if (err) + goto disable_device; + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && + !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { + *using_dac = 1; + } else { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (err) { + err = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + if (err) + goto release_regions; + } + *using_dac = 0; + } + pci_set_master(pdev); + return 0; + +release_regions: + pci_release_regions(pdev); +disable_device: + pci_disable_device(pdev); + + return err; +} + +static void +bnad_pci_uninit(struct pci_dev *pdev) +{ + pci_release_regions(pdev); + pci_disable_device(pdev); +} + +static int __devinit +bnad_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *pcidev_id) +{ + bool using_dac; + int err; + struct bnad *bnad; + struct bna *bna; + struct net_device *netdev; + struct bfa_pcidev pcidev_info; + unsigned long flags; + + pr_info("bnad_pci_probe : (0x%p, 0x%p) PCI Func : (%d)\n", + pdev, pcidev_id, PCI_FUNC(pdev->devfn)); + + mutex_lock(&bnad_fwimg_mutex); + if (!cna_get_firmware_buf(pdev)) { + mutex_unlock(&bnad_fwimg_mutex); + pr_warn("Failed to load Firmware Image!\n"); + return -ENODEV; + } + mutex_unlock(&bnad_fwimg_mutex); + + /* + * Allocates sizeof(struct net_device + struct bnad) + * bnad = netdev->priv + */ + netdev = alloc_etherdev(sizeof(struct bnad)); + if (!netdev) { + dev_err(&pdev->dev, "alloc_etherdev failed\n"); + err = -ENOMEM; + return err; + } + bnad = netdev_priv(netdev); + + /* + * PCI initialization + * Output : using_dac = 1 for 64 bit DMA + * = 0 for 32 bit DMA + */ + err = bnad_pci_init(bnad, pdev, &using_dac); + if (err) + goto free_netdev; + + bnad_lock_init(bnad); + /* + * Initialize bnad structure + * Setup relation between pci_dev & netdev + * Init Tx free tasklet + */ + err = bnad_init(bnad, pdev, netdev); + if (err) + goto pci_uninit; + /* Initialize netdev structure, set up ethtool ops */ + bnad_netdev_init(bnad, using_dac); + + bnad_enable_msix(bnad); + + /* Get resource requirement form bna */ + bna_res_req(&bnad->res_info[0]); + + /* Allocate resources from bna */ + err = bnad_res_alloc(bnad); + if (err) + goto free_netdev; + + bna = &bnad->bna; + + /* Setup pcidev_info for bna_init() */ + pcidev_info.pci_slot = PCI_SLOT(bnad->pcidev->devfn); + pcidev_info.pci_func = PCI_FUNC(bnad->pcidev->devfn); + pcidev_info.device_id = bnad->pcidev->device; + pcidev_info.pci_bar_kva = bnad->bar0; + + mutex_lock(&bnad->conf_mutex); + + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_init(bna, bnad, &pcidev_info, &bnad->res_info[0]); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + bnad->stats.bna_stats = &bna->stats; + + /* Set up timers */ + setup_timer(&bnad->bna.device.ioc.ioc_timer, bnad_ioc_timeout, + ((unsigned long)bnad)); + setup_timer(&bnad->bna.device.ioc.hb_timer, bnad_ioc_hb_check, + ((unsigned long)bnad)); + setup_timer(&bnad->bna.device.ioc.sem_timer, bnad_ioc_sem_timeout, + ((unsigned long)bnad)); + + /* Now start the timer before calling IOC */ + mod_timer(&bnad->bna.device.ioc.ioc_timer, + jiffies + msecs_to_jiffies(BNA_IOC_TIMER_FREQ)); + + /* + * Start the chip + * Don't care even if err != 0, bna state machine will + * deal with it + */ + err = bnad_device_enable(bnad); + + /* Get the burnt-in mac */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_mac_get(&bna->port, &bnad->perm_addr); + bnad_set_netdev_perm_addr(bnad); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); + + /* + * Make sure the link appears down to the stack + */ + netif_carrier_off(netdev); + + /* Finally, reguister with net_device layer */ + err = register_netdev(netdev); + if (err) { + pr_err("BNA : Registering with netdev failed\n"); + goto disable_device; + } + + return 0; + +disable_device: + mutex_lock(&bnad->conf_mutex); + bnad_device_disable(bnad); + del_timer_sync(&bnad->bna.device.ioc.ioc_timer); + del_timer_sync(&bnad->bna.device.ioc.sem_timer); + del_timer_sync(&bnad->bna.device.ioc.hb_timer); + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_uninit(bna); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + mutex_unlock(&bnad->conf_mutex); + + bnad_res_free(bnad); + bnad_disable_msix(bnad); +pci_uninit: + bnad_pci_uninit(pdev); + bnad_lock_uninit(bnad); + bnad_uninit(bnad); +free_netdev: + free_netdev(netdev); + return err; +} + +static void __devexit +bnad_pci_remove(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct bnad *bnad; + struct bna *bna; + unsigned long flags; + + if (!netdev) + return; + + pr_info("%s bnad_pci_remove\n", netdev->name); + bnad = netdev_priv(netdev); + bna = &bnad->bna; + + unregister_netdev(netdev); + + mutex_lock(&bnad->conf_mutex); + bnad_device_disable(bnad); + del_timer_sync(&bnad->bna.device.ioc.ioc_timer); + del_timer_sync(&bnad->bna.device.ioc.sem_timer); + del_timer_sync(&bnad->bna.device.ioc.hb_timer); + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_uninit(bna); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + mutex_unlock(&bnad->conf_mutex); + + bnad_res_free(bnad); + bnad_disable_msix(bnad); + bnad_pci_uninit(pdev); + bnad_lock_uninit(bnad); + bnad_uninit(bnad); + free_netdev(netdev); +} + +static const struct pci_device_id bnad_pci_id_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_BROCADE, + PCI_DEVICE_ID_BROCADE_CT), + .class = PCI_CLASS_NETWORK_ETHERNET << 8, + .class_mask = 0xffff00 + }, {0, } +}; + +MODULE_DEVICE_TABLE(pci, bnad_pci_id_table); + +static struct pci_driver bnad_pci_driver = { + .name = BNAD_NAME, + .id_table = bnad_pci_id_table, + .probe = bnad_pci_probe, + .remove = __devexit_p(bnad_pci_remove), +}; + +static int __init +bnad_module_init(void) +{ + int err; + + pr_info("Brocade 10G Ethernet driver\n"); + + bfa_nw_ioc_auto_recover(bnad_ioc_auto_recover); + + err = pci_register_driver(&bnad_pci_driver); + if (err < 0) { + pr_err("bna : PCI registration failed in module init " + "(%d)\n", err); + return err; + } + + return 0; +} + +static void __exit +bnad_module_exit(void) +{ + pci_unregister_driver(&bnad_pci_driver); + + if (bfi_fw) + release_firmware(bfi_fw); +} + +module_init(bnad_module_init); +module_exit(bnad_module_exit); + +MODULE_AUTHOR("Brocade"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Brocade 10G PCIe Ethernet driver"); +MODULE_VERSION(BNAD_VERSION); +MODULE_FIRMWARE(CNA_FW_FILE_CT); diff --git a/drivers/net/bna/bnad.h b/drivers/net/bna/bnad.h new file mode 100644 index 0000000000000000000000000000000000000000..ebc3a9078642d6b3fd5447c17f824fcdc29715f3 --- /dev/null +++ b/drivers/net/bna/bnad.h @@ -0,0 +1,332 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#ifndef __BNAD_H__ +#define __BNAD_H__ + +#include +#include +#include +#include +#include +#include + +/* Fix for IA64 */ +#include +#include + +#include +#include + +#include "bna.h" + +#define BNAD_TXQ_DEPTH 2048 +#define BNAD_RXQ_DEPTH 2048 + +#define BNAD_MAX_TXS 1 +#define BNAD_MAX_TXQ_PER_TX 8 /* 8 priority queues */ +#define BNAD_TXQ_NUM 1 + +#define BNAD_MAX_RXS 1 +#define BNAD_MAX_RXPS_PER_RX 16 + +/* + * Control structure pointed to ccb->ctrl, which + * determines the NAPI / LRO behavior CCB + * There is 1:1 corres. between ccb & ctrl + */ +struct bnad_rx_ctrl { + struct bna_ccb *ccb; + struct napi_struct napi; +}; + +#define BNAD_RXMODE_PROMISC_DEFAULT BNA_RXMODE_PROMISC + +#define BNAD_GET_TX_ID(_skb) (0) + +/* + * GLOBAL #defines (CONSTANTS) + */ +#define BNAD_NAME "bna" +#define BNAD_NAME_LEN 64 + +#define BNAD_VERSION "2.3.2.0" + +#define BNAD_MAILBOX_MSIX_VECTORS 1 + +#define BNAD_STATS_TIMER_FREQ 1000 /* in msecs */ +#define BNAD_DIM_TIMER_FREQ 1000 /* in msecs */ + +#define BNAD_MAX_Q_DEPTH 0x10000 +#define BNAD_MIN_Q_DEPTH 0x200 + +#define BNAD_JUMBO_MTU 9000 + +#define BNAD_NETIF_WAKE_THRESHOLD 8 + +#define BNAD_RXQ_REFILL_THRESHOLD_SHIFT 3 + +/* Bit positions for tcb->flags */ +#define BNAD_TXQ_FREE_SENT 0 + +/* Bit positions for rcb->flags */ +#define BNAD_RXQ_REFILL 0 +#define BNAD_RXQ_STARTED 1 + +/* + * DATA STRUCTURES + */ + +/* enums */ +enum bnad_intr_source { + BNAD_INTR_TX = 1, + BNAD_INTR_RX = 2 +}; + +enum bnad_link_state { + BNAD_LS_DOWN = 0, + BNAD_LS_UP = 1 +}; + +struct bnad_completion { + struct completion ioc_comp; + struct completion ucast_comp; + struct completion mcast_comp; + struct completion tx_comp; + struct completion rx_comp; + struct completion stats_comp; + struct completion port_comp; + + u8 ioc_comp_status; + u8 ucast_comp_status; + u8 mcast_comp_status; + u8 tx_comp_status; + u8 rx_comp_status; + u8 stats_comp_status; + u8 port_comp_status; +}; + +/* Tx Rx Control Stats */ +struct bnad_drv_stats { + u64 netif_queue_stop; + u64 netif_queue_wakeup; + u64 tso4; + u64 tso6; + u64 tso_err; + u64 tcpcsum_offload; + u64 udpcsum_offload; + u64 csum_help; + u64 csum_help_err; + + u64 hw_stats_updates; + u64 netif_rx_schedule; + u64 netif_rx_complete; + u64 netif_rx_dropped; + + u64 link_toggle; + u64 cee_up; + + u64 rxp_info_alloc_failed; + u64 mbox_intr_disabled; + u64 mbox_intr_enabled; + u64 tx_unmap_q_alloc_failed; + u64 rx_unmap_q_alloc_failed; + + u64 rxbuf_alloc_failed; +}; + +/* Complete driver stats */ +struct bnad_stats { + struct bnad_drv_stats drv_stats; + struct bna_stats *bna_stats; +}; + +/* Tx / Rx Resources */ +struct bnad_tx_res_info { + struct bna_res_info res_info[BNA_TX_RES_T_MAX]; +}; + +struct bnad_rx_res_info { + struct bna_res_info res_info[BNA_RX_RES_T_MAX]; +}; + +struct bnad_tx_info { + struct bna_tx *tx; /* 1:1 between tx_info & tx */ + struct bna_tcb *tcb[BNAD_MAX_TXQ_PER_TX]; +} ____cacheline_aligned; + +struct bnad_rx_info { + struct bna_rx *rx; /* 1:1 between rx_info & rx */ + + struct bnad_rx_ctrl rx_ctrl[BNAD_MAX_RXPS_PER_RX]; +} ____cacheline_aligned; + +/* Unmap queues for Tx / Rx cleanup */ +struct bnad_skb_unmap { + struct sk_buff *skb; + DECLARE_PCI_UNMAP_ADDR(dma_addr) +}; + +struct bnad_unmap_q { + u32 producer_index; + u32 consumer_index; + u32 q_depth; + /* This should be the last one */ + struct bnad_skb_unmap unmap_array[1]; +}; + +/* Bit mask values for bnad->cfg_flags */ +#define BNAD_CF_DIM_ENABLED 0x01 /* DIM */ +#define BNAD_CF_PROMISC 0x02 +#define BNAD_CF_ALLMULTI 0x04 +#define BNAD_CF_MSIX 0x08 /* If in MSIx mode */ + +/* Defines for run_flags bit-mask */ +/* Set, tested & cleared using xxx_bit() functions */ +/* Values indicated bit positions */ +#define BNAD_RF_CEE_RUNNING 1 +#define BNAD_RF_HW_ERROR 2 +#define BNAD_RF_MBOX_IRQ_DISABLED 3 +#define BNAD_RF_TX_STARTED 4 +#define BNAD_RF_RX_STARTED 5 +#define BNAD_RF_DIM_TIMER_RUNNING 6 +#define BNAD_RF_STATS_TIMER_RUNNING 7 + +struct bnad { + struct net_device *netdev; + + /* Data path */ + struct bnad_tx_info tx_info[BNAD_MAX_TXS]; + struct bnad_rx_info rx_info[BNAD_MAX_RXS]; + + struct vlan_group *vlan_grp; + /* + * These q numbers are global only because + * they are used to calculate MSIx vectors. + * Actually the exact # of queues are per Tx/Rx + * object. + */ + u32 num_tx; + u32 num_rx; + u32 num_txq_per_tx; + u32 num_rxp_per_rx; + + u32 txq_depth; + u32 rxq_depth; + + u8 tx_coalescing_timeo; + u8 rx_coalescing_timeo; + + struct bna_rx_config rx_config[BNAD_MAX_RXS]; + struct bna_tx_config tx_config[BNAD_MAX_TXS]; + + u32 rx_csum; + + void __iomem *bar0; /* BAR0 address */ + + struct bna bna; + + u32 cfg_flags; + unsigned long run_flags; + + struct pci_dev *pcidev; + u64 mmio_start; + u64 mmio_len; + + u32 msix_num; + struct msix_entry *msix_table; + + struct mutex conf_mutex; + spinlock_t bna_lock ____cacheline_aligned; + + /* Timers */ + struct timer_list ioc_timer; + struct timer_list dim_timer; + struct timer_list stats_timer; + + /* Control path resources, memory & irq */ + struct bna_res_info res_info[BNA_RES_T_MAX]; + struct bnad_tx_res_info tx_res_info[BNAD_MAX_TXS]; + struct bnad_rx_res_info rx_res_info[BNAD_MAX_RXS]; + + struct bnad_completion bnad_completions; + + /* Burnt in MAC address */ + mac_t perm_addr; + + struct tasklet_struct tx_free_tasklet; + + /* Statistics */ + struct bnad_stats stats; + + struct bnad_diag *diag; + + char adapter_name[BNAD_NAME_LEN]; + char port_name[BNAD_NAME_LEN]; + char mbox_irq_name[BNAD_NAME_LEN]; +}; + +/* + * EXTERN VARIABLES + */ +extern struct firmware *bfi_fw; +extern u32 bnad_rxqs_per_cq; + +/* + * EXTERN PROTOTYPES + */ +extern u32 *cna_get_firmware_buf(struct pci_dev *pdev); +/* Netdev entry point prototypes */ +extern void bnad_set_ethtool_ops(struct net_device *netdev); + +/* Configuration & setup */ +extern void bnad_tx_coalescing_timeo_set(struct bnad *bnad); +extern void bnad_rx_coalescing_timeo_set(struct bnad *bnad); + +extern int bnad_setup_rx(struct bnad *bnad, uint rx_id); +extern int bnad_setup_tx(struct bnad *bnad, uint tx_id); +extern void bnad_cleanup_tx(struct bnad *bnad, uint tx_id); +extern void bnad_cleanup_rx(struct bnad *bnad, uint rx_id); + +/* Timer start/stop protos */ +extern void bnad_dim_timer_start(struct bnad *bnad); + +/* Statistics */ +extern void bnad_netdev_qstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats); +extern void bnad_netdev_hwstats_fill(struct bnad *bnad, struct rtnl_link_stats64 *stats); + +/** + * MACROS + */ +/* To set & get the stats counters */ +#define BNAD_UPDATE_CTR(_bnad, _ctr) \ + (((_bnad)->stats.drv_stats._ctr)++) + +#define BNAD_GET_CTR(_bnad, _ctr) ((_bnad)->stats.drv_stats._ctr) + +#define bnad_enable_rx_irq_unsafe(_ccb) \ +{ \ + bna_ib_coalescing_timer_set((_ccb)->i_dbell, \ + (_ccb)->rx_coalescing_timeo); \ + bna_ib_ack((_ccb)->i_dbell, 0); \ +} + +#define bnad_dim_timer_running(_bnad) \ + (((_bnad)->cfg_flags & BNAD_CF_DIM_ENABLED) && \ + (test_bit(BNAD_RF_DIM_TIMER_RUNNING, &((_bnad)->run_flags)))) + +#endif /* __BNAD_H__ */ diff --git a/drivers/net/bna/bnad_ethtool.c b/drivers/net/bna/bnad_ethtool.c new file mode 100644 index 0000000000000000000000000000000000000000..11fa2ea842c1258c855e666ab1e5244b330c60c8 --- /dev/null +++ b/drivers/net/bna/bnad_ethtool.c @@ -0,0 +1,1277 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#include "cna.h" + +#include +#include +#include +#include + +#include "bna.h" + +#include "bnad.h" + +#define BNAD_NUM_TXF_COUNTERS 12 +#define BNAD_NUM_RXF_COUNTERS 10 +#define BNAD_NUM_CQ_COUNTERS 3 +#define BNAD_NUM_RXQ_COUNTERS 6 +#define BNAD_NUM_TXQ_COUNTERS 5 + +#define BNAD_ETHTOOL_STATS_NUM \ + (sizeof(struct rtnl_link_stats64) / sizeof(u64) + \ + sizeof(struct bnad_drv_stats) / sizeof(u64) + \ + offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64)) + +static char *bnad_net_stats_strings[BNAD_ETHTOOL_STATS_NUM] = { + "rx_packets", + "tx_packets", + "rx_bytes", + "tx_bytes", + "rx_errors", + "tx_errors", + "rx_dropped", + "tx_dropped", + "multicast", + "collisions", + + "rx_length_errors", + "rx_over_errors", + "rx_crc_errors", + "rx_frame_errors", + "rx_fifo_errors", + "rx_missed_errors", + + "tx_aborted_errors", + "tx_carrier_errors", + "tx_fifo_errors", + "tx_heartbeat_errors", + "tx_window_errors", + + "rx_compressed", + "tx_compressed", + + "netif_queue_stop", + "netif_queue_wakeup", + "tso4", + "tso6", + "tso_err", + "tcpcsum_offload", + "udpcsum_offload", + "csum_help", + "csum_help_err", + "hw_stats_updates", + "netif_rx_schedule", + "netif_rx_complete", + "netif_rx_dropped", + + "link_toggle", + "cee_up", + + "rxp_info_alloc_failed", + "mbox_intr_disabled", + "mbox_intr_enabled", + "tx_unmap_q_alloc_failed", + "rx_unmap_q_alloc_failed", + "rxbuf_alloc_failed", + + "mac_frame_64", + "mac_frame_65_127", + "mac_frame_128_255", + "mac_frame_256_511", + "mac_frame_512_1023", + "mac_frame_1024_1518", + "mac_frame_1518_1522", + "mac_rx_bytes", + "mac_rx_packets", + "mac_rx_fcs_error", + "mac_rx_multicast", + "mac_rx_broadcast", + "mac_rx_control_frames", + "mac_rx_pause", + "mac_rx_unknown_opcode", + "mac_rx_alignment_error", + "mac_rx_frame_length_error", + "mac_rx_code_error", + "mac_rx_carrier_sense_error", + "mac_rx_undersize", + "mac_rx_oversize", + "mac_rx_fragments", + "mac_rx_jabber", + "mac_rx_drop", + + "mac_tx_bytes", + "mac_tx_packets", + "mac_tx_multicast", + "mac_tx_broadcast", + "mac_tx_pause", + "mac_tx_deferral", + "mac_tx_excessive_deferral", + "mac_tx_single_collision", + "mac_tx_muliple_collision", + "mac_tx_late_collision", + "mac_tx_excessive_collision", + "mac_tx_total_collision", + "mac_tx_pause_honored", + "mac_tx_drop", + "mac_tx_jabber", + "mac_tx_fcs_error", + "mac_tx_control_frame", + "mac_tx_oversize", + "mac_tx_undersize", + "mac_tx_fragments", + + "bpc_tx_pause_0", + "bpc_tx_pause_1", + "bpc_tx_pause_2", + "bpc_tx_pause_3", + "bpc_tx_pause_4", + "bpc_tx_pause_5", + "bpc_tx_pause_6", + "bpc_tx_pause_7", + "bpc_tx_zero_pause_0", + "bpc_tx_zero_pause_1", + "bpc_tx_zero_pause_2", + "bpc_tx_zero_pause_3", + "bpc_tx_zero_pause_4", + "bpc_tx_zero_pause_5", + "bpc_tx_zero_pause_6", + "bpc_tx_zero_pause_7", + "bpc_tx_first_pause_0", + "bpc_tx_first_pause_1", + "bpc_tx_first_pause_2", + "bpc_tx_first_pause_3", + "bpc_tx_first_pause_4", + "bpc_tx_first_pause_5", + "bpc_tx_first_pause_6", + "bpc_tx_first_pause_7", + + "bpc_rx_pause_0", + "bpc_rx_pause_1", + "bpc_rx_pause_2", + "bpc_rx_pause_3", + "bpc_rx_pause_4", + "bpc_rx_pause_5", + "bpc_rx_pause_6", + "bpc_rx_pause_7", + "bpc_rx_zero_pause_0", + "bpc_rx_zero_pause_1", + "bpc_rx_zero_pause_2", + "bpc_rx_zero_pause_3", + "bpc_rx_zero_pause_4", + "bpc_rx_zero_pause_5", + "bpc_rx_zero_pause_6", + "bpc_rx_zero_pause_7", + "bpc_rx_first_pause_0", + "bpc_rx_first_pause_1", + "bpc_rx_first_pause_2", + "bpc_rx_first_pause_3", + "bpc_rx_first_pause_4", + "bpc_rx_first_pause_5", + "bpc_rx_first_pause_6", + "bpc_rx_first_pause_7", + + "rad_rx_frames", + "rad_rx_octets", + "rad_rx_vlan_frames", + "rad_rx_ucast", + "rad_rx_ucast_octets", + "rad_rx_ucast_vlan", + "rad_rx_mcast", + "rad_rx_mcast_octets", + "rad_rx_mcast_vlan", + "rad_rx_bcast", + "rad_rx_bcast_octets", + "rad_rx_bcast_vlan", + "rad_rx_drops", + + "fc_rx_ucast_octets", + "fc_rx_ucast", + "fc_rx_ucast_vlan", + "fc_rx_mcast_octets", + "fc_rx_mcast", + "fc_rx_mcast_vlan", + "fc_rx_bcast_octets", + "fc_rx_bcast", + "fc_rx_bcast_vlan", + + "fc_tx_ucast_octets", + "fc_tx_ucast", + "fc_tx_ucast_vlan", + "fc_tx_mcast_octets", + "fc_tx_mcast", + "fc_tx_mcast_vlan", + "fc_tx_bcast_octets", + "fc_tx_bcast", + "fc_tx_bcast_vlan", + "fc_tx_parity_errors", + "fc_tx_timeout", + "fc_tx_fid_parity_errors", +}; + +static int +bnad_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +{ + cmd->supported = SUPPORTED_10000baseT_Full; + cmd->advertising = ADVERTISED_10000baseT_Full; + cmd->autoneg = AUTONEG_DISABLE; + cmd->supported |= SUPPORTED_FIBRE; + cmd->advertising |= ADVERTISED_FIBRE; + cmd->port = PORT_FIBRE; + cmd->phy_address = 0; + + if (netif_carrier_ok(netdev)) { + cmd->speed = SPEED_10000; + cmd->duplex = DUPLEX_FULL; + } else { + cmd->speed = -1; + cmd->duplex = -1; + } + cmd->transceiver = XCVR_EXTERNAL; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + + return 0; +} + +static int +bnad_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd) +{ + /* 10G full duplex setting supported only */ + if (cmd->autoneg == AUTONEG_ENABLE) + return -EOPNOTSUPP; else { + if ((cmd->speed == SPEED_10000) && (cmd->duplex == DUPLEX_FULL)) + return 0; + } + + return -EOPNOTSUPP; +} + +static void +bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) +{ + struct bnad *bnad = netdev_priv(netdev); + struct bfa_ioc_attr *ioc_attr; + unsigned long flags; + + strcpy(drvinfo->driver, BNAD_NAME); + strcpy(drvinfo->version, BNAD_VERSION); + + ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL); + if (ioc_attr) { + memset(ioc_attr, 0, sizeof(*ioc_attr)); + spin_lock_irqsave(&bnad->bna_lock, flags); + bfa_nw_ioc_get_attr(&bnad->bna.device.ioc, ioc_attr); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + strncpy(drvinfo->fw_version, ioc_attr->adapter_attr.fw_ver, + sizeof(drvinfo->fw_version) - 1); + kfree(ioc_attr); + } + + strncpy(drvinfo->bus_info, pci_name(bnad->pcidev), ETHTOOL_BUSINFO_LEN); +} + +static int +get_regs(struct bnad *bnad, u32 * regs) +{ + int num = 0, i; + u32 reg_addr; + unsigned long flags; + +#define BNAD_GET_REG(addr) \ +do { \ + if (regs) \ + regs[num++] = readl(bnad->bar0 + (addr)); \ + else \ + num++; \ +} while (0) + + spin_lock_irqsave(&bnad->bna_lock, flags); + + /* DMA Block Internal Registers */ + BNAD_GET_REG(DMA_CTRL_REG0); + BNAD_GET_REG(DMA_CTRL_REG1); + BNAD_GET_REG(DMA_ERR_INT_STATUS); + BNAD_GET_REG(DMA_ERR_INT_ENABLE); + BNAD_GET_REG(DMA_ERR_INT_STATUS_SET); + + /* APP Block Register Address Offset from BAR0 */ + BNAD_GET_REG(HOSTFN0_INT_STATUS); + BNAD_GET_REG(HOSTFN0_INT_MASK); + BNAD_GET_REG(HOST_PAGE_NUM_FN0); + BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN0); + BNAD_GET_REG(FN0_PCIE_ERR_REG); + BNAD_GET_REG(FN0_ERR_TYPE_STATUS_REG); + BNAD_GET_REG(FN0_ERR_TYPE_MSK_STATUS_REG); + + BNAD_GET_REG(HOSTFN1_INT_STATUS); + BNAD_GET_REG(HOSTFN1_INT_MASK); + BNAD_GET_REG(HOST_PAGE_NUM_FN1); + BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN1); + BNAD_GET_REG(FN1_PCIE_ERR_REG); + BNAD_GET_REG(FN1_ERR_TYPE_STATUS_REG); + BNAD_GET_REG(FN1_ERR_TYPE_MSK_STATUS_REG); + + BNAD_GET_REG(PCIE_MISC_REG); + + BNAD_GET_REG(HOST_SEM0_REG); + BNAD_GET_REG(HOST_SEM1_REG); + BNAD_GET_REG(HOST_SEM2_REG); + BNAD_GET_REG(HOST_SEM3_REG); + BNAD_GET_REG(HOST_SEM0_INFO_REG); + BNAD_GET_REG(HOST_SEM1_INFO_REG); + BNAD_GET_REG(HOST_SEM2_INFO_REG); + BNAD_GET_REG(HOST_SEM3_INFO_REG); + + BNAD_GET_REG(TEMPSENSE_CNTL_REG); + BNAD_GET_REG(TEMPSENSE_STAT_REG); + + BNAD_GET_REG(APP_LOCAL_ERR_STAT); + BNAD_GET_REG(APP_LOCAL_ERR_MSK); + + BNAD_GET_REG(PCIE_LNK_ERR_STAT); + BNAD_GET_REG(PCIE_LNK_ERR_MSK); + + BNAD_GET_REG(FCOE_FIP_ETH_TYPE); + BNAD_GET_REG(RESV_ETH_TYPE); + + BNAD_GET_REG(HOSTFN2_INT_STATUS); + BNAD_GET_REG(HOSTFN2_INT_MASK); + BNAD_GET_REG(HOST_PAGE_NUM_FN2); + BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN2); + BNAD_GET_REG(FN2_PCIE_ERR_REG); + BNAD_GET_REG(FN2_ERR_TYPE_STATUS_REG); + BNAD_GET_REG(FN2_ERR_TYPE_MSK_STATUS_REG); + + BNAD_GET_REG(HOSTFN3_INT_STATUS); + BNAD_GET_REG(HOSTFN3_INT_MASK); + BNAD_GET_REG(HOST_PAGE_NUM_FN3); + BNAD_GET_REG(HOST_MSIX_ERR_INDEX_FN3); + BNAD_GET_REG(FN3_PCIE_ERR_REG); + BNAD_GET_REG(FN3_ERR_TYPE_STATUS_REG); + BNAD_GET_REG(FN3_ERR_TYPE_MSK_STATUS_REG); + + /* Host Command Status Registers */ + reg_addr = HOST_CMDSTS0_CLR_REG; + for (i = 0; i < 16; i++) { + BNAD_GET_REG(reg_addr); + BNAD_GET_REG(reg_addr + 4); + BNAD_GET_REG(reg_addr + 8); + reg_addr += 0x10; + } + + /* Function ID register */ + BNAD_GET_REG(FNC_ID_REG); + + /* Function personality register */ + BNAD_GET_REG(FNC_PERS_REG); + + /* Operation mode register */ + BNAD_GET_REG(OP_MODE); + + /* LPU0 Registers */ + BNAD_GET_REG(LPU0_MBOX_CTL_REG); + BNAD_GET_REG(LPU0_MBOX_CMD_REG); + BNAD_GET_REG(LPU0_MBOX_LINK_0REG); + BNAD_GET_REG(LPU1_MBOX_LINK_0REG); + BNAD_GET_REG(LPU0_MBOX_STATUS_0REG); + BNAD_GET_REG(LPU1_MBOX_STATUS_0REG); + BNAD_GET_REG(LPU0_ERR_STATUS_REG); + BNAD_GET_REG(LPU0_ERR_SET_REG); + + /* LPU1 Registers */ + BNAD_GET_REG(LPU1_MBOX_CTL_REG); + BNAD_GET_REG(LPU1_MBOX_CMD_REG); + BNAD_GET_REG(LPU0_MBOX_LINK_1REG); + BNAD_GET_REG(LPU1_MBOX_LINK_1REG); + BNAD_GET_REG(LPU0_MBOX_STATUS_1REG); + BNAD_GET_REG(LPU1_MBOX_STATUS_1REG); + BNAD_GET_REG(LPU1_ERR_STATUS_REG); + BNAD_GET_REG(LPU1_ERR_SET_REG); + + /* PSS Registers */ + BNAD_GET_REG(PSS_CTL_REG); + BNAD_GET_REG(PSS_ERR_STATUS_REG); + BNAD_GET_REG(ERR_STATUS_SET); + BNAD_GET_REG(PSS_RAM_ERR_STATUS_REG); + + /* Catapult CPQ Registers */ + BNAD_GET_REG(HOSTFN0_LPU0_MBOX0_CMD_STAT); + BNAD_GET_REG(HOSTFN0_LPU1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN0_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN0_MBOX0_CMD_STAT); + + BNAD_GET_REG(HOSTFN0_LPU0_MBOX1_CMD_STAT); + BNAD_GET_REG(HOSTFN0_LPU1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN0_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN0_MBOX1_CMD_STAT); + + BNAD_GET_REG(HOSTFN1_LPU0_MBOX0_CMD_STAT); + BNAD_GET_REG(HOSTFN1_LPU1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN1_MBOX0_CMD_STAT); + + BNAD_GET_REG(HOSTFN1_LPU0_MBOX1_CMD_STAT); + BNAD_GET_REG(HOSTFN1_LPU1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN1_MBOX1_CMD_STAT); + + BNAD_GET_REG(HOSTFN2_LPU0_MBOX0_CMD_STAT); + BNAD_GET_REG(HOSTFN2_LPU1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN2_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN2_MBOX0_CMD_STAT); + + BNAD_GET_REG(HOSTFN2_LPU0_MBOX1_CMD_STAT); + BNAD_GET_REG(HOSTFN2_LPU1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN2_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN2_MBOX1_CMD_STAT); + + BNAD_GET_REG(HOSTFN3_LPU0_MBOX0_CMD_STAT); + BNAD_GET_REG(HOSTFN3_LPU1_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN3_MBOX0_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN3_MBOX0_CMD_STAT); + + BNAD_GET_REG(HOSTFN3_LPU0_MBOX1_CMD_STAT); + BNAD_GET_REG(HOSTFN3_LPU1_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU0_HOSTFN3_MBOX1_CMD_STAT); + BNAD_GET_REG(LPU1_HOSTFN3_MBOX1_CMD_STAT); + + /* Host Function Force Parity Error Registers */ + BNAD_GET_REG(HOSTFN0_LPU_FORCE_PERR); + BNAD_GET_REG(HOSTFN1_LPU_FORCE_PERR); + BNAD_GET_REG(HOSTFN2_LPU_FORCE_PERR); + BNAD_GET_REG(HOSTFN3_LPU_FORCE_PERR); + + /* LL Port[0|1] Halt Mask Registers */ + BNAD_GET_REG(LL_HALT_MSK_P0); + BNAD_GET_REG(LL_HALT_MSK_P1); + + /* LL Port[0|1] Error Mask Registers */ + BNAD_GET_REG(LL_ERR_MSK_P0); + BNAD_GET_REG(LL_ERR_MSK_P1); + + /* EMC FLI Registers */ + BNAD_GET_REG(FLI_CMD_REG); + BNAD_GET_REG(FLI_ADDR_REG); + BNAD_GET_REG(FLI_CTL_REG); + BNAD_GET_REG(FLI_WRDATA_REG); + BNAD_GET_REG(FLI_RDDATA_REG); + BNAD_GET_REG(FLI_DEV_STATUS_REG); + BNAD_GET_REG(FLI_SIG_WD_REG); + + BNAD_GET_REG(FLI_DEV_VENDOR_REG); + BNAD_GET_REG(FLI_ERR_STATUS_REG); + + /* RxAdm 0 Registers */ + BNAD_GET_REG(RAD0_CTL_REG); + BNAD_GET_REG(RAD0_PE_PARM_REG); + BNAD_GET_REG(RAD0_BCN_REG); + BNAD_GET_REG(RAD0_DEFAULT_REG); + BNAD_GET_REG(RAD0_PROMISC_REG); + BNAD_GET_REG(RAD0_BCNQ_REG); + BNAD_GET_REG(RAD0_DEFAULTQ_REG); + + BNAD_GET_REG(RAD0_ERR_STS); + BNAD_GET_REG(RAD0_SET_ERR_STS); + BNAD_GET_REG(RAD0_ERR_INT_EN); + BNAD_GET_REG(RAD0_FIRST_ERR); + BNAD_GET_REG(RAD0_FORCE_ERR); + + BNAD_GET_REG(RAD0_MAC_MAN_1H); + BNAD_GET_REG(RAD0_MAC_MAN_1L); + BNAD_GET_REG(RAD0_MAC_MAN_2H); + BNAD_GET_REG(RAD0_MAC_MAN_2L); + BNAD_GET_REG(RAD0_MAC_MAN_3H); + BNAD_GET_REG(RAD0_MAC_MAN_3L); + BNAD_GET_REG(RAD0_MAC_MAN_4H); + BNAD_GET_REG(RAD0_MAC_MAN_4L); + + BNAD_GET_REG(RAD0_LAST4_IP); + + /* RxAdm 1 Registers */ + BNAD_GET_REG(RAD1_CTL_REG); + BNAD_GET_REG(RAD1_PE_PARM_REG); + BNAD_GET_REG(RAD1_BCN_REG); + BNAD_GET_REG(RAD1_DEFAULT_REG); + BNAD_GET_REG(RAD1_PROMISC_REG); + BNAD_GET_REG(RAD1_BCNQ_REG); + BNAD_GET_REG(RAD1_DEFAULTQ_REG); + + BNAD_GET_REG(RAD1_ERR_STS); + BNAD_GET_REG(RAD1_SET_ERR_STS); + BNAD_GET_REG(RAD1_ERR_INT_EN); + + /* TxA0 Registers */ + BNAD_GET_REG(TXA0_CTRL_REG); + /* TxA0 TSO Sequence # Registers (RO) */ + for (i = 0; i < 8; i++) { + BNAD_GET_REG(TXA0_TSO_TCP_SEQ_REG(i)); + BNAD_GET_REG(TXA0_TSO_IP_INFO_REG(i)); + } + + /* TxA1 Registers */ + BNAD_GET_REG(TXA1_CTRL_REG); + /* TxA1 TSO Sequence # Registers (RO) */ + for (i = 0; i < 8; i++) { + BNAD_GET_REG(TXA1_TSO_TCP_SEQ_REG(i)); + BNAD_GET_REG(TXA1_TSO_IP_INFO_REG(i)); + } + + /* RxA Registers */ + BNAD_GET_REG(RXA0_CTL_REG); + BNAD_GET_REG(RXA1_CTL_REG); + + /* PLB0 Registers */ + BNAD_GET_REG(PLB0_ECM_TIMER_REG); + BNAD_GET_REG(PLB0_RL_CTL); + for (i = 0; i < 8; i++) + BNAD_GET_REG(PLB0_RL_MAX_BC(i)); + BNAD_GET_REG(PLB0_RL_TU_PRIO); + for (i = 0; i < 8; i++) + BNAD_GET_REG(PLB0_RL_BYTE_CNT(i)); + BNAD_GET_REG(PLB0_RL_MIN_REG); + BNAD_GET_REG(PLB0_RL_MAX_REG); + BNAD_GET_REG(PLB0_EMS_ADD_REG); + + /* PLB1 Registers */ + BNAD_GET_REG(PLB1_ECM_TIMER_REG); + BNAD_GET_REG(PLB1_RL_CTL); + for (i = 0; i < 8; i++) + BNAD_GET_REG(PLB1_RL_MAX_BC(i)); + BNAD_GET_REG(PLB1_RL_TU_PRIO); + for (i = 0; i < 8; i++) + BNAD_GET_REG(PLB1_RL_BYTE_CNT(i)); + BNAD_GET_REG(PLB1_RL_MIN_REG); + BNAD_GET_REG(PLB1_RL_MAX_REG); + BNAD_GET_REG(PLB1_EMS_ADD_REG); + + /* HQM Control Register */ + BNAD_GET_REG(HQM0_CTL_REG); + BNAD_GET_REG(HQM0_RXQ_STOP_SEM); + BNAD_GET_REG(HQM0_TXQ_STOP_SEM); + BNAD_GET_REG(HQM1_CTL_REG); + BNAD_GET_REG(HQM1_RXQ_STOP_SEM); + BNAD_GET_REG(HQM1_TXQ_STOP_SEM); + + /* LUT Registers */ + BNAD_GET_REG(LUT0_ERR_STS); + BNAD_GET_REG(LUT0_SET_ERR_STS); + BNAD_GET_REG(LUT1_ERR_STS); + BNAD_GET_REG(LUT1_SET_ERR_STS); + + /* TRC Registers */ + BNAD_GET_REG(TRC_CTL_REG); + BNAD_GET_REG(TRC_MODS_REG); + BNAD_GET_REG(TRC_TRGC_REG); + BNAD_GET_REG(TRC_CNT1_REG); + BNAD_GET_REG(TRC_CNT2_REG); + BNAD_GET_REG(TRC_NXTS_REG); + BNAD_GET_REG(TRC_DIRR_REG); + for (i = 0; i < 10; i++) + BNAD_GET_REG(TRC_TRGM_REG(i)); + for (i = 0; i < 10; i++) + BNAD_GET_REG(TRC_NXTM_REG(i)); + for (i = 0; i < 10; i++) + BNAD_GET_REG(TRC_STRM_REG(i)); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); +#undef BNAD_GET_REG + return num; +} +static int +bnad_get_regs_len(struct net_device *netdev) +{ + int ret = get_regs(netdev_priv(netdev), NULL) * sizeof(u32); + return ret; +} + +static void +bnad_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf) +{ + memset(buf, 0, bnad_get_regs_len(netdev)); + get_regs(netdev_priv(netdev), buf); +} + +static void +bnad_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wolinfo) +{ + wolinfo->supported = 0; + wolinfo->wolopts = 0; +} + +static int +bnad_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + + /* Lock rqd. to access bnad->bna_lock */ + spin_lock_irqsave(&bnad->bna_lock, flags); + coalesce->use_adaptive_rx_coalesce = + (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) ? true : false; + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + coalesce->rx_coalesce_usecs = bnad->rx_coalescing_timeo * + BFI_COALESCING_TIMER_UNIT; + coalesce->tx_coalesce_usecs = bnad->tx_coalescing_timeo * + BFI_COALESCING_TIMER_UNIT; + coalesce->tx_max_coalesced_frames = BFI_TX_INTERPKT_COUNT; + + return 0; +} + +static int +bnad_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) +{ + struct bnad *bnad = netdev_priv(netdev); + unsigned long flags; + int dim_timer_del = 0; + + if (coalesce->rx_coalesce_usecs == 0 || + coalesce->rx_coalesce_usecs > + BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT) + return -EINVAL; + + if (coalesce->tx_coalesce_usecs == 0 || + coalesce->tx_coalesce_usecs > + BFI_MAX_COALESCING_TIMEO * BFI_COALESCING_TIMER_UNIT) + return -EINVAL; + + mutex_lock(&bnad->conf_mutex); + /* + * Do not need to store rx_coalesce_usecs here + * Every time DIM is disabled, we can get it from the + * stack. + */ + spin_lock_irqsave(&bnad->bna_lock, flags); + if (coalesce->use_adaptive_rx_coalesce) { + if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED)) { + bnad->cfg_flags |= BNAD_CF_DIM_ENABLED; + bnad_dim_timer_start(bnad); + } + } else { + if (bnad->cfg_flags & BNAD_CF_DIM_ENABLED) { + bnad->cfg_flags &= ~BNAD_CF_DIM_ENABLED; + dim_timer_del = bnad_dim_timer_running(bnad); + if (dim_timer_del) { + clear_bit(BNAD_RF_DIM_TIMER_RUNNING, + &bnad->run_flags); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + del_timer_sync(&bnad->dim_timer); + spin_lock_irqsave(&bnad->bna_lock, flags); + } + bnad_rx_coalescing_timeo_set(bnad); + } + } + if (bnad->tx_coalescing_timeo != coalesce->tx_coalesce_usecs / + BFI_COALESCING_TIMER_UNIT) { + bnad->tx_coalescing_timeo = coalesce->tx_coalesce_usecs / + BFI_COALESCING_TIMER_UNIT; + bnad_tx_coalescing_timeo_set(bnad); + } + + if (bnad->rx_coalescing_timeo != coalesce->rx_coalesce_usecs / + BFI_COALESCING_TIMER_UNIT) { + bnad->rx_coalescing_timeo = coalesce->rx_coalesce_usecs / + BFI_COALESCING_TIMER_UNIT; + + if (!(bnad->cfg_flags & BNAD_CF_DIM_ENABLED)) + bnad_rx_coalescing_timeo_set(bnad); + + } + + /* Add Tx Inter-pkt DMA count? */ + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static void +bnad_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ringparam) +{ + struct bnad *bnad = netdev_priv(netdev); + + ringparam->rx_max_pending = BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq; + ringparam->rx_mini_max_pending = 0; + ringparam->rx_jumbo_max_pending = 0; + ringparam->tx_max_pending = BNAD_MAX_Q_DEPTH; + + ringparam->rx_pending = bnad->rxq_depth; + ringparam->rx_mini_max_pending = 0; + ringparam->rx_jumbo_max_pending = 0; + ringparam->tx_pending = bnad->txq_depth; +} + +static int +bnad_set_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ringparam) +{ + int i, current_err, err = 0; + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + if (ringparam->rx_pending == bnad->rxq_depth && + ringparam->tx_pending == bnad->txq_depth) { + mutex_unlock(&bnad->conf_mutex); + return 0; + } + + if (ringparam->rx_pending < BNAD_MIN_Q_DEPTH || + ringparam->rx_pending > BNAD_MAX_Q_DEPTH / bnad_rxqs_per_cq || + !BNA_POWER_OF_2(ringparam->rx_pending)) { + mutex_unlock(&bnad->conf_mutex); + return -EINVAL; + } + if (ringparam->tx_pending < BNAD_MIN_Q_DEPTH || + ringparam->tx_pending > BNAD_MAX_Q_DEPTH || + !BNA_POWER_OF_2(ringparam->tx_pending)) { + mutex_unlock(&bnad->conf_mutex); + return -EINVAL; + } + + if (ringparam->rx_pending != bnad->rxq_depth) { + bnad->rxq_depth = ringparam->rx_pending; + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + bnad_cleanup_rx(bnad, i); + current_err = bnad_setup_rx(bnad, i); + if (current_err && !err) + err = current_err; + } + } + if (ringparam->tx_pending != bnad->txq_depth) { + bnad->txq_depth = ringparam->tx_pending; + for (i = 0; i < bnad->num_tx; i++) { + if (!bnad->tx_info[i].tx) + continue; + bnad_cleanup_tx(bnad, i); + current_err = bnad_setup_tx(bnad, i); + if (current_err && !err) + err = current_err; + } + } + + mutex_unlock(&bnad->conf_mutex); + return err; +} + +static void +bnad_get_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pauseparam) +{ + struct bnad *bnad = netdev_priv(netdev); + + pauseparam->autoneg = 0; + pauseparam->rx_pause = bnad->bna.port.pause_config.rx_pause; + pauseparam->tx_pause = bnad->bna.port.pause_config.tx_pause; +} + +static int +bnad_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pauseparam) +{ + struct bnad *bnad = netdev_priv(netdev); + struct bna_pause_config pause_config; + unsigned long flags; + + if (pauseparam->autoneg == AUTONEG_ENABLE) + return -EINVAL; + + mutex_lock(&bnad->conf_mutex); + if (pauseparam->rx_pause != bnad->bna.port.pause_config.rx_pause || + pauseparam->tx_pause != bnad->bna.port.pause_config.tx_pause) { + pause_config.rx_pause = pauseparam->rx_pause; + pause_config.tx_pause = pauseparam->tx_pause; + spin_lock_irqsave(&bnad->bna_lock, flags); + bna_port_pause_config(&bnad->bna.port, &pause_config, NULL); + spin_unlock_irqrestore(&bnad->bna_lock, flags); + } + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static u32 +bnad_get_rx_csum(struct net_device *netdev) +{ + u32 rx_csum; + struct bnad *bnad = netdev_priv(netdev); + + rx_csum = bnad->rx_csum; + return rx_csum; +} + +static int +bnad_set_rx_csum(struct net_device *netdev, u32 rx_csum) +{ + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + bnad->rx_csum = rx_csum; + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static int +bnad_set_tx_csum(struct net_device *netdev, u32 tx_csum) +{ + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + if (tx_csum) { + netdev->features |= NETIF_F_IP_CSUM; + netdev->features |= NETIF_F_IPV6_CSUM; + } else { + netdev->features &= ~NETIF_F_IP_CSUM; + netdev->features &= ~NETIF_F_IPV6_CSUM; + } + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static int +bnad_set_tso(struct net_device *netdev, u32 tso) +{ + struct bnad *bnad = netdev_priv(netdev); + + mutex_lock(&bnad->conf_mutex); + if (tso) { + netdev->features |= NETIF_F_TSO; + netdev->features |= NETIF_F_TSO6; + } else { + netdev->features &= ~NETIF_F_TSO; + netdev->features &= ~NETIF_F_TSO6; + } + mutex_unlock(&bnad->conf_mutex); + return 0; +} + +static void +bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string) +{ + struct bnad *bnad = netdev_priv(netdev); + int i, j, q_num; + u64 bmap; + + mutex_lock(&bnad->conf_mutex); + + switch (stringset) { + case ETH_SS_STATS: + for (i = 0; i < BNAD_ETHTOOL_STATS_NUM; i++) { + BUG_ON(!(strlen(bnad_net_stats_strings[i]) < + ETH_GSTRING_LEN)); + memcpy(string, bnad_net_stats_strings[i], + ETH_GSTRING_LEN); + string += ETH_GSTRING_LEN; + } + bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] | + ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) { + if (bmap & 1) { + sprintf(string, "txf%d_ucast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_ucast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_ucast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_mcast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_mcast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_mcast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_bcast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_bcast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_bcast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_errors", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_filter_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "txf%d_filter_mac_sa", i); + string += ETH_GSTRING_LEN; + } + bmap >>= 1; + } + + bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] | + ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { + if (bmap & 1) { + sprintf(string, "rxf%d_ucast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_ucast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_ucast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_mcast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_mcast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_mcast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_bcast_octets", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_bcast", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_bcast_vlan", i); + string += ETH_GSTRING_LEN; + sprintf(string, "rxf%d_frame_drops", i); + string += ETH_GSTRING_LEN; + } + bmap >>= 1; + } + + q_num = 0; + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + sprintf(string, "cq%d_producer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "cq%d_consumer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "cq%d_hw_producer_index", + q_num); + string += ETH_GSTRING_LEN; + q_num++; + } + } + + q_num = 0; + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) { + sprintf(string, "rxq%d_packets", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_bytes", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_packets_with_error", + q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_allocbuf_failed", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_producer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_consumer_index", q_num); + string += ETH_GSTRING_LEN; + q_num++; + if (bnad->rx_info[i].rx_ctrl[j].ccb && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[1] && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[1]->rxq) { + sprintf(string, "rxq%d_packets", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_bytes", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, + "rxq%d_packets_with_error", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_allocbuf_failed", + q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_producer_index", + q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "rxq%d_consumer_index", + q_num); + string += ETH_GSTRING_LEN; + q_num++; + } + } + } + + q_num = 0; + for (i = 0; i < bnad->num_tx; i++) { + if (!bnad->tx_info[i].tx) + continue; + for (j = 0; j < bnad->num_txq_per_tx; j++) { + sprintf(string, "txq%d_packets", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "txq%d_bytes", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "txq%d_producer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "txq%d_consumer_index", q_num); + string += ETH_GSTRING_LEN; + sprintf(string, "txq%d_hw_consumer_index", + q_num); + string += ETH_GSTRING_LEN; + q_num++; + } + } + + break; + + default: + break; + } + + mutex_unlock(&bnad->conf_mutex); +} + +static int +bnad_get_stats_count_locked(struct net_device *netdev) +{ + struct bnad *bnad = netdev_priv(netdev); + int i, j, count, rxf_active_num = 0, txf_active_num = 0; + u64 bmap; + + bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] | + ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) { + if (bmap & 1) + txf_active_num++; + bmap >>= 1; + } + bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] | + ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { + if (bmap & 1) + rxf_active_num++; + bmap >>= 1; + } + count = BNAD_ETHTOOL_STATS_NUM + + txf_active_num * BNAD_NUM_TXF_COUNTERS + + rxf_active_num * BNAD_NUM_RXF_COUNTERS; + + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + count += bnad->num_rxp_per_rx * BNAD_NUM_CQ_COUNTERS; + count += bnad->num_rxp_per_rx * BNAD_NUM_RXQ_COUNTERS; + for (j = 0; j < bnad->num_rxp_per_rx; j++) + if (bnad->rx_info[i].rx_ctrl[j].ccb && + bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] && + bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1]->rxq) + count += BNAD_NUM_RXQ_COUNTERS; + } + + for (i = 0; i < bnad->num_tx; i++) { + if (!bnad->tx_info[i].tx) + continue; + count += bnad->num_txq_per_tx * BNAD_NUM_TXQ_COUNTERS; + } + return count; +} + +static int +bnad_per_q_stats_fill(struct bnad *bnad, u64 *buf, int bi) +{ + int i, j; + struct bna_rcb *rcb = NULL; + struct bna_tcb *tcb = NULL; + + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) + if (bnad->rx_info[i].rx_ctrl[j].ccb && + bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] && + bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0]->rxq) { + buf[bi++] = bnad->rx_info[i].rx_ctrl[j]. + ccb->producer_index; + buf[bi++] = 0; /* ccb->consumer_index */ + buf[bi++] = *(bnad->rx_info[i].rx_ctrl[j]. + ccb->hw_producer_index); + } + } + for (i = 0; i < bnad->num_rx; i++) { + if (!bnad->rx_info[i].rx) + continue; + for (j = 0; j < bnad->num_rxp_per_rx; j++) + if (bnad->rx_info[i].rx_ctrl[j].ccb) { + if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[0] && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[0]->rxq) { + rcb = bnad->rx_info[i].rx_ctrl[j]. + ccb->rcb[0]; + buf[bi++] = rcb->rxq->rx_packets; + buf[bi++] = rcb->rxq->rx_bytes; + buf[bi++] = rcb->rxq-> + rx_packets_with_error; + buf[bi++] = rcb->rxq-> + rxbuf_alloc_failed; + buf[bi++] = rcb->producer_index; + buf[bi++] = rcb->consumer_index; + } + if (bnad->rx_info[i].rx_ctrl[j].ccb->rcb[1] && + bnad->rx_info[i].rx_ctrl[j].ccb-> + rcb[1]->rxq) { + rcb = bnad->rx_info[i].rx_ctrl[j]. + ccb->rcb[1]; + buf[bi++] = rcb->rxq->rx_packets; + buf[bi++] = rcb->rxq->rx_bytes; + buf[bi++] = rcb->rxq-> + rx_packets_with_error; + buf[bi++] = rcb->rxq-> + rxbuf_alloc_failed; + buf[bi++] = rcb->producer_index; + buf[bi++] = rcb->consumer_index; + } + } + } + + for (i = 0; i < bnad->num_tx; i++) { + if (!bnad->tx_info[i].tx) + continue; + for (j = 0; j < bnad->num_txq_per_tx; j++) + if (bnad->tx_info[i].tcb[j] && + bnad->tx_info[i].tcb[j]->txq) { + tcb = bnad->tx_info[i].tcb[j]; + buf[bi++] = tcb->txq->tx_packets; + buf[bi++] = tcb->txq->tx_bytes; + buf[bi++] = tcb->producer_index; + buf[bi++] = tcb->consumer_index; + buf[bi++] = *(tcb->hw_consumer_index); + } + } + + return bi; +} + +static void +bnad_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, + u64 *buf) +{ + struct bnad *bnad = netdev_priv(netdev); + int i, j, bi; + unsigned long flags; + struct rtnl_link_stats64 *net_stats64; + u64 *stats64; + u64 bmap; + + mutex_lock(&bnad->conf_mutex); + if (bnad_get_stats_count_locked(netdev) != stats->n_stats) { + mutex_unlock(&bnad->conf_mutex); + return; + } + + /* + * Used bna_lock to sync reads from bna_stats, which is written + * under the same lock + */ + spin_lock_irqsave(&bnad->bna_lock, flags); + bi = 0; + memset(buf, 0, stats->n_stats * sizeof(u64)); + + net_stats64 = (struct rtnl_link_stats64 *)buf; + bnad_netdev_qstats_fill(bnad, net_stats64); + bnad_netdev_hwstats_fill(bnad, net_stats64); + + bi = sizeof(*net_stats64) / sizeof(u64); + + /* Fill driver stats into ethtool buffers */ + stats64 = (u64 *)&bnad->stats.drv_stats; + for (i = 0; i < sizeof(struct bnad_drv_stats) / sizeof(u64); i++) + buf[bi++] = stats64[i]; + + /* Fill hardware stats excluding the rxf/txf into ethtool bufs */ + stats64 = (u64 *) bnad->stats.bna_stats->hw_stats; + for (i = 0; + i < offsetof(struct bfi_ll_stats, rxf_stats[0]) / sizeof(u64); + i++) + buf[bi++] = stats64[i]; + + /* Fill txf stats into ethtool buffers */ + bmap = (u64)bnad->bna.tx_mod.txf_bmap[0] | + ((u64)bnad->bna.tx_mod.txf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_TXF_ID_MAX); i++) { + if (bmap & 1) { + stats64 = (u64 *)&bnad->stats.bna_stats-> + hw_stats->txf_stats[i]; + for (j = 0; j < sizeof(struct bfi_ll_stats_txf) / + sizeof(u64); j++) + buf[bi++] = stats64[j]; + } + bmap >>= 1; + } + + /* Fill rxf stats into ethtool buffers */ + bmap = (u64)bnad->bna.rx_mod.rxf_bmap[0] | + ((u64)bnad->bna.rx_mod.rxf_bmap[1] << 32); + for (i = 0; bmap && (i < BFI_LL_RXF_ID_MAX); i++) { + if (bmap & 1) { + stats64 = (u64 *)&bnad->stats.bna_stats-> + hw_stats->rxf_stats[i]; + for (j = 0; j < sizeof(struct bfi_ll_stats_rxf) / + sizeof(u64); j++) + buf[bi++] = stats64[j]; + } + bmap >>= 1; + } + + /* Fill per Q stats into ethtool buffers */ + bi = bnad_per_q_stats_fill(bnad, buf, bi); + + spin_unlock_irqrestore(&bnad->bna_lock, flags); + + mutex_unlock(&bnad->conf_mutex); +} + +static int +bnad_get_sset_count(struct net_device *netdev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return bnad_get_stats_count_locked(netdev); + default: + return -EOPNOTSUPP; + } +} + +static struct ethtool_ops bnad_ethtool_ops = { + .get_settings = bnad_get_settings, + .set_settings = bnad_set_settings, + .get_drvinfo = bnad_get_drvinfo, + .get_regs_len = bnad_get_regs_len, + .get_regs = bnad_get_regs, + .get_wol = bnad_get_wol, + .get_link = ethtool_op_get_link, + .get_coalesce = bnad_get_coalesce, + .set_coalesce = bnad_set_coalesce, + .get_ringparam = bnad_get_ringparam, + .set_ringparam = bnad_set_ringparam, + .get_pauseparam = bnad_get_pauseparam, + .set_pauseparam = bnad_set_pauseparam, + .get_rx_csum = bnad_get_rx_csum, + .set_rx_csum = bnad_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = bnad_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, + .get_tso = ethtool_op_get_tso, + .set_tso = bnad_set_tso, + .get_strings = bnad_get_strings, + .get_ethtool_stats = bnad_get_ethtool_stats, + .get_sset_count = bnad_get_sset_count +}; + +void +bnad_set_ethtool_ops(struct net_device *netdev) +{ + SET_ETHTOOL_OPS(netdev, &bnad_ethtool_ops); +} diff --git a/drivers/net/bna/cna.h b/drivers/net/bna/cna.h new file mode 100644 index 0000000000000000000000000000000000000000..bbd39dc659727cceccc2d42455e686c382af9027 --- /dev/null +++ b/drivers/net/bna/cna.h @@ -0,0 +1,81 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2006-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ + +#ifndef __CNA_H__ +#define __CNA_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define bfa_sm_fault(__mod, __event) do { \ + pr_err("SM Assertion failure: %s: %d: event = %d", __FILE__, __LINE__, \ + __event); \ +} while (0) + +extern char bfa_version[]; + +#define CNA_FW_FILE_CT "ctfw_cna.bin" +#define FC_SYMNAME_MAX 256 /*!< max name server symbolic name size */ + +#pragma pack(1) + +#define MAC_ADDRLEN (6) +typedef struct mac { u8 mac[MAC_ADDRLEN]; } mac_t; + +#pragma pack() + +#define bfa_q_first(_q) ((void *)(((struct list_head *) (_q))->next)) +#define bfa_q_next(_qe) (((struct list_head *) (_qe))->next) +#define bfa_q_prev(_qe) (((struct list_head *) (_qe))->prev) + +/* + * bfa_q_qe_init - to initialize a queue element + */ +#define bfa_q_qe_init(_qe) { \ + bfa_q_next(_qe) = (struct list_head *) NULL; \ + bfa_q_prev(_qe) = (struct list_head *) NULL; \ +} + +/* + * bfa_q_deq - dequeue an element from head of the queue + */ +#define bfa_q_deq(_q, _qe) { \ + if (!list_empty(_q)) { \ + (*((struct list_head **) (_qe))) = bfa_q_next(_q); \ + bfa_q_prev(bfa_q_next(*((struct list_head **) _qe))) = \ + (struct list_head *) (_q); \ + bfa_q_next(_q) = bfa_q_next(*((struct list_head **) _qe)); \ + bfa_q_qe_init(*((struct list_head **) _qe)); \ + } else { \ + *((struct list_head **) (_qe)) = (struct list_head *) NULL; \ + } \ +} + +#endif /* __CNA_H__ */ diff --git a/drivers/net/bna/cna_fwimg.c b/drivers/net/bna/cna_fwimg.c new file mode 100644 index 0000000000000000000000000000000000000000..e8f4ecd9ebb5cd8c70235d891899673059bb76a3 --- /dev/null +++ b/drivers/net/bna/cna_fwimg.c @@ -0,0 +1,64 @@ +/* + * Linux network driver for Brocade Converged Network Adapter. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License (GPL) Version 2 as + * published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +/* + * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. + * All rights reserved + * www.brocade.com + */ +#include +#include "cna.h" + +const struct firmware *bfi_fw; +static u32 *bfi_image_ct_cna; +static u32 bfi_image_ct_cna_size; + +static u32 * +cna_read_firmware(struct pci_dev *pdev, u32 **bfi_image, + u32 *bfi_image_size, char *fw_name) +{ + const struct firmware *fw; + + if (request_firmware(&fw, fw_name, &pdev->dev)) { + pr_alert("Can't locate firmware %s\n", fw_name); + goto error; + } + + *bfi_image = (u32 *)fw->data; + *bfi_image_size = fw->size/sizeof(u32); + bfi_fw = fw; + + return *bfi_image; +error: + return NULL; +} + +u32 * +cna_get_firmware_buf(struct pci_dev *pdev) +{ + if (bfi_image_ct_cna_size == 0) + cna_read_firmware(pdev, &bfi_image_ct_cna, + &bfi_image_ct_cna_size, CNA_FW_FILE_CT); + return bfi_image_ct_cna; +} + +u32 * +bfa_cb_image_get_chunk(int type, u32 off) +{ + return (u32 *)(bfi_image_ct_cna + off); +} + +u32 +bfa_cb_image_get_size(int type) +{ + return bfi_image_ct_cna_size; +} diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index e6a803f1c507f848ee8b4ac28ddb4ce8fc138c44..062600be073b91b47a70b0d65edb8824b941c1f8 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -37,9 +37,6 @@ #include #include #include -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -#define BCM_VLAN 1 -#endif #include #include #include @@ -49,6 +46,7 @@ #include #include #include +#include #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 @@ -58,13 +56,13 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.0.17" -#define DRV_MODULE_RELDATE "July 18, 2010" -#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-5.0.0.j6.fw" -#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-5.0.0.j3.fw" -#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-5.0.0.j15.fw" -#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw" -#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-5.0.0.j10.fw" +#define DRV_MODULE_VERSION "2.0.18" +#define DRV_MODULE_RELDATE "Oct 7, 2010" +#define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.0.15.fw" +#define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" +#define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.0.17.fw" +#define FW_RV2P_FILE_09_Ax "bnx2/bnx2-rv2p-09ax-6.0.17.fw" +#define FW_RV2P_FILE_09 "bnx2/bnx2-rv2p-09-6.0.17.fw" #define RUN_AT(x) (jiffies + (x)) @@ -265,7 +263,7 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr) if (diff == TX_DESC_CNT) diff = MAX_TX_DESC_CNT; } - return (bp->tx_ring_size - diff); + return bp->tx_ring_size - diff; } static u32 @@ -298,7 +296,7 @@ bnx2_shmem_wr(struct bnx2 *bp, u32 offset, u32 val) static u32 bnx2_shmem_rd(struct bnx2 *bp, u32 offset) { - return (bnx2_reg_rd_ind(bp, bp->shmem_base + offset)); + return bnx2_reg_rd_ind(bp, bp->shmem_base + offset); } static void @@ -976,9 +974,9 @@ bnx2_report_fw_link(struct bnx2 *bp) static char * bnx2_xceiver_str(struct bnx2 *bp) { - return ((bp->phy_port == PORT_FIBRE) ? "SerDes" : + return (bp->phy_port == PORT_FIBRE) ? "SerDes" : ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) ? "Remote Copper" : - "Copper")); + "Copper"); } static void @@ -1268,30 +1266,9 @@ bnx2_init_rx_context(struct bnx2 *bp, u32 cid) val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; val |= 0x02 << 8; - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - u32 lo_water, hi_water; - - if (bp->flow_ctrl & FLOW_CTRL_TX) - lo_water = BNX2_L2CTX_LO_WATER_MARK_DEFAULT; - else - lo_water = BNX2_L2CTX_LO_WATER_MARK_DIS; - if (lo_water >= bp->rx_ring_size) - lo_water = 0; - - hi_water = min_t(int, bp->rx_ring_size / 4, lo_water + 16); - - if (hi_water <= lo_water) - lo_water = 0; - - hi_water /= BNX2_L2CTX_HI_WATER_MARK_SCALE; - lo_water /= BNX2_L2CTX_LO_WATER_MARK_SCALE; + if (bp->flow_ctrl & FLOW_CTRL_TX) + val |= BNX2_L2CTX_FLOW_CTRL_ENABLE; - if (hi_water > 0xf) - hi_water = 0xf; - else if (hi_water == 0) - lo_water = 0; - val |= lo_water | (hi_water << BNX2_L2CTX_HI_WATER_MARK_SHIFT); - } bnx2_ctx_wr(bp, rx_cid_addr, BNX2_L2CTX_CTX_TYPE, val); } @@ -1372,8 +1349,7 @@ bnx2_set_mac_link(struct bnx2 *bp) /* Acknowledge the interrupt. */ REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); - if (CHIP_NUM(bp) == CHIP_NUM_5709) - bnx2_init_all_rx_contexts(bp); + bnx2_init_all_rx_contexts(bp); } static void @@ -1757,7 +1733,7 @@ __acquires(&bp->phy_lock) u32 new_adv = 0; if (bp->phy_flags & BNX2_PHY_FLAG_REMOTE_PHY_CAP) - return (bnx2_setup_remote_phy(bp, port)); + return bnx2_setup_remote_phy(bp, port); if (!(bp->autoneg & AUTONEG_SPEED)) { u32 new_bmcr; @@ -2170,10 +2146,10 @@ __acquires(&bp->phy_lock) return 0; if (bp->phy_flags & BNX2_PHY_FLAG_SERDES) { - return (bnx2_setup_serdes_phy(bp, port)); + return bnx2_setup_serdes_phy(bp, port); } else { - return (bnx2_setup_copper_phy(bp)); + return bnx2_setup_copper_phy(bp); } } @@ -3108,8 +3084,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) struct sw_bd *rx_buf, *next_rx_buf; struct sk_buff *skb; dma_addr_t dma_addr; - u16 vtag = 0; - int hw_vlan __maybe_unused = 0; sw_ring_cons = RX_RING_IDX(sw_cons); sw_ring_prod = RX_RING_IDX(sw_prod); @@ -3189,23 +3163,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) goto next_rx; if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && - !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) { - vtag = rx_hdr->l2_fhdr_vlan_tag; -#ifdef BCM_VLAN - if (bp->vlgrp) - hw_vlan = 1; - else -#endif - { - struct vlan_ethhdr *ve = (struct vlan_ethhdr *) - __skb_push(skb, 4); - - memmove(ve, skb->data + 4, ETH_ALEN * 2); - ve->h_vlan_proto = htons(ETH_P_8021Q); - ve->h_vlan_TCI = htons(vtag); - len += 4; - } - } + !(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) + __vlan_hwaccel_put_tag(skb, rx_hdr->l2_fhdr_vlan_tag); skb->protocol = eth_type_trans(skb, bp->dev); @@ -3217,7 +3176,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) } - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (bp->rx_csum && (status & (L2_FHDR_STATUS_TCP_SEGMENT | L2_FHDR_STATUS_UDP_DATAGRAM))) { @@ -3232,14 +3191,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) skb->rxhash = rx_hdr->l2_fhdr_hash; skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]); - -#ifdef BCM_VLAN - if (hw_vlan) - vlan_gro_receive(&bnapi->napi, bp->vlgrp, vtag, skb); - else -#endif - napi_gro_receive(&bnapi->napi, skb); - + napi_gro_receive(&bnapi->napi, skb); rx_pkt++; next_rx: @@ -3554,13 +3506,9 @@ bnx2_set_rx_mode(struct net_device *dev) rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; -#ifdef BCM_VLAN - if (!bp->vlgrp && (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) + if (!(dev->features & NETIF_F_HW_VLAN_RX) && + (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN)) rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; -#else - if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) - rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; -#endif if (dev->flags & IFF_PROMISC) { /* Promiscuous mode. */ rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; @@ -4973,6 +4921,11 @@ bnx2_init_chip(struct bnx2 *bp) REG_WR(bp, BNX2_HC_CONFIG, val); + if (bp->rx_ticks < 25) + bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 1); + else + bnx2_reg_wr_ind(bp, BNX2_FW_RX_LOW_LATENCY, 0); + for (i = 1; i < bp->irq_nvecs; i++) { u32 base = ((i - 1) * BNX2_HC_SB_CONFIG_SIZE) + BNX2_HC_SB_CONFIG_1; @@ -5241,18 +5194,20 @@ bnx2_init_all_rings(struct bnx2 *bp) bnx2_init_rx_ring(bp, i); if (bp->num_rx_rings > 1) { - u32 tbl_32; - u8 *tbl = (u8 *) &tbl_32; - - bnx2_reg_wr_ind(bp, BNX2_RXP_SCRATCH_RSS_TBL_SZ, - BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES); + u32 tbl_32 = 0; for (i = 0; i < BNX2_RXP_SCRATCH_RSS_TBL_MAX_ENTRIES; i++) { - tbl[i % 4] = i % (bp->num_rx_rings - 1); - if ((i % 4) == 3) - bnx2_reg_wr_ind(bp, - BNX2_RXP_SCRATCH_RSS_TBL + i, - cpu_to_be32(tbl_32)); + int shift = (i % 8) << 2; + + tbl_32 |= (i % (bp->num_rx_rings - 1)) << shift; + if ((i % 8) == 7) { + REG_WR(bp, BNX2_RLUP_RSS_DATA, tbl_32); + REG_WR(bp, BNX2_RLUP_RSS_COMMAND, (i >> 3) | + BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK | + BNX2_RLUP_RSS_COMMAND_WRITE | + BNX2_RLUP_RSS_COMMAND_HASH_MASK); + tbl_32 = 0; + } } val = BNX2_RLUP_RSS_CONFIG_IPV4_RSS_TYPE_ALL_XI | @@ -6201,7 +6156,7 @@ bnx2_enable_msix(struct bnx2 *bp, int msix_vecs) } } -static void +static int bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) { int cpus = num_online_cpus(); @@ -6230,9 +6185,10 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi) } bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs); - bp->dev->real_num_tx_queues = bp->num_tx_rings; + netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings); bp->num_rx_rings = bp->irq_nvecs; + return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings); } /* Called with rtnl_lock */ @@ -6247,7 +6203,9 @@ bnx2_open(struct net_device *dev) bnx2_set_power_state(bp, PCI_D0); bnx2_disable_int(bp); - bnx2_setup_int_mode(bp, disable_msi); + rc = bnx2_setup_int_mode(bp, disable_msi); + if (rc) + goto open_err; bnx2_init_napi(bp); bnx2_napi_enable(bp); rc = bnx2_alloc_mem(bp); @@ -6376,29 +6334,6 @@ bnx2_tx_timeout(struct net_device *dev) schedule_work(&bp->reset_task); } -#ifdef BCM_VLAN -/* Called with rtnl_lock */ -static void -bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp) -{ - struct bnx2 *bp = netdev_priv(dev); - - if (netif_running(dev)) - bnx2_netif_stop(bp, false); - - bp->vlgrp = vlgrp; - - if (!netif_running(dev)) - return; - - bnx2_set_rx_mode(dev); - if (bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) - bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); - - bnx2_netif_start(bp, false); -} -#endif - /* Called with netif_tx_lock. * bnx2_tx_int() runs without netif_tx_lock unless it needs to call * netif_wake_queue(). @@ -6439,12 +6374,11 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; } -#ifdef BCM_VLAN - if (bp->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { vlan_tag_flags |= (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); } -#endif + if ((mss = skb_shinfo(skb)->gso_size)) { u32 tcp_opt_len; struct iphdr *iph; @@ -7581,15 +7515,36 @@ bnx2_set_tx_csum(struct net_device *dev, u32 data) struct bnx2 *bp = netdev_priv(dev); if (CHIP_NUM(bp) == CHIP_NUM_5709) - return (ethtool_op_set_tx_ipv6_csum(dev, data)); + return ethtool_op_set_tx_ipv6_csum(dev, data); else - return (ethtool_op_set_tx_csum(dev, data)); + return ethtool_op_set_tx_csum(dev, data); } static int bnx2_set_flags(struct net_device *dev, u32 data) { - return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH); + struct bnx2 *bp = netdev_priv(dev); + int rc; + + if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) && + !(data & ETH_FLAG_RXVLAN)) + return -EINVAL; + + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN | + ETH_FLAG_TXVLAN); + if (rc) + return rc; + + if ((!!(data & ETH_FLAG_RXVLAN) != + !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) && + netif_running(dev)) { + bnx2_netif_stop(bp, false); + bnx2_set_rx_mode(dev); + bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1); + bnx2_netif_start(bp, false); + } + + return 0; } static const struct ethtool_ops bnx2_ethtool_ops = { @@ -7704,7 +7659,7 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; dev->mtu = new_mtu; - return (bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size)); + return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -7890,6 +7845,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) int rc, i, j; u32 reg; u64 dma_mask, persist_dma_mask; + int err; SET_NETDEV_DEV(dev, &pdev->dev); bp = netdev_priv(dev); @@ -7926,7 +7882,6 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) } pci_set_master(pdev); - pci_save_state(pdev); bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); if (bp->pm_cap == 0) { @@ -7981,6 +7936,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->flags |= BNX2_FLAG_PCIE; if (CHIP_REV(bp) == CHIP_REV_Ax) bp->flags |= BNX2_FLAG_JUMBO_BROKEN; + + /* AER (Advanced Error Reporting) hooks */ + err = pci_enable_pcie_error_reporting(pdev); + if (err) { + dev_err(&pdev->dev, "pci_enable_pcie_error_reporting " + "failed 0x%x\n", err); + /* non-fatal, continue */ + } + } else { bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); if (bp->pcix_cap == 0) { @@ -8237,9 +8201,14 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->timer.data = (unsigned long) bp; bp->timer.function = bnx2_timer; + pci_save_state(pdev); + return 0; err_out_unmap: + if (bp->flags & BNX2_FLAG_PCIE) + pci_disable_pcie_error_reporting(pdev); + if (bp->regview) { iounmap(bp->regview); bp->regview = NULL; @@ -8315,9 +8284,6 @@ static const struct net_device_ops bnx2_netdev_ops = { .ndo_set_mac_address = bnx2_change_mac_addr, .ndo_change_mtu = bnx2_change_mtu, .ndo_tx_timeout = bnx2_tx_timeout, -#ifdef BCM_VLAN - .ndo_vlan_rx_register = bnx2_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2, #endif @@ -8325,9 +8291,7 @@ static const struct net_device_ops bnx2_netdev_ops = { static void inline vlan_features_add(struct net_device *dev, unsigned long flags) { -#ifdef BCM_VLAN dev->vlan_features |= flags; -#endif } static int __devinit @@ -8376,9 +8340,7 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->features |= NETIF_F_IPV6_CSUM; vlan_features_add(dev, NETIF_F_IPV6_CSUM); } -#ifdef BCM_VLAN dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; -#endif dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN; vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN); if (CHIP_NUM(bp) == CHIP_NUM_5709) { @@ -8435,7 +8397,11 @@ bnx2_remove_one(struct pci_dev *pdev) kfree(bp->temp_stats_blk); + if (bp->flags & BNX2_FLAG_PCIE) + pci_disable_pcie_error_reporting(pdev); + free_netdev(dev); + pci_release_regions(pdev); pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); @@ -8527,25 +8493,38 @@ static pci_ers_result_t bnx2_io_slot_reset(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); struct bnx2 *bp = netdev_priv(dev); + pci_ers_result_t result; + int err; rtnl_lock(); if (pci_enable_device(pdev)) { dev_err(&pdev->dev, "Cannot re-enable PCI device after reset\n"); - rtnl_unlock(); - return PCI_ERS_RESULT_DISCONNECT; + result = PCI_ERS_RESULT_DISCONNECT; + } else { + pci_set_master(pdev); + pci_restore_state(pdev); + pci_save_state(pdev); + + if (netif_running(dev)) { + bnx2_set_power_state(bp, PCI_D0); + bnx2_init_nic(bp, 1); + } + result = PCI_ERS_RESULT_RECOVERED; } - pci_set_master(pdev); - pci_restore_state(pdev); - pci_save_state(pdev); + rtnl_unlock(); - if (netif_running(dev)) { - bnx2_set_power_state(bp, PCI_D0); - bnx2_init_nic(bp, 1); + if (!(bp->flags & BNX2_FLAG_PCIE)) + return result; + + err = pci_cleanup_aer_uncorrect_error_status(pdev); + if (err) { + dev_err(&pdev->dev, + "pci_cleanup_aer_uncorrect_error_status failed 0x%0x\n", + err); /* non-fatal, continue */ } - rtnl_unlock(); - return PCI_ERS_RESULT_RECOVERED; + return result; } /** diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 2104c1005d023fee037d49ee5c8cd6595ad93acb..bf4c3421067d2078b56c6da7818f25c979717185 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -352,12 +352,7 @@ struct l2_fhdr { #define BNX2_L2CTX_BD_PRE_READ 0x00000000 #define BNX2_L2CTX_CTX_SIZE 0x00000000 #define BNX2_L2CTX_CTX_TYPE 0x00000000 -#define BNX2_L2CTX_LO_WATER_MARK_DEFAULT 4 -#define BNX2_L2CTX_LO_WATER_MARK_SCALE 4 -#define BNX2_L2CTX_LO_WATER_MARK_DIS 0 -#define BNX2_L2CTX_HI_WATER_MARK_SHIFT 4 -#define BNX2_L2CTX_HI_WATER_MARK_SCALE 16 -#define BNX2_L2CTX_WATER_MARKS_MSK 0x000000ff +#define BNX2_L2CTX_FLOW_CTRL_ENABLE 0x000000ff #define BNX2_L2CTX_CTX_TYPE_SIZE_L2 ((0x20/20)<<16) #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE (0xf<<28) #define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED (0<<28) @@ -4185,6 +4180,15 @@ struct l2_fhdr { #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_IP_ONLY_XI (2L<<2) #define BNX2_RLUP_RSS_CONFIG_IPV6_RSS_TYPE_RES_XI (3L<<2) +#define BNX2_RLUP_RSS_COMMAND 0x00002048 +#define BNX2_RLUP_RSS_COMMAND_RSS_IND_TABLE_ADDR (0xfUL<<0) +#define BNX2_RLUP_RSS_COMMAND_RSS_WRITE_MASK (0xffUL<<4) +#define BNX2_RLUP_RSS_COMMAND_WRITE (1UL<<12) +#define BNX2_RLUP_RSS_COMMAND_READ (1UL<<13) +#define BNX2_RLUP_RSS_COMMAND_HASH_MASK (0x7UL<<14) + +#define BNX2_RLUP_RSS_DATA 0x0000204c + /* * rbuf_reg definition @@ -6077,6 +6081,7 @@ struct l2_fhdr { #define BNX2_COM_SCRATCH 0x00120000 +#define BNX2_FW_RX_LOW_LATENCY 0x00120058 #define BNX2_FW_RX_DROP_COUNT 0x00120084 @@ -6497,8 +6502,8 @@ struct l2_fhdr { #define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct tx_bd)) #define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) -#define MAX_RX_RINGS 4 -#define MAX_RX_PG_RINGS 16 +#define MAX_RX_RINGS 8 +#define MAX_RX_PG_RINGS 32 #define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd)) #define MAX_RX_DESC_CNT (RX_DESC_CNT - 1) #define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS) @@ -6737,10 +6742,6 @@ struct bnx2 { struct bnx2_napi bnx2_napi[BNX2_MAX_MSIX_VEC]; -#ifdef BCM_VLAN - struct vlan_group *vlgrp; -#endif - u32 rx_buf_use_size; /* useable size */ u32 rx_buf_size; /* with alignment */ u32 rx_copy_thresh; diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 0c2d96ed561c46ebd63f3c03c119c0751b5204e1..9571ecf48f35b11a44e6cb6b6262fa8d3c4fb5b7 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,26 +20,20 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.52.53-4" -#define DRV_MODULE_RELDATE "2010/16/08" +#define DRV_MODULE_VERSION "1.60.00-3" +#define DRV_MODULE_RELDATE "2010/10/19" #define BNX2X_BC_VER 0x040200 -#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -#define BCM_VLAN 1 -#endif - #define BNX2X_MULTI_QUEUE #define BNX2X_NEW_NAPI - #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE) #define BCM_CNIC 1 #include "../cnic_if.h" #endif - #ifdef BCM_CNIC #define BNX2X_MIN_MSIX_VEC_CNT 3 #define BNX2X_MSIX_VEC_FP_START 2 @@ -129,16 +123,18 @@ void bnx2x_panic_dump(struct bnx2x *bp); } while (0) #endif +#define bnx2x_mc_addr(ha) ((ha)->addr) #define U64_LO(x) (u32)(((u64)(x)) & 0xffffffff) #define U64_HI(x) (u32)(((u64)(x)) >> 32) #define HILO_U64(hi, lo) ((((u64)(hi)) << 32) + (lo)) -#define REG_ADDR(bp, offset) (bp->regview + offset) +#define REG_ADDR(bp, offset) ((bp->regview) + (offset)) #define REG_RD(bp, offset) readl(REG_ADDR(bp, offset)) #define REG_RD8(bp, offset) readb(REG_ADDR(bp, offset)) +#define REG_RD16(bp, offset) readw(REG_ADDR(bp, offset)) #define REG_WR(bp, offset, val) writel((u32)val, REG_ADDR(bp, offset)) #define REG_WR8(bp, offset, val) writeb((u8)val, REG_ADDR(bp, offset)) @@ -160,6 +156,9 @@ void bnx2x_panic_dump(struct bnx2x *bp); offset, len32); \ } while (0) +#define REG_WR_DMAE_LEN(bp, offset, valp, len32) \ + REG_WR_DMAE(bp, offset, valp, len32) + #define VIRT_WR_DMAE_LEN(bp, data, addr, len32, le32_swap) \ do { \ memcpy(GUNZIP_BUF(bp), data, (len32) * 4); \ @@ -175,16 +174,59 @@ void bnx2x_panic_dump(struct bnx2x *bp); offsetof(struct shmem2_region, field)) #define SHMEM2_RD(bp, field) REG_RD(bp, SHMEM2_ADDR(bp, field)) #define SHMEM2_WR(bp, field, val) REG_WR(bp, SHMEM2_ADDR(bp, field), val) +#define MF_CFG_ADDR(bp, field) (bp->common.mf_cfg_base + \ + offsetof(struct mf_cfg, field)) +#define MF2_CFG_ADDR(bp, field) (bp->common.mf2_cfg_base + \ + offsetof(struct mf2_cfg, field)) -#define MF_CFG_RD(bp, field) SHMEM_RD(bp, mf_cfg.field) -#define MF_CFG_WR(bp, field, val) SHMEM_WR(bp, mf_cfg.field, val) +#define MF_CFG_RD(bp, field) REG_RD(bp, MF_CFG_ADDR(bp, field)) +#define MF_CFG_WR(bp, field, val) REG_WR(bp,\ + MF_CFG_ADDR(bp, field), (val)) +#define MF2_CFG_RD(bp, field) REG_RD(bp, MF2_CFG_ADDR(bp, field)) + +#define SHMEM2_HAS(bp, field) ((bp)->common.shmem2_base && \ + (SHMEM2_RD((bp), size) > \ + offsetof(struct shmem2_region, field))) #define EMAC_RD(bp, reg) REG_RD(bp, emac_base + reg) #define EMAC_WR(bp, reg, val) REG_WR(bp, emac_base + reg, val) +/* SP SB indices */ + +/* General SP events - stats query, cfc delete, etc */ +#define HC_SP_INDEX_ETH_DEF_CONS 3 + +/* EQ completions */ +#define HC_SP_INDEX_EQ_CONS 7 + +/* iSCSI L2 */ +#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 +#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 + +/** + * CIDs and CLIDs: + * CLIDs below is a CLID for func 0, then the CLID for other + * functions will be calculated by the formula: + * + * FUNC_N_CLID_X = N * NUM_SPECIAL_CLIENTS + FUNC_0_CLID_X + * + */ +/* iSCSI L2 */ +#define BNX2X_ISCSI_ETH_CL_ID 17 +#define BNX2X_ISCSI_ETH_CID 17 + +/** Additional rings budgeting */ +#ifdef BCM_CNIC +#define CNIC_CONTEXT_USE 1 +#else +#define CNIC_CONTEXT_USE 0 +#endif /* BCM_CNIC */ + #define AEU_IN_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR \ AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_PARITY_ERROR +#define SM_RX_ID 0 +#define SM_TX_ID 1 /* fast path */ @@ -254,11 +296,24 @@ union db_prod { #define RX_SGE_MASK_LEN_MASK (RX_SGE_MASK_LEN - 1) #define NEXT_SGE_MASK_ELEM(el) (((el) + 1) & RX_SGE_MASK_LEN_MASK) +union host_hc_status_block { + /* pointer to fp status block e1x */ + struct host_hc_status_block_e1x *e1x_sb; + /* pointer to fp status block e2 */ + struct host_hc_status_block_e2 *e2_sb; +}; struct bnx2x_fastpath { +#define BNX2X_NAPI_WEIGHT 128 struct napi_struct napi; - struct host_status_block *status_blk; + union host_hc_status_block status_blk; + /* chip independed shortcuts into sb structure */ + __le16 *sb_index_values; + __le16 *sb_running_index; + /* chip independed shortcut into rx_prods_offset memory */ + u32 ustorm_rx_prods_offset; + dma_addr_t status_blk_mapping; struct sw_tx_bd *tx_buf_ring; @@ -288,10 +343,15 @@ struct bnx2x_fastpath { #define BNX2X_FP_STATE_OPEN 0xa0000 #define BNX2X_FP_STATE_HALTING 0xb0000 #define BNX2X_FP_STATE_HALTED 0xc0000 +#define BNX2X_FP_STATE_TERMINATING 0xd0000 +#define BNX2X_FP_STATE_TERMINATED 0xe0000 - u8 index; /* number in fp array */ - u8 cl_id; /* eth client id */ - u8 sb_id; /* status block number in HW */ + u8 index; /* number in fp array */ + u8 cl_id; /* eth client id */ + u8 cl_qzone_id; + u8 fw_sb_id; /* status block number in FW */ + u8 igu_sb_id; /* status block number in HW */ + u32 cid; union db_prod tx_db; @@ -301,8 +361,7 @@ struct bnx2x_fastpath { u16 tx_bd_cons; __le16 *tx_cons_sb; - __le16 fp_c_idx; - __le16 fp_u_idx; + __le16 fp_hc_idx; u16 rx_bd_prod; u16 rx_bd_cons; @@ -312,8 +371,6 @@ struct bnx2x_fastpath { /* The last maximal completed SGE */ u16 last_max_sge; __le16 *rx_cons_sb; - __le16 *rx_bd_cons_sb; - unsigned long tx_pkt, rx_pkt, @@ -356,6 +413,8 @@ struct bnx2x_fastpath { #define NUM_TX_BD (TX_DESC_CNT * NUM_TX_RINGS) #define MAX_TX_BD (NUM_TX_BD - 1) #define MAX_TX_AVAIL (MAX_TX_DESC_CNT * NUM_TX_RINGS - 2) +#define INIT_JUMBO_TX_RING_SIZE MAX_TX_AVAIL +#define INIT_TX_RING_SIZE MAX_TX_AVAIL #define NEXT_TX_IDX(x) ((((x) & MAX_TX_DESC_CNT) == \ (MAX_TX_DESC_CNT - 1)) ? (x) + 2 : (x) + 1) #define TX_BD(x) ((x) & MAX_TX_BD) @@ -369,6 +428,9 @@ struct bnx2x_fastpath { #define NUM_RX_BD (RX_DESC_CNT * NUM_RX_RINGS) #define MAX_RX_BD (NUM_RX_BD - 1) #define MAX_RX_AVAIL (MAX_RX_DESC_CNT * NUM_RX_RINGS - 2) +#define MIN_RX_AVAIL 128 +#define INIT_JUMBO_RX_RING_SIZE MAX_RX_AVAIL +#define INIT_RX_RING_SIZE MAX_RX_AVAIL #define NEXT_RX_IDX(x) ((((x) & RX_DESC_MASK) == \ (MAX_RX_DESC_CNT - 1)) ? (x) + 3 : (x) + 1) #define RX_BD(x) ((x) & MAX_RX_BD) @@ -419,11 +481,12 @@ struct bnx2x_fastpath { le32_to_cpu((bd)->addr_lo)) #define BD_UNMAP_LEN(bd) (le16_to_cpu((bd)->nbytes)) - +#define BNX2X_DB_MIN_SHIFT 3 /* 8 bytes */ +#define BNX2X_DB_SHIFT 7 /* 128 bytes*/ #define DPM_TRIGER_TYPE 0x40 #define DOORBELL(bp, cid, val) \ do { \ - writel((u32)(val), bp->doorbells + (BCM_PAGE_SIZE * (cid)) + \ + writel((u32)(val), bp->doorbells + (bp->db_size * (cid)) + \ DPM_TRIGER_TYPE); \ } while (0) @@ -481,31 +544,15 @@ struct bnx2x_fastpath { #define BNX2X_RX_SUM_FIX(cqe) \ BNX2X_PRS_FLAG_OVERETH_IPV4(cqe->fast_path_cqe.pars_flags.flags) - -#define FP_USB_FUNC_OFF (2 + 2*HC_USTORM_SB_NUM_INDICES) -#define FP_CSB_FUNC_OFF (2 + 2*HC_CSTORM_SB_NUM_INDICES) - -#define U_SB_ETH_RX_CQ_INDEX HC_INDEX_U_ETH_RX_CQ_CONS -#define U_SB_ETH_RX_BD_INDEX HC_INDEX_U_ETH_RX_BD_CONS -#define C_SB_ETH_TX_CQ_INDEX HC_INDEX_C_ETH_TX_CQ_CONS +#define U_SB_ETH_RX_CQ_INDEX 1 +#define U_SB_ETH_RX_BD_INDEX 2 +#define C_SB_ETH_TX_CQ_INDEX 5 #define BNX2X_RX_SB_INDEX \ - (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_CQ_INDEX]) - -#define BNX2X_RX_SB_BD_INDEX \ - (&fp->status_blk->u_status_block.index_values[U_SB_ETH_RX_BD_INDEX]) - -#define BNX2X_RX_SB_INDEX_NUM \ - (((U_SB_ETH_RX_CQ_INDEX << \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) | \ - ((U_SB_ETH_RX_BD_INDEX << \ - USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER)) + (&fp->sb_index_values[U_SB_ETH_RX_CQ_INDEX]) #define BNX2X_TX_SB_INDEX \ - (&fp->status_blk->c_status_block.index_values[C_SB_ETH_TX_CQ_INDEX]) - + (&fp->sb_index_values[C_SB_ETH_TX_CQ_INDEX]) /* end of fast path */ @@ -521,12 +568,19 @@ struct bnx2x_common { #define CHIP_NUM_57710 0x164e #define CHIP_NUM_57711 0x164f #define CHIP_NUM_57711E 0x1650 +#define CHIP_NUM_57712 0x1662 +#define CHIP_NUM_57712E 0x1663 #define CHIP_IS_E1(bp) (CHIP_NUM(bp) == CHIP_NUM_57710) #define CHIP_IS_57711(bp) (CHIP_NUM(bp) == CHIP_NUM_57711) #define CHIP_IS_57711E(bp) (CHIP_NUM(bp) == CHIP_NUM_57711E) +#define CHIP_IS_57712(bp) (CHIP_NUM(bp) == CHIP_NUM_57712) +#define CHIP_IS_57712E(bp) (CHIP_NUM(bp) == CHIP_NUM_57712E) #define CHIP_IS_E1H(bp) (CHIP_IS_57711(bp) || \ CHIP_IS_57711E(bp)) -#define IS_E1H_OFFSET CHIP_IS_E1H(bp) +#define CHIP_IS_E2(bp) (CHIP_IS_57712(bp) || \ + CHIP_IS_57712E(bp)) +#define CHIP_IS_E1x(bp) (CHIP_IS_E1((bp)) || CHIP_IS_E1H((bp))) +#define IS_E1H_OFFSET (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) #define CHIP_REV(bp) (bp->common.chip_id & 0x0000f000) #define CHIP_REV_Ax 0x00000000 @@ -552,12 +606,34 @@ struct bnx2x_common { u32 shmem_base; u32 shmem2_base; + u32 mf_cfg_base; + u32 mf2_cfg_base; u32 hw_config; u32 bc_ver; + + u8 int_block; +#define INT_BLOCK_HC 0 +#define INT_BLOCK_IGU 1 +#define INT_BLOCK_MODE_NORMAL 0 +#define INT_BLOCK_MODE_BW_COMP 2 +#define CHIP_INT_MODE_IS_NBC(bp) \ + (CHIP_IS_E2(bp) && \ + !((bp)->common.int_block & INT_BLOCK_MODE_BW_COMP)) +#define CHIP_INT_MODE_IS_BC(bp) (!CHIP_INT_MODE_IS_NBC(bp)) + + u8 chip_port_mode; +#define CHIP_4_PORT_MODE 0x0 +#define CHIP_2_PORT_MODE 0x1 +#define CHIP_PORT_MODE_NONE 0x2 +#define CHIP_MODE(bp) (bp->common.chip_port_mode) +#define CHIP_MODE_IS_4_PORT(bp) (CHIP_MODE(bp) == CHIP_4_PORT_MODE) }; +/* IGU MSIX STATISTICS on 57712: 64 for VFs; 4 for PFs; 4 for Attentions */ +#define BNX2X_IGU_STAS_MSG_VF_CNT 64 +#define BNX2X_IGU_STAS_MSG_PF_CNT 4 /* end of common */ @@ -566,13 +642,13 @@ struct bnx2x_common { struct bnx2x_port { u32 pmf; - u32 link_config; + u32 link_config[LINK_CONFIG_SIZE]; - u32 supported; + u32 supported[LINK_CONFIG_SIZE]; /* link settings - missing defines */ #define SUPPORTED_2500baseX_Full (1 << 15) - u32 advertising; + u32 advertising[LINK_CONFIG_SIZE]; /* link settings - missing defines */ #define ADVERTISED_2500baseX_Full (1 << 15) @@ -589,27 +665,98 @@ struct bnx2x_port { /* end of port */ +/* e1h Classification CAM line allocations */ +enum { + CAM_ETH_LINE = 0, + CAM_ISCSI_ETH_LINE, + CAM_MAX_PF_LINE = CAM_ISCSI_ETH_LINE +}; +#define BNX2X_VF_ID_INVALID 0xFF -#ifdef BCM_CNIC -#define MAX_CONTEXT 15 -#else -#define MAX_CONTEXT 16 -#endif +/* + * The total number of L2 queues, MSIX vectors and HW contexts (CIDs) is + * control by the number of fast-path status blocks supported by the + * device (HW/FW). Each fast-path status block (FP-SB) aka non-default + * status block represents an independent interrupts context that can + * serve a regular L2 networking queue. However special L2 queues such + * as the FCoE queue do not require a FP-SB and other components like + * the CNIC may consume FP-SB reducing the number of possible L2 queues + * + * If the maximum number of FP-SB available is X then: + * a. If CNIC is supported it consumes 1 FP-SB thus the max number of + * regular L2 queues is Y=X-1 + * b. in MF mode the actual number of L2 queues is Y= (X-1/MF_factor) + * c. If the FCoE L2 queue is supported the actual number of L2 queues + * is Y+1 + * d. The number of irqs (MSIX vectors) is either Y+1 (one extra for + * slow-path interrupts) or Y+2 if CNIC is supported (one additional + * FP interrupt context for the CNIC). + * e. The number of HW context (CID count) is always X or X+1 if FCoE + * L2 queue is supported. the cid for the FCoE L2 queue is always X. + */ + +#define FP_SB_MAX_E1x 16 /* fast-path interrupt contexts E1x */ +#define FP_SB_MAX_E2 16 /* fast-path interrupt contexts E2 */ + +/* + * cid_cnt paramter below refers to the value returned by + * 'bnx2x_get_l2_cid_count()' routine + */ + +/* + * The number of FP context allocated by the driver == max number of regular + * L2 queues + 1 for the FCoE L2 queue + */ +#define L2_FP_COUNT(cid_cnt) ((cid_cnt) - CNIC_CONTEXT_USE) union cdu_context { struct eth_context eth; char pad[1024]; }; +/* CDU host DB constants */ +#define CDU_ILT_PAGE_SZ_HW 3 +#define CDU_ILT_PAGE_SZ (4096 << CDU_ILT_PAGE_SZ_HW) /* 32K */ +#define ILT_PAGE_CIDS (CDU_ILT_PAGE_SZ / sizeof(union cdu_context)) + +#ifdef BCM_CNIC +#define CNIC_ISCSI_CID_MAX 256 +#define CNIC_CID_MAX (CNIC_ISCSI_CID_MAX) +#define CNIC_ILT_LINES DIV_ROUND_UP(CNIC_CID_MAX, ILT_PAGE_CIDS) +#endif + +#define QM_ILT_PAGE_SZ_HW 3 +#define QM_ILT_PAGE_SZ (4096 << QM_ILT_PAGE_SZ_HW) /* 32K */ +#define QM_CID_ROUND 1024 + +#ifdef BCM_CNIC +/* TM (timers) host DB constants */ +#define TM_ILT_PAGE_SZ_HW 2 +#define TM_ILT_PAGE_SZ (4096 << TM_ILT_PAGE_SZ_HW) /* 16K */ +/* #define TM_CONN_NUM (CNIC_STARTING_CID+CNIC_ISCSI_CXT_MAX) */ +#define TM_CONN_NUM 1024 +#define TM_ILT_SZ (8 * TM_CONN_NUM) +#define TM_ILT_LINES DIV_ROUND_UP(TM_ILT_SZ, TM_ILT_PAGE_SZ) + +/* SRC (Searcher) host DB constants */ +#define SRC_ILT_PAGE_SZ_HW 3 +#define SRC_ILT_PAGE_SZ (4096 << SRC_ILT_PAGE_SZ_HW) /* 32K */ +#define SRC_HASH_BITS 10 +#define SRC_CONN_NUM (1 << SRC_HASH_BITS) /* 1024 */ +#define SRC_ILT_SZ (sizeof(struct src_ent) * SRC_CONN_NUM) +#define SRC_T2_SZ SRC_ILT_SZ +#define SRC_ILT_LINES DIV_ROUND_UP(SRC_ILT_SZ, SRC_ILT_PAGE_SZ) +#endif + #define MAX_DMAE_C 8 /* DMA memory not used in fastpath */ struct bnx2x_slowpath { - union cdu_context context[MAX_CONTEXT]; struct eth_stats_query fw_stats; struct mac_configuration_cmd mac_config; struct mac_configuration_cmd mcast_config; + struct client_init_ramrod_data client_init_data; /* used by dmae command executer */ struct dmae_command dmae[MAX_DMAE_C]; @@ -634,52 +781,83 @@ struct bnx2x_slowpath { #define MAX_DYNAMIC_ATTN_GRPS 8 struct attn_route { - u32 sig[4]; + u32 sig[5]; +}; + +struct iro { + u32 base; + u16 m1; + u16 m2; + u16 m3; + u16 size; }; +struct hw_context { + union cdu_context *vcxt; + dma_addr_t cxt_mapping; + size_t size; +}; + +/* forward */ +struct bnx2x_ilt; + typedef enum { BNX2X_RECOVERY_DONE, BNX2X_RECOVERY_INIT, BNX2X_RECOVERY_WAIT, } bnx2x_recovery_state_t; +/** + * Event queue (EQ or event ring) MC hsi + * NUM_EQ_PAGES and EQ_DESC_CNT_PAGE must be power of 2 + */ +#define NUM_EQ_PAGES 1 +#define EQ_DESC_CNT_PAGE (BCM_PAGE_SIZE / sizeof(union event_ring_elem)) +#define EQ_DESC_MAX_PAGE (EQ_DESC_CNT_PAGE - 1) +#define NUM_EQ_DESC (EQ_DESC_CNT_PAGE * NUM_EQ_PAGES) +#define EQ_DESC_MASK (NUM_EQ_DESC - 1) +#define MAX_EQ_AVAIL (EQ_DESC_MAX_PAGE * NUM_EQ_PAGES - 2) + +/* depends on EQ_DESC_CNT_PAGE being a power of 2 */ +#define NEXT_EQ_IDX(x) ((((x) & EQ_DESC_MAX_PAGE) == \ + (EQ_DESC_MAX_PAGE - 1)) ? (x) + 2 : (x) + 1) + +/* depends on the above and on NUM_EQ_PAGES being a power of 2 */ +#define EQ_DESC(x) ((x) & EQ_DESC_MASK) + +#define BNX2X_EQ_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_EQ_CONS]) + struct bnx2x { /* Fields used in the tx and intr/napi performance paths * are grouped together in the beginning of the structure */ - struct bnx2x_fastpath fp[MAX_CONTEXT]; + struct bnx2x_fastpath *fp; void __iomem *regview; void __iomem *doorbells; -#ifdef BCM_CNIC -#define BNX2X_DB_SIZE (18*BCM_PAGE_SIZE) -#else -#define BNX2X_DB_SIZE (16*BCM_PAGE_SIZE) -#endif + u16 db_size; struct net_device *dev; struct pci_dev *pdev; + struct iro *iro_arr; +#define IRO (bp->iro_arr) + atomic_t intr_sem; bnx2x_recovery_state_t recovery_state; int is_leader; -#ifdef BCM_CNIC - struct msix_entry msix_table[MAX_CONTEXT+2]; -#else - struct msix_entry msix_table[MAX_CONTEXT+1]; -#endif + struct msix_entry *msix_table; #define INT_MODE_INTx 1 #define INT_MODE_MSI 2 int tx_ring_size; -#ifdef BCM_VLAN - struct vlan_group *vlgrp; -#endif - u32 rx_csum; u32 rx_buf_size; -#define ETH_OVREHEAD (ETH_HLEN + 8) /* 8 for CRC + VLAN */ +/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */ +#define ETH_OVREHEAD (ETH_HLEN + 8 + 8) #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 @@ -688,13 +866,12 @@ struct bnx2x { #define BNX2X_RX_ALIGN_SHIFT ((L1_CACHE_SHIFT < 8) ? \ L1_CACHE_SHIFT : 8) #define BNX2X_RX_ALIGN (1 << BNX2X_RX_ALIGN_SHIFT) +#define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) - struct host_def_status_block *def_status_blk; -#define DEF_SB_ID 16 - __le16 def_c_idx; - __le16 def_u_idx; - __le16 def_x_idx; - __le16 def_t_idx; + struct host_sp_status_block *def_status_blk; +#define DEF_SB_IGU_ID 16 +#define DEF_SB_ID HC_SP_SB_ID + __le16 def_idx; __le16 def_att_idx; u32 attn_state; struct attn_route attn_group[MAX_DYNAMIC_ATTN_GRPS]; @@ -706,10 +883,17 @@ struct bnx2x { struct eth_spe *spq_prod_bd; struct eth_spe *spq_last_bd; __le16 *dsb_sp_prod; - u16 spq_left; /* serialize spq */ + atomic_t spq_left; /* serialize spq */ /* used to synchronize spq accesses */ spinlock_t spq_lock; + /* event queue */ + union event_ring_elem *eq_ring; + dma_addr_t eq_mapping; + u16 eq_prod; + u16 eq_cons; + __le16 *eq_cons_sb; + /* Flags for marking that there is a STAT_QUERY or SET_MAC ramrod pending */ int stats_pending; @@ -728,18 +912,27 @@ struct bnx2x { #define USING_DAC_FLAG 0x10 #define USING_MSIX_FLAG 0x20 #define USING_MSI_FLAG 0x40 + #define TPA_ENABLE_FLAG 0x80 #define NO_MCP_FLAG 0x100 +#define DISABLE_MSI_FLAG 0x200 #define BP_NOMCP(bp) (bp->flags & NO_MCP_FLAG) -#define HW_VLAN_TX_FLAG 0x400 -#define HW_VLAN_RX_FLAG 0x800 #define MF_FUNC_DIS 0x1000 - int func; -#define BP_PORT(bp) (bp->func % PORT_MAX) -#define BP_FUNC(bp) (bp->func) -#define BP_E1HVN(bp) (bp->func >> 1) + int pf_num; /* absolute PF number */ + int pfid; /* per-path PF number */ + int base_fw_ndsb; +#define BP_PATH(bp) (!CHIP_IS_E2(bp) ? \ + 0 : (bp->pf_num & 1)) +#define BP_PORT(bp) (bp->pfid & 1) +#define BP_FUNC(bp) (bp->pfid) +#define BP_ABS_FUNC(bp) (bp->pf_num) +#define BP_E1HVN(bp) (bp->pfid >> 1) +#define BP_VN(bp) (CHIP_MODE_IS_4_PORT(bp) ? \ + 0 : BP_E1HVN(bp)) #define BP_L_ID(bp) (BP_E1HVN(bp) << 2) +#define BP_FW_MB_IDX(bp) (BP_PORT(bp) +\ + BP_VN(bp) * (CHIP_IS_E1x(bp) ? 2 : 1)) #ifdef BCM_CNIC #define BCM_CNIC_CID_START 16 @@ -769,10 +962,11 @@ struct bnx2x { struct cmng_struct_per_port cmng; u32 vn_weight_sum; - u32 mf_config; - u16 e1hov; - u8 e1hmf; -#define IS_E1HMF(bp) (bp->e1hmf != 0) + u32 mf_config[E1HVN_MAX]; + u32 mf2_config[E2_FUNC_MAX]; + u16 mf_ov; + u8 mf_mode; +#define IS_MF(bp) (bp->mf_mode != 0) u8 wol; @@ -800,6 +994,7 @@ struct bnx2x { #define BNX2X_STATE_CLOSING_WAIT4_HALT 0x4000 #define BNX2X_STATE_CLOSING_WAIT4_DELETE 0x5000 #define BNX2X_STATE_CLOSING_WAIT4_UNLOAD 0x6000 +#define BNX2X_STATE_FUNC_STARTED 0x7000 #define BNX2X_STATE_DIAG 0xe000 #define BNX2X_STATE_ERROR 0xf000 @@ -808,6 +1003,15 @@ struct bnx2x { int disable_tpa; int int_mode; + struct tstorm_eth_mac_filter_config mac_filters; +#define BNX2X_ACCEPT_NONE 0x0000 +#define BNX2X_ACCEPT_UNICAST 0x0001 +#define BNX2X_ACCEPT_MULTICAST 0x0002 +#define BNX2X_ACCEPT_ALL_UNICAST 0x0004 +#define BNX2X_ACCEPT_ALL_MULTICAST 0x0008 +#define BNX2X_ACCEPT_BROADCAST 0x0010 +#define BNX2X_PROMISCUOUS_MODE 0x10000 + u32 rx_mode; #define BNX2X_RX_MODE_NONE 0 #define BNX2X_RX_MODE_NORMAL 1 @@ -816,34 +1020,41 @@ struct bnx2x { #define BNX2X_MAX_MULTICAST 64 #define BNX2X_MAX_EMUL_MULTI 16 - u32 rx_mode_cl_mask; - + u8 igu_dsb_id; + u8 igu_base_sb; + u8 igu_sb_cnt; dma_addr_t def_status_blk_mapping; struct bnx2x_slowpath *slowpath; dma_addr_t slowpath_mapping; + struct hw_context context; + + struct bnx2x_ilt *ilt; +#define BP_ILT(bp) ((bp)->ilt) +#define ILT_MAX_LINES 128 + + int l2_cid_count; +#define L2_ILT_LINES(bp) (DIV_ROUND_UP((bp)->l2_cid_count, \ + ILT_PAGE_CIDS)) +#define BNX2X_DB_SIZE(bp) ((bp)->l2_cid_count * (1 << BNX2X_DB_SHIFT)) + + int qm_cid_count; int dropless_fc; #ifdef BCM_CNIC u32 cnic_flags; #define BNX2X_CNIC_FLAG_MAC_SET 1 - - void *t1; - dma_addr_t t1_mapping; void *t2; dma_addr_t t2_mapping; - void *timers; - dma_addr_t timers_mapping; - void *qm; - dma_addr_t qm_mapping; struct cnic_ops *cnic_ops; void *cnic_data; u32 cnic_tag; struct cnic_eth_dev cnic_eth_dev; - struct host_status_block *cnic_sb; + union host_hc_status_block cnic_sb; dma_addr_t cnic_sb_mapping; -#define CNIC_SB_ID(bp) BP_L_ID(bp) +#define CNIC_SB_ID(bp) ((bp)->base_fw_ndsb + BP_L_ID(bp)) +#define CNIC_IGU_SB_ID(bp) ((bp)->igu_base_sb) struct eth_spe *cnic_kwq; struct eth_spe *cnic_kwq_prod; struct eth_spe *cnic_kwq_cons; @@ -913,32 +1124,196 @@ struct bnx2x { const struct firmware *firmware; }; +/** + * Init queue/func interface + */ +/* queue init flags */ +#define QUEUE_FLG_TPA 0x0001 +#define QUEUE_FLG_CACHE_ALIGN 0x0002 +#define QUEUE_FLG_STATS 0x0004 +#define QUEUE_FLG_OV 0x0008 +#define QUEUE_FLG_VLAN 0x0010 +#define QUEUE_FLG_COS 0x0020 +#define QUEUE_FLG_HC 0x0040 +#define QUEUE_FLG_DHC 0x0080 +#define QUEUE_FLG_OOO 0x0100 + +#define QUEUE_DROP_IP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR +#define QUEUE_DROP_TCP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR +#define QUEUE_DROP_TTL0 TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 +#define QUEUE_DROP_UDP_CS_ERR TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR + + + +/* rss capabilities */ +#define RSS_IPV4_CAP 0x0001 +#define RSS_IPV4_TCP_CAP 0x0002 +#define RSS_IPV6_CAP 0x0004 +#define RSS_IPV6_TCP_CAP 0x0008 -#define BNX2X_MAX_QUEUES(bp) (IS_E1HMF(bp) ? (MAX_CONTEXT/E1HVN_MAX) \ - : MAX_CONTEXT) #define BNX2X_NUM_QUEUES(bp) (bp->num_queues) #define is_multi(bp) (BNX2X_NUM_QUEUES(bp) > 1) +#define BNX2X_MAX_QUEUES(bp) (bp->igu_sb_cnt - CNIC_CONTEXT_USE) +#define is_eth_multi(bp) (BNX2X_NUM_ETH_QUEUES(bp) > 1) + +#define RSS_IPV4_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY + +#define RSS_IPV4_TCP_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_TCP_CAPABILITY + +#define RSS_IPV6_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_CAPABILITY + +#define RSS_IPV6_TCP_CAP_MASK \ + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY + +/* func init flags */ +#define FUNC_FLG_STATS 0x0001 +#define FUNC_FLG_TPA 0x0002 +#define FUNC_FLG_SPQ 0x0004 +#define FUNC_FLG_LEADING 0x0008 /* PF only */ + +struct rxq_pause_params { + u16 bd_th_lo; + u16 bd_th_hi; + u16 rcq_th_lo; + u16 rcq_th_hi; + u16 sge_th_lo; /* valid iff QUEUE_FLG_TPA */ + u16 sge_th_hi; /* valid iff QUEUE_FLG_TPA */ + u16 pri_map; +}; + +struct bnx2x_rxq_init_params { + /* cxt*/ + struct eth_context *cxt; + + /* dma */ + dma_addr_t dscr_map; + dma_addr_t sge_map; + dma_addr_t rcq_map; + dma_addr_t rcq_np_map; + + u16 flags; + u16 drop_flags; + u16 mtu; + u16 buf_sz; + u16 fw_sb_id; + u16 cl_id; + u16 spcl_id; + u16 cl_qzone_id; + + /* valid iff QUEUE_FLG_STATS */ + u16 stat_id; + + /* valid iff QUEUE_FLG_TPA */ + u16 tpa_agg_sz; + u16 sge_buf_sz; + u16 max_sges_pkt; + + /* valid iff QUEUE_FLG_CACHE_ALIGN */ + u8 cache_line_log; + + u8 sb_cq_index; + u32 cid; + + /* desired interrupts per sec. valid iff QUEUE_FLG_HC */ + u32 hc_rate; +}; + +struct bnx2x_txq_init_params { + /* cxt*/ + struct eth_context *cxt; + + /* dma */ + dma_addr_t dscr_map; + + u16 flags; + u16 fw_sb_id; + u8 sb_cq_index; + u8 cos; /* valid iff QUEUE_FLG_COS */ + u16 stat_id; /* valid iff QUEUE_FLG_STATS */ + u16 traffic_type; + u32 cid; + u16 hc_rate; /* desired interrupts per sec.*/ + /* valid iff QUEUE_FLG_HC */ + +}; + +struct bnx2x_client_ramrod_params { + int *pstate; + int state; + u16 index; + u16 cl_id; + u32 cid; + u8 poll; +#define CLIENT_IS_LEADING_RSS 0x02 + u8 flags; +}; + +struct bnx2x_client_init_params { + struct rxq_pause_params pause; + struct bnx2x_rxq_init_params rxq_params; + struct bnx2x_txq_init_params txq_params; + struct bnx2x_client_ramrod_params ramrod_params; +}; + +struct bnx2x_rss_params { + int mode; + u16 cap; + u16 result_mask; +}; + +struct bnx2x_func_init_params { + + /* rss */ + struct bnx2x_rss_params *rss; /* valid iff FUNC_FLG_RSS */ + + /* dma */ + dma_addr_t fw_stat_map; /* valid iff FUNC_FLG_STATS */ + dma_addr_t spq_map; /* valid iff FUNC_FLG_SPQ */ + + u16 func_flgs; + u16 func_id; /* abs fid */ + u16 pf_id; + u16 spq_prod; /* valid iff FUNC_FLG_SPQ */ +}; + #define for_each_queue(bp, var) \ for (var = 0; var < BNX2X_NUM_QUEUES(bp); var++) #define for_each_nondefault_queue(bp, var) \ for (var = 1; var < BNX2X_NUM_QUEUES(bp); var++) +#define WAIT_RAMROD_POLL 0x01 +#define WAIT_RAMROD_COMMON 0x02 +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags); + +/* dmae */ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, u32 len32); +void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, + u32 addr, u32 len); +void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); +u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type); +u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode); +u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, + bool with_comp, u8 comp_type); + int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); -u32 bnx2x_fw_command(struct bnx2x *bp, u32 command); +u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param); void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); -void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, - u32 addr, u32 len); + void bnx2x_calc_fc_adv(struct bnx2x *bp); int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, u32 data_hi, u32 data_lo, int common); void bnx2x_update_coalesce(struct bnx2x *bp); +int bnx2x_get_link_cfg_idx(struct bnx2x *bp); static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, int wait) @@ -957,6 +1332,40 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, return val; } +#define BNX2X_ILT_ZALLOC(x, y, size) \ + do { \ + x = pci_alloc_consistent(bp->pdev, size, y); \ + if (x) \ + memset(x, 0, size); \ + } while (0) + +#define BNX2X_ILT_FREE(x, y, size) \ + do { \ + if (x) { \ + pci_free_consistent(bp->pdev, size, x, y); \ + x = NULL; \ + y = 0; \ + } \ + } while (0) + +#define ILOG2(x) (ilog2((x))) + +#define ILT_NUM_PAGE_ENTRIES (3072) +/* In 57710/11 we use whole table since we have 8 func + * In 57712 we have only 4 func, but use same size per func, then only half of + * the table in use + */ +#define ILT_PER_FUNC (ILT_NUM_PAGE_ENTRIES/8) + +#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) +/* + * the phys address is shifted right 12 bits and has an added + * 1=valid bit added to the 53rd bit + * then since this is a wide register(TM) + * we split it into two 32 bit writes + */ +#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) +#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) /* load/unload mode */ #define LOAD_NORMAL 0 @@ -964,18 +1373,44 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define LOAD_DIAG 2 #define UNLOAD_NORMAL 0 #define UNLOAD_CLOSE 1 -#define UNLOAD_RECOVERY 2 +#define UNLOAD_RECOVERY 2 /* DMAE command defines */ -#define DMAE_CMD_SRC_PCI 0 -#define DMAE_CMD_SRC_GRC DMAE_COMMAND_SRC +#define DMAE_TIMEOUT -1 +#define DMAE_PCI_ERROR -2 /* E2 and onward */ +#define DMAE_NOT_RDY -3 +#define DMAE_PCI_ERR_FLAG 0x80000000 + +#define DMAE_SRC_PCI 0 +#define DMAE_SRC_GRC 1 + +#define DMAE_DST_NONE 0 +#define DMAE_DST_PCI 1 +#define DMAE_DST_GRC 2 + +#define DMAE_COMP_PCI 0 +#define DMAE_COMP_GRC 1 + +/* E2 and onward - PCI error handling in the completion */ -#define DMAE_CMD_DST_PCI (1 << DMAE_COMMAND_DST_SHIFT) -#define DMAE_CMD_DST_GRC (2 << DMAE_COMMAND_DST_SHIFT) +#define DMAE_COMP_REGULAR 0 +#define DMAE_COM_SET_ERR 1 -#define DMAE_CMD_C_DST_PCI 0 -#define DMAE_CMD_C_DST_GRC (1 << DMAE_COMMAND_C_DST_SHIFT) +#define DMAE_CMD_SRC_PCI (DMAE_SRC_PCI << \ + DMAE_COMMAND_SRC_SHIFT) +#define DMAE_CMD_SRC_GRC (DMAE_SRC_GRC << \ + DMAE_COMMAND_SRC_SHIFT) + +#define DMAE_CMD_DST_PCI (DMAE_DST_PCI << \ + DMAE_COMMAND_DST_SHIFT) +#define DMAE_CMD_DST_GRC (DMAE_DST_GRC << \ + DMAE_COMMAND_DST_SHIFT) + +#define DMAE_CMD_C_DST_PCI (DMAE_COMP_PCI << \ + DMAE_COMMAND_C_DST_SHIFT) +#define DMAE_CMD_C_DST_GRC (DMAE_COMP_GRC << \ + DMAE_COMMAND_C_DST_SHIFT) #define DMAE_CMD_C_ENABLE DMAE_COMMAND_C_TYPE_ENABLE @@ -991,10 +1426,20 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define DMAE_CMD_DST_RESET DMAE_COMMAND_DST_RESET #define DMAE_CMD_E1HVN_SHIFT DMAE_COMMAND_E1HVN_SHIFT +#define DMAE_SRC_PF 0 +#define DMAE_SRC_VF 1 + +#define DMAE_DST_PF 0 +#define DMAE_DST_VF 1 + +#define DMAE_C_SRC 0 +#define DMAE_C_DST 1 + #define DMAE_LEN32_RD_MAX 0x80 #define DMAE_LEN32_WR_MAX(bp) (CHIP_IS_E1(bp) ? 0x400 : 0x2000) -#define DMAE_COMP_VAL 0xe0d0d0ae +#define DMAE_COMP_VAL 0x60d0d0ae /* E2 and on - upper bit + indicates eror */ #define MAX_DMAE_C_PER_PORT 8 #define INIT_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ @@ -1002,7 +1447,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ E1HVN_MAX) - /* PCIE link and speed */ #define PCICFG_LINK_WIDTH 0x1f00000 #define PCICFG_LINK_WIDTH_SHIFT 20 @@ -1031,7 +1475,7 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define MAX_SP_DESC_CNT (SP_DESC_CNT - 1) -#define BNX2X_BTR 1 +#define BNX2X_BTR 4 #define MAX_SPQ_PENDING 8 @@ -1148,20 +1592,26 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT)) #define MULTI_MASK 0x7f +#define BNX2X_SP_DSB_INDEX \ + (&bp->def_status_blk->sp_sb.\ + index_values[HC_SP_INDEX_ETH_DEF_CONS]) -#define DEF_USB_FUNC_OFF (2 + 2*HC_USTORM_DEF_SB_NUM_INDICES) -#define DEF_CSB_FUNC_OFF (2 + 2*HC_CSTORM_DEF_SB_NUM_INDICES) -#define DEF_XSB_FUNC_OFF (2 + 2*HC_XSTORM_DEF_SB_NUM_INDICES) -#define DEF_TSB_FUNC_OFF (2 + 2*HC_TSTORM_DEF_SB_NUM_INDICES) +#define SET_FLAG(value, mask, flag) \ + do {\ + (value) &= ~(mask);\ + (value) |= ((flag) << (mask##_SHIFT));\ + } while (0) -#define C_DEF_SB_SP_INDEX HC_INDEX_DEF_C_ETH_SLOW_PATH - -#define BNX2X_SP_DSB_INDEX \ -(&bp->def_status_blk->c_def_status_block.index_values[C_DEF_SB_SP_INDEX]) +#define GET_FLAG(value, mask) \ + (((value) &= (mask)) >> (mask##_SHIFT)) +#define GET_FIELD(value, fname) \ + (((value) & (fname##_MASK)) >> (fname##_SHIFT)) #define CAM_IS_INVALID(x) \ -(x.target_table_entry.flags == TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) + (GET_FLAG(x.flags, \ + MAC_CONFIGURATION_ENTRY_ACTION_TYPE) == \ + (T_ETH_MAC_COMMAND_INVALIDATE)) #define CAM_INVALIDATE(x) \ (x.target_table_entry.flags = TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE) @@ -1177,21 +1627,29 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, #define PXP2_REG_PXP2_INT_STS PXP2_REG_PXP2_INT_STS_0 #endif +#ifndef ETH_MAX_RX_CLIENTS_E2 +#define ETH_MAX_RX_CLIENTS_E2 ETH_MAX_RX_CLIENTS_E1H +#endif + #define BNX2X_VPD_LEN 128 #define VENDOR_ID_LEN 4 +/* Congestion management fairness mode */ +#define CMNG_FNS_NONE 0 +#define CMNG_FNS_MINMAX 1 + +#define HC_SEG_ACCESS_DEF 0 /*Driver decision 0-3*/ +#define HC_SEG_ACCESS_ATTN 4 +#define HC_SEG_ACCESS_NORM 0 /*Driver decision 0-1*/ + #ifdef BNX2X_MAIN #define BNX2X_EXTERN #else #define BNX2X_EXTERN extern #endif -BNX2X_EXTERN int load_count[3]; /* 0-common, 1-port0, 2-port1 */ - -/* MISC_REG_RESET_REG - this is here for the hsi to work don't touch */ +BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */ extern void bnx2x_set_ethtool_ops(struct net_device *netdev); -void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx); - #endif /* bnx2x.h */ diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 02bf710629a3eec2b4b05f17943c1565b3912144..bc5837514074d410fb740d57dbe90350376dc11b 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c @@ -15,18 +15,16 @@ * */ - #include +#include #include -#include +#include #include +#include #include "bnx2x_cmn.h" -#ifdef BCM_VLAN -#include -#endif +#include "bnx2x_init.h" -static int bnx2x_poll(struct napi_struct *napi, int budget); /* free skb in the packet ring at pos idx * return idx of last bd freed @@ -51,7 +49,7 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fastpath *fp, DP(BNX2X_MSG_OFF, "free bd_idx %d\n", bd_idx); tx_start_bd = &fp->tx_desc_ring[bd_idx].start_bd; dma_unmap_single(&bp->pdev->dev, BD_UNMAP_ADDR(tx_start_bd), - BD_UNMAP_LEN(tx_start_bd), PCI_DMA_TODEVICE); + BD_UNMAP_LEN(tx_start_bd), DMA_TO_DEVICE); nbd = le16_to_cpu(tx_start_bd->nbd) - 1; #ifdef BNX2X_STOP_ON_ERROR @@ -115,16 +113,10 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) pkt_cons = TX_BD(sw_cons); - /* prefetch(bp->tx_buf_ring[pkt_cons].skb); */ - - DP(NETIF_MSG_TX_DONE, "hw_cons %u sw_cons %u pkt_cons %u\n", - hw_cons, sw_cons, pkt_cons); + DP(NETIF_MSG_TX_DONE, "queue[%d]: hw_cons %u sw_cons %u " + " pkt_cons %u\n", + fp->index, hw_cons, sw_cons, pkt_cons); -/* if (NEXT_TX_IDX(sw_cons) != hw_cons) { - rmb(); - prefetch(fp->tx_buf_ring[NEXT_TX_IDX(sw_cons)].skb); - } -*/ bd_cons = bnx2x_free_tx_pkt(bp, fp, pkt_cons); sw_cons++; } @@ -140,7 +132,6 @@ int bnx2x_tx_int(struct bnx2x_fastpath *fp) */ smp_mb(); - /* TBD need a thresh? */ if (unlikely(netif_tx_queue_stopped(txq))) { /* Taking tx_lock() is needed to prevent reenabling the queue * while it's empty. This could have happen if rx_action() gets @@ -189,14 +180,16 @@ static void bnx2x_update_sge_prod(struct bnx2x_fastpath *fp, /* First mark all used pages */ for (i = 0; i < sge_len; i++) - SGE_MASK_CLEAR_BIT(fp, RX_SGE(le16_to_cpu(fp_cqe->sgl[i]))); + SGE_MASK_CLEAR_BIT(fp, + RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[i]))); DP(NETIF_MSG_RX_STATUS, "fp_cqe->sgl[%d] = %d\n", - sge_len - 1, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + sge_len - 1, le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); /* Here we assume that the last SGE index is the biggest */ prefetch((void *)(fp->sge_mask)); - bnx2x_update_last_max_sge(fp, le16_to_cpu(fp_cqe->sgl[sge_len - 1])); + bnx2x_update_last_max_sge(fp, + le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[sge_len - 1])); last_max = RX_SGE(fp->last_max_sge); last_elem = last_max >> RX_SGE_MASK_ELEM_SHIFT; @@ -297,7 +290,8 @@ static int bnx2x_fill_frag_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, /* Run through the SGL and compose the fragmented skb */ for (i = 0, j = 0; i < pages; i += PAGES_PER_SGE, j++) { - u16 sge_idx = RX_SGE(le16_to_cpu(fp_cqe->sgl[j])); + u16 sge_idx = + RX_SGE(le16_to_cpu(fp_cqe->sgl_or_raw_data.sgl[j])); /* FW gives the indices of the SGE as if the ring is an array (meaning that "next" element will consume 2 indices) */ @@ -349,16 +343,9 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, if (likely(new_skb)) { /* fix ip xsum and give it to the stack */ /* (no need to map the new skb) */ -#ifdef BCM_VLAN - int is_vlan_cqe = - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN); - int is_not_hwaccel_vlan_cqe = - (is_vlan_cqe && (!(bp->flags & HW_VLAN_RX_FLAG))); -#endif prefetch(skb); - prefetch(((char *)(skb)) + 128); + prefetch(((char *)(skb)) + L1_CACHE_BYTES); #ifdef BNX2X_STOP_ON_ERROR if (pad + len > bp->rx_buf_size) { @@ -380,27 +367,18 @@ static void bnx2x_tpa_stop(struct bnx2x *bp, struct bnx2x_fastpath *fp, struct iphdr *iph; iph = (struct iphdr *)skb->data; -#ifdef BCM_VLAN - /* If there is no Rx VLAN offloading - - take VLAN tag into an account */ - if (unlikely(is_not_hwaccel_vlan_cqe)) - iph = (struct iphdr *)((u8 *)iph + VLAN_HLEN); -#endif iph->check = 0; iph->check = ip_fast_csum((u8 *)iph, iph->ihl); } if (!bnx2x_fill_frag_skb(bp, fp, skb, &cqe->fast_path_cqe, cqe_idx)) { -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && is_vlan_cqe && - (!is_not_hwaccel_vlan_cqe)) - vlan_gro_receive(&fp->napi, bp->vlgrp, + if ((le16_to_cpu(cqe->fast_path_cqe. + pars_flags.flags) & PARSING_FLAGS_VLAN)) + __vlan_hwaccel_put_tag(skb, le16_to_cpu(cqe->fast_path_cqe. - vlan_tag), skb); - else -#endif - napi_gro_receive(&fp->napi, skb); + vlan_tag)); + napi_gro_receive(&fp->napi, skb); } else { DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages" " - dropping packet!\n"); @@ -509,8 +487,11 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) len = le16_to_cpu(cqe->fast_path_cqe.pkt_len); pad = cqe->fast_path_cqe.placement_offset; - /* If CQE is marked both TPA_START and TPA_END - it is a non-TPA CQE */ + /* - If CQE is marked both TPA_START and TPA_END it is + * a non-TPA CQE. + * - FP CQE will always have either TPA_START or/and + * TPA_STOP flags set. + */ if ((!fp->disable_tpa) && (TPA_TYPE(cqe_fp_flags) != (TPA_TYPE_START | TPA_TYPE_END))) { @@ -528,9 +509,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) bnx2x_set_skb_rxhash(bp, cqe, skb); goto next_rx; - } - - if (TPA_TYPE(cqe_fp_flags) == TPA_TYPE_END) { + } else { /* TPA_STOP */ DP(NETIF_MSG_RX_STATUS, "calling tpa_stop on queue %d\n", queue); @@ -560,7 +539,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) dma_unmap_addr(rx_buf, mapping), pad + RX_COPY_THRESH, DMA_FROM_DEVICE); - prefetch(((char *)(skb)) + 128); + prefetch(((char *)(skb)) + L1_CACHE_BYTES); /* is this an error packet? */ if (unlikely(cqe_fp_flags & ETH_RX_ERROR_FALGS)) { @@ -594,7 +573,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) skb_reserve(new_skb, pad); skb_put(new_skb, len); - bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); skb = new_skb; @@ -613,7 +592,7 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) "of alloc failure\n"); fp->eth_q_stats.rx_skb_alloc_failed++; reuse_rx: - bnx2x_reuse_rx_skb(fp, skb, bd_cons, bd_prod); + bnx2x_reuse_rx_skb(fp, bd_cons, bd_prod); goto next_rx; } @@ -622,7 +601,8 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) /* Set Toeplitz hash for a none-LRO skb */ bnx2x_set_skb_rxhash(bp, cqe, skb); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); + if (bp->rx_csum) { if (likely(BNX2X_RX_CSUM_OK(cqe))) skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -633,15 +613,11 @@ int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget) skb_record_rx_queue(skb, fp->index); -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && (bp->flags & HW_VLAN_RX_FLAG) && - (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & - PARSING_FLAGS_VLAN)) - vlan_gro_receive(&fp->napi, bp->vlgrp, - le16_to_cpu(cqe->fast_path_cqe.vlan_tag), skb); - else -#endif - napi_gro_receive(&fp->napi, skb); + if (le16_to_cpu(cqe->fast_path_cqe.pars_flags.flags) & + PARSING_FLAGS_VLAN) + __vlan_hwaccel_put_tag(skb, + le16_to_cpu(cqe->fast_path_cqe.vlan_tag)); + napi_gro_receive(&fp->napi, skb); next_rx: @@ -685,9 +661,10 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) return IRQ_HANDLED; } - DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB [%d:%d]\n", - fp->index, fp->sb_id); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); + DP(BNX2X_MSG_FP, "got an MSI-X interrupt on IDX:SB " + "[fp %d fw_sd %d igusb %d]\n", + fp->index, fp->fw_sb_id, fp->igu_sb_id); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -697,14 +674,12 @@ static irqreturn_t bnx2x_msix_fp_int(int irq, void *fp_cookie) /* Handle Rx and Tx according to MSI-X vector */ prefetch(fp->rx_cons_sb); prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->u_status_block.status_block_index); - prefetch(&fp->status_blk->c_status_block.status_block_index); + prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); return IRQ_HANDLED; } - /* HW Lock for shared dual port PHYs */ void bnx2x_acquire_phy_lock(struct bnx2x *bp) { @@ -738,12 +713,13 @@ void bnx2x_link_report(struct bnx2x *bp) netdev_info(bp->dev, "NIC Link is Up, "); line_speed = bp->link_vars.line_speed; - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { u16 vn_max_rate; vn_max_rate = - ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; + ((bp->mf_config[BP_VN(bp)] & + FUNC_MF_CFG_MAX_BW_MASK) >> + FUNC_MF_CFG_MAX_BW_SHIFT) * 100; if (vn_max_rate < line_speed) line_speed = vn_max_rate; } @@ -773,23 +749,73 @@ void bnx2x_link_report(struct bnx2x *bp) } } +/* Returns the number of actually allocated BDs */ +static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, + int rx_ring_size) +{ + struct bnx2x *bp = fp->bp; + u16 ring_prod, cqe_ring_prod; + int i; + + fp->rx_comp_cons = 0; + cqe_ring_prod = ring_prod = 0; + for (i = 0; i < rx_ring_size; i++) { + if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx skbs on queue[%d]\n", i, fp->index); + fp->eth_q_stats.rx_skb_alloc_failed++; + break; + } + ring_prod = NEXT_RX_IDX(ring_prod); + cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); + WARN_ON(ring_prod <= i); + } + + fp->rx_bd_prod = ring_prod; + /* Limit the CQE producer by the CQE ring size */ + fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, + cqe_ring_prod); + fp->rx_pkt = fp->rx_calls = 0; + + return i; +} + +static inline void bnx2x_alloc_rx_bd_ring(struct bnx2x_fastpath *fp) +{ + struct bnx2x *bp = fp->bp; + int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size : + MAX_RX_AVAIL/bp->num_queues; + + rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size); + + bnx2x_alloc_rx_bds(fp, rx_ring_size); + + /* Warning! + * this will generate an interrupt (to the TSTORM) + * must only be done after chip is initialized + */ + bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod, + fp->rx_sge_prod); +} + void bnx2x_init_rx_rings(struct bnx2x *bp) { int func = BP_FUNC(bp); int max_agg_queues = CHIP_IS_E1(bp) ? ETH_MAX_AGGREGATION_QUEUES_E1 : ETH_MAX_AGGREGATION_QUEUES_E1H; - u16 ring_prod, cqe_ring_prod; + u16 ring_prod; int i, j; - bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN; + bp->rx_buf_size = bp->dev->mtu + ETH_OVREHEAD + BNX2X_RX_ALIGN + + IP_HEADER_ALIGNMENT_PADDING; + DP(NETIF_MSG_IFUP, "mtu %d rx_buf_size %d\n", bp->dev->mtu, bp->rx_buf_size); - if (bp->flags & TPA_ENABLE_FLAG) { - - for_each_queue(bp, j) { - struct bnx2x_fastpath *fp = &bp->fp[j]; + for_each_queue(bp, j) { + struct bnx2x_fastpath *fp = &bp->fp[j]; + if (!fp->disable_tpa) { for (i = 0; i < max_agg_queues; i++) { fp->tpa_pool[i].skb = netdev_alloc_skb(bp->dev, bp->rx_buf_size); @@ -807,6 +833,35 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) mapping, 0); fp->tpa_state[i] = BNX2X_TPA_STOP; } + + /* "next page" elements initialization */ + bnx2x_set_next_page_sgl(fp); + + /* set SGEs bit mask */ + bnx2x_init_sge_ring_bit_mask(fp); + + /* Allocate SGEs and initialize the ring elements */ + for (i = 0, ring_prod = 0; + i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) { + + if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { + BNX2X_ERR("was only able to allocate " + "%d rx sges\n", i); + BNX2X_ERR("disabling TPA for" + " queue[%d]\n", j); + /* Cleanup already allocated elements */ + bnx2x_free_rx_sge_range(bp, + fp, ring_prod); + bnx2x_free_tpa_pool(bp, + fp, max_agg_queues); + fp->disable_tpa = 1; + ring_prod = 0; + break; + } + ring_prod = NEXT_SGE_IDX(ring_prod); + } + + fp->rx_sge_prod = ring_prod; } } @@ -814,109 +869,29 @@ void bnx2x_init_rx_rings(struct bnx2x *bp) struct bnx2x_fastpath *fp = &bp->fp[j]; fp->rx_bd_cons = 0; - fp->rx_cons_sb = BNX2X_RX_SB_INDEX; - fp->rx_bd_cons_sb = BNX2X_RX_SB_BD_INDEX; - - /* "next page" elements initialization */ - /* SGE ring */ - for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { - struct eth_rx_sge *sge; - - sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2]; - sge->addr_hi = - cpu_to_le32(U64_HI(fp->rx_sge_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); - sge->addr_lo = - cpu_to_le32(U64_LO(fp->rx_sge_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); - } - - bnx2x_init_sge_ring_bit_mask(fp); - /* RX BD ring */ - for (i = 1; i <= NUM_RX_RINGS; i++) { - struct eth_rx_bd *rx_bd; - - rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; - rx_bd->addr_hi = - cpu_to_le32(U64_HI(fp->rx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); - rx_bd->addr_lo = - cpu_to_le32(U64_LO(fp->rx_desc_mapping + - BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); - } + bnx2x_set_next_page_rx_bd(fp); /* CQ ring */ - for (i = 1; i <= NUM_RCQ_RINGS; i++) { - struct eth_rx_cqe_next_page *nextpg; - - nextpg = (struct eth_rx_cqe_next_page *) - &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1]; - nextpg->addr_hi = - cpu_to_le32(U64_HI(fp->rx_comp_mapping + - BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); - nextpg->addr_lo = - cpu_to_le32(U64_LO(fp->rx_comp_mapping + - BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); - } - - /* Allocate SGEs and initialize the ring elements */ - for (i = 0, ring_prod = 0; - i < MAX_RX_SGE_CNT*NUM_RX_SGE_PAGES; i++) { - - if (bnx2x_alloc_rx_sge(bp, fp, ring_prod) < 0) { - BNX2X_ERR("was only able to allocate " - "%d rx sges\n", i); - BNX2X_ERR("disabling TPA for queue[%d]\n", j); - /* Cleanup already allocated elements */ - bnx2x_free_rx_sge_range(bp, fp, ring_prod); - bnx2x_free_tpa_pool(bp, fp, max_agg_queues); - fp->disable_tpa = 1; - ring_prod = 0; - break; - } - ring_prod = NEXT_SGE_IDX(ring_prod); - } - fp->rx_sge_prod = ring_prod; + bnx2x_set_next_page_rx_cq(fp); /* Allocate BDs and initialize BD ring */ - fp->rx_comp_cons = 0; - cqe_ring_prod = ring_prod = 0; - for (i = 0; i < bp->rx_ring_size; i++) { - if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) { - BNX2X_ERR("was only able to allocate " - "%d rx skbs on queue[%d]\n", i, j); - fp->eth_q_stats.rx_skb_alloc_failed++; - break; - } - ring_prod = NEXT_RX_IDX(ring_prod); - cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod); - WARN_ON(ring_prod <= i); - } + bnx2x_alloc_rx_bd_ring(fp); - fp->rx_bd_prod = ring_prod; - /* must not have more available CQEs than BDs */ - fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT, - cqe_ring_prod); - fp->rx_pkt = fp->rx_calls = 0; - - /* Warning! - * this will generate an interrupt (to the TSTORM) - * must only be done after chip is initialized - */ - bnx2x_update_rx_prod(bp, fp, ring_prod, fp->rx_comp_prod, - fp->rx_sge_prod); if (j != 0) continue; - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), - U64_LO(fp->rx_comp_mapping)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, - U64_HI(fp->rx_comp_mapping)); + if (!CHIP_IS_E2(bp)) { + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func), + U64_LO(fp->rx_comp_mapping)); + REG_WR(bp, BAR_USTRORM_INTMEM + + USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(func) + 4, + U64_HI(fp->rx_comp_mapping)); + } } } + static void bnx2x_free_tx_skbs(struct bnx2x *bp) { int i; @@ -989,55 +964,49 @@ static void bnx2x_free_msix_irqs(struct bnx2x *bp) } } -void bnx2x_free_irq(struct bnx2x *bp, bool disable_only) +void bnx2x_free_irq(struct bnx2x *bp) { - if (bp->flags & USING_MSIX_FLAG) { - if (!disable_only) - bnx2x_free_msix_irqs(bp); - pci_disable_msix(bp->pdev); - bp->flags &= ~USING_MSIX_FLAG; - - } else if (bp->flags & USING_MSI_FLAG) { - if (!disable_only) - free_irq(bp->pdev->irq, bp->dev); - pci_disable_msi(bp->pdev); - bp->flags &= ~USING_MSI_FLAG; - - } else if (!disable_only) + if (bp->flags & USING_MSIX_FLAG) + bnx2x_free_msix_irqs(bp); + else if (bp->flags & USING_MSI_FLAG) + free_irq(bp->pdev->irq, bp->dev); + else free_irq(bp->pdev->irq, bp->dev); } -static int bnx2x_enable_msix(struct bnx2x *bp) +int bnx2x_enable_msix(struct bnx2x *bp) { - int i, rc, offset = 1; - int igu_vec = 0; + int msix_vec = 0, i, rc, req_cnt; - bp->msix_table[0].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", igu_vec); + bp->msix_table[msix_vec].entry = msix_vec; + DP(NETIF_MSG_IFUP, "msix_table[0].entry = %d (slowpath)\n", + bp->msix_table[0].entry); + msix_vec++; #ifdef BCM_CNIC - igu_vec = BP_L_ID(bp) + offset; - bp->msix_table[1].entry = igu_vec; - DP(NETIF_MSG_IFUP, "msix_table[1].entry = %d (CNIC)\n", igu_vec); - offset++; + bp->msix_table[msix_vec].entry = msix_vec; + DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d (CNIC)\n", + bp->msix_table[msix_vec].entry, bp->msix_table[msix_vec].entry); + msix_vec++; #endif for_each_queue(bp, i) { - igu_vec = BP_L_ID(bp) + offset + i; - bp->msix_table[i + offset].entry = igu_vec; + bp->msix_table[msix_vec].entry = msix_vec; DP(NETIF_MSG_IFUP, "msix_table[%d].entry = %d " - "(fastpath #%u)\n", i + offset, igu_vec, i); + "(fastpath #%u)\n", msix_vec, msix_vec, i); + msix_vec++; } - rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], - BNX2X_NUM_QUEUES(bp) + offset); + req_cnt = BNX2X_NUM_QUEUES(bp) + CNIC_CONTEXT_USE + 1; + + rc = pci_enable_msix(bp->pdev, &bp->msix_table[0], req_cnt); /* * reconfigure number of tx/rx queues according to available * MSI-X vectors */ if (rc >= BNX2X_MIN_MSIX_VEC_CNT) { - /* vectors available for FP */ - int fp_vec = rc - BNX2X_MSIX_VEC_FP_START; + /* how less vectors we will have? */ + int diff = req_cnt - rc; DP(NETIF_MSG_IFUP, "Trying to use less MSI-X vectors: %d\n", rc); @@ -1049,12 +1018,17 @@ static int bnx2x_enable_msix(struct bnx2x *bp) "MSI-X is not attainable rc %d\n", rc); return rc; } - - bp->num_queues = min(bp->num_queues, fp_vec); + /* + * decrease number of queues by number of unallocated entries + */ + bp->num_queues -= diff; DP(NETIF_MSG_IFUP, "New queue configuration set: %d\n", bp->num_queues); } else if (rc) { + /* fall to INTx if not enough memory */ + if (rc == -ENOMEM) + bp->flags |= DISABLE_MSI_FLAG; DP(NETIF_MSG_IFUP, "MSI-X is not attainable rc %d\n", rc); return rc; } @@ -1083,7 +1057,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) snprintf(fp->name, sizeof(fp->name), "%s-fp-%d", bp->dev->name, i); - rc = request_irq(bp->msix_table[i + offset].vector, + rc = request_irq(bp->msix_table[offset].vector, bnx2x_msix_fp_int, 0, fp->name, fp); if (rc) { BNX2X_ERR("request fp #%d irq failed rc %d\n", i, rc); @@ -1091,10 +1065,12 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) return -EBUSY; } + offset++; fp->state = BNX2X_FP_STATE_IRQ; } i = BNX2X_NUM_QUEUES(bp); + offset = 1 + CNIC_CONTEXT_USE; netdev_info(bp->dev, "using MSI-X IRQs: sp %d fp[%d] %d" " ... fp[%d] %d\n", bp->msix_table[0].vector, @@ -1104,7 +1080,7 @@ static int bnx2x_req_msix_irqs(struct bnx2x *bp) return 0; } -static int bnx2x_enable_msi(struct bnx2x *bp) +int bnx2x_enable_msi(struct bnx2x *bp) { int rc; @@ -1175,35 +1151,29 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) bnx2x_napi_disable(bp); netif_tx_disable(bp->dev); } -static int bnx2x_set_num_queues(struct bnx2x *bp) -{ - int rc = 0; - switch (bp->int_mode) { - case INT_MODE_INTx: - case INT_MODE_MSI: +void bnx2x_set_num_queues(struct bnx2x *bp) +{ + switch (bp->multi_mode) { + case ETH_RSS_MODE_DISABLED: bp->num_queues = 1; - DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); break; - default: - /* Set number of queues according to bp->multi_mode value */ - bnx2x_set_num_queues_msix(bp); - - DP(NETIF_MSG_IFUP, "set number of queues to %d\n", - bp->num_queues); + case ETH_RSS_MODE_REGULAR: + bp->num_queues = bnx2x_calc_num_queues(bp); + break; - /* if we can't use MSI-X we only need one fp, - * so try to enable MSI-X with the requested number of fp's - * and fallback to MSI or legacy INTx with one fp - */ - rc = bnx2x_enable_msix(bp); - if (rc) - /* failed to enable MSI-X */ - bp->num_queues = 1; + default: + bp->num_queues = 1; break; } - bp->dev->real_num_tx_queues = bp->num_queues; - return rc; +} + +static void bnx2x_release_firmware(struct bnx2x *bp) +{ + kfree(bp->init_ops_offsets); + kfree(bp->init_ops); + kfree(bp->init_data); + release_firmware(bp->firmware); } /* must be called with rtnl_lock */ @@ -1212,6 +1182,13 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) u32 load_code; int i, rc; + /* Set init arrays */ + rc = bnx2x_init_firmware(bp); + if (rc) { + BNX2X_ERR("Error loading firmware\n"); + return rc; + } + #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) return -EPERM; @@ -1219,83 +1196,64 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD; - rc = bnx2x_set_num_queues(bp); + /* must be called before memory allocation and HW init */ + bnx2x_ilt_set_info(bp); - if (bnx2x_alloc_mem(bp)) { - bnx2x_free_irq(bp, true); + if (bnx2x_alloc_mem(bp)) return -ENOMEM; + + netif_set_real_num_tx_queues(bp->dev, bp->num_queues); + rc = netif_set_real_num_rx_queues(bp->dev, bp->num_queues); + if (rc) { + BNX2X_ERR("Unable to update real_num_rx_queues\n"); + goto load_error0; } for_each_queue(bp, i) bnx2x_fp(bp, i, disable_tpa) = ((bp->flags & TPA_ENABLE_FLAG) == 0); - for_each_queue(bp, i) - netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), - bnx2x_poll, 128); - bnx2x_napi_enable(bp); - if (bp->flags & USING_MSIX_FLAG) { - rc = bnx2x_req_msix_irqs(bp); - if (rc) { - bnx2x_free_irq(bp, true); - goto load_error1; - } - } else { - /* Fall to INTx if failed to enable MSI-X due to lack of - memory (in bnx2x_set_num_queues()) */ - if ((rc != -ENOMEM) && (bp->int_mode != INT_MODE_INTx)) - bnx2x_enable_msi(bp); - bnx2x_ack_int(bp); - rc = bnx2x_req_irq(bp); - if (rc) { - BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); - bnx2x_free_irq(bp, true); - goto load_error1; - } - if (bp->flags & USING_MSI_FLAG) { - bp->dev->irq = bp->pdev->irq; - netdev_info(bp->dev, "using MSI IRQ %d\n", - bp->pdev->irq); - } - } - /* Send LOAD_REQUEST command to MCP Returns the type of LOAD command: if it is the first port to be initialized common blocks should be initialized, otherwise - not */ if (!BP_NOMCP(bp)) { - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ); + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; - goto load_error2; + goto load_error1; } if (load_code == FW_MSG_CODE_DRV_LOAD_REFUSED) { rc = -EBUSY; /* other port in diagnostic mode */ - goto load_error2; + goto load_error1; } } else { + int path = BP_PATH(bp); int port = BP_PORT(bp); - DP(NETIF_MSG_IFUP, "NO MCP - load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - load_count[0]++; - load_count[1 + port]++; - DP(NETIF_MSG_IFUP, "NO MCP - new load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - if (load_count[0] == 1) + DP(NETIF_MSG_IFUP, "NO MCP - load counts[%d] %d, %d, %d\n", + path, load_count[path][0], load_count[path][1], + load_count[path][2]); + load_count[path][0]++; + load_count[path][1 + port]++; + DP(NETIF_MSG_IFUP, "NO MCP - new load counts[%d] %d, %d, %d\n", + path, load_count[path][0], load_count[path][1], + load_count[path][2]); + if (load_count[path][0] == 1) load_code = FW_MSG_CODE_DRV_LOAD_COMMON; - else if (load_count[1 + port] == 1) + else if (load_count[path][1 + port] == 1) load_code = FW_MSG_CODE_DRV_LOAD_PORT; else load_code = FW_MSG_CODE_DRV_LOAD_FUNCTION; } if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || + (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) || (load_code == FW_MSG_CODE_DRV_LOAD_PORT)) bp->port.pmf = 1; else @@ -1306,16 +1264,22 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = bnx2x_init_hw(bp, load_code); if (rc) { BNX2X_ERR("HW init failed, aborting\n"); - bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); + goto load_error2; + } + + /* Connect to IRQs */ + rc = bnx2x_setup_irqs(bp); + if (rc) { + bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); goto load_error2; } /* Setup NIC internals and enable interrupts */ bnx2x_nic_init(bp, load_code); - if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) && + if (((load_code == FW_MSG_CODE_DRV_LOAD_COMMON) || + (load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP)) && (bp->common.shmem2_base)) SHMEM2_WR(bp, dcc_support, (SHMEM_DCC_SUPPORT_DISABLE_ENABLE_PF_TLV | @@ -1323,7 +1287,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) /* Send LOAD_DONE command to MCP */ if (!BP_NOMCP(bp)) { - load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE); + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); rc = -EBUSY; @@ -1333,7 +1297,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bp->state = BNX2X_STATE_OPENING_WAIT4_PORT; - rc = bnx2x_setup_leading(bp); + rc = bnx2x_func_start(bp); + if (rc) { + BNX2X_ERR("Function start failed!\n"); +#ifndef BNX2X_STOP_ON_ERROR + goto load_error3; +#else + bp->panic = 1; + return -EBUSY; +#endif + } + + rc = bnx2x_setup_client(bp, &bp->fp[0], 1 /* Leading */); if (rc) { BNX2X_ERR("Setup leading failed!\n"); #ifndef BNX2X_STOP_ON_ERROR @@ -1344,62 +1319,47 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) #endif } - if (CHIP_IS_E1H(bp)) - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { - DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); - bp->flags |= MF_FUNC_DIS; - } + if (!CHIP_IS_E1(bp) && + (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED)) { + DP(NETIF_MSG_IFUP, "mf_cfg function disabled\n"); + bp->flags |= MF_FUNC_DIS; + } - if (bp->state == BNX2X_STATE_OPEN) { -#ifdef BCM_CNIC - /* Enable Timer scan */ - REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); -#endif - for_each_nondefault_queue(bp, i) { - rc = bnx2x_setup_multi(bp, i); - if (rc) #ifdef BCM_CNIC - goto load_error4; -#else - goto load_error3; + /* Enable Timer scan */ + REG_WR(bp, TM_REG_EN_LINEAR0_TIMER + BP_PORT(bp)*4, 1); #endif - } - if (CHIP_IS_E1(bp)) - bnx2x_set_eth_mac_addr_e1(bp, 1); - else - bnx2x_set_eth_mac_addr_e1h(bp, 1); + for_each_nondefault_queue(bp, i) { + rc = bnx2x_setup_client(bp, &bp->fp[i], 0); + if (rc) #ifdef BCM_CNIC - /* Set iSCSI L2 MAC */ - mutex_lock(&bp->cnic_mutex); - if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; - bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, - CNIC_SB_ID(bp)); - } - mutex_unlock(&bp->cnic_mutex); + goto load_error4; +#else + goto load_error3; #endif } + /* Now when Clients are configured we are ready to work */ + bp->state = BNX2X_STATE_OPEN; + + bnx2x_set_eth_mac(bp, 1); + if (bp->port.pmf) bnx2x_initial_phy_init(bp, load_mode); /* Start fast path */ switch (load_mode) { case LOAD_NORMAL: - if (bp->state == BNX2X_STATE_OPEN) { - /* Tx queue should be only reenabled */ - netif_tx_wake_all_queues(bp->dev); - } + /* Tx queue should be only reenabled */ + netif_tx_wake_all_queues(bp->dev); /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); break; case LOAD_OPEN: netif_tx_start_all_queues(bp->dev); - if (bp->state != BNX2X_STATE_OPEN) - netif_tx_disable(bp->dev); + smp_mb__after_clear_bit(); /* Initialize the receive filter. */ bnx2x_set_rx_mode(bp->dev); break; @@ -1427,6 +1387,8 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) #endif bnx2x_inc_load_cnt(bp); + bnx2x_release_firmware(bp); + return 0; #ifdef BCM_CNIC @@ -1436,24 +1398,28 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) #endif load_error3: bnx2x_int_disable_sync(bp, 1); - if (!BP_NOMCP(bp)) { - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP); - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); - } - bp->port.pmf = 0; + /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); -load_error2: + /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_free_irq(bp); +load_error2: + if (!BP_NOMCP(bp)) { + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); + } + + bp->port.pmf = 0; load_error1: bnx2x_napi_disable(bp); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); +load_error0: bnx2x_free_mem(bp); + bnx2x_release_firmware(bp); + return rc; } @@ -1481,21 +1447,26 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bp->rx_mode = BNX2X_RX_MODE_NONE; bnx2x_set_storm_rx_mode(bp); - /* Disable HW interrupts, NAPI and Tx */ - bnx2x_netif_stop(bp, 1); - netif_carrier_off(bp->dev); + /* Stop Tx */ + bnx2x_tx_disable(bp); del_timer_sync(&bp->timer); - SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb, + + SHMEM_WR(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb, (DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq)); - bnx2x_stats_handle(bp, STATS_EVENT_STOP); - /* Release IRQs */ - bnx2x_free_irq(bp, false); + bnx2x_stats_handle(bp, STATS_EVENT_STOP); /* Cleanup the chip if needed */ if (unload_mode != UNLOAD_RECOVERY) bnx2x_chip_cleanup(bp, unload_mode); + else { + /* Disable HW interrupts, NAPI and Tx */ + bnx2x_netif_stop(bp, 1); + + /* Release IRQs */ + bnx2x_free_irq(bp); + } bp->port.pmf = 0; @@ -1503,8 +1474,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) bnx2x_free_skbs(bp); for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); + bnx2x_free_mem(bp); bp->state = BNX2X_STATE_CLOSED; @@ -1522,10 +1492,17 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) return 0; } + int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) { u16 pmcsr; + /* If there is no power capability, silently succeed */ + if (!bp->pm_cap) { + DP(NETIF_MSG_HW, "No power capability. Breaking.\n"); + return 0; + } + pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); switch (state) { @@ -1568,13 +1545,10 @@ int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state) return 0; } - - /* * net_device service functions */ - -static int bnx2x_poll(struct napi_struct *napi, int budget) +int bnx2x_poll(struct napi_struct *napi, int budget) { int work_done = 0; struct bnx2x_fastpath *fp = container_of(napi, struct bnx2x_fastpath, @@ -1603,27 +1577,28 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) /* Fall out from the NAPI loop if needed */ if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { bnx2x_update_fpsb_idx(fp); - /* bnx2x_has_rx_work() reads the status block, thus we need - * to ensure that status block indices have been actually read - * (bnx2x_update_fpsb_idx) prior to this check - * (bnx2x_has_rx_work) so that we won't write the "newer" - * value of the status block to IGU (if there was a DMA right - * after bnx2x_has_rx_work and if there is no rmb, the memory - * reading (bnx2x_update_fpsb_idx) may be postponed to right - * before bnx2x_ack_sb). In this case there will never be - * another interrupt until there is another update of the - * status block, while there is still unhandled work. - */ + /* bnx2x_has_rx_work() reads the status block, + * thus we need to ensure that status block indices + * have been actually read (bnx2x_update_fpsb_idx) + * prior to this check (bnx2x_has_rx_work) so that + * we won't write the "newer" value of the status block + * to IGU (if there was a DMA right after + * bnx2x_has_rx_work and if there is no rmb, the memory + * reading (bnx2x_update_fpsb_idx) may be postponed + * to right before bnx2x_ack_sb). In this case there + * will never be another interrupt until there is + * another update of the status block, while there + * is still unhandled work. + */ rmb(); if (!(bnx2x_has_rx_work(fp) || bnx2x_has_tx_work(fp))) { napi_complete(napi); /* Re-enable interrupts */ - bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, - le16_to_cpu(fp->fp_c_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, fp->sb_id, USTORM_ID, - le16_to_cpu(fp->fp_u_idx), + DP(NETIF_MSG_HW, + "Update index to %d\n", fp->fp_hc_idx); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, + le16_to_cpu(fp->fp_hc_idx), IGU_INT_ENABLE, 1); break; } @@ -1633,7 +1608,6 @@ static int bnx2x_poll(struct napi_struct *napi, int budget) return work_done; } - /* we split the first BD into headers and data BDs * to ease the pain of our fellow microcode engineers * we use one mapping for both BDs @@ -1807,6 +1781,122 @@ static int bnx2x_pkt_req_lin(struct bnx2x *bp, struct sk_buff *skb, } #endif +static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, + struct eth_tx_parse_bd_e2 *pbd, + u32 xmit_type) +{ + pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << + ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; + if ((xmit_type & XMIT_GSO_V6) && + (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) + pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; +} + +/** + * Update PBD in GSO case. + * + * @param skb + * @param tx_start_bd + * @param pbd + * @param xmit_type + */ +static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, + struct eth_tx_parse_bd_e1x *pbd, + u32 xmit_type) +{ + pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); + pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); + pbd->tcp_flags = pbd_tcp_flags(skb); + + if (xmit_type & XMIT_GSO_V4) { + pbd->ip_id = swab16(ip_hdr(skb)->id); + pbd->tcp_pseudo_csum = + swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, + ip_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + } else + pbd->tcp_pseudo_csum = + swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0)); + + pbd->global_data |= ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN; +} + +/** + * + * @param skb + * @param tx_start_bd + * @param pbd_e2 + * @param xmit_type + * + * @return header len + */ +static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_parse_bd_e2 *pbd, + u32 xmit_type) +{ + pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; + + pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - + skb->data) / 2) << + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; + + return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; +} + +/** + * + * @param skb + * @param tx_start_bd + * @param pbd + * @param xmit_type + * + * @return Header length + */ +static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, + struct eth_tx_parse_bd_e1x *pbd, + u32 xmit_type) +{ + u8 hlen = (skb_network_header(skb) - skb->data) / 2; + + /* for now NS flag is not used in Linux */ + pbd->global_data = + (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << + ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); + + pbd->ip_hlen_w = (skb_transport_header(skb) - + skb_network_header(skb)) / 2; + + hlen += pbd->ip_hlen_w + tcp_hdrlen(skb) / 2; + + pbd->total_hlen_w = cpu_to_le16(hlen); + hlen = hlen*2; + + if (xmit_type & XMIT_CSUM_TCP) { + pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); + + } else { + s8 fix = SKB_CS_OFF(skb); /* signed! */ + + DP(NETIF_MSG_TX_QUEUED, + "hlen %d fix %d csum before fix %x\n", + le16_to_cpu(pbd->total_hlen_w), fix, SKB_CS(skb)); + + /* HW bug: fixup the CSUM */ + pbd->tcp_pseudo_csum = + bnx2x_csum_fix(skb_transport_header(skb), + SKB_CS(skb), fix); + + DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", + pbd->tcp_pseudo_csum); + } + + return hlen; +} + /* called with netif_tx_lock * bnx2x_tx_int() runs without netif_tx_lock unless it needs to call * netif_wake_queue() @@ -1819,7 +1909,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; - struct eth_tx_parse_bd *pbd = NULL; + struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; + struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; u16 pkt_prod, bd_prod; int nbd, fp_index; dma_addr_t mapping; @@ -1847,9 +1938,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; } - DP(NETIF_MSG_TX_QUEUED, "SKB: summed %x protocol %x protocol(%x,%x)" - " gso type %x xmit_type %x\n", - skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, + DP(NETIF_MSG_TX_QUEUED, "queue[%d]: SKB: summed %x protocol %x " + "protocol(%x,%x) gso type %x xmit_type %x\n", + fp_index, skb->ip_summed, skb->protocol, ipv6_hdr(skb)->nexthdr, ip_hdr(skb)->protocol, skb_shinfo(skb)->gso_type, xmit_type); eth = (struct ethhdr *)skb->data; @@ -1895,10 +1986,11 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd = &fp->tx_desc_ring[bd_prod].start_bd; tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - tx_start_bd->general_data = (mac_type << - ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT); + SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_ETH_ADDR_TYPE, + mac_type); + /* header nbd */ - tx_start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT); + SET_FLAG(tx_start_bd->general_data, ETH_TX_START_BD_HDR_NBDS, 1); /* remember the first BD of the packet */ tx_buf->first_bd = fp->tx_bd_prod; @@ -1909,37 +2001,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) "sending pkt %u @%p next_idx %u bd %u @%p\n", pkt_prod, tx_buf, fp->tx_pkt_prod, bd_prod, tx_start_bd); -#ifdef BCM_VLAN - if ((bp->vlgrp != NULL) && vlan_tx_tag_present(skb) && - (bp->flags & HW_VLAN_TX_FLAG)) { - tx_start_bd->vlan = cpu_to_le16(vlan_tx_tag_get(skb)); - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_VLAN_TAG; + if (vlan_tx_tag_present(skb)) { + tx_start_bd->vlan_or_ethertype = + cpu_to_le16(vlan_tx_tag_get(skb)); + tx_start_bd->bd_flags.as_bitfield |= + (X_ETH_OUTBAND_VLAN << ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT); } else -#endif - tx_start_bd->vlan = cpu_to_le16(pkt_prod); + tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd = &fp->tx_desc_ring[bd_prod].parse_bd; - - memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); if (xmit_type & XMIT_CSUM) { - hlen = (skb_network_header(skb) - skb->data) / 2; - - /* for now NS flag is not used in Linux */ - pbd->global_data = - (hlen | ((skb->protocol == cpu_to_be16(ETH_P_8021Q)) << - ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT)); - - pbd->ip_hlen = (skb_transport_header(skb) - - skb_network_header(skb)) / 2; - - hlen += pbd->ip_hlen + tcp_hdrlen(skb) / 2; - - pbd->total_hlen = cpu_to_le16(hlen); - hlen = hlen*2; - tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_L4_CSUM; if (xmit_type & XMIT_CSUM_V4) @@ -1949,31 +2022,32 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_start_bd->bd_flags.as_bitfield |= ETH_TX_BD_FLAGS_IPV6; - if (xmit_type & XMIT_CSUM_TCP) { - pbd->tcp_pseudo_csum = swab16(tcp_hdr(skb)->check); - - } else { - s8 fix = SKB_CS_OFF(skb); /* signed! */ - - pbd->global_data |= ETH_TX_PARSE_BD_UDP_CS_FLG; - - DP(NETIF_MSG_TX_QUEUED, - "hlen %d fix %d csum before fix %x\n", - le16_to_cpu(pbd->total_hlen), fix, SKB_CS(skb)); + if (!(xmit_type & XMIT_CSUM_TCP)) + tx_start_bd->bd_flags.as_bitfield |= + ETH_TX_BD_FLAGS_IS_UDP; + } - /* HW bug: fixup the CSUM */ - pbd->tcp_pseudo_csum = - bnx2x_csum_fix(skb_transport_header(skb), - SKB_CS(skb), fix); + if (CHIP_IS_E2(bp)) { + pbd_e2 = &fp->tx_desc_ring[bd_prod].parse_bd_e2; + memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); + /* Set PBD in checksum offload case */ + if (xmit_type & XMIT_CSUM) + hlen = bnx2x_set_pbd_csum_e2(bp, + skb, pbd_e2, xmit_type); + } else { + pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; + memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); + /* Set PBD in checksum offload case */ + if (xmit_type & XMIT_CSUM) + hlen = bnx2x_set_pbd_csum(bp, skb, pbd_e1x, xmit_type); - DP(NETIF_MSG_TX_QUEUED, "csum after fix %x\n", - pbd->tcp_pseudo_csum); - } } + /* Map skb linear data for DMA */ mapping = dma_map_single(&bp->pdev->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); + /* Setup the data pointer of the first BD of the packet */ tx_start_bd->addr_hi = cpu_to_le32(U64_HI(mapping)); tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); nbd = skb_shinfo(skb)->nr_frags + 2; /* start_bd + pbd + frags */ @@ -1985,7 +2059,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) " nbytes %d flags %x vlan %x\n", tx_start_bd, tx_start_bd->addr_hi, tx_start_bd->addr_lo, le16_to_cpu(tx_start_bd->nbd), le16_to_cpu(tx_start_bd->nbytes), - tx_start_bd->bd_flags.as_bitfield, le16_to_cpu(tx_start_bd->vlan)); + tx_start_bd->bd_flags.as_bitfield, + le16_to_cpu(tx_start_bd->vlan_or_ethertype)); if (xmit_type & XMIT_GSO) { @@ -1999,28 +2074,14 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (unlikely(skb_headlen(skb) > hlen)) bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, hlen, bd_prod, ++nbd); - - pbd->lso_mss = cpu_to_le16(skb_shinfo(skb)->gso_size); - pbd->tcp_send_seq = swab32(tcp_hdr(skb)->seq); - pbd->tcp_flags = pbd_tcp_flags(skb); - - if (xmit_type & XMIT_GSO_V4) { - pbd->ip_id = swab16(ip_hdr(skb)->id); - pbd->tcp_pseudo_csum = - swab16(~csum_tcpudp_magic(ip_hdr(skb)->saddr, - ip_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0)); - - } else - pbd->tcp_pseudo_csum = - swab16(~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0)); - - pbd->global_data |= ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN; + if (CHIP_IS_E2(bp)) + bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); + else + bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); } tx_data_bd = (struct eth_tx_bd *)tx_start_bd; + /* Handle fragmented skb */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; @@ -2057,14 +2118,21 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) if (total_pkt_bd != NULL) total_pkt_bd->total_pkt_bytes = pkt_size; - if (pbd) + if (pbd_e1x) DP(NETIF_MSG_TX_QUEUED, - "PBD @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u" + "PBD (E1X) @%p ip_data %x ip_hlen %u ip_id %u lso_mss %u" " tcp_flags %x xsum %x seq %u hlen %u\n", - pbd, pbd->global_data, pbd->ip_hlen, pbd->ip_id, - pbd->lso_mss, pbd->tcp_flags, pbd->tcp_pseudo_csum, - pbd->tcp_send_seq, le16_to_cpu(pbd->total_hlen)); - + pbd_e1x, pbd_e1x->global_data, pbd_e1x->ip_hlen_w, + pbd_e1x->ip_id, pbd_e1x->lso_mss, pbd_e1x->tcp_flags, + pbd_e1x->tcp_pseudo_csum, pbd_e1x->tcp_send_seq, + le16_to_cpu(pbd_e1x->total_hlen_w)); + if (pbd_e2) + DP(NETIF_MSG_TX_QUEUED, + "PBD (E2) @%p dst %x %x %x src %x %x %x parsing_data %x\n", + pbd_e2, pbd_e2->dst_mac_addr_hi, pbd_e2->dst_mac_addr_mid, + pbd_e2->dst_mac_addr_lo, pbd_e2->src_mac_addr_hi, + pbd_e2->src_mac_addr_mid, pbd_e2->src_mac_addr_lo, + pbd_e2->parsing_data); DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d bd %u\n", nbd, bd_prod); /* @@ -2078,7 +2146,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) fp->tx_db.data.prod += nbd; barrier(); - DOORBELL(bp, fp->index, fp->tx_db.raw); + + DOORBELL(bp, fp->cid, fp->tx_db.raw); mmiowb(); @@ -2100,6 +2169,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } + /* called with rtnl_lock */ int bnx2x_change_mac_addr(struct net_device *dev, void *p) { @@ -2110,16 +2180,76 @@ int bnx2x_change_mac_addr(struct net_device *dev, void *p) return -EINVAL; memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); - if (netif_running(dev)) { - if (CHIP_IS_E1(bp)) - bnx2x_set_eth_mac_addr_e1(bp, 1); - else - bnx2x_set_eth_mac_addr_e1h(bp, 1); + if (netif_running(dev)) + bnx2x_set_eth_mac(bp, 1); + + return 0; +} + + +int bnx2x_setup_irqs(struct bnx2x *bp) +{ + int rc = 0; + if (bp->flags & USING_MSIX_FLAG) { + rc = bnx2x_req_msix_irqs(bp); + if (rc) + return rc; + } else { + bnx2x_ack_int(bp); + rc = bnx2x_req_irq(bp); + if (rc) { + BNX2X_ERR("IRQ request failed rc %d, aborting\n", rc); + return rc; + } + if (bp->flags & USING_MSI_FLAG) { + bp->dev->irq = bp->pdev->irq; + netdev_info(bp->dev, "using MSI IRQ %d\n", + bp->pdev->irq); + } } return 0; } +void bnx2x_free_mem_bp(struct bnx2x *bp) +{ + kfree(bp->fp); + kfree(bp->msix_table); + kfree(bp->ilt); +} + +int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp) +{ + struct bnx2x_fastpath *fp; + struct msix_entry *tbl; + struct bnx2x_ilt *ilt; + + /* fp array */ + fp = kzalloc(L2_FP_COUNT(bp->l2_cid_count)*sizeof(*fp), GFP_KERNEL); + if (!fp) + goto alloc_err; + bp->fp = fp; + + /* msix table */ + tbl = kzalloc((bp->l2_cid_count + 1) * sizeof(*tbl), + GFP_KERNEL); + if (!tbl) + goto alloc_err; + bp->msix_table = tbl; + + /* ilt */ + ilt = kzalloc(sizeof(*ilt), GFP_KERNEL); + if (!ilt) + goto alloc_err; + bp->ilt = ilt; + + return 0; +alloc_err: + bnx2x_free_mem_bp(bp); + return -ENOMEM; + +} + /* called with rtnl_lock */ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) { @@ -2161,29 +2291,6 @@ void bnx2x_tx_timeout(struct net_device *dev) schedule_delayed_work(&bp->reset_task, 0); } -#ifdef BCM_VLAN -/* called with rtnl_lock */ -void bnx2x_vlan_rx_register(struct net_device *dev, - struct vlan_group *vlgrp) -{ - struct bnx2x *bp = netdev_priv(dev); - - bp->vlgrp = vlgrp; - - /* Set flags according to the required capabilities */ - bp->flags &= ~(HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); - - if (dev->features & NETIF_F_HW_VLAN_TX) - bp->flags |= HW_VLAN_TX_FLAG; - - if (dev->features & NETIF_F_HW_VLAN_RX) - bp->flags |= HW_VLAN_RX_FLAG; - - if (netif_running(dev)) - bnx2x_set_client_config(bp); -} - -#endif int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *dev = pci_get_drvdata(pdev); @@ -2244,6 +2351,8 @@ int bnx2x_resume(struct pci_dev *pdev) bnx2x_set_power_state(bp, PCI_D0); netif_device_attach(dev); + /* Since the chip was reset, clear the FW sequence number */ + bp->fw_seq = 0; rc = bnx2x_nic_load(bp, LOAD_OPEN); rtnl_unlock(); diff --git a/drivers/net/bnx2x/bnx2x_cmn.h b/drivers/net/bnx2x/bnx2x_cmn.h index d1979b1a7ed276f391d3a860aaf41a10449c139b..5bfe0ab1d2d4d71cf1f801149f40de07b5f9ffad 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.h +++ b/drivers/net/bnx2x/bnx2x_cmn.h @@ -23,6 +23,7 @@ #include "bnx2x.h" +extern int num_queues; /*********************** Interfaces **************************** * Functions that need to be implemented by each driver version @@ -49,10 +50,11 @@ void bnx2x_link_set(struct bnx2x *bp); * Query link status * * @param bp + * @param is_serdes * * @return 0 - link is UP */ -u8 bnx2x_link_test(struct bnx2x *bp); +u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes); /** * Handles link status change @@ -61,6 +63,15 @@ u8 bnx2x_link_test(struct bnx2x *bp); */ void bnx2x__link_status_update(struct bnx2x *bp); +/** + * Report link status to upper layer + * + * @param bp + * + * @return int + */ +void bnx2x_link_report(struct bnx2x *bp); + /** * MSI-X slowpath interrupt handler * @@ -105,6 +116,13 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp); */ void bnx2x_int_enable(struct bnx2x *bp); +/** + * Disable HW interrupts. + * + * @param bp + */ +void bnx2x_int_disable(struct bnx2x *bp); + /** * Disable interrupts. This function ensures that there are no * ISRs or SP DPCs (sp_task) are running after it returns. @@ -114,6 +132,15 @@ void bnx2x_int_enable(struct bnx2x *bp); */ void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw); +/** + * Loads device firmware + * + * @param bp + * + * @return int + */ +int bnx2x_init_firmware(struct bnx2x *bp); + /** * Init HW blocks according to current initialization stage: * COMMON, PORT or FUNCTION. @@ -153,32 +180,35 @@ int bnx2x_alloc_mem(struct bnx2x *bp); void bnx2x_free_mem(struct bnx2x *bp); /** - * Bring up a leading (the first) eth Client. + * Setup eth Client. * * @param bp + * @param fp + * @param is_leading * * @return int */ -int bnx2x_setup_leading(struct bnx2x *bp); +int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, + int is_leading); /** - * Setup non-leading eth Client. + * Bring down an eth client. * * @param bp - * @param fp + * @param p * * @return int */ -int bnx2x_setup_multi(struct bnx2x *bp, int index); +int bnx2x_stop_fw_client(struct bnx2x *bp, + struct bnx2x_client_ramrod_params *p); /** - * Set number of quueus according to mode and number of available - * msi-x vectors + * Set number of queues according to mode * * @param bp * */ -void bnx2x_set_num_queues_msix(struct bnx2x *bp); +void bnx2x_set_num_queues(struct bnx2x *bp); /** * Cleanup chip internals: @@ -213,21 +243,12 @@ int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource); /** * Configure eth MAC address in the HW according to the value in - * netdev->dev_addr for 57711 - * - * @param bp driver handle - * @param set - */ -void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set); - -/** - * Configure eth MAC address in the HW according to the value in - * netdev->dev_addr for 57710 + * netdev->dev_addr. * * @param bp driver handle * @param set */ -void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set); +void bnx2x_set_eth_mac(struct bnx2x *bp, int set); #ifdef BCM_CNIC /** @@ -247,18 +268,22 @@ int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set); * Initialize status block in FW and HW * * @param bp driver handle - * @param sb host_status_block * @param dma_addr_t mapping * @param int sb_id + * @param int vfid + * @param u8 vf_valid + * @param int fw_sb_id + * @param int igu_sb_id */ -void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, - dma_addr_t mapping, int sb_id); +void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, + u8 vf_valid, int fw_sb_id, int igu_sb_id); /** - * Reconfigure FW/HW according to dev->flags rx mode + * Set MAC filtering configurations. * - * @param dev net_device + * @remarks called with netif_tx_lock from dev_mcast.c * + * @param dev net_device */ void bnx2x_set_rx_mode(struct net_device *dev); @@ -280,34 +305,162 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp); * Perform statistics handling according to event * * @param bp driver handle - * @param even tbnx2x_stats_event + * @param event bnx2x_stats_event */ void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event); /** - * Configures FW with client paramteres (like HW VLAN removal) - * for each active client. + * Handle ramrods completion + * + * @param fp fastpath handle for the event + * @param rr_cqe eth_rx_cqe + */ +void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); + +/** + * Init/halt function before/after sending + * CLIENT_SETUP/CFC_DEL for the first/last client. * * @param bp + * + * @return int */ -void bnx2x_set_client_config(struct bnx2x *bp); +int bnx2x_func_start(struct bnx2x *bp); +int bnx2x_func_stop(struct bnx2x *bp); /** - * Handle sp events + * Prepare ILT configurations according to current driver + * parameters. * - * @param fp fastpath handle for the event - * @param rr_cqe eth_rx_cqe + * @param bp + */ +void bnx2x_ilt_set_info(struct bnx2x *bp); + +/** + * Set power state to the requested value. Currently only D0 and + * D3hot are supported. + * + * @param bp + * @param state D0 or D3hot + * + * @return int */ -void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe); +int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); + +/* dev_close main block */ +int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); + +/* dev_open main block */ +int bnx2x_nic_load(struct bnx2x *bp, int load_mode); + +/* hard_xmit callback */ +netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); + +int bnx2x_change_mac_addr(struct net_device *dev, void *p); + +/* NAPI poll Rx part */ +int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); + +/* NAPI poll Tx part */ +int bnx2x_tx_int(struct bnx2x_fastpath *fp); + +/* suspend/resume callbacks */ +int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); +int bnx2x_resume(struct pci_dev *pdev); + +/* Release IRQ vectors */ +void bnx2x_free_irq(struct bnx2x *bp); + +void bnx2x_init_rx_rings(struct bnx2x *bp); +void bnx2x_free_skbs(struct bnx2x *bp); +void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); +void bnx2x_netif_start(struct bnx2x *bp); +/** + * Fill msix_table, request vectors, update num_queues according + * to number of available vectors + * + * @param bp + * + * @return int + */ +int bnx2x_enable_msix(struct bnx2x *bp); + +/** + * Request msi mode from OS, updated internals accordingly + * + * @param bp + * + * @return int + */ +int bnx2x_enable_msi(struct bnx2x *bp); + +/** + * Request IRQ vectors from OS. + * + * @param bp + * + * @return int + */ +int bnx2x_setup_irqs(struct bnx2x *bp); +/** + * NAPI callback + * + * @param napi + * @param budget + * + * @return int + */ +int bnx2x_poll(struct napi_struct *napi, int budget); + +/** + * Allocate/release memories outsize main driver structure + * + * @param bp + * + * @return int + */ +int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp); +void bnx2x_free_mem_bp(struct bnx2x *bp); + +/** + * Change mtu netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +int bnx2x_change_mtu(struct net_device *dev, int new_mtu); + +/** + * tx timeout netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +void bnx2x_tx_timeout(struct net_device *dev); + +#ifdef BCM_VLAN +/** + * vlan rx register netdev callback + * + * @param dev + * @param new_mtu + * + * @return int + */ +void bnx2x_vlan_rx_register(struct net_device *dev, + struct vlan_group *vlgrp); + +#endif static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp) { - struct host_status_block *fpsb = fp->status_blk; - barrier(); /* status block is written to by the chip */ - fp->fp_c_idx = fpsb->c_status_block.status_block_index; - fp->fp_u_idx = fpsb->u_status_block.status_block_index; + fp->fp_hc_idx = fp->sb_running_index[SM_RX_ID]; } static inline void bnx2x_update_rx_prod(struct bnx2x *bp, @@ -334,8 +487,8 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, wmb(); for (i = 0; i < sizeof(struct ustorm_eth_rx_producers)/4; i++) - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_RX_PRODS_OFFSET(BP_PORT(bp), fp->cl_id) + i*4, + REG_WR(bp, + BAR_USTRORM_INTMEM + fp->ustorm_rx_prods_offset + i*4, ((u32 *)&rx_prods)[i]); mmiowb(); /* keep prod updates ordered */ @@ -345,10 +498,77 @@ static inline void bnx2x_update_rx_prod(struct bnx2x *bp, fp->index, bd_prod, rx_comp_prod, rx_sge_prod); } +static inline void bnx2x_igu_ack_sb_gen(struct bnx2x *bp, u8 igu_sb_id, + u8 segment, u16 index, u8 op, + u8 update, u32 igu_addr) +{ + struct igu_regular cmd_data = {0}; + + cmd_data.sb_id_and_flags = + ((index << IGU_REGULAR_SB_INDEX_SHIFT) | + (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) | + (update << IGU_REGULAR_BUPDATE_SHIFT) | + (op << IGU_REGULAR_ENABLE_INT_SHIFT)); + + DP(NETIF_MSG_HW, "write 0x%08x to IGU addr 0x%x\n", + cmd_data.sb_id_and_flags, igu_addr); + REG_WR(bp, igu_addr, cmd_data.sb_id_and_flags); + + /* Make sure that ACK is written */ + mmiowb(); + barrier(); +} + +static inline void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, + u8 idu_sb_id, bool is_Pf) +{ + u32 data, ctl, cnt = 100; + u32 igu_addr_data = IGU_REG_COMMAND_REG_32LSB_DATA; + u32 igu_addr_ctl = IGU_REG_COMMAND_REG_CTRL; + u32 igu_addr_ack = IGU_REG_CSTORM_TYPE_0_SB_CLEANUP + (idu_sb_id/32)*4; + u32 sb_bit = 1 << (idu_sb_id%32); + u32 func_encode = BP_FUNC(bp) | + ((is_Pf == true ? 1 : 0) << IGU_FID_ENCODE_IS_PF_SHIFT); + u32 addr_encode = IGU_CMD_E2_PROD_UPD_BASE + idu_sb_id; + + /* Not supported in BC mode */ + if (CHIP_INT_MODE_IS_BC(bp)) + return; + + data = (IGU_USE_REGISTER_cstorm_type_0_sb_cleanup + << IGU_REGULAR_CLEANUP_TYPE_SHIFT) | + IGU_REGULAR_CLEANUP_SET | + IGU_REGULAR_BCLEANUP; + + ctl = addr_encode << IGU_CTRL_REG_ADDRESS_SHIFT | + func_encode << IGU_CTRL_REG_FID_SHIFT | + IGU_CTRL_CMD_TYPE_WR << IGU_CTRL_REG_TYPE_SHIFT; + + DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n", + data, igu_addr_data); + REG_WR(bp, igu_addr_data, data); + mmiowb(); + barrier(); + DP(NETIF_MSG_HW, "write 0x%08x to IGU(via GRC) addr 0x%x\n", + ctl, igu_addr_ctl); + REG_WR(bp, igu_addr_ctl, ctl); + mmiowb(); + barrier(); + + /* wait for clean up to finish */ + while (!(REG_RD(bp, igu_addr_ack) & sb_bit) && --cnt) + msleep(20); + + if (!(REG_RD(bp, igu_addr_ack) & sb_bit)) { + DP(NETIF_MSG_HW, "Unable to finish IGU cleanup: " + "idu_sb_id %d offset %d bit %d (cnt %d)\n", + idu_sb_id, idu_sb_id/32, idu_sb_id%32, cnt); + } +} -static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, - u8 storm, u16 index, u8 op, u8 update) +static inline void bnx2x_hc_ack_sb(struct bnx2x *bp, u8 sb_id, + u8 storm, u16 index, u8 op, u8 update) { u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + COMMAND_REG_INT_ACK); @@ -369,7 +589,37 @@ static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 sb_id, mmiowb(); barrier(); } -static inline u16 bnx2x_ack_int(struct bnx2x *bp) + +static inline void bnx2x_igu_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 segment, + u16 index, u8 op, u8 update) +{ + u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id)*8; + + bnx2x_igu_ack_sb_gen(bp, igu_sb_id, segment, index, op, update, + igu_addr); +} + +static inline void bnx2x_ack_sb(struct bnx2x *bp, u8 igu_sb_id, u8 storm, + u16 index, u8 op, u8 update) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_ack_sb(bp, igu_sb_id, storm, index, op, update); + else { + u8 segment; + + if (CHIP_INT_MODE_IS_BC(bp)) + segment = storm; + else if (igu_sb_id != bp->igu_dsb_id) + segment = IGU_SEG_ACCESS_DEF; + else if (storm == ATTENTION_ID) + segment = IGU_SEG_ACCESS_ATTN; + else + segment = IGU_SEG_ACCESS_DEF; + bnx2x_igu_ack_sb(bp, igu_sb_id, segment, index, op, update); + } +} + +static inline u16 bnx2x_hc_ack_int(struct bnx2x *bp) { u32 hc_addr = (HC_REG_COMMAND_REG + BP_PORT(bp)*32 + COMMAND_REG_SIMD_MASK); @@ -378,18 +628,36 @@ static inline u16 bnx2x_ack_int(struct bnx2x *bp) DP(BNX2X_MSG_OFF, "read 0x%08x from HC addr 0x%x\n", result, hc_addr); + barrier(); return result; } -/* - * fast path service functions - */ +static inline u16 bnx2x_igu_ack_int(struct bnx2x *bp) +{ + u32 igu_addr = (BAR_IGU_INTMEM + IGU_REG_SISR_MDPC_WMASK_LSB_UPPER*8); + u32 result = REG_RD(bp, igu_addr); + + DP(NETIF_MSG_HW, "read 0x%08x from IGU addr 0x%x\n", + result, igu_addr); + + barrier(); + return result; +} + +static inline u16 bnx2x_ack_int(struct bnx2x *bp) +{ + barrier(); + if (bp->common.int_block == INT_BLOCK_HC) + return bnx2x_hc_ack_int(bp); + else + return bnx2x_igu_ack_int(bp); +} static inline int bnx2x_has_tx_work_unload(struct bnx2x_fastpath *fp) { /* Tell compiler that consumer and producer can change */ barrier(); - return (fp->tx_pkt_prod != fp->tx_pkt_cons); + return fp->tx_pkt_prod != fp->tx_pkt_cons; } static inline u16 bnx2x_tx_avail(struct bnx2x_fastpath *fp) @@ -424,6 +692,29 @@ static inline int bnx2x_has_tx_work(struct bnx2x_fastpath *fp) return hw_cons != fp->tx_pkt_cons; } +static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) +{ + u16 rx_cons_sb; + + /* Tell compiler that status block fields can change */ + barrier(); + rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); + if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) + rx_cons_sb++; + return (fp->rx_comp_cons != rx_cons_sb); +} + +/** + * disables tx from stack point of view + * + * @param bp + */ +static inline void bnx2x_tx_disable(struct bnx2x *bp) +{ + netif_tx_disable(bp->dev); + netif_carrier_off(bp->dev); +} + static inline void bnx2x_free_rx_sge(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 index) { @@ -436,7 +727,7 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, return; dma_unmap_page(&bp->pdev->dev, dma_unmap_addr(sw_buf, mapping), - SGE_PAGE_SIZE*PAGES_PER_SGE, PCI_DMA_FROMDEVICE); + SGE_PAGE_SIZE*PAGES_PER_SGE, DMA_FROM_DEVICE); __free_pages(page, PAGES_PER_SGE_SHIFT); sw_buf->page = NULL; @@ -444,13 +735,67 @@ static inline void bnx2x_free_rx_sge(struct bnx2x *bp, sge->addr_lo = 0; } -static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, - struct bnx2x_fastpath *fp, int last) +static inline void bnx2x_add_all_napi(struct bnx2x *bp) { int i; - for (i = 0; i < last; i++) - bnx2x_free_rx_sge(bp, fp, i); + /* Add NAPI objects */ + for_each_queue(bp, i) + netif_napi_add(bp->dev, &bnx2x_fp(bp, i, napi), + bnx2x_poll, BNX2X_NAPI_WEIGHT); +} + +static inline void bnx2x_del_all_napi(struct bnx2x *bp) +{ + int i; + + for_each_queue(bp, i) + netif_napi_del(&bnx2x_fp(bp, i, napi)); +} + +static inline void bnx2x_disable_msi(struct bnx2x *bp) +{ + if (bp->flags & USING_MSIX_FLAG) { + pci_disable_msix(bp->pdev); + bp->flags &= ~USING_MSIX_FLAG; + } else if (bp->flags & USING_MSI_FLAG) { + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + } +} + +static inline int bnx2x_calc_num_queues(struct bnx2x *bp) +{ + return num_queues ? + min_t(int, num_queues, BNX2X_MAX_QUEUES(bp)) : + min_t(int, num_online_cpus(), BNX2X_MAX_QUEUES(bp)); +} + +static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) +{ + int i, j; + + for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { + int idx = RX_SGE_CNT * i - 1; + + for (j = 0; j < 2; j++) { + SGE_MASK_CLEAR_BIT(fp, idx); + idx--; + } + } +} + +static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) +{ + /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ + memset(fp->sge_mask, 0xff, + (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); + + /* Clear the two last indices in the page to 1: + these are the indices that correspond to the "next" element, + hence will never be indicated and should be removed from + the calculations. */ + bnx2x_clear_sge_mask_next_elems(fp); } static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, @@ -479,6 +824,7 @@ static inline int bnx2x_alloc_rx_sge(struct bnx2x *bp, return 0; } + static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, struct bnx2x_fastpath *fp, u16 index) { @@ -513,7 +859,7 @@ static inline int bnx2x_alloc_rx_skb(struct bnx2x *bp, * so there is no need to check for dma_mapping_error(). */ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, - struct sk_buff *skb, u16 cons, u16 prod) + u16 cons, u16 prod) { struct bnx2x *bp = fp->bp; struct sw_rx_bd *cons_rx_buf = &fp->rx_buf_ring[cons]; @@ -531,32 +877,15 @@ static inline void bnx2x_reuse_rx_skb(struct bnx2x_fastpath *fp, *prod_bd = *cons_bd; } -static inline void bnx2x_clear_sge_mask_next_elems(struct bnx2x_fastpath *fp) +static inline void bnx2x_free_rx_sge_range(struct bnx2x *bp, + struct bnx2x_fastpath *fp, int last) { - int i, j; - - for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { - int idx = RX_SGE_CNT * i - 1; + int i; - for (j = 0; j < 2; j++) { - SGE_MASK_CLEAR_BIT(fp, idx); - idx--; - } - } + for (i = 0; i < last; i++) + bnx2x_free_rx_sge(bp, fp, i); } -static inline void bnx2x_init_sge_ring_bit_mask(struct bnx2x_fastpath *fp) -{ - /* Set the mask to all 1-s: it's faster to compare to 0 than to 0xf-s */ - memset(fp->sge_mask, 0xff, - (NUM_RX_SGE >> RX_SGE_MASK_ELEM_SHIFT)*sizeof(u64)); - - /* Clear the two last indices in the page to 1: - these are the indices that correspond to the "next" element, - hence will never be indicated and should be removed from - the calculations. */ - bnx2x_clear_sge_mask_next_elems(fp); -} static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, struct bnx2x_fastpath *fp, int last) { @@ -582,7 +911,7 @@ static inline void bnx2x_free_tpa_pool(struct bnx2x *bp, } -static inline void bnx2x_init_tx_ring(struct bnx2x *bp) +static inline void bnx2x_init_tx_rings(struct bnx2x *bp) { int i, j; @@ -601,7 +930,7 @@ static inline void bnx2x_init_tx_ring(struct bnx2x *bp) BCM_PAGE_SIZE*(i % NUM_TX_RINGS))); } - fp->tx_db.data.header.header = DOORBELL_HDR_DB_TYPE; + SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1); fp->tx_db.data.zero_fill1 = 0; fp->tx_db.data.prod = 0; @@ -609,44 +938,98 @@ static inline void bnx2x_init_tx_ring(struct bnx2x *bp) fp->tx_pkt_cons = 0; fp->tx_bd_prod = 0; fp->tx_bd_cons = 0; - fp->tx_cons_sb = BNX2X_TX_SB_INDEX; fp->tx_pkt = 0; } } -static inline int bnx2x_has_rx_work(struct bnx2x_fastpath *fp) + +static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp) { - u16 rx_cons_sb; + int i; - /* Tell compiler that status block fields can change */ - barrier(); - rx_cons_sb = le16_to_cpu(*fp->rx_cons_sb); - if ((rx_cons_sb & MAX_RCQ_DESC_CNT) == MAX_RCQ_DESC_CNT) - rx_cons_sb++; - return (fp->rx_comp_cons != rx_cons_sb); + for (i = 1; i <= NUM_RX_RINGS; i++) { + struct eth_rx_bd *rx_bd; + + rx_bd = &fp->rx_desc_ring[RX_DESC_CNT * i - 2]; + rx_bd->addr_hi = + cpu_to_le32(U64_HI(fp->rx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); + rx_bd->addr_lo = + cpu_to_le32(U64_LO(fp->rx_desc_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_RINGS))); + } +} + +static inline void bnx2x_set_next_page_sgl(struct bnx2x_fastpath *fp) +{ + int i; + + for (i = 1; i <= NUM_RX_SGE_PAGES; i++) { + struct eth_rx_sge *sge; + + sge = &fp->rx_sge_ring[RX_SGE_CNT * i - 2]; + sge->addr_hi = + cpu_to_le32(U64_HI(fp->rx_sge_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); + + sge->addr_lo = + cpu_to_le32(U64_LO(fp->rx_sge_mapping + + BCM_PAGE_SIZE*(i % NUM_RX_SGE_PAGES))); + } +} + +static inline void bnx2x_set_next_page_rx_cq(struct bnx2x_fastpath *fp) +{ + int i; + for (i = 1; i <= NUM_RCQ_RINGS; i++) { + struct eth_rx_cqe_next_page *nextpg; + + nextpg = (struct eth_rx_cqe_next_page *) + &fp->rx_comp_ring[RCQ_DESC_CNT * i - 1]; + nextpg->addr_hi = + cpu_to_le32(U64_HI(fp->rx_comp_mapping + + BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); + nextpg->addr_lo = + cpu_to_le32(U64_LO(fp->rx_comp_mapping + + BCM_PAGE_SIZE*(i % NUM_RCQ_RINGS))); + } +} + + + +static inline void __storm_memset_struct(struct bnx2x *bp, + u32 addr, size_t size, u32 *data) +{ + int i; + for (i = 0; i < size/4; i++) + REG_WR(bp, addr + (i * 4), data[i]); +} + +static inline void storm_memset_mac_filters(struct bnx2x *bp, + struct tstorm_eth_mac_filter_config *mac_filters, + u16 abs_fid) +{ + size_t size = sizeof(struct tstorm_eth_mac_filter_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_MAC_FILTER_CONFIG_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)mac_filters); +} + +static inline void storm_memset_cmng(struct bnx2x *bp, + struct cmng_struct_per_port *cmng, + u8 port) +{ + size_t size = sizeof(struct cmng_struct_per_port); + + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_CMNG_PER_PORT_VARS_OFFSET(port); + + __storm_memset_struct(bp, addr, size, (u32 *)cmng); } /* HW Lock for shared dual port PHYs */ void bnx2x_acquire_phy_lock(struct bnx2x *bp); void bnx2x_release_phy_lock(struct bnx2x *bp); -void bnx2x_link_report(struct bnx2x *bp); -int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget); -int bnx2x_tx_int(struct bnx2x_fastpath *fp); -void bnx2x_init_rx_rings(struct bnx2x *bp); -netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev); - -int bnx2x_change_mac_addr(struct net_device *dev, void *p); -void bnx2x_tx_timeout(struct net_device *dev); -void bnx2x_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp); -void bnx2x_netif_start(struct bnx2x *bp); -void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw); -void bnx2x_free_irq(struct bnx2x *bp, bool disable_only); -int bnx2x_suspend(struct pci_dev *pdev, pm_message_t state); -int bnx2x_resume(struct pci_dev *pdev); -void bnx2x_free_skbs(struct bnx2x *bp); -int bnx2x_change_mtu(struct net_device *dev, int new_mtu); -int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode); -int bnx2x_nic_load(struct bnx2x *bp, int load_mode); -int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state); - #endif /* BNX2X_CMN_H */ diff --git a/drivers/net/bnx2x/bnx2x_dump.h b/drivers/net/bnx2x/bnx2x_dump.h index 3bb9a91bb3f74e198f065bfa55b622b42ec2f2db..dc18c25ca9e523d4bd262185ed642005281b7123 100644 --- a/drivers/net/bnx2x/bnx2x_dump.h +++ b/drivers/net/bnx2x/bnx2x_dump.h @@ -31,14 +31,24 @@ struct dump_sign { #define RI_E1 0x1 #define RI_E1H 0x2 +#define RI_E2 0x4 #define RI_ONLINE 0x100 - +#define RI_PATH0_DUMP 0x200 +#define RI_PATH1_DUMP 0x400 #define RI_E1_OFFLINE (RI_E1) #define RI_E1_ONLINE (RI_E1 | RI_ONLINE) #define RI_E1H_OFFLINE (RI_E1H) #define RI_E1H_ONLINE (RI_E1H | RI_ONLINE) -#define RI_ALL_OFFLINE (RI_E1 | RI_E1H) -#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E2_OFFLINE (RI_E2) +#define RI_E2_ONLINE (RI_E2 | RI_ONLINE) +#define RI_E1E1H_OFFLINE (RI_E1 | RI_E1H) +#define RI_E1E1H_ONLINE (RI_E1 | RI_E1H | RI_ONLINE) +#define RI_E1HE2_OFFLINE (RI_E2 | RI_E1H) +#define RI_E1HE2_ONLINE (RI_E2 | RI_E1H | RI_ONLINE) +#define RI_E1E2_OFFLINE (RI_E2 | RI_E1) +#define RI_E1E2_ONLINE (RI_E2 | RI_E1 | RI_ONLINE) +#define RI_ALL_OFFLINE (RI_E1 | RI_E1H | RI_E2) +#define RI_ALL_ONLINE (RI_E1 | RI_E1H | RI_E2 | RI_ONLINE) #define MAX_TIMER_PENDING 200 #define TIMER_SCAN_DONT_CARE 0xFF @@ -513,6 +523,12 @@ static const struct wreg_addr wreg_addrs_e1h[WREGS_COUNT_E1H] = { { 0x1b0c00, 256, 2, read_reg_e1h_0, RI_E1H_OFFLINE } }; +#define WREGS_COUNT_E2 1 +static const u32 read_reg_e2_0[] = { 0x1b1040, 0x1b1000 }; + +static const struct wreg_addr wreg_addrs_e2[WREGS_COUNT_E2] = { + { 0x1b0c00, 128, 2, read_reg_e2_0, RI_E2_OFFLINE } +}; static const struct dump_sign dump_sign_all = { 0x49aa93ee, 0x40835, 0x22 }; @@ -531,4 +547,17 @@ static const u32 timer_scan_regs_e1h[TIMER_REGS_COUNT_E1H] = { 0x1640d0, 0x1640d4 }; +#define PAGE_MODE_VALUES_E2 2 + +#define PAGE_READ_REGS_E2 1 + +#define PAGE_WRITE_REGS_E2 1 + +static const u32 page_vals_e2[PAGE_MODE_VALUES_E2] = { 0, 128 }; + +static const u32 page_write_regs_e2[PAGE_WRITE_REGS_E2] = { 328476 }; + +static const struct reg_addr page_read_regs_e2[PAGE_READ_REGS_E2] = { + { 0x58000, 4608, RI_E2_ONLINE } }; + #endif /* BNX2X_DUMP_H */ diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c index 8b75b05e34c5a124d246a862ea6460ef80e6ec47..d02ffbdc9f0ef551d4f17ba384f2d32a683c7ab2 100644 --- a/drivers/net/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/bnx2x/bnx2x_ethtool.c @@ -25,70 +25,46 @@ #include "bnx2x_cmn.h" #include "bnx2x_dump.h" - static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); - - cmd->supported = bp->port.supported; - cmd->advertising = bp->port.advertising; + int cfg_idx = bnx2x_get_link_cfg_idx(bp); + /* Dual Media boards present all available port types */ + cmd->supported = bp->port.supported[cfg_idx] | + (bp->port.supported[cfg_idx ^ 1] & + (SUPPORTED_TP | SUPPORTED_FIBRE)); + cmd->advertising = bp->port.advertising[cfg_idx]; if ((bp->state == BNX2X_STATE_OPEN) && !(bp->flags & MF_FUNC_DIS) && (bp->link_vars.link_up)) { cmd->speed = bp->link_vars.line_speed; cmd->duplex = bp->link_vars.duplex; - if (IS_E1HMF(bp)) { - u16 vn_max_rate; - - vn_max_rate = - ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >> - FUNC_MF_CFG_MAX_BW_SHIFT) * 100; - if (vn_max_rate < cmd->speed) - cmd->speed = vn_max_rate; - } } else { - cmd->speed = -1; - cmd->duplex = -1; - } - - if (bp->link_params.switch_cfg == SWITCH_CFG_10G) { - u32 ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - cmd->port = PORT_FIBRE; - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - cmd->port = PORT_TP; - break; + cmd->speed = bp->link_params.req_line_speed[cfg_idx]; + cmd->duplex = bp->link_params.req_duplex[cfg_idx]; + } + if (IS_MF(bp)) { + u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] & + FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * + 100; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - BNX2X_ERR("XGXS PHY Failure detected 0x%x\n", - bp->link_params.ext_phy_config); - break; + if (vn_max_rate < cmd->speed) + cmd->speed = vn_max_rate; + } - default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); - break; - } - } else + if (bp->port.supported[cfg_idx] & SUPPORTED_TP) cmd->port = PORT_TP; + else if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE) + cmd->port = PORT_FIBRE; + else + BNX2X_ERR("XGXS PHY Failure detected\n"); cmd->phy_address = bp->mdio.prtad; cmd->transceiver = XCVR_INTERNAL; - if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) + if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) cmd->autoneg = AUTONEG_ENABLE; else cmd->autoneg = AUTONEG_DISABLE; @@ -110,9 +86,9 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct bnx2x *bp = netdev_priv(dev); - u32 advertising; + u32 advertising, cfg_idx, old_multi_phy_config, new_multi_phy_config; - if (IS_E1HMF(bp)) + if (IS_MF(bp)) return 0; DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n" @@ -123,26 +99,81 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver, cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt); + cfg_idx = bnx2x_get_link_cfg_idx(bp); + old_multi_phy_config = bp->link_params.multi_phy_config; + switch (cmd->port) { + case PORT_TP: + if (bp->port.supported[cfg_idx] & SUPPORTED_TP) + break; /* no port change */ + + if (!(bp->port.supported[0] & SUPPORTED_TP || + bp->port.supported[1] & SUPPORTED_TP)) { + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + bp->link_params.multi_phy_config &= + ~PORT_HW_CFG_PHY_SELECTION_MASK; + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + else + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + break; + case PORT_FIBRE: + if (bp->port.supported[cfg_idx] & SUPPORTED_FIBRE) + break; /* no port change */ + + if (!(bp->port.supported[0] & SUPPORTED_FIBRE || + bp->port.supported[1] & SUPPORTED_FIBRE)) { + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + bp->link_params.multi_phy_config &= + ~PORT_HW_CFG_PHY_SELECTION_MASK; + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + else + bp->link_params.multi_phy_config |= + PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + break; + default: + DP(NETIF_MSG_LINK, "Unsupported port type\n"); + return -EINVAL; + } + /* Save new config in case command complete successuly */ + new_multi_phy_config = bp->link_params.multi_phy_config; + /* Get the new cfg_idx */ + cfg_idx = bnx2x_get_link_cfg_idx(bp); + /* Restore old config in case command failed */ + bp->link_params.multi_phy_config = old_multi_phy_config; + DP(NETIF_MSG_LINK, "cfg_idx = %x\n", cfg_idx); + if (cmd->autoneg == AUTONEG_ENABLE) { - if (!(bp->port.supported & SUPPORTED_Autoneg)) { + if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) { DP(NETIF_MSG_LINK, "Autoneg not supported\n"); return -EINVAL; } /* advertise the requested speed and duplex if supported */ - cmd->advertising &= bp->port.supported; + cmd->advertising &= bp->port.supported[cfg_idx]; - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->link_params.req_duplex = DUPLEX_FULL; - bp->port.advertising |= (ADVERTISED_Autoneg | + bp->link_params.req_line_speed[cfg_idx] = SPEED_AUTO_NEG; + bp->link_params.req_duplex[cfg_idx] = DUPLEX_FULL; + bp->port.advertising[cfg_idx] |= (ADVERTISED_Autoneg | cmd->advertising); } else { /* forced speed */ /* advertise the requested speed and duplex if supported */ - switch (cmd->speed) { + u32 speed = cmd->speed; + speed |= (cmd->speed_hi << 16); + switch (speed) { case SPEED_10: if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_10baseT_Full)) { DP(NETIF_MSG_LINK, "10M full not supported\n"); @@ -152,7 +183,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) advertising = (ADVERTISED_10baseT_Full | ADVERTISED_TP); } else { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_10baseT_Half)) { DP(NETIF_MSG_LINK, "10M half not supported\n"); @@ -166,7 +197,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) case SPEED_100: if (cmd->duplex == DUPLEX_FULL) { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_100baseT_Full)) { DP(NETIF_MSG_LINK, "100M full not supported\n"); @@ -176,7 +207,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) advertising = (ADVERTISED_100baseT_Full | ADVERTISED_TP); } else { - if (!(bp->port.supported & + if (!(bp->port.supported[cfg_idx] & SUPPORTED_100baseT_Half)) { DP(NETIF_MSG_LINK, "100M half not supported\n"); @@ -194,7 +225,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_1000baseT_Full)) { + if (!(bp->port.supported[cfg_idx] & + SUPPORTED_1000baseT_Full)) { DP(NETIF_MSG_LINK, "1G full not supported\n"); return -EINVAL; } @@ -210,7 +242,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_2500baseX_Full)) { + if (!(bp->port.supported[cfg_idx] + & SUPPORTED_2500baseX_Full)) { DP(NETIF_MSG_LINK, "2.5G full not supported\n"); return -EINVAL; @@ -226,7 +259,8 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } - if (!(bp->port.supported & SUPPORTED_10000baseT_Full)) { + if (!(bp->port.supported[cfg_idx] + & SUPPORTED_10000baseT_Full)) { DP(NETIF_MSG_LINK, "10G full not supported\n"); return -EINVAL; } @@ -236,20 +270,23 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) break; default: - DP(NETIF_MSG_LINK, "Unsupported speed\n"); + DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed); return -EINVAL; } - bp->link_params.req_line_speed = cmd->speed; - bp->link_params.req_duplex = cmd->duplex; - bp->port.advertising = advertising; + bp->link_params.req_line_speed[cfg_idx] = speed; + bp->link_params.req_duplex[cfg_idx] = cmd->duplex; + bp->port.advertising[cfg_idx] = advertising; } DP(NETIF_MSG_LINK, "req_line_speed %d\n" DP_LEVEL " req_duplex %d advertising 0x%x\n", - bp->link_params.req_line_speed, bp->link_params.req_duplex, - bp->port.advertising); + bp->link_params.req_line_speed[cfg_idx], + bp->link_params.req_duplex[cfg_idx], + bp->port.advertising[cfg_idx]); + /* Set new config */ + bp->link_params.multi_phy_config = new_multi_phy_config; if (netif_running(dev)) { bnx2x_stats_handle(bp, STATS_EVENT_STOP); bnx2x_link_set(bp); @@ -260,6 +297,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) #define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE) #define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE) +#define IS_E2_ONLINE(info) (((info) & RI_E2_ONLINE) == RI_E2_ONLINE) static int bnx2x_get_regs_len(struct net_device *dev) { @@ -277,7 +315,7 @@ static int bnx2x_get_regs_len(struct net_device *dev) regdump_len += wreg_addrs_e1[i].size * (1 + wreg_addrs_e1[i].read_regs_count); - } else { /* E1H */ + } else if (CHIP_IS_E1H(bp)) { for (i = 0; i < REGS_COUNT; i++) if (IS_E1H_ONLINE(reg_addrs[i].info)) regdump_len += reg_addrs[i].size; @@ -286,6 +324,15 @@ static int bnx2x_get_regs_len(struct net_device *dev) if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) regdump_len += wreg_addrs_e1h[i].size * (1 + wreg_addrs_e1h[i].read_regs_count); + } else if (CHIP_IS_E2(bp)) { + for (i = 0; i < REGS_COUNT; i++) + if (IS_E2_ONLINE(reg_addrs[i].info)) + regdump_len += reg_addrs[i].size; + + for (i = 0; i < WREGS_COUNT_E2; i++) + if (IS_E2_ONLINE(wreg_addrs_e2[i].info)) + regdump_len += wreg_addrs_e2[i].size * + (1 + wreg_addrs_e2[i].read_regs_count); } regdump_len *= 4; regdump_len += sizeof(struct dump_hdr); @@ -293,6 +340,23 @@ static int bnx2x_get_regs_len(struct net_device *dev) return regdump_len; } +static inline void bnx2x_read_pages_regs_e2(struct bnx2x *bp, u32 *p) +{ + u32 i, j, k, n; + + for (i = 0; i < PAGE_MODE_VALUES_E2; i++) { + for (j = 0; j < PAGE_WRITE_REGS_E2; j++) { + REG_WR(bp, page_write_regs_e2[j], page_vals_e2[i]); + for (k = 0; k < PAGE_READ_REGS_E2; k++) + if (IS_E2_ONLINE(page_read_regs_e2[k].info)) + for (n = 0; n < + page_read_regs_e2[k].size; n++) + *p++ = REG_RD(bp, + page_read_regs_e2[k].addr + n*4); + } + } +} + static void bnx2x_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) { @@ -312,7 +376,14 @@ static void bnx2x_get_regs(struct net_device *dev, dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR); dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR); dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR); - dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE; + + if (CHIP_IS_E1(bp)) + dump_hdr.info = RI_E1_ONLINE; + else if (CHIP_IS_E1H(bp)) + dump_hdr.info = RI_E1H_ONLINE; + else if (CHIP_IS_E2(bp)) + dump_hdr.info = RI_E2_ONLINE | + (BP_PATH(bp) ? RI_PATH1_DUMP : RI_PATH0_DUMP); memcpy(p, &dump_hdr, sizeof(struct dump_hdr)); p += dump_hdr.hdr_size + 1; @@ -324,16 +395,25 @@ static void bnx2x_get_regs(struct net_device *dev, *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); - } else { /* E1H */ + } else if (CHIP_IS_E1H(bp)) { for (i = 0; i < REGS_COUNT; i++) if (IS_E1H_ONLINE(reg_addrs[i].info)) for (j = 0; j < reg_addrs[i].size; j++) *p++ = REG_RD(bp, reg_addrs[i].addr + j*4); + + } else if (CHIP_IS_E2(bp)) { + for (i = 0; i < REGS_COUNT; i++) + if (IS_E2_ONLINE(reg_addrs[i].info)) + for (j = 0; j < reg_addrs[i].size; j++) + *p++ = REG_RD(bp, + reg_addrs[i].addr + j*4); + + bnx2x_read_pages_regs_e2(bp, p); } } -#define PHY_FW_VER_LEN 10 +#define PHY_FW_VER_LEN 20 static void bnx2x_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) @@ -436,7 +516,7 @@ static u32 bnx2x_get_link(struct net_device *dev) { struct bnx2x *bp = netdev_priv(dev); - if (bp->flags & MF_FUNC_DIS) + if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN)) return 0; return bp->link_vars.link_up; @@ -811,7 +891,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); int port = BP_PORT(bp); int rc = 0; - + u32 ext_phy_config; if (!netif_running(dev)) return -EAGAIN; @@ -827,6 +907,10 @@ static int bnx2x_set_eeprom(struct net_device *dev, !bp->port.pmf) return -EINVAL; + ext_phy_config = + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config); + if (eeprom->magic == 0x50485950) { /* 'PHYP' (0x50485950): prepare phy for FW upgrade */ bnx2x_stats_handle(bp, STATS_EVENT_STOP); @@ -834,7 +918,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, bnx2x_acquire_phy_lock(bp); rc |= bnx2x_link_reset(&bp->link_params, &bp->link_vars, 0); - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == + if (XGXS_EXT_PHY_TYPE(ext_phy_config) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_HIGH, port); @@ -855,10 +939,8 @@ static int bnx2x_set_eeprom(struct net_device *dev, } } else if (eeprom->magic == 0x53985943) { /* 'PHYC' (0x53985943): PHY FW upgrade completed */ - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == + if (XGXS_EXT_PHY_TYPE(ext_phy_config) == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) { - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config); /* DSP Remove Download Mode */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, @@ -866,7 +948,8 @@ static int bnx2x_set_eeprom(struct net_device *dev, bnx2x_acquire_phy_lock(bp); - bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr); + bnx2x_sfx7101_sp_sw_reset(bp, + &bp->link_params.phy[EXT_PHY1]); /* wait 0.5 sec to allow it to run */ msleep(500); @@ -879,6 +962,7 @@ static int bnx2x_set_eeprom(struct net_device *dev, return rc; } + static int bnx2x_get_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) { @@ -920,7 +1004,14 @@ static void bnx2x_get_ringparam(struct net_device *dev, ering->rx_mini_max_pending = 0; ering->rx_jumbo_max_pending = 0; - ering->rx_pending = bp->rx_ring_size; + if (bp->rx_ring_size) + ering->rx_pending = bp->rx_ring_size; + else + if (bp->state == BNX2X_STATE_OPEN && bp->num_queues) + ering->rx_pending = MAX_RX_AVAIL/bp->num_queues; + else + ering->rx_pending = MAX_RX_AVAIL; + ering->rx_mini_pending = 0; ering->rx_jumbo_pending = 0; @@ -940,6 +1031,7 @@ static int bnx2x_set_ringparam(struct net_device *dev, } if ((ering->rx_pending > MAX_RX_AVAIL) || + (ering->rx_pending < MIN_RX_AVAIL) || (ering->tx_pending > MAX_TX_AVAIL) || (ering->tx_pending <= MAX_SKB_FRAGS + 4)) return -EINVAL; @@ -959,10 +1051,9 @@ static void bnx2x_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct bnx2x *bp = netdev_priv(dev); - - epause->autoneg = (bp->link_params.req_flow_ctrl == - BNX2X_FLOW_CTRL_AUTO) && - (bp->link_params.req_line_speed == SPEED_AUTO_NEG); + int cfg_idx = bnx2x_get_link_cfg_idx(bp); + epause->autoneg = (bp->link_params.req_flow_ctrl[cfg_idx] == + BNX2X_FLOW_CTRL_AUTO); epause->rx_pause = ((bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) == BNX2X_FLOW_CTRL_RX); @@ -978,37 +1069,39 @@ static int bnx2x_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct bnx2x *bp = netdev_priv(dev); - - if (IS_E1HMF(bp)) + u32 cfg_idx = bnx2x_get_link_cfg_idx(bp); + if (IS_MF(bp)) return 0; DP(NETIF_MSG_LINK, "ethtool_pauseparam: cmd %d\n" DP_LEVEL " autoneg %d rx_pause %d tx_pause %d\n", epause->cmd, epause->autoneg, epause->rx_pause, epause->tx_pause); - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_AUTO; if (epause->rx_pause) - bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_RX; + bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_RX; if (epause->tx_pause) - bp->link_params.req_flow_ctrl |= BNX2X_FLOW_CTRL_TX; + bp->link_params.req_flow_ctrl[cfg_idx] |= BNX2X_FLOW_CTRL_TX; - if (bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + if (bp->link_params.req_flow_ctrl[cfg_idx] == BNX2X_FLOW_CTRL_AUTO) + bp->link_params.req_flow_ctrl[cfg_idx] = BNX2X_FLOW_CTRL_NONE; if (epause->autoneg) { - if (!(bp->port.supported & SUPPORTED_Autoneg)) { + if (!(bp->port.supported[cfg_idx] & SUPPORTED_Autoneg)) { DP(NETIF_MSG_LINK, "autoneg not supported\n"); return -EINVAL; } - if (bp->link_params.req_line_speed == SPEED_AUTO_NEG) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + if (bp->link_params.req_line_speed[cfg_idx] == SPEED_AUTO_NEG) { + bp->link_params.req_flow_ctrl[cfg_idx] = + BNX2X_FLOW_CTRL_AUTO; + } } DP(NETIF_MSG_LINK, - "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl); + "req_flow_ctrl 0x%x\n", bp->link_params.req_flow_ctrl[cfg_idx]); if (netif_running(dev)) { bnx2x_stats_handle(bp, STATS_EVENT_STOP); @@ -1024,35 +1117,34 @@ static int bnx2x_set_flags(struct net_device *dev, u32 data) int changed = 0; int rc = 0; - if (data & ~(ETH_FLAG_LRO | ETH_FLAG_RXHASH)) - return -EINVAL; - if (bp->recovery_state != BNX2X_RECOVERY_DONE) { printk(KERN_ERR "Handling parity error recovery. Try again later\n"); return -EAGAIN; } + if (!(data & ETH_FLAG_RXVLAN)) + return -EINVAL; + + if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa) + return -EINVAL; + + rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN | + ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH); + if (rc) + return rc; + /* TPA requires Rx CSUM offloading */ if ((data & ETH_FLAG_LRO) && bp->rx_csum) { - if (!bp->disable_tpa) { - if (!(dev->features & NETIF_F_LRO)) { - dev->features |= NETIF_F_LRO; - bp->flags |= TPA_ENABLE_FLAG; - changed = 1; - } - } else - rc = -EINVAL; - } else if (dev->features & NETIF_F_LRO) { + if (!(bp->flags & TPA_ENABLE_FLAG)) { + bp->flags |= TPA_ENABLE_FLAG; + changed = 1; + } + } else if (bp->flags & TPA_ENABLE_FLAG) { dev->features &= ~NETIF_F_LRO; bp->flags &= ~TPA_ENABLE_FLAG; changed = 1; } - if (data & ETH_FLAG_RXHASH) - dev->features |= NETIF_F_RXHASH; - else - dev->features &= ~NETIF_F_RXHASH; - if (changed && netif_running(dev)) { bnx2x_nic_unload(bp, UNLOAD_NORMAL); rc = bnx2x_nic_load(bp, LOAD_NORMAL); @@ -1185,6 +1277,9 @@ static int bnx2x_test_registers(struct bnx2x *bp) for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) { u32 offset, mask, save_val, val; + if (CHIP_IS_E2(bp) && + reg_tbl[i].offset0 == HC_REG_AGG_INT_0) + continue; offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1; mask = reg_tbl[i].mask; @@ -1192,6 +1287,7 @@ static int bnx2x_test_registers(struct bnx2x *bp) save_val = REG_RD(bp, offset); REG_WR(bp, offset, (wr_val & mask)); + val = REG_RD(bp, offset); /* Restore the original register's value */ @@ -1236,20 +1332,33 @@ static int bnx2x_test_memory(struct bnx2x *bp) u32 offset; u32 e1_mask; u32 e1h_mask; + u32 e2_mask; } prty_tbl[] = { - { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 }, - { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 }, - { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 }, - { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 }, - { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 }, - { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 }, - - { NULL, 0xffffffff, 0, 0 } + { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2, 0 }, + { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0, 0 }, + { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0, 0 }, + { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0, 0 }, + + { NULL, 0xffffffff, 0, 0, 0 } }; if (!netif_running(bp->dev)) return rc; + /* pre-Check the parity status */ + for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { + val = REG_RD(bp, prty_tbl[i].offset); + if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || + (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) || + (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) { + DP(NETIF_MSG_HW, + "%s is 0x%x\n", prty_tbl[i].name, val); + goto test_mem_exit; + } + } + /* Go through all the memories */ for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) for (j = 0; j < mem_tbl[i].size; j++) @@ -1259,7 +1368,8 @@ static int bnx2x_test_memory(struct bnx2x *bp) for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { val = REG_RD(bp, prty_tbl[i].offset); if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || - (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) { + (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) || + (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) { DP(NETIF_MSG_HW, "%s is 0x%x\n", prty_tbl[i].name, val); goto test_mem_exit; @@ -1272,12 +1382,12 @@ static int bnx2x_test_memory(struct bnx2x *bp) return rc; } -static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up) +static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes) { - int cnt = 1000; + int cnt = 1400; if (link_up) - while (bnx2x_link_test(bp) && cnt--) + while (bnx2x_link_test(bp, is_serdes) && cnt--) msleep(10); } @@ -1293,7 +1403,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) u16 pkt_prod, bd_prod; struct sw_tx_bd *tx_buf; struct eth_tx_start_bd *tx_start_bd; - struct eth_tx_parse_bd *pbd = NULL; + struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; + struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; dma_addr_t mapping; union eth_rx_cqe *cqe; u8 cqe_fp_flags; @@ -1304,7 +1415,7 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) /* check the loopback mode */ switch (loopback_mode) { case BNX2X_PHY_LOOPBACK: - if (bp->link_params.loopback_mode != LOOPBACK_XGXS_10) + if (bp->link_params.loopback_mode != LOOPBACK_XGXS) return -EINVAL; break; case BNX2X_MAC_LOOPBACK: @@ -1349,16 +1460,23 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) tx_start_bd->addr_lo = cpu_to_le32(U64_LO(mapping)); tx_start_bd->nbd = cpu_to_le16(2); /* start + pbd */ tx_start_bd->nbytes = cpu_to_le16(skb_headlen(skb)); - tx_start_bd->vlan = cpu_to_le16(pkt_prod); + tx_start_bd->vlan_or_ethertype = cpu_to_le16(pkt_prod); tx_start_bd->bd_flags.as_bitfield = ETH_TX_BD_FLAGS_START_BD; - tx_start_bd->general_data = ((UNICAST_ADDRESS << - ETH_TX_START_BD_ETH_ADDR_TYPE_SHIFT) | 1); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_ETH_ADDR_TYPE, + UNICAST_ADDRESS); + SET_FLAG(tx_start_bd->general_data, + ETH_TX_START_BD_HDR_NBDS, + 1); /* turn on parsing and get a BD */ bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); - pbd = &fp_tx->tx_desc_ring[bd_prod].parse_bd; - memset(pbd, 0, sizeof(struct eth_tx_parse_bd)); + pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; + pbd_e2 = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e2; + + memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); + memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); wmb(); @@ -1377,6 +1495,13 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up) if (tx_idx != tx_start_idx + num_pkts) goto test_loopback_exit; + /* Unlike HC IGU won't generate an interrupt for status block + * updates that have been performed while interrupts were + * disabled. + */ + if (bp->common.int_block == INT_BLOCK_IGU) + bnx2x_tx_int(fp_tx); + rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); if (rx_idx != rx_start_idx + num_pkts) goto test_loopback_exit; @@ -1519,8 +1644,7 @@ static int bnx2x_test_intr(struct bnx2x *bp) config->hdr.length = 0; if (CHIP_IS_E1(bp)) - /* use last unicast entries */ - config->hdr.offset = (BP_PORT(bp) ? 63 : 31); + config->hdr.offset = (BP_PORT(bp) ? 32 : 0); else config->hdr.offset = BP_FUNC(bp); config->hdr.client_id = bp->fp->cl_id; @@ -1528,9 +1652,9 @@ static int bnx2x_test_intr(struct bnx2x *bp) bp->set_mac_pending++; smp_wmb(); - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); if (rc == 0) { for (i = 0; i < 10; i++) { if (!bp->set_mac_pending) @@ -1549,7 +1673,7 @@ static void bnx2x_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) { struct bnx2x *bp = netdev_priv(dev); - + u8 is_serdes; if (bp->recovery_state != BNX2X_RECOVERY_DONE) { printk(KERN_ERR "Handling parity error recovery. Try again later\n"); etest->flags |= ETH_TEST_FL_FAILED; @@ -1562,8 +1686,9 @@ static void bnx2x_self_test(struct net_device *dev, return; /* offline tests are not supported in MF mode */ - if (IS_E1HMF(bp)) + if (IS_MF(bp)) etest->flags &= ~ETH_TEST_FL_OFFLINE; + is_serdes = (bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) > 0; if (etest->flags & ETH_TEST_FL_OFFLINE) { int port = BP_PORT(bp); @@ -1575,11 +1700,12 @@ static void bnx2x_self_test(struct net_device *dev, /* disable input for TX port IF */ REG_WR(bp, NIG_REG_EGRESS_UMP0_IN_EN + port*4, 0); - link_up = (bnx2x_link_test(bp) == 0); + link_up = bp->link_vars.link_up; + bnx2x_nic_unload(bp, UNLOAD_NORMAL); bnx2x_nic_load(bp, LOAD_DIAG); /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); + bnx2x_wait_for_link(bp, link_up, is_serdes); if (bnx2x_test_registers(bp) != 0) { buf[0] = 1; @@ -1589,6 +1715,7 @@ static void bnx2x_self_test(struct net_device *dev, buf[1] = 1; etest->flags |= ETH_TEST_FL_FAILED; } + buf[2] = bnx2x_test_loopback(bp, link_up); if (buf[2] != 0) etest->flags |= ETH_TEST_FL_FAILED; @@ -1600,7 +1727,7 @@ static void bnx2x_self_test(struct net_device *dev, bnx2x_nic_load(bp, LOAD_NORMAL); /* wait until link state is restored */ - bnx2x_wait_for_link(bp, link_up); + bnx2x_wait_for_link(bp, link_up, is_serdes); } if (bnx2x_test_nvram(bp) != 0) { buf[3] = 1; @@ -1611,7 +1738,7 @@ static void bnx2x_self_test(struct net_device *dev, etest->flags |= ETH_TEST_FL_FAILED; } if (bp->port.pmf) - if (bnx2x_link_test(bp) != 0) { + if (bnx2x_link_test(bp, is_serdes) != 0) { buf[5] = 1; etest->flags |= ETH_TEST_FL_FAILED; } @@ -1752,8 +1879,8 @@ static const struct { #define IS_PORT_STAT(i) \ ((bnx2x_stats_arr[i].flags & STATS_FLAGS_BOTH) == STATS_FLAGS_PORT) #define IS_FUNC_STAT(i) (bnx2x_stats_arr[i].flags & STATS_FLAGS_FUNC) -#define IS_E1HMF_MODE_STAT(bp) \ - (IS_E1HMF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) +#define IS_MF_MODE_STAT(bp) \ + (IS_MF(bp) && !(bp->msg_enable & BNX2X_MSG_STATS)) static int bnx2x_get_sset_count(struct net_device *dev, int stringset) { @@ -1764,10 +1891,10 @@ static int bnx2x_get_sset_count(struct net_device *dev, int stringset) case ETH_SS_STATS: if (is_multi(bp)) { num_stats = BNX2X_NUM_Q_STATS * bp->num_queues; - if (!IS_E1HMF_MODE_STAT(bp)) + if (!IS_MF_MODE_STAT(bp)) num_stats += BNX2X_NUM_STATS; } else { - if (IS_E1HMF_MODE_STAT(bp)) { + if (IS_MF_MODE_STAT(bp)) { num_stats = 0; for (i = 0; i < BNX2X_NUM_STATS; i++) if (IS_FUNC_STAT(i)) @@ -1800,14 +1927,14 @@ static void bnx2x_get_strings(struct net_device *dev, u32 stringset, u8 *buf) bnx2x_q_stats_arr[j].string, i); k += BNX2X_NUM_Q_STATS; } - if (IS_E1HMF_MODE_STAT(bp)) + if (IS_MF_MODE_STAT(bp)) break; for (j = 0; j < BNX2X_NUM_STATS; j++) strcpy(buf + (k + j)*ETH_GSTRING_LEN, bnx2x_stats_arr[j].string); } else { for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) + if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) continue; strcpy(buf + j*ETH_GSTRING_LEN, bnx2x_stats_arr[i].string); @@ -1851,7 +1978,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, } k += BNX2X_NUM_Q_STATS; } - if (IS_E1HMF_MODE_STAT(bp)) + if (IS_MF_MODE_STAT(bp)) return; hw_stats = (u32 *)&bp->eth_stats; for (j = 0; j < BNX2X_NUM_STATS; j++) { @@ -1872,7 +1999,7 @@ static void bnx2x_get_ethtool_stats(struct net_device *dev, } else { hw_stats = (u32 *)&bp->eth_stats; for (i = 0, j = 0; i < BNX2X_NUM_STATS; i++) { - if (IS_E1HMF_MODE_STAT(bp) && IS_PORT_STAT(i)) + if (IS_MF_MODE_STAT(bp) && IS_PORT_STAT(i)) continue; if (bnx2x_stats_arr[i].size == 0) { /* skip this counter */ @@ -1910,10 +2037,11 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) for (i = 0; i < (data * 2); i++) { if ((i % 2) == 0) - bnx2x_set_led(&bp->link_params, LED_MODE_OPER, - SPEED_1000); + bnx2x_set_led(&bp->link_params, &bp->link_vars, + LED_MODE_OPER, SPEED_1000); else - bnx2x_set_led(&bp->link_params, LED_MODE_OFF, 0); + bnx2x_set_led(&bp->link_params, &bp->link_vars, + LED_MODE_OFF, 0); msleep_interruptible(500); if (signal_pending(current)) @@ -1921,7 +2049,7 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) } if (bp->link_vars.link_up) - bnx2x_set_led(&bp->link_params, LED_MODE_OPER, + bnx2x_set_led(&bp->link_params, &bp->link_vars, LED_MODE_OPER, bp->link_vars.line_speed); return 0; diff --git a/drivers/net/bnx2x/bnx2x_fw_defs.h b/drivers/net/bnx2x/bnx2x_fw_defs.h index 08d71bf438d63baf270404409ec607d09895dff1..f4e5b1ce81497727bd1a443f642038626a8511ec 100644 --- a/drivers/net/bnx2x/bnx2x_fw_defs.h +++ b/drivers/net/bnx2x/bnx2x_fw_defs.h @@ -7,369 +7,272 @@ * the Free Software Foundation. */ - -#define CSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x7000 : 0x1000) -#define CSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x7020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0x8622 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100) + (index * 0x4)) : (0x3562 + (function * \ - 0x40) + (index * 0x4))) -#define CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0x8822 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200) + (index * 0x4)) : (0x35e2 + (function * \ - 0x80) + (index * 0x4))) -#define CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8600 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100)) : (0x3540 + (function * 0x40))) -#define CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8800 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200)) : (0x35c0 + (function * 0x80))) -#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8608 + ((function>>1) * 0x40) + \ - ((function&1) * 0x100)) : (0x3548 + (function * 0x40))) -#define CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8808 + ((function>>1) * 0x80) + \ - ((function&1) * 0x200)) : (0x35c8 + (function * 0x80))) -#define CSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x11e8 : 0xffffffff) -#define CSTORM_HC_BTR_C_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x8c04 + (port * 0xf0)) : (0x36c4 + (port * 0xc0))) -#define CSTORM_HC_BTR_U_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x8de4 + (port * 0xf0)) : (0x3844 + (port * 0xc0))) -#define CSTORM_ISCSI_CQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6680 + (function * 0x8)) : (0x25a0 + \ - (function * 0x8))) -#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x66c0 + (function * 0x8)) : (0x25b0 + \ - (function * 0x8))) -#define CSTORM_ISCSI_EQ_CONS_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6040 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2410 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6044 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2414 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x604c + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x241c + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6057 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2427 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_PROD_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6042 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2412 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6056 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2426 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(function, eqIdx) \ - (IS_E1H_OFFSET ? (0x6054 + (function * 0xc0) + (eqIdx * 0x18)) : \ - (0x2424 + (function * 0xc0) + (eqIdx * 0x18))) -#define CSTORM_ISCSI_HQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6640 + (function * 0x8)) : (0x2590 + \ - (function * 0x8))) -#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x2404 + \ - (function * 0x8))) -#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x2402 + \ - (function * 0x8))) -#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x2400 + \ - (function * 0x8))) -#define CSTORM_SB_HC_DISABLE_C_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0x811a + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4)) : (0x305a + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4))) -#define CSTORM_SB_HC_DISABLE_U_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0xb01a + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4)) : (0x401a + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4))) -#define CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0x8118 + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4)) : (0x3058 + (port * 0x280) + (cpu_id * 0x28) + \ - (index * 0x4))) -#define CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, cpu_id, index) \ - (IS_E1H_OFFSET ? (0xb018 + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4)) : (0x4018 + (port * 0x800) + (cpu_id * 0x80) + \ - (index * 0x4))) -#define CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0x8100 + (port * 0x280) + (cpu_id * 0x28)) : \ - (0x3040 + (port * 0x280) + (cpu_id * 0x28))) -#define CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0xb000 + (port * 0x800) + (cpu_id * 0x80)) : \ - (0x4000 + (port * 0x800) + (cpu_id * 0x80))) -#define CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0x8108 + (port * 0x280) + (cpu_id * 0x28)) : \ - (0x3048 + (port * 0x280) + (cpu_id * 0x28))) -#define CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, cpu_id) \ - (IS_E1H_OFFSET ? (0xb008 + (port * 0x800) + (cpu_id * 0x80)) : \ - (0x4008 + (port * 0x800) + (cpu_id * 0x80))) -#define CSTORM_SB_STATUS_BLOCK_C_SIZE 0x10 -#define CSTORM_SB_STATUS_BLOCK_U_SIZE 0x60 -#define CSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x1108 + (function * 0x8)) : (0x5108 + \ - (function * 0x8))) -#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3200 + (function * 0x20)) : 0xffffffff) -#define TSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0xa000 : 0x1000) -#define TSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0xa020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define TSTORM_CLIENT_CONFIG_OFFSET(port, client_id) \ - (IS_E1H_OFFSET ? (0x33a0 + (port * 0x1a0) + (client_id * 0x10)) \ - : (0x9c0 + (port * 0x120) + (client_id * 0x10))) -#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET \ - (IS_E1H_OFFSET ? 0x1ed8 : 0xffffffff) +#ifndef BNX2X_FW_DEFS_H +#define BNX2X_FW_DEFS_H + +#define CSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[142].base) +#define CSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[141].base + ((assertListEntry) * IRO[141].m1)) +#define CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[144].base + ((pfId) * IRO[144].m1)) +#define CSTORM_EVENT_RING_DATA_OFFSET(pfId) \ + (IRO[149].base + (((pfId)>>1) * IRO[149].m1) + (((pfId)&1) * \ + IRO[149].m2)) +#define CSTORM_EVENT_RING_PROD_OFFSET(pfId) \ + (IRO[150].base + (((pfId)>>1) * IRO[150].m1) + (((pfId)&1) * \ + IRO[150].m2)) +#define CSTORM_FINAL_CLEANUP_COMPLETE_OFFSET(funcId) \ + (IRO[156].base + ((funcId) * IRO[156].m1)) +#define CSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[146].base + ((funcId) * IRO[146].m1)) +#define CSTORM_FUNCTION_MODE_OFFSET (IRO[153].base) +#define CSTORM_IGU_MODE_OFFSET (IRO[154].base) +#define CSTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ + (IRO[311].base + ((pfId) * IRO[311].m1)) +#define CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ + (IRO[312].base + ((pfId) * IRO[312].m1)) + #define CSTORM_ISCSI_EQ_CONS_OFFSET(pfId, iscsiEqId) \ + (IRO[304].base + ((pfId) * IRO[304].m1) + ((iscsiEqId) * \ + IRO[304].m2)) + #define CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[306].base + ((pfId) * IRO[306].m1) + ((iscsiEqId) * \ + IRO[306].m2)) + #define CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfId, iscsiEqId) \ + (IRO[305].base + ((pfId) * IRO[305].m1) + ((iscsiEqId) * \ + IRO[305].m2)) + #define \ + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfId, iscsiEqId) \ + (IRO[307].base + ((pfId) * IRO[307].m1) + ((iscsiEqId) * \ + IRO[307].m2)) + #define CSTORM_ISCSI_EQ_PROD_OFFSET(pfId, iscsiEqId) \ + (IRO[303].base + ((pfId) * IRO[303].m1) + ((iscsiEqId) * \ + IRO[303].m2)) + #define CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfId, iscsiEqId) \ + (IRO[309].base + ((pfId) * IRO[309].m1) + ((iscsiEqId) * \ + IRO[309].m2)) + #define CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfId, iscsiEqId) \ + (IRO[308].base + ((pfId) * IRO[308].m1) + ((iscsiEqId) * \ + IRO[308].m2)) +#define CSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ + (IRO[310].base + ((pfId) * IRO[310].m1)) +#define CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[302].base + ((pfId) * IRO[302].m1)) +#define CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[301].base + ((pfId) * IRO[301].m1)) +#define CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[300].base + ((pfId) * IRO[300].m1)) +#define CSTORM_PATH_ID_OFFSET (IRO[159].base) +#define CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(pfId) \ + (IRO[137].base + ((pfId) * IRO[137].m1)) +#define CSTORM_SP_STATUS_BLOCK_OFFSET(pfId) \ + (IRO[136].base + ((pfId) * IRO[136].m1)) +#define CSTORM_SP_STATUS_BLOCK_SIZE (IRO[136].size) +#define CSTORM_SP_SYNC_BLOCK_OFFSET(pfId) \ + (IRO[138].base + ((pfId) * IRO[138].m1)) +#define CSTORM_SP_SYNC_BLOCK_SIZE (IRO[138].size) +#define CSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[143].base + ((pfId) * IRO[143].m1)) +#define CSTORM_STATUS_BLOCK_DATA_OFFSET(sbId) \ + (IRO[129].base + ((sbId) * IRO[129].m1)) +#define CSTORM_STATUS_BLOCK_OFFSET(sbId) \ + (IRO[128].base + ((sbId) * IRO[128].m1)) +#define CSTORM_STATUS_BLOCK_SIZE (IRO[128].size) +#define CSTORM_SYNC_BLOCK_OFFSET(sbId) \ + (IRO[132].base + ((sbId) * IRO[132].m1)) +#define CSTORM_SYNC_BLOCK_SIZE (IRO[132].size) +#define CSTORM_VF_PF_CHANNEL_STATE_OFFSET(vfId) \ + (IRO[151].base + ((vfId) * IRO[151].m1)) +#define CSTORM_VF_PF_CHANNEL_VALID_OFFSET(vfId) \ + (IRO[152].base + ((vfId) * IRO[152].m1)) +#define CSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[147].base + ((funcId) * IRO[147].m1)) +#define TSTORM_ACCEPT_CLASSIFY_FAILED_OFFSET (IRO[199].base) +#define TSTORM_APPROXIMATE_MATCH_MULTICAST_FILTERING_OFFSET(pfId) \ + (IRO[198].base + ((pfId) * IRO[198].m1)) +#define TSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[99].base) +#define TSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[98].base + ((assertListEntry) * IRO[98].m1)) + #define TSTORM_CLIENT_CONFIG_OFFSET(portId, clientId) \ + (IRO[197].base + ((portId) * IRO[197].m1) + ((clientId) * \ + IRO[197].m2)) +#define TSTORM_COMMON_SAFC_WORKAROUND_ENABLE_OFFSET (IRO[104].base) #define TSTORM_COMMON_SAFC_WORKAROUND_TIMEOUT_10USEC_OFFSET \ - (IS_E1H_OFFSET ? 0x1eda : 0xffffffff) -#define TSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0xb01a + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \ - 0x28) + (index * 0x4))) -#define TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xb000 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1400 + (function * 0x28))) -#define TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xb008 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1408 + (function * 0x28))) -#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2940 + (function * 0x8)) : (0x4928 + \ - (function * 0x8))) -#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3000 + (function * 0x40)) : (0x1500 + \ - (function * 0x40))) -#define TSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x1ed0 : 0xffffffff) -#define TSTORM_HC_BTR_OFFSET(port) \ - (IS_E1H_OFFSET ? (0xb144 + (port * 0x30)) : (0x1454 + (port * 0x18))) -#define TSTORM_INDIRECTION_TABLE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x12c8 + (function * 0x80)) : (0x22c8 + \ - (function * 0x80))) -#define TSTORM_INDIRECTION_TABLE_SIZE 0x80 -#define TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(function, pblEntry) \ - (IS_E1H_OFFSET ? (0x60c0 + (function * 0x40) + (pblEntry * 0x8)) \ - : (0x4c30 + (function * 0x40) + (pblEntry * 0x8))) -#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6340 + (function * 0x8)) : (0x4cd0 + \ - (function * 0x8))) -#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6004 + (function * 0x8)) : (0x4c04 + \ - (function * 0x8))) -#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6002 + (function * 0x8)) : (0x4c02 + \ - (function * 0x8))) -#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6000 + (function * 0x8)) : (0x4c00 + \ - (function * 0x8))) -#define TSTORM_ISCSI_RQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6080 + (function * 0x8)) : (0x4c20 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6040 + (function * 0x8)) : (0x4c10 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6042 + (function * 0x8)) : (0x4c12 + \ - (function * 0x8))) -#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x6044 + (function * 0x8)) : (0x4c14 + \ - (function * 0x8))) -#define TSTORM_MAC_FILTER_CONFIG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x3008 + (function * 0x40)) : (0x1508 + \ - (function * 0x40))) -#define TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0x2010 + (port * 0x490) + (stats_counter_id * \ - 0x40)) : (0x4010 + (port * 0x490) + (stats_counter_id * 0x40))) -#define TSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x29c0 + (function * 0x8)) : (0x4948 + \ - (function * 0x8))) -#define TSTORM_TCP_MAX_CWND_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x4004 + (function * 0x8)) : (0x1fb4 + \ - (function * 0x8))) -#define USTORM_AGG_DATA_OFFSET (IS_E1H_OFFSET ? 0xa000 : 0x3000) -#define USTORM_AGG_DATA_SIZE (IS_E1H_OFFSET ? 0x2000 : 0x1000) -#define USTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x8000 : 0x1000) -#define USTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x8020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define USTORM_CQE_PAGE_BASE_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1010 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4010 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_CQE_PAGE_NEXT_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1028 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4028 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_ETH_PAUSE_ENABLED_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x2ad4 + (port * 0x8)) : 0xffffffff) -#define USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1030 + (port * 0x680) + (clientId * 0x40)) : \ - 0xffffffff) -#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2a50 + (function * 0x8)) : (0x1dd0 + \ - (function * 0x8))) -#define USTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x2448 : 0xffffffff) -#define USTORM_ISCSI_CQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7044 + (function * 0x8)) : (0x2414 + \ - (function * 0x8))) -#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7046 + (function * 0x8)) : (0x2416 + \ - (function * 0x8))) -#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7688 + (function * 0x8)) : (0x29c8 + \ - (function * 0x8))) -#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7648 + (function * 0x8)) : (0x29b8 + \ - (function * 0x8))) -#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7004 + (function * 0x8)) : (0x2404 + \ - (function * 0x8))) -#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7002 + (function * 0x8)) : (0x2402 + \ - (function * 0x8))) -#define USTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7000 + (function * 0x8)) : (0x2400 + \ - (function * 0x8))) -#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7040 + (function * 0x8)) : (0x2410 + \ - (function * 0x8))) -#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7080 + (function * 0x8)) : (0x2420 + \ - (function * 0x8))) -#define USTORM_ISCSI_RQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x7084 + (function * 0x8)) : (0x2424 + \ - (function * 0x8))) -#define USTORM_MAX_AGG_SIZE_OFFSET(port, clientId) \ - (IS_E1H_OFFSET ? (0x1018 + (port * 0x680) + (clientId * 0x40)) : \ - (0x4018 + (port * 0x360) + (clientId * 0x30))) -#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2408 + (function * 0x8)) : (0x1da8 + \ - (function * 0x8))) -#define USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0x2450 + (port * 0x2d0) + (stats_counter_id * \ - 0x28)) : (0x1500 + (port * 0x2d0) + (stats_counter_id * 0x28))) -#define USTORM_RX_PRODS_OFFSET(port, client_id) \ - (IS_E1H_OFFSET ? (0x1000 + (port * 0x680) + (client_id * 0x40)) \ - : (0x4000 + (port * 0x360) + (client_id * 0x30))) -#define USTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x29f0 + (function * 0x8)) : (0x1db8 + \ - (function * 0x8))) -#define USTORM_TPA_BTR_OFFSET (IS_E1H_OFFSET ? 0x3da5 : 0x5095) -#define USTORM_TPA_BTR_SIZE 0x1 -#define XSTORM_ASSERT_LIST_INDEX_OFFSET \ - (IS_E1H_OFFSET ? 0x9000 : 0x1000) -#define XSTORM_ASSERT_LIST_OFFSET(idx) \ - (IS_E1H_OFFSET ? (0x9020 + (idx * 0x10)) : (0x1020 + (idx * 0x10))) -#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x24a8 + (port * 0x50)) : (0x3a80 + (port * 0x50))) -#define XSTORM_DEF_SB_HC_DISABLE_OFFSET(function, index) \ - (IS_E1H_OFFSET ? (0xa01a + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0) + (index * 0x4)) : (0x141a + (function * \ - 0x28) + (index * 0x4))) -#define XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xa000 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1400 + (function * 0x28))) -#define XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(function) \ - (IS_E1H_OFFSET ? (0xa008 + ((function>>1) * 0x28) + \ - ((function&1) * 0xa0)) : (0x1408 + (function * 0x28))) -#define XSTORM_E1HOV_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2c10 + (function * 0x8)) : 0xffffffff) -#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2418 + (function * 0x8)) : (0x3a50 + \ - (function * 0x8))) -#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2588 + (function * 0x90)) : (0x3b60 + \ - (function * 0x90))) -#define XSTORM_FUNCTION_MODE_OFFSET \ - (IS_E1H_OFFSET ? 0x2c50 : 0xffffffff) -#define XSTORM_HC_BTR_OFFSET(port) \ - (IS_E1H_OFFSET ? (0xa144 + (port * 0x30)) : (0x1454 + (port * 0x18))) -#define XSTORM_ISCSI_HQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c0 + (function * 0x8)) : (0x1c30 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8080 + (function * 0x8)) : (0x1c20 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8081 + (function * 0x8)) : (0x1c21 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8082 + (function * 0x8)) : (0x1c22 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8083 + (function * 0x8)) : (0x1c23 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8084 + (function * 0x8)) : (0x1c24 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8085 + (function * 0x8)) : (0x1c25 + \ - (function * 0x8))) -#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8086 + (function * 0x8)) : (0x1c26 + \ - (function * 0x8))) -#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8004 + (function * 0x8)) : (0x1c04 + \ - (function * 0x8))) -#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8002 + (function * 0x8)) : (0x1c02 + \ - (function * 0x8))) -#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8000 + (function * 0x8)) : (0x1c00 + \ - (function * 0x8))) -#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c4 + (function * 0x8)) : (0x1c34 + \ - (function * 0x8))) -#define XSTORM_ISCSI_SQ_SIZE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x80c2 + (function * 0x8)) : (0x1c32 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8043 + (function * 0x8)) : (0x1c13 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8042 + (function * 0x8)) : (0x1c12 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8041 + (function * 0x8)) : (0x1c11 + \ - (function * 0x8))) -#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x8040 + (function * 0x8)) : (0x1c10 + \ - (function * 0x8))) -#define XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stats_counter_id) \ - (IS_E1H_OFFSET ? (0xc000 + (port * 0x360) + (stats_counter_id * \ - 0x30)) : (0x3378 + (port * 0x360) + (stats_counter_id * 0x30))) -#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2548 + (function * 0x90)) : (0x3b20 + \ - (function * 0x90))) -#define XSTORM_SPQ_PAGE_BASE_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2000 + (function * 0x10)) : (0x3328 + \ - (function * 0x10))) -#define XSTORM_SPQ_PROD_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x2008 + (function * 0x10)) : (0x3330 + \ - (function * 0x10))) -#define XSTORM_STATS_FLAGS_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x23d8 + (function * 0x8)) : (0x3a40 + \ - (function * 0x8))) -#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x4000 + (port * 0x8)) : (0x1960 + (port * 0x8))) -#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port) \ - (IS_E1H_OFFSET ? (0x4001 + (port * 0x8)) : (0x1961 + (port * 0x8))) -#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(function) \ - (IS_E1H_OFFSET ? (0x4060 + ((function>>1) * 0x8) + ((function&1) \ - * 0x4)) : (0x1978 + (function * 0x4))) + (IRO[105].base) +#define TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[96].base + ((pfId) * IRO[96].m1)) +#define TSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[101].base + ((funcId) * IRO[101].m1)) +#define TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(pfId) \ + (IRO[195].base + ((pfId) * IRO[195].m1)) +#define TSTORM_FUNCTION_MODE_OFFSET (IRO[103].base) +#define TSTORM_INDIRECTION_TABLE_OFFSET(pfId) \ + (IRO[91].base + ((pfId) * IRO[91].m1)) +#define TSTORM_INDIRECTION_TABLE_SIZE (IRO[91].size) + #define \ + TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfId, iscsiConBufPblEntry) \ + (IRO[260].base + ((pfId) * IRO[260].m1) + ((iscsiConBufPblEntry) \ + * IRO[260].m2)) +#define TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ + (IRO[264].base + ((pfId) * IRO[264].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_CID_TABLE_OFFSET(pfId) \ + (IRO[265].base + ((pfId) * IRO[265].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_CLIENT_ID_TABLE_OFFSET(pfId) \ + (IRO[266].base + ((pfId) * IRO[266].m1)) +#define TSTORM_ISCSI_L2_ISCSI_OOO_PROD_OFFSET(pfId) \ + (IRO[267].base + ((pfId) * IRO[267].m1)) +#define TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[263].base + ((pfId) * IRO[263].m1)) +#define TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[262].base + ((pfId) * IRO[262].m1)) +#define TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[261].base + ((pfId) * IRO[261].m1)) +#define TSTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ + (IRO[259].base + ((pfId) * IRO[259].m1)) +#define TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfId) \ + (IRO[269].base + ((pfId) * IRO[269].m1)) +#define TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ + (IRO[256].base + ((pfId) * IRO[256].m1)) +#define TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ + (IRO[257].base + ((pfId) * IRO[257].m1)) +#define TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfId) \ + (IRO[258].base + ((pfId) * IRO[258].m1)) +#define TSTORM_MAC_FILTER_CONFIG_OFFSET(pfId) \ + (IRO[196].base + ((pfId) * IRO[196].m1)) + #define TSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, tStatCntId) \ + (IRO[100].base + ((portId) * IRO[100].m1) + ((tStatCntId) * \ + IRO[100].m2)) +#define TSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[95].base + ((pfId) * IRO[95].m1)) +#define TSTORM_TCP_MAX_CWND_OFFSET(pfId) \ + (IRO[211].base + ((pfId) * IRO[211].m1)) +#define TSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[102].base + ((funcId) * IRO[102].m1)) +#define USTORM_AGG_DATA_OFFSET (IRO[201].base) +#define USTORM_AGG_DATA_SIZE (IRO[201].size) +#define USTORM_ASSERT_LIST_INDEX_OFFSET (IRO[170].base) +#define USTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[169].base + ((assertListEntry) * IRO[169].m1)) +#define USTORM_ETH_PAUSE_ENABLED_OFFSET(portId) \ + (IRO[178].base + ((portId) * IRO[178].m1)) +#define USTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[172].base + ((pfId) * IRO[172].m1)) +#define USTORM_FCOE_EQ_PROD_OFFSET(pfId) \ + (IRO[313].base + ((pfId) * IRO[313].m1)) +#define USTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[174].base + ((funcId) * IRO[174].m1)) +#define USTORM_FUNCTION_MODE_OFFSET (IRO[177].base) +#define USTORM_ISCSI_CQ_SIZE_OFFSET(pfId) \ + (IRO[277].base + ((pfId) * IRO[277].m1)) +#define USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfId) \ + (IRO[278].base + ((pfId) * IRO[278].m1)) +#define USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfId) \ + (IRO[282].base + ((pfId) * IRO[282].m1)) +#define USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfId) \ + (IRO[279].base + ((pfId) * IRO[279].m1)) +#define USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[275].base + ((pfId) * IRO[275].m1)) +#define USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[274].base + ((pfId) * IRO[274].m1)) +#define USTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[273].base + ((pfId) * IRO[273].m1)) +#define USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ + (IRO[276].base + ((pfId) * IRO[276].m1)) +#define USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfId) \ + (IRO[280].base + ((pfId) * IRO[280].m1)) +#define USTORM_ISCSI_RQ_SIZE_OFFSET(pfId) \ + (IRO[281].base + ((pfId) * IRO[281].m1)) +#define USTORM_MEM_WORKAROUND_ADDRESS_OFFSET(pfId) \ + (IRO[176].base + ((pfId) * IRO[176].m1)) + #define USTORM_PER_COUNTER_ID_STATS_OFFSET(portId, uStatCntId) \ + (IRO[173].base + ((portId) * IRO[173].m1) + ((uStatCntId) * \ + IRO[173].m2)) + #define USTORM_RX_PRODS_E1X_OFFSET(portId, clientId) \ + (IRO[204].base + ((portId) * IRO[204].m1) + ((clientId) * \ + IRO[204].m2)) +#define USTORM_RX_PRODS_E2_OFFSET(qzoneId) \ + (IRO[205].base + ((qzoneId) * IRO[205].m1)) +#define USTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[171].base + ((pfId) * IRO[171].m1)) +#define USTORM_TPA_BTR_OFFSET (IRO[202].base) +#define USTORM_TPA_BTR_SIZE (IRO[202].size) +#define USTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[175].base + ((funcId) * IRO[175].m1)) +#define XSTORM_AGG_INT_FINAL_CLEANUP_COMP_TYPE (IRO[59].base) +#define XSTORM_AGG_INT_FINAL_CLEANUP_INDEX (IRO[58].base) +#define XSTORM_ASSERT_LIST_INDEX_OFFSET (IRO[54].base) +#define XSTORM_ASSERT_LIST_OFFSET(assertListEntry) \ + (IRO[53].base + ((assertListEntry) * IRO[53].m1)) +#define XSTORM_CMNG_PER_PORT_VARS_OFFSET(portId) \ + (IRO[47].base + ((portId) * IRO[47].m1)) +#define XSTORM_E1HOV_OFFSET(pfId) \ + (IRO[55].base + ((pfId) * IRO[55].m1)) +#define XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(pfId) \ + (IRO[45].base + ((pfId) * IRO[45].m1)) +#define XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(pfId) \ + (IRO[49].base + ((pfId) * IRO[49].m1)) +#define XSTORM_FUNC_EN_OFFSET(funcId) \ + (IRO[51].base + ((funcId) * IRO[51].m1)) +#define XSTORM_FUNCTION_MODE_OFFSET (IRO[56].base) +#define XSTORM_ISCSI_HQ_SIZE_OFFSET(pfId) \ + (IRO[290].base + ((pfId) * IRO[290].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfId) \ + (IRO[293].base + ((pfId) * IRO[293].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfId) \ + (IRO[294].base + ((pfId) * IRO[294].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfId) \ + (IRO[295].base + ((pfId) * IRO[295].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfId) \ + (IRO[296].base + ((pfId) * IRO[296].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfId) \ + (IRO[297].base + ((pfId) * IRO[297].m1)) +#define XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfId) \ + (IRO[298].base + ((pfId) * IRO[298].m1)) +#define XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfId) \ + (IRO[299].base + ((pfId) * IRO[299].m1)) +#define XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfId) \ + (IRO[289].base + ((pfId) * IRO[289].m1)) +#define XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfId) \ + (IRO[288].base + ((pfId) * IRO[288].m1)) +#define XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfId) \ + (IRO[287].base + ((pfId) * IRO[287].m1)) +#define XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfId) \ + (IRO[292].base + ((pfId) * IRO[292].m1)) +#define XSTORM_ISCSI_SQ_SIZE_OFFSET(pfId) \ + (IRO[291].base + ((pfId) * IRO[291].m1)) +#define XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfId) \ + (IRO[286].base + ((pfId) * IRO[286].m1)) +#define XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(pfId) \ + (IRO[285].base + ((pfId) * IRO[285].m1)) +#define XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfId) \ + (IRO[284].base + ((pfId) * IRO[284].m1)) +#define XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfId) \ + (IRO[283].base + ((pfId) * IRO[283].m1)) +#define XSTORM_PATH_ID_OFFSET (IRO[65].base) + #define XSTORM_PER_COUNTER_ID_STATS_OFFSET(portId, xStatCntId) \ + (IRO[50].base + ((portId) * IRO[50].m1) + ((xStatCntId) * \ + IRO[50].m2)) +#define XSTORM_RATE_SHAPING_PER_VN_VARS_OFFSET(pfId) \ + (IRO[48].base + ((pfId) * IRO[48].m1)) +#define XSTORM_SPQ_DATA_OFFSET(funcId) \ + (IRO[32].base + ((funcId) * IRO[32].m1)) +#define XSTORM_SPQ_DATA_SIZE (IRO[32].size) +#define XSTORM_SPQ_PAGE_BASE_OFFSET(funcId) \ + (IRO[30].base + ((funcId) * IRO[30].m1)) +#define XSTORM_SPQ_PROD_OFFSET(funcId) \ + (IRO[31].base + ((funcId) * IRO[31].m1)) +#define XSTORM_STATS_FLAGS_OFFSET(pfId) \ + (IRO[43].base + ((pfId) * IRO[43].m1)) +#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(portId) \ + (IRO[206].base + ((portId) * IRO[206].m1)) +#define XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(portId) \ + (IRO[207].base + ((portId) * IRO[207].m1)) +#define XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfId) \ + (IRO[209].base + (((pfId)>>1) * IRO[209].m1) + (((pfId)&1) * \ + IRO[209].m2)) +#define XSTORM_VF_TO_PF_OFFSET(funcId) \ + (IRO[52].base + ((funcId) * IRO[52].m1)) #define COMMON_ASM_INVALID_ASSERT_OPCODE 0x0 -/** -* This file defines HSI constants for the ETH flow -*/ -#ifdef _EVEREST_MICROCODE -#include "microcode_constants.h" -#include "eth_rx_bd.h" -#include "eth_tx_bd.h" -#include "eth_rx_cqe.h" -#include "eth_rx_sge.h" -#include "eth_rx_cqe_next_page.h" -#endif - /* RSS hash types */ #define DEFAULT_HASH_TYPE 0 #define IPV4_HASH_TYPE 1 @@ -389,11 +292,17 @@ #define U_ETH_NUM_OF_SGES_TO_FETCH 8 #define U_ETH_MAX_SGES_FOR_PACKET 3 +/*Tx params*/ +#define X_ETH_NO_VLAN 0 +#define X_ETH_OUTBAND_VLAN 1 +#define X_ETH_INBAND_VLAN 2 /* Rx ring params */ #define U_ETH_LOCAL_BD_RING_SIZE 8 #define U_ETH_LOCAL_SGE_RING_SIZE 10 #define U_ETH_SGL_SIZE 8 - + /* The fw will padd the buffer with this value, so the IP header \ + will be align to 4 Byte */ +#define IP_HEADER_ALIGNMENT_PADDING 2 #define U_ETH_SGES_PER_PAGE_INVERSE_MASK \ (0xFFFF - ((PAGE_SIZE/((STRUCT_SIZE(eth_rx_sge))/8))-1)) @@ -409,16 +318,15 @@ #define U_ETH_UNDEFINED_Q 0xFF /* values of command IDs in the ramrod message */ -#define RAMROD_CMD_ID_ETH_PORT_SETUP 80 -#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 85 -#define RAMROD_CMD_ID_ETH_STAT_QUERY 90 -#define RAMROD_CMD_ID_ETH_UPDATE 100 -#define RAMROD_CMD_ID_ETH_HALT 105 -#define RAMROD_CMD_ID_ETH_SET_MAC 110 -#define RAMROD_CMD_ID_ETH_CFC_DEL 115 -#define RAMROD_CMD_ID_ETH_PORT_DEL 120 -#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 125 - +#define RAMROD_CMD_ID_ETH_UNUSED 0 +#define RAMROD_CMD_ID_ETH_CLIENT_SETUP 1 +#define RAMROD_CMD_ID_ETH_UPDATE 2 +#define RAMROD_CMD_ID_ETH_HALT 3 +#define RAMROD_CMD_ID_ETH_FORWARD_SETUP 4 +#define RAMROD_CMD_ID_ETH_ACTIVATE 5 +#define RAMROD_CMD_ID_ETH_DEACTIVATE 6 +#define RAMROD_CMD_ID_ETH_EMPTY 7 +#define RAMROD_CMD_ID_ETH_TERMINATE 8 /* command values for set mac command */ #define T_ETH_MAC_COMMAND_SET 0 @@ -431,7 +339,9 @@ /* Maximal L2 clients supported */ #define ETH_MAX_RX_CLIENTS_E1 18 -#define ETH_MAX_RX_CLIENTS_E1H 26 +#define ETH_MAX_RX_CLIENTS_E1H 28 + +#define MAX_STAT_COUNTER_ID ETH_MAX_RX_CLIENTS_E1H /* Maximal aggregation queues supported */ #define ETH_MAX_AGGREGATION_QUEUES_E1 32 @@ -443,6 +353,20 @@ #define ETH_RSS_MODE_VLAN_PRI 2 #define ETH_RSS_MODE_E1HOV_PRI 3 #define ETH_RSS_MODE_IP_DSCP 4 +#define ETH_RSS_MODE_E2_INTEG 5 + + +/* ETH vlan filtering modes */ +#define ETH_VLAN_FILTER_ANY_VLAN 0 /* Don't filter by vlan */ +#define ETH_VLAN_FILTER_SPECIFIC_VLAN \ + 1 /* Only the vlan_id is allowed */ +#define ETH_VLAN_FILTER_CLASSIFY \ + 2 /* vlan will be added to CAM for classification */ + +/* Fast path CQE selection */ +#define ETH_FP_CQE_REGULAR 0 +#define ETH_FP_CQE_SGL 1 +#define ETH_FP_CQE_RAW 2 /** @@ -458,6 +382,7 @@ #define RESERVED_CONNECTION_TYPE_0 5 #define RESERVED_CONNECTION_TYPE_1 6 #define RESERVED_CONNECTION_TYPE_2 7 +#define NONE_CONNECTION_TYPE 8 #define PROTOCOL_STATE_BIT_OFFSET 6 @@ -466,6 +391,16 @@ #define TOE_STATE (TOE_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET) #define RDMA_STATE (RDMA_CONNECTION_TYPE << PROTOCOL_STATE_BIT_OFFSET) +/* values of command IDs in the ramrod message */ +#define RAMROD_CMD_ID_COMMON_FUNCTION_START 1 +#define RAMROD_CMD_ID_COMMON_FUNCTION_STOP 2 +#define RAMROD_CMD_ID_COMMON_CFC_DEL 3 +#define RAMROD_CMD_ID_COMMON_CFC_DEL_WB 4 +#define RAMROD_CMD_ID_COMMON_SET_MAC 5 +#define RAMROD_CMD_ID_COMMON_STAT_QUERY 6 +#define RAMROD_CMD_ID_COMMON_STOP_TRAFFIC 7 +#define RAMROD_CMD_ID_COMMON_START_TRAFFIC 8 + /* microcode fixed page page size 4K (chains and ring segments) */ #define MC_PAGE_SIZE 4096 @@ -473,46 +408,26 @@ /* Host coalescing constants */ #define HC_IGU_BC_MODE 0 #define HC_IGU_NBC_MODE 1 +/* Host coalescing constants. E1 includes E1H as well */ + +/* Number of indices per slow-path SB */ +#define HC_SP_SB_MAX_INDICES 16 + +/* Number of indices per SB */ +#define HC_SB_MAX_INDICES_E1X 8 +#define HC_SB_MAX_INDICES_E2 8 + +#define HC_SB_MAX_SB_E1X 32 +#define HC_SB_MAX_SB_E2 136 + +#define HC_SP_SB_ID 0xde #define HC_REGULAR_SEGMENT 0 #define HC_DEFAULT_SEGMENT 1 +#define HC_SB_MAX_SM 2 -/* index numbers */ -#define HC_USTORM_DEF_SB_NUM_INDICES 8 -#define HC_CSTORM_DEF_SB_NUM_INDICES 8 -#define HC_XSTORM_DEF_SB_NUM_INDICES 4 -#define HC_TSTORM_DEF_SB_NUM_INDICES 4 -#define HC_USTORM_SB_NUM_INDICES 4 -#define HC_CSTORM_SB_NUM_INDICES 4 - -/* index values - which counter to update */ - -#define HC_INDEX_U_TOE_RX_CQ_CONS 0 -#define HC_INDEX_U_ETH_RX_CQ_CONS 1 -#define HC_INDEX_U_ETH_RX_BD_CONS 2 -#define HC_INDEX_U_FCOE_EQ_CONS 3 - -#define HC_INDEX_C_TOE_TX_CQ_CONS 0 -#define HC_INDEX_C_ETH_TX_CQ_CONS 1 -#define HC_INDEX_C_ISCSI_EQ_CONS 2 - -#define HC_INDEX_DEF_X_SPQ_CONS 0 - -#define HC_INDEX_DEF_C_RDMA_EQ_CONS 0 -#define HC_INDEX_DEF_C_RDMA_NAL_PROD 1 -#define HC_INDEX_DEF_C_ETH_FW_TX_CQ_CONS 2 -#define HC_INDEX_DEF_C_ETH_SLOW_PATH 3 -#define HC_INDEX_DEF_C_ETH_RDMA_CQ_CONS 4 -#define HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS 5 -#define HC_INDEX_DEF_C_ETH_FCOE_CQ_CONS 6 - -#define HC_INDEX_DEF_U_ETH_RDMA_RX_CQ_CONS 0 -#define HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS 1 -#define HC_INDEX_DEF_U_ETH_RDMA_RX_BD_CONS 2 -#define HC_INDEX_DEF_U_ETH_ISCSI_RX_BD_CONS 3 -#define HC_INDEX_DEF_U_ETH_FCOE_RX_CQ_CONS 4 -#define HC_INDEX_DEF_U_ETH_FCOE_RX_BD_CONS 5 - +#define HC_SB_MAX_DYNAMIC_INDICES 4 +#define HC_FUNCTION_DISABLED 0xff /* used by the driver to get the SB offset */ #define USTORM_ID 0 #define CSTORM_ID 1 @@ -529,45 +444,17 @@ /**** DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/ -#define EMULATION_FREQUENCY_FACTOR 1600 -#define FPGA_FREQUENCY_FACTOR 100 #define TIMERS_TICK_SIZE_CHIP (1e-3) -#define TIMERS_TICK_SIZE_EMUL \ - ((TIMERS_TICK_SIZE_CHIP)/((EMULATION_FREQUENCY_FACTOR))) -#define TIMERS_TICK_SIZE_FPGA \ - ((TIMERS_TICK_SIZE_CHIP)/((FPGA_FREQUENCY_FACTOR))) #define TSEMI_CLK1_RESUL_CHIP (1e-3) -#define TSEMI_CLK1_RESUL_EMUL \ - ((TSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define TSEMI_CLK1_RESUL_FPGA \ - ((TSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - -#define USEMI_CLK1_RESUL_CHIP (TIMERS_TICK_SIZE_CHIP) -#define USEMI_CLK1_RESUL_EMUL (TIMERS_TICK_SIZE_EMUL) -#define USEMI_CLK1_RESUL_FPGA (TIMERS_TICK_SIZE_FPGA) #define XSEMI_CLK1_RESUL_CHIP (1e-3) -#define XSEMI_CLK1_RESUL_EMUL \ - ((XSEMI_CLK1_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define XSEMI_CLK1_RESUL_FPGA \ - ((XSEMI_CLK1_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - -#define XSEMI_CLK2_RESUL_CHIP (1e-6) -#define XSEMI_CLK2_RESUL_EMUL \ - ((XSEMI_CLK2_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define XSEMI_CLK2_RESUL_FPGA \ - ((XSEMI_CLK2_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) #define SDM_TIMER_TICK_RESUL_CHIP (4*(1e-6)) -#define SDM_TIMER_TICK_RESUL_EMUL \ - ((SDM_TIMER_TICK_RESUL_CHIP)/(EMULATION_FREQUENCY_FACTOR)) -#define SDM_TIMER_TICK_RESUL_FPGA \ - ((SDM_TIMER_TICK_RESUL_CHIP)/(FPGA_FREQUENCY_FACTOR)) - /**** END DEFINES FOR TIMERS/CLOCKS RESOLUTIONS ****/ + #define XSTORM_IP_ID_ROLL_HALF 0x8000 #define XSTORM_IP_ID_ROLL_ALL 0 @@ -576,10 +463,36 @@ #define NUM_OF_PROTOCOLS 4 #define NUM_OF_SAFC_BITS 16 #define MAX_COS_NUMBER 4 -#define MAX_T_STAT_COUNTER_ID 18 -#define MAX_X_STAT_COUNTER_ID 18 -#define MAX_U_STAT_COUNTER_ID 18 +#define FAIRNESS_COS_WRR_MODE 0 +#define FAIRNESS_COS_ETS_MODE 1 + + +/* Priority Flow Control (PFC) */ +#define MAX_PFC_PRIORITIES 8 +#define MAX_PFC_TRAFFIC_TYPES 8 + +/* Available Traffic Types for Link Layer Flow Control */ +#define LLFC_TRAFFIC_TYPE_NW 0 +#define LLFC_TRAFFIC_TYPE_FCOE 1 +#define LLFC_TRAFFIC_TYPE_ISCSI 2 + /***************** START OF E2 INTEGRATION \ + CODE***************************************/ +#define LLFC_TRAFFIC_TYPE_NW_COS1_E2INTEG 3 + /***************** END OF E2 INTEGRATION \ + CODE***************************************/ +#define LLFC_TRAFFIC_TYPE_MAX 4 + + /* used by array traffic_type_to_priority[] to mark traffic type \ + that is not mapped to priority*/ +#define LLFC_TRAFFIC_TYPE_TO_PRIORITY_UNMAPPED 0xFF + +#define LLFC_MODE_NONE 0 +#define LLFC_MODE_PFC 1 +#define LLFC_MODE_SAFC 2 + +#define DCB_DISABLED 0 +#define DCB_ENABLED 1 #define UNKNOWN_ADDRESS 0 #define UNICAST_ADDRESS 1 @@ -587,8 +500,32 @@ #define BROADCAST_ADDRESS 3 #define SINGLE_FUNCTION 0 -#define MULTI_FUNCTION 1 +#define MULTI_FUNCTION_SD 1 +#define MULTI_FUNCTION_SI 2 #define IP_V4 0 #define IP_V6 1 + +#define C_ERES_PER_PAGE \ + (PAGE_SIZE / BITS_TO_BYTES(STRUCT_SIZE(event_ring_elem))) +#define C_ERE_PER_PAGE_MASK (C_ERES_PER_PAGE - 1) + +#define EVENT_RING_OPCODE_VF_PF_CHANNEL 0 +#define EVENT_RING_OPCODE_FUNCTION_START 1 +#define EVENT_RING_OPCODE_FUNCTION_STOP 2 +#define EVENT_RING_OPCODE_CFC_DEL 3 +#define EVENT_RING_OPCODE_CFC_DEL_WB 4 +#define EVENT_RING_OPCODE_SET_MAC 5 +#define EVENT_RING_OPCODE_STAT_QUERY 6 +#define EVENT_RING_OPCODE_STOP_TRAFFIC 7 +#define EVENT_RING_OPCODE_START_TRAFFIC 8 +#define EVENT_RING_OPCODE_FORWARD_SETUP 9 + +#define VF_PF_CHANNEL_STATE_READY 0 +#define VF_PF_CHANNEL_STATE_WAITING_FOR_ACK 1 + +#define VF_PF_CHANNEL_STATE_MAX_NUMBER 2 + + +#endif /* BNX2X_FW_DEFS_H */ diff --git a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h index 3f5ee5d7cc2ae0d38d66e5302ac3da8e9a4d15d8..f807262911e5617bc4a8496a8f1f2ba7d5f654c8 100644 --- a/drivers/net/bnx2x/bnx2x_fw_file_hdr.h +++ b/drivers/net/bnx2x/bnx2x_fw_file_hdr.h @@ -31,6 +31,7 @@ struct bnx2x_fw_file_hdr { struct bnx2x_fw_file_section csem_pram_data; struct bnx2x_fw_file_section xsem_int_table_data; struct bnx2x_fw_file_section xsem_pram_data; + struct bnx2x_fw_file_section iro_arr; struct bnx2x_fw_file_section fw_version; }; diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index fd1f29e0317d6b9c2c90798336d69073ad370a2d..18c8e23a0e82fafaabe0183700960a194c9524af 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -6,6 +6,10 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. */ +#ifndef BNX2X_HSI_H +#define BNX2X_HSI_H + +#include "bnx2x_fw_defs.h" struct license_key { u32 reserved[6]; @@ -78,6 +82,8 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_LED_PHY11 0x000b0000 #define SHARED_HW_CFG_LED_MAC4 0x000c0000 #define SHARED_HW_CFG_LED_PHY8 0x000d0000 +#define SHARED_HW_CFG_LED_EXTPHY1 0x000e0000 + #define SHARED_HW_CFG_AN_ENABLE_MASK 0x3f000000 #define SHARED_HW_CFG_AN_ENABLE_SHIFT 24 @@ -120,6 +126,23 @@ struct shared_hw_cfg { /* NVRAM Offset */ #define SHARED_HW_CFG_FAN_FAILURE_DISABLED 0x00080000 #define SHARED_HW_CFG_FAN_FAILURE_ENABLED 0x00100000 + /* Set the MDC/MDIO access for the first external phy */ +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK 0x1C000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT 26 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE 0x00000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0 0x04000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1 0x08000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH 0x0c000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED 0x10000000 + + /* Set the MDC/MDIO access for the second external phy */ +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK 0xE0000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT 29 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_PHY_TYPE 0x00000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_EMAC0 0x20000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_EMAC1 0x40000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_BOTH 0x60000000 +#define SHARED_HW_CFG_MDC_MDIO_ACCESS2_SWAPPED 0x80000000 u32 power_dissipated; /* 0x11c */ #define SHARED_HW_CFG_POWER_DIS_CMN_MASK 0xff000000 #define SHARED_HW_CFG_POWER_DIS_CMN_SHIFT 24 @@ -221,11 +244,93 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u16 xgxs_config_tx[4]; /* 0x1A0 */ - u32 Reserved1[64]; /* 0x1A8 */ + u32 Reserved1[57]; /* 0x1A8 */ + u32 speed_capability_mask2; /* 0x28C */ +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10M_FULL 0x00000001 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3__ 0x00000002 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3___ 0x00000004 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_100M_FULL 0x00000008 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_1G 0x00000010 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_2_DOT_5G 0x00000020 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_10G 0x00000040 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12G 0x00000080 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_12_DOT_5G 0x00000100 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_13G 0x00000200 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_15G 0x00000400 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D3_16G 0x00000800 + +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_MASK 0xFFFF0000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_SHIFT 16 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10M_FULL 0x00010000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0__ 0x00020000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0___ 0x00040000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_100M_FULL 0x00080000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_1G 0x00100000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_2_DOT_5G 0x00200000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_10G 0x00400000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12G 0x00800000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_12_DOT_5G 0x01000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_13G 0x02000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_15G 0x04000000 +#define PORT_HW_CFG_SPEED_CAPABILITY2_D0_16G 0x08000000 + + /* In the case where two media types (e.g. copper and fiber) are + present and electrically active at the same time, PHY Selection + will determine which of the two PHYs will be designated as the + Active PHY and used for a connection to the network. */ + u32 multi_phy_config; /* 0x290 */ +#define PORT_HW_CFG_PHY_SELECTION_MASK 0x00000007 +#define PORT_HW_CFG_PHY_SELECTION_SHIFT 0 +#define PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT 0x00000000 +#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY 0x00000001 +#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY 0x00000002 +#define PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY 0x00000003 +#define PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY 0x00000004 + + /* When enabled, all second phy nvram parameters will be swapped + with the first phy parameters */ +#define PORT_HW_CFG_PHY_SWAPPED_MASK 0x00000008 +#define PORT_HW_CFG_PHY_SWAPPED_SHIFT 3 +#define PORT_HW_CFG_PHY_SWAPPED_DISABLED 0x00000000 +#define PORT_HW_CFG_PHY_SWAPPED_ENABLED 0x00000008 + + + /* Address of the second external phy */ + u32 external_phy_config2; /* 0x294 */ +#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_MASK 0x000000FF +#define PORT_HW_CFG_XGXS_EXT_PHY2_ADDR_SHIFT 0 + + /* The second XGXS external PHY type */ +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_MASK 0x0000FF00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SHIFT 8 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_DIRECT 0x00000000 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8071 0x00000100 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8072 0x00000200 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8073 0x00000300 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8705 0x00000400 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8706 0x00000500 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8726 0x00000600 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8481 0x00000700 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_SFX7101 0x00000800 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727 0x00000900 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM8727_NOC 0x00000a00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84823 0x00000b00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM54640 0x00000c00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_BCM84833 0x00000d00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_FAILURE 0x0000fd00 +#define PORT_HW_CFG_XGXS_EXT_PHY2_TYPE_NOT_CONN 0x0000ff00 + + /* 4 times 16 bits for all 4 lanes. For some external PHYs (such as + 8706, 8726 and 8727) not all 4 values are needed. */ + u16 xgxs_config2_rx[4]; /* 0x296 */ + u16 xgxs_config2_tx[4]; /* 0x2A0 */ u32 lane_config; #define PORT_HW_CFG_LANE_SWAP_CFG_MASK 0x0000ffff #define PORT_HW_CFG_LANE_SWAP_CFG_SHIFT 0 + #define PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK 0x000000ff #define PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT 0 #define PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK 0x0000ff00 @@ -515,10 +620,17 @@ struct port_feat_cfg { /* port 0: 0x454 port 1: 0x4c8 */ #define PORT_FEATURE_FLOW_CONTROL_NONE 0x00000400 /* The default for MCP link configuration, - uses the same defines as link_config */ + uses the same defines as link_config */ u32 mfw_wol_link_cfg; + /* The default for the driver of the second external phy, + uses the same defines as link_config */ + u32 link_config2; /* 0x47C */ + + /* The default for MCP of the second external phy, + uses the same defines as link_config */ + u32 mfw_wol_link_cfg2; /* 0x480 */ - u32 reserved[19]; + u32 Reserved2[17]; /* 0x484 */ }; @@ -551,6 +663,7 @@ struct shm_dev_info { /* size */ #define FUNC_7 7 #define E1_FUNC_MAX 2 #define E1H_FUNC_MAX 8 +#define E2_FUNC_MAX 4 /* per path */ #define VN_0 0 #define VN_1 1 @@ -686,8 +799,14 @@ struct drv_func_mb { * The optic module verification commands require bootcode * v5.0.6 or later */ -#define DRV_MSG_CODE_VRFY_OPT_MDL 0xa0000000 -#define REQ_BC_VER_4_VRFY_OPT_MDL 0x00050006 +#define DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL 0xa0000000 +#define REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL 0x00050006 + /* + * The specific optic module verification command requires bootcode + * v5.2.12 or later + */ +#define DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL 0xa1000000 +#define REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL 0x00050234 #define BIOS_MSG_CODE_LIC_CHALLENGE 0xff010000 #define BIOS_MSG_CODE_LIC_RESPONSE 0xff020000 @@ -703,6 +822,9 @@ struct drv_func_mb { #define FW_MSG_CODE_DRV_LOAD_COMMON 0x10100000 #define FW_MSG_CODE_DRV_LOAD_PORT 0x10110000 #define FW_MSG_CODE_DRV_LOAD_FUNCTION 0x10120000 + /* Load common chip is supported from bc 6.0.0 */ +#define REQ_BC_VER_4_DRV_LOAD_COMMON_CHIP 0x00060000 +#define FW_MSG_CODE_DRV_LOAD_COMMON_CHIP 0x10130000 #define FW_MSG_CODE_DRV_LOAD_REFUSED 0x10200000 #define FW_MSG_CODE_DRV_LOAD_DONE 0x11100000 #define FW_MSG_CODE_DRV_UNLOAD_COMMON 0x20100000 @@ -903,11 +1025,22 @@ struct shmem_region { /* SharedMem Offset (size) */ struct mgmtfw_state mgmtfw_state; /* 0x4ac (0x1b8) */ struct drv_port_mb port_mb[PORT_MAX]; /* 0x664 (16*2=0x20) */ - struct drv_func_mb func_mb[E1H_FUNC_MAX]; + struct drv_func_mb func_mb[]; /* 0x684 + (44*2/4/8=0x58/0xb0/0x160) */ - struct mf_cfg mf_cfg; +}; /* 57710 = 0x6dc | 57711 = 0x7E4 | 57712 = 0x734 */ + +struct fw_flr_ack { + u32 pf_ack; + u32 vf_ack[1]; + u32 iov_dis_ack; +}; -}; /* 0x6dc */ +struct fw_flr_mb { + u32 aggint; + u32 opgen_addr; + struct fw_flr_ack ack; +}; struct shmem2_region { @@ -922,7 +1055,25 @@ struct shmem2_region { #define SHMEM_DCC_SUPPORT_SET_PROTOCOL_TLV 0x00000040 #define SHMEM_DCC_SUPPORT_SET_PRIORITY_TLV 0x00000080 #define SHMEM_DCC_SUPPORT_DEFAULT SHMEM_DCC_SUPPORT_NONE - + u32 ext_phy_fw_version2[PORT_MAX]; + /* + * For backwards compatibility, if the mf_cfg_addr does not exist + * (the size filed is smaller than 0xc) the mf_cfg resides at the + * end of struct shmem_region + */ + u32 mf_cfg_addr; +#define SHMEM_MF_CFG_ADDR_NONE 0x00000000 + + struct fw_flr_mb flr_mb; + u32 reserved[3]; + /* + * The other shmemX_base_addr holds the other path's shmem address + * required for example in case of common phy init, or for path1 to know + * the address of mcp debug trace which is located in offset from shmem + * of path0 + */ + u32 other_shmem_base_addr; + u32 other_shmem2_base_addr; }; @@ -978,7 +1129,7 @@ struct emac_stats { }; -struct bmac_stats { +struct bmac1_stats { u32 tx_stat_gtpkt_lo; u32 tx_stat_gtpkt_hi; u32 tx_stat_gtxpf_lo; @@ -1082,10 +1233,126 @@ struct bmac_stats { u32 rx_stat_gripj_hi; }; +struct bmac2_stats { + u32 tx_stat_gtpk_lo; /* gtpok */ + u32 tx_stat_gtpk_hi; /* gtpok */ + u32 tx_stat_gtxpf_lo; /* gtpf */ + u32 tx_stat_gtxpf_hi; /* gtpf */ + u32 tx_stat_gtpp_lo; /* NEW BMAC2 */ + u32 tx_stat_gtpp_hi; /* NEW BMAC2 */ + u32 tx_stat_gtfcs_lo; + u32 tx_stat_gtfcs_hi; + u32 tx_stat_gtuca_lo; /* NEW BMAC2 */ + u32 tx_stat_gtuca_hi; /* NEW BMAC2 */ + u32 tx_stat_gtmca_lo; + u32 tx_stat_gtmca_hi; + u32 tx_stat_gtbca_lo; + u32 tx_stat_gtbca_hi; + u32 tx_stat_gtovr_lo; + u32 tx_stat_gtovr_hi; + u32 tx_stat_gtfrg_lo; + u32 tx_stat_gtfrg_hi; + u32 tx_stat_gtpkt1_lo; /* gtpkt */ + u32 tx_stat_gtpkt1_hi; /* gtpkt */ + u32 tx_stat_gt64_lo; + u32 tx_stat_gt64_hi; + u32 tx_stat_gt127_lo; + u32 tx_stat_gt127_hi; + u32 tx_stat_gt255_lo; + u32 tx_stat_gt255_hi; + u32 tx_stat_gt511_lo; + u32 tx_stat_gt511_hi; + u32 tx_stat_gt1023_lo; + u32 tx_stat_gt1023_hi; + u32 tx_stat_gt1518_lo; + u32 tx_stat_gt1518_hi; + u32 tx_stat_gt2047_lo; + u32 tx_stat_gt2047_hi; + u32 tx_stat_gt4095_lo; + u32 tx_stat_gt4095_hi; + u32 tx_stat_gt9216_lo; + u32 tx_stat_gt9216_hi; + u32 tx_stat_gt16383_lo; + u32 tx_stat_gt16383_hi; + u32 tx_stat_gtmax_lo; + u32 tx_stat_gtmax_hi; + u32 tx_stat_gtufl_lo; + u32 tx_stat_gtufl_hi; + u32 tx_stat_gterr_lo; + u32 tx_stat_gterr_hi; + u32 tx_stat_gtbyt_lo; + u32 tx_stat_gtbyt_hi; + + u32 rx_stat_gr64_lo; + u32 rx_stat_gr64_hi; + u32 rx_stat_gr127_lo; + u32 rx_stat_gr127_hi; + u32 rx_stat_gr255_lo; + u32 rx_stat_gr255_hi; + u32 rx_stat_gr511_lo; + u32 rx_stat_gr511_hi; + u32 rx_stat_gr1023_lo; + u32 rx_stat_gr1023_hi; + u32 rx_stat_gr1518_lo; + u32 rx_stat_gr1518_hi; + u32 rx_stat_gr2047_lo; + u32 rx_stat_gr2047_hi; + u32 rx_stat_gr4095_lo; + u32 rx_stat_gr4095_hi; + u32 rx_stat_gr9216_lo; + u32 rx_stat_gr9216_hi; + u32 rx_stat_gr16383_lo; + u32 rx_stat_gr16383_hi; + u32 rx_stat_grmax_lo; + u32 rx_stat_grmax_hi; + u32 rx_stat_grpkt_lo; + u32 rx_stat_grpkt_hi; + u32 rx_stat_grfcs_lo; + u32 rx_stat_grfcs_hi; + u32 rx_stat_gruca_lo; + u32 rx_stat_gruca_hi; + u32 rx_stat_grmca_lo; + u32 rx_stat_grmca_hi; + u32 rx_stat_grbca_lo; + u32 rx_stat_grbca_hi; + u32 rx_stat_grxpf_lo; /* grpf */ + u32 rx_stat_grxpf_hi; /* grpf */ + u32 rx_stat_grpp_lo; + u32 rx_stat_grpp_hi; + u32 rx_stat_grxuo_lo; /* gruo */ + u32 rx_stat_grxuo_hi; /* gruo */ + u32 rx_stat_grjbr_lo; + u32 rx_stat_grjbr_hi; + u32 rx_stat_grovr_lo; + u32 rx_stat_grovr_hi; + u32 rx_stat_grxcf_lo; /* grcf */ + u32 rx_stat_grxcf_hi; /* grcf */ + u32 rx_stat_grflr_lo; + u32 rx_stat_grflr_hi; + u32 rx_stat_grpok_lo; + u32 rx_stat_grpok_hi; + u32 rx_stat_grmeg_lo; + u32 rx_stat_grmeg_hi; + u32 rx_stat_grmeb_lo; + u32 rx_stat_grmeb_hi; + u32 rx_stat_grbyt_lo; + u32 rx_stat_grbyt_hi; + u32 rx_stat_grund_lo; + u32 rx_stat_grund_hi; + u32 rx_stat_grfrg_lo; + u32 rx_stat_grfrg_hi; + u32 rx_stat_grerb_lo; /* grerrbyt */ + u32 rx_stat_grerb_hi; /* grerrbyt */ + u32 rx_stat_grfre_lo; /* grfrerr */ + u32 rx_stat_grfre_hi; /* grfrerr */ + u32 rx_stat_gripj_lo; + u32 rx_stat_gripj_hi; +}; union mac_stats { - struct emac_stats emac_stats; - struct bmac_stats bmac_stats; + struct emac_stats emac_stats; + struct bmac1_stats bmac1_stats; + struct bmac2_stats bmac2_stats; }; @@ -1259,17 +1526,17 @@ struct host_func_stats { }; -#define BCM_5710_FW_MAJOR_VERSION 5 -#define BCM_5710_FW_MINOR_VERSION 2 -#define BCM_5710_FW_REVISION_VERSION 13 -#define BCM_5710_FW_ENGINEERING_VERSION 0 +#define BCM_5710_FW_MAJOR_VERSION 6 +#define BCM_5710_FW_MINOR_VERSION 0 +#define BCM_5710_FW_REVISION_VERSION 34 +#define BCM_5710_FW_ENGINEERING_VERSION 0 #define BCM_5710_FW_COMPILE_FLAGS 1 /* * attention bits */ -struct atten_def_status_block { +struct atten_sp_status_block { __le32 attn_bits; __le32 attn_bits_ack; u8 status_block_id; @@ -1327,7 +1594,60 @@ struct doorbell_set_prod { /* - * IGU driver acknowledgement register + * 3 lines. status block + */ +struct hc_status_block_e1x { + __le16 index_values[HC_SB_MAX_INDICES_E1X]; + __le16 running_index[HC_SB_MAX_SM]; + u32 rsrv; +}; + +/* + * host status block + */ +struct host_hc_status_block_e1x { + struct hc_status_block_e1x sb; +}; + + +/* + * 3 lines. status block + */ +struct hc_status_block_e2 { + __le16 index_values[HC_SB_MAX_INDICES_E2]; + __le16 running_index[HC_SB_MAX_SM]; + u32 reserved; +}; + +/* + * host status block + */ +struct host_hc_status_block_e2 { + struct hc_status_block_e2 sb; +}; + + +/* + * 5 lines. slow-path status block + */ +struct hc_sp_status_block { + __le16 index_values[HC_SP_SB_MAX_INDICES]; + __le16 running_index; + __le16 rsrv; + u32 rsrv1; +}; + +/* + * host status block + */ +struct host_sp_status_block { + struct atten_sp_status_block atten_status_block; + struct hc_sp_status_block sp_sb; +}; + + +/* + * IGU driver acknowledgment register */ struct igu_ack_register { #if defined(__BIG_ENDIAN) @@ -1416,6 +1736,24 @@ union igu_consprod_reg { }; +/* + * Control register for the IGU command register + */ +struct igu_ctrl_reg { + u32 ctrl_data; +#define IGU_CTRL_REG_ADDRESS (0xFFF<<0) +#define IGU_CTRL_REG_ADDRESS_SHIFT 0 +#define IGU_CTRL_REG_FID (0x7F<<12) +#define IGU_CTRL_REG_FID_SHIFT 12 +#define IGU_CTRL_REG_RESERVED (0x1<<19) +#define IGU_CTRL_REG_RESERVED_SHIFT 19 +#define IGU_CTRL_REG_TYPE (0x1<<20) +#define IGU_CTRL_REG_TYPE_SHIFT 20 +#define IGU_CTRL_REG_UNUSED (0x7FF<<21) +#define IGU_CTRL_REG_UNUSED_SHIFT 21 +}; + + /* * Parser parsing flags field */ @@ -1485,8 +1823,14 @@ struct dmae_command { #define DMAE_COMMAND_DST_RESET_SHIFT 14 #define DMAE_COMMAND_E1HVN (0x3<<15) #define DMAE_COMMAND_E1HVN_SHIFT 15 -#define DMAE_COMMAND_RESERVED0 (0x7FFF<<17) -#define DMAE_COMMAND_RESERVED0_SHIFT 17 +#define DMAE_COMMAND_DST_VN (0x3<<17) +#define DMAE_COMMAND_DST_VN_SHIFT 17 +#define DMAE_COMMAND_C_FUNC (0x1<<19) +#define DMAE_COMMAND_C_FUNC_SHIFT 19 +#define DMAE_COMMAND_ERR_POLICY (0x3<<20) +#define DMAE_COMMAND_ERR_POLICY_SHIFT 20 +#define DMAE_COMMAND_RESERVED0 (0x3FF<<22) +#define DMAE_COMMAND_RESERVED0_SHIFT 22 u32 src_addr_lo; u32 src_addr_hi; u32 dst_addr_lo; @@ -1511,11 +1855,11 @@ struct dmae_command { u16 crc16_c; #endif #if defined(__BIG_ENDIAN) - u16 reserved2; + u16 reserved3; u16 crc_t10; #elif defined(__LITTLE_ENDIAN) u16 crc_t10; - u16 reserved2; + u16 reserved3; #endif #if defined(__BIG_ENDIAN) u16 xsum8; @@ -1536,96 +1880,20 @@ struct double_regpair { /* - * The eth storm context of Ustorm (configuration part) + * SDM operation gen command (generate aggregative interrupt) */ -struct ustorm_eth_st_context_config { -#if defined(__BIG_ENDIAN) - u8 flags; -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3 -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4) -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4 - u8 status_block_id; - u8 clientId; - u8 sb_index_numbers; -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4) -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4 -#elif defined(__LITTLE_ENDIAN) - u8 sb_index_numbers; -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER (0xF<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER (0xF<<4) -#define USTORM_ETH_ST_CONTEXT_CONFIG_BD_SB_INDEX_NUMBER_SHIFT 4 - u8 clientId; - u8 status_block_id; - u8 flags; -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT (0x1<<0) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT_SHIFT 0 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC (0x1<<1) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_DYNAMIC_HC_SHIFT 1 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA (0x1<<2) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA_SHIFT 2 -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS (0x1<<3) -#define USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS_SHIFT 3 -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0 (0xF<<4) -#define __USTORM_ETH_ST_CONTEXT_CONFIG_RESERVED0_SHIFT 4 -#endif -#if defined(__BIG_ENDIAN) - u16 bd_buff_size; - u8 statistics_counter_id; - u8 mc_alignment_log_size; -#elif defined(__LITTLE_ENDIAN) - u8 mc_alignment_log_size; - u8 statistics_counter_id; - u16 bd_buff_size; -#endif -#if defined(__BIG_ENDIAN) - u8 __local_sge_prod; - u8 __local_bd_prod; - u16 sge_buff_size; -#elif defined(__LITTLE_ENDIAN) - u16 sge_buff_size; - u8 __local_bd_prod; - u8 __local_sge_prod; -#endif -#if defined(__BIG_ENDIAN) - u16 __sdm_bd_expected_counter; - u8 cstorm_agg_int; - u8 __expected_bds_on_ram; -#elif defined(__LITTLE_ENDIAN) - u8 __expected_bds_on_ram; - u8 cstorm_agg_int; - u16 __sdm_bd_expected_counter; -#endif -#if defined(__BIG_ENDIAN) - u16 __ring_data_ram_addr; - u16 __hc_cstorm_ram_addr; -#elif defined(__LITTLE_ENDIAN) - u16 __hc_cstorm_ram_addr; - u16 __ring_data_ram_addr; -#endif -#if defined(__BIG_ENDIAN) - u8 reserved1; - u8 max_sges_for_packet; - u16 __bd_ring_ram_addr; -#elif defined(__LITTLE_ENDIAN) - u16 __bd_ring_ram_addr; - u8 max_sges_for_packet; - u8 reserved1; -#endif - u32 bd_page_base_lo; - u32 bd_page_base_hi; - u32 sge_page_base_lo; - u32 sge_page_base_hi; - struct regpair reserved2; +struct sdm_op_gen { + __le32 command; +#define SDM_OP_GEN_COMP_PARAM (0x1F<<0) +#define SDM_OP_GEN_COMP_PARAM_SHIFT 0 +#define SDM_OP_GEN_COMP_TYPE (0x7<<5) +#define SDM_OP_GEN_COMP_TYPE_SHIFT 5 +#define SDM_OP_GEN_AGG_VECT_IDX (0xFF<<8) +#define SDM_OP_GEN_AGG_VECT_IDX_SHIFT 8 +#define SDM_OP_GEN_AGG_VECT_IDX_VALID (0x1<<16) +#define SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT 16 +#define SDM_OP_GEN_RESERVED (0x7FFF<<17) +#define SDM_OP_GEN_RESERVED_SHIFT 17 }; /* @@ -1644,20 +1912,13 @@ struct eth_rx_sge { __le32 addr_hi; }; -/* - * Local BDs and SGEs rings (in ETH) - */ -struct eth_local_rx_rings { - struct eth_rx_bd __local_bd_ring[8]; - struct eth_rx_sge __local_sge_ring[10]; -}; + /* * The eth storm context of Ustorm */ struct ustorm_eth_st_context { - struct ustorm_eth_st_context_config common; - struct eth_local_rx_rings __rings; + u32 reserved0[48]; }; /* @@ -1667,338 +1928,54 @@ struct tstorm_eth_st_context { u32 __reserved0[28]; }; -/* - * The eth aggregative context section of Xstorm - */ -struct xstorm_eth_extra_ag_context_section { -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars1; - u8 __reserved50; - u16 __mss; -#elif defined(__LITTLE_ENDIAN) - u16 __mss; - u8 __reserved50; - u8 __tcp_agg_vars1; -#endif - u32 __snd_nxt; - u32 __tx_wnd; - u32 __snd_una; - u32 __reserved53; -#if defined(__BIG_ENDIAN) - u8 __agg_val8_th; - u8 __agg_val8; - u16 __tcp_agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __tcp_agg_vars2; - u8 __agg_val8; - u8 __agg_val8_th; -#endif - u32 __reserved58; - u32 __reserved59; - u32 __reserved60; - u32 __reserved61; -#if defined(__BIG_ENDIAN) - u16 __agg_val7_th; - u16 __agg_val7; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val7; - u16 __agg_val7_th; -#endif -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars5; - u8 __tcp_agg_vars4; - u8 __tcp_agg_vars3; - u8 __reserved62; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved62; - u8 __tcp_agg_vars3; - u8 __tcp_agg_vars4; - u8 __tcp_agg_vars5; -#endif - u32 __tcp_agg_vars6; -#if defined(__BIG_ENDIAN) - u16 __agg_misc6; - u16 __tcp_agg_vars7; -#elif defined(__LITTLE_ENDIAN) - u16 __tcp_agg_vars7; - u16 __agg_misc6; -#endif - u32 __agg_val10; - u32 __agg_val10_th; -#if defined(__BIG_ENDIAN) - u16 __reserved3; - u8 __reserved2; - u8 __da_only_cnt; -#elif defined(__LITTLE_ENDIAN) - u8 __da_only_cnt; - u8 __reserved2; - u16 __reserved3; -#endif -}; - /* * The eth aggregative context of Xstorm */ struct xstorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u16 agg_val1; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u16 agg_val1; -#endif + u32 reserved0; #if defined(__BIG_ENDIAN) u8 cdu_reserved; - u8 __agg_vars4; - u8 __agg_vars3; - u8 __agg_vars2; + u8 reserved2; + u16 reserved1; #elif defined(__LITTLE_ENDIAN) - u8 __agg_vars2; - u8 __agg_vars3; - u8 __agg_vars4; + u16 reserved1; + u8 reserved2; u8 cdu_reserved; #endif - u32 __bd_prod; -#if defined(__BIG_ENDIAN) - u16 __agg_vars5; - u16 __agg_val4_th; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val4_th; - u16 __agg_vars5; -#endif - struct xstorm_eth_extra_ag_context_section __extra_section; -#if defined(__BIG_ENDIAN) - u16 __agg_vars7; - u8 __agg_val3_th; - u8 __agg_vars6; -#elif defined(__LITTLE_ENDIAN) - u8 __agg_vars6; - u8 __agg_val3_th; - u16 __agg_vars7; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val11_th; - u16 __agg_val11; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val11; - u16 __agg_val11_th; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved1; - u8 __agg_val6_th; - u16 __agg_val9; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val9; - u8 __agg_val6_th; - u8 __reserved1; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val2_th; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u16 __agg_val2_th; -#endif - u32 __agg_vars8; -#if defined(__BIG_ENDIAN) - u16 __agg_misc0; - u16 __agg_val4; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val4; - u16 __agg_misc0; -#endif -#if defined(__BIG_ENDIAN) - u8 __agg_val3; - u8 __agg_val6; - u8 __agg_val5_th; - u8 __agg_val5; -#elif defined(__LITTLE_ENDIAN) - u8 __agg_val5; - u8 __agg_val5_th; - u8 __agg_val6; - u8 __agg_val3; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_misc1; - u16 __bd_ind_max_val; -#elif defined(__LITTLE_ENDIAN) - u16 __bd_ind_max_val; - u16 __agg_misc1; -#endif - u32 __reserved57; - u32 __agg_misc4; - u32 __agg_misc5; -}; - -/* - * The eth extra aggregative context section of Tstorm - */ -struct tstorm_eth_extra_ag_context_section { - u32 __agg_val1; -#if defined(__BIG_ENDIAN) - u8 __tcp_agg_vars2; - u8 __agg_val3; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u8 __agg_val3; - u8 __tcp_agg_vars2; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val5; - u8 __agg_val6; - u8 __tcp_agg_vars3; -#elif defined(__LITTLE_ENDIAN) - u8 __tcp_agg_vars3; - u8 __agg_val6; - u16 __agg_val5; -#endif - u32 __reserved63; - u32 __reserved64; - u32 __reserved65; - u32 __reserved66; - u32 __reserved67; - u32 __tcp_agg_vars1; - u32 __reserved61; - u32 __reserved62; - u32 __reserved2; + u32 reserved3[30]; }; /* * The eth aggregative context of Tstorm */ struct tstorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u16 __reserved54; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u16 __reserved54; -#endif -#if defined(__BIG_ENDIAN) - u16 __agg_val4; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u16 __agg_val4; -#endif - struct tstorm_eth_extra_ag_context_section __extra_section; + u32 __reserved0[14]; }; + /* * The eth aggregative context of Cstorm */ struct cstorm_eth_ag_context { - u32 __agg_vars1; -#if defined(__BIG_ENDIAN) - u8 __aux1_th; - u8 __aux1_val; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u8 __aux1_val; - u8 __aux1_th; -#endif - u32 __num_of_treated_packet; - u32 __last_packet_treated; -#if defined(__BIG_ENDIAN) - u16 __reserved58; - u16 __reserved57; -#elif defined(__LITTLE_ENDIAN) - u16 __reserved57; - u16 __reserved58; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved62; - u8 __reserved61; - u8 __reserved60; - u8 __reserved59; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved59; - u8 __reserved60; - u8 __reserved61; - u8 __reserved62; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved64; - u16 __reserved63; -#elif defined(__LITTLE_ENDIAN) - u16 __reserved63; - u16 __reserved64; -#endif - u32 __reserved65; -#if defined(__BIG_ENDIAN) - u16 __agg_vars3; - u16 __rq_inv_cnt; -#elif defined(__LITTLE_ENDIAN) - u16 __rq_inv_cnt; - u16 __agg_vars3; -#endif -#if defined(__BIG_ENDIAN) - u16 __packet_index_th; - u16 __packet_index; -#elif defined(__LITTLE_ENDIAN) - u16 __packet_index; - u16 __packet_index_th; -#endif + u32 __reserved0[10]; }; + /* * The eth aggregative context of Ustorm */ struct ustorm_eth_ag_context { -#if defined(__BIG_ENDIAN) - u8 __aux_counter_flags; - u8 __agg_vars2; - u8 __agg_vars1; - u8 __state; -#elif defined(__LITTLE_ENDIAN) - u8 __state; - u8 __agg_vars1; - u8 __agg_vars2; - u8 __aux_counter_flags; -#endif + u32 __reserved0; #if defined(__BIG_ENDIAN) u8 cdu_usage; - u8 __agg_misc2; - u16 __agg_misc1; + u8 __reserved2; + u16 __reserved1; #elif defined(__LITTLE_ENDIAN) - u16 __agg_misc1; - u8 __agg_misc2; + u16 __reserved1; + u8 __reserved2; u8 cdu_usage; #endif - u32 __agg_misc4; -#if defined(__BIG_ENDIAN) - u8 __agg_val3_th; - u8 __agg_val3; - u16 __agg_misc3; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_misc3; - u8 __agg_val3; - u8 __agg_val3_th; -#endif - u32 __agg_val1; - u32 __agg_misc4_th; -#if defined(__BIG_ENDIAN) - u16 __agg_val2_th; - u16 __agg_val2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_val2; - u16 __agg_val2_th; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved2; - u8 __decision_rules; - u8 __decision_rule_enable_bits; -#elif defined(__LITTLE_ENDIAN) - u8 __decision_rule_enable_bits; - u8 __decision_rules; - u16 __reserved2; -#endif + u32 __reserved3[6]; }; /* @@ -2022,18 +1999,16 @@ struct timers_block_context { */ struct eth_tx_bd_flags { u8 as_bitfield; -#define ETH_TX_BD_FLAGS_VLAN_TAG (0x1<<0) -#define ETH_TX_BD_FLAGS_VLAN_TAG_SHIFT 0 -#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<1) -#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 1 -#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<2) -#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 2 -#define ETH_TX_BD_FLAGS_END_BD (0x1<<3) -#define ETH_TX_BD_FLAGS_END_BD_SHIFT 3 +#define ETH_TX_BD_FLAGS_IP_CSUM (0x1<<0) +#define ETH_TX_BD_FLAGS_IP_CSUM_SHIFT 0 +#define ETH_TX_BD_FLAGS_L4_CSUM (0x1<<1) +#define ETH_TX_BD_FLAGS_L4_CSUM_SHIFT 1 +#define ETH_TX_BD_FLAGS_VLAN_MODE (0x3<<2) +#define ETH_TX_BD_FLAGS_VLAN_MODE_SHIFT 2 #define ETH_TX_BD_FLAGS_START_BD (0x1<<4) #define ETH_TX_BD_FLAGS_START_BD_SHIFT 4 -#define ETH_TX_BD_FLAGS_HDR_POOL (0x1<<5) -#define ETH_TX_BD_FLAGS_HDR_POOL_SHIFT 5 +#define ETH_TX_BD_FLAGS_IS_UDP (0x1<<5) +#define ETH_TX_BD_FLAGS_IS_UDP_SHIFT 5 #define ETH_TX_BD_FLAGS_SW_LSO (0x1<<6) #define ETH_TX_BD_FLAGS_SW_LSO_SHIFT 6 #define ETH_TX_BD_FLAGS_IPV6 (0x1<<7) @@ -2048,7 +2023,7 @@ struct eth_tx_start_bd { __le32 addr_hi; __le16 nbd; __le16 nbytes; - __le16 vlan; + __le16 vlan_or_ethertype; struct eth_tx_bd_flags bd_flags; u8 general_data; #define ETH_TX_START_BD_HDR_NBDS (0x3F<<0) @@ -2061,54 +2036,75 @@ struct eth_tx_start_bd { * Tx regular BD structure */ struct eth_tx_bd { - u32 addr_lo; - u32 addr_hi; - u16 total_pkt_bytes; - u16 nbytes; + __le32 addr_lo; + __le32 addr_hi; + __le16 total_pkt_bytes; + __le16 nbytes; u8 reserved[4]; }; /* - * Tx parsing BD structure for ETH,Relevant in START + * Tx parsing BD structure for ETH E1/E1h */ -struct eth_tx_parse_bd { +struct eth_tx_parse_bd_e1x { u8 global_data; -#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET (0xF<<0) -#define ETH_TX_PARSE_BD_IP_HDR_START_OFFSET_SHIFT 0 -#define ETH_TX_PARSE_BD_UDP_CS_FLG (0x1<<4) -#define ETH_TX_PARSE_BD_UDP_CS_FLG_SHIFT 4 -#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN (0x1<<5) -#define ETH_TX_PARSE_BD_PSEUDO_CS_WITHOUT_LEN_SHIFT 5 -#define ETH_TX_PARSE_BD_LLC_SNAP_EN (0x1<<6) -#define ETH_TX_PARSE_BD_LLC_SNAP_EN_SHIFT 6 -#define ETH_TX_PARSE_BD_NS_FLG (0x1<<7) -#define ETH_TX_PARSE_BD_NS_FLG_SHIFT 7 +#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W (0xF<<0) +#define ETH_TX_PARSE_BD_E1X_IP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E1X_RESERVED0 (0x1<<4) +#define ETH_TX_PARSE_BD_E1X_RESERVED0_SHIFT 4 +#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN (0x1<<5) +#define ETH_TX_PARSE_BD_E1X_PSEUDO_CS_WITHOUT_LEN_SHIFT 5 +#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN (0x1<<6) +#define ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT 6 +#define ETH_TX_PARSE_BD_E1X_NS_FLG (0x1<<7) +#define ETH_TX_PARSE_BD_E1X_NS_FLG_SHIFT 7 u8 tcp_flags; -#define ETH_TX_PARSE_BD_FIN_FLG (0x1<<0) -#define ETH_TX_PARSE_BD_FIN_FLG_SHIFT 0 -#define ETH_TX_PARSE_BD_SYN_FLG (0x1<<1) -#define ETH_TX_PARSE_BD_SYN_FLG_SHIFT 1 -#define ETH_TX_PARSE_BD_RST_FLG (0x1<<2) -#define ETH_TX_PARSE_BD_RST_FLG_SHIFT 2 -#define ETH_TX_PARSE_BD_PSH_FLG (0x1<<3) -#define ETH_TX_PARSE_BD_PSH_FLG_SHIFT 3 -#define ETH_TX_PARSE_BD_ACK_FLG (0x1<<4) -#define ETH_TX_PARSE_BD_ACK_FLG_SHIFT 4 -#define ETH_TX_PARSE_BD_URG_FLG (0x1<<5) -#define ETH_TX_PARSE_BD_URG_FLG_SHIFT 5 -#define ETH_TX_PARSE_BD_ECE_FLG (0x1<<6) -#define ETH_TX_PARSE_BD_ECE_FLG_SHIFT 6 -#define ETH_TX_PARSE_BD_CWR_FLG (0x1<<7) -#define ETH_TX_PARSE_BD_CWR_FLG_SHIFT 7 - u8 ip_hlen; +#define ETH_TX_PARSE_BD_E1X_FIN_FLG (0x1<<0) +#define ETH_TX_PARSE_BD_E1X_FIN_FLG_SHIFT 0 +#define ETH_TX_PARSE_BD_E1X_SYN_FLG (0x1<<1) +#define ETH_TX_PARSE_BD_E1X_SYN_FLG_SHIFT 1 +#define ETH_TX_PARSE_BD_E1X_RST_FLG (0x1<<2) +#define ETH_TX_PARSE_BD_E1X_RST_FLG_SHIFT 2 +#define ETH_TX_PARSE_BD_E1X_PSH_FLG (0x1<<3) +#define ETH_TX_PARSE_BD_E1X_PSH_FLG_SHIFT 3 +#define ETH_TX_PARSE_BD_E1X_ACK_FLG (0x1<<4) +#define ETH_TX_PARSE_BD_E1X_ACK_FLG_SHIFT 4 +#define ETH_TX_PARSE_BD_E1X_URG_FLG (0x1<<5) +#define ETH_TX_PARSE_BD_E1X_URG_FLG_SHIFT 5 +#define ETH_TX_PARSE_BD_E1X_ECE_FLG (0x1<<6) +#define ETH_TX_PARSE_BD_E1X_ECE_FLG_SHIFT 6 +#define ETH_TX_PARSE_BD_E1X_CWR_FLG (0x1<<7) +#define ETH_TX_PARSE_BD_E1X_CWR_FLG_SHIFT 7 + u8 ip_hlen_w; s8 reserved; - __le16 total_hlen; + __le16 total_hlen_w; __le16 tcp_pseudo_csum; __le16 lso_mss; __le16 ip_id; __le32 tcp_send_seq; }; +/* + * Tx parsing BD structure for ETH E2 + */ +struct eth_tx_parse_bd_e2 { + __le16 dst_mac_addr_lo; + __le16 dst_mac_addr_mid; + __le16 dst_mac_addr_hi; + __le16 src_mac_addr_lo; + __le16 src_mac_addr_mid; + __le16 src_mac_addr_hi; + __le32 parsing_data; +#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W (0x1FFF<<0) +#define ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT 0 +#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW (0xF<<13) +#define ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT 13 +#define ETH_TX_PARSE_BD_E2_LSO_MSS (0x3FFF<<17) +#define ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT 17 +#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR (0x1<<31) +#define ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR_SHIFT 31 +}; + /* * The last BD in the BD memory will hold a pointer to the next BD memory */ @@ -2124,79 +2120,24 @@ struct eth_tx_next_bd { union eth_tx_bd_types { struct eth_tx_start_bd start_bd; struct eth_tx_bd reg_bd; - struct eth_tx_parse_bd parse_bd; + struct eth_tx_parse_bd_e1x parse_bd_e1x; + struct eth_tx_parse_bd_e2 parse_bd_e2; struct eth_tx_next_bd next_bd; }; + /* * The eth storm context of Xstorm */ struct xstorm_eth_st_context { - u32 tx_bd_page_base_lo; - u32 tx_bd_page_base_hi; -#if defined(__BIG_ENDIAN) - u16 tx_bd_cons; - u8 statistics_data; -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0 -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7 - u8 __local_tx_bd_prod; -#elif defined(__LITTLE_ENDIAN) - u8 __local_tx_bd_prod; - u8 statistics_data; -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID (0x7F<<0) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_COUNTER_ID_SHIFT 0 -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE (0x1<<7) -#define XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE_SHIFT 7 - u16 tx_bd_cons; -#endif - u32 __reserved1; - u32 __reserved2; -#if defined(__BIG_ENDIAN) - u8 __ram_cache_index; - u8 __double_buffer_client; - u16 __pkt_cons; -#elif defined(__LITTLE_ENDIAN) - u16 __pkt_cons; - u8 __double_buffer_client; - u8 __ram_cache_index; -#endif -#if defined(__BIG_ENDIAN) - u16 __statistics_address; - u16 __gso_next; -#elif defined(__LITTLE_ENDIAN) - u16 __gso_next; - u16 __statistics_address; -#endif -#if defined(__BIG_ENDIAN) - u8 __local_tx_bd_cons; - u8 safc_group_num; - u8 safc_group_en; - u8 __is_eth_conn; -#elif defined(__LITTLE_ENDIAN) - u8 __is_eth_conn; - u8 safc_group_en; - u8 safc_group_num; - u8 __local_tx_bd_cons; -#endif - union eth_tx_bd_types __bds[13]; + u32 reserved0[60]; }; /* * The eth storm context of Cstorm */ struct cstorm_eth_st_context { -#if defined(__BIG_ENDIAN) - u16 __reserved0; - u8 sb_index_number; - u8 status_block_id; -#elif defined(__LITTLE_ENDIAN) - u8 status_block_id; - u8 sb_index_number; - u16 __reserved0; -#endif - u32 __reserved1[3]; + u32 __reserved0[4]; }; /* @@ -2244,103 +2185,114 @@ struct eth_tx_doorbell { /* - * cstorm default status block, generated by ustorm - */ -struct cstorm_def_status_block_u { - __le16 index_values[HC_USTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; - -/* - * cstorm default status block, generated by cstorm - */ -struct cstorm_def_status_block_c { - __le16 index_values[HC_CSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; - -/* - * xstorm status block + * client init fc data */ -struct xstorm_def_status_block { - __le16 index_values[HC_XSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; +struct client_init_fc_data { + __le16 cqe_pause_thr_low; + __le16 cqe_pause_thr_high; + __le16 bd_pause_thr_low; + __le16 bd_pause_thr_high; + __le16 sge_pause_thr_low; + __le16 sge_pause_thr_high; + __le16 rx_cos_mask; + u8 safc_group_num; + u8 safc_group_en_flg; + u8 traffic_type; + u8 reserved0; + __le16 reserved1; + __le32 reserved2; }; -/* - * tstorm status block - */ -struct tstorm_def_status_block { - __le16 index_values[HC_TSTORM_DEF_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; -}; /* - * host status block + * client init ramrod data */ -struct host_def_status_block { - struct atten_def_status_block atten_status_block; - struct cstorm_def_status_block_u u_def_status_block; - struct cstorm_def_status_block_c c_def_status_block; - struct xstorm_def_status_block x_def_status_block; - struct tstorm_def_status_block t_def_status_block; +struct client_init_general_data { + u8 client_id; + u8 statistics_counter_id; + u8 statistics_en_flg; + u8 is_fcoe_flg; + u8 activate_flg; + u8 sp_client_id; + __le16 reserved0; + __le32 reserved1[2]; }; /* - * cstorm status block, generated by ustorm + * client init rx data */ -struct cstorm_status_block_u { - __le16 index_values[HC_USTORM_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; +struct client_init_rx_data { + u8 tpa_en_flg; + u8 vmqueue_mode_en_flg; + u8 extra_data_over_sgl_en_flg; + u8 cache_line_alignment_log_size; + u8 enable_dynamic_hc; + u8 max_sges_for_packet; + u8 client_qzone_id; + u8 drop_ip_cs_err_flg; + u8 drop_tcp_cs_err_flg; + u8 drop_ttl0_flg; + u8 drop_udp_cs_err_flg; + u8 inner_vlan_removal_enable_flg; + u8 outer_vlan_removal_enable_flg; u8 status_block_id; - __le32 __flags; + u8 rx_sb_index_number; + u8 reserved0[3]; + __le16 bd_buff_size; + __le16 sge_buff_size; + __le16 mtu; + struct regpair bd_page_base; + struct regpair sge_page_base; + struct regpair cqe_page_base; + u8 is_leading_rss; + u8 is_approx_mcast; + __le16 max_agg_size; + __le32 reserved2[3]; +}; + +/* + * client init tx data + */ +struct client_init_tx_data { + u8 enforce_security_flg; + u8 tx_status_block_id; + u8 tx_sb_index_number; + u8 reserved0; + __le16 mtu; + __le16 reserved1; + struct regpair tx_bd_page_base; + __le32 reserved2[2]; }; /* - * cstorm status block, generated by cstorm + * client init ramrod data */ -struct cstorm_status_block_c { - __le16 index_values[HC_CSTORM_SB_NUM_INDICES]; - __le16 status_block_index; - u8 func; - u8 status_block_id; - __le32 __flags; +struct client_init_ramrod_data { + struct client_init_general_data general; + struct client_init_rx_data rx; + struct client_init_tx_data tx; + struct client_init_fc_data fc; }; + /* - * host status block + * The data contain client ID need to the ramrod */ -struct host_status_block { - struct cstorm_status_block_u u_status_block; - struct cstorm_status_block_c c_status_block; +struct eth_common_ramrod_data { + u32 client_id; + u32 reserved1; }; /* - * The data for RSS setup ramrod + * union for sgl and raw data. */ -struct eth_client_setup_ramrod_data { - u32 client_id; - u8 is_rdma; - u8 is_fcoe; - u16 reserved1; +union eth_sgl_or_raw_data { + __le16 sgl[8]; + u32 raw_data[4]; }; - /* * regular eth FP CQE parameters struct */ @@ -2358,8 +2310,8 @@ struct eth_fast_path_rx_cqe { #define ETH_FAST_PATH_RX_CQE_START_FLG_SHIFT 4 #define ETH_FAST_PATH_RX_CQE_END_FLG (0x1<<5) #define ETH_FAST_PATH_RX_CQE_END_FLG_SHIFT 5 -#define ETH_FAST_PATH_RX_CQE_RESERVED0 (0x3<<6) -#define ETH_FAST_PATH_RX_CQE_RESERVED0_SHIFT 6 +#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL (0x3<<6) +#define ETH_FAST_PATH_RX_CQE_SGL_RAW_SEL_SHIFT 6 u8 status_flags; #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE (0x7<<0) #define ETH_FAST_PATH_RX_CQE_RSS_HASH_TYPE_SHIFT 0 @@ -2380,7 +2332,7 @@ struct eth_fast_path_rx_cqe { __le16 pkt_len; __le16 len_on_bd; struct parsing_flags pars_flags; - __le16 sgl[8]; + union eth_sgl_or_raw_data sgl_or_raw_data; }; @@ -2392,11 +2344,10 @@ struct eth_halt_ramrod_data { u32 reserved0; }; - /* * The data for statistics query ramrod */ -struct eth_query_ramrod_data { +struct common_query_ramrod_data { #if defined(__BIG_ENDIAN) u8 reserved0; u8 collect_port; @@ -2479,9 +2430,9 @@ struct spe_hdr { __le16 type; #define SPE_HDR_CONN_TYPE (0xFF<<0) #define SPE_HDR_CONN_TYPE_SHIFT 0 -#define SPE_HDR_COMMON_RAMROD (0xFF<<8) -#define SPE_HDR_COMMON_RAMROD_SHIFT 8 - __le16 reserved; +#define SPE_HDR_FUNCTION_ID (0xFF<<8) +#define SPE_HDR_FUNCTION_ID_SHIFT 8 + __le16 reserved1; }; /* @@ -2489,12 +2440,10 @@ struct spe_hdr { */ union eth_specific_data { u8 protocol_data[8]; - struct regpair mac_config_addr; - struct eth_client_setup_ramrod_data client_setup_ramrod_data; + struct regpair client_init_ramrod_init_data; struct eth_halt_ramrod_data halt_ramrod_data; - struct regpair leading_cqe_addr; struct regpair update_data_addr; - struct eth_query_ramrod_data query_ramrod_data; + struct eth_common_ramrod_data common_ramrod_data; }; /* @@ -2519,7 +2468,7 @@ struct eth_tx_bds_array { */ struct tstorm_eth_function_common_config { #if defined(__BIG_ENDIAN) - u8 leading_client_id; + u8 reserved1; u8 rss_result_mask; u16 config_flags; #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) @@ -2532,16 +2481,12 @@ struct tstorm_eth_function_common_config { #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10 -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11) -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8 +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9) +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9 #elif defined(__LITTLE_ENDIAN) u16 config_flags; #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV4_CAPABILITY (0x1<<0) @@ -2554,18 +2499,14 @@ struct tstorm_eth_function_common_config { #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_IPV6_TCP_CAPABILITY_SHIFT 3 #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE (0x7<<4) #define TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT 4 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE (0x1<<7) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_DEFAULT_ENABLE_SHIFT 7 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM (0x1<<8) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_IN_CAM_SHIFT 8 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM (0x1<<9) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM_SHIFT 9 -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<10) -#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 10 -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x1F<<11) -#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 11 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA (0x1<<7) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA_SHIFT 7 +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE (0x1<<8) +#define TSTORM_ETH_FUNCTION_COMMON_CONFIG_VLAN_FILTERING_ENABLE_SHIFT 8 +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0 (0x7F<<9) +#define __TSTORM_ETH_FUNCTION_COMMON_CONFIG_RESERVED0_SHIFT 9 u8 rss_result_mask; - u8 leading_client_id; + u8 reserved1; #endif u16 vlan_id[2]; }; @@ -2613,90 +2554,42 @@ struct mac_configuration_hdr { u8 length; u8 offset; u16 client_id; - u32 reserved1; -}; - -/* - * MAC address in list for ramrod - */ -struct tstorm_cam_entry { - __le16 lsb_mac_addr; - __le16 middle_mac_addr; - __le16 msb_mac_addr; - __le16 flags; -#define TSTORM_CAM_ENTRY_PORT_ID (0x1<<0) -#define TSTORM_CAM_ENTRY_PORT_ID_SHIFT 0 -#define TSTORM_CAM_ENTRY_RSRVVAL0 (0x7<<1) -#define TSTORM_CAM_ENTRY_RSRVVAL0_SHIFT 1 -#define TSTORM_CAM_ENTRY_RESERVED0 (0xFFF<<4) -#define TSTORM_CAM_ENTRY_RESERVED0_SHIFT 4 -}; - -/* - * MAC filtering: CAM target table entry - */ -struct tstorm_cam_target_table_entry { - u8 flags; -#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST (0x1<<0) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST_SHIFT 0 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<1) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 1 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE (0x1<<2) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_ACTION_TYPE_SHIFT 2 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC (0x1<<3) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RDMA_MAC_SHIFT 3 -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0 (0xF<<4) -#define TSTORM_CAM_TARGET_TABLE_ENTRY_RESERVED0_SHIFT 4 - u8 reserved1; - u16 vlan_id; - u32 clients_bit_vector; + u16 echo; + u16 reserved1; }; /* * MAC address in list for ramrod */ struct mac_configuration_entry { - struct tstorm_cam_entry cam_entry; - struct tstorm_cam_target_table_entry target_table_entry; -}; - -/* - * MAC filtering configuration command - */ -struct mac_configuration_cmd { - struct mac_configuration_hdr hdr; - struct mac_configuration_entry config_table[64]; -}; - - -/* - * MAC address in list for ramrod - */ -struct mac_configuration_entry_e1h { __le16 lsb_mac_addr; __le16 middle_mac_addr; __le16 msb_mac_addr; __le16 vlan_id; - __le16 e1hov_id; - u8 reserved0; + u8 pf_id; u8 flags; -#define MAC_CONFIGURATION_ENTRY_E1H_PORT (0x1<<0) -#define MAC_CONFIGURATION_ENTRY_E1H_PORT_SHIFT 0 -#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE (0x1<<1) -#define MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE_SHIFT 1 -#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC (0x1<<2) -#define MAC_CONFIGURATION_ENTRY_E1H_RDMA_MAC_SHIFT 2 -#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1 (0x1F<<3) -#define MAC_CONFIGURATION_ENTRY_E1H_RESERVED1_SHIFT 3 +#define MAC_CONFIGURATION_ENTRY_ACTION_TYPE (0x1<<0) +#define MAC_CONFIGURATION_ENTRY_ACTION_TYPE_SHIFT 0 +#define MAC_CONFIGURATION_ENTRY_RDMA_MAC (0x1<<1) +#define MAC_CONFIGURATION_ENTRY_RDMA_MAC_SHIFT 1 +#define MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE (0x3<<2) +#define MAC_CONFIGURATION_ENTRY_VLAN_FILTERING_MODE_SHIFT 2 +#define MAC_CONFIGURATION_ENTRY_OVERRIDE_VLAN_REMOVAL (0x1<<4) +#define MAC_CONFIGURATION_ENTRY_OVERRIDE_VLAN_REMOVAL_SHIFT 4 +#define MAC_CONFIGURATION_ENTRY_BROADCAST (0x1<<5) +#define MAC_CONFIGURATION_ENTRY_BROADCAST_SHIFT 5 +#define MAC_CONFIGURATION_ENTRY_RESERVED1 (0x3<<6) +#define MAC_CONFIGURATION_ENTRY_RESERVED1_SHIFT 6 + u16 reserved0; u32 clients_bit_vector; }; /* * MAC filtering configuration command */ -struct mac_configuration_cmd_e1h { +struct mac_configuration_cmd { struct mac_configuration_hdr hdr; - struct mac_configuration_entry_e1h config_table[32]; + struct mac_configuration_entry config_table[64]; }; @@ -2708,65 +2601,6 @@ struct tstorm_eth_approximate_match_multicast_filtering { }; -/* - * Configuration parameters per client in Tstorm - */ -struct tstorm_eth_client_config { -#if defined(__BIG_ENDIAN) - u8 reserved0; - u8 statistics_counter_id; - u16 mtu; -#elif defined(__LITTLE_ENDIAN) - u16 mtu; - u8 statistics_counter_id; - u8 reserved0; -#endif -#if defined(__BIG_ENDIAN) - u16 drop_flags; -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4 - u16 config_flags; -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3 -#elif defined(__LITTLE_ENDIAN) - u16 config_flags; -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE_SHIFT 2 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1 (0x1FFF<<3) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED1_SHIFT 3 - u16 drop_flags; -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR (0x1<<0) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_IP_CS_ERR_SHIFT 0 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR (0x1<<1) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TCP_CS_ERR_SHIFT 1 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0 (0x1<<2) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_TTL0_SHIFT 2 -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR (0x1<<3) -#define TSTORM_ETH_CLIENT_CONFIG_DROP_UDP_CS_ERR_SHIFT 3 -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2 (0xFFF<<4) -#define __TSTORM_ETH_CLIENT_CONFIG_RESERVED2_SHIFT 4 -#endif -}; - - /* * MAC filtering configuration parameters per port in Tstorm */ @@ -2777,8 +2611,8 @@ struct tstorm_eth_mac_filter_config { u32 mcast_accept_all; u32 bcast_drop_all; u32 bcast_accept_all; - u32 strict_vlan; u32 vlan_filter[2]; + u32 unmatched_unicast; u32 reserved; }; @@ -2800,41 +2634,6 @@ struct tstorm_eth_tpa_exist { }; -/* - * rx rings pause data for E1h only - */ -struct ustorm_eth_rx_pause_data_e1h { -#if defined(__BIG_ENDIAN) - u16 bd_thr_low; - u16 cqe_thr_low; -#elif defined(__LITTLE_ENDIAN) - u16 cqe_thr_low; - u16 bd_thr_low; -#endif -#if defined(__BIG_ENDIAN) - u16 cos; - u16 sge_thr_low; -#elif defined(__LITTLE_ENDIAN) - u16 sge_thr_low; - u16 cos; -#endif -#if defined(__BIG_ENDIAN) - u16 bd_thr_high; - u16 cqe_thr_high; -#elif defined(__LITTLE_ENDIAN) - u16 cqe_thr_high; - u16 bd_thr_high; -#endif -#if defined(__BIG_ENDIAN) - u16 reserved0; - u16 sge_thr_high; -#elif defined(__LITTLE_ENDIAN) - u16 sge_thr_high; - u16 reserved0; -#endif -}; - - /* * Three RX producers for ETH */ @@ -2856,6 +2655,18 @@ struct ustorm_eth_rx_producers { }; +/* + * cfc delete event data + */ +struct cfc_del_event_data { + u32 cid; + u8 error; + u8 reserved0; + u16 reserved1; + u32 reserved2; +}; + + /* * per-port SAFC demo variables */ @@ -2872,8 +2683,10 @@ struct cmng_flags_per_port { #define CMNG_FLAGS_PER_PORT_RATE_SHAPING_PROTOCOL_SHIFT 3 #define CMNG_FLAGS_PER_PORT_FAIRNESS_COS (0x1<<4) #define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_SHIFT 4 -#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x7FFFFFF<<5) -#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 5 +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE (0x1<<5) +#define CMNG_FLAGS_PER_PORT_FAIRNESS_COS_MODE_SHIFT 5 +#define __CMNG_FLAGS_PER_PORT_RESERVED0 (0x3FFFFFF<<6) +#define __CMNG_FLAGS_PER_PORT_RESERVED0_SHIFT 6 }; @@ -2907,9 +2720,43 @@ struct safc_struct_per_port { u8 __reserved0; u16 __reserved1; #endif + u8 cos_to_traffic_types[MAX_COS_NUMBER]; + u32 __reserved2; u16 cos_to_pause_mask[NUM_OF_SAFC_BITS]; }; +/* + * per-port PFC variables + */ +struct pfc_struct_per_port { + u8 priority_to_traffic_types[MAX_PFC_PRIORITIES]; +#if defined(__BIG_ENDIAN) + u16 pfc_pause_quanta_in_nanosec; + u8 __reserved0; + u8 priority_non_pausable_mask; +#elif defined(__LITTLE_ENDIAN) + u8 priority_non_pausable_mask; + u8 __reserved0; + u16 pfc_pause_quanta_in_nanosec; +#endif +}; + +/* + * Priority and cos + */ +struct priority_cos { +#if defined(__BIG_ENDIAN) + u16 reserved1; + u8 cos; + u8 priority; +#elif defined(__LITTLE_ENDIAN) + u8 priority; + u8 cos; + u16 reserved1; +#endif + u32 reserved2; +}; + /* * Per-port congestion management variables */ @@ -2917,20 +2764,48 @@ struct cmng_struct_per_port { struct rate_shaping_vars_per_port rs_vars; struct fairness_vars_per_port fair_vars; struct safc_struct_per_port safc_vars; + struct pfc_struct_per_port pfc_vars; +#if defined(__BIG_ENDIAN) + u16 __reserved1; + u8 dcb_enabled; + u8 llfc_mode; +#elif defined(__LITTLE_ENDIAN) + u8 llfc_mode; + u8 dcb_enabled; + u16 __reserved1; +#endif + struct priority_cos + traffic_type_to_priority_cos[MAX_PFC_TRAFFIC_TYPES]; struct cmng_flags_per_port flags; }; + +/* + * Dynamic HC counters set by the driver + */ +struct hc_dynamic_drv_counter { + u32 val[HC_SB_MAX_DYNAMIC_INDICES]; +}; + +/* + * zone A per-queue data + */ +struct cstorm_queue_zone_data { + struct hc_dynamic_drv_counter hc_dyn_drv_cnt; + struct regpair reserved[2]; +}; + /* * Dynamic host coalescing init parameters */ struct dynamic_hc_config { u32 threshold[3]; - u8 shift_per_protocol[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout0[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout1[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout2[HC_USTORM_SB_NUM_INDICES]; - u8 hc_timeout3[HC_USTORM_SB_NUM_INDICES]; + u8 shift_per_protocol[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout0[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout1[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout2[HC_SB_MAX_DYNAMIC_INDICES]; + u8 hc_timeout3[HC_SB_MAX_DYNAMIC_INDICES]; }; @@ -2954,7 +2829,7 @@ struct xstorm_per_client_stats { * Common statistics collected by the Xstorm (per port) */ struct xstorm_common_stats { - struct xstorm_per_client_stats client_statistics[MAX_X_STAT_COUNTER_ID]; + struct xstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -2991,7 +2866,7 @@ struct tstorm_per_client_stats { */ struct tstorm_common_stats { struct tstorm_per_port_stats port_statistics; - struct tstorm_per_client_stats client_statistics[MAX_T_STAT_COUNTER_ID]; + struct tstorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -3012,7 +2887,7 @@ struct ustorm_per_client_stats { * Protocol-common statistics collected by the Ustorm */ struct ustorm_common_stats { - struct ustorm_per_client_stats client_statistics[MAX_U_STAT_COUNTER_ID]; + struct ustorm_per_client_stats client_statistics[MAX_STAT_COUNTER_ID]; }; /* @@ -3025,6 +2900,70 @@ struct eth_stats_query { }; +/* + * set mac event data + */ +struct set_mac_event_data { + u16 echo; + u16 reserved0; + u32 reserved1; + u32 reserved2; +}; + +/* + * union for all event ring message types + */ +union event_data { + struct set_mac_event_data set_mac_event; + struct cfc_del_event_data cfc_del_event; +}; + + +/* + * per PF event ring data + */ +struct event_ring_data { + struct regpair base_addr; +#if defined(__BIG_ENDIAN) + u8 index_id; + u8 sb_id; + u16 producer; +#elif defined(__LITTLE_ENDIAN) + u16 producer; + u8 sb_id; + u8 index_id; +#endif + u32 reserved0; +}; + + +/* + * event ring message element (each element is 128 bits) + */ +struct event_ring_msg { + u8 opcode; + u8 reserved0; + u16 reserved1; + union event_data data; +}; + +/* + * event ring next page element (128 bits) + */ +struct event_ring_next { + struct regpair addr; + u32 reserved[2]; +}; + +/* + * union for event ring element types (each element is 128 bits) + */ +union event_ring_elem { + struct event_ring_msg message; + struct event_ring_next next_page; +}; + + /* * per-vnic fairness variables */ @@ -3063,6 +3002,137 @@ struct fw_version { }; +/* + * Dynamic Host-Coalescing - Driver(host) counters + */ +struct hc_dynamic_sb_drv_counters { + u32 dynamic_hc_drv_counter[HC_SB_MAX_DYNAMIC_INDICES]; +}; + + +/* + * 2 bytes. configuration/state parameters for a single protocol index + */ +struct hc_index_data { +#if defined(__BIG_ENDIAN) + u8 flags; +#define HC_INDEX_DATA_SM_ID (0x1<<0) +#define HC_INDEX_DATA_SM_ID_SHIFT 0 +#define HC_INDEX_DATA_HC_ENABLED (0x1<<1) +#define HC_INDEX_DATA_HC_ENABLED_SHIFT 1 +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED (0x1<<2) +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED_SHIFT 2 +#define HC_INDEX_DATA_RESERVE (0x1F<<3) +#define HC_INDEX_DATA_RESERVE_SHIFT 3 + u8 timeout; +#elif defined(__LITTLE_ENDIAN) + u8 timeout; + u8 flags; +#define HC_INDEX_DATA_SM_ID (0x1<<0) +#define HC_INDEX_DATA_SM_ID_SHIFT 0 +#define HC_INDEX_DATA_HC_ENABLED (0x1<<1) +#define HC_INDEX_DATA_HC_ENABLED_SHIFT 1 +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED (0x1<<2) +#define HC_INDEX_DATA_DYNAMIC_HC_ENABLED_SHIFT 2 +#define HC_INDEX_DATA_RESERVE (0x1F<<3) +#define HC_INDEX_DATA_RESERVE_SHIFT 3 +#endif +}; + + +/* + * HC state-machine + */ +struct hc_status_block_sm { +#if defined(__BIG_ENDIAN) + u8 igu_seg_id; + u8 igu_sb_id; + u8 timer_value; + u8 __flags; +#elif defined(__LITTLE_ENDIAN) + u8 __flags; + u8 timer_value; + u8 igu_sb_id; + u8 igu_seg_id; +#endif + u32 time_to_expire; +}; + +/* + * hold PCI identification variables- used in various places in firmware + */ +struct pci_entity { +#if defined(__BIG_ENDIAN) + u8 vf_valid; + u8 vf_id; + u8 vnic_id; + u8 pf_id; +#elif defined(__LITTLE_ENDIAN) + u8 pf_id; + u8 vnic_id; + u8 vf_id; + u8 vf_valid; +#endif +}; + +/* + * The fast-path status block meta-data, common to all chips + */ +struct hc_sb_data { + struct regpair host_sb_addr; + struct hc_status_block_sm state_machine[HC_SB_MAX_SM]; + struct pci_entity p_func; +#if defined(__BIG_ENDIAN) + u8 rsrv0; + u8 dhc_qzone_id; + u8 __dynamic_hc_level; + u8 same_igu_sb_1b; +#elif defined(__LITTLE_ENDIAN) + u8 same_igu_sb_1b; + u8 __dynamic_hc_level; + u8 dhc_qzone_id; + u8 rsrv0; +#endif + struct regpair rsrv1[2]; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_sp_status_block_data { + struct regpair host_sb_addr; +#if defined(__BIG_ENDIAN) + u16 rsrv; + u8 igu_seg_id; + u8 igu_sb_id; +#elif defined(__LITTLE_ENDIAN) + u8 igu_sb_id; + u8 igu_seg_id; + u16 rsrv; +#endif + struct pci_entity p_func; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_status_block_data_e1x { + struct hc_index_data index_data[HC_SB_MAX_INDICES_E1X]; + struct hc_sb_data common; +}; + + +/* + * The fast-path status block meta-data + */ +struct hc_status_block_data_e2 { + struct hc_index_data index_data[HC_SB_MAX_INDICES_E2]; + struct hc_sb_data common; +}; + + /* * FW version stored in first line of pram */ @@ -3085,12 +3155,22 @@ struct pram_fw_version { }; +/* + * Ethernet slow path element + */ +union protocol_common_specific_data { + u8 protocol_data[8]; + struct regpair phy_address; + struct regpair mac_config_addr; + struct common_query_ramrod_data query_ramrod_data; +}; + /* * The send queue element */ struct protocol_common_spe { struct spe_hdr hdr; - struct regpair phy_address; + union protocol_common_specific_data data; }; @@ -3123,7 +3203,7 @@ struct rate_shaping_vars_per_vn { */ struct slow_path_element { struct spe_hdr hdr; - u8 protocol_data[8]; + struct regpair protocol_data; }; @@ -3136,3 +3216,97 @@ struct stats_indication_flags { }; +/* + * per-port PFC variables + */ +struct storm_pfc_struct_per_port { +#if defined(__BIG_ENDIAN) + u16 mid_mac_addr; + u16 msb_mac_addr; +#elif defined(__LITTLE_ENDIAN) + u16 msb_mac_addr; + u16 mid_mac_addr; +#endif +#if defined(__BIG_ENDIAN) + u16 pfc_pause_quanta_in_nanosec; + u16 lsb_mac_addr; +#elif defined(__LITTLE_ENDIAN) + u16 lsb_mac_addr; + u16 pfc_pause_quanta_in_nanosec; +#endif +}; + +/* + * Per-port congestion management variables + */ +struct storm_cmng_struct_per_port { + struct storm_pfc_struct_per_port pfc_vars; +}; + + +/* + * zone A per-queue data + */ +struct tstorm_queue_zone_data { + struct regpair reserved[4]; +}; + + +/* + * zone B per-VF data + */ +struct tstorm_vf_zone_data { + struct regpair reserved; +}; + + +/* + * zone A per-queue data + */ +struct ustorm_queue_zone_data { + struct ustorm_eth_rx_producers eth_rx_producers; + struct regpair reserved[3]; +}; + + +/* + * zone B per-VF data + */ +struct ustorm_vf_zone_data { + struct regpair reserved; +}; + + +/* + * data per VF-PF channel + */ +struct vf_pf_channel_data { +#if defined(__BIG_ENDIAN) + u16 reserved0; + u8 valid; + u8 state; +#elif defined(__LITTLE_ENDIAN) + u8 state; + u8 valid; + u16 reserved0; +#endif + u32 reserved1; +}; + + +/* + * zone A per-queue data + */ +struct xstorm_queue_zone_data { + struct regpair reserved[4]; +}; + + +/* + * zone B per-VF data + */ +struct xstorm_vf_zone_data { + struct regpair reserved; +}; + +#endif /* BNX2X_HSI_H */ diff --git a/drivers/net/bnx2x/bnx2x_init.h b/drivers/net/bnx2x/bnx2x_init.h index 65b26cbfe3e74bef00c623c82e8bd880c826387d..a9d54874a55997f26d8808cd42d143204e4462d8 100644 --- a/drivers/net/bnx2x/bnx2x_init.h +++ b/drivers/net/bnx2x/bnx2x_init.h @@ -97,6 +97,9 @@ #define MISC_AEU_BLOCK 35 #define PGLUE_B_BLOCK 36 #define IGU_BLOCK 37 +#define ATC_BLOCK 38 +#define QM_4PORT_BLOCK 39 +#define XSEM_4PORT_BLOCK 40 /* Returns the index of start or end of a specific block stage in ops array*/ @@ -148,5 +151,46 @@ union init_op { struct raw_op raw; }; +#define INITOP_SET 0 /* set the HW directly */ +#define INITOP_CLEAR 1 /* clear the HW directly */ +#define INITOP_INIT 2 /* set the init-value array */ + +/**************************************************************************** +* ILT management +****************************************************************************/ +struct ilt_line { + dma_addr_t page_mapping; + void *page; + u32 size; +}; + +struct ilt_client_info { + u32 page_size; + u16 start; + u16 end; + u16 client_num; + u16 flags; +#define ILT_CLIENT_SKIP_INIT 0x1 +#define ILT_CLIENT_SKIP_MEM 0x2 +}; + +struct bnx2x_ilt { + u32 start_line; + struct ilt_line *lines; + struct ilt_client_info clients[4]; +#define ILT_CLIENT_CDU 0 +#define ILT_CLIENT_QM 1 +#define ILT_CLIENT_SRC 2 +#define ILT_CLIENT_TM 3 +}; + +/**************************************************************************** +* SRC configuration +****************************************************************************/ +struct src_ent { + u8 opaque[56]; + u64 next; +}; + #endif /* BNX2X_INIT_H */ diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index 2b1363a6fe7837844ef1e9043c567ac894a14d79..e65de784182c72e9e1395086b08b569ee5823328 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h @@ -151,6 +151,15 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, bnx2x_init_ind_wr(bp, addr, data, len); } +static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, u32 val_hi) +{ + u32 wb_write[2]; + + wb_write[0] = val_lo; + wb_write[1] = val_hi; + REG_WR_DMAE_LEN(bp, reg, wb_write, 2); +} + static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off) { const u8 *data = NULL; @@ -477,18 +486,30 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order); - if (r_order == MAX_RD_ORD) + if ((CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) && (r_order == MAX_RD_ORD)) REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); - REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x8 << w_order)); + else + REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); - if (CHIP_IS_E1H(bp)) { + if (CHIP_IS_E1H(bp) || CHIP_IS_E2(bp)) { /* MPS w_order optimal TH presently TH * 128 0 0 2 * 256 1 1 3 * >=512 2 2 3 */ - val = ((w_order == 0) ? 2 : 3); + /* DMAE is special */ + if (CHIP_IS_E2(bp)) { + /* E2 can use optimal TH */ + val = w_order; + REG_WR(bp, PXP2_REG_WR_DMAE_MPS, val); + } else { + val = ((w_order == 0) ? 2 : 3); + REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); + } + REG_WR(bp, PXP2_REG_WR_HC_MPS, val); REG_WR(bp, PXP2_REG_WR_USDM_MPS, val); REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val); @@ -498,9 +519,344 @@ static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) REG_WR(bp, PXP2_REG_WR_TM_MPS, val); REG_WR(bp, PXP2_REG_WR_SRC_MPS, val); REG_WR(bp, PXP2_REG_WR_DBG_MPS, val); - REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */ REG_WR(bp, PXP2_REG_WR_CDU_MPS, val); } + + /* Validate number of tags suppoted by device */ +#define PCIE_REG_PCIER_TL_HDR_FC_ST 0x2980 + val = REG_RD(bp, PCIE_REG_PCIER_TL_HDR_FC_ST); + val &= 0xFF; + if (val <= 0x20) + REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x20); +} + +/**************************************************************************** +* ILT management +****************************************************************************/ +/* + * This codes hides the low level HW interaction for ILT management and + * configuration. The API consists of a shadow ILT table which is set by the + * driver and a set of routines to use it to configure the HW. + * + */ + +/* ILT HW init operations */ + +/* ILT memory management operations */ +#define ILT_MEMOP_ALLOC 0 +#define ILT_MEMOP_FREE 1 + +/* the phys address is shifted right 12 bits and has an added + * 1=valid bit added to the 53rd bit + * then since this is a wide register(TM) + * we split it into two 32 bit writes + */ +#define ILT_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) +#define ILT_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) +#define ILT_RANGE(f, l) (((l) << 10) | f) + +static int bnx2x_ilt_line_mem_op(struct bnx2x *bp, struct ilt_line *line, + u32 size, u8 memop) +{ + if (memop == ILT_MEMOP_FREE) { + BNX2X_ILT_FREE(line->page, line->page_mapping, line->size); + return 0; + } + BNX2X_ILT_ZALLOC(line->page, &line->page_mapping, size); + if (!line->page) + return -1; + line->size = size; + return 0; +} + + +static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num, u8 memop) +{ + int i, rc; + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + if (!ilt || !ilt->lines) + return -1; + + if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM)) + return 0; + + for (rc = 0, i = ilt_cli->start; i <= ilt_cli->end && !rc; i++) { + rc = bnx2x_ilt_line_mem_op(bp, &ilt->lines[i], + ilt_cli->page_size, memop); + } + return rc; +} + +int bnx2x_ilt_mem_op(struct bnx2x *bp, u8 memop) +{ + int rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_CDU, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_QM, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop); + if (!rc) + rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_TM, memop); + + return rc; +} + +static void bnx2x_ilt_line_wr(struct bnx2x *bp, int abs_idx, + dma_addr_t page_mapping) +{ + u32 reg; + + if (CHIP_IS_E1(bp)) + reg = PXP2_REG_RQ_ONCHIP_AT + abs_idx*8; + else + reg = PXP2_REG_RQ_ONCHIP_AT_B0 + abs_idx*8; + + bnx2x_wr_64(bp, reg, ILT_ADDR1(page_mapping), ILT_ADDR2(page_mapping)); +} + +static void bnx2x_ilt_line_init_op(struct bnx2x *bp, struct bnx2x_ilt *ilt, + int idx, u8 initop) +{ + dma_addr_t null_mapping; + int abs_idx = ilt->start_line + idx; + + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + bnx2x_ilt_line_wr(bp, abs_idx, ilt->lines[idx].page_mapping); + break; + case INITOP_CLEAR: + null_mapping = 0; + bnx2x_ilt_line_wr(bp, abs_idx, null_mapping); + break; + } +} + +void bnx2x_ilt_boundry_init_op(struct bnx2x *bp, + struct ilt_client_info *ilt_cli, + u32 ilt_start, u8 initop) +{ + u32 start_reg = 0; + u32 end_reg = 0; + + /* The boundary is either SET or INIT, + CLEAR => SET and for now SET ~~ INIT */ + + /* find the appropriate regs */ + if (CHIP_IS_E1(bp)) { + switch (ilt_cli->client_num) { + case ILT_CLIENT_CDU: + start_reg = PXP2_REG_PSWRQ_CDU0_L2P; + break; + case ILT_CLIENT_QM: + start_reg = PXP2_REG_PSWRQ_QM0_L2P; + break; + case ILT_CLIENT_SRC: + start_reg = PXP2_REG_PSWRQ_SRC0_L2P; + break; + case ILT_CLIENT_TM: + start_reg = PXP2_REG_PSWRQ_TM0_L2P; + break; + } + REG_WR(bp, start_reg + BP_FUNC(bp)*4, + ILT_RANGE((ilt_start + ilt_cli->start), + (ilt_start + ilt_cli->end))); + } else { + switch (ilt_cli->client_num) { + case ILT_CLIENT_CDU: + start_reg = PXP2_REG_RQ_CDU_FIRST_ILT; + end_reg = PXP2_REG_RQ_CDU_LAST_ILT; + break; + case ILT_CLIENT_QM: + start_reg = PXP2_REG_RQ_QM_FIRST_ILT; + end_reg = PXP2_REG_RQ_QM_LAST_ILT; + break; + case ILT_CLIENT_SRC: + start_reg = PXP2_REG_RQ_SRC_FIRST_ILT; + end_reg = PXP2_REG_RQ_SRC_LAST_ILT; + break; + case ILT_CLIENT_TM: + start_reg = PXP2_REG_RQ_TM_FIRST_ILT; + end_reg = PXP2_REG_RQ_TM_LAST_ILT; + break; + } + REG_WR(bp, start_reg, (ilt_start + ilt_cli->start)); + REG_WR(bp, end_reg, (ilt_start + ilt_cli->end)); + } +} + +void bnx2x_ilt_client_init_op_ilt(struct bnx2x *bp, struct bnx2x_ilt *ilt, + struct ilt_client_info *ilt_cli, u8 initop) +{ + int i; + + if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT) + return; + + for (i = ilt_cli->start; i <= ilt_cli->end; i++) + bnx2x_ilt_line_init_op(bp, ilt, i, initop); + + /* init/clear the ILT boundries */ + bnx2x_ilt_boundry_init_op(bp, ilt_cli, ilt->start_line, initop); +} + +void bnx2x_ilt_client_init_op(struct bnx2x *bp, + struct ilt_client_info *ilt_cli, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + + bnx2x_ilt_client_init_op_ilt(bp, ilt, ilt_cli, initop); +} + +static void bnx2x_ilt_client_id_init_op(struct bnx2x *bp, + int cli_num, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + bnx2x_ilt_client_init_op(bp, ilt_cli, initop); +} + +void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop) +{ + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_CDU, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_QM, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop); + bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_TM, initop); +} + +static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num, + u32 psz_reg, u8 initop) +{ + struct bnx2x_ilt *ilt = BP_ILT(bp); + struct ilt_client_info *ilt_cli = &ilt->clients[cli_num]; + + if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT) + return; + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + REG_WR(bp, psz_reg, ILOG2(ilt_cli->page_size >> 12)); + break; + case INITOP_CLEAR: + break; + } +} + +/* + * called during init common stage, ilt clients should be initialized + * prioir to calling this function + */ +void bnx2x_ilt_init_page_size(struct bnx2x *bp, u8 initop) +{ + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_CDU, + PXP2_REG_RQ_CDU_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_QM, + PXP2_REG_RQ_QM_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_SRC, + PXP2_REG_RQ_SRC_P_SIZE, initop); + bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_TM, + PXP2_REG_RQ_TM_P_SIZE, initop); +} + +/**************************************************************************** +* QM initializations +****************************************************************************/ +#define QM_QUEUES_PER_FUNC 16 /* E1 has 32, but only 16 are used */ +#define QM_INIT_MIN_CID_COUNT 31 +#define QM_INIT(cid_cnt) (cid_cnt > QM_INIT_MIN_CID_COUNT) + +/* called during init port stage */ +void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count, + u8 initop) +{ + int port = BP_PORT(bp); + + if (QM_INIT(qm_cid_count)) { + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + REG_WR(bp, QM_REG_CONNNUM_0 + port*4, + qm_cid_count/16 - 1); + break; + case INITOP_CLEAR: + break; + } + } +} + +static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count) +{ + int i; + u32 wb_data[2]; + + wb_data[0] = wb_data[1] = 0; + + for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) { + REG_WR(bp, QM_REG_BASEADDR + i*4, + qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); + bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, + wb_data, 2); + + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, + qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); + bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, + wb_data, 2); + } + } +} + +/* called during init common stage */ +void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, + u8 initop) +{ + if (!QM_INIT(qm_cid_count)) + return; + + switch (initop) { + case INITOP_INIT: + /* set in the init-value array */ + case INITOP_SET: + bnx2x_qm_set_ptr_table(bp, qm_cid_count); + break; + case INITOP_CLEAR: + break; + } +} + +/**************************************************************************** +* SRC initializations +****************************************************************************/ + +/* called during init func stage */ +void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, + dma_addr_t t2_mapping, int src_cid_count) +{ + int i; + int port = BP_PORT(bp); + + /* Initialize T2 */ + for (i = 0; i < src_cid_count-1; i++) + t2[i].next = (u64)(t2_mapping + (i+1)*sizeof(struct src_ent)); + + /* tell the searcher where the T2 table is */ + REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, src_cid_count); + + bnx2x_wr_64(bp, SRC_REG_FIRSTFREE0 + port*16, + U64_LO(t2_mapping), U64_HI(t2_mapping)); + + bnx2x_wr_64(bp, SRC_REG_LASTFREE0 + port*16, + U64_LO((u64)t2_mapping + + (src_cid_count-1) * sizeof(struct src_ent)), + U64_HI((u64)t2_mapping + + (src_cid_count-1) * sizeof(struct src_ent))); } #endif /* BNX2X_INIT_OPS_H */ diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 0383e30663135355d9de8ea79bc7b926fe162a7d..3e99bf9c42b9a83ae18437538f42322e38413d28 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -28,7 +28,7 @@ /********************************************************/ #define ETH_HLEN 14 -#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/ +#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)/* 16 for CRC + VLAN + LLC */ #define ETH_MIN_PACKET_SIZE 60 #define ETH_MAX_PACKET_SIZE 1500 #define ETH_MAX_JUMBO_PACKET_SIZE 9600 @@ -168,50 +168,19 @@ /**********************************************************/ /* INTERFACE */ /**********************************************************/ -#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \ - bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \ - DEFAULT_PHY_DEV_ADDR, \ + +#define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \ + bnx2x_cl45_write(_bp, _phy, \ + (_phy)->def_md_devad, \ (_bank + (_addr & 0xf)), \ _val) -#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \ - bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \ - DEFAULT_PHY_DEV_ADDR, \ +#define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \ + bnx2x_cl45_read(_bp, _phy, \ + (_phy)->def_md_devad, \ (_bank + (_addr & 0xf)), \ _val) -static void bnx2x_set_serdes_access(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - - /* Set Clause 22 */ - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1); - REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000); - udelay(500); - REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f); - udelay(500); - /* Set Clause 45 */ - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0); -} -static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags) -{ - struct bnx2x *bp = params->bp; - - if (phy_flags & PHY_XGXS_FLAG) { - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + - params->port*0x18, 0); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18, - DEFAULT_PHY_DEV_ADDR); - } else { - bnx2x_set_serdes_access(params); - - REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + - params->port*0x10, - DEFAULT_PHY_DEV_ADDR); - } -} - static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) { u32 val = REG_RD(bp, reg); @@ -408,9 +377,60 @@ static u8 bnx2x_emac_enable(struct link_params *params, return 0; } +static void bnx2x_update_bmac2(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + /* + * Set rx control: Strip CRC and enable BigMAC to relay + * control packets to the system as well + */ + u32 wb_data[2]; + struct bnx2x *bp = params->bp; + u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 val = 0x14; + + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + /* Enable BigMAC to react on received Pause packets */ + val |= (1<<5); + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, + wb_data, 2); + udelay(30); + + /* Tx control */ + val = 0xc0; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + val |= 0x800000; + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, + wb_data, 2); + + val = 0x8000; + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL, + wb_data, 2); + + /* mac control */ + val = 0x3; /* Enable RX and TX */ + if (is_lb) { + val |= 0x4; /* Local loopback */ + DP(NETIF_MSG_LINK, "enable bmac loopback\n"); + } + + wb_data[0] = val; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); +} -static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, +static u8 bnx2x_bmac1_enable(struct link_params *params, + struct link_vars *vars, u8 is_lb) { struct bnx2x *bp = params->bp; @@ -420,17 +440,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, u32 wb_data[2]; u32 val; - DP(NETIF_MSG_LINK, "Enabling BigMAC\n"); - /* reset and unreset the BigMac */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - msleep(1); - - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - - /* enable access for bmac registers */ - REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); + DP(NETIF_MSG_LINK, "Enabling BigMAC1\n"); /* XGXS control */ wb_data[0] = 0x3c; @@ -510,180 +520,121 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, wb_data, 2); } - REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1); - REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); - REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); - val = 0; - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) - val = 1; - REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val); - REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0); - REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0); - REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0); - REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1); - REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1); - vars->mac_type = MAC_TYPE_BMAC; return 0; } -static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags) -{ - struct bnx2x *bp = params->bp; - u32 val; - - if (phy_flags & PHY_XGXS_FLAG) { - DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n"); - val = XGXS_RESET_BITS; - - } else { /* SerDes */ - DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n"); - val = SERDES_RESET_BITS; - } - - val = val << (params->port*16); - - /* reset and unreset the SerDes/XGXS */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, - val); - udelay(500); - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, - val); - bnx2x_set_phy_mdio(params, phy_flags); -} - -void bnx2x_link_status_update(struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_bmac2_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) { struct bnx2x *bp = params->bp; - u8 link_10g; u8 port = params->port; + u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : + NIG_REG_INGRESS_BMAC0_MEM; + u32 wb_data[2]; - if (params->switch_cfg == SWITCH_CFG_1G) - vars->phy_flags = PHY_SERDES_FLAG; - else - vars->phy_flags = PHY_XGXS_FLAG; - vars->link_status = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - port_mb[port].link_status)); - - vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); - - if (vars->link_up) { - DP(NETIF_MSG_LINK, "phy link up\n"); - - vars->phy_link_up = 1; - vars->duplex = DUPLEX_FULL; - switch (vars->link_status & - LINK_STATUS_SPEED_AND_DUPLEX_MASK) { - case LINK_10THD: - vars->duplex = DUPLEX_HALF; - /* fall thru */ - case LINK_10TFD: - vars->line_speed = SPEED_10; - break; - - case LINK_100TXHD: - vars->duplex = DUPLEX_HALF; - /* fall thru */ - case LINK_100T4: - case LINK_100TXFD: - vars->line_speed = SPEED_100; - break; - - case LINK_1000THD: - vars->duplex = DUPLEX_HALF; - /* fall thru */ - case LINK_1000TFD: - vars->line_speed = SPEED_1000; - break; - - case LINK_2500THD: - vars->duplex = DUPLEX_HALF; - /* fall thru */ - case LINK_2500TFD: - vars->line_speed = SPEED_2500; - break; - - case LINK_10GTFD: - vars->line_speed = SPEED_10000; - break; - - case LINK_12GTFD: - vars->line_speed = SPEED_12000; - break; + DP(NETIF_MSG_LINK, "Enabling BigMAC2\n"); - case LINK_12_5GTFD: - vars->line_speed = SPEED_12500; - break; + wb_data[0] = 0; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + udelay(30); - case LINK_13GTFD: - vars->line_speed = SPEED_13000; - break; + /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */ + wb_data[0] = 0x3c; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL, + wb_data, 2); - case LINK_15GTFD: - vars->line_speed = SPEED_15000; - break; + udelay(30); - case LINK_16GTFD: - vars->line_speed = SPEED_16000; - break; + /* tx MAC SA */ + wb_data[0] = ((params->mac_addr[2] << 24) | + (params->mac_addr[3] << 16) | + (params->mac_addr[4] << 8) | + params->mac_addr[5]); + wb_data[1] = ((params->mac_addr[0] << 8) | + params->mac_addr[1]); + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR, + wb_data, 2); - default: - break; - } + udelay(30); - if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED) - vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX; - else - vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX; + /* Configure SAFC */ + wb_data[0] = 0x1000200; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS, + wb_data, 2); + udelay(30); - if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED) - vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX; - else - vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX; + /* set rx mtu */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, + wb_data, 2); + udelay(30); - if (vars->phy_flags & PHY_XGXS_FLAG) { - if (vars->line_speed && - ((vars->line_speed == SPEED_10) || - (vars->line_speed == SPEED_100))) { - vars->phy_flags |= PHY_SGMII_FLAG; - } else { - vars->phy_flags &= ~PHY_SGMII_FLAG; - } - } + /* set tx mtu */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, + wb_data, 2); + udelay(30); + /* set cnt max size */ + wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2; + wb_data[1] = 0; + REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, + wb_data, 2); + udelay(30); + bnx2x_update_bmac2(params, vars, is_lb); - /* anything 10 and over uses the bmac */ - link_10g = ((vars->line_speed == SPEED_10000) || - (vars->line_speed == SPEED_12000) || - (vars->line_speed == SPEED_12500) || - (vars->line_speed == SPEED_13000) || - (vars->line_speed == SPEED_15000) || - (vars->line_speed == SPEED_16000)); - if (link_10g) - vars->mac_type = MAC_TYPE_BMAC; - else - vars->mac_type = MAC_TYPE_EMAC; + return 0; +} - } else { /* link down */ - DP(NETIF_MSG_LINK, "phy link down\n"); +u8 bnx2x_bmac_enable(struct link_params *params, + struct link_vars *vars, + u8 is_lb) +{ + u8 rc, port = params->port; + struct bnx2x *bp = params->bp; + u32 val; + /* reset and unreset the BigMac */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + udelay(10); - vars->phy_link_up = 0; + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - vars->line_speed = 0; - vars->duplex = DUPLEX_FULL; - vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + /* enable access for bmac registers */ + REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1); - /* indicate no mac active */ - vars->mac_type = MAC_TYPE_NONE; - } + /* Enable BMAC according to BMAC type*/ + if (CHIP_IS_E2(bp)) + rc = bnx2x_bmac2_enable(params, vars, is_lb); + else + rc = bnx2x_bmac1_enable(params, vars, is_lb); + REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1); + REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0); + REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0); + val = 0; + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + val = 1; + REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val); + REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0); + REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0); + REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0); + REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1); + REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1); - DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n", - vars->link_status, vars->phy_link_up); - DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", - vars->line_speed, vars->duplex, vars->flow_ctrl); + vars->mac_type = MAC_TYPE_BMAC; + return rc; } + static void bnx2x_update_mng(struct link_params *params, u32 link_status) { struct bnx2x *bp = params->bp; @@ -706,13 +657,25 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) && nig_bmac_enable) { - /* Clear Rx Enable bit in BMAC_CONTROL register */ - REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, - wb_data, 2); - wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; - REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, - wb_data, 2); - + if (CHIP_IS_E2(bp)) { + /* Clear Rx Enable bit in BMAC_CONTROL register */ + REG_RD_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC2_REGISTER_BMAC_CONTROL, + wb_data, 2); + } else { + /* Clear Rx Enable bit in BMAC_CONTROL register */ + REG_RD_DMAE(bp, bmac_addr + + BIGMAC_REGISTER_BMAC_CONTROL, + wb_data, 2); + wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; + REG_WR_DMAE(bp, bmac_addr + + BIGMAC_REGISTER_BMAC_CONTROL, + wb_data, 2); + } msleep(1); } } @@ -800,62 +763,69 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, return 0; } -static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port) +static u32 bnx2x_get_emac_base(struct bnx2x *bp, + u32 mdc_mdio_access, u8 port) { - u32 emac_base; - - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - /* All MDC/MDIO is directed through single EMAC */ + u32 emac_base = 0; + switch (mdc_mdio_access) { + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE: + break; + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0: + if (REG_RD(bp, NIG_REG_PORT_SWAP)) + emac_base = GRCBASE_EMAC1; + else + emac_base = GRCBASE_EMAC0; + break; + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1: if (REG_RD(bp, NIG_REG_PORT_SWAP)) emac_base = GRCBASE_EMAC0; else emac_base = GRCBASE_EMAC1; break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH: + emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + break; + case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED: emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; break; default: - emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; break; } return emac_base; } -u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, - u8 phy_addr, u8 devad, u16 reg, u16 val) +u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 val) { u32 tmp, saved_mode; u8 i, rc = 0; - u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port); /* set clause 45 mode, slow down the MDIO clock to 2.5MHz * (a value of 49==0x31) and make sure that the AUTO poll is off */ - saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT); tmp |= (EMAC_MDIO_MODE_CLAUSE_45 | (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); - REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); + REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); udelay(40); /* address */ - tmp = ((phy_addr << 21) | (devad << 16) | reg | + tmp = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); + tmp = REG_RD(bp, phy->mdio_ctrl + + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; @@ -866,15 +836,15 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, rc = -EFAULT; } else { /* data */ - tmp = ((phy_addr << 21) | (devad << 16) | val | + tmp = ((phy->addr << 21) | (devad << 16) | val | EMAC_MDIO_COMM_COMMAND_WRITE_45 | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); for (i = 0; i < 50; i++) { udelay(10); - tmp = REG_RD(bp, mdio_ctrl + + tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); @@ -888,42 +858,41 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, } /* Restore the saved mode */ - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); return rc; } -u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, - u8 phy_addr, u8 devad, u16 reg, u16 *ret_val) +u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 *ret_val) { u32 val, saved_mode; u16 i; u8 rc = 0; - u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port); /* set clause 45 mode, slow down the MDIO clock to 2.5MHz * (a value of 49==0x31) and make sure that the AUTO poll is off */ - saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); - val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL | + saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT)); val |= (EMAC_MDIO_MODE_CLAUSE_45 | (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); - REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); + REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); udelay(40); /* address */ - val = ((phy_addr << 21) | (devad << 16) | reg | + val = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); + val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { udelay(5); break; @@ -937,15 +906,15 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, } else { /* data */ - val = ((phy_addr << 21) | (devad << 16) | + val = ((phy->addr << 21) | (devad << 16) | EMAC_MDIO_COMM_COMMAND_READ_45 | EMAC_MDIO_COMM_START_BUSY); - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); for (i = 0; i < 50; i++) { udelay(10); - val = REG_RD(bp, mdio_ctrl + + val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); if (!(val & EMAC_MDIO_COMM_START_BUSY)) { *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); @@ -961,32 +930,262 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, } /* Restore the saved mode */ - REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); + REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); return rc; } -static void bnx2x_set_aer_mmd(struct link_params *params, - struct link_vars *vars) +u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 *ret_val) { - struct bnx2x *bp = params->bp; - u32 ser_lane; - u16 offset; + u8 phy_index; + /** + * Probe for the phy according to the given phy_addr, and execute + * the read request on it + */ + for (phy_index = 0; phy_index < params->num_phys; phy_index++) { + if (params->phy[phy_index].addr == phy_addr) { + return bnx2x_cl45_read(params->bp, + ¶ms->phy[phy_index], devad, + reg, ret_val); + } + } + return -EINVAL; +} + +u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 val) +{ + u8 phy_index; + /** + * Probe for the phy according to the given phy_addr, and execute + * the write request on it + */ + for (phy_index = 0; phy_index < params->num_phys; phy_index++) { + if (params->phy[phy_index].addr == phy_addr) { + return bnx2x_cl45_write(params->bp, + ¶ms->phy[phy_index], devad, + reg, val); + } + } + return -EINVAL; +} +static void bnx2x_set_aer_mmd_xgxs(struct link_params *params, + struct bnx2x_phy *phy) +{ + u32 ser_lane; + u16 offset, aer_val; + struct bnx2x *bp = params->bp; ser_lane = ((params->lane_config & PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - offset = (vars->phy_flags & PHY_XGXS_FLAG) ? - (params->phy_addr + ser_lane) : 0; + offset = phy->addr + ser_lane; + if (CHIP_IS_E2(bp)) + aer_val = 0x2800 + offset - 1; + else + aer_val = 0x3800 + offset; + CL45_WR_OVER_CL22(bp, phy, + MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, aer_val); +} +static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + CL45_WR_OVER_CL22(bp, phy, + MDIO_REG_BANK_AER_BLOCK, + MDIO_AER_BLOCK_AER_REG, 0x3800); +} + +/******************************************************************/ +/* Internal phy section */ +/******************************************************************/ + +static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port) +{ + u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + + /* Set Clause 22 */ + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1); + REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000); + udelay(500); + REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f); + udelay(500); + /* Set Clause 45 */ + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0); +} + +static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port) +{ + u32 val; + + DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n"); + + val = SERDES_RESET_BITS << (port*16); + + /* reset and unreset the SerDes/XGXS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); + udelay(500); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); + + bnx2x_set_serdes_access(bp, port); + + REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + + port*0x10, + DEFAULT_PHY_DEV_ADDR); +} + +static void bnx2x_xgxs_deassert(struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 port; + u32 val; + DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n"); + port = params->port; + + val = XGXS_RESET_BITS << (port*16); + + /* reset and unreset the SerDes/XGXS */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val); + udelay(500); + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val); + + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + + port*0x18, 0); + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + params->phy[INT_PHY].def_md_devad); +} + + +void bnx2x_link_status_update(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 link_10g; + u8 port = params->port; + + vars->link_status = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, + port_mb[port].link_status)); + + vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); + + if (vars->link_up) { + DP(NETIF_MSG_LINK, "phy link up\n"); + + vars->phy_link_up = 1; + vars->duplex = DUPLEX_FULL; + switch (vars->link_status & + LINK_STATUS_SPEED_AND_DUPLEX_MASK) { + case LINK_10THD: + vars->duplex = DUPLEX_HALF; + /* fall thru */ + case LINK_10TFD: + vars->line_speed = SPEED_10; + break; + + case LINK_100TXHD: + vars->duplex = DUPLEX_HALF; + /* fall thru */ + case LINK_100T4: + case LINK_100TXFD: + vars->line_speed = SPEED_100; + break; + + case LINK_1000THD: + vars->duplex = DUPLEX_HALF; + /* fall thru */ + case LINK_1000TFD: + vars->line_speed = SPEED_1000; + break; + + case LINK_2500THD: + vars->duplex = DUPLEX_HALF; + /* fall thru */ + case LINK_2500TFD: + vars->line_speed = SPEED_2500; + break; + + case LINK_10GTFD: + vars->line_speed = SPEED_10000; + break; + + case LINK_12GTFD: + vars->line_speed = SPEED_12000; + break; + + case LINK_12_5GTFD: + vars->line_speed = SPEED_12500; + break; + + case LINK_13GTFD: + vars->line_speed = SPEED_13000; + break; + + case LINK_15GTFD: + vars->line_speed = SPEED_15000; + break; + + case LINK_16GTFD: + vars->line_speed = SPEED_16000; + break; + + default: + break; + } + vars->flow_ctrl = 0; + if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED) + vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX; + + if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED) + vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX; + + if (!vars->flow_ctrl) + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + if (vars->line_speed && + ((vars->line_speed == SPEED_10) || + (vars->line_speed == SPEED_100))) { + vars->phy_flags |= PHY_SGMII_FLAG; + } else { + vars->phy_flags &= ~PHY_SGMII_FLAG; + } + + /* anything 10 and over uses the bmac */ + link_10g = ((vars->line_speed == SPEED_10000) || + (vars->line_speed == SPEED_12000) || + (vars->line_speed == SPEED_12500) || + (vars->line_speed == SPEED_13000) || + (vars->line_speed == SPEED_15000) || + (vars->line_speed == SPEED_16000)); + if (link_10g) + vars->mac_type = MAC_TYPE_BMAC; + else + vars->mac_type = MAC_TYPE_EMAC; + + } else { /* link down */ + DP(NETIF_MSG_LINK, "phy link down\n"); + + vars->phy_link_up = 0; + + vars->line_speed = 0; + vars->duplex = DUPLEX_FULL; + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + /* indicate no mac active */ + vars->mac_type = MAC_TYPE_NONE; + } - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_AER_BLOCK, - MDIO_AER_BLOCK_AER_REG, 0x3800 + offset); + DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n", + vars->link_status, vars->phy_link_up); + DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n", + vars->line_speed, vars->duplex, vars->flow_ctrl); } -static void bnx2x_set_master_ln(struct link_params *params) + +static void bnx2x_set_master_ln(struct link_params *params, + struct bnx2x_phy *phy) { struct bnx2x *bp = params->bp; u16 new_master_ln, ser_lane; @@ -995,47 +1194,44 @@ static void bnx2x_set_master_ln(struct link_params *params) PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); /* set the master_ln for AN */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TEST_MODE_LANE, &new_master_ln); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2 , MDIO_XGXS_BLOCK2_TEST_MODE_LANE, (new_master_ln | ser_lane)); } -static u8 bnx2x_reset_unicore(struct link_params *params) +static u8 bnx2x_reset_unicore(struct link_params *params, + struct bnx2x_phy *phy, + u8 set_serdes) { struct bnx2x *bp = params->bp; u16 mii_control; u16 i; - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); /* reset the unicore */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, (mii_control | MDIO_COMBO_IEEO_MII_CONTROL_RESET)); - if (params->switch_cfg == SWITCH_CFG_1G) - bnx2x_set_serdes_access(params); + if (set_serdes) + bnx2x_set_serdes_access(bp, params->port); /* wait for the reset to self clear */ for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) { udelay(5); /* the reset erased the previous bank value */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); @@ -1051,7 +1247,8 @@ static u8 bnx2x_reset_unicore(struct link_params *params) } -static void bnx2x_set_swap_lanes(struct link_params *params) +static void bnx2x_set_swap_lanes(struct link_params *params, + struct bnx2x_phy *phy) { struct bnx2x *bp = params->bp; /* Each two bits represents a lane number: @@ -1069,71 +1266,62 @@ static void bnx2x_set_swap_lanes(struct link_params *params) PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT); if (rx_lane_swap != 0x1b) { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_RX_LN_SWAP, (rx_lane_swap | MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE | MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE)); } else { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0); } if (tx_lane_swap != 0x1b) { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TX_LN_SWAP, (tx_lane_swap | MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE)); } else { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0); } } -static void bnx2x_set_parallel_detection(struct link_params *params, - u8 phy_flags) +static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 control2; - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, &control2); - if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; else control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; - DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n", - params->speed_cap_mask, control2); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n", + phy->speed_cap_mask, control2); + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, control2); - if ((phy_flags & PHY_XGXS_FLAG) && - (params->speed_cap_mask & + if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && + (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { DP(NETIF_MSG_LINK, "XGXS\n"); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, &control2); @@ -1142,15 +1330,13 @@ static void bnx2x_set_parallel_detection(struct link_params *params, control2 |= MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, control2); /* Disable parallel detection of HiG */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_XGXS_BLOCK2, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | @@ -1158,7 +1344,8 @@ static void bnx2x_set_parallel_detection(struct link_params *params, } } -static void bnx2x_set_autoneg(struct link_params *params, +static void bnx2x_set_autoneg(struct bnx2x_phy *phy, + struct link_params *params, struct link_vars *vars, u8 enable_cl73) { @@ -1166,9 +1353,7 @@ static void bnx2x_set_autoneg(struct link_params *params, u16 reg_val; /* CL37 Autoneg */ - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); @@ -1179,15 +1364,13 @@ static void bnx2x_set_autoneg(struct link_params *params, reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); /* Enable/Disable Autodetection */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, ®_val); reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN | @@ -1198,14 +1381,12 @@ static void bnx2x_set_autoneg(struct link_params *params, else reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val); /* Enable TetonII and BAM autoneg */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_BAM_NEXT_PAGE, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, ®_val); @@ -1218,23 +1399,20 @@ static void bnx2x_set_autoneg(struct link_params *params, reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); } - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_BAM_NEXT_PAGE, MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, reg_val); if (enable_cl73) { /* Enable Cl73 FSM status bits */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_UCTRL, 0xe); /* Enable BAM Station Manager*/ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_BAM_CTRL1, MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN | @@ -1242,20 +1420,18 @@ static void bnx2x_set_autoneg(struct link_params *params, MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN); /* Advertise CL73 link speeds */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, ®_val); - if (params->speed_cap_mask & + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4; - if (params->speed_cap_mask & + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV2, reg_val); @@ -1266,38 +1442,35 @@ static void bnx2x_set_autoneg(struct link_params *params, } else /* CL73 Autoneg Disabled */ reg_val = 0; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val); } /* program SerDes, forced speed */ -static void bnx2x_program_serdes(struct link_params *params, +static void bnx2x_program_serdes(struct bnx2x_phy *phy, + struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; u16 reg_val; /* program duplex, disable autoneg and sgmii*/ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, ®_val); reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX | MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK); - if (params->req_duplex == DUPLEX_FULL) + if (phy->req_duplex == DUPLEX_FULL) reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); /* program speed - needed only if the speed is greater than 1G (2.5G or 10G) */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_MISC1, ®_val); /* clearing the speed value before setting the right speed */ @@ -1320,14 +1493,14 @@ static void bnx2x_program_serdes(struct link_params *params, MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; } - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_MISC1, reg_val); } -static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) +static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 val = 0; @@ -1335,29 +1508,28 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) /* configure the 48 bits for BAM AN */ /* set extended capabilities */ - if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) val |= MDIO_OVER_1G_UP1_2_5G; - if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) + if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) val |= MDIO_OVER_1G_UP1_10G; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_UP1, val); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_UP3, 0x400); } -static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc) +static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy, + struct link_params *params, u16 *ieee_fc) { struct bnx2x *bp = params->bp; *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; /* resolve pause mode and advertisement * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ - switch (params->req_flow_ctrl) { + switch (phy->req_flow_ctrl) { case BNX2X_FLOW_CTRL_AUTO: if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) { *ieee_fc |= @@ -1385,30 +1557,30 @@ static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc) DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc); } -static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params, +static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy, + struct link_params *params, u16 ieee_fc) { struct bnx2x *bp = params->bp; u16 val; /* for AN, we are always publishing full duplex */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, &val); val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH; val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, val); } -static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) +static void bnx2x_restart_autoneg(struct bnx2x_phy *phy, + struct link_params *params, + u8 enable_cl73) { struct bnx2x *bp = params->bp; u16 mii_control; @@ -1417,14 +1589,12 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) /* Enable and restart BAM/CL37 aneg */ if (enable_cl73) { - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, &mii_control); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, (mii_control | @@ -1432,16 +1602,14 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN)); } else { - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg mii_control before = 0x%x\n", mii_control); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, (mii_control | @@ -1450,7 +1618,8 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) } } -static void bnx2x_initialize_sgmii_process(struct link_params *params, +static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy, + struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; @@ -1458,8 +1627,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params, /* in SGMII mode, the unicore is always slave */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &control1); @@ -1468,8 +1636,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params, control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET | MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, control1); @@ -1479,8 +1646,7 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params, /* set speed, disable autoneg */ u16 mii_control; - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control); @@ -1508,18 +1674,17 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params, } /* setting the full duplex */ - if (params->req_duplex == DUPLEX_FULL) + if (phy->req_duplex == DUPLEX_FULL) mii_control |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_MII_CONTROL, mii_control); } else { /* AN mode */ /* enable and restart AN */ - bnx2x_restart_autoneg(params, 0); + bnx2x_restart_autoneg(phy, params, 0); } } @@ -1549,91 +1714,24 @@ static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) default: break; } + if (pause_result & (1<<0)) + vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE; + if (pause_result & (1<<1)) + vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE; } -static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u8 ext_phy_addr; - u16 ld_pause; /* local */ - u16 lp_pause; /* link partner */ - u16 an_complete; /* AN complete */ - u16 pause_result; - u8 ret = 0; - u32 ext_phy_type; - u8 port = params->port; - ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - /* read twice */ - - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_STATUS, &an_complete); - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_STATUS, &an_complete); - - if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) { - ret = 1; - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, &ld_pause); - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); - pause_result = (ld_pause & - MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; - pause_result |= (lp_pause & - MDIO_AN_REG_ADV_PAUSE_MASK) >> 10; - DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", - pause_result); - bnx2x_pause_resolve(vars, pause_result); - if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE && - ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, &ld_pause); - - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LP, &lp_pause); - pause_result = (ld_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5; - pause_result |= (lp_pause & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; - - bnx2x_pause_resolve(vars, pause_result); - DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", - pause_result); - } - } - return ret; -} - -static u8 bnx2x_direct_parallel_detect_used(struct link_params *params) +static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 pd_10g, status2_1000x; - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + if (phy->req_line_speed != SPEED_AUTO_NEG) + return 0; + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_STATUS2, &status2_1000x); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_SERDES_DIGITAL, MDIO_SERDES_DIGITAL_A_1000X_STATUS2, &status2_1000x); @@ -1643,8 +1741,7 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params) return 1; } - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_10G_PARALLEL_DETECT, MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, &pd_10g); @@ -1657,9 +1754,10 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params) return 0; } -static void bnx2x_flow_ctrl_resolve(struct link_params *params, - struct link_vars *vars, - u32 gp_status) +static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars, + u32 gp_status) { struct bnx2x *bp = params->bp; u16 ld_pause; /* local driver */ @@ -1669,12 +1767,13 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; /* resolve from gp_status in case of AN complete and not sgmii */ - if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && - (!(vars->phy_flags & PHY_SGMII_FLAG)) && - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) { - if (bnx2x_direct_parallel_detect_used(params)) { + if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) + vars->flow_ctrl = phy->req_flow_ctrl; + else if (phy->req_line_speed != SPEED_AUTO_NEG) + vars->flow_ctrl = params->req_fc_auto_adv; + else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && + (!(vars->phy_flags & PHY_SGMII_FLAG))) { + if (bnx2x_direct_parallel_detect_used(phy, params)) { vars->flow_ctrl = params->req_fc_auto_adv; return; } @@ -1684,13 +1783,11 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) { - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_ADV1, &ld_pause); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB1, MDIO_CL73_IEEEB1_AN_LP_ADV1, &lp_pause); @@ -1703,14 +1800,11 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", pause_result); } else { - - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_ADV, &ld_pause); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_COMBO_IEEE0, MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1, &lp_pause); @@ -1722,26 +1816,18 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params, pause_result); } bnx2x_pause_resolve(vars, pause_result); - } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - (bnx2x_ext_phy_resolve_fc(params, vars))) { - return; - } else { - if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) - vars->flow_ctrl = params->req_fc_auto_adv; - else - vars->flow_ctrl = params->req_flow_ctrl; } DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl); } -static void bnx2x_check_fallback_to_cl37(struct link_params *params) +static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 rx_status, ustat_val, cl37_fsm_recieved; DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n"); /* Step 1: Make sure signal is detected */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_RX0, MDIO_RX0_RX_STATUS, &rx_status); @@ -1749,16 +1835,14 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params) (MDIO_RX0_RX_STATUS_SIGDET)) { DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73." "rx_status(0x80b0) = 0x%x\n", rx_status); - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN); return; } /* Step 2: Check CL73 state machine */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_USERB0, MDIO_CL73_USERB0_CL73_USTAT1, &ustat_val); @@ -1773,8 +1857,7 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params) } /* Step 3: Check CL37 Message Pages received to indicate LP supports only CL37 */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_REMOTE_PHY, MDIO_REMOTE_PHY_MISC_RX_STATUS, &cl37_fsm_recieved); @@ -1792,25 +1875,45 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params) connected to a device which does not support cl73, but does support cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */ /* Disable CL73 */ - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, MDIO_REG_BANK_CL73_IEEEB0, MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 0); /* Restart CL37 autoneg */ - bnx2x_restart_autoneg(params, 0); + bnx2x_restart_autoneg(phy, params, 0); DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n"); } -static u8 bnx2x_link_settings_status(struct link_params *params, - struct link_vars *vars, - u32 gp_status, - u8 ext_phy_link_up) + +static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars, + u32 gp_status) +{ + if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) + vars->link_status |= + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + + if (bnx2x_direct_parallel_detect_used(phy, params)) + vars->link_status |= + LINK_STATUS_PARALLEL_DETECTION_USED; +} + +static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 new_line_speed; + u16 new_line_speed , gp_status; u8 rc = 0; - vars->link_status = 0; + /* Read gp_status */ + CL45_RD_OVER_CL22(bp, phy, + MDIO_REG_BANK_GP_STATUS, + MDIO_GP_STATUS_TOP_AN_STATUS1, + &gp_status); + + if (phy->req_line_speed == SPEED_AUTO_NEG) + vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED; if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n", gp_status); @@ -1823,7 +1926,12 @@ static u8 bnx2x_link_settings_status(struct link_params *params, else vars->duplex = DUPLEX_HALF; - bnx2x_flow_ctrl_resolve(params, vars, gp_status); + if (SINGLE_MEDIA_DIRECT(params)) { + bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); + if (phy->req_line_speed == SPEED_AUTO_NEG) + bnx2x_xgxs_an_resolve(phy, params, vars, + gp_status); + } switch (gp_status & GP_STATUS_SPEED_MASK) { case GP_STATUS_10M: @@ -1905,96 +2013,41 @@ static u8 bnx2x_link_settings_status(struct link_params *params, return -EINVAL; } - /* Upon link speed change set the NIG into drain mode. - Comes to deals with possible FIFO glitch due to clk change - when speed is decreased without link down indicator */ - if (new_line_speed != vars->line_speed) { - if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) != - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT && - ext_phy_link_up) { - DP(NETIF_MSG_LINK, "Internal link speed %d is" - " different than the external" - " link speed %d\n", new_line_speed, - vars->line_speed); - vars->phy_link_up = 0; - return 0; - } - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE - + params->port*4, 0); - msleep(1); - } vars->line_speed = new_line_speed; - vars->link_status |= LINK_STATUS_SERDES_LINK; - - if ((params->req_line_speed == SPEED_AUTO_NEG) && - ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) { - vars->autoneg = AUTO_NEG_ENABLED; - - if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { - vars->autoneg |= AUTO_NEG_COMPLETE; - vars->link_status |= - LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; - } - vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED; - vars->link_status |= - LINK_STATUS_PARALLEL_DETECTION_USED; - - } - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) - vars->link_status |= - LINK_STATUS_TX_FLOW_CONTROL_ENABLED; - - if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) - vars->link_status |= - LINK_STATUS_RX_FLOW_CONTROL_ENABLED; - - } else { /* link_down */ - DP(NETIF_MSG_LINK, "phy link down\n"); + } else { /* link_down */ + DP(NETIF_MSG_LINK, "phy link down\n"); vars->phy_link_up = 0; vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - vars->autoneg = AUTO_NEG_DISABLED; vars->mac_type = MAC_TYPE_NONE; - if ((params->req_line_speed == SPEED_AUTO_NEG) && - ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) { + if ((phy->req_line_speed == SPEED_AUTO_NEG) && + SINGLE_MEDIA_DIRECT(params)) { /* Check signal is detected */ - bnx2x_check_fallback_to_cl37(params); + bnx2x_check_fallback_to_cl37(phy, params); } } DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n", gp_status, vars->phy_link_up, vars->line_speed); - DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x" - " autoneg 0x%x\n", - vars->duplex, - vars->flow_ctrl, vars->autoneg); - DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status); - + DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n", + vars->duplex, vars->flow_ctrl, vars->link_status); return rc; } static void bnx2x_set_gmii_tx_driver(struct link_params *params) { struct bnx2x *bp = params->bp; + struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; u16 lp_up2; u16 tx_driver; u16 bank; /* read precomp */ - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, MDIO_REG_BANK_OVER_1G, MDIO_OVER_1G_LP_UP2, &lp_up2); @@ -2008,8 +2061,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3; bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) { - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_RD_OVER_CL22(bp, phy, bank, MDIO_TX0_TX_DRIVER, &tx_driver); @@ -2018,8 +2070,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) { tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; tx_driver |= lp_up2; - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, + CL45_WR_OVER_CL22(bp, phy, bank, MDIO_TX0_TX_DRIVER, tx_driver); } @@ -2027,7 +2078,7 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params) } static u8 bnx2x_emac_program(struct link_params *params, - u32 line_speed, u32 duplex) + struct link_vars *vars) { struct bnx2x *bp = params->bp; u8 port = params->port; @@ -2039,7 +2090,7 @@ static u8 bnx2x_emac_program(struct link_params *params, (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_MII_10M | EMAC_MODE_HALF_DUPLEX)); - switch (line_speed) { + switch (vars->line_speed) { case SPEED_10: mode |= EMAC_MODE_PORT_MII_10M; break; @@ -2058,382 +2109,1382 @@ static u8 bnx2x_emac_program(struct link_params *params, default: /* 10G not valid for EMAC */ - DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed); + DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", + vars->line_speed); return -EINVAL; } - if (duplex == DUPLEX_HALF) + if (vars->duplex == DUPLEX_HALF) mode |= EMAC_MODE_HALF_DUPLEX; bnx2x_bits_en(bp, GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, mode); - bnx2x_set_led(params, LED_MODE_OPER, line_speed); + bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed); return 0; } -/*****************************************************************************/ -/* External Phy section */ -/*****************************************************************************/ -void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) +static void bnx2x_set_preemphasis(struct bnx2x_phy *phy, + struct link_params *params) { - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - msleep(1); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); + + u16 bank, i = 0; + struct bnx2x *bp = params->bp; + + for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; + bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { + CL45_WR_OVER_CL22(bp, phy, + bank, + MDIO_RX0_RX_EQ_BOOST, + phy->rx_preemphasis[i]); + } + + for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; + bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) { + CL45_WR_OVER_CL22(bp, phy, + bank, + MDIO_TX0_TX_DRIVER, + phy->tx_preemphasis[i]); + } } -static void bnx2x_ext_phy_reset(struct link_params *params, - struct link_vars *vars) +static void bnx2x_init_internal_phy(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 ext_phy_type; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - - DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - /* The PHY reset is controled by GPIO 1 - * Give it 1ms of reset pulse - */ - if (vars->phy_flags & PHY_XGXS_FLAG) { + u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) || + (params->loopback_mode == LOOPBACK_XGXS)); + if (!(vars->phy_flags & PHY_SGMII_FLAG)) { + if (SINGLE_MEDIA_DIRECT(params) && + (params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) + bnx2x_set_preemphasis(phy, params); - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "XGXS Direct\n"); - break; + /* forced speed requested? */ + if (vars->line_speed != SPEED_AUTO_NEG || + (SINGLE_MEDIA_DIRECT(params) && + params->loopback_mode == LOOPBACK_EXT)) { + DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - DP(NETIF_MSG_LINK, "XGXS 8705/8706\n"); + /* disable autoneg */ + bnx2x_set_autoneg(phy, params, vars, 0); - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); + /* program speed and duplex */ + bnx2x_program_serdes(phy, params, vars); - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); + } else { /* AN_mode */ + DP(NETIF_MSG_LINK, "not SGMII, AN\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0xa040); - break; + /* AN enabled */ + bnx2x_set_brcm_cl37_advertisment(phy, params); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - break; + /* program duplex & pause advertisement (for aneg) */ + bnx2x_set_ieee_aneg_advertisment(phy, params, + vars->ieee_fc); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + /* enable autoneg */ + bnx2x_set_autoneg(phy, params, vars, enable_cl73); - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); + /* enable and restart AN */ + bnx2x_restart_autoneg(phy, params, enable_cl73); + } - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); + } else { /* SGMII mode */ + DP(NETIF_MSG_LINK, "SGMII\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 1<<15); - break; + bnx2x_initialize_sgmii_process(phy, params, vars); + } +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - DP(NETIF_MSG_LINK, "XGXS 8072\n"); +static u8 bnx2x_init_serdes(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 rc; + vars->phy_flags |= PHY_SGMII_FLAG; + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + bnx2x_set_aer_mmd_serdes(params->bp, phy); + rc = bnx2x_reset_unicore(params, phy, 1); + /* reset the SerDes and wait for reset bit return low */ + if (rc != 0) + return rc; + bnx2x_set_aer_mmd_serdes(params->bp, phy); - /* Unset Low Power Mode and SW reset */ - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); + return rc; +} - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 1<<15); - break; +static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 rc; + vars->phy_flags = PHY_XGXS_FLAG; + if ((phy->req_line_speed && + ((phy->req_line_speed == SPEED_100) || + (phy->req_line_speed == SPEED_10))) || + (!phy->req_line_speed && + (phy->speed_cap_mask >= + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && + (phy->speed_cap_mask < + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) + )) + vars->phy_flags |= PHY_SGMII_FLAG; + else + vars->phy_flags &= ~PHY_SGMII_FLAG; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - DP(NETIF_MSG_LINK, "XGXS 8073\n"); + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + bnx2x_set_aer_mmd_xgxs(params, phy); + bnx2x_set_master_ln(params, phy); - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); + rc = bnx2x_reset_unicore(params, phy, 0); + /* reset the SerDes and wait for reset bit return low */ + if (rc != 0) + return rc; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - break; + bnx2x_set_aer_mmd_xgxs(params, phy); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - DP(NETIF_MSG_LINK, "XGXS SFX7101\n"); + /* setting the masterLn_def again after the reset */ + bnx2x_set_master_ln(params, phy); + bnx2x_set_swap_lanes(params, phy); - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); + return rc; +} - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); +static u16 bnx2x_wait_reset_complete(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + u16 cnt, ctrl; + /* Wait for soft reset to get cleared upto 1 sec */ + for (cnt = 0; cnt < 1000; cnt++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl); + if (!(ctrl & (1<<15))) break; + msleep(1); + } + DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt); + return cnt; +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - /* Restore normal power mode*/ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_HIGH, - params->port); - - /* HW reset */ - bnx2x_ext_phy_hw_reset(bp, params->port); +static void bnx2x_link_int_enable(struct link_params *params) +{ + u8 port = params->port; + u32 mask; + struct bnx2x *bp = params->bp; - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 1<<15); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n"); - break; + /* setting the status to report on link up + for either XGXS or SerDes */ - default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - params->ext_phy_config); - break; + if (params->switch_cfg == SWITCH_CFG_10G) { + mask = (NIG_MASK_XGXS0_LINK10G | + NIG_MASK_XGXS0_LINK_STATUS); + DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); + if (!(SINGLE_MEDIA_DIRECT(params)) && + params->phy[INT_PHY].type != + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) { + mask |= NIG_MASK_MI_INT; + DP(NETIF_MSG_LINK, "enabled external phy int\n"); } } else { /* SerDes */ - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "SerDes Direct\n"); - break; - - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - DP(NETIF_MSG_LINK, "SerDes 5482\n"); - bnx2x_ext_phy_hw_reset(bp, params->port); - break; - - default: - DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", - params->ext_phy_config); - break; + mask = NIG_MASK_SERDES0_LINK_STATUS; + DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); + if (!(SINGLE_MEDIA_DIRECT(params)) && + params->phy[INT_PHY].type != + PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) { + mask |= NIG_MASK_MI_INT; + DP(NETIF_MSG_LINK, "enabled external phy int\n"); } } -} - -static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, - u32 shmem_base, u32 spirom_ver) -{ - DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", - (u16)(spirom_ver>>16), (u16)spirom_ver, port); - REG_WR(bp, shmem_base + - offsetof(struct shmem_region, - port_mb[port].ext_phy_fw_version), - spirom_ver); -} - -static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port, - u32 ext_phy_type, u8 ext_phy_addr, - u32 shmem_base) -{ - u16 fw_ver1, fw_ver2; + bnx2x_bits_en(bp, + NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + mask); - bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER1, &fw_ver1); - bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, &fw_ver2); - bnx2x_save_spirom_version(bp, port, shmem_base, - (u32)(fw_ver1<<16 | fw_ver2)); + DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port, + (params->switch_cfg == SWITCH_CFG_10G), + REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); + DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n", + REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), + REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), + REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c)); + DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); } - -static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port, - u8 ext_phy_addr, u32 shmem_base) +static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port, + u8 exp_mi_int) { - u16 val, fw_ver1, fw_ver2, cnt; - /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/ - /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, MDIO_PMA_DEVAD, - 0xA819, 0x0014); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - 0xA81A, - 0xc200); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - 0xA81B, - 0x0000); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - 0xA81C, - 0x0300); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - 0xA817, - 0x0009); + u32 latch_status = 0; - for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - 0xA818, - &val); - if (val & 1) - break; - udelay(5); - } - if (cnt == 100) { - DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n"); - bnx2x_save_spirom_version(bp, port, - shmem_base, 0); - return; - } + /** + * Disable the MI INT ( external phy int ) by writing 1 to the + * status register. Link down indication is high-active-signal, + * so in this case we need to write the status to clear the XOR + */ + /* Read Latched signals */ + latch_status = REG_RD(bp, + NIG_REG_LATCH_STATUS_0 + port*8); + DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status); + /* Handle only those with latched-signal=up.*/ + if (exp_mi_int) + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + + port*4, + NIG_STATUS_EMAC0_MI_INT); + else + bnx2x_bits_dis(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + + port*4, + NIG_STATUS_EMAC0_MI_INT); + if (latch_status & 1) { - /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, MDIO_PMA_DEVAD, - 0xA819, 0x0000); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, MDIO_PMA_DEVAD, - 0xA81A, 0xc200); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, MDIO_PMA_DEVAD, - 0xA817, 0x000A); - for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - 0xA818, - &val); - if (val & 1) - break; - udelay(5); - } - if (cnt == 100) { - DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n"); - bnx2x_save_spirom_version(bp, port, - shmem_base, 0); - return; + /* For all latched-signal=up : Re-Arm Latch signals */ + REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, + (latch_status & 0xfffe) | (latch_status & 1)); } - - /* lower 16 bits of the register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - 0xA81B, - &fw_ver1); - /* upper 16 bits of register SPI_FW_STATUS */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - 0xA81C, - &fw_ver2); - - bnx2x_save_spirom_version(bp, port, - shmem_base, (fw_ver2<<16) | fw_ver1); + /* For all latched-signal=up,Write original_signal to status */ } -static void bnx2x_bcm8072_external_rom_boot(struct link_params *params) +static void bnx2x_link_int_ack(struct link_params *params, + struct link_vars *vars, u8 is_10g) { struct bnx2x *bp = params->bp; u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - /* Need to wait 200ms after reset */ - msleep(200); - /* Boot port from external ROM - * Set ser_boot_ctl bit in the MISC_CTRL1 register - */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); + /* first reset all status + * we assume only one line will be change at a time */ + bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS)); + if (vars->phy_link_up) { + if (is_10g) { + /* Disable the 10G link interrupt + * by writing 1 to the status register + */ + DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + NIG_STATUS_XGXS0_LINK10G); - /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); - /* set micro reset = 0 */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); - /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); - /* wait for 100ms for code download via SPI port */ - msleep(100); + } else if (params->switch_cfg == SWITCH_CFG_10G) { + /* Disable the link interrupt + * by writing 1 to the relevant lane + * in the status register + */ + u32 ser_lane = ((params->lane_config & + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> + PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); - /* Clear ser_boot_ctl bit */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0000); - /* Wait 100ms */ - msleep(100); + DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n", + vars->line_speed); + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + ((1 << ser_lane) << + NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); + + } else { /* SerDes */ + DP(NETIF_MSG_LINK, "SerDes phy link up\n"); + /* Disable the link interrupt + * by writing 1 to the status register + */ + bnx2x_bits_en(bp, + NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, + NIG_STATUS_SERDES0_LINK_STATUS); + } - bnx2x_save_bcm_spirom_ver(bp, port, - ext_phy_type, - ext_phy_addr, - params->shmem_base); + } } -static u8 bnx2x_8073_is_snr_needed(struct link_params *params) +static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len) { - /* This is only required for 8073A1, version 102 only */ + u8 *str_ptr = str; + u32 mask = 0xf0000000; + u8 shift = 8*4; + u8 digit; + u8 remove_leading_zeros = 1; + if (*len < 10) { + /* Need more than 10chars for this format */ + *str_ptr = '\0'; + (*len)--; + return -EINVAL; + } + while (shift > 0) { - struct bnx2x *bp = params->bp; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u16 val; + shift -= 4; + digit = ((num & mask) >> shift); + if (digit == 0 && remove_leading_zeros) { + mask = mask >> 4; + continue; + } else if (digit < 0xa) + *str_ptr = digit + '0'; + else + *str_ptr = digit - 0xa + 'a'; + remove_leading_zeros = 0; + str_ptr++; + (*len)--; + mask = mask >> 4; + if (shift == 4*4) { + *str_ptr = '.'; + str_ptr++; + (*len)--; + remove_leading_zeros = 1; + } + } + return 0; +} - /* Read 8073 HW revision*/ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &val); + +static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len) +{ + str[0] = '\0'; + (*len)--; + return 0; +} + +u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, + u8 *version, u16 len) +{ + struct bnx2x *bp; + u32 spirom_ver = 0; + u8 status = 0; + u8 *ver_p = version; + u16 remain_len = len; + if (version == NULL || params == NULL) + return -EINVAL; + bp = params->bp; + + /* Extract first external phy*/ + version[0] = '\0'; + spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr); + + if (params->phy[EXT_PHY1].format_fw_ver) { + status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver, + ver_p, + &remain_len); + ver_p += (len - remain_len); + } + if ((params->num_phys == MAX_PHYS) && + (params->phy[EXT_PHY2].ver_addr != 0)) { + spirom_ver = REG_RD(bp, + params->phy[EXT_PHY2].ver_addr); + if (params->phy[EXT_PHY2].format_fw_ver) { + *ver_p = '/'; + ver_p++; + remain_len--; + status |= params->phy[EXT_PHY2].format_fw_ver( + spirom_ver, + ver_p, + &remain_len); + ver_p = version + (len - remain_len); + } + } + *ver_p = '\0'; + return status; +} + +static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy, + struct link_params *params) +{ + u8 port = params->port; + struct bnx2x *bp = params->bp; + + if (phy->req_line_speed != SPEED_1000) { + u32 md_devad; + + DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); + + /* change the uni_phy_addr in the nig */ + md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + + port*0x18)); + + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); + + bnx2x_cl45_write(bp, phy, + 5, + (MDIO_REG_BANK_AER_BLOCK + + (MDIO_AER_BLOCK_AER_REG & 0xf)), + 0x2800); + + bnx2x_cl45_write(bp, phy, + 5, + (MDIO_REG_BANK_CL73_IEEEB0 + + (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), + 0x6041); + msleep(200); + /* set aer mmd back */ + bnx2x_set_aer_mmd_xgxs(params, phy); + + /* and md_devad */ + REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, + md_devad); + + } else { + u16 mii_ctrl; + DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); + bnx2x_cl45_read(bp, phy, 5, + (MDIO_REG_BANK_COMBO_IEEE0 + + (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), + &mii_ctrl); + bnx2x_cl45_write(bp, phy, 5, + (MDIO_REG_BANK_COMBO_IEEE0 + + (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)), + mii_ctrl | + MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK); + } +} + +/* + *------------------------------------------------------------------------ + * bnx2x_override_led_value - + * + * Override the led value of the requested led + * + *------------------------------------------------------------------------ + */ +u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, + u32 led_idx, u32 value) +{ + u32 reg_val; + + /* If port 0 then use EMAC0, else use EMAC1*/ + u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + + DP(NETIF_MSG_LINK, + "bnx2x_override_led_value() port %x led_idx %d value %d\n", + port, led_idx, value); + + switch (led_idx) { + case 0: /* 10MB led */ + /* Read the current value of the LED register in + the EMAC block */ + reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); + /* Set the OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the 10M_OVERRIDE bit, + otherwise reset it.*/ + reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) : + (reg_val & ~EMAC_LED_10MB_OVERRIDE); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + break; + case 1: /*100MB led */ + /*Read the current value of the LED register in + the EMAC block */ + reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); + /* Set the OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the 100M_OVERRIDE bit, + otherwise reset it.*/ + reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) : + (reg_val & ~EMAC_LED_100MB_OVERRIDE); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + break; + case 2: /* 1000MB led */ + /* Read the current value of the LED register in the + EMAC block */ + reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); + /* Set the OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the 1000M_OVERRIDE bit, otherwise + reset it. */ + reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) : + (reg_val & ~EMAC_LED_1000MB_OVERRIDE); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + break; + case 3: /* 2500MB led */ + /* Read the current value of the LED register in the + EMAC block*/ + reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); + /* Set the OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the 2500M_OVERRIDE bit, otherwise + reset it.*/ + reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) : + (reg_val & ~EMAC_LED_2500MB_OVERRIDE); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + break; + case 4: /*10G led */ + if (port == 0) { + REG_WR(bp, NIG_REG_LED_10G_P0, + value); + } else { + REG_WR(bp, NIG_REG_LED_10G_P1, + value); + } + break; + case 5: /* TRAFFIC led */ + /* Find if the traffic control is via BMAC or EMAC */ + if (port == 0) + reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN); + else + reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN); + + /* Override the traffic led in the EMAC:*/ + if (reg_val == 1) { + /* Read the current value of the LED register in + the EMAC block */ + reg_val = REG_RD(bp, emac_base + + EMAC_REG_EMAC_LED); + /* Set the TRAFFIC_OVERRIDE bit to 1 */ + reg_val |= EMAC_LED_OVERRIDE; + /* If value is 1, set the TRAFFIC bit, otherwise + reset it.*/ + reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) : + (reg_val & ~EMAC_LED_TRAFFIC); + REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + } else { /* Override the traffic led in the BMAC: */ + REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + + port*4, 1); + REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, + value); + } + break; + default: + DP(NETIF_MSG_LINK, + "bnx2x_override_led_value() unknown led index %d " + "(should be 0-5)\n", led_idx); + return -EINVAL; + } + + return 0; +} + + +u8 bnx2x_set_led(struct link_params *params, + struct link_vars *vars, u8 mode, u32 speed) +{ + u8 port = params->port; + u16 hw_led_mode = params->hw_led_mode; + u8 rc = 0, phy_idx; + u32 tmp; + u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); + DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", + speed, hw_led_mode); + /* In case */ + for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) { + if (params->phy[phy_idx].set_link_led) { + params->phy[phy_idx].set_link_led( + ¶ms->phy[phy_idx], params, mode); + } + } + + switch (mode) { + case LED_MODE_FRONT_PANEL_OFF: + case LED_MODE_OFF: + REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, + SHARED_HW_CFG_LED_MAC1); + + tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); + EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE)); + break; + + case LED_MODE_OPER: + /** + * For all other phys, OPER mode is same as ON, so in case + * link is down, do nothing + **/ + if (!vars->link_up) + break; + case LED_MODE_ON: + if (SINGLE_MEDIA_DIRECT(params)) { + /** + * This is a work-around for HW issue found when link + * is up in CL73 + */ + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); + REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); + } else { + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, + hw_led_mode); + } + + REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + + port*4, 0); + /* Set blinking rate to ~15.9Hz */ + REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4, + LED_BLINK_RATE_VAL); + REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + + port*4, 1); + tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); + EMAC_WR(bp, EMAC_REG_EMAC_LED, + (tmp & (~EMAC_LED_OVERRIDE))); + + if (CHIP_IS_E1(bp) && + ((speed == SPEED_2500) || + (speed == SPEED_1000) || + (speed == SPEED_100) || + (speed == SPEED_10))) { + /* On Everest 1 Ax chip versions for speeds less than + 10G LED scheme is different */ + REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + + port*4, 1); + REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + + port*4, 0); + REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + + port*4, 1); + } + break; + + default: + rc = -EINVAL; + DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n", + mode); + break; + } + return rc; + +} + +/** + * This function comes to reflect the actual link state read DIRECTLY from the + * HW + */ +u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars, + u8 is_serdes) +{ + struct bnx2x *bp = params->bp; + u16 gp_status = 0, phy_index = 0; + u8 ext_phy_link_up = 0, serdes_phy_type; + struct link_vars temp_vars; + + CL45_RD_OVER_CL22(bp, ¶ms->phy[INT_PHY], + MDIO_REG_BANK_GP_STATUS, + MDIO_GP_STATUS_TOP_AN_STATUS1, + &gp_status); + /* link is up only if both local phy and external phy are up */ + if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)) + return -ESRCH; + + switch (params->num_phys) { + case 1: + /* No external PHY */ + return 0; + case 2: + ext_phy_link_up = params->phy[EXT_PHY1].read_status( + ¶ms->phy[EXT_PHY1], + params, &temp_vars); + break; + case 3: /* Dual Media */ + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + serdes_phy_type = ((params->phy[phy_index].media_type == + ETH_PHY_SFP_FIBER) || + (params->phy[phy_index].media_type == + ETH_PHY_XFP_FIBER)); + + if (is_serdes != serdes_phy_type) + continue; + if (params->phy[phy_index].read_status) { + ext_phy_link_up |= + params->phy[phy_index].read_status( + ¶ms->phy[phy_index], + params, &temp_vars); + } + } + break; + } + if (ext_phy_link_up) + return 0; + return -ESRCH; +} + +static u8 bnx2x_link_initialize(struct link_params *params, + struct link_vars *vars) +{ + u8 rc = 0; + u8 phy_index, non_ext_phy; + struct bnx2x *bp = params->bp; + /** + * In case of external phy existence, the line speed would be the + * line speed linked up by the external phy. In case it is direct + * only, then the line_speed during initialization will be + * equal to the req_line_speed + */ + vars->line_speed = params->phy[INT_PHY].req_line_speed; + + /** + * Initialize the internal phy in case this is a direct board + * (no external phys), or this board has external phy which requires + * to first. + */ + + if (params->phy[INT_PHY].config_init) + params->phy[INT_PHY].config_init( + ¶ms->phy[INT_PHY], + params, vars); + + /* init ext phy and enable link state int */ + non_ext_phy = (SINGLE_MEDIA_DIRECT(params) || + (params->loopback_mode == LOOPBACK_XGXS)); + + if (non_ext_phy || + (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) || + (params->loopback_mode == LOOPBACK_EXT_PHY)) { + struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; + if (vars->line_speed == SPEED_AUTO_NEG) + bnx2x_set_parallel_detection(phy, params); + bnx2x_init_internal_phy(phy, params, vars); + } + + /* Init external phy*/ + if (!non_ext_phy) + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + /** + * No need to initialize second phy in case of first + * phy only selection. In case of second phy, we do + * need to initialize the first phy, since they are + * connected. + **/ + if (phy_index == EXT_PHY2 && + (bnx2x_phy_selection(params) == + PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) { + DP(NETIF_MSG_LINK, "Not initializing" + "second phy\n"); + continue; + } + params->phy[phy_index].config_init( + ¶ms->phy[phy_index], + params, vars); + } + + /* Reset the interrupt indication after phy was initialized */ + bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + + params->port*4, + (NIG_STATUS_XGXS0_LINK10G | + NIG_STATUS_XGXS0_LINK_STATUS | + NIG_STATUS_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); + return rc; +} + +static void bnx2x_int_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + /* reset the SerDes/XGXS */ + REG_WR(params->bp, GRCBASE_MISC + + MISC_REGISTERS_RESET_REG_3_CLEAR, + (0x1ff << (params->port*16))); +} + +static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 gpio_port; + /* HW reset */ + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); + DP(NETIF_MSG_LINK, "reset external PHY\n"); +} + +static u8 bnx2x_update_link_down(struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 port = params->port; + + DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); + bnx2x_set_led(params, vars, LED_MODE_OFF, 0); + + /* indicate no mac active */ + vars->mac_type = MAC_TYPE_NONE; + + /* update shared memory */ + vars->link_status = 0; + vars->line_speed = 0; + bnx2x_update_mng(params, vars->link_status); + + /* activate nig drain */ + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); + + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + + msleep(10); + + /* reset BigMac */ + bnx2x_bmac_rx_disable(bp, params->port); + REG_WR(bp, GRCBASE_MISC + + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); + return 0; +} + +static u8 bnx2x_update_link_up(struct link_params *params, + struct link_vars *vars, + u8 link_10g) +{ + struct bnx2x *bp = params->bp; + u8 port = params->port; + u8 rc = 0; + + vars->link_status |= LINK_STATUS_LINK_UP; + + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) + vars->link_status |= + LINK_STATUS_TX_FLOW_CONTROL_ENABLED; + + if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX) + vars->link_status |= + LINK_STATUS_RX_FLOW_CONTROL_ENABLED; + + if (link_10g) { + bnx2x_bmac_enable(params, vars, 0); + bnx2x_set_led(params, vars, + LED_MODE_OPER, SPEED_10000); + } else { + rc = bnx2x_emac_program(params, vars); + + bnx2x_emac_enable(params, vars, 0); + + /* AN complete? */ + if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) + && (!(vars->phy_flags & PHY_SGMII_FLAG)) && + SINGLE_MEDIA_DIRECT(params)) + bnx2x_set_gmii_tx_driver(params); + } + + /* PBF - link up */ + if (!(CHIP_IS_E2(bp))) + rc |= bnx2x_pbf_update(params, vars->flow_ctrl, + vars->line_speed); + + /* disable drain */ + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); + + /* update shared memory */ + bnx2x_update_mng(params, vars->link_status); + msleep(20); + return rc; +} +/** + * The bnx2x_link_update function should be called upon link + * interrupt. + * Link is considered up as follows: + * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs + * to be up + * - SINGLE_MEDIA - The link between the 577xx and the external + * phy (XGXS) need to up as well as the external link of the + * phy (PHY_EXT1) + * - DUAL_MEDIA - The link between the 577xx and the first + * external phy needs to be up, and at least one of the 2 + * external phy link must be up. + */ +u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + struct link_vars phy_vars[MAX_PHYS]; + u8 port = params->port; + u8 link_10g, phy_index; + u8 ext_phy_link_up = 0, cur_link_up, rc = 0; + u8 is_mi_int = 0; + u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed; + u8 active_external_phy = INT_PHY; + vars->link_status = 0; + for (phy_index = INT_PHY; phy_index < params->num_phys; + phy_index++) { + phy_vars[phy_index].flow_ctrl = 0; + phy_vars[phy_index].link_status = 0; + phy_vars[phy_index].line_speed = 0; + phy_vars[phy_index].duplex = DUPLEX_FULL; + phy_vars[phy_index].phy_link_up = 0; + phy_vars[phy_index].link_up = 0; + } + + DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", + port, (vars->phy_flags & PHY_XGXS_FLAG), + REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); + + is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + + port*0x18) > 0); + DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n", + REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), + is_mi_int, + REG_RD(bp, + NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); + + DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), + REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); + + /* disable emac */ + REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); + + /** + * Step 1: + * Check external link change only for external phys, and apply + * priority selection between them in case the link on both phys + * is up. Note that the instead of the common vars, a temporary + * vars argument is used since each phy may have different link/ + * speed/duplex result + */ + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + struct bnx2x_phy *phy = ¶ms->phy[phy_index]; + if (!phy->read_status) + continue; + /* Read link status and params of this ext phy */ + cur_link_up = phy->read_status(phy, params, + &phy_vars[phy_index]); + if (cur_link_up) { + DP(NETIF_MSG_LINK, "phy in index %d link is up\n", + phy_index); + } else { + DP(NETIF_MSG_LINK, "phy in index %d link is down\n", + phy_index); + continue; + } + + if (!ext_phy_link_up) { + ext_phy_link_up = 1; + active_external_phy = phy_index; + } else { + switch (bnx2x_phy_selection(params)) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + /** + * In this option, the first PHY makes sure to pass the + * traffic through itself only. + * Its not clear how to reset the link on the second phy + **/ + active_external_phy = EXT_PHY1; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + /** + * In this option, the first PHY makes sure to pass the + * traffic through the second PHY. + **/ + active_external_phy = EXT_PHY2; + break; + default: + /** + * Link indication on both PHYs with the following cases + * is invalid: + * - FIRST_PHY means that second phy wasn't initialized, + * hence its link is expected to be down + * - SECOND_PHY means that first phy should not be able + * to link up by itself (using configuration) + * - DEFAULT should be overriden during initialiazation + **/ + DP(NETIF_MSG_LINK, "Invalid link indication" + "mpc=0x%x. DISABLING LINK !!!\n", + params->multi_phy_config); + ext_phy_link_up = 0; + break; + } + } + } + prev_line_speed = vars->line_speed; + /** + * Step 2: + * Read the status of the internal phy. In case of + * DIRECT_SINGLE_MEDIA board, this link is the external link, + * otherwise this is the link between the 577xx and the first + * external phy + */ + if (params->phy[INT_PHY].read_status) + params->phy[INT_PHY].read_status( + ¶ms->phy[INT_PHY], + params, vars); + /** + * The INT_PHY flow control reside in the vars. This include the + * case where the speed or flow control are not set to AUTO. + * Otherwise, the active external phy flow control result is set + * to the vars. The ext_phy_line_speed is needed to check if the + * speed is different between the internal phy and external phy. + * This case may be result of intermediate link speed change. + */ + if (active_external_phy > INT_PHY) { + vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl; + /** + * Link speed is taken from the XGXS. AN and FC result from + * the external phy. + */ + vars->link_status |= phy_vars[active_external_phy].link_status; + + /** + * if active_external_phy is first PHY and link is up - disable + * disable TX on second external PHY + */ + if (active_external_phy == EXT_PHY1) { + if (params->phy[EXT_PHY2].phy_specific_func) { + DP(NETIF_MSG_LINK, "Disabling TX on" + " EXT_PHY2\n"); + params->phy[EXT_PHY2].phy_specific_func( + ¶ms->phy[EXT_PHY2], + params, DISABLE_TX); + } + } + + ext_phy_line_speed = phy_vars[active_external_phy].line_speed; + vars->duplex = phy_vars[active_external_phy].duplex; + if (params->phy[active_external_phy].supported & + SUPPORTED_FIBRE) + vars->link_status |= LINK_STATUS_SERDES_LINK; + DP(NETIF_MSG_LINK, "Active external phy selected: %x\n", + active_external_phy); + } + + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + if (params->phy[phy_index].flags & + FLAGS_REARM_LATCH_SIGNAL) { + bnx2x_rearm_latch_signal(bp, port, + phy_index == + active_external_phy); + break; + } + } + DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x," + " ext_phy_line_speed = %d\n", vars->flow_ctrl, + vars->link_status, ext_phy_line_speed); + /** + * Upon link speed change set the NIG into drain mode. Comes to + * deals with possible FIFO glitch due to clk change when speed + * is decreased without link down indicator + */ + + if (vars->phy_link_up) { + if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up && + (ext_phy_line_speed != vars->line_speed)) { + DP(NETIF_MSG_LINK, "Internal link speed %d is" + " different than the external" + " link speed %d\n", vars->line_speed, + ext_phy_line_speed); + vars->phy_link_up = 0; + } else if (prev_line_speed != vars->line_speed) { + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); + msleep(1); + } + } + + /* anything 10 and over uses the bmac */ + link_10g = ((vars->line_speed == SPEED_10000) || + (vars->line_speed == SPEED_12000) || + (vars->line_speed == SPEED_12500) || + (vars->line_speed == SPEED_13000) || + (vars->line_speed == SPEED_15000) || + (vars->line_speed == SPEED_16000)); + + bnx2x_link_int_ack(params, vars, link_10g); + + /** + * In case external phy link is up, and internal link is down + * (not initialized yet probably after link initialization, it + * needs to be initialized. + * Note that after link down-up as result of cable plug, the xgxs + * link would probably become up again without the need + * initialize it + */ + if (!(SINGLE_MEDIA_DIRECT(params))) { + DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d," + " init_preceding = %d\n", ext_phy_link_up, + vars->phy_link_up, + params->phy[EXT_PHY1].flags & + FLAGS_INIT_XGXS_FIRST); + if (!(params->phy[EXT_PHY1].flags & + FLAGS_INIT_XGXS_FIRST) + && ext_phy_link_up && !vars->phy_link_up) { + vars->line_speed = ext_phy_line_speed; + if (vars->line_speed < SPEED_1000) + vars->phy_flags |= PHY_SGMII_FLAG; + else + vars->phy_flags &= ~PHY_SGMII_FLAG; + bnx2x_init_internal_phy(¶ms->phy[INT_PHY], + params, + vars); + } + } + /** + * Link is up only if both local phy and external phy (in case of + * non-direct board) are up + */ + vars->link_up = (vars->phy_link_up && + (ext_phy_link_up || + SINGLE_MEDIA_DIRECT(params))); + + if (vars->link_up) + rc = bnx2x_update_link_up(params, vars, link_10g); + else + rc = bnx2x_update_link_down(params, vars); + + return rc; +} + + +/*****************************************************************************/ +/* External Phy section */ +/*****************************************************************************/ +void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port) +{ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); + msleep(1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); +} + +static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, + u32 spirom_ver, u32 ver_addr) +{ + DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", + (u16)(spirom_ver>>16), (u16)spirom_ver, port); + + if (ver_addr) + REG_WR(bp, ver_addr, spirom_ver); +} + +static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 port) +{ + u16 fw_ver1, fw_ver2; + + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER1, &fw_ver1); + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, &fw_ver2); + bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2), + phy->ver_addr); +} + +static void bnx2x_ext_phy_set_pause(struct link_params *params, + struct bnx2x_phy *phy, + struct link_vars *vars) +{ + u16 val; + struct bnx2x *bp = params->bp; + /* read modify write pause advertizing */ + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val); + + val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; + + /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { + val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; + } + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { + val |= MDIO_AN_REG_ADV_PAUSE_PAUSE; + } + DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val); +} + +static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 ld_pause; /* local */ + u16 lp_pause; /* link partner */ + u16 pause_result; + u8 ret = 0; + /* read twice */ + + vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; + + if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) + vars->flow_ctrl = phy->req_flow_ctrl; + else if (phy->req_line_speed != SPEED_AUTO_NEG) + vars->flow_ctrl = params->req_fc_auto_adv; + else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) { + ret = 1; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_ADV_PAUSE, &ld_pause); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_LP_AUTO_NEG, &lp_pause); + pause_result = (ld_pause & + MDIO_AN_REG_ADV_PAUSE_MASK) >> 8; + pause_result |= (lp_pause & + MDIO_AN_REG_ADV_PAUSE_MASK) >> 10; + DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", + pause_result); + bnx2x_pause_resolve(vars, pause_result); + } + return ret; +} + +static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp, + struct bnx2x_phy *phy, + struct link_vars *vars) +{ + u16 val; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_STATUS, &val); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_STATUS, &val); + if (val & (1<<5)) + vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + if ((val & (1<<0)) == 0) + vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED; +} + +/******************************************************************/ +/* common BCM8073/BCM8727 PHY SECTION */ +/******************************************************************/ +static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + if (phy->req_line_speed == SPEED_10 || + phy->req_line_speed == SPEED_100) { + vars->flow_ctrl = phy->req_flow_ctrl; + return; + } + + if (bnx2x_ext_phy_resolve_fc(phy, params, vars) && + (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) { + u16 pause_result; + u16 ld_pause; /* local */ + u16 lp_pause; /* link partner */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_CL37_FC_LD, &ld_pause); + + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_CL37_FC_LP, &lp_pause); + pause_result = (ld_pause & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5; + pause_result |= (lp_pause & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7; + + bnx2x_pause_resolve(vars, pause_result); + DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n", + pause_result); + } +} + +static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 port) +{ + /* Boot port from external ROM */ + /* EDC grst */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + 0x0001); + + /* ucode reboot and rst */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + 0x008c); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0001); + + /* Reset internal microprocessor */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + + /* Release srst bit */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); + + /* wait for 120ms for code download via SPI port */ + msleep(120); + + /* Clear ser_boot_ctl bit */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0000); + bnx2x_save_bcm_spirom_ver(bp, phy, port); +} + +static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + u16 val; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); + + if (val == 0) { + /* Mustn't set low power mode in 8073 A0 */ + return; + } + + /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ + bnx2x_cl45_read(bp, phy, + MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); + val &= ~(1<<13); + bnx2x_cl45_write(bp, phy, + MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); + + /* PLL controls */ + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490); + + /* Tx Controls */ + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640); + + /* Rx Controls */ + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015); + + /* Enable PLL sequencer (use read-modify-write to set bit 13) */ + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val); + val |= (1<<13); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); +} + +/******************************************************************/ +/* BCM8073 PHY SECTION */ +/******************************************************************/ +static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy) +{ + /* This is only required for 8073A1, version 102 only */ + u16 val; + + /* Read 8073 HW revision*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_CHIP_REV, &val); if (val != 1) { /* No need to workaround in 8073 A1 */ return 0; } - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, &val); @@ -2444,15 +3495,11 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params) return 1; } -static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) +static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); u16 val, cnt, cnt1 ; - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val); @@ -2466,9 +3513,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) poll Dev1, Reg $C820: */ for (cnt = 0; cnt < 1000; cnt++) { - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &val); @@ -2485,9 +3530,7 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) XAUI workaround has completed), then continue on with system initialization.*/ for (cnt1 = 0; cnt1 < 1000; cnt1++) { - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_XAUI_WA, &val); if (val & (1<<15)) { @@ -2505,143 +3548,391 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) return -EINVAL; } -static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, - u8 ext_phy_addr, - u32 ext_phy_type, - u32 shmem_base) +static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy) { - /* Boot port from external ROM */ - /* EDC grst */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - 0x0001); + /* Force KR or KX */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); +} - /* ucode reboot and rst */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - 0x008c); +static void bnx2x_8073_set_pause_cl37(struct link_params *params, + struct bnx2x_phy *phy, + struct link_vars *vars) +{ + u16 cl37_val; + struct bnx2x *bp = params->bp; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val); - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); + cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ + bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc); + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) { + cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; + } + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { + cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; + } + if ((vars->ieee_fc & + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == + MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { + cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; + } + DP(NETIF_MSG_LINK, + "Ext phy AN advertize cl37 0x%x\n", cl37_val); - /* Reset internal microprocessor */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val); + msleep(500); +} - /* Release srst bit */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); +static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val = 0, tmp1; + u8 gpio_port; + DP(NETIF_MSG_LINK, "Init 8073\n"); - /* wait for 100ms for code download via SPI port */ - msleep(100); + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); - /* Clear ser_boot_ctl bit */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0000); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port); - bnx2x_save_bcm_spirom_ver(bp, port, - ext_phy_type, - ext_phy_addr, - shmem_base); -} + /* enable LASI */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2)); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004); -static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, - u8 ext_phy_addr, - u32 shmem_base) -{ - bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - shmem_base); -} + bnx2x_8073_set_pause_cl37(params, phy, vars); -static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, - u8 ext_phy_addr, - u32 shmem_base) -{ - bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - shmem_base); + bnx2x_8073_set_xaui_low_power_mode(bp, phy); -} + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); -static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); - /* Need to wait 100ms after reset */ - msleep(100); + DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); - /* Micro controller re-boot */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - 0x018B); + /* Enable CL37 BAM */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, &val); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, val | 1); - /* Set soft reset */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); + if (params->loopback_mode == LOOPBACK_EXT) { + bnx2x_807x_force_10G(bp, phy); + DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); + return 0; + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002); + } + if (phy->req_line_speed != SPEED_AUTO_NEG) { + if (phy->req_line_speed == SPEED_10000) { + val = (1<<7); + } else if (phy->req_line_speed == SPEED_2500) { + val = (1<<5); + /* Note that 2.5G works only + when used with 1G advertisment */ + } else + val = (1<<5); + } else { + val = 0; + if (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) + val |= (1<<7); + + /* Note that 2.5G works only when + used with 1G advertisment */ + if (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | + PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) + val |= (1<<5); + DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val); + } - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0001); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1); + + if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && + (phy->req_line_speed == SPEED_AUTO_NEG)) || + (phy->req_line_speed == SPEED_2500)) { + u16 phy_ver; + /* Allow 2.5G for A1 and above */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, + &phy_ver); + DP(NETIF_MSG_LINK, "Add 2.5G\n"); + if (phy_ver > 0) + tmp1 |= 1; + else + tmp1 &= 0xfffe; + } else { + DP(NETIF_MSG_LINK, "Disable 2.5G\n"); + tmp1 &= 0xfffe; + } - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, - MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1); + /* Add support for CL37 (passive mode) II */ - /* wait for 150ms for microcode load */ - msleep(150); + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, + (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ? + 0x20 : 0x40))); - /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL1, 0x0000); + /* Add support for CL37 (passive mode) III */ + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); - msleep(200); - bnx2x_save_bcm_spirom_ver(bp, port, - ext_phy_type, - ext_phy_addr, - params->shmem_base); + /* The SNR will improve about 2db by changing + BW and FEE main tap. Rest commands are executed + after link is up*/ + if (bnx2x_8073_is_snr_needed(bp, phy)) + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, + 0xFB0C); + + /* Enable FEC (Forware Error Correction) Request in the AN */ + bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1); + tmp1 |= (1<<15); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1); + + bnx2x_ext_phy_set_pause(params, phy, vars); + + /* Restart autoneg */ + msleep(500); + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n", + ((val & (1<<5)) > 0), ((val & (1<<7)) > 0)); + return 0; +} + +static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 link_up = 0; + u16 val1, val2; + u16 link_status = 0; + u16 an1000_status = 0; + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + + DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1); + + /* clear the interrupt LASI status register */ + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1); + /* Clear MSG-OUT */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); + + /* Check the LASI */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + + DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); + + /* Check the link status */ + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2); + DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + link_up = ((val1 & 4) == 4); + DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); + + if (link_up && + ((phy->req_line_speed != SPEED_10000))) { + if (bnx2x_8073_xaui_wa(bp, phy) != 0) + return 0; + } + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status); + + /* Check the link status on 1.1.2 */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," + "an_link_status=0x%x\n", val2, val1, an1000_status); + + link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1))); + if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) { + /* The SNR will improve about 2dbby + changing the BW and FEE main tap.*/ + /* The 1st write to change FFE main + tap is set before restart AN */ + /* Change PLL Bandwidth in EDC + register */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH, + 0x26BC); + + /* Change CDR Bandwidth in EDC register */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH, + 0x0333); + } + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS, + &link_status); + + /* Bits 0..2 --> speed detected, bits 13..15--> link is down */ + if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { + link_up = 1; + vars->line_speed = SPEED_10000; + DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n", + params->port); + } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) { + link_up = 1; + vars->line_speed = SPEED_2500; + DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n", + params->port); + } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { + link_up = 1; + vars->line_speed = SPEED_1000; + DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", + params->port); + } else { + link_up = 0; + DP(NETIF_MSG_LINK, "port %x: External link is down\n", + params->port); + } + + if (link_up) { + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); + bnx2x_8073_resolve_fc(phy, params, vars); + } + return link_up; +} + +static void bnx2x_8073_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 gpio_port; + if (CHIP_IS_E2(bp)) + gpio_port = BP_PATH(bp); + else + gpio_port = params->port; + DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n", + gpio_port); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + gpio_port); +} + +/******************************************************************/ +/* BCM8705 PHY SECTION */ +/******************************************************************/ +static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "init 8705\n"); + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); + bnx2x_wait_reset_complete(bp, phy); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100); + bnx2x_cl45_write(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1); + /* BCM8705 doesn't have microcode, hence the 0 */ + bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0); + return 0; +} + +static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u8 link_up = 0; + u16 val1, rx_sd; + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "read status 8705\n"); + bnx2x_cl45_read(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + + bnx2x_cl45_read(bp, phy, + MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, 0xc809, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, 0xc809, &val1); + + DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1); + link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0)); + if (link_up) { + vars->line_speed = SPEED_10000; + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } + return link_up; } -static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port, - u32 ext_phy_type, u8 ext_phy_addr, - u8 tx_en) +/******************************************************************/ +/* SFP+ module Section */ +/******************************************************************/ +static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 port, + u8 tx_en) { u16 val; DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n", tx_en, port); /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val); @@ -2651,58 +3942,42 @@ static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port, else val |= (1<<15); - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, val); } -static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params, +static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; u16 val = 0; u16 i; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - if (byte_cnt > 16) { DP(NETIF_MSG_LINK, "Reading from eeprom is" " is limited to 0xf\n"); return -EINVAL; } /* Set the read command byte count */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, (byte_cnt | 0xa000)); /* Set the read command address */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, addr); /* Activate read command */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 0x2c0f); /* Wait up to 500us for command complete status */ for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == @@ -2721,18 +3996,14 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params, /* Read the buffer */ for (i = 0; i < byte_cnt; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val); o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK); } for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == @@ -2743,14 +4014,12 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params, return -EINVAL; } -static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, +static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) { struct bnx2x *bp = params->bp; u16 val, i; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); if (byte_cnt > 16) { DP(NETIF_MSG_LINK, "Reading from eeprom is" @@ -2759,40 +4028,30 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, } /* Need to read from 1.8000 to clear it */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); /* Set the read command byte count */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT, ((byte_cnt < 2) ? 2 : byte_cnt)); /* Set the read command address */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR, addr); /* Set the destination address */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0x8004, MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF); /* Activate read command */ - bnx2x_cl45_write(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 0x8002); @@ -2802,9 +4061,7 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, /* Wait up to 500us for command complete status */ for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == @@ -2823,18 +4080,14 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, /* Read the buffer */ for (i = 0; i < byte_cnt; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val); o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK); } for (i = 0; i < 100; i++) { - bnx2x_cl45_read(bp, port, - ext_phy_type, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val); if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == @@ -2846,21 +4099,21 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, return -EINVAL; } -u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, +u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf) { - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) - return bnx2x_8726_read_sfp_module_eeprom(params, addr, + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) + return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr, byte_cnt, o_buf); - else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - return bnx2x_8727_read_sfp_module_eeprom(params, addr, + else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) + return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr, byte_cnt, o_buf); return -EINVAL; } -static u8 bnx2x_get_edc_mode(struct link_params *params, +static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy, + struct link_params *params, u16 *edc_mode) { struct bnx2x *bp = params->bp; @@ -2868,10 +4121,11 @@ static u8 bnx2x_get_edc_mode(struct link_params *params, *edc_mode = EDC_MODE_LIMITING; /* First check for copper cable */ - if (bnx2x_read_sfp_module_eeprom(params, - SFP_EEPROM_CON_TYPE_ADDR, - 1, - &val) != 0) { + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_CON_TYPE_ADDR, + 1, + &val) != 0) { DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); return -EINVAL; } @@ -2883,7 +4137,8 @@ static u8 bnx2x_get_edc_mode(struct link_params *params, /* Check if its active cable( includes SFP+ module) of passive cable*/ - if (bnx2x_read_sfp_module_eeprom(params, + if (bnx2x_read_sfp_module_eeprom(phy, + params, SFP_EEPROM_FC_TX_TECH_ADDR, 1, &copper_module_type) != @@ -2923,10 +4178,11 @@ static u8 bnx2x_get_edc_mode(struct link_params *params, if (check_limiting_mode) { u8 options[SFP_EEPROM_OPTIONS_SIZE]; - if (bnx2x_read_sfp_module_eeprom(params, - SFP_EEPROM_OPTIONS_ADDR, - SFP_EEPROM_OPTIONS_SIZE, - options) != 0) { + if (bnx2x_read_sfp_module_eeprom(phy, + params, + SFP_EEPROM_OPTIONS_ADDR, + SFP_EEPROM_OPTIONS_SIZE, + options) != 0) { DP(NETIF_MSG_LINK, "Failed to read Option" " field from module EEPROM\n"); return -EINVAL; @@ -2939,17 +4195,17 @@ static u8 bnx2x_get_edc_mode(struct link_params *params, DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode); return 0; } - /* This function read the relevant field from the module ( SFP+ ), and verify it is compliant with this board */ -static u8 bnx2x_verify_sfp_module(struct link_params *params) +static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; - u32 val; - u32 fw_resp; + u32 val, cmd; + u32 fw_resp, fw_cmd_param; char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1]; char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1]; - + phy->flags &= ~FLAGS_SFP_NOT_APPROVED; val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port].config)); @@ -2959,52 +4215,123 @@ static u8 bnx2x_verify_sfp_module(struct link_params *params) return 0; } - /* Ask the FW to validate the module */ - if (!(params->feature_config_flags & - FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) { + if (params->feature_config_flags & + FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) { + /* Use specific phy request */ + cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL; + } else if (params->feature_config_flags & + FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) { + /* Use first phy request only in case of non-dual media*/ + if (DUAL_MEDIA(params)) { + DP(NETIF_MSG_LINK, "FW does not support OPT MDL " + "verification\n"); + return -EINVAL; + } + cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL; + } else { + /* No support in OPT MDL detection */ DP(NETIF_MSG_LINK, "FW does not support OPT MDL " - "verification\n"); + "verification\n"); return -EINVAL; } - fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL); + fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl); + fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param); if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { DP(NETIF_MSG_LINK, "Approved module\n"); return 0; } /* format the warning message */ - if (bnx2x_read_sfp_module_eeprom(params, + if (bnx2x_read_sfp_module_eeprom(phy, + params, SFP_EEPROM_VENDOR_NAME_ADDR, SFP_EEPROM_VENDOR_NAME_SIZE, (u8 *)vendor_name)) vendor_name[0] = '\0'; else vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; - if (bnx2x_read_sfp_module_eeprom(params, + if (bnx2x_read_sfp_module_eeprom(phy, + params, SFP_EEPROM_PART_NO_ADDR, SFP_EEPROM_PART_NO_SIZE, (u8 *)vendor_pn)) vendor_pn[0] = '\0'; else - vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; + vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; + + netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected," + " Port %d from %s part number %s\n", + params->port, vendor_name, vendor_pn); + phy->flags |= FLAGS_SFP_NOT_APPROVED; + return -EINVAL; +} + +static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy, + struct link_params *params) + +{ + u8 val; + struct bnx2x *bp = params->bp; + u16 timeout; + /* Initialization time after hot-plug may take up to 300ms for some + phys type ( e.g. JDSU ) */ + for (timeout = 0; timeout < 60; timeout++) { + if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val) + == 0) { + DP(NETIF_MSG_LINK, "SFP+ module initialization " + "took %d ms\n", timeout * 5); + return 0; + } + msleep(5); + } + return -EINVAL; +} + +static void bnx2x_8727_power_module(struct bnx2x *bp, + struct bnx2x_phy *phy, + u8 is_power_up) { + /* Make sure GPIOs are not using for LED mode */ + u16 val; + /* + * In the GPIO register, bit 4 is use to detemine if the GPIOs are + * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for + * output + * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 + * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 + * where the 1st bit is the over-current(only input), and 2nd bit is + * for power( only output ) + */ + + /* + * In case of NOC feature is disabled and power is up, set GPIO control + * as input to enable listening of over-current indication + */ + if (phy->flags & FLAGS_NOC) + return; + if (!(phy->flags & + FLAGS_NOC) && is_power_up) + val = (1<<4); + else + /* + * Set GPIO control to OUTPUT, and set the power bit + * to according to the is_power_up + */ + val = ((!(is_power_up)) << 1); - netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected, Port %d from %s part number %s\n", - params->port, vendor_name, vendor_pn); - return -EINVAL; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_GPIO_CTRL, + val); } -static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, - u16 edc_mode) +static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp, + struct bnx2x_phy *phy, + u16 edc_mode) { - struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); u16 cur_limiting_mode; - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, &cur_limiting_mode); @@ -3014,12 +4341,10 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, if (edc_mode == EDC_MODE_LIMITING) { DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n"); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER2, - EDC_MODE_LIMITING); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_ROM_VER2, + EDC_MODE_LIMITING); } else { /* LRM mode ( default )*/ DP(NETIF_MSG_LINK, "Setting LRM MODE\n"); @@ -3030,27 +4355,19 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, if (cur_limiting_mode != EDC_MODE_LIMITING) return 0; - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LRM_MODE, 0); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, 0x128); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL0, 0x4008); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LRM_MODE, 0xaaaa); @@ -3058,46 +4375,33 @@ static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, return 0; } -static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params, +static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp, + struct bnx2x_phy *phy, u16 edc_mode) { - struct bnx2x *bp = params->bp; - u8 port = params->port; u16 phy_identifier; u16 rom_ver2_val; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &phy_identifier); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, (phy_identifier & ~(1<<9))); - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, &rom_ver2_val); /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER2, (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff)); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, (phy_identifier | (1<<9))); @@ -3105,72 +4409,34 @@ static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params, return 0; } - -static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params) +static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, + struct link_params *params, + u32 action) { - u8 val; struct bnx2x *bp = params->bp; - u16 timeout; - /* Initialization time after hot-plug may take up to 300ms for some - phys type ( e.g. JDSU ) */ - for (timeout = 0; timeout < 60; timeout++) { - if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val) - == 0) { - DP(NETIF_MSG_LINK, "SFP+ module initialization " - "took %d ms\n", timeout * 5); - return 0; - } - msleep(5); - } - return -EINVAL; -} - -static void bnx2x_8727_power_module(struct bnx2x *bp, - struct link_params *params, - u8 ext_phy_addr, u8 is_power_up) { - /* Make sure GPIOs are not using for LED mode */ - u16 val; - u8 port = params->port; - /* - * In the GPIO register, bit 4 is use to detemine if the GPIOs are - * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for - * output - * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 - * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 - * where the 1st bit is the over-current(only input), and 2nd bit is - * for power( only output ) - */ - - /* - * In case of NOC feature is disabled and power is up, set GPIO control - * as input to enable listening of over-current indication - */ - - if (!(params->feature_config_flags & - FEATURE_CONFIG_BCM8727_NOC) && is_power_up) - val = (1<<4); - else - /* - * Set GPIO control to OUTPUT, and set the power bit - * to according to the is_power_up - */ - val = ((!(is_power_up)) << 1); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_GPIO_CTRL, - val); + switch (action) { + case DISABLE_TX: + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + break; + case ENABLE_TX: + if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) + bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); + break; + default: + DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n", + action); + return; + } } -static u8 bnx2x_sfp_module_detection(struct link_params *params) +static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 edc_mode; u8 rc = 0; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); + u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port].config)); @@ -3178,10 +4444,10 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", params->port); - if (bnx2x_get_edc_mode(params, &edc_mode) != 0) { + if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) { DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); return -EINVAL; - } else if (bnx2x_verify_sfp_module(params) != + } else if (bnx2x_verify_sfp_module(phy, params) != 0) { /* check SFP+ module compatibility */ DP(NETIF_MSG_LINK, "Module verification failed!!\n"); @@ -3190,13 +4456,12 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, MISC_REGISTERS_GPIO_HIGH, params->port); - if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && + if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { /* Shutdown SFP+ module */ DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); - bnx2x_8727_power_module(bp, params, - ext_phy_addr, 0); + bnx2x_8727_power_module(bp, phy, 0); return rc; } } else { @@ -3208,15 +4473,15 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) } /* power up the SFP module */ - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) - bnx2x_8727_power_module(bp, params, ext_phy_addr, 1); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) + bnx2x_8727_power_module(bp, phy, 1); /* Check and set limiting mode / LRM mode on 8726. On 8727 it is done automatically */ - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) - bnx2x_bcm8726_set_limiting_mode(params, edc_mode); + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) + bnx2x_8726_set_limiting_mode(bp, phy, edc_mode); else - bnx2x_bcm8727_set_limiting_mode(params, edc_mode); + bnx2x_8727_set_limiting_mode(bp, phy, edc_mode); /* * Enable transmit for this module if the module is approved, or * if unapproved modules should also enable the Tx laser @@ -3224,11 +4489,9 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) if (rc == 0 || (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, params->port, - ext_phy_type, ext_phy_addr, 1); + bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); else - bnx2x_sfp_set_transmitter(bp, params->port, - ext_phy_type, ext_phy_addr, 0); + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); return rc; } @@ -3236,6 +4499,7 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params) void bnx2x_handle_module_detect_int(struct link_params *params) { struct bnx2x *bp = params->bp; + struct bnx2x_phy *phy = ¶ms->phy[EXT_PHY1]; u32 gpio_val; u8 port = params->port; @@ -3245,1349 +4509,587 @@ void bnx2x_handle_module_detect_int(struct link_params *params) params->port); /* Get current gpio val refelecting module plugged in / out*/ - gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); + gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); /* Call the handling function in case module is detected */ if (gpio_val == 0) { bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, - port); + MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, + port); - if (bnx2x_wait_for_sfp_module_initialized(params) == - 0) - bnx2x_sfp_module_detection(params); + if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) + bnx2x_sfp_module_detection(phy, params); else DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); } else { - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - - u32 ext_phy_type = - XGXS_EXT_PHY_TYPE(params->ext_phy_config); u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port]. - config)); - - bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INT_OUTPUT_SET, - port); - /* Module was plugged out. */ - /* Disable transmit for this module */ - if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, params->port, - ext_phy_type, ext_phy_addr, 0); - } -} - -static void bnx2x_bcm807x_force_10G(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - /* Force KR or KX */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 0x2040); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, - 0x000b); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_BCM_CTRL, - 0x0000); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, - 0x0000); -} - -static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params) -{ - struct bnx2x *bp = params->bp; - u8 port = params->port; - u16 val; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &val); - - if (val == 0) { - /* Mustn't set low power mode in 8073 A0 */ - return; - } - - /* Disable PLL sequencer (use read-modify-write to clear bit 13) */ - bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, - MDIO_XS_PLL_SEQUENCER, &val); - val &= ~(1<<13); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); - - /* PLL controls */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x805E, 0x1077); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x805D, 0x0000); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x805C, 0x030B); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x805B, 0x1240); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x805A, 0x2490); - - /* Tx Controls */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x80A7, 0x0C74); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x80A6, 0x9041); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x80A5, 0x4640); - - /* Rx Controls */ - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x80FE, 0x01C4); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x80FD, 0x9249); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, 0x80FC, 0x2015); - - /* Enable PLL sequencer (use read-modify-write to set bit 13) */ - bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, - MDIO_XS_PLL_SEQUENCER, &val); - val |= (1<<13); - bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, - MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val); -} - -static void bnx2x_8073_set_pause_cl37(struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u16 cl37_val; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, &cl37_val); - - cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; - /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ - - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) { - cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; - } - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { - cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; - } - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { - cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; - } - DP(NETIF_MSG_LINK, - "Ext phy AN advertize cl37 0x%x\n", cl37_val); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, cl37_val); - msleep(500); -} - -static void bnx2x_ext_phy_set_pause(struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u16 val; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - /* read modify write pause advertizing */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, &val); - - val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; - - /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ - - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { - val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC; - } - if ((vars->ieee_fc & - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == - MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { - val |= - MDIO_AN_REG_ADV_PAUSE_PAUSE; - } - DP(NETIF_MSG_LINK, - "Ext phy AN advertize 0x%x\n", val); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV_PAUSE, val); -} -static void bnx2x_set_preemphasis(struct link_params *params) -{ - u16 bank, i = 0; - struct bnx2x *bp = params->bp; - - for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; - bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, - bank, - MDIO_RX0_RX_EQ_BOOST, - params->xgxs_config_rx[i]); - } - - for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; - bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) { - CL45_WR_OVER_CL22(bp, params->port, - params->phy_addr, - bank, - MDIO_TX0_TX_DRIVER, - params->xgxs_config_tx[i]); - } -} - - -static void bnx2x_8481_set_led4(struct link_params *params, - u32 ext_phy_type, u8 ext_phy_addr) -{ - struct bnx2x *bp = params->bp; - - /* PHYC_CTL_LED_CTL */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482); - - /* Unmask LED4 for 10G link */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6)); - /* 'Interrupt Mask' */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - 0xFFFB, 0xFFFD); -} -static void bnx2x_8481_set_legacy_led_mode(struct link_params *params, - u32 ext_phy_type, u8 ext_phy_addr) -{ - struct bnx2x *bp = params->bp; - - /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */ - /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_SHADOW, - (1<<15) | (0xd << 10) | (0xc<<4) | 0xe); -} - -static void bnx2x_8481_set_10G_led_mode(struct link_params *params, - u32 ext_phy_type, u8 ext_phy_addr) -{ - struct bnx2x *bp = params->bp; - u16 val1; - - /* LED1 (10G Link) */ - /* Enable continuse based on source 7(10G-link) */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, - &val1); - /* Set bit 2 to 0, and bits [1:0] to 10 */ - val1 &= ~((1<<0) | (1<<2) | (1<<7)); /* Clear bits 0,2,7*/ - val1 |= ((1<<1) | (1<<6)); /* Set bit 1, 6 */ - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LINK_SIGNAL, - val1); - - /* Unmask LED1 for 10G link */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - &val1); - /* Set bit 2 to 0, and bits [1:0] to 10 */ - val1 |= (1<<7); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED1_MASK, - val1); - - /* LED2 (1G/100/10G Link) */ - /* Mask LED2 for 10G link */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED2_MASK, - 0); - - /* Unmask LED3 for 10G link */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_MASK, - 0x6); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_LED3_BLINK, - 0); -} - - -static void bnx2x_init_internal_phy(struct link_params *params, - struct link_vars *vars, - u8 enable_cl73) -{ - struct bnx2x *bp = params->bp; - - if (!(vars->phy_flags & PHY_SGMII_FLAG)) { - if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - (params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) - bnx2x_set_preemphasis(params); - - /* forced speed requested? */ - if (vars->line_speed != SPEED_AUTO_NEG || - ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - params->loopback_mode == LOOPBACK_EXT)) { - DP(NETIF_MSG_LINK, "not SGMII, no AN\n"); - - /* disable autoneg */ - bnx2x_set_autoneg(params, vars, 0); - - /* program speed and duplex */ - bnx2x_program_serdes(params, vars); - - } else { /* AN_mode */ - DP(NETIF_MSG_LINK, "not SGMII, AN\n"); - - /* AN enabled */ - bnx2x_set_brcm_cl37_advertisment(params); - - /* program duplex & pause advertisement (for aneg) */ - bnx2x_set_ieee_aneg_advertisment(params, - vars->ieee_fc); - - /* enable autoneg */ - bnx2x_set_autoneg(params, vars, enable_cl73); - - /* enable and restart AN */ - bnx2x_restart_autoneg(params, enable_cl73); - } - - } else { /* SGMII mode */ - DP(NETIF_MSG_LINK, "SGMII\n"); + config)); - bnx2x_initialize_sgmii_process(params, vars); + bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_INT_OUTPUT_SET, + port); + /* Module was plugged out. */ + /* Disable transmit for this module */ + if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == + PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); } } -static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) +/******************************************************************/ +/* common BCM8706/BCM8726 PHY SECTION */ +/******************************************************************/ +static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { + u8 link_up = 0; + u16 val1, val2, rx_sd, pcs_status; struct bnx2x *bp = params->bp; - u32 ext_phy_type; - u8 ext_phy_addr; - u16 cnt; - u16 ctrl = 0; - u16 val = 0; - u8 rc = 0; + DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); + /* Clear RX Alarm*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2); + /* clear LASI indication*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); + DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd); + bnx2x_cl45_read(bp, phy, + MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2); + + DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps" + " link_status 0x%x\n", rx_sd, pcs_status, val2); + /* link is up if both bit 0 of pmd_rx_sd and + * bit 0 of pcs_status are set, or if the autoneg bit + * 1 is set + */ + link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1))); + if (link_up) { + if (val2 & (1<<1)) + vars->line_speed = SPEED_1000; + else + vars->line_speed = SPEED_10000; + bnx2x_ext_phy_resolve_fc(phy, params, vars); + } + return link_up; +} - if (vars->phy_flags & PHY_XGXS_FLAG) { - ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); +/******************************************************************/ +/* BCM8706 PHY SECTION */ +/******************************************************************/ +static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u16 cnt, val; + struct bnx2x *bp = params->bp; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040); + bnx2x_wait_reset_complete(bp, phy); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - /* Make sure that the soft reset is off (expect for the 8072: - * due to the lock, it will be done inside the specific - * handling) - */ - if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) { - /* Wait for soft reset to get cleared upto 1 sec */ - for (cnt = 0; cnt < 1000; cnt++) { - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, &ctrl); - if (!(ctrl & (1<<15))) - break; - msleep(1); - } - DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", - ctrl, cnt); + /* Wait until fw is loaded */ + for (cnt = 0; cnt < 100; cnt++) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val); + if (val) + break; + msleep(10); + } + DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt); + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + u8 i; + u16 reg; + for (i = 0; i < 4; i++) { + reg = MDIO_XS_8706_REG_BANK_RX0 + + i*(MDIO_XS_8706_REG_BANK_RX1 - + MDIO_XS_8706_REG_BANK_RX0); + bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val); + /* Clear first 3 bits of the control */ + val &= ~0x7; + /* Set control bits according to configuration */ + val |= (phy->rx_preemphasis[i] & 0x7); + DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706" + " reg 0x%x <-- val 0x%x\n", reg, val); + bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val); } + } + /* Force speed */ + if (phy->req_line_speed == SPEED_10000) { + DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_DIGITAL_CTRL, 0x400); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); + } else { + /* Force 1Gbps using autoneg with 1G advertisment */ + + /* Allow CL37 through CL73 */ + DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); + + /* Enable Full-Duplex advertisment on CL37 */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020); + /* Enable CL37 AN */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); + /* 1G support */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5)); + + /* Enable clause 73 AN */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x0400); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, + 0x0004); + } + bnx2x_save_bcm_spirom_ver(bp, phy, params->port); + return 0; +} - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - break; +static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + return bnx2x_8706_8726_read_status(phy, params, vars); +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - DP(NETIF_MSG_LINK, "XGXS 8705\n"); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_MISC_CTRL, - 0x8288); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - 0x7fbf); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CMU_PLL_BYPASS, - 0x0100); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_WIS_DEVAD, - MDIO_WIS_REG_LASI_CNTL, 0x1); - - /* BCM8705 doesn't have microcode, hence the 0 */ - bnx2x_save_spirom_version(bp, params->port, - params->shmem_base, 0); - break; +/******************************************************************/ +/* BCM8726 PHY SECTION */ +/******************************************************************/ +static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001); +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - /* Wait until fw is loaded */ - for (cnt = 0; cnt < 100; cnt++) { - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_ROM_VER1, &val); - if (val) - break; - msleep(10); - } - DP(NETIF_MSG_LINK, "XGXS 8706 is initialized " - "after %d ms\n", cnt); - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - u8 i; - u16 reg; - for (i = 0; i < 4; i++) { - reg = MDIO_XS_8706_REG_BANK_RX0 + - i*(MDIO_XS_8706_REG_BANK_RX1 - - MDIO_XS_8706_REG_BANK_RX0); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_XS_DEVAD, - reg, &val); - /* Clear first 3 bits of the control */ - val &= ~0x7; - /* Set control bits according to - configuation */ - val |= (params->xgxs_config_rx[i] & - 0x7); - DP(NETIF_MSG_LINK, "Setting RX" - "Equalizer to BCM8706 reg 0x%x" - " <-- val 0x%x\n", reg, val); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_XS_DEVAD, - reg, val); - } - } - /* Force speed */ - if (params->req_line_speed == SPEED_10000) { - DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n"); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_DIGITAL_CTRL, - 0x400); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 1); - } else { - /* Force 1Gbps using autoneg with 1G - advertisment */ - - /* Allow CL37 through CL73 */ - DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_CL73, - 0x040c); - - /* Enable Full-Duplex advertisment on CL37 */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LP, - 0x0020); - /* Enable CL37 AN */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, - 0x1000); - /* 1G support */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV, (1<<5)); - - /* Enable clause 73 AN */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, - 0x1200); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - 0x0400); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x0004); +static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + /* Need to wait 100ms after reset */ + msleep(100); - } - bnx2x_save_bcm_spirom_ver(bp, params->port, - ext_phy_type, - ext_phy_addr, - params->shmem_base); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); - bnx2x_bcm8726_external_rom_boot(params); - - /* Need to call module detected on initialization since - the module detection triggered by actual module - insertion might occur before driver is loaded, and when - driver is loaded, it reset all registers, including the - transmitter */ - bnx2x_sfp_module_detection(params); - - /* Set Flow control */ - bnx2x_ext_phy_set_pause(params, vars); - if (params->req_line_speed == SPEED_1000) { - DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, 0xD); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x5); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - 0x400); - } else if ((params->req_line_speed == - SPEED_AUTO_NEG) && - ((params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) { - DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_ADV, 0x20); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_CL73, 0x040c); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, 0x0020); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, 0x1000); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x1200); - - /* Enable RX-ALARM control to receive - interrupt for 1G speed change */ - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x4); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - 0x400); - - } else { /* Default 10G. Set only LASI control */ - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 1); - } + /* Micro controller re-boot */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B); - /* Set TX PreEmphasis if needed */ - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," - "TX_CTRL2 0x%x\n", - params->xgxs_config_tx[0], - params->xgxs_config_tx[1]); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8726_TX_CTRL1, - params->xgxs_config_tx[0]); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8726_TX_CTRL2, - params->xgxs_config_tx[1]); - } - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - { - u16 tmp1; - u16 rx_alarm_ctrl_val; - u16 lasi_ctrl_val; - if (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { - rx_alarm_ctrl_val = 0x400; - lasi_ctrl_val = 0x0004; - } else { - rx_alarm_ctrl_val = (1<<2); - lasi_ctrl_val = 0x0004; - } + /* Set soft reset */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); - /* enable LASI */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - rx_alarm_ctrl_val); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, - lasi_ctrl_val); - - bnx2x_8073_set_pause_cl37(params, vars); - - if (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) - bnx2x_bcm8072_external_rom_boot(params); - else - /* In case of 8073 with long xaui lines, - don't set the 8073 xaui low power*/ - bnx2x_bcm8073_set_xaui_low_power_mode(params); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_M8051_MSGOUT_REG, - &tmp1); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &tmp1); - - DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):" - "0x%x\n", tmp1); - - /* If this is forced speed, set to KR or KX - * (all other are not supported) - */ - if (params->loopback_mode == LOOPBACK_EXT) { - bnx2x_bcm807x_force_10G(params); - DP(NETIF_MSG_LINK, - "Forced speed 10G on 807X\n"); - break; - } else { - bnx2x_cl45_write(bp, params->port, - ext_phy_type, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_BCM_CTRL, - 0x0002); - } - if (params->req_line_speed != SPEED_AUTO_NEG) { - if (params->req_line_speed == SPEED_10000) { - val = (1<<7); - } else if (params->req_line_speed == - SPEED_2500) { - val = (1<<5); - /* Note that 2.5G works only - when used with 1G advertisment */ - } else - val = (1<<5); - } else { - - val = 0; - if (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) - val |= (1<<7); - - /* Note that 2.5G works only when - used with 1G advertisment */ - if (params->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G | - PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - val |= (1<<5); - DP(NETIF_MSG_LINK, - "807x autoneg val = 0x%x\n", val); - } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0001); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV, val); - if (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_2_5G, &tmp1); - - if (((params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) && - (params->req_line_speed == - SPEED_AUTO_NEG)) || - (params->req_line_speed == - SPEED_2500)) { - u16 phy_ver; - /* Allow 2.5G for A1 and above */ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_CHIP_REV, &phy_ver); - DP(NETIF_MSG_LINK, "Add 2.5G\n"); - if (phy_ver > 0) - tmp1 |= 1; - else - tmp1 &= 0xfffe; - } else { - DP(NETIF_MSG_LINK, "Disable 2.5G\n"); - tmp1 &= 0xfffe; - } - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_2_5G, tmp1); - } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, + MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); + + /* wait for 150ms for microcode load */ + msleep(150); - /* Add support for CL37 (passive mode) II */ - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, - &tmp1); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_FC_LD, (tmp1 | - ((params->req_duplex == DUPLEX_FULL) ? - 0x20 : 0x40))); - - /* Add support for CL37 (passive mode) III */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, 0x1000); - - if (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - /* The SNR will improve about 2db by changing - BW and FEE main tap. Rest commands are executed - after link is up*/ - /*Change FFE main cursor to 5 in EDC register*/ - if (bnx2x_8073_is_snr_needed(params)) - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_EDC_FFE_MAIN, - 0xFB0C); - - /* Enable FEC (Forware Error Correction) - Request in the AN */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV2, &tmp1); - - tmp1 |= (1<<15); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_ADV2, tmp1); + /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_MISC_CTRL1, 0x0000); - } + msleep(200); + bnx2x_save_bcm_spirom_ver(bp, phy, params->port); +} - bnx2x_ext_phy_set_pause(params, vars); - - /* Restart autoneg */ - msleep(500); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x1200); - DP(NETIF_MSG_LINK, "807x Autoneg Restart: " - "Advertise 1G=%x, 10G=%x\n", - ((val & (1<<5)) > 0), - ((val & (1<<7)) > 0)); - break; +static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val1; + u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars); + if (link_up) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, + &val1); + if (val1 & (1<<15)) { + DP(NETIF_MSG_LINK, "Tx is disabled\n"); + link_up = 0; + vars->line_speed = 0; } + } + return link_up; +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - { - u16 tmp1; - u16 rx_alarm_ctrl_val; - u16 lasi_ctrl_val; - - /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ - - u16 mod_abs; - rx_alarm_ctrl_val = (1<<2) | (1<<5) ; - lasi_ctrl_val = 0x0004; - - DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); - /* enable LASI */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - rx_alarm_ctrl_val); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, - lasi_ctrl_val); - - /* Initially configure MOD_ABS to interrupt when - module is presence( bit 8) */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); - /* Set EDC off by setting OPTXLOS signal input to low - (bit 9). - When the EDC is off it locks onto a reference clock and - avoids becoming 'lost'.*/ - mod_abs &= ~((1<<8) | (1<<9)); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); - - /* Make MOD_ABS give interrupt on change */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_OPT_CTRL, - &val); - val |= (1<<12); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_OPT_CTRL, - val); - - /* Set 8727 GPIOs to input to allow reading from the - 8727 GPIO0 status which reflect SFP+ module - over-current */ - - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_OPT_CTRL, - &val); - val &= 0xff8f; /* Reset bits 4-6 */ - bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_PCS_OPT_CTRL, - val); - - bnx2x_8727_power_module(bp, params, ext_phy_addr, 1); - bnx2x_bcm8073_set_xaui_low_power_mode(params); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_M8051_MSGOUT_REG, - &tmp1); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &tmp1); - - /* Set option 1G speed */ - if (params->req_line_speed == SPEED_1000) { - - DP(NETIF_MSG_LINK, "Setting 1G force\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x40); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, 0xD); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, &tmp1); - DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); - - } else if ((params->req_line_speed == - SPEED_AUTO_NEG) && - ((params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) { - - DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_PMA_REG_8727_MISC_CTRL, 0); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_CL37_AN, 0x1300); - } else { - /* Since the 8727 has only single reset pin, - need to set the 10G registers although it is - default */ - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x0020); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_AN_DEVAD, - 0x7, 0x0100); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x2040); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_10G_CTRL2, 0x0008); - } - /* Set 2-wire transfer rate of SFP+ module EEPROM - * to 100Khz since some DACs(direct attached cables) do - * not work at 400Khz. - */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, - 0xa001); - - /* Set TX PreEmphasis if needed */ - if ((params->feature_config_flags & - FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { - DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," - "TX_CTRL2 0x%x\n", - params->xgxs_config_tx[0], - params->xgxs_config_tx[1]); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_TX_CTRL1, - params->xgxs_config_tx[0]); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_TX_CTRL2, - params->xgxs_config_tx[1]); - } +static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u32 val; + u32 swap_val, swap_override, aeu_gpio_mask, offset; + DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); - break; - } + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); + bnx2x_wait_reset_complete(bp, phy); + + bnx2x_8726_external_rom_boot(phy, params); + + /* Need to call module detected on initialization since + the module detection triggered by actual module + insertion might occur before driver is loaded, and when + driver is loaded, it reset all registers, including the + transmitter */ + bnx2x_sfp_module_detection(phy, params); + + if (phy->req_line_speed == SPEED_1000) { + DP(NETIF_MSG_LINK, "Setting 1G force\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x400); + } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { + DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); + /* Set Flow control */ + bnx2x_ext_phy_set_pause(params, phy, vars); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200); + /* Enable RX-ALARM control to receive + interrupt for 1G speed change */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + 0x400); + + } else { /* Default 10G. Set only LASI control */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1); + } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - { - u16 fw_ver1, fw_ver2; - DP(NETIF_MSG_LINK, - "Setting the SFX7101 LASI indication\n"); + /* Set TX PreEmphasis if needed */ + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," + "TX_CTRL2 0x%x\n", + phy->tx_preemphasis[0], + phy->tx_preemphasis[1]); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8726_TX_CTRL1, + phy->tx_preemphasis[0]); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8726_TX_CTRL2, + phy->tx_preemphasis[1]); + } - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_CTRL, 0x1); - DP(NETIF_MSG_LINK, - "Setting the SFX7101 LED to blink on traffic\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); - - bnx2x_ext_phy_set_pause(params, vars); - /* Restart autoneg */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, &val); - val |= 0x200; - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, val); - - /* Save spirom version */ - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_7101_VER1, &fw_ver1); - - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, MDIO_PMA_DEVAD, - MDIO_PMA_REG_7101_VER2, &fw_ver2); - - bnx2x_save_spirom_version(params->bp, params->port, - params->shmem_base, - (u32)(fw_ver1<<16 | fw_ver2)); - break; - } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - /* This phy uses the NIG latch mechanism since link - indication arrives through its LED4 and not via - its LASI signal, so we get steady signal - instead of clear on read */ - bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, - 1 << NIG_LATCH_BC_ENABLE_MI_INT); - - bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x0000); - - bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr); - if (params->req_line_speed == SPEED_AUTO_NEG) { - - u16 autoneg_val, an_1000_val, an_10_100_val; - /* set 1000 speed advertisement */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_1000T_CTRL, - &an_1000_val); - - if (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) { - an_1000_val |= (1<<8); - if (params->req_duplex == DUPLEX_FULL) - an_1000_val |= (1<<9); - DP(NETIF_MSG_LINK, "Advertising 1G\n"); - } else - an_1000_val &= ~((1<<8) | (1<<9)); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_1000T_CTRL, - an_1000_val); - - /* set 100 speed advertisement */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_AN_ADV, - &an_10_100_val); - - if (params->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) { - an_10_100_val |= (1<<7); - if (params->req_duplex == DUPLEX_FULL) - an_10_100_val |= (1<<8); - DP(NETIF_MSG_LINK, - "Advertising 100M\n"); - } else - an_10_100_val &= ~((1<<7) | (1<<8)); - - /* set 10 speed advertisement */ - if (params->speed_cap_mask & - (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) { - an_10_100_val |= (1<<5); - if (params->req_duplex == DUPLEX_FULL) - an_10_100_val |= (1<<6); - DP(NETIF_MSG_LINK, "Advertising 10M\n"); - } - else - an_10_100_val &= ~((1<<5) | (1<<6)); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_AN_ADV, - an_10_100_val); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - &autoneg_val); - - /* Disable forced speed */ - autoneg_val &= ~(1<<6|1<<13); - - /* Enable autoneg and restart autoneg - for legacy speeds */ - autoneg_val |= (1<<9|1<<12); - - if (params->req_duplex == DUPLEX_FULL) - autoneg_val |= (1<<8); - else - autoneg_val &= ~(1<<8); - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - autoneg_val); - - if (params->speed_cap_mask & - PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) { - DP(NETIF_MSG_LINK, "Advertising 10G\n"); - /* Restart autoneg for 10G*/ - - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x3200); - } - } else { - /* Force speed */ - u16 autoneg_ctrl, pma_ctrl; - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - &autoneg_ctrl); - - /* Disable autoneg */ - autoneg_ctrl &= ~(1<<12); - - /* Set 1000 force */ - switch (params->req_line_speed) { - case SPEED_10000: - DP(NETIF_MSG_LINK, - "Unable to set 10G force !\n"); - break; - case SPEED_1000: - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - &pma_ctrl); - autoneg_ctrl &= ~(1<<13); - autoneg_ctrl |= (1<<6); - pma_ctrl &= ~(1<<13); - pma_ctrl |= (1<<6); - DP(NETIF_MSG_LINK, - "Setting 1000M force\n"); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - pma_ctrl); - break; - case SPEED_100: - autoneg_ctrl |= (1<<13); - autoneg_ctrl &= ~(1<<6); - DP(NETIF_MSG_LINK, - "Setting 100M force\n"); - break; - case SPEED_10: - autoneg_ctrl &= ~(1<<13); - autoneg_ctrl &= ~(1<<6); - DP(NETIF_MSG_LINK, - "Setting 10M force\n"); - break; - } + /* Set GPIO3 to trigger SFP+ module insertion/removal */ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port); - /* Duplex mode */ - if (params->req_duplex == DUPLEX_FULL) { - autoneg_ctrl |= (1<<8); - DP(NETIF_MSG_LINK, - "Setting full duplex\n"); - } else - autoneg_ctrl &= ~(1<<8); - - /* Update autoneg ctrl and pma ctrl */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_LEGACY_MII_CTRL, - autoneg_ctrl); - } + /* The GPIO should be swapped if the swap register is set and active */ + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - /* Save spirom version */ - bnx2x_save_8481_spirom_version(bp, params->port, - ext_phy_addr, - params->shmem_base); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - DP(NETIF_MSG_LINK, - "XGXS PHY Failure detected 0x%x\n", - params->ext_phy_config); - rc = -EINVAL; - break; - default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - params->ext_phy_config); - rc = -EINVAL; - break; - } + /* Select function upon port-swap configuration */ + if (params->port == 0) { + offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; + aeu_gpio_mask = (swap_val && swap_override) ? + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; + } else { + offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; + aeu_gpio_mask = (swap_val && swap_override) ? + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : + AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; + } + val = REG_RD(bp, offset); + /* add GPIO3 to group */ + val |= aeu_gpio_mask; + REG_WR(bp, offset, val); + return 0; - } else { /* SerDes */ +} - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "SerDes Direct\n"); - break; +static void bnx2x_8726_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port); + /* Set serial boot control for external load */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_GEN_CTRL, 0x0001); +} - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - DP(NETIF_MSG_LINK, "SerDes 5482\n"); - break; +/******************************************************************/ +/* BCM8727 PHY SECTION */ +/******************************************************************/ - default: - DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", - params->ext_phy_config); - break; +static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy, + struct link_params *params, u8 mode) +{ + struct bnx2x *bp = params->bp; + u16 led_mode_bitmask = 0; + u16 gpio_pins_bitmask = 0; + u16 val; + /* Only NOC flavor requires to set the LED specifically */ + if (!(phy->flags & FLAGS_NOC)) + return; + switch (mode) { + case LED_MODE_FRONT_PANEL_OFF: + case LED_MODE_OFF: + led_mode_bitmask = 0; + gpio_pins_bitmask = 0x03; + break; + case LED_MODE_ON: + led_mode_bitmask = 0; + gpio_pins_bitmask = 0x02; + break; + case LED_MODE_OPER: + led_mode_bitmask = 0x60; + gpio_pins_bitmask = 0x11; + break; + } + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_OPT_CTRL, + &val); + val &= 0xff8f; + val |= led_mode_bitmask; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_OPT_CTRL, + val); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_GPIO_CTRL, + &val); + val &= 0xffe0; + val |= gpio_pins_bitmask; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_GPIO_CTRL, + val); +} +static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) { + u32 swap_val, swap_override; + u8 port; + /** + * The PHY reset is controlled by GPIO 1. Fake the port number + * to cancel the swap done in set_gpio() + */ + struct bnx2x *bp = params->bp; + swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); + swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); + port = (swap_val && swap_override) ^ 1; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, port); +} + +static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + u16 tmp1, val, mod_abs; + u16 rx_alarm_ctrl_val; + u16 lasi_ctrl_val; + struct bnx2x *bp = params->bp; + /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ + + bnx2x_wait_reset_complete(bp, phy); + rx_alarm_ctrl_val = (1<<2) | (1<<5) ; + lasi_ctrl_val = 0x0004; + + DP(NETIF_MSG_LINK, "Initializing BCM8727\n"); + /* enable LASI */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + rx_alarm_ctrl_val); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val); + + /* Initially configure MOD_ABS to interrupt when + module is presence( bit 8) */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); + /* Set EDC off by setting OPTXLOS signal input to low + (bit 9). + When the EDC is off it locks onto a reference clock and + avoids becoming 'lost'.*/ + mod_abs &= ~(1<<8); + if (!(phy->flags & FLAGS_NOC)) + mod_abs &= ~(1<<9); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); + + + /* Make MOD_ABS give interrupt on change */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, + &val); + val |= (1<<12); + if (phy->flags & FLAGS_NOC) + val |= (3<<5); + + /** + * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0 + * status which reflect SFP+ module over-current + */ + if (!(phy->flags & FLAGS_NOC)) + val &= 0xff8f; /* Reset bits 4-6 */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val); + + bnx2x_8727_power_module(bp, phy, 1); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1); + + /* Set option 1G speed */ + if (phy->req_line_speed == SPEED_1000) { + DP(NETIF_MSG_LINK, "Setting 1G force\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1); + DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1); + /** + * Power down the XAUI until link is up in case of dual-media + * and 1G + */ + if (DUAL_MEDIA(params)) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, &val); + val |= (3<<10); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, val); } + } else if ((phy->req_line_speed == SPEED_AUTO_NEG) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) && + ((phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) != + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { + + DP(NETIF_MSG_LINK, "Setting 1G clause37\n"); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300); + } else { + /** + * Since the 8727 has only single reset pin, need to set the 10G + * registers although it is default + */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, + 0x0020); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, + 0x0008); } - return rc; + + /* Set 2-wire transfer rate of SFP+ module EEPROM + * to 100Khz since some DACs(direct attached cables) do + * not work at 400Khz. + */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR, + 0xa001); + + /* Set TX PreEmphasis if needed */ + if ((params->feature_config_flags & + FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { + DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n", + phy->tx_preemphasis[0], + phy->tx_preemphasis[1]); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1, + phy->tx_preemphasis[0]); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2, + phy->tx_preemphasis[1]); + } + + return 0; } -static void bnx2x_8727_handle_mod_abs(struct link_params *params) +static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, + struct link_params *params) { struct bnx2x *bp = params->bp; u16 mod_abs, rx_alarm_status; - u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); u32 val = REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, dev_info. port_feature_config[params->port]. config)); - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs); if (mod_abs & (1<<8)) { @@ -4602,18 +5104,16 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params) (bit 9). When the EDC is off it locks onto a reference clock and avoids becoming 'lost'.*/ - mod_abs &= ~((1<<8)|(1<<9)); - bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + mod_abs &= ~(1<<8); + if (!(phy->flags & FLAGS_NOC)) + mod_abs &= ~(1<<9); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); /* Clear RX alarm since it stays up as long as the mod_abs wasn't changed */ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); @@ -4630,33 +5130,28 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params) 2. Restore the default polarity of the OPRXLOS signal and this signal will then correctly indicate the presence or absence of the Rx signal. (bit 9) */ - mod_abs |= ((1<<8)|(1<<9)); - bnx2x_cl45_write(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); + mod_abs |= (1<<8); + if (!(phy->flags & FLAGS_NOC)) + mod_abs |= (1<<9); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); /* Clear RX alarm since it stays up as long as the mod_abs wasn't changed. This is need to be done before calling the module detection, otherwise it will clear the link update alarm */ - bnx2x_cl45_read(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, params->port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, 0); + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); - if (bnx2x_wait_for_sfp_module_initialized(params) - == 0) - bnx2x_sfp_module_detection(params); + if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) + bnx2x_sfp_module_detection(phy, params); else DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); } @@ -4667,1298 +5162,1714 @@ static void bnx2x_8727_handle_mod_abs(struct link_params *params) module plugged in/out */ } +static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) -static u8 bnx2x_ext_phy_is_link_up(struct link_params *params, - struct link_vars *vars, - u8 is_mi_int) { struct bnx2x *bp = params->bp; - u32 ext_phy_type; - u8 ext_phy_addr; - u16 val1 = 0, val2; - u16 rx_sd, pcs_status; - u8 ext_phy_link_up = 0; - u8 port = params->port; - - if (vars->phy_flags & PHY_XGXS_FLAG) { - ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "XGXS Direct\n"); - ext_phy_link_up = 1; - break; + u8 link_up = 0; + u16 link_status = 0; + u16 rx_alarm_status, lasi_ctrl, val1; + + /* If PHY is not initialized, do not check link status */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, + &lasi_ctrl); + if (!lasi_ctrl) + return 0; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - DP(NETIF_MSG_LINK, "XGXS 8705\n"); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_WIS_DEVAD, - MDIO_WIS_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); - - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_WIS_DEVAD, - MDIO_WIS_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1); - - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_SD, &rx_sd); - - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - 1, - 0xc809, &val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - 1, - 0xc809, &val1); - - DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1); - ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && - ((val1 & (1<<8)) == 0)); - if (ext_phy_link_up) - vars->line_speed = SPEED_10000; - break; + /* Check the LASI */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, + &rx_alarm_status); + vars->line_speed = 0; + DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - DP(NETIF_MSG_LINK, "XGXS 8706/8726\n"); - /* Clear RX Alarm*/ - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, - &val2); - /* clear LASI indication*/ - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, - &val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, - &val2); - DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->" - "0x%x\n", val1, val2); - - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, - &rx_sd); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, - &pcs_status); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, - &val2); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, - &val2); - - DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x" - " pcs_status 0x%x 1Gbps link_status 0x%x\n", - rx_sd, pcs_status, val2); - /* link is up if both bit 0 of pmd_rx_sd and - * bit 0 of pcs_status are set, or if the autoneg bit - 1 is set - */ - ext_phy_link_up = ((rx_sd & pcs_status & 0x1) || - (val2 & (1<<1))); - if (ext_phy_link_up) { - if (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) { - /* If transmitter is disabled, - ignore false link up indication */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &val1); - if (val1 & (1<<15)) { - DP(NETIF_MSG_LINK, "Tx is " - "disabled\n"); - ext_phy_link_up = 0; - break; - } - } - if (val2 & (1<<1)) - vars->line_speed = SPEED_1000; - else - vars->line_speed = SPEED_10000; - } - break; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - { - u16 link_status = 0; - u16 rx_alarm_status; - /* Check the LASI */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); - - DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", - rx_alarm_status); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1); - DP(NETIF_MSG_LINK, - "8727 LASI status 0x%x\n", - val1); + /* Clear MSG-OUT */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1); - /* Clear MSG-OUT */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_M8051_MSGOUT_REG, - &val1); + /** + * If a module is present and there is need to check + * for over current + */ + if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) { + /* Check over-current using 8727 GPIO0 input*/ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL, + &val1); + + if ((val1 & (1<<8)) == 0) { + DP(NETIF_MSG_LINK, "8727 Power fault has been detected" + " on port %d\n", params->port); + netdev_err(bp->dev, "Error: Power fault on Port %d has" + " been detected and the power to " + "that SFP+ module has been removed" + " to prevent failure of the card." + " Please remove the SFP+ module and" + " restart the system to clear this" + " error.\n", + params->port); /* - * If a module is present and there is need to check - * for over current + * Disable all RX_ALARMs except for + * mod_abs */ - if (!(params->feature_config_flags & - FEATURE_CONFIG_BCM8727_NOC) && - !(rx_alarm_status & (1<<5))) { - /* Check over-current using 8727 GPIO0 input*/ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8727_GPIO_CTRL, - &val1); - - if ((val1 & (1<<8)) == 0) { - DP(NETIF_MSG_LINK, "8727 Power fault" - " has been detected on " - "port %d\n", - params->port); - netdev_err(bp->dev, "Error: Power fault on Port %d has been detected and the power to that SFP+ module has been removed to prevent failure of the card. Please remove the SFP+ module and restart the system to clear this error.\n", - params->port); - /* - * Disable all RX_ALARMs except for - * mod_abs - */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - (1<<5)); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &val1); - /* Wait for module_absent_event */ - val1 |= (1<<8); - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - val1); - /* Clear RX alarm */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, - &rx_alarm_status); - break; - } - } /* Over current check */ - - /* When module absent bit is set, check module */ - if (rx_alarm_status & (1<<5)) { - bnx2x_8727_handle_mod_abs(params); - /* Enable all mod_abs and link detection bits */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM_CTRL, - ((1<<5) | (1<<2))); - } - - /* If transmitter is disabled, - ignore false link up indication */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PHY_IDENTIFIER, - &val1); - if (val1 & (1<<15)) { - DP(NETIF_MSG_LINK, "Tx is disabled\n"); - ext_phy_link_up = 0; - break; - } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5)); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_SPEED_LINK_STATUS, - &link_status); - - /* Bits 0..2 --> speed detected, - bits 13..15--> link is down */ - if ((link_status & (1<<2)) && - (!(link_status & (1<<15)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_10000; - } else if ((link_status & (1<<0)) && - (!(link_status & (1<<13)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_1000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 1G\n", params->port); - } else { - ext_phy_link_up = 0; - DP(NETIF_MSG_LINK, - "port %x: External link" - " is down\n", params->port); - } - break; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, &val1); + /* Wait for module_absent_event */ + val1 |= (1<<8); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_PHY_IDENTIFIER, val1); + /* Clear RX alarm */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); + return 0; } + } /* Over current check */ + + /* When module absent bit is set, check module */ + if (rx_alarm_status & (1<<5)) { + bnx2x_8727_handle_mod_abs(phy, params); + /* Enable all mod_abs and link detection bits */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, + ((1<<5) | (1<<2))); + } + DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n"); + bnx2x_8727_specific_func(phy, params, ENABLE_TX); + /* If transmitter is disabled, ignore false link up indication */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1); + if (val1 & (1<<15)) { + DP(NETIF_MSG_LINK, "Tx is disabled\n"); + return 0; + } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - { - u16 link_status = 0; - u16 an1000_status = 0; - - if (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_LASI_STATUS, &val1); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_LASI_STATUS, &val2); - DP(NETIF_MSG_LINK, - "870x LASI status 0x%x->0x%x\n", - val1, val2); - } else { - /* In 8073, port1 is directed through emac0 and - * port0 is directed through emac1 - */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_STATUS, &val1); - - DP(NETIF_MSG_LINK, - "8703 LASI status 0x%x\n", - val1); - } + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status); - /* clear the interrupt LASI status register */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", - val2, val1); - /* Clear MSG-OUT */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_M8051_MSGOUT_REG, - &val1); - - /* Check the LASI */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_RX_ALARM, &val2); - - DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2); - - /* Check the link status */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PCS_DEVAD, - MDIO_PCS_REG_STATUS, &val2); - DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2); - - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val1); - ext_phy_link_up = ((val1 & 4) == 4); - DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1); - if (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { - - if (ext_phy_link_up && - ((params->req_line_speed != - SPEED_10000))) { - if (bnx2x_bcm8073_xaui_wa(params) - != 0) { - ext_phy_link_up = 0; - break; - } - } - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_LINK_STATUS, - &an1000_status); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_LINK_STATUS, - &an1000_status); - - /* Check the link status on 1.1.2 */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x," - "an_link_status=0x%x\n", - val2, val1, an1000_status); - - ext_phy_link_up = (((val1 & 4) == 4) || - (an1000_status & (1<<1))); - if (ext_phy_link_up && - bnx2x_8073_is_snr_needed(params)) { - /* The SNR will improve about 2dbby - changing the BW and FEE main tap.*/ - - /* The 1st write to change FFE main - tap is set before restart AN */ - /* Change PLL Bandwidth in EDC - register */ - bnx2x_cl45_write(bp, port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_PLL_BANDWIDTH, - 0x26BC); - - /* Change CDR Bandwidth in EDC - register */ - bnx2x_cl45_write(bp, port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CDR_BANDWIDTH, - 0x0333); - } - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8073_SPEED_LINK_STATUS, - &link_status); - - /* Bits 0..2 --> speed detected, - bits 13..15--> link is down */ - if ((link_status & (1<<2)) && - (!(link_status & (1<<15)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_10000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 10G\n", params->port); - } else if ((link_status & (1<<1)) && - (!(link_status & (1<<14)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_2500; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 2.5G\n", params->port); - } else if ((link_status & (1<<0)) && - (!(link_status & (1<<13)))) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_1000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 1G\n", params->port); - } else { - ext_phy_link_up = 0; - DP(NETIF_MSG_LINK, - "port %x: External link" - " is down\n", params->port); - } - } else { - /* See if 1G link is up for the 8072 */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_LINK_STATUS, - &an1000_status); - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_LINK_STATUS, - &an1000_status); - if (an1000_status & (1<<1)) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_1000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 1G\n", params->port); - } else if (ext_phy_link_up) { - ext_phy_link_up = 1; - vars->line_speed = SPEED_10000; - DP(NETIF_MSG_LINK, - "port %x: External link" - " up in 10G\n", params->port); - } - } + /* Bits 0..2 --> speed detected, + bits 13..15--> link is down */ + if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) { + link_up = 1; + vars->line_speed = SPEED_10000; + } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) { + link_up = 1; + vars->line_speed = SPEED_1000; + DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n", + params->port); + } else { + link_up = 0; + DP(NETIF_MSG_LINK, "port %x: External link is down\n", + params->port); + } + if (link_up) + bnx2x_ext_phy_resolve_fc(phy, params, vars); + + if ((DUAL_MEDIA(params)) && + (phy->req_line_speed == SPEED_1000)) { + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, &val1); + /** + * In case of dual-media board and 1G, power up the XAUI side, + * otherwise power it down. For 10G it is done automatically + */ + if (link_up) + val1 &= ~(3<<10); + else + val1 |= (3<<10); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8727_PCS_GP, val1); + } + return link_up; +} + +static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + /* Disable Transmitter */ + bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); + /* Clear LASI */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0); +} +/******************************************************************/ +/* BCM8481/BCM84823/BCM84833 PHY SECTION */ +/******************************************************************/ +static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy, + struct link_params *params) +{ + u16 val, fw_ver1, fw_ver2, cnt; + struct bnx2x *bp = params->bp; + + /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/ + /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009); + + for (cnt = 0; cnt < 100; cnt++) { + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); + if (val & 1) break; - } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_LASI_STATUS, &val1); - DP(NETIF_MSG_LINK, - "10G-base-T LASI status 0x%x->0x%x\n", - val2, val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val2); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_STATUS, &val1); - DP(NETIF_MSG_LINK, - "10G-base-T PMA status 0x%x->0x%x\n", - val2, val1); - ext_phy_link_up = ((val1 & 4) == 4); - /* if link is up - * print the AN outcome of the SFX7101 PHY - */ - if (ext_phy_link_up) { - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_MASTER_STATUS, - &val2); - vars->line_speed = SPEED_10000; - DP(NETIF_MSG_LINK, - "SFX7101 AN status 0x%x->Master=%x\n", - val2, - (val2 & (1<<14))); - } - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - /* Check 10G-BaseT link status */ - /* Check PMD signal ok */ - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - 0xFFFA, - &val1); - bnx2x_cl45_read(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_8481_PMD_SIGNAL, - &val2); - DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2); - - /* Check link 10G */ - if (val2 & (1<<11)) { - vars->line_speed = SPEED_10000; - ext_phy_link_up = 1; - bnx2x_8481_set_10G_led_mode(params, - ext_phy_type, - ext_phy_addr); - } else { /* Check Legacy speed link */ - u16 legacy_status, legacy_speed; - - /* Enable expansion register 0x42 - (Operation mode status) */ - bnx2x_cl45_write(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, - 0xf42); - - /* Get legacy speed operation status */ - bnx2x_cl45_read(bp, params->port, - ext_phy_type, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, - &legacy_status); - - DP(NETIF_MSG_LINK, "Legacy speed status" - " = 0x%x\n", legacy_status); - ext_phy_link_up = ((legacy_status & (1<<11)) - == (1<<11)); - if (ext_phy_link_up) { - legacy_speed = (legacy_status & (3<<9)); - if (legacy_speed == (0<<9)) - vars->line_speed = SPEED_10; - else if (legacy_speed == (1<<9)) - vars->line_speed = - SPEED_100; - else if (legacy_speed == (2<<9)) - vars->line_speed = - SPEED_1000; - else /* Should not happen */ - vars->line_speed = 0; - - if (legacy_status & (1<<8)) - vars->duplex = DUPLEX_FULL; - else - vars->duplex = DUPLEX_HALF; - - DP(NETIF_MSG_LINK, "Link is up " - "in %dMbps, is_duplex_full" - "= %d\n", - vars->line_speed, - (vars->duplex == DUPLEX_FULL)); - bnx2x_8481_set_legacy_led_mode(params, - ext_phy_type, - ext_phy_addr); - } - } - break; - default: - DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", - params->ext_phy_config); - ext_phy_link_up = 0; - break; - } - /* Set SGMII mode for external phy */ - if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { - if (vars->line_speed < SPEED_1000) - vars->phy_flags |= PHY_SGMII_FLAG; - else - vars->phy_flags &= ~PHY_SGMII_FLAG; - } + udelay(5); + } + if (cnt == 100) { + DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n"); + bnx2x_save_spirom_version(bp, params->port, 0, + phy->ver_addr); + return; + } - } else { /* SerDes */ - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - DP(NETIF_MSG_LINK, "SerDes Direct\n"); - ext_phy_link_up = 1; + + /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200); + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A); + for (cnt = 0; cnt < 100; cnt++) { + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val); + if (val & 1) break; + udelay(5); + } + if (cnt == 100) { + DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n"); + bnx2x_save_spirom_version(bp, params->port, 0, + phy->ver_addr); + return; + } + + /* lower 16 bits of the register SPI_FW_STATUS */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1); + /* upper 16 bits of register SPI_FW_STATUS */ + bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2); - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - DP(NETIF_MSG_LINK, "SerDes 5482\n"); - ext_phy_link_up = 1; - break; + bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1, + phy->ver_addr); +} - default: - DP(NETIF_MSG_LINK, - "BAD SerDes ext_phy_config 0x%x\n", - params->ext_phy_config); - ext_phy_link_up = 0; - break; - } - } +static void bnx2x_848xx_set_led(struct bnx2x *bp, + struct bnx2x_phy *phy) +{ + u16 val; + + /* PHYC_CTL_LED_CTL */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, &val); + val &= 0xFE00; + val |= 0x0092; + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, val); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x80); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x18); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x0040); - return ext_phy_link_up; + /* 'Interrupt Mask' */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + 0xFFFB, 0xFFFD); } -static void bnx2x_link_int_enable(struct link_params *params) +static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { - u8 port = params->port; - u32 ext_phy_type; - u32 mask; struct bnx2x *bp = params->bp; + u16 autoneg_val, an_1000_val, an_10_100_val; + bnx2x_wait_reset_complete(bp, phy); + bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, + 1 << NIG_LATCH_BC_ENABLE_MI_INT); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000); + + bnx2x_848xx_set_led(bp, phy); + + /* set 1000 speed advertisement */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, + &an_1000_val); + + bnx2x_ext_phy_set_pause(params, phy, vars); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_AN_ADV, + &an_10_100_val); + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL, + &autoneg_val); + /* Disable forced speed */ + autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13)); + an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8)); + + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) || + (phy->req_line_speed == SPEED_1000)) { + an_1000_val |= (1<<8); + autoneg_val |= (1<<9 | 1<<12); + if (phy->req_duplex == DUPLEX_FULL) + an_1000_val |= (1<<9); + DP(NETIF_MSG_LINK, "Advertising 1G\n"); + } else + an_1000_val &= ~((1<<8) | (1<<9)); + + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL, + an_1000_val); + + /* set 10 speed advertisement */ + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) { + an_10_100_val |= (1<<7); + /* Enable autoneg and restart autoneg for legacy speeds */ + autoneg_val |= (1<<9 | 1<<12); + + if (phy->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<8); + DP(NETIF_MSG_LINK, "Advertising 100M\n"); + } + /* set 10 speed advertisement */ + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL | + PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) { + an_10_100_val |= (1<<5); + autoneg_val |= (1<<9 | 1<<12); + if (phy->req_duplex == DUPLEX_FULL) + an_10_100_val |= (1<<6); + DP(NETIF_MSG_LINK, "Advertising 10M\n"); + } - /* setting the status to report on link up - for either XGXS or SerDes */ - - if (params->switch_cfg == SWITCH_CFG_10G) { - mask = (NIG_MASK_XGXS0_LINK10G | - NIG_MASK_XGXS0_LINK_STATUS); - DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n"); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && - (ext_phy_type != - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) { - mask |= NIG_MASK_MI_INT; - DP(NETIF_MSG_LINK, "enabled external phy int\n"); - } + /* Only 10/100 are allowed to work in FORCE mode */ + if (phy->req_line_speed == SPEED_100) { + autoneg_val |= (1<<13); + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 100M force\n"); + } + if (phy->req_line_speed == SPEED_10) { + /* Enabled AUTO-MDIX when autoneg is disabled */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL, + (1<<15 | 1<<9 | 7<<0)); + DP(NETIF_MSG_LINK, "Setting 10M force\n"); + } - } else { /* SerDes */ - mask = NIG_MASK_SERDES0_LINK_STATUS; - DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - if ((ext_phy_type != - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && - (ext_phy_type != - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) { - mask |= NIG_MASK_MI_INT; - DP(NETIF_MSG_LINK, "enabled external phy int\n"); - } + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV, + an_10_100_val); + + if (phy->req_duplex == DUPLEX_FULL) + autoneg_val |= (1<<8); + + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); + + if (((phy->req_line_speed == SPEED_AUTO_NEG) && + (phy->speed_cap_mask & + PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) || + (phy->req_line_speed == SPEED_10000)) { + DP(NETIF_MSG_LINK, "Advertising 10G\n"); + /* Restart autoneg for 10G*/ + + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, + 0x3200); + } else if (phy->req_line_speed != SPEED_10 && + phy->req_line_speed != SPEED_100) { + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, + 1); } - bnx2x_bits_en(bp, - NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - mask); + /* Save spirom version */ + bnx2x_save_848xx_spirom_version(phy, params); - DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port, - (params->switch_cfg == SWITCH_CFG_10G), - REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); - DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n", - REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), - REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18), - REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c)); - DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", - REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), - REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); + return 0; } -static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port, - u8 is_mi_int) +static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { - u32 latch_status = 0, is_mi_int_status; - /* Disable the MI INT ( external phy int ) - * by writing 1 to the status register. Link down indication - * is high-active-signal, so in this case we need to write the - * status to clear the XOR - */ - /* Read Latched signals */ - latch_status = REG_RD(bp, - NIG_REG_LATCH_STATUS_0 + port*8); - is_mi_int_status = REG_RD(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4); - DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x," - "latch_status = 0x%x\n", - is_mi_int, is_mi_int_status, latch_status); - /* Handle only those with latched-signal=up.*/ - if (latch_status & 1) { - /* For all latched-signal=up,Write original_signal to status */ - if (is_mi_int) - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 - + port*4, - NIG_STATUS_EMAC0_MI_INT); - else - bnx2x_bits_dis(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 - + port*4, - NIG_STATUS_EMAC0_MI_INT); - /* For all latched-signal=up : Re-Arm Latch signals */ - REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, - (latch_status & 0xfffe) | (latch_status & 1)); - } + struct bnx2x *bp = params->bp; + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); + return bnx2x_848xx_cmn_config_init(phy, params, vars); } -/* - * link management - */ -static void bnx2x_link_int_ack(struct link_params *params, - struct link_vars *vars, u8 is_10g, - u8 is_mi_int) + +static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 port = params->port; + u8 port = params->port, initialize = 1; + u16 val; + u16 temp; + u32 actual_phy_selection; + u8 rc = 0; - /* first reset all status - * we assume only one line will be change at a time */ - bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_STATUS_XGXS0_LINK10G | - NIG_STATUS_XGXS0_LINK_STATUS | - NIG_STATUS_SERDES0_LINK_STATUS)); - if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) || - (XGXS_EXT_PHY_TYPE(params->ext_phy_config) - == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) { - bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int); + /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ + + msleep(1); + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, + port); + msleep(200); /* 100 is not enough */ + + /* BCM84823 requires that XGXS links up first @ 10G for normal + behavior */ + temp = vars->line_speed; + vars->line_speed = SPEED_10000; + bnx2x_set_autoneg(¶ms->phy[INT_PHY], params, vars, 0); + bnx2x_program_serdes(¶ms->phy[INT_PHY], params, vars); + vars->line_speed = temp; + + /* Set dual-media configuration according to configuration */ + + bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_MEDIA, &val); + val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK | + MDIO_CTL_REG_84823_MEDIA_LINE_MASK | + MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN | + MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK | + MDIO_CTL_REG_84823_MEDIA_FIBER_1G); + val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI | + MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L; + + actual_phy_selection = bnx2x_phy_selection(params); + + switch (actual_phy_selection) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + /* Do nothing. Essentialy this is like the priority copper */ + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER; + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + /* Do nothing here. The first PHY won't be initialized at all */ + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN; + initialize = 0; + break; } - if (vars->phy_link_up) { - if (is_10g) { - /* Disable the 10G link interrupt - * by writing 1 to the status register - */ - DP(NETIF_MSG_LINK, "10G XGXS phy link up\n"); - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_STATUS_XGXS0_LINK10G); + if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000) + val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G; - } else if (params->switch_cfg == SWITCH_CFG_10G) { - /* Disable the link interrupt - * by writing 1 to the relevant lane - * in the status register - */ - u32 ser_lane = ((params->lane_config & - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> - PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); + bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD, + MDIO_CTL_REG_84823_MEDIA, val); + DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n", + params->multi_phy_config, val); - DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n", - vars->line_speed); - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - ((1 << ser_lane) << - NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); + if (initialize) + rc = bnx2x_848xx_cmn_config_init(phy, params, vars); + else + bnx2x_save_848xx_spirom_version(phy, params); + return rc; +} - } else { /* SerDes */ - DP(NETIF_MSG_LINK, "SerDes phy link up\n"); - /* Disable the link interrupt - * by writing 1 to the status register - */ - bnx2x_bits_en(bp, - NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - NIG_STATUS_SERDES0_LINK_STATUS); - } +static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u16 val, val1, val2; + u8 link_up = 0; + + /* Check 10G-BaseT link status */ + /* Check PMD signal ok */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, 0xFFFA, &val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL, + &val2); + DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2); + + /* Check link 10G */ + if (val2 & (1<<11)) { + vars->line_speed = SPEED_10000; + link_up = 1; + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); + } else { /* Check Legacy speed link */ + u16 legacy_status, legacy_speed; + + /* Enable expansion register 0x42 (Operation mode status) */ + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42); + + /* Get legacy speed operation status */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_EXPANSION_REG_RD_RW, + &legacy_status); + + DP(NETIF_MSG_LINK, "Legacy speed status" + " = 0x%x\n", legacy_status); + link_up = ((legacy_status & (1<<11)) == (1<<11)); + if (link_up) { + legacy_speed = (legacy_status & (3<<9)); + if (legacy_speed == (0<<9)) + vars->line_speed = SPEED_10; + else if (legacy_speed == (1<<9)) + vars->line_speed = SPEED_100; + else if (legacy_speed == (2<<9)) + vars->line_speed = SPEED_1000; + else /* Should not happen */ + vars->line_speed = 0; - } else { /* link_down */ + if (legacy_status & (1<<8)) + vars->duplex = DUPLEX_FULL; + else + vars->duplex = DUPLEX_HALF; + + DP(NETIF_MSG_LINK, "Link is up in %dMbps," + " is_duplex_full= %d\n", vars->line_speed, + (vars->duplex == DUPLEX_FULL)); + /* Check legacy speed AN resolution */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_MII_STATUS, + &val); + if (val & (1<<5)) + vars->link_status |= + LINK_STATUS_AUTO_NEGOTIATE_COMPLETE; + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8481_LEGACY_AN_EXPANSION, + &val); + if ((val & (1<<0)) == 0) + vars->link_status |= + LINK_STATUS_PARALLEL_DETECTION_USED; + } + } + if (link_up) { + DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n", + vars->line_speed); + bnx2x_ext_phy_resolve_fc(phy, params, vars); } + + return link_up; } -static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len) +static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len) { - u8 *str_ptr = str; - u32 mask = 0xf0000000; - u8 shift = 8*4; - u8 digit; - if (len < 10) { - /* Need more than 10chars for this format */ - *str_ptr = '\0'; - return -EINVAL; - } - while (shift > 0) { + u8 status = 0; + u32 spirom_ver; + spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F); + status = bnx2x_format_ver(spirom_ver, str, len); + return status; +} - shift -= 4; - digit = ((num & mask) >> shift); - if (digit < 0xa) - *str_ptr = digit + '0'; - else - *str_ptr = digit - 0xa + 'a'; - str_ptr++; - mask = mask >> 4; - if (shift == 4*4) { - *str_ptr = ':'; - str_ptr++; - } - } - *str_ptr = '\0'; - return 0; +static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, 0); + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, 1); } -u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, - u8 *version, u16 len) +static void bnx2x_8481_link_reset(struct bnx2x_phy *phy, + struct link_params *params) { - struct bnx2x *bp; - u32 ext_phy_type = 0; - u32 spirom_ver = 0; - u8 status; + bnx2x_cl45_write(params->bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000); + bnx2x_cl45_write(params->bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1); +} - if (version == NULL || params == NULL) - return -EINVAL; - bp = params->bp; +static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 port = params->port; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, + MISC_REGISTERS_GPIO_OUTPUT_LOW, + port); +} - spirom_ver = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, - port_mb[params->port].ext_phy_fw_version)); +static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, + struct link_params *params, u8 mode) +{ + struct bnx2x *bp = params->bp; + u16 val; - status = 0; - /* reset the returned value to zero */ - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + switch (mode) { + case LED_MODE_OFF: - if (len < 5) - return -EINVAL; + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port); - version[0] = (spirom_ver & 0xFF); - version[1] = (spirom_ver & 0xFF00) >> 8; - version[2] = (spirom_ver & 0xFF0000) >> 16; - version[3] = (spirom_ver & 0xFF000000) >> 24; - version[4] = '\0'; + if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY1) { - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - status = bnx2x_format_ver(spirom_ver, version, len); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 | - (spirom_ver & 0x7F); - status = bnx2x_format_ver(spirom_ver, version, len); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - version[0] = '\0'; - break; + /* Set LED masks */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:" - " type is FAILURE!\n"); - status = -EINVAL; + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x0); + + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); + } break; + case LED_MODE_FRONT_PANEL_OFF: - default: + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n", + params->port); + + if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY1) { + + /* Set LED masks */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x0); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x20); + + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); + } break; - } - return status; -} + case LED_MODE_ON: -static void bnx2x_set_xgxs_loopback(struct link_params *params, - struct link_vars *vars, - u8 is_10g) -{ - u8 port = params->port; - struct bnx2x *bp = params->bp; + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port); - if (is_10g) { - u32 md_devad; + if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY1) { + /* Set control reg */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + &val); + val &= 0x8000; + val |= 0x2492; - DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + val); - /* change the uni_phy_addr in the nig */ - md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + - port*0x18)); + /* Set LED masks */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x0); - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x20); - bnx2x_cl45_write(bp, port, 0, - params->phy_addr, - 5, - (MDIO_REG_BANK_AER_BLOCK + - (MDIO_AER_BLOCK_AER_REG & 0xf)), - 0x2800); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x20); - bnx2x_cl45_write(bp, port, 0, - params->phy_addr, - 5, - (MDIO_REG_BANK_CL73_IEEEB0 + - (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)), - 0x6041); - msleep(200); - /* set aer mmd back */ - bnx2x_set_aer_mmd(params, vars); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x0); + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x20); + } + break; + + case LED_MODE_OPER: + + DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port); - /* and md_devad */ - REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, - md_devad); + if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) == + SHARED_HW_CFG_LED_EXTPHY1) { - } else { - u16 mii_control; + /* Set control reg */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + &val); + + if (!((val & + MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK) + >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)){ + DP(NETIF_MSG_LINK, "Seting LINK_SIGNAL\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LINK_SIGNAL, + 0xa492); + } - DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); + /* Set LED masks */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x10); - CL45_RD_OVER_CL22(bp, port, - params->phy_addr, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - &mii_control); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED2_MASK, + 0x80); - CL45_WR_OVER_CL22(bp, port, - params->phy_addr, - MDIO_REG_BANK_COMBO_IEEE0, - MDIO_COMBO_IEEE0_MII_CONTROL, - (mii_control | - MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK)); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED3_MASK, + 0x98); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED5_MASK, + 0x40); + + } else { + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_LED1_MASK, + 0x80); + } + break; } } +/******************************************************************/ +/* SFX7101 PHY SECTION */ +/******************************************************************/ +static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy, + struct link_params *params) +{ + struct bnx2x *bp = params->bp; + /* SFX7101_XGXS_TEST1 */ + bnx2x_cl45_write(bp, phy, + MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100); +} - -static void bnx2x_ext_phy_loopback(struct link_params *params) +static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) { + u16 fw_ver1, fw_ver2, val; struct bnx2x *bp = params->bp; - u8 ext_phy_addr; - u32 ext_phy_type; + DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n"); - if (params->switch_cfg == SWITCH_CFG_10G) { - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); - /* CL37 Autoneg Enabled */ - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN: - DP(NETIF_MSG_LINK, - "ext_phy_loopback: We should not get here\n"); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n"); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n"); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, - 0x0001); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - /* SFX7101_XGXS_TEST1 */ - bnx2x_cl45_write(bp, params->port, ext_phy_type, - ext_phy_addr, - MDIO_XS_DEVAD, - MDIO_XS_SFX7101_XGXS_TEST1, - 0x100); - DP(NETIF_MSG_LINK, - "ext_phy_loopback: set ext phy loopback\n"); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: + /* Restore normal power mode*/ + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); + /* HW reset */ + bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_wait_reset_complete(bp, phy); + + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1); + DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n"); + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3)); + + bnx2x_ext_phy_set_pause(params, phy, vars); + /* Restart autoneg */ + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val); + val |= 0x200; + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val); + + /* Save spirom version */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1); + + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2); + bnx2x_save_spirom_version(bp, params->port, + (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr); + return 0; +} - break; - } /* switch external PHY type */ - } else { - /* serdes */ - ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); - ext_phy_addr = (params->ext_phy_config & - PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) - >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT; +static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy, + struct link_params *params, + struct link_vars *vars) +{ + struct bnx2x *bp = params->bp; + u8 link_up; + u16 val1, val2; + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1); + DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n", + val2, val1); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1); + DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n", + val2, val1); + link_up = ((val1 & 4) == 4); + /* if link is up + * print the AN outcome of the SFX7101 PHY + */ + if (link_up) { + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS, + &val2); + vars->line_speed = SPEED_10000; + DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n", + val2, (val2 & (1<<14))); + bnx2x_ext_phy_10G_an_resolve(bp, phy, vars); + bnx2x_ext_phy_resolve_fc(phy, params, vars); } + return link_up; } -/* - *------------------------------------------------------------------------ - * bnx2x_override_led_value - - * - * Override the led value of the requsted led - * - *------------------------------------------------------------------------ - */ -u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, - u32 led_idx, u32 value) +static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len) { - u32 reg_val; + if (*len < 5) + return -EINVAL; + str[0] = (spirom_ver & 0xFF); + str[1] = (spirom_ver & 0xFF00) >> 8; + str[2] = (spirom_ver & 0xFF0000) >> 16; + str[3] = (spirom_ver & 0xFF000000) >> 24; + str[4] = '\0'; + *len -= 5; + return 0; +} - /* If port 0 then use EMAC0, else use EMAC1*/ - u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; +void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy) +{ + u16 val, cnt; - DP(NETIF_MSG_LINK, - "bnx2x_override_led_value() port %x led_idx %d value %d\n", - port, led_idx, value); + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, &val); - switch (led_idx) { - case 0: /* 10MB led */ - /* Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 10M_OVERRIDE bit, - otherwise reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) : - (reg_val & ~EMAC_LED_10MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - break; - case 1: /*100MB led */ - /*Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 100M_OVERRIDE bit, - otherwise reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) : - (reg_val & ~EMAC_LED_100MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + for (cnt = 0; cnt < 10; cnt++) { + msleep(50); + /* Writes a self-clearing reset */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, + (val | (1<<15))); + /* Wait for clear */ + bnx2x_cl45_read(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7101_RESET, &val); + + if ((val & (1<<15)) == 0) + break; + } +} + +static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy, + struct link_params *params) { + /* Low power mode is controlled by GPIO 2 */ + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2, + MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); + /* The PHY reset is controlled by GPIO 1 */ + bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1, + MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port); +} + +static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy, + struct link_params *params, u8 mode) +{ + u16 val = 0; + struct bnx2x *bp = params->bp; + switch (mode) { + case LED_MODE_FRONT_PANEL_OFF: + case LED_MODE_OFF: + val = 2; break; - case 2: /* 1000MB led */ - /* Read the current value of the LED register in the - EMAC block */ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 1000M_OVERRIDE bit, otherwise - reset it. */ - reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) : - (reg_val & ~EMAC_LED_1000MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + case LED_MODE_ON: + val = 1; break; - case 3: /* 2500MB led */ - /* Read the current value of the LED register in the - EMAC block*/ - reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED); - /* Set the OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the 2500M_OVERRIDE bit, otherwise - reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) : - (reg_val & ~EMAC_LED_2500MB_OVERRIDE); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); + case LED_MODE_OPER: + val = 0; break; - case 4: /*10G led */ - if (port == 0) { - REG_WR(bp, NIG_REG_LED_10G_P0, - value); + } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_7107_LINK_LED_CNTL, + val); +} + +/******************************************************************/ +/* STATIC PHY DECLARATION */ +/******************************************************************/ + +static struct bnx2x_phy phy_null = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN, + .addr = 0, + .flags = FLAGS_INIT_XGXS_FIRST, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = 0, + .media_type = ETH_PHY_NOT_PRESENT, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)NULL, + .read_status = (read_status_t)NULL, + .link_reset = (link_reset_t)NULL, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL +}; + +static struct bnx2x_phy phy_serdes = { + .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT, + .addr = 0xff, + .flags = 0, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_UNSPECIFIED, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_init_serdes, + .read_status = (read_status_t)bnx2x_link_settings_status, + .link_reset = (link_reset_t)bnx2x_int_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL +}; + +static struct bnx2x_phy phy_xgxs = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, + .addr = 0xff, + .flags = 0, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_UNSPECIFIED, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_init_xgxs, + .read_status = (read_status_t)bnx2x_link_settings_status, + .link_reset = (link_reset_t)bnx2x_int_link_reset, + .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback, + .format_fw_ver = (format_fw_ver_t)NULL, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL +}; + +static struct bnx2x_phy phy_7101 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_7101_config_init, + .read_status = (read_status_t)bnx2x_7101_read_status, + .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, + .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback, + .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver, + .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset, + .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led, + .phy_specific_func = (phy_specific_func_t)NULL +}; +static struct bnx2x_phy phy_8073 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, + .addr = 0xff, + .flags = FLAGS_HW_LOCK_REQUIRED, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_2500baseX_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_UNSPECIFIED, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8073_config_init, + .read_status = (read_status_t)bnx2x_8073_read_status, + .link_reset = (link_reset_t)bnx2x_8073_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL +}; +static struct bnx2x_phy phy_8705 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705, + .addr = 0xff, + .flags = FLAGS_INIT_XGXS_FIRST, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_XFP_FIBER, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8705_config_init, + .read_status = (read_status_t)bnx2x_8705_read_status, + .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL +}; +static struct bnx2x_phy phy_8706 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706, + .addr = 0xff, + .flags = FLAGS_INIT_XGXS_FIRST, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_SFP_FIBER, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8706_config_init, + .read_status = (read_status_t)bnx2x_8706_read_status, + .link_reset = (link_reset_t)bnx2x_common_ext_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL +}; + +static struct bnx2x_phy phy_8726 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, + .addr = 0xff, + .flags = (FLAGS_HW_LOCK_REQUIRED | + FLAGS_INIT_XGXS_FIRST), + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_SFP_FIBER, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8726_config_init, + .read_status = (read_status_t)bnx2x_8726_read_status, + .link_reset = (link_reset_t)bnx2x_8726_link_reset, + .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback, + .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)NULL, + .phy_specific_func = (phy_specific_func_t)NULL +}; + +static struct bnx2x_phy phy_8727 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_SFP_FIBER, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8727_config_init, + .read_status = (read_status_t)bnx2x_8727_read_status, + .link_reset = (link_reset_t)bnx2x_8727_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver, + .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset, + .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led, + .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func +}; +static struct bnx2x_phy phy_8481 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ | + FLAGS_REARM_LATCH_SIGNAL, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_8481_config_init, + .read_status = (read_status_t)bnx2x_848xx_read_status, + .link_reset = (link_reset_t)bnx2x_8481_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, + .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset, + .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, + .phy_specific_func = (phy_specific_func_t)NULL +}; + +static struct bnx2x_phy phy_84823 = { + .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823, + .addr = 0xff, + .flags = FLAGS_FAN_FAILURE_DET_REQ | + FLAGS_REARM_LATCH_SIGNAL, + .def_md_devad = 0, + .reserved = 0, + .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, + .mdio_ctrl = 0, + .supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_Pause | + SUPPORTED_Asym_Pause), + .media_type = ETH_PHY_BASE_T, + .ver_addr = 0, + .req_flow_ctrl = 0, + .req_line_speed = 0, + .speed_cap_mask = 0, + .req_duplex = 0, + .rsrv = 0, + .config_init = (config_init_t)bnx2x_848x3_config_init, + .read_status = (read_status_t)bnx2x_848xx_read_status, + .link_reset = (link_reset_t)bnx2x_848x3_link_reset, + .config_loopback = (config_loopback_t)NULL, + .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver, + .hw_reset = (hw_reset_t)NULL, + .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led, + .phy_specific_func = (phy_specific_func_t)NULL +}; + +/*****************************************************************/ +/* */ +/* Populate the phy according. Main function: bnx2x_populate_phy */ +/* */ +/*****************************************************************/ + +static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base, + struct bnx2x_phy *phy, u8 port, + u8 phy_index) +{ + /* Get the 4 lanes xgxs config rx and tx */ + u32 rx = 0, tx = 0, i; + for (i = 0; i < 2; i++) { + /** + * INT_PHY and EXT_PHY1 share the same value location in the + * shmem. When num_phys is greater than 1, than this value + * applies only to EXT_PHY1 + */ + if (phy_index == INT_PHY || phy_index == EXT_PHY1) { + rx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_rx[i<<1])); + + tx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config_tx[i<<1])); } else { - REG_WR(bp, NIG_REG_LED_10G_P1, - value); - } - break; - case 5: /* TRAFFIC led */ - /* Find if the traffic control is via BMAC or EMAC */ - if (port == 0) - reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN); - else - reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN); + rx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); - /* Override the traffic led in the EMAC:*/ - if (reg_val == 1) { - /* Read the current value of the LED register in - the EMAC block */ - reg_val = REG_RD(bp, emac_base + - EMAC_REG_EMAC_LED); - /* Set the TRAFFIC_OVERRIDE bit to 1 */ - reg_val |= EMAC_LED_OVERRIDE; - /* If value is 1, set the TRAFFIC bit, otherwise - reset it.*/ - reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) : - (reg_val & ~EMAC_LED_TRAFFIC); - REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val); - } else { /* Override the traffic led in the BMAC: */ - REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 - + port*4, 1); - REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4, - value); + tx = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].xgxs_config2_rx[i<<1])); } + + phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff); + phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff); + + phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff); + phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff); + } +} + +static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base, + u8 phy_index, u8 port) +{ + u32 ext_phy_config = 0; + switch (phy_index) { + case EXT_PHY1: + ext_phy_config = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].external_phy_config)); + break; + case EXT_PHY2: + ext_phy_config = REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_hw_config[port].external_phy_config2)); break; default: - DP(NETIF_MSG_LINK, - "bnx2x_override_led_value() unknown led index %d " - "(should be 0-5)\n", led_idx); + DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index); return -EINVAL; } - return 0; + return ext_phy_config; } - - -u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) +static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, + struct bnx2x_phy *phy) { - u8 port = params->port; - u16 hw_led_mode = params->hw_led_mode; - u8 rc = 0; - u32 tmp; - u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0; - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - struct bnx2x *bp = params->bp; - DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode); - DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n", - speed, hw_led_mode); - switch (mode) { - case LED_MODE_OFF: - REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - SHARED_HW_CFG_LED_MAC1); - - tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); - EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE)); + u32 phy_addr; + u32 chip_id; + u32 switch_cfg = (REG_RD(bp, shmem_base + + offsetof(struct shmem_region, + dev_info.port_feature_config[port].link_config)) & + PORT_FEATURE_CONNECTED_SWITCH_MASK); + chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16; + switch (switch_cfg) { + case SWITCH_CFG_1G: + phy_addr = REG_RD(bp, + NIG_REG_SERDES0_CTRL_PHY_ADDR + + port * 0x10); + *phy = phy_serdes; break; + case SWITCH_CFG_10G: + phy_addr = REG_RD(bp, + NIG_REG_XGXS0_CTRL_PHY_ADDR + + port * 0x18); + *phy = phy_xgxs; + break; + default: + DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); + return -EINVAL; + } + phy->addr = (u8)phy_addr; + phy->mdio_ctrl = bnx2x_get_emac_base(bp, + SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH, + port); + if (CHIP_IS_E2(bp)) + phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR; + else + phy->def_md_devad = DEFAULT_PHY_DEV_ADDR; - case LED_MODE_OPER: - if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); - REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); - } else { - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - hw_led_mode); - } + DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n", + port, phy->addr, phy->mdio_ctrl); - REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + - port*4, 0); - /* Set blinking rate to ~15.9Hz */ - REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4, - LED_BLINK_RATE_VAL); - REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 + - port*4, 1); - tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); - EMAC_WR(bp, EMAC_REG_EMAC_LED, - (tmp & (~EMAC_LED_OVERRIDE))); + bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY); + return 0; +} - if (CHIP_IS_E1(bp) && - ((speed == SPEED_2500) || - (speed == SPEED_1000) || - (speed == SPEED_100) || - (speed == SPEED_10))) { - /* On Everest 1 Ax chip versions for speeds less than - 10G LED scheme is different */ - REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 - + port*4, 1); - REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + - port*4, 0); - REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 + - port*4, 1); - } +static u8 bnx2x_populate_ext_phy(struct bnx2x *bp, + u8 phy_index, + u32 shmem_base, + u32 shmem2_base, + u8 port, + struct bnx2x_phy *phy) +{ + u32 ext_phy_config, phy_type, config2; + u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH; + ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base, + phy_index, port); + phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); + /* Select the phy type */ + switch (phy_type) { + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED; + *phy = phy_8073; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: + *phy = phy_8705; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: + *phy = phy_8706; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; + *phy = phy_8726; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: + /* BCM8727_NOC => BCM8727 no over current */ + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; + *phy = phy_8727; + phy->flags |= FLAGS_NOC; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: + mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1; + *phy = phy_8727; break; - - default: - rc = -EINVAL; - DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n", - mode); + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: + *phy = phy_8481; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: + *phy = phy_84823; break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: + *phy = phy_7101; + break; + case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: + *phy = phy_null; + return -EINVAL; + default: + *phy = phy_null; + return 0; } - return rc; -} + phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config); + bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index); -u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u16 gp_status = 0; + /** + * The shmem address of the phy version is located on different + * structures. In case this structure is too old, do not set + * the address + */ + config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region, + dev_info.shared_hw_config.config2)); + if (phy_index == EXT_PHY1) { + phy->ver_addr = shmem_base + offsetof(struct shmem_region, + port_mb[port].ext_phy_fw_version); + + /* Check specific mdc mdio settings */ + if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK) + mdc_mdio_access = config2 & + SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK; + } else { + u32 size = REG_RD(bp, shmem2_base); - CL45_RD_OVER_CL22(bp, params->port, - params->phy_addr, - MDIO_REG_BANK_GP_STATUS, - MDIO_GP_STATUS_TOP_AN_STATUS1, - &gp_status); - /* link is up only if both local phy and external phy are up */ - if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) && - bnx2x_ext_phy_is_link_up(params, vars, 1)) - return 0; + if (size > + offsetof(struct shmem2_region, ext_phy_fw_version2)) { + phy->ver_addr = shmem2_base + + offsetof(struct shmem2_region, + ext_phy_fw_version2[port]); + } + /* Check specific mdc mdio settings */ + if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) + mdc_mdio_access = (config2 & + SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >> + (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT - + SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT); + } + phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port); - return -ESRCH; + /** + * In case mdc/mdio_access of the external phy is different than the + * mdc/mdio access of the XGXS, a HW lock must be taken in each access + * to prevent one port interfere with another port's CL45 operations. + */ + if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH) + phy->flags |= FLAGS_HW_LOCK_REQUIRED; + DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n", + phy_type, port, phy_index); + DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n", + phy->addr, phy->mdio_ctrl); + return 0; } -static u8 bnx2x_link_initialize(struct link_params *params, - struct link_vars *vars) +static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base, + u32 shmem2_base, u8 port, struct bnx2x_phy *phy) { - struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 rc = 0; - u8 non_ext_phy; - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - /* Activate the external PHY */ - bnx2x_ext_phy_reset(params, vars); + u8 status = 0; + phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN; + if (phy_index == INT_PHY) + return bnx2x_populate_int_phy(bp, shmem_base, port, phy); + status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base, + port, phy); + return status; +} - bnx2x_set_aer_mmd(params, vars); +static void bnx2x_phy_def_cfg(struct link_params *params, + struct bnx2x_phy *phy, + u8 phy_index) +{ + struct bnx2x *bp = params->bp; + u32 link_config; + /* Populate the default phy configuration for MF mode */ + if (phy_index == EXT_PHY2) { + link_config = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].link_config2)); + phy->speed_cap_mask = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].speed_capability_mask2)); + } else { + link_config = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_feature_config[params->port].link_config)); + phy->speed_cap_mask = REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].speed_capability_mask)); + } + DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask" + " 0x%x\n", phy_index, link_config, phy->speed_cap_mask); + + phy->req_duplex = DUPLEX_FULL; + switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { + case PORT_FEATURE_LINK_SPEED_10M_HALF: + phy->req_duplex = DUPLEX_HALF; + case PORT_FEATURE_LINK_SPEED_10M_FULL: + phy->req_line_speed = SPEED_10; + break; + case PORT_FEATURE_LINK_SPEED_100M_HALF: + phy->req_duplex = DUPLEX_HALF; + case PORT_FEATURE_LINK_SPEED_100M_FULL: + phy->req_line_speed = SPEED_100; + break; + case PORT_FEATURE_LINK_SPEED_1G: + phy->req_line_speed = SPEED_1000; + break; + case PORT_FEATURE_LINK_SPEED_2_5G: + phy->req_line_speed = SPEED_2500; + break; + case PORT_FEATURE_LINK_SPEED_10G_CX4: + phy->req_line_speed = SPEED_10000; + break; + default: + phy->req_line_speed = SPEED_AUTO_NEG; + break; + } - if (vars->phy_flags & PHY_XGXS_FLAG) - bnx2x_set_master_ln(params); + switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) { + case PORT_FEATURE_FLOW_CONTROL_AUTO: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO; + break; + case PORT_FEATURE_FLOW_CONTROL_TX: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX; + break; + case PORT_FEATURE_FLOW_CONTROL_RX: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX; + break; + case PORT_FEATURE_FLOW_CONTROL_BOTH: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH; + break; + default: + phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; + break; + } +} - rc = bnx2x_reset_unicore(params); - /* reset the SerDes and wait for reset bit return low */ - if (rc != 0) - return rc; +u32 bnx2x_phy_selection(struct link_params *params) +{ + u32 phy_config_swapped, prio_cfg; + u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT; + + phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; + + prio_cfg = params->multi_phy_config & + PORT_HW_CFG_PHY_SELECTION_MASK; + + if (phy_config_swapped) { + switch (prio_cfg) { + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY; + break; + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY; + break; + } + } else + return_cfg = prio_cfg; - bnx2x_set_aer_mmd(params, vars); + return return_cfg; +} - /* setting the masterLn_def again after the reset */ - if (vars->phy_flags & PHY_XGXS_FLAG) { - bnx2x_set_master_ln(params); - bnx2x_set_swap_lanes(params); - } - if (vars->phy_flags & PHY_XGXS_FLAG) { - if ((params->req_line_speed && - ((params->req_line_speed == SPEED_100) || - (params->req_line_speed == SPEED_10))) || - (!params->req_line_speed && - (params->speed_cap_mask >= - PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && - (params->speed_cap_mask < - PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) - )) { - vars->phy_flags |= PHY_SGMII_FLAG; - } else { - vars->phy_flags &= ~PHY_SGMII_FLAG; +u8 bnx2x_phy_probe(struct link_params *params) +{ + u8 phy_index, actual_phy_idx, link_cfg_idx; + u32 phy_config_swapped; + struct bnx2x *bp = params->bp; + struct bnx2x_phy *phy; + params->num_phys = 0; + DP(NETIF_MSG_LINK, "Begin phy probe\n"); + phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; + + for (phy_index = INT_PHY; phy_index < MAX_PHYS; + phy_index++) { + link_cfg_idx = LINK_CONFIG_IDX(phy_index); + actual_phy_idx = phy_index; + if (phy_config_swapped) { + if (phy_index == EXT_PHY1) + actual_phy_idx = EXT_PHY2; + else if (phy_index == EXT_PHY2) + actual_phy_idx = EXT_PHY1; + } + DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x," + " actual_phy_idx %x\n", phy_config_swapped, + phy_index, actual_phy_idx); + phy = ¶ms->phy[actual_phy_idx]; + if (bnx2x_populate_phy(bp, phy_index, params->shmem_base, + params->shmem2_base, params->port, + phy) != 0) { + params->num_phys = 0; + DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n", + phy_index); + for (phy_index = INT_PHY; + phy_index < MAX_PHYS; + phy_index++) + *phy = phy_null; + return -EINVAL; } + if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) + break; + + bnx2x_phy_def_cfg(params, phy, phy_index); + params->num_phys++; } - /* In case of external phy existance, the line speed would be the - line speed linked up by the external phy. In case it is direct only, - then the line_speed during initialization will be equal to the - req_line_speed*/ - vars->line_speed = params->req_line_speed; - bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc); + DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys); + return 0; +} - /* init ext phy and enable link state int */ - non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || - (params->loopback_mode == LOOPBACK_XGXS_10)); +u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx) +{ + if (phy_idx < params->num_phys) + return params->phy[phy_idx].supported; + return 0; +} - if (non_ext_phy || - (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || - (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) || - (params->loopback_mode == LOOPBACK_EXT_PHY)) { - if (params->req_line_speed == SPEED_AUTO_NEG) - bnx2x_set_parallel_detection(params, vars->phy_flags); - bnx2x_init_internal_phy(params, vars, non_ext_phy); - } +static void set_phy_vars(struct link_params *params) +{ + struct bnx2x *bp = params->bp; + u8 actual_phy_idx, phy_index, link_cfg_idx; + u8 phy_config_swapped = params->multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED; + for (phy_index = INT_PHY; phy_index < params->num_phys; + phy_index++) { + link_cfg_idx = LINK_CONFIG_IDX(phy_index); + actual_phy_idx = phy_index; + if (phy_config_swapped) { + if (phy_index == EXT_PHY1) + actual_phy_idx = EXT_PHY2; + else if (phy_index == EXT_PHY2) + actual_phy_idx = EXT_PHY1; + } + params->phy[actual_phy_idx].req_flow_ctrl = + params->req_flow_ctrl[link_cfg_idx]; - if (!non_ext_phy) - rc |= bnx2x_ext_phy_init(params, vars); + params->phy[actual_phy_idx].req_line_speed = + params->req_line_speed[link_cfg_idx]; - bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, - (NIG_STATUS_XGXS0_LINK10G | - NIG_STATUS_XGXS0_LINK_STATUS | - NIG_STATUS_SERDES0_LINK_STATUS)); + params->phy[actual_phy_idx].speed_cap_mask = + params->speed_cap_mask[link_cfg_idx]; - return rc; + params->phy[actual_phy_idx].req_duplex = + params->req_duplex[link_cfg_idx]; + DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x," + " speed_cap_mask %x\n", + params->phy[actual_phy_idx].req_flow_ctrl, + params->phy[actual_phy_idx].req_line_speed, + params->phy[actual_phy_idx].speed_cap_mask); + } } - u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u32 val; - DP(NETIF_MSG_LINK, "Phy Initialization started\n"); - DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n", - params->req_line_speed, params->req_flow_ctrl); + DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n", + params->req_line_speed[0], params->req_flow_ctrl[0]); + DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n", + params->req_line_speed[1], params->req_flow_ctrl[1]); vars->link_status = 0; vars->phy_link_up = 0; vars->link_up = 0; @@ -5966,11 +6877,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; vars->mac_type = MAC_TYPE_NONE; - - if (params->switch_cfg == SWITCH_CFG_1G) - vars->phy_flags = PHY_SERDES_FLAG; - else - vars->phy_flags = PHY_XGXS_FLAG; + vars->phy_flags = 0; /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, @@ -5981,6 +6888,13 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) bnx2x_emac_init(params, vars); + if (params->num_phys == 0) { + DP(NETIF_MSG_LINK, "No phy found for initialization !!\n"); + return -EINVAL; + } + set_phy_vars(params); + + DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys); if (CHIP_REV_IS_FPGA(bp)) { vars->link_up = 1; @@ -5999,7 +6913,9 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) } bnx2x_emac_enable(params, vars, 0); - bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed); + if (!(CHIP_IS_E2(bp))) + bnx2x_pbf_update(params, vars->flow_ctrl, + vars->line_speed); /* disable drain */ REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); @@ -6040,7 +6956,8 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->phy_flags = PHY_XGXS_FLAG; - bnx2x_phy_deassert(params, vars->phy_flags); + bnx2x_xgxs_deassert(params); + /* set bmac loopback */ bnx2x_bmac_enable(params, vars, 1); @@ -6057,395 +6974,169 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->phy_flags = PHY_XGXS_FLAG; - bnx2x_phy_deassert(params, vars->phy_flags); + bnx2x_xgxs_deassert(params); /* set bmac loopback */ bnx2x_emac_enable(params, vars, 1); - bnx2x_emac_program(params, vars->line_speed, - vars->duplex); + bnx2x_emac_program(params, vars); REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); - } else if ((params->loopback_mode == LOOPBACK_XGXS_10) || + } else if ((params->loopback_mode == LOOPBACK_XGXS) || (params->loopback_mode == LOOPBACK_EXT_PHY)) { vars->link_up = 1; - vars->line_speed = SPEED_10000; - vars->duplex = DUPLEX_FULL; vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - vars->phy_flags = PHY_XGXS_FLAG; - - val = REG_RD(bp, - NIG_REG_XGXS0_CTRL_PHY_ADDR+ - params->port*0x18); - params->phy_addr = (u8)val; - - bnx2x_phy_deassert(params, vars->phy_flags); - bnx2x_link_initialize(params, vars); - - vars->mac_type = MAC_TYPE_BMAC; - - bnx2x_bmac_enable(params, vars, 0); - - if (params->loopback_mode == LOOPBACK_XGXS_10) { - /* set 10G XGXS loopback */ - bnx2x_set_xgxs_loopback(params, vars, 1); + vars->duplex = DUPLEX_FULL; + if (params->req_line_speed[0] == SPEED_1000) { + vars->line_speed = SPEED_1000; + vars->mac_type = MAC_TYPE_EMAC; } else { - /* set external phy loopback */ - bnx2x_ext_phy_loopback(params); - } - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + - params->port*4, 0); - - bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed); - } else - /* No loopback */ - { - bnx2x_phy_deassert(params, vars->phy_flags); - switch (params->switch_cfg) { - case SWITCH_CFG_1G: - vars->phy_flags |= PHY_SERDES_FLAG; - if ((params->ext_phy_config & - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) == - PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) { - vars->phy_flags |= PHY_SGMII_FLAG; - } - - val = REG_RD(bp, - NIG_REG_SERDES0_CTRL_PHY_ADDR+ - params->port*0x10); - - params->phy_addr = (u8)val; - - break; - case SWITCH_CFG_10G: - vars->phy_flags |= PHY_XGXS_FLAG; - val = REG_RD(bp, - NIG_REG_XGXS0_CTRL_PHY_ADDR+ - params->port*0x18); - params->phy_addr = (u8)val; - - break; - default: - DP(NETIF_MSG_LINK, "Invalid switch_cfg\n"); - return -EINVAL; + vars->line_speed = SPEED_10000; + vars->mac_type = MAC_TYPE_BMAC; } - DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr); + bnx2x_xgxs_deassert(params); bnx2x_link_initialize(params, vars); - msleep(30); - bnx2x_link_int_enable(params); - } - return 0; -} - -static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr) -{ - DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port); - - /* Set serial boot control for external load */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_GEN_CTRL, 0x0001); -} - -u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, - u8 reset_ext_phy) -{ - struct bnx2x *bp = params->bp; - u32 ext_phy_config = params->ext_phy_config; - u8 port = params->port; - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); - u32 val = REG_RD(bp, params->shmem_base + - offsetof(struct shmem_region, dev_info. - port_feature_config[params->port]. - config)); - DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); - /* disable attentions */ - vars->link_status = 0; - bnx2x_update_mng(params, vars->link_status); - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); - - /* activate nig drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - - /* disable nig egress interface */ - REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); - REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); - - /* Stop BigMac rx */ - bnx2x_bmac_rx_disable(bp, port); - - /* disable emac */ - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - - msleep(10); - /* The PHY reset is controled by GPIO 1 - * Hold it as vars low - */ - /* clear link led */ - bnx2x_set_led(params, LED_MODE_OFF, 0); - if (reset_ext_phy) { - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - { - - /* Disable Transmitter */ - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(params->ext_phy_config); - if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) - bnx2x_sfp_set_transmitter(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr, 0); - break; - } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - DP(NETIF_MSG_LINK, "Setting 8073 port %d into " - "low power mode\n", - port); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - port); - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - { - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(params->ext_phy_config); - /* Set soft reset */ - bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr); - break; - } - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: - { - u8 ext_phy_addr = - XGXS_EXT_PHY_ADDR(params->ext_phy_config); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_AN_DEVAD, - MDIO_AN_REG_CTRL, 0x0000); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, - ext_phy_addr, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 1); - break; - } - default: - /* HW reset */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - port); - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, - port); - DP(NETIF_MSG_LINK, "reset external PHY\n"); - } - } - /* reset the SerDes/XGXS */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, - (0x1ff << (port*16))); - - /* reset BigMac */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - - /* disable nig ingress interface */ - REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); - REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); - REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); - REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); - vars->link_up = 0; - return 0; -} - -static u8 bnx2x_update_link_down(struct link_params *params, - struct link_vars *vars) -{ - struct bnx2x *bp = params->bp; - u8 port = params->port; - - DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); - bnx2x_set_led(params, LED_MODE_OFF, 0); - - /* indicate no mac active */ - vars->mac_type = MAC_TYPE_NONE; - - /* update shared memory */ - vars->link_status = 0; - vars->line_speed = 0; - bnx2x_update_mng(params, vars->link_status); - - /* activate nig drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - - /* disable emac */ - REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - - msleep(10); - - /* reset BigMac */ - bnx2x_bmac_rx_disable(bp, params->port); - REG_WR(bp, GRCBASE_MISC + - MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - return 0; -} - -static u8 bnx2x_update_link_up(struct link_params *params, - struct link_vars *vars, - u8 link_10g, u32 gp_status) -{ - struct bnx2x *bp = params->bp; - u8 port = params->port; - u8 rc = 0; - vars->link_status |= LINK_STATUS_LINK_UP; - if (link_10g) { + if (params->req_line_speed[0] == SPEED_1000) { + bnx2x_emac_program(params, vars); + bnx2x_emac_enable(params, vars, 0); + } else bnx2x_bmac_enable(params, vars, 0); - bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000); - } else { - rc = bnx2x_emac_program(params, vars->line_speed, - vars->duplex); - bnx2x_emac_enable(params, vars, 0); + if (params->loopback_mode == LOOPBACK_XGXS) { + /* set 10G XGXS loopback */ + params->phy[INT_PHY].config_loopback( + ¶ms->phy[INT_PHY], + params); - /* AN complete? */ - if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) { - if (!(vars->phy_flags & - PHY_SGMII_FLAG)) - bnx2x_set_gmii_tx_driver(params); + } else { + /* set external phy loopback */ + u8 phy_index; + for (phy_index = EXT_PHY1; + phy_index < params->num_phys; phy_index++) { + if (params->phy[phy_index].config_loopback) + params->phy[phy_index].config_loopback( + ¶ms->phy[phy_index], + params); + } } - } - /* PBF - link up */ - rc |= bnx2x_pbf_update(params, vars->flow_ctrl, - vars->line_speed); + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + + params->port*4, 0); - /* disable drain */ - REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0); + bnx2x_set_led(params, vars, + LED_MODE_OPER, vars->line_speed); + } else + /* No loopback */ + { + if (params->switch_cfg == SWITCH_CFG_10G) + bnx2x_xgxs_deassert(params); + else + bnx2x_serdes_deassert(bp, params->port); - /* update shared memory */ - bnx2x_update_mng(params, vars->link_status); - msleep(20); - return rc; + bnx2x_link_initialize(params, vars); + msleep(30); + bnx2x_link_int_enable(params); + } + return 0; } -/* This function should called upon link interrupt */ -/* In case vars->link_up, driver needs to - 1. Update the pbf - 2. Disable drain - 3. Update the shared memory - 4. Indicate link up - 5. Set LEDs - Otherwise, - 1. Update shared memory - 2. Reset BigMac - 3. Report link down - 4. Unset LEDs -*/ -u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars) +u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, + u8 reset_ext_phy) { struct bnx2x *bp = params->bp; - u8 port = params->port; - u16 gp_status; - u8 link_10g; - u8 ext_phy_link_up, rc = 0; - u32 ext_phy_type; - u8 is_mi_int = 0; + u8 phy_index, port = params->port; + DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); + /* disable attentions */ + vars->link_status = 0; + bnx2x_update_mng(params, vars->link_status); + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); - DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n", - port, (vars->phy_flags & PHY_XGXS_FLAG), - REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); + /* activate nig drain */ + REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); - is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + - port*0x18) > 0); - DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n", - REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4), - is_mi_int, - REG_RD(bp, - NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c)); + /* disable nig egress interface */ + REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); - DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n", - REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68), - REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68)); + /* Stop BigMac rx */ + bnx2x_bmac_rx_disable(bp, port); /* disable emac */ REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); - ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); - - /* Check external link change only for non-direct */ - ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int); - - /* Read gp_status */ - CL45_RD_OVER_CL22(bp, port, params->phy_addr, - MDIO_REG_BANK_GP_STATUS, - MDIO_GP_STATUS_TOP_AN_STATUS1, - &gp_status); - - rc = bnx2x_link_settings_status(params, vars, gp_status, - ext_phy_link_up); - if (rc != 0) - return rc; - - /* anything 10 and over uses the bmac */ - link_10g = ((vars->line_speed == SPEED_10000) || - (vars->line_speed == SPEED_12000) || - (vars->line_speed == SPEED_12500) || - (vars->line_speed == SPEED_13000) || - (vars->line_speed == SPEED_15000) || - (vars->line_speed == SPEED_16000)); - - bnx2x_link_int_ack(params, vars, link_10g, is_mi_int); - - /* In case external phy link is up, and internal link is down - ( not initialized yet probably after link initialization, it needs - to be initialized. - Note that after link down-up as result of cable plug, - the xgxs link would probably become up again without the need to - initialize it*/ - - if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) && - (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) && - (ext_phy_link_up && !vars->phy_link_up)) - bnx2x_init_internal_phy(params, vars, 0); + msleep(10); + /* The PHY reset is controled by GPIO 1 + * Hold it as vars low + */ + /* clear link led */ + bnx2x_set_led(params, vars, LED_MODE_OFF, 0); - /* link is up only if both local phy and external phy are up */ - vars->link_up = (ext_phy_link_up && vars->phy_link_up); + if (reset_ext_phy) { + for (phy_index = EXT_PHY1; phy_index < params->num_phys; + phy_index++) { + if (params->phy[phy_index].link_reset) + params->phy[phy_index].link_reset( + ¶ms->phy[phy_index], + params); + } + } - if (vars->link_up) - rc = bnx2x_update_link_up(params, vars, link_10g, gp_status); - else - rc = bnx2x_update_link_down(params, vars); + if (params->phy[INT_PHY].link_reset) + params->phy[INT_PHY].link_reset( + ¶ms->phy[INT_PHY], params); + /* reset BigMac */ + REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - return rc; + /* disable nig ingress interface */ + REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0); + REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0); + REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0); + REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0); + vars->link_up = 0; + return 0; } -static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) +/****************************************************************************/ +/* Common function */ +/****************************************************************************/ +static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) { - u8 ext_phy_addr[PORT_MAX]; + struct bnx2x_phy phy[PORT_MAX]; + struct bnx2x_phy *phy_blk[PORT_MAX]; u16 val; s8 port; + s8 port_of_path = 0; /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { - /* Extract the ext phy address for the port */ - u32 ext_phy_config = REG_RD(bp, shmem_base + - offsetof(struct shmem_region, - dev_info.port_hw_config[port].external_phy_config)); + u32 shmem_base, shmem2_base; + /* In E2, same phy is using for port0 of the two paths */ + if (CHIP_IS_E2(bp)) { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + port_of_path = 0; + } else { + shmem_base = shmem_base_path[0]; + shmem2_base = shmem2_base_path[0]; + port_of_path = port; + } + /* Extract the ext phy address for the port */ + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, + port_of_path, &phy[port]) != + 0) { + DP(NETIF_MSG_LINK, "populate_phy failed\n"); + return -EINVAL; + } /* disable attentions */ bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, (NIG_MASK_XGXS0_LINK_STATUS | @@ -6453,17 +7144,13 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) NIG_MASK_SERDES0_LINK_STATUS | NIG_MASK_MI_INT)); - ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config); - /* Need to take the phy out of low power mode in order to write to access its registers */ bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); /* Reset the phy */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_write(bp, &phy[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -6472,15 +7159,28 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) /* Add delay of 150ms after reset */ msleep(150); + if (phy[PORT_0].addr & 0x1) { + phy_blk[PORT_0] = &(phy[PORT_1]); + phy_blk[PORT_1] = &(phy[PORT_0]); + } else { + phy_blk[PORT_0] = &(phy[PORT_0]); + phy_blk[PORT_1] = &(phy[PORT_1]); + } + /* PART2 - Download firmware to both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u16 fw_ver1; + if (CHIP_IS_E2(bp)) + port_of_path = 0; + else + port_of_path = port; - bnx2x_bcm8073_external_rom_boot(bp, port, - ext_phy_addr[port], shmem_base); + DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", + phy_blk[port]->addr); + bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], + port_of_path); - bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); if (fw_ver1 == 0 || fw_ver1 == 0x4321) { @@ -6492,16 +7192,12 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) } /* Only set bit 10 = 1 (Tx power down) */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, &val); /* Phase1 of TX_POWER_DOWN reset */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_write(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10)); @@ -6515,28 +7211,20 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) for (port = PORT_MAX - 1; port >= PORT_0; port--) { /* Phase2 of POWER_DOWN_RESET */ /* Release bit 10 (Release Tx power down) */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, &val); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_write(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10)))); msleep(15); /* Read modify write the SPI-ROM version select register */ - bnx2x_cl45_read(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, &val); - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, - ext_phy_addr[port], + bnx2x_cl45_write(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12))); @@ -6545,46 +7233,111 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base) MISC_REGISTERS_GPIO_OUTPUT_LOW, port); } return 0; - } +static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, + u32 shmem_base_path[], + u32 shmem2_base_path[], u8 phy_index, + u32 chip_id) +{ + u32 val; + s8 port; + struct bnx2x_phy phy; + /* Use port1 because of the static port-swap */ + /* Enable the module detection interrupt */ + val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); + val |= ((1<= PORT_0; port--) { + u32 shmem_base, shmem2_base; + + /* In E2, same phy is using for port0 of the two paths */ + if (CHIP_IS_E2(bp)) { + shmem_base = shmem_base_path[port]; + shmem2_base = shmem2_base_path[port]; + port_of_path = 0; + } else { + shmem_base = shmem_base_path[0]; + shmem2_base = shmem2_base_path[0]; + port_of_path = port; + } + /* Extract the ext phy address for the port */ + if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base, + port_of_path, &phy[port]) != + 0) { + DP(NETIF_MSG_LINK, "populate phy failed\n"); + return -EINVAL; + } /* disable attentions */ - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, - (NIG_MASK_XGXS0_LINK_STATUS | - NIG_MASK_XGXS0_LINK10G | - NIG_MASK_SERDES0_LINK_STATUS | - NIG_MASK_MI_INT)); + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + + port_of_path*4, + (NIG_MASK_XGXS0_LINK_STATUS | + NIG_MASK_XGXS0_LINK10G | + NIG_MASK_SERDES0_LINK_STATUS | + NIG_MASK_MI_INT)); - ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config); /* Reset the phy */ - bnx2x_cl45_write(bp, port, - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr[port], + bnx2x_cl45_write(bp, &phy[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); @@ -6592,16 +7345,25 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) /* Add delay of 150ms after reset */ msleep(150); - + if (phy[PORT_0].addr & 0x1) { + phy_blk[PORT_0] = &(phy[PORT_1]); + phy_blk[PORT_1] = &(phy[PORT_0]); + } else { + phy_blk[PORT_0] = &(phy[PORT_0]); + phy_blk[PORT_1] = &(phy[PORT_1]); + } /* PART2 - Download firmware to both phys */ - for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) { + for (port = PORT_MAX - 1; port >= PORT_0; port--) { u16 fw_ver1; - - bnx2x_bcm8727_external_rom_boot(bp, port, - ext_phy_addr[port], shmem_base); - - bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, - ext_phy_addr[port], + if (CHIP_IS_E2(bp)) + port_of_path = 0; + else + port_of_path = port; + DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n", + phy_blk[port]->addr); + bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port], + port_of_path); + bnx2x_cl45_read(bp, phy_blk[port], MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &fw_ver1); if (fw_ver1 == 0 || fw_ver1 == 0x4321) { @@ -6616,82 +7378,35 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) return 0; } - -static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) -{ - u8 ext_phy_addr; - u32 val; - s8 port; - - /* Use port1 because of the static port-swap */ - /* Enable the module detection interrupt */ - val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); - val |= ((1<phy[phy_index].hw_reset) { + params->phy[phy_index].hw_reset( + ¶ms->phy[phy_index], + params); + params->phy[phy_index] = phy_null; + } } } diff --git a/drivers/net/bnx2x/bnx2x_link.h b/drivers/net/bnx2x/bnx2x_link.h index 40c2981de8edde699fbc0211da844ee046b12ed1..58a4c719927633a0a525546238b271c8eaf08a85 100644 --- a/drivers/net/bnx2x/bnx2x_link.h +++ b/drivers/net/bnx2x/bnx2x_link.h @@ -1,4 +1,4 @@ -/* Copyright 2008-2009 Broadcom Corporation +/* Copyright 2008-2010 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you @@ -22,7 +22,8 @@ /***********************************************************/ /* Defines */ /***********************************************************/ -#define DEFAULT_PHY_DEV_ADDR 3 +#define DEFAULT_PHY_DEV_ADDR 3 +#define E2_DEFAULT_PHY_DEV_ADDR 5 @@ -46,9 +47,137 @@ #define SFP_EEPROM_PART_NO_ADDR 0x28 #define SFP_EEPROM_PART_NO_SIZE 16 #define PWR_FLT_ERR_MSG_LEN 250 + +#define XGXS_EXT_PHY_TYPE(ext_phy_config) \ + ((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK) +#define XGXS_EXT_PHY_ADDR(ext_phy_config) \ + (((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \ + PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT) +#define SERDES_EXT_PHY_TYPE(ext_phy_config) \ + ((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) + +/* Single Media Direct board is the plain 577xx board with CX4/RJ45 jacks */ +#define SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1) +/* Single Media board contains single external phy */ +#define SINGLE_MEDIA(params) (params->num_phys == 2) +/* Dual Media board contains two external phy with different media */ +#define DUAL_MEDIA(params) (params->num_phys == 3) +#define FW_PARAM_MDIO_CTRL_OFFSET 16 +#define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \ + (phy_addr | phy_type | mdio_access << FW_PARAM_MDIO_CTRL_OFFSET) /***********************************************************/ /* Structs */ /***********************************************************/ +#define INT_PHY 0 +#define EXT_PHY1 1 +#define EXT_PHY2 2 +#define MAX_PHYS 3 + +/* Same configuration is shared between the XGXS and the first external phy */ +#define LINK_CONFIG_SIZE (MAX_PHYS - 1) +#define LINK_CONFIG_IDX(_phy_idx) ((_phy_idx == INT_PHY) ? \ + 0 : (_phy_idx - 1)) +/***********************************************************/ +/* bnx2x_phy struct */ +/* Defines the required arguments and function per phy */ +/***********************************************************/ +struct link_vars; +struct link_params; +struct bnx2x_phy; + +typedef u8 (*config_init_t)(struct bnx2x_phy *phy, struct link_params *params, + struct link_vars *vars); +typedef u8 (*read_status_t)(struct bnx2x_phy *phy, struct link_params *params, + struct link_vars *vars); +typedef void (*link_reset_t)(struct bnx2x_phy *phy, + struct link_params *params); +typedef void (*config_loopback_t)(struct bnx2x_phy *phy, + struct link_params *params); +typedef u8 (*format_fw_ver_t)(u32 raw, u8 *str, u16 *len); +typedef void (*hw_reset_t)(struct bnx2x_phy *phy, struct link_params *params); +typedef void (*set_link_led_t)(struct bnx2x_phy *phy, + struct link_params *params, u8 mode); +typedef void (*phy_specific_func_t)(struct bnx2x_phy *phy, + struct link_params *params, u32 action); + +struct bnx2x_phy { + u32 type; + + /* Loaded during init */ + u8 addr; + + u8 flags; + /* Require HW lock */ +#define FLAGS_HW_LOCK_REQUIRED (1<<0) + /* No Over-Current detection */ +#define FLAGS_NOC (1<<1) + /* Fan failure detection required */ +#define FLAGS_FAN_FAILURE_DET_REQ (1<<2) + /* Initialize first the XGXS and only then the phy itself */ +#define FLAGS_INIT_XGXS_FIRST (1<<3) +#define FLAGS_REARM_LATCH_SIGNAL (1<<6) +#define FLAGS_SFP_NOT_APPROVED (1<<7) + + u8 def_md_devad; + u8 reserved; + /* preemphasis values for the rx side */ + u16 rx_preemphasis[4]; + + /* preemphasis values for the tx side */ + u16 tx_preemphasis[4]; + + /* EMAC address for access MDIO */ + u32 mdio_ctrl; + + u32 supported; + + u32 media_type; +#define ETH_PHY_UNSPECIFIED 0x0 +#define ETH_PHY_SFP_FIBER 0x1 +#define ETH_PHY_XFP_FIBER 0x2 +#define ETH_PHY_DA_TWINAX 0x3 +#define ETH_PHY_BASE_T 0x4 +#define ETH_PHY_NOT_PRESENT 0xff + + /* The address in which version is located*/ + u32 ver_addr; + + u16 req_flow_ctrl; + + u16 req_line_speed; + + u32 speed_cap_mask; + + u16 req_duplex; + u16 rsrv; + /* Called per phy/port init, and it configures LASI, speed, autoneg, + duplex, flow control negotiation, etc. */ + config_init_t config_init; + + /* Called due to interrupt. It determines the link, speed */ + read_status_t read_status; + + /* Called when driver is unloading. Should reset the phy */ + link_reset_t link_reset; + + /* Set the loopback configuration for the phy */ + config_loopback_t config_loopback; + + /* Format the given raw number into str up to len */ + format_fw_ver_t format_fw_ver; + + /* Reset the phy (both ports) */ + hw_reset_t hw_reset; + + /* Set link led mode (on/off/oper)*/ + set_link_led_t set_link_led; + + /* PHY Specific tasks */ + phy_specific_func_t phy_specific_func; +#define DISABLE_TX 1 +#define ENABLE_TX 2 +}; + /* Inputs parameters to the CLC */ struct link_params { @@ -59,56 +188,50 @@ struct link_params { #define LOOPBACK_NONE 0 #define LOOPBACK_EMAC 1 #define LOOPBACK_BMAC 2 -#define LOOPBACK_XGXS_10 3 +#define LOOPBACK_XGXS 3 #define LOOPBACK_EXT_PHY 4 #define LOOPBACK_EXT 5 - u16 req_duplex; - u16 req_flow_ctrl; - u16 req_fc_auto_adv; /* Should be set to TX / BOTH when - req_flow_ctrl is set to AUTO */ - u16 req_line_speed; /* Also determine AutoNeg */ - /* Device parameters */ u8 mac_addr[6]; + u16 req_duplex[LINK_CONFIG_SIZE]; + u16 req_flow_ctrl[LINK_CONFIG_SIZE]; + + u16 req_line_speed[LINK_CONFIG_SIZE]; /* Also determine AutoNeg */ + /* shmem parameters */ u32 shmem_base; - u32 speed_cap_mask; + u32 shmem2_base; + u32 speed_cap_mask[LINK_CONFIG_SIZE]; u32 switch_cfg; #define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH #define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH #define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT - u16 hw_led_mode; /* part of the hw_config read from the shmem */ - - /* phy_addr populated by the phy_init function */ - u8 phy_addr; - /*u8 reserved1;*/ - u32 lane_config; - u32 ext_phy_config; -#define XGXS_EXT_PHY_TYPE(ext_phy_config) \ - ((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK) -#define XGXS_EXT_PHY_ADDR(ext_phy_config) \ - (((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \ - PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT) -#define SERDES_EXT_PHY_TYPE(ext_phy_config) \ - ((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) /* Phy register parameter */ u32 chip_id; - u16 xgxs_config_rx[4]; /* preemphasis values for the rx side */ - u16 xgxs_config_tx[4]; /* preemphasis values for the tx side */ - u32 feature_config_flags; #define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0) #define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2) -#define FEATURE_CONFIG_BCM8727_NOC (1<<3) +#define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3) + /* Will be populated during common init */ + struct bnx2x_phy phy[MAX_PHYS]; + + /* Will be populated during common init */ + u8 num_phys; + + u8 rsrv; + u16 hw_led_mode; /* part of the hw_config read from the shmem */ + u32 multi_phy_config; /* Device pointer passed to all callback functions */ struct bnx2x *bp; + u16 req_fc_auto_adv; /* Should be set to TX / BOTH when + req_flow_ctrl is set to AUTO */ }; /* Output parameters */ @@ -129,12 +252,6 @@ struct link_vars { u16 flow_ctrl; u16 ieee_fc; - u32 autoneg; -#define AUTO_NEG_DISABLED 0x0 -#define AUTO_NEG_ENABLED 0x1 -#define AUTO_NEG_COMPLETE 0x2 -#define AUTO_NEG_PARALLEL_DETECTION_USED 0x3 - /* The same definitions as the shmem parameter */ u32 link_status; }; @@ -142,8 +259,6 @@ struct link_vars { /***********************************************************/ /* Functions */ /***********************************************************/ - -/* Initialize the phy */ u8 bnx2x_phy_init(struct link_params *input, struct link_vars *output); /* Reset the link. Should be called when driver or interface goes down @@ -155,17 +270,21 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, /* bnx2x_link_update should be called upon link interrupt */ u8 bnx2x_link_update(struct link_params *input, struct link_vars *output); -/* use the following cl45 functions to read/write from external_phy +/* use the following phy functions to read/write from external_phy In order to use it to read/write internal phy registers, use DEFAULT_PHY_DEV_ADDR as devad, and (_bank + (_addr & 0xf)) as - Use ext_phy_type of 0 in case of cl22 over cl45 the register */ -u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, - u8 phy_addr, u8 devad, u16 reg, u16 *ret_val); +u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 *ret_val); + +u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr, + u8 devad, u16 reg, u16 val); -u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, - u8 phy_addr, u8 devad, u16 reg, u16 val); +u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 *ret_val); +u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, + u8 devad, u16 reg, u16 val); /* Reads the link_status from the shmem, and update the link vars accordingly */ void bnx2x_link_status_update(struct link_params *input, @@ -178,9 +297,12 @@ u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, Basically, the CLC takes care of the led for the link, but in case one needs to set/unset the led unnaturally, set the "mode" to LED_MODE_OPER to blink the led, and LED_MODE_OFF to set the led off.*/ -u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed); -#define LED_MODE_OFF 0 -#define LED_MODE_OPER 2 +u8 bnx2x_set_led(struct link_params *params, struct link_vars *vars, + u8 mode, u32 speed); +#define LED_MODE_OFF 0 +#define LED_MODE_ON 1 +#define LED_MODE_OPER 2 +#define LED_MODE_FRONT_PANEL_OFF 3 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port, u32 led_idx, u32 value); @@ -190,17 +312,39 @@ void bnx2x_handle_module_detect_int(struct link_params *params); /* Get the actual link status. In case it returns 0, link is up, otherwise link is down*/ -u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars); +u8 bnx2x_test_link(struct link_params *input, struct link_vars *vars, + u8 is_serdes); /* One-time initialization for external phy after power up */ -u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base); +u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], + u32 shmem2_base_path[], u32 chip_id); /* Reset the external PHY using GPIO */ void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port); -void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr); +/* Reset the external of SFX7101 */ +void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy); -u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, +u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy, + struct link_params *params, u16 addr, u8 byte_cnt, u8 *o_buf); +void bnx2x_hw_reset_phy(struct link_params *params); + +/* Checks if HW lock is required for this phy/board type */ +u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base); + +/* Returns the aggregative supported attributes of the phys on board */ +u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx); + +/* Check swap bit and adjust PHY order */ +u32 bnx2x_phy_selection(struct link_params *params); + +/* Probe the phys on board, and populate them in "params" */ +u8 bnx2x_phy_probe(struct link_params *params); +/* Checks if fan failure detection is required on one of the phys on board */ +u8 bnx2x_fan_failure_det_req(struct bnx2x *bp, u32 shmem_base, + u32 shmem2_base, u8 port); + #endif /* BNX2X_LINK_H */ diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index f8c3f08e4ce73fb4d5d37739fa7dd18cfc557da7..ff99a2fc04267b6aef6d926cbc5483d12fbb2635 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -57,7 +56,6 @@ #include "bnx2x_init_ops.h" #include "bnx2x_cmn.h" - #include #include "bnx2x_fw_file_hdr.h" /* FW files */ @@ -66,8 +64,9 @@ __stringify(BCM_5710_FW_MINOR_VERSION) "." \ __stringify(BCM_5710_FW_REVISION_VERSION) "." \ __stringify(BCM_5710_FW_ENGINEERING_VERSION) -#define FW_FILE_NAME_E1 "bnx2x-e1-" FW_FILE_VERSION ".fw" -#define FW_FILE_NAME_E1H "bnx2x-e1h-" FW_FILE_VERSION ".fw" +#define FW_FILE_NAME_E1 "bnx2x/bnx2x-e1-" FW_FILE_VERSION ".fw" +#define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" +#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw" /* Time in jiffies before concluding the transmitter is hung */ #define TX_TIMEOUT (5*HZ) @@ -77,18 +76,20 @@ static char version[] __devinitdata = DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("Eliezer Tamir"); -MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710/57711/57711E Driver"); +MODULE_DESCRIPTION("Broadcom NetXtreme II " + "BCM57710/57711/57711E/57712/57712E Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); MODULE_FIRMWARE(FW_FILE_NAME_E1); MODULE_FIRMWARE(FW_FILE_NAME_E1H); +MODULE_FIRMWARE(FW_FILE_NAME_E2); static int multi_mode = 1; module_param(multi_mode, int, 0); MODULE_PARM_DESC(multi_mode, " Multi queue mode " "(0 Disable; 1 Enable (default))"); -static int num_queues; +int num_queues; module_param(num_queues, int, 0); MODULE_PARM_DESC(num_queues, " Number of queues for multi_mode=1" " (default is as a number of CPUs)"); @@ -124,6 +125,8 @@ enum bnx2x_board_type { BCM57710 = 0, BCM57711 = 1, BCM57711E = 2, + BCM57712 = 3, + BCM57712E = 4 }; /* indexed by board_type, above */ @@ -132,14 +135,24 @@ static struct { } board_info[] __devinitdata = { { "Broadcom NetXtreme II BCM57710 XGb" }, { "Broadcom NetXtreme II BCM57711 XGb" }, - { "Broadcom NetXtreme II BCM57711E XGb" } + { "Broadcom NetXtreme II BCM57711E XGb" }, + { "Broadcom NetXtreme II BCM57712 XGb" }, + { "Broadcom NetXtreme II BCM57712E XGb" } }; +#ifndef PCI_DEVICE_ID_NX2_57712 +#define PCI_DEVICE_ID_NX2_57712 0x1662 +#endif +#ifndef PCI_DEVICE_ID_NX2_57712E +#define PCI_DEVICE_ID_NX2_57712E 0x1663 +#endif static DEFINE_PCI_DEVICE_TABLE(bnx2x_pci_tbl) = { { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57710), BCM57710 }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711), BCM57711 }, { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57711E), BCM57711E }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712), BCM57712 }, + { PCI_VDEVICE(BROADCOM, PCI_DEVICE_ID_NX2_57712E), BCM57712E }, { 0 } }; @@ -149,6 +162,244 @@ MODULE_DEVICE_TABLE(pci, bnx2x_pci_tbl); * General service functions ****************************************************************************/ +static inline void __storm_memset_dma_mapping(struct bnx2x *bp, + u32 addr, dma_addr_t mapping) +{ + REG_WR(bp, addr, U64_LO(mapping)); + REG_WR(bp, addr + 4, U64_HI(mapping)); +} + +static inline void __storm_memset_fill(struct bnx2x *bp, + u32 addr, size_t size, u32 val) +{ + int i; + for (i = 0; i < size/4; i++) + REG_WR(bp, addr + (i * 4), val); +} + +static inline void storm_memset_ustats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct ustorm_per_client_stats); + + u32 addr = BAR_USTRORM_INTMEM + + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + +static inline void storm_memset_tstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct tstorm_per_client_stats); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + +static inline void storm_memset_xstats_zero(struct bnx2x *bp, + u8 port, u16 stat_id) +{ + size_t size = sizeof(struct xstorm_per_client_stats); + + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, stat_id); + + __storm_memset_fill(bp, addr, size, 0); +} + + +static inline void storm_memset_spq_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_ov(struct bnx2x *bp, u16 ov, u16 abs_fid) +{ + REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(abs_fid), ov); +} + +static inline void storm_memset_func_cfg(struct bnx2x *bp, + struct tstorm_eth_function_common_config *tcfg, + u16 abs_fid) +{ + size_t size = sizeof(struct tstorm_eth_function_common_config); + + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)tcfg); +} + +static inline void storm_memset_xstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_tstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_ustats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_cstats_flags(struct bnx2x *bp, + struct stats_indication_flags *flags, + u16 abs_fid) +{ + size_t size = sizeof(struct stats_indication_flags); + + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(abs_fid); + + __storm_memset_struct(bp, addr, size, (u32 *)flags); +} + +static inline void storm_memset_xstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_XSTRORM_INTMEM + + XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_tstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_TSTRORM_INTMEM + + TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_ustats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_USTRORM_INTMEM + + USTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_cstats_addr(struct bnx2x *bp, + dma_addr_t mapping, u16 abs_fid) +{ + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_ETH_STATS_QUERY_ADDR_OFFSET(abs_fid); + + __storm_memset_dma_mapping(bp, addr, mapping); +} + +static inline void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, + u16 pf_id) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid), + pf_id); +} + +static inline void storm_memset_func_en(struct bnx2x *bp, u16 abs_fid, + u8 enable) +{ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid), + enable); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid), + enable); +} + +static inline void storm_memset_eq_data(struct bnx2x *bp, + struct event_ring_data *eq_data, + u16 pfid) +{ + size_t size = sizeof(struct event_ring_data); + + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_DATA_OFFSET(pfid); + + __storm_memset_struct(bp, addr, size, (u32 *)eq_data); +} + +static inline void storm_memset_eq_prod(struct bnx2x *bp, u16 eq_prod, + u16 pfid) +{ + u32 addr = BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_PROD_OFFSET(pfid); + REG_WR16(bp, addr, eq_prod); +} + +static inline void storm_memset_hc_timeout(struct bnx2x *bp, u8 port, + u16 fw_sb_id, u8 sb_index, + u8 ticks) +{ + + int index_offset = CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, index_data) : + offsetof(struct hc_status_block_data_e1x, index_data); + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + index_offset + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, timeout); + REG_WR8(bp, addr, ticks); + DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d ticks %d\n", + port, fw_sb_id, sb_index, ticks); +} +static inline void storm_memset_hc_disable(struct bnx2x *bp, u8 port, + u16 fw_sb_id, u8 sb_index, + u8 disable) +{ + u32 enable_flag = disable ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT); + int index_offset = CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, index_data) : + offsetof(struct hc_status_block_data_e1x, index_data); + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + index_offset + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, flags); + u16 flags = REG_RD16(bp, addr); + /* clear and set */ + flags &= ~HC_INDEX_DATA_HC_ENABLED; + flags |= enable_flag; + REG_WR16(bp, addr, flags); + DP(NETIF_MSG_HW, "port %x fw_sb_id %d sb_index %d disable %d\n", + port, fw_sb_id, sb_index, disable); +} + /* used only at init * locking is done by mcp */ @@ -172,6 +423,75 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr) return val; } +#define DMAE_DP_SRC_GRC "grc src_addr [%08x]" +#define DMAE_DP_SRC_PCI "pci src_addr [%x:%08x]" +#define DMAE_DP_DST_GRC "grc dst_addr [%08x]" +#define DMAE_DP_DST_PCI "pci dst_addr [%x:%08x]" +#define DMAE_DP_DST_NONE "dst_addr [none]" + +void bnx2x_dp_dmae(struct bnx2x *bp, struct dmae_command *dmae, int msglvl) +{ + u32 src_type = dmae->opcode & DMAE_COMMAND_SRC; + + switch (dmae->opcode & DMAE_COMMAND_DST) { + case DMAE_CMD_DST_PCI: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%x:%08x], len [%d*4], dst [%x:%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%08x], len [%d*4], dst [%x:%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + case DMAE_CMD_DST_GRC: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%x:%08x], len [%d*4], dst_addr [%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->dst_addr_lo >> 2, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + "src [%08x], len [%d*4], dst [%08x]\n" + "comp_addr [%x:%08x], comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->dst_addr_lo >> 2, + dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + default: + if (src_type == DMAE_CMD_SRC_PCI) + DP(msglvl, "DMAE: opcode 0x%08x\n" + DP_LEVEL "src_addr [%x:%08x] len [%d * 4] " + "dst_addr [none]\n" + DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, + dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + else + DP(msglvl, "DMAE: opcode 0x%08x\n" + DP_LEVEL "src_addr [%08x] len [%d * 4] " + "dst_addr [none]\n" + DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", + dmae->opcode, dmae->src_addr_lo >> 2, + dmae->len, dmae->comp_addr_hi, dmae->comp_addr_lo, + dmae->comp_val); + break; + } + +} + const u32 dmae_reg_go_c[] = { DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, DMAE_REG_GO_C4, DMAE_REG_GO_C5, DMAE_REG_GO_C6, DMAE_REG_GO_C7, @@ -195,85 +515,137 @@ void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae, int idx) REG_WR(bp, dmae_reg_go_c[idx], 1); } -void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, - u32 len32) +u32 bnx2x_dmae_opcode_add_comp(u32 opcode, u8 comp_type) { - struct dmae_command dmae; - u32 *wb_comp = bnx2x_sp(bp, wb_comp); - int cnt = 200; + return opcode | ((comp_type << DMAE_COMMAND_C_DST_SHIFT) | + DMAE_CMD_C_ENABLE); +} - if (!bp->dmae_ready) { - u32 *data = bnx2x_sp(bp, wb_data[0]); +u32 bnx2x_dmae_opcode_clr_src_reset(u32 opcode) +{ + return opcode & ~DMAE_CMD_SRC_RESET; +} - DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" - " using indirect\n", dst_addr, len32); - bnx2x_init_ind_wr(bp, dst_addr, data, len32); - return; - } +u32 bnx2x_dmae_opcode(struct bnx2x *bp, u8 src_type, u8 dst_type, + bool with_comp, u8 comp_type) +{ + u32 opcode = 0; + + opcode |= ((src_type << DMAE_COMMAND_SRC_SHIFT) | + (dst_type << DMAE_COMMAND_DST_SHIFT)); + + opcode |= (DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET); - memset(&dmae, 0, sizeof(struct dmae_command)); + opcode |= (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0); + opcode |= ((BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT) | + (BP_E1HVN(bp) << DMAE_COMMAND_DST_VN_SHIFT)); + opcode |= (DMAE_COM_SET_ERR << DMAE_COMMAND_ERR_POLICY_SHIFT); - dmae.opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | #ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | + opcode |= DMAE_CMD_ENDIANITY_B_DW_SWAP; #else - DMAE_CMD_ENDIANITY_DW_SWAP | + opcode |= DMAE_CMD_ENDIANITY_DW_SWAP; #endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); - dmae.src_addr_lo = U64_LO(dma_addr); - dmae.src_addr_hi = U64_HI(dma_addr); - dmae.dst_addr_lo = dst_addr >> 2; - dmae.dst_addr_hi = 0; - dmae.len = len32; - dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_val = DMAE_COMP_VAL; - - DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n" - DP_LEVEL "src_addr [%x:%08x] len [%d *4] " - "dst_addr [%x:%08x (%08x)]\n" - DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", - dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo, - dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, dst_addr, - dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val); - DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n", + if (with_comp) + opcode = bnx2x_dmae_opcode_add_comp(opcode, comp_type); + return opcode; +} + +void bnx2x_prep_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae, + u8 src_type, u8 dst_type) +{ + memset(dmae, 0, sizeof(struct dmae_command)); + + /* set the opcode */ + dmae->opcode = bnx2x_dmae_opcode(bp, src_type, dst_type, + true, DMAE_COMP_PCI); + + /* fill in the completion parameters */ + dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); + dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); + dmae->comp_val = DMAE_COMP_VAL; +} + +/* issue a dmae command over the init-channel and wailt for completion */ +int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, struct dmae_command *dmae) +{ + u32 *wb_comp = bnx2x_sp(bp, wb_comp); + int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 40; + int rc = 0; + + DP(BNX2X_MSG_OFF, "data before [0x%08x 0x%08x 0x%08x 0x%08x]\n", bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); + /* lock the dmae channel */ mutex_lock(&bp->dmae_mutex); + /* reset completion */ *wb_comp = 0; - bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp)); + /* post the command on the channel used for initializations */ + bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); + /* wait for completion */ udelay(5); - - while (*wb_comp != DMAE_COMP_VAL) { + while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) { DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp); if (!cnt) { BNX2X_ERR("DMAE timeout!\n"); - break; + rc = DMAE_TIMEOUT; + goto unlock; } cnt--; - /* adjust delay for emulation/FPGA */ - if (CHIP_REV_IS_SLOW(bp)) - msleep(100); - else - udelay(5); + udelay(50); + } + if (*wb_comp & DMAE_PCI_ERR_FLAG) { + BNX2X_ERR("DMAE PCI error!\n"); + rc = DMAE_PCI_ERROR; } + DP(BNX2X_MSG_OFF, "data after [0x%08x 0x%08x 0x%08x 0x%08x]\n", + bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], + bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); + +unlock: mutex_unlock(&bp->dmae_mutex); + return rc; +} + +void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, + u32 len32) +{ + struct dmae_command dmae; + + if (!bp->dmae_ready) { + u32 *data = bnx2x_sp(bp, wb_data[0]); + + DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" + " using indirect\n", dst_addr, len32); + bnx2x_init_ind_wr(bp, dst_addr, data, len32); + return; + } + + /* set opcode and fixed command fields */ + bnx2x_prep_dmae_with_comp(bp, &dmae, DMAE_SRC_PCI, DMAE_DST_GRC); + + /* fill in addresses and len */ + dmae.src_addr_lo = U64_LO(dma_addr); + dmae.src_addr_hi = U64_HI(dma_addr); + dmae.dst_addr_lo = dst_addr >> 2; + dmae.dst_addr_hi = 0; + dmae.len = len32; + + bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF); + + /* issue the command and wait for completion */ + bnx2x_issue_dmae_with_comp(bp, &dmae); } void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) { struct dmae_command dmae; - u32 *wb_comp = bnx2x_sp(bp, wb_comp); - int cnt = 200; if (!bp->dmae_ready) { u32 *data = bnx2x_sp(bp, wb_data[0]); @@ -286,62 +658,20 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) return; } - memset(&dmae, 0, sizeof(struct dmae_command)); + /* set opcode and fixed command fields */ + bnx2x_prep_dmae_with_comp(bp, &dmae, DMAE_SRC_GRC, DMAE_DST_PCI); - dmae.opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + /* fill in addresses and len */ dmae.src_addr_lo = src_addr >> 2; dmae.src_addr_hi = 0; dmae.dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data)); dmae.dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_data)); dmae.len = len32; - dmae.comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); - dmae.comp_val = DMAE_COMP_VAL; - - DP(BNX2X_MSG_OFF, "DMAE: opcode 0x%08x\n" - DP_LEVEL "src_addr [%x:%08x] len [%d *4] " - "dst_addr [%x:%08x (%08x)]\n" - DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", - dmae.opcode, dmae.src_addr_hi, dmae.src_addr_lo, - dmae.len, dmae.dst_addr_hi, dmae.dst_addr_lo, src_addr, - dmae.comp_addr_hi, dmae.comp_addr_lo, dmae.comp_val); - - mutex_lock(&bp->dmae_mutex); - - memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4); - *wb_comp = 0; - - bnx2x_post_dmae(bp, &dmae, INIT_DMAE_C(bp)); - - udelay(5); - - while (*wb_comp != DMAE_COMP_VAL) { - if (!cnt) { - BNX2X_ERR("DMAE timeout!\n"); - break; - } - cnt--; - /* adjust delay for emulation/FPGA */ - if (CHIP_REV_IS_SLOW(bp)) - msleep(100); - else - udelay(5); - } - DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n", - bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], - bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); + bnx2x_dp_dmae(bp, &dmae, BNX2X_MSG_OFF); - mutex_unlock(&bp->dmae_mutex); + /* issue the command and wait for completion */ + bnx2x_issue_dmae_with_comp(bp, &dmae); } void bnx2x_write_dmae_phys_len(struct bnx2x *bp, dma_addr_t phys_addr, @@ -508,19 +838,24 @@ static void bnx2x_fw_dump(struct bnx2x *bp) u32 mark, offset; __be32 data[9]; int word; - + u32 trace_shmem_base; if (BP_NOMCP(bp)) { BNX2X_ERR("NO MCP - can not dump\n"); return; } - addr = bp->common.shmem_base - 0x0800 + 4; + if (BP_PATH(bp) == 0) + trace_shmem_base = bp->common.shmem_base; + else + trace_shmem_base = SHMEM2_RD(bp, other_shmem_base_addr); + addr = trace_shmem_base - 0x0800 + 4; mark = REG_RD(bp, addr); - mark = MCP_REG_MCPR_SCRATCH + ((mark + 0x3) & ~0x3) - 0x08000000; + mark = (CHIP_IS_E1x(bp) ? MCP_REG_MCPR_SCRATCH : MCP_A_REG_MCPR_SCRATCH) + + ((mark + 0x3) & ~0x3) - 0x08000000; pr_err("begin fw dump (mark 0x%x)\n", mark); pr_err(""); - for (offset = mark; offset <= bp->common.shmem_base; offset += 0x8*4) { + for (offset = mark; offset <= trace_shmem_base; offset += 0x8*4) { for (word = 0; word < 8; word++) data[word] = htonl(REG_RD(bp, offset + 4*word)); data[8] = 0x0; @@ -538,7 +873,12 @@ static void bnx2x_fw_dump(struct bnx2x *bp) void bnx2x_panic_dump(struct bnx2x *bp) { int i; - u16 j, start, end; + u16 j; + struct hc_sp_status_block_data sp_sb_data; + int func = BP_FUNC(bp); +#ifdef BNX2X_STOP_ON_ERROR + u16 start = 0, end = 0; +#endif bp->stats_state = STATS_STATE_DISABLED; DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); @@ -547,44 +887,143 @@ void bnx2x_panic_dump(struct bnx2x *bp) /* Indices */ /* Common */ - BNX2X_ERR("def_c_idx(0x%x) def_u_idx(0x%x) def_x_idx(0x%x)" - " def_t_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)" + BNX2X_ERR("def_idx(0x%x) def_att_idx(0x%x) attn_state(0x%x)" " spq_prod_idx(0x%x)\n", - bp->def_c_idx, bp->def_u_idx, bp->def_x_idx, bp->def_t_idx, - bp->def_att_idx, bp->attn_state, bp->spq_prod_idx); + bp->def_idx, bp->def_att_idx, + bp->attn_state, bp->spq_prod_idx); + BNX2X_ERR("DSB: attn bits(0x%x) ack(0x%x) id(0x%x) idx(0x%x)\n", + bp->def_status_blk->atten_status_block.attn_bits, + bp->def_status_blk->atten_status_block.attn_bits_ack, + bp->def_status_blk->atten_status_block.status_block_id, + bp->def_status_blk->atten_status_block.attn_bits_index); + BNX2X_ERR(" def ("); + for (i = 0; i < HC_SP_SB_MAX_INDICES; i++) + pr_cont("0x%x%s", + bp->def_status_blk->sp_sb.index_values[i], + (i == HC_SP_SB_MAX_INDICES - 1) ? ") " : " "); + + for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++) + *((u32 *)&sp_sb_data + i) = REG_RD(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + i*sizeof(u32)); + + 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)\n", + sp_sb_data.igu_sb_id, + sp_sb_data.igu_seg_id, + sp_sb_data.p_func.pf_id, + sp_sb_data.p_func.vnic_id, + sp_sb_data.p_func.vf_id, + sp_sb_data.p_func.vf_valid); + - /* Rx */ for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - + int loop; + struct hc_status_block_data_e2 sb_data_e2; + struct hc_status_block_data_e1x sb_data_e1x; + struct hc_status_block_sm *hc_sm_p = + CHIP_IS_E2(bp) ? + sb_data_e2.common.state_machine : + sb_data_e1x.common.state_machine; + struct hc_index_data *hc_index_p = + CHIP_IS_E2(bp) ? + sb_data_e2.index_data : + sb_data_e1x.index_data; + int data_size; + u32 *sb_data_p; + + /* Rx */ BNX2X_ERR("fp%d: rx_bd_prod(0x%x) rx_bd_cons(0x%x)" - " *rx_bd_cons_sb(0x%x) rx_comp_prod(0x%x)" + " rx_comp_prod(0x%x)" " rx_comp_cons(0x%x) *rx_cons_sb(0x%x)\n", i, fp->rx_bd_prod, fp->rx_bd_cons, - le16_to_cpu(*fp->rx_bd_cons_sb), fp->rx_comp_prod, + fp->rx_comp_prod, fp->rx_comp_cons, le16_to_cpu(*fp->rx_cons_sb)); BNX2X_ERR(" rx_sge_prod(0x%x) last_max_sge(0x%x)" - " fp_u_idx(0x%x) *sb_u_idx(0x%x)\n", + " fp_hc_idx(0x%x)\n", fp->rx_sge_prod, fp->last_max_sge, - le16_to_cpu(fp->fp_u_idx), - fp->status_blk->u_status_block.status_block_index); - } - - /* Tx */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; + le16_to_cpu(fp->fp_hc_idx)); + /* Tx */ BNX2X_ERR("fp%d: tx_pkt_prod(0x%x) tx_pkt_cons(0x%x)" " tx_bd_prod(0x%x) tx_bd_cons(0x%x)" " *tx_cons_sb(0x%x)\n", i, fp->tx_pkt_prod, fp->tx_pkt_cons, fp->tx_bd_prod, fp->tx_bd_cons, le16_to_cpu(*fp->tx_cons_sb)); - BNX2X_ERR(" fp_c_idx(0x%x) *sb_c_idx(0x%x)" - " tx_db_prod(0x%x)\n", le16_to_cpu(fp->fp_c_idx), - fp->status_blk->c_status_block.status_block_index, - fp->tx_db.data.prod); + + loop = CHIP_IS_E2(bp) ? + HC_SB_MAX_INDICES_E2 : HC_SB_MAX_INDICES_E1X; + + /* host sb data */ + + BNX2X_ERR(" run indexes ("); + for (j = 0; j < HC_SB_MAX_SM; j++) + pr_cont("0x%x%s", + fp->sb_running_index[j], + (j == HC_SB_MAX_SM - 1) ? ")" : " "); + + BNX2X_ERR(" indexes ("); + for (j = 0; j < loop; j++) + pr_cont("0x%x%s", + fp->sb_index_values[j], + (j == loop - 1) ? ")" : " "); + /* fw sb data */ + data_size = CHIP_IS_E2(bp) ? + sizeof(struct hc_status_block_data_e2) : + sizeof(struct hc_status_block_data_e1x); + data_size /= sizeof(u32); + sb_data_p = CHIP_IS_E2(bp) ? + (u32 *)&sb_data_e2 : + (u32 *)&sb_data_e1x; + /* copy sb data in here */ + for (j = 0; j < data_size; j++) + *(sb_data_p + j) = REG_RD(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + + j * sizeof(u32)); + + if (CHIP_IS_E2(bp)) { + pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + sb_data_e2.common.p_func.pf_id, + sb_data_e2.common.p_func.vf_id, + sb_data_e2.common.p_func.vf_valid, + sb_data_e2.common.p_func.vnic_id, + sb_data_e2.common.same_igu_sb_1b); + } else { + pr_cont("pf_id(0x%x) vf_id (0x%x) vf_valid(0x%x) " + "vnic_id(0x%x) same_igu_sb_1b(0x%x)\n", + sb_data_e1x.common.p_func.pf_id, + sb_data_e1x.common.p_func.vf_id, + sb_data_e1x.common.p_func.vf_valid, + sb_data_e1x.common.p_func.vnic_id, + sb_data_e1x.common.same_igu_sb_1b); + } + + /* SB_SMs data */ + for (j = 0; j < HC_SB_MAX_SM; j++) { + pr_cont("SM[%d] __flags (0x%x) " + "igu_sb_id (0x%x) igu_seg_id(0x%x) " + "time_to_expire (0x%x) " + "timer_value(0x%x)\n", j, + hc_sm_p[j].__flags, + hc_sm_p[j].igu_sb_id, + hc_sm_p[j].igu_seg_id, + hc_sm_p[j].time_to_expire, + hc_sm_p[j].timer_value); + } + + /* Indecies data */ + for (j = 0; j < loop; j++) { + pr_cont("INDEX[%d] flags (0x%x) " + "timeout (0x%x)\n", j, + hc_index_p[j].flags, + hc_index_p[j].timeout); + } } +#ifdef BNX2X_STOP_ON_ERROR /* Rings */ /* Rx */ for_each_queue(bp, i) { @@ -642,13 +1081,13 @@ void bnx2x_panic_dump(struct bnx2x *bp) i, j, tx_bd[0], tx_bd[1], tx_bd[2], tx_bd[3]); } } - +#endif bnx2x_fw_dump(bp); bnx2x_mc_assert(bp); BNX2X_ERR("end crash dump -----------------\n"); } -void bnx2x_int_enable(struct bnx2x *bp) +static void bnx2x_hc_int_enable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; @@ -672,14 +1111,19 @@ void bnx2x_int_enable(struct bnx2x *bp) HC_CONFIG_0_REG_INT_LINE_EN_0 | HC_CONFIG_0_REG_ATTN_BIT_EN_0); - DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n", - val, port, addr); + if (!CHIP_IS_E1(bp)) { + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n", + val, port, addr); - REG_WR(bp, addr, val); + REG_WR(bp, addr, val); - val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; + val &= ~HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0; + } } + if (CHIP_IS_E1(bp)) + REG_WR(bp, HC_REG_INT_MASK + port*4, 0x1FFFF); + DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x) mode %s\n", val, port, addr, (msix ? "MSI-X" : (msi ? "MSI" : "INTx"))); @@ -690,9 +1134,9 @@ void bnx2x_int_enable(struct bnx2x *bp) mmiowb(); barrier(); - if (CHIP_IS_E1H(bp)) { + if (!CHIP_IS_E1(bp)) { /* init leading/trailing edge */ - if (IS_E1HMF(bp)) { + if (IS_MF(bp)) { val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); if (bp->port.pmf) /* enable nig and gpio3 attention */ @@ -708,16 +1152,91 @@ void bnx2x_int_enable(struct bnx2x *bp) mmiowb(); } -static void bnx2x_int_disable(struct bnx2x *bp) +static void bnx2x_igu_int_enable(struct bnx2x *bp) +{ + u32 val; + int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; + int msi = (bp->flags & USING_MSI_FLAG) ? 1 : 0; + + val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + + if (msix) { + val &= ~(IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_ATTN_BIT_EN); + } else if (msi) { + val &= ~IGU_PF_CONF_INT_LINE_EN; + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_ATTN_BIT_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + } else { + val &= ~IGU_PF_CONF_MSI_MSIX_EN; + val |= (IGU_PF_CONF_FUNC_EN | + IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_ATTN_BIT_EN | + IGU_PF_CONF_SINGLE_ISR_EN); + } + + DP(NETIF_MSG_INTR, "write 0x%x to IGU mode %s\n", + val, (msix ? "MSI-X" : (msi ? "MSI" : "INTx"))); + + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + + barrier(); + + /* init leading/trailing edge */ + if (IS_MF(bp)) { + val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); + if (bp->port.pmf) + /* enable nig and gpio3 attention */ + val |= 0x1100; + } else + val = 0xffff; + + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val); + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val); + + /* Make sure that interrupts are indeed enabled from here on */ + mmiowb(); +} + +void bnx2x_int_enable(struct bnx2x *bp) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_int_enable(bp); + else + bnx2x_igu_int_enable(bp); +} + +static void bnx2x_hc_int_disable(struct bnx2x *bp) { int port = BP_PORT(bp); u32 addr = port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0; u32 val = REG_RD(bp, addr); - val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | - HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 | - HC_CONFIG_0_REG_INT_LINE_EN_0 | - HC_CONFIG_0_REG_ATTN_BIT_EN_0); + /* + * in E1 we must use only PCI configuration space to disable + * MSI/MSIX capablility + * It's forbitten to disable IGU_PF_CONF_MSI_MSIX_EN in HC block + */ + if (CHIP_IS_E1(bp)) { + /* Since IGU_PF_CONF_MSI_MSIX_EN still always on + * Use mask register to prevent from HC sending interrupts + * after we exit the function + */ + REG_WR(bp, HC_REG_INT_MASK + port*4, 0); + + val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | + HC_CONFIG_0_REG_INT_LINE_EN_0 | + HC_CONFIG_0_REG_ATTN_BIT_EN_0); + } else + val &= ~(HC_CONFIG_0_REG_SINGLE_ISR_EN_0 | + HC_CONFIG_0_REG_MSI_MSIX_INT_EN_0 | + HC_CONFIG_0_REG_INT_LINE_EN_0 | + HC_CONFIG_0_REG_ATTN_BIT_EN_0); DP(NETIF_MSG_INTR, "write %x to HC %d (addr 0x%x)\n", val, port, addr); @@ -730,6 +1249,32 @@ static void bnx2x_int_disable(struct bnx2x *bp) BNX2X_ERR("BUG! proper val not read from IGU!\n"); } +static void bnx2x_igu_int_disable(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + + val &= ~(IGU_PF_CONF_MSI_MSIX_EN | + IGU_PF_CONF_INT_LINE_EN | + IGU_PF_CONF_ATTN_BIT_EN); + + DP(NETIF_MSG_INTR, "write %x to IGU\n", val); + + /* flush all outstanding writes */ + mmiowb(); + + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + if (REG_RD(bp, IGU_REG_PF_CONFIGURATION) != val) + BNX2X_ERR("BUG! proper val not read from IGU!\n"); +} + +void bnx2x_int_disable(struct bnx2x *bp) +{ + if (bp->common.int_block == INT_BLOCK_HC) + bnx2x_hc_int_disable(bp); + else + bnx2x_igu_int_disable(bp); +} + void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw) { int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; @@ -781,7 +1326,7 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource) DP(NETIF_MSG_HW, "resource(0x%x) > HW_LOCK_MAX_RESOURCE_VALUE(0x%x)\n", resource, HW_LOCK_MAX_RESOURCE_VALUE); - return -EINVAL; + return false; } if (func <= 5) @@ -800,7 +1345,6 @@ static bool bnx2x_trylock_hw_lock(struct bnx2x *bp, u32 resource) return false; } - #ifdef BCM_CNIC static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid); #endif @@ -817,76 +1361,35 @@ void bnx2x_sp_event(struct bnx2x_fastpath *fp, fp->index, cid, command, bp->state, rr_cqe->ramrod_cqe.ramrod_type); - bp->spq_left++; - - if (fp->index) { - switch (command | fp->state) { - case (RAMROD_CMD_ID_ETH_CLIENT_SETUP | - BNX2X_FP_STATE_OPENING): - DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", - cid); - fp->state = BNX2X_FP_STATE_OPEN; - break; - - case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING): - DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", - cid); - fp->state = BNX2X_FP_STATE_HALTED; - break; - - default: - BNX2X_ERR("unexpected MC reply (%d) " - "fp[%d] state is %x\n", - command, fp->index, fp->state); - break; - } - mb(); /* force bnx2x_wait_ramrod() to see the change */ - return; - } - - switch (command | bp->state) { - case (RAMROD_CMD_ID_ETH_PORT_SETUP | BNX2X_STATE_OPENING_WAIT4_PORT): - DP(NETIF_MSG_IFUP, "got setup ramrod\n"); - bp->state = BNX2X_STATE_OPEN; + switch (command | fp->state) { + case (RAMROD_CMD_ID_ETH_CLIENT_SETUP | BNX2X_FP_STATE_OPENING): + DP(NETIF_MSG_IFUP, "got MULTI[%d] setup ramrod\n", cid); + fp->state = BNX2X_FP_STATE_OPEN; break; - case (RAMROD_CMD_ID_ETH_HALT | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got halt ramrod\n"); - bp->state = BNX2X_STATE_CLOSING_WAIT4_DELETE; + case (RAMROD_CMD_ID_ETH_HALT | BNX2X_FP_STATE_HALTING): + DP(NETIF_MSG_IFDOWN, "got MULTI[%d] halt ramrod\n", cid); fp->state = BNX2X_FP_STATE_HALTED; break; - case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got delete ramrod for MULTI[%d]\n", cid); - bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; - break; - -#ifdef BCM_CNIC - case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_OPEN): - DP(NETIF_MSG_IFDOWN, "got delete ramrod for CID %d\n", cid); - bnx2x_cnic_cfc_comp(bp, cid); - break; -#endif - - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG): - DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); - bp->set_mac_pending--; - smp_wmb(); - break; - - case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_CLOSING_WAIT4_HALT): - DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n"); - bp->set_mac_pending--; - smp_wmb(); + case (RAMROD_CMD_ID_ETH_TERMINATE | BNX2X_FP_STATE_TERMINATING): + DP(NETIF_MSG_IFDOWN, "got MULTI[%d] teminate ramrod\n", cid); + fp->state = BNX2X_FP_STATE_TERMINATED; break; default: - BNX2X_ERR("unexpected MC reply (%d) bp->state is %x\n", - command, bp->state); + BNX2X_ERR("unexpected MC reply (%d) " + "fp[%d] state is %x\n", + command, fp->index, fp->state); break; } - mb(); /* force bnx2x_wait_ramrod() to see the change */ + + smp_mb__before_atomic_inc(); + atomic_inc(&bp->spq_left); + /* push the change in fp->state and towards the memory */ + smp_wmb(); + + return; } irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) @@ -914,25 +1417,22 @@ irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) return IRQ_HANDLED; #endif - for (i = 0; i < BNX2X_NUM_QUEUES(bp); i++) { + for_each_queue(bp, i) { struct bnx2x_fastpath *fp = &bp->fp[i]; - mask = 0x2 << fp->sb_id; + mask = 0x2 << (fp->index + CNIC_CONTEXT_USE); if (status & mask) { /* Handle Rx and Tx according to SB id */ prefetch(fp->rx_cons_sb); - prefetch(&fp->status_blk->u_status_block. - status_block_index); prefetch(fp->tx_cons_sb); - prefetch(&fp->status_blk->c_status_block. - status_block_index); + prefetch(&fp->sb_running_index[SM_RX_ID]); napi_schedule(&bnx2x_fp(bp, fp->index, napi)); status &= ~mask; } } #ifdef BCM_CNIC - mask = 0x2 << CNIC_SB_ID(bp); + mask = 0x2; if (status & (mask | 0x1)) { struct cnic_ops *c_ops = NULL; @@ -1224,52 +1724,94 @@ static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) REG_WR(bp, MISC_REG_SPIO, spio_reg); bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_SPIO); - return 0; + return 0; +} + +int bnx2x_get_link_cfg_idx(struct bnx2x *bp) +{ + u32 sel_phy_idx = 0; + if (bp->link_vars.link_up) { + sel_phy_idx = EXT_PHY1; + /* In case link is SERDES, check if the EXT_PHY2 is the one */ + if ((bp->link_vars.link_status & LINK_STATUS_SERDES_LINK) && + (bp->link_params.phy[EXT_PHY2].supported & SUPPORTED_FIBRE)) + sel_phy_idx = EXT_PHY2; + } else { + + switch (bnx2x_phy_selection(&bp->link_params)) { + case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY: + case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY: + sel_phy_idx = EXT_PHY1; + break; + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY: + case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY: + sel_phy_idx = EXT_PHY2; + break; + } + } + /* + * The selected actived PHY is always after swapping (in case PHY + * swapping is enabled). So when swapping is enabled, we need to reverse + * the configuration + */ + + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) { + if (sel_phy_idx == EXT_PHY1) + sel_phy_idx = EXT_PHY2; + else if (sel_phy_idx == EXT_PHY2) + sel_phy_idx = EXT_PHY1; + } + return LINK_CONFIG_IDX(sel_phy_idx); } void bnx2x_calc_fc_adv(struct bnx2x *bp) { + u8 cfg_idx = bnx2x_get_link_cfg_idx(bp); switch (bp->link_vars.ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK) { case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE: - bp->port.advertising &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | + ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH: - bp->port.advertising |= (ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + bp->port.advertising[cfg_idx] |= (ADVERTISED_Asym_Pause | + ADVERTISED_Pause); break; case MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC: - bp->port.advertising |= ADVERTISED_Asym_Pause; + bp->port.advertising[cfg_idx] |= ADVERTISED_Asym_Pause; break; default: - bp->port.advertising &= ~(ADVERTISED_Asym_Pause | - ADVERTISED_Pause); + bp->port.advertising[cfg_idx] &= ~(ADVERTISED_Asym_Pause | + ADVERTISED_Pause); break; } } - u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) { if (!BP_NOMCP(bp)) { u8 rc; - + int cfx_idx = bnx2x_get_link_cfg_idx(bp); + u16 req_line_speed = bp->link_params.req_line_speed[cfx_idx]; /* Initialize link parameters structure variables */ /* It is recommended to turn off RX FC for jumbo frames for better performance */ - if (bp->dev->mtu > 5000) + if ((CHIP_IS_E1x(bp)) && (bp->dev->mtu > 5000)) bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_TX; else bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_BOTH; bnx2x_acquire_phy_lock(bp); - if (load_mode == LOAD_DIAG) - bp->link_params.loopback_mode = LOOPBACK_XGXS_10; + if (load_mode == LOAD_DIAG) { + bp->link_params.loopback_mode = LOOPBACK_XGXS; + bp->link_params.req_line_speed[cfx_idx] = SPEED_10000; + } rc = bnx2x_phy_init(&bp->link_params, &bp->link_vars); @@ -1281,7 +1823,7 @@ u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode) bnx2x_stats_handle(bp, STATS_EVENT_LINK_UP); bnx2x_link_report(bp); } - + bp->link_params.req_line_speed[cfx_idx] = req_line_speed; return rc; } BNX2X_ERR("Bootcode is missing - can not initialize link\n"); @@ -1292,6 +1834,7 @@ void bnx2x_link_set(struct bnx2x *bp) { if (!BP_NOMCP(bp)) { bnx2x_acquire_phy_lock(bp); + bnx2x_link_reset(&bp->link_params, &bp->link_vars, 1); bnx2x_phy_init(&bp->link_params, &bp->link_vars); bnx2x_release_phy_lock(bp); @@ -1310,13 +1853,14 @@ static void bnx2x__link_reset(struct bnx2x *bp) BNX2X_ERR("Bootcode is missing - can not reset link\n"); } -u8 bnx2x_link_test(struct bnx2x *bp) +u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes) { u8 rc = 0; if (!BP_NOMCP(bp)) { bnx2x_acquire_phy_lock(bp); - rc = bnx2x_test_link(&bp->link_params, &bp->link_vars); + rc = bnx2x_test_link(&bp->link_params, &bp->link_vars, + is_serdes); bnx2x_release_phy_lock(bp); } else BNX2X_ERR("Bootcode is missing - can not test link\n"); @@ -1371,13 +1915,11 @@ static void bnx2x_init_port_minmax(struct bnx2x *bp) static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) { int all_zero = 1; - int port = BP_PORT(bp); int vn; bp->vn_weight_sum = 0; for (vn = VN_0; vn < E1HVN_MAX; vn++) { - int func = 2*vn + port; - u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + u32 vn_cfg = bp->mf_config[vn]; u32 vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; @@ -1405,11 +1947,12 @@ static void bnx2x_calc_vn_weight_sum(struct bnx2x *bp) CMNG_FLAGS_PER_PORT_FAIRNESS_VN; } -static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) +static void bnx2x_init_vn_minmax(struct bnx2x *bp, int vn) { struct rate_shaping_vars_per_vn m_rs_vn; struct fairness_vars_per_vn m_fair_vn; - u32 vn_cfg = SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + u32 vn_cfg = bp->mf_config[vn]; + int func = 2*vn + BP_PORT(bp); u16 vn_min_rate, vn_max_rate; int i; @@ -1422,11 +1965,12 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) vn_min_rate = ((vn_cfg & FUNC_MF_CFG_MIN_BW_MASK) >> FUNC_MF_CFG_MIN_BW_SHIFT) * 100; /* If min rate is zero - set it to 1 */ - if (!vn_min_rate) + if (bp->vn_weight_sum && (vn_min_rate == 0)) vn_min_rate = DEF_MIN_RATE; vn_max_rate = ((vn_cfg & FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) * 100; } + DP(NETIF_MSG_IFUP, "func %d: vn_min_rate %d vn_max_rate %d vn_weight_sum %d\n", func, vn_min_rate, vn_max_rate, bp->vn_weight_sum); @@ -1467,6 +2011,83 @@ static void bnx2x_init_vn_minmax(struct bnx2x *bp, int func) ((u32 *)(&m_fair_vn))[i]); } +static int bnx2x_get_cmng_fns_mode(struct bnx2x *bp) +{ + if (CHIP_REV_IS_SLOW(bp)) + return CMNG_FNS_NONE; + if (IS_MF(bp)) + return CMNG_FNS_MINMAX; + + return CMNG_FNS_NONE; +} + +static void bnx2x_read_mf_cfg(struct bnx2x *bp) +{ + int vn; + + if (BP_NOMCP(bp)) + return; /* what should be the default bvalue in this case */ + + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + int /*abs*/func = 2*vn + BP_PORT(bp); + bp->mf_config[vn] = + MF_CFG_RD(bp, func_mf_config[func].config); + } +} + +static void bnx2x_cmng_fns_init(struct bnx2x *bp, u8 read_cfg, u8 cmng_type) +{ + + if (cmng_type == CMNG_FNS_MINMAX) { + int vn; + + /* clear cmng_enables */ + bp->cmng.flags.cmng_enables = 0; + + /* read mf conf from shmem */ + if (read_cfg) + bnx2x_read_mf_cfg(bp); + + /* Init rate shaping and fairness contexts */ + bnx2x_init_port_minmax(bp); + + /* vn_weight_sum and enable fairness if not 0 */ + bnx2x_calc_vn_weight_sum(bp); + + /* calculate and set min-max rate for each vn */ + for (vn = VN_0; vn < E1HVN_MAX; vn++) + bnx2x_init_vn_minmax(bp, vn); + + /* always enable rate shaping and fairness */ + bp->cmng.flags.cmng_enables |= + CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN; + if (!bp->vn_weight_sum) + DP(NETIF_MSG_IFUP, "All MIN values are zeroes" + " fairness will be disabled\n"); + return; + } + + /* rate shaping and fairness are disabled */ + DP(NETIF_MSG_IFUP, + "rate shaping and fairness are disabled\n"); +} + +static inline void bnx2x_link_sync_notify(struct bnx2x *bp) +{ + int port = BP_PORT(bp); + int func; + int vn; + + /* Set the attention towards other drivers on the same port */ + for (vn = VN_0; vn < E1HVN_MAX; vn++) { + if (vn == BP_E1HVN(bp)) + continue; + + func = ((vn << 1) | port); + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + + (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); + } +} /* This function is called upon link interrupt */ static void bnx2x_link_attn(struct bnx2x *bp) @@ -1480,7 +2101,7 @@ static void bnx2x_link_attn(struct bnx2x *bp) if (bp->link_vars.link_up) { /* dropless flow control */ - if (CHIP_IS_E1H(bp) && bp->dropless_fc) { + if (!CHIP_IS_E1(bp) && bp->dropless_fc) { int port = BP_PORT(bp); u32 pause_enabled = 0; @@ -1508,37 +2129,19 @@ static void bnx2x_link_attn(struct bnx2x *bp) if (prev_link_status != bp->link_vars.link_status) bnx2x_link_report(bp); - if (IS_E1HMF(bp)) { - int port = BP_PORT(bp); - int func; - int vn; - - /* Set the attention towards other drivers on the same port */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - if (vn == BP_E1HVN(bp)) - continue; - - func = ((vn << 1) | port); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + - (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); - } - - if (bp->link_vars.link_up) { - int i; - - /* Init rate shaping and fairness contexts */ - bnx2x_init_port_minmax(bp); + if (IS_MF(bp)) + bnx2x_link_sync_notify(bp); - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); + if (bp->link_vars.link_up && bp->link_vars.line_speed) { + int cmng_fns = bnx2x_get_cmng_fns_mode(bp); - /* Store it to internal memory */ - for (i = 0; - i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, - ((u32 *)(&bp->cmng))[i]); - } + if (cmng_fns != CMNG_FNS_NONE) { + bnx2x_cmng_fns_init(bp, false, cmng_fns); + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + } else + /* rate shaping and fairness are disabled */ + DP(NETIF_MSG_IFUP, + "single function mode without fairness\n"); } } @@ -1554,7 +2157,9 @@ void bnx2x__link_status_update(struct bnx2x *bp) else bnx2x_stats_handle(bp, STATS_EVENT_STOP); - bnx2x_calc_vn_weight_sum(bp); + /* the link status update could be the result of a DCC event + hence re-read the shmem mf configuration */ + bnx2x_read_mf_cfg(bp); /* indicate link status */ bnx2x_link_report(bp); @@ -1570,8 +2175,13 @@ static void bnx2x_pmf_update(struct bnx2x *bp) /* enable nig attention */ val = (0xff0f | (1 << (BP_E1HVN(bp) + 4))); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); + if (bp->common.int_block == INT_BLOCK_HC) { + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, val); + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, val); + } else if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, val); + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, val); + } bnx2x_stats_handle(bp, STATS_EVENT_PMF); } @@ -1585,23 +2195,25 @@ static void bnx2x_pmf_update(struct bnx2x *bp) */ /* send the MCP a request, block until there is a reply */ -u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) +u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); u32 seq = ++bp->fw_seq; u32 rc = 0; u32 cnt = 1; u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10; mutex_lock(&bp->fw_mb_mutex); - SHMEM_WR(bp, func_mb[func].drv_mb_header, (command | seq)); + SHMEM_WR(bp, func_mb[mb_idx].drv_mb_param, param); + SHMEM_WR(bp, func_mb[mb_idx].drv_mb_header, (command | seq)); + DP(BNX2X_MSG_MCP, "wrote command (%x) to FW MB\n", (command | seq)); do { /* let the FW do it's magic ... */ msleep(delay); - rc = SHMEM_RD(bp, func_mb[func].fw_mb_header); + rc = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_header); /* Give the FW up to 5 second (500*10ms) */ } while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500)); @@ -1623,6 +2235,315 @@ u32 bnx2x_fw_command(struct bnx2x *bp, u32 command) return rc; } +/* must be called under rtnl_lock */ +void bnx2x_rxq_set_mac_filters(struct bnx2x *bp, u16 cl_id, u32 filters) +{ + u32 mask = (1 << cl_id); + + /* initial seeting is BNX2X_ACCEPT_NONE */ + u8 drop_all_ucast = 1, drop_all_bcast = 1, drop_all_mcast = 1; + u8 accp_all_ucast = 0, accp_all_bcast = 0, accp_all_mcast = 0; + u8 unmatched_unicast = 0; + + if (filters & BNX2X_PROMISCUOUS_MODE) { + /* promiscious - accept all, drop none */ + drop_all_ucast = drop_all_bcast = drop_all_mcast = 0; + accp_all_ucast = accp_all_bcast = accp_all_mcast = 1; + } + if (filters & BNX2X_ACCEPT_UNICAST) { + /* accept matched ucast */ + drop_all_ucast = 0; + } + if (filters & BNX2X_ACCEPT_MULTICAST) { + /* accept matched mcast */ + drop_all_mcast = 0; + } + if (filters & BNX2X_ACCEPT_ALL_UNICAST) { + /* accept all mcast */ + drop_all_ucast = 0; + accp_all_ucast = 1; + } + if (filters & BNX2X_ACCEPT_ALL_MULTICAST) { + /* accept all mcast */ + drop_all_mcast = 0; + accp_all_mcast = 1; + } + if (filters & BNX2X_ACCEPT_BROADCAST) { + /* accept (all) bcast */ + drop_all_bcast = 0; + accp_all_bcast = 1; + } + + bp->mac_filters.ucast_drop_all = drop_all_ucast ? + bp->mac_filters.ucast_drop_all | mask : + bp->mac_filters.ucast_drop_all & ~mask; + + bp->mac_filters.mcast_drop_all = drop_all_mcast ? + bp->mac_filters.mcast_drop_all | mask : + bp->mac_filters.mcast_drop_all & ~mask; + + bp->mac_filters.bcast_drop_all = drop_all_bcast ? + bp->mac_filters.bcast_drop_all | mask : + bp->mac_filters.bcast_drop_all & ~mask; + + bp->mac_filters.ucast_accept_all = accp_all_ucast ? + bp->mac_filters.ucast_accept_all | mask : + bp->mac_filters.ucast_accept_all & ~mask; + + bp->mac_filters.mcast_accept_all = accp_all_mcast ? + bp->mac_filters.mcast_accept_all | mask : + bp->mac_filters.mcast_accept_all & ~mask; + + bp->mac_filters.bcast_accept_all = accp_all_bcast ? + bp->mac_filters.bcast_accept_all | mask : + bp->mac_filters.bcast_accept_all & ~mask; + + bp->mac_filters.unmatched_unicast = unmatched_unicast ? + bp->mac_filters.unmatched_unicast | mask : + bp->mac_filters.unmatched_unicast & ~mask; +} + +void bnx2x_func_init(struct bnx2x *bp, struct bnx2x_func_init_params *p) +{ + struct tstorm_eth_function_common_config tcfg = {0}; + u16 rss_flgs; + + /* tpa */ + if (p->func_flgs & FUNC_FLG_TPA) + tcfg.config_flags |= + TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; + + /* set rss flags */ + rss_flgs = (p->rss->mode << + TSTORM_ETH_FUNCTION_COMMON_CONFIG_RSS_MODE_SHIFT); + + if (p->rss->cap & RSS_IPV4_CAP) + rss_flgs |= RSS_IPV4_CAP_MASK; + if (p->rss->cap & RSS_IPV4_TCP_CAP) + rss_flgs |= RSS_IPV4_TCP_CAP_MASK; + if (p->rss->cap & RSS_IPV6_CAP) + rss_flgs |= RSS_IPV6_CAP_MASK; + if (p->rss->cap & RSS_IPV6_TCP_CAP) + rss_flgs |= RSS_IPV6_TCP_CAP_MASK; + + tcfg.config_flags |= rss_flgs; + tcfg.rss_result_mask = p->rss->result_mask; + + storm_memset_func_cfg(bp, &tcfg, p->func_id); + + /* Enable the function in the FW */ + storm_memset_vf_to_pf(bp, p->func_id, p->pf_id); + storm_memset_func_en(bp, p->func_id, 1); + + /* statistics */ + if (p->func_flgs & FUNC_FLG_STATS) { + struct stats_indication_flags stats_flags = {0}; + stats_flags.collect_eth = 1; + + storm_memset_xstats_flags(bp, &stats_flags, p->func_id); + storm_memset_xstats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_tstats_flags(bp, &stats_flags, p->func_id); + storm_memset_tstats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_ustats_flags(bp, &stats_flags, p->func_id); + storm_memset_ustats_addr(bp, p->fw_stat_map, p->func_id); + + storm_memset_cstats_flags(bp, &stats_flags, p->func_id); + storm_memset_cstats_addr(bp, p->fw_stat_map, p->func_id); + } + + /* spq */ + if (p->func_flgs & FUNC_FLG_SPQ) { + storm_memset_spq_addr(bp, p->spq_map, p->func_id); + REG_WR(bp, XSEM_REG_FAST_MEMORY + + XSTORM_SPQ_PROD_OFFSET(p->func_id), p->spq_prod); + } +} + +static inline u16 bnx2x_get_cl_flags(struct bnx2x *bp, + struct bnx2x_fastpath *fp) +{ + u16 flags = 0; + + /* calculate queue flags */ + flags |= QUEUE_FLG_CACHE_ALIGN; + flags |= QUEUE_FLG_HC; + flags |= IS_MF(bp) ? QUEUE_FLG_OV : 0; + + flags |= QUEUE_FLG_VLAN; + DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); + + if (!fp->disable_tpa) + flags |= QUEUE_FLG_TPA; + + flags |= QUEUE_FLG_STATS; + + return flags; +} + +static void bnx2x_pf_rx_cl_prep(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct rxq_pause_params *pause, + struct bnx2x_rxq_init_params *rxq_init) +{ + u16 max_sge = 0; + u16 sge_sz = 0; + u16 tpa_agg_size = 0; + + /* calculate queue flags */ + u16 flags = bnx2x_get_cl_flags(bp, fp); + + if (!fp->disable_tpa) { + pause->sge_th_hi = 250; + pause->sge_th_lo = 150; + tpa_agg_size = min_t(u32, + (min_t(u32, 8, MAX_SKB_FRAGS) * + SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff); + max_sge = SGE_PAGE_ALIGN(bp->dev->mtu) >> + SGE_PAGE_SHIFT; + max_sge = ((max_sge + PAGES_PER_SGE - 1) & + (~(PAGES_PER_SGE-1))) >> PAGES_PER_SGE_SHIFT; + sge_sz = (u16)min_t(u32, SGE_PAGE_SIZE * PAGES_PER_SGE, + 0xffff); + } + + /* pause - not for e1 */ + if (!CHIP_IS_E1(bp)) { + pause->bd_th_hi = 350; + pause->bd_th_lo = 250; + pause->rcq_th_hi = 350; + pause->rcq_th_lo = 250; + pause->sge_th_hi = 0; + pause->sge_th_lo = 0; + pause->pri_map = 1; + } + + /* rxq setup */ + rxq_init->flags = flags; + rxq_init->cxt = &bp->context.vcxt[fp->cid].eth; + rxq_init->dscr_map = fp->rx_desc_mapping; + rxq_init->sge_map = fp->rx_sge_mapping; + rxq_init->rcq_map = fp->rx_comp_mapping; + rxq_init->rcq_np_map = fp->rx_comp_mapping + BCM_PAGE_SIZE; + rxq_init->mtu = bp->dev->mtu; + rxq_init->buf_sz = bp->rx_buf_size; + rxq_init->cl_qzone_id = fp->cl_qzone_id; + rxq_init->cl_id = fp->cl_id; + rxq_init->spcl_id = fp->cl_id; + rxq_init->stat_id = fp->cl_id; + rxq_init->tpa_agg_sz = tpa_agg_size; + rxq_init->sge_buf_sz = sge_sz; + rxq_init->max_sges_pkt = max_sge; + rxq_init->cache_line_log = BNX2X_RX_ALIGN_SHIFT; + rxq_init->fw_sb_id = fp->fw_sb_id; + + rxq_init->sb_cq_index = U_SB_ETH_RX_CQ_INDEX; + + rxq_init->cid = HW_CID(bp, fp->cid); + + rxq_init->hc_rate = bp->rx_ticks ? (1000000 / bp->rx_ticks) : 0; +} + +static void bnx2x_pf_tx_cl_prep(struct bnx2x *bp, + struct bnx2x_fastpath *fp, struct bnx2x_txq_init_params *txq_init) +{ + u16 flags = bnx2x_get_cl_flags(bp, fp); + + txq_init->flags = flags; + txq_init->cxt = &bp->context.vcxt[fp->cid].eth; + txq_init->dscr_map = fp->tx_desc_mapping; + txq_init->stat_id = fp->cl_id; + txq_init->cid = HW_CID(bp, fp->cid); + txq_init->sb_cq_index = C_SB_ETH_TX_CQ_INDEX; + txq_init->traffic_type = LLFC_TRAFFIC_TYPE_NW; + txq_init->fw_sb_id = fp->fw_sb_id; + txq_init->hc_rate = bp->tx_ticks ? (1000000 / bp->tx_ticks) : 0; +} + +void bnx2x_pf_init(struct bnx2x *bp) +{ + struct bnx2x_func_init_params func_init = {0}; + struct bnx2x_rss_params rss = {0}; + struct event_ring_data eq_data = { {0} }; + u16 flags; + + /* pf specific setups */ + if (!CHIP_IS_E1(bp)) + storm_memset_ov(bp, bp->mf_ov, BP_FUNC(bp)); + + if (CHIP_IS_E2(bp)) { + /* reset IGU PF statistics: MSIX + ATTN */ + /* PF */ + REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT + + BNX2X_IGU_STAS_MSG_VF_CNT*4 + + (CHIP_MODE_IS_4_PORT(bp) ? + BP_FUNC(bp) : BP_VN(bp))*4, 0); + /* ATTN */ + REG_WR(bp, IGU_REG_STATISTIC_NUM_MESSAGE_SENT + + BNX2X_IGU_STAS_MSG_VF_CNT*4 + + BNX2X_IGU_STAS_MSG_PF_CNT*4 + + (CHIP_MODE_IS_4_PORT(bp) ? + BP_FUNC(bp) : BP_VN(bp))*4, 0); + } + + /* function setup flags */ + flags = (FUNC_FLG_STATS | FUNC_FLG_LEADING | FUNC_FLG_SPQ); + + if (CHIP_IS_E1x(bp)) + flags |= (bp->flags & TPA_ENABLE_FLAG) ? FUNC_FLG_TPA : 0; + else + flags |= FUNC_FLG_TPA; + + /* function setup */ + + /** + * Although RSS is meaningless when there is a single HW queue we + * still need it enabled in order to have HW Rx hash generated. + */ + rss.cap = (RSS_IPV4_CAP | RSS_IPV4_TCP_CAP | + RSS_IPV6_CAP | RSS_IPV6_TCP_CAP); + rss.mode = bp->multi_mode; + rss.result_mask = MULTI_MASK; + func_init.rss = &rss; + + func_init.func_flgs = flags; + func_init.pf_id = BP_FUNC(bp); + func_init.func_id = BP_FUNC(bp); + func_init.fw_stat_map = bnx2x_sp_mapping(bp, fw_stats); + func_init.spq_map = bp->spq_mapping; + func_init.spq_prod = bp->spq_prod_idx; + + bnx2x_func_init(bp, &func_init); + + memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); + + /* + Congestion management values depend on the link rate + There is no active link so initial link rate is set to 10 Gbps. + When the link comes up The congestion management values are + re-calculated according to the actual link rate. + */ + bp->link_vars.line_speed = SPEED_10000; + bnx2x_cmng_fns_init(bp, true, bnx2x_get_cmng_fns_mode(bp)); + + /* Only the PMF sets the HW */ + if (bp->port.pmf) + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); + + /* no rx until link is up */ + bp->rx_mode = BNX2X_RX_MODE_NONE; + bnx2x_set_storm_rx_mode(bp); + + /* init Event Queue */ + eq_data.base_addr.hi = U64_HI(bp->eq_mapping); + eq_data.base_addr.lo = U64_LO(bp->eq_mapping); + eq_data.producer = bp->eq_prod; + eq_data.index_id = HC_SP_INDEX_EQ_CONS; + eq_data.sb_id = DEF_SB_ID; + storm_memset_eq_data(bp, &eq_data, BP_FUNC(bp)); +} + + static void bnx2x_e1h_disable(struct bnx2x *bp) { int port = BP_PORT(bp); @@ -1649,40 +2570,6 @@ static void bnx2x_e1h_enable(struct bnx2x *bp) */ } -static void bnx2x_update_min_max(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - int vn, i; - - /* Init rate shaping and fairness contexts */ - bnx2x_init_port_minmax(bp); - - bnx2x_calc_vn_weight_sum(bp); - - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); - - if (bp->port.pmf) { - int func; - - /* Set the attention towards other drivers on the same port */ - for (vn = VN_0; vn < E1HVN_MAX; vn++) { - if (vn == BP_E1HVN(bp)) - continue; - - func = ((vn << 1) | port); - REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_0 + - (LINK_SYNC_ATTENTION_BIT_FUNC_0 + func)*4, 1); - } - - /* Store it to internal memory */ - for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i*4, - ((u32 *)(&bp->cmng))[i]); - } -} - static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) { DP(BNX2X_MSG_MCP, "dcc_event 0x%x\n", dcc_event); @@ -1694,7 +2581,7 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) * where the bp->flags can change so it is done without any * locks */ - if (bp->mf_config & FUNC_MF_CFG_FUNC_DISABLED) { + if (bp->mf_config[BP_VN(bp)] & FUNC_MF_CFG_FUNC_DISABLED) { DP(NETIF_MSG_IFDOWN, "mf_cfg function disabled\n"); bp->flags |= MF_FUNC_DIS; @@ -1709,15 +2596,17 @@ static void bnx2x_dcc_event(struct bnx2x *bp, u32 dcc_event) } if (dcc_event & DRV_STATUS_DCC_BANDWIDTH_ALLOCATION) { - bnx2x_update_min_max(bp); + bnx2x_cmng_fns_init(bp, true, CMNG_FNS_MINMAX); + bnx2x_link_sync_notify(bp); + storm_memset_cmng(bp, &bp->cmng, BP_PORT(bp)); dcc_event &= ~DRV_STATUS_DCC_BANDWIDTH_ALLOCATION; } /* Report results to MCP */ if (dcc_event) - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE); + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_FAILURE, 0); else - bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK); + bnx2x_fw_command(bp, DRV_MSG_CODE_DCC_OK, 0); } /* must be called under the spq lock */ @@ -1744,16 +2633,17 @@ static inline void bnx2x_sp_prod_update(struct bnx2x *bp) /* Make sure that BD data is updated before writing the producer */ wmb(); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), - bp->spq_prod_idx); + REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func), + bp->spq_prod_idx); mmiowb(); } /* the slow path queue is odd since completions arrive on the fastpath ring */ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common) + u32 data_hi, u32 data_lo, int common) { struct eth_spe *spe; + u16 type; #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -1762,7 +2652,7 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, spin_lock_bh(&bp->spq_lock); - if (!bp->spq_left) { + if (!atomic_read(&bp->spq_left)) { BNX2X_ERR("BUG! SPQ ring full!\n"); spin_unlock_bh(&bp->spq_lock); bnx2x_panic(); @@ -1775,22 +2665,42 @@ int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, spe->hdr.conn_and_cmd_data = cpu_to_le32((command << SPE_HDR_CMD_ID_SHIFT) | HW_CID(bp, cid)); - spe->hdr.type = cpu_to_le16(ETH_CONNECTION_TYPE); + if (common) - spe->hdr.type |= - cpu_to_le16((1 << SPE_HDR_COMMON_RAMROD_SHIFT)); + /* Common ramrods: + * FUNC_START, FUNC_STOP, CFC_DEL, STATS, SET_MAC + * TRAFFIC_STOP, TRAFFIC_START + */ + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + else + /* ETH ramrods: SETUP, HALT */ + type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + + type |= ((BP_FUNC(bp) << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); - spe->data.mac_config_addr.hi = cpu_to_le32(data_hi); - spe->data.mac_config_addr.lo = cpu_to_le32(data_lo); + spe->hdr.type = cpu_to_le16(type); - bp->spq_left--; + spe->data.update_data_addr.hi = cpu_to_le32(data_hi); + spe->data.update_data_addr.lo = cpu_to_le32(data_lo); + + /* stats ramrod has it's own slot on the spq */ + if (command != RAMROD_CMD_ID_COMMON_STAT_QUERY) + /* It's ok if the actual decrement is issued towards the memory + * somewhere between the spin_lock and spin_unlock. Thus no + * more explict memory barrier is needed. + */ + atomic_dec(&bp->spq_left); DP(BNX2X_MSG_SP/*NETIF_MSG_TIMER*/, - "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) left %x\n", + "SPQE[%x] (%x:%x) command %d hw_cid %x data (%x:%x) " + "type(0x%x) left %x\n", bp->spq_prod_idx, (u32)U64_HI(bp->spq_mapping), (u32)(U64_LO(bp->spq_mapping) + (void *)bp->spq_prod_bd - (void *)bp->spq), command, - HW_CID(bp, cid), data_hi, data_lo, bp->spq_left); + HW_CID(bp, cid), data_hi, data_lo, type, atomic_read(&bp->spq_left)); bnx2x_sp_prod_update(bp); spin_unlock_bh(&bp->spq_lock); @@ -1827,32 +2737,27 @@ static void bnx2x_release_alr(struct bnx2x *bp) REG_WR(bp, GRCBASE_MCP + 0x9c, 0); } +#define BNX2X_DEF_SB_ATT_IDX 0x0001 +#define BNX2X_DEF_SB_IDX 0x0002 + static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) { - struct host_def_status_block *def_sb = bp->def_status_blk; + struct host_sp_status_block *def_sb = bp->def_status_blk; u16 rc = 0; barrier(); /* status block is written to by the chip */ if (bp->def_att_idx != def_sb->atten_status_block.attn_bits_index) { bp->def_att_idx = def_sb->atten_status_block.attn_bits_index; - rc |= 1; - } - if (bp->def_c_idx != def_sb->c_def_status_block.status_block_index) { - bp->def_c_idx = def_sb->c_def_status_block.status_block_index; - rc |= 2; + rc |= BNX2X_DEF_SB_ATT_IDX; } - if (bp->def_u_idx != def_sb->u_def_status_block.status_block_index) { - bp->def_u_idx = def_sb->u_def_status_block.status_block_index; - rc |= 4; - } - if (bp->def_x_idx != def_sb->x_def_status_block.status_block_index) { - bp->def_x_idx = def_sb->x_def_status_block.status_block_index; - rc |= 8; - } - if (bp->def_t_idx != def_sb->t_def_status_block.status_block_index) { - bp->def_t_idx = def_sb->t_def_status_block.status_block_index; - rc |= 16; + + if (bp->def_idx != def_sb->sp_sb.running_index) { + bp->def_idx = def_sb->sp_sb.running_index; + rc |= BNX2X_DEF_SB_IDX; } + + /* Do not reorder: indecies reading should complete before handling */ + barrier(); return rc; } @@ -1863,14 +2768,13 @@ static inline u16 bnx2x_update_dsb_idx(struct bnx2x *bp) static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) { int port = BP_PORT(bp); - u32 hc_addr = (HC_REG_COMMAND_REG + port*32 + - COMMAND_REG_ATTN_BITS_SET); u32 aeu_addr = port ? MISC_REG_AEU_MASK_ATTN_FUNC_1 : MISC_REG_AEU_MASK_ATTN_FUNC_0; u32 nig_int_mask_addr = port ? NIG_REG_MASK_INTERRUPT_PORT1 : NIG_REG_MASK_INTERRUPT_PORT0; u32 aeu_mask; u32 nig_mask = 0; + u32 reg_addr; if (bp->attn_state & asserted) BNX2X_ERR("IGU ERROR\n"); @@ -1945,9 +2849,15 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) } /* if hardwired */ - DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", - asserted, hc_addr); - REG_WR(bp, hc_addr, asserted); + if (bp->common.int_block == INT_BLOCK_HC) + reg_addr = (HC_REG_COMMAND_REG + port*32 + + COMMAND_REG_ATTN_BITS_SET); + else + reg_addr = (BAR_IGU_INTMEM + IGU_CMD_ATTN_BIT_SET_UPPER*8); + + DP(NETIF_MSG_HW, "about to mask 0x%08x at %s addr 0x%x\n", asserted, + (bp->common.int_block == INT_BLOCK_HC) ? "HC" : "IGU", reg_addr); + REG_WR(bp, reg_addr, asserted); /* now set back the mask */ if (asserted & ATTN_NIG_FOR_FUNC) { @@ -1959,12 +2869,16 @@ static void bnx2x_attn_int_asserted(struct bnx2x *bp, u32 asserted) static inline void bnx2x_fan_failure(struct bnx2x *bp) { int port = BP_PORT(bp); - + u32 ext_phy_config; /* mark the failure */ - bp->link_params.ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; - bp->link_params.ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE; + ext_phy_config = + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config); + + ext_phy_config &= ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; + ext_phy_config |= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE; SHMEM_WR(bp, dev_info.port_hw_config[port].external_phy_config, - bp->link_params.ext_phy_config); + ext_phy_config); /* log the failure */ netdev_err(bp->dev, "Fan Failure on Network Controller has caused" @@ -1976,7 +2890,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) { int port = BP_PORT(bp); int reg_offset; - u32 val, swap_val, swap_override; + u32 val; reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); @@ -1990,30 +2904,7 @@ static inline void bnx2x_attn_int_deasserted0(struct bnx2x *bp, u32 attn) BNX2X_ERR("SPIO5 hw attention\n"); /* Fan failure attention */ - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - /* Low power mode is controlled by GPIO 2 */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - /* The PHY reset is controlled by GPIO 1 */ - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - /* The PHY reset is controlled by GPIO 1 */ - /* fake the port number to cancel the swap done in - set_gpio() */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - port = (swap_val && swap_override) ^ 1; - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, - MISC_REGISTERS_GPIO_OUTPUT_LOW, port); - break; - - default: - break; - } + bnx2x_hw_reset_phy(&bp->link_params); bnx2x_fan_failure(bp); } @@ -2087,6 +2978,10 @@ static inline void bnx2x_attn_int_deasserted2(struct bnx2x *bp, u32 attn) /* RQ_USDMDP_FIFO_OVERFLOW */ if (val & 0x18000) BNX2X_ERR("FATAL error from PXP\n"); + if (CHIP_IS_E2(bp)) { + val = REG_RD(bp, PXP_REG_PXP_INT_STS_CLR_1); + BNX2X_ERR("PXP hw attention-1 0x%x\n", val); + } } if (attn & HW_INTERRUT_ASSERT_SET_2) { @@ -2117,9 +3012,10 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) int func = BP_FUNC(bp); REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - bp->mf_config = SHMEM_RD(bp, - mf_cfg.func_mf_config[func].config); - val = SHMEM_RD(bp, func_mb[func].drv_status); + bp->mf_config[BP_VN(bp)] = MF_CFG_RD(bp, + func_mf_config[BP_ABS_FUNC(bp)].config); + val = SHMEM_RD(bp, + func_mb[BP_FW_MB_IDX(bp)].drv_status); if (val & DRV_STATUS_DCC_EVENT_MASK) bnx2x_dcc_event(bp, (val & DRV_STATUS_DCC_EVENT_MASK)); @@ -2149,13 +3045,13 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) if (attn & EVEREST_LATCHED_ATTN_IN_USE_MASK) { BNX2X_ERR("LATCHED attention 0x%08x (masked)\n", attn); if (attn & BNX2X_GRC_TIMEOUT) { - val = CHIP_IS_E1H(bp) ? - REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN) : 0; + val = CHIP_IS_E1(bp) ? 0 : + REG_RD(bp, MISC_REG_GRC_TIMEOUT_ATTN); BNX2X_ERR("GRC time-out 0x%08x\n", val); } if (attn & BNX2X_GRC_RSV) { - val = CHIP_IS_E1H(bp) ? - REG_RD(bp, MISC_REG_GRC_RSV_ATTN) : 0; + val = CHIP_IS_E1(bp) ? 0 : + REG_RD(bp, MISC_REG_GRC_RSV_ATTN); BNX2X_ERR("GRC reserved 0x%08x\n", val); } REG_WR(bp, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x7ff); @@ -2168,6 +3064,7 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) #define RESET_DONE_FLAG_MASK (~LOAD_COUNTER_MASK) #define RESET_DONE_FLAG_SHIFT LOAD_COUNTER_BITS #define CHIP_PARITY_SUPPORTED(bp) (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) + /* * should be run under rtnl lock */ @@ -2460,6 +3357,74 @@ bool bnx2x_chk_parity_attn(struct bnx2x *bp) attn.sig[3]); } + +static inline void bnx2x_attn_int_deasserted4(struct bnx2x *bp, u32 attn) +{ + u32 val; + if (attn & AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT) { + + val = REG_RD(bp, PGLUE_B_REG_PGLUE_B_INT_STS_CLR); + BNX2X_ERR("PGLUE hw attention 0x%x\n", val); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "ADDRESS_ERROR\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "INCORRECT_RCV_BEHAVIOR\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "WAS_ERROR_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_VF_LENGTH_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_LENGTH_VIOLATION_ATTN\n"); + if (val & + PGLUE_B_PGLUE_B_INT_STS_REG_VF_GRC_SPACE_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_GRC_SPACE_VIOLATION_ATTN\n"); + if (val & + PGLUE_B_PGLUE_B_INT_STS_REG_VF_MSIX_BAR_VIOLATION_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "VF_MSIX_BAR_VIOLATION_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_ERROR_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "TCPL_ERROR_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_IN_TWO_RCBS_ATTN) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "TCPL_IN_TWO_RCBS_ATTN\n"); + if (val & PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW) + BNX2X_ERR("PGLUE_B_PGLUE_B_INT_STS_REG_" + "CSSNOOP_FIFO_OVERFLOW\n"); + } + if (attn & AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT) { + val = REG_RD(bp, ATC_REG_ATC_INT_STS_CLR); + BNX2X_ERR("ATC hw attention 0x%x\n", val); + if (val & ATC_ATC_INT_STS_REG_ADDRESS_ERROR) + BNX2X_ERR("ATC_ATC_INT_STS_REG_ADDRESS_ERROR\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND) + BNX2X_ERR("ATC_ATC_INT_STS_REG" + "_ATC_TCPL_TO_NOT_PEND\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_GPA_MULTIPLE_HITS\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_RCPL_TO_EMPTY_CNT) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_RCPL_TO_EMPTY_CNT\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR) + BNX2X_ERR("ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR\n"); + if (val & ATC_ATC_INT_STS_REG_ATC_IREQ_LESS_THAN_STU) + BNX2X_ERR("ATC_ATC_INT_STS_REG_" + "ATC_IREQ_LESS_THAN_STU\n"); + } + + if (attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | + AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR)) { + BNX2X_ERR("FATAL parity attention set4 0x%x\n", + (u32)(attn & (AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR | + AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR))); + } + +} + static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) { struct attn_route attn, *group_mask; @@ -2490,17 +3455,28 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) attn.sig[1] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_2_FUNC_0 + port*4); attn.sig[2] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_3_FUNC_0 + port*4); attn.sig[3] = REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_4_FUNC_0 + port*4); - DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x\n", - attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3]); + if (CHIP_IS_E2(bp)) + attn.sig[4] = + REG_RD(bp, MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 + port*4); + else + attn.sig[4] = 0; + + DP(NETIF_MSG_HW, "attn: %08x %08x %08x %08x %08x\n", + attn.sig[0], attn.sig[1], attn.sig[2], attn.sig[3], attn.sig[4]); for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { if (deasserted & (1 << index)) { group_mask = &bp->attn_group[index]; - DP(NETIF_MSG_HW, "group[%d]: %08x %08x %08x %08x\n", - index, group_mask->sig[0], group_mask->sig[1], - group_mask->sig[2], group_mask->sig[3]); + DP(NETIF_MSG_HW, "group[%d]: %08x %08x " + "%08x %08x %08x\n", + index, + group_mask->sig[0], group_mask->sig[1], + group_mask->sig[2], group_mask->sig[3], + group_mask->sig[4]); + bnx2x_attn_int_deasserted4(bp, + attn.sig[4] & group_mask->sig[4]); bnx2x_attn_int_deasserted3(bp, attn.sig[3] & group_mask->sig[3]); bnx2x_attn_int_deasserted1(bp, @@ -2514,11 +3490,15 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) bnx2x_release_alr(bp); - reg_addr = (HC_REG_COMMAND_REG + port*32 + COMMAND_REG_ATTN_BITS_CLR); + if (bp->common.int_block == INT_BLOCK_HC) + reg_addr = (HC_REG_COMMAND_REG + port*32 + + COMMAND_REG_ATTN_BITS_CLR); + else + reg_addr = (BAR_IGU_INTMEM + IGU_CMD_ATTN_BIT_CLR_UPPER*8); val = ~deasserted; - DP(NETIF_MSG_HW, "about to mask 0x%08x at HC addr 0x%x\n", - val, reg_addr); + DP(NETIF_MSG_HW, "about to mask 0x%08x at %s addr 0x%x\n", val, + (bp->common.int_block == INT_BLOCK_HC) ? "HC" : "IGU", reg_addr); REG_WR(bp, reg_addr, val); if (~bp->attn_state & deasserted) @@ -2543,32 +3523,167 @@ static void bnx2x_attn_int_deasserted(struct bnx2x *bp, u32 deasserted) DP(NETIF_MSG_HW, "new state %x\n", bp->attn_state); } -static void bnx2x_attn_int(struct bnx2x *bp) -{ - /* read local copy of bits */ - u32 attn_bits = le32_to_cpu(bp->def_status_blk->atten_status_block. - attn_bits); - u32 attn_ack = le32_to_cpu(bp->def_status_blk->atten_status_block. - attn_bits_ack); - u32 attn_state = bp->attn_state; +static void bnx2x_attn_int(struct bnx2x *bp) +{ + /* read local copy of bits */ + u32 attn_bits = le32_to_cpu(bp->def_status_blk->atten_status_block. + attn_bits); + u32 attn_ack = le32_to_cpu(bp->def_status_blk->atten_status_block. + attn_bits_ack); + u32 attn_state = bp->attn_state; + + /* look for changed bits */ + u32 asserted = attn_bits & ~attn_ack & ~attn_state; + u32 deasserted = ~attn_bits & attn_ack & attn_state; + + DP(NETIF_MSG_HW, + "attn_bits %x attn_ack %x asserted %x deasserted %x\n", + attn_bits, attn_ack, asserted, deasserted); + + if (~(attn_bits ^ attn_ack) & (attn_bits ^ attn_state)) + BNX2X_ERR("BAD attention state\n"); + + /* handle bits that were raised */ + if (asserted) + bnx2x_attn_int_asserted(bp, asserted); + + if (deasserted) + bnx2x_attn_int_deasserted(bp, deasserted); +} + +static inline void bnx2x_update_eq_prod(struct bnx2x *bp, u16 prod) +{ + /* No memory barriers */ + storm_memset_eq_prod(bp, prod, BP_FUNC(bp)); + mmiowb(); /* keep prod updates ordered */ +} + +#ifdef BCM_CNIC +static int bnx2x_cnic_handle_cfc_del(struct bnx2x *bp, u32 cid, + union event_ring_elem *elem) +{ + if (!bp->cnic_eth_dev.starting_cid || + cid < bp->cnic_eth_dev.starting_cid) + return 1; + + DP(BNX2X_MSG_SP, "got delete ramrod for CNIC CID %d\n", cid); + + if (unlikely(elem->message.data.cfc_del_event.error)) { + BNX2X_ERR("got delete ramrod for CNIC CID %d with error!\n", + cid); + bnx2x_panic_dump(bp); + } + bnx2x_cnic_cfc_comp(bp, cid); + return 0; +} +#endif + +static void bnx2x_eq_int(struct bnx2x *bp) +{ + u16 hw_cons, sw_cons, sw_prod; + union event_ring_elem *elem; + u32 cid; + u8 opcode; + int spqe_cnt = 0; + + hw_cons = le16_to_cpu(*bp->eq_cons_sb); + + /* The hw_cos range is 1-255, 257 - the sw_cons range is 0-254, 256. + * when we get the the next-page we nned to adjust so the loop + * condition below will be met. The next element is the size of a + * regular element and hence incrementing by 1 + */ + if ((hw_cons & EQ_DESC_MAX_PAGE) == EQ_DESC_MAX_PAGE) + hw_cons++; + + /* This function may never run in parralel with itself for a + * specific bp, thus there is no need in "paired" read memory + * barrier here. + */ + sw_cons = bp->eq_cons; + sw_prod = bp->eq_prod; + + DP(BNX2X_MSG_SP, "EQ: hw_cons %u sw_cons %u bp->spq_left %u\n", + hw_cons, sw_cons, atomic_read(&bp->spq_left)); + + for (; sw_cons != hw_cons; + sw_prod = NEXT_EQ_IDX(sw_prod), sw_cons = NEXT_EQ_IDX(sw_cons)) { + + + elem = &bp->eq_ring[EQ_DESC(sw_cons)]; + + cid = SW_CID(elem->message.data.cfc_del_event.cid); + opcode = elem->message.opcode; + + + /* handle eq element */ + switch (opcode) { + case EVENT_RING_OPCODE_STAT_QUERY: + DP(NETIF_MSG_TIMER, "got statistics comp event\n"); + /* nothing to do with stats comp */ + continue; + + case EVENT_RING_OPCODE_CFC_DEL: + /* handle according to cid range */ + /* + * we may want to verify here that the bp state is + * HALTING + */ + DP(NETIF_MSG_IFDOWN, + "got delete ramrod for MULTI[%d]\n", cid); +#ifdef BCM_CNIC + if (!bnx2x_cnic_handle_cfc_del(bp, cid, elem)) + goto next_spqe; +#endif + bnx2x_fp(bp, cid, state) = + BNX2X_FP_STATE_CLOSED; + + goto next_spqe; + } + + switch (opcode | bp->state) { + case (EVENT_RING_OPCODE_FUNCTION_START | + BNX2X_STATE_OPENING_WAIT4_PORT): + DP(NETIF_MSG_IFUP, "got setup ramrod\n"); + bp->state = BNX2X_STATE_FUNC_STARTED; + break; + + case (EVENT_RING_OPCODE_FUNCTION_STOP | + BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFDOWN, "got halt ramrod\n"); + bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; + break; - /* look for changed bits */ - u32 asserted = attn_bits & ~attn_ack & ~attn_state; - u32 deasserted = ~attn_bits & attn_ack & attn_state; + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_OPEN): + case (EVENT_RING_OPCODE_SET_MAC | BNX2X_STATE_DIAG): + DP(NETIF_MSG_IFUP, "got set mac ramrod\n"); + bp->set_mac_pending = 0; + break; - DP(NETIF_MSG_HW, - "attn_bits %x attn_ack %x asserted %x deasserted %x\n", - attn_bits, attn_ack, asserted, deasserted); + case (EVENT_RING_OPCODE_SET_MAC | + BNX2X_STATE_CLOSING_WAIT4_HALT): + DP(NETIF_MSG_IFDOWN, "got (un)set mac ramrod\n"); + bp->set_mac_pending = 0; + break; + default: + /* unknown event log error and continue */ + BNX2X_ERR("Unknown EQ event %d\n", + elem->message.opcode); + } +next_spqe: + spqe_cnt++; + } /* for */ - if (~(attn_bits ^ attn_ack) & (attn_bits ^ attn_state)) - BNX2X_ERR("BAD attention state\n"); + smp_mb__before_atomic_inc(); + atomic_add(spqe_cnt, &bp->spq_left); - /* handle bits that were raised */ - if (asserted) - bnx2x_attn_int_asserted(bp, asserted); + bp->eq_cons = sw_cons; + bp->eq_prod = sw_prod; + /* Make sure that above mem writes were issued towards the memory */ + smp_wmb(); - if (deasserted) - bnx2x_attn_int_deasserted(bp, deasserted); + /* update producer */ + bnx2x_update_eq_prod(bp, bp->eq_prod); } static void bnx2x_sp_task(struct work_struct *work) @@ -2589,31 +3704,29 @@ static void bnx2x_sp_task(struct work_struct *work) DP(NETIF_MSG_INTR, "got a slowpath interrupt (status 0x%x)\n", status); /* HW attentions */ - if (status & 0x1) { + if (status & BNX2X_DEF_SB_ATT_IDX) { bnx2x_attn_int(bp); - status &= ~0x1; + status &= ~BNX2X_DEF_SB_ATT_IDX; } - /* CStorm events: STAT_QUERY */ - if (status & 0x2) { - DP(BNX2X_MSG_SP, "CStorm events: STAT_QUERY\n"); - status &= ~0x2; + /* SP events: STAT_QUERY and others */ + if (status & BNX2X_DEF_SB_IDX) { + + /* Handle EQ completions */ + bnx2x_eq_int(bp); + + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, + le16_to_cpu(bp->def_idx), IGU_INT_NOP, 1); + + status &= ~BNX2X_DEF_SB_IDX; } if (unlikely(status)) DP(NETIF_MSG_INTR, "got an unknown interrupt! (status 0x%x)\n", status); - bnx2x_ack_sb(bp, DEF_SB_ID, ATTENTION_ID, le16_to_cpu(bp->def_att_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, USTORM_ID, le16_to_cpu(bp->def_u_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, CSTORM_ID, le16_to_cpu(bp->def_c_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, XSTORM_ID, le16_to_cpu(bp->def_x_idx), - IGU_INT_NOP, 1); - bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, le16_to_cpu(bp->def_t_idx), - IGU_INT_ENABLE, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, ATTENTION_ID, + le16_to_cpu(bp->def_att_idx), IGU_INT_ENABLE, 1); } irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) @@ -2627,7 +3740,8 @@ irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) return IRQ_HANDLED; } - bnx2x_ack_sb(bp, DEF_SB_ID, TSTORM_ID, 0, IGU_INT_DISABLE, 0); + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, + IGU_INT_DISABLE, 0); #ifdef BNX2X_STOP_ON_ERROR if (unlikely(bp->panic)) @@ -2671,7 +3785,7 @@ static void bnx2x_timer(unsigned long data) } if (!BP_NOMCP(bp)) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); u32 drv_pulse; u32 mcp_pulse; @@ -2679,9 +3793,9 @@ static void bnx2x_timer(unsigned long data) bp->fw_drv_pulse_wr_seq &= DRV_PULSE_SEQ_MASK; /* TBD - add SYSTEM_TIME */ drv_pulse = bp->fw_drv_pulse_wr_seq; - SHMEM_WR(bp, func_mb[func].drv_pulse_mb, drv_pulse); + SHMEM_WR(bp, func_mb[mb_idx].drv_pulse_mb, drv_pulse); - mcp_pulse = (SHMEM_RD(bp, func_mb[func].mcp_pulse_mb) & + mcp_pulse = (SHMEM_RD(bp, func_mb[mb_idx].mcp_pulse_mb) & MCP_PULSE_SEQ_MASK); /* The delta between driver pulse and mcp response * should be 1 (before mcp response) or 0 (after mcp response) @@ -2709,324 +3823,310 @@ static void bnx2x_timer(unsigned long data) * nic init service functions */ -static void bnx2x_zero_sb(struct bnx2x *bp, int sb_id) +static inline void bnx2x_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) { - int port = BP_PORT(bp); + u32 i; + if (!(len%4) && !(addr%4)) + for (i = 0; i < len; i += 4) + REG_WR(bp, addr + i, fill); + else + for (i = 0; i < len; i++) + REG_WR8(bp, addr + i, fill); - /* "CSTORM" */ - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), 0, - CSTORM_SB_STATUS_BLOCK_U_SIZE / 4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), 0, - CSTORM_SB_STATUS_BLOCK_C_SIZE / 4); } -void bnx2x_init_sb(struct bnx2x *bp, struct host_status_block *sb, - dma_addr_t mapping, int sb_id) +/* helper: writes FP SP data to FW - data_size in dwords */ +static inline void bnx2x_wr_fp_sb_data(struct bnx2x *bp, + int fw_sb_id, + u32 *sb_data_p, + u32 data_size) { - int port = BP_PORT(bp); - int func = BP_FUNC(bp); int index; - u64 section; + for (index = 0; index < data_size; index++) + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fw_sb_id) + + sizeof(u32)*index, + *(sb_data_p + index)); +} + +static inline void bnx2x_zero_fp_sb(struct bnx2x *bp, int fw_sb_id) +{ + u32 *sb_data_p; + u32 data_size = 0; + struct hc_status_block_data_e2 sb_data_e2; + struct hc_status_block_data_e1x sb_data_e1x; + + /* disable the function first */ + if (CHIP_IS_E2(bp)) { + memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2)); + sb_data_e2.common.p_func.pf_id = HC_FUNCTION_DISABLED; + sb_data_e2.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e2.common.p_func.vf_valid = false; + sb_data_p = (u32 *)&sb_data_e2; + data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32); + } else { + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_id = HC_FUNCTION_DISABLED; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); + } + bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); - /* USTORM */ - section = ((u64)mapping) + offsetof(struct host_status_block, - u_status_block); - sb->u_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_SB_HOST_SB_ADDR_U_OFFSET(port, sb_id)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_USB_FUNC_OFF + - CSTORM_SB_HOST_STATUS_BLOCK_U_OFFSET(port, sb_id), func); - - for (index = 0; index < HC_USTORM_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, index), 1); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_OFFSET(fw_sb_id), 0, + CSTORM_STATUS_BLOCK_SIZE); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SYNC_BLOCK_OFFSET(fw_sb_id), 0, + CSTORM_SYNC_BLOCK_SIZE); +} - /* CSTORM */ - section = ((u64)mapping) + offsetof(struct host_status_block, - c_status_block); - sb->c_status_block.status_block_id = sb_id; +/* helper: writes SP SB data to FW */ +static inline void bnx2x_wr_sp_sb_data(struct bnx2x *bp, + struct hc_sp_status_block_data *sp_sb_data) +{ + int func = BP_FUNC(bp); + int i; + for (i = 0; i < sizeof(struct hc_sp_status_block_data)/sizeof(u32); i++) + REG_WR(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + i*sizeof(u32), + *((u32 *)sp_sb_data + i)); +} + +static inline void bnx2x_zero_sp_sb(struct bnx2x *bp) +{ + int func = BP_FUNC(bp); + struct hc_sp_status_block_data sp_sb_data; + memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); + + sp_sb_data.p_func.pf_id = HC_FUNCTION_DISABLED; + sp_sb_data.p_func.vf_id = HC_FUNCTION_DISABLED; + sp_sb_data.p_func.vf_valid = false; - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_SB_HOST_SB_ADDR_C_OFFSET(port, sb_id)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + FP_CSB_FUNC_OFF + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id), func); + bnx2x_wr_sp_sb_data(bp, &sp_sb_data); - for (index = 0; index < HC_CSTORM_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, index), 1); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_OFFSET(func), 0, + CSTORM_SP_STATUS_BLOCK_SIZE); + bnx2x_fill(bp, BAR_CSTRORM_INTMEM + + CSTORM_SP_SYNC_BLOCK_OFFSET(func), 0, + CSTORM_SP_SYNC_BLOCK_SIZE); - bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); } -static void bnx2x_zero_def_sb(struct bnx2x *bp) + +static inline +void bnx2x_setup_ndsb_state_machine(struct hc_status_block_sm *hc_sm, + int igu_sb_id, int igu_seg_id) { - int func = BP_FUNC(bp); + hc_sm->igu_sb_id = igu_sb_id; + hc_sm->igu_seg_id = igu_seg_id; + hc_sm->timer_value = 0xFF; + hc_sm->time_to_expire = 0xFFFFFFFF; +} + +void bnx2x_init_sb(struct bnx2x *bp, dma_addr_t mapping, int vfid, + u8 vf_valid, int fw_sb_id, int igu_sb_id) +{ + int igu_seg_id; + + struct hc_status_block_data_e2 sb_data_e2; + struct hc_status_block_data_e1x sb_data_e1x; + struct hc_status_block_sm *hc_sm_p; + struct hc_index_data *hc_index_p; + int data_size; + u32 *sb_data_p; + + if (CHIP_INT_MODE_IS_BC(bp)) + igu_seg_id = HC_SEG_ACCESS_NORM; + else + igu_seg_id = IGU_SEG_ACCESS_NORM; + + bnx2x_zero_fp_sb(bp, fw_sb_id); + + if (CHIP_IS_E2(bp)) { + memset(&sb_data_e2, 0, sizeof(struct hc_status_block_data_e2)); + sb_data_e2.common.p_func.pf_id = BP_FUNC(bp); + sb_data_e2.common.p_func.vf_id = vfid; + sb_data_e2.common.p_func.vf_valid = vf_valid; + sb_data_e2.common.p_func.vnic_id = BP_VN(bp); + sb_data_e2.common.same_igu_sb_1b = true; + sb_data_e2.common.host_sb_addr.hi = U64_HI(mapping); + sb_data_e2.common.host_sb_addr.lo = U64_LO(mapping); + hc_sm_p = sb_data_e2.common.state_machine; + hc_index_p = sb_data_e2.index_data; + sb_data_p = (u32 *)&sb_data_e2; + data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32); + } else { + memset(&sb_data_e1x, 0, + sizeof(struct hc_status_block_data_e1x)); + sb_data_e1x.common.p_func.pf_id = BP_FUNC(bp); + sb_data_e1x.common.p_func.vf_id = 0xff; + sb_data_e1x.common.p_func.vf_valid = false; + sb_data_e1x.common.p_func.vnic_id = BP_VN(bp); + sb_data_e1x.common.same_igu_sb_1b = true; + sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping); + sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping); + hc_sm_p = sb_data_e1x.common.state_machine; + hc_index_p = sb_data_e1x.index_data; + sb_data_p = (u32 *)&sb_data_e1x; + data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32); + } + + bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_RX_ID], + igu_sb_id, igu_seg_id); + bnx2x_setup_ndsb_state_machine(&hc_sm_p[SM_TX_ID], + igu_sb_id, igu_seg_id); + + DP(NETIF_MSG_HW, "Init FW SB %d\n", fw_sb_id); + + /* write indecies to HW */ + bnx2x_wr_fp_sb_data(bp, fw_sb_id, sb_data_p, data_size); +} - bnx2x_init_fill(bp, TSEM_REG_FAST_MEMORY + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct tstorm_def_status_block)/4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), 0, - sizeof(struct cstorm_def_status_block_u)/4); - bnx2x_init_fill(bp, CSEM_REG_FAST_MEMORY + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), 0, - sizeof(struct cstorm_def_status_block_c)/4); - bnx2x_init_fill(bp, XSEM_REG_FAST_MEMORY + - XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), 0, - sizeof(struct xstorm_def_status_block)/4); +static void bnx2x_update_coalesce_sb_index(struct bnx2x *bp, u16 fw_sb_id, + u8 sb_index, u8 disable, u16 usec) +{ + int port = BP_PORT(bp); + u8 ticks = usec / BNX2X_BTR; + + storm_memset_hc_timeout(bp, port, fw_sb_id, sb_index, ticks); + + disable = disable ? 1 : (usec ? 0 : 1); + storm_memset_hc_disable(bp, port, fw_sb_id, sb_index, disable); } -static void bnx2x_init_def_sb(struct bnx2x *bp, - struct host_def_status_block *def_sb, - dma_addr_t mapping, int sb_id) +static void bnx2x_update_coalesce_sb(struct bnx2x *bp, u16 fw_sb_id, + u16 tx_usec, u16 rx_usec) { + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, U_SB_ETH_RX_CQ_INDEX, + false, rx_usec); + bnx2x_update_coalesce_sb_index(bp, fw_sb_id, C_SB_ETH_TX_CQ_INDEX, + false, tx_usec); +} + +static void bnx2x_init_def_sb(struct bnx2x *bp) +{ + struct host_sp_status_block *def_sb = bp->def_status_blk; + dma_addr_t mapping = bp->def_status_blk_mapping; + int igu_sp_sb_index; + int igu_seg_id; int port = BP_PORT(bp); int func = BP_FUNC(bp); - int index, val, reg_offset; + int reg_offset; u64 section; + int index; + struct hc_sp_status_block_data sp_sb_data; + memset(&sp_sb_data, 0, sizeof(struct hc_sp_status_block_data)); + + if (CHIP_INT_MODE_IS_BC(bp)) { + igu_sp_sb_index = DEF_SB_IGU_ID; + igu_seg_id = HC_SEG_ACCESS_DEF; + } else { + igu_sp_sb_index = bp->igu_dsb_id; + igu_seg_id = IGU_SEG_ACCESS_DEF; + } /* ATTN */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, + section = ((u64)mapping) + offsetof(struct host_sp_status_block, atten_status_block); - def_sb->atten_status_block.status_block_id = sb_id; + def_sb->atten_status_block.status_block_id = igu_sp_sb_index; bp->attn_state = 0; reg_offset = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); - for (index = 0; index < MAX_DYNAMIC_ATTN_GRPS; index++) { - bp->attn_group[index].sig[0] = REG_RD(bp, - reg_offset + 0x10*index); - bp->attn_group[index].sig[1] = REG_RD(bp, - reg_offset + 0x4 + 0x10*index); - bp->attn_group[index].sig[2] = REG_RD(bp, - reg_offset + 0x8 + 0x10*index); - bp->attn_group[index].sig[3] = REG_RD(bp, - reg_offset + 0xc + 0x10*index); + int sindex; + /* take care of sig[0]..sig[4] */ + for (sindex = 0; sindex < 4; sindex++) + bp->attn_group[index].sig[sindex] = + REG_RD(bp, reg_offset + sindex*0x4 + 0x10*index); + + if (CHIP_IS_E2(bp)) + /* + * enable5 is separate from the rest of the registers, + * and therefore the address skip is 4 + * and not 16 between the different groups + */ + bp->attn_group[index].sig[4] = REG_RD(bp, + reg_offset + 0x10 + 0x4*index); + else + bp->attn_group[index].sig[4] = 0; } - reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : - HC_REG_ATTN_MSG0_ADDR_L); - - REG_WR(bp, reg_offset, U64_LO(section)); - REG_WR(bp, reg_offset + 4, U64_HI(section)); + if (bp->common.int_block == INT_BLOCK_HC) { + reg_offset = (port ? HC_REG_ATTN_MSG1_ADDR_L : + HC_REG_ATTN_MSG0_ADDR_L); - reg_offset = (port ? HC_REG_ATTN_NUM_P1 : HC_REG_ATTN_NUM_P0); - - val = REG_RD(bp, reg_offset); - val |= sb_id; - REG_WR(bp, reg_offset, val); + REG_WR(bp, reg_offset, U64_LO(section)); + REG_WR(bp, reg_offset + 4, U64_HI(section)); + } else if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_L, U64_LO(section)); + REG_WR(bp, IGU_REG_ATTN_MSG_ADDR_H, U64_HI(section)); + } - /* USTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - u_def_status_block); - def_sb->u_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_DEF_SB_HOST_SB_ADDR_U_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_USB_FUNC_OFF + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_U_OFFSET(func), func); - - for (index = 0; index < HC_USTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HC_DISABLE_U_OFFSET(func, index), 1); + section = ((u64)mapping) + offsetof(struct host_sp_status_block, + sp_sb); - /* CSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - c_def_status_block); - def_sb->c_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_CSTRORM_INTMEM + - ((CSTORM_DEF_SB_HOST_SB_ADDR_C_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_CSTRORM_INTMEM + DEF_CSB_FUNC_OFF + - CSTORM_DEF_SB_HOST_STATUS_BLOCK_C_OFFSET(func), func); - - for (index = 0; index < HC_CSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_DEF_SB_HC_DISABLE_C_OFFSET(func, index), 1); + bnx2x_zero_sp_sb(bp); - /* TSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - t_def_status_block); - def_sb->t_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_TSTRORM_INTMEM + - ((TSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_TSTRORM_INTMEM + DEF_TSB_FUNC_OFF + - TSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); - - for (index = 0; index < HC_TSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_TSTRORM_INTMEM + - TSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); + sp_sb_data.host_sb_addr.lo = U64_LO(section); + sp_sb_data.host_sb_addr.hi = U64_HI(section); + sp_sb_data.igu_sb_id = igu_sp_sb_index; + sp_sb_data.igu_seg_id = igu_seg_id; + sp_sb_data.p_func.pf_id = func; + sp_sb_data.p_func.vnic_id = BP_VN(bp); + sp_sb_data.p_func.vf_id = 0xff; - /* XSTORM */ - section = ((u64)mapping) + offsetof(struct host_def_status_block, - x_def_status_block); - def_sb->x_def_status_block.status_block_id = sb_id; - - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func), U64_LO(section)); - REG_WR(bp, BAR_XSTRORM_INTMEM + - ((XSTORM_DEF_SB_HOST_SB_ADDR_OFFSET(func)) + 4), - U64_HI(section)); - REG_WR8(bp, BAR_XSTRORM_INTMEM + DEF_XSB_FUNC_OFF + - XSTORM_DEF_SB_HOST_STATUS_BLOCK_OFFSET(func), func); - - for (index = 0; index < HC_XSTORM_DEF_SB_NUM_INDICES; index++) - REG_WR16(bp, BAR_XSTRORM_INTMEM + - XSTORM_DEF_SB_HC_DISABLE_OFFSET(func, index), 1); + bnx2x_wr_sp_sb_data(bp, &sp_sb_data); bp->stats_pending = 0; bp->set_mac_pending = 0; - bnx2x_ack_sb(bp, sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + bnx2x_ack_sb(bp, bp->igu_dsb_id, USTORM_ID, 0, IGU_INT_ENABLE, 0); } void bnx2x_update_coalesce(struct bnx2x *bp) { - int port = BP_PORT(bp); int i; - for_each_queue(bp, i) { - int sb_id = bp->fp[i].sb_id; - - /* HC_INDEX_U_ETH_RX_CQ_CONS */ - REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_U_OFFSET(port, sb_id, - U_SB_ETH_RX_CQ_INDEX), - bp->rx_ticks/(4 * BNX2X_BTR)); - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_U_OFFSET(port, sb_id, - U_SB_ETH_RX_CQ_INDEX), - (bp->rx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); - - /* HC_INDEX_C_ETH_TX_CQ_CONS */ - REG_WR8(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id, - C_SB_ETH_TX_CQ_INDEX), - bp->tx_ticks/(4 * BNX2X_BTR)); - REG_WR16(bp, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, - C_SB_ETH_TX_CQ_INDEX), - (bp->tx_ticks/(4 * BNX2X_BTR)) ? 0 : 1); - } + for_each_queue(bp, i) + bnx2x_update_coalesce_sb(bp, bp->fp[i].fw_sb_id, + bp->rx_ticks, bp->tx_ticks); } static void bnx2x_init_sp_ring(struct bnx2x *bp) { - int func = BP_FUNC(bp); - spin_lock_init(&bp->spq_lock); + atomic_set(&bp->spq_left, MAX_SPQ_PENDING); - bp->spq_left = MAX_SPQ_PENDING; bp->spq_prod_idx = 0; bp->dsb_sp_prod = BNX2X_SP_DSB_INDEX; bp->spq_prod_bd = bp->spq; bp->spq_last_bd = bp->spq_prod_bd + MAX_SP_DESC_CNT; - - REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func), - U64_LO(bp->spq_mapping)); - REG_WR(bp, - XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PAGE_BASE_OFFSET(func) + 4, - U64_HI(bp->spq_mapping)); - - REG_WR(bp, XSEM_REG_FAST_MEMORY + XSTORM_SPQ_PROD_OFFSET(func), - bp->spq_prod_idx); } -static void bnx2x_init_context(struct bnx2x *bp) +static void bnx2x_init_eq_ring(struct bnx2x *bp) { int i; + for (i = 1; i <= NUM_EQ_PAGES; i++) { + union event_ring_elem *elem = + &bp->eq_ring[EQ_DESC_CNT_PAGE * i - 1]; - /* Rx */ - for_each_queue(bp, i) { - struct eth_context *context = bnx2x_sp(bp, context[i].eth); - struct bnx2x_fastpath *fp = &bp->fp[i]; - u8 cl_id = fp->cl_id; - - context->ustorm_st_context.common.sb_index_numbers = - BNX2X_RX_SB_INDEX_NUM; - context->ustorm_st_context.common.clientId = cl_id; - context->ustorm_st_context.common.status_block_id = fp->sb_id; - context->ustorm_st_context.common.flags = - (USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_MC_ALIGNMENT | - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS); - context->ustorm_st_context.common.statistics_counter_id = - cl_id; - context->ustorm_st_context.common.mc_alignment_log_size = - BNX2X_RX_ALIGN_SHIFT; - context->ustorm_st_context.common.bd_buff_size = - bp->rx_buf_size; - context->ustorm_st_context.common.bd_page_base_hi = - U64_HI(fp->rx_desc_mapping); - context->ustorm_st_context.common.bd_page_base_lo = - U64_LO(fp->rx_desc_mapping); - if (!fp->disable_tpa) { - context->ustorm_st_context.common.flags |= - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_TPA; - context->ustorm_st_context.common.sge_buff_size = - (u16)min_t(u32, SGE_PAGE_SIZE*PAGES_PER_SGE, - 0xffff); - context->ustorm_st_context.common.sge_page_base_hi = - U64_HI(fp->rx_sge_mapping); - context->ustorm_st_context.common.sge_page_base_lo = - U64_LO(fp->rx_sge_mapping); - - context->ustorm_st_context.common.max_sges_for_packet = - SGE_PAGE_ALIGN(bp->dev->mtu) >> SGE_PAGE_SHIFT; - context->ustorm_st_context.common.max_sges_for_packet = - ((context->ustorm_st_context.common. - max_sges_for_packet + PAGES_PER_SGE - 1) & - (~(PAGES_PER_SGE - 1))) >> PAGES_PER_SGE_SHIFT; - } - - context->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), - CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); - - context->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(HW_CID(bp, i), - CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); - } - - /* Tx */ - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - struct eth_context *context = - bnx2x_sp(bp, context[i].eth); - - context->cstorm_st_context.sb_index_number = - C_SB_ETH_TX_CQ_INDEX; - context->cstorm_st_context.status_block_id = fp->sb_id; - - context->xstorm_st_context.tx_bd_page_base_hi = - U64_HI(fp->tx_desc_mapping); - context->xstorm_st_context.tx_bd_page_base_lo = - U64_LO(fp->tx_desc_mapping); - context->xstorm_st_context.statistics_data = (fp->cl_id | - XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE); + elem->next_page.addr.hi = + cpu_to_le32(U64_HI(bp->eq_mapping + + BCM_PAGE_SIZE * (i % NUM_EQ_PAGES))); + elem->next_page.addr.lo = + cpu_to_le32(U64_LO(bp->eq_mapping + + BCM_PAGE_SIZE*(i % NUM_EQ_PAGES))); } + bp->eq_cons = 0; + bp->eq_prod = NUM_EQ_DESC; + bp->eq_cons_sb = BNX2X_EQ_INDEX; } static void bnx2x_init_ind_table(struct bnx2x *bp) @@ -3045,47 +4145,11 @@ static void bnx2x_init_ind_table(struct bnx2x *bp) bp->fp->cl_id + (i % bp->num_queues)); } -void bnx2x_set_client_config(struct bnx2x *bp) -{ - struct tstorm_eth_client_config tstorm_client = {0}; - int port = BP_PORT(bp); - int i; - - tstorm_client.mtu = bp->dev->mtu; - tstorm_client.config_flags = - (TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE | - TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE); -#ifdef BCM_VLAN - if (bp->rx_mode && bp->vlgrp && (bp->flags & HW_VLAN_RX_FLAG)) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_VLAN_REM_ENABLE; - DP(NETIF_MSG_IFUP, "vlan removal enabled\n"); - } -#endif - - for_each_queue(bp, i) { - tstorm_client.statistics_counter_id = bp->fp[i].cl_id; - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id), - ((u32 *)&tstorm_client)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, bp->fp[i].cl_id) + 4, - ((u32 *)&tstorm_client)[1]); - } - - DP(BNX2X_MSG_OFF, "tstorm_client: 0x%08x 0x%08x\n", - ((u32 *)&tstorm_client)[0], ((u32 *)&tstorm_client)[1]); -} - void bnx2x_set_storm_rx_mode(struct bnx2x *bp) { - struct tstorm_eth_mac_filter_config tstorm_mac_filter = {0}; int mode = bp->rx_mode; - int mask = bp->rx_mode_cl_mask; - int func = BP_FUNC(bp); - int port = BP_PORT(bp); - int i; + u16 cl_id; + /* All but management unicast packets should pass to the host as well */ u32 llh_mask = NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_BRCST | @@ -3093,28 +4157,32 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_VLAN | NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_NO_VLAN; - DP(NETIF_MSG_IFUP, "rx mode %d mask 0x%x\n", mode, mask); - switch (mode) { case BNX2X_RX_MODE_NONE: /* no Rx */ - tstorm_mac_filter.ucast_drop_all = mask; - tstorm_mac_filter.mcast_drop_all = mask; - tstorm_mac_filter.bcast_drop_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_ACCEPT_NONE); break; case BNX2X_RX_MODE_NORMAL: - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_MULTICAST); break; case BNX2X_RX_MODE_ALLMULTI: - tstorm_mac_filter.mcast_accept_all = mask; - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST); break; case BNX2X_RX_MODE_PROMISC: - tstorm_mac_filter.ucast_accept_all = mask; - tstorm_mac_filter.mcast_accept_all = mask; - tstorm_mac_filter.bcast_accept_all = mask; + cl_id = BP_L_ID(bp); + bnx2x_rxq_set_mac_filters(bp, cl_id, BNX2X_PROMISCUOUS_MODE); + /* pass management unicast packets as well */ llh_mask |= NIG_LLH0_BRB1_DRV_MASK_REG_LLH0_BRB1_DRV_MASK_UNCST; break; @@ -3125,262 +4193,64 @@ void bnx2x_set_storm_rx_mode(struct bnx2x *bp) } REG_WR(bp, - (port ? NIG_REG_LLH1_BRB1_DRV_MASK : NIG_REG_LLH0_BRB1_DRV_MASK), + BP_PORT(bp) ? NIG_REG_LLH1_BRB1_DRV_MASK : + NIG_REG_LLH0_BRB1_DRV_MASK, llh_mask); - for (i = 0; i < sizeof(struct tstorm_eth_mac_filter_config)/4; i++) { - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_MAC_FILTER_CONFIG_OFFSET(func) + i * 4, - ((u32 *)&tstorm_mac_filter)[i]); - -/* DP(NETIF_MSG_IFUP, "tstorm_mac_filter[%d]: 0x%08x\n", i, - ((u32 *)&tstorm_mac_filter)[i]); */ - } + DP(NETIF_MSG_IFUP, "rx mode %d\n" + "drop_ucast 0x%x\ndrop_mcast 0x%x\ndrop_bcast 0x%x\n" + "accp_ucast 0x%x\naccp_mcast 0x%x\naccp_bcast 0x%x\n", mode, + bp->mac_filters.ucast_drop_all, + bp->mac_filters.mcast_drop_all, + bp->mac_filters.bcast_drop_all, + bp->mac_filters.ucast_accept_all, + bp->mac_filters.mcast_accept_all, + bp->mac_filters.bcast_accept_all + ); - if (mode != BNX2X_RX_MODE_NONE) - bnx2x_set_client_config(bp); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); } static void bnx2x_init_internal_common(struct bnx2x *bp) { int i; - /* Zero this manually as its initialization is - currently missing in the initTool */ - for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_AGG_DATA_OFFSET + i * 4, 0); -} - -static void bnx2x_init_internal_port(struct bnx2x *bp) -{ - int port = BP_PORT(bp); - - REG_WR(bp, - BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_U_OFFSET(port), BNX2X_BTR); - REG_WR(bp, - BAR_CSTRORM_INTMEM + CSTORM_HC_BTR_C_OFFSET(port), BNX2X_BTR); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_HC_BTR_OFFSET(port), BNX2X_BTR); -} - -static void bnx2x_init_internal_func(struct bnx2x *bp) -{ - struct tstorm_eth_function_common_config tstorm_config = {0}; - struct stats_indication_flags stats_flags = {0}; - int port = BP_PORT(bp); - int func = BP_FUNC(bp); - int i, j; - u32 offset; - u16 max_agg_size; - - tstorm_config.config_flags = RSS_FLAGS(bp); - - if (is_multi(bp)) - tstorm_config.rss_result_mask = MULTI_MASK; - - /* Enable TPA if needed */ - if (bp->flags & TPA_ENABLE_FLAG) - tstorm_config.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_ENABLE_TPA; - - if (IS_E1HMF(bp)) - tstorm_config.config_flags |= - TSTORM_ETH_FUNCTION_COMMON_CONFIG_E1HOV_IN_CAM; - - tstorm_config.leading_client_id = BP_L_ID(bp); - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_FUNCTION_COMMON_CONFIG_OFFSET(func), - (*(u32 *)&tstorm_config)); - - bp->rx_mode = BNX2X_RX_MODE_NONE; /* no rx until link is up */ - bp->rx_mode_cl_mask = (1 << BP_L_ID(bp)); - bnx2x_set_storm_rx_mode(bp); + if (!CHIP_IS_E1(bp)) { - for_each_queue(bp, i) { - u8 cl_id = bp->fp[i].cl_id; - - /* reset xstorm per client statistics */ - offset = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct xstorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - - /* reset tstorm per client statistics */ - offset = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct tstorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - - /* reset ustorm per client statistics */ - offset = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cl_id); - for (j = 0; - j < sizeof(struct ustorm_per_client_stats) / 4; j++) - REG_WR(bp, offset + j*4, 0); - } - - /* Init statistics related context */ - stats_flags.collect_eth = 1; - - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_TSTRORM_INTMEM + TSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_USTRORM_INTMEM + USTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func), - ((u32 *)&stats_flags)[0]); - REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_STATS_FLAGS_OFFSET(func) + 4, - ((u32 *)&stats_flags)[1]); - - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); - - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_TSTRORM_INTMEM + - TSTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); - - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func), - U64_LO(bnx2x_sp_mapping(bp, fw_stats))); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_ETH_STATS_QUERY_ADDR_OFFSET(func) + 4, - U64_HI(bnx2x_sp_mapping(bp, fw_stats))); - - if (CHIP_IS_E1H(bp)) { + /* xstorm needs to know whether to add ovlan to packets or not, + * in switch-independent we'll write 0 to here... */ REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->mf_mode); REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->mf_mode); REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); + bp->mf_mode); REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNCTION_MODE_OFFSET, - IS_E1HMF(bp)); - - REG_WR16(bp, BAR_XSTRORM_INTMEM + XSTORM_E1HOV_OFFSET(func), - bp->e1hov); + bp->mf_mode); } - /* Init CQ ring mapping and aggregation size, the FW limit is 8 frags */ - max_agg_size = min_t(u32, (min_t(u32, 8, MAX_SKB_FRAGS) * - SGE_PAGE_SIZE * PAGES_PER_SGE), 0xffff); - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id), - U64_LO(fp->rx_comp_mapping)); - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, fp->cl_id) + 4, - U64_HI(fp->rx_comp_mapping)); - - /* Next page */ - REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id), - U64_LO(fp->rx_comp_mapping + BCM_PAGE_SIZE)); + /* Zero this manually as its initialization is + currently missing in the initTool */ + for (i = 0; i < (USTORM_AGG_DATA_SIZE >> 2); i++) REG_WR(bp, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, fp->cl_id) + 4, - U64_HI(fp->rx_comp_mapping + BCM_PAGE_SIZE)); - - REG_WR16(bp, BAR_USTRORM_INTMEM + - USTORM_MAX_AGG_SIZE_OFFSET(port, fp->cl_id), - max_agg_size); - } - - /* dropless flow control */ - if (CHIP_IS_E1H(bp)) { - struct ustorm_eth_rx_pause_data_e1h rx_pause = {0}; - - rx_pause.bd_thr_low = 250; - rx_pause.cqe_thr_low = 250; - rx_pause.cos = 1; - rx_pause.sge_thr_low = 0; - rx_pause.bd_thr_high = 350; - rx_pause.cqe_thr_high = 350; - rx_pause.sge_thr_high = 0; - - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - if (!fp->disable_tpa) { - rx_pause.sge_thr_low = 150; - rx_pause.sge_thr_high = 250; - } - - - offset = BAR_USTRORM_INTMEM + - USTORM_ETH_RING_PAUSE_DATA_OFFSET(port, - fp->cl_id); - for (j = 0; - j < sizeof(struct ustorm_eth_rx_pause_data_e1h)/4; - j++) - REG_WR(bp, offset + j*4, - ((u32 *)&rx_pause)[j]); - } - } - - memset(&(bp->cmng), 0, sizeof(struct cmng_struct_per_port)); - - /* Init rate shaping and fairness contexts */ - if (IS_E1HMF(bp)) { - int vn; - - /* During init there is no active link - Until link is up, set link rate to 10Gbps */ - bp->link_vars.line_speed = SPEED_10000; - bnx2x_init_port_minmax(bp); - - if (!BP_NOMCP(bp)) - bp->mf_config = - SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); - bnx2x_calc_vn_weight_sum(bp); - - for (vn = VN_0; vn < E1HVN_MAX; vn++) - bnx2x_init_vn_minmax(bp, 2*vn + port); - - /* Enable rate shaping and fairness */ - bp->cmng.flags.cmng_enables |= - CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN; - - } else { - /* rate shaping and fairness are disabled */ - DP(NETIF_MSG_IFUP, - "single function mode minmax will be disabled\n"); + USTORM_AGG_DATA_OFFSET + i * 4, 0); + if (CHIP_IS_E2(bp)) { + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_IGU_MODE_OFFSET, + CHIP_INT_MODE_IS_BC(bp) ? + HC_IGU_BC_MODE : HC_IGU_NBC_MODE); } +} - - /* Store cmng structures to internal memory */ - if (bp->port.pmf) - for (i = 0; i < sizeof(struct cmng_struct_per_port) / 4; i++) - REG_WR(bp, BAR_XSTRORM_INTMEM + - XSTORM_CMNG_PER_PORT_VARS_OFFSET(port) + i * 4, - ((u32 *)(&bp->cmng))[i]); +static void bnx2x_init_internal_port(struct bnx2x *bp) +{ + /* port */ } static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) { switch (load_code) { case FW_MSG_CODE_DRV_LOAD_COMMON: + case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: bnx2x_init_internal_common(bp); /* no break */ @@ -3389,7 +4259,8 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) /* no break */ case FW_MSG_CODE_DRV_LOAD_FUNCTION: - bnx2x_init_internal_func(bp); + /* internal memory per function is + initialized inside bnx2x_pf_init */ break; default: @@ -3398,43 +4269,63 @@ static void bnx2x_init_internal(struct bnx2x *bp, u32 load_code) } } +static void bnx2x_init_fp_sb(struct bnx2x *bp, int fp_idx) +{ + struct bnx2x_fastpath *fp = &bp->fp[fp_idx]; + + fp->state = BNX2X_FP_STATE_CLOSED; + + fp->index = fp->cid = fp_idx; + fp->cl_id = BP_L_ID(bp) + fp_idx; + fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE; + fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE; + /* qZone id equals to FW (per path) client id */ + fp->cl_qzone_id = fp->cl_id + + BP_PORT(bp)*(CHIP_IS_E2(bp) ? ETH_MAX_RX_CLIENTS_E2 : + ETH_MAX_RX_CLIENTS_E1H); + /* init shortcut */ + fp->ustorm_rx_prods_offset = CHIP_IS_E2(bp) ? + USTORM_RX_PRODS_E2_OFFSET(fp->cl_qzone_id) : + USTORM_RX_PRODS_E1X_OFFSET(BP_PORT(bp), fp->cl_id); + /* Setup SB indicies */ + fp->rx_cons_sb = BNX2X_RX_SB_INDEX; + fp->tx_cons_sb = BNX2X_TX_SB_INDEX; + + DP(NETIF_MSG_IFUP, "queue[%d]: bnx2x_init_sb(%p,%p) " + "cl_id %d fw_sb %d igu_sb %d\n", + fp_idx, bp, fp->status_blk.e1x_sb, fp->cl_id, fp->fw_sb_id, + fp->igu_sb_id); + bnx2x_init_sb(bp, fp->status_blk_mapping, BNX2X_VF_ID_INVALID, false, + fp->fw_sb_id, fp->igu_sb_id); + + bnx2x_update_fpsb_idx(fp); +} + void bnx2x_nic_init(struct bnx2x *bp, u32 load_code) { int i; - for_each_queue(bp, i) { - struct bnx2x_fastpath *fp = &bp->fp[i]; - - fp->bp = bp; - fp->state = BNX2X_FP_STATE_CLOSED; - fp->index = i; - fp->cl_id = BP_L_ID(bp) + i; + for_each_queue(bp, i) + bnx2x_init_fp_sb(bp, i); #ifdef BCM_CNIC - fp->sb_id = fp->cl_id + 1; -#else - fp->sb_id = fp->cl_id; + + bnx2x_init_sb(bp, bp->cnic_sb_mapping, + BNX2X_VF_ID_INVALID, false, + CNIC_SB_ID(bp), CNIC_IGU_SB_ID(bp)); + #endif - DP(NETIF_MSG_IFUP, - "queue[%d]: bnx2x_init_sb(%p,%p) cl_id %d sb %d\n", - i, bp, fp->status_blk, fp->cl_id, fp->sb_id); - bnx2x_init_sb(bp, fp->status_blk, fp->status_blk_mapping, - fp->sb_id); - bnx2x_update_fpsb_idx(fp); - } /* ensure status block indices were read */ rmb(); - - bnx2x_init_def_sb(bp, bp->def_status_blk, bp->def_status_blk_mapping, - DEF_SB_ID); + bnx2x_init_def_sb(bp); bnx2x_update_dsb_idx(bp); - bnx2x_update_coalesce(bp); bnx2x_init_rx_rings(bp); - bnx2x_init_tx_ring(bp); + bnx2x_init_tx_rings(bp); bnx2x_init_sp_ring(bp); - bnx2x_init_context(bp); + bnx2x_init_eq_ring(bp); bnx2x_init_internal(bp, load_code); + bnx2x_pf_init(bp); bnx2x_init_ind_table(bp); bnx2x_stats_init(bp); @@ -3495,7 +4386,6 @@ static int bnx2x_gunzip_init(struct bnx2x *bp) static void bnx2x_gunzip_end(struct bnx2x *bp) { kfree(bp->strm->workspace); - kfree(bp->strm); bp->strm = NULL; @@ -3593,8 +4483,6 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) else factor = 1; - DP(NETIF_MSG_HW, "start part1\n"); - /* Disable inputs of parser neighbor blocks */ REG_WR(bp, TSDM_REG_ENABLE_IN1, 0x0); REG_WR(bp, TCM_REG_PRS_IFEN, 0x0); @@ -3731,9 +4619,19 @@ static int bnx2x_int_mem_test(struct bnx2x *bp) static void enable_blocks_attention(struct bnx2x *bp) { REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0); - REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0x40); + else + REG_WR(bp, PXP_REG_PXP_INT_MASK_1, 0); REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); REG_WR(bp, CFC_REG_CFC_INT_MASK, 0); + /* + * mask read length error interrupts in brb for parser + * (parsing unit and 'checksum and crc' unit) + * these errors are legal (PU reads fixed length and CAC can cause + * read length error on truncated packets) + */ + REG_WR(bp, BRB1_REG_BRB1_INT_MASK, 0xFC00); REG_WR(bp, QM_REG_QM_INT_MASK, 0); REG_WR(bp, TM_REG_TM_INT_MASK, 0); REG_WR(bp, XSDM_REG_XSDM_INT_MASK_0, 0); @@ -3752,8 +4650,16 @@ static void enable_blocks_attention(struct bnx2x *bp) REG_WR(bp, CCM_REG_CCM_INT_MASK, 0); /* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_0, 0); */ /* REG_WR(bp, CSEM_REG_CSEM_INT_MASK_1, 0); */ + if (CHIP_REV_IS_FPGA(bp)) REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x580000); + else if (CHIP_IS_E2(bp)) + REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, + (PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF + | PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT + | PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN + | PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED + | PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED)); else REG_WR(bp, PXP2_REG_PXP2_INT_MASK_0, 0x480000); REG_WR(bp, TSDM_REG_TSDM_INT_MASK_0, 0); @@ -3771,42 +4677,41 @@ static const struct { u32 addr; u32 mask; } bnx2x_parity_mask[] = { - {PXP_REG_PXP_PRTY_MASK, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, - {PXP2_REG_PXP2_PRTY_MASK_1, 0xffffffff}, - {HC_REG_HC_PRTY_MASK, 0xffffffff}, - {MISC_REG_MISC_PRTY_MASK, 0xffffffff}, - {QM_REG_QM_PRTY_MASK, 0x0}, - {DORQ_REG_DORQ_PRTY_MASK, 0x0}, + {PXP_REG_PXP_PRTY_MASK, 0x3ffffff}, + {PXP2_REG_PXP2_PRTY_MASK_0, 0xffffffff}, + {PXP2_REG_PXP2_PRTY_MASK_1, 0x7f}, + {HC_REG_HC_PRTY_MASK, 0x7}, + {MISC_REG_MISC_PRTY_MASK, 0x1}, + {QM_REG_QM_PRTY_MASK, 0x0}, + {DORQ_REG_DORQ_PRTY_MASK, 0x0}, {GRCBASE_UPB + PB_REG_PB_PRTY_MASK, 0x0}, {GRCBASE_XPB + PB_REG_PB_PRTY_MASK, 0x0}, - {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ - {CDU_REG_CDU_PRTY_MASK, 0x0}, - {CFC_REG_CFC_PRTY_MASK, 0x0}, - {DBG_REG_DBG_PRTY_MASK, 0x0}, - {DMAE_REG_DMAE_PRTY_MASK, 0x0}, - {BRB1_REG_BRB1_PRTY_MASK, 0x0}, - {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ - {TSDM_REG_TSDM_PRTY_MASK, 0x18},/* bit 3,4 */ - {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {USDM_REG_USDM_PRTY_MASK, 0x38},/* bit 3,4,5 */ - {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ - {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, - {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, - {USEM_REG_USEM_PRTY_MASK_0, 0x0}, - {USEM_REG_USEM_PRTY_MASK_1, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, - {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, - {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} + {SRC_REG_SRC_PRTY_MASK, 0x4}, /* bit 2 */ + {CDU_REG_CDU_PRTY_MASK, 0x0}, + {CFC_REG_CFC_PRTY_MASK, 0x0}, + {DBG_REG_DBG_PRTY_MASK, 0x0}, + {DMAE_REG_DMAE_PRTY_MASK, 0x0}, + {BRB1_REG_BRB1_PRTY_MASK, 0x0}, + {PRS_REG_PRS_PRTY_MASK, (1<<6)},/* bit 6 */ + {TSDM_REG_TSDM_PRTY_MASK, 0x18}, /* bit 3,4 */ + {CSDM_REG_CSDM_PRTY_MASK, 0x8}, /* bit 3 */ + {USDM_REG_USDM_PRTY_MASK, 0x38}, /* bit 3,4,5 */ + {XSDM_REG_XSDM_PRTY_MASK, 0x8}, /* bit 3 */ + {TSEM_REG_TSEM_PRTY_MASK_0, 0x0}, + {TSEM_REG_TSEM_PRTY_MASK_1, 0x0}, + {USEM_REG_USEM_PRTY_MASK_0, 0x0}, + {USEM_REG_USEM_PRTY_MASK_1, 0x0}, + {CSEM_REG_CSEM_PRTY_MASK_0, 0x0}, + {CSEM_REG_CSEM_PRTY_MASK_1, 0x0}, + {XSEM_REG_XSEM_PRTY_MASK_0, 0x0}, + {XSEM_REG_XSEM_PRTY_MASK_1, 0x0} }; static void enable_blocks_parity(struct bnx2x *bp) { - int i, mask_arr_len = - sizeof(bnx2x_parity_mask)/(sizeof(bnx2x_parity_mask[0])); + int i; - for (i = 0; i < mask_arr_len; i++) + for (i = 0; i < ARRAY_SIZE(bnx2x_parity_mask); i++) REG_WR(bp, bnx2x_parity_mask[i].addr, bnx2x_parity_mask[i].mask); } @@ -3862,17 +4767,12 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) */ else if (val == SHARED_HW_CFG_FAN_FAILURE_PHY_TYPE) for (port = PORT_0; port < PORT_MAX; port++) { - u32 phy_type = - SHMEM_RD(bp, dev_info.port_hw_config[port]. - external_phy_config) & - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; is_required |= - ((phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101) || - (phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) || - (phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481)); + bnx2x_fan_failure_det_req( + bp, + bp->common.shmem_base, + bp->common.shmem2_base, + port); } DP(NETIF_MSG_HW, "fan detection setting: %d\n", is_required); @@ -3880,42 +4780,113 @@ static void bnx2x_setup_fan_failure_detection(struct bnx2x *bp) if (is_required == 0) return; - /* Fan failure is indicated by SPIO 5 */ - bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5, - MISC_REGISTERS_SPIO_INPUT_HI_Z); + /* Fan failure is indicated by SPIO 5 */ + bnx2x_set_spio(bp, MISC_REGISTERS_SPIO_5, + MISC_REGISTERS_SPIO_INPUT_HI_Z); + + /* set to active low mode */ + val = REG_RD(bp, MISC_REG_SPIO_INT); + val |= ((1 << MISC_REGISTERS_SPIO_5) << + MISC_REGISTERS_SPIO_INT_OLD_SET_POS); + REG_WR(bp, MISC_REG_SPIO_INT, val); + + /* enable interrupt to signal the IGU */ + val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN); + val |= (1 << MISC_REGISTERS_SPIO_5); + REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); +} + +static void bnx2x_pretend_func(struct bnx2x *bp, u8 pretend_func_num) +{ + u32 offset = 0; + + if (CHIP_IS_E1(bp)) + return; + if (CHIP_IS_E1H(bp) && (pretend_func_num >= E1H_FUNC_MAX)) + return; + + switch (BP_ABS_FUNC(bp)) { + case 0: + offset = PXP2_REG_PGL_PRETEND_FUNC_F0; + break; + case 1: + offset = PXP2_REG_PGL_PRETEND_FUNC_F1; + break; + case 2: + offset = PXP2_REG_PGL_PRETEND_FUNC_F2; + break; + case 3: + offset = PXP2_REG_PGL_PRETEND_FUNC_F3; + break; + case 4: + offset = PXP2_REG_PGL_PRETEND_FUNC_F4; + break; + case 5: + offset = PXP2_REG_PGL_PRETEND_FUNC_F5; + break; + case 6: + offset = PXP2_REG_PGL_PRETEND_FUNC_F6; + break; + case 7: + offset = PXP2_REG_PGL_PRETEND_FUNC_F7; + break; + default: + return; + } + + REG_WR(bp, offset, pretend_func_num); + REG_RD(bp, offset); + DP(NETIF_MSG_HW, "Pretending to func %d\n", pretend_func_num); +} - /* set to active low mode */ - val = REG_RD(bp, MISC_REG_SPIO_INT); - val |= ((1 << MISC_REGISTERS_SPIO_5) << - MISC_REGISTERS_SPIO_INT_OLD_SET_POS); - REG_WR(bp, MISC_REG_SPIO_INT, val); +static void bnx2x_pf_disable(struct bnx2x *bp) +{ + u32 val = REG_RD(bp, IGU_REG_PF_CONFIGURATION); + val &= ~IGU_PF_CONF_FUNC_EN; - /* enable interrupt to signal the IGU */ - val = REG_RD(bp, MISC_REG_SPIO_EVENT_EN); - val |= (1 << MISC_REGISTERS_SPIO_5); - REG_WR(bp, MISC_REG_SPIO_EVENT_EN, val); + REG_WR(bp, IGU_REG_PF_CONFIGURATION, val); + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 0); + REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 0); } -static int bnx2x_init_common(struct bnx2x *bp) +static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) { u32 val, i; -#ifdef BCM_CNIC - u32 wb_write[2]; -#endif - DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_FUNC(bp)); + DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_ABS_FUNC(bp)); bnx2x_reset_common(bp); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc); bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1H(bp)) - REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp)); + if (!CHIP_IS_E1(bp)) + REG_WR(bp, MISC_REG_E1HMF_MODE, IS_MF(bp)); + + if (CHIP_IS_E2(bp)) { + u8 fid; + + /** + * 4-port mode or 2-port mode we need to turn of master-enable + * for everyone, after that, turn it back on for self. + * so, we disregard multi-function or not, and always disable + * for all functions on the given path, this means 0,2,4,6 for + * path 0 and 1,3,5,7 for path 1 + */ + for (fid = BP_PATH(bp); fid < E2_FUNC_MAX*2; fid += 2) { + if (fid == BP_ABS_FUNC(bp)) { + REG_WR(bp, + PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, + 1); + continue; + } - REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x100); - msleep(30); - REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0); + bnx2x_pretend_func(bp, fid); + /* clear pf enable */ + bnx2x_pf_disable(bp); + bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); + } + } bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE); if (CHIP_IS_E1(bp)) { @@ -3943,12 +4914,7 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1); #endif - REG_WR(bp, PXP2_REG_RQ_CDU_P_SIZE, 2); -#ifdef BCM_CNIC - REG_WR(bp, PXP2_REG_RQ_TM_P_SIZE, 5); - REG_WR(bp, PXP2_REG_RQ_QM_P_SIZE, 5); - REG_WR(bp, PXP2_REG_RQ_SRC_P_SIZE, 5); -#endif + bnx2x_ilt_init_page_size(bp, INITOP_SET); if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp)) REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x1); @@ -3967,9 +4933,65 @@ static int bnx2x_init_common(struct bnx2x *bp) return -EBUSY; } + /* Timers bug workaround E2 only. We need to set the entire ILT to + * have entries with value "0" and valid bit on. + * This needs to be done by the first PF that is loaded in a path + * (i.e. common phase) + */ + if (CHIP_IS_E2(bp)) { + struct ilt_client_info ilt_cli; + struct bnx2x_ilt ilt; + memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); + memset(&ilt, 0, sizeof(struct bnx2x_ilt)); + + /* initalize dummy TM client */ + ilt_cli.start = 0; + ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; + ilt_cli.client_num = ILT_CLIENT_TM; + + /* Step 1: set zeroes to all ilt page entries with valid bit on + * Step 2: set the timers first/last ilt entry to point + * to the entire range to prevent ILT range error for 3rd/4th + * vnic (this code assumes existance of the vnic) + * + * both steps performed by call to bnx2x_ilt_client_init_op() + * with dummy TM client + * + * we must use pretend since PXP2_REG_RQ_##blk##_FIRST_ILT + * and his brother are split registers + */ + bnx2x_pretend_func(bp, (BP_PATH(bp) + 6)); + bnx2x_ilt_client_init_op_ilt(bp, &ilt, &ilt_cli, INITOP_CLEAR); + bnx2x_pretend_func(bp, BP_ABS_FUNC(bp)); + + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN, BNX2X_PXP_DRAM_ALIGN); + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN_RD, BNX2X_PXP_DRAM_ALIGN); + REG_WR(bp, PXP2_REG_RQ_DRAM_ALIGN_SEL, 1); + } + + REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0); REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0); + if (CHIP_IS_E2(bp)) { + int factor = CHIP_REV_IS_EMUL(bp) ? 1000 : + (CHIP_REV_IS_FPGA(bp) ? 400 : 0); + bnx2x_init_block(bp, PGLUE_B_BLOCK, COMMON_STAGE); + + bnx2x_init_block(bp, ATC_BLOCK, COMMON_STAGE); + + /* let the HW do it's magic ... */ + do { + msleep(200); + val = REG_RD(bp, ATC_REG_ATC_INIT_DONE); + } while (factor-- && (val != 1)); + + if (val != 1) { + BNX2X_ERR("ATC_INIT failed\n"); + return -EBUSY; + } + } + bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE); /* clean the DMAE memory */ @@ -3988,20 +5010,12 @@ static int bnx2x_init_common(struct bnx2x *bp) bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE); -#ifdef BCM_CNIC - wb_write[0] = 0; - wb_write[1] = 0; - for (i = 0; i < 64; i++) { - REG_WR(bp, QM_REG_BASEADDR + i*4, 1024 * 4 * (i%16)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, wb_write, 2); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, COMMON_STAGE); + + /* QM queues pointers table */ + bnx2x_qm_init_ptr_table(bp, bp->qm_cid_count, INITOP_SET); - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, 1024*4*(i%16)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, - wb_write, 2); - } - } -#endif /* soft reset pulse */ REG_WR(bp, QM_REG_SOFT_RESET, 1); REG_WR(bp, QM_REG_SOFT_RESET, 0); @@ -4011,21 +5025,35 @@ static int bnx2x_init_common(struct bnx2x *bp) #endif bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE); - REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT); + REG_WR(bp, DORQ_REG_DPM_CID_OFST, BNX2X_DB_SHIFT); + if (!CHIP_REV_IS_SLOW(bp)) { /* enable hw interrupt from doorbell Q */ REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0); } bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE); + if (CHIP_MODE_IS_4_PORT(bp)) { + REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD, 248); + REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD, 328); + } + bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE); REG_WR(bp, PRS_REG_A_PRSU_20, 0xf); #ifndef BCM_CNIC /* set NIC mode */ REG_WR(bp, PRS_REG_NIC_MODE, 1); #endif - if (CHIP_IS_E1H(bp)) - REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp)); + if (!CHIP_IS_E1(bp)) + REG_WR(bp, PRS_REG_E1HOV_MODE, IS_MF(bp)); + + if (CHIP_IS_E2(bp)) { + /* Bit-map indicating which L2 hdrs may appear after the + basic Ethernet header */ + int has_ovlan = IS_MF(bp); + REG_WR(bp, PRS_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); + REG_WR(bp, PRS_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); + } bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE); @@ -4042,6 +5070,9 @@ static int bnx2x_init_common(struct bnx2x *bp) bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, COMMON_STAGE); + /* sync semi rtc */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR, 0x80000000); @@ -4052,9 +5083,16 @@ static int bnx2x_init_common(struct bnx2x *bp) bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE); + if (CHIP_IS_E2(bp)) { + int has_ovlan = IS_MF(bp); + REG_WR(bp, PBF_REG_HDRS_AFTER_BASIC, (has_ovlan ? 7 : 6)); + REG_WR(bp, PBF_REG_MUST_HAVE_HDRS, (has_ovlan ? 1 : 0)); + } + REG_WR(bp, SRC_REG_SOFT_RST, 1); for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) REG_WR(bp, i, random32()); + bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE); #ifdef BCM_CNIC REG_WR(bp, SRC_REG_KEYSEARCH_0, 0x63285672); @@ -4089,6 +5127,11 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, CFC_REG_DEBUG0, 0x20020000); bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE); + + if (CHIP_IS_E2(bp) && BP_NOMCP(bp)) + REG_WR(bp, IGU_REG_RESET_MEMORIES, 0x36); + + bnx2x_init_block(bp, IGU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE); @@ -4096,15 +5139,34 @@ static int bnx2x_init_common(struct bnx2x *bp) REG_WR(bp, 0x2814, 0xffffffff); REG_WR(bp, 0x3820, 0xffffffff); + if (CHIP_IS_E2(bp)) { + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_CONTROL_5, + (PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 | + PXPCS_TL_CONTROL_5_ERR_UNSPPORT)); + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_FUNC345_STAT, + (PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT4 | + PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT3 | + PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT2)); + REG_WR(bp, PCICFG_OFFSET + PXPCS_TL_FUNC678_STAT, + (PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT7 | + PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT6 | + PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5)); + } + bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE); bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE); - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp)); - REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp)); + if (!CHIP_IS_E1(bp)) { + REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_MF(bp)); + REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_MF(bp)); + } + if (CHIP_IS_E2(bp)) { + /* Bit-map indicating which L2 hdrs may appear after the + basic Ethernet header */ + REG_WR(bp, NIG_REG_P0_HDRS_AFTER_BASIC, (IS_MF(bp) ? 7 : 6)); } if (CHIP_REV_IS_SLOW(bp)) @@ -4128,28 +5190,22 @@ static int bnx2x_init_common(struct bnx2x *bp) } REG_WR(bp, CFC_REG_DEBUG0, 0); - /* read NIG statistic - to see if this is our first up since powerup */ - bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); - val = *bnx2x_sp(bp, wb_data[0]); + if (CHIP_IS_E1(bp)) { + /* read NIG statistic + to see if this is our first up since powerup */ + bnx2x_read_dmae(bp, NIG_REG_STAT2_BRB_OCTET, 2); + val = *bnx2x_sp(bp, wb_data[0]); - /* do internal memory self test */ - if ((CHIP_IS_E1(bp)) && (val == 0) && bnx2x_int_mem_test(bp)) { - BNX2X_ERR("internal mem self test failed\n"); - return -EBUSY; + /* do internal memory self test */ + if ((val == 0) && bnx2x_int_mem_test(bp)) { + BNX2X_ERR("internal mem self test failed\n"); + return -EBUSY; + } } - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - bp->port.need_hw_lock = 1; - break; - - default: - break; - } + bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, + bp->common.shmem_base, + bp->common.shmem2_base); bnx2x_setup_fan_failure_detection(bp); @@ -4161,16 +5217,30 @@ static int bnx2x_init_common(struct bnx2x *bp) enable_blocks_parity(bp); if (!BP_NOMCP(bp)) { - bnx2x_acquire_phy_lock(bp); - bnx2x_common_init_phy(bp, bp->common.shmem_base); - bnx2x_release_phy_lock(bp); + /* In E2 2-PORT mode, same ext phy is used for the two paths */ + if ((load_code == FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) || + CHIP_IS_E1x(bp)) { + u32 shmem_base[2], shmem2_base[2]; + shmem_base[0] = bp->common.shmem_base; + shmem2_base[0] = bp->common.shmem2_base; + if (CHIP_IS_E2(bp)) { + shmem_base[1] = + SHMEM2_RD(bp, other_shmem_base_addr); + shmem2_base[1] = + SHMEM2_RD(bp, other_shmem2_base_addr); + } + bnx2x_acquire_phy_lock(bp); + bnx2x_common_init_phy(bp, shmem_base, shmem2_base, + bp->common.chip_id); + bnx2x_release_phy_lock(bp); + } } else BNX2X_ERR("Bootcode is missing - can not initialize link\n"); return 0; } -static int bnx2x_init_port(struct bnx2x *bp) +static int bnx2x_init_hw_port(struct bnx2x *bp) { int port = BP_PORT(bp); int init_stage = port ? PORT1_STAGE : PORT0_STAGE; @@ -4184,14 +5254,23 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, PXP_BLOCK, init_stage); bnx2x_init_block(bp, PXP2_BLOCK, init_stage); + /* Timers bug workaround: disables the pf_master bit in pglue at + * common phase, we need to enable it here before any dmae access are + * attempted. Therefore we manually added the enable-master to the + * port phase (it also happens in the function phase) + */ + if (CHIP_IS_E2(bp)) + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); + bnx2x_init_block(bp, TCM_BLOCK, init_stage); bnx2x_init_block(bp, UCM_BLOCK, init_stage); bnx2x_init_block(bp, CCM_BLOCK, init_stage); bnx2x_init_block(bp, XCM_BLOCK, init_stage); -#ifdef BCM_CNIC - REG_WR(bp, QM_REG_CONNNUM_0 + port*4, 1024/16 - 1); + /* QM cid (connection) count */ + bnx2x_qm_init_cid_count(bp, bp->qm_cid_count, INITOP_SET); +#ifdef BCM_CNIC bnx2x_init_block(bp, TIMERS_BLOCK, init_stage); REG_WR(bp, TM_REG_LIN0_SCAN_TIME + port*4, 20); REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + port*4, 31); @@ -4199,29 +5278,41 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, DQ_BLOCK, init_stage); - bnx2x_init_block(bp, BRB1_BLOCK, init_stage); - if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) { - /* no pause for emulation and FPGA */ - low = 0; - high = 513; - } else { - if (IS_E1HMF(bp)) - low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); - else if (bp->dev->mtu > 4096) { - if (bp->flags & ONE_PORT_FLAG) - low = 160; - else { - val = bp->dev->mtu; - /* (24*1024 + val*4)/256 */ - low = 96 + (val/64) + ((val % 64) ? 1 : 0); - } - } else - low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); - high = low + 56; /* 14*1024/256 */ + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, init_stage); + + if (CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) { + bnx2x_init_block(bp, BRB1_BLOCK, init_stage); + if (CHIP_REV_IS_SLOW(bp) && CHIP_IS_E1(bp)) { + /* no pause for emulation and FPGA */ + low = 0; + high = 513; + } else { + if (IS_MF(bp)) + low = ((bp->flags & ONE_PORT_FLAG) ? 160 : 246); + else if (bp->dev->mtu > 4096) { + if (bp->flags & ONE_PORT_FLAG) + low = 160; + else { + val = bp->dev->mtu; + /* (24*1024 + val*4)/256 */ + low = 96 + (val/64) + + ((val % 64) ? 1 : 0); + } + } else + low = ((bp->flags & ONE_PORT_FLAG) ? 80 : 160); + high = low + 56; /* 14*1024/256 */ + } + REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); + REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); } - REG_WR(bp, BRB1_REG_PAUSE_LOW_THRESHOLD_0 + port*4, low); - REG_WR(bp, BRB1_REG_PAUSE_HIGH_THRESHOLD_0 + port*4, high); + if (CHIP_MODE_IS_4_PORT(bp)) { + REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 + port*8, 248); + REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 + port*8, 328); + REG_WR(bp, (BP_PORT(bp) ? BRB1_REG_MAC_GUARANTIED_1 : + BRB1_REG_MAC_GUARANTIED_0), 40); + } bnx2x_init_block(bp, PRS_BLOCK, init_stage); @@ -4234,24 +5325,28 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, USEM_BLOCK, init_stage); bnx2x_init_block(bp, CSEM_BLOCK, init_stage); bnx2x_init_block(bp, XSEM_BLOCK, init_stage); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, init_stage); bnx2x_init_block(bp, UPB_BLOCK, init_stage); bnx2x_init_block(bp, XPB_BLOCK, init_stage); bnx2x_init_block(bp, PBF_BLOCK, init_stage); - /* configure PBF to work without PAUSE mtu 9000 */ - REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); + if (!CHIP_IS_E2(bp)) { + /* configure PBF to work without PAUSE mtu 9000 */ + REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0); - /* update threshold */ - REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16)); - /* update init credit */ - REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22); + /* update threshold */ + REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, (9040/16)); + /* update init credit */ + REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, (9040/16) + 553 - 22); - /* probe changes */ - REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1); - msleep(5); - REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); + /* probe changes */ + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 1); + udelay(50); + REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0); + } #ifdef BCM_CNIC bnx2x_init_block(bp, SRCH_BLOCK, init_stage); @@ -4265,13 +5360,15 @@ static int bnx2x_init_port(struct bnx2x *bp) } bnx2x_init_block(bp, HC_BLOCK, init_stage); + bnx2x_init_block(bp, IGU_BLOCK, init_stage); + bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage); /* init aeu_mask_attn_func_0/1: * - SF mode: bits 3-7 are masked. only bits 0-2 are in use * - MF mode: bit 3 is masked. bits 0-2 are in use as in SF * bits 4-7 are used for "per vn group attention" */ REG_WR(bp, MISC_REG_AEU_MASK_ATTN_FUNC_0 + port*4, - (IS_E1HMF(bp) ? 0xF7 : 0x7)); + (IS_MF(bp) ? 0xF7 : 0x7)); bnx2x_init_block(bp, PXPCS_BLOCK, init_stage); bnx2x_init_block(bp, EMAC0_BLOCK, init_stage); @@ -4283,11 +5380,25 @@ static int bnx2x_init_port(struct bnx2x *bp) REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1); - if (CHIP_IS_E1H(bp)) { - /* 0x2 disable e1hov, 0x1 enable */ + if (!CHIP_IS_E1(bp)) { + /* 0x2 disable mf_ov, 0x1 enable */ REG_WR(bp, NIG_REG_LLH0_BRB1_DRV_MASK_MF + port*4, - (IS_E1HMF(bp) ? 0x1 : 0x2)); + (IS_MF(bp) ? 0x1 : 0x2)); + + if (CHIP_IS_E2(bp)) { + val = 0; + switch (bp->mf_mode) { + case MULTI_FUNCTION_SD: + val = 1; + break; + case MULTI_FUNCTION_SI: + val = 2; + break; + } + REG_WR(bp, (BP_PORT(bp) ? NIG_REG_LLH1_CLS_TYPE : + NIG_REG_LLH0_CLS_TYPE), val); + } { REG_WR(bp, NIG_REG_LLFC_ENABLE_0 + port*4, 0); REG_WR(bp, NIG_REG_LLFC_OUT_EN_0 + port*4, 0); @@ -4297,199 +5408,339 @@ static int bnx2x_init_port(struct bnx2x *bp) bnx2x_init_block(bp, MCP_BLOCK, init_stage); bnx2x_init_block(bp, DMAE_BLOCK, init_stage); - - switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - { - u32 swap_val, swap_override, aeu_gpio_mask, offset; - - bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, - MISC_REGISTERS_GPIO_INPUT_HI_Z, port); - - /* The GPIO should be swapped if the swap register is - set and active */ - swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); - swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); - - /* Select function upon port-swap configuration */ - if (port == 0) { - offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0; - } else { - offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0; - aeu_gpio_mask = (swap_val && swap_override) ? - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 : - AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1; - } - val = REG_RD(bp, offset); - /* add GPIO3 to group */ - val |= aeu_gpio_mask; - REG_WR(bp, offset, val); - } - bp->port.need_hw_lock = 1; - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - bp->port.need_hw_lock = 1; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - /* add SPIO 5 to group 0 */ - { + bp->port.need_hw_lock = bnx2x_hw_lock_required(bp, + bp->common.shmem_base, + bp->common.shmem2_base); + if (bnx2x_fan_failure_det_req(bp, bp->common.shmem_base, + bp->common.shmem2_base, port)) { u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0); val = REG_RD(bp, reg_addr); val |= AEU_INPUTS_ATTN_BITS_SPIO5; REG_WR(bp, reg_addr, val); - } - break; - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - bp->port.need_hw_lock = 1; - break; - default: - break; } - bnx2x__link_reset(bp); return 0; } -#define ILT_PER_FUNC (768/2) -#define FUNC_ILT_BASE(func) (func * ILT_PER_FUNC) -/* the phys address is shifted right 12 bits and has an added - 1=valid bit added to the 53rd bit - then since this is a wide register(TM) - we split it into two 32 bit writes - */ -#define ONCHIP_ADDR1(x) ((u32)(((u64)x >> 12) & 0xFFFFFFFF)) -#define ONCHIP_ADDR2(x) ((u32)((1 << 20) | ((u64)x >> 44))) -#define PXP_ONE_ILT(x) (((x) << 10) | x) -#define PXP_ILT_RANGE(f, l) (((l) << 10) | f) - -#ifdef BCM_CNIC -#define CNIC_ILT_LINES 127 -#define CNIC_CTX_PER_ILT 16 -#else -#define CNIC_ILT_LINES 0 -#endif - static void bnx2x_ilt_wr(struct bnx2x *bp, u32 index, dma_addr_t addr) { int reg; - if (CHIP_IS_E1H(bp)) - reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8; - else /* E1 */ + if (CHIP_IS_E1(bp)) reg = PXP2_REG_RQ_ONCHIP_AT + index*8; + else + reg = PXP2_REG_RQ_ONCHIP_AT_B0 + index*8; bnx2x_wb_wr(bp, reg, ONCHIP_ADDR1(addr), ONCHIP_ADDR2(addr)); } -static int bnx2x_init_func(struct bnx2x *bp) +static inline void bnx2x_igu_clear_sb(struct bnx2x *bp, u8 idu_sb_id) +{ + bnx2x_igu_clear_sb_gen(bp, idu_sb_id, true /*PF*/); +} + +static inline void bnx2x_clear_func_ilt(struct bnx2x *bp, u32 func) +{ + u32 i, base = FUNC_ILT_BASE(func); + for (i = base; i < base + ILT_PER_FUNC; i++) + bnx2x_ilt_wr(bp, i, 0); +} + +static int bnx2x_init_hw_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); + struct bnx2x_ilt *ilt = BP_ILT(bp); + u16 cdu_ilt_start; u32 addr, val; - int i; + u32 main_mem_base, main_mem_size, main_mem_prty_clr; + int i, main_mem_width; DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); /* set MSI reconfigure capability */ - addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); - val = REG_RD(bp, addr); - val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; - REG_WR(bp, addr, val); + if (bp->common.int_block == INT_BLOCK_HC) { + addr = (port ? HC_REG_CONFIG_1 : HC_REG_CONFIG_0); + val = REG_RD(bp, addr); + val |= HC_CONFIG_0_REG_MSI_ATTN_EN_0; + REG_WR(bp, addr, val); + } - i = FUNC_ILT_BASE(func); + ilt = BP_ILT(bp); + cdu_ilt_start = ilt->clients[ILT_CLIENT_CDU].start; - bnx2x_ilt_wr(bp, i, bnx2x_sp_mapping(bp, context)); - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, PXP2_REG_RQ_CDU_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_CDU_LAST_ILT, i + CNIC_ILT_LINES); - } else /* E1 */ - REG_WR(bp, PXP2_REG_PSWRQ_CDU0_L2P + func*4, - PXP_ILT_RANGE(i, i + CNIC_ILT_LINES)); + for (i = 0; i < L2_ILT_LINES(bp); i++) { + ilt->lines[cdu_ilt_start + i].page = + bp->context.vcxt + (ILT_PAGE_CIDS * i); + ilt->lines[cdu_ilt_start + i].page_mapping = + bp->context.cxt_mapping + (CDU_ILT_PAGE_SZ * i); + /* cdu ilt pages are allocated manually so there's no need to + set the size */ + } + bnx2x_ilt_init_op(bp, INITOP_SET); #ifdef BCM_CNIC - i += 1 + CNIC_ILT_LINES; - bnx2x_ilt_wr(bp, i, bp->timers_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_TM0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_TM_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_TM_LAST_ILT, i); - } + bnx2x_src_init_t2(bp, bp->t2, bp->t2_mapping, SRC_CONN_NUM); - i++; - bnx2x_ilt_wr(bp, i, bp->qm_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_QM0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_QM_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_QM_LAST_ILT, i); + /* T1 hash bits value determines the T1 number of entries */ + REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, SRC_HASH_BITS); +#endif + +#ifndef BCM_CNIC + /* set NIC mode */ + REG_WR(bp, PRS_REG_NIC_MODE, 1); +#endif /* BCM_CNIC */ + + if (CHIP_IS_E2(bp)) { + u32 pf_conf = IGU_PF_CONF_FUNC_EN; + + /* Turn on a single ISR mode in IGU if driver is going to use + * INT#x or MSI + */ + if (!(bp->flags & USING_MSIX_FLAG)) + pf_conf |= IGU_PF_CONF_SINGLE_ISR_EN; + /* + * Timers workaround bug: function init part. + * Need to wait 20msec after initializing ILT, + * needed to make sure there are no requests in + * one of the PXP internal queues with "old" ILT addresses + */ + msleep(20); + /* + * Master enable - Due to WB DMAE writes performed before this + * register is re-initialized as part of the regular function + * init + */ + REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER, 1); + /* Enable the function in IGU */ + REG_WR(bp, IGU_REG_PF_CONFIGURATION, pf_conf); } - i++; - bnx2x_ilt_wr(bp, i, bp->t1_mapping); - if (CHIP_IS_E1(bp)) - REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i)); - else { - REG_WR(bp, PXP2_REG_RQ_SRC_FIRST_ILT, i); - REG_WR(bp, PXP2_REG_RQ_SRC_LAST_ILT, i); + bp->dmae_ready = 1; + + bnx2x_init_block(bp, PGLUE_B_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E2(bp)) + REG_WR(bp, PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR, func); + + bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E2(bp)) { + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_PATH_ID_OFFSET, + BP_PATH(bp)); + REG_WR(bp, BAR_CSTRORM_INTMEM + CSTORM_PATH_ID_OFFSET, + BP_PATH(bp)); } - /* tell the searcher where the T2 table is */ - REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, 16*1024/64); + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, XSEM_4PORT_BLOCK, FUNC0_STAGE + func); - bnx2x_wb_wr(bp, SRC_REG_FIRSTFREE0 + port*16, - U64_LO(bp->t2_mapping), U64_HI(bp->t2_mapping)); + if (CHIP_IS_E2(bp)) + REG_WR(bp, QM_REG_PF_EN, 1); - bnx2x_wb_wr(bp, SRC_REG_LASTFREE0 + port*16, - U64_LO((u64)bp->t2_mapping + 16*1024 - 64), - U64_HI((u64)bp->t2_mapping + 16*1024 - 64)); + bnx2x_init_block(bp, QM_BLOCK, FUNC0_STAGE + func); - REG_WR(bp, SRC_REG_NUMBER_HASH_BITS0 + port*4, 10); -#endif + if (CHIP_MODE_IS_4_PORT(bp)) + bnx2x_init_block(bp, QM_4PORT_BLOCK, FUNC0_STAGE + func); - if (CHIP_IS_E1H(bp)) { - bnx2x_init_block(bp, MISC_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, UCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XCM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, TSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, USEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, CSEM_BLOCK, FUNC0_STAGE + func); - bnx2x_init_block(bp, XSEM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TIMERS_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DQ_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, BRB1_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, PRS_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, TSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, CSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, USDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XSDM_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, UPB_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, XPB_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, PBF_BLOCK, FUNC0_STAGE + func); + if (CHIP_IS_E2(bp)) + REG_WR(bp, PBF_REG_DISABLE_PF, 0); + bnx2x_init_block(bp, CDU_BLOCK, FUNC0_STAGE + func); + + bnx2x_init_block(bp, CFC_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E2(bp)) + REG_WR(bp, CFC_REG_WEAK_ENABLE_PF, 1); + + if (IS_MF(bp)) { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1); - REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov); + REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->mf_ov); } + bnx2x_init_block(bp, MISC_AEU_BLOCK, FUNC0_STAGE + func); + /* HC init per function */ - if (CHIP_IS_E1H(bp)) { + if (bp->common.int_block == INT_BLOCK_HC) { + if (CHIP_IS_E1H(bp)) { + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); + + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + } + bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); + + } else { + int num_segs, sb_idx, prod_offset; + REG_WR(bp, MISC_REG_AEU_GENERAL_ATTN_12 + func*4, 0); - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + if (CHIP_IS_E2(bp)) { + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0); + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); + } + + bnx2x_init_block(bp, IGU_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E2(bp)) { + int dsb_idx = 0; + /** + * Producer memory: + * E2 mode: address 0-135 match to the mapping memory; + * 136 - PF0 default prod; 137 - PF1 default prod; + * 138 - PF2 default prod; 139 - PF3 default prod; + * 140 - PF0 attn prod; 141 - PF1 attn prod; + * 142 - PF2 attn prod; 143 - PF3 attn prod; + * 144-147 reserved. + * + * E1.5 mode - In backward compatible mode; + * for non default SB; each even line in the memory + * holds the U producer and each odd line hold + * the C producer. The first 128 producers are for + * NDSB (PF0 - 0-31; PF1 - 32-63 and so on). The last 20 + * producers are for the DSB for each PF. + * Each PF has five segments: (the order inside each + * segment is PF0; PF1; PF2; PF3) - 128-131 U prods; + * 132-135 C prods; 136-139 X prods; 140-143 T prods; + * 144-147 attn prods; + */ + /* non-default-status-blocks */ + num_segs = CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_NDSB_NUM_SEGS : IGU_NORM_NDSB_NUM_SEGS; + for (sb_idx = 0; sb_idx < bp->igu_sb_cnt; sb_idx++) { + prod_offset = (bp->igu_base_sb + sb_idx) * + num_segs; + + for (i = 0; i < num_segs; i++) { + addr = IGU_REG_PROD_CONS_MEMORY + + (prod_offset + i) * 4; + REG_WR(bp, addr, 0); + } + /* send consumer update with value 0 */ + bnx2x_ack_sb(bp, bp->igu_base_sb + sb_idx, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_igu_clear_sb(bp, + bp->igu_base_sb + sb_idx); + } + + /* default-status-blocks */ + num_segs = CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_DSB_NUM_SEGS : IGU_NORM_DSB_NUM_SEGS; + + if (CHIP_MODE_IS_4_PORT(bp)) + dsb_idx = BP_FUNC(bp); + else + dsb_idx = BP_E1HVN(bp); + + prod_offset = (CHIP_INT_MODE_IS_BC(bp) ? + IGU_BC_BASE_DSB_PROD + dsb_idx : + IGU_NORM_BASE_DSB_PROD + dsb_idx); + + for (i = 0; i < (num_segs * E1HVN_MAX); + i += E1HVN_MAX) { + addr = IGU_REG_PROD_CONS_MEMORY + + (prod_offset + i)*4; + REG_WR(bp, addr, 0); + } + /* send consumer update with 0 */ + if (CHIP_INT_MODE_IS_BC(bp)) { + bnx2x_ack_sb(bp, bp->igu_dsb_id, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + CSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + XSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + TSTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + ATTENTION_ID, 0, IGU_INT_NOP, 1); + } else { + bnx2x_ack_sb(bp, bp->igu_dsb_id, + USTORM_ID, 0, IGU_INT_NOP, 1); + bnx2x_ack_sb(bp, bp->igu_dsb_id, + ATTENTION_ID, 0, IGU_INT_NOP, 1); + } + bnx2x_igu_clear_sb(bp, bp->igu_dsb_id); + + /* !!! these should become driver const once + rf-tool supports split-68 const */ + REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_LSB, 0); + REG_WR(bp, IGU_REG_SB_INT_BEFORE_MASK_MSB, 0); + REG_WR(bp, IGU_REG_SB_MASK_LSB, 0); + REG_WR(bp, IGU_REG_SB_MASK_MSB, 0); + REG_WR(bp, IGU_REG_PBA_STATUS_LSB, 0); + REG_WR(bp, IGU_REG_PBA_STATUS_MSB, 0); + } } - bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func); /* Reset PCIE errors for debug */ REG_WR(bp, 0x2114, 0xffffffff); REG_WR(bp, 0x2120, 0xffffffff); + bnx2x_init_block(bp, EMAC0_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, EMAC1_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DBU_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DBG_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, MCP_BLOCK, FUNC0_STAGE + func); + bnx2x_init_block(bp, DMAE_BLOCK, FUNC0_STAGE + func); + + if (CHIP_IS_E1x(bp)) { + main_mem_size = HC_REG_MAIN_MEMORY_SIZE / 2; /*dwords*/ + main_mem_base = HC_REG_MAIN_MEMORY + + BP_PORT(bp) * (main_mem_size * 4); + main_mem_prty_clr = HC_REG_HC_PRTY_STS_CLR; + main_mem_width = 8; + + val = REG_RD(bp, main_mem_prty_clr); + if (val) + DP(BNX2X_MSG_MCP, "Hmmm... Parity errors in HC " + "block during " + "function init (0x%x)!\n", val); + + /* Clear "false" parity errors in MSI-X table */ + for (i = main_mem_base; + i < main_mem_base + main_mem_size * 4; + i += main_mem_width) { + bnx2x_read_dmae(bp, i, main_mem_width / 4); + bnx2x_write_dmae(bp, bnx2x_sp_mapping(bp, wb_data), + i, main_mem_width / 4); + } + /* Clear HC parity attention */ + REG_RD(bp, main_mem_prty_clr); + } + + bnx2x_phy_probe(&bp->link_params); + return 0; } int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) { - int i, rc = 0; + int rc = 0; DP(BNX2X_MSG_MCP, "function %d load_code %x\n", - BP_FUNC(bp), load_code); + BP_ABS_FUNC(bp), load_code); bp->dmae_ready = 0; mutex_init(&bp->dmae_mutex); @@ -4499,21 +5750,20 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) switch (load_code) { case FW_MSG_CODE_DRV_LOAD_COMMON: - rc = bnx2x_init_common(bp); + case FW_MSG_CODE_DRV_LOAD_COMMON_CHIP: + rc = bnx2x_init_hw_common(bp, load_code); if (rc) goto init_hw_err; /* no break */ case FW_MSG_CODE_DRV_LOAD_PORT: - bp->dmae_ready = 1; - rc = bnx2x_init_port(bp); + rc = bnx2x_init_hw_port(bp); if (rc) goto init_hw_err; /* no break */ case FW_MSG_CODE_DRV_LOAD_FUNCTION: - bp->dmae_ready = 1; - rc = bnx2x_init_func(bp); + rc = bnx2x_init_hw_func(bp); if (rc) goto init_hw_err; break; @@ -4524,22 +5774,14 @@ int bnx2x_init_hw(struct bnx2x *bp, u32 load_code) } if (!BP_NOMCP(bp)) { - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, func_mb[func].drv_pulse_mb) & + (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) & DRV_PULSE_SEQ_MASK); DP(BNX2X_MSG_MCP, "drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); } - /* this needs to be done before gunzip end */ - bnx2x_zero_def_sb(bp); - for_each_queue(bp, i) - bnx2x_zero_sb(bp, BP_L_ID(bp) + i); -#ifdef BCM_CNIC - bnx2x_zero_sb(bp, BP_L_ID(bp) + i); -#endif - init_hw_err: bnx2x_gunzip_end(bp); @@ -4552,7 +5794,7 @@ void bnx2x_free_mem(struct bnx2x *bp) #define BNX2X_PCI_FREE(x, y, size) \ do { \ if (x) { \ - dma_free_coherent(&bp->pdev->dev, size, x, y); \ + dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \ x = NULL; \ y = 0; \ } \ @@ -4561,7 +5803,7 @@ void bnx2x_free_mem(struct bnx2x *bp) #define BNX2X_FREE(x) \ do { \ if (x) { \ - vfree(x); \ + kfree((void *)x); \ x = NULL; \ } \ } while (0) @@ -4571,11 +5813,15 @@ void bnx2x_free_mem(struct bnx2x *bp) /* fastpath */ /* Common */ for_each_queue(bp, i) { - /* status blocks */ - BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk), - bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_status_block)); + if (CHIP_IS_E2(bp)) + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb), + bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb), + bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e1x)); } /* Rx */ for_each_queue(bp, i) { @@ -4609,28 +5855,56 @@ void bnx2x_free_mem(struct bnx2x *bp) /* end of fastpath */ BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping, - sizeof(struct host_def_status_block)); + sizeof(struct host_sp_status_block)); BNX2X_PCI_FREE(bp->slowpath, bp->slowpath_mapping, sizeof(struct bnx2x_slowpath)); + BNX2X_PCI_FREE(bp->context.vcxt, bp->context.cxt_mapping, + bp->context.size); + + bnx2x_ilt_mem_op(bp, ILT_MEMOP_FREE); + + BNX2X_FREE(bp->ilt->lines); + #ifdef BCM_CNIC - BNX2X_PCI_FREE(bp->t1, bp->t1_mapping, 64*1024); - BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, 16*1024); - BNX2X_PCI_FREE(bp->timers, bp->timers_mapping, 8*1024); - BNX2X_PCI_FREE(bp->qm, bp->qm_mapping, 128*1024); - BNX2X_PCI_FREE(bp->cnic_sb, bp->cnic_sb_mapping, - sizeof(struct host_status_block)); + if (CHIP_IS_E2(bp)) + BNX2X_PCI_FREE(bp->cnic_sb.e2_sb, bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_FREE(bp->cnic_sb.e1x_sb, bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); + + BNX2X_PCI_FREE(bp->t2, bp->t2_mapping, SRC_T2_SZ); #endif + BNX2X_PCI_FREE(bp->spq, bp->spq_mapping, BCM_PAGE_SIZE); + BNX2X_PCI_FREE(bp->eq_ring, bp->eq_mapping, + BCM_PAGE_SIZE * NUM_EQ_PAGES); + #undef BNX2X_PCI_FREE #undef BNX2X_KFREE } -int bnx2x_alloc_mem(struct bnx2x *bp) +static inline void set_sb_shortcuts(struct bnx2x *bp, int index) { + union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk); + if (CHIP_IS_E2(bp)) { + bnx2x_fp(bp, index, sb_index_values) = + (__le16 *)status_blk.e2_sb->sb.index_values; + bnx2x_fp(bp, index, sb_running_index) = + (__le16 *)status_blk.e2_sb->sb.running_index; + } else { + bnx2x_fp(bp, index, sb_index_values) = + (__le16 *)status_blk.e1x_sb->sb.index_values; + bnx2x_fp(bp, index, sb_running_index) = + (__le16 *)status_blk.e1x_sb->sb.running_index; + } +} +int bnx2x_alloc_mem(struct bnx2x *bp) +{ #define BNX2X_PCI_ALLOC(x, y, size) \ do { \ x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \ @@ -4641,10 +5915,9 @@ int bnx2x_alloc_mem(struct bnx2x *bp) #define BNX2X_ALLOC(x, size) \ do { \ - x = vmalloc(size); \ + x = kzalloc(size, GFP_KERNEL); \ if (x == NULL) \ goto alloc_mem_err; \ - memset(x, 0, size); \ } while (0) int i; @@ -4652,12 +5925,19 @@ int bnx2x_alloc_mem(struct bnx2x *bp) /* fastpath */ /* Common */ for_each_queue(bp, i) { + union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk); bnx2x_fp(bp, i, bp) = bp; - /* status blocks */ - BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, status_blk), + if (CHIP_IS_E2(bp)) + BNX2X_PCI_ALLOC(sb->e2_sb, + &bnx2x_fp(bp, i, status_blk_mapping), + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_ALLOC(sb->e1x_sb, &bnx2x_fp(bp, i, status_blk_mapping), - sizeof(struct host_status_block)); + sizeof(struct host_hc_status_block_e1x)); + + set_sb_shortcuts(bp, i); } /* Rx */ for_each_queue(bp, i) { @@ -4693,37 +5973,41 @@ int bnx2x_alloc_mem(struct bnx2x *bp) } /* end of fastpath */ +#ifdef BCM_CNIC + if (CHIP_IS_E2(bp)) + BNX2X_PCI_ALLOC(bp->cnic_sb.e2_sb, &bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e2)); + else + BNX2X_PCI_ALLOC(bp->cnic_sb.e1x_sb, &bp->cnic_sb_mapping, + sizeof(struct host_hc_status_block_e1x)); + + /* allocate searcher T2 table */ + BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, SRC_T2_SZ); +#endif + + BNX2X_PCI_ALLOC(bp->def_status_blk, &bp->def_status_blk_mapping, - sizeof(struct host_def_status_block)); + sizeof(struct host_sp_status_block)); BNX2X_PCI_ALLOC(bp->slowpath, &bp->slowpath_mapping, sizeof(struct bnx2x_slowpath)); -#ifdef BCM_CNIC - BNX2X_PCI_ALLOC(bp->t1, &bp->t1_mapping, 64*1024); - - /* allocate searcher T2 table - we allocate 1/4 of alloc num for T2 - (which is not entered into the ILT) */ - BNX2X_PCI_ALLOC(bp->t2, &bp->t2_mapping, 16*1024); - - /* Initialize T2 (for 1024 connections) */ - for (i = 0; i < 16*1024; i += 64) - *(u64 *)((char *)bp->t2 + i + 56) = bp->t2_mapping + i + 64; + bp->context.size = sizeof(union cdu_context) * bp->l2_cid_count; - /* Timer block array (8*MAX_CONN) phys uncached for now 1024 conns */ - BNX2X_PCI_ALLOC(bp->timers, &bp->timers_mapping, 8*1024); + BNX2X_PCI_ALLOC(bp->context.vcxt, &bp->context.cxt_mapping, + bp->context.size); - /* QM queues (128*MAX_CONN) */ - BNX2X_PCI_ALLOC(bp->qm, &bp->qm_mapping, 128*1024); + BNX2X_ALLOC(bp->ilt->lines, sizeof(struct ilt_line) * ILT_MAX_LINES); - BNX2X_PCI_ALLOC(bp->cnic_sb, &bp->cnic_sb_mapping, - sizeof(struct host_status_block)); -#endif + if (bnx2x_ilt_mem_op(bp, ILT_MEMOP_ALLOC)) + goto alloc_mem_err; /* Slow path ring */ BNX2X_PCI_ALLOC(bp->spq, &bp->spq_mapping, BCM_PAGE_SIZE); + /* EQ */ + BNX2X_PCI_ALLOC(bp->eq_ring, &bp->eq_mapping, + BCM_PAGE_SIZE * NUM_EQ_PAGES); return 0; alloc_mem_err: @@ -4734,97 +6018,47 @@ int bnx2x_alloc_mem(struct bnx2x *bp) #undef BNX2X_ALLOC } - /* * Init service functions */ +int bnx2x_func_start(struct bnx2x *bp) +{ + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_START, 0, 0, 0, 1); -/** - * Sets a MAC in a CAM for a few L2 Clients for E1 chip - * - * @param bp driver descriptor - * @param set set or clear an entry (1 or 0) - * @param mac pointer to a buffer containing a MAC - * @param cl_bit_vec bit vector of clients to register a MAC for - * @param cam_offset offset in a CAM to use - * @param with_bcast set broadcast MAC as well - */ -static void bnx2x_set_mac_addr_e1_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset, - u8 with_bcast) -{ - struct mac_configuration_cmd *config = bnx2x_sp(bp, mac_config); - int port = BP_PORT(bp); - - /* CAM allocation - * unicasts 0-31:port0 32-63:port1 - * multicast 64-127:port0 128-191:port1 - */ - config->hdr.length = 1 + (with_bcast ? 1 : 0); - config->hdr.offset = cam_offset; - config->hdr.client_id = 0xff; - config->hdr.reserved1 = 0; - - /* primary MAC */ - config->config_table[0].cam_entry.msb_mac_addr = - swab16(*(u16 *)&mac[0]); - config->config_table[0].cam_entry.middle_mac_addr = - swab16(*(u16 *)&mac[2]); - config->config_table[0].cam_entry.lsb_mac_addr = - swab16(*(u16 *)&mac[4]); - config->config_table[0].cam_entry.flags = cpu_to_le16(port); - if (set) - config->config_table[0].target_table_entry.flags = 0; - else - CAM_INVALIDATE(config->config_table[0]); - config->config_table[0].target_table_entry.clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[0].target_table_entry.vlan_id = 0; + /* Wait for completion */ + return bnx2x_wait_ramrod(bp, BNX2X_STATE_FUNC_STARTED, 0, &(bp->state), + WAIT_RAMROD_COMMON); +} - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x)\n", - (set ? "setting" : "clearing"), - config->config_table[0].cam_entry.msb_mac_addr, - config->config_table[0].cam_entry.middle_mac_addr, - config->config_table[0].cam_entry.lsb_mac_addr); - - /* broadcast */ - if (with_bcast) { - config->config_table[1].cam_entry.msb_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.middle_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.lsb_mac_addr = - cpu_to_le16(0xffff); - config->config_table[1].cam_entry.flags = cpu_to_le16(port); - if (set) - config->config_table[1].target_table_entry.flags = - TSTORM_CAM_TARGET_TABLE_ENTRY_BROADCAST; - else - CAM_INVALIDATE(config->config_table[1]); - config->config_table[1].target_table_entry.clients_bit_vector = - cpu_to_le32(cl_bit_vec); - config->config_table[1].target_table_entry.vlan_id = 0; - } +int bnx2x_func_stop(struct bnx2x *bp) +{ + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_STOP, 0, 0, 0, 1); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + /* Wait for completion */ + return bnx2x_wait_ramrod(bp, BNX2X_STATE_CLOSING_WAIT4_UNLOAD, + 0, &(bp->state), WAIT_RAMROD_COMMON); } /** - * Sets a MAC in a CAM for a few L2 Clients for E1H chip + * Sets a MAC in a CAM for a few L2 Clients for E1x chips * * @param bp driver descriptor * @param set set or clear an entry (1 or 0) * @param mac pointer to a buffer containing a MAC * @param cl_bit_vec bit vector of clients to register a MAC for * @param cam_offset offset in a CAM to use + * @param is_bcast is the set MAC a broadcast address (for E1 only) */ -static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac, - u32 cl_bit_vec, u8 cam_offset) +static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, u8 *mac, + u32 cl_bit_vec, u8 cam_offset, + u8 is_bcast) { - struct mac_configuration_cmd_e1h *config = - (struct mac_configuration_cmd_e1h *)bnx2x_sp(bp, mac_config); + struct mac_configuration_cmd *config = + (struct mac_configuration_cmd *)bnx2x_sp(bp, mac_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + + bp->set_mac_pending = 1; + smp_wmb(); config->hdr.length = 1; config->hdr.offset = cam_offset; @@ -4841,29 +6075,41 @@ static void bnx2x_set_mac_addr_e1h_gen(struct bnx2x *bp, int set, u8 *mac, config->config_table[0].clients_bit_vector = cpu_to_le32(cl_bit_vec); config->config_table[0].vlan_id = 0; - config->config_table[0].e1hov_id = cpu_to_le16(bp->e1hov); + config->config_table[0].pf_id = BP_FUNC(bp); if (set) - config->config_table[0].flags = BP_PORT(bp); + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); else - config->config_table[0].flags = - MAC_CONFIGURATION_ENTRY_E1H_ACTION_TYPE; + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + if (is_bcast) + SET_FLAG(config->config_table[0].flags, + MAC_CONFIGURATION_ENTRY_BROADCAST, 1); - DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) E1HOV %d CLID mask %d\n", + DP(NETIF_MSG_IFUP, "%s MAC (%04x:%04x:%04x) PF_ID %d CLID mask %d\n", (set ? "setting" : "clearing"), config->config_table[0].msb_mac_addr, config->config_table[0].middle_mac_addr, - config->config_table[0].lsb_mac_addr, bp->e1hov, cl_bit_vec); + config->config_table[0].lsb_mac_addr, BP_FUNC(bp), cl_bit_vec); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, U64_HI(bnx2x_sp_mapping(bp, mac_config)), - U64_LO(bnx2x_sp_mapping(bp, mac_config)), 0); + U64_LO(bnx2x_sp_mapping(bp, mac_config)), 1); + + /* Wait for a completion */ + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, ramrod_flags); } -static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, - int *state_p, int poll) +int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, + int *state_p, int flags) { /* can take a while if any port is running */ int cnt = 5000; + u8 poll = flags & WAIT_RAMROD_POLL; + u8 common = flags & WAIT_RAMROD_COMMON; DP(NETIF_MSG_IFUP, "%s for state to become %x on IDX [%d]\n", poll ? "polling" : "waiting", state, idx); @@ -4871,13 +6117,17 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, might_sleep(); while (cnt--) { if (poll) { - bnx2x_rx_int(bp->fp, 10); - /* if index is different from 0 - * the reply for some commands will - * be on the non default queue - */ - if (idx) - bnx2x_rx_int(&bp->fp[idx], 10); + if (common) + bnx2x_eq_int(bp); + else { + bnx2x_rx_int(bp->fp, 10); + /* if index is different from 0 + * the reply for some commands will + * be on the non default queue + */ + if (idx) + bnx2x_rx_int(&bp->fp[idx], 10); + } } mb(); /* state is changed by bnx2x_sp_event() */ @@ -4904,29 +6154,112 @@ static int bnx2x_wait_ramrod(struct bnx2x *bp, int state, int idx, return -EBUSY; } -void bnx2x_set_eth_mac_addr_e1h(struct bnx2x *bp, int set) +u8 bnx2x_e1h_cam_offset(struct bnx2x *bp, u8 rel_offset) { - bp->set_mac_pending++; - smp_wmb(); + if (CHIP_IS_E1H(bp)) + return E1H_FUNC_MAX * rel_offset + BP_FUNC(bp); + else if (CHIP_MODE_IS_4_PORT(bp)) + return BP_FUNC(bp) * 32 + rel_offset; + else + return BP_VN(bp) * 32 + rel_offset; +} + +void bnx2x_set_eth_mac(struct bnx2x *bp, int set) +{ + u8 cam_offset = (CHIP_IS_E1(bp) ? (BP_PORT(bp) ? 32 : 0) : + bnx2x_e1h_cam_offset(bp, CAM_ETH_LINE)); - bnx2x_set_mac_addr_e1h_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), BP_FUNC(bp)); + /* networking MAC */ + bnx2x_set_mac_addr_gen(bp, set, bp->dev->dev_addr, + (1 << bp->fp->cl_id), cam_offset , 0); - /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); + if (CHIP_IS_E1(bp)) { + /* broadcast MAC */ + u8 bcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + bnx2x_set_mac_addr_gen(bp, set, bcast, 0, cam_offset + 1, 1); + } } +static void bnx2x_set_e1_mc_list(struct bnx2x *bp, u8 offset) +{ + int i = 0, old; + struct net_device *dev = bp->dev; + struct netdev_hw_addr *ha; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + + netdev_for_each_mc_addr(ha, dev) { + /* copy mac */ + config_cmd->config_table[i].msb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[0]); + config_cmd->config_table[i].middle_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[2]); + config_cmd->config_table[i].lsb_mac_addr = + swab16(*(u16 *)&bnx2x_mc_addr(ha)[4]); + + config_cmd->config_table[i].vlan_id = 0; + config_cmd->config_table[i].pf_id = BP_FUNC(bp); + config_cmd->config_table[i].clients_bit_vector = + cpu_to_le32(1 << BP_L_ID(bp)); + + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_SET); + + DP(NETIF_MSG_IFUP, + "setting MCAST[%d] (%04x:%04x:%04x)\n", i, + config_cmd->config_table[i].msb_mac_addr, + config_cmd->config_table[i].middle_mac_addr, + config_cmd->config_table[i].lsb_mac_addr); + i++; + } + old = config_cmd->hdr.length; + if (old > i) { + for (; i < old; i++) { + if (CAM_IS_INVALID(config_cmd-> + config_table[i])) { + /* already invalidated */ + break; + } + /* invalidate */ + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + } + } + + config_cmd->hdr.length = i; + config_cmd->hdr.offset = offset; + config_cmd->hdr.client_id = 0xff; + config_cmd->hdr.reserved1 = 0; + + bp->set_mac_pending = 1; + smp_wmb(); -void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); +} +static void bnx2x_invlidate_e1_mc_list(struct bnx2x *bp) { - bp->set_mac_pending++; + int i; + struct mac_configuration_cmd *config_cmd = bnx2x_sp(bp, mcast_config); + dma_addr_t config_cmd_map = bnx2x_sp_mapping(bp, mcast_config); + int ramrod_flags = WAIT_RAMROD_COMMON; + + bp->set_mac_pending = 1; smp_wmb(); - bnx2x_set_mac_addr_e1_gen(bp, set, bp->dev->dev_addr, - (1 << bp->fp->cl_id), (BP_PORT(bp) ? 32 : 0), - 1); + for (i = 0; i < config_cmd->hdr.length; i++) + SET_FLAG(config_cmd->config_table[i].flags, + MAC_CONFIGURATION_ENTRY_ACTION_TYPE, + T_ETH_MAC_COMMAND_INVALIDATE); + + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_SET_MAC, 0, + U64_HI(config_cmd_map), U64_LO(config_cmd_map), 1); /* Wait for a completion */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); + bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, + ramrod_flags); + } #ifdef BCM_CNIC @@ -4942,174 +6275,463 @@ void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) */ int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) { - u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID); - - bp->set_mac_pending++; - smp_wmb(); + u8 cam_offset = (CHIP_IS_E1(bp) ? ((BP_PORT(bp) ? 32 : 0) + 2) : + bnx2x_e1h_cam_offset(bp, CAM_ISCSI_ETH_LINE)); + u32 iscsi_l2_cl_id = BNX2X_ISCSI_ETH_CL_ID; + u32 cl_bit_vec = (1 << iscsi_l2_cl_id); /* Send a SET_MAC ramrod */ - if (CHIP_IS_E1(bp)) - bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac, - cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2, - 1); - else - /* CAM allocation for E1H - * unicasts: by func number - * multicast: 20+FUNC*20, 20 each - */ - bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac, - cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp)); - - /* Wait for a completion when setting */ - bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); - + bnx2x_set_mac_addr_gen(bp, set, bp->iscsi_mac, cl_bit_vec, + cam_offset, 0); return 0; } #endif -int bnx2x_setup_leading(struct bnx2x *bp) -{ - int rc; +static void bnx2x_fill_cl_init_data(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data) +{ + /* Clear the buffer */ + memset(data, 0, sizeof(*data)); + + /* general */ + data->general.client_id = params->rxq_params.cl_id; + data->general.statistics_counter_id = params->rxq_params.stat_id; + data->general.statistics_en_flg = + (params->rxq_params.flags & QUEUE_FLG_STATS) ? 1 : 0; + data->general.activate_flg = activate; + data->general.sp_client_id = params->rxq_params.spcl_id; + + /* Rx data */ + data->rx.tpa_en_flg = + (params->rxq_params.flags & QUEUE_FLG_TPA) ? 1 : 0; + data->rx.vmqueue_mode_en_flg = 0; + data->rx.cache_line_alignment_log_size = + params->rxq_params.cache_line_log; + data->rx.enable_dynamic_hc = + (params->rxq_params.flags & QUEUE_FLG_DHC) ? 1 : 0; + data->rx.max_sges_for_packet = params->rxq_params.max_sges_pkt; + data->rx.client_qzone_id = params->rxq_params.cl_qzone_id; + data->rx.max_agg_size = params->rxq_params.tpa_agg_sz; + + /* We don't set drop flags */ + data->rx.drop_ip_cs_err_flg = 0; + data->rx.drop_tcp_cs_err_flg = 0; + data->rx.drop_ttl0_flg = 0; + data->rx.drop_udp_cs_err_flg = 0; + + data->rx.inner_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_VLAN) ? 1 : 0; + data->rx.outer_vlan_removal_enable_flg = + (params->rxq_params.flags & QUEUE_FLG_OV) ? 1 : 0; + data->rx.status_block_id = params->rxq_params.fw_sb_id; + data->rx.rx_sb_index_number = params->rxq_params.sb_cq_index; + data->rx.bd_buff_size = cpu_to_le16(params->rxq_params.buf_sz); + data->rx.sge_buff_size = cpu_to_le16(params->rxq_params.sge_buf_sz); + data->rx.mtu = cpu_to_le16(params->rxq_params.mtu); + data->rx.bd_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.dscr_map)); + data->rx.bd_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.dscr_map)); + data->rx.sge_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.sge_map)); + data->rx.sge_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.sge_map)); + data->rx.cqe_page_base.lo = + cpu_to_le32(U64_LO(params->rxq_params.rcq_map)); + data->rx.cqe_page_base.hi = + cpu_to_le32(U64_HI(params->rxq_params.rcq_map)); + data->rx.is_leading_rss = + (params->ramrod_params.flags & CLIENT_IS_LEADING_RSS) ? 1 : 0; + data->rx.is_approx_mcast = data->rx.is_leading_rss; + + /* Tx data */ + data->tx.enforce_security_flg = 0; /* VF specific */ + data->tx.tx_status_block_id = params->txq_params.fw_sb_id; + data->tx.tx_sb_index_number = params->txq_params.sb_cq_index; + data->tx.mtu = 0; /* VF specific */ + data->tx.tx_bd_page_base.lo = + cpu_to_le32(U64_LO(params->txq_params.dscr_map)); + data->tx.tx_bd_page_base.hi = + cpu_to_le32(U64_HI(params->txq_params.dscr_map)); + + /* flow control data */ + data->fc.cqe_pause_thr_low = cpu_to_le16(params->pause.rcq_th_lo); + data->fc.cqe_pause_thr_high = cpu_to_le16(params->pause.rcq_th_hi); + data->fc.bd_pause_thr_low = cpu_to_le16(params->pause.bd_th_lo); + data->fc.bd_pause_thr_high = cpu_to_le16(params->pause.bd_th_hi); + data->fc.sge_pause_thr_low = cpu_to_le16(params->pause.sge_th_lo); + data->fc.sge_pause_thr_high = cpu_to_le16(params->pause.sge_th_hi); + data->fc.rx_cos_mask = cpu_to_le16(params->pause.pri_map); + + data->fc.safc_group_num = params->txq_params.cos; + data->fc.safc_group_en_flg = + (params->txq_params.flags & QUEUE_FLG_COS) ? 1 : 0; + data->fc.traffic_type = LLFC_TRAFFIC_TYPE_NW; +} + +static inline void bnx2x_set_ctx_validation(struct eth_context *cxt, u32 cid) +{ + /* ustorm cxt validation */ + cxt->ustorm_ag_context.cdu_usage = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_UCM_AG, + ETH_CONNECTION_TYPE); + /* xcontext validation */ + cxt->xstorm_ag_context.cdu_reserved = + CDU_RSRVD_VALUE_TYPE_A(cid, CDU_REGION_NUMBER_XCM_AG, + ETH_CONNECTION_TYPE); +} + +int bnx2x_setup_fw_client(struct bnx2x *bp, + struct bnx2x_client_init_params *params, + u8 activate, + struct client_init_ramrod_data *data, + dma_addr_t data_mapping) +{ + u16 hc_usec; + int ramrod = RAMROD_CMD_ID_ETH_CLIENT_SETUP; + int ramrod_flags = 0, rc; + + /* HC and context validation values */ + hc_usec = params->txq_params.hc_rate ? + 1000000 / params->txq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->txq_params.fw_sb_id, + params->txq_params.sb_cq_index, + !(params->txq_params.flags & QUEUE_FLG_HC), + hc_usec); + + *(params->ramrod_params.pstate) = BNX2X_FP_STATE_OPENING; + + hc_usec = params->rxq_params.hc_rate ? + 1000000 / params->rxq_params.hc_rate : 0; + bnx2x_update_coalesce_sb_index(bp, + params->rxq_params.fw_sb_id, + params->rxq_params.sb_cq_index, + !(params->rxq_params.flags & QUEUE_FLG_HC), + hc_usec); + + bnx2x_set_ctx_validation(params->rxq_params.cxt, + params->rxq_params.cid); + + /* zero stats */ + if (params->txq_params.flags & QUEUE_FLG_STATS) + storm_memset_xstats_zero(bp, BP_PORT(bp), + params->txq_params.stat_id); + + if (params->rxq_params.flags & QUEUE_FLG_STATS) { + storm_memset_ustats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + storm_memset_tstats_zero(bp, BP_PORT(bp), + params->rxq_params.stat_id); + } + + /* Fill the ramrod data */ + bnx2x_fill_cl_init_data(bp, params, activate, data); + + /* SETUP ramrod. + * + * bnx2x_sp_post() takes a spin_lock thus no other explict memory + * barrier except from mmiowb() is needed to impose a + * proper ordering of memory operations. + */ + mmiowb(); - /* reset IGU state */ - bnx2x_ack_sb(bp, bp->fp[0].sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); - /* SETUP ramrod */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_SETUP, 0, 0, 0, 0); + bnx2x_sp_post(bp, ramrod, params->ramrod_params.cid, + U64_HI(data_mapping), U64_LO(data_mapping), 0); /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_STATE_OPEN, 0, &(bp->state), 0); - + rc = bnx2x_wait_ramrod(bp, params->ramrod_params.state, + params->ramrod_params.index, + params->ramrod_params.pstate, + ramrod_flags); return rc; } -int bnx2x_setup_multi(struct bnx2x *bp, int index) +/** + * Configure interrupt mode according to current configuration. + * In case of MSI-X it will also try to enable MSI-X. + * + * @param bp + * + * @return int + */ +static int __devinit bnx2x_set_int_mode(struct bnx2x *bp) { - struct bnx2x_fastpath *fp = &bp->fp[index]; + int rc = 0; - /* reset IGU state */ - bnx2x_ack_sb(bp, fp->sb_id, CSTORM_ID, 0, IGU_INT_ENABLE, 0); + switch (bp->int_mode) { + case INT_MODE_MSI: + bnx2x_enable_msi(bp); + /* falling through... */ + case INT_MODE_INTx: + bp->num_queues = 1; + DP(NETIF_MSG_IFUP, "set number of queues to 1\n"); + break; + default: + /* Set number of queues according to bp->multi_mode value */ + bnx2x_set_num_queues(bp); - /* SETUP ramrod */ - fp->state = BNX2X_FP_STATE_OPENING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CLIENT_SETUP, index, 0, - fp->cl_id, 0); + DP(NETIF_MSG_IFUP, "set number of queues to %d\n", + bp->num_queues); - /* Wait for completion */ - return bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_OPEN, index, - &(fp->state), 0); -} + /* if we can't use MSI-X we only need one fp, + * so try to enable MSI-X with the requested number of fp's + * and fallback to MSI or legacy INTx with one fp + */ + rc = bnx2x_enable_msix(bp); + if (rc) { + /* failed to enable MSI-X */ + if (bp->multi_mode) + DP(NETIF_MSG_IFUP, + "Multi requested but failed to " + "enable MSI-X (%d), " + "set number of queues to %d\n", + bp->num_queues, + 1); + bp->num_queues = 1; + + if (!(bp->flags & DISABLE_MSI_FLAG)) + bnx2x_enable_msi(bp); + } + + break; + } + return rc; +} -void bnx2x_set_num_queues_msix(struct bnx2x *bp) +/* must be called prioir to any HW initializations */ +static inline u16 bnx2x_cid_ilt_lines(struct bnx2x *bp) { + return L2_ILT_LINES(bp); +} - switch (bp->multi_mode) { - case ETH_RSS_MODE_DISABLED: - bp->num_queues = 1; - break; +void bnx2x_ilt_set_info(struct bnx2x *bp) +{ + struct ilt_client_info *ilt_client; + struct bnx2x_ilt *ilt = BP_ILT(bp); + u16 line = 0; - case ETH_RSS_MODE_REGULAR: - if (num_queues) - bp->num_queues = min_t(u32, num_queues, - BNX2X_MAX_QUEUES(bp)); - else - bp->num_queues = min_t(u32, num_online_cpus(), - BNX2X_MAX_QUEUES(bp)); - break; + ilt->start_line = FUNC_ILT_BASE(BP_FUNC(bp)); + DP(BNX2X_MSG_SP, "ilt starts at line %d\n", ilt->start_line); + /* CDU */ + ilt_client = &ilt->clients[ILT_CLIENT_CDU]; + ilt_client->client_num = ILT_CLIENT_CDU; + ilt_client->page_size = CDU_ILT_PAGE_SZ; + ilt_client->flags = ILT_CLIENT_SKIP_MEM; + ilt_client->start = line; + line += L2_ILT_LINES(bp); +#ifdef BCM_CNIC + line += CNIC_ILT_LINES; +#endif + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[CDU]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); + + /* QM */ + if (QM_INIT(bp->qm_cid_count)) { + ilt_client = &ilt->clients[ILT_CLIENT_QM]; + ilt_client->client_num = ILT_CLIENT_QM; + ilt_client->page_size = QM_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + + /* 4 bytes for each cid */ + line += DIV_ROUND_UP(bp->qm_cid_count * QM_QUEUES_PER_FUNC * 4, + QM_ILT_PAGE_SZ); + + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[QM]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); + + } + /* SRC */ + ilt_client = &ilt->clients[ILT_CLIENT_SRC]; +#ifdef BCM_CNIC + ilt_client->client_num = ILT_CLIENT_SRC; + ilt_client->page_size = SRC_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + line += SRC_ILT_LINES; + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[SRC]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); - default: - bp->num_queues = 1; - break; - } -} +#else + ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); +#endif + /* TM */ + ilt_client = &ilt->clients[ILT_CLIENT_TM]; +#ifdef BCM_CNIC + ilt_client->client_num = ILT_CLIENT_TM; + ilt_client->page_size = TM_ILT_PAGE_SZ; + ilt_client->flags = 0; + ilt_client->start = line; + line += TM_ILT_LINES; + ilt_client->end = line - 1; + + DP(BNX2X_MSG_SP, "ilt client[TM]: start %d, end %d, psz 0x%x, " + "flags 0x%x, hw psz %d\n", + ilt_client->start, + ilt_client->end, + ilt_client->page_size, + ilt_client->flags, + ilog2(ilt_client->page_size >> 12)); +#else + ilt_client->flags = (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM); +#endif +} -static int bnx2x_stop_multi(struct bnx2x *bp, int index) +int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp, + int is_leading) { - struct bnx2x_fastpath *fp = &bp->fp[index]; + struct bnx2x_client_init_params params = { {0} }; int rc; - /* halt the connection */ - fp->state = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, index, 0, fp->cl_id, 0); + bnx2x_ack_sb(bp, fp->igu_sb_id, USTORM_ID, 0, + IGU_INT_ENABLE, 0); - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, index, - &(fp->state), 1); - if (rc) /* timeout */ - return rc; + params.ramrod_params.pstate = &fp->state; + params.ramrod_params.state = BNX2X_FP_STATE_OPEN; + params.ramrod_params.index = fp->index; + params.ramrod_params.cid = fp->cid; - /* delete cfc entry */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_CFC_DEL, index, 0, 0, 1); + if (is_leading) + params.ramrod_params.flags |= CLIENT_IS_LEADING_RSS; - /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, index, - &(fp->state), 1); + bnx2x_pf_rx_cl_prep(bp, fp, ¶ms.pause, ¶ms.rxq_params); + + bnx2x_pf_tx_cl_prep(bp, fp, ¶ms.txq_params); + + rc = bnx2x_setup_fw_client(bp, ¶ms, 1, + bnx2x_sp(bp, client_init_data), + bnx2x_sp_mapping(bp, client_init_data)); return rc; } -static int bnx2x_stop_leading(struct bnx2x *bp) +int bnx2x_stop_fw_client(struct bnx2x *bp, struct bnx2x_client_ramrod_params *p) { - __le16 dsb_sp_prod_idx; - /* if the other port is handling traffic, - this can take a lot of time */ - int cnt = 500; int rc; - might_sleep(); + int poll_flag = p->poll ? WAIT_RAMROD_POLL : 0; - /* Send HALT ramrod */ - bp->fp[0].state = BNX2X_FP_STATE_HALTING; - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, 0, 0, bp->fp->cl_id, 0); + /* halt the connection */ + *p->pstate = BNX2X_FP_STATE_HALTING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_HALT, p->cid, 0, + p->cl_id, 0); /* Wait for completion */ - rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, 0, - &(bp->fp[0].state), 1); + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_HALTED, p->index, + p->pstate, poll_flag); if (rc) /* timeout */ return rc; - dsb_sp_prod_idx = *bp->dsb_sp_prod; + *p->pstate = BNX2X_FP_STATE_TERMINATING; + bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_TERMINATE, p->cid, 0, + p->cl_id, 0); + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_TERMINATED, p->index, + p->pstate, poll_flag); + if (rc) /* timeout */ + return rc; - /* Send PORT_DELETE ramrod */ - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_PORT_DEL, 0, 0, 0, 1); - /* Wait for completion to arrive on default status block - we are going to reset the chip anyway - so there is not much to do if this times out - */ - while (dsb_sp_prod_idx == *bp->dsb_sp_prod) { - if (!cnt) { - DP(NETIF_MSG_IFDOWN, "timeout waiting for port del " - "dsb_sp_prod 0x%x != dsb_sp_prod_idx 0x%x\n", - *bp->dsb_sp_prod, dsb_sp_prod_idx); -#ifdef BNX2X_STOP_ON_ERROR - bnx2x_panic(); -#endif - rc = -EBUSY; - break; - } - cnt--; - msleep(1); - rmb(); /* Refresh the dsb_sp_prod */ - } - bp->state = BNX2X_STATE_CLOSING_WAIT4_UNLOAD; - bp->fp[0].state = BNX2X_FP_STATE_CLOSED; + /* delete cfc entry */ + bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_CFC_DEL, p->cid, 0, 0, 1); + /* Wait for completion */ + rc = bnx2x_wait_ramrod(bp, BNX2X_FP_STATE_CLOSED, p->index, + p->pstate, WAIT_RAMROD_COMMON); return rc; } +static int bnx2x_stop_client(struct bnx2x *bp, int index) +{ + struct bnx2x_client_ramrod_params client_stop = {0}; + struct bnx2x_fastpath *fp = &bp->fp[index]; + + client_stop.index = index; + client_stop.cid = fp->cid; + client_stop.cl_id = fp->cl_id; + client_stop.pstate = &(fp->state); + client_stop.poll = 0; + + return bnx2x_stop_fw_client(bp, &client_stop); +} + + static void bnx2x_reset_func(struct bnx2x *bp) { int port = BP_PORT(bp); int func = BP_FUNC(bp); - int base, i; + int i; + int pfunc_offset_fp = offsetof(struct hc_sb_data, p_func) + + (CHIP_IS_E2(bp) ? + offsetof(struct hc_status_block_data_e2, common) : + offsetof(struct hc_status_block_data_e1x, common)); + int pfunc_offset_sp = offsetof(struct hc_sp_status_block_data, p_func); + int pfid_offset = offsetof(struct pci_entity, pf_id); + + /* Disable the function in the FW */ + REG_WR8(bp, BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(func), 0); + REG_WR8(bp, BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(func), 0); + + /* FP SBs */ + for_each_queue(bp, i) { + struct bnx2x_fastpath *fp = &bp->fp[i]; + REG_WR8(bp, + BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(fp->fw_sb_id) + + pfunc_offset_fp + pfid_offset, + HC_FUNCTION_DISABLED); + } + + /* SP SB */ + REG_WR8(bp, + BAR_CSTRORM_INTMEM + + CSTORM_SP_STATUS_BLOCK_DATA_OFFSET(func) + + pfunc_offset_sp + pfid_offset, + HC_FUNCTION_DISABLED); + + + for (i = 0; i < XSTORM_SPQ_DATA_SIZE / 4; i++) + REG_WR(bp, BAR_XSTRORM_INTMEM + XSTORM_SPQ_DATA_OFFSET(func), + 0); /* Configure IGU */ - REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); - REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + if (bp->common.int_block == INT_BLOCK_HC) { + REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0); + REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0); + } else { + REG_WR(bp, IGU_REG_LEADING_EDGE_LATCH, 0); + REG_WR(bp, IGU_REG_TRAILING_EDGE_LATCH, 0); + } #ifdef BCM_CNIC /* Disable Timer scan */ @@ -5125,9 +6747,27 @@ static void bnx2x_reset_func(struct bnx2x *bp) } #endif /* Clear ILT */ - base = FUNC_ILT_BASE(func); - for (i = base; i < base + ILT_PER_FUNC; i++) - bnx2x_ilt_wr(bp, i, 0); + bnx2x_clear_func_ilt(bp, func); + + /* Timers workaround bug for E2: if this is vnic-3, + * we need to set the entire ilt range for this timers. + */ + if (CHIP_IS_E2(bp) && BP_VN(bp) == 3) { + struct ilt_client_info ilt_cli; + /* use dummy TM client */ + memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); + ilt_cli.start = 0; + ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; + ilt_cli.client_num = ILT_CLIENT_TM; + + bnx2x_ilt_boundry_init_op(bp, &ilt_cli, 0, INITOP_CLEAR); + } + + /* this assumes that reset_port() called before reset_func()*/ + if (CHIP_IS_E2(bp)) + bnx2x_pf_disable(bp); + + bp->dmae_ready = 0; } static void bnx2x_reset_port(struct bnx2x *bp) @@ -5159,7 +6799,7 @@ static void bnx2x_reset_port(struct bnx2x *bp) static void bnx2x_reset_chip(struct bnx2x *bp, u32 reset_code) { DP(BNX2X_MSG_MCP, "function %d reset_code %x\n", - BP_FUNC(bp), reset_code); + BP_ABS_FUNC(bp), reset_code); switch (reset_code) { case FW_MSG_CODE_DRV_UNLOAD_COMMON: @@ -5196,7 +6836,6 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) cnt = 1000; while (bnx2x_has_tx_work_unload(fp)) { - bnx2x_tx_int(fp); if (!cnt) { BNX2X_ERR("timeout waiting for queue[%d]\n", i); @@ -5215,39 +6854,21 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) msleep(1); if (CHIP_IS_E1(bp)) { - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - bnx2x_set_eth_mac_addr_e1(bp, 0); - - for (i = 0; i < config->hdr.length; i++) - CAM_INVALIDATE(config->config_table[i]); - - config->hdr.length = i; - if (CHIP_REV_IS_SLOW(bp)) - config->hdr.offset = BNX2X_MAX_EMUL_MULTI*(1 + port); - else - config->hdr.offset = BNX2X_MAX_MULTICAST*(1 + port); - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; - - bp->set_mac_pending++; - smp_wmb(); - - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mcast_config)), - U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0); + /* invalidate mc list, + * wait and poll (interrupts are off) + */ + bnx2x_invlidate_e1_mc_list(bp); + bnx2x_set_eth_mac(bp, 0); - } else { /* E1H */ + } else { REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0); - bnx2x_set_eth_mac_addr_e1h(bp, 0); + bnx2x_set_eth_mac(bp, 0); for (i = 0; i < MC_HASH_SIZE; i++) REG_WR(bp, MC_HASH_OFFSET(bp, i), 0); - - REG_WR(bp, MISC_REG_E1HMF_MODE, 0); } + #ifdef BCM_CNIC /* Clear iSCSI L2 MAC */ mutex_lock(&bp->cnic_mutex); @@ -5286,33 +6907,44 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) /* Close multi and leading connections Completions for ramrods are collected in a synchronous way */ - for_each_nondefault_queue(bp, i) - if (bnx2x_stop_multi(bp, i)) + for_each_queue(bp, i) + + if (bnx2x_stop_client(bp, i)) +#ifdef BNX2X_STOP_ON_ERROR + return; +#else goto unload_error; +#endif - rc = bnx2x_stop_leading(bp); + rc = bnx2x_func_stop(bp); if (rc) { - BNX2X_ERR("Stop leading failed!\n"); + BNX2X_ERR("Function stop failed!\n"); #ifdef BNX2X_STOP_ON_ERROR - return -EBUSY; + return; #else goto unload_error; #endif } - +#ifndef BNX2X_STOP_ON_ERROR unload_error: +#endif if (!BP_NOMCP(bp)) - reset_code = bnx2x_fw_command(bp, reset_code); + reset_code = bnx2x_fw_command(bp, reset_code, 0); else { - DP(NETIF_MSG_IFDOWN, "NO MCP - load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - load_count[0]--; - load_count[1 + port]--; - DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts %d, %d, %d\n", - load_count[0], load_count[1], load_count[2]); - if (load_count[0] == 0) + DP(NETIF_MSG_IFDOWN, "NO MCP - load counts[%d] " + "%d, %d, %d\n", BP_PATH(bp), + load_count[BP_PATH(bp)][0], + load_count[BP_PATH(bp)][1], + load_count[BP_PATH(bp)][2]); + load_count[BP_PATH(bp)][0]--; + load_count[BP_PATH(bp)][1 + port]--; + DP(NETIF_MSG_IFDOWN, "NO MCP - new load counts[%d] " + "%d, %d, %d\n", BP_PATH(bp), + load_count[BP_PATH(bp)][0], load_count[BP_PATH(bp)][1], + load_count[BP_PATH(bp)][2]); + if (load_count[BP_PATH(bp)][0] == 0) reset_code = FW_MSG_CODE_DRV_UNLOAD_COMMON; - else if (load_count[1 + port] == 0) + else if (load_count[BP_PATH(bp)][1 + port] == 0) reset_code = FW_MSG_CODE_DRV_UNLOAD_PORT; else reset_code = FW_MSG_CODE_DRV_UNLOAD_FUNCTION; @@ -5322,12 +6954,18 @@ void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode) (reset_code == FW_MSG_CODE_DRV_UNLOAD_PORT)) bnx2x__link_reset(bp); + /* Disable HW interrupts, NAPI */ + bnx2x_netif_stop(bp, 1); + + /* Release IRQs */ + bnx2x_free_irq(bp); + /* Reset the chip */ bnx2x_reset_chip(bp, reset_code); /* Report UNLOAD_DONE to MCP */ if (!BP_NOMCP(bp)) - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); } @@ -5353,7 +6991,6 @@ void bnx2x_disable_close_the_gate(struct bnx2x *bp) } } - /* Close gates #2, #3 and #4: */ static void bnx2x_set_234_gates(struct bnx2x *bp, bool close) { @@ -5399,15 +7036,13 @@ static void bnx2x_clp_reset_prep(struct bnx2x *bp, u32 *magic_val) static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val) { /* Restore the `magic' bit value... */ - /* u32 val = SHMEM_RD(bp, mf_cfg.shared_mf_config.clp_mb); - SHMEM_WR(bp, mf_cfg.shared_mf_config.clp_mb, - (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); */ u32 val = MF_CFG_RD(bp, shared_mf_config.clp_mb); MF_CFG_WR(bp, shared_mf_config.clp_mb, (val & (~SHARED_MF_CLP_MAGIC)) | magic_val); } -/* Prepares for MCP reset: takes care of CLP configurations. +/** + * Prepares for MCP reset: takes care of CLP configurations. * * @param bp * @param magic_val Old value of 'magic' bit. @@ -5805,39 +7440,23 @@ static void bnx2x_reset_task(struct work_struct *work) * Init service functions */ -static inline u32 bnx2x_get_pretend_reg(struct bnx2x *bp, int func) -{ - switch (func) { - case 0: return PXP2_REG_PGL_PRETEND_FUNC_F0; - case 1: return PXP2_REG_PGL_PRETEND_FUNC_F1; - case 2: return PXP2_REG_PGL_PRETEND_FUNC_F2; - case 3: return PXP2_REG_PGL_PRETEND_FUNC_F3; - case 4: return PXP2_REG_PGL_PRETEND_FUNC_F4; - case 5: return PXP2_REG_PGL_PRETEND_FUNC_F5; - case 6: return PXP2_REG_PGL_PRETEND_FUNC_F6; - case 7: return PXP2_REG_PGL_PRETEND_FUNC_F7; - default: - BNX2X_ERR("Unsupported function index: %d\n", func); - return (u32)(-1); - } +u32 bnx2x_get_pretend_reg(struct bnx2x *bp) +{ + u32 base = PXP2_REG_PGL_PRETEND_FUNC_F0; + u32 stride = PXP2_REG_PGL_PRETEND_FUNC_F1 - base; + return base + (BP_ABS_FUNC(bp)) * stride; } -static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func) +static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp) { - u32 reg = bnx2x_get_pretend_reg(bp, orig_func), new_val; + u32 reg = bnx2x_get_pretend_reg(bp); /* Flush all outstanding writes */ mmiowb(); /* Pretend to be function 0 */ REG_WR(bp, reg, 0); - /* Flush the GRC transaction (in the chip) */ - new_val = REG_RD(bp, reg); - if (new_val != 0) { - BNX2X_ERR("Hmmm... Pretend register wasn't updated: (0,%d)!\n", - new_val); - BUG(); - } + REG_RD(bp, reg); /* Flush the GRC transaction (in the chip) */ /* From now we are in the "like-E1" mode */ bnx2x_int_disable(bp); @@ -5845,22 +7464,17 @@ static void bnx2x_undi_int_disable_e1h(struct bnx2x *bp, int orig_func) /* Flush all outstanding writes */ mmiowb(); - /* Restore the original funtion settings */ - REG_WR(bp, reg, orig_func); - new_val = REG_RD(bp, reg); - if (new_val != orig_func) { - BNX2X_ERR("Hmmm... Pretend register wasn't updated: (%d,%d)!\n", - orig_func, new_val); - BUG(); - } + /* Restore the original function */ + REG_WR(bp, reg, BP_ABS_FUNC(bp)); + REG_RD(bp, reg); } -static inline void bnx2x_undi_int_disable(struct bnx2x *bp, int func) +static inline void bnx2x_undi_int_disable(struct bnx2x *bp) { - if (CHIP_IS_E1H(bp)) - bnx2x_undi_int_disable_e1h(bp, func); - else + if (CHIP_IS_E1(bp)) bnx2x_int_disable(bp); + else + bnx2x_undi_int_disable_e1h(bp); } static void __devinit bnx2x_undi_unload(struct bnx2x *bp) @@ -5877,8 +7491,8 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) val = REG_RD(bp, DORQ_REG_NORM_CID_OFST); if (val == 0x7) { u32 reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - /* save our func */ - int func = BP_FUNC(bp); + /* save our pf_num */ + int orig_pf_num = bp->pf_num; u32 swap_en; u32 swap_val; @@ -5888,32 +7502,33 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) BNX2X_DEV_INFO("UNDI is active! reset device\n"); /* try unload UNDI on port 0 */ - bp->func = 0; + bp->pf_num = 0; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); - reset_code = bnx2x_fw_command(bp, reset_code); + reset_code = bnx2x_fw_command(bp, reset_code, 0); /* if UNDI is loaded on the other port */ if (reset_code != FW_MSG_CODE_DRV_UNLOAD_COMMON) { /* send "DONE" for previous unload */ - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, + DRV_MSG_CODE_UNLOAD_DONE, 0); /* unload UNDI on port 1 */ - bp->func = 1; + bp->pf_num = 1; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; - bnx2x_fw_command(bp, reset_code); + bnx2x_fw_command(bp, reset_code, 0); } /* now it's safe to release the lock */ bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); - bnx2x_undi_int_disable(bp, func); + bnx2x_undi_int_disable(bp); /* close input traffic and wait for it */ /* Do not rcv packets to BRB */ @@ -5949,14 +7564,13 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) REG_WR(bp, NIG_REG_STRAP_OVERRIDE, swap_en); /* send unload done to the MCP */ - bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); /* restore our func and fw_seq */ - bp->func = func; + bp->pf_num = orig_pf_num; bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->func].drv_mb_header) & + (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); - } else bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); } @@ -5978,6 +7592,40 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val = REG_RD(bp, MISC_REG_BOND_ID); id |= (val & 0xf); bp->common.chip_id = id; + + /* Set doorbell size */ + bp->db_size = (1 << BNX2X_DB_SHIFT); + + if (CHIP_IS_E2(bp)) { + val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR); + if ((val & 1) == 0) + val = REG_RD(bp, MISC_REG_PORT4MODE_EN); + else + val = (val >> 1) & 1; + BNX2X_DEV_INFO("chip is in %s\n", val ? "4_PORT_MODE" : + "2_PORT_MODE"); + bp->common.chip_port_mode = val ? CHIP_4_PORT_MODE : + CHIP_2_PORT_MODE; + + if (CHIP_MODE_IS_4_PORT(bp)) + bp->pfid = (bp->pf_num >> 1); /* 0..3 */ + else + bp->pfid = (bp->pf_num & 0x6); /* 0, 2, 4, 6 */ + } else { + bp->common.chip_port_mode = CHIP_PORT_MODE_NONE; /* N/A */ + bp->pfid = bp->pf_num; /* 0..7 */ + } + + /* + * set base FW non-default (fast path) status block id, this value is + * used to initialize the fw_sb_id saved on the fp/queue structure to + * determine the id used by the FW. + */ + if (CHIP_IS_E1x(bp)) + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E1x; + else /* E2 */ + bp->base_fw_ndsb = BP_PORT(bp) * FP_SB_MAX_E2; + bp->link_params.chip_id = bp->common.chip_id; BNX2X_DEV_INFO("chip ID is 0x%x\n", id); @@ -5995,14 +7643,15 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) bp->common.flash_size, bp->common.flash_size); bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR); - bp->common.shmem2_base = REG_RD(bp, MISC_REG_GENERIC_CR_0); + bp->common.shmem2_base = REG_RD(bp, (BP_PATH(bp) ? + MISC_REG_GENERIC_CR_1 : + MISC_REG_GENERIC_CR_0)); bp->link_params.shmem_base = bp->common.shmem_base; + bp->link_params.shmem2_base = bp->common.shmem2_base; BNX2X_DEV_INFO("shmem offset 0x%x shmem2 offset 0x%x\n", bp->common.shmem_base, bp->common.shmem2_base); - if (!bp->common.shmem_base || - (bp->common.shmem_base < 0xA0000) || - (bp->common.shmem_base >= 0xC0000)) { + if (!bp->common.shmem_base) { BNX2X_DEV_INFO("MCP not active\n"); bp->flags |= NO_MCP_FLAG; return; @@ -6011,7 +7660,7 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]); if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) - BNX2X_ERROR("BAD MCP validity signature\n"); + BNX2X_ERR("BAD MCP validity signature\n"); bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config); BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config); @@ -6035,12 +7684,16 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) if (val < BNX2X_BC_VER) { /* for now only warn * later we might need to enforce this */ - BNX2X_ERROR("This driver needs bc_ver %X but found %X, " - "please upgrade BC\n", BNX2X_BC_VER, val); + BNX2X_ERR("This driver needs bc_ver %X but found %X, " + "please upgrade BC\n", BNX2X_BC_VER, val); } bp->link_params.feature_config_flags |= - (val >= REQ_BC_VER_4_VRFY_OPT_MDL) ? - FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + (val >= REQ_BC_VER_4_VRFY_FIRST_PHY_OPT_MDL) ? + FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY : 0; + + bp->link_params.feature_config_flags |= + (val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ? + FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0; if (BP_E1HVN(bp) == 0) { pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc); @@ -6061,404 +7714,348 @@ static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) val, val2, val3, val4); } -static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, - u32 switch_cfg) -{ - int port = BP_PORT(bp); - u32 ext_phy_type; - - switch (switch_cfg) { - case SWITCH_CFG_1G: - BNX2X_DEV_INFO("switch_cfg 0x%x (1G)\n", switch_cfg); - - ext_phy_type = - SERDES_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: - BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: - BNX2X_DEV_INFO("ext_phy_type 0x%x (5482)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - default: - BNX2X_ERR("NVRAM config error. " - "BAD SerDes ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); - return; - } - - bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR + - port*0x10); - BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); - break; - - case SWITCH_CFG_10G: - BNX2X_DEV_INFO("switch_cfg 0x%x (10G)\n", switch_cfg); - - ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); - switch (ext_phy_type) { - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: - BNX2X_DEV_INFO("ext_phy_type 0x%x (Direct)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8072)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8073)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_2500baseX_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8705)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; - - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8706)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; +#define IGU_FID(val) GET_FIELD((val), IGU_REG_MAPPING_MEMORY_FID) +#define IGU_VEC(val) GET_FIELD((val), IGU_REG_MAPPING_MEMORY_VECTOR) - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8726)\n", - ext_phy_type); +static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp) +{ + int pfid = BP_FUNC(bp); + int vn = BP_E1HVN(bp); + int igu_sb_id; + u32 val; + u8 fid; - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + bp->igu_base_sb = 0xff; + bp->igu_sb_cnt = 0; + if (CHIP_INT_MODE_IS_BC(bp)) { + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, + bp->l2_cid_count); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: - BNX2X_DEV_INFO("ext_phy_type 0x%x (8727)\n", - ext_phy_type); + bp->igu_base_sb = (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn) * + FP_SB_MAX_E1x; - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_Autoneg | - SUPPORTED_FIBRE | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + bp->igu_dsb_id = E1HVN_MAX * FP_SB_MAX_E1x + + (CHIP_MODE_IS_4_PORT(bp) ? pfid : vn); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: - BNX2X_DEV_INFO("ext_phy_type 0x%x (SFX7101)\n", - ext_phy_type); + return; + } - bp->port.supported |= (SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; + /* IGU in normal mode - read CAM */ + for (igu_sb_id = 0; igu_sb_id < IGU_REG_MAPPING_MEMORY_SIZE; + igu_sb_id++) { + val = REG_RD(bp, IGU_REG_MAPPING_MEMORY + igu_sb_id * 4); + if (!(val & IGU_REG_MAPPING_MEMORY_VALID)) + continue; + fid = IGU_FID(val); + if ((fid & IGU_FID_ENCODE_IS_PF)) { + if ((fid & IGU_FID_PF_NUM_MASK) != pfid) + continue; + if (IGU_VEC(val) == 0) + /* default status block */ + bp->igu_dsb_id = igu_sb_id; + else { + if (bp->igu_base_sb == 0xff) + bp->igu_base_sb = igu_sb_id; + bp->igu_sb_cnt++; + } + } + } + bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, bp->l2_cid_count); + if (bp->igu_sb_cnt == 0) + BNX2X_ERR("CAM configuration error\n"); +} - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: - BNX2X_DEV_INFO("ext_phy_type 0x%x (BCM8481)\n", - ext_phy_type); - - bp->port.supported |= (SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full | - SUPPORTED_10000baseT_Full | - SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_Pause | - SUPPORTED_Asym_Pause); - break; +static void __devinit bnx2x_link_settings_supported(struct bnx2x *bp, + u32 switch_cfg) +{ + int cfg_size = 0, idx, port = BP_PORT(bp); - case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: - BNX2X_ERR("XGXS PHY Failure detected 0x%x\n", - bp->link_params.ext_phy_config); - break; + /* Aggregation of supported attributes of all external phys */ + bp->port.supported[0] = 0; + bp->port.supported[1] = 0; + switch (bp->link_params.num_phys) { + case 1: + bp->port.supported[0] = bp->link_params.phy[INT_PHY].supported; + cfg_size = 1; + break; + case 2: + bp->port.supported[0] = bp->link_params.phy[EXT_PHY1].supported; + cfg_size = 1; + break; + case 3: + if (bp->link_params.multi_phy_config & + PORT_HW_CFG_PHY_SWAPPED_ENABLED) { + bp->port.supported[1] = + bp->link_params.phy[EXT_PHY1].supported; + bp->port.supported[0] = + bp->link_params.phy[EXT_PHY2].supported; + } else { + bp->port.supported[0] = + bp->link_params.phy[EXT_PHY1].supported; + bp->port.supported[1] = + bp->link_params.phy[EXT_PHY2].supported; + } + cfg_size = 2; + break; + } - default: - BNX2X_ERR("NVRAM config error. " - "BAD XGXS ext_phy_config 0x%x\n", - bp->link_params.ext_phy_config); + if (!(bp->port.supported[0] || bp->port.supported[1])) { + BNX2X_ERR("NVRAM config error. BAD phy config." + "PHY1 config 0x%x, PHY2 config 0x%x\n", + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config), + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config2)); return; - } + } + + switch (switch_cfg) { + case SWITCH_CFG_1G: + bp->port.phy_addr = REG_RD(bp, NIG_REG_SERDES0_CTRL_PHY_ADDR + + port*0x10); + BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); + break; + case SWITCH_CFG_10G: bp->port.phy_addr = REG_RD(bp, NIG_REG_XGXS0_CTRL_PHY_ADDR + port*0x18); BNX2X_DEV_INFO("phy_addr 0x%x\n", bp->port.phy_addr); - break; default: BNX2X_ERR("BAD switch_cfg link_config 0x%x\n", - bp->port.link_config); + bp->port.link_config[0]); return; } - bp->link_params.phy_addr = bp->port.phy_addr; - - /* mask what we support according to speed_cap_mask */ - if (!(bp->link_params.speed_cap_mask & + /* mask what we support according to speed_cap_mask per configuration */ + for (idx = 0; idx < cfg_size; idx++) { + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) - bp->port.supported &= ~SUPPORTED_10baseT_Half; + bp->port.supported[idx] &= ~SUPPORTED_10baseT_Half; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL)) - bp->port.supported &= ~SUPPORTED_10baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_10baseT_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) - bp->port.supported &= ~SUPPORTED_100baseT_Half; + bp->port.supported[idx] &= ~SUPPORTED_100baseT_Half; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL)) - bp->port.supported &= ~SUPPORTED_100baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_100baseT_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) - bp->port.supported &= ~(SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); + bp->port.supported[idx] &= ~(SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full); - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)) - bp->port.supported &= ~SUPPORTED_2500baseX_Full; + bp->port.supported[idx] &= ~SUPPORTED_2500baseX_Full; - if (!(bp->link_params.speed_cap_mask & + if (!(bp->link_params.speed_cap_mask[idx] & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) - bp->port.supported &= ~SUPPORTED_10000baseT_Full; + bp->port.supported[idx] &= ~SUPPORTED_10000baseT_Full; + + } - BNX2X_DEV_INFO("supported 0x%x\n", bp->port.supported); + BNX2X_DEV_INFO("supported 0x%x 0x%x\n", bp->port.supported[0], + bp->port.supported[1]); } static void __devinit bnx2x_link_settings_requested(struct bnx2x *bp) { - bp->link_params.req_duplex = DUPLEX_FULL; + u32 link_config, idx, cfg_size = 0; + bp->port.advertising[0] = 0; + bp->port.advertising[1] = 0; + switch (bp->link_params.num_phys) { + case 1: + case 2: + cfg_size = 1; + break; + case 3: + cfg_size = 2; + break; + } + for (idx = 0; idx < cfg_size; idx++) { + bp->link_params.req_duplex[idx] = DUPLEX_FULL; + link_config = bp->port.link_config[idx]; + switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) { + case PORT_FEATURE_LINK_SPEED_AUTO: + if (bp->port.supported[idx] & SUPPORTED_Autoneg) { + bp->link_params.req_line_speed[idx] = + SPEED_AUTO_NEG; + bp->port.advertising[idx] |= + bp->port.supported[idx]; + } else { + /* force 10G, no AN */ + bp->link_params.req_line_speed[idx] = + SPEED_10000; + bp->port.advertising[idx] |= + (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + continue; + } + break; - switch (bp->port.link_config & PORT_FEATURE_LINK_SPEED_MASK) { - case PORT_FEATURE_LINK_SPEED_AUTO: - if (bp->port.supported & SUPPORTED_Autoneg) { - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->port.advertising = bp->port.supported; - } else { - u32 ext_phy_type = - XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); + case PORT_FEATURE_LINK_SPEED_10M_FULL: + if (bp->port.supported[idx] & SUPPORTED_10baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_10; + bp->port.advertising[idx] |= + (ADVERTISED_10baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - if ((ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || - (ext_phy_type == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706)) { - /* force 10G, no AN */ - bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = - (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); - break; + case PORT_FEATURE_LINK_SPEED_10M_HALF: + if (bp->port.supported[idx] & SUPPORTED_10baseT_Half) { + bp->link_params.req_line_speed[idx] = + SPEED_10; + bp->link_params.req_duplex[idx] = + DUPLEX_HALF; + bp->port.advertising[idx] |= + (ADVERTISED_10baseT_Half | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, + bp->link_params.speed_cap_mask[idx]); + return; } - BNX2X_ERR("NVRAM config error. " - "Invalid link_config 0x%x" - " Autoneg not supported\n", - bp->port.link_config); - return; - } - break; + break; - case PORT_FEATURE_LINK_SPEED_10M_FULL: - if (bp->port.supported & SUPPORTED_10baseT_Full) { - bp->link_params.req_line_speed = SPEED_10; - bp->port.advertising = (ADVERTISED_10baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } - break; + case PORT_FEATURE_LINK_SPEED_100M_FULL: + if (bp->port.supported[idx] & + SUPPORTED_100baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_100; + bp->port.advertising[idx] |= + (ADVERTISED_100baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " + "Invalid link_config 0x%x" + " speed_cap_mask 0x%x\n", + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_10M_HALF: - if (bp->port.supported & SUPPORTED_10baseT_Half) { - bp->link_params.req_line_speed = SPEED_10; - bp->link_params.req_duplex = DUPLEX_HALF; - bp->port.advertising = (ADVERTISED_10baseT_Half | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + case PORT_FEATURE_LINK_SPEED_100M_HALF: + if (bp->port.supported[idx] & + SUPPORTED_100baseT_Half) { + bp->link_params.req_line_speed[idx] = + SPEED_100; + bp->link_params.req_duplex[idx] = + DUPLEX_HALF; + bp->port.advertising[idx] |= + (ADVERTISED_100baseT_Half | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } - break; + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_100M_FULL: - if (bp->port.supported & SUPPORTED_100baseT_Full) { - bp->link_params.req_line_speed = SPEED_100; - bp->port.advertising = (ADVERTISED_100baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + case PORT_FEATURE_LINK_SPEED_1G: + if (bp->port.supported[idx] & + SUPPORTED_1000baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_1000; + bp->port.advertising[idx] |= + (ADVERTISED_1000baseT_Full | + ADVERTISED_TP); + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } - break; + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_100M_HALF: - if (bp->port.supported & SUPPORTED_100baseT_Half) { - bp->link_params.req_line_speed = SPEED_100; - bp->link_params.req_duplex = DUPLEX_HALF; - bp->port.advertising = (ADVERTISED_100baseT_Half | + case PORT_FEATURE_LINK_SPEED_2_5G: + if (bp->port.supported[idx] & + SUPPORTED_2500baseX_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_2500; + bp->port.advertising[idx] |= + (ADVERTISED_2500baseX_Full | ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } - break; + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_1G: - if (bp->port.supported & SUPPORTED_1000baseT_Full) { - bp->link_params.req_line_speed = SPEED_1000; - bp->port.advertising = (ADVERTISED_1000baseT_Full | - ADVERTISED_TP); - } else { - BNX2X_ERROR("NVRAM config error. " + case PORT_FEATURE_LINK_SPEED_10G_CX4: + case PORT_FEATURE_LINK_SPEED_10G_KX4: + case PORT_FEATURE_LINK_SPEED_10G_KR: + if (bp->port.supported[idx] & + SUPPORTED_10000baseT_Full) { + bp->link_params.req_line_speed[idx] = + SPEED_10000; + bp->port.advertising[idx] |= + (ADVERTISED_10000baseT_Full | + ADVERTISED_FIBRE); + } else { + BNX2X_ERROR("NVRAM config error. " "Invalid link_config 0x%x" " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; - } - break; + link_config, + bp->link_params.speed_cap_mask[idx]); + return; + } + break; - case PORT_FEATURE_LINK_SPEED_2_5G: - if (bp->port.supported & SUPPORTED_2500baseX_Full) { - bp->link_params.req_line_speed = SPEED_2500; - bp->port.advertising = (ADVERTISED_2500baseX_Full | - ADVERTISED_TP); - } else { + default: BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; + "BAD link speed link_config 0x%x\n", + link_config); + bp->link_params.req_line_speed[idx] = + SPEED_AUTO_NEG; + bp->port.advertising[idx] = + bp->port.supported[idx]; + break; } - break; - case PORT_FEATURE_LINK_SPEED_10G_CX4: - case PORT_FEATURE_LINK_SPEED_10G_KX4: - case PORT_FEATURE_LINK_SPEED_10G_KR: - if (bp->port.supported & SUPPORTED_10000baseT_Full) { - bp->link_params.req_line_speed = SPEED_10000; - bp->port.advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); - } else { - BNX2X_ERROR("NVRAM config error. " - "Invalid link_config 0x%x" - " speed_cap_mask 0x%x\n", - bp->port.link_config, - bp->link_params.speed_cap_mask); - return; + bp->link_params.req_flow_ctrl[idx] = (link_config & + PORT_FEATURE_FLOW_CONTROL_MASK); + if ((bp->link_params.req_flow_ctrl[idx] == + BNX2X_FLOW_CTRL_AUTO) && + !(bp->port.supported[idx] & SUPPORTED_Autoneg)) { + bp->link_params.req_flow_ctrl[idx] = + BNX2X_FLOW_CTRL_NONE; } - break; - default: - BNX2X_ERROR("NVRAM config error. " - "BAD link speed link_config 0x%x\n", - bp->port.link_config); - bp->link_params.req_line_speed = SPEED_AUTO_NEG; - bp->port.advertising = bp->port.supported; - break; + BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl" + " 0x%x advertising 0x%x\n", + bp->link_params.req_line_speed[idx], + bp->link_params.req_duplex[idx], + bp->link_params.req_flow_ctrl[idx], + bp->port.advertising[idx]); } - - bp->link_params.req_flow_ctrl = (bp->port.link_config & - PORT_FEATURE_FLOW_CONTROL_MASK); - if ((bp->link_params.req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && - !(bp->port.supported & SUPPORTED_Autoneg)) - bp->link_params.req_flow_ctrl = BNX2X_FLOW_CTRL_NONE; - - BNX2X_DEV_INFO("req_line_speed %d req_duplex %d req_flow_ctrl 0x%x" - " advertising 0x%x\n", - bp->link_params.req_line_speed, - bp->link_params.req_duplex, - bp->link_params.req_flow_ctrl, bp->port.advertising); } static void __devinit bnx2x_set_mac_buf(u8 *mac_buf, u32 mac_lo, u16 mac_hi) @@ -6474,48 +8071,28 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) int port = BP_PORT(bp); u32 val, val2; u32 config; - u16 i; - u32 ext_phy_type; + u32 ext_phy_type, ext_phy_config;; bp->link_params.bp = bp; bp->link_params.port = port; bp->link_params.lane_config = SHMEM_RD(bp, dev_info.port_hw_config[port].lane_config); - bp->link_params.ext_phy_config = - SHMEM_RD(bp, - dev_info.port_hw_config[port].external_phy_config); - /* BCM8727_NOC => BCM8727 no over current */ - if (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config) == - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC) { - bp->link_params.ext_phy_config &= - ~PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK; - bp->link_params.ext_phy_config |= - PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727; - bp->link_params.feature_config_flags |= - FEATURE_CONFIG_BCM8727_NOC; - } - bp->link_params.speed_cap_mask = + bp->link_params.speed_cap_mask[0] = SHMEM_RD(bp, dev_info.port_hw_config[port].speed_capability_mask); - - bp->port.link_config = + bp->link_params.speed_cap_mask[1] = + SHMEM_RD(bp, + dev_info.port_hw_config[port].speed_capability_mask2); + bp->port.link_config[0] = SHMEM_RD(bp, dev_info.port_feature_config[port].link_config); - /* Get the 4 lanes xgxs config rx and tx */ - for (i = 0; i < 2; i++) { - val = SHMEM_RD(bp, - dev_info.port_hw_config[port].xgxs_config_rx[i<<1]); - bp->link_params.xgxs_config_rx[i << 1] = ((val>>16) & 0xffff); - bp->link_params.xgxs_config_rx[(i << 1) + 1] = (val & 0xffff); - - val = SHMEM_RD(bp, - dev_info.port_hw_config[port].xgxs_config_tx[i<<1]); - bp->link_params.xgxs_config_tx[i << 1] = ((val>>16) & 0xffff); - bp->link_params.xgxs_config_tx[(i << 1) + 1] = (val & 0xffff); - } + bp->port.link_config[1] = + SHMEM_RD(bp, dev_info.port_feature_config[port].link_config2); + bp->link_params.multi_phy_config = + SHMEM_RD(bp, dev_info.port_hw_config[port].multi_phy_config); /* If the device is capable of WoL, set the default state according * to the HW */ @@ -6523,14 +8100,15 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) bp->wol = (!(bp->flags & NO_WOL_FLAG) && (config & PORT_FEATURE_WOL_ENABLED)); - BNX2X_DEV_INFO("lane_config 0x%08x ext_phy_config 0x%08x" - " speed_cap_mask 0x%08x link_config 0x%08x\n", + BNX2X_DEV_INFO("lane_config 0x%08x " + "speed_cap_mask0 0x%08x link_config0 0x%08x\n", bp->link_params.lane_config, - bp->link_params.ext_phy_config, - bp->link_params.speed_cap_mask, bp->port.link_config); + bp->link_params.speed_cap_mask[0], + bp->port.link_config[0]); - bp->link_params.switch_cfg |= (bp->port.link_config & - PORT_FEATURE_CONNECTED_SWITCH_MASK); + bp->link_params.switch_cfg = (bp->port.link_config[0] & + PORT_FEATURE_CONNECTED_SWITCH_MASK); + bnx2x_phy_probe(&bp->link_params); bnx2x_link_settings_supported(bp, bp->link_params.switch_cfg); bnx2x_link_settings_requested(bp); @@ -6539,14 +8117,17 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) * If connected directly, work with the internal PHY, otherwise, work * with the external PHY */ - ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); + ext_phy_config = + SHMEM_RD(bp, + dev_info.port_hw_config[port].external_phy_config); + ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config); if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) - bp->mdio.prtad = bp->link_params.phy_addr; + bp->mdio.prtad = bp->port.phy_addr; else if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) && (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) bp->mdio.prtad = - XGXS_EXT_PHY_ADDR(bp->link_params.ext_phy_config); + XGXS_EXT_PHY_ADDR(ext_phy_config); val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper); val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower); @@ -6563,41 +8144,74 @@ static void __devinit bnx2x_get_port_hwinfo(struct bnx2x *bp) static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) { - int func = BP_FUNC(bp); + int func = BP_ABS_FUNC(bp); + int vn; u32 val, val2; int rc = 0; bnx2x_get_common_hwinfo(bp); - bp->e1hov = 0; - bp->e1hmf = 0; - if (CHIP_IS_E1H(bp) && !BP_NOMCP(bp)) { - bp->mf_config = - SHMEM_RD(bp, mf_cfg.func_mf_config[func].config); + if (CHIP_IS_E1x(bp)) { + bp->common.int_block = INT_BLOCK_HC; + + bp->igu_dsb_id = DEF_SB_IGU_ID; + bp->igu_base_sb = 0; + bp->igu_sb_cnt = min_t(u8, FP_SB_MAX_E1x, bp->l2_cid_count); + } else { + bp->common.int_block = INT_BLOCK_IGU; + val = REG_RD(bp, IGU_REG_BLOCK_CONFIGURATION); + if (val & IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN) { + DP(NETIF_MSG_PROBE, "IGU Backward Compatible Mode\n"); + bp->common.int_block |= INT_BLOCK_MODE_BW_COMP; + } else + DP(NETIF_MSG_PROBE, "IGU Normal Mode\n"); + + bnx2x_get_igu_cam_info(bp); + + } + DP(NETIF_MSG_PROBE, "igu_dsb_id %d igu_base_sb %d igu_sb_cnt %d\n", + bp->igu_dsb_id, bp->igu_base_sb, bp->igu_sb_cnt); + + /* + * Initialize MF configuration + */ + + bp->mf_ov = 0; + bp->mf_mode = 0; + vn = BP_E1HVN(bp); + if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) { + if (SHMEM2_HAS(bp, mf_cfg_addr)) + bp->common.mf_cfg_base = SHMEM2_RD(bp, mf_cfg_addr); + else + bp->common.mf_cfg_base = bp->common.shmem_base + + offsetof(struct shmem_region, func_mb) + + E1H_FUNC_MAX * sizeof(struct drv_func_mb); + bp->mf_config[vn] = + MF_CFG_RD(bp, func_mf_config[func].config); - val = (SHMEM_RD(bp, mf_cfg.func_mf_config[FUNC_0].e1hov_tag) & + val = (MF_CFG_RD(bp, func_mf_config[FUNC_0].e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) - bp->e1hmf = 1; + bp->mf_mode = 1; BNX2X_DEV_INFO("%s function mode\n", - IS_E1HMF(bp) ? "multi" : "single"); + IS_MF(bp) ? "multi" : "single"); - if (IS_E1HMF(bp)) { - val = (SHMEM_RD(bp, mf_cfg.func_mf_config[func]. + if (IS_MF(bp)) { + val = (MF_CFG_RD(bp, func_mf_config[func]. e1hov_tag) & FUNC_MF_CFG_E1HOV_TAG_MASK); if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - bp->e1hov = val; - BNX2X_DEV_INFO("E1HOV for func %d is %d " + bp->mf_ov = val; + BNX2X_DEV_INFO("MF OV for func %d is %d " "(0x%04x)\n", - func, bp->e1hov, bp->e1hov); + func, bp->mf_ov, bp->mf_ov); } else { - BNX2X_ERROR("No valid E1HOV for func %d," + BNX2X_ERROR("No valid MF OV for func %d," " aborting\n", func); rc = -EPERM; } } else { - if (BP_E1HVN(bp)) { + if (BP_VN(bp)) { BNX2X_ERROR("VN %d in single function mode," " aborting\n", BP_E1HVN(bp)); rc = -EPERM; @@ -6605,17 +8219,31 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) } } + /* adjust igu_sb_cnt to MF for E1x */ + if (CHIP_IS_E1x(bp) && IS_MF(bp)) + bp->igu_sb_cnt /= E1HVN_MAX; + + /* + * adjust E2 sb count: to be removed when FW will support + * more then 16 L2 clients + */ +#define MAX_L2_CLIENTS 16 + if (CHIP_IS_E2(bp)) + bp->igu_sb_cnt = min_t(u8, bp->igu_sb_cnt, + MAX_L2_CLIENTS / (IS_MF(bp) ? 4 : 1)); + if (!BP_NOMCP(bp)) { bnx2x_get_port_hwinfo(bp); - bp->fw_seq = (SHMEM_RD(bp, func_mb[func].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); + bp->fw_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } - if (IS_E1HMF(bp)) { - val2 = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_upper); - val = SHMEM_RD(bp, mf_cfg.func_mf_config[func].mac_lower); + if (IS_MF(bp)) { + val2 = MF_CFG_RD(bp, func_mf_config[func].mac_upper); + val = MF_CFG_RD(bp, func_mf_config[func].mac_lower); if ((val2 != FUNC_MF_CFG_UPPERMAC_DEFAULT) && (val != FUNC_MF_CFG_LOWERMAC_DEFAULT)) { bp->dev->dev_addr[0] = (u8)(val2 >> 8 & 0xff); @@ -6709,7 +8337,7 @@ static void __devinit bnx2x_read_fwinfo(struct bnx2x *bp) static int __devinit bnx2x_init_bp(struct bnx2x *bp) { - int func = BP_FUNC(bp); + int func; int timer_interval; int rc; @@ -6729,7 +8357,13 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) rc = bnx2x_get_hwinfo(bp); + if (!rc) + rc = bnx2x_alloc_mem_bp(bp); + bnx2x_read_fwinfo(bp); + + func = BP_FUNC(bp); + /* need to reset chip if undi was active */ if (!BP_NOMCP(bp)) bnx2x_undi_unload(bp); @@ -6771,13 +8405,12 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->mrrs = mrrs; bp->tx_ring_size = MAX_TX_AVAIL; - bp->rx_ring_size = MAX_RX_AVAIL; bp->rx_csum = 1; /* make sure that the numbers are in the right granularity */ - bp->tx_ticks = (50 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); - bp->rx_ticks = (25 / (4 * BNX2X_BTR)) * (4 * BNX2X_BTR); + bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR; + bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR; timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ); bp->current_interval = (poll ? poll : timer_interval); @@ -6869,81 +8502,22 @@ void bnx2x_set_rx_mode(struct net_device *dev) if (dev->flags & IFF_PROMISC) rx_mode = BNX2X_RX_MODE_PROMISC; - else if ((dev->flags & IFF_ALLMULTI) || ((netdev_mc_count(dev) > BNX2X_MAX_MULTICAST) && CHIP_IS_E1(bp))) rx_mode = BNX2X_RX_MODE_ALLMULTI; - else { /* some multicasts */ if (CHIP_IS_E1(bp)) { - int i, old, offset; - struct netdev_hw_addr *ha; - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - i = 0; - netdev_for_each_mc_addr(ha, dev) { - config->config_table[i]. - cam_entry.msb_mac_addr = - swab16(*(u16 *)&ha->addr[0]); - config->config_table[i]. - cam_entry.middle_mac_addr = - swab16(*(u16 *)&ha->addr[2]); - config->config_table[i]. - cam_entry.lsb_mac_addr = - swab16(*(u16 *)&ha->addr[4]); - config->config_table[i].cam_entry.flags = - cpu_to_le16(port); - config->config_table[i]. - target_table_entry.flags = 0; - config->config_table[i].target_table_entry. - clients_bit_vector = - cpu_to_le32(1 << BP_L_ID(bp)); - config->config_table[i]. - target_table_entry.vlan_id = 0; - - DP(NETIF_MSG_IFUP, - "setting MCAST[%d] (%04x:%04x:%04x)\n", i, - config->config_table[i]. - cam_entry.msb_mac_addr, - config->config_table[i]. - cam_entry.middle_mac_addr, - config->config_table[i]. - cam_entry.lsb_mac_addr); - i++; - } - old = config->hdr.length; - if (old > i) { - for (; i < old; i++) { - if (CAM_IS_INVALID(config-> - config_table[i])) { - /* already invalidated */ - break; - } - /* invalidate */ - CAM_INVALIDATE(config-> - config_table[i]); - } - } - - if (CHIP_REV_IS_SLOW(bp)) - offset = BNX2X_MAX_EMUL_MULTI*(1 + port); - else - offset = BNX2X_MAX_MULTICAST*(1 + port); - - config->hdr.length = i; - config->hdr.offset = offset; - config->hdr.client_id = bp->fp->cl_id; - config->hdr.reserved1 = 0; - - bp->set_mac_pending++; - smp_wmb(); + /* + * set mc list, do not wait as wait implies sleep + * and set_rx_mode can be invoked from non-sleepable + * context + */ + u8 offset = (CHIP_REV_IS_SLOW(bp) ? + BNX2X_MAX_EMUL_MULTI*(1 + port) : + BNX2X_MAX_MULTICAST*(1 + port)); - bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_SET_MAC, 0, - U64_HI(bnx2x_sp_mapping(bp, mcast_config)), - U64_LO(bnx2x_sp_mapping(bp, mcast_config)), - 0); + bnx2x_set_e1_mc_list(bp, offset); } else { /* E1H */ /* Accept one or more multicasts */ struct netdev_hw_addr *ha; @@ -6955,9 +8529,10 @@ void bnx2x_set_rx_mode(struct net_device *dev) netdev_for_each_mc_addr(ha, dev) { DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n", - ha->addr); + bnx2x_mc_addr(ha)); - crc = crc32c_le(0, ha->addr, ETH_ALEN); + crc = crc32c_le(0, bnx2x_mc_addr(ha), + ETH_ALEN); bit = (crc >> 24) & 0xff; regidx = bit >> 5; bit &= 0x1f; @@ -6974,7 +8549,6 @@ void bnx2x_set_rx_mode(struct net_device *dev) bnx2x_set_storm_rx_mode(bp); } - /* called with rtnl_lock */ static int bnx2x_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr) @@ -6982,23 +8556,15 @@ static int bnx2x_mdio_read(struct net_device *netdev, int prtad, struct bnx2x *bp = netdev_priv(netdev); u16 value; int rc; - u32 phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); DP(NETIF_MSG_LINK, "mdio_read: prtad 0x%x, devad 0x%x, addr 0x%x\n", prtad, devad, addr); - if (prtad != bp->mdio.prtad) { - DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n", - prtad, bp->mdio.prtad); - return -EINVAL; - } - /* The HW expects different devad if CL22 is used */ devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad; bnx2x_acquire_phy_lock(bp); - rc = bnx2x_cl45_read(bp, BP_PORT(bp), phy_type, prtad, - devad, addr, &value); + rc = bnx2x_phy_read(&bp->link_params, prtad, devad, addr, &value); bnx2x_release_phy_lock(bp); DP(NETIF_MSG_LINK, "mdio_read_val 0x%x rc = 0x%x\n", value, rc); @@ -7012,24 +8578,16 @@ static int bnx2x_mdio_write(struct net_device *netdev, int prtad, int devad, u16 addr, u16 value) { struct bnx2x *bp = netdev_priv(netdev); - u32 ext_phy_type = XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config); int rc; DP(NETIF_MSG_LINK, "mdio_write: prtad 0x%x, devad 0x%x, addr 0x%x," " value 0x%x\n", prtad, devad, addr, value); - if (prtad != bp->mdio.prtad) { - DP(NETIF_MSG_LINK, "prtad missmatch (cmd:0x%x != bp:0x%x)\n", - prtad, bp->mdio.prtad); - return -EINVAL; - } - /* The HW expects different devad if CL22 is used */ devad = (devad == MDIO_DEVAD_NONE) ? DEFAULT_PHY_DEV_ADDR : devad; bnx2x_acquire_phy_lock(bp); - rc = bnx2x_cl45_write(bp, BP_PORT(bp), ext_phy_type, prtad, - devad, addr, value); + rc = bnx2x_phy_write(&bp->link_params, prtad, devad, addr, value); bnx2x_release_phy_lock(bp); return rc; } @@ -7070,9 +8628,6 @@ static const struct net_device_ops bnx2x_netdev_ops = { .ndo_do_ioctl = bnx2x_ioctl, .ndo_change_mtu = bnx2x_change_mtu, .ndo_tx_timeout = bnx2x_tx_timeout, -#ifdef BCM_VLAN - .ndo_vlan_rx_register = bnx2x_vlan_rx_register, -#endif #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = poll_bnx2x, #endif @@ -7090,7 +8645,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, bp->dev = dev; bp->pdev = pdev; bp->flags = 0; - bp->func = PCI_FUNC(pdev->devfn); + bp->pf_num = PCI_FUNC(pdev->devfn); rc = pci_enable_device(pdev); if (rc) { @@ -7172,7 +8727,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, } bp->doorbells = ioremap_nocache(pci_resource_start(pdev, 2), - min_t(u64, BNX2X_DB_SIZE, + min_t(u64, BNX2X_DB_SIZE(bp), pci_resource_len(pdev, 2))); if (!bp->doorbells) { dev_err(&bp->pdev->dev, @@ -7204,9 +8759,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->features |= NETIF_F_HIGHDMA; dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->features |= NETIF_F_TSO6; -#ifdef BCM_VLAN dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX); - bp->flags |= (HW_VLAN_RX_FLAG | HW_VLAN_TX_FLAG); dev->vlan_features |= NETIF_F_SG; dev->vlan_features |= NETIF_F_HW_CSUM; @@ -7214,7 +8767,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, dev->vlan_features |= NETIF_F_HIGHDMA; dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN); dev->vlan_features |= NETIF_F_TSO6; -#endif /* get_port_hwinfo() will set prtad and mmds properly */ bp->mdio.prtad = MDIO_PRTAD_NONE; @@ -7259,7 +8811,7 @@ static void __devinit bnx2x_get_pcie_width_speed(struct bnx2x *bp, *speed = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT; } -static int __devinit bnx2x_check_firmware(struct bnx2x *bp) +static int bnx2x_check_firmware(struct bnx2x *bp) { const struct firmware *firmware = bp->firmware; struct bnx2x_fw_file_hdr *fw_hdr; @@ -7348,6 +8900,30 @@ static inline void bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n) } } +/** + * IRO array is stored in the following format: + * {base(24bit), m1(16bit), m2(16bit), m3(16bit), size(16bit) } + */ +static inline void bnx2x_prep_iro(const u8 *_source, u8 *_target, u32 n) +{ + const __be32 *source = (const __be32 *)_source; + struct iro *target = (struct iro *)_target; + u32 i, j, tmp; + + for (i = 0, j = 0; i < n/sizeof(struct iro); i++) { + target[i].base = be32_to_cpu(source[j]); + j++; + tmp = be32_to_cpu(source[j]); + target[i].m1 = (tmp >> 16) & 0xffff; + target[i].m2 = tmp & 0xffff; + j++; + tmp = be32_to_cpu(source[j]); + target[i].m3 = (tmp >> 16) & 0xffff; + target[i].size = tmp & 0xffff; + j++; + } +} + static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n) { const __be16 *source = (const __be16 *)_source; @@ -7370,7 +8946,7 @@ do { \ (u8 *)bp->arr, len); \ } while (0) -static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev) +int bnx2x_init_firmware(struct bnx2x *bp) { const char *fw_file_name; struct bnx2x_fw_file_hdr *fw_hdr; @@ -7380,22 +8956,24 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev) fw_file_name = FW_FILE_NAME_E1; else if (CHIP_IS_E1H(bp)) fw_file_name = FW_FILE_NAME_E1H; + else if (CHIP_IS_E2(bp)) + fw_file_name = FW_FILE_NAME_E2; else { - dev_err(dev, "Unsupported chip revision\n"); + BNX2X_ERR("Unsupported chip revision\n"); return -EINVAL; } - dev_info(dev, "Loading %s\n", fw_file_name); + BNX2X_DEV_INFO("Loading %s\n", fw_file_name); - rc = request_firmware(&bp->firmware, fw_file_name, dev); + rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); if (rc) { - dev_err(dev, "Can't load firmware file %s\n", fw_file_name); + BNX2X_ERR("Can't load firmware file %s\n", fw_file_name); goto request_firmware_exit; } rc = bnx2x_check_firmware(bp); if (rc) { - dev_err(dev, "Corrupt firmware file %s\n", fw_file_name); + BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); goto request_firmware_exit; } @@ -7429,9 +9007,13 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev) be32_to_cpu(fw_hdr->csem_int_table_data.offset); INIT_CSEM_PRAM_DATA(bp) = bp->firmware->data + be32_to_cpu(fw_hdr->csem_pram_data.offset); + /* IRO */ + BNX2X_ALLOC_AND_SET(iro_arr, iro_alloc_err, bnx2x_prep_iro); return 0; +iro_alloc_err: + kfree(bp->init_ops_offsets); init_offsets_alloc_err: kfree(bp->init_ops); init_ops_alloc_err: @@ -7442,6 +9024,15 @@ static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev) return rc; } +static inline int bnx2x_set_qm_cid_count(struct bnx2x *bp, int l2_cid_count) +{ + int cid_count = L2_FP_COUNT(l2_cid_count); + +#ifdef BCM_CNIC + cid_count += CNIC_CID_MAX; +#endif + return roundup(cid_count, QM_CID_ROUND); +} static int __devinit bnx2x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -7449,10 +9040,30 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, struct net_device *dev = NULL; struct bnx2x *bp; int pcie_width, pcie_speed; - int rc; + int rc, cid_count; + + switch (ent->driver_data) { + case BCM57710: + case BCM57711: + case BCM57711E: + cid_count = FP_SB_MAX_E1x; + break; + + case BCM57712: + case BCM57712E: + cid_count = FP_SB_MAX_E2; + break; + + default: + pr_err("Unknown board_type (%ld), aborting\n", + ent->driver_data); + return ENODEV; + } + + cid_count += CNIC_CONTEXT_USE; /* dev zeroed in init_etherdev */ - dev = alloc_etherdev_mq(sizeof(*bp), MAX_CONTEXT); + dev = alloc_etherdev_mq(sizeof(*bp), cid_count); if (!dev) { dev_err(&pdev->dev, "Cannot allocate net device\n"); return -ENOMEM; @@ -7463,6 +9074,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); + bp->l2_cid_count = cid_count; + rc = bnx2x_init_dev(pdev, dev); if (rc < 0) { free_netdev(dev); @@ -7473,12 +9086,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, if (rc) goto init_one_exit; - /* Set init arrays */ - rc = bnx2x_init_firmware(bp, &pdev->dev); - if (rc) { - dev_err(&pdev->dev, "Error loading firmware\n"); - goto init_one_exit; - } + /* calc qm_cid_count */ + bp->qm_cid_count = bnx2x_set_qm_cid_count(bp, cid_count); rc = register_netdev(dev); if (rc) { @@ -7486,11 +9095,23 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, goto init_one_exit; } + /* Configure interupt mode: try to enable MSI-X/MSI if + * needed, set bp->num_queues appropriately. + */ + bnx2x_set_int_mode(bp); + + /* Add all NAPI objects */ + bnx2x_add_all_napi(bp); + bnx2x_get_pcie_width_speed(bp, &pcie_width, &pcie_speed); + netdev_info(dev, "%s (%c%d) PCI-E x%d %s found at mem %lx," " IRQ %d, ", board_info[ent->driver_data].name, (CHIP_REV(bp) >> 12) + 'A', (CHIP_METAL(bp) >> 4), - pcie_width, (pcie_speed == 2) ? "5GHz (Gen2)" : "2.5GHz", + pcie_width, + ((!CHIP_IS_E2(bp) && pcie_speed == 2) || + (CHIP_IS_E2(bp) && pcie_speed == 1)) ? + "5GHz (Gen2)" : "2.5GHz", dev->base_addr, bp->pdev->irq); pr_cont("node addr %pM\n", dev->dev_addr); @@ -7527,20 +9148,23 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev) unregister_netdev(dev); + /* Delete all NAPI objects */ + bnx2x_del_all_napi(bp); + + /* Disable MSI/MSI-X */ + bnx2x_disable_msi(bp); + /* Make sure RESET task is not scheduled before continuing */ cancel_delayed_work_sync(&bp->reset_task); - kfree(bp->init_ops_offsets); - kfree(bp->init_ops); - kfree(bp->init_data); - release_firmware(bp->firmware); - if (bp->regview) iounmap(bp->regview); if (bp->doorbells) iounmap(bp->doorbells); + bnx2x_free_mem_bp(bp); + free_netdev(dev); if (atomic_read(&pdev->enable_cnt) == 1) @@ -7566,22 +9190,14 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp) DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); /* Release IRQs */ - bnx2x_free_irq(bp, false); - - if (CHIP_IS_E1(bp)) { - struct mac_configuration_cmd *config = - bnx2x_sp(bp, mcast_config); - - for (i = 0; i < config->hdr.length; i++) - CAM_INVALIDATE(config->config_table[i]); - } + bnx2x_free_irq(bp); /* Free SKBs, SGEs, TPA pool and driver internals */ bnx2x_free_skbs(bp); + for_each_queue(bp, i) bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); - for_each_queue(bp, i) - netif_napi_del(&bnx2x_fp(bp, i, napi)); + bnx2x_free_mem(bp); bp->state = BNX2X_STATE_CLOSED; @@ -7613,8 +9229,9 @@ static void bnx2x_eeh_recover(struct bnx2x *bp) BNX2X_ERR("BAD MCP validity signature\n"); if (!BP_NOMCP(bp)) { - bp->fw_seq = (SHMEM_RD(bp, func_mb[BP_FUNC(bp)].drv_mb_header) - & DRV_MSG_SEQ_NUMBER_MASK); + bp->fw_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); } } @@ -7697,7 +9314,8 @@ static void bnx2x_io_resume(struct pci_dev *pdev) struct bnx2x *bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - printk(KERN_ERR "Handling parity error recovery. Try again later\n"); + printk(KERN_ERR "Handling parity error recovery. " + "Try again later\n"); return; } @@ -7772,19 +9390,53 @@ static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) #endif spin_lock_bh(&bp->spq_lock); + BUG_ON(bp->cnic_spq_pending < count); bp->cnic_spq_pending -= count; - for (; bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending; - bp->cnic_spq_pending++) { - if (!bp->cnic_kwq_pending) + for (; bp->cnic_kwq_pending; bp->cnic_kwq_pending--) { + u16 type = (le16_to_cpu(bp->cnic_kwq_cons->hdr.type) + & SPE_HDR_CONN_TYPE) >> + SPE_HDR_CONN_TYPE_SHIFT; + + /* Set validation for iSCSI L2 client before sending SETUP + * ramrod + */ + if (type == ETH_CONNECTION_TYPE) { + u8 cmd = (le32_to_cpu(bp->cnic_kwq_cons-> + hdr.conn_and_cmd_data) >> + SPE_HDR_CMD_ID_SHIFT) & 0xff; + + if (cmd == RAMROD_CMD_ID_ETH_CLIENT_SETUP) + bnx2x_set_ctx_validation(&bp->context. + vcxt[BNX2X_ISCSI_ETH_CID].eth, + HW_CID(bp, BNX2X_ISCSI_ETH_CID)); + } + + /* There may be not more than 8 L2 and COMMON SPEs and not more + * than 8 L5 SPEs in the air. + */ + if ((type == NONE_CONNECTION_TYPE) || + (type == ETH_CONNECTION_TYPE)) { + if (!atomic_read(&bp->spq_left)) + break; + else + atomic_dec(&bp->spq_left); + } else if (type == ISCSI_CONNECTION_TYPE) { + if (bp->cnic_spq_pending >= + bp->cnic_eth_dev.max_kwqe_pending) + break; + else + bp->cnic_spq_pending++; + } else { + BNX2X_ERR("Unknown SPE type: %d\n", type); + bnx2x_panic(); break; + } spe = bnx2x_sp_get_next(bp); *spe = *bp->cnic_kwq_cons; - bp->cnic_kwq_pending--; - DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n", bp->cnic_spq_pending, bp->cnic_kwq_pending, count); @@ -7822,8 +9474,8 @@ static int bnx2x_cnic_sp_queue(struct net_device *dev, DP(NETIF_MSG_TIMER, "L5 SPQE %x %x %x:%x pos %d\n", spe->hdr.conn_and_cmd_data, spe->hdr.type, - spe->data.mac_config_addr.hi, - spe->data.mac_config_addr.lo, + spe->data.update_data_addr.hi, + spe->data.update_data_addr.lo, bp->cnic_kwq_pending); if (bp->cnic_kwq_prod == bp->cnic_kwq_last) @@ -7889,7 +9541,7 @@ static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid) ctl.data.comp.cid = cid; bnx2x_cnic_ctl_send_bh(bp, &ctl); - bnx2x_cnic_sp_post(bp, 1); + bnx2x_cnic_sp_post(bp, 0); } static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) @@ -7906,8 +9558,8 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) break; } - case DRV_CTL_COMPLETION_CMD: { - int count = ctl->data.comp.comp_count; + case DRV_CTL_RET_L5_SPQ_CREDIT_CMD: { + int count = ctl->data.credit.credit_count; bnx2x_cnic_sp_post(bp, count); break; @@ -7917,8 +9569,24 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) case DRV_CTL_START_L2_CMD: { u32 cli = ctl->data.ring.client_id; - bp->rx_mode_cl_mask |= (1 << cli); - bnx2x_set_storm_rx_mode(bp); + /* Set iSCSI MAC address */ + bnx2x_set_iscsi_eth_mac_addr(bp, 1); + + mmiowb(); + barrier(); + + /* Start accepting on iSCSI L2 ring. Accept all multicasts + * because it's the only way for UIO Client to accept + * multicasts (in non-promiscuous mode only one Client per + * function will receive multicast packets (leading in our + * case). + */ + bnx2x_rxq_set_mac_filters(bp, cli, + BNX2X_ACCEPT_UNICAST | + BNX2X_ACCEPT_BROADCAST | + BNX2X_ACCEPT_ALL_MULTICAST); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); + break; } @@ -7926,8 +9594,23 @@ static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) case DRV_CTL_STOP_L2_CMD: { u32 cli = ctl->data.ring.client_id; - bp->rx_mode_cl_mask &= ~(1 << cli); - bnx2x_set_storm_rx_mode(bp); + /* Stop accepting on iSCSI L2 ring */ + bnx2x_rxq_set_mac_filters(bp, cli, BNX2X_ACCEPT_NONE); + storm_memset_mac_filters(bp, &bp->mac_filters, BP_FUNC(bp)); + + mmiowb(); + barrier(); + + /* Unset iSCSI L2 MAC */ + bnx2x_set_iscsi_eth_mac_addr(bp, 0); + break; + } + case DRV_CTL_RET_L2_SPQ_CREDIT_CMD: { + int count = ctl->data.credit.credit_count; + + smp_mb__before_atomic_inc(); + atomic_add(count, &bp->spq_left); + smp_mb__after_atomic_inc(); break; } @@ -7951,10 +9634,16 @@ void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX; cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX; } - cp->irq_arr[0].status_blk = bp->cnic_sb; + if (CHIP_IS_E2(bp)) + cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e2_sb; + else + cp->irq_arr[0].status_blk = (void *)bp->cnic_sb.e1x_sb; + cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp); + cp->irq_arr[0].status_blk_num2 = CNIC_IGU_SB_ID(bp); cp->irq_arr[1].status_blk = bp->def_status_blk; cp->irq_arr[1].status_blk_num = DEF_SB_ID; + cp->irq_arr[1].status_blk_num2 = DEF_SB_IGU_ID; cp->num_irq = 2; } @@ -7986,12 +9675,10 @@ static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, cp->num_irq = 0; cp->drv_state = CNIC_DRV_STATE_REGD; - - bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, CNIC_SB_ID(bp)); + cp->iro_arr = bp->iro_arr; bnx2x_setup_cnic_irq_info(bp); - bnx2x_set_iscsi_eth_mac_addr(bp, 1); - bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; + rcu_assign_pointer(bp->cnic_ops, ops); return 0; @@ -8028,15 +9715,24 @@ struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) cp->io_base = bp->regview; cp->io_base2 = bp->doorbells; cp->max_kwqe_pending = 8; - cp->ctx_blk_size = CNIC_CTX_PER_ILT * sizeof(union cdu_context); - cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1; + cp->ctx_blk_size = CDU_ILT_PAGE_SZ; + cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + + bnx2x_cid_ilt_lines(bp); cp->ctx_tbl_len = CNIC_ILT_LINES; - cp->starting_cid = BCM_CNIC_CID_START; + cp->starting_cid = bnx2x_cid_ilt_lines(bp) * ILT_PAGE_CIDS; cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue; cp->drv_ctl = bnx2x_drv_ctl; cp->drv_register_cnic = bnx2x_register_cnic; cp->drv_unregister_cnic = bnx2x_unregister_cnic; - + cp->iscsi_l2_client_id = BNX2X_ISCSI_ETH_CL_ID; + cp->iscsi_l2_cid = BNX2X_ISCSI_ETH_CID; + + DP(BNX2X_MSG_SP, "page_size %d, tbl_offset %d, tbl_lines %d, " + "starting cid %d\n", + cp->ctx_blk_size, + cp->ctx_tbl_offset, + cp->ctx_tbl_len, + cp->starting_cid); return cp; } EXPORT_SYMBOL(bnx2x_cnic_probe); diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index a1f3bf0cd630d2de15be155830ca7f038de904f7..1cefe489a9553b62ff6b8b2618efebf9b440ba4e 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2009 Broadcom Corporation + * Copyright (c) 2007-2010 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,20 @@ * */ - +#define ATC_ATC_INT_STS_REG_ADDRESS_ERROR (0x1<<0) +#define ATC_ATC_INT_STS_REG_ATC_GPA_MULTIPLE_HITS (0x1<<2) +#define ATC_ATC_INT_STS_REG_ATC_IREQ_LESS_THAN_STU (0x1<<5) +#define ATC_ATC_INT_STS_REG_ATC_RCPL_TO_EMPTY_CNT (0x1<<3) +#define ATC_ATC_INT_STS_REG_ATC_TCPL_ERROR (0x1<<4) +#define ATC_ATC_INT_STS_REG_ATC_TCPL_TO_NOT_PEND (0x1<<1) +/* [RW 1] Initiate the ATC array - reset all the valid bits */ +#define ATC_REG_ATC_INIT_ARRAY 0x1100b8 +/* [R 1] ATC initalization done */ +#define ATC_REG_ATC_INIT_DONE 0x1100bc +/* [RC 6] Interrupt register #0 read clear */ +#define ATC_REG_ATC_INT_STS_CLR 0x1101c0 +/* [RW 19] Interrupt mask register #0 read/write */ +#define BRB1_REG_BRB1_INT_MASK 0x60128 /* [R 19] Interrupt register #0 read */ #define BRB1_REG_BRB1_INT_STS 0x6011c /* [RW 4] Parity mask register #0 read/write */ @@ -27,9 +40,31 @@ /* [R 4] Parity register #0 read */ #define BRB1_REG_BRB1_PRTY_STS 0x6012c /* [RW 10] At address BRB1_IND_FREE_LIST_PRS_CRDT initialize free head. At - address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address - BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. */ + * address BRB1_IND_FREE_LIST_PRS_CRDT+1 initialize free tail. At address + * BRB1_IND_FREE_LIST_PRS_CRDT+2 initialize parser initial credit. Warning - + * following reset the first rbc access to this reg must be write; there can + * be no more rbc writes after the first one; there can be any number of rbc + * read following the first write; rbc access not following these rules will + * result in hang condition. */ #define BRB1_REG_FREE_LIST_PRS_CRDT 0x60200 +/* [RW 10] The number of free blocks below which the full signal to class 0 + * is asserted */ +#define BRB1_REG_FULL_0_XOFF_THRESHOLD_0 0x601d0 +/* [RW 10] The number of free blocks above which the full signal to class 0 + * is de-asserted */ +#define BRB1_REG_FULL_0_XON_THRESHOLD_0 0x601d4 +/* [RW 10] The number of free blocks below which the full signal to class 1 + * is asserted */ +#define BRB1_REG_FULL_1_XOFF_THRESHOLD_0 0x601d8 +/* [RW 10] The number of free blocks above which the full signal to class 1 + * is de-asserted */ +#define BRB1_REG_FULL_1_XON_THRESHOLD_0 0x601dc +/* [RW 10] The number of free blocks below which the full signal to the LB + * port is asserted */ +#define BRB1_REG_FULL_LB_XOFF_THRESHOLD 0x601e0 +/* [RW 10] The number of free blocks above which the full signal to the LB + * port is de-asserted */ +#define BRB1_REG_FULL_LB_XON_THRESHOLD 0x601e4 /* [RW 10] The number of free blocks above which the High_llfc signal to interface #n is de-asserted. */ #define BRB1_REG_HIGH_LLFC_HIGH_THRESHOLD_0 0x6014c @@ -44,6 +79,9 @@ /* [RW 10] The number of free blocks below which the Low_llfc signal to interface #n is asserted. */ #define BRB1_REG_LOW_LLFC_LOW_THRESHOLD_0 0x6015c +/* [RW 10] The number of blocks guarantied for the MAC port */ +#define BRB1_REG_MAC_GUARANTIED_0 0x601e8 +#define BRB1_REG_MAC_GUARANTIED_1 0x60240 /* [R 24] The number of full blocks. */ #define BRB1_REG_NUM_OF_FULL_BLOCKS 0x60090 /* [ST 32] The number of cycles that the write_full signal towards MAC #0 @@ -55,7 +93,19 @@ asserted. */ #define BRB1_REG_NUM_OF_PAUSE_CYCLES_0 0x600b8 #define BRB1_REG_NUM_OF_PAUSE_CYCLES_1 0x600bc -/* [RW 10] Write client 0: De-assert pause threshold. */ +/* [RW 10] The number of free blocks below which the pause signal to class 0 + * is asserted */ +#define BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 0x601c0 +/* [RW 10] The number of free blocks above which the pause signal to class 0 + * is de-asserted */ +#define BRB1_REG_PAUSE_0_XON_THRESHOLD_0 0x601c4 +/* [RW 10] The number of free blocks below which the pause signal to class 1 + * is asserted */ +#define BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0 0x601c8 +/* [RW 10] The number of free blocks above which the pause signal to class 1 + * is de-asserted */ +#define BRB1_REG_PAUSE_1_XON_THRESHOLD_0 0x601cc +/* [RW 10] Write client 0: De-assert pause threshold. Not Functional */ #define BRB1_REG_PAUSE_HIGH_THRESHOLD_0 0x60078 #define BRB1_REG_PAUSE_HIGH_THRESHOLD_1 0x6007c /* [RW 10] Write client 0: Assert pause threshold. */ @@ -362,6 +412,7 @@ #define CFC_REG_NUM_LCIDS_ARRIVING 0x104004 /* [R 9] Number of Leaving LCIDs in Link List Block */ #define CFC_REG_NUM_LCIDS_LEAVING 0x104018 +#define CFC_REG_WEAK_ENABLE_PF 0x104124 /* [RW 8] The event id for aggregated interrupt 0 */ #define CSDM_REG_AGG_INT_EVENT_0 0xc2038 #define CSDM_REG_AGG_INT_EVENT_10 0xc2060 @@ -590,10 +641,17 @@ #define CSEM_REG_TS_8_AS 0x200058 /* [RW 3] The arbitration scheme of time_slot 9 */ #define CSEM_REG_TS_9_AS 0x20005c +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define CSEM_REG_VFPF_ERR_NUM 0x200380 /* [RW 1] Parity mask register #0 read/write */ #define DBG_REG_DBG_PRTY_MASK 0xc0a8 /* [R 1] Parity register #0 read */ #define DBG_REG_DBG_PRTY_STS 0xc09c +/* [RW 1] When set the DMAE will process the commands as in E1.5. 1.The + * function that is used is always SRC-PCI; 2.VF_Valid = 0; 3.VFID=0; + * 4.Completion function=0; 5.Error handling=0 */ +#define DMAE_REG_BACKWARD_COMP_EN 0x10207c /* [RW 32] Commands memory. The address to command X; row Y is to calculated as 14*X+Y. */ #define DMAE_REG_CMD_MEM 0x102400 @@ -742,9 +800,13 @@ #define HC_REG_HC_PRTY_MASK 0x1080a0 /* [R 3] Parity register #0 read */ #define HC_REG_HC_PRTY_STS 0x108094 -#define HC_REG_INT_MASK 0x108108 +/* [RC 3] Parity register #0 read clear */ +#define HC_REG_HC_PRTY_STS_CLR 0x108098 +#define HC_REG_INT_MASK 0x108108 #define HC_REG_LEADING_EDGE_0 0x108040 #define HC_REG_LEADING_EDGE_1 0x108048 +#define HC_REG_MAIN_MEMORY 0x108800 +#define HC_REG_MAIN_MEMORY_SIZE 152 #define HC_REG_P0_PROD_CONS 0x108200 #define HC_REG_P1_PROD_CONS 0x108400 #define HC_REG_PBA_COMMAND 0x108140 @@ -758,6 +820,92 @@ #define HC_REG_USTORM_ADDR_FOR_COALESCE 0x108068 #define HC_REG_VQID_0 0x108008 #define HC_REG_VQID_1 0x10800c +#define IGU_BLOCK_CONFIGURATION_REG_BACKWARD_COMP_EN (0x1<<1) +#define IGU_REG_ATTENTION_ACK_BITS 0x130108 +/* [R 4] Debug: attn_fsm */ +#define IGU_REG_ATTN_FSM 0x130054 +#define IGU_REG_ATTN_MSG_ADDR_H 0x13011c +#define IGU_REG_ATTN_MSG_ADDR_L 0x130120 +/* [R 4] Debug: [3] - attention write done message is pending (0-no pending; + * 1-pending). [2:0] = PFID. Pending means attention message was sent; but + * write done didnt receive. */ +#define IGU_REG_ATTN_WRITE_DONE_PENDING 0x130030 +#define IGU_REG_BLOCK_CONFIGURATION 0x130000 +#define IGU_REG_COMMAND_REG_32LSB_DATA 0x130124 +#define IGU_REG_COMMAND_REG_CTRL 0x13012c +/* [WB_R 32] Cleanup bit status per SB. 1 = cleanup is set. 0 = cleanup bit + * is clear. The bits in this registers are set and clear via the producer + * command. Data valid only in addresses 0-4. all the rest are zero. */ +#define IGU_REG_CSTORM_TYPE_0_SB_CLEANUP 0x130200 +/* [R 5] Debug: ctrl_fsm */ +#define IGU_REG_CTRL_FSM 0x130064 +/* [R 1] data availble for error memory. If this bit is clear do not red + * from error_handling_memory. */ +#define IGU_REG_ERROR_HANDLING_DATA_VALID 0x130130 +/* [R 11] Parity register #0 read */ +#define IGU_REG_IGU_PRTY_STS 0x13009c +/* [R 4] Debug: int_handle_fsm */ +#define IGU_REG_INT_HANDLE_FSM 0x130050 +#define IGU_REG_LEADING_EDGE_LATCH 0x130134 +/* [RW 14] mapping CAM; relevant for E2 operating mode only. [0] - valid. + * [6:1] - vector number; [13:7] - FID (if VF - [13] = 0; [12:7] = VF + * number; if PF - [13] = 1; [12:10] = 0; [9:7] = PF number); */ +#define IGU_REG_MAPPING_MEMORY 0x131000 +#define IGU_REG_MAPPING_MEMORY_SIZE 136 +#define IGU_REG_PBA_STATUS_LSB 0x130138 +#define IGU_REG_PBA_STATUS_MSB 0x13013c +#define IGU_REG_PCI_PF_MSI_EN 0x130140 +#define IGU_REG_PCI_PF_MSIX_EN 0x130144 +#define IGU_REG_PCI_PF_MSIX_FUNC_MASK 0x130148 +/* [WB_R 32] Each bit represent the pending bits status for that SB. 0 = no + * pending; 1 = pending. Pendings means interrupt was asserted; and write + * done was not received. Data valid only in addresses 0-4. all the rest are + * zero. */ +#define IGU_REG_PENDING_BITS_STATUS 0x130300 +#define IGU_REG_PF_CONFIGURATION 0x130154 +/* [RW 20] producers only. E2 mode: address 0-135 match to the mapping + * memory; 136 - PF0 default prod; 137 PF1 default prod; 138 - PF2 default + * prod; 139 PF3 default prod; 140 - PF0 - ATTN prod; 141 - PF1 - ATTN prod; + * 142 - PF2 - ATTN prod; 143 - PF3 - ATTN prod; 144-147 reserved. E1.5 mode + * - In backward compatible mode; for non default SB; each even line in the + * memory holds the U producer and each odd line hold the C producer. The + * first 128 producer are for NDSB (PF0 - 0-31; PF1 - 32-63 and so on). The + * last 20 producers are for the DSB for each PF. each PF has five segments + * (the order inside each segment is PF0; PF1; PF2; PF3) - 128-131 U prods; + * 132-135 C prods; 136-139 X prods; 140-143 T prods; 144-147 ATTN prods; */ +#define IGU_REG_PROD_CONS_MEMORY 0x132000 +/* [R 3] Debug: pxp_arb_fsm */ +#define IGU_REG_PXP_ARB_FSM 0x130068 +/* [RW 6] Write one for each bit will reset the appropriate memory. When the + * memory reset finished the appropriate bit will be clear. Bit 0 - mapping + * memory; Bit 1 - SB memory; Bit 2 - SB interrupt and mask register; Bit 3 + * - MSIX memory; Bit 4 - PBA memory; Bit 5 - statistics; */ +#define IGU_REG_RESET_MEMORIES 0x130158 +/* [R 4] Debug: sb_ctrl_fsm */ +#define IGU_REG_SB_CTRL_FSM 0x13004c +#define IGU_REG_SB_INT_BEFORE_MASK_LSB 0x13015c +#define IGU_REG_SB_INT_BEFORE_MASK_MSB 0x130160 +#define IGU_REG_SB_MASK_LSB 0x130164 +#define IGU_REG_SB_MASK_MSB 0x130168 +/* [RW 16] Number of command that were dropped without causing an interrupt + * due to: read access for WO BAR address; or write access for RO BAR + * address or any access for reserved address or PCI function error is set + * and address is not MSIX; PBA or cleanup */ +#define IGU_REG_SILENT_DROP 0x13016c +/* [RW 10] Number of MSI/MSIX/ATTN messages sent for the function: 0-63 - + * number of MSIX messages per VF; 64-67 - number of MSI/MSIX messages per + * PF; 68-71 number of ATTN messages per PF */ +#define IGU_REG_STATISTIC_NUM_MESSAGE_SENT 0x130800 +/* [RW 32] Number of cycles the timer mask masking the IGU interrupt when a + * timer mask command arrives. Value must be bigger than 100. */ +#define IGU_REG_TIMER_MASKING_VALUE 0x13003c +#define IGU_REG_TRAILING_EDGE_LATCH 0x130104 +#define IGU_REG_VF_CONFIGURATION 0x130170 +/* [WB_R 32] Each bit represent write done pending bits status for that SB + * (MSI/MSIX message was sent and write done was not received yet). 0 = + * clear; 1 = set. Data valid only in addresses 0-4. all the rest are zero. */ +#define IGU_REG_WRITE_DONE_PENDING 0x130480 +#define MCP_A_REG_MCPR_SCRATCH 0x3a0000 #define MCP_REG_MCPR_NVM_ACCESS_ENABLE 0x86424 #define MCP_REG_MCPR_NVM_ADDR 0x8640c #define MCP_REG_MCPR_NVM_CFG4 0x8642c @@ -880,6 +1028,11 @@ rom_parity; [29] MCP Latched ump_rx_parity; [30] MCP Latched ump_tx_parity; [31] MCP Latched scpad_parity; */ #define MISC_REG_AEU_AFTER_INVERT_4_MCP 0xa458 +/* [R 32] Read fifth 32 bit after inversion of function 0. Mapped as + * follows: [0] PGLUE config_space; [1] PGLUE misc_flr; [2] PGLUE B RBC + * attention [3] PGLUE B RBC parity; [4] ATC attention; [5] ATC parity; [6] + * CNIG attention (reserved); [7] CNIG parity (reserved); [31-8] Reserved; */ +#define MISC_REG_AEU_AFTER_INVERT_5_FUNC_0 0xa700 /* [W 14] write to this register results with the clear of the latched signals; one in d0 clears RBCR latch; one in d1 clears RBCT latch; one in d2 clears RBCN latch; one in d3 clears RBCU latch; one in d4 clears RBCP @@ -1251,6 +1404,7 @@ #define MISC_REG_E1HMF_MODE 0xa5f8 /* [RW 32] Debug only: spare RW register reset by core reset */ #define MISC_REG_GENERIC_CR_0 0xa460 +#define MISC_REG_GENERIC_CR_1 0xa464 /* [RW 32] Debug only: spare RW register reset by por reset */ #define MISC_REG_GENERIC_POR_1 0xa474 /* [RW 32] GPIO. [31-28] FLOAT port 0; [27-24] FLOAT port 0; When any of @@ -1373,6 +1527,14 @@ #define MISC_REG_PLL_STORM_CTRL_2 0xa298 #define MISC_REG_PLL_STORM_CTRL_3 0xa29c #define MISC_REG_PLL_STORM_CTRL_4 0xa2a0 +/* [R 1] Status of 4 port mode enable input pin. */ +#define MISC_REG_PORT4MODE_EN 0xa750 +/* [RW 2] 4 port mode enable overwrite.[0] - Overwrite control; if it is 0 - + * the port4mode_en output is equal to 4 port mode input pin; if it is 1 - + * the port4mode_en output is equal to bit[1] of this register; [1] - + * Overwrite value. If bit[0] of this register is 1 this is the value that + * receives the port4mode_en output . */ +#define MISC_REG_PORT4MODE_EN_OVWR 0xa720 /* [RW 32] reset reg#2; rite/read one = the specific block is out of reset; write/read zero = the specific block is in reset; addr 0-wr- the write value will be written to the register; addr 1-set - one will be written @@ -1656,8 +1818,91 @@ /* [R 32] Interrupt register #0 read */ #define NIG_REG_NIG_INT_STS_0 0x103b0 #define NIG_REG_NIG_INT_STS_1 0x103c0 -/* [R 32] Parity register #0 read */ +/* [R 32] Legacy E1 and E1H location for parity error status register. */ #define NIG_REG_NIG_PRTY_STS 0x103d0 +/* [R 32] Parity register #0 read */ +#define NIG_REG_NIG_PRTY_STS_0 0x183bc +#define NIG_REG_NIG_PRTY_STS_1 0x183cc +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define NIG_REG_P0_HDRS_AFTER_BASIC 0x18038 +/* [RW 1] HW PFC enable bit. Set this bit to enable the PFC functionality in + * the NIG. Other flow control modes such as PAUSE and SAFC/LLFC should be + * disabled when this bit is set. */ +#define NIG_REG_P0_HWPFC_ENABLE 0x18078 +#define NIG_REG_P0_LLH_FUNC_MEM2 0x18480 +#define NIG_REG_P0_LLH_FUNC_MEM2_ENABLE 0x18440 +/* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for + * future expansion) each priorty is to be mapped to. Bits 3:0 specify the + * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit + * priority field is extracted from the outer-most VLAN in receive packet. + * Only COS 0 and COS 1 are supported in E2. */ +#define NIG_REG_P0_PKT_PRIORITY_TO_COS 0x18054 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A + * priority is mapped to COS 0 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS0_PRIORITY_MASK 0x18058 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 1. A + * priority is mapped to COS 1 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P0_RX_COS1_PRIORITY_MASK 0x1805c +/* [RW 15] Specify which of the credit registers the client is to be mapped + * to. Bits[2:0] are for client 0; bits [14:12] are for client 4. For + * clients that are not subject to WFQ credit blocking - their + * specifications here are not used. */ +#define NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP 0x180f0 +/* [RW 5] Specify whether the client competes directly in the strict + * priority arbiter. The bits are mapped according to client ID (client IDs + * are defined in tx_arb_priority_client). Default value is set to enable + * strict priorities for clients 0-2 -- management and debug traffic. */ +#define NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT 0x180e8 +/* [RW 5] Specify whether the client is subject to WFQ credit blocking. The + * bits are mapped according to client ID (client IDs are defined in + * tx_arb_priority_client). Default value is 0 for not using WFQ credit + * blocking. */ +#define NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ 0x180ec +/* [RW 32] Specify the upper bound that credit register 0 is allowed to + * reach. */ +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0 0x1810c +#define NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1 0x18110 +/* [RW 32] Specify the weight (in bytes) to be added to credit register 0 + * when it is time to increment. */ +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0 0x180f8 +#define NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1 0x180fc +/* [RW 12] Specify the number of strict priority arbitration slots between + * two round-robin arbitration slots to avoid starvation. A value of 0 means + * no strict priority cycles - the strict priority with anti-starvation + * arbiter becomes a round-robin arbiter. */ +#define NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS 0x180f4 +/* [RW 15] Specify the client number to be assigned to each priority of the + * strict priority arbiter. Priority 0 is the highest priority. Bits [2:0] + * are for priority 0 client; bits [14:12] are for priority 4 client. The + * clients are assigned the following IDs: 0-management; 1-debug traffic + * from this port; 2-debug traffic from other port; 3-COS0 traffic; 4-COS1 + * traffic. The reset value[14:0] is set to 0x4688 (15'b100_011_010_001_000) + * for management at priority 0; debug traffic at priorities 1 and 2; COS0 + * traffic at priority 3; and COS1 traffic at priority 4. */ +#define NIG_REG_P0_TX_ARB_PRIORITY_CLIENT 0x180e4 +#define NIG_REG_P1_LLH_FUNC_MEM2 0x184c0 +#define NIG_REG_P1_LLH_FUNC_MEM2_ENABLE 0x18460 +/* [RW 32] Eight 4-bit configurations for specifying which COS (0-15 for + * future expansion) each priorty is to be mapped to. Bits 3:0 specify the + * COS for priority 0. Bits 31:28 specify the COS for priority 7. The 3-bit + * priority field is extracted from the outer-most VLAN in receive packet. + * Only COS 0 and COS 1 are supported in E2. */ +#define NIG_REG_P1_PKT_PRIORITY_TO_COS 0x181a8 +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 0. A + * priority is mapped to COS 0 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P1_RX_COS0_PRIORITY_MASK 0x181ac +/* [RW 16] Bit-map indicating which SAFC/PFC priorities to map to COS 1. A + * priority is mapped to COS 1 when the corresponding mask bit is 1. More + * than one bit may be set; allowing multiple priorities to be mapped to one + * COS. */ +#define NIG_REG_P1_RX_COS1_PRIORITY_MASK 0x181b0 /* [RW 1] Pause enable for port0. This register may get 1 only when ~safc_enable.safc_enable = 0 and ppp_enable.ppp_enable =0 for the same port */ @@ -1742,6 +1987,10 @@ /* [RW 1] Disable processing further tasks from port 4 (after ending the current task in process). */ #define PBF_REG_DISABLE_NEW_TASK_PROC_P4 0x14006c +#define PBF_REG_DISABLE_PF 0x1402e8 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define PBF_REG_HDRS_AFTER_BASIC 0x15c0a8 #define PBF_REG_IF_ENABLE_REG 0x140044 /* [RW 1] Init bit. When set the initial credits are copied to the credit registers (except the port credits). Should be set and then reset after @@ -1765,6 +2014,8 @@ #define PBF_REG_MAC_IF1_ENABLE 0x140034 /* [RW 1] Enable for the loopback interface. */ #define PBF_REG_MAC_LB_ENABLE 0x140040 +/* [RW 6] Bit-map indicating which headers must appear in the packet */ +#define PBF_REG_MUST_HAVE_HDRS 0x15c0c4 /* [RW 10] Port 0 threshold used by arbiter in 16 byte lines used when pause not suppoterd. */ #define PBF_REG_P0_ARB_THRSH 0x1400e4 @@ -1804,6 +2055,259 @@ #define PB_REG_PB_PRTY_MASK 0x38 /* [R 4] Parity register #0 read */ #define PB_REG_PB_PRTY_STS 0x2c +#define PGLUE_B_PGLUE_B_INT_STS_REG_ADDRESS_ERROR (0x1<<0) +#define PGLUE_B_PGLUE_B_INT_STS_REG_CSSNOOP_FIFO_OVERFLOW (0x1<<8) +#define PGLUE_B_PGLUE_B_INT_STS_REG_INCORRECT_RCV_BEHAVIOR (0x1<<1) +#define PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_ERROR_ATTN (0x1<<6) +#define PGLUE_B_PGLUE_B_INT_STS_REG_TCPL_IN_TWO_RCBS_ATTN (0x1<<7) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_GRC_SPACE_VIOLATION_ATTN (0x1<<4) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_LENGTH_VIOLATION_ATTN (0x1<<3) +#define PGLUE_B_PGLUE_B_INT_STS_REG_VF_MSIX_BAR_VIOLATION_ATTN (0x1<<5) +#define PGLUE_B_PGLUE_B_INT_STS_REG_WAS_ERROR_ATTN (0x1<<2) +/* [R 8] Config space A attention dirty bits. Each bit indicates that the + * corresponding PF generates config space A attention. Set by PXP. Reset by + * MCP writing 1 to icfg_space_a_request_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_CFG_SPACE_A_REQUEST 0x9010 +/* [R 8] Config space B attention dirty bits. Each bit indicates that the + * corresponding PF generates config space B attention. Set by PXP. Reset by + * MCP writing 1 to icfg_space_b_request_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_CFG_SPACE_B_REQUEST 0x9014 +/* [RW 1] Type A PF enable inbound interrupt table for CSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_CSDM_INB_INT_A_PF_ENABLE 0x9194 +/* [RW 18] Type B VF inbound interrupt table for CSDM: bits[17:9]-mask; + * its[8:0]-address. Bits [1:0] must be zero (DW resolution address). */ +#define PGLUE_B_REG_CSDM_INB_INT_B_VF 0x916c +/* [RW 1] Type B VF enable inbound interrupt table for CSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_CSDM_INB_INT_B_VF_ENABLE 0x919c +/* [RW 16] Start offset of CSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_START_OFFSET_A 0x9100 +/* [RW 16] Start offset of CSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_START_OFFSET_B 0x9108 +/* [RW 5] VF Shift of CSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_CSDM_VF_SHIFT_B 0x9110 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_CSDM_ZONE_A_SIZE_PF 0x91ac +/* [R 8] FLR request attention dirty bits for PFs 0 to 7. Each bit indicates + * that the FLR register of the corresponding PF was set. Set by PXP. Reset + * by MCP writing 1 to flr_request_pf_7_0_clr. Note: register contains bits + * from both paths. */ +#define PGLUE_B_REG_FLR_REQUEST_PF_7_0 0x9028 +/* [W 8] FLR request attention dirty bits clear for PFs 0 to 7. MCP writes 1 + * to a bit in this register in order to clear the corresponding bit in + * flr_request_pf_7_0 register. Note: register contains bits from both + * paths. */ +#define PGLUE_B_REG_FLR_REQUEST_PF_7_0_CLR 0x9418 +/* [R 32] FLR request attention dirty bits for VFs 96 to 127. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_127_96_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_127_96 0x9024 +/* [R 32] FLR request attention dirty bits for VFs 0 to 31. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_31_0_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_31_0 0x9018 +/* [R 32] FLR request attention dirty bits for VFs 32 to 63. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_63_32_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_63_32 0x901c +/* [R 32] FLR request attention dirty bits for VFs 64 to 95. Each bit + * indicates that the FLR register of the corresponding VF was set. Set by + * PXP. Reset by MCP writing 1 to flr_request_vf_95_64_clr. */ +#define PGLUE_B_REG_FLR_REQUEST_VF_95_64 0x9020 +/* [R 8] Each bit indicates an incorrect behavior in user RX interface. Bit + * 0 - Target memory read arrived with a correctable error. Bit 1 - Target + * memory read arrived with an uncorrectable error. Bit 2 - Configuration RW + * arrived with a correctable error. Bit 3 - Configuration RW arrived with + * an uncorrectable error. Bit 4 - Completion with Configuration Request + * Retry Status. Bit 5 - Expansion ROM access received with a write request. + * Bit 6 - Completion with pcie_rx_err of 0000; CMPL_STATUS of non-zero; and + * pcie_rx_last not asserted. Bit 7 - Completion with pcie_rx_err of 1010; + * and pcie_rx_last not asserted. */ +#define PGLUE_B_REG_INCORRECT_RCV_DETAILS 0x9068 +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_MASTER 0x942c +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ 0x9430 +#define PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_WRITE 0x9434 +#define PGLUE_B_REG_INTERNAL_VFID_ENABLE 0x9438 +/* [R 9] Interrupt register #0 read */ +#define PGLUE_B_REG_PGLUE_B_INT_STS 0x9298 +/* [RC 9] Interrupt register #0 read clear */ +#define PGLUE_B_REG_PGLUE_B_INT_STS_CLR 0x929c +/* [R 2] Parity register #0 read */ +#define PGLUE_B_REG_PGLUE_B_PRTY_STS 0x92a8 +/* [R 13] Details of first request received with error. [2:0] - PFID. [3] - + * VF_VALID. [9:4] - VFID. [11:10] - Error Code - 0 - Indicates Completion + * Timeout of a User Tx non-posted request. 1 - unsupported request. 2 - + * completer abort. 3 - Illegal value for this field. [12] valid - indicates + * if there was a completion error since the last time this register was + * cleared. */ +#define PGLUE_B_REG_RX_ERR_DETAILS 0x9080 +/* [R 18] Details of first ATS Translation Completion request received with + * error. [2:0] - PFID. [3] - VF_VALID. [9:4] - VFID. [11:10] - Error Code - + * 0 - Indicates Completion Timeout of a User Tx non-posted request. 1 - + * unsupported request. 2 - completer abort. 3 - Illegal value for this + * field. [16:12] - ATC OTB EntryID. [17] valid - indicates if there was a + * completion error since the last time this register was cleared. */ +#define PGLUE_B_REG_RX_TCPL_ERR_DETAILS 0x9084 +/* [W 8] Debug only - Shadow BME bits clear for PFs 0 to 7. MCP writes 1 to + * a bit in this register in order to clear the corresponding bit in + * shadow_bme_pf_7_0 register. MCP should never use this unless a + * work-around is needed. Note: register contains bits from both paths. */ +#define PGLUE_B_REG_SHADOW_BME_PF_7_0_CLR 0x9458 +/* [R 8] SR IOV disabled attention dirty bits. Each bit indicates that the + * VF enable register of the corresponding PF is written to 0 and was + * previously 1. Set by PXP. Reset by MCP writing 1 to + * sr_iov_disabled_request_clr. Note: register contains bits from both + * paths. */ +#define PGLUE_B_REG_SR_IOV_DISABLED_REQUEST 0x9030 +/* [R 32] Indicates the status of tags 32-63. 0 - tags is used - read + * completion did not return yet. 1 - tag is unused. Same functionality as + * pxp2_registers_pgl_exp_rom_data2 for tags 0-31. */ +#define PGLUE_B_REG_TAGS_63_32 0x9244 +/* [RW 1] Type A PF enable inbound interrupt table for TSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_TSDM_INB_INT_A_PF_ENABLE 0x9170 +/* [RW 16] Start offset of TSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_START_OFFSET_A 0x90c4 +/* [RW 16] Start offset of TSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_START_OFFSET_B 0x90cc +/* [RW 5] VF Shift of TSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_TSDM_VF_SHIFT_B 0x90d4 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_TSDM_ZONE_A_SIZE_PF 0x91a0 +/* [R 32] Address [31:0] of first read request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_RD_ADD_31_0 0x9098 +/* [R 32] Address [63:32] of first read request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_RD_ADD_63_32 0x909c +/* [R 31] Details of first read request not submitted due to error. [4:0] + * VQID. [5] TREQ. 1 - Indicates the request is a Translation Request. + * [20:8] - Length in bytes. [23:21] - PFID. [24] - VF_VALID. [30:25] - + * VFID. */ +#define PGLUE_B_REG_TX_ERR_RD_DETAILS 0x90a0 +/* [R 26] Details of first read request not submitted due to error. [15:0] + * Request ID. [19:16] client ID. [20] - last SR. [24:21] - Error type - + * [21] - Indicates was_error was set; [22] - Indicates BME was cleared; + * [23] - Indicates FID_enable was cleared; [24] - Indicates VF with parent + * PF FLR_request or IOV_disable_request dirty bit is set. [25] valid - + * indicates if there was a request not submitted due to error since the + * last time this register was cleared. */ +#define PGLUE_B_REG_TX_ERR_RD_DETAILS2 0x90a4 +/* [R 32] Address [31:0] of first write request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_WR_ADD_31_0 0x9088 +/* [R 32] Address [63:32] of first write request not submitted due to error */ +#define PGLUE_B_REG_TX_ERR_WR_ADD_63_32 0x908c +/* [R 31] Details of first write request not submitted due to error. [4:0] + * VQID. [20:8] - Length in bytes. [23:21] - PFID. [24] - VF_VALID. [30:25] + * - VFID. */ +#define PGLUE_B_REG_TX_ERR_WR_DETAILS 0x9090 +/* [R 26] Details of first write request not submitted due to error. [15:0] + * Request ID. [19:16] client ID. [20] - last SR. [24:21] - Error type - + * [21] - Indicates was_error was set; [22] - Indicates BME was cleared; + * [23] - Indicates FID_enable was cleared; [24] - Indicates VF with parent + * PF FLR_request or IOV_disable_request dirty bit is set. [25] valid - + * indicates if there was a request not submitted due to error since the + * last time this register was cleared. */ +#define PGLUE_B_REG_TX_ERR_WR_DETAILS2 0x9094 +/* [RW 10] Type A PF/VF inbound interrupt table for USDM: bits[9:5]-mask; + * its[4:0]-address relative to start_offset_a. Bits [1:0] can have any + * value (Byte resolution address). */ +#define PGLUE_B_REG_USDM_INB_INT_A_0 0x9128 +#define PGLUE_B_REG_USDM_INB_INT_A_1 0x912c +#define PGLUE_B_REG_USDM_INB_INT_A_2 0x9130 +#define PGLUE_B_REG_USDM_INB_INT_A_3 0x9134 +#define PGLUE_B_REG_USDM_INB_INT_A_4 0x9138 +#define PGLUE_B_REG_USDM_INB_INT_A_5 0x913c +#define PGLUE_B_REG_USDM_INB_INT_A_6 0x9140 +/* [RW 1] Type A PF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_A_PF_ENABLE 0x917c +/* [RW 1] Type A VF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_A_VF_ENABLE 0x9180 +/* [RW 1] Type B VF enable inbound interrupt table for USDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_USDM_INB_INT_B_VF_ENABLE 0x9184 +/* [RW 16] Start offset of USDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_START_OFFSET_A 0x90d8 +/* [RW 16] Start offset of USDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_START_OFFSET_B 0x90e0 +/* [RW 5] VF Shift of USDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_USDM_VF_SHIFT_B 0x90e8 +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_USDM_ZONE_A_SIZE_PF 0x91a4 +/* [R 26] Details of first target VF request accessing VF GRC space that + * failed permission check. [14:0] Address. [15] w_nr: 0 - Read; 1 - Write. + * [21:16] VFID. [24:22] - PFID. [25] valid - indicates if there was a + * request accessing VF GRC space that failed permission check since the + * last time this register was cleared. Permission checks are: function + * permission; R/W permission; address range permission. */ +#define PGLUE_B_REG_VF_GRC_SPACE_VIOLATION_DETAILS 0x9234 +/* [R 31] Details of first target VF request with length violation (too many + * DWs) accessing BAR0. [12:0] Address in DWs (bits [14:2] of byte address). + * [14:13] BAR. [20:15] VFID. [23:21] - PFID. [29:24] - Length in DWs. [30] + * valid - indicates if there was a request with length violation since the + * last time this register was cleared. Length violations: length of more + * than 2DWs; length of 2DWs and address not QW aligned; window is GRC and + * length is more than 1 DW. */ +#define PGLUE_B_REG_VF_LENGTH_VIOLATION_DETAILS 0x9230 +/* [R 8] Was_error indication dirty bits for PFs 0 to 7. Each bit indicates + * that there was a completion with uncorrectable error for the + * corresponding PF. Set by PXP. Reset by MCP writing 1 to + * was_error_pf_7_0_clr. */ +#define PGLUE_B_REG_WAS_ERROR_PF_7_0 0x907c +/* [W 8] Was_error indication dirty bits clear for PFs 0 to 7. MCP writes 1 + * to a bit in this register in order to clear the corresponding bit in + * flr_request_pf_7_0 register. */ +#define PGLUE_B_REG_WAS_ERROR_PF_7_0_CLR 0x9470 +/* [R 32] Was_error indication dirty bits for VFs 96 to 127. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_127_96_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_127_96 0x9078 +/* [W 32] Was_error indication dirty bits clear for VFs 96 to 127. MCP + * writes 1 to a bit in this register in order to clear the corresponding + * bit in was_error_vf_127_96 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_127_96_CLR 0x9474 +/* [R 32] Was_error indication dirty bits for VFs 0 to 31. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_31_0_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_31_0 0x906c +/* [W 32] Was_error indication dirty bits clear for VFs 0 to 31. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_31_0 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_31_0_CLR 0x9478 +/* [R 32] Was_error indication dirty bits for VFs 32 to 63. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_63_32_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_63_32 0x9070 +/* [W 32] Was_error indication dirty bits clear for VFs 32 to 63. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_63_32 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_63_32_CLR 0x947c +/* [R 32] Was_error indication dirty bits for VFs 64 to 95. Each bit + * indicates that there was a completion with uncorrectable error for the + * corresponding VF. Set by PXP. Reset by MCP writing 1 to + * was_error_vf_95_64_clr. */ +#define PGLUE_B_REG_WAS_ERROR_VF_95_64 0x9074 +/* [W 32] Was_error indication dirty bits clear for VFs 64 to 95. MCP writes + * 1 to a bit in this register in order to clear the corresponding bit in + * was_error_vf_95_64 register. */ +#define PGLUE_B_REG_WAS_ERROR_VF_95_64_CLR 0x9480 +/* [RW 1] Type A PF enable inbound interrupt table for XSDM. 0 - disable; 1 + * - enable. */ +#define PGLUE_B_REG_XSDM_INB_INT_A_PF_ENABLE 0x9188 +/* [RW 16] Start offset of XSDM zone A (queue zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_START_OFFSET_A 0x90ec +/* [RW 16] Start offset of XSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_START_OFFSET_B 0x90f4 +/* [RW 5] VF Shift of XSDM zone B (legacy zone) in the internal RAM */ +#define PGLUE_B_REG_XSDM_VF_SHIFT_B 0x90fc +/* [RW 1] 0 - Zone A size is 136x32B; 1 - Zone A size is 152x32B. */ +#define PGLUE_B_REG_XSDM_ZONE_A_SIZE_PF 0x91a8 #define PRS_REG_A_PRSU_20 0x40134 /* [R 8] debug only: CFC load request current credit. Transaction based. */ #define PRS_REG_CFC_LD_CURRENT_CREDIT 0x40164 @@ -1866,9 +2370,13 @@ #define PRS_REG_FLUSH_REGIONS_TYPE_5 0x40018 #define PRS_REG_FLUSH_REGIONS_TYPE_6 0x4001c #define PRS_REG_FLUSH_REGIONS_TYPE_7 0x40020 +/* [RW 6] Bit-map indicating which L2 hdrs may appear after the basic + * Ethernet header. */ +#define PRS_REG_HDRS_AFTER_BASIC 0x40238 /* [RW 4] The increment value to send in the CFC load request message */ #define PRS_REG_INC_VALUE 0x40048 -/* [RW 1] If set indicates not to send messages to CFC on received packets */ +/* [RW 6] Bit-map indicating which headers must appear in the packet */ +#define PRS_REG_MUST_HAVE_HDRS 0x40254 #define PRS_REG_NIC_MODE 0x40138 /* [RW 8] The 8-bit event ID for cases where there is no match on the connection. Used in packet start message to TCM. */ @@ -1919,6 +2427,13 @@ #define PRS_REG_TCM_CURRENT_CREDIT 0x40160 /* [R 8] debug only: TSDM current credit. Transaction based. */ #define PRS_REG_TSDM_CURRENT_CREDIT 0x4015c +#define PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_AFT (0x1<<19) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_CPL_OF (0x1<<20) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_PCIE_ATTN (0x1<<22) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_READ_BLOCKED (0x1<<23) +#define PXP2_PXP2_INT_MASK_0_REG_PGL_WRITE_BLOCKED (0x1<<24) +#define PXP2_PXP2_INT_STS_0_REG_WR_PGLUE_EOP_ERROR (0x1<<7) +#define PXP2_PXP2_INT_STS_CLR_0_REG_WR_PGLUE_EOP_ERROR (0x1<<7) /* [R 6] Debug only: Number of used entries in the data FIFO */ #define PXP2_REG_HST_DATA_FIFO_STATUS 0x12047c /* [R 7] Debug only: Number of used entries in the header FIFO */ @@ -2244,8 +2759,17 @@ /* [RW 1] When '1'; requests will enter input buffers but wont get out towards the glue */ #define PXP2_REG_RQ_DISABLE_INPUTS 0x120330 -/* [RW 1] 1 - SR will be aligned by 64B; 0 - SR will be aligned by 8B */ +/* [RW 4] Determines alignment of write SRs when a request is split into + * several SRs. 0 - 8B aligned. 1 - 64B aligned. 2 - 128B aligned. 3 - 256B + * aligned. 4 - 512B aligned. */ #define PXP2_REG_RQ_DRAM_ALIGN 0x1205b0 +/* [RW 4] Determines alignment of read SRs when a request is split into + * several SRs. 0 - 8B aligned. 1 - 64B aligned. 2 - 128B aligned. 3 - 256B + * aligned. 4 - 512B aligned. */ +#define PXP2_REG_RQ_DRAM_ALIGN_RD 0x12092c +/* [RW 1] when set the new alignment method (E2) will be applied; when reset + * the original alignment method (E1 E1H) will be applied */ +#define PXP2_REG_RQ_DRAM_ALIGN_SEL 0x120930 /* [RW 1] If 1 ILT failiue will not result in ELT access; An interrupt will be asserted */ #define PXP2_REG_RQ_ELT_DISABLE 0x12066c @@ -2436,7 +2960,8 @@ #define PXP_REG_PXP_INT_STS_1 0x103078 /* [RC 32] Interrupt register #0 read clear */ #define PXP_REG_PXP_INT_STS_CLR_0 0x10306c -/* [RW 26] Parity mask register #0 read/write */ +#define PXP_REG_PXP_INT_STS_CLR_1 0x10307c +/* [RW 27] Parity mask register #0 read/write */ #define PXP_REG_PXP_PRTY_MASK 0x103094 /* [R 26] Parity register #0 read */ #define PXP_REG_PXP_PRTY_STS 0x103088 @@ -2566,6 +3091,7 @@ #define QM_REG_PAUSESTATE7 0x16e698 /* [RW 2] The PCI attributes field used in the PCI request. */ #define QM_REG_PCIREQAT 0x168054 +#define QM_REG_PF_EN 0x16e70c /* [R 16] The byte credit of port 0 */ #define QM_REG_PORT0BYTECRD 0x168300 /* [R 16] The byte credit of port 1 */ @@ -3402,6 +3928,14 @@ /* [R 32] Parity register #0 read */ #define TSEM_REG_TSEM_PRTY_STS_0 0x180114 #define TSEM_REG_TSEM_PRTY_STS_1 0x180124 +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define TSEM_REG_VFPF_ERR_NUM 0x180380 +/* [RW 32] Indirect access to AG context with 32-bits granularity. The bits + * [10:8] of the address should be the offset within the accessed LCID + * context; the bits [7:0] are the accessed LCID.Example: to write to REG10 + * LCID100. The RBC address should be 12'ha64. */ +#define UCM_REG_AG_CTX 0xe2000 /* [R 5] Used to read the XX protection CAM occupancy counter. */ #define UCM_REG_CAM_OCCUP 0xe0170 /* [RW 1] CDU AG read Interface enable. If 0 - the request input is @@ -3851,6 +4385,17 @@ /* [R 32] Parity register #0 read */ #define USEM_REG_USEM_PRTY_STS_0 0x300124 #define USEM_REG_USEM_PRTY_STS_1 0x300134 +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define USEM_REG_VFPF_ERR_NUM 0x300380 +#define VFC_MEMORIES_RST_REG_CAM_RST (0x1<<0) +#define VFC_MEMORIES_RST_REG_RAM_RST (0x1<<1) +#define VFC_REG_MEMORIES_RST 0x1943c +/* [RW 32] Indirect access to AG context with 32-bits granularity. The bits + * [12:8] of the address should be the offset within the accessed LCID + * context; the bits [7:0] are the accessed LCID.Example: to write to REG10 + * LCID100. The RBC address should be 13'ha64. */ +#define XCM_REG_AG_CTX 0x28000 /* [RW 2] The queue index for registration on Aux1 counter flag. */ #define XCM_REG_AUX1_Q 0x20134 /* [RW 2] Per each decision rule the queue index to register to. */ @@ -4333,6 +4878,9 @@ #define XSEM_REG_TS_8_AS 0x280058 /* [RW 3] The arbitration scheme of time_slot 9 */ #define XSEM_REG_TS_9_AS 0x28005c +/* [W 7] VF or PF ID for reset error bit. Values 0-63 reset error bit for 64 + * VF; values 64-67 reset error for 4 PF; values 68-127 are not valid. */ +#define XSEM_REG_VFPF_ERR_NUM 0x280380 /* [RW 32] Interrupt mask register #0 read/write */ #define XSEM_REG_XSEM_INT_MASK_0 0x280110 #define XSEM_REG_XSEM_INT_MASK_1 0x280120 @@ -4371,6 +4919,23 @@ #define BIGMAC_REGISTER_TX_SOURCE_ADDR (0x08<<3) #define BIGMAC_REGISTER_TX_STAT_GTBYT (0x20<<3) #define BIGMAC_REGISTER_TX_STAT_GTPKT (0x0C<<3) +#define BIGMAC2_REGISTER_BMAC_CONTROL (0x00<<3) +#define BIGMAC2_REGISTER_BMAC_XGXS_CONTROL (0x01<<3) +#define BIGMAC2_REGISTER_CNT_MAX_SIZE (0x05<<3) +#define BIGMAC2_REGISTER_PFC_CONTROL (0x06<<3) +#define BIGMAC2_REGISTER_RX_CONTROL (0x3A<<3) +#define BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS (0x62<<3) +#define BIGMAC2_REGISTER_RX_MAX_SIZE (0x3C<<3) +#define BIGMAC2_REGISTER_RX_STAT_GR64 (0x40<<3) +#define BIGMAC2_REGISTER_RX_STAT_GRIPJ (0x5f<<3) +#define BIGMAC2_REGISTER_RX_STAT_GRPP (0x51<<3) +#define BIGMAC2_REGISTER_TX_CONTROL (0x1C<<3) +#define BIGMAC2_REGISTER_TX_MAX_SIZE (0x1E<<3) +#define BIGMAC2_REGISTER_TX_PAUSE_CONTROL (0x20<<3) +#define BIGMAC2_REGISTER_TX_SOURCE_ADDR (0x1D<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTBYT (0x39<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTPOK (0x22<<3) +#define BIGMAC2_REGISTER_TX_STAT_GTPP (0x24<<3) #define EMAC_LED_1000MB_OVERRIDE (1L<<1) #define EMAC_LED_100MB_OVERRIDE (1L<<2) #define EMAC_LED_10MB_OVERRIDE (1L<<3) @@ -4478,6 +5043,8 @@ #define HW_LOCK_RESOURCE_SPIO 2 #define HW_LOCK_RESOURCE_UNDI 5 #define PRS_FLAG_OVERETH_IPV4 1 +#define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) +#define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (1<<18) #define AEU_INPUTS_ATTN_BITS_CCM_HW_INTERRUPT (1<<31) #define AEU_INPUTS_ATTN_BITS_CDU_HW_INTERRUPT (1<<9) @@ -4504,6 +5071,8 @@ #define AEU_INPUTS_ATTN_BITS_PARSER_PARITY_ERROR (1<<20) #define AEU_INPUTS_ATTN_BITS_PBCLIENT_PARITY_ERROR (1<<0) #define AEU_INPUTS_ATTN_BITS_PBF_HW_INTERRUPT (1<<31) +#define AEU_INPUTS_ATTN_BITS_PGLUE_HW_INTERRUPT (0x1<<2) +#define AEU_INPUTS_ATTN_BITS_PGLUE_PARITY_ERROR (0x1<<3) #define AEU_INPUTS_ATTN_BITS_PXP_HW_INTERRUPT (1<<3) #define AEU_INPUTS_ATTN_BITS_PXP_PARITY_ERROR (1<<2) #define AEU_INPUTS_ATTN_BITS_PXPPCICLOCKCLIENT_HW_INTERRUPT (1<<5) @@ -4796,6 +5365,253 @@ #define PCI_ID_VAL1 0x434 #define PCI_ID_VAL2 0x438 +#define PXPCS_TL_CONTROL_5 0x814 +#define PXPCS_TL_CONTROL_5_UNKNOWNTYPE_ERR_ATTN (1 << 29) /*WC*/ +#define PXPCS_TL_CONTROL_5_BOUNDARY4K_ERR_ATTN (1 << 28) /*WC*/ +#define PXPCS_TL_CONTROL_5_MRRS_ERR_ATTN (1 << 27) /*WC*/ +#define PXPCS_TL_CONTROL_5_MPS_ERR_ATTN (1 << 26) /*WC*/ +#define PXPCS_TL_CONTROL_5_TTX_BRIDGE_FORWARD_ERR (1 << 25) /*WC*/ +#define PXPCS_TL_CONTROL_5_TTX_TXINTF_OVERFLOW (1 << 24) /*WC*/ +#define PXPCS_TL_CONTROL_5_PHY_ERR_ATTN (1 << 23) /*RO*/ +#define PXPCS_TL_CONTROL_5_DL_ERR_ATTN (1 << 22) /*RO*/ +#define PXPCS_TL_CONTROL_5_TTX_ERR_NP_TAG_IN_USE (1 << 21) /*WC*/ +#define PXPCS_TL_CONTROL_5_TRX_ERR_UNEXP_RTAG (1 << 20) /*WC*/ +#define PXPCS_TL_CONTROL_5_PRI_SIG_TARGET_ABORT1 (1 << 19) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNSPPORT1 (1 << 18) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_ECRC1 (1 << 17) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MALF_TLP1 (1 << 16) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_RX_OFLOW1 (1 << 15) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNEXP_CPL1 (1 << 14) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MASTER_ABRT1 (1 << 13) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_CPL_TIMEOUT1 (1 << 12) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_FC_PRTL1 (1 << 11) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_PSND_TLP1 (1 << 10) /*WC*/ +#define PXPCS_TL_CONTROL_5_PRI_SIG_TARGET_ABORT (1 << 9) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNSPPORT (1 << 8) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_ECRC (1 << 7) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MALF_TLP (1 << 6) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_RX_OFLOW (1 << 5) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_UNEXP_CPL (1 << 4) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_MASTER_ABRT (1 << 3) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_CPL_TIMEOUT (1 << 2) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_FC_PRTL (1 << 1) /*WC*/ +#define PXPCS_TL_CONTROL_5_ERR_PSND_TLP (1 << 0) /*WC*/ + + +#define PXPCS_TL_FUNC345_STAT 0x854 +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT4 (1 << 29) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT4\ + (1 << 28) /* Unsupported Request Error Status in function4, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC4\ + (1 << 27) /* ECRC Error TLP Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP4\ + (1 << 26) /* Malformed TLP Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW4\ + (1 << 25) /* Receiver Overflow Status Status in function 4, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL4\ + (1 << 24) /* Unexpected Completion Status Status in function 4, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT4\ + (1 << 23) /* Receive UR Statusin function 4. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT4\ + (1 << 22) /* Completer Timeout Status Status in function 4, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL4\ + (1 << 21) /* Flow Control Protocol Error Status Status in \ + function 4, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP4\ + (1 << 20) /* Poisoned Error Status Status in function 4, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT3 (1 << 19) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT3\ + (1 << 18) /* Unsupported Request Error Status in function3, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC3\ + (1 << 17) /* ECRC Error TLP Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP3\ + (1 << 16) /* Malformed TLP Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW3\ + (1 << 15) /* Receiver Overflow Status Status in function 3, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL3\ + (1 << 14) /* Unexpected Completion Status Status in function 3, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT3\ + (1 << 13) /* Receive UR Statusin function 3. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT3\ + (1 << 12) /* Completer Timeout Status Status in function 3, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL3\ + (1 << 11) /* Flow Control Protocol Error Status Status in \ + function 3, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP3\ + (1 << 10) /* Poisoned Error Status Status in function 3, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_PRI_SIG_TARGET_ABORT2 (1 << 9) /* WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNSPPORT2\ + (1 << 8) /* Unsupported Request Error Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_ECRC2\ + (1 << 7) /* ECRC Error TLP Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_MALF_TLP2\ + (1 << 6) /* Malformed TLP Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_RX_OFLOW2\ + (1 << 5) /* Receiver Overflow Status Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_UNEXP_CPL2\ + (1 << 4) /* Unexpected Completion Status Status for Function 2, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC345_STAT_ERR_MASTER_ABRT2\ + (1 << 3) /* Receive UR Statusfor Function 2. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_CPL_TIMEOUT2\ + (1 << 2) /* Completer Timeout Status Status for Function 2, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_FC_PRTL2\ + (1 << 1) /* Flow Control Protocol Error Status Status for \ + Function 2, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC345_STAT_ERR_PSND_TLP2\ + (1 << 0) /* Poisoned Error Status Status for Function 2, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ + + +#define PXPCS_TL_FUNC678_STAT 0x85C +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT7 (1 << 29) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT7\ + (1 << 28) /* Unsupported Request Error Status in function7, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC7\ + (1 << 27) /* ECRC Error TLP Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP7\ + (1 << 26) /* Malformed TLP Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW7\ + (1 << 25) /* Receiver Overflow Status Status in function 7, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL7\ + (1 << 24) /* Unexpected Completion Status Status in function 7, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT7\ + (1 << 23) /* Receive UR Statusin function 7. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT7\ + (1 << 22) /* Completer Timeout Status Status in function 7, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL7\ + (1 << 21) /* Flow Control Protocol Error Status Status in \ + function 7, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP7\ + (1 << 20) /* Poisoned Error Status Status in function 7, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT6 (1 << 19) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT6\ + (1 << 18) /* Unsupported Request Error Status in function6, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC6\ + (1 << 17) /* ECRC Error TLP Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP6\ + (1 << 16) /* Malformed TLP Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW6\ + (1 << 15) /* Receiver Overflow Status Status in function 6, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL6\ + (1 << 14) /* Unexpected Completion Status Status in function 6, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT6\ + (1 << 13) /* Receive UR Statusin function 6. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT6\ + (1 << 12) /* Completer Timeout Status Status in function 6, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL6\ + (1 << 11) /* Flow Control Protocol Error Status Status in \ + function 6, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP6\ + (1 << 10) /* Poisoned Error Status Status in function 6, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_PRI_SIG_TARGET_ABORT5 (1 << 9) /* WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNSPPORT5\ + (1 << 8) /* Unsupported Request Error Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_ECRC5\ + (1 << 7) /* ECRC Error TLP Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_MALF_TLP5\ + (1 << 6) /* Malformed TLP Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_RX_OFLOW5\ + (1 << 5) /* Receiver Overflow Status Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen.. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_UNEXP_CPL5\ + (1 << 4) /* Unexpected Completion Status Status for Function 5, \ + if set, generate pcie_err_attn output when this error is seen. WC \ + */ +#define PXPCS_TL_FUNC678_STAT_ERR_MASTER_ABRT5\ + (1 << 3) /* Receive UR Statusfor Function 5. If set, generate \ + pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_CPL_TIMEOUT5\ + (1 << 2) /* Completer Timeout Status Status for Function 5, if \ + set, generate pcie_err_attn output when this error is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_FC_PRTL5\ + (1 << 1) /* Flow Control Protocol Error Status Status for \ + Function 5, if set, generate pcie_err_attn output when this error \ + is seen. WC */ +#define PXPCS_TL_FUNC678_STAT_ERR_PSND_TLP5\ + (1 << 0) /* Poisoned Error Status Status for Function 5, if set, \ + generate pcie_err_attn output when this error is seen.. WC */ + + +#define BAR_USTRORM_INTMEM 0x400000 +#define BAR_CSTRORM_INTMEM 0x410000 +#define BAR_XSTRORM_INTMEM 0x420000 +#define BAR_TSTRORM_INTMEM 0x430000 + +/* for accessing the IGU in case of status block ACK */ +#define BAR_IGU_INTMEM 0x440000 + +#define BAR_DOORBELL_OFFSET 0x800000 + +#define BAR_ME_REGISTER 0x450000 +#define ME_REG_PF_NUM_SHIFT 0 +#define ME_REG_PF_NUM\ + (7L<stats_pending) { - struct eth_query_ramrod_data ramrod_data = {0}; + struct common_query_ramrod_data ramrod_data = {0}; int i, rc; spin_lock_bh(&bp->stats_lock); @@ -163,14 +163,11 @@ static void bnx2x_storm_stats_post(struct bnx2x *bp) for_each_queue(bp, i) ramrod_data.ctr_id_vector |= (1 << bp->fp[i].cl_id); - rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_ETH_STAT_QUERY, 0, + rc = bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_STAT_QUERY, 0, ((u32 *)&ramrod_data)[1], - ((u32 *)&ramrod_data)[0], 0); - if (rc == 0) { - /* stats ramrod has it's own slot on the spq */ - bp->spq_left++; + ((u32 *)&ramrod_data)[0], 1); + if (rc == 0) bp->stats_pending = 1; - } spin_unlock_bh(&bp->stats_lock); } @@ -188,20 +185,12 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) /* loader */ if (bp->executer_idx) { int loader_idx = PMF_DMAE_C(bp); + u32 opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_GRC); + opcode = bnx2x_dmae_opcode_clr_src_reset(opcode); memset(dmae, 0, sizeof(struct dmae_command)); - - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : - DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = opcode; dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, dmae[0])); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, dmae[0])); dmae->dst_addr_lo = (DMAE_REG_CMD_MEM + @@ -253,26 +242,17 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp) u32 *stats_comp = bnx2x_sp(bp, stats_comp); /* sanity */ - if (!IS_E1HMF(bp) || !bp->port.pmf || !bp->port.port_stx) { + if (!IS_MF(bp) || !bp->port.pmf || !bp->port.port_stx) { BNX2X_ERR("BUG!\n"); return; } bp->executer_idx = 0; - opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, false, 0); dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); + dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_GRC); dmae->src_addr_lo = bp->port.port_stx >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); @@ -283,7 +263,7 @@ static void bnx2x_stats_pmf_update(struct bnx2x *bp) dmae->comp_val = 1; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI); dmae->src_addr_lo = (bp->port.port_stx >> 2) + DMAE_LEN32_RD_MAX; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats) + @@ -304,7 +284,6 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) { struct dmae_command *dmae; int port = BP_PORT(bp); - int vn = BP_E1HVN(bp); u32 opcode; int loader_idx = PMF_DMAE_C(bp); u32 mac_addr; @@ -319,16 +298,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) bp->executer_idx = 0; /* MCP */ - opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_GRC); if (bp->port.port_stx) { @@ -359,16 +330,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) } /* MAC */ - opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_GRC | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_GRC); if (bp->link_vars.mac_type == MAC_TYPE_BMAC) { @@ -379,13 +342,21 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) BIGMAC_REGISTER_TX_STAT_GTBYT */ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + + if (CHIP_IS_E1x(bp)) { + dmae->src_addr_lo = (mac_addr + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - + BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; + } else { + dmae->src_addr_lo = (mac_addr + + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; + dmae->len = (8 + BIGMAC2_REGISTER_TX_STAT_GTBYT - + BIGMAC2_REGISTER_TX_STAT_GTPOK) >> 2; + } + dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats)); dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats)); - dmae->len = (8 + BIGMAC_REGISTER_TX_STAT_GTBYT - - BIGMAC_REGISTER_TX_STAT_GTPKT) >> 2; dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_hi = 0; dmae->comp_val = 1; @@ -394,15 +365,31 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) BIGMAC_REGISTER_RX_STAT_GRIPJ */ dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); dmae->opcode = opcode; - dmae->src_addr_lo = (mac_addr + - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; dmae->src_addr_hi = 0; - dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac_stats, rx_stat_gr64_lo)); - dmae->dst_addr_hi = U64_HI(bnx2x_sp_mapping(bp, mac_stats) + - offsetof(struct bmac_stats, rx_stat_gr64_lo)); - dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - - BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + if (CHIP_IS_E1x(bp)) { + dmae->src_addr_lo = (mac_addr + + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + dmae->dst_addr_lo = + U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); + dmae->dst_addr_hi = + U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac1_stats, rx_stat_gr64_lo)); + dmae->len = (8 + BIGMAC_REGISTER_RX_STAT_GRIPJ - + BIGMAC_REGISTER_RX_STAT_GR64) >> 2; + } else { + dmae->src_addr_lo = + (mac_addr + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; + dmae->dst_addr_lo = + U64_LO(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac2_stats, rx_stat_gr64_lo)); + dmae->dst_addr_hi = + U64_HI(bnx2x_sp_mapping(bp, mac_stats) + + offsetof(struct bmac2_stats, rx_stat_gr64_lo)); + dmae->len = (8 + BIGMAC2_REGISTER_RX_STAT_GRIPJ - + BIGMAC2_REGISTER_RX_STAT_GR64) >> 2; + } + dmae->comp_addr_lo = dmae_reg_go_c[loader_idx] >> 2; dmae->comp_addr_hi = 0; dmae->comp_val = 1; @@ -483,16 +470,8 @@ static void bnx2x_port_stats_init(struct bnx2x *bp) dmae->comp_val = 1; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (vn << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_PCI); dmae->src_addr_lo = (port ? NIG_REG_STAT1_EGRESS_MAC_PKT1 : NIG_REG_STAT0_EGRESS_MAC_PKT1) >> 2; dmae->src_addr_hi = 0; @@ -522,16 +501,8 @@ static void bnx2x_func_stats_init(struct bnx2x *bp) bp->executer_idx = 0; memset(dmae, 0, sizeof(struct dmae_command)); - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); dmae->dst_addr_lo = bp->func_stx >> 2; @@ -571,7 +542,6 @@ static void bnx2x_stats_restart(struct bnx2x *bp) static void bnx2x_bmac_stats_update(struct bnx2x *bp) { - struct bmac_stats *new = bnx2x_sp(bp, mac_stats.bmac_stats); struct host_port_stats *pstats = bnx2x_sp(bp, port_stats); struct bnx2x_eth_stats *estats = &bp->eth_stats; struct { @@ -579,35 +549,74 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) u32 hi; } diff; - UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); - UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); - UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); - UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); - UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); - UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); - UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); - UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); - UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); - UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); - UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); - UPDATE_STAT64(tx_stat_gt127, + if (CHIP_IS_E1x(bp)) { + struct bmac1_stats *new = bnx2x_sp(bp, mac_stats.bmac1_stats); + + /* the macros below will use "bmac1_stats" type */ + UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); + UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); + UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); + UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); + UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); + UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); + UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); + UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); + UPDATE_STAT64(tx_stat_gt127, + tx_stat_etherstatspkts65octetsto127octets); + UPDATE_STAT64(tx_stat_gt255, + tx_stat_etherstatspkts128octetsto255octets); + UPDATE_STAT64(tx_stat_gt511, + tx_stat_etherstatspkts256octetsto511octets); + UPDATE_STAT64(tx_stat_gt1023, + tx_stat_etherstatspkts512octetsto1023octets); + UPDATE_STAT64(tx_stat_gt1518, + tx_stat_etherstatspkts1024octetsto1522octets); + UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gterr, + tx_stat_dot3statsinternalmactransmiterrors); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + + } else { + struct bmac2_stats *new = bnx2x_sp(bp, mac_stats.bmac2_stats); + + /* the macros below will use "bmac2_stats" type */ + UPDATE_STAT64(rx_stat_grerb, rx_stat_ifhcinbadoctets); + UPDATE_STAT64(rx_stat_grfcs, rx_stat_dot3statsfcserrors); + UPDATE_STAT64(rx_stat_grund, rx_stat_etherstatsundersizepkts); + UPDATE_STAT64(rx_stat_grovr, rx_stat_dot3statsframestoolong); + UPDATE_STAT64(rx_stat_grfrg, rx_stat_etherstatsfragments); + UPDATE_STAT64(rx_stat_grjbr, rx_stat_etherstatsjabbers); + UPDATE_STAT64(rx_stat_grxcf, rx_stat_maccontrolframesreceived); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_xoffstateentered); + UPDATE_STAT64(rx_stat_grxpf, rx_stat_bmac_xpf); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_outxoffsent); + UPDATE_STAT64(tx_stat_gtxpf, tx_stat_flowcontroldone); + UPDATE_STAT64(tx_stat_gt64, tx_stat_etherstatspkts64octets); + UPDATE_STAT64(tx_stat_gt127, tx_stat_etherstatspkts65octetsto127octets); - UPDATE_STAT64(tx_stat_gt255, + UPDATE_STAT64(tx_stat_gt255, tx_stat_etherstatspkts128octetsto255octets); - UPDATE_STAT64(tx_stat_gt511, + UPDATE_STAT64(tx_stat_gt511, tx_stat_etherstatspkts256octetsto511octets); - UPDATE_STAT64(tx_stat_gt1023, + UPDATE_STAT64(tx_stat_gt1023, tx_stat_etherstatspkts512octetsto1023octets); - UPDATE_STAT64(tx_stat_gt1518, + UPDATE_STAT64(tx_stat_gt1518, tx_stat_etherstatspkts1024octetsto1522octets); - UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); - UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); - UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); - UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); - UPDATE_STAT64(tx_stat_gterr, + UPDATE_STAT64(tx_stat_gt2047, tx_stat_bmac_2047); + UPDATE_STAT64(tx_stat_gt4095, tx_stat_bmac_4095); + UPDATE_STAT64(tx_stat_gt9216, tx_stat_bmac_9216); + UPDATE_STAT64(tx_stat_gt16383, tx_stat_bmac_16383); + UPDATE_STAT64(tx_stat_gterr, tx_stat_dot3statsinternalmactransmiterrors); - UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + UPDATE_STAT64(tx_stat_gtufl, tx_stat_bmac_ufl); + } estats->pause_frames_received_hi = pstats->mac_stx[1].rx_stat_bmac_xpf_hi; @@ -969,6 +978,7 @@ static void bnx2x_net_stats_update(struct bnx2x *bp) { struct bnx2x_eth_stats *estats = &bp->eth_stats; struct net_device_stats *nstats = &bp->dev->stats; + unsigned long tmp; int i; nstats->rx_packets = @@ -985,10 +995,10 @@ static void bnx2x_net_stats_update(struct bnx2x *bp) nstats->tx_bytes = bnx2x_hilo(&estats->total_bytes_transmitted_hi); - nstats->rx_dropped = estats->mac_discard; + tmp = estats->mac_discard; for_each_queue(bp, i) - nstats->rx_dropped += - le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); + tmp += le32_to_cpu(bp->fp[i].old_tclient.checksum_discard); + nstats->rx_dropped = tmp; nstats->tx_dropped = 0; @@ -1123,24 +1133,17 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp) bp->executer_idx = 0; - opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, false, 0); if (bp->port.port_stx) { dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); if (bp->func_stx) - dmae->opcode = (opcode | DMAE_CMD_C_DST_GRC); + dmae->opcode = bnx2x_dmae_opcode_add_comp( + opcode, DMAE_COMP_GRC); else - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = bnx2x_dmae_opcode_add_comp( + opcode, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); dmae->dst_addr_lo = bp->port.port_stx >> 2; @@ -1164,7 +1167,8 @@ static void bnx2x_port_stats_stop(struct bnx2x *bp) if (bp->func_stx) { dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (opcode | DMAE_CMD_C_DST_PCI); + dmae->opcode = + bnx2x_dmae_opcode_add_comp(opcode, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, func_stats)); dmae->dst_addr_lo = bp->func_stx >> 2; @@ -1257,16 +1261,8 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp) bp->executer_idx = 0; dmae = bnx2x_sp(bp, dmae[bp->executer_idx++]); - dmae->opcode = (DMAE_CMD_SRC_PCI | DMAE_CMD_DST_GRC | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_PCI, DMAE_DST_GRC, + true, DMAE_COMP_PCI); dmae->src_addr_lo = U64_LO(bnx2x_sp_mapping(bp, port_stats)); dmae->src_addr_hi = U64_HI(bnx2x_sp_mapping(bp, port_stats)); dmae->dst_addr_lo = bp->port.port_stx >> 2; @@ -1283,9 +1279,7 @@ static void bnx2x_port_stats_base_init(struct bnx2x *bp) static void bnx2x_func_stats_base_init(struct bnx2x *bp) { - int vn, vn_max = IS_E1HMF(bp) ? E1HVN_MAX : E1VN_MAX; - int port = BP_PORT(bp); - int func; + int vn, vn_max = IS_MF(bp) ? E1HVN_MAX : E1VN_MAX; u32 func_stx; /* sanity */ @@ -1298,9 +1292,9 @@ static void bnx2x_func_stats_base_init(struct bnx2x *bp) func_stx = bp->func_stx; for (vn = VN_0; vn < vn_max; vn++) { - func = 2*vn + port; + int mb_idx = !CHIP_IS_E2(bp) ? 2*vn + BP_PORT(bp) : vn; - bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); + bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param); bnx2x_func_stats_init(bp); bnx2x_hw_stats_post(bp); bnx2x_stats_comp(bp); @@ -1324,16 +1318,8 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp) bp->executer_idx = 0; memset(dmae, 0, sizeof(struct dmae_command)); - dmae->opcode = (DMAE_CMD_SRC_GRC | DMAE_CMD_DST_PCI | - DMAE_CMD_C_DST_PCI | DMAE_CMD_C_ENABLE | - DMAE_CMD_SRC_RESET | DMAE_CMD_DST_RESET | -#ifdef __BIG_ENDIAN - DMAE_CMD_ENDIANITY_B_DW_SWAP | -#else - DMAE_CMD_ENDIANITY_DW_SWAP | -#endif - (BP_PORT(bp) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0) | - (BP_E1HVN(bp) << DMAE_CMD_E1HVN_SHIFT)); + dmae->opcode = bnx2x_dmae_opcode(bp, DMAE_SRC_GRC, DMAE_DST_PCI, + true, DMAE_COMP_PCI); dmae->src_addr_lo = bp->func_stx >> 2; dmae->src_addr_hi = 0; dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, func_stats_base)); @@ -1351,8 +1337,9 @@ static void bnx2x_func_stats_base_update(struct bnx2x *bp) void bnx2x_stats_init(struct bnx2x *bp) { int port = BP_PORT(bp); - int func = BP_FUNC(bp); + int mb_idx = BP_FW_MB_IDX(bp); int i; + struct eth_stats_query *stats = bnx2x_sp(bp, fw_stats); bp->stats_pending = 0; bp->executer_idx = 0; @@ -1361,7 +1348,7 @@ void bnx2x_stats_init(struct bnx2x *bp) /* port and func stats for management */ if (!BP_NOMCP(bp)) { bp->port.port_stx = SHMEM_RD(bp, port_mb[port].port_stx); - bp->func_stx = SHMEM_RD(bp, func_mb[func].fw_mb_param); + bp->func_stx = SHMEM_RD(bp, func_mb[mb_idx].fw_mb_param); } else { bp->port.port_stx = 0; @@ -1394,6 +1381,18 @@ void bnx2x_stats_init(struct bnx2x *bp) memset(&fp->eth_q_stats, 0, sizeof(struct bnx2x_eth_q_stats)); } + for_each_queue(bp, i) { + /* Set initial stats counter in the stats ramrod data to -1 */ + int cl_id = bp->fp[i].cl_id; + + stats->xstorm_common.client_statistics[cl_id]. + stats_counter = 0xffff; + stats->ustorm_common.client_statistics[cl_id]. + stats_counter = 0xffff; + stats->tstorm_common.client_statistics[cl_id]. + stats_counter = 0xffff; + } + memset(&bp->dev->stats, 0, sizeof(struct net_device_stats)); memset(&bp->eth_stats, 0, sizeof(struct bnx2x_eth_stats)); diff --git a/drivers/net/bnx2x/bnx2x_stats.h b/drivers/net/bnx2x/bnx2x_stats.h index 38a4e908f4fbe141be6ee1149a06727036a9e0d3..afd15efa429a35f7fcb6eab29581cd971b654cb8 100644 --- a/drivers/net/bnx2x/bnx2x_stats.h +++ b/drivers/net/bnx2x/bnx2x_stats.h @@ -9,6 +9,10 @@ * Maintained by: Eilon Greenstein * Written by: Eliezer Tamir * Based on code from Michael Chan's bnx2 driver + * UDP CSUM errata workaround by Arik Gendelman + * Slowpath and fastpath rework by Vladislav Zolotarov + * Statistics and Link management by Yitchak Gertner + * */ #ifndef BNX2X_STATS_H @@ -228,12 +232,8 @@ struct bnx2x_eth_stats { /* Forward declaration */ struct bnx2x; - void bnx2x_stats_init(struct bnx2x *bp); extern const u32 dmae_reg_go_c[]; -extern int bnx2x_sp_post(struct bnx2x *bp, int command, int cid, - u32 data_hi, u32 data_lo, int common); - #endif /* BNX2X_STATS_H */ diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 0ddf4c66afe21aa99679a3fb31b1e932dc51612c..881914bc4e9c0177a371c76c9781568aa0b4ffdd 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -93,7 +93,7 @@ // compare MAC addresses #define MAC_ADDRESS_COMPARE(A, B) memcmp(A, B, ETH_ALEN) -static struct mac_addr null_mac_addr = {{0, 0, 0, 0, 0, 0}}; +static struct mac_addr null_mac_addr = { { 0, 0, 0, 0, 0, 0 } }; static u16 ad_ticks_per_sec; static const int ad_delta_in_ticks = (AD_TIMER_INTERVAL * HZ) / 1000; @@ -129,9 +129,8 @@ static void ad_marker_response_received(struct bond_marker *marker, struct port */ static inline struct bonding *__get_bond_by_port(struct port *port) { - if (port->slave == NULL) { + if (port->slave == NULL) return NULL; - } return bond_get_bond_by_slave(port->slave); } @@ -144,9 +143,8 @@ static inline struct bonding *__get_bond_by_port(struct port *port) */ static inline struct port *__get_first_port(struct bonding *bond) { - if (bond->slave_cnt == 0) { + if (bond->slave_cnt == 0) return NULL; - } return &(SLAVE_AD_INFO(bond->first_slave).port); } @@ -164,9 +162,8 @@ static inline struct port *__get_next_port(struct port *port) struct slave *slave = port->slave; // If there's no bond for this port, or this is the last slave - if ((bond == NULL) || (slave->next == bond->first_slave)) { + if ((bond == NULL) || (slave->next == bond->first_slave)) return NULL; - } return &(SLAVE_AD_INFO(slave->next).port); } @@ -183,9 +180,8 @@ static inline struct aggregator *__get_first_agg(struct port *port) struct bonding *bond = __get_bond_by_port(port); // If there's no bond for this port, or bond has no slaves - if ((bond == NULL) || (bond->slave_cnt == 0)) { + if ((bond == NULL) || (bond->slave_cnt == 0)) return NULL; - } return &(SLAVE_AD_INFO(bond->first_slave).aggregator); } @@ -203,9 +199,8 @@ static inline struct aggregator *__get_next_agg(struct aggregator *aggregator) struct bonding *bond = bond_get_bond_by_slave(slave); // If there's no bond for this aggregator, or this is the last slave - if ((bond == NULL) || (slave->next == bond->first_slave)) { + if ((bond == NULL) || (slave->next == bond->first_slave)) return NULL; - } return &(SLAVE_AD_INFO(slave->next).aggregator); } @@ -240,9 +235,8 @@ static inline void __enable_port(struct port *port) { struct slave *slave = port->slave; - if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) { + if ((slave->link == BOND_LINK_UP) && IS_UP(slave->dev)) bond_set_slave_active_flags(slave); - } } /** @@ -252,7 +246,7 @@ static inline void __enable_port(struct port *port) */ static inline int __port_is_enabled(struct port *port) { - return(port->slave->state == BOND_STATE_ACTIVE); + return port->slave->state == BOND_STATE_ACTIVE; } /** @@ -265,9 +259,8 @@ static inline u32 __get_agg_selection_mode(struct port *port) { struct bonding *bond = __get_bond_by_port(port); - if (bond == NULL) { + if (bond == NULL) return BOND_AD_STABLE; - } return BOND_AD_INFO(bond).agg_select_mode; } @@ -281,9 +274,8 @@ static inline int __check_agg_selection_timer(struct port *port) { struct bonding *bond = __get_bond_by_port(port); - if (bond == NULL) { + if (bond == NULL) return 0; - } return BOND_AD_INFO(bond).agg_select_timer ? 1 : 0; } @@ -328,9 +320,9 @@ static u16 __get_link_speed(struct port *port) * link down, it sets the speed to 0. * This is done in spite of the fact that the e100 driver reports 0 to be * compatible with MVT in the future.*/ - if (slave->link != BOND_LINK_UP) { - speed=0; - } else { + if (slave->link != BOND_LINK_UP) + speed = 0; + else { switch (slave->speed) { case SPEED_10: speed = AD_LINK_SPEED_BITMASK_10MBPS; @@ -375,18 +367,18 @@ static u8 __get_duplex(struct port *port) // handling a special case: when the configuration starts with // link down, it sets the duplex to 0. - if (slave->link != BOND_LINK_UP) { - retval=0x0; - } else { + if (slave->link != BOND_LINK_UP) + retval = 0x0; + else { switch (slave->duplex) { case DUPLEX_FULL: - retval=0x1; + retval = 0x1; pr_debug("Port %d Received status full duplex update from adapter\n", port->actor_port_number); break; case DUPLEX_HALF: default: - retval=0x0; + retval = 0x0; pr_debug("Port %d Received status NOT full duplex update from adapter\n", port->actor_port_number); break; @@ -419,15 +411,14 @@ static inline void __initialize_port_locks(struct port *port) */ static u16 __ad_timer_to_ticks(u16 timer_type, u16 par) { - u16 retval=0; //to silence the compiler + u16 retval = 0; /* to silence the compiler */ switch (timer_type) { case AD_CURRENT_WHILE_TIMER: // for rx machine usage - if (par) { // for short or long timeout + if (par) retval = (AD_SHORT_TIMEOUT_TIME*ad_ticks_per_sec); // short timeout - } else { + else retval = (AD_LONG_TIMEOUT_TIME*ad_ticks_per_sec); // long timeout - } break; case AD_ACTOR_CHURN_TIMER: // for local churn machine retval = (AD_CHURN_DETECTION_TIME*ad_ticks_per_sec); @@ -519,11 +510,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) port->actor_oper_port_state &= ~AD_STATE_DEFAULTED; // set the partner sync. to on if the partner is sync. and the port is matched - if ((port->sm_vars & AD_PORT_MATCHED) && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) { + if ((port->sm_vars & AD_PORT_MATCHED) + && (lacpdu->actor_state & AD_STATE_SYNCHRONIZATION)) partner->port_state |= AD_STATE_SYNCHRONIZATION; - } else { + else partner->port_state &= ~AD_STATE_SYNCHRONIZATION; - } } } @@ -653,7 +644,7 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port) */ static void __attach_bond_to_agg(struct port *port) { - port=NULL; // just to satisfy the compiler + port = NULL; /* just to satisfy the compiler */ // This function does nothing since the parser/multiplexer of the receive // and the parser/multiplexer of the aggregator are already combined } @@ -668,7 +659,7 @@ static void __attach_bond_to_agg(struct port *port) */ static void __detach_bond_from_agg(struct port *port) { - port=NULL; // just to satisfy the compiler + port = NULL; /* just to satisfy the compiler */ // This function does nothing sience the parser/multiplexer of the receive // and the parser/multiplexer of the aggregator are already combined } @@ -685,7 +676,9 @@ static int __agg_ports_are_ready(struct aggregator *aggregator) if (aggregator) { // scan all ports in this aggregator to verfy if they are all ready - for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) { + for (port = aggregator->lag_ports; + port; + port = port->next_port_in_aggregator) { if (!(port->sm_vars & AD_PORT_READY_N)) { retval = 0; break; @@ -706,12 +699,12 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val) { struct port *port; - for (port=aggregator->lag_ports; port; port=port->next_port_in_aggregator) { - if (val) { + for (port = aggregator->lag_ports; port; + port = port->next_port_in_aggregator) { + if (val) port->sm_vars |= AD_PORT_READY; - } else { + else port->sm_vars &= ~AD_PORT_READY; - } } } @@ -722,7 +715,7 @@ static void __set_agg_ports_ready(struct aggregator *aggregator, int val) */ static u32 __get_agg_bandwidth(struct aggregator *aggregator) { - u32 bandwidth=0; + u32 bandwidth = 0; u32 basic_speed; if (aggregator->num_of_ports) { @@ -744,7 +737,7 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) bandwidth = aggregator->num_of_ports * 10000; break; default: - bandwidth=0; // to silent the compilor .... + bandwidth = 0; /*to silence the compiler ....*/ } } return bandwidth; @@ -835,9 +828,8 @@ static int ad_lacpdu_send(struct port *port) int length = sizeof(struct lacpdu_header); skb = dev_alloc_skb(length); - if (!skb) { + if (!skb) return -ENOMEM; - } skb->dev = slave->dev; skb_reset_mac_header(skb); @@ -876,9 +868,8 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) int length = sizeof(struct bond_marker_header); skb = dev_alloc_skb(length + 16); - if (!skb) { + if (!skb) return -ENOMEM; - } skb_reserve(skb, 16); @@ -919,9 +910,10 @@ static void ad_mux_machine(struct port *port) } else { switch (port->sm_mux_state) { case AD_MUX_DETACHED: - if ((port->sm_vars & AD_PORT_SELECTED) || (port->sm_vars & AD_PORT_STANDBY)) { // if SELECTED or STANDBY + if ((port->sm_vars & AD_PORT_SELECTED) + || (port->sm_vars & AD_PORT_STANDBY)) + /* if SELECTED or STANDBY */ port->sm_mux_state = AD_MUX_WAITING; // next state - } break; case AD_MUX_WAITING: // if SELECTED == FALSE return to DETACH state @@ -935,18 +927,18 @@ static void ad_mux_machine(struct port *port) } // check if the wait_while_timer expired - if (port->sm_mux_timer_counter && !(--port->sm_mux_timer_counter)) { + if (port->sm_mux_timer_counter + && !(--port->sm_mux_timer_counter)) port->sm_vars |= AD_PORT_READY_N; - } // in order to withhold the selection logic to check all ports READY_N value // every callback cycle to update ready variable, we check READY_N and update READY here __set_agg_ports_ready(port->aggregator, __agg_ports_are_ready(port->aggregator)); // if the wait_while_timer expired, and the port is in READY state, move to ATTACHED state - if ((port->sm_vars & AD_PORT_READY) && !port->sm_mux_timer_counter) { + if ((port->sm_vars & AD_PORT_READY) + && !port->sm_mux_timer_counter) port->sm_mux_state = AD_MUX_ATTACHED; // next state - } break; case AD_MUX_ATTACHED: // check also if agg_select_timer expired(so the edable port will take place only after this timer) @@ -1041,13 +1033,14 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) // check if state machine should change state // first, check if port was reinitialized - if (port->sm_vars & AD_PORT_BEGIN) { - port->sm_rx_state = AD_RX_INITIALIZE; // next state - } + if (port->sm_vars & AD_PORT_BEGIN) + /* next state */ + port->sm_rx_state = AD_RX_INITIALIZE; // check if port is not enabled - else if (!(port->sm_vars & AD_PORT_BEGIN) && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) { - port->sm_rx_state = AD_RX_PORT_DISABLED; // next state - } + else if (!(port->sm_vars & AD_PORT_BEGIN) + && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) + /* next state */ + port->sm_rx_state = AD_RX_PORT_DISABLED; // check if new lacpdu arrived else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || (port->sm_rx_state == AD_RX_DEFAULTED) || (port->sm_rx_state == AD_RX_CURRENT))) { port->sm_rx_timer_counter = 0; // zero timer @@ -1069,13 +1062,16 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) // if no lacpdu arrived and no timer is on switch (port->sm_rx_state) { case AD_RX_PORT_DISABLED: - if (port->sm_vars & AD_PORT_MOVED) { + if (port->sm_vars & AD_PORT_MOVED) port->sm_rx_state = AD_RX_INITIALIZE; // next state - } else if (port->is_enabled && (port->sm_vars & AD_PORT_LACP_ENABLED)) { + else if (port->is_enabled + && (port->sm_vars + & AD_PORT_LACP_ENABLED)) port->sm_rx_state = AD_RX_EXPIRED; // next state - } else if (port->is_enabled && ((port->sm_vars & AD_PORT_LACP_ENABLED) == 0)) { + else if (port->is_enabled + && ((port->sm_vars + & AD_PORT_LACP_ENABLED) == 0)) port->sm_rx_state = AD_RX_LACP_DISABLED; // next state - } break; default: //to silence the compiler break; @@ -1091,11 +1087,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) port->sm_rx_state); switch (port->sm_rx_state) { case AD_RX_INITIALIZE: - if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { + if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) port->sm_vars &= ~AD_PORT_LACP_ENABLED; - } else { + else port->sm_vars |= AD_PORT_LACP_ENABLED; - } port->sm_vars &= ~AD_PORT_SELECTED; __record_default(port); port->actor_oper_port_state &= ~AD_STATE_EXPIRED; @@ -1149,9 +1144,10 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) // verify that if the aggregator is enabled, the port is enabled too. //(because if the link goes down for a short time, the 802.3ad will not // catch it, and the port will continue to be disabled) - if (port->aggregator && port->aggregator->is_active && !__port_is_enabled(port)) { + if (port->aggregator + && port->aggregator->is_active + && !__port_is_enabled(port)) __enable_port(port); - } break; default: //to silence the compiler break; @@ -1183,7 +1179,8 @@ static void ad_tx_machine(struct port *port) } } // restart tx timer(to verify that we will not exceed AD_MAX_TX_IN_SECOND - port->sm_tx_timer_counter=ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; + port->sm_tx_timer_counter = + ad_ticks_per_sec/AD_MAX_TX_IN_SECOND; } } @@ -1216,9 +1213,9 @@ static void ad_periodic_machine(struct port *port) // If not expired, check if there is some new timeout parameter from the partner state switch (port->sm_periodic_state) { case AD_FAST_PERIODIC: - if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { + if (!(port->partner_oper.port_state + & AD_STATE_LACP_TIMEOUT)) port->sm_periodic_state = AD_SLOW_PERIODIC; // next state - } break; case AD_SLOW_PERIODIC: if ((port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { @@ -1237,11 +1234,11 @@ static void ad_periodic_machine(struct port *port) port->sm_periodic_state = AD_FAST_PERIODIC; // next state break; case AD_PERIODIC_TX: - if (!(port->partner_oper.port_state & AD_STATE_LACP_TIMEOUT)) { + if (!(port->partner_oper.port_state + & AD_STATE_LACP_TIMEOUT)) port->sm_periodic_state = AD_SLOW_PERIODIC; // next state - } else { + else port->sm_periodic_state = AD_FAST_PERIODIC; // next state - } break; default: //to silence the compiler break; @@ -1287,35 +1284,37 @@ static void ad_port_selection_logic(struct port *port) int found = 0; // if the port is already Selected, do nothing - if (port->sm_vars & AD_PORT_SELECTED) { + if (port->sm_vars & AD_PORT_SELECTED) return; - } // if the port is connected to other aggregator, detach it if (port->aggregator) { // detach the port from its former aggregator - temp_aggregator=port->aggregator; - for (curr_port=temp_aggregator->lag_ports; curr_port; last_port=curr_port, curr_port=curr_port->next_port_in_aggregator) { + temp_aggregator = port->aggregator; + for (curr_port = temp_aggregator->lag_ports; curr_port; + last_port = curr_port, + curr_port = curr_port->next_port_in_aggregator) { if (curr_port == port) { temp_aggregator->num_of_ports--; if (!last_port) {// if it is the first port attached to the aggregator - temp_aggregator->lag_ports=port->next_port_in_aggregator; + temp_aggregator->lag_ports = + port->next_port_in_aggregator; } else {// not the first port attached to the aggregator - last_port->next_port_in_aggregator=port->next_port_in_aggregator; + last_port->next_port_in_aggregator = + port->next_port_in_aggregator; } // clear the port's relations to this aggregator port->aggregator = NULL; - port->next_port_in_aggregator=NULL; - port->actor_port_aggregator_identifier=0; + port->next_port_in_aggregator = NULL; + port->actor_port_aggregator_identifier = 0; pr_debug("Port %d left LAG %d\n", port->actor_port_number, temp_aggregator->aggregator_identifier); // if the aggregator is empty, clear its parameters, and set it ready to be attached - if (!temp_aggregator->lag_ports) { + if (!temp_aggregator->lag_ports) ad_clear_agg(temp_aggregator); - } break; } } @@ -1333,9 +1332,8 @@ static void ad_port_selection_logic(struct port *port) // keep a free aggregator for later use(if needed) if (!aggregator->lag_ports) { - if (!free_aggregator) { - free_aggregator=aggregator; - } + if (!free_aggregator) + free_aggregator = aggregator; continue; } // check if current aggregator suits us @@ -1350,10 +1348,11 @@ static void ad_port_selection_logic(struct port *port) ) { // attach to the founded aggregator port->aggregator = aggregator; - port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier; - port->next_port_in_aggregator=aggregator->lag_ports; + port->actor_port_aggregator_identifier = + port->aggregator->aggregator_identifier; + port->next_port_in_aggregator = aggregator->lag_ports; port->aggregator->num_of_ports++; - aggregator->lag_ports=port; + aggregator->lag_ports = port; pr_debug("Port %d joined LAG %d(existing LAG)\n", port->actor_port_number, port->aggregator->aggregator_identifier); @@ -1370,20 +1369,23 @@ static void ad_port_selection_logic(struct port *port) if (free_aggregator) { // assign port a new aggregator port->aggregator = free_aggregator; - port->actor_port_aggregator_identifier=port->aggregator->aggregator_identifier; + port->actor_port_aggregator_identifier = + port->aggregator->aggregator_identifier; // update the new aggregator's parameters // if port was responsed from the end-user - if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) {// if port is full duplex + if (port->actor_oper_port_key & AD_DUPLEX_KEY_BITS) + /* if port is full duplex */ port->aggregator->is_individual = false; - } else { + else port->aggregator->is_individual = true; - } port->aggregator->actor_admin_aggregator_key = port->actor_admin_port_key; port->aggregator->actor_oper_aggregator_key = port->actor_oper_port_key; - port->aggregator->partner_system=port->partner_oper.system; - port->aggregator->partner_system_priority = port->partner_oper.system_priority; + port->aggregator->partner_system = + port->partner_oper.system; + port->aggregator->partner_system_priority = + port->partner_oper.system_priority; port->aggregator->partner_oper_aggregator_key = port->partner_oper.key; port->aggregator->receive_state = 1; port->aggregator->transmit_state = 1; @@ -1704,9 +1706,8 @@ static void ad_initialize_port(struct port *port, int lacp_fast) port->actor_admin_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; port->actor_oper_port_state = AD_STATE_AGGREGATION | AD_STATE_LACP_ACTIVITY; - if (lacp_fast) { + if (lacp_fast) port->actor_oper_port_state |= AD_STATE_LACP_TIMEOUT; - } memcpy(&port->partner_admin, &tmpl, sizeof(tmpl)); memcpy(&port->partner_oper, &tmpl, sizeof(tmpl)); @@ -1785,13 +1786,16 @@ static void ad_marker_info_send(struct port *port) marker.requester_port = (((port->actor_port_number & 0xFF) << 8) |((u16)(port->actor_port_number & 0xFF00) >> 8)); marker.requester_system = port->actor_system; // convert requester_port(u32) to Big Endian - marker.requester_transaction_id = (((++port->transaction_id & 0xFF) << 24) |((port->transaction_id & 0xFF00) << 8) |((port->transaction_id & 0xFF0000) >> 8) |((port->transaction_id & 0xFF000000) >> 24)); + marker.requester_transaction_id = + (((++port->transaction_id & 0xFF) << 24) + | ((port->transaction_id & 0xFF00) << 8) + | ((port->transaction_id & 0xFF0000) >> 8) + | ((port->transaction_id & 0xFF000000) >> 24)); marker.pad = 0; marker.tlv_type_terminator = 0x00; marker.terminator_length = 0x00; - for (index=0; index<90; index++) { - marker.reserved_90[index]=0; - } + for (index = 0; index < 90; index++) + marker.reserved_90[index] = 0; // send the marker information if (ad_marker_send(port, &marker) >= 0) { @@ -1816,7 +1820,7 @@ static void ad_marker_info_received(struct bond_marker *marker_info, //marker = *marker_info; memcpy(&marker, marker_info, sizeof(struct bond_marker)); // change the marker subtype to marker response - marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE; + marker.tlv_type = AD_MARKER_RESPONSE_SUBTYPE; // send the marker response if (ad_marker_send(port, &marker) >= 0) { @@ -1837,8 +1841,8 @@ static void ad_marker_info_received(struct bond_marker *marker_info, static void ad_marker_response_received(struct bond_marker *marker, struct port *port) { - marker=NULL; // just to satisfy the compiler - port=NULL; // just to satisfy the compiler + marker = NULL; /* just to satisfy the compiler */ + port = NULL; /* just to satisfy the compiler */ // DO NOTHING, SINCE WE DECIDED NOT TO IMPLEMENT THIS FEATURE FOR NOW } @@ -1932,9 +1936,8 @@ int bond_3ad_bind_slave(struct slave *slave) port->actor_admin_port_key |= (__get_link_speed(port) << 1); port->actor_oper_port_key = port->actor_admin_port_key; // if the port is not full duplex, then the port should be not lacp Enabled - if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) { + if (!(port->actor_oper_port_key & AD_DUPLEX_KEY_BITS)) port->sm_vars &= ~AD_PORT_LACP_ENABLED; - } // actor system is the bond's system port->actor_system = BOND_AD_INFO(bond).system.sys_mac_addr; // tx timer(to verify that no more than MAX_TX_IN_SECOND lacpdu's are sent in one second) @@ -2006,9 +2009,10 @@ void bond_3ad_unbind_slave(struct slave *slave) new_aggregator = __get_first_agg(port); for (; new_aggregator; new_aggregator = __get_next_agg(new_aggregator)) { // if the new aggregator is empty, or it is connected to our port only - if (!new_aggregator->lag_ports || ((new_aggregator->lag_ports == port) && !new_aggregator->lag_ports->next_port_in_aggregator)) { + if (!new_aggregator->lag_ports + || ((new_aggregator->lag_ports == port) + && !new_aggregator->lag_ports->next_port_in_aggregator)) break; - } } // if new aggregator found, copy the aggregator's parameters // and connect the related lag_ports to the new aggregator @@ -2037,17 +2041,17 @@ void bond_3ad_unbind_slave(struct slave *slave) new_aggregator->num_of_ports = aggregator->num_of_ports; // update the information that is written on the ports about the aggregator - for (temp_port=aggregator->lag_ports; temp_port; temp_port=temp_port->next_port_in_aggregator) { - temp_port->aggregator=new_aggregator; + for (temp_port = aggregator->lag_ports; temp_port; + temp_port = temp_port->next_port_in_aggregator) { + temp_port->aggregator = new_aggregator; temp_port->actor_port_aggregator_identifier = new_aggregator->aggregator_identifier; } // clear the aggregator ad_clear_agg(aggregator); - if (select_new_active_agg) { + if (select_new_active_agg) ad_agg_selection_logic(__get_first_agg(port)); - } } else { pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", slave->dev->master->name); @@ -2071,15 +2075,16 @@ void bond_3ad_unbind_slave(struct slave *slave) for (; temp_aggregator; temp_aggregator = __get_next_agg(temp_aggregator)) { prev_port = NULL; // search the port in the aggregator's related ports - for (temp_port=temp_aggregator->lag_ports; temp_port; prev_port=temp_port, temp_port=temp_port->next_port_in_aggregator) { + for (temp_port = temp_aggregator->lag_ports; temp_port; + prev_port = temp_port, + temp_port = temp_port->next_port_in_aggregator) { if (temp_port == port) { // the aggregator found - detach the port from this aggregator - if (prev_port) { + if (prev_port) prev_port->next_port_in_aggregator = temp_port->next_port_in_aggregator; - } else { + else temp_aggregator->lag_ports = temp_port->next_port_in_aggregator; - } temp_aggregator->num_of_ports--; - if (temp_aggregator->num_of_ports==0) { + if (temp_aggregator->num_of_ports == 0) { select_new_active_agg = temp_aggregator->is_active; // clear the aggregator ad_clear_agg(temp_aggregator); @@ -2094,7 +2099,7 @@ void bond_3ad_unbind_slave(struct slave *slave) } } } - port->slave=NULL; + port->slave = NULL; } /** @@ -2119,14 +2124,12 @@ void bond_3ad_state_machine_handler(struct work_struct *work) read_lock(&bond->lock); - if (bond->kill_timers) { + if (bond->kill_timers) goto out; - } //check if there are any slaves - if (bond->slave_cnt == 0) { + if (bond->slave_cnt == 0) goto re_arm; - } // check if agg_select_timer timer after initialize is timed out if (BOND_AD_INFO(bond).agg_select_timer && !(--BOND_AD_INFO(bond).agg_select_timer)) { @@ -2159,9 +2162,8 @@ void bond_3ad_state_machine_handler(struct work_struct *work) ad_tx_machine(port); // turn off the BEGIN bit, since we already handled it - if (port->sm_vars & AD_PORT_BEGIN) { + if (port->sm_vars & AD_PORT_BEGIN) port->sm_vars &= ~AD_PORT_BEGIN; - } } re_arm: @@ -2245,7 +2247,8 @@ void bond_3ad_adapter_speed_changed(struct slave *slave) } port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; - port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1); + port->actor_oper_port_key = port->actor_admin_port_key |= + (__get_link_speed(port) << 1); pr_debug("Port %d changed speed\n", port->actor_port_number); // there is no need to reselect a new aggregator, just signal the // state machines to reinitialize @@ -2262,7 +2265,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) { struct port *port; - port=&(SLAVE_AD_INFO(slave).port); + port = &(SLAVE_AD_INFO(slave).port); // if slave is null, the whole port is not initialized if (!port->slave) { @@ -2272,7 +2275,8 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) } port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; - port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port); + port->actor_oper_port_key = port->actor_admin_port_key |= + __get_duplex(port); pr_debug("Port %d changed duplex\n", port->actor_port_number); // there is no need to reselect a new aggregator, just signal the // state machines to reinitialize @@ -2304,14 +2308,17 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) if (link == BOND_LINK_UP) { port->is_enabled = true; port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; - port->actor_oper_port_key=port->actor_admin_port_key |= __get_duplex(port); + port->actor_oper_port_key = port->actor_admin_port_key |= + __get_duplex(port); port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS; - port->actor_oper_port_key=port->actor_admin_port_key |= (__get_link_speed(port) << 1); + port->actor_oper_port_key = port->actor_admin_port_key |= + (__get_link_speed(port) << 1); } else { /* link has failed */ port->is_enabled = false; port->actor_admin_port_key &= ~AD_DUPLEX_KEY_BITS; - port->actor_oper_port_key= (port->actor_admin_port_key &= ~AD_SPEED_KEY_BITS); + port->actor_oper_port_key = (port->actor_admin_port_key &= + ~AD_SPEED_KEY_BITS); } //BOND_PRINT_DBG(("Port %d changed link status to %s", port->actor_port_number, ((link == BOND_LINK_UP)?"UP":"DOWN"))); // there is no need to reselect a new aggregator, just signal the @@ -2394,9 +2401,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) */ read_lock(&bond->lock); - if (!BOND_IS_OK(bond)) { + if (!BOND_IS_OK(bond)) goto out; - } if (bond_3ad_get_active_agg_info(bond, &ad_info)) { pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n", @@ -2420,9 +2426,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) if (agg && (agg->aggregator_identifier == agg_id)) { slave_agg_no--; - if (slave_agg_no < 0) { + if (slave_agg_no < 0) break; - } } } @@ -2438,9 +2443,8 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) int slave_agg_id = 0; struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; - if (agg) { + if (agg) slave_agg_id = agg->aggregator_identifier; - } if (SLAVE_IS_OK(slave) && agg && (slave_agg_id == agg_id)) { res = bond_dev_queue_xmit(bond, skb, slave->dev); diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index e953c6ad6e6d1ea3fd7e22fddc8f5f27ba1f8b38..beb3b7cecd52aff51d49d6e2a6cc35ea19e911f5 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -76,6 +76,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +110,7 @@ static char *arp_validate; static char *fail_over_mac; static int all_slaves_active = 0; static struct bond_params bonding_defaults; +static int resend_igmp = BOND_DEFAULT_RESEND_IGMP; module_param(max_bonds, int, 0); MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); @@ -163,9 +165,15 @@ module_param(all_slaves_active, int, 0); MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface" "by setting active flag for all slaves. " "0 for never (default), 1 for always."); +module_param(resend_igmp, int, 0); +MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link failure"); /*----------------------------- Global variables ----------------------------*/ +#ifdef CONFIG_NET_POLL_CONTROLLER +cpumask_var_t netpoll_block_tx; +#endif + static const char * const version = DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n"; @@ -176,9 +184,6 @@ static int arp_ip_count; static int bond_mode = BOND_MODE_ROUNDROBIN; static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2; static int lacp_fast; -#ifdef CONFIG_NET_POLL_CONTROLLER -static int disable_netpoll = 1; -#endif const struct bond_parm_tbl bond_lacp_tbl[] = { { "slow", AD_LACP_SLOW}, @@ -307,6 +312,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) pr_debug("bond: %s, vlan id %d\n", bond->dev->name, vlan_id); + block_netpoll_tx(); write_lock_bh(&bond->lock); list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { @@ -341,6 +347,7 @@ static int bond_del_vlan(struct bonding *bond, unsigned short vlan_id) out: write_unlock_bh(&bond->lock); + unblock_netpoll_tx(); return res; } @@ -446,11 +453,9 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { struct netpoll *np = bond->dev->npinfo->netpoll; slave_dev->npinfo = bond->dev->npinfo; - np->real_dev = np->dev = skb->dev; slave_dev->priv_flags |= IFF_IN_NETPOLL; - netpoll_send_skb(np, skb); + netpoll_send_skb_on_dev(np, skb, slave_dev); slave_dev->priv_flags &= ~IFF_IN_NETPOLL; - np->dev = bond->dev; } else #endif dev_queue_xmit(skb); @@ -865,18 +870,13 @@ static void bond_mc_del(struct bonding *bond, void *addr) } -/* - * Retrieve the list of registered multicast addresses for the bonding - * device and retransmit an IGMP JOIN request to the current active - * slave. - */ -static void bond_resend_igmp_join_requests(struct bonding *bond) +static void __bond_resend_igmp_join_requests(struct net_device *dev) { struct in_device *in_dev; struct ip_mc_list *im; rcu_read_lock(); - in_dev = __in_dev_get_rcu(bond->dev); + in_dev = __in_dev_get_rcu(dev); if (in_dev) { for (im = in_dev->mc_list; im; im = im->next) ip_mc_rejoin_group(im); @@ -885,6 +885,44 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) rcu_read_unlock(); } +/* + * Retrieve the list of registered multicast addresses for the bonding + * device and retransmit an IGMP JOIN request to the current active + * slave. + */ +static void bond_resend_igmp_join_requests(struct bonding *bond) +{ + struct net_device *vlan_dev; + struct vlan_entry *vlan; + + read_lock(&bond->lock); + + /* rejoin all groups on bond device */ + __bond_resend_igmp_join_requests(bond->dev); + + /* rejoin all groups on vlan devices */ + if (bond->vlgrp) { + list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { + vlan_dev = vlan_group_get_device(bond->vlgrp, + vlan->vlan_id); + if (vlan_dev) + __bond_resend_igmp_join_requests(vlan_dev); + } + } + + if (--bond->igmp_retrans > 0) + queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); + + read_unlock(&bond->lock); +} + +static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) +{ + struct bonding *bond = container_of(work, struct bonding, + mcast_work.work); + bond_resend_igmp_join_requests(bond); +} + /* * flush all members of flush->mc_list from device dev->mc_list */ @@ -944,7 +982,6 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, netdev_for_each_mc_addr(ha, bond->dev) dev_mc_add(new_active->dev, ha->addr); - bond_resend_igmp_join_requests(bond); } } @@ -1180,9 +1217,12 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) } } - /* resend IGMP joins since all were sent on curr_active_slave */ - if (bond->params.mode == BOND_MODE_ROUNDROBIN) { - bond_resend_igmp_join_requests(bond); + /* resend IGMP joins since active slave has changed or + * all were sent on curr_active_slave */ + if ((USES_PRIMARY(bond->params.mode) && new_active) || + bond->params.mode == BOND_MODE_ROUNDROBIN) { + bond->igmp_retrans = bond->params.resend_igmp; + queue_delayed_work(bond->wq, &bond->mcast_work, 0); } } @@ -1294,9 +1334,14 @@ static bool slaves_support_netpoll(struct net_device *bond_dev) static void bond_poll_controller(struct net_device *bond_dev) { - struct net_device *dev = bond_dev->npinfo->netpoll->real_dev; - if (dev != bond_dev) - netpoll_poll_dev(dev); + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave; + int i; + + bond_for_each_slave(bond, slave, i) { + if (slave->dev && IS_UP(slave->dev)) + netpoll_poll_dev(slave->dev); + } } static void bond_netpoll_cleanup(struct net_device *bond_dev) @@ -1763,23 +1808,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) bond_set_carrier(bond); #ifdef CONFIG_NET_POLL_CONTROLLER - /* - * Netpoll and bonding is broken, make sure it is not initialized - * until it is fixed. - */ - if (disable_netpoll) { + if (slaves_support_netpoll(bond_dev)) { + bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; + if (bond_dev->npinfo) + slave_dev->npinfo = bond_dev->npinfo; + } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; - } else { - if (slaves_support_netpoll(bond_dev)) { - bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; - if (bond_dev->npinfo) - slave_dev->npinfo = bond_dev->npinfo; - } else if (!(bond_dev->priv_flags & IFF_DISABLE_NETPOLL)) { - bond_dev->priv_flags |= IFF_DISABLE_NETPOLL; - pr_info("New slave device %s does not support netpoll\n", - slave_dev->name); - pr_info("Disabling netpoll support for %s\n", bond_dev->name); - } + pr_info("New slave device %s does not support netpoll\n", + slave_dev->name); + pr_info("Disabling netpoll support for %s\n", bond_dev->name); } #endif read_unlock(&bond->lock); @@ -1851,6 +1888,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) return -EINVAL; } + block_netpoll_tx(); netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE); write_lock_bh(&bond->lock); @@ -1860,6 +1898,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) pr_info("%s: %s not enslaved\n", bond_dev->name, slave_dev->name); write_unlock_bh(&bond->lock); + unblock_netpoll_tx(); return -EINVAL; } @@ -1953,6 +1992,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) } write_unlock_bh(&bond->lock); + unblock_netpoll_tx(); /* must do this from outside any spinlocks */ bond_destroy_slave_symlinks(bond_dev, slave_dev); @@ -1983,10 +2023,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) #ifdef CONFIG_NET_POLL_CONTROLLER read_lock_bh(&bond->lock); - /* Make sure netpoll over stays disabled until fixed. */ - if (!disable_netpoll) - if (slaves_support_netpoll(bond_dev)) - bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; + if (slaves_support_netpoll(bond_dev)) + bond_dev->priv_flags &= ~IFF_DISABLE_NETPOLL; read_unlock_bh(&bond->lock); if (slave_dev->netdev_ops->ndo_netpoll_cleanup) slave_dev->netdev_ops->ndo_netpoll_cleanup(slave_dev); @@ -2019,8 +2057,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) * First release a slave and than destroy the bond if no more slaves are left. * Must be under rtnl_lock when this function is called. */ -int bond_release_and_destroy(struct net_device *bond_dev, - struct net_device *slave_dev) +static int bond_release_and_destroy(struct net_device *bond_dev, + struct net_device *slave_dev) { struct bonding *bond = netdev_priv(bond_dev); int ret; @@ -2142,7 +2180,6 @@ static int bond_release_all(struct net_device *bond_dev) out: write_unlock_bh(&bond->lock); - return 0; } @@ -2191,9 +2228,11 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi (old_active) && (new_active->link == BOND_LINK_UP) && IS_UP(new_active->dev)) { + block_netpoll_tx(); write_lock_bh(&bond->curr_slave_lock); bond_change_active_slave(bond, new_active); write_unlock_bh(&bond->curr_slave_lock); + unblock_netpoll_tx(); } else res = -EINVAL; @@ -2368,8 +2407,11 @@ static void bond_miimon_commit(struct bonding *bond) slave->state = BOND_STATE_BACKUP; } - pr_info("%s: link status definitely up for interface %s.\n", - bond->dev->name, slave->dev->name); + bond_update_speed_duplex(slave); + + pr_info("%s: link status definitely up for interface %s, %d Mbps %s duplex.\n", + bond->dev->name, slave->dev->name, + slave->speed, slave->duplex ? "full" : "half"); /* notify ad that the link status has changed */ if (bond->params.mode == BOND_MODE_8023AD) @@ -2422,9 +2464,11 @@ static void bond_miimon_commit(struct bonding *bond) do_failover: ASSERT_RTNL(); + block_netpoll_tx(); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); + unblock_netpoll_tx(); } bond_set_carrier(bond); @@ -2867,11 +2911,13 @@ void bond_loadbalance_arp_mon(struct work_struct *work) } if (do_failover) { + block_netpoll_tx(); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); + unblock_netpoll_tx(); } re_arm: @@ -3030,9 +3076,11 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks) do_failover: ASSERT_RTNL(); + block_netpoll_tx(); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); + unblock_netpoll_tx(); } bond_set_carrier(bond); @@ -3312,6 +3360,8 @@ static void bond_info_show_slave(struct seq_file *seq, seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); seq_printf(seq, "MII Status: %s\n", (slave->link == BOND_LINK_UP) ? "up" : "down"); + seq_printf(seq, "Speed: %d Mbps\n", slave->speed); + seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half"); seq_printf(seq, "Link Failure Count: %u\n", slave->link_failure_count); @@ -3744,6 +3794,8 @@ static int bond_open(struct net_device *bond_dev) bond->kill_timers = 0; + INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); + if (bond_is_lb(bond)) { /* bond_alb_initialize must be called before the timer * is started. @@ -3828,6 +3880,8 @@ static int bond_close(struct net_device *bond_dev) break; } + if (delayed_work_pending(&bond->mcast_work)) + cancel_delayed_work(&bond->mcast_work); if (bond_is_lb(bond)) { /* Must be called only after all @@ -4514,6 +4568,13 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bonding *bond = netdev_priv(dev); + /* + * If we risk deadlock from transmitting this in the + * netpoll path, tell netpoll to queue the frame for later tx + */ + if (is_netpoll_tx_blocked(dev)) + return NETDEV_TX_BUSY; + if (TX_QUEUE_OVERRIDE(bond->params.mode)) { if (!bond_slave_override(bond, skb)) return NETDEV_TX_OK; @@ -4678,6 +4739,10 @@ static void bond_setup(struct net_device *bond_dev) NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER); + /* By default, we enable GRO on bonding devices. + * Actual support requires lowlevel drivers are GRO ready. + */ + bond_dev->features |= NETIF_F_GRO; } static void bond_work_cancel_all(struct bonding *bond) @@ -4699,6 +4764,9 @@ static void bond_work_cancel_all(struct bonding *bond) if (bond->params.mode == BOND_MODE_8023AD && delayed_work_pending(&bond->ad_work)) cancel_delayed_work(&bond->ad_work); + + if (delayed_work_pending(&bond->mcast_work)) + cancel_delayed_work(&bond->mcast_work); } /* @@ -4891,6 +4959,13 @@ static int bond_check_params(struct bond_params *params) all_slaves_active = 0; } + if (resend_igmp < 0 || resend_igmp > 255) { + pr_warning("Warning: resend_igmp (%d) should be between " + "0 and 255, resetting to %d\n", + resend_igmp, BOND_DEFAULT_RESEND_IGMP); + resend_igmp = BOND_DEFAULT_RESEND_IGMP; + } + /* reset values for TLB/ALB */ if ((bond_mode == BOND_MODE_TLB) || (bond_mode == BOND_MODE_ALB)) { @@ -5063,6 +5138,7 @@ static int bond_check_params(struct bond_params *params) params->fail_over_mac = fail_over_mac_value; params->tx_queues = tx_queues; params->all_slaves_active = all_slaves_active; + params->resend_igmp = resend_igmp; if (primary) { strncpy(params->primary, primary, IFNAMSIZ); @@ -5221,6 +5297,13 @@ static int __init bonding_init(void) if (res) goto out; +#ifdef CONFIG_NET_POLL_CONTROLLER + if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { + res = -ENOMEM; + goto out; + } +#endif + res = register_pernet_subsys(&bond_net_ops); if (res) goto out; @@ -5239,6 +5322,7 @@ static int __init bonding_init(void) if (res) goto err; + register_netdevice_notifier(&bond_netdev_notifier); register_inetaddr_notifier(&bond_inetaddr_notifier); bond_register_ipv6_notifier(); @@ -5248,6 +5332,9 @@ static int __init bonding_init(void) rtnl_link_unregister(&bond_link_ops); err_link: unregister_pernet_subsys(&bond_net_ops); +#ifdef CONFIG_NET_POLL_CONTROLLER + free_cpumask_var(netpoll_block_tx); +#endif goto out; } @@ -5262,6 +5349,10 @@ static void __exit bonding_exit(void) rtnl_link_unregister(&bond_link_ops); unregister_pernet_subsys(&bond_net_ops); + +#ifdef CONFIG_NET_POLL_CONTROLLER + free_cpumask_var(netpoll_block_tx); +#endif } module_init(bonding_init); diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index c311aed9bd022c2870b33fdc8c88a953d6cceb93..8fd0174c5380499f5a87178ca2a6024c4cc124e9 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c @@ -1066,6 +1066,7 @@ static ssize_t bonding_store_primary(struct device *d, if (!rtnl_trylock()) return restart_syscall(); + block_netpoll_tx(); read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); @@ -1101,6 +1102,7 @@ static ssize_t bonding_store_primary(struct device *d, out: write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); + unblock_netpoll_tx(); rtnl_unlock(); return count; @@ -1146,11 +1148,13 @@ static ssize_t bonding_store_primary_reselect(struct device *d, bond->dev->name, pri_reselect_tbl[new_value].modename, new_value); + block_netpoll_tx(); read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); bond_select_active_slave(bond); write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); + unblock_netpoll_tx(); out: rtnl_unlock(); return ret; @@ -1232,6 +1236,8 @@ static ssize_t bonding_store_active_slave(struct device *d, if (!rtnl_trylock()) return restart_syscall(); + + block_netpoll_tx(); read_lock(&bond->lock); write_lock_bh(&bond->curr_slave_lock); @@ -1288,6 +1294,8 @@ static ssize_t bonding_store_active_slave(struct device *d, out: write_unlock_bh(&bond->curr_slave_lock); read_unlock(&bond->lock); + unblock_netpoll_tx(); + rtnl_unlock(); return count; @@ -1592,6 +1600,49 @@ static ssize_t bonding_store_slaves_active(struct device *d, static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, bonding_show_slaves_active, bonding_store_slaves_active); +/* + * Show and set the number of IGMP membership reports to send on link failure + */ +static ssize_t bonding_show_resend_igmp(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct bonding *bond = to_bond(d); + + return sprintf(buf, "%d\n", bond->params.resend_igmp); +} + +static ssize_t bonding_store_resend_igmp(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int new_value, ret = count; + struct bonding *bond = to_bond(d); + + if (sscanf(buf, "%d", &new_value) != 1) { + pr_err("%s: no resend_igmp value specified.\n", + bond->dev->name); + ret = -EINVAL; + goto out; + } + + if (new_value < 0) { + pr_err("%s: Invalid resend_igmp value %d not in range 0-255; rejected.\n", + bond->dev->name, new_value); + ret = -EINVAL; + goto out; + } + + pr_info("%s: Setting resend_igmp to %d.\n", + bond->dev->name, new_value); + bond->params.resend_igmp = new_value; +out: + return ret; +} + +static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR, + bonding_show_resend_igmp, bonding_store_resend_igmp); + static struct attribute *per_bond_attrs[] = { &dev_attr_slaves.attr, &dev_attr_mode.attr, @@ -1619,6 +1670,7 @@ static struct attribute *per_bond_attrs[] = { &dev_attr_ad_partner_mac.attr, &dev_attr_queue_id.attr, &dev_attr_all_slaves_active.attr, + &dev_attr_resend_igmp.attr, NULL, }; diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index c6fdd851579a77c953d259de7611c4298fec824f..4eedb12df6caf2e4676cbe11e2134e97ec01def1 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "bond_3ad.h" #include "bond_alb.h" @@ -117,6 +118,35 @@ bond_for_each_slave_from(bond, pos, cnt, (bond)->first_slave) +#ifdef CONFIG_NET_POLL_CONTROLLER +extern cpumask_var_t netpoll_block_tx; + +static inline void block_netpoll_tx(void) +{ + preempt_disable(); + BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(), + netpoll_block_tx)); +} + +static inline void unblock_netpoll_tx(void) +{ + BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(), + netpoll_block_tx)); + preempt_enable(); +} + +static inline int is_netpoll_tx_blocked(struct net_device *dev) +{ + if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) + return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx); + return 0; +} +#else +#define block_netpoll_tx() +#define unblock_netpoll_tx() +#define is_netpoll_tx_blocked(dev) (0) +#endif + struct bond_params { int mode; int xmit_policy; @@ -136,6 +166,7 @@ struct bond_params { __be32 arp_targets[BOND_MAX_ARP_TARGETS]; int tx_queues; int all_slaves_active; + int resend_igmp; }; struct bond_parm_tbl { @@ -202,6 +233,7 @@ struct bonding { s8 send_grat_arp; s8 send_unsol_na; s8 setup_by_slave; + s8 igmp_retrans; #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry; char proc_file_name[IFNAMSIZ]; @@ -223,6 +255,7 @@ struct bonding { struct delayed_work arp_work; struct delayed_work alb_work; struct delayed_work ad_work; + struct delayed_work mcast_work; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct in6_addr master_ipv6; #endif @@ -331,7 +364,6 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond) struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr); int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev); int bond_create(struct net *net, const char *name); -int bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev); int bond_create_sysfs(void); void bond_destroy_sysfs(void); void bond_prepare_sysfs_group(struct bonding *bond); diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c index 88edb986691a5c2f2d847096986a80c31dd39983..6e99d80ec409be994fb1a9d41d5a8a5e5b14c33c 100644 --- a/drivers/net/bsd_comp.c +++ b/drivers/net/bsd_comp.c @@ -429,7 +429,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) if (!db->lens) { bsd_free (db); - return (NULL); + return NULL; } } /* diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index b11a0cb5ed81eb9ffabaa067dcdc544edabadc22..6aadc3e32bd5c8bc31c1d5c231e1e9ff99ae9188 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -38,14 +38,14 @@ * static struct mcp251x_platform_data mcp251x_info = { * .oscillator_frequency = 8000000, * .board_specific_setup = &mcp251x_setup, - * .model = CAN_MCP251X_MCP2510, * .power_enable = mcp251x_power_enable, * .transceiver_enable = NULL, * }; * * static struct spi_board_info spi_board_info[] = { * { - * .modalias = "mcp251x", + * .modalias = "mcp2510", + * // or "mcp2515" depending on your controller * .platform_data = &mcp251x_info, * .irq = IRQ_EINT13, * .max_speed_hz = 2*1000*1000, @@ -125,6 +125,9 @@ # define CANINTF_TX0IF 0x04 # define CANINTF_RX1IF 0x02 # define CANINTF_RX0IF 0x01 +# define CANINTF_RX (CANINTF_RX0IF | CANINTF_RX1IF) +# define CANINTF_TX (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF) +# define CANINTF_ERR (CANINTF_ERRIF) #define EFLG 0x2d # define EFLG_EWARN 0x01 # define EFLG_RXWAR 0x02 @@ -222,10 +225,16 @@ static struct can_bittiming_const mcp251x_bittiming_const = { .brp_inc = 1, }; +enum mcp251x_model { + CAN_MCP251X_MCP2510 = 0x2510, + CAN_MCP251X_MCP2515 = 0x2515, +}; + struct mcp251x_priv { struct can_priv can; struct net_device *net; struct spi_device *spi; + enum mcp251x_model model; struct mutex mcp_lock; /* SPI device lock */ @@ -250,6 +259,16 @@ struct mcp251x_priv { int restart_tx; }; +#define MCP251X_IS(_model) \ +static inline int mcp251x_is_##_model(struct spi_device *spi) \ +{ \ + struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); \ + return priv->model == CAN_MCP251X_MCP##_model; \ +} + +MCP251X_IS(2510); +MCP251X_IS(2515); + static void mcp251x_clean(struct net_device *net) { struct mcp251x_priv *priv = netdev_priv(net); @@ -319,6 +338,20 @@ static u8 mcp251x_read_reg(struct spi_device *spi, uint8_t reg) return val; } +static void mcp251x_read_2regs(struct spi_device *spi, uint8_t reg, + uint8_t *v1, uint8_t *v2) +{ + struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); + + priv->spi_tx_buf[0] = INSTRUCTION_READ; + priv->spi_tx_buf[1] = reg; + + mcp251x_spi_trans(spi, 4); + + *v1 = priv->spi_rx_buf[2]; + *v2 = priv->spi_rx_buf[3]; +} + static void mcp251x_write_reg(struct spi_device *spi, u8 reg, uint8_t val) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); @@ -346,10 +379,9 @@ static void mcp251x_write_bits(struct spi_device *spi, u8 reg, static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, int len, int tx_buf_idx) { - struct mcp251x_platform_data *pdata = spi->dev.platform_data; struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); - if (pdata->model == CAN_MCP251X_MCP2510) { + if (mcp251x_is_2510(spi)) { int i; for (i = 1; i < TXBDAT_OFF + len; i++) @@ -392,9 +424,8 @@ static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, int buf_idx) { struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); - struct mcp251x_platform_data *pdata = spi->dev.platform_data; - if (pdata->model == CAN_MCP251X_MCP2510) { + if (mcp251x_is_2510(spi)) { int i, len; for (i = 1; i < RXBDAT_OFF; i++) @@ -451,7 +482,7 @@ static void mcp251x_hw_rx(struct spi_device *spi, int buf_idx) priv->net->stats.rx_packets++; priv->net->stats.rx_bytes += frame->can_dlc; - netif_rx(skb); + netif_rx_ni(skb); } static void mcp251x_hw_sleep(struct spi_device *spi) @@ -674,9 +705,9 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1) skb = alloc_can_err_skb(net, &frame); if (skb) { - frame->can_id = can_id; + frame->can_id |= can_id; frame->data[1] = data1; - netif_rx(skb); + netif_rx_ni(skb); } else { dev_err(&net->dev, "cannot allocate error skb\n"); @@ -754,24 +785,42 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) mutex_lock(&priv->mcp_lock); while (!priv->force_quit) { enum can_state new_state; - u8 intf = mcp251x_read_reg(spi, CANINTF); - u8 eflag; + u8 intf, eflag; + u8 clear_intf = 0; int can_id = 0, data1 = 0; + mcp251x_read_2regs(spi, CANINTF, &intf, &eflag); + + /* mask out flags we don't care about */ + intf &= CANINTF_RX | CANINTF_TX | CANINTF_ERR; + + /* receive buffer 0 */ if (intf & CANINTF_RX0IF) { mcp251x_hw_rx(spi, 0); - /* Free one buffer ASAP */ - mcp251x_write_bits(spi, CANINTF, intf & CANINTF_RX0IF, - 0x00); + /* + * Free one buffer ASAP + * (The MCP2515 does this automatically.) + */ + if (mcp251x_is_2510(spi)) + mcp251x_write_bits(spi, CANINTF, CANINTF_RX0IF, 0x00); } - if (intf & CANINTF_RX1IF) + /* receive buffer 1 */ + if (intf & CANINTF_RX1IF) { mcp251x_hw_rx(spi, 1); + /* the MCP2515 does this automatically */ + if (mcp251x_is_2510(spi)) + clear_intf |= CANINTF_RX1IF; + } - mcp251x_write_bits(spi, CANINTF, intf, 0x00); + /* any error or tx interrupt we need to clear? */ + if (intf & (CANINTF_ERR | CANINTF_TX)) + clear_intf |= intf & (CANINTF_ERR | CANINTF_TX); + if (clear_intf) + mcp251x_write_bits(spi, CANINTF, clear_intf, 0x00); - eflag = mcp251x_read_reg(spi, EFLG); - mcp251x_write_reg(spi, EFLG, 0x00); + if (eflag) + mcp251x_write_bits(spi, EFLG, eflag, 0x00); /* Update can state */ if (eflag & EFLG_TXBO) { @@ -816,10 +865,14 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) if (intf & CANINTF_ERRIF) { /* Handle overflow counters */ if (eflag & (EFLG_RX0OVR | EFLG_RX1OVR)) { - if (eflag & EFLG_RX0OVR) + if (eflag & EFLG_RX0OVR) { net->stats.rx_over_errors++; - if (eflag & EFLG_RX1OVR) + net->stats.rx_errors++; + } + if (eflag & EFLG_RX1OVR) { net->stats.rx_over_errors++; + net->stats.rx_errors++; + } can_id |= CAN_ERR_CRTL; data1 |= CAN_ERR_CRTL_RX_OVERFLOW; } @@ -838,7 +891,7 @@ static irqreturn_t mcp251x_can_ist(int irq, void *dev_id) if (intf == 0) break; - if (intf & (CANINTF_TX2IF | CANINTF_TX1IF | CANINTF_TX0IF)) { + if (intf & CANINTF_TX) { net->stats.tx_packets++; net->stats.tx_bytes += priv->tx_len - 1; if (priv->tx_len) { @@ -921,16 +974,12 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) struct net_device *net; struct mcp251x_priv *priv; struct mcp251x_platform_data *pdata = spi->dev.platform_data; - int model = spi_get_device_id(spi)->driver_data; int ret = -ENODEV; if (!pdata) /* Platform data is required for osc freq */ goto error_out; - if (model) - pdata->model = model; - /* Allocate can/net device */ net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX); if (!net) { @@ -947,6 +996,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi) priv->can.clock.freq = pdata->oscillator_frequency / 2; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY; + priv->model = spi_get_device_id(spi)->driver_data; priv->net = net; dev_set_drvdata(&spi->dev, priv); @@ -1120,8 +1170,7 @@ static int mcp251x_can_resume(struct spi_device *spi) #define mcp251x_can_resume NULL #endif -static struct spi_device_id mcp251x_id_table[] = { - { "mcp251x", 0 /* Use pdata.model */ }, +static const struct spi_device_id mcp251x_id_table[] = { { "mcp2510", CAN_MCP251X_MCP2510 }, { "mcp2515", CAN_MCP251X_MCP2515 }, { }, diff --git a/drivers/net/can/mscan/mpc5xxx_can.c b/drivers/net/can/mscan/mpc5xxx_can.c index b1bdc909090f7130ccf88cbb6e5257542623b9d2..312b9c8f4f3bdbcb5342b4aae732bde2a3307c70 100644 --- a/drivers/net/can/mscan/mpc5xxx_can.c +++ b/drivers/net/can/mscan/mpc5xxx_can.c @@ -143,12 +143,12 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, np_clock = of_find_matching_node(NULL, mpc512x_clock_ids); if (!np_clock) { dev_err(&ofdev->dev, "couldn't find clock node\n"); - return -ENODEV; + return 0; } clockctl = of_iomap(np_clock, 0); if (!clockctl) { dev_err(&ofdev->dev, "couldn't map clock registers\n"); - return 0; + goto exit_put; } /* Determine the MSCAN device index from the physical address */ @@ -233,9 +233,9 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, clocksrc == 1 ? "ref_clk" : "sys_clk", clockdiv); exit_unmap: - of_node_put(np_clock); iounmap(clockctl); - +exit_put: + of_node_put(np_clock); return freq; } #else /* !CONFIG_PPC_MPC512x */ diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index 28c88eeec757361fb2fa3db11a63b57c97b892fb..d6b6d6aa565a377f368d15ac4aef1faab23267b1 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -419,7 +419,7 @@ static u16 cas_phy_read(struct cas *cp, int reg) udelay(10); cmd = readl(cp->regs + REG_MIF_FRAME); if (cmd & MIF_FRAME_TURN_AROUND_LSB) - return (cmd & MIF_FRAME_DATA_MASK); + return cmd & MIF_FRAME_DATA_MASK; } return 0xFFFF; /* -1 */ } @@ -804,7 +804,7 @@ static int cas_reset_mii_phy(struct cas *cp) break; udelay(10); } - return (limit <= 0); + return limit <= 0; } static int cas_saturn_firmware_init(struct cas *cp) @@ -2149,7 +2149,7 @@ static int cas_rx_process_pkt(struct cas *cp, struct cas_rx_comp *rxc, skb->csum = csum_unfold(~csum); skb->ip_summed = CHECKSUM_COMPLETE; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); return len; } diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index f01cfdb995deaef8a04d74b5d997a8fb1e74b6dd..70221ca3268373cf35ad44254514256cb91105b9 100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c @@ -1388,7 +1388,7 @@ static void sge_rx(struct sge *sge, struct freelQ *fl, unsigned int len) ++st->rx_cso_good; skb->ip_summed = CHECKSUM_UNNECESSARY; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(adapter->vlan_grp && p->vlan_valid)) { st->vlan_xtract++; @@ -1551,7 +1551,7 @@ static inline int responses_pending(const struct adapter *adapter) const struct respQ *Q = &adapter->sge->respQ; const struct respQ_e *e = &Q->entries[Q->cidx]; - return (e->GenerationBit == Q->genbit); + return e->GenerationBit == Q->genbit; } /* @@ -1870,7 +1870,7 @@ netdev_tx_t t1_start_xmit(struct sk_buff *skb, struct net_device *dev) cpl->iff = dev->if_port; #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) - if (adapter->vlan_grp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { cpl->vlan_valid = 1; cpl->vlan = htons(vlan_tx_tag_get(skb)); st->vlan_insert++; diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c index 599d178df62ddd0e1289369802c04c18921a1583..63ebf76d2390858ec10f2bf77cfce1439a87ffc5 100644 --- a/drivers/net/chelsio/subr.c +++ b/drivers/net/chelsio/subr.c @@ -314,14 +314,12 @@ static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr, return 0; } -#if defined(CONFIG_CHELSIO_T1_1G) static const struct mdio_ops mi1_mdio_ops = { .init = mi1_mdio_init, .read = mi1_mdio_read, .write = mi1_mdio_write, .mode_support = MDIO_SUPPORTS_C22 }; -#endif #endif diff --git a/drivers/net/chelsio/vsc7326.c b/drivers/net/chelsio/vsc7326.c index c844111cffebfbf7cc11a1cb2cc6ef754e49fad7..106a590f0d9afae6dfff55b99ac83fc5bdc52369 100644 --- a/drivers/net/chelsio/vsc7326.c +++ b/drivers/net/chelsio/vsc7326.c @@ -255,7 +255,7 @@ static int bist_rd(adapter_t *adapter, int moduleid, int address) else if ((result & (1 << 8)) != 0x0) pr_err("bist read error: 0x%x\n", result); - return (result & 0xff); + return result & 0xff; } static int bist_wr(adapter_t *adapter, int moduleid, int address, int value) diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 09610323a948cab243d083c1a8435853b8893184..92bac19ad60ab0be5383b7566f48cc5dbbf2ab8e 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -60,6 +60,7 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(CNIC_MODULE_VERSION); static LIST_HEAD(cnic_dev_list); +static LIST_HEAD(cnic_udev_list); static DEFINE_RWLOCK(cnic_dev_lock); static DEFINE_MUTEX(cnic_lock); @@ -81,29 +82,34 @@ static struct cnic_ops cnic_bnx2x_ops = { .cnic_ctl = cnic_ctl, }; +static struct workqueue_struct *cnic_wq; + static void cnic_shutdown_rings(struct cnic_dev *); static void cnic_init_rings(struct cnic_dev *); static int cnic_cm_set_pg(struct cnic_sock *); static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) { - struct cnic_dev *dev = uinfo->priv; - struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = uinfo->priv; + struct cnic_dev *dev; if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (cp->uio_dev != -1) + if (udev->uio_dev != -1) return -EBUSY; rtnl_lock(); - if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) { + dev = udev->dev; + + if (!dev || !test_bit(CNIC_F_CNIC_UP, &dev->flags)) { rtnl_unlock(); return -ENODEV; } - cp->uio_dev = iminor(inode); + udev->uio_dev = iminor(inode); + cnic_shutdown_rings(dev); cnic_init_rings(dev); rtnl_unlock(); @@ -112,12 +118,9 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode) static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode) { - struct cnic_dev *dev = uinfo->priv; - struct cnic_local *cp = dev->cnic_priv; - - cnic_shutdown_rings(dev); + struct cnic_uio_dev *udev = uinfo->priv; - cp->uio_dev = -1; + udev->uio_dev = -1; return 0; } @@ -242,14 +245,14 @@ static int cnic_in_use(struct cnic_sock *csk) return test_bit(SK_F_INUSE, &csk->flags); } -static void cnic_kwq_completion(struct cnic_dev *dev, u32 count) +static void cnic_spq_completion(struct cnic_dev *dev, int cmd, u32 count) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; struct drv_ctl_info info; - info.cmd = DRV_CTL_COMPLETION_CMD; - info.data.comp.comp_count = count; + info.cmd = cmd; + info.data.credit.credit_count = count; ethdev->drv_ctl(dev->netdev, &info); } @@ -274,8 +277,9 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type, u16 len = 0; u32 msg_type = ISCSI_KEVENT_IF_DOWN; struct cnic_ulp_ops *ulp_ops; + struct cnic_uio_dev *udev = cp->udev; - if (cp->uio_dev == -1) + if (!udev || udev->uio_dev == -1) return -ENODEV; if (csk) { @@ -406,8 +410,7 @@ static void cnic_uio_stop(void) list_for_each_entry(dev, &cnic_dev_list, list) { struct cnic_local *cp = dev->cnic_priv; - if (cp->cnic_uinfo) - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); } read_unlock(&cnic_dev_lock); } @@ -768,31 +771,45 @@ static void cnic_free_context(struct cnic_dev *dev) } } -static void cnic_free_resc(struct cnic_dev *dev) +static void __cnic_free_uio(struct cnic_uio_dev *udev) { - struct cnic_local *cp = dev->cnic_priv; - int i = 0; + uio_unregister_device(&udev->cnic_uinfo); - if (cp->cnic_uinfo) { - while (cp->uio_dev != -1 && i < 15) { - msleep(100); - i++; - } - uio_unregister_device(cp->cnic_uinfo); - kfree(cp->cnic_uinfo); - cp->cnic_uinfo = NULL; + if (udev->l2_buf) { + dma_free_coherent(&udev->pdev->dev, udev->l2_buf_size, + udev->l2_buf, udev->l2_buf_map); + udev->l2_buf = NULL; } - if (cp->l2_buf) { - dma_free_coherent(&dev->pcidev->dev, cp->l2_buf_size, - cp->l2_buf, cp->l2_buf_map); - cp->l2_buf = NULL; + if (udev->l2_ring) { + dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size, + udev->l2_ring, udev->l2_ring_map); + udev->l2_ring = NULL; } - if (cp->l2_ring) { - dma_free_coherent(&dev->pcidev->dev, cp->l2_ring_size, - cp->l2_ring, cp->l2_ring_map); - cp->l2_ring = NULL; + pci_dev_put(udev->pdev); + kfree(udev); +} + +static void cnic_free_uio(struct cnic_uio_dev *udev) +{ + if (!udev) + return; + + write_lock(&cnic_dev_lock); + list_del_init(&udev->list); + write_unlock(&cnic_dev_lock); + __cnic_free_uio(udev); +} + +static void cnic_free_resc(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; + + if (udev) { + udev->dev = NULL; + cp->udev = NULL; } cnic_free_context(dev); @@ -894,37 +911,68 @@ static int cnic_alloc_kcq(struct cnic_dev *dev, struct kcq_info *info) return 0; } -static int cnic_alloc_l2_rings(struct cnic_dev *dev, int pages) +static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev; + + read_lock(&cnic_dev_lock); + list_for_each_entry(udev, &cnic_udev_list, list) { + if (udev->pdev == dev->pcidev) { + udev->dev = dev; + cp->udev = udev; + read_unlock(&cnic_dev_lock); + return 0; + } + } + read_unlock(&cnic_dev_lock); + + udev = kzalloc(sizeof(struct cnic_uio_dev), GFP_ATOMIC); + if (!udev) + return -ENOMEM; - cp->l2_ring_size = pages * BCM_PAGE_SIZE; - cp->l2_ring = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_ring_size, - &cp->l2_ring_map, - GFP_KERNEL | __GFP_COMP); - if (!cp->l2_ring) + udev->uio_dev = -1; + + udev->dev = dev; + udev->pdev = dev->pcidev; + udev->l2_ring_size = pages * BCM_PAGE_SIZE; + udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size, + &udev->l2_ring_map, + GFP_KERNEL | __GFP_COMP); + if (!udev->l2_ring) return -ENOMEM; - cp->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; - cp->l2_buf_size = PAGE_ALIGN(cp->l2_buf_size); - cp->l2_buf = dma_alloc_coherent(&dev->pcidev->dev, cp->l2_buf_size, - &cp->l2_buf_map, - GFP_KERNEL | __GFP_COMP); - if (!cp->l2_buf) + udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; + udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); + udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size, + &udev->l2_buf_map, + GFP_KERNEL | __GFP_COMP); + if (!udev->l2_buf) return -ENOMEM; + write_lock(&cnic_dev_lock); + list_add(&udev->list, &cnic_udev_list); + write_unlock(&cnic_dev_lock); + + pci_dev_get(udev->pdev); + + cp->udev = udev; + return 0; } -static int cnic_alloc_uio(struct cnic_dev *dev) { +static int cnic_init_uio(struct cnic_dev *dev) +{ struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; struct uio_info *uinfo; - int ret; + int ret = 0; - uinfo = kzalloc(sizeof(*uinfo), GFP_ATOMIC); - if (!uinfo) + if (!udev) return -ENOMEM; + uinfo = &udev->cnic_uinfo; + uinfo->mem[0].addr = dev->netdev->base_addr; uinfo->mem[0].internal_addr = dev->regview; uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start; @@ -932,7 +980,7 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen & - PAGE_MASK; + PAGE_MASK; if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) uinfo->mem[1].size = BNX2_SBLK_MSIX_ALIGN_SIZE * 9; else @@ -942,19 +990,19 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk & PAGE_MASK; - uinfo->mem[1].size = sizeof(struct host_def_status_block); + uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); uinfo->name = "bnx2x_cnic"; } uinfo->mem[1].memtype = UIO_MEM_LOGICAL; - uinfo->mem[2].addr = (unsigned long) cp->l2_ring; - uinfo->mem[2].size = cp->l2_ring_size; + uinfo->mem[2].addr = (unsigned long) udev->l2_ring; + uinfo->mem[2].size = udev->l2_ring_size; uinfo->mem[2].memtype = UIO_MEM_LOGICAL; - uinfo->mem[3].addr = (unsigned long) cp->l2_buf; - uinfo->mem[3].size = cp->l2_buf_size; + uinfo->mem[3].addr = (unsigned long) udev->l2_buf; + uinfo->mem[3].size = udev->l2_buf_size; uinfo->mem[3].memtype = UIO_MEM_LOGICAL; uinfo->version = CNIC_MODULE_VERSION; @@ -963,16 +1011,17 @@ static int cnic_alloc_uio(struct cnic_dev *dev) { uinfo->open = cnic_uio_open; uinfo->release = cnic_uio_close; - uinfo->priv = dev; + if (udev->uio_dev == -1) { + if (!uinfo->priv) { + uinfo->priv = udev; - ret = uio_register_device(&dev->pcidev->dev, uinfo); - if (ret) { - kfree(uinfo); - return ret; + ret = uio_register_device(&udev->pdev->dev, uinfo); + } + } else { + cnic_init_rings(dev); } - cp->cnic_uinfo = uinfo; - return 0; + return ret; } static int cnic_alloc_bnx2_resc(struct cnic_dev *dev) @@ -993,11 +1042,11 @@ static int cnic_alloc_bnx2_resc(struct cnic_dev *dev) if (ret) goto error; - ret = cnic_alloc_l2_rings(dev, 2); + ret = cnic_alloc_uio_rings(dev, 2); if (ret) goto error; - ret = cnic_alloc_uio(dev); + ret = cnic_init_uio(dev); if (ret) goto error; @@ -1022,13 +1071,13 @@ static int cnic_alloc_bnx2x_context(struct cnic_dev *dev) if (blks > cp->ethdev->ctx_tbl_len) return -ENOMEM; - cp->ctx_arr = kzalloc(blks * sizeof(struct cnic_ctx), GFP_KERNEL); + cp->ctx_arr = kcalloc(blks, sizeof(struct cnic_ctx), GFP_KERNEL); if (cp->ctx_arr == NULL) return -ENOMEM; cp->ctx_blks = blks; cp->ctx_blk_size = ctx_blk_size; - if (BNX2X_CHIP_IS_E1H(cp->chip_id)) + if (!BNX2X_CHIP_IS_57710(cp->chip_id)) cp->ctx_align = 0; else cp->ctx_align = ctx_blk_size; @@ -1063,6 +1112,8 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) int i, j, n, ret, pages; struct cnic_dma *kwq_16_dma = &cp->kwq_16_data_info; + cp->iro_arr = ethdev->iro_arr; + cp->max_cid_space = MAX_ISCSI_TBL_SZ; cp->iscsi_start_cid = start_cid; if (start_cid < BNX2X_ISCSI_START_CID) { @@ -1127,15 +1178,13 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->bnx2x_def_status_blk = cp->ethdev->irq_arr[1].status_blk; - memset(cp->status_blk.bnx2x, 0, sizeof(*cp->status_blk.bnx2x)); - cp->l2_rx_ring_size = 15; - ret = cnic_alloc_l2_rings(dev, 4); + ret = cnic_alloc_uio_rings(dev, 4); if (ret) goto error; - ret = cnic_alloc_uio(dev); + ret = cnic_init_uio(dev); if (ret) goto error; @@ -1209,9 +1258,9 @@ static int cnic_submit_kwqe_16(struct cnic_dev *dev, u32 cmd, u32 cid, kwqe.hdr.conn_and_cmd_data = cpu_to_le32(((cmd << SPE_HDR_CMD_ID_SHIFT) | - BNX2X_HW_CID(cid, cp->func))); + BNX2X_HW_CID(cp, cid))); kwqe.hdr.type = cpu_to_le16(type); - kwqe.hdr.reserved = 0; + kwqe.hdr.reserved1 = 0; kwqe.data.phy_address.lo = cpu_to_le32(l5_data->phy_address.lo); kwqe.data.phy_address.hi = cpu_to_le32(l5_data->phy_address.hi); @@ -1246,8 +1295,8 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) { struct cnic_local *cp = dev->cnic_priv; struct iscsi_kwqe_init1 *req1 = (struct iscsi_kwqe_init1 *) kwqe; - int func = cp->func, pages; - int hq_bds; + int hq_bds, pages; + u32 pfid = cp->pfid; cp->num_iscsi_tasks = req1->num_tasks_per_conn; cp->num_ccells = req1->num_ccells_per_conn; @@ -1264,60 +1313,60 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe) return 0; /* init Tstorm RAM */ - CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_RQ_SIZE_OFFSET(pfid), req1->rq_num_wqes); - CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_TSTRORM_INTMEM + TSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), PAGE_SIZE); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT); + TSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); CNIC_WR16(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), + TSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), req1->num_tasks_per_conn); /* init Ustorm RAM */ CNIC_WR16(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(func), + USTORM_ISCSI_RQ_BUFFER_SIZE_OFFSET(pfid), req1->rq_buffer_size); - CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), PAGE_SIZE); CNIC_WR8(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT); + USTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); CNIC_WR16(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), + USTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), req1->num_tasks_per_conn); - CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_RQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_RQ_SIZE_OFFSET(pfid), req1->rq_num_wqes); - CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_CQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_CQ_SIZE_OFFSET(pfid), req1->cq_num_wqes); - CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_R2TQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_USTRORM_INTMEM + USTORM_ISCSI_R2TQ_SIZE_OFFSET(pfid), cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS); /* init Xstorm RAM */ - CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), PAGE_SIZE); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT); + XSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); CNIC_WR16(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), + XSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), req1->num_tasks_per_conn); - CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_HQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_HQ_SIZE_OFFSET(pfid), hq_bds); - CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_SQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_SQ_SIZE_OFFSET(pfid), req1->num_tasks_per_conn); - CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_R2TQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_XSTRORM_INTMEM + XSTORM_ISCSI_R2TQ_SIZE_OFFSET(pfid), cp->num_iscsi_tasks * BNX2X_ISCSI_MAX_PENDING_R2TS); /* init Cstorm RAM */ - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_PAGE_SIZE_OFFSET(pfid), PAGE_SIZE); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(func), PAGE_SHIFT); + CSTORM_ISCSI_PAGE_SIZE_LOG_OFFSET(pfid), PAGE_SHIFT); CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(func), + CSTORM_ISCSI_NUM_OF_TASKS_OFFSET(pfid), req1->num_tasks_per_conn); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_CQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_CQ_SIZE_OFFSET(pfid), req1->cq_num_wqes); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_HQ_SIZE_OFFSET(func), + CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_HQ_SIZE_OFFSET(pfid), hq_bds); return 0; @@ -1327,7 +1376,7 @@ static int cnic_bnx2x_iscsi_init2(struct cnic_dev *dev, struct kwqe *kwqe) { struct iscsi_kwqe_init2 *req2 = (struct iscsi_kwqe_init2 *) kwqe; struct cnic_local *cp = dev->cnic_priv; - int func = cp->func; + u32 pfid = cp->pfid; struct iscsi_kcqe kcqe; struct kcqe *cqes[1]; @@ -1339,21 +1388,21 @@ static int cnic_bnx2x_iscsi_init2(struct cnic_dev *dev, struct kwqe *kwqe) } CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func), req2->error_bit_map[0]); + TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid), req2->error_bit_map[0]); CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_ERROR_BITMAP_OFFSET(func) + 4, + TSTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid) + 4, req2->error_bit_map[1]); CNIC_WR16(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn); + USTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfid), req2->max_cq_sqn); CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_ERROR_BITMAP_OFFSET(func), req2->error_bit_map[0]); + USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid), req2->error_bit_map[0]); CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_ERROR_BITMAP_OFFSET(func) + 4, + USTORM_ISCSI_ERROR_BITMAP_OFFSET(pfid) + 4, req2->error_bit_map[1]); CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(func), req2->max_cq_sqn); + CSTORM_ISCSI_CQ_SQN_SIZE_OFFSET(pfid), req2->max_cq_sqn); kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS; @@ -1461,7 +1510,7 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], struct cnic_context *ctx = &cp->ctx_tbl[req1->iscsi_conn_id]; struct cnic_iscsi *iscsi = ctx->proto.iscsi; u32 cid = ctx->cid; - u32 hw_cid = BNX2X_HW_CID(cid, cp->func); + u32 hw_cid = BNX2X_HW_CID(cp, cid); struct iscsi_context *ictx; struct regpair context_addr; int i, j, n = 2, n_max; @@ -1527,8 +1576,10 @@ static int cnic_setup_bnx2x_ctx(struct cnic_dev *dev, struct kwqe *wqes[], ictx->tstorm_st_context.tcp.cwnd = 0x5A8; ictx->tstorm_st_context.tcp.flags2 |= TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN; + ictx->tstorm_st_context.tcp.ooo_support_mode = + TCP_TSTORM_OOO_DROP_AND_PROC_ACK; - ictx->timers_context.flags |= ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG; + ictx->timers_context.flags |= TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG; ictx->ustorm_st_context.ring.rq.pbl_base.lo = req2->rq_page_table_addr_lo; @@ -1627,10 +1678,11 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], struct iscsi_kwqe_conn_offload1 *req1; struct iscsi_kwqe_conn_offload2 *req2; struct cnic_local *cp = dev->cnic_priv; + struct cnic_context *ctx; struct iscsi_kcqe kcqe; struct kcqe *cqes[1]; u32 l5_cid; - int ret; + int ret = 0; if (num < 2) { *work = num; @@ -1654,9 +1706,15 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], kcqe.iscsi_conn_id = l5_cid; kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAILURE; + ctx = &cp->ctx_tbl[l5_cid]; + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) { + kcqe.completion_status = + ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY; + goto done; + } + if (atomic_inc_return(&cp->iscsi_conn) > dev->max_iscsi_conn) { atomic_dec(&cp->iscsi_conn); - ret = 0; goto done; } ret = cnic_alloc_bnx2x_conn_resc(dev, l5_cid); @@ -1673,8 +1731,7 @@ static int cnic_bnx2x_iscsi_ofld1(struct cnic_dev *dev, struct kwqe *wqes[], } kcqe.completion_status = ISCSI_KCQE_COMPLETION_STATUS_SUCCESS; - kcqe.iscsi_conn_context_id = BNX2X_HW_CID(cp->ctx_tbl[l5_cid].cid, - cp->func); + kcqe.iscsi_conn_context_id = BNX2X_HW_CID(cp, cp->ctx_tbl[l5_cid].cid); done: cqes[0] = (struct kcqe *) &kcqe; @@ -1707,40 +1764,66 @@ static int cnic_bnx2x_iscsi_update(struct cnic_dev *dev, struct kwqe *kwqe) return ret; } +static int cnic_bnx2x_destroy_ramrod(struct cnic_dev *dev, u32 l5_cid) +{ + struct cnic_local *cp = dev->cnic_priv; + struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; + union l5cm_specific_data l5_data; + int ret; + u32 hw_cid, type; + + init_waitqueue_head(&ctx->waitq); + ctx->wait_cond = 0; + memset(&l5_data, 0, sizeof(l5_data)); + hw_cid = BNX2X_HW_CID(cp, ctx->cid); + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); + + ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, + hw_cid, type, &l5_data); + + if (ret == 0) + wait_event(ctx->waitq, ctx->wait_cond); + + return ret; +} + static int cnic_bnx2x_iscsi_destroy(struct cnic_dev *dev, struct kwqe *kwqe) { struct cnic_local *cp = dev->cnic_priv; struct iscsi_kwqe_conn_destroy *req = (struct iscsi_kwqe_conn_destroy *) kwqe; - union l5cm_specific_data l5_data; u32 l5_cid = req->reserved0; struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; int ret = 0; struct iscsi_kcqe kcqe; struct kcqe *cqes[1]; - if (!(ctx->ctx_flags & CTX_FL_OFFLD_START)) + if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) goto skip_cfc_delete; - while (!time_after(jiffies, ctx->timestamp + (2 * HZ))) - msleep(250); + if (!time_after(jiffies, ctx->timestamp + (2 * HZ))) { + unsigned long delta = ctx->timestamp + (2 * HZ) - jiffies; - init_waitqueue_head(&ctx->waitq); - ctx->wait_cond = 0; - memset(&l5_data, 0, sizeof(l5_data)); - ret = cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL, - req->context_id, - ETH_CONNECTION_TYPE | - (1 << SPE_HDR_COMMON_RAMROD_SHIFT), - &l5_data); - if (ret == 0) - wait_event(ctx->waitq, ctx->wait_cond); + if (delta > (2 * HZ)) + delta = 0; + + set_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags); + queue_delayed_work(cnic_wq, &cp->delete_task, delta); + goto destroy_reply; + } + + ret = cnic_bnx2x_destroy_ramrod(dev, l5_cid); skip_cfc_delete: cnic_free_bnx2x_conn_resc(dev, l5_cid); atomic_dec(&cp->iscsi_conn); + clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); +destroy_reply: memset(&kcqe, 0, sizeof(kcqe)); kcqe.op_code = ISCSI_KCQE_OPCODE_DESTROY_CONN; kcqe.iscsi_conn_id = l5_cid; @@ -1805,37 +1888,37 @@ static void cnic_init_storm_conn_bufs(struct cnic_dev *dev, static void cnic_init_bnx2x_mac(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - int func = CNIC_FUNC(cp); + u32 pfid = cp->pfid; u8 *mac = dev->mac_addr; CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(func), mac[0]); + XSTORM_ISCSI_LOCAL_MAC_ADDR0_OFFSET(pfid), mac[0]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(func), mac[1]); + XSTORM_ISCSI_LOCAL_MAC_ADDR1_OFFSET(pfid), mac[1]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(func), mac[2]); + XSTORM_ISCSI_LOCAL_MAC_ADDR2_OFFSET(pfid), mac[2]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(func), mac[3]); + XSTORM_ISCSI_LOCAL_MAC_ADDR3_OFFSET(pfid), mac[3]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(func), mac[4]); + XSTORM_ISCSI_LOCAL_MAC_ADDR4_OFFSET(pfid), mac[4]); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(func), mac[5]); + XSTORM_ISCSI_LOCAL_MAC_ADDR5_OFFSET(pfid), mac[5]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(func), mac[5]); + TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfid), mac[5]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(func) + 1, + TSTORM_ISCSI_TCP_VARS_LSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1, mac[4]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func), mac[3]); + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid), mac[3]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 1, + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 1, mac[2]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 2, + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 2, mac[1]); CNIC_WR8(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(func) + 3, + TSTORM_ISCSI_TCP_VARS_MSB_LOCAL_MAC_ADDR_OFFSET(pfid) + 3, mac[0]); } @@ -1851,10 +1934,10 @@ static void cnic_bnx2x_set_tcp_timestamp(struct cnic_dev *dev, int tcp_ts) } CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->func), xstorm_flags); + XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), xstorm_flags); CNIC_WR16(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->func), tstorm_flags); + TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), tstorm_flags); } static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[], @@ -1929,7 +2012,7 @@ static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[], cnic_init_storm_conn_bufs(dev, kwqe1, kwqe3, conn_buf); CNIC_WR16(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_VLAN_OFFSET(cp->func), csk->vlan_id); + XSTORM_ISCSI_LOCAL_VLAN_OFFSET(cp->pfid), csk->vlan_id); cnic_bnx2x_set_tcp_timestamp(dev, kwqe1->tcp_flags & L4_KWQ_CONNECT_REQ1_TIME_STAMP); @@ -1937,7 +2020,7 @@ static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[], ret = cnic_submit_kwqe_16(dev, L5CM_RAMROD_CMD_ID_TCP_CONNECT, kwqe1->cid, ISCSI_CONNECTION_TYPE, &l5_data); if (!ret) - ctx->ctx_flags |= CTX_FL_OFFLD_START; + set_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); return ret; } @@ -2063,7 +2146,7 @@ static int cnic_submit_bnx2x_kwqes(struct cnic_dev *dev, struct kwqe *wqes[], static void service_kcqes(struct cnic_dev *dev, int num_cqes) { struct cnic_local *cp = dev->cnic_priv; - int i, j; + int i, j, comp = 0; i = 0; j = 1; @@ -2074,7 +2157,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) u32 kcqe_layer = kcqe_op_flag & KCQE_FLAGS_LAYER_MASK; if (unlikely(kcqe_op_flag & KCQE_RAMROD_COMPLETION)) - cnic_kwq_completion(dev, 1); + comp++; while (j < num_cqes) { u32 next_op = cp->completed_kcq[i + j]->kcqe_op_flag; @@ -2083,7 +2166,7 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) break; if (unlikely(next_op & KCQE_RAMROD_COMPLETION)) - cnic_kwq_completion(dev, 1); + comp++; j++; } @@ -2113,6 +2196,8 @@ static void service_kcqes(struct cnic_dev *dev, int num_cqes) i += j; j = 1; } + if (unlikely(comp)) + cnic_spq_completion(dev, DRV_CTL_RET_L5_SPQ_CREDIT_CMD, comp); } static u16 cnic_bnx2_next_idx(u16 idx) @@ -2171,8 +2256,9 @@ static int cnic_get_kcqes(struct cnic_dev *dev, struct kcq_info *info) static int cnic_l2_completion(struct cnic_local *cp) { u16 hw_cons, sw_cons; + struct cnic_uio_dev *udev = cp->udev; union eth_rx_cqe *cqe, *cqe_ring = (union eth_rx_cqe *) - (cp->l2_ring + (2 * BCM_PAGE_SIZE)); + (udev->l2_ring + (2 * BCM_PAGE_SIZE)); u32 cmd; int comp = 0; @@ -2203,13 +2289,14 @@ static int cnic_l2_completion(struct cnic_local *cp) static void cnic_chk_pkt_rings(struct cnic_local *cp) { - u16 rx_cons = *cp->rx_cons_ptr; - u16 tx_cons = *cp->tx_cons_ptr; + u16 rx_cons, tx_cons; int comp = 0; - if (!test_bit(CNIC_F_CNIC_UP, &cp->dev->flags)) + if (!test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags)) return; + rx_cons = *cp->rx_cons_ptr; + tx_cons = *cp->tx_cons_ptr; if (cp->tx_cons != tx_cons || cp->rx_cons != rx_cons) { if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) comp = cnic_l2_completion(cp); @@ -2217,7 +2304,8 @@ static void cnic_chk_pkt_rings(struct cnic_local *cp) cp->tx_cons = tx_cons; cp->rx_cons = rx_cons; - uio_event_notify(cp->cnic_uinfo); + if (cp->udev) + uio_event_notify(&cp->udev->cnic_uinfo); } if (comp) clear_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); @@ -2318,14 +2406,38 @@ static inline void cnic_ack_bnx2x_int(struct cnic_dev *dev, u8 id, u8 storm, CNIC_WR(dev, hc_addr, (*(u32 *)&igu_ack)); } +static void cnic_ack_igu_sb(struct cnic_dev *dev, u8 igu_sb_id, u8 segment, + u16 index, u8 op, u8 update) +{ + struct igu_regular cmd_data; + u32 igu_addr = BAR_IGU_INTMEM + (IGU_CMD_INT_ACK_BASE + igu_sb_id) * 8; + + cmd_data.sb_id_and_flags = + (index << IGU_REGULAR_SB_INDEX_SHIFT) | + (segment << IGU_REGULAR_SEGMENT_ACCESS_SHIFT) | + (update << IGU_REGULAR_BUPDATE_SHIFT) | + (op << IGU_REGULAR_ENABLE_INT_SHIFT); + + + CNIC_WR(dev, igu_addr, cmd_data.sb_id_and_flags); +} + static void cnic_ack_bnx2x_msix(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, 0, + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, CSTORM_ID, 0, IGU_INT_DISABLE, 0); } +static void cnic_ack_bnx2x_e2_msix(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + + cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, 0, + IGU_INT_DISABLE, 0); +} + static u32 cnic_service_bnx2x_kcq(struct cnic_dev *dev, struct kcq_info *info) { u32 last_status = *info->status_idx_ptr; @@ -2357,8 +2469,12 @@ static void cnic_service_bnx2x_bh(unsigned long data) status_idx = cnic_service_bnx2x_kcq(dev, &cp->kcq1); CNIC_WR16(dev, cp->kcq1.io_addr, cp->kcq1.sw_prod_idx + MAX_KCQ_IDX); - cnic_ack_bnx2x_int(dev, cp->status_blk_num, CSTORM_ID, - status_idx, IGU_INT_ENABLE, 1); + if (BNX2X_CHIP_IS_E2(cp->chip_id)) + cnic_ack_igu_sb(dev, cp->bnx2x_igu_sb_id, IGU_SEG_ACCESS_DEF, + status_idx, IGU_INT_ENABLE, 1); + else + cnic_ack_bnx2x_int(dev, cp->bnx2x_igu_sb_id, USTORM_ID, + status_idx, IGU_INT_ENABLE, 1); } static int cnic_service_bnx2x(void *data, void *status_blk) @@ -2379,8 +2495,7 @@ static void cnic_ulp_stop(struct cnic_dev *dev) struct cnic_local *cp = dev->cnic_priv; int if_type; - if (cp->cnic_uinfo) - cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); + cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) { struct cnic_ulp_ops *ulp_ops; @@ -2728,6 +2843,13 @@ static int cnic_cm_create(struct cnic_dev *dev, int ulp_type, u32 cid, if (l5_cid >= MAX_CM_SK_TBL_SZ) return -EINVAL; + if (cp->ctx_tbl) { + struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; + + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + return -EAGAIN; + } + csk1 = &cp->csk_tbl[l5_cid]; if (atomic_read(&csk1->ref_count)) return -EAGAIN; @@ -3279,39 +3401,106 @@ static void cnic_close_bnx2x_conn(struct cnic_sock *csk, u32 opcode) static void cnic_cm_stop_bnx2x_hw(struct cnic_dev *dev) { + struct cnic_local *cp = dev->cnic_priv; + int i; + + if (!cp->ctx_tbl) + return; + + if (!netif_running(dev->netdev)) + return; + + for (i = 0; i < cp->max_cid_space; i++) { + struct cnic_context *ctx = &cp->ctx_tbl[i]; + + while (test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) + msleep(10); + + if (test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags)) + netdev_warn(dev->netdev, "CID %x not deleted\n", + ctx->cid); + } + + cancel_delayed_work(&cp->delete_task); + flush_workqueue(cnic_wq); + + if (atomic_read(&cp->iscsi_conn) != 0) + netdev_warn(dev->netdev, "%d iSCSI connections not destroyed\n", + atomic_read(&cp->iscsi_conn)); } static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - int func = CNIC_FUNC(cp); + u32 pfid = cp->pfid; + u32 port = CNIC_PORT(cp); cnic_init_bnx2x_mac(dev); cnic_bnx2x_set_tcp_timestamp(dev, 1); CNIC_WR16(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_LOCAL_VLAN_OFFSET(func), 0); + XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfid), 0); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(func), 1); + XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_ENABLED_OFFSET(port), 1); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(func), + XSTORM_TCP_GLOBAL_DEL_ACK_COUNTER_MAX_COUNT_OFFSET(port), DEF_MAX_DA_COUNT); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(func), DEF_TTL); + XSTORM_ISCSI_TCP_VARS_TTL_OFFSET(pfid), DEF_TTL); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(func), DEF_TOS); + XSTORM_ISCSI_TCP_VARS_TOS_OFFSET(pfid), DEF_TOS); CNIC_WR8(dev, BAR_XSTRORM_INTMEM + - XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(func), 2); + XSTORM_ISCSI_TCP_VARS_ADV_WND_SCL_OFFSET(pfid), 2); CNIC_WR(dev, BAR_XSTRORM_INTMEM + - XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(func), DEF_SWS_TIMER); + XSTORM_TCP_TX_SWS_TIMER_VAL_OFFSET(pfid), DEF_SWS_TIMER); - CNIC_WR(dev, BAR_TSTRORM_INTMEM + TSTORM_TCP_MAX_CWND_OFFSET(func), + CNIC_WR(dev, BAR_TSTRORM_INTMEM + TSTORM_TCP_MAX_CWND_OFFSET(pfid), DEF_MAX_CWND); return 0; } +static void cnic_delete_task(struct work_struct *work) +{ + struct cnic_local *cp; + struct cnic_dev *dev; + u32 i; + int need_resched = 0; + + cp = container_of(work, struct cnic_local, delete_task.work); + dev = cp->dev; + + for (i = 0; i < cp->max_cid_space; i++) { + struct cnic_context *ctx = &cp->ctx_tbl[i]; + + if (!test_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags) || + !test_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) + continue; + + if (!time_after(jiffies, ctx->timestamp + (2 * HZ))) { + need_resched = 1; + continue; + } + + if (!test_and_clear_bit(CTX_FL_DELETE_WAIT, &ctx->ctx_flags)) + continue; + + cnic_bnx2x_destroy_ramrod(dev, i); + + cnic_free_bnx2x_conn_resc(dev, i); + if (ctx->ulp_proto_id == CNIC_ULP_ISCSI) + atomic_dec(&cp->iscsi_conn); + + clear_bit(CTX_FL_OFFLD_START, &ctx->ctx_flags); + } + + if (need_resched) + queue_delayed_work(cnic_wq, &cp->delete_task, + msecs_to_jiffies(10)); + +} + static int cnic_cm_open(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -3326,6 +3515,8 @@ static int cnic_cm_open(struct cnic_dev *dev) if (err) goto err_out; + INIT_DELAYED_WORK(&cp->delete_task, cnic_delete_task); + dev->cm_create = cnic_cm_create; dev->cm_destroy = cnic_cm_destroy; dev->cm_connect = cnic_cm_connect; @@ -3418,11 +3609,24 @@ static void cnic_free_irq(struct cnic_dev *dev) if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { cp->disable_int_sync(dev); - tasklet_disable(&cp->cnic_irq_task); + tasklet_kill(&cp->cnic_irq_task); free_irq(ethdev->irq_arr[0].vector, dev); } } +static int cnic_request_irq(struct cnic_dev *dev) +{ + struct cnic_local *cp = dev->cnic_priv; + struct cnic_eth_dev *ethdev = cp->ethdev; + int err; + + err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0, "cnic", dev); + if (err) + tasklet_disable(&cp->cnic_irq_task); + + return err; +} + static int cnic_init_bnx2_irq(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; @@ -3443,12 +3647,10 @@ static int cnic_init_bnx2_irq(struct cnic_dev *dev) cp->last_status_idx = cp->status_blk.bnx2->status_idx; tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2_msix, (unsigned long) dev); - err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0, - "cnic", dev); - if (err) { - tasklet_disable(&cp->cnic_irq_task); + err = cnic_request_irq(dev); + if (err) return err; - } + while (cp->status_blk.bnx2->status_completion_producer_index && i < 10) { CNIC_WR(dev, BNX2_HC_COALESCE_NOW, @@ -3515,11 +3717,12 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; + struct cnic_uio_dev *udev = cp->udev; u32 cid_addr, tx_cid, sb_id; u32 val, offset0, offset1, offset2, offset3; int i; struct tx_bd *txbd; - dma_addr_t buf_map; + dma_addr_t buf_map, ring_map = udev->l2_ring_map; struct status_block *s_blk = cp->status_blk.gen; sb_id = cp->status_blk_num; @@ -3561,18 +3764,18 @@ static void cnic_init_bnx2_tx_ring(struct cnic_dev *dev) val = BNX2_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16); cnic_ctx_wr(dev, cid_addr, offset1, val); - txbd = (struct tx_bd *) cp->l2_ring; + txbd = (struct tx_bd *) udev->l2_ring; - buf_map = cp->l2_buf_map; + buf_map = udev->l2_buf_map; for (i = 0; i < MAX_TX_DESC_CNT; i++, txbd++) { txbd->tx_bd_haddr_hi = (u64) buf_map >> 32; txbd->tx_bd_haddr_lo = (u64) buf_map & 0xffffffff; } - val = (u64) cp->l2_ring_map >> 32; + val = (u64) ring_map >> 32; cnic_ctx_wr(dev, cid_addr, offset2, val); txbd->tx_bd_haddr_hi = val; - val = (u64) cp->l2_ring_map & 0xffffffff; + val = (u64) ring_map & 0xffffffff; cnic_ctx_wr(dev, cid_addr, offset3, val); txbd->tx_bd_haddr_lo = val; } @@ -3581,10 +3784,12 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; struct cnic_eth_dev *ethdev = cp->ethdev; + struct cnic_uio_dev *udev = cp->udev; u32 cid_addr, sb_id, val, coal_reg, coal_val; int i; struct rx_bd *rxbd; struct status_block *s_blk = cp->status_blk.gen; + dma_addr_t ring_map = udev->l2_ring_map; sb_id = cp->status_blk_num; cnic_init_context(dev, 2); @@ -3618,22 +3823,22 @@ static void cnic_init_bnx2_rx_ring(struct cnic_dev *dev) val = BNX2_L2CTX_L2_STATUSB_NUM(sb_id); cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_HOST_BDIDX, val); - rxbd = (struct rx_bd *) (cp->l2_ring + BCM_PAGE_SIZE); + rxbd = (struct rx_bd *) (udev->l2_ring + BCM_PAGE_SIZE); for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; int n = (i % cp->l2_rx_ring_size) + 1; - buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size); + buf_map = udev->l2_buf_map + (n * cp->l2_single_buf_size); rxbd->rx_bd_len = cp->l2_single_buf_size; rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; rxbd->rx_bd_haddr_hi = (u64) buf_map >> 32; rxbd->rx_bd_haddr_lo = (u64) buf_map & 0xffffffff; } - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32; + val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32; cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_HI, val); rxbd->rx_bd_haddr_hi = val; - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff; + val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff; cnic_ctx_wr(dev, cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val); rxbd->rx_bd_haddr_lo = val; @@ -3850,42 +4055,55 @@ static int cnic_init_bnx2x_irq(struct cnic_dev *dev) tasklet_init(&cp->cnic_irq_task, cnic_service_bnx2x_bh, (unsigned long) dev); - if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) { - err = request_irq(ethdev->irq_arr[0].vector, cnic_irq, 0, - "cnic", dev); - if (err) - tasklet_disable(&cp->cnic_irq_task); - } + if (ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) + err = cnic_request_irq(dev); + return err; } +static inline void cnic_storm_memset_hc_disable(struct cnic_dev *dev, + u16 sb_id, u8 sb_index, + u8 disable) +{ + + u32 addr = BAR_CSTRORM_INTMEM + + CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) + + offsetof(struct hc_status_block_data_e1x, index_data) + + sizeof(struct hc_index_data)*sb_index + + offsetof(struct hc_index_data, flags); + u16 flags = CNIC_RD16(dev, addr); + /* clear and set */ + flags &= ~HC_INDEX_DATA_HC_ENABLED; + flags |= (((~disable) << HC_INDEX_DATA_HC_ENABLED_SHIFT) & + HC_INDEX_DATA_HC_ENABLED); + CNIC_WR16(dev, addr, flags); +} + static void cnic_enable_bnx2x_int(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; u8 sb_id = cp->status_blk_num; - int port = CNIC_PORT(cp); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_TIMEOUT_C_OFFSET(port, sb_id, - HC_INDEX_C_ISCSI_EQ_CONS), - 64 / 12); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HC_DISABLE_C_OFFSET(port, sb_id, - HC_INDEX_C_ISCSI_EQ_CONS), 0); + CSTORM_STATUS_BLOCK_DATA_OFFSET(sb_id) + + offsetof(struct hc_status_block_data_e1x, index_data) + + sizeof(struct hc_index_data)*HC_INDEX_ISCSI_EQ_CONS + + offsetof(struct hc_index_data, timeout), 64 / 12); + cnic_storm_memset_hc_disable(dev, sb_id, HC_INDEX_ISCSI_EQ_CONS, 0); } static void cnic_disable_bnx2x_int_sync(struct cnic_dev *dev) { } -static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) +static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev, + struct client_init_ramrod_data *data) { struct cnic_local *cp = dev->cnic_priv; - union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) cp->l2_ring; - struct eth_context *context; - struct regpair context_addr; - dma_addr_t buf_map; - int func = CNIC_FUNC(cp); + struct cnic_uio_dev *udev = cp->udev; + union eth_tx_bd_types *txbd = (union eth_tx_bd_types *) udev->l2_ring; + dma_addr_t buf_map, ring_map = udev->l2_ring_map; + struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int port = CNIC_PORT(cp); int i; int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); @@ -3893,7 +4111,7 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) memset(txbd, 0, BCM_PAGE_SIZE); - buf_map = cp->l2_buf_map; + buf_map = udev->l2_buf_map; for (i = 0; i < MAX_TX_DESC_CNT; i += 3, txbd += 3) { struct eth_tx_start_bd *start_bd = &txbd->start_bd; struct eth_tx_bd *reg_bd = &((txbd + 2)->reg_bd); @@ -3910,33 +4128,23 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) start_bd->general_data |= (1 << ETH_TX_START_BD_HDR_NBDS_SHIFT); } - context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 1, &context_addr); - val = (u64) cp->l2_ring_map >> 32; + val = (u64) ring_map >> 32; txbd->next_bd.addr_hi = cpu_to_le32(val); - context->xstorm_st_context.tx_bd_page_base_hi = val; + data->tx.tx_bd_page_base.hi = cpu_to_le32(val); - val = (u64) cp->l2_ring_map & 0xffffffff; + val = (u64) ring_map & 0xffffffff; txbd->next_bd.addr_lo = cpu_to_le32(val); - context->xstorm_st_context.tx_bd_page_base_lo = val; - - context->cstorm_st_context.sb_index_number = - HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS; - context->cstorm_st_context.status_block_id = BNX2X_DEF_SB_ID; + data->tx.tx_bd_page_base.lo = cpu_to_le32(val); - if (cli < MAX_X_STAT_COUNTER_ID) - context->xstorm_st_context.statistics_data = cli | - XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE; - - context->xstorm_ag_context.cdu_reserved = - CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func), - CDU_REGION_NUMBER_XCM_AG, - ETH_CONNECTION_TYPE); + /* Other ramrod params */ + data->tx.tx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_CQ_CONS; + data->tx.tx_status_block_id = BNX2X_DEF_SB_ID; /* reset xstorm per client statistics */ - if (cli < MAX_X_STAT_COUNTER_ID) { + if (cli < MAX_STAT_COUNTER_ID) { val = BAR_XSTRORM_INTMEM + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) @@ -3944,111 +4152,77 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) } cp->tx_cons_ptr = - &cp->bnx2x_def_status_blk->c_def_status_block.index_values[ - HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS]; + &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_CQ_CONS]; } -static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) +static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev, + struct client_init_ramrod_data *data) { struct cnic_local *cp = dev->cnic_priv; - struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (cp->l2_ring + + struct cnic_uio_dev *udev = cp->udev; + struct eth_rx_bd *rxbd = (struct eth_rx_bd *) (udev->l2_ring + BCM_PAGE_SIZE); struct eth_rx_cqe_next_page *rxcqe = (struct eth_rx_cqe_next_page *) - (cp->l2_ring + (2 * BCM_PAGE_SIZE)); - struct eth_context *context; - struct regpair context_addr; + (udev->l2_ring + (2 * BCM_PAGE_SIZE)); + struct host_sp_status_block *sb = cp->bnx2x_def_status_blk; int i; int port = CNIC_PORT(cp); - int func = CNIC_FUNC(cp); int cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + int cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); u32 val; - struct tstorm_eth_client_config tstorm_client = {0}; + dma_addr_t ring_map = udev->l2_ring_map; + + /* General data */ + data->general.client_id = cli; + data->general.statistics_en_flg = 1; + data->general.statistics_counter_id = cli; + data->general.activate_flg = 1; + data->general.sp_client_id = cli; for (i = 0; i < BNX2X_MAX_RX_DESC_CNT; i++, rxbd++) { dma_addr_t buf_map; int n = (i % cp->l2_rx_ring_size) + 1; - buf_map = cp->l2_buf_map + (n * cp->l2_single_buf_size); + buf_map = udev->l2_buf_map + (n * cp->l2_single_buf_size); rxbd->addr_hi = cpu_to_le32((u64) buf_map >> 32); rxbd->addr_lo = cpu_to_le32(buf_map & 0xffffffff); } - context = cnic_get_bnx2x_ctx(dev, BNX2X_ISCSI_L2_CID, 0, &context_addr); - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) >> 32; + val = (u64) (ring_map + BCM_PAGE_SIZE) >> 32; rxbd->addr_hi = cpu_to_le32(val); + data->rx.bd_page_base.hi = cpu_to_le32(val); - context->ustorm_st_context.common.bd_page_base_hi = val; - - val = (u64) (cp->l2_ring_map + BCM_PAGE_SIZE) & 0xffffffff; + val = (u64) (ring_map + BCM_PAGE_SIZE) & 0xffffffff; rxbd->addr_lo = cpu_to_le32(val); - - context->ustorm_st_context.common.bd_page_base_lo = val; - - context->ustorm_st_context.common.sb_index_numbers = - BNX2X_ISCSI_RX_SB_INDEX_NUM; - context->ustorm_st_context.common.clientId = cli; - context->ustorm_st_context.common.status_block_id = BNX2X_DEF_SB_ID; - if (cli < MAX_U_STAT_COUNTER_ID) { - context->ustorm_st_context.common.flags = - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS; - context->ustorm_st_context.common.statistics_counter_id = cli; - } - context->ustorm_st_context.common.mc_alignment_log_size = 0; - context->ustorm_st_context.common.bd_buff_size = - cp->l2_single_buf_size; - - context->ustorm_ag_context.cdu_usage = - CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func), - CDU_REGION_NUMBER_UCM_AG, - ETH_CONNECTION_TYPE); + data->rx.bd_page_base.lo = cpu_to_le32(val); rxcqe += BNX2X_MAX_RCQ_DESC_CNT; - val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) >> 32; + val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) >> 32; rxcqe->addr_hi = cpu_to_le32(val); + data->rx.cqe_page_base.hi = cpu_to_le32(val); - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, cli) + 4, val); - - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, cli) + 4, val); - - val = (u64) (cp->l2_ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff; + val = (u64) (ring_map + (2 * BCM_PAGE_SIZE)) & 0xffffffff; rxcqe->addr_lo = cpu_to_le32(val); + data->rx.cqe_page_base.lo = cpu_to_le32(val); - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_BASE_OFFSET(port, cli), val); - - CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_CQE_PAGE_NEXT_OFFSET(port, cli), val); - - /* client tstorm info */ - tstorm_client.mtu = cp->l2_single_buf_size - 14; - tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE; - - if (cli < MAX_T_STAT_COUNTER_ID) { - tstorm_client.config_flags |= - TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; - tstorm_client.statistics_counter_id = cli; - } + /* Other ramrod params */ + data->rx.client_qzone_id = cl_qzone_id; + data->rx.rx_sb_index_number = HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS; + data->rx.status_block_id = BNX2X_DEF_SB_ID; - CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, cli), - ((u32 *)&tstorm_client)[0]); - CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_CLIENT_CONFIG_OFFSET(port, cli) + 4, - ((u32 *)&tstorm_client)[1]); + data->rx.cache_line_alignment_log_size = L1_CACHE_SHIFT; + data->rx.bd_buff_size = cpu_to_le16(cp->l2_single_buf_size); - /* reset tstorm per client statistics */ - if (cli < MAX_T_STAT_COUNTER_ID) { + data->rx.mtu = cpu_to_le16(cp->l2_single_buf_size - 14); + data->rx.outer_vlan_removal_enable_flg = 1; + /* reset tstorm and ustorm per client statistics */ + if (cli < MAX_STAT_COUNTER_ID) { val = BAR_TSTRORM_INTMEM + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) CNIC_WR(dev, val + i * 4, 0); - } - /* reset ustorm per client statistics */ - if (cli < MAX_U_STAT_COUNTER_ID) { val = BAR_USTRORM_INTMEM + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++) @@ -4056,21 +4230,22 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) } cp->rx_cons_ptr = - &cp->bnx2x_def_status_blk->u_def_status_block.index_values[ - HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS]; + &sb->sp_sb.index_values[HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS]; } static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - u32 base, addr, val; + u32 base, base2, addr, val; int port = CNIC_PORT(cp); dev->max_iscsi_conn = 0; base = CNIC_RD(dev, MISC_REG_SHARED_MEM_ADDR); - if (base < 0xa0000 || base >= 0xc0000) + if (base == 0) return; + base2 = CNIC_RD(dev, (CNIC_PATH(cp) ? MISC_REG_GENERIC_CR_1 : + MISC_REG_GENERIC_CR_0)); addr = BNX2X_SHMEM_ADDR(base, dev_info.port_hw_config[port].iscsi_mac_upper); @@ -4103,16 +4278,25 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) val16 ^= 0x1e1e; dev->max_iscsi_conn = val16; } - if (BNX2X_CHIP_IS_E1H(cp->chip_id)) { + if (BNX2X_CHIP_IS_E1H(cp->chip_id) || BNX2X_CHIP_IS_E2(cp->chip_id)) { int func = CNIC_FUNC(cp); + u32 mf_cfg_addr; + + if (BNX2X_SHMEM2_HAS(base2, mf_cfg_addr)) + mf_cfg_addr = CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base2, + mf_cfg_addr)); + else + mf_cfg_addr = base + BNX2X_SHMEM_MF_BLK_OFFSET; + + addr = mf_cfg_addr + + offsetof(struct mf_cfg, func_mf_config[func].e1hov_tag); - addr = BNX2X_SHMEM_ADDR(base, - mf_cfg.func_mf_config[func].e1hov_tag); val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_E1HOV_TAG_MASK; if (val != FUNC_MF_CFG_E1HOV_TAG_DEFAULT) { - addr = BNX2X_SHMEM_ADDR(base, - mf_cfg.func_mf_config[func].config); + addr = mf_cfg_addr + + offsetof(struct mf_cfg, + func_mf_config[func].config); val = CNIC_RD(dev, addr); val &= FUNC_MF_CFG_PROTOCOL_MASK; if (val != FUNC_MF_CFG_PROTOCOL_ISCSI) @@ -4124,10 +4308,26 @@ static void cnic_get_bnx2x_iscsi_info(struct cnic_dev *dev) static int cnic_start_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; + struct cnic_eth_dev *ethdev = cp->ethdev; int func = CNIC_FUNC(cp), ret, i; - int port = CNIC_PORT(cp); - u16 eq_idx; - u8 sb_id = cp->status_blk_num; + u32 pfid; + + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + u32 val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN_OVWR); + + if (!(val & 1)) + val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN); + else + val = (val >> 1) & 1; + + if (val) + cp->pfid = func >> 1; + else + cp->pfid = func & 0x6; + } else { + cp->pfid = func; + } + pfid = cp->pfid; ret = cnic_init_id_tbl(&cp->cid_tbl, MAX_ISCSI_TBL_SZ, cp->iscsi_start_cid); @@ -4135,86 +4335,98 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev) if (ret) return -ENOMEM; + cp->bnx2x_igu_sb_id = ethdev->irq_arr[0].status_blk_num2; + cp->kcq1.io_addr = BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_PROD_OFFSET(func, 0); + CSTORM_ISCSI_EQ_PROD_OFFSET(pfid, 0); cp->kcq1.sw_prod_idx = 0; - cp->kcq1.hw_prod_idx_ptr = - &cp->status_blk.bnx2x->c_status_block.index_values[ - HC_INDEX_C_ISCSI_EQ_CONS]; - cp->kcq1.status_idx_ptr = - &cp->status_blk.bnx2x->c_status_block.status_block_index; + if (BNX2X_CHIP_IS_E2(cp->chip_id)) { + struct host_hc_status_block_e2 *sb = cp->status_blk.gen; + + cp->kcq1.hw_prod_idx_ptr = + &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; + cp->kcq1.status_idx_ptr = + &sb->sb.running_index[SM_RX_ID]; + } else { + struct host_hc_status_block_e1x *sb = cp->status_blk.gen; + + cp->kcq1.hw_prod_idx_ptr = + &sb->sb.index_values[HC_INDEX_ISCSI_EQ_CONS]; + cp->kcq1.status_idx_ptr = + &sb->sb.running_index[SM_RX_ID]; + } cnic_get_bnx2x_iscsi_info(dev); /* Only 1 EQ */ CNIC_WR16(dev, cp->kcq1.io_addr, MAX_KCQ_IDX); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_CONS_OFFSET(func, 0), 0); + CSTORM_ISCSI_EQ_CONS_OFFSET(pfid, 0), 0); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0), + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfid, 0), cp->kcq1.dma.pg_map_arr[1] & 0xffffffff); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(func, 0) + 4, + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_OFFSET(pfid, 0) + 4, (u64) cp->kcq1.dma.pg_map_arr[1] >> 32); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0), + CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfid, 0), cp->kcq1.dma.pg_map_arr[0] & 0xffffffff); CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(func, 0) + 4, + CSTORM_ISCSI_EQ_NEXT_EQE_ADDR_OFFSET(pfid, 0) + 4, (u64) cp->kcq1.dma.pg_map_arr[0] >> 32); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(func, 0), 1); + CSTORM_ISCSI_EQ_NEXT_PAGE_ADDR_VALID_OFFSET(pfid, 0), 1); CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_SB_NUM_OFFSET(func, 0), cp->status_blk_num); + CSTORM_ISCSI_EQ_SB_NUM_OFFSET(pfid, 0), cp->status_blk_num); CNIC_WR8(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(func, 0), - HC_INDEX_C_ISCSI_EQ_CONS); + CSTORM_ISCSI_EQ_SB_INDEX_OFFSET(pfid, 0), + HC_INDEX_ISCSI_EQ_CONS); for (i = 0; i < cp->conn_buf_info.num_pages; i++) { CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(func, i), + TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfid, i), cp->conn_buf_info.pgtbl[2 * i]); CNIC_WR(dev, BAR_TSTRORM_INTMEM + - TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(func, i) + 4, + TSTORM_ISCSI_CONN_BUF_PBL_OFFSET(pfid, i) + 4, cp->conn_buf_info.pgtbl[(2 * i) + 1]); } CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func), + USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid), cp->gbl_buf_info.pg_map_arr[0] & 0xffffffff); CNIC_WR(dev, BAR_USTRORM_INTMEM + - USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(func) + 4, + USTORM_ISCSI_GLOBAL_BUF_PHYS_ADDR_OFFSET(pfid) + 4, (u64) cp->gbl_buf_info.pg_map_arr[0] >> 32); + CNIC_WR(dev, BAR_TSTRORM_INTMEM + + TSTORM_ISCSI_TCP_LOCAL_ADV_WND_OFFSET(pfid), DEF_RCV_BUF); + cnic_setup_bnx2x_context(dev); - eq_idx = CNIC_RD16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) + - offsetof(struct cstorm_status_block_c, - index_values[HC_INDEX_C_ISCSI_EQ_CONS])); - if (eq_idx != 0) { - netdev_err(dev->netdev, "EQ cons index %x != 0\n", eq_idx); - return -EBUSY; - } ret = cnic_init_bnx2x_irq(dev); if (ret) return ret; - cnic_init_bnx2x_tx_ring(dev); - cnic_init_bnx2x_rx_ring(dev); - return 0; } static void cnic_init_rings(struct cnic_dev *dev) { + struct cnic_local *cp = dev->cnic_priv; + struct cnic_uio_dev *udev = cp->udev; + + if (test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags)) + return; + if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { cnic_init_bnx2_tx_ring(dev); cnic_init_bnx2_rx_ring(dev); + set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { - struct cnic_local *cp = dev->cnic_priv; u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); + u32 cl_qzone_id, type; + struct client_init_ramrod_data *data; union l5cm_specific_data l5_data; struct ustorm_eth_rx_producers rx_prods = {0}; u32 off, i; @@ -4223,21 +4435,38 @@ static void cnic_init_rings(struct cnic_dev *dev) rx_prods.cqe_prod = BNX2X_MAX_RCQ_DESC_CNT; barrier(); + cl_qzone_id = BNX2X_CL_QZONE_ID(cp, cli); + off = BAR_USTRORM_INTMEM + - USTORM_RX_PRODS_OFFSET(CNIC_PORT(cp), cli); + (BNX2X_CHIP_IS_E2(cp->chip_id) ? + USTORM_RX_PRODS_E2_OFFSET(cl_qzone_id) : + USTORM_RX_PRODS_E1X_OFFSET(CNIC_PORT(cp), cli)); for (i = 0; i < sizeof(struct ustorm_eth_rx_producers) / 4; i++) CNIC_WR(dev, off + i * 4, ((u32 *) &rx_prods)[i]); set_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags); - cnic_init_bnx2x_tx_ring(dev); - cnic_init_bnx2x_rx_ring(dev); + data = udev->l2_buf; + + memset(data, 0, sizeof(*data)); + + cnic_init_bnx2x_tx_ring(dev, data); + cnic_init_bnx2x_rx_ring(dev, data); + + l5_data.phy_address.lo = udev->l2_buf_map & 0xffffffff; + l5_data.phy_address.hi = (u64) udev->l2_buf_map >> 32; + + type = (ETH_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); + + set_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); - l5_data.phy_address.lo = cli; - l5_data.phy_address.hi = 0; cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CLIENT_SETUP, - BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE, &l5_data); + BNX2X_ISCSI_L2_CID, type, &l5_data); + i = 0; while (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags) && ++i < 10) @@ -4246,13 +4475,18 @@ static void cnic_init_rings(struct cnic_dev *dev) if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) netdev_err(dev->netdev, "iSCSI CLIENT_SETUP did not complete\n"); - cnic_kwq_completion(dev, 1); + cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 1); } } static void cnic_shutdown_rings(struct cnic_dev *dev) { + struct cnic_local *cp = dev->cnic_priv; + + if (!test_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags)) + return; + if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { cnic_shutdown_bnx2_rx_ring(dev); } else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { @@ -4260,6 +4494,7 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) u32 cli = BNX2X_ISCSI_CL_ID(CNIC_E1HVN(cp)); union l5cm_specific_data l5_data; int i; + u32 type; cnic_ring_ctl(dev, BNX2X_ISCSI_L2_CID, cli, 0); @@ -4277,14 +4512,18 @@ static void cnic_shutdown_rings(struct cnic_dev *dev) if (test_bit(CNIC_LCL_FL_L2_WAIT, &cp->cnic_local_flags)) netdev_err(dev->netdev, "iSCSI CLIENT_HALT did not complete\n"); - cnic_kwq_completion(dev, 1); + cnic_spq_completion(dev, DRV_CTL_RET_L2_SPQ_CREDIT_CMD, 1); memset(&l5_data, 0, sizeof(l5_data)); - cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_ETH_CFC_DEL, - BNX2X_ISCSI_L2_CID, ETH_CONNECTION_TYPE | - (1 << SPE_HDR_COMMON_RAMROD_SHIFT), &l5_data); + type = (NONE_CONNECTION_TYPE << SPE_HDR_CONN_TYPE_SHIFT) + & SPE_HDR_CONN_TYPE; + type |= ((cp->pfid << SPE_HDR_FUNCTION_ID_SHIFT) & + SPE_HDR_FUNCTION_ID); + cnic_submit_kwqe_16(dev, RAMROD_CMD_ID_COMMON_CFC_DEL, + BNX2X_ISCSI_L2_CID, type, &l5_data); msleep(10); } + clear_bit(CNIC_LCL_FL_RINGS_INITED, &cp->cnic_local_flags); } static int cnic_register_netdev(struct cnic_dev *dev) @@ -4327,7 +4566,6 @@ static int cnic_start_hw(struct cnic_dev *dev) return -EALREADY; dev->regview = ethdev->io_base; - cp->chip_id = ethdev->chip_id; pci_dev_get(dev->pcidev); cp->func = PCI_FUNC(dev->pcidev->devfn); cp->status_blk.gen = ethdev->irq_arr[0].status_blk; @@ -4379,17 +4617,11 @@ static void cnic_stop_bnx2_hw(struct cnic_dev *dev) static void cnic_stop_bnx2x_hw(struct cnic_dev *dev) { struct cnic_local *cp = dev->cnic_priv; - u8 sb_id = cp->status_blk_num; - int port = CNIC_PORT(cp); cnic_free_irq(dev); - CNIC_WR16(dev, BAR_CSTRORM_INTMEM + - CSTORM_SB_HOST_STATUS_BLOCK_C_OFFSET(port, sb_id) + - offsetof(struct cstorm_status_block_c, - index_values[HC_INDEX_C_ISCSI_EQ_CONS]), - 0); + *cp->kcq1.hw_prod_idx_ptr = 0; CNIC_WR(dev, BAR_CSTRORM_INTMEM + - CSTORM_ISCSI_EQ_CONS_OFFSET(cp->func, 0), 0); + CSTORM_ISCSI_EQ_CONS_OFFSET(cp->pfid, 0), 0); CNIC_WR16(dev, cp->kcq1.io_addr, 0); cnic_free_resc(dev); } @@ -4403,10 +4635,11 @@ static void cnic_stop_hw(struct cnic_dev *dev) /* Need to wait for the ring shutdown event to complete * before clearing the CNIC_UP flag. */ - while (cp->uio_dev != -1 && i < 15) { + while (cp->udev->uio_dev != -1 && i < 15) { msleep(100); i++; } + cnic_shutdown_rings(dev); clear_bit(CNIC_F_CNIC_UP, &dev->flags); rcu_assign_pointer(cp->ulp_ops[CNIC_ULP_L4], NULL); synchronize_rcu(); @@ -4455,7 +4688,6 @@ static struct cnic_dev *cnic_alloc_dev(struct net_device *dev, cp = cdev->cnic_priv; cp->dev = cdev; - cp->uio_dev = -1; cp->l2_single_buf_size = 0x400; cp->l2_rx_ring_size = 3; @@ -4510,6 +4742,7 @@ static struct cnic_dev *init_bnx2_cnic(struct net_device *dev) cp = cdev->cnic_priv; cp->ethdev = ethdev; cdev->pcidev = pdev; + cp->chip_id = ethdev->chip_id; cp->cnic_ops = &cnic_bnx2_ops; cp->start_hw = cnic_start_bnx2_hw; @@ -4564,6 +4797,7 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) cp = cdev->cnic_priv; cp->ethdev = ethdev; cdev->pcidev = pdev; + cp->chip_id = ethdev->chip_id; cp->cnic_ops = &cnic_bnx2x_ops; cp->start_hw = cnic_start_bnx2x_hw; @@ -4575,7 +4809,10 @@ static struct cnic_dev *init_bnx2x_cnic(struct net_device *dev) cp->stop_cm = cnic_cm_stop_bnx2x_hw; cp->enable_int = cnic_enable_bnx2x_int; cp->disable_int_sync = cnic_disable_bnx2x_int_sync; - cp->ack_int = cnic_ack_bnx2x_msix; + if (BNX2X_CHIP_IS_E2(cp->chip_id)) + cp->ack_int = cnic_ack_bnx2x_e2_msix; + else + cp->ack_int = cnic_ack_bnx2x_msix; cp->close_conn = cnic_close_bnx2x_conn; cp->next_idx = cnic_bnx2x_next_idx; cp->hw_idx = cnic_bnx2x_hw_idx; @@ -4683,6 +4920,7 @@ static struct notifier_block cnic_netdev_notifier = { static void cnic_release(void) { struct cnic_dev *dev; + struct cnic_uio_dev *udev; while (!list_empty(&cnic_dev_list)) { dev = list_entry(cnic_dev_list.next, struct cnic_dev, list); @@ -4696,6 +4934,11 @@ static void cnic_release(void) list_del_init(&dev->list); cnic_free_dev(dev); } + while (!list_empty(&cnic_udev_list)) { + udev = list_entry(cnic_udev_list.next, struct cnic_uio_dev, + list); + cnic_free_uio(udev); + } } static int __init cnic_init(void) @@ -4710,6 +4953,13 @@ static int __init cnic_init(void) return rc; } + cnic_wq = create_singlethread_workqueue("cnic_wq"); + if (!cnic_wq) { + cnic_release(); + unregister_netdevice_notifier(&cnic_netdev_notifier); + return -ENOMEM; + } + return 0; } @@ -4717,6 +4967,7 @@ static void __exit cnic_exit(void) { unregister_netdevice_notifier(&cnic_netdev_notifier); cnic_release(); + destroy_workqueue(cnic_wq); } module_init(cnic_init); diff --git a/drivers/net/cnic.h b/drivers/net/cnic.h index 275c36114d852a4fd5bd97d1e1da6feea0b629bb..6a4a0ae5cfe310d2d3b8b952da88179376984276 100644 --- a/drivers/net/cnic.h +++ b/drivers/net/cnic.h @@ -12,6 +12,13 @@ #ifndef CNIC_H #define CNIC_H +#define HC_INDEX_ISCSI_EQ_CONS 6 + +#define HC_INDEX_FCOE_EQ_CONS 3 + +#define HC_SP_INDEX_ETH_ISCSI_CQ_CONS 5 +#define HC_SP_INDEX_ETH_ISCSI_RX_CQ_CONS 1 + #define KWQ_PAGE_CNT 4 #define KCQ_PAGE_CNT 16 @@ -161,8 +168,9 @@ struct cnic_context { wait_queue_head_t waitq; int wait_cond; unsigned long timestamp; - u32 ctx_flags; -#define CTX_FL_OFFLD_START 0x00000001 + unsigned long ctx_flags; +#define CTX_FL_OFFLD_START 0 +#define CTX_FL_DELETE_WAIT 1 u8 ulp_proto_id; union { struct cnic_iscsi *iscsi; @@ -179,6 +187,31 @@ struct kcq_info { u32 io_addr; }; +struct iro { + u32 base; + u16 m1; + u16 m2; + u16 m3; + u16 size; +}; + +struct cnic_uio_dev { + struct uio_info cnic_uinfo; + u32 uio_dev; + + int l2_ring_size; + void *l2_ring; + dma_addr_t l2_ring_map; + + int l2_buf_size; + void *l2_buf; + dma_addr_t l2_buf_map; + + struct cnic_dev *dev; + struct pci_dev *pdev; + struct list_head list; +}; + struct cnic_local { spinlock_t cnic_ulp_lock; @@ -192,19 +225,15 @@ struct cnic_local { unsigned long cnic_local_flags; #define CNIC_LCL_FL_KWQ_INIT 0x0 #define CNIC_LCL_FL_L2_WAIT 0x1 +#define CNIC_LCL_FL_RINGS_INITED 0x2 struct cnic_dev *dev; struct cnic_eth_dev *ethdev; - void *l2_ring; - dma_addr_t l2_ring_map; - int l2_ring_size; - int l2_rx_ring_size; + struct cnic_uio_dev *udev; - void *l2_buf; - dma_addr_t l2_buf_map; - int l2_buf_size; + int l2_rx_ring_size; int l2_single_buf_size; u16 *rx_cons_ptr; @@ -212,6 +241,9 @@ struct cnic_local { u16 rx_cons; u16 tx_cons; + struct iro *iro_arr; +#define IRO (((struct cnic_local *) dev->cnic_priv)->iro_arr) + struct cnic_dma kwq_info; struct kwqe **kwq; @@ -230,12 +262,16 @@ struct cnic_local { union { void *gen; struct status_block_msix *bnx2; - struct host_status_block *bnx2x; + struct host_hc_status_block_e1x *bnx2x_e1x; + /* index values - which counter to update */ + #define SM_RX_ID 0 + #define SM_TX_ID 1 } status_blk; - struct host_def_status_block *bnx2x_def_status_blk; + struct host_sp_status_block *bnx2x_def_status_blk; u32 status_blk_num; + u32 bnx2x_igu_sb_id; u32 int_num; u32 last_status_idx; struct tasklet_struct cnic_irq_task; @@ -264,6 +300,8 @@ struct cnic_local { int hq_size; int num_cqs; + struct delayed_work delete_task; + struct cnic_ctx *ctx_arr; int ctx_blks; int ctx_blk_size; @@ -272,11 +310,9 @@ struct cnic_local { u32 chip_id; int func; + u32 pfid; u32 shmem_base; - u32 uio_dev; - struct uio_info *cnic_uinfo; - struct cnic_ops *cnic_ops; int (*start_hw)(struct cnic_dev *); void (*stop_hw)(struct cnic_dev *); @@ -335,18 +371,36 @@ struct bnx2x_bd_chain_next { #define BNX2X_ISCSI_GLB_BUF_SIZE 64 #define BNX2X_ISCSI_PBL_NOT_CACHED 0xff #define BNX2X_ISCSI_PDU_HEADER_NOT_CACHED 0xff -#define BNX2X_HW_CID(x, func) ((x) | (((func) % PORT_MAX) << 23) | \ - (((func) >> 1) << 17)) -#define BNX2X_SW_CID(x) (x & 0x1ffff) + +#define BNX2X_CHIP_NUM_57710 0x164e #define BNX2X_CHIP_NUM_57711 0x164f #define BNX2X_CHIP_NUM_57711E 0x1650 +#define BNX2X_CHIP_NUM_57712 0x1662 +#define BNX2X_CHIP_NUM_57712E 0x1663 +#define BNX2X_CHIP_NUM_57713 0x1651 +#define BNX2X_CHIP_NUM_57713E 0x1652 + #define BNX2X_CHIP_NUM(x) (x >> 16) +#define BNX2X_CHIP_IS_57710(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57710) #define BNX2X_CHIP_IS_57711(x) \ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57711) #define BNX2X_CHIP_IS_57711E(x) \ (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57711E) #define BNX2X_CHIP_IS_E1H(x) \ (BNX2X_CHIP_IS_57711(x) || BNX2X_CHIP_IS_57711E(x)) +#define BNX2X_CHIP_IS_57712(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57712) +#define BNX2X_CHIP_IS_57712E(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57712E) +#define BNX2X_CHIP_IS_57713(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57713) +#define BNX2X_CHIP_IS_57713E(x) \ + (BNX2X_CHIP_NUM(x) == BNX2X_CHIP_NUM_57713E) +#define BNX2X_CHIP_IS_E2(x) \ + (BNX2X_CHIP_IS_57712(x) || BNX2X_CHIP_IS_57712E(x) || \ + BNX2X_CHIP_IS_57713(x) || BNX2X_CHIP_IS_57713E(x)) + #define IS_E1H_OFFSET BNX2X_CHIP_IS_E1H(cp->chip_id) #define BNX2X_RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct eth_rx_bd)) @@ -358,19 +412,35 @@ struct bnx2x_bd_chain_next { (BNX2X_MAX_RCQ_DESC_CNT - 1)) ? \ ((x) + 2) : ((x) + 1) -#define BNX2X_DEF_SB_ID 16 +#define BNX2X_DEF_SB_ID HC_SP_SB_ID -#define BNX2X_ISCSI_RX_SB_INDEX_NUM \ - ((HC_INDEX_DEF_U_ETH_ISCSI_RX_CQ_CONS << \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER_SHIFT) & \ - USTORM_ETH_ST_CONTEXT_CONFIG_CQE_SB_INDEX_NUMBER) +#define BNX2X_SHMEM_MF_BLK_OFFSET 0x7e4 #define BNX2X_SHMEM_ADDR(base, field) (base + \ offsetof(struct shmem_region, field)) -#define CNIC_PORT(cp) ((cp)->func % PORT_MAX) +#define BNX2X_SHMEM2_ADDR(base, field) (base + \ + offsetof(struct shmem2_region, field)) + +#define BNX2X_SHMEM2_HAS(base, field) \ + ((base) && \ + (CNIC_RD(dev, BNX2X_SHMEM2_ADDR(base, size)) > \ + offsetof(struct shmem2_region, field))) + +#define CNIC_PORT(cp) ((cp)->pfid & 1) #define CNIC_FUNC(cp) ((cp)->func) -#define CNIC_E1HVN(cp) ((cp)->func >> 1) +#define CNIC_PATH(cp) (!BNX2X_CHIP_IS_E2(cp->chip_id) ? 0 :\ + (CNIC_FUNC(cp) & 1)) +#define CNIC_E1HVN(cp) ((cp)->pfid >> 1) + +#define BNX2X_HW_CID(cp, x) ((CNIC_PORT(cp) << 23) | \ + (CNIC_E1HVN(cp) << 17) | (x)) + +#define BNX2X_SW_CID(x) (x & 0x1ffff) + +#define BNX2X_CL_QZONE_ID(cp, cli) \ + (cli + (CNIC_PORT(cp) * ETH_MAX_RX_CLIENTS_E1H)) +#define TCP_TSTORM_OOO_DROP_AND_PROC_ACK (0<<4) #endif diff --git a/drivers/net/cnic_defs.h b/drivers/net/cnic_defs.h index 7ce694d41b6b9089800bcb8e60de8a1b6fe4c268..328e8b2765a3079ae474dbd15fe025deb7e20a84 100644 --- a/drivers/net/cnic_defs.h +++ b/drivers/net/cnic_defs.h @@ -14,6 +14,7 @@ /* KWQ (kernel work queue) request op codes */ #define L2_KWQE_OPCODE_VALUE_FLUSH (4) +#define L2_KWQE_OPCODE_VALUE_VM_FREE_RX_QUEUE (8) #define L4_KWQE_OPCODE_VALUE_CONNECT1 (50) #define L4_KWQE_OPCODE_VALUE_CONNECT2 (51) @@ -48,11 +49,14 @@ #define L4_KCQE_OPCODE_VALUE_UPLOAD_PG (14) /* KCQ (kernel completion queue) completion status */ -#define L4_KCQE_COMPLETION_STATUS_SUCCESS (0) -#define L4_KCQE_COMPLETION_STATUS_TIMEOUT (0x93) +#define L4_KCQE_COMPLETION_STATUS_SUCCESS (0) +#define L4_KCQE_COMPLETION_STATUS_TIMEOUT (0x93) -#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83) -#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG (0x89) +#define L4_KCQE_COMPLETION_STATUS_CTX_ALLOC_FAIL (0x83) +#define L4_KCQE_COMPLETION_STATUS_OFFLOADED_PG (0x89) + +#define L4_KCQE_OPCODE_VALUE_OOO_EVENT_NOTIFICATION (0xa0) +#define L4_KCQE_OPCODE_VALUE_OOO_FLUSH (0xa1) #define L4_LAYER_CODE (4) #define L2_LAYER_CODE (2) @@ -584,6 +588,100 @@ struct l4_kwq_upload { * bnx2x structures */ +/* + * The iscsi aggregative context of Cstorm + */ +struct cstorm_iscsi_ag_context { + u32 agg_vars1; +#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0) +#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10 +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11) +#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16 +#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18) +#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21 +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22) +#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22 +#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23) +#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23 +#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26) +#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28 +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30) +#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30 +#if defined(__BIG_ENDIAN) + u8 __aux1_th; + u8 __aux1_val; + u16 __agg_vars2; +#elif defined(__LITTLE_ENDIAN) + u16 __agg_vars2; + u8 __aux1_val; + u8 __aux1_th; +#endif + u32 rel_seq; + u32 rel_seq_th; +#if defined(__BIG_ENDIAN) + u16 hq_cons; + u16 hq_prod; +#elif defined(__LITTLE_ENDIAN) + u16 hq_prod; + u16 hq_cons; +#endif +#if defined(__BIG_ENDIAN) + u8 __reserved62; + u8 __reserved61; + u8 __reserved60; + u8 __reserved59; +#elif defined(__LITTLE_ENDIAN) + u8 __reserved59; + u8 __reserved60; + u8 __reserved61; + u8 __reserved62; +#endif +#if defined(__BIG_ENDIAN) + u16 __reserved64; + u16 __cq_u_prod0; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod0; + u16 __reserved64; +#endif + u32 __cq_u_prod1; +#if defined(__BIG_ENDIAN) + u16 __agg_vars3; + u16 __cq_u_prod2; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod2; + u16 __agg_vars3; +#endif +#if defined(__BIG_ENDIAN) + u16 __aux2_th; + u16 __cq_u_prod3; +#elif defined(__LITTLE_ENDIAN) + u16 __cq_u_prod3; + u16 __aux2_th; +#endif +}; + /* * iSCSI context region, used only in iSCSI */ @@ -696,7 +794,7 @@ struct ustorm_iscsi_st_context { struct regpair task_pbl_base; struct regpair tce_phy_addr; struct ustorm_iscsi_placement_db place_db; - u32 data_rcv_seq; + u32 reserved8; u32 rem_rcv_len; #if defined(__BIG_ENDIAN) u16 hdr_itt; @@ -713,8 +811,10 @@ struct ustorm_iscsi_st_context { #define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2) -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 u8 task_pdu_cache_index; u8 task_pbe_cache_index; #elif defined(__LITTLE_ENDIAN) @@ -725,8 +825,10 @@ struct ustorm_iscsi_st_context { #define USTORM_ISCSI_ST_CONTEXT_BMIDDLEOFPDU_SHIFT 0 #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE (0x1<<1) #define USTORM_ISCSI_ST_CONTEXT_BFENCECQE_SHIFT 1 -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x3F<<2) -#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC (0x1<<2) +#define USTORM_ISCSI_ST_CONTEXT_BRESETCRC_SHIFT 2 +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1 (0x1F<<3) +#define USTORM_ISCSI_ST_CONTEXT_RESERVED1_SHIFT 3 u8 hdr_second_byte_union; #endif #if defined(__BIG_ENDIAN) @@ -777,14 +879,14 @@ struct ustorm_iscsi_st_context { */ struct tstorm_tcp_st_context_section { u32 flags1; -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B (0xFFFFFF<<0) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_20B_SHIFT 0 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT (0xFFFFFF<<0) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_SRTT_SHIFT 0 #define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID (0x1<<24) #define TSTORM_TCP_ST_CONTEXT_SECTION_PAWS_INVALID_SHIFT 24 #define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS (0x1<<25) #define TSTORM_TCP_ST_CONTEXT_SECTION_TIMESTAMP_EXISTS_SHIFT 25 -#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS (0x1<<26) -#define TSTORM_TCP_ST_CONTEXT_SECTION_ISLE_EXISTS_SHIFT 26 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0 (0x1<<26) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED0_SHIFT 26 #define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD (0x1<<27) #define TSTORM_TCP_ST_CONTEXT_SECTION_STOP_RX_PAYLOAD_SHIFT 27 #define TSTORM_TCP_ST_CONTEXT_SECTION_KA_ENABLED (0x1<<28) @@ -793,11 +895,11 @@ struct tstorm_tcp_st_context_section { #define TSTORM_TCP_ST_CONTEXT_SECTION_FIRST_RTO_ESTIMATE_SHIFT 29 #define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN (0x1<<30) #define TSTORM_TCP_ST_CONTEXT_SECTION_MAX_SEG_RETRANSMIT_EN_SHIFT 30 -#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3 (0x1<<31) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RESERVED3_SHIFT 31 +#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN (0x1<<31) +#define TSTORM_TCP_ST_CONTEXT_SECTION_LAST_ISLE_HAS_FIN_SHIFT 31 u32 flags2; -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B (0xFFFFFF<<0) -#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_20B_SHIFT 0 +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION (0xFFFFFF<<0) +#define TSTORM_TCP_ST_CONTEXT_SECTION_RTT_VARIATION_SHIFT 0 #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN (0x1<<24) #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_EN_SHIFT 24 #define TSTORM_TCP_ST_CONTEXT_SECTION_DA_COUNTER_EN (0x1<<25) @@ -810,18 +912,18 @@ struct tstorm_tcp_st_context_section { #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L2_STATSTICS_SHIFT 28 #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS (0x1<<29) #define TSTORM_TCP_ST_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 29 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED (0x1<<30) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_SECOND_ISLE_DROPPED_SHIFT 30 -#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO (0x1<<31) -#define __TSTORM_TCP_ST_CONTEXT_SECTION_DONT_SUPPORT_OOO_SHIFT 31 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK (0x1<<30) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_RST_ATTACK_SHIFT 30 +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK (0x1<<31) +#define __TSTORM_TCP_ST_CONTEXT_SECTION_IN_WINDOW_SYN_ATTACK_SHIFT 31 #if defined(__BIG_ENDIAN) - u16 reserved_slowpath; - u8 tcp_sm_state_3b; - u8 rto_exp_3b; + u16 mss; + u8 tcp_sm_state; + u8 rto_exp; #elif defined(__LITTLE_ENDIAN) - u8 rto_exp_3b; - u8 tcp_sm_state_3b; - u16 reserved_slowpath; + u8 rto_exp; + u8 tcp_sm_state; + u16 mss; #endif u32 rcv_nxt; u32 timestamp_recent; @@ -846,11 +948,11 @@ struct tstorm_tcp_st_context_section { #if defined(__BIG_ENDIAN) u8 statistics_counter_id; u8 ooo_support_mode; - u8 snd_wnd_scale_4b; + u8 snd_wnd_scale; u8 dup_ack_count; #elif defined(__LITTLE_ENDIAN) u8 dup_ack_count; - u8 snd_wnd_scale_4b; + u8 snd_wnd_scale; u8 ooo_support_mode; u8 statistics_counter_id; #endif @@ -860,13 +962,21 @@ struct tstorm_tcp_st_context_section { u32 isle_start_seq; u32 isle_end_seq; #if defined(__BIG_ENDIAN) - u16 mss; + u16 second_isle_address; u16 recent_seg_wnd; #elif defined(__LITTLE_ENDIAN) u16 recent_seg_wnd; - u16 mss; + u16 second_isle_address; +#endif +#if defined(__BIG_ENDIAN) + u8 max_isles_ever_happened; + u8 isles_number; + u16 last_isle_address; +#elif defined(__LITTLE_ENDIAN) + u16 last_isle_address; + u8 isles_number; + u8 max_isles_ever_happened; #endif - u32 reserved4; u32 max_rt_time; #if defined(__BIG_ENDIAN) u16 lsb_mac_address; @@ -876,7 +986,7 @@ struct tstorm_tcp_st_context_section { u16 lsb_mac_address; #endif u32 msb_mac_address; - u32 reserved2; + u32 rightmost_received_seq; }; /* @@ -951,7 +1061,7 @@ struct tstorm_iscsi_st_context_section { u8 scratchpad_idx; struct iscsi_term_vars term_vars; #endif - u32 reserved2; + u32 process_nxt; }; /* @@ -1174,24 +1284,12 @@ struct xstorm_iscsi_ag_context { #endif #if defined(__BIG_ENDIAN) u8 cdu_reserved; - u8 agg_vars4; -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0) -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7 + u8 __agg_vars4; u8 agg_vars3; #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 u8 agg_vars2; #define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF (0x3<<0) #define __XSTORM_ISCSI_AG_CONTEXT_DQ_CF_SHIFT 0 @@ -1222,21 +1320,9 @@ struct xstorm_iscsi_ag_context { u8 agg_vars3; #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2 (0x3F<<0) #define XSTORM_ISCSI_AG_CONTEXT_PHYSICAL_QUEUE_NUM2_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF (0x3<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_SHIFT 6 - u8 agg_vars4; -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF (0x3<<0) -#define XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_SHIFT 0 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF (0x3<<2) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_SHIFT 2 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN (0x1<<4) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_EN_SHIFT 4 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN (0x1<<5) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX19_CF_EN_SHIFT 5 -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN (0x1<<6) -#define __XSTORM_ISCSI_AG_CONTEXT_R2TQ_PROD_CF_EN_SHIFT 6 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN (0x1<<7) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX21_CF_EN_SHIFT 7 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF (0x3<<6) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_TS_EN_CF_SHIFT 6 + u8 __agg_vars4; u8 cdu_reserved; #endif u32 more_to_send; @@ -1270,8 +1356,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4) -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4 +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 #define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) @@ -1286,8 +1372,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 u8 agg_val3_th; u8 agg_vars6; #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE6 (0x7<<0) @@ -1310,8 +1396,8 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AGG_VAL11_DECISION_RULE_SHIFT 0 #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG (0x1<<3) #define __XSTORM_ISCSI_AG_CONTEXT_AUX13_FLAG_SHIFT 3 -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF (0x3<<4) -#define XSTORM_ISCSI_AG_CONTEXT_AUX18_CF_SHIFT 4 +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF (0x3<<4) +#define __XSTORM_ISCSI_AG_CONTEXT_STORMS_SYNC_CF_SHIFT 4 #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3 (0x3<<6) #define XSTORM_ISCSI_AG_CONTEXT_DECISION_RULE3_SHIFT 6 #define XSTORM_ISCSI_AG_CONTEXT_AUX1_CF (0x3<<8) @@ -1326,14 +1412,14 @@ struct xstorm_iscsi_ag_context { #define __XSTORM_ISCSI_AG_CONTEXT_AUX11_FLAG_SHIFT 13 #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG (0x1<<14) #define __XSTORM_ISCSI_AG_CONTEXT_AUX12_FLAG_SHIFT 14 -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG (0x1<<15) -#define __XSTORM_ISCSI_AG_CONTEXT_AUX2_FLAG_SHIFT 15 +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN (0x1<<15) +#define __XSTORM_ISCSI_AG_CONTEXT_RX_WND_SCL_EN_SHIFT 15 #endif #if defined(__BIG_ENDIAN) u16 __agg_val11_th; - u16 __agg_val11; + u16 __gen_data; #elif defined(__LITTLE_ENDIAN) - u16 __agg_val11; + u16 __gen_data; u16 __agg_val11_th; #endif #if defined(__BIG_ENDIAN) @@ -1384,7 +1470,7 @@ struct xstorm_iscsi_ag_context { #endif u32 hq_cons_tcp_seq; u32 exp_stat_sn; - u32 agg_misc5; + u32 rst_seq_num; }; /* @@ -1478,12 +1564,12 @@ struct tstorm_iscsi_ag_context { #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7 +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 u8 state; #elif defined(__LITTLE_ENDIAN) u8 state; @@ -1496,63 +1582,63 @@ struct tstorm_iscsi_ag_context { #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 2 #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<3) #define TSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 3 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG (0x1<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX3_FLAG_SHIFT 6 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG (0x1<<7) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_FLAG_SHIFT 7 +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG (0x1<<7) +#define __TSTORM_ISCSI_AG_CONTEXT_ACK_ON_FIN_SENT_FLAG_SHIFT 7 u16 ulp_credit; #endif #if defined(__BIG_ENDIAN) u16 __agg_val4; u16 agg_vars2; -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11) -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11 -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12) -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13) -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN_SHIFT 15 #elif defined(__LITTLE_ENDIAN) u16 agg_vars2; -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG (0x1<<0) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_FLAG_SHIFT 0 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG (0x1<<1) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX6_FLAG_SHIFT 1 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF (0x3<<2) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_SHIFT 2 -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF (0x3<<4) -#define __TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_SHIFT 4 +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG (0x1<<0) +#define __TSTORM_ISCSI_AG_CONTEXT_MSL_TIMER_SET_FLAG_SHIFT 0 +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG (0x1<<1) +#define __TSTORM_ISCSI_AG_CONTEXT_FIN_SENT_FIRST_FLAG_SHIFT 1 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF (0x3<<2) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_SHIFT 2 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF (0x3<<4) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_SHIFT 4 #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF (0x3<<6) #define __TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_SHIFT 6 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF (0x3<<8) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_SHIFT 8 #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG (0x1<<10) #define __TSTORM_ISCSI_AG_CONTEXT_AUX7_FLAG_SHIFT 10 -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN (0x1<<11) -#define TSTORM_ISCSI_AG_CONTEXT_AUX3_CF_EN_SHIFT 11 -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN (0x1<<12) -#define TSTORM_ISCSI_AG_CONTEXT_AUX4_CF_EN_SHIFT 12 -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN (0x1<<13) -#define TSTORM_ISCSI_AG_CONTEXT_AUX5_CF_EN_SHIFT 13 +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN (0x1<<11) +#define __TSTORM_ISCSI_AG_CONTEXT_QUEUES_FLUSH_Q0_CF_EN_SHIFT 11 +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN (0x1<<12) +#define __TSTORM_ISCSI_AG_CONTEXT_RST_SENT_CF_EN_SHIFT 12 +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN (0x1<<13) +#define __TSTORM_ISCSI_AG_CONTEXT_WAKEUP_CALL_CF_EN_SHIFT 13 #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN (0x1<<14) #define TSTORM_ISCSI_AG_CONTEXT_AUX6_CF_EN_SHIFT 14 #define TSTORM_ISCSI_AG_CONTEXT_AUX7_CF_EN (0x1<<15) @@ -1562,100 +1648,6 @@ struct tstorm_iscsi_ag_context { struct tstorm_tcp_tcp_ag_context_section tcp; }; -/* - * The iscsi aggregative context of Cstorm - */ -struct cstorm_iscsi_ag_context { - u32 agg_vars1; -#define CSTORM_ISCSI_AG_CONTEXT_STATE (0xFF<<0) -#define CSTORM_ISCSI_AG_CONTEXT_STATE_SHIFT 0 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0 (0x1<<8) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM0_SHIFT 8 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1 (0x1<<9) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM1_SHIFT 9 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2 (0x1<<10) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM2_SHIFT 10 -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3 (0x1<<11) -#define __CSTORM_ISCSI_AG_CONTEXT_EXISTS_IN_QM3_SHIFT 11 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN (0x1<<12) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_SE_CF_EN_SHIFT 12 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN (0x1<<13) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED_ULP_RX_INV_CF_EN_SHIFT 13 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF (0x3<<14) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_SHIFT 14 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66 (0x3<<16) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED66_SHIFT 16 -#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN (0x1<<18) -#define __CSTORM_ISCSI_AG_CONTEXT_FIN_RECEIVED_CF_EN_SHIFT 18 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN (0x1<<19) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION0_CF_EN_SHIFT 19 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN (0x1<<20) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION1_CF_EN_SHIFT 20 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN (0x1<<21) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION2_CF_EN_SHIFT 21 -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN (0x1<<22) -#define __CSTORM_ISCSI_AG_CONTEXT_PENDING_COMPLETION3_CF_EN_SHIFT 22 -#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE (0x7<<23) -#define __CSTORM_ISCSI_AG_CONTEXT_REL_SEQ_RULE_SHIFT 23 -#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE (0x3<<26) -#define CSTORM_ISCSI_AG_CONTEXT_HQ_PROD_RULE_SHIFT 26 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52 (0x3<<28) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED52_SHIFT 28 -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53 (0x3<<30) -#define __CSTORM_ISCSI_AG_CONTEXT_RESERVED53_SHIFT 30 -#if defined(__BIG_ENDIAN) - u8 __aux1_th; - u8 __aux1_val; - u16 __agg_vars2; -#elif defined(__LITTLE_ENDIAN) - u16 __agg_vars2; - u8 __aux1_val; - u8 __aux1_th; -#endif - u32 rel_seq; - u32 rel_seq_th; -#if defined(__BIG_ENDIAN) - u16 hq_cons; - u16 hq_prod; -#elif defined(__LITTLE_ENDIAN) - u16 hq_prod; - u16 hq_cons; -#endif -#if defined(__BIG_ENDIAN) - u8 __reserved62; - u8 __reserved61; - u8 __reserved60; - u8 __reserved59; -#elif defined(__LITTLE_ENDIAN) - u8 __reserved59; - u8 __reserved60; - u8 __reserved61; - u8 __reserved62; -#endif -#if defined(__BIG_ENDIAN) - u16 __reserved64; - u16 __cq_u_prod0; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod0; - u16 __reserved64; -#endif - u32 __cq_u_prod1; -#if defined(__BIG_ENDIAN) - u16 __agg_vars3; - u16 __cq_u_prod2; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod2; - u16 __agg_vars3; -#endif -#if defined(__BIG_ENDIAN) - u16 __aux2_th; - u16 __cq_u_prod3; -#elif defined(__LITTLE_ENDIAN) - u16 __cq_u_prod3; - u16 __aux2_th; -#endif -}; - /* * The iscsi aggregative context of Ustorm */ @@ -1746,8 +1738,8 @@ struct ustorm_iscsi_ag_context { #define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 u8 decision_rule_enable_bits; @@ -1790,30 +1782,14 @@ struct ustorm_iscsi_ag_context { #define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_RULE_SHIFT 0 #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE (0x7<<3) #define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL3_RULE_SHIFT 3 -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) -#define __USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG (0x1<<6) +#define USTORM_ISCSI_AG_CONTEXT_AGG_VAL2_ARM_N_FLAG_SHIFT 6 #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1 (0x1<<7) #define __USTORM_ISCSI_AG_CONTEXT_RESERVED1_SHIFT 7 u16 __reserved2; #endif }; -/* - * Timers connection context - */ -struct iscsi_timers_block_context { - u32 __reserved_0; - u32 __reserved_1; - u32 __reserved_2; - u32 flags; -#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS (0x3<<0) -#define __ISCSI_TIMERS_BLOCK_CONTEXT_NUM_OF_ACTIVE_TIMERS_SHIFT 0 -#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG (0x1<<2) -#define ISCSI_TIMERS_BLOCK_CONTEXT_CONN_VALID_FLG_SHIFT 2 -#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0 (0x1FFFFFFF<<3) -#define __ISCSI_TIMERS_BLOCK_CONTEXT_RESERVED0_SHIFT 3 -}; - /* * Ethernet context section, shared in TOE, RDMA and ISCSI */ @@ -1963,7 +1939,7 @@ struct xstorm_tcp_context_section { #endif #if defined(__BIG_ENDIAN) u8 original_nagle_1b; - u8 ts_enabled_1b; + u8 ts_enabled; u16 tcp_params; #define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE (0xFF<<0) #define XSTORM_TCP_CONTEXT_SECTION_TOTAL_HEADER_SIZE_SHIFT 0 @@ -1973,8 +1949,8 @@ struct xstorm_tcp_context_section { #define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11) -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11 +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) @@ -1991,15 +1967,15 @@ struct xstorm_tcp_context_section { #define __XSTORM_TCP_CONTEXT_SECTION_ECN_ENABLED_SHIFT 9 #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED (0x1<<10) #define XSTORM_TCP_CONTEXT_SECTION_SACK_ENABLED_SHIFT 10 -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE (0x1<<11) -#define XSTORM_TCP_CONTEXT_SECTION_KA_STATE_SHIFT 11 +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV (0x1<<11) +#define XSTORM_TCP_CONTEXT_SECTION_SMALL_WIN_ADV_SHIFT 11 #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG (0x1<<12) #define XSTORM_TCP_CONTEXT_SECTION_FIN_SENT_FLAG_SHIFT 12 #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED (0x1<<13) #define XSTORM_TCP_CONTEXT_SECTION_WINDOW_SATURATED_SHIFT 13 #define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER (0x3<<14) #define XSTORM_TCP_CONTEXT_SECTION_SLOWPATH_QUEUES_FLUSH_COUNTER_SHIFT 14 - u8 ts_enabled_1b; + u8 ts_enabled; u8 original_nagle_1b; #endif #if defined(__BIG_ENDIAN) @@ -2030,8 +2006,8 @@ struct xstorm_common_context_section { #define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2) #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2 -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7) -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7 +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7) +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7 u8 ip_version_1b; #elif defined(__LITTLE_ENDIAN) u8 ip_version_1b; @@ -2042,8 +2018,8 @@ struct xstorm_common_context_section { #define XSTORM_COMMON_CONTEXT_SECTION_UPDATE_L4_STATSTICS_SHIFT 1 #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID (0x1F<<2) #define XSTORM_COMMON_CONTEXT_SECTION_STATISTICS_COUNTER_ID_SHIFT 2 -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0 (0x1<<7) -#define XSTORM_COMMON_CONTEXT_SECTION_RESERVED0_SHIFT 7 +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS (0x1<<7) +#define XSTORM_COMMON_CONTEXT_SECTION_DCB_EXISTS_SHIFT 7 u16 reserved; #endif }; @@ -2284,7 +2260,7 @@ struct iscsi_context { struct tstorm_iscsi_ag_context tstorm_ag_context; struct cstorm_iscsi_ag_context cstorm_ag_context; struct ustorm_iscsi_ag_context ustorm_ag_context; - struct iscsi_timers_block_context timers_context; + struct timers_block_context timers_context; struct regpair upb_context; struct xstorm_iscsi_st_context xstorm_st_context; struct regpair xpb_context; @@ -2434,16 +2410,16 @@ struct l5cm_packet_size { * l5cm connection parameters */ union l5cm_reduce_param_union { - u32 passive_side_scramble_key; - u32 pcs_id; + u32 opaque1; + u32 opaque2; }; /* * l5cm connection parameters */ struct l5cm_reduce_conn { - union l5cm_reduce_param_union param; - u32 isn; + union l5cm_reduce_param_union opaque1; + u32 opaque2; }; /* diff --git a/drivers/net/cnic_if.h b/drivers/net/cnic_if.h index 344c842d55aba180eaade74b45b4912b7facd8b8..0dbeaec4f03a6888ac22dc350c2c2e2e0c49001e 100644 --- a/drivers/net/cnic_if.h +++ b/drivers/net/cnic_if.h @@ -12,8 +12,8 @@ #ifndef CNIC_IF_H #define CNIC_IF_H -#define CNIC_MODULE_VERSION "2.1.3" -#define CNIC_MODULE_RELDATE "June 24, 2010" +#define CNIC_MODULE_VERSION "2.2.6" +#define CNIC_MODULE_RELDATE "Oct 12, 2010" #define CNIC_ULP_RDMA 0 #define CNIC_ULP_ISCSI 1 @@ -80,18 +80,15 @@ struct kcqe { #define DRV_CTL_IO_RD_CMD 0x102 #define DRV_CTL_CTX_WR_CMD 0x103 #define DRV_CTL_CTXTBL_WR_CMD 0x104 -#define DRV_CTL_COMPLETION_CMD 0x105 +#define DRV_CTL_RET_L5_SPQ_CREDIT_CMD 0x105 #define DRV_CTL_START_L2_CMD 0x106 #define DRV_CTL_STOP_L2_CMD 0x107 +#define DRV_CTL_RET_L2_SPQ_CREDIT_CMD 0x10c struct cnic_ctl_completion { u32 cid; }; -struct drv_ctl_completion { - u32 comp_count; -}; - struct cnic_ctl_info { int cmd; union { @@ -100,6 +97,10 @@ struct cnic_ctl_info { } data; }; +struct drv_ctl_spq_credit { + u32 credit_count; +}; + struct drv_ctl_io { u32 cid_addr; u32 offset; @@ -115,7 +116,7 @@ struct drv_ctl_l2_ring { struct drv_ctl_info { int cmd; union { - struct drv_ctl_completion comp; + struct drv_ctl_spq_credit credit; struct drv_ctl_io io; struct drv_ctl_l2_ring ring; char bytes[MAX_DRV_CTL_DATA]; @@ -138,6 +139,7 @@ struct cnic_irq { unsigned int vector; void *status_blk; u32 status_blk_num; + u32 status_blk_num2; u32 irq_flags; #define CNIC_IRQ_FL_MSIX 0x00000001 }; @@ -152,6 +154,7 @@ struct cnic_eth_dev { struct pci_dev *pdev; void __iomem *io_base; void __iomem *io_base2; + void *iro_arr; u32 ctx_tbl_offset; u32 ctx_tbl_len; @@ -160,7 +163,9 @@ struct cnic_eth_dev { u32 max_iscsi_conn; u32 max_fcoe_conn; u32 max_rdma_conn; - u32 reserved0[2]; + u32 fcoe_init_cid; + u16 iscsi_l2_client_id; + u16 iscsi_l2_cid; int num_irq; struct cnic_irq irq_arr[MAX_CNIC_VEC]; diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index e1f6156b3710e9888f779610ddb10a52fcfd5d9d..fec939f8f65f760cf31b7d4a1981a499124d1cba 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include MODULE_AUTHOR("Eugene Konev "); @@ -108,7 +108,7 @@ MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus"); #define CPMAC_RX_INT_CLEAR 0x019c #define CPMAC_MAC_INT_ENABLE 0x01a8 #define CPMAC_MAC_INT_CLEAR 0x01ac -#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4) +#define CPMAC_MAC_ADDR_LO(channel) (0x01b0 + (channel) * 4) #define CPMAC_MAC_ADDR_MID 0x01d0 #define CPMAC_MAC_ADDR_HI 0x01d4 #define CPMAC_MAC_HASH_LO 0x01d8 @@ -227,7 +227,7 @@ static void cpmac_dump_regs(struct net_device *dev) for (i = 0; i < CPMAC_REG_END; i += 4) { if (i % 16 == 0) { if (i) - printk("\n"); + pr_cont("\n"); printk(KERN_DEBUG "%s: reg[%p]:", dev->name, priv->regs + i); } @@ -262,7 +262,7 @@ static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb) for (i = 0; i < skb->len; i++) { if (i % 16 == 0) { if (i) - printk("\n"); + pr_cont("\n"); printk(KERN_DEBUG "%s: data[%p]:", dev->name, skb->data + i); } @@ -391,7 +391,7 @@ static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv, if (likely(skb)) { skb_put(desc->skb, desc->datalen); desc->skb->protocol = eth_type_trans(desc->skb, priv->dev); - desc->skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(desc->skb); priv->dev->stats.rx_packets++; priv->dev->stats.rx_bytes += desc->datalen; result = desc->skb; @@ -506,7 +506,7 @@ static int cpmac_poll(struct napi_struct *napi, int budget) "restart rx from a descriptor that's " "not free: %p\n", priv->dev->name, restart); - goto fatal_error; + goto fatal_error; } cpmac_write(priv->regs, CPMAC_RX_PTR(0), restart->mapping); @@ -873,7 +873,8 @@ static int cpmac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) return -EINVAL; } -static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) +static void cpmac_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) { struct cpmac_priv *priv = netdev_priv(dev); @@ -888,7 +889,8 @@ static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam ring->tx_pending = 1; } -static int cpmac_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ring) +static int cpmac_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *ring) { struct cpmac_priv *priv = netdev_priv(dev); @@ -1012,8 +1014,8 @@ static int cpmac_open(struct net_device *dev) priv->rx_head->prev->hw_next = (u32)0; - if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, - dev->name, dev))) { + res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED, dev->name, dev); + if (res) { if (netif_msg_drv(priv)) printk(KERN_ERR "%s: failed to obtain irq\n", dev->name); @@ -1133,7 +1135,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) } if (phy_id == PHY_MAX_ADDR) { - dev_err(&pdev->dev, "no PHY present, falling back to switch on MDIO bus 0\n"); + dev_err(&pdev->dev, "no PHY present, falling back " + "to switch on MDIO bus 0\n"); strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */ phy_id = pdev->id; } @@ -1169,9 +1172,10 @@ static int __devinit cpmac_probe(struct platform_device *pdev) priv->msg_enable = netif_msg_init(debug_level, 0xff); memcpy(dev->dev_addr, pdata->dev_addr, sizeof(pdata->dev_addr)); - snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); + snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, + mdio_bus_id, phy_id); - priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0, + priv->phy = phy_connect(dev, priv->phy_name, cpmac_adjust_link, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(priv->phy)) { @@ -1182,7 +1186,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) goto fail; } - if ((rc = register_netdev(dev))) { + rc = register_netdev(dev); + if (rc) { printk(KERN_ERR "cpmac: error %i registering device %s\n", rc, dev->name); goto fail; @@ -1248,11 +1253,13 @@ int __devinit cpmac_init(void) cpmac_mii->reset(cpmac_mii); - for (i = 0; i < 300; i++) - if ((mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE))) + for (i = 0; i < 300; i++) { + mask = cpmac_read(cpmac_mii->priv, CPMAC_MDIO_ALIVE); + if (mask) break; else msleep(10); + } mask &= 0x7fffffff; if (mask & (mask - 1)) { diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 4cd7f420766a4a9c7bde0007ba14393b74016ff3..ef67be59680f9cc2138d09e742a91c160f16f334 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -336,9 +336,6 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, int irq_vec_idx, const struct qset_params *p, int ntxq, struct net_device *dev, struct netdev_queue *netdevq); -int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, - unsigned char *data); -irqreturn_t t3_sge_intr_msix(int irq, void *cookie); extern struct workqueue_struct *cxgb3_wq; int t3_get_edc_fw(struct cphy *phy, int edc_idx, int size); diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index fe08a004b0ddeb57bec280e62adf37e0b76e23f8..5ccb77d078aa33ca0b4987f872a19a5bf91246c4 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h @@ -673,7 +673,6 @@ void t3_xgm_intr_enable(struct adapter *adapter, int idx); void t3_xgm_intr_disable(struct adapter *adapter, int idx); void t3_port_intr_enable(struct adapter *adapter, int idx); void t3_port_intr_disable(struct adapter *adapter, int idx); -void t3_port_intr_clear(struct adapter *adapter, int idx); int t3_slow_intr_handler(struct adapter *adapter); int t3_phy_intr_handler(struct adapter *adapter); @@ -689,14 +688,10 @@ int t3_check_tpsram_version(struct adapter *adapter); int t3_check_tpsram(struct adapter *adapter, const u8 *tp_ram, unsigned int size); int t3_set_proto_sram(struct adapter *adap, const u8 *data); -int t3_read_flash(struct adapter *adapter, unsigned int addr, - unsigned int nwords, u32 *data, int byte_oriented); int t3_load_fw(struct adapter *adapter, const u8 * fw_data, unsigned int size); int t3_get_fw_version(struct adapter *adapter, u32 *vers); int t3_check_fw_version(struct adapter *adapter); int t3_init_hw(struct adapter *adapter, u32 fw_params); -void mac_prep(struct cmac *mac, struct adapter *adapter, int index); -void early_hw_init(struct adapter *adapter, const struct adapter_info *ai); int t3_reset_adapter(struct adapter *adapter); int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, int reset); @@ -706,8 +701,6 @@ void t3_fatal_err(struct adapter *adapter); void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on); void t3_config_rss(struct adapter *adapter, unsigned int rss_config, const u8 * cpus, const u16 *rspq); -int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map); -int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask); int t3_cim_ctl_blk_read(struct adapter *adap, unsigned int addr, unsigned int n, unsigned int *valp); int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n, @@ -731,19 +724,12 @@ void t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode); int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, unsigned int nroutes); void t3_mc5_intr_handler(struct mc5 *mc5); -int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, unsigned int n, - u32 *buf); -int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh); -void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size); void t3_tp_set_offload_mode(struct adapter *adap, int enable); void t3_tp_get_mib_stats(struct adapter *adap, struct tp_mib_stats *tps); void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS], unsigned short alpha[NCCTRL_WIN], unsigned short beta[NCCTRL_WIN], unsigned short mtu_cap); -void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS]); -void t3_get_cong_cntl_tab(struct adapter *adap, - unsigned short incr[NMTUS][NCCTRL_WIN]); void t3_config_trace_filter(struct adapter *adapter, const struct trace_params *tp, int filter_index, int invert, int enable); @@ -769,10 +755,6 @@ int t3_sge_enable_ecntxt(struct adapter *adapter, unsigned int id, int enable); int t3_sge_disable_fl(struct adapter *adapter, unsigned int id); int t3_sge_disable_rspcntxt(struct adapter *adapter, unsigned int id); int t3_sge_disable_cqcntxt(struct adapter *adapter, unsigned int id); -int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4]); -int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4]); int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op, unsigned int credits); diff --git a/drivers/net/cxgb3/cxgb3_defs.h b/drivers/net/cxgb3/cxgb3_defs.h index 47e53769af5b7f074e45e07505be797263261458..920d918ed193256c0f218216304779abb092ef3d 100644 --- a/drivers/net/cxgb3/cxgb3_defs.h +++ b/drivers/net/cxgb3/cxgb3_defs.h @@ -43,8 +43,6 @@ void *cxgb_alloc_mem(unsigned long size); void cxgb_free_mem(void *addr); -void cxgb_neigh_update(struct neighbour *neigh); -void cxgb_redirect(struct dst_entry *old, struct dst_entry *new); /* * Map an ATID or STID to their entries in the corresponding TID tables. @@ -111,7 +109,6 @@ static inline struct t3c_tid_entry *lookup_atid(const struct tid_info *t, return &e->t3c_tid; } -int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n); int attach_t3cdev(struct t3cdev *dev); void detach_t3cdev(struct t3cdev *dev); #endif diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index f208712c0b90d6b675f1ef1179f5825ae9f9f911..a04ce6a5f637142a1aba4cb933c03bb8485cd5ec 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -1286,7 +1286,7 @@ static int cxgb_up(struct adapter *adap) /* * Release resources when all the ports and offloading have been stopped. */ -static void cxgb_down(struct adapter *adapter) +static void cxgb_down(struct adapter *adapter, int on_wq) { t3_sge_stop(adapter); spin_lock_irq(&adapter->work_lock); /* sync with PHY intr task */ @@ -1296,7 +1296,8 @@ static void cxgb_down(struct adapter *adapter) free_irq_resources(adapter); quiesce_rx(adapter); t3_sge_stop(adapter); - flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ + if (!on_wq) + flush_workqueue(cxgb3_wq);/* wait for external IRQ handler */ } static void schedule_chk_task(struct adapter *adap) @@ -1374,7 +1375,7 @@ static int offload_close(struct t3cdev *tdev) clear_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); if (!adapter->open_device_map) - cxgb_down(adapter); + cxgb_down(adapter, 0); cxgb3_offload_deactivate(adapter); return 0; @@ -1398,7 +1399,10 @@ static int cxgb_open(struct net_device *dev) "Could not initialize offload capabilities\n"); } - dev->real_num_tx_queues = pi->nqsets; + netif_set_real_num_tx_queues(dev, pi->nqsets); + err = netif_set_real_num_rx_queues(dev, pi->nqsets); + if (err) + return err; link_start(dev); t3_port_intr_enable(adapter, pi->port_id); netif_tx_start_all_queues(dev); @@ -1409,7 +1413,7 @@ static int cxgb_open(struct net_device *dev) return 0; } -static int cxgb_close(struct net_device *dev) +static int __cxgb_close(struct net_device *dev, int on_wq) { struct port_info *pi = netdev_priv(dev); struct adapter *adapter = pi->adapter; @@ -1436,12 +1440,17 @@ static int cxgb_close(struct net_device *dev) cancel_delayed_work_sync(&adapter->adap_check_task); if (!adapter->open_device_map) - cxgb_down(adapter); + cxgb_down(adapter, on_wq); cxgb3_event_notify(&adapter->tdev, OFFLOAD_PORT_DOWN, pi->port_id); return 0; } +static int cxgb_close(struct net_device *dev) +{ + return __cxgb_close(dev, 0); +} + static struct net_device_stats *cxgb_get_stats(struct net_device *dev) { struct port_info *pi = netdev_priv(dev); @@ -2864,7 +2873,7 @@ void t3_os_link_fault_handler(struct adapter *adapter, int port_id) spin_unlock(&adapter->work_lock); } -static int t3_adapter_error(struct adapter *adapter, int reset) +static int t3_adapter_error(struct adapter *adapter, int reset, int on_wq) { int i, ret = 0; @@ -2879,7 +2888,7 @@ static int t3_adapter_error(struct adapter *adapter, int reset) struct net_device *netdev = adapter->port[i]; if (netif_running(netdev)) - cxgb_close(netdev); + __cxgb_close(netdev, on_wq); } /* Stop SGE timers */ @@ -2950,7 +2959,7 @@ static void fatal_error_task(struct work_struct *work) int err = 0; rtnl_lock(); - err = t3_adapter_error(adapter, 1); + err = t3_adapter_error(adapter, 1, 1); if (!err) err = t3_reenable_adapter(adapter); if (!err) @@ -3000,7 +3009,7 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev, if (state == pci_channel_io_perm_failure) return PCI_ERS_RESULT_DISCONNECT; - ret = t3_adapter_error(adapter, 0); + ret = t3_adapter_error(adapter, 0, 0); /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index c6485b39eb0e630c67a5f91cd683ab7365362928..bcf07532953d3c7e9c7fb5fe1ead1c69ec3e63b5 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -60,11 +60,14 @@ static LIST_HEAD(adapter_list); static const unsigned int MAX_ATIDS = 64 * 1024; static const unsigned int ATID_BASE = 0x10000; +static void cxgb_neigh_update(struct neighbour *neigh); +static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new); + static inline int offload_activated(struct t3cdev *tdev) { const struct adapter *adapter = tdev2adap(tdev); - return (test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)); + return test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map); } /** @@ -1015,7 +1018,7 @@ EXPORT_SYMBOL(t3_register_cpl_handler); /* * T3CDEV's receive method. */ -int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n) +static int process_rx(struct t3cdev *dev, struct sk_buff **skbs, int n) { while (n--) { struct sk_buff *skb = *skbs++; @@ -1070,7 +1073,7 @@ static int is_offloading(struct net_device *dev) return 0; } -void cxgb_neigh_update(struct neighbour *neigh) +static void cxgb_neigh_update(struct neighbour *neigh) { struct net_device *dev = neigh->dev; @@ -1104,7 +1107,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e) tdev->send(tdev, skb); } -void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) +static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) { struct net_device *olddev, *newdev; struct tid_info *ti; diff --git a/drivers/net/cxgb3/mc5.c b/drivers/net/cxgb3/mc5.c index 3b5517b8fbde74a1131d932c890d0d5e3f39ab97..a8766fb2f9abbb23db2ba6c01cc4080d8d5575d5 100644 --- a/drivers/net/cxgb3/mc5.c +++ b/drivers/net/cxgb3/mc5.c @@ -374,44 +374,6 @@ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, return err; } -/* - * read_mc5_range - dump a part of the memory managed by MC5 - * @mc5: the MC5 handle - * @start: the start address for the dump - * @n: number of 72-bit words to read - * @buf: result buffer - * - * Read n 72-bit words from MC5 memory from the given start location. - */ -int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, - unsigned int n, u32 *buf) -{ - u32 read_cmd; - int err = 0; - struct adapter *adap = mc5->adapter; - - if (mc5->part_type == IDT75P52100) - read_cmd = IDT_CMD_READ; - else if (mc5->part_type == IDT75N43102) - read_cmd = IDT4_CMD_READ; - else - return -EINVAL; - - mc5_dbgi_mode_enable(mc5); - - while (n--) { - t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++); - if (mc5_cmd_write(adap, read_cmd)) { - err = -EIO; - break; - } - dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf); - buf += 3; - } - - mc5_dbgi_mode_disable(mc5); - return 0; -} #define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR) diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h index cb42353c9fdd49c3368c70fe6ced350463a1c761..6990f6c6522164a7e602903554f3c8e3ccde83fc 100644 --- a/drivers/net/cxgb3/regs.h +++ b/drivers/net/cxgb3/regs.h @@ -1997,6 +1997,10 @@ #define A_PL_RST 0x6f0 +#define S_FATALPERREN 4 +#define V_FATALPERREN(x) ((x) << S_FATALPERREN) +#define F_FATALPERREN V_FATALPERREN(1U) + #define S_CRSTWRM 1 #define V_CRSTWRM(x) ((x) << S_CRSTWRM) #define F_CRSTWRM V_CRSTWRM(1U) diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 8ff96c6f6de53304789a16de04a98ac86d1f7d15..5d72bda543894c3a990d959c8f7bcff17f270d08 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -1145,7 +1145,7 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb, cpl->len = htonl(skb->len); cntrl = V_TXPKT_INTF(pi->port_id); - if (vlan_tx_tag_present(skb) && pi->vlan_grp) + if (vlan_tx_tag_present(skb)) cntrl |= F_TXPKT_VLAN_VLD | V_TXPKT_VLAN(vlan_tx_tag_get(skb)); tso_info = V_LSO_MSS(skb_shinfo(skb)->gso_size); @@ -1279,7 +1279,7 @@ netdev_tx_t t3_eth_xmit(struct sk_buff *skb, struct net_device *dev) qs->port_stats[SGE_PSTAT_TX_CSUM]++; if (skb_shinfo(skb)->gso_size) qs->port_stats[SGE_PSTAT_TSO]++; - if (vlan_tx_tag_present(skb) && pi->vlan_grp) + if (vlan_tx_tag_present(skb)) qs->port_stats[SGE_PSTAT_VLANINS]++; /* @@ -2022,7 +2022,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq, qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_record_rx_queue(skb, qs - &adap->sge.qs[0]); if (unlikely(p->vlan_valid)) { @@ -2554,7 +2554,7 @@ static inline int handle_responses(struct adapter *adap, struct sge_rspq *q) * The MSI-X interrupt handler for an SGE response queue for the non-NAPI case * (i.e., response queue serviced in hard interrupt). */ -irqreturn_t t3_sge_intr_msix(int irq, void *cookie) +static irqreturn_t t3_sge_intr_msix(int irq, void *cookie) { struct sge_qset *qs = cookie; struct adapter *adap = qs->adap; @@ -3320,40 +3320,3 @@ void t3_sge_prep(struct adapter *adap, struct sge_params *p) spin_lock_init(&adap->sge.reg_lock); } - -/** - * t3_get_desc - dump an SGE descriptor for debugging purposes - * @qs: the queue set - * @qnum: identifies the specific queue (0..2: Tx, 3:response, 4..5: Rx) - * @idx: the descriptor index in the queue - * @data: where to dump the descriptor contents - * - * Dumps the contents of a HW descriptor of an SGE queue. Returns the - * size of the descriptor. - */ -int t3_get_desc(const struct sge_qset *qs, unsigned int qnum, unsigned int idx, - unsigned char *data) -{ - if (qnum >= 6) - return -EINVAL; - - if (qnum < 3) { - if (!qs->txq[qnum].desc || idx >= qs->txq[qnum].size) - return -EINVAL; - memcpy(data, &qs->txq[qnum].desc[idx], sizeof(struct tx_desc)); - return sizeof(struct tx_desc); - } - - if (qnum == 3) { - if (!qs->rspq.desc || idx >= qs->rspq.size) - return -EINVAL; - memcpy(data, &qs->rspq.desc[idx], sizeof(struct rsp_desc)); - return sizeof(struct rsp_desc); - } - - qnum -= 4; - if (!qs->fl[qnum].desc || idx >= qs->fl[qnum].size) - return -EINVAL; - memcpy(data, &qs->fl[qnum].desc[idx], sizeof(struct rx_desc)); - return sizeof(struct rx_desc); -} diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 427c451be1a78d64b6ed7ca4e710ce4fddee2192..3a6adf0b3e9d4689ff5130a435ae026eb44b30a8 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -34,6 +34,8 @@ #include "sge_defs.h" #include "firmware_exports.h" +static void t3_port_intr_clear(struct adapter *adapter, int idx); + /** * t3_wait_op_done_val - wait until an operation is completed * @adapter: the adapter performing the operation @@ -840,8 +842,8 @@ static int flash_wait_op(struct adapter *adapter, int attempts, int delay) * (i.e., big-endian), otherwise as 32-bit words in the platform's * natural endianess. */ -int t3_read_flash(struct adapter *adapter, unsigned int addr, - unsigned int nwords, u32 *data, int byte_oriented) +static int t3_read_flash(struct adapter *adapter, unsigned int addr, + unsigned int nwords, u32 *data, int byte_oriented) { int ret; @@ -1408,6 +1410,7 @@ static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg, fatal++; CH_ALERT(adapter, "%s (0x%x)\n", acts->msg, status & acts->mask); + status &= ~acts->mask; } else if (acts->msg) CH_WARN(adapter, "%s (0x%x)\n", acts->msg, status & acts->mask); @@ -1843,11 +1846,10 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx) t3_os_link_fault_handler(adap, idx); } - t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause); - if (cause & XGM_INTR_FATAL) t3_fatal_err(adap); + t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause); return cause != 0; } @@ -2111,7 +2113,7 @@ void t3_port_intr_disable(struct adapter *adapter, int idx) * Clear port-specific (i.e., MAC and PHY) interrupts for the given * adapter port. */ -void t3_port_intr_clear(struct adapter *adapter, int idx) +static void t3_port_intr_clear(struct adapter *adapter, int idx) { struct cphy *phy = &adap2pinfo(adapter, idx)->phy; @@ -2483,98 +2485,6 @@ int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op, return 0; } -/** - * t3_sge_read_context - read an SGE context - * @type: the context type - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE egress context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -static int t3_sge_read_context(unsigned int type, struct adapter *adapter, - unsigned int id, u32 data[4]) -{ - if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY) - return -EBUSY; - - t3_write_reg(adapter, A_SG_CONTEXT_CMD, - V_CONTEXT_CMD_OPCODE(0) | type | V_CONTEXT(id)); - if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, 0, - SG_CONTEXT_CMD_ATTEMPTS, 1)) - return -EIO; - data[0] = t3_read_reg(adapter, A_SG_CONTEXT_DATA0); - data[1] = t3_read_reg(adapter, A_SG_CONTEXT_DATA1); - data[2] = t3_read_reg(adapter, A_SG_CONTEXT_DATA2); - data[3] = t3_read_reg(adapter, A_SG_CONTEXT_DATA3); - return 0; -} - -/** - * t3_sge_read_ecntxt - read an SGE egress context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE egress context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= 65536) - return -EINVAL; - return t3_sge_read_context(F_EGRESS, adapter, id, data); -} - -/** - * t3_sge_read_cq - read an SGE CQ context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE CQ context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= 65536) - return -EINVAL; - return t3_sge_read_context(F_CQ, adapter, id, data); -} - -/** - * t3_sge_read_fl - read an SGE free-list context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE free-list context. The caller is responsible for ensuring - * only one context operation occurs at a time. - */ -int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= SGE_QSETS * 2) - return -EINVAL; - return t3_sge_read_context(F_FREELIST, adapter, id, data); -} - -/** - * t3_sge_read_rspq - read an SGE response queue context - * @adapter: the adapter - * @id: the context id - * @data: holds the retrieved context - * - * Read an SGE response queue context. The caller is responsible for - * ensuring only one context operation occurs at a time. - */ -int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4]) -{ - if (id >= SGE_QSETS) - return -EINVAL; - return t3_sge_read_context(F_RESPONSEQ, adapter, id, data); -} - /** * t3_config_rss - configure Rx packet steering * @adapter: the adapter @@ -2615,42 +2525,6 @@ void t3_config_rss(struct adapter *adapter, unsigned int rss_config, t3_write_reg(adapter, A_TP_RSS_CONFIG, rss_config); } -/** - * t3_read_rss - read the contents of the RSS tables - * @adapter: the adapter - * @lkup: holds the contents of the RSS lookup table - * @map: holds the contents of the RSS map table - * - * Reads the contents of the receive packet steering tables. - */ -int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map) -{ - int i; - u32 val; - - if (lkup) - for (i = 0; i < RSS_TABLE_SIZE; ++i) { - t3_write_reg(adapter, A_TP_RSS_LKP_TABLE, - 0xffff0000 | i); - val = t3_read_reg(adapter, A_TP_RSS_LKP_TABLE); - if (!(val & 0x80000000)) - return -EAGAIN; - *lkup++ = val; - *lkup++ = (val >> 8); - } - - if (map) - for (i = 0; i < RSS_TABLE_SIZE; ++i) { - t3_write_reg(adapter, A_TP_RSS_MAP_TABLE, - 0xffff0000 | i); - val = t3_read_reg(adapter, A_TP_RSS_MAP_TABLE); - if (!(val & 0x80000000)) - return -EAGAIN; - *map++ = val; - } - return 0; -} - /** * t3_tp_set_offload_mode - put TP in NIC/offload mode * @adap: the adapter @@ -2868,7 +2742,8 @@ static void tp_set_timers(struct adapter *adap, unsigned int core_clk) * * Set the receive coalescing size and PSH bit handling. */ -int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh) +static int t3_tp_set_coalescing_size(struct adapter *adap, + unsigned int size, int psh) { u32 val; @@ -2898,7 +2773,7 @@ int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh) * Set TP's max receive size. This is the limit that applies when * receive coalescing is disabled. */ -void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size) +static void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size) { t3_write_reg(adap, A_TP_PARA_REG7, V_PMMAXXFERLEN0(size) | V_PMMAXXFERLEN1(size)); @@ -3017,48 +2892,6 @@ void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS], } } -/** - * t3_read_hw_mtus - returns the values in the HW MTU table - * @adap: the adapter - * @mtus: where to store the HW MTU values - * - * Reads the HW MTU table. - */ -void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS]) -{ - int i; - - for (i = 0; i < NMTUS; ++i) { - unsigned int val; - - t3_write_reg(adap, A_TP_MTU_TABLE, 0xff000000 | i); - val = t3_read_reg(adap, A_TP_MTU_TABLE); - mtus[i] = val & 0x3fff; - } -} - -/** - * t3_get_cong_cntl_tab - reads the congestion control table - * @adap: the adapter - * @incr: where to store the alpha values - * - * Reads the additive increments programmed into the HW congestion - * control table. - */ -void t3_get_cong_cntl_tab(struct adapter *adap, - unsigned short incr[NMTUS][NCCTRL_WIN]) -{ - unsigned int mtu, w; - - for (mtu = 0; mtu < NMTUS; ++mtu) - for (w = 0; w < NCCTRL_WIN; ++w) { - t3_write_reg(adap, A_TP_CCTRL_TABLE, - 0xffff0000 | (mtu << 5) | w); - incr[mtu][w] = t3_read_reg(adap, A_TP_CCTRL_TABLE) & - 0x1fff; - } -} - /** * t3_tp_get_mib_stats - read TP's MIB counters * @adap: the adapter @@ -3223,15 +3056,6 @@ static int tp_init(struct adapter *adap, const struct tp_params *p) return busy; } -int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask) -{ - if (port_mask & ~((1 << adap->params.nports) - 1)) - return -EINVAL; - t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE | F_PORT0ACTIVE, - port_mask << S_PORT0ACTIVE); - return 0; -} - /* * Perform the bits of HW initialization that are dependent on the Tx * channels being used. @@ -3569,6 +3393,7 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params) t3_write_reg(adapter, A_PM1_TX_MODE, 0); chan_init_hw(adapter, adapter->params.chan_map); t3_sge_init(adapter, &adapter->params.sge); + t3_set_reg_field(adapter, A_PL_RST, 0, F_FATALPERREN); t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, calc_gpio_intr(adapter)); @@ -3682,11 +3507,11 @@ static void mc7_prep(struct adapter *adapter, struct mc7 *mc7, mc7->name = name; mc7->offset = base_addr - MC7_PMRX_BASE_ADDR; cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); - mc7->size = mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg); + mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg); mc7->width = G_WIDTH(cfg); } -void mac_prep(struct cmac *mac, struct adapter *adapter, int index) +static void mac_prep(struct cmac *mac, struct adapter *adapter, int index) { u16 devid; @@ -3706,7 +3531,8 @@ void mac_prep(struct cmac *mac, struct adapter *adapter, int index) } } -void early_hw_init(struct adapter *adapter, const struct adapter_info *ai) +static void early_hw_init(struct adapter *adapter, + const struct adapter_info *ai) { u32 val = V_PORTSPEED(is_10G(adapter) ? 3 : 2); diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h index 6e562c0dad7dee0a309b87a0e7cec03a91cf69ec..eaa49e4119f146c047903a37dfda408086910faa 100644 --- a/drivers/net/cxgb4/cxgb4.h +++ b/drivers/net/cxgb4/cxgb4.h @@ -463,6 +463,8 @@ struct sge { u8 counter_val[SGE_NCOUNTERS]; unsigned int starve_thres; u8 idma_state[2]; + unsigned int egr_start; + unsigned int ingr_start; void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */ struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */ DECLARE_BITMAP(starving_fl, MAX_EGRQ); @@ -590,7 +592,6 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id); void t4_os_link_changed(struct adapter *adap, int port_id, int link_stat); void *t4_alloc_mem(size_t size); -void t4_free_mem(void *addr); void t4_free_sge_resources(struct adapter *adap); irq_handler_t t4_intr_handler(struct adapter *adap); @@ -649,7 +650,6 @@ static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd, void t4_intr_enable(struct adapter *adapter); void t4_intr_disable(struct adapter *adapter); -void t4_intr_clear(struct adapter *adapter); int t4_slow_intr_handler(struct adapter *adapter); int t4_wait_dev_ready(struct adapter *adap); @@ -662,24 +662,16 @@ int t4_check_fw_version(struct adapter *adapter); int t4_prep_adapter(struct adapter *adapter); int t4_port_init(struct adapter *adap, int mbox, int pf, int vf); void t4_fatal_err(struct adapter *adapter); -int t4_set_trace_filter(struct adapter *adapter, const struct trace_params *tp, - int filter_index, int enable); -void t4_get_trace_filter(struct adapter *adapter, struct trace_params *tp, - int filter_index, int *enabled); int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid, int start, int n, const u16 *rspq, unsigned int nrspq); int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, unsigned int flags); -int t4_read_rss(struct adapter *adapter, u16 *entries); int t4_mc_read(struct adapter *adap, u32 addr, __be32 *data, u64 *parity); int t4_edc_read(struct adapter *adap, int idx, u32 addr, __be32 *data, u64 *parity); void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p); -void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p); - void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log); -void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st); void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, struct tp_tcp_stats *v6); void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, @@ -709,8 +701,6 @@ int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf, int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac, unsigned int *rss_size); -int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, - unsigned int vf, unsigned int viid); int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid, int mtu, int promisc, int all_multi, int bcast, int vlanex, bool sleep_ok); @@ -729,9 +719,6 @@ int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, u16 *valp); int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr, unsigned int mmd, unsigned int reg, u16 val); -int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start, - unsigned int pf, unsigned int vf, unsigned int iqid, - unsigned int fl0id, unsigned int fl1id); int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int iqtype, unsigned int iqid, unsigned int fl0id, unsigned int fl1id); diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index e2bf10d90add64cb445545c570df20021b75d326..87054e0a57467841be71bcb3e3cfc7517c54bbe8 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -175,16 +175,26 @@ enum { static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { CH_DEVICE(0xa000, 0), /* PE10K */ - CH_DEVICE(0x4001, 0), - CH_DEVICE(0x4002, 0), - CH_DEVICE(0x4003, 0), - CH_DEVICE(0x4004, 0), - CH_DEVICE(0x4005, 0), - CH_DEVICE(0x4006, 0), - CH_DEVICE(0x4007, 0), - CH_DEVICE(0x4008, 0), - CH_DEVICE(0x4009, 0), - CH_DEVICE(0x400a, 0), + CH_DEVICE(0x4001, -1), + CH_DEVICE(0x4002, -1), + CH_DEVICE(0x4003, -1), + CH_DEVICE(0x4004, -1), + CH_DEVICE(0x4005, -1), + CH_DEVICE(0x4006, -1), + CH_DEVICE(0x4007, -1), + CH_DEVICE(0x4008, -1), + CH_DEVICE(0x4009, -1), + CH_DEVICE(0x400a, -1), + CH_DEVICE(0x4401, 4), + CH_DEVICE(0x4402, 4), + CH_DEVICE(0x4403, 4), + CH_DEVICE(0x4404, 4), + CH_DEVICE(0x4405, 4), + CH_DEVICE(0x4406, 4), + CH_DEVICE(0x4407, 4), + CH_DEVICE(0x4408, 4), + CH_DEVICE(0x4409, 4), + CH_DEVICE(0x440a, 4), { 0, } }; @@ -423,10 +433,11 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, if (likely(opcode == CPL_SGE_EGR_UPDATE)) { const struct cpl_sge_egr_update *p = (void *)rsp; unsigned int qid = EGR_QID(ntohl(p->opcode_qid)); - struct sge_txq *txq = q->adap->sge.egr_map[qid]; + struct sge_txq *txq; + txq = q->adap->sge.egr_map[qid - q->adap->sge.egr_start]; txq->restarts++; - if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) { + if ((u8 *)txq < (u8 *)q->adap->sge.ofldtxq) { struct sge_eth_txq *eq; eq = container_of(txq, struct sge_eth_txq, q); @@ -657,6 +668,15 @@ static int setup_rss(struct adapter *adap) return 0; } +/* + * Return the channel of the ingress queue with the given qid. + */ +static unsigned int rxq_to_chan(const struct sge *p, unsigned int qid) +{ + qid -= p->ingr_start; + return netdev2pinfo(p->ingr_map[qid]->netdev)->tx_chan; +} + /* * Wait until all NAPI handlers are descheduled. */ @@ -860,7 +880,7 @@ void *t4_alloc_mem(size_t size) /* * Free memory allocated through alloc_mem(). */ -void t4_free_mem(void *addr) +static void t4_free_mem(void *addr) { if (is_vmalloc_addr(addr)) vfree(addr); @@ -1671,27 +1691,41 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) return 0; } -/* - * Translate a physical EEPROM address to virtual. The first 1K is accessed - * through virtual addresses starting at 31K, the rest is accessed through - * virtual addresses starting at 0. This mapping is correct only for PF0. +/** + * eeprom_ptov - translate a physical EEPROM address to virtual + * @phys_addr: the physical EEPROM address + * @fn: the PCI function number + * @sz: size of function-specific area + * + * Translate a physical EEPROM address to virtual. The first 1K is + * accessed through virtual addresses starting at 31K, the rest is + * accessed through virtual addresses starting at 0. + * + * The mapping is as follows: + * [0..1K) -> [31K..32K) + * [1K..1K+A) -> [31K-A..31K) + * [1K+A..ES) -> [0..ES-A-1K) + * + * where A = @fn * @sz, and ES = EEPROM size. */ -static int eeprom_ptov(unsigned int phys_addr) +static int eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz) { + fn *= sz; if (phys_addr < 1024) return phys_addr + (31 << 10); + if (phys_addr < 1024 + fn) + return 31744 - fn + phys_addr - 1024; if (phys_addr < EEPROMSIZE) - return phys_addr - 1024; + return phys_addr - 1024 - fn; return -EINVAL; } /* * The next two routines implement eeprom read/write from physical addresses. - * The physical->virtual translation is correct only for PF0. */ static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v) { - int vaddr = eeprom_ptov(phys_addr); + int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); if (vaddr >= 0) vaddr = pci_read_vpd(adap->pdev, vaddr, sizeof(u32), v); @@ -1700,7 +1734,7 @@ static int eeprom_rd_phys(struct adapter *adap, unsigned int phys_addr, u32 *v) static int eeprom_wr_phys(struct adapter *adap, unsigned int phys_addr, u32 v) { - int vaddr = eeprom_ptov(phys_addr); + int vaddr = eeprom_ptov(phys_addr, adap->fn, EEPROMPFSIZE); if (vaddr >= 0) vaddr = pci_write_vpd(adap->pdev, vaddr, sizeof(u32), &v); @@ -1743,6 +1777,14 @@ static int set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, aligned_offset = eeprom->offset & ~3; aligned_len = (eeprom->len + (eeprom->offset & 3) + 3) & ~3; + if (adapter->fn > 0) { + u32 start = 1024 + adapter->fn * EEPROMPFSIZE; + + if (aligned_offset < start || + aligned_offset + aligned_len > start + EEPROMPFSIZE) + return -EPERM; + } + if (aligned_offset != eeprom->offset || aligned_len != eeprom->len) { /* * RMW possibly needed for first or last words. @@ -2165,8 +2207,8 @@ static void mk_tid_release(struct sk_buff *skb, unsigned int chan, * Queue a TID release request and if necessary schedule a work queue to * process it. */ -void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, - unsigned int tid) +static void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, + unsigned int tid) { void **p = &t->tid_tab[tid]; struct adapter *adap = container_of(t, struct adapter, tids); @@ -2181,7 +2223,6 @@ void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, } spin_unlock_bh(&adap->tid_release_lock); } -EXPORT_SYMBOL(cxgb4_queue_tid_release); /* * Process the list of pending TID release requests. @@ -2305,7 +2346,7 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid, req->peer_port = htons(0); req->local_ip = sip; req->peer_ip = htonl(0); - chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan; + chan = rxq_to_chan(&adap->sge, queue); req->opt0 = cpu_to_be64(TX_CHAN(chan)); req->opt1 = cpu_to_be64(CONN_POLICY_ASK | SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); @@ -2313,48 +2354,6 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid, } EXPORT_SYMBOL(cxgb4_create_server); -/** - * cxgb4_create_server6 - create an IPv6 server - * @dev: the device - * @stid: the server TID - * @sip: local IPv6 address to bind server to - * @sport: the server's TCP port - * @queue: queue to direct messages from this server to - * - * Create an IPv6 server for the given port and address. - * Returns <0 on error and one of the %NET_XMIT_* values on success. - */ -int cxgb4_create_server6(const struct net_device *dev, unsigned int stid, - const struct in6_addr *sip, __be16 sport, - unsigned int queue) -{ - unsigned int chan; - struct sk_buff *skb; - struct adapter *adap; - struct cpl_pass_open_req6 *req; - - skb = alloc_skb(sizeof(*req), GFP_KERNEL); - if (!skb) - return -ENOMEM; - - adap = netdev2adap(dev); - req = (struct cpl_pass_open_req6 *)__skb_put(skb, sizeof(*req)); - INIT_TP_WR(req, 0); - OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ6, stid)); - req->local_port = sport; - req->peer_port = htons(0); - req->local_ip_hi = *(__be64 *)(sip->s6_addr); - req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8); - req->peer_ip_hi = cpu_to_be64(0); - req->peer_ip_lo = cpu_to_be64(0); - chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan; - req->opt0 = cpu_to_be64(TX_CHAN(chan)); - req->opt1 = cpu_to_be64(CONN_POLICY_ASK | - SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); - return t4_mgmt_tx(adap, skb); -} -EXPORT_SYMBOL(cxgb4_create_server6); - /** * cxgb4_best_mtu - find the entry in the MTU table closest to an MTU * @mtus: the HW MTU table @@ -2414,25 +2413,6 @@ unsigned int cxgb4_port_idx(const struct net_device *dev) } EXPORT_SYMBOL(cxgb4_port_idx); -/** - * cxgb4_netdev_by_hwid - return the net device of a HW port - * @pdev: identifies the adapter - * @id: the HW port id - * - * Return the net device associated with the interface with the given HW - * id. - */ -struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id) -{ - const struct adapter *adap = pci_get_drvdata(pdev); - - if (!adap || id >= NCHAN) - return NULL; - id = adap->chan_map[id]; - return id < MAX_NPORTS ? adap->port[id] : NULL; -} -EXPORT_SYMBOL(cxgb4_netdev_by_hwid); - void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4, struct tp_tcp_stats *v6) { @@ -2722,7 +2702,10 @@ static int cxgb_open(struct net_device *dev) return err; } - dev->real_num_tx_queues = pi->nqsets; + netif_set_real_num_tx_queues(dev, pi->nqsets); + err = netif_set_real_num_rx_queues(dev, pi->nqsets); + if (err) + return err; err = link_start(dev); if (!err) netif_tx_start_all_queues(dev); @@ -3062,12 +3045,16 @@ static int adap_init0(struct adapter *adap) params[2] = FW_PARAM_PFVF(L2T_END); params[3] = FW_PARAM_PFVF(FILTER_START); params[4] = FW_PARAM_PFVF(FILTER_END); - ret = t4_query_params(adap, adap->fn, adap->fn, 0, 5, params, val); + params[5] = FW_PARAM_PFVF(IQFLINT_START); + params[6] = FW_PARAM_PFVF(EQ_START); + ret = t4_query_params(adap, adap->fn, adap->fn, 0, 7, params, val); if (ret < 0) goto bye; port_vec = val[0]; adap->tids.ftid_base = val[3]; adap->tids.nftids = val[4] - val[3] + 1; + adap->sge.ingr_start = val[5]; + adap->sge.egr_start = val[6]; if (c.ofldcaps) { /* query offload-related parameters */ @@ -3815,7 +3802,7 @@ static void __devexit remove_one(struct pci_dev *pdev) pci_disable_device(pdev); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); - } else if (PCI_FUNC(pdev->devfn) > 0) + } else pci_release_regions(pdev); } diff --git a/drivers/net/cxgb4/cxgb4_uld.h b/drivers/net/cxgb4/cxgb4_uld.h index 85d74e751ce00b33d88971f030a73771d2f7f2a4..1b48c0170145a04abe457d10ac0cb326f17d1518 100644 --- a/drivers/net/cxgb4/cxgb4_uld.h +++ b/drivers/net/cxgb4/cxgb4_uld.h @@ -139,16 +139,11 @@ int cxgb4_alloc_stid(struct tid_info *t, int family, void *data); void cxgb4_free_atid(struct tid_info *t, unsigned int atid); void cxgb4_free_stid(struct tid_info *t, unsigned int stid, int family); void cxgb4_remove_tid(struct tid_info *t, unsigned int qid, unsigned int tid); -void cxgb4_queue_tid_release(struct tid_info *t, unsigned int chan, - unsigned int tid); struct in6_addr; int cxgb4_create_server(const struct net_device *dev, unsigned int stid, __be32 sip, __be16 sport, unsigned int queue); -int cxgb4_create_server6(const struct net_device *dev, unsigned int stid, - const struct in6_addr *sip, __be16 sport, - unsigned int queue); static inline void set_wr_txq(struct sk_buff *skb, int prio, int queue) { @@ -233,7 +228,6 @@ int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb); unsigned int cxgb4_port_chan(const struct net_device *dev); unsigned int cxgb4_port_viid(const struct net_device *dev); unsigned int cxgb4_port_idx(const struct net_device *dev); -struct net_device *cxgb4_netdev_by_hwid(struct pci_dev *pdev, unsigned int id); unsigned int cxgb4_best_mtu(const unsigned short *mtus, unsigned short mtu, unsigned int *idx); void cxgb4_get_tcp_stats(struct pci_dev *pdev, struct tp_tcp_stats *v4, diff --git a/drivers/net/cxgb4/l2t.c b/drivers/net/cxgb4/l2t.c index e8f0f55e9d08e7c537a129f271b34891e5d282c2..a2d323c473f8bd5789e75b0a6ae504115347e065 100644 --- a/drivers/net/cxgb4/l2t.c +++ b/drivers/net/cxgb4/l2t.c @@ -481,40 +481,6 @@ void t4_l2t_update(struct adapter *adap, struct neighbour *neigh) handle_failed_resolution(adap, arpq); } -/* - * Allocate an L2T entry for use by a switching rule. Such entries need to be - * explicitly freed and while busy they are not on any hash chain, so normal - * address resolution updates do not see them. - */ -struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d) -{ - struct l2t_entry *e; - - write_lock_bh(&d->lock); - e = alloc_l2e(d); - if (e) { - spin_lock(&e->lock); /* avoid race with t4_l2t_free */ - e->state = L2T_STATE_SWITCHING; - atomic_set(&e->refcnt, 1); - spin_unlock(&e->lock); - } - write_unlock_bh(&d->lock); - return e; -} - -/* - * Sets/updates the contents of a switching L2T entry that has been allocated - * with an earlier call to @t4_l2t_alloc_switching. - */ -int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, - u8 port, u8 *eth_addr) -{ - e->vlan = vlan; - e->lport = port; - memcpy(e->dmac, eth_addr, ETH_ALEN); - return write_l2e(adap, e, 0); -} - struct l2t_data *t4_init_l2t(void) { int i; diff --git a/drivers/net/cxgb4/l2t.h b/drivers/net/cxgb4/l2t.h index 643f27ed3cf448c3816c9a9dfb770ef0a639f473..7bd8f42378ff19b3b659092fcf98de8c31c60bce 100644 --- a/drivers/net/cxgb4/l2t.h +++ b/drivers/net/cxgb4/l2t.h @@ -100,9 +100,6 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh, unsigned int priority); void t4_l2t_update(struct adapter *adap, struct neighbour *neigh); -struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *d); -int t4_l2t_set_switching(struct adapter *adap, struct l2t_entry *e, u16 vlan, - u8 port, u8 *eth_addr); struct l2t_data *t4_init_l2t(void); void do_l2t_write_rpl(struct adapter *p, const struct cpl_l2t_write_rpl *rpl); diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c index bf38cfc575655650b46038f9722170c801f75070..9967f3debce7e1010bd6ff58df5d6ad2060543d3 100644 --- a/drivers/net/cxgb4/sge.c +++ b/drivers/net/cxgb4/sge.c @@ -557,7 +557,8 @@ out: cred = q->avail - cred; if (unlikely(fl_starving(q))) { smp_wmb(); - set_bit(q->cntxt_id, adap->sge.starving_fl); + set_bit(q->cntxt_id - adap->sge.egr_start, + adap->sge.starving_fl); } return cred; @@ -974,7 +975,7 @@ out_free: dev_kfree_skb(skb); } cpl->ctrl0 = htonl(TXPKT_OPCODE(CPL_TX_PKT_XT) | - TXPKT_INTF(pi->tx_chan) | TXPKT_PF(0)); + TXPKT_INTF(pi->tx_chan) | TXPKT_PF(adap->fn)); cpl->pack = htons(0); cpl->len = htons(skb->len); cpl->ctrl1 = cpu_to_be64(cntrl); @@ -1213,7 +1214,8 @@ static void txq_stop_maperr(struct sge_ofld_txq *q) { q->mapping_err++; q->q.stops++; - set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr); + set_bit(q->q.cntxt_id - q->adap->sge.egr_start, + q->adap->sge.txq_maperr); } /** @@ -1603,7 +1605,7 @@ int t4_ethrx_handler(struct sge_rspq *q, const __be64 *rsp, rxq->stats.rx_cso++; } } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; @@ -1835,6 +1837,7 @@ static unsigned int process_intrq(struct adapter *adap) if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) { unsigned int qid = ntohl(rc->pldbuflen_qid); + qid -= adap->sge.ingr_start; napi_schedule(&adap->sge.ingr_map[qid]->napi); } @@ -2050,14 +2053,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq, /* set offset to -1 to distinguish ingress queues without FL */ iq->offset = fl ? 0 : -1; - adap->sge.ingr_map[iq->cntxt_id] = iq; + adap->sge.ingr_map[iq->cntxt_id - adap->sge.ingr_start] = iq; if (fl) { fl->cntxt_id = ntohs(c.fl0id); fl->avail = fl->pend_cred = 0; fl->pidx = fl->cidx = 0; fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0; - adap->sge.egr_map[fl->cntxt_id] = fl; + adap->sge.egr_map[fl->cntxt_id - adap->sge.egr_start] = fl; refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL); } return 0; @@ -2087,7 +2090,7 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id) q->stops = q->restarts = 0; q->stat = (void *)&q->desc[q->size]; q->cntxt_id = id; - adap->sge.egr_map[id] = q; + adap->sge.egr_map[id - adap->sge.egr_start] = q; } int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, @@ -2259,7 +2262,7 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq, { unsigned int fl_id = fl ? fl->cntxt_id : 0xffff; - adap->sge.ingr_map[rq->cntxt_id] = NULL; + adap->sge.ingr_map[rq->cntxt_id - adap->sge.ingr_start] = NULL; t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP, rq->cntxt_id, fl_id, 0xffff); dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len, diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index 9e1a4b49b47a56821851d065eb1e3e6f64cbb86b..bb813d94aea8ef5ae11db63ce6ac795fd0a62c39 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c @@ -120,30 +120,6 @@ static void t4_read_indirect(struct adapter *adap, unsigned int addr_reg, } } -#if 0 -/** - * t4_write_indirect - write indirectly addressed registers - * @adap: the adapter - * @addr_reg: register holding the indirect addresses - * @data_reg: register holding the value for the indirect registers - * @vals: values to write - * @nregs: how many indirect registers to write - * @start_idx: address of first indirect register to write - * - * Writes a sequential block of registers that are accessed indirectly - * through an address/data register pair. - */ -static void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, - unsigned int data_reg, const u32 *vals, - unsigned int nregs, unsigned int start_idx) -{ - while (nregs--) { - t4_write_reg(adap, addr_reg, start_idx++); - t4_write_reg(adap, data_reg, *vals++); - } -} -#endif - /* * Get the reply to a mailbox command and store it in @rpl in big-endian order. */ @@ -1559,44 +1535,6 @@ void t4_intr_disable(struct adapter *adapter) t4_set_reg_field(adapter, PL_INT_MAP0, 1 << pf, 0); } -/** - * t4_intr_clear - clear all interrupts - * @adapter: the adapter whose interrupts should be cleared - * - * Clears all interrupts. The caller must be a PCI function managing - * global interrupts. - */ -void t4_intr_clear(struct adapter *adapter) -{ - static const unsigned int cause_reg[] = { - SGE_INT_CAUSE1, SGE_INT_CAUSE2, SGE_INT_CAUSE3, - PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS, - PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS, - PCIE_NONFAT_ERR, PCIE_INT_CAUSE, - MC_INT_CAUSE, - MA_INT_WRAP_STATUS, MA_PARITY_ERROR_STATUS, MA_INT_CAUSE, - EDC_INT_CAUSE, EDC_REG(EDC_INT_CAUSE, 1), - CIM_HOST_INT_CAUSE, CIM_HOST_UPACC_INT_CAUSE, - MYPF_REG(CIM_PF_HOST_INT_CAUSE), - TP_INT_CAUSE, - ULP_RX_INT_CAUSE, ULP_TX_INT_CAUSE, - PM_RX_INT_CAUSE, PM_TX_INT_CAUSE, - MPS_RX_PERR_INT_CAUSE, - CPL_INTR_CAUSE, - MYPF_REG(PL_PF_INT_CAUSE), - PL_PL_INT_CAUSE, - LE_DB_INT_CAUSE, - }; - - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(cause_reg); ++i) - t4_write_reg(adapter, cause_reg[i], 0xffffffff); - - t4_write_reg(adapter, PL_INT_CAUSE, GLBL_INTR_MASK); - (void) t4_read_reg(adapter, PL_INT_CAUSE); /* flush */ -} - /** * hash_mac_addr - return the hash value of a MAC address * @addr: the 48-bit Ethernet MAC address @@ -1709,36 +1647,6 @@ int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode, return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL); } -/* Read an RSS table row */ -static int rd_rss_row(struct adapter *adap, int row, u32 *val) -{ - t4_write_reg(adap, TP_RSS_LKP_TABLE, 0xfff00000 | row); - return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE, LKPTBLROWVLD, 1, - 5, 0, val); -} - -/** - * t4_read_rss - read the contents of the RSS mapping table - * @adapter: the adapter - * @map: holds the contents of the RSS mapping table - * - * Reads the contents of the RSS hash->queue mapping table. - */ -int t4_read_rss(struct adapter *adapter, u16 *map) -{ - u32 val; - int i, ret; - - for (i = 0; i < RSS_NENTRIES / 2; ++i) { - ret = rd_rss_row(adapter, i, &val); - if (ret) - return ret; - *map++ = LKPTBLQUEUE0_GET(val); - *map++ = LKPTBLQUEUE1_GET(val); - } - return 0; -} - /** * t4_tp_get_tcp_stats - read TP's TCP MIB counters * @adap: the adapter @@ -1778,29 +1686,6 @@ void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, #undef STAT_IDX } -/** - * t4_tp_get_err_stats - read TP's error MIB counters - * @adap: the adapter - * @st: holds the counter values - * - * Returns the values of TP's error counters. - */ -void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st) -{ - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->macInErrs, - 12, TP_MIB_MAC_IN_ERR_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlCongDrops, - 8, TP_MIB_TNL_CNG_DROP_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tnlTxDrops, - 4, TP_MIB_TNL_DROP_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->ofldVlanDrops, - 4, TP_MIB_OFD_VLN_DROP_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, st->tcp6InErrs, - 4, TP_MIB_TCP_V6IN_ERR_0); - t4_read_indirect(adap, TP_MIB_INDEX, TP_MIB_DATA, &st->ofldNoNeigh, - 2, TP_MIB_OFD_ARP_DROP); -} - /** * t4_read_mtu_tbl - returns the values in the HW path MTU table * @adap: the adapter @@ -1915,122 +1800,6 @@ void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, } } -/** - * t4_set_trace_filter - configure one of the tracing filters - * @adap: the adapter - * @tp: the desired trace filter parameters - * @idx: which filter to configure - * @enable: whether to enable or disable the filter - * - * Configures one of the tracing filters available in HW. If @enable is - * %0 @tp is not examined and may be %NULL. - */ -int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp, - int idx, int enable) -{ - int i, ofst = idx * 4; - u32 data_reg, mask_reg, cfg; - u32 multitrc = TRCMULTIFILTER; - - if (!enable) { - t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0); - goto out; - } - - if (tp->port > 11 || tp->invert > 1 || tp->skip_len > 0x1f || - tp->skip_ofst > 0x1f || tp->min_len > 0x1ff || - tp->snap_len > 9600 || (idx && tp->snap_len > 256)) - return -EINVAL; - - if (tp->snap_len > 256) { /* must be tracer 0 */ - if ((t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 4) | - t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 8) | - t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + 12)) & TFEN) - return -EINVAL; /* other tracers are enabled */ - multitrc = 0; - } else if (idx) { - i = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B); - if (TFCAPTUREMAX_GET(i) > 256 && - (t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A) & TFEN)) - return -EINVAL; - } - - /* stop the tracer we'll be changing */ - t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, 0); - - /* disable tracing globally if running in the wrong single/multi mode */ - cfg = t4_read_reg(adap, MPS_TRC_CFG); - if ((cfg & TRCEN) && multitrc != (cfg & TRCMULTIFILTER)) { - t4_write_reg(adap, MPS_TRC_CFG, cfg ^ TRCEN); - t4_read_reg(adap, MPS_TRC_CFG); /* flush */ - msleep(1); - if (!(t4_read_reg(adap, MPS_TRC_CFG) & TRCFIFOEMPTY)) - return -ETIMEDOUT; - } - /* - * At this point either the tracing is enabled and in the right mode or - * disabled. - */ - - idx *= (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH); - data_reg = MPS_TRC_FILTER0_MATCH + idx; - mask_reg = MPS_TRC_FILTER0_DONT_CARE + idx; - - for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) { - t4_write_reg(adap, data_reg, tp->data[i]); - t4_write_reg(adap, mask_reg, ~tp->mask[i]); - } - t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst, - TFCAPTUREMAX(tp->snap_len) | - TFMINPKTSIZE(tp->min_len)); - t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst, - TFOFFSET(tp->skip_ofst) | TFLENGTH(tp->skip_len) | - TFPORT(tp->port) | TFEN | - (tp->invert ? TFINVERTMATCH : 0)); - - cfg &= ~TRCMULTIFILTER; - t4_write_reg(adap, MPS_TRC_CFG, cfg | TRCEN | multitrc); -out: t4_read_reg(adap, MPS_TRC_CFG); /* flush */ - return 0; -} - -/** - * t4_get_trace_filter - query one of the tracing filters - * @adap: the adapter - * @tp: the current trace filter parameters - * @idx: which trace filter to query - * @enabled: non-zero if the filter is enabled - * - * Returns the current settings of one of the HW tracing filters. - */ -void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx, - int *enabled) -{ - u32 ctla, ctlb; - int i, ofst = idx * 4; - u32 data_reg, mask_reg; - - ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A + ofst); - ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B + ofst); - - *enabled = !!(ctla & TFEN); - tp->snap_len = TFCAPTUREMAX_GET(ctlb); - tp->min_len = TFMINPKTSIZE_GET(ctlb); - tp->skip_ofst = TFOFFSET_GET(ctla); - tp->skip_len = TFLENGTH_GET(ctla); - tp->invert = !!(ctla & TFINVERTMATCH); - tp->port = TFPORT_GET(ctla); - - ofst = (MPS_TRC_FILTER1_MATCH - MPS_TRC_FILTER0_MATCH) * idx; - data_reg = MPS_TRC_FILTER0_MATCH + ofst; - mask_reg = MPS_TRC_FILTER0_DONT_CARE + ofst; - - for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) { - tp->mask[i] = ~t4_read_reg(adap, mask_reg); - tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i]; - } -} - /** * get_mps_bg_map - return the buffer groups associated with a port * @adap: the adapter @@ -2132,52 +1901,6 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) #undef GET_STAT_COM } -/** - * t4_get_lb_stats - collect loopback port statistics - * @adap: the adapter - * @idx: the loopback port index - * @p: the stats structure to fill - * - * Return HW statistics for the given loopback port. - */ -void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p) -{ - u32 bgmap = get_mps_bg_map(adap, idx); - -#define GET_STAT(name) \ - t4_read_reg64(adap, PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L)) -#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L) - - p->octets = GET_STAT(BYTES); - p->frames = GET_STAT(FRAMES); - p->bcast_frames = GET_STAT(BCAST); - p->mcast_frames = GET_STAT(MCAST); - p->ucast_frames = GET_STAT(UCAST); - p->error_frames = GET_STAT(ERROR); - - p->frames_64 = GET_STAT(64B); - p->frames_65_127 = GET_STAT(65B_127B); - p->frames_128_255 = GET_STAT(128B_255B); - p->frames_256_511 = GET_STAT(256B_511B); - p->frames_512_1023 = GET_STAT(512B_1023B); - p->frames_1024_1518 = GET_STAT(1024B_1518B); - p->frames_1519_max = GET_STAT(1519B_MAX); - p->drop = t4_read_reg(adap, PORT_REG(idx, - MPS_PORT_STAT_LB_PORT_DROP_FRAMES)); - - p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0; - p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0; - p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0; - p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0; - p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0; - p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0; - p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0; - p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0; - -#undef GET_STAT -#undef GET_STAT_COM -} - /** * t4_wol_magic_enable - enable/disable magic packet WoL * @adap: the adapter @@ -2583,30 +2306,6 @@ int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port, return FW_VI_CMD_VIID_GET(ntohs(c.type_viid)); } -/** - * t4_free_vi - free a virtual interface - * @adap: the adapter - * @mbox: mailbox to use for the FW command - * @pf: the PF owning the VI - * @vf: the VF owning the VI - * @viid: virtual interface identifiler - * - * Free a previously allocated virtual interface. - */ -int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf, - unsigned int vf, unsigned int viid) -{ - struct fw_vi_cmd c; - - memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_VI_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_VI_CMD_PFN(pf) | - FW_VI_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_VI_CMD_FREE | FW_LEN16(c)); - c.type_viid = htons(FW_VI_CMD_VIID(viid)); - return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c); -} - /** * t4_set_rxmode - set Rx properties of a virtual interface * @adap: the adapter @@ -2832,37 +2531,6 @@ int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid, return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); } -/** - * t4_iq_start_stop - enable/disable an ingress queue and its FLs - * @adap: the adapter - * @mbox: mailbox to use for the FW command - * @start: %true to enable the queues, %false to disable them - * @pf: the PF owning the queues - * @vf: the VF owning the queues - * @iqid: ingress queue id - * @fl0id: FL0 queue id or 0xffff if no attached FL0 - * @fl1id: FL1 queue id or 0xffff if no attached FL1 - * - * Starts or stops an ingress queue and its associated FLs, if any. - */ -int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start, - unsigned int pf, unsigned int vf, unsigned int iqid, - unsigned int fl0id, unsigned int fl1id) -{ - struct fw_iq_cmd c; - - memset(&c, 0, sizeof(c)); - c.op_to_vfn = htonl(FW_CMD_OP(FW_IQ_CMD) | FW_CMD_REQUEST | - FW_CMD_EXEC | FW_IQ_CMD_PFN(pf) | - FW_IQ_CMD_VFN(vf)); - c.alloc_to_len16 = htonl(FW_IQ_CMD_IQSTART(start) | - FW_IQ_CMD_IQSTOP(!start) | FW_LEN16(c)); - c.iqid = htons(iqid); - c.fl0id = htons(fl0id); - c.fl1id = htons(fl1id); - return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL); -} - /** * t4_iq_free - free an ingress queue and its FLs * @adap: the adapter diff --git a/drivers/net/cxgb4/t4_hw.h b/drivers/net/cxgb4/t4_hw.h index 10a055565776cfceb4730df1168b44662d4d9761..c26b455f37de54c1075a93e6d100282ef8c6e134 100644 --- a/drivers/net/cxgb4/t4_hw.h +++ b/drivers/net/cxgb4/t4_hw.h @@ -42,6 +42,7 @@ enum { MAX_MTU = 9600, /* max MAC MTU, excluding header + FCS */ EEPROMSIZE = 17408, /* Serial EEPROM physical size */ EEPROMVSIZE = 32768, /* Serial EEPROM virtual address space size */ + EEPROMPFSIZE = 1024, /* EEPROM writable area size for PFn, n>0 */ RSS_NENTRIES = 2048, /* # of entries in RSS mapping table */ TCB_SIZE = 128, /* TCB size */ NMTUS = 16, /* size of MTU table */ diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h index 0969f2fbc1b0f0a977b1e470a1f4d60e19be215c..940584a8a640b077374e5caf1319341773f08fd3 100644 --- a/drivers/net/cxgb4/t4fw_api.h +++ b/drivers/net/cxgb4/t4fw_api.h @@ -487,6 +487,11 @@ enum fw_params_param_pfvf { FW_PARAMS_PARAM_PFVF_CPMASK = 0x25, FW_PARAMS_PARAM_PFVF_OCQ_START = 0x26, FW_PARAMS_PARAM_PFVF_OCQ_END = 0x27, + FW_PARAMS_PARAM_PFVF_CONM_MAP = 0x28, + FW_PARAMS_PARAM_PFVF_IQFLINT_START = 0x29, + FW_PARAMS_PARAM_PFVF_IQFLINT_END = 0x2A, + FW_PARAMS_PARAM_PFVF_EQ_START = 0x2B, + FW_PARAMS_PARAM_PFVF_EQ_END = 0x2C, }; /* diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 7b6d07f50c71a424adcba9c4fae981c842972c60..555ecc5a2e939b25028ac6a61cf2792da379caa7 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -748,7 +748,10 @@ static int cxgb4vf_open(struct net_device *dev) /* * Note that this interface is up and start everything up ... */ - dev->real_num_tx_queues = pi->nqsets; + netif_set_real_num_tx_queues(dev, pi->nqsets); + err = netif_set_real_num_rx_queues(dev, pi->nqsets); + if (err) + return err; set_bit(pi->port_id, &adapter->open_device_map); link_start(dev); netif_tx_start_all_queues(dev); diff --git a/drivers/net/cxgb4vf/sge.c b/drivers/net/cxgb4vf/sge.c index eb5a1c9cb2d3b588a309ea9cefc326ef1ee71b81..f10864ddafbef62492fc95608e0d0f7b8737c561 100644 --- a/drivers/net/cxgb4vf/sge.c +++ b/drivers/net/cxgb4vf/sge.c @@ -1520,7 +1520,6 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, __skb_pull(skb, PKTSHIFT); skb->protocol = eth_type_trans(skb, rspq->netdev); skb_record_rx_queue(skb, rspq->idx); - skb->dev->last_rx = jiffies; /* XXX removed 2.6.29 */ pi = netdev_priv(skb->dev); rxq->stats.pkts++; @@ -1535,7 +1534,7 @@ int t4vf_ethrx_handler(struct sge_rspq *rspq, const __be64 *rsp, } rxq->stats.rx_cso++; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (unlikely(pkt->vlan_ex)) { struct vlan_group *grp = pi->vlan_grp; diff --git a/drivers/net/cxgb4vf/t4vf_common.h b/drivers/net/cxgb4vf/t4vf_common.h index 5c7bde7f9baeb18268c80f04e63cdcf951fe328c..873cb7d86c57fc50ae3c71d6638c5e2b58e2ca07 100644 --- a/drivers/net/cxgb4vf/t4vf_common.h +++ b/drivers/net/cxgb4vf/t4vf_common.h @@ -132,15 +132,15 @@ struct rss_params { unsigned int mode; /* RSS mode */ union { struct { - int synmapen:1; /* SYN Map Enable */ - int syn4tupenipv6:1; /* enable hashing 4-tuple IPv6 SYNs */ - int syn2tupenipv6:1; /* enable hashing 2-tuple IPv6 SYNs */ - int syn4tupenipv4:1; /* enable hashing 4-tuple IPv4 SYNs */ - int syn2tupenipv4:1; /* enable hashing 2-tuple IPv4 SYNs */ - int ofdmapen:1; /* Offload Map Enable */ - int tnlmapen:1; /* Tunnel Map Enable */ - int tnlalllookup:1; /* Tunnel All Lookup */ - int hashtoeplitz:1; /* use Toeplitz hash */ + unsigned int synmapen:1; /* SYN Map Enable */ + unsigned int syn4tupenipv6:1; /* enable hashing 4-tuple IPv6 SYNs */ + unsigned int syn2tupenipv6:1; /* enable hashing 2-tuple IPv6 SYNs */ + unsigned int syn4tupenipv4:1; /* enable hashing 4-tuple IPv4 SYNs */ + unsigned int syn2tupenipv4:1; /* enable hashing 2-tuple IPv4 SYNs */ + unsigned int ofdmapen:1; /* Offload Map Enable */ + unsigned int tnlmapen:1; /* Tunnel Map Enable */ + unsigned int tnlalllookup:1; /* Tunnel All Lookup */ + unsigned int hashtoeplitz:1; /* use Toeplitz hash */ } basicvirtual; } u; }; @@ -151,10 +151,10 @@ struct rss_params { union rss_vi_config { struct { u16 defaultq; /* Ingress Queue ID for !tnlalllookup */ - int ip6fourtupen:1; /* hash 4-tuple IPv6 ingress packets */ - int ip6twotupen:1; /* hash 2-tuple IPv6 ingress packets */ - int ip4fourtupen:1; /* hash 4-tuple IPv4 ingress packets */ - int ip4twotupen:1; /* hash 2-tuple IPv4 ingress packets */ + unsigned int ip6fourtupen:1; /* hash 4-tuple IPv6 ingress packets */ + unsigned int ip6twotupen:1; /* hash 2-tuple IPv6 ingress packets */ + unsigned int ip4fourtupen:1; /* hash 4-tuple IPv4 ingress packets */ + unsigned int ip4twotupen:1; /* hash 2-tuple IPv4 ingress packets */ int udpen; /* hash 4-tuple UDP ingress packets */ } basicvirtual; }; diff --git a/drivers/net/de620.c b/drivers/net/de620.c index f3650fd096f4fd9e62b84966adee3a9615c723c3..1c51a757611904dfbc5aa03c6c56113a5321496c 100644 --- a/drivers/net/de620.c +++ b/drivers/net/de620.c @@ -676,7 +676,7 @@ static int de620_rx_intr(struct net_device *dev) de620_set_register(dev, W_NPRF, next_rx_page); pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page); - return (next_rx_page != curr_page); /* That was slightly tricky... */ + return next_rx_page != curr_page; /* That was slightly tricky... */ } /********************************************* diff --git a/drivers/net/declance.c b/drivers/net/declance.c index d7de376d7178ad2b9470797d5cab92846277e363..219eb5ad5c128bda75e0a9c3bcaabd9ef6df8e31 100644 --- a/drivers/net/declance.c +++ b/drivers/net/declance.c @@ -1255,7 +1255,7 @@ static int __devinit dec_lance_probe(struct device *bdev, const int type) */ init_timer(&lp->multicast_timer); lp->multicast_timer.data = (unsigned long) dev; - lp->multicast_timer.function = &lance_set_multicast_retry; + lp->multicast_timer.function = lance_set_multicast_retry; ret = register_netdev(dev); if (ret) { diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c index e5667c55844e17ac23bbf228fe4d890c995d59cc..417e143856237c8927c3a093e8f60ac0c055b4d4 100644 --- a/drivers/net/defxx.c +++ b/drivers/net/defxx.c @@ -1024,7 +1024,7 @@ static int __devinit dfx_driver_init(struct net_device *dev, &data) != DFX_K_SUCCESS) { printk("%s: Could not read adapter factory MAC address!\n", print_name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } le32 = cpu_to_le32(data); memcpy(&bp->factory_mac_addr[0], &le32, sizeof(u32)); @@ -1033,7 +1033,7 @@ static int __devinit dfx_driver_init(struct net_device *dev, &data) != DFX_K_SUCCESS) { printk("%s: Could not read adapter factory MAC address!\n", print_name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } le32 = cpu_to_le32(data); memcpy(&bp->factory_mac_addr[4], &le32, sizeof(u16)); @@ -1075,7 +1075,7 @@ static int __devinit dfx_driver_init(struct net_device *dev, if (top_v == NULL) { printk("%s: Could not allocate memory for host buffers " "and structures!\n", print_name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } memset(top_v, 0, alloc_size); /* zero out memory before continuing */ top_p = bp->kmalloced_dma; /* get physical address of buffer */ @@ -1145,7 +1145,7 @@ static int __devinit dfx_driver_init(struct net_device *dev, DBG_printk("%s: Consumer block virt = %0lX, phys = %0X\n", print_name, (long)bp->cons_block_virt, bp->cons_block_phys); - return(DFX_K_SUCCESS); + return DFX_K_SUCCESS; } @@ -1195,7 +1195,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_hw_dma_uninit(bp, bp->reset_type) != DFX_K_SUCCESS) { printk("%s: Could not uninitialize/reset adapter!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* @@ -1229,7 +1229,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) NULL) != DFX_K_SUCCESS) { printk("%s: Could not set adapter burst size!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* @@ -1246,7 +1246,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) NULL) != DFX_K_SUCCESS) { printk("%s: Could not set consumer block address!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* @@ -1278,7 +1278,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) { printk("%s: DMA command request failed!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Set the initial values for eFDXEnable and MACTReq MIB objects */ @@ -1294,7 +1294,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) { printk("%s: DMA command request failed!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Initialize adapter CAM */ @@ -1302,7 +1302,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_ctl_update_cam(bp) != DFX_K_SUCCESS) { printk("%s: Adapter CAM update failed!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Initialize adapter filters */ @@ -1310,7 +1310,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) if (dfx_ctl_update_filters(bp) != DFX_K_SUCCESS) { printk("%s: Adapter filters update failed!\n", bp->dev->name); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* @@ -1328,7 +1328,7 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) printk("%s: Receive buffer allocation failed\n", bp->dev->name); if (get_buffers) dfx_rcv_flush(bp); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Issue START command and bring adapter to LINK_(UN)AVAILABLE state */ @@ -1339,13 +1339,13 @@ static int dfx_adap_init(DFX_board_t *bp, int get_buffers) printk("%s: Start command failed\n", bp->dev->name); if (get_buffers) dfx_rcv_flush(bp); - return(DFX_K_FAILURE); + return DFX_K_FAILURE; } /* Initialization succeeded, reenable PDQ interrupts */ dfx_port_write_long(bp, PI_PDQ_K_REG_HOST_INT_ENB, PI_HOST_INT_K_ENABLE_DEF_INTS); - return(DFX_K_SUCCESS); + return DFX_K_SUCCESS; } @@ -1434,7 +1434,7 @@ static int dfx_open(struct net_device *dev) /* Set device structure info */ netif_start_queue(dev); - return(0); + return 0; } @@ -1526,7 +1526,7 @@ static int dfx_close(struct net_device *dev) free_irq(dev->irq, dev); - return(0); + return 0; } @@ -2027,7 +2027,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) bp->cmd_req_virt->cmd_type = PI_CMD_K_SMT_MIB_GET; if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) - return((struct net_device_stats *) &bp->stats); + return (struct net_device_stats *)&bp->stats; /* Fill the bp->stats structure with the SMT MIB object values */ @@ -2128,7 +2128,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) bp->cmd_req_virt->cmd_type = PI_CMD_K_CNTRS_GET; if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) - return((struct net_device_stats *) &bp->stats); + return (struct net_device_stats *)&bp->stats; /* Fill the bp->stats structure with the FDDI counter values */ @@ -2144,7 +2144,7 @@ static struct net_device_stats *dfx_ctl_get_stats(struct net_device *dev) bp->stats.port_lem_cts[0] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[0].ls; bp->stats.port_lem_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[1].ls; - return((struct net_device_stats *) &bp->stats); + return (struct net_device_stats *)&bp->stats; } @@ -2354,7 +2354,7 @@ static int dfx_ctl_set_mac_address(struct net_device *dev, void *addr) { DBG_printk("%s: Adapter CAM updated with new MAC address\n", dev->name); } - return(0); /* always return zero */ + return 0; /* always return zero */ } @@ -2438,8 +2438,8 @@ static int dfx_ctl_update_cam(DFX_board_t *bp) /* Issue command to update adapter CAM, then return */ if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) - return(DFX_K_FAILURE); - return(DFX_K_SUCCESS); + return DFX_K_FAILURE; + return DFX_K_SUCCESS; } @@ -2504,8 +2504,8 @@ static int dfx_ctl_update_filters(DFX_board_t *bp) /* Issue command to update adapter filters, then return */ if (dfx_hw_dma_cmd_req(bp) != DFX_K_SUCCESS) - return(DFX_K_FAILURE); - return(DFX_K_SUCCESS); + return DFX_K_FAILURE; + return DFX_K_SUCCESS; } @@ -2561,7 +2561,7 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp) (status == PI_STATE_K_HALTED) || (status == PI_STATE_K_DMA_UNAVAIL) || (status == PI_STATE_K_UPGRADE)) - return(DFX_K_OUTSTATE); + return DFX_K_OUTSTATE; /* Put response buffer on the command response queue */ @@ -2599,7 +2599,7 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp) udelay(100); /* wait for 100 microseconds */ } if (timeout_cnt == 0) - return(DFX_K_HW_TIMEOUT); + return DFX_K_HW_TIMEOUT; /* Bump (and wrap) the completion index and write out to register */ @@ -2619,14 +2619,14 @@ static int dfx_hw_dma_cmd_req(DFX_board_t *bp) udelay(100); /* wait for 100 microseconds */ } if (timeout_cnt == 0) - return(DFX_K_HW_TIMEOUT); + return DFX_K_HW_TIMEOUT; /* Bump (and wrap) the completion index and write out to register */ bp->cmd_rsp_reg.index.comp += 1; bp->cmd_rsp_reg.index.comp &= PI_CMD_RSP_K_NUM_ENTRIES-1; dfx_port_write_long(bp, PI_PDQ_K_REG_CMD_RSP_PROD, bp->cmd_rsp_reg.lword); - return(DFX_K_SUCCESS); + return DFX_K_SUCCESS; } @@ -2700,7 +2700,7 @@ static int dfx_hw_port_ctrl_req( udelay(100); /* wait for 100 microseconds */ } if (timeout_cnt == 0) - return(DFX_K_HW_TIMEOUT); + return DFX_K_HW_TIMEOUT; /* * If the address of host_data is non-zero, assume caller has supplied a @@ -2710,7 +2710,7 @@ static int dfx_hw_port_ctrl_req( if (host_data != NULL) dfx_port_read_long(bp, PI_PDQ_K_REG_HOST_DATA, host_data); - return(DFX_K_SUCCESS); + return DFX_K_SUCCESS; } @@ -2800,7 +2800,7 @@ static int dfx_hw_adap_state_rd(DFX_board_t *bp) PI_UINT32 port_status; /* Port Status register value */ dfx_port_read_long(bp, PI_PDQ_K_REG_PORT_STATUS, &port_status); - return((port_status & PI_PSTATUS_M_STATE) >> PI_PSTATUS_V_STATE); + return (port_status & PI_PSTATUS_M_STATE) >> PI_PSTATUS_V_STATE; } @@ -2852,8 +2852,8 @@ static int dfx_hw_dma_uninit(DFX_board_t *bp, PI_UINT32 type) udelay(100); /* wait for 100 microseconds */ } if (timeout_cnt == 0) - return(DFX_K_HW_TIMEOUT); - return(DFX_K_SUCCESS); + return DFX_K_HW_TIMEOUT; + return DFX_K_SUCCESS; } /* diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index a2f238d20caab0cfa80f196890ea6b96f47df363..e1a8216ff6926608759e9da69313c1d1958f4759 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -465,7 +465,7 @@ rio_open (struct net_device *dev) init_timer (&np->timer); np->timer.expires = jiffies + 1*HZ; np->timer.data = (unsigned long) dev; - np->timer.function = &rio_timer; + np->timer.function = rio_timer; add_timer (&np->timer); /* Start Tx/Rx */ diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 4fd6b2b4554b18e0072048bd2f018b5497072b89..9f6aeefa06bf9dd8060da75e57d5b796450abd32 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1056,7 +1056,7 @@ dm9000_rx(struct net_device *dev) if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } netif_rx(skb); dev->stats.rx_packets++; diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c index 7c075756611ad9d20e752a99105ead383524d342..9d8a20b72fa9ecdaa694481f1c4151a5dd51ce3d 100644 --- a/drivers/net/dnet.c +++ b/drivers/net/dnet.c @@ -27,7 +27,7 @@ #undef DEBUG /* function for reading internal MAC register */ -u16 dnet_readw_mac(struct dnet *bp, u16 reg) +static u16 dnet_readw_mac(struct dnet *bp, u16 reg) { u16 data_read; @@ -46,7 +46,7 @@ u16 dnet_readw_mac(struct dnet *bp, u16 reg) } /* function for writing internal MAC register */ -void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val) +static void dnet_writew_mac(struct dnet *bp, u16 reg, u16 val) { /* load data to write */ dnet_writel(bp, val, MACREG_DATA); @@ -63,11 +63,11 @@ static void __dnet_set_hwaddr(struct dnet *bp) { u16 tmp; - tmp = cpu_to_be16(*((u16 *) bp->dev->dev_addr)); + tmp = be16_to_cpup((__be16 *)bp->dev->dev_addr); dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG, tmp); - tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 2))); + tmp = be16_to_cpup((__be16 *)(bp->dev->dev_addr + 2)); dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG, tmp); - tmp = cpu_to_be16(*((u16 *) (bp->dev->dev_addr + 4))); + tmp = be16_to_cpup((__be16 *)(bp->dev->dev_addr + 4)); dnet_writew_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG, tmp); } @@ -89,11 +89,11 @@ static void __devinit dnet_get_hwaddr(struct dnet *bp) * Mac_addr[15:0]). */ tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_0_REG); - *((u16 *) addr) = be16_to_cpu(tmp); + *((__be16 *)addr) = cpu_to_be16(tmp); tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_1_REG); - *((u16 *) (addr + 2)) = be16_to_cpu(tmp); + *((__be16 *)(addr + 2)) = cpu_to_be16(tmp); tmp = dnet_readw_mac(bp, DNET_INTERNAL_MAC_ADDR_2_REG); - *((u16 *) (addr + 4)) = be16_to_cpu(tmp); + *((__be16 *)(addr + 4)) = cpu_to_be16(tmp); if (is_valid_ether_addr(addr)) memcpy(bp->dev->dev_addr, addr, sizeof(addr)); @@ -361,7 +361,7 @@ static int dnet_mii_init(struct dnet *bp) } /* For Neptune board: LINK1000 as Link LED and TX as activity LED */ -int dnet_phy_marvell_fixup(struct phy_device *phydev) +static int dnet_phy_marvell_fixup(struct phy_device *phydev) { return phy_write(phydev, 0x18, 0x4148); } diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 37dcfdc63456bb521bfd0e74ec58f65ad403dea5..ff2d29b178587eebfd22feba9e21aae496f12b17 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -36,6 +36,7 @@ #include #include #include +#include static int numdummies = 1; @@ -55,21 +56,69 @@ static void set_multicast_list(struct net_device *dev) { } +struct pcpu_dstats { + u64 tx_packets; + u64 tx_bytes; + struct u64_stats_sync syncp; +}; + +static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats) +{ + int i; + + for_each_possible_cpu(i) { + const struct pcpu_dstats *dstats; + u64 tbytes, tpackets; + unsigned int start; + + dstats = per_cpu_ptr(dev->dstats, i); + do { + start = u64_stats_fetch_begin(&dstats->syncp); + tbytes = dstats->tx_bytes; + tpackets = dstats->tx_packets; + } while (u64_stats_fetch_retry(&dstats->syncp, start)); + stats->tx_bytes += tbytes; + stats->tx_packets += tpackets; + } + return stats; +} static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) { - dev->stats.tx_packets++; - dev->stats.tx_bytes += skb->len; + struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats); + + u64_stats_update_begin(&dstats->syncp); + dstats->tx_packets++; + dstats->tx_bytes += skb->len; + u64_stats_update_end(&dstats->syncp); dev_kfree_skb(skb); return NETDEV_TX_OK; } +static int dummy_dev_init(struct net_device *dev) +{ + dev->dstats = alloc_percpu(struct pcpu_dstats); + if (!dev->dstats) + return -ENOMEM; + + return 0; +} + +static void dummy_dev_free(struct net_device *dev) +{ + free_percpu(dev->dstats); + free_netdev(dev); +} + static const struct net_device_ops dummy_netdev_ops = { + .ndo_init = dummy_dev_init, .ndo_start_xmit = dummy_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = set_multicast_list, .ndo_set_mac_address = dummy_set_address, + .ndo_get_stats64 = dummy_get_stats64, }; static void dummy_setup(struct net_device *dev) @@ -78,14 +127,17 @@ static void dummy_setup(struct net_device *dev) /* Initialize the device structure. */ dev->netdev_ops = &dummy_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = dummy_dev_free; /* Fill in device structure with ethernet-generic values. */ dev->tx_queue_len = 0; dev->flags |= IFF_NOARP; dev->flags &= ~IFF_MULTICAST; + dev->features |= NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO; + dev->features |= NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | NETIF_F_LLTX; random_ether_addr(dev->dev_addr); } + static int dummy_validate(struct nlattr *tb[], struct nlattr *data[]) { if (tb[IFLA_ADDRESS]) { diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 8e2eab4e7c759c6f1ae82bd3ea8959050c901684..b0aa9e68990a70e783118ca78c39f969f56098d0 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2215,10 +2215,10 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu) static int e100_asf(struct nic *nic) { /* ASF can be enabled from eeprom */ - return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) && + return (nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) && (nic->eeprom[eeprom_config_asf] & eeprom_asf) && !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && - ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE)); + ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE); } static int e100_up(struct nic *nic) diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 99288b95aead4460edc009434be71015730ba95f..a881dd0093bd896177507549389abe40c3438899 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -310,6 +310,9 @@ struct e1000_adapter { int need_ioport; bool discarding; + + struct work_struct fifo_stall_task; + struct work_struct phy_info_task; }; enum e1000_state_t { diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5cc39ed289c62234d2f56cd9ad4c1eb841c26b8e..a117f2a0252e8c884f6d890f912556924635cae9 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -123,8 +123,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring); static void e1000_set_rx_mode(struct net_device *netdev); static void e1000_update_phy_info(unsigned long data); +static void e1000_update_phy_info_task(struct work_struct *work); static void e1000_watchdog(unsigned long data); static void e1000_82547_tx_fifo_stall(unsigned long data); +static void e1000_82547_tx_fifo_stall_task(struct work_struct *work); static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev); static struct net_device_stats * e1000_get_stats(struct net_device *netdev); @@ -519,8 +521,21 @@ void e1000_down(struct e1000_adapter *adapter) e1000_clean_all_rx_rings(adapter); } +void e1000_reinit_safe(struct e1000_adapter *adapter) +{ + while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) + msleep(1); + rtnl_lock(); + e1000_down(adapter); + e1000_up(adapter); + rtnl_unlock(); + clear_bit(__E1000_RESETTING, &adapter->flags); +} + void e1000_reinit_locked(struct e1000_adapter *adapter) { + /* if rtnl_lock is not held the call path is bogus */ + ASSERT_RTNL(); WARN_ON(in_interrupt()); while (test_and_set_bit(__E1000_RESETTING, &adapter->flags)) msleep(1); @@ -789,6 +804,70 @@ static const struct net_device_ops e1000_netdev_ops = { #endif }; +/** + * e1000_init_hw_struct - initialize members of hw struct + * @adapter: board private struct + * @hw: structure used by e1000_hw.c + * + * Factors out initialization of the e1000_hw struct to its own function + * that can be called very early at init (just after struct allocation). + * Fields are initialized based on PCI device information and + * OS network device settings (MTU size). + * Returns negative error codes if MAC type setup fails. + */ +static int e1000_init_hw_struct(struct e1000_adapter *adapter, + struct e1000_hw *hw) +{ + struct pci_dev *pdev = adapter->pdev; + + /* PCI config space info */ + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_id = pdev->subsystem_device; + hw->revision_id = pdev->revision; + + pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); + + hw->max_frame_size = adapter->netdev->mtu + + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; + hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; + + /* identify the MAC */ + if (e1000_set_mac_type(hw)) { + e_err(probe, "Unknown MAC Type\n"); + return -EIO; + } + + switch (hw->mac_type) { + default: + break; + case e1000_82541: + case e1000_82547: + case e1000_82541_rev_2: + case e1000_82547_rev_2: + hw->phy_init_script = 1; + break; + } + + e1000_set_media_type(hw); + e1000_get_bus_info(hw); + + hw->wait_autoneg_complete = false; + hw->tbi_compatibility_en = true; + hw->adaptive_ifs = true; + + /* Copper options */ + + if (hw->media_type == e1000_media_type_copper) { + hw->mdix = AUTO_ALL_MODES; + hw->disable_polarity_correction = false; + hw->master_slave = E1000_MASTER_SLAVE; + } + + return 0; +} + /** * e1000_probe - Device Initialization Routine * @pdev: PCI device information struct @@ -826,22 +905,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (err) return err; - if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64)) && - !dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64))) { - pci_using_dac = 1; - } else { - err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); - if (err) { - err = dma_set_coherent_mask(&pdev->dev, - DMA_BIT_MASK(32)); - if (err) { - pr_err("No usable DMA config, aborting\n"); - goto err_dma; - } - } - pci_using_dac = 0; - } - err = pci_request_selected_regions(pdev, bars, e1000_driver_name); if (err) goto err_pci_reg; @@ -885,6 +948,32 @@ static int __devinit e1000_probe(struct pci_dev *pdev, } } + /* make ready for any if (hw->...) below */ + err = e1000_init_hw_struct(adapter, hw); + if (err) + goto err_sw_init; + + /* + * there is a workaround being applied below that limits + * 64-bit DMA addresses to 64-bit hardware. There are some + * 32-bit adapters that Tx hang when given 64-bit DMA addresses + */ + pci_using_dac = 0; + if ((hw->bus_type == e1000_bus_type_pcix) && + !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) { + /* + * according to DMA-API-HOWTO, coherent calls will always + * succeed if the set call did + */ + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64)); + pci_using_dac = 1; + } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) { + dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); + } else { + pr_err("No usable DMA config, aborting\n"); + goto err_dma; + } + netdev->netdev_ops = &e1000_netdev_ops; e1000_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; @@ -914,8 +1003,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev, (hw->mac_type != e1000_82547)) netdev->features |= NETIF_F_TSO; - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } netdev->vlan_features |= NETIF_F_TSO; netdev->vlan_features |= NETIF_F_HW_CSUM; @@ -959,21 +1050,21 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (!is_valid_ether_addr(netdev->perm_addr)) e_err(probe, "Invalid MAC Address\n"); - e1000_get_bus_info(hw); - init_timer(&adapter->tx_fifo_stall_timer); - adapter->tx_fifo_stall_timer.function = &e1000_82547_tx_fifo_stall; + adapter->tx_fifo_stall_timer.function = e1000_82547_tx_fifo_stall; adapter->tx_fifo_stall_timer.data = (unsigned long)adapter; init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &e1000_watchdog; + adapter->watchdog_timer.function = e1000_watchdog; adapter->watchdog_timer.data = (unsigned long) adapter; init_timer(&adapter->phy_info_timer); - adapter->phy_info_timer.function = &e1000_update_phy_info; + adapter->phy_info_timer.function = e1000_update_phy_info; adapter->phy_info_timer.data = (unsigned long)adapter; + INIT_WORK(&adapter->fifo_stall_task, e1000_82547_tx_fifo_stall_task); INIT_WORK(&adapter->reset_task, e1000_reset_task); + INIT_WORK(&adapter->phy_info_task, e1000_update_phy_info_task); e1000_check_options(adapter); @@ -1072,6 +1163,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, iounmap(hw->flash_address); kfree(adapter->tx_ring); kfree(adapter->rx_ring); +err_dma: err_sw_init: iounmap(hw->hw_addr); err_ioremap: @@ -1079,7 +1171,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, err_alloc_etherdev: pci_release_selected_regions(pdev, bars); err_pci_reg: -err_dma: pci_disable_device(pdev); return err; } @@ -1131,62 +1222,12 @@ static void __devexit e1000_remove(struct pci_dev *pdev) * @adapter: board private structure to initialize * * e1000_sw_init initializes the Adapter private data structure. - * Fields are initialized based on PCI device information and - * OS network device settings (MTU size). + * e1000_init_hw_struct MUST be called before this function **/ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) { - struct e1000_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - - /* PCI config space info */ - - hw->vendor_id = pdev->vendor; - hw->device_id = pdev->device; - hw->subsystem_vendor_id = pdev->subsystem_vendor; - hw->subsystem_id = pdev->subsystem_device; - hw->revision_id = pdev->revision; - - pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); - adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; - hw->max_frame_size = netdev->mtu + - ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; - hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; - - /* identify the MAC */ - - if (e1000_set_mac_type(hw)) { - e_err(probe, "Unknown MAC Type\n"); - return -EIO; - } - - switch (hw->mac_type) { - default: - break; - case e1000_82541: - case e1000_82547: - case e1000_82541_rev_2: - case e1000_82547_rev_2: - hw->phy_init_script = 1; - break; - } - - e1000_set_media_type(hw); - - hw->wait_autoneg_complete = false; - hw->tbi_compatibility_en = true; - hw->adaptive_ifs = true; - - /* Copper options */ - - if (hw->media_type == e1000_media_type_copper) { - hw->mdix = AUTO_ALL_MODES; - hw->disable_polarity_correction = false; - hw->master_slave = E1000_MASTER_SLAVE; - } adapter->num_tx_queues = 1; adapter->num_rx_queues = 1; @@ -2210,22 +2251,45 @@ static void e1000_set_rx_mode(struct net_device *netdev) static void e1000_update_phy_info(unsigned long data) { struct e1000_adapter *adapter = (struct e1000_adapter *)data; + schedule_work(&adapter->phy_info_task); +} + +static void e1000_update_phy_info_task(struct work_struct *work) +{ + struct e1000_adapter *adapter = container_of(work, + struct e1000_adapter, + phy_info_task); struct e1000_hw *hw = &adapter->hw; + + rtnl_lock(); e1000_phy_get_info(hw, &adapter->phy_info); + rtnl_unlock(); } /** * e1000_82547_tx_fifo_stall - Timer Call-back * @data: pointer to adapter cast into an unsigned long **/ - static void e1000_82547_tx_fifo_stall(unsigned long data) { struct e1000_adapter *adapter = (struct e1000_adapter *)data; + schedule_work(&adapter->fifo_stall_task); +} + +/** + * e1000_82547_tx_fifo_stall_task - task to complete work + * @work: work struct contained inside adapter struct + **/ +static void e1000_82547_tx_fifo_stall_task(struct work_struct *work) +{ + struct e1000_adapter *adapter = container_of(work, + struct e1000_adapter, + fifo_stall_task); struct e1000_hw *hw = &adapter->hw; struct net_device *netdev = adapter->netdev; u32 tctl; + rtnl_lock(); if (atomic_read(&adapter->tx_fifo_stall)) { if ((er32(TDT) == er32(TDH)) && (er32(TDFT) == er32(TDFH)) && @@ -2246,6 +2310,7 @@ static void e1000_82547_tx_fifo_stall(unsigned long data) mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1); } } + rtnl_unlock(); } bool e1000_has_link(struct e1000_adapter *adapter) @@ -3054,7 +3119,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, } } - if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) { + if (unlikely(vlan_tx_tag_present(skb))) { tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } @@ -3113,7 +3178,7 @@ static void e1000_reset_task(struct work_struct *work) struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, reset_task); - e1000_reinit_locked(adapter); + e1000_reinit_safe(adapter); } /** @@ -3535,7 +3600,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter, adapter->total_tx_packets += total_tx_packets; netdev->stats.tx_bytes += total_tx_bytes; netdev->stats.tx_packets += total_tx_packets; - return (count < tx_ring->count); + return count < tx_ring->count; } /** @@ -3552,7 +3617,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, struct e1000_hw *hw = &adapter->hw; u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); - skb->ip_summed = CHECKSUM_NONE; + + skb_checksum_none_assert(skb); /* 82543 or newer only */ if (unlikely(hw->mac_type < e1000_82543)) return; @@ -3598,13 +3664,14 @@ static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, static void e1000_receive_skb(struct e1000_adapter *adapter, u8 status, __le16 vlan, struct sk_buff *skb) { - if (unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP))) { - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - le16_to_cpu(vlan) & - E1000_RXD_SPC_VLAN_MASK); - } else { - netif_receive_skb(skb); - } + skb->protocol = eth_type_trans(skb, adapter->netdev); + + if ((unlikely(adapter->vlgrp && (status & E1000_RXD_STAT_VP)))) + vlan_gro_receive(&adapter->napi, adapter->vlgrp, + le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK, + skb); + else + napi_gro_receive(&adapter->napi, skb); } /** @@ -3762,8 +3829,6 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, goto next_desc; } - skb->protocol = eth_type_trans(skb, netdev); - e1000_receive_skb(adapter, status, rx_desc->special, skb); next_desc: @@ -3926,8 +3991,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, ((u32)(rx_desc->errors) << 24), le16_to_cpu(rx_desc->csum), skb); - skb->protocol = eth_type_trans(skb, netdev); - e1000_receive_skb(adapter, status, rx_desc->special, skb); next_desc: @@ -4478,7 +4541,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; e1000_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index d3d4a57e24505f9c36af9ef139bfc9133788a4bd..ca663f19d7df97563dec1ac9192e30042cef8cc6 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -1801,7 +1801,8 @@ struct e1000_info e1000_82571_info = { | FLAG_RESET_OVERWRITES_LAA /* errata */ | FLAG_TARC_SPEED_MODE_BIT /* errata */ | FLAG_APME_CHECK_PORT_B, - .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */ + .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */ + | FLAG2_DMA_BURST, .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, @@ -1819,7 +1820,8 @@ struct e1000_info e1000_82572_info = { | FLAG_RX_CSUM_ENABLED | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_TARC_SPEED_MODE_BIT, /* errata */ - .flags2 = FLAG2_DISABLE_ASPM_L1, /* errata 13 */ + .flags2 = FLAG2_DISABLE_ASPM_L1 /* errata 13 */ + | FLAG2_DMA_BURST, .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 93b3bedae8d2b2457a88f52b4664fe1b4b6b7dd8..d3f7a9c3f9738e8ed6aa8a60078d9c93572f6a35 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -446,7 +446,9 @@ /* Transmit Descriptor Control */ #define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ +#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ #define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ +#define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ #define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */ /* Enable the counting of desc. still to be processed. */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index f9a31c82f87108c3e9ef6974a6c9089a62cdb5fe..cee882dd67bf74c3601259e1fc6a3e87d605d6ee 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -153,6 +153,33 @@ struct e1000_info; /* Time to wait before putting the device into D3 if there's no link (in ms). */ #define LINK_TIMEOUT 100 +#define DEFAULT_RDTR 0 +#define DEFAULT_RADV 8 +#define BURST_RDTR 0x20 +#define BURST_RADV 0x20 + +/* + * in the case of WTHRESH, it appears at least the 82571/2 hardware + * writes back 4 descriptors when WTHRESH=5, and 3 descriptors when + * WTHRESH=4, and since we want 64 bytes at a time written back, set + * it to 5 + */ +#define E1000_TXDCTL_DMA_BURST_ENABLE \ + (E1000_TXDCTL_GRAN | /* set descriptor granularity */ \ + E1000_TXDCTL_COUNT_DESC | \ + (5 << 16) | /* wthresh must be +1 more than desired */\ + (1 << 8) | /* hthresh */ \ + 0x1f) /* pthresh */ + +#define E1000_RXDCTL_DMA_BURST_ENABLE \ + (0x01000000 | /* set descriptor granularity */ \ + (4 << 16) | /* set writeback threshold */ \ + (4 << 8) | /* set prefetch threshold */ \ + 0x20) /* set hthresh */ + +#define E1000_TIDV_FPD (1 << 31) +#define E1000_RDTR_FPD (1 << 31) + enum e1000_boards { board_82571, board_82572, @@ -425,6 +452,8 @@ struct e1000_info { #define FLAG2_DISABLE_ASPM_L1 (1 << 3) #define FLAG2_HAS_PHY_STATS (1 << 4) #define FLAG2_HAS_EEE (1 << 5) +#define FLAG2_DMA_BURST (1 << 6) +#define FLAG2_DISABLE_AIM (1 << 8) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 45aebb4a6fe1e37f316bac0f0cb656db97829c1b..24f8ac9cf703825685b73cf480b8dad07e93efed 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -1494,6 +1494,7 @@ struct e1000_info e1000_es2_info = { | FLAG_APME_CHECK_PORT_B | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ | FLAG_TIPG_MEDIUM_FOR_80003ESLAN, + .flags2 = FLAG2_DMA_BURST, .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_80003es2lan, diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 6355a1b779d3e7f0833c7cd6e96e23b3c9671fc9..8984d165a39b8bab735d718b363c9e7e97f48dd2 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -368,7 +368,7 @@ static int e1000_set_pauseparam(struct net_device *netdev, static u32 e1000_get_rx_csum(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - return (adapter->flags & FLAG_RX_CSUM_ENABLED); + return adapter->flags & FLAG_RX_CSUM_ENABLED; } static int e1000_set_rx_csum(struct net_device *netdev, u32 data) @@ -389,7 +389,7 @@ static int e1000_set_rx_csum(struct net_device *netdev, u32 data) static u32 e1000_get_tx_csum(struct net_device *netdev) { - return ((netdev->features & NETIF_F_HW_CSUM) != 0); + return (netdev->features & NETIF_F_HW_CSUM) != 0; } static int e1000_set_tx_csum(struct net_device *netdev, u32 data) @@ -1717,13 +1717,6 @@ static void e1000_diag_test(struct net_device *netdev, e_info("offline testing starting\n"); - /* - * Link test performed before hardware reset so autoneg doesn't - * interfere with test result - */ - if (e1000_link_test(adapter, &data[4])) - eth_test->flags |= ETH_TEST_FL_FAILED; - if (if_running) /* indicate we're in test mode */ dev_close(netdev); @@ -1747,15 +1740,19 @@ static void e1000_diag_test(struct net_device *netdev, if (e1000_loopback_test(adapter, &data[3])) eth_test->flags |= ETH_TEST_FL_FAILED; + /* force this routine to wait until autoneg complete/timeout */ + adapter->hw.phy.autoneg_wait_to_complete = 1; + e1000e_reset(adapter); + adapter->hw.phy.autoneg_wait_to_complete = 0; + + if (e1000_link_test(adapter, &data[4])) + eth_test->flags |= ETH_TEST_FL_FAILED; + /* restore speed, duplex, autoneg settings */ adapter->hw.phy.autoneg_advertised = autoneg_advertised; adapter->hw.mac.forced_speed_duplex = forced_speed_duplex; adapter->hw.mac.autoneg = autoneg; - - /* force this routine to wait until autoneg complete/timeout */ - adapter->hw.phy.autoneg_wait_to_complete = 1; e1000e_reset(adapter); - adapter->hw.phy.autoneg_wait_to_complete = 0; clear_bit(__E1000_TESTING, &adapter->state); if (if_running) diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 57b5435599ab1d61c58e393d04e0a2f3912d66fc..e3374d9a2472a2af316ca137305a53162f62e882 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -3986,7 +3986,7 @@ struct e1000_info e1000_pch2_info = { | FLAG_APME_IN_WUC, .flags2 = FLAG2_HAS_PHY_STATS | FLAG2_HAS_EEE, - .pba = 18, + .pba = 26, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index e561d15c3eb161558f9a7da3825f3cc6c90840c7..ec8cf3f51423fbf12fbdb9794ce1684f314b5140 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -475,7 +475,8 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); - skb->ip_summed = CHECKSUM_NONE; + + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set */ if (status & E1000_RXD_STAT_IXSM) @@ -1052,7 +1053,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) adapter->total_tx_packets += total_tx_packets; netdev->stats.tx_bytes += total_tx_bytes; netdev->stats.tx_packets += total_tx_packets; - return (count < tx_ring->count); + return count < tx_ring->count; } /** @@ -2289,6 +2290,11 @@ static void e1000_set_itr(struct e1000_adapter *adapter) goto set_itr_now; } + if (adapter->flags2 & FLAG2_DISABLE_AIM) { + new_itr = 0; + goto set_itr_now; + } + adapter->tx_itr = e1000_update_itr(adapter, adapter->tx_itr, adapter->total_tx_packets, @@ -2337,7 +2343,10 @@ static void e1000_set_itr(struct e1000_adapter *adapter) if (adapter->msix_entries) adapter->rx_ring->set_itr = 1; else - ew32(ITR, 1000000000 / (new_itr * 256)); + if (new_itr) + ew32(ITR, 1000000000 / (new_itr * 256)); + else + ew32(ITR, 0); } } @@ -2536,7 +2545,7 @@ static void e1000_restore_vlan(struct e1000_adapter *adapter) if (!adapter->vlgrp) return; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; e1000_vlan_rx_add_vid(adapter->netdev, vid); @@ -2649,6 +2658,26 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) /* Tx irq moderation */ ew32(TADV, adapter->tx_abs_int_delay); + if (adapter->flags2 & FLAG2_DMA_BURST) { + u32 txdctl = er32(TXDCTL(0)); + txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH | + E1000_TXDCTL_WTHRESH); + /* + * set up some performance related parameters to encourage the + * hardware to use the bus more efficiently in bursts, depends + * on the tx_int_delay to be enabled, + * wthresh = 5 ==> burst write a cacheline (64 bytes) at a time + * hthresh = 1 ==> prefetch when one or more available + * pthresh = 0x1f ==> prefetch if internal cache 31 or less + * BEWARE: this seems to work but should be considered first if + * there are tx hangs or other tx related bugs + */ + txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE; + ew32(TXDCTL(0), txdctl); + /* erratum work around: set txdctl the same for both queues */ + ew32(TXDCTL(1), txdctl); + } + /* Program the Transmit Control Register */ tctl = er32(TCTL); tctl &= ~E1000_TCTL_CT; @@ -2871,12 +2900,35 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) e1e_flush(); msleep(10); + if (adapter->flags2 & FLAG2_DMA_BURST) { + /* + * set the writeback threshold (only takes effect if the RDTR + * is set). set GRAN=1 and write back up to 0x4 worth, and + * enable prefetching of 0x20 rx descriptors + * granularity = 01 + * wthresh = 04, + * hthresh = 04, + * pthresh = 0x20 + */ + ew32(RXDCTL(0), E1000_RXDCTL_DMA_BURST_ENABLE); + ew32(RXDCTL(1), E1000_RXDCTL_DMA_BURST_ENABLE); + + /* + * override the delay timers for enabling bursting, only if + * the value was not set by the user via module options + */ + if (adapter->rx_int_delay == DEFAULT_RDTR) + adapter->rx_int_delay = BURST_RDTR; + if (adapter->rx_abs_int_delay == DEFAULT_RADV) + adapter->rx_abs_int_delay = BURST_RADV; + } + /* set the Receive Delay Timer Register */ ew32(RDTR, adapter->rx_int_delay); /* irq moderation */ ew32(RADV, adapter->rx_abs_int_delay); - if (adapter->itr_setting != 0) + if ((adapter->itr_setting != 0) && (adapter->itr != 0)) ew32(ITR, 1000000000 / (adapter->itr * 256)); ctrl_ext = er32(CTRL_EXT); @@ -2921,11 +2973,13 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) * packet size is equal or larger than the specified value (in 8 byte * units), e.g. using jumbo frames when setting to E1000_ERT_2048 */ - if (adapter->flags & FLAG_HAS_ERT) { + if ((adapter->flags & FLAG_HAS_ERT) || + (adapter->hw.mac.type == e1000_pch2lan)) { if (adapter->netdev->mtu > ETH_DATA_LEN) { u32 rxdctl = er32(RXDCTL(0)); ew32(RXDCTL(0), rxdctl | 0x3); - ew32(ERT, E1000_ERT_2048 | (1 << 13)); + if (adapter->flags & FLAG_HAS_ERT) + ew32(ERT, E1000_ERT_2048 | (1 << 13)); /* * With jumbo frames and early-receive enabled, * excessive C-state transition latencies result in @@ -3188,9 +3242,35 @@ void e1000e_reset(struct e1000_adapter *adapter) fc->low_water = 0x05048; fc->pause_time = 0x0650; fc->refresh_time = 0x0400; + if (adapter->netdev->mtu > ETH_DATA_LEN) { + pba = 14; + ew32(PBA, pba); + } break; } + /* + * Disable Adaptive Interrupt Moderation if 2 full packets cannot + * fit in receive buffer and early-receive not supported. + */ + if (adapter->itr_setting & 0x3) { + if (((adapter->max_frame_size * 2) > (pba << 10)) && + !(adapter->flags & FLAG_HAS_ERT)) { + if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) { + dev_info(&adapter->pdev->dev, + "Interrupt Throttle Rate turned off\n"); + adapter->flags2 |= FLAG2_DISABLE_AIM; + ew32(ITR, 0); + } + } else if (adapter->flags2 & FLAG2_DISABLE_AIM) { + dev_info(&adapter->pdev->dev, + "Interrupt Throttle Rate turned on\n"); + adapter->flags2 &= ~FLAG2_DISABLE_AIM; + adapter->itr = 20000; + ew32(ITR, 1000000000 / (adapter->itr * 256)); + } + } + /* Allow time for pending master requests to run */ mac->ops.reset_hw(hw); @@ -3411,22 +3491,16 @@ static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) if (adapter->flags & FLAG_MSI_TEST_FAILED) { adapter->int_mode = E1000E_INT_MODE_LEGACY; - err = -EIO; - e_info("MSI interrupt test failed!\n"); - } + e_info("MSI interrupt test failed, using legacy interrupt.\n"); + } else + e_dbg("MSI interrupt test succeeded!\n"); free_irq(adapter->pdev->irq, netdev); pci_disable_msi(adapter->pdev); - if (err == -EIO) - goto msi_test_failed; - - /* okay so the test worked, restore settings */ - e_dbg("MSI interrupt test succeeded!\n"); msi_test_failed: e1000e_set_interrupt_capability(adapter); - e1000_request_irq(adapter); - return err; + return e1000_request_irq(adapter); } /** @@ -3458,21 +3532,6 @@ static int e1000_test_msi(struct e1000_adapter *adapter) pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd); } - /* success ! */ - if (!err) - return 0; - - /* EIO means MSI test failed */ - if (err != -EIO) - return err; - - /* back to INTx mode */ - e_warn("MSI interrupt test failed, using legacy interrupt.\n"); - - e1000_free_irq(adapter); - - err = e1000_request_irq(adapter); - return err; } @@ -3530,7 +3589,8 @@ static int e1000_open(struct net_device *netdev) e1000_update_mng_vlan(adapter); /* DMA latency requirement to workaround early-receive/jumbo issue */ - if (adapter->flags & FLAG_HAS_ERT) + if ((adapter->flags & FLAG_HAS_ERT) || + (adapter->hw.mac.type == e1000_pch2lan)) pm_qos_add_request(&adapter->netdev->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); @@ -3639,7 +3699,8 @@ static int e1000_close(struct net_device *netdev) if (adapter->flags & FLAG_HAS_AMT) e1000_release_hw_control(adapter); - if (adapter->flags & FLAG_HAS_ERT) + if ((adapter->flags & FLAG_HAS_ERT) || + (adapter->hw.mac.type == e1000_pch2lan)) pm_qos_remove_request(&adapter->netdev->pm_qos_req); pm_runtime_put_sync(&pdev->dev); @@ -4255,6 +4316,16 @@ static void e1000_watchdog_task(struct work_struct *work) /* Force detection of hung controller every watchdog period */ adapter->detect_tx_hung = 1; + /* flush partial descriptors to memory before detecting tx hang */ + if (adapter->flags2 & FLAG2_DMA_BURST) { + ew32(TIDV, adapter->tx_int_delay | E1000_TIDV_FPD); + ew32(RDTR, adapter->rx_int_delay | E1000_RDTR_FPD); + /* + * no need to flush the writes because the timeout code does + * an er32 first thing + */ + } + /* * With 82571 controllers, LAA may be overwritten due to controller * reset from the other port. Set the appropriate LAA in RAR[0] @@ -4729,7 +4800,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (e1000_maybe_stop_tx(netdev, count + 2)) return NETDEV_TX_BUSY; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= E1000_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT); } @@ -5712,8 +5783,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_HW_CSUM; netdev->vlan_features |= NETIF_F_SG; - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } if (e1000e_enable_mng_pass_thru(&adapter->hw)) adapter->flags |= FLAG_MNG_PT_ENABLED; @@ -5754,11 +5827,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev, } init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &e1000_watchdog; + adapter->watchdog_timer.function = e1000_watchdog; adapter->watchdog_timer.data = (unsigned long) adapter; init_timer(&adapter->phy_info_timer); - adapter->phy_info_timer.function = &e1000_update_phy_info; + adapter->phy_info_timer.function = e1000_update_phy_info; adapter->phy_info_timer.data = (unsigned long) adapter; INIT_WORK(&adapter->reset_task, e1000_reset_task); diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 34aeec13bb168390f869cbb91b30a4c5655b6fa5..3d36911f77f3080c4f8893a23e04a2810f56966c 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -91,7 +91,6 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay"); * Valid Range: 0-65535 */ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); -#define DEFAULT_RDTR 0 #define MAX_RXDELAY 0xFFFF #define MIN_RXDELAY 0 @@ -101,7 +100,6 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); * Valid Range: 0-65535 */ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); -#define DEFAULT_RADV 8 #define MAX_RXABSDELAY 0xFFFF #define MIN_RXABSDELAY 0 diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 8d97f168f018734bcaeb1af1372b77ba9fca2eef..7c826319ee5a153111a59a1c517992dadcd5a84e 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -1457,11 +1457,11 @@ hardware_send_packet(struct net_device *dev, void *buf, short length) if (net_debug > 5) printk(KERN_DEBUG "%s: entering hardware_send_packet routine.\n", dev->name); - /* determine how much of the transmit buffer space is available */ - if (lp->tx_end > lp->tx_start) + /* determine how much of the transmit buffer space is available */ + if (lp->tx_end > lp->tx_start) tx_available = lp->xmt_ram - (lp->tx_end - lp->tx_start); - else if (lp->tx_end < lp->tx_start) - tx_available = lp->tx_start - lp->tx_end; + else if (lp->tx_end < lp->tx_start) + tx_available = lp->tx_start - lp->tx_end; else tx_available = lp->xmt_ram; if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) >= tx_available) { diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 1846623c6ae65d18b6223ada9be4531809f64a99..1321cb6401cfc9fd2a68ed0ba524a6fc83c17a32 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -491,6 +491,8 @@ struct ehea_port { u8 full_duplex; u8 autoneg; u8 num_def_qps; + wait_queue_head_t swqe_avail_wq; + wait_queue_head_t restart_wq; }; struct port_res_cfg { diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 6372610ed24093b8ed99fdf002e44442be49f696..bb7d306fb44656c3070fa3c20e2ef7b0759c73fc 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -180,7 +180,7 @@ static void ehea_update_firmware_handles(void) num_portres * EHEA_NUM_PORTRES_FW_HANDLES; if (num_fw_handles) { - arr = kzalloc(num_fw_handles * sizeof(*arr), GFP_KERNEL); + arr = kcalloc(num_fw_handles, sizeof(*arr), GFP_KERNEL); if (!arr) goto out; /* Keep the existing array */ } else @@ -265,7 +265,7 @@ static void ehea_update_bcmc_registrations(void) } if (num_registrations) { - arr = kzalloc(num_registrations * sizeof(*arr), GFP_ATOMIC); + arr = kcalloc(num_registrations, sizeof(*arr), GFP_ATOMIC); if (!arr) goto out; /* Keep the existing array */ } else @@ -793,6 +793,7 @@ static void reset_sq_restart_flag(struct ehea_port *port) struct ehea_port_res *pr = &port->port_res[i]; pr->sq_restart_flag = 0; } + wake_up(&port->restart_wq); } static void check_sqs(struct ehea_port *port) @@ -803,6 +804,7 @@ static void check_sqs(struct ehea_port *port) for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { struct ehea_port_res *pr = &port->port_res[i]; + int ret; k = 0; swqe = ehea_get_swqe(pr->qp, &swqe_index); memset(swqe, 0, SWQE_HEADER_SIZE); @@ -816,17 +818,16 @@ static void check_sqs(struct ehea_port *port) ehea_post_swqe(pr->qp, swqe); - while (pr->sq_restart_flag == 0) { - msleep(5); - if (++k == 100) { - ehea_error("HW/SW queues out of sync"); - ehea_schedule_port_reset(pr->port); - return; - } + ret = wait_event_timeout(port->restart_wq, + pr->sq_restart_flag == 0, + msecs_to_jiffies(100)); + + if (!ret) { + ehea_error("HW/SW queues out of sync"); + ehea_schedule_port_reset(pr->port); + return; } } - - return; } @@ -897,6 +898,7 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) pr->queue_stopped = 0; } spin_unlock_irqrestore(&pr->netif_queue, flags); + wake_up(&pr->port->swqe_avail_wq); return cqe; } @@ -1923,7 +1925,7 @@ static void ehea_promiscuous(struct net_device *dev, int enable) struct hcp_ehea_port_cb7 *cb7; u64 hret; - if ((enable && port->promisc) || (!enable && !port->promisc)) + if (enable == port->promisc) return; cb7 = (void *)get_zeroed_page(GFP_ATOMIC); @@ -2277,7 +2279,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev) } pr->swqe_id_counter += 1; - if (port->vgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { swqe->tx_control |= EHEA_SWQE_VLAN_INSERT; swqe->vlan_tag = vlan_tx_tag_get(skb); } @@ -2661,6 +2663,9 @@ static int ehea_open(struct net_device *dev) netif_start_queue(dev); } + init_waitqueue_head(&port->swqe_avail_wq); + init_waitqueue_head(&port->restart_wq); + mutex_unlock(&port->port_lock); return ret; @@ -2733,13 +2738,15 @@ static void ehea_flush_sq(struct ehea_port *port) for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { struct ehea_port_res *pr = &port->port_res[i]; int swqe_max = pr->sq_skba_size - 2 - pr->swqe_ll_count; - int k = 0; - while (atomic_read(&pr->swqe_avail) < swqe_max) { - msleep(5); - if (++k == 20) { - ehea_error("WARNING: sq not flushed completely"); - break; - } + int ret; + + ret = wait_event_timeout(port->swqe_avail_wq, + atomic_read(&pr->swqe_avail) >= swqe_max, + msecs_to_jiffies(100)); + + if (!ret) { + ehea_error("WARNING: sq not flushed completely"); + break; } } } @@ -3728,7 +3735,7 @@ int __init ehea_module_init(void) if (ret) ehea_info("failed registering memory remove notifier"); - ret = crash_shutdown_register(&ehea_crash_handler); + ret = crash_shutdown_register(ehea_crash_handler); if (ret) ehea_info("failed registering crash handler"); @@ -3753,7 +3760,7 @@ int __init ehea_module_init(void) out2: unregister_memory_notifier(&ehea_mem_nb); unregister_reboot_notifier(&ehea_reboot_nb); - crash_shutdown_unregister(&ehea_crash_handler); + crash_shutdown_unregister(ehea_crash_handler); out: return ret; } @@ -3766,7 +3773,7 @@ static void __exit ehea_module_exit(void) driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities); ibmebus_unregister_driver(&ehea_driver); unregister_reboot_notifier(&ehea_reboot_nb); - ret = crash_shutdown_unregister(&ehea_crash_handler); + ret = crash_shutdown_unregister(ehea_crash_handler); if (ret) ehea_info("failed unregistering crash handler"); unregister_memory_notifier(&ehea_mem_nb); diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index f239aa8c6f4ce6d6e86341ab09ca461fdd76f89e..c91d364c55279e81425ba50d80ec8cbcb9ec54c0 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -32,7 +32,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver" -#define DRV_VERSION "1.4.1.1" +#define DRV_VERSION "1.4.1.6" #define DRV_COPYRIGHT "Copyright 2008-2010 Cisco Systems, Inc" #define ENIC_BARS_MAX 6 @@ -42,25 +42,6 @@ #define ENIC_CQ_MAX (ENIC_WQ_MAX + ENIC_RQ_MAX) #define ENIC_INTR_MAX (ENIC_CQ_MAX + 2) -enum enic_cq_index { - ENIC_CQ_RQ, - ENIC_CQ_WQ, -}; - -enum enic_intx_intr_index { - ENIC_INTX_WQ_RQ, - ENIC_INTX_ERR, - ENIC_INTX_NOTIFY, -}; - -enum enic_msix_intr_index { - ENIC_MSIX_RQ, - ENIC_MSIX_WQ, - ENIC_MSIX_ERR, - ENIC_MSIX_NOTIFY, - ENIC_MSIX_MAX, -}; - struct enic_msix_entry { int requested; char devname[IFNAMSIZ]; @@ -91,8 +72,8 @@ struct enic { struct vnic_dev *vdev; struct timer_list notify_timer; struct work_struct reset; - struct msix_entry msix_entry[ENIC_MSIX_MAX]; - struct enic_msix_entry msix[ENIC_MSIX_MAX]; + struct msix_entry msix_entry[ENIC_INTR_MAX]; + struct enic_msix_entry msix[ENIC_INTR_MAX]; u32 msg_enable; spinlock_t devcmd_lock; u8 mac_addr[ETH_ALEN]; @@ -119,7 +100,7 @@ struct enic { int (*rq_alloc_buf)(struct vnic_rq *rq); u64 rq_truncated_pkts; u64 rq_bad_fcs; - struct napi_struct napi; + struct napi_struct napi[ENIC_RQ_MAX]; /* interrupt resource cache line section */ ____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX]; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 9aab85366d21e782e0f60d5c2e917f3ee2759780..a466ef91dd4351d58f37e4ed5b443395ce4725e6 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -122,6 +122,51 @@ static int enic_is_dynamic(struct enic *enic) return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN; } +static inline unsigned int enic_cq_rq(struct enic *enic, unsigned int rq) +{ + return rq; +} + +static inline unsigned int enic_cq_wq(struct enic *enic, unsigned int wq) +{ + return enic->rq_count + wq; +} + +static inline unsigned int enic_legacy_io_intr(void) +{ + return 0; +} + +static inline unsigned int enic_legacy_err_intr(void) +{ + return 1; +} + +static inline unsigned int enic_legacy_notify_intr(void) +{ + return 2; +} + +static inline unsigned int enic_msix_rq_intr(struct enic *enic, unsigned int rq) +{ + return rq; +} + +static inline unsigned int enic_msix_wq_intr(struct enic *enic, unsigned int wq) +{ + return enic->rq_count + wq; +} + +static inline unsigned int enic_msix_err_intr(struct enic *enic) +{ + return enic->rq_count + enic->wq_count; +} + +static inline unsigned int enic_msix_notify_intr(struct enic *enic) +{ + return enic->rq_count + enic->wq_count + 1; +} + static int enic_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { @@ -306,6 +351,7 @@ static int enic_set_coalesce(struct net_device *netdev, struct enic *enic = netdev_priv(netdev); u32 tx_coalesce_usecs; u32 rx_coalesce_usecs; + unsigned int i, intr; tx_coalesce_usecs = min_t(u32, INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), @@ -319,7 +365,8 @@ static int enic_set_coalesce(struct net_device *netdev, if (tx_coalesce_usecs != rx_coalesce_usecs) return -EINVAL; - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_INTX_WQ_RQ], + intr = enic_legacy_io_intr(); + vnic_intr_coalescing_timer_set(&enic->intr[intr], INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); break; case VNIC_DEV_INTR_MODE_MSI: @@ -330,10 +377,18 @@ static int enic_set_coalesce(struct net_device *netdev, INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); break; case VNIC_DEV_INTR_MODE_MSIX: - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_WQ], - INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); - vnic_intr_coalescing_timer_set(&enic->intr[ENIC_MSIX_RQ], - INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs)); + for (i = 0; i < enic->wq_count; i++) { + intr = enic_msix_wq_intr(enic, i); + vnic_intr_coalescing_timer_set(&enic->intr[intr], + INTR_COALESCE_USEC_TO_HW(tx_coalesce_usecs)); + } + + for (i = 0; i < enic->rq_count; i++) { + intr = enic_msix_rq_intr(enic, i); + vnic_intr_coalescing_timer_set(&enic->intr[intr], + INTR_COALESCE_USEC_TO_HW(rx_coalesce_usecs)); + } + break; default: break; @@ -482,34 +537,37 @@ static irqreturn_t enic_isr_legacy(int irq, void *data) { struct net_device *netdev = data; struct enic *enic = netdev_priv(netdev); + unsigned int io_intr = enic_legacy_io_intr(); + unsigned int err_intr = enic_legacy_err_intr(); + unsigned int notify_intr = enic_legacy_notify_intr(); u32 pba; - vnic_intr_mask(&enic->intr[ENIC_INTX_WQ_RQ]); + vnic_intr_mask(&enic->intr[io_intr]); pba = vnic_intr_legacy_pba(enic->legacy_pba); if (!pba) { - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); + vnic_intr_unmask(&enic->intr[io_intr]); return IRQ_NONE; /* not our interrupt */ } - if (ENIC_TEST_INTR(pba, ENIC_INTX_NOTIFY)) { - vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_NOTIFY]); + if (ENIC_TEST_INTR(pba, notify_intr)) { + vnic_intr_return_all_credits(&enic->intr[notify_intr]); enic_notify_check(enic); } - if (ENIC_TEST_INTR(pba, ENIC_INTX_ERR)) { - vnic_intr_return_all_credits(&enic->intr[ENIC_INTX_ERR]); + if (ENIC_TEST_INTR(pba, err_intr)) { + vnic_intr_return_all_credits(&enic->intr[err_intr]); enic_log_q_error(enic); /* schedule recovery from WQ/RQ error */ schedule_work(&enic->reset); return IRQ_HANDLED; } - if (ENIC_TEST_INTR(pba, ENIC_INTX_WQ_RQ)) { - if (napi_schedule_prep(&enic->napi)) - __napi_schedule(&enic->napi); + if (ENIC_TEST_INTR(pba, io_intr)) { + if (napi_schedule_prep(&enic->napi[0])) + __napi_schedule(&enic->napi[0]); } else { - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); + vnic_intr_unmask(&enic->intr[io_intr]); } return IRQ_HANDLED; @@ -535,17 +593,17 @@ static irqreturn_t enic_isr_msi(int irq, void *data) * writes). */ - napi_schedule(&enic->napi); + napi_schedule(&enic->napi[0]); return IRQ_HANDLED; } static irqreturn_t enic_isr_msix_rq(int irq, void *data) { - struct enic *enic = data; + struct napi_struct *napi = data; /* schedule NAPI polling for RQ cleanup */ - napi_schedule(&enic->napi); + napi_schedule(napi); return IRQ_HANDLED; } @@ -553,13 +611,15 @@ static irqreturn_t enic_isr_msix_rq(int irq, void *data) static irqreturn_t enic_isr_msix_wq(int irq, void *data) { struct enic *enic = data; + unsigned int cq = enic_cq_wq(enic, 0); + unsigned int intr = enic_msix_wq_intr(enic, 0); unsigned int wq_work_to_do = -1; /* no limit */ unsigned int wq_work_done; - wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ], + wq_work_done = vnic_cq_service(&enic->cq[cq], wq_work_to_do, enic_wq_service, NULL); - vnic_intr_return_credits(&enic->intr[ENIC_MSIX_WQ], + vnic_intr_return_credits(&enic->intr[intr], wq_work_done, 1 /* unmask intr */, 1 /* reset intr timer */); @@ -570,8 +630,9 @@ static irqreturn_t enic_isr_msix_wq(int irq, void *data) static irqreturn_t enic_isr_msix_err(int irq, void *data) { struct enic *enic = data; + unsigned int intr = enic_msix_err_intr(enic); - vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_ERR]); + vnic_intr_return_all_credits(&enic->intr[intr]); enic_log_q_error(enic); @@ -584,8 +645,9 @@ static irqreturn_t enic_isr_msix_err(int irq, void *data) static irqreturn_t enic_isr_msix_notify(int irq, void *data) { struct enic *enic = data; + unsigned int intr = enic_msix_notify_intr(enic); - vnic_intr_return_all_credits(&enic->intr[ENIC_MSIX_NOTIFY]); + vnic_intr_return_all_credits(&enic->intr[intr]); enic_notify_check(enic); return IRQ_HANDLED; @@ -743,7 +805,7 @@ static inline void enic_queue_wq_skb(struct enic *enic, int vlan_tag_insert = 0; int loopback = 0; - if (enic->vlan_group && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { /* VLAN tag from trunking driver */ vlan_tag_insert = 1; vlan_tag = vlan_tx_tag_get(skb); @@ -911,7 +973,20 @@ static int enic_set_mac_address_dynamic(struct net_device *netdev, void *p) static int enic_set_mac_address(struct net_device *netdev, void *p) { - return -EOPNOTSUPP; + struct sockaddr *saddr = p; + char *addr = saddr->sa_data; + struct enic *enic = netdev_priv(netdev); + int err; + + err = enic_dev_del_station_addr(enic); + if (err) + return err; + + err = enic_set_mac_addr(netdev, addr); + if (err) + return err; + + return enic_dev_add_station_addr(enic); } static int enic_dev_packet_filter(struct enic *enic, int directed, @@ -1407,8 +1482,8 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, (vlan_tci & CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK)) { if (netdev->features & NETIF_F_GRO) - vlan_gro_receive(&enic->napi, enic->vlan_group, - vlan_tci, skb); + vlan_gro_receive(&enic->napi[q_number], + enic->vlan_group, vlan_tci, skb); else vlan_hwaccel_receive_skb(skb, enic->vlan_group, vlan_tci); @@ -1416,12 +1491,11 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, } else { if (netdev->features & NETIF_F_GRO) - napi_gro_receive(&enic->napi, skb); + napi_gro_receive(&enic->napi[q_number], skb); else netif_receive_skb(skb); } - } else { /* Buffer overflow @@ -1445,7 +1519,11 @@ static int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc, static int enic_poll(struct napi_struct *napi, int budget) { - struct enic *enic = container_of(napi, struct enic, napi); + struct net_device *netdev = napi->dev; + struct enic *enic = netdev_priv(netdev); + unsigned int cq_rq = enic_cq_rq(enic, 0); + unsigned int cq_wq = enic_cq_wq(enic, 0); + unsigned int intr = enic_legacy_io_intr(); unsigned int rq_work_to_do = budget; unsigned int wq_work_to_do = -1; /* no limit */ unsigned int work_done, rq_work_done, wq_work_done; @@ -1454,10 +1532,10 @@ static int enic_poll(struct napi_struct *napi, int budget) /* Service RQ (first) and WQ */ - rq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ], + rq_work_done = vnic_cq_service(&enic->cq[cq_rq], rq_work_to_do, enic_rq_service, NULL); - wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ], + wq_work_done = vnic_cq_service(&enic->cq[cq_wq], wq_work_to_do, enic_wq_service, NULL); /* Accumulate intr event credits for this polling @@ -1468,7 +1546,7 @@ static int enic_poll(struct napi_struct *napi, int budget) work_done = rq_work_done + wq_work_done; if (work_done > 0) - vnic_intr_return_credits(&enic->intr[ENIC_INTX_WQ_RQ], + vnic_intr_return_credits(&enic->intr[intr], work_done, 0 /* don't unmask intr */, 0 /* don't reset intr timer */); @@ -1489,7 +1567,7 @@ static int enic_poll(struct napi_struct *napi, int budget) */ napi_complete(napi); - vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); + vnic_intr_unmask(&enic->intr[intr]); } return rq_work_done; @@ -1497,7 +1575,11 @@ static int enic_poll(struct napi_struct *napi, int budget) static int enic_poll_msix(struct napi_struct *napi, int budget) { - struct enic *enic = container_of(napi, struct enic, napi); + struct net_device *netdev = napi->dev; + struct enic *enic = netdev_priv(netdev); + unsigned int rq = (napi - &enic->napi[0]); + unsigned int cq = enic_cq_rq(enic, rq); + unsigned int intr = enic_msix_rq_intr(enic, rq); unsigned int work_to_do = budget; unsigned int work_done; int err; @@ -1505,7 +1587,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) /* Service RQ */ - work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ], + work_done = vnic_cq_service(&enic->cq[cq], work_to_do, enic_rq_service, NULL); /* Return intr event credits for this polling @@ -1514,12 +1596,12 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) */ if (work_done > 0) - vnic_intr_return_credits(&enic->intr[ENIC_MSIX_RQ], + vnic_intr_return_credits(&enic->intr[intr], work_done, 0 /* don't unmask intr */, 0 /* don't reset intr timer */); - err = vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf); + err = vnic_rq_fill(&enic->rq[rq], enic->rq_alloc_buf); /* Buffer allocation failed. Stay in polling mode * so we can try to fill the ring again. @@ -1535,7 +1617,7 @@ static int enic_poll_msix(struct napi_struct *napi, int budget) */ napi_complete(napi); - vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); + vnic_intr_unmask(&enic->intr[intr]); } return work_done; @@ -1577,7 +1659,7 @@ static void enic_free_intr(struct enic *enic) static int enic_request_intr(struct enic *enic) { struct net_device *netdev = enic->netdev; - unsigned int i; + unsigned int i, intr; int err = 0; switch (vnic_dev_get_intr_mode(enic->vdev)) { @@ -1596,27 +1678,38 @@ static int enic_request_intr(struct enic *enic) case VNIC_DEV_INTR_MODE_MSIX: - sprintf(enic->msix[ENIC_MSIX_RQ].devname, - "%.11s-rx-0", netdev->name); - enic->msix[ENIC_MSIX_RQ].isr = enic_isr_msix_rq; - enic->msix[ENIC_MSIX_RQ].devid = enic; + for (i = 0; i < enic->rq_count; i++) { + intr = enic_msix_rq_intr(enic, i); + sprintf(enic->msix[intr].devname, + "%.11s-rx-%d", netdev->name, i); + enic->msix[intr].isr = enic_isr_msix_rq; + enic->msix[intr].devid = &enic->napi[i]; + } - sprintf(enic->msix[ENIC_MSIX_WQ].devname, - "%.11s-tx-0", netdev->name); - enic->msix[ENIC_MSIX_WQ].isr = enic_isr_msix_wq; - enic->msix[ENIC_MSIX_WQ].devid = enic; + for (i = 0; i < enic->wq_count; i++) { + intr = enic_msix_wq_intr(enic, i); + sprintf(enic->msix[intr].devname, + "%.11s-tx-%d", netdev->name, i); + enic->msix[intr].isr = enic_isr_msix_wq; + enic->msix[intr].devid = enic; + } - sprintf(enic->msix[ENIC_MSIX_ERR].devname, + intr = enic_msix_err_intr(enic); + sprintf(enic->msix[intr].devname, "%.11s-err", netdev->name); - enic->msix[ENIC_MSIX_ERR].isr = enic_isr_msix_err; - enic->msix[ENIC_MSIX_ERR].devid = enic; + enic->msix[intr].isr = enic_isr_msix_err; + enic->msix[intr].devid = enic; - sprintf(enic->msix[ENIC_MSIX_NOTIFY].devname, + intr = enic_msix_notify_intr(enic); + sprintf(enic->msix[intr].devname, "%.11s-notify", netdev->name); - enic->msix[ENIC_MSIX_NOTIFY].isr = enic_isr_msix_notify; - enic->msix[ENIC_MSIX_NOTIFY].devid = enic; + enic->msix[intr].isr = enic_isr_msix_notify; + enic->msix[intr].devid = enic; + + for (i = 0; i < ARRAY_SIZE(enic->msix); i++) + enic->msix[i].requested = 0; - for (i = 0; i < ARRAY_SIZE(enic->msix); i++) { + for (i = 0; i < enic->intr_count; i++) { err = request_irq(enic->msix_entry[i].vector, enic->msix[i].isr, 0, enic->msix[i].devname, @@ -1662,10 +1755,12 @@ static int enic_dev_notify_set(struct enic *enic) spin_lock(&enic->devcmd_lock); switch (vnic_dev_get_intr_mode(enic->vdev)) { case VNIC_DEV_INTR_MODE_INTX: - err = vnic_dev_notify_set(enic->vdev, ENIC_INTX_NOTIFY); + err = vnic_dev_notify_set(enic->vdev, + enic_legacy_notify_intr()); break; case VNIC_DEV_INTR_MODE_MSIX: - err = vnic_dev_notify_set(enic->vdev, ENIC_MSIX_NOTIFY); + err = vnic_dev_notify_set(enic->vdev, + enic_msix_notify_intr(enic)); break; default: err = vnic_dev_notify_set(enic->vdev, -1 /* no intr */); @@ -1692,7 +1787,7 @@ static int enic_dev_enable(struct enic *enic) int err; spin_lock(&enic->devcmd_lock); - err = vnic_dev_enable(enic->vdev); + err = vnic_dev_enable_wait(enic->vdev); spin_unlock(&enic->devcmd_lock); return err; @@ -1760,7 +1855,10 @@ static int enic_open(struct net_device *netdev) enic_set_multicast_list(netdev); netif_wake_queue(netdev); - napi_enable(&enic->napi); + + for (i = 0; i < enic->rq_count; i++) + napi_enable(&enic->napi[i]); + enic_dev_enable(enic); for (i = 0; i < enic->intr_count; i++) @@ -1795,7 +1893,10 @@ static int enic_stop(struct net_device *netdev) del_timer_sync(&enic->notify_timer); enic_dev_disable(enic); - napi_disable(&enic->napi); + + for (i = 0; i < enic->rq_count; i++) + napi_disable(&enic->napi[i]); + netif_carrier_off(netdev); netif_tx_disable(netdev); enic_dev_del_station_addr(enic); @@ -1855,11 +1956,16 @@ static void enic_poll_controller(struct net_device *netdev) { struct enic *enic = netdev_priv(netdev); struct vnic_dev *vdev = enic->vdev; + unsigned int i, intr; switch (vnic_dev_get_intr_mode(vdev)) { case VNIC_DEV_INTR_MODE_MSIX: - enic_isr_msix_rq(enic->pdev->irq, enic); - enic_isr_msix_wq(enic->pdev->irq, enic); + for (i = 0; i < enic->rq_count; i++) { + intr = enic_msix_rq_intr(enic, i); + enic_isr_msix_rq(enic->msix_entry[intr].vector, enic); + } + intr = enic_msix_wq_intr(enic, i); + enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); break; case VNIC_DEV_INTR_MODE_MSI: enic_isr_msi(enic->pdev->irq, enic); @@ -1934,19 +2040,73 @@ static int enic_dev_hang_reset(struct enic *enic) return err; } -static int enic_set_niccfg(struct enic *enic) +static int enic_set_rsskey(struct enic *enic) +{ + u64 rss_key_buf_pa; + union vnic_rss_key *rss_key_buf_va = NULL; + union vnic_rss_key rss_key = { + .key[0].b = {85, 67, 83, 97, 119, 101, 115, 111, 109, 101}, + .key[1].b = {80, 65, 76, 79, 117, 110, 105, 113, 117, 101}, + .key[2].b = {76, 73, 78, 85, 88, 114, 111, 99, 107, 115}, + .key[3].b = {69, 78, 73, 67, 105, 115, 99, 111, 111, 108}, + }; + int err; + + rss_key_buf_va = pci_alloc_consistent(enic->pdev, + sizeof(union vnic_rss_key), &rss_key_buf_pa); + if (!rss_key_buf_va) + return -ENOMEM; + + memcpy(rss_key_buf_va, &rss_key, sizeof(union vnic_rss_key)); + + spin_lock(&enic->devcmd_lock); + err = enic_set_rss_key(enic, + rss_key_buf_pa, + sizeof(union vnic_rss_key)); + spin_unlock(&enic->devcmd_lock); + + pci_free_consistent(enic->pdev, sizeof(union vnic_rss_key), + rss_key_buf_va, rss_key_buf_pa); + + return err; +} + +static int enic_set_rsscpu(struct enic *enic, u8 rss_hash_bits) +{ + u64 rss_cpu_buf_pa; + union vnic_rss_cpu *rss_cpu_buf_va = NULL; + unsigned int i; + int err; + + rss_cpu_buf_va = pci_alloc_consistent(enic->pdev, + sizeof(union vnic_rss_cpu), &rss_cpu_buf_pa); + if (!rss_cpu_buf_va) + return -ENOMEM; + + for (i = 0; i < (1 << rss_hash_bits); i++) + (*rss_cpu_buf_va).cpu[i/4].b[i%4] = i % enic->rq_count; + + spin_lock(&enic->devcmd_lock); + err = enic_set_rss_cpu(enic, + rss_cpu_buf_pa, + sizeof(union vnic_rss_cpu)); + spin_unlock(&enic->devcmd_lock); + + pci_free_consistent(enic->pdev, sizeof(union vnic_rss_cpu), + rss_cpu_buf_va, rss_cpu_buf_pa); + + return err; +} + +static int enic_set_niccfg(struct enic *enic, u8 rss_default_cpu, + u8 rss_hash_type, u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable) { - const u8 rss_default_cpu = 0; - const u8 rss_hash_type = 0; - const u8 rss_hash_bits = 0; - const u8 rss_base_cpu = 0; - const u8 rss_enable = 0; const u8 tso_ipid_split_en = 0; const u8 ig_vlan_strip_en = 1; int err; - /* Enable VLAN tag stripping. RSS not enabled (yet). - */ + /* Enable VLAN tag stripping. + */ spin_lock(&enic->devcmd_lock); err = enic_set_nic_cfg(enic, @@ -1959,6 +2119,35 @@ static int enic_set_niccfg(struct enic *enic) return err; } +static int enic_set_rss_nic_cfg(struct enic *enic) +{ + struct device *dev = enic_get_dev(enic); + const u8 rss_default_cpu = 0; + const u8 rss_hash_type = NIC_CFG_RSS_HASH_TYPE_IPV4 | + NIC_CFG_RSS_HASH_TYPE_TCP_IPV4 | + NIC_CFG_RSS_HASH_TYPE_IPV6 | + NIC_CFG_RSS_HASH_TYPE_TCP_IPV6; + const u8 rss_hash_bits = 7; + const u8 rss_base_cpu = 0; + u8 rss_enable = ENIC_SETTING(enic, RSS) && (enic->rq_count > 1); + + if (rss_enable) { + if (!enic_set_rsskey(enic)) { + if (enic_set_rsscpu(enic, rss_hash_bits)) { + rss_enable = 0; + dev_warn(dev, "RSS disabled, " + "Failed to set RSS cpu indirection table."); + } + } else { + rss_enable = 0; + dev_warn(dev, "RSS disabled, Failed to set RSS key.\n"); + } + } + + return enic_set_niccfg(enic, rss_default_cpu, rss_hash_type, + rss_hash_bits, rss_base_cpu, rss_enable); +} + static int enic_dev_hang_notify(struct enic *enic) { int err; @@ -1970,7 +2159,7 @@ static int enic_dev_hang_notify(struct enic *enic) return err; } -int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) +static int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic) { int err; @@ -1996,7 +2185,7 @@ static void enic_reset(struct work_struct *work) enic_dev_hang_reset(enic); enic_reset_multicast_list(enic); enic_init_vnic_resources(enic); - enic_set_niccfg(enic); + enic_set_rss_nic_cfg(enic); enic_dev_set_ig_vlan_rewrite_mode(enic); enic_open(enic->netdev); @@ -2005,12 +2194,12 @@ static void enic_reset(struct work_struct *work) static int enic_set_intr_mode(struct enic *enic) { - unsigned int n = 1; + unsigned int n = min_t(unsigned int, enic->rq_count, ENIC_RQ_MAX); unsigned int m = 1; unsigned int i; /* Set interrupt mode (INTx, MSI, MSI-X) depending - * system capabilities. + * on system capabilities. * * Try MSI-X first * @@ -2023,21 +2212,47 @@ static int enic_set_intr_mode(struct enic *enic) for (i = 0; i < n + m + 2; i++) enic->msix_entry[i].entry = i; - if (enic->config.intr_mode < 1 && + /* Use multiple RQs if RSS is enabled + */ + + if (ENIC_SETTING(enic, RSS) && + enic->config.intr_mode < 1 && enic->rq_count >= n && enic->wq_count >= m && enic->cq_count >= n + m && - enic->intr_count >= n + m + 2 && - !pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) { + enic->intr_count >= n + m + 2) { - enic->rq_count = n; - enic->wq_count = m; - enic->cq_count = n + m; - enic->intr_count = n + m + 2; + if (!pci_enable_msix(enic->pdev, enic->msix_entry, n + m + 2)) { - vnic_dev_set_intr_mode(enic->vdev, VNIC_DEV_INTR_MODE_MSIX); + enic->rq_count = n; + enic->wq_count = m; + enic->cq_count = n + m; + enic->intr_count = n + m + 2; - return 0; + vnic_dev_set_intr_mode(enic->vdev, + VNIC_DEV_INTR_MODE_MSIX); + + return 0; + } + } + + if (enic->config.intr_mode < 1 && + enic->rq_count >= 1 && + enic->wq_count >= m && + enic->cq_count >= 1 + m && + enic->intr_count >= 1 + m + 2) { + if (!pci_enable_msix(enic->pdev, enic->msix_entry, 1 + m + 2)) { + + enic->rq_count = 1; + enic->wq_count = m; + enic->cq_count = 1 + m; + enic->intr_count = 1 + m + 2; + + vnic_dev_set_intr_mode(enic->vdev, + VNIC_DEV_INTR_MODE_MSIX); + + return 0; + } } /* Next try MSI @@ -2145,28 +2360,22 @@ static const struct net_device_ops enic_netdev_ops = { #endif }; -void enic_dev_deinit(struct enic *enic) +static void enic_dev_deinit(struct enic *enic) { - netif_napi_del(&enic->napi); - enic_free_vnic_resources(enic); - enic_clear_intr_mode(enic); -} - -static int enic_dev_stats_clear(struct enic *enic) -{ - int err; + unsigned int i; - spin_lock(&enic->devcmd_lock); - err = vnic_dev_stats_clear(enic->vdev); - spin_unlock(&enic->devcmd_lock); + for (i = 0; i < enic->rq_count; i++) + netif_napi_del(&enic->napi[i]); - return err; + enic_free_vnic_resources(enic); + enic_clear_intr_mode(enic); } -int enic_dev_init(struct enic *enic) +static int enic_dev_init(struct enic *enic) { struct device *dev = enic_get_dev(enic); struct net_device *netdev = enic->netdev; + unsigned int i; int err; /* Get vNIC configuration @@ -2205,17 +2414,13 @@ int enic_dev_init(struct enic *enic) enic_init_vnic_resources(enic); - /* Clear LIF stats - */ - enic_dev_stats_clear(enic); - err = enic_set_rq_alloc_buf(enic); if (err) { dev_err(dev, "Failed to set RQ buffer allocator, aborting\n"); goto err_out_free_vnic_resources; } - err = enic_set_niccfg(enic); + err = enic_set_rss_nic_cfg(enic); if (err) { dev_err(dev, "Failed to config nic, aborting\n"); goto err_out_free_vnic_resources; @@ -2223,17 +2428,19 @@ int enic_dev_init(struct enic *enic) err = enic_dev_set_ig_vlan_rewrite_mode(enic); if (err) { - netdev_err(netdev, + dev_err(dev, "Failed to set ingress vlan rewrite mode, aborting.\n"); goto err_out_free_vnic_resources; } switch (vnic_dev_get_intr_mode(enic->vdev)) { default: - netif_napi_add(netdev, &enic->napi, enic_poll, 64); + netif_napi_add(netdev, &enic->napi[0], enic_poll, 64); break; case VNIC_DEV_INTR_MODE_MSIX: - netif_napi_add(netdev, &enic->napi, enic_poll_msix, 64); + for (i = 0; i < enic->rq_count; i++) + netif_napi_add(netdev, &enic->napi[i], + enic_poll_msix, 64); break; } diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c index 29ede8a17a2ca5a7d99e140c0a8e0c8f43848314..f111a37419ce05ed639c32a59d02636dec926117 100644 --- a/drivers/net/enic/enic_res.c +++ b/drivers/net/enic/enic_res.c @@ -94,13 +94,14 @@ int enic_get_vnic_config(struct enic *enic) INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX), c->intr_timer_usec); - dev_info(enic_get_dev(enic), "vNIC MAC addr %pM wq/rq %d/%d\n", - enic->mac_addr, c->wq_desc_count, c->rq_desc_count); - dev_info(enic_get_dev(enic), "vNIC mtu %d csum tx/rx %d/%d " - "tso/lro %d/%d intr timer %d usec\n", - c->mtu, ENIC_SETTING(enic, TXCSUM), - ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO), - ENIC_SETTING(enic, LRO), c->intr_timer_usec); + dev_info(enic_get_dev(enic), + "vNIC MAC addr %pM wq/rq %d/%d mtu %d\n", + enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu); + dev_info(enic_get_dev(enic), "vNIC csum tx/rx %d/%d " + "tso/lro %d/%d intr timer %d usec rss %d\n", + ENIC_SETTING(enic, TXCSUM), ENIC_SETTING(enic, RXCSUM), + ENIC_SETTING(enic, TSO), ENIC_SETTING(enic, LRO), + c->intr_timer_usec, ENIC_SETTING(enic, RSS)); return 0; } @@ -181,18 +182,11 @@ void enic_free_vnic_resources(struct enic *enic) void enic_get_res_counts(struct enic *enic) { - enic->wq_count = min_t(int, - vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ), - ENIC_WQ_MAX); - enic->rq_count = min_t(int, - vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ), - ENIC_RQ_MAX); - enic->cq_count = min_t(int, - vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ), - ENIC_CQ_MAX); - enic->intr_count = min_t(int, - vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL), - ENIC_INTR_MAX); + enic->wq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_WQ); + enic->rq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_RQ); + enic->cq_count = vnic_dev_get_res_count(enic->vdev, RES_TYPE_CQ); + enic->intr_count = vnic_dev_get_res_count(enic->vdev, + RES_TYPE_INTR_CTRL); dev_info(enic_get_dev(enic), "vNIC resources avail: wq %d rq %d cq %d intr %d\n", diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h index 83bd172c356cf329db232831d42cd3dd092f6a6d..9a103d9ef9e21bbb1d8c56accb95658250c73f4a 100644 --- a/drivers/net/enic/enic_res.h +++ b/drivers/net/enic/enic_res.h @@ -30,7 +30,7 @@ #define ENIC_MIN_RQ_DESCS 64 #define ENIC_MAX_RQ_DESCS 4096 -#define ENIC_MIN_MTU 576 /* minimum for IPv4 */ +#define ENIC_MIN_MTU 68 #define ENIC_MAX_MTU 9000 #define ENIC_MULTICAST_PERFECT_FILTERS 32 diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 6a5b578a69e169501f27eca1ec31262b3fc0d3d2..fb35d8b176686b75a62856d1a1da539a6113d568 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -74,6 +74,7 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, struct vnic_dev_bar *bar, unsigned int num_bars) { struct vnic_resource_header __iomem *rh; + struct mgmt_barmap_hdr __iomem *mrh; struct vnic_resource __iomem *r; u8 type; @@ -85,22 +86,32 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev, return -EINVAL; } - rh = bar->vaddr; + rh = bar->vaddr; + mrh = bar->vaddr; if (!rh) { pr_err("vNIC BAR0 res hdr not mem-mapped\n"); return -EINVAL; } - if (ioread32(&rh->magic) != VNIC_RES_MAGIC || - ioread32(&rh->version) != VNIC_RES_VERSION) { - pr_err("vNIC BAR0 res magic/version error " - "exp (%lx/%lx) curr (%x/%x)\n", + /* Check for mgmt vnic in addition to normal vnic */ + if ((ioread32(&rh->magic) != VNIC_RES_MAGIC) || + (ioread32(&rh->version) != VNIC_RES_VERSION)) { + if ((ioread32(&mrh->magic) != MGMTVNIC_MAGIC) || + (ioread32(&mrh->version) != MGMTVNIC_VERSION)) { + pr_err("vNIC BAR0 res magic/version error " + "exp (%lx/%lx) or (%lx/%lx), curr (%x/%x)\n", VNIC_RES_MAGIC, VNIC_RES_VERSION, + MGMTVNIC_MAGIC, MGMTVNIC_VERSION, ioread32(&rh->magic), ioread32(&rh->version)); - return -EINVAL; + return -EINVAL; + } } - r = (struct vnic_resource __iomem *)(rh + 1); + if (ioread32(&mrh->magic) == MGMTVNIC_MAGIC) + r = (struct vnic_resource __iomem *)(mrh + 1); + else + r = (struct vnic_resource __iomem *)(rh + 1); + while ((type = ioread8(&r->type)) != RES_TYPE_EOL) { @@ -175,22 +186,7 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, } } -dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev, - enum vnic_res_type type, unsigned int index) -{ - switch (type) { - case RES_TYPE_WQ: - case RES_TYPE_RQ: - case RES_TYPE_CQ: - case RES_TYPE_INTR_CTRL: - return vdev->res[type].bus_addr + - index * VNIC_RES_STRIDE; - default: - return vdev->res[type].bus_addr; - } -} - -unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, +static unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, unsigned int desc_count, unsigned int desc_size) { /* The base address of the desc rings must be 512 byte aligned. @@ -373,18 +369,6 @@ static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev, return err; } -void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf) -{ - vdev->proxy = PROXY_BY_BDF; - vdev->proxy_index = bdf; -} - -void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev) -{ - vdev->proxy = PROXY_NONE; - vdev->proxy_index = 0; -} - int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait) { @@ -477,13 +461,6 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, return err; } -int vnic_dev_stats_clear(struct vnic_dev *vdev) -{ - u64 a0 = 0, a1 = 0; - int wait = 1000; - return vnic_dev_cmd(vdev, CMD_STATS_CLEAR, &a0, &a1, wait); -} - int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats) { u64 a0, a1; @@ -510,13 +487,6 @@ int vnic_dev_close(struct vnic_dev *vdev) return vnic_dev_cmd(vdev, CMD_CLOSE, &a0, &a1, wait); } -int vnic_dev_enable(struct vnic_dev *vdev) -{ - u64 a0 = 0, a1 = 0; - int wait = 1000; - return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait); -} - int vnic_dev_enable_wait(struct vnic_dev *vdev) { u64 a0 = 0, a1 = 0; @@ -561,14 +531,14 @@ int vnic_dev_open_done(struct vnic_dev *vdev, int *done) return 0; } -int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg) +static int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg) { u64 a0 = (u32)arg, a1 = 0; int wait = 1000; return vnic_dev_cmd(vdev, CMD_SOFT_RESET, &a0, &a1, wait); } -int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done) +static int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done) { u64 a0 = 0, a1 = 0; int wait = 1000; @@ -669,26 +639,6 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, return err; } -int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed, - int multicast, int broadcast, int promisc, int allmulti) -{ - u64 a0, a1 = 0; - int wait = 1000; - int err; - - a0 = (directed ? CMD_PFILTER_DIRECTED : 0) | - (multicast ? CMD_PFILTER_MULTICAST : 0) | - (broadcast ? CMD_PFILTER_BROADCAST : 0) | - (promisc ? CMD_PFILTER_PROMISCUOUS : 0) | - (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0); - - err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER_ALL, &a0, &a1, wait); - if (err) - pr_err("Can't set packet filter\n"); - - return err; -} - int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr) { u64 a0 = 0, a1 = 0; @@ -737,20 +687,7 @@ int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev, return err; } -int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) -{ - u64 a0 = intr, a1 = 0; - int wait = 1000; - int err; - - err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait); - if (err) - pr_err("Failed to raise INTR[%d], err %d\n", intr, err); - - return err; -} - -int vnic_dev_notify_setcmd(struct vnic_dev *vdev, +static int vnic_dev_notify_setcmd(struct vnic_dev *vdev, void *notify_addr, dma_addr_t notify_pa, u16 intr) { u64 a0, a1; @@ -789,7 +726,7 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); } -int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) +static int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) { u64 a0, a1; int wait = 1000; @@ -943,30 +880,6 @@ u32 vnic_dev_mtu(struct vnic_dev *vdev) return vdev->notify_copy.mtu; } -u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev) -{ - if (!vnic_dev_notify_ready(vdev)) - return 0; - - return vdev->notify_copy.link_down_cnt; -} - -u32 vnic_dev_notify_status(struct vnic_dev *vdev) -{ - if (!vnic_dev_notify_ready(vdev)) - return 0; - - return vdev->notify_copy.status; -} - -u32 vnic_dev_uif(struct vnic_dev *vdev) -{ - if (!vnic_dev_notify_ready(vdev)) - return 0; - - return vdev->notify_copy.uif; -} - void vnic_dev_set_intr_mode(struct vnic_dev *vdev, enum vnic_dev_intr_mode intr_mode) { diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h index 3a61873138b69112b28f60de2a70fa11f2dc052c..05f9a24cd45974e6463891af6b154facc0b24e0d 100644 --- a/drivers/net/enic/vnic_dev.h +++ b/drivers/net/enic/vnic_dev.h @@ -84,10 +84,6 @@ unsigned int vnic_dev_get_res_count(struct vnic_dev *vdev, enum vnic_res_type type); void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type, unsigned int index); -dma_addr_t vnic_dev_get_res_bus_addr(struct vnic_dev *vdev, - enum vnic_res_type type, unsigned int index); -unsigned int vnic_dev_desc_ring_size(struct vnic_dev_ring *ring, - unsigned int desc_count, unsigned int desc_size); void vnic_dev_clear_desc_ring(struct vnic_dev_ring *ring); int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring, unsigned int desc_count, unsigned int desc_size); @@ -95,39 +91,26 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring); int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait); -void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf); -void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev); int vnic_dev_fw_info(struct vnic_dev *vdev, struct vnic_devcmd_fw_info **fw_info); int vnic_dev_hw_version(struct vnic_dev *vdev, enum vnic_dev_hw_version *hw_ver); int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size, void *value); -int vnic_dev_stats_clear(struct vnic_dev *vdev); int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats); int vnic_dev_hang_notify(struct vnic_dev *vdev); int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast, int broadcast, int promisc, int allmulti); -int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed, - int multicast, int broadcast, int promisc, int allmulti); int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr); int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr); int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr); -int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr); -int vnic_dev_notify_setcmd(struct vnic_dev *vdev, - void *notify_addr, dma_addr_t notify_pa, u16 intr); int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr); -int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev); int vnic_dev_notify_unset(struct vnic_dev *vdev); int vnic_dev_link_status(struct vnic_dev *vdev); u32 vnic_dev_port_speed(struct vnic_dev *vdev); u32 vnic_dev_msg_lvl(struct vnic_dev *vdev); u32 vnic_dev_mtu(struct vnic_dev *vdev); -u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev); -u32 vnic_dev_notify_status(struct vnic_dev *vdev); -u32 vnic_dev_uif(struct vnic_dev *vdev); int vnic_dev_close(struct vnic_dev *vdev); -int vnic_dev_enable(struct vnic_dev *vdev); int vnic_dev_enable_wait(struct vnic_dev *vdev); int vnic_dev_disable(struct vnic_dev *vdev); int vnic_dev_open(struct vnic_dev *vdev, int arg); @@ -136,8 +119,6 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg); int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err); int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len); int vnic_dev_deinit(struct vnic_dev *vdev); -int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg); -int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done); int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg); int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done); void vnic_dev_set_intr_mode(struct vnic_dev *vdev, diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h index 20661755df6bf4c96f9209efe4767a53c9217cdd..9abb3d51dea18bbdb33d361dc443a41b30721752 100644 --- a/drivers/net/enic/vnic_devcmd.h +++ b/drivers/net/enic/vnic_devcmd.h @@ -238,6 +238,18 @@ enum vnic_devcmd_cmd { * out: (u32)a0=status of proxied cmd * a1-a15=out args of proxied cmd */ CMD_PROXY_BY_BDF = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 42), + + /* + * As for BY_BDF except a0 is index of hvnlink subordinate vnic + * or SR-IOV virtual vnic */ + CMD_PROXY_BY_INDEX = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 43), + + /* + * in: (u64)a0=paddr of buffer to put latest VIC VIF-CONFIG-INFO TLV in + * (u32)a1=length of buffer in a0 + * out: (u64)a0=paddr of buffer with latest VIC VIF-CONFIG-INFO TLV + * (u32)a1=actual length of latest VIC VIF-CONFIG-INFO TLV */ + CMD_CONFIG_INFO_GET = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44), }; /* flags for CMD_OPEN */ diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h index 3b3291248956a4d01848b635bf294f2622c175e7..e8740e3704e495eedbdb4726bc0f48bff72b06ff 100644 --- a/drivers/net/enic/vnic_enet.h +++ b/drivers/net/enic/vnic_enet.h @@ -30,7 +30,7 @@ struct vnic_enet_config { u32 wq_desc_count; u32 rq_desc_count; u16 mtu; - u16 intr_timer; + u16 intr_timer_deprecated; u8 intr_timer_type; u8 intr_mode; char devname[16]; diff --git a/drivers/net/enic/vnic_intr.c b/drivers/net/enic/vnic_intr.c index 52ab61af2750fa9287d53f3c8e4dcbec84dca0b5..3873771d75cc4208abfa70d6bcc4e106e73fd227 100644 --- a/drivers/net/enic/vnic_intr.c +++ b/drivers/net/enic/vnic_intr.c @@ -65,8 +65,3 @@ void vnic_intr_clean(struct vnic_intr *intr) { iowrite32(0, &intr->ctrl->int_credits); } - -void vnic_intr_raise(struct vnic_intr *intr) -{ - vnic_dev_raise_intr(intr->vdev, (u16)intr->index); -} diff --git a/drivers/net/enic/vnic_resource.h b/drivers/net/enic/vnic_resource.h index 810287beff149f2969e0bda67b28754d600555e9..e0a73f1ca6f43e3b66558edb933cb9a9105aa5bb 100644 --- a/drivers/net/enic/vnic_resource.h +++ b/drivers/net/enic/vnic_resource.h @@ -22,6 +22,11 @@ #define VNIC_RES_MAGIC 0x766E6963L /* 'vnic' */ #define VNIC_RES_VERSION 0x00000000L +#define MGMTVNIC_MAGIC 0x544d474dL /* 'MGMT' */ +#define MGMTVNIC_VERSION 0x00000000L + +/* The MAC address assigned to the CFG vNIC is fixed. */ +#define MGMTVNIC_MAC { 0x02, 0x00, 0x54, 0x4d, 0x47, 0x4d } /* vNIC resource types */ enum vnic_res_type { @@ -52,6 +57,14 @@ struct vnic_resource_header { u32 version; }; +struct mgmt_barmap_hdr { + u32 magic; /* magic number */ + u32 version; /* header format version */ + u16 lif; /* loopback lif for mgmt frames */ + u16 pci_slot; /* installed pci slot */ + char serial[16]; /* card serial number */ +}; + struct vnic_resource { u8 type; u8 bar; diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c index dbb2aca258b9087ed1734dd2b7da61e478702303..34105e0951a5d40a24ef80e2e40bf1b24c898df3 100644 --- a/drivers/net/enic/vnic_rq.c +++ b/drivers/net/enic/vnic_rq.c @@ -77,8 +77,10 @@ void vnic_rq_free(struct vnic_rq *rq) vnic_dev_free_desc_ring(vdev, &rq->ring); for (i = 0; i < VNIC_RQ_BUF_BLKS_MAX; i++) { - kfree(rq->bufs[i]); - rq->bufs[i] = NULL; + if (rq->bufs[i]) { + kfree(rq->bufs[i]); + rq->bufs[i] = NULL; + } } rq->ctrl = NULL; @@ -113,7 +115,7 @@ int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index, return 0; } -void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, +static void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, unsigned int fetch_index, unsigned int posted_index, unsigned int error_interrupt_enable, unsigned int error_interrupt_offset) diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h index 2dc48f91abf71dc4da9d00f863f6766dd58b6349..37f08de2454ada35c39ae681b04e10a607d11633 100644 --- a/drivers/net/enic/vnic_rq.h +++ b/drivers/net/enic/vnic_rq.h @@ -143,7 +143,7 @@ static inline void vnic_rq_post(struct vnic_rq *rq, static inline int vnic_rq_posting_soon(struct vnic_rq *rq) { - return ((rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0); + return (rq->to_use->index & VNIC_RQ_RETURN_RATE) == 0; } static inline void vnic_rq_return_descs(struct vnic_rq *rq, unsigned int count) @@ -202,10 +202,6 @@ static inline int vnic_rq_fill(struct vnic_rq *rq, void vnic_rq_free(struct vnic_rq *rq); int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index, unsigned int desc_count, unsigned int desc_size); -void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index, - unsigned int fetch_index, unsigned int posted_index, - unsigned int error_interrupt_enable, - unsigned int error_interrupt_offset); void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index, unsigned int error_interrupt_enable, unsigned int error_interrupt_offset); diff --git a/drivers/net/enic/vnic_rss.h b/drivers/net/enic/vnic_rss.h index f62d1871962983bfce011fdbb4097a3421daf9a0..fa421baf45b87eadbf5857843869f1bbcabcdb08 100644 --- a/drivers/net/enic/vnic_rss.h +++ b/drivers/net/enic/vnic_rss.h @@ -37,9 +37,4 @@ union vnic_rss_cpu { u64 raw[32]; }; -void vnic_set_rss_key(union vnic_rss_key *rss_key, u8 *key); -void vnic_set_rss_cpu(union vnic_rss_cpu *rss_cpu, u8 *cpu); -void vnic_get_rss_key(union vnic_rss_key *rss_key, u8 *key); -void vnic_get_rss_cpu(union vnic_rss_cpu *rss_cpu, u8 *cpu); - #endif /* _VNIC_RSS_H_ */ diff --git a/drivers/net/enic/vnic_vic.c b/drivers/net/enic/vnic_vic.c index 197c9d24af824552a62622ec3aebfc39ec9b02cf..4725b79de0ef1686484e71dda80e9ae2aad48bc1 100644 --- a/drivers/net/enic/vnic_vic.c +++ b/drivers/net/enic/vnic_vic.c @@ -54,8 +54,8 @@ int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, if (!vp || !value) return -EINVAL; - if (ntohl(vp->length) + sizeof(*tlv) + length > - VIC_PROVINFO_MAX_TLV_DATA) + if (ntohl(vp->length) + offsetof(struct vic_provinfo_tlv, value) + + length > VIC_PROVINFO_MAX_TLV_DATA) return -ENOMEM; tlv = (struct vic_provinfo_tlv *)((u8 *)vp->tlv + @@ -66,7 +66,8 @@ int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length, memcpy(tlv->value, value, length); vp->num_tlvs = htonl(ntohl(vp->num_tlvs) + 1); - vp->length = htonl(ntohl(vp->length) + sizeof(*tlv) + length); + vp->length = htonl(ntohl(vp->length) + + offsetof(struct vic_provinfo_tlv, value) + length); return 0; } diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c index 122e33bcc57826a1ef08abf0337a3b97da014570..df61bd932ea622ef71b591406383f749db3f7fba 100644 --- a/drivers/net/enic/vnic_wq.c +++ b/drivers/net/enic/vnic_wq.c @@ -77,8 +77,10 @@ void vnic_wq_free(struct vnic_wq *wq) vnic_dev_free_desc_ring(vdev, &wq->ring); for (i = 0; i < VNIC_WQ_BUF_BLKS_MAX; i++) { - kfree(wq->bufs[i]); - wq->bufs[i] = NULL; + if (wq->bufs[i]) { + kfree(wq->bufs[i]); + wq->bufs[i] = NULL; + } } wq->ctrl = NULL; @@ -113,7 +115,7 @@ int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index, return 0; } -void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, +static void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, unsigned int fetch_index, unsigned int posted_index, unsigned int error_interrupt_enable, unsigned int error_interrupt_offset) diff --git a/drivers/net/enic/vnic_wq.h b/drivers/net/enic/vnic_wq.h index 94ac4621acc5ac945a7df33acc2894906d3f34ce..7dd937ac11c23e51fefdedf7ce72f70d7f2b76e9 100644 --- a/drivers/net/enic/vnic_wq.h +++ b/drivers/net/enic/vnic_wq.h @@ -153,10 +153,6 @@ static inline void vnic_wq_service(struct vnic_wq *wq, void vnic_wq_free(struct vnic_wq *wq); int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index, unsigned int desc_count, unsigned int desc_size); -void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index, - unsigned int fetch_index, unsigned int posted_index, - unsigned int error_interrupt_enable, - unsigned int error_interrupt_offset); void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index, unsigned int error_interrupt_enable, unsigned int error_interrupt_offset); diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 57c8ac0ef3f1232d41e4f00399eb27b18170dcf6..32543a300b810aeddecc69db0c25d9cf8e44e0ff 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -758,7 +758,7 @@ static int epic_open(struct net_device *dev) init_timer(&ep->timer); ep->timer.expires = jiffies + 3*HZ; ep->timer.data = (unsigned long)dev; - ep->timer.function = &epic_timer; /* timer handler */ + ep->timer.function = epic_timer; /* timer handler */ add_timer(&ep->timer); return 0; diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c index 10e39f2b31c3993e7e5bce57be2944702235481a..fb717be511f6023bcee869adf410523b0583632d 100644 --- a/drivers/net/eth16i.c +++ b/drivers/net/eth16i.c @@ -637,7 +637,9 @@ static void eth16i_initialize(struct net_device *dev, int boot) /* Set interface port type */ if(boot) { - char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" }; + static const char * const porttype[] = { + "BNC", "DIX", "TP", "AUTO", "FROM_EPROM" + }; switch(dev->if_port) { @@ -794,7 +796,7 @@ static int eth16i_receive_probe_packet(int ioaddr) if(eth16i_debug > 1) printk(KERN_DEBUG "RECEIVE_PACKET\n"); - return(0); /* Found receive packet */ + return 0; /* Found receive packet */ } } @@ -803,7 +805,7 @@ static int eth16i_receive_probe_packet(int ioaddr) printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG)); } - return(0); /* Return success */ + return 0; /* Return success */ } #if 0 @@ -839,7 +841,7 @@ static int __init eth16i_get_irq(int ioaddr) if( ioaddr < 0x1000) { cbyte = inb(ioaddr + JUMPERLESS_CONFIG); - return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] ); + return eth16i_irqmap[((cbyte & 0xC0) >> 6)]; } else { /* Oh..the card is EISA so method getting IRQ different */ unsigned short index = 0; cbyte = inb(ioaddr + EISA_IRQ_REG); @@ -847,7 +849,7 @@ static int __init eth16i_get_irq(int ioaddr) cbyte = cbyte >> 1; index++; } - return( eth32i_irqmap[ index ] ); + return eth32i_irqmap[index]; } } @@ -907,7 +909,7 @@ static int eth16i_read_eeprom(int ioaddr, int offset) data = eth16i_read_eeprom_word(ioaddr); outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG); - return(data); + return data; } static int eth16i_read_eeprom_word(int ioaddr) @@ -926,7 +928,7 @@ static int eth16i_read_eeprom_word(int ioaddr) eeprom_slow_io(); } - return(data); + return data; } static void eth16i_eeprom_cmd(int ioaddr, unsigned char command) diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 6d653c459c1f7e817661225619ddb837ddb0622e..c5a2fe099a8d772d6ef158bfac61bbe903f54aaa 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -806,11 +806,6 @@ static void ethoc_tx_timeout(struct net_device *dev) ethoc_interrupt(dev->irq, dev); } -static struct net_device_stats *ethoc_stats(struct net_device *dev) -{ - return &dev->stats; -} - static netdev_tx_t ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct ethoc *priv = netdev_priv(dev); @@ -863,7 +858,6 @@ static const struct net_device_ops ethoc_netdev_ops = { .ndo_set_multicast_list = ethoc_set_multicast_list, .ndo_change_mtu = ethoc_change_mtu, .ndo_tx_timeout = ethoc_tx_timeout, - .ndo_get_stats = ethoc_stats, .ndo_start_xmit = ethoc_start_xmit, }; diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index d7e8f6b8f4cf38c54107b5a616d87af7c0b5db3d..dd54abe2f7103d1a4eef72928b4f0494f212a013 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -915,14 +915,14 @@ static int netdev_open(struct net_device *dev) init_timer(&np->timer); np->timer.expires = RUN_AT(3 * HZ); np->timer.data = (unsigned long) dev; - np->timer.function = &netdev_timer; + np->timer.function = netdev_timer; /* timer handler */ add_timer(&np->timer); init_timer(&np->reset_timer); np->reset_timer.data = (unsigned long) dev; - np->reset_timer.function = &reset_timer; + np->reset_timer.function = reset_timer; np->reset_timer_armed = 0; return 0; diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index e3e10b4add9ce3e2f1f55adf54707190a6622ea9..e9f5d030bc267923acb405d394f1ba67be1101ae 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -771,11 +771,6 @@ static void mpc52xx_fec_reset(struct net_device *dev) /* ethtool interface */ -static void mpc52xx_fec_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, DRIVER_NAME); -} static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { @@ -810,7 +805,6 @@ static void mpc52xx_fec_set_msglevel(struct net_device *dev, u32 level) } static const struct ethtool_ops mpc52xx_fec_ethtool_ops = { - .get_drvinfo = mpc52xx_fec_get_drvinfo, .get_settings = mpc52xx_fec_get_settings, .set_settings = mpc52xx_fec_set_settings, .get_link = ethtool_op_get_link, diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 4da05b1b445c033a3606bdd0d1cf05ca0675660b..0fa1776563a33c61a827f79e6824c600e9b41efc 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2321,14 +2321,11 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb, NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0; /* vlan tag */ - if (likely(!np->vlangrp)) { + if (vlan_tx_tag_present(skb)) + start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | + vlan_tx_tag_get(skb)); + else start_tx->txvlan = 0; - } else { - if (vlan_tx_tag_present(skb)) - start_tx->txvlan = cpu_to_le32(NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb)); - else - start_tx->txvlan = 0; - } spin_lock_irqsave(&np->lock, flags); @@ -4620,7 +4617,7 @@ static int nv_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam* static u32 nv_get_rx_csum(struct net_device *dev) { struct fe_priv *np = netdev_priv(dev); - return (np->rx_csum) != 0; + return np->rx_csum != 0; } static int nv_set_rx_csum(struct net_device *dev, u32 data) @@ -5440,13 +5437,13 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i init_timer(&np->oom_kick); np->oom_kick.data = (unsigned long) dev; - np->oom_kick.function = &nv_do_rx_refill; /* timer handler */ + np->oom_kick.function = nv_do_rx_refill; /* timer handler */ init_timer(&np->nic_poll); np->nic_poll.data = (unsigned long) dev; - np->nic_poll.function = &nv_do_nic_poll; /* timer handler */ + np->nic_poll.function = nv_do_nic_poll; /* timer handler */ init_timer(&np->stats_poll); np->stats_poll.data = (unsigned long) dev; - np->stats_poll.function = &nv_do_stats_poll; /* timer handler */ + np->stats_poll.function = nv_do_stats_poll; /* timer handler */ err = pci_enable_device(pci_dev); if (err) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index d6e3111959abc49d82849fc22dd2ad6a3ec62b1b..d684f187de57714f4b38a2e7e8bf58771234d0a5 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -1036,7 +1036,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev, ndev = alloc_etherdev(privsize); if (!ndev) { ret = -ENOMEM; - goto out_free_fpi; + goto out_put; } SET_NETDEV_DEV(ndev, &ofdev->dev); @@ -1099,6 +1099,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev, out_free_dev: free_netdev(ndev); dev_set_drvdata(&ofdev->dev, NULL); +out_put: of_node_put(fpi->phy_node); out_free_fpi: kfree(fpi); diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index d4bf91aac25f003f99d1531ef1ef26f5a29cbda6..8d3a2ccbc953e39879c88ebd2d80d92211c2b792 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c @@ -125,7 +125,7 @@ int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); /* Write to the local MII regs */ - return(fsl_pq_local_mdio_write(regs, mii_id, regnum, value)); + return fsl_pq_local_mdio_write(regs, mii_id, regnum, value); } /* @@ -137,7 +137,7 @@ int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum) struct fsl_pq_mdio __iomem *regs = fsl_pq_mdio_get_regs(bus); /* Read the local MII regs */ - return(fsl_pq_local_mdio_read(regs, mii_id, regnum)); + return fsl_pq_local_mdio_read(regs, mii_id, regnum); } /* Reset the MIIM registers, and wait for the bus to free */ diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 4f7c3f3ca234634203c246d4e6494930de5f7247..4c4cc80ec0a1938f4a543254a7bf763f0a3ebfd4 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -654,9 +654,8 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev) priv->node = ofdev->dev.of_node; priv->ndev = dev; - dev->num_tx_queues = num_tx_qs; - dev->real_num_tx_queues = num_tx_qs; priv->num_tx_queues = num_tx_qs; + netif_set_real_num_rx_queues(dev, num_rx_qs); priv->num_rx_queues = num_rx_qs; priv->num_grps = 0x0; @@ -1859,7 +1858,7 @@ static int register_grp_irqs(struct gfar_priv_grp *grp) printk(KERN_ERR "%s: Can't get IRQ %d\n", dev->name, grp->interruptError); - goto err_irq_fail; + goto err_irq_fail; } if ((err = request_irq(grp->interruptTransmit, gfar_transmit, @@ -2048,7 +2047,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 bufaddr; unsigned long flags; unsigned int nr_frags, nr_txbds, length; - union skb_shared_tx *shtx; /* * TOE=1 frames larger than 2500 bytes may see excess delays @@ -2069,15 +2067,15 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) txq = netdev_get_tx_queue(dev, rq); base = tx_queue->tx_bd_base; regs = tx_queue->grp->regs; - shtx = skb_tx(skb); /* check if time stamp should be generated */ - if (unlikely(shtx->hardware && priv->hwts_tx_en)) + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && + priv->hwts_tx_en)) do_tstamp = 1; /* make space for additional header when fcb is needed */ if (((skb->ip_summed == CHECKSUM_PARTIAL) || - (priv->vlgrp && vlan_tx_tag_present(skb)) || + vlan_tx_tag_present(skb) || unlikely(do_tstamp)) && (skb_headroom(skb) < GMAC_FCB_LEN)) { struct sk_buff *skb_new; @@ -2163,7 +2161,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) gfar_tx_checksum(skb, fcb); } - if (priv->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { if (unlikely(NULL == fcb)) { fcb = gfar_add_fcb(skb); lstatus |= BD_LFLAG(TXBD_TOE); @@ -2174,7 +2172,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Setup tx hardware time stamping if requested */ if (unlikely(do_tstamp)) { - shtx->in_progress = 1; + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; if (fcb == NULL) fcb = gfar_add_fcb(skb); fcb->ptp = 1; @@ -2446,7 +2444,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) int howmany = 0; u32 lstatus; size_t buflen; - union skb_shared_tx *shtx; rx_queue = priv->rx_queue[tx_queue->qindex]; bdp = tx_queue->dirty_tx; @@ -2461,8 +2458,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) * When time stamping, one additional TxBD must be freed. * Also, we need to dma_unmap_single() the TxPAL. */ - shtx = skb_tx(skb); - if (unlikely(shtx->in_progress)) + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) nr_txbds = frags + 2; else nr_txbds = frags + 1; @@ -2476,7 +2472,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) (lstatus & BD_LENGTH_MASK)) break; - if (unlikely(shtx->in_progress)) { + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { next = next_txbd(bdp, base, tx_ring_size); buflen = next->length + GMAC_FCB_LEN; } else @@ -2485,7 +2481,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, buflen, DMA_TO_DEVICE); - if (unlikely(shtx->in_progress)) { + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { struct skb_shared_hwtstamps shhwtstamps; u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7); memset(&shhwtstamps, 0, sizeof(shhwtstamps)); @@ -2657,7 +2653,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb) if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 9bda023c0235664f9000411fa543ce182371259f..5c566ebc54b80f7da56a4cdf71b68368065c864f 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c @@ -254,7 +254,7 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use /* Make sure we return a number greater than 0 * if usecs > 0 */ - return ((usecs * 1000 + count - 1) / count); + return (usecs * 1000 + count - 1) / count; } /* Convert ethernet clock ticks to microseconds */ @@ -278,7 +278,7 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic /* Make sure we return a number greater than 0 */ /* if ticks is > 0 */ - return ((ticks * count) / 1000); + return (ticks * count) / 1000; } /* Get the coalescing parameters, and put them in the cvals @@ -538,7 +538,7 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) unlock_tx_qs(priv); unlock_rx_qs(priv); - local_irq_save(flags); + local_irq_restore(flags); for (i = 0; i < priv->num_rx_queues; i++) gfar_clean_rx_ring(priv->rx_queue[i], diff --git a/drivers/net/greth.c b/drivers/net/greth.c index f15c64f1cd3886a77ec09354c7caf3408eba14b4..27d6960ce09ea7a8d7f12ef970f9de5c769ebd37 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c @@ -893,7 +893,7 @@ static int greth_rx_gbit(struct net_device *dev, int limit) if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, dev); dev->stats.rx_packets++; @@ -1547,10 +1547,10 @@ static int __devinit greth_of_probe(struct platform_device *ofdev, const struct dev->netdev_ops = &greth_netdev_ops; dev->ethtool_ops = &greth_ethtool_ops; - if (register_netdev(dev)) { + err = register_netdev(dev); + if (err) { if (netif_msg_probe(greth)) dev_err(greth->dev, "netdevice registration failed.\n"); - err = -ENOMEM; goto error5; } diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 49aac7027fbb8841f62f11b18492119e02bb0bb1..9a6485892b3d48dfbcf783a27b670be83704e803 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -1004,7 +1004,7 @@ static int hamachi_open(struct net_device *dev) init_timer(&hmp->timer); hmp->timer.expires = RUN_AT((24*HZ)/10); /* 2.4 sec. */ hmp->timer.data = (unsigned long)dev; - hmp->timer.function = &hamachi_timer; /* timer handler */ + hmp->timer.function = hamachi_timer; /* timer handler */ add_timer(&hmp->timer); return 0; diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c index 14f01d156db9cf588a7640de77998cbba65a3c75..ac1d323c5eb5112194db47a7f1170be32c81cf5a 100644 --- a/drivers/net/hamradio/bpqether.c +++ b/drivers/net/hamradio/bpqether.c @@ -168,7 +168,7 @@ static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev) static inline int dev_is_ethdev(struct net_device *dev) { - return (dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5)); + return dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5); } /* ------------------------------------------------------------------------ */ diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c index b8bdf9d51cd44c5b145af8c860e0f2a0a771a898..5b37579e84b788952988ce5f4b5d48738e16e472 100644 --- a/drivers/net/hamradio/hdlcdrv.c +++ b/drivers/net/hamradio/hdlcdrv.c @@ -110,7 +110,7 @@ static int calc_crc_ccitt(const unsigned char *buf, int cnt) for (; cnt > 0; cnt--) crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; crc ^= 0xffff; - return (crc & 0xffff); + return crc & 0xffff; } #endif diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index 9f64c8637208c4b8395743ef8385dc57b9e7605a..33655814448e3a5485cce6d923961c615c986781 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -1069,7 +1069,8 @@ static void scc_tx_done(struct scc_channel *scc) case KISS_DUPLEX_LINK: scc->stat.tx_state = TXS_IDLE2; if (scc->kiss.idletime != TIMER_OFF) - scc_start_tx_timer(scc, t_idle, scc->kiss.idletime*100); + scc_start_tx_timer(scc, t_idle, + scc->kiss.idletime*100); break; case KISS_DUPLEX_OPTIMA: scc_notify(scc, HWEV_ALL_SENT); diff --git a/drivers/net/hp.c b/drivers/net/hp.c index 86ececd3c6582d17f7d0ffe0d3a19eeb5d85cfb0..d15d2f2ba78ec84cc9e6e73d0898f4d0b20e745c 100644 --- a/drivers/net/hp.c +++ b/drivers/net/hp.c @@ -204,10 +204,10 @@ static int __init hp_probe1(struct net_device *dev, int ioaddr) ei_status.rx_start_page = HP_START_PG + TX_PAGES; ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG; - ei_status.reset_8390 = &hp_reset_8390; - ei_status.get_8390_hdr = &hp_get_8390_hdr; - ei_status.block_input = &hp_block_input; - ei_status.block_output = &hp_block_output; + ei_status.reset_8390 = hp_reset_8390; + ei_status.get_8390_hdr = hp_get_8390_hdr; + ei_status.block_input = hp_block_input; + ei_status.block_output = hp_block_output; hp_init_card(dev); retval = register_netdev(dev); diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c index 095b17ecf609a4c9ca10585ded917f8925fa6cfa..8e2c4601b5f5c3dd2c6042c31c9dde21cd619fbd 100644 --- a/drivers/net/hp100.c +++ b/drivers/net/hp100.c @@ -1312,7 +1312,7 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr, for (p = (ringptr->pdl); p < (ringptr->pdl + 5); p++) printk("hp100: %s: Adr 0x%.8x = 0x%.8x\n", dev->name, (u_int) p, (u_int) * p); #endif - return (1); + return 1; } /* else: */ /* alloc_skb failed (no memory) -> still can receive the header @@ -1325,7 +1325,7 @@ static int hp100_build_rx_pdl(hp100_ring_t * ringptr, ringptr->pdl[0] = 0x00010000; /* PDH: Count=1 Fragment */ - return (0); + return 0; } /* @@ -2752,7 +2752,7 @@ static int hp100_login_to_vg_hub(struct net_device *dev, u_short force_relogin) hp100_outw(HP100_MISC_ERROR, IRQ_STATUS); if (val & HP100_LINK_UP_ST) - return (0); /* login was ok */ + return 0; /* login was ok */ else { printk("hp100: %s: Training failed.\n", dev->name); hp100_down_vg_link(dev); diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c index 07d8e5b634f36caeec8e8df868e3ab586807c774..c5ef62ceb8403ac777a36886156bec25a94006dd 100644 --- a/drivers/net/hydra.c +++ b/drivers/net/hydra.c @@ -155,10 +155,10 @@ static int __devinit hydra_init(struct zorro_dev *z) ei_status.rx_start_page = start_page + TX_PAGES; - ei_status.reset_8390 = &hydra_reset_8390; - ei_status.block_input = &hydra_block_input; - ei_status.block_output = &hydra_block_output; - ei_status.get_8390_hdr = &hydra_get_8390_hdr; + ei_status.reset_8390 = hydra_reset_8390; + ei_status.block_input = hydra_block_input; + ei_status.block_output = hydra_block_output; + ei_status.get_8390_hdr = hydra_get_8390_hdr; ei_status.reg_offset = hydra_offsets; dev->netdev_ops = &hydra_netdev_ops; @@ -173,9 +173,8 @@ static int __devinit hydra_init(struct zorro_dev *z) zorro_set_drvdata(z, dev); - printk(KERN_INFO "%s: Hydra at 0x%08llx, address " - "%pM (hydra.c " HYDRA_VERSION ")\n", - dev->name, (unsigned long long)z->resource.start, dev->dev_addr); + pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n", + dev->name, &z->resource, dev->dev_addr); return 0; } diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 519e19e23955a3c3a86d8e04f615b67daa7a996e..385dc3204cb7eefbbaa184f0601267abe7c392ee 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2095,11 +2095,11 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf) if (emac_has_feature(dev, EMAC_FTR_EMAC4)) { hdr->version = EMAC4_ETHTOOL_REGS_VER; memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev)); - return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev)); + return (void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev); } else { hdr->version = EMAC_ETHTOOL_REGS_VER; memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev)); - return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev)); + return (void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev); } } @@ -2293,7 +2293,7 @@ static int __devinit emac_check_deps(struct emac_instance *dev, if (deps[i].drvdata != NULL) there++; } - return (there == EMAC_DEP_COUNT); + return there == EMAC_DEP_COUNT; } static void emac_put_deps(struct emac_instance *dev) diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h index 9e37e3d9c51d778c072a5a7b417e6af743794944..4fec0844d59dffd34496428a900deb5d0641c3d4 100644 --- a/drivers/net/ibm_newemac/core.h +++ b/drivers/net/ibm_newemac/core.h @@ -410,7 +410,7 @@ static inline u32 *emac_xaht_base(struct emac_instance *dev) else offset = offsetof(struct emac_regs, u0.emac4.iaht1); - return ((u32 *)((ptrdiff_t)p + offset)); + return (u32 *)((ptrdiff_t)p + offset); } static inline u32 *emac_gaht_base(struct emac_instance *dev) @@ -418,7 +418,7 @@ static inline u32 *emac_gaht_base(struct emac_instance *dev) /* GAHT registers always come after an identical number of * IAHT registers. */ - return (emac_xaht_base(dev) + EMAC_XAHT_REGS(dev)); + return emac_xaht_base(dev) + EMAC_XAHT_REGS(dev); } static inline u32 *emac_iaht_base(struct emac_instance *dev) @@ -426,7 +426,7 @@ static inline u32 *emac_iaht_base(struct emac_instance *dev) /* IAHT registers always come before an identical number of * GAHT registers. */ - return (emac_xaht_base(dev)); + return emac_xaht_base(dev); } /* Ethtool get_regs complex data. diff --git a/drivers/net/ibmlana.c b/drivers/net/ibmlana.c index 294ccfb427cf13475603a7194a03df6b8cbdc619..0037a696cd0a78e880e2e5968ded58a87b70bf17 100644 --- a/drivers/net/ibmlana.c +++ b/drivers/net/ibmlana.c @@ -602,7 +602,7 @@ static void irqrx_handler(struct net_device *dev) /* set up skb fields */ skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* bookkeeping */ dev->stats.rx_packets++; diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 4734c939ad03574a63e6dd0bc9ccf6d8cf29c06a..c454b45ca7ec9caf55cd0f22d0dd7bb2438db381 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c @@ -1,122 +1,84 @@ -/**************************************************************************/ -/* */ -/* IBM eServer i/pSeries Virtual Ethernet Device Driver */ -/* Copyright (C) 2003 IBM Corp. */ -/* Originally written by Dave Larson (larson1@us.ibm.com) */ -/* Maintained by Santiago Leon (santil@us.ibm.com) */ -/* */ -/* This program is free software; you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation; either version 2 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ -/* USA */ -/* */ -/* This module contains the implementation of a virtual ethernet device */ -/* for use with IBM i/pSeries LPAR Linux. It utilizes the logical LAN */ -/* option of the RS/6000 Platform Architechture to interface with virtual */ -/* ethernet NICs that are presented to the partition by the hypervisor. */ -/* */ -/**************************************************************************/ /* - TODO: - - add support for sysfs - - possibly remove procfs support -*/ + * IBM Power Virtual Ethernet Device Driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2003, 2010 + * + * Authors: Dave Larson + * Santiago Leon + * Brian King + * Robert Jennings + * Anton Blanchard + */ #include #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include -#include #include #include +#include #include -#include #include #include #include #include -#include #include -#include #include "ibmveth.h" -#undef DEBUG - -#define ibmveth_printk(fmt, args...) \ - printk(KERN_DEBUG "%s: " fmt, __FILE__, ## args) - -#define ibmveth_error_printk(fmt, args...) \ - printk(KERN_ERR "(%s:%3.3d ua:%x) ERROR: " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) - -#ifdef DEBUG -#define ibmveth_debug_printk_no_adapter(fmt, args...) \ - printk(KERN_DEBUG "(%s:%3.3d): " fmt, __FILE__, __LINE__ , ## args) -#define ibmveth_debug_printk(fmt, args...) \ - printk(KERN_DEBUG "(%s:%3.3d ua:%x): " fmt, __FILE__, __LINE__ , adapter->vdev->unit_address, ## args) -#define ibmveth_assert(expr) \ - if(!(expr)) { \ - printk(KERN_DEBUG "assertion failed (%s:%3.3d ua:%x): %s\n", __FILE__, __LINE__, adapter->vdev->unit_address, #expr); \ - BUG(); \ - } -#else -#define ibmveth_debug_printk_no_adapter(fmt, args...) -#define ibmveth_debug_printk(fmt, args...) -#define ibmveth_assert(expr) -#endif - -static int ibmveth_open(struct net_device *dev); -static int ibmveth_close(struct net_device *dev); -static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -static int ibmveth_poll(struct napi_struct *napi, int budget); -static int ibmveth_start_xmit(struct sk_buff *skb, struct net_device *dev); -static void ibmveth_set_multicast_list(struct net_device *dev); -static int ibmveth_change_mtu(struct net_device *dev, int new_mtu); -static void ibmveth_proc_register_driver(void); -static void ibmveth_proc_unregister_driver(void); -static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter); -static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter); static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance); static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter); static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev); -static struct kobj_type ktype_veth_pool; +static struct kobj_type ktype_veth_pool; -#ifdef CONFIG_PROC_FS -#define IBMVETH_PROC_DIR "ibmveth" -static struct proc_dir_entry *ibmveth_proc_dir; -#endif static const char ibmveth_driver_name[] = "ibmveth"; -static const char ibmveth_driver_string[] = "IBM i/pSeries Virtual Ethernet Driver"; -#define ibmveth_driver_version "1.03" +static const char ibmveth_driver_string[] = "IBM Power Virtual Ethernet Driver"; +#define ibmveth_driver_version "1.04" -MODULE_AUTHOR("Santiago Leon "); -MODULE_DESCRIPTION("IBM i/pSeries Virtual Ethernet Driver"); +MODULE_AUTHOR("Santiago Leon "); +MODULE_DESCRIPTION("IBM Power Virtual Ethernet Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(ibmveth_driver_version); +static unsigned int tx_copybreak __read_mostly = 128; +module_param(tx_copybreak, uint, 0644); +MODULE_PARM_DESC(tx_copybreak, + "Maximum size of packet that is copied to a new buffer on transmit"); + +static unsigned int rx_copybreak __read_mostly = 128; +module_param(rx_copybreak, uint, 0644); +MODULE_PARM_DESC(rx_copybreak, + "Maximum size of packet that is copied to a new buffer on receive"); + +static unsigned int rx_flush __read_mostly = 0; +module_param(rx_flush, uint, 0644); +MODULE_PARM_DESC(rx_flush, "Flush receive buffers before use"); + struct ibmveth_stat { char name[ETH_GSTRING_LEN]; int offset; @@ -128,12 +90,16 @@ struct ibmveth_stat { struct ibmveth_stat ibmveth_stats[] = { { "replenish_task_cycles", IBMVETH_STAT_OFF(replenish_task_cycles) }, { "replenish_no_mem", IBMVETH_STAT_OFF(replenish_no_mem) }, - { "replenish_add_buff_failure", IBMVETH_STAT_OFF(replenish_add_buff_failure) }, - { "replenish_add_buff_success", IBMVETH_STAT_OFF(replenish_add_buff_success) }, + { "replenish_add_buff_failure", + IBMVETH_STAT_OFF(replenish_add_buff_failure) }, + { "replenish_add_buff_success", + IBMVETH_STAT_OFF(replenish_add_buff_success) }, { "rx_invalid_buffer", IBMVETH_STAT_OFF(rx_invalid_buffer) }, { "rx_no_buffer", IBMVETH_STAT_OFF(rx_no_buffer) }, { "tx_map_failed", IBMVETH_STAT_OFF(tx_map_failed) }, { "tx_send_failed", IBMVETH_STAT_OFF(tx_send_failed) }, + { "fw_enabled_ipv4_csum", IBMVETH_STAT_OFF(fw_ipv4_csum_support) }, + { "fw_enabled_ipv6_csum", IBMVETH_STAT_OFF(fw_ipv6_csum_support) }, }; /* simple methods of getting data from the current rxq entry */ @@ -144,41 +110,44 @@ static inline u32 ibmveth_rxq_flags(struct ibmveth_adapter *adapter) static inline int ibmveth_rxq_toggle(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_TOGGLE) >> IBMVETH_RXQ_TOGGLE_SHIFT; + return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_TOGGLE) >> + IBMVETH_RXQ_TOGGLE_SHIFT; } static inline int ibmveth_rxq_pending_buffer(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_toggle(adapter) == adapter->rx_queue.toggle); + return ibmveth_rxq_toggle(adapter) == adapter->rx_queue.toggle; } static inline int ibmveth_rxq_buffer_valid(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_VALID); + return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_VALID; } static inline int ibmveth_rxq_frame_offset(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK); + return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_OFF_MASK; } static inline int ibmveth_rxq_frame_length(struct ibmveth_adapter *adapter) { - return (adapter->rx_queue.queue_addr[adapter->rx_queue.index].length); + return adapter->rx_queue.queue_addr[adapter->rx_queue.index].length; } static inline int ibmveth_rxq_csum_good(struct ibmveth_adapter *adapter) { - return (ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_CSUM_GOOD); + return ibmveth_rxq_flags(adapter) & IBMVETH_RXQ_CSUM_GOOD; } /* setup the initial settings for a buffer pool */ -static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool, u32 pool_index, u32 pool_size, u32 buff_size, u32 pool_active) +static void ibmveth_init_buffer_pool(struct ibmveth_buff_pool *pool, + u32 pool_index, u32 pool_size, + u32 buff_size, u32 pool_active) { pool->size = pool_size; pool->index = pool_index; pool->buff_size = buff_size; - pool->threshold = pool_size / 2; + pool->threshold = pool_size * 7 / 8; pool->active = pool_active; } @@ -189,12 +158,11 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) pool->free_map = kmalloc(sizeof(u16) * pool->size, GFP_KERNEL); - if(!pool->free_map) { + if (!pool->free_map) return -1; - } pool->dma_addr = kmalloc(sizeof(dma_addr_t) * pool->size, GFP_KERNEL); - if(!pool->dma_addr) { + if (!pool->dma_addr) { kfree(pool->free_map); pool->free_map = NULL; return -1; @@ -202,7 +170,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) pool->skbuff = kcalloc(pool->size, sizeof(void *), GFP_KERNEL); - if(!pool->skbuff) { + if (!pool->skbuff) { kfree(pool->dma_addr); pool->dma_addr = NULL; @@ -213,9 +181,8 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) memset(pool->dma_addr, 0, sizeof(dma_addr_t) * pool->size); - for(i = 0; i < pool->size; ++i) { + for (i = 0; i < pool->size; ++i) pool->free_map[i] = i; - } atomic_set(&pool->available, 0); pool->producer_index = 0; @@ -224,10 +191,19 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) return 0; } +static inline void ibmveth_flush_buffer(void *addr, unsigned long length) +{ + unsigned long offset; + + for (offset = 0; offset < length; offset += SMP_CACHE_BYTES) + asm("dcbfl %0,%1" :: "b" (addr), "r" (offset)); +} + /* replenish the buffers for a pool. note that we don't need to * skb_reserve these since they are used for incoming... */ -static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool) +static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, + struct ibmveth_buff_pool *pool) { u32 i; u32 count = pool->size - atomic_read(&pool->available); @@ -240,23 +216,26 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc mb(); - for(i = 0; i < count; ++i) { + for (i = 0; i < count; ++i) { union ibmveth_buf_desc desc; - skb = alloc_skb(pool->buff_size, GFP_ATOMIC); + skb = netdev_alloc_skb(adapter->netdev, pool->buff_size); - if(!skb) { - ibmveth_debug_printk("replenish: unable to allocate skb\n"); + if (!skb) { + netdev_dbg(adapter->netdev, + "replenish: unable to allocate skb\n"); adapter->replenish_no_mem++; break; } free_index = pool->consumer_index; - pool->consumer_index = (pool->consumer_index + 1) % pool->size; + pool->consumer_index++; + if (pool->consumer_index >= pool->size) + pool->consumer_index = 0; index = pool->free_map[free_index]; - ibmveth_assert(index != IBM_VETH_INVALID_MAP); - ibmveth_assert(pool->skbuff[index] == NULL); + BUG_ON(index == IBM_VETH_INVALID_MAP); + BUG_ON(pool->skbuff[index] != NULL); dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, pool->buff_size, DMA_FROM_DEVICE); @@ -269,16 +248,23 @@ static void ibmveth_replenish_buffer_pool(struct ibmveth_adapter *adapter, struc pool->skbuff[index] = skb; correlator = ((u64)pool->index << 32) | index; - *(u64*)skb->data = correlator; + *(u64 *)skb->data = correlator; desc.fields.flags_len = IBMVETH_BUF_VALID | pool->buff_size; desc.fields.address = dma_addr; - lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); + if (rx_flush) { + unsigned int len = min(pool->buff_size, + adapter->netdev->mtu + + IBMVETH_BUFF_OH); + ibmveth_flush_buffer(skb->data, len); + } + lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, + desc.desc); - if (lpar_rc != H_SUCCESS) + if (lpar_rc != H_SUCCESS) { goto failure; - else { + } else { buffers_added++; adapter->replenish_add_buff_success++; } @@ -313,26 +299,31 @@ static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) adapter->replenish_task_cycles++; - for (i = (IbmVethNumBufferPools - 1); i >= 0; i--) - if(adapter->rx_buff_pool[i].active) - ibmveth_replenish_buffer_pool(adapter, - &adapter->rx_buff_pool[i]); + for (i = (IBMVETH_NUM_BUFF_POOLS - 1); i >= 0; i--) { + struct ibmveth_buff_pool *pool = &adapter->rx_buff_pool[i]; - adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); + if (pool->active && + (atomic_read(&pool->available) < pool->threshold)) + ibmveth_replenish_buffer_pool(adapter, pool); + } + + adapter->rx_no_buffer = *(u64 *)(((char*)adapter->buffer_list_addr) + + 4096 - 8); } /* empty and free ana buffer pool - also used to do cleanup in error paths */ -static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibmveth_buff_pool *pool) +static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, + struct ibmveth_buff_pool *pool) { int i; kfree(pool->free_map); pool->free_map = NULL; - if(pool->skbuff && pool->dma_addr) { - for(i = 0; i < pool->size; ++i) { + if (pool->skbuff && pool->dma_addr) { + for (i = 0; i < pool->size; ++i) { struct sk_buff *skb = pool->skbuff[i]; - if(skb) { + if (skb) { dma_unmap_single(&adapter->vdev->dev, pool->dma_addr[i], pool->buff_size, @@ -343,31 +334,32 @@ static void ibmveth_free_buffer_pool(struct ibmveth_adapter *adapter, struct ibm } } - if(pool->dma_addr) { + if (pool->dma_addr) { kfree(pool->dma_addr); pool->dma_addr = NULL; } - if(pool->skbuff) { + if (pool->skbuff) { kfree(pool->skbuff); pool->skbuff = NULL; } } /* remove a buffer from a pool */ -static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 correlator) +static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, + u64 correlator) { unsigned int pool = correlator >> 32; unsigned int index = correlator & 0xffffffffUL; unsigned int free_index; struct sk_buff *skb; - ibmveth_assert(pool < IbmVethNumBufferPools); - ibmveth_assert(index < adapter->rx_buff_pool[pool].size); + BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); + BUG_ON(index >= adapter->rx_buff_pool[pool].size); skb = adapter->rx_buff_pool[pool].skbuff[index]; - ibmveth_assert(skb != NULL); + BUG_ON(skb == NULL); adapter->rx_buff_pool[pool].skbuff[index] = NULL; @@ -377,9 +369,10 @@ static void ibmveth_remove_buffer_from_pool(struct ibmveth_adapter *adapter, u64 DMA_FROM_DEVICE); free_index = adapter->rx_buff_pool[pool].producer_index; - adapter->rx_buff_pool[pool].producer_index - = (adapter->rx_buff_pool[pool].producer_index + 1) - % adapter->rx_buff_pool[pool].size; + adapter->rx_buff_pool[pool].producer_index++; + if (adapter->rx_buff_pool[pool].producer_index >= + adapter->rx_buff_pool[pool].size) + adapter->rx_buff_pool[pool].producer_index = 0; adapter->rx_buff_pool[pool].free_map[free_index] = index; mb(); @@ -394,8 +387,8 @@ static inline struct sk_buff *ibmveth_rxq_get_buffer(struct ibmveth_adapter *ada unsigned int pool = correlator >> 32; unsigned int index = correlator & 0xffffffffUL; - ibmveth_assert(pool < IbmVethNumBufferPools); - ibmveth_assert(index < adapter->rx_buff_pool[pool].size); + BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); + BUG_ON(index >= adapter->rx_buff_pool[pool].size); return adapter->rx_buff_pool[pool].skbuff[index]; } @@ -410,10 +403,10 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) union ibmveth_buf_desc desc; unsigned long lpar_rc; - ibmveth_assert(pool < IbmVethNumBufferPools); - ibmveth_assert(index < adapter->rx_buff_pool[pool].size); + BUG_ON(pool >= IBMVETH_NUM_BUFF_POOLS); + BUG_ON(index >= adapter->rx_buff_pool[pool].size); - if(!adapter->rx_buff_pool[pool].active) { + if (!adapter->rx_buff_pool[pool].active) { ibmveth_rxq_harvest_buffer(adapter); ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]); return; @@ -425,12 +418,13 @@ static void ibmveth_rxq_recycle_buffer(struct ibmveth_adapter *adapter) lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc); - if(lpar_rc != H_SUCCESS) { - ibmveth_debug_printk("h_add_logical_lan_buffer failed during recycle rc=%ld", lpar_rc); + if (lpar_rc != H_SUCCESS) { + netdev_dbg(adapter->netdev, "h_add_logical_lan_buffer failed " + "during recycle rc=%ld", lpar_rc); ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); } - if(++adapter->rx_queue.index == adapter->rx_queue.num_slots) { + if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { adapter->rx_queue.index = 0; adapter->rx_queue.toggle = !adapter->rx_queue.toggle; } @@ -440,7 +434,7 @@ static void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter) { ibmveth_remove_buffer_from_pool(adapter, adapter->rx_queue.queue_addr[adapter->rx_queue.index].correlator); - if(++adapter->rx_queue.index == adapter->rx_queue.num_slots) { + if (++adapter->rx_queue.index == adapter->rx_queue.num_slots) { adapter->rx_queue.index = 0; adapter->rx_queue.toggle = !adapter->rx_queue.toggle; } @@ -451,7 +445,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) int i; struct device *dev = &adapter->vdev->dev; - if(adapter->buffer_list_addr != NULL) { + if (adapter->buffer_list_addr != NULL) { if (!dma_mapping_error(dev, adapter->buffer_list_dma)) { dma_unmap_single(dev, adapter->buffer_list_dma, 4096, DMA_BIDIRECTIONAL); @@ -461,7 +455,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) adapter->buffer_list_addr = NULL; } - if(adapter->filter_list_addr != NULL) { + if (adapter->filter_list_addr != NULL) { if (!dma_mapping_error(dev, adapter->filter_list_dma)) { dma_unmap_single(dev, adapter->filter_list_dma, 4096, DMA_BIDIRECTIONAL); @@ -471,7 +465,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) adapter->filter_list_addr = NULL; } - if(adapter->rx_queue.queue_addr != NULL) { + if (adapter->rx_queue.queue_addr != NULL) { if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { dma_unmap_single(dev, adapter->rx_queue.queue_dma, @@ -483,7 +477,7 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) adapter->rx_queue.queue_addr = NULL; } - for(i = 0; irx_buff_pool[i].active) ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[i]); @@ -506,9 +500,11 @@ static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter, { int rc, try_again = 1; - /* After a kexec the adapter will still be open, so our attempt to - * open it will fail. So if we get a failure we free the adapter and - * try again, but only once. */ + /* + * After a kexec the adapter will still be open, so our attempt to + * open it will fail. So if we get a failure we free the adapter and + * try again, but only once. + */ retry: rc = h_register_logical_lan(adapter->vdev->unit_address, adapter->buffer_list_dma, rxq_desc.desc, @@ -537,31 +533,32 @@ static int ibmveth_open(struct net_device *netdev) int i; struct device *dev; - ibmveth_debug_printk("open starting\n"); + netdev_dbg(netdev, "open starting\n"); napi_enable(&adapter->napi); - for(i = 0; irx_buff_pool[i].size; adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL); adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL); - if(!adapter->buffer_list_addr || !adapter->filter_list_addr) { - ibmveth_error_printk("unable to allocate filter or buffer list pages\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + if (!adapter->buffer_list_addr || !adapter->filter_list_addr) { + netdev_err(netdev, "unable to allocate filter or buffer list " + "pages\n"); + rc = -ENOMEM; + goto err_out; } - adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * rxq_entries; - adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, GFP_KERNEL); + adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * + rxq_entries; + adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, + GFP_KERNEL); - if(!adapter->rx_queue.queue_addr) { - ibmveth_error_printk("unable to allocate rx queue pages\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + if (!adapter->rx_queue.queue_addr) { + netdev_err(netdev, "unable to allocate rx queue pages\n"); + rc = -ENOMEM; + goto err_out; } dev = &adapter->vdev->dev; @@ -577,10 +574,10 @@ static int ibmveth_open(struct net_device *netdev) if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || (dma_mapping_error(dev, adapter->filter_list_dma)) || (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { - ibmveth_error_printk("unable to map filter or buffer list pages\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + netdev_err(netdev, "unable to map filter or buffer list " + "pages\n"); + rc = -ENOMEM; + goto err_out; } adapter->rx_queue.index = 0; @@ -590,79 +587,86 @@ static int ibmveth_open(struct net_device *netdev) memcpy(&mac_address, netdev->dev_addr, netdev->addr_len); mac_address = mac_address >> 16; - rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | adapter->rx_queue.queue_len; + rxq_desc.fields.flags_len = IBMVETH_BUF_VALID | + adapter->rx_queue.queue_len; rxq_desc.fields.address = adapter->rx_queue.queue_dma; - ibmveth_debug_printk("buffer list @ 0x%p\n", adapter->buffer_list_addr); - ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); - ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); + netdev_dbg(netdev, "buffer list @ 0x%p\n", adapter->buffer_list_addr); + netdev_dbg(netdev, "filter list @ 0x%p\n", adapter->filter_list_addr); + netdev_dbg(netdev, "receive q @ 0x%p\n", adapter->rx_queue.queue_addr); h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address); - if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); - ibmveth_error_printk("buffer TCE:0x%llx filter TCE:0x%llx rxq desc:0x%llx MAC:0x%llx\n", + if (lpar_rc != H_SUCCESS) { + netdev_err(netdev, "h_register_logical_lan failed with %ld\n", + lpar_rc); + netdev_err(netdev, "buffer TCE:0x%llx filter TCE:0x%llx rxq " + "desc:0x%llx MAC:0x%llx\n", adapter->buffer_list_dma, adapter->filter_list_dma, rxq_desc.desc, mac_address); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENONET; + rc = -ENONET; + goto err_out; } - for(i = 0; irx_buff_pool[i].active) + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { + if (!adapter->rx_buff_pool[i].active) continue; if (ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[i])) { - ibmveth_error_printk("unable to alloc pool\n"); + netdev_err(netdev, "unable to alloc pool\n"); adapter->rx_buff_pool[i].active = 0; - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM ; + rc = -ENOMEM; + goto err_out; } } - ibmveth_debug_printk("registering irq 0x%x\n", netdev->irq); - if((rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, netdev)) != 0) { - ibmveth_error_printk("unable to request irq 0x%x, rc %d\n", netdev->irq, rc); + netdev_dbg(netdev, "registering irq 0x%x\n", netdev->irq); + rc = request_irq(netdev->irq, ibmveth_interrupt, 0, netdev->name, + netdev); + if (rc != 0) { + netdev_err(netdev, "unable to request irq 0x%x, rc %d\n", + netdev->irq, rc); do { rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY)); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return rc; + goto err_out; } adapter->bounce_buffer = kmalloc(netdev->mtu + IBMVETH_BUFF_OH, GFP_KERNEL); if (!adapter->bounce_buffer) { - ibmveth_error_printk("unable to allocate bounce buffer\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + netdev_err(netdev, "unable to allocate bounce buffer\n"); + rc = -ENOMEM; + goto err_out_free_irq; } adapter->bounce_buffer_dma = dma_map_single(&adapter->vdev->dev, adapter->bounce_buffer, netdev->mtu + IBMVETH_BUFF_OH, DMA_BIDIRECTIONAL); if (dma_mapping_error(dev, adapter->bounce_buffer_dma)) { - ibmveth_error_printk("unable to map bounce buffer\n"); - ibmveth_cleanup(adapter); - napi_disable(&adapter->napi); - return -ENOMEM; + netdev_err(netdev, "unable to map bounce buffer\n"); + rc = -ENOMEM; + goto err_out_free_irq; } - ibmveth_debug_printk("initial replenish cycle\n"); + netdev_dbg(netdev, "initial replenish cycle\n"); ibmveth_interrupt(netdev->irq, netdev); netif_start_queue(netdev); - ibmveth_debug_printk("open complete\n"); + netdev_dbg(netdev, "open complete\n"); return 0; + +err_out_free_irq: + free_irq(netdev->irq, netdev); +err_out: + ibmveth_cleanup(adapter); + napi_disable(&adapter->napi); + return rc; } static int ibmveth_close(struct net_device *netdev) @@ -670,7 +674,7 @@ static int ibmveth_close(struct net_device *netdev) struct ibmveth_adapter *adapter = netdev_priv(netdev); long lpar_rc; - ibmveth_debug_printk("close starting\n"); + netdev_dbg(netdev, "close starting\n"); napi_disable(&adapter->napi); @@ -683,26 +687,29 @@ static int ibmveth_close(struct net_device *netdev) lpar_rc = h_free_logical_lan(adapter->vdev->unit_address); } while (H_IS_LONG_BUSY(lpar_rc) || (lpar_rc == H_BUSY)); - if(lpar_rc != H_SUCCESS) - { - ibmveth_error_printk("h_free_logical_lan failed with %lx, continuing with close\n", - lpar_rc); + if (lpar_rc != H_SUCCESS) { + netdev_err(netdev, "h_free_logical_lan failed with %lx, " + "continuing with close\n", lpar_rc); } free_irq(netdev->irq, netdev); - adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8); + adapter->rx_no_buffer = *(u64 *)(((char *)adapter->buffer_list_addr) + + 4096 - 8); ibmveth_cleanup(adapter); - ibmveth_debug_printk("close complete\n"); + netdev_dbg(netdev, "close complete\n"); return 0; } -static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE); - cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | ADVERTISED_FIBRE); +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | + SUPPORTED_FIBRE); + cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | + ADVERTISED_FIBRE); cmd->speed = SPEED_1000; cmd->duplex = DUPLEX_FULL; cmd->port = PORT_FIBRE; @@ -714,12 +721,16 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) return 0; } -static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { +static void netdev_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ strncpy(info->driver, ibmveth_driver_name, sizeof(info->driver) - 1); - strncpy(info->version, ibmveth_driver_version, sizeof(info->version) - 1); + strncpy(info->version, ibmveth_driver_version, + sizeof(info->version) - 1); } -static u32 netdev_get_link(struct net_device *dev) { +static u32 netdev_get_link(struct net_device *dev) +{ return 1; } @@ -727,18 +738,20 @@ static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data) { struct ibmveth_adapter *adapter = netdev_priv(dev); - if (data) + if (data) { adapter->rx_csum = 1; - else { + } else { /* - * Since the ibmveth firmware interface does not have the concept of - * separate tx/rx checksum offload enable, if rx checksum is disabled - * we also have to disable tx checksum offload. Once we disable rx - * checksum offload, we are no longer allowed to send tx buffers that - * are not properly checksummed. + * Since the ibmveth firmware interface does not have the + * concept of separate tx/rx checksum offload enable, if rx + * checksum is disabled we also have to disable tx checksum + * offload. Once we disable rx checksum offload, we are no + * longer allowed to send tx buffers that are not properly + * checksummed. */ adapter->rx_csum = 0; dev->features &= ~NETIF_F_IP_CSUM; + dev->features &= ~NETIF_F_IPV6_CSUM; } } @@ -747,10 +760,15 @@ static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data) struct ibmveth_adapter *adapter = netdev_priv(dev); if (data) { - dev->features |= NETIF_F_IP_CSUM; + if (adapter->fw_ipv4_csum_support) + dev->features |= NETIF_F_IP_CSUM; + if (adapter->fw_ipv6_csum_support) + dev->features |= NETIF_F_IPV6_CSUM; adapter->rx_csum = 1; - } else + } else { dev->features &= ~NETIF_F_IP_CSUM; + dev->features &= ~NETIF_F_IPV6_CSUM; + } } static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, @@ -758,7 +776,8 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, { struct ibmveth_adapter *adapter = netdev_priv(dev); unsigned long set_attr, clr_attr, ret_attr; - long ret; + unsigned long set_attr6, clr_attr6; + long ret, ret6; int rc1 = 0, rc2 = 0; int restart = 0; @@ -772,10 +791,13 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, set_attr = 0; clr_attr = 0; - if (data) + if (data) { set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; - else + set_attr6 = IBMVETH_ILLAN_IPV6_TCP_CSUM; + } else { clr_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; + clr_attr6 = IBMVETH_ILLAN_IPV6_TCP_CSUM; + } ret = h_illan_attributes(adapter->vdev->unit_address, 0, 0, &ret_attr); @@ -786,18 +808,39 @@ static int ibmveth_set_csum_offload(struct net_device *dev, u32 data, set_attr, &ret_attr); if (ret != H_SUCCESS) { - rc1 = -EIO; - ibmveth_error_printk("unable to change checksum offload settings." - " %d rc=%ld\n", data, ret); + netdev_err(dev, "unable to change IPv4 checksum " + "offload settings. %d rc=%ld\n", + data, ret); ret = h_illan_attributes(adapter->vdev->unit_address, set_attr, clr_attr, &ret_attr); + } else { + adapter->fw_ipv4_csum_support = data; + } + + ret6 = h_illan_attributes(adapter->vdev->unit_address, + clr_attr6, set_attr6, &ret_attr); + + if (ret6 != H_SUCCESS) { + netdev_err(dev, "unable to change IPv6 checksum " + "offload settings. %d rc=%ld\n", + data, ret); + + ret = h_illan_attributes(adapter->vdev->unit_address, + set_attr6, clr_attr6, + &ret_attr); } else + adapter->fw_ipv6_csum_support = data; + + if (ret == H_SUCCESS || ret6 == H_SUCCESS) done(dev, data); + else + rc1 = -EIO; } else { rc1 = -EIO; - ibmveth_error_printk("unable to change checksum offload settings." - " %d rc=%ld ret_attr=%lx\n", data, ret, ret_attr); + netdev_err(dev, "unable to change checksum offload settings." + " %d rc=%ld ret_attr=%lx\n", data, ret, + ret_attr); } if (restart) @@ -821,13 +864,14 @@ static int ibmveth_set_tx_csum(struct net_device *dev, u32 data) struct ibmveth_adapter *adapter = netdev_priv(dev); int rc = 0; - if (data && (dev->features & NETIF_F_IP_CSUM)) + if (data && (dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) return 0; - if (!data && !(dev->features & NETIF_F_IP_CSUM)) + if (!data && !(dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))) return 0; if (data && !adapter->rx_csum) - rc = ibmveth_set_csum_offload(dev, data, ibmveth_set_tx_csum_flags); + rc = ibmveth_set_csum_offload(dev, data, + ibmveth_set_tx_csum_flags); else ibmveth_set_tx_csum_flags(dev, data); @@ -881,6 +925,7 @@ static const struct ethtool_ops netdev_ethtool_ops = { .get_strings = ibmveth_get_strings, .get_sset_count = ibmveth_get_sset_count, .get_ethtool_stats = ibmveth_get_ethtool_stats, + .set_sg = ethtool_op_set_sg, }; static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -890,129 +935,216 @@ static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) #define page_offset(v) ((unsigned long)(v) & ((1 << 12) - 1)) -static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, - struct net_device *netdev) +static int ibmveth_send(struct ibmveth_adapter *adapter, + union ibmveth_buf_desc *descs) { - struct ibmveth_adapter *adapter = netdev_priv(netdev); - union ibmveth_buf_desc desc; - unsigned long lpar_rc; unsigned long correlator; - unsigned long flags; unsigned int retry_count; - unsigned int tx_dropped = 0; - unsigned int tx_bytes = 0; - unsigned int tx_packets = 0; - unsigned int tx_send_failed = 0; - unsigned int tx_map_failed = 0; - int used_bounce = 0; - unsigned long data_dma_addr; + unsigned long ret; - desc.fields.flags_len = IBMVETH_BUF_VALID | skb->len; + /* + * The retry count sets a maximum for the number of broadcast and + * multicast destinations within the system. + */ + retry_count = 1024; + correlator = 0; + do { + ret = h_send_logical_lan(adapter->vdev->unit_address, + descs[0].desc, descs[1].desc, + descs[2].desc, descs[3].desc, + descs[4].desc, descs[5].desc, + correlator, &correlator); + } while ((ret == H_BUSY) && (retry_count--)); + if (ret != H_SUCCESS && ret != H_DROPPED) { + netdev_err(adapter->netdev, "tx: h_send_logical_lan failed " + "with rc=%ld\n", ret); + return 1; + } + + return 0; +} + +static netdev_tx_t ibmveth_start_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct ibmveth_adapter *adapter = netdev_priv(netdev); + unsigned int desc_flags; + union ibmveth_buf_desc descs[6]; + int last, i; + int force_bounce = 0; + + /* + * veth handles a maximum of 6 segments including the header, so + * we have to linearize the skb if there are more than this. + */ + if (skb_shinfo(skb)->nr_frags > 5 && __skb_linearize(skb)) { + netdev->stats.tx_dropped++; + goto out; + } + + /* veth can't checksum offload UDP */ if (skb->ip_summed == CHECKSUM_PARTIAL && - ip_hdr(skb)->protocol != IPPROTO_TCP && skb_checksum_help(skb)) { - ibmveth_error_printk("tx: failed to checksum packet\n"); - tx_dropped++; + ((skb->protocol == htons(ETH_P_IP) && + ip_hdr(skb)->protocol != IPPROTO_TCP) || + (skb->protocol == htons(ETH_P_IPV6) && + ipv6_hdr(skb)->nexthdr != IPPROTO_TCP)) && + skb_checksum_help(skb)) { + + netdev_err(netdev, "tx: failed to checksum packet\n"); + netdev->stats.tx_dropped++; goto out; } + desc_flags = IBMVETH_BUF_VALID; + if (skb->ip_summed == CHECKSUM_PARTIAL) { - unsigned char *buf = skb_transport_header(skb) + skb->csum_offset; + unsigned char *buf = skb_transport_header(skb) + + skb->csum_offset; - desc.fields.flags_len |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD); + desc_flags |= (IBMVETH_BUF_NO_CSUM | IBMVETH_BUF_CSUM_GOOD); /* Need to zero out the checksum */ buf[0] = 0; buf[1] = 0; } - data_dma_addr = dma_map_single(&adapter->vdev->dev, skb->data, - skb->len, DMA_TO_DEVICE); - if (dma_mapping_error(&adapter->vdev->dev, data_dma_addr)) { - if (!firmware_has_feature(FW_FEATURE_CMO)) - ibmveth_error_printk("tx: unable to map xmit buffer\n"); +retry_bounce: + memset(descs, 0, sizeof(descs)); + + /* + * If a linear packet is below the rx threshold then + * copy it into the static bounce buffer. This avoids the + * cost of a TCE insert and remove. + */ + if (force_bounce || (!skb_is_nonlinear(skb) && + (skb->len < tx_copybreak))) { skb_copy_from_linear_data(skb, adapter->bounce_buffer, skb->len); - desc.fields.address = adapter->bounce_buffer_dma; - tx_map_failed++; - used_bounce = 1; - wmb(); - } else - desc.fields.address = data_dma_addr; - - /* send the frame. Arbitrarily set retrycount to 1024 */ - correlator = 0; - retry_count = 1024; - do { - lpar_rc = h_send_logical_lan(adapter->vdev->unit_address, - desc.desc, 0, 0, 0, 0, 0, - correlator, &correlator); - } while ((lpar_rc == H_BUSY) && (retry_count--)); - - if(lpar_rc != H_SUCCESS && lpar_rc != H_DROPPED) { - ibmveth_error_printk("tx: h_send_logical_lan failed with rc=%ld\n", lpar_rc); - ibmveth_error_printk("tx: valid=%d, len=%d, address=0x%08x\n", - (desc.fields.flags_len & IBMVETH_BUF_VALID) ? 1 : 0, - skb->len, desc.fields.address); - tx_send_failed++; - tx_dropped++; - } else { - tx_packets++; - tx_bytes += skb->len; - netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ + + descs[0].fields.flags_len = desc_flags | skb->len; + descs[0].fields.address = adapter->bounce_buffer_dma; + + if (ibmveth_send(adapter, descs)) { + adapter->tx_send_failed++; + netdev->stats.tx_dropped++; + } else { + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + } + + goto out; + } + + /* Map the header */ + descs[0].fields.address = dma_map_single(&adapter->vdev->dev, skb->data, + skb_headlen(skb), + DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->vdev->dev, descs[0].fields.address)) + goto map_failed; + + descs[0].fields.flags_len = desc_flags | skb_headlen(skb); + + /* Map the frags */ + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + unsigned long dma_addr; + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + dma_addr = dma_map_page(&adapter->vdev->dev, frag->page, + frag->page_offset, frag->size, + DMA_TO_DEVICE); + + if (dma_mapping_error(&adapter->vdev->dev, dma_addr)) + goto map_failed_frags; + + descs[i+1].fields.flags_len = desc_flags | frag->size; + descs[i+1].fields.address = dma_addr; } - if (!used_bounce) - dma_unmap_single(&adapter->vdev->dev, data_dma_addr, - skb->len, DMA_TO_DEVICE); + if (ibmveth_send(adapter, descs)) { + adapter->tx_send_failed++; + netdev->stats.tx_dropped++; + } else { + netdev->stats.tx_packets++; + netdev->stats.tx_bytes += skb->len; + } -out: spin_lock_irqsave(&adapter->stats_lock, flags); - netdev->stats.tx_dropped += tx_dropped; - netdev->stats.tx_bytes += tx_bytes; - netdev->stats.tx_packets += tx_packets; - adapter->tx_send_failed += tx_send_failed; - adapter->tx_map_failed += tx_map_failed; - spin_unlock_irqrestore(&adapter->stats_lock, flags); + for (i = 0; i < skb_shinfo(skb)->nr_frags + 1; i++) + dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, + descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, + DMA_TO_DEVICE); +out: dev_kfree_skb(skb); return NETDEV_TX_OK; + +map_failed_frags: + last = i+1; + for (i = 0; i < last; i++) + dma_unmap_page(&adapter->vdev->dev, descs[i].fields.address, + descs[i].fields.flags_len & IBMVETH_BUF_LEN_MASK, + DMA_TO_DEVICE); + +map_failed: + if (!firmware_has_feature(FW_FEATURE_CMO)) + netdev_err(netdev, "tx: unable to map xmit buffer\n"); + adapter->tx_map_failed++; + skb_linearize(skb); + force_bounce = 1; + goto retry_bounce; } static int ibmveth_poll(struct napi_struct *napi, int budget) { - struct ibmveth_adapter *adapter = container_of(napi, struct ibmveth_adapter, napi); + struct ibmveth_adapter *adapter = + container_of(napi, struct ibmveth_adapter, napi); struct net_device *netdev = adapter->netdev; int frames_processed = 0; unsigned long lpar_rc; - restart_poll: +restart_poll: do { - struct sk_buff *skb; - if (!ibmveth_rxq_pending_buffer(adapter)) break; - rmb(); + smp_rmb(); if (!ibmveth_rxq_buffer_valid(adapter)) { wmb(); /* suggested by larson1 */ adapter->rx_invalid_buffer++; - ibmveth_debug_printk("recycling invalid buffer\n"); + netdev_dbg(netdev, "recycling invalid buffer\n"); ibmveth_rxq_recycle_buffer(adapter); } else { + struct sk_buff *skb, *new_skb; int length = ibmveth_rxq_frame_length(adapter); int offset = ibmveth_rxq_frame_offset(adapter); int csum_good = ibmveth_rxq_csum_good(adapter); skb = ibmveth_rxq_get_buffer(adapter); - if (csum_good) - skb->ip_summed = CHECKSUM_UNNECESSARY; - ibmveth_rxq_harvest_buffer(adapter); + new_skb = NULL; + if (length < rx_copybreak) + new_skb = netdev_alloc_skb(netdev, length); + + if (new_skb) { + skb_copy_to_linear_data(new_skb, + skb->data + offset, + length); + if (rx_flush) + ibmveth_flush_buffer(skb->data, + length + offset); + skb = new_skb; + ibmveth_rxq_recycle_buffer(adapter); + } else { + ibmveth_rxq_harvest_buffer(adapter); + skb_reserve(skb, offset); + } - skb_reserve(skb, offset); skb_put(skb, length); skb->protocol = eth_type_trans(skb, netdev); + if (csum_good) + skb->ip_summed = CHECKSUM_UNNECESSARY; + netif_receive_skb(skb); /* send it up */ netdev->stats.rx_packets++; @@ -1030,7 +1162,7 @@ static int ibmveth_poll(struct napi_struct *napi, int budget) lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_ENABLE); - ibmveth_assert(lpar_rc == H_SUCCESS); + BUG_ON(lpar_rc != H_SUCCESS); napi_complete(napi); @@ -1054,7 +1186,7 @@ static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance) if (napi_schedule_prep(&adapter->napi)) { lpar_rc = h_vio_signal(adapter->vdev->unit_address, VIO_IRQ_DISABLE); - ibmveth_assert(lpar_rc == H_SUCCESS); + BUG_ON(lpar_rc != H_SUCCESS); __napi_schedule(&adapter->napi); } return IRQ_HANDLED; @@ -1071,8 +1203,9 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastEnableRecv | IbmVethMcastDisableFiltering, 0); - if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_multicast_ctrl rc=%ld when entering promisc mode\n", lpar_rc); + if (lpar_rc != H_SUCCESS) { + netdev_err(netdev, "h_multicast_ctrl rc=%ld when " + "entering promisc mode\n", lpar_rc); } } else { struct netdev_hw_addr *ha; @@ -1082,19 +1215,23 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) IbmVethMcastDisableFiltering | IbmVethMcastClearFilterTable, 0); - if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_multicast_ctrl rc=%ld when attempting to clear filter table\n", lpar_rc); + if (lpar_rc != H_SUCCESS) { + netdev_err(netdev, "h_multicast_ctrl rc=%ld when " + "attempting to clear filter table\n", + lpar_rc); } /* add the addresses to the filter table */ netdev_for_each_mc_addr(ha, netdev) { - // add the multicast address to the filter table + /* add the multicast address to the filter table */ unsigned long mcast_addr = 0; memcpy(((char *)&mcast_addr)+2, ha->addr, 6); lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastAddFilter, mcast_addr); - if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_multicast_ctrl rc=%ld when adding an entry to the filter table\n", lpar_rc); + if (lpar_rc != H_SUCCESS) { + netdev_err(netdev, "h_multicast_ctrl rc=%ld " + "when adding an entry to the filter " + "table\n", lpar_rc); } } @@ -1102,8 +1239,9 @@ static void ibmveth_set_multicast_list(struct net_device *netdev) lpar_rc = h_multicast_ctrl(adapter->vdev->unit_address, IbmVethMcastEnableFiltering, 0); - if(lpar_rc != H_SUCCESS) { - ibmveth_error_printk("h_multicast_ctrl rc=%ld when enabling filtering\n", lpar_rc); + if (lpar_rc != H_SUCCESS) { + netdev_err(netdev, "h_multicast_ctrl rc=%ld when " + "enabling filtering\n", lpar_rc); } } } @@ -1116,14 +1254,14 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) int i, rc; int need_restart = 0; - if (new_mtu < IBMVETH_MAX_MTU) + if (new_mtu < IBMVETH_MIN_MTU) return -EINVAL; - for (i = 0; i < IbmVethNumBufferPools; i++) + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) break; - if (i == IbmVethNumBufferPools) + if (i == IBMVETH_NUM_BUFF_POOLS) return -EINVAL; /* Deactivate all the buffer pools so that the next loop can activate @@ -1136,7 +1274,7 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) } /* Look for an active buffer pool that can hold the new MTU */ - for(i = 0; irx_buff_pool[i].active = 1; if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { @@ -1190,7 +1328,7 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev) ret = IBMVETH_BUFF_LIST_SIZE + IBMVETH_FILT_LIST_SIZE; ret += IOMMU_PAGE_ALIGN(netdev->mtu); - for (i = 0; i < IbmVethNumBufferPools; i++) { + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { /* add the size of the active receive buffers */ if (adapter->rx_buff_pool[i].active) ret += @@ -1219,41 +1357,36 @@ static const struct net_device_ops ibmveth_netdev_ops = { #endif }; -static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id) +static int __devinit ibmveth_probe(struct vio_dev *dev, + const struct vio_device_id *id) { int rc, i; - long ret; struct net_device *netdev; struct ibmveth_adapter *adapter; - unsigned long set_attr, ret_attr; - unsigned char *mac_addr_p; unsigned int *mcastFilterSize_p; + dev_dbg(&dev->dev, "entering ibmveth_probe for UA 0x%x\n", + dev->unit_address); - ibmveth_debug_printk_no_adapter("entering ibmveth_probe for UA 0x%x\n", - dev->unit_address); - - mac_addr_p = (unsigned char *) vio_get_attribute(dev, - VETH_MAC_ADDR, NULL); - if(!mac_addr_p) { - printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find VETH_MAC_ADDR " - "attribute\n", __FILE__, __LINE__); - return 0; + mac_addr_p = (unsigned char *)vio_get_attribute(dev, VETH_MAC_ADDR, + NULL); + if (!mac_addr_p) { + dev_err(&dev->dev, "Can't find VETH_MAC_ADDR attribute\n"); + return -EINVAL; } - mcastFilterSize_p = (unsigned int *) vio_get_attribute(dev, + mcastFilterSize_p = (unsigned int *)vio_get_attribute(dev, VETH_MCAST_FILTER_SIZE, NULL); - if(!mcastFilterSize_p) { - printk(KERN_ERR "(%s:%3.3d) ERROR: Can't find " - "VETH_MCAST_FILTER_SIZE attribute\n", - __FILE__, __LINE__); - return 0; + if (!mcastFilterSize_p) { + dev_err(&dev->dev, "Can't find VETH_MCAST_FILTER_SIZE " + "attribute\n"); + return -EINVAL; } netdev = alloc_etherdev(sizeof(struct ibmveth_adapter)); - if(!netdev) + if (!netdev) return -ENOMEM; adapter = netdev_priv(netdev); @@ -1261,19 +1394,19 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ adapter->vdev = dev; adapter->netdev = netdev; - adapter->mcastFilterSize= *mcastFilterSize_p; + adapter->mcastFilterSize = *mcastFilterSize_p; adapter->pool_config = 0; netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16); - /* Some older boxes running PHYP non-natively have an OF that - returns a 8-byte local-mac-address field (and the first - 2 bytes have to be ignored) while newer boxes' OF return - a 6-byte field. Note that IEEE 1275 specifies that - local-mac-address must be a 6-byte field. - The RPA doc specifies that the first byte must be 10b, so - we'll just look for it to solve this 8 vs. 6 byte field issue */ - + /* + * Some older boxes running PHYP non-natively have an OF that returns + * a 8-byte local-mac-address field (and the first 2 bytes have to be + * ignored) while newer boxes' OF return a 6-byte field. Note that + * IEEE 1275 specifies that local-mac-address must be a 6-byte field. + * The RPA doc specifies that the first byte must be 10b, so we'll + * just look for it to solve this 8 vs. 6 byte field issue + */ if ((*mac_addr_p & 0x3) != 0x02) mac_addr_p += 2; @@ -1284,12 +1417,11 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ netdev->netdev_ops = &ibmveth_netdev_ops; netdev->ethtool_ops = &netdev_ethtool_ops; SET_NETDEV_DEV(netdev, &dev->dev); - netdev->features |= NETIF_F_LLTX; - spin_lock_init(&adapter->stats_lock); + netdev->features |= NETIF_F_SG; memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len); - for(i = 0; irx_buff_pool[i].kobj; int error; @@ -1302,41 +1434,25 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_ kobject_uevent(kobj, KOBJ_ADD); } - ibmveth_debug_printk("adapter @ 0x%p\n", adapter); + netdev_dbg(netdev, "adapter @ 0x%p\n", adapter); adapter->buffer_list_dma = DMA_ERROR_CODE; adapter->filter_list_dma = DMA_ERROR_CODE; adapter->rx_queue.queue_dma = DMA_ERROR_CODE; - ibmveth_debug_printk("registering netdev...\n"); + netdev_dbg(netdev, "registering netdev...\n"); - ret = h_illan_attributes(dev->unit_address, 0, 0, &ret_attr); - - if (ret == H_SUCCESS && !(ret_attr & IBMVETH_ILLAN_ACTIVE_TRUNK) && - !(ret_attr & IBMVETH_ILLAN_TRUNK_PRI_MASK) && - (ret_attr & IBMVETH_ILLAN_PADDED_PKT_CSUM)) { - set_attr = IBMVETH_ILLAN_IPV4_TCP_CSUM; - - ret = h_illan_attributes(dev->unit_address, 0, set_attr, &ret_attr); - - if (ret == H_SUCCESS) { - adapter->rx_csum = 1; - netdev->features |= NETIF_F_IP_CSUM; - } else - ret = h_illan_attributes(dev->unit_address, set_attr, 0, &ret_attr); - } + ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags); rc = register_netdev(netdev); - if(rc) { - ibmveth_debug_printk("failed to register netdev rc=%d\n", rc); + if (rc) { + netdev_dbg(netdev, "failed to register netdev rc=%d\n", rc); free_netdev(netdev); return rc; } - ibmveth_debug_printk("registered\n"); - - ibmveth_proc_register_adapter(adapter); + netdev_dbg(netdev, "registered\n"); return 0; } @@ -1347,114 +1463,23 @@ static int __devexit ibmveth_remove(struct vio_dev *dev) struct ibmveth_adapter *adapter = netdev_priv(netdev); int i; - for(i = 0; irx_buff_pool[i].kobj); unregister_netdev(netdev); - ibmveth_proc_unregister_adapter(adapter); - free_netdev(netdev); dev_set_drvdata(&dev->dev, NULL); return 0; } -#ifdef CONFIG_PROC_FS -static void ibmveth_proc_register_driver(void) -{ - ibmveth_proc_dir = proc_mkdir(IBMVETH_PROC_DIR, init_net.proc_net); - if (ibmveth_proc_dir) { - } -} - -static void ibmveth_proc_unregister_driver(void) -{ - remove_proc_entry(IBMVETH_PROC_DIR, init_net.proc_net); -} - -static int ibmveth_show(struct seq_file *seq, void *v) -{ - struct ibmveth_adapter *adapter = seq->private; - char *current_mac = (char *) adapter->netdev->dev_addr; - char *firmware_mac = (char *) &adapter->mac_addr; - - seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version); - - seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address); - seq_printf(seq, "Current MAC: %pM\n", current_mac); - seq_printf(seq, "Firmware MAC: %pM\n", firmware_mac); - - seq_printf(seq, "\nAdapter Statistics:\n"); - seq_printf(seq, " TX: vio_map_single failres: %lld\n", adapter->tx_map_failed); - seq_printf(seq, " send failures: %lld\n", adapter->tx_send_failed); - seq_printf(seq, " RX: replenish task cycles: %lld\n", adapter->replenish_task_cycles); - seq_printf(seq, " alloc_skb_failures: %lld\n", adapter->replenish_no_mem); - seq_printf(seq, " add buffer failures: %lld\n", adapter->replenish_add_buff_failure); - seq_printf(seq, " invalid buffers: %lld\n", adapter->rx_invalid_buffer); - seq_printf(seq, " no buffers: %lld\n", adapter->rx_no_buffer); - - return 0; -} - -static int ibmveth_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, ibmveth_show, PDE(inode)->data); -} - -static const struct file_operations ibmveth_proc_fops = { - .owner = THIS_MODULE, - .open = ibmveth_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) -{ - struct proc_dir_entry *entry; - if (ibmveth_proc_dir) { - char u_addr[10]; - sprintf(u_addr, "%x", adapter->vdev->unit_address); - entry = proc_create_data(u_addr, S_IFREG, ibmveth_proc_dir, - &ibmveth_proc_fops, adapter); - if (!entry) - ibmveth_error_printk("Cannot create adapter proc entry"); - } -} - -static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter) -{ - if (ibmveth_proc_dir) { - char u_addr[10]; - sprintf(u_addr, "%x", adapter->vdev->unit_address); - remove_proc_entry(u_addr, ibmveth_proc_dir); - } -} - -#else /* CONFIG_PROC_FS */ -static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter) -{ -} - -static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter) -{ -} -static void ibmveth_proc_register_driver(void) -{ -} - -static void ibmveth_proc_unregister_driver(void) -{ -} -#endif /* CONFIG_PROC_FS */ - static struct attribute veth_active_attr; static struct attribute veth_num_attr; static struct attribute veth_size_attr; -static ssize_t veth_pool_show(struct kobject * kobj, - struct attribute * attr, char * buf) +static ssize_t veth_pool_show(struct kobject *kobj, + struct attribute *attr, char *buf) { struct ibmveth_buff_pool *pool = container_of(kobj, struct ibmveth_buff_pool, @@ -1469,8 +1494,8 @@ static ssize_t veth_pool_show(struct kobject * kobj, return 0; } -static ssize_t veth_pool_store(struct kobject * kobj, struct attribute * attr, -const char * buf, size_t count) +static ssize_t veth_pool_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) { struct ibmveth_buff_pool *pool = container_of(kobj, struct ibmveth_buff_pool, @@ -1484,8 +1509,9 @@ const char * buf, size_t count) if (attr == &veth_active_attr) { if (value && !pool->active) { if (netif_running(netdev)) { - if(ibmveth_alloc_buffer_pool(pool)) { - ibmveth_error_printk("unable to alloc pool\n"); + if (ibmveth_alloc_buffer_pool(pool)) { + netdev_err(netdev, + "unable to alloc pool\n"); return -ENOMEM; } pool->active = 1; @@ -1494,14 +1520,15 @@ const char * buf, size_t count) adapter->pool_config = 0; if ((rc = ibmveth_open(netdev))) return rc; - } else + } else { pool->active = 1; + } } else if (!value && pool->active) { int mtu = netdev->mtu + IBMVETH_BUFF_OH; int i; /* Make sure there is a buffer pool with buffers that can hold a packet of the size of the MTU */ - for (i = 0; i < IbmVethNumBufferPools; i++) { + for (i = 0; i < IBMVETH_NUM_BUFF_POOLS; i++) { if (pool == &adapter->rx_buff_pool[i]) continue; if (!adapter->rx_buff_pool[i].active) @@ -1510,8 +1537,8 @@ const char * buf, size_t count) break; } - if (i == IbmVethNumBufferPools) { - ibmveth_error_printk("no active pool >= MTU\n"); + if (i == IBMVETH_NUM_BUFF_POOLS) { + netdev_err(netdev, "no active pool >= MTU\n"); return -EPERM; } @@ -1526,9 +1553,9 @@ const char * buf, size_t count) pool->active = 0; } } else if (attr == &veth_num_attr) { - if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) + if (value <= 0 || value > IBMVETH_MAX_POOL_COUNT) { return -EINVAL; - else { + } else { if (netif_running(netdev)) { adapter->pool_config = 1; ibmveth_close(netdev); @@ -1536,13 +1563,14 @@ const char * buf, size_t count) pool->size = value; if ((rc = ibmveth_open(netdev))) return rc; - } else + } else { pool->size = value; + } } } else if (attr == &veth_size_attr) { - if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) + if (value <= IBMVETH_BUFF_OH || value > IBMVETH_MAX_BUF_SIZE) { return -EINVAL; - else { + } else { if (netif_running(netdev)) { adapter->pool_config = 1; ibmveth_close(netdev); @@ -1550,8 +1578,9 @@ const char * buf, size_t count) pool->buff_size = value; if ((rc = ibmveth_open(netdev))) return rc; - } else + } else { pool->buff_size = value; + } } } @@ -1561,16 +1590,16 @@ const char * buf, size_t count) } -#define ATTR(_name, _mode) \ - struct attribute veth_##_name##_attr = { \ - .name = __stringify(_name), .mode = _mode, \ - }; +#define ATTR(_name, _mode) \ + struct attribute veth_##_name##_attr = { \ + .name = __stringify(_name), .mode = _mode, \ + }; static ATTR(active, 0644); static ATTR(num, 0644); static ATTR(size, 0644); -static struct attribute * veth_pool_attrs[] = { +static struct attribute *veth_pool_attrs[] = { &veth_active_attr, &veth_num_attr, &veth_size_attr, @@ -1595,7 +1624,7 @@ static int ibmveth_resume(struct device *dev) return 0; } -static struct vio_device_id ibmveth_device_table[] __devinitdata= { +static struct vio_device_id ibmveth_device_table[] __devinitdata = { { "network", "IBM,l-lan"}, { "", "" } }; @@ -1619,9 +1648,8 @@ static struct vio_driver ibmveth_driver = { static int __init ibmveth_module_init(void) { - ibmveth_printk("%s: %s %s\n", ibmveth_driver_name, ibmveth_driver_string, ibmveth_driver_version); - - ibmveth_proc_register_driver(); + printk(KERN_DEBUG "%s: %s %s\n", ibmveth_driver_name, + ibmveth_driver_string, ibmveth_driver_version); return vio_register_driver(&ibmveth_driver); } @@ -1629,7 +1657,6 @@ static int __init ibmveth_module_init(void) static void __exit ibmveth_module_exit(void) { vio_unregister_driver(&ibmveth_driver); - ibmveth_proc_unregister_driver(); } module_init(ibmveth_module_init); diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h index ec76ace66c6b64520f2a3e4ac9d2f88ad29f88e5..43a794fab9ff9e2b0e9998ceaa887d1973562059 100644 --- a/drivers/net/ibmveth.h +++ b/drivers/net/ibmveth.h @@ -1,26 +1,28 @@ -/**************************************************************************/ -/* */ -/* IBM eServer i/[Series Virtual Ethernet Device Driver */ -/* Copyright (C) 2003 IBM Corp. */ -/* Dave Larson (larson1@us.ibm.com) */ -/* Santiago Leon (santil@us.ibm.com) */ -/* */ -/* This program is free software; you can redistribute it and/or modify */ -/* it under the terms of the GNU General Public License as published by */ -/* the Free Software Foundation; either version 2 of the License, or */ -/* (at your option) any later version. */ -/* */ -/* This program is distributed in the hope that it will be useful, */ -/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ -/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ -/* GNU General Public License for more details. */ -/* */ -/* You should have received a copy of the GNU General Public License */ -/* along with this program; if not, write to the Free Software */ -/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 */ -/* USA */ -/* */ -/**************************************************************************/ +/* + * IBM Power Virtual Ethernet Device Driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2003, 2010 + * + * Authors: Dave Larson + * Santiago Leon + * Brian King + * Robert Jennings + * Anton Blanchard + */ #ifndef _IBMVETH_H #define _IBMVETH_H @@ -92,17 +94,17 @@ static inline long h_illan_attributes(unsigned long unit_address, #define h_change_logical_lan_mac(ua, mac) \ plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac) -#define IbmVethNumBufferPools 5 +#define IBMVETH_NUM_BUFF_POOLS 5 #define IBMVETH_IO_ENTITLEMENT_DEFAULT 4243456 /* MTU of 1500 needs 4.2Mb */ #define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */ -#define IBMVETH_MAX_MTU 68 +#define IBMVETH_MIN_MTU 68 #define IBMVETH_MAX_POOL_COUNT 4096 #define IBMVETH_BUFF_LIST_SIZE 4096 #define IBMVETH_FILT_LIST_SIZE 4096 #define IBMVETH_MAX_BUF_SIZE (1024 * 128) static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 }; -static int pool_count[] = { 256, 768, 256, 256, 256 }; +static int pool_count[] = { 256, 512, 256, 256, 256 }; static int pool_active[] = { 1, 1, 0, 0, 0}; #define IBM_VETH_INVALID_MAP ((u16)0xffff) @@ -142,13 +144,15 @@ struct ibmveth_adapter { void * filter_list_addr; dma_addr_t buffer_list_dma; dma_addr_t filter_list_dma; - struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools]; + struct ibmveth_buff_pool rx_buff_pool[IBMVETH_NUM_BUFF_POOLS]; struct ibmveth_rx_q rx_queue; int pool_config; int rx_csum; void *bounce_buffer; dma_addr_t bounce_buffer_dma; + u64 fw_ipv6_csum_support; + u64 fw_ipv4_csum_support; /* adapter specific stats */ u64 replenish_task_cycles; u64 replenish_no_mem; @@ -158,7 +162,6 @@ struct ibmveth_adapter { u64 rx_no_buffer; u64 tx_map_failed; u64 tx_send_failed; - spinlock_t stats_lock; }; struct ibmveth_buf_desc_fields { diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 187622f1c81611f3b5b269c7c730610460c03210..bc183f5487cb11e668bea5e29b69ce2cf8fbded8 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c @@ -132,6 +132,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) case E1000_DEV_ID_82580_SERDES: case E1000_DEV_ID_82580_SGMII: case E1000_DEV_ID_82580_COPPER_DUAL: + case E1000_DEV_ID_DH89XXCC_SGMII: + case E1000_DEV_ID_DH89XXCC_SERDES: mac->type = e1000_82580; break; case E1000_DEV_ID_I350_COPPER: @@ -282,10 +284,18 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) /* Verify phy id and set remaining function pointers */ switch (phy->id) { + case I347AT4_E_PHY_ID: + case M88E1112_E_PHY_ID: case M88E1111_I_PHY_ID: phy->type = e1000_phy_m88; phy->ops.get_phy_info = igb_get_phy_info_m88; - phy->ops.get_cable_length = igb_get_cable_length_m88; + + if (phy->id == I347AT4_E_PHY_ID || + phy->id == M88E1112_E_PHY_ID) + phy->ops.get_cable_length = igb_get_cable_length_m88_gen2; + else + phy->ops.get_cable_length = igb_get_cable_length_m88; + phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88; break; case IGP03E1000_E_PHY_ID: @@ -1058,7 +1068,11 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) } switch (hw->phy.type) { case e1000_phy_m88: - ret_val = igb_copper_link_setup_m88(hw); + if (hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) + ret_val = igb_copper_link_setup_m88_gen2(hw); + else + ret_val = igb_copper_link_setup_m88(hw); break; case e1000_phy_igp_3: ret_val = igb_copper_link_setup_igp(hw); diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index bbd2ec308eb06b07963bfc5d658d73318968c406..62222796a8b37a771b28b4bedb544b5e542df0e8 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h @@ -634,6 +634,8 @@ * E = External */ #define M88E1111_I_PHY_ID 0x01410CC0 +#define M88E1112_E_PHY_ID 0x01410C90 +#define I347AT4_E_PHY_ID 0x01410DC0 #define IGP03E1000_E_PHY_ID 0x02A80390 #define I82580_I_PHY_ID 0x015403A0 #define I350_I_PHY_ID 0x015403B0 @@ -702,6 +704,35 @@ #define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100 #define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ +/* Intel i347-AT4 Registers */ + +#define I347AT4_PCDL 0x10 /* PHY Cable Diagnostics Length */ +#define I347AT4_PCDC 0x15 /* PHY Cable Diagnostics Control */ +#define I347AT4_PAGE_SELECT 0x16 + +/* i347-AT4 Extended PHY Specific Control Register */ + +/* + * Number of times we will attempt to autonegotiate before downshifting if we + * are the master + */ +#define I347AT4_PSCR_DOWNSHIFT_ENABLE 0x0800 +#define I347AT4_PSCR_DOWNSHIFT_MASK 0x7000 +#define I347AT4_PSCR_DOWNSHIFT_1X 0x0000 +#define I347AT4_PSCR_DOWNSHIFT_2X 0x1000 +#define I347AT4_PSCR_DOWNSHIFT_3X 0x2000 +#define I347AT4_PSCR_DOWNSHIFT_4X 0x3000 +#define I347AT4_PSCR_DOWNSHIFT_5X 0x4000 +#define I347AT4_PSCR_DOWNSHIFT_6X 0x5000 +#define I347AT4_PSCR_DOWNSHIFT_7X 0x6000 +#define I347AT4_PSCR_DOWNSHIFT_8X 0x7000 + +/* i347-AT4 PHY Cable Diagnostics Control */ +#define I347AT4_PCDC_CABLE_LENGTH_UNIT 0x0400 /* 0=cm 1=meters */ + +/* Marvell 1112 only registers */ +#define M88E1112_VCT_DSP_DISTANCE 0x001A + /* M88EC018 Rev 2 specific DownShift settings */ #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h index cb8db78b1a05ba4f241cab3c98c617213e1d3b16..c0b017f8d782e12c1021e61101b89b731e05378e 100644 --- a/drivers/net/igb/e1000_hw.h +++ b/drivers/net/igb/e1000_hw.h @@ -54,6 +54,8 @@ struct e1000_hw; #define E1000_DEV_ID_82580_SERDES 0x1510 #define E1000_DEV_ID_82580_SGMII 0x1511 #define E1000_DEV_ID_82580_COPPER_DUAL 0x1516 +#define E1000_DEV_ID_DH89XXCC_SGMII 0x0436 +#define E1000_DEV_ID_DH89XXCC_SERDES 0x0438 #define E1000_DEV_ID_I350_COPPER 0x1521 #define E1000_DEV_ID_I350_FIBER 0x1522 #define E1000_DEV_ID_I350_SERDES 0x1523 diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c index cf1f323009233aed82c601b0d73454bdfe7200e1..ddd036a78999c145ade02b705b2956b3260abc96 100644 --- a/drivers/net/igb/e1000_phy.c +++ b/drivers/net/igb/e1000_phy.c @@ -569,6 +569,89 @@ s32 igb_copper_link_setup_m88(struct e1000_hw *hw) return ret_val; } +/** + * igb_copper_link_setup_m88_gen2 - Setup m88 PHY's for copper link + * @hw: pointer to the HW structure + * + * Sets up MDI/MDI-X and polarity for i347-AT4, m88e1322 and m88e1112 PHY's. + * Also enables and sets the downshift parameters. + **/ +s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 phy_data; + + if (phy->reset_disable) { + ret_val = 0; + goto out; + } + + /* Enable CRS on Tx. This must be set for half-duplex operation. */ + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + if (ret_val) + goto out; + + /* + * Options: + * MDI/MDI-X = 0 (default) + * 0 - Auto for all speeds + * 1 - MDI mode + * 2 - MDI-X mode + * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) + */ + phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; + + switch (phy->mdix) { + case 1: + phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; + break; + case 2: + phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; + break; + case 3: + /* M88E1112 does not support this mode) */ + if (phy->id != M88E1112_E_PHY_ID) { + phy_data |= M88E1000_PSCR_AUTO_X_1000T; + break; + } + case 0: + default: + phy_data |= M88E1000_PSCR_AUTO_X_MODE; + break; + } + + /* + * Options: + * disable_polarity_correction = 0 (default) + * Automatic Correction for Reversed Cable Polarity + * 0 - Disabled + * 1 - Enabled + */ + phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; + if (phy->disable_polarity_correction == 1) + phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; + + /* Enable downshift and setting it to X6 */ + phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK; + phy_data |= I347AT4_PSCR_DOWNSHIFT_6X; + phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE; + + ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + if (ret_val) + goto out; + + /* Commit the changes. */ + ret_val = igb_phy_sw_reset(hw); + if (ret_val) { + hw_dbg("Error committing the PHY changes\n"); + goto out; + } + +out: + return ret_val; +} + /** * igb_copper_link_setup_igp - Setup igp PHY's for copper link * @hw: pointer to the HW structure @@ -1124,18 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; if (!link) { - /* - * We didn't get link. - * Reset the DSP and cross our fingers. - */ - ret_val = phy->ops.write_reg(hw, - M88E1000_PHY_PAGE_SELECT, - 0x001d); - if (ret_val) - goto out; - ret_val = igb_phy_reset_dsp(hw); - if (ret_val) - goto out; + if (hw->phy.type != e1000_phy_m88 || + hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) { + hw_dbg("Link taking longer than expected.\n"); + } else { + + /* + * We didn't get link. + * Reset the DSP and cross our fingers. + */ + ret_val = phy->ops.write_reg(hw, + M88E1000_PHY_PAGE_SELECT, + 0x001d); + if (ret_val) + goto out; + ret_val = igb_phy_reset_dsp(hw); + if (ret_val) + goto out; + } } /* Try once more */ @@ -1145,6 +1235,11 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; } + if (hw->phy.type != e1000_phy_m88 || + hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1112_E_PHY_ID) + goto out; + ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; @@ -1557,6 +1652,93 @@ s32 igb_get_cable_length_m88(struct e1000_hw *hw) return ret_val; } +s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 phy_data, phy_data2, index, default_page, is_cm; + + switch (hw->phy.id) { + case I347AT4_E_PHY_ID: + /* Remember the original page select and set it to 7 */ + ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, + &default_page); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07); + if (ret_val) + goto out; + + /* Get cable length from PHY Cable Diagnostics Control Reg */ + ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr), + &phy_data); + if (ret_val) + goto out; + + /* Check if the unit of cable length is meters or cm */ + ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2); + if (ret_val) + goto out; + + is_cm = !(phy_data & I347AT4_PCDC_CABLE_LENGTH_UNIT); + + /* Populate the phy structure with cable length in meters */ + phy->min_cable_length = phy_data / (is_cm ? 100 : 1); + phy->max_cable_length = phy_data / (is_cm ? 100 : 1); + phy->cable_length = phy_data / (is_cm ? 100 : 1); + + /* Reset the page selec to its original value */ + ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, + default_page); + if (ret_val) + goto out; + break; + case M88E1112_E_PHY_ID: + /* Remember the original page select and set it to 5 */ + ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, + &default_page); + if (ret_val) + goto out; + + ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05); + if (ret_val) + goto out; + + ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE, + &phy_data); + if (ret_val) + goto out; + + index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> + M88E1000_PSSR_CABLE_LENGTH_SHIFT; + if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) { + ret_val = -E1000_ERR_PHY; + goto out; + } + + phy->min_cable_length = e1000_m88_cable_length_table[index]; + phy->max_cable_length = e1000_m88_cable_length_table[index + 1]; + + phy->cable_length = (phy->min_cable_length + + phy->max_cable_length) / 2; + + /* Reset the page select to its original value */ + ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, + default_page); + if (ret_val) + goto out; + + break; + default: + ret_val = -E1000_ERR_PHY; + goto out; + } + +out: + return ret_val; +} + /** * igb_get_cable_length_igp_2 - Determine cable length for igp2 PHY * @hw: pointer to the HW structure diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h index 565a6dbb3714418d7776c8a4ceb2095f27e793db..2cc117705a316bf4c073095790fb4104f11374e6 100644 --- a/drivers/net/igb/e1000_phy.h +++ b/drivers/net/igb/e1000_phy.h @@ -45,9 +45,11 @@ s32 igb_check_downshift(struct e1000_hw *hw); s32 igb_check_reset_block(struct e1000_hw *hw); s32 igb_copper_link_setup_igp(struct e1000_hw *hw); s32 igb_copper_link_setup_m88(struct e1000_hw *hw); +s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw); s32 igb_phy_force_speed_duplex_igp(struct e1000_hw *hw); s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw); s32 igb_get_cable_length_m88(struct e1000_hw *hw); +s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw); s32 igb_get_cable_length_igp_2(struct e1000_hw *hw); s32 igb_get_phy_id(struct e1000_hw *hw); s32 igb_get_phy_info_igp(struct e1000_hw *hw); diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h index 6e63d9a7fc75808baac188b1719f3d0223ad3303..edab9c442399448bc6f930d5cae1a3a7e75ffd61 100644 --- a/drivers/net/igb/igb.h +++ b/drivers/net/igb/igb.h @@ -143,7 +143,7 @@ struct igb_buffer { u16 next_to_watch; unsigned int bytecount; u16 gso_segs; - union skb_shared_tx shtx; + u8 tx_flags; u8 mapped_as_page; }; /* RX */ @@ -159,6 +159,7 @@ struct igb_tx_queue_stats { u64 packets; u64 bytes; u64 restart_queue; + u64 restart_queue2; }; struct igb_rx_queue_stats { @@ -210,11 +211,14 @@ struct igb_ring { /* TX */ struct { struct igb_tx_queue_stats tx_stats; + struct u64_stats_sync tx_syncp; + struct u64_stats_sync tx_syncp2; bool detect_tx_hung; }; /* RX */ struct { struct igb_rx_queue_stats rx_stats; + struct u64_stats_sync rx_syncp; u32 rx_buffer_len; }; }; @@ -288,6 +292,9 @@ struct igb_adapter { struct timecompare compare; struct hwtstamp_config hwtstamp_config; + spinlock_t stats64_lock; + struct rtnl_link_stats64 stats64; + /* structs defined in e1000_hw.h */ struct e1000_hw hw; struct e1000_hw_stats stats; @@ -357,7 +364,7 @@ extern netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *, struct igb_ring *); extern void igb_unmap_and_free_tx_resource(struct igb_ring *, struct igb_buffer *); extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int); -extern void igb_update_stats(struct igb_adapter *); +extern void igb_update_stats(struct igb_adapter *, struct rtnl_link_stats64 *); extern bool igb_has_link(struct igb_adapter *adapter); extern void igb_set_ethtool_ops(struct net_device *); extern void igb_power_up_link(struct igb_adapter *); diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c index 26bf6a13d1c1a6e40beb4f1b8ec9c207fb501e1a..a70e16bcfa7e3fb58ac34205c3540cb306957cd7 100644 --- a/drivers/net/igb/igb_ethtool.c +++ b/drivers/net/igb/igb_ethtool.c @@ -90,8 +90,8 @@ static const struct igb_stats igb_gstrings_stats[] = { #define IGB_NETDEV_STAT(_net_stat) { \ .stat_string = __stringify(_net_stat), \ - .sizeof_stat = FIELD_SIZEOF(struct net_device_stats, _net_stat), \ - .stat_offset = offsetof(struct net_device_stats, _net_stat) \ + .sizeof_stat = FIELD_SIZEOF(struct rtnl_link_stats64, _net_stat), \ + .stat_offset = offsetof(struct rtnl_link_stats64, _net_stat) \ } static const struct igb_stats igb_gstrings_net_stats[] = { IGB_NETDEV_STAT(rx_errors), @@ -111,8 +111,9 @@ static const struct igb_stats igb_gstrings_net_stats[] = { (sizeof(igb_gstrings_net_stats) / sizeof(struct igb_stats)) #define IGB_RX_QUEUE_STATS_LEN \ (sizeof(struct igb_rx_queue_stats) / sizeof(u64)) -#define IGB_TX_QUEUE_STATS_LEN \ - (sizeof(struct igb_tx_queue_stats) / sizeof(u64)) + +#define IGB_TX_QUEUE_STATS_LEN 3 /* packets, bytes, restart_queue */ + #define IGB_QUEUE_STATS_LEN \ ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues * \ IGB_RX_QUEUE_STATS_LEN) + \ @@ -2070,12 +2071,14 @@ static void igb_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data) { struct igb_adapter *adapter = netdev_priv(netdev); - struct net_device_stats *net_stats = &netdev->stats; - u64 *queue_stat; - int i, j, k; + struct rtnl_link_stats64 *net_stats = &adapter->stats64; + unsigned int start; + struct igb_ring *ring; + int i, j; char *p; - igb_update_stats(adapter); + spin_lock(&adapter->stats64_lock); + igb_update_stats(adapter, net_stats); for (i = 0; i < IGB_GLOBAL_STATS_LEN; i++) { p = (char *)adapter + igb_gstrings_stats[i].stat_offset; @@ -2088,15 +2091,36 @@ static void igb_get_ethtool_stats(struct net_device *netdev, sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } for (j = 0; j < adapter->num_tx_queues; j++) { - queue_stat = (u64 *)&adapter->tx_ring[j]->tx_stats; - for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++) - data[i] = queue_stat[k]; + u64 restart2; + + ring = adapter->tx_ring[j]; + do { + start = u64_stats_fetch_begin_bh(&ring->tx_syncp); + data[i] = ring->tx_stats.packets; + data[i+1] = ring->tx_stats.bytes; + data[i+2] = ring->tx_stats.restart_queue; + } while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start)); + do { + start = u64_stats_fetch_begin_bh(&ring->tx_syncp2); + restart2 = ring->tx_stats.restart_queue2; + } while (u64_stats_fetch_retry_bh(&ring->tx_syncp2, start)); + data[i+2] += restart2; + + i += IGB_TX_QUEUE_STATS_LEN; } for (j = 0; j < adapter->num_rx_queues; j++) { - queue_stat = (u64 *)&adapter->rx_ring[j]->rx_stats; - for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++) - data[i] = queue_stat[k]; + ring = adapter->rx_ring[j]; + do { + start = u64_stats_fetch_begin_bh(&ring->rx_syncp); + data[i] = ring->rx_stats.packets; + data[i+1] = ring->rx_stats.bytes; + data[i+2] = ring->rx_stats.drops; + data[i+3] = ring->rx_stats.csum_err; + data[i+4] = ring->rx_stats.alloc_failed; + } while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start)); + i += IGB_RX_QUEUE_STATS_LEN; } + spin_unlock(&adapter->stats64_lock); } static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 9b4e5895f5f9d978992b204c3cbbbd8190b2340f..75155a27fdde50594f5626c2e412fd91a0c20c9a 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c @@ -71,6 +71,8 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SGMII), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SGMII), board_82575 }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SERDES), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 }, @@ -94,7 +96,6 @@ static int igb_setup_all_rx_resources(struct igb_adapter *); static void igb_free_all_tx_resources(struct igb_adapter *); static void igb_free_all_rx_resources(struct igb_adapter *); static void igb_setup_mrqc(struct igb_adapter *); -void igb_update_stats(struct igb_adapter *); static int igb_probe(struct pci_dev *, const struct pci_device_id *); static void __devexit igb_remove(struct pci_dev *pdev); static int igb_sw_init(struct igb_adapter *); @@ -111,7 +112,8 @@ static void igb_update_phy_info(unsigned long); static void igb_watchdog(unsigned long); static void igb_watchdog_task(struct work_struct *); static netdev_tx_t igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *); -static struct net_device_stats *igb_get_stats(struct net_device *); +static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev, + struct rtnl_link_stats64 *stats); static int igb_change_mtu(struct net_device *, int); static int igb_set_mac(struct net_device *, void *); static void igb_set_uta(struct igb_adapter *adapter); @@ -986,7 +988,7 @@ static void igb_clear_interrupt_scheme(struct igb_adapter *adapter) * Attempt to configure interrupts using the best available * capabilities of the hardware and kernel. **/ -static void igb_set_interrupt_capability(struct igb_adapter *adapter) +static int igb_set_interrupt_capability(struct igb_adapter *adapter) { int err; int numvecs, i; @@ -1052,8 +1054,10 @@ static void igb_set_interrupt_capability(struct igb_adapter *adapter) if (!pci_enable_msi(adapter->pdev)) adapter->flags |= IGB_FLAG_HAS_MSI; out: - /* Notify the stack of the (possibly) reduced Tx Queue count. */ - adapter->netdev->real_num_tx_queues = adapter->num_tx_queues; + /* Notify the stack of the (possibly) reduced queue counts. */ + netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); + return netif_set_real_num_rx_queues(adapter->netdev, + adapter->num_rx_queues); } /** @@ -1152,7 +1156,9 @@ static int igb_init_interrupt_scheme(struct igb_adapter *adapter) struct pci_dev *pdev = adapter->pdev; int err; - igb_set_interrupt_capability(adapter); + err = igb_set_interrupt_capability(adapter); + if (err) + return err; err = igb_alloc_q_vectors(adapter); if (err) { @@ -1530,7 +1536,9 @@ void igb_down(struct igb_adapter *adapter) netif_carrier_off(netdev); /* record the stats before reset*/ - igb_update_stats(adapter); + spin_lock(&adapter->stats64_lock); + igb_update_stats(adapter, &adapter->stats64); + spin_unlock(&adapter->stats64_lock); adapter->link_speed = 0; adapter->link_duplex = 0; @@ -1683,7 +1691,7 @@ static const struct net_device_ops igb_netdev_ops = { .ndo_open = igb_open, .ndo_stop = igb_close, .ndo_start_xmit = igb_xmit_frame_adv, - .ndo_get_stats = igb_get_stats, + .ndo_get_stats64 = igb_get_stats64, .ndo_set_rx_mode = igb_set_rx_mode, .ndo_set_multicast_list = igb_set_rx_mode, .ndo_set_mac_address = igb_set_mac, @@ -1856,8 +1864,10 @@ static int __devinit igb_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_IPV6_CSUM; netdev->vlan_features |= NETIF_F_SG; - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } if (hw->mac.type >= e1000_82576) netdev->features |= NETIF_F_SCTP_CSUM; @@ -1888,9 +1898,9 @@ static int __devinit igb_probe(struct pci_dev *pdev, goto err_eeprom; } - setup_timer(&adapter->watchdog_timer, &igb_watchdog, + setup_timer(&adapter->watchdog_timer, igb_watchdog, (unsigned long) adapter); - setup_timer(&adapter->phy_info_timer, &igb_update_phy_info, + setup_timer(&adapter->phy_info_timer, igb_update_phy_info, (unsigned long) adapter); INIT_WORK(&adapter->reset_task, igb_reset_task); @@ -2268,6 +2278,7 @@ static int __devinit igb_sw_init(struct igb_adapter *adapter) adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + spin_lock_init(&adapter->stats64_lock); #ifdef CONFIG_PCI_IOV if (hw->mac.type == e1000_82576) adapter->vfs_allocated_count = (max_vfs > 7) ? 7 : max_vfs; @@ -3475,7 +3486,9 @@ static void igb_watchdog_task(struct work_struct *work) } } - igb_update_stats(adapter); + spin_lock(&adapter->stats64_lock); + igb_update_stats(adapter, &adapter->stats64); + spin_unlock(&adapter->stats64_lock); for (i = 0; i < adapter->num_tx_queues; i++) { struct igb_ring *tx_ring = adapter->tx_ring[i]; @@ -3542,6 +3555,8 @@ static void igb_update_ring_itr(struct igb_q_vector *q_vector) int new_val = q_vector->itr_val; int avg_wire_size = 0; struct igb_adapter *adapter = q_vector->adapter; + struct igb_ring *ring; + unsigned int packets; /* For non-gigabit speeds, just fix the interrupt rate at 4000 * ints/sec - ITR timer value of 120 ticks. @@ -3551,16 +3566,21 @@ static void igb_update_ring_itr(struct igb_q_vector *q_vector) goto set_itr_val; } - if (q_vector->rx_ring && q_vector->rx_ring->total_packets) { - struct igb_ring *ring = q_vector->rx_ring; - avg_wire_size = ring->total_bytes / ring->total_packets; + ring = q_vector->rx_ring; + if (ring) { + packets = ACCESS_ONCE(ring->total_packets); + + if (packets) + avg_wire_size = ring->total_bytes / packets; } - if (q_vector->tx_ring && q_vector->tx_ring->total_packets) { - struct igb_ring *ring = q_vector->tx_ring; - avg_wire_size = max_t(u32, avg_wire_size, - (ring->total_bytes / - ring->total_packets)); + ring = q_vector->tx_ring; + if (ring) { + packets = ACCESS_ONCE(ring->total_packets); + + if (packets) + avg_wire_size = max_t(u32, avg_wire_size, + ring->total_bytes / packets); } /* if avg_wire_size isn't set no work was done */ @@ -3954,7 +3974,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb, } tx_ring->buffer_info[i].skb = skb; - tx_ring->buffer_info[i].shtx = skb_shinfo(skb)->tx_flags; + tx_ring->buffer_info[i].tx_flags = skb_shinfo(skb)->tx_flags; /* multiply data chunks by size of headers */ tx_ring->buffer_info[i].bytecount = ((gso_segs - 1) * hlen) + skb->len; tx_ring->buffer_info[i].gso_segs = gso_segs; @@ -4069,7 +4089,11 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, int size) /* A reprieve! */ netif_wake_subqueue(netdev, tx_ring->queue_index); - tx_ring->tx_stats.restart_queue++; + + u64_stats_update_begin(&tx_ring->tx_syncp2); + tx_ring->tx_stats.restart_queue2++; + u64_stats_update_end(&tx_ring->tx_syncp2); + return 0; } @@ -4088,7 +4112,6 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, u32 tx_flags = 0; u16 first; u8 hdr_len = 0; - union skb_shared_tx *shtx = skb_tx(skb); /* need: 1 descriptor per page, * + 2 desc gap to keep tail from touching head, @@ -4100,12 +4123,12 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb, return NETDEV_TX_BUSY; } - if (unlikely(shtx->hardware)) { - shtx->in_progress = 1; + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS; tx_flags |= IGB_TX_FLAGS_TSTAMP; } - if (vlan_tx_tag_present(skb) && adapter->vlgrp) { + if (vlan_tx_tag_present(skb)) { tx_flags |= IGB_TX_FLAGS_VLAN; tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT); } @@ -4207,16 +4230,22 @@ static void igb_reset_task(struct work_struct *work) } /** - * igb_get_stats - Get System Network Statistics + * igb_get_stats64 - Get System Network Statistics * @netdev: network interface device structure + * @stats: rtnl_link_stats64 pointer * - * Returns the address of the device statistics structure. - * The statistics are actually updated from the timer callback. **/ -static struct net_device_stats *igb_get_stats(struct net_device *netdev) +static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) { - /* only return the current stats */ - return &netdev->stats; + struct igb_adapter *adapter = netdev_priv(netdev); + + spin_lock(&adapter->stats64_lock); + igb_update_stats(adapter, &adapter->stats64); + memcpy(stats, &adapter->stats64, sizeof(*stats)); + spin_unlock(&adapter->stats64_lock); + + return stats; } /** @@ -4298,15 +4327,17 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu) * @adapter: board private structure **/ -void igb_update_stats(struct igb_adapter *adapter) +void igb_update_stats(struct igb_adapter *adapter, + struct rtnl_link_stats64 *net_stats) { - struct net_device_stats *net_stats = igb_get_stats(adapter->netdev); struct e1000_hw *hw = &adapter->hw; struct pci_dev *pdev = adapter->pdev; u32 reg, mpc; u16 phy_tmp; int i; u64 bytes, packets; + unsigned int start; + u64 _bytes, _packets; #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF @@ -4324,10 +4355,17 @@ void igb_update_stats(struct igb_adapter *adapter) for (i = 0; i < adapter->num_rx_queues; i++) { u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF; struct igb_ring *ring = adapter->rx_ring[i]; + ring->rx_stats.drops += rqdpc_tmp; net_stats->rx_fifo_errors += rqdpc_tmp; - bytes += ring->rx_stats.bytes; - packets += ring->rx_stats.packets; + + do { + start = u64_stats_fetch_begin_bh(&ring->rx_syncp); + _bytes = ring->rx_stats.bytes; + _packets = ring->rx_stats.packets; + } while (u64_stats_fetch_retry_bh(&ring->rx_syncp, start)); + bytes += _bytes; + packets += _packets; } net_stats->rx_bytes = bytes; @@ -4337,8 +4375,13 @@ void igb_update_stats(struct igb_adapter *adapter) packets = 0; for (i = 0; i < adapter->num_tx_queues; i++) { struct igb_ring *ring = adapter->tx_ring[i]; - bytes += ring->tx_stats.bytes; - packets += ring->tx_stats.packets; + do { + start = u64_stats_fetch_begin_bh(&ring->tx_syncp); + _bytes = ring->tx_stats.bytes; + _packets = ring->tx_stats.packets; + } while (u64_stats_fetch_retry_bh(&ring->tx_syncp, start)); + bytes += _bytes; + packets += _packets; } net_stats->tx_bytes = bytes; net_stats->tx_packets = packets; @@ -4660,12 +4703,13 @@ static int igb_set_vf_promisc(struct igb_adapter *adapter, u32 *msgbuf, u32 vf) u32 vmolr = rd32(E1000_VMOLR(vf)); struct vf_data_storage *vf_data = &adapter->vf_data[vf]; - vf_data->flags |= ~(IGB_VF_FLAG_UNI_PROMISC | + vf_data->flags &= ~(IGB_VF_FLAG_UNI_PROMISC | IGB_VF_FLAG_MULTI_PROMISC); vmolr &= ~(E1000_VMOLR_ROPE | E1000_VMOLR_ROMPE | E1000_VMOLR_MPME); if (*msgbuf & E1000_VF_SET_PROMISC_MULTICAST) { vmolr |= E1000_VMOLR_MPME; + vf_data->flags |= IGB_VF_FLAG_MULTI_PROMISC; *msgbuf &= ~E1000_VF_SET_PROMISC_MULTICAST; } else { /* @@ -5319,7 +5363,7 @@ static void igb_tx_hwtstamp(struct igb_q_vector *q_vector, struct igb_buffer *bu u64 regval; /* if skb does not support hw timestamp or TX stamp not valid exit */ - if (likely(!buffer_info->shtx.hardware) || + if (likely(!(buffer_info->tx_flags & SKBTX_HW_TSTAMP)) || !(rd32(E1000_TSYNCTXCTL) & E1000_TSYNCTXCTL_VALID)) return; @@ -5389,7 +5433,10 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) && !(test_bit(__IGB_DOWN, &adapter->state))) { netif_wake_subqueue(netdev, tx_ring->queue_index); + + u64_stats_update_begin(&tx_ring->tx_syncp); tx_ring->tx_stats.restart_queue++; + u64_stats_update_end(&tx_ring->tx_syncp); } } @@ -5429,9 +5476,11 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector) } tx_ring->total_bytes += total_bytes; tx_ring->total_packets += total_packets; + u64_stats_update_begin(&tx_ring->tx_syncp); tx_ring->tx_stats.bytes += total_bytes; tx_ring->tx_stats.packets += total_packets; - return (count < tx_ring->count); + u64_stats_update_end(&tx_ring->tx_syncp); + return count < tx_ring->count; } /** @@ -5456,7 +5505,7 @@ static void igb_receive_skb(struct igb_q_vector *q_vector, static inline void igb_rx_checksum_adv(struct igb_ring *ring, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set or checksum is disabled through ethtool */ if (!(ring->flags & IGB_RING_FLAG_RX_CSUM) || @@ -5472,9 +5521,11 @@ static inline void igb_rx_checksum_adv(struct igb_ring *ring, * packets, (aka let the stack check the crc32c) */ if ((skb->len == 60) && - (ring->flags & IGB_RING_FLAG_RX_SCTP_CSUM)) + (ring->flags & IGB_RING_FLAG_RX_SCTP_CSUM)) { + u64_stats_update_begin(&ring->rx_syncp); ring->rx_stats.csum_err++; - + u64_stats_update_end(&ring->rx_syncp); + } /* let the stack verify checksum errors */ return; } @@ -5500,7 +5551,7 @@ static void igb_rx_hwtstamp(struct igb_q_vector *q_vector, u32 staterr, * values must belong to this one here and therefore we don't need to * compare any of the additional attributes stored for it. * - * If nothing went wrong, then it should have a skb_shared_tx that we + * If nothing went wrong, then it should have a shared tx_flags that we * can turn into a skb_shared_hwtstamps. */ if (staterr & E1000_RXDADV_STAT_TSIP) { @@ -5661,8 +5712,10 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector, rx_ring->total_packets += total_packets; rx_ring->total_bytes += total_bytes; + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.packets += total_packets; rx_ring->rx_stats.bytes += total_bytes; + u64_stats_update_end(&rx_ring->rx_syncp); return cleaned; } @@ -5690,8 +5743,10 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count) if ((bufsz < IGB_RXBUFFER_1024) && !buffer_info->page_dma) { if (!buffer_info->page) { buffer_info->page = netdev_alloc_page(netdev); - if (!buffer_info->page) { + if (unlikely(!buffer_info->page)) { + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.alloc_failed++; + u64_stats_update_end(&rx_ring->rx_syncp); goto no_buffers; } buffer_info->page_offset = 0; @@ -5706,7 +5761,9 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count) if (dma_mapping_error(rx_ring->dev, buffer_info->page_dma)) { buffer_info->page_dma = 0; + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.alloc_failed++; + u64_stats_update_end(&rx_ring->rx_syncp); goto no_buffers; } } @@ -5714,8 +5771,10 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count) skb = buffer_info->skb; if (!skb) { skb = netdev_alloc_skb_ip_align(netdev, bufsz); - if (!skb) { + if (unlikely(!skb)) { + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.alloc_failed++; + u64_stats_update_end(&rx_ring->rx_syncp); goto no_buffers; } @@ -5729,7 +5788,9 @@ void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring, int cleaned_count) if (dma_mapping_error(rx_ring->dev, buffer_info->dma)) { buffer_info->dma = 0; + u64_stats_update_begin(&rx_ring->rx_syncp); rx_ring->rx_stats.alloc_failed++; + u64_stats_update_end(&rx_ring->rx_syncp); goto no_buffers; } } @@ -6092,7 +6153,7 @@ static void igb_restore_vlan(struct igb_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; igb_vlan_rx_add_vid(adapter->netdev, vid); @@ -6107,6 +6168,13 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx) mac->autoneg = 0; + /* Fiber NIC's only allow 1000 Gbps Full duplex */ + if ((adapter->hw.phy.media_type == e1000_media_type_internal_serdes) && + spddplx != (SPEED_1000 + DUPLEX_FULL)) { + dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n"); + return -EINVAL; + } + switch (spddplx) { case SPEED_10 + DUPLEX_HALF: mac->forced_speed_duplex = ADVERTISE_10_HALF; diff --git a/drivers/net/igbvf/ethtool.c b/drivers/net/igbvf/ethtool.c index 103b3aa1afc2297d862005d25b48dc42af9607e8..33add708bcbece9b67a519c73c709c98f5f2d94b 100644 --- a/drivers/net/igbvf/ethtool.c +++ b/drivers/net/igbvf/ethtool.c @@ -153,7 +153,7 @@ static int igbvf_set_rx_csum(struct net_device *netdev, u32 data) static u32 igbvf_get_tx_csum(struct net_device *netdev) { - return ((netdev->features & NETIF_F_IP_CSUM) != 0); + return (netdev->features & NETIF_F_IP_CSUM) != 0; } static int igbvf_set_tx_csum(struct net_device *netdev, u32 data) diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c index c539f7c9c3e08a2957826387fb1ce259954e9015..ebfaa68ee630404addca4607b4dffa2e3fe6bc33 100644 --- a/drivers/net/igbvf/netdev.c +++ b/drivers/net/igbvf/netdev.c @@ -41,14 +41,12 @@ #include #include #include -#include #include "igbvf.h" #define DRV_VERSION "1.0.0-k0" char igbvf_driver_name[] = "igbvf"; const char igbvf_driver_version[] = DRV_VERSION; -static struct pm_qos_request_list igbvf_driver_pm_qos_req; static const char igbvf_driver_string[] = "Intel(R) Virtual Function Network Driver"; static const char igbvf_copyright[] = "Copyright (c) 2009 Intel Corporation."; @@ -103,7 +101,7 @@ static void igbvf_receive_skb(struct igbvf_adapter *adapter, static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Ignore Checksum bit is set or checksum is disabled through ethtool */ if ((status_err & E1000_RXD_STAT_IXSM) || @@ -845,7 +843,7 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring) } adapter->net_stats.tx_bytes += total_bytes; adapter->net_stats.tx_packets += total_packets; - return (count < tx_ring->count); + return count < tx_ring->count; } static irqreturn_t igbvf_msix_other(int irq, void *data) @@ -1256,7 +1254,7 @@ static void igbvf_restore_vlan(struct igbvf_adapter *adapter) if (!adapter->vlgrp) return; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; igbvf_vlan_rx_add_vid(adapter->netdev, vid); @@ -2904,8 +2902,6 @@ static int __init igbvf_init_module(void) printk(KERN_INFO "%s\n", igbvf_copyright); ret = pci_register_driver(&igbvf_driver); - pm_qos_add_request(&igbvf_driver_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, - PM_QOS_DEFAULT_VALUE); return ret; } @@ -2920,7 +2916,6 @@ module_init(igbvf_init_module); static void __exit igbvf_exit_module(void) { pci_unregister_driver(&igbvf_driver); - pm_qos_remove_request(&igbvf_driver_pm_qos_req); } module_exit(igbvf_exit_module); diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index 0b3f6df5cff78686d4324626fbc9c1966879e63c..c8ee8d28767b6832167e65c98a00ca859e26d87f 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c @@ -827,7 +827,7 @@ static void ioc3_mii_start(struct ioc3_private *ip) { ip->ioc3_timer.expires = jiffies + (12 * HZ)/10; /* 1.2 sec. */ ip->ioc3_timer.data = (unsigned long) ip; - ip->ioc3_timer.function = &ioc3_timer; + ip->ioc3_timer.function = ioc3_timer; add_timer(&ip->ioc3_timer); } diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 72e3d2da9e9fd3174bea52c1d9feaf57e0423316..dc019809234352418978474531efa675a4e879a2 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c @@ -1213,7 +1213,7 @@ static void ipg_nic_rx_with_start_and_end(struct net_device *dev, skb_put(skb, framelen); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_rx(skb); sp->rx_buff[entry] = NULL; } @@ -1278,7 +1278,7 @@ static void ipg_nic_rx_with_end(struct net_device *dev, jumbo->skb->protocol = eth_type_trans(jumbo->skb, dev); - jumbo->skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(jumbo->skb); netif_rx(jumbo->skb); } } @@ -1476,7 +1476,7 @@ static int ipg_nic_rx(struct net_device *dev) * IP/TCP/UDP frame was received. Let the * upper layer decide. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Hand off frame for higher layer processing. * The function netif_rx() releases the sk_buff diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 48bd5ec9f29b34edafeeda78d08fafba543376e5..b626cccbccd141e28fc2ac10667e2010595fefb9 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -217,7 +217,7 @@ toshoboe_checkfcs (unsigned char *buf, int len) for (i = 0; i < len; ++i) fcs.value = irda_fcs (fcs.value, *(buf++)); - return (fcs.value == GOOD_FCS); + return fcs.value == GOOD_FCS; } /***********************************************************************/ @@ -759,7 +759,7 @@ toshoboe_maketestpacket (unsigned char *buf, int badcrc, int fir) if (fir) { memset (buf, 0, TT_LEN); - return (TT_LEN); + return TT_LEN; } fcs.value = INIT_FCS; diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c index 4441fa3389c265248ae45fa8f2adee625c30a7e1..e4ea61944c22937a5a1e3309242467d0f7b4edc9 100644 --- a/drivers/net/irda/irda-usb.c +++ b/drivers/net/irda/irda-usb.c @@ -1124,11 +1124,11 @@ static int stir421x_patch_device(struct irda_usb_cb *self) * The actual image starts after the "STMP" keyword * so forward to the firmware header tag */ - for (i = 0; (fw->data[i] != STIR421X_PATCH_END_OF_HDR_TAG) && - (i < fw->size); i++) ; + for (i = 0; i < fw->size && fw->data[i] != + STIR421X_PATCH_END_OF_HDR_TAG; i++) ; /* here we check for the out of buffer case */ - if ((STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) && - (i < STIR421X_PATCH_CODE_OFFSET)) { + if (i < STIR421X_PATCH_CODE_OFFSET && i < fw->size && + STIR421X_PATCH_END_OF_HDR_TAG == fw->data[i]) { if (!memcmp(fw->data + i + 1, STIR421X_PATCH_STMP_TAG, sizeof(STIR421X_PATCH_STMP_TAG) - 1)) { @@ -1514,7 +1514,7 @@ static inline int irda_usb_parse_endpoints(struct irda_usb_cb *self, struct usb_ IRDA_DEBUG(0, "%s(), And our endpoints are : in=%02X, out=%02X (%d), int=%02X\n", __func__, self->bulk_in_ep, self->bulk_out_ep, self->bulk_out_mtu, self->bulk_int_ep); - return((self->bulk_in_ep != 0) && (self->bulk_out_ep != 0)); + return (self->bulk_in_ep != 0) && (self->bulk_out_ep != 0); } #ifdef IU_DUMP_CLASS_DESC diff --git a/drivers/net/irda/mcs7780.c b/drivers/net/irda/mcs7780.c index 5b1036ac38d7ba1a14a54394ad19f9f29b0397f4..74b20f179cea029be0f2767fac5e3b04cee987a6 100644 --- a/drivers/net/irda/mcs7780.c +++ b/drivers/net/irda/mcs7780.c @@ -734,7 +734,7 @@ static int mcs_net_open(struct net_device *netdev) } if (!mcs_setup_urbs(mcs)) - goto error3; + goto error3; ret = mcs_receive_start(mcs); if (ret) diff --git a/drivers/net/irda/nsc-ircc.c b/drivers/net/irda/nsc-ircc.c index e30cdbb1474567885d64a9c4cd2d281fcf6d32c8..559fe854d76d2277d82530af9e1bd368121c6533 100644 --- a/drivers/net/irda/nsc-ircc.c +++ b/drivers/net/irda/nsc-ircc.c @@ -1348,7 +1348,7 @@ static __u8 nsc_ircc_change_speed(struct nsc_ircc_cb *self, __u32 speed) outb(bank, iobase+BSR); /* Make sure interrupt handlers keep the proper interrupt mask */ - return(ier); + return ier; } /* diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c index 51d74447f8f8cb7d428c7bbdf22b14f71cdfc4aa..efe05bb34dd807ec8f34c810acd7c1c9990bff15 100644 --- a/drivers/net/irda/sir_dev.c +++ b/drivers/net/irda/sir_dev.c @@ -336,7 +336,7 @@ static int sirdev_is_receiving(struct sir_dev *dev) if (!atomic_read(&dev->enable_rx)) return 0; - return (dev->rx_buff.state != OUTSIDE_FRAME); + return dev->rx_buff.state != OUTSIDE_FRAME; } int sirdev_set_dongle(struct sir_dev *dev, IRDA_DONGLE type) diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c index 850ca1c5ee19cc024cb41aff9164b459ab999e46..8c57bfb5f098ac910c88f34d7849ad88d6705ac3 100644 --- a/drivers/net/irda/smsc-ircc2.c +++ b/drivers/net/irda/smsc-ircc2.c @@ -2051,7 +2051,7 @@ static int smsc_ircc_sir_write(int iobase, int fifo_size, __u8 *buf, int len) */ static int smsc_ircc_is_receiving(struct smsc_ircc_cb *self) { - return (self->rx_buff.state != OUTSIDE_FRAME); + return self->rx_buff.state != OUTSIDE_FRAME; } diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c index e5698fa30a4f262e3538af06c436a289911ecf63..41c96b3d8152acba4d61ed5b43b7086deae07f7a 100644 --- a/drivers/net/irda/stir4200.c +++ b/drivers/net/irda/stir4200.c @@ -219,7 +219,7 @@ static inline int read_reg(struct stir_cb *stir, __u16 reg, static inline int isfir(u32 speed) { - return (speed == 4000000); + return speed == 4000000; } /* diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c index b0a6cd815be198e11334880d9ce8a728ee28d4e4..67c0ad42d818a37a282312d72ab396f9b0a1e106 100644 --- a/drivers/net/irda/via-ircc.c +++ b/drivers/net/irda/via-ircc.c @@ -1182,12 +1182,13 @@ F01_E */ skb = dev_alloc_skb(len + 1 - 4); /* - * if frame size,data ptr,or skb ptr are wrong ,the get next + * if frame size, data ptr, or skb ptr are wrong, then get next * entry. */ if ((skb == NULL) || (skb->data == NULL) || (self->rx_buff.data == NULL) || (len < 6)) { self->netdev->stats.rx_dropped++; + kfree_skb(skb); return TRUE; } skb_reserve(skb, 1); diff --git a/drivers/net/irda/via-ircc.h b/drivers/net/irda/via-ircc.h index 5a84822b5a43ed0dcefc9622723753490d961733..c6f58482b769185ce9b1c9369bff30e853effa75 100644 --- a/drivers/net/irda/via-ircc.h +++ b/drivers/net/irda/via-ircc.h @@ -238,7 +238,7 @@ static void WriteLPCReg(int iRegNum, unsigned char iVal) static __u8 ReadReg(unsigned int BaseAddr, int iRegNum) { - return ((__u8) inb(BaseAddr + iRegNum)); + return (__u8) inb(BaseAddr + iRegNum); } static void WriteReg(unsigned int BaseAddr, int iRegNum, unsigned char iVal) diff --git a/drivers/net/irda/vlsi_ir.h b/drivers/net/irda/vlsi_ir.h index 3f24a1f330220aedc7f584265fd3c9fe55cec8d5..d66fab854bf181e42568d198b028864e84c19295 100644 --- a/drivers/net/irda/vlsi_ir.h +++ b/drivers/net/irda/vlsi_ir.h @@ -595,7 +595,7 @@ struct ring_descr { static inline int rd_is_active(struct ring_descr *rd) { - return ((rd->hw->rd_status & RD_ACTIVE) != 0); + return (rd->hw->rd_status & RD_ACTIVE) != 0; } static inline void rd_activate(struct ring_descr *rd) diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index ba1de5973fb2083fe669027d551ea98d427bf350..8df645e78f2e9618bd22b83225efbfde4f43008a 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1524,7 +1524,7 @@ static void veth_receive(struct veth_lpar_connection *cnx, skb_put(skb, length); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_rx(skb); /* send it up */ dev->stats.rx_packets++; dev->stats.rx_bytes += length; diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c index 813993f9c65c920f338c6b46cfab8d62ecd2ef6b..c982ab9f9005179b1910a75f45404442dfb9fec5 100644 --- a/drivers/net/ixgb/ixgb_ee.c +++ b/drivers/net/ixgb/ixgb_ee.c @@ -296,12 +296,12 @@ ixgb_wait_eeprom_command(struct ixgb_hw *hw) eecd_reg = IXGB_READ_REG(hw, EECD); if (eecd_reg & IXGB_EECD_DO) - return (true); + return true; udelay(50); } ASSERT(0); - return (false); + return false; } /****************************************************************************** @@ -327,9 +327,9 @@ ixgb_validate_eeprom_checksum(struct ixgb_hw *hw) checksum += ixgb_read_eeprom(hw, i); if (checksum == (u16) EEPROM_SUM) - return (true); + return true; else - return (false); + return false; } /****************************************************************************** @@ -439,7 +439,7 @@ ixgb_read_eeprom(struct ixgb_hw *hw, /* End this read operation */ ixgb_standby_eeprom(hw); - return (data); + return data; } /****************************************************************************** @@ -476,16 +476,16 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw) /* clear the init_ctrl_reg_1 to signify that the cache is * invalidated */ ee_map->init_ctrl_reg_1 = cpu_to_le16(EEPROM_ICW1_SIGNATURE_CLEAR); - return (false); + return false; } if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK)) != cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) { pr_debug("Signature invalid\n"); - return(false); + return false; } - return(true); + return true; } /****************************************************************************** @@ -505,7 +505,7 @@ ixgb_check_and_get_eeprom_data (struct ixgb_hw* hw) if ((ee_map->init_ctrl_reg_1 & cpu_to_le16(EEPROM_ICW1_SIGNATURE_MASK)) == cpu_to_le16(EEPROM_ICW1_SIGNATURE_VALID)) { - return (true); + return true; } else { return ixgb_get_eeprom_data(hw); } @@ -526,10 +526,10 @@ ixgb_get_eeprom_word(struct ixgb_hw *hw, u16 index) if ((index < IXGB_EEPROM_SIZE) && (ixgb_check_and_get_eeprom_data(hw) == true)) { - return(hw->eeprom[index]); + return hw->eeprom[index]; } - return(0); + return 0; } /****************************************************************************** @@ -570,10 +570,10 @@ u32 ixgb_get_ee_pba_number(struct ixgb_hw *hw) { if (ixgb_check_and_get_eeprom_data(hw) == true) - return (le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG]) - | (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16)); + return le16_to_cpu(hw->eeprom[EEPROM_PBA_1_2_REG]) + | (le16_to_cpu(hw->eeprom[EEPROM_PBA_3_4_REG])<<16); - return(0); + return 0; } @@ -591,8 +591,8 @@ ixgb_get_ee_device_id(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if (ixgb_check_and_get_eeprom_data(hw) == true) - return (le16_to_cpu(ee_map->device_id)); + return le16_to_cpu(ee_map->device_id); - return (0); + return 0; } diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index a4ed96caae6969b12d6e6638cde65430a8dc08cf..43994c1999914d87aec511827dea54554b1117de 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c @@ -410,7 +410,7 @@ static int ixgb_get_eeprom_len(struct net_device *netdev) { /* return size in bytes */ - return (IXGB_EEPROM_SIZE << 1); + return IXGB_EEPROM_SIZE << 1; } static int diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c index 397acabccab6c2a43ad8e18cc6f8775d1f0a6429..6cb2e42ff4c135d2bf171b2b5e2e6ec57da8f271 100644 --- a/drivers/net/ixgb/ixgb_hw.c +++ b/drivers/net/ixgb/ixgb_hw.c @@ -167,7 +167,7 @@ ixgb_adapter_stop(struct ixgb_hw *hw) /* Clear any pending interrupt events. */ icr_reg = IXGB_READ_REG(hw, ICR); - return (ctrl_reg & IXGB_CTRL0_RST); + return ctrl_reg & IXGB_CTRL0_RST; } @@ -209,7 +209,7 @@ ixgb_identify_xpak_vendor(struct ixgb_hw *hw) xpak_vendor = ixgb_xpak_vendor_infineon; } - return (xpak_vendor); + return xpak_vendor; } /****************************************************************************** @@ -273,7 +273,7 @@ ixgb_identify_phy(struct ixgb_hw *hw) if (hw->subsystem_vendor_id == SUN_SUBVENDOR_ID) phy_type = ixgb_phy_type_bcm; - return (phy_type); + return phy_type; } /****************************************************************************** @@ -366,7 +366,7 @@ ixgb_init_hw(struct ixgb_hw *hw) /* 82597EX errata: Call check-for-link in case lane deskew is locked */ ixgb_check_for_link(hw); - return (status); + return status; } /****************************************************************************** @@ -531,7 +531,7 @@ ixgb_hash_mc_addr(struct ixgb_hw *hw, } hash_value &= 0xFFF; - return (hash_value); + return hash_value; } /****************************************************************************** @@ -715,7 +715,7 @@ ixgb_setup_fc(struct ixgb_hw *hw) } IXGB_WRITE_REG(hw, FCRTH, hw->fc.high_water); } - return (status); + return status; } /****************************************************************************** @@ -1140,7 +1140,7 @@ mac_addr_valid(u8 *mac_addr) pr_debug("MAC address is all zeros\n"); is_valid = false; } - return (is_valid); + return is_valid; } /****************************************************************************** diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 45fc89b9ba643d0e8f28edc8664cba4d89ae964a..666207a9c039ee2875aa92a553f5f9e321573df7 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -446,8 +446,10 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) NETIF_F_HW_VLAN_FILTER; netdev->features |= NETIF_F_TSO; - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } /* make sure the EEPROM is good */ @@ -470,7 +472,7 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) adapter->part_num = ixgb_get_ee_pba_number(&adapter->hw); init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &ixgb_watchdog; + adapter->watchdog_timer.function = ixgb_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->tx_timeout_task, ixgb_tx_timeout_task); @@ -1905,7 +1907,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter, */ if ((rx_desc->status & IXGB_RX_DESC_STATUS_IXSM) || (!(rx_desc->status & IXGB_RX_DESC_STATUS_TCPCS))) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); return; } @@ -1913,7 +1915,7 @@ ixgb_rx_checksum(struct ixgb_adapter *adapter, /* now look at the TCP checksum error bit */ if (rx_desc->errors & IXGB_RX_DESC_ERRORS_TCPE) { /* let the stack verify checksum errors */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); adapter->hw_csum_rx_error++; } else { /* TCP checksum is good */ @@ -2221,7 +2223,7 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; ixgb_vlan_rx_add_vid(adapter->netdev, vid); diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 9e15eb93860eb4686ad79ca5058de708ff2bda72..ed8703cfffb7ec06ede55d5dce2ff02324d47bd6 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -28,10 +28,13 @@ #ifndef _IXGBE_H_ #define _IXGBE_H_ +#include #include #include #include +#include #include +#include #include "ixgbe_type.h" #include "ixgbe_common.h" @@ -69,15 +72,20 @@ #define IXGBE_MAX_FCPAUSE 0xFFFF /* Supported Rx Buffer Sizes */ -#define IXGBE_RXBUFFER_64 64 /* Used for packet split */ -#define IXGBE_RXBUFFER_128 128 /* Used for packet split */ -#define IXGBE_RXBUFFER_256 256 /* Used for packet split */ +#define IXGBE_RXBUFFER_512 512 /* Used for packet split */ #define IXGBE_RXBUFFER_2048 2048 #define IXGBE_RXBUFFER_4096 4096 #define IXGBE_RXBUFFER_8192 8192 #define IXGBE_MAX_RXBUFFER 16384 /* largest size for a single descriptor */ -#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256 +/* + * NOTE: netdev_alloc_skb reserves up to 64 bytes, NET_IP_ALIGN mans we + * reserve 2 more, and skb_shared_info adds an additional 384 bytes more, + * this adds up to 512 bytes of extra data meaning the smallest allocation + * we could have is 1K. + * i.e. RXBUFFER_512 --> size-1024 slab + */ +#define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_512 #define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) @@ -174,8 +182,9 @@ struct ixgbe_ring { */ struct ixgbe_queue_stats stats; - unsigned long reinit_state; + struct u64_stats_sync syncp; int numa_node; + unsigned long reinit_state; u64 rsc_count; /* stat for coalesced packets */ u64 rsc_flush; /* stats for flushed packets */ u32 restart_queue; /* track tx queue restarts */ @@ -236,6 +245,7 @@ struct ixgbe_q_vector { u8 tx_itr; u8 rx_itr; u32 eitr; + cpumask_var_t affinity_mask; }; /* Helper macros to switch between ints/sec and what the register uses. @@ -251,11 +261,11 @@ struct ixgbe_q_vector { (R)->next_to_clean - (R)->next_to_use - 1) #define IXGBE_RX_DESC_ADV(R, i) \ - (&(((union ixgbe_adv_rx_desc *)((R).desc))[i])) + (&(((union ixgbe_adv_rx_desc *)((R)->desc))[i])) #define IXGBE_TX_DESC_ADV(R, i) \ - (&(((union ixgbe_adv_tx_desc *)((R).desc))[i])) + (&(((union ixgbe_adv_tx_desc *)((R)->desc))[i])) #define IXGBE_TX_CTXTDESC_ADV(R, i) \ - (&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i])) + (&(((struct ixgbe_adv_tx_context_desc *)((R)->desc))[i])) #define IXGBE_MAX_JUMBO_FRAME_SIZE 16128 #ifdef IXGBE_FCOE @@ -280,7 +290,7 @@ struct ixgbe_q_vector { /* board specific private data structure */ struct ixgbe_adapter { struct timer_list watchdog_timer; - struct vlan_group *vlgrp; + unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; u16 bd_number; struct work_struct reset_task; struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS]; @@ -448,9 +458,20 @@ extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *) extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern void ixgbe_configure_rx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); +extern void ixgbe_configure_tx_ring(struct ixgbe_adapter *,struct ixgbe_ring *); extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter); extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter); +extern netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, + struct net_device *, + struct ixgbe_adapter *, + struct ixgbe_ring *); +extern void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *, + struct ixgbe_tx_buffer *); +extern void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + int cleaned_count); extern void ixgbe_write_eitr(struct ixgbe_q_vector *); extern int ethtool_ioctl(struct ifreq *ifr); extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw); diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 3e06a61da9212bdd61563221f1cd3567fee4d200..0bd8fbb5bfd0dc5c32771e3521744a1f50808e64 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -39,20 +39,20 @@ #define IXGBE_82599_MC_TBL_SIZE 128 #define IXGBE_82599_VFT_TBL_SIZE 128 -void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); -void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); -void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); -s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, - ixgbe_link_speed speed, - bool autoneg, - bool autoneg_wait_to_complete); +static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw); +static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg, + bool autoneg_wait_to_complete); static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); -s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, - bool autoneg_wait_to_complete); -s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, +static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, + bool autoneg_wait_to_complete); +static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete); @@ -369,7 +369,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw) * Configures link settings based on values in the ixgbe_hw struct. * Restarts the link. Performs autonegotiation if needed. **/ -s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, +static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, bool autoneg_wait_to_complete) { u32 autoc_reg; @@ -418,7 +418,7 @@ s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, * PHY states. This includes selectively shutting down the Tx * laser on the PHY, effectively halting physical link. **/ -void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); @@ -437,7 +437,7 @@ void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) * PHY states. This includes selectively turning on the Tx * laser on the PHY, effectively starting physical link. **/ -void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP); @@ -460,7 +460,7 @@ void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) * end. This is consistent with true clause 37 autoneg, which also * involves a loss of signal. **/ -void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) +static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw) { hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n"); @@ -729,7 +729,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw, * * Set the link speed in the AUTOC register and restarts link. **/ -s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, +static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed speed, bool autoneg, bool autoneg_wait_to_complete) { @@ -1414,92 +1414,6 @@ s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr) return 0; } -/** - * ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address - * @input: input stream to modify - * @src_addr_1: the first 4 bytes of the IP address to load - * @src_addr_2: the second 4 bytes of the IP address to load - * @src_addr_3: the third 4 bytes of the IP address to load - * @src_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input, - u32 src_addr_1, u32 src_addr_2, - u32 src_addr_3, u32 src_addr_4) -{ - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] = - (src_addr_4 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] = - (src_addr_4 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] = src_addr_4 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4] = src_addr_3 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] = - (src_addr_3 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] = - (src_addr_3 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] = src_addr_3 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8] = src_addr_2 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] = - (src_addr_2 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] = - (src_addr_2 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] = src_addr_2 >> 24; - - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12] = src_addr_1 & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] = - (src_addr_1 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] = - (src_addr_1 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] = src_addr_1 >> 24; - - return 0; -} - -/** - * ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address - * @input: input stream to modify - * @dst_addr_1: the first 4 bytes of the IP address to load - * @dst_addr_2: the second 4 bytes of the IP address to load - * @dst_addr_3: the third 4 bytes of the IP address to load - * @dst_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input, - u32 dst_addr_1, u32 dst_addr_2, - u32 dst_addr_3, u32 dst_addr_4) -{ - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] = - (dst_addr_4 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] = - (dst_addr_4 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] = dst_addr_4 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4] = dst_addr_3 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] = - (dst_addr_3 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] = - (dst_addr_3 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] = dst_addr_3 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8] = dst_addr_2 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] = - (dst_addr_2 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] = - (dst_addr_2 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] = dst_addr_2 >> 24; - - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12] = dst_addr_1 & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] = - (dst_addr_1 >> 8) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] = - (dst_addr_1 >> 16) & 0xff; - input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] = dst_addr_1 >> 24; - - return 0; -} - /** * ixgbe_atr_set_src_port_82599 - Sets the source port * @input: input stream to modify @@ -1539,19 +1453,6 @@ s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte) return 0; } -/** - * ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool - * @input: input stream to modify - * @vm_pool: the Virtual Machine pool to load - **/ -s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, - u8 vm_pool) -{ - input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool; - - return 0; -} - /** * ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type * @input: input stream to modify @@ -1644,41 +1545,6 @@ static s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input, return 0; } -/** - * ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address - * @input: input stream to search - * @dst_addr_1: the first 4 bytes of the IP address to load - * @dst_addr_2: the second 4 bytes of the IP address to load - * @dst_addr_3: the third 4 bytes of the IP address to load - * @dst_addr_4: the fourth 4 bytes of the IP address to load - **/ -s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input, - u32 *dst_addr_1, u32 *dst_addr_2, - u32 *dst_addr_3, u32 *dst_addr_4) -{ - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12]; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16; - *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] << 24; - - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8]; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] << 8; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] << 16; - *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] << 24; - - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4]; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] << 8; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] << 16; - *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] << 24; - - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET]; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] << 8; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] << 16; - *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] << 24; - - return 0; -} - /** * ixgbe_atr_get_src_port_82599 - Gets the source port * @input: input stream to modify @@ -1731,19 +1597,6 @@ static s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, return 0; } -/** - * ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool - * @input: input stream to modify - * @vm_pool: the Virtual Machine pool to load - **/ -s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, - u8 *vm_pool) -{ - *vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET]; - - return 0; -} - /** * ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type * @input: input stream to modify @@ -1910,56 +1763,27 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT))); /* - * Program the relevant mask registers. If src/dst_port or src/dst_addr - * are zero, then assume a full mask for that field. Also assume that - * a VLAN of 0 is unspecified, so mask that out as well. L4type - * cannot be masked out in this implementation. + * Program the relevant mask registers. L4type cannot be + * masked out in this implementation. * * This also assumes IPv4 only. IPv6 masking isn't supported at this * point in time. */ - if (src_ipv4 == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, 0xffffffff); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask); - - if (dst_ipv4 == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, 0xffffffff); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask); + IXGBE_WRITE_REG(hw, IXGBE_FDIRSIP4M, input_masks->src_ip_mask); + IXGBE_WRITE_REG(hw, IXGBE_FDIRDIP4M, input_masks->dst_ip_mask); switch (l4type & IXGBE_ATR_L4TYPE_MASK) { case IXGBE_ATR_L4TYPE_TCP: - if (src_port == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, 0xffff); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, - input_masks->src_port_mask); - - if (dst_port == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, - (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | - (0xffff << 16))); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, - (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | - (input_masks->dst_port_mask << 16))); + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, input_masks->src_port_mask); + IXGBE_WRITE_REG(hw, IXGBE_FDIRTCPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRTCPM) | + (input_masks->dst_port_mask << 16))); break; case IXGBE_ATR_L4TYPE_UDP: - if (src_port == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, 0xffff); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, - input_masks->src_port_mask); - - if (dst_port == 0) - IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, - (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | - (0xffff << 16))); - else - IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, - (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | - (input_masks->src_port_mask << 16))); + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, input_masks->src_port_mask); + IXGBE_WRITE_REG(hw, IXGBE_FDIRUDPM, + (IXGBE_READ_REG(hw, IXGBE_FDIRUDPM) | + (input_masks->src_port_mask << 16))); break; default: /* this already would have failed above */ @@ -1967,11 +1791,11 @@ s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw, } /* Program the last mask register, FDIRM */ - if (input_masks->vlan_id_mask || !vlan_id) + if (input_masks->vlan_id_mask) /* Mask both VLAN and VLANP - bits 0 and 1 */ fdirm |= 0x3; - if (input_masks->data_mask || !flex_bytes) + if (input_masks->data_mask) /* Flex bytes need masking, so mask the whole thing - bit 4 */ fdirm |= 0x10; diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 9595b1bfb8dd54edab12c60fcf0bace4a19d1d1f..e3eca13163891c7ba339b71c1b95768247c4542e 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -52,6 +52,7 @@ static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num); +static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); /** * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx @@ -637,7 +638,7 @@ s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) * Polls the status bit (bit 1) of the EERD or EEWR to determine when the * read or write is done respectively. **/ -s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) +static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg) { u32 i; u32 reg; @@ -2449,7 +2450,7 @@ s32 ixgbe_init_uta_tables_generic(struct ixgbe_hw *hw) * return the VLVF index where this VLAN id should be placed * **/ -s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) +static s32 ixgbe_find_vlvf_slot(struct ixgbe_hw *hw, u32 vlan) { u32 bits = 0; u32 first_empty_slot = 0; @@ -2704,48 +2705,3 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, return 0; } - -/** - * ixgbe_get_wwn_prefix_generic - Get alternative WWNN/WWPN prefix from - * the EEPROM - * @hw: pointer to hardware structure - * @wwnn_prefix: the alternative WWNN prefix - * @wwpn_prefix: the alternative WWPN prefix - * - * This function will read the EEPROM from the alternative SAN MAC address - * block to check the support for the alternative WWNN/WWPN prefix support. - **/ -s32 ixgbe_get_wwn_prefix_generic(struct ixgbe_hw *hw, u16 *wwnn_prefix, - u16 *wwpn_prefix) -{ - u16 offset, caps; - u16 alt_san_mac_blk_offset; - - /* clear output first */ - *wwnn_prefix = 0xFFFF; - *wwpn_prefix = 0xFFFF; - - /* check if alternative SAN MAC is supported */ - hw->eeprom.ops.read(hw, IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR, - &alt_san_mac_blk_offset); - - if ((alt_san_mac_blk_offset == 0) || - (alt_san_mac_blk_offset == 0xFFFF)) - goto wwn_prefix_out; - - /* check capability in alternative san mac address block */ - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET; - hw->eeprom.ops.read(hw, offset, &caps); - if (!(caps & IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN)) - goto wwn_prefix_out; - - /* get the corresponding prefix for WWNN/WWPN */ - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWNN_OFFSET; - hw->eeprom.ops.read(hw, offset, wwnn_prefix); - - offset = alt_san_mac_blk_offset + IXGBE_ALT_SAN_MAC_ADDR_WWPN_OFFSET; - hw->eeprom.ops.read(hw, offset, wwpn_prefix); - -wwn_prefix_out: - return 0; -} diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index 5cf15aa11cac01cf69c3ef9c76e96efe07c7691b..424c223437dcf909c5248485adad16030f68e0bd 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -52,7 +52,6 @@ s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, u16 *checksum_val); s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); -s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg); s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, u32 enable_addr); diff --git a/drivers/net/ixgbe/ixgbe_dcb.c b/drivers/net/ixgbe/ixgbe_dcb.c index 9aea4f04bbd2bcaaf4af62f7ed592bb62fdfbe5f..8bb9ddb6dffeaff7fbdb7d8b3c0a4eacb87a797f 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.c +++ b/drivers/net/ixgbe/ixgbe_dcb.c @@ -33,98 +33,6 @@ #include "ixgbe_dcb_82598.h" #include "ixgbe_dcb_82599.h" -/** - * ixgbe_dcb_config - Struct containing DCB settings. - * @dcb_config: Pointer to DCB config structure - * - * This function checks DCB rules for DCB settings. - * The following rules are checked: - * 1. The sum of bandwidth percentages of all Bandwidth Groups must total 100%. - * 2. The sum of bandwidth percentages of all Traffic Classes within a Bandwidth - * Group must total 100. - * 3. A Traffic Class should not be set to both Link Strict Priority - * and Group Strict Priority. - * 4. Link strict Bandwidth Groups can only have link strict traffic classes - * with zero bandwidth. - */ -s32 ixgbe_dcb_check_config(struct ixgbe_dcb_config *dcb_config) -{ - struct tc_bw_alloc *p; - s32 ret_val = 0; - u8 i, j, bw = 0, bw_id; - u8 bw_sum[2][MAX_BW_GROUP]; - bool link_strict[2][MAX_BW_GROUP]; - - memset(bw_sum, 0, sizeof(bw_sum)); - memset(link_strict, 0, sizeof(link_strict)); - - /* First Tx, then Rx */ - for (i = 0; i < 2; i++) { - /* Check each traffic class for rule violation */ - for (j = 0; j < MAX_TRAFFIC_CLASS; j++) { - p = &dcb_config->tc_config[j].path[i]; - - bw = p->bwg_percent; - bw_id = p->bwg_id; - - if (bw_id >= MAX_BW_GROUP) { - ret_val = DCB_ERR_CONFIG; - goto err_config; - } - if (p->prio_type == prio_link) { - link_strict[i][bw_id] = true; - /* Link strict should have zero bandwidth */ - if (bw) { - ret_val = DCB_ERR_LS_BW_NONZERO; - goto err_config; - } - } else if (!bw) { - /* - * Traffic classes without link strict - * should have non-zero bandwidth. - */ - ret_val = DCB_ERR_TC_BW_ZERO; - goto err_config; - } - bw_sum[i][bw_id] += bw; - } - - bw = 0; - - /* Check each bandwidth group for rule violation */ - for (j = 0; j < MAX_BW_GROUP; j++) { - bw += dcb_config->bw_percentage[i][j]; - /* - * Sum of bandwidth percentages of all traffic classes - * within a Bandwidth Group must total 100 except for - * link strict group (zero bandwidth). - */ - if (link_strict[i][j]) { - if (bw_sum[i][j]) { - /* - * Link strict group should have zero - * bandwidth. - */ - ret_val = DCB_ERR_LS_BWG_NONZERO; - goto err_config; - } - } else if (bw_sum[i][j] != BW_PERCENT && - bw_sum[i][j] != 0) { - ret_val = DCB_ERR_TC_BW; - goto err_config; - } - } - - if (bw != BW_PERCENT) { - ret_val = DCB_ERR_BW_GROUP; - goto err_config; - } - } - -err_config: - return ret_val; -} - /** * ixgbe_dcb_calculate_tc_credits - Calculates traffic class credits * @ixgbe_dcb_config: Struct containing DCB settings. @@ -202,133 +110,6 @@ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *dcb_config, return ret_val; } -/** - * ixgbe_dcb_get_tc_stats - Returns status of each traffic class - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the status data for each of the Traffic Classes in use. - */ -s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_get_tc_stats_82598(hw, stats, tc_count); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_get_tc_stats_82599(hw, stats, tc_count); - return ret; -} - -/** - * ixgbe_dcb_get_pfc_stats - Returns CBFC status of each traffic class - * hw - pointer to hardware structure - * stats - pointer to statistics structure - * tc_count - Number of elements in bwg_array. - * - * This function returns the CBFC status data for each of the Traffic Classes. - */ -s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *hw, struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_get_pfc_stats_82598(hw, stats, tc_count); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_get_pfc_stats_82599(hw, stats, tc_count); - return ret; -} - -/** - * ixgbe_dcb_config_rx_arbiter - Config Rx arbiter - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure Rx Data Arbiter and credits for each traffic class. - */ -s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config); - return ret; -} - -/** - * ixgbe_dcb_config_tx_desc_arbiter - Config Tx Desc arbiter - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure Tx Descriptor Arbiter and credits for each traffic class. - */ -s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config); - return ret; -} - -/** - * ixgbe_dcb_config_tx_data_arbiter - Config Tx data arbiter - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure Tx Data Arbiter and credits for each traffic class. - */ -s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config); - return ret; -} - -/** - * ixgbe_dcb_config_pfc - Config priority flow control - * @hw: pointer to hardware structure - * @dcb_config: pointer to ixgbe_dcb_config structure - * - * Configure Priority Flow Control for each traffic class. - */ -s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_pfc_82598(hw, dcb_config); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_pfc_82599(hw, dcb_config); - return ret; -} - -/** - * ixgbe_dcb_config_tc_stats - Config traffic class statistics - * @hw: pointer to hardware structure - * - * Configure queue statistics registers, all queues belonging to same traffic - * class uses a single set of queue statistics counters. - */ -s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *hw) -{ - s32 ret = 0; - if (hw->mac.type == ixgbe_mac_82598EB) - ret = ixgbe_dcb_config_tc_stats_82598(hw); - else if (hw->mac.type == ixgbe_mac_82599EB) - ret = ixgbe_dcb_config_tc_stats_82599(hw); - return ret; -} - /** * ixgbe_dcb_hw_config - Config and enable DCB * @hw: pointer to hardware structure diff --git a/drivers/net/ixgbe/ixgbe_dcb.h b/drivers/net/ixgbe/ixgbe_dcb.h index 5caafd4afbc314ffe929d9d8083844db1753e85f..eb1059f09da0d590a98e0356c552986f576e004b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb.h +++ b/drivers/net/ixgbe/ixgbe_dcb.h @@ -149,27 +149,9 @@ struct ixgbe_dcb_config { /* DCB driver APIs */ -/* DCB rule checking function.*/ -s32 ixgbe_dcb_check_config(struct ixgbe_dcb_config *config); - /* DCB credits calculation */ s32 ixgbe_dcb_calculate_tc_credits(struct ixgbe_dcb_config *, u8); -/* DCB PFC functions */ -s32 ixgbe_dcb_config_pfc(struct ixgbe_hw *, struct ixgbe_dcb_config *g); -s32 ixgbe_dcb_get_pfc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8); - -/* DCB traffic class stats */ -s32 ixgbe_dcb_config_tc_stats(struct ixgbe_hw *); -s32 ixgbe_dcb_get_tc_stats(struct ixgbe_hw *, struct ixgbe_hw_stats *, u8); - -/* DCB config arbiters */ -s32 ixgbe_dcb_config_tx_desc_arbiter(struct ixgbe_hw *, - struct ixgbe_dcb_config *); -s32 ixgbe_dcb_config_tx_data_arbiter(struct ixgbe_hw *, - struct ixgbe_dcb_config *); -s32 ixgbe_dcb_config_rx_arbiter(struct ixgbe_hw *, struct ixgbe_dcb_config *); - /* DCB hw initialization */ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *, struct ixgbe_dcb_config *); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index f0e9279d4669b261364997693a8547581665d75e..50288bcadc5985bac86d29e2ff12abd1777875bc 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c @@ -31,65 +31,6 @@ #include "ixgbe_dcb.h" #include "ixgbe_dcb_82598.h" -/** - * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the status data for each of the Traffic Classes in use. - */ -s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - int tc; - - if (tc_count > MAX_TRAFFIC_CLASS) - return DCB_ERR_PARAM; - - /* Statistics pertaining to each traffic class */ - for (tc = 0; tc < tc_count; tc++) { - /* Transmitted Packets */ - stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc)); - /* Transmitted Bytes */ - stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc)); - /* Received Packets */ - stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc)); - /* Received Bytes */ - stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc)); - } - - return 0; -} - -/** - * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the CBFC status data for each of the Traffic Classes. - */ -s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - int tc; - - if (tc_count > MAX_TRAFFIC_CLASS) - return DCB_ERR_PARAM; - - for (tc = 0; tc < tc_count; tc++) { - /* Priority XOFF Transmitted */ - stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc)); - /* Priority XOFF Received */ - stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc)); - } - - return 0; -} - /** * ixgbe_dcb_config_packet_buffers_82598 - Configure packet buffers * @hw: pointer to hardware structure @@ -137,7 +78,7 @@ static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, * * Configure Rx Data Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -194,7 +135,7 @@ s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, * * Configure Tx Descriptor Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -242,7 +183,7 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, * * Configure Tx Data Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -355,7 +296,7 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, * Configure queue statistics registers, all queues belonging to same traffic * class uses a single set of queue statistics counters. */ -s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) +static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) { u32 reg = 0; u8 i = 0; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.h b/drivers/net/ixgbe/ixgbe_dcb_82598.h index cc728fa092e293c3e2cb642c6b075af097e96ee3..abc03ccfa088ed40bc94fb6ff81fb3bbe0914171 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.h @@ -72,21 +72,6 @@ /* DCB PFC functions */ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *); -s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *, struct ixgbe_hw_stats *, - u8); - -/* DCB traffic class stats */ -s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *); -s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *, struct ixgbe_hw_stats *, - u8); - -/* DCB config arbiters */ -s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *, - struct ixgbe_dcb_config *); -s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *, - struct ixgbe_dcb_config *); -s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *, - struct ixgbe_dcb_config *); /* DCB hw initialization */ s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *, struct ixgbe_dcb_config *); diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c index 25b02fb425ac3209aa6d4fe6fa9203525da583d0..67c219f86c3a09d06e1f51abc05bde1bc29a2345 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c @@ -30,63 +30,6 @@ #include "ixgbe_dcb.h" #include "ixgbe_dcb_82599.h" -/** - * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the status data for each of the Traffic Classes in use. - */ -s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - int tc; - - if (tc_count > MAX_TRAFFIC_CLASS) - return DCB_ERR_PARAM; - /* Statistics pertaining to each traffic class */ - for (tc = 0; tc < tc_count; tc++) { - /* Transmitted Packets */ - stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc)); - /* Transmitted Bytes */ - stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc)); - /* Received Packets */ - stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc)); - /* Received Bytes */ - stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc)); - } - - return 0; -} - -/** - * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data - * @hw: pointer to hardware structure - * @stats: pointer to statistics structure - * @tc_count: Number of elements in bwg_array. - * - * This function returns the CBFC status data for each of the Traffic Classes. - */ -s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count) -{ - int tc; - - if (tc_count > MAX_TRAFFIC_CLASS) - return DCB_ERR_PARAM; - for (tc = 0; tc < tc_count; tc++) { - /* Priority XOFF Transmitted */ - stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc)); - /* Priority XOFF Received */ - stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc)); - } - - return 0; -} - /** * ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers * @hw: pointer to hardware structure @@ -94,7 +37,7 @@ s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw, * * Configure packet buffers for DCB mode. */ -s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { s32 ret_val = 0; @@ -136,7 +79,7 @@ s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, * * Configure Rx Packet Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -191,7 +134,7 @@ s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, * * Configure Tx Descriptor Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -238,7 +181,7 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, * * Configure Tx Packet Arbiter and credits for each traffic class. */ -s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, +static s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { struct tc_bw_alloc *p; @@ -359,7 +302,7 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, * Configure queue statistics registers, all queues belonging to same traffic * class uses a single set of queue statistics counters. */ -s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) +static s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) { u32 reg = 0; u8 i = 0; @@ -412,7 +355,7 @@ s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw) * * Configure general DCB parameters. */ -s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) +static s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw) { u32 reg; u32 q; diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.h b/drivers/net/ixgbe/ixgbe_dcb_82599.h index 0f3f791e1e1d061258972e91651b344c4f380fbc..18d7fbf6c292f92d065c9434866aaedaf737623b 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82599.h +++ b/drivers/net/ixgbe/ixgbe_dcb_82599.h @@ -101,24 +101,6 @@ /* DCB PFC functions */ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config); -s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count); - -/* DCB traffic class stats */ -s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw); -s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw, - struct ixgbe_hw_stats *stats, - u8 tc_count); - -/* DCB config arbiters */ -s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config); -s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config); -s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw, - struct ixgbe_dcb_config *dcb_config); - /* DCB hw initialization */ s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw, diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index dcebc82c6f4de3a4ae0134f802cbf5c7f8e8d302..3dc731c22ff2480af0a068cea4dfe0a677486407 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -401,7 +401,7 @@ static int ixgbe_set_pauseparam(struct net_device *netdev, static u32 ixgbe_get_rx_csum(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - return (adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED); + return adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED; } static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data) @@ -820,16 +820,19 @@ static void ixgbe_get_drvinfo(struct net_device *netdev, struct ixgbe_adapter *adapter = netdev_priv(netdev); char firmware_version[32]; - strncpy(drvinfo->driver, ixgbe_driver_name, 32); - strncpy(drvinfo->version, ixgbe_driver_version, 32); + strncpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver)); + strncpy(drvinfo->version, ixgbe_driver_version, + sizeof(drvinfo->version)); - sprintf(firmware_version, "%d.%d-%d", - (adapter->eeprom_version & 0xF000) >> 12, - (adapter->eeprom_version & 0x0FF0) >> 4, - adapter->eeprom_version & 0x000F); + snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d", + (adapter->eeprom_version & 0xF000) >> 12, + (adapter->eeprom_version & 0x0FF0) >> 4, + adapter->eeprom_version & 0x000F); - strncpy(drvinfo->fw_version, firmware_version, 32); - strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); + strncpy(drvinfo->fw_version, firmware_version, + sizeof(drvinfo->fw_version)); + strncpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info)); drvinfo->n_stats = IXGBE_STATS_LEN; drvinfo->testinfo_len = IXGBE_TEST_LEN; drvinfo->regdump_len = ixgbe_get_regs_len(netdev); @@ -985,8 +988,8 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset) case ETH_SS_STATS: return IXGBE_STATS_LEN; case ETH_SS_NTUPLE_FILTERS: - return (ETHTOOL_MAX_NTUPLE_LIST_ENTRY * - ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY); + return ETHTOOL_MAX_NTUPLE_LIST_ENTRY * + ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY; default: return -EOPNOTSUPP; } @@ -996,12 +999,11 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, u64 *data) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - u64 *queue_stat; - int stat_count = sizeof(struct ixgbe_queue_stats) / sizeof(u64); struct rtnl_link_stats64 temp; const struct rtnl_link_stats64 *net_stats; - int j, k; - int i; + unsigned int start; + struct ixgbe_ring *ring; + int i, j; char *p = NULL; ixgbe_update_stats(adapter); @@ -1022,16 +1024,22 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } for (j = 0; j < adapter->num_tx_queues; j++) { - queue_stat = (u64 *)&adapter->tx_ring[j]->stats; - for (k = 0; k < stat_count; k++) - data[i + k] = queue_stat[k]; - i += k; + ring = adapter->tx_ring[j]; + do { + start = u64_stats_fetch_begin_bh(&ring->syncp); + data[i] = ring->stats.packets; + data[i+1] = ring->stats.bytes; + } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); + i += 2; } for (j = 0; j < adapter->num_rx_queues; j++) { - queue_stat = (u64 *)&adapter->rx_ring[j]->stats; - for (k = 0; k < stat_count; k++) - data[i + k] = queue_stat[k]; - i += k; + ring = adapter->rx_ring[j]; + do { + start = u64_stats_fetch_begin_bh(&ring->syncp); + data[i] = ring->stats.packets; + data[i+1] = ring->stats.bytes; + } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); + i += 2; } if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { for (j = 0; j < MAX_TX_PACKET_BUFFERS; j++) { @@ -1435,9 +1443,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; struct ixgbe_hw *hw = &adapter->hw; - struct pci_dev *pdev = adapter->pdev; u32 reg_ctl; - int i; /* shut down the DMA engines now so they can be reinitialized later */ @@ -1445,14 +1451,15 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); reg_ctl &= ~IXGBE_RXCTRL_RXEN; IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl); - reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(0)); + reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx)); reg_ctl &= ~IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(0), reg_ctl); + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx), reg_ctl); /* now Tx */ - reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(0)); + reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx)); reg_ctl &= ~IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(0), reg_ctl); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx), reg_ctl); + if (hw->mac.type == ixgbe_mac_82599EB) { reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); reg_ctl &= ~IXGBE_DMATXCTL_TE; @@ -1461,221 +1468,57 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) ixgbe_reset(adapter); - if (tx_ring->desc && tx_ring->tx_buffer_info) { - for (i = 0; i < tx_ring->count; i++) { - struct ixgbe_tx_buffer *buf = - &(tx_ring->tx_buffer_info[i]); - if (buf->dma) - dma_unmap_single(&pdev->dev, buf->dma, - buf->length, DMA_TO_DEVICE); - if (buf->skb) - dev_kfree_skb(buf->skb); - } - } - - if (rx_ring->desc && rx_ring->rx_buffer_info) { - for (i = 0; i < rx_ring->count; i++) { - struct ixgbe_rx_buffer *buf = - &(rx_ring->rx_buffer_info[i]); - if (buf->dma) - dma_unmap_single(&pdev->dev, buf->dma, - IXGBE_RXBUFFER_2048, - DMA_FROM_DEVICE); - if (buf->skb) - dev_kfree_skb(buf->skb); - } - } - - if (tx_ring->desc) { - dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc, - tx_ring->dma); - tx_ring->desc = NULL; - } - if (rx_ring->desc) { - dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, - rx_ring->dma); - rx_ring->desc = NULL; - } - - kfree(tx_ring->tx_buffer_info); - tx_ring->tx_buffer_info = NULL; - kfree(rx_ring->rx_buffer_info); - rx_ring->rx_buffer_info = NULL; + ixgbe_free_tx_resources(adapter, &adapter->test_tx_ring); + ixgbe_free_rx_resources(adapter, &adapter->test_rx_ring); } static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) { struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; - struct pci_dev *pdev = adapter->pdev; u32 rctl, reg_data; - int i, ret_val; + int ret_val; + int err; /* Setup Tx descriptor ring and Tx buffers */ + tx_ring->count = IXGBE_DEFAULT_TXD; + tx_ring->queue_index = 0; + tx_ring->reg_idx = adapter->tx_ring[0]->reg_idx; + tx_ring->numa_node = adapter->node; - if (!tx_ring->count) - tx_ring->count = IXGBE_DEFAULT_TXD; - - tx_ring->tx_buffer_info = kcalloc(tx_ring->count, - sizeof(struct ixgbe_tx_buffer), - GFP_KERNEL); - if (!(tx_ring->tx_buffer_info)) { - ret_val = 1; - goto err_nomem; - } - - tx_ring->size = tx_ring->count * sizeof(union ixgbe_adv_tx_desc); - tx_ring->size = ALIGN(tx_ring->size, 4096); - tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, - &tx_ring->dma, GFP_KERNEL); - if (!(tx_ring->desc)) { - ret_val = 2; - goto err_nomem; - } - tx_ring->next_to_use = tx_ring->next_to_clean = 0; - - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAL(0), - ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0), - ((u64) tx_ring->dma >> 32)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0), - tx_ring->count * sizeof(union ixgbe_adv_tx_desc)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); - reg_data |= IXGBE_HLREG0_TXPADEN; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); + err = ixgbe_setup_tx_resources(adapter, tx_ring); + if (err) + return 1; if (adapter->hw.mac.type == ixgbe_mac_82599EB) { reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); reg_data |= IXGBE_DMATXCTL_TE; IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); } - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(0)); - reg_data |= IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data); - - for (i = 0; i < tx_ring->count; i++) { - union ixgbe_adv_tx_desc *desc = IXGBE_TX_DESC_ADV(*tx_ring, i); - struct sk_buff *skb; - unsigned int size = 1024; - - skb = alloc_skb(size, GFP_KERNEL); - if (!skb) { - ret_val = 3; - goto err_nomem; - } - skb_put(skb, size); - tx_ring->tx_buffer_info[i].skb = skb; - tx_ring->tx_buffer_info[i].length = skb->len; - tx_ring->tx_buffer_info[i].dma = - dma_map_single(&pdev->dev, skb->data, skb->len, - DMA_TO_DEVICE); - desc->read.buffer_addr = - cpu_to_le64(tx_ring->tx_buffer_info[i].dma); - desc->read.cmd_type_len = cpu_to_le32(skb->len); - desc->read.cmd_type_len |= cpu_to_le32(IXGBE_TXD_CMD_EOP | - IXGBE_TXD_CMD_IFCS | - IXGBE_TXD_CMD_RS); - desc->read.olinfo_status = 0; - if (adapter->hw.mac.type == ixgbe_mac_82599EB) - desc->read.olinfo_status |= - (skb->len << IXGBE_ADVTXD_PAYLEN_SHIFT); - } + ixgbe_configure_tx_ring(adapter, tx_ring); /* Setup Rx Descriptor ring and Rx buffers */ - - if (!rx_ring->count) - rx_ring->count = IXGBE_DEFAULT_RXD; - - rx_ring->rx_buffer_info = kcalloc(rx_ring->count, - sizeof(struct ixgbe_rx_buffer), - GFP_KERNEL); - if (!(rx_ring->rx_buffer_info)) { + rx_ring->count = IXGBE_DEFAULT_RXD; + rx_ring->queue_index = 0; + rx_ring->reg_idx = adapter->rx_ring[0]->reg_idx; + rx_ring->rx_buf_len = IXGBE_RXBUFFER_2048; + rx_ring->numa_node = adapter->node; + + err = ixgbe_setup_rx_resources(adapter, rx_ring); + if (err) { ret_val = 4; goto err_nomem; } - rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); - rx_ring->size = ALIGN(rx_ring->size, 4096); - rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, - &rx_ring->dma, GFP_KERNEL); - if (!(rx_ring->desc)) { - ret_val = 5; - goto err_nomem; - } - rx_ring->next_to_use = rx_ring->next_to_clean = 0; - rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL); IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAL(0), - ((u64)rx_ring->dma & 0xFFFFFFFF)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAH(0), - ((u64) rx_ring->dma >> 32)); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDLEN(0), rx_ring->size); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDH(0), 0); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), 0); - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); - reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); - reg_data &= ~IXGBE_HLREG0_LPBK; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RDRXCTL); -#define IXGBE_RDRXCTL_RDMTS_MASK 0x00000003 /* Receive Descriptor Minimum - Threshold Size mask */ - reg_data &= ~IXGBE_RDRXCTL_RDMTS_MASK; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDRXCTL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MCSTCTRL); -#define IXGBE_MCSTCTRL_MO_MASK 0x00000003 /* Multicast Offset mask */ - reg_data &= ~IXGBE_MCSTCTRL_MO_MASK; - reg_data |= adapter->hw.mac.mc_filter_type; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_MCSTCTRL, reg_data); - - reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(0)); - reg_data |= IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data); - if (adapter->hw.mac.type == ixgbe_mac_82599EB) { - int j = adapter->rx_ring[0]->reg_idx; - u32 k; - for (k = 0; k < 10; k++) { - if (IXGBE_READ_REG(&adapter->hw, - IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE) - break; - else - msleep(1); - } - } + ixgbe_configure_rx_ring(adapter, rx_ring); rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS; IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl); - for (i = 0; i < rx_ring->count; i++) { - union ixgbe_adv_rx_desc *rx_desc = - IXGBE_RX_DESC_ADV(*rx_ring, i); - struct sk_buff *skb; - - skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL); - if (!skb) { - ret_val = 6; - goto err_nomem; - } - skb_reserve(skb, NET_IP_ALIGN); - rx_ring->rx_buffer_info[i].skb = skb; - rx_ring->rx_buffer_info[i].dma = - dma_map_single(&pdev->dev, skb->data, - IXGBE_RXBUFFER_2048, DMA_FROM_DEVICE); - rx_desc->read.pkt_addr = - cpu_to_le64(rx_ring->rx_buffer_info[i].dma); - memset(skb->data, 0x00, skb->len); - } - return 0; err_nomem: @@ -1689,16 +1532,21 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) u32 reg_data; /* right now we only support MAC loopback in the driver */ - - /* Setup MAC loopback */ reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0); + /* Setup MAC loopback */ reg_data |= IXGBE_HLREG0_LPBK; IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data); + reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); + reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE; + IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data); + reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_AUTOC); reg_data &= ~IXGBE_AUTOC_LMS_MASK; reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU; IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data); + IXGBE_WRITE_FLUSH(&adapter->hw); + msleep(10); /* Disable Atlas Tx lanes; re-enabled in reset path */ if (hw->mac.type == ixgbe_mac_82598EB) { @@ -1756,15 +1604,81 @@ static int ixgbe_check_lbtest_frame(struct sk_buff *skb, return 13; } +static u16 ixgbe_clean_test_rings(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + struct ixgbe_ring *tx_ring, + unsigned int size) +{ + union ixgbe_adv_rx_desc *rx_desc; + struct ixgbe_rx_buffer *rx_buffer_info; + struct ixgbe_tx_buffer *tx_buffer_info; + const int bufsz = rx_ring->rx_buf_len; + u32 staterr; + u16 rx_ntc, tx_ntc, count = 0; + + /* initialize next to clean and descriptor values */ + rx_ntc = rx_ring->next_to_clean; + tx_ntc = tx_ring->next_to_clean; + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc); + staterr = le32_to_cpu(rx_desc->wb.upper.status_error); + + while (staterr & IXGBE_RXD_STAT_DD) { + /* check Rx buffer */ + rx_buffer_info = &rx_ring->rx_buffer_info[rx_ntc]; + + /* unmap Rx buffer, will be remapped by alloc_rx_buffers */ + dma_unmap_single(&adapter->pdev->dev, + rx_buffer_info->dma, + bufsz, + DMA_FROM_DEVICE); + rx_buffer_info->dma = 0; + + /* verify contents of skb */ + if (!ixgbe_check_lbtest_frame(rx_buffer_info->skb, size)) + count++; + + /* unmap buffer on Tx side */ + tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc]; + ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); + + /* increment Rx/Tx next to clean counters */ + rx_ntc++; + if (rx_ntc == rx_ring->count) + rx_ntc = 0; + tx_ntc++; + if (tx_ntc == tx_ring->count) + tx_ntc = 0; + + /* fetch next descriptor */ + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, rx_ntc); + staterr = le32_to_cpu(rx_desc->wb.upper.status_error); + } + + /* re-map buffers to ring, store next to clean values */ + ixgbe_alloc_rx_buffers(adapter, rx_ring, count); + rx_ring->next_to_clean = rx_ntc; + tx_ring->next_to_clean = tx_ntc; + + return count; +} + static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) { struct ixgbe_ring *tx_ring = &adapter->test_tx_ring; struct ixgbe_ring *rx_ring = &adapter->test_rx_ring; - struct pci_dev *pdev = adapter->pdev; - int i, j, k, l, lc, good_cnt, ret_val = 0; - unsigned long time; + int i, j, lc, good_cnt, ret_val = 0; + unsigned int size = 1024; + netdev_tx_t tx_ret_val; + struct sk_buff *skb; + + /* allocate test skb */ + skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return 11; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), rx_ring->count - 1); + /* place data into test skb */ + ixgbe_create_lbtest_frame(skb, size); + skb_put(skb, size); /* * Calculate the loop count based on the largest descriptor ring @@ -1777,54 +1691,40 @@ static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter) else lc = ((rx_ring->count / 64) * 2) + 1; - k = l = 0; for (j = 0; j <= lc; j++) { - for (i = 0; i < 64; i++) { - ixgbe_create_lbtest_frame( - tx_ring->tx_buffer_info[k].skb, - 1024); - dma_sync_single_for_device(&pdev->dev, - tx_ring->tx_buffer_info[k].dma, - tx_ring->tx_buffer_info[k].length, - DMA_TO_DEVICE); - if (unlikely(++k == tx_ring->count)) - k = 0; - } - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), k); - msleep(200); - /* set the start time for the receive */ - time = jiffies; + /* reset count of good packets */ good_cnt = 0; - do { - /* receive the sent packets */ - dma_sync_single_for_cpu(&pdev->dev, - rx_ring->rx_buffer_info[l].dma, - IXGBE_RXBUFFER_2048, - DMA_FROM_DEVICE); - ret_val = ixgbe_check_lbtest_frame( - rx_ring->rx_buffer_info[l].skb, 1024); - if (!ret_val) + + /* place 64 packets on the transmit queue*/ + for (i = 0; i < 64; i++) { + skb_get(skb); + tx_ret_val = ixgbe_xmit_frame_ring(skb, + adapter->netdev, + adapter, + tx_ring); + if (tx_ret_val == NETDEV_TX_OK) good_cnt++; - if (++l == rx_ring->count) - l = 0; - /* - * time + 20 msecs (200 msecs on 2.4) is more than - * enough time to complete the receives, if it's - * exceeded, break and error off - */ - } while (good_cnt < 64 && jiffies < (time + 20)); + } + if (good_cnt != 64) { - /* ret_val is the same as mis-compare */ - ret_val = 13; + ret_val = 12; break; } - if (jiffies >= (time + 20)) { - /* Error code for time out error */ - ret_val = 14; + + /* allow 200 milliseconds for packets to go from Tx to Rx */ + msleep(200); + + good_cnt = ixgbe_clean_test_rings(adapter, rx_ring, + tx_ring, size); + if (good_cnt != 64) { + ret_val = 13; break; } } + /* free the original skb */ + kfree_skb(skb); + return ret_val; } @@ -2218,7 +2118,17 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) bool need_reset = false; int rc; - rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE); +#ifdef CONFIG_IXGBE_DCB + if ((adapter->flags & IXGBE_FLAG_DCB_ENABLED) && + !(data & ETH_FLAG_RXVLAN)) + return -EINVAL; +#endif + + need_reset = (data & ETH_FLAG_RXVLAN) != + (netdev->features & NETIF_F_HW_VLAN_RX); + + rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | + ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN); if (rc) return rc; diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c index 072327c5e41ab287e4ad9598145f6d3f60283f12..05efa6a8ce8e080c6cea2d85e31bcfd09728e8dd 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.c +++ b/drivers/net/ixgbe/ixgbe_fcoe.c @@ -304,12 +304,13 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, if (!ixgbe_rx_is_fcoe(rx_desc)) goto ddp_out; - skb->ip_summed = CHECKSUM_UNNECESSARY; sterr = le32_to_cpu(rx_desc->wb.upper.status_error); fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR); fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE); if (fcerr == IXGBE_FCERR_BADCRC) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); + else + skb->ip_summed = CHECKSUM_UNNECESSARY; if (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q)) fh = (struct fc_frame_header *)(skb->data + @@ -471,7 +472,7 @@ int ixgbe_fso(struct ixgbe_adapter *adapter, /* write context desc */ i = tx_ring->next_to_use; - context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i); + context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); context_desc->seqnum_seed = cpu_to_le32(fcoe_sof_eof); context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd); @@ -603,11 +604,13 @@ int ixgbe_fcoe_enable(struct net_device *netdev) { int rc = -EINVAL; struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_fcoe *fcoe = &adapter->fcoe; if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE)) goto out_enable; + atomic_inc(&fcoe->refcnt); if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) goto out_enable; @@ -647,6 +650,7 @@ int ixgbe_fcoe_disable(struct net_device *netdev) { int rc = -EINVAL; struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_fcoe *fcoe = &adapter->fcoe; if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE)) goto out_disable; @@ -654,6 +658,9 @@ int ixgbe_fcoe_disable(struct net_device *netdev) if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) goto out_disable; + if (!atomic_dec_and_test(&fcoe->refcnt)) + goto out_disable; + e_info(drv, "Disabling FCoE offload features.\n"); netdev->features &= ~NETIF_F_FCOE_CRC; netdev->features &= ~NETIF_F_FSO; diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h index abf4b2b3f2520f35117403061895cf9e968fc003..4bc2c551c8dbc85b96aed6b3fc74ba1a8c0ebd08 100644 --- a/drivers/net/ixgbe/ixgbe_fcoe.h +++ b/drivers/net/ixgbe/ixgbe_fcoe.h @@ -66,6 +66,7 @@ struct ixgbe_fcoe { u8 tc; u8 up; #endif + atomic_t refcnt; spinlock_t lock; struct pci_pool *pool; struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index e32af434cc9dd4903f41f2d53d438ff950e9fb82..f85631263af8573f7f0ea96ac63e961abebe225b 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -50,7 +50,7 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = - "Intel(R) 10 Gigabit PCI Express Network Driver"; + "Intel(R) 10 Gigabit PCI Express Network Driver"; #define DRV_VERSION "2.0.84-k2" const char ixgbe_driver_version[] = DRV_VERSION; @@ -120,7 +120,7 @@ MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); #ifdef CONFIG_IXGBE_DCA static int ixgbe_notify_dca(struct notifier_block *, unsigned long event, - void *p); + void *p); static struct notifier_block dca_notifier = { .notifier_call = ixgbe_notify_dca, .next = NULL, @@ -131,8 +131,8 @@ static struct notifier_block dca_notifier = { #ifdef CONFIG_PCI_IOV static unsigned int max_vfs; module_param(max_vfs, uint, 0); -MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate " - "per physical function"); +MODULE_PARM_DESC(max_vfs, + "Maximum number of virtual functions to allocate per physical function"); #endif /* CONFIG_PCI_IOV */ MODULE_AUTHOR("Intel Corporation, "); @@ -169,8 +169,8 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) /* take a breather then clean up driver data */ msleep(100); - if (adapter->vfinfo) - kfree(adapter->vfinfo); + + kfree(adapter->vfinfo); adapter->vfinfo = NULL; adapter->num_vfs = 0; @@ -282,17 +282,17 @@ static void ixgbe_regdump(struct ixgbe_hw *hw, struct ixgbe_reg_info *reginfo) regs[i] = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); break; default: - printk(KERN_INFO "%-15s %08x\n", reginfo->name, + pr_info("%-15s %08x\n", reginfo->name, IXGBE_READ_REG(hw, reginfo->ofs)); return; } for (i = 0; i < 8; i++) { snprintf(rname, 16, "%s[%d-%d]", reginfo->name, i*8, i*8+7); - printk(KERN_ERR "%-15s ", rname); + pr_err("%-15s", rname); for (j = 0; j < 8; j++) - printk(KERN_CONT "%08x ", regs[i*8+j]); - printk(KERN_CONT "\n"); + pr_cont(" %08x", regs[i*8+j]); + pr_cont("\n"); } } @@ -322,18 +322,18 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) /* Print netdevice Info */ if (netdev) { dev_info(&adapter->pdev->dev, "Net device Info\n"); - printk(KERN_INFO "Device Name state " + pr_info("Device Name state " "trans_start last_rx\n"); - printk(KERN_INFO "%-15s %016lX %016lX %016lX\n", - netdev->name, - netdev->state, - netdev->trans_start, - netdev->last_rx); + pr_info("%-15s %016lX %016lX %016lX\n", + netdev->name, + netdev->state, + netdev->trans_start, + netdev->last_rx); } /* Print Registers */ dev_info(&adapter->pdev->dev, "Register Dump\n"); - printk(KERN_INFO " Register Name Value\n"); + pr_info(" Register Name Value\n"); for (reginfo = (struct ixgbe_reg_info *)ixgbe_reg_info_tbl; reginfo->name; reginfo++) { ixgbe_regdump(hw, reginfo); @@ -344,13 +344,12 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) goto exit; dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); - printk(KERN_INFO "Queue [NTU] [NTC] [bi(ntc)->dma ] " - "leng ntw timestamp\n"); + pr_info("Queue [NTU] [NTC] [bi(ntc)->dma ] leng ntw timestamp\n"); for (n = 0; n < adapter->num_tx_queues; n++) { tx_ring = adapter->tx_ring[n]; tx_buffer_info = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; - printk(KERN_INFO " %5d %5X %5X %016llX %04X %3X %016llX\n", + pr_info(" %5d %5X %5X %016llX %04X %3X %016llX\n", n, tx_ring->next_to_use, tx_ring->next_to_clean, (u64)tx_buffer_info->dma, tx_buffer_info->length, @@ -377,18 +376,18 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) for (n = 0; n < adapter->num_tx_queues; n++) { tx_ring = adapter->tx_ring[n]; - printk(KERN_INFO "------------------------------------\n"); - printk(KERN_INFO "TX QUEUE INDEX = %d\n", tx_ring->queue_index); - printk(KERN_INFO "------------------------------------\n"); - printk(KERN_INFO "T [desc] [address 63:0 ] " + pr_info("------------------------------------\n"); + pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index); + pr_info("------------------------------------\n"); + pr_info("T [desc] [address 63:0 ] " "[PlPOIdStDDt Ln] [bi->dma ] " "leng ntw timestamp bi->skb\n"); for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_buffer_info = &tx_ring->tx_buffer_info[i]; u0 = (struct my_u0 *)tx_desc; - printk(KERN_INFO "T [0x%03X] %016llX %016llX %016llX" + pr_info("T [0x%03X] %016llX %016llX %016llX" " %04X %3X %016llX %p", i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), @@ -399,13 +398,13 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) tx_buffer_info->skb); if (i == tx_ring->next_to_use && i == tx_ring->next_to_clean) - printk(KERN_CONT " NTC/U\n"); + pr_cont(" NTC/U\n"); else if (i == tx_ring->next_to_use) - printk(KERN_CONT " NTU\n"); + pr_cont(" NTU\n"); else if (i == tx_ring->next_to_clean) - printk(KERN_CONT " NTC\n"); + pr_cont(" NTC\n"); else - printk(KERN_CONT "\n"); + pr_cont("\n"); if (netif_msg_pktdata(adapter) && tx_buffer_info->dma != 0) @@ -419,11 +418,11 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) /* Print RX Rings Summary */ rx_ring_summary: dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); - printk(KERN_INFO "Queue [NTU] [NTC]\n"); + pr_info("Queue [NTU] [NTC]\n"); for (n = 0; n < adapter->num_rx_queues; n++) { rx_ring = adapter->rx_ring[n]; - printk(KERN_INFO "%5d %5X %5X\n", n, - rx_ring->next_to_use, rx_ring->next_to_clean); + pr_info("%5d %5X %5X\n", + n, rx_ring->next_to_use, rx_ring->next_to_clean); } /* Print RX Rings */ @@ -454,30 +453,30 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) */ for (n = 0; n < adapter->num_rx_queues; n++) { rx_ring = adapter->rx_ring[n]; - printk(KERN_INFO "------------------------------------\n"); - printk(KERN_INFO "RX QUEUE INDEX = %d\n", rx_ring->queue_index); - printk(KERN_INFO "------------------------------------\n"); - printk(KERN_INFO "R [desc] [ PktBuf A0] " + pr_info("------------------------------------\n"); + pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index); + pr_info("------------------------------------\n"); + pr_info("R [desc] [ PktBuf A0] " "[ HeadBuf DD] [bi->dma ] [bi->skb] " "<-- Adv Rx Read format\n"); - printk(KERN_INFO "RWB[desc] [PcsmIpSHl PtRs] " + pr_info("RWB[desc] [PcsmIpSHl PtRs] " "[vl er S cks ln] ---------------- [bi->skb] " "<-- Adv Rx Write-Back format\n"); for (i = 0; i < rx_ring->count; i++) { rx_buffer_info = &rx_ring->rx_buffer_info[i]; - rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); u0 = (struct my_u0 *)rx_desc; staterr = le32_to_cpu(rx_desc->wb.upper.status_error); if (staterr & IXGBE_RXD_STAT_DD) { /* Descriptor Done */ - printk(KERN_INFO "RWB[0x%03X] %016llX " + pr_info("RWB[0x%03X] %016llX " "%016llX ---------------- %p", i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), rx_buffer_info->skb); } else { - printk(KERN_INFO "R [0x%03X] %016llX " + pr_info("R [0x%03X] %016llX " "%016llX %016llX %p", i, le64_to_cpu(u0->a), le64_to_cpu(u0->b), @@ -503,11 +502,11 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) } if (i == rx_ring->next_to_use) - printk(KERN_CONT " NTU\n"); + pr_cont(" NTU\n"); else if (i == rx_ring->next_to_clean) - printk(KERN_CONT " NTC\n"); + pr_cont(" NTC\n"); else - printk(KERN_CONT "\n"); + pr_cont("\n"); } } @@ -523,7 +522,7 @@ static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter) /* Let firmware take over control of h/w */ ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, - ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD); + ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD); } static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) @@ -533,7 +532,7 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) /* Let firmware know the driver has taken over */ ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, - ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD); + ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD); } /* @@ -545,7 +544,7 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) * */ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, - u8 queue, u8 msix_vector) + u8 queue, u8 msix_vector) { u32 ivar, index; struct ixgbe_hw *hw = &adapter->hw; @@ -586,7 +585,7 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction, } static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, - u64 qmask) + u64 qmask) { u32 mask; @@ -601,9 +600,9 @@ static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter, } } -static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, - struct ixgbe_tx_buffer - *tx_buffer_info) +void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, + struct ixgbe_tx_buffer + *tx_buffer_info) { if (tx_buffer_info->dma) { if (tx_buffer_info->mapped_as_page) @@ -637,7 +636,7 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, * Returns : true if in xon state (currently not paused) */ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { u32 txoff = IXGBE_TFCS_TXOFF; @@ -682,8 +681,8 @@ static inline bool ixgbe_tx_xon_state(struct ixgbe_adapter *adapter, } static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - unsigned int eop) + struct ixgbe_ring *tx_ring, + unsigned int eop) { struct ixgbe_hw *hw = &adapter->hw; @@ -695,7 +694,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, ixgbe_tx_xon_state(adapter, tx_ring)) { /* detected Tx unit hang */ union ixgbe_adv_tx_desc *tx_desc; - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); e_err(drv, "Detected Tx Unit Hang\n" " Tx Queue <%d>\n" " TDH, TDT <%x>, <%x>\n" @@ -732,7 +731,7 @@ static void ixgbe_tx_timeout(struct net_device *netdev); * @tx_ring: tx ring to clean **/ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct ixgbe_adapter *adapter = q_vector->adapter; struct net_device *netdev = adapter->netdev; @@ -743,7 +742,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, i = tx_ring->next_to_clean; eop = tx_ring->tx_buffer_info[i].next_to_watch; - eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); + eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) && (count < tx_ring->work_limit)) { @@ -751,7 +750,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, rmb(); /* read buffer_info after eop_desc */ for ( ; !cleaned; count++) { struct sk_buff *skb; - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_buffer_info = &tx_ring->tx_buffer_info[i]; cleaned = (i == eop); skb = tx_buffer_info->skb; @@ -781,7 +780,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } ixgbe_unmap_and_free_tx_resource(adapter, - tx_buffer_info); + tx_buffer_info); tx_desc->wb.status = 0; @@ -791,14 +790,14 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, } eop = tx_ring->tx_buffer_info[i].next_to_watch; - eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); + eop_desc = IXGBE_TX_DESC_ADV(tx_ring, eop); } tx_ring->next_to_clean = i; #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2) if (unlikely(count && netif_carrier_ok(netdev) && - (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) { + (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))) { /* Make sure that anybody stopping the queue after this * sees the new next_to_clean. */ @@ -825,14 +824,16 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector, tx_ring->total_bytes += total_bytes; tx_ring->total_packets += total_packets; + u64_stats_update_begin(&tx_ring->syncp); tx_ring->stats.packets += total_packets; tx_ring->stats.bytes += total_bytes; - return (count < tx_ring->work_limit); + u64_stats_update_end(&tx_ring->syncp); + return count < tx_ring->work_limit; } #ifdef CONFIG_IXGBE_DCA static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { u32 rxctrl; int cpu = get_cpu(); @@ -846,13 +847,13 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { rxctrl &= ~IXGBE_DCA_RXCTRL_CPUID_MASK_82599; rxctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); + IXGBE_DCA_RXCTRL_CPUID_SHIFT_82599); } rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN; rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN; rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN); rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN | - IXGBE_DCA_RXCTRL_DESC_HSRO_EN); + IXGBE_DCA_RXCTRL_DESC_HSRO_EN); IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_RXCTRL(q), rxctrl); rx_ring->cpu = cpu; } @@ -860,7 +861,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, } static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { u32 txctrl; int cpu = get_cpu(); @@ -878,7 +879,7 @@ static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(q)); txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK_82599; txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) << - IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); + IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599); txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN; IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(q), txctrl); } @@ -946,27 +947,22 @@ static int __ixgbe_notify_dca(struct device *dev, void *data) * @rx_desc: rx descriptor **/ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector, - struct sk_buff *skb, u8 status, - struct ixgbe_ring *ring, - union ixgbe_adv_rx_desc *rx_desc) + struct sk_buff *skb, u8 status, + struct ixgbe_ring *ring, + union ixgbe_adv_rx_desc *rx_desc) { struct ixgbe_adapter *adapter = q_vector->adapter; struct napi_struct *napi = &q_vector->napi; bool is_vlan = (status & IXGBE_RXD_STAT_VP); u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan); - skb_record_rx_queue(skb, ring->queue_index); - if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) { - if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK)) - vlan_gro_receive(napi, adapter->vlgrp, tag, skb); - else - napi_gro_receive(napi, skb); - } else { - if (adapter->vlgrp && is_vlan && (tag & VLAN_VID_MASK)) - vlan_hwaccel_rx(skb, adapter->vlgrp, tag); - else - netif_rx(skb); - } + if (is_vlan && (tag & VLAN_VID_MASK)) + __vlan_hwaccel_put_tag(skb, tag); + + if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) + napi_gro_receive(napi, skb); + else + netif_rx(skb); } /** @@ -981,7 +977,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, { u32 status_err = le32_to_cpu(rx_desc->wb.upper.status_error); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Rx csum disabled */ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) @@ -1017,7 +1013,7 @@ static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter, } static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, - struct ixgbe_ring *rx_ring, u32 val) + struct ixgbe_ring *rx_ring, u32 val) { /* * Force memory writes to complete before letting h/w @@ -1033,25 +1029,27 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_hw *hw, * ixgbe_alloc_rx_buffers - Replace used receive buffers; packet split * @adapter: address of board private structure **/ -static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring, - int cleaned_count) +void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring, + int cleaned_count) { + struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; unsigned int i; + unsigned int bufsz = rx_ring->rx_buf_len; i = rx_ring->next_to_use; bi = &rx_ring->rx_buffer_info[i]; while (cleaned_count--) { - rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); if (!bi->page_dma && (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED)) { if (!bi->page) { - bi->page = alloc_page(GFP_ATOMIC); + bi->page = netdev_alloc_page(netdev); if (!bi->page) { adapter->alloc_rx_page_failed++; goto no_buffers; @@ -1063,29 +1061,28 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, } bi->page_dma = dma_map_page(&pdev->dev, bi->page, - bi->page_offset, - (PAGE_SIZE / 2), + bi->page_offset, + (PAGE_SIZE / 2), DMA_FROM_DEVICE); } if (!bi->skb) { - struct sk_buff *skb; - /* netdev_alloc_skb reserves 32 bytes up front!! */ - uint bufsz = rx_ring->rx_buf_len + SMP_CACHE_BYTES; - skb = netdev_alloc_skb(adapter->netdev, bufsz); + struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, + bufsz); + bi->skb = skb; if (!skb) { adapter->alloc_rx_buff_failed++; goto no_buffers; } + /* initialize queue mapping */ + skb_record_rx_queue(skb, rx_ring->queue_index); + } - /* advance the data pointer to the next cache line */ - skb_reserve(skb, (PTR_ALIGN(skb->data, SMP_CACHE_BYTES) - - skb->data)); - - bi->skb = skb; - bi->dma = dma_map_single(&pdev->dev, skb->data, - rx_ring->rx_buf_len, + if (!bi->dma) { + bi->dma = dma_map_single(&pdev->dev, + bi->skb->data, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); } /* Refresh the desc even if buffer_addrs didn't change because @@ -1095,6 +1092,7 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, rx_desc->read.hdr_addr = cpu_to_le64(bi->dma); } else { rx_desc->read.pkt_addr = cpu_to_le64(bi->dma); + rx_desc->read.hdr_addr = 0; } i++; @@ -1126,8 +1124,8 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc) static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc) { return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) & - IXGBE_RXDADV_RSCCNT_MASK) >> - IXGBE_RXDADV_RSCCNT_SHIFT; + IXGBE_RXDADV_RSCCNT_MASK) >> + IXGBE_RXDADV_RSCCNT_SHIFT; } /** @@ -1140,7 +1138,7 @@ static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc) * turns it into the frag list owner. **/ static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb, - u64 *count) + u64 *count) { unsigned int frag_list_size = 0; @@ -1168,11 +1166,10 @@ struct ixgbe_rsc_cb { #define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, - struct ixgbe_ring *rx_ring, - int *work_done, int work_to_do) + struct ixgbe_ring *rx_ring, + int *work_done, int work_to_do) { struct ixgbe_adapter *adapter = q_vector->adapter; - struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc, *next_rxd; struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; @@ -1188,7 +1185,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, #endif /* IXGBE_FCOE */ i = rx_ring->next_to_clean; - rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); + rx_desc = IXGBE_RX_DESC_ADV(rx_ring, i); staterr = le32_to_cpu(rx_desc->wb.upper.status_error); rx_buffer_info = &rx_ring->rx_buffer_info[i]; @@ -1231,9 +1228,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma; } else { dma_unmap_single(&pdev->dev, - rx_buffer_info->dma, - rx_ring->rx_buf_len, - DMA_FROM_DEVICE); + rx_buffer_info->dma, + rx_ring->rx_buf_len, + DMA_FROM_DEVICE); } rx_buffer_info->dma = 0; skb_put(skb, len); @@ -1244,9 +1241,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, PAGE_SIZE / 2, DMA_FROM_DEVICE); rx_buffer_info->page_dma = 0; skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, - rx_buffer_info->page, - rx_buffer_info->page_offset, - upper_len); + rx_buffer_info->page, + rx_buffer_info->page_offset, + upper_len); if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) || (page_count(rx_buffer_info->page) != 1)) @@ -1263,7 +1260,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (i == rx_ring->count) i = 0; - next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i); + next_rxd = IXGBE_RX_DESC_ADV(rx_ring, i); prefetch(next_rxd); cleaned_count++; @@ -1280,24 +1277,28 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, if (staterr & IXGBE_RXD_STAT_EOP) { if (skb->prev) - skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count)); + skb = ixgbe_transform_rsc_queue(skb, + &(rx_ring->rsc_count)); if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { if (IXGBE_RSC_CB(skb)->delay_unmap) { dma_unmap_single(&pdev->dev, IXGBE_RSC_CB(skb)->dma, - rx_ring->rx_buf_len, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); IXGBE_RSC_CB(skb)->dma = 0; IXGBE_RSC_CB(skb)->delay_unmap = false; } if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) - rx_ring->rsc_count += skb_shinfo(skb)->nr_frags; + rx_ring->rsc_count += + skb_shinfo(skb)->nr_frags; else rx_ring->rsc_count++; rx_ring->rsc_flush++; } + u64_stats_update_begin(&rx_ring->syncp); rx_ring->stats.packets++; rx_ring->stats.bytes += skb->len; + u64_stats_update_end(&rx_ring->syncp); } else { if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { rx_buffer_info->skb = next_buffer->skb; @@ -1373,8 +1374,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, rx_ring->total_packets += total_rx_packets; rx_ring->total_bytes += total_rx_bytes; - netdev->stats.rx_bytes += total_rx_bytes; - netdev->stats.rx_packets += total_rx_packets; return cleaned; } @@ -1403,24 +1402,24 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) q_vector = adapter->q_vector[v_idx]; /* XXX for_each_set_bit(...) */ r_idx = find_first_bit(q_vector->rxr_idx, - adapter->num_rx_queues); + adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { j = adapter->rx_ring[r_idx]->reg_idx; ixgbe_set_ivar(adapter, 0, j, v_idx); r_idx = find_next_bit(q_vector->rxr_idx, - adapter->num_rx_queues, - r_idx + 1); + adapter->num_rx_queues, + r_idx + 1); } r_idx = find_first_bit(q_vector->txr_idx, - adapter->num_tx_queues); + adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { j = adapter->tx_ring[r_idx]->reg_idx; ixgbe_set_ivar(adapter, 1, j, v_idx); r_idx = find_next_bit(q_vector->txr_idx, - adapter->num_tx_queues, - r_idx + 1); + adapter->num_tx_queues, + r_idx + 1); } if (q_vector->txr_count && !q_vector->rxr_count) @@ -1431,11 +1430,26 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) q_vector->eitr = adapter->rx_eitr_param; ixgbe_write_eitr(q_vector); + /* If Flow Director is enabled, set interrupt affinity */ + if ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) || + (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)) { + /* + * Allocate the affinity_hint cpumask, assign the mask + * for this vector, and set our affinity_hint for + * this irq. + */ + if (!alloc_cpumask_var(&q_vector->affinity_mask, + GFP_KERNEL)) + return; + cpumask_set_cpu(v_idx, q_vector->affinity_mask); + irq_set_affinity_hint(adapter->msix_entries[v_idx].vector, + q_vector->affinity_mask); + } } if (adapter->hw.mac.type == ixgbe_mac_82598EB) ixgbe_set_ivar(adapter, -1, IXGBE_IVAR_OTHER_CAUSES_INDEX, - v_idx); + v_idx); else if (adapter->hw.mac.type == ixgbe_mac_82599EB) ixgbe_set_ivar(adapter, -1, 1, v_idx); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950); @@ -1477,8 +1491,8 @@ enum latency_range { * parameter (see ixgbe_param.c) **/ static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter, - u32 eitr, u8 itr_setting, - int packets, int bytes) + u32 eitr, u8 itr_setting, + int packets, int bytes) { unsigned int retval = itr_setting; u32 timepassed_us; @@ -1567,30 +1581,30 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) for (i = 0; i < q_vector->txr_count; i++) { tx_ring = adapter->tx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->tx_itr, - tx_ring->total_packets, - tx_ring->total_bytes); + q_vector->tx_itr, + tx_ring->total_packets, + tx_ring->total_bytes); /* if the result for this queue would decrease interrupt * rate for this vector then use that result */ q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ? - q_vector->tx_itr - 1 : ret_itr); + q_vector->tx_itr - 1 : ret_itr); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { rx_ring = adapter->rx_ring[r_idx]; ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->rx_itr, - rx_ring->total_packets, - rx_ring->total_bytes); + q_vector->rx_itr, + rx_ring->total_packets, + rx_ring->total_bytes); /* if the result for this queue would decrease interrupt * rate for this vector then use that result */ q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ? - q_vector->rx_itr - 1 : ret_itr); + q_vector->rx_itr - 1 : ret_itr); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } current_itr = max(q_vector->rx_itr, q_vector->tx_itr); @@ -1627,39 +1641,40 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) static void ixgbe_check_overtemp_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - check_overtemp_task); + struct ixgbe_adapter, + check_overtemp_task); struct ixgbe_hw *hw = &adapter->hw; u32 eicr = adapter->interrupt_event; - if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) { - switch (hw->device_id) { - case IXGBE_DEV_ID_82599_T3_LOM: { - u32 autoneg; - bool link_up = false; + if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)) + return; - if (hw->mac.ops.check_link) - hw->mac.ops.check_link(hw, &autoneg, &link_up, false); + switch (hw->device_id) { + case IXGBE_DEV_ID_82599_T3_LOM: { + u32 autoneg; + bool link_up = false; - if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) || - (eicr & IXGBE_EICR_LSC)) - /* Check if this is due to overtemp */ - if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP) - break; - } + if (hw->mac.ops.check_link) + hw->mac.ops.check_link(hw, &autoneg, &link_up, false); + + if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) || + (eicr & IXGBE_EICR_LSC)) + /* Check if this is due to overtemp */ + if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP) + break; + return; + } + default: + if (!(eicr & IXGBE_EICR_GPI_SDP0)) return; - default: - if (!(eicr & IXGBE_EICR_GPI_SDP0)) - return; - break; - } - e_crit(drv, "Network adapter has been stopped because it has " - "over heated. Restart the computer. If the problem " - "persists, power off the system and replace the " - "adapter\n"); - /* write to clear the interrupt */ - IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0); + break; } + e_crit(drv, + "Network adapter has been stopped because it has over heated. " + "Restart the computer. If the problem persists, " + "power off the system and replace the adapter\n"); + /* write to clear the interrupt */ + IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0); } static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr) @@ -1746,9 +1761,9 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) netif_tx_stop_all_queues(netdev); for (i = 0; i < adapter->num_tx_queues; i++) { struct ixgbe_ring *tx_ring = - adapter->tx_ring[i]; + adapter->tx_ring[i]; if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE, - &tx_ring->reinit_state)) + &tx_ring->reinit_state)) schedule_work(&adapter->fdir_reinit_task); } } @@ -1777,7 +1792,7 @@ static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter, } static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter, - u64 qmask) + u64 qmask) { u32 mask; @@ -1809,7 +1824,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) tx_ring->total_bytes = 0; tx_ring->total_packets = 0; r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } /* EIAM disabled interrupts (on this vector) for us */ @@ -1837,7 +1852,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) rx_ring->total_bytes = 0; rx_ring->total_packets = 0; r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } if (!q_vector->rxr_count) @@ -1867,7 +1882,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) ring->total_bytes = 0; ring->total_packets = 0; r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); @@ -1876,7 +1891,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) ring->total_bytes = 0; ring->total_packets = 0; r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } /* EIAM disabled interrupts (on this vector) for us */ @@ -1896,7 +1911,7 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; struct ixgbe_ring *rx_ring = NULL; int work_done = 0; @@ -1918,7 +1933,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, - ((u64)1 << q_vector->v_idx)); + ((u64)1 << q_vector->v_idx)); } return work_done; @@ -1935,7 +1950,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; struct ixgbe_ring *ring = NULL; int work_done = 0, i; @@ -1951,7 +1966,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) #endif tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } /* attempt to distribute budget to each queue fairly, but don't allow @@ -1967,7 +1982,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) #endif ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); @@ -1979,7 +1994,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable_queues(adapter, - ((u64)1 << q_vector->v_idx)); + ((u64)1 << q_vector->v_idx)); return 0; } @@ -1997,7 +2012,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget) static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; struct ixgbe_ring *tx_ring = NULL; int work_done = 0; @@ -2019,14 +2034,15 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget) if (adapter->tx_itr_setting & 1) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx)); + ixgbe_irq_enable_queues(adapter, + ((u64)1 << q_vector->v_idx)); } return work_done; } static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, - int r_idx) + int r_idx) { struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; @@ -2035,7 +2051,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, } static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, - int t_idx) + int t_idx) { struct ixgbe_q_vector *q_vector = a->q_vector[v_idx]; @@ -2055,7 +2071,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, * mapping configurations in here. **/ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter, - int vectors) + int vectors) { int v_start = 0; int rxr_idx = 0, txr_idx = 0; @@ -2122,7 +2138,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) struct net_device *netdev = adapter->netdev; irqreturn_t (*handler)(int, void *); int i, vector, q_vectors, err; - int ri=0, ti=0; + int ri = 0, ti = 0; /* Decrement for Other and TCP Timer vectors */ q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; @@ -2133,26 +2149,24 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) goto out; #define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \ - (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ - &ixgbe_msix_clean_many) + (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ + &ixgbe_msix_clean_many) for (vector = 0; vector < q_vectors; vector++) { handler = SET_HANDLER(adapter->q_vector[vector]); - if(handler == &ixgbe_msix_clean_rx) { + if (handler == &ixgbe_msix_clean_rx) { sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "rx", ri++); - } - else if(handler == &ixgbe_msix_clean_tx) { + } else if (handler == &ixgbe_msix_clean_tx) { sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "tx", ti++); - } - else + } else sprintf(adapter->name[vector], "%s-%s-%d", netdev->name, "TxRx", vector); err = request_irq(adapter->msix_entries[vector].vector, - handler, 0, adapter->name[vector], - adapter->q_vector[vector]); + handler, 0, adapter->name[vector], + adapter->q_vector[vector]); if (err) { e_err(probe, "request_irq failed for MSIX interrupt " "Error: %d\n", err); @@ -2162,7 +2176,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) sprintf(adapter->name[vector], "%s:lsc", netdev->name); err = request_irq(adapter->msix_entries[vector].vector, - ixgbe_msix_lsc, 0, adapter->name[vector], netdev); + ixgbe_msix_lsc, 0, adapter->name[vector], netdev); if (err) { e_err(probe, "request_irq for msix_lsc failed: %d\n", err); goto free_queue_irqs; @@ -2173,7 +2187,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) free_queue_irqs: for (i = vector - 1; i >= 0; i--) free_irq(adapter->msix_entries[--vector].vector, - adapter->q_vector[i]); + adapter->q_vector[i]); adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; pci_disable_msix(adapter->pdev); kfree(adapter->msix_entries); @@ -2191,13 +2205,13 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) struct ixgbe_ring *tx_ring = adapter->tx_ring[0]; q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr, - q_vector->tx_itr, - tx_ring->total_packets, - tx_ring->total_bytes); + q_vector->tx_itr, + tx_ring->total_packets, + tx_ring->total_bytes); q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr, - q_vector->rx_itr, - rx_ring->total_packets, - rx_ring->total_bytes); + q_vector->rx_itr, + rx_ring->total_packets, + rx_ring->total_bytes); current_itr = max(q_vector->rx_itr, q_vector->tx_itr); @@ -2231,7 +2245,8 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) * ixgbe_irq_enable - Enable default interrupt generation settings * @adapter: board private structure **/ -static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) +static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, + bool flush) { u32 mask; @@ -2252,8 +2267,10 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) mask |= IXGBE_EIMS_FLOW_DIR; IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); - ixgbe_irq_enable_queues(adapter, ~0); - IXGBE_WRITE_FLUSH(&adapter->hw); + if (queues) + ixgbe_irq_enable_queues(adapter, ~0); + if (flush) + IXGBE_WRITE_FLUSH(&adapter->hw); if (adapter->num_vfs > 32) { u32 eitrsel = (1 << (adapter->num_vfs - 32)) - 1; @@ -2275,7 +2292,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data) u32 eicr; /* - * Workaround for silicon errata. Mask the interrupts + * Workaround for silicon errata on 82598. Mask the interrupts * before the read of EICR. */ IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); @@ -2284,10 +2301,15 @@ static irqreturn_t ixgbe_intr(int irq, void *data) * therefore no explict interrupt disable is necessary */ eicr = IXGBE_READ_REG(hw, IXGBE_EICR); if (!eicr) { - /* shared interrupt alert! + /* + * shared interrupt alert! * make sure interrupts are enabled because the read will - * have disabled interrupts due to EIAM */ - ixgbe_irq_enable(adapter); + * have disabled interrupts due to EIAM + * finish the workaround of silicon errata on 82598. Unmask + * the interrupt that we masked before the EICR read. + */ + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + ixgbe_irq_enable(adapter, true, true); return IRQ_NONE; /* Not our interrupt */ } @@ -2311,6 +2333,14 @@ static irqreturn_t ixgbe_intr(int irq, void *data) __napi_schedule(&(q_vector->napi)); } + /* + * re-enable link(maybe) and non-queue interrupts, no flush. + * ixgbe_poll will re-enable the queue interrupts + */ + + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + ixgbe_irq_enable(adapter, false, false); + return IRQ_HANDLED; } @@ -2343,10 +2373,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter) err = ixgbe_request_msix_irqs(adapter); } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { err = request_irq(adapter->pdev->irq, ixgbe_intr, 0, - netdev->name, netdev); + netdev->name, netdev); } else { err = request_irq(adapter->pdev->irq, ixgbe_intr, IRQF_SHARED, - netdev->name, netdev); + netdev->name, netdev); } if (err) @@ -2370,7 +2400,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) i--; for (; i >= 0; i--) { free_irq(adapter->msix_entries[i].vector, - adapter->q_vector[i]); + adapter->q_vector[i]); } ixgbe_reset_q_vectors(adapter); @@ -2413,7 +2443,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; IXGBE_WRITE_REG(hw, IXGBE_EITR(0), - EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param)); + EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param)); ixgbe_set_ivar(adapter, 0, 0, 0); ixgbe_set_ivar(adapter, 1, 0, 0); @@ -2425,95 +2455,140 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) } /** - * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset + * ixgbe_configure_tx_ring - Configure 8259x Tx ring after Reset * @adapter: board private structure + * @ring: structure containing ring specific data * - * Configure the Tx unit of the MAC after a reset. + * Configure the Tx descriptor ring after a reset. **/ -static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) +void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) { - u64 tdba; struct ixgbe_hw *hw = &adapter->hw; - u32 i, j, tdlen, txctrl; + u64 tdba = ring->dma; + int wait_loop = 10; + u32 txdctl; + u16 reg_idx = ring->reg_idx; - /* Setup the HW Tx Head and Tail descriptor pointers */ - for (i = 0; i < adapter->num_tx_queues; i++) { - struct ixgbe_ring *ring = adapter->tx_ring[i]; - j = ring->reg_idx; - tdba = ring->dma; - tdlen = ring->count * sizeof(union ixgbe_adv_tx_desc); - IXGBE_WRITE_REG(hw, IXGBE_TDBAL(j), - (tdba & DMA_BIT_MASK(32))); - IXGBE_WRITE_REG(hw, IXGBE_TDBAH(j), (tdba >> 32)); - IXGBE_WRITE_REG(hw, IXGBE_TDLEN(j), tdlen); - IXGBE_WRITE_REG(hw, IXGBE_TDH(j), 0); - IXGBE_WRITE_REG(hw, IXGBE_TDT(j), 0); - adapter->tx_ring[i]->head = IXGBE_TDH(j); - adapter->tx_ring[i]->tail = IXGBE_TDT(j); - /* - * Disable Tx Head Writeback RO bit, since this hoses - * bookkeeping if things aren't delivered in order. - */ - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(j)); - break; - case ixgbe_mac_82599EB: - default: - txctrl = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(j)); - break; - } - txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN; - switch (hw->mac.type) { - case ixgbe_mac_82598EB: - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(j), txctrl); - break; - case ixgbe_mac_82599EB: - default: - IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(j), txctrl); - break; - } + /* disable queue to avoid issues while updating state */ + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), + txdctl & ~IXGBE_TXDCTL_ENABLE); + IXGBE_WRITE_FLUSH(hw); + + IXGBE_WRITE_REG(hw, IXGBE_TDBAL(reg_idx), + (tdba & DMA_BIT_MASK(32))); + IXGBE_WRITE_REG(hw, IXGBE_TDBAH(reg_idx), (tdba >> 32)); + IXGBE_WRITE_REG(hw, IXGBE_TDLEN(reg_idx), + ring->count * sizeof(union ixgbe_adv_tx_desc)); + IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0); + IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0); + ring->head = IXGBE_TDH(reg_idx); + ring->tail = IXGBE_TDT(reg_idx); + + /* configure fetching thresholds */ + if (adapter->rx_itr_setting == 0) { + /* cannot set wthresh when itr==0 */ + txdctl &= ~0x007F0000; + } else { + /* enable WTHRESH=8 descriptors, to encourage burst writeback */ + txdctl |= (8 << 16); + } + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { + /* PThresh workaround for Tx hang with DFP enabled. */ + txdctl |= 32; } - if (hw->mac.type == ixgbe_mac_82599EB) { - u32 rttdcs; - u32 mask; + /* reinitialize flowdirector state */ + set_bit(__IXGBE_FDIR_INIT_DONE, &ring->reinit_state); - /* disable the arbiter while setting MTQC */ - rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); - rttdcs |= IXGBE_RTTDCS_ARBDIS; - IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); + /* enable queue */ + txdctl |= IXGBE_TXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl); - /* set transmit pool layout */ - mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED); - switch (adapter->flags & mask) { + /* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */ + if (hw->mac.type == ixgbe_mac_82598EB && + !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + return; - case (IXGBE_FLAG_SRIOV_ENABLED): - IXGBE_WRITE_REG(hw, IXGBE_MTQC, - (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF)); - break; + /* poll to verify queue is enabled */ + do { + msleep(1); + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx)); + } while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE)); + if (!wait_loop) + e_err(drv, "Could not enable Tx Queue %d\n", reg_idx); +} - case (IXGBE_FLAG_DCB_ENABLED): - /* We enable 8 traffic classes, DCB only */ - IXGBE_WRITE_REG(hw, IXGBE_MTQC, - (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ)); - break; +static void ixgbe_setup_mtqc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rttdcs; + u32 mask; - default: - IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB); - break; - } + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + /* disable the arbiter while setting MTQC */ + rttdcs = IXGBE_READ_REG(hw, IXGBE_RTTDCS); + rttdcs |= IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); + + /* set transmit pool layout */ + mask = (IXGBE_FLAG_SRIOV_ENABLED | IXGBE_FLAG_DCB_ENABLED); + switch (adapter->flags & mask) { + + case (IXGBE_FLAG_SRIOV_ENABLED): + IXGBE_WRITE_REG(hw, IXGBE_MTQC, + (IXGBE_MTQC_VT_ENA | IXGBE_MTQC_64VF)); + break; + + case (IXGBE_FLAG_DCB_ENABLED): + /* We enable 8 traffic classes, DCB only */ + IXGBE_WRITE_REG(hw, IXGBE_MTQC, + (IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ)); + break; + + default: + IXGBE_WRITE_REG(hw, IXGBE_MTQC, IXGBE_MTQC_64Q_1PB); + break; + } + + /* re-enable the arbiter */ + rttdcs &= ~IXGBE_RTTDCS_ARBDIS; + IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); +} - /* re-eable the arbiter */ - rttdcs &= ~IXGBE_RTTDCS_ARBDIS; - IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, rttdcs); +/** + * ixgbe_configure_tx - Configure 8259x Transmit Unit after Reset + * @adapter: board private structure + * + * Configure the Tx unit of the MAC after a reset. + **/ +static void ixgbe_configure_tx(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 dmatxctl; + u32 i; + + ixgbe_setup_mtqc(adapter); + + if (hw->mac.type != ixgbe_mac_82598EB) { + /* DMATXCTL.EN must be before Tx queues are enabled */ + dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); + dmatxctl |= IXGBE_DMATXCTL_TE; + IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); } + + /* Setup the HW Tx Head and Tail descriptor pointers */ + for (i = 0; i < adapter->num_tx_queues; i++) + ixgbe_configure_tx_ring(adapter, adapter->tx_ring[i]); } #define IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT 2 static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { u32 srrctl; int index; @@ -2529,6 +2604,8 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK; srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK; + if (adapter->num_vfs) + srrctl |= IXGBE_SRRCTL_DROP_EN; srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & IXGBE_SRRCTL_BSIZEHDR_MASK; @@ -2549,20 +2626,46 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl); } -static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) +static void ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) { - u32 mrqc = 0; + struct ixgbe_hw *hw = &adapter->hw; + static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D, + 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, + 0x6A3E67EA, 0x14364D17, 0x3BED200D}; + u32 mrqc = 0, reta = 0; + u32 rxcsum; + int i, j; int mask; - if (!(adapter->hw.mac.type == ixgbe_mac_82599EB)) - return mrqc; + /* Fill out hash function seeds */ + for (i = 0; i < 10; i++) + IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]); - mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED + /* Fill out redirection table */ + for (i = 0, j = 0; i < 128; i++, j++) { + if (j == adapter->ring_feature[RING_F_RSS].indices) + j = 0; + /* reta = 4-byte sliding window of + * 0x00..(indices-1)(indices-1)00..etc. */ + reta = (reta << 8) | (j * 0x11); + if ((i & 3) == 3) + IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); + } + + /* Disable indicating checksum in descriptor, enables RSS hash */ + rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); + rxcsum |= IXGBE_RXCSUM_PCSD; + IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); + + if (adapter->hw.mac.type == ixgbe_mac_82598EB) + mask = adapter->flags & IXGBE_FLAG_RSS_ENABLED; + else + mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED #ifdef CONFIG_IXGBE_DCB - | IXGBE_FLAG_DCB_ENABLED + | IXGBE_FLAG_DCB_ENABLED #endif - | IXGBE_FLAG_SRIOV_ENABLED - ); + | IXGBE_FLAG_SRIOV_ENABLED + ); switch (mask) { case (IXGBE_FLAG_RSS_ENABLED): @@ -2580,7 +2683,13 @@ static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) break; } - return mrqc; + /* Perform hash on these packet types */ + mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4 + | IXGBE_MRQC_RSS_FIELD_IPV4_TCP + | IXGBE_MRQC_RSS_FIELD_IPV6 + | IXGBE_MRQC_RSS_FIELD_IPV6_TCP; + + IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); } /** @@ -2588,25 +2697,26 @@ static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter) * @adapter: address of board private structure * @index: index of ring to set **/ -static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index) +static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) { - struct ixgbe_ring *rx_ring; struct ixgbe_hw *hw = &adapter->hw; - int j; u32 rscctrl; int rx_buf_len; + u16 reg_idx = ring->reg_idx; - rx_ring = adapter->rx_ring[index]; - j = rx_ring->reg_idx; - rx_buf_len = rx_ring->rx_buf_len; - rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j)); + if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)) + return; + + rx_buf_len = ring->rx_buf_len; + rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(reg_idx)); rscctrl |= IXGBE_RSCCTL_RSCEN; /* * we must limit the number of descriptors so that the * total size of max desc * buf_len is not greater * than 65535 */ - if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) { + if (ring->flags & IXGBE_RING_RX_PS_ENABLED) { #if (MAX_SKB_FRAGS > 16) rscctrl |= IXGBE_RSCCTL_MAXDESC_16; #elif (MAX_SKB_FRAGS > 8) @@ -2624,31 +2734,181 @@ static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index) else rscctrl |= IXGBE_RSCCTL_MAXDESC_4; } - IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl); + IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(reg_idx), rscctrl); } /** - * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset - * @adapter: board private structure + * ixgbe_set_uta - Set unicast filter table address + * @adapter: board private structure * - * Configure the Rx unit of the MAC after a reset. + * The unicast table address is a register array of 32-bit registers. + * The table is meant to be used in a way similar to how the MTA is used + * however due to certain limitations in the hardware it is necessary to + * set all the hash bits to 1 and use the VMOLR ROPE bit as a promiscuous + * enable bit to allow vlan tag stripping when promiscuous mode is enabled **/ -static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) +static void ixgbe_set_uta(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i; + + /* The UTA table only exists on 82599 hardware and newer */ + if (hw->mac.type < ixgbe_mac_82599EB) + return; + + /* we only need to do this if VMDq is enabled */ + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + return; + + for (i = 0; i < 128; i++) + IXGBE_WRITE_REG(hw, IXGBE_UTA(i), ~0); +} + +#define IXGBE_MAX_RX_DESC_POLL 10 +static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + int reg_idx = ring->reg_idx; + int wait_loop = IXGBE_MAX_RX_DESC_POLL; + u32 rxdctl; + + /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */ + if (hw->mac.type == ixgbe_mac_82598EB && + !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP)) + return; + + do { + msleep(1); + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + } while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE)); + + if (!wait_loop) { + e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within " + "the polling period\n", reg_idx); + } +} + +void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter, + struct ixgbe_ring *ring) +{ + struct ixgbe_hw *hw = &adapter->hw; + u64 rdba = ring->dma; + u32 rxdctl; + u16 reg_idx = ring->reg_idx; + + /* disable queue to avoid issues while updating state */ + rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx)); + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), + rxdctl & ~IXGBE_RXDCTL_ENABLE); + IXGBE_WRITE_FLUSH(hw); + + IXGBE_WRITE_REG(hw, IXGBE_RDBAL(reg_idx), (rdba & DMA_BIT_MASK(32))); + IXGBE_WRITE_REG(hw, IXGBE_RDBAH(reg_idx), (rdba >> 32)); + IXGBE_WRITE_REG(hw, IXGBE_RDLEN(reg_idx), + ring->count * sizeof(union ixgbe_adv_rx_desc)); + IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0); + IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0); + ring->head = IXGBE_RDH(reg_idx); + ring->tail = IXGBE_RDT(reg_idx); + + ixgbe_configure_srrctl(adapter, ring); + ixgbe_configure_rscctl(adapter, ring); + + if (hw->mac.type == ixgbe_mac_82598EB) { + /* + * enable cache line friendly hardware writes: + * PTHRESH=32 descriptors (half the internal cache), + * this also removes ugly rx_no_buffer_count increment + * HTHRESH=4 descriptors (to minimize latency on fetch) + * WTHRESH=8 burst writeback up to two cache lines + */ + rxdctl &= ~0x3FFFFF; + rxdctl |= 0x080420; + } + + /* enable receive descriptor ring */ + rxdctl |= IXGBE_RXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(reg_idx), rxdctl); + + ixgbe_rx_desc_queue_enable(adapter, ring); + ixgbe_alloc_rx_buffers(adapter, ring, IXGBE_DESC_UNUSED(ring)); +} + +static void ixgbe_setup_psrtype(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int p; + + /* PSRTYPE must be initialized in non 82598 adapters */ + u32 psrtype = IXGBE_PSRTYPE_TCPHDR | + IXGBE_PSRTYPE_UDPHDR | + IXGBE_PSRTYPE_IPV4HDR | + IXGBE_PSRTYPE_L2HDR | + IXGBE_PSRTYPE_IPV6HDR; + + if (hw->mac.type == ixgbe_mac_82598EB) + return; + + if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) + psrtype |= (adapter->num_rx_queues_per_pool << 29); + + for (p = 0; p < adapter->num_rx_pools; p++) + IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(adapter->num_vfs + p), + psrtype); +} + +static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 gcr_ext; + u32 vt_reg_bits; + u32 reg_offset, vf_shift; + u32 vmdctl; + + if (!(adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)) + return; + + vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); + vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN | IXGBE_VT_CTL_REPLEN; + vt_reg_bits |= (adapter->num_vfs << IXGBE_VT_CTL_POOL_SHIFT); + IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits); + + vf_shift = adapter->num_vfs % 32; + reg_offset = (adapter->num_vfs > 32) ? 1 : 0; + + /* Enable only the PF's pool for Tx/Rx */ + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift)); + IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset ^ 1), 0); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift)); + IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset ^ 1), 0); + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); + + /* Map PF MAC address in RAR Entry 0 to first pool following VFs */ + hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs); + + /* + * Set up VF register offsets for selected VT Mode, + * i.e. 32 or 64 VFs for SR-IOV + */ + gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); + gcr_ext |= IXGBE_GCR_EXT_MSIX_EN; + gcr_ext |= IXGBE_GCR_EXT_VT_MODE_64; + IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, gcr_ext); + + /* enable Tx loopback for VF/PF communication */ + IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); +} + +static void ixgbe_set_rx_buffer_len(struct ixgbe_adapter *adapter) { - u64 rdba; struct ixgbe_hw *hw = &adapter->hw; - struct ixgbe_ring *rx_ring; struct net_device *netdev = adapter->netdev; int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - int i, j; - u32 rdlen, rxctrl, rxcsum; - static const u32 seed[10] = { 0xE291D73D, 0x1805EC6C, 0x2A94B30D, - 0xA54F2BEC, 0xEA49AF7C, 0xE214AD3D, 0xB855AABE, - 0x6A3E67EA, 0x14364D17, 0x3BED200D}; - u32 fctrl, hlreg0; - u32 reta = 0, mrqc = 0; - u32 rdrxctl; int rx_buf_len; + struct ixgbe_ring *rx_ring; + int i; + u32 mhadd, hlreg0; /* Decide whether to use packet split mode or not */ /* Do not use packet split if we're in SR-IOV Mode */ @@ -2658,62 +2918,40 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) /* Set the RX buffer length according to the mode */ if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { rx_buf_len = IXGBE_RX_HDR_SIZE; - if (hw->mac.type == ixgbe_mac_82599EB) { - /* PSRTYPE must be initialized in 82599 */ - u32 psrtype = IXGBE_PSRTYPE_TCPHDR | - IXGBE_PSRTYPE_UDPHDR | - IXGBE_PSRTYPE_IPV4HDR | - IXGBE_PSRTYPE_IPV6HDR | - IXGBE_PSRTYPE_L2HDR; - IXGBE_WRITE_REG(hw, - IXGBE_PSRTYPE(adapter->num_vfs), - psrtype); - } } else { if (!(adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && (netdev->mtu <= ETH_DATA_LEN)) rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE; else - rx_buf_len = ALIGN(max_frame, 1024); + rx_buf_len = ALIGN(max_frame + VLAN_HLEN, 1024); } - fctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); - fctrl |= IXGBE_FCTRL_BAM; - fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */ - fctrl |= IXGBE_FCTRL_PMCF; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, fctrl); +#ifdef IXGBE_FCOE + /* adjust max frame to be able to do baby jumbo for FCoE */ + if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) && + (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE)) + max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE; + +#endif /* IXGBE_FCOE */ + mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); + if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { + mhadd &= ~IXGBE_MHADD_MFS_MASK; + mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT; + + IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); + } hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0); - if (adapter->netdev->mtu <= ETH_DATA_LEN) - hlreg0 &= ~IXGBE_HLREG0_JUMBOEN; - else - hlreg0 |= IXGBE_HLREG0_JUMBOEN; -#ifdef IXGBE_FCOE - if (netdev->features & NETIF_F_FCOE_MTU) - hlreg0 |= IXGBE_HLREG0_JUMBOEN; -#endif + /* set jumbo enable since MHADD.MFS is keeping size locked at max_frame */ + hlreg0 |= IXGBE_HLREG0_JUMBOEN; IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0); - rdlen = adapter->rx_ring[0]->count * sizeof(union ixgbe_adv_rx_desc); - /* disable receives while setting up the descriptors */ - rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); - IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); - /* * Setup the HW Rx Head and Tail Descriptor Pointers and * the Base and Length of the Rx Descriptor Ring */ for (i = 0; i < adapter->num_rx_queues; i++) { rx_ring = adapter->rx_ring[i]; - rdba = rx_ring->dma; - j = rx_ring->reg_idx; - IXGBE_WRITE_REG(hw, IXGBE_RDBAL(j), (rdba & DMA_BIT_MASK(32))); - IXGBE_WRITE_REG(hw, IXGBE_RDBAH(j), (rdba >> 32)); - IXGBE_WRITE_REG(hw, IXGBE_RDLEN(j), rdlen); - IXGBE_WRITE_REG(hw, IXGBE_RDH(j), 0); - IXGBE_WRITE_REG(hw, IXGBE_RDT(j), 0); - rx_ring->head = IXGBE_RDH(j); - rx_ring->tail = IXGBE_RDT(j); rx_ring->rx_buf_len = rx_buf_len; if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) @@ -2729,15 +2967,21 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) rx_ring->flags &= ~IXGBE_RING_RX_PS_ENABLED; if (rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE) rx_ring->rx_buf_len = - IXGBE_FCOE_JUMBO_FRAME_SIZE; + IXGBE_FCOE_JUMBO_FRAME_SIZE; } } - #endif /* IXGBE_FCOE */ - ixgbe_configure_srrctl(adapter, rx_ring); } - if (hw->mac.type == ixgbe_mac_82598EB) { +} + +static void ixgbe_setup_rdrxctl(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); + + switch (hw->mac.type) { + case ixgbe_mac_82598EB: /* * For VMDq support of different descriptor types or * buffer sizes through the use of multiple SRRCTL @@ -2748,110 +2992,66 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) * effects of setting this bit are only that SRRCTL must be * fully programmed [0..15] */ - rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); rdrxctl |= IXGBE_RDRXCTL_MVMEN; - IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); + break; + case ixgbe_mac_82599EB: + /* Disable RSC for ACK packets */ + IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, + (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); + rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; + /* hardware requires some bits to be set by default */ + rdrxctl |= (IXGBE_RDRXCTL_RSCACKC | IXGBE_RDRXCTL_FCOE_WRFIX); + rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; + break; + default: + /* We should do nothing since we don't know this hardware */ + return; } - if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { - u32 vt_reg_bits; - u32 reg_offset, vf_shift; - u32 vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); - vt_reg_bits = IXGBE_VMD_CTL_VMDQ_EN - | IXGBE_VT_CTL_REPLEN; - vt_reg_bits |= (adapter->num_vfs << - IXGBE_VT_CTL_POOL_SHIFT); - IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl | vt_reg_bits); - IXGBE_WRITE_REG(hw, IXGBE_MRQC, 0); - - vf_shift = adapter->num_vfs % 32; - reg_offset = adapter->num_vfs / 32; - IXGBE_WRITE_REG(hw, IXGBE_VFRE(0), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFRE(1), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(0), 0); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(1), 0); - /* Enable only the PF's pool for Tx/Rx */ - IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), (1 << vf_shift)); - IXGBE_WRITE_REG(hw, IXGBE_VFTE(reg_offset), (1 << vf_shift)); - IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); - ixgbe_set_vmolr(hw, adapter->num_vfs, true); - } - - /* Program MRQC for the distribution of queues */ - mrqc = ixgbe_setup_mrqc(adapter); - - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) { - /* Fill out redirection table */ - for (i = 0, j = 0; i < 128; i++, j++) { - if (j == adapter->ring_feature[RING_F_RSS].indices) - j = 0; - /* reta = 4-byte sliding window of - * 0x00..(indices-1)(indices-1)00..etc. */ - reta = (reta << 8) | (j * 0x11); - if ((i & 3) == 3) - IXGBE_WRITE_REG(hw, IXGBE_RETA(i >> 2), reta); - } - - /* Fill out hash function seeds */ - for (i = 0; i < 10; i++) - IXGBE_WRITE_REG(hw, IXGBE_RSSRK(i), seed[i]); - - if (hw->mac.type == ixgbe_mac_82598EB) - mrqc |= IXGBE_MRQC_RSSEN; - /* Perform hash on these packet types */ - mrqc |= IXGBE_MRQC_RSS_FIELD_IPV4 - | IXGBE_MRQC_RSS_FIELD_IPV4_TCP - | IXGBE_MRQC_RSS_FIELD_IPV6 - | IXGBE_MRQC_RSS_FIELD_IPV6_TCP; - } - IXGBE_WRITE_REG(hw, IXGBE_MRQC, mrqc); + IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); +} - if (adapter->num_vfs) { - u32 reg; +/** + * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset + * @adapter: board private structure + * + * Configure the Rx unit of the MAC after a reset. + **/ +static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int i; + u32 rxctrl; - /* Map PF MAC address in RAR Entry 0 to first pool - * following VFs */ - hw->mac.ops.set_vmdq(hw, 0, adapter->num_vfs); + /* disable receives while setting up the descriptors */ + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); - /* Set up VF register offsets for selected VT Mode, i.e. - * 64 VFs for SR-IOV */ - reg = IXGBE_READ_REG(hw, IXGBE_GCR_EXT); - reg |= IXGBE_GCR_EXT_SRIOV; - IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT, reg); - } + ixgbe_setup_psrtype(adapter); + ixgbe_setup_rdrxctl(adapter); - rxcsum = IXGBE_READ_REG(hw, IXGBE_RXCSUM); + /* Program registers for the distribution of queues */ + ixgbe_setup_mrqc(adapter); - if (adapter->flags & IXGBE_FLAG_RSS_ENABLED || - adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED) { - /* Disable indicating checksum in descriptor, enables - * RSS hash */ - rxcsum |= IXGBE_RXCSUM_PCSD; - } - if (!(rxcsum & IXGBE_RXCSUM_PCSD)) { - /* Enable IPv4 payload checksum for UDP fragments - * if PCSD is not set */ - rxcsum |= IXGBE_RXCSUM_IPPCSE; - } + ixgbe_set_uta(adapter); - IXGBE_WRITE_REG(hw, IXGBE_RXCSUM, rxcsum); + /* set_rx_buffer_len must be called before ring initialization */ + ixgbe_set_rx_buffer_len(adapter); - if (hw->mac.type == ixgbe_mac_82599EB) { - rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL); - rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP; - rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE; - IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl); - } + /* + * Setup the HW Rx Head and Tail Descriptor Pointers and + * the Base and Length of the Rx Descriptor Ring + */ + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_configure_rx_ring(adapter, adapter->rx_ring[i]); - if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { - /* Enable 82599 HW-RSC */ - for (i = 0; i < adapter->num_rx_queues; i++) - ixgbe_configure_rscctl(adapter, i); + /* disable drop enable for 82598 parts */ + if (hw->mac.type == ixgbe_mac_82598EB) + rxctrl |= IXGBE_RXCTRL_DMBYPS; - /* Disable RSC for ACK packets */ - IXGBE_WRITE_REG(hw, IXGBE_RSCDBU, - (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU))); - } + /* enable all receives */ + rxctrl |= IXGBE_RXCTRL_RXEN; + hw->mac.ops.enable_rx_dma(hw, rxctrl); } static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) @@ -2862,6 +3062,7 @@ static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) /* add VID to filter table */ hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, true); + set_bit(vid, adapter->active_vlans); } static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) @@ -2870,16 +3071,9 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) struct ixgbe_hw *hw = &adapter->hw; int pool_ndx = adapter->num_vfs; - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_disable(adapter); - - vlan_group_set_device(adapter->vlgrp, vid, NULL); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter); - /* remove VID from filter table */ hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false); + clear_bit(vid, adapter->active_vlans); } /** @@ -2889,27 +3083,45 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + u32 vlnctrl; + + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN); + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); +} + +/** + * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering + * @adapter: driver data + */ +static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl; + + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl |= IXGBE_VLNCTRL_VFE; + vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; + IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); +} + +/** + * ixgbe_vlan_strip_disable - helper to disable hw vlan stripping + * @adapter: driver data + */ +static void ixgbe_vlan_strip_disable(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + u32 vlnctrl; int i, j; switch (hw->mac.type) { case ixgbe_mac_82598EB: - vlnctrl &= ~IXGBE_VLNCTRL_VFE; -#ifdef CONFIG_IXGBE_DCB - if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) - vlnctrl &= ~IXGBE_VLNCTRL_VME; -#endif - vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl &= ~IXGBE_VLNCTRL_VME; IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: - vlnctrl &= ~IXGBE_VLNCTRL_VFE; - vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; - IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); -#ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) - break; -#endif for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i]->reg_idx; vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -2923,25 +3135,22 @@ static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter) } /** - * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering + * ixgbe_vlan_strip_enable - helper to enable hw vlan stripping * @adapter: driver data */ -static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) +static void ixgbe_vlan_strip_enable(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - u32 vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + u32 vlnctrl; int i, j; switch (hw->mac.type) { case ixgbe_mac_82598EB: - vlnctrl |= IXGBE_VLNCTRL_VME | IXGBE_VLNCTRL_VFE; - vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; + vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); + vlnctrl |= IXGBE_VLNCTRL_VME; IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); break; case ixgbe_mac_82599EB: - vlnctrl |= IXGBE_VLNCTRL_VFE; - vlnctrl &= ~IXGBE_VLNCTRL_CFIEN; - IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); for (i = 0; i < adapter->num_rx_queues; i++) { j = adapter->rx_ring[i]->reg_idx; vlnctrl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); @@ -2954,40 +3163,14 @@ static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter) } } -static void ixgbe_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) -{ - struct ixgbe_adapter *adapter = netdev_priv(netdev); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_disable(adapter); - adapter->vlgrp = grp; - - /* - * For a DCB driver, always enable VLAN tag stripping so we can - * still receive traffic from a DCB-enabled host even if we're - * not in DCB mode. - */ - ixgbe_vlan_filter_enable(adapter); - - ixgbe_vlan_rx_add_vid(netdev, 0); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - ixgbe_irq_enable(adapter); -} - static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) { - ixgbe_vlan_rx_register(adapter->netdev, adapter->vlgrp); + u16 vid; - if (adapter->vlgrp) { - u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { - if (!vlan_group_get_device(adapter->vlgrp, vid)) - continue; - ixgbe_vlan_rx_add_vid(adapter->netdev, vid); - } - } + ixgbe_vlan_rx_add_vid(adapter->netdev, 0); + + for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) + ixgbe_vlan_rx_add_vid(adapter->netdev, vid); } /** @@ -3052,6 +3235,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev) fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + /* set all bits that we expect to always be set */ + fctrl |= IXGBE_FCTRL_BAM; + fctrl |= IXGBE_FCTRL_DPF; /* discard pause frames when FC enabled */ + fctrl |= IXGBE_FCTRL_PMCF; + /* clear the bits we are changing the status of */ fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); @@ -3097,6 +3285,11 @@ void ixgbe_set_rx_mode(struct net_device *netdev) } IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); + + if (netdev->features & NETIF_F_HW_VLAN_RX) + ixgbe_vlan_strip_enable(adapter); + else + ixgbe_vlan_strip_disable(adapter); } static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) @@ -3157,7 +3350,15 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) u32 txdctl; int i, j; - ixgbe_dcb_check_config(&adapter->dcb_cfg); + if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED)) { + if (hw->mac.type == ixgbe_mac_82598EB) + netif_set_gso_max_size(adapter->netdev, 65536); + return; + } + + if (hw->mac.type == ixgbe_mac_82598EB) + netif_set_gso_max_size(adapter->netdev, 32768); + ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_TX_CONFIG); ixgbe_dcb_calculate_tc_credits(&adapter->dcb_cfg, DCB_RX_CONFIG); @@ -3172,7 +3373,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); } /* Enable VLAN tag insert/strip */ - ixgbe_vlan_filter_enable(adapter); + adapter->netdev->features |= NETIF_F_HW_VLAN_RX; hw->mac.ops.set_vfta(&adapter->hw, 0, 0, true); } @@ -3184,23 +3385,13 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; int i; - ixgbe_set_rx_mode(netdev); - - ixgbe_restore_vlan(adapter); #ifdef CONFIG_IXGBE_DCB - if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { - if (hw->mac.type == ixgbe_mac_82598EB) - netif_set_gso_max_size(netdev, 32768); - else - netif_set_gso_max_size(netdev, 65536); - ixgbe_configure_dcb(adapter); - } else { - netif_set_gso_max_size(netdev, 65536); - } -#else - netif_set_gso_max_size(netdev, 65536); + ixgbe_configure_dcb(adapter); #endif + ixgbe_set_rx_mode(netdev); + ixgbe_restore_vlan(adapter); + #ifdef IXGBE_FCOE if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) ixgbe_configure_fcoe(adapter); @@ -3209,17 +3400,15 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) { for (i = 0; i < adapter->num_tx_queues; i++) adapter->tx_ring[i]->atr_sample_rate = - adapter->atr_sample_rate; + adapter->atr_sample_rate; ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc); } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) { ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc); } + ixgbe_configure_virtualization(adapter); ixgbe_configure_tx(adapter); ixgbe_configure_rx(adapter); - for (i = 0; i < adapter->num_rx_queues; i++) - ixgbe_alloc_rx_buffers(adapter, adapter->rx_ring[i], - (adapter->rx_ring[i]->count - 1)); } static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw) @@ -3290,7 +3479,8 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw) goto link_cfg_out; if (hw->mac.ops.get_link_capabilities) - ret = hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation); + ret = hw->mac.ops.get_link_capabilities(hw, &autoneg, + &negotiation); if (ret) goto link_cfg_out; @@ -3300,62 +3490,15 @@ static int ixgbe_non_sfp_link_config(struct ixgbe_hw *hw) return ret; } -#define IXGBE_MAX_RX_DESC_POLL 10 -static inline void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter, - int rxr) -{ - int j = adapter->rx_ring[rxr]->reg_idx; - int k; - - for (k = 0; k < IXGBE_MAX_RX_DESC_POLL; k++) { - if (IXGBE_READ_REG(&adapter->hw, - IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE) - break; - else - msleep(1); - } - if (k >= IXGBE_MAX_RX_DESC_POLL) { - e_err(drv, "RXDCTL.ENABLE on Rx queue %d not set within " - "the polling period\n", rxr); - } - ixgbe_release_rx_desc(&adapter->hw, adapter->rx_ring[rxr], - (adapter->rx_ring[rxr]->count - 1)); -} - -static int ixgbe_up_complete(struct ixgbe_adapter *adapter) +static void ixgbe_setup_gpie(struct ixgbe_adapter *adapter) { - struct net_device *netdev = adapter->netdev; struct ixgbe_hw *hw = &adapter->hw; - int i, j = 0; - int num_rx_rings = adapter->num_rx_queues; - int err; - int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; - u32 txdctl, rxdctl, mhadd; - u32 dmatxctl; - u32 gpie; - u32 ctrl_ext; - - ixgbe_get_hw_control(adapter); - - if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) || - (adapter->flags & IXGBE_FLAG_MSI_ENABLED)) { - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME | - IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD); - } else { - /* MSI only */ - gpie = 0; - } - if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { - gpie &= ~IXGBE_GPIE_VTMODE_MASK; - gpie |= IXGBE_GPIE_VTMODE_64; - } - /* XXX: to interrupt immediately for EICS writes, enable this */ - /* gpie |= IXGBE_GPIE_EIMEN; */ - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - } + u32 gpie = 0; if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + gpie = IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_PBA_SUPPORT | + IXGBE_GPIE_OCD; + gpie |= IXGBE_GPIE_EIAME; /* * use EIAM to auto-mask when MSI-X interrupt is asserted * this saves a register write for every interrupt @@ -3376,98 +3519,33 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE); } - /* Enable Thermal over heat sensor interrupt */ - if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) { - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); - gpie |= IXGBE_SDP0_GPIEN; - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); + /* XXX: to interrupt immediately for EICS writes, enable this */ + /* gpie |= IXGBE_GPIE_EIMEN; */ + + if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) { + gpie &= ~IXGBE_GPIE_VTMODE_MASK; + gpie |= IXGBE_GPIE_VTMODE_64; } - /* Enable fan failure interrupt if media type is copper */ - if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) { - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); + /* Enable fan failure interrupt */ + if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) gpie |= IXGBE_SDP1_GPIEN; - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - } - if (hw->mac.type == ixgbe_mac_82599EB) { - gpie = IXGBE_READ_REG(hw, IXGBE_GPIE); + if (hw->mac.type == ixgbe_mac_82599EB) gpie |= IXGBE_SDP1_GPIEN; gpie |= IXGBE_SDP2_GPIEN; - IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); - } - -#ifdef IXGBE_FCOE - /* adjust max frame to be able to do baby jumbo for FCoE */ - if ((netdev->features & NETIF_F_FCOE_MTU) && - (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE)) - max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE; - -#endif /* IXGBE_FCOE */ - mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD); - if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) { - mhadd &= ~IXGBE_MHADD_MFS_MASK; - mhadd |= max_frame << IXGBE_MHADD_MFS_SHIFT; - IXGBE_WRITE_REG(hw, IXGBE_MHADD, mhadd); - } - - for (i = 0; i < adapter->num_tx_queues; i++) { - j = adapter->tx_ring[i]->reg_idx; - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); - if (adapter->rx_itr_setting == 0) { - /* cannot set wthresh when itr==0 */ - txdctl &= ~0x007F0000; - } else { - /* enable WTHRESH=8 descriptors, to encourage burst writeback */ - txdctl |= (8 << 16); - } - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); - } + IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie); +} - if (hw->mac.type == ixgbe_mac_82599EB) { - /* DMATXCTL.EN must be set after all Tx queue config is done */ - dmatxctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); - dmatxctl |= IXGBE_DMATXCTL_TE; - IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, dmatxctl); - } - for (i = 0; i < adapter->num_tx_queues; i++) { - j = adapter->tx_ring[i]->reg_idx; - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); - txdctl |= IXGBE_TXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), txdctl); - if (hw->mac.type == ixgbe_mac_82599EB) { - int wait_loop = 10; - /* poll for Tx Enable ready */ - do { - msleep(1); - txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); - } while (--wait_loop && - !(txdctl & IXGBE_TXDCTL_ENABLE)); - if (!wait_loop) - e_err(drv, "Could not enable Tx Queue %d\n", j); - } - } +static int ixgbe_up_complete(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + int err; + u32 ctrl_ext; - for (i = 0; i < num_rx_rings; i++) { - j = adapter->rx_ring[i]->reg_idx; - rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(j)); - /* enable PTHRESH=32 descriptors (half the internal cache) - * and HTHRESH=0 descriptors (to minimize latency on fetch), - * this also removes a pesky rx_no_buffer_count increment */ - rxdctl |= 0x0020; - rxdctl |= IXGBE_RXDCTL_ENABLE; - IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(j), rxdctl); - if (hw->mac.type == ixgbe_mac_82599EB) - ixgbe_rx_desc_queue_enable(adapter, i); - } - /* enable all receives */ - rxdctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); - if (hw->mac.type == ixgbe_mac_82598EB) - rxdctl |= (IXGBE_RXCTRL_DMBYPS | IXGBE_RXCTRL_RXEN); - else - rxdctl |= IXGBE_RXCTRL_RXEN; - hw->mac.ops.enable_rx_dma(hw, rxdctl); + ixgbe_get_hw_control(adapter); + ixgbe_setup_gpie(adapter); if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) ixgbe_configure_msix(adapter); @@ -3483,8 +3561,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) /* clear any pending interrupts, may auto mask */ IXGBE_READ_REG(hw, IXGBE_EICR); - - ixgbe_irq_enable(adapter); + ixgbe_irq_enable(adapter, true, true); /* * If this adapter has a fan, check to see if we had a failure @@ -3525,12 +3602,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) e_err(probe, "link_config FAILED %d\n", err); } - for (i = 0; i < adapter->num_tx_queues; i++) - set_bit(__IXGBE_FDIR_INIT_DONE, - &(adapter->tx_ring[i]->reinit_state)); - /* enable transmits */ - netif_tx_start_all_queues(netdev); + netif_tx_start_all_queues(adapter->netdev); /* bring the link up in the watchdog, this could race with our first * link up interrupt but shouldn't be a problem */ @@ -3609,21 +3682,24 @@ void ixgbe_reset(struct ixgbe_adapter *adapter) * @rx_ring: ring to free buffers from **/ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; unsigned long size; unsigned int i; - /* Free all the Rx ring sk_buffs */ + /* ring already cleared, nothing to do */ + if (!rx_ring->rx_buffer_info) + return; + /* Free all the Rx ring sk_buffs */ for (i = 0; i < rx_ring->count; i++) { struct ixgbe_rx_buffer *rx_buffer_info; rx_buffer_info = &rx_ring->rx_buffer_info[i]; if (rx_buffer_info->dma) { dma_unmap_single(&pdev->dev, rx_buffer_info->dma, - rx_ring->rx_buf_len, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); rx_buffer_info->dma = 0; } @@ -3635,7 +3711,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, if (IXGBE_RSC_CB(this)->delay_unmap) { dma_unmap_single(&pdev->dev, IXGBE_RSC_CB(this)->dma, - rx_ring->rx_buf_len, + rx_ring->rx_buf_len, DMA_FROM_DEVICE); IXGBE_RSC_CB(this)->dma = 0; IXGBE_RSC_CB(skb)->delay_unmap = false; @@ -3677,14 +3753,17 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, * @tx_ring: ring to be cleaned **/ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct ixgbe_tx_buffer *tx_buffer_info; unsigned long size; unsigned int i; - /* Free all the Tx ring sk_buffs */ + /* ring already cleared, nothing to do */ + if (!tx_ring->tx_buffer_info) + return; + /* Free all the Tx ring sk_buffs */ for (i = 0; i < tx_ring->count; i++) { tx_buffer_info = &tx_ring->tx_buffer_info[i]; ixgbe_unmap_and_free_tx_resource(adapter, tx_buffer_info); @@ -3736,6 +3815,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) u32 rxctrl; u32 txdctl; int i, j; + int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; /* signal that we are down to the interrupt handler */ set_bit(__IXGBE_DOWN, &adapter->state); @@ -3774,6 +3854,15 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ixgbe_napi_disable_all(adapter); + /* Cleanup the affinity_hint CPU mask memory and callback */ + for (i = 0; i < num_q_vectors; i++) { + struct ixgbe_q_vector *q_vector = adapter->q_vector[i]; + /* clear the affinity_mask in the IRQ descriptor */ + irq_set_affinity_hint(adapter->msix_entries[i]. vector, NULL); + /* release the CPU mask memory */ + free_cpumask_var(q_vector->affinity_mask); + } + if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE || adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) cancel_work_sync(&adapter->fdir_reinit_task); @@ -3786,13 +3875,13 @@ void ixgbe_down(struct ixgbe_adapter *adapter) j = adapter->tx_ring[i]->reg_idx; txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), - (txdctl & ~IXGBE_TXDCTL_ENABLE)); + (txdctl & ~IXGBE_TXDCTL_ENABLE)); } /* Disable the Tx DMA engine on 82599 */ if (hw->mac.type == ixgbe_mac_82599EB) IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, - (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & - ~IXGBE_DMATXCTL_TE)); + (IXGBE_READ_REG(hw, IXGBE_DMATXCTL) & + ~IXGBE_DMATXCTL_TE)); /* power down the optics */ if (hw->phy.multispeed_fiber) @@ -3822,7 +3911,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter) static int ixgbe_poll(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; int tx_clean_complete, work_done = 0; @@ -3932,7 +4021,7 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter) * Rx load across CPUs using RSS. * **/ -static bool inline ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter) +static inline bool ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter) { bool ret = false; struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR]; @@ -4024,7 +4113,7 @@ static inline bool ixgbe_set_sriov_queues(struct ixgbe_adapter *adapter) * fallthrough conditions. * **/ -static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) +static int ixgbe_set_num_queues(struct ixgbe_adapter *adapter) { /* Start with base case */ adapter->num_rx_queues = 1; @@ -4033,7 +4122,7 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) adapter->num_rx_queues_per_pool = 1; if (ixgbe_set_sriov_queues(adapter)) - return; + goto done; #ifdef IXGBE_FCOE if (ixgbe_set_fcoe_queues(adapter)) @@ -4056,12 +4145,14 @@ static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) adapter->num_tx_queues = 1; done: - /* Notify the stack of the (possibly) reduced Tx Queue count. */ + /* Notify the stack of the (possibly) reduced queue counts. */ netif_set_real_num_tx_queues(adapter->netdev, adapter->num_tx_queues); + return netif_set_real_num_rx_queues(adapter->netdev, + adapter->num_rx_queues); } static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, - int vectors) + int vectors) { int err, vector_threshold; @@ -4080,7 +4171,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, */ while (vectors >= vector_threshold) { err = pci_enable_msix(adapter->pdev, adapter->msix_entries, - vectors); + vectors); if (!err) /* Success in acquiring all requested vectors. */ break; else if (err < 0) @@ -4107,7 +4198,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, * vectors we were allocated. */ adapter->num_msix_vectors = min(vectors, - adapter->max_msix_q_vectors + NON_Q_VECTORS); + adapter->max_msix_q_vectors + NON_Q_VECTORS); } } @@ -4178,12 +4269,12 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) } for ( ; i < 5; i++) { adapter->tx_ring[i]->reg_idx = - ((i + 2) << 4); + ((i + 2) << 4); adapter->rx_ring[i]->reg_idx = i << 4; } for ( ; i < dcb_i; i++) { adapter->tx_ring[i]->reg_idx = - ((i + 8) << 3); + ((i + 8) << 3); adapter->rx_ring[i]->reg_idx = i << 4; } @@ -4226,7 +4317,7 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter) * Cache the descriptor ring offsets for Flow Director to the assigned rings. * **/ -static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) +static inline bool ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter) { int i; bool ret = false; @@ -4383,7 +4474,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) adapter->node = cur_node; } ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL, - adapter->node); + adapter->node); if (!ring) ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); if (!ring) @@ -4407,7 +4498,7 @@ static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter) adapter->node = cur_node; } ring = kzalloc_node(sizeof(struct ixgbe_ring), GFP_KERNEL, - adapter->node); + adapter->node); if (!ring) ring = kzalloc(sizeof(struct ixgbe_ring), GFP_KERNEL); if (!ring) @@ -4453,7 +4544,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) * (roughly) the same number of vectors as there are CPU's. */ v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues, - (int)num_online_cpus()) + NON_Q_VECTORS; + (int)num_online_cpus()) + NON_Q_VECTORS; /* * At the same time, hardware can only support a maximum of @@ -4467,7 +4558,7 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) /* A failure in MSI-X entry allocation isn't fatal, but it does * mean we disable MSI-X capabilities of the adapter. */ adapter->msix_entries = kcalloc(v_budget, - sizeof(struct msix_entry), GFP_KERNEL); + sizeof(struct msix_entry), GFP_KERNEL); if (adapter->msix_entries) { for (vector = 0; vector < v_budget; vector++) adapter->msix_entries[vector].entry = vector; @@ -4486,7 +4577,9 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter) if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) ixgbe_disable_sriov(adapter); - ixgbe_set_num_queues(adapter); + err = ixgbe_set_num_queues(adapter); + if (err) + return err; err = pci_enable_msi(adapter->pdev); if (!err) { @@ -4529,10 +4622,10 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter) for (q_idx = 0; q_idx < num_q_vectors; q_idx++) { q_vector = kzalloc_node(sizeof(struct ixgbe_q_vector), - GFP_KERNEL, adapter->node); + GFP_KERNEL, adapter->node); if (!q_vector) q_vector = kzalloc(sizeof(struct ixgbe_q_vector), - GFP_KERNEL); + GFP_KERNEL); if (!q_vector) goto err_out; q_vector->adapter = adapter; @@ -4611,7 +4704,9 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter) int err; /* Number of supported queues */ - ixgbe_set_num_queues(adapter); + err = ixgbe_set_num_queues(adapter); + if (err) + return err; err = ixgbe_set_interrupt_capability(adapter); if (err) { @@ -4693,8 +4788,8 @@ static void ixgbe_sfp_timer(unsigned long data) static void ixgbe_sfp_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - sfp_task); + struct ixgbe_adapter, + sfp_task); struct ixgbe_hw *hw = &adapter->hw; if ((hw->phy.type == ixgbe_phy_nl) && @@ -4719,7 +4814,7 @@ static void ixgbe_sfp_task(struct work_struct *work) reschedule: if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state)) mod_timer(&adapter->sfp_timer, - round_jiffies(jiffies + (2 * HZ))); + round_jiffies(jiffies + (2 * HZ))); } /** @@ -4775,7 +4870,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->atr_sample_rate = 20; } adapter->ring_feature[RING_F_FDIR].indices = - IXGBE_MAX_FDIR_INDICES; + IXGBE_MAX_FDIR_INDICES; adapter->fdir_pballoc = 0; #ifdef IXGBE_FCOE adapter->flags |= IXGBE_FLAG_FCOE_CAPABLE; @@ -4806,7 +4901,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) adapter->dcb_cfg.round_robin_enable = false; adapter->dcb_set_bitmap = 0x00; ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg, - adapter->ring_feature[RING_F_DCB].indices); + adapter->ring_feature[RING_F_DCB].indices); #endif @@ -4861,7 +4956,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) * Return 0 on success, negative on failure **/ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct pci_dev *pdev = adapter->pdev; int size; @@ -4928,7 +5023,7 @@ static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) * Returns 0 on success, negative on failure **/ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; int size; @@ -5001,7 +5096,7 @@ static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) * Free all transmit software resources **/ void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct pci_dev *pdev = adapter->pdev; @@ -5039,7 +5134,7 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter) * Free all receive software resources **/ void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; @@ -5333,6 +5428,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) u64 total_mpc = 0; u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot; u64 non_eop_descs = 0, restart_queue = 0; + struct ixgbe_hw_stats *hwstats = &adapter->stats; if (test_bit(__IXGBE_DOWN, &adapter->state) || test_bit(__IXGBE_RESETTING, &adapter->state)) @@ -5343,7 +5439,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) u64 rsc_flush = 0; for (i = 0; i < 16; i++) adapter->hw_rx_no_dma_resources += - IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); for (i = 0; i < adapter->num_rx_queues; i++) { rsc_count += adapter->rx_ring[i]->rsc_count; rsc_flush += adapter->rx_ring[i]->rsc_flush; @@ -5361,119 +5457,118 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) non_eop_descs += adapter->rx_ring[i]->non_eop_descs; adapter->non_eop_descs = non_eop_descs; - adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); + hwstats->crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS); for (i = 0; i < 8; i++) { /* for packet buffers not used, the register should read 0 */ mpc = IXGBE_READ_REG(hw, IXGBE_MPC(i)); missed_rx += mpc; - adapter->stats.mpc[i] += mpc; - total_mpc += adapter->stats.mpc[i]; + hwstats->mpc[i] += mpc; + total_mpc += hwstats->mpc[i]; if (hw->mac.type == ixgbe_mac_82598EB) - adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i)); - adapter->stats.qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); - adapter->stats.qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i)); - adapter->stats.qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); - adapter->stats.qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); + hwstats->rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i)); + hwstats->qptc[i] += IXGBE_READ_REG(hw, IXGBE_QPTC(i)); + hwstats->qbtc[i] += IXGBE_READ_REG(hw, IXGBE_QBTC(i)); + hwstats->qprc[i] += IXGBE_READ_REG(hw, IXGBE_QPRC(i)); + hwstats->qbrc[i] += IXGBE_READ_REG(hw, IXGBE_QBRC(i)); if (hw->mac.type == ixgbe_mac_82599EB) { - adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONRXCNT(i)); - adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFRXCNT(i)); - adapter->stats.qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); + hwstats->pxonrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXONRXCNT(i)); + hwstats->pxoffrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(i)); + hwstats->qprdc[i] += IXGBE_READ_REG(hw, IXGBE_QPRDC(i)); } else { - adapter->stats.pxonrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONRXC(i)); - adapter->stats.pxoffrxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFRXC(i)); + hwstats->pxonrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXONRXC(i)); + hwstats->pxoffrxc[i] += + IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(i)); } - adapter->stats.pxontxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXONTXC(i)); - adapter->stats.pxofftxc[i] += IXGBE_READ_REG(hw, - IXGBE_PXOFFTXC(i)); + hwstats->pxontxc[i] += IXGBE_READ_REG(hw, IXGBE_PXONTXC(i)); + hwstats->pxofftxc[i] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(i)); } - adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); + hwstats->gprc += IXGBE_READ_REG(hw, IXGBE_GPRC); /* work around hardware counting issue */ - adapter->stats.gprc -= missed_rx; + hwstats->gprc -= missed_rx; /* 82598 hardware only has a 32 bit counter in the high register */ if (hw->mac.type == ixgbe_mac_82599EB) { u64 tmp; - adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); - tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; /* 4 high bits of GORC */ - adapter->stats.gorc += (tmp << 32); - adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); - tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; /* 4 high bits of GOTC */ - adapter->stats.gotc += (tmp << 32); - adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORL); - IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ - adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); - adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); - adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); - adapter->stats.fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); + hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL); + tmp = IXGBE_READ_REG(hw, IXGBE_GORCH) & 0xF; + /* 4 high bits of GORC */ + hwstats->gorc += (tmp << 32); + hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL); + tmp = IXGBE_READ_REG(hw, IXGBE_GOTCH) & 0xF; + /* 4 high bits of GOTC */ + hwstats->gotc += (tmp << 32); + hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORL); + IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */ + hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT); + hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT); + hwstats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH); + hwstats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS); #ifdef IXGBE_FCOE - adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); - adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); - adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); - adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); - adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); - adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); + hwstats->fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC); + hwstats->fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC); + hwstats->fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC); + hwstats->fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC); + hwstats->fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC); + hwstats->fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC); #endif /* IXGBE_FCOE */ } else { - adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); - adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); - adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); - adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); - adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH); + hwstats->lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC); + hwstats->lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC); + hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCH); + hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH); + hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH); } bprc = IXGBE_READ_REG(hw, IXGBE_BPRC); - adapter->stats.bprc += bprc; - adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC); + hwstats->bprc += bprc; + hwstats->mprc += IXGBE_READ_REG(hw, IXGBE_MPRC); if (hw->mac.type == ixgbe_mac_82598EB) - adapter->stats.mprc -= bprc; - adapter->stats.roc += IXGBE_READ_REG(hw, IXGBE_ROC); - adapter->stats.prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64); - adapter->stats.prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127); - adapter->stats.prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255); - adapter->stats.prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511); - adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023); - adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); - adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); + hwstats->mprc -= bprc; + hwstats->roc += IXGBE_READ_REG(hw, IXGBE_ROC); + hwstats->prc64 += IXGBE_READ_REG(hw, IXGBE_PRC64); + hwstats->prc127 += IXGBE_READ_REG(hw, IXGBE_PRC127); + hwstats->prc255 += IXGBE_READ_REG(hw, IXGBE_PRC255); + hwstats->prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511); + hwstats->prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023); + hwstats->prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522); + hwstats->rlec += IXGBE_READ_REG(hw, IXGBE_RLEC); lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC); - adapter->stats.lxontxc += lxon; + hwstats->lxontxc += lxon; lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC); - adapter->stats.lxofftxc += lxoff; - adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC); - adapter->stats.gptc += IXGBE_READ_REG(hw, IXGBE_GPTC); - adapter->stats.mptc += IXGBE_READ_REG(hw, IXGBE_MPTC); + hwstats->lxofftxc += lxoff; + hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC); + hwstats->gptc += IXGBE_READ_REG(hw, IXGBE_GPTC); + hwstats->mptc += IXGBE_READ_REG(hw, IXGBE_MPTC); /* * 82598 errata - tx of flow control packets is included in tx counters */ xon_off_tot = lxon + lxoff; - adapter->stats.gptc -= xon_off_tot; - adapter->stats.mptc -= xon_off_tot; - adapter->stats.gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN)); - adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC); - adapter->stats.rfc += IXGBE_READ_REG(hw, IXGBE_RFC); - adapter->stats.rjc += IXGBE_READ_REG(hw, IXGBE_RJC); - adapter->stats.tpr += IXGBE_READ_REG(hw, IXGBE_TPR); - adapter->stats.ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64); - adapter->stats.ptc64 -= xon_off_tot; - adapter->stats.ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127); - adapter->stats.ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255); - adapter->stats.ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511); - adapter->stats.ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023); - adapter->stats.ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522); - adapter->stats.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC); + hwstats->gptc -= xon_off_tot; + hwstats->mptc -= xon_off_tot; + hwstats->gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN)); + hwstats->ruc += IXGBE_READ_REG(hw, IXGBE_RUC); + hwstats->rfc += IXGBE_READ_REG(hw, IXGBE_RFC); + hwstats->rjc += IXGBE_READ_REG(hw, IXGBE_RJC); + hwstats->tpr += IXGBE_READ_REG(hw, IXGBE_TPR); + hwstats->ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64); + hwstats->ptc64 -= xon_off_tot; + hwstats->ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127); + hwstats->ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255); + hwstats->ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511); + hwstats->ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023); + hwstats->ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522); + hwstats->bptc += IXGBE_READ_REG(hw, IXGBE_BPTC); /* Fill out the OS statistics structure */ - netdev->stats.multicast = adapter->stats.mprc; + netdev->stats.multicast = hwstats->mprc; /* Rx Errors */ - netdev->stats.rx_errors = adapter->stats.crcerrs + - adapter->stats.rlec; + netdev->stats.rx_errors = hwstats->crcerrs + hwstats->rlec; netdev->stats.rx_dropped = 0; - netdev->stats.rx_length_errors = adapter->stats.rlec; - netdev->stats.rx_crc_errors = adapter->stats.crcerrs; + netdev->stats.rx_length_errors = hwstats->rlec; + netdev->stats.rx_crc_errors = hwstats->crcerrs; netdev->stats.rx_missed_errors = total_mpc; } @@ -5532,8 +5627,8 @@ static void ixgbe_watchdog(unsigned long data) static void ixgbe_multispeed_fiber_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - multispeed_fiber_task); + struct ixgbe_adapter, + multispeed_fiber_task); struct ixgbe_hw *hw = &adapter->hw; u32 autoneg; bool negotiation; @@ -5556,8 +5651,8 @@ static void ixgbe_multispeed_fiber_task(struct work_struct *work) static void ixgbe_sfp_config_module_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - sfp_config_module_task); + struct ixgbe_adapter, + sfp_config_module_task); struct ixgbe_hw *hw = &adapter->hw; u32 err; @@ -5590,15 +5685,15 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work) static void ixgbe_fdir_reinit_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - fdir_reinit_task); + struct ixgbe_adapter, + fdir_reinit_task); struct ixgbe_hw *hw = &adapter->hw; int i; if (ixgbe_reinit_fdir_tables_82599(hw) == 0) { for (i = 0; i < adapter->num_tx_queues; i++) set_bit(__IXGBE_FDIR_INIT_DONE, - &(adapter->tx_ring[i]->reinit_state)); + &(adapter->tx_ring[i]->reinit_state)); } else { e_err(probe, "failed to finish FDIR re-initialization, " "ignored adding FDIR ATR filters\n"); @@ -5616,8 +5711,8 @@ static DEFINE_MUTEX(ixgbe_watchdog_lock); static void ixgbe_watchdog_task(struct work_struct *work) { struct ixgbe_adapter *adapter = container_of(work, - struct ixgbe_adapter, - watchdog_task); + struct ixgbe_adapter, + watchdog_task); struct net_device *netdev = adapter->netdev; struct ixgbe_hw *hw = &adapter->hw; u32 link_speed; @@ -5648,7 +5743,7 @@ static void ixgbe_watchdog_task(struct work_struct *work) if (link_up || time_after(jiffies, (adapter->link_check_timeout + - IXGBE_TRY_LINK_TIMEOUT))) { + IXGBE_TRY_LINK_TIMEOUT))) { adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC); } @@ -5719,8 +5814,8 @@ static void ixgbe_watchdog_task(struct work_struct *work) } static int ixgbe_tso(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, struct sk_buff *skb, - u32 tx_flags, u8 *hdr_len) + struct ixgbe_ring *tx_ring, struct sk_buff *skb, + u32 tx_flags, u8 *hdr_len) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -5743,28 +5838,28 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, iph->tot_len = 0; iph->check = 0; tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, - iph->daddr, 0, - IPPROTO_TCP, - 0); + iph->daddr, 0, + IPPROTO_TCP, + 0); } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0); + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0); } i = tx_ring->next_to_use; tx_buffer_info = &tx_ring->tx_buffer_info[i]; - context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i); + context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); /* VLAN MACLEN IPLEN */ if (tx_flags & IXGBE_TX_FLAGS_VLAN) vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); vlan_macip_lens |= ((skb_network_offset(skb)) << - IXGBE_ADVTXD_MACLEN_SHIFT); + IXGBE_ADVTXD_MACLEN_SHIFT); *hdr_len += skb_network_offset(skb); vlan_macip_lens |= (skb_transport_header(skb) - skb_network_header(skb)); @@ -5775,7 +5870,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */ type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT | - IXGBE_ADVTXD_DTYP_CTXT); + IXGBE_ADVTXD_DTYP_CTXT); if (skb->protocol == htons(ETH_P_IP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; @@ -5803,9 +5898,53 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, return false; } +static u32 ixgbe_psum(struct ixgbe_adapter *adapter, struct sk_buff *skb) +{ + u32 rtn = 0; + __be16 protocol; + + if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) + protocol = ((const struct vlan_ethhdr *)skb->data)-> + h_vlan_encapsulated_proto; + else + protocol = skb->protocol; + + switch (protocol) { + case cpu_to_be16(ETH_P_IP): + rtn |= IXGBE_ADVTXD_TUCMD_IPV4; + switch (ip_hdr(skb)->protocol) { + case IPPROTO_TCP: + rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + break; + case IPPROTO_SCTP: + rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + break; + } + break; + case cpu_to_be16(ETH_P_IPV6): + /* XXX what about other V6 headers?? */ + switch (ipv6_hdr(skb)->nexthdr) { + case IPPROTO_TCP: + rtn |= IXGBE_ADVTXD_TUCMD_L4T_TCP; + break; + case IPPROTO_SCTP: + rtn |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; + break; + } + break; + default: + if (unlikely(net_ratelimit())) + e_warn(probe, "partial checksum but proto=%x!\n", + skb->protocol); + break; + } + + return rtn; +} + static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags) + struct ixgbe_ring *tx_ring, + struct sk_buff *skb, u32 tx_flags) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -5816,63 +5955,25 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, (tx_flags & IXGBE_TX_FLAGS_VLAN)) { i = tx_ring->next_to_use; tx_buffer_info = &tx_ring->tx_buffer_info[i]; - context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i); + context_desc = IXGBE_TX_CTXTDESC_ADV(tx_ring, i); if (tx_flags & IXGBE_TX_FLAGS_VLAN) vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); vlan_macip_lens |= (skb_network_offset(skb) << - IXGBE_ADVTXD_MACLEN_SHIFT); + IXGBE_ADVTXD_MACLEN_SHIFT); if (skb->ip_summed == CHECKSUM_PARTIAL) vlan_macip_lens |= (skb_transport_header(skb) - - skb_network_header(skb)); + skb_network_header(skb)); context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); context_desc->seqnum_seed = 0; type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT | - IXGBE_ADVTXD_DTYP_CTXT); - - if (skb->ip_summed == CHECKSUM_PARTIAL) { - __be16 protocol; - - if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { - const struct vlan_ethhdr *vhdr = - (const struct vlan_ethhdr *)skb->data; - - protocol = vhdr->h_vlan_encapsulated_proto; - } else { - protocol = skb->protocol; - } + IXGBE_ADVTXD_DTYP_CTXT); - switch (protocol) { - case cpu_to_be16(ETH_P_IP): - type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; - if (ip_hdr(skb)->protocol == IPPROTO_TCP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; - else if (ip_hdr(skb)->protocol == IPPROTO_SCTP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_SCTP; - break; - case cpu_to_be16(ETH_P_IPV6): - /* XXX what about other V6 headers?? */ - if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; - else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP) - type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_SCTP; - break; - default: - if (unlikely(net_ratelimit())) { - e_warn(probe, "partial checksum " - "but proto=%x!\n", - skb->protocol); - } - break; - } - } + if (skb->ip_summed == CHECKSUM_PARTIAL) + type_tucmd_mlhl |= ixgbe_psum(adapter, skb); context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); /* use index zero for tx checksum offload */ @@ -5893,9 +5994,9 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, } static int ixgbe_tx_map(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags, - unsigned int first) + struct ixgbe_ring *tx_ring, + struct sk_buff *skb, u32 tx_flags, + unsigned int first) { struct pci_dev *pdev = adapter->pdev; struct ixgbe_tx_buffer *tx_buffer_info; @@ -5990,7 +6091,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, /* clear timestamp and dma mappings for remaining portion of packet */ while (count--) { - if (i==0) + if (i == 0) i += tx_ring->count; i--; tx_buffer_info = &tx_ring->tx_buffer_info[i]; @@ -6001,8 +6102,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, } static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - int tx_flags, int count, u32 paylen, u8 hdr_len) + struct ixgbe_ring *tx_ring, + int tx_flags, int count, u32 paylen, u8 hdr_len) { union ixgbe_adv_tx_desc *tx_desc = NULL; struct ixgbe_tx_buffer *tx_buffer_info; @@ -6021,17 +6122,17 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; olinfo_status |= IXGBE_TXD_POPTS_TXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; /* use index 1 context for tso */ olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT); if (tx_flags & IXGBE_TX_FLAGS_IPV4) olinfo_status |= IXGBE_TXD_POPTS_IXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; } else if (tx_flags & IXGBE_TX_FLAGS_CSUM) olinfo_status |= IXGBE_TXD_POPTS_TXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; if (tx_flags & IXGBE_TX_FLAGS_FCOE) { olinfo_status |= IXGBE_ADVTXD_CC; @@ -6045,10 +6146,10 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, i = tx_ring->next_to_use; while (count--) { tx_buffer_info = &tx_ring->tx_buffer_info[i]; - tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); + tx_desc = IXGBE_TX_DESC_ADV(tx_ring, i); tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma); tx_desc->read.cmd_type_len = - cpu_to_le32(cmd_type_len | tx_buffer_info->length); + cpu_to_le32(cmd_type_len | tx_buffer_info->length); tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status); i++; if (i == tx_ring->count) @@ -6070,7 +6171,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, } static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, - int queue, u32 tx_flags) + int queue, u32 tx_flags) { struct ixgbe_atr_input atr_input; struct tcphdr *th; @@ -6098,7 +6199,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, memset(&atr_input, 0, sizeof(struct ixgbe_atr_input)); vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >> - IXGBE_TX_FLAGS_VLAN_SHIFT; + IXGBE_TX_FLAGS_VLAN_SHIFT; src_ipv4_addr = iph->saddr; dst_ipv4_addr = iph->daddr; flex_bytes = eth->h_proto; @@ -6117,7 +6218,7 @@ static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb, } static int __ixgbe_maybe_stop_tx(struct net_device *netdev, - struct ixgbe_ring *tx_ring, int size) + struct ixgbe_ring *tx_ring, int size) { netif_stop_subqueue(netdev, tx_ring->queue_index); /* Herbert's original patch had: @@ -6137,7 +6238,7 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev, } static int ixgbe_maybe_stop_tx(struct net_device *netdev, - struct ixgbe_ring *tx_ring, int size) + struct ixgbe_ring *tx_ring, int size) { if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size)) return 0; @@ -6183,11 +6284,10 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb) return skb_tx_hash(dev, skb); } -static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, - struct net_device *netdev) +netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb, struct net_device *netdev, + struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) { - struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_ring *tx_ring; struct netdev_queue *txq; unsigned int first; unsigned int tx_flags = 0; @@ -6196,7 +6296,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, int count = 0; unsigned int f; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { tx_flags &= ~IXGBE_TX_FLAGS_VLAN_PRIO_MASK; @@ -6211,8 +6311,6 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, tx_flags |= IXGBE_TX_FLAGS_VLAN; } - tx_ring = adapter->tx_ring[skb->queue_mapping]; - #ifdef IXGBE_FCOE /* for FCoE with DCB, we force the priority to what * was specified by the switch */ @@ -6283,10 +6381,10 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, if (tx_ring->atr_sample_rate) { ++tx_ring->atr_count; if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) && - test_bit(__IXGBE_FDIR_INIT_DONE, - &tx_ring->reinit_state)) { + test_bit(__IXGBE_FDIR_INIT_DONE, + &tx_ring->reinit_state)) { ixgbe_atr(adapter, skb, tx_ring->queue_index, - tx_flags); + tx_flags); tx_ring->atr_count = 0; } } @@ -6294,7 +6392,7 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, txq->tx_bytes += skb->len; txq->tx_packets++; ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len, - hdr_len); + hdr_len); ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED); } else { @@ -6306,6 +6404,15 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, return NETDEV_TX_OK; } +static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_ring *tx_ring; + + tx_ring = adapter->tx_ring[skb->queue_mapping]; + return ixgbe_xmit_frame_ring(skb, netdev, adapter, tx_ring); +} + /** * ixgbe_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure @@ -6436,8 +6543,40 @@ static void ixgbe_netpoll(struct net_device *netdev) } #endif +static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, + struct rtnl_link_stats64 *stats) +{ + struct ixgbe_adapter *adapter = netdev_priv(netdev); + int i; + + /* accurate rx/tx bytes/packets stats */ + dev_txq_stats_fold(netdev, stats); + for (i = 0; i < adapter->num_rx_queues; i++) { + struct ixgbe_ring *ring = adapter->rx_ring[i]; + u64 bytes, packets; + unsigned int start; + + do { + start = u64_stats_fetch_begin_bh(&ring->syncp); + packets = ring->stats.packets; + bytes = ring->stats.bytes; + } while (u64_stats_fetch_retry_bh(&ring->syncp, start)); + stats->rx_packets += packets; + stats->rx_bytes += bytes; + } + + /* following stats updated by ixgbe_watchdog_task() */ + stats->multicast = netdev->stats.multicast; + stats->rx_errors = netdev->stats.rx_errors; + stats->rx_length_errors = netdev->stats.rx_length_errors; + stats->rx_crc_errors = netdev->stats.rx_crc_errors; + stats->rx_missed_errors = netdev->stats.rx_missed_errors; + return stats; +} + + static const struct net_device_ops ixgbe_netdev_ops = { - .ndo_open = ixgbe_open, + .ndo_open = ixgbe_open, .ndo_stop = ixgbe_close, .ndo_start_xmit = ixgbe_xmit_frame, .ndo_select_queue = ixgbe_select_queue, @@ -6447,7 +6586,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_mac_address = ixgbe_set_mac, .ndo_change_mtu = ixgbe_change_mtu, .ndo_tx_timeout = ixgbe_tx_timeout, - .ndo_vlan_rx_register = ixgbe_vlan_rx_register, .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, .ndo_do_ioctl = ixgbe_ioctl, @@ -6455,6 +6593,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_set_vf_vlan = ixgbe_ndo_set_vf_vlan, .ndo_set_vf_tx_rate = ixgbe_ndo_set_vf_bw, .ndo_get_vf_config = ixgbe_ndo_get_vf_config, + .ndo_get_stats64 = ixgbe_get_stats64, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = ixgbe_netpoll, #endif @@ -6532,7 +6671,7 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter, * and a hardware reset occur. **/ static int __devinit ixgbe_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { struct net_device *netdev; struct ixgbe_adapter *adapter = NULL; @@ -6577,7 +6716,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, } err = pci_request_selected_regions(pdev, pci_select_bars(pdev, - IORESOURCE_MEM), ixgbe_driver_name); + IORESOURCE_MEM), ixgbe_driver_name); if (err) { dev_err(&pdev->dev, "pci_request_selected_regions failed 0x%x\n", err); @@ -6617,7 +6756,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1; hw->hw_addr = ioremap(pci_resource_start(pdev, 0), - pci_resource_len(pdev, 0)); + pci_resource_len(pdev, 0)); if (!hw->hw_addr) { err = -EIO; goto err_ioremap; @@ -6661,7 +6800,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, * which might start the timer */ init_timer(&adapter->sfp_timer); - adapter->sfp_timer.function = &ixgbe_sfp_timer; + adapter->sfp_timer.function = ixgbe_sfp_timer; adapter->sfp_timer.data = (unsigned long) adapter; INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task); @@ -6671,7 +6810,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* a new SFP+ module arrival, called from GPI SDP2 context */ INIT_WORK(&adapter->sfp_config_module_task, - ixgbe_sfp_config_module_task); + ixgbe_sfp_config_module_task); ii->get_invariants(hw); @@ -6723,10 +6862,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ixgbe_probe_vf(adapter, ii); netdev->features = NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; + NETIF_F_IP_CSUM | + NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; netdev->features |= NETIF_F_IPV6_CSUM; netdev->features |= NETIF_F_TSO; @@ -6766,8 +6905,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->vlan_features |= NETIF_F_FCOE_MTU; } #endif /* IXGBE_FCOE */ - if (pci_using_dac) + if (pci_using_dac) { netdev->features |= NETIF_F_HIGHDMA; + netdev->vlan_features |= NETIF_F_HIGHDMA; + } if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) netdev->features |= NETIF_F_LRO; @@ -6793,7 +6934,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, hw->mac.ops.disable_tx_laser(hw); init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &ixgbe_watchdog; + adapter->watchdog_timer.function = ixgbe_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->reset_task, ixgbe_reset_task); @@ -6806,7 +6947,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, switch (pdev->device) { case IXGBE_DEV_ID_82599_KX4: adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX | - IXGBE_WUFC_MC | IXGBE_WUFC_BC); + IXGBE_WUFC_MC | IXGBE_WUFC_BC); break; default: adapter->wol = 0; @@ -6819,13 +6960,14 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, /* print bus type/speed/width info */ e_dev_info("(PCI Express:%s:%s) %pM\n", - ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s": - (hw->bus.speed == ixgbe_bus_speed_2500) ? "2.5Gb/s":"Unknown"), - ((hw->bus.width == ixgbe_bus_width_pcie_x8) ? "Width x8" : - (hw->bus.width == ixgbe_bus_width_pcie_x4) ? "Width x4" : - (hw->bus.width == ixgbe_bus_width_pcie_x1) ? "Width x1" : - "Unknown"), - netdev->dev_addr); + (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0Gb/s" : + hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5Gb/s" : + "Unknown"), + (hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" : + hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" : + hw->bus.width == ixgbe_bus_width_pcie_x1 ? "Width x1" : + "Unknown"), + netdev->dev_addr); ixgbe_read_pba_num_generic(hw, &part_num); if (ixgbe_is_sfp(hw) && hw->phy.sfp_type != ixgbe_sfp_type_not_present) e_dev_info("MAC: %d, PHY: %d, SFP+: %d, " @@ -6872,7 +7014,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task); if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) - INIT_WORK(&adapter->check_overtemp_task, ixgbe_check_overtemp_task); + INIT_WORK(&adapter->check_overtemp_task, + ixgbe_check_overtemp_task); #ifdef CONFIG_IXGBE_DCA if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; @@ -6908,8 +7051,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, err_ioremap: free_netdev(netdev); err_alloc_etherdev: - pci_release_selected_regions(pdev, pci_select_bars(pdev, - IORESOURCE_MEM)); + pci_release_selected_regions(pdev, + pci_select_bars(pdev, IORESOURCE_MEM)); err_pci_reg: err_dma: pci_disable_device(pdev); @@ -6976,7 +7119,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) iounmap(adapter->hw.hw_addr); pci_release_selected_regions(pdev, pci_select_bars(pdev, - IORESOURCE_MEM)); + IORESOURCE_MEM)); e_dev_info("complete\n"); @@ -6996,7 +7139,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) * this device has been detected. */ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) + pci_channel_state_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -7102,8 +7245,7 @@ static struct pci_driver ixgbe_driver = { static int __init ixgbe_init_module(void) { int ret; - pr_info("%s - version %s\n", ixgbe_driver_string, - ixgbe_driver_version); + pr_info("%s - version %s\n", ixgbe_driver_string, ixgbe_driver_version); pr_info("%s\n", ixgbe_copyright); #ifdef CONFIG_IXGBE_DCA @@ -7132,12 +7274,12 @@ static void __exit ixgbe_exit_module(void) #ifdef CONFIG_IXGBE_DCA static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event, - void *p) + void *p) { int ret_val; ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event, - __ixgbe_notify_dca); + __ixgbe_notify_dca); return ret_val ? NOTIFY_BAD : NOTIFY_DONE; } diff --git a/drivers/net/ixgbe/ixgbe_mbx.c b/drivers/net/ixgbe/ixgbe_mbx.c index d75f9148eb1f8d1e9adb316380a74bb573346e08..471f0f2cdb98976ac3d6785a134a9d8b5a2f3087 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.c +++ b/drivers/net/ixgbe/ixgbe_mbx.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -200,7 +200,8 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) * returns SUCCESS if it successfully received a message notification and * copied it into the receive buffer. **/ -s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) +static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; s32 ret_val = IXGBE_ERR_MBX; @@ -227,7 +228,7 @@ s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) * returns SUCCESS if it successfully copied message into the buffer and * received an ack to that message within delay * timeout period **/ -s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, +static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) { struct ixgbe_mbx_info *mbx = &hw->mbx; @@ -247,20 +248,6 @@ s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, return ret_val; } -/** - * ixgbe_init_mbx_ops_generic - Initialize MB function pointers - * @hw: pointer to the HW structure - * - * Setup the mailbox read and write message function pointers - **/ -void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw) -{ - struct ixgbe_mbx_info *mbx = &hw->mbx; - - mbx->ops.read_posted = ixgbe_read_posted_mbx; - mbx->ops.write_posted = ixgbe_write_posted_mbx; -} - static s32 ixgbe_check_for_bit_pf(struct ixgbe_hw *hw, u32 mask, s32 index) { u32 mbvficr = IXGBE_READ_REG(hw, IXGBE_MBVFICR(index)); diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h index be7ab3309ab733590ef6c231db6f3db6d2eee823..7e0d08ff5b53f53cad83da3db0ef96981cbc1eb6 100644 --- a/drivers/net/ixgbe/ixgbe_mbx.h +++ b/drivers/net/ixgbe/ixgbe_mbx.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -83,12 +83,9 @@ s32 ixgbe_read_mbx(struct ixgbe_hw *, u32 *, u16, u16); s32 ixgbe_write_mbx(struct ixgbe_hw *, u32 *, u16, u16); -s32 ixgbe_read_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16); -s32 ixgbe_write_posted_mbx(struct ixgbe_hw *, u32 *, u16, u16); s32 ixgbe_check_for_msg(struct ixgbe_hw *, u16); s32 ixgbe_check_for_ack(struct ixgbe_hw *, u16); s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16); -void ixgbe_init_mbx_ops_generic(struct ixgbe_hw *hw); void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); extern struct ixgbe_mbx_operations mbx_ops_82599; diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 49661a138e227d7caf74e70bc8ad026050fcdc32..5428153af8f31a83ca56d2beb8dea42b121d6462 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -43,8 +43,8 @@ #include "ixgbe_sriov.h" -int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, - int entries, u16 *hash_list, u32 vf) +static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, + int entries, u16 *hash_list, u32 vf) { struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; struct ixgbe_hw *hw = &adapter->hw; @@ -104,13 +104,14 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) } } -int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf) +static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, + u32 vf) { return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); } -void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) +static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) { u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); vmolr |= (IXGBE_VMOLR_ROMPE | @@ -134,7 +135,7 @@ static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf) IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); } -inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) +static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) { struct ixgbe_hw *hw = &adapter->hw; int rar_entry = hw->mac.num_rar_entries - (vf + 1); @@ -162,8 +163,8 @@ inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) hw->mac.ops.clear_rar(hw, rar_entry); } -int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, - int vf, unsigned char *mac_addr) +static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, + int vf, unsigned char *mac_addr) { struct ixgbe_hw *hw = &adapter->hw; int rar_entry = hw->mac.num_rar_entries - (vf + 1); @@ -197,7 +198,7 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) return 0; } -inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) +static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) { struct ixgbe_hw *hw = &adapter->hw; u32 reg; diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h index 184730ecdfb66c4f668b298b5d411fc4a1a4d47f..49dc14debef7b82bff70a07d4c9416a56c3ab655 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.h +++ b/drivers/net/ixgbe/ixgbe_sriov.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2009 Intel Corporation. + Copyright(c) 1999 - 2010 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -28,16 +28,8 @@ #ifndef _IXGBE_SRIOV_H_ #define _IXGBE_SRIOV_H_ -int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, - int entries, u16 *hash_list, u32 vf); void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter); -int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf); -void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe); -void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf); -void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf); void ixgbe_msg_task(struct ixgbe_adapter *adapter); -int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, - int vf, unsigned char *mac_addr); int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask); void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter); void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 9587d975d66c6eeb31e82f9233ab82f876036134..d3cc6ce7c973a3c71855588029e57ab7dcd82ef6 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -871,6 +871,8 @@ #define IXGBE_RDRXCTL_MVMEN 0x00000020 #define IXGBE_RDRXCTL_DMAIDONE 0x00000008 /* DMA init cycle done */ #define IXGBE_RDRXCTL_AGGDIS 0x00010000 /* Aggregation disable */ +#define IXGBE_RDRXCTL_RSCACKC 0x02000000 /* must set 1 when RSC enabled */ +#define IXGBE_RDRXCTL_FCOE_WRFIX 0x04000000 /* must set 1 when RSC enabled */ /* RQTC Bit Masks and Shifts */ #define IXGBE_RQTC_SHIFT_TC(_i) ((_i) * 4) diff --git a/drivers/net/ixgbevf/ethtool.c b/drivers/net/ixgbevf/ethtool.c index 4680b069b84fe5d953841ecdf98717088ce21bb1..4cc817acfb62041f95c0233ae8117176a353d8b3 100644 --- a/drivers/net/ixgbevf/ethtool.c +++ b/drivers/net/ixgbevf/ethtool.c @@ -330,10 +330,8 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, { struct ixgbevf_adapter *adapter = netdev_priv(netdev); struct ixgbevf_ring *tx_ring = NULL, *rx_ring = NULL; - int i, err; + int i, err = 0; u32 new_rx_count, new_tx_count; - bool need_tx_update = false; - bool need_rx_update = false; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; @@ -355,89 +353,96 @@ static int ixgbevf_set_ringparam(struct net_device *netdev, while (test_and_set_bit(__IXGBEVF_RESETTING, &adapter->state)) msleep(1); - if (new_tx_count != adapter->tx_ring_count) { - tx_ring = kcalloc(adapter->num_tx_queues, - sizeof(struct ixgbevf_ring), GFP_KERNEL); - if (!tx_ring) { - err = -ENOMEM; - goto err_setup; - } - memcpy(tx_ring, adapter->tx_ring, - adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); - for (i = 0; i < adapter->num_tx_queues; i++) { - tx_ring[i].count = new_tx_count; - err = ixgbevf_setup_tx_resources(adapter, - &tx_ring[i]); - if (err) { - while (i) { - i--; - ixgbevf_free_tx_resources(adapter, - &tx_ring[i]); - } - kfree(tx_ring); - goto err_setup; - } - tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; - } - need_tx_update = true; + /* + * If the adapter isn't up and running then just set the + * new parameters and scurry for the exits. + */ + if (!netif_running(adapter->netdev)) { + for (i = 0; i < adapter->num_tx_queues; i++) + adapter->tx_ring[i].count = new_tx_count; + for (i = 0; i < adapter->num_rx_queues; i++) + adapter->rx_ring[i].count = new_rx_count; + adapter->tx_ring_count = new_tx_count; + adapter->rx_ring_count = new_rx_count; + goto clear_reset; } - if (new_rx_count != adapter->rx_ring_count) { - rx_ring = kcalloc(adapter->num_rx_queues, - sizeof(struct ixgbevf_ring), GFP_KERNEL); - if ((!rx_ring) && (need_tx_update)) { - err = -ENOMEM; - goto err_rx_setup; - } - memcpy(rx_ring, adapter->rx_ring, - adapter->num_rx_queues * sizeof(struct ixgbevf_ring)); - for (i = 0; i < adapter->num_rx_queues; i++) { - rx_ring[i].count = new_rx_count; - err = ixgbevf_setup_rx_resources(adapter, - &rx_ring[i]); - if (err) { - while (i) { - i--; - ixgbevf_free_rx_resources(adapter, - &rx_ring[i]); - } - kfree(rx_ring); - goto err_rx_setup; - } - rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; - } - need_rx_update = true; + tx_ring = kcalloc(adapter->num_tx_queues, + sizeof(struct ixgbevf_ring), GFP_KERNEL); + if (!tx_ring) { + err = -ENOMEM; + goto clear_reset; } -err_rx_setup: - /* if rings need to be updated, here's the place to do it in one shot */ - if (need_tx_update || need_rx_update) { - if (netif_running(netdev)) - ixgbevf_down(adapter); + rx_ring = kcalloc(adapter->num_rx_queues, + sizeof(struct ixgbevf_ring), GFP_KERNEL); + if (!rx_ring) { + err = -ENOMEM; + goto err_rx_setup; } - /* tx */ - if (need_tx_update) { - kfree(adapter->tx_ring); - adapter->tx_ring = tx_ring; - tx_ring = NULL; - adapter->tx_ring_count = new_tx_count; + ixgbevf_down(adapter); + + memcpy(tx_ring, adapter->tx_ring, + adapter->num_tx_queues * sizeof(struct ixgbevf_ring)); + for (i = 0; i < adapter->num_tx_queues; i++) { + tx_ring[i].count = new_tx_count; + err = ixgbevf_setup_tx_resources(adapter, &tx_ring[i]); + if (err) { + while (i) { + i--; + ixgbevf_free_tx_resources(adapter, + &tx_ring[i]); + } + goto err_tx_ring_setup; + } + tx_ring[i].v_idx = adapter->tx_ring[i].v_idx; } - /* rx */ - if (need_rx_update) { - kfree(adapter->rx_ring); - adapter->rx_ring = rx_ring; - rx_ring = NULL; - adapter->rx_ring_count = new_rx_count; + memcpy(rx_ring, adapter->rx_ring, + adapter->num_rx_queues * sizeof(struct ixgbevf_ring)); + for (i = 0; i < adapter->num_rx_queues; i++) { + rx_ring[i].count = new_rx_count; + err = ixgbevf_setup_rx_resources(adapter, &rx_ring[i]); + if (err) { + while (i) { + i--; + ixgbevf_free_rx_resources(adapter, + &rx_ring[i]); + } + goto err_rx_ring_setup; + } + rx_ring[i].v_idx = adapter->rx_ring[i].v_idx; } + /* + * Only switch to new rings if all the prior allocations + * and ring setups have succeeded. + */ + kfree(adapter->tx_ring); + adapter->tx_ring = tx_ring; + adapter->tx_ring_count = new_tx_count; + + kfree(adapter->rx_ring); + adapter->rx_ring = rx_ring; + adapter->rx_ring_count = new_rx_count; + /* success! */ - err = 0; - if (netif_running(netdev)) - ixgbevf_up(adapter); + ixgbevf_up(adapter); + + goto clear_reset; + +err_rx_ring_setup: + for(i = 0; i < adapter->num_tx_queues; i++) + ixgbevf_free_tx_resources(adapter, &tx_ring[i]); + +err_tx_ring_setup: + kfree(rx_ring); + +err_rx_setup: + kfree(tx_ring); -err_setup: +clear_reset: clear_bit(__IXGBEVF_RESETTING, &adapter->state); return err; } diff --git a/drivers/net/ixgbevf/ixgbevf.h b/drivers/net/ixgbevf/ixgbevf.h index f7015efbff05cfc91da412e43e664af72594ce41..da4033c6efa20f677342a8f6aff4bbca224548cd 100644 --- a/drivers/net/ixgbevf/ixgbevf.h +++ b/drivers/net/ixgbevf/ixgbevf.h @@ -243,7 +243,6 @@ struct ixgbevf_adapter { /* OS defined structs */ struct net_device *netdev; struct pci_dev *pdev; - struct net_device_stats net_stats; /* structs defined in ixgbe_vf.h */ struct ixgbe_hw hw; diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 918c00359b0a5355ea9862f6cf6a3963b8b80a04..dc03c9652389692982dbcff1be6693c5d76e2f6b 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c @@ -308,10 +308,10 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter, tx_ring->total_bytes += total_bytes; tx_ring->total_packets += total_packets; - adapter->net_stats.tx_bytes += total_bytes; - adapter->net_stats.tx_packets += total_packets; + netdev->stats.tx_bytes += total_bytes; + netdev->stats.tx_packets += total_packets; - return (count < tx_ring->work_limit); + return count < tx_ring->work_limit; } /** @@ -356,7 +356,7 @@ static void ixgbevf_receive_skb(struct ixgbevf_q_vector *q_vector, static inline void ixgbevf_rx_checksum(struct ixgbevf_adapter *adapter, u32 status_err, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Rx csum disabled */ if (!(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED)) @@ -639,8 +639,8 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector, rx_ring->total_packets += total_rx_packets; rx_ring->total_bytes += total_rx_bytes; - adapter->net_stats.rx_bytes += total_rx_bytes; - adapter->net_stats.rx_packets += total_rx_packets; + adapter->netdev->stats.rx_bytes += total_rx_bytes; + adapter->netdev->stats.rx_packets += total_rx_packets; return cleaned; } @@ -1495,7 +1495,7 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) if (adapter->vlgrp) { u16 vid; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(adapter->vlgrp, vid)) continue; ixgbevf_vlan_rx_add_vid(adapter->netdev, vid); @@ -2297,7 +2297,7 @@ void ixgbevf_update_stats(struct ixgbevf_adapter *adapter) adapter->stats.vfmprc); /* Fill out the OS statistics structure */ - adapter->net_stats.multicast = adapter->stats.vfmprc - + adapter->netdev->stats.multicast = adapter->stats.vfmprc - adapter->stats.base_vfmprc; } @@ -3134,7 +3134,7 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) tx_ring = &adapter->tx_ring[r_idx]; - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { tx_flags |= vlan_tx_tag_get(skb); tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; tx_flags |= IXGBE_TX_FLAGS_VLAN; @@ -3180,21 +3180,6 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } -/** - * ixgbevf_get_stats - Get System Network Statistics - * @netdev: network interface device structure - * - * Returns the address of the device statistics structure. - * The statistics are actually updated from the timer callback. - **/ -static struct net_device_stats *ixgbevf_get_stats(struct net_device *netdev) -{ - struct ixgbevf_adapter *adapter = netdev_priv(netdev); - - /* only return the current stats */ - return &adapter->net_stats; -} - /** * ixgbevf_set_mac - Change the Ethernet Address of the NIC * @netdev: network interface device structure @@ -3272,7 +3257,6 @@ static const struct net_device_ops ixgbe_netdev_ops = { .ndo_open = &ixgbevf_open, .ndo_stop = &ixgbevf_close, .ndo_start_xmit = &ixgbevf_xmit_frame, - .ndo_get_stats = &ixgbevf_get_stats, .ndo_set_rx_mode = &ixgbevf_set_rx_mode, .ndo_set_multicast_list = &ixgbevf_set_rx_mode, .ndo_validate_addr = eth_validate_addr, @@ -3426,7 +3410,7 @@ static int __devinit ixgbevf_probe(struct pci_dev *pdev, } init_timer(&adapter->watchdog_timer); - adapter->watchdog_timer.function = &ixgbevf_watchdog; + adapter->watchdog_timer.function = ixgbevf_watchdog; adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->reset_task, ixgbevf_reset_task); diff --git a/drivers/net/ixgbevf/mbx.c b/drivers/net/ixgbevf/mbx.c index b8143501e6fc04eca2a06f285c3d0c42c53f97e8..84ac486f4a65f9f4abb65b5d94236c646b56bec0 100644 --- a/drivers/net/ixgbevf/mbx.c +++ b/drivers/net/ixgbevf/mbx.c @@ -308,7 +308,7 @@ static s32 ixgbevf_read_mbx_vf(struct ixgbe_hw *hw, u32 *msg, u16 size) * * Initializes the hw->mbx struct to correct values for vf mailbox */ -s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw) +static s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *hw) { struct ixgbe_mbx_info *mbx = &hw->mbx; diff --git a/drivers/net/ixgbevf/mbx.h b/drivers/net/ixgbevf/mbx.h index 1b0e0bf4c0f5c05934ba1027e9c124c85cabdc39..8c063bebee7f13a5f1b6d28054c4d1fe5658fc3f 100644 --- a/drivers/net/ixgbevf/mbx.h +++ b/drivers/net/ixgbevf/mbx.h @@ -95,6 +95,4 @@ /* forward declaration of the HW struct */ struct ixgbe_hw; -s32 ixgbevf_init_mbx_params_vf(struct ixgbe_hw *); - #endif /* _IXGBE_MBX_H_ */ diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c index f6f929958ba0beb3cb3ec60970042976f1062247..bfe42c1fcfafa681c660d10e2b399e20d12f22ca 100644 --- a/drivers/net/ixgbevf/vf.c +++ b/drivers/net/ixgbevf/vf.c @@ -368,7 +368,7 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw, return 0; } -struct ixgbe_mac_operations ixgbevf_mac_ops = { +static struct ixgbe_mac_operations ixgbevf_mac_ops = { .init_hw = ixgbevf_init_hw_vf, .reset_hw = ixgbevf_reset_hw_vf, .start_hw = ixgbevf_start_hw_vf, diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h index 94b750b8874f492d279fac3b68943c58e566be8f..61f9dc831424143d02497b335387caba5bf65823 100644 --- a/drivers/net/ixgbevf/vf.h +++ b/drivers/net/ixgbevf/vf.h @@ -124,8 +124,6 @@ struct ixgbe_hw { void *back; u8 __iomem *hw_addr; - u8 *flash_address; - unsigned long io_base; struct ixgbe_mac_info mac; struct ixgbe_mbx_info mbx; diff --git a/drivers/net/jme.c b/drivers/net/jme.c index 99f24f5cac53f6c6a70e25681253593b3b485a6e..d7a975ee2add393010e9db6ad38fbd1c770603a4 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -3,6 +3,7 @@ * * Copyright 2008 JMicron Technology Corporation * http://www.jmicron.com/ + * Copyright (c) 2009 - 2010 Guo-Fu Tseng * * Author: Guo-Fu Tseng * @@ -21,6 +22,8 @@ * */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -73,7 +76,7 @@ jme_mdio_read(struct net_device *netdev, int phy, int reg) } if (i == 0) { - jeprintk(jme->pdev, "phy(%d) read timeout : %d\n", phy, reg); + pr_err("phy(%d) read timeout : %d\n", phy, reg); return 0; } @@ -102,7 +105,7 @@ jme_mdio_write(struct net_device *netdev, } if (i == 0) - jeprintk(jme->pdev, "phy(%d) write timeout : %d\n", phy, reg); + pr_err("phy(%d) write timeout : %d\n", phy, reg); } static inline void @@ -227,7 +230,7 @@ jme_reload_eeprom(struct jme_adapter *jme) } if (i == 0) { - jeprintk(jme->pdev, "eeprom reload timeout\n"); + pr_err("eeprom reload timeout\n"); return -EIO; } } @@ -397,8 +400,7 @@ jme_check_link(struct net_device *netdev, int testonly) phylink = jread32(jme, JME_PHY_LINK); } if (!cnt) - jeprintk(jme->pdev, - "Waiting speed resolve timeout.\n"); + pr_err("Waiting speed resolve timeout\n"); strcat(linkmsg, "ANed: "); } @@ -480,13 +482,13 @@ jme_check_link(struct net_device *netdev, int testonly) strcat(linkmsg, (phylink & PHY_LINK_MDI_STAT) ? "MDI-X" : "MDI"); - netif_info(jme, link, jme->dev, "Link is up at %s.\n", linkmsg); + netif_info(jme, link, jme->dev, "Link is up at %s\n", linkmsg); netif_carrier_on(netdev); } else { if (testonly) goto out; - netif_info(jme, link, jme->dev, "Link is down.\n"); + netif_info(jme, link, jme->dev, "Link is down\n"); jme->phylink = 0; netif_carrier_off(netdev); } @@ -648,7 +650,7 @@ jme_disable_tx_engine(struct jme_adapter *jme) } if (!i) - jeprintk(jme->pdev, "Disable TX engine timeout.\n"); + pr_err("Disable TX engine timeout\n"); } static void @@ -867,7 +869,7 @@ jme_disable_rx_engine(struct jme_adapter *jme) } if (!i) - jeprintk(jme->pdev, "Disable RX engine timeout.\n"); + pr_err("Disable RX engine timeout\n"); } @@ -887,13 +889,13 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags) if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS)) == RXWBFLAG_UDPON)) { if (flags & RXWBFLAG_IPV4) - netif_err(jme, rx_err, jme->dev, "UDP Checksum error.\n"); + netif_err(jme, rx_err, jme->dev, "UDP Checksum error\n"); return false; } if (unlikely((flags & (RXWBFLAG_IPV4 | RXWBFLAG_IPCS)) == RXWBFLAG_IPV4)) { - netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error.\n"); + netif_err(jme, rx_err, jme->dev, "IPv4 Checksum error\n"); return false; } @@ -936,7 +938,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx) if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) { if (jme->vlgrp) { @@ -988,6 +990,7 @@ jme_process_receive(struct jme_adapter *jme, int limit) goto out; --limit; + rmb(); desccnt = rxdesc->descwb.desccnt & RXWBDCNT_DCNT; if (unlikely(desccnt > 1 || @@ -1185,9 +1188,9 @@ jme_link_change_tasklet(unsigned long arg) while (!atomic_dec_and_test(&jme->link_changing)) { atomic_inc(&jme->link_changing); - netif_info(jme, intr, jme->dev, "Get link change lock failed.\n"); + netif_info(jme, intr, jme->dev, "Get link change lock failed\n"); while (atomic_read(&jme->link_changing) != 1) - netif_info(jme, intr, jme->dev, "Waiting link change lock.\n"); + netif_info(jme, intr, jme->dev, "Waiting link change lock\n"); } if (jme_check_link(netdev, 1) && jme->old_mtu == netdev->mtu) @@ -1221,15 +1224,13 @@ jme_link_change_tasklet(unsigned long arg) if (netif_carrier_ok(netdev)) { rc = jme_setup_rx_resources(jme); if (rc) { - jeprintk(jme->pdev, "Allocating resources for RX error" - ", Device STOPPED!\n"); + pr_err("Allocating resources for RX error, Device STOPPED!\n"); goto out_enable_tasklet; } rc = jme_setup_tx_resources(jme); if (rc) { - jeprintk(jme->pdev, "Allocating resources for TX error" - ", Device STOPPED!\n"); + pr_err("Allocating resources for TX error, Device STOPPED!\n"); goto err_out_free_rx_resources; } @@ -1324,7 +1325,7 @@ jme_wake_queue_if_stopped(struct jme_adapter *jme) smp_wmb(); if (unlikely(netif_queue_stopped(jme->dev) && atomic_read(&txring->nr_free) >= (jme->tx_wake_threshold))) { - netif_info(jme, tx_done, jme->dev, "TX Queue Waked.\n"); + netif_info(jme, tx_done, jme->dev, "TX Queue Waked\n"); netif_wake_queue(jme->dev); } @@ -1339,7 +1340,7 @@ jme_tx_clean_tasklet(unsigned long arg) struct jme_buffer_info *txbi = txring->bufinf, *ctxbi, *ttxbi; int i, j, cnt = 0, max, err, mask; - tx_dbg(jme, "Into txclean.\n"); + tx_dbg(jme, "Into txclean\n"); if (unlikely(!atomic_dec_and_test(&jme->tx_cleaning))) goto out; @@ -1361,7 +1362,7 @@ jme_tx_clean_tasklet(unsigned long arg) !(txdesc[i].descwb.flags & TXWBFLAG_OWN))) { tx_dbg(jme, "txclean: %d+%d@%lu\n", - i, ctxbi->nr_desc, jiffies); + i, ctxbi->nr_desc, jiffies); err = txdesc[i].descwb.flags & TXWBFLAG_ALLERR; @@ -1402,7 +1403,7 @@ jme_tx_clean_tasklet(unsigned long arg) ctxbi->nr_desc = 0; } - tx_dbg(jme, "txclean: done %d@%lu.\n", i, jiffies); + tx_dbg(jme, "txclean: done %d@%lu\n", i, jiffies); atomic_set(&txring->next_to_clean, i); atomic_add(cnt, &txring->nr_free); @@ -1548,10 +1549,10 @@ jme_request_irq(struct jme_adapter *jme) rc = request_irq(jme->pdev->irq, handler, irq_flags, netdev->name, netdev); if (rc) { - jeprintk(jme->pdev, - "Unable to request %s interrupt (return: %d)\n", - test_bit(JME_FLAG_MSI, &jme->flags) ? "MSI" : "INTx", - rc); + netdev_err(netdev, + "Unable to request %s interrupt (return: %d)\n", + test_bit(JME_FLAG_MSI, &jme->flags) ? "MSI" : "INTx", + rc); if (test_bit(JME_FLAG_MSI, &jme->flags)) { pci_disable_msi(jme->pdev); @@ -1575,6 +1576,16 @@ jme_free_irq(struct jme_adapter *jme) } } +static inline void +jme_phy_on(struct jme_adapter *jme) +{ + u32 bmcr; + + bmcr = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_BMCR); + bmcr &= ~BMCR_PDOWN; + jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr); +} + static int jme_open(struct net_device *netdev) { @@ -1595,10 +1606,12 @@ jme_open(struct net_device *netdev) jme_start_irq(jme); - if (test_bit(JME_FLAG_SSET, &jme->flags)) + if (test_bit(JME_FLAG_SSET, &jme->flags)) { + jme_phy_on(jme); jme_set_settings(netdev, &jme->old_ecmd); - else + } else { jme_reset_phy_processor(jme); + } jme_reset_link(jme); @@ -1834,7 +1847,7 @@ jme_tx_csum(struct jme_adapter *jme, struct sk_buff *skb, u8 *flags) *flags |= TXFLAG_UDPCS; break; default: - netif_err(jme, tx_err, jme->dev, "Error upper layer protocol.\n"); + netif_err(jme, tx_err, jme->dev, "Error upper layer protocol\n"); break; } } @@ -1909,12 +1922,12 @@ jme_stop_queue_if_full(struct jme_adapter *jme) smp_wmb(); if (unlikely(atomic_read(&txring->nr_free) < (MAX_SKB_FRAGS+2))) { netif_stop_queue(jme->dev); - netif_info(jme, tx_queued, jme->dev, "TX Queue Paused.\n"); + netif_info(jme, tx_queued, jme->dev, "TX Queue Paused\n"); smp_wmb(); if (atomic_read(&txring->nr_free) >= (jme->tx_wake_threshold)) { netif_wake_queue(jme->dev); - netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked.\n"); + netif_info(jme, tx_queued, jme->dev, "TX Queue Fast Waked\n"); } } @@ -1922,7 +1935,8 @@ jme_stop_queue_if_full(struct jme_adapter *jme) (jiffies - txbi->start_xmit) >= TX_TIMEOUT && txbi->skb)) { netif_stop_queue(jme->dev); - netif_info(jme, tx_queued, jme->dev, "TX Queue Stopped %d@%lu.\n", idx, jiffies); + netif_info(jme, tx_queued, jme->dev, + "TX Queue Stopped %d@%lu\n", idx, jiffies); } } @@ -1945,7 +1959,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) if (unlikely(idx < 0)) { netif_stop_queue(netdev); - netif_err(jme, tx_err, jme->dev, "BUG! Tx ring full when queue awake!\n"); + netif_err(jme, tx_err, jme->dev, + "BUG! Tx ring full when queue awake!\n"); return NETDEV_TX_BUSY; } @@ -1957,9 +1972,8 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) TXCS_QUEUE0S | TXCS_ENABLE); - tx_dbg(jme, "xmit: %d+%d@%lu\n", idx, - skb_shinfo(skb)->nr_frags + 2, - jiffies); + tx_dbg(jme, "xmit: %d+%d@%lu\n", + idx, skb_shinfo(skb)->nr_frags + 2, jiffies); jme_stop_queue_if_full(jme); return NETDEV_TX_OK; @@ -2382,6 +2396,10 @@ jme_set_settings(struct net_device *netdev, if (ecmd->speed == SPEED_1000 && ecmd->autoneg != AUTONEG_ENABLE) return -EINVAL; + /* + * Check If user changed duplex only while force_media. + * Hardware would not generate link change interrupt. + */ if (jme->mii_if.force_media && ecmd->autoneg != AUTONEG_ENABLE && (jme->mii_if.full_duplex != ecmd->duplex)) @@ -2391,12 +2409,40 @@ jme_set_settings(struct net_device *netdev, rc = mii_ethtool_sset(&(jme->mii_if), ecmd); spin_unlock_bh(&jme->phy_lock); - if (!rc && fdc) - jme_reset_link(jme); - if (!rc) { - set_bit(JME_FLAG_SSET, &jme->flags); + if (fdc) + jme_reset_link(jme); jme->old_ecmd = *ecmd; + set_bit(JME_FLAG_SSET, &jme->flags); + } + + return rc; +} + +static int +jme_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) +{ + int rc; + struct jme_adapter *jme = netdev_priv(netdev); + struct mii_ioctl_data *mii_data = if_mii(rq); + unsigned int duplex_chg; + + if (cmd == SIOCSMIIREG) { + u16 val = mii_data->val_in; + if (!(val & (BMCR_RESET|BMCR_ANENABLE)) && + (val & BMCR_SPEED1000)) + return -EINVAL; + } + + spin_lock_bh(&jme->phy_lock); + rc = generic_mii_ioctl(&jme->mii_if, mii_data, cmd, &duplex_chg); + spin_unlock_bh(&jme->phy_lock); + + if (!rc && (cmd == SIOCSMIIREG)) { + if (duplex_chg) + jme_reset_link(jme); + jme_get_settings(netdev, &jme->old_ecmd); + set_bit(JME_FLAG_SSET, &jme->flags); } return rc; @@ -2501,7 +2547,7 @@ jme_smb_read(struct jme_adapter *jme, unsigned int addr) val = jread32(jme, JME_SMBCSR); } if (!to) { - netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n"); + netif_err(jme, hw, jme->dev, "SMB Bus Busy\n"); return 0xFF; } @@ -2517,7 +2563,7 @@ jme_smb_read(struct jme_adapter *jme, unsigned int addr) val = jread32(jme, JME_SMBINTF); } if (!to) { - netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n"); + netif_err(jme, hw, jme->dev, "SMB Bus Busy\n"); return 0xFF; } @@ -2537,7 +2583,7 @@ jme_smb_write(struct jme_adapter *jme, unsigned int addr, u8 data) val = jread32(jme, JME_SMBCSR); } if (!to) { - netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n"); + netif_err(jme, hw, jme->dev, "SMB Bus Busy\n"); return; } @@ -2554,7 +2600,7 @@ jme_smb_write(struct jme_adapter *jme, unsigned int addr, u8 data) val = jread32(jme, JME_SMBINTF); } if (!to) { - netif_err(jme, hw, jme->dev, "SMB Bus Busy.\n"); + netif_err(jme, hw, jme->dev, "SMB Bus Busy\n"); return; } @@ -2676,6 +2722,7 @@ static const struct net_device_ops jme_netdev_ops = { .ndo_open = jme_open, .ndo_stop = jme_close, .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = jme_ioctl, .ndo_start_xmit = jme_start_xmit, .ndo_set_mac_address = jme_set_macaddr, .ndo_set_multicast_list = jme_set_multi, @@ -2699,26 +2746,26 @@ jme_init_one(struct pci_dev *pdev, */ rc = pci_enable_device(pdev); if (rc) { - jeprintk(pdev, "Cannot enable PCI device.\n"); + pr_err("Cannot enable PCI device\n"); goto err_out; } using_dac = jme_pci_dma64(pdev); if (using_dac < 0) { - jeprintk(pdev, "Cannot set PCI DMA Mask.\n"); + pr_err("Cannot set PCI DMA Mask\n"); rc = -EIO; goto err_out_disable_pdev; } if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { - jeprintk(pdev, "No PCI resource region found.\n"); + pr_err("No PCI resource region found\n"); rc = -ENOMEM; goto err_out_disable_pdev; } rc = pci_request_regions(pdev, DRV_NAME); if (rc) { - jeprintk(pdev, "Cannot obtain PCI resource region.\n"); + pr_err("Cannot obtain PCI resource region\n"); goto err_out_disable_pdev; } @@ -2729,7 +2776,7 @@ jme_init_one(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(*jme)); if (!netdev) { - jeprintk(pdev, "Cannot allocate netdev structure.\n"); + pr_err("Cannot allocate netdev structure\n"); rc = -ENOMEM; goto err_out_release_regions; } @@ -2767,7 +2814,7 @@ jme_init_one(struct pci_dev *pdev, jme->regs = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (!(jme->regs)) { - jeprintk(pdev, "Mapping PCI resource region error.\n"); + pr_err("Mapping PCI resource region error\n"); rc = -ENOMEM; goto err_out_free_netdev; } @@ -2855,8 +2902,8 @@ jme_init_one(struct pci_dev *pdev, if (!jme->mii_if.phy_id) { rc = -EIO; - jeprintk(pdev, "Can not find phy_id.\n"); - goto err_out_unmap; + pr_err("Can not find phy_id\n"); + goto err_out_unmap; } jme->reg_ghc |= GHC_LINK_POLL; @@ -2867,6 +2914,8 @@ jme_init_one(struct pci_dev *pdev, jme->mii_if.supports_gmii = true; else jme->mii_if.supports_gmii = false; + jme->mii_if.phy_id_mask = 0x1F; + jme->mii_if.reg_num_mask = 0x1F; jme->mii_if.mdio_read = jme_mdio_read; jme->mii_if.mdio_write = jme_mdio_write; @@ -2883,8 +2932,7 @@ jme_init_one(struct pci_dev *pdev, jme_reset_mac_processor(jme); rc = jme_reload_eeprom(jme); if (rc) { - jeprintk(pdev, - "Reload eeprom for reading MAC Address error.\n"); + pr_err("Reload eeprom for reading MAC Address error\n"); goto err_out_unmap; } jme_load_macaddr(netdev); @@ -2900,7 +2948,7 @@ jme_init_one(struct pci_dev *pdev, */ rc = register_netdev(netdev); if (rc) { - jeprintk(pdev, "Cannot register net device.\n"); + pr_err("Cannot register net device\n"); goto err_out_unmap; } @@ -3006,10 +3054,12 @@ jme_resume(struct pci_dev *pdev) jme_clear_pm(jme); pci_restore_state(pdev); - if (test_bit(JME_FLAG_SSET, &jme->flags)) + if (test_bit(JME_FLAG_SSET, &jme->flags)) { + jme_phy_on(jme); jme_set_settings(netdev, &jme->old_ecmd); - else + } else { jme_reset_phy_processor(jme); + } jme_start_irq(jme); netif_device_attach(netdev); @@ -3042,8 +3092,7 @@ static struct pci_driver jme_driver = { static int __init jme_init_module(void) { - printk(KERN_INFO PFX "JMicron JMC2XX ethernet " - "driver version %s\n", DRV_VERSION); + pr_info("JMicron JMC2XX ethernet driver version %s\n", DRV_VERSION); return pci_register_driver(&jme_driver); } diff --git a/drivers/net/jme.h b/drivers/net/jme.h index 07ad3a457185c3f440c65e9d2a04cb6de1214aa3..eac09264bf2a0da8d48247df6b8e482835a5a249 100644 --- a/drivers/net/jme.h +++ b/drivers/net/jme.h @@ -3,6 +3,7 @@ * * Copyright 2008 JMicron Technology Corporation * http://www.jmicron.com/ + * Copyright (c) 2009 - 2010 Guo-Fu Tseng * * Author: Guo-Fu Tseng * @@ -25,7 +26,7 @@ #define __JME_H_INCLUDED__ #define DRV_NAME "jme" -#define DRV_VERSION "1.0.6" +#define DRV_VERSION "1.0.7" #define PFX DRV_NAME ": " #define PCI_DEVICE_ID_JMICRON_JMC250 0x0250 @@ -41,9 +42,6 @@ NETIF_MSG_TX_ERR | \ NETIF_MSG_HW) -#define jeprintk(pdev, fmt, args...) \ - printk(KERN_ERR PFX fmt, ## args) - #ifdef TX_DEBUG #define tx_dbg(priv, fmt, args...) \ printk(KERN_DEBUG "%s: " fmt, (priv)->dev->name, ##args) diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 87f0a93b165c33478e1d59aa5e23942afaccc80f..9f8e7027b0b32de8030d6e100a8b0e9467e35685 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -495,7 +495,7 @@ static u32 temac_setoptions(struct net_device *ndev, u32 options) lp->options |= options; mutex_unlock(&lp->indirect_mutex); - return (0); + return 0; } /* Initialize temac */ @@ -761,7 +761,7 @@ static void ll_temac_recv(struct net_device *ndev) skb_put(skb, length); skb->dev = ndev; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* if we're doing rx csum offload, set it up */ if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) && diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 9a0996795321b327353e7a6d28cf94a308876c01..2d9663a1c54d91b3e25246f671ab35c51b606921 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -64,7 +64,6 @@ struct pcpu_lstats { u64 packets; u64 bytes; struct u64_stats_sync syncp; - unsigned long drops; }; /* @@ -74,7 +73,6 @@ struct pcpu_lstats { static netdev_tx_t loopback_xmit(struct sk_buff *skb, struct net_device *dev) { - struct pcpu_lstats __percpu *pcpu_lstats; struct pcpu_lstats *lb_stats; int len; @@ -83,8 +81,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, skb->protocol = eth_type_trans(skb, dev); /* it's OK to use per_cpu_ptr() because BHs are off */ - pcpu_lstats = (void __percpu __force *)dev->ml_priv; - lb_stats = this_cpu_ptr(pcpu_lstats); + lb_stats = this_cpu_ptr(dev->lstats); len = skb->len; if (likely(netif_rx(skb) == NET_RX_SUCCESS)) { @@ -92,8 +89,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, lb_stats->bytes += len; lb_stats->packets++; u64_stats_update_end(&lb_stats->syncp); - } else - lb_stats->drops++; + } return NETDEV_TX_OK; } @@ -101,32 +97,26 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb, static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { - const struct pcpu_lstats __percpu *pcpu_lstats; u64 bytes = 0; u64 packets = 0; - u64 drops = 0; int i; - pcpu_lstats = (void __percpu __force *)dev->ml_priv; for_each_possible_cpu(i) { const struct pcpu_lstats *lb_stats; u64 tbytes, tpackets; unsigned int start; - lb_stats = per_cpu_ptr(pcpu_lstats, i); + lb_stats = per_cpu_ptr(dev->lstats, i); do { start = u64_stats_fetch_begin(&lb_stats->syncp); tbytes = lb_stats->bytes; tpackets = lb_stats->packets; } while (u64_stats_fetch_retry(&lb_stats->syncp, start)); - drops += lb_stats->drops; bytes += tbytes; packets += tpackets; } stats->rx_packets = packets; stats->tx_packets = packets; - stats->rx_dropped = drops; - stats->rx_errors = drops; stats->rx_bytes = bytes; stats->tx_bytes = bytes; return stats; @@ -147,22 +137,16 @@ static const struct ethtool_ops loopback_ethtool_ops = { static int loopback_dev_init(struct net_device *dev) { - struct pcpu_lstats __percpu *lstats; - - lstats = alloc_percpu(struct pcpu_lstats); - if (!lstats) + dev->lstats = alloc_percpu(struct pcpu_lstats); + if (!dev->lstats) return -ENOMEM; - dev->ml_priv = (void __force *)lstats; return 0; } static void loopback_dev_free(struct net_device *dev) { - struct pcpu_lstats __percpu *lstats = - (void __percpu __force *)dev->ml_priv; - - free_percpu(lstats); + free_percpu(dev->lstats); free_netdev(dev); } diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c index 3df046a58b1d484c11625e984b1a8b5b0420c327..3698824744cb2c44b9e30f9b6c9103a74fb629e4 100644 --- a/drivers/net/lp486e.c +++ b/drivers/net/lp486e.c @@ -460,7 +460,7 @@ init_rx_bufs(struct net_device *dev, int num) { } lp->rbd_tail->next = rfd->rbd; #endif - return (i); + return i; } static inline void diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c index 3832fa4961dd6b3ba2a3806e236a07d0ad9c4f8b..f84f5e6ededbe168173644d842b7b9c26ef21911 100644 --- a/drivers/net/mac8390.c +++ b/drivers/net/mac8390.c @@ -562,19 +562,19 @@ static int __init mac8390_initdev(struct net_device *dev, case ACCESS_16: /* 16 bit card, register map is reversed */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = slow_sane_block_input; + ei_status.block_output = slow_sane_block_output; + ei_status.get_8390_hdr = slow_sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; break; case ACCESS_32: /* 32 bit card, register map is reversed */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &sane_block_input; - ei_status.block_output = &sane_block_output; - ei_status.get_8390_hdr = &sane_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = sane_block_input; + ei_status.block_output = sane_block_output; + ei_status.get_8390_hdr = sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; access_bitmode = 1; break; @@ -586,19 +586,19 @@ static int __init mac8390_initdev(struct net_device *dev, * but overwrite system memory when run at 32 bit. * so we run them all at 16 bit. */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = slow_sane_block_input; + ei_status.block_output = slow_sane_block_output; + ei_status.get_8390_hdr = slow_sane_get_8390_hdr; ei_status.reg_offset = back4_offsets; break; case MAC8390_CABLETRON: /* 16 bit card, register map is short forward */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = slow_sane_block_input; + ei_status.block_output = slow_sane_block_output; + ei_status.get_8390_hdr = slow_sane_get_8390_hdr; ei_status.reg_offset = fwrd2_offsets; break; @@ -606,19 +606,19 @@ static int __init mac8390_initdev(struct net_device *dev, case MAC8390_KINETICS: /* 16 bit memory, register map is forward */ /* dayna and similar */ - ei_status.reset_8390 = &mac8390_no_reset; - ei_status.block_input = &dayna_block_input; - ei_status.block_output = &dayna_block_output; - ei_status.get_8390_hdr = &dayna_get_8390_hdr; + ei_status.reset_8390 = mac8390_no_reset; + ei_status.block_input = dayna_block_input; + ei_status.block_output = dayna_block_output; + ei_status.get_8390_hdr = dayna_get_8390_hdr; ei_status.reg_offset = fwrd4_offsets; break; case MAC8390_INTERLAN: /* 16 bit memory, register map is forward */ - ei_status.reset_8390 = &interlan_reset; - ei_status.block_input = &slow_sane_block_input; - ei_status.block_output = &slow_sane_block_output; - ei_status.get_8390_hdr = &slow_sane_get_8390_hdr; + ei_status.reset_8390 = interlan_reset; + ei_status.block_input = slow_sane_block_input; + ei_status.block_output = slow_sane_block_output; + ei_status.get_8390_hdr = slow_sane_get_8390_hdr; ei_status.reg_offset = fwrd4_offsets; break; diff --git a/drivers/net/macb.c b/drivers/net/macb.c index ff2f158ab0b92d88597bf68d1b1a13cf89ca4e41..4297f6e8c4bc0ab571dd571d9a6f08d5493c6e76 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -407,7 +407,7 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag, } skb_reserve(skb, RX_OFFSET); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb_put(skb, len); for (frag = first_frag; ; frag = NEXT_RX(frag)) { diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 0ef0eb0db94564dda7d0c7f28c7581db799e0e7a..0fc9dc7f20db02da7ac784c193b940453b7eccd7 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -788,6 +788,10 @@ static int macvlan_device_event(struct notifier_block *unused, } break; case NETDEV_UNREGISTER: + /* twiddle thumbs on netns device moves */ + if (dev->reg_state != NETREG_UNREGISTERING) + break; + list_for_each_entry_safe(vlan, next, &port->vlans, list) vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL); break; diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 3b1c54a9c6ef12bc255f0af833ef6de2788da219..42567279843ecfc804efd233b841338f21cef933 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -84,26 +84,45 @@ static const struct proto_ops macvtap_socket_ops; static DEFINE_SPINLOCK(macvtap_lock); /* - * Choose the next free queue, for now there is only one + * get_slot: return a [unused/occupied] slot in vlan->taps[]: + * - if 'q' is NULL, return the first empty slot; + * - otherwise, return the slot this pointer occupies. */ +static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q) +{ + int i; + + for (i = 0; i < MAX_MACVTAP_QUEUES; i++) { + if (rcu_dereference(vlan->taps[i]) == q) + return i; + } + + /* Should never happen */ + BUG_ON(1); +} + static int macvtap_set_queue(struct net_device *dev, struct file *file, struct macvtap_queue *q) { struct macvlan_dev *vlan = netdev_priv(dev); + int index; int err = -EBUSY; spin_lock(&macvtap_lock); - if (rcu_dereference(vlan->tap)) + if (vlan->numvtaps == MAX_MACVTAP_QUEUES) goto out; err = 0; + index = get_slot(vlan, NULL); rcu_assign_pointer(q->vlan, vlan); - rcu_assign_pointer(vlan->tap, q); + rcu_assign_pointer(vlan->taps[index], q); sock_hold(&q->sk); q->file = file; file->private_data = q; + vlan->numvtaps++; + out: spin_unlock(&macvtap_lock); return err; @@ -124,9 +143,12 @@ static void macvtap_put_queue(struct macvtap_queue *q) spin_lock(&macvtap_lock); vlan = rcu_dereference(q->vlan); if (vlan) { - rcu_assign_pointer(vlan->tap, NULL); + int index = get_slot(vlan, q); + + rcu_assign_pointer(vlan->taps[index], NULL); rcu_assign_pointer(q->vlan, NULL); sock_put(&q->sk); + --vlan->numvtaps; } spin_unlock(&macvtap_lock); @@ -136,39 +158,82 @@ static void macvtap_put_queue(struct macvtap_queue *q) } /* - * Since we only support one queue, just dereference the pointer. + * Select a queue based on the rxq of the device on which this packet + * arrived. If the incoming device is not mq, calculate a flow hash + * to select a queue. If all fails, find the first available queue. + * Cache vlan->numvtaps since it can become zero during the execution + * of this function. */ static struct macvtap_queue *macvtap_get_queue(struct net_device *dev, struct sk_buff *skb) { struct macvlan_dev *vlan = netdev_priv(dev); + struct macvtap_queue *tap = NULL; + int numvtaps = vlan->numvtaps; + __u32 rxq; + + if (!numvtaps) + goto out; + + if (likely(skb_rx_queue_recorded(skb))) { + rxq = skb_get_rx_queue(skb); + + while (unlikely(rxq >= numvtaps)) + rxq -= numvtaps; + + tap = rcu_dereference(vlan->taps[rxq]); + if (tap) + goto out; + } + + /* Check if we can use flow to select a queue */ + rxq = skb_get_rxhash(skb); + if (rxq) { + tap = rcu_dereference(vlan->taps[rxq % numvtaps]); + if (tap) + goto out; + } - return rcu_dereference(vlan->tap); + /* Everything failed - find first available queue */ + for (rxq = 0; rxq < MAX_MACVTAP_QUEUES; rxq++) { + tap = rcu_dereference(vlan->taps[rxq]); + if (tap) + break; + } + +out: + return tap; } /* * The net_device is going away, give up the reference - * that it holds on the queue (all the queues one day) - * and safely set the pointer from the queues to NULL. + * that it holds on all queues and safely set the pointer + * from the queues to NULL. */ static void macvtap_del_queues(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); - struct macvtap_queue *q; + struct macvtap_queue *q, *qlist[MAX_MACVTAP_QUEUES]; + int i, j = 0; + /* macvtap_put_queue can free some slots, so go through all slots */ spin_lock(&macvtap_lock); - q = rcu_dereference(vlan->tap); - if (!q) { - spin_unlock(&macvtap_lock); - return; + for (i = 0; i < MAX_MACVTAP_QUEUES && vlan->numvtaps; i++) { + q = rcu_dereference(vlan->taps[i]); + if (q) { + qlist[j++] = q; + rcu_assign_pointer(vlan->taps[i], NULL); + rcu_assign_pointer(q->vlan, NULL); + vlan->numvtaps--; + } } - - rcu_assign_pointer(vlan->tap, NULL); - rcu_assign_pointer(q->vlan, NULL); + BUG_ON(vlan->numvtaps != 0); spin_unlock(&macvtap_lock); synchronize_rcu(); - sock_put(&q->sk); + + for (--j; j >= 0; j--) + sock_put(&qlist[j]->sk); } /* diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 42e3294671d7fc743c910e19ec20dac33cd2b2fb..60135aa558025bc9f86b434aa5e8b330476dec82 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -461,7 +461,7 @@ static int meth_tx_full(struct net_device *dev) { struct meth_private *priv = netdev_priv(dev); - return (priv->tx_count >= TX_RING_ENTRIES - 1); + return priv->tx_count >= TX_RING_ENTRIES - 1; } static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status) diff --git a/drivers/net/mlx4/Makefile b/drivers/net/mlx4/Makefile index 1fd068e1d93054ad7e9d72feade1e053d9939673..d1aa45a158541b83168de0fcb8513c297ff32a6e 100644 --- a/drivers/net/mlx4/Makefile +++ b/drivers/net/mlx4/Makefile @@ -6,4 +6,4 @@ mlx4_core-y := alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \ obj-$(CONFIG_MLX4_EN) += mlx4_en.o mlx4_en-y := en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \ - en_resources.o en_netdev.o + en_resources.o en_netdev.o en_selftest.o diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c index 8c8515619b8e9b808aafbf08bdab91bb080bb17a..8f4bf1f07c11e824e8e21785f122c5d0d66775c5 100644 --- a/drivers/net/mlx4/alloc.c +++ b/drivers/net/mlx4/alloc.c @@ -74,7 +74,7 @@ void mlx4_bitmap_free(struct mlx4_bitmap *bitmap, u32 obj) u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align) { - u32 obj, i; + u32 obj; if (likely(cnt == 1 && align == 1)) return mlx4_bitmap_alloc(bitmap); @@ -91,8 +91,7 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align) } if (obj < bitmap->max) { - for (i = 0; i < cnt; i++) - set_bit(obj + i, bitmap->table); + bitmap_set(bitmap->table, obj, cnt); if (obj == bitmap->last) { bitmap->last = (obj + cnt); if (bitmap->last >= bitmap->max) @@ -109,13 +108,10 @@ u32 mlx4_bitmap_alloc_range(struct mlx4_bitmap *bitmap, int cnt, int align) void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt) { - u32 i; - obj &= bitmap->max + bitmap->reserved_top - 1; spin_lock(&bitmap->lock); - for (i = 0; i < cnt; i++) - clear_bit(obj + i, bitmap->table); + bitmap_clear(bitmap->table, obj, cnt); bitmap->last = min(bitmap->last, obj); bitmap->top = (bitmap->top + bitmap->max + bitmap->reserved_top) & bitmap->mask; @@ -125,8 +121,6 @@ void mlx4_bitmap_free_range(struct mlx4_bitmap *bitmap, u32 obj, int cnt) int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, u32 reserved_bot, u32 reserved_top) { - int i; - /* num must be a power of 2 */ if (num != roundup_pow_of_two(num)) return -EINVAL; @@ -142,8 +136,7 @@ int mlx4_bitmap_init(struct mlx4_bitmap *bitmap, u32 num, u32 mask, if (!bitmap->table) return -ENOMEM; - for (i = 0; i < reserved_bot; ++i) - set_bit(i, bitmap->table); + bitmap_set(bitmap->table, 0, reserved_bot); return 0; } @@ -188,7 +181,7 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct, buf->nbufs = (size + PAGE_SIZE - 1) / PAGE_SIZE; buf->npages = buf->nbufs; buf->page_shift = PAGE_SHIFT; - buf->page_list = kzalloc(buf->nbufs * sizeof *buf->page_list, + buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list), GFP_KERNEL); if (!buf->page_list) return -ENOMEM; diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c index b275238fe70d347dd89fa59b3152f1fc1fdc162d..056152b3ff58fc051284a7d629f7876218e8b1de 100644 --- a/drivers/net/mlx4/en_ethtool.c +++ b/drivers/net/mlx4/en_ethtool.c @@ -39,21 +39,6 @@ #include "en_port.h" -static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv) -{ - int i; - - priv->port_stats.lro_aggregated = 0; - priv->port_stats.lro_flushed = 0; - priv->port_stats.lro_no_desc = 0; - - for (i = 0; i < priv->rx_ring_num; i++) { - priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated; - priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed; - priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc; - } -} - static void mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { @@ -112,7 +97,7 @@ static const char main_strings[][ETH_GSTRING_LEN] = { "tx_heartbeat_errors", "tx_window_errors", /* port statistics */ - "lro_aggregated", "lro_flushed", "lro_no_desc", "tso_packets", + "tso_packets", "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed", "rx_csum_good", "rx_csum_none", "tx_chksum_offload", @@ -125,6 +110,14 @@ static const char main_strings[][ETH_GSTRING_LEN] = { #define NUM_MAIN_STATS 21 #define NUM_ALL_STATS (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS) +static const char mlx4_en_test_names[][ETH_GSTRING_LEN]= { + "Interupt Test", + "Link Test", + "Speed Test", + "Register Test", + "Loopback Test", +}; + static u32 mlx4_en_get_msglevel(struct net_device *dev) { return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable; @@ -146,10 +139,15 @@ static int mlx4_en_get_sset_count(struct net_device *dev, int sset) { struct mlx4_en_priv *priv = netdev_priv(dev); - if (sset != ETH_SS_STATS) + switch (sset) { + case ETH_SS_STATS: + return NUM_ALL_STATS + + (priv->tx_ring_num + priv->rx_ring_num) * 2; + case ETH_SS_TEST: + return MLX4_EN_NUM_SELF_TEST - !(priv->mdev->dev->caps.loopback_support) * 2; + default: return -EOPNOTSUPP; - - return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2; + } } static void mlx4_en_get_ethtool_stats(struct net_device *dev, @@ -161,8 +159,6 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, spin_lock_bh(&priv->stats_lock); - mlx4_en_update_lro_stats(priv); - for (i = 0; i < NUM_MAIN_STATS; i++) data[index++] = ((unsigned long *) &priv->stats)[i]; for (i = 0; i < NUM_PORT_STATS; i++) @@ -181,6 +177,12 @@ static void mlx4_en_get_ethtool_stats(struct net_device *dev, } +static void mlx4_en_self_test(struct net_device *dev, + struct ethtool_test *etest, u64 *buf) +{ + mlx4_en_ex_selftest(dev, &etest->flags, buf); +} + static void mlx4_en_get_strings(struct net_device *dev, uint32_t stringset, uint8_t *data) { @@ -188,44 +190,76 @@ static void mlx4_en_get_strings(struct net_device *dev, int index = 0; int i; - if (stringset != ETH_SS_STATS) - return; - - /* Add main counters */ - for (i = 0; i < NUM_MAIN_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); - for (i = 0; i < NUM_PORT_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, + switch (stringset) { + case ETH_SS_TEST: + for (i = 0; i < MLX4_EN_NUM_SELF_TEST - 2; i++) + strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); + if (priv->mdev->dev->caps.loopback_support) + for (; i < MLX4_EN_NUM_SELF_TEST; i++) + strcpy(data + i * ETH_GSTRING_LEN, mlx4_en_test_names[i]); + break; + + case ETH_SS_STATS: + /* Add main counters */ + for (i = 0; i < NUM_MAIN_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]); + for (i = 0; i< NUM_PORT_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i + NUM_MAIN_STATS]); - for (i = 0; i < priv->tx_ring_num; i++) { - sprintf(data + (index++) * ETH_GSTRING_LEN, - "tx%d_packets", i); - sprintf(data + (index++) * ETH_GSTRING_LEN, - "tx%d_bytes", i); - } - for (i = 0; i < priv->rx_ring_num; i++) { - sprintf(data + (index++) * ETH_GSTRING_LEN, - "rx%d_packets", i); - sprintf(data + (index++) * ETH_GSTRING_LEN, - "rx%d_bytes", i); - } - for (i = 0; i < NUM_PKT_STATS; i++) - strcpy(data + (index++) * ETH_GSTRING_LEN, + for (i = 0; i < priv->tx_ring_num; i++) { + sprintf(data + (index++) * ETH_GSTRING_LEN, + "tx%d_packets", i); + sprintf(data + (index++) * ETH_GSTRING_LEN, + "tx%d_bytes", i); + } + for (i = 0; i < priv->rx_ring_num; i++) { + sprintf(data + (index++) * ETH_GSTRING_LEN, + "rx%d_packets", i); + sprintf(data + (index++) * ETH_GSTRING_LEN, + "rx%d_bytes", i); + } + for (i = 0; i< NUM_PKT_STATS; i++) + strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]); + break; + } } static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { + struct mlx4_en_priv *priv = netdev_priv(dev); + int trans_type; + cmd->autoneg = AUTONEG_DISABLE; cmd->supported = SUPPORTED_10000baseT_Full; - cmd->advertising = ADVERTISED_1000baseT_Full; + cmd->advertising = ADVERTISED_10000baseT_Full; + + if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) + return -ENOMEM; + + trans_type = priv->port_state.transciver; if (netif_carrier_ok(dev)) { - cmd->speed = SPEED_10000; + cmd->speed = priv->port_state.link_speed; cmd->duplex = DUPLEX_FULL; } else { cmd->speed = -1; cmd->duplex = -1; } + + if (trans_type > 0 && trans_type <= 0xC) { + cmd->port = PORT_FIBRE; + cmd->transceiver = XCVR_EXTERNAL; + cmd->supported |= SUPPORTED_FIBRE; + cmd->advertising |= ADVERTISED_FIBRE; + } else if (trans_type == 0x80 || trans_type == 0) { + cmd->port = PORT_TP; + cmd->transceiver = XCVR_INTERNAL; + cmd->supported |= SUPPORTED_TP; + cmd->advertising |= ADVERTISED_TP; + } else { + cmd->port = -1; + cmd->transceiver = -1; + } return 0; } @@ -343,8 +377,9 @@ static int mlx4_en_set_ringparam(struct net_device *dev, tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE); tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE); - if (rx_size == priv->prof->rx_ring_size && - tx_size == priv->prof->tx_ring_size) + if (rx_size == (priv->port_up ? priv->rx_ring[0].actual_size : + priv->rx_ring[0].size) && + tx_size == priv->tx_ring[0].size) return 0; mutex_lock(&mdev->state_lock); @@ -378,49 +413,13 @@ static void mlx4_en_get_ringparam(struct net_device *dev, struct ethtool_ringparam *param) { struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; memset(param, 0, sizeof(*param)); param->rx_max_pending = MLX4_EN_MAX_RX_SIZE; param->tx_max_pending = MLX4_EN_MAX_TX_SIZE; - param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size; - param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size; -} - -static int mlx4_ethtool_op_set_flags(struct net_device *dev, u32 data) -{ - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - int rc = 0; - int changed = 0; - - if (data & ~ETH_FLAG_LRO) - return -EOPNOTSUPP; - - if (data & ETH_FLAG_LRO) { - if (mdev->profile.num_lro == 0) - return -EOPNOTSUPP; - if (!(dev->features & NETIF_F_LRO)) - changed = 1; - } else if (dev->features & NETIF_F_LRO) { - changed = 1; - } - - if (changed) { - if (netif_running(dev)) { - mutex_lock(&mdev->state_lock); - mlx4_en_stop_port(dev); - } - dev->features ^= NETIF_F_LRO; - if (netif_running(dev)) { - rc = mlx4_en_start_port(dev); - if (rc) - en_err(priv, "Failed to restart port\n"); - mutex_unlock(&mdev->state_lock); - } - } - - return rc; + param->rx_pending = priv->port_up ? + priv->rx_ring[0].actual_size : priv->rx_ring[0].size; + param->tx_pending = priv->tx_ring[0].size; } const struct ethtool_ops mlx4_en_ethtool_ops = { @@ -441,6 +440,7 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_strings = mlx4_en_get_strings, .get_sset_count = mlx4_en_get_sset_count, .get_ethtool_stats = mlx4_en_get_ethtool_stats, + .self_test = mlx4_en_self_test, .get_wol = mlx4_en_get_wol, .get_msglevel = mlx4_en_get_msglevel, .set_msglevel = mlx4_en_set_msglevel, @@ -451,7 +451,6 @@ const struct ethtool_ops mlx4_en_ethtool_ops = { .get_ringparam = mlx4_en_get_ringparam, .set_ringparam = mlx4_en_set_ringparam, .get_flags = ethtool_op_get_flags, - .set_flags = mlx4_ethtool_op_set_flags, }; diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c index 97934f1ec53af83c0dfe40e3b9e8730c83ae1c1e..14390641704881ffb71ded6fd2d19118be07a4d6 100644 --- a/drivers/net/mlx4/en_main.c +++ b/drivers/net/mlx4/en_main.c @@ -63,15 +63,12 @@ static const char mlx4_en_version[] = */ -/* Use a XOR rathern than Toeplitz hash function for RSS */ -MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS"); - -/* RSS hash type mask - default to */ -MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask"); - -/* Number of LRO sessions per Rx ring (rounded up to a power of two) */ -MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS, - "Number of LRO sessions per ring or disabled (0)"); +/* Enable RSS TCP traffic */ +MLX4_EN_PARM_INT(tcp_rss, 1, + "Enable RSS for incomming TCP traffic or disabled (0)"); +/* Enable RSS UDP traffic */ +MLX4_EN_PARM_INT(udp_rss, 1, + "Enable RSS for incomming UDP traffic or disabled (0)"); /* Priority pausing */ MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]." @@ -107,9 +104,12 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev) struct mlx4_en_profile *params = &mdev->profile; int i; - params->rss_xor = (rss_xor != 0); - params->rss_mask = rss_mask & 0x1f; - params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS); + params->tcp_rss = tcp_rss; + params->udp_rss = udp_rss; + if (params->udp_rss && !mdev->dev->caps.udp_rss) { + mlx4_warn(mdev, "UDP RSS is not supported on this device.\n"); + params->udp_rss = 0; + } for (i = 1; i <= MLX4_MAX_PORTS; i++) { params->prof[i].rx_pause = 1; params->prof[i].rx_ppp = pfcrx; diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c index a0d8a26f5a025be35c67ff29b4a124f34ceb1c78..79478bd4211a958b369f9c8882351e3bcbb89424 100644 --- a/drivers/net/mlx4/en_netdev.c +++ b/drivers/net/mlx4/en_netdev.c @@ -109,7 +109,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) mutex_unlock(&mdev->state_lock); } -static u64 mlx4_en_mac_to_u64(u8 *addr) +u64 mlx4_en_mac_to_u64(u8 *addr) { u64 mac = 0; int i; @@ -513,6 +513,10 @@ static void mlx4_en_do_get_stats(struct work_struct *work) queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); } + if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) { + queue_work(mdev->workqueue, &priv->mac_task); + mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0; + } mutex_unlock(&mdev->state_lock); } @@ -528,10 +532,10 @@ static void mlx4_en_linkstate(struct work_struct *work) * report to system log */ if (priv->last_link_state != linkstate) { if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) { - en_dbg(LINK, priv, "Link Down\n"); + en_info(priv, "Link Down\n"); netif_carrier_off(priv->dev); } else { - en_dbg(LINK, priv, "Link Up\n"); + en_info(priv, "Link Up\n"); netif_carrier_on(priv->dev); } } @@ -653,6 +657,7 @@ int mlx4_en_start_port(struct net_device *dev) en_err(priv, "Failed setting port mac\n"); goto tx_err; } + mdev->mac_removed[priv->port] = 0; /* Init port */ en_dbg(HW, priv, "Initializing port\n"); @@ -704,12 +709,12 @@ void mlx4_en_stop_port(struct net_device *dev) netif_tx_stop_all_queues(dev); netif_tx_unlock_bh(dev); - /* close port*/ + /* Set port as not active */ priv->port_up = false; - mlx4_CLOSE_PORT(mdev->dev, priv->port); /* Unregister Mac address for the port */ mlx4_unregister_mac(mdev->dev, priv->port, priv->mac_index); + mdev->mac_removed[priv->port] = 1; /* Free TX Rings */ for (i = 0; i < priv->tx_ring_num; i++) { @@ -731,6 +736,9 @@ void mlx4_en_stop_port(struct net_device *dev) msleep(1); mlx4_en_deactivate_cq(priv, &priv->rx_cq[i]); } + + /* close port*/ + mlx4_CLOSE_PORT(mdev->dev, priv->port); } static void mlx4_en_restart(struct work_struct *work) @@ -1017,15 +1025,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, */ dev->netdev_ops = &mlx4_netdev_ops; dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT; - dev->real_num_tx_queues = MLX4_EN_NUM_TX_RINGS; + netif_set_real_num_tx_queues(dev, priv->tx_ring_num); + netif_set_real_num_rx_queues(dev, priv->rx_ring_num); SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops); /* Set defualt MAC */ dev->addr_len = ETH_ALEN; - for (i = 0; i < ETH_ALEN; i++) - dev->dev_addr[ETH_ALEN - 1 - i] = - (u8) (priv->mac >> (8 * i)); + for (i = 0; i < ETH_ALEN; i++) { + dev->dev_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i)); + dev->perm_addr[ETH_ALEN - 1 - i] = (u8) (priv->mac >> (8 * i)); + } /* * Set driver features @@ -1038,8 +1048,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER; - if (mdev->profile.num_lro) - dev->features |= NETIF_F_LRO; + dev->features |= NETIF_F_GRO; if (mdev->LSO_support) { dev->features |= NETIF_F_TSO; dev->features |= NETIF_F_TSO6; diff --git a/drivers/net/mlx4/en_port.c b/drivers/net/mlx4/en_port.c index a29abe845d2e83d2d61e6087c8ed489abcdc123d..aa3ef2aee5bf8435575a6f75a8e65502ebc09456 100644 --- a/drivers/net/mlx4/en_port.c +++ b/drivers/net/mlx4/en_port.c @@ -142,6 +142,38 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, return err; } +int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port) +{ + struct mlx4_en_query_port_context *qport_context; + struct mlx4_en_priv *priv = netdev_priv(mdev->pndev[port]); + struct mlx4_en_port_state *state = &priv->port_state; + struct mlx4_cmd_mailbox *mailbox; + int err; + + mailbox = mlx4_alloc_cmd_mailbox(mdev->dev); + if (IS_ERR(mailbox)) + return PTR_ERR(mailbox); + memset(mailbox->buf, 0, sizeof(*qport_context)); + err = mlx4_cmd_box(mdev->dev, 0, mailbox->dma, port, 0, + MLX4_CMD_QUERY_PORT, MLX4_CMD_TIME_CLASS_B); + if (err) + goto out; + qport_context = mailbox->buf; + + /* This command is always accessed from Ethtool context + * already synchronized, no need in locking */ + state->link_state = !!(qport_context->link_up & MLX4_EN_LINK_UP_MASK); + if ((qport_context->link_speed & MLX4_EN_SPEED_MASK) == + MLX4_EN_1G_SPEED) + state->link_speed = 1000; + else + state->link_speed = 10000; + state->transciver = qport_context->transceiver; + +out: + mlx4_free_cmd_mailbox(mdev->dev, mailbox); + return err; +} int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset) { diff --git a/drivers/net/mlx4/en_port.h b/drivers/net/mlx4/en_port.h index e6477f12beb53618db726076584d2dbfc803989a..f6511aa2b7dfba0a8fca919f606189be9b3a2a5b 100644 --- a/drivers/net/mlx4/en_port.h +++ b/drivers/net/mlx4/en_port.h @@ -84,6 +84,20 @@ enum { MLX4_MCAST_ENABLE = 2, }; +struct mlx4_en_query_port_context { + u8 link_up; +#define MLX4_EN_LINK_UP_MASK 0x80 + u8 reserved; + __be16 mtu; + u8 reserved2; + u8 link_speed; +#define MLX4_EN_SPEED_MASK 0x3 +#define MLX4_EN_1G_SPEED 0x2 + u16 reserved3[5]; + __be64 mac; + u8 transceiver; +}; + struct mlx4_en_stat_out_mbox { /* Received frames with a length of 64 octets */ diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c index 8e2fcb7103c3a12a3072549881a7529d3062bc85..570f2508fb30b423982ae14f228ef1e3539f13b4 100644 --- a/drivers/net/mlx4/en_rx.c +++ b/drivers/net/mlx4/en_rx.c @@ -42,18 +42,6 @@ #include "mlx4_en.h" -static int mlx4_en_get_frag_header(struct skb_frag_struct *frags, void **mac_hdr, - void **ip_hdr, void **tcpudp_hdr, - u64 *hdr_flags, void *priv) -{ - *mac_hdr = page_address(frags->page) + frags->page_offset; - *ip_hdr = *mac_hdr + ETH_HLEN; - *tcpudp_hdr = (struct tcphdr *)(*ip_hdr + sizeof(struct iphdr)); - *hdr_flags = LRO_IPV4 | LRO_TCP; - - return 0; -} - static int mlx4_en_alloc_frag(struct mlx4_en_priv *priv, struct mlx4_en_rx_desc *rx_desc, struct skb_frag_struct *skb_frags, @@ -251,7 +239,6 @@ static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv) ring->prod--; mlx4_en_free_rx_desc(priv, ring, ring->actual_size); } - ring->size_mask = ring->actual_size - 1; } return 0; @@ -313,28 +300,8 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, } ring->buf = ring->wqres.buf.direct.buf; - /* Configure lro mngr */ - memset(&ring->lro, 0, sizeof(struct net_lro_mgr)); - ring->lro.dev = priv->dev; - ring->lro.features = LRO_F_NAPI; - ring->lro.frag_align_pad = NET_IP_ALIGN; - ring->lro.ip_summed = CHECKSUM_UNNECESSARY; - ring->lro.ip_summed_aggr = CHECKSUM_UNNECESSARY; - ring->lro.max_desc = mdev->profile.num_lro; - ring->lro.max_aggr = MAX_SKB_FRAGS; - ring->lro.lro_arr = kzalloc(mdev->profile.num_lro * - sizeof(struct net_lro_desc), - GFP_KERNEL); - if (!ring->lro.lro_arr) { - en_err(priv, "Failed to allocate lro array\n"); - goto err_map; - } - ring->lro.get_frag_header = mlx4_en_get_frag_header; - return 0; -err_map: - mlx4_en_unmap_buffer(&ring->wqres.buf); err_hwq: mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size); err_ring: @@ -389,6 +356,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv) for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) { ring = &priv->rx_ring[ring_ind]; + ring->size_mask = ring->actual_size - 1; mlx4_en_update_rx_prod_db(ring); } @@ -412,7 +380,6 @@ void mlx4_en_destroy_rx_ring(struct mlx4_en_priv *priv, { struct mlx4_en_dev *mdev = priv->mdev; - kfree(ring->lro.lro_arr); mlx4_en_unmap_buffer(&ring->wqres.buf); mlx4_free_hwq_res(mdev->dev, &ring->wqres, ring->buf_size + TXBB_SIZE); vfree(ring->rx_info); @@ -459,7 +426,7 @@ static int mlx4_en_complete_rx_desc(struct mlx4_en_priv *priv, goto fail; /* Unmap buffer */ - pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size, + pci_unmap_single(mdev->pdev, dma, skb_frags_rx[nr].size, PCI_DMA_FROMDEVICE); } /* Adjust size of last fragment to match actual length */ @@ -541,6 +508,21 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv, return skb; } +static void validate_loopback(struct mlx4_en_priv *priv, struct sk_buff *skb) +{ + int i; + int offset = ETH_HLEN; + + for (i = 0; i < MLX4_LOOPBACK_TEST_PAYLOAD; i++, offset++) { + if (*(skb->data + offset) != (unsigned char) (i & 0xff)) + goto out_loopback; + } + /* Loopback found */ + priv->loopback_ok = 1; + +out_loopback: + dev_kfree_skb_any(skb); +} int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget) { @@ -548,7 +530,6 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud struct mlx4_cqe *cqe; struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring]; struct skb_frag_struct *skb_frags; - struct skb_frag_struct lro_frags[MLX4_EN_MAX_RX_FRAGS]; struct mlx4_en_rx_desc *rx_desc; struct sk_buff *skb; int index; @@ -608,37 +589,35 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud * - TCP/IP (v4) * - without IP options * - not an IP fragment */ - if (mlx4_en_can_lro(cqe->status) && - dev->features & NETIF_F_LRO) { + if (dev->features & NETIF_F_GRO) { + struct sk_buff *gro_skb = napi_get_frags(&cq->napi); + if (!gro_skb) + goto next; nr = mlx4_en_complete_rx_desc( priv, rx_desc, - skb_frags, lro_frags, + skb_frags, skb_shinfo(gro_skb)->frags, ring->page_alloc, length); if (!nr) goto next; + skb_shinfo(gro_skb)->nr_frags = nr; + gro_skb->len = length; + gro_skb->data_len = length; + gro_skb->truesize += length; + gro_skb->ip_summed = CHECKSUM_UNNECESSARY; + if (priv->vlgrp && (cqe->vlan_my_qpn & - cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) { - lro_vlan_hwaccel_receive_frags( - &ring->lro, lro_frags, - length, length, - priv->vlgrp, - be16_to_cpu(cqe->sl_vid), - NULL, 0); - } else - lro_receive_frags(&ring->lro, - lro_frags, - length, - length, - NULL, 0); + cpu_to_be32(MLX4_CQE_VLAN_PRESENT_MASK))) + vlan_gro_frags(&cq->napi, priv->vlgrp, be16_to_cpu(cqe->sl_vid)); + else + napi_gro_frags(&cq->napi); goto next; } /* LRO not possible, complete processing here */ ip_summed = CHECKSUM_UNNECESSARY; - INC_PERF_COUNTER(priv->pstats.lro_misses); } else { ip_summed = CHECKSUM_NONE; priv->port_stats.rx_chksum_none++; @@ -655,6 +634,11 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud goto next; } + if (unlikely(priv->validate_loopback)) { + validate_loopback(priv, skb); + goto next; + } + skb->ip_summed = ip_summed; skb->protocol = eth_type_trans(skb, dev); skb_record_rx_queue(skb, cq->ring); @@ -674,14 +658,10 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud if (++polled == budget) { /* We are here because we reached the NAPI budget - * flush only pending LRO sessions */ - lro_flush_all(&ring->lro); goto out; } } - /* If CQ is empty flush all LRO sessions unconditionally */ - lro_flush_all(&ring->lro); - out: AVG_PERF_COUNTER(priv->pstats.rx_coal_avg, polled); mlx4_cq_set_ci(&cq->mcq); @@ -816,7 +796,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn, qp->event = mlx4_en_sqp_event; memset(context, 0, sizeof *context); - mlx4_en_fill_qp_context(priv, ring->size, ring->stride, 0, 0, + mlx4_en_fill_qp_context(priv, ring->actual_size, ring->stride, 0, 0, qpn, ring->cqn, context); context->db_rec_addr = cpu_to_be64(ring->wqres.db.dma); @@ -839,8 +819,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) struct mlx4_qp_context context; struct mlx4_en_rss_context *rss_context; void *ptr; - int rss_xor = mdev->profile.rss_xor; - u8 rss_mask = mdev->profile.rss_mask; + u8 rss_mask = 0x3f; int i, qpn; int err = 0; int good_qps = 0; @@ -886,9 +865,10 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 | (rss_map->base_qpn)); rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn); - rss_context->hash_fn = rss_xor & 0x3; - rss_context->flags = rss_mask << 2; + rss_context->flags = rss_mask; + if (priv->mdev->profile.udp_rss) + rss_context->base_qpn_udp = rss_context->default_qpn; err = mlx4_qp_to_ready(mdev->dev, &priv->res.mtt, &context, &rss_map->indir_qp, &rss_map->indir_state); if (err) diff --git a/drivers/net/mlx4/en_selftest.c b/drivers/net/mlx4/en_selftest.c new file mode 100644 index 0000000000000000000000000000000000000000..9c91a92da705fb313ff810cb08e68a032f846476 --- /dev/null +++ b/drivers/net/mlx4/en_selftest.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2007 Mellanox Technologies. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include +#include +#include +#include +#include + +#include "mlx4_en.h" + + +static int mlx4_en_test_registers(struct mlx4_en_priv *priv) +{ + return mlx4_cmd(priv->mdev->dev, 0, 0, 0, MLX4_CMD_HW_HEALTH_CHECK, + MLX4_CMD_TIME_CLASS_A); +} + +static int mlx4_en_test_loopback_xmit(struct mlx4_en_priv *priv) +{ + struct sk_buff *skb; + struct ethhdr *ethh; + unsigned char *packet; + unsigned int packet_size = MLX4_LOOPBACK_TEST_PAYLOAD; + unsigned int i; + int err; + + + /* build the pkt before xmit */ + skb = netdev_alloc_skb(priv->dev, MLX4_LOOPBACK_TEST_PAYLOAD + ETH_HLEN + NET_IP_ALIGN); + if (!skb) { + en_err(priv, "-LOOPBACK_TEST_XMIT- failed to create skb for xmit\n"); + return -ENOMEM; + } + skb_reserve(skb, NET_IP_ALIGN); + + ethh = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr)); + packet = (unsigned char *)skb_put(skb, packet_size); + memcpy(ethh->h_dest, priv->dev->dev_addr, ETH_ALEN); + memset(ethh->h_source, 0, ETH_ALEN); + ethh->h_proto = htons(ETH_P_ARP); + skb_set_mac_header(skb, 0); + for (i = 0; i < packet_size; ++i) /* fill our packet */ + packet[i] = (unsigned char)(i & 0xff); + + /* xmit the pkt */ + err = mlx4_en_xmit(skb, priv->dev); + return err; +} + +static int mlx4_en_test_loopback(struct mlx4_en_priv *priv) +{ + u32 loopback_ok = 0; + int i; + + + priv->loopback_ok = 0; + priv->validate_loopback = 1; + + /* xmit */ + if (mlx4_en_test_loopback_xmit(priv)) { + en_err(priv, "Transmitting loopback packet failed\n"); + goto mlx4_en_test_loopback_exit; + } + + /* polling for result */ + for (i = 0; i < MLX4_EN_LOOPBACK_RETRIES; ++i) { + msleep(MLX4_EN_LOOPBACK_TIMEOUT); + if (priv->loopback_ok) { + loopback_ok = 1; + break; + } + } + if (!loopback_ok) + en_err(priv, "Loopback packet didn't arrive\n"); + +mlx4_en_test_loopback_exit: + + priv->validate_loopback = 0; + return !loopback_ok; +} + + +static int mlx4_en_test_link(struct mlx4_en_priv *priv) +{ + if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) + return -ENOMEM; + if (priv->port_state.link_state == 1) + return 0; + else + return 1; +} + +static int mlx4_en_test_speed(struct mlx4_en_priv *priv) +{ + + if (mlx4_en_QUERY_PORT(priv->mdev, priv->port)) + return -ENOMEM; + + /* The device currently only supports 10G speed */ + if (priv->port_state.link_speed != SPEED_10000) + return priv->port_state.link_speed; + return 0; +} + + +void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + struct mlx4_en_tx_ring *tx_ring; + int i, carrier_ok; + + memset(buf, 0, sizeof(u64) * MLX4_EN_NUM_SELF_TEST); + + if (*flags & ETH_TEST_FL_OFFLINE) { + /* disable the interface */ + carrier_ok = netif_carrier_ok(dev); + + netif_carrier_off(dev); +retry_tx: + /* Wait untill all tx queues are empty. + * there should not be any additional incoming traffic + * since we turned the carrier off */ + msleep(200); + for (i = 0; i < priv->tx_ring_num && carrier_ok; i++) { + tx_ring = &priv->tx_ring[i]; + if (tx_ring->prod != (tx_ring->cons + tx_ring->last_nr_txbb)) + goto retry_tx; + } + + if (priv->mdev->dev->caps.loopback_support){ + buf[3] = mlx4_en_test_registers(priv); + buf[4] = mlx4_en_test_loopback(priv); + } + + if (carrier_ok) + netif_carrier_on(dev); + + } + buf[0] = mlx4_test_interrupts(mdev->dev); + buf[1] = mlx4_en_test_link(priv); + buf[2] = mlx4_en_test_speed(priv); + + for (i = 0; i < MLX4_EN_NUM_SELF_TEST; i++) { + if (buf[i]) + *flags |= ETH_TEST_FL_FAILED; + } +} diff --git a/drivers/net/mlx4/en_tx.c b/drivers/net/mlx4/en_tx.c index 580968f304eb9d24f752e38fc368e64208700510..a680cd4a5ab66de803116ba69d7603f1919ceebe 100644 --- a/drivers/net/mlx4/en_tx.c +++ b/drivers/net/mlx4/en_tx.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "mlx4_en.h" @@ -582,7 +583,7 @@ u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb) /* If we support per priority flow control and the packet contains * a vlan tag, send the packet to the TX ring assigned to that priority */ - if (priv->prof->rx_ppp && priv->vlgrp && vlan_tx_tag_present(skb)) { + if (priv->prof->rx_ppp && vlan_tx_tag_present(skb)) { vlan_tag = vlan_tx_tag_get(skb); return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13); } @@ -600,6 +601,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) struct mlx4_wqe_data_seg *data; struct skb_frag_struct *frag; struct mlx4_en_tx_info *tx_info; + struct ethhdr *ethh; + u64 mac; + u32 mac_l, mac_h; int tx_ind = 0; int nr_txbb; int desc_size; @@ -612,6 +616,9 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) int lso_header_size; void *fragptr; + if (!priv->port_up) + goto tx_drop; + real_size = get_real_size(skb, dev, &lso_header_size); if (unlikely(!real_size)) goto tx_drop; @@ -627,7 +634,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) tx_ind = skb->queue_mapping; ring = &priv->tx_ring[tx_ind]; - if (priv->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = vlan_tx_tag_get(skb); /* Check available TXBBs And 2K spare for prefetch */ @@ -676,6 +683,19 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) priv->port_stats.tx_chksum_offload++; } + if (unlikely(priv->validate_loopback)) { + /* Copy dst mac address to wqe */ + skb_reset_mac_header(skb); + ethh = eth_hdr(skb); + if (ethh && ethh->h_dest) { + mac = mlx4_en_mac_to_u64(ethh->h_dest); + mac_h = (u32) ((mac & 0xffff00000000ULL) >> 16); + mac_l = (u32) (mac & 0xffffffff); + tx_desc->ctrl.srcrb_flags |= cpu_to_be32(mac_h); + tx_desc->ctrl.imm = cpu_to_be32(mac_l); + } + } + /* Handle LSO (TSO) packets */ if (lso_header_size) { /* Mark opcode as LSO */ diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 6d7b2bf210ceb8818a811699d179819304df8510..552d0fce6f671a50da289aa5b7d96f5ce05fb874 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -699,3 +699,47 @@ void mlx4_cleanup_eq_table(struct mlx4_dev *dev) kfree(priv->eq_table.uar_map); } + +/* A test that verifies that we can accept interrupts on all + * the irq vectors of the device. + * Interrupts are checked using the NOP command. + */ +int mlx4_test_interrupts(struct mlx4_dev *dev) +{ + struct mlx4_priv *priv = mlx4_priv(dev); + int i; + int err; + + err = mlx4_NOP(dev); + /* When not in MSI_X, there is only one irq to check */ + if (!(dev->flags & MLX4_FLAG_MSI_X)) + return err; + + /* A loop over all completion vectors, for each vector we will check + * whether it works by mapping command completions to that vector + * and performing a NOP command + */ + for(i = 0; !err && (i < dev->caps.num_comp_vectors); ++i) { + /* Temporary use polling for command completions */ + mlx4_cmd_use_polling(dev); + + /* Map the new eq to handle all asyncronous events */ + err = mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, + priv->eq_table.eq[i].eqn); + if (err) { + mlx4_warn(dev, "Failed mapping eq for interrupt test\n"); + mlx4_cmd_use_events(dev); + break; + } + + /* Go back to using events */ + mlx4_cmd_use_events(dev); + err = mlx4_NOP(dev); + } + + /* Return to default */ + mlx4_MAP_EQ(dev, MLX4_ASYNC_EVENT_MASK, 0, + priv->eq_table.eq[dev->caps.num_comp_vectors].eqn); + return err; +} +EXPORT_SYMBOL(mlx4_test_interrupts); diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index 04f42ae1eda092d9650af5ef23d16a1b9efdbf52..b716e1a1b2982bae0f25b1ed57793c3ccc31aaa7 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -141,6 +141,7 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) struct mlx4_cmd_mailbox *mailbox; u32 *outbox; u8 field; + u32 field32; u16 size; u16 stat_rate; int err; @@ -178,6 +179,8 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_DEV_CAP_MAX_GID_OFFSET 0x3b #define QUERY_DEV_CAP_RATE_SUPPORT_OFFSET 0x3c #define QUERY_DEV_CAP_MAX_PKEY_OFFSET 0x3f +#define QUERY_DEV_CAP_UDP_RSS_OFFSET 0x42 +#define QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET 0x43 #define QUERY_DEV_CAP_FLAGS_OFFSET 0x44 #define QUERY_DEV_CAP_RSVD_UAR_OFFSET 0x48 #define QUERY_DEV_CAP_UAR_SZ_OFFSET 0x49 @@ -268,6 +271,10 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->max_msg_sz = 1 << (field & 0x1f); MLX4_GET(stat_rate, outbox, QUERY_DEV_CAP_RATE_SUPPORT_OFFSET); dev_cap->stat_rate_support = stat_rate; + MLX4_GET(field, outbox, QUERY_DEV_CAP_UDP_RSS_OFFSET); + dev_cap->udp_rss = field & 0x1; + MLX4_GET(field, outbox, QUERY_DEV_CAP_ETH_UC_LOOPBACK_OFFSET); + dev_cap->loopback_support = field & 0x1; MLX4_GET(dev_cap->flags, outbox, QUERY_DEV_CAP_FLAGS_OFFSET); MLX4_GET(field, outbox, QUERY_DEV_CAP_RSVD_UAR_OFFSET); dev_cap->reserved_uars = field >> 4; @@ -365,6 +372,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) #define QUERY_PORT_MAX_MACVLAN_OFFSET 0x0a #define QUERY_PORT_MAX_VL_OFFSET 0x0b #define QUERY_PORT_MAC_OFFSET 0x10 +#define QUERY_PORT_TRANS_VENDOR_OFFSET 0x18 +#define QUERY_PORT_WAVELENGTH_OFFSET 0x1c +#define QUERY_PORT_TRANS_CODE_OFFSET 0x20 for (i = 1; i <= dev_cap->num_ports; ++i) { err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT, @@ -388,6 +398,11 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev_cap->log_max_vlans[i] = field >> 4; MLX4_GET(dev_cap->eth_mtu[i], outbox, QUERY_PORT_ETH_MTU_OFFSET); MLX4_GET(dev_cap->def_mac[i], outbox, QUERY_PORT_MAC_OFFSET); + MLX4_GET(field32, outbox, QUERY_PORT_TRANS_VENDOR_OFFSET); + dev_cap->trans_type[i] = field32 >> 24; + dev_cap->vendor_oui[i] = field32 & 0xffffff; + MLX4_GET(dev_cap->wavelength[i], outbox, QUERY_PORT_WAVELENGTH_OFFSET); + MLX4_GET(dev_cap->trans_code[i], outbox, QUERY_PORT_TRANS_CODE_OFFSET); } } diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h index 526d7f30c041849da3b27077bbb8d9007222a5aa..65cc72eb899d0491d53b844a0014d6106bee0c6c 100644 --- a/drivers/net/mlx4/fw.h +++ b/drivers/net/mlx4/fw.h @@ -73,7 +73,13 @@ struct mlx4_dev_cap { int max_pkeys[MLX4_MAX_PORTS + 1]; u64 def_mac[MLX4_MAX_PORTS + 1]; u16 eth_mtu[MLX4_MAX_PORTS + 1]; + int trans_type[MLX4_MAX_PORTS + 1]; + int vendor_oui[MLX4_MAX_PORTS + 1]; + u16 wavelength[MLX4_MAX_PORTS + 1]; + u64 trans_code[MLX4_MAX_PORTS + 1]; u16 stat_rate_support; + int udp_rss; + int loopback_support; u32 flags; int reserved_uars; int uar_size; diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 5102ab1ac561dbaece380465a9806d886d29f651..569fa3df381f8131bb6b91454a577bde8314500b 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -184,6 +184,10 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.eth_mtu_cap[i] = dev_cap->eth_mtu[i]; dev->caps.def_mac[i] = dev_cap->def_mac[i]; dev->caps.supported_type[i] = dev_cap->supported_port_types[i]; + dev->caps.trans_type[i] = dev_cap->trans_type[i]; + dev->caps.vendor_oui[i] = dev_cap->vendor_oui[i]; + dev->caps.wavelength[i] = dev_cap->wavelength[i]; + dev->caps.trans_code[i] = dev_cap->trans_code[i]; } dev->caps.num_uars = dev_cap->uar_size / PAGE_SIZE; @@ -221,6 +225,8 @@ static int mlx4_dev_cap(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap) dev->caps.bmme_flags = dev_cap->bmme_flags; dev->caps.reserved_lkey = dev_cap->reserved_lkey; dev->caps.stat_rate_support = dev_cap->stat_rate_support; + dev->caps.udp_rss = dev_cap->udp_rss; + dev->caps.loopback_support = dev_cap->loopback_support; dev->caps.max_gso_sz = dev_cap->max_gso_sz; dev->caps.log_num_macs = log_num_mac; diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h index 449210994ee9cee94323fb3646af114aa4ca3619..1fc16ab7ad2f0ebc0d6b7b6d604e593ceb223e69 100644 --- a/drivers/net/mlx4/mlx4_en.h +++ b/drivers/net/mlx4/mlx4_en.h @@ -38,19 +38,19 @@ #include #include #include -#include #include #include #include #include #include +#include #include "en_port.h" #define DRV_NAME "mlx4_en" -#define DRV_VERSION "1.4.1.1" -#define DRV_RELDATE "June 2009" +#define DRV_VERSION "1.5.1.6" +#define DRV_RELDATE "August 2010" #define MLX4_EN_MSG_LEVEL (NETIF_MSG_LINK | NETIF_MSG_IFDOWN) @@ -61,7 +61,6 @@ #define MLX4_EN_PAGE_SHIFT 12 #define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT) -#define MAX_TX_RINGS 16 #define MAX_RX_RINGS 16 #define TXBB_SIZE 64 #define HEADROOM (2048 / TXBB_SIZE + 1) @@ -107,6 +106,7 @@ enum { #define MLX4_EN_SMALL_PKT_SIZE 64 #define MLX4_EN_NUM_TX_RINGS 8 #define MLX4_EN_NUM_PPP_RINGS 8 +#define MAX_TX_RINGS (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS) #define MLX4_EN_DEF_TX_RING_SIZE 512 #define MLX4_EN_DEF_RX_RING_SIZE 1024 @@ -139,10 +139,14 @@ enum { #define SMALL_PACKET_SIZE (256 - NET_IP_ALIGN) #define HEADER_COPY_SIZE (128 - NET_IP_ALIGN) +#define MLX4_LOOPBACK_TEST_PAYLOAD (HEADER_COPY_SIZE - ETH_HLEN) #define MLX4_EN_MIN_MTU 46 #define ETH_BCAST 0xffffffffffffULL +#define MLX4_EN_LOOPBACK_RETRIES 5 +#define MLX4_EN_LOOPBACK_TIMEOUT 100 + #ifdef MLX4_EN_PERF_STAT /* Number of samples to 'average' */ #define AVG_SIZE 128 @@ -249,7 +253,6 @@ struct mlx4_en_rx_desc { struct mlx4_en_rx_ring { struct mlx4_hwq_resources wqres; struct mlx4_en_rx_alloc page_alloc[MLX4_EN_MAX_RX_FRAGS]; - struct net_lro_mgr lro; u32 size ; /* number of Rx descs*/ u32 actual_size; u32 size_mask; @@ -313,7 +316,8 @@ struct mlx4_en_port_profile { struct mlx4_en_profile { int rss_xor; - int num_lro; + int tcp_rss; + int udp_rss; u8 rss_mask; u32 active_ports; u32 small_pkt_int; @@ -337,6 +341,7 @@ struct mlx4_en_dev { struct mlx4_mr mr; u32 priv_pdn; spinlock_t uar_lock; + u8 mac_removed[MLX4_MAX_PORTS + 1]; }; @@ -355,6 +360,13 @@ struct mlx4_en_rss_context { u8 hash_fn; u8 flags; __be32 rss_key[10]; + __be32 base_qpn_udp; +}; + +struct mlx4_en_port_state { + int link_state; + int link_speed; + int transciver; }; struct mlx4_en_pkt_stats { @@ -365,9 +377,6 @@ struct mlx4_en_pkt_stats { }; struct mlx4_en_port_stats { - unsigned long lro_aggregated; - unsigned long lro_flushed; - unsigned long lro_no_desc; unsigned long tso_packets; unsigned long queue_stopped; unsigned long wake_queue; @@ -376,7 +385,7 @@ struct mlx4_en_port_stats { unsigned long rx_chksum_good; unsigned long rx_chksum_none; unsigned long tx_chksum_offload; -#define NUM_PORT_STATS 11 +#define NUM_PORT_STATS 8 }; struct mlx4_en_perf_stats { @@ -405,6 +414,7 @@ struct mlx4_en_priv { struct vlan_group *vlgrp; struct net_device_stats stats; struct net_device_stats ret_stats; + struct mlx4_en_port_state port_state; spinlock_t stats_lock; unsigned long last_moder_packets; @@ -423,6 +433,8 @@ struct mlx4_en_priv { u16 sample_interval; u16 adaptive_rx_coal; u32 msg_enable; + u32 loopback_ok; + u32 validate_loopback; struct mlx4_hwq_resources res; int link_state; @@ -531,6 +543,11 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, u8 promisc); int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset); +int mlx4_en_QUERY_PORT(struct mlx4_en_dev *mdev, u8 port); + +#define MLX4_EN_NUM_SELF_TEST 5 +void mlx4_en_ex_selftest(struct net_device *dev, u32 *flags, u64 *buf); +u64 mlx4_en_mac_to_u64(u8 *addr); /* * Globals @@ -555,6 +572,8 @@ do { \ en_print(KERN_WARNING, priv, format, ##arg) #define en_err(priv, format, arg...) \ en_print(KERN_ERR, priv, format, ##arg) +#define en_info(priv, format, arg...) \ + en_print(KERN_INFO, priv, format, ## arg) #define mlx4_err(mdev, format, arg...) \ pr_err("%s %s: " format, DRV_NAME, \ diff --git a/drivers/net/mlx4/profile.c b/drivers/net/mlx4/profile.c index 5caf0115fa5b4e923e3d10d760c6c1284a21c694..e749f82865fee073175182b5451d683dd2ba1707 100644 --- a/drivers/net/mlx4/profile.c +++ b/drivers/net/mlx4/profile.c @@ -85,7 +85,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, struct mlx4_resource tmp; int i, j; - profile = kzalloc(MLX4_RES_NUM * sizeof *profile, GFP_KERNEL); + profile = kcalloc(MLX4_RES_NUM, sizeof(*profile), GFP_KERNEL); if (!profile) return -ENOMEM; diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 2d488abcf62d7c789a84583dd1ad7564c00ba80c..dd2b6a71c6d70f15dc18312b13c616370f94c16a 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -2901,7 +2901,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->dev = dev; set_params(mp, pd); - dev->real_num_tx_queues = mp->txq_count; + netif_set_real_num_tx_queues(dev, mp->txq_count); + netif_set_real_num_rx_queues(dev, mp->rxq_count); if (pd->phy_addr != MV643XX_ETH_PHY_NONE) mp->phy = phy_scan(mp, pd->phy_addr); diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index fb2c0927d3ccd76135d069f29971f238886b0f5a..8524cc40ec57b8beb86b1bed83b5e7677487172c 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -225,6 +225,7 @@ struct myri10ge_priv { struct msix_entry *msix_vectors; #ifdef CONFIG_MYRI10GE_DCA int dca_enabled; + int relaxed_order; #endif u32 link_state; unsigned int rdma_tags_available; @@ -990,7 +991,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) * RX queues, so if we get an error, first retry using a * single TX queue before giving up */ if (status != 0 && mgp->dev->real_num_tx_queues > 1) { - mgp->dev->real_num_tx_queues = 1; + netif_set_real_num_tx_queues(mgp->dev, 1); cmd.data0 = mgp->num_slices; cmd.data1 = MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE; status = myri10ge_send_cmd(mgp, @@ -1074,10 +1075,28 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } #ifdef CONFIG_MYRI10GE_DCA +static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on) +{ + int ret, cap, err; + u16 ctl; + + cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (!cap) + return 0; + + err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); + ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4; + if (ret != on) { + ctl &= ~PCI_EXP_DEVCTL_RELAX_EN; + ctl |= (on << 4); + pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); + } + return ret; +} + static void myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag) { - ss->cpu = cpu; ss->cached_dca_tag = tag; put_be32(htonl(tag), ss->dca_tag); } @@ -1088,9 +1107,10 @@ static inline void myri10ge_update_dca(struct myri10ge_slice_state *ss) int tag; if (cpu != ss->cpu) { - tag = dca_get_tag(cpu); + tag = dca3_get_tag(&ss->mgp->pdev->dev, cpu); if (ss->cached_dca_tag != tag) myri10ge_write_dca(ss, cpu, tag); + ss->cpu = cpu; } put_cpu(); } @@ -1113,9 +1133,13 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp) "dca_add_requester() failed, err=%d\n", err); return; } + mgp->relaxed_order = myri10ge_toggle_relaxed(pdev, 0); mgp->dca_enabled = 1; - for (i = 0; i < mgp->num_slices; i++) - myri10ge_write_dca(&mgp->ss[i], -1, 0); + for (i = 0; i < mgp->num_slices; i++) { + mgp->ss[i].cpu = -1; + mgp->ss[i].cached_dca_tag = -1; + myri10ge_update_dca(&mgp->ss[i]); + } } static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) @@ -1126,6 +1150,8 @@ static void myri10ge_teardown_dca(struct myri10ge_priv *mgp) if (!mgp->dca_enabled) return; mgp->dca_enabled = 0; + if (mgp->relaxed_order) + myri10ge_toggle_relaxed(pdev, 1); err = dca_remove_requester(&pdev->dev); } @@ -1555,12 +1581,12 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) * valid since MSI-X irqs are not shared */ if ((mgp->dev->real_num_tx_queues == 1) && (ss != mgp->ss)) { napi_schedule(&ss->napi); - return (IRQ_HANDLED); + return IRQ_HANDLED; } /* make sure it is our IRQ, and that the DMA has finished */ if (unlikely(!stats->valid)) - return (IRQ_NONE); + return IRQ_NONE; /* low bit indicates receives are present, so schedule * napi poll handler */ @@ -1599,7 +1625,7 @@ static irqreturn_t myri10ge_intr(int irq, void *arg) myri10ge_check_statblock(mgp); put_be32(htonl(3), ss->irq_claim + 1); - return (IRQ_HANDLED); + return IRQ_HANDLED; } static int @@ -3753,8 +3779,8 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) * slices. We give up on MSI-X if we can only get a single * vector. */ - mgp->msix_vectors = kzalloc(mgp->num_slices * - sizeof(*mgp->msix_vectors), GFP_KERNEL); + mgp->msix_vectors = kcalloc(mgp->num_slices, sizeof(*mgp->msix_vectors), + GFP_KERNEL); if (mgp->msix_vectors == NULL) goto disable_msix; for (i = 0; i < mgp->num_slices; i++) { @@ -3923,7 +3949,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "failed to alloc slice state\n"); goto abort_with_firmware; } - netdev->real_num_tx_queues = mgp->num_slices; + netif_set_real_num_tx_queues(netdev, mgp->num_slices); + netif_set_real_num_rx_queues(netdev, mgp->num_slices); status = myri10ge_reset(mgp); if (status != 0) { dev_err(&pdev->dev, "failed reset\n"); diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 617f898ba5f017d1d3439a3e3ea63ed14f67db8f..4846e131a04e8c4edc609764595523e8bffcebe0 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -735,7 +735,7 @@ static int myri_header(struct sk_buff *skb, struct net_device *dev, int i; for (i = 0; i < dev->addr_len; i++) eth->h_dest[i] = 0; - return(dev->hard_header_len); + return dev->hard_header_len; } if (daddr) { diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index a6033d48b5ccae7a1efa2377baac061d15075fb6..2fd39630b1e57c0e706165022335428e173cfb35 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -1570,7 +1570,7 @@ static int netdev_open(struct net_device *dev) init_timer(&np->timer); np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ); np->timer.data = (unsigned long)dev; - np->timer.function = &netdev_timer; /* timer handler */ + np->timer.function = netdev_timer; /* timer handler */ add_timer(&np->timer); return 0; diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index ca142c47b2e4c631a90c5b61382c99c49f784dd2..94255f09093d670695de61b00a07b818371844a0 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -678,7 +678,14 @@ static int netconsole_netdev_event(struct notifier_block *this, strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ); break; case NETDEV_UNREGISTER: - netpoll_cleanup(&nt->np); + /* + * rtnl_lock already held + */ + if (nt->np.dev) { + __netpoll_cleanup(&nt->np); + dev_put(nt->np.dev); + nt->np.dev = NULL; + } /* Fall through */ case NETDEV_GOING_DOWN: case NETDEV_BONDING_DESLAVE: diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 6dca3574e35507a94ca7e5b1b518a06199e99e03..8e8a97839cb0568abae8fa474b11e16511aba26b 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -175,7 +175,10 @@ #define MAX_NUM_CARDS 4 #define MAX_BUFFERS_PER_CMD 32 -#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + 4) +#define MAX_TSO_HEADER_DESC 2 +#define MGMT_CMD_DESC_RESV 4 +#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ + + MGMT_CMD_DESC_RESV) #define NX_MAX_TX_TIMEOUTS 2 /* @@ -1253,19 +1256,9 @@ struct netxen_adapter { const struct firmware *fw; }; -int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port); -int netxen_niu_disable_xg_port(struct netxen_adapter *adapter); - int nx_fw_cmd_query_phy(struct netxen_adapter *adapter, u32 reg, u32 *val); int nx_fw_cmd_set_phy(struct netxen_adapter *adapter, u32 reg, u32 val); -/* Functions available from netxen_nic_hw.c */ -int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); -int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu); - -int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr); -int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr); - #define NXRD32(adapter, off) \ (adapter->crb_read(adapter, off)) #define NXWR32(adapter, off, val) \ @@ -1345,11 +1338,8 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, struct nx_host_rds_ring *rds_ring); int netxen_process_cmd_ring(struct netxen_adapter *adapter); int netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max); -void netxen_p2_nic_set_multi(struct net_device *netdev); -void netxen_p3_nic_set_multi(struct net_device *netdev); + void netxen_p3_free_mac_list(struct netxen_adapter *adapter); -int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode); -int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32); int netxen_config_intr_coalesce(struct netxen_adapter *adapter); int netxen_config_rss(struct netxen_adapter *adapter, int enable); int netxen_config_ipaddr(struct netxen_adapter *adapter, u32 ip, int cmd); @@ -1364,9 +1354,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable); int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable); int netxen_send_lro_cleanup(struct netxen_adapter *adapter); -int netxen_nic_set_mac(struct net_device *netdev, void *p); -struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); - void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring); diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 29d7b93d0493be12e4a5def185282371b5cd400d..37d3ebd65be898b50b3f9e5fd0ab9e1c2c2cfbc9 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -319,6 +319,8 @@ static unsigned crb_hub_agt[64] = #define NETXEN_PCIE_SEM_TIMEOUT 10000 +static int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); + int netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg) { @@ -345,7 +347,7 @@ netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem))); } -int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) +static int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) { if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447); @@ -356,7 +358,7 @@ int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) } /* Disable an XG interface */ -int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) +static int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) { __u32 mac_cfg; u32 port = adapter->physical_port; @@ -383,7 +385,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) #define MAC_LO(addr) \ ((addr[5] << 16) | (addr[4] << 8) | (addr[3])) -int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) +static int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) { u32 mac_cfg; u32 cnt = 0; @@ -434,7 +436,7 @@ int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) return 0; } -int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) +static int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) { u32 mac_hi, mac_lo; u32 reg_hi, reg_lo; @@ -531,7 +533,7 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter, return 0; } -void netxen_p2_nic_set_multi(struct net_device *netdev) +static void netxen_p2_nic_set_multi(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct netdev_hw_addr *ha; @@ -598,8 +600,14 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter, if (nr_desc >= netxen_tx_avail(tx_ring)) { netif_tx_stop_queue(tx_ring->txq); - __netif_tx_unlock_bh(tx_ring->txq); - return -EBUSY; + smp_mb(); + if (netxen_tx_avail(tx_ring) > nr_desc) { + if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) + netif_tx_wake_queue(tx_ring->txq); + } else { + __netif_tx_unlock_bh(tx_ring->txq); + return -EBUSY; + } } do { @@ -674,7 +682,7 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, cur->mac_addr, NETXEN_MAC_ADD); } -void netxen_p3_nic_set_multi(struct net_device *netdev) +static void netxen_p3_nic_set_multi(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct netdev_hw_addr *ha; @@ -721,7 +729,7 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) } } -int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) +static int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) { nx_nic_req_t req; u64 word; @@ -754,7 +762,7 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter) } } -int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) +static int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr) { /* assuming caller has already copied new addr to netdev */ netxen_p3_nic_set_multi(adapter->netdev); @@ -1816,14 +1824,14 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) if (netxen_rom_fast_read(adapter, offset, &board_type)) return -EIO; - adapter->ahw.board_type = board_type; - if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) { u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I); if ((gpio & 0x8000) == 0) board_type = NETXEN_BRDTYPE_P3_10G_TP; } + adapter->ahw.board_type = board_type; + switch (board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: adapter->ahw.port_type = NETXEN_NIC_GBE; @@ -1867,16 +1875,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter) } /* NIU access sections */ - -int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu) -{ - new_mtu += MTU_FUDGE_FACTOR; - NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port), - new_mtu); - return 0; -} - -int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) +static int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu) { new_mtu += MTU_FUDGE_FACTOR; if (adapter->physical_port == 0) diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index b075a35b85d4ef09cfab1b2df3b42be0313c2516..95fe552aa2795a1a3a38bd5263c1eea8cfff5d13 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -346,7 +346,7 @@ static u32 netxen_decode_crb_addr(u32 addr) if (pci_base == NETXEN_ADDR_ERROR) return pci_base; else - return (pci_base + offset); + return pci_base + offset; } #define NETXEN_MAX_ROM_WAIT_USEC 100 @@ -1763,14 +1763,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) smp_mb(); - if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { - __netif_tx_lock(tx_ring->txq, smp_processor_id()); - if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) { + if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) + if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) netif_wake_queue(netdev); - adapter->tx_timeo_cnt = 0; - } - __netif_tx_unlock(tx_ring->txq); - } + adapter->tx_timeo_cnt = 0; } /* * If everything is freed up to consumer then check if the ring is full @@ -1789,7 +1785,7 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter) done = (sw_consumer == hw_consumer); spin_unlock(&adapter->tx_clean_lock); - return (done); + return done; } void diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 73d31459223098c8e3727a0565ed12805d58e388..50820beac3aa7c20ec8775e6886b419678bf4b04 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -95,6 +95,8 @@ static irqreturn_t netxen_msi_intr(int irq, void *data); static irqreturn_t netxen_msix_intr(int irq, void *data); static void netxen_config_indev_addr(struct net_device *dev, unsigned long); +static struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); +static int netxen_nic_set_mac(struct net_device *netdev, void *p); /* PCI Device ID Table */ #define ENTRY(device) \ @@ -125,11 +127,6 @@ netxen_nic_update_cmd_producer(struct netxen_adapter *adapter, struct nx_host_tx_ring *tx_ring) { NXWRIO(adapter, tx_ring->crb_cmd_producer, tx_ring->producer); - - if (netxen_tx_avail(tx_ring) <= TX_STOP_THRESH) { - netif_stop_queue(adapter->netdev); - smp_mb(); - } } static uint32_t crb_cmd_consumer[4] = { @@ -177,7 +174,7 @@ netxen_alloc_sds_rings(struct netxen_recv_context *recv_ctx, int count) recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL); - return (recv_ctx->sds_rings == NULL); + return recv_ctx->sds_rings == NULL; } static void @@ -460,7 +457,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) return 0; } -int netxen_nic_set_mac(struct net_device *netdev, void *p) +static int netxen_nic_set_mac(struct net_device *netdev, void *p) { struct netxen_adapter *adapter = netdev_priv(netdev); struct sockaddr *addr = p; @@ -1209,7 +1206,7 @@ netxen_setup_netdev(struct netxen_adapter *adapter, adapter->max_mc_count = 16; netdev->netdev_ops = &netxen_netdev_ops; - netdev->watchdog_timeo = 2*HZ; + netdev->watchdog_timeo = 5*HZ; netxen_nic_change_mtu(netdev, netdev->mtu); @@ -1254,6 +1251,28 @@ netxen_setup_netdev(struct netxen_adapter *adapter, return 0; } +#ifdef CONFIG_PCIEAER +static void netxen_mask_aer_correctable(struct netxen_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + struct pci_dev *root = pdev->bus->self; + u32 aer_pos; + + if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM && + adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP) + return; + + if (root->pcie_type != PCI_EXP_TYPE_ROOT_PORT) + return; + + aer_pos = pci_find_ext_capability(root, PCI_EXT_CAP_ID_ERR); + if (!aer_pos) + return; + + pci_write_config_dword(root, aer_pos + PCI_ERR_COR_MASK, 0xffff); +} +#endif + static int __devinit netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -1322,6 +1341,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_iounmap; } +#ifdef CONFIG_PCIEAER + netxen_mask_aer_correctable(adapter); +#endif + /* Mezz cards have PCI function 0,2,3 enabled */ switch (adapter->ahw.board_type) { case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: @@ -1825,9 +1848,13 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* 4 fragments per cmd des */ no_of_desc = (frag_count + 3) >> 2; - if (unlikely(no_of_desc + 2 > netxen_tx_avail(tx_ring))) { + if (unlikely(netxen_tx_avail(tx_ring) <= TX_STOP_THRESH)) { netif_stop_queue(netdev); - return NETDEV_TX_BUSY; + smp_mb(); + if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) + netif_start_queue(netdev); + else + return NETDEV_TX_BUSY; } producer = tx_ring->producer; @@ -2027,7 +2054,7 @@ static void netxen_tx_timeout_task(struct work_struct *work) clear_bit(__NX_RESETTING, &adapter->state); } -struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) +static struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) { struct netxen_adapter *adapter = netdev_priv(netdev); struct net_device_stats *stats = &netdev->stats; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index fe6983af6918fe37cdb5589907346557ddeeb8df..781e368329f91efe26389c17e0b293bb4342fcde 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -283,7 +283,7 @@ static int niu_enable_interrupts(struct niu *np, int on) static u32 phy_encode(u32 type, int port) { - return (type << (port * 2)); + return type << (port * 2); } static u32 phy_decode(u32 val, int port) @@ -3043,8 +3043,7 @@ static int tcam_flush_all(struct niu *np) static u64 hash_addr_regval(unsigned long index, unsigned long num_entries) { - return ((u64)index | (num_entries == 1 ? - HASH_TBL_ADDR_AUTOINC : 0)); + return (u64)index | (num_entries == 1 ? HASH_TBL_ADDR_AUTOINC : 0); } #if 0 @@ -3276,7 +3275,7 @@ static u16 tcam_get_index(struct niu *np, u16 idx) /* One entry reserved for IP fragment rule */ if (idx >= (np->clas.tcam_sz - 1)) idx = 0; - return (np->clas.tcam_top + ((idx+1) * np->parent->num_ports)); + return np->clas.tcam_top + ((idx+1) * np->parent->num_ports); } static u16 tcam_get_size(struct niu *np) @@ -3313,7 +3312,7 @@ static unsigned int niu_hash_rxaddr(struct rx_ring_info *rp, u64 a) a >>= PAGE_SHIFT; a ^= (a >> ilog2(MAX_RBR_RING_SIZE)); - return (a & (MAX_RBR_RING_SIZE - 1)); + return a & (MAX_RBR_RING_SIZE - 1); } static struct page *niu_find_rxpage(struct rx_ring_info *rp, u64 addr, @@ -3484,7 +3483,7 @@ static int niu_process_rx_pkt(struct napi_struct *napi, struct niu *np, RCR_ENTRY_ERROR))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else if (!(val & RCR_ENTRY_MULTI)) append_size = len - skb->len; @@ -4502,9 +4501,10 @@ static int niu_alloc_channels(struct niu *np) np->num_rx_rings = parent->rxchan_per_port[port]; np->num_tx_rings = parent->txchan_per_port[port]; - np->dev->real_num_tx_queues = np->num_tx_rings; + netif_set_real_num_rx_queues(np->dev, np->num_rx_rings); + netif_set_real_num_tx_queues(np->dev, np->num_tx_rings); - np->rx_rings = kzalloc(np->num_rx_rings * sizeof(struct rx_ring_info), + np->rx_rings = kcalloc(np->num_rx_rings, sizeof(struct rx_ring_info), GFP_KERNEL); err = -ENOMEM; if (!np->rx_rings) @@ -4538,7 +4538,7 @@ static int niu_alloc_channels(struct niu *np) return err; } - np->tx_rings = kzalloc(np->num_tx_rings * sizeof(struct tx_ring_info), + np->tx_rings = kcalloc(np->num_tx_rings, sizeof(struct tx_ring_info), GFP_KERNEL); err = -ENOMEM; if (!np->tx_rings) @@ -7090,24 +7090,20 @@ static int niu_get_hash_opts(struct niu *np, struct ethtool_rxnfc *nfc) static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp, struct ethtool_rx_flow_spec *fsp) { + u32 tmp; + u16 prt; - fsp->h_u.tcp_ip4_spec.ip4src = (tp->key[3] & TCAM_V4KEY3_SADDR) >> - TCAM_V4KEY3_SADDR_SHIFT; - fsp->h_u.tcp_ip4_spec.ip4dst = (tp->key[3] & TCAM_V4KEY3_DADDR) >> - TCAM_V4KEY3_DADDR_SHIFT; - fsp->m_u.tcp_ip4_spec.ip4src = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >> - TCAM_V4KEY3_SADDR_SHIFT; - fsp->m_u.tcp_ip4_spec.ip4dst = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >> - TCAM_V4KEY3_DADDR_SHIFT; - - fsp->h_u.tcp_ip4_spec.ip4src = - cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4src); - fsp->m_u.tcp_ip4_spec.ip4src = - cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4src); - fsp->h_u.tcp_ip4_spec.ip4dst = - cpu_to_be32(fsp->h_u.tcp_ip4_spec.ip4dst); - fsp->m_u.tcp_ip4_spec.ip4dst = - cpu_to_be32(fsp->m_u.tcp_ip4_spec.ip4dst); + tmp = (tp->key[3] & TCAM_V4KEY3_SADDR) >> TCAM_V4KEY3_SADDR_SHIFT; + fsp->h_u.tcp_ip4_spec.ip4src = cpu_to_be32(tmp); + + tmp = (tp->key[3] & TCAM_V4KEY3_DADDR) >> TCAM_V4KEY3_DADDR_SHIFT; + fsp->h_u.tcp_ip4_spec.ip4dst = cpu_to_be32(tmp); + + tmp = (tp->key_mask[3] & TCAM_V4KEY3_SADDR) >> TCAM_V4KEY3_SADDR_SHIFT; + fsp->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(tmp); + + tmp = (tp->key_mask[3] & TCAM_V4KEY3_DADDR) >> TCAM_V4KEY3_DADDR_SHIFT; + fsp->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(tmp); fsp->h_u.tcp_ip4_spec.tos = (tp->key[2] & TCAM_V4KEY2_TOS) >> TCAM_V4KEY2_TOS_SHIFT; @@ -7118,54 +7114,40 @@ static void niu_get_ip4fs_from_tcam_key(struct niu_tcam_entry *tp, case TCP_V4_FLOW: case UDP_V4_FLOW: case SCTP_V4_FLOW: - fsp->h_u.tcp_ip4_spec.psrc = - ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16; - fsp->h_u.tcp_ip4_spec.pdst = - ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff; - fsp->m_u.tcp_ip4_spec.psrc = - ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16; - fsp->m_u.tcp_ip4_spec.pdst = - ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff; + prt = ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16; + fsp->h_u.tcp_ip4_spec.psrc = cpu_to_be16(prt); - fsp->h_u.tcp_ip4_spec.psrc = - cpu_to_be16(fsp->h_u.tcp_ip4_spec.psrc); - fsp->h_u.tcp_ip4_spec.pdst = - cpu_to_be16(fsp->h_u.tcp_ip4_spec.pdst); - fsp->m_u.tcp_ip4_spec.psrc = - cpu_to_be16(fsp->m_u.tcp_ip4_spec.psrc); - fsp->m_u.tcp_ip4_spec.pdst = - cpu_to_be16(fsp->m_u.tcp_ip4_spec.pdst); + prt = ((tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff; + fsp->h_u.tcp_ip4_spec.pdst = cpu_to_be16(prt); + + prt = ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT) >> 16; + fsp->m_u.tcp_ip4_spec.psrc = cpu_to_be16(prt); + + prt = ((tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT) & 0xffff; + fsp->m_u.tcp_ip4_spec.pdst = cpu_to_be16(prt); break; case AH_V4_FLOW: case ESP_V4_FLOW: - fsp->h_u.ah_ip4_spec.spi = - (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT; - fsp->m_u.ah_ip4_spec.spi = - (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + tmp = (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> TCAM_V4KEY2_PORT_SPI_SHIFT; + fsp->h_u.ah_ip4_spec.spi = cpu_to_be32(tmp); - fsp->h_u.ah_ip4_spec.spi = - cpu_to_be32(fsp->h_u.ah_ip4_spec.spi); - fsp->m_u.ah_ip4_spec.spi = - cpu_to_be32(fsp->m_u.ah_ip4_spec.spi); + tmp = (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT; + fsp->m_u.ah_ip4_spec.spi = cpu_to_be32(tmp); break; case IP_USER_FLOW: - fsp->h_u.usr_ip4_spec.l4_4_bytes = - (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> - TCAM_V4KEY2_PORT_SPI_SHIFT; - fsp->m_u.usr_ip4_spec.l4_4_bytes = - (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + tmp = (tp->key[2] & TCAM_V4KEY2_PORT_SPI) >> TCAM_V4KEY2_PORT_SPI_SHIFT; + fsp->h_u.usr_ip4_spec.l4_4_bytes = cpu_to_be32(tmp); - fsp->h_u.usr_ip4_spec.l4_4_bytes = - cpu_to_be32(fsp->h_u.usr_ip4_spec.l4_4_bytes); - fsp->m_u.usr_ip4_spec.l4_4_bytes = - cpu_to_be32(fsp->m_u.usr_ip4_spec.l4_4_bytes); + tmp = (tp->key_mask[2] & TCAM_V4KEY2_PORT_SPI) >> + TCAM_V4KEY2_PORT_SPI_SHIFT; + fsp->m_u.usr_ip4_spec.l4_4_bytes = cpu_to_be32(tmp); fsp->h_u.usr_ip4_spec.proto = (tp->key[2] & TCAM_V4KEY2_PROTO) >> @@ -7462,10 +7444,12 @@ static int niu_add_ethtool_tcam_entry(struct niu *np, if (fsp->flow_type == IP_USER_FLOW) { int i; int add_usr_cls = 0; - int ipv6 = 0; struct ethtool_usrip4_spec *uspec = &fsp->h_u.usr_ip4_spec; struct ethtool_usrip4_spec *umask = &fsp->m_u.usr_ip4_spec; + if (uspec->ip_ver != ETH_RX_NFC_IP4) + return -EINVAL; + niu_lock_parent(np, flags); for (i = 0; i < NIU_L3_PROG_CLS; i++) { @@ -7494,9 +7478,7 @@ static int niu_add_ethtool_tcam_entry(struct niu *np, default: break; } - if (uspec->ip_ver == ETH_RX_NFC_IP6) - ipv6 = 1; - ret = tcam_user_ip_class_set(np, class, ipv6, + ret = tcam_user_ip_class_set(np, class, 0, uspec->proto, uspec->tos, umask->tos); @@ -7553,16 +7535,7 @@ static int niu_add_ethtool_tcam_entry(struct niu *np, ret = -EINVAL; goto out; case IP_USER_FLOW: - if (fsp->h_u.usr_ip4_spec.ip_ver == ETH_RX_NFC_IP4) { - niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table, - class); - } else { - /* Not yet implemented */ - netdev_info(np->dev, "niu%d: In %s(): usr flow for IPv6 not implemented\n", - parent->index, __func__); - ret = -EINVAL; - goto out; - } + niu_get_tcamkey_from_ip4fs(fsp, tp, l2_rdc_table, class); break; default: netdev_info(np->dev, "niu%d: In %s(): Unknown flow type %d\n", @@ -7805,11 +7778,11 @@ static int niu_get_sset_count(struct net_device *dev, int stringset) if (stringset != ETH_SS_STATS) return -EINVAL; - return ((np->flags & NIU_FLAGS_XMAC ? + return (np->flags & NIU_FLAGS_XMAC ? NUM_XMAC_STAT_KEYS : NUM_BMAC_STAT_KEYS) + (np->num_rx_rings * NUM_RXCHAN_STAT_KEYS) + - (np->num_tx_rings * NUM_TXCHAN_STAT_KEYS)); + (np->num_tx_rings * NUM_TXCHAN_STAT_KEYS); } static void niu_get_ethtool_stats(struct net_device *dev, diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 5a3488f76b388f49939a373abb1e03079ca07554..84134c766f3a86fca82195683be07de25cbf5fa1 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -772,7 +772,7 @@ static int ns83820_setup_rx(struct net_device *ndev) phy_intr(ndev); /* Okay, let it rip */ - spin_lock_irq(&dev->misc_lock); + spin_lock(&dev->misc_lock); dev->IMR_cache |= ISR_PHY; dev->IMR_cache |= ISR_RXRCMP; //dev->IMR_cache |= ISR_RXERR; @@ -923,7 +923,7 @@ static void rx_irq(struct net_device *ndev) if ((extsts & 0x002a0000) && !(extsts & 0x00540000)) { skb->ip_summed = CHECKSUM_UNNECESSARY; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } skb->protocol = eth_type_trans(skb, ndev); #ifdef NS83820_VLAN_ACCEL_SUPPORT @@ -1246,7 +1246,6 @@ static int ns83820_get_settings(struct net_device *ndev, { struct ns83820 *dev = PRIV(ndev); u32 cfg, tanar, tbicr; - int have_optical = 0; int fullduplex = 0; /* @@ -1267,25 +1266,25 @@ static int ns83820_get_settings(struct net_device *ndev, tanar = readl(dev->base + TANAR); tbicr = readl(dev->base + TBICR); - if (dev->CFG_cache & CFG_TBI_EN) { - /* we have an optical interface */ - have_optical = 1; - fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; - - } else { - /* We have copper */ - fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; - } + fullduplex = (cfg & CFG_DUPSTS) ? 1 : 0; cmd->supported = SUPPORTED_Autoneg; - /* we have optical interface */ if (dev->CFG_cache & CFG_TBI_EN) { + /* we have optical interface */ cmd->supported |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE; cmd->port = PORT_FIBRE; - } /* TODO: else copper related support */ + } else { + /* we have copper */ + cmd->supported |= SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full | + SUPPORTED_MII; + cmd->port = PORT_MII; + } cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF; switch (cfg / CFG_SPDSTS0 & 3) { @@ -1299,7 +1298,8 @@ static int ns83820_get_settings(struct net_device *ndev, cmd->speed = SPEED_10; break; } - cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) ? 1: 0; + cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE) + ? AUTONEG_ENABLE : AUTONEG_DISABLE; return 0; } @@ -1405,6 +1405,13 @@ static const struct ethtool_ops ops = { .get_link = ns83820_get_link }; +static inline void ns83820_disable_interrupts(struct ns83820 *dev) +{ + writel(0, dev->base + IMR); + writel(0, dev->base + IER); + readl(dev->base + IER); +} + /* this function is called in irq context from the ISR */ static void ns83820_mib_isr(struct ns83820 *dev) { @@ -1557,10 +1564,7 @@ static int ns83820_stop(struct net_device *ndev) /* FIXME: protect against interrupt handler? */ del_timer_sync(&dev->tx_watchdog); - /* disable interrupts */ - writel(0, dev->base + IMR); - writel(0, dev->base + IER); - readl(dev->base + IER); + ns83820_disable_interrupts(dev); dev->rx_info.up = 0; synchronize_irq(dev->pci_dev->irq); @@ -2023,10 +2027,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, dev->tx_descs, (long)dev->tx_phy_descs, dev->rx_info.descs, (long)dev->rx_info.phy_descs); - /* disable interrupts */ - writel(0, dev->base + IMR); - writel(0, dev->base + IER); - readl(dev->base + IER); + ns83820_disable_interrupts(dev); dev->IMR_cache = 0; @@ -2250,9 +2251,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, return 0; out_cleanup: - writel(0, dev->base + IMR); /* paranoia */ - writel(0, dev->base + IER); - readl(dev->base + IER); + ns83820_disable_interrupts(dev); /* paranoia */ out_free_irq: rtnl_unlock(); free_irq(pci_dev->irq, ndev); @@ -2277,9 +2276,7 @@ static void __devexit ns83820_remove_one(struct pci_dev *pci_dev) if (!ndev) /* paranoia */ return; - writel(0, dev->base + IMR); /* paranoia */ - writel(0, dev->base + IER); - readl(dev->base + IER); + ns83820_disable_interrupts(dev); /* paranoia */ unregister_netdev(ndev); free_irq(dev->pci_dev->irq, ndev); diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 8ab6ae0a61079dd28f606ce3ca4d637dfdf50e52..828e97cacdbfe33bc9351dea24f7d1b894f9e8af 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -808,7 +808,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac_rxring *rx, skb->csum = (macrx & XCT_MACRX_CSUM_M) >> XCT_MACRX_CSUM_S; } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); packets++; tot_bytes += len; diff --git a/drivers/net/pasemi_mac_ethtool.c b/drivers/net/pasemi_mac_ethtool.c index fefa79e34b95c43386ef1488cfbb673f1d4af886..4825959a0efe1288712ce1080d47a45f6daf254b 100644 --- a/drivers/net/pasemi_mac_ethtool.c +++ b/drivers/net/pasemi_mac_ethtool.c @@ -90,21 +90,6 @@ pasemi_mac_ethtool_set_settings(struct net_device *netdev, return phy_ethtool_sset(phydev, cmd); } -static void -pasemi_mac_ethtool_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) -{ - struct pasemi_mac *mac; - mac = netdev_priv(netdev); - - /* clear and fill out info */ - memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); - strncpy(drvinfo->driver, "pasemi_mac", 12); - strcpy(drvinfo->version, "N/A"); - strcpy(drvinfo->fw_version, "N/A"); - strncpy(drvinfo->bus_info, pci_name(mac->pdev), 32); -} - static u32 pasemi_mac_ethtool_get_msglevel(struct net_device *netdev) { @@ -164,7 +149,6 @@ static void pasemi_mac_get_strings(struct net_device *netdev, u32 stringset, const struct ethtool_ops pasemi_mac_ethtool_ops = { .get_settings = pasemi_mac_ethtool_get_settings, .set_settings = pasemi_mac_ethtool_set_settings, - .get_drvinfo = pasemi_mac_ethtool_get_drvinfo, .get_msglevel = pasemi_mac_ethtool_get_msglevel, .set_msglevel = pasemi_mac_ethtool_set_msglevel, .get_link = ethtool_op_get_link, diff --git a/drivers/net/pch_gbe/Makefile b/drivers/net/pch_gbe/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..31288d4ad248fc5f4db4738ed9c2ca75b2a34d43 --- /dev/null +++ b/drivers/net/pch_gbe/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_PCH_GBE) += pch_gbe.o + +pch_gbe-y := pch_gbe_phy.o pch_gbe_ethtool.o pch_gbe_param.o +pch_gbe-y += pch_gbe_api.o pch_gbe_main.o diff --git a/drivers/net/pch_gbe/pch_gbe.h b/drivers/net/pch_gbe/pch_gbe.h new file mode 100644 index 0000000000000000000000000000000000000000..a0c26a99520fb183f13dc302852d85d334264778 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe.h @@ -0,0 +1,659 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _PCH_GBE_H_ +#define _PCH_GBE_H_ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * pch_gbe_regs_mac_adr - Structure holding values of mac address registers + * @high Denotes the 1st to 4th byte from the initial of MAC address + * @low Denotes the 5th to 6th byte from the initial of MAC address + */ +struct pch_gbe_regs_mac_adr { + u32 high; + u32 low; +}; +/** + * pch_udc_regs - Structure holding values of MAC registers + */ +struct pch_gbe_regs { + u32 INT_ST; + u32 INT_EN; + u32 MODE; + u32 RESET; + u32 TCPIP_ACC; + u32 EX_LIST; + u32 INT_ST_HOLD; + u32 PHY_INT_CTRL; + u32 MAC_RX_EN; + u32 RX_FCTRL; + u32 PAUSE_REQ; + u32 RX_MODE; + u32 TX_MODE; + u32 RX_FIFO_ST; + u32 TX_FIFO_ST; + u32 TX_FID; + u32 TX_RESULT; + u32 PAUSE_PKT1; + u32 PAUSE_PKT2; + u32 PAUSE_PKT3; + u32 PAUSE_PKT4; + u32 PAUSE_PKT5; + u32 reserve[2]; + struct pch_gbe_regs_mac_adr mac_adr[16]; + u32 ADDR_MASK; + u32 MIIM; + u32 reserve2; + u32 RGMII_ST; + u32 RGMII_CTRL; + u32 reserve3[3]; + u32 DMA_CTRL; + u32 reserve4[3]; + u32 RX_DSC_BASE; + u32 RX_DSC_SIZE; + u32 RX_DSC_HW_P; + u32 RX_DSC_HW_P_HLD; + u32 RX_DSC_SW_P; + u32 reserve5[3]; + u32 TX_DSC_BASE; + u32 TX_DSC_SIZE; + u32 TX_DSC_HW_P; + u32 TX_DSC_HW_P_HLD; + u32 TX_DSC_SW_P; + u32 reserve6[3]; + u32 RX_DMA_ST; + u32 TX_DMA_ST; + u32 reserve7[2]; + u32 WOL_ST; + u32 WOL_CTRL; + u32 WOL_ADDR_MASK; +}; + +/* Interrupt Status */ +/* Interrupt Status Hold */ +/* Interrupt Enable */ +#define PCH_GBE_INT_RX_DMA_CMPLT 0x00000001 /* Receive DMA Transfer Complete */ +#define PCH_GBE_INT_RX_VALID 0x00000002 /* MAC Normal Receive Complete */ +#define PCH_GBE_INT_RX_FRAME_ERR 0x00000004 /* Receive frame error */ +#define PCH_GBE_INT_RX_FIFO_ERR 0x00000008 /* Receive FIFO Overflow */ +#define PCH_GBE_INT_RX_DMA_ERR 0x00000010 /* Receive DMA Transfer Error */ +#define PCH_GBE_INT_RX_DSC_EMP 0x00000020 /* Receive Descriptor Empty */ +#define PCH_GBE_INT_TX_CMPLT 0x00000100 /* MAC Transmission Complete */ +#define PCH_GBE_INT_TX_DMA_CMPLT 0x00000200 /* DMA Transfer Complete */ +#define PCH_GBE_INT_TX_FIFO_ERR 0x00000400 /* Transmission FIFO underflow. */ +#define PCH_GBE_INT_TX_DMA_ERR 0x00000800 /* Transmission DMA Error */ +#define PCH_GBE_INT_PAUSE_CMPLT 0x00001000 /* Pause Transmission complete */ +#define PCH_GBE_INT_MIIM_CMPLT 0x00010000 /* MIIM I/F Read completion */ +#define PCH_GBE_INT_PHY_INT 0x00100000 /* Interruption from PHY */ +#define PCH_GBE_INT_WOL_DET 0x01000000 /* Wake On LAN Event detection. */ +#define PCH_GBE_INT_TCPIP_ERR 0x10000000 /* TCP/IP Accelerator Error */ + +/* Mode */ +#define PCH_GBE_MODE_MII_ETHER 0x00000000 /* GIGA Ethernet Mode [MII] */ +#define PCH_GBE_MODE_GMII_ETHER 0x80000000 /* GIGA Ethernet Mode [GMII] */ +#define PCH_GBE_MODE_HALF_DUPLEX 0x00000000 /* Duplex Mode [half duplex] */ +#define PCH_GBE_MODE_FULL_DUPLEX 0x40000000 /* Duplex Mode [full duplex] */ +#define PCH_GBE_MODE_FR_BST 0x04000000 /* Frame bursting is done */ + +/* Reset */ +#define PCH_GBE_ALL_RST 0x80000000 /* All reset */ +#define PCH_GBE_TX_RST 0x40000000 /* TX MAC, TX FIFO, TX DMA reset */ +#define PCH_GBE_RX_RST 0x04000000 /* RX MAC, RX FIFO, RX DMA reset */ + +/* TCP/IP Accelerator Control */ +#define PCH_GBE_EX_LIST_EN 0x00000008 /* External List Enable */ +#define PCH_GBE_RX_TCPIPACC_OFF 0x00000004 /* RX TCP/IP ACC Disabled */ +#define PCH_GBE_TX_TCPIPACC_EN 0x00000002 /* TX TCP/IP ACC Enable */ +#define PCH_GBE_RX_TCPIPACC_EN 0x00000001 /* RX TCP/IP ACC Enable */ + +/* MAC RX Enable */ +#define PCH_GBE_MRE_MAC_RX_EN 0x00000001 /* MAC Receive Enable */ + +/* RX Flow Control */ +#define PCH_GBE_FL_CTRL_EN 0x80000000 /* Pause packet is enabled */ + +/* Pause Packet Request */ +#define PCH_GBE_PS_PKT_RQ 0x80000000 /* Pause packet Request */ + +/* RX Mode */ +#define PCH_GBE_ADD_FIL_EN 0x80000000 /* Address Filtering Enable */ +/* Multicast Filtering Enable */ +#define PCH_GBE_MLT_FIL_EN 0x40000000 +/* Receive Almost Empty Threshold */ +#define PCH_GBE_RH_ALM_EMP_4 0x00000000 /* 4 words */ +#define PCH_GBE_RH_ALM_EMP_8 0x00004000 /* 8 words */ +#define PCH_GBE_RH_ALM_EMP_16 0x00008000 /* 16 words */ +#define PCH_GBE_RH_ALM_EMP_32 0x0000C000 /* 32 words */ +/* Receive Almost Full Threshold */ +#define PCH_GBE_RH_ALM_FULL_4 0x00000000 /* 4 words */ +#define PCH_GBE_RH_ALM_FULL_8 0x00001000 /* 8 words */ +#define PCH_GBE_RH_ALM_FULL_16 0x00002000 /* 16 words */ +#define PCH_GBE_RH_ALM_FULL_32 0x00003000 /* 32 words */ +/* RX FIFO Read Triger Threshold */ +#define PCH_GBE_RH_RD_TRG_4 0x00000000 /* 4 words */ +#define PCH_GBE_RH_RD_TRG_8 0x00000200 /* 8 words */ +#define PCH_GBE_RH_RD_TRG_16 0x00000400 /* 16 words */ +#define PCH_GBE_RH_RD_TRG_32 0x00000600 /* 32 words */ +#define PCH_GBE_RH_RD_TRG_64 0x00000800 /* 64 words */ +#define PCH_GBE_RH_RD_TRG_128 0x00000A00 /* 128 words */ +#define PCH_GBE_RH_RD_TRG_256 0x00000C00 /* 256 words */ +#define PCH_GBE_RH_RD_TRG_512 0x00000E00 /* 512 words */ + +/* Receive Descriptor bit definitions */ +#define PCH_GBE_RXD_ACC_STAT_BCAST 0x00000400 +#define PCH_GBE_RXD_ACC_STAT_MCAST 0x00000200 +#define PCH_GBE_RXD_ACC_STAT_UCAST 0x00000100 +#define PCH_GBE_RXD_ACC_STAT_TCPIPOK 0x000000C0 +#define PCH_GBE_RXD_ACC_STAT_IPOK 0x00000080 +#define PCH_GBE_RXD_ACC_STAT_TCPOK 0x00000040 +#define PCH_GBE_RXD_ACC_STAT_IP6ERR 0x00000020 +#define PCH_GBE_RXD_ACC_STAT_OFLIST 0x00000010 +#define PCH_GBE_RXD_ACC_STAT_TYPEIP 0x00000008 +#define PCH_GBE_RXD_ACC_STAT_MACL 0x00000004 +#define PCH_GBE_RXD_ACC_STAT_PPPOE 0x00000002 +#define PCH_GBE_RXD_ACC_STAT_VTAGT 0x00000001 +#define PCH_GBE_RXD_GMAC_STAT_PAUSE 0x0200 +#define PCH_GBE_RXD_GMAC_STAT_MARBR 0x0100 +#define PCH_GBE_RXD_GMAC_STAT_MARMLT 0x0080 +#define PCH_GBE_RXD_GMAC_STAT_MARIND 0x0040 +#define PCH_GBE_RXD_GMAC_STAT_MARNOTMT 0x0020 +#define PCH_GBE_RXD_GMAC_STAT_TLONG 0x0010 +#define PCH_GBE_RXD_GMAC_STAT_TSHRT 0x0008 +#define PCH_GBE_RXD_GMAC_STAT_NOTOCTAL 0x0004 +#define PCH_GBE_RXD_GMAC_STAT_NBLERR 0x0002 +#define PCH_GBE_RXD_GMAC_STAT_CRCERR 0x0001 + +/* Transmit Descriptor bit definitions */ +#define PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF 0x0008 +#define PCH_GBE_TXD_CTRL_ITAG 0x0004 +#define PCH_GBE_TXD_CTRL_ICRC 0x0002 +#define PCH_GBE_TXD_CTRL_APAD 0x0001 +#define PCH_GBE_TXD_WORDS_SHIFT 2 +#define PCH_GBE_TXD_GMAC_STAT_CMPLT 0x2000 +#define PCH_GBE_TXD_GMAC_STAT_ABT 0x1000 +#define PCH_GBE_TXD_GMAC_STAT_EXCOL 0x0800 +#define PCH_GBE_TXD_GMAC_STAT_SNGCOL 0x0400 +#define PCH_GBE_TXD_GMAC_STAT_MLTCOL 0x0200 +#define PCH_GBE_TXD_GMAC_STAT_CRSER 0x0100 +#define PCH_GBE_TXD_GMAC_STAT_TLNG 0x0080 +#define PCH_GBE_TXD_GMAC_STAT_TSHRT 0x0040 +#define PCH_GBE_TXD_GMAC_STAT_LTCOL 0x0020 +#define PCH_GBE_TXD_GMAC_STAT_TFUNDFLW 0x0010 +#define PCH_GBE_TXD_GMAC_STAT_RTYCNT_MASK 0x000F + +/* TX Mode */ +#define PCH_GBE_TM_NO_RTRY 0x80000000 /* No Retransmission */ +#define PCH_GBE_TM_LONG_PKT 0x40000000 /* Long Packt TX Enable */ +#define PCH_GBE_TM_ST_AND_FD 0x20000000 /* Stare and Forward */ +#define PCH_GBE_TM_SHORT_PKT 0x10000000 /* Short Packet TX Enable */ +#define PCH_GBE_TM_LTCOL_RETX 0x08000000 /* Retransmission at Late Collision */ +/* Frame Start Threshold */ +#define PCH_GBE_TM_TH_TX_STRT_4 0x00000000 /* 4 words */ +#define PCH_GBE_TM_TH_TX_STRT_8 0x00004000 /* 8 words */ +#define PCH_GBE_TM_TH_TX_STRT_16 0x00008000 /* 16 words */ +#define PCH_GBE_TM_TH_TX_STRT_32 0x0000C000 /* 32 words */ +/* Transmit Almost Empty Threshold */ +#define PCH_GBE_TM_TH_ALM_EMP_4 0x00000000 /* 4 words */ +#define PCH_GBE_TM_TH_ALM_EMP_8 0x00000800 /* 8 words */ +#define PCH_GBE_TM_TH_ALM_EMP_16 0x00001000 /* 16 words */ +#define PCH_GBE_TM_TH_ALM_EMP_32 0x00001800 /* 32 words */ +#define PCH_GBE_TM_TH_ALM_EMP_64 0x00002000 /* 64 words */ +#define PCH_GBE_TM_TH_ALM_EMP_128 0x00002800 /* 128 words */ +#define PCH_GBE_TM_TH_ALM_EMP_256 0x00003000 /* 256 words */ +#define PCH_GBE_TM_TH_ALM_EMP_512 0x00003800 /* 512 words */ +/* Transmit Almost Full Threshold */ +#define PCH_GBE_TM_TH_ALM_FULL_4 0x00000000 /* 4 words */ +#define PCH_GBE_TM_TH_ALM_FULL_8 0x00000200 /* 8 words */ +#define PCH_GBE_TM_TH_ALM_FULL_16 0x00000400 /* 16 words */ +#define PCH_GBE_TM_TH_ALM_FULL_32 0x00000600 /* 32 words */ + +/* RX FIFO Status */ +#define PCH_GBE_RF_ALM_FULL 0x80000000 /* RX FIFO is almost full. */ +#define PCH_GBE_RF_ALM_EMP 0x40000000 /* RX FIFO is almost empty. */ +#define PCH_GBE_RF_RD_TRG 0x20000000 /* Become more than RH_RD_TRG. */ +#define PCH_GBE_RF_STRWD 0x1FFE0000 /* The word count of RX FIFO. */ +#define PCH_GBE_RF_RCVING 0x00010000 /* Stored in RX FIFO. */ + +/* MAC Address Mask */ +#define PCH_GBE_BUSY 0x80000000 + +/* MIIM */ +#define PCH_GBE_MIIM_OPER_WRITE 0x04000000 +#define PCH_GBE_MIIM_OPER_READ 0x00000000 +#define PCH_GBE_MIIM_OPER_READY 0x04000000 +#define PCH_GBE_MIIM_PHY_ADDR_SHIFT 21 +#define PCH_GBE_MIIM_REG_ADDR_SHIFT 16 + +/* RGMII Status */ +#define PCH_GBE_LINK_UP 0x80000008 +#define PCH_GBE_RXC_SPEED_MSK 0x00000006 +#define PCH_GBE_RXC_SPEED_2_5M 0x00000000 /* 2.5MHz */ +#define PCH_GBE_RXC_SPEED_25M 0x00000002 /* 25MHz */ +#define PCH_GBE_RXC_SPEED_125M 0x00000004 /* 100MHz */ +#define PCH_GBE_DUPLEX_FULL 0x00000001 + +/* RGMII Control */ +#define PCH_GBE_CRS_SEL 0x00000010 +#define PCH_GBE_RGMII_RATE_125M 0x00000000 +#define PCH_GBE_RGMII_RATE_25M 0x00000008 +#define PCH_GBE_RGMII_RATE_2_5M 0x0000000C +#define PCH_GBE_RGMII_MODE_GMII 0x00000000 +#define PCH_GBE_RGMII_MODE_RGMII 0x00000002 +#define PCH_GBE_CHIP_TYPE_EXTERNAL 0x00000000 +#define PCH_GBE_CHIP_TYPE_INTERNAL 0x00000001 + +/* DMA Control */ +#define PCH_GBE_RX_DMA_EN 0x00000002 /* Enables Receive DMA */ +#define PCH_GBE_TX_DMA_EN 0x00000001 /* Enables Transmission DMA */ + +/* Wake On LAN Status */ +#define PCH_GBE_WLS_BR 0x00000008 /* Broadcas Address */ +#define PCH_GBE_WLS_MLT 0x00000004 /* Multicast Address */ + +/* The Frame registered in Address Recognizer */ +#define PCH_GBE_WLS_IND 0x00000002 +#define PCH_GBE_WLS_MP 0x00000001 /* Magic packet Address */ + +/* Wake On LAN Control */ +#define PCH_GBE_WLC_WOL_MODE 0x00010000 +#define PCH_GBE_WLC_IGN_TLONG 0x00000100 +#define PCH_GBE_WLC_IGN_TSHRT 0x00000080 +#define PCH_GBE_WLC_IGN_OCTER 0x00000040 +#define PCH_GBE_WLC_IGN_NBLER 0x00000020 +#define PCH_GBE_WLC_IGN_CRCER 0x00000010 +#define PCH_GBE_WLC_BR 0x00000008 +#define PCH_GBE_WLC_MLT 0x00000004 +#define PCH_GBE_WLC_IND 0x00000002 +#define PCH_GBE_WLC_MP 0x00000001 + +/* Wake On LAN Address Mask */ +#define PCH_GBE_WLA_BUSY 0x80000000 + + + +/* TX/RX descriptor defines */ +#define PCH_GBE_MAX_TXD 4096 +#define PCH_GBE_DEFAULT_TXD 256 +#define PCH_GBE_MIN_TXD 8 +#define PCH_GBE_MAX_RXD 4096 +#define PCH_GBE_DEFAULT_RXD 256 +#define PCH_GBE_MIN_RXD 8 + +/* Number of Transmit and Receive Descriptors must be a multiple of 8 */ +#define PCH_GBE_TX_DESC_MULTIPLE 8 +#define PCH_GBE_RX_DESC_MULTIPLE 8 + +/* Read/Write operation is done through MII Management IF */ +#define PCH_GBE_HAL_MIIM_READ ((u32)0x00000000) +#define PCH_GBE_HAL_MIIM_WRITE ((u32)0x04000000) + +/* flow control values */ +#define PCH_GBE_FC_NONE 0 +#define PCH_GBE_FC_RX_PAUSE 1 +#define PCH_GBE_FC_TX_PAUSE 2 +#define PCH_GBE_FC_FULL 3 +#define PCH_GBE_FC_DEFAULT PCH_GBE_FC_FULL + + +struct pch_gbe_hw; +/** + * struct pch_gbe_functions - HAL APi function pointer + * @get_bus_info: for pch_gbe_hal_get_bus_info + * @init_hw: for pch_gbe_hal_init_hw + * @read_phy_reg: for pch_gbe_hal_read_phy_reg + * @write_phy_reg: for pch_gbe_hal_write_phy_reg + * @reset_phy: for pch_gbe_hal_phy_hw_reset + * @sw_reset_phy: for pch_gbe_hal_phy_sw_reset + * @power_up_phy: for pch_gbe_hal_power_up_phy + * @power_down_phy: for pch_gbe_hal_power_down_phy + * @read_mac_addr: for pch_gbe_hal_read_mac_addr + */ +struct pch_gbe_functions { + void (*get_bus_info) (struct pch_gbe_hw *); + s32 (*init_hw) (struct pch_gbe_hw *); + s32 (*read_phy_reg) (struct pch_gbe_hw *, u32, u16 *); + s32 (*write_phy_reg) (struct pch_gbe_hw *, u32, u16); + void (*reset_phy) (struct pch_gbe_hw *); + void (*sw_reset_phy) (struct pch_gbe_hw *); + void (*power_up_phy) (struct pch_gbe_hw *hw); + void (*power_down_phy) (struct pch_gbe_hw *hw); + s32 (*read_mac_addr) (struct pch_gbe_hw *); +}; + +/** + * struct pch_gbe_mac_info - MAC infomation + * @addr[6]: Store the MAC address + * @fc: Mode of flow control + * @fc_autoneg: Auto negotiation enable for flow control setting + * @tx_fc_enable: Enable flag of Transmit flow control + * @max_frame_size: Max transmit frame size + * @min_frame_size: Min transmit frame size + * @autoneg: Auto negotiation enable + * @link_speed: Link speed + * @link_duplex: Link duplex + */ +struct pch_gbe_mac_info { + u8 addr[6]; + u8 fc; + u8 fc_autoneg; + u8 tx_fc_enable; + u32 max_frame_size; + u32 min_frame_size; + u8 autoneg; + u16 link_speed; + u16 link_duplex; +}; + +/** + * struct pch_gbe_phy_info - PHY infomation + * @addr: PHY address + * @id: PHY's identifier + * @revision: PHY's revision + * @reset_delay_us: HW reset delay time[us] + * @autoneg_advertised: Autoneg advertised + */ +struct pch_gbe_phy_info { + u32 addr; + u32 id; + u32 revision; + u32 reset_delay_us; + u16 autoneg_advertised; +}; + +/*! + * @ingroup Gigabit Ether driver Layer + * @struct pch_gbe_bus_info + * @brief Bus infomation + */ +struct pch_gbe_bus_info { + u8 type; + u8 speed; + u8 width; +}; + +/*! + * @ingroup Gigabit Ether driver Layer + * @struct pch_gbe_hw + * @brief Hardware infomation + */ +struct pch_gbe_hw { + void *back; + + struct pch_gbe_regs __iomem *reg; + spinlock_t miim_lock; + + const struct pch_gbe_functions *func; + struct pch_gbe_mac_info mac; + struct pch_gbe_phy_info phy; + struct pch_gbe_bus_info bus; +}; + +/** + * struct pch_gbe_rx_desc - Receive Descriptor + * @buffer_addr: RX Frame Buffer Address + * @tcp_ip_status: TCP/IP Accelerator Status + * @rx_words_eob: RX word count and Byte position + * @gbec_status: GMAC Status + * @dma_status: DMA Status + * @reserved1: Reserved + * @reserved2: Reserved + */ +struct pch_gbe_rx_desc { + u32 buffer_addr; + u32 tcp_ip_status; + u16 rx_words_eob; + u16 gbec_status; + u8 dma_status; + u8 reserved1; + u16 reserved2; +}; + +/** + * struct pch_gbe_tx_desc - Transmit Descriptor + * @buffer_addr: TX Frame Buffer Address + * @length: Data buffer length + * @reserved1: Reserved + * @tx_words_eob: TX word count and Byte position + * @tx_frame_ctrl: TX Frame Control + * @dma_status: DMA Status + * @reserved2: Reserved + * @gbec_status: GMAC Status + */ +struct pch_gbe_tx_desc { + u32 buffer_addr; + u16 length; + u16 reserved1; + u16 tx_words_eob; + u16 tx_frame_ctrl; + u8 dma_status; + u8 reserved2; + u16 gbec_status; +}; + + +/** + * struct pch_gbe_buffer - Buffer infomation + * @skb: pointer to a socket buffer + * @dma: DMA address + * @time_stamp: time stamp + * @length: data size + */ +struct pch_gbe_buffer { + struct sk_buff *skb; + dma_addr_t dma; + unsigned long time_stamp; + u16 length; + bool mapped; +}; + +/** + * struct pch_gbe_tx_ring - tx ring infomation + * @tx_lock: spinlock structs + * @desc: pointer to the descriptor ring memory + * @dma: physical address of the descriptor ring + * @size: length of descriptor ring in bytes + * @count: number of descriptors in the ring + * @next_to_use: next descriptor to associate a buffer with + * @next_to_clean: next descriptor to check for DD status bit + * @buffer_info: array of buffer information structs + */ +struct pch_gbe_tx_ring { + spinlock_t tx_lock; + struct pch_gbe_tx_desc *desc; + dma_addr_t dma; + unsigned int size; + unsigned int count; + unsigned int next_to_use; + unsigned int next_to_clean; + struct pch_gbe_buffer *buffer_info; +}; + +/** + * struct pch_gbe_rx_ring - rx ring infomation + * @desc: pointer to the descriptor ring memory + * @dma: physical address of the descriptor ring + * @size: length of descriptor ring in bytes + * @count: number of descriptors in the ring + * @next_to_use: next descriptor to associate a buffer with + * @next_to_clean: next descriptor to check for DD status bit + * @buffer_info: array of buffer information structs + */ +struct pch_gbe_rx_ring { + struct pch_gbe_rx_desc *desc; + dma_addr_t dma; + unsigned int size; + unsigned int count; + unsigned int next_to_use; + unsigned int next_to_clean; + struct pch_gbe_buffer *buffer_info; +}; + +/** + * struct pch_gbe_hw_stats - Statistics counters collected by the MAC + * @rx_packets: total packets received + * @tx_packets: total packets transmitted + * @rx_bytes: total bytes received + * @tx_bytes: total bytes transmitted + * @rx_errors: bad packets received + * @tx_errors: packet transmit problems + * @rx_dropped: no space in Linux buffers + * @tx_dropped: no space available in Linux + * @multicast: multicast packets received + * @collisions: collisions + * @rx_crc_errors: received packet with crc error + * @rx_frame_errors: received frame alignment error + * @rx_alloc_buff_failed: allocate failure of a receive buffer + * @tx_length_errors: transmit length error + * @tx_aborted_errors: transmit aborted error + * @tx_carrier_errors: transmit carrier error + * @tx_timeout_count: Number of transmit timeout + * @tx_restart_count: Number of transmit restert + * @intr_rx_dsc_empty_count: Interrupt count of receive descriptor empty + * @intr_rx_frame_err_count: Interrupt count of receive frame error + * @intr_rx_fifo_err_count: Interrupt count of receive FIFO error + * @intr_rx_dma_err_count: Interrupt count of receive DMA error + * @intr_tx_fifo_err_count: Interrupt count of transmit FIFO error + * @intr_tx_dma_err_count: Interrupt count of transmit DMA error + * @intr_tcpip_err_count: Interrupt count of TCP/IP Accelerator + */ +struct pch_gbe_hw_stats { + u32 rx_packets; + u32 tx_packets; + u32 rx_bytes; + u32 tx_bytes; + u32 rx_errors; + u32 tx_errors; + u32 rx_dropped; + u32 tx_dropped; + u32 multicast; + u32 collisions; + u32 rx_crc_errors; + u32 rx_frame_errors; + u32 rx_alloc_buff_failed; + u32 tx_length_errors; + u32 tx_aborted_errors; + u32 tx_carrier_errors; + u32 tx_timeout_count; + u32 tx_restart_count; + u32 intr_rx_dsc_empty_count; + u32 intr_rx_frame_err_count; + u32 intr_rx_fifo_err_count; + u32 intr_rx_dma_err_count; + u32 intr_tx_fifo_err_count; + u32 intr_tx_dma_err_count; + u32 intr_tcpip_err_count; +}; + +/** + * struct pch_gbe_adapter - board specific private data structure + * @stats_lock: Spinlock structure for status + * @tx_queue_lock: Spinlock structure for transmit + * @ethtool_lock: Spinlock structure for ethtool + * @irq_sem: Semaphore for interrupt + * @netdev: Pointer of network device structure + * @pdev: Pointer of pci device structure + * @polling_netdev: Pointer of polling network device structure + * @napi: NAPI structure + * @hw: Pointer of hardware structure + * @stats: Hardware status + * @reset_task: Reset task + * @mii: MII information structure + * @watchdog_timer: Watchdog timer list + * @wake_up_evt: Wake up event + * @config_space: Configuration space + * @msg_enable: Driver message level + * @led_status: LED status + * @tx_ring: Pointer of Tx descriptor ring structure + * @rx_ring: Pointer of Rx descriptor ring structure + * @rx_buffer_len: Receive buffer length + * @tx_queue_len: Transmit queue length + * @rx_csum: Receive TCP/IP checksum enable/disable + * @tx_csum: Transmit TCP/IP checksum enable/disable + * @have_msi: PCI MSI mode flag + */ + +struct pch_gbe_adapter { + spinlock_t stats_lock; + spinlock_t tx_queue_lock; + spinlock_t ethtool_lock; + atomic_t irq_sem; + struct net_device *netdev; + struct pci_dev *pdev; + struct net_device *polling_netdev; + struct napi_struct napi; + struct pch_gbe_hw hw; + struct pch_gbe_hw_stats stats; + struct work_struct reset_task; + struct mii_if_info mii; + struct timer_list watchdog_timer; + u32 wake_up_evt; + u32 *config_space; + unsigned long led_status; + struct pch_gbe_tx_ring *tx_ring; + struct pch_gbe_rx_ring *rx_ring; + unsigned long rx_buffer_len; + unsigned long tx_queue_len; + bool rx_csum; + bool tx_csum; + bool have_msi; +}; + +extern const char pch_driver_version[]; + +/* pch_gbe_main.c */ +extern int pch_gbe_up(struct pch_gbe_adapter *adapter); +extern void pch_gbe_down(struct pch_gbe_adapter *adapter); +extern void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter); +extern void pch_gbe_reset(struct pch_gbe_adapter *adapter); +extern int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *txdr); +extern int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rxdr); +extern void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring); +extern void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring); +extern void pch_gbe_update_stats(struct pch_gbe_adapter *adapter); + +/* pch_gbe_param.c */ +extern void pch_gbe_check_options(struct pch_gbe_adapter *adapter); + +/* pch_gbe_ethtool.c */ +extern void pch_gbe_set_ethtool_ops(struct net_device *netdev); + +/* pch_gbe_mac.c */ +extern s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw); +extern s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw); +extern u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, + u32 addr, u32 dir, u32 reg, u16 data); +#endif /* _PCH_GBE_H_ */ diff --git a/drivers/net/pch_gbe/pch_gbe_api.c b/drivers/net/pch_gbe/pch_gbe_api.c new file mode 100644 index 0000000000000000000000000000000000000000..e48f084ad226f5872f9fa5bd5275cd8de92066e7 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_api.c @@ -0,0 +1,245 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#include "pch_gbe.h" +#include "pch_gbe_phy.h" + +/* bus type values */ +#define pch_gbe_bus_type_unknown 0 +#define pch_gbe_bus_type_pci 1 +#define pch_gbe_bus_type_pcix 2 +#define pch_gbe_bus_type_pci_express 3 +#define pch_gbe_bus_type_reserved 4 + +/* bus speed values */ +#define pch_gbe_bus_speed_unknown 0 +#define pch_gbe_bus_speed_33 1 +#define pch_gbe_bus_speed_66 2 +#define pch_gbe_bus_speed_100 3 +#define pch_gbe_bus_speed_120 4 +#define pch_gbe_bus_speed_133 5 +#define pch_gbe_bus_speed_2500 6 +#define pch_gbe_bus_speed_reserved 7 + +/* bus width values */ +#define pch_gbe_bus_width_unknown 0 +#define pch_gbe_bus_width_pcie_x1 1 +#define pch_gbe_bus_width_pcie_x2 2 +#define pch_gbe_bus_width_pcie_x4 4 +#define pch_gbe_bus_width_32 5 +#define pch_gbe_bus_width_64 6 +#define pch_gbe_bus_width_reserved 7 + +/** + * pch_gbe_plat_get_bus_info - Obtain bus information for adapter + * @hw: Pointer to the HW structure + */ +static void pch_gbe_plat_get_bus_info(struct pch_gbe_hw *hw) +{ + hw->bus.type = pch_gbe_bus_type_pci_express; + hw->bus.speed = pch_gbe_bus_speed_2500; + hw->bus.width = pch_gbe_bus_width_pcie_x1; +} + +/** + * pch_gbe_plat_init_hw - Initialize hardware + * @hw: Pointer to the HW structure + * Returns + * 0: Successfully + * Negative value: Failed-EBUSY + */ +static s32 pch_gbe_plat_init_hw(struct pch_gbe_hw *hw) +{ + s32 ret_val; + + ret_val = pch_gbe_phy_get_id(hw); + if (ret_val) { + pr_err("pch_gbe_phy_get_id error\n"); + return ret_val; + } + pch_gbe_phy_init_setting(hw); + /* Setup Mac interface option RGMII */ +#ifdef PCH_GBE_MAC_IFOP_RGMII + pch_gbe_phy_set_rgmii(hw); +#endif + return ret_val; +} + +static const struct pch_gbe_functions pch_gbe_ops = { + .get_bus_info = pch_gbe_plat_get_bus_info, + .init_hw = pch_gbe_plat_init_hw, + .read_phy_reg = pch_gbe_phy_read_reg_miic, + .write_phy_reg = pch_gbe_phy_write_reg_miic, + .reset_phy = pch_gbe_phy_hw_reset, + .sw_reset_phy = pch_gbe_phy_sw_reset, + .power_up_phy = pch_gbe_phy_power_up, + .power_down_phy = pch_gbe_phy_power_down, + .read_mac_addr = pch_gbe_mac_read_mac_addr +}; + +/** + * pch_gbe_plat_init_function_pointers - Init func ptrs + * @hw: Pointer to the HW structure + */ +static void pch_gbe_plat_init_function_pointers(struct pch_gbe_hw *hw) +{ + /* Set PHY parameter */ + hw->phy.reset_delay_us = PCH_GBE_PHY_RESET_DELAY_US; + /* Set function pointers */ + hw->func = &pch_gbe_ops; +} + +/** + * pch_gbe_hal_setup_init_funcs - Initializes function pointers + * @hw: Pointer to the HW structure + * Returns + * 0: Successfully + * ENOSYS: Function is not registered + */ +inline s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw) +{ + if (!hw->reg) { + pr_err("ERROR: Registers not mapped\n"); + return -ENOSYS; + } + pch_gbe_plat_init_function_pointers(hw); + return 0; +} + +/** + * pch_gbe_hal_get_bus_info - Obtain bus information for adapter + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw) +{ + if (!hw->func->get_bus_info) + pr_err("ERROR: configuration\n"); + else + hw->func->get_bus_info(hw); +} + +/** + * pch_gbe_hal_init_hw - Initialize hardware + * @hw: Pointer to the HW structure + * Returns + * 0: Successfully + * ENOSYS: Function is not registered + */ +inline s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw) +{ + if (!hw->func->init_hw) { + pr_err("ERROR: configuration\n"); + return -ENOSYS; + } + return hw->func->init_hw(hw); +} + +/** + * pch_gbe_hal_read_phy_reg - Reads PHY register + * @hw: Pointer to the HW structure + * @offset: The register to read + * @data: The buffer to store the 16-bit read. + * Returns + * 0: Successfully + * Negative value: Failed + */ +inline s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, + u16 *data) +{ + if (!hw->func->read_phy_reg) + return 0; + return hw->func->read_phy_reg(hw, offset, data); +} + +/** + * pch_gbe_hal_write_phy_reg - Writes PHY register + * @hw: Pointer to the HW structure + * @offset: The register to read + * @data: The value to write. + * Returns + * 0: Successfully + * Negative value: Failed + */ +inline s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, + u16 data) +{ + if (!hw->func->write_phy_reg) + return 0; + return hw->func->write_phy_reg(hw, offset, data); +} + +/** + * pch_gbe_hal_phy_hw_reset - Hard PHY reset + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw) +{ + if (!hw->func->reset_phy) + pr_err("ERROR: configuration\n"); + else + hw->func->reset_phy(hw); +} + +/** + * pch_gbe_hal_phy_sw_reset - Soft PHY reset + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw) +{ + if (!hw->func->sw_reset_phy) + pr_err("ERROR: configuration\n"); + else + hw->func->sw_reset_phy(hw); +} + +/** + * pch_gbe_hal_read_mac_addr - Reads MAC address + * @hw: Pointer to the HW structure + * Returns + * 0: Successfully + * ENOSYS: Function is not registered + */ +inline s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw) +{ + if (!hw->func->read_mac_addr) { + pr_err("ERROR: configuration\n"); + return -ENOSYS; + } + return hw->func->read_mac_addr(hw); +} + +/** + * pch_gbe_hal_power_up_phy - Power up PHY + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw) +{ + if (hw->func->power_up_phy) + hw->func->power_up_phy(hw); +} + +/** + * pch_gbe_hal_power_down_phy - Power down PHY + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw) +{ + if (hw->func->power_down_phy) + hw->func->power_down_phy(hw); +} diff --git a/drivers/net/pch_gbe/pch_gbe_api.h b/drivers/net/pch_gbe/pch_gbe_api.h new file mode 100644 index 0000000000000000000000000000000000000000..94aaac5b057bcb0bbd9bda5bbaec8cc8db718dcc --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_api.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _PCH_GBE_API_H_ +#define _PCH_GBE_API_H_ + +#include "pch_gbe_phy.h" + +s32 pch_gbe_hal_setup_init_funcs(struct pch_gbe_hw *hw); +void pch_gbe_hal_get_bus_info(struct pch_gbe_hw *hw); +s32 pch_gbe_hal_init_hw(struct pch_gbe_hw *hw); +s32 pch_gbe_hal_read_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 *data); +s32 pch_gbe_hal_write_phy_reg(struct pch_gbe_hw *hw, u32 offset, u16 data); +void pch_gbe_hal_phy_hw_reset(struct pch_gbe_hw *hw); +void pch_gbe_hal_phy_sw_reset(struct pch_gbe_hw *hw); +s32 pch_gbe_hal_read_mac_addr(struct pch_gbe_hw *hw); +void pch_gbe_hal_power_up_phy(struct pch_gbe_hw *hw); +void pch_gbe_hal_power_down_phy(struct pch_gbe_hw *hw); + +#endif diff --git a/drivers/net/pch_gbe/pch_gbe_ethtool.c b/drivers/net/pch_gbe/pch_gbe_ethtool.c new file mode 100644 index 0000000000000000000000000000000000000000..c8cc32c0edc9678d6174693412e977e43a4ebf29 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_ethtool.c @@ -0,0 +1,585 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#include "pch_gbe.h" +#include "pch_gbe_api.h" + +/** + * pch_gbe_stats - Stats item infomation + */ +struct pch_gbe_stats { + char string[ETH_GSTRING_LEN]; + size_t size; + size_t offset; +}; + +#define PCH_GBE_STAT(m) \ +{ \ + .string = #m, \ + .size = FIELD_SIZEOF(struct pch_gbe_hw_stats, m), \ + .offset = offsetof(struct pch_gbe_hw_stats, m), \ +} + +/** + * pch_gbe_gstrings_stats - ethtool information status name list + */ +static const struct pch_gbe_stats pch_gbe_gstrings_stats[] = { + PCH_GBE_STAT(rx_packets), + PCH_GBE_STAT(tx_packets), + PCH_GBE_STAT(rx_bytes), + PCH_GBE_STAT(tx_bytes), + PCH_GBE_STAT(rx_errors), + PCH_GBE_STAT(tx_errors), + PCH_GBE_STAT(rx_dropped), + PCH_GBE_STAT(tx_dropped), + PCH_GBE_STAT(multicast), + PCH_GBE_STAT(collisions), + PCH_GBE_STAT(rx_crc_errors), + PCH_GBE_STAT(rx_frame_errors), + PCH_GBE_STAT(rx_alloc_buff_failed), + PCH_GBE_STAT(tx_length_errors), + PCH_GBE_STAT(tx_aborted_errors), + PCH_GBE_STAT(tx_carrier_errors), + PCH_GBE_STAT(tx_timeout_count), + PCH_GBE_STAT(tx_restart_count), + PCH_GBE_STAT(intr_rx_dsc_empty_count), + PCH_GBE_STAT(intr_rx_frame_err_count), + PCH_GBE_STAT(intr_rx_fifo_err_count), + PCH_GBE_STAT(intr_rx_dma_err_count), + PCH_GBE_STAT(intr_tx_fifo_err_count), + PCH_GBE_STAT(intr_tx_dma_err_count), + PCH_GBE_STAT(intr_tcpip_err_count) +}; + +#define PCH_GBE_QUEUE_STATS_LEN 0 +#define PCH_GBE_GLOBAL_STATS_LEN ARRAY_SIZE(pch_gbe_gstrings_stats) +#define PCH_GBE_STATS_LEN (PCH_GBE_GLOBAL_STATS_LEN + PCH_GBE_QUEUE_STATS_LEN) + +#define PCH_GBE_MAC_REGS_LEN (sizeof(struct pch_gbe_regs) / 4) +#define PCH_GBE_REGS_LEN (PCH_GBE_MAC_REGS_LEN + PCH_GBE_PHY_REGS_LEN) +/** + * pch_gbe_get_settings - Get device-specific settings + * @netdev: Network interface device structure + * @ecmd: Ethtool command + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_get_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + int ret; + + ret = mii_ethtool_gset(&adapter->mii, ecmd); + ecmd->supported &= ~(SUPPORTED_TP | SUPPORTED_1000baseT_Half); + ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half); + + if (!netif_carrier_ok(adapter->netdev)) + ecmd->speed = -1; + return ret; +} + +/** + * pch_gbe_set_settings - Set device-specific settings + * @netdev: Network interface device structure + * @ecmd: Ethtool command + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_settings(struct net_device *netdev, + struct ethtool_cmd *ecmd) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + int ret; + + pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET); + + if (ecmd->speed == USHRT_MAX) { + ecmd->speed = SPEED_1000; + ecmd->duplex = DUPLEX_FULL; + } + ret = mii_ethtool_sset(&adapter->mii, ecmd); + if (ret) { + pr_err("Error: mii_ethtool_sset\n"); + return ret; + } + hw->mac.link_speed = ecmd->speed; + hw->mac.link_duplex = ecmd->duplex; + hw->phy.autoneg_advertised = ecmd->advertising; + hw->mac.autoneg = ecmd->autoneg; + pch_gbe_hal_phy_sw_reset(hw); + + /* reset the link */ + if (netif_running(adapter->netdev)) { + pch_gbe_down(adapter); + ret = pch_gbe_up(adapter); + } else { + pch_gbe_reset(adapter); + } + return ret; +} + +/** + * pch_gbe_get_regs_len - Report the size of device registers + * @netdev: Network interface device structure + * Returns: the size of device registers. + */ +static int pch_gbe_get_regs_len(struct net_device *netdev) +{ + return PCH_GBE_REGS_LEN * (int)sizeof(u32); +} + +/** + * pch_gbe_get_drvinfo - Report driver information + * @netdev: Network interface device structure + * @drvinfo: Driver information structure + */ +static void pch_gbe_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + strcpy(drvinfo->driver, KBUILD_MODNAME); + strcpy(drvinfo->version, pch_driver_version); + strcpy(drvinfo->fw_version, "N/A"); + strcpy(drvinfo->bus_info, pci_name(adapter->pdev)); + drvinfo->regdump_len = pch_gbe_get_regs_len(netdev); +} + +/** + * pch_gbe_get_regs - Get device registers + * @netdev: Network interface device structure + * @regs: Ethtool register structure + * @p: Buffer pointer of read device register date + */ +static void pch_gbe_get_regs(struct net_device *netdev, + struct ethtool_regs *regs, void *p) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; + u32 *regs_buff = p; + u16 i, tmp; + + regs->version = 0x1000000 | (__u32)pdev->revision << 16 | pdev->device; + for (i = 0; i < PCH_GBE_MAC_REGS_LEN; i++) + *regs_buff++ = ioread32(&hw->reg->INT_ST + i); + /* PHY register */ + for (i = 0; i < PCH_GBE_PHY_REGS_LEN; i++) { + pch_gbe_hal_read_phy_reg(&adapter->hw, i, &tmp); + *regs_buff++ = tmp; + } +} + +/** + * pch_gbe_get_wol - Report whether Wake-on-Lan is enabled + * @netdev: Network interface device structure + * @wol: Wake-on-Lan information + */ +static void pch_gbe_get_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + wol->supported = WAKE_UCAST | WAKE_MCAST | WAKE_BCAST | WAKE_MAGIC; + wol->wolopts = 0; + + if ((adapter->wake_up_evt & PCH_GBE_WLC_IND)) + wol->wolopts |= WAKE_UCAST; + if ((adapter->wake_up_evt & PCH_GBE_WLC_MLT)) + wol->wolopts |= WAKE_MCAST; + if ((adapter->wake_up_evt & PCH_GBE_WLC_BR)) + wol->wolopts |= WAKE_BCAST; + if ((adapter->wake_up_evt & PCH_GBE_WLC_MP)) + wol->wolopts |= WAKE_MAGIC; +} + +/** + * pch_gbe_set_wol - Turn Wake-on-Lan on or off + * @netdev: Network interface device structure + * @wol: Pointer of wake-on-Lan information straucture + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_wol(struct net_device *netdev, + struct ethtool_wolinfo *wol) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + if ((wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))) + return -EOPNOTSUPP; + /* these settings will always override what we currently have */ + adapter->wake_up_evt = 0; + + if ((wol->wolopts & WAKE_UCAST)) + adapter->wake_up_evt |= PCH_GBE_WLC_IND; + if ((wol->wolopts & WAKE_MCAST)) + adapter->wake_up_evt |= PCH_GBE_WLC_MLT; + if ((wol->wolopts & WAKE_BCAST)) + adapter->wake_up_evt |= PCH_GBE_WLC_BR; + if ((wol->wolopts & WAKE_MAGIC)) + adapter->wake_up_evt |= PCH_GBE_WLC_MP; + return 0; +} + +/** + * pch_gbe_nway_reset - Restart autonegotiation + * @netdev: Network interface device structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_nway_reset(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + return mii_nway_restart(&adapter->mii); +} + +/** + * pch_gbe_get_ringparam - Report ring sizes + * @netdev: Network interface device structure + * @ring: Ring param structure + */ +static void pch_gbe_get_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_tx_ring *txdr = adapter->tx_ring; + struct pch_gbe_rx_ring *rxdr = adapter->rx_ring; + + ring->rx_max_pending = PCH_GBE_MAX_RXD; + ring->tx_max_pending = PCH_GBE_MAX_TXD; + ring->rx_mini_max_pending = 0; + ring->rx_jumbo_max_pending = 0; + ring->rx_pending = rxdr->count; + ring->tx_pending = txdr->count; + ring->rx_mini_pending = 0; + ring->rx_jumbo_pending = 0; +} + +/** + * pch_gbe_set_ringparam - Set ring sizes + * @netdev: Network interface device structure + * @ring: Ring param structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_ringparam(struct net_device *netdev, + struct ethtool_ringparam *ring) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_tx_ring *txdr, *tx_old; + struct pch_gbe_rx_ring *rxdr, *rx_old; + int tx_ring_size, rx_ring_size; + int err = 0; + + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + return -EINVAL; + tx_ring_size = (int)sizeof(struct pch_gbe_tx_ring); + rx_ring_size = (int)sizeof(struct pch_gbe_rx_ring); + + if ((netif_running(adapter->netdev))) + pch_gbe_down(adapter); + tx_old = adapter->tx_ring; + rx_old = adapter->rx_ring; + + txdr = kzalloc(tx_ring_size, GFP_KERNEL); + if (!txdr) { + err = -ENOMEM; + goto err_alloc_tx; + } + rxdr = kzalloc(rx_ring_size, GFP_KERNEL); + if (!rxdr) { + err = -ENOMEM; + goto err_alloc_rx; + } + adapter->tx_ring = txdr; + adapter->rx_ring = rxdr; + + rxdr->count = + clamp_val(ring->rx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD); + rxdr->count = roundup(rxdr->count, PCH_GBE_RX_DESC_MULTIPLE); + + txdr->count = + clamp_val(ring->tx_pending, PCH_GBE_MIN_RXD, PCH_GBE_MAX_RXD); + txdr->count = roundup(txdr->count, PCH_GBE_TX_DESC_MULTIPLE); + + if ((netif_running(adapter->netdev))) { + /* Try to get new resources before deleting old */ + err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring); + if (err) + goto err_setup_rx; + err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring); + if (err) + goto err_setup_tx; + /* save the new, restore the old in order to free it, + * then restore the new back again */ +#ifdef RINGFREE + adapter->rx_ring = rx_old; + adapter->tx_ring = tx_old; + pch_gbe_free_rx_resources(adapter, adapter->rx_ring); + pch_gbe_free_tx_resources(adapter, adapter->tx_ring); + kfree(tx_old); + kfree(rx_old); + adapter->rx_ring = rxdr; + adapter->tx_ring = txdr; +#else + pch_gbe_free_rx_resources(adapter, rx_old); + pch_gbe_free_tx_resources(adapter, tx_old); + kfree(tx_old); + kfree(rx_old); + adapter->rx_ring = rxdr; + adapter->tx_ring = txdr; +#endif + err = pch_gbe_up(adapter); + } + return err; + +err_setup_tx: + pch_gbe_free_rx_resources(adapter, adapter->rx_ring); +err_setup_rx: + adapter->rx_ring = rx_old; + adapter->tx_ring = tx_old; + kfree(rxdr); +err_alloc_rx: + kfree(txdr); +err_alloc_tx: + if (netif_running(adapter->netdev)) + pch_gbe_up(adapter); + return err; +} + +/** + * pch_gbe_get_pauseparam - Report pause parameters + * @netdev: Network interface device structure + * @pause: Pause parameters structure + */ +static void pch_gbe_get_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + pause->autoneg = + ((hw->mac.fc_autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE); + + if (hw->mac.fc == PCH_GBE_FC_RX_PAUSE) { + pause->rx_pause = 1; + } else if (hw->mac.fc == PCH_GBE_FC_TX_PAUSE) { + pause->tx_pause = 1; + } else if (hw->mac.fc == PCH_GBE_FC_FULL) { + pause->rx_pause = 1; + pause->tx_pause = 1; + } +} + +/** + * pch_gbe_set_pauseparam - Set pause paramters + * @netdev: Network interface device structure + * @pause: Pause parameters structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + int ret = 0; + + hw->mac.fc_autoneg = pause->autoneg; + if ((pause->rx_pause) && (pause->tx_pause)) + hw->mac.fc = PCH_GBE_FC_FULL; + else if ((pause->rx_pause) && (!pause->tx_pause)) + hw->mac.fc = PCH_GBE_FC_RX_PAUSE; + else if ((!pause->rx_pause) && (pause->tx_pause)) + hw->mac.fc = PCH_GBE_FC_TX_PAUSE; + else if ((!pause->rx_pause) && (!pause->tx_pause)) + hw->mac.fc = PCH_GBE_FC_NONE; + + if (hw->mac.fc_autoneg == AUTONEG_ENABLE) { + if ((netif_running(adapter->netdev))) { + pch_gbe_down(adapter); + ret = pch_gbe_up(adapter); + } else { + pch_gbe_reset(adapter); + } + } else { + ret = pch_gbe_mac_force_mac_fc(hw); + } + return ret; +} + +/** + * pch_gbe_get_rx_csum - Report whether receive checksums are turned on or off + * @netdev: Network interface device structure + * Returns + * true(1): Checksum On + * false(0): Checksum Off + */ +static u32 pch_gbe_get_rx_csum(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + return adapter->rx_csum; +} + +/** + * pch_gbe_set_rx_csum - Turn receive checksum on or off + * @netdev: Network interface device structure + * @data: Checksum On[true] or Off[false] + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + adapter->rx_csum = data; + if ((netif_running(netdev))) + pch_gbe_reinit_locked(adapter); + else + pch_gbe_reset(adapter); + + return 0; +} + +/** + * pch_gbe_get_tx_csum - Report whether transmit checksums are turned on or off + * @netdev: Network interface device structure + * Returns + * true(1): Checksum On + * false(0): Checksum Off + */ +static u32 pch_gbe_get_tx_csum(struct net_device *netdev) +{ + return (netdev->features & NETIF_F_HW_CSUM) != 0; +} + +/** + * pch_gbe_set_tx_csum - Turn transmit checksums on or off + * @netdev: Network interface device structure + * @data: Checksum on[true] or off[false] + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + adapter->tx_csum = data; + if (data) + netdev->features |= NETIF_F_HW_CSUM; + else + netdev->features &= ~NETIF_F_HW_CSUM; + return 0; +} + +/** + * pch_gbe_get_strings - Return a set of strings that describe the requested + * objects + * @netdev: Network interface device structure + * @stringset: Select the stringset. [ETH_SS_TEST] [ETH_SS_STATS] + * @data: Pointer of read string data. + */ +static void pch_gbe_get_strings(struct net_device *netdev, u32 stringset, + u8 *data) +{ + u8 *p = data; + int i; + + switch (stringset) { + case (u32) ETH_SS_STATS: + for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) { + memcpy(p, pch_gbe_gstrings_stats[i].string, + ETH_GSTRING_LEN); + p += ETH_GSTRING_LEN; + } + break; + } +} + +/** + * pch_gbe_get_ethtool_stats - Return statistics about the device + * @netdev: Network interface device structure + * @stats: Ethtool statue structure + * @data: Pointer of read status area + */ +static void pch_gbe_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, u64 *data) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + int i; + const struct pch_gbe_stats *gstats = pch_gbe_gstrings_stats; + char *hw_stats = (char *)&adapter->stats; + + pch_gbe_update_stats(adapter); + for (i = 0; i < PCH_GBE_GLOBAL_STATS_LEN; i++) { + char *p = hw_stats + gstats->offset; + data[i] = gstats->size == sizeof(u64) ? *(u64 *)p:(*(u32 *)p); + gstats++; + } +} + +static int pch_gbe_get_sset_count(struct net_device *netdev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return PCH_GBE_STATS_LEN; + default: + return -EOPNOTSUPP; + } +} + +static const struct ethtool_ops pch_gbe_ethtool_ops = { + .get_settings = pch_gbe_get_settings, + .set_settings = pch_gbe_set_settings, + .get_drvinfo = pch_gbe_get_drvinfo, + .get_regs_len = pch_gbe_get_regs_len, + .get_regs = pch_gbe_get_regs, + .get_wol = pch_gbe_get_wol, + .set_wol = pch_gbe_set_wol, + .nway_reset = pch_gbe_nway_reset, + .get_link = ethtool_op_get_link, + .get_ringparam = pch_gbe_get_ringparam, + .set_ringparam = pch_gbe_set_ringparam, + .get_pauseparam = pch_gbe_get_pauseparam, + .set_pauseparam = pch_gbe_set_pauseparam, + .get_rx_csum = pch_gbe_get_rx_csum, + .set_rx_csum = pch_gbe_set_rx_csum, + .get_tx_csum = pch_gbe_get_tx_csum, + .set_tx_csum = pch_gbe_set_tx_csum, + .get_strings = pch_gbe_get_strings, + .get_ethtool_stats = pch_gbe_get_ethtool_stats, + .get_sset_count = pch_gbe_get_sset_count, +}; + +void pch_gbe_set_ethtool_ops(struct net_device *netdev) +{ + SET_ETHTOOL_OPS(netdev, &pch_gbe_ethtool_ops); +} diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c new file mode 100644 index 0000000000000000000000000000000000000000..472056b47440877f93c83a11d994fca16b99dd96 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_main.c @@ -0,0 +1,2477 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "pch_gbe.h" +#include "pch_gbe_api.h" + +#define DRV_VERSION "1.00" +const char pch_driver_version[] = DRV_VERSION; + +#define PCI_DEVICE_ID_INTEL_IOH1_GBE 0x8802 /* Pci device ID */ +#define PCH_GBE_MAR_ENTRIES 16 +#define PCH_GBE_SHORT_PKT 64 +#define DSC_INIT16 0xC000 +#define PCH_GBE_DMA_ALIGN 0 +#define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ +#define PCH_GBE_COPYBREAK_DEFAULT 256 +#define PCH_GBE_PCI_BAR 1 + +#define PCH_GBE_TX_WEIGHT 64 +#define PCH_GBE_RX_WEIGHT 64 +#define PCH_GBE_RX_BUFFER_WRITE 16 + +/* Initialize the wake-on-LAN settings */ +#define PCH_GBE_WL_INIT_SETTING (PCH_GBE_WLC_MP) + +#define PCH_GBE_MAC_RGMII_CTRL_SETTING ( \ + PCH_GBE_CHIP_TYPE_INTERNAL | \ + PCH_GBE_RGMII_MODE_RGMII | \ + PCH_GBE_CRS_SEL \ + ) + +/* Ethertype field values */ +#define PCH_GBE_MAX_JUMBO_FRAME_SIZE 10318 +#define PCH_GBE_FRAME_SIZE_2048 2048 +#define PCH_GBE_FRAME_SIZE_4096 4096 +#define PCH_GBE_FRAME_SIZE_8192 8192 + +#define PCH_GBE_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) +#define PCH_GBE_RX_DESC(R, i) PCH_GBE_GET_DESC(R, i, pch_gbe_rx_desc) +#define PCH_GBE_TX_DESC(R, i) PCH_GBE_GET_DESC(R, i, pch_gbe_tx_desc) +#define PCH_GBE_DESC_UNUSED(R) \ + ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \ + (R)->next_to_clean - (R)->next_to_use - 1) + +/* Pause packet value */ +#define PCH_GBE_PAUSE_PKT1_VALUE 0x00C28001 +#define PCH_GBE_PAUSE_PKT2_VALUE 0x00000100 +#define PCH_GBE_PAUSE_PKT4_VALUE 0x01000888 +#define PCH_GBE_PAUSE_PKT5_VALUE 0x0000FFFF + +#define PCH_GBE_ETH_ALEN 6 + +/* This defines the bits that are set in the Interrupt Mask + * Set/Read Register. Each bit is documented below: + * o RXT0 = Receiver Timer Interrupt (ring 0) + * o TXDW = Transmit Descriptor Written Back + * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) + * o RXSEQ = Receive Sequence Error + * o LSC = Link Status Change + */ +#define PCH_GBE_INT_ENABLE_MASK ( \ + PCH_GBE_INT_RX_DMA_CMPLT | \ + PCH_GBE_INT_RX_DSC_EMP | \ + PCH_GBE_INT_WOL_DET | \ + PCH_GBE_INT_TX_CMPLT \ + ) + + +static unsigned int copybreak __read_mostly = PCH_GBE_COPYBREAK_DEFAULT; + +static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg); +static void pch_gbe_mdio_write(struct net_device *netdev, int addr, int reg, + int data); +/** + * pch_gbe_mac_read_mac_addr - Read MAC address + * @hw: Pointer to the HW structure + * Returns + * 0: Successful. + */ +s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw) +{ + u32 adr1a, adr1b; + + adr1a = ioread32(&hw->reg->mac_adr[0].high); + adr1b = ioread32(&hw->reg->mac_adr[0].low); + + hw->mac.addr[0] = (u8)(adr1a & 0xFF); + hw->mac.addr[1] = (u8)((adr1a >> 8) & 0xFF); + hw->mac.addr[2] = (u8)((adr1a >> 16) & 0xFF); + hw->mac.addr[3] = (u8)((adr1a >> 24) & 0xFF); + hw->mac.addr[4] = (u8)(adr1b & 0xFF); + hw->mac.addr[5] = (u8)((adr1b >> 8) & 0xFF); + + pr_debug("hw->mac.addr : %pM\n", hw->mac.addr); + return 0; +} + +/** + * pch_gbe_wait_clr_bit - Wait to clear a bit + * @reg: Pointer of register + * @busy: Busy bit + */ +static void pch_gbe_wait_clr_bit(void *reg, u32 bit) +{ + u32 tmp; + /* wait busy */ + tmp = 1000; + while ((ioread32(reg) & bit) && --tmp) + cpu_relax(); + if (!tmp) + pr_err("Error: busy bit is not cleared\n"); +} +/** + * pch_gbe_mac_mar_set - Set MAC address register + * @hw: Pointer to the HW structure + * @addr: Pointer to the MAC address + * @index: MAC address array register + */ +static void pch_gbe_mac_mar_set(struct pch_gbe_hw *hw, u8 * addr, u32 index) +{ + u32 mar_low, mar_high, adrmask; + + pr_debug("index : 0x%x\n", index); + + /* + * HW expects these in little endian so we reverse the byte order + * from network order (big endian) to little endian + */ + mar_high = ((u32) addr[0] | ((u32) addr[1] << 8) | + ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); + mar_low = ((u32) addr[4] | ((u32) addr[5] << 8)); + /* Stop the MAC Address of index. */ + adrmask = ioread32(&hw->reg->ADDR_MASK); + iowrite32((adrmask | (0x0001 << index)), &hw->reg->ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); + /* Set the MAC address to the MAC address 1A/1B register */ + iowrite32(mar_high, &hw->reg->mac_adr[index].high); + iowrite32(mar_low, &hw->reg->mac_adr[index].low); + /* Start the MAC address of index */ + iowrite32((adrmask & ~(0x0001 << index)), &hw->reg->ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); +} + +/** + * pch_gbe_mac_reset_hw - Reset hardware + * @hw: Pointer to the HW structure + */ +static void pch_gbe_mac_reset_hw(struct pch_gbe_hw *hw) +{ + /* Read the MAC address. and store to the private data */ + pch_gbe_mac_read_mac_addr(hw); + iowrite32(PCH_GBE_ALL_RST, &hw->reg->RESET); +#ifdef PCH_GBE_MAC_IFOP_RGMII + iowrite32(PCH_GBE_MODE_GMII_ETHER, &hw->reg->MODE); +#endif + pch_gbe_wait_clr_bit(&hw->reg->RESET, PCH_GBE_ALL_RST); + /* Setup the receive address */ + pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); + return; +} + +/** + * pch_gbe_mac_init_rx_addrs - Initialize receive address's + * @hw: Pointer to the HW structure + * @mar_count: Receive address registers + */ +static void pch_gbe_mac_init_rx_addrs(struct pch_gbe_hw *hw, u16 mar_count) +{ + u32 i; + + /* Setup the receive address */ + pch_gbe_mac_mar_set(hw, hw->mac.addr, 0); + + /* Zero out the other receive addresses */ + for (i = 1; i < mar_count; i++) { + iowrite32(0, &hw->reg->mac_adr[i].high); + iowrite32(0, &hw->reg->mac_adr[i].low); + } + iowrite32(0xFFFE, &hw->reg->ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); +} + + +/** + * pch_gbe_mac_mc_addr_list_update - Update Multicast addresses + * @hw: Pointer to the HW structure + * @mc_addr_list: Array of multicast addresses to program + * @mc_addr_count: Number of multicast addresses to program + * @mar_used_count: The first MAC Address register free to program + * @mar_total_num: Total number of supported MAC Address Registers + */ +static void pch_gbe_mac_mc_addr_list_update(struct pch_gbe_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count, + u32 mar_used_count, u32 mar_total_num) +{ + u32 i, adrmask; + + /* Load the first set of multicast addresses into the exact + * filters (RAR). If there are not enough to fill the RAR + * array, clear the filters. + */ + for (i = mar_used_count; i < mar_total_num; i++) { + if (mc_addr_count) { + pch_gbe_mac_mar_set(hw, mc_addr_list, i); + mc_addr_count--; + mc_addr_list += PCH_GBE_ETH_ALEN; + } else { + /* Clear MAC address mask */ + adrmask = ioread32(&hw->reg->ADDR_MASK); + iowrite32((adrmask | (0x0001 << i)), + &hw->reg->ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->ADDR_MASK, PCH_GBE_BUSY); + /* Clear MAC address */ + iowrite32(0, &hw->reg->mac_adr[i].high); + iowrite32(0, &hw->reg->mac_adr[i].low); + } + } +} + +/** + * pch_gbe_mac_force_mac_fc - Force the MAC's flow control settings + * @hw: Pointer to the HW structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +s32 pch_gbe_mac_force_mac_fc(struct pch_gbe_hw *hw) +{ + struct pch_gbe_mac_info *mac = &hw->mac; + u32 rx_fctrl; + + pr_debug("mac->fc = %u\n", mac->fc); + + rx_fctrl = ioread32(&hw->reg->RX_FCTRL); + + switch (mac->fc) { + case PCH_GBE_FC_NONE: + rx_fctrl &= ~PCH_GBE_FL_CTRL_EN; + mac->tx_fc_enable = false; + break; + case PCH_GBE_FC_RX_PAUSE: + rx_fctrl |= PCH_GBE_FL_CTRL_EN; + mac->tx_fc_enable = false; + break; + case PCH_GBE_FC_TX_PAUSE: + rx_fctrl &= ~PCH_GBE_FL_CTRL_EN; + mac->tx_fc_enable = true; + break; + case PCH_GBE_FC_FULL: + rx_fctrl |= PCH_GBE_FL_CTRL_EN; + mac->tx_fc_enable = true; + break; + default: + pr_err("Flow control param set incorrectly\n"); + return -EINVAL; + } + if (mac->link_duplex == DUPLEX_HALF) + rx_fctrl &= ~PCH_GBE_FL_CTRL_EN; + iowrite32(rx_fctrl, &hw->reg->RX_FCTRL); + pr_debug("RX_FCTRL reg : 0x%08x mac->tx_fc_enable : %d\n", + ioread32(&hw->reg->RX_FCTRL), mac->tx_fc_enable); + return 0; +} + +/** + * pch_gbe_mac_set_wol_event - Set wake-on-lan event + * @hw: Pointer to the HW structure + * @wu_evt: Wake up event + */ +static void pch_gbe_mac_set_wol_event(struct pch_gbe_hw *hw, u32 wu_evt) +{ + u32 addr_mask; + + pr_debug("wu_evt : 0x%08x ADDR_MASK reg : 0x%08x\n", + wu_evt, ioread32(&hw->reg->ADDR_MASK)); + + if (wu_evt) { + /* Set Wake-On-Lan address mask */ + addr_mask = ioread32(&hw->reg->ADDR_MASK); + iowrite32(addr_mask, &hw->reg->WOL_ADDR_MASK); + /* wait busy */ + pch_gbe_wait_clr_bit(&hw->reg->WOL_ADDR_MASK, PCH_GBE_WLA_BUSY); + iowrite32(0, &hw->reg->WOL_ST); + iowrite32((wu_evt | PCH_GBE_WLC_WOL_MODE), &hw->reg->WOL_CTRL); + iowrite32(0x02, &hw->reg->TCPIP_ACC); + iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN); + } else { + iowrite32(0, &hw->reg->WOL_CTRL); + iowrite32(0, &hw->reg->WOL_ST); + } + return; +} + +/** + * pch_gbe_mac_ctrl_miim - Control MIIM interface + * @hw: Pointer to the HW structure + * @addr: Address of PHY + * @dir: Operetion. (Write or Read) + * @reg: Access register of PHY + * @data: Write data. + * + * Returns: Read date. + */ +u16 pch_gbe_mac_ctrl_miim(struct pch_gbe_hw *hw, u32 addr, u32 dir, u32 reg, + u16 data) +{ + u32 data_out = 0; + unsigned int i; + unsigned long flags; + + spin_lock_irqsave(&hw->miim_lock, flags); + + for (i = 100; i; --i) { + if ((ioread32(&hw->reg->MIIM) & PCH_GBE_MIIM_OPER_READY)) + break; + udelay(20); + } + if (i == 0) { + pr_err("pch-gbe.miim won't go Ready\n"); + spin_unlock_irqrestore(&hw->miim_lock, flags); + return 0; /* No way to indicate timeout error */ + } + iowrite32(((reg << PCH_GBE_MIIM_REG_ADDR_SHIFT) | + (addr << PCH_GBE_MIIM_PHY_ADDR_SHIFT) | + dir | data), &hw->reg->MIIM); + for (i = 0; i < 100; i++) { + udelay(20); + data_out = ioread32(&hw->reg->MIIM); + if ((data_out & PCH_GBE_MIIM_OPER_READY)) + break; + } + spin_unlock_irqrestore(&hw->miim_lock, flags); + + pr_debug("PHY %s: reg=%d, data=0x%04X\n", + dir == PCH_GBE_MIIM_OPER_READ ? "READ" : "WRITE", reg, + dir == PCH_GBE_MIIM_OPER_READ ? data_out : data); + return (u16) data_out; +} + +/** + * pch_gbe_mac_set_pause_packet - Set pause packet + * @hw: Pointer to the HW structure + */ +static void pch_gbe_mac_set_pause_packet(struct pch_gbe_hw *hw) +{ + unsigned long tmp2, tmp3; + + /* Set Pause packet */ + tmp2 = hw->mac.addr[1]; + tmp2 = (tmp2 << 8) | hw->mac.addr[0]; + tmp2 = PCH_GBE_PAUSE_PKT2_VALUE | (tmp2 << 16); + + tmp3 = hw->mac.addr[5]; + tmp3 = (tmp3 << 8) | hw->mac.addr[4]; + tmp3 = (tmp3 << 8) | hw->mac.addr[3]; + tmp3 = (tmp3 << 8) | hw->mac.addr[2]; + + iowrite32(PCH_GBE_PAUSE_PKT1_VALUE, &hw->reg->PAUSE_PKT1); + iowrite32(tmp2, &hw->reg->PAUSE_PKT2); + iowrite32(tmp3, &hw->reg->PAUSE_PKT3); + iowrite32(PCH_GBE_PAUSE_PKT4_VALUE, &hw->reg->PAUSE_PKT4); + iowrite32(PCH_GBE_PAUSE_PKT5_VALUE, &hw->reg->PAUSE_PKT5); + + /* Transmit Pause Packet */ + iowrite32(PCH_GBE_PS_PKT_RQ, &hw->reg->PAUSE_REQ); + + pr_debug("PAUSE_PKT1-5 reg : 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", + ioread32(&hw->reg->PAUSE_PKT1), ioread32(&hw->reg->PAUSE_PKT2), + ioread32(&hw->reg->PAUSE_PKT3), ioread32(&hw->reg->PAUSE_PKT4), + ioread32(&hw->reg->PAUSE_PKT5)); + + return; +} + + +/** + * pch_gbe_alloc_queues - Allocate memory for all rings + * @adapter: Board private structure to initialize + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_alloc_queues(struct pch_gbe_adapter *adapter) +{ + int size; + + size = (int)sizeof(struct pch_gbe_tx_ring); + adapter->tx_ring = kzalloc(size, GFP_KERNEL); + if (!adapter->tx_ring) + return -ENOMEM; + size = (int)sizeof(struct pch_gbe_rx_ring); + adapter->rx_ring = kzalloc(size, GFP_KERNEL); + if (!adapter->rx_ring) { + kfree(adapter->tx_ring); + return -ENOMEM; + } + return 0; +} + +/** + * pch_gbe_init_stats - Initialize status + * @adapter: Board private structure to initialize + */ +static void pch_gbe_init_stats(struct pch_gbe_adapter *adapter) +{ + memset(&adapter->stats, 0, sizeof(adapter->stats)); + return; +} + +/** + * pch_gbe_init_phy - Initialize PHY + * @adapter: Board private structure to initialize + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_init_phy(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + u32 addr; + u16 bmcr, stat; + + /* Discover phy addr by searching addrs in order {1,0,2,..., 31} */ + for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) { + adapter->mii.phy_id = (addr == 0) ? 1 : (addr == 1) ? 0 : addr; + bmcr = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMCR); + stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR); + stat = pch_gbe_mdio_read(netdev, adapter->mii.phy_id, MII_BMSR); + if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0)))) + break; + } + adapter->hw.phy.addr = adapter->mii.phy_id; + pr_debug("phy_addr = %d\n", adapter->mii.phy_id); + if (addr == 32) + return -EAGAIN; + /* Selected the phy and isolate the rest */ + for (addr = 0; addr < PCH_GBE_PHY_REGS_LEN; addr++) { + if (addr != adapter->mii.phy_id) { + pch_gbe_mdio_write(netdev, addr, MII_BMCR, + BMCR_ISOLATE); + } else { + bmcr = pch_gbe_mdio_read(netdev, addr, MII_BMCR); + pch_gbe_mdio_write(netdev, addr, MII_BMCR, + bmcr & ~BMCR_ISOLATE); + } + } + + /* MII setup */ + adapter->mii.phy_id_mask = 0x1F; + adapter->mii.reg_num_mask = 0x1F; + adapter->mii.dev = adapter->netdev; + adapter->mii.mdio_read = pch_gbe_mdio_read; + adapter->mii.mdio_write = pch_gbe_mdio_write; + adapter->mii.supports_gmii = mii_check_gmii_support(&adapter->mii); + return 0; +} + +/** + * pch_gbe_mdio_read - The read function for mii + * @netdev: Network interface device structure + * @addr: Phy ID + * @reg: Access location + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_mdio_read(struct net_device *netdev, int addr, int reg) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + return pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_READ, reg, + (u16) 0); +} + +/** + * pch_gbe_mdio_write - The write function for mii + * @netdev: Network interface device structure + * @addr: Phy ID (not used) + * @reg: Access location + * @data: Write data + */ +static void pch_gbe_mdio_write(struct net_device *netdev, + int addr, int reg, int data) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + pch_gbe_mac_ctrl_miim(hw, addr, PCH_GBE_HAL_MIIM_WRITE, reg, data); +} + +/** + * pch_gbe_reset_task - Reset processing at the time of transmission timeout + * @work: Pointer of board private structure + */ +static void pch_gbe_reset_task(struct work_struct *work) +{ + struct pch_gbe_adapter *adapter; + adapter = container_of(work, struct pch_gbe_adapter, reset_task); + + pch_gbe_reinit_locked(adapter); +} + +/** + * pch_gbe_reinit_locked- Re-initialization + * @adapter: Board private structure + */ +void pch_gbe_reinit_locked(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + rtnl_lock(); + if (netif_running(netdev)) { + pch_gbe_down(adapter); + pch_gbe_up(adapter); + } + rtnl_unlock(); +} + +/** + * pch_gbe_reset - Reset GbE + * @adapter: Board private structure + */ +void pch_gbe_reset(struct pch_gbe_adapter *adapter) +{ + pch_gbe_mac_reset_hw(&adapter->hw); + /* Setup the receive address. */ + pch_gbe_mac_init_rx_addrs(&adapter->hw, PCH_GBE_MAR_ENTRIES); + if (pch_gbe_hal_init_hw(&adapter->hw)) + pr_err("Hardware Error\n"); +} + +/** + * pch_gbe_free_irq - Free an interrupt + * @adapter: Board private structure + */ +static void pch_gbe_free_irq(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + free_irq(adapter->pdev->irq, netdev); + if (adapter->have_msi) { + pci_disable_msi(adapter->pdev); + pr_debug("call pci_disable_msi\n"); + } +} + +/** + * pch_gbe_irq_disable - Mask off interrupt generation on the NIC + * @adapter: Board private structure + */ +static void pch_gbe_irq_disable(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + + atomic_inc(&adapter->irq_sem); + iowrite32(0, &hw->reg->INT_EN); + ioread32(&hw->reg->INT_ST); + synchronize_irq(adapter->pdev->irq); + + pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN)); +} + +/** + * pch_gbe_irq_enable - Enable default interrupt generation settings + * @adapter: Board private structure + */ +static void pch_gbe_irq_enable(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + + if (likely(atomic_dec_and_test(&adapter->irq_sem))) + iowrite32(PCH_GBE_INT_ENABLE_MASK, &hw->reg->INT_EN); + ioread32(&hw->reg->INT_ST); + pr_debug("INT_EN reg : 0x%08x\n", ioread32(&hw->reg->INT_EN)); +} + + + +/** + * pch_gbe_setup_tctl - configure the Transmit control registers + * @adapter: Board private structure + */ +static void pch_gbe_setup_tctl(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + u32 tx_mode, tcpip; + + tx_mode = PCH_GBE_TM_LONG_PKT | + PCH_GBE_TM_ST_AND_FD | + PCH_GBE_TM_SHORT_PKT | + PCH_GBE_TM_TH_TX_STRT_8 | + PCH_GBE_TM_TH_ALM_EMP_4 | PCH_GBE_TM_TH_ALM_FULL_8; + + iowrite32(tx_mode, &hw->reg->TX_MODE); + + tcpip = ioread32(&hw->reg->TCPIP_ACC); + tcpip |= PCH_GBE_TX_TCPIPACC_EN; + iowrite32(tcpip, &hw->reg->TCPIP_ACC); + return; +} + +/** + * pch_gbe_configure_tx - Configure Transmit Unit after Reset + * @adapter: Board private structure + */ +static void pch_gbe_configure_tx(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + u32 tdba, tdlen, dctrl; + + pr_debug("dma addr = 0x%08llx size = 0x%08x\n", + (unsigned long long)adapter->tx_ring->dma, + adapter->tx_ring->size); + + /* Setup the HW Tx Head and Tail descriptor pointers */ + tdba = adapter->tx_ring->dma; + tdlen = adapter->tx_ring->size - 0x10; + iowrite32(tdba, &hw->reg->TX_DSC_BASE); + iowrite32(tdlen, &hw->reg->TX_DSC_SIZE); + iowrite32(tdba, &hw->reg->TX_DSC_SW_P); + + /* Enables Transmission DMA */ + dctrl = ioread32(&hw->reg->DMA_CTRL); + dctrl |= PCH_GBE_TX_DMA_EN; + iowrite32(dctrl, &hw->reg->DMA_CTRL); +} + +/** + * pch_gbe_setup_rctl - Configure the receive control registers + * @adapter: Board private structure + */ +static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + u32 rx_mode, tcpip; + + rx_mode = PCH_GBE_ADD_FIL_EN | PCH_GBE_MLT_FIL_EN | + PCH_GBE_RH_ALM_EMP_4 | PCH_GBE_RH_ALM_FULL_4 | PCH_GBE_RH_RD_TRG_8; + + iowrite32(rx_mode, &hw->reg->RX_MODE); + + tcpip = ioread32(&hw->reg->TCPIP_ACC); + + if (adapter->rx_csum) { + tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF; + tcpip |= PCH_GBE_RX_TCPIPACC_EN; + } else { + tcpip |= PCH_GBE_RX_TCPIPACC_OFF; + tcpip &= ~PCH_GBE_RX_TCPIPACC_EN; + } + iowrite32(tcpip, &hw->reg->TCPIP_ACC); + return; +} + +/** + * pch_gbe_configure_rx - Configure Receive Unit after Reset + * @adapter: Board private structure + */ +static void pch_gbe_configure_rx(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + u32 rdba, rdlen, rctl, rxdma; + + pr_debug("dma adr = 0x%08llx size = 0x%08x\n", + (unsigned long long)adapter->rx_ring->dma, + adapter->rx_ring->size); + + pch_gbe_mac_force_mac_fc(hw); + + /* Disables Receive MAC */ + rctl = ioread32(&hw->reg->MAC_RX_EN); + iowrite32((rctl & ~PCH_GBE_MRE_MAC_RX_EN), &hw->reg->MAC_RX_EN); + + /* Disables Receive DMA */ + rxdma = ioread32(&hw->reg->DMA_CTRL); + rxdma &= ~PCH_GBE_RX_DMA_EN; + iowrite32(rxdma, &hw->reg->DMA_CTRL); + + pr_debug("MAC_RX_EN reg = 0x%08x DMA_CTRL reg = 0x%08x\n", + ioread32(&hw->reg->MAC_RX_EN), + ioread32(&hw->reg->DMA_CTRL)); + + /* Setup the HW Rx Head and Tail Descriptor Pointers and + * the Base and Length of the Rx Descriptor Ring */ + rdba = adapter->rx_ring->dma; + rdlen = adapter->rx_ring->size - 0x10; + iowrite32(rdba, &hw->reg->RX_DSC_BASE); + iowrite32(rdlen, &hw->reg->RX_DSC_SIZE); + iowrite32((rdba + rdlen), &hw->reg->RX_DSC_SW_P); + + /* Enables Receive DMA */ + rxdma = ioread32(&hw->reg->DMA_CTRL); + rxdma |= PCH_GBE_RX_DMA_EN; + iowrite32(rxdma, &hw->reg->DMA_CTRL); + /* Enables Receive */ + iowrite32(PCH_GBE_MRE_MAC_RX_EN, &hw->reg->MAC_RX_EN); +} + +/** + * pch_gbe_unmap_and_free_tx_resource - Unmap and free tx socket buffer + * @adapter: Board private structure + * @buffer_info: Buffer information structure + */ +static void pch_gbe_unmap_and_free_tx_resource( + struct pch_gbe_adapter *adapter, struct pch_gbe_buffer *buffer_info) +{ + if (buffer_info->mapped) { + dma_unmap_single(&adapter->pdev->dev, buffer_info->dma, + buffer_info->length, DMA_TO_DEVICE); + buffer_info->mapped = false; + } + if (buffer_info->skb) { + dev_kfree_skb_any(buffer_info->skb); + buffer_info->skb = NULL; + } +} + +/** + * pch_gbe_unmap_and_free_rx_resource - Unmap and free rx socket buffer + * @adapter: Board private structure + * @buffer_info: Buffer information structure + */ +static void pch_gbe_unmap_and_free_rx_resource( + struct pch_gbe_adapter *adapter, + struct pch_gbe_buffer *buffer_info) +{ + if (buffer_info->mapped) { + dma_unmap_single(&adapter->pdev->dev, buffer_info->dma, + buffer_info->length, DMA_FROM_DEVICE); + buffer_info->mapped = false; + } + if (buffer_info->skb) { + dev_kfree_skb_any(buffer_info->skb); + buffer_info->skb = NULL; + } +} + +/** + * pch_gbe_clean_tx_ring - Free Tx Buffers + * @adapter: Board private structure + * @tx_ring: Ring to be cleaned + */ +static void pch_gbe_clean_tx_ring(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pch_gbe_hw *hw = &adapter->hw; + struct pch_gbe_buffer *buffer_info; + unsigned long size; + unsigned int i; + + /* Free all the Tx ring sk_buffs */ + for (i = 0; i < tx_ring->count; i++) { + buffer_info = &tx_ring->buffer_info[i]; + pch_gbe_unmap_and_free_tx_resource(adapter, buffer_info); + } + pr_debug("call pch_gbe_unmap_and_free_tx_resource() %d count\n", i); + + size = (unsigned long)sizeof(struct pch_gbe_buffer) * tx_ring->count; + memset(tx_ring->buffer_info, 0, size); + + /* Zero out the descriptor ring */ + memset(tx_ring->desc, 0, tx_ring->size); + tx_ring->next_to_use = 0; + tx_ring->next_to_clean = 0; + iowrite32(tx_ring->dma, &hw->reg->TX_DSC_HW_P); + iowrite32((tx_ring->size - 0x10), &hw->reg->TX_DSC_SIZE); +} + +/** + * pch_gbe_clean_rx_ring - Free Rx Buffers + * @adapter: Board private structure + * @rx_ring: Ring to free buffers from + */ +static void +pch_gbe_clean_rx_ring(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring) +{ + struct pch_gbe_hw *hw = &adapter->hw; + struct pch_gbe_buffer *buffer_info; + unsigned long size; + unsigned int i; + + /* Free all the Rx ring sk_buffs */ + for (i = 0; i < rx_ring->count; i++) { + buffer_info = &rx_ring->buffer_info[i]; + pch_gbe_unmap_and_free_rx_resource(adapter, buffer_info); + } + pr_debug("call pch_gbe_unmap_and_free_rx_resource() %d count\n", i); + size = (unsigned long)sizeof(struct pch_gbe_buffer) * rx_ring->count; + memset(rx_ring->buffer_info, 0, size); + + /* Zero out the descriptor ring */ + memset(rx_ring->desc, 0, rx_ring->size); + rx_ring->next_to_clean = 0; + rx_ring->next_to_use = 0; + iowrite32(rx_ring->dma, &hw->reg->RX_DSC_HW_P); + iowrite32((rx_ring->size - 0x10), &hw->reg->RX_DSC_SIZE); +} + +static void pch_gbe_set_rgmii_ctrl(struct pch_gbe_adapter *adapter, u16 speed, + u16 duplex) +{ + struct pch_gbe_hw *hw = &adapter->hw; + unsigned long rgmii = 0; + + /* Set the RGMII control. */ +#ifdef PCH_GBE_MAC_IFOP_RGMII + switch (speed) { + case SPEED_10: + rgmii = (PCH_GBE_RGMII_RATE_2_5M | + PCH_GBE_MAC_RGMII_CTRL_SETTING); + break; + case SPEED_100: + rgmii = (PCH_GBE_RGMII_RATE_25M | + PCH_GBE_MAC_RGMII_CTRL_SETTING); + break; + case SPEED_1000: + rgmii = (PCH_GBE_RGMII_RATE_125M | + PCH_GBE_MAC_RGMII_CTRL_SETTING); + break; + } + iowrite32(rgmii, &hw->reg->RGMII_CTRL); +#else /* GMII */ + rgmii = 0; + iowrite32(rgmii, &hw->reg->RGMII_CTRL); +#endif +} +static void pch_gbe_set_mode(struct pch_gbe_adapter *adapter, u16 speed, + u16 duplex) +{ + struct net_device *netdev = adapter->netdev; + struct pch_gbe_hw *hw = &adapter->hw; + unsigned long mode = 0; + + /* Set the communication mode */ + switch (speed) { + case SPEED_10: + mode = PCH_GBE_MODE_MII_ETHER; + netdev->tx_queue_len = 10; + break; + case SPEED_100: + mode = PCH_GBE_MODE_MII_ETHER; + netdev->tx_queue_len = 100; + break; + case SPEED_1000: + mode = PCH_GBE_MODE_GMII_ETHER; + break; + } + if (duplex == DUPLEX_FULL) + mode |= PCH_GBE_MODE_FULL_DUPLEX; + else + mode |= PCH_GBE_MODE_HALF_DUPLEX; + iowrite32(mode, &hw->reg->MODE); +} + +/** + * pch_gbe_watchdog - Watchdog process + * @data: Board private structure + */ +static void pch_gbe_watchdog(unsigned long data) +{ + struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data; + struct net_device *netdev = adapter->netdev; + struct pch_gbe_hw *hw = &adapter->hw; + struct ethtool_cmd cmd; + + pr_debug("right now = %ld\n", jiffies); + + pch_gbe_update_stats(adapter); + if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) { + netdev->tx_queue_len = adapter->tx_queue_len; + /* mii library handles link maintenance tasks */ + if (mii_ethtool_gset(&adapter->mii, &cmd)) { + pr_err("ethtool get setting Error\n"); + mod_timer(&adapter->watchdog_timer, + round_jiffies(jiffies + + PCH_GBE_WATCHDOG_PERIOD)); + return; + } + hw->mac.link_speed = cmd.speed; + hw->mac.link_duplex = cmd.duplex; + /* Set the RGMII control. */ + pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, + hw->mac.link_duplex); + /* Set the communication mode */ + pch_gbe_set_mode(adapter, hw->mac.link_speed, + hw->mac.link_duplex); + netdev_dbg(netdev, + "Link is Up %d Mbps %s-Duplex\n", + cmd.speed, + cmd.duplex == DUPLEX_FULL ? "Full" : "Half"); + netif_carrier_on(netdev); + netif_wake_queue(netdev); + } else if ((!mii_link_ok(&adapter->mii)) && + (netif_carrier_ok(netdev))) { + netdev_dbg(netdev, "NIC Link is Down\n"); + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + mod_timer(&adapter->watchdog_timer, + round_jiffies(jiffies + PCH_GBE_WATCHDOG_PERIOD)); +} + +/** + * pch_gbe_tx_queue - Carry out queuing of the transmission data + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring structure + * @skb: Sockt buffer structure + */ +static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring, + struct sk_buff *skb) +{ + struct pch_gbe_hw *hw = &adapter->hw; + struct pch_gbe_tx_desc *tx_desc; + struct pch_gbe_buffer *buffer_info; + struct sk_buff *tmp_skb; + unsigned int frame_ctrl; + unsigned int ring_num; + unsigned long flags; + + /*-- Set frame control --*/ + frame_ctrl = 0; + if (unlikely(skb->len < PCH_GBE_SHORT_PKT)) + frame_ctrl |= PCH_GBE_TXD_CTRL_APAD; + if (unlikely(!adapter->tx_csum)) + frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF; + + /* Performs checksum processing */ + /* + * It is because the hardware accelerator does not support a checksum, + * when the received data size is less than 64 bytes. + */ + if ((skb->len < PCH_GBE_SHORT_PKT) && (adapter->tx_csum)) { + frame_ctrl |= PCH_GBE_TXD_CTRL_APAD | + PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF; + if (skb->protocol == htons(ETH_P_IP)) { + struct iphdr *iph = ip_hdr(skb); + unsigned int offset; + iph->check = 0; + iph->check = ip_fast_csum((u8 *) iph, iph->ihl); + offset = skb_transport_offset(skb); + if (iph->protocol == IPPROTO_TCP) { + skb->csum = 0; + tcp_hdr(skb)->check = 0; + skb->csum = skb_checksum(skb, offset, + skb->len - offset, 0); + tcp_hdr(skb)->check = + csum_tcpudp_magic(iph->saddr, + iph->daddr, + skb->len - offset, + IPPROTO_TCP, + skb->csum); + } else if (iph->protocol == IPPROTO_UDP) { + skb->csum = 0; + udp_hdr(skb)->check = 0; + skb->csum = + skb_checksum(skb, offset, + skb->len - offset, 0); + udp_hdr(skb)->check = + csum_tcpudp_magic(iph->saddr, + iph->daddr, + skb->len - offset, + IPPROTO_UDP, + skb->csum); + } + } + } + spin_lock_irqsave(&tx_ring->tx_lock, flags); + ring_num = tx_ring->next_to_use; + if (unlikely((ring_num + 1) == tx_ring->count)) + tx_ring->next_to_use = 0; + else + tx_ring->next_to_use = ring_num + 1; + + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); + buffer_info = &tx_ring->buffer_info[ring_num]; + tmp_skb = buffer_info->skb; + + /* [Header:14][payload] ---> [Header:14][paddong:2][payload] */ + memcpy(tmp_skb->data, skb->data, ETH_HLEN); + tmp_skb->data[ETH_HLEN] = 0x00; + tmp_skb->data[ETH_HLEN + 1] = 0x00; + tmp_skb->len = skb->len; + memcpy(&tmp_skb->data[ETH_HLEN + 2], &skb->data[ETH_HLEN], + (skb->len - ETH_HLEN)); + /*-- Set Buffer infomation --*/ + buffer_info->length = tmp_skb->len; + buffer_info->dma = dma_map_single(&adapter->pdev->dev, tmp_skb->data, + buffer_info->length, + DMA_TO_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) { + pr_err("TX DMA map failed\n"); + buffer_info->dma = 0; + buffer_info->time_stamp = 0; + tx_ring->next_to_use = ring_num; + return; + } + buffer_info->mapped = true; + buffer_info->time_stamp = jiffies; + + /*-- Set Tx descriptor --*/ + tx_desc = PCH_GBE_TX_DESC(*tx_ring, ring_num); + tx_desc->buffer_addr = (buffer_info->dma); + tx_desc->length = (tmp_skb->len); + tx_desc->tx_words_eob = ((tmp_skb->len + 3)); + tx_desc->tx_frame_ctrl = (frame_ctrl); + tx_desc->gbec_status = (DSC_INIT16); + + if (unlikely(++ring_num == tx_ring->count)) + ring_num = 0; + + /* Update software pointer of TX descriptor */ + iowrite32(tx_ring->dma + + (int)sizeof(struct pch_gbe_tx_desc) * ring_num, + &hw->reg->TX_DSC_SW_P); + dev_kfree_skb_any(skb); +} + +/** + * pch_gbe_update_stats - Update the board statistics counters + * @adapter: Board private structure + */ +void pch_gbe_update_stats(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_hw_stats *stats = &adapter->stats; + unsigned long flags; + + /* + * Prevent stats update while adapter is being reset, or if the pci + * connection is down. + */ + if ((pdev->error_state) && (pdev->error_state != pci_channel_io_normal)) + return; + + spin_lock_irqsave(&adapter->stats_lock, flags); + + /* Update device status "adapter->stats" */ + stats->rx_errors = stats->rx_crc_errors + stats->rx_frame_errors; + stats->tx_errors = stats->tx_length_errors + + stats->tx_aborted_errors + + stats->tx_carrier_errors + stats->tx_timeout_count; + + /* Update network device status "adapter->net_stats" */ + netdev->stats.rx_packets = stats->rx_packets; + netdev->stats.rx_bytes = stats->rx_bytes; + netdev->stats.rx_dropped = stats->rx_dropped; + netdev->stats.tx_packets = stats->tx_packets; + netdev->stats.tx_bytes = stats->tx_bytes; + netdev->stats.tx_dropped = stats->tx_dropped; + /* Fill out the OS statistics structure */ + netdev->stats.multicast = stats->multicast; + netdev->stats.collisions = stats->collisions; + /* Rx Errors */ + netdev->stats.rx_errors = stats->rx_errors; + netdev->stats.rx_crc_errors = stats->rx_crc_errors; + netdev->stats.rx_frame_errors = stats->rx_frame_errors; + /* Tx Errors */ + netdev->stats.tx_errors = stats->tx_errors; + netdev->stats.tx_aborted_errors = stats->tx_aborted_errors; + netdev->stats.tx_carrier_errors = stats->tx_carrier_errors; + + spin_unlock_irqrestore(&adapter->stats_lock, flags); +} + +/** + * pch_gbe_intr - Interrupt Handler + * @irq: Interrupt number + * @data: Pointer to a network interface device structure + * Returns + * - IRQ_HANDLED: Our interrupt + * - IRQ_NONE: Not our interrupt + */ +static irqreturn_t pch_gbe_intr(int irq, void *data) +{ + struct net_device *netdev = data; + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + u32 int_st; + u32 int_en; + + /* Check request status */ + int_st = ioread32(&hw->reg->INT_ST); + int_st = int_st & ioread32(&hw->reg->INT_EN); + /* When request status is no interruption factor */ + if (unlikely(!int_st)) + return IRQ_NONE; /* Not our interrupt. End processing. */ + pr_debug("%s occur int_st = 0x%08x\n", __func__, int_st); + if (int_st & PCH_GBE_INT_RX_FRAME_ERR) + adapter->stats.intr_rx_frame_err_count++; + if (int_st & PCH_GBE_INT_RX_FIFO_ERR) + adapter->stats.intr_rx_fifo_err_count++; + if (int_st & PCH_GBE_INT_RX_DMA_ERR) + adapter->stats.intr_rx_dma_err_count++; + if (int_st & PCH_GBE_INT_TX_FIFO_ERR) + adapter->stats.intr_tx_fifo_err_count++; + if (int_st & PCH_GBE_INT_TX_DMA_ERR) + adapter->stats.intr_tx_dma_err_count++; + if (int_st & PCH_GBE_INT_TCPIP_ERR) + adapter->stats.intr_tcpip_err_count++; + /* When Rx descriptor is empty */ + if ((int_st & PCH_GBE_INT_RX_DSC_EMP)) { + adapter->stats.intr_rx_dsc_empty_count++; + pr_err("Rx descriptor is empty\n"); + int_en = ioread32(&hw->reg->INT_EN); + iowrite32((int_en & ~PCH_GBE_INT_RX_DSC_EMP), &hw->reg->INT_EN); + if (hw->mac.tx_fc_enable) { + /* Set Pause packet */ + pch_gbe_mac_set_pause_packet(hw); + } + if ((int_en & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT)) + == 0) { + return IRQ_HANDLED; + } + } + + /* When request status is Receive interruption */ + if ((int_st & (PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT))) { + if (likely(napi_schedule_prep(&adapter->napi))) { + /* Enable only Rx Descriptor empty */ + atomic_inc(&adapter->irq_sem); + int_en = ioread32(&hw->reg->INT_EN); + int_en &= + ~(PCH_GBE_INT_RX_DMA_CMPLT | PCH_GBE_INT_TX_CMPLT); + iowrite32(int_en, &hw->reg->INT_EN); + /* Start polling for NAPI */ + __napi_schedule(&adapter->napi); + } + } + pr_debug("return = 0x%08x INT_EN reg = 0x%08x\n", + IRQ_HANDLED, ioread32(&hw->reg->INT_EN)); + return IRQ_HANDLED; +} + +/** + * pch_gbe_alloc_rx_buffers - Replace used receive buffers; legacy & extended + * @adapter: Board private structure + * @rx_ring: Rx descriptor ring + * @cleaned_count: Cleaned count + */ +static void +pch_gbe_alloc_rx_buffers(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring, int cleaned_count) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_hw *hw = &adapter->hw; + struct pch_gbe_rx_desc *rx_desc; + struct pch_gbe_buffer *buffer_info; + struct sk_buff *skb; + unsigned int i; + unsigned int bufsz; + + bufsz = adapter->rx_buffer_len + PCH_GBE_DMA_ALIGN; + i = rx_ring->next_to_use; + + while ((cleaned_count--)) { + buffer_info = &rx_ring->buffer_info[i]; + skb = buffer_info->skb; + if (skb) { + skb_trim(skb, 0); + } else { + skb = netdev_alloc_skb(netdev, bufsz); + if (unlikely(!skb)) { + /* Better luck next round */ + adapter->stats.rx_alloc_buff_failed++; + break; + } + /* 64byte align */ + skb_reserve(skb, PCH_GBE_DMA_ALIGN); + + buffer_info->skb = skb; + buffer_info->length = adapter->rx_buffer_len; + } + buffer_info->dma = dma_map_single(&pdev->dev, + skb->data, + buffer_info->length, + DMA_FROM_DEVICE); + if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma)) { + dev_kfree_skb(skb); + buffer_info->skb = NULL; + buffer_info->dma = 0; + adapter->stats.rx_alloc_buff_failed++; + break; /* while !buffer_info->skb */ + } + buffer_info->mapped = true; + rx_desc = PCH_GBE_RX_DESC(*rx_ring, i); + rx_desc->buffer_addr = (buffer_info->dma); + rx_desc->gbec_status = DSC_INIT16; + + pr_debug("i = %d buffer_info->dma = 0x08%llx buffer_info->length = 0x%x\n", + i, (unsigned long long)buffer_info->dma, + buffer_info->length); + + if (unlikely(++i == rx_ring->count)) + i = 0; + } + if (likely(rx_ring->next_to_use != i)) { + rx_ring->next_to_use = i; + if (unlikely(i-- == 0)) + i = (rx_ring->count - 1); + iowrite32(rx_ring->dma + + (int)sizeof(struct pch_gbe_rx_desc) * i, + &hw->reg->RX_DSC_SW_P); + } + return; +} + +/** + * pch_gbe_alloc_tx_buffers - Allocate transmit buffers + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring + */ +static void pch_gbe_alloc_tx_buffers(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pch_gbe_buffer *buffer_info; + struct sk_buff *skb; + unsigned int i; + unsigned int bufsz; + struct pch_gbe_tx_desc *tx_desc; + + bufsz = + adapter->hw.mac.max_frame_size + PCH_GBE_DMA_ALIGN + NET_IP_ALIGN; + + for (i = 0; i < tx_ring->count; i++) { + buffer_info = &tx_ring->buffer_info[i]; + skb = netdev_alloc_skb(adapter->netdev, bufsz); + skb_reserve(skb, PCH_GBE_DMA_ALIGN); + buffer_info->skb = skb; + tx_desc = PCH_GBE_TX_DESC(*tx_ring, i); + tx_desc->gbec_status = (DSC_INIT16); + } + return; +} + +/** + * pch_gbe_clean_tx - Reclaim resources after transmit completes + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring + * Returns + * true: Cleaned the descriptor + * false: Not cleaned the descriptor + */ +static bool +pch_gbe_clean_tx(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pch_gbe_tx_desc *tx_desc; + struct pch_gbe_buffer *buffer_info; + struct sk_buff *skb; + unsigned int i; + unsigned int cleaned_count = 0; + bool cleaned = false; + + pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); + + i = tx_ring->next_to_clean; + tx_desc = PCH_GBE_TX_DESC(*tx_ring, i); + pr_debug("gbec_status:0x%04x dma_status:0x%04x\n", + tx_desc->gbec_status, tx_desc->dma_status); + + while ((tx_desc->gbec_status & DSC_INIT16) == 0x0000) { + pr_debug("gbec_status:0x%04x\n", tx_desc->gbec_status); + cleaned = true; + buffer_info = &tx_ring->buffer_info[i]; + skb = buffer_info->skb; + + if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_ABT)) { + adapter->stats.tx_aborted_errors++; + pr_err("Transfer Abort Error\n"); + } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CRSER) + ) { + adapter->stats.tx_carrier_errors++; + pr_err("Transfer Carrier Sense Error\n"); + } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_EXCOL) + ) { + adapter->stats.tx_aborted_errors++; + pr_err("Transfer Collision Abort Error\n"); + } else if ((tx_desc->gbec_status & + (PCH_GBE_TXD_GMAC_STAT_SNGCOL | + PCH_GBE_TXD_GMAC_STAT_MLTCOL))) { + adapter->stats.collisions++; + adapter->stats.tx_packets++; + adapter->stats.tx_bytes += skb->len; + pr_debug("Transfer Collision\n"); + } else if ((tx_desc->gbec_status & PCH_GBE_TXD_GMAC_STAT_CMPLT) + ) { + adapter->stats.tx_packets++; + adapter->stats.tx_bytes += skb->len; + } + if (buffer_info->mapped) { + pr_debug("unmap buffer_info->dma : %d\n", i); + dma_unmap_single(&adapter->pdev->dev, buffer_info->dma, + buffer_info->length, DMA_TO_DEVICE); + buffer_info->mapped = false; + } + if (buffer_info->skb) { + pr_debug("trim buffer_info->skb : %d\n", i); + skb_trim(buffer_info->skb, 0); + } + tx_desc->gbec_status = DSC_INIT16; + if (unlikely(++i == tx_ring->count)) + i = 0; + tx_desc = PCH_GBE_TX_DESC(*tx_ring, i); + + /* weight of a sort for tx, to avoid endless transmit cleanup */ + if (cleaned_count++ == PCH_GBE_TX_WEIGHT) + break; + } + pr_debug("called pch_gbe_unmap_and_free_tx_resource() %d count\n", + cleaned_count); + /* Recover from running out of Tx resources in xmit_frame */ + if (unlikely(cleaned && (netif_queue_stopped(adapter->netdev)))) { + netif_wake_queue(adapter->netdev); + adapter->stats.tx_restart_count++; + pr_debug("Tx wake queue\n"); + } + spin_lock(&adapter->tx_queue_lock); + tx_ring->next_to_clean = i; + spin_unlock(&adapter->tx_queue_lock); + pr_debug("next_to_clean : %d\n", tx_ring->next_to_clean); + return cleaned; +} + +/** + * pch_gbe_clean_rx - Send received data up the network stack; legacy + * @adapter: Board private structure + * @rx_ring: Rx descriptor ring + * @work_done: Completed count + * @work_to_do: Request count + * Returns + * true: Cleaned the descriptor + * false: Not cleaned the descriptor + */ +static bool +pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring, + int *work_done, int work_to_do) +{ + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_buffer *buffer_info; + struct pch_gbe_rx_desc *rx_desc; + u32 length; + unsigned char tmp_packet[ETH_HLEN]; + unsigned int i; + unsigned int cleaned_count = 0; + bool cleaned = false; + struct sk_buff *skb; + u8 dma_status; + u16 gbec_status; + u32 tcp_ip_status; + u8 skb_copy_flag = 0; + u8 skb_padding_flag = 0; + + i = rx_ring->next_to_clean; + + while (*work_done < work_to_do) { + /* Check Rx descriptor status */ + rx_desc = PCH_GBE_RX_DESC(*rx_ring, i); + if (rx_desc->gbec_status == DSC_INIT16) + break; + cleaned = true; + cleaned_count++; + + dma_status = rx_desc->dma_status; + gbec_status = rx_desc->gbec_status; + tcp_ip_status = rx_desc->tcp_ip_status; + rx_desc->gbec_status = DSC_INIT16; + buffer_info = &rx_ring->buffer_info[i]; + skb = buffer_info->skb; + + /* unmap dma */ + dma_unmap_single(&pdev->dev, buffer_info->dma, + buffer_info->length, DMA_FROM_DEVICE); + buffer_info->mapped = false; + /* Prefetch the packet */ + prefetch(skb->data); + + pr_debug("RxDecNo = 0x%04x Status[DMA:0x%02x GBE:0x%04x " + "TCP:0x%08x] BufInf = 0x%p\n", + i, dma_status, gbec_status, tcp_ip_status, + buffer_info); + /* Error check */ + if (unlikely(gbec_status & PCH_GBE_RXD_GMAC_STAT_NOTOCTAL)) { + adapter->stats.rx_frame_errors++; + pr_err("Receive Not Octal Error\n"); + } else if (unlikely(gbec_status & + PCH_GBE_RXD_GMAC_STAT_NBLERR)) { + adapter->stats.rx_frame_errors++; + pr_err("Receive Nibble Error\n"); + } else if (unlikely(gbec_status & + PCH_GBE_RXD_GMAC_STAT_CRCERR)) { + adapter->stats.rx_crc_errors++; + pr_err("Receive CRC Error\n"); + } else { + /* get receive length */ + /* length convert[-3], padding[-2] */ + length = (rx_desc->rx_words_eob) - 3 - 2; + + /* Decide the data conversion method */ + if (!adapter->rx_csum) { + /* [Header:14][payload] */ + skb_padding_flag = 0; + skb_copy_flag = 1; + } else { + /* [Header:14][padding:2][payload] */ + skb_padding_flag = 1; + if (length < copybreak) + skb_copy_flag = 1; + else + skb_copy_flag = 0; + } + + /* Data conversion */ + if (skb_copy_flag) { /* recycle skb */ + struct sk_buff *new_skb; + new_skb = + netdev_alloc_skb(netdev, + length + NET_IP_ALIGN); + if (new_skb) { + if (!skb_padding_flag) { + skb_reserve(new_skb, + NET_IP_ALIGN); + } + memcpy(new_skb->data, skb->data, + length); + /* save the skb + * in buffer_info as good */ + skb = new_skb; + } else if (!skb_padding_flag) { + /* dorrop error */ + pr_err("New skb allocation Error\n"); + goto dorrop; + } + } else { + buffer_info->skb = NULL; + } + if (skb_padding_flag) { + memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN); + memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0], + ETH_HLEN); + skb_reserve(skb, NET_IP_ALIGN); + + } + + /* update status of driver */ + adapter->stats.rx_bytes += length; + adapter->stats.rx_packets++; + if ((gbec_status & PCH_GBE_RXD_GMAC_STAT_MARMLT)) + adapter->stats.multicast++; + /* Write meta date of skb */ + skb_put(skb, length); + skb->protocol = eth_type_trans(skb, netdev); + if ((tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) == + PCH_GBE_RXD_ACC_STAT_TCPIPOK) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { + skb->ip_summed = CHECKSUM_NONE; + } + napi_gro_receive(&adapter->napi, skb); + (*work_done)++; + pr_debug("Receive skb->ip_summed: %d length: %d\n", + skb->ip_summed, length); + } +dorrop: + /* return some buffers to hardware, one at a time is too slow */ + if (unlikely(cleaned_count >= PCH_GBE_RX_BUFFER_WRITE)) { + pch_gbe_alloc_rx_buffers(adapter, rx_ring, + cleaned_count); + cleaned_count = 0; + } + if (++i == rx_ring->count) + i = 0; + } + rx_ring->next_to_clean = i; + if (cleaned_count) + pch_gbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count); + return cleaned; +} + +/** + * pch_gbe_setup_tx_resources - Allocate Tx resources (Descriptors) + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring (for a specific queue) to setup + * Returns + * 0: Successfully + * Negative value: Failed + */ +int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_tx_desc *tx_desc; + int size; + int desNo; + + size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count; + tx_ring->buffer_info = vmalloc(size); + if (!tx_ring->buffer_info) { + pr_err("Unable to allocate memory for the buffer infomation\n"); + return -ENOMEM; + } + memset(tx_ring->buffer_info, 0, size); + + tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc); + + tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, + &tx_ring->dma, GFP_KERNEL); + if (!tx_ring->desc) { + vfree(tx_ring->buffer_info); + pr_err("Unable to allocate memory for the transmit descriptor ring\n"); + return -ENOMEM; + } + memset(tx_ring->desc, 0, tx_ring->size); + + tx_ring->next_to_use = 0; + tx_ring->next_to_clean = 0; + spin_lock_init(&tx_ring->tx_lock); + + for (desNo = 0; desNo < tx_ring->count; desNo++) { + tx_desc = PCH_GBE_TX_DESC(*tx_ring, desNo); + tx_desc->gbec_status = DSC_INIT16; + } + pr_debug("tx_ring->desc = 0x%p tx_ring->dma = 0x%08llx\n" + "next_to_clean = 0x%08x next_to_use = 0x%08x\n", + tx_ring->desc, (unsigned long long)tx_ring->dma, + tx_ring->next_to_clean, tx_ring->next_to_use); + return 0; +} + +/** + * pch_gbe_setup_rx_resources - Allocate Rx resources (Descriptors) + * @adapter: Board private structure + * @rx_ring: Rx descriptor ring (for a specific queue) to setup + * Returns + * 0: Successfully + * Negative value: Failed + */ +int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring) +{ + struct pci_dev *pdev = adapter->pdev; + struct pch_gbe_rx_desc *rx_desc; + int size; + int desNo; + + size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count; + rx_ring->buffer_info = vmalloc(size); + if (!rx_ring->buffer_info) { + pr_err("Unable to allocate memory for the receive descriptor ring\n"); + return -ENOMEM; + } + memset(rx_ring->buffer_info, 0, size); + rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc); + rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, + &rx_ring->dma, GFP_KERNEL); + + if (!rx_ring->desc) { + pr_err("Unable to allocate memory for the receive descriptor ring\n"); + vfree(rx_ring->buffer_info); + return -ENOMEM; + } + memset(rx_ring->desc, 0, rx_ring->size); + rx_ring->next_to_clean = 0; + rx_ring->next_to_use = 0; + for (desNo = 0; desNo < rx_ring->count; desNo++) { + rx_desc = PCH_GBE_RX_DESC(*rx_ring, desNo); + rx_desc->gbec_status = DSC_INIT16; + } + pr_debug("rx_ring->desc = 0x%p rx_ring->dma = 0x%08llx " + "next_to_clean = 0x%08x next_to_use = 0x%08x\n", + rx_ring->desc, (unsigned long long)rx_ring->dma, + rx_ring->next_to_clean, rx_ring->next_to_use); + return 0; +} + +/** + * pch_gbe_free_tx_resources - Free Tx Resources + * @adapter: Board private structure + * @tx_ring: Tx descriptor ring for a specific queue + */ +void pch_gbe_free_tx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_tx_ring *tx_ring) +{ + struct pci_dev *pdev = adapter->pdev; + + pch_gbe_clean_tx_ring(adapter, tx_ring); + vfree(tx_ring->buffer_info); + tx_ring->buffer_info = NULL; + pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma); + tx_ring->desc = NULL; +} + +/** + * pch_gbe_free_rx_resources - Free Rx Resources + * @adapter: Board private structure + * @rx_ring: Ring to clean the resources from + */ +void pch_gbe_free_rx_resources(struct pch_gbe_adapter *adapter, + struct pch_gbe_rx_ring *rx_ring) +{ + struct pci_dev *pdev = adapter->pdev; + + pch_gbe_clean_rx_ring(adapter, rx_ring); + vfree(rx_ring->buffer_info); + rx_ring->buffer_info = NULL; + pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma); + rx_ring->desc = NULL; +} + +/** + * pch_gbe_request_irq - Allocate an interrupt line + * @adapter: Board private structure + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_request_irq(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + int err; + int flags; + + flags = IRQF_SHARED; + adapter->have_msi = false; + err = pci_enable_msi(adapter->pdev); + pr_debug("call pci_enable_msi\n"); + if (err) { + pr_debug("call pci_enable_msi - Error: %d\n", err); + } else { + flags = 0; + adapter->have_msi = true; + } + err = request_irq(adapter->pdev->irq, &pch_gbe_intr, + flags, netdev->name, netdev); + if (err) + pr_err("Unable to allocate interrupt Error: %d\n", err); + pr_debug("adapter->have_msi : %d flags : 0x%04x return : 0x%04x\n", + adapter->have_msi, flags, err); + return err; +} + + +static void pch_gbe_set_multi(struct net_device *netdev); +/** + * pch_gbe_up - Up GbE network device + * @adapter: Board private structure + * Returns + * 0: Successfully + * Negative value: Failed + */ +int pch_gbe_up(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; + struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; + int err; + + /* hardware has been reset, we need to reload some things */ + pch_gbe_set_multi(netdev); + + pch_gbe_setup_tctl(adapter); + pch_gbe_configure_tx(adapter); + pch_gbe_setup_rctl(adapter); + pch_gbe_configure_rx(adapter); + + err = pch_gbe_request_irq(adapter); + if (err) { + pr_err("Error: can't bring device up\n"); + return err; + } + pch_gbe_alloc_tx_buffers(adapter, tx_ring); + pch_gbe_alloc_rx_buffers(adapter, rx_ring, rx_ring->count); + adapter->tx_queue_len = netdev->tx_queue_len; + + mod_timer(&adapter->watchdog_timer, jiffies); + + napi_enable(&adapter->napi); + pch_gbe_irq_enable(adapter); + netif_start_queue(adapter->netdev); + + return 0; +} + +/** + * pch_gbe_down - Down GbE network device + * @adapter: Board private structure + */ +void pch_gbe_down(struct pch_gbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + /* signal that we're down so the interrupt handler does not + * reschedule our watchdog timer */ + napi_disable(&adapter->napi); + atomic_set(&adapter->irq_sem, 0); + + pch_gbe_irq_disable(adapter); + pch_gbe_free_irq(adapter); + + del_timer_sync(&adapter->watchdog_timer); + + netdev->tx_queue_len = adapter->tx_queue_len; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + + pch_gbe_reset(adapter); + pch_gbe_clean_tx_ring(adapter, adapter->tx_ring); + pch_gbe_clean_rx_ring(adapter, adapter->rx_ring); +} + +/** + * pch_gbe_sw_init - Initialize general software structures (struct pch_gbe_adapter) + * @adapter: Board private structure to initialize + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_sw_init(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; + + adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_2048; + hw->mac.max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; + hw->mac.min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + + /* Initialize the hardware-specific values */ + if (pch_gbe_hal_setup_init_funcs(hw)) { + pr_err("Hardware Initialization Failure\n"); + return -EIO; + } + if (pch_gbe_alloc_queues(adapter)) { + pr_err("Unable to allocate memory for queues\n"); + return -ENOMEM; + } + spin_lock_init(&adapter->hw.miim_lock); + spin_lock_init(&adapter->tx_queue_lock); + spin_lock_init(&adapter->stats_lock); + spin_lock_init(&adapter->ethtool_lock); + atomic_set(&adapter->irq_sem, 0); + pch_gbe_irq_disable(adapter); + + pch_gbe_init_stats(adapter); + + pr_debug("rx_buffer_len : %d mac.min_frame_size : %d mac.max_frame_size : %d\n", + (u32) adapter->rx_buffer_len, + hw->mac.min_frame_size, hw->mac.max_frame_size); + return 0; +} + +/** + * pch_gbe_open - Called when a network interface is made active + * @netdev: Network interface device structure + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_open(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + int err; + + /* allocate transmit descriptors */ + err = pch_gbe_setup_tx_resources(adapter, adapter->tx_ring); + if (err) + goto err_setup_tx; + /* allocate receive descriptors */ + err = pch_gbe_setup_rx_resources(adapter, adapter->rx_ring); + if (err) + goto err_setup_rx; + pch_gbe_hal_power_up_phy(hw); + err = pch_gbe_up(adapter); + if (err) + goto err_up; + pr_debug("Success End\n"); + return 0; + +err_up: + if (!adapter->wake_up_evt) + pch_gbe_hal_power_down_phy(hw); + pch_gbe_free_rx_resources(adapter, adapter->rx_ring); +err_setup_rx: + pch_gbe_free_tx_resources(adapter, adapter->tx_ring); +err_setup_tx: + pch_gbe_reset(adapter); + pr_err("Error End\n"); + return err; +} + +/** + * pch_gbe_stop - Disables a network interface + * @netdev: Network interface device structure + * Returns + * 0: Successfully + */ +static int pch_gbe_stop(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + pch_gbe_down(adapter); + if (!adapter->wake_up_evt) + pch_gbe_hal_power_down_phy(hw); + pch_gbe_free_tx_resources(adapter, adapter->tx_ring); + pch_gbe_free_rx_resources(adapter, adapter->rx_ring); + return 0; +} + +/** + * pch_gbe_xmit_frame - Packet transmitting start + * @skb: Socket buffer structure + * @netdev: Network interface device structure + * Returns + * - NETDEV_TX_OK: Normal end + * - NETDEV_TX_BUSY: Error end + */ +static int pch_gbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; + unsigned long flags; + + if (unlikely(skb->len > (adapter->hw.mac.max_frame_size - 4))) { + pr_err("Transfer length Error: skb len: %d > max: %d\n", + skb->len, adapter->hw.mac.max_frame_size); + dev_kfree_skb_any(skb); + adapter->stats.tx_length_errors++; + return NETDEV_TX_OK; + } + if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) { + /* Collision - tell upper layer to requeue */ + return NETDEV_TX_LOCKED; + } + if (unlikely(!PCH_GBE_DESC_UNUSED(tx_ring))) { + netif_stop_queue(netdev); + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); + pr_debug("Return : BUSY next_to use : 0x%08x next_to clean : 0x%08x\n", + tx_ring->next_to_use, tx_ring->next_to_clean); + return NETDEV_TX_BUSY; + } + spin_unlock_irqrestore(&tx_ring->tx_lock, flags); + + /* CRC,ITAG no support */ + pch_gbe_tx_queue(adapter, tx_ring, skb); + return NETDEV_TX_OK; +} + +/** + * pch_gbe_get_stats - Get System Network Statistics + * @netdev: Network interface device structure + * Returns: The current stats + */ +static struct net_device_stats *pch_gbe_get_stats(struct net_device *netdev) +{ + /* only return the current stats */ + return &netdev->stats; +} + +/** + * pch_gbe_set_multi - Multicast and Promiscuous mode set + * @netdev: Network interface device structure + */ +static void pch_gbe_set_multi(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + struct netdev_hw_addr *ha; + u8 *mta_list; + u32 rctl; + int i; + int mc_count; + + pr_debug("netdev->flags : 0x%08x\n", netdev->flags); + + /* Check for Promiscuous and All Multicast modes */ + rctl = ioread32(&hw->reg->RX_MODE); + mc_count = netdev_mc_count(netdev); + if ((netdev->flags & IFF_PROMISC)) { + rctl &= ~PCH_GBE_ADD_FIL_EN; + rctl &= ~PCH_GBE_MLT_FIL_EN; + } else if ((netdev->flags & IFF_ALLMULTI)) { + /* all the multicasting receive permissions */ + rctl |= PCH_GBE_ADD_FIL_EN; + rctl &= ~PCH_GBE_MLT_FIL_EN; + } else { + if (mc_count >= PCH_GBE_MAR_ENTRIES) { + /* all the multicasting receive permissions */ + rctl |= PCH_GBE_ADD_FIL_EN; + rctl &= ~PCH_GBE_MLT_FIL_EN; + } else { + rctl |= (PCH_GBE_ADD_FIL_EN | PCH_GBE_MLT_FIL_EN); + } + } + iowrite32(rctl, &hw->reg->RX_MODE); + + if (mc_count >= PCH_GBE_MAR_ENTRIES) + return; + mta_list = kmalloc(mc_count * ETH_ALEN, GFP_ATOMIC); + if (!mta_list) + return; + + /* The shared function expects a packed array of only addresses. */ + i = 0; + netdev_for_each_mc_addr(ha, netdev) { + if (i == mc_count) + break; + memcpy(mta_list + (i++ * ETH_ALEN), &ha->addr, ETH_ALEN); + } + pch_gbe_mac_mc_addr_list_update(hw, mta_list, i, 1, + PCH_GBE_MAR_ENTRIES); + kfree(mta_list); + + pr_debug("RX_MODE reg(check bit31,30 ADD,MLT) : 0x%08x netdev->mc_count : 0x%08x\n", + ioread32(&hw->reg->RX_MODE), mc_count); +} + +/** + * pch_gbe_set_mac - Change the Ethernet Address of the NIC + * @netdev: Network interface device structure + * @addr: Pointer to an address structure + * Returns + * 0: Successfully + * -EADDRNOTAVAIL: Failed + */ +static int pch_gbe_set_mac(struct net_device *netdev, void *addr) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct sockaddr *skaddr = addr; + int ret_val; + + if (!is_valid_ether_addr(skaddr->sa_data)) { + ret_val = -EADDRNOTAVAIL; + } else { + memcpy(netdev->dev_addr, skaddr->sa_data, netdev->addr_len); + memcpy(adapter->hw.mac.addr, skaddr->sa_data, netdev->addr_len); + pch_gbe_mac_mar_set(&adapter->hw, adapter->hw.mac.addr, 0); + ret_val = 0; + } + pr_debug("ret_val : 0x%08x\n", ret_val); + pr_debug("dev_addr : %pM\n", netdev->dev_addr); + pr_debug("mac_addr : %pM\n", adapter->hw.mac.addr); + pr_debug("MAC_ADR1AB reg : 0x%08x 0x%08x\n", + ioread32(&adapter->hw.reg->mac_adr[0].high), + ioread32(&adapter->hw.reg->mac_adr[0].low)); + return ret_val; +} + +/** + * pch_gbe_change_mtu - Change the Maximum Transfer Unit + * @netdev: Network interface device structure + * @new_mtu: New value for maximum frame size + * Returns + * 0: Successfully + * -EINVAL: Failed + */ +static int pch_gbe_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + int max_frame; + + max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; + if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || + (max_frame > PCH_GBE_MAX_JUMBO_FRAME_SIZE)) { + pr_err("Invalid MTU setting\n"); + return -EINVAL; + } + if (max_frame <= PCH_GBE_FRAME_SIZE_2048) + adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_2048; + else if (max_frame <= PCH_GBE_FRAME_SIZE_4096) + adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_4096; + else if (max_frame <= PCH_GBE_FRAME_SIZE_8192) + adapter->rx_buffer_len = PCH_GBE_FRAME_SIZE_8192; + else + adapter->rx_buffer_len = PCH_GBE_MAX_JUMBO_FRAME_SIZE; + netdev->mtu = new_mtu; + adapter->hw.mac.max_frame_size = max_frame; + + if (netif_running(netdev)) + pch_gbe_reinit_locked(adapter); + else + pch_gbe_reset(adapter); + + pr_debug("max_frame : %d rx_buffer_len : %d mtu : %d max_frame_size : %d\n", + max_frame, (u32) adapter->rx_buffer_len, netdev->mtu, + adapter->hw.mac.max_frame_size); + return 0; +} + +/** + * pch_gbe_ioctl - Controls register through a MII interface + * @netdev: Network interface device structure + * @ifr: Pointer to ifr structure + * @cmd: Control command + * Returns + * 0: Successfully + * Negative value: Failed + */ +static int pch_gbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + pr_debug("cmd : 0x%04x\n", cmd); + + return generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL); +} + +/** + * pch_gbe_tx_timeout - Respond to a Tx Hang + * @netdev: Network interface device structure + */ +static void pch_gbe_tx_timeout(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + /* Do the reset outside of interrupt context */ + adapter->stats.tx_timeout_count++; + schedule_work(&adapter->reset_task); +} + +/** + * pch_gbe_napi_poll - NAPI receive and transfer polling callback + * @napi: Pointer of polling device struct + * @budget: The maximum number of a packet + * Returns + * false: Exit the polling mode + * true: Continue the polling mode + */ +static int pch_gbe_napi_poll(struct napi_struct *napi, int budget) +{ + struct pch_gbe_adapter *adapter = + container_of(napi, struct pch_gbe_adapter, napi); + struct net_device *netdev = adapter->netdev; + int work_done = 0; + bool poll_end_flag = false; + bool cleaned = false; + + pr_debug("budget : %d\n", budget); + + /* Keep link state information with original netdev */ + if (!netif_carrier_ok(netdev)) { + poll_end_flag = true; + } else { + cleaned = pch_gbe_clean_tx(adapter, adapter->tx_ring); + pch_gbe_clean_rx(adapter, adapter->rx_ring, &work_done, budget); + + if (cleaned) + work_done = budget; + /* If no Tx and not enough Rx work done, + * exit the polling mode + */ + if ((work_done < budget) || !netif_running(netdev)) + poll_end_flag = true; + } + + if (poll_end_flag) { + napi_complete(napi); + pch_gbe_irq_enable(adapter); + } + + pr_debug("poll_end_flag : %d work_done : %d budget : %d\n", + poll_end_flag, work_done, budget); + + return work_done; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/** + * pch_gbe_netpoll - Used by things like netconsole to send skbs + * @netdev: Network interface device structure + */ +static void pch_gbe_netpoll(struct net_device *netdev) +{ + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + disable_irq(adapter->pdev->irq); + pch_gbe_intr(adapter->pdev->irq, netdev); + enable_irq(adapter->pdev->irq); +} +#endif + +static const struct net_device_ops pch_gbe_netdev_ops = { + .ndo_open = pch_gbe_open, + .ndo_stop = pch_gbe_stop, + .ndo_start_xmit = pch_gbe_xmit_frame, + .ndo_get_stats = pch_gbe_get_stats, + .ndo_set_mac_address = pch_gbe_set_mac, + .ndo_tx_timeout = pch_gbe_tx_timeout, + .ndo_change_mtu = pch_gbe_change_mtu, + .ndo_do_ioctl = pch_gbe_ioctl, + .ndo_set_multicast_list = &pch_gbe_set_multi, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = pch_gbe_netpoll, +#endif +}; + +static pci_ers_result_t pch_gbe_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + netif_device_detach(netdev); + if (netif_running(netdev)) + pch_gbe_down(adapter); + pci_disable_device(pdev); + /* Request a slot slot reset. */ + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t pch_gbe_io_slot_reset(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + + if (pci_enable_device(pdev)) { + pr_err("Cannot re-enable PCI device after reset\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + pci_set_master(pdev); + pci_enable_wake(pdev, PCI_D0, 0); + pch_gbe_hal_power_up_phy(hw); + pch_gbe_reset(adapter); + /* Clear wake up status */ + pch_gbe_mac_set_wol_event(hw, 0); + + return PCI_ERS_RESULT_RECOVERED; +} + +static void pch_gbe_io_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) { + if (pch_gbe_up(adapter)) { + pr_debug("can't bring device back up after reset\n"); + return; + } + } + netif_device_attach(netdev); +} + +static int __pch_gbe_suspend(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + u32 wufc = adapter->wake_up_evt; + int retval = 0; + + netif_device_detach(netdev); + if (netif_running(netdev)) + pch_gbe_down(adapter); + if (wufc) { + pch_gbe_set_multi(netdev); + pch_gbe_setup_rctl(adapter); + pch_gbe_configure_rx(adapter); + pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed, + hw->mac.link_duplex); + pch_gbe_set_mode(adapter, hw->mac.link_speed, + hw->mac.link_duplex); + pch_gbe_mac_set_wol_event(hw, wufc); + pci_disable_device(pdev); + } else { + pch_gbe_hal_power_down_phy(hw); + pch_gbe_mac_set_wol_event(hw, wufc); + pci_disable_device(pdev); + } + return retval; +} + +#ifdef CONFIG_PM +static int pch_gbe_suspend(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + + return __pch_gbe_suspend(pdev); +} + +static int pch_gbe_resume(struct device *device) +{ + struct pci_dev *pdev = to_pci_dev(device); + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + struct pch_gbe_hw *hw = &adapter->hw; + u32 err; + + err = pci_enable_device(pdev); + if (err) { + pr_err("Cannot enable PCI device from suspend\n"); + return err; + } + pci_set_master(pdev); + pch_gbe_hal_power_up_phy(hw); + pch_gbe_reset(adapter); + /* Clear wake on lan control and status */ + pch_gbe_mac_set_wol_event(hw, 0); + + if (netif_running(netdev)) + pch_gbe_up(adapter); + netif_device_attach(netdev); + + return 0; +} +#endif /* CONFIG_PM */ + +static void pch_gbe_shutdown(struct pci_dev *pdev) +{ + __pch_gbe_suspend(pdev); + if (system_state == SYSTEM_POWER_OFF) { + pci_wake_from_d3(pdev, true); + pci_set_power_state(pdev, PCI_D3hot); + } +} + +static void pch_gbe_remove(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct pch_gbe_adapter *adapter = netdev_priv(netdev); + + flush_scheduled_work(); + unregister_netdev(netdev); + + pch_gbe_hal_phy_hw_reset(&adapter->hw); + + kfree(adapter->tx_ring); + kfree(adapter->rx_ring); + + iounmap(adapter->hw.reg); + pci_release_regions(pdev); + free_netdev(netdev); + pci_disable_device(pdev); +} + +static int pch_gbe_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_id) +{ + struct net_device *netdev; + struct pch_gbe_adapter *adapter; + int ret; + + ret = pci_enable_device(pdev); + if (ret) + return ret; + + if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) + || pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + ret = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "ERR: No usable DMA " + "configuration, aborting\n"); + goto err_disable_device; + } + } + } + + ret = pci_request_regions(pdev, KBUILD_MODNAME); + if (ret) { + dev_err(&pdev->dev, + "ERR: Can't reserve PCI I/O and memory resources\n"); + goto err_disable_device; + } + pci_set_master(pdev); + + netdev = alloc_etherdev((int)sizeof(struct pch_gbe_adapter)); + if (!netdev) { + ret = -ENOMEM; + dev_err(&pdev->dev, + "ERR: Can't allocate and set up an Ethernet device\n"); + goto err_release_pci; + } + SET_NETDEV_DEV(netdev, &pdev->dev); + + pci_set_drvdata(pdev, netdev); + adapter = netdev_priv(netdev); + adapter->netdev = netdev; + adapter->pdev = pdev; + adapter->hw.back = adapter; + adapter->hw.reg = pci_iomap(pdev, PCH_GBE_PCI_BAR, 0); + if (!adapter->hw.reg) { + ret = -EIO; + dev_err(&pdev->dev, "Can't ioremap\n"); + goto err_free_netdev; + } + + netdev->netdev_ops = &pch_gbe_netdev_ops; + netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD; + netif_napi_add(netdev, &adapter->napi, + pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT); + netdev->features = NETIF_F_HW_CSUM | NETIF_F_GRO; + pch_gbe_set_ethtool_ops(netdev); + + pch_gbe_mac_reset_hw(&adapter->hw); + + /* setup the private structure */ + ret = pch_gbe_sw_init(adapter); + if (ret) + goto err_iounmap; + + /* Initialize PHY */ + ret = pch_gbe_init_phy(adapter); + if (ret) { + dev_err(&pdev->dev, "PHY initialize error\n"); + goto err_free_adapter; + } + pch_gbe_hal_get_bus_info(&adapter->hw); + + /* Read the MAC address. and store to the private data */ + ret = pch_gbe_hal_read_mac_addr(&adapter->hw); + if (ret) { + dev_err(&pdev->dev, "MAC address Read Error\n"); + goto err_free_adapter; + } + + memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); + if (!is_valid_ether_addr(netdev->dev_addr)) { + dev_err(&pdev->dev, "Invalid MAC Address\n"); + ret = -EIO; + goto err_free_adapter; + } + setup_timer(&adapter->watchdog_timer, pch_gbe_watchdog, + (unsigned long)adapter); + + INIT_WORK(&adapter->reset_task, pch_gbe_reset_task); + + pch_gbe_check_options(adapter); + + if (adapter->tx_csum) + netdev->features |= NETIF_F_HW_CSUM; + else + netdev->features &= ~NETIF_F_HW_CSUM; + + /* initialize the wol settings based on the eeprom settings */ + adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING; + dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr); + + /* reset the hardware with the new settings */ + pch_gbe_reset(adapter); + + ret = register_netdev(netdev); + if (ret) + goto err_free_adapter; + /* tell the stack to leave us alone until pch_gbe_open() is called */ + netif_carrier_off(netdev); + netif_stop_queue(netdev); + + dev_dbg(&pdev->dev, "OKIsemi(R) PCH Network Connection\n"); + + device_set_wakeup_enable(&pdev->dev, 1); + return 0; + +err_free_adapter: + pch_gbe_hal_phy_hw_reset(&adapter->hw); + kfree(adapter->tx_ring); + kfree(adapter->rx_ring); +err_iounmap: + iounmap(adapter->hw.reg); +err_free_netdev: + free_netdev(netdev); +err_release_pci: + pci_release_regions(pdev); +err_disable_device: + pci_disable_device(pdev); + return ret; +} + +static DEFINE_PCI_DEVICE_TABLE(pch_gbe_pcidev_id) = { + {.vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_IOH1_GBE, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .class = (PCI_CLASS_NETWORK_ETHERNET << 8), + .class_mask = (0xFFFF00) + }, + /* required last entry */ + {0} +}; + +#ifdef CONFIG_PM +static const struct dev_pm_ops pch_gbe_pm_ops = { + .suspend = pch_gbe_suspend, + .resume = pch_gbe_resume, + .freeze = pch_gbe_suspend, + .thaw = pch_gbe_resume, + .poweroff = pch_gbe_suspend, + .restore = pch_gbe_resume, +}; +#endif + +static struct pci_error_handlers pch_gbe_err_handler = { + .error_detected = pch_gbe_io_error_detected, + .slot_reset = pch_gbe_io_slot_reset, + .resume = pch_gbe_io_resume +}; + +static struct pci_driver pch_gbe_pcidev = { + .name = KBUILD_MODNAME, + .id_table = pch_gbe_pcidev_id, + .probe = pch_gbe_probe, + .remove = pch_gbe_remove, +#ifdef CONFIG_PM_OPS + .driver.pm = &pch_gbe_pm_ops, +#endif + .shutdown = pch_gbe_shutdown, + .err_handler = &pch_gbe_err_handler +}; + + +static int __init pch_gbe_init_module(void) +{ + int ret; + + ret = pci_register_driver(&pch_gbe_pcidev); + if (copybreak != PCH_GBE_COPYBREAK_DEFAULT) { + if (copybreak == 0) { + pr_info("copybreak disabled\n"); + } else { + pr_info("copybreak enabled for packets <= %u bytes\n", + copybreak); + } + } + return ret; +} + +static void __exit pch_gbe_exit_module(void) +{ + pci_unregister_driver(&pch_gbe_pcidev); +} + +module_init(pch_gbe_init_module); +module_exit(pch_gbe_exit_module); + +MODULE_DESCRIPTION("OKI semiconductor PCH Gigabit ethernet Driver"); +MODULE_AUTHOR("OKI semiconductor, "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); +MODULE_DEVICE_TABLE(pci, pch_gbe_pcidev_id); + +module_param(copybreak, uint, 0644); +MODULE_PARM_DESC(copybreak, + "Maximum size of packet that is copied to a new buffer on receive"); + +/* pch_gbe_main.c */ diff --git a/drivers/net/pch_gbe/pch_gbe_param.c b/drivers/net/pch_gbe/pch_gbe_param.c new file mode 100644 index 0000000000000000000000000000000000000000..2510146fc5607db7a26d9b54ad634f8941d65ae2 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_param.c @@ -0,0 +1,499 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "pch_gbe.h" + +#define OPTION_UNSET -1 +#define OPTION_DISABLED 0 +#define OPTION_ENABLED 1 + +/** + * TxDescriptors - Transmit Descriptor Count + * @Valid Range: PCH_GBE_MIN_TXD - PCH_GBE_MAX_TXD + * @Default Value: PCH_GBE_DEFAULT_TXD + */ +static int TxDescriptors = OPTION_UNSET; +module_param(TxDescriptors, int, 0); +MODULE_PARM_DESC(TxDescriptors, "Number of transmit descriptors"); + +/** + * RxDescriptors -Receive Descriptor Count + * @Valid Range: PCH_GBE_MIN_RXD - PCH_GBE_MAX_RXD + * @Default Value: PCH_GBE_DEFAULT_RXD + */ +static int RxDescriptors = OPTION_UNSET; +module_param(RxDescriptors, int, 0); +MODULE_PARM_DESC(RxDescriptors, "Number of receive descriptors"); + +/** + * Speed - User Specified Speed Override + * @Valid Range: 0, 10, 100, 1000 + * - 0: auto-negotiate at all supported speeds + * - 10: only link at 10 Mbps + * - 100: only link at 100 Mbps + * - 1000: only link at 1000 Mbps + * @Default Value: 0 + */ +static int Speed = OPTION_UNSET; +module_param(Speed, int, 0); +MODULE_PARM_DESC(Speed, "Speed setting"); + +/** + * Duplex - User Specified Duplex Override + * @Valid Range: 0-2 + * - 0: auto-negotiate for duplex + * - 1: only link at half duplex + * - 2: only link at full duplex + * @Default Value: 0 + */ +static int Duplex = OPTION_UNSET; +module_param(Duplex, int, 0); +MODULE_PARM_DESC(Duplex, "Duplex setting"); + +#define HALF_DUPLEX 1 +#define FULL_DUPLEX 2 + +/** + * AutoNeg - Auto-negotiation Advertisement Override + * @Valid Range: 0x01-0x0F, 0x20-0x2F + * + * The AutoNeg value is a bit mask describing which speed and duplex + * combinations should be advertised during auto-negotiation. + * The supported speed and duplex modes are listed below + * + * Bit 7 6 5 4 3 2 1 0 + * Speed (Mbps) N/A N/A 1000 N/A 100 100 10 10 + * Duplex Full Full Half Full Half + * + * @Default Value: 0x2F (copper) + */ +static int AutoNeg = OPTION_UNSET; +module_param(AutoNeg, int, 0); +MODULE_PARM_DESC(AutoNeg, "Advertised auto-negotiation setting"); + +#define PHY_ADVERTISE_10_HALF 0x0001 +#define PHY_ADVERTISE_10_FULL 0x0002 +#define PHY_ADVERTISE_100_HALF 0x0004 +#define PHY_ADVERTISE_100_FULL 0x0008 +#define PHY_ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ +#define PHY_ADVERTISE_1000_FULL 0x0020 +#define PCH_AUTONEG_ADVERTISE_DEFAULT 0x2F + +/** + * FlowControl - User Specified Flow Control Override + * @Valid Range: 0-3 + * - 0: No Flow Control + * - 1: Rx only, respond to PAUSE frames but do not generate them + * - 2: Tx only, generate PAUSE frames but ignore them on receive + * - 3: Full Flow Control Support + * @Default Value: Read flow control settings from the EEPROM + */ +static int FlowControl = OPTION_UNSET; +module_param(FlowControl, int, 0); +MODULE_PARM_DESC(FlowControl, "Flow Control setting"); + +/* + * XsumRX - Receive Checksum Offload Enable/Disable + * @Valid Range: 0, 1 + * - 0: disables all checksum offload + * - 1: enables receive IP/TCP/UDP checksum offload + * @Default Value: PCH_GBE_DEFAULT_RX_CSUM + */ +static int XsumRX = OPTION_UNSET; +module_param(XsumRX, int, 0); +MODULE_PARM_DESC(XsumRX, "Disable or enable Receive Checksum offload"); + +#define PCH_GBE_DEFAULT_RX_CSUM true /* trueorfalse */ + +/* + * XsumTX - Transmit Checksum Offload Enable/Disable + * @Valid Range: 0, 1 + * - 0: disables all checksum offload + * - 1: enables transmit IP/TCP/UDP checksum offload + * @Default Value: PCH_GBE_DEFAULT_TX_CSUM + */ +static int XsumTX = OPTION_UNSET; +module_param(XsumTX, int, 0); +MODULE_PARM_DESC(XsumTX, "Disable or enable Transmit Checksum offload"); + +#define PCH_GBE_DEFAULT_TX_CSUM true /* trueorfalse */ + +/** + * pch_gbe_option - Force the MAC's flow control settings + * @hw: Pointer to the HW structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +struct pch_gbe_option { + enum { enable_option, range_option, list_option } type; + char *name; + char *err; + int def; + union { + struct { /* range_option info */ + int min; + int max; + } r; + struct { /* list_option info */ + int nr; + const struct pch_gbe_opt_list { int i; char *str; } *p; + } l; + } arg; +}; + +static const struct pch_gbe_opt_list speed_list[] = { + { 0, "" }, + { SPEED_10, "" }, + { SPEED_100, "" }, + { SPEED_1000, "" } +}; + +static const struct pch_gbe_opt_list dplx_list[] = { + { 0, "" }, + { HALF_DUPLEX, "" }, + { FULL_DUPLEX, "" } +}; + +static const struct pch_gbe_opt_list an_list[] = + #define AA "AutoNeg advertising " + {{ 0x01, AA "10/HD" }, + { 0x02, AA "10/FD" }, + { 0x03, AA "10/FD, 10/HD" }, + { 0x04, AA "100/HD" }, + { 0x05, AA "100/HD, 10/HD" }, + { 0x06, AA "100/HD, 10/FD" }, + { 0x07, AA "100/HD, 10/FD, 10/HD" }, + { 0x08, AA "100/FD" }, + { 0x09, AA "100/FD, 10/HD" }, + { 0x0a, AA "100/FD, 10/FD" }, + { 0x0b, AA "100/FD, 10/FD, 10/HD" }, + { 0x0c, AA "100/FD, 100/HD" }, + { 0x0d, AA "100/FD, 100/HD, 10/HD" }, + { 0x0e, AA "100/FD, 100/HD, 10/FD" }, + { 0x0f, AA "100/FD, 100/HD, 10/FD, 10/HD" }, + { 0x20, AA "1000/FD" }, + { 0x21, AA "1000/FD, 10/HD" }, + { 0x22, AA "1000/FD, 10/FD" }, + { 0x23, AA "1000/FD, 10/FD, 10/HD" }, + { 0x24, AA "1000/FD, 100/HD" }, + { 0x25, AA "1000/FD, 100/HD, 10/HD" }, + { 0x26, AA "1000/FD, 100/HD, 10/FD" }, + { 0x27, AA "1000/FD, 100/HD, 10/FD, 10/HD" }, + { 0x28, AA "1000/FD, 100/FD" }, + { 0x29, AA "1000/FD, 100/FD, 10/HD" }, + { 0x2a, AA "1000/FD, 100/FD, 10/FD" }, + { 0x2b, AA "1000/FD, 100/FD, 10/FD, 10/HD" }, + { 0x2c, AA "1000/FD, 100/FD, 100/HD" }, + { 0x2d, AA "1000/FD, 100/FD, 100/HD, 10/HD" }, + { 0x2e, AA "1000/FD, 100/FD, 100/HD, 10/FD" }, + { 0x2f, AA "1000/FD, 100/FD, 100/HD, 10/FD, 10/HD" } +}; + +static const struct pch_gbe_opt_list fc_list[] = { + { PCH_GBE_FC_NONE, "Flow Control Disabled" }, + { PCH_GBE_FC_RX_PAUSE, "Flow Control Receive Only" }, + { PCH_GBE_FC_TX_PAUSE, "Flow Control Transmit Only" }, + { PCH_GBE_FC_FULL, "Flow Control Enabled" } +}; + +/** + * pch_gbe_validate_option - Validate option + * @value: value + * @opt: option + * @adapter: Board private structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +static int pch_gbe_validate_option(int *value, + const struct pch_gbe_option *opt, + struct pch_gbe_adapter *adapter) +{ + if (*value == OPTION_UNSET) { + *value = opt->def; + return 0; + } + + switch (opt->type) { + case enable_option: + switch (*value) { + case OPTION_ENABLED: + pr_debug("%s Enabled\n", opt->name); + return 0; + case OPTION_DISABLED: + pr_debug("%s Disabled\n", opt->name); + return 0; + } + break; + case range_option: + if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { + pr_debug("%s set to %i\n", opt->name, *value); + return 0; + } + break; + case list_option: { + int i; + const struct pch_gbe_opt_list *ent; + + for (i = 0; i < opt->arg.l.nr; i++) { + ent = &opt->arg.l.p[i]; + if (*value == ent->i) { + if (ent->str[0] != '\0') + pr_debug("%s\n", ent->str); + return 0; + } + } + } + break; + default: + BUG(); + } + + pr_debug("Invalid %s value specified (%i) %s\n", + opt->name, *value, opt->err); + *value = opt->def; + return -1; +} + +/** + * pch_gbe_check_copper_options - Range Checking for Link Options, Copper Version + * @adapter: Board private structure + */ +static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + int speed, dplx; + + { /* Speed */ + static const struct pch_gbe_option opt = { + .type = list_option, + .name = "Speed", + .err = "parameter ignored", + .def = 0, + .arg = { .l = { .nr = (int)ARRAY_SIZE(speed_list), + .p = speed_list } } + }; + speed = Speed; + pch_gbe_validate_option(&speed, &opt, adapter); + } + { /* Duplex */ + static const struct pch_gbe_option opt = { + .type = list_option, + .name = "Duplex", + .err = "parameter ignored", + .def = 0, + .arg = { .l = { .nr = (int)ARRAY_SIZE(dplx_list), + .p = dplx_list } } + }; + dplx = Duplex; + pch_gbe_validate_option(&dplx, &opt, adapter); + } + + { /* Autoneg */ + static const struct pch_gbe_option opt = { + .type = list_option, + .name = "AutoNeg", + .err = "parameter ignored", + .def = PCH_AUTONEG_ADVERTISE_DEFAULT, + .arg = { .l = { .nr = (int)ARRAY_SIZE(an_list), + .p = an_list} } + }; + if (speed || dplx) { + pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n"); + hw->phy.autoneg_advertised = opt.def; + } else { + hw->phy.autoneg_advertised = AutoNeg; + pch_gbe_validate_option( + (int *)(&hw->phy.autoneg_advertised), + &opt, adapter); + } + } + + switch (speed + dplx) { + case 0: + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + if ((speed || dplx)) + pr_debug("Speed and duplex autonegotiation enabled\n"); + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case HALF_DUPLEX: + pr_debug("Half Duplex specified without Speed\n"); + pr_debug("Using Autonegotiation at Half Duplex only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF | + PHY_ADVERTISE_100_HALF; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case FULL_DUPLEX: + pr_debug("Full Duplex specified without Speed\n"); + pr_debug("Using Autonegotiation at Full Duplex only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_FULL | + PHY_ADVERTISE_100_FULL | + PHY_ADVERTISE_1000_FULL; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_FULL; + break; + case SPEED_10: + pr_debug("10 Mbps Speed specified without Duplex\n"); + pr_debug("Using Autonegotiation at 10 Mbps only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_10_HALF | + PHY_ADVERTISE_10_FULL; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case SPEED_10 + HALF_DUPLEX: + pr_debug("Forcing to 10 Mbps Half Duplex\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 0; + hw->phy.autoneg_advertised = 0; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case SPEED_10 + FULL_DUPLEX: + pr_debug("Forcing to 10 Mbps Full Duplex\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 0; + hw->phy.autoneg_advertised = 0; + hw->mac.link_speed = SPEED_10; + hw->mac.link_duplex = DUPLEX_FULL; + break; + case SPEED_100: + pr_debug("100 Mbps Speed specified without Duplex\n"); + pr_debug("Using Autonegotiation at 100 Mbps only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_100_HALF | + PHY_ADVERTISE_100_FULL; + hw->mac.link_speed = SPEED_100; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case SPEED_100 + HALF_DUPLEX: + pr_debug("Forcing to 100 Mbps Half Duplex\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 0; + hw->phy.autoneg_advertised = 0; + hw->mac.link_speed = SPEED_100; + hw->mac.link_duplex = DUPLEX_HALF; + break; + case SPEED_100 + FULL_DUPLEX: + pr_debug("Forcing to 100 Mbps Full Duplex\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 0; + hw->phy.autoneg_advertised = 0; + hw->mac.link_speed = SPEED_100; + hw->mac.link_duplex = DUPLEX_FULL; + break; + case SPEED_1000: + pr_debug("1000 Mbps Speed specified without Duplex\n"); + goto full_duplex_only; + case SPEED_1000 + HALF_DUPLEX: + pr_debug("Half Duplex is not supported at 1000 Mbps\n"); + /* fall through */ + case SPEED_1000 + FULL_DUPLEX: +full_duplex_only: + pr_debug("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); + hw->mac.autoneg = hw->mac.fc_autoneg = 1; + hw->phy.autoneg_advertised = PHY_ADVERTISE_1000_FULL; + hw->mac.link_speed = SPEED_1000; + hw->mac.link_duplex = DUPLEX_FULL; + break; + default: + BUG(); + } +} + +/** + * pch_gbe_check_options - Range Checking for Command Line Parameters + * @adapter: Board private structure + */ +void pch_gbe_check_options(struct pch_gbe_adapter *adapter) +{ + struct pch_gbe_hw *hw = &adapter->hw; + + { /* Transmit Descriptor Count */ + static const struct pch_gbe_option opt = { + .type = range_option, + .name = "Transmit Descriptors", + .err = "using default of " + __MODULE_STRING(PCH_GBE_DEFAULT_TXD), + .def = PCH_GBE_DEFAULT_TXD, + .arg = { .r = { .min = PCH_GBE_MIN_TXD } }, + .arg = { .r = { .max = PCH_GBE_MAX_TXD } } + }; + struct pch_gbe_tx_ring *tx_ring = adapter->tx_ring; + tx_ring->count = TxDescriptors; + pch_gbe_validate_option(&tx_ring->count, &opt, adapter); + tx_ring->count = roundup(tx_ring->count, + PCH_GBE_TX_DESC_MULTIPLE); + } + { /* Receive Descriptor Count */ + static const struct pch_gbe_option opt = { + .type = range_option, + .name = "Receive Descriptors", + .err = "using default of " + __MODULE_STRING(PCH_GBE_DEFAULT_RXD), + .def = PCH_GBE_DEFAULT_RXD, + .arg = { .r = { .min = PCH_GBE_MIN_RXD } }, + .arg = { .r = { .max = PCH_GBE_MAX_RXD } } + }; + struct pch_gbe_rx_ring *rx_ring = adapter->rx_ring; + rx_ring->count = RxDescriptors; + pch_gbe_validate_option(&rx_ring->count, &opt, adapter); + rx_ring->count = roundup(rx_ring->count, + PCH_GBE_RX_DESC_MULTIPLE); + } + { /* Checksum Offload Enable/Disable */ + static const struct pch_gbe_option opt = { + .type = enable_option, + .name = "Checksum Offload", + .err = "defaulting to Enabled", + .def = PCH_GBE_DEFAULT_RX_CSUM + }; + adapter->rx_csum = XsumRX; + pch_gbe_validate_option((int *)(&adapter->rx_csum), + &opt, adapter); + } + { /* Checksum Offload Enable/Disable */ + static const struct pch_gbe_option opt = { + .type = enable_option, + .name = "Checksum Offload", + .err = "defaulting to Enabled", + .def = PCH_GBE_DEFAULT_TX_CSUM + }; + adapter->tx_csum = XsumTX; + pch_gbe_validate_option((int *)(&adapter->tx_csum), + &opt, adapter); + } + { /* Flow Control */ + static const struct pch_gbe_option opt = { + .type = list_option, + .name = "Flow Control", + .err = "reading default settings from EEPROM", + .def = PCH_GBE_FC_DEFAULT, + .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list), + .p = fc_list } } + }; + hw->mac.fc = FlowControl; + pch_gbe_validate_option((int *)(&hw->mac.fc), + &opt, adapter); + } + + pch_gbe_check_copper_options(adapter); +} diff --git a/drivers/net/pch_gbe/pch_gbe_phy.c b/drivers/net/pch_gbe/pch_gbe_phy.c new file mode 100644 index 0000000000000000000000000000000000000000..923a687acd30461ab536e351353d0a227765c3e1 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_phy.c @@ -0,0 +1,274 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "pch_gbe.h" +#include "pch_gbe_phy.h" + +#define PHY_MAX_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ + +/* PHY 1000 MII Register/Bit Definitions */ +/* PHY Registers defined by IEEE */ +#define PHY_CONTROL 0x00 /* Control Register */ +#define PHY_STATUS 0x01 /* Status Regiser */ +#define PHY_ID1 0x02 /* Phy Id Register (word 1) */ +#define PHY_ID2 0x03 /* Phy Id Register (word 2) */ +#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ +#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ +#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Register */ +#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */ +#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ +#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Register */ +#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Register */ +#define PHY_EXT_STATUS 0x0F /* Extended Status Register */ +#define PHY_PHYSP_CONTROL 0x10 /* PHY Specific Control Register */ +#define PHY_EXT_PHYSP_CONTROL 0x14 /* Extended PHY Specific Control Register */ +#define PHY_LED_CONTROL 0x18 /* LED Control Register */ +#define PHY_EXT_PHYSP_STATUS 0x1B /* Extended PHY Specific Status Register */ + +/* PHY Control Register */ +#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ +#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ +#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ +#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ +#define MII_CR_POWER_DOWN 0x0800 /* Power down */ +#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ +#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +#define MII_CR_SPEED_1000 0x0040 +#define MII_CR_SPEED_100 0x2000 +#define MII_CR_SPEED_10 0x0000 + +/* PHY Status Register */ +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ + +/* Phy Id Register (word 2) */ +#define PHY_REVISION_MASK 0x000F + +/* PHY Specific Control Register */ +#define PHYSP_CTRL_ASSERT_CRS_TX 0x0800 + + +/* Default value of PHY register */ +#define PHY_CONTROL_DEFAULT 0x1140 /* Control Register */ +#define PHY_AUTONEG_ADV_DEFAULT 0x01e0 /* Autoneg Advertisement */ +#define PHY_NEXT_PAGE_TX_DEFAULT 0x2001 /* Next Page TX */ +#define PHY_1000T_CTRL_DEFAULT 0x0300 /* 1000Base-T Control Register */ +#define PHY_PHYSP_CONTROL_DEFAULT 0x01EE /* PHY Specific Control Register */ + +/** + * pch_gbe_phy_get_id - Retrieve the PHY ID and revision + * @hw: Pointer to the HW structure + * Returns + * 0: Successful. + * Negative value: Failed. + */ +s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw) +{ + struct pch_gbe_phy_info *phy = &hw->phy; + s32 ret; + u16 phy_id1; + u16 phy_id2; + + ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID1, &phy_id1); + if (ret) + return ret; + ret = pch_gbe_phy_read_reg_miic(hw, PHY_ID2, &phy_id2); + if (ret) + return ret; + /* + * PHY_ID1: [bit15-0:ID(21-6)] + * PHY_ID2: [bit15-10:ID(5-0)][bit9-4:Model][bit3-0:revision] + */ + phy->id = (u32)phy_id1; + phy->id = ((phy->id << 6) | ((phy_id2 & 0xFC00) >> 10)); + phy->revision = (u32) (phy_id2 & 0x000F); + pr_debug("phy->id : 0x%08x phy->revision : 0x%08x\n", + phy->id, phy->revision); + return 0; +} + +/** + * pch_gbe_phy_read_reg_miic - Read MII control register + * @hw: Pointer to the HW structure + * @offset: Register offset to be read + * @data: Pointer to the read data + * Returns + * 0: Successful. + * -EINVAL: Invalid argument. + */ +s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data) +{ + struct pch_gbe_phy_info *phy = &hw->phy; + + if (offset > PHY_MAX_REG_ADDRESS) { + pr_err("PHY Address %d is out of range\n", offset); + return -EINVAL; + } + *data = pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_READ, + offset, (u16)0); + return 0; +} + +/** + * pch_gbe_phy_write_reg_miic - Write MII control register + * @hw: Pointer to the HW structure + * @offset: Register offset to be read + * @data: data to write to register at offset + * Returns + * 0: Successful. + * -EINVAL: Invalid argument. + */ +s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data) +{ + struct pch_gbe_phy_info *phy = &hw->phy; + + if (offset > PHY_MAX_REG_ADDRESS) { + pr_err("PHY Address %d is out of range\n", offset); + return -EINVAL; + } + pch_gbe_mac_ctrl_miim(hw, phy->addr, PCH_GBE_HAL_MIIM_WRITE, + offset, data); + return 0; +} + +/** + * pch_gbe_phy_sw_reset - PHY software reset + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw) +{ + u16 phy_ctrl; + + pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &phy_ctrl); + phy_ctrl |= MII_CR_RESET; + pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, phy_ctrl); + udelay(1); +} + +/** + * pch_gbe_phy_hw_reset - PHY hardware reset + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw) +{ + pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, PHY_CONTROL_DEFAULT); + pch_gbe_phy_write_reg_miic(hw, PHY_AUTONEG_ADV, + PHY_AUTONEG_ADV_DEFAULT); + pch_gbe_phy_write_reg_miic(hw, PHY_NEXT_PAGE_TX, + PHY_NEXT_PAGE_TX_DEFAULT); + pch_gbe_phy_write_reg_miic(hw, PHY_1000T_CTRL, PHY_1000T_CTRL_DEFAULT); + pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, + PHY_PHYSP_CONTROL_DEFAULT); +} + +/** + * pch_gbe_phy_power_up - restore link in case the phy was powered down + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_power_up(struct pch_gbe_hw *hw) +{ + u16 mii_reg; + + mii_reg = 0; + /* Just clear the power down bit to wake the phy back up */ + /* according to the manual, the phy will retain its + * settings across a power-down/up cycle */ + pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg); + mii_reg &= ~MII_CR_POWER_DOWN; + pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg); +} + +/** + * pch_gbe_phy_power_down - Power down PHY + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_power_down(struct pch_gbe_hw *hw) +{ + u16 mii_reg; + + mii_reg = 0; + /* Power down the PHY so no link is implied when interface is down * + * The PHY cannot be powered down if any of the following is TRUE * + * (a) WoL is enabled + * (b) AMT is active + */ + pch_gbe_phy_read_reg_miic(hw, PHY_CONTROL, &mii_reg); + mii_reg |= MII_CR_POWER_DOWN; + pch_gbe_phy_write_reg_miic(hw, PHY_CONTROL, mii_reg); + mdelay(1); +} + +/** + * pch_gbe_phy_set_rgmii - RGMII interface setting + * @hw: Pointer to the HW structure + */ +inline void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw) +{ + pch_gbe_phy_sw_reset(hw); +} + +/** + * pch_gbe_phy_init_setting - PHY initial setting + * @hw: Pointer to the HW structure + */ +void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw) +{ + struct pch_gbe_adapter *adapter; + struct ethtool_cmd cmd; + int ret; + u16 mii_reg; + + adapter = container_of(hw, struct pch_gbe_adapter, hw); + ret = mii_ethtool_gset(&adapter->mii, &cmd); + if (ret) + pr_err("Error: mii_ethtool_gset\n"); + + cmd.speed = hw->mac.link_speed; + cmd.duplex = hw->mac.link_duplex; + cmd.advertising = hw->phy.autoneg_advertised; + cmd.autoneg = hw->mac.autoneg; + pch_gbe_phy_write_reg_miic(hw, MII_BMCR, BMCR_RESET); + ret = mii_ethtool_sset(&adapter->mii, &cmd); + if (ret) + pr_err("Error: mii_ethtool_sset\n"); + + pch_gbe_phy_sw_reset(hw); + + pch_gbe_phy_read_reg_miic(hw, PHY_PHYSP_CONTROL, &mii_reg); + mii_reg |= PHYSP_CTRL_ASSERT_CRS_TX; + pch_gbe_phy_write_reg_miic(hw, PHY_PHYSP_CONTROL, mii_reg); + +} diff --git a/drivers/net/pch_gbe/pch_gbe_phy.h b/drivers/net/pch_gbe/pch_gbe_phy.h new file mode 100644 index 0000000000000000000000000000000000000000..03264dc7b5ec8a294da8c4e662f348ca74230d32 --- /dev/null +++ b/drivers/net/pch_gbe/pch_gbe_phy.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 1999 - 2010 Intel Corporation. + * Copyright (C) 2010 OKI SEMICONDUCTOR Co., LTD. + * + * This code was derived from the Intel e1000e Linux driver. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef _PCH_GBE_PHY_H_ +#define _PCH_GBE_PHY_H_ + +#define PCH_GBE_PHY_REGS_LEN 32 +#define PCH_GBE_PHY_RESET_DELAY_US 10 +#define PCH_GBE_MAC_IFOP_RGMII + +s32 pch_gbe_phy_get_id(struct pch_gbe_hw *hw); +s32 pch_gbe_phy_read_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 *data); +s32 pch_gbe_phy_write_reg_miic(struct pch_gbe_hw *hw, u32 offset, u16 data); +void pch_gbe_phy_sw_reset(struct pch_gbe_hw *hw); +void pch_gbe_phy_hw_reset(struct pch_gbe_hw *hw); +void pch_gbe_phy_power_up(struct pch_gbe_hw *hw); +void pch_gbe_phy_power_down(struct pch_gbe_hw *hw); +void pch_gbe_phy_set_rgmii(struct pch_gbe_hw *hw); +void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw); + +#endif /* _PCH_GBE_PHY_H_ */ diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 56f3fc45dbaa84ab9ecbc9f2e8a29902413c6ef6..8dd03439d994290a016c872a84a0bf439a7e6393 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -1125,7 +1125,7 @@ static int netdrv_open(struct net_device *dev) init_timer(&tp->timer); tp->timer.expires = jiffies + 3 * HZ; tp->timer.data = (unsigned long) dev; - tp->timer.function = &netdrv_timer; + tp->timer.function = netdrv_timer; add_timer(&tp->timer); DPRINTK("EXIT, returning 0\n"); diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index ff824e11f0b6865a74a0f55de50f7a02d659e75c..2807a0fcadc4f7a8630d41a92173c2942ecbda1b 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -69,6 +69,8 @@ earlier 3Com products. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -83,7 +85,6 @@ earlier 3Com products. #include #include #include -#include #include #include @@ -237,7 +238,6 @@ static int el3_rx(struct net_device *dev, int worklimit); static int el3_close(struct net_device *dev); static void el3_tx_timeout(struct net_device *dev); static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static const struct ethtool_ops netdev_ethtool_ops; static void set_rx_mode(struct net_device *dev); static void set_multicast_list(struct net_device *dev); @@ -283,7 +283,6 @@ static int tc574_probe(struct pcmcia_device *link) link->config_index = 1; dev->netdev_ops = &el3_netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->watchdog_timeo = TX_TIMEOUT; return tc574_config(link); @@ -359,8 +358,8 @@ static int tc574_config(struct pcmcia_device *link) for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i + 10)); if (phys_addr[0] == htons(0x6060)) { - printk(KERN_NOTICE "3c574_cs: IO port conflict at 0x%03lx" - "-0x%03lx\n", dev->base_addr, dev->base_addr+15); + pr_notice("IO port conflict at 0x%03lx-0x%03lx\n", + dev->base_addr, dev->base_addr+15); goto failed; } } @@ -374,7 +373,7 @@ static int tc574_config(struct pcmcia_device *link) outw(2<<11, ioaddr + RunnerRdCtrl); mcr = inb(ioaddr + 2); outw(0<<11, ioaddr + RunnerRdCtrl); - printk(KERN_INFO " ASIC rev %d,", mcr>>3); + pr_info(" ASIC rev %d,", mcr>>3); EL3WINDOW(3); config = inl(ioaddr + Wn3_Config); lp->default_media = (config & Xcvr) >> Xcvr_shift; @@ -411,7 +410,7 @@ static int tc574_config(struct pcmcia_device *link) } } if (phy > 32) { - printk(KERN_NOTICE " No MII transceivers found!\n"); + pr_notice(" No MII transceivers found!\n"); goto failed; } i = mdio_read(ioaddr, lp->phys, 16) | 0x40; @@ -427,18 +426,16 @@ static int tc574_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } - printk(KERN_INFO "%s: %s at io %#3lx, irq %d, " - "hw_addr %pM.\n", - dev->name, cardname, dev->base_addr, dev->irq, - dev->dev_addr); - printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n", - 8 << config & Ram_size, - ram_split[(config & Ram_split) >> Ram_split_shift], - config & Autoselect ? "autoselect " : ""); + netdev_info(dev, "%s at io %#3lx, irq %d, hw_addr %pM\n", + cardname, dev->base_addr, dev->irq, dev->dev_addr); + netdev_info(dev, " %dK FIFO split %s Rx:Tx, %sMII interface.\n", + 8 << config & Ram_size, + ram_split[(config & Ram_split) >> Ram_split_shift], + config & Autoselect ? "autoselect " : ""); return 0; @@ -479,14 +476,14 @@ static void dump_status(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; EL3WINDOW(1); - printk(KERN_INFO " irq status %04x, rx status %04x, tx status " - "%02x, tx free %04x\n", inw(ioaddr+EL3_STATUS), - inw(ioaddr+RxStatus), inb(ioaddr+TxStatus), - inw(ioaddr+TxFree)); + netdev_info(dev, " irq status %04x, rx status %04x, tx status %02x, tx free %04x\n", + inw(ioaddr+EL3_STATUS), + inw(ioaddr+RxStatus), inb(ioaddr+TxStatus), + inw(ioaddr+TxFree)); EL3WINDOW(4); - printk(KERN_INFO " diagnostics: fifo %04x net %04x ethernet %04x" - " media %04x\n", inw(ioaddr+0x04), inw(ioaddr+0x06), - inw(ioaddr+0x08), inw(ioaddr+0x0a)); + netdev_info(dev, " diagnostics: fifo %04x net %04x ethernet %04x media %04x\n", + inw(ioaddr+0x04), inw(ioaddr+0x06), + inw(ioaddr+0x08), inw(ioaddr+0x0a)); EL3WINDOW(1); } @@ -500,7 +497,7 @@ static void tc574_wait_for_completion(struct net_device *dev, int cmd) while (--i > 0) if (!(inw(dev->base_addr + EL3_STATUS) & 0x1000)) break; if (i == 0) - printk(KERN_NOTICE "%s: command 0x%04x did not complete!\n", dev->name, cmd); + netdev_notice(dev, "command 0x%04x did not complete!\n", cmd); } /* Read a word from the EEPROM using the regular EEPROM access register. @@ -687,7 +684,7 @@ static int el3_open(struct net_device *dev) netif_start_queue(dev); tc574_reset(dev); - lp->media.function = &media_check; + lp->media.function = media_check; lp->media.data = (unsigned long) dev; lp->media.expires = jiffies + HZ; add_timer(&lp->media); @@ -702,7 +699,7 @@ static void el3_tx_timeout(struct net_device *dev) { unsigned int ioaddr = dev->base_addr; - printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name); + netdev_notice(dev, "Transmit timed out!\n"); dump_status(dev); dev->stats.tx_errors++; dev->trans_start = jiffies; /* prevent tx timeout */ @@ -825,8 +822,8 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id) EL3WINDOW(4); fifo_diag = inw(ioaddr + Wn4_FIFODiag); EL3WINDOW(1); - printk(KERN_NOTICE "%s: adapter failure, FIFO diagnostic" - " register %04x.\n", dev->name, fifo_diag); + netdev_notice(dev, "adapter failure, FIFO diagnostic register %04x\n", + fifo_diag); if (fifo_diag & 0x0400) { /* Tx overrun */ tc574_wait_for_completion(dev, TxReset); @@ -880,7 +877,7 @@ static void media_check(unsigned long arg) this, we can limp along even if the interrupt is blocked */ if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) { if (!lp->fast_poll) - printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + netdev_info(dev, "interrupt(s) dropped!\n"); local_irq_save(flags); el3_interrupt(dev->irq, dev); @@ -903,23 +900,21 @@ static void media_check(unsigned long arg) if (media != lp->media_status) { if ((media ^ lp->media_status) & 0x0004) - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (lp->media_status & 0x0004) ? "lost" : "found"); + netdev_info(dev, "%s link beat\n", + (lp->media_status & 0x0004) ? "lost" : "found"); if ((media ^ lp->media_status) & 0x0020) { lp->partner = 0; if (lp->media_status & 0x0020) { - printk(KERN_INFO "%s: autonegotiation restarted\n", - dev->name); + netdev_info(dev, "autonegotiation restarted\n"); } else if (partner) { partner &= lp->advertising; lp->partner = partner; - printk(KERN_INFO "%s: autonegotiation complete: " - "%sbaseT-%cD selected\n", dev->name, - ((partner & 0x0180) ? "100" : "10"), - ((partner & 0x0140) ? 'F' : 'H')); + netdev_info(dev, "autonegotiation complete: " + "%dbaseT-%cD selected\n", + (partner & 0x0180) ? 100 : 10, + (partner & 0x0140) ? 'F' : 'H'); } else { - printk(KERN_INFO "%s: link partner did not autonegotiate\n", - dev->name); + netdev_info(dev, "link partner did not autonegotiate\n"); } EL3WINDOW(3); @@ -929,10 +924,9 @@ static void media_check(unsigned long arg) } if (media & 0x0010) - printk(KERN_INFO "%s: remote fault detected\n", - dev->name); + netdev_info(dev, "remote fault detected\n"); if (media & 0x0002) - printk(KERN_INFO "%s: jabber detected\n", dev->name); + netdev_info(dev, "jabber detected\n"); lp->media_status = media; } spin_unlock_irqrestore(&lp->window_lock, flags); @@ -1042,16 +1036,6 @@ static int el3_rx(struct net_device *dev, int worklimit) return worklimit; } -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "3c574_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - /* Provide ioctl() calls to examine the MII xcvr state. */ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index a07e22295330dadf2407f558e8500231e8990035..79b9ca0dbdb4351f3c7182833fae229e1b765222 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -19,6 +19,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRV_NAME "3c589_cs" #define DRV_VERSION "1.162-ac" @@ -237,7 +239,7 @@ static int tc589_config(struct pcmcia_device *link) __be16 *phys_addr; int ret, i, j, multi = 0, fifo; unsigned int ioaddr; - char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; + static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"}; u8 *buf; size_t len; @@ -246,8 +248,7 @@ static int tc589_config(struct pcmcia_device *link) phys_addr = (__be16 *)dev->dev_addr; /* Is this a 3c562? */ if (link->manf_id != MANFID_3COM) - printk(KERN_INFO "3c589_cs: hmmm, is this really a " - "3Com card??\n"); + dev_info(&link->dev, "hmmm, is this really a 3Com card??\n"); multi = (link->card_id == PRODID_3COM_3C562); link->io_lines = 16; @@ -288,8 +289,8 @@ static int tc589_config(struct pcmcia_device *link) for (i = 0; i < 3; i++) phys_addr[i] = htons(read_eeprom(ioaddr, i)); if (phys_addr[0] == htons(0x6060)) { - printk(KERN_ERR "3c589_cs: IO port conflict at 0x%03lx" - "-0x%03lx\n", dev->base_addr, dev->base_addr+15); + dev_err(&link->dev, "IO port conflict at 0x%03lx-0x%03lx\n", + dev->base_addr, dev->base_addr+15); goto failed; } } @@ -303,12 +304,12 @@ static int tc589_config(struct pcmcia_device *link) if ((if_port >= 0) && (if_port <= 3)) dev->if_port = if_port; else - printk(KERN_ERR "3c589_cs: invalid if_port requested\n"); + dev_err(&link->dev, "invalid if_port requested\n"); SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_ERR "3c589_cs: register_netdev() failed\n"); + dev_err(&link->dev, "register_netdev() failed\n"); goto failed; } @@ -502,7 +503,7 @@ static int el3_open(struct net_device *dev) tc589_reset(dev); init_timer(&lp->media); - lp->media.function = &media_check; + lp->media.function = media_check; lp->media.data = (unsigned long) dev; lp->media.expires = jiffies + HZ; add_timer(&lp->media); diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 9e8b28b271ae9e48e4a798a4806a4a8c7853299a..d2e166e29dda2ea5e972526a89af60097221fa0a 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -24,6 +24,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -32,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -85,7 +86,6 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, static struct net_device_stats *get_stats(struct net_device *dev); static void set_multicast_list(struct net_device *dev); static void axnet_tx_timeout(struct net_device *dev); -static const struct ethtool_ops netdev_ethtool_ops; static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); static void ei_watchdog(u_long arg); static void axnet_reset_8390(struct net_device *dev); @@ -161,7 +161,6 @@ static int axnet_probe(struct pcmcia_device *link) dev->netdev_ops = &axnet_netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->watchdog_timeo = TX_TIMEOUT; return axnet_config(link); @@ -300,8 +299,8 @@ static int axnet_config(struct pcmcia_device *link) dev->base_addr = link->resource[0]->start; if (!get_prom(link)) { - printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n"); - printk(KERN_NOTICE "axnet_cs: use pcnet_cs instead.\n"); + pr_notice("this is not an AX88190 card!\n"); + pr_notice("use pcnet_cs instead.\n"); goto failed; } @@ -310,10 +309,10 @@ static int axnet_config(struct pcmcia_device *link) ei_status.tx_start_page = AXNET_START_PG; ei_status.rx_start_page = AXNET_START_PG + TX_PAGES; ei_status.stop_page = AXNET_STOP_PG; - ei_status.reset_8390 = &axnet_reset_8390; - ei_status.get_8390_hdr = &get_8390_hdr; - ei_status.block_input = &block_input; - ei_status.block_output = &block_output; + ei_status.reset_8390 = axnet_reset_8390; + ei_status.get_8390_hdr = get_8390_hdr; + ei_status.block_input = block_input; + ei_status.block_output = block_output; if (inb(dev->base_addr + AXNET_TEST) != 0) info->flags |= IS_AX88790; @@ -346,19 +345,18 @@ static int axnet_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } - printk(KERN_INFO "%s: Asix AX88%d90: io %#3lx, irq %d, " - "hw_addr %pM\n", - dev->name, ((info->flags & IS_AX88790) ? 7 : 1), - dev->base_addr, dev->irq, - dev->dev_addr); + netdev_info(dev, "Asix AX88%d90: io %#3lx, irq %d, hw_addr %pM\n", + ((info->flags & IS_AX88790) ? 7 : 1), + dev->base_addr, dev->irq, dev->dev_addr); if (info->phy_id != -1) { - dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", info->phy_id, j); + netdev_dbg(dev, " MII transceiver at index %d, status %x\n", + info->phy_id, j); } else { - printk(KERN_NOTICE " No MII transceivers found!\n"); + netdev_notice(dev, " No MII transceivers found!\n"); } return 0; @@ -477,7 +475,7 @@ static int axnet_open(struct net_device *dev) info->link_status = 0x00; init_timer(&info->watchdog); - info->watchdog.function = &ei_watchdog; + info->watchdog.function = ei_watchdog; info->watchdog.data = (u_long)dev; info->watchdog.expires = jiffies + HZ; add_timer(&info->watchdog); @@ -530,8 +528,7 @@ static void axnet_reset_8390(struct net_device *dev) outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ if (i == 100) - printk(KERN_ERR "%s: axnet_reset_8390() did not complete.\n", - dev->name); + netdev_err(dev, "axnet_reset_8390() did not complete\n"); } /* axnet_reset_8390 */ @@ -558,7 +555,7 @@ static void ei_watchdog(u_long arg) this, we can limp along even if the interrupt is blocked */ if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { if (!info->fast_poll) - printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + netdev_info(dev, "interrupt(s) dropped!\n"); ei_irq_wrapper(dev->irq, dev); info->fast_poll = HZ; } @@ -573,7 +570,7 @@ static void ei_watchdog(u_long arg) goto reschedule; link = mdio_read(mii_addr, info->phy_id, 1); if (!link || (link == 0xffff)) { - printk(KERN_INFO "%s: MII is missing!\n", dev->name); + netdev_info(dev, "MII is missing!\n"); info->phy_id = -1; goto reschedule; } @@ -581,18 +578,14 @@ static void ei_watchdog(u_long arg) link &= 0x0004; if (link != info->link_status) { u_short p = mdio_read(mii_addr, info->phy_id, 5); - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (link) ? "found" : "lost"); + netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); if (link) { info->duplex_flag = (p & 0x0140) ? 0x80 : 0x00; if (p) - printk(KERN_INFO "%s: autonegotiation complete: " - "%sbaseT-%cD selected\n", dev->name, - ((p & 0x0180) ? "100" : "10"), - ((p & 0x0140) ? 'F' : 'H')); + netdev_info(dev, "autonegotiation complete: %dbaseT-%cD selected\n", + (p & 0x0180) ? 100 : 10, (p & 0x0140) ? 'F' : 'H'); else - printk(KERN_INFO "%s: link partner did not autonegotiate\n", - dev->name); + netdev_info(dev, "link partner did not autonegotiate\n"); AX88190_init(dev, 1); } info->link_status = link; @@ -603,16 +596,6 @@ static void ei_watchdog(u_long arg) add_timer(&info->watchdog); } -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "axnet_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - /*====================================================================*/ static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) @@ -798,9 +781,6 @@ module_exit(exit_axnet_cs); */ -static const char version_8390[] = KERN_INFO \ - "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@scyld.com)\n"; - #include #include #include @@ -947,9 +927,11 @@ static void axnet_tx_timeout(struct net_device *dev) isr = inb(e8390_base+EN0_ISR); spin_unlock_irqrestore(&ei_local->page_lock, flags); - printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", - dev->name, (txsr & ENTSR_ABT) ? "excess collisions." : - (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar); + netdev_printk(KERN_DEBUG, dev, + "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", + (txsr & ENTSR_ABT) ? "excess collisions." : + (isr) ? "lost interrupt?" : "cable problem?", + txsr, isr, tickssofar); if (!isr && !dev->stats.tx_packets) { @@ -1019,22 +1001,28 @@ static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, output_page = ei_local->tx_start_page; ei_local->tx1 = send_length; if (ei_debug && ei_local->tx2 > 0) - printk(KERN_DEBUG "%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n", - dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing); + netdev_printk(KERN_DEBUG, dev, + "idle transmitter tx2=%d, lasttx=%d, txing=%d\n", + ei_local->tx2, ei_local->lasttx, + ei_local->txing); } else if (ei_local->tx2 == 0) { output_page = ei_local->tx_start_page + TX_PAGES/2; ei_local->tx2 = send_length; if (ei_debug && ei_local->tx1 > 0) - printk(KERN_DEBUG "%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n", - dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing); + netdev_printk(KERN_DEBUG, dev, + "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n", + ei_local->tx1, ei_local->lasttx, + ei_local->txing); } else { /* We should never get here. */ if (ei_debug) - printk(KERN_DEBUG "%s: No Tx buffers free! tx1=%d tx2=%d last=%d\n", - dev->name, ei_local->tx1, ei_local->tx2, ei_local->lasttx); + netdev_printk(KERN_DEBUG, dev, + "No Tx buffers free! tx1=%d tx2=%d last=%d\n", + ei_local->tx1, ei_local->tx2, + ei_local->lasttx); ei_local->irqlock = 0; netif_stop_queue(dev); outb_p(ENISR_ALL, e8390_base + EN0_IMR); @@ -1122,23 +1110,26 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) spin_lock_irqsave(&ei_local->page_lock, flags); - if (ei_local->irqlock) - { + if (ei_local->irqlock) { #if 1 /* This might just be an interrupt for a PCI device sharing this line */ + const char *msg; /* The "irqlock" check is only for testing. */ - printk(ei_local->irqlock - ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n" - : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n", - dev->name, inb_p(e8390_base + EN0_ISR), - inb_p(e8390_base + EN0_IMR)); + if (ei_local->irqlock) + msg = "Interrupted while interrupts are masked!"; + else + msg = "Reentering the interrupt handler!"; + netdev_info(dev, "%s, isr=%#2x imr=%#2x\n", + msg, + inb_p(e8390_base + EN0_ISR), + inb_p(e8390_base + EN0_IMR)); #endif spin_unlock_irqrestore(&ei_local->page_lock, flags); return IRQ_NONE; } if (ei_debug > 3) - printk(KERN_DEBUG "%s: interrupt(isr=%#2.2x).\n", dev->name, - inb_p(e8390_base + EN0_ISR)); + netdev_printk(KERN_DEBUG, dev, "interrupt(isr=%#2.2x)\n", + inb_p(e8390_base + EN0_ISR)); outb_p(0x00, e8390_base + EN0_ISR); ei_local->irqlock = 1; @@ -1149,7 +1140,8 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) { if (!netif_running(dev) || (interrupts == 0xff)) { if (ei_debug > 1) - printk(KERN_WARNING "%s: interrupt from stopped card\n", dev->name); + netdev_warn(dev, + "interrupt from stopped card\n"); outb_p(interrupts, e8390_base + EN0_ISR); interrupts = 0; break; @@ -1192,11 +1184,12 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id) { /* 0xFF is valid for a card removal */ if(interrupts!=0xFF) - printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n", - dev->name, interrupts); + netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n", + interrupts); outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ } else { - printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts); + netdev_warn(dev, "unknown interrupt %#2x\n", + interrupts); outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ } } @@ -1230,18 +1223,19 @@ static void ei_tx_err(struct net_device *dev) unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); #ifdef VERBOSE_ERROR_DUMP - printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr); + netdev_printk(KERN_DEBUG, dev, + "transmitter error (%#2x):", txsr); if (txsr & ENTSR_ABT) - printk("excess-collisions "); + pr_cont(" excess-collisions"); if (txsr & ENTSR_ND) - printk("non-deferral "); + pr_cont(" non-deferral"); if (txsr & ENTSR_CRS) - printk("lost-carrier "); + pr_cont(" lost-carrier"); if (txsr & ENTSR_FU) - printk("FIFO-underrun "); + pr_cont(" FIFO-underrun"); if (txsr & ENTSR_CDH) - printk("lost-heartbeat "); - printk("\n"); + pr_cont(" lost-heartbeat"); + pr_cont("\n"); #endif if (tx_was_aborted) @@ -1278,8 +1272,9 @@ static void ei_tx_intr(struct net_device *dev) if (ei_local->tx1 < 0) { if (ei_local->lasttx != 1 && ei_local->lasttx != -1) - printk(KERN_ERR "%s: bogus last_tx_buffer %d, tx1=%d.\n", - ei_local->name, ei_local->lasttx, ei_local->tx1); + netdev_err(dev, "%s: bogus last_tx_buffer %d, tx1=%d\n", + ei_local->name, ei_local->lasttx, + ei_local->tx1); ei_local->tx1 = 0; if (ei_local->tx2 > 0) { @@ -1294,8 +1289,9 @@ static void ei_tx_intr(struct net_device *dev) else if (ei_local->tx2 < 0) { if (ei_local->lasttx != 2 && ei_local->lasttx != -2) - printk("%s: bogus last_tx_buffer %d, tx2=%d.\n", - ei_local->name, ei_local->lasttx, ei_local->tx2); + netdev_info(dev, "%s: bogus last_tx_buffer %d, tx2=%d\n", + ei_local->name, ei_local->lasttx, + ei_local->tx2); ei_local->tx2 = 0; if (ei_local->tx1 > 0) { @@ -1308,8 +1304,9 @@ static void ei_tx_intr(struct net_device *dev) else ei_local->lasttx = 10, ei_local->txing = 0; } -// else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n", -// dev->name, ei_local->lasttx); +// else +// netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n", +// ei_local->lasttx); /* Minimize Tx latency: update the statistics after we restart TXing. */ if (status & ENTSR_COL) @@ -1372,8 +1369,8 @@ static void ei_receive(struct net_device *dev) is that some clones crash in roughly the same way. */ if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF)) - printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n", - dev->name, this_frame, ei_local->current_page); + netdev_err(dev, "mismatched read page pointers %2x vs %2x\n", + this_frame, ei_local->current_page); if (this_frame == rxing_page) /* Read all the frames? */ break; /* Done for now */ @@ -1389,9 +1386,10 @@ static void ei_receive(struct net_device *dev) if (pkt_len < 60 || pkt_len > 1518) { if (ei_debug) - printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n", - dev->name, rx_frame.count, rx_frame.status, - rx_frame.next); + netdev_printk(KERN_DEBUG, dev, + "bogus packet size: %d, status=%#2x nxpg=%#2x\n", + rx_frame.count, rx_frame.status, + rx_frame.next); dev->stats.rx_errors++; dev->stats.rx_length_errors++; } @@ -1403,8 +1401,9 @@ static void ei_receive(struct net_device *dev) if (skb == NULL) { if (ei_debug > 1) - printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n", - dev->name, pkt_len); + netdev_printk(KERN_DEBUG, dev, + "Couldn't allocate a sk_buff of size %d\n", + pkt_len); dev->stats.rx_dropped++; break; } @@ -1424,9 +1423,10 @@ static void ei_receive(struct net_device *dev) else { if (ei_debug) - printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n", - dev->name, rx_frame.status, rx_frame.next, - rx_frame.count); + netdev_printk(KERN_DEBUG, dev, + "bogus packet: status=%#2x nxpg=%#2x size=%d\n", + rx_frame.status, rx_frame.next, + rx_frame.count); dev->stats.rx_errors++; /* NB: The NIC counts CRC, frame and missed errors. */ if (pkt_stat & ENRSR_FO) @@ -1436,8 +1436,8 @@ static void ei_receive(struct net_device *dev) /* This _should_ never happen: it's here for avoiding bad clones. */ if (next_frame >= ei_local->stop_page) { - printk("%s: next frame inconsistency, %#2x\n", dev->name, - next_frame); + netdev_info(dev, "next frame inconsistency, %#2x\n", + next_frame); next_frame = ei_local->rx_start_page; } ei_local->current_page = next_frame; @@ -1472,7 +1472,7 @@ static void ei_rx_overrun(struct net_device *dev) outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); if (ei_debug > 1) - printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name); + netdev_printk(KERN_DEBUG, dev, "Receiver overrun\n"); dev->stats.rx_over_errors++; /* @@ -1669,7 +1669,7 @@ static void AX88190_init(struct net_device *dev, int startp) { outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) - printk(KERN_ERR "Hw. address read/write mismap %d\n",i); + netdev_err(dev, "Hw. address read/write mismap %d\n", i); } outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); @@ -1706,8 +1706,7 @@ static void NS8390_trigger_send(struct net_device *dev, unsigned int length, if (inb_p(e8390_base) & E8390_TRANS) { - printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n", - dev->name); + netdev_warn(dev, "trigger_send() called with the transmitter busy\n"); return; } outb_p(length & 0xff, e8390_base + EN0_TCNTLO); diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index b706a72494774a73dd0514e85f5a37ea52985b05..27bfad76fc4077bdaa74187a79c2f0beb53c4ffc 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -51,23 +51,23 @@ #define VERSION "arcnet: COM20020 PCMCIA support loaded.\n" -#ifdef DEBUG static void regdump(struct net_device *dev) { +#ifdef DEBUG int ioaddr = dev->base_addr; int count; - printk("com20020 register dump:\n"); + netdev_dbg(dev, "register dump:\n"); for (count = ioaddr; count < ioaddr + 16; count++) { if (!(count % 16)) - printk("\n%04X: ", count); - printk("%02X ", inb(count)); + pr_cont("%04X:", count); + pr_cont(" %02X", inb(count)); } - printk("\n"); + pr_cont("\n"); - printk("buffer0 dump:\n"); + netdev_dbg(dev, "buffer0 dump:\n"); /* set up the address register */ count = 0; outb((count >> 8) | RDDATAflag | AUTOINCflag, _ADDR_HI); @@ -76,19 +76,15 @@ static void regdump(struct net_device *dev) for (count = 0; count < 256+32; count++) { if (!(count % 16)) - printk("\n%04X: ", count); + pr_cont("%04X:", count); /* copy the data */ - printk("%02X ", inb(_MEMDATA)); + pr_cont(" %02X", inb(_MEMDATA)); } - printk("\n"); + pr_cont("\n"); +#endif } -#else - -static inline void regdump(struct net_device *dev) { } - -#endif /*====================================================================*/ @@ -274,13 +270,13 @@ static int com20020_config(struct pcmcia_device *link) i = com20020_found(dev, 0); /* calls register_netdev */ if (i != 0) { - dev_printk(KERN_NOTICE, &link->dev, - "com20020_cs: com20020_found() failed\n"); + dev_notice(&link->dev, + "com20020_found() failed\n"); goto failed; } - dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n", - dev->name, dev->base_addr, dev->irq); + netdev_dbg(dev, "port %#3lx, irq %d\n", + dev->base_addr, dev->irq); return 0; failed: diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 1c327598bbe80efaa346d4f460ce54461f898368..9226cda4d054d4156f1f05e9a2df07856b300b10 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -28,6 +28,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRV_NAME "fmvj18x_cs" #define DRV_VERSION "2.9" @@ -289,7 +291,7 @@ static int mfc_try_io_port(struct pcmcia_device *link) link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; if (link->resource[1]->start == 0) { link->resource[1]->end = 0; - printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n"); + pr_notice("out of resource for serial\n"); } ret = pcmcia_request_io(link); if (ret == 0) @@ -497,7 +499,7 @@ static int fmvj18x_config(struct pcmcia_device *link) case XXX10304: /* Read MACID from Buggy CIS */ if (fmvj18x_get_hwinfo(link, buggybuf) == -1) { - printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n"); + pr_notice("unable to read hardware net address\n"); goto failed; } for (i = 0 ; i < 6; i++) { @@ -518,15 +520,14 @@ static int fmvj18x_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } /* print current configuration */ - printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, " - "hw_addr %pM\n", - dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", - dev->base_addr, dev->irq, dev->dev_addr); + netdev_info(dev, "%s, sram %s, port %#3lx, irq %d, hw_addr %pM\n", + card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", + dev->base_addr, dev->irq, dev->dev_addr); return 0; @@ -597,7 +598,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link) lp->base = ioremap(link->resource[3]->start, resource_size(link->resource[3])); if (lp->base == NULL) { - printk(KERN_NOTICE "fmvj18x_cs: ioremap failed\n"); + netdev_notice(dev, "ioremap failed\n"); return -1; } @@ -787,17 +788,16 @@ static void fjn_tx_timeout(struct net_device *dev) struct local_info_t *lp = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; - printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n", - dev->name, htons(inw(ioaddr + TX_STATUS)), - inb(ioaddr + TX_STATUS) & F_TMT_RDY - ? "IRQ conflict" : "network cable problem"); - printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x " - "%04x %04x %04x %04x %04x.\n", - dev->name, htons(inw(ioaddr + 0)), - htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)), - htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)), - htons(inw(ioaddr +10)), htons(inw(ioaddr +12)), - htons(inw(ioaddr +14))); + netdev_notice(dev, "transmit timed out with status %04x, %s?\n", + htons(inw(ioaddr + TX_STATUS)), + inb(ioaddr + TX_STATUS) & F_TMT_RDY + ? "IRQ conflict" : "network cable problem"); + netdev_notice(dev, "timeout registers: %04x %04x %04x " + "%04x %04x %04x %04x %04x.\n", + htons(inw(ioaddr + 0)), htons(inw(ioaddr + 2)), + htons(inw(ioaddr + 4)), htons(inw(ioaddr + 6)), + htons(inw(ioaddr + 8)), htons(inw(ioaddr + 10)), + htons(inw(ioaddr + 12)), htons(inw(ioaddr + 14))); dev->stats.tx_errors++; /* ToDo: We should try to restart the adaptor... */ local_irq_disable(); @@ -832,13 +832,13 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb, unsigned char *buf = skb->data; if (length > ETH_FRAME_LEN) { - printk(KERN_NOTICE "%s: Attempting to send a large packet" - " (%d bytes).\n", dev->name, length); + netdev_notice(dev, "Attempting to send a large packet (%d bytes)\n", + length); return NETDEV_TX_BUSY; } - pr_debug("%s: Transmitting a packet of length %lu.\n", - dev->name, (unsigned long)skb->len); + netdev_dbg(dev, "Transmitting a packet of length %lu\n", + (unsigned long)skb->len); dev->stats.tx_bytes += skb->len; /* Disable both interrupts. */ @@ -891,7 +891,7 @@ static void fjn_reset(struct net_device *dev) unsigned int ioaddr = dev->base_addr; int i; - pr_debug("fjn_reset(%s) called.\n",dev->name); + netdev_dbg(dev, "fjn_reset() called\n"); /* Reset controller */ if( sram_config == 0 ) @@ -975,8 +975,8 @@ static void fjn_rx(struct net_device *dev) while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) { u_short status = inw(ioaddr + DATAPORT); - pr_debug("%s: Rxing packet mode %02x status %04x.\n", - dev->name, inb(ioaddr + RX_MODE), status); + netdev_dbg(dev, "Rxing packet mode %02x status %04x.\n", + inb(ioaddr + RX_MODE), status); #ifndef final_version if (status == 0) { outb(F_SKP_PKT, ioaddr + RX_SKIP); @@ -995,16 +995,16 @@ static void fjn_rx(struct net_device *dev) struct sk_buff *skb; if (pkt_len > 1550) { - printk(KERN_NOTICE "%s: The FMV-18x claimed a very " - "large packet, size %d.\n", dev->name, pkt_len); + netdev_notice(dev, "The FMV-18x claimed a very large packet, size %d\n", + pkt_len); outb(F_SKP_PKT, ioaddr + RX_SKIP); dev->stats.rx_errors++; break; } skb = dev_alloc_skb(pkt_len+2); if (skb == NULL) { - printk(KERN_NOTICE "%s: Memory squeeze, dropping " - "packet (len %d).\n", dev->name, pkt_len); + netdev_notice(dev, "Memory squeeze, dropping packet (len %d)\n", + pkt_len); outb(F_SKP_PKT, ioaddr + RX_SKIP); dev->stats.rx_dropped++; break; diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index bf7dff96d881d20ade26849c61604882709e4fd2..15d57f5b6f2967b0eadb3335b1ec835230ec7f1b 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -45,6 +45,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -52,7 +54,6 @@ #include #include #include -#include #include #include #include @@ -105,16 +106,6 @@ typedef struct ibmtr_dev_t { struct tok_info *ti; } ibmtr_dev_t; -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "ibmtr_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) { ibmtr_dev_t *info = dev_id; struct net_device *dev = info->dev; @@ -148,8 +139,6 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link) info->dev = dev; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - return ibmtr_config(link); } /* ibmtr_attach */ @@ -256,15 +245,14 @@ static int __devinit ibmtr_config(struct pcmcia_device *link) i = ibmtr_probe_card(dev); if (i != 0) { - printk(KERN_NOTICE "ibmtr_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } - printk(KERN_INFO - "%s: port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", - dev->name, dev->base_addr, dev->irq, - (u_long)ti->mmio, (u_long)(ti->sram_base << 12), - dev->dev_addr); + netdev_info(dev, "port %#3lx, irq %d, mmio %#5lx, sram %#5lx, hwaddr=%pM\n", + dev->base_addr, dev->irq, + (u_long)ti->mmio, (u_long)(ti->sram_base << 12), + dev->dev_addr); return 0; failed: diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 1eca4f5a6e78b3824d3129a28a535764c0eefb98..0a2b0f9cdf337d116016a6f1814659f22d1e2487 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -111,6 +111,8 @@ Log: nmclan_cs.c,v ---------------------------------------------------------------------------- */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #define DRV_NAME "nmclan_cs" #define DRV_VERSION "0.16" @@ -502,7 +504,7 @@ static int mace_read(mace_private *lp, unsigned int ioaddr, int reg) spin_unlock_irqrestore(&lp->bank_lock, flags); break; } - return (data & 0xFF); + return data & 0xFF; } /* mace_read */ /* ---------------------------------------------------------------------------- @@ -546,7 +548,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr) /* Wait for reset bit to be cleared automatically after <= 200ns */; if(++ct > 500) { - printk(KERN_ERR "mace: reset failed, card removed ?\n"); + pr_err("reset failed, card removed?\n"); return -1; } udelay(1); @@ -593,7 +595,7 @@ static int mace_init(mace_private *lp, unsigned int ioaddr, char *enet_addr) { if(++ ct > 500) { - printk(KERN_ERR "mace: ADDRCHG timeout, card removed ?\n"); + pr_err("ADDRCHG timeout, card removed?\n"); return -1; } } @@ -654,8 +656,8 @@ static int nmclan_config(struct pcmcia_device *link) dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n", sig[0], sig[1]); } else { - printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should" - " be 0x40 0x?9\n", sig[0], sig[1]); + pr_notice("mace id not found: %x %x should be 0x40 0x?9\n", + sig[0], sig[1]); return -ENODEV; } } @@ -667,20 +669,18 @@ static int nmclan_config(struct pcmcia_device *link) if (if_port <= 2) dev->if_port = if_port; else - printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n"); + pr_notice("invalid if_port requested\n"); SET_NETDEV_DEV(dev, &link->dev); i = register_netdev(dev); if (i != 0) { - printk(KERN_NOTICE "nmclan_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } - printk(KERN_INFO "%s: nmclan: port %#3lx, irq %d, %s port," - " hw_addr %pM\n", - dev->name, dev->base_addr, dev->irq, if_names[dev->if_port], - dev->dev_addr); + netdev_info(dev, "nmclan: port %#3lx, irq %d, %s port, hw_addr %pM\n", + dev->base_addr, dev->irq, if_names[dev->if_port], dev->dev_addr); return 0; failed: @@ -768,8 +768,7 @@ static int mace_config(struct net_device *dev, struct ifmap *map) if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { if (map->port <= 2) { dev->if_port = map->port; - printk(KERN_INFO "%s: switched to %s port\n", dev->name, - if_names[dev->if_port]); + netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); } else return -EINVAL; } @@ -848,12 +847,12 @@ static void mace_tx_timeout(struct net_device *dev) mace_private *lp = netdev_priv(dev); struct pcmcia_device *link = lp->p_dev; - printk(KERN_NOTICE "%s: transmit timed out -- ", dev->name); + netdev_notice(dev, "transmit timed out -- "); #if RESET_ON_TIMEOUT - printk("resetting card\n"); + pr_cont("resetting card\n"); pcmcia_reset_card(link->socket); #else /* #if RESET_ON_TIMEOUT */ - printk("NOT resetting card\n"); + pr_cont("NOT resetting card\n"); #endif /* #if RESET_ON_TIMEOUT */ dev->trans_start = jiffies; /* prevent tx timeout */ netif_wake_queue(dev); @@ -935,22 +934,21 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id) ioaddr = dev->base_addr; if (lp->tx_irq_disabled) { - printk( - (lp->tx_irq_disabled? - KERN_NOTICE "%s: Interrupt with tx_irq_disabled " - "[isr=%02X, imr=%02X]\n": - KERN_NOTICE "%s: Re-entering the interrupt handler " - "[isr=%02X, imr=%02X]\n"), - dev->name, - inb(ioaddr + AM2150_MACE_BASE + MACE_IR), - inb(ioaddr + AM2150_MACE_BASE + MACE_IMR) - ); + const char *msg; + if (lp->tx_irq_disabled) + msg = "Interrupt with tx_irq_disabled"; + else + msg = "Re-entering the interrupt handler"; + netdev_notice(dev, "%s [isr=%02X, imr=%02X]\n", + msg, + inb(ioaddr + AM2150_MACE_BASE + MACE_IR), + inb(ioaddr + AM2150_MACE_BASE + MACE_IMR)); /* WARNING: MACE_IR has been read! */ return IRQ_NONE; } if (!netif_device_present(dev)) { - pr_debug("%s: interrupt from dead card\n", dev->name); + netdev_dbg(dev, "interrupt from dead card\n"); return IRQ_NONE; } @@ -1348,8 +1346,8 @@ static void BuildLAF(int *ladrf, int *adr) printk(KERN_DEBUG " adr =%pM\n", adr); printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode); for (i = 0; i < 8; i++) - printk(KERN_CONT " %02X", ladrf[i]); - printk(KERN_CONT "\n"); + pr_cont(" %02X", ladrf[i]); + pr_cont("\n"); #endif } /* BuildLAF */ diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 5d7d1d3088ae148b6491fc07482b0970178b9466..03096c80103d5c0fc98a52990aa18ec2d9af3804 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -28,6 +28,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -35,7 +37,6 @@ #include #include #include -#include #include #include #include @@ -99,7 +100,6 @@ static void pcnet_release(struct pcmcia_device *link); static int pcnet_open(struct net_device *dev); static int pcnet_close(struct net_device *dev); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -static const struct ethtool_ops netdev_ethtool_ops; static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); static void ei_watchdog(u_long arg); static void pcnet_reset_8390(struct net_device *dev); @@ -415,8 +415,6 @@ static hw_info_t *get_ax88190(struct pcmcia_device *link) dev->dev_addr[i] = j & 0xff; dev->dev_addr[i+1] = j >> 8; } - printk(KERN_NOTICE "pcnet_cs: this is an AX88190 card!\n"); - printk(KERN_NOTICE "pcnet_cs: use axnet_cs instead.\n"); return NULL; } @@ -604,9 +602,7 @@ static int pcnet_config(struct pcmcia_device *link) ei_status.name = "NE2000"; ei_status.word16 = 1; - ei_status.reset_8390 = &pcnet_reset_8390; - - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); + ei_status.reset_8390 = pcnet_reset_8390; if (info->flags & (IS_DL10019|IS_DL10022)) mii_phy_probe(dev); @@ -614,25 +610,25 @@ static int pcnet_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto failed; } if (info->flags & (IS_DL10019|IS_DL10022)) { u_char id = inb(dev->base_addr + 0x1a); - printk(KERN_INFO "%s: NE2000 (DL100%d rev %02x): ", - dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id); + netdev_info(dev, "NE2000 (DL100%d rev %02x): ", + (info->flags & IS_DL10022) ? 22 : 19, id); if (info->pna_phy) - printk("PNA, "); + pr_cont("PNA, "); } else { - printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name); + netdev_info(dev, "NE2000 Compatible: "); } - printk("io %#3lx, irq %d,", dev->base_addr, dev->irq); + pr_cont("io %#3lx, irq %d,", dev->base_addr, dev->irq); if (info->flags & USE_SHMEM) - printk (" mem %#5lx,", dev->mem_start); + pr_cont(" mem %#5lx,", dev->mem_start); if (info->flags & HAS_MISC_REG) - printk(" %s xcvr,", if_names[dev->if_port]); - printk(" hw_addr %pM\n", dev->dev_addr); + pr_cont(" %s xcvr,", if_names[dev->if_port]); + pr_cont(" hw_addr %pM\n", dev->dev_addr); return 0; failed: @@ -889,7 +885,7 @@ static void mii_phy_probe(struct net_device *dev) phyid = tmp << 16; phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2); phyid &= MII_PHYID_REV_MASK; - pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid); + netdev_dbg(dev, "MII at %d is 0x%08x\n", i, phyid); if (phyid == AM79C9XX_HOME_PHY) { info->pna_phy = i; } else if (phyid != AM79C9XX_ETH_PHY) { @@ -922,7 +918,7 @@ static int pcnet_open(struct net_device *dev) info->phy_id = info->eth_phy; info->link_status = 0x00; init_timer(&info->watchdog); - info->watchdog.function = &ei_watchdog; + info->watchdog.function = ei_watchdog; info->watchdog.data = (u_long)dev; info->watchdog.expires = jiffies + HZ; add_timer(&info->watchdog); @@ -975,8 +971,8 @@ static void pcnet_reset_8390(struct net_device *dev) outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ if (i == 100) - printk(KERN_ERR "%s: pcnet_reset_8390() did not complete.\n", - dev->name); + netdev_err(dev, "pcnet_reset_8390() did not complete.\n"); + set_misc_reg(dev); } /* pcnet_reset_8390 */ @@ -992,8 +988,7 @@ static int set_config(struct net_device *dev, struct ifmap *map) else if ((map->port < 1) || (map->port > 2)) return -EINVAL; dev->if_port = map->port; - printk(KERN_INFO "%s: switched to %s port\n", - dev->name, if_names[dev->if_port]); + netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); NS8390_init(dev, 1); } return 0; @@ -1028,7 +1023,7 @@ static void ei_watchdog(u_long arg) this, we can limp along even if the interrupt is blocked */ if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { if (!info->fast_poll) - printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + netdev_info(dev, "interrupt(s) dropped!\n"); ei_irq_wrapper(dev->irq, dev); info->fast_poll = HZ; } @@ -1048,7 +1043,7 @@ static void ei_watchdog(u_long arg) if (info->eth_phy) { info->phy_id = info->eth_phy = 0; } else { - printk(KERN_INFO "%s: MII is missing!\n", dev->name); + netdev_info(dev, "MII is missing!\n"); info->flags &= ~HAS_MII; } goto reschedule; @@ -1057,8 +1052,7 @@ static void ei_watchdog(u_long arg) link &= 0x0004; if (link != info->link_status) { u_short p = mdio_read(mii_addr, info->phy_id, 5); - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (link) ? "found" : "lost"); + netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); if (link && (info->flags & IS_DL10022)) { /* Disable collision detection on full duplex links */ outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG); @@ -1069,13 +1063,12 @@ static void ei_watchdog(u_long arg) if (link) { if (info->phy_id == info->eth_phy) { if (p) - printk(KERN_INFO "%s: autonegotiation complete: " - "%sbaseT-%cD selected\n", dev->name, + netdev_info(dev, "autonegotiation complete: " + "%sbaseT-%cD selected\n", ((p & 0x0180) ? "100" : "10"), ((p & 0x0140) ? 'F' : 'H')); else - printk(KERN_INFO "%s: link partner did not " - "autonegotiate\n", dev->name); + netdev_info(dev, "link partner did not autonegotiate\n"); } NS8390_init(dev, 1); } @@ -1088,7 +1081,7 @@ static void ei_watchdog(u_long arg) /* isolate this MII and try flipping to the other one */ mdio_write(mii_addr, info->phy_id, 0, 0x0400); info->phy_id ^= info->pna_phy ^ info->eth_phy; - printk(KERN_INFO "%s: switched to %s transceiver\n", dev->name, + netdev_info(dev, "switched to %s transceiver\n", (info->phy_id == info->eth_phy) ? "ethernet" : "PNA"); mdio_write(mii_addr, info->phy_id, 0, (info->phy_id == info->eth_phy) ? 0x1000 : 0); @@ -1104,18 +1097,6 @@ static void ei_watchdog(u_long arg) /*====================================================================*/ -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "pcnet_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - -/*====================================================================*/ - static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1148,9 +1129,9 @@ static void dma_get_8390_hdr(struct net_device *dev, unsigned int nic_base = dev->base_addr; if (ei_status.dmaing) { - printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input." + netdev_notice(dev, "DMAing conflict in dma_block_input." "[DMAstat:%1x][irqlock:%1x]\n", - dev->name, ei_status.dmaing, ei_status.irqlock); + ei_status.dmaing, ei_status.irqlock); return; } @@ -1181,11 +1162,11 @@ static void dma_block_input(struct net_device *dev, int count, char *buf = skb->data; if ((ei_debug > 4) && (count != 4)) - pr_debug("%s: [bi=%d]\n", dev->name, count+4); + netdev_dbg(dev, "[bi=%d]\n", count+4); if (ei_status.dmaing) { - printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input." + netdev_notice(dev, "DMAing conflict in dma_block_input." "[DMAstat:%1x][irqlock:%1x]\n", - dev->name, ei_status.dmaing, ei_status.irqlock); + ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; @@ -1215,9 +1196,9 @@ static void dma_block_input(struct net_device *dev, int count, break; } while (--tries > 0); if (tries <= 0) - printk(KERN_NOTICE "%s: RX transfer address mismatch," + netdev_notice(dev, "RX transfer address mismatch," "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, ring_offset + xfer_count, addr); + ring_offset + xfer_count, addr); } #endif outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ @@ -1238,7 +1219,7 @@ static void dma_block_output(struct net_device *dev, int count, #ifdef PCMCIA_DEBUG if (ei_debug > 4) - printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count); + netdev_dbg(dev, "[bo=%d]\n", count); #endif /* Round the count up for word writes. Do we need to do this? @@ -1247,9 +1228,9 @@ static void dma_block_output(struct net_device *dev, int count, if (count & 0x01) count++; if (ei_status.dmaing) { - printk(KERN_NOTICE "%s: DMAing conflict in dma_block_output." + netdev_notice(dev, "DMAing conflict in dma_block_output." "[DMAstat:%1x][irqlock:%1x]\n", - dev->name, ei_status.dmaing, ei_status.irqlock); + ei_status.dmaing, ei_status.irqlock); return; } ei_status.dmaing |= 0x01; @@ -1286,9 +1267,9 @@ static void dma_block_output(struct net_device *dev, int count, break; } while (--tries > 0); if (tries <= 0) { - printk(KERN_NOTICE "%s: Tx packet transfer address mismatch," + netdev_notice(dev, "Tx packet transfer address mismatch," "%#4.4x (expected) vs. %#4.4x (actual).\n", - dev->name, (start_page << 8) + count, addr); + (start_page << 8) + count, addr); if (retries++ == 0) goto retry; } @@ -1297,8 +1278,7 @@ static void dma_block_output(struct net_device *dev, int count, while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) { - printk(KERN_NOTICE "%s: timeout waiting for Tx RDC.\n", - dev->name); + netdev_notice(dev, "timeout waiting for Tx RDC.\n"); pcnet_reset_8390(dev); NS8390_init(dev, 1); break; @@ -1322,9 +1302,9 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg, ei_status.stop_page = stop_pg; /* set up block i/o functions */ - ei_status.get_8390_hdr = &dma_get_8390_hdr; - ei_status.block_input = &dma_block_input; - ei_status.block_output = &dma_block_output; + ei_status.get_8390_hdr = dma_get_8390_hdr; + ei_status.block_input = dma_block_input; + ei_status.block_output = dma_block_output; return 0; } @@ -1470,9 +1450,9 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg, (resource_size(link->resource[3]) - offset) >> 8); /* set up block i/o functions */ - ei_status.get_8390_hdr = &shmem_get_8390_hdr; - ei_status.block_input = &shmem_block_input; - ei_status.block_output = &shmem_block_output; + ei_status.get_8390_hdr = shmem_get_8390_hdr; + ei_status.block_input = shmem_block_input; + ei_status.block_output = shmem_block_output; info->flags |= USE_SHMEM; return 0; diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 0af2fc8ec164a7b2a200ee0452777538d93d4b4e..8a9ff53189236eff17bca6abd2afb8d5f9ac8809 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -25,6 +25,8 @@ ======================================================================*/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -293,7 +295,7 @@ static const struct net_device_ops smc_netdev_ops = { .ndo_tx_timeout = smc_tx_timeout, .ndo_set_config = s9k_config, .ndo_set_multicast_list = set_rx_mode, - .ndo_do_ioctl = &smc_ioctl, + .ndo_do_ioctl = smc_ioctl, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, @@ -788,11 +790,11 @@ static int check_sig(struct pcmcia_device *link) ((s >> 8) != (s & 0xff))) { SMC_SELECT_BANK(3); s = inw(ioaddr + REVISION); - return (s & 0xff); + return s & 0xff; } if (width) { - printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); + pr_info("using 8-bit IO window\n"); smc91c92_suspend(link); pcmcia_fixup_iowidth(link); @@ -845,7 +847,7 @@ static int smc91c92_config(struct pcmcia_device *link) if ((if_port >= 0) && (if_port <= 2)) dev->if_port = if_port; else - printk(KERN_NOTICE "smc91c92_cs: invalid if_port requested\n"); + dev_notice(&link->dev, "invalid if_port requested\n"); switch (smc->manfid) { case MANFID_OSITECH: @@ -863,7 +865,7 @@ static int smc91c92_config(struct pcmcia_device *link) } if (i != 0) { - printk(KERN_NOTICE "smc91c92_cs: Unable to find hardware address.\n"); + dev_notice(&link->dev, "Unable to find hardware address.\n"); goto config_failed; } @@ -916,30 +918,28 @@ static int smc91c92_config(struct pcmcia_device *link) SET_NETDEV_DEV(dev, &link->dev); if (register_netdev(dev) != 0) { - printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n"); + dev_err(&link->dev, "register_netdev() failed\n"); goto config_undo; } - printk(KERN_INFO "%s: smc91c%s rev %d: io %#3lx, irq %d, " - "hw_addr %pM\n", - dev->name, name, (rev & 0x0f), dev->base_addr, dev->irq, - dev->dev_addr); + netdev_info(dev, "smc91c%s rev %d: io %#3lx, irq %d, hw_addr %pM\n", + name, (rev & 0x0f), dev->base_addr, dev->irq, dev->dev_addr); if (rev > 0) { if (mir & 0x3ff) - printk(KERN_INFO " %lu byte", mir); + netdev_info(dev, " %lu byte", mir); else - printk(KERN_INFO " %lu kb", mir>>10); - printk(" buffer, %s xcvr\n", (smc->cfg & CFG_MII_SELECT) ? - "MII" : if_names[dev->if_port]); + netdev_info(dev, " %lu kb", mir>>10); + pr_cont(" buffer, %s xcvr\n", + (smc->cfg & CFG_MII_SELECT) ? "MII" : if_names[dev->if_port]); } if (smc->cfg & CFG_MII_SELECT) { if (smc->mii_if.phy_id != -1) { - dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", - smc->mii_if.phy_id, j); + netdev_dbg(dev, " MII transceiver at index %d, status %x\n", + smc->mii_if.phy_id, j); } else { - printk(KERN_NOTICE " No MII transceivers found!\n"); + netdev_notice(dev, " No MII transceivers found!\n"); } } return 0; @@ -1037,10 +1037,10 @@ static void smc_dump(struct net_device *dev) save = inw(ioaddr + BANK_SELECT); for (w = 0; w < 4; w++) { SMC_SELECT_BANK(w); - printk(KERN_DEBUG "bank %d: ", w); + netdev_printk(KERN_DEBUG, dev, "bank %d: ", w); for (i = 0; i < 14; i += 2) - printk(" %04x", inw(ioaddr + i)); - printk("\n"); + pr_cont(" %04x", inw(ioaddr + i)); + pr_cont("\n"); } outw(save, ioaddr + BANK_SELECT); } @@ -1062,7 +1062,7 @@ static int smc_open(struct net_device *dev) return -ENODEV; /* Physical device present signature. */ if (check_sig(link) < 0) { - printk("smc91c92_cs: Yikes! Bad chip signature!\n"); + netdev_info(dev, "Yikes! Bad chip signature!\n"); return -ENODEV; } link->open++; @@ -1073,7 +1073,7 @@ static int smc_open(struct net_device *dev) smc_reset(dev); init_timer(&smc->media); - smc->media.function = &media_check; + smc->media.function = media_check; smc->media.data = (u_long) dev; smc->media.expires = jiffies + HZ; add_timer(&smc->media); @@ -1128,7 +1128,7 @@ static void smc_hardware_send_packet(struct net_device * dev) u_char packet_no; if (!skb) { - printk(KERN_ERR "%s: In XMIT with no packet to send.\n", dev->name); + netdev_err(dev, "In XMIT with no packet to send\n"); return; } @@ -1136,8 +1136,8 @@ static void smc_hardware_send_packet(struct net_device * dev) packet_no = inw(ioaddr + PNR_ARR) >> 8; if (packet_no & 0x80) { /* If not, there is a hardware problem! Likely an ejected card. */ - printk(KERN_WARNING "%s: 91c92 hardware Tx buffer allocation" - " failed, status %#2.2x.\n", dev->name, packet_no); + netdev_warn(dev, "hardware Tx buffer allocation failed, status %#2.2x\n", + packet_no); dev_kfree_skb_irq(skb); smc->saved_skb = NULL; netif_start_queue(dev); @@ -1156,8 +1156,7 @@ static void smc_hardware_send_packet(struct net_device * dev) u_char *buf = skb->data; u_int length = skb->len; /* The chip will pad to ethernet min. */ - pr_debug("%s: Trying to xmit packet of length %d.\n", - dev->name, length); + netdev_dbg(dev, "Trying to xmit packet of length %d\n", length); /* send the packet length: +6 for status word, length, and ctl */ outw(0, ioaddr + DATA_1); @@ -1189,9 +1188,8 @@ static void smc_tx_timeout(struct net_device *dev) struct smc_private *smc = netdev_priv(dev); unsigned int ioaddr = dev->base_addr; - printk(KERN_NOTICE "%s: SMC91c92 transmit timed out, " - "Tx_status %2.2x status %4.4x.\n", - dev->name, inw(ioaddr)&0xff, inw(ioaddr + 2)); + netdev_notice(dev, "transmit timed out, Tx_status %2.2x status %4.4x.\n", + inw(ioaddr)&0xff, inw(ioaddr + 2)); dev->stats.tx_errors++; smc_reset(dev); dev->trans_start = jiffies; /* prevent tx timeout */ @@ -1210,14 +1208,14 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb, netif_stop_queue(dev); - pr_debug("%s: smc_start_xmit(length = %d) called," - " status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2)); + netdev_dbg(dev, "smc_start_xmit(length = %d) called, status %04x\n", + skb->len, inw(ioaddr + 2)); if (smc->saved_skb) { /* THIS SHOULD NEVER HAPPEN. */ dev->stats.tx_aborted_errors++; - printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n", - dev->name); + netdev_printk(KERN_DEBUG, dev, + "Internal error -- sent packet while busy\n"); return NETDEV_TX_BUSY; } smc->saved_skb = skb; @@ -1225,7 +1223,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb, num_pages = skb->len >> 8; if (num_pages > 7) { - printk(KERN_ERR "%s: Far too big packet error.\n", dev->name); + netdev_err(dev, "Far too big packet error: %d pages\n", num_pages); dev_kfree_skb (skb); smc->saved_skb = NULL; dev->stats.tx_dropped++; @@ -1295,8 +1293,7 @@ static void smc_tx_err(struct net_device * dev) } if (tx_status & TS_SUCCESS) { - printk(KERN_NOTICE "%s: Successful packet caused error " - "interrupt?\n", dev->name); + netdev_notice(dev, "Successful packet caused error interrupt?\n"); } /* re-enable transmit */ SMC_SELECT_BANK(0); @@ -1486,8 +1483,7 @@ static void smc_rx(struct net_device *dev) /* Assertion: we are in Window 2. */ if (inw(ioaddr + FIFO_PORTS) & FP_RXEMPTY) { - printk(KERN_ERR "%s: smc_rx() with nothing on Rx FIFO.\n", - dev->name); + netdev_err(dev, "smc_rx() with nothing on Rx FIFO\n"); return; } @@ -1602,8 +1598,7 @@ static int s9k_config(struct net_device *dev, struct ifmap *map) else if (map->port > 2) return -EINVAL; dev->if_port = map->port; - printk(KERN_INFO "%s: switched to %s port\n", - dev->name, if_names[dev->if_port]); + netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); smc_reset(dev); } return 0; @@ -1754,7 +1749,7 @@ static void media_check(u_long arg) this, we can limp along even if the interrupt is blocked */ if (smc->watchdog++ && ((i>>8) & i)) { if (!smc->fast_poll) - printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name); + netdev_info(dev, "interrupt(s) dropped!\n"); local_irq_save(flags); smc_interrupt(dev->irq, dev); local_irq_restore(flags); @@ -1778,7 +1773,7 @@ static void media_check(u_long arg) SMC_SELECT_BANK(3); link = mdio_read(dev, smc->mii_if.phy_id, 1); if (!link || (link == 0xffff)) { - printk(KERN_INFO "%s: MII is missing!\n", dev->name); + netdev_info(dev, "MII is missing!\n"); smc->mii_if.phy_id = -1; goto reschedule; } @@ -1786,15 +1781,13 @@ static void media_check(u_long arg) link &= 0x0004; if (link != smc->link_status) { u_short p = mdio_read(dev, smc->mii_if.phy_id, 5); - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (link) ? "found" : "lost"); + netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); smc->duplex = (((p & 0x0100) || ((p & 0x1c0) == 0x40)) ? TCR_FDUPLX : 0); if (link) { - printk(KERN_INFO "%s: autonegotiation complete: " - "%sbaseT-%cD selected\n", dev->name, - ((p & 0x0180) ? "100" : "10"), - (smc->duplex ? 'F' : 'H')); + netdev_info(dev, "autonegotiation complete: " + "%dbaseT-%cD selected\n", + (p & 0x0180) ? 100 : 10, smc->duplex ? 'F' : 'H'); } SMC_SELECT_BANK(0); outw(inw(ioaddr + TCR) | smc->duplex, ioaddr + TCR); @@ -1813,25 +1806,23 @@ static void media_check(u_long arg) if (media != smc->media_status) { if ((media & smc->media_status & 1) && ((smc->media_status ^ media) & EPH_LINK_OK)) - printk(KERN_INFO "%s: %s link beat\n", dev->name, - (smc->media_status & EPH_LINK_OK ? "lost" : "found")); + netdev_info(dev, "%s link beat\n", + smc->media_status & EPH_LINK_OK ? "lost" : "found"); else if ((media & smc->media_status & 2) && ((smc->media_status ^ media) & EPH_16COL)) - printk(KERN_INFO "%s: coax cable %s\n", dev->name, - (media & EPH_16COL ? "problem" : "ok")); + netdev_info(dev, "coax cable %s\n", + media & EPH_16COL ? "problem" : "ok"); if (dev->if_port == 0) { if (media & 1) { if (media & EPH_LINK_OK) - printk(KERN_INFO "%s: flipped to 10baseT\n", - dev->name); + netdev_info(dev, "flipped to 10baseT\n"); else smc_set_xcvr(dev, 2); } else { if (media & EPH_16COL) smc_set_xcvr(dev, 1); else - printk(KERN_INFO "%s: flipped to 10base2\n", - dev->name); + netdev_info(dev, "flipped to 10base2\n"); } } smc->media_status = media; diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 1fece617c069b68ddb6b384741bf43519d52b99c..a46b7fd6c0f5483f4a117f4c3c9a7e00b7b93e81 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -63,6 +63,8 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -209,13 +211,6 @@ enum xirc_cmd { /* Commands */ static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" }; - -#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: " -#define KERR_XIRC KERN_ERR "xirc2ps_cs: " -#define KWRN_XIRC KERN_WARNING "xirc2ps_cs: " -#define KNOT_XIRC KERN_NOTICE "xirc2ps_cs: " -#define KINF_XIRC KERN_INFO "xirc2ps_cs: " - /* card types */ #define XIR_UNKNOWN 0 /* unknown: not supported */ #define XIR_CE 1 /* (prodid 1) different hardware: not supported */ @@ -327,26 +322,26 @@ PrintRegisters(struct net_device *dev) if (pc_debug > 1) { int i, page; - printk(KDBG_XIRC "Register common: "); + printk(KERN_DEBUG pr_fmt("Register common: ")); for (i = 0; i < 8; i++) - printk(" %2.2x", GetByte(i)); - printk("\n"); + pr_cont(" %2.2x", GetByte(i)); + pr_cont("\n"); for (page = 0; page <= 8; page++) { - printk(KDBG_XIRC "Register page %2x: ", page); + printk(KERN_DEBUG pr_fmt("Register page %2x: "), page); SelectPage(page); for (i = 8; i < 16; i++) - printk(" %2.2x", GetByte(i)); - printk("\n"); + pr_cont(" %2.2x", GetByte(i)); + pr_cont("\n"); } for (page=0x40 ; page <= 0x5f; page++) { if (page == 0x43 || (page >= 0x46 && page <= 0x4f) || (page >= 0x51 && page <=0x5e)) continue; - printk(KDBG_XIRC "Register page %2x: ", page); + printk(KERN_DEBUG pr_fmt("Register page %2x: "), page); SelectPage(page); for (i = 8; i < 16; i++) - printk(" %2.2x", GetByte(i)); - printk("\n"); + pr_cont(" %2.2x", GetByte(i)); + pr_cont("\n"); } } } @@ -566,11 +561,11 @@ set_card_type(struct pcmcia_device *link) local->modem = 0; local->card_type = XIR_UNKNOWN; if (!(prodid & 0x40)) { - printk(KNOT_XIRC "Ooops: Not a creditcard\n"); + pr_notice("Oops: Not a creditcard\n"); return 0; } if (!(mediaid & 0x01)) { - printk(KNOT_XIRC "Not an Ethernet card\n"); + pr_notice("Not an Ethernet card\n"); return 0; } if (mediaid & 0x10) { @@ -601,12 +596,11 @@ set_card_type(struct pcmcia_device *link) } } if (local->card_type == XIR_CE || local->card_type == XIR_CEM) { - printk(KNOT_XIRC "Sorry, this is an old CE card\n"); + pr_notice("Sorry, this is an old CE card\n"); return 0; } if (local->card_type == XIR_UNKNOWN) - printk(KNOT_XIRC "unknown card (mediaid=%02x prodid=%02x)\n", - mediaid, prodid); + pr_notice("unknown card (mediaid=%02x prodid=%02x)\n", mediaid, prodid); return 1; } @@ -710,7 +704,7 @@ xirc2ps_config(struct pcmcia_device * link) /* Is this a valid card */ if (link->has_manf_id == 0) { - printk(KNOT_XIRC "manfid not found in CIS\n"); + pr_notice("manfid not found in CIS\n"); goto failure; } @@ -732,14 +726,14 @@ xirc2ps_config(struct pcmcia_device * link) local->manf_str = "Toshiba"; break; default: - printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n", - (unsigned)link->manf_id); + pr_notice("Unknown Card Manufacturer ID: 0x%04x\n", + (unsigned)link->manf_id); goto failure; } dev_dbg(&link->dev, "found %s card\n", local->manf_str); if (!set_card_type(link)) { - printk(KNOT_XIRC "this card is not supported\n"); + pr_notice("this card is not supported\n"); goto failure; } @@ -765,7 +759,7 @@ xirc2ps_config(struct pcmcia_device * link) err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev); if (err) { - printk(KNOT_XIRC "node-id not found in CIS\n"); + pr_notice("node-id not found in CIS\n"); goto failure; } @@ -792,7 +786,7 @@ xirc2ps_config(struct pcmcia_device * link) * try to configure as Ethernet only. * .... */ } - printk(KNOT_XIRC "no ports available\n"); + pr_notice("no ports available\n"); } else { link->io_lines = 10; link->resource[0]->end = 16; @@ -865,24 +859,24 @@ xirc2ps_config(struct pcmcia_device * link) #if 0 { u_char tmp; - printk(KERN_INFO "ECOR:"); + pr_info("ECOR:"); for (i=0; i < 7; i++) { tmp = readb(local->dingo_ccr + i*2); - printk(" %02x", tmp); + pr_cont(" %02x", tmp); } - printk("\n"); - printk(KERN_INFO "DCOR:"); + pr_cont("\n"); + pr_info("DCOR:"); for (i=0; i < 4; i++) { tmp = readb(local->dingo_ccr + 0x20 + i*2); - printk(" %02x", tmp); + pr_cont(" %02x", tmp); } - printk("\n"); - printk(KERN_INFO "SCOR:"); + pr_cont("\n"); + pr_info("SCOR:"); for (i=0; i < 10; i++) { tmp = readb(local->dingo_ccr + 0x40 + i*2); - printk(" %02x", tmp); + pr_cont(" %02x", tmp); } - printk("\n"); + pr_cont("\n"); } #endif @@ -901,7 +895,7 @@ xirc2ps_config(struct pcmcia_device * link) (local->mohawk && if_port==4)) dev->if_port = if_port; else - printk(KNOT_XIRC "invalid if_port requested\n"); + pr_notice("invalid if_port requested\n"); /* we can now register the device with the net subsystem */ dev->irq = link->irq; @@ -913,14 +907,14 @@ xirc2ps_config(struct pcmcia_device * link) SET_NETDEV_DEV(dev, &link->dev); if ((err=register_netdev(dev))) { - printk(KNOT_XIRC "register_netdev() failed\n"); + pr_notice("register_netdev() failed\n"); goto config_error; } /* give some infos about the hardware */ - printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr %pM\n", - dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq, - dev->dev_addr); + netdev_info(dev, "%s: port %#3lx, irq %d, hwaddr %pM\n", + local->manf_str, (u_long)dev->base_addr, (int)dev->irq, + dev->dev_addr); return 0; @@ -1047,8 +1041,7 @@ xirc2ps_interrupt(int irq, void *dev_id) skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */ if (!skb) { - printk(KNOT_XIRC "low memory, packet dropped (size=%u)\n", - pktlen); + pr_notice("low memory, packet dropped (size=%u)\n", pktlen); dev->stats.rx_dropped++; } else { /* okay get the packet */ skb_reserve(skb, 2); @@ -1217,7 +1210,7 @@ xirc_tx_timeout(struct net_device *dev) { local_info_t *lp = netdev_priv(dev); dev->stats.tx_errors++; - printk(KERN_NOTICE "%s: transmit timed out\n", dev->name); + netdev_notice(dev, "transmit timed out\n"); schedule_work(&lp->tx_timeout_task); } @@ -1384,8 +1377,7 @@ do_config(struct net_device *dev, struct ifmap *map) local->probe_port = 0; dev->if_port = map->port; } - printk(KERN_INFO "%s: switching to %s port\n", - dev->name, if_names[dev->if_port]); + netdev_info(dev, "switching to %s port\n", if_names[dev->if_port]); do_reset(dev,1); /* not the fine way :-) */ } return 0; @@ -1525,7 +1517,7 @@ do_reset(struct net_device *dev, int full) { SelectPage(0); value = GetByte(XIRCREG_ESR); /* read the ESR */ - printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value); + pr_debug("%s: ESR is: %#02x\n", dev->name, value); } #endif @@ -1575,13 +1567,12 @@ do_reset(struct net_device *dev, int full) if (full && local->mohawk && init_mii(dev)) { if (dev->if_port == 4 || local->dingo || local->new_mii) { - printk(KERN_INFO "%s: MII selected\n", dev->name); + netdev_info(dev, "MII selected\n"); SelectPage(2); PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08); msleep(20); } else { - printk(KERN_INFO "%s: MII detected; using 10mbs\n", - dev->name); + netdev_info(dev, "MII detected; using 10mbs\n"); SelectPage(0x42); if (dev->if_port == 2) /* enable 10Base2 */ PutByte(XIRCREG42_SWC1, 0xC0); @@ -1626,8 +1617,8 @@ do_reset(struct net_device *dev, int full) } if (full) - printk(KERN_INFO "%s: media %s, silicon revision %d\n", - dev->name, if_names[dev->if_port], local->silicon); + netdev_info(dev, "media %s, silicon revision %d\n", + if_names[dev->if_port], local->silicon); /* We should switch back to page 0 to avoid a bug in revision 0 * where regs with offset below 8 can't be read after an access * to the MAC registers */ @@ -1669,8 +1660,7 @@ init_mii(struct net_device *dev) control = mii_rd(ioaddr, 0, 0); if (control & 0x0400) { - printk(KERN_NOTICE "%s can't take PHY out of isolation mode\n", - dev->name); + netdev_notice(dev, "can't take PHY out of isolation mode\n"); local->probe_port = 0; return 0; } @@ -1688,8 +1678,7 @@ init_mii(struct net_device *dev) } if (!(status & 0x0020)) { - printk(KERN_INFO "%s: autonegotiation failed;" - " using 10mbs\n", dev->name); + netdev_info(dev, "autonegotiation failed; using 10mbs\n"); if (!local->new_mii) { control = 0x0000; mii_wr(ioaddr, 0, 0, control, 16); @@ -1699,8 +1688,7 @@ init_mii(struct net_device *dev) } } else { linkpartner = mii_rd(ioaddr, 0, 5); - printk(KERN_INFO "%s: MII link partner: %04x\n", - dev->name, linkpartner); + netdev_info(dev, "MII link partner: %04x\n", linkpartner); if (linkpartner & 0x0080) { dev->if_port = 4; } else diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index c200c2821730a0cdd3121f9cf6b6ee023db30f79..aee3bb0358bf9b49801cff98602699870cdec0c1 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -376,7 +376,7 @@ static void pcnet32_wio_reset(unsigned long addr) static int pcnet32_wio_check(unsigned long addr) { outw(88, addr + PCNET32_WIO_RAP); - return (inw(addr + PCNET32_WIO_RAP) == 88); + return inw(addr + PCNET32_WIO_RAP) == 88; } static struct pcnet32_access pcnet32_wio = { @@ -431,7 +431,7 @@ static void pcnet32_dwio_reset(unsigned long addr) static int pcnet32_dwio_check(unsigned long addr) { outl(88, addr + PCNET32_DWIO_RAP); - return ((inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88); + return (inl(addr + PCNET32_DWIO_RAP) & 0xffff) == 88; } static struct pcnet32_access pcnet32_dwio = { diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index eb799b36c86a391f90bb7f07074257084f4047ba..cb3d13e4e074097a4b89b9f0315f3d64b6ad68ff 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -58,7 +58,6 @@ config BROADCOM_PHY config BCM63XX_PHY tristate "Drivers for Broadcom 63xx SOCs internal PHY" - depends on BCM63XX ---help--- Currently supports the 6348 and 6358 PHYs. diff --git a/drivers/net/phy/bcm63xx.c b/drivers/net/phy/bcm63xx.c index c1281567983739bdd3a5bbecd0f7c1fbf03e6ba0..e16f98cb4f04733c962aa9219d407c3066a4ef64 100644 --- a/drivers/net/phy/bcm63xx.c +++ b/drivers/net/phy/bcm63xx.c @@ -131,7 +131,7 @@ static void __exit bcm63xx_phy_exit(void) module_init(bcm63xx_phy_init); module_exit(bcm63xx_phy_exit); -static struct mdio_device_id bcm63xx_tbl[] = { +static struct mdio_device_id __maybe_unused bcm63xx_tbl[] = { { 0x00406000, 0xfffffc00 }, { 0x002bdc00, 0xfffffc00 }, { } diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 4accd83d3dfe8152067408e4fc5dc7b454c4d95e..d84c4224dd1258ee878bb8cc2d5d60f892667790 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -930,7 +930,7 @@ static void __exit broadcom_exit(void) module_init(broadcom_init); module_exit(broadcom_exit); -static struct mdio_device_id broadcom_tbl[] = { +static struct mdio_device_id __maybe_unused broadcom_tbl[] = { { PHY_ID_BCM5411, 0xfffffff0 }, { PHY_ID_BCM5421, 0xfffffff0 }, { PHY_ID_BCM5461, 0xfffffff0 }, diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c index 1a325d63756b9cac7230080073fc02a2f38518ec..d28173161c215d2a02ff796a6f5ad172695d74d8 100644 --- a/drivers/net/phy/cicada.c +++ b/drivers/net/phy/cicada.c @@ -159,7 +159,7 @@ static void __exit cicada_exit(void) module_init(cicada_init); module_exit(cicada_exit); -static struct mdio_device_id cicada_tbl[] = { +static struct mdio_device_id __maybe_unused cicada_tbl[] = { { 0x000fc410, 0x000ffff0 }, { 0x000fc440, 0x000fffc0 }, { } diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c index 29c17617a2ec22ec216ab32129313b491ccf674b..2f774acdb55192f0df5086e6d2a51ef193bf3cfc 100644 --- a/drivers/net/phy/davicom.c +++ b/drivers/net/phy/davicom.c @@ -219,7 +219,7 @@ static void __exit davicom_exit(void) module_init(davicom_init); module_exit(davicom_exit); -static struct mdio_device_id davicom_tbl[] = { +static struct mdio_device_id __maybe_unused davicom_tbl[] = { { 0x0181b880, 0x0ffffff0 }, { 0x0181b8a0, 0x0ffffff0 }, { 0x00181b80, 0x0ffffff0 }, diff --git a/drivers/net/phy/et1011c.c b/drivers/net/phy/et1011c.c index 13995f52d6af1429c556312759ded6f010654be8..a8eb19ec3183b5606e300c27061701298aaa13bf 100644 --- a/drivers/net/phy/et1011c.c +++ b/drivers/net/phy/et1011c.c @@ -111,7 +111,7 @@ static void __exit et1011c_exit(void) module_init(et1011c_init); module_exit(et1011c_exit); -static struct mdio_device_id et1011c_tbl[] = { +static struct mdio_device_id __maybe_unused et1011c_tbl[] = { { 0x0282f014, 0xfffffff0 }, { } }; diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index 3f2583f18a39c3756c6296055a811cb1f1122f4e..c1d2d251fe8bfcef7114fd57b1018c70697006f5 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c @@ -134,7 +134,7 @@ static void __exit ip175c_exit(void) module_init(ip175c_init); module_exit(ip175c_exit); -static struct mdio_device_id icplus_tbl[] = { +static struct mdio_device_id __maybe_unused icplus_tbl[] = { { 0x02430d80, 0x0ffffff0 }, { } }; diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index 29c39ff85de56a0012ac8be5a50508aeab56e784..6f6e8b616a627d869bae3743a56b3d45f8d39868 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c @@ -223,7 +223,7 @@ static void __exit lxt_exit(void) module_init(lxt_init); module_exit(lxt_exit); -static struct mdio_device_id lxt_tbl[] = { +static struct mdio_device_id __maybe_unused lxt_tbl[] = { { 0x78100000, 0xfffffff0 }, { 0x001378e0, 0xfffffff0 }, { 0x00137a10, 0xfffffff0 }, diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 0101f2bdf400e7b28eca39d0c9b7a413e2f0d326..e2afdce0a43781a7dc6876e20eecbb9df8f38f93 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c @@ -196,20 +196,27 @@ static int m88e1121_config_aneg(struct phy_device *phydev) MII_88E1121_PHY_MSCR_PAGE); if (err < 0) return err; - mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & - MII_88E1121_PHY_MSCR_DELAY_MASK; - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) - mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | - MII_88E1121_PHY_MSCR_TX_DELAY); - else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) - mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; - else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) - mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; + if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) || + (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) || + (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) || + (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) { - err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); - if (err < 0) - return err; + mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) & + MII_88E1121_PHY_MSCR_DELAY_MASK; + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) + mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY | + MII_88E1121_PHY_MSCR_TX_DELAY); + else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) + mscr |= MII_88E1121_PHY_MSCR_RX_DELAY; + else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) + mscr |= MII_88E1121_PHY_MSCR_TX_DELAY; + + err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr); + if (err < 0) + return err; + } phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage); @@ -721,7 +728,7 @@ static void __exit marvell_exit(void) module_init(marvell_init); module_exit(marvell_exit); -static struct mdio_device_id marvell_tbl[] = { +static struct mdio_device_id __maybe_unused marvell_tbl[] = { { 0x01410c60, 0xfffffff0 }, { 0x01410c90, 0xfffffff0 }, { 0x01410cc0, 0xfffffff0 }, diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 8bb7db676a5cc13b0651a8970fd25a27d7a79d48..0fd1678bc5a928eac50ec9862567ed2019f5bb4b 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -231,7 +231,7 @@ MODULE_DESCRIPTION("Micrel PHY driver"); MODULE_AUTHOR("David J. Choi"); MODULE_LICENSE("GPL"); -static struct mdio_device_id micrel_tbl[] = { +static struct mdio_device_id __maybe_unused micrel_tbl[] = { { PHY_ID_KSZ9021, 0x000fff10 }, { PHY_ID_KS8001, 0x00fffff0 }, { PHY_ID_KS8737, 0x00fffff0 }, diff --git a/drivers/net/phy/national.c b/drivers/net/phy/national.c index a73ba0bcc0ce86f632bf8d7e5c5287e9d7e02062..0620ba963508e17096dab555ed79495749c68e70 100644 --- a/drivers/net/phy/national.c +++ b/drivers/net/phy/national.c @@ -151,7 +151,7 @@ MODULE_LICENSE("GPL"); module_init(ns_init); module_exit(ns_exit); -static struct mdio_device_id ns_tbl[] = { +static struct mdio_device_id __maybe_unused ns_tbl[] = { { DP83865_PHY_ID, 0xfffffff0 }, { } }; diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c index 6736b23f1b28a3828456fbfc80b9b88739050ecb..fe0d0a15d5e1498801b2a0d5415da1a5a1c1edeb 100644 --- a/drivers/net/phy/qsemi.c +++ b/drivers/net/phy/qsemi.c @@ -138,7 +138,7 @@ static void __exit qs6612_exit(void) module_init(qs6612_init); module_exit(qs6612_exit); -static struct mdio_device_id qs6612_tbl[] = { +static struct mdio_device_id __maybe_unused qs6612_tbl[] = { { 0x00181440, 0xfffffff0 }, { } }; diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index f567c0e1aaa1a0d745b8ca1f719b93a8d96c9577..a4eae750a4145084b0cf45e90b875f1eb2c019c3 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -79,7 +79,7 @@ static void __exit realtek_exit(void) module_init(realtek_init); module_exit(realtek_exit); -static struct mdio_device_id realtek_tbl[] = { +static struct mdio_device_id __maybe_unused realtek_tbl[] = { { 0x001cc912, 0x001fffff }, { } }; diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 78fa988256fce4d2bd691029ca8b4ababba2789a..342505c976d652095a2eac183e6df365a4de2475 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -254,7 +254,7 @@ MODULE_LICENSE("GPL"); module_init(smsc_init); module_exit(smsc_exit); -static struct mdio_device_id smsc_tbl[] = { +static struct mdio_device_id __maybe_unused smsc_tbl[] = { { 0x0007c0a0, 0xfffffff0 }, { 0x0007c0b0, 0xfffffff0 }, { 0x0007c0c0, 0xfffffff0 }, diff --git a/drivers/net/phy/ste10Xp.c b/drivers/net/phy/ste10Xp.c index 72290099e5e1f01e2784629ec54e01e9a037926e..187a2fa814f27325c3da0c10e6ae258f0ad7cffe 100644 --- a/drivers/net/phy/ste10Xp.c +++ b/drivers/net/phy/ste10Xp.c @@ -132,7 +132,7 @@ static void __exit ste10Xp_exit(void) module_init(ste10Xp_init); module_exit(ste10Xp_exit); -static struct mdio_device_id ste10Xp_tbl[] = { +static struct mdio_device_id __maybe_unused ste10Xp_tbl[] = { { STE101P_PHY_ID, 0xfffffff0 }, { STE100P_PHY_ID, 0xffffffff }, { } diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 45cce50a279992eee14fd6edf185fabb4fe1e94a..5d8f6e17bd55b1b7e2f3348a95224b4814540787 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -192,7 +192,7 @@ static void __exit vsc82xx_exit(void) module_init(vsc82xx_init); module_exit(vsc82xx_exit); -static struct mdio_device_id vitesse_tbl[] = { +static struct mdio_device_id __maybe_unused vitesse_tbl[] = { { PHY_ID_VSC8244, 0x000fffc0 }, { PHY_ID_VSC8221, 0x000ffff0 }, { } diff --git a/drivers/net/plip.c b/drivers/net/plip.c index ec0349e84a8a8cd093977a50d3f9aa0879b291e7..ca4df7f4cf21df0099c883a2484c482e202246b0 100644 --- a/drivers/net/plip.c +++ b/drivers/net/plip.c @@ -995,8 +995,10 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev) static void plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth) { - const struct in_device *in_dev = dev->ip_ptr; + const struct in_device *in_dev; + rcu_read_lock(); + in_dev = __in_dev_get_rcu(dev); if (in_dev) { /* Any address will do - we take the first */ const struct in_ifaddr *ifa = in_dev->ifa_list; @@ -1006,6 +1008,7 @@ plip_rewrite_address(const struct net_device *dev, struct ethhdr *eth) memcpy(eth->h_dest+2, &ifa->ifa_address, 4); } } + rcu_read_unlock(); } static int @@ -1088,7 +1091,8 @@ plip_open(struct net_device *dev) when the device address isn't identical to the address of a received frame, the kernel incorrectly drops it). */ - if ((in_dev=dev->ip_ptr) != NULL) { + in_dev=__in_dev_get_rtnl(dev); + if (in_dev) { /* Any address will do - we take the first. We already have the first two bytes filled with 0xfc, from plip_init_dev(). */ @@ -1279,7 +1283,6 @@ static void plip_attach (struct parport *port) if (!nl->pardev) { printk(KERN_ERR "%s: parport_register failed\n", name); goto err_free_dev; - return; } plip_init_netdev(dev); diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 4bddb2afdd158aafccca77fa300b6c2743577727..09cf56d0416a8c24c78780c7eb374fcebf01cffc 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1548,9 +1548,11 @@ ppp_channel_push(struct channel *pch) * Receive-side routines. */ -/* misuse a few fields of the skb for MP reconstruction */ -#define sequence priority -#define BEbits cb[0] +struct ppp_mp_skb_parm { + u32 sequence; + u8 BEbits; +}; +#define PPP_MP_CB(skb) ((struct ppp_mp_skb_parm *)((skb)->cb)) static inline void ppp_do_recv(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) @@ -1879,13 +1881,13 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) seq = (skb->data[3] << 16) | (skb->data[4] << 8)| skb->data[5]; mask = 0xffffff; } - skb->BEbits = skb->data[2]; + PPP_MP_CB(skb)->BEbits = skb->data[2]; skb_pull(skb, mphdrlen); /* pull off PPP and MP headers */ /* * Do protocol ID decompression on the first fragment of each packet. */ - if ((skb->BEbits & B) && (skb->data[0] & 1)) + if ((PPP_MP_CB(skb)->BEbits & B) && (skb->data[0] & 1)) *skb_push(skb, 1) = 0; /* @@ -1897,7 +1899,7 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) seq += mask + 1; else if ((int)(seq - ppp->minseq) > (int)(mask >> 1)) seq -= mask + 1; /* should never happen */ - skb->sequence = seq; + PPP_MP_CB(skb)->sequence = seq; pch->lastseq = seq; /* @@ -1933,8 +1935,8 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) before the start of the queue. */ if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) { struct sk_buff *mskb = skb_peek(&ppp->mrq); - if (seq_before(ppp->minseq, mskb->sequence)) - ppp->minseq = mskb->sequence; + if (seq_before(ppp->minseq, PPP_MP_CB(mskb)->sequence)) + ppp->minseq = PPP_MP_CB(mskb)->sequence; } /* Pull completed packets off the queue and receive them. */ @@ -1964,12 +1966,12 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb) { struct sk_buff *p; struct sk_buff_head *list = &ppp->mrq; - u32 seq = skb->sequence; + u32 seq = PPP_MP_CB(skb)->sequence; /* N.B. we don't need to lock the list lock because we have the ppp unit receive-side lock. */ skb_queue_walk(list, p) { - if (seq_before(seq, p->sequence)) + if (seq_before(seq, PPP_MP_CB(p)->sequence)) break; } __skb_queue_before(list, p, skb); @@ -1998,22 +2000,22 @@ ppp_mp_reconstruct(struct ppp *ppp) tail = NULL; for (p = head; p != (struct sk_buff *) list; p = next) { next = p->next; - if (seq_before(p->sequence, seq)) { + if (seq_before(PPP_MP_CB(p)->sequence, seq)) { /* this can't happen, anyway ignore the skb */ printk(KERN_ERR "ppp_mp_reconstruct bad seq %u < %u\n", - p->sequence, seq); + PPP_MP_CB(p)->sequence, seq); head = next; continue; } - if (p->sequence != seq) { + if (PPP_MP_CB(p)->sequence != seq) { /* Fragment `seq' is missing. If it is after minseq, it might arrive later, so stop here. */ if (seq_after(seq, minseq)) break; /* Fragment `seq' is lost, keep going. */ lost = 1; - seq = seq_before(minseq, p->sequence)? - minseq + 1: p->sequence; + seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? + minseq + 1: PPP_MP_CB(p)->sequence; next = p; continue; } @@ -2027,7 +2029,7 @@ ppp_mp_reconstruct(struct ppp *ppp) */ /* B bit set indicates this fragment starts a packet */ - if (p->BEbits & B) { + if (PPP_MP_CB(p)->BEbits & B) { head = p; lost = 0; len = 0; @@ -2036,7 +2038,8 @@ ppp_mp_reconstruct(struct ppp *ppp) len += p->len; /* Got a complete packet yet? */ - if (lost == 0 && (p->BEbits & E) && (head->BEbits & B)) { + if (lost == 0 && (PPP_MP_CB(p)->BEbits & E) && + (PPP_MP_CB(head)->BEbits & B)) { if (len > ppp->mrru + 2) { ++ppp->dev->stats.rx_length_errors; printk(KERN_DEBUG "PPP: reconstructed packet" @@ -2062,7 +2065,7 @@ ppp_mp_reconstruct(struct ppp *ppp) * and we haven't found a complete valid packet yet, * we can discard up to and including this fragment. */ - if (p->BEbits & E) + if (PPP_MP_CB(p)->BEbits & E) head = next; ++seq; @@ -2072,10 +2075,11 @@ ppp_mp_reconstruct(struct ppp *ppp) if (tail != NULL) { /* If we have discarded any fragments, signal a receive error. */ - if (head->sequence != ppp->nextseq) { + if (PPP_MP_CB(head)->sequence != ppp->nextseq) { if (ppp->debug & 1) printk(KERN_DEBUG " missed pkts %u..%u\n", - ppp->nextseq, head->sequence-1); + ppp->nextseq, + PPP_MP_CB(head)->sequence-1); ++ppp->dev->stats.rx_dropped; ppp_receive_error(ppp); } @@ -2084,7 +2088,7 @@ ppp_mp_reconstruct(struct ppp *ppp) /* copy to a single skb */ for (p = head; p != tail->next; p = p->next) skb_copy_bits(p, 0, skb_put(skb, p->len), p->len); - ppp->nextseq = tail->sequence + 1; + ppp->nextseq = PPP_MP_CB(tail)->sequence + 1; head = tail->next; } diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index c07de359dc074e7abd789826f25728ab065350b3..d72fb0519a2aa674a8757f5146b0df19655d9749 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -1124,7 +1124,7 @@ static const struct proto_ops pppoe_ops = { .ioctl = pppox_ioctl, }; -static struct pppox_proto pppoe_proto = { +static const struct pppox_proto pppoe_proto = { .create = pppoe_create, .ioctl = pppoe_ioctl, .owner = THIS_MODULE, diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c index d4191ef9cad14fed8d1cd6c0d284ddb7e51c8163..8c0d170dabcd5ab32685e6e4e0df52533d9f6de5 100644 --- a/drivers/net/pppox.c +++ b/drivers/net/pppox.c @@ -36,9 +36,9 @@ #include -static struct pppox_proto *pppox_protos[PX_MAX_PROTO + 1]; +static const struct pppox_proto *pppox_protos[PX_MAX_PROTO + 1]; -int register_pppox_proto(int proto_num, struct pppox_proto *pp) +int register_pppox_proto(int proto_num, const struct pppox_proto *pp) { if (proto_num < 0 || proto_num > PX_MAX_PROTO) return -EINVAL; diff --git a/drivers/net/pptp.c b/drivers/net/pptp.c new file mode 100644 index 0000000000000000000000000000000000000000..ccbc91326bfad5b04cdb279be57b74fd3c0d6247 --- /dev/null +++ b/drivers/net/pptp.c @@ -0,0 +1,726 @@ +/* + * Point-to-Point Tunneling Protocol for Linux + * + * Authors: Dmitry Kozlov + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define PPTP_DRIVER_VERSION "0.8.5" + +#define MAX_CALLID 65535 + +static DECLARE_BITMAP(callid_bitmap, MAX_CALLID + 1); +static struct pppox_sock **callid_sock; + +static DEFINE_SPINLOCK(chan_lock); + +static struct proto pptp_sk_proto __read_mostly; +static const struct ppp_channel_ops pptp_chan_ops; +static const struct proto_ops pptp_ops; + +#define PPP_LCP_ECHOREQ 0x09 +#define PPP_LCP_ECHOREP 0x0A +#define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) + +#define MISSING_WINDOW 20 +#define WRAPPED(curseq, lastseq)\ + ((((curseq) & 0xffffff00) == 0) &&\ + (((lastseq) & 0xffffff00) == 0xffffff00)) + +#define PPTP_GRE_PROTO 0x880B +#define PPTP_GRE_VER 0x1 + +#define PPTP_GRE_FLAG_C 0x80 +#define PPTP_GRE_FLAG_R 0x40 +#define PPTP_GRE_FLAG_K 0x20 +#define PPTP_GRE_FLAG_S 0x10 +#define PPTP_GRE_FLAG_A 0x80 + +#define PPTP_GRE_IS_C(f) ((f)&PPTP_GRE_FLAG_C) +#define PPTP_GRE_IS_R(f) ((f)&PPTP_GRE_FLAG_R) +#define PPTP_GRE_IS_K(f) ((f)&PPTP_GRE_FLAG_K) +#define PPTP_GRE_IS_S(f) ((f)&PPTP_GRE_FLAG_S) +#define PPTP_GRE_IS_A(f) ((f)&PPTP_GRE_FLAG_A) + +#define PPTP_HEADER_OVERHEAD (2+sizeof(struct pptp_gre_header)) +struct pptp_gre_header { + u8 flags; + u8 ver; + u16 protocol; + u16 payload_len; + u16 call_id; + u32 seq; + u32 ack; +} __packed; + +static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr) +{ + struct pppox_sock *sock; + struct pptp_opt *opt; + + rcu_read_lock(); + sock = rcu_dereference(callid_sock[call_id]); + if (sock) { + opt = &sock->proto.pptp; + if (opt->dst_addr.sin_addr.s_addr != s_addr) + sock = NULL; + else + sock_hold(sk_pppox(sock)); + } + rcu_read_unlock(); + + return sock; +} + +static int lookup_chan_dst(u16 call_id, __be32 d_addr) +{ + struct pppox_sock *sock; + struct pptp_opt *opt; + int i; + + rcu_read_lock(); + for (i = find_next_bit(callid_bitmap, MAX_CALLID, 1); i < MAX_CALLID; + i = find_next_bit(callid_bitmap, MAX_CALLID, i + 1)) { + sock = rcu_dereference(callid_sock[i]); + if (!sock) + continue; + opt = &sock->proto.pptp; + if (opt->dst_addr.call_id == call_id && + opt->dst_addr.sin_addr.s_addr == d_addr) + break; + } + rcu_read_unlock(); + + return i < MAX_CALLID; +} + +static int add_chan(struct pppox_sock *sock) +{ + static int call_id; + + spin_lock(&chan_lock); + if (!sock->proto.pptp.src_addr.call_id) { + call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, call_id + 1); + if (call_id == MAX_CALLID) { + call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, 1); + if (call_id == MAX_CALLID) + goto out_err; + } + sock->proto.pptp.src_addr.call_id = call_id; + } else if (test_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap)) + goto out_err; + + set_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap); + rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], sock); + spin_unlock(&chan_lock); + + return 0; + +out_err: + spin_unlock(&chan_lock); + return -1; +} + +static void del_chan(struct pppox_sock *sock) +{ + spin_lock(&chan_lock); + clear_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap); + rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], NULL); + spin_unlock(&chan_lock); + synchronize_rcu(); +} + +static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) +{ + struct sock *sk = (struct sock *) chan->private; + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + struct pptp_gre_header *hdr; + unsigned int header_len = sizeof(*hdr); + int err = 0; + int islcp; + int len; + unsigned char *data; + __u32 seq_recv; + + + struct rtable *rt; + struct net_device *tdev; + struct iphdr *iph; + int max_headroom; + + if (sk_pppox(po)->sk_state & PPPOX_DEAD) + goto tx_error; + + { + struct flowi fl = { .oif = 0, + .nl_u = { + .ip4_u = { + .daddr = opt->dst_addr.sin_addr.s_addr, + .saddr = opt->src_addr.sin_addr.s_addr, + .tos = RT_TOS(0) } }, + .proto = IPPROTO_GRE }; + err = ip_route_output_key(&init_net, &rt, &fl); + if (err) + goto tx_error; + } + tdev = rt->dst.dev; + + max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph) + sizeof(*hdr) + 2; + + if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { + struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); + if (!new_skb) { + ip_rt_put(rt); + goto tx_error; + } + if (skb->sk) + skb_set_owner_w(new_skb, skb->sk); + kfree_skb(skb); + skb = new_skb; + } + + data = skb->data; + islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7; + + /* compress protocol field */ + if ((opt->ppp_flags & SC_COMP_PROT) && data[0] == 0 && !islcp) + skb_pull(skb, 1); + + /* Put in the address/control bytes if necessary */ + if ((opt->ppp_flags & SC_COMP_AC) == 0 || islcp) { + data = skb_push(skb, 2); + data[0] = PPP_ALLSTATIONS; + data[1] = PPP_UI; + } + + len = skb->len; + + seq_recv = opt->seq_recv; + + if (opt->ack_sent == seq_recv) + header_len -= sizeof(hdr->ack); + + /* Push down and install GRE header */ + skb_push(skb, header_len); + hdr = (struct pptp_gre_header *)(skb->data); + + hdr->flags = PPTP_GRE_FLAG_K; + hdr->ver = PPTP_GRE_VER; + hdr->protocol = htons(PPTP_GRE_PROTO); + hdr->call_id = htons(opt->dst_addr.call_id); + + hdr->flags |= PPTP_GRE_FLAG_S; + hdr->seq = htonl(++opt->seq_sent); + if (opt->ack_sent != seq_recv) { + /* send ack with this message */ + hdr->ver |= PPTP_GRE_FLAG_A; + hdr->ack = htonl(seq_recv); + opt->ack_sent = seq_recv; + } + hdr->payload_len = htons(len); + + /* Push down and install the IP header. */ + + skb_reset_transport_header(skb); + skb_push(skb, sizeof(*iph)); + skb_reset_network_header(skb); + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); + + iph = ip_hdr(skb); + iph->version = 4; + iph->ihl = sizeof(struct iphdr) >> 2; + if (ip_dont_fragment(sk, &rt->dst)) + iph->frag_off = htons(IP_DF); + else + iph->frag_off = 0; + iph->protocol = IPPROTO_GRE; + iph->tos = 0; + iph->daddr = rt->rt_dst; + iph->saddr = rt->rt_src; + iph->ttl = dst_metric(&rt->dst, RTAX_HOPLIMIT); + iph->tot_len = htons(skb->len); + + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + + nf_reset(skb); + + skb->ip_summed = CHECKSUM_NONE; + ip_select_ident(iph, &rt->dst, NULL); + ip_send_check(iph); + + ip_local_out(skb); + +tx_error: + return 1; +} + +static int pptp_rcv_core(struct sock *sk, struct sk_buff *skb) +{ + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + int headersize, payload_len, seq; + __u8 *payload; + struct pptp_gre_header *header; + + if (!(sk->sk_state & PPPOX_CONNECTED)) { + if (sock_queue_rcv_skb(sk, skb)) + goto drop; + return NET_RX_SUCCESS; + } + + header = (struct pptp_gre_header *)(skb->data); + + /* test if acknowledgement present */ + if (PPTP_GRE_IS_A(header->ver)) { + __u32 ack = (PPTP_GRE_IS_S(header->flags)) ? + header->ack : header->seq; /* ack in different place if S = 0 */ + + ack = ntohl(ack); + + if (ack > opt->ack_recv) + opt->ack_recv = ack; + /* also handle sequence number wrap-around */ + if (WRAPPED(ack, opt->ack_recv)) + opt->ack_recv = ack; + } + + /* test if payload present */ + if (!PPTP_GRE_IS_S(header->flags)) + goto drop; + + headersize = sizeof(*header); + payload_len = ntohs(header->payload_len); + seq = ntohl(header->seq); + + /* no ack present? */ + if (!PPTP_GRE_IS_A(header->ver)) + headersize -= sizeof(header->ack); + /* check for incomplete packet (length smaller than expected) */ + if (skb->len - headersize < payload_len) + goto drop; + + payload = skb->data + headersize; + /* check for expected sequence number */ + if (seq < opt->seq_recv + 1 || WRAPPED(opt->seq_recv, seq)) { + if ((payload[0] == PPP_ALLSTATIONS) && (payload[1] == PPP_UI) && + (PPP_PROTOCOL(payload) == PPP_LCP) && + ((payload[4] == PPP_LCP_ECHOREQ) || (payload[4] == PPP_LCP_ECHOREP))) + goto allow_packet; + } else { + opt->seq_recv = seq; +allow_packet: + skb_pull(skb, headersize); + + if (payload[0] == PPP_ALLSTATIONS && payload[1] == PPP_UI) { + /* chop off address/control */ + if (skb->len < 3) + goto drop; + skb_pull(skb, 2); + } + + if ((*skb->data) & 1) { + /* protocol is compressed */ + skb_push(skb, 1)[0] = 0; + } + + skb->ip_summed = CHECKSUM_NONE; + skb_set_network_header(skb, skb->head-skb->data); + ppp_input(&po->chan, skb); + + return NET_RX_SUCCESS; + } +drop: + kfree_skb(skb); + return NET_RX_DROP; +} + +static int pptp_rcv(struct sk_buff *skb) +{ + struct pppox_sock *po; + struct pptp_gre_header *header; + struct iphdr *iph; + + if (skb->pkt_type != PACKET_HOST) + goto drop; + + if (!pskb_may_pull(skb, 12)) + goto drop; + + iph = ip_hdr(skb); + + header = (struct pptp_gre_header *)skb->data; + + if (ntohs(header->protocol) != PPTP_GRE_PROTO || /* PPTP-GRE protocol for PPTP */ + PPTP_GRE_IS_C(header->flags) || /* flag C should be clear */ + PPTP_GRE_IS_R(header->flags) || /* flag R should be clear */ + !PPTP_GRE_IS_K(header->flags) || /* flag K should be set */ + (header->flags&0xF) != 0) /* routing and recursion ctrl = 0 */ + /* if invalid, discard this packet */ + goto drop; + + po = lookup_chan(htons(header->call_id), iph->saddr); + if (po) { + skb_dst_drop(skb); + nf_reset(skb); + return sk_receive_skb(sk_pppox(po), skb, 0); + } +drop: + kfree_skb(skb); + return NET_RX_DROP; +} + +static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr, + int sockaddr_len) +{ + struct sock *sk = sock->sk; + struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr; + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + int error = 0; + + lock_sock(sk); + + opt->src_addr = sp->sa_addr.pptp; + if (add_chan(po)) { + release_sock(sk); + error = -EBUSY; + } + + release_sock(sk); + return error; +} + +static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, + int sockaddr_len, int flags) +{ + struct sock *sk = sock->sk; + struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr; + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + struct rtable *rt; + int error = 0; + + if (sp->sa_protocol != PX_PROTO_PPTP) + return -EINVAL; + + if (lookup_chan_dst(sp->sa_addr.pptp.call_id, sp->sa_addr.pptp.sin_addr.s_addr)) + return -EALREADY; + + lock_sock(sk); + /* Check for already bound sockets */ + if (sk->sk_state & PPPOX_CONNECTED) { + error = -EBUSY; + goto end; + } + + /* Check for already disconnected sockets, on attempts to disconnect */ + if (sk->sk_state & PPPOX_DEAD) { + error = -EALREADY; + goto end; + } + + if (!opt->src_addr.sin_addr.s_addr || !sp->sa_addr.pptp.sin_addr.s_addr) { + error = -EINVAL; + goto end; + } + + po->chan.private = sk; + po->chan.ops = &pptp_chan_ops; + + { + struct flowi fl = { + .nl_u = { + .ip4_u = { + .daddr = opt->dst_addr.sin_addr.s_addr, + .saddr = opt->src_addr.sin_addr.s_addr, + .tos = RT_CONN_FLAGS(sk) } }, + .proto = IPPROTO_GRE }; + security_sk_classify_flow(sk, &fl); + if (ip_route_output_key(&init_net, &rt, &fl)) { + error = -EHOSTUNREACH; + goto end; + } + sk_setup_caps(sk, &rt->dst); + } + po->chan.mtu = dst_mtu(&rt->dst); + if (!po->chan.mtu) + po->chan.mtu = PPP_MTU; + ip_rt_put(rt); + po->chan.mtu -= PPTP_HEADER_OVERHEAD; + + po->chan.hdrlen = 2 + sizeof(struct pptp_gre_header); + error = ppp_register_channel(&po->chan); + if (error) { + pr_err("PPTP: failed to register PPP channel (%d)\n", error); + goto end; + } + + opt->dst_addr = sp->sa_addr.pptp; + sk->sk_state = PPPOX_CONNECTED; + + end: + release_sock(sk); + return error; +} + +static int pptp_getname(struct socket *sock, struct sockaddr *uaddr, + int *usockaddr_len, int peer) +{ + int len = sizeof(struct sockaddr_pppox); + struct sockaddr_pppox sp; + + sp.sa_family = AF_PPPOX; + sp.sa_protocol = PX_PROTO_PPTP; + sp.sa_addr.pptp = pppox_sk(sock->sk)->proto.pptp.src_addr; + + memcpy(uaddr, &sp, len); + + *usockaddr_len = len; + + return 0; +} + +static int pptp_release(struct socket *sock) +{ + struct sock *sk = sock->sk; + struct pppox_sock *po; + struct pptp_opt *opt; + int error = 0; + + if (!sk) + return 0; + + lock_sock(sk); + + if (sock_flag(sk, SOCK_DEAD)) { + release_sock(sk); + return -EBADF; + } + + po = pppox_sk(sk); + opt = &po->proto.pptp; + del_chan(po); + + pppox_unbind_sock(sk); + sk->sk_state = PPPOX_DEAD; + + sock_orphan(sk); + sock->sk = NULL; + + release_sock(sk); + sock_put(sk); + + return error; +} + +static void pptp_sock_destruct(struct sock *sk) +{ + if (!(sk->sk_state & PPPOX_DEAD)) { + del_chan(pppox_sk(sk)); + pppox_unbind_sock(sk); + } + skb_queue_purge(&sk->sk_receive_queue); +} + +static int pptp_create(struct net *net, struct socket *sock) +{ + int error = -ENOMEM; + struct sock *sk; + struct pppox_sock *po; + struct pptp_opt *opt; + + sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pptp_sk_proto); + if (!sk) + goto out; + + sock_init_data(sock, sk); + + sock->state = SS_UNCONNECTED; + sock->ops = &pptp_ops; + + sk->sk_backlog_rcv = pptp_rcv_core; + sk->sk_state = PPPOX_NONE; + sk->sk_type = SOCK_STREAM; + sk->sk_family = PF_PPPOX; + sk->sk_protocol = PX_PROTO_PPTP; + sk->sk_destruct = pptp_sock_destruct; + + po = pppox_sk(sk); + opt = &po->proto.pptp; + + opt->seq_sent = 0; opt->seq_recv = 0; + opt->ack_recv = 0; opt->ack_sent = 0; + + error = 0; +out: + return error; +} + +static int pptp_ppp_ioctl(struct ppp_channel *chan, unsigned int cmd, + unsigned long arg) +{ + struct sock *sk = (struct sock *) chan->private; + struct pppox_sock *po = pppox_sk(sk); + struct pptp_opt *opt = &po->proto.pptp; + void __user *argp = (void __user *)arg; + int __user *p = argp; + int err, val; + + err = -EFAULT; + switch (cmd) { + case PPPIOCGFLAGS: + val = opt->ppp_flags; + if (put_user(val, p)) + break; + err = 0; + break; + case PPPIOCSFLAGS: + if (get_user(val, p)) + break; + opt->ppp_flags = val & ~SC_RCV_BITS; + err = 0; + break; + default: + err = -ENOTTY; + } + + return err; +} + +static const struct ppp_channel_ops pptp_chan_ops = { + .start_xmit = pptp_xmit, + .ioctl = pptp_ppp_ioctl, +}; + +static struct proto pptp_sk_proto __read_mostly = { + .name = "PPTP", + .owner = THIS_MODULE, + .obj_size = sizeof(struct pppox_sock), +}; + +static const struct proto_ops pptp_ops = { + .family = AF_PPPOX, + .owner = THIS_MODULE, + .release = pptp_release, + .bind = pptp_bind, + .connect = pptp_connect, + .socketpair = sock_no_socketpair, + .accept = sock_no_accept, + .getname = pptp_getname, + .poll = sock_no_poll, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .setsockopt = sock_no_setsockopt, + .getsockopt = sock_no_getsockopt, + .sendmsg = sock_no_sendmsg, + .recvmsg = sock_no_recvmsg, + .mmap = sock_no_mmap, + .ioctl = pppox_ioctl, +}; + +static const struct pppox_proto pppox_pptp_proto = { + .create = pptp_create, + .owner = THIS_MODULE, +}; + +static const struct gre_protocol gre_pptp_protocol = { + .handler = pptp_rcv, +}; + +static int __init pptp_init_module(void) +{ + int err = 0; + pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n"); + + callid_sock = __vmalloc((MAX_CALLID + 1) * sizeof(void *), + GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); + if (!callid_sock) { + pr_err("PPTP: cann't allocate memory\n"); + return -ENOMEM; + } + + err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP); + if (err) { + pr_err("PPTP: can't add gre protocol\n"); + goto out_mem_free; + } + + err = proto_register(&pptp_sk_proto, 0); + if (err) { + pr_err("PPTP: can't register sk_proto\n"); + goto out_gre_del_protocol; + } + + err = register_pppox_proto(PX_PROTO_PPTP, &pppox_pptp_proto); + if (err) { + pr_err("PPTP: can't register pppox_proto\n"); + goto out_unregister_sk_proto; + } + + return 0; + +out_unregister_sk_proto: + proto_unregister(&pptp_sk_proto); +out_gre_del_protocol: + gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP); +out_mem_free: + vfree(callid_sock); + + return err; +} + +static void __exit pptp_exit_module(void) +{ + unregister_pppox_proto(PX_PROTO_PPTP); + proto_unregister(&pptp_sk_proto); + gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP); + vfree(callid_sock); +} + +module_init(pptp_init_module); +module_exit(pptp_exit_module); + +MODULE_DESCRIPTION("Point-to-Point Tunneling Protocol"); +MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c index 87d6b8f3630470cce8219a4738352377e9d6cac6..5526ab4895e64163c7edb950765823b67b7b2cf4 100644 --- a/drivers/net/ps3_gelic_net.c +++ b/drivers/net/ps3_gelic_net.c @@ -956,9 +956,9 @@ static void gelic_net_pass_skb_up(struct gelic_descr *descr, (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* update netdevice statistics */ netdev->stats.rx_packets++; diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index 43b8d7797f0aa9695a3c78ddc48a68db5a2df770..4a624a29393f832498e3083befd44d5fe67785a5 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c @@ -85,12 +85,12 @@ static const int bitrate_list[] = { */ static inline int wpa2_capable(void) { - return (0 <= ps3_compare_firmware_version(2, 0, 0)); + return 0 <= ps3_compare_firmware_version(2, 0, 0); } static inline int precise_ie(void) { - return (0 <= ps3_compare_firmware_version(2, 2, 0)); + return 0 <= ps3_compare_firmware_version(2, 2, 0); } /* * post_eurus_cmd helpers @@ -506,7 +506,7 @@ static size_t gelic_wl_synthesize_ie(u8 *buf, start[1] = (buf - start - 2); pr_debug("%s: ->\n", __func__); - return (buf - start); + return buf - start; } struct ie_item { diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c index 85eddda276bdf350f17660fd2361b86e059b9001..18c0297743f122f488cc01a935adcb720ec9a32a 100644 --- a/drivers/net/pxa168_eth.c +++ b/drivers/net/pxa168_eth.c @@ -4,6 +4,7 @@ * * Copyright (C) 2010 Marvell International Ltd. * Sachin Sanap + * Zhangfei Gao * Philip Rakity * Mark Brown * @@ -42,8 +43,6 @@ #include #include #include -#include -#include #include #include @@ -850,7 +849,6 @@ static int rxq_process(struct net_device *dev, int budget) skb->protocol = eth_type_trans(skb, dev); netif_receive_skb(skb); } - dev->last_rx = jiffies; } /* Fill RX ring with skb's */ rxq_refill(dev); diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c index 6168a130f33fc1a18548427a73918d572db19107..7496ed2c34aba61aa06f616774cd2b139c578342 100644 --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -2029,7 +2029,7 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, dma_unmap_len(lrg_buf_cb2, maplen), PCI_DMA_FROMDEVICE); prefetch(skb->data); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, qdev->ndev); netif_receive_skb(skb); @@ -2076,7 +2076,7 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, PCI_DMA_FROMDEVICE); prefetch(skb2->data); - skb2->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb2); if (qdev->device_id == QL3022_DEVICE_ID) { /* * Copy the ethhdr from first buffer to second. This diff --git a/drivers/net/qlcnic/qlcnic.h b/drivers/net/qlcnic/qlcnic.h index 970389331bbc4cb5c91da180fd04d282db872ac5..26c37d3a5868ce2bf7e73ba98da5456006c02c53 100644 --- a/drivers/net/qlcnic/qlcnic.h +++ b/drivers/net/qlcnic/qlcnic.h @@ -51,9 +51,11 @@ #define _QLCNIC_LINUX_MAJOR 5 #define _QLCNIC_LINUX_MINOR 0 -#define _QLCNIC_LINUX_SUBVERSION 7 -#define QLCNIC_LINUX_VERSIONID "5.0.7" +#define _QLCNIC_LINUX_SUBVERSION 11 +#define QLCNIC_LINUX_VERSIONID "5.0.11" #define QLCNIC_DRV_IDC_VER 0x01 +#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ + (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) #define QLCNIC_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) #define _major(v) (((v) >> 24) & 0xff) @@ -92,11 +94,12 @@ #define FIRST_PAGE_GROUP_START 0 #define FIRST_PAGE_GROUP_END 0x100000 -#define P3_MAX_MTU (9600) +#define P3P_MAX_MTU (9600) +#define P3P_MIN_MTU (68) #define QLCNIC_MAX_ETHERHDR 32 /* This contains some padding */ -#define QLCNIC_P3_RX_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + ETH_DATA_LEN) -#define QLCNIC_P3_RX_JUMBO_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + P3_MAX_MTU) +#define QLCNIC_P3P_RX_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + ETH_DATA_LEN) +#define QLCNIC_P3P_RX_JUMBO_BUF_MAX_LEN (QLCNIC_MAX_ETHERHDR + P3P_MAX_MTU) #define QLCNIC_CT_DEFAULT_RX_BUF_LEN 2048 #define QLCNIC_LRO_BUFFER_EXTRA 2048 @@ -148,6 +151,7 @@ #define DEFAULT_RCV_DESCRIPTORS_1G 2048 #define DEFAULT_RCV_DESCRIPTORS_10G 4096 +#define MAX_RDS_RINGS 2 #define get_next_index(index, length) \ (((index) + 1) & ((length) - 1)) @@ -172,7 +176,7 @@ ((_desc)->port_ctxid = ((_port) & 0xf) | (((_port) << 4) & 0xf0)) #define qlcnic_set_tx_flags_opcode(_desc, _flags, _opcode) \ - ((_desc)->flags_opcode = \ + ((_desc)->flags_opcode |= \ cpu_to_le16(((_flags) & 0x7f) | (((_opcode) & 0x3f) << 7))) #define qlcnic_set_tx_frags_len(_desc, _frags, _len) \ @@ -221,7 +225,8 @@ struct rcv_desc { #define QLCNIC_LRO_DESC 0x12 /* for status field in status_desc */ -#define STATUS_CKSUM_OK (2) +#define STATUS_CKSUM_LOOP 0 +#define STATUS_CKSUM_OK 2 /* owner bits of status_desc */ #define STATUS_OWNER_HOST (0x1ULL << 56) @@ -302,20 +307,20 @@ struct uni_data_desc{ /* Magic number to let user know flash is programmed */ #define QLCNIC_BDINFO_MAGIC 0x12345678 -#define QLCNIC_BRDTYPE_P3_REF_QG 0x0021 -#define QLCNIC_BRDTYPE_P3_HMEZ 0x0022 -#define QLCNIC_BRDTYPE_P3_10G_CX4_LP 0x0023 -#define QLCNIC_BRDTYPE_P3_4_GB 0x0024 -#define QLCNIC_BRDTYPE_P3_IMEZ 0x0025 -#define QLCNIC_BRDTYPE_P3_10G_SFP_PLUS 0x0026 -#define QLCNIC_BRDTYPE_P3_10000_BASE_T 0x0027 -#define QLCNIC_BRDTYPE_P3_XG_LOM 0x0028 -#define QLCNIC_BRDTYPE_P3_4_GB_MM 0x0029 -#define QLCNIC_BRDTYPE_P3_10G_SFP_CT 0x002a -#define QLCNIC_BRDTYPE_P3_10G_SFP_QT 0x002b -#define QLCNIC_BRDTYPE_P3_10G_CX4 0x0031 -#define QLCNIC_BRDTYPE_P3_10G_XFP 0x0032 -#define QLCNIC_BRDTYPE_P3_10G_TP 0x0080 +#define QLCNIC_BRDTYPE_P3P_REF_QG 0x0021 +#define QLCNIC_BRDTYPE_P3P_HMEZ 0x0022 +#define QLCNIC_BRDTYPE_P3P_10G_CX4_LP 0x0023 +#define QLCNIC_BRDTYPE_P3P_4_GB 0x0024 +#define QLCNIC_BRDTYPE_P3P_IMEZ 0x0025 +#define QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS 0x0026 +#define QLCNIC_BRDTYPE_P3P_10000_BASE_T 0x0027 +#define QLCNIC_BRDTYPE_P3P_XG_LOM 0x0028 +#define QLCNIC_BRDTYPE_P3P_4_GB_MM 0x0029 +#define QLCNIC_BRDTYPE_P3P_10G_SFP_CT 0x002a +#define QLCNIC_BRDTYPE_P3P_10G_SFP_QT 0x002b +#define QLCNIC_BRDTYPE_P3P_10G_CX4 0x0031 +#define QLCNIC_BRDTYPE_P3P_10G_XFP 0x0032 +#define QLCNIC_BRDTYPE_P3P_10G_TP 0x0080 #define QLCNIC_MSIX_TABLE_OFFSET 0x44 @@ -555,6 +560,8 @@ struct qlcnic_recv_context { #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS 0x00000026 #define QLCNIC_CDRP_CMD_SET_PORTMIRRORING 0x00000027 #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH 0x00000028 +#define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG 0x00000029 +#define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS 0x0000002a #define QLCNIC_RCODE_SUCCESS 0 #define QLCNIC_RCODE_TIMEOUT 17 @@ -712,11 +719,13 @@ struct qlcnic_cardrsp_tx_ctx { /* MAC */ -#define MC_COUNT_P3 38 +#define MC_COUNT_P3P 38 #define QLCNIC_MAC_NOOP 0 #define QLCNIC_MAC_ADD 1 #define QLCNIC_MAC_DEL 2 +#define QLCNIC_MAC_VLAN_ADD 3 +#define QLCNIC_MAC_VLAN_DEL 4 struct qlcnic_mac_list_s { struct list_head list; @@ -890,12 +899,28 @@ struct qlcnic_mac_req { u8 mac_addr[6]; }; +struct qlcnic_vlan_req { + __le16 vlan_id; + __le16 rsvd[3]; +}; + +struct qlcnic_ipaddr { + __be32 ipv4; + __be32 ipv6[4]; +}; + #define QLCNIC_MSI_ENABLED 0x02 #define QLCNIC_MSIX_ENABLED 0x04 #define QLCNIC_LRO_ENABLED 0x08 +#define QLCNIC_LRO_DISABLED 0x00 #define QLCNIC_BRIDGE_ENABLED 0X10 #define QLCNIC_DIAG_ENABLED 0x20 #define QLCNIC_ESWITCH_ENABLED 0x40 +#define QLCNIC_ADAPTER_INITIALIZED 0x80 +#define QLCNIC_TAGGING_ENABLED 0x100 +#define QLCNIC_MACSPOOF 0x200 +#define QLCNIC_MAC_OVERRIDE_DISABLED 0x400 +#define QLCNIC_PROMISC_DISABLED 0x800 #define QLCNIC_IS_MSI_FAMILY(adapter) \ ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) @@ -916,6 +941,22 @@ struct qlcnic_mac_req { #define QLCNIC_INTERRUPT_TEST 1 #define QLCNIC_LOOPBACK_TEST 2 +#define QLCNIC_FILTER_AGE 80 +#define QLCNIC_LB_MAX_FILTERS 64 + +struct qlcnic_filter { + struct hlist_node fnode; + u8 faddr[ETH_ALEN]; + __le16 vlan_id; + unsigned long ftime; +}; + +struct qlcnic_filter_hash { + struct hlist_head *fhead; + u8 fnum; + u8 fmax; +}; + struct qlcnic_adapter { struct qlcnic_hardware_context ahw; @@ -924,6 +965,7 @@ struct qlcnic_adapter { struct list_head mac_list; spinlock_t tx_clean_lock; + spinlock_t mac_learn_lock; u16 num_txd; u16 num_rxd; @@ -931,7 +973,6 @@ struct qlcnic_adapter { u8 max_rds_rings; u8 max_sds_rings; - u8 driver_mismatch; u8 msix_supported; u8 rx_csum; u8 portnum; @@ -961,6 +1002,7 @@ struct qlcnic_adapter { u16 max_tx_ques; u16 max_rx_ques; u16 max_mtu; + u16 pvid; u32 fw_hal_version; u32 capabilities; @@ -969,7 +1011,7 @@ struct qlcnic_adapter { u32 temp; u32 int_vec_bit; - u32 heartbit; + u32 heartbeat; u8 max_mac_filters; u8 dev_state; @@ -983,6 +1025,7 @@ struct qlcnic_adapter { u64 dev_rst_time; + struct vlan_group *vlgrp; struct qlcnic_npar_info *npars; struct qlcnic_eswitch *eswitch; struct qlcnic_nic_template *nic_ops; @@ -1003,6 +1046,8 @@ struct qlcnic_adapter { struct qlcnic_nic_intr_coalesce coal; + struct qlcnic_filter_hash fhash; + unsigned long state; __le32 file_prd_off; /*File fw product offset*/ u32 fw_version; @@ -1042,7 +1087,7 @@ struct qlcnic_pci_info { }; struct qlcnic_npar_info { - u16 vlan_id; + u16 pvid; u16 min_bw; u16 max_bw; u8 phy_port; @@ -1050,11 +1095,13 @@ struct qlcnic_npar_info { u8 active; u8 enable_pm; u8 dest_npar; - u8 host_vlan_tag; - u8 promisc_mode; u8 discard_tagged; - u8 mac_learning; + u8 mac_override; + u8 mac_anti_spoof; + u8 promisc_mode; + u8 offload_flags; }; + struct qlcnic_eswitch { u8 port; u8 active_vports; @@ -1086,7 +1133,6 @@ struct qlcnic_eswitch { #define IS_VALID_BW(bw) (bw >= MIN_BW && bw <= MAX_BW) #define IS_VALID_TX_QUEUES(que) (que > 0 && que <= MAX_TX_QUEUES) #define IS_VALID_RX_QUEUES(que) (que > 0 && que <= MAX_RX_QUEUES) -#define IS_VALID_MODE(mode) (mode == 0 || mode == 1) struct qlcnic_pci_func_cfg { u16 func_type; @@ -1118,12 +1164,53 @@ struct qlcnic_pm_func_cfg { struct qlcnic_esw_func_cfg { u16 vlan_id; + u8 op_mode; + u8 op_type; u8 pci_func; u8 host_vlan_tag; u8 promisc_mode; u8 discard_tagged; - u8 mac_learning; - u8 reserved; + u8 mac_override; + u8 mac_anti_spoof; + u8 offload_flags; + u8 reserved[5]; +}; + +#define QLCNIC_STATS_VERSION 1 +#define QLCNIC_STATS_PORT 1 +#define QLCNIC_STATS_ESWITCH 2 +#define QLCNIC_QUERY_RX_COUNTER 0 +#define QLCNIC_QUERY_TX_COUNTER 1 +#define QLCNIC_ESW_STATS_NOT_AVAIL 0xffffffffffffffffULL + +#define QLCNIC_ADD_ESW_STATS(VAL1, VAL2)\ +do { \ + if (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) && \ + ((VAL2) != QLCNIC_ESW_STATS_NOT_AVAIL)) \ + (VAL1) = (VAL2); \ + else if (((VAL1) != QLCNIC_ESW_STATS_NOT_AVAIL) && \ + ((VAL2) != QLCNIC_ESW_STATS_NOT_AVAIL)) \ + (VAL1) += (VAL2); \ +} while (0) + +struct __qlcnic_esw_statistics { + __le16 context_id; + __le16 version; + __le16 size; + __le16 unused; + __le64 unicast_frames; + __le64 multicast_frames; + __le64 broadcast_frames; + __le64 dropped_frames; + __le64 errors; + __le64 local_frames; + __le64 numbytes; + __le64 rsvd[3]; +}; + +struct qlcnic_esw_statistics { + struct __qlcnic_esw_statistics rx; + struct __qlcnic_esw_statistics tx; }; int qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val); @@ -1171,6 +1258,8 @@ void qlcnic_pcie_sem_unlock(struct qlcnic_adapter *, int); int qlcnic_get_board_info(struct qlcnic_adapter *adapter); int qlcnic_wol_supported(struct qlcnic_adapter *adapter); int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate); +void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter); +void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter); /* Functions from qlcnic_init.c */ int qlcnic_load_firmware(struct qlcnic_adapter *adapter); @@ -1199,7 +1288,7 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter); void qlcnic_release_rx_buffers(struct qlcnic_adapter *adapter); void qlcnic_release_tx_buffers(struct qlcnic_adapter *adapter); -int qlcnic_init_firmware(struct qlcnic_adapter *adapter); +int qlcnic_check_fw_status(struct qlcnic_adapter *adapter); void qlcnic_watchdog_task(struct work_struct *work); void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid, struct qlcnic_host_rds_ring *rds_ring); @@ -1209,7 +1298,7 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter); int qlcnic_nic_set_promisc(struct qlcnic_adapter *adapter, u32); int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter); int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable); -int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd); +int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd); int qlcnic_linkevent_request(struct qlcnic_adapter *adapter, int enable); void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup); @@ -1220,12 +1309,13 @@ int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable); int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter); void qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter, struct qlcnic_host_tx_ring *tx_ring); -int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac); void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter); int qlcnic_set_ilb_mode(struct qlcnic_adapter *adapter); void qlcnic_fetch_mac(struct qlcnic_adapter *, u32, u32, u8, u8 *); /* Functions from qlcnic_main.c */ +int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter); +void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter); int qlcnic_reset_context(struct qlcnic_adapter *); u32 qlcnic_issue_cmd(struct qlcnic_adapter *adapter, u32 pci_fn, u32 version, u32 arg1, u32 arg2, u32 arg3, u32 cmd); @@ -1236,22 +1326,22 @@ netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); void qlcnic_process_rcv_ring_diag(struct qlcnic_host_sds_ring *sds_ring); /* Management functions */ -int qlcnic_set_mac_address(struct qlcnic_adapter *, u8*); int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*); int qlcnic_get_nic_info(struct qlcnic_adapter *, struct qlcnic_info *, u8); int qlcnic_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); int qlcnic_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info*); -int qlcnic_reset_partition(struct qlcnic_adapter *, u8); /* eSwitch management functions */ -int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *, u8, - struct qlcnic_eswitch *); -int qlcnic_get_eswitch_status(struct qlcnic_adapter *, u8, - struct qlcnic_eswitch *); -int qlcnic_toggle_eswitch(struct qlcnic_adapter *, u8, u8); -int qlcnic_config_switch_port(struct qlcnic_adapter *, u8, int, u8, u8, - u8, u8, u16); +int qlcnic_config_switch_port(struct qlcnic_adapter *, + struct qlcnic_esw_func_cfg *); +int qlcnic_get_eswitch_port_config(struct qlcnic_adapter *, + struct qlcnic_esw_func_cfg *); int qlcnic_config_port_mirroring(struct qlcnic_adapter *, u8, u8, u8); +int qlcnic_get_port_stats(struct qlcnic_adapter *, const u8, const u8, + struct __qlcnic_esw_statistics *); +int qlcnic_get_eswitch_stats(struct qlcnic_adapter *, const u8, u8, + struct __qlcnic_esw_statistics *); +int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, u8, u8, u8); extern int qlcnic_config_tso; /* @@ -1280,6 +1370,8 @@ static const struct qlcnic_brdinfo qlcnic_boards[] = { "3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"}, {0x1077, 0x8020, 0x1077, 0x20f, "3200 Series Single Port 10Gb Intelligent Ethernet Adapter"}, + {0x1077, 0x8020, 0x103c, 0x3733, + "NC523SFP 10Gb 2-port Server Adapter"}, {0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"}, }; @@ -1298,7 +1390,6 @@ static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring) extern const struct ethtool_ops qlcnic_ethtool_ops; struct qlcnic_nic_template { - int (*get_mac_addr) (struct qlcnic_adapter *, u8*); int (*config_bridged_mode) (struct qlcnic_adapter *, u32); int (*config_led) (struct qlcnic_adapter *, u32, u32); int (*start_firmware) (struct qlcnic_adapter *); diff --git a/drivers/net/qlcnic/qlcnic_ctx.c b/drivers/net/qlcnic/qlcnic_ctx.c index cc5d861d9a128bfc932da00a6bb0917a7ac26931..1cdc05dade6b0b5d31d9b0aa27fab5a7fffed894 100644 --- a/drivers/net/qlcnic/qlcnic_ctx.c +++ b/drivers/net/qlcnic/qlcnic_ctx.c @@ -556,32 +556,6 @@ void qlcnic_free_hw_resources(struct qlcnic_adapter *adapter) } } -/* Set MAC address of a NIC partition */ -int qlcnic_set_mac_address(struct qlcnic_adapter *adapter, u8* mac) -{ - int err = 0; - u32 arg1, arg2, arg3; - - arg1 = adapter->ahw.pci_func | BIT_9; - arg2 = mac[0] | (mac[1] << 8) | (mac[2] << 16) | (mac[3] << 24); - arg3 = mac[4] | (mac[5] << 16); - - err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, - adapter->fw_hal_version, - arg1, - arg2, - arg3, - QLCNIC_CDRP_CMD_MAC_ADDRESS); - - if (err != QLCNIC_RCODE_SUCCESS) { - dev_err(&adapter->pdev->dev, - "Failed to set mac address%d\n", err); - err = -EIO; - } - - return err; -} /* Get MAC address of a NIC partition */ int qlcnic_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) @@ -742,15 +716,15 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, if (err == QLCNIC_RCODE_SUCCESS) { for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++, npar++, pci_info++) { - pci_info->id = le32_to_cpu(npar->id); - pci_info->active = le32_to_cpu(npar->active); - pci_info->type = le32_to_cpu(npar->type); + pci_info->id = le16_to_cpu(npar->id); + pci_info->active = le16_to_cpu(npar->active); + pci_info->type = le16_to_cpu(npar->type); pci_info->default_port = - le32_to_cpu(npar->default_port); + le16_to_cpu(npar->default_port); pci_info->tx_min_bw = - le32_to_cpu(npar->tx_min_bw); + le16_to_cpu(npar->tx_min_bw); pci_info->tx_max_bw = - le32_to_cpu(npar->tx_max_bw); + le16_to_cpu(npar->tx_max_bw); memcpy(pci_info->mac, npar->mac, ETH_ALEN); } } else { @@ -764,222 +738,319 @@ int qlcnic_get_pci_info(struct qlcnic_adapter *adapter, return err; } -/* Reset a NIC partition */ - -int qlcnic_reset_partition(struct qlcnic_adapter *adapter, u8 func_no) +/* Configure eSwitch for port mirroring */ +int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, + u8 enable_mirroring, u8 pci_func) { int err = -EIO; + u32 arg1; - if (adapter->op_mode != QLCNIC_MGMT_FUNC) + if (adapter->op_mode != QLCNIC_MGMT_FUNC || + !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) return err; + arg1 = id | (enable_mirroring ? BIT_4 : 0); + arg1 |= pci_func << 8; + err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, - func_no, + arg1, 0, 0, - QLCNIC_CDRP_CMD_RESET_NPAR); + QLCNIC_CDRP_CMD_SET_PORTMIRRORING); if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, - "Failed to issue reset partition%d\n", err); - err = -EIO; + "Failed to configure port mirroring%d on eswitch:%d\n", + pci_func, id); + } else { + dev_info(&adapter->pdev->dev, + "Configured eSwitch %d for port mirroring:%d\n", + id, pci_func); } return err; } -/* Get eSwitch Capabilities */ -int qlcnic_get_eswitch_capabilities(struct qlcnic_adapter *adapter, u8 port, - struct qlcnic_eswitch *eswitch) -{ - int err = -EIO; - u32 arg1, arg2; +int qlcnic_get_port_stats(struct qlcnic_adapter *adapter, const u8 func, + const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { - if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) - return err; + size_t stats_size = sizeof(struct __qlcnic_esw_statistics); + struct __qlcnic_esw_statistics *stats; + dma_addr_t stats_dma_t; + void *stats_addr; + u32 arg1; + int err; - err = qlcnic_issue_cmd(adapter, - adapter->ahw.pci_func, - adapter->fw_hal_version, - port, - 0, - 0, - QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY); + if (esw_stats == NULL) + return -ENOMEM; - if (err == QLCNIC_RCODE_SUCCESS) { - arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); - arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); - - eswitch->port = arg1 & 0xf; - eswitch->active_vports = LSB(arg2); - eswitch->max_ucast_filters = MSB(arg2); - eswitch->max_active_vlans = LSB(MSW(arg2)); - if (arg1 & BIT_6) - eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; - if (arg1 & BIT_7) - eswitch->flags |= QLCNIC_SWITCH_PROMISC_MODE; - if (arg1 & BIT_8) - eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING; - } else { + if (adapter->op_mode != QLCNIC_MGMT_FUNC && + func != adapter->ahw.pci_func) { dev_err(&adapter->pdev->dev, - "Failed to get eswitch capabilities%d\n", err); + "Not privilege to query stats for func=%d", func); + return -EIO; } - return err; -} - -/* Get current status of eswitch */ -int qlcnic_get_eswitch_status(struct qlcnic_adapter *adapter, u8 port, - struct qlcnic_eswitch *eswitch) -{ - int err = -EIO; - u32 arg1, arg2; + stats_addr = pci_alloc_consistent(adapter->pdev, stats_size, + &stats_dma_t); + if (!stats_addr) { + dev_err(&adapter->pdev->dev, "Unable to allocate memory\n"); + return -ENOMEM; + } + memset(stats_addr, 0, stats_size); - if (adapter->op_mode != QLCNIC_MGMT_FUNC) - return err; + arg1 = func | QLCNIC_STATS_VERSION << 8 | QLCNIC_STATS_PORT << 12; + arg1 |= rx_tx << 15 | stats_size << 16; err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, - port, - 0, - 0, - QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS); - - if (err == QLCNIC_RCODE_SUCCESS) { - arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); - arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); - - eswitch->port = arg1 & 0xf; - eswitch->active_vports = LSB(arg2); - eswitch->active_ucast_filters = MSB(arg2); - eswitch->active_vlans = LSB(MSW(arg2)); - if (arg1 & BIT_6) - eswitch->flags |= QLCNIC_SWITCH_VLAN_FILTERING; - if (arg1 & BIT_8) - eswitch->flags |= QLCNIC_SWITCH_PORT_MIRRORING; - - } else { - dev_err(&adapter->pdev->dev, - "Failed to get eswitch status%d\n", err); + arg1, + MSD(stats_dma_t), + LSD(stats_dma_t), + QLCNIC_CDRP_CMD_GET_ESWITCH_STATS); + + if (!err) { + stats = (struct __qlcnic_esw_statistics *)stats_addr; + esw_stats->context_id = le16_to_cpu(stats->context_id); + esw_stats->version = le16_to_cpu(stats->version); + esw_stats->size = le16_to_cpu(stats->size); + esw_stats->multicast_frames = + le64_to_cpu(stats->multicast_frames); + esw_stats->broadcast_frames = + le64_to_cpu(stats->broadcast_frames); + esw_stats->unicast_frames = le64_to_cpu(stats->unicast_frames); + esw_stats->dropped_frames = le64_to_cpu(stats->dropped_frames); + esw_stats->local_frames = le64_to_cpu(stats->local_frames); + esw_stats->errors = le64_to_cpu(stats->errors); + esw_stats->numbytes = le64_to_cpu(stats->numbytes); } + pci_free_consistent(adapter->pdev, stats_size, stats_addr, + stats_dma_t); return err; } -/* Enable/Disable eSwitch */ -int qlcnic_toggle_eswitch(struct qlcnic_adapter *adapter, u8 id, u8 enable) +int qlcnic_get_eswitch_stats(struct qlcnic_adapter *adapter, const u8 eswitch, + const u8 rx_tx, struct __qlcnic_esw_statistics *esw_stats) { + + struct __qlcnic_esw_statistics port_stats; + u8 i; + int ret = -EIO; + + if (esw_stats == NULL) + return -ENOMEM; + if (adapter->op_mode != QLCNIC_MGMT_FUNC) + return -EIO; + if (adapter->npars == NULL) + return -EIO; + + memset(esw_stats, 0, sizeof(u64)); + esw_stats->unicast_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->multicast_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->broadcast_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->dropped_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->errors = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->local_frames = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->numbytes = QLCNIC_ESW_STATS_NOT_AVAIL; + esw_stats->context_id = eswitch; + + for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { + if (adapter->npars[i].phy_port != eswitch) + continue; + + memset(&port_stats, 0, sizeof(struct __qlcnic_esw_statistics)); + if (qlcnic_get_port_stats(adapter, i, rx_tx, &port_stats)) + continue; + + esw_stats->size = port_stats.size; + esw_stats->version = port_stats.version; + QLCNIC_ADD_ESW_STATS(esw_stats->unicast_frames, + port_stats.unicast_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->multicast_frames, + port_stats.multicast_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->broadcast_frames, + port_stats.broadcast_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->dropped_frames, + port_stats.dropped_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->errors, + port_stats.errors); + QLCNIC_ADD_ESW_STATS(esw_stats->local_frames, + port_stats.local_frames); + QLCNIC_ADD_ESW_STATS(esw_stats->numbytes, + port_stats.numbytes); + ret = 0; + } + return ret; +} + +int qlcnic_clear_esw_stats(struct qlcnic_adapter *adapter, const u8 func_esw, + const u8 port, const u8 rx_tx) { - int err = -EIO; - u32 arg1, arg2; - struct qlcnic_eswitch *eswitch; + + u32 arg1; if (adapter->op_mode != QLCNIC_MGMT_FUNC) - return err; + return -EIO; - eswitch = &adapter->eswitch[id]; - if (!eswitch) - return err; + if (func_esw == QLCNIC_STATS_PORT) { + if (port >= QLCNIC_MAX_PCI_FUNC) + goto err_ret; + } else if (func_esw == QLCNIC_STATS_ESWITCH) { + if (port >= QLCNIC_NIU_MAX_XG_PORTS) + goto err_ret; + } else { + goto err_ret; + } - arg1 = eswitch->port | (enable ? BIT_4 : 0); - arg2 = eswitch->active_vports | (eswitch->max_ucast_filters << 8) | - (eswitch->max_active_vlans << 16); - err = qlcnic_issue_cmd(adapter, + if (rx_tx > QLCNIC_QUERY_TX_COUNTER) + goto err_ret; + + arg1 = port | QLCNIC_STATS_VERSION << 8 | func_esw << 12; + arg1 |= BIT_14 | rx_tx << 15; + + return qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, arg1, - arg2, 0, - QLCNIC_CDRP_CMD_TOGGLE_ESWITCH); - - if (err != QLCNIC_RCODE_SUCCESS) { - dev_err(&adapter->pdev->dev, - "Failed to enable eswitch%d\n", eswitch->port); - eswitch->flags &= ~QLCNIC_SWITCH_ENABLE; - err = -EIO; - } else { - eswitch->flags |= QLCNIC_SWITCH_ENABLE; - dev_info(&adapter->pdev->dev, - "Enabled eSwitch for port %d\n", eswitch->port); - } + 0, + QLCNIC_CDRP_CMD_GET_ESWITCH_STATS); - return err; +err_ret: + dev_err(&adapter->pdev->dev, "Invalid argument func_esw=%d port=%d" + "rx_ctx=%d\n", func_esw, port, rx_tx); + return -EIO; } -/* Configure eSwitch for port mirroring */ -int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id, - u8 enable_mirroring, u8 pci_func) +static int +__qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, + u32 *arg1, u32 *arg2) { int err = -EIO; - u32 arg1; - - if (adapter->op_mode != QLCNIC_MGMT_FUNC || - !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) - return err; - - arg1 = id | (enable_mirroring ? BIT_4 : 0); - arg1 |= pci_func << 8; - + u8 pci_func; + pci_func = (*arg1 >> 8); err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, - arg1, + *arg1, 0, 0, - QLCNIC_CDRP_CMD_SET_PORTMIRRORING); + QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG); - if (err != QLCNIC_RCODE_SUCCESS) { - dev_err(&adapter->pdev->dev, - "Failed to configure port mirroring%d on eswitch:%d\n", - pci_func, id); - } else { + if (err == QLCNIC_RCODE_SUCCESS) { + *arg1 = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET); + *arg2 = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET); dev_info(&adapter->pdev->dev, - "Configured eSwitch %d for port mirroring:%d\n", - id, pci_func); + "eSwitch port config for pci func %d\n", pci_func); + } else { + dev_err(&adapter->pdev->dev, + "Failed to get eswitch port config for pci func %d\n", + pci_func); } - return err; } - -/* Configure eSwitch port */ -int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, u8 id, - int vlan_tagging, u8 discard_tagged, u8 promsc_mode, - u8 mac_learn, u8 pci_func, u16 vlan_id) +/* Configure eSwitch port +op_mode = 0 for setting default port behavior +op_mode = 1 for setting vlan id +op_mode = 2 for deleting vlan id +op_type = 0 for vlan_id +op_type = 1 for port vlan_id +*/ +int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) { int err = -EIO; - u32 arg1; - struct qlcnic_eswitch *eswitch; + u32 arg1, arg2 = 0; + u8 pci_func; if (adapter->op_mode != QLCNIC_MGMT_FUNC) return err; + pci_func = esw_cfg->pci_func; + arg1 = (adapter->npars[pci_func].phy_port & BIT_0); + arg1 |= (pci_func << 8); - eswitch = &adapter->eswitch[id]; - if (!(eswitch->flags & QLCNIC_SWITCH_ENABLE)) + if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2)) return err; - - arg1 = eswitch->port | (discard_tagged ? BIT_4 : 0); - arg1 |= (promsc_mode ? BIT_6 : 0) | (mac_learn ? BIT_7 : 0); - arg1 |= pci_func << 8; - if (vlan_tagging) - arg1 |= BIT_5 | (vlan_id << 16); + arg1 &= ~(0x0ff << 8); + arg1 |= (pci_func << 8); + arg1 &= ~(BIT_2 | BIT_3); + switch (esw_cfg->op_mode) { + case QLCNIC_PORT_DEFAULTS: + arg1 |= (BIT_4 | BIT_6 | BIT_7); + arg2 |= (BIT_0 | BIT_1); + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) + arg2 |= (BIT_2 | BIT_3); + if (!(esw_cfg->discard_tagged)) + arg1 &= ~BIT_4; + if (!(esw_cfg->promisc_mode)) + arg1 &= ~BIT_6; + if (!(esw_cfg->mac_override)) + arg1 &= ~BIT_7; + if (!(esw_cfg->mac_anti_spoof)) + arg2 &= ~BIT_0; + if (!(esw_cfg->offload_flags & BIT_0)) + arg2 &= ~(BIT_1 | BIT_2 | BIT_3); + if (!(esw_cfg->offload_flags & BIT_1)) + arg2 &= ~BIT_2; + if (!(esw_cfg->offload_flags & BIT_2)) + arg2 &= ~BIT_3; + break; + case QLCNIC_ADD_VLAN: + arg1 |= (BIT_2 | BIT_5); + arg1 |= (esw_cfg->vlan_id << 16); + break; + case QLCNIC_DEL_VLAN: + arg1 |= (BIT_3 | BIT_5); + arg1 &= ~(0x0ffff << 16); + break; + default: + return err; + } err = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func, adapter->fw_hal_version, arg1, - 0, + arg2, 0, QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH); if (err != QLCNIC_RCODE_SUCCESS) { dev_err(&adapter->pdev->dev, - "Failed to configure eswitch port%d\n", eswitch->port); + "Failed to configure eswitch pci func %d\n", pci_func); } else { dev_info(&adapter->pdev->dev, - "Configured eSwitch for port %d\n", eswitch->port); + "Configured eSwitch for pci func %d\n", pci_func); } return err; } + +int +qlcnic_get_eswitch_port_config(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + u32 arg1, arg2; + u8 phy_port; + if (adapter->op_mode == QLCNIC_MGMT_FUNC) + phy_port = adapter->npars[esw_cfg->pci_func].phy_port; + else + phy_port = adapter->physical_port; + arg1 = phy_port; + arg1 |= (esw_cfg->pci_func << 8); + if (__qlcnic_get_eswitch_port_config(adapter, &arg1, &arg2)) + return -EIO; + + esw_cfg->discard_tagged = !!(arg1 & BIT_4); + esw_cfg->host_vlan_tag = !!(arg1 & BIT_5); + esw_cfg->promisc_mode = !!(arg1 & BIT_6); + esw_cfg->mac_override = !!(arg1 & BIT_7); + esw_cfg->vlan_id = LSW(arg1 >> 16); + esw_cfg->mac_anti_spoof = (arg2 & 0x1); + esw_cfg->offload_flags = ((arg2 >> 1) & 0x7); + + return 0; +} diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c index 9328d59e21e0c6c2ff8011b19eb30f5f041fed5d..25e93a53fca0954e41728e9c55e31305ee62cc53 100644 --- a/drivers/net/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/qlcnic/qlcnic_ethtool.c @@ -78,7 +78,25 @@ static const struct qlcnic_stats qlcnic_gstrings_stats[] = { }; +static const char qlcnic_device_gstrings_stats[][ETH_GSTRING_LEN] = { + "rx unicast frames", + "rx multicast frames", + "rx broadcast frames", + "rx dropped frames", + "rx errors", + "rx local frames", + "rx numbytes", + "tx unicast frames", + "tx multicast frames", + "tx broadcast frames", + "tx dropped frames", + "tx errors", + "tx local frames", + "tx numbytes", +}; + #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) +#define QLCNIC_DEVICE_STATS_LEN ARRAY_SIZE(qlcnic_device_gstrings_stats) static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { "Register_Test_on_offline", @@ -96,10 +114,10 @@ static const char qlcnic_gstrings_test[][ETH_GSTRING_LEN] = { static const u32 diag_registers[] = { CRB_CMDPEG_STATE, CRB_RCVPEG_STATE, - CRB_XG_STATE_P3, + CRB_XG_STATE_P3P, CRB_FW_CAPABILITIES_1, ISR_INT_STATE_REG, - QLCNIC_CRB_DEV_REF_COUNT, + QLCNIC_CRB_DRV_ACTIVE, QLCNIC_CRB_DEV_STATE, QLCNIC_CRB_DRV_STATE, QLCNIC_CRB_DRV_SCRATCH, @@ -115,9 +133,13 @@ static const u32 diag_registers[] = { -1 }; +#define QLCNIC_MGMT_API_VERSION 2 +#define QLCNIC_DEV_INFO_SIZE 1 +#define QLCNIC_ETHTOOL_REGS_VER 2 static int qlcnic_get_regs_len(struct net_device *dev) { - return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN; + return sizeof(diag_registers) + QLCNIC_RING_REGS_LEN + + QLCNIC_DEV_INFO_SIZE + 1; } static int qlcnic_get_eeprom_len(struct net_device *dev) @@ -185,9 +207,9 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) goto skip; } - val = QLCRD32(adapter, P3_LINK_SPEED_REG(pcifn)); - ecmd->speed = P3_LINK_SPEED_MHZ * - P3_LINK_SPEED_VAL(pcifn, val); + val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn)); + ecmd->speed = P3P_LINK_SPEED_MHZ * + P3P_LINK_SPEED_VAL(pcifn, val); ecmd->duplex = DUPLEX_FULL; ecmd->autoneg = AUTONEG_DISABLE; } else @@ -198,42 +220,42 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) ecmd->transceiver = XCVR_EXTERNAL; switch (adapter->ahw.board_type) { - case QLCNIC_BRDTYPE_P3_REF_QG: - case QLCNIC_BRDTYPE_P3_4_GB: - case QLCNIC_BRDTYPE_P3_4_GB_MM: + case QLCNIC_BRDTYPE_P3P_REF_QG: + case QLCNIC_BRDTYPE_P3P_4_GB: + case QLCNIC_BRDTYPE_P3P_4_GB_MM: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; - case QLCNIC_BRDTYPE_P3_10G_CX4: - case QLCNIC_BRDTYPE_P3_10G_CX4_LP: - case QLCNIC_BRDTYPE_P3_10000_BASE_T: + case QLCNIC_BRDTYPE_P3P_10G_CX4: + case QLCNIC_BRDTYPE_P3P_10G_CX4_LP: + case QLCNIC_BRDTYPE_P3P_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->autoneg = adapter->link_autoneg; break; - case QLCNIC_BRDTYPE_P3_IMEZ: - case QLCNIC_BRDTYPE_P3_XG_LOM: - case QLCNIC_BRDTYPE_P3_HMEZ: + case QLCNIC_BRDTYPE_P3P_IMEZ: + case QLCNIC_BRDTYPE_P3P_XG_LOM: + case QLCNIC_BRDTYPE_P3P_HMEZ: ecmd->supported |= SUPPORTED_MII; ecmd->advertising |= ADVERTISED_MII; ecmd->port = PORT_MII; ecmd->autoneg = AUTONEG_DISABLE; break; - case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS: - case QLCNIC_BRDTYPE_P3_10G_SFP_CT: - case QLCNIC_BRDTYPE_P3_10G_SFP_QT: + case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS: + case QLCNIC_BRDTYPE_P3P_10G_SFP_CT: + case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: ecmd->advertising |= ADVERTISED_TP; ecmd->supported |= SUPPORTED_TP; check_sfp_module = netif_running(dev) && adapter->has_link_events; - case QLCNIC_BRDTYPE_P3_10G_XFP: + case QLCNIC_BRDTYPE_P3P_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; - case QLCNIC_BRDTYPE_P3_10G_TP: + case QLCNIC_BRDTYPE_P3P_10G_TP: if (adapter->ahw.port_type == QLCNIC_XGBE) { ecmd->autoneg = AUTONEG_DISABLE; ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); @@ -339,14 +361,17 @@ qlcnic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring; u32 *regs_buff = p; - int ring, i = 0; + int ring, i = 0, j = 0; memset(p, 0, qlcnic_get_regs_len(dev)); - regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | - (adapter->pdev)->device; + regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) | + (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; + + regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff)); + regs_buff[1] = QLCNIC_MGMT_API_VERSION; - for (i = 0; diag_registers[i] != -1; i++) - regs_buff[i] = QLCRD32(adapter, diag_registers[i]); + for (i = QLCNIC_DEV_INFO_SIZE + 1; diag_registers[j] != -1; j++, i++) + regs_buff[i] = QLCRD32(adapter, diag_registers[j]); if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) return; @@ -374,9 +399,9 @@ static u32 qlcnic_test_link(struct net_device *dev) struct qlcnic_adapter *adapter = netdev_priv(dev); u32 val; - val = QLCRD32(adapter, CRB_XG_STATE_P3); - val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val); - return (val == XG_LINK_UP_P3) ? 0 : 1; + val = QLCRD32(adapter, CRB_XG_STATE_P3P); + val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val); + return (val == XG_LINK_UP_P3P) ? 0 : 1; } static int @@ -618,10 +643,13 @@ static int qlcnic_reg_test(struct net_device *dev) static int qlcnic_get_sset_count(struct net_device *dev, int sset) { + struct qlcnic_adapter *adapter = netdev_priv(dev); switch (sset) { case ETH_SS_TEST: return QLCNIC_TEST_LEN; case ETH_SS_STATS: + if (adapter->flags & QLCNIC_ESWITCH_ENABLED) + return QLCNIC_STATS_LEN + QLCNIC_DEVICE_STATS_LEN; return QLCNIC_STATS_LEN; default: return -EOPNOTSUPP; @@ -629,6 +657,8 @@ static int qlcnic_get_sset_count(struct net_device *dev, int sset) } #define QLC_ILB_PKT_SIZE 64 +#define QLC_NUM_ILB_PKT 16 +#define QLC_ILB_MAX_RCV_LOOP 10 static void qlcnic_create_loopback_buff(unsigned char *data) { @@ -650,24 +680,34 @@ static int qlcnic_do_ilb_test(struct qlcnic_adapter *adapter) struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; struct qlcnic_host_sds_ring *sds_ring = &recv_ctx->sds_rings[0]; struct sk_buff *skb; - int i; + int i, loop, cnt = 0; - for (i = 0; i < 16; i++) { + for (i = 0; i < QLC_NUM_ILB_PKT; i++) { skb = dev_alloc_skb(QLC_ILB_PKT_SIZE); qlcnic_create_loopback_buff(skb->data); skb_put(skb, QLC_ILB_PKT_SIZE); adapter->diag_cnt = 0; - qlcnic_xmit_frame(skb, adapter->netdev); - msleep(5); - - qlcnic_process_rcv_ring_diag(sds_ring); + loop = 0; + do { + msleep(1); + qlcnic_process_rcv_ring_diag(sds_ring); + } while (loop++ < QLC_ILB_MAX_RCV_LOOP && + !adapter->diag_cnt); dev_kfree_skb_any(skb); + if (!adapter->diag_cnt) - return -1; + dev_warn(&adapter->pdev->dev, "ILB Test: %dth packet" + " not recevied\n", i + 1); + else + cnt++; + } + if (cnt != i) { + dev_warn(&adapter->pdev->dev, "ILB Test failed\n"); + return -1; } return 0; } @@ -687,6 +727,11 @@ static int qlcnic_loopback_test(struct net_device *netdev) if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) return -EIO; + if (qlcnic_request_quiscent_mode(adapter)) { + clear_bit(__QLCNIC_RESETTING, &adapter->state); + return -EIO; + } + ret = qlcnic_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); if (ret) goto clear_it; @@ -703,6 +748,7 @@ static int qlcnic_loopback_test(struct net_device *netdev) qlcnic_diag_free_res(netdev, max_sds_rings); clear_it: + qlcnic_clear_quiscent_mode(adapter); adapter->max_sds_rings = max_sds_rings; clear_bit(__QLCNIC_RESETTING, &adapter->state); return ret; @@ -747,6 +793,14 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, { memset(data, 0, sizeof(u64) * QLCNIC_TEST_LEN); + data[0] = qlcnic_reg_test(dev); + if (data[0]) + eth_test->flags |= ETH_TEST_FL_FAILED; + + data[1] = (u64) qlcnic_test_link(dev); + if (data[1]) + eth_test->flags |= ETH_TEST_FL_FAILED; + if (eth_test->flags == ETH_TEST_FL_OFFLINE) { data[2] = qlcnic_irq_test(dev); if (data[2]) @@ -757,21 +811,13 @@ qlcnic_diag_test(struct net_device *dev, struct ethtool_test *eth_test, eth_test->flags |= ETH_TEST_FL_FAILED; } - - data[0] = qlcnic_reg_test(dev); - if (data[0]) - eth_test->flags |= ETH_TEST_FL_FAILED; - - /* link test */ - data[1] = (u64) qlcnic_test_link(dev); - if (data[1]) - eth_test->flags |= ETH_TEST_FL_FAILED; } static void qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data) { - int index; + struct qlcnic_adapter *adapter = netdev_priv(dev); + int index, i; switch (stringset) { case ETH_SS_TEST: @@ -784,16 +830,43 @@ qlcnic_get_strings(struct net_device *dev, u32 stringset, u8 * data) qlcnic_gstrings_stats[index].stat_string, ETH_GSTRING_LEN); } - break; + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return; + for (i = 0; i < QLCNIC_DEVICE_STATS_LEN; index++, i++) { + memcpy(data + index * ETH_GSTRING_LEN, + qlcnic_device_gstrings_stats[i], + ETH_GSTRING_LEN); + } } } +#define QLCNIC_FILL_ESWITCH_STATS(VAL1) \ + (((VAL1) == QLCNIC_ESW_STATS_NOT_AVAIL) ? 0 : VAL1) + +static void +qlcnic_fill_device_stats(int *index, u64 *data, + struct __qlcnic_esw_statistics *stats) +{ + int ind = *index; + + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->unicast_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->multicast_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->broadcast_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->dropped_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->errors); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->local_frames); + data[ind++] = QLCNIC_FILL_ESWITCH_STATS(stats->numbytes); + + *index = ind; +} + static void qlcnic_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 * data) { struct qlcnic_adapter *adapter = netdev_priv(dev); - int index; + struct qlcnic_esw_statistics port_stats; + int index, ret; for (index = 0; index < QLCNIC_STATS_LEN; index++) { char *p = @@ -803,8 +876,40 @@ qlcnic_get_ethtool_stats(struct net_device *dev, (qlcnic_gstrings_stats[index].sizeof_stat == sizeof(u64)) ? *(u64 *)p:(*(u32 *)p); } + + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return; + + memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics)); + ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func, + QLCNIC_QUERY_RX_COUNTER, &port_stats.rx); + if (ret) + return; + + qlcnic_fill_device_stats(&index, data, &port_stats.rx); + + ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func, + QLCNIC_QUERY_TX_COUNTER, &port_stats.tx); + if (ret) + return; + + qlcnic_fill_device_stats(&index, data, &port_stats.tx); } +static int qlcnic_set_tx_csum(struct net_device *dev, u32 data) +{ + struct qlcnic_adapter *adapter = netdev_priv(dev); + + if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return -EOPNOTSUPP; + if (data) + dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + else + dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); + + return 0; + +} static u32 qlcnic_get_tx_csum(struct net_device *dev) { return dev->features & NETIF_F_IP_CSUM; @@ -819,7 +924,23 @@ static u32 qlcnic_get_rx_csum(struct net_device *dev) static int qlcnic_set_rx_csum(struct net_device *dev, u32 data) { struct qlcnic_adapter *adapter = netdev_priv(dev); + + if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return -EOPNOTSUPP; + if (!!data) { + adapter->rx_csum = !!data; + return 0; + } + + if (dev->features & NETIF_F_LRO) { + if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED)) + return -EIO; + + dev->features &= ~NETIF_F_LRO; + qlcnic_send_lro_cleanup(adapter); + } adapter->rx_csum = !!data; + dev_info(&adapter->pdev->dev, "disabling LRO as rx_csum is off\n"); return 0; } @@ -1002,6 +1123,15 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data) if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)) return -EINVAL; + if (!adapter->rx_csum) { + dev_info(&adapter->pdev->dev, "rx csum is off, " + "cannot toggle lro\n"); + return -EINVAL; + } + + if ((data & ETH_FLAG_LRO) && (netdev->features & NETIF_F_LRO)) + return 0; + if (data & ETH_FLAG_LRO) { hw_lro = QLCNIC_LRO_ENABLED; netdev->features |= NETIF_F_LRO; @@ -1048,7 +1178,7 @@ const struct ethtool_ops qlcnic_ethtool_ops = { .get_pauseparam = qlcnic_get_pauseparam, .set_pauseparam = qlcnic_set_pauseparam, .get_tx_csum = qlcnic_get_tx_csum, - .set_tx_csum = ethtool_op_set_tx_csum, + .set_tx_csum = qlcnic_set_tx_csum, .set_sg = ethtool_op_set_sg, .get_tso = qlcnic_get_tso, .set_tso = qlcnic_set_tso, diff --git a/drivers/net/qlcnic/qlcnic_hdr.h b/drivers/net/qlcnic/qlcnic_hdr.h index 15fc32070be3dfd689c7acece6658e866b22f59b..4290b80cde1ad5b179e241f1576e8c2648e83709 100644 --- a/drivers/net/qlcnic/qlcnic_hdr.h +++ b/drivers/net/qlcnic/qlcnic_hdr.h @@ -556,18 +556,18 @@ enum { #define XG_LINK_UP 0x10 #define XG_LINK_DOWN 0x20 -#define XG_LINK_UP_P3 0x01 -#define XG_LINK_DOWN_P3 0x02 -#define XG_LINK_STATE_P3_MASK 0xf -#define XG_LINK_STATE_P3(pcifn, val) \ - (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK) - -#define P3_LINK_SPEED_MHZ 100 -#define P3_LINK_SPEED_MASK 0xff -#define P3_LINK_SPEED_REG(pcifn) \ +#define XG_LINK_UP_P3P 0x01 +#define XG_LINK_DOWN_P3P 0x02 +#define XG_LINK_STATE_P3P_MASK 0xf +#define XG_LINK_STATE_P3P(pcifn, val) \ + (((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3P_MASK) + +#define P3P_LINK_SPEED_MHZ 100 +#define P3P_LINK_SPEED_MASK 0xff +#define P3P_LINK_SPEED_REG(pcifn) \ (CRB_PF_LINK_SPEED_1 + (((pcifn) / 4) * 4)) -#define P3_LINK_SPEED_VAL(pcifn, reg) \ - (((reg) >> (8 * ((pcifn) & 0x3))) & P3_LINK_SPEED_MASK) +#define P3P_LINK_SPEED_VAL(pcifn, reg) \ + (((reg) >> (8 * ((pcifn) & 0x3))) & P3P_LINK_SPEED_MASK) #define QLCNIC_CAM_RAM_BASE (QLCNIC_CRB_CAM + 0x02000) #define QLCNIC_CAM_RAM(reg) (QLCNIC_CAM_RAM_BASE + (reg)) @@ -592,7 +592,7 @@ enum { #define CRB_CMDPEG_STATE (QLCNIC_REG(0x50)) #define CRB_RCVPEG_STATE (QLCNIC_REG(0x13c)) -#define CRB_XG_STATE_P3 (QLCNIC_REG(0x98)) +#define CRB_XG_STATE_P3P (QLCNIC_REG(0x98)) #define CRB_PF_LINK_SPEED_1 (QLCNIC_REG(0xe8)) #define CRB_PF_LINK_SPEED_2 (QLCNIC_REG(0xec)) @@ -698,7 +698,7 @@ enum { #define QLCNIC_PEG_ALIVE_COUNTER (QLCNIC_CAM_RAM(0xb0)) #define QLCNIC_PEG_HALT_STATUS1 (QLCNIC_CAM_RAM(0xa8)) #define QLCNIC_PEG_HALT_STATUS2 (QLCNIC_CAM_RAM(0xac)) -#define QLCNIC_CRB_DEV_REF_COUNT (QLCNIC_CAM_RAM(0x138)) +#define QLCNIC_CRB_DRV_ACTIVE (QLCNIC_CAM_RAM(0x138)) #define QLCNIC_CRB_DEV_STATE (QLCNIC_CAM_RAM(0x140)) #define QLCNIC_CRB_DRV_STATE (QLCNIC_CAM_RAM(0x144)) @@ -718,8 +718,9 @@ enum { #define QLCNIC_DEV_FAILED 0x6 #define QLCNIC_DEV_QUISCENT 0x7 -#define QLCNIC_DEV_NPAR_NOT_RDY 0 -#define QLCNIC_DEV_NPAR_RDY 1 +#define QLCNIC_DEV_NPAR_NON_OPER 0 /* NON Operational */ +#define QLCNIC_DEV_NPAR_OPER 1 /* NPAR Operational */ +#define QLCNIC_DEV_NPAR_OPER_TIMEO 30 /* Operational time out */ #define QLC_DEV_CHECK_ACTIVE(VAL, FN) ((VAL) &= (1 << (FN * 4))) #define QLC_DEV_SET_REF_CNT(VAL, FN) ((VAL) |= (1 << (FN * 4))) @@ -744,6 +745,15 @@ enum { #define FW_POLL_DELAY (1 * HZ) #define FW_FAIL_THRESH 2 +#define QLCNIC_RESET_TIMEOUT_SECS 10 +#define QLCNIC_INIT_TIMEOUT_SECS 30 +#define QLCNIC_RCVPEG_CHECK_RETRY_COUNT 2000 +#define QLCNIC_RCVPEG_CHECK_DELAY 10 +#define QLCNIC_CMDPEG_CHECK_RETRY_COUNT 60 +#define QLCNIC_CMDPEG_CHECK_DELAY 500 +#define QLCNIC_HEARTBEAT_PERIOD_MSECS 200 +#define QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT 45 + #define ISR_MSI_INT_TRIGGER(FUNC) (QLCNIC_PCIX_PS_REG(PCIX_MSI_F(FUNC))) #define ISR_LEGACY_INT_TRIGGERED(VAL) (((VAL) & 0x300) == 0x200) @@ -770,6 +780,7 @@ struct qlcnic_legacy_intr_set { #define QLCNIC_DRV_OP_MODE 0x1b2170 #define QLCNIC_MSIX_BASE 0x132110 #define QLCNIC_MAX_PCI_FUNC 8 +#define QLCNIC_MAX_VLAN_FILTERS 64 /* PCI function operational mode */ enum { @@ -778,6 +789,12 @@ enum { QLCNIC_NON_PRIV_FUNC = 2 }; +enum { + QLCNIC_PORT_DEFAULTS = 0, + QLCNIC_ADD_VLAN = 1, + QLCNIC_DEL_VLAN = 2 +}; + #define QLC_DEV_DRV_DEFAULT 0x11111111 #define LSB(x) ((uint8_t)(x)) diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index e08c8b0556a47bf2692d272d7d6a1cd029b69608..7a47a2a7ee2763b88b3b6cca21ca6f418c553465 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c @@ -297,8 +297,8 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) break; if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) { dev_err(&adapter->pdev->dev, - "Failed to acquire sem=%d lock;reg_id=%d\n", - sem, id_reg); + "Failed to acquire sem=%d lock; holdby=%d\n", + sem, id_reg ? QLCRD32(adapter, id_reg) : -1); return -EIO; } msleep(1); @@ -375,10 +375,11 @@ qlcnic_send_cmd_descs(struct qlcnic_adapter *adapter, static int qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, - unsigned op) + __le16 vlan_id, unsigned op) { struct qlcnic_nic_req req; struct qlcnic_mac_req *mac_req; + struct qlcnic_vlan_req *vlan_req; u64 word; memset(&req, 0, sizeof(struct qlcnic_nic_req)); @@ -391,6 +392,9 @@ qlcnic_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, mac_req->op = op; memcpy(mac_req->mac_addr, addr, 6); + vlan_req = (struct qlcnic_vlan_req *)&req.words[1]; + vlan_req->vlan_id = vlan_id; + return qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); } @@ -415,7 +419,7 @@ static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) memcpy(cur->mac_addr, addr, ETH_ALEN); if (qlcnic_sre_macaddr_change(adapter, - cur->mac_addr, QLCNIC_MAC_ADD)) { + cur->mac_addr, 0, QLCNIC_MAC_ADD)) { kfree(cur); return -EIO; } @@ -438,7 +442,8 @@ void qlcnic_set_multi(struct net_device *netdev) qlcnic_nic_add_mac(adapter, bcast_addr); if (netdev->flags & IFF_PROMISC) { - mode = VPORT_MISS_MODE_ACCEPT_ALL; + if (!(adapter->flags & QLCNIC_PROMISC_DISABLED)) + mode = VPORT_MISS_MODE_ACCEPT_ALL; goto send_fw_cmd; } @@ -485,12 +490,63 @@ void qlcnic_free_mac_list(struct qlcnic_adapter *adapter) while (!list_empty(head)) { cur = list_entry(head->next, struct qlcnic_mac_list_s, list); qlcnic_sre_macaddr_change(adapter, - cur->mac_addr, QLCNIC_MAC_DEL); + cur->mac_addr, 0, QLCNIC_MAC_DEL); list_del(&cur->list); kfree(cur); } } +void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter) +{ + struct qlcnic_filter *tmp_fil; + struct hlist_node *tmp_hnode, *n; + struct hlist_head *head; + int i; + + for (i = 0; i < adapter->fhash.fmax; i++) { + head = &(adapter->fhash.fhead[i]); + + hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) + { + if (jiffies > + (QLCNIC_FILTER_AGE * HZ + tmp_fil->ftime)) { + qlcnic_sre_macaddr_change(adapter, + tmp_fil->faddr, tmp_fil->vlan_id, + tmp_fil->vlan_id ? QLCNIC_MAC_VLAN_DEL : + QLCNIC_MAC_DEL); + spin_lock_bh(&adapter->mac_learn_lock); + adapter->fhash.fnum--; + hlist_del(&tmp_fil->fnode); + spin_unlock_bh(&adapter->mac_learn_lock); + kfree(tmp_fil); + } + } + } +} + +void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter) +{ + struct qlcnic_filter *tmp_fil; + struct hlist_node *tmp_hnode, *n; + struct hlist_head *head; + int i; + + for (i = 0; i < adapter->fhash.fmax; i++) { + head = &(adapter->fhash.fhead[i]); + + hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { + qlcnic_sre_macaddr_change(adapter, tmp_fil->faddr, + tmp_fil->vlan_id, tmp_fil->vlan_id ? + QLCNIC_MAC_VLAN_DEL : QLCNIC_MAC_DEL); + spin_lock_bh(&adapter->mac_learn_lock); + adapter->fhash.fnum--; + hlist_del(&tmp_fil->fnode); + spin_unlock_bh(&adapter->mac_learn_lock); + kfree(tmp_fil); + } + } +} + #define QLCNIC_CONFIG_INTR_COALESCE 3 /* @@ -527,9 +583,6 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable) u64 word; int rv; - if ((adapter->flags & QLCNIC_LRO_ENABLED) == enable) - return 0; - memset(&req, 0, sizeof(struct qlcnic_nic_req)); req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23); @@ -544,8 +597,6 @@ int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable) dev_err(&adapter->netdev->dev, "Could not send configure hw lro request\n"); - adapter->flags ^= QLCNIC_LRO_ENABLED; - return rv; } @@ -623,9 +674,10 @@ int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) return rv; } -int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd) +int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip, int cmd) { struct qlcnic_nic_req req; + struct qlcnic_ipaddr *ipa; u64 word; int rv; @@ -636,7 +688,8 @@ int qlcnic_config_ipaddr(struct qlcnic_adapter *adapter, u32 ip, int cmd) req.req_hdr = cpu_to_le64(word); req.words[0] = cpu_to_le64(cmd); - req.words[1] = cpu_to_le64(ip); + ipa = (struct qlcnic_ipaddr *)&req.words[1]; + ipa->ipv4 = ip; rv = qlcnic_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); if (rv != 0) @@ -701,9 +754,9 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) struct qlcnic_adapter *adapter = netdev_priv(netdev); int rc = 0; - if (mtu > P3_MAX_MTU) { - dev_err(&adapter->netdev->dev, "mtu > %d bytes unsupported\n", - P3_MAX_MTU); + if (mtu < P3P_MIN_MTU || mtu > P3P_MAX_MTU) { + dev_err(&adapter->netdev->dev, "%d bytes < mtu < %d bytes" + " not supported\n", P3P_MAX_MTU, P3P_MIN_MTU); return -EINVAL; } @@ -715,19 +768,6 @@ int qlcnic_change_mtu(struct net_device *netdev, int mtu) return rc; } -int qlcnic_get_mac_addr(struct qlcnic_adapter *adapter, u8 *mac) -{ - u32 crbaddr; - int pci_func = adapter->ahw.pci_func; - - crbaddr = CRB_MAC_BLOCK_START + - (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); - - qlcnic_fetch_mac(adapter, crbaddr, crbaddr+4, pci_func & 1, mac); - - return 0; -} - /* * Changes the CRB window to the specified window. */ @@ -1121,31 +1161,31 @@ int qlcnic_get_board_info(struct qlcnic_adapter *adapter) adapter->ahw.board_type = board_type; - if (board_type == QLCNIC_BRDTYPE_P3_4_GB_MM) { + if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) { u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I); if ((gpio & 0x8000) == 0) - board_type = QLCNIC_BRDTYPE_P3_10G_TP; + board_type = QLCNIC_BRDTYPE_P3P_10G_TP; } switch (board_type) { - case QLCNIC_BRDTYPE_P3_HMEZ: - case QLCNIC_BRDTYPE_P3_XG_LOM: - case QLCNIC_BRDTYPE_P3_10G_CX4: - case QLCNIC_BRDTYPE_P3_10G_CX4_LP: - case QLCNIC_BRDTYPE_P3_IMEZ: - case QLCNIC_BRDTYPE_P3_10G_SFP_PLUS: - case QLCNIC_BRDTYPE_P3_10G_SFP_CT: - case QLCNIC_BRDTYPE_P3_10G_SFP_QT: - case QLCNIC_BRDTYPE_P3_10G_XFP: - case QLCNIC_BRDTYPE_P3_10000_BASE_T: + case QLCNIC_BRDTYPE_P3P_HMEZ: + case QLCNIC_BRDTYPE_P3P_XG_LOM: + case QLCNIC_BRDTYPE_P3P_10G_CX4: + case QLCNIC_BRDTYPE_P3P_10G_CX4_LP: + case QLCNIC_BRDTYPE_P3P_IMEZ: + case QLCNIC_BRDTYPE_P3P_10G_SFP_PLUS: + case QLCNIC_BRDTYPE_P3P_10G_SFP_CT: + case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: + case QLCNIC_BRDTYPE_P3P_10G_XFP: + case QLCNIC_BRDTYPE_P3P_10000_BASE_T: adapter->ahw.port_type = QLCNIC_XGBE; break; - case QLCNIC_BRDTYPE_P3_REF_QG: - case QLCNIC_BRDTYPE_P3_4_GB: - case QLCNIC_BRDTYPE_P3_4_GB_MM: + case QLCNIC_BRDTYPE_P3P_REF_QG: + case QLCNIC_BRDTYPE_P3P_4_GB: + case QLCNIC_BRDTYPE_P3P_4_GB_MM: adapter->ahw.port_type = QLCNIC_GBE; break; - case QLCNIC_BRDTYPE_P3_10G_TP: + case QLCNIC_BRDTYPE_P3P_10G_TP: adapter->ahw.port_type = (adapter->portnum < 2) ? QLCNIC_XGBE : QLCNIC_GBE; break; @@ -1245,4 +1285,5 @@ void qlcnic_clear_ilb_mode(struct qlcnic_adapter *adapter) mode = VPORT_MISS_MODE_ACCEPT_MULTI; qlcnic_nic_set_promisc(adapter, mode); + msleep(1000); } diff --git a/drivers/net/qlcnic/qlcnic_init.c b/drivers/net/qlcnic/qlcnic_init.c index 2c7cf0b64811ed72d4d6368c02d46fa966e7de2f..0d180c6e41fe1f08fd6658e45bd57e0ba0d23f72 100644 --- a/drivers/net/qlcnic/qlcnic_init.c +++ b/drivers/net/qlcnic/qlcnic_init.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "qlcnic.h" struct crb_addr_pair { @@ -45,6 +46,9 @@ static void qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, struct qlcnic_host_rds_ring *rds_ring); +static int +qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter); + static void crb_addr_transform_setup(void) { crb_addr_transform(XDMA); @@ -136,8 +140,6 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter) for (ring = 0; ring < adapter->max_rds_rings; ring++) { rds_ring = &recv_ctx->rds_rings[ring]; - spin_lock(&rds_ring->lock); - INIT_LIST_HEAD(&rds_ring->free_list); rx_buf = rds_ring->rx_buf_arr; @@ -146,8 +148,6 @@ void qlcnic_reset_rx_buffers_list(struct qlcnic_adapter *adapter) &rds_ring->free_list); rx_buf++; } - - spin_unlock(&rds_ring->lock); } } @@ -259,14 +259,14 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) switch (ring) { case RCV_RING_NORMAL: rds_ring->num_desc = adapter->num_rxd; - rds_ring->dma_size = QLCNIC_P3_RX_BUF_MAX_LEN; + rds_ring->dma_size = QLCNIC_P3P_RX_BUF_MAX_LEN; rds_ring->skb_size = rds_ring->dma_size + NET_IP_ALIGN; break; case RCV_RING_JUMBO: rds_ring->num_desc = adapter->num_jumbo_rxd; rds_ring->dma_size = - QLCNIC_P3_RX_JUMBO_BUF_MAX_LEN; + QLCNIC_P3P_RX_JUMBO_BUF_MAX_LEN; if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) rds_ring->dma_size += QLCNIC_LRO_BUFFER_EXTRA; @@ -439,11 +439,14 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) u32 off; struct pci_dev *pdev = adapter->pdev; - /* resetall */ + QLCWR32(adapter, CRB_CMDPEG_STATE, 0); + QLCWR32(adapter, CRB_RCVPEG_STATE, 0); + qlcnic_rom_lock(adapter); QLCWR32(adapter, QLCNIC_ROMUSB_GLB_SW_RESET, 0xfeffffff); qlcnic_rom_unlock(adapter); + /* Init HW CRB block */ if (qlcnic_rom_fast_read(adapter, 0, &n) != 0 || (n != 0xcafecafe) || qlcnic_rom_fast_read(adapter, 4, &n) != 0) { dev_err(&pdev->dev, "ERROR Reading crb_init area: val:%x\n", n); @@ -524,13 +527,10 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) } kfree(buf); - /* p2dn replyCount */ + /* Initialize protocol process engine */ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0xec, 0x1e); - /* disable_peg_cache 0 & 1*/ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_D + 0x4c, 8); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_I + 0x4c, 8); - - /* peg_clr_all */ QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0x8, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_0 + 0xc, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_1 + 0x8, 0); @@ -539,9 +539,87 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) QLCWR32(adapter, QLCNIC_CRB_PEG_NET_2 + 0xc, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0x8, 0); QLCWR32(adapter, QLCNIC_CRB_PEG_NET_3 + 0xc, 0); + QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0x8, 0); + QLCWR32(adapter, QLCNIC_CRB_PEG_NET_4 + 0xc, 0); + msleep(1); + QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0); + QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0); + return 0; +} + +static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter) +{ + u32 val; + int retries = QLCNIC_CMDPEG_CHECK_RETRY_COUNT; + + do { + val = QLCRD32(adapter, CRB_CMDPEG_STATE); + + switch (val) { + case PHAN_INITIALIZE_COMPLETE: + case PHAN_INITIALIZE_ACK: + return 0; + case PHAN_INITIALIZE_FAILED: + goto out_err; + default: + break; + } + + msleep(QLCNIC_CMDPEG_CHECK_DELAY); + + } while (--retries); + + QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED); + +out_err: + dev_err(&adapter->pdev->dev, "Command Peg initialization not " + "complete, state: 0x%x.\n", val); + return -EIO; +} + +static int +qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter) +{ + u32 val; + int retries = QLCNIC_RCVPEG_CHECK_RETRY_COUNT; + + do { + val = QLCRD32(adapter, CRB_RCVPEG_STATE); + + if (val == PHAN_PEG_RCV_INITIALIZED) + return 0; + + msleep(QLCNIC_RCVPEG_CHECK_DELAY); + + } while (--retries); + + if (!retries) { + dev_err(&adapter->pdev->dev, "Receive Peg initialization not " + "complete, state: 0x%x.\n", val); + return -EIO; + } + return 0; } +int +qlcnic_check_fw_status(struct qlcnic_adapter *adapter) +{ + int err; + + err = qlcnic_cmd_peg_ready(adapter); + if (err) + return err; + + err = qlcnic_receive_peg_ready(adapter); + if (err) + return err; + + QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); + + return err; +} + int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) { @@ -557,12 +635,12 @@ qlcnic_setup_idc_param(struct qlcnic_adapter *adapter) { } adapter->physical_port = (val >> 2); if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DEV_INIT_TIMEOUT, &timeo)) - timeo = 30; + timeo = QLCNIC_INIT_TIMEOUT_SECS; adapter->dev_init_timeo = timeo; if (qlcnic_rom_fast_read(adapter, QLCNIC_ROM_DRV_RESET_TIMEOUT, &timeo)) - timeo = 10; + timeo = QLCNIC_RESET_TIMEOUT_SECS; adapter->reset_ack_timeo = timeo; @@ -906,54 +984,47 @@ qlcnic_get_bios_version(struct qlcnic_adapter *adapter) return (bios_ver << 16) + ((bios_ver >> 8) & 0xff00) + (bios_ver >> 24); } -int -qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) +static void qlcnic_rom_lock_recovery(struct qlcnic_adapter *adapter) { - u32 count, old_count; - u32 val, version, major, minor, build; - int i, timeout; - - if (adapter->need_fw_reset) - return 1; + if (qlcnic_pcie_sem_lock(adapter, 2, QLCNIC_ROM_LOCK_ID)) + dev_info(&adapter->pdev->dev, "Resetting rom_lock\n"); - /* last attempt had failed */ - if (QLCRD32(adapter, CRB_CMDPEG_STATE) == PHAN_INITIALIZE_FAILED) - return 1; + qlcnic_pcie_sem_unlock(adapter, 2); +} - old_count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); +static int +qlcnic_check_fw_hearbeat(struct qlcnic_adapter *adapter) +{ + u32 heartbeat, ret = -EIO; + int retries = QLCNIC_HEARTBEAT_CHECK_RETRY_COUNT; - for (i = 0; i < 10; i++) { + adapter->heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); - timeout = msleep_interruptible(200); - if (timeout) { - QLCWR32(adapter, CRB_CMDPEG_STATE, - PHAN_INITIALIZE_FAILED); - return -EINTR; + do { + msleep(QLCNIC_HEARTBEAT_PERIOD_MSECS); + heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); + if (heartbeat != adapter->heartbeat) { + ret = QLCNIC_RCODE_SUCCESS; + break; } + } while (--retries); - count = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); - if (count != old_count) - break; - } + return ret; +} - /* firmware is dead */ - if (count == old_count) +int +qlcnic_need_fw_reset(struct qlcnic_adapter *adapter) +{ + if (qlcnic_check_fw_hearbeat(adapter)) { + qlcnic_rom_lock_recovery(adapter); return 1; + } - /* check if we have got newer or different file firmware */ - if (adapter->fw) { - - val = qlcnic_get_fw_version(adapter); - - version = QLCNIC_DECODE_VERSION(val); - - major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); - minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); - build = QLCRD32(adapter, QLCNIC_FW_VERSION_SUB); + if (adapter->need_fw_reset) + return 1; - if (version > QLCNIC_VERSION_CODE(major, minor, build)) - return 1; - } + if (adapter->fw) + return 1; return 0; } @@ -1089,18 +1160,6 @@ qlcnic_validate_firmware(struct qlcnic_adapter *adapter) return -EINVAL; } - /* check if flashed firmware is newer */ - if (qlcnic_rom_fast_read(adapter, - QLCNIC_FW_VERSION_OFFSET, (int *)&val)) - return -EIO; - - val = QLCNIC_DECODE_VERSION(val); - if (val > ver) { - dev_info(&pdev->dev, "%s: firmware is older than flash\n", - fw_name[fw_type]); - return -EINVAL; - } - QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC); return 0; } @@ -1162,78 +1221,6 @@ qlcnic_release_firmware(struct qlcnic_adapter *adapter) adapter->fw = NULL; } -static int qlcnic_cmd_peg_ready(struct qlcnic_adapter *adapter) -{ - u32 val; - int retries = 60; - - do { - val = QLCRD32(adapter, CRB_CMDPEG_STATE); - - switch (val) { - case PHAN_INITIALIZE_COMPLETE: - case PHAN_INITIALIZE_ACK: - return 0; - case PHAN_INITIALIZE_FAILED: - goto out_err; - default: - break; - } - - msleep(500); - - } while (--retries); - - QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_FAILED); - -out_err: - dev_err(&adapter->pdev->dev, "Command Peg initialization not " - "complete, state: 0x%x.\n", val); - return -EIO; -} - -static int -qlcnic_receive_peg_ready(struct qlcnic_adapter *adapter) -{ - u32 val; - int retries = 2000; - - do { - val = QLCRD32(adapter, CRB_RCVPEG_STATE); - - if (val == PHAN_PEG_RCV_INITIALIZED) - return 0; - - msleep(10); - - } while (--retries); - - if (!retries) { - dev_err(&adapter->pdev->dev, "Receive Peg initialization not " - "complete, state: 0x%x.\n", val); - return -EIO; - } - - return 0; -} - -int qlcnic_init_firmware(struct qlcnic_adapter *adapter) -{ - int err; - - err = qlcnic_cmd_peg_ready(adapter); - if (err) - return err; - - err = qlcnic_receive_peg_ready(adapter); - if (err) - return err; - - QLCWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK); - - return err; -} - static void qlcnic_handle_linkevent(struct qlcnic_adapter *adapter, struct qlcnic_fw_msg *msg) @@ -1351,11 +1338,12 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, skb = buffer->skb; - if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) { + if (likely(adapter->rx_csum && (cksum == STATUS_CKSUM_OK || + cksum == STATUS_CKSUM_LOOP))) { adapter->stats.csummed++; skb->ip_summed = CHECKSUM_UNNECESSARY; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } skb->dev = adapter->netdev; @@ -1365,6 +1353,31 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *adapter, return skb; } +static int +qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb, + u16 *vlan_tag) +{ + struct ethhdr *eth_hdr; + + if (!__vlan_get_tag(skb, vlan_tag)) { + eth_hdr = (struct ethhdr *) skb->data; + memmove(skb->data + VLAN_HLEN, eth_hdr, ETH_ALEN * 2); + skb_pull(skb, VLAN_HLEN); + } + if (!adapter->pvid) + return 0; + + if (*vlan_tag == adapter->pvid) { + /* Outer vlan tag. Packet should follow non-vlan path */ + *vlan_tag = 0xffff; + return 0; + } + if (adapter->flags & QLCNIC_TAGGING_ENABLED) + return 0; + + return -EINVAL; +} + static struct qlcnic_rx_buffer * qlcnic_process_rcv(struct qlcnic_adapter *adapter, struct qlcnic_host_sds_ring *sds_ring, @@ -1376,6 +1389,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, struct sk_buff *skb; struct qlcnic_host_rds_ring *rds_ring; int index, length, cksum, pkt_offset; + u16 vid = 0xffff; if (unlikely(ring >= adapter->max_rds_rings)) return NULL; @@ -1404,9 +1418,18 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter, if (pkt_offset) skb_pull(skb, pkt_offset); + if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { + adapter->stats.rxdropped++; + dev_kfree_skb(skb); + return buffer; + } + skb->protocol = eth_type_trans(skb, netdev); - napi_gro_receive(&sds_ring->napi, skb); + if ((vid != 0xffff) && adapter->vlgrp) + vlan_gro_receive(&sds_ring->napi, adapter->vlgrp, vid, skb); + else + napi_gro_receive(&sds_ring->napi, skb); adapter->stats.rx_pkts++; adapter->stats.rxbytes += length; @@ -1435,6 +1458,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, int index; u16 lro_length, length, data_offset; u32 seq_number; + u16 vid = 0xffff; if (unlikely(ring > adapter->max_rds_rings)) return NULL; @@ -1466,6 +1490,13 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, skb_put(skb, lro_length + data_offset); skb_pull(skb, l2_hdr_offset); + + if (unlikely(qlcnic_check_rx_tagging(adapter, skb, &vid))) { + adapter->stats.rxdropped++; + dev_kfree_skb(skb); + return buffer; + } + skb->protocol = eth_type_trans(skb, netdev); iph = (struct iphdr *)skb->data; @@ -1480,7 +1511,10 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter, length = skb->len; - netif_receive_skb(skb); + if ((vid != 0xffff) && adapter->vlgrp) + vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vid); + else + netif_receive_skb(skb); adapter->stats.lro_pkts++; adapter->stats.lrobytes += length; @@ -1584,8 +1618,6 @@ qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid, int producer, count = 0; struct list_head *head; - spin_lock(&rds_ring->lock); - producer = rds_ring->producer; head = &rds_ring->free_list; @@ -1615,7 +1647,6 @@ qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid, writel((producer-1) & (rds_ring->num_desc-1), rds_ring->crb_rcv_producer); } - spin_unlock(&rds_ring->lock); } static void @@ -1662,6 +1693,18 @@ qlcnic_post_rx_buffers_nodb(struct qlcnic_adapter *adapter, spin_unlock(&rds_ring->lock); } +static void dump_skb(struct sk_buff *skb) +{ + int i; + unsigned char *data = skb->data; + + for (i = 0; i < skb->len; i++) { + printk("%02x ", data[i]); + if ((i & 0x0f) == 8) + printk("\n"); + } +} + static struct qlcnic_rx_buffer * qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, struct qlcnic_host_sds_ring *sds_ring, @@ -1692,13 +1735,18 @@ qlcnic_process_rcv_diag(struct qlcnic_adapter *adapter, if (!skb) return buffer; - skb_put(skb, rds_ring->skb_size); + if (length > rds_ring->skb_size) + skb_put(skb, rds_ring->skb_size); + else + skb_put(skb, length); if (pkt_offset) skb_pull(skb, pkt_offset); if (!qlcnic_check_loopback_buff(skb->data)) adapter->diag_cnt++; + else + dump_skb(skb); dev_kfree_skb_any(skb); adapter->stats.rx_pkts++; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 66eea59720209f85278cf223b6d723f879337aac..f047c7c48314ccd48c76df8d68babb5d24c796d5 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -28,6 +28,7 @@ #include "qlcnic.h" +#include #include #include #include @@ -45,10 +46,10 @@ char qlcnic_driver_name[] = "qlcnic"; static const char qlcnic_driver_string[] = "QLogic 1/10 GbE " "Converged/Intelligent Ethernet Driver v" QLCNIC_LINUX_VERSIONID; -static int port_mode = QLCNIC_PORT_MODE_AUTO_NEG; - -/* Default to restricted 1G auto-neg mode */ -static int wol_port_mode = 5; +static struct workqueue_struct *qlcnic_wq; +static int qlcnic_mac_learn; +module_param(qlcnic_mac_learn, int, 0644); +MODULE_PARM_DESC(qlcnic_mac_learn, "Mac Filter (0=disabled, 1=enabled)"); static int use_msi = 1; module_param(use_msi, int, 0644); @@ -94,7 +95,7 @@ static void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter); static void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter); static void qlcnic_idc_debug_info(struct qlcnic_adapter *adapter, u8 encoding); -static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter); +static void qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8); static int qlcnic_can_start_firmware(struct qlcnic_adapter *adapter); static irqreturn_t qlcnic_tmp_intr(int irq, void *data); @@ -103,13 +104,17 @@ static irqreturn_t qlcnic_msi_intr(int irq, void *data); static irqreturn_t qlcnic_msix_intr(int irq, void *data); static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev); -static void qlcnic_config_indev_addr(struct net_device *dev, unsigned long); +static void qlcnic_restore_indev_addr(struct net_device *dev, unsigned long); static int qlcnic_start_firmware(struct qlcnic_adapter *); +static void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); +static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter); static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *); static int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); static int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); static int qlcnicvf_start_firmware(struct qlcnic_adapter *); +static void qlcnic_set_netdev_features(struct qlcnic_adapter *, + struct qlcnic_esw_func_cfg *); /* PCI Device ID Table */ #define ENTRY(device) \ {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \ @@ -164,7 +169,7 @@ qlcnic_alloc_sds_rings(struct qlcnic_recv_context *recv_ctx, int count) recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL); - return (recv_ctx->sds_rings == NULL); + return recv_ctx->sds_rings == NULL; } static void @@ -255,40 +260,6 @@ static void qlcnic_clear_stats(struct qlcnic_adapter *adapter) memset(&adapter->stats, 0, sizeof(adapter->stats)); } -static void qlcnic_set_port_mode(struct qlcnic_adapter *adapter) -{ - u32 val, data; - - val = adapter->ahw.board_type; - if ((val == QLCNIC_BRDTYPE_P3_HMEZ) || - (val == QLCNIC_BRDTYPE_P3_XG_LOM)) { - if (port_mode == QLCNIC_PORT_MODE_802_3_AP) { - data = QLCNIC_PORT_MODE_802_3_AP; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } else if (port_mode == QLCNIC_PORT_MODE_XG) { - data = QLCNIC_PORT_MODE_XG; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_1G) { - data = QLCNIC_PORT_MODE_AUTO_NEG_1G; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } else if (port_mode == QLCNIC_PORT_MODE_AUTO_NEG_XG) { - data = QLCNIC_PORT_MODE_AUTO_NEG_XG; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } else { - data = QLCNIC_PORT_MODE_AUTO_NEG; - QLCWR32(adapter, QLCNIC_PORT_MODE_ADDR, data); - } - - if ((wol_port_mode != QLCNIC_PORT_MODE_802_3_AP) && - (wol_port_mode != QLCNIC_PORT_MODE_XG) && - (wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_1G) && - (wol_port_mode != QLCNIC_PORT_MODE_AUTO_NEG_XG)) { - wol_port_mode = QLCNIC_PORT_MODE_AUTO_NEG; - } - QLCWR32(adapter, QLCNIC_WOL_PORT_MODE, wol_port_mode); - } -} - static void qlcnic_set_msix_bit(struct pci_dev *pdev, int enable) { u32 control; @@ -320,7 +291,7 @@ qlcnic_read_mac_addr(struct qlcnic_adapter *adapter) struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - if (adapter->nic_ops->get_mac_addr(adapter, mac_addr) != 0) + if (qlcnic_get_mac_address(adapter, mac_addr) != 0) return -EIO; memcpy(netdev->dev_addr, mac_addr, ETH_ALEN); @@ -341,6 +312,9 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) struct qlcnic_adapter *adapter = netdev_priv(netdev); struct sockaddr *addr = p; + if ((adapter->flags & QLCNIC_MAC_OVERRIDE_DISABLED)) + return -EOPNOTSUPP; + if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; @@ -360,6 +334,13 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p) return 0; } +static void qlcnic_vlan_rx_register(struct net_device *netdev, + struct vlan_group *grp) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + adapter->vlgrp = grp; +} + static const struct net_device_ops qlcnic_netdev_ops = { .ndo_open = qlcnic_open, .ndo_stop = qlcnic_close, @@ -370,20 +351,19 @@ static const struct net_device_ops qlcnic_netdev_ops = { .ndo_set_mac_address = qlcnic_set_mac, .ndo_change_mtu = qlcnic_change_mtu, .ndo_tx_timeout = qlcnic_tx_timeout, + .ndo_vlan_rx_register = qlcnic_vlan_rx_register, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = qlcnic_poll_controller, #endif }; static struct qlcnic_nic_template qlcnic_ops = { - .get_mac_addr = qlcnic_get_mac_address, .config_bridged_mode = qlcnic_config_bridged_mode, .config_led = qlcnic_config_led, .start_firmware = qlcnic_start_firmware }; static struct qlcnic_nic_template qlcnic_vf_ops = { - .get_mac_addr = qlcnic_get_mac_address, .config_bridged_mode = qlcnicvf_config_bridged_mode, .config_led = qlcnicvf_config_led, .start_firmware = qlcnicvf_start_firmware @@ -474,7 +454,7 @@ static int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) { struct qlcnic_pci_info *pci_info; - int i, ret = 0, err; + int i, ret = 0; u8 pfn; pci_info = kcalloc(QLCNIC_MAX_PCI_FUNC, sizeof(*pci_info), GFP_KERNEL); @@ -484,14 +464,14 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) adapter->npars = kzalloc(sizeof(struct qlcnic_npar_info) * QLCNIC_MAX_PCI_FUNC, GFP_KERNEL); if (!adapter->npars) { - err = -ENOMEM; + ret = -ENOMEM; goto err_pci_info; } adapter->eswitch = kzalloc(sizeof(struct qlcnic_eswitch) * QLCNIC_NIU_MAX_XG_PORTS, GFP_KERNEL); if (!adapter->eswitch) { - err = -ENOMEM; + ret = -ENOMEM; goto err_npars; } @@ -503,10 +483,9 @@ qlcnic_init_pci_info(struct qlcnic_adapter *adapter) pfn = pci_info[i].id; if (pfn > QLCNIC_MAX_PCI_FUNC) return QL_STATUS_INVALID_PARAM; - adapter->npars[pfn].active = pci_info[i].active; - adapter->npars[pfn].type = pci_info[i].type; - adapter->npars[pfn].phy_port = pci_info[i].default_port; - adapter->npars[pfn].mac_learning = DEFAULT_MAC_LEARN; + adapter->npars[pfn].active = (u8)pci_info[i].active; + adapter->npars[pfn].type = (u8)pci_info[i].type; + adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port; adapter->npars[pfn].min_bw = pci_info[i].tx_min_bw; adapter->npars[pfn].max_bw = pci_info[i].tx_max_bw; } @@ -539,12 +518,10 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; /* If other drivers are not in use set their privilege level */ - ref_count = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); + ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); ret = qlcnic_api_lock(adapter); if (ret) goto err_lock; - if (QLC_DEV_CLR_REF_CNT(ref_count, adapter->ahw.pci_func)) - goto err_npar; if (qlcnic_config_npars) { for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { @@ -562,18 +539,16 @@ qlcnic_set_function_modes(struct qlcnic_adapter *adapter) adapter->ahw.pci_func)); } writel(data, priv_op); -err_npar: qlcnic_api_unlock(adapter); err_lock: return ret; } -static u32 -qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) +static void +qlcnic_check_vf(struct qlcnic_adapter *adapter) { void __iomem *msix_base_addr; void __iomem *priv_op; - struct qlcnic_info nic_info; u32 func; u32 msix_base; u32 op_mode, priv_level; @@ -588,20 +563,6 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE; adapter->ahw.pci_func = func; - if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) { - adapter->capabilities = nic_info.capabilities; - - if (adapter->capabilities & BIT_6) - adapter->flags |= QLCNIC_ESWITCH_ENABLED; - else - adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; - } - - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) { - adapter->nic_ops = &qlcnic_ops; - return adapter->fw_hal_version; - } - /* Determine function privilege level */ priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; op_mode = readl(priv_op); @@ -610,37 +571,14 @@ qlcnic_get_driver_mode(struct qlcnic_adapter *adapter) else priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); - switch (priv_level) { - case QLCNIC_MGMT_FUNC: - adapter->op_mode = QLCNIC_MGMT_FUNC; - adapter->nic_ops = &qlcnic_ops; - qlcnic_init_pci_info(adapter); - /* Set privilege level for other functions */ - qlcnic_set_function_modes(adapter); - dev_info(&adapter->pdev->dev, - "HAL Version: %d, Management function\n", - adapter->fw_hal_version); - break; - case QLCNIC_PRIV_FUNC: - adapter->op_mode = QLCNIC_PRIV_FUNC; - dev_info(&adapter->pdev->dev, - "HAL Version: %d, Privileged function\n", - adapter->fw_hal_version); - adapter->nic_ops = &qlcnic_ops; - break; - case QLCNIC_NON_PRIV_FUNC: + if (priv_level == QLCNIC_NON_PRIV_FUNC) { adapter->op_mode = QLCNIC_NON_PRIV_FUNC; dev_info(&adapter->pdev->dev, "HAL Version: %d Non Privileged function\n", adapter->fw_hal_version); adapter->nic_ops = &qlcnic_vf_ops; - break; - default: - dev_info(&adapter->pdev->dev, "Unknown function mode: %d\n", - priv_level); - return 0; - } - return adapter->fw_hal_version; + } else + adapter->nic_ops = &qlcnic_ops; } static int @@ -673,10 +611,7 @@ qlcnic_setup_pci_map(struct qlcnic_adapter *adapter) adapter->ahw.pci_base0 = mem_ptr0; adapter->ahw.pci_len0 = pci_len0; - if (!qlcnic_get_driver_mode(adapter)) { - iounmap(adapter->ahw.pci_base0); - return -EIO; - } + qlcnic_check_vf(adapter); adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter, QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func))); @@ -711,25 +646,7 @@ static void qlcnic_check_options(struct qlcnic_adapter *adapter) { u32 fw_major, fw_minor, fw_build; - char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; - char serial_num[32]; - int i, offset, val; - int *ptr32; struct pci_dev *pdev = adapter->pdev; - struct qlcnic_info nic_info; - adapter->driver_mismatch = 0; - - ptr32 = (int *)&serial_num; - offset = QLCNIC_FW_SERIAL_NUM_OFFSET; - for (i = 0; i < 8; i++) { - if (qlcnic_rom_fast_read(adapter, offset, &val) == -1) { - dev_err(&pdev->dev, "error reading board info\n"); - adapter->driver_mismatch = 1; - return; - } - ptr32[i] = cpu_to_le32(val); - offset += sizeof(u32); - } fw_major = QLCRD32(adapter, QLCNIC_FW_VERSION_MAJOR); fw_minor = QLCRD32(adapter, QLCNIC_FW_VERSION_MINOR); @@ -737,19 +654,9 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->fw_version = QLCNIC_VERSION_CODE(fw_major, fw_minor, fw_build); - if (adapter->portnum == 0) { - get_brd_name(adapter, brd_name); - - pr_info("%s: %s Board Chip rev 0x%x\n", - module_name(THIS_MODULE), - brd_name, adapter->ahw.revision_id); - } - dev_info(&pdev->dev, "firmware v%d.%d.%d\n", fw_major, fw_minor, fw_build); - adapter->flags &= ~QLCNIC_LRO_ENABLED; - if (adapter->ahw.port_type == QLCNIC_XGBE) { adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G; adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G; @@ -758,136 +665,364 @@ qlcnic_check_options(struct qlcnic_adapter *adapter) adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G; } - if (!qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func)) { - adapter->physical_port = nic_info.phys_port; - adapter->switch_mode = nic_info.switch_mode; - adapter->max_tx_ques = nic_info.max_tx_ques; - adapter->max_rx_ques = nic_info.max_rx_ques; - adapter->capabilities = nic_info.capabilities; - adapter->max_mac_filters = nic_info.max_mac_filters; - adapter->max_mtu = nic_info.max_mtu; - } - adapter->msix_supported = !!use_msi_x; adapter->rss_supported = !!use_msi_x; adapter->num_txd = MAX_CMD_DESCRIPTORS; - adapter->max_rds_rings = 2; + adapter->max_rds_rings = MAX_RDS_RINGS; +} + +static int +qlcnic_initialize_nic(struct qlcnic_adapter *adapter) +{ + int err; + struct qlcnic_info nic_info; + + err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func); + if (err) + return err; + + adapter->physical_port = (u8)nic_info.phys_port; + adapter->switch_mode = nic_info.switch_mode; + adapter->max_tx_ques = nic_info.max_tx_ques; + adapter->max_rx_ques = nic_info.max_rx_ques; + adapter->capabilities = nic_info.capabilities; + adapter->max_mac_filters = nic_info.max_mac_filters; + adapter->max_mtu = nic_info.max_mtu; + + if (adapter->capabilities & BIT_6) + adapter->flags |= QLCNIC_ESWITCH_ENABLED; + else + adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; + + return err; +} + +static void +qlcnic_set_vlan_config(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + if (esw_cfg->discard_tagged) + adapter->flags &= ~QLCNIC_TAGGING_ENABLED; + else + adapter->flags |= QLCNIC_TAGGING_ENABLED; + + if (esw_cfg->vlan_id) + adapter->pvid = esw_cfg->vlan_id; + else + adapter->pvid = 0; +} + +static void +qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + adapter->flags &= ~(QLCNIC_MACSPOOF | QLCNIC_MAC_OVERRIDE_DISABLED | + QLCNIC_PROMISC_DISABLED); + + if (esw_cfg->mac_anti_spoof) + adapter->flags |= QLCNIC_MACSPOOF; + + if (!esw_cfg->mac_override) + adapter->flags |= QLCNIC_MAC_OVERRIDE_DISABLED; + + if (!esw_cfg->promisc_mode) + adapter->flags |= QLCNIC_PROMISC_DISABLED; + + qlcnic_set_netdev_features(adapter, esw_cfg); +} + +static int +qlcnic_set_eswitch_port_config(struct qlcnic_adapter *adapter) +{ + struct qlcnic_esw_func_cfg esw_cfg; + + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return 0; + + esw_cfg.pci_func = adapter->ahw.pci_func; + if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg)) + return -EIO; + qlcnic_set_vlan_config(adapter, &esw_cfg); + qlcnic_set_eswitch_port_features(adapter, &esw_cfg); + + return 0; +} + +static void +qlcnic_set_netdev_features(struct qlcnic_adapter *adapter, + struct qlcnic_esw_func_cfg *esw_cfg) +{ + struct net_device *netdev = adapter->netdev; + unsigned long features, vlan_features; + + features = (NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM | NETIF_F_GRO); + vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM | + NETIF_F_IPV6_CSUM); + + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) { + features |= (NETIF_F_TSO | NETIF_F_TSO6); + vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6); + } + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) + features |= NETIF_F_LRO; + + if (esw_cfg->offload_flags & BIT_0) { + netdev->features |= features; + adapter->rx_csum = 1; + if (!(esw_cfg->offload_flags & BIT_1)) + netdev->features &= ~NETIF_F_TSO; + if (!(esw_cfg->offload_flags & BIT_2)) + netdev->features &= ~NETIF_F_TSO6; + } else { + netdev->features &= ~features; + adapter->rx_csum = 0; + } + + netdev->vlan_features = (features & vlan_features); +} + +static int +qlcnic_check_eswitch_mode(struct qlcnic_adapter *adapter) +{ + void __iomem *priv_op; + u32 op_mode, priv_level; + int err = 0; + + err = qlcnic_initialize_nic(adapter); + if (err) + return err; + + if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED) + return 0; + + priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE; + op_mode = readl(priv_op); + priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); + + if (op_mode == QLC_DEV_DRV_DEFAULT) + priv_level = QLCNIC_MGMT_FUNC; + else + priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func); + + if (adapter->flags & QLCNIC_ESWITCH_ENABLED) { + if (priv_level == QLCNIC_MGMT_FUNC) { + adapter->op_mode = QLCNIC_MGMT_FUNC; + err = qlcnic_init_pci_info(adapter); + if (err) + return err; + /* Set privilege level for other functions */ + qlcnic_set_function_modes(adapter); + dev_info(&adapter->pdev->dev, + "HAL Version: %d, Management function\n", + adapter->fw_hal_version); + } else if (priv_level == QLCNIC_PRIV_FUNC) { + adapter->op_mode = QLCNIC_PRIV_FUNC; + dev_info(&adapter->pdev->dev, + "HAL Version: %d, Privileged function\n", + adapter->fw_hal_version); + } + } + + adapter->flags |= QLCNIC_ADAPTER_INITIALIZED; + + return err; +} + +static int +qlcnic_set_default_offload_settings(struct qlcnic_adapter *adapter) +{ + struct qlcnic_esw_func_cfg esw_cfg; + struct qlcnic_npar_info *npar; + u8 i; + + if (adapter->need_fw_reset) + return 0; + + for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { + if (adapter->npars[i].type != QLCNIC_TYPE_NIC) + continue; + memset(&esw_cfg, 0, sizeof(struct qlcnic_esw_func_cfg)); + esw_cfg.pci_func = i; + esw_cfg.offload_flags = BIT_0; + esw_cfg.mac_override = BIT_0; + esw_cfg.promisc_mode = BIT_0; + if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) + esw_cfg.offload_flags |= (BIT_1 | BIT_2); + if (qlcnic_config_switch_port(adapter, &esw_cfg)) + return -EIO; + npar = &adapter->npars[i]; + npar->pvid = esw_cfg.vlan_id; + npar->mac_override = esw_cfg.mac_override; + npar->mac_anti_spoof = esw_cfg.mac_anti_spoof; + npar->discard_tagged = esw_cfg.discard_tagged; + npar->promisc_mode = esw_cfg.promisc_mode; + npar->offload_flags = esw_cfg.offload_flags; + } + + return 0; +} + +static int +qlcnic_reset_eswitch_config(struct qlcnic_adapter *adapter, + struct qlcnic_npar_info *npar, int pci_func) +{ + struct qlcnic_esw_func_cfg esw_cfg; + esw_cfg.op_mode = QLCNIC_PORT_DEFAULTS; + esw_cfg.pci_func = pci_func; + esw_cfg.vlan_id = npar->pvid; + esw_cfg.mac_override = npar->mac_override; + esw_cfg.discard_tagged = npar->discard_tagged; + esw_cfg.mac_anti_spoof = npar->mac_anti_spoof; + esw_cfg.offload_flags = npar->offload_flags; + esw_cfg.promisc_mode = npar->promisc_mode; + if (qlcnic_config_switch_port(adapter, &esw_cfg)) + return -EIO; + + esw_cfg.op_mode = QLCNIC_ADD_VLAN; + if (qlcnic_config_switch_port(adapter, &esw_cfg)) + return -EIO; + + return 0; } static int qlcnic_reset_npar_config(struct qlcnic_adapter *adapter) { - int i, err = 0; + int i, err; struct qlcnic_npar_info *npar; struct qlcnic_info nic_info; - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - !adapter->need_fw_reset) + if (!adapter->need_fw_reset) return 0; - if (adapter->op_mode == QLCNIC_MGMT_FUNC) { - /* Set the NPAR config data after FW reset */ - for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { - npar = &adapter->npars[i]; - if (npar->type != QLCNIC_TYPE_NIC) - continue; - err = qlcnic_get_nic_info(adapter, &nic_info, i); - if (err) - goto err_out; - nic_info.min_tx_bw = npar->min_bw; - nic_info.max_tx_bw = npar->max_bw; - err = qlcnic_set_nic_info(adapter, &nic_info); + /* Set the NPAR config data after FW reset */ + for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { + npar = &adapter->npars[i]; + if (npar->type != QLCNIC_TYPE_NIC) + continue; + err = qlcnic_get_nic_info(adapter, &nic_info, i); + if (err) + return err; + nic_info.min_tx_bw = npar->min_bw; + nic_info.max_tx_bw = npar->max_bw; + err = qlcnic_set_nic_info(adapter, &nic_info); + if (err) + return err; + + if (npar->enable_pm) { + err = qlcnic_config_port_mirroring(adapter, + npar->dest_npar, 1, i); if (err) - goto err_out; + return err; + } + err = qlcnic_reset_eswitch_config(adapter, npar, i); + if (err) + return err; + } + return 0; +} - if (npar->enable_pm) { - err = qlcnic_config_port_mirroring(adapter, - npar->dest_npar, 1, i); - if (err) - goto err_out; +static int qlcnic_check_npar_opertional(struct qlcnic_adapter *adapter) +{ + u8 npar_opt_timeo = QLCNIC_DEV_NPAR_OPER_TIMEO; + u32 npar_state; - } - npar->mac_learning = DEFAULT_MAC_LEARN; - npar->host_vlan_tag = 0; - npar->promisc_mode = 0; - npar->discard_tagged = 0; - npar->vlan_id = 0; - } + if (adapter->op_mode == QLCNIC_MGMT_FUNC) + return 0; + + npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + while (npar_state != QLCNIC_DEV_NPAR_OPER && --npar_opt_timeo) { + msleep(1000); + npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); } -err_out: + if (!npar_opt_timeo) { + dev_err(&adapter->pdev->dev, + "Waiting for NPAR state to opertional timeout\n"); + return -EIO; + } + return 0; +} + +static int +qlcnic_set_mgmt_operations(struct qlcnic_adapter *adapter) +{ + int err; + + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || + adapter->op_mode != QLCNIC_MGMT_FUNC) + return 0; + + err = qlcnic_set_default_offload_settings(adapter); + if (err) + return err; + + err = qlcnic_reset_npar_config(adapter); + if (err) + return err; + + qlcnic_dev_set_npar_ready(adapter); + return err; } static int qlcnic_start_firmware(struct qlcnic_adapter *adapter) { - int val, err, first_boot; + int err; err = qlcnic_can_start_firmware(adapter); if (err < 0) return err; else if (!err) - goto wait_init; - - first_boot = QLCRD32(adapter, QLCNIC_CAM_RAM(0x1fc)); - if (first_boot == 0x55555555) - /* This is the first boot after power up */ - QLCWR32(adapter, QLCNIC_CAM_RAM(0x1fc), QLCNIC_BDINFO_MAGIC); + goto check_fw_status; if (load_fw_file) qlcnic_request_firmware(adapter); else { - if (qlcnic_check_flash_fw_ver(adapter)) + err = qlcnic_check_flash_fw_ver(adapter); + if (err) goto err_out; adapter->fw_type = QLCNIC_FLASH_ROMIMAGE; } err = qlcnic_need_fw_reset(adapter); - if (err < 0) - goto err_out; if (err == 0) - goto wait_init; - - if (first_boot != 0x55555555) { - QLCWR32(adapter, CRB_CMDPEG_STATE, 0); - QLCWR32(adapter, CRB_RCVPEG_STATE, 0); - qlcnic_pinit_from_rom(adapter); - msleep(1); - } - - QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS1, 0); - QLCWR32(adapter, QLCNIC_PEG_HALT_STATUS2, 0); + goto check_fw_status; - qlcnic_set_port_mode(adapter); + err = qlcnic_pinit_from_rom(adapter); + if (err) + goto err_out; err = qlcnic_load_firmware(adapter); if (err) goto err_out; qlcnic_release_firmware(adapter); + QLCWR32(adapter, CRB_DRIVER_VERSION, QLCNIC_DRIVER_VERSION); - val = (_QLCNIC_LINUX_MAJOR << 16) - | ((_QLCNIC_LINUX_MINOR << 8)) - | (_QLCNIC_LINUX_SUBVERSION); - QLCWR32(adapter, CRB_DRIVER_VERSION, val); - -wait_init: - /* Handshake with the card before we register the devices. */ - err = qlcnic_init_firmware(adapter); +check_fw_status: + err = qlcnic_check_fw_status(adapter); if (err) goto err_out; QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); qlcnic_idc_debug_info(adapter, 1); - qlcnic_check_options(adapter); - if (qlcnic_reset_npar_config(adapter)) + err = qlcnic_check_eswitch_mode(adapter); + if (err) { + dev_err(&adapter->pdev->dev, + "Memory allocation failed for eswitch\n"); + goto err_out; + } + err = qlcnic_set_mgmt_operations(adapter); + if (err) goto err_out; - qlcnic_dev_set_npar_ready(adapter); + qlcnic_check_options(adapter); adapter->need_fw_reset = 0; qlcnic_release_firmware(adapter); @@ -896,6 +1031,7 @@ qlcnic_start_firmware(struct qlcnic_adapter *adapter) err_out: QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); dev_err(&adapter->pdev->dev, "Device state set to failed\n"); + qlcnic_release_firmware(adapter); return err; } @@ -979,6 +1115,8 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) return 0; + if (qlcnic_set_eswitch_port_config(adapter)) + return -EIO; if (qlcnic_fw_create_ctx(adapter)) return -EIO; @@ -998,7 +1136,7 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) qlcnic_config_intr_coalesce(adapter); - if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) + if (netdev->features & NETIF_F_LRO) qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); qlcnic_napi_enable(adapter); @@ -1041,6 +1179,9 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev) qlcnic_free_mac_list(adapter); + if (adapter->fhash.fnum) + qlcnic_delete_lb_filters(adapter); + qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); qlcnic_napi_disable(adapter); @@ -1277,7 +1418,7 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | NETIF_F_GRO); + NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_HW_VLAN_RX); netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); @@ -1296,12 +1437,8 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO) netdev->features |= NETIF_F_LRO; - netdev->irq = adapter->msix_entries[0].vector; - if (qlcnic_read_mac_addr(adapter)) - dev_warn(&pdev->dev, "failed to read mac addr\n"); - netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -1338,6 +1475,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int err; uint8_t revision_id; uint8_t pci_using_dac; + char brd_name[QLCNIC_MAX_BOARD_NAME_LEN]; err = pci_enable_device(pdev); if (err) @@ -1395,10 +1533,8 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_iounmap; } - if (qlcnic_read_mac_addr(adapter)) - dev_warn(&pdev->dev, "failed to read mac addr\n"); - - if (qlcnic_setup_idc_param(adapter)) + err = qlcnic_setup_idc_param(adapter); + if (err) goto err_out_iounmap; err = adapter->nic_ops->start_firmware(adapter); @@ -1407,6 +1543,17 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_decr_ref; } + if (qlcnic_read_mac_addr(adapter)) + dev_warn(&pdev->dev, "failed to read mac addr\n"); + + if (adapter->portnum == 0) { + get_brd_name(adapter, brd_name); + + pr_info("%s: %s Board Chip rev 0x%x\n", + module_name(THIS_MODULE), + brd_name, adapter->ahw.revision_id); + } + qlcnic_clear_stats(adapter); qlcnic_setup_intr(adapter); @@ -1430,6 +1577,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) break; } + qlcnic_alloc_lb_filters_mem(adapter); qlcnic_create_diag_entries(adapter); return 0; @@ -1438,7 +1586,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) qlcnic_teardown_intr(adapter); err_out_decr_ref: - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 0); err_out_iounmap: qlcnic_cleanup_pci_map(adapter); @@ -1477,10 +1625,12 @@ static void __devexit qlcnic_remove(struct pci_dev *pdev) if (adapter->eswitch != NULL) kfree(adapter->eswitch); - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 0); clear_bit(__QLCNIC_RESETTING, &adapter->state); + qlcnic_free_lb_filters_mem(adapter); + qlcnic_teardown_intr(adapter); qlcnic_remove_diag_entries(adapter); @@ -1509,7 +1659,7 @@ static int __qlcnic_shutdown(struct pci_dev *pdev) if (netif_running(netdev)) qlcnic_down(adapter, netdev); - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 0); clear_bit(__QLCNIC_RESETTING, &adapter->state); @@ -1573,7 +1723,7 @@ qlcnic_resume(struct pci_dev *pdev) if (err) goto done; - qlcnic_config_indev_addr(netdev, NETDEV_UP); + qlcnic_restore_indev_addr(netdev, NETDEV_UP); } done: netif_device_attach(netdev); @@ -1587,9 +1737,6 @@ static int qlcnic_open(struct net_device *netdev) struct qlcnic_adapter *adapter = netdev_priv(netdev); int err; - if (adapter->driver_mismatch) - return -EIO; - err = qlcnic_attach(adapter); if (err) return err; @@ -1618,6 +1765,121 @@ static int qlcnic_close(struct net_device *netdev) return 0; } +static void +qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) +{ + void *head; + int i; + + if (!qlcnic_mac_learn) + return; + + spin_lock_init(&adapter->mac_learn_lock); + + head = kcalloc(QLCNIC_LB_MAX_FILTERS, sizeof(struct hlist_head), + GFP_KERNEL); + if (!head) + return; + + adapter->fhash.fmax = QLCNIC_LB_MAX_FILTERS; + adapter->fhash.fhead = (struct hlist_head *)head; + + for (i = 0; i < adapter->fhash.fmax; i++) + INIT_HLIST_HEAD(&adapter->fhash.fhead[i]); +} + +static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) +{ + if (adapter->fhash.fmax && adapter->fhash.fhead) + kfree(adapter->fhash.fhead); + + adapter->fhash.fhead = NULL; + adapter->fhash.fmax = 0; +} + +static void qlcnic_change_filter(struct qlcnic_adapter *adapter, + u64 uaddr, __le16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) +{ + struct cmd_desc_type0 *hwdesc; + struct qlcnic_nic_req *req; + struct qlcnic_mac_req *mac_req; + struct qlcnic_vlan_req *vlan_req; + u32 producer; + u64 word; + + producer = tx_ring->producer; + hwdesc = &tx_ring->desc_head[tx_ring->producer]; + + req = (struct qlcnic_nic_req *)hwdesc; + memset(req, 0, sizeof(struct qlcnic_nic_req)); + req->qhdr = cpu_to_le64(QLCNIC_REQUEST << 23); + + word = QLCNIC_MAC_EVENT | ((u64)(adapter->portnum) << 16); + req->req_hdr = cpu_to_le64(word); + + mac_req = (struct qlcnic_mac_req *)&(req->words[0]); + mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD; + memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN); + + vlan_req = (struct qlcnic_vlan_req *)&req->words[1]; + vlan_req->vlan_id = vlan_id; + + tx_ring->producer = get_next_index(producer, tx_ring->num_desc); +} + +#define QLCNIC_MAC_HASH(MAC)\ + ((((MAC) & 0x70000) >> 0x10) | (((MAC) & 0x70000000000ULL) >> 0x25)) + +static void +qlcnic_send_filter(struct qlcnic_adapter *adapter, + struct qlcnic_host_tx_ring *tx_ring, + struct cmd_desc_type0 *first_desc, + struct sk_buff *skb) +{ + struct ethhdr *phdr = (struct ethhdr *)(skb->data); + struct qlcnic_filter *fil, *tmp_fil; + struct hlist_node *tmp_hnode, *n; + struct hlist_head *head; + u64 src_addr = 0; + __le16 vlan_id = 0; + u8 hindex; + + if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) + return; + + if (adapter->fhash.fnum >= adapter->fhash.fmax) + return; + + /* Only NPAR capable devices support vlan based learning*/ + if (adapter->flags & QLCNIC_ESWITCH_ENABLED) + vlan_id = first_desc->vlan_TCI; + memcpy(&src_addr, phdr->h_source, ETH_ALEN); + hindex = QLCNIC_MAC_HASH(src_addr) & (QLCNIC_LB_MAX_FILTERS - 1); + head = &(adapter->fhash.fhead[hindex]); + + hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { + if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) && + tmp_fil->vlan_id == vlan_id) { + tmp_fil->ftime = jiffies; + return; + } + } + + fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); + if (!fil) + return; + + qlcnic_change_filter(adapter, src_addr, vlan_id, tx_ring); + + fil->ftime = jiffies; + fil->vlan_id = vlan_id; + memcpy(fil->faddr, &src_addr, ETH_ALEN); + spin_lock(&adapter->mac_learn_lock); + hlist_add_head(&(fil->fnode), head); + adapter->fhash.fnum++; + spin_unlock(&adapter->mac_learn_lock); +} + static void qlcnic_tso_check(struct net_device *netdev, struct qlcnic_host_tx_ring *tx_ring, @@ -1626,26 +1888,14 @@ qlcnic_tso_check(struct net_device *netdev, { u8 opcode = TX_ETHER_PKT; __be16 protocol = skb->protocol; - u16 flags = 0, vid = 0; - int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0; + u16 flags = 0; + int copied, offset, copy_len, hdr_len = 0, tso = 0; struct cmd_desc_type0 *hwdesc; struct vlan_ethhdr *vh; struct qlcnic_adapter *adapter = netdev_priv(netdev); u32 producer = tx_ring->producer; - - if (protocol == cpu_to_be16(ETH_P_8021Q)) { - - vh = (struct vlan_ethhdr *)skb->data; - protocol = vh->h_vlan_encapsulated_proto; - flags = FLAGS_VLAN_TAGGED; - - } else if (vlan_tx_tag_present(skb)) { - - flags = FLAGS_VLAN_OOB; - vid = vlan_tx_tag_get(skb); - qlcnic_set_tx_vlan_tci(first_desc, vid); - vlan_oob = 1; - } + __le16 vlan_oob = first_desc->flags_opcode & + cpu_to_le16(FLAGS_VLAN_OOB); if (*(skb->data) & BIT_0) { flags |= BIT_0; @@ -1716,7 +1966,8 @@ qlcnic_tso_check(struct net_device *netdev, vh = (struct vlan_ethhdr *)((char *)hwdesc + 2); skb_copy_from_linear_data(skb, vh, 12); vh->h_vlan_proto = htons(ETH_P_8021Q); - vh->h_vlan_TCI = htons(vid); + vh->h_vlan_TCI = (__be16)swab16((u16)first_desc->vlan_TCI); + skb_copy_from_linear_data_offset(skb, 12, (char *)vh + 16, copy_len - 16); @@ -1796,11 +2047,47 @@ qlcnic_map_tx_skb(struct pci_dev *pdev, return -ENOMEM; } +static int +qlcnic_check_tx_tagging(struct qlcnic_adapter *adapter, + struct sk_buff *skb, + struct cmd_desc_type0 *first_desc) +{ + u8 opcode = 0; + u16 flags = 0; + __be16 protocol = skb->protocol; + struct vlan_ethhdr *vh; + + if (protocol == cpu_to_be16(ETH_P_8021Q)) { + vh = (struct vlan_ethhdr *)skb->data; + protocol = vh->h_vlan_encapsulated_proto; + flags = FLAGS_VLAN_TAGGED; + qlcnic_set_tx_vlan_tci(first_desc, ntohs(vh->h_vlan_TCI)); + } else if (vlan_tx_tag_present(skb)) { + flags = FLAGS_VLAN_OOB; + qlcnic_set_tx_vlan_tci(first_desc, vlan_tx_tag_get(skb)); + } + if (unlikely(adapter->pvid)) { + if (first_desc->vlan_TCI && + !(adapter->flags & QLCNIC_TAGGING_ENABLED)) + return -EIO; + if (first_desc->vlan_TCI && + (adapter->flags & QLCNIC_TAGGING_ENABLED)) + goto set_flags; + + flags = FLAGS_VLAN_OOB; + qlcnic_set_tx_vlan_tci(first_desc, adapter->pvid); + } +set_flags: + qlcnic_set_tx_flags_opcode(first_desc, flags, opcode); + return 0; +} + static inline void qlcnic_clear_cmddesc(u64 *desc) { desc[0] = 0ULL; desc[2] = 0ULL; + desc[7] = 0ULL; } netdev_tx_t @@ -1812,6 +2099,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) struct qlcnic_skb_frag *buffrag; struct cmd_desc_type0 *hwdesc, *first_desc; struct pci_dev *pdev; + struct ethhdr *phdr; int i, k; u32 producer; @@ -1823,6 +2111,13 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_BUSY; } + if (adapter->flags & QLCNIC_MACSPOOF) { + phdr = (struct ethhdr *)skb->data; + if (compare_ether_addr(phdr->h_source, + adapter->mac_addr)) + goto drop_packet; + } + frag_count = skb_shinfo(skb)->nr_frags + 1; /* 4 fragments per cmd des */ @@ -1844,6 +2139,12 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) pdev = adapter->pdev; + first_desc = hwdesc = &tx_ring->desc_head[producer]; + qlcnic_clear_cmddesc((u64 *)hwdesc); + + if (qlcnic_check_tx_tagging(adapter, skb, first_desc)) + goto drop_packet; + if (qlcnic_map_tx_skb(pdev, skb, pbuf)) { adapter->stats.tx_dma_map_error++; goto drop_packet; @@ -1852,9 +2153,6 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) pbuf->skb = skb; pbuf->frag_count = frag_count; - first_desc = hwdesc = &tx_ring->desc_head[producer]; - qlcnic_clear_cmddesc((u64 *)hwdesc); - qlcnic_set_tx_frags_len(first_desc, frag_count, skb->len); qlcnic_set_tx_port(first_desc, adapter->portnum); @@ -1893,6 +2191,9 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) qlcnic_tso_check(netdev, tx_ring, first_desc, skb); + if (qlcnic_mac_learn) + qlcnic_send_filter(adapter, tx_ring, first_desc, skb); + qlcnic_update_cmd_producer(adapter, tx_ring); adapter->stats.txbytes += skb->len; @@ -1947,14 +2248,14 @@ void qlcnic_advert_link_change(struct qlcnic_adapter *adapter, int linkup) struct net_device *netdev = adapter->netdev; if (adapter->ahw.linkup && !linkup) { - dev_info(&netdev->dev, "NIC Link is down\n"); + netdev_info(netdev, "NIC Link is down\n"); adapter->ahw.linkup = 0; if (netif_running(netdev)) { netif_carrier_off(netdev); netif_stop_queue(netdev); } } else if (!adapter->ahw.linkup && linkup) { - dev_info(&netdev->dev, "NIC Link is up\n"); + netdev_info(netdev, "NIC Link is up\n"); adapter->ahw.linkup = 1; if (netif_running(netdev)) { netif_carrier_on(netdev); @@ -2258,18 +2559,22 @@ qlcnic_clr_drv_state(struct qlcnic_adapter *adapter) } static void -qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter) +qlcnic_clr_all_drv_state(struct qlcnic_adapter *adapter, u8 failed) { u32 val; if (qlcnic_api_lock(adapter)) goto err; - val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); + val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); QLC_DEV_CLR_REF_CNT(val, adapter->portnum); - QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); + QLCWR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); - if (!(val & 0x11111111)) + if (failed) { + QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_FAILED); + dev_info(&adapter->pdev->dev, + "Device state set to Failed. Please Reboot\n"); + } else if (!(val & 0x11111111)) QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_COLD); val = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); @@ -2290,7 +2595,7 @@ qlcnic_check_drv_state(struct qlcnic_adapter *adapter) int act, state; state = QLCRD32(adapter, QLCNIC_CRB_DRV_STATE); - act = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); + act = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); if (((state & 0x11111111) == (act & 0x11111111)) || ((act & 0x11111111) == ((state >> 1) & 0x11111111))) @@ -2325,10 +2630,10 @@ qlcnic_can_start_firmware(struct qlcnic_adapter *adapter) if (qlcnic_api_lock(adapter)) return -1; - val = QLCRD32(adapter, QLCNIC_CRB_DEV_REF_COUNT); + val = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE); if (!(val & (1 << (portnum * 4)))) { QLC_DEV_SET_REF_CNT(val, portnum); - QLCWR32(adapter, QLCNIC_CRB_DEV_REF_COUNT, val); + QLCWR32(adapter, QLCNIC_CRB_DRV_ACTIVE, val); } prev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); @@ -2403,13 +2708,14 @@ qlcnic_fwinit_work(struct work_struct *work) { struct qlcnic_adapter *adapter = container_of(work, struct qlcnic_adapter, fw_work.work); - u32 dev_state = 0xf, npar_state; + u32 dev_state = 0xf; if (qlcnic_api_lock(adapter)) goto err_ret; dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (dev_state == QLCNIC_DEV_QUISCENT) { + if (dev_state == QLCNIC_DEV_QUISCENT || + dev_state == QLCNIC_DEV_NEED_QUISCENT) { qlcnic_api_unlock(adapter); qlcnic_schedule_work(adapter, qlcnic_fwinit_work, FW_POLL_DELAY * 2); @@ -2417,16 +2723,8 @@ qlcnic_fwinit_work(struct work_struct *work) } if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) { - npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); - if (npar_state == QLCNIC_DEV_NPAR_RDY) { - qlcnic_api_unlock(adapter); - goto wait_npar; - } else { - qlcnic_schedule_work(adapter, qlcnic_fwinit_work, - FW_POLL_DELAY); - qlcnic_api_unlock(adapter); - return; - } + qlcnic_api_unlock(adapter); + goto wait_npar; } if (adapter->fw_wait_cnt++ > adapter->reset_ack_timeo) { @@ -2439,18 +2737,6 @@ qlcnic_fwinit_work(struct work_struct *work) skip_ack_check: dev_state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (dev_state == QLCNIC_DEV_NEED_QUISCENT) { - QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, - QLCNIC_DEV_QUISCENT); - qlcnic_schedule_work(adapter, qlcnic_fwinit_work, - FW_POLL_DELAY * 2); - QLCDB(adapter, DRV, "Quiscing the driver\n"); - qlcnic_idc_debug_info(adapter, 0); - - qlcnic_api_unlock(adapter); - return; - } - if (dev_state == QLCNIC_DEV_NEED_RESET) { QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING); @@ -2463,6 +2749,7 @@ qlcnic_fwinit_work(struct work_struct *work) if (!adapter->nic_ops->start_firmware(adapter)) { qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); + adapter->fw_wait_cnt = 0; return; } goto err_ret; @@ -2475,27 +2762,25 @@ qlcnic_fwinit_work(struct work_struct *work) QLCDB(adapter, HW, "Func waiting: Device state=%u\n", dev_state); switch (dev_state) { - case QLCNIC_DEV_QUISCENT: - case QLCNIC_DEV_NEED_QUISCENT: - case QLCNIC_DEV_NEED_RESET: - qlcnic_schedule_work(adapter, - qlcnic_fwinit_work, FW_POLL_DELAY); - return; - case QLCNIC_DEV_FAILED: - break; - - default: + case QLCNIC_DEV_READY: if (!adapter->nic_ops->start_firmware(adapter)) { qlcnic_schedule_work(adapter, qlcnic_attach_work, 0); + adapter->fw_wait_cnt = 0; return; } + case QLCNIC_DEV_FAILED: + break; + default: + qlcnic_schedule_work(adapter, + qlcnic_fwinit_work, FW_POLL_DELAY); + return; } err_ret: dev_err(&adapter->pdev->dev, "Fwinit work failed state=%u " "fw_wait_cnt=%u\n", dev_state, adapter->fw_wait_cnt); netif_device_attach(adapter->netdev); - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 0); } static void @@ -2508,7 +2793,12 @@ qlcnic_detach_work(struct work_struct *work) netif_device_detach(netdev); - qlcnic_down(adapter, netdev); + /* Dont grab rtnl lock during Quiscent mode */ + if (adapter->dev_state == QLCNIC_DEV_NEED_QUISCENT) { + if (netif_running(netdev)) + __qlcnic_down(adapter, netdev); + } else + qlcnic_down(adapter, netdev); status = QLCRD32(adapter, QLCNIC_PEG_HALT_STATUS1); @@ -2531,8 +2821,78 @@ qlcnic_detach_work(struct work_struct *work) dev_err(&adapter->pdev->dev, "detach failed; status=%d temp=%d\n", status, adapter->temp); netif_device_attach(netdev); - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 1); +} + +/*Transit NPAR state to NON Operational */ +static void +qlcnic_set_npar_non_operational(struct qlcnic_adapter *adapter) +{ + u32 state; + + state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + if (state == QLCNIC_DEV_NPAR_NON_OPER) + return; + + if (qlcnic_api_lock(adapter)) + return; + QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER); + qlcnic_api_unlock(adapter); +} + +/* Caller should held RESETTING bit. + * This should be call in sync with qlcnic_request_quiscent_mode. + */ +void qlcnic_clear_quiscent_mode(struct qlcnic_adapter *adapter) +{ + qlcnic_clr_drv_state(adapter); + qlcnic_api_lock(adapter); + QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_READY); + qlcnic_api_unlock(adapter); +} + +/* Caller should held RESETTING bit. + */ +int qlcnic_request_quiscent_mode(struct qlcnic_adapter *adapter) +{ + u8 timeo = adapter->dev_init_timeo / 2; + u32 state; + + if (qlcnic_api_lock(adapter)) + return -EIO; + + state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); + if (state != QLCNIC_DEV_READY) + return -EIO; + + QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_NEED_QUISCENT); + qlcnic_api_unlock(adapter); + QLCDB(adapter, DRV, "NEED QUISCENT state set\n"); + qlcnic_idc_debug_info(adapter, 0); + + qlcnic_set_drv_state(adapter, QLCNIC_DEV_NEED_QUISCENT); + + do { + msleep(2000); + state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); + if (state == QLCNIC_DEV_QUISCENT) + return 0; + if (!qlcnic_check_drv_state(adapter)) { + if (qlcnic_api_lock(adapter)) + return -EIO; + QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, + QLCNIC_DEV_QUISCENT); + qlcnic_api_unlock(adapter); + QLCDB(adapter, DRV, "QUISCENT mode set\n"); + return 0; + } + } while (--timeo); + dev_err(&adapter->pdev->dev, "Failed to quiesce device, DRV_STATE=%08x" + " DRV_ACTIVE=%08x\n", QLCRD32(adapter, QLCNIC_CRB_DRV_STATE), + QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE)); + qlcnic_clear_quiscent_mode(adapter); + return -EIO; } /*Transit to RESET state from READY state only */ @@ -2553,6 +2913,7 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) qlcnic_idc_debug_info(adapter, 0); } + QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_NON_OPER); qlcnic_api_unlock(adapter); } @@ -2560,21 +2921,11 @@ qlcnic_dev_request_reset(struct qlcnic_adapter *adapter) static void qlcnic_dev_set_npar_ready(struct qlcnic_adapter *adapter) { - u32 state; - - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - adapter->op_mode == QLCNIC_NON_PRIV_FUNC) - return; if (qlcnic_api_lock(adapter)) return; - state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); - - if (state != QLCNIC_DEV_NPAR_RDY) { - QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, - QLCNIC_DEV_NPAR_RDY); - QLCDB(adapter, DRV, "NPAR READY state set\n"); - } + QLCWR32(adapter, QLCNIC_CRB_DEV_NPAR_STATE, QLCNIC_DEV_NPAR_OPER); + QLCDB(adapter, DRV, "NPAR operational state set\n"); qlcnic_api_unlock(adapter); } @@ -2587,7 +2938,8 @@ qlcnic_schedule_work(struct qlcnic_adapter *adapter, return; INIT_DELAYED_WORK(&adapter->fw_work, func); - schedule_delayed_work(&adapter->fw_work, round_jiffies_relative(delay)); + queue_delayed_work(qlcnic_wq, &adapter->fw_work, + round_jiffies_relative(delay)); } static void @@ -2605,12 +2957,26 @@ qlcnic_attach_work(struct work_struct *work) struct qlcnic_adapter *adapter = container_of(work, struct qlcnic_adapter, fw_work.work); struct net_device *netdev = adapter->netdev; + u32 npar_state; + if (adapter->op_mode != QLCNIC_MGMT_FUNC) { + npar_state = QLCRD32(adapter, QLCNIC_CRB_DEV_NPAR_STATE); + if (adapter->fw_wait_cnt++ > QLCNIC_DEV_NPAR_OPER_TIMEO) + qlcnic_clr_all_drv_state(adapter, 0); + else if (npar_state != QLCNIC_DEV_NPAR_OPER) + qlcnic_schedule_work(adapter, qlcnic_attach_work, + FW_POLL_DELAY); + else + goto attach; + QLCDB(adapter, DRV, "Waiting for NPAR state to operational\n"); + return; + } +attach: if (netif_running(netdev)) { if (qlcnic_up(adapter, netdev)) goto done; - qlcnic_config_indev_addr(netdev, NETDEV_UP); + qlcnic_restore_indev_addr(netdev, NETDEV_UP); } done: @@ -2626,7 +2992,7 @@ qlcnic_attach_work(struct work_struct *work) static int qlcnic_check_health(struct qlcnic_adapter *adapter) { - u32 state = 0, heartbit; + u32 state = 0, heartbeat; struct net_device *netdev = adapter->netdev; if (qlcnic_check_temp(adapter)) @@ -2636,12 +3002,15 @@ qlcnic_check_health(struct qlcnic_adapter *adapter) qlcnic_dev_request_reset(adapter); state = QLCRD32(adapter, QLCNIC_CRB_DEV_STATE); - if (state == QLCNIC_DEV_NEED_RESET || state == QLCNIC_DEV_NEED_QUISCENT) + if (state == QLCNIC_DEV_NEED_RESET) { + qlcnic_set_npar_non_operational(adapter); adapter->need_fw_reset = 1; + } else if (state == QLCNIC_DEV_NEED_QUISCENT) + goto detach; - heartbit = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); - if (heartbit != adapter->heartbit) { - adapter->heartbit = heartbit; + heartbeat = QLCRD32(adapter, QLCNIC_PEG_ALIVE_COUNTER); + if (heartbeat != adapter->heartbeat) { + adapter->heartbeat = heartbeat; adapter->fw_fail_cnt = 0; if (adapter->need_fw_reset) goto detach; @@ -2692,6 +3061,9 @@ qlcnic_fw_poll_work(struct work_struct *work) if (qlcnic_check_health(adapter)) return; + if (adapter->fhash.fnum) + qlcnic_prune_lb_filters(adapter); + reschedule: qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY); } @@ -2738,7 +3110,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev) if (qlcnic_api_lock(adapter)) return -EINVAL; - if (first_func) { + if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC && first_func) { adapter->need_fw_reset = 1; set_bit(__QLCNIC_START_FW, &adapter->state); QLCWR32(adapter, QLCNIC_CRB_DEV_STATE, QLCNIC_DEV_INITIALIZING); @@ -2756,7 +3128,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev) if (netif_running(netdev)) { err = qlcnic_attach(adapter); if (err) { - qlcnic_clr_all_drv_state(adapter); + qlcnic_clr_all_drv_state(adapter, 1); clear_bit(__QLCNIC_AER, &adapter->state); netif_device_attach(netdev); return err; @@ -2766,7 +3138,7 @@ static int qlcnic_attach_func(struct pci_dev *pdev) if (err) goto done; - qlcnic_config_indev_addr(netdev, NETDEV_UP); + qlcnic_restore_indev_addr(netdev, NETDEV_UP); } done: netif_device_attach(netdev); @@ -2822,7 +3194,6 @@ static void qlcnic_io_resume(struct pci_dev *pdev) FW_POLL_DELAY); } - static int qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) { @@ -2832,8 +3203,20 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) if (err) return err; + err = qlcnic_check_npar_opertional(adapter); + if (err) + return err; + + err = qlcnic_initialize_nic(adapter); + if (err) + return err; + qlcnic_check_options(adapter); + err = qlcnic_set_eswitch_port_config(adapter); + if (err) + return err; + adapter->need_fw_reset = 0; return err; @@ -3093,9 +3476,6 @@ validate_pm_config(struct qlcnic_adapter *adapter, if (adapter->npars[dest_pci_func].type != QLCNIC_TYPE_NIC) return QL_STATUS_INVALID_PARAM; - if (!IS_VALID_MODE(pm_cfg[i].action)) - return QL_STATUS_INVALID_PARAM; - s_esw_id = adapter->npars[src_pci_func].phy_port; d_esw_id = adapter->npars[dest_pci_func].phy_port; @@ -3129,7 +3509,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj, return ret; for (i = 0; i < count; i++) { pci_func = pm_cfg[i].pci_func; - action = pm_cfg[i].action; + action = !!pm_cfg[i].action; id = adapter->npars[pci_func].phy_port; ret = qlcnic_config_port_mirroring(adapter, id, action, pci_func); @@ -3140,7 +3520,7 @@ qlcnic_sysfs_write_pm_config(struct file *filp, struct kobject *kobj, for (i = 0; i < count; i++) { pci_func = pm_cfg[i].pci_func; id = adapter->npars[pci_func].phy_port; - adapter->npars[pci_func].enable_pm = pm_cfg[i].action; + adapter->npars[pci_func].enable_pm = !!pm_cfg[i].action; adapter->npars[pci_func].dest_npar = id; } return size; @@ -3172,30 +3552,46 @@ qlcnic_sysfs_read_pm_config(struct file *filp, struct kobject *kobj, static int validate_esw_config(struct qlcnic_adapter *adapter, - struct qlcnic_esw_func_cfg *esw_cfg, int count) + struct qlcnic_esw_func_cfg *esw_cfg, int count) { + u32 op_mode; u8 pci_func; int i; + op_mode = readl(adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE); + for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; if (pci_func >= QLCNIC_MAX_PCI_FUNC) return QL_STATUS_INVALID_PARAM; - if (adapter->npars[i].type != QLCNIC_TYPE_NIC) - return QL_STATUS_INVALID_PARAM; + if (adapter->op_mode == QLCNIC_MGMT_FUNC) + if (adapter->npars[pci_func].type != QLCNIC_TYPE_NIC) + return QL_STATUS_INVALID_PARAM; - if (esw_cfg->host_vlan_tag == 1) + switch (esw_cfg[i].op_mode) { + case QLCNIC_PORT_DEFAULTS: + if (QLC_DEV_GET_DRV(op_mode, pci_func) != + QLCNIC_NON_PRIV_FUNC) { + esw_cfg[i].mac_anti_spoof = 0; + esw_cfg[i].mac_override = 1; + esw_cfg[i].promisc_mode = 1; + } + break; + case QLCNIC_ADD_VLAN: if (!IS_VALID_VLAN(esw_cfg[i].vlan_id)) return QL_STATUS_INVALID_PARAM; - - if (!IS_VALID_MODE(esw_cfg[i].promisc_mode) - || !IS_VALID_MODE(esw_cfg[i].host_vlan_tag) - || !IS_VALID_MODE(esw_cfg[i].mac_learning) - || !IS_VALID_MODE(esw_cfg[i].discard_tagged)) + if (!esw_cfg[i].op_type) + return QL_STATUS_INVALID_PARAM; + break; + case QLCNIC_DEL_VLAN: + if (!esw_cfg[i].op_type) + return QL_STATUS_INVALID_PARAM; + break; + default: return QL_STATUS_INVALID_PARAM; + } } - return 0; } @@ -3206,8 +3602,9 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, struct device *dev = container_of(kobj, struct device, kobj); struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_esw_func_cfg *esw_cfg; + struct qlcnic_npar_info *npar; int count, rem, i, ret; - u8 id, pci_func; + u8 pci_func, op_mode = 0; count = size / sizeof(struct qlcnic_esw_func_cfg); rem = size % sizeof(struct qlcnic_esw_func_cfg); @@ -3220,30 +3617,55 @@ qlcnic_sysfs_write_esw_config(struct file *file, struct kobject *kobj, return ret; for (i = 0; i < count; i++) { - pci_func = esw_cfg[i].pci_func; - id = adapter->npars[pci_func].phy_port; - ret = qlcnic_config_switch_port(adapter, id, - esw_cfg[i].host_vlan_tag, - esw_cfg[i].discard_tagged, - esw_cfg[i].promisc_mode, - esw_cfg[i].mac_learning, - esw_cfg[i].pci_func, - esw_cfg[i].vlan_id); - if (ret) - return ret; + if (adapter->op_mode == QLCNIC_MGMT_FUNC) + if (qlcnic_config_switch_port(adapter, &esw_cfg[i])) + return QL_STATUS_INVALID_PARAM; + + if (adapter->ahw.pci_func != esw_cfg[i].pci_func) + continue; + + op_mode = esw_cfg[i].op_mode; + qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]); + esw_cfg[i].op_mode = op_mode; + esw_cfg[i].pci_func = adapter->ahw.pci_func; + + switch (esw_cfg[i].op_mode) { + case QLCNIC_PORT_DEFAULTS: + qlcnic_set_eswitch_port_features(adapter, &esw_cfg[i]); + break; + case QLCNIC_ADD_VLAN: + qlcnic_set_vlan_config(adapter, &esw_cfg[i]); + break; + case QLCNIC_DEL_VLAN: + esw_cfg[i].vlan_id = 0; + qlcnic_set_vlan_config(adapter, &esw_cfg[i]); + break; + } } + if (adapter->op_mode != QLCNIC_MGMT_FUNC) + goto out; + for (i = 0; i < count; i++) { pci_func = esw_cfg[i].pci_func; - adapter->npars[pci_func].promisc_mode = esw_cfg[i].promisc_mode; - adapter->npars[pci_func].mac_learning = esw_cfg[i].mac_learning; - adapter->npars[pci_func].vlan_id = esw_cfg[i].vlan_id; - adapter->npars[pci_func].discard_tagged = - esw_cfg[i].discard_tagged; - adapter->npars[pci_func].host_vlan_tag = - esw_cfg[i].host_vlan_tag; + npar = &adapter->npars[pci_func]; + switch (esw_cfg[i].op_mode) { + case QLCNIC_PORT_DEFAULTS: + npar->promisc_mode = esw_cfg[i].promisc_mode; + npar->mac_override = esw_cfg[i].mac_override; + npar->offload_flags = esw_cfg[i].offload_flags; + npar->mac_anti_spoof = esw_cfg[i].mac_anti_spoof; + npar->discard_tagged = esw_cfg[i].discard_tagged; + break; + case QLCNIC_ADD_VLAN: + npar->pvid = esw_cfg[i].vlan_id; + break; + case QLCNIC_DEL_VLAN: + npar->pvid = 0; + break; + } } - +out: return size; } @@ -3254,7 +3676,7 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj, struct device *dev = container_of(kobj, struct device, kobj); struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_esw_func_cfg esw_cfg[QLCNIC_MAX_PCI_FUNC]; - int i; + u8 i; if (size != sizeof(esw_cfg)) return QL_STATUS_INVALID_PARAM; @@ -3262,12 +3684,9 @@ qlcnic_sysfs_read_esw_config(struct file *file, struct kobject *kobj, for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) { if (adapter->npars[i].type != QLCNIC_TYPE_NIC) continue; - - esw_cfg[i].host_vlan_tag = adapter->npars[i].host_vlan_tag; - esw_cfg[i].promisc_mode = adapter->npars[i].promisc_mode; - esw_cfg[i].discard_tagged = adapter->npars[i].discard_tagged; - esw_cfg[i].vlan_id = adapter->npars[i].vlan_id; - esw_cfg[i].mac_learning = adapter->npars[i].mac_learning; + esw_cfg[i].pci_func = i; + if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i])) + return QL_STATUS_INVALID_PARAM; } memcpy(buf, &esw_cfg, size); @@ -3357,7 +3776,7 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj, return ret; np_cfg[i].pci_func = i; - np_cfg[i].op_mode = nic_info.op_mode; + np_cfg[i].op_mode = (u8)nic_info.op_mode; np_cfg[i].port_num = nic_info.phys_port; np_cfg[i].fw_capab = nic_info.capabilities; np_cfg[i].min_bw = nic_info.min_tx_bw ; @@ -3369,6 +3788,115 @@ qlcnic_sysfs_read_npar_config(struct file *file, struct kobject *kobj, return size; } +static ssize_t +qlcnic_sysfs_get_port_stats(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + struct qlcnic_esw_statistics port_stats; + int ret; + + if (size != sizeof(struct qlcnic_esw_statistics)) + return QL_STATUS_INVALID_PARAM; + + if (offset >= QLCNIC_MAX_PCI_FUNC) + return QL_STATUS_INVALID_PARAM; + + memset(&port_stats, 0, size); + ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER, + &port_stats.rx); + if (ret) + return ret; + + ret = qlcnic_get_port_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER, + &port_stats.tx); + if (ret) + return ret; + + memcpy(buf, &port_stats, size); + return size; +} + +static ssize_t +qlcnic_sysfs_get_esw_stats(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + struct qlcnic_esw_statistics esw_stats; + int ret; + + if (size != sizeof(struct qlcnic_esw_statistics)) + return QL_STATUS_INVALID_PARAM; + + if (offset >= QLCNIC_NIU_MAX_XG_PORTS) + return QL_STATUS_INVALID_PARAM; + + memset(&esw_stats, 0, size); + ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_RX_COUNTER, + &esw_stats.rx); + if (ret) + return ret; + + ret = qlcnic_get_eswitch_stats(adapter, offset, QLCNIC_QUERY_TX_COUNTER, + &esw_stats.tx); + if (ret) + return ret; + + memcpy(buf, &esw_stats, size); + return size; +} + +static ssize_t +qlcnic_sysfs_clear_esw_stats(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + int ret; + + if (offset >= QLCNIC_NIU_MAX_XG_PORTS) + return QL_STATUS_INVALID_PARAM; + + ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset, + QLCNIC_QUERY_RX_COUNTER); + if (ret) + return ret; + + ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_ESWITCH, offset, + QLCNIC_QUERY_TX_COUNTER); + if (ret) + return ret; + + return size; +} + +static ssize_t +qlcnic_sysfs_clear_port_stats(struct file *file, struct kobject *kobj, + struct bin_attribute *attr, char *buf, loff_t offset, size_t size) +{ + + struct device *dev = container_of(kobj, struct device, kobj); + struct qlcnic_adapter *adapter = dev_get_drvdata(dev); + int ret; + + if (offset >= QLCNIC_MAX_PCI_FUNC) + return QL_STATUS_INVALID_PARAM; + + ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, + QLCNIC_QUERY_RX_COUNTER); + if (ret) + return ret; + + ret = qlcnic_clear_esw_stats(adapter, QLCNIC_STATS_PORT, offset, + QLCNIC_QUERY_TX_COUNTER); + if (ret) + return ret; + + return size; +} + static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t offset, size_t size) @@ -3418,6 +3946,20 @@ static struct bin_attribute bin_attr_pci_config = { .write = NULL, }; +static struct bin_attribute bin_attr_port_stats = { + .attr = {.name = "port_stats", .mode = (S_IRUGO | S_IWUSR)}, + .size = 0, + .read = qlcnic_sysfs_get_port_stats, + .write = qlcnic_sysfs_clear_port_stats, +}; + +static struct bin_attribute bin_attr_esw_stats = { + .attr = {.name = "esw_stats", .mode = (S_IRUGO | S_IWUSR)}, + .size = 0, + .read = qlcnic_sysfs_get_esw_stats, + .write = qlcnic_sysfs_clear_esw_stats, +}; + static struct bin_attribute bin_attr_esw_config = { .attr = {.name = "esw_config", .mode = (S_IRUGO | S_IWUSR)}, .size = 0, @@ -3457,6 +3999,9 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) { struct device *dev = &adapter->pdev->dev; + if (device_create_bin_file(dev, &bin_attr_port_stats)) + dev_info(dev, "failed to create port stats sysfs entry"); + if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) return; if (device_create_file(dev, &dev_attr_diag_mode)) @@ -3465,18 +4010,20 @@ qlcnic_create_diag_entries(struct qlcnic_adapter *adapter) dev_info(dev, "failed to create crb sysfs entry\n"); if (device_create_bin_file(dev, &bin_attr_mem)) dev_info(dev, "failed to create mem sysfs entry\n"); - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - adapter->op_mode != QLCNIC_MGMT_FUNC) + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return; + if (device_create_bin_file(dev, &bin_attr_esw_config)) + dev_info(dev, "failed to create esw config sysfs entry"); + if (adapter->op_mode != QLCNIC_MGMT_FUNC) return; if (device_create_bin_file(dev, &bin_attr_pci_config)) dev_info(dev, "failed to create pci config sysfs entry"); if (device_create_bin_file(dev, &bin_attr_npar_config)) dev_info(dev, "failed to create npar config sysfs entry"); - if (device_create_bin_file(dev, &bin_attr_esw_config)) - dev_info(dev, "failed to create esw config sysfs entry"); if (device_create_bin_file(dev, &bin_attr_pm_config)) dev_info(dev, "failed to create pm config sysfs entry"); - + if (device_create_bin_file(dev, &bin_attr_esw_stats)) + dev_info(dev, "failed to create eswitch stats sysfs entry"); } static void @@ -3484,18 +4031,22 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) { struct device *dev = &adapter->pdev->dev; + device_remove_bin_file(dev, &bin_attr_port_stats); + if (adapter->op_mode == QLCNIC_NON_PRIV_FUNC) return; device_remove_file(dev, &dev_attr_diag_mode); device_remove_bin_file(dev, &bin_attr_crb); device_remove_bin_file(dev, &bin_attr_mem); - if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) || - adapter->op_mode != QLCNIC_MGMT_FUNC) + if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED)) + return; + device_remove_bin_file(dev, &bin_attr_esw_config); + if (adapter->op_mode != QLCNIC_MGMT_FUNC) return; device_remove_bin_file(dev, &bin_attr_pci_config); device_remove_bin_file(dev, &bin_attr_npar_config); - device_remove_bin_file(dev, &bin_attr_esw_config); device_remove_bin_file(dev, &bin_attr_pm_config); + device_remove_bin_file(dev, &bin_attr_esw_stats); } #ifdef CONFIG_INET @@ -3503,10 +4054,10 @@ qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter) #define is_qlcnic_netdev(dev) (dev->netdev_ops == &qlcnic_netdev_ops) static void -qlcnic_config_indev_addr(struct net_device *dev, unsigned long event) +qlcnic_config_indev_addr(struct qlcnic_adapter *adapter, + struct net_device *dev, unsigned long event) { struct in_device *indev; - struct qlcnic_adapter *adapter = netdev_priv(dev); indev = in_dev_get(dev); if (!indev) @@ -3530,6 +4081,27 @@ qlcnic_config_indev_addr(struct net_device *dev, unsigned long event) in_dev_put(indev); } +static void +qlcnic_restore_indev_addr(struct net_device *netdev, unsigned long event) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + struct net_device *dev; + u16 vid; + + qlcnic_config_indev_addr(adapter, netdev, event); + + if (!adapter->vlgrp) + return; + + for (vid = 0; vid < VLAN_N_VID; vid++) { + dev = vlan_group_get_device(adapter->vlgrp, vid); + if (!dev) + continue; + + qlcnic_config_indev_addr(adapter, dev, event); + } +} + static int qlcnic_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) { @@ -3556,7 +4128,7 @@ static int qlcnic_netdev_event(struct notifier_block *this, if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) goto done; - qlcnic_config_indev_addr(dev, event); + qlcnic_config_indev_addr(adapter, dev, event); done: return NOTIFY_DONE; } @@ -3573,7 +4145,7 @@ qlcnic_inetaddr_event(struct notifier_block *this, dev = ifa->ifa_dev ? ifa->ifa_dev->dev : NULL; recheck: - if (dev == NULL || !netif_running(dev)) + if (dev == NULL) goto done; if (dev->priv_flags & IFF_802_1Q_VLAN) { @@ -3616,7 +4188,7 @@ static struct notifier_block qlcnic_inetaddr_cb = { }; #else static void -qlcnic_config_indev_addr(struct net_device *dev, unsigned long event) +qlcnic_restore_indev_addr(struct net_device *dev, unsigned long event) { } #endif static struct pci_error_handlers qlcnic_err_handler = { @@ -3645,6 +4217,12 @@ static int __init qlcnic_init_module(void) printk(KERN_INFO "%s\n", qlcnic_driver_string); + qlcnic_wq = create_singlethread_workqueue("qlcnic"); + if (qlcnic_wq == NULL) { + printk(KERN_ERR "qlcnic: cannot create workqueue\n"); + return -ENOMEM; + } + #ifdef CONFIG_INET register_netdevice_notifier(&qlcnic_netdev_cb); register_inetaddr_notifier(&qlcnic_inetaddr_cb); @@ -3656,6 +4234,7 @@ static int __init qlcnic_init_module(void) unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); unregister_netdevice_notifier(&qlcnic_netdev_cb); #endif + destroy_workqueue(qlcnic_wq); } return ret; @@ -3672,6 +4251,7 @@ static void __exit qlcnic_exit_module(void) unregister_inetaddr_notifier(&qlcnic_inetaddr_cb); unregister_netdevice_notifier(&qlcnic_netdev_cb); #endif + destroy_workqueue(qlcnic_wq); } module_exit(qlcnic_exit_module); diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 5f89e83501f4f5c1892ac15a84681a76ade08c19..ba0053d8515e24096854ee7cb7a07e99da32617b 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c @@ -1566,7 +1566,7 @@ static void ql_process_mac_rx_page(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (qdev->rx_csum && !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) { @@ -1676,7 +1676,7 @@ static void ql_process_mac_rx_skb(struct ql_adapter *qdev, rx_ring->rx_packets++; rx_ring->rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* If rx checksum is on, and there are no * csum or frame errors. @@ -1996,7 +1996,7 @@ static void ql_process_mac_split_rx_intr(struct ql_adapter *qdev, } skb->protocol = eth_type_trans(skb, ndev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* If rx checksum is on, and there are no * csum or frame errors. @@ -2222,10 +2222,11 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring) ql_update_cq(rx_ring); prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg); } + if (!net_rsp) + return 0; ql_write_cq_idx(rx_ring); tx_ring = &qdev->tx_ring[net_rsp->txq_idx]; - if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id) && - net_rsp != NULL) { + if (__netif_subqueue_stopped(qdev->ndev, tx_ring->wq_id)) { if (atomic_read(&tx_ring->queue_stopped) && (atomic_read(&tx_ring->tx_count) > (tx_ring->wq_len / 4))) /* @@ -2571,7 +2572,7 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev) mac_iocb_ptr->frame_len = cpu_to_le16((u16) skb->len); - if (qdev->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev, "Adding a vlan tag %d.\n", vlan_tx_tag_get(skb)); mac_iocb_ptr->flags3 |= OB_MAC_IOCB_V; @@ -3888,11 +3889,8 @@ int ql_wol(struct ql_adapter *qdev) return status; } -static int ql_adapter_down(struct ql_adapter *qdev) +static void ql_cancel_all_work_sync(struct ql_adapter *qdev) { - int i, status = 0; - - ql_link_off(qdev); /* Don't kill the reset worker thread if we * are in the process of recovery. @@ -3904,6 +3902,15 @@ static int ql_adapter_down(struct ql_adapter *qdev) cancel_delayed_work_sync(&qdev->mpi_idc_work); cancel_delayed_work_sync(&qdev->mpi_core_to_log); cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); +} + +static int ql_adapter_down(struct ql_adapter *qdev) +{ + int i, status = 0; + + ql_link_off(qdev); + + ql_cancel_all_work_sync(qdev); for (i = 0; i < qdev->rss_ring_count; i++) napi_disable(&qdev->rx_ring[i].napi); @@ -4726,6 +4733,7 @@ static void __devexit qlge_remove(struct pci_dev *pdev) struct net_device *ndev = pci_get_drvdata(pdev); struct ql_adapter *qdev = netdev_priv(ndev); del_timer_sync(&qdev->timer); + ql_cancel_all_work_sync(qdev); unregister_netdev(ndev); ql_release_all(pdev); pci_disable_device(pdev); @@ -4745,13 +4753,7 @@ static void ql_eeh_close(struct net_device *ndev) /* Disabling the timer */ del_timer_sync(&qdev->timer); - if (test_bit(QL_ADAPTER_UP, &qdev->flags)) - cancel_delayed_work_sync(&qdev->asic_reset_work); - cancel_delayed_work_sync(&qdev->mpi_reset_work); - cancel_delayed_work_sync(&qdev->mpi_work); - cancel_delayed_work_sync(&qdev->mpi_idc_work); - cancel_delayed_work_sync(&qdev->mpi_core_to_log); - cancel_delayed_work_sync(&qdev->mpi_port_cfg_work); + ql_cancel_all_work_sync(qdev); for (i = 0; i < qdev->rss_ring_count; i++) netif_napi_del(&qdev->rx_ring[i].napi); diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 142c381e1d73e0644eac3df74fea212385ad1115..0b014c894686b06921d4fa4fa31321fdb0d1412e 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -200,7 +200,7 @@ struct r6040_private { int old_duplex; }; -static char version[] __devinitdata = KERN_INFO DRV_NAME +static char version[] __devinitdata = DRV_NAME ": RDC R6040 NAPI net driver," "version "DRV_VERSION " (" DRV_RELDATE ")"; @@ -224,7 +224,8 @@ static int r6040_phy_read(void __iomem *ioaddr, int phy_addr, int reg) } /* Write a word data from PHY Chip */ -static void r6040_phy_write(void __iomem *ioaddr, int phy_addr, int reg, u16 val) +static void r6040_phy_write(void __iomem *ioaddr, + int phy_addr, int reg, u16 val) { int limit = 2048; u16 cmd; @@ -348,8 +349,8 @@ static int r6040_alloc_rxbufs(struct net_device *dev) } desc->skb_ptr = skb; desc->buf = cpu_to_le32(pci_map_single(lp->pdev, - desc->skb_ptr->data, - MAX_BUF_SIZE, PCI_DMA_FROMDEVICE)); + desc->skb_ptr->data, + MAX_BUF_SIZE, PCI_DMA_FROMDEVICE)); desc->status = DSC_OWNER_MAC; desc = desc->vndescp; } while (desc != lp->rx_ring); @@ -491,12 +492,14 @@ static int r6040_close(struct net_device *dev) /* Free Descriptor memory */ if (lp->rx_ring) { - pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); + pci_free_consistent(pdev, + RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); lp->rx_ring = NULL; } if (lp->tx_ring) { - pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); + pci_free_consistent(pdev, + TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma); lp->tx_ring = NULL; } @@ -547,7 +550,7 @@ static int r6040_rx(struct net_device *dev, int limit) } goto next_descr; } - + /* Packet successfully received */ new_skb = netdev_alloc_skb(dev, MAX_BUF_SIZE); if (!new_skb) { @@ -556,13 +559,13 @@ static int r6040_rx(struct net_device *dev, int limit) } skb_ptr = descptr->skb_ptr; skb_ptr->dev = priv->dev; - + /* Do not count the CRC */ skb_put(skb_ptr, descptr->len - 4); pci_unmap_single(priv->pdev, le32_to_cpu(descptr->buf), MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); skb_ptr->protocol = eth_type_trans(skb_ptr, priv->dev); - + /* Send to upper layer */ netif_receive_skb(skb_ptr); dev->stats.rx_packets++; @@ -710,8 +713,10 @@ static int r6040_up(struct net_device *dev) return ret; /* improve performance (by RDC guys) */ - r6040_phy_write(ioaddr, 30, 17, (r6040_phy_read(ioaddr, 30, 17) | 0x4000)); - r6040_phy_write(ioaddr, 30, 17, ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000)); + r6040_phy_write(ioaddr, 30, 17, + (r6040_phy_read(ioaddr, 30, 17) | 0x4000)); + r6040_phy_write(ioaddr, 30, 17, + ~((~r6040_phy_read(ioaddr, 30, 17)) | 0x2000)); r6040_phy_write(ioaddr, 0, 19, 0x0000); r6040_phy_write(ioaddr, 0, 30, 0x01F0); @@ -740,6 +745,9 @@ static void r6040_mac_address(struct net_device *dev) iowrite16(adrp[0], ioaddr + MID_0L); iowrite16(adrp[1], ioaddr + MID_0M); iowrite16(adrp[2], ioaddr + MID_0H); + + /* Store MAC Address in perm_addr */ + memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); } static int r6040_open(struct net_device *dev) @@ -751,7 +759,7 @@ static int r6040_open(struct net_device *dev) ret = request_irq(dev->irq, r6040_interrupt, IRQF_SHARED, dev->name, dev); if (ret) - return ret; + goto out; /* Set MAC address */ r6040_mac_address(dev); @@ -759,30 +767,37 @@ static int r6040_open(struct net_device *dev) /* Allocate Descriptor memory */ lp->rx_ring = pci_alloc_consistent(lp->pdev, RX_DESC_SIZE, &lp->rx_ring_dma); - if (!lp->rx_ring) - return -ENOMEM; + if (!lp->rx_ring) { + ret = -ENOMEM; + goto err_free_irq; + } lp->tx_ring = pci_alloc_consistent(lp->pdev, TX_DESC_SIZE, &lp->tx_ring_dma); if (!lp->tx_ring) { - pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring, - lp->rx_ring_dma); - return -ENOMEM; + ret = -ENOMEM; + goto err_free_rx_ring; } ret = r6040_up(dev); - if (ret) { - pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring, - lp->tx_ring_dma); - pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring, - lp->rx_ring_dma); - return ret; - } + if (ret) + goto err_free_tx_ring; napi_enable(&lp->napi); netif_start_queue(dev); return 0; + +err_free_tx_ring: + pci_free_consistent(lp->pdev, TX_DESC_SIZE, lp->tx_ring, + lp->tx_ring_dma); +err_free_rx_ring: + pci_free_consistent(lp->pdev, RX_DESC_SIZE, lp->rx_ring, + lp->rx_ring_dma); +err_free_irq: + free_irq(dev->irq, dev); +out: + return ret; } static netdev_tx_t r6040_start_xmit(struct sk_buff *skb, @@ -893,16 +908,18 @@ static void r6040_multicast_list(struct net_device *dev) /* Multicast Address 1~4 case */ i = 0; netdev_for_each_mc_addr(ha, dev) { - if (i < MCAST_MAX) { - adrp = (u16 *) ha->addr; - iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); - iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); - iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); - } else { - iowrite16(0xffff, ioaddr + MID_1L + 8 * i); - iowrite16(0xffff, ioaddr + MID_1M + 8 * i); - iowrite16(0xffff, ioaddr + MID_1H + 8 * i); - } + if (i >= MCAST_MAX) + break; + adrp = (u16 *) ha->addr; + iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); + iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); + iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); + i++; + } + while (i < MCAST_MAX) { + iowrite16(0xffff, ioaddr + MID_1L + 8 * i); + iowrite16(0xffff, ioaddr + MID_1M + 8 * i); + iowrite16(0xffff, ioaddr + MID_1H + 8 * i); i++; } } @@ -946,7 +963,7 @@ static const struct net_device_ops r6040_netdev_ops = { .ndo_set_multicast_list = r6040_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_do_ioctl = r6040_ioctl, .ndo_tx_timeout = r6040_tx_timeout, #ifdef CONFIG_NET_POLL_CONTROLLER @@ -1039,7 +1056,7 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, u16 *adrp; int i; - printk("%s\n", version); + pr_info("%s\n", version); err = pci_enable_device(pdev); if (err) @@ -1113,7 +1130,8 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, /* Some bootloader/BIOSes do not initialize * MAC address, warn about that */ if (!(adrp[0] || adrp[1] || adrp[2])) { - netdev_warn(dev, "MAC address not initialized, generating random\n"); + netdev_warn(dev, "MAC address not initialized, " + "generating random\n"); random_ether_addr(dev->dev_addr); } diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 992db2fa136e9c5e6f5130c053393aa662d4e5c9..d88ce9fb1cbdacd4c04e802369f504af15e17d37 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -187,12 +187,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { MODULE_DEVICE_TABLE(pci, rtl8169_pci_tbl); -/* - * we set our copybreak very high so that we don't have - * to allocate 16k frames all the time (see note in - * rtl8169_open() - */ -static int rx_copybreak = 16383; +static int rx_buf_sz = 16383; static int use_dac; static struct { u32 msg_enable; @@ -484,10 +479,8 @@ struct rtl8169_private { struct RxDesc *RxDescArray; /* 256-aligned Rx descriptor ring */ dma_addr_t TxPhyAddr; dma_addr_t RxPhyAddr; - struct sk_buff *Rx_skbuff[NUM_RX_DESC]; /* Rx data buffers */ + void *Rx_databuff[NUM_RX_DESC]; /* Rx data buffers */ struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ - unsigned align; - unsigned rx_buf_sz; struct timer_list timer; u16 cp_cmd; u16 intr_event; @@ -515,8 +508,6 @@ struct rtl8169_private { MODULE_AUTHOR("Realtek and the Linux r8169 crew "); MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); -module_param(rx_copybreak, int, 0); -MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); module_param(use_dac, int, 0); MODULE_PARM_DESC(use_dac, "Enable PCI DAC. Unsafe on 32 bit PCI slot."); module_param_named(debug, debug.msg_enable, int, 0); @@ -1043,7 +1034,7 @@ static int rtl8169_set_rx_csum(struct net_device *dev, u32 data) static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, struct sk_buff *skb) { - return (tp->vlgrp && vlan_tx_tag_present(skb)) ? + return (vlan_tx_tag_present(skb)) ? TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00; } @@ -1076,7 +1067,12 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc, int ret; if (vlgrp && (opts2 & RxVlanTag)) { - __vlan_hwaccel_rx(skb, vlgrp, swab16(opts2 & 0xffff), polling); + u16 vtag = swab16(opts2 & 0xffff); + + if (likely(polling)) + vlan_gro_receive(&tp->napi, vlgrp, vtag, skb); + else + __vlan_hwaccel_rx(skb, vlgrp, vtag, polling); ret = 0; } else ret = -1; @@ -1204,6 +1200,7 @@ static void rtl8169_update_counters(struct net_device *dev) dma_addr_t paddr; u32 cmd; int wait = 1000; + struct device *d = &tp->pci_dev->dev; /* * Some chips are unable to dump tally counters when the receiver @@ -1212,8 +1209,7 @@ static void rtl8169_update_counters(struct net_device *dev) if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0) return; - counters = dma_alloc_coherent(&tp->pci_dev->dev, sizeof(*counters), - &paddr, GFP_KERNEL); + counters = dma_alloc_coherent(d, sizeof(*counters), &paddr, GFP_KERNEL); if (!counters) return; @@ -1234,8 +1230,7 @@ static void rtl8169_update_counters(struct net_device *dev) RTL_W32(CounterAddrLow, 0); RTL_W32(CounterAddrHigh, 0); - dma_free_coherent(&tp->pci_dev->dev, sizeof(*counters), counters, - paddr); + dma_free_coherent(d, sizeof(*counters), counters, paddr); } static void rtl8169_get_ethtool_stats(struct net_device *dev, @@ -3188,9 +3183,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_R8169_VLAN dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; #endif + dev->features |= NETIF_F_GRO; tp->intr_mask = 0xffff; - tp->align = cfg->align; tp->hw_start = cfg->hw_start; tp->intr_event = cfg->intr_event; tp->napi_event = cfg->napi_event; @@ -3260,18 +3255,6 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -static void rtl8169_set_rxbufsize(struct rtl8169_private *tp, - unsigned int mtu) -{ - unsigned int max_frame = mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; - - if (max_frame != 16383) - printk(KERN_WARNING PFX "WARNING! Changing of MTU on this " - "NIC may lead to frame reception errors!\n"); - - tp->rx_buf_sz = (max_frame > RX_BUF_SIZE) ? max_frame : RX_BUF_SIZE; -} - static int rtl8169_open(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3280,18 +3263,6 @@ static int rtl8169_open(struct net_device *dev) pm_runtime_get_sync(&pdev->dev); - /* - * Note that we use a magic value here, its wierd I know - * its done because, some subset of rtl8169 hardware suffers from - * a problem in which frames received that are longer than - * the size set in RxMaxSize register return garbage sizes - * when received. To avoid this we need to turn off filtering, - * which is done by setting a value of 16383 in the RxMaxSize register - * and allocating 16k frames to handle the largest possible rx value - * thats what the magic math below does. - */ - rtl8169_set_rxbufsize(tp, 16383 - VLAN_ETH_HLEN - ETH_FCS_LEN); - /* * Rx and Tx desscriptors needs 256 bytes alignment. * dma_alloc_coherent provides more. @@ -3468,7 +3439,7 @@ static void rtl_hw_start_8169(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr, rx_buf_sz); if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || (tp->mac_version == RTL_GIGA_MAC_VER_02) || @@ -3729,7 +3700,7 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr, rx_buf_sz); tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; @@ -3909,7 +3880,7 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr, rx_buf_sz); tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; @@ -3937,33 +3908,11 @@ static void rtl_hw_start_8101(struct net_device *dev) static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) { - struct rtl8169_private *tp = netdev_priv(dev); - int ret = 0; - if (new_mtu < ETH_ZLEN || new_mtu > SafeMtu) return -EINVAL; dev->mtu = new_mtu; - - if (!netif_running(dev)) - goto out; - - rtl8169_down(dev); - - rtl8169_set_rxbufsize(tp, dev->mtu); - - ret = rtl8169_init_ring(dev); - if (ret < 0) - goto out; - - napi_enable(&tp->napi); - - rtl_hw_start(dev); - - rtl8169_request_timer(dev); - -out: - return ret; + return 0; } static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) @@ -3972,15 +3921,14 @@ static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) desc->opts1 &= ~cpu_to_le32(DescOwn | RsvdMask); } -static void rtl8169_free_rx_skb(struct rtl8169_private *tp, - struct sk_buff **sk_buff, struct RxDesc *desc) +static void rtl8169_free_rx_databuff(struct rtl8169_private *tp, + void **data_buff, struct RxDesc *desc) { - struct pci_dev *pdev = tp->pci_dev; + dma_unmap_single(&tp->pci_dev->dev, le64_to_cpu(desc->addr), rx_buf_sz, + DMA_FROM_DEVICE); - dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); - dev_kfree_skb(*sk_buff); - *sk_buff = NULL; + kfree(*data_buff); + *data_buff = NULL; rtl8169_make_unusable_by_asic(desc); } @@ -3999,33 +3947,45 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, rtl8169_mark_to_asic(desc, rx_buf_sz); } -static struct sk_buff *rtl8169_alloc_rx_skb(struct pci_dev *pdev, - struct net_device *dev, - struct RxDesc *desc, int rx_buf_sz, - unsigned int align, gfp_t gfp) +static inline void *rtl8169_align(void *data) { - struct sk_buff *skb; - dma_addr_t mapping; - unsigned int pad; + return (void *)ALIGN((long)data, 16); +} - pad = align ? align : NET_IP_ALIGN; +static struct sk_buff *rtl8169_alloc_rx_data(struct rtl8169_private *tp, + struct RxDesc *desc) +{ + void *data; + dma_addr_t mapping; + struct device *d = &tp->pci_dev->dev; + struct net_device *dev = tp->dev; + int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; - skb = __netdev_alloc_skb(dev, rx_buf_sz + pad, gfp); - if (!skb) - goto err_out; + data = kmalloc_node(rx_buf_sz, GFP_KERNEL, node); + if (!data) + return NULL; - skb_reserve(skb, align ? ((pad - 1) & (unsigned long)skb->data) : pad); + if (rtl8169_align(data) != data) { + kfree(data); + data = kmalloc_node(rx_buf_sz + 15, GFP_KERNEL, node); + if (!data) + return NULL; + } - mapping = dma_map_single(&pdev->dev, skb->data, rx_buf_sz, - PCI_DMA_FROMDEVICE); + mapping = dma_map_single(d, rtl8169_align(data), rx_buf_sz, + DMA_FROM_DEVICE); + if (unlikely(dma_mapping_error(d, mapping))) { + if (net_ratelimit()) + netif_err(tp, drv, tp->dev, "Failed to map RX DMA!\n"); + goto err_out; + } rtl8169_map_to_asic(desc, mapping, rx_buf_sz); -out: - return skb; + return data; err_out: - rtl8169_make_unusable_by_asic(desc); - goto out; + kfree(data); + return NULL; } static void rtl8169_rx_clear(struct rtl8169_private *tp) @@ -4033,41 +3993,42 @@ static void rtl8169_rx_clear(struct rtl8169_private *tp) unsigned int i; for (i = 0; i < NUM_RX_DESC; i++) { - if (tp->Rx_skbuff[i]) { - rtl8169_free_rx_skb(tp, tp->Rx_skbuff + i, + if (tp->Rx_databuff[i]) { + rtl8169_free_rx_databuff(tp, tp->Rx_databuff + i, tp->RxDescArray + i); } } } -static u32 rtl8169_rx_fill(struct rtl8169_private *tp, struct net_device *dev, - u32 start, u32 end, gfp_t gfp) +static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc) { - u32 cur; + desc->opts1 |= cpu_to_le32(RingEnd); +} - for (cur = start; end - cur != 0; cur++) { - struct sk_buff *skb; - unsigned int i = cur % NUM_RX_DESC; +static int rtl8169_rx_fill(struct rtl8169_private *tp) +{ + unsigned int i; - WARN_ON((s32)(end - cur) < 0); + for (i = 0; i < NUM_RX_DESC; i++) { + void *data; - if (tp->Rx_skbuff[i]) + if (tp->Rx_databuff[i]) continue; - skb = rtl8169_alloc_rx_skb(tp->pci_dev, dev, - tp->RxDescArray + i, - tp->rx_buf_sz, tp->align, gfp); - if (!skb) - break; - - tp->Rx_skbuff[i] = skb; + data = rtl8169_alloc_rx_data(tp, tp->RxDescArray + i); + if (!data) { + rtl8169_make_unusable_by_asic(tp->RxDescArray + i); + goto err_out; + } + tp->Rx_databuff[i] = data; } - return cur - start; -} -static inline void rtl8169_mark_as_last_descriptor(struct RxDesc *desc) -{ - desc->opts1 |= cpu_to_le32(RingEnd); + rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); + return 0; + +err_out: + rtl8169_rx_clear(tp); + return -ENOMEM; } static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) @@ -4082,54 +4043,51 @@ static int rtl8169_init_ring(struct net_device *dev) rtl8169_init_ring_indexes(tp); memset(tp->tx_skb, 0x0, NUM_TX_DESC * sizeof(struct ring_info)); - memset(tp->Rx_skbuff, 0x0, NUM_RX_DESC * sizeof(struct sk_buff *)); - - if (rtl8169_rx_fill(tp, dev, 0, NUM_RX_DESC, GFP_KERNEL) != NUM_RX_DESC) - goto err_out; - - rtl8169_mark_as_last_descriptor(tp->RxDescArray + NUM_RX_DESC - 1); - - return 0; + memset(tp->Rx_databuff, 0x0, NUM_RX_DESC * sizeof(void *)); -err_out: - rtl8169_rx_clear(tp); - return -ENOMEM; + return rtl8169_rx_fill(tp); } -static void rtl8169_unmap_tx_skb(struct pci_dev *pdev, struct ring_info *tx_skb, +static void rtl8169_unmap_tx_skb(struct device *d, struct ring_info *tx_skb, struct TxDesc *desc) { unsigned int len = tx_skb->len; - dma_unmap_single(&pdev->dev, le64_to_cpu(desc->addr), len, - PCI_DMA_TODEVICE); + dma_unmap_single(d, le64_to_cpu(desc->addr), len, DMA_TO_DEVICE); + desc->opts1 = 0x00; desc->opts2 = 0x00; desc->addr = 0x00; tx_skb->len = 0; } -static void rtl8169_tx_clear(struct rtl8169_private *tp) +static void rtl8169_tx_clear_range(struct rtl8169_private *tp, u32 start, + unsigned int n) { unsigned int i; - for (i = tp->dirty_tx; i < tp->dirty_tx + NUM_TX_DESC; i++) { - unsigned int entry = i % NUM_TX_DESC; + for (i = 0; i < n; i++) { + unsigned int entry = (start + i) % NUM_TX_DESC; struct ring_info *tx_skb = tp->tx_skb + entry; unsigned int len = tx_skb->len; if (len) { struct sk_buff *skb = tx_skb->skb; - rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, + rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, tp->TxDescArray + entry); if (skb) { + tp->dev->stats.tx_dropped++; dev_kfree_skb(skb); tx_skb->skb = NULL; } - tp->dev->stats.tx_dropped++; } } +} + +static void rtl8169_tx_clear(struct rtl8169_private *tp) +{ + rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); tp->cur_tx = tp->dirty_tx = 0; } @@ -4233,6 +4191,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, struct skb_shared_info *info = skb_shinfo(skb); unsigned int cur_frag, entry; struct TxDesc * uninitialized_var(txd); + struct device *d = &tp->pci_dev->dev; entry = tp->cur_tx; for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) { @@ -4246,8 +4205,13 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, txd = tp->TxDescArray + entry; len = frag->size; addr = ((void *) page_address(frag->page)) + frag->page_offset; - mapping = dma_map_single(&tp->pci_dev->dev, addr, len, - PCI_DMA_TODEVICE); + mapping = dma_map_single(d, addr, len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(d, mapping))) { + if (net_ratelimit()) + netif_err(tp, drv, tp->dev, + "Failed to map TX fragments DMA!\n"); + goto err_out; + } /* anti gcc 2.95.3 bugware (sic) */ status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); @@ -4264,6 +4228,10 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, } return cur_frag; + +err_out: + rtl8169_tx_clear_range(tp, tp->cur_tx + 1, cur_frag); + return -EIO; } static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev) @@ -4290,40 +4258,47 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - unsigned int frags, entry = tp->cur_tx % NUM_TX_DESC; + unsigned int entry = tp->cur_tx % NUM_TX_DESC; struct TxDesc *txd = tp->TxDescArray + entry; void __iomem *ioaddr = tp->mmio_addr; + struct device *d = &tp->pci_dev->dev; dma_addr_t mapping; u32 status, len; u32 opts1; + int frags; if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) { netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n"); - goto err_stop; + goto err_stop_0; } if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) - goto err_stop; + goto err_stop_0; + + len = skb_headlen(skb); + mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(d, mapping))) { + if (net_ratelimit()) + netif_err(tp, drv, dev, "Failed to map TX DMA!\n"); + goto err_dma_0; + } + + tp->tx_skb[entry].len = len; + txd->addr = cpu_to_le64(mapping); + txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); opts1 = DescOwn | rtl8169_tso_csum(skb, dev); frags = rtl8169_xmit_frags(tp, skb, opts1); - if (frags) { - len = skb_headlen(skb); + if (frags < 0) + goto err_dma_1; + else if (frags) opts1 |= FirstFrag; - } else { - len = skb->len; + else { opts1 |= FirstFrag | LastFrag; tp->tx_skb[entry].skb = skb; } - mapping = dma_map_single(&tp->pci_dev->dev, skb->data, len, - PCI_DMA_TODEVICE); - - tp->tx_skb[entry].len = len; - txd->addr = cpu_to_le64(mapping); - txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); - wmb(); /* anti gcc 2.95.3 bugware (sic) */ @@ -4345,7 +4320,14 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; -err_stop: +err_dma_1: + rtl8169_unmap_tx_skb(d, tp->tx_skb + entry, txd); +err_dma_0: + dev_kfree_skb(skb); + dev->stats.tx_dropped++; + return NETDEV_TX_OK; + +err_stop_0: netif_stop_queue(dev); dev->stats.tx_dropped++; return NETDEV_TX_BUSY; @@ -4410,7 +4392,6 @@ static void rtl8169_tx_interrupt(struct net_device *dev, while (tx_left > 0) { unsigned int entry = dirty_tx % NUM_TX_DESC; struct ring_info *tx_skb = tp->tx_skb + entry; - u32 len = tx_skb->len; u32 status; rmb(); @@ -4418,12 +4399,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev, if (status & DescOwn) break; - dev->stats.tx_bytes += len; - dev->stats.tx_packets++; - - rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry); - + rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, + tp->TxDescArray + entry); if (status & LastFrag) { + dev->stats.tx_packets++; + dev->stats.tx_bytes += tx_skb->skb->len; dev_kfree_skb(tx_skb->skb); tx_skb->skb = NULL; } @@ -4455,9 +4435,8 @@ static inline int rtl8169_fragmented_frame(u32 status) return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); } -static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) +static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) { - u32 opts1 = le32_to_cpu(desc->opts1); u32 status = opts1 & RxProtoMask; if (((status == RxProtoTCP) && !(opts1 & TCPFail)) || @@ -4465,30 +4444,26 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) ((status == RxProtoIP) && !(opts1 & IPFail))) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } -static inline bool rtl8169_try_rx_copy(struct sk_buff **sk_buff, - struct rtl8169_private *tp, int pkt_size, - dma_addr_t addr) +static struct sk_buff *rtl8169_try_rx_copy(void *data, + struct rtl8169_private *tp, + int pkt_size, + dma_addr_t addr) { struct sk_buff *skb; - bool done = false; - - if (pkt_size >= rx_copybreak) - goto out; + struct device *d = &tp->pci_dev->dev; + data = rtl8169_align(data); + dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); + prefetch(data); skb = netdev_alloc_skb_ip_align(tp->dev, pkt_size); - if (!skb) - goto out; + if (skb) + memcpy(skb->data, data, pkt_size); + dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE); - dma_sync_single_for_cpu(&tp->pci_dev->dev, addr, pkt_size, - PCI_DMA_FROMDEVICE); - skb_copy_from_linear_data(*sk_buff, skb->data, pkt_size); - *sk_buff = skb; - done = true; -out: - return done; + return skb; } /* @@ -4503,7 +4478,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, void __iomem *ioaddr, u32 budget) { unsigned int cur_rx, rx_left; - unsigned int delta, count; + unsigned int count; int polling = (budget != ~(u32)0) ? 1 : 0; cur_rx = tp->cur_rx; @@ -4532,12 +4507,11 @@ static int rtl8169_rx_interrupt(struct net_device *dev, rtl8169_schedule_work(dev, rtl8169_reset_task); dev->stats.rx_fifo_errors++; } - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); + rtl8169_mark_to_asic(desc, rx_buf_sz); } else { - struct sk_buff *skb = tp->Rx_skbuff[entry]; + struct sk_buff *skb; dma_addr_t addr = le64_to_cpu(desc->addr); int pkt_size = (status & 0x00001FFF) - 4; - struct pci_dev *pdev = tp->pci_dev; /* * The driver does not support incoming fragmented @@ -4547,28 +4521,25 @@ static int rtl8169_rx_interrupt(struct net_device *dev, if (unlikely(rtl8169_fragmented_frame(status))) { dev->stats.rx_dropped++; dev->stats.rx_length_errors++; - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); + rtl8169_mark_to_asic(desc, rx_buf_sz); continue; } - rtl8169_rx_csum(skb, desc); - - if (rtl8169_try_rx_copy(&skb, tp, pkt_size, addr)) { - dma_sync_single_for_device(&pdev->dev, addr, - pkt_size, PCI_DMA_FROMDEVICE); - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); - } else { - dma_unmap_single(&pdev->dev, addr, tp->rx_buf_sz, - PCI_DMA_FROMDEVICE); - tp->Rx_skbuff[entry] = NULL; + skb = rtl8169_try_rx_copy(tp->Rx_databuff[entry], + tp, pkt_size, addr); + rtl8169_mark_to_asic(desc, rx_buf_sz); + if (!skb) { + dev->stats.rx_dropped++; + continue; } + rtl8169_rx_csum(skb, status); skb_put(skb, pkt_size); skb->protocol = eth_type_trans(skb, dev); if (rtl8169_rx_vlan_skb(tp, desc, skb, polling) < 0) { if (likely(polling)) - netif_receive_skb(skb); + napi_gro_receive(&tp->napi, skb); else netif_rx(skb); } @@ -4588,20 +4559,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, count = cur_rx - tp->cur_rx; tp->cur_rx = cur_rx; - delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx, GFP_ATOMIC); - if (!delta && count) - netif_info(tp, intr, dev, "no Rx buffer allocated\n"); - tp->dirty_rx += delta; - - /* - * FIXME: until there is periodic timer to try and refill the ring, - * a temporary shortage may definitely kill the Rx process. - * - disable the asic to try and avoid an overflow and kick it again - * after refill ? - * - how do others driver handle this condition (Uh oh...). - */ - if (tp->dirty_rx + NUM_RX_DESC == tp->cur_rx) - netif_emerg(tp, intr, dev, "Rx buffers exhausted\n"); + tp->dirty_rx += count; return count; } @@ -4716,7 +4674,6 @@ static void rtl8169_down(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - unsigned int intrmask; rtl8169_delete_timer(dev); @@ -4724,11 +4681,14 @@ static void rtl8169_down(struct net_device *dev) napi_disable(&tp->napi); -core_down: spin_lock_irq(&tp->lock); rtl8169_asic_down(ioaddr); - + /* + * At this point device interrupts can not be enabled in any function, + * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, + * rtl8169_reinit_task) and napi is disabled (rtl8169_poll). + */ rtl8169_rx_missed(dev, ioaddr); spin_unlock_irq(&tp->lock); @@ -4738,23 +4698,6 @@ static void rtl8169_down(struct net_device *dev) /* Give a racing hard_start_xmit a few cycles to complete. */ synchronize_sched(); /* FIXME: should this be synchronize_irq()? */ - /* - * And now for the 50k$ question: are IRQ disabled or not ? - * - * Two paths lead here: - * 1) dev->close - * -> netif_running() is available to sync the current code and the - * IRQ handler. See rtl8169_interrupt for details. - * 2) dev->change_mtu - * -> rtl8169_poll can not be issued again and re-enable the - * interruptions. Let's simply issue the IRQ down sequence again. - * - * No loop if hotpluged or major error (0xffff). - */ - intrmask = RTL_R16(IntrMask); - if (intrmask && (intrmask != 0xffff)) - goto core_down; - rtl8169_tx_clear(tp); rtl8169_rx_clear(tp); @@ -4891,6 +4834,9 @@ static int rtl8169_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct net_device *dev = pci_get_drvdata(pdev); + struct rtl8169_private *tp = netdev_priv(dev); + + rtl8169_init_phy(dev, tp); if (netif_running(dev)) __rtl8169_resume(dev); @@ -4931,6 +4877,8 @@ static int rtl8169_runtime_resume(struct device *device) tp->saved_wolopts = 0; spin_unlock_irq(&tp->lock); + rtl8169_init_phy(dev, tp); + __rtl8169_resume(dev); return 0; diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c index e26e107f93e0c4ee18156a3c188bdc673c7c3691..e68c941926f16cf44feebe7ef103947592b0263e 100644 --- a/drivers/net/rrunner.c +++ b/drivers/net/rrunner.c @@ -1245,7 +1245,7 @@ static int rr_open(struct net_device *dev) init_timer(&rrpriv->timer); rrpriv->timer.expires = RUN_AT(5*HZ); /* 5 sec. watchdog */ rrpriv->timer.data = (unsigned long)dev; - rrpriv->timer.function = &rr_timer; /* timer handler */ + rrpriv->timer.function = rr_timer; /* timer handler */ add_timer(&rrpriv->timer); netif_start_queue(dev); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 18bc5b718bbb51875dd5e2fbf14be6f626d0fa88..ecc25aab896af3ee9e55a9da4e90bccd32553d37 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -38,8 +38,6 @@ * Tx descriptors that can be associated with each corresponding FIFO. * intr_type: This defines the type of interrupt. The values can be 0(INTA), * 2(MSI_X). Default value is '2(MSI_X)' - * lro: Specifies whether to enable Large Receive Offload (LRO) or not. - * Possible values '1' for enable '0' for disable. Default is '0' * lro_max_pkts: This parameter defines maximum number of packets can be * aggregated as a single large packet * napi: This parameter used to enable/disable NAPI (polling Rx) @@ -90,7 +88,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.26" +#define DRV_VERSION "2.0.26.27" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -496,8 +494,6 @@ S2IO_PARM_INT(rxsync_frequency, 3); /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ S2IO_PARM_INT(intr_type, 2); /* Large receive offload feature */ -static unsigned int lro_enable = 1; -module_param_named(lro, lro_enable, uint, 0); /* Max pkts to be aggregated by LRO at one time. If not specified, * aggregation happens until we hit max IP pkt size(64K) @@ -4105,7 +4101,7 @@ static netdev_tx_t s2io_xmit(struct sk_buff *skb, struct net_device *dev) } queue = 0; - if (sp->vlgrp && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) vlan_tag = vlan_tx_tag_get(skb); if (sp->config.tx_steering_type == TX_DEFAULT_STEERING) { if (skb->protocol == htons(ETH_P_IP)) { @@ -5124,8 +5120,6 @@ static void s2io_set_multicast(struct net_device *dev) /* Create the new Rx filter list and update the same in H/W. */ i = 0; netdev_for_each_mc_addr(ha, dev) { - memcpy(sp->usr_addrs[i].addr, ha->addr, - ETH_ALEN); mac_addr = 0; for (j = 0; j < ETH_ALEN; j++) { mac_addr |= ha->addr[j]; @@ -6735,13 +6729,10 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data) return -EINVAL; if (data & ETH_FLAG_LRO) { - if (lro_enable) { - if (!(dev->features & NETIF_F_LRO)) { - dev->features |= NETIF_F_LRO; - changed = 1; - } - } else - rc = -EINVAL; + if (!(dev->features & NETIF_F_LRO)) { + dev->features |= NETIF_F_LRO; + changed = 1; + } } else if (dev->features & NETIF_F_LRO) { dev->features &= ~NETIF_F_LRO; changed = 1; @@ -6750,7 +6741,6 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data) if (changed && netif_running(dev)) { s2io_stop_all_tx_queue(sp); s2io_card_down(sp); - sp->lro = !!(dev->features & NETIF_F_LRO); rc = s2io_card_up(sp); if (rc) s2io_reset(sp); @@ -7307,7 +7297,7 @@ static int s2io_card_up(struct s2io_nic *sp) struct ring_info *ring = &mac_control->rings[i]; ring->mtu = dev->mtu; - ring->lro = sp->lro; + ring->lro = !!(dev->features & NETIF_F_LRO); ret = fill_rx_buffers(sp, ring, 1); if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", @@ -7341,7 +7331,7 @@ static int s2io_card_up(struct s2io_nic *sp) /* Setting its receive mode */ s2io_set_multicast(dev); - if (sp->lro) { + if (dev->features & NETIF_F_LRO) { /* Initialize max aggregatable pkts per session based on MTU */ sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; /* Check if we can use (if specified) user provided value */ @@ -7613,10 +7603,10 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) * Packet with erroneous checksum, let the * upper layers deal with it. */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); swstats->mem_freed += skb->truesize; send_up: @@ -7911,7 +7901,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) else sp->device_type = XFRAME_I_DEVICE; - sp->lro = lro_enable; /* Initialize some PCI/PCI-X fields of the NIC. */ s2io_init_pci(sp); @@ -8047,8 +8036,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->netdev_ops = &s2io_netdev_ops; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; - if (lro_enable) - dev->features |= NETIF_F_LRO; + dev->features |= NETIF_F_LRO; dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; if (sp->high_dma_flag == true) dev->features |= NETIF_F_HIGHDMA; @@ -8283,9 +8271,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->name); } - if (sp->lro) - DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", - dev->name); + DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", + dev->name); if (ufo) DBG_PRINT(ERR_DBG, "%s: UDP Fragmentation Offload(UFO) enabled\n", diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 0af0335339053f8512280077d66b0ab4f41a2941..00b8614efe48bcac4e85c88dbd11d2cfdc65b5ef 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -816,12 +816,6 @@ struct mac_info { struct stat_block *stats_info; /* Logical address of the stat block */ }; -/* structure representing the user defined MAC addresses */ -struct usr_addr { - char addr[ETH_ALEN]; - int usage_cnt; -}; - /* Default Tunable parameters of the NIC. */ #define DEFAULT_FIFO_0_LEN 4096 #define DEFAULT_FIFO_1_7_LEN 512 @@ -894,9 +888,7 @@ struct s2io_nic { #define ALL_MULTI 2 #define MAX_ADDRS_SUPPORTED 64 - u16 usr_addr_count; u16 mc_addr_count; - struct usr_addr usr_addrs[256]; u16 m_cast_flg; u16 all_multi_pos; @@ -971,7 +963,6 @@ struct s2io_nic { unsigned long clubbed_frms_cnt; unsigned long sending_both; - u8 lro; u16 lro_max_aggr_per_sess; volatile unsigned long state; u64 general_int_mask; diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index 8e6bd45b9f311f4ea4c164d6d2528455cb64ae8e..d8249d7653c6abdc108b87a1de3ff1ceb1ec05d4 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -1170,7 +1170,7 @@ static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, sb->ip_summed = CHECKSUM_UNNECESSARY; /* don't need to set sb->csum */ } else { - sb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(sb); } } prefetch(sb->data); diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c index 8c4067af32b0fbc671d2d38652a09e0594268611..31b92f5f32cb60dc2a2404850a868ac00398ee97 100644 --- a/drivers/net/sc92031.c +++ b/drivers/net/sc92031.c @@ -1251,16 +1251,6 @@ static int sc92031_ethtool_set_settings(struct net_device *dev, return 0; } -static void sc92031_ethtool_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *drvinfo) -{ - struct sc92031_priv *priv = netdev_priv(dev); - struct pci_dev *pdev = priv->pdev; - - strcpy(drvinfo->driver, SC92031_NAME); - strcpy(drvinfo->bus_info, pci_name(pdev)); -} - static void sc92031_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo) { @@ -1382,7 +1372,6 @@ static void sc92031_ethtool_get_ethtool_stats(struct net_device *dev, static const struct ethtool_ops sc92031_ethtool_ops = { .get_settings = sc92031_ethtool_get_settings, .set_settings = sc92031_ethtool_set_settings, - .get_drvinfo = sc92031_ethtool_get_drvinfo, .get_wol = sc92031_ethtool_get_wol, .set_wol = sc92031_ethtool_set_wol, .nway_reset = sc92031_ethtool_nway_reset, diff --git a/drivers/net/sfc/Makefile b/drivers/net/sfc/Makefile index 1047b19c60a590f1bb67f4315950c707a5623d6d..ab31c7124db1898ed58460fb7c7593c89498fcac 100644 --- a/drivers/net/sfc/Makefile +++ b/drivers/net/sfc/Makefile @@ -1,7 +1,8 @@ -sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o \ - falcon_gmac.o falcon_xmac.o mcdi_mac.o \ +sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \ + falcon_xmac.o mcdi_mac.o \ selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ - tenxpress.o falcon_boards.o mcdi.o mcdi_phy.o + tenxpress.o txc43128_phy.o falcon_boards.o \ + mcdi.o mcdi_phy.o sfc-$(CONFIG_SFC_MTD) += mtd.o obj-$(CONFIG_SFC) += sfc.o diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index ba674c5ca29e76a87da30259505b5fa7e0e43098..05df20e47976cb3965c59c5b227e67877bd2d0c4 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -68,14 +68,6 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_PHYXS_WS] = "PHYXS_WS", }; -/* Interrupt mode names (see INT_MODE())) */ -const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX; -const char *efx_interrupt_mode_names[] = { - [EFX_INT_MODE_MSIX] = "MSI-X", - [EFX_INT_MODE_MSI] = "MSI", - [EFX_INT_MODE_LEGACY] = "legacy", -}; - const unsigned int efx_reset_type_max = RESET_TYPE_MAX; const char *efx_reset_type_names[] = { [RESET_TYPE_INVISIBLE] = "INVISIBLE", @@ -114,7 +106,7 @@ static struct workqueue_struct *reset_workqueue; * This is only used in MSI-X interrupt mode */ static unsigned int separate_tx_channels; -module_param(separate_tx_channels, uint, 0644); +module_param(separate_tx_channels, uint, 0444); MODULE_PARM_DESC(separate_tx_channels, "Use separate channels for TX and RX"); @@ -124,10 +116,11 @@ MODULE_PARM_DESC(separate_tx_channels, static int napi_weight = 64; /* This is the time (in jiffies) between invocations of the hardware - * monitor, which checks for known hardware bugs and resets the - * hardware and driver as necessary. + * monitor. On Falcon-based NICs, this will: + * - Check the on-board hardware monitor; + * - Poll the link state and reconfigure the hardware as necessary. */ -unsigned int efx_monitor_interval = 1 * HZ; +static unsigned int efx_monitor_interval = 1 * HZ; /* This controls whether or not the driver will initialise devices * with invalid MAC addresses stored in the EEPROM or flash. If true, @@ -201,10 +194,13 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value"); * Utility functions and prototypes * *************************************************************************/ -static void efx_remove_channel(struct efx_channel *channel); + +static void efx_remove_channels(struct efx_nic *efx); static void efx_remove_port(struct efx_nic *efx); static void efx_fini_napi(struct efx_nic *efx); -static void efx_fini_channels(struct efx_nic *efx); +static void efx_fini_struct(struct efx_nic *efx); +static void efx_start_all(struct efx_nic *efx); +static void efx_stop_all(struct efx_nic *efx); #define EFX_ASSERT_RESET_SERIALISED(efx) \ do { \ @@ -248,7 +244,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) efx_rx_strategy(channel); - efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]); + efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel)); return spent; } @@ -334,6 +330,7 @@ void efx_process_channel_now(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; + BUG_ON(channel->channel >= efx->n_channels); BUG_ON(!channel->enabled); /* Disable interrupts and wait for ISRs to complete */ @@ -347,7 +344,7 @@ void efx_process_channel_now(struct efx_channel *channel) napi_disable(&channel->napi_str); /* Poll the channel */ - efx_process_channel(channel, EFX_EVQ_SIZE); + efx_process_channel(channel, channel->eventq_mask + 1); /* Ack the eventq. This may cause an interrupt to be generated * when they are reenabled */ @@ -364,9 +361,18 @@ void efx_process_channel_now(struct efx_channel *channel) */ static int efx_probe_eventq(struct efx_channel *channel) { + struct efx_nic *efx = channel->efx; + unsigned long entries; + netif_dbg(channel->efx, probe, channel->efx->net_dev, "chan %d create event queue\n", channel->channel); + /* Build an event queue with room for one event per tx and rx buffer, + * plus some extra for link state events and MCDI completions. */ + entries = roundup_pow_of_two(efx->rxq_entries + efx->txq_entries + 128); + EFX_BUG_ON_PARANOID(entries > EFX_MAX_EVQ_SIZE); + channel->eventq_mask = max(entries, EFX_MIN_EVQ_SIZE) - 1; + return efx_nic_probe_eventq(channel); } @@ -403,6 +409,63 @@ static void efx_remove_eventq(struct efx_channel *channel) * *************************************************************************/ +/* Allocate and initialise a channel structure, optionally copying + * parameters (but not resources) from an old channel structure. */ +static struct efx_channel * +efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) +{ + struct efx_channel *channel; + struct efx_rx_queue *rx_queue; + struct efx_tx_queue *tx_queue; + int j; + + if (old_channel) { + channel = kmalloc(sizeof(*channel), GFP_KERNEL); + if (!channel) + return NULL; + + *channel = *old_channel; + + memset(&channel->eventq, 0, sizeof(channel->eventq)); + + rx_queue = &channel->rx_queue; + rx_queue->buffer = NULL; + memset(&rx_queue->rxd, 0, sizeof(rx_queue->rxd)); + + for (j = 0; j < EFX_TXQ_TYPES; j++) { + tx_queue = &channel->tx_queue[j]; + if (tx_queue->channel) + tx_queue->channel = channel; + tx_queue->buffer = NULL; + memset(&tx_queue->txd, 0, sizeof(tx_queue->txd)); + } + } else { + channel = kzalloc(sizeof(*channel), GFP_KERNEL); + if (!channel) + return NULL; + + channel->efx = efx; + channel->channel = i; + + for (j = 0; j < EFX_TXQ_TYPES; j++) { + tx_queue = &channel->tx_queue[j]; + tx_queue->efx = efx; + tx_queue->queue = i * EFX_TXQ_TYPES + j; + tx_queue->channel = channel; + } + } + + spin_lock_init(&channel->tx_stop_lock); + atomic_set(&channel->tx_stop_count, 1); + + rx_queue = &channel->rx_queue; + rx_queue->efx = efx; + setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill, + (unsigned long)rx_queue); + + return channel; +} + static int efx_probe_channel(struct efx_channel *channel) { struct efx_tx_queue *tx_queue; @@ -459,11 +522,38 @@ static void efx_set_channel_names(struct efx_nic *efx) number -= efx->n_rx_channels; } } - snprintf(channel->name, sizeof(channel->name), + snprintf(efx->channel_name[channel->channel], + sizeof(efx->channel_name[0]), "%s%s-%d", efx->name, type, number); } } +static int efx_probe_channels(struct efx_nic *efx) +{ + struct efx_channel *channel; + int rc; + + /* Restart special buffer allocation */ + efx->next_buffer_table = 0; + + efx_for_each_channel(channel, efx) { + rc = efx_probe_channel(channel); + if (rc) { + netif_err(efx, probe, efx->net_dev, + "failed to create channel %d\n", + channel->channel); + goto fail; + } + } + efx_set_channel_names(efx); + + return 0; + +fail: + efx_remove_channels(efx); + return rc; +} + /* Channels are shutdown and reinitialised whilst the NIC is running * to propagate configuration changes (mtu, checksum offload), or * to clear hardware error conditions @@ -601,6 +691,75 @@ static void efx_remove_channel(struct efx_channel *channel) efx_remove_eventq(channel); } +static void efx_remove_channels(struct efx_nic *efx) +{ + struct efx_channel *channel; + + efx_for_each_channel(channel, efx) + efx_remove_channel(channel); +} + +int +efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) +{ + struct efx_channel *other_channel[EFX_MAX_CHANNELS], *channel; + u32 old_rxq_entries, old_txq_entries; + unsigned i; + int rc; + + efx_stop_all(efx); + efx_fini_channels(efx); + + /* Clone channels */ + memset(other_channel, 0, sizeof(other_channel)); + for (i = 0; i < efx->n_channels; i++) { + channel = efx_alloc_channel(efx, i, efx->channel[i]); + if (!channel) { + rc = -ENOMEM; + goto out; + } + other_channel[i] = channel; + } + + /* Swap entry counts and channel pointers */ + old_rxq_entries = efx->rxq_entries; + old_txq_entries = efx->txq_entries; + efx->rxq_entries = rxq_entries; + efx->txq_entries = txq_entries; + for (i = 0; i < efx->n_channels; i++) { + channel = efx->channel[i]; + efx->channel[i] = other_channel[i]; + other_channel[i] = channel; + } + + rc = efx_probe_channels(efx); + if (rc) + goto rollback; + + /* Destroy old channels */ + for (i = 0; i < efx->n_channels; i++) + efx_remove_channel(other_channel[i]); +out: + /* Free unused channel structures */ + for (i = 0; i < efx->n_channels; i++) + kfree(other_channel[i]); + + efx_init_channels(efx); + efx_start_all(efx); + return rc; + +rollback: + /* Swap back */ + efx->rxq_entries = old_rxq_entries; + efx->txq_entries = old_txq_entries; + for (i = 0; i < efx->n_channels; i++) { + channel = efx->channel[i]; + efx->channel[i] = other_channel[i]; + other_channel[i] = channel; + } + goto out; +} + void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue) { mod_timer(&rx_queue->slow_fill, jiffies + msecs_to_jiffies(100)); @@ -761,7 +920,7 @@ static int efx_probe_port(struct efx_nic *efx) /* Connect up MAC/PHY operations table */ rc = efx->type->probe_port(efx); if (rc) - goto err; + return rc; /* Sanity check MAC address */ if (is_valid_ether_addr(efx->mac_address)) { @@ -782,7 +941,7 @@ static int efx_probe_port(struct efx_nic *efx) return 0; err: - efx_remove_port(efx); + efx->type->remove_port(efx); return rc; } @@ -1050,7 +1209,8 @@ static void efx_probe_interrupts(struct efx_nic *efx) efx->n_rx_channels = efx->n_channels; } for (i = 0; i < n_channels; i++) - efx->channel[i].irq = xentries[i].vector; + efx_get_channel(efx, i)->irq = + xentries[i].vector; } else { /* Fall back to single channel MSI */ efx->interrupt_mode = EFX_INT_MODE_MSI; @@ -1066,7 +1226,7 @@ static void efx_probe_interrupts(struct efx_nic *efx) efx->n_tx_channels = 1; rc = pci_enable_msi(efx->pci_dev); if (rc == 0) { - efx->channel[0].irq = efx->pci_dev->irq; + efx_get_channel(efx, 0)->irq = efx->pci_dev->irq; } else { netif_err(efx, drv, efx->net_dev, "could not enable MSI\n"); @@ -1097,26 +1257,32 @@ static void efx_remove_interrupts(struct efx_nic *efx) efx->legacy_irq = 0; } +struct efx_tx_queue * +efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type) +{ + unsigned tx_channel_offset = + separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0; + EFX_BUG_ON_PARANOID(index >= efx->n_tx_channels || + type >= EFX_TXQ_TYPES); + return &efx->channel[tx_channel_offset + index]->tx_queue[type]; +} + static void efx_set_channels(struct efx_nic *efx) { struct efx_channel *channel; struct efx_tx_queue *tx_queue; - struct efx_rx_queue *rx_queue; unsigned tx_channel_offset = separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0; + /* Channel pointers were set in efx_init_struct() but we now + * need to clear them for TX queues in any RX-only channels. */ efx_for_each_channel(channel, efx) { - if (channel->channel - tx_channel_offset < efx->n_tx_channels) { - channel->tx_queue = &efx->tx_queue[ - (channel->channel - tx_channel_offset) * - EFX_TXQ_TYPES]; + if (channel->channel - tx_channel_offset >= + efx->n_tx_channels) { efx_for_each_channel_tx_queue(tx_queue, channel) - tx_queue->channel = channel; + tx_queue->channel = NULL; } } - - efx_for_each_rx_queue(rx_queue, efx) - rx_queue->channel = &efx->channel[rx_queue->queue]; } static int efx_probe_nic(struct efx_nic *efx) @@ -1141,7 +1307,8 @@ static int efx_probe_nic(struct efx_nic *efx) efx->rx_indir_table[i] = i % efx->n_rx_channels; efx_set_channels(efx); - efx->net_dev->real_num_tx_queues = efx->n_tx_channels; + netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels); + netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels); /* Initialise the interrupt moderation settings */ efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true); @@ -1165,40 +1332,37 @@ static void efx_remove_nic(struct efx_nic *efx) static int efx_probe_all(struct efx_nic *efx) { - struct efx_channel *channel; int rc; - /* Create NIC */ rc = efx_probe_nic(efx); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to create NIC\n"); goto fail1; } - /* Create port */ rc = efx_probe_port(efx); if (rc) { netif_err(efx, probe, efx->net_dev, "failed to create port\n"); goto fail2; } - /* Create channels */ - efx_for_each_channel(channel, efx) { - rc = efx_probe_channel(channel); - if (rc) { - netif_err(efx, probe, efx->net_dev, - "failed to create channel %d\n", - channel->channel); - goto fail3; - } + efx->rxq_entries = efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE; + rc = efx_probe_channels(efx); + if (rc) + goto fail3; + + rc = efx_probe_filters(efx); + if (rc) { + netif_err(efx, probe, efx->net_dev, + "failed to create filter tables\n"); + goto fail4; } - efx_set_channel_names(efx); return 0; + fail4: + efx_remove_channels(efx); fail3: - efx_for_each_channel(channel, efx) - efx_remove_channel(channel); efx_remove_port(efx); fail2: efx_remove_nic(efx); @@ -1328,10 +1492,8 @@ static void efx_stop_all(struct efx_nic *efx) static void efx_remove_all(struct efx_nic *efx) { - struct efx_channel *channel; - - efx_for_each_channel(channel, efx) - efx_remove_channel(channel); + efx_remove_filters(efx); + efx_remove_channels(efx); efx_remove_port(efx); efx_remove_nic(efx); } @@ -1355,20 +1517,20 @@ static unsigned irq_mod_ticks(int usecs, int resolution) void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, bool rx_adaptive) { - struct efx_tx_queue *tx_queue; - struct efx_rx_queue *rx_queue; + struct efx_channel *channel; unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION); unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION); EFX_ASSERT_RESET_SERIALISED(efx); - efx_for_each_tx_queue(tx_queue, efx) - tx_queue->channel->irq_moderation = tx_ticks; - efx->irq_rx_adaptive = rx_adaptive; efx->irq_rx_moderation = rx_ticks; - efx_for_each_rx_queue(rx_queue, efx) - rx_queue->channel->irq_moderation = rx_ticks; + efx_for_each_channel(channel, efx) { + if (efx_channel_get_rx_queue(channel)) + channel->irq_moderation = rx_ticks; + else if (efx_channel_get_tx_queue(channel, 0)) + channel->irq_moderation = tx_ticks; + } } /************************************************************************** @@ -1377,8 +1539,7 @@ void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, * **************************************************************************/ -/* Run periodically off the general workqueue. Serialised against - * efx_reconfigure_port via the mac_lock */ +/* Run periodically off the general workqueue */ static void efx_monitor(struct work_struct *data) { struct efx_nic *efx = container_of(data, struct efx_nic, @@ -1391,16 +1552,13 @@ static void efx_monitor(struct work_struct *data) /* If the mac_lock is already held then it is likely a port * reconfiguration is already in place, which will likely do - * most of the work of check_hw() anyway. */ - if (!mutex_trylock(&efx->mac_lock)) - goto out_requeue; - if (!efx->port_enabled) - goto out_unlock; - efx->type->monitor(efx); + * most of the work of monitor() anyway. */ + if (mutex_trylock(&efx->mac_lock)) { + if (efx->port_enabled) + efx->type->monitor(efx); + mutex_unlock(&efx->mac_lock); + } -out_unlock: - mutex_unlock(&efx->mac_lock); -out_requeue: queue_delayed_work(efx->workqueue, &efx->monitor_work, efx_monitor_interval); } @@ -1546,11 +1704,11 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc stats->tx_packets = mac_stats->tx_packets; stats->rx_bytes = mac_stats->rx_bytes; stats->tx_bytes = mac_stats->tx_bytes; + stats->rx_dropped = efx->n_rx_nodesc_drop_cnt; stats->multicast = mac_stats->rx_multicast; stats->collisions = mac_stats->tx_collision; stats->rx_length_errors = (mac_stats->rx_gtjumbo + mac_stats->rx_length_error); - stats->rx_over_errors = efx->n_rx_nodesc_drop_cnt; stats->rx_crc_errors = mac_stats->rx_bad; stats->rx_frame_errors = mac_stats->rx_align_error; stats->rx_fifo_errors = mac_stats->rx_overflow; @@ -1767,6 +1925,7 @@ static int efx_register_netdev(struct efx_nic *efx) static void efx_unregister_netdev(struct efx_nic *efx) { + struct efx_channel *channel; struct efx_tx_queue *tx_queue; if (!efx->net_dev) @@ -1777,8 +1936,10 @@ static void efx_unregister_netdev(struct efx_nic *efx) /* Free up any skbs still remaining. This has to happen before * we try to unregister the netdev as running their destructors * may be needed to get the device ref. count to 0. */ - efx_for_each_tx_queue(tx_queue, efx) - efx_release_tx_buffers(tx_queue); + efx_for_each_channel(channel, efx) { + efx_for_each_channel_tx_queue(tx_queue, channel) + efx_release_tx_buffers(tx_queue); + } if (efx_dev_registered(efx)) { strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); @@ -1841,6 +2002,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) efx->mac_op->reconfigure(efx); efx_init_channels(efx); + efx_restore_filters(efx); mutex_unlock(&efx->spi_lock); mutex_unlock(&efx->mac_lock); @@ -2010,10 +2172,8 @@ int efx_port_dummy_op_int(struct efx_nic *efx) return 0; } void efx_port_dummy_op_void(struct efx_nic *efx) {} -void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) -{ -} -bool efx_port_dummy_op_poll(struct efx_nic *efx) + +static bool efx_port_dummy_op_poll(struct efx_nic *efx) { return false; } @@ -2037,9 +2197,6 @@ static struct efx_phy_operations efx_dummy_phy_operations = { static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, struct pci_dev *pci_dev, struct net_device *net_dev) { - struct efx_channel *channel; - struct efx_tx_queue *tx_queue; - struct efx_rx_queue *rx_queue; int i; /* Initialise common structures */ @@ -2068,36 +2225,13 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, INIT_WORK(&efx->mac_work, efx_mac_work); for (i = 0; i < EFX_MAX_CHANNELS; i++) { - channel = &efx->channel[i]; - channel->efx = efx; - channel->channel = i; - channel->work_pending = false; - spin_lock_init(&channel->tx_stop_lock); - atomic_set(&channel->tx_stop_count, 1); - } - for (i = 0; i < EFX_MAX_TX_QUEUES; i++) { - tx_queue = &efx->tx_queue[i]; - tx_queue->efx = efx; - tx_queue->queue = i; - tx_queue->buffer = NULL; - tx_queue->channel = &efx->channel[0]; /* for safety */ - tx_queue->tso_headers_free = NULL; - } - for (i = 0; i < EFX_MAX_RX_QUEUES; i++) { - rx_queue = &efx->rx_queue[i]; - rx_queue->efx = efx; - rx_queue->queue = i; - rx_queue->channel = &efx->channel[0]; /* for safety */ - rx_queue->buffer = NULL; - setup_timer(&rx_queue->slow_fill, efx_rx_slow_fill, - (unsigned long)rx_queue); + efx->channel[i] = efx_alloc_channel(efx, i, NULL); + if (!efx->channel[i]) + goto fail; } efx->type = type; - /* As close as we can get to guaranteeing that we don't overflow */ - BUILD_BUG_ON(EFX_EVQ_SIZE < EFX_TXQ_SIZE + EFX_RXQ_SIZE); - EFX_BUG_ON_PARANOID(efx->type->phys_addr_channels > EFX_MAX_CHANNELS); /* Higher numbered interrupt modes are less capable! */ @@ -2109,13 +2243,22 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, pci_name(pci_dev)); efx->workqueue = create_singlethread_workqueue(efx->workqueue_name); if (!efx->workqueue) - return -ENOMEM; + goto fail; return 0; + +fail: + efx_fini_struct(efx); + return -ENOMEM; } static void efx_fini_struct(struct efx_nic *efx) { + int i; + + for (i = 0; i < EFX_MAX_CHANNELS; i++) + kfree(efx->channel[i]); + if (efx->workqueue) { destroy_workqueue(efx->workqueue); efx->workqueue = NULL; diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index 060dc952a0fd062f93ce21642d3a8471299c86e8..10a1bf40da962e729c3c8e3312a24cb7af08f8b5 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -12,6 +12,7 @@ #define EFX_EFX_H #include "net_driver.h" +#include "filter.h" /* PCI IDs */ #define EFX_VENDID_SFC 0x1924 @@ -37,8 +38,6 @@ efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb); extern void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index); extern void efx_stop_queue(struct efx_channel *channel); extern void efx_wake_queue(struct efx_channel *channel); -#define EFX_TXQ_SIZE 1024 -#define EFX_TXQ_MASK (EFX_TXQ_SIZE - 1) /* RX */ extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue); @@ -53,23 +52,42 @@ extern void __efx_rx_packet(struct efx_channel *channel, extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, unsigned int len, bool checksummed, bool discard); extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); -#define EFX_RXQ_SIZE 1024 -#define EFX_RXQ_MASK (EFX_RXQ_SIZE - 1) + +#define EFX_MAX_DMAQ_SIZE 4096UL +#define EFX_DEFAULT_DMAQ_SIZE 1024UL +#define EFX_MIN_DMAQ_SIZE 512UL + +#define EFX_MAX_EVQ_SIZE 16384UL +#define EFX_MIN_EVQ_SIZE 512UL + +/* The smallest [rt]xq_entries that the driver supports. Callers of + * efx_wake_queue() assume that they can subsequently send at least one + * skb. Falcon/A1 may require up to three descriptors per skb_frag. */ +#define EFX_MIN_RING_SIZE (roundup_pow_of_two(2 * 3 * MAX_SKB_FRAGS)) + +/* Filters */ +extern int efx_probe_filters(struct efx_nic *efx); +extern void efx_restore_filters(struct efx_nic *efx); +extern void efx_remove_filters(struct efx_nic *efx); +extern int efx_filter_insert_filter(struct efx_nic *efx, + struct efx_filter_spec *spec, + bool replace); +extern int efx_filter_remove_filter(struct efx_nic *efx, + struct efx_filter_spec *spec); +extern void efx_filter_table_clear(struct efx_nic *efx, + enum efx_filter_table_id table_id, + enum efx_filter_priority priority); /* Channels */ extern void efx_process_channel_now(struct efx_channel *channel); -#define EFX_EVQ_SIZE 4096 -#define EFX_EVQ_MASK (EFX_EVQ_SIZE - 1) +extern int +efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries); /* Ports */ extern int efx_reconfigure_port(struct efx_nic *efx); extern int __efx_reconfigure_port(struct efx_nic *efx); /* Ethtool support */ -extern int efx_ethtool_get_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd); -extern int efx_ethtool_set_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd); extern const struct ethtool_ops efx_ethtool_ops; /* Reset handling */ @@ -81,15 +99,11 @@ extern int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok); extern void efx_schedule_reset(struct efx_nic *efx, enum reset_type type); extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, int rx_usecs, bool rx_adaptive); -extern int efx_request_power(struct efx_nic *efx, int mw, const char *name); -extern void efx_hex_dump(const u8 *, unsigned int, const char *); /* Dummy PHY ops for PHY drivers */ extern int efx_port_dummy_op_int(struct efx_nic *efx); extern void efx_port_dummy_op_void(struct efx_nic *efx); -extern void -efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); -extern bool efx_port_dummy_op_poll(struct efx_nic *efx); + /* MTD */ #ifdef CONFIG_SFC_MTD @@ -102,8 +116,6 @@ static inline void efx_mtd_rename(struct efx_nic *efx) {} static inline void efx_mtd_remove(struct efx_nic *efx) {} #endif -extern unsigned int efx_monitor_interval; - static inline void efx_schedule_channel(struct efx_channel *channel) { netif_vdbg(channel->efx, intr, channel->efx->net_dev, diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index fd19d6ab97a256259db66636f2856bc3bf8ebe26..edb9d16b8b47b0f81f622bfd91b6e9fbf3a70f6a 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -15,6 +15,7 @@ #include "workarounds.h" #include "selftest.h" #include "efx.h" +#include "filter.h" #include "nic.h" #include "spi.h" #include "mdio_10g.h" @@ -186,8 +187,8 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count) } /* This must be called with rtnl_lock held. */ -int efx_ethtool_get_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd) +static int efx_ethtool_get_settings(struct net_device *net_dev, + struct ethtool_cmd *ecmd) { struct efx_nic *efx = netdev_priv(net_dev); struct efx_link_state *link_state = &efx->link_state; @@ -210,8 +211,8 @@ int efx_ethtool_get_settings(struct net_device *net_dev, } /* This must be called with rtnl_lock held. */ -int efx_ethtool_set_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd) +static int efx_ethtool_set_settings(struct net_device *net_dev, + struct ethtool_cmd *ecmd) { struct efx_nic *efx = netdev_priv(net_dev); int rc; @@ -328,9 +329,10 @@ static int efx_fill_loopback_test(struct efx_nic *efx, unsigned int test_index, struct ethtool_string *strings, u64 *data) { + struct efx_channel *channel = efx_get_channel(efx, 0); struct efx_tx_queue *tx_queue; - efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) { + efx_for_each_channel_tx_queue(tx_queue, channel) { efx_fill_test(test_index++, strings, data, &lb_tests->tx_sent[tx_queue->queue], EFX_TX_QUEUE_NAME(tx_queue), @@ -550,9 +552,22 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data) { struct efx_nic *efx = netdev_priv(net_dev); - u32 supported = efx->type->offload_features & ETH_FLAG_RXHASH; + u32 supported = (efx->type->offload_features & + (ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE)); + int rc; + + rc = ethtool_op_set_flags(net_dev, data, supported); + if (rc) + return rc; - return ethtool_op_set_flags(net_dev, data, supported); + if (!(data & ETH_FLAG_NTUPLE)) { + efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, + EFX_FILTER_PRI_MANUAL); + efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, + EFX_FILTER_PRI_MANUAL); + } + + return 0; } static void efx_ethtool_self_test(struct net_device *net_dev, @@ -673,15 +688,15 @@ static int efx_ethtool_get_coalesce(struct net_device *net_dev, struct ethtool_coalesce *coalesce) { struct efx_nic *efx = netdev_priv(net_dev); - struct efx_tx_queue *tx_queue; struct efx_channel *channel; memset(coalesce, 0, sizeof(*coalesce)); /* Find lowest IRQ moderation across all used TX queues */ coalesce->tx_coalesce_usecs_irq = ~((u32) 0); - efx_for_each_tx_queue(tx_queue, efx) { - channel = tx_queue->channel; + efx_for_each_channel(channel, efx) { + if (!efx_channel_get_tx_queue(channel, 0)) + continue; if (channel->irq_moderation < coalesce->tx_coalesce_usecs_irq) { if (channel->channel < efx->n_rx_channels) coalesce->tx_coalesce_usecs_irq = @@ -708,7 +723,6 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, { struct efx_nic *efx = netdev_priv(net_dev); struct efx_channel *channel; - struct efx_tx_queue *tx_queue; unsigned tx_usecs, rx_usecs, adaptive; if (coalesce->use_adaptive_tx_coalesce) @@ -725,8 +739,9 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, adaptive = coalesce->use_adaptive_rx_coalesce; /* If the channel is shared only allow RX parameters to be set */ - efx_for_each_tx_queue(tx_queue, efx) { - if ((tx_queue->channel->channel < efx->n_rx_channels) && + efx_for_each_channel(channel, efx) { + if (efx_channel_get_rx_queue(channel) && + efx_channel_get_tx_queue(channel, 0) && tx_usecs) { netif_err(efx, drv, efx->net_dev, "Channel is shared. " "Only RX coalescing may be set\n"); @@ -741,6 +756,42 @@ static int efx_ethtool_set_coalesce(struct net_device *net_dev, return 0; } +static void efx_ethtool_get_ringparam(struct net_device *net_dev, + struct ethtool_ringparam *ring) +{ + struct efx_nic *efx = netdev_priv(net_dev); + + ring->rx_max_pending = EFX_MAX_DMAQ_SIZE; + ring->tx_max_pending = EFX_MAX_DMAQ_SIZE; + ring->rx_mini_max_pending = 0; + ring->rx_jumbo_max_pending = 0; + ring->rx_pending = efx->rxq_entries; + ring->tx_pending = efx->txq_entries; + ring->rx_mini_pending = 0; + ring->rx_jumbo_pending = 0; +} + +static int efx_ethtool_set_ringparam(struct net_device *net_dev, + struct ethtool_ringparam *ring) +{ + struct efx_nic *efx = netdev_priv(net_dev); + + if (ring->rx_mini_pending || ring->rx_jumbo_pending || + ring->rx_pending > EFX_MAX_DMAQ_SIZE || + ring->tx_pending > EFX_MAX_DMAQ_SIZE) + return -EINVAL; + + if (ring->rx_pending < EFX_MIN_RING_SIZE || + ring->tx_pending < EFX_MIN_RING_SIZE) { + netif_err(efx, drv, efx->net_dev, + "TX and RX queues cannot be smaller than %ld\n", + EFX_MIN_RING_SIZE); + return -EINVAL; + } + + return efx_realloc_channels(efx, ring->rx_pending, ring->tx_pending); +} + static int efx_ethtool_set_pauseparam(struct net_device *net_dev, struct ethtool_pauseparam *pause) { @@ -840,7 +891,7 @@ static int efx_ethtool_set_wol(struct net_device *net_dev, return efx->type->set_wol(efx, wol->wolopts); } -extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) +static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) { struct efx_nic *efx = netdev_priv(net_dev); enum reset_type method; @@ -918,6 +969,105 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev, } } +static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev, + struct ethtool_rx_ntuple *ntuple) +{ + struct efx_nic *efx = netdev_priv(net_dev); + struct ethtool_tcpip4_spec *ip_entry = &ntuple->fs.h_u.tcp_ip4_spec; + struct ethtool_tcpip4_spec *ip_mask = &ntuple->fs.m_u.tcp_ip4_spec; + struct ethhdr *mac_entry = &ntuple->fs.h_u.ether_spec; + struct ethhdr *mac_mask = &ntuple->fs.m_u.ether_spec; + struct efx_filter_spec filter; + + /* Range-check action */ + if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR || + ntuple->fs.action >= (s32)efx->n_rx_channels) + return -EINVAL; + + if (~ntuple->fs.data_mask) + return -EINVAL; + + switch (ntuple->fs.flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + /* Must match all of destination, */ + if (ip_mask->ip4dst | ip_mask->pdst) + return -EINVAL; + /* all or none of source, */ + if ((ip_mask->ip4src | ip_mask->psrc) && + ((__force u32)~ip_mask->ip4src | + (__force u16)~ip_mask->psrc)) + return -EINVAL; + /* and nothing else */ + if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask) + return -EINVAL; + break; + case ETHER_FLOW: + /* Must match all of destination, */ + if (!is_zero_ether_addr(mac_mask->h_dest)) + return -EINVAL; + /* all or none of VID, */ + if (ntuple->fs.vlan_tag_mask != 0xf000 && + ntuple->fs.vlan_tag_mask != 0xffff) + return -EINVAL; + /* and nothing else */ + if (!is_broadcast_ether_addr(mac_mask->h_source) || + mac_mask->h_proto != htons(0xffff)) + return -EINVAL; + break; + default: + return -EINVAL; + } + + filter.priority = EFX_FILTER_PRI_MANUAL; + filter.flags = 0; + + switch (ntuple->fs.flow_type) { + case TCP_V4_FLOW: + if (!ip_mask->ip4src) + efx_filter_set_rx_tcp_full(&filter, + htonl(ip_entry->ip4src), + htons(ip_entry->psrc), + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + else + efx_filter_set_rx_tcp_wild(&filter, + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + break; + case UDP_V4_FLOW: + if (!ip_mask->ip4src) + efx_filter_set_rx_udp_full(&filter, + htonl(ip_entry->ip4src), + htons(ip_entry->psrc), + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + else + efx_filter_set_rx_udp_wild(&filter, + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + break; + case ETHER_FLOW: + if (ntuple->fs.vlan_tag_mask == 0xf000) + efx_filter_set_rx_mac_full(&filter, + ntuple->fs.vlan_tag & 0xfff, + mac_entry->h_dest); + else + efx_filter_set_rx_mac_wild(&filter, mac_entry->h_dest); + break; + } + + if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) { + return efx_filter_remove_filter(efx, &filter); + } else { + if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) + filter.dmaq_id = 0xfff; + else + filter.dmaq_id = ntuple->fs.action; + return efx_filter_insert_filter(efx, &filter, true); + } +} + static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, struct ethtool_rxfh_indir *indir) { @@ -971,6 +1121,8 @@ const struct ethtool_ops efx_ethtool_ops = { .set_eeprom = efx_ethtool_set_eeprom, .get_coalesce = efx_ethtool_get_coalesce, .set_coalesce = efx_ethtool_set_coalesce, + .get_ringparam = efx_ethtool_get_ringparam, + .set_ringparam = efx_ethtool_set_ringparam, .get_pauseparam = efx_ethtool_get_pauseparam, .set_pauseparam = efx_ethtool_set_pauseparam, .get_rx_csum = efx_ethtool_get_rx_csum, @@ -994,6 +1146,7 @@ const struct ethtool_ops efx_ethtool_ops = { .set_wol = efx_ethtool_set_wol, .reset = efx_ethtool_reset, .get_rxnfc = efx_ethtool_get_rxnfc, + .set_rx_ntuple = efx_ethtool_set_rx_ntuple, .get_rxfh_indir = efx_ethtool_get_rxfh_indir, .set_rxfh_indir = efx_ethtool_set_rxfh_indir, }; diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 4f9d33f3cca1899a9fa745af4cb49c734383031f..267019bb2b156815f269a9ae4429ceec6d4e2d7a 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -159,7 +159,6 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) { struct efx_nic *efx = dev_id; efx_oword_t *int_ker = efx->irq_status.addr; - struct efx_channel *channel; int syserr; int queues; @@ -194,15 +193,10 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) wmb(); /* Ensure the vector is cleared before interrupt ack */ falcon_irq_ack_a1(efx); - /* Schedule processing of any interrupting queues */ - channel = &efx->channel[0]; - while (queues) { - if (queues & 0x01) - efx_schedule_channel(channel); - channel++; - queues >>= 1; - } - + if (queues & 1) + efx_schedule_channel(efx_get_channel(efx, 0)); + if (queues & 2) + efx_schedule_channel(efx_get_channel(efx, 1)); return IRQ_HANDLED; } /************************************************************************** @@ -452,30 +446,19 @@ static void falcon_reset_macs(struct efx_nic *efx) /* It's not safe to use GLB_CTL_REG to reset the * macs, so instead use the internal MAC resets */ - if (!EFX_IS10G(efx)) { - EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 1); - efx_writeo(efx, ®, FR_AB_GM_CFG1); - udelay(1000); - - EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_SW_RST, 0); - efx_writeo(efx, ®, FR_AB_GM_CFG1); - udelay(1000); - return; - } else { - EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); - efx_writeo(efx, ®, FR_AB_XM_GLB_CFG); - - for (count = 0; count < 10000; count++) { - efx_reado(efx, ®, FR_AB_XM_GLB_CFG); - if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == - 0) - return; - udelay(10); - } - - netif_err(efx, hw, efx->net_dev, - "timed out waiting for XMAC core reset\n"); + EFX_POPULATE_OWORD_1(reg, FRF_AB_XM_CORE_RST, 1); + efx_writeo(efx, ®, FR_AB_XM_GLB_CFG); + + for (count = 0; count < 10000; count++) { + efx_reado(efx, ®, FR_AB_XM_GLB_CFG); + if (EFX_OWORD_FIELD(reg, FRF_AB_XM_CORE_RST) == + 0) + return; + udelay(10); } + + netif_err(efx, hw, efx->net_dev, + "timed out waiting for XMAC core reset\n"); } /* Mac stats will fail whist the TX fifo is draining */ @@ -514,7 +497,6 @@ static void falcon_reset_macs(struct efx_nic *efx) * are re-enabled by the caller */ efx_writeo(efx, &mac_ctrl, FR_AB_MAC_CTRL); - /* This can run even when the GMAC is selected */ falcon_setup_xaui(efx); } @@ -652,8 +634,6 @@ static void falcon_stats_timer_func(unsigned long context) spin_unlock(&efx->stats_lock); } -static void falcon_switch_mac(struct efx_nic *efx); - static bool falcon_loopback_link_poll(struct efx_nic *efx) { struct efx_link_state old_state = efx->link_state; @@ -664,11 +644,7 @@ static bool falcon_loopback_link_poll(struct efx_nic *efx) efx->link_state.fd = true; efx->link_state.fc = efx->wanted_fc; efx->link_state.up = true; - - if (efx->loopback_mode == LOOPBACK_GMAC) - efx->link_state.speed = 1000; - else - efx->link_state.speed = 10000; + efx->link_state.speed = 10000; return !efx_link_state_equal(&efx->link_state, &old_state); } @@ -691,7 +667,7 @@ static int falcon_reconfigure_port(struct efx_nic *efx) falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); - falcon_switch_mac(efx); + falcon_reset_macs(efx); efx->phy_op->reconfigure(efx); rc = efx->mac_op->reconfigure(efx); @@ -841,73 +817,23 @@ static int falcon_mdio_read(struct net_device *net_dev, return rc; } -static void falcon_clock_mac(struct efx_nic *efx) -{ - unsigned strap_val; - efx_oword_t nic_stat; - - /* Configure the NIC generated MAC clock correctly */ - efx_reado(efx, &nic_stat, FR_AB_NIC_STAT); - strap_val = EFX_IS10G(efx) ? 5 : 3; - if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { - EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP_EN, 1); - EFX_SET_OWORD_FIELD(nic_stat, FRF_BB_EE_STRAP, strap_val); - efx_writeo(efx, &nic_stat, FR_AB_NIC_STAT); - } else { - /* Falcon A1 does not support 1G/10G speed switching - * and must not be used with a PHY that does. */ - BUG_ON(EFX_OWORD_FIELD(nic_stat, FRF_AB_STRAP_PINS) != - strap_val); - } -} - -static void falcon_switch_mac(struct efx_nic *efx) -{ - struct efx_mac_operations *old_mac_op = efx->mac_op; - struct falcon_nic_data *nic_data = efx->nic_data; - unsigned int stats_done_offset; - - WARN_ON(!mutex_is_locked(&efx->mac_lock)); - WARN_ON(nic_data->stats_disable_count == 0); - - efx->mac_op = (EFX_IS10G(efx) ? - &falcon_xmac_operations : &falcon_gmac_operations); - - if (EFX_IS10G(efx)) - stats_done_offset = XgDmaDone_offset; - else - stats_done_offset = GDmaDone_offset; - nic_data->stats_dma_done = efx->stats_buffer.addr + stats_done_offset; - - if (old_mac_op == efx->mac_op) - return; - - falcon_clock_mac(efx); - - netif_dbg(efx, hw, efx->net_dev, "selected %cMAC\n", - EFX_IS10G(efx) ? 'X' : 'G'); - /* Not all macs support a mac-level link state */ - efx->xmac_poll_required = false; - falcon_reset_macs(efx); -} - /* This call is responsible for hooking in the MAC and PHY operations */ static int falcon_probe_port(struct efx_nic *efx) { + struct falcon_nic_data *nic_data = efx->nic_data; int rc; switch (efx->phy_type) { case PHY_TYPE_SFX7101: efx->phy_op = &falcon_sfx7101_phy_ops; break; - case PHY_TYPE_SFT9001A: - case PHY_TYPE_SFT9001B: - efx->phy_op = &falcon_sft9001_phy_ops; - break; case PHY_TYPE_QT2022C2: case PHY_TYPE_QT2025C: efx->phy_op = &falcon_qt202x_phy_ops; break; + case PHY_TYPE_TXC43128: + efx->phy_op = &falcon_txc_phy_ops; + break; default: netif_err(efx, probe, efx->net_dev, "Unknown PHY type %d\n", efx->phy_type); @@ -943,6 +869,7 @@ static int falcon_probe_port(struct efx_nic *efx) (u64)efx->stats_buffer.dma_addr, efx->stats_buffer.addr, (u64)virt_to_phys(efx->stats_buffer.addr)); + nic_data->stats_dma_done = efx->stats_buffer.addr + XgDmaDone_offset; return 0; } @@ -1207,7 +1134,7 @@ static void falcon_monitor(struct efx_nic *efx) falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); - falcon_switch_mac(efx); + falcon_reset_macs(efx); rc = efx->mac_op->reconfigure(efx); BUG_ON(rc); @@ -1216,8 +1143,7 @@ static void falcon_monitor(struct efx_nic *efx) efx_link_status_changed(efx); } - if (EFX_IS10G(efx)) - falcon_poll_xmac(efx); + falcon_poll_xmac(efx); } /* Zeroes out the SRAM contents. This routine must be called in @@ -1610,16 +1536,6 @@ static int falcon_init_nic(struct efx_nic *efx) EFX_SET_OWORD_FIELD(temp, FRF_AB_ONCHIP_SRAM, 1); efx_writeo(efx, &temp, FR_AB_NIC_STAT); - /* Set the source of the GMAC clock */ - if (efx_nic_rev(efx) == EFX_REV_FALCON_B0) { - efx_reado(efx, &temp, FR_AB_GPIO_CTL); - EFX_SET_OWORD_FIELD(temp, FRF_AB_USE_NIC_CLK, true); - efx_writeo(efx, &temp, FR_AB_GPIO_CTL); - } - - /* Select the correct MAC */ - falcon_clock_mac(efx); - rc = falcon_reset_sram(efx); if (rc) return rc; @@ -1880,7 +1796,7 @@ struct efx_nic_type falcon_b0_nic_type = { * channels */ .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, - .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH, + .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, .reset_world_flags = ETH_RESET_IRQ, }; diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c index 3d950c2cf205965d6aafced30330acd235d48734..cfc6a5b5a4770a3e2c48446b7dc168dbba318ceb 100644 --- a/drivers/net/sfc/falcon_boards.c +++ b/drivers/net/sfc/falcon_boards.c @@ -26,7 +26,7 @@ /* Board types */ #define FALCON_BOARD_SFE4001 0x01 #define FALCON_BOARD_SFE4002 0x02 -#define FALCON_BOARD_SFN4111T 0x51 +#define FALCON_BOARD_SFE4003 0x03 #define FALCON_BOARD_SFN4112F 0x52 /* Board temperature is about 15°C above ambient when air flow is @@ -142,17 +142,17 @@ static inline int efx_check_lm87(struct efx_nic *efx, unsigned mask) #endif /* CONFIG_SENSORS_LM87 */ /***************************************************************************** - * Support for the SFE4001 and SFN4111T NICs. + * Support for the SFE4001 NIC. * * The SFE4001 does not power-up fully at reset due to its high power * consumption. We control its power via a PCA9539 I/O expander. - * Both boards have a MAX6647 temperature monitor which we expose to + * It also has a MAX6647 temperature monitor which we expose to * the lm90 driver. * * This also provides minimal support for reflashing the PHY, which is * initiated by resetting it with the FLASH_CFG_1 pin pulled down. * On SFE4001 rev A2 and later this is connected to the 3V3X output of - * the IO-expander; on the SFN4111T it is connected to Falcon's GPIO3. + * the IO-expander. * We represent reflash mode as PHY_MODE_SPECIAL and make it mutually * exclusive with the network device being open. */ @@ -304,34 +304,6 @@ static int sfe4001_poweron(struct efx_nic *efx) return rc; } -static int sfn4111t_reset(struct efx_nic *efx) -{ - struct falcon_board *board = falcon_board(efx); - efx_oword_t reg; - - /* GPIO 3 and the GPIO register are shared with I2C, so block that */ - i2c_lock_adapter(&board->i2c_adap); - - /* Pull RST_N (GPIO 2) low then let it up again, setting the - * FLASH_CFG_1 strap (GPIO 3) appropriately. Only change the - * output enables; the output levels should always be 0 (low) - * and we rely on external pull-ups. */ - efx_reado(efx, ®, FR_AB_GPIO_CTL); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, true); - efx_writeo(efx, ®, FR_AB_GPIO_CTL); - msleep(1000); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO2_OEN, false); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GPIO3_OEN, - !!(efx->phy_mode & PHY_MODE_SPECIAL)); - efx_writeo(efx, ®, FR_AB_GPIO_CTL); - msleep(1); - - i2c_unlock_adapter(&board->i2c_adap); - - ssleep(1); - return 0; -} - static ssize_t show_phy_flash_cfg(struct device *dev, struct device_attribute *attr, char *buf) { @@ -363,10 +335,7 @@ static ssize_t set_phy_flash_cfg(struct device *dev, efx->phy_mode = new_mode; if (new_mode & PHY_MODE_SPECIAL) falcon_stop_nic_stats(efx); - if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001) - err = sfe4001_poweron(efx); - else - err = sfn4111t_reset(efx); + err = sfe4001_poweron(efx); if (!err) err = efx_reconfigure_port(efx); if (!(new_mode & PHY_MODE_SPECIAL)) @@ -479,83 +448,6 @@ static int sfe4001_init(struct efx_nic *efx) return rc; } -static int sfn4111t_check_hw(struct efx_nic *efx) -{ - s32 status; - - /* If XAUI link is up then do not monitor */ - if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required) - return 0; - - /* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */ - status = i2c_smbus_read_byte_data(falcon_board(efx)->hwmon_client, - MAX664X_REG_RSL); - if (status < 0) - return -EIO; - if (status & 0x57) - return -ERANGE; - return 0; -} - -static void sfn4111t_fini(struct efx_nic *efx) -{ - netif_info(efx, drv, efx->net_dev, "%s\n", __func__); - - device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); - i2c_unregister_device(falcon_board(efx)->hwmon_client); -} - -static struct i2c_board_info sfn4111t_a0_hwmon_info = { - I2C_BOARD_INFO("max6647", 0x4e), -}; - -static struct i2c_board_info sfn4111t_r5_hwmon_info = { - I2C_BOARD_INFO("max6646", 0x4d), -}; - -static void sfn4111t_init_phy(struct efx_nic *efx) -{ - if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { - if (sft9001_wait_boot(efx) != -EINVAL) - return; - - efx->phy_mode = PHY_MODE_SPECIAL; - falcon_stop_nic_stats(efx); - } - - sfn4111t_reset(efx); - sft9001_wait_boot(efx); -} - -static int sfn4111t_init(struct efx_nic *efx) -{ - struct falcon_board *board = falcon_board(efx); - int rc; - - board->hwmon_client = - i2c_new_device(&board->i2c_adap, - (board->minor < 5) ? - &sfn4111t_a0_hwmon_info : - &sfn4111t_r5_hwmon_info); - if (!board->hwmon_client) - return -EIO; - - rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg); - if (rc) - goto fail_hwmon; - - if (efx->phy_mode & PHY_MODE_SPECIAL) - /* PHY may not generate a 156.25 MHz clock and MAC - * stats fetch will fail. */ - falcon_stop_nic_stats(efx); - - return 0; - -fail_hwmon: - i2c_unregister_device(board->hwmon_client); - return rc; -} - /***************************************************************************** * Support for the SFE4002 * @@ -691,6 +583,75 @@ static int sfn4112f_init(struct efx_nic *efx) return efx_init_lm87(efx, &sfn4112f_hwmon_info, sfn4112f_lm87_regs); } +/***************************************************************************** + * Support for the SFE4003 + * + */ +static u8 sfe4003_lm87_channel = 0x03; /* use AIN not FAN inputs */ + +static const u8 sfe4003_lm87_regs[] = { + LM87_IN_LIMITS(0, 0x67, 0x7f), /* 2.5V: 1.5V +/- 10% */ + LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */ + LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */ + LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */ + LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */ + LM87_TEMP_INT_LIMITS(0, 70 + FALCON_BOARD_TEMP_BIAS), + 0 +}; + +static struct i2c_board_info sfe4003_hwmon_info = { + I2C_BOARD_INFO("lm87", 0x2e), + .platform_data = &sfe4003_lm87_channel, +}; + +/* Board-specific LED info. */ +#define SFE4003_RED_LED_GPIO 11 +#define SFE4003_LED_ON 1 +#define SFE4003_LED_OFF 0 + +static void sfe4003_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) +{ + struct falcon_board *board = falcon_board(efx); + + /* The LEDs were not wired to GPIOs before A3 */ + if (board->minor < 3 && board->major == 0) + return; + + falcon_txc_set_gpio_val( + efx, SFE4003_RED_LED_GPIO, + (mode == EFX_LED_ON) ? SFE4003_LED_ON : SFE4003_LED_OFF); +} + +static void sfe4003_init_phy(struct efx_nic *efx) +{ + struct falcon_board *board = falcon_board(efx); + + /* The LEDs were not wired to GPIOs before A3 */ + if (board->minor < 3 && board->major == 0) + return; + + falcon_txc_set_gpio_dir(efx, SFE4003_RED_LED_GPIO, TXC_GPIO_DIR_OUTPUT); + falcon_txc_set_gpio_val(efx, SFE4003_RED_LED_GPIO, SFE4003_LED_OFF); +} + +static int sfe4003_check_hw(struct efx_nic *efx) +{ + struct falcon_board *board = falcon_board(efx); + + /* A0/A1/A2 board rev. 4003s report a temperature fault the whole time + * (bad sensor) so we mask it out. */ + unsigned alarm_mask = + (board->major == 0 && board->minor <= 2) ? + ~LM87_ALARM_TEMP_EXT1 : ~0; + + return efx_check_lm87(efx, alarm_mask); +} + +static int sfe4003_init(struct efx_nic *efx) +{ + return efx_init_lm87(efx, &sfe4003_hwmon_info, sfe4003_lm87_regs); +} + static const struct falcon_board_type board_types[] = { { .id = FALCON_BOARD_SFE4001, @@ -713,14 +674,14 @@ static const struct falcon_board_type board_types[] = { .monitor = sfe4002_check_hw, }, { - .id = FALCON_BOARD_SFN4111T, - .ref_model = "SFN4111T", - .gen_type = "100/1000/10GBASE-T adapter", - .init = sfn4111t_init, - .init_phy = sfn4111t_init_phy, - .fini = sfn4111t_fini, - .set_id_led = tenxpress_set_id_led, - .monitor = sfn4111t_check_hw, + .id = FALCON_BOARD_SFE4003, + .ref_model = "SFE4003", + .gen_type = "10GBASE-CX4 adapter", + .init = sfe4003_init, + .init_phy = sfe4003_init_phy, + .fini = efx_fini_lm87, + .set_id_led = sfe4003_set_id_led, + .monitor = sfe4003_check_hw, }, { .id = FALCON_BOARD_SFN4112F, diff --git a/drivers/net/sfc/falcon_gmac.c b/drivers/net/sfc/falcon_gmac.c deleted file mode 100644 index 7dadfcbd6ce7e75e8c22a1e3a6a4ce89de1ce21e..0000000000000000000000000000000000000000 --- a/drivers/net/sfc/falcon_gmac.c +++ /dev/null @@ -1,230 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ - -#include -#include "net_driver.h" -#include "efx.h" -#include "nic.h" -#include "mac.h" -#include "regs.h" -#include "io.h" - -/************************************************************************** - * - * MAC operations - * - *************************************************************************/ - -static int falcon_reconfigure_gmac(struct efx_nic *efx) -{ - struct efx_link_state *link_state = &efx->link_state; - bool loopback, tx_fc, rx_fc, bytemode; - int if_mode; - unsigned int max_frame_len; - efx_oword_t reg; - - /* Configuration register 1 */ - tx_fc = (link_state->fc & EFX_FC_TX) || !link_state->fd; - rx_fc = !!(link_state->fc & EFX_FC_RX); - loopback = (efx->loopback_mode == LOOPBACK_GMAC); - bytemode = (link_state->speed == 1000); - - EFX_POPULATE_OWORD_5(reg, - FRF_AB_GM_LOOP, loopback, - FRF_AB_GM_TX_EN, 1, - FRF_AB_GM_TX_FC_EN, tx_fc, - FRF_AB_GM_RX_EN, 1, - FRF_AB_GM_RX_FC_EN, rx_fc); - efx_writeo(efx, ®, FR_AB_GM_CFG1); - udelay(10); - - /* Configuration register 2 */ - if_mode = (bytemode) ? 2 : 1; - EFX_POPULATE_OWORD_5(reg, - FRF_AB_GM_IF_MODE, if_mode, - FRF_AB_GM_PAD_CRC_EN, 1, - FRF_AB_GM_LEN_CHK, 1, - FRF_AB_GM_FD, link_state->fd, - FRF_AB_GM_PAMBL_LEN, 0x7/*datasheet recommended */); - - efx_writeo(efx, ®, FR_AB_GM_CFG2); - udelay(10); - - /* Max frame len register */ - max_frame_len = EFX_MAX_FRAME_LEN(efx->net_dev->mtu); - EFX_POPULATE_OWORD_1(reg, FRF_AB_GM_MAX_FLEN, max_frame_len); - efx_writeo(efx, ®, FR_AB_GM_MAX_FLEN); - udelay(10); - - /* FIFO configuration register 0 */ - EFX_POPULATE_OWORD_5(reg, - FRF_AB_GMF_FTFENREQ, 1, - FRF_AB_GMF_STFENREQ, 1, - FRF_AB_GMF_FRFENREQ, 1, - FRF_AB_GMF_SRFENREQ, 1, - FRF_AB_GMF_WTMENREQ, 1); - efx_writeo(efx, ®, FR_AB_GMF_CFG0); - udelay(10); - - /* FIFO configuration register 1 */ - EFX_POPULATE_OWORD_2(reg, - FRF_AB_GMF_CFGFRTH, 0x12, - FRF_AB_GMF_CFGXOFFRTX, 0xffff); - efx_writeo(efx, ®, FR_AB_GMF_CFG1); - udelay(10); - - /* FIFO configuration register 2 */ - EFX_POPULATE_OWORD_2(reg, - FRF_AB_GMF_CFGHWM, 0x3f, - FRF_AB_GMF_CFGLWM, 0xa); - efx_writeo(efx, ®, FR_AB_GMF_CFG2); - udelay(10); - - /* FIFO configuration register 3 */ - EFX_POPULATE_OWORD_2(reg, - FRF_AB_GMF_CFGHWMFT, 0x1c, - FRF_AB_GMF_CFGFTTH, 0x08); - efx_writeo(efx, ®, FR_AB_GMF_CFG3); - udelay(10); - - /* FIFO configuration register 4 */ - EFX_POPULATE_OWORD_1(reg, FRF_AB_GMF_HSTFLTRFRM_PAUSE, 1); - efx_writeo(efx, ®, FR_AB_GMF_CFG4); - udelay(10); - - /* FIFO configuration register 5 */ - efx_reado(efx, ®, FR_AB_GMF_CFG5); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGBYTMODE, bytemode); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_CFGHDPLX, !link_state->fd); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTDRPLT64, !link_state->fd); - EFX_SET_OWORD_FIELD(reg, FRF_AB_GMF_HSTFLTRFRMDC_PAUSE, 0); - efx_writeo(efx, ®, FR_AB_GMF_CFG5); - udelay(10); - - /* MAC address */ - EFX_POPULATE_OWORD_4(reg, - FRF_AB_GM_ADR_B0, efx->net_dev->dev_addr[5], - FRF_AB_GM_ADR_B1, efx->net_dev->dev_addr[4], - FRF_AB_GM_ADR_B2, efx->net_dev->dev_addr[3], - FRF_AB_GM_ADR_B3, efx->net_dev->dev_addr[2]); - efx_writeo(efx, ®, FR_AB_GM_ADR1); - udelay(10); - EFX_POPULATE_OWORD_2(reg, - FRF_AB_GM_ADR_B4, efx->net_dev->dev_addr[1], - FRF_AB_GM_ADR_B5, efx->net_dev->dev_addr[0]); - efx_writeo(efx, ®, FR_AB_GM_ADR2); - udelay(10); - - falcon_reconfigure_mac_wrapper(efx); - - return 0; -} - -static void falcon_update_stats_gmac(struct efx_nic *efx) -{ - struct efx_mac_stats *mac_stats = &efx->mac_stats; - unsigned long old_rx_pause, old_tx_pause; - unsigned long new_rx_pause, new_tx_pause; - - /* Pause frames are erroneously counted as errors (SFC bug 3269) */ - old_rx_pause = mac_stats->rx_pause; - old_tx_pause = mac_stats->tx_pause; - - /* Update MAC stats from DMAed values */ - FALCON_STAT(efx, GRxGoodOct, rx_good_bytes); - FALCON_STAT(efx, GRxBadOct, rx_bad_bytes); - FALCON_STAT(efx, GRxMissPkt, rx_missed); - FALCON_STAT(efx, GRxFalseCRS, rx_false_carrier); - FALCON_STAT(efx, GRxPausePkt, rx_pause); - FALCON_STAT(efx, GRxBadPkt, rx_bad); - FALCON_STAT(efx, GRxUcastPkt, rx_unicast); - FALCON_STAT(efx, GRxMcastPkt, rx_multicast); - FALCON_STAT(efx, GRxBcastPkt, rx_broadcast); - FALCON_STAT(efx, GRxGoodLt64Pkt, rx_good_lt64); - FALCON_STAT(efx, GRxBadLt64Pkt, rx_bad_lt64); - FALCON_STAT(efx, GRx64Pkt, rx_64); - FALCON_STAT(efx, GRx65to127Pkt, rx_65_to_127); - FALCON_STAT(efx, GRx128to255Pkt, rx_128_to_255); - FALCON_STAT(efx, GRx256to511Pkt, rx_256_to_511); - FALCON_STAT(efx, GRx512to1023Pkt, rx_512_to_1023); - FALCON_STAT(efx, GRx1024to15xxPkt, rx_1024_to_15xx); - FALCON_STAT(efx, GRx15xxtoJumboPkt, rx_15xx_to_jumbo); - FALCON_STAT(efx, GRxGtJumboPkt, rx_gtjumbo); - FALCON_STAT(efx, GRxFcsErr64to15xxPkt, rx_bad_64_to_15xx); - FALCON_STAT(efx, GRxFcsErr15xxtoJumboPkt, rx_bad_15xx_to_jumbo); - FALCON_STAT(efx, GRxFcsErrGtJumboPkt, rx_bad_gtjumbo); - FALCON_STAT(efx, GTxGoodBadOct, tx_bytes); - FALCON_STAT(efx, GTxGoodOct, tx_good_bytes); - FALCON_STAT(efx, GTxSglColPkt, tx_single_collision); - FALCON_STAT(efx, GTxMultColPkt, tx_multiple_collision); - FALCON_STAT(efx, GTxExColPkt, tx_excessive_collision); - FALCON_STAT(efx, GTxDefPkt, tx_deferred); - FALCON_STAT(efx, GTxLateCol, tx_late_collision); - FALCON_STAT(efx, GTxExDefPkt, tx_excessive_deferred); - FALCON_STAT(efx, GTxPausePkt, tx_pause); - FALCON_STAT(efx, GTxBadPkt, tx_bad); - FALCON_STAT(efx, GTxUcastPkt, tx_unicast); - FALCON_STAT(efx, GTxMcastPkt, tx_multicast); - FALCON_STAT(efx, GTxBcastPkt, tx_broadcast); - FALCON_STAT(efx, GTxLt64Pkt, tx_lt64); - FALCON_STAT(efx, GTx64Pkt, tx_64); - FALCON_STAT(efx, GTx65to127Pkt, tx_65_to_127); - FALCON_STAT(efx, GTx128to255Pkt, tx_128_to_255); - FALCON_STAT(efx, GTx256to511Pkt, tx_256_to_511); - FALCON_STAT(efx, GTx512to1023Pkt, tx_512_to_1023); - FALCON_STAT(efx, GTx1024to15xxPkt, tx_1024_to_15xx); - FALCON_STAT(efx, GTx15xxtoJumboPkt, tx_15xx_to_jumbo); - FALCON_STAT(efx, GTxGtJumboPkt, tx_gtjumbo); - FALCON_STAT(efx, GTxNonTcpUdpPkt, tx_non_tcpudp); - FALCON_STAT(efx, GTxMacSrcErrPkt, tx_mac_src_error); - FALCON_STAT(efx, GTxIpSrcErrPkt, tx_ip_src_error); - - /* Pause frames are erroneously counted as errors (SFC bug 3269) */ - new_rx_pause = mac_stats->rx_pause; - new_tx_pause = mac_stats->tx_pause; - mac_stats->rx_bad -= (new_rx_pause - old_rx_pause); - mac_stats->tx_bad -= (new_tx_pause - old_tx_pause); - - /* Derive stats that the MAC doesn't provide directly */ - mac_stats->tx_bad_bytes = - mac_stats->tx_bytes - mac_stats->tx_good_bytes; - mac_stats->tx_packets = - mac_stats->tx_lt64 + mac_stats->tx_64 + - mac_stats->tx_65_to_127 + mac_stats->tx_128_to_255 + - mac_stats->tx_256_to_511 + mac_stats->tx_512_to_1023 + - mac_stats->tx_1024_to_15xx + mac_stats->tx_15xx_to_jumbo + - mac_stats->tx_gtjumbo; - mac_stats->tx_collision = - mac_stats->tx_single_collision + - mac_stats->tx_multiple_collision + - mac_stats->tx_excessive_collision + - mac_stats->tx_late_collision; - mac_stats->rx_bytes = - mac_stats->rx_good_bytes + mac_stats->rx_bad_bytes; - mac_stats->rx_packets = - mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64 + - mac_stats->rx_64 + mac_stats->rx_65_to_127 + - mac_stats->rx_128_to_255 + mac_stats->rx_256_to_511 + - mac_stats->rx_512_to_1023 + mac_stats->rx_1024_to_15xx + - mac_stats->rx_15xx_to_jumbo + mac_stats->rx_gtjumbo; - mac_stats->rx_good = mac_stats->rx_packets - mac_stats->rx_bad; - mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64; -} - -static bool falcon_gmac_check_fault(struct efx_nic *efx) -{ - return false; -} - -struct efx_mac_operations falcon_gmac_operations = { - .reconfigure = falcon_reconfigure_gmac, - .update_stats = falcon_update_stats_gmac, - .check_fault = falcon_gmac_check_fault, -}; diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index bae656dd2c4ee800d161caf3d47255aca07dae40..b31f595ebb5b6c3426e968d7d790cd1409f8518d 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -143,7 +143,7 @@ static bool falcon_xmac_link_ok(struct efx_nic *efx) efx_mdio_phyxgxs_lane_sync(efx)); } -void falcon_reconfigure_xmac_core(struct efx_nic *efx) +static void falcon_reconfigure_xmac_core(struct efx_nic *efx) { unsigned int max_frame_len; efx_oword_t reg; diff --git a/drivers/net/sfc/filter.c b/drivers/net/sfc/filter.c new file mode 100644 index 0000000000000000000000000000000000000000..52cb6082b910cd3c2a6072662a750691b6bc2173 --- /dev/null +++ b/drivers/net/sfc/filter.c @@ -0,0 +1,454 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2005-2010 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include "efx.h" +#include "filter.h" +#include "io.h" +#include "nic.h" +#include "regs.h" + +/* "Fudge factors" - difference between programmed value and actual depth. + * Due to pipelined implementation we need to program H/W with a value that + * is larger than the hop limit we want. + */ +#define FILTER_CTL_SRCH_FUDGE_WILD 3 +#define FILTER_CTL_SRCH_FUDGE_FULL 1 + +/* Hard maximum hop limit. Hardware will time-out beyond 200-something. + * We also need to avoid infinite loops in efx_filter_search() when the + * table is full. + */ +#define FILTER_CTL_SRCH_MAX 200 + +struct efx_filter_table { + u32 offset; /* address of table relative to BAR */ + unsigned size; /* number of entries */ + unsigned step; /* step between entries */ + unsigned used; /* number currently used */ + unsigned long *used_bitmap; + struct efx_filter_spec *spec; +}; + +struct efx_filter_state { + spinlock_t lock; + struct efx_filter_table table[EFX_FILTER_TABLE_COUNT]; + unsigned search_depth[EFX_FILTER_TYPE_COUNT]; +}; + +/* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit + * key derived from the n-tuple. The initial LFSR state is 0xffff. */ +static u16 efx_filter_hash(u32 key) +{ + u16 tmp; + + /* First 16 rounds */ + tmp = 0x1fff ^ key >> 16; + tmp = tmp ^ tmp >> 3 ^ tmp >> 6; + tmp = tmp ^ tmp >> 9; + /* Last 16 rounds */ + tmp = tmp ^ tmp << 13 ^ key; + tmp = tmp ^ tmp >> 3 ^ tmp >> 6; + return tmp ^ tmp >> 9; +} + +/* To allow for hash collisions, filter search continues at these + * increments from the first possible entry selected by the hash. */ +static u16 efx_filter_increment(u32 key) +{ + return key * 2 - 1; +} + +static enum efx_filter_table_id +efx_filter_type_table_id(enum efx_filter_type type) +{ + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_TCP_WILD >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_RX_UDP_WILD >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_FULL >> 2)); + BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_RX_MAC_WILD >> 2)); + return type >> 2; +} + +static void +efx_filter_table_reset_search_depth(struct efx_filter_state *state, + enum efx_filter_table_id table_id) +{ + memset(state->search_depth + (table_id << 2), 0, + sizeof(state->search_depth[0]) << 2); +} + +static void efx_filter_push_rx_limits(struct efx_nic *efx) +{ + struct efx_filter_state *state = efx->filter_state; + efx_oword_t filter_ctl; + + efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); + + EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT, + state->search_depth[EFX_FILTER_RX_TCP_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT, + state->search_depth[EFX_FILTER_RX_TCP_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT, + state->search_depth[EFX_FILTER_RX_UDP_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT, + state->search_depth[EFX_FILTER_RX_UDP_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + + if (state->table[EFX_FILTER_TABLE_RX_MAC].size) { + EFX_SET_OWORD_FIELD( + filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT, + state->search_depth[EFX_FILTER_RX_MAC_FULL] + + FILTER_CTL_SRCH_FUDGE_FULL); + EFX_SET_OWORD_FIELD( + filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT, + state->search_depth[EFX_FILTER_RX_MAC_WILD] + + FILTER_CTL_SRCH_FUDGE_WILD); + } + + efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL); +} + +/* Build a filter entry and return its n-tuple key. */ +static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec) +{ + u32 data3; + + switch (efx_filter_type_table_id(spec->type)) { + case EFX_FILTER_TABLE_RX_IP: { + bool is_udp = (spec->type == EFX_FILTER_RX_UDP_FULL || + spec->type == EFX_FILTER_RX_UDP_WILD); + EFX_POPULATE_OWORD_7( + *filter, + FRF_BZ_RSS_EN, + !!(spec->flags & EFX_FILTER_FLAG_RX_RSS), + FRF_BZ_SCATTER_EN, + !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER), + FRF_BZ_TCP_UDP, is_udp, + FRF_BZ_RXQ_ID, spec->dmaq_id, + EFX_DWORD_2, spec->data[2], + EFX_DWORD_1, spec->data[1], + EFX_DWORD_0, spec->data[0]); + data3 = is_udp; + break; + } + + case EFX_FILTER_TABLE_RX_MAC: { + bool is_wild = spec->type == EFX_FILTER_RX_MAC_WILD; + EFX_POPULATE_OWORD_8( + *filter, + FRF_CZ_RMFT_RSS_EN, + !!(spec->flags & EFX_FILTER_FLAG_RX_RSS), + FRF_CZ_RMFT_SCATTER_EN, + !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER), + FRF_CZ_RMFT_IP_OVERRIDE, + !!(spec->flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP), + FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id, + FRF_CZ_RMFT_WILDCARD_MATCH, is_wild, + FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2], + FRF_CZ_RMFT_DEST_MAC_LO, spec->data[1], + FRF_CZ_RMFT_VLAN_ID, spec->data[0]); + data3 = is_wild; + break; + } + + default: + BUG(); + } + + return spec->data[0] ^ spec->data[1] ^ spec->data[2] ^ data3; +} + +static bool efx_filter_equal(const struct efx_filter_spec *left, + const struct efx_filter_spec *right) +{ + if (left->type != right->type || + memcmp(left->data, right->data, sizeof(left->data))) + return false; + + return true; +} + +static int efx_filter_search(struct efx_filter_table *table, + struct efx_filter_spec *spec, u32 key, + bool for_insert, int *depth_required) +{ + unsigned hash, incr, filter_idx, depth; + struct efx_filter_spec *cmp; + + hash = efx_filter_hash(key); + incr = efx_filter_increment(key); + + for (depth = 1, filter_idx = hash & (table->size - 1); + depth <= FILTER_CTL_SRCH_MAX && + test_bit(filter_idx, table->used_bitmap); + ++depth) { + cmp = &table->spec[filter_idx]; + if (efx_filter_equal(spec, cmp)) + goto found; + filter_idx = (filter_idx + incr) & (table->size - 1); + } + if (!for_insert) + return -ENOENT; + if (depth > FILTER_CTL_SRCH_MAX) + return -EBUSY; +found: + *depth_required = depth; + return filter_idx; +} + +/** + * efx_filter_insert_filter - add or replace a filter + * @efx: NIC in which to insert the filter + * @spec: Specification for the filter + * @replace: Flag for whether the specified filter may replace a filter + * with an identical match expression and equal or lower priority + * + * On success, return the filter index within its table. + * On failure, return a negative error code. + */ +int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec, + bool replace) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id = + efx_filter_type_table_id(spec->type); + struct efx_filter_table *table = &state->table[table_id]; + struct efx_filter_spec *saved_spec; + efx_oword_t filter; + int filter_idx, depth; + u32 key; + int rc; + + if (table->size == 0) + return -EINVAL; + + key = efx_filter_build(&filter, spec); + + netif_vdbg(efx, hw, efx->net_dev, + "%s: type %d search_depth=%d", __func__, spec->type, + state->search_depth[spec->type]); + + spin_lock_bh(&state->lock); + + rc = efx_filter_search(table, spec, key, true, &depth); + if (rc < 0) + goto out; + filter_idx = rc; + BUG_ON(filter_idx >= table->size); + saved_spec = &table->spec[filter_idx]; + + if (test_bit(filter_idx, table->used_bitmap)) { + /* Should we replace the existing filter? */ + if (!replace) { + rc = -EEXIST; + goto out; + } + if (spec->priority < saved_spec->priority) { + rc = -EPERM; + goto out; + } + } else { + __set_bit(filter_idx, table->used_bitmap); + ++table->used; + } + *saved_spec = *spec; + + if (state->search_depth[spec->type] < depth) { + state->search_depth[spec->type] = depth; + efx_filter_push_rx_limits(efx); + } + + efx_writeo(efx, &filter, table->offset + table->step * filter_idx); + + netif_vdbg(efx, hw, efx->net_dev, + "%s: filter type %d index %d rxq %u set", + __func__, spec->type, filter_idx, spec->dmaq_id); + +out: + spin_unlock_bh(&state->lock); + return rc; +} + +static void efx_filter_table_clear_entry(struct efx_nic *efx, + struct efx_filter_table *table, + int filter_idx) +{ + static efx_oword_t filter; + + if (test_bit(filter_idx, table->used_bitmap)) { + __clear_bit(filter_idx, table->used_bitmap); + --table->used; + memset(&table->spec[filter_idx], 0, sizeof(table->spec[0])); + + efx_writeo(efx, &filter, + table->offset + table->step * filter_idx); + } +} + +/** + * efx_filter_remove_filter - remove a filter by specification + * @efx: NIC from which to remove the filter + * @spec: Specification for the filter + * + * On success, return zero. + * On failure, return a negative error code. + */ +int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id = + efx_filter_type_table_id(spec->type); + struct efx_filter_table *table = &state->table[table_id]; + struct efx_filter_spec *saved_spec; + efx_oword_t filter; + int filter_idx, depth; + u32 key; + int rc; + + key = efx_filter_build(&filter, spec); + + spin_lock_bh(&state->lock); + + rc = efx_filter_search(table, spec, key, false, &depth); + if (rc < 0) + goto out; + filter_idx = rc; + saved_spec = &table->spec[filter_idx]; + + if (spec->priority < saved_spec->priority) { + rc = -EPERM; + goto out; + } + + efx_filter_table_clear_entry(efx, table, filter_idx); + if (table->used == 0) + efx_filter_table_reset_search_depth(state, table_id); + rc = 0; + +out: + spin_unlock_bh(&state->lock); + return rc; +} + +/** + * efx_filter_table_clear - remove filters from a table by priority + * @efx: NIC from which to remove the filters + * @table_id: Table from which to remove the filters + * @priority: Maximum priority to remove + */ +void efx_filter_table_clear(struct efx_nic *efx, + enum efx_filter_table_id table_id, + enum efx_filter_priority priority) +{ + struct efx_filter_state *state = efx->filter_state; + struct efx_filter_table *table = &state->table[table_id]; + int filter_idx; + + spin_lock_bh(&state->lock); + + for (filter_idx = 0; filter_idx < table->size; ++filter_idx) + if (table->spec[filter_idx].priority <= priority) + efx_filter_table_clear_entry(efx, table, filter_idx); + if (table->used == 0) + efx_filter_table_reset_search_depth(state, table_id); + + spin_unlock_bh(&state->lock); +} + +/* Restore filter stater after reset */ +void efx_restore_filters(struct efx_nic *efx) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id; + struct efx_filter_table *table; + efx_oword_t filter; + int filter_idx; + + spin_lock_bh(&state->lock); + + for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) { + table = &state->table[table_id]; + for (filter_idx = 0; filter_idx < table->size; filter_idx++) { + if (!test_bit(filter_idx, table->used_bitmap)) + continue; + efx_filter_build(&filter, &table->spec[filter_idx]); + efx_writeo(efx, &filter, + table->offset + table->step * filter_idx); + } + } + + efx_filter_push_rx_limits(efx); + + spin_unlock_bh(&state->lock); +} + +int efx_probe_filters(struct efx_nic *efx) +{ + struct efx_filter_state *state; + struct efx_filter_table *table; + unsigned table_id; + + state = kzalloc(sizeof(*efx->filter_state), GFP_KERNEL); + if (!state) + return -ENOMEM; + efx->filter_state = state; + + spin_lock_init(&state->lock); + + if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) { + table = &state->table[EFX_FILTER_TABLE_RX_IP]; + table->offset = FR_BZ_RX_FILTER_TBL0; + table->size = FR_BZ_RX_FILTER_TBL0_ROWS; + table->step = FR_BZ_RX_FILTER_TBL0_STEP; + } + + if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) { + table = &state->table[EFX_FILTER_TABLE_RX_MAC]; + table->offset = FR_CZ_RX_MAC_FILTER_TBL0; + table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS; + table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP; + } + + for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) { + table = &state->table[table_id]; + if (table->size == 0) + continue; + table->used_bitmap = kcalloc(BITS_TO_LONGS(table->size), + sizeof(unsigned long), + GFP_KERNEL); + if (!table->used_bitmap) + goto fail; + table->spec = vmalloc(table->size * sizeof(*table->spec)); + if (!table->spec) + goto fail; + memset(table->spec, 0, table->size * sizeof(*table->spec)); + } + + return 0; + +fail: + efx_remove_filters(efx); + return -ENOMEM; +} + +void efx_remove_filters(struct efx_nic *efx) +{ + struct efx_filter_state *state = efx->filter_state; + enum efx_filter_table_id table_id; + + for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) { + kfree(state->table[table_id].used_bitmap); + vfree(state->table[table_id].spec); + } + kfree(state); +} diff --git a/drivers/net/sfc/filter.h b/drivers/net/sfc/filter.h new file mode 100644 index 0000000000000000000000000000000000000000..a53319ded79cdc916291f71590b53ca474197086 --- /dev/null +++ b/drivers/net/sfc/filter.h @@ -0,0 +1,189 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2005-2010 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#ifndef EFX_FILTER_H +#define EFX_FILTER_H + +#include + +enum efx_filter_table_id { + EFX_FILTER_TABLE_RX_IP = 0, + EFX_FILTER_TABLE_RX_MAC, + EFX_FILTER_TABLE_COUNT, +}; + +/** + * enum efx_filter_type - type of hardware filter + * @EFX_FILTER_RX_TCP_FULL: RX, matching TCP/IPv4 4-tuple + * @EFX_FILTER_RX_TCP_WILD: RX, matching TCP/IPv4 destination (host, port) + * @EFX_FILTER_RX_UDP_FULL: RX, matching UDP/IPv4 4-tuple + * @EFX_FILTER_RX_UDP_WILD: RX, matching UDP/IPv4 destination (host, port) + * @EFX_FILTER_RX_MAC_FULL: RX, matching Ethernet destination MAC address, VID + * @EFX_FILTER_RX_MAC_WILD: RX, matching Ethernet destination MAC address + * + * Falcon NICs only support the RX TCP/IPv4 and UDP/IPv4 filter types. + */ +enum efx_filter_type { + EFX_FILTER_RX_TCP_FULL = 0, + EFX_FILTER_RX_TCP_WILD, + EFX_FILTER_RX_UDP_FULL, + EFX_FILTER_RX_UDP_WILD, + EFX_FILTER_RX_MAC_FULL = 4, + EFX_FILTER_RX_MAC_WILD, + EFX_FILTER_TYPE_COUNT, +}; + +/** + * enum efx_filter_priority - priority of a hardware filter specification + * @EFX_FILTER_PRI_HINT: Performance hint + * @EFX_FILTER_PRI_MANUAL: Manually configured filter + * @EFX_FILTER_PRI_REQUIRED: Required for correct behaviour + */ +enum efx_filter_priority { + EFX_FILTER_PRI_HINT = 0, + EFX_FILTER_PRI_MANUAL, + EFX_FILTER_PRI_REQUIRED, +}; + +/** + * enum efx_filter_flags - flags for hardware filter specifications + * @EFX_FILTER_FLAG_RX_RSS: Use RSS to spread across multiple queues. + * By default, matching packets will be delivered only to the + * specified queue. If this flag is set, they will be delivered + * to a range of queues offset from the specified queue number + * according to the indirection table. + * @EFX_FILTER_FLAG_RX_SCATTER: Enable DMA scatter on the receiving + * queue. + * @EFX_FILTER_FLAG_RX_OVERRIDE_IP: Enables a MAC filter to override + * any IP filter that matches the same packet. By default, IP + * filters take precedence. + * + * Currently, no flags are defined for TX filters. + */ +enum efx_filter_flags { + EFX_FILTER_FLAG_RX_RSS = 0x01, + EFX_FILTER_FLAG_RX_SCATTER = 0x02, + EFX_FILTER_FLAG_RX_OVERRIDE_IP = 0x04, +}; + +/** + * struct efx_filter_spec - specification for a hardware filter + * @type: Type of match to be performed, from &enum efx_filter_type + * @priority: Priority of the filter, from &enum efx_filter_priority + * @flags: Miscellaneous flags, from &enum efx_filter_flags + * @dmaq_id: Source/target queue index + * @data: Match data (type-dependent) + * + * Use the efx_filter_set_*() functions to initialise the @type and + * @data fields. + */ +struct efx_filter_spec { + u8 type:4; + u8 priority:4; + u8 flags; + u16 dmaq_id; + u32 data[3]; +}; + +/** + * efx_filter_set_rx_tcp_full - specify RX filter with TCP/IPv4 full match + * @spec: Specification to initialise + * @shost: Source host address (host byte order) + * @sport: Source port (host byte order) + * @dhost: Destination host address (host byte order) + * @dport: Destination port (host byte order) + */ +static inline void +efx_filter_set_rx_tcp_full(struct efx_filter_spec *spec, + u32 shost, u16 sport, u32 dhost, u16 dport) +{ + spec->type = EFX_FILTER_RX_TCP_FULL; + spec->data[0] = sport | shost << 16; + spec->data[1] = dport << 16 | shost >> 16; + spec->data[2] = dhost; +} + +/** + * efx_filter_set_rx_tcp_wild - specify RX filter with TCP/IPv4 wildcard match + * @spec: Specification to initialise + * @dhost: Destination host address (host byte order) + * @dport: Destination port (host byte order) + */ +static inline void +efx_filter_set_rx_tcp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport) +{ + spec->type = EFX_FILTER_RX_TCP_WILD; + spec->data[0] = 0; + spec->data[1] = dport << 16; + spec->data[2] = dhost; +} + +/** + * efx_filter_set_rx_udp_full - specify RX filter with UDP/IPv4 full match + * @spec: Specification to initialise + * @shost: Source host address (host byte order) + * @sport: Source port (host byte order) + * @dhost: Destination host address (host byte order) + * @dport: Destination port (host byte order) + */ +static inline void +efx_filter_set_rx_udp_full(struct efx_filter_spec *spec, + u32 shost, u16 sport, u32 dhost, u16 dport) +{ + spec->type = EFX_FILTER_RX_UDP_FULL; + spec->data[0] = sport | shost << 16; + spec->data[1] = dport << 16 | shost >> 16; + spec->data[2] = dhost; +} + +/** + * efx_filter_set_rx_udp_wild - specify RX filter with UDP/IPv4 wildcard match + * @spec: Specification to initialise + * @dhost: Destination host address (host byte order) + * @dport: Destination port (host byte order) + */ +static inline void +efx_filter_set_rx_udp_wild(struct efx_filter_spec *spec, u32 dhost, u16 dport) +{ + spec->type = EFX_FILTER_RX_UDP_WILD; + spec->data[0] = dport; + spec->data[1] = 0; + spec->data[2] = dhost; +} + +/** + * efx_filter_set_rx_mac_full - specify RX filter with MAC full match + * @spec: Specification to initialise + * @vid: VLAN ID + * @addr: Destination MAC address + */ +static inline void efx_filter_set_rx_mac_full(struct efx_filter_spec *spec, + u16 vid, const u8 *addr) +{ + spec->type = EFX_FILTER_RX_MAC_FULL; + spec->data[0] = vid; + spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5]; + spec->data[2] = addr[0] << 8 | addr[1]; +} + +/** + * efx_filter_set_rx_mac_full - specify RX filter with MAC wildcard match + * @spec: Specification to initialise + * @addr: Destination MAC address + */ +static inline void efx_filter_set_rx_mac_wild(struct efx_filter_spec *spec, + const u8 *addr) +{ + spec->type = EFX_FILTER_RX_MAC_WILD; + spec->data[0] = 0; + spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5]; + spec->data[2] = addr[0] << 8 | addr[1]; +} + +#endif /* EFX_FILTER_H */ diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h index f1aa5f37489036adb028b6d306a04e5a7d15203c..6886cdf87c127c911aa63024a86826adc4da94b1 100644 --- a/drivers/net/sfc/mac.h +++ b/drivers/net/sfc/mac.h @@ -13,10 +13,8 @@ #include "net_driver.h" -extern struct efx_mac_operations falcon_gmac_operations; extern struct efx_mac_operations falcon_xmac_operations; extern struct efx_mac_operations efx_mcdi_mac_operations; -extern void falcon_reconfigure_xmac_core(struct efx_nic *efx); extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, u32 dma_len, int enable, int clear); diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 3912b8fed912d5f2bb488acc4bdccf439b0c5fe7..12cf910c2ce712f72dc5b960695700395b516d59 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -1093,8 +1093,8 @@ int efx_mcdi_reset_mc(struct efx_nic *efx) return rc; } -int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, - const u8 *mac, int *id_out) +static int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, + const u8 *mac, int *id_out) { u8 inbuf[MC_CMD_WOL_FILTER_SET_IN_LEN]; u8 outbuf[MC_CMD_WOL_FILTER_SET_OUT_LEN]; diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h index f1f89ad4075ac2750623a840dc66812217fa0ad9..c792f1d65e4880d84e85a136289e945e1ca863f1 100644 --- a/drivers/net/sfc/mcdi.h +++ b/drivers/net/sfc/mcdi.h @@ -121,8 +121,6 @@ extern int efx_mcdi_handle_assertion(struct efx_nic *efx); extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); extern int efx_mcdi_reset_port(struct efx_nic *efx); extern int efx_mcdi_reset_mc(struct efx_nic *efx); -extern int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, - const u8 *mac, int *id_out); extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, const u8 *mac, int *id_out); extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 0121e71702bf9a5183ece1870c544f409d44b05f..c992742446b167d2a660665bda43eced3445fcab 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -713,7 +713,8 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, return 0; } -const char *efx_mcdi_phy_test_name(struct efx_nic *efx, unsigned int index) +static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, + unsigned int index) { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; diff --git a/drivers/net/sfc/mdio_10g.c b/drivers/net/sfc/mdio_10g.c index eeaf0bd64bd3c2873c74bb0e4664a44f478c4e8d..98d946020429a781a3c86c0b21a1b3b59d5c28d1 100644 --- a/drivers/net/sfc/mdio_10g.c +++ b/drivers/net/sfc/mdio_10g.c @@ -286,46 +286,24 @@ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) */ void efx_mdio_an_reconfigure(struct efx_nic *efx) { - bool xnp = (efx->link_advertising & ADVERTISED_10000baseT_Full - || EFX_WORKAROUND_13204(efx)); int reg; WARN_ON(!(efx->mdio.mmds & MDIO_DEVS_AN)); /* Set up the base page */ - reg = ADVERTISE_CSMA; - if (efx->link_advertising & ADVERTISED_10baseT_Half) - reg |= ADVERTISE_10HALF; - if (efx->link_advertising & ADVERTISED_10baseT_Full) - reg |= ADVERTISE_10FULL; - if (efx->link_advertising & ADVERTISED_100baseT_Half) - reg |= ADVERTISE_100HALF; - if (efx->link_advertising & ADVERTISED_100baseT_Full) - reg |= ADVERTISE_100FULL; - if (xnp) - reg |= ADVERTISE_RESV; - else if (efx->link_advertising & (ADVERTISED_1000baseT_Half | - ADVERTISED_1000baseT_Full)) - reg |= ADVERTISE_NPAGE; + reg = ADVERTISE_CSMA | ADVERTISE_RESV; if (efx->link_advertising & ADVERTISED_Pause) reg |= ADVERTISE_PAUSE_CAP; if (efx->link_advertising & ADVERTISED_Asym_Pause) reg |= ADVERTISE_PAUSE_ASYM; efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); - /* Set up the (extended) next page if necessary */ - if (efx->phy_op->set_npage_adv) - efx->phy_op->set_npage_adv(efx, efx->link_advertising); + /* Set up the (extended) next page */ + efx->phy_op->set_npage_adv(efx, efx->link_advertising); /* Enable and restart AN */ reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1); - reg |= MDIO_AN_CTRL1_ENABLE; - if (!(EFX_WORKAROUND_15195(efx) && LOOPBACK_EXTERNAL(efx))) - reg |= MDIO_AN_CTRL1_RESTART; - if (xnp) - reg |= MDIO_AN_CTRL1_XNP; - else - reg &= ~MDIO_AN_CTRL1_XNP; + reg |= MDIO_AN_CTRL1_ENABLE | MDIO_AN_CTRL1_RESTART | MDIO_AN_CTRL1_XNP; efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg); } diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 64e7caa4bbb5444798ef133df0ad54ef2c411863..0a7e26d73b525b13aba1fc9e234d38a699322f2a 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "enum.h" @@ -137,6 +138,7 @@ struct efx_tx_buffer { * @channel: The associated channel * @buffer: The software buffer ring * @txd: The hardware descriptor ring + * @ptr_mask: The size of the ring minus 1. * @flushed: Used when handling queue flushing * @read_count: Current read pointer. * This is the number of buffers that have been removed from both rings. @@ -170,6 +172,7 @@ struct efx_tx_queue { struct efx_nic *nic; struct efx_tx_buffer *buffer; struct efx_special_buffer txd; + unsigned int ptr_mask; enum efx_flush_state flushed; /* Members used mainly on the completion path */ @@ -225,10 +228,9 @@ struct efx_rx_page_state { /** * struct efx_rx_queue - An Efx RX queue * @efx: The associated Efx NIC - * @queue: DMA queue number - * @channel: The associated channel * @buffer: The software buffer ring * @rxd: The hardware descriptor ring + * @ptr_mask: The size of the ring minus 1. * @added_count: Number of buffers added to the receive queue. * @notified_count: Number of buffers given to NIC (<= @added_count). * @removed_count: Number of buffers removed from the receive queue. @@ -240,9 +242,6 @@ struct efx_rx_page_state { * @min_fill: RX descriptor minimum non-zero fill level. * This records the minimum fill level observed when a ring * refill was triggered. - * @min_overfill: RX descriptor minimum overflow fill level. - * This records the minimum fill level at which RX queue - * overflow was observed. It should never be set. * @alloc_page_count: RX allocation strategy counter. * @alloc_skb_count: RX allocation strategy counter. * @slow_fill: Timer used to defer efx_nic_generate_fill_event(). @@ -250,10 +249,9 @@ struct efx_rx_page_state { */ struct efx_rx_queue { struct efx_nic *efx; - int queue; - struct efx_channel *channel; struct efx_rx_buffer *buffer; struct efx_special_buffer rxd; + unsigned int ptr_mask; int added_count; int notified_count; @@ -302,7 +300,6 @@ enum efx_rx_alloc_method { * * @efx: Associated Efx NIC * @channel: Channel instance number - * @name: Name for channel and IRQ * @enabled: Channel enabled indicator * @irq: IRQ number (MSI and MSI-X only) * @irq_moderation: IRQ moderation value (in hardware ticks) @@ -311,6 +308,7 @@ enum efx_rx_alloc_method { * @reset_work: Scheduled reset work thread * @work_pending: Is work pending via NAPI? * @eventq: Event queue buffer + * @eventq_mask: Event queue pointer mask * @eventq_read_ptr: Event queue read pointer * @last_eventq_read_ptr: Last event queue read pointer value. * @magic_count: Event queue test event count @@ -327,14 +325,14 @@ enum efx_rx_alloc_method { * @n_rx_frm_trunc: Count of RX_FRM_TRUNC errors * @n_rx_overlength: Count of RX_OVERLENGTH errors * @n_skbuff_leaks: Count of skbuffs leaked due to RX overrun - * @tx_queue: Pointer to first TX queue, or %NULL if not used for TX + * @rx_queue: RX queue for this channel * @tx_stop_count: Core TX queue stop count * @tx_stop_lock: Core TX queue stop lock + * @tx_queue: TX queues for this channel */ struct efx_channel { struct efx_nic *efx; int channel; - char name[IFNAMSIZ + 6]; bool enabled; int irq; unsigned int irq_moderation; @@ -342,6 +340,7 @@ struct efx_channel { struct napi_struct napi_str; bool work_pending; struct efx_special_buffer eventq; + unsigned int eventq_mask; unsigned int eventq_read_ptr; unsigned int last_eventq_read_ptr; unsigned int magic_count; @@ -366,9 +365,12 @@ struct efx_channel { struct efx_rx_buffer *rx_pkt; bool rx_pkt_csummed; - struct efx_tx_queue *tx_queue; + struct efx_rx_queue rx_queue; + atomic_t tx_stop_count; spinlock_t tx_stop_lock; + + struct efx_tx_queue tx_queue[2]; }; enum efx_led_mode { @@ -385,11 +387,6 @@ extern const unsigned int efx_loopback_mode_max; #define LOOPBACK_MODE(efx) \ STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode) -extern const char *efx_interrupt_mode_names[]; -extern const unsigned int efx_interrupt_mode_max; -#define INT_MODE(efx) \ - STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode) - extern const char *efx_reset_type_names[]; extern const unsigned int efx_reset_type_max; #define RESET_TYPE(type) \ @@ -404,8 +401,6 @@ enum efx_int_mode { }; #define EFX_INT_MODE_USE_MSI(x) (((x)->interrupt_mode) <= EFX_INT_MODE_MSI) -#define EFX_IS10G(efx) ((efx)->link_state.speed == 10000) - enum nic_state { STATE_INIT = 0, STATE_RUNNING = 1, @@ -618,6 +613,8 @@ union efx_multicast_hash { efx_oword_t oword[EFX_MCAST_HASH_ENTRIES / sizeof(efx_oword_t) / 8]; }; +struct efx_filter_state; + /** * struct efx_nic - an Efx NIC * @name: Device name (net device name or bus id before net device registered) @@ -641,6 +638,9 @@ union efx_multicast_hash { * @tx_queue: TX DMA queues * @rx_queue: RX DMA queues * @channel: Channels + * @channel_name: Names for channels and their IRQs + * @rxq_entries: Size of receive queues requested by user. + * @txq_entries: Size of transmit queues requested by user. * @next_buffer_table: First available buffer table id * @n_channels: Number of channels in use * @n_rx_channels: Number of channels used for RX (= number of RX queues) @@ -724,10 +724,11 @@ struct efx_nic { enum nic_state state; enum reset_type reset_pending; - struct efx_tx_queue tx_queue[EFX_MAX_TX_QUEUES]; - struct efx_rx_queue rx_queue[EFX_MAX_RX_QUEUES]; - struct efx_channel channel[EFX_MAX_CHANNELS]; + struct efx_channel *channel[EFX_MAX_CHANNELS]; + char channel_name[EFX_MAX_CHANNELS][IFNAMSIZ + 6]; + unsigned rxq_entries; + unsigned txq_entries; unsigned next_buffer_table; unsigned n_channels; unsigned n_rx_channels; @@ -794,6 +795,8 @@ struct efx_nic { u64 loopback_modes; void *loopback_selftest; + + struct efx_filter_state *filter_state; }; static inline int efx_dev_registered(struct efx_nic *efx) @@ -909,39 +912,67 @@ struct efx_nic_type { * *************************************************************************/ +static inline struct efx_channel * +efx_get_channel(struct efx_nic *efx, unsigned index) +{ + EFX_BUG_ON_PARANOID(index >= efx->n_channels); + return efx->channel[index]; +} + /* Iterate over all used channels */ #define efx_for_each_channel(_channel, _efx) \ - for (_channel = &((_efx)->channel[0]); \ - _channel < &((_efx)->channel[(efx)->n_channels]); \ - _channel++) - -/* Iterate over all used TX queues */ -#define efx_for_each_tx_queue(_tx_queue, _efx) \ - for (_tx_queue = &((_efx)->tx_queue[0]); \ - _tx_queue < &((_efx)->tx_queue[EFX_TXQ_TYPES * \ - (_efx)->n_tx_channels]); \ - _tx_queue++) + for (_channel = (_efx)->channel[0]; \ + _channel; \ + _channel = (_channel->channel + 1 < (_efx)->n_channels) ? \ + (_efx)->channel[_channel->channel + 1] : NULL) + +extern struct efx_tx_queue * +efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type); + +static inline struct efx_tx_queue * +efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type) +{ + struct efx_tx_queue *tx_queue = channel->tx_queue; + EFX_BUG_ON_PARANOID(type >= EFX_TXQ_TYPES); + return tx_queue->channel ? tx_queue + type : NULL; +} /* Iterate over all TX queues belonging to a channel */ #define efx_for_each_channel_tx_queue(_tx_queue, _channel) \ - for (_tx_queue = (_channel)->tx_queue; \ + for (_tx_queue = efx_channel_get_tx_queue(channel, 0); \ _tx_queue && _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES; \ _tx_queue++) -/* Iterate over all used RX queues */ -#define efx_for_each_rx_queue(_rx_queue, _efx) \ - for (_rx_queue = &((_efx)->rx_queue[0]); \ - _rx_queue < &((_efx)->rx_queue[(_efx)->n_rx_channels]); \ - _rx_queue++) +static inline struct efx_rx_queue * +efx_get_rx_queue(struct efx_nic *efx, unsigned index) +{ + EFX_BUG_ON_PARANOID(index >= efx->n_rx_channels); + return &efx->channel[index]->rx_queue; +} + +static inline struct efx_rx_queue * +efx_channel_get_rx_queue(struct efx_channel *channel) +{ + return channel->channel < channel->efx->n_rx_channels ? + &channel->rx_queue : NULL; +} /* Iterate over all RX queues belonging to a channel */ #define efx_for_each_channel_rx_queue(_rx_queue, _channel) \ - for (_rx_queue = &((_channel)->efx->rx_queue[(_channel)->channel]); \ + for (_rx_queue = efx_channel_get_rx_queue(channel); \ _rx_queue; \ - _rx_queue = NULL) \ - if (_rx_queue->channel != (_channel)) \ - continue; \ - else + _rx_queue = NULL) + +static inline struct efx_channel * +efx_rx_queue_channel(struct efx_rx_queue *rx_queue) +{ + return container_of(rx_queue, struct efx_channel, rx_queue); +} + +static inline int efx_rx_queue_index(struct efx_rx_queue *rx_queue) +{ + return efx_rx_queue_channel(rx_queue)->channel; +} /* Returns a pointer to the specified receive buffer in the RX * descriptor queue. @@ -949,7 +980,7 @@ struct efx_nic_type { static inline struct efx_rx_buffer *efx_rx_buffer(struct efx_rx_queue *rx_queue, unsigned int index) { - return (&rx_queue->buffer[index]); + return &rx_queue->buffer[index]; } /* Set bit in a little-endian bitfield */ diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index f595d920c7c46b323f0a778e58c0984a19839be6..41c36b9a4244b907907936b0a6abeaf8f2a301d1 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -104,7 +104,7 @@ static inline void efx_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value, static inline efx_qword_t *efx_event(struct efx_channel *channel, unsigned int index) { - return (((efx_qword_t *) (channel->eventq.addr)) + index); + return ((efx_qword_t *) (channel->eventq.addr)) + index; } /* See if an event is present @@ -119,8 +119,8 @@ static inline efx_qword_t *efx_event(struct efx_channel *channel, */ static inline int efx_event_present(efx_qword_t *event) { - return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) | - EFX_DWORD_IS_ALL_ONES(event->dword[1]))); + return !(EFX_DWORD_IS_ALL_ONES(event->dword[0]) | + EFX_DWORD_IS_ALL_ONES(event->dword[1])); } static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b, @@ -263,8 +263,8 @@ static int efx_alloc_special_buffer(struct efx_nic *efx, { len = ALIGN(len, EFX_BUF_SIZE); - buffer->addr = pci_alloc_consistent(efx->pci_dev, len, - &buffer->dma_addr); + buffer->addr = dma_alloc_coherent(&efx->pci_dev->dev, len, + &buffer->dma_addr, GFP_KERNEL); if (!buffer->addr) return -ENOMEM; buffer->len = len; @@ -301,8 +301,8 @@ efx_free_special_buffer(struct efx_nic *efx, struct efx_special_buffer *buffer) (u64)buffer->dma_addr, buffer->len, buffer->addr, (u64)virt_to_phys(buffer->addr)); - pci_free_consistent(efx->pci_dev, buffer->len, buffer->addr, - buffer->dma_addr); + dma_free_coherent(&efx->pci_dev->dev, buffer->len, buffer->addr, + buffer->dma_addr); buffer->addr = NULL; buffer->entries = 0; } @@ -347,7 +347,7 @@ void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer) static inline efx_qword_t * efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index) { - return (((efx_qword_t *) (tx_queue->txd.addr)) + index); + return ((efx_qword_t *) (tx_queue->txd.addr)) + index; } /* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */ @@ -356,7 +356,7 @@ static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue) unsigned write_ptr; efx_dword_t reg; - write_ptr = tx_queue->write_count & EFX_TXQ_MASK; + write_ptr = tx_queue->write_count & tx_queue->ptr_mask; EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr); efx_writed_page(tx_queue->efx, ®, FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue); @@ -377,7 +377,7 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) BUG_ON(tx_queue->write_count == tx_queue->insert_count); do { - write_ptr = tx_queue->write_count & EFX_TXQ_MASK; + write_ptr = tx_queue->write_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[write_ptr]; txd = efx_tx_desc(tx_queue, write_ptr); ++tx_queue->write_count; @@ -398,10 +398,11 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue) int efx_nic_probe_tx(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; - BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 || - EFX_TXQ_SIZE & EFX_TXQ_MASK); + unsigned entries; + + entries = tx_queue->ptr_mask + 1; return efx_alloc_special_buffer(efx, &tx_queue->txd, - EFX_TXQ_SIZE * sizeof(efx_qword_t)); + entries * sizeof(efx_qword_t)); } void efx_nic_init_tx(struct efx_tx_queue *tx_queue) @@ -501,7 +502,7 @@ void efx_nic_remove_tx(struct efx_tx_queue *tx_queue) static inline efx_qword_t * efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index) { - return (((efx_qword_t *) (rx_queue->rxd.addr)) + index); + return ((efx_qword_t *) (rx_queue->rxd.addr)) + index; } /* This creates an entry in the RX descriptor queue */ @@ -526,30 +527,32 @@ efx_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned index) */ void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue) { + struct efx_nic *efx = rx_queue->efx; efx_dword_t reg; unsigned write_ptr; while (rx_queue->notified_count != rx_queue->added_count) { - efx_build_rx_desc(rx_queue, - rx_queue->notified_count & - EFX_RXQ_MASK); + efx_build_rx_desc( + rx_queue, + rx_queue->notified_count & rx_queue->ptr_mask); ++rx_queue->notified_count; } wmb(); - write_ptr = rx_queue->added_count & EFX_RXQ_MASK; + write_ptr = rx_queue->added_count & rx_queue->ptr_mask; EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr); - efx_writed_page(rx_queue->efx, ®, - FR_AZ_RX_DESC_UPD_DWORD_P0, rx_queue->queue); + efx_writed_page(efx, ®, FR_AZ_RX_DESC_UPD_DWORD_P0, + efx_rx_queue_index(rx_queue)); } int efx_nic_probe_rx(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; - BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 || - EFX_RXQ_SIZE & EFX_RXQ_MASK); + unsigned entries; + + entries = rx_queue->ptr_mask + 1; return efx_alloc_special_buffer(efx, &rx_queue->rxd, - EFX_RXQ_SIZE * sizeof(efx_qword_t)); + entries * sizeof(efx_qword_t)); } void efx_nic_init_rx(struct efx_rx_queue *rx_queue) @@ -561,7 +564,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue) netif_dbg(efx, hw, efx->net_dev, "RX queue %d ring in special buffers %d-%d\n", - rx_queue->queue, rx_queue->rxd.index, + efx_rx_queue_index(rx_queue), rx_queue->rxd.index, rx_queue->rxd.index + rx_queue->rxd.entries - 1); rx_queue->flushed = FLUSH_NONE; @@ -575,9 +578,10 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue) FRF_AZ_RX_ISCSI_HDIG_EN, iscsi_digest_en, FRF_AZ_RX_DESCQ_BUF_BASE_ID, rx_queue->rxd.index, FRF_AZ_RX_DESCQ_EVQ_ID, - rx_queue->channel->channel, + efx_rx_queue_channel(rx_queue)->channel, FRF_AZ_RX_DESCQ_OWNER_ID, 0, - FRF_AZ_RX_DESCQ_LABEL, rx_queue->queue, + FRF_AZ_RX_DESCQ_LABEL, + efx_rx_queue_index(rx_queue), FRF_AZ_RX_DESCQ_SIZE, __ffs(rx_queue->rxd.entries), FRF_AZ_RX_DESCQ_TYPE, 0 /* kernel queue */ , @@ -585,7 +589,7 @@ void efx_nic_init_rx(struct efx_rx_queue *rx_queue) FRF_AZ_RX_DESCQ_JUMBO, !is_b0, FRF_AZ_RX_DESCQ_EN, 1); efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); + efx_rx_queue_index(rx_queue)); } static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue) @@ -598,7 +602,8 @@ static void efx_flush_rx_queue(struct efx_rx_queue *rx_queue) /* Post a flush command */ EFX_POPULATE_OWORD_2(rx_flush_descq, FRF_AZ_RX_FLUSH_DESCQ_CMD, 1, - FRF_AZ_RX_FLUSH_DESCQ, rx_queue->queue); + FRF_AZ_RX_FLUSH_DESCQ, + efx_rx_queue_index(rx_queue)); efx_writeo(efx, &rx_flush_descq, FR_AZ_RX_FLUSH_DESCQ); } @@ -613,7 +618,7 @@ void efx_nic_fini_rx(struct efx_rx_queue *rx_queue) /* Remove RX descriptor ring from card */ EFX_ZERO_OWORD(rx_desc_ptr); efx_writeo_table(efx, &rx_desc_ptr, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); + efx_rx_queue_index(rx_queue)); /* Unpin RX descriptor ring */ efx_fini_special_buffer(efx, &rx_queue->rxd); @@ -648,7 +653,7 @@ void efx_nic_eventq_read_ack(struct efx_channel *channel) } /* Use HW to insert a SW defined event */ -void efx_generate_event(struct efx_channel *channel, efx_qword_t *event) +static void efx_generate_event(struct efx_channel *channel, efx_qword_t *event) { efx_oword_t drv_ev_reg; @@ -680,15 +685,17 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) /* Transmit completion */ tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR); tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); - tx_queue = &efx->tx_queue[tx_ev_q_label]; + tx_queue = efx_channel_get_tx_queue( + channel, tx_ev_q_label % EFX_TXQ_TYPES); tx_packets = ((tx_ev_desc_ptr - tx_queue->read_count) & - EFX_TXQ_MASK); + tx_queue->ptr_mask); channel->irq_mod_score += tx_packets; efx_xmit_done(tx_queue, tx_ev_desc_ptr); } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) { /* Rewrite the FIFO write pointer */ tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL); - tx_queue = &efx->tx_queue[tx_ev_q_label]; + tx_queue = efx_channel_get_tx_queue( + channel, tx_ev_q_label % EFX_TXQ_TYPES); if (efx_dev_registered(efx)) netif_tx_lock(efx->net_dev); @@ -714,6 +721,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, bool *rx_ev_pkt_ok, bool *discard) { + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_nic *efx = rx_queue->efx; bool rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; bool rx_ev_tcp_udp_chksum_err, rx_ev_eth_crc_err; @@ -746,14 +754,14 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, /* Count errors that are not in MAC stats. Ignore expected * checksum errors during self-test. */ if (rx_ev_frm_trunc) - ++rx_queue->channel->n_rx_frm_trunc; + ++channel->n_rx_frm_trunc; else if (rx_ev_tobe_disc) - ++rx_queue->channel->n_rx_tobe_disc; + ++channel->n_rx_tobe_disc; else if (!efx->loopback_selftest) { if (rx_ev_ip_hdr_chksum_err) - ++rx_queue->channel->n_rx_ip_hdr_chksum_err; + ++channel->n_rx_ip_hdr_chksum_err; else if (rx_ev_tcp_udp_chksum_err) - ++rx_queue->channel->n_rx_tcp_udp_chksum_err; + ++channel->n_rx_tcp_udp_chksum_err; } /* The frame must be discarded if any of these are true. */ @@ -769,7 +777,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, netif_dbg(efx, rx_err, efx->net_dev, " RX queue %d unexpected RX event " EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n", - rx_queue->queue, EFX_QWORD_VAL(*event), + efx_rx_queue_index(rx_queue), EFX_QWORD_VAL(*event), rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "", rx_ev_ip_hdr_chksum_err ? " [IP_HDR_CHKSUM_ERR]" : "", @@ -791,8 +799,8 @@ efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index) struct efx_nic *efx = rx_queue->efx; unsigned expected, dropped; - expected = rx_queue->removed_count & EFX_RXQ_MASK; - dropped = (index - expected) & EFX_RXQ_MASK; + expected = rx_queue->removed_count & rx_queue->ptr_mask; + dropped = (index - expected) & rx_queue->ptr_mask; netif_info(efx, rx_err, efx->net_dev, "dropped %d events (index=%d expected=%d)\n", dropped, index, expected); @@ -827,10 +835,10 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) != channel->channel); - rx_queue = &efx->rx_queue[channel->channel]; + rx_queue = efx_channel_get_rx_queue(channel); rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR); - expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK; + expected_ptr = rx_queue->removed_count & rx_queue->ptr_mask; if (unlikely(rx_ev_desc_ptr != expected_ptr)) efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr); @@ -879,7 +887,7 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event) /* The queue must be empty, so we won't receive any rx * events, so efx_process_channel() won't refill the * queue. Refill it here */ - efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]); + efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel)); else netif_dbg(efx, hw, efx->net_dev, "channel %d received " "generated event "EFX_QWORD_FMT"\n", @@ -997,6 +1005,7 @@ efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event) int efx_nic_process_eventq(struct efx_channel *channel, int budget) { + struct efx_nic *efx = channel->efx; unsigned int read_ptr; efx_qword_t event, *p_event; int ev_code; @@ -1021,7 +1030,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget) EFX_SET_QWORD(*p_event); /* Increment read pointer */ - read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; + read_ptr = (read_ptr + 1) & channel->eventq_mask; ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE); @@ -1033,7 +1042,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget) break; case FSE_AZ_EV_CODE_TX_EV: tx_packets += efx_handle_tx_event(channel, &event); - if (tx_packets >= EFX_TXQ_SIZE) { + if (tx_packets > efx->txq_entries) { spent = budget; goto out; } @@ -1068,10 +1077,11 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget) int efx_nic_probe_eventq(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; - BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 || - EFX_EVQ_SIZE & EFX_EVQ_MASK); + unsigned entries; + + entries = channel->eventq_mask + 1; return efx_alloc_special_buffer(efx, &channel->eventq, - EFX_EVQ_SIZE * sizeof(efx_qword_t)); + entries * sizeof(efx_qword_t)); } void efx_nic_init_eventq(struct efx_channel *channel) @@ -1163,11 +1173,11 @@ void efx_nic_generate_fill_event(struct efx_channel *channel) static void efx_poll_flush_events(struct efx_nic *efx) { - struct efx_channel *channel = &efx->channel[0]; + struct efx_channel *channel = efx_get_channel(efx, 0); struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; unsigned int read_ptr = channel->eventq_read_ptr; - unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK; + unsigned int end_ptr = (read_ptr - 1) & channel->eventq_mask; do { efx_qword_t *event = efx_event(channel, read_ptr); @@ -1185,7 +1195,9 @@ static void efx_poll_flush_events(struct efx_nic *efx) ev_queue = EFX_QWORD_FIELD(*event, FSF_AZ_DRIVER_EV_SUBDATA); if (ev_queue < EFX_TXQ_TYPES * efx->n_tx_channels) { - tx_queue = efx->tx_queue + ev_queue; + tx_queue = efx_get_tx_queue( + efx, ev_queue / EFX_TXQ_TYPES, + ev_queue % EFX_TXQ_TYPES); tx_queue->flushed = FLUSH_DONE; } } else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV && @@ -1195,7 +1207,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) ev_failed = EFX_QWORD_FIELD( *event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL); if (ev_queue < efx->n_rx_channels) { - rx_queue = efx->rx_queue + ev_queue; + rx_queue = efx_get_rx_queue(efx, ev_queue); rx_queue->flushed = ev_failed ? FLUSH_FAILED : FLUSH_DONE; } @@ -1205,7 +1217,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) * it's ok to throw away every non-flush event */ EFX_SET_QWORD(*event); - read_ptr = (read_ptr + 1) & EFX_EVQ_MASK; + read_ptr = (read_ptr + 1) & channel->eventq_mask; } while (read_ptr != end_ptr); channel->eventq_read_ptr = read_ptr; @@ -1216,6 +1228,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) * serialise them */ int efx_nic_flush_queues(struct efx_nic *efx) { + struct efx_channel *channel; struct efx_rx_queue *rx_queue; struct efx_tx_queue *tx_queue; int i, tx_pending, rx_pending; @@ -1224,29 +1237,35 @@ int efx_nic_flush_queues(struct efx_nic *efx) efx->type->prepare_flush(efx); /* Flush all tx queues in parallel */ - efx_for_each_tx_queue(tx_queue, efx) - efx_flush_tx_queue(tx_queue); + efx_for_each_channel(channel, efx) { + efx_for_each_channel_tx_queue(tx_queue, channel) + efx_flush_tx_queue(tx_queue); + } /* The hardware supports four concurrent rx flushes, each of which may * need to be retried if there is an outstanding descriptor fetch */ for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) { rx_pending = tx_pending = 0; - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_queue->flushed == FLUSH_PENDING) - ++rx_pending; - } - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_pending == EFX_RX_FLUSH_COUNT) - break; - if (rx_queue->flushed == FLUSH_FAILED || - rx_queue->flushed == FLUSH_NONE) { - efx_flush_rx_queue(rx_queue); - ++rx_pending; + efx_for_each_channel(channel, efx) { + efx_for_each_channel_rx_queue(rx_queue, channel) { + if (rx_queue->flushed == FLUSH_PENDING) + ++rx_pending; } } - efx_for_each_tx_queue(tx_queue, efx) { - if (tx_queue->flushed != FLUSH_DONE) - ++tx_pending; + efx_for_each_channel(channel, efx) { + efx_for_each_channel_rx_queue(rx_queue, channel) { + if (rx_pending == EFX_RX_FLUSH_COUNT) + break; + if (rx_queue->flushed == FLUSH_FAILED || + rx_queue->flushed == FLUSH_NONE) { + efx_flush_rx_queue(rx_queue); + ++rx_pending; + } + } + efx_for_each_channel_tx_queue(tx_queue, channel) { + if (tx_queue->flushed != FLUSH_DONE) + ++tx_pending; + } } if (rx_pending == 0 && tx_pending == 0) @@ -1258,19 +1277,21 @@ int efx_nic_flush_queues(struct efx_nic *efx) /* Mark the queues as all flushed. We're going to return failure * leading to a reset, or fake up success anyway */ - efx_for_each_tx_queue(tx_queue, efx) { - if (tx_queue->flushed != FLUSH_DONE) - netif_err(efx, hw, efx->net_dev, - "tx queue %d flush command timed out\n", - tx_queue->queue); - tx_queue->flushed = FLUSH_DONE; - } - efx_for_each_rx_queue(rx_queue, efx) { - if (rx_queue->flushed != FLUSH_DONE) - netif_err(efx, hw, efx->net_dev, - "rx queue %d flush command timed out\n", - rx_queue->queue); - rx_queue->flushed = FLUSH_DONE; + efx_for_each_channel(channel, efx) { + efx_for_each_channel_tx_queue(tx_queue, channel) { + if (tx_queue->flushed != FLUSH_DONE) + netif_err(efx, hw, efx->net_dev, + "tx queue %d flush command timed out\n", + tx_queue->queue); + tx_queue->flushed = FLUSH_DONE; + } + efx_for_each_channel_rx_queue(rx_queue, channel) { + if (rx_queue->flushed != FLUSH_DONE) + netif_err(efx, hw, efx->net_dev, + "rx queue %d flush command timed out\n", + efx_rx_queue_index(rx_queue)); + rx_queue->flushed = FLUSH_DONE; + } } return -ETIMEDOUT; @@ -1457,7 +1478,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) */ static irqreturn_t efx_msi_interrupt(int irq, void *dev_id) { - struct efx_channel *channel = dev_id; + struct efx_channel *channel = *(struct efx_channel **)dev_id; struct efx_nic *efx = channel->efx; efx_oword_t *int_ker = efx->irq_status.addr; int syserr; @@ -1532,7 +1553,8 @@ int efx_nic_init_interrupt(struct efx_nic *efx) efx_for_each_channel(channel, efx) { rc = request_irq(channel->irq, efx_msi_interrupt, IRQF_PROBE_SHARED, /* Not shared */ - channel->name, channel); + efx->channel_name[channel->channel], + &efx->channel[channel->channel]); if (rc) { netif_err(efx, drv, efx->net_dev, "failed to hook IRQ %d\n", channel->irq); @@ -1544,7 +1566,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx) fail2: efx_for_each_channel(channel, efx) - free_irq(channel->irq, channel); + free_irq(channel->irq, &efx->channel[channel->channel]); fail1: return rc; } @@ -1557,7 +1579,7 @@ void efx_nic_fini_interrupt(struct efx_nic *efx) /* Disable MSI/MSI-X interrupts */ efx_for_each_channel(channel, efx) { if (channel->irq) - free_irq(channel->irq, channel); + free_irq(channel->irq, &efx->channel[channel->channel]); } /* ACK legacy interrupt */ @@ -1827,8 +1849,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = { REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL), REGISTER_TABLE_AA(EVQ_PTR_TBL_KER), REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL), - /* The register buffer is allocated with slab, so we can't - * reasonably read all of the buffer table (up to 8MB!). + /* We can't reasonably read all of the buffer table (up to 8MB!). * However this driver will only use a few entries. Reading * 1K entries allows for some expansion of queue count and * size before we need to change the version. */ @@ -1836,7 +1857,6 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = { A, A, 8, 1024), REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL, B, Z, 8, 1024), - /* RX_FILTER_TBL{0,1} is huge and not used by this driver */ REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0), REGISTER_TABLE_BB_CZ(TIMER_TBL), REGISTER_TABLE_BB_CZ(TX_PACE_TBL), @@ -1846,6 +1866,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = { REGISTER_TABLE_CZ(MC_TREG_SMEM), /* MSIX_PBA_TABLE is not mapped */ /* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */ + REGISTER_TABLE_BZ(RX_FILTER_TBL0), }; size_t efx_nic_get_regs_len(struct efx_nic *efx) diff --git a/drivers/net/sfc/phy.h b/drivers/net/sfc/phy.h index 5bc26137257b3ea4909e924165c1298a5f2c7267..1dab609757fb5490a7bf8af68f34acc81aac99d4 100644 --- a/drivers/net/sfc/phy.h +++ b/drivers/net/sfc/phy.h @@ -11,17 +11,12 @@ #define EFX_PHY_H /**************************************************************************** - * 10Xpress (SFX7101 and SFT9001) PHYs + * 10Xpress (SFX7101) PHY */ extern struct efx_phy_operations falcon_sfx7101_phy_ops; -extern struct efx_phy_operations falcon_sft9001_phy_ops; extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); -/* Wait for the PHY to boot. Return 0 on success, -EINVAL if the PHY failed - * to boot due to corrupt flash, or some other negative error code. */ -extern int sft9001_wait_boot(struct efx_nic *efx); - /**************************************************************************** * AMCC/Quake QT202x PHYs */ @@ -41,6 +36,17 @@ extern struct efx_phy_operations falcon_qt202x_phy_ops; extern void falcon_qt202x_set_led(struct efx_nic *p, int led, int state); +/**************************************************************************** +* Transwitch CX4 retimer +*/ +extern struct efx_phy_operations falcon_txc_phy_ops; + +#define TXC_GPIO_DIR_INPUT 0 +#define TXC_GPIO_DIR_OUTPUT 1 + +extern void falcon_txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir); +extern void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int val); + /**************************************************************************** * Siena managed PHYs */ diff --git a/drivers/net/sfc/regs.h b/drivers/net/sfc/regs.h index 18a3be428348754028fc1556f0e06813f8081197..96430ed81c36712a3dec2134f35f241f91466a07 100644 --- a/drivers/net/sfc/regs.h +++ b/drivers/net/sfc/regs.h @@ -2893,6 +2893,20 @@ #define FRF_AB_XX_FORCE_SIG_WIDTH 8 #define FFE_AB_XX_FORCE_SIG_ALL_LANES 0xff +/* RX_MAC_FILTER_TBL0 */ +/* RMFT_DEST_MAC is wider than 32 bits */ +#define FRF_CZ_RMFT_DEST_MAC_LO_LBN 12 +#define FRF_CZ_RMFT_DEST_MAC_LO_WIDTH 32 +#define FRF_CZ_RMFT_DEST_MAC_HI_LBN 44 +#define FRF_CZ_RMFT_DEST_MAC_HI_WIDTH 16 + +/* TX_MAC_FILTER_TBL0 */ +/* TMFT_SRC_MAC is wider than 32 bits */ +#define FRF_CZ_TMFT_SRC_MAC_LO_LBN 12 +#define FRF_CZ_TMFT_SRC_MAC_LO_WIDTH 32 +#define FRF_CZ_TMFT_SRC_MAC_HI_LBN 44 +#define FRF_CZ_TMFT_SRC_MAC_HI_WIDTH 16 + /* DRIVER_EV */ /* Sub-fields of an RX flush completion event */ #define FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL_LBN 12 diff --git a/drivers/net/sfc/rx.c b/drivers/net/sfc/rx.c index 799c461ce7b850c91fbdbff627c4993880a43c43..6d0959b5158e614e71180b3116f7de7196900d62 100644 --- a/drivers/net/sfc/rx.c +++ b/drivers/net/sfc/rx.c @@ -133,7 +133,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) unsigned index, count; for (count = 0; count < EFX_RX_BATCH; ++count) { - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->skb = netdev_alloc_skb(net_dev, skb_len); @@ -208,7 +208,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) dma_addr += sizeof(struct efx_rx_page_state); split: - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; rx_buf = efx_rx_buffer(rx_queue, index); rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->skb = NULL; @@ -285,7 +285,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, * we'd like to insert an additional descriptor whilst leaving * EFX_RXD_HEAD_ROOM for the non-recycle path */ fill_level = (rx_queue->added_count - rx_queue->removed_count + 2); - if (unlikely(fill_level >= EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM)) { + if (unlikely(fill_level > rx_queue->max_fill)) { /* We could place "state" on a list, and drain the list in * efx_fast_push_rx_descriptors(). For now, this will do. */ return; @@ -294,7 +294,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, ++state->refcnt; get_page(rx_buf->page); - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); new_buf->skb = NULL; @@ -311,7 +311,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) { struct efx_nic *efx = channel->efx; - struct efx_rx_queue *rx_queue = &efx->rx_queue[channel->channel]; + struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel); struct efx_rx_buffer *new_buf; unsigned index; @@ -319,7 +319,7 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, page_count(rx_buf->page) == 1) efx_resurrect_rx_buffer(rx_queue, rx_buf); - index = rx_queue->added_count & EFX_RXQ_MASK; + index = rx_queue->added_count & rx_queue->ptr_mask; new_buf = efx_rx_buffer(rx_queue, index); memcpy(new_buf, rx_buf, sizeof(*new_buf)); @@ -341,13 +341,13 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, */ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) { - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); unsigned fill_level; int space, rc = 0; /* Calculate current fill level, and exit if we don't need to fill */ fill_level = (rx_queue->added_count - rx_queue->removed_count); - EFX_BUG_ON_PARANOID(fill_level > EFX_RXQ_SIZE); + EFX_BUG_ON_PARANOID(fill_level > rx_queue->efx->rxq_entries); if (fill_level >= rx_queue->fast_fill_trigger) goto out; @@ -364,7 +364,8 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filling descriptor ring from" " level %d to level %d using %s allocation\n", - rx_queue->queue, fill_level, rx_queue->fast_fill_limit, + efx_rx_queue_index(rx_queue), fill_level, + rx_queue->fast_fill_limit, channel->rx_alloc_push_pages ? "page" : "skb"); do { @@ -382,7 +383,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) netif_vdbg(rx_queue->efx, rx_status, rx_queue->efx->net_dev, "RX queue %d fast-filled descriptor ring " - "to level %d\n", rx_queue->queue, + "to level %d\n", efx_rx_queue_index(rx_queue), rx_queue->added_count - rx_queue->removed_count); out: @@ -393,7 +394,7 @@ void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue) void efx_rx_slow_fill(unsigned long context) { struct efx_rx_queue *rx_queue = (struct efx_rx_queue *)context; - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); /* Post an event to cause NAPI to run and refill the queue */ efx_nic_generate_fill_event(channel); @@ -421,7 +422,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, netif_err(efx, rx_err, efx->net_dev, " RX queue %d seriously overlength " "RX event (0x%x > 0x%x+0x%x). Leaking\n", - rx_queue->queue, len, max_len, + efx_rx_queue_index(rx_queue), len, max_len, efx->type->rx_buffer_padding); /* If this buffer was skb-allocated, then the meta * data at the end of the skb will be trashed. So @@ -434,10 +435,10 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, netif_err(efx, rx_err, efx->net_dev, " RX queue %d overlength RX event " "(0x%x > 0x%x)\n", - rx_queue->queue, len, max_len); + efx_rx_queue_index(rx_queue), len, max_len); } - rx_queue->channel->n_rx_overlength++; + efx_rx_queue_channel(rx_queue)->n_rx_overlength++; } /* Pass a received packet up through the generic LRO stack @@ -507,7 +508,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, unsigned int len, bool checksummed, bool discard) { struct efx_nic *efx = rx_queue->efx; - struct efx_channel *channel = rx_queue->channel; + struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_rx_buffer *rx_buf; bool leak_packet = false; @@ -528,7 +529,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, netif_vdbg(efx, rx_status, efx->net_dev, "RX queue %d received id %x at %llx+%x %s%s\n", - rx_queue->queue, index, + efx_rx_queue_index(rx_queue), index, (unsigned long long)rx_buf->dma_addr, len, (checksummed ? " [SUMMED]" : ""), (discard ? " [DISCARD]" : "")); @@ -560,12 +561,11 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, */ rx_buf->len = len; out: - if (rx_queue->channel->rx_pkt) - __efx_rx_packet(rx_queue->channel, - rx_queue->channel->rx_pkt, - rx_queue->channel->rx_pkt_csummed); - rx_queue->channel->rx_pkt = rx_buf; - rx_queue->channel->rx_pkt_csummed = checksummed; + if (channel->rx_pkt) + __efx_rx_packet(channel, + channel->rx_pkt, channel->rx_pkt_csummed); + channel->rx_pkt = rx_buf; + channel->rx_pkt_csummed = checksummed; } /* Handle a received packet. Second half: Touches packet payload. */ @@ -615,7 +615,7 @@ void __efx_rx_packet(struct efx_channel *channel, EFX_BUG_ON_PARANOID(!skb); /* Set the SKB flags */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); /* Pass the packet up */ netif_receive_skb(skb); @@ -650,15 +650,22 @@ void efx_rx_strategy(struct efx_channel *channel) int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; - unsigned int rxq_size; + unsigned int entries; int rc; + /* Create the smallest power-of-two aligned ring */ + entries = max(roundup_pow_of_two(efx->rxq_entries), EFX_MIN_DMAQ_SIZE); + EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE); + rx_queue->ptr_mask = entries - 1; + netif_dbg(efx, probe, efx->net_dev, - "creating RX queue %d\n", rx_queue->queue); + "creating RX queue %d size %#x mask %#x\n", + efx_rx_queue_index(rx_queue), efx->rxq_entries, + rx_queue->ptr_mask); /* Allocate RX buffers */ - rxq_size = EFX_RXQ_SIZE * sizeof(*rx_queue->buffer); - rx_queue->buffer = kzalloc(rxq_size, GFP_KERNEL); + rx_queue->buffer = kzalloc(entries * sizeof(*rx_queue->buffer), + GFP_KERNEL); if (!rx_queue->buffer) return -ENOMEM; @@ -672,20 +679,20 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) void efx_init_rx_queue(struct efx_rx_queue *rx_queue) { + struct efx_nic *efx = rx_queue->efx; unsigned int max_fill, trigger, limit; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "initialising RX queue %d\n", rx_queue->queue); + "initialising RX queue %d\n", efx_rx_queue_index(rx_queue)); /* Initialise ptr fields */ rx_queue->added_count = 0; rx_queue->notified_count = 0; rx_queue->removed_count = 0; rx_queue->min_fill = -1U; - rx_queue->min_overfill = -1U; /* Initialise limit fields */ - max_fill = EFX_RXQ_SIZE - EFX_RXD_HEAD_ROOM; + max_fill = efx->rxq_entries - EFX_RXD_HEAD_ROOM; trigger = max_fill * min(rx_refill_threshold, 100U) / 100U; limit = max_fill * min(rx_refill_limit, 100U) / 100U; @@ -703,14 +710,14 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) struct efx_rx_buffer *rx_buf; netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "shutting down RX queue %d\n", rx_queue->queue); + "shutting down RX queue %d\n", efx_rx_queue_index(rx_queue)); del_timer_sync(&rx_queue->slow_fill); efx_nic_fini_rx(rx_queue); /* Release RX buffers NB start at index 0 not current HW ptr */ if (rx_queue->buffer) { - for (i = 0; i <= EFX_RXQ_MASK; i++) { + for (i = 0; i <= rx_queue->ptr_mask; i++) { rx_buf = efx_rx_buffer(rx_queue, i); efx_fini_rx_buffer(rx_queue, rx_buf); } @@ -720,7 +727,7 @@ void efx_fini_rx_queue(struct efx_rx_queue *rx_queue) void efx_remove_rx_queue(struct efx_rx_queue *rx_queue) { netif_dbg(rx_queue->efx, drv, rx_queue->efx->net_dev, - "destroying RX queue %d\n", rx_queue->queue); + "destroying RX queue %d\n", efx_rx_queue_index(rx_queue)); efx_nic_remove_rx(rx_queue); diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index 85f015f005d5c12afecdf1a1db7fe91fbdd8c3f1..0ebfb99f12991fc0e4a7bfe3b17799c736834798 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -48,6 +48,16 @@ static const unsigned char payload_source[ETH_ALEN] = { static const char payload_msg[] = "Hello world! This is an Efx loopback test in progress!"; +/* Interrupt mode names */ +static const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX; +static const char *efx_interrupt_mode_names[] = { + [EFX_INT_MODE_MSIX] = "MSI-X", + [EFX_INT_MODE_MSI] = "MSI", + [EFX_INT_MODE_LEGACY] = "legacy", +}; +#define INT_MODE(efx) \ + STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode) + /** * efx_loopback_state - persistent state during a loopback selftest * @flush: Drop all packets in efx_loopback_rx_packet @@ -506,7 +516,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue, for (i = 0; i < 3; i++) { /* Determine how many packets to send */ - state->packet_count = EFX_TXQ_SIZE / 3; + state->packet_count = efx->txq_entries / 3; state->packet_count = min(1 << (i << 2), state->packet_count); state->skbs = kzalloc(sizeof(state->skbs[0]) * state->packet_count, GFP_KERNEL); @@ -567,7 +577,7 @@ static int efx_wait_for_link(struct efx_nic *efx) efx->type->monitor(efx); mutex_unlock(&efx->mac_lock); } else { - struct efx_channel *channel = &efx->channel[0]; + struct efx_channel *channel = efx_get_channel(efx, 0); if (channel->work_pending) efx_process_channel_now(channel); } @@ -594,6 +604,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, { enum efx_loopback_mode mode; struct efx_loopback_state *state; + struct efx_channel *channel = efx_get_channel(efx, 0); struct efx_tx_queue *tx_queue; int rc = 0; @@ -634,7 +645,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, } /* Test both types of TX queue */ - efx_for_each_channel_tx_queue(tx_queue, &efx->channel[0]) { + efx_for_each_channel_tx_queue(tx_queue, channel) { state->offload_csum = (tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD); rc = efx_test_loopback(tx_queue, diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 3fab030f8ab5508aa191dd5cc2d1b7b69a935fd8..45236f58a25849e6bf49f63a9e1207725a245834 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -129,7 +129,7 @@ static int siena_probe_port(struct efx_nic *efx) return 0; } -void siena_remove_port(struct efx_nic *efx) +static void siena_remove_port(struct efx_nic *efx) { efx->phy_op->remove(efx); efx_nic_free_buffer(efx, &efx->stats_buffer); @@ -450,7 +450,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) mac_stats->rx_bad_bytes); MAC_STAT(rx_packets, RX_PKTS); MAC_STAT(rx_good, RX_GOOD_PKTS); - mac_stats->rx_bad = mac_stats->rx_packets - mac_stats->rx_good; + MAC_STAT(rx_bad, RX_BAD_FCS_PKTS); MAC_STAT(rx_pause, RX_PAUSE_PKTS); MAC_STAT(rx_control, RX_CONTROL_PKTS); MAC_STAT(rx_unicast, RX_UNICAST_PKTS); @@ -651,6 +651,6 @@ struct efx_nic_type siena_a0_nic_type = { .tx_dc_base = 0x88000, .rx_dc_base = 0x68000, .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXHASH), + NETIF_F_RXHASH | NETIF_F_NTUPLE), .reset_world_flags = ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT, }; diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 6791be90c2fe095f213e8d94e3f5077f0e8053da..1bc6c48c96ee5ff064f40423c05be0c6d8701b0e 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -19,10 +19,7 @@ #include "workarounds.h" #include "selftest.h" -/* We expect these MMDs to be in the package. SFT9001 also has a - * clause 22 extension MMD, but since it doesn't have all the generic - * MMD registers it is pointless to include it here. - */ +/* We expect these MMDs to be in the package. */ #define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD | \ MDIO_DEVS_PCS | \ MDIO_DEVS_PHYXS | \ @@ -33,12 +30,6 @@ (1 << LOOPBACK_PMAPMD) | \ (1 << LOOPBACK_PHYXS_WS)) -#define SFT9001_LOOPBACKS ((1 << LOOPBACK_GPHY) | \ - (1 << LOOPBACK_PHYXS) | \ - (1 << LOOPBACK_PCS) | \ - (1 << LOOPBACK_PMAPMD) | \ - (1 << LOOPBACK_PHYXS_WS)) - /* We complain if we fail to see the link partner as 10G capable this many * times in a row (must be > 1 as sampling the autoneg. registers is racy) */ @@ -50,9 +41,8 @@ #define PMA_PMD_EXT_GMII_EN_WIDTH 1 #define PMA_PMD_EXT_CLK_OUT_LBN 2 #define PMA_PMD_EXT_CLK_OUT_WIDTH 1 -#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 /* SFX7101 only */ +#define PMA_PMD_LNPGA_POWERDOWN_LBN 8 #define PMA_PMD_LNPGA_POWERDOWN_WIDTH 1 -#define PMA_PMD_EXT_CLK312_LBN 8 /* SFT9001 only */ #define PMA_PMD_EXT_CLK312_WIDTH 1 #define PMA_PMD_EXT_LPOWER_LBN 12 #define PMA_PMD_EXT_LPOWER_WIDTH 1 @@ -84,7 +74,6 @@ #define PMA_PMD_LED_FLASH (3) #define PMA_PMD_LED_MASK 3 /* All LEDs under hardware control */ -#define SFT9001_PMA_PMD_LED_DEFAULT 0 /* Green and Amber under hardware control, Red off */ #define SFX7101_PMA_PMD_LED_DEFAULT (PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN) @@ -98,31 +87,7 @@ #define PMA_PMD_SPEED_LBN 4 #define PMA_PMD_SPEED_WIDTH 4 -/* Cable diagnostics - SFT9001 only */ -#define PMA_PMD_CDIAG_CTRL_REG 49213 -#define CDIAG_CTRL_IMMED_LBN 15 -#define CDIAG_CTRL_BRK_LINK_LBN 12 -#define CDIAG_CTRL_IN_PROG_LBN 11 -#define CDIAG_CTRL_LEN_UNIT_LBN 10 -#define CDIAG_CTRL_LEN_METRES 1 -#define PMA_PMD_CDIAG_RES_REG 49174 -#define CDIAG_RES_A_LBN 12 -#define CDIAG_RES_B_LBN 8 -#define CDIAG_RES_C_LBN 4 -#define CDIAG_RES_D_LBN 0 -#define CDIAG_RES_WIDTH 4 -#define CDIAG_RES_OPEN 2 -#define CDIAG_RES_OK 1 -#define CDIAG_RES_INVALID 0 -/* Set of 4 registers for pairs A-D */ -#define PMA_PMD_CDIAG_LEN_REG 49175 - -/* Serdes control registers - SFT9001 only */ -#define PMA_PMD_CSERDES_CTRL_REG 64258 -/* Set the 156.25 MHz output to 312.5 MHz to drive Falcon's XMAC */ -#define PMA_PMD_CSERDES_DEFAULT 0x000f - -/* Misc register defines - SFX7101 only */ +/* Misc register defines */ #define PCS_CLOCK_CTRL_REG 55297 #define PLL312_RST_N_LBN 2 @@ -185,121 +150,17 @@ struct tenxpress_phy_data { int bad_lp_tries; }; -static ssize_t show_phy_short_reach(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); - int reg; - - reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR); - return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT)); -} - -static ssize_t set_phy_short_reach(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); - int rc; - - rtnl_lock(); - if (efx->state != STATE_RUNNING) { - rc = -EBUSY; - } else { - efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR, - MDIO_PMA_10GBT_TXPWR_SHORT, - count != 0 && *buf != '0'); - rc = efx_reconfigure_port(efx); - } - rtnl_unlock(); - - return rc < 0 ? rc : (ssize_t)count; -} - -static DEVICE_ATTR(phy_short_reach, 0644, show_phy_short_reach, - set_phy_short_reach); - -int sft9001_wait_boot(struct efx_nic *efx) -{ - unsigned long timeout = jiffies + HZ + 1; - int boot_stat; - - for (;;) { - boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS, - PCS_BOOT_STATUS_REG); - if (boot_stat >= 0) { - netif_dbg(efx, hw, efx->net_dev, - "PHY boot status = %#x\n", boot_stat); - switch (boot_stat & - ((1 << PCS_BOOT_FATAL_ERROR_LBN) | - (3 << PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) | - (1 << PCS_BOOT_CODE_STARTED_LBN))) { - case ((1 << PCS_BOOT_FATAL_ERROR_LBN) | - (PCS_BOOT_PROGRESS_CHECKSUM << - PCS_BOOT_PROGRESS_LBN)): - case ((1 << PCS_BOOT_FATAL_ERROR_LBN) | - (PCS_BOOT_PROGRESS_INIT << - PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)): - return -EINVAL; - case ((PCS_BOOT_PROGRESS_WAIT_MDIO << - PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN)): - return (efx->phy_mode & PHY_MODE_SPECIAL) ? - 0 : -EIO; - case ((PCS_BOOT_PROGRESS_JUMP << - PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_CODE_STARTED_LBN)): - case ((PCS_BOOT_PROGRESS_JUMP << - PCS_BOOT_PROGRESS_LBN) | - (1 << PCS_BOOT_DOWNLOAD_WAIT_LBN) | - (1 << PCS_BOOT_CODE_STARTED_LBN)): - return (efx->phy_mode & PHY_MODE_SPECIAL) ? - -EIO : 0; - default: - if (boot_stat & (1 << PCS_BOOT_FATAL_ERROR_LBN)) - return -EIO; - break; - } - } - - if (time_after_eq(jiffies, timeout)) - return -ETIMEDOUT; - - msleep(50); - } -} - static int tenxpress_init(struct efx_nic *efx) { - int reg; - - if (efx->phy_type == PHY_TYPE_SFX7101) { - /* Enable 312.5 MHz clock */ - efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG, - 1 << CLK312_EN_LBN); - } else { - /* Enable 312.5 MHz clock and GMII */ - reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); - reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) | - (1 << PMA_PMD_EXT_CLK_OUT_LBN) | - (1 << PMA_PMD_EXT_CLK312_LBN) | - (1 << PMA_PMD_EXT_ROBUST_LBN)); - - efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); - efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, - GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN, - false); - } + /* Enable 312.5 MHz clock */ + efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG, + 1 << CLK312_EN_LBN); /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */ - if (efx->phy_type == PHY_TYPE_SFX7101) { - efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG, - 1 << PMA_PMA_LED_ACTIVITY_LBN, true); - efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, - SFX7101_PMA_PMD_LED_DEFAULT); - } + efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG, + 1 << PMA_PMA_LED_ACTIVITY_LBN, true); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, + SFX7101_PMA_PMD_LED_DEFAULT); return 0; } @@ -307,7 +168,6 @@ static int tenxpress_init(struct efx_nic *efx) static int tenxpress_phy_probe(struct efx_nic *efx) { struct tenxpress_phy_data *phy_data; - int rc; /* Allocate phy private storage */ phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); @@ -316,42 +176,15 @@ static int tenxpress_phy_probe(struct efx_nic *efx) efx->phy_data = phy_data; phy_data->phy_mode = efx->phy_mode; - /* Create any special files */ - if (efx->phy_type == PHY_TYPE_SFT9001B) { - rc = device_create_file(&efx->pci_dev->dev, - &dev_attr_phy_short_reach); - if (rc) - goto fail; - } - - if (efx->phy_type == PHY_TYPE_SFX7101) { - efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; - efx->mdio.mode_support = MDIO_SUPPORTS_C45; - - efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; + efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45; - efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | - ADVERTISED_10000baseT_Full); - } else { - efx->mdio.mmds = TENXPRESS_REQUIRED_DEVS; - efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + efx->loopback_modes = SFX7101_LOOPBACKS | FALCON_XMAC_LOOPBACKS; - efx->loopback_modes = (SFT9001_LOOPBACKS | - FALCON_XMAC_LOOPBACKS | - FALCON_GMAC_LOOPBACKS); - - efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | - ADVERTISED_10000baseT_Full | - ADVERTISED_1000baseT_Full | - ADVERTISED_100baseT_Full); - } + efx->link_advertising = (ADVERTISED_TP | ADVERTISED_Autoneg | + ADVERTISED_10000baseT_Full); return 0; - -fail: - kfree(efx->phy_data); - efx->phy_data = NULL; - return rc; } static int tenxpress_phy_init(struct efx_nic *efx) @@ -361,16 +194,6 @@ static int tenxpress_phy_init(struct efx_nic *efx) falcon_board(efx)->type->init_phy(efx); if (!(efx->phy_mode & PHY_MODE_SPECIAL)) { - if (efx->phy_type == PHY_TYPE_SFT9001A) { - int reg; - reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG); - reg |= (1 << PMA_PMD_EXT_SSR_LBN); - efx_mdio_write(efx, MDIO_MMD_PMAPMD, - PMA_PMD_XCONTROL_REG, reg); - mdelay(200); - } - rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) return rc; @@ -403,7 +226,7 @@ static int tenxpress_special_reset(struct efx_nic *efx) { int rc, reg; - /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so + /* The XGMAC clock is driven from the SFX7101 312MHz clock, so * a special software reset can glitch the XGMAC sufficiently for stats * requests to fail. */ falcon_stop_nic_stats(efx); @@ -484,53 +307,18 @@ static bool sfx7101_link_ok(struct efx_nic *efx) MDIO_DEVS_PHYXS); } -static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd) -{ - u32 reg; - - if (efx_phy_mode_disabled(efx->phy_mode)) - return false; - else if (efx->loopback_mode == LOOPBACK_GPHY) - return true; - else if (efx->loopback_mode) - return efx_mdio_links_ok(efx, - MDIO_DEVS_PMAPMD | - MDIO_DEVS_PHYXS); - - /* We must use the same definition of link state as LASI, - * otherwise we can miss a link state transition - */ - if (ecmd->speed == 10000) { - reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1); - return reg & MDIO_PCS_10GBRT_STAT1_BLKLK; - } else { - reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG); - return reg & (1 << C22EXT_STATUS_LINK_LBN); - } -} - static void tenxpress_ext_loopback(struct efx_nic *efx) { efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1, 1 << LOOPBACK_NEAR_LBN, efx->loopback_mode == LOOPBACK_PHYXS); - if (efx->phy_type != PHY_TYPE_SFX7101) - efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG, - 1 << GPHY_LOOPBACK_NEAR_LBN, - efx->loopback_mode == LOOPBACK_GPHY); } static void tenxpress_low_power(struct efx_nic *efx) { - if (efx->phy_type == PHY_TYPE_SFX7101) - efx_mdio_set_mmds_lpower( - efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), - TENXPRESS_REQUIRED_DEVS); - else - efx_mdio_set_flag( - efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, - 1 << PMA_PMD_EXT_LPOWER_LBN, - !!(efx->phy_mode & PHY_MODE_LOW_POWER)); + efx_mdio_set_mmds_lpower( + efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER), + TENXPRESS_REQUIRED_DEVS); } static int tenxpress_phy_reconfigure(struct efx_nic *efx) @@ -550,12 +338,7 @@ static int tenxpress_phy_reconfigure(struct efx_nic *efx) if (loop_reset || phy_mode_change) { tenxpress_special_reset(efx); - - /* Reset XAUI if we were in 10G, and are staying - * in 10G. If we're moving into and out of 10G - * then xaui will be reset anyway */ - if (EFX_IS10G(efx)) - falcon_reset_xaui(efx); + falcon_reset_xaui(efx); } tenxpress_low_power(efx); @@ -578,29 +361,12 @@ static bool tenxpress_phy_poll(struct efx_nic *efx) { struct efx_link_state old_state = efx->link_state; - if (efx->phy_type == PHY_TYPE_SFX7101) { - efx->link_state.up = sfx7101_link_ok(efx); - efx->link_state.speed = 10000; - efx->link_state.fd = true; - efx->link_state.fc = efx_mdio_get_pause(efx); - - sfx7101_check_bad_lp(efx, efx->link_state.up); - } else { - struct ethtool_cmd ecmd; - - /* Check the LASI alarm first */ - if (efx->loopback_mode == LOOPBACK_NONE && - !(efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT) & - MDIO_PMA_LASI_LSALARM)) - return false; + efx->link_state.up = sfx7101_link_ok(efx); + efx->link_state.speed = 10000; + efx->link_state.fd = true; + efx->link_state.fc = efx_mdio_get_pause(efx); - tenxpress_get_settings(efx, &ecmd); - - efx->link_state.up = sft9001_link_ok(efx, &ecmd); - efx->link_state.speed = ecmd.speed; - efx->link_state.fd = (ecmd.duplex == DUPLEX_FULL); - efx->link_state.fc = efx_mdio_get_pause(efx); - } + sfx7101_check_bad_lp(efx, efx->link_state.up); return !efx_link_state_equal(&efx->link_state, &old_state); } @@ -621,10 +387,6 @@ static void sfx7101_phy_fini(struct efx_nic *efx) static void tenxpress_phy_remove(struct efx_nic *efx) { - if (efx->phy_type == PHY_TYPE_SFT9001B) - device_remove_file(&efx->pci_dev->dev, - &dev_attr_phy_short_reach); - kfree(efx->phy_data); efx->phy_data = NULL; } @@ -647,10 +409,7 @@ void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) (PMA_PMD_LED_ON << PMA_PMD_LED_LINK_LBN); break; default: - if (efx->phy_type == PHY_TYPE_SFX7101) - reg = SFX7101_PMA_PMD_LED_DEFAULT; - else - reg = SFT9001_PMA_PMD_LED_DEFAULT; + reg = SFX7101_PMA_PMD_LED_DEFAULT; break; } @@ -685,102 +444,12 @@ sfx7101_run_tests(struct efx_nic *efx, int *results, unsigned flags) return rc; } -static const char *const sft9001_test_names[] = { - "bist", - "cable.pairA.status", - "cable.pairB.status", - "cable.pairC.status", - "cable.pairD.status", - "cable.pairA.length", - "cable.pairB.length", - "cable.pairC.length", - "cable.pairD.length", -}; - -static const char *sft9001_test_name(struct efx_nic *efx, unsigned int index) -{ - if (index < ARRAY_SIZE(sft9001_test_names)) - return sft9001_test_names[index]; - return NULL; -} - -static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags) -{ - int rc = 0, rc2, i, ctrl_reg, res_reg; - - /* Initialise cable diagnostic results to unknown failure */ - for (i = 1; i < 9; ++i) - results[i] = -1; - - /* Run cable diagnostics; wait up to 5 seconds for them to complete. - * A cable fault is not a self-test failure, but a timeout is. */ - ctrl_reg = ((1 << CDIAG_CTRL_IMMED_LBN) | - (CDIAG_CTRL_LEN_METRES << CDIAG_CTRL_LEN_UNIT_LBN)); - if (flags & ETH_TEST_FL_OFFLINE) { - /* Break the link in order to run full diagnostics. We - * must reset the PHY to resume normal service. */ - ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN); - } - efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG, - ctrl_reg); - i = 0; - while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) & - (1 << CDIAG_CTRL_IN_PROG_LBN)) { - if (++i == 50) { - rc = -ETIMEDOUT; - goto out; - } - msleep(100); - } - res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG); - for (i = 0; i < 4; i++) { - int pair_res = - (res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH)) - & ((1 << CDIAG_RES_WIDTH) - 1); - int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, - PMA_PMD_CDIAG_LEN_REG + i); - if (pair_res == CDIAG_RES_OK) - results[1 + i] = 1; - else if (pair_res == CDIAG_RES_INVALID) - results[1 + i] = -1; - else - results[1 + i] = -pair_res; - if (pair_res != CDIAG_RES_INVALID && - pair_res != CDIAG_RES_OPEN && - len_reg != 0xffff) - results[5 + i] = len_reg; - } - -out: - if (flags & ETH_TEST_FL_OFFLINE) { - /* Reset, running the BIST and then resuming normal service. */ - rc2 = tenxpress_special_reset(efx); - results[0] = rc2 ? -1 : 1; - if (!rc) - rc = rc2; - - efx_mdio_an_reconfigure(efx); - } - - return rc; -} - static void tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { u32 adv = 0, lpa = 0; int reg; - if (efx->phy_type != PHY_TYPE_SFX7101) { - reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL); - if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN)) - adv |= ADVERTISED_1000baseT_Full; - reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS); - if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN)) - lpa |= ADVERTISED_1000baseT_Half; - if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN)) - lpa |= ADVERTISED_1000baseT_Full; - } reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL); if (reg & MDIO_AN_10GBT_CTRL_ADV10G) adv |= ADVERTISED_10000baseT_Full; @@ -790,23 +459,9 @@ tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa); - if (efx->phy_type != PHY_TYPE_SFX7101) { - ecmd->supported |= (SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Full); - if (ecmd->speed != SPEED_10000) { - ecmd->eth_tp_mdix = - (efx_mdio_read(efx, MDIO_MMD_PMAPMD, - PMA_PMD_XSTATUS_REG) & - (1 << PMA_PMD_XSTAT_MDIX_LBN)) - ? ETH_TP_MDI_X : ETH_TP_MDI; - } - } - /* In loopback, the PHY automatically brings up the correct interface, * but doesn't advertise the correct speed. So override it */ - if (efx->loopback_mode == LOOPBACK_GPHY) - ecmd->speed = SPEED_1000; - else if (LOOPBACK_EXTERNAL(efx)) + if (LOOPBACK_EXTERNAL(efx)) ecmd->speed = SPEED_10000; } @@ -825,16 +480,6 @@ static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising) advertising & ADVERTISED_10000baseT_Full); } -static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising) -{ - efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL, - 1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN, - advertising & ADVERTISED_1000baseT_Full); - efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, - MDIO_AN_10GBT_CTRL_ADV10G, - advertising & ADVERTISED_10000baseT_Full); -} - struct efx_phy_operations falcon_sfx7101_phy_ops = { .probe = tenxpress_phy_probe, .init = tenxpress_phy_init, @@ -849,18 +494,3 @@ struct efx_phy_operations falcon_sfx7101_phy_ops = { .test_name = sfx7101_test_name, .run_tests = sfx7101_run_tests, }; - -struct efx_phy_operations falcon_sft9001_phy_ops = { - .probe = tenxpress_phy_probe, - .init = tenxpress_phy_init, - .reconfigure = tenxpress_phy_reconfigure, - .poll = tenxpress_phy_poll, - .fini = efx_port_dummy_op_void, - .remove = tenxpress_phy_remove, - .get_settings = tenxpress_get_settings, - .set_settings = tenxpress_set_settings, - .set_npage_adv = sft9001_set_npage_adv, - .test_alive = efx_mdio_test_alive, - .test_name = sft9001_test_name, - .run_tests = sft9001_run_tests, -}; diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index c6942da2c99af75b6749c7b94edf7b8204cdc676..11726989fe2d8d62d0de7fd4ba09f5682cd491a6 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -28,7 +28,7 @@ * The tx_queue descriptor ring fill-level must fall below this value * before we restart the netif queue */ -#define EFX_TXQ_THRESHOLD (EFX_TXQ_MASK / 2u) +#define EFX_TXQ_THRESHOLD(_efx) ((_efx)->txq_entries / 2u) /* We need to be able to nest calls to netif_tx_stop_queue(), partly * because of the 2 hardware queues associated with each core queue, @@ -37,8 +37,9 @@ void efx_stop_queue(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; + struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0); - if (!channel->tx_queue) + if (!tx_queue) return; spin_lock_bh(&channel->tx_stop_lock); @@ -46,9 +47,8 @@ void efx_stop_queue(struct efx_channel *channel) atomic_inc(&channel->tx_stop_count); netif_tx_stop_queue( - netdev_get_tx_queue( - efx->net_dev, - channel->tx_queue->queue / EFX_TXQ_TYPES)); + netdev_get_tx_queue(efx->net_dev, + tx_queue->queue / EFX_TXQ_TYPES)); spin_unlock_bh(&channel->tx_stop_lock); } @@ -57,8 +57,9 @@ void efx_stop_queue(struct efx_channel *channel) void efx_wake_queue(struct efx_channel *channel) { struct efx_nic *efx = channel->efx; + struct efx_tx_queue *tx_queue = efx_channel_get_tx_queue(channel, 0); - if (!channel->tx_queue) + if (!tx_queue) return; local_bh_disable(); @@ -66,9 +67,8 @@ void efx_wake_queue(struct efx_channel *channel) &channel->tx_stop_lock)) { netif_vdbg(efx, tx_queued, efx->net_dev, "waking TX queue\n"); netif_tx_wake_queue( - netdev_get_tx_queue( - efx->net_dev, - channel->tx_queue->queue / EFX_TXQ_TYPES)); + netdev_get_tx_queue(efx->net_dev, + tx_queue->queue / EFX_TXQ_TYPES)); spin_unlock(&channel->tx_stop_lock); } local_bh_enable(); @@ -207,7 +207,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) } fill_level = tx_queue->insert_count - tx_queue->old_read_count; - q_space = EFX_TXQ_MASK - 1 - fill_level; + q_space = efx->txq_entries - 1 - fill_level; /* Map for DMA. Use pci_map_single rather than pci_map_page * since this is more efficient on machines with sparse @@ -244,14 +244,14 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) &tx_queue->read_count; fill_level = (tx_queue->insert_count - tx_queue->old_read_count); - q_space = EFX_TXQ_MASK - 1 - fill_level; + q_space = efx->txq_entries - 1 - fill_level; if (unlikely(q_space-- <= 0)) goto stop; smp_mb(); --tx_queue->stopped; } - insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK; + insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->tsoh); @@ -320,7 +320,7 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb) /* Work backwards until we hit the original insert pointer value */ while (tx_queue->insert_count != tx_queue->write_count) { --tx_queue->insert_count; - insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK; + insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; efx_dequeue_buffer(tx_queue, buffer); buffer->len = 0; @@ -350,8 +350,8 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, struct efx_nic *efx = tx_queue->efx; unsigned int stop_index, read_ptr; - stop_index = (index + 1) & EFX_TXQ_MASK; - read_ptr = tx_queue->read_count & EFX_TXQ_MASK; + stop_index = (index + 1) & tx_queue->ptr_mask; + read_ptr = tx_queue->read_count & tx_queue->ptr_mask; while (read_ptr != stop_index) { struct efx_tx_buffer *buffer = &tx_queue->buffer[read_ptr]; @@ -368,7 +368,7 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue, buffer->len = 0; ++tx_queue->read_count; - read_ptr = tx_queue->read_count & EFX_TXQ_MASK; + read_ptr = tx_queue->read_count & tx_queue->ptr_mask; } } @@ -390,9 +390,9 @@ netdev_tx_t efx_hard_start_xmit(struct sk_buff *skb, if (unlikely(efx->port_inhibited)) return NETDEV_TX_BUSY; - tx_queue = &efx->tx_queue[EFX_TXQ_TYPES * skb_get_queue_mapping(skb)]; - if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) - tx_queue += EFX_TXQ_TYPE_OFFLOAD; + tx_queue = efx_get_tx_queue(efx, skb_get_queue_mapping(skb), + skb->ip_summed == CHECKSUM_PARTIAL ? + EFX_TXQ_TYPE_OFFLOAD : 0); return efx_enqueue_skb(tx_queue, skb); } @@ -402,7 +402,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) unsigned fill_level; struct efx_nic *efx = tx_queue->efx; - EFX_BUG_ON_PARANOID(index > EFX_TXQ_MASK); + EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask); efx_dequeue_buffers(tx_queue, index); @@ -412,7 +412,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) smp_mb(); if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) { fill_level = tx_queue->insert_count - tx_queue->read_count; - if (fill_level < EFX_TXQ_THRESHOLD) { + if (fill_level < EFX_TXQ_THRESHOLD(efx)) { EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); /* Do this under netif_tx_lock(), to avoid racing @@ -430,18 +430,24 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; - unsigned int txq_size; + unsigned int entries; int i, rc; - netif_dbg(efx, probe, efx->net_dev, "creating TX queue %d\n", - tx_queue->queue); + /* Create the smallest power-of-two aligned ring */ + entries = max(roundup_pow_of_two(efx->txq_entries), EFX_MIN_DMAQ_SIZE); + EFX_BUG_ON_PARANOID(entries > EFX_MAX_DMAQ_SIZE); + tx_queue->ptr_mask = entries - 1; + + netif_dbg(efx, probe, efx->net_dev, + "creating TX queue %d size %#x mask %#x\n", + tx_queue->queue, efx->txq_entries, tx_queue->ptr_mask); /* Allocate software ring */ - txq_size = EFX_TXQ_SIZE * sizeof(*tx_queue->buffer); - tx_queue->buffer = kzalloc(txq_size, GFP_KERNEL); + tx_queue->buffer = kzalloc(entries * sizeof(*tx_queue->buffer), + GFP_KERNEL); if (!tx_queue->buffer) return -ENOMEM; - for (i = 0; i <= EFX_TXQ_MASK; ++i) + for (i = 0; i <= tx_queue->ptr_mask; ++i) tx_queue->buffer[i].continuation = true; /* Allocate hardware ring */ @@ -481,7 +487,7 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue) /* Free any buffers left in the ring */ while (tx_queue->read_count != tx_queue->write_count) { - buffer = &tx_queue->buffer[tx_queue->read_count & EFX_TXQ_MASK]; + buffer = &tx_queue->buffer[tx_queue->read_count & tx_queue->ptr_mask]; efx_dequeue_buffer(tx_queue, buffer); buffer->continuation = true; buffer->len = 0; @@ -741,7 +747,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, fill_level = tx_queue->insert_count - tx_queue->old_read_count; /* -1 as there is no way to represent all descriptors used */ - q_space = EFX_TXQ_MASK - 1 - fill_level; + q_space = efx->txq_entries - 1 - fill_level; while (1) { if (unlikely(q_space-- <= 0)) { @@ -757,7 +763,7 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, *(volatile unsigned *)&tx_queue->read_count; fill_level = (tx_queue->insert_count - tx_queue->old_read_count); - q_space = EFX_TXQ_MASK - 1 - fill_level; + q_space = efx->txq_entries - 1 - fill_level; if (unlikely(q_space-- <= 0)) { *final_buffer = NULL; return 1; @@ -766,13 +772,13 @@ static int efx_tx_queue_insert(struct efx_tx_queue *tx_queue, --tx_queue->stopped; } - insert_ptr = tx_queue->insert_count & EFX_TXQ_MASK; + insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask; buffer = &tx_queue->buffer[insert_ptr]; ++tx_queue->insert_count; EFX_BUG_ON_PARANOID(tx_queue->insert_count - - tx_queue->read_count > - EFX_TXQ_MASK); + tx_queue->read_count >= + efx->txq_entries); efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->len); @@ -813,7 +819,7 @@ static void efx_tso_put_header(struct efx_tx_queue *tx_queue, { struct efx_tx_buffer *buffer; - buffer = &tx_queue->buffer[tx_queue->insert_count & EFX_TXQ_MASK]; + buffer = &tx_queue->buffer[tx_queue->insert_count & tx_queue->ptr_mask]; efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->len); EFX_BUG_ON_PARANOID(buffer->unmap_len); @@ -838,7 +844,7 @@ static void efx_enqueue_unwind(struct efx_tx_queue *tx_queue) while (tx_queue->insert_count != tx_queue->write_count) { --tx_queue->insert_count; buffer = &tx_queue->buffer[tx_queue->insert_count & - EFX_TXQ_MASK]; + tx_queue->ptr_mask]; efx_tsoh_free(tx_queue, buffer); EFX_BUG_ON_PARANOID(buffer->skb); if (buffer->unmap_len) { @@ -1168,7 +1174,7 @@ static void efx_fini_tso(struct efx_tx_queue *tx_queue) unsigned i; if (tx_queue->buffer) { - for (i = 0; i <= EFX_TXQ_MASK; ++i) + for (i = 0; i <= tx_queue->ptr_mask; ++i) efx_tsoh_free(tx_queue, &tx_queue->buffer[i]); } diff --git a/drivers/net/sfc/txc43128_phy.c b/drivers/net/sfc/txc43128_phy.c new file mode 100644 index 0000000000000000000000000000000000000000..351794a79215d071aa39ab468b93681d0c7ff205 --- /dev/null +++ b/drivers/net/sfc/txc43128_phy.c @@ -0,0 +1,560 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2006-2010 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +/* + * Driver for Transwitch/Mysticom CX4 retimer + * see www.transwitch.com, part is TXC-43128 + */ + +#include +#include +#include "efx.h" +#include "mdio_10g.h" +#include "phy.h" +#include "nic.h" + +/* We expect these MMDs to be in the package */ +#define TXC_REQUIRED_DEVS (MDIO_DEVS_PCS | \ + MDIO_DEVS_PMAPMD | \ + MDIO_DEVS_PHYXS) + +#define TXC_LOOPBACKS ((1 << LOOPBACK_PCS) | \ + (1 << LOOPBACK_PMAPMD) | \ + (1 << LOOPBACK_PHYXS_WS)) + +/************************************************************************** + * + * Compile-time config + * + ************************************************************************** + */ +#define TXCNAME "TXC43128" +/* Total length of time we'll wait for the PHY to come out of reset (ms) */ +#define TXC_MAX_RESET_TIME 500 +/* Interval between checks (ms) */ +#define TXC_RESET_WAIT 10 +/* How long to run BIST (us) */ +#define TXC_BIST_DURATION 50 + +/************************************************************************** + * + * Register definitions + * + ************************************************************************** + */ + +/* Command register */ +#define TXC_GLRGS_GLCMD 0xc004 +/* Useful bits in command register */ +/* Lane power-down */ +#define TXC_GLCMD_L01PD_LBN 5 +#define TXC_GLCMD_L23PD_LBN 6 +/* Limited SW reset: preserves configuration but + * initiates a logic reset. Self-clearing */ +#define TXC_GLCMD_LMTSWRST_LBN 14 + +/* Signal Quality Control */ +#define TXC_GLRGS_GSGQLCTL 0xc01a +/* Enable bit */ +#define TXC_GSGQLCT_SGQLEN_LBN 15 +/* Lane selection */ +#define TXC_GSGQLCT_LNSL_LBN 13 +#define TXC_GSGQLCT_LNSL_WIDTH 2 + +/* Analog TX control */ +#define TXC_ALRGS_ATXCTL 0xc040 +/* Lane power-down */ +#define TXC_ATXCTL_TXPD3_LBN 15 +#define TXC_ATXCTL_TXPD2_LBN 14 +#define TXC_ATXCTL_TXPD1_LBN 13 +#define TXC_ATXCTL_TXPD0_LBN 12 + +/* Amplitude on lanes 0, 1 */ +#define TXC_ALRGS_ATXAMP0 0xc041 +/* Amplitude on lanes 2, 3 */ +#define TXC_ALRGS_ATXAMP1 0xc042 +/* Bit position of value for lane 0 (or 2) */ +#define TXC_ATXAMP_LANE02_LBN 3 +/* Bit position of value for lane 1 (or 3) */ +#define TXC_ATXAMP_LANE13_LBN 11 + +#define TXC_ATXAMP_1280_mV 0 +#define TXC_ATXAMP_1200_mV 8 +#define TXC_ATXAMP_1120_mV 12 +#define TXC_ATXAMP_1060_mV 14 +#define TXC_ATXAMP_0820_mV 25 +#define TXC_ATXAMP_0720_mV 26 +#define TXC_ATXAMP_0580_mV 27 +#define TXC_ATXAMP_0440_mV 28 + +#define TXC_ATXAMP_0820_BOTH \ + ((TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE02_LBN) \ + | (TXC_ATXAMP_0820_mV << TXC_ATXAMP_LANE13_LBN)) + +#define TXC_ATXAMP_DEFAULT 0x6060 /* From databook */ + +/* Preemphasis on lanes 0, 1 */ +#define TXC_ALRGS_ATXPRE0 0xc043 +/* Preemphasis on lanes 2, 3 */ +#define TXC_ALRGS_ATXPRE1 0xc044 + +#define TXC_ATXPRE_NONE 0 +#define TXC_ATXPRE_DEFAULT 0x1010 /* From databook */ + +#define TXC_ALRGS_ARXCTL 0xc045 +/* Lane power-down */ +#define TXC_ARXCTL_RXPD3_LBN 15 +#define TXC_ARXCTL_RXPD2_LBN 14 +#define TXC_ARXCTL_RXPD1_LBN 13 +#define TXC_ARXCTL_RXPD0_LBN 12 + +/* Main control */ +#define TXC_MRGS_CTL 0xc340 +/* Bits in main control */ +#define TXC_MCTL_RESET_LBN 15 /* Self clear */ +#define TXC_MCTL_TXLED_LBN 14 /* 1 to show align status */ +#define TXC_MCTL_RXLED_LBN 13 /* 1 to show align status */ + +/* GPIO output */ +#define TXC_GPIO_OUTPUT 0xc346 +#define TXC_GPIO_DIR 0xc348 + +/* Vendor-specific BIST registers */ +#define TXC_BIST_CTL 0xc280 +#define TXC_BIST_TXFRMCNT 0xc281 +#define TXC_BIST_RX0FRMCNT 0xc282 +#define TXC_BIST_RX1FRMCNT 0xc283 +#define TXC_BIST_RX2FRMCNT 0xc284 +#define TXC_BIST_RX3FRMCNT 0xc285 +#define TXC_BIST_RX0ERRCNT 0xc286 +#define TXC_BIST_RX1ERRCNT 0xc287 +#define TXC_BIST_RX2ERRCNT 0xc288 +#define TXC_BIST_RX3ERRCNT 0xc289 + +/* BIST type (controls bit patter in test) */ +#define TXC_BIST_CTRL_TYPE_LBN 10 +#define TXC_BIST_CTRL_TYPE_TSD 0 /* TranSwitch Deterministic */ +#define TXC_BIST_CTRL_TYPE_CRP 1 /* CRPAT standard */ +#define TXC_BIST_CTRL_TYPE_CJP 2 /* CJPAT standard */ +#define TXC_BIST_CTRL_TYPE_TSR 3 /* TranSwitch pseudo-random */ +/* Set this to 1 for 10 bit and 0 for 8 bit */ +#define TXC_BIST_CTRL_B10EN_LBN 12 +/* Enable BIST (write 0 to disable) */ +#define TXC_BIST_CTRL_ENAB_LBN 13 +/* Stop BIST (self-clears when stop complete) */ +#define TXC_BIST_CTRL_STOP_LBN 14 +/* Start BIST (cleared by writing 1 to STOP) */ +#define TXC_BIST_CTRL_STRT_LBN 15 + +/* Mt. Diablo test configuration */ +#define TXC_MTDIABLO_CTRL 0xc34f +#define TXC_MTDIABLO_CTRL_PMA_LOOP_LBN 10 + +struct txc43128_data { + unsigned long bug10934_timer; + enum efx_phy_mode phy_mode; + enum efx_loopback_mode loopback_mode; +}; + +/* The PHY sometimes needs a reset to bring the link back up. So long as + * it reports link down, we reset it every 5 seconds. + */ +#define BUG10934_RESET_INTERVAL (5 * HZ) + +/* Perform a reset that doesn't clear configuration changes */ +static void txc_reset_logic(struct efx_nic *efx); + +/* Set the output value of a gpio */ +void falcon_txc_set_gpio_val(struct efx_nic *efx, int pin, int on) +{ + efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, TXC_GPIO_OUTPUT, 1 << pin, on); +} + +/* Set up the GPIO direction register */ +void falcon_txc_set_gpio_dir(struct efx_nic *efx, int pin, int dir) +{ + efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, TXC_GPIO_DIR, 1 << pin, dir); +} + +/* Reset the PMA/PMD MMD. The documentation is explicit that this does a + * global reset (it's less clear what reset of other MMDs does).*/ +static int txc_reset_phy(struct efx_nic *efx) +{ + int rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PMAPMD, + TXC_MAX_RESET_TIME / TXC_RESET_WAIT, + TXC_RESET_WAIT); + if (rc < 0) + goto fail; + + /* Check that all the MMDs we expect are present and responding. */ + rc = efx_mdio_check_mmds(efx, TXC_REQUIRED_DEVS, 0); + if (rc < 0) + goto fail; + + return 0; + +fail: + netif_err(efx, hw, efx->net_dev, TXCNAME ": reset timed out!\n"); + return rc; +} + +/* Run a single BIST on one MMD */ +static int txc_bist_one(struct efx_nic *efx, int mmd, int test) +{ + int ctrl, bctl; + int lane; + int rc = 0; + + /* Set PMA to test into loopback using Mt Diablo reg as per app note */ + ctrl = efx_mdio_read(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL); + ctrl |= (1 << TXC_MTDIABLO_CTRL_PMA_LOOP_LBN); + efx_mdio_write(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL, ctrl); + + /* The BIST app. note lists these as 3 distinct steps. */ + /* Set the BIST type */ + bctl = (test << TXC_BIST_CTRL_TYPE_LBN); + efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl); + + /* Set the BSTEN bit in the BIST Control register to enable */ + bctl |= (1 << TXC_BIST_CTRL_ENAB_LBN); + efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl); + + /* Set the BSTRT bit in the BIST Control register */ + efx_mdio_write(efx, mmd, TXC_BIST_CTL, + bctl | (1 << TXC_BIST_CTRL_STRT_LBN)); + + /* Wait. */ + udelay(TXC_BIST_DURATION); + + /* Set the BSTOP bit in the BIST Control register */ + bctl |= (1 << TXC_BIST_CTRL_STOP_LBN); + efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl); + + /* The STOP bit should go off when things have stopped */ + while (bctl & (1 << TXC_BIST_CTRL_STOP_LBN)) + bctl = efx_mdio_read(efx, mmd, TXC_BIST_CTL); + + /* Check all the error counts are 0 and all the frame counts are + non-zero */ + for (lane = 0; lane < 4; lane++) { + int count = efx_mdio_read(efx, mmd, TXC_BIST_RX0ERRCNT + lane); + if (count != 0) { + netif_err(efx, hw, efx->net_dev, TXCNAME": BIST error. " + "Lane %d had %d errs\n", lane, count); + rc = -EIO; + } + count = efx_mdio_read(efx, mmd, TXC_BIST_RX0FRMCNT + lane); + if (count == 0) { + netif_err(efx, hw, efx->net_dev, TXCNAME": BIST error. " + "Lane %d got 0 frames\n", lane); + rc = -EIO; + } + } + + if (rc == 0) + netif_info(efx, hw, efx->net_dev, TXCNAME": BIST pass\n"); + + /* Disable BIST */ + efx_mdio_write(efx, mmd, TXC_BIST_CTL, 0); + + /* Turn off loopback */ + ctrl &= ~(1 << TXC_MTDIABLO_CTRL_PMA_LOOP_LBN); + efx_mdio_write(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL, ctrl); + + return rc; +} + +static int txc_bist(struct efx_nic *efx) +{ + return txc_bist_one(efx, MDIO_MMD_PCS, TXC_BIST_CTRL_TYPE_TSD); +} + +/* Push the non-configurable defaults into the PHY. This must be + * done after every full reset */ +static void txc_apply_defaults(struct efx_nic *efx) +{ + int mctrl; + + /* Turn amplitude down and preemphasis off on the host side + * (PHY<->MAC) as this is believed less likely to upset Falcon + * and no adverse effects have been noted. It probably also + * saves a picowatt or two */ + + /* Turn off preemphasis */ + efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE0, TXC_ATXPRE_NONE); + efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_ALRGS_ATXPRE1, TXC_ATXPRE_NONE); + + /* Turn down the amplitude */ + efx_mdio_write(efx, MDIO_MMD_PHYXS, + TXC_ALRGS_ATXAMP0, TXC_ATXAMP_0820_BOTH); + efx_mdio_write(efx, MDIO_MMD_PHYXS, + TXC_ALRGS_ATXAMP1, TXC_ATXAMP_0820_BOTH); + + /* Set the line side amplitude and preemphasis to the databook + * defaults as an erratum causes them to be 0 on at least some + * PHY rev.s */ + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + TXC_ALRGS_ATXPRE0, TXC_ATXPRE_DEFAULT); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + TXC_ALRGS_ATXPRE1, TXC_ATXPRE_DEFAULT); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + TXC_ALRGS_ATXAMP0, TXC_ATXAMP_DEFAULT); + efx_mdio_write(efx, MDIO_MMD_PMAPMD, + TXC_ALRGS_ATXAMP1, TXC_ATXAMP_DEFAULT); + + /* Set up the LEDs */ + mctrl = efx_mdio_read(efx, MDIO_MMD_PHYXS, TXC_MRGS_CTL); + + /* Set the Green and Red LEDs to their default modes */ + mctrl &= ~((1 << TXC_MCTL_TXLED_LBN) | (1 << TXC_MCTL_RXLED_LBN)); + efx_mdio_write(efx, MDIO_MMD_PHYXS, TXC_MRGS_CTL, mctrl); + + /* Databook recommends doing this after configuration changes */ + txc_reset_logic(efx); + + falcon_board(efx)->type->init_phy(efx); +} + +static int txc43128_phy_probe(struct efx_nic *efx) +{ + struct txc43128_data *phy_data; + + /* Allocate phy private storage */ + phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); + if (!phy_data) + return -ENOMEM; + efx->phy_data = phy_data; + phy_data->phy_mode = efx->phy_mode; + + efx->mdio.mmds = TXC_REQUIRED_DEVS; + efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22; + + efx->loopback_modes = TXC_LOOPBACKS | FALCON_XMAC_LOOPBACKS; + + return 0; +} + +/* Initialisation entry point for this PHY driver */ +static int txc43128_phy_init(struct efx_nic *efx) +{ + int rc; + + rc = txc_reset_phy(efx); + if (rc < 0) + return rc; + + rc = txc_bist(efx); + if (rc < 0) + return rc; + + txc_apply_defaults(efx); + + return 0; +} + +/* Set the lane power down state in the global registers */ +static void txc_glrgs_lane_power(struct efx_nic *efx, int mmd) +{ + int pd = (1 << TXC_GLCMD_L01PD_LBN) | (1 << TXC_GLCMD_L23PD_LBN); + int ctl = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD); + + if (!(efx->phy_mode & PHY_MODE_LOW_POWER)) + ctl &= ~pd; + else + ctl |= pd; + + efx_mdio_write(efx, mmd, TXC_GLRGS_GLCMD, ctl); +} + +/* Set the lane power down state in the analog control registers */ +static void txc_analog_lane_power(struct efx_nic *efx, int mmd) +{ + int txpd = (1 << TXC_ATXCTL_TXPD3_LBN) | (1 << TXC_ATXCTL_TXPD2_LBN) + | (1 << TXC_ATXCTL_TXPD1_LBN) | (1 << TXC_ATXCTL_TXPD0_LBN); + int rxpd = (1 << TXC_ARXCTL_RXPD3_LBN) | (1 << TXC_ARXCTL_RXPD2_LBN) + | (1 << TXC_ARXCTL_RXPD1_LBN) | (1 << TXC_ARXCTL_RXPD0_LBN); + int txctl = efx_mdio_read(efx, mmd, TXC_ALRGS_ATXCTL); + int rxctl = efx_mdio_read(efx, mmd, TXC_ALRGS_ARXCTL); + + if (!(efx->phy_mode & PHY_MODE_LOW_POWER)) { + txctl &= ~txpd; + rxctl &= ~rxpd; + } else { + txctl |= txpd; + rxctl |= rxpd; + } + + efx_mdio_write(efx, mmd, TXC_ALRGS_ATXCTL, txctl); + efx_mdio_write(efx, mmd, TXC_ALRGS_ARXCTL, rxctl); +} + +static void txc_set_power(struct efx_nic *efx) +{ + /* According to the data book, all the MMDs can do low power */ + efx_mdio_set_mmds_lpower(efx, + !!(efx->phy_mode & PHY_MODE_LOW_POWER), + TXC_REQUIRED_DEVS); + + /* Global register bank is in PCS, PHY XS. These control the host + * side and line side settings respectively. */ + txc_glrgs_lane_power(efx, MDIO_MMD_PCS); + txc_glrgs_lane_power(efx, MDIO_MMD_PHYXS); + + /* Analog register bank in PMA/PMD, PHY XS */ + txc_analog_lane_power(efx, MDIO_MMD_PMAPMD); + txc_analog_lane_power(efx, MDIO_MMD_PHYXS); +} + +static void txc_reset_logic_mmd(struct efx_nic *efx, int mmd) +{ + int val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD); + int tries = 50; + + val |= (1 << TXC_GLCMD_LMTSWRST_LBN); + efx_mdio_write(efx, mmd, TXC_GLRGS_GLCMD, val); + while (tries--) { + val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD); + if (!(val & (1 << TXC_GLCMD_LMTSWRST_LBN))) + break; + udelay(1); + } + if (!tries) + netif_info(efx, hw, efx->net_dev, + TXCNAME " Logic reset timed out!\n"); +} + +/* Perform a logic reset. This preserves the configuration registers + * and is needed for some configuration changes to take effect */ +static void txc_reset_logic(struct efx_nic *efx) +{ + /* The data sheet claims we can do the logic reset on either the + * PCS or the PHYXS and the result is a reset of both host- and + * line-side logic. */ + txc_reset_logic_mmd(efx, MDIO_MMD_PCS); +} + +static bool txc43128_phy_read_link(struct efx_nic *efx) +{ + return efx_mdio_links_ok(efx, TXC_REQUIRED_DEVS); +} + +static int txc43128_phy_reconfigure(struct efx_nic *efx) +{ + struct txc43128_data *phy_data = efx->phy_data; + enum efx_phy_mode mode_change = efx->phy_mode ^ phy_data->phy_mode; + bool loop_change = LOOPBACK_CHANGED(phy_data, efx, TXC_LOOPBACKS); + + if (efx->phy_mode & mode_change & PHY_MODE_TX_DISABLED) { + txc_reset_phy(efx); + txc_apply_defaults(efx); + falcon_reset_xaui(efx); + mode_change &= ~PHY_MODE_TX_DISABLED; + } + + efx_mdio_transmit_disable(efx); + efx_mdio_phy_reconfigure(efx); + if (mode_change & PHY_MODE_LOW_POWER) + txc_set_power(efx); + + /* The data sheet claims this is required after every reconfiguration + * (note at end of 7.1), but we mustn't do it when nothing changes as + * it glitches the link, and reconfigure gets called on link change, + * so we get an IRQ storm on link up. */ + if (loop_change || mode_change) + txc_reset_logic(efx); + + phy_data->phy_mode = efx->phy_mode; + phy_data->loopback_mode = efx->loopback_mode; + + return 0; +} + +static void txc43128_phy_fini(struct efx_nic *efx) +{ + /* Disable link events */ + efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0); +} + +static void txc43128_phy_remove(struct efx_nic *efx) +{ + kfree(efx->phy_data); + efx->phy_data = NULL; +} + +/* Periodic callback: this exists mainly to poll link status as we + * don't use LASI interrupts */ +static bool txc43128_phy_poll(struct efx_nic *efx) +{ + struct txc43128_data *data = efx->phy_data; + bool was_up = efx->link_state.up; + + efx->link_state.up = txc43128_phy_read_link(efx); + efx->link_state.speed = 10000; + efx->link_state.fd = true; + efx->link_state.fc = efx->wanted_fc; + + if (efx->link_state.up || (efx->loopback_mode != LOOPBACK_NONE)) { + data->bug10934_timer = jiffies; + } else { + if (time_after_eq(jiffies, (data->bug10934_timer + + BUG10934_RESET_INTERVAL))) { + data->bug10934_timer = jiffies; + txc_reset_logic(efx); + } + } + + return efx->link_state.up != was_up; +} + +static const char *txc43128_test_names[] = { + "bist" +}; + +static const char *txc43128_test_name(struct efx_nic *efx, unsigned int index) +{ + if (index < ARRAY_SIZE(txc43128_test_names)) + return txc43128_test_names[index]; + return NULL; +} + +static int txc43128_run_tests(struct efx_nic *efx, int *results, unsigned flags) +{ + int rc; + + if (!(flags & ETH_TEST_FL_OFFLINE)) + return 0; + + rc = txc_reset_phy(efx); + if (rc < 0) + return rc; + + rc = txc_bist(efx); + txc_apply_defaults(efx); + results[0] = rc ? -1 : 1; + return rc; +} + +static void txc43128_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) +{ + mdio45_ethtool_gset(&efx->mdio, ecmd); +} + +struct efx_phy_operations falcon_txc_phy_ops = { + .probe = txc43128_phy_probe, + .init = txc43128_phy_init, + .reconfigure = txc43128_phy_reconfigure, + .poll = txc43128_phy_poll, + .fini = txc43128_phy_fini, + .remove = txc43128_phy_remove, + .get_settings = txc43128_get_settings, + .set_settings = efx_mdio_set_settings, + .test_alive = efx_mdio_test_alive, + .run_tests = txc43128_run_tests, + .test_name = txc43128_test_name, +}; diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index 782e45a613d606c9c8e615015f30fc3a06b1a4ec..e0d63083c3a866081c8fcea67760cca575a65dc7 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -19,9 +19,7 @@ #define EFX_WORKAROUND_FALCON_A(efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_A1) #define EFX_WORKAROUND_FALCON_AB(efx) (efx_nic_rev(efx) <= EFX_REV_FALCON_B0) #define EFX_WORKAROUND_SIENA(efx) (efx_nic_rev(efx) == EFX_REV_SIENA_A0) -#define EFX_WORKAROUND_10G(efx) EFX_IS10G(efx) -#define EFX_WORKAROUND_SFT9001(efx) ((efx)->phy_type == PHY_TYPE_SFT9001A || \ - (efx)->phy_type == PHY_TYPE_SFT9001B) +#define EFX_WORKAROUND_10G(efx) 1 /* XAUI resets if link not detected */ #define EFX_WORKAROUND_5147 EFX_WORKAROUND_ALWAYS @@ -58,9 +56,4 @@ /* Leak overlength packets rather than free */ #define EFX_WORKAROUND_8071 EFX_WORKAROUND_FALCON_A -/* Need to send XNP pages for 100BaseT */ -#define EFX_WORKAROUND_13204 EFX_WORKAROUND_SFT9001 -/* Don't restart AN in near-side loopback */ -#define EFX_WORKAROUND_15195 EFX_WORKAROUND_SFT9001 - #endif /* EFX_WORKAROUNDS_H */ diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 79fd02bc69fd0854f14e0fdac452980cd7fed74b..50259dfec5836772570d96f8bd402cd7a482a706 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -798,7 +798,7 @@ static int sh_eth_rx(struct net_device *ndev) skb->dev = ndev; sh_eth_set_receive_align(skb); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4)); } if (entry >= RX_RING_SIZE - 1) @@ -1031,7 +1031,7 @@ static int sh_eth_phy_init(struct net_device *ndev) mdp->duplex = -1; /* Try connect to PHY */ - phydev = phy_connect(ndev, phy_id, &sh_eth_adjust_link, + phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(phydev)) { dev_err(&ndev->dev, "phy_connect failed\n"); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index bbbded76ff14d28e561edeed2bfcfa6b91db7187..58183686709852ee431dba13cbe477138b94f55c 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -832,7 +832,7 @@ static u16 __devinit read_eeprom(long ioaddr, int location) outl(0, ee_addr); eeprom_delay(); - return (retval); + return retval; } /* Read and write the MII management registers using software-generated @@ -1042,7 +1042,7 @@ sis900_open(struct net_device *net_dev) init_timer(&sis_priv->timer); sis_priv->timer.expires = jiffies + HZ; sis_priv->timer.data = (unsigned long)net_dev; - sis_priv->timer.function = &sis900_timer; + sis_priv->timer.function = sis900_timer; add_timer(&sis_priv->timer); return 0; @@ -2247,9 +2247,9 @@ static inline u16 sis900_mcast_bitnr(u8 *addr, u8 revision) /* leave 8 or 7 most siginifant bits */ if ((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV)) - return ((int)(crc >> 24)); + return (int)(crc >> 24); else - return ((int)(crc >> 25)); + return (int)(crc >> 25); } /** diff --git a/drivers/net/skfp/cfm.c b/drivers/net/skfp/cfm.c index 5310d39b5737492da4aed57fc29f563750810d1e..e395ace3120b1e53ac36079ea9de015aed8f631b 100644 --- a/drivers/net/skfp/cfm.c +++ b/drivers/net/skfp/cfm.c @@ -542,8 +542,8 @@ static void cfm_fsm(struct s_smc *smc, int cmd) */ int cfm_get_mac_input(struct s_smc *smc) { - return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || - smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA) ; + return (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || + smc->mib.fddiSMTCF_State == SC5_THRU_B) ? PB : PA; } /* @@ -553,8 +553,8 @@ int cfm_get_mac_input(struct s_smc *smc) */ int cfm_get_mac_output(struct s_smc *smc) { - return((smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || - smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA) ; + return (smc->mib.fddiSMTCF_State == SC10_C_WRAP_B || + smc->mib.fddiSMTCF_State == SC4_THRU_A) ? PB : PA; } static char path_iso[] = { @@ -623,5 +623,5 @@ int cem_build_path(struct s_smc *smc, char *to, int path_index) LINT_USE(path_index); - return(len) ; + return len; } diff --git a/drivers/net/skfp/drvfbi.c b/drivers/net/skfp/drvfbi.c index c77cc14b322714937b3d39185fa32bc1dbb3c0e6..07da97c303d6893858ad661afcbdb4434c897787 100644 --- a/drivers/net/skfp/drvfbi.c +++ b/drivers/net/skfp/drvfbi.c @@ -267,7 +267,7 @@ void timer_irq(struct s_smc *smc) int pcm_get_s_port(struct s_smc *smc) { SK_UNUSED(smc) ; - return(PS) ; + return PS; } /* @@ -366,7 +366,7 @@ void sm_pm_bypass_req(struct s_smc *smc, int mode) */ int sm_pm_bypass_present(struct s_smc *smc) { - return( (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE: FALSE) ; + return (inp(ADDR(B0_DAS)) & DAS_BYP_ST) ? TRUE : FALSE; } void plc_clear_irq(struct s_smc *smc, int p) @@ -483,9 +483,9 @@ static int is_equal_num(char comp1[], char comp2[], int num) for (i = 0 ; i < num ; i++) { if (comp1[i] != comp2[i]) - return (0) ; + return 0; } - return (1) ; + return 1; } /* is_equal_num */ @@ -522,18 +522,18 @@ int set_oi_id_def(struct s_smc *smc) i++ ; break ; /* entry ok */ default: - return (1) ; /* invalid oi_status */ + return 1; /* invalid oi_status */ } } if (i == 0) - return (2) ; + return 2; if (!act_entries) - return (3) ; + return 3; /* ok, we have a valid OEM data base with an active entry */ smc->hw.oem_id = (struct s_oem_ids *) &oem_ids[sel_id] ; - return (0) ; + return 0; } #endif /* MULT_OEM */ diff --git a/drivers/net/skfp/ess.c b/drivers/net/skfp/ess.c index e8387d25f24acab7c0a47f1a50810e202232cce2..8639a0884f5c59cbda034120a7b1d5a68932c6df 100644 --- a/drivers/net/skfp/ess.c +++ b/drivers/net/skfp/ess.c @@ -135,7 +135,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (!(p = (void *) sm_to_para(smc,sm,SMT_P0015))) { DB_ESS("ESS: RAF frame error, parameter type not found\n",0,0) ; - return(fs) ; + return fs; } msg_res_type = ((struct smt_p_0015 *)p)->res_type ; @@ -147,7 +147,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, * error in frame: para ESS command was not found */ DB_ESS("ESS: RAF frame error, parameter command not found\n",0,0); - return(fs) ; + return fs; } DB_ESSN(2,"fc %x ft %x\n",sm->smt_class,sm->smt_type) ; @@ -175,12 +175,12 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, * local and no static allocation is used */ if (!local || smc->mib.fddiESSPayload) - return(fs) ; + return fs; p = (void *) sm_to_para(smc,sm,SMT_P0019) ; for (i = 0; i < 5; i++) { if (((struct smt_p_0019 *)p)->alloc_addr.a[i]) { - return(fs) ; + return fs; } } @@ -199,10 +199,10 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, sm->smt_dest = smt_sba_da ; if (smc->ess.local_sba_active) - return(fs | I_INDICATOR) ; + return fs | I_INDICATOR; if (!(db = smt_get_mbuf(smc))) - return(fs) ; + return fs; db->sm_len = mb->sm_len ; db->sm_off = mb->sm_off ; @@ -212,7 +212,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, (struct smt_header *)(db->sm_data+db->sm_off), "RAF") ; smt_send_frame(smc,db,FC_SMT_INFO,0) ; - return(fs) ; + return fs; } /* @@ -221,7 +221,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (smt_check_para(smc,sm,plist_raf_alc_res)) { DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ; - return(fs) ; + return fs; } /* @@ -242,7 +242,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, (sm->smt_tid != smc->ess.alloc_trans_id)) { DB_ESS("ESS: Allocation Responce not accepted\n",0,0) ; - return(fs) ; + return fs; } /* @@ -268,7 +268,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ (void)process_bw_alloc(smc,(long)payload,(long)overhead) ; - return(fs) ; + return fs; /* end of Process Allocation Request */ /* @@ -280,7 +280,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (sm->smt_type != SMT_REQUEST) { DB_ESS("ESS: Do not process Change Responses\n",0,0) ; - return(fs) ; + return fs; } /* @@ -288,7 +288,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (smt_check_para(smc,sm,plist_raf_chg_req)) { DB_ESS("ESS: RAF with para problem, ignoring\n",0,0) ; - return(fs) ; + return fs; } /* @@ -300,7 +300,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, if ((((struct smt_p_320b *)sm_to_para(smc,sm,SMT_P320B))->path_index != PRIMARY_RING) || (msg_res_type != SYNC_BW)) { DB_ESS("ESS: RAF frame with para problem, ignoring\n",0,0) ; - return(fs) ; + return fs; } /* @@ -319,14 +319,14 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, * process the bandwidth allocation */ if(!process_bw_alloc(smc,(long)payload,(long)overhead)) - return(fs) ; + return fs; /* * send an RAF Change Reply */ ess_send_response(smc,sm,CHANGE_ALLOCATION) ; - return(fs) ; + return fs; /* end of Process Change Request */ /* @@ -338,7 +338,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (sm->smt_type != SMT_REQUEST) { DB_ESS("ESS: Do not process a Report Reply\n",0,0) ; - return(fs) ; + return fs; } DB_ESSN(2,"ESS: Report Request from %s\n", @@ -349,7 +349,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ if (msg_res_type != SYNC_BW) { DB_ESS("ESS: ignoring RAF with para problem\n",0,0) ; - return(fs) ; + return fs; } /* @@ -357,7 +357,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, */ ess_send_response(smc,sm,REPORT_ALLOCATION) ; - return(fs) ; + return fs; /* end of Process Report Request */ default: @@ -368,7 +368,7 @@ int ess_raf_received_pack(struct s_smc *smc, SMbuf *mb, struct smt_header *sm, break ; } - return(fs) ; + return fs; } /* @@ -418,17 +418,17 @@ static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhe */ /* if (smt_set_obj(smc,SMT_P320F,payload,S_SET)) { DB_ESS("ESS: SMT does not accept the payload value\n",0,0) ; - return(FALSE) ; + return FALSE; } if (smt_set_obj(smc,SMT_P3210,overhead,S_SET)) { DB_ESS("ESS: SMT does not accept the overhead value\n",0,0) ; - return(FALSE) ; + return FALSE; } */ /* premliminary */ if (payload > MAX_PAYLOAD || overhead > 5000) { DB_ESS("ESS: payload / overhead not accepted\n",0,0) ; - return(FALSE) ; + return FALSE; } /* @@ -468,7 +468,7 @@ static int process_bw_alloc(struct s_smc *smc, long int payload, long int overhe ess_config_fifo(smc) ; set_formac_tsync(smc,smc->ess.sync_bw) ; - return(TRUE) ; + return TRUE; } static void ess_send_response(struct s_smc *smc, struct smt_header *sm, diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c index 9d8d1ac48176dfc1558de9f944cb6bf6cadee26a..ca4e7bb6a5a8a0f592778821bf722c1d25803cfa 100644 --- a/drivers/net/skfp/fplustm.c +++ b/drivers/net/skfp/fplustm.c @@ -112,8 +112,8 @@ static u_long mac_get_tneg(struct s_smc *smc) u_long tneg ; tneg = (u_long)((long)inpw(FM_A(FM_TNEG))<<5) ; - return((u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) | - 0xffe00000L)) ; + return (u_long)((tneg + ((inpw(FM_A(FM_TMRS))>>10)&0x1f)) | + 0xffe00000L) ; } void mac_update_counter(struct s_smc *smc) @@ -163,7 +163,7 @@ static u_long read_mdr(struct s_smc *smc, unsigned int addr) /* is used */ p = (u_long)inpw(FM_A(FM_MDRU))<<16 ; p += (u_long)inpw(FM_A(FM_MDRL)) ; - return(p) ; + return p; } #endif @@ -887,7 +887,7 @@ int init_fplus(struct s_smc *smc) /* make sure all PCI settings are correct */ mac_do_pci_fix(smc) ; - return(init_mac(smc,1)) ; + return init_mac(smc, 1); /* enable_formac(smc) ; */ } @@ -989,7 +989,7 @@ static int init_mac(struct s_smc *smc, int all) } smc->hw.hw_state = STARTED ; - return(0) ; + return 0; } @@ -1049,7 +1049,7 @@ void sm_ma_control(struct s_smc *smc, int mode) int sm_mac_get_tx_state(struct s_smc *smc) { - return((inpw(FM_A(FM_STMCHN))>>4)&7) ; + return (inpw(FM_A(FM_STMCHN))>>4) & 7; } /* @@ -1084,9 +1084,9 @@ static struct s_fpmc* mac_get_mc_table(struct s_smc *smc, } if (memcmp((char *)&tb->a,(char *)own,6)) continue ; - return(tb) ; + return tb; } - return(slot) ; /* return first free or NULL */ + return slot; /* return first free or NULL */ } /* @@ -1152,12 +1152,12 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can) */ if (can & 0x80) { if (smc->hw.fp.smt_slots_used >= SMT_MAX_MULTI) { - return(1) ; + return 1; } } else { if (smc->hw.fp.os_slots_used >= FPMAX_MULTICAST-SMT_MAX_MULTI) { - return(1) ; + return 1; } } @@ -1165,7 +1165,7 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can) * find empty slot */ if (!(tb = mac_get_mc_table(smc,addr,&own,0,can & ~0x80))) - return(1) ; + return 1; tb->n++ ; tb->a = own ; tb->perm = (can & 0x80) ? 1 : 0 ; @@ -1175,7 +1175,7 @@ int mac_add_multicast(struct s_smc *smc, struct fddi_addr *addr, int can) else smc->hw.fp.os_slots_used++ ; - return(0) ; + return 0; } /* diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c index d322f1b702ac52ae1e3d8aa6ff8944155d8dab20..af5a755e269de6077c14310d04502ccd526b4dad 100644 --- a/drivers/net/skfp/hwmtm.c +++ b/drivers/net/skfp/hwmtm.c @@ -232,16 +232,16 @@ u_int mac_drv_check_space(void) #ifdef COMMON_MB_POOL call_count++ ; if (call_count == 1) { - return(EXT_VIRT_MEM) ; + return EXT_VIRT_MEM; } else { - return(EXT_VIRT_MEM_2) ; + return EXT_VIRT_MEM_2; } #else - return (EXT_VIRT_MEM) ; + return EXT_VIRT_MEM; #endif #else - return (0) ; + return 0; #endif } @@ -271,7 +271,7 @@ int mac_drv_init(struct s_smc *smc) if (!(smc->os.hwm.descr_p = (union s_fp_descr volatile *) mac_drv_get_desc_mem(smc,(u_int) (RXD_TXD_COUNT+1)*sizeof(struct s_smt_fp_txd)))) { - return(1) ; /* no space the hwm modul can't work */ + return 1; /* no space the hwm modul can't work */ } /* @@ -283,18 +283,18 @@ int mac_drv_init(struct s_smc *smc) #ifndef COMMON_MB_POOL if (!(smc->os.hwm.mbuf_pool.mb_start = (SMbuf *) mac_drv_get_space(smc, MAX_MBUF*sizeof(SMbuf)))) { - return(1) ; /* no space the hwm modul can't work */ + return 1; /* no space the hwm modul can't work */ } #else if (!mb_start) { if (!(mb_start = (SMbuf *) mac_drv_get_space(smc, MAX_MBUF*sizeof(SMbuf)))) { - return(1) ; /* no space the hwm modul can't work */ + return 1; /* no space the hwm modul can't work */ } } #endif #endif - return (0) ; + return 0; } /* @@ -349,7 +349,7 @@ static u_long init_descr_ring(struct s_smc *smc, DRV_BUF_FLUSH(&d1->r,DDI_DMA_SYNC_FORDEV) ; d1++; } - return(phys) ; + return phys; } static void init_txd_ring(struct s_smc *smc) @@ -502,7 +502,7 @@ SMbuf *smt_get_mbuf(struct s_smc *smc) mb->sm_use_count = 1 ; } DB_GEN("get SMbuf: mb = %x",(void *)mb,0,3) ; - return (mb) ; /* May be NULL */ + return mb; /* May be NULL */ } void smt_free_mbuf(struct s_smc *smc, SMbuf *mb) @@ -621,7 +621,7 @@ static u_long repair_txd_ring(struct s_smc *smc, struct s_smt_tx_queue *queue) t = t->txd_next ; tx_used-- ; } - return(phys) ; + return phys; } /* @@ -673,7 +673,7 @@ static u_long repair_rxd_ring(struct s_smc *smc, struct s_smt_rx_queue *queue) r = r->rxd_next ; rx_used-- ; } - return(phys) ; + return phys; } @@ -1595,7 +1595,7 @@ int hwm_tx_init(struct s_smc *smc, u_char fc, int frag_count, int frame_len, } DB_TX("frame_status = %x",frame_status,0,3) ; NDD_TRACE("THiE",frame_status,smc->os.hwm.tx_p->tx_free,0) ; - return(frame_status) ; + return frame_status; } /* @@ -1764,7 +1764,7 @@ static SMbuf *get_llc_rx(struct s_smc *smc) smc->os.hwm.llc_rx_pipe = mb->sm_next ; } DB_GEN("get_llc_rx: mb = 0x%x",(void *)mb,0,4) ; - return(mb) ; + return mb; } /* @@ -1797,7 +1797,7 @@ static SMbuf *get_txd_mb(struct s_smc *smc) smc->os.hwm.txd_tx_pipe = mb->sm_next ; } DB_GEN("get_txd_mb: mb = 0x%x",(void *)mb,0,4) ; - return(mb) ; + return mb; } /* diff --git a/drivers/net/skfp/hwt.c b/drivers/net/skfp/hwt.c index 053151468f93af7947d0bc9dc3da41a409a3971f..e6baa53307c7aa5ddc74641fd0733809963526fd 100644 --- a/drivers/net/skfp/hwt.c +++ b/drivers/net/skfp/hwt.c @@ -179,7 +179,7 @@ u_long hwt_read(struct s_smc *smc) else smc->hw.t_stop = smc->hw.t_start - tr ; } - return (smc->hw.t_stop) ; + return smc->hw.t_stop; } #ifdef PCI @@ -208,7 +208,7 @@ u_long hwt_quick_read(struct s_smc *smc) outpw(ADDR(B2_TI_CRTL), TIM_START) ; outpd(ADDR(B2_TI_INI),interval) ; - return(time) ; + return time; } /************************ diff --git a/drivers/net/skfp/pcmplc.c b/drivers/net/skfp/pcmplc.c index ba45bc794d774d76c6c110572137ee81958062d8..112d35b1bf0ebc5f6b2b082c46d373dbaf7b6716 100644 --- a/drivers/net/skfp/pcmplc.c +++ b/drivers/net/skfp/pcmplc.c @@ -504,7 +504,7 @@ int sm_pm_get_ls(struct s_smc *smc, int phy) #ifdef CONCENTRATOR if (!plc_is_installed(smc,phy)) - return(PC_QLS) ; + return PC_QLS; #endif state = inpw(PLC(phy,PL_STATUS_A)) & PL_LINE_ST ; @@ -528,7 +528,7 @@ int sm_pm_get_ls(struct s_smc *smc, int phy) default : state = PC_LS_NONE ; } - return(state) ; + return state; } static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len) @@ -547,7 +547,7 @@ static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len) #if 0 printf("PL_PCM_SIGNAL is set\n") ; #endif - return(1) ; + return 1; } /* write bit[n] & length = 1 to regs */ outpw(PLC(np,PL_VECTOR_LEN),len-1) ; /* len=nr-1 */ @@ -562,7 +562,7 @@ static int plc_send_bits(struct s_smc *smc, struct s_phy *phy, int len) printf("SIGNALING bit %d .. %d\n",phy->bitn,phy->bitn+len-1) ; #endif #endif - return(0) ; + return 0; } /* @@ -1590,12 +1590,12 @@ int pcm_status_twisted(struct s_smc *smc) { int twist = 0 ; if (smc->s.sas != SMT_DAS) - return(0) ; + return 0; if (smc->y[PA].twisted && (smc->y[PA].mib->fddiPORTPCMState == PC8_ACTIVE)) twist |= 1 ; if (smc->y[PB].twisted && (smc->y[PB].mib->fddiPORTPCMState == PC8_ACTIVE)) twist |= 2 ; - return(twist) ; + return twist; } /* @@ -1636,9 +1636,9 @@ int pcm_rooted_station(struct s_smc *smc) for (n = 0 ; n < NUMPHYS ; n++) { if (smc->y[n].mib->fddiPORTPCMState == PC8_ACTIVE && smc->y[n].mib->fddiPORTNeighborType == TM) - return(0) ; + return 0; } - return(1) ; + return 1; } /* @@ -1915,7 +1915,7 @@ int get_pcm_state(struct s_smc *smc, int np) case PL_PC9 : pcs = PC_MAINT ; break ; default : pcs = PC_DISABLE ; break ; } - return(pcs) ; + return pcs; } char *get_linestate(struct s_smc *smc, int np) @@ -1937,7 +1937,7 @@ char *get_linestate(struct s_smc *smc, int np) default: ls = "unknown" ; break ; #endif } - return(ls) ; + return ls; } char *get_pcmstate(struct s_smc *smc, int np) @@ -1959,7 +1959,7 @@ char *get_pcmstate(struct s_smc *smc, int np) case PL_PC9 : pcs = "MAINT" ; break ; default : pcs = "UNKNOWN" ; break ; } - return(pcs) ; + return pcs; } void list_phy(struct s_smc *smc) diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c index a320fdb3727ded529bd95833c32b50182bccfff6..9ac4665d7411323e4dd2f7514b1f000e7755770c 100644 --- a/drivers/net/skfp/pmf.c +++ b/drivers/net/skfp/pmf.c @@ -328,7 +328,7 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, * build SMT header */ if (!(mb = smt_get_mbuf(smc))) - return(mb) ; + return mb; smt = smtod(mb, struct smt_header *) ; smt->smt_dest = req->smt_source ; /* DA == source of request */ @@ -493,7 +493,7 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, smt_add_para(smc,&set_pcon,(u_short) SMT_P1035,0,0) ; smt_add_para(smc,&set_pcon,(u_short) SMT_P1036,0,0) ; } - return(mb) ; + return mb; } static int smt_authorize(struct s_smc *smc, struct smt_header *sm) @@ -511,7 +511,7 @@ static int smt_authorize(struct s_smc *smc, struct smt_header *sm) if (i != 8) { if (memcmp((char *) &sm->smt_sid, (char *) &smc->mib.fddiPRPMFStation,8)) - return(1) ; + return 1; } /* * check authoriziation parameter if passwd not zero @@ -522,13 +522,13 @@ static int smt_authorize(struct s_smc *smc, struct smt_header *sm) if (i != 8) { pa = (struct smt_para *) sm_to_para(smc,sm,SMT_P_AUTHOR) ; if (!pa) - return(1) ; + return 1; if (pa->p_len != 8) - return(1) ; + return 1; if (memcmp((char *)(pa+1),(char *)smc->mib.fddiPRPMFPasswd,8)) - return(1) ; + return 1; } - return(0) ; + return 0; } static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm) @@ -542,9 +542,9 @@ static int smt_check_set_count(struct s_smc *smc, struct smt_header *sm) if ((smc->mib.fddiSMTSetCount.count != sc->count) || memcmp((char *) smc->mib.fddiSMTSetCount.timestamp, (char *)sc->timestamp,8)) - return(1) ; + return 1; } - return(0) ; + return 0; } void smt_add_para(struct s_smc *smc, struct s_pcon *pcon, u_short para, @@ -1109,7 +1109,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, break ; case 0x2000 : if (mac < 0 || mac >= NUMMACS) { - return(SMT_RDF_NOPARAM) ; + return SMT_RDF_NOPARAM; } mib_m = &smc->mib.m[mac] ; mib_addr = (char *) mib_m ; @@ -1118,7 +1118,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, break ; case 0x3000 : if (path < 0 || path >= NUMPATHS) { - return(SMT_RDF_NOPARAM) ; + return SMT_RDF_NOPARAM; } mib_a = &smc->mib.a[path] ; mib_addr = (char *) mib_a ; @@ -1127,7 +1127,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, break ; case 0x4000 : if (port < 0 || port >= smt_mib_phys(smc)) { - return(SMT_RDF_NOPARAM) ; + return SMT_RDF_NOPARAM; } mib_p = &smc->mib.p[port_to_mib(smc,port)] ; mib_addr = (char *) mib_p ; @@ -1151,22 +1151,20 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, case SMT_P10F9 : #endif case SMT_P20F1 : - if (!local) { - return(SMT_RDF_NOPARAM) ; - } + if (!local) + return SMT_RDF_NOPARAM; break ; } pt = smt_get_ptab(pa->p_type) ; - if (!pt) { - return( (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM : - SMT_RDF_ILLEGAL ) ; - } + if (!pt) + return (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM : + SMT_RDF_ILLEGAL; switch (pt->p_access) { case AC_GR : case AC_S : break ; default : - return(SMT_RDF_ILLEGAL) ; + return SMT_RDF_ILLEGAL; } to = mib_addr + pt->p_offset ; swap = pt->p_swap ; /* pointer to swap string */ @@ -1292,7 +1290,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, break ; default : SMT_PANIC(smc,SMT_E0120, SMT_E0120_MSG) ; - return(SMT_RDF_ILLEGAL) ; + return SMT_RDF_ILLEGAL; } } /* @@ -1501,15 +1499,15 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, default : break ; } - return(0) ; + return 0; val_error: /* parameter value in frame is out of range */ - return(SMT_RDF_RANGE) ; + return SMT_RDF_RANGE; len_error: /* parameter value in frame is too short */ - return(SMT_RDF_LENGTH) ; + return SMT_RDF_LENGTH; #if 0 no_author_error: @@ -1518,7 +1516,7 @@ static int smt_set_para(struct s_smc *smc, struct smt_para *pa, int index, * because SBA denied is not a valid return code in the * PMF protocol. */ - return(SMT_RDF_AUTHOR) ; + return SMT_RDF_AUTHOR; #endif } @@ -1527,7 +1525,7 @@ static const struct s_p_tab *smt_get_ptab(u_short para) const struct s_p_tab *pt ; for (pt = p_tab ; pt->p_num && pt->p_num != para ; pt++) ; - return(pt->p_num ? pt : NULL) ; + return pt->p_num ? pt : NULL; } static int smt_mib_phys(struct s_smc *smc) @@ -1535,11 +1533,11 @@ static int smt_mib_phys(struct s_smc *smc) #ifdef CONCENTRATOR SK_UNUSED(smc) ; - return(NUMPHYS) ; + return NUMPHYS; #else if (smc->s.sas == SMT_SAS) - return(1) ; - return(NUMPHYS) ; + return 1; + return NUMPHYS; #endif } @@ -1548,11 +1546,11 @@ static int port_to_mib(struct s_smc *smc, int p) #ifdef CONCENTRATOR SK_UNUSED(smc) ; - return(p) ; + return p; #else if (smc->s.sas == SMT_SAS) - return(PS) ; - return(p) ; + return PS; + return p; #endif } diff --git a/drivers/net/skfp/queue.c b/drivers/net/skfp/queue.c index 09adb3d68b7cdab6d0598f4cd31625ee8f072d4d..c1a0df455a5958089bc4bae4c6dcfe8b9539042b 100644 --- a/drivers/net/skfp/queue.c +++ b/drivers/net/skfp/queue.c @@ -128,7 +128,7 @@ u_short smt_online(struct s_smc *smc, int on) { queue_event(smc,EVENT_ECM,on ? EC_CONNECT : EC_DISCONNECT) ; ev_dispatcher(smc) ; - return(smc->mib.fddiSMTCF_State) ; + return smc->mib.fddiSMTCF_State; } /* diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 31b2dabf094cdbce1a9ace31b1657d28e5a459ac..ba2e8339fe90fa4fdbf0478c90c5e28e20ff63f2 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c @@ -209,7 +209,7 @@ static int skfp_init_one(struct pci_dev *pdev, void __iomem *mem; int err; - pr_debug(KERN_INFO "entering skfp_init_one\n"); + pr_debug("entering skfp_init_one\n"); if (num_boards == 0) printk("%s\n", boot_msg); @@ -385,7 +385,7 @@ static int skfp_driver_init(struct net_device *dev) skfddi_priv *bp = &smc->os; int err = -EIO; - pr_debug(KERN_INFO "entering skfp_driver_init\n"); + pr_debug("entering skfp_driver_init\n"); // set the io address in private structures bp->base_addr = dev->base_addr; @@ -405,7 +405,7 @@ static int skfp_driver_init(struct net_device *dev) // Determine the required size of the 'shared' memory area. bp->SharedMemSize = mac_drv_check_space(); - pr_debug(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize); + pr_debug("Memory for HWM: %ld\n", bp->SharedMemSize); if (bp->SharedMemSize > 0) { bp->SharedMemSize += 16; // for descriptor alignment @@ -429,18 +429,18 @@ static int skfp_driver_init(struct net_device *dev) card_stop(smc); // Reset adapter. - pr_debug(KERN_INFO "mac_drv_init()..\n"); + pr_debug("mac_drv_init()..\n"); if (mac_drv_init(smc) != 0) { - pr_debug(KERN_INFO "mac_drv_init() failed.\n"); + pr_debug("mac_drv_init() failed\n"); goto fail; } read_address(smc, NULL); - pr_debug(KERN_INFO "HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a); + pr_debug("HW-Addr: %pMF\n", smc->hw.fddi_canon_addr.a); memcpy(dev->dev_addr, smc->hw.fddi_canon_addr.a, 6); smt_reset_defaults(smc, 0); - return (0); + return 0; fail: if (bp->SharedMemAddr) { @@ -485,7 +485,7 @@ static int skfp_open(struct net_device *dev) struct s_smc *smc = netdev_priv(dev); int err; - pr_debug(KERN_INFO "entering skfp_open\n"); + pr_debug("entering skfp_open\n"); /* Register IRQ - support shared interrupts by passing device ptr */ err = request_irq(dev->irq, skfp_interrupt, IRQF_SHARED, dev->name, dev); @@ -516,7 +516,7 @@ static int skfp_open(struct net_device *dev) mac_drv_rx_mode(smc, RX_DISABLE_PROMISC); netif_start_queue(dev); - return (0); + return 0; } // skfp_open @@ -565,7 +565,7 @@ static int skfp_close(struct net_device *dev) skb_queue_purge(&bp->SendSkbQueue); bp->QueueSkb = MAX_TX_QUEUE_LEN; - return (0); + return 0; } // skfp_close @@ -794,7 +794,7 @@ static struct net_device_stats *skfp_ctl_get_stats(struct net_device *dev) bp->stats.port_lem_cts[1] = bp->cmd_rsp_virt->cntrs_get.cntrs.link_errors[1].ls; #endif - return ((struct net_device_stats *) &bp->os.MacStat); + return (struct net_device_stats *)&bp->os.MacStat; } // ctl_get_stat @@ -856,12 +856,12 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev) /* Enable promiscuous mode, if necessary */ if (dev->flags & IFF_PROMISC) { mac_drv_rx_mode(smc, RX_ENABLE_PROMISC); - pr_debug(KERN_INFO "PROMISCUOUS MODE ENABLED\n"); + pr_debug("PROMISCUOUS MODE ENABLED\n"); } /* Else, update multicast address table */ else { mac_drv_rx_mode(smc, RX_DISABLE_PROMISC); - pr_debug(KERN_INFO "PROMISCUOUS MODE DISABLED\n"); + pr_debug("PROMISCUOUS MODE DISABLED\n"); // Reset all MC addresses mac_clear_multicast(smc); @@ -869,7 +869,7 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev) if (dev->flags & IFF_ALLMULTI) { mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI); - pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n"); + pr_debug("ENABLE ALL MC ADDRESSES\n"); } else if (!netdev_mc_empty(dev)) { if (netdev_mc_count(dev) <= FPMAX_MULTICAST) { /* use exact filtering */ @@ -880,18 +880,18 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev) (struct fddi_addr *)ha->addr, 1); - pr_debug(KERN_INFO "ENABLE MC ADDRESS: %pMF\n", - ha->addr); + pr_debug("ENABLE MC ADDRESS: %pMF\n", + ha->addr); } } else { // more MC addresses than HW supports mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI); - pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n"); + pr_debug("ENABLE ALL MC ADDRESSES\n"); } } else { // no MC addresses - pr_debug(KERN_INFO "DISABLE ALL MC ADDRESSES\n"); + pr_debug("DISABLE ALL MC ADDRESSES\n"); } /* Update adapter filters */ @@ -932,7 +932,7 @@ static int skfp_ctl_set_mac_address(struct net_device *dev, void *addr) ResetAdapter(smc); spin_unlock_irqrestore(&bp->DriverLock, Flags); - return (0); /* always return zero */ + return 0; /* always return zero */ } // skfp_ctl_set_mac_address @@ -1045,7 +1045,7 @@ static netdev_tx_t skfp_send_pkt(struct sk_buff *skb, struct s_smc *smc = netdev_priv(dev); skfddi_priv *bp = &smc->os; - pr_debug(KERN_INFO "skfp_send_pkt\n"); + pr_debug("skfp_send_pkt\n"); /* * Verify that incoming transmit request is OK @@ -1114,13 +1114,13 @@ static void send_queued_packets(struct s_smc *smc) int frame_status; // HWM tx frame status. - pr_debug(KERN_INFO "send queued packets\n"); + pr_debug("send queued packets\n"); for (;;) { // send first buffer from queue skb = skb_dequeue(&bp->SendSkbQueue); if (!skb) { - pr_debug(KERN_INFO "queue empty\n"); + pr_debug("queue empty\n"); return; } // queue empty ! @@ -1232,7 +1232,7 @@ static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr) static void ResetAdapter(struct s_smc *smc) { - pr_debug(KERN_INFO "[fddi: ResetAdapter]\n"); + pr_debug("[fddi: ResetAdapter]\n"); // Stop the adapter. @@ -1278,7 +1278,7 @@ void llc_restart_tx(struct s_smc *smc) { skfddi_priv *bp = &smc->os; - pr_debug(KERN_INFO "[llc_restart_tx]\n"); + pr_debug("[llc_restart_tx]\n"); // Try to send queued packets spin_unlock(&bp->DriverLock); @@ -1308,21 +1308,21 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size) { void *virt; - pr_debug(KERN_INFO "mac_drv_get_space (%d bytes), ", size); + pr_debug("mac_drv_get_space (%d bytes), ", size); virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap); if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) { printk("Unexpected SMT memory size requested: %d\n", size); - return (NULL); + return NULL; } smc->os.SharedMemHeap += size; // Move heap pointer. - pr_debug(KERN_INFO "mac_drv_get_space end\n"); - pr_debug(KERN_INFO "virt addr: %lx\n", (ulong) virt); - pr_debug(KERN_INFO "bus addr: %lx\n", (ulong) + pr_debug("mac_drv_get_space end\n"); + pr_debug("virt addr: %lx\n", (ulong) virt); + pr_debug("bus addr: %lx\n", (ulong) (smc->os.SharedMemDMA + ((char *) virt - (char *)smc->os.SharedMemAddr))); - return (virt); + return virt; } // mac_drv_get_space @@ -1349,7 +1349,7 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size) char *virt; - pr_debug(KERN_INFO "mac_drv_get_desc_mem\n"); + pr_debug("mac_drv_get_desc_mem\n"); // Descriptor memory must be aligned on 16-byte boundary. @@ -1363,9 +1363,9 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size) if (!mac_drv_get_space(smc, size)) { printk("fddi: Unable to align descriptor memory.\n"); - return (NULL); + return NULL; } - return (virt + size); + return virt + size; } // mac_drv_get_desc_mem @@ -1384,8 +1384,8 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size) ************************/ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt) { - return (smc->os.SharedMemDMA + - ((char *) virt - (char *)smc->os.SharedMemAddr)); + return smc->os.SharedMemDMA + + ((char *) virt - (char *)smc->os.SharedMemAddr); } // mac_drv_virt2phys @@ -1419,8 +1419,8 @@ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt) ************************/ u_long dma_master(struct s_smc * smc, void *virt, int len, int flag) { - return (smc->os.SharedMemDMA + - ((char *) virt - (char *)smc->os.SharedMemAddr)); + return smc->os.SharedMemDMA + + ((char *) virt - (char *)smc->os.SharedMemAddr); } // dma_master @@ -1493,7 +1493,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd) { struct sk_buff *skb; - pr_debug(KERN_INFO "entering mac_drv_tx_complete\n"); + pr_debug("entering mac_drv_tx_complete\n"); // Check if this TxD points to a skb if (!(skb = txd->txd_os.skb)) { @@ -1513,7 +1513,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd) // free the skb dev_kfree_skb_irq(skb); - pr_debug(KERN_INFO "leaving mac_drv_tx_complete\n"); + pr_debug("leaving mac_drv_tx_complete\n"); } // mac_drv_tx_complete @@ -1580,7 +1580,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, unsigned short ri; u_int RifLength; - pr_debug(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len); + pr_debug("entering mac_drv_rx_complete (len=%d)\n", len); if (frag_count != 1) { // This is not allowed to happen. printk("fddi: Multi-fragment receive!\n"); @@ -1589,7 +1589,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, } skb = rxd->rxd_os.skb; if (!skb) { - pr_debug(KERN_INFO "No skb in rxd\n"); + pr_debug("No skb in rxd\n"); smc->os.MacStat.gen.rx_errors++; goto RequeueRxd; } @@ -1619,7 +1619,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, else { int n; // goos: RIF removal has still to be tested - pr_debug(KERN_INFO "RIF found\n"); + pr_debug("RIF found\n"); // Get RIF length from Routing Control (RC) field. cp = virt + FDDI_MAC_HDR_LEN; // Point behind MAC header. @@ -1664,7 +1664,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd, return; RequeueRxd: - pr_debug(KERN_INFO "Rx: re-queue RXD.\n"); + pr_debug("Rx: re-queue RXD.\n"); mac_drv_requeue_rxd(smc, rxd, frag_count); smc->os.MacStat.gen.rx_errors++; // Count receive packets // not indicated. @@ -1775,7 +1775,7 @@ void mac_drv_fill_rxd(struct s_smc *smc) struct sk_buff *skb; volatile struct s_smt_fp_rxd *rxd; - pr_debug(KERN_INFO "entering mac_drv_fill_rxd\n"); + pr_debug("entering mac_drv_fill_rxd\n"); // Walk through the list of free receive buffers, passing receive // buffers to the HWM as long as RXDs are available. @@ -1783,7 +1783,7 @@ void mac_drv_fill_rxd(struct s_smc *smc) MaxFrameSize = smc->os.MaxFrameSize; // Check if there is any RXD left. while (HWM_GET_RX_FREE(smc) > 0) { - pr_debug(KERN_INFO ".\n"); + pr_debug(".\n"); rxd = HWM_GET_CURR_RXD(smc); skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC); @@ -1814,7 +1814,7 @@ void mac_drv_fill_rxd(struct s_smc *smc) hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize, FIRST_FRAG | LAST_FRAG); } - pr_debug(KERN_INFO "leaving mac_drv_fill_rxd\n"); + pr_debug("leaving mac_drv_fill_rxd\n"); } // mac_drv_fill_rxd @@ -1904,12 +1904,12 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc, pr_debug("fddi: Discard invalid local SMT frame\n"); pr_debug(" len=%d, la_len=%d, (ULONG) look_ahead=%08lXh.\n", len, la_len, (unsigned long) look_ahead); - return (0); + return 0; } skb = alloc_skb(len + 3, GFP_ATOMIC); if (!skb) { pr_debug("fddi: Local SMT: skb memory exhausted.\n"); - return (0); + return 0; } skb_reserve(skb, 3); skb_put(skb, len); @@ -1919,7 +1919,7 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc, skb->protocol = fddi_type_trans(skb, smc->os.dev); netif_rx(skb); - return (0); + return 0; } // mac_drv_rx_init @@ -2034,17 +2034,17 @@ void smt_stat_counter(struct s_smc *smc, int stat) { // BOOLEAN RingIsUp ; - pr_debug(KERN_INFO "smt_stat_counter\n"); + pr_debug("smt_stat_counter\n"); switch (stat) { case 0: - pr_debug(KERN_INFO "Ring operational change.\n"); + pr_debug("Ring operational change.\n"); break; case 1: - pr_debug(KERN_INFO "Receive fifo overflow.\n"); + pr_debug("Receive fifo overflow.\n"); smc->os.MacStat.gen.rx_errors++; break; default: - pr_debug(KERN_INFO "Unknown status (%d).\n", stat); + pr_debug("Unknown status (%d).\n", stat); break; } } // smt_stat_counter @@ -2100,10 +2100,10 @@ void cfm_state_change(struct s_smc *smc, int c_state) s = "SC11_C_WRAP_S"; break; default: - pr_debug(KERN_INFO "cfm_state_change: unknown %d\n", c_state); + pr_debug("cfm_state_change: unknown %d\n", c_state); return; } - pr_debug(KERN_INFO "cfm_state_change: %s\n", s); + pr_debug("cfm_state_change: %s\n", s); #endif // DRIVERDEBUG } // cfm_state_change @@ -2158,7 +2158,7 @@ void ecm_state_change(struct s_smc *smc, int e_state) s = "unknown"; break; } - pr_debug(KERN_INFO "ecm_state_change: %s\n", s); + pr_debug("ecm_state_change: %s\n", s); #endif //DRIVERDEBUG } // ecm_state_change @@ -2213,7 +2213,7 @@ void rmt_state_change(struct s_smc *smc, int r_state) s = "unknown"; break; } - pr_debug(KERN_INFO "[rmt_state_change: %s]\n", s); + pr_debug("[rmt_state_change: %s]\n", s); #endif // DRIVERDEBUG } // rmt_state_change @@ -2233,7 +2233,7 @@ void rmt_state_change(struct s_smc *smc, int r_state) ************************/ void drv_reset_indication(struct s_smc *smc) { - pr_debug(KERN_INFO "entering drv_reset_indication\n"); + pr_debug("entering drv_reset_indication\n"); smc->os.ResetRequested = TRUE; // Set flag. diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c index 6f35bb77595f2ffab9cdb939f75a95efb8d0a27b..2d9941c045bc152469f61acbf7db8762bbbc74b3 100644 --- a/drivers/net/skfp/smt.c +++ b/drivers/net/skfp/smt.c @@ -127,22 +127,22 @@ static inline int is_my_addr(const struct s_smc *smc, static inline int is_broadcast(const struct fddi_addr *addr) { - return(*(u_short *)(&addr->a[0]) == 0xffff && + return *(u_short *)(&addr->a[0]) == 0xffff && *(u_short *)(&addr->a[2]) == 0xffff && - *(u_short *)(&addr->a[4]) == 0xffff ) ; + *(u_short *)(&addr->a[4]) == 0xffff; } static inline int is_individual(const struct fddi_addr *addr) { - return(!(addr->a[0] & GROUP_ADDR)) ; + return !(addr->a[0] & GROUP_ADDR); } static inline int is_equal(const struct fddi_addr *addr1, const struct fddi_addr *addr2) { - return(*(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) && + return *(u_short *)(&addr1->a[0]) == *(u_short *)(&addr2->a[0]) && *(u_short *)(&addr1->a[2]) == *(u_short *)(&addr2->a[2]) && - *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]) ) ; + *(u_short *)(&addr1->a[4]) == *(u_short *)(&addr2->a[4]); } /* @@ -457,8 +457,8 @@ static int div_ratio(u_long upper, u_long lower) else upper <<= 16L ; if (!lower) - return(0) ; - return((int)(upper/lower)) ; + return 0; + return (int)(upper/lower) ; } #ifndef SLIM_SMT @@ -1111,11 +1111,11 @@ SMbuf *smt_build_frame(struct s_smc *smc, int class, int type, #if 0 if (!smc->r.sm_ma_avail) { - return(0) ; + return 0; } #endif if (!(mb = smt_get_mbuf(smc))) - return(mb) ; + return mb; mb->sm_len = length ; smt = smtod(mb, struct smt_header *) ; @@ -1136,7 +1136,7 @@ SMbuf *smt_build_frame(struct s_smc *smc, int class, int type, smt->smt_tid = smt_get_tid(smc) ; /* set transaction ID */ smt->smt_pad = 0 ; smt->smt_len = length - sizeof(struct smt_header) ; - return(mb) ; + return mb; } static void smt_add_frame_len(SMbuf *mb, int len) @@ -1375,7 +1375,7 @@ static int smt_fill_path(struct s_smc *smc, struct smt_p_path *path) pd_mac = (struct smt_mac_rec *) phy ; pd_mac->mac_addr = smc->mib.m[MAC0].fddiMACSMTAddress ; pd_mac->mac_resource_idx = mac_con_resource_index(smc,1) ; - return(len) ; + return len; } /* @@ -1563,7 +1563,7 @@ u_long smt_get_tid(struct s_smc *smc) u_long tid ; while ((tid = ++(smc->sm.smt_tid) ^ SMT_TID_MAGIC) == 0) ; - return(tid & 0x3fffffffL) ; + return tid & 0x3fffffffL; } @@ -1654,11 +1654,11 @@ int smt_check_para(struct s_smc *smc, struct smt_header *sm, while (*p) { if (!sm_to_para(smc,sm,(int) *p)) { DB_SMT("SMT: smt_check_para - missing para %x\n",*p,0); - return(-1) ; + return -1; } p++ ; } - return(0) ; + return 0; } void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para) @@ -1687,7 +1687,7 @@ void *sm_to_para(struct s_smc *smc, struct smt_header *sm, int para) return NULL; } if (found) - return(found) ; + return found; } return NULL; } @@ -1732,7 +1732,7 @@ char *addr_to_string(struct fddi_addr *addr) string[i * 3 + 2] = ':'; } string[5 * 3 + 2] = 0; - return(string); + return string; } #endif @@ -1742,9 +1742,9 @@ int smt_ifconfig(int argc, char *argv[]) if (argc >= 2 && !strcmp(argv[0],"opt_bypass") && !strcmp(argv[1],"yes")) { smc->mib.fddiSMTBypassPresent = 1 ; - return(0) ; + return 0; } - return(amdfddi_config(0,argc,argv)) ; + return amdfddi_config(0, argc, argv); } #endif @@ -1756,9 +1756,9 @@ static int mac_index(struct s_smc *smc, int mac) SK_UNUSED(mac) ; #ifdef CONCENTRATOR SK_UNUSED(smc) ; - return(NUMPHYS+1) ; + return NUMPHYS + 1; #else - return((smc->s.sas == SMT_SAS) ? 2 : 3) ; + return (smc->s.sas == SMT_SAS) ? 2 : 3; #endif } @@ -1768,7 +1768,7 @@ static int mac_index(struct s_smc *smc, int mac) static int phy_index(struct s_smc *smc, int phy) { SK_UNUSED(smc) ; - return(phy+1); + return phy + 1; } /* @@ -1779,19 +1779,19 @@ static int mac_con_resource_index(struct s_smc *smc, int mac) #ifdef CONCENTRATOR SK_UNUSED(smc) ; SK_UNUSED(mac) ; - return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_MAC))) ; + return entity_to_index(smc, cem_get_downstream(smc, ENTITY_MAC)); #else SK_UNUSED(mac) ; switch (smc->mib.fddiSMTCF_State) { case SC9_C_WRAP_A : case SC5_THRU_B : case SC11_C_WRAP_S : - return(1) ; + return 1; case SC10_C_WRAP_B : case SC4_THRU_A : - return(2) ; + return 2; } - return(smc->s.sas == SMT_SAS ? 2 : 3) ; + return smc->s.sas == SMT_SAS ? 2 : 3; #endif } @@ -1801,21 +1801,21 @@ static int mac_con_resource_index(struct s_smc *smc, int mac) static int phy_con_resource_index(struct s_smc *smc, int phy) { #ifdef CONCENTRATOR - return(entity_to_index(smc,cem_get_downstream(smc,ENTITY_PHY(phy)))) ; + return entity_to_index(smc, cem_get_downstream(smc, ENTITY_PHY(phy))) ; #else switch (smc->mib.fddiSMTCF_State) { case SC9_C_WRAP_A : - return(phy == PA ? 3 : 2) ; + return phy == PA ? 3 : 2; case SC10_C_WRAP_B : - return(phy == PA ? 1 : 3) ; + return phy == PA ? 1 : 3; case SC4_THRU_A : - return(phy == PA ? 3 : 1) ; + return phy == PA ? 3 : 1; case SC5_THRU_B : - return(phy == PA ? 2 : 3) ; + return phy == PA ? 2 : 3; case SC11_C_WRAP_S : - return(2) ; + return 2; } - return(phy) ; + return phy; #endif } @@ -1823,16 +1823,16 @@ static int phy_con_resource_index(struct s_smc *smc, int phy) static int entity_to_index(struct s_smc *smc, int e) { if (e == ENTITY_MAC) - return(mac_index(smc,1)) ; + return mac_index(smc, 1); else - return(phy_index(smc,e - ENTITY_PHY(0))) ; + return phy_index(smc, e - ENTITY_PHY(0)); } #endif #ifdef LITTLE_ENDIAN static int smt_swap_short(u_short s) { - return(((s>>8)&0xff)|((s&0xff)<<8)) ; + return ((s>>8)&0xff) | ((s&0xff)<<8); } void smt_swap_para(struct smt_header *sm, int len, int direction) @@ -1996,7 +1996,7 @@ int smt_action(struct s_smc *smc, int class, int code, int index) } break ; default : - return(1) ; + return 1; } break ; case SMT_PORT_ACTION : @@ -2017,14 +2017,14 @@ int smt_action(struct s_smc *smc, int class, int code, int index) event = PC_STOP ; break ; default : - return(1) ; + return 1; } queue_event(smc,EVENT_PCM+index,event) ; break ; default : - return(1) ; + return 1; } - return(0) ; + return 0; } /* diff --git a/drivers/net/skfp/smtdef.c b/drivers/net/skfp/smtdef.c index 4e07ff7073f1141f209c0773f16c0972261c260a..1acab0b368e3188fa63a289bf41cf22b4dbc11a6 100644 --- a/drivers/net/skfp/smtdef.c +++ b/drivers/net/skfp/smtdef.c @@ -303,7 +303,7 @@ int smt_set_mac_opvalues(struct s_smc *smc) FDDI_SMT_EVENT, (u_long) FDDI_REMOTE_T_REQ, smt_get_event_word(smc)); } - return(st) ; + return st; } void smt_fixup_mib(struct s_smc *smc) @@ -350,6 +350,6 @@ static int set_min_max(int maxflag, u_long mib, u_long limit, u_long *oper) *oper = limit ; else *oper = mib ; - return(old != *oper) ; + return old != *oper; } diff --git a/drivers/net/skfp/smtinit.c b/drivers/net/skfp/smtinit.c index 3c8964ce1837229d95b5d197de3229c885712007..e3a0c0bc22331e20b8a7e30e5a3cb416d2a1d8b8 100644 --- a/drivers/net/skfp/smtinit.c +++ b/drivers/net/skfp/smtinit.c @@ -120,6 +120,6 @@ int init_smt(struct s_smc *smc, u_char *mac_addr) PNMI_INIT(smc) ; /* PNMI initialization */ - return(0) ; + return 0; } diff --git a/drivers/net/skfp/srf.c b/drivers/net/skfp/srf.c index 40882b3faba6c3238d9edd75502c17b9abb72e8e..f6f7baf9f27a7f6072c046970edb1ef38105bd9b 100644 --- a/drivers/net/skfp/srf.c +++ b/drivers/net/skfp/srf.c @@ -165,7 +165,7 @@ static struct s_srf_evc *smt_get_evc(struct s_smc *smc, int code, int index) for (i = 0, evc = smc->evcs ; (unsigned) i < MAX_EVCS ; i++, evc++) { if (evc->evc_code == code && evc->evc_index == index) - return(evc) ; + return evc; } return NULL; } diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 465ae7e84507385b079c7922cb7360cec428a30f..bfec2e0f52757bdb1097d158b813aaecd7164d66 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3179,8 +3179,7 @@ static int skge_poll(struct napi_struct *napi, int to_do) skb = skge_rx_get(dev, e, control, rd->status, rd->csum2); if (likely(skb)) { - netif_receive_skb(skb); - + napi_gro_receive(napi, skb); ++work_done; } } @@ -3193,6 +3192,7 @@ static int skge_poll(struct napi_struct *napi, int to_do) if (work_done < to_do) { unsigned long flags; + napi_gro_flush(napi); spin_lock_irqsave(&hw->hw_lock, flags); __napi_complete(napi); hw->intr_mask |= napimask[skge->port]; @@ -3850,6 +3850,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; skge->rx_csum = 1; } + dev->features |= NETIF_F_GRO; /* read the mac address */ memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN); diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 194e5cf8c763d8055e988ea14d1c5c43a8819029..d6577084ce70b79690e79aea191ac2b36240cbfb 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -1782,7 +1782,7 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb, ctrl = 0; #ifdef SKY2_VLAN_TAG_USED /* Add VLAN tag, can piggyback on LRGLEN or ADDR64 */ - if (sky2->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { if (!le) { le = get_tx_le(sky2, &slot); le->addr = 0; @@ -4581,7 +4581,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, sky2->port = port; - dev->features |= NETIF_F_TSO | NETIF_F_IP_CSUM | NETIF_F_SG; + dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG + | NETIF_F_TSO | NETIF_F_GRO; if (highmem) dev->features |= NETIF_F_HIGHDMA; diff --git a/drivers/net/slip.c b/drivers/net/slip.c index fa434fb8fb7c087df16bacaf9108dfa3646e35db..86cbb9ea2f269ee2532078dea529eebdb8cc0a9f 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -271,7 +271,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) memcpy(sl->xbuff, sl->xhead, sl->xleft); } else { sl->xleft = 0; - sl->tx_dropped++; + dev->stats.tx_dropped++; } } sl->xhead = sl->xbuff; @@ -281,7 +281,7 @@ static int sl_realloc_bufs(struct slip *sl, int mtu) memcpy(sl->rbuff, rbuff, sl->rcount); } else { sl->rcount = 0; - sl->rx_over_errors++; + dev->stats.rx_over_errors++; set_bit(SLF_ERROR, &sl->flags); } } @@ -319,6 +319,7 @@ static inline void sl_unlock(struct slip *sl) /* Send one completely decapsulated IP datagram to the IP layer. */ static void sl_bump(struct slip *sl) { + struct net_device *dev = sl->dev; struct sk_buff *skb; int count; @@ -329,13 +330,13 @@ static void sl_bump(struct slip *sl) if (c & SL_TYPE_COMPRESSED_TCP) { /* ignore compressed packets when CSLIP is off */ if (!(sl->mode & SL_MODE_CSLIP)) { - printk(KERN_WARNING "%s: compressed packet ignored\n", sl->dev->name); + printk(KERN_WARNING "%s: compressed packet ignored\n", dev->name); return; } /* make sure we've reserved enough space for uncompress to use */ if (count + 80 > sl->buffsize) { - sl->rx_over_errors++; + dev->stats.rx_over_errors++; return; } count = slhc_uncompress(sl->slcomp, sl->rbuff, count); @@ -346,7 +347,7 @@ static void sl_bump(struct slip *sl) /* turn on header compression */ sl->mode |= SL_MODE_CSLIP; sl->mode &= ~SL_MODE_ADAPTIVE; - printk(KERN_INFO "%s: header compression turned on\n", sl->dev->name); + printk(KERN_INFO "%s: header compression turned on\n", dev->name); } sl->rbuff[0] &= 0x4f; if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) @@ -355,20 +356,20 @@ static void sl_bump(struct slip *sl) } #endif /* SL_INCLUDE_CSLIP */ - sl->rx_bytes += count; + dev->stats.rx_bytes += count; skb = dev_alloc_skb(count); if (skb == NULL) { - printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", sl->dev->name); - sl->rx_dropped++; + printk(KERN_WARNING "%s: memory squeeze, dropping packet.\n", dev->name); + dev->stats.rx_dropped++; return; } - skb->dev = sl->dev; + skb->dev = dev; memcpy(skb_put(skb, count), sl->rbuff, count); skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IP); netif_rx(skb); - sl->rx_packets++; + dev->stats.rx_packets++; } /* Encapsulate one IP datagram and stuff into a TTY queue. */ @@ -379,7 +380,7 @@ static void sl_encaps(struct slip *sl, unsigned char *icp, int len) if (len > sl->mtu) { /* Sigh, shouldn't occur BUT ... */ printk(KERN_WARNING "%s: truncating oversized transmit packet!\n", sl->dev->name); - sl->tx_dropped++; + sl->dev->stats.tx_dropped++; sl_unlock(sl); return; } @@ -433,7 +434,7 @@ static void slip_write_wakeup(struct tty_struct *tty) if (sl->xleft <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet */ - sl->tx_packets++; + sl->dev->stats.tx_packets++; clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); sl_unlock(sl); return; @@ -496,7 +497,7 @@ sl_xmit(struct sk_buff *skb, struct net_device *dev) } sl_lock(sl); - sl->tx_bytes += skb->len; + dev->stats.tx_bytes += skb->len; sl_encaps(sl, skb->data, skb->len); spin_unlock(&sl->lock); @@ -558,39 +559,39 @@ static int sl_change_mtu(struct net_device *dev, int new_mtu) /* Netdevice get statistics request */ -static struct net_device_stats * -sl_get_stats(struct net_device *dev) +static struct rtnl_link_stats64 * +sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) { - static struct net_device_stats stats; - struct slip *sl = netdev_priv(dev); + struct net_device_stats *devstats = &dev->stats; + unsigned long c_rx_dropped = 0; #ifdef SL_INCLUDE_CSLIP - struct slcompress *comp; -#endif + unsigned long c_rx_fifo_errors = 0; + unsigned long c_tx_fifo_errors = 0; + unsigned long c_collisions = 0; + struct slip *sl = netdev_priv(dev); + struct slcompress *comp = sl->slcomp; - memset(&stats, 0, sizeof(struct net_device_stats)); - - stats.rx_packets = sl->rx_packets; - stats.tx_packets = sl->tx_packets; - stats.rx_bytes = sl->rx_bytes; - stats.tx_bytes = sl->tx_bytes; - stats.rx_dropped = sl->rx_dropped; - stats.tx_dropped = sl->tx_dropped; - stats.tx_errors = sl->tx_errors; - stats.rx_errors = sl->rx_errors; - stats.rx_over_errors = sl->rx_over_errors; -#ifdef SL_INCLUDE_CSLIP - stats.rx_fifo_errors = sl->rx_compressed; - stats.tx_fifo_errors = sl->tx_compressed; - stats.collisions = sl->tx_misses; - comp = sl->slcomp; if (comp) { - stats.rx_fifo_errors += comp->sls_i_compressed; - stats.rx_dropped += comp->sls_i_tossed; - stats.tx_fifo_errors += comp->sls_o_compressed; - stats.collisions += comp->sls_o_misses; + c_rx_fifo_errors = comp->sls_i_compressed; + c_rx_dropped = comp->sls_i_tossed; + c_tx_fifo_errors = comp->sls_o_compressed; + c_collisions = comp->sls_o_misses; } -#endif /* CONFIG_INET */ - return (&stats); + stats->rx_fifo_errors = sl->rx_compressed + c_rx_fifo_errors; + stats->tx_fifo_errors = sl->tx_compressed + c_tx_fifo_errors; + stats->collisions = sl->tx_misses + c_collisions; +#endif + stats->rx_packets = devstats->rx_packets; + stats->tx_packets = devstats->tx_packets; + stats->rx_bytes = devstats->rx_bytes; + stats->tx_bytes = devstats->tx_bytes; + stats->rx_dropped = devstats->rx_dropped + c_rx_dropped; + stats->tx_dropped = devstats->tx_dropped; + stats->tx_errors = devstats->tx_errors; + stats->rx_errors = devstats->rx_errors; + stats->rx_over_errors = devstats->rx_over_errors; + + return stats; } /* Netdevice register callback */ @@ -633,7 +634,7 @@ static const struct net_device_ops sl_netdev_ops = { .ndo_open = sl_open, .ndo_stop = sl_close, .ndo_start_xmit = sl_xmit, - .ndo_get_stats = sl_get_stats, + .ndo_get_stats64 = sl_get_stats64, .ndo_change_mtu = sl_change_mtu, .ndo_tx_timeout = sl_tx_timeout, #ifdef CONFIG_SLIP_SMART @@ -681,7 +682,7 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, while (count--) { if (fp && *fp++) { if (!test_and_set_bit(SLF_ERROR, &sl->flags)) - sl->rx_errors++; + sl->dev->stats.rx_errors++; cp++; continue; } @@ -943,7 +944,7 @@ static int slip_esc(unsigned char *s, unsigned char *d, int len) } } *ptr++ = END; - return (ptr - d); + return ptr - d; } static void slip_unesc(struct slip *sl, unsigned char s) @@ -981,7 +982,7 @@ static void slip_unesc(struct slip *sl, unsigned char s) sl->rbuff[sl->rcount++] = s; return; } - sl->rx_over_errors++; + sl->dev->stats.rx_over_errors++; set_bit(SLF_ERROR, &sl->flags); } } @@ -1057,7 +1058,7 @@ static void slip_unesc6(struct slip *sl, unsigned char s) sl->rbuff[sl->rcount++] = c; return; } - sl->rx_over_errors++; + sl->dev->stats.rx_over_errors++; set_bit(SLF_ERROR, &sl->flags); } } diff --git a/drivers/net/slip.h b/drivers/net/slip.h index 9ea5c11287d26594f8daee415b7b65239a9ed33e..914e958abbfc88fb74b2a13bf22dff007d79ee70 100644 --- a/drivers/net/slip.h +++ b/drivers/net/slip.h @@ -67,15 +67,6 @@ struct slip { int xleft; /* bytes left in XMIT queue */ /* SLIP interface statistics. */ - unsigned long rx_packets; /* inbound frames counter */ - unsigned long tx_packets; /* outbound frames counter */ - unsigned long rx_bytes; /* inbound byte counte */ - unsigned long tx_bytes; /* outbound byte counter */ - unsigned long rx_errors; /* Parity, etc. errors */ - unsigned long tx_errors; /* Planned stuff */ - unsigned long rx_dropped; /* No memory for skb */ - unsigned long tx_dropped; /* When MTU change */ - unsigned long rx_over_errors; /* Frame bigger than SLIP buf. */ #ifdef SL_INCLUDE_CSLIP unsigned long tx_compressed; unsigned long rx_compressed; diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c index 8150ba1541161ab2e7781ade13be970540f835ec..a8e5856ce8821b4f441173be994d90bd021b9bcb 100644 --- a/drivers/net/smsc911x.c +++ b/drivers/net/smsc911x.c @@ -1049,7 +1049,7 @@ static int smsc911x_poll(struct napi_struct *napi, int budget) smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head, pktwords); skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_receive_skb(skb); /* Update counters */ diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 1636a34d95dd60ca6e8c4c6e0ea4871366ad220b..cb6bcca9d541d2287e5a963bbacad8c540b58f27 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c @@ -1000,9 +1000,9 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (data_status & SPIDER_NET_VLAN_PACKET) { /* further enhancements: HW-accel VLAN diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index a42b6873370b04924af204596baf17342319121b..4adf124227877e704fe66a7bb74919738bbd46c5 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, }; * This SUCKS. * We need a much better method to determine if dma_addr_t is 64-bit. */ -#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) +#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)) /* 64-bit dma_addr_t */ #define ADDR_64BITS /* This chip uses 64 bit addresses. */ #define netdrv_addr_t __le64 @@ -302,7 +302,7 @@ enum chipset { }; static DEFINE_PCI_DEVICE_TABLE(starfire_pci_tbl) = { - { 0x9004, 0x6915, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_6915 }, + { PCI_VDEVICE(ADAPTEC, 0x6915), CH_6915 }, { 0, } }; MODULE_DEVICE_TABLE(pci, starfire_pci_tbl); @@ -2078,11 +2078,7 @@ static int __init starfire_init (void) printk(KERN_INFO DRV_NAME ": polling (NAPI) enabled\n"); #endif - /* we can do this test only at run-time... sigh */ - if (sizeof(dma_addr_t) != sizeof(netdrv_addr_t)) { - printk("This driver has dma_addr_t issues, please send email to maintainer\n"); - return -ENODEV; - } + BUILD_BUG_ON(sizeof(dma_addr_t) != sizeof(netdrv_addr_t)); return pci_register_driver(&starfire_driver); } diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig index eb63d44748a76cd3182e002284afe84296552d1e..7df7df4e79c5cef7b3f6e006a2150d21f882c101 100644 --- a/drivers/net/stmmac/Kconfig +++ b/drivers/net/stmmac/Kconfig @@ -3,10 +3,10 @@ config STMMAC_ETH select MII select PHYLIB select CRC32 - depends on NETDEVICES && CPU_SUBTYPE_ST40 + depends on NETDEVICES && HAS_IOMEM help This is the driver for the Ethernet IPs are built around a - Synopsys IP Core and fully tested on the STMicroelectronics + Synopsys IP Core and only tested on the STMicroelectronics platforms. if STMMAC_ETH @@ -32,6 +32,7 @@ config STMMAC_DUAL_MAC config STMMAC_TIMER bool "STMMAC Timer optimisation" default n + depends on RTC_HCTOSYS_DEVICE help Use an external timer for mitigating the number of network interrupts. Currently, for SH architectures, it is possible diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h index 66b9da0260fe70b6177c6980604f24184dcdb431..375ea193e139a4a1bd23ecf68937007402682745 100644 --- a/drivers/net/stmmac/common.h +++ b/drivers/net/stmmac/common.h @@ -102,8 +102,6 @@ struct stmmac_extra_stats { #define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */ -#define HW_CSUM 1 -#define NO_HW_CSUM 0 enum rx_frame_status { /* IPC status */ good_frame = 0, discard_frame = 1, @@ -167,7 +165,7 @@ struct stmmac_desc_ops { int (*get_tx_ls) (struct dma_desc *p); /* Return the transmit status looking at the TDES1 */ int (*tx_status) (void *data, struct stmmac_extra_stats *x, - struct dma_desc *p, unsigned long ioaddr); + struct dma_desc *p, void __iomem *ioaddr); /* Get the buffer size from the descriptor */ int (*get_tx_len) (struct dma_desc *p); /* Handle extra events on specific interrupts hw dependent */ @@ -182,44 +180,46 @@ struct stmmac_desc_ops { struct stmmac_dma_ops { /* DMA core initialization */ - int (*init) (unsigned long ioaddr, int pbl, u32 dma_tx, u32 dma_rx); + int (*init) (void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx); /* Dump DMA registers */ - void (*dump_regs) (unsigned long ioaddr); + void (*dump_regs) (void __iomem *ioaddr); /* Set tx/rx threshold in the csr6 register * An invalid value enables the store-and-forward mode */ - void (*dma_mode) (unsigned long ioaddr, int txmode, int rxmode); + void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode); /* To track extra statistic (if supported) */ void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x, - unsigned long ioaddr); - void (*enable_dma_transmission) (unsigned long ioaddr); - void (*enable_dma_irq) (unsigned long ioaddr); - void (*disable_dma_irq) (unsigned long ioaddr); - void (*start_tx) (unsigned long ioaddr); - void (*stop_tx) (unsigned long ioaddr); - void (*start_rx) (unsigned long ioaddr); - void (*stop_rx) (unsigned long ioaddr); - int (*dma_interrupt) (unsigned long ioaddr, + void __iomem *ioaddr); + void (*enable_dma_transmission) (void __iomem *ioaddr); + void (*enable_dma_irq) (void __iomem *ioaddr); + void (*disable_dma_irq) (void __iomem *ioaddr); + void (*start_tx) (void __iomem *ioaddr); + void (*stop_tx) (void __iomem *ioaddr); + void (*start_rx) (void __iomem *ioaddr); + void (*stop_rx) (void __iomem *ioaddr); + int (*dma_interrupt) (void __iomem *ioaddr, struct stmmac_extra_stats *x); }; struct stmmac_ops { /* MAC core initialization */ - void (*core_init) (unsigned long ioaddr) ____cacheline_aligned; + void (*core_init) (void __iomem *ioaddr) ____cacheline_aligned; + /* Support checksum offload engine */ + int (*rx_coe) (void __iomem *ioaddr); /* Dump MAC registers */ - void (*dump_regs) (unsigned long ioaddr); + void (*dump_regs) (void __iomem *ioaddr); /* Handle extra events on specific interrupts hw dependent */ - void (*host_irq_status) (unsigned long ioaddr); + void (*host_irq_status) (void __iomem *ioaddr); /* Multicast filter setting */ void (*set_filter) (struct net_device *dev); /* Flow control setting */ - void (*flow_ctrl) (unsigned long ioaddr, unsigned int duplex, + void (*flow_ctrl) (void __iomem *ioaddr, unsigned int duplex, unsigned int fc, unsigned int pause_time); /* Set power management mode (e.g. magic frame) */ - void (*pmt) (unsigned long ioaddr, unsigned long mode); + void (*pmt) (void __iomem *ioaddr, unsigned long mode); /* Set/Get Unicast MAC addresses */ - void (*set_umac_addr) (unsigned long ioaddr, unsigned char *addr, + void (*set_umac_addr) (void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n); - void (*get_umac_addr) (unsigned long ioaddr, unsigned char *addr, + void (*get_umac_addr) (void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n); }; @@ -235,19 +235,18 @@ struct mii_regs { }; struct mac_device_info { - struct stmmac_ops *mac; - struct stmmac_desc_ops *desc; - struct stmmac_dma_ops *dma; - unsigned int pmt; /* support Power-Down */ + const struct stmmac_ops *mac; + const struct stmmac_desc_ops *desc; + const struct stmmac_dma_ops *dma; struct mii_regs mii; /* MII register Addresses */ struct mac_link link; }; -struct mac_device_info *dwmac1000_setup(unsigned long addr); -struct mac_device_info *dwmac100_setup(unsigned long addr); +struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr); +struct mac_device_info *dwmac100_setup(void __iomem *ioaddr); -extern void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6], +extern void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned int high, unsigned int low); -extern void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr, +extern void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int high, unsigned int low); -extern void dwmac_dma_flush_tx_fifo(unsigned long ioaddr); +extern void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr); diff --git a/drivers/net/stmmac/dwmac100.h b/drivers/net/stmmac/dwmac100.h index 97956cbf1cb4de2a374e0626f20df4977e680fd1..7c6d857a9cc7f0c357bb7b1d0cb9d417ecbc25a5 100644 --- a/drivers/net/stmmac/dwmac100.h +++ b/drivers/net/stmmac/dwmac100.h @@ -118,4 +118,4 @@ enum ttc_control { #define DMA_MISSED_FRAME_OVE_M 0x00010000 /* Missed Frame Overflow */ #define DMA_MISSED_FRAME_M_CNTR 0x0000ffff /* Missed Frame Couinter */ -extern struct stmmac_dma_ops dwmac100_dma_ops; +extern const struct stmmac_dma_ops dwmac100_dma_ops; diff --git a/drivers/net/stmmac/dwmac1000.h b/drivers/net/stmmac/dwmac1000.h index 8b20b19971cbe6e0156ce5bee9edc96f73f06785..cfcef0ea0fa5db049120c5a2f097d031b29330a8 100644 --- a/drivers/net/stmmac/dwmac1000.h +++ b/drivers/net/stmmac/dwmac1000.h @@ -99,7 +99,7 @@ enum inter_frame_gap { #define GMAC_CONTROL_RE 0x00000004 /* Receiver Enable */ #define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \ - GMAC_CONTROL_IPC | GMAC_CONTROL_JE | GMAC_CONTROL_BE) + GMAC_CONTROL_JE | GMAC_CONTROL_BE) /* GMAC Frame Filter defines */ #define GMAC_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */ @@ -205,4 +205,4 @@ enum rtc_control { #define GMAC_MMC_TX_INTR 0x108 #define GMAC_MMC_RX_CSUM_OFFLOAD 0x208 -extern struct stmmac_dma_ops dwmac1000_dma_ops; +extern const struct stmmac_dma_ops dwmac1000_dma_ops; diff --git a/drivers/net/stmmac/dwmac1000_core.c b/drivers/net/stmmac/dwmac1000_core.c index 2b2f5c8caf1c52ea010843789417bfb40768366b..6ae4c3f4c63c712031b4ca67549a8d8f631ed9fd 100644 --- a/drivers/net/stmmac/dwmac1000_core.c +++ b/drivers/net/stmmac/dwmac1000_core.c @@ -30,7 +30,7 @@ #include #include "dwmac1000.h" -static void dwmac1000_core_init(unsigned long ioaddr) +static void dwmac1000_core_init(void __iomem *ioaddr) { u32 value = readl(ioaddr + GMAC_CONTROL); value |= GMAC_CORE_INIT; @@ -50,10 +50,22 @@ static void dwmac1000_core_init(unsigned long ioaddr) #endif } -static void dwmac1000_dump_regs(unsigned long ioaddr) +static int dwmac1000_rx_coe_supported(void __iomem *ioaddr) +{ + u32 value = readl(ioaddr + GMAC_CONTROL); + + value |= GMAC_CONTROL_IPC; + writel(value, ioaddr + GMAC_CONTROL); + + value = readl(ioaddr + GMAC_CONTROL); + + return !!(value & GMAC_CONTROL_IPC); +} + +static void dwmac1000_dump_regs(void __iomem *ioaddr) { int i; - pr_info("\tDWMAC1000 regs (base addr = 0x%8x)\n", (unsigned int)ioaddr); + pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr); for (i = 0; i < 55; i++) { int offset = i * 4; @@ -62,14 +74,14 @@ static void dwmac1000_dump_regs(unsigned long ioaddr) } } -static void dwmac1000_set_umac_addr(unsigned long ioaddr, unsigned char *addr, +static void dwmac1000_set_umac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n) { stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), GMAC_ADDR_LOW(reg_n)); } -static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr, +static void dwmac1000_get_umac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n) { stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n), @@ -78,7 +90,7 @@ static void dwmac1000_get_umac_addr(unsigned long ioaddr, unsigned char *addr, static void dwmac1000_set_filter(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; + void __iomem *ioaddr = (void __iomem *) dev->base_addr; unsigned int value = 0; CHIP_DBG(KERN_INFO "%s: # mcasts %d, # unicast %d\n", @@ -139,7 +151,7 @@ static void dwmac1000_set_filter(struct net_device *dev) readl(ioaddr + GMAC_HASH_HIGH), readl(ioaddr + GMAC_HASH_LOW)); } -static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex, +static void dwmac1000_flow_ctrl(void __iomem *ioaddr, unsigned int duplex, unsigned int fc, unsigned int pause_time) { unsigned int flow = 0; @@ -162,7 +174,7 @@ static void dwmac1000_flow_ctrl(unsigned long ioaddr, unsigned int duplex, writel(flow, ioaddr + GMAC_FLOW_CTRL); } -static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode) +static void dwmac1000_pmt(void __iomem *ioaddr, unsigned long mode) { unsigned int pmt = 0; @@ -178,7 +190,7 @@ static void dwmac1000_pmt(unsigned long ioaddr, unsigned long mode) } -static void dwmac1000_irq_status(unsigned long ioaddr) +static void dwmac1000_irq_status(void __iomem *ioaddr) { u32 intr_status = readl(ioaddr + GMAC_INT_STATUS); @@ -200,8 +212,9 @@ static void dwmac1000_irq_status(unsigned long ioaddr) } } -struct stmmac_ops dwmac1000_ops = { +static const struct stmmac_ops dwmac1000_ops = { .core_init = dwmac1000_core_init, + .rx_coe = dwmac1000_rx_coe_supported, .dump_regs = dwmac1000_dump_regs, .host_irq_status = dwmac1000_irq_status, .set_filter = dwmac1000_set_filter, @@ -211,7 +224,7 @@ struct stmmac_ops dwmac1000_ops = { .get_umac_addr = dwmac1000_get_umac_addr, }; -struct mac_device_info *dwmac1000_setup(unsigned long ioaddr) +struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr) { struct mac_device_info *mac; u32 uid = readl(ioaddr + GMAC_VERSION); @@ -226,7 +239,6 @@ struct mac_device_info *dwmac1000_setup(unsigned long ioaddr) mac->mac = &dwmac1000_ops; mac->dma = &dwmac1000_dma_ops; - mac->pmt = PMT_SUPPORTED; mac->link.port = GMAC_CONTROL_PS; mac->link.duplex = GMAC_CONTROL_DM; mac->link.speed = GMAC_CONTROL_FES; diff --git a/drivers/net/stmmac/dwmac1000_dma.c b/drivers/net/stmmac/dwmac1000_dma.c index 415805057cb0ff12e116bd7621fa2246831efeca..2c47712d45d05cbe7ffddc792f62cf362e6c310c 100644 --- a/drivers/net/stmmac/dwmac1000_dma.c +++ b/drivers/net/stmmac/dwmac1000_dma.c @@ -29,14 +29,22 @@ #include "dwmac1000.h" #include "dwmac_dma.h" -static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, +static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); + int limit; + /* DMA SW reset */ value |= DMA_BUS_MODE_SFT_RESET; writel(value, ioaddr + DMA_BUS_MODE); - do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)); + limit = 15000; + while (limit--) { + if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) + break; + } + if (limit < 0) + return -EBUSY; value = /* DMA_BUS_MODE_FB | */ DMA_BUS_MODE_4PBL | ((pbl << DMA_BUS_MODE_PBL_SHIFT) | @@ -58,7 +66,7 @@ static int dwmac1000_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, return 0; } -static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode, +static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode, int rxmode) { u32 csr6 = readl(ioaddr + DMA_CONTROL); @@ -111,12 +119,12 @@ static void dwmac1000_dma_operation_mode(unsigned long ioaddr, int txmode, /* Not yet implemented --- no RMON module */ static void dwmac1000_dma_diagnostic_fr(void *data, - struct stmmac_extra_stats *x, unsigned long ioaddr) + struct stmmac_extra_stats *x, void __iomem *ioaddr) { return; } -static void dwmac1000_dump_dma_regs(unsigned long ioaddr) +static void dwmac1000_dump_dma_regs(void __iomem *ioaddr) { int i; pr_info(" DMA registers\n"); @@ -130,7 +138,7 @@ static void dwmac1000_dump_dma_regs(unsigned long ioaddr) } } -struct stmmac_dma_ops dwmac1000_dma_ops = { +const struct stmmac_dma_ops dwmac1000_dma_ops = { .init = dwmac1000_dma_init, .dump_regs = dwmac1000_dump_dma_regs, .dma_mode = dwmac1000_dma_operation_mode, diff --git a/drivers/net/stmmac/dwmac100_core.c b/drivers/net/stmmac/dwmac100_core.c index 2fb165fa2ba075b256533a7d1058ea00c36f2b33..c724fc36a24fd696557c32afc87f0cdc6835ba0c 100644 --- a/drivers/net/stmmac/dwmac100_core.c +++ b/drivers/net/stmmac/dwmac100_core.c @@ -31,7 +31,7 @@ #include #include "dwmac100.h" -static void dwmac100_core_init(unsigned long ioaddr) +static void dwmac100_core_init(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CONTROL); @@ -42,12 +42,17 @@ static void dwmac100_core_init(unsigned long ioaddr) #endif } -static void dwmac100_dump_mac_regs(unsigned long ioaddr) +static int dwmac100_rx_coe_supported(void __iomem *ioaddr) +{ + return 0; +} + +static void dwmac100_dump_mac_regs(void __iomem *ioaddr) { pr_info("\t----------------------------------------------\n" - "\t DWMAC 100 CSR (base addr = 0x%8x)\n" + "\t DWMAC 100 CSR (base addr = 0x%p)\n" "\t----------------------------------------------\n", - (unsigned int)ioaddr); + ioaddr); pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL, readl(ioaddr + MAC_CONTROL)); pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH, @@ -77,18 +82,18 @@ static void dwmac100_dump_mac_regs(unsigned long ioaddr) MMC_LOW_INTR_MASK, readl(ioaddr + MMC_LOW_INTR_MASK)); } -static void dwmac100_irq_status(unsigned long ioaddr) +static void dwmac100_irq_status(void __iomem *ioaddr) { return; } -static void dwmac100_set_umac_addr(unsigned long ioaddr, unsigned char *addr, +static void dwmac100_set_umac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n) { stmmac_set_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); } -static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr, +static void dwmac100_get_umac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int reg_n) { stmmac_get_mac_addr(ioaddr, addr, MAC_ADDR_HIGH, MAC_ADDR_LOW); @@ -96,7 +101,7 @@ static void dwmac100_get_umac_addr(unsigned long ioaddr, unsigned char *addr, static void dwmac100_set_filter(struct net_device *dev) { - unsigned long ioaddr = dev->base_addr; + void __iomem *ioaddr = (void __iomem *) dev->base_addr; u32 value = readl(ioaddr + MAC_CONTROL); if (dev->flags & IFF_PROMISC) { @@ -145,7 +150,7 @@ static void dwmac100_set_filter(struct net_device *dev) readl(ioaddr + MAC_HASH_HIGH), readl(ioaddr + MAC_HASH_LOW)); } -static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex, +static void dwmac100_flow_ctrl(void __iomem *ioaddr, unsigned int duplex, unsigned int fc, unsigned int pause_time) { unsigned int flow = MAC_FLOW_CTRL_ENABLE; @@ -158,13 +163,14 @@ static void dwmac100_flow_ctrl(unsigned long ioaddr, unsigned int duplex, /* No PMT module supported for this Ethernet Controller. * Tested on ST platforms only. */ -static void dwmac100_pmt(unsigned long ioaddr, unsigned long mode) +static void dwmac100_pmt(void __iomem *ioaddr, unsigned long mode) { return; } -struct stmmac_ops dwmac100_ops = { +static const struct stmmac_ops dwmac100_ops = { .core_init = dwmac100_core_init, + .rx_coe = dwmac100_rx_coe_supported, .dump_regs = dwmac100_dump_mac_regs, .host_irq_status = dwmac100_irq_status, .set_filter = dwmac100_set_filter, @@ -174,7 +180,7 @@ struct stmmac_ops dwmac100_ops = { .get_umac_addr = dwmac100_get_umac_addr, }; -struct mac_device_info *dwmac100_setup(unsigned long ioaddr) +struct mac_device_info *dwmac100_setup(void __iomem *ioaddr) { struct mac_device_info *mac; @@ -187,7 +193,6 @@ struct mac_device_info *dwmac100_setup(unsigned long ioaddr) mac->mac = &dwmac100_ops; mac->dma = &dwmac100_dma_ops; - mac->pmt = PMT_NOT_SUPPORTED; mac->link.port = MAC_CONTROL_PS; mac->link.duplex = MAC_CONTROL_F; mac->link.speed = 0; diff --git a/drivers/net/stmmac/dwmac100_dma.c b/drivers/net/stmmac/dwmac100_dma.c index 2fece7b727279a96a369313208f51b1f63eafd36..e3e224b7d9e23c6903a0f970ae4c7cd0c8491192 100644 --- a/drivers/net/stmmac/dwmac100_dma.c +++ b/drivers/net/stmmac/dwmac100_dma.c @@ -31,14 +31,22 @@ #include "dwmac100.h" #include "dwmac_dma.h" -static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, +static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, u32 dma_tx, u32 dma_rx) { u32 value = readl(ioaddr + DMA_BUS_MODE); + int limit; + /* DMA SW reset */ value |= DMA_BUS_MODE_SFT_RESET; writel(value, ioaddr + DMA_BUS_MODE); - do {} while ((readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)); + limit = 15000; + while (limit--) { + if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) + break; + } + if (limit < 0) + return -EBUSY; /* Enable Application Access by writing to DMA CSR0 */ writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT), @@ -58,7 +66,7 @@ static int dwmac100_dma_init(unsigned long ioaddr, int pbl, u32 dma_tx, /* Store and Forward capability is not used at all.. * The transmit threshold can be programmed by * setting the TTC bits in the DMA control register.*/ -static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode, +static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode, int rxmode) { u32 csr6 = readl(ioaddr + DMA_CONTROL); @@ -73,7 +81,7 @@ static void dwmac100_dma_operation_mode(unsigned long ioaddr, int txmode, writel(csr6, ioaddr + DMA_CONTROL); } -static void dwmac100_dump_dma_regs(unsigned long ioaddr) +static void dwmac100_dump_dma_regs(void __iomem *ioaddr) { int i; @@ -91,7 +99,7 @@ static void dwmac100_dump_dma_regs(unsigned long ioaddr) /* DMA controller has two counters to track the number of * the receive missed frames. */ static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x, - unsigned long ioaddr) + void __iomem *ioaddr) { struct net_device_stats *stats = (struct net_device_stats *)data; u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR); @@ -118,7 +126,7 @@ static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x, } } -struct stmmac_dma_ops dwmac100_dma_ops = { +const struct stmmac_dma_ops dwmac100_dma_ops = { .init = dwmac100_dma_init, .dump_regs = dwmac100_dump_dma_regs, .dma_mode = dwmac100_dma_operation_mode, diff --git a/drivers/net/stmmac/dwmac_dma.h b/drivers/net/stmmac/dwmac_dma.h index 7b815a1b7b8cb82e8a9d6e85302f1ee8ac07bc4b..da3f5ccf83d300e09d1b7804717ad2c16e722977 100644 --- a/drivers/net/stmmac/dwmac_dma.h +++ b/drivers/net/stmmac/dwmac_dma.h @@ -97,12 +97,12 @@ #define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */ #define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */ -extern void dwmac_enable_dma_transmission(unsigned long ioaddr); -extern void dwmac_enable_dma_irq(unsigned long ioaddr); -extern void dwmac_disable_dma_irq(unsigned long ioaddr); -extern void dwmac_dma_start_tx(unsigned long ioaddr); -extern void dwmac_dma_stop_tx(unsigned long ioaddr); -extern void dwmac_dma_start_rx(unsigned long ioaddr); -extern void dwmac_dma_stop_rx(unsigned long ioaddr); -extern int dwmac_dma_interrupt(unsigned long ioaddr, +extern void dwmac_enable_dma_transmission(void __iomem *ioaddr); +extern void dwmac_enable_dma_irq(void __iomem *ioaddr); +extern void dwmac_disable_dma_irq(void __iomem *ioaddr); +extern void dwmac_dma_start_tx(void __iomem *ioaddr); +extern void dwmac_dma_stop_tx(void __iomem *ioaddr); +extern void dwmac_dma_start_rx(void __iomem *ioaddr); +extern void dwmac_dma_stop_rx(void __iomem *ioaddr); +extern int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x); diff --git a/drivers/net/stmmac/dwmac_lib.c b/drivers/net/stmmac/dwmac_lib.c index a85415216ef4e326a3ae21afa833c03be1ca6e52..d65fab1ba790dfd0dba7af94bbf2506fc5566d7f 100644 --- a/drivers/net/stmmac/dwmac_lib.c +++ b/drivers/net/stmmac/dwmac_lib.c @@ -32,43 +32,43 @@ #endif /* CSR1 enables the transmit DMA to check for new descriptor */ -void dwmac_enable_dma_transmission(unsigned long ioaddr) +void dwmac_enable_dma_transmission(void __iomem *ioaddr) { writel(1, ioaddr + DMA_XMT_POLL_DEMAND); } -void dwmac_enable_dma_irq(unsigned long ioaddr) +void dwmac_enable_dma_irq(void __iomem *ioaddr) { writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA); } -void dwmac_disable_dma_irq(unsigned long ioaddr) +void dwmac_disable_dma_irq(void __iomem *ioaddr) { writel(0, ioaddr + DMA_INTR_ENA); } -void dwmac_dma_start_tx(unsigned long ioaddr) +void dwmac_dma_start_tx(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_CONTROL); value |= DMA_CONTROL_ST; writel(value, ioaddr + DMA_CONTROL); } -void dwmac_dma_stop_tx(unsigned long ioaddr) +void dwmac_dma_stop_tx(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_CONTROL); value &= ~DMA_CONTROL_ST; writel(value, ioaddr + DMA_CONTROL); } -void dwmac_dma_start_rx(unsigned long ioaddr) +void dwmac_dma_start_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_CONTROL); value |= DMA_CONTROL_SR; writel(value, ioaddr + DMA_CONTROL); } -void dwmac_dma_stop_rx(unsigned long ioaddr) +void dwmac_dma_stop_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + DMA_CONTROL); value &= ~DMA_CONTROL_SR; @@ -145,7 +145,7 @@ static void show_rx_process_state(unsigned int status) } #endif -int dwmac_dma_interrupt(unsigned long ioaddr, +int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x) { int ret = 0; @@ -219,7 +219,7 @@ int dwmac_dma_interrupt(unsigned long ioaddr, return ret; } -void dwmac_dma_flush_tx_fifo(unsigned long ioaddr) +void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr) { u32 csr6 = readl(ioaddr + DMA_CONTROL); writel((csr6 | DMA_CONTROL_FTF), ioaddr + DMA_CONTROL); @@ -227,7 +227,7 @@ void dwmac_dma_flush_tx_fifo(unsigned long ioaddr) do {} while ((readl(ioaddr + DMA_CONTROL) & DMA_CONTROL_FTF)); } -void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6], +void stmmac_set_mac_addr(void __iomem *ioaddr, u8 addr[6], unsigned int high, unsigned int low) { unsigned long data; @@ -238,7 +238,7 @@ void stmmac_set_mac_addr(unsigned long ioaddr, u8 addr[6], writel(data, ioaddr + low); } -void stmmac_get_mac_addr(unsigned long ioaddr, unsigned char *addr, +void stmmac_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, unsigned int high, unsigned int low) { unsigned int hi_addr, lo_addr; diff --git a/drivers/net/stmmac/enh_desc.c b/drivers/net/stmmac/enh_desc.c index f612f986a7e16b186ba5c5c1aafcc4ae98fa2313..e5dfb6a30182a114e198d4955ac08ee303dd7f41 100644 --- a/drivers/net/stmmac/enh_desc.c +++ b/drivers/net/stmmac/enh_desc.c @@ -25,7 +25,7 @@ #include "common.h" static int enh_desc_get_tx_status(void *data, struct stmmac_extra_stats *x, - struct dma_desc *p, unsigned long ioaddr) + struct dma_desc *p, void __iomem *ioaddr) { int ret = 0; struct net_device_stats *stats = (struct net_device_stats *)data; @@ -284,7 +284,7 @@ static void enh_desc_release_tx_desc(struct dma_desc *p) { int ter = p->des01.etx.end_ring; - memset(p, 0, sizeof(struct dma_desc)); + memset(p, 0, offsetof(struct dma_desc, des2)); p->des01.etx.end_ring = ter; } @@ -318,7 +318,7 @@ static int enh_desc_get_rx_frame_len(struct dma_desc *p) return p->des01.erx.frame_length; } -struct stmmac_desc_ops enh_desc_ops = { +const struct stmmac_desc_ops enh_desc_ops = { .tx_status = enh_desc_get_tx_status, .rx_status = enh_desc_get_rx_status, .get_tx_len = enh_desc_get_tx_len, diff --git a/drivers/net/stmmac/norm_desc.c b/drivers/net/stmmac/norm_desc.c index 31ad53643792f17bf72f2815216e6ac5380b02f3..cd0cc76f7a1c8d3fbc3daf615a0c438a2880c07f 100644 --- a/drivers/net/stmmac/norm_desc.c +++ b/drivers/net/stmmac/norm_desc.c @@ -25,7 +25,7 @@ #include "common.h" static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x, - struct dma_desc *p, unsigned long ioaddr) + struct dma_desc *p, void __iomem *ioaddr) { int ret = 0; struct net_device_stats *stats = (struct net_device_stats *)data; @@ -174,22 +174,7 @@ static void ndesc_release_tx_desc(struct dma_desc *p) { int ter = p->des01.tx.end_ring; - /* clean field used within the xmit */ - p->des01.tx.first_segment = 0; - p->des01.tx.last_segment = 0; - p->des01.tx.buffer1_size = 0; - - /* clean status reported */ - p->des01.tx.error_summary = 0; - p->des01.tx.underflow_error = 0; - p->des01.tx.no_carrier = 0; - p->des01.tx.loss_carrier = 0; - p->des01.tx.excessive_deferral = 0; - p->des01.tx.excessive_collisions = 0; - p->des01.tx.late_collision = 0; - p->des01.tx.heartbeat_fail = 0; - p->des01.tx.deferred = 0; - + memset(p, 0, offsetof(struct dma_desc, des2)); /* set termination field */ p->des01.tx.end_ring = ter; } @@ -217,7 +202,7 @@ static int ndesc_get_rx_frame_len(struct dma_desc *p) return p->des01.rx.frame_length; } -struct stmmac_desc_ops ndesc_ops = { +const struct stmmac_desc_ops ndesc_ops = { .tx_status = ndesc_get_tx_status, .rx_status = ndesc_get_rx_status, .get_tx_len = ndesc_get_tx_len, diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h index ebebc644b1b8cf7b503fb07ef137cdf323d70a2c..79bdc2e1322489d4fc226409b4f3bb50f549bf48 100644 --- a/drivers/net/stmmac/stmmac.h +++ b/drivers/net/stmmac/stmmac.h @@ -21,6 +21,7 @@ *******************************************************************************/ #define DRV_MODULE_VERSION "Apr_2010" +#include #include #include "common.h" @@ -50,10 +51,10 @@ struct stmmac_priv { int is_gmac; dma_addr_t dma_rx_phy; unsigned int dma_rx_size; - int rx_csum; unsigned int dma_buf_sz; struct device *device; struct mac_device_info *hw; + void __iomem *ioaddr; struct stmmac_extra_stats xstats; struct napi_struct napi; @@ -65,7 +66,7 @@ struct stmmac_priv { int phy_mask; int (*phy_reset) (void *priv); void (*fix_mac_speed) (void *priv, unsigned int speed); - void (*bus_setup)(unsigned long ioaddr); + void (*bus_setup)(void __iomem *ioaddr); void *bsp_priv; int phy_irq; @@ -76,6 +77,7 @@ struct stmmac_priv { unsigned int flow_ctrl; unsigned int pause; struct mii_bus *mii; + int mii_clk_csr; u32 msg_enable; spinlock_t lock; @@ -89,6 +91,9 @@ struct stmmac_priv { struct vlan_group *vlgrp; #endif int enh_desc; + int rx_coe; + int bugged_jumbo; + int no_csum_insertion; }; #ifdef CONFIG_STM_DRIVERS @@ -116,5 +121,5 @@ static inline int stmmac_claim_resource(struct platform_device *pdev) extern int stmmac_mdio_unregister(struct net_device *ndev); extern int stmmac_mdio_register(struct net_device *ndev); extern void stmmac_set_ethtool_ops(struct net_device *netdev); -extern struct stmmac_desc_ops enh_desc_ops; -extern struct stmmac_desc_ops ndesc_ops; +extern const struct stmmac_desc_ops enh_desc_ops; +extern const struct stmmac_desc_ops ndesc_ops; diff --git a/drivers/net/stmmac/stmmac_ethtool.c b/drivers/net/stmmac/stmmac_ethtool.c index f080509923f03eae4f787e9fc5615e1f9e03f2f5..6d65482e789a3639aa310da5d048ea19232022eb 100644 --- a/drivers/net/stmmac/stmmac_ethtool.c +++ b/drivers/net/stmmac/stmmac_ethtool.c @@ -89,8 +89,8 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { }; #define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats) -void stmmac_ethtool_getdrvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) +static void stmmac_ethtool_getdrvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) { struct stmmac_priv *priv = netdev_priv(dev); @@ -104,7 +104,8 @@ void stmmac_ethtool_getdrvinfo(struct net_device *dev, info->n_stats = STMMAC_STATS_LEN; } -int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) +static int stmmac_ethtool_getsettings(struct net_device *dev, + struct ethtool_cmd *cmd) { struct stmmac_priv *priv = netdev_priv(dev); struct phy_device *phy = priv->phydev; @@ -126,7 +127,8 @@ int stmmac_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) return rc; } -int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) +static int stmmac_ethtool_setsettings(struct net_device *dev, + struct ethtool_cmd *cmd) { struct stmmac_priv *priv = netdev_priv(dev); struct phy_device *phy = priv->phydev; @@ -139,32 +141,32 @@ int stmmac_ethtool_setsettings(struct net_device *dev, struct ethtool_cmd *cmd) return rc; } -u32 stmmac_ethtool_getmsglevel(struct net_device *dev) +static u32 stmmac_ethtool_getmsglevel(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); return priv->msg_enable; } -void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level) +static void stmmac_ethtool_setmsglevel(struct net_device *dev, u32 level) { struct stmmac_priv *priv = netdev_priv(dev); priv->msg_enable = level; } -int stmmac_check_if_running(struct net_device *dev) +static int stmmac_check_if_running(struct net_device *dev) { if (!netif_running(dev)) return -EBUSY; return 0; } -int stmmac_ethtool_get_regs_len(struct net_device *dev) +static int stmmac_ethtool_get_regs_len(struct net_device *dev) { return REG_SPACE_SIZE; } -void stmmac_ethtool_gregs(struct net_device *dev, +static void stmmac_ethtool_gregs(struct net_device *dev, struct ethtool_regs *regs, void *space) { int i; @@ -177,25 +179,25 @@ void stmmac_ethtool_gregs(struct net_device *dev, if (!priv->is_gmac) { /* MAC registers */ for (i = 0; i < 12; i++) - reg_space[i] = readl(dev->base_addr + (i * 4)); + reg_space[i] = readl(priv->ioaddr + (i * 4)); /* DMA registers */ for (i = 0; i < 9; i++) reg_space[i + 12] = - readl(dev->base_addr + (DMA_BUS_MODE + (i * 4))); - reg_space[22] = readl(dev->base_addr + DMA_CUR_TX_BUF_ADDR); - reg_space[23] = readl(dev->base_addr + DMA_CUR_RX_BUF_ADDR); + readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4))); + reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR); + reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR); } else { /* MAC registers */ for (i = 0; i < 55; i++) - reg_space[i] = readl(dev->base_addr + (i * 4)); + reg_space[i] = readl(priv->ioaddr + (i * 4)); /* DMA registers */ for (i = 0; i < 22; i++) reg_space[i + 55] = - readl(dev->base_addr + (DMA_BUS_MODE + (i * 4))); + readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4))); } } -int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data) +static int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data) { if (data) netdev->features |= NETIF_F_HW_CSUM; @@ -205,11 +207,11 @@ int stmmac_ethtool_set_tx_csum(struct net_device *netdev, u32 data) return 0; } -u32 stmmac_ethtool_get_rx_csum(struct net_device *dev) +static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); - return priv->rx_csum; + return priv->rx_coe; } static void @@ -263,11 +265,9 @@ stmmac_set_pauseparam(struct net_device *netdev, cmd.phy_address = phy->addr; ret = phy_ethtool_sset(phy, &cmd); } - } else { - unsigned long ioaddr = netdev->base_addr; - priv->hw->mac->flow_ctrl(ioaddr, phy->duplex, + } else + priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex, priv->flow_ctrl, priv->pause); - } spin_unlock(&priv->lock); return ret; } @@ -276,12 +276,11 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 *data) { struct stmmac_priv *priv = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; int i; /* Update HW stats if supported */ priv->hw->dma->dma_diagnostic_fr(&dev->stats, (void *) &priv->xstats, - ioaddr); + priv->ioaddr); for (i = 0; i < STMMAC_STATS_LEN; i++) { char *p = (char *)priv + stmmac_gstrings_stats[i].stat_offset; @@ -325,7 +324,7 @@ static void stmmac_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct stmmac_priv *priv = netdev_priv(dev); spin_lock_irq(&priv->lock); - if (priv->wolenabled == PMT_SUPPORTED) { + if (device_can_wakeup(priv->device)) { wol->supported = WAKE_MAGIC; wol->wolopts = priv->wolopts; } @@ -337,16 +336,20 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct stmmac_priv *priv = netdev_priv(dev); u32 support = WAKE_MAGIC; - if (priv->wolenabled == PMT_NOT_SUPPORTED) + if (!device_can_wakeup(priv->device)) return -EINVAL; if (wol->wolopts & ~support) return -EINVAL; - if (wol->wolopts == 0) - device_set_wakeup_enable(priv->device, 0); - else + if (wol->wolopts) { + pr_info("stmmac: wakeup enable\n"); device_set_wakeup_enable(priv->device, 1); + enable_irq_wake(dev->irq); + } else { + device_set_wakeup_enable(priv->device, 0); + disable_irq_wake(dev->irq); + } spin_lock_irq(&priv->lock); priv->wolopts = wol->wolopts; @@ -377,10 +380,8 @@ static struct ethtool_ops stmmac_ethtool_ops = { .get_wol = stmmac_get_wol, .set_wol = stmmac_set_wol, .get_sset_count = stmmac_get_sset_count, -#ifdef NETIF_F_TSO .get_tso = ethtool_op_get_tso, .set_tso = ethtool_op_set_tso, -#endif }; void stmmac_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index ea0461eb2dbe4314c223ab2ad47f17ea9b90e740..823b9e6431d5f29a3b23a45be8bdbda962a61565 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c @@ -134,13 +134,6 @@ static int buf_sz = DMA_BUFFER_SIZE; module_param(buf_sz, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(buf_sz, "DMA buffer size"); -/* In case of Giga ETH, we can enable/disable the COE for the - * transmit HW checksum computation. - * Note that, if tx csum is off in HW, SG will be still supported. */ -static int tx_coe = HW_CSUM; -module_param(tx_coe, int, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(tx_coe, "GMAC COE type 2 [on/off]"); - static const u32 default_msg_level = (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN | NETIF_MSG_TIMER); @@ -202,7 +195,6 @@ static void stmmac_adjust_link(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); struct phy_device *phydev = priv->phydev; - unsigned long ioaddr = dev->base_addr; unsigned long flags; int new_state = 0; unsigned int fc = priv->flow_ctrl, pause_time = priv->pause; @@ -215,7 +207,7 @@ static void stmmac_adjust_link(struct net_device *dev) spin_lock_irqsave(&priv->lock, flags); if (phydev->link) { - u32 ctrl = readl(ioaddr + MAC_CTRL_REG); + u32 ctrl = readl(priv->ioaddr + MAC_CTRL_REG); /* Now we make sure that we can be in full duplex mode. * If not, we operate in half-duplex mode. */ @@ -229,7 +221,7 @@ static void stmmac_adjust_link(struct net_device *dev) } /* Flow Control operation */ if (phydev->pause) - priv->hw->mac->flow_ctrl(ioaddr, phydev->duplex, + priv->hw->mac->flow_ctrl(priv->ioaddr, phydev->duplex, fc, pause_time); if (phydev->speed != priv->speed) { @@ -238,6 +230,9 @@ static void stmmac_adjust_link(struct net_device *dev) case 1000: if (likely(priv->is_gmac)) ctrl &= ~priv->hw->link.port; + if (likely(priv->fix_mac_speed)) + priv->fix_mac_speed(priv->bsp_priv, + phydev->speed); break; case 100: case 10: @@ -265,7 +260,7 @@ static void stmmac_adjust_link(struct net_device *dev) priv->speed = phydev->speed; } - writel(ctrl, ioaddr + MAC_CTRL_REG); + writel(ctrl, priv->ioaddr + MAC_CTRL_REG); if (!priv->oldlink) { new_state = 1; @@ -342,7 +337,7 @@ static int stmmac_init_phy(struct net_device *dev) return 0; } -static inline void stmmac_mac_enable_rx(unsigned long ioaddr) +static inline void stmmac_mac_enable_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); value |= MAC_RNABLE_RX; @@ -350,7 +345,7 @@ static inline void stmmac_mac_enable_rx(unsigned long ioaddr) writel(value, ioaddr + MAC_CTRL_REG); } -static inline void stmmac_mac_enable_tx(unsigned long ioaddr) +static inline void stmmac_mac_enable_tx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); value |= MAC_ENABLE_TX; @@ -358,14 +353,14 @@ static inline void stmmac_mac_enable_tx(unsigned long ioaddr) writel(value, ioaddr + MAC_CTRL_REG); } -static inline void stmmac_mac_disable_rx(unsigned long ioaddr) +static inline void stmmac_mac_disable_rx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); value &= ~MAC_RNABLE_RX; writel(value, ioaddr + MAC_CTRL_REG); } -static inline void stmmac_mac_disable_tx(unsigned long ioaddr) +static inline void stmmac_mac_disable_tx(void __iomem *ioaddr) { u32 value = readl(ioaddr + MAC_CTRL_REG); value &= ~MAC_ENABLE_TX; @@ -567,29 +562,22 @@ static void free_dma_desc_resources(struct stmmac_priv *priv) * stmmac_dma_operation_mode - HW DMA operation mode * @priv : pointer to the private device structure. * Description: it sets the DMA operation mode: tx/rx DMA thresholds - * or Store-And-Forward capability. It also verifies the COE for the - * transmission in case of Giga ETH. + * or Store-And-Forward capability. */ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) { - if (!priv->is_gmac) { - /* MAC 10/100 */ - priv->hw->dma->dma_mode(priv->dev->base_addr, tc, 0); - priv->tx_coe = NO_HW_CSUM; - } else { - if ((priv->dev->mtu <= ETH_DATA_LEN) && (tx_coe)) { - priv->hw->dma->dma_mode(priv->dev->base_addr, - SF_DMA_MODE, SF_DMA_MODE); - tc = SF_DMA_MODE; - priv->tx_coe = HW_CSUM; - } else { - /* Checksum computation is performed in software. */ - priv->hw->dma->dma_mode(priv->dev->base_addr, tc, - SF_DMA_MODE); - priv->tx_coe = NO_HW_CSUM; - } - } - tx_coe = priv->tx_coe; + if (likely((priv->tx_coe) && (!priv->no_csum_insertion))) { + /* In case of GMAC, SF mode has to be enabled + * to perform the TX COE. This depends on: + * 1) TX COE if actually supported + * 2) There is no bugged Jumbo frame support + * that needs to not insert csum in the TDES. + */ + priv->hw->dma->dma_mode(priv->ioaddr, + SF_DMA_MODE, SF_DMA_MODE); + tc = SF_DMA_MODE; + } else + priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); } /** @@ -600,7 +588,6 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv) static void stmmac_tx(struct stmmac_priv *priv) { unsigned int txsize = priv->dma_tx_size; - unsigned long ioaddr = priv->dev->base_addr; while (priv->dirty_tx != priv->cur_tx) { int last; @@ -618,7 +605,7 @@ static void stmmac_tx(struct stmmac_priv *priv) int tx_error = priv->hw->desc->tx_status(&priv->dev->stats, &priv->xstats, p, - ioaddr); + priv->ioaddr); if (likely(tx_error == 0)) { priv->dev->stats.tx_packets++; priv->xstats.tx_pkt_n++; @@ -674,7 +661,7 @@ static inline void stmmac_enable_irq(struct stmmac_priv *priv) priv->tm->timer_start(tmrate); else #endif - priv->hw->dma->enable_dma_irq(priv->dev->base_addr); + priv->hw->dma->enable_dma_irq(priv->ioaddr); } static inline void stmmac_disable_irq(struct stmmac_priv *priv) @@ -684,7 +671,7 @@ static inline void stmmac_disable_irq(struct stmmac_priv *priv) priv->tm->timer_stop(); else #endif - priv->hw->dma->disable_dma_irq(priv->dev->base_addr); + priv->hw->dma->disable_dma_irq(priv->ioaddr); } static int stmmac_has_work(struct stmmac_priv *priv) @@ -739,14 +726,15 @@ static void stmmac_no_timer_stopped(void) */ static void stmmac_tx_err(struct stmmac_priv *priv) { + netif_stop_queue(priv->dev); - priv->hw->dma->stop_tx(priv->dev->base_addr); + priv->hw->dma->stop_tx(priv->ioaddr); dma_free_tx_skbufs(priv); priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); priv->dirty_tx = 0; priv->cur_tx = 0; - priv->hw->dma->start_tx(priv->dev->base_addr); + priv->hw->dma->start_tx(priv->ioaddr); priv->dev->stats.tx_errors++; netif_wake_queue(priv->dev); @@ -755,11 +743,9 @@ static void stmmac_tx_err(struct stmmac_priv *priv) static void stmmac_dma_interrupt(struct stmmac_priv *priv) { - unsigned long ioaddr = priv->dev->base_addr; int status; - status = priv->hw->dma->dma_interrupt(priv->dev->base_addr, - &priv->xstats); + status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); if (likely(status == handle_tx_rx)) _stmmac_schedule(priv); @@ -767,7 +753,7 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv) /* Try to bump up the dma threshold on this failure */ if (unlikely(tc != SF_DMA_MODE) && (tc <= 256)) { tc += 64; - priv->hw->dma->dma_mode(ioaddr, tc, SF_DMA_MODE); + priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); priv->xstats.threshold = tc; } stmmac_tx_err(priv); @@ -787,7 +773,6 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv) static int stmmac_open(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; int ret; /* Check that the MAC address is valid. If its not, refuse @@ -843,7 +828,8 @@ static int stmmac_open(struct net_device *dev) init_dma_desc_rings(dev); /* DMA initialization and SW reset */ - if (unlikely(priv->hw->dma->init(ioaddr, priv->pbl, priv->dma_tx_phy, + if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->pbl, + priv->dma_tx_phy, priv->dma_rx_phy) < 0)) { pr_err("%s: DMA initialization failed\n", __func__); @@ -851,22 +837,28 @@ static int stmmac_open(struct net_device *dev) } /* Copy the MAC addr into the HW */ - priv->hw->mac->set_umac_addr(ioaddr, dev->dev_addr, 0); + priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); /* If required, perform hw setup of the bus. */ if (priv->bus_setup) - priv->bus_setup(ioaddr); + priv->bus_setup(priv->ioaddr); /* Initialize the MAC Core */ - priv->hw->mac->core_init(ioaddr); + priv->hw->mac->core_init(priv->ioaddr); + + priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); + if (priv->rx_coe) + pr_info("stmmac: Rx Checksum Offload Engine supported\n"); + if (priv->tx_coe) + pr_info("\tTX Checksum insertion supported\n"); priv->shutdown = 0; /* Initialise the MMC (if present) to disable all interrupts. */ - writel(0xffffffff, ioaddr + MMC_HIGH_INTR_MASK); - writel(0xffffffff, ioaddr + MMC_LOW_INTR_MASK); + writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK); + writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK); /* Enable the MAC Rx/Tx */ - stmmac_mac_enable_rx(ioaddr); - stmmac_mac_enable_tx(ioaddr); + stmmac_mac_enable_rx(priv->ioaddr); + stmmac_mac_enable_tx(priv->ioaddr); /* Set the HW DMA mode and the COE */ stmmac_dma_operation_mode(priv); @@ -877,16 +869,16 @@ static int stmmac_open(struct net_device *dev) /* Start the ball rolling... */ DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); - priv->hw->dma->start_tx(ioaddr); - priv->hw->dma->start_rx(ioaddr); + priv->hw->dma->start_tx(priv->ioaddr); + priv->hw->dma->start_rx(priv->ioaddr); #ifdef CONFIG_STMMAC_TIMER priv->tm->timer_start(tmrate); #endif /* Dump DMA/MAC registers */ if (netif_msg_hw(priv)) { - priv->hw->mac->dump_regs(ioaddr); - priv->hw->dma->dump_regs(ioaddr); + priv->hw->mac->dump_regs(priv->ioaddr); + priv->hw->dma->dump_regs(priv->ioaddr); } if (priv->phydev) @@ -930,15 +922,15 @@ static int stmmac_release(struct net_device *dev) free_irq(dev->irq, dev); /* Stop TX/RX DMA and clear the descriptors */ - priv->hw->dma->stop_tx(dev->base_addr); - priv->hw->dma->stop_rx(dev->base_addr); + priv->hw->dma->stop_tx(priv->ioaddr); + priv->hw->dma->stop_rx(priv->ioaddr); /* Release and free the Rx/Tx resources */ free_dma_desc_resources(priv); /* Disable the MAC core */ - stmmac_mac_disable_tx(dev->base_addr); - stmmac_mac_disable_rx(dev->base_addr); + stmmac_mac_disable_tx(priv->ioaddr); + stmmac_mac_disable_rx(priv->ioaddr); netif_carrier_off(dev); @@ -1066,7 +1058,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) return stmmac_sw_tso(priv, skb); if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) { - if (likely(priv->tx_coe == NO_HW_CSUM)) + if (unlikely((!priv->tx_coe) || (priv->no_csum_insertion))) skb_checksum_help(skb); else csum_insertion = 1; @@ -1140,7 +1132,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) dev->stats.tx_bytes += skb->len; - priv->hw->dma->enable_dma_transmission(dev->base_addr); + priv->hw->dma->enable_dma_transmission(priv->ioaddr); return NETDEV_TX_OK; } @@ -1256,7 +1248,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit) if (unlikely(status == csum_none)) { /* always for the old mac 10/100 */ - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); netif_receive_skb(skb); } else { skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -1390,6 +1382,15 @@ static int stmmac_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; } + /* Some GMAC devices have a bugged Jumbo frame support that + * needs to have the Tx COE disabled for oversized frames + * (due to limited buffer sizes). In this case we disable + * the TX csum insertionin the TDES and not use SF. */ + if ((priv->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN)) + priv->no_csum_insertion = 1; + else + priv->no_csum_insertion = 0; + dev->mtu = new_mtu; return 0; @@ -1405,11 +1406,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id) return IRQ_NONE; } - if (priv->is_gmac) { - unsigned long ioaddr = dev->base_addr; + if (priv->is_gmac) /* To handle GMAC own interrupts */ - priv->hw->mac->host_irq_status(ioaddr); - } + priv->hw->mac->host_irq_status((void __iomem *) dev->base_addr); stmmac_dma_interrupt(priv); @@ -1512,9 +1511,6 @@ static int stmmac_probe(struct net_device *dev) #endif priv->msg_enable = netif_msg_init(debug, default_msg_level); - if (priv->is_gmac) - priv->rx_csum = 1; - if (flow_ctrl) priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ @@ -1522,7 +1518,8 @@ static int stmmac_probe(struct net_device *dev) netif_napi_add(dev, &priv->napi, stmmac_poll, 64); /* Get the MAC address */ - priv->hw->mac->get_umac_addr(dev->base_addr, dev->dev_addr, 0); + priv->hw->mac->get_umac_addr((void __iomem *) dev->base_addr, + dev->dev_addr, 0); if (!is_valid_ether_addr(dev->dev_addr)) pr_warning("\tno valid MAC address;" @@ -1552,14 +1549,13 @@ static int stmmac_probe(struct net_device *dev) static int stmmac_mac_device_setup(struct net_device *dev) { struct stmmac_priv *priv = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; struct mac_device_info *device; if (priv->is_gmac) - device = dwmac1000_setup(ioaddr); + device = dwmac1000_setup(priv->ioaddr); else - device = dwmac100_setup(ioaddr); + device = dwmac100_setup(priv->ioaddr); if (!device) return -ENOMEM; @@ -1572,9 +1568,8 @@ static int stmmac_mac_device_setup(struct net_device *dev) priv->hw = device; - priv->wolenabled = priv->hw->pmt; /* PMT supported */ - if (priv->wolenabled == PMT_SUPPORTED) - priv->wolopts = WAKE_MAGIC; /* Magic Frame */ + if (device_can_wakeup(priv->device)) + priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ return 0; } @@ -1653,7 +1648,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) { int ret = 0; struct resource *res; - unsigned int *addr = NULL; + void __iomem *addr = NULL; struct net_device *ndev = NULL; struct stmmac_priv *priv; struct plat_stmmacenet_data *plat_dat; @@ -1664,7 +1659,7 @@ static int stmmac_dvr_probe(struct platform_device *pdev) ret = -ENODEV; goto out; } - pr_info("done!\n"); + pr_info("\tdone!\n"); if (!request_mem_region(res->start, resource_size(res), pdev->name)) { @@ -1706,8 +1701,18 @@ static int stmmac_dvr_probe(struct platform_device *pdev) plat_dat = pdev->dev.platform_data; priv->bus_id = plat_dat->bus_id; priv->pbl = plat_dat->pbl; /* TLI */ + priv->mii_clk_csr = plat_dat->clk_csr; + priv->tx_coe = plat_dat->tx_coe; + priv->bugged_jumbo = plat_dat->bugged_jumbo; priv->is_gmac = plat_dat->has_gmac; /* GMAC is on board */ priv->enh_desc = plat_dat->enh_desc; + priv->ioaddr = addr; + + /* PMT module is not integrated in all the MAC devices. */ + if (plat_dat->pmt) { + pr_info("\tPMT module supported\n"); + device_set_wakeup_capable(&pdev->dev, 1); + } platform_set_drvdata(pdev, ndev); @@ -1743,8 +1748,8 @@ static int stmmac_dvr_probe(struct platform_device *pdev) priv->bsp_priv = plat_dat->bsp_priv; pr_info("\t%s - (dev. name: %s - id: %d, IRQ #%d\n" - "\tIO base addr: 0x%08x)\n", ndev->name, pdev->name, - pdev->id, ndev->irq, (unsigned int)addr); + "\tIO base addr: 0x%p)\n", ndev->name, pdev->name, + pdev->id, ndev->irq, addr); /* MDIO bus Registration */ pr_debug("\tMDIO bus (id: %d)...", priv->bus_id); @@ -1779,11 +1784,11 @@ static int stmmac_dvr_remove(struct platform_device *pdev) pr_info("%s:\n\tremoving driver", __func__); - priv->hw->dma->stop_rx(ndev->base_addr); - priv->hw->dma->stop_tx(ndev->base_addr); + priv->hw->dma->stop_rx(priv->ioaddr); + priv->hw->dma->stop_tx(priv->ioaddr); - stmmac_mac_disable_rx(ndev->base_addr); - stmmac_mac_disable_tx(ndev->base_addr); + stmmac_mac_disable_rx(priv->ioaddr); + stmmac_mac_disable_tx(priv->ioaddr); netif_carrier_off(ndev); @@ -1792,7 +1797,7 @@ static int stmmac_dvr_remove(struct platform_device *pdev) platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); - iounmap((void *)ndev->base_addr); + iounmap((void *)priv->ioaddr); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); @@ -1827,23 +1832,20 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) napi_disable(&priv->napi); /* Stop TX/RX DMA */ - priv->hw->dma->stop_tx(dev->base_addr); - priv->hw->dma->stop_rx(dev->base_addr); + priv->hw->dma->stop_tx(priv->ioaddr); + priv->hw->dma->stop_rx(priv->ioaddr); /* Clear the Rx/Tx descriptors */ priv->hw->desc->init_rx_desc(priv->dma_rx, priv->dma_rx_size, dis_ic); priv->hw->desc->init_tx_desc(priv->dma_tx, priv->dma_tx_size); - stmmac_mac_disable_tx(dev->base_addr); + stmmac_mac_disable_tx(priv->ioaddr); - if (device_may_wakeup(&(pdev->dev))) { - /* Enable Power down mode by programming the PMT regs */ - if (priv->wolenabled == PMT_SUPPORTED) - priv->hw->mac->pmt(dev->base_addr, - priv->wolopts); - } else { - stmmac_mac_disable_rx(dev->base_addr); - } + /* Enable Power down mode by programming the PMT regs */ + if (device_can_wakeup(priv->device)) + priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); + else + stmmac_mac_disable_rx(priv->ioaddr); } else { priv->shutdown = 1; /* Although this can appear slightly redundant it actually @@ -1860,7 +1862,6 @@ static int stmmac_resume(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct stmmac_priv *priv = netdev_priv(dev); - unsigned long ioaddr = dev->base_addr; if (!netif_running(dev)) return 0; @@ -1879,17 +1880,16 @@ static int stmmac_resume(struct platform_device *pdev) * is received. Anyway, it's better to manually clear * this bit because it can generate problems while resuming * from another devices (e.g. serial console). */ - if (device_may_wakeup(&(pdev->dev))) - if (priv->wolenabled == PMT_SUPPORTED) - priv->hw->mac->pmt(dev->base_addr, 0); + if (device_can_wakeup(priv->device)) + priv->hw->mac->pmt(priv->ioaddr, 0); netif_device_attach(dev); /* Enable the MAC and DMA */ - stmmac_mac_enable_rx(ioaddr); - stmmac_mac_enable_tx(ioaddr); - priv->hw->dma->start_tx(ioaddr); - priv->hw->dma->start_rx(ioaddr); + stmmac_mac_enable_rx(priv->ioaddr); + stmmac_mac_enable_tx(priv->ioaddr); + priv->hw->dma->start_tx(priv->ioaddr); + priv->hw->dma->start_rx(priv->ioaddr); #ifdef CONFIG_STMMAC_TIMER priv->tm->timer_start(tmrate); @@ -1968,8 +1968,6 @@ static int __init stmmac_cmdline_opt(char *str) strict_strtoul(opt + 7, 0, (unsigned long *)&buf_sz); else if (!strncmp(opt, "tc:", 3)) strict_strtoul(opt + 3, 0, (unsigned long *)&tc); - else if (!strncmp(opt, "tx_coe:", 7)) - strict_strtoul(opt + 7, 0, (unsigned long *)&tx_coe); else if (!strncmp(opt, "watchdog:", 9)) strict_strtoul(opt + 9, 0, (unsigned long *)&watchdog); else if (!strncmp(opt, "flow_ctrl:", 10)) diff --git a/drivers/net/stmmac/stmmac_mdio.c b/drivers/net/stmmac/stmmac_mdio.c index 40b2c79297192455e954ad73f7ea195709fc56e1..d7441616357d292a7f67d4777299dd74025a8ca4 100644 --- a/drivers/net/stmmac/stmmac_mdio.c +++ b/drivers/net/stmmac/stmmac_mdio.c @@ -47,21 +47,20 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg) { struct net_device *ndev = bus->priv; struct stmmac_priv *priv = netdev_priv(ndev); - unsigned long ioaddr = ndev->base_addr; unsigned int mii_address = priv->hw->mii.addr; unsigned int mii_data = priv->hw->mii.data; int data; u16 regValue = (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))); - regValue |= MII_BUSY; /* in case of GMAC */ + regValue |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2); - do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1); - writel(regValue, ioaddr + mii_address); - do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1); + do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); + writel(regValue, priv->ioaddr + mii_address); + do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); /* Read the data from the MII data register */ - data = (int)readl(ioaddr + mii_data); + data = (int)readl(priv->ioaddr + mii_data); return data; } @@ -79,7 +78,6 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, { struct net_device *ndev = bus->priv; struct stmmac_priv *priv = netdev_priv(ndev); - unsigned long ioaddr = ndev->base_addr; unsigned int mii_address = priv->hw->mii.addr; unsigned int mii_data = priv->hw->mii.data; @@ -87,17 +85,18 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg, (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0))) | MII_WRITE; - value |= MII_BUSY; + value |= MII_BUSY | ((priv->mii_clk_csr & 7) << 2); + /* Wait until any existing MII operation is complete */ - do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1); + do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); /* Set the MII address register to write */ - writel(phydata, ioaddr + mii_data); - writel(value, ioaddr + mii_address); + writel(phydata, priv->ioaddr + mii_data); + writel(value, priv->ioaddr + mii_address); /* Wait until any existing MII operation is complete */ - do {} while (((readl(ioaddr + mii_address)) & MII_BUSY) == 1); + do {} while (((readl(priv->ioaddr + mii_address)) & MII_BUSY) == 1); return 0; } @@ -111,7 +110,6 @@ static int stmmac_mdio_reset(struct mii_bus *bus) { struct net_device *ndev = bus->priv; struct stmmac_priv *priv = netdev_priv(ndev); - unsigned long ioaddr = ndev->base_addr; unsigned int mii_address = priv->hw->mii.addr; if (priv->phy_reset) { @@ -123,7 +121,7 @@ static int stmmac_mdio_reset(struct mii_bus *bus) * It doesn't complete its reset until at least one clock cycle * on MDC, so perform a dummy mdio read. */ - writel(0, ioaddr + mii_address); + writel(0, priv->ioaddr + mii_address); return 0; } diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c index 358c22f9acbef8e4978cf8cc0969123dbe9c3974..7d9ec23aabf6b22be99a01d2d7526d5e6cc23cda 100644 --- a/drivers/net/sun3lance.c +++ b/drivers/net/sun3lance.c @@ -436,7 +436,7 @@ static int lance_open( struct net_device *dev ) DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", dev->name, i, DREG )); DREG = CSR0_STOP; - return( -EIO ); + return -EIO; } DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA; @@ -445,7 +445,7 @@ static int lance_open( struct net_device *dev ) DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); - return( 0 ); + return 0; } diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 618643e3ca3ed36b64cc405e352d21babb35599f..0a6a5ced3c1cc88d71f0a3fce501b6b14cebf4e3 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -617,7 +617,7 @@ static void bigmac_begin_auto_negotiation(struct bigmac *bp) bp->timer_ticks = 0; bp->bigmac_timer.expires = jiffies + (12 * HZ) / 10; bp->bigmac_timer.data = (unsigned long) bp; - bp->bigmac_timer.function = &bigmac_timer; + bp->bigmac_timer.function = bigmac_timer; add_timer(&bp->bigmac_timer); } diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 2678588ea4b201bdd6a1c9395f5abeeae9d9216f..3ed2a67bd6d36c5da4608570bc8d494faa614f59 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -96,16 +96,10 @@ static char *media[MAX_UNITS]; #include #include #include -#ifndef _COMPAT_WITH_OLD_KERNEL +#include #include #include #include -#else -#include "crc32.h" -#include "ethtool.h" -#include "mii.h" -#include "compat.h" -#endif /* These identify the driver base version and may not be removed. */ static const char version[] __devinitconst = @@ -369,9 +363,21 @@ struct netdev_private { dma_addr_t tx_ring_dma; dma_addr_t rx_ring_dma; struct timer_list timer; /* Media monitoring timer. */ + /* ethtool extra stats */ + struct { + u64 tx_multiple_collisions; + u64 tx_single_collisions; + u64 tx_late_collisions; + u64 tx_deferred; + u64 tx_deferred_excessive; + u64 tx_aborted; + u64 tx_bcasts; + u64 rx_bcasts; + u64 tx_mcasts; + u64 rx_mcasts; + } xstats; /* Frequently used values: keep some adjacent for cache effect. */ spinlock_t lock; - spinlock_t rx_lock; /* Group with Tx control cache line. */ int msg_enable; int chip_id; unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */ @@ -396,6 +402,7 @@ struct netdev_private { unsigned char phys[MII_CNT]; /* MII device addresses, only first one used. */ struct pci_dev *pci_dev; void __iomem *base; + spinlock_t statlock; }; /* The station address location in the EEPROM. */ @@ -520,16 +527,19 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, np->chip_id = chip_idx; np->msg_enable = (1 << debug) - 1; spin_lock_init(&np->lock); + spin_lock_init(&np->statlock); tasklet_init(&np->rx_tasklet, rx_poll, (unsigned long)dev); tasklet_init(&np->tx_tasklet, tx_poll, (unsigned long)dev); - ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma); + ring_space = dma_alloc_coherent(&pdev->dev, TX_TOTAL_SIZE, + &ring_dma, GFP_KERNEL); if (!ring_space) goto err_out_cleardev; np->tx_ring = (struct netdev_desc *)ring_space; np->tx_ring_dma = ring_dma; - ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma); + ring_space = dma_alloc_coherent(&pdev->dev, RX_TOTAL_SIZE, + &ring_dma, GFP_KERNEL); if (!ring_space) goto err_out_unmap_tx; np->rx_ring = (struct netdev_desc *)ring_space; @@ -663,9 +673,11 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev, err_out_unregister: unregister_netdev(dev); err_out_unmap_rx: - pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma); + dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, + np->rx_ring, np->rx_ring_dma); err_out_unmap_tx: - pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma); + dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, + np->tx_ring, np->tx_ring_dma); err_out_cleardev: pci_set_drvdata(pdev, NULL); pci_iounmap(pdev, ioaddr); @@ -874,7 +886,7 @@ static int netdev_open(struct net_device *dev) init_timer(&np->timer); np->timer.expires = jiffies + 3*HZ; np->timer.data = (unsigned long)dev; - np->timer.function = &netdev_timer; /* timer handler */ + np->timer.function = netdev_timer; /* timer handler */ add_timer(&np->timer); /* Enable interrupts by setting the interrupt mask. */ @@ -1011,8 +1023,14 @@ static void init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ np->rx_ring[i].frag[0].addr = cpu_to_le32( - pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, - PCI_DMA_FROMDEVICE)); + dma_map_single(&np->pci_dev->dev, skb->data, + np->rx_buf_sz, DMA_FROM_DEVICE)); + if (dma_mapping_error(&np->pci_dev->dev, + np->rx_ring[i].frag[0].addr)) { + dev_kfree_skb(skb); + np->rx_skbuff[i] = NULL; + break; + } np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag); } np->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1063,9 +1081,11 @@ start_tx (struct sk_buff *skb, struct net_device *dev) txdesc->next_desc = 0; txdesc->status = cpu_to_le32 ((entry << 2) | DisableAlign); - txdesc->frag[0].addr = cpu_to_le32 (pci_map_single (np->pci_dev, skb->data, - skb->len, - PCI_DMA_TODEVICE)); + txdesc->frag[0].addr = cpu_to_le32(dma_map_single(&np->pci_dev->dev, + skb->data, skb->len, DMA_TO_DEVICE)); + if (dma_mapping_error(&np->pci_dev->dev, + txdesc->frag[0].addr)) + goto drop_frame; txdesc->frag[0].length = cpu_to_le32 (skb->len | LastFrag); /* Increment cur_tx before tasklet_schedule() */ @@ -1087,6 +1107,12 @@ start_tx (struct sk_buff *skb, struct net_device *dev) dev->name, np->cur_tx, entry); } return NETDEV_TX_OK; + +drop_frame: + dev_kfree_skb(skb); + np->tx_skbuff[entry] = NULL; + dev->stats.tx_dropped++; + return NETDEV_TX_OK; } /* Reset hardware tx and free all of tx buffers */ @@ -1097,7 +1123,6 @@ reset_tx (struct net_device *dev) void __iomem *ioaddr = np->base; struct sk_buff *skb; int i; - int irq = in_interrupt(); /* Reset tx logic, TxListPtr will be cleaned */ iowrite16 (TxDisable, ioaddr + MACCtrl1); @@ -1109,13 +1134,10 @@ reset_tx (struct net_device *dev) skb = np->tx_skbuff[i]; if (skb) { - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[i].frag[0].addr), - skb->len, PCI_DMA_TODEVICE); - if (irq) - dev_kfree_skb_irq (skb); - else - dev_kfree_skb (skb); + skb->len, DMA_TO_DEVICE); + dev_kfree_skb_any(skb); np->tx_skbuff[i] = NULL; dev->stats.tx_dropped++; } @@ -1233,9 +1255,9 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) break; skb = np->tx_skbuff[entry]; /* Free the original skb. */ - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[entry].frag[0].addr), - skb->len, PCI_DMA_TODEVICE); + skb->len, DMA_TO_DEVICE); dev_kfree_skb_irq (np->tx_skbuff[entry]); np->tx_skbuff[entry] = NULL; np->tx_ring[entry].frag[0].addr = 0; @@ -1252,9 +1274,9 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) break; skb = np->tx_skbuff[entry]; /* Free the original skb. */ - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[entry].frag[0].addr), - skb->len, PCI_DMA_TODEVICE); + skb->len, DMA_TO_DEVICE); dev_kfree_skb_irq (np->tx_skbuff[entry]); np->tx_skbuff[entry] = NULL; np->tx_ring[entry].frag[0].addr = 0; @@ -1334,22 +1356,18 @@ static void rx_poll(unsigned long data) if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) { skb_reserve(skb, 2); /* 16 byte align the IP header */ - pci_dma_sync_single_for_cpu(np->pci_dev, - le32_to_cpu(desc->frag[0].addr), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); - + dma_sync_single_for_cpu(&np->pci_dev->dev, + le32_to_cpu(desc->frag[0].addr), + np->rx_buf_sz, DMA_FROM_DEVICE); skb_copy_to_linear_data(skb, np->rx_skbuff[entry]->data, pkt_len); - pci_dma_sync_single_for_device(np->pci_dev, - le32_to_cpu(desc->frag[0].addr), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); + dma_sync_single_for_device(&np->pci_dev->dev, + le32_to_cpu(desc->frag[0].addr), + np->rx_buf_sz, DMA_FROM_DEVICE); skb_put(skb, pkt_len); } else { - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(desc->frag[0].addr), - np->rx_buf_sz, - PCI_DMA_FROMDEVICE); + np->rx_buf_sz, DMA_FROM_DEVICE); skb_put(skb = np->rx_skbuff[entry], pkt_len); np->rx_skbuff[entry] = NULL; } @@ -1396,8 +1414,14 @@ static void refill_rx (struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ np->rx_ring[entry].frag[0].addr = cpu_to_le32( - pci_map_single(np->pci_dev, skb->data, - np->rx_buf_sz, PCI_DMA_FROMDEVICE)); + dma_map_single(&np->pci_dev->dev, skb->data, + np->rx_buf_sz, DMA_FROM_DEVICE)); + if (dma_mapping_error(&np->pci_dev->dev, + np->rx_ring[entry].frag[0].addr)) { + dev_kfree_skb_irq(skb); + np->rx_skbuff[entry] = NULL; + break; + } } /* Perhaps we need not reset this field. */ np->rx_ring[entry].frag[0].length = @@ -1475,27 +1499,41 @@ static struct net_device_stats *get_stats(struct net_device *dev) { struct netdev_private *np = netdev_priv(dev); void __iomem *ioaddr = np->base; - int i; + unsigned long flags; + u8 late_coll, single_coll, mult_coll; - /* We should lock this segment of code for SMP eventually, although - the vulnerability window is very small and statistics are - non-critical. */ + spin_lock_irqsave(&np->statlock, flags); /* The chip only need report frame silently dropped. */ dev->stats.rx_missed_errors += ioread8(ioaddr + RxMissed); dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK); dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK); - dev->stats.collisions += ioread8(ioaddr + StatsLateColl); - dev->stats.collisions += ioread8(ioaddr + StatsMultiColl); - dev->stats.collisions += ioread8(ioaddr + StatsOneColl); dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError); - ioread8(ioaddr + StatsTxDefer); - for (i = StatsTxDefer; i <= StatsMcastRx; i++) - ioread8(ioaddr + i); + + mult_coll = ioread8(ioaddr + StatsMultiColl); + np->xstats.tx_multiple_collisions += mult_coll; + single_coll = ioread8(ioaddr + StatsOneColl); + np->xstats.tx_single_collisions += single_coll; + late_coll = ioread8(ioaddr + StatsLateColl); + np->xstats.tx_late_collisions += late_coll; + dev->stats.collisions += mult_coll + + single_coll + + late_coll; + + np->xstats.tx_deferred += ioread8(ioaddr + StatsTxDefer); + np->xstats.tx_deferred_excessive += ioread8(ioaddr + StatsTxXSDefer); + np->xstats.tx_aborted += ioread8(ioaddr + StatsTxAbort); + np->xstats.tx_bcasts += ioread8(ioaddr + StatsBcastTx); + np->xstats.rx_bcasts += ioread8(ioaddr + StatsBcastRx); + np->xstats.tx_mcasts += ioread8(ioaddr + StatsMcastTx); + np->xstats.rx_mcasts += ioread8(ioaddr + StatsMcastRx); + dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow); dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16; dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow); dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16; + spin_unlock_irqrestore(&np->statlock, flags); + return &dev->stats; } @@ -1554,6 +1592,21 @@ static int __set_mac_addr(struct net_device *dev) return 0; } +static const struct { + const char name[ETH_GSTRING_LEN]; +} sundance_stats[] = { + { "tx_multiple_collisions" }, + { "tx_single_collisions" }, + { "tx_late_collisions" }, + { "tx_deferred" }, + { "tx_deferred_excessive" }, + { "tx_aborted" }, + { "tx_bcasts" }, + { "rx_bcasts" }, + { "tx_mcasts" }, + { "rx_mcasts" }, +}; + static int check_if_running(struct net_device *dev) { if (!netif_running(dev)) @@ -1612,6 +1665,42 @@ static void set_msglevel(struct net_device *dev, u32 val) np->msg_enable = val; } +static void get_strings(struct net_device *dev, u32 stringset, + u8 *data) +{ + if (stringset == ETH_SS_STATS) + memcpy(data, sundance_stats, sizeof(sundance_stats)); +} + +static int get_sset_count(struct net_device *dev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return ARRAY_SIZE(sundance_stats); + default: + return -EOPNOTSUPP; + } +} + +static void get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *data) +{ + struct netdev_private *np = netdev_priv(dev); + int i = 0; + + get_stats(dev); + data[i++] = np->xstats.tx_multiple_collisions; + data[i++] = np->xstats.tx_single_collisions; + data[i++] = np->xstats.tx_late_collisions; + data[i++] = np->xstats.tx_deferred; + data[i++] = np->xstats.tx_deferred_excessive; + data[i++] = np->xstats.tx_aborted; + data[i++] = np->xstats.tx_bcasts; + data[i++] = np->xstats.rx_bcasts; + data[i++] = np->xstats.tx_mcasts; + data[i++] = np->xstats.rx_mcasts; +} + static const struct ethtool_ops ethtool_ops = { .begin = check_if_running, .get_drvinfo = get_drvinfo, @@ -1621,6 +1710,9 @@ static const struct ethtool_ops ethtool_ops = { .get_link = get_link, .get_msglevel = get_msglevel, .set_msglevel = set_msglevel, + .get_strings = get_strings, + .get_sset_count = get_sset_count, + .get_ethtool_stats = get_ethtool_stats, }; static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) @@ -1715,9 +1807,9 @@ static int netdev_close(struct net_device *dev) np->rx_ring[i].status = 0; skb = np->rx_skbuff[i]; if (skb) { - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->rx_ring[i].frag[0].addr), - np->rx_buf_sz, PCI_DMA_FROMDEVICE); + np->rx_buf_sz, DMA_FROM_DEVICE); dev_kfree_skb(skb); np->rx_skbuff[i] = NULL; } @@ -1727,9 +1819,9 @@ static int netdev_close(struct net_device *dev) np->tx_ring[i].next_desc = 0; skb = np->tx_skbuff[i]; if (skb) { - pci_unmap_single(np->pci_dev, + dma_unmap_single(&np->pci_dev->dev, le32_to_cpu(np->tx_ring[i].frag[0].addr), - skb->len, PCI_DMA_TODEVICE); + skb->len, DMA_TO_DEVICE); dev_kfree_skb(skb); np->tx_skbuff[i] = NULL; } @@ -1743,25 +1835,72 @@ static void __devexit sundance_remove1 (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); if (dev) { - struct netdev_private *np = netdev_priv(dev); - - unregister_netdev(dev); - pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, - np->rx_ring_dma); - pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, - np->tx_ring_dma); - pci_iounmap(pdev, np->base); - pci_release_regions(pdev); - free_netdev(dev); - pci_set_drvdata(pdev, NULL); + struct netdev_private *np = netdev_priv(dev); + unregister_netdev(dev); + dma_free_coherent(&pdev->dev, RX_TOTAL_SIZE, + np->rx_ring, np->rx_ring_dma); + dma_free_coherent(&pdev->dev, TX_TOTAL_SIZE, + np->tx_ring, np->tx_ring_dma); + pci_iounmap(pdev, np->base); + pci_release_regions(pdev); + free_netdev(dev); + pci_set_drvdata(pdev, NULL); + } +} + +#ifdef CONFIG_PM + +static int sundance_suspend(struct pci_dev *pci_dev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pci_dev); + + if (!netif_running(dev)) + return 0; + + netdev_close(dev); + netif_device_detach(dev); + + pci_save_state(pci_dev); + pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); + + return 0; +} + +static int sundance_resume(struct pci_dev *pci_dev) +{ + struct net_device *dev = pci_get_drvdata(pci_dev); + int err = 0; + + if (!netif_running(dev)) + return 0; + + pci_set_power_state(pci_dev, PCI_D0); + pci_restore_state(pci_dev); + + err = netdev_open(dev); + if (err) { + printk(KERN_ERR "%s: Can't resume interface!\n", + dev->name); + goto out; } + + netif_device_attach(dev); + +out: + return err; } +#endif /* CONFIG_PM */ + static struct pci_driver sundance_driver = { .name = DRV_NAME, .id_table = sundance_pci_tbl, .probe = sundance_probe1, .remove = __devexit_p(sundance_remove1), +#ifdef CONFIG_PM + .suspend = sundance_suspend, + .resume = sundance_resume, +#endif /* CONFIG_PM */ }; static int __init sundance_init(void) diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 434f9d735333663919c199b3e929dd74de924549..4ceb3cf6a9a96750931b01a78b444de40d788014 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -31,6 +31,8 @@ * about when we can start taking interrupts or get xmit() called... */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -105,7 +107,6 @@ MODULE_DESCRIPTION("Sun GEM Gbit ethernet driver"); MODULE_LICENSE("GPL"); #define GEM_MODULE_NAME "gem" -#define PFX GEM_MODULE_NAME ": " static DEFINE_PCI_DEVICE_TABLE(gem_pci_tbl) = { { PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_GEM, @@ -262,8 +263,7 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta gp->dev->name, pcs_istat); if (!(pcs_istat & PCS_ISTAT_LSC)) { - printk(KERN_ERR "%s: PCS irq but no link status change???\n", - dev->name); + netdev_err(dev, "PCS irq but no link status change???\n"); return 0; } @@ -282,20 +282,16 @@ static int gem_pcs_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta * when autoneg has completed. */ if (pcs_miistat & PCS_MIISTAT_RF) - printk(KERN_INFO "%s: PCS AutoNEG complete, " - "RemoteFault\n", dev->name); + netdev_info(dev, "PCS AutoNEG complete, RemoteFault\n"); else - printk(KERN_INFO "%s: PCS AutoNEG complete.\n", - dev->name); + netdev_info(dev, "PCS AutoNEG complete\n"); } if (pcs_miistat & PCS_MIISTAT_LS) { - printk(KERN_INFO "%s: PCS link is now up.\n", - dev->name); + netdev_info(dev, "PCS link is now up\n"); netif_carrier_on(gp->dev); } else { - printk(KERN_INFO "%s: PCS link is now down.\n", - dev->name); + netdev_info(dev, "PCS link is now down\n"); netif_carrier_off(gp->dev); /* If this happens and the link timer is not running, * reset so we re-negotiate. @@ -323,14 +319,12 @@ static int gem_txmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s return 0; if (txmac_stat & MAC_TXSTAT_URUN) { - printk(KERN_ERR "%s: TX MAC xmit underrun.\n", - dev->name); + netdev_err(dev, "TX MAC xmit underrun\n"); gp->net_stats.tx_fifo_errors++; } if (txmac_stat & MAC_TXSTAT_MPE) { - printk(KERN_ERR "%s: TX MAC max packet size error.\n", - dev->name); + netdev_err(dev, "TX MAC max packet size error\n"); gp->net_stats.tx_errors++; } @@ -377,8 +371,7 @@ static int gem_rxmac_reset(struct gem *gp) udelay(10); } if (limit == 5000) { - printk(KERN_ERR "%s: RX MAC will not reset, resetting whole " - "chip.\n", dev->name); + netdev_err(dev, "RX MAC will not reset, resetting whole chip\n"); return 1; } @@ -390,8 +383,7 @@ static int gem_rxmac_reset(struct gem *gp) udelay(10); } if (limit == 5000) { - printk(KERN_ERR "%s: RX MAC will not disable, resetting whole " - "chip.\n", dev->name); + netdev_err(dev, "RX MAC will not disable, resetting whole chip\n"); return 1; } @@ -403,8 +395,7 @@ static int gem_rxmac_reset(struct gem *gp) udelay(10); } if (limit == 5000) { - printk(KERN_ERR "%s: RX DMA will not disable, resetting whole " - "chip.\n", dev->name); + netdev_err(dev, "RX DMA will not disable, resetting whole chip\n"); return 1; } @@ -419,8 +410,7 @@ static int gem_rxmac_reset(struct gem *gp) udelay(10); } if (limit == 5000) { - printk(KERN_ERR "%s: RX reset command will not execute, resetting " - "whole chip.\n", dev->name); + netdev_err(dev, "RX reset command will not execute, resetting whole chip\n"); return 1; } @@ -429,8 +419,7 @@ static int gem_rxmac_reset(struct gem *gp) struct gem_rxd *rxd = &gp->init_block->rxd[i]; if (gp->rx_skbs[i] == NULL) { - printk(KERN_ERR "%s: Parts of RX ring empty, resetting " - "whole chip.\n", dev->name); + netdev_err(dev, "Parts of RX ring empty, resetting whole chip\n"); return 1; } @@ -479,8 +468,7 @@ static int gem_rxmac_interrupt(struct net_device *dev, struct gem *gp, u32 gem_s if (rxmac_stat & MAC_RXSTAT_OFLW) { u32 smac = readl(gp->regs + MAC_SMACHINE); - printk(KERN_ERR "%s: RX MAC fifo overflow smac[%08x].\n", - dev->name, smac); + netdev_err(dev, "RX MAC fifo overflow smac[%08x]\n", smac); gp->net_stats.rx_over_errors++; gp->net_stats.rx_fifo_errors++; @@ -542,19 +530,18 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta if (gp->pdev->vendor == PCI_VENDOR_ID_SUN && gp->pdev->device == PCI_DEVICE_ID_SUN_GEM) { - printk(KERN_ERR "%s: PCI error [%04x] ", - dev->name, pci_estat); + netdev_err(dev, "PCI error [%04x]", pci_estat); if (pci_estat & GREG_PCIESTAT_BADACK) - printk(" "); + pr_cont(" "); if (pci_estat & GREG_PCIESTAT_DTRTO) - printk(" "); + pr_cont(" "); if (pci_estat & GREG_PCIESTAT_OTHER) - printk(""); - printk("\n"); + pr_cont(" "); + pr_cont("\n"); } else { pci_estat |= GREG_PCIESTAT_OTHER; - printk(KERN_ERR "%s: PCI error\n", dev->name); + netdev_err(dev, "PCI error\n"); } if (pci_estat & GREG_PCIESTAT_OTHER) { @@ -565,26 +552,20 @@ static int gem_pci_interrupt(struct net_device *dev, struct gem *gp, u32 gem_sta */ pci_read_config_word(gp->pdev, PCI_STATUS, &pci_cfg_stat); - printk(KERN_ERR "%s: Read PCI cfg space status [%04x]\n", - dev->name, pci_cfg_stat); + netdev_err(dev, "Read PCI cfg space status [%04x]\n", + pci_cfg_stat); if (pci_cfg_stat & PCI_STATUS_PARITY) - printk(KERN_ERR "%s: PCI parity error detected.\n", - dev->name); + netdev_err(dev, "PCI parity error detected\n"); if (pci_cfg_stat & PCI_STATUS_SIG_TARGET_ABORT) - printk(KERN_ERR "%s: PCI target abort.\n", - dev->name); + netdev_err(dev, "PCI target abort\n"); if (pci_cfg_stat & PCI_STATUS_REC_TARGET_ABORT) - printk(KERN_ERR "%s: PCI master acks target abort.\n", - dev->name); + netdev_err(dev, "PCI master acks target abort\n"); if (pci_cfg_stat & PCI_STATUS_REC_MASTER_ABORT) - printk(KERN_ERR "%s: PCI master abort.\n", - dev->name); + netdev_err(dev, "PCI master abort\n"); if (pci_cfg_stat & PCI_STATUS_SIG_SYSTEM_ERROR) - printk(KERN_ERR "%s: PCI system error SERR#.\n", - dev->name); + netdev_err(dev, "PCI system error SERR#\n"); if (pci_cfg_stat & PCI_STATUS_DETECTED_PARITY) - printk(KERN_ERR "%s: PCI parity error.\n", - dev->name); + netdev_err(dev, "PCI parity error\n"); /* Write the error bits back to clear them. */ pci_cfg_stat &= (PCI_STATUS_PARITY | @@ -874,8 +855,7 @@ static int gem_rx(struct gem *gp, int work_to_do) gp->rx_new = entry; if (drops) - printk(KERN_INFO "%s: Memory squeeze, deferring packet.\n", - gp->dev->name); + netdev_info(gp->dev, "Memory squeeze, deferring packet\n"); return work_done; } @@ -981,21 +961,19 @@ static void gem_tx_timeout(struct net_device *dev) { struct gem *gp = netdev_priv(dev); - printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name); + netdev_err(dev, "transmit timed out, resetting\n"); if (!gp->running) { - printk("%s: hrm.. hw not running !\n", dev->name); + netdev_err(dev, "hrm.. hw not running !\n"); return; } - printk(KERN_ERR "%s: TX_STATE[%08x:%08x:%08x]\n", - dev->name, - readl(gp->regs + TXDMA_CFG), - readl(gp->regs + MAC_TXSTAT), - readl(gp->regs + MAC_TXCFG)); - printk(KERN_ERR "%s: RX_STATE[%08x:%08x:%08x]\n", - dev->name, - readl(gp->regs + RXDMA_CFG), - readl(gp->regs + MAC_RXSTAT), - readl(gp->regs + MAC_RXCFG)); + netdev_err(dev, "TX_STATE[%08x:%08x:%08x]\n", + readl(gp->regs + TXDMA_CFG), + readl(gp->regs + MAC_TXSTAT), + readl(gp->regs + MAC_TXCFG)); + netdev_err(dev, "RX_STATE[%08x:%08x:%08x]\n", + readl(gp->regs + RXDMA_CFG), + readl(gp->regs + MAC_RXSTAT), + readl(gp->regs + MAC_RXCFG)); spin_lock_irq(&gp->lock); spin_lock(&gp->tx_lock); @@ -1048,8 +1026,7 @@ static netdev_tx_t gem_start_xmit(struct sk_buff *skb, if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) { netif_stop_queue(dev); spin_unlock_irqrestore(&gp->tx_lock, flags); - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", - dev->name); + netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); return NETDEV_TX_BUSY; } @@ -1158,8 +1135,7 @@ static void gem_pcs_reset(struct gem *gp) break; } if (limit < 0) - printk(KERN_WARNING "%s: PCS reset bit would not clear.\n", - gp->dev->name); + netdev_warn(gp->dev, "PCS reset bit would not clear\n"); } static void gem_pcs_reinit_adv(struct gem *gp) @@ -1230,7 +1206,7 @@ static void gem_reset(struct gem *gp) } while (val & (GREG_SWRST_TXRST | GREG_SWRST_RXRST)); if (limit < 0) - printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name); + netdev_err(gp->dev, "SW reset is ghetto\n"); if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes) gem_pcs_reinit_adv(gp); @@ -1395,9 +1371,8 @@ static int gem_set_link_modes(struct gem *gp) speed = SPEED_1000; } - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: Link is up at %d Mbps, %s-duplex.\n", - gp->dev->name, speed, (full_duplex ? "full" : "half")); + netif_info(gp, link, gp->dev, "Link is up at %d Mbps, %s-duplex\n", + speed, (full_duplex ? "full" : "half")); if (!gp->running) return 0; @@ -1451,15 +1426,13 @@ static int gem_set_link_modes(struct gem *gp) if (netif_msg_link(gp)) { if (pause) { - printk(KERN_INFO "%s: Pause is enabled " - "(rxfifo: %d off: %d on: %d)\n", - gp->dev->name, - gp->rx_fifo_sz, - gp->rx_pause_off, - gp->rx_pause_on); + netdev_info(gp->dev, + "Pause is enabled (rxfifo: %d off: %d on: %d)\n", + gp->rx_fifo_sz, + gp->rx_pause_off, + gp->rx_pause_on); } else { - printk(KERN_INFO "%s: Pause is disabled\n", - gp->dev->name); + netdev_info(gp->dev, "Pause is disabled\n"); } } @@ -1484,9 +1457,8 @@ static int gem_mdio_link_not_up(struct gem *gp) { switch (gp->lstate) { case link_force_ret: - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: Autoneg failed again, keeping" - " forced mode\n", gp->dev->name); + netif_info(gp, link, gp->dev, + "Autoneg failed again, keeping forced mode\n"); gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, gp->last_forced_speed, DUPLEX_HALF); gp->timer_ticks = 5; @@ -1499,9 +1471,7 @@ static int gem_mdio_link_not_up(struct gem *gp) */ if (gp->phy_mii.def->magic_aneg) return 1; - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: switching to forced 100bt\n", - gp->dev->name); + netif_info(gp, link, gp->dev, "switching to forced 100bt\n"); /* Try forced modes. */ gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_100, DUPLEX_HALF); @@ -1517,9 +1487,8 @@ static int gem_mdio_link_not_up(struct gem *gp) gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_10, DUPLEX_HALF); gp->timer_ticks = 5; - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: switching to forced 10bt\n", - gp->dev->name); + netif_info(gp, link, gp->dev, + "switching to forced 10bt\n"); return 0; } else return 1; @@ -1574,8 +1543,8 @@ static void gem_link_timer(unsigned long data) gp->last_forced_speed = gp->phy_mii.speed; gp->timer_ticks = 5; if (netif_msg_link(gp)) - printk(KERN_INFO "%s: Got link after fallback, retrying" - " autoneg once...\n", gp->dev->name); + netdev_info(gp->dev, + "Got link after fallback, retrying autoneg once...\n"); gp->phy_mii.def->ops->setup_aneg(&gp->phy_mii, gp->phy_mii.advertising); } else if (gp->lstate != link_up) { gp->lstate = link_up; @@ -1589,9 +1558,7 @@ static void gem_link_timer(unsigned long data) */ if (gp->lstate == link_up) { gp->lstate = link_down; - if (netif_msg_link(gp)) - printk(KERN_INFO "%s: Link down\n", - gp->dev->name); + netif_info(gp, link, gp->dev, "Link down\n"); netif_carrier_off(gp->dev); gp->reset_task_pending = 1; schedule_work(&gp->reset_task); @@ -1746,8 +1713,7 @@ static void gem_init_phy(struct gem *gp) if (phy_read(gp, MII_BMCR) != 0xffff) break; if (i == 2) - printk(KERN_WARNING "%s: GMAC PHY not responding !\n", - gp->dev->name); + netdev_warn(gp->dev, "GMAC PHY not responding !\n"); } } @@ -2038,7 +2004,7 @@ static int gem_check_invariants(struct gem *gp) * as this chip has no gigabit PHY. */ if ((mif_cfg & (MIF_CFG_MDI0 | MIF_CFG_MDI1)) == 0) { - printk(KERN_ERR PFX "RIO GEM lacks MII phy, mif_cfg[%08x]\n", + pr_err("RIO GEM lacks MII phy, mif_cfg[%08x]\n", mif_cfg); return -1; } @@ -2078,7 +2044,7 @@ static int gem_check_invariants(struct gem *gp) } if (i == 32) { if (pdev->device != PCI_DEVICE_ID_SUN_GEM) { - printk(KERN_ERR PFX "RIO MII phy will not respond.\n"); + pr_err("RIO MII phy will not respond\n"); return -1; } gp->phy_type = phy_serdes; @@ -2093,7 +2059,7 @@ static int gem_check_invariants(struct gem *gp) if (pdev->device == PCI_DEVICE_ID_SUN_GEM) { if (gp->tx_fifo_sz != (9 * 1024) || gp->rx_fifo_sz != (20 * 1024)) { - printk(KERN_ERR PFX "GEM has bogus fifo sizes tx(%d) rx(%d)\n", + pr_err("GEM has bogus fifo sizes tx(%d) rx(%d)\n", gp->tx_fifo_sz, gp->rx_fifo_sz); return -1; } @@ -2101,7 +2067,7 @@ static int gem_check_invariants(struct gem *gp) } else { if (gp->tx_fifo_sz != (2 * 1024) || gp->rx_fifo_sz != (2 * 1024)) { - printk(KERN_ERR PFX "RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n", + pr_err("RIO GEM has bogus fifo sizes tx(%d) rx(%d)\n", gp->tx_fifo_sz, gp->rx_fifo_sz); return -1; } @@ -2239,7 +2205,7 @@ static int gem_do_start(struct net_device *dev) if (request_irq(gp->pdev->irq, gem_interrupt, IRQF_SHARED, dev->name, (void *)dev)) { - printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name); + netdev_err(dev, "failed to request irq !\n"); spin_lock_irqsave(&gp->lock, flags); spin_lock(&gp->tx_lock); @@ -2378,9 +2344,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state) mutex_lock(&gp->pm_mutex); - printk(KERN_INFO "%s: suspending, WakeOnLan %s\n", - dev->name, - (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled"); + netdev_info(dev, "suspending, WakeOnLan %s\n", + (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled"); /* Keep the cell enabled during the entire operation */ spin_lock_irqsave(&gp->lock, flags); @@ -2440,7 +2405,7 @@ static int gem_resume(struct pci_dev *pdev) struct gem *gp = netdev_priv(dev); unsigned long flags; - printk(KERN_INFO "%s: resuming\n", dev->name); + netdev_info(dev, "resuming\n"); mutex_lock(&gp->pm_mutex); @@ -2452,8 +2417,7 @@ static int gem_resume(struct pci_dev *pdev) /* Make sure PCI access and bus master are enabled */ if (pci_enable_device(gp->pdev)) { - printk(KERN_ERR "%s: Can't re-enable chip !\n", - dev->name); + netdev_err(dev, "Can't re-enable chip !\n"); /* Put cell and forget it for now, it will be considered as * still asleep, a new sleep cycle may bring it back */ @@ -2938,7 +2902,7 @@ static int __devinit gem_get_device_address(struct gem *gp) addr = idprom->id_ethaddr; #else printk("\n"); - printk(KERN_ERR "%s: can't get mac-address\n", dev->name); + pr_err("%s: can't get mac-address\n", dev->name); return -1; #endif } @@ -3009,14 +2973,12 @@ static const struct net_device_ops gem_netdev_ops = { static int __devinit gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { - static int gem_version_printed = 0; unsigned long gemreg_base, gemreg_len; struct net_device *dev; struct gem *gp; int err, pci_using_dac; - if (gem_version_printed++ == 0) - printk(KERN_INFO "%s", version); + printk_once(KERN_INFO "%s", version); /* Apple gmac note: during probe, the chip is powered up by * the arch code to allow the code below to work (and to let @@ -3026,8 +2988,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, */ err = pci_enable_device(pdev); if (err) { - printk(KERN_ERR PFX "Cannot enable MMIO operation, " - "aborting.\n"); + pr_err("Cannot enable MMIO operation, aborting\n"); return err; } pci_set_master(pdev); @@ -3048,8 +3009,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, } else { err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { - printk(KERN_ERR PFX "No usable DMA configuration, " - "aborting.\n"); + pr_err("No usable DMA configuration, aborting\n"); goto err_disable_device; } pci_using_dac = 0; @@ -3059,15 +3019,14 @@ static int __devinit gem_init_one(struct pci_dev *pdev, gemreg_len = pci_resource_len(pdev, 0); if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) { - printk(KERN_ERR PFX "Cannot find proper PCI device " - "base address, aborting.\n"); + pr_err("Cannot find proper PCI device base address, aborting\n"); err = -ENODEV; goto err_disable_device; } dev = alloc_etherdev(sizeof(*gp)); if (!dev) { - printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); + pr_err("Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_disable_device; } @@ -3077,8 +3036,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, err = pci_request_regions(pdev, DRV_NAME); if (err) { - printk(KERN_ERR PFX "Cannot obtain PCI resources, " - "aborting.\n"); + pr_err("Cannot obtain PCI resources, aborting\n"); goto err_out_free_netdev; } @@ -3104,8 +3062,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, gp->regs = ioremap(gemreg_base, gemreg_len); if (!gp->regs) { - printk(KERN_ERR PFX "Cannot map device registers, " - "aborting.\n"); + pr_err("Cannot map device registers, aborting\n"); err = -EIO; goto err_out_free_res; } @@ -3150,8 +3107,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev, pci_alloc_consistent(pdev, sizeof(struct gem_init_block), &gp->gblock_dvma); if (!gp->init_block) { - printk(KERN_ERR PFX "Cannot allocate init block, " - "aborting.\n"); + pr_err("Cannot allocate init block, aborting\n"); err = -ENOMEM; goto err_out_iounmap; } @@ -3180,19 +3136,18 @@ static int __devinit gem_init_one(struct pci_dev *pdev, /* Register with kernel */ if (register_netdev(dev)) { - printk(KERN_ERR PFX "Cannot register net device, " - "aborting.\n"); + pr_err("Cannot register net device, aborting\n"); err = -ENOMEM; goto err_out_free_consistent; } - printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n", - dev->name, dev->dev_addr); + netdev_info(dev, "Sun GEM (PCI) 10/100/1000BaseT Ethernet %pM\n", + dev->dev_addr); if (gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) - printk(KERN_INFO "%s: Found %s PHY\n", dev->name, - gp->phy_mii.def ? gp->phy_mii.def->name : "no"); + netdev_info(dev, "Found %s PHY\n", + gp->phy_mii.def ? gp->phy_mii.def->name : "no"); /* GEM can do it all... */ dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_LLTX; diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c index 78f8cee5fd7428b96e447e568d07c0cafb959f47..d16880d7099b014916a408ac7682b9c748251ca7 100644 --- a/drivers/net/sungem_phy.c +++ b/drivers/net/sungem_phy.c @@ -88,7 +88,7 @@ static int reset_one_mii_phy(struct mii_phy* phy, int phy_id) if ((val & BMCR_ISOLATE) && limit > 0) __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE); - return (limit <= 0); + return limit <= 0; } static int bcm5201_init(struct mii_phy* phy) @@ -1175,7 +1175,8 @@ int mii_phy_probe(struct mii_phy *phy, int mii_id) /* Read ID and find matching entry */ id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2)); - printk(KERN_DEBUG "PHY ID: %x, addr: %x\n", id, mii_id); + printk(KERN_DEBUG KBUILD_MODNAME ": " "PHY ID: %x, addr: %x\n", + id, mii_id); for (i=0; (def = mii_phy_table[i]) != NULL; i++) if ((id & def->phy_id_mask) == def->phy_id) break; diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c index bd0df1c1495587e9f6cf5f03ed85f98fbce5c2c7..5e28c414421ad0768e8a8e4082b188bf371536e9 100644 --- a/drivers/net/sunhme.c +++ b/drivers/net/sunhme.c @@ -1409,7 +1409,7 @@ static void happy_meal_begin_auto_negotiation(struct happy_meal *hp, hp->timer_ticks = 0; hp->happy_timer.expires = jiffies + (12 * HZ)/10; /* 1.2 sec. */ hp->happy_timer.data = (unsigned long) hp; - hp->happy_timer.function = &happy_meal_timer; + hp->happy_timer.function = happy_meal_timer; add_timer(&hp->happy_timer); } @@ -2497,7 +2497,7 @@ static u32 hme_get_link(struct net_device *dev) hp->sw_bmcr = happy_meal_tcvr_read(hp, hp->tcvregs, MII_BMCR); spin_unlock_irq(&hp->happy_lock); - return (hp->sw_bmsr & BMSR_LSTATUS); + return hp->sw_bmsr & BMSR_LSTATUS; } static const struct ethtool_ops hme_ethtool_ops = { @@ -2808,7 +2808,8 @@ static int __devinit happy_meal_sbus_probe_one(struct platform_device *op, int i happy_meal_set_initial_advertisement(hp); spin_unlock_irq(&hp->happy_lock); - if (register_netdev(hp->dev)) { + err = register_netdev(hp->dev); + if (err) { printk(KERN_ERR "happymeal: Cannot register net device, " "aborting.\n"); goto err_out_free_coherent; @@ -3130,7 +3131,8 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev, happy_meal_set_initial_advertisement(hp); spin_unlock_irq(&hp->happy_lock); - if (register_netdev(hp->dev)) { + err = register_netdev(hp->dev); + if (err) { printk(KERN_ERR "happymeal(PCI): Cannot register net device, " "aborting.\n"); goto err_out_iounmap; diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 8dcb858f216859c600a8c251ac5d714bc938976b..2cf84e5968b2b3217fd487c53f82420d31f71868 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1483,7 +1483,7 @@ static int __devinit sparc_lance_probe_one(struct platform_device *op, */ init_timer(&lp->multicast_timer); lp->multicast_timer.data = (unsigned long) dev; - lp->multicast_timer.function = &lance_set_multicast_retry; + lp->multicast_timer.function = lance_set_multicast_retry; if (register_netdev(dev)) { printk(KERN_ERR "SunLance: Cannot register device.\n"); diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c index 72e65d4666ef2e09bfc86c369860e12c3018fc31..9536b2f010be7d08cba459b505473956109f605c 100644 --- a/drivers/net/sunqe.c +++ b/drivers/net/sunqe.c @@ -711,7 +711,7 @@ static u32 qe_get_link(struct net_device *dev) phyconfig = sbus_readb(mregs + MREGS_PHYCONFIG); spin_unlock_irq(&qep->lock); - return (phyconfig & MREGS_PHYCONFIG_LSTAT); + return phyconfig & MREGS_PHYCONFIG_LSTAT; } static const struct ethtool_ops qe_ethtool_ops = { diff --git a/drivers/net/sunvnet.c b/drivers/net/sunvnet.c index d281a7b34701060d4ab23f3f2c764b684bf7bb0d..bf3c762de6204ac7c2536e210e1b89a16e5a28d0 100644 --- a/drivers/net/sunvnet.c +++ b/drivers/net/sunvnet.c @@ -3,6 +3,8 @@ * Copyright (C) 2007, 2008 David S. Miller */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -20,7 +22,6 @@ #include "sunvnet.h" #define DRV_MODULE_NAME "sunvnet" -#define PFX DRV_MODULE_NAME ": " #define DRV_MODULE_VERSION "1.0" #define DRV_MODULE_RELDATE "June 25, 2007" @@ -45,9 +46,9 @@ static int vnet_handle_unknown(struct vnet_port *port, void *arg) { struct vio_msg_tag *pkt = arg; - printk(KERN_ERR PFX "Received unknown msg [%02x:%02x:%04x:%08x]\n", + pr_err("Received unknown msg [%02x:%02x:%04x:%08x]\n", pkt->type, pkt->stype, pkt->stype_env, pkt->sid); - printk(KERN_ERR PFX "Resetting connection.\n"); + pr_err("Resetting connection\n"); ldc_disconnect(port->vio.lp); @@ -400,8 +401,8 @@ static int vnet_rx(struct vnet_port *port, void *msgbuf) if (unlikely(pkt->tag.stype_env != VIO_DRING_DATA)) return 0; if (unlikely(pkt->seq != dr->rcv_nxt)) { - printk(KERN_ERR PFX "RX out of sequence seq[0x%llx] " - "rcv_nxt[0x%llx]\n", pkt->seq, dr->rcv_nxt); + pr_err("RX out of sequence seq[0x%llx] rcv_nxt[0x%llx]\n", + pkt->seq, dr->rcv_nxt); return 0; } @@ -464,8 +465,7 @@ static int handle_mcast(struct vnet_port *port, void *msgbuf) struct vio_net_mcast_info *pkt = msgbuf; if (pkt->tag.stype != VIO_SUBTYPE_ACK) - printk(KERN_ERR PFX "%s: Got unexpected MCAST reply " - "[%02x:%02x:%04x:%08x]\n", + pr_err("%s: Got unexpected MCAST reply [%02x:%02x:%04x:%08x]\n", port->vp->dev->name, pkt->tag.type, pkt->tag.stype, @@ -520,7 +520,7 @@ static void vnet_event(void *arg, int event) } if (unlikely(event != LDC_EVENT_DATA_READY)) { - printk(KERN_WARNING PFX "Unexpected LDC event %d\n", event); + pr_warning("Unexpected LDC event %d\n", event); spin_unlock_irqrestore(&vio->lock, flags); return; } @@ -662,8 +662,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_stop_queue(dev); /* This is a hard error, log it. */ - printk(KERN_ERR PFX "%s: BUG! Tx Ring full when " - "queue awake!\n", dev->name); + netdev_err(dev, "BUG! Tx Ring full when queue awake!\n"); dev->stats.tx_errors++; } spin_unlock_irqrestore(&port->vio.lock, flags); @@ -696,8 +695,7 @@ static int vnet_start_xmit(struct sk_buff *skb, struct net_device *dev) err = __vnet_tx_trigger(port); if (unlikely(err < 0)) { - printk(KERN_INFO PFX "%s: TX trigger error %d\n", - dev->name, err); + netdev_info(dev, "TX trigger error %d\n", err); d->hdr.state = VIO_DESC_FREE; dev->stats.tx_carrier_errors++; goto out_dropped_unlock; @@ -952,12 +950,12 @@ static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port) err = -ENOMEM; if (!buf) { - printk(KERN_ERR "TX buffer allocation failure\n"); + pr_err("TX buffer allocation failure\n"); goto err_out; } err = -EFAULT; if ((unsigned long)buf & (8UL - 1)) { - printk(KERN_ERR "TX buffer misaligned\n"); + pr_err("TX buffer misaligned\n"); kfree(buf); goto err_out; } @@ -1030,7 +1028,7 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac) dev = alloc_etherdev(sizeof(*vp)); if (!dev) { - printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n"); + pr_err("Etherdev alloc failed, aborting\n"); return ERR_PTR(-ENOMEM); } @@ -1056,12 +1054,11 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac) err = register_netdev(dev); if (err) { - printk(KERN_ERR PFX "Cannot register net device, " - "aborting.\n"); + pr_err("Cannot register net device, aborting\n"); goto err_out_free_dev; } - printk(KERN_INFO "%s: Sun LDOM vnet %pM\n", dev->name, dev->dev_addr); + netdev_info(dev, "Sun LDOM vnet %pM\n", dev->dev_addr); list_add(&vp->list, &vnet_list); @@ -1133,10 +1130,7 @@ static struct vio_driver_ops vnet_vio_ops = { static void __devinit print_version(void) { - static int version_printed; - - if (version_printed++ == 0) - printk(KERN_INFO "%s", version); + printk_once(KERN_INFO "%s", version); } const char *remote_macaddr_prop = "remote-mac-address"; @@ -1157,7 +1151,7 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, vp = vnet_find_parent(hp, vdev->mp); if (IS_ERR(vp)) { - printk(KERN_ERR PFX "Cannot find port parent vnet.\n"); + pr_err("Cannot find port parent vnet\n"); err = PTR_ERR(vp); goto err_out_put_mdesc; } @@ -1165,15 +1159,14 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, rmac = mdesc_get_property(hp, vdev->mp, remote_macaddr_prop, &len); err = -ENODEV; if (!rmac) { - printk(KERN_ERR PFX "Port lacks %s property.\n", - remote_macaddr_prop); + pr_err("Port lacks %s property\n", remote_macaddr_prop); goto err_out_put_mdesc; } port = kzalloc(sizeof(*port), GFP_KERNEL); err = -ENOMEM; if (!port) { - printk(KERN_ERR PFX "Cannot allocate vnet_port.\n"); + pr_err("Cannot allocate vnet_port\n"); goto err_out_put_mdesc; } @@ -1214,9 +1207,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, dev_set_drvdata(&vdev->dev, port); - printk(KERN_INFO "%s: PORT ( remote-mac %pM%s )\n", - vp->dev->name, port->raddr, - switch_port ? " switch-port" : ""); + pr_info("%s: PORT ( remote-mac %pM%s )\n", + vp->dev->name, port->raddr, switch_port ? " switch-port" : ""); vio_port_up(&port->vio); diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 99e423a5b9f1d556211235ae52bfe3ce422a0254..b6eec8cea20948c37fc1c95e15e6f4992245df94 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -1167,7 +1167,7 @@ static void print_eth(const u8 *add) static int tc35815_tx_full(struct net_device *dev) { struct tc35815_local *lp = netdev_priv(dev); - return ((lp->tfd_start + 1) % TX_FD_NUM == lp->tfd_end); + return (lp->tfd_start + 1) % TX_FD_NUM == lp->tfd_end; } static void tc35815_restart(struct net_device *dev) diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 737df6032bbc1d4bd9635b78210a52bcfa7efea2..8b3dc1eb401541e8e1c3de31ce5308d84f477845 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -92,7 +92,7 @@ static void bdx_rx_free(struct bdx_priv *priv); static void bdx_tx_free(struct bdx_priv *priv); /* Definitions needed by bdx_probe */ -static void bdx_ethtool_ops(struct net_device *netdev); +static void bdx_set_ethtool_ops(struct net_device *netdev); /************************************************************************* * Print Info * @@ -927,13 +927,6 @@ static void bdx_update_stats(struct bdx_priv *priv) BDX_ASSERT((sizeof(struct bdx_stats) / sizeof(u64)) != i); } -static struct net_device_stats *bdx_get_stats(struct net_device *ndev) -{ - struct bdx_priv *priv = netdev_priv(ndev); - struct net_device_stats *net_stat = &priv->net_stats; - return net_stat; -} - static void print_rxdd(struct rxd_desc *rxdd, u32 rxd_val1, u16 len, u16 rxd_vlan); static void print_rxfd(struct rxf_desc *rxfd); @@ -1220,6 +1213,7 @@ static void bdx_recycle_skb(struct bdx_priv *priv, struct rxd_desc *rxdd) static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) { + struct net_device *ndev = priv->ndev; struct sk_buff *skb, *skb2; struct rxd_desc *rxdd; struct rx_map *dm; @@ -1273,7 +1267,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) if (unlikely(GET_RXD_ERR(rxd_val1))) { DBG("rxd_err = 0x%x\n", GET_RXD_ERR(rxd_val1)); - priv->net_stats.rx_errors++; + ndev->stats.rx_errors++; bdx_recycle_skb(priv, rxdd); continue; } @@ -1300,15 +1294,16 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) bdx_rxdb_free_elem(db, rxdd->va_lo); } - priv->net_stats.rx_bytes += len; + ndev->stats.rx_bytes += len; skb_put(skb, len); - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->protocol = eth_type_trans(skb, priv->ndev); + skb->protocol = eth_type_trans(skb, ndev); /* Non-IP packets aren't checksum-offloaded */ if (GET_RXD_PKT_ID(rxd_val1) == 0) - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); + else + skb->ip_summed = CHECKSUM_UNNECESSARY; NETIF_RX_MUX(priv, rxd_val1, rxd_vlan, skb); @@ -1316,7 +1311,7 @@ static int bdx_rx_receive(struct bdx_priv *priv, struct rxd_fifo *f, int budget) break; } - priv->net_stats.rx_packets += done; + ndev->stats.rx_packets += done; /* FIXME: do smth to minimize pci accesses */ WRITE_REG(priv, f->m.reg_RPTR, f->m.rptr & TXF_WPTR_WR_PTR); @@ -1712,8 +1707,8 @@ static netdev_tx_t bdx_tx_transmit(struct sk_buff *skb, #ifdef BDX_LLTX ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ #endif - priv->net_stats.tx_packets++; - priv->net_stats.tx_bytes += skb->len; + ndev->stats.tx_packets++; + ndev->stats.tx_bytes += skb->len; if (priv->tx_level < BDX_MIN_TX_LEVEL) { DBG("%s: %s: TX Q STOP level %d\n", @@ -1888,7 +1883,6 @@ static const struct net_device_ops bdx_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = bdx_ioctl, .ndo_set_multicast_list = bdx_setmulti, - .ndo_get_stats = bdx_get_stats, .ndo_change_mtu = bdx_change_mtu, .ndo_set_mac_address = bdx_set_mac, .ndo_vlan_rx_register = bdx_vlan_rx_register, @@ -2012,7 +2006,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ndev->netdev_ops = &bdx_netdev_ops; ndev->tx_queue_len = BDX_NDEV_TXQ_LEN; - bdx_ethtool_ops(ndev); /* ethtool interface */ + bdx_set_ethtool_ops(ndev); /* ethtool interface */ /* these fields are used for info purposes only * so we can have them same for all ports of the board */ @@ -2417,10 +2411,10 @@ static void bdx_get_ethtool_stats(struct net_device *netdev, } /* - * bdx_ethtool_ops - ethtool interface implementation + * bdx_set_ethtool_ops - ethtool interface implementation * @netdev */ -static void bdx_ethtool_ops(struct net_device *netdev) +static void bdx_set_ethtool_ops(struct net_device *netdev) { static const struct ethtool_ops bdx_ethtool_ops = { .get_settings = bdx_get_settings, diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h index 67e3b71bf7059de90cb861cc2f23e8d6ff252020..b6ba8601e2b538b70e892273a23107ca04192cc5 100644 --- a/drivers/net/tehuti.h +++ b/drivers/net/tehuti.h @@ -269,7 +269,6 @@ struct bdx_priv { u32 msg_enable; int stats_flag; struct bdx_stats hw_stats; - struct net_device_stats net_stats; struct pci_dev *pdev; struct pci_nic *nic; diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 1ec4b9e0239a8ff8c0d3cb18882ff517ef528881..852e917778f8a51643096f648d9020c2a7963725 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -69,10 +69,10 @@ #define DRV_MODULE_NAME "tg3" #define TG3_MAJ_NUM 3 -#define TG3_MIN_NUM 113 +#define TG3_MIN_NUM 115 #define DRV_MODULE_VERSION \ __stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM) -#define DRV_MODULE_RELDATE "August 2, 2010" +#define DRV_MODULE_RELDATE "October 14, 2010" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -101,9 +101,15 @@ * You can't change the ring sizes, but you can change where you place * them in the NIC onboard memory. */ -#define TG3_RX_RING_SIZE 512 +#define TG3_RX_STD_RING_SIZE(tp) \ + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \ + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \ + RX_STD_MAX_SIZE_5717 : 512) #define TG3_DEF_RX_RING_PENDING 200 -#define TG3_RX_JUMBO_RING_SIZE 256 +#define TG3_RX_JMB_RING_SIZE(tp) \ + ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \ + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \ + 1024 : 256) #define TG3_DEF_RX_JUMBO_RING_PENDING 100 #define TG3_RSS_INDIR_TBL_SIZE 128 @@ -113,19 +119,16 @@ * hw multiply/modulo instructions. Another solution would be to * replace things like '% foo' with '& (foo - 1)'. */ -#define TG3_RX_RCB_RING_SIZE(tp) \ - (((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && \ - !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) ? 1024 : 512) #define TG3_TX_RING_SIZE 512 #define TG3_DEF_TX_RING_PENDING (TG3_TX_RING_SIZE - 1) -#define TG3_RX_RING_BYTES (sizeof(struct tg3_rx_buffer_desc) * \ - TG3_RX_RING_SIZE) -#define TG3_RX_JUMBO_RING_BYTES (sizeof(struct tg3_ext_rx_buffer_desc) * \ - TG3_RX_JUMBO_RING_SIZE) -#define TG3_RX_RCB_RING_BYTES(tp) (sizeof(struct tg3_rx_buffer_desc) * \ - TG3_RX_RCB_RING_SIZE(tp)) +#define TG3_RX_STD_RING_BYTES(tp) \ + (sizeof(struct tg3_rx_buffer_desc) * TG3_RX_STD_RING_SIZE(tp)) +#define TG3_RX_JMB_RING_BYTES(tp) \ + (sizeof(struct tg3_ext_rx_buffer_desc) * TG3_RX_JMB_RING_SIZE(tp)) +#define TG3_RX_RCB_RING_BYTES(tp) \ + (sizeof(struct tg3_rx_buffer_desc) * (tp->rx_ret_ring_mask + 1)) #define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ TG3_TX_RING_SIZE) #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) @@ -143,11 +146,11 @@ #define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ) #define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ) -#define TG3_RX_STD_BUFF_RING_SIZE \ - (sizeof(struct ring_info) * TG3_RX_RING_SIZE) +#define TG3_RX_STD_BUFF_RING_SIZE(tp) \ + (sizeof(struct ring_info) * TG3_RX_STD_RING_SIZE(tp)) -#define TG3_RX_JMB_BUFF_RING_SIZE \ - (sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE) +#define TG3_RX_JMB_BUFF_RING_SIZE(tp) \ + (sizeof(struct ring_info) * TG3_RX_JMB_RING_SIZE(tp)) /* Due to a hardware bug, the 5701 can only DMA to memory addresses * that are at least dword aligned when used in PCIX mode. The driver @@ -264,7 +267,6 @@ static DEFINE_PCI_DEVICE_TABLE(tg3_pci_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57788)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5717)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5718)}, - {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5724)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57781)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57785)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_57761)}, @@ -752,42 +754,6 @@ static void tg3_int_reenable(struct tg3_napi *tnapi) HOSTCC_MODE_ENABLE | tnapi->coal_now); } -static void tg3_napi_disable(struct tg3 *tp) -{ - int i; - - for (i = tp->irq_cnt - 1; i >= 0; i--) - napi_disable(&tp->napi[i].napi); -} - -static void tg3_napi_enable(struct tg3 *tp) -{ - int i; - - for (i = 0; i < tp->irq_cnt; i++) - napi_enable(&tp->napi[i].napi); -} - -static inline void tg3_netif_stop(struct tg3 *tp) -{ - tp->dev->trans_start = jiffies; /* prevent tx timeout */ - tg3_napi_disable(tp); - netif_tx_disable(tp->dev); -} - -static inline void tg3_netif_start(struct tg3 *tp) -{ - /* NOTE: unconditional netif_tx_wake_all_queues is only - * appropriate so long as all callers are assured to - * have free tx slots (such as after tg3_init_hw) - */ - netif_tx_wake_all_queues(tp->dev); - - tg3_napi_enable(tp); - tp->napi[0].hw_status->status |= SD_STATUS_UPDATED; - tg3_enable_ints(tp); -} - static void tg3_switch_clocks(struct tg3 *tp) { u32 clock_ctrl; @@ -1196,6 +1162,52 @@ static void tg3_mdio_fini(struct tg3 *tp) } } +static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val) +{ + int err; + + err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_CTRL, + MII_TG3_MMD_CTRL_DATA_NOINC | devad); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val); + +done: + return err; +} + +static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val) +{ + int err; + + err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr); + if (err) + goto done; + + err = tg3_writephy(tp, MII_TG3_MMD_CTRL, + MII_TG3_MMD_CTRL_DATA_NOINC | devad); + if (err) + goto done; + + err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val); + +done: + return err; +} + /* tp->lock is held. */ static inline void tg3_generate_fw_event(struct tg3 *tp) { @@ -1572,6 +1584,17 @@ static void tg3_phy_fini(struct tg3 *tp) } } +static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val) +{ + int err; + + err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg); + if (!err) + err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val); + + return err; +} + static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val) { int err; @@ -1735,6 +1758,42 @@ static void tg3_phy_apply_otp(struct tg3 *tp) tg3_writephy(tp, MII_TG3_AUX_CTRL, phy); } +static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up) +{ + u32 val; + + if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP)) + return; + + tp->setlpicnt = 0; + + if (tp->link_config.autoneg == AUTONEG_ENABLE && + current_link_up == 1 && + (tp->link_config.active_speed == SPEED_1000 || + (tp->link_config.active_speed == SPEED_100 && + tp->link_config.active_duplex == DUPLEX_FULL))) { + u32 eeectl; + + if (tp->link_config.active_speed == SPEED_1000) + eeectl = TG3_CPMU_EEE_CTRL_EXIT_16_5_US; + else + eeectl = TG3_CPMU_EEE_CTRL_EXIT_36_US; + + tw32(TG3_CPMU_EEE_CTRL, eeectl); + + tg3_phy_cl45_read(tp, 0x7, TG3_CL45_D7_EEERES_STAT, &val); + + if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T || + val == TG3_CL45_D7_EEERES_STAT_LP_100TX) + tp->setlpicnt = 2; + } + + if (!tp->setlpicnt) { + val = tr32(TG3_CPMU_EEE_MODE); + tw32(TG3_CPMU_EEE_MODE, val & ~TG3_CPMU_EEEMD_LPI_ENABLE); + } +} + static int tg3_wait_macro_done(struct tg3 *tp) { int limit = 100; @@ -1917,19 +1976,16 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) */ static int tg3_phy_reset(struct tg3 *tp) { - u32 cpmuctrl; - u32 phy_status; + u32 val, cpmuctrl; int err; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { - u32 val; - val = tr32(GRC_MISC_CFG); tw32_f(GRC_MISC_CFG, val & ~GRC_MISC_CFG_EPHY_IDDQ); udelay(40); } - err = tg3_readphy(tp, MII_BMSR, &phy_status); - err |= tg3_readphy(tp, MII_BMSR, &phy_status); + err = tg3_readphy(tp, MII_BMSR, &val); + err |= tg3_readphy(tp, MII_BMSR, &val); if (err != 0) return -EBUSY; @@ -1961,18 +2017,14 @@ static int tg3_phy_reset(struct tg3 *tp) return err; if (cpmuctrl & CPMU_CTRL_GPHY_10MB_RXONLY) { - u32 phy; - - phy = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz; - tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, phy); + val = MII_TG3_DSP_EXP8_AEDW | MII_TG3_DSP_EXP8_REJ2MHz; + tg3_phydsp_write(tp, MII_TG3_DSP_EXP8, val); tw32(TG3_CPMU_CTRL, cpmuctrl); } if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX || GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5761_AX) { - u32 val; - val = tr32(TG3_CPMU_LSPD_1000MB_CLK); if ((val & CPMU_LSPD_1000MB_MACCLK_MASK) == CPMU_LSPD_1000MB_MACCLK_12_5) { @@ -2028,23 +2080,19 @@ static int tg3_phy_reset(struct tg3 *tp) /* Cannot do read-modify-write on 5401 */ tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20); } else if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { - u32 phy_reg; - /* Set bit 14 with read-modify-write to preserve other bits */ if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) && - !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy_reg)) - tg3_writephy(tp, MII_TG3_AUX_CTRL, phy_reg | 0x4000); + !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val)) + tg3_writephy(tp, MII_TG3_AUX_CTRL, val | 0x4000); } /* Set phy register 0x10 bit 0 to high fifo elasticity to support * jumbo frames transmission. */ if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { - u32 phy_reg; - - if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &phy_reg)) + if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &val)) tg3_writephy(tp, MII_TG3_EXT_CTRL, - phy_reg | MII_TG3_EXT_CTRL_FIFO_ELASTIC); + val | MII_TG3_EXT_CTRL_FIFO_ELASTIC); } if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { @@ -2920,6 +2968,44 @@ static void tg3_phy_copper_begin(struct tg3 *tp) tg3_writephy(tp, MII_TG3_CTRL, new_adv); } + if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) { + u32 val = 0; + + tw32(TG3_CPMU_EEE_MODE, + tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE); + + /* Enable SM_DSP clock and tx 6dB coding. */ + val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL | + MII_TG3_AUXCTL_ACTL_SMDSP_ENA | + MII_TG3_AUXCTL_ACTL_TX_6DB; + tg3_writephy(tp, MII_TG3_AUX_CTRL, val); + + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) && + !tg3_phydsp_read(tp, MII_TG3_DSP_CH34TP2, &val)) + tg3_phydsp_write(tp, MII_TG3_DSP_CH34TP2, + val | MII_TG3_DSP_CH34TP2_HIBW01); + + if (tp->link_config.autoneg == AUTONEG_ENABLE) { + /* Advertise 100-BaseTX EEE ability */ + if (tp->link_config.advertising & + (ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full)) + val |= TG3_CL45_D7_EEEADV_CAP_100TX; + /* Advertise 1000-BaseT EEE ability */ + if (tp->link_config.advertising & + (ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full)) + val |= TG3_CL45_D7_EEEADV_CAP_1000T; + } + tg3_phy_cl45_write(tp, 0x7, TG3_CL45_D7_EEEADV_CAP, val); + + /* Turn off SM_DSP clock. */ + val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL | + MII_TG3_AUXCTL_ACTL_TX_6DB; + tg3_writephy(tp, MII_TG3_AUX_CTRL, val); + } + if (tp->link_config.autoneg == AUTONEG_DISABLE && tp->link_config.speed != SPEED_INVALID) { u32 bmcr, orig_bmcr; @@ -3060,7 +3146,7 @@ static int tg3_adv_1000T_flowctrl_ok(struct tg3 *tp, u32 *lcladv, u32 *rmtadv) static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) { int current_link_up; - u32 bmsr, dummy; + u32 bmsr, val; u32 lcl_adv, rmt_adv; u16 current_speed; u8 current_duplex; @@ -3140,8 +3226,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) } /* Clear pending interrupts... */ - tg3_readphy(tp, MII_TG3_ISTAT, &dummy); - tg3_readphy(tp, MII_TG3_ISTAT, &dummy); + tg3_readphy(tp, MII_TG3_ISTAT, &val); + tg3_readphy(tp, MII_TG3_ISTAT, &val); if (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) tg3_writephy(tp, MII_TG3_IMASK, ~MII_TG3_INT_LINKCHG); @@ -3162,8 +3248,6 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) current_duplex = DUPLEX_INVALID; if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) { - u32 val; - tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007); tg3_readphy(tp, MII_TG3_AUX_CTRL, &val); if (!(val & (1 << 10))) { @@ -3238,13 +3322,11 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) relink: if (current_link_up == 0 || (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { - u32 tmp; - tg3_phy_copper_begin(tp); - tg3_readphy(tp, MII_BMSR, &tmp); - if (!tg3_readphy(tp, MII_BMSR, &tmp) && - (tmp & BMSR_LSTATUS)) + tg3_readphy(tp, MII_BMSR, &bmsr); + if (!tg3_readphy(tp, MII_BMSR, &bmsr) && + (bmsr & BMSR_LSTATUS)) current_link_up = 1; } @@ -3285,6 +3367,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) tw32_f(MAC_MODE, tp->mac_mode); udelay(40); + tg3_phy_eee_adjust(tp, current_link_up); + if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { /* Polled via timer. */ tw32_f(MAC_EVENT, 0); @@ -4353,6 +4437,11 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) return err; } +static inline int tg3_irq_sync(struct tg3 *tp) +{ + return tp->irq_sync; +} + /* This is called whenever we suspect that the system chipset is re- * ordering the sequence of MMIO to the tx send mailbox. The symptom * is bogus tx completions. We try to recover by setting the @@ -4484,22 +4573,21 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, struct tg3_rx_prodring_set *tpr, u32 opaque_key, u32 dest_idx_unmasked) { struct tg3_rx_buffer_desc *desc; - struct ring_info *map, *src_map; + struct ring_info *map; struct sk_buff *skb; dma_addr_t mapping; int skb_size, dest_idx; - src_map = NULL; switch (opaque_key) { case RXD_OPAQUE_RING_STD: - dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE; + dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; desc = &tpr->rx_std[dest_idx]; map = &tpr->rx_std_buffers[dest_idx]; skb_size = tp->rx_pkt_map_sz; break; case RXD_OPAQUE_RING_JUMBO: - dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE; + dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask; desc = &tpr->rx_jmb[dest_idx].std; map = &tpr->rx_jmb_buffers[dest_idx]; skb_size = TG3_RX_JMB_MAP_SZ; @@ -4549,12 +4637,12 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi, struct tg3 *tp = tnapi->tp; struct tg3_rx_buffer_desc *src_desc, *dest_desc; struct ring_info *src_map, *dest_map; - struct tg3_rx_prodring_set *spr = &tp->prodring[0]; + struct tg3_rx_prodring_set *spr = &tp->napi[0].prodring; int dest_idx; switch (opaque_key) { case RXD_OPAQUE_RING_STD: - dest_idx = dest_idx_unmasked % TG3_RX_RING_SIZE; + dest_idx = dest_idx_unmasked & tp->rx_std_ring_mask; dest_desc = &dpr->rx_std[dest_idx]; dest_map = &dpr->rx_std_buffers[dest_idx]; src_desc = &spr->rx_std[src_idx]; @@ -4562,7 +4650,7 @@ static void tg3_recycle_rx(struct tg3_napi *tnapi, break; case RXD_OPAQUE_RING_JUMBO: - dest_idx = dest_idx_unmasked % TG3_RX_JUMBO_RING_SIZE; + dest_idx = dest_idx_unmasked & tp->rx_jmb_ring_mask; dest_desc = &dpr->rx_jmb[dest_idx].std; dest_map = &dpr->rx_jmb_buffers[dest_idx]; src_desc = &spr->rx_jmb[src_idx].std; @@ -4619,7 +4707,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) u32 sw_idx = tnapi->rx_rcb_ptr; u16 hw_idx; int received; - struct tg3_rx_prodring_set *tpr = tnapi->prodring; + struct tg3_rx_prodring_set *tpr = &tnapi->prodring; hw_idx = *(tnapi->rx_rcb_prod_idx); /* @@ -4644,13 +4732,13 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; if (opaque_key == RXD_OPAQUE_RING_STD) { - ri = &tp->prodring[0].rx_std_buffers[desc_idx]; + ri = &tp->napi[0].prodring.rx_std_buffers[desc_idx]; dma_addr = dma_unmap_addr(ri, mapping); skb = ri->skb; post_ptr = &std_prod_idx; rx_std_posted++; } else if (opaque_key == RXD_OPAQUE_RING_JUMBO) { - ri = &tp->prodring[0].rx_jmb_buffers[desc_idx]; + ri = &tp->napi[0].prodring.rx_jmb_buffers[desc_idx]; dma_addr = dma_unmap_addr(ri, mapping); skb = ri->skb; post_ptr = &jmb_prod_idx; @@ -4719,7 +4807,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) >> RXD_TCPCSUM_SHIFT) == 0xffff)) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); skb->protocol = eth_type_trans(skb, tp->dev); @@ -4762,7 +4850,8 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) (*post_ptr)++; if (unlikely(rx_std_posted >= tp->rx_std_max_post)) { - tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; + tpr->rx_std_prod_idx = std_prod_idx & + tp->rx_std_ring_mask; tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx); work_mask &= ~RXD_OPAQUE_RING_STD; @@ -4770,7 +4859,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) } next_pkt_nopost: sw_idx++; - sw_idx &= (TG3_RX_RCB_RING_SIZE(tp) - 1); + sw_idx &= tp->rx_ret_ring_mask; /* Refresh hw_idx to see if there is new work */ if (sw_idx == hw_idx) { @@ -4786,13 +4875,14 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) /* Refill RX ring(s). */ if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) { if (work_mask & RXD_OPAQUE_RING_STD) { - tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; + tpr->rx_std_prod_idx = std_prod_idx & + tp->rx_std_ring_mask; tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx); } if (work_mask & RXD_OPAQUE_RING_JUMBO) { - tpr->rx_jmb_prod_idx = jmb_prod_idx % - TG3_RX_JUMBO_RING_SIZE; + tpr->rx_jmb_prod_idx = jmb_prod_idx & + tp->rx_jmb_ring_mask; tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx); } @@ -4803,8 +4893,8 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget) */ smp_wmb(); - tpr->rx_std_prod_idx = std_prod_idx % TG3_RX_RING_SIZE; - tpr->rx_jmb_prod_idx = jmb_prod_idx % TG3_RX_JUMBO_RING_SIZE; + tpr->rx_std_prod_idx = std_prod_idx & tp->rx_std_ring_mask; + tpr->rx_jmb_prod_idx = jmb_prod_idx & tp->rx_jmb_ring_mask; if (tnapi != &tp->napi[1]) napi_schedule(&tp->napi[1].napi); @@ -4860,9 +4950,11 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, if (spr->rx_std_cons_idx < src_prod_idx) cpycnt = src_prod_idx - spr->rx_std_cons_idx; else - cpycnt = TG3_RX_RING_SIZE - spr->rx_std_cons_idx; + cpycnt = tp->rx_std_ring_mask + 1 - + spr->rx_std_cons_idx; - cpycnt = min(cpycnt, TG3_RX_RING_SIZE - dpr->rx_std_prod_idx); + cpycnt = min(cpycnt, + tp->rx_std_ring_mask + 1 - dpr->rx_std_prod_idx); si = spr->rx_std_cons_idx; di = dpr->rx_std_prod_idx; @@ -4896,10 +4988,10 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, dbd->addr_lo = sbd->addr_lo; } - spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) % - TG3_RX_RING_SIZE; - dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) % - TG3_RX_RING_SIZE; + spr->rx_std_cons_idx = (spr->rx_std_cons_idx + cpycnt) & + tp->rx_std_ring_mask; + dpr->rx_std_prod_idx = (dpr->rx_std_prod_idx + cpycnt) & + tp->rx_std_ring_mask; } while (1) { @@ -4916,10 +5008,11 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, if (spr->rx_jmb_cons_idx < src_prod_idx) cpycnt = src_prod_idx - spr->rx_jmb_cons_idx; else - cpycnt = TG3_RX_JUMBO_RING_SIZE - spr->rx_jmb_cons_idx; + cpycnt = tp->rx_jmb_ring_mask + 1 - + spr->rx_jmb_cons_idx; cpycnt = min(cpycnt, - TG3_RX_JUMBO_RING_SIZE - dpr->rx_jmb_prod_idx); + tp->rx_jmb_ring_mask + 1 - dpr->rx_jmb_prod_idx); si = spr->rx_jmb_cons_idx; di = dpr->rx_jmb_prod_idx; @@ -4953,10 +5046,10 @@ static int tg3_rx_prodring_xfer(struct tg3 *tp, dbd->addr_lo = sbd->addr_lo; } - spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) % - TG3_RX_JUMBO_RING_SIZE; - dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) % - TG3_RX_JUMBO_RING_SIZE; + spr->rx_jmb_cons_idx = (spr->rx_jmb_cons_idx + cpycnt) & + tp->rx_jmb_ring_mask; + dpr->rx_jmb_prod_idx = (dpr->rx_jmb_prod_idx + cpycnt) & + tp->rx_jmb_ring_mask; } return err; @@ -4981,14 +5074,14 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget) work_done += tg3_rx(tnapi, budget - work_done); if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) { - struct tg3_rx_prodring_set *dpr = &tp->prodring[0]; + struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring; int i, err = 0; u32 std_prod_idx = dpr->rx_std_prod_idx; u32 jmb_prod_idx = dpr->rx_jmb_prod_idx; for (i = 1; i < tp->irq_cnt; i++) err |= tg3_rx_prodring_xfer(tp, dpr, - tp->napi[i].prodring); + &tp->napi[i].prodring); wmb(); @@ -5098,6 +5191,59 @@ static int tg3_poll(struct napi_struct *napi, int budget) return work_done; } +static void tg3_napi_disable(struct tg3 *tp) +{ + int i; + + for (i = tp->irq_cnt - 1; i >= 0; i--) + napi_disable(&tp->napi[i].napi); +} + +static void tg3_napi_enable(struct tg3 *tp) +{ + int i; + + for (i = 0; i < tp->irq_cnt; i++) + napi_enable(&tp->napi[i].napi); +} + +static void tg3_napi_init(struct tg3 *tp) +{ + int i; + + netif_napi_add(tp->dev, &tp->napi[0].napi, tg3_poll, 64); + for (i = 1; i < tp->irq_cnt; i++) + netif_napi_add(tp->dev, &tp->napi[i].napi, tg3_poll_msix, 64); +} + +static void tg3_napi_fini(struct tg3 *tp) +{ + int i; + + for (i = 0; i < tp->irq_cnt; i++) + netif_napi_del(&tp->napi[i].napi); +} + +static inline void tg3_netif_stop(struct tg3 *tp) +{ + tp->dev->trans_start = jiffies; /* prevent tx timeout */ + tg3_napi_disable(tp); + netif_tx_disable(tp->dev); +} + +static inline void tg3_netif_start(struct tg3 *tp) +{ + /* NOTE: unconditional netif_tx_wake_all_queues is only + * appropriate so long as all callers are assured to + * have free tx slots (such as after tg3_init_hw) + */ + netif_tx_wake_all_queues(tp->dev); + + tg3_napi_enable(tp); + tp->napi[0].hw_status->status |= SD_STATUS_UPDATED; + tg3_enable_ints(tp); +} + static void tg3_irq_quiesce(struct tg3 *tp) { int i; @@ -5111,11 +5257,6 @@ static void tg3_irq_quiesce(struct tg3 *tp) synchronize_irq(tp->napi[i].irq_vec); } -static inline int tg3_irq_sync(struct tg3 *tp) -{ - return tp->irq_sync; -} - /* Fully shutdown all tg3 driver activity elsewhere in the system. * If irq_sync is non-zero, then the IRQ handler must be synchronized * with as well. Most of the time, this is not necessary except when @@ -5404,8 +5545,7 @@ static inline int tg3_4g_overflow_test(dma_addr_t mapping, int len) { u32 base = (u32) mapping & 0xffffffff; - return ((base > 0xffffdcc0) && - (base + len + 8 < base)); + return (base > 0xffffdcc0) && (base + len + 8 < base); } /* Test for DMA addresses > 40-bit */ @@ -5414,7 +5554,7 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping, { #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64) if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) - return (((u64) mapping + len) > DMA_BIT_MASK(40)); + return ((u64) mapping + len) > DMA_BIT_MASK(40); return 0; #else return 0; @@ -5574,9 +5714,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, goto out_unlock; } - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) + if (skb_is_gso_v6(skb)) { hdrlen = skb_headlen(skb) - ETH_HLEN; - else { + } else { struct iphdr *iph = ip_hdr(skb); tcp_opt_len = tcp_optlen(skb); @@ -5605,7 +5745,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, } #if TG3_VLAN_TAG_USED - if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | (vlan_tx_tag_get(skb) << 16)); #endif @@ -5798,7 +5938,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, iph = ip_hdr(skb); tcp_opt_len = tcp_optlen(skb); - if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6) { + if (skb_is_gso_v6(skb)) { hdr_len = skb_headlen(skb) - ETH_HLEN; } else { u32 ip_tcp_len; @@ -5851,7 +5991,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb, } } #if TG3_VLAN_TAG_USED - if (tp->vlgrp != NULL && vlan_tx_tag_present(skb)) + if (vlan_tx_tag_present(skb)) base_flags |= (TXD_FLAG_VLAN | (vlan_tx_tag_get(skb) << 16)); #endif @@ -6057,16 +6197,16 @@ static void tg3_rx_prodring_free(struct tg3 *tp, { int i; - if (tpr != &tp->prodring[0]) { + if (tpr != &tp->napi[0].prodring) { for (i = tpr->rx_std_cons_idx; i != tpr->rx_std_prod_idx; - i = (i + 1) % TG3_RX_RING_SIZE) + i = (i + 1) & tp->rx_std_ring_mask) tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], tp->rx_pkt_map_sz); if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { for (i = tpr->rx_jmb_cons_idx; i != tpr->rx_jmb_prod_idx; - i = (i + 1) % TG3_RX_JUMBO_RING_SIZE) { + i = (i + 1) & tp->rx_jmb_ring_mask) { tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i], TG3_RX_JMB_MAP_SZ); } @@ -6075,12 +6215,13 @@ static void tg3_rx_prodring_free(struct tg3 *tp, return; } - for (i = 0; i < TG3_RX_RING_SIZE; i++) + for (i = 0; i <= tp->rx_std_ring_mask; i++) tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i], tp->rx_pkt_map_sz); - if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { - for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) + if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { + for (i = 0; i <= tp->rx_jmb_ring_mask; i++) tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i], TG3_RX_JMB_MAP_SZ); } @@ -6103,16 +6244,17 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, tpr->rx_jmb_cons_idx = 0; tpr->rx_jmb_prod_idx = 0; - if (tpr != &tp->prodring[0]) { - memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE); - if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) + if (tpr != &tp->napi[0].prodring) { + memset(&tpr->rx_std_buffers[0], 0, + TG3_RX_STD_BUFF_RING_SIZE(tp)); + if (tpr->rx_jmb_buffers) memset(&tpr->rx_jmb_buffers[0], 0, - TG3_RX_JMB_BUFF_RING_SIZE); + TG3_RX_JMB_BUFF_RING_SIZE(tp)); goto done; } /* Zero out all descriptors. */ - memset(tpr->rx_std, 0, TG3_RX_RING_BYTES); + memset(tpr->rx_std, 0, TG3_RX_STD_RING_BYTES(tp)); rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ; if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) && @@ -6124,7 +6266,7 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, * stuff once. This works because the card does not * write into the rx buffer posting rings. */ - for (i = 0; i < TG3_RX_RING_SIZE; i++) { + for (i = 0; i <= tp->rx_std_ring_mask; i++) { struct tg3_rx_buffer_desc *rxd; rxd = &tpr->rx_std[i]; @@ -6148,15 +6290,16 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp, } } - if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)) + if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) || + (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) goto done; - memset(tpr->rx_jmb, 0, TG3_RX_JUMBO_RING_BYTES); + memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp)); if (!(tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)) goto done; - for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) { + for (i = 0; i <= tp->rx_jmb_ring_mask; i++) { struct tg3_rx_buffer_desc *rxd; rxd = &tpr->rx_jmb[i].std; @@ -6196,12 +6339,12 @@ static void tg3_rx_prodring_fini(struct tg3 *tp, kfree(tpr->rx_jmb_buffers); tpr->rx_jmb_buffers = NULL; if (tpr->rx_std) { - pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES, + pci_free_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp), tpr->rx_std, tpr->rx_std_mapping); tpr->rx_std = NULL; } if (tpr->rx_jmb) { - pci_free_consistent(tp->pdev, TG3_RX_JUMBO_RING_BYTES, + pci_free_consistent(tp->pdev, TG3_RX_JMB_RING_BYTES(tp), tpr->rx_jmb, tpr->rx_jmb_mapping); tpr->rx_jmb = NULL; } @@ -6210,23 +6353,25 @@ static void tg3_rx_prodring_fini(struct tg3 *tp, static int tg3_rx_prodring_init(struct tg3 *tp, struct tg3_rx_prodring_set *tpr) { - tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL); + tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE(tp), + GFP_KERNEL); if (!tpr->rx_std_buffers) return -ENOMEM; - tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_RING_BYTES, + tpr->rx_std = pci_alloc_consistent(tp->pdev, TG3_RX_STD_RING_BYTES(tp), &tpr->rx_std_mapping); if (!tpr->rx_std) goto err_out; - if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) { - tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE, + if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { + tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE(tp), GFP_KERNEL); if (!tpr->rx_jmb_buffers) goto err_out; tpr->rx_jmb = pci_alloc_consistent(tp->pdev, - TG3_RX_JUMBO_RING_BYTES, + TG3_RX_JMB_RING_BYTES(tp), &tpr->rx_jmb_mapping); if (!tpr->rx_jmb) goto err_out; @@ -6253,7 +6398,7 @@ static void tg3_free_rings(struct tg3 *tp) for (j = 0; j < tp->irq_cnt; j++) { struct tg3_napi *tnapi = &tp->napi[j]; - tg3_rx_prodring_free(tp, &tp->prodring[j]); + tg3_rx_prodring_free(tp, &tnapi->prodring); if (!tnapi->tx_buffers) continue; @@ -6325,7 +6470,7 @@ static int tg3_init_rings(struct tg3 *tp) if (tnapi->rx_rcb) memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); - if (tg3_rx_prodring_alloc(tp, &tp->prodring[i])) { + if (tg3_rx_prodring_alloc(tp, &tnapi->prodring)) { tg3_free_rings(tp); return -ENOMEM; } @@ -6361,6 +6506,8 @@ static void tg3_free_consistent(struct tg3 *tp) tnapi->rx_rcb = NULL; } + tg3_rx_prodring_fini(tp, &tnapi->prodring); + if (tnapi->hw_status) { pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE, tnapi->hw_status, @@ -6374,9 +6521,6 @@ static void tg3_free_consistent(struct tg3 *tp) tp->hw_stats, tp->stats_mapping); tp->hw_stats = NULL; } - - for (i = 0; i < tp->irq_cnt; i++) - tg3_rx_prodring_fini(tp, &tp->prodring[i]); } /* @@ -6387,11 +6531,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) { int i; - for (i = 0; i < tp->irq_cnt; i++) { - if (tg3_rx_prodring_init(tp, &tp->prodring[i])) - goto err_out; - } - tp->hw_stats = pci_alloc_consistent(tp->pdev, sizeof(struct tg3_hw_stats), &tp->stats_mapping); @@ -6413,6 +6552,9 @@ static int tg3_alloc_consistent(struct tg3 *tp) memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); sblk = tnapi->hw_status; + if (tg3_rx_prodring_init(tp, &tnapi->prodring)) + goto err_out; + /* If multivector TSS is enabled, vector 0 does not handle * tx interrupts. Don't allocate any resources for it. */ @@ -6452,8 +6594,6 @@ static int tg3_alloc_consistent(struct tg3 *tp) break; } - tnapi->prodring = &tp->prodring[i]; - /* * If multivector RSS is enabled, vector 0 does not handle * rx or tx interrupts. Don't allocate any resources for it. @@ -6596,6 +6736,10 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event) int i; u32 apedata; + /* NCSI does not support APE events */ + if (tp->tg3_flags3 & TG3_FLG3_APE_HAS_NCSI) + return; + apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG); if (apedata != APE_SEG_SIG_MAGIC) return; @@ -6647,6 +6791,8 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) APE_HOST_DRIVER_ID_MAGIC(TG3_MAJ_NUM, TG3_MIN_NUM)); tg3_ape_write32(tp, TG3_APE_HOST_BEHAVIOR, APE_HOST_BEHAV_NO_PHYLOCK); + tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, + TG3_APE_HOST_DRVR_STATE_START); event = APE_EVENT_STATUS_STATE_START; break; @@ -6658,6 +6804,16 @@ static void tg3_ape_driver_state_change(struct tg3 *tp, int kind) */ tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0); + if (device_may_wakeup(&tp->pdev->dev) && + (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) { + tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED, + TG3_APE_HOST_WOL_SPEED_AUTO); + apedata = TG3_APE_HOST_DRVR_STATE_WOL; + } else + apedata = TG3_APE_HOST_DRVR_STATE_UNLOAD; + + tg3_ape_write32(tp, TG3_APE_HOST_DRVR_STATE, apedata); + event = APE_EVENT_STATUS_STATE_UNLOAD; break; case RESET_KIND_SUSPEND: @@ -7515,6 +7671,9 @@ static void tg3_rings_reset(struct tg3 *tp) /* Disable all transmit rings but the first. */ if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16; + else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4; else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2; else @@ -7548,7 +7707,7 @@ static void tg3_rings_reset(struct tg3 *tp) /* Zero mailbox registers. */ if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) { - for (i = 1; i < TG3_IRQ_MAX_VECS; i++) { + for (i = 1; i < tp->irq_max; i++) { tp->napi[i].tx_prod = 0; tp->napi[i].tx_cons = 0; if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) @@ -7594,8 +7753,8 @@ static void tg3_rings_reset(struct tg3 *tp) if (tnapi->rx_rcb) { tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping, - (TG3_RX_RCB_RING_SIZE(tp) << - BDINFO_FLAGS_MAXLEN_SHIFT), 0); + (tp->rx_ret_ring_mask + 1) << + BDINFO_FLAGS_MAXLEN_SHIFT, 0); rxrcb += TG3_BDINFO_SIZE; } @@ -7618,7 +7777,7 @@ static void tg3_rings_reset(struct tg3 *tp) } tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping, - (TG3_RX_RCB_RING_SIZE(tp) << + ((tp->rx_ret_ring_mask + 1) << BDINFO_FLAGS_MAXLEN_SHIFT), 0); stblk += 8; @@ -7631,7 +7790,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) { u32 val, rdmac_mode; int i, err, limit; - struct tg3_rx_prodring_set *tpr = &tp->prodring[0]; + struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring; tg3_disable_ints(tp); @@ -7720,6 +7879,22 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(TG3_CPMU_LSPD_10MB_CLK, val); } + /* Enable MAC control of LPI */ + if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) { + tw32_f(TG3_CPMU_EEE_LNKIDL_CTRL, + TG3_CPMU_EEE_LNKIDL_PCIE_NL0 | + TG3_CPMU_EEE_LNKIDL_UART_IDL); + + tw32_f(TG3_CPMU_EEE_CTRL, + TG3_CPMU_EEE_CTRL_EXIT_20_1_US); + + tw32_f(TG3_CPMU_EEE_MODE, + TG3_CPMU_EEEMD_ERLY_L1_XIT_DET | + TG3_CPMU_EEEMD_LPI_IN_TX | + TG3_CPMU_EEEMD_LPI_IN_RX | + TG3_CPMU_EEEMD_EEE_ENABLE); + } + /* This works around an issue with Athlon chipsets on * B3 tigon3 silicon. This bit has no effect on any * other revision. But do not set this on PCI Express @@ -7845,7 +8020,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(BUFMGR_DMA_HIGH_WATER, tp->bufmgr_config.dma_high_water); - tw32(BUFMGR_MODE, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE); + val = BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + val |= BUFMGR_MODE_NO_TX_UNDERRUN; + tw32(BUFMGR_MODE, val); for (i = 0; i < 2000; i++) { if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE) break; @@ -7928,10 +8106,14 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) BDINFO_FLAGS_DISABLED); } - if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) - val = (RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT) | - (TG3_RX_STD_DMA_SZ << 2); - else + if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) { + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) + val = RX_STD_MAX_SIZE_5705; + else + val = RX_STD_MAX_SIZE_5717; + val <<= BDINFO_FLAGS_MAXLEN_SHIFT; + val |= (TG3_RX_STD_DMA_SZ << 2); + } else val = TG3_RX_STD_DMA_SZ << BDINFO_FLAGS_MAXLEN_SHIFT; } else val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT; @@ -8015,6 +8197,23 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 || + (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) { + val = tr32(TG3_RDMA_RSRVCTRL_REG); + tw32(TG3_RDMA_RSRVCTRL_REG, + val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX); + } + + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { + val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL); + tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val | + TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K | + TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K); + } + /* Receive/send statistics. */ if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) { val = tr32(RCVLPC_STATS_ENABLE); @@ -8197,7 +8396,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE); tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB); - tw32(RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ); + val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + val |= RCVDBDI_MODE_LRG_RING_SZ; + tw32(RCVDBDI_MODE, val); tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); @@ -8500,6 +8703,12 @@ static void tg3_timer(unsigned long __opaque) if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) tg3_periodic_fetch_stats(tp); + if (tp->setlpicnt && !--tp->setlpicnt) { + u32 val = tr32(TG3_CPMU_EEE_MODE); + tw32(TG3_CPMU_EEE_MODE, + val | TG3_CPMU_EEEMD_LPI_ENABLE); + } + if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { u32 mac_stat; int phy_event; @@ -8816,16 +9025,14 @@ static bool tg3_enable_msix(struct tg3 *tp) for (i = 0; i < tp->irq_max; i++) tp->napi[i].irq_vec = msix_ent[i].vector; - tp->dev->real_num_tx_queues = 1; - if (tp->irq_cnt > 1) { - tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; - - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) { - tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS; - tp->dev->real_num_tx_queues = tp->irq_cnt - 1; - } + netif_set_real_num_tx_queues(tp->dev, 1); + rc = tp->irq_cnt > 1 ? tp->irq_cnt - 1 : 1; + if (netif_set_real_num_rx_queues(tp->dev, rc)) { + pci_disable_msix(tp->pdev); + return false; } + if (tp->irq_cnt > 1) + tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; return true; } @@ -8858,7 +9065,8 @@ static void tg3_ints_init(struct tg3 *tp) if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) { tp->irq_cnt = 1; tp->napi[0].irq_vec = tp->pdev->irq; - tp->dev->real_num_tx_queues = 1; + netif_set_real_num_tx_queues(tp->dev, 1); + netif_set_real_num_rx_queues(tp->dev, 1); } } @@ -8917,6 +9125,8 @@ static int tg3_open(struct net_device *dev) if (err) goto err_out1; + tg3_napi_init(tp); + tg3_napi_enable(tp); for (i = 0; i < tp->irq_cnt; i++) { @@ -9004,6 +9214,7 @@ static int tg3_open(struct net_device *dev) err_out2: tg3_napi_disable(tp); + tg3_napi_fini(tp); tg3_free_consistent(tp); err_out1: @@ -9051,6 +9262,8 @@ static int tg3_close(struct net_device *dev) memcpy(&tp->estats_prev, tg3_get_estats(tp), sizeof(tp->estats_prev)); + tg3_napi_fini(tp); + tg3_free_consistent(tp); tg3_set_power_state(tp, PCI_D3hot); @@ -9596,6 +9809,9 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) if (netif_running(dev)) { cmd->speed = tp->link_config.active_speed; cmd->duplex = tp->link_config.active_duplex; + } else { + cmd->speed = SPEED_INVALID; + cmd->duplex = DUPLEX_INVALID; } cmd->phy_address = tp->phy_addr; cmd->transceiver = XCVR_INTERNAL; @@ -9822,10 +10038,10 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * { struct tg3 *tp = netdev_priv(dev); - ering->rx_max_pending = TG3_RX_RING_SIZE - 1; + ering->rx_max_pending = tp->rx_std_ring_mask; ering->rx_mini_max_pending = 0; if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) - ering->rx_jumbo_max_pending = TG3_RX_JUMBO_RING_SIZE - 1; + ering->rx_jumbo_max_pending = tp->rx_jmb_ring_mask; else ering->rx_jumbo_max_pending = 0; @@ -9846,8 +10062,8 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e struct tg3 *tp = netdev_priv(dev); int i, irq_sync = 0, err = 0; - if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || - (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || + if ((ering->rx_pending > tp->rx_std_ring_mask) || + (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) || (ering->tx_pending > TG3_TX_RING_SIZE - 1) || (ering->tx_pending <= MAX_SKB_FRAGS) || ((tp->tg3_flags2 & TG3_FLG2_TSO_BUG) && @@ -9869,7 +10085,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e tp->rx_pending = 63; tp->rx_jumbo_pending = ering->rx_jumbo_pending; - for (i = 0; i < TG3_IRQ_MAX_VECS; i++) + for (i = 0; i < tp->irq_max; i++) tp->napi[i].tx_pending = ering->tx_pending; if (netif_running(dev)) { @@ -9917,8 +10133,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam if (!(phydev->supported & SUPPORTED_Pause) || (!(phydev->supported & SUPPORTED_Asym_Pause) && - ((epause->rx_pause && !epause->tx_pause) || - (!epause->rx_pause && epause->tx_pause)))) + (epause->rx_pause != epause->tx_pause))) return -EINVAL; tp->link_config.flowctrl = 0; @@ -10610,12 +10825,13 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) int num_pkts, tx_len, rx_len, i, err; struct tg3_rx_buffer_desc *desc; struct tg3_napi *tnapi, *rnapi; - struct tg3_rx_prodring_set *tpr = &tp->prodring[0]; + struct tg3_rx_prodring_set *tpr = &tp->napi[0].prodring; tnapi = &tp->napi[0]; rnapi = &tp->napi[0]; if (tp->irq_cnt > 1) { - rnapi = &tp->napi[1]; + if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) + rnapi = &tp->napi[1]; if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) tnapi = &tp->napi[1]; } @@ -12332,6 +12548,11 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) } } + if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || + (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && + tp->pci_chip_rev_id != CHIPREV_ID_57765_A0)) + tp->phy_flags |= TG3_PHYFLG_EEE_CAP; + if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { @@ -12403,14 +12624,18 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) static void __devinit tg3_read_vpd(struct tg3 *tp) { - u8 vpd_data[TG3_NVM_VPD_LEN]; + u8 *vpd_data; unsigned int block_end, rosize, len; int j, i = 0; u32 magic; if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) || tg3_nvram_read(tp, 0x0, &magic)) - goto out_not_found; + goto out_no_vpd; + + vpd_data = kmalloc(TG3_NVM_VPD_LEN, GFP_KERNEL); + if (!vpd_data) + goto out_no_vpd; if (magic == TG3_EEPROM_MAGIC) { for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) { @@ -12494,43 +12719,51 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) memcpy(tp->board_part_number, &vpd_data[i], len); - return; - out_not_found: - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + kfree(vpd_data); + if (tp->board_part_number[0]) + return; + +out_no_vpd: + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) { + if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717) + strcpy(tp->board_part_number, "BCM5717"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718) + strcpy(tp->board_part_number, "BCM5718"); + else + goto nomatch; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) { + if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780) + strcpy(tp->board_part_number, "BCM57780"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760) + strcpy(tp->board_part_number, "BCM57760"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790) + strcpy(tp->board_part_number, "BCM57790"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788) + strcpy(tp->board_part_number, "BCM57788"); + else + goto nomatch; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) { + if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761) + strcpy(tp->board_part_number, "BCM57761"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765) + strcpy(tp->board_part_number, "BCM57765"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781) + strcpy(tp->board_part_number, "BCM57781"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785) + strcpy(tp->board_part_number, "BCM57785"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791) + strcpy(tp->board_part_number, "BCM57791"); + else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795) + strcpy(tp->board_part_number, "BCM57795"); + else + goto nomatch; + } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { strcpy(tp->board_part_number, "BCM95906"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780) - strcpy(tp->board_part_number, "BCM57780"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760) - strcpy(tp->board_part_number, "BCM57760"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790) - strcpy(tp->board_part_number, "BCM57790"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57788) - strcpy(tp->board_part_number, "BCM57788"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57761) - strcpy(tp->board_part_number, "BCM57761"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57765) - strcpy(tp->board_part_number, "BCM57765"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57781) - strcpy(tp->board_part_number, "BCM57781"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57785) - strcpy(tp->board_part_number, "BCM57785"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57791) - strcpy(tp->board_part_number, "BCM57791"); - else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 && - tp->pdev->device == TG3PCI_DEVICE_TIGON3_57795) - strcpy(tp->board_part_number, "BCM57795"); - else + } else { +nomatch: strcpy(tp->board_part_number, "none"); + } } static int __devinit tg3_fw_img_is_valid(struct tg3 *tp, u32 offset) @@ -12639,6 +12872,9 @@ static void __devinit tg3_read_sb_ver(struct tg3 *tp, u32 val) case TG3_EEPROM_SB_REVISION_5: offset = TG3_EEPROM_SB_F1R5_EDH_OFF; break; + case TG3_EEPROM_SB_REVISION_6: + offset = TG3_EEPROM_SB_F1R6_EDH_OFF; + break; default: return; } @@ -12738,10 +12974,12 @@ static void __devinit tg3_read_dash_ver(struct tg3 *tp) apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION); - if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) + if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) { + tp->tg3_flags3 |= TG3_FLG3_APE_HAS_NCSI; fwtype = "NCSI"; - else + } else { fwtype = "DASH"; + } vlen = strlen(tp->fw_ver); @@ -12797,6 +13035,18 @@ static void inline vlan_features_add(struct net_device *dev, unsigned long flags #endif } +static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp) +{ + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) + return 4096; + else if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) && + !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) + return 1024; + else + return 512; +} + static int __devinit tg3_get_invariants(struct tg3 *tp) { static struct pci_device_id write_reorder_chipsets[] = { @@ -12841,7 +13091,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 || - tp->pdev->device == TG3PCI_DEVICE_TIGON3_5724 || tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719) pci_read_config_dword(tp->pdev, TG3PCI_GEN2_PRODID_ASICREV, @@ -13412,10 +13661,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (err) return err; - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 && - tp->pci_chip_rev_id != CHIPREV_ID_5717_A0) - return -ENOTSUPP; - /* Initialize data/descriptor byte/word swapping. */ val = tr32(GRC_MODE); val &= GRC_MODE_HOST_STACKUP; @@ -13555,7 +13800,11 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) #endif } - tp->rx_std_max_post = TG3_RX_RING_SIZE; + tp->rx_std_ring_mask = TG3_RX_STD_RING_SIZE(tp) - 1; + tp->rx_jmb_ring_mask = TG3_RX_JMB_RING_SIZE(tp) - 1; + tp->rx_ret_ring_mask = tg3_rx_ret_ring_size(tp) - 1; + + tp->rx_std_max_post = tp->rx_std_ring_mask + 1; /* Increment the rx prod index on the rx std ring by at most * 8 for these chips to workaround hw errata. @@ -14444,7 +14693,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, } if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) && - tp->pci_chip_rev_id != CHIPREV_ID_5717_A0 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 && GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719) dev->netdev_ops = &tg3_netdev_ops; else @@ -14583,7 +14832,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, intmbx = MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW; rcvmbx = MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW; sndmbx = MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW; - for (i = 0; i < TG3_IRQ_MAX_VECS; i++) { + for (i = 0; i < tp->irq_max; i++) { struct tg3_napi *tnapi = &tp->napi[i]; tnapi->tp = tp; @@ -14598,13 +14847,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, tnapi->consmbox = rcvmbx; tnapi->prodmbox = sndmbx; - if (i) { + if (i) tnapi->coal_now = HOSTCC_MODE_COAL_VEC1_NOW << (i - 1); - netif_napi_add(dev, &tnapi->napi, tg3_poll_msix, 64); - } else { + else tnapi->coal_now = HOSTCC_MODE_NOW; - netif_napi_add(dev, &tnapi->napi, tg3_poll, 64); - } if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX)) break; diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index be7ff138a7f98d58a4f4d4c8ff7fe70bb83911d9..4a1974804b9fcd0c6531c86f899c03834d0061db 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -26,6 +26,7 @@ #define TG3_RX_INTERNAL_RING_SZ_5906 32 #define RX_STD_MAX_SIZE_5705 512 +#define RX_STD_MAX_SIZE_5717 2048 #define RX_JUMBO_MAX_SIZE 0xdeadbeef /* XXX */ /* First 256 bytes are a mirror of PCI config space. */ @@ -46,7 +47,6 @@ #define TG3PCI_DEVICE_TIGON3_5785_F 0x16a0 /* 10/100 only */ #define TG3PCI_DEVICE_TIGON3_5717 0x1655 #define TG3PCI_DEVICE_TIGON3_5718 0x1656 -#define TG3PCI_DEVICE_TIGON3_5724 0x165c #define TG3PCI_DEVICE_TIGON3_57781 0x16b1 #define TG3PCI_DEVICE_TIGON3_57785 0x16b5 #define TG3PCI_DEVICE_TIGON3_57761 0x16b0 @@ -973,6 +973,7 @@ #define RCVDBDI_MODE_JUMBOBD_NEEDED 0x00000004 #define RCVDBDI_MODE_FRM_TOO_BIG 0x00000008 #define RCVDBDI_MODE_INV_RING_SZ 0x00000010 +#define RCVDBDI_MODE_LRG_RING_SZ 0x00010000 #define RCVDBDI_STATUS 0x00002404 #define RCVDBDI_STATUS_JUMBOBD_NEEDED 0x00000004 #define RCVDBDI_STATUS_FRM_TOO_BIG 0x00000008 @@ -1090,7 +1091,26 @@ #define CPMU_MUTEX_GNT_DRIVER 0x00001000 #define TG3_CPMU_PHY_STRAP 0x00003664 #define TG3_CPMU_PHY_STRAP_IS_SERDES 0x00000020 -/* 0x3664 --> 0x3800 unused */ +/* 0x3664 --> 0x36b0 unused */ + +#define TG3_CPMU_EEE_MODE 0x000036b0 +#define TG3_CPMU_EEEMD_ERLY_L1_XIT_DET 0x00000008 +#define TG3_CPMU_EEEMD_LPI_ENABLE 0x00000080 +#define TG3_CPMU_EEEMD_LPI_IN_TX 0x00000100 +#define TG3_CPMU_EEEMD_LPI_IN_RX 0x00000200 +#define TG3_CPMU_EEEMD_EEE_ENABLE 0x00100000 +/* 0x36b4 --> 0x36b8 unused */ + +#define TG3_CPMU_EEE_LNKIDL_CTRL 0x000036bc +#define TG3_CPMU_EEE_LNKIDL_PCIE_NL0 0x01000000 +#define TG3_CPMU_EEE_LNKIDL_UART_IDL 0x00000004 +/* 0x36c0 --> 0x36d0 unused */ + +#define TG3_CPMU_EEE_CTRL 0x000036d0 +#define TG3_CPMU_EEE_CTRL_EXIT_16_5_US 0x0000019d +#define TG3_CPMU_EEE_CTRL_EXIT_36_US 0x00000384 +#define TG3_CPMU_EEE_CTRL_EXIT_20_1_US 0x000001f8 +/* 0x36d4 --> 0x3800 unused */ /* Mbuf cluster free registers */ #define MBFREE_MODE 0x00003800 @@ -1225,6 +1245,7 @@ #define BUFMGR_MODE_ATTN_ENABLE 0x00000004 #define BUFMGR_MODE_BM_TEST 0x00000008 #define BUFMGR_MODE_MBLOW_ATTN_ENAB 0x00000010 +#define BUFMGR_MODE_NO_TX_UNDERRUN 0x80000000 #define BUFMGR_STATUS 0x00004404 #define BUFMGR_STATUS_ERROR 0x00000004 #define BUFMGR_STATUS_MBLOW 0x00000010 @@ -1302,7 +1323,16 @@ #define RDMAC_STATUS_FIFOURUN 0x00000080 #define RDMAC_STATUS_FIFOOREAD 0x00000100 #define RDMAC_STATUS_LNGREAD 0x00000200 -/* 0x4808 --> 0x4c00 unused */ +/* 0x4808 --> 0x4900 unused */ + +#define TG3_RDMA_RSRVCTRL_REG 0x00004900 +#define TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX 0x00000004 +/* 0x4904 --> 0x4910 unused */ + +#define TG3_LSO_RD_DMA_CRPTEN_CTRL 0x00004910 +#define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K 0x00030000 +#define TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_LSO_4K 0x000c0000 +/* 0x4914 --> 0x4c00 unused */ /* Write DMA control registers */ #define WDMAC_MODE 0x00004c00 @@ -1904,6 +1934,7 @@ #define TG3_EEPROM_SB_REVISION_3 0x00030000 #define TG3_EEPROM_SB_REVISION_4 0x00040000 #define TG3_EEPROM_SB_REVISION_5 0x00050000 +#define TG3_EEPROM_SB_REVISION_6 0x00060000 #define TG3_EEPROM_MAGIC_HW 0xabcd #define TG3_EEPROM_MAGIC_HW_MSK 0xffff @@ -1923,6 +1954,7 @@ #define TG3_EEPROM_SB_F1R3_EDH_OFF 0x18 #define TG3_EEPROM_SB_F1R4_EDH_OFF 0x1c #define TG3_EEPROM_SB_F1R5_EDH_OFF 0x20 +#define TG3_EEPROM_SB_F1R6_EDH_OFF 0x4c #define TG3_EEPROM_SB_EDH_MAJ_MASK 0x00000700 #define TG3_EEPROM_SB_EDH_MAJ_SHFT 8 #define TG3_EEPROM_SB_EDH_MIN_MASK 0x000000ff @@ -2048,6 +2080,10 @@ #define MII_TG3_CTRL_AS_MASTER 0x0800 #define MII_TG3_CTRL_ENABLE_AS_MASTER 0x1000 +#define MII_TG3_MMD_CTRL 0x0d /* MMD Access Control register */ +#define MII_TG3_MMD_CTRL_DATA_NOINC 0x4000 +#define MII_TG3_MMD_ADDRESS 0x0e /* MMD Address Data register */ + #define MII_TG3_EXT_CTRL 0x10 /* Extended control register */ #define MII_TG3_EXT_CTRL_FIFO_ELASTIC 0x0001 #define MII_TG3_EXT_CTRL_LNK3_LED_MODE 0x0002 @@ -2065,6 +2101,8 @@ #define MII_TG3_DSP_TAP1 0x0001 #define MII_TG3_DSP_TAP1_AGCTGT_DFLT 0x0007 #define MII_TG3_DSP_AADJ1CH0 0x001f +#define MII_TG3_DSP_CH34TP2 0x4022 +#define MII_TG3_DSP_CH34TP2_HIBW01 0x0010 #define MII_TG3_DSP_AADJ1CH3 0x601f #define MII_TG3_DSP_AADJ1CH3_ADCCKADJ 0x0002 #define MII_TG3_DSP_EXP1_INT_STAT 0x0f01 @@ -2131,6 +2169,14 @@ #define MII_TG3_TEST1_TRIM_EN 0x0010 #define MII_TG3_TEST1_CRC_EN 0x8000 +/* Clause 45 expansion registers */ +#define TG3_CL45_D7_EEEADV_CAP 0x003c +#define TG3_CL45_D7_EEEADV_CAP_100TX 0x0002 +#define TG3_CL45_D7_EEEADV_CAP_1000T 0x0004 +#define TG3_CL45_D7_EEERES_STAT 0x803e +#define TG3_CL45_D7_EEERES_STAT_LP_100TX 0x0002 +#define TG3_CL45_D7_EEERES_STAT_LP_1000T 0x0004 + /* Fast Ethernet Tranceiver definitions */ #define MII_TG3_FET_PTEST 0x17 @@ -2176,7 +2222,7 @@ #define TG3_APE_HOST_SEG_SIG 0x4200 #define APE_HOST_SEG_SIG_MAGIC 0x484f5354 #define TG3_APE_HOST_SEG_LEN 0x4204 -#define APE_HOST_SEG_LEN_MAGIC 0x0000001c +#define APE_HOST_SEG_LEN_MAGIC 0x00000020 #define TG3_APE_HOST_INIT_COUNT 0x4208 #define TG3_APE_HOST_DRIVER_ID 0x420c #define APE_HOST_DRIVER_ID_LINUX 0xf0000000 @@ -2188,6 +2234,12 @@ #define APE_HOST_HEARTBEAT_INT_DISABLE 0 #define APE_HOST_HEARTBEAT_INT_5SEC 5000 #define TG3_APE_HOST_HEARTBEAT_COUNT 0x4218 +#define TG3_APE_HOST_DRVR_STATE 0x421c +#define TG3_APE_HOST_DRVR_STATE_START 0x00000001 +#define TG3_APE_HOST_DRVR_STATE_UNLOAD 0x00000002 +#define TG3_APE_HOST_DRVR_STATE_WOL 0x00000003 +#define TG3_APE_HOST_WOL_SPEED 0x4224 +#define TG3_APE_HOST_WOL_SPEED_AUTO 0x00008000 #define TG3_APE_EVENT_STATUS 0x4300 @@ -2649,7 +2701,8 @@ struct tg3_rx_prodring_set { dma_addr_t rx_jmb_mapping; }; -#define TG3_IRQ_MAX_VECS 5 +#define TG3_IRQ_MAX_VECS_RSS 5 +#define TG3_IRQ_MAX_VECS TG3_IRQ_MAX_VECS_RSS struct tg3_napi { struct napi_struct napi ____cacheline_aligned; @@ -2668,7 +2721,7 @@ struct tg3_napi { u32 consmbox; u32 rx_rcb_ptr; u16 *rx_rcb_prod_idx; - struct tg3_rx_prodring_set *prodring; + struct tg3_rx_prodring_set prodring; struct tg3_rx_buffer_desc *rx_rcb; struct tg3_tx_buffer_desc *tx_ring; @@ -2746,6 +2799,9 @@ struct tg3 { void (*write32_rx_mbox) (struct tg3 *, u32, u32); u32 rx_copy_thresh; + u32 rx_std_ring_mask; + u32 rx_jmb_ring_mask; + u32 rx_ret_ring_mask; u32 rx_pending; u32 rx_jumbo_pending; u32 rx_std_max_post; @@ -2755,8 +2811,6 @@ struct tg3 { struct vlan_group *vlgrp; #endif - struct tg3_rx_prodring_set prodring[TG3_IRQ_MAX_VECS]; - /* begin "everything else" cacheline(s) section */ unsigned long rx_dropped; @@ -2850,6 +2904,7 @@ struct tg3 { #define TG3_FLG3_USE_JUMBO_BDFLAG 0x00400000 #define TG3_FLG3_L1PLLPD_EN 0x00800000 #define TG3_FLG3_5717_PLUS 0x01000000 +#define TG3_FLG3_APE_HAS_NCSI 0x02000000 struct timer_list timer; u16 timer_counter; @@ -2966,9 +3021,11 @@ struct tg3 { #define TG3_PHYFLG_BER_BUG 0x00008000 #define TG3_PHYFLG_SERDES_PREEMPHASIS 0x00010000 #define TG3_PHYFLG_PARALLEL_DETECT 0x00020000 +#define TG3_PHYFLG_EEE_CAP 0x00040000 u32 led_ctrl; u32 phy_otp; + u32 setlpicnt; #define TG3_BPN_SIZE 24 char board_part_number[TG3_BPN_SIZE]; diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index ccee3eddc5f4c24b4afcdf6cb4dcaf8759165b7a..ec8c804a795d09183967d6ef28e13c97551ab7d3 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -393,7 +393,7 @@ TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type ) spin_unlock_irqrestore(&priv->lock, flags); return; } - priv->timer.function = &TLan_Timer; + priv->timer.function = TLan_Timer; if (!in_irq()) spin_unlock_irqrestore(&priv->lock, flags); @@ -1453,7 +1453,7 @@ static u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int ) TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT ); if ( priv->timer.function == NULL ) { - priv->timer.function = &TLan_Timer; + priv->timer.function = TLan_Timer; priv->timer.data = (unsigned long) dev; priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY; priv->timerSetAt = jiffies; @@ -1601,7 +1601,7 @@ static u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int ) TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT ); if ( priv->timer.function == NULL ) { - priv->timer.function = &TLan_Timer; + priv->timer.function = TLan_Timer; priv->timer.data = (unsigned long) dev; priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY; priv->timerSetAt = jiffies; @@ -1897,7 +1897,7 @@ static void TLan_Timer( unsigned long data ) TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK ); } else { - priv->timer.function = &TLan_Timer; + priv->timer.function = TLan_Timer; priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY; spin_unlock_irqrestore(&priv->lock, flags); @@ -3187,7 +3187,7 @@ static int TLan_EeSendByte( u16 io_base, u8 data, int stop ) TLan_SetBit( TLAN_NET_SIO_EDATA, sio ); } - return ( err ); + return err; } /* TLan_EeSendByte */ diff --git a/drivers/net/tlan.h b/drivers/net/tlan.h index d13ff12d7500b95cff207a67ecf9f4c5118ab83b..3315ced774e2ff9078b972462b50295abbdb8f63 100644 --- a/drivers/net/tlan.h +++ b/drivers/net/tlan.h @@ -442,7 +442,7 @@ typedef struct tlan_private_tag { static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); - return (inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3))); + return inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3)); } /* TLan_DioRead8 */ @@ -452,7 +452,7 @@ static inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr) static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); - return (inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2))); + return inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2)); } /* TLan_DioRead16 */ @@ -462,7 +462,7 @@ static inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr) static inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr) { outw(internal_addr, base_addr + TLAN_DIO_ADR); - return (inl(base_addr + TLAN_DIO_DATA)); + return inl(base_addr + TLAN_DIO_DATA); } /* TLan_DioRead32 */ @@ -537,6 +537,6 @@ static inline u32 TLan_HashFunc( const u8 *a ) hash ^= ((a[2]^a[5])<<4); /* & 060 */ hash ^= ((a[2]^a[5])>>2); /* & 077 */ - return (hash & 077); + return hash & 077; } #endif diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index 16e8783ee9cd3b1b4252975812c3d43029597663..8d362e64a40e45ddfbac4bd68a16befe7152dd33 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c @@ -110,7 +110,7 @@ static int __init proteon_probe1(struct net_device *dev, int ioaddr) } dev->base_addr = ioaddr; - return (0); + return 0; nodev: release_region(ioaddr, PROTEON_IO_EXTENT); return -ENODEV; diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 0929fff5982c73e93902cc20ae02447e5bd26262..63db5a6762ae2049064461602905f9d81ddc4a8a 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -435,7 +435,7 @@ static int smctr_alloc_shared_memory(struct net_device *dev) RX_DATA_BUFFER_SIZE * tp->num_rx_bdbs[NON_MAC_QUEUE]); tp->rx_buff_end[NON_MAC_QUEUE] = (__u16 *)smctr_malloc(dev, 0); - return (0); + return 0; } /* Enter Bypass state. */ @@ -448,7 +448,7 @@ static int smctr_bypass_state(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_BYPASS_STATE); - return (err); + return err; } static int smctr_checksum_firmware(struct net_device *dev) @@ -471,9 +471,9 @@ static int smctr_checksum_firmware(struct net_device *dev) smctr_disable_adapter_ctrl_store(dev); if(checksum) - return (checksum); + return checksum; - return (0); + return 0; } static int __init smctr_chk_mca(struct net_device *dev) @@ -485,7 +485,7 @@ static int __init smctr_chk_mca(struct net_device *dev) current_slot = mca_find_unused_adapter(smctr_posid, 0); if(current_slot == MCA_NOTFOUND) - return (-ENODEV); + return -ENODEV; mca_set_adapter_name(current_slot, smctr_name); mca_mark_as_used(current_slot); @@ -622,9 +622,9 @@ static int __init smctr_chk_mca(struct net_device *dev) break; } - return (0); + return 0; #else - return (-1); + return -1; #endif /* CONFIG_MCA_LEGACY */ } @@ -677,18 +677,18 @@ static int smctr_chg_rx_mask(struct net_device *dev) if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_0, &tp->config_word0))) { - return (err); + return err; } if((err = smctr_issue_write_word_cmd(dev, RW_CONFIG_REGISTER_1, &tp->config_word1))) { - return (err); + return err; } smctr_disable_16bit(dev); - return (0); + return 0; } static int smctr_clear_int(struct net_device *dev) @@ -697,7 +697,7 @@ static int smctr_clear_int(struct net_device *dev) outb((tp->trc_mask | CSR_CLRTINT), dev->base_addr + CSR); - return (0); + return 0; } static int smctr_clear_trc_reset(int ioaddr) @@ -707,7 +707,7 @@ static int smctr_clear_trc_reset(int ioaddr) r = inb(ioaddr + MSR); outb(~MSR_RST & r, ioaddr + MSR); - return (0); + return 0; } /* @@ -725,7 +725,7 @@ static int smctr_close(struct net_device *dev) /* Check to see if adapter is already in a closed state. */ if(tp->status != OPEN) - return (0); + return 0; smctr_enable_16bit(dev); smctr_set_page(dev, (__u8 *)tp->ram_access); @@ -733,7 +733,7 @@ static int smctr_close(struct net_device *dev) if((err = smctr_issue_remove_cmd(dev))) { smctr_disable_16bit(dev); - return (err); + return err; } for(;;) @@ -746,7 +746,7 @@ static int smctr_close(struct net_device *dev) } - return (0); + return 0; } static int smctr_decode_firmware(struct net_device *dev, @@ -807,12 +807,12 @@ static int smctr_decode_firmware(struct net_device *dev, if(buff) *(mem++) = SWAP_BYTES(buff); - return (0); + return 0; } static int smctr_disable_16bit(struct net_device *dev) { - return (0); + return 0; } /* @@ -832,7 +832,7 @@ static int smctr_disable_adapter_ctrl_store(struct net_device *dev) tp->trc_mask |= CSR_WCSS; outb(tp->trc_mask, ioaddr + CSR); - return (0); + return 0; } static int smctr_disable_bic_int(struct net_device *dev) @@ -844,7 +844,7 @@ static int smctr_disable_bic_int(struct net_device *dev) | CSR_MSKTINT | CSR_WCSS; outb(tp->trc_mask, ioaddr + CSR); - return (0); + return 0; } static int smctr_enable_16bit(struct net_device *dev) @@ -858,7 +858,7 @@ static int smctr_enable_16bit(struct net_device *dev) outb((r | LAAR_MEM16ENB), dev->base_addr + LAAR); } - return (0); + return 0; } /* @@ -881,7 +881,7 @@ static int smctr_enable_adapter_ctrl_store(struct net_device *dev) tp->trc_mask &= ~CSR_WCSS; outb(tp->trc_mask, ioaddr + CSR); - return (0); + return 0; } static int smctr_enable_adapter_ram(struct net_device *dev) @@ -895,7 +895,7 @@ static int smctr_enable_adapter_ram(struct net_device *dev) r = inb(ioaddr + MSR); outb(MSR_MEMB | r, ioaddr + MSR); - return (0); + return 0; } static int smctr_enable_bic_int(struct net_device *dev) @@ -921,7 +921,7 @@ static int smctr_enable_bic_int(struct net_device *dev) break; } - return (0); + return 0; } static int __init smctr_chk_isa(struct net_device *dev) @@ -1145,7 +1145,7 @@ static int __init smctr_chk_isa(struct net_device *dev) */ } - return (0); + return 0; out2: release_region(ioaddr, SMCTR_IO_EXTENT); @@ -1199,7 +1199,7 @@ static int __init smctr_get_boardid(struct net_device *dev, int mca) * return; */ if(IdByte & 0xF8) - return (-1); + return -1; r1 = inb(ioaddr + BID_REG_1); r1 &= BID_ICR_MASK; @@ -1250,21 +1250,21 @@ static int __init smctr_get_boardid(struct net_device *dev, int mca) while(r1 & BID_RECALL_DONE_MASK) r1 = inb(ioaddr + BID_REG_1); - return (BoardIdMask); + return BoardIdMask; } static int smctr_get_group_address(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_GROUP_ADDR); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } static int smctr_get_functional_address(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_FUNCTIONAL_ADDR); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } /* Calculate number of Non-MAC receive BDB's and data buffers. @@ -1346,14 +1346,14 @@ static unsigned int smctr_get_num_rx_bdbs(struct net_device *dev) */ mem_used += 0x100; - return((0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock))); + return (0xffff - mem_used) / (RX_DATA_BUFFER_SIZE + sizeof(BDBlock)); } static int smctr_get_physical_drop_number(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_PHYSICAL_DROP_NUMBER); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) @@ -1366,14 +1366,14 @@ static __u8 * smctr_get_rx_pointer(struct net_device *dev, short queue) tp->rx_fcb_curr[queue]->bdb_ptr = bdb; - return ((__u8 *)bdb->data_block_ptr); + return (__u8 *)bdb->data_block_ptr; } static int smctr_get_station_id(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_INDIVIDUAL_MAC_ADDRESS); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } /* @@ -1384,7 +1384,7 @@ static struct net_device_stats *smctr_get_stats(struct net_device *dev) { struct net_local *tp = netdev_priv(dev); - return ((struct net_device_stats *)&tp->MacStat); + return (struct net_device_stats *)&tp->MacStat; } static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, @@ -1401,14 +1401,14 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, /* check if there is enough FCB blocks */ if(tp->num_tx_fcbs_used[queue] >= tp->num_tx_fcbs[queue]) - return ((FCBlock *)(-1L)); + return (FCBlock *)(-1L); /* round off the input pkt size to the nearest even number */ alloc_size = (bytes_count + 1) & 0xfffe; /* check if enough mem */ if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue]) - return ((FCBlock *)(-1L)); + return (FCBlock *)(-1L); /* check if past the end ; * if exactly enough mem to end of ring, alloc from front. @@ -1425,7 +1425,7 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, if((tp->tx_buff_used[queue] + alloc_size) > tp->tx_buff_size[queue]) { - return ((FCBlock *)(-1L)); + return (FCBlock *)(-1L); } /* ring wrap */ @@ -1448,14 +1448,14 @@ static FCBlock *smctr_get_tx_fcb(struct net_device *dev, __u16 queue, pFCB = tp->tx_fcb_curr[queue]; tp->tx_fcb_curr[queue] = tp->tx_fcb_curr[queue]->next_ptr; - return (pFCB); + return pFCB; } static int smctr_get_upstream_neighbor_addr(struct net_device *dev) { smctr_issue_read_word_cmd(dev, RW_UPSTREAM_NEIGHBOR_ADDRESS); - return(smctr_wait_cmd(dev)); + return smctr_wait_cmd(dev); } static int smctr_hardware_send_packet(struct net_device *dev, @@ -1469,21 +1469,22 @@ static int smctr_hardware_send_packet(struct net_device *dev, printk(KERN_DEBUG"%s: smctr_hardware_send_packet\n", dev->name); if(tp->status != OPEN) - return (-1); + return -1; if(tp->monitor_state_ready != 1) - return (-1); + return -1; for(;;) { /* Send first buffer from queue */ skb = skb_dequeue(&tp->SendSkbQueue); if(skb == NULL) - return (-1); + return -1; tp->QueueSkb++; - if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) return (-1); + if(skb->len < SMC_HEADER_SIZE || skb->len > tp->max_packet_size) + return -1; smctr_enable_16bit(dev); smctr_set_page(dev, (__u8 *)tp->ram_access); @@ -1492,7 +1493,7 @@ static int smctr_hardware_send_packet(struct net_device *dev, == (FCBlock *)(-1L)) { smctr_disable_16bit(dev); - return (-1); + return -1; } smctr_tx_move_frame(dev, skb, @@ -1508,7 +1509,7 @@ static int smctr_hardware_send_packet(struct net_device *dev, smctr_disable_16bit(dev); } - return (0); + return 0; } static int smctr_init_acbs(struct net_device *dev) @@ -1552,7 +1553,7 @@ static int smctr_init_acbs(struct net_device *dev) tp->acb_curr = tp->acb_head->next_ptr; tp->num_acbs_used = 0; - return (0); + return 0; } static int smctr_init_adapter(struct net_device *dev) @@ -1590,13 +1591,14 @@ static int smctr_init_adapter(struct net_device *dev) if(smctr_checksum_firmware(dev)) { - printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); return (-ENOENT); + printk(KERN_ERR "%s: Previously loaded firmware is missing\n",dev->name); + return -ENOENT; } if((err = smctr_ram_memory_test(dev))) { printk(KERN_ERR "%s: RAM memory test failed.\n", dev->name); - return (-EIO); + return -EIO; } smctr_set_rx_look_ahead(dev); @@ -1608,7 +1610,7 @@ static int smctr_init_adapter(struct net_device *dev) { printk(KERN_ERR "%s: Initialization of card failed (%d)\n", dev->name, err); - return (-EINVAL); + return -EINVAL; } /* This routine clobbers the TRC's internal registers. */ @@ -1616,7 +1618,7 @@ static int smctr_init_adapter(struct net_device *dev) { printk(KERN_ERR "%s: Card failed internal self test (%d)\n", dev->name, err); - return (-EINVAL); + return -EINVAL; } /* Re-Initialize adapter's internal registers */ @@ -1625,17 +1627,17 @@ static int smctr_init_adapter(struct net_device *dev) { printk(KERN_ERR "%s: Initialization of card failed (%d)\n", dev->name, err); - return (-EINVAL); + return -EINVAL; } smctr_enable_bic_int(dev); if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) - return (err); + return err; smctr_disable_16bit(dev); - return (0); + return 0; } static int smctr_init_card_real(struct net_device *dev) @@ -1703,15 +1705,15 @@ static int smctr_init_card_real(struct net_device *dev) smctr_init_shared_memory(dev); if((err = smctr_issue_init_timers_cmd(dev))) - return (err); + return err; if((err = smctr_issue_init_txrx_cmd(dev))) { printk(KERN_ERR "%s: Hardware failure\n", dev->name); - return (err); + return err; } - return (0); + return 0; } static int smctr_init_rx_bdbs(struct net_device *dev) @@ -1763,7 +1765,7 @@ static int smctr_init_rx_bdbs(struct net_device *dev) tp->rx_bdb_curr[i] = tp->rx_bdb_head[i]->next_ptr; } - return (0); + return 0; } static int smctr_init_rx_fcbs(struct net_device *dev) @@ -1813,7 +1815,7 @@ static int smctr_init_rx_fcbs(struct net_device *dev) tp->rx_fcb_curr[i] = tp->rx_fcb_head[i]->next_ptr; } - return(0); + return 0; } static int smctr_init_shared_memory(struct net_device *dev) @@ -1871,7 +1873,7 @@ static int smctr_init_shared_memory(struct net_device *dev) smctr_init_rx_bdbs(dev); smctr_init_rx_fcbs(dev); - return (0); + return 0; } static int smctr_init_tx_bdbs(struct net_device *dev) @@ -1901,7 +1903,7 @@ static int smctr_init_tx_bdbs(struct net_device *dev) tp->tx_bdb_head[i]->back_ptr = bdb; } - return (0); + return 0; } static int smctr_init_tx_fcbs(struct net_device *dev) @@ -1940,7 +1942,7 @@ static int smctr_init_tx_fcbs(struct net_device *dev) tp->num_tx_fcbs_used[i] = 0; } - return (0); + return 0; } static int smctr_internal_self_test(struct net_device *dev) @@ -1949,33 +1951,33 @@ static int smctr_internal_self_test(struct net_device *dev) int err; if((err = smctr_issue_test_internal_rom_cmd(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; if(tp->acb_head->cmd_done_status & 0xff) - return (-1); + return -1; if((err = smctr_issue_test_hic_cmd(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; if(tp->acb_head->cmd_done_status & 0xff) - return (-1); + return -1; if((err = smctr_issue_test_mac_reg_cmd(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; if(tp->acb_head->cmd_done_status & 0xff) - return (-1); + return -1; - return (0); + return 0; } /* @@ -2468,14 +2470,14 @@ static int smctr_issue_enable_int_cmd(struct net_device *dev, int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; tp->sclb_ptr->int_mask_control = interrupt_enable_mask; tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_CLEAR_INTERRUPT_MASK; smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ibits) @@ -2483,7 +2485,7 @@ static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ib struct net_local *tp = netdev_priv(dev); if(smctr_wait_while_cbusy(dev)) - return (-1); + return -1; tp->sclb_ptr->int_mask_control = ibits; tp->sclb_ptr->iack_code = iack_code << 1; /* use the offset from base */ tp->sclb_ptr->resume_control = 0; @@ -2491,7 +2493,7 @@ static int smctr_issue_int_ack(struct net_device *dev, __u16 iack_code, __u16 ib smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_init_timers_cmd(struct net_device *dev) @@ -2502,10 +2504,10 @@ static int smctr_issue_init_timers_cmd(struct net_device *dev) __u16 *pTimer_Struc = (__u16 *)tp->misc_command_data; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; tp->config_word0 = THDREN | DMA_TRIGGER | USETPT | NO_AUTOREMOVE; tp->config_word1 = 0; @@ -2648,7 +2650,7 @@ static int smctr_issue_init_timers_cmd(struct net_device *dev) err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TRC_TIMERS, 0); - return (err); + return err; } static int smctr_issue_init_txrx_cmd(struct net_device *dev) @@ -2659,12 +2661,12 @@ static int smctr_issue_init_txrx_cmd(struct net_device *dev) void **txrx_ptrs = (void *)tp->misc_command_data; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) { printk(KERN_ERR "%s: Hardware failure\n", dev->name); - return (err); + return err; } /* Initialize Transmit Queue Pointers that are used, to point to @@ -2695,7 +2697,7 @@ static int smctr_issue_init_txrx_cmd(struct net_device *dev) err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_INIT_TX_RX, 0); - return (err); + return err; } static int smctr_issue_insert_cmd(struct net_device *dev) @@ -2704,7 +2706,7 @@ static int smctr_issue_insert_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_INSERT, ACB_SUB_CMD_NOP); - return (err); + return err; } static int smctr_issue_read_ring_status_cmd(struct net_device *dev) @@ -2712,15 +2714,15 @@ static int smctr_issue_read_ring_status_cmd(struct net_device *dev) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_READ_TRC_STATUS, RW_TRC_STATUS_BLOCK); - return (err); + return err; } static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt) @@ -2728,15 +2730,15 @@ static int smctr_issue_read_word_cmd(struct net_device *dev, __u16 aword_cnt) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_READ_VALUE, aword_cnt); - return (err); + return err; } static int smctr_issue_remove_cmd(struct net_device *dev) @@ -2745,14 +2747,14 @@ static int smctr_issue_remove_cmd(struct net_device *dev) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; tp->sclb_ptr->resume_control = 0; tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_CMD_REMOVE; smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_resume_acb_cmd(struct net_device *dev) @@ -2761,7 +2763,7 @@ static int smctr_issue_resume_acb_cmd(struct net_device *dev) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; tp->sclb_ptr->resume_control = SCLB_RC_ACB; tp->sclb_ptr->valid_command = SCLB_VALID | SCLB_RESUME_CONTROL_VALID; @@ -2770,7 +2772,7 @@ static int smctr_issue_resume_acb_cmd(struct net_device *dev) smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) @@ -2779,7 +2781,7 @@ static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if(queue == MAC_QUEUE) tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_BDB; @@ -2790,7 +2792,7 @@ static int smctr_issue_resume_rx_bdb_cmd(struct net_device *dev, __u16 queue) smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) @@ -2801,7 +2803,7 @@ static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) printk(KERN_DEBUG "%s: smctr_issue_resume_rx_fcb_cmd\n", dev->name); if(smctr_wait_while_cbusy(dev)) - return (-1); + return -1; if(queue == MAC_QUEUE) tp->sclb_ptr->resume_control = SCLB_RC_RX_MAC_FCB; @@ -2812,7 +2814,7 @@ static int smctr_issue_resume_rx_fcb_cmd(struct net_device *dev, __u16 queue) smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) @@ -2823,14 +2825,14 @@ static int smctr_issue_resume_tx_fcb_cmd(struct net_device *dev, __u16 queue) printk(KERN_DEBUG "%s: smctr_issue_resume_tx_fcb_cmd\n", dev->name); if(smctr_wait_while_cbusy(dev)) - return (-1); + return -1; tp->sclb_ptr->resume_control = (SCLB_RC_TFCB0 << queue); tp->sclb_ptr->valid_command = SCLB_RESUME_CONTROL_VALID | SCLB_VALID; smctr_set_ctrl_attention(dev); - return (0); + return 0; } static int smctr_issue_test_internal_rom_cmd(struct net_device *dev) @@ -2840,7 +2842,7 @@ static int smctr_issue_test_internal_rom_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_INTERNAL_ROM_TEST); - return (err); + return err; } static int smctr_issue_test_hic_cmd(struct net_device *dev) @@ -2850,7 +2852,7 @@ static int smctr_issue_test_hic_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_HIC_TEST, TRC_HOST_INTERFACE_REG_TEST); - return (err); + return err; } static int smctr_issue_test_mac_reg_cmd(struct net_device *dev) @@ -2860,7 +2862,7 @@ static int smctr_issue_test_mac_reg_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_MAC_REGISTERS_TEST); - return (err); + return err; } static int smctr_issue_trc_loopback_cmd(struct net_device *dev) @@ -2870,7 +2872,7 @@ static int smctr_issue_trc_loopback_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_INTERNAL_LOOPBACK); - return (err); + return err; } static int smctr_issue_tri_loopback_cmd(struct net_device *dev) @@ -2880,7 +2882,7 @@ static int smctr_issue_tri_loopback_cmd(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_TRI_LOOPBACK); - return (err); + return err; } static int smctr_issue_write_byte_cmd(struct net_device *dev, @@ -2891,10 +2893,10 @@ static int smctr_issue_write_byte_cmd(struct net_device *dev, int err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; for(iword = 0, ibyte = 0; iword < (unsigned int)(aword_cnt & 0xff); iword++, ibyte += 2) @@ -2903,8 +2905,8 @@ static int smctr_issue_write_byte_cmd(struct net_device *dev, | (*((__u8 *)byte + ibyte + 1)); } - return (smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, - aword_cnt)); + return smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, + aword_cnt); } static int smctr_issue_write_word_cmd(struct net_device *dev, @@ -2914,10 +2916,10 @@ static int smctr_issue_write_word_cmd(struct net_device *dev, unsigned int i, err; if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = smctr_wait_cmd(dev))) - return (err); + return err; for(i = 0; i < (unsigned int)(aword_cnt & 0xff); i++) tp->misc_command_data[i] = *((__u16 *)word + i); @@ -2925,7 +2927,7 @@ static int smctr_issue_write_word_cmd(struct net_device *dev, err = smctr_setup_single_cmd_w_data(dev, ACB_CMD_MCT_WRITE_VALUE, aword_cnt); - return (err); + return err; } static int smctr_join_complete_state(struct net_device *dev) @@ -2935,7 +2937,7 @@ static int smctr_join_complete_state(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_JOIN_COMPLETE_STATE); - return (err); + return err; } static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) @@ -2959,7 +2961,7 @@ static int smctr_link_tx_fcbs_to_bdbs(struct net_device *dev) } } - return (0); + return 0; } static int smctr_load_firmware(struct net_device *dev) @@ -2974,7 +2976,7 @@ static int smctr_load_firmware(struct net_device *dev) if (request_firmware(&fw, "tr_smctr.bin", &dev->dev)) { printk(KERN_ERR "%s: firmware not found\n", dev->name); - return (UCODE_NOT_PRESENT); + return UCODE_NOT_PRESENT; } tp->num_of_tx_buffs = 4; @@ -3036,7 +3038,7 @@ static int smctr_load_firmware(struct net_device *dev) smctr_disable_16bit(dev); out: release_firmware(fw); - return (err); + return err; } static int smctr_load_node_addr(struct net_device *dev) @@ -3052,7 +3054,7 @@ static int smctr_load_node_addr(struct net_device *dev) } dev->addr_len = 6; - return (0); + return 0; } /* Lobe Media Test. @@ -3146,14 +3148,14 @@ static int smctr_lobe_media_test_cmd(struct net_device *dev) if(smctr_wait_cmd(dev)) { printk(KERN_ERR "Lobe Failed test state\n"); - return (LOBE_MEDIA_TEST_FAILED); + return LOBE_MEDIA_TEST_FAILED; } } err = smctr_setup_single_cmd(dev, ACB_CMD_MCT_TEST, TRC_LOBE_MEDIA_TEST); - return (err); + return err; } static int smctr_lobe_media_test_state(struct net_device *dev) @@ -3163,7 +3165,7 @@ static int smctr_lobe_media_test_state(struct net_device *dev) err = smctr_setup_single_cmd(dev, ACB_CMD_CHANGE_JOIN_STATE, JS_LOBE_TEST_STATE); - return (err); + return err; } static int smctr_make_8025_hdr(struct net_device *dev, @@ -3212,7 +3214,7 @@ static int smctr_make_8025_hdr(struct net_device *dev, break; } - return (0); + return 0; } static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3225,7 +3227,7 @@ static int smctr_make_access_pri(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[0] = MSB(tp->authorized_access_priority); tsv->svv[1] = LSB(tp->authorized_access_priority); - return (0); + return 0; } static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3236,7 +3238,7 @@ static int smctr_make_addr_mod(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[0] = 0; tsv->svv[1] = 0; - return (0); + return 0; } static int smctr_make_auth_funct_class(struct net_device *dev, @@ -3250,7 +3252,7 @@ static int smctr_make_auth_funct_class(struct net_device *dev, tsv->svv[0] = MSB(tp->authorized_function_classes); tsv->svv[1] = LSB(tp->authorized_function_classes); - return (0); + return 0; } static int smctr_make_corr(struct net_device *dev, @@ -3262,7 +3264,7 @@ static int smctr_make_corr(struct net_device *dev, tsv->svv[0] = MSB(correlator); tsv->svv[1] = LSB(correlator); - return (0); + return 0; } static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3280,7 +3282,7 @@ static int smctr_make_funct_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[2] = MSB(tp->misc_command_data[1]); tsv->svv[3] = LSB(tp->misc_command_data[1]); - return (0); + return 0; } static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3305,7 +3307,7 @@ static int smctr_make_group_addr(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[2] == 0x00 && tsv->svv[3] == 0x00) tsv->svv[0] = 0x00; - return (0); + return 0; } static int smctr_make_phy_drop_num(struct net_device *dev, @@ -3324,7 +3326,7 @@ static int smctr_make_phy_drop_num(struct net_device *dev, tsv->svv[2] = MSB(tp->misc_command_data[1]); tsv->svv[3] = LSB(tp->misc_command_data[1]); - return (0); + return 0; } static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3337,7 +3339,7 @@ static int smctr_make_product_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) for(i = 0; i < 18; i++) tsv->svv[i] = 0xF0; - return (0); + return 0; } static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3358,7 +3360,7 @@ static int smctr_make_station_id(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svv[4] = MSB(tp->misc_command_data[2]); tsv->svv[5] = LSB(tp->misc_command_data[2]); - return (0); + return 0; } static int smctr_make_ring_station_status(struct net_device *dev, @@ -3374,7 +3376,7 @@ static int smctr_make_ring_station_status(struct net_device *dev, tsv->svv[4] = 0; tsv->svv[5] = 0; - return (0); + return 0; } static int smctr_make_ring_station_version(struct net_device *dev, @@ -3400,7 +3402,7 @@ static int smctr_make_ring_station_version(struct net_device *dev, else tsv->svv[9] = 0xc4; /* EBCDIC - D */ - return (0); + return 0; } static int smctr_make_tx_status_code(struct net_device *dev, @@ -3414,7 +3416,7 @@ static int smctr_make_tx_status_code(struct net_device *dev, /* Stripped frame status of Transmitted Frame */ tsv->svv[1] = tx_fstatus & 0xff; - return (0); + return 0; } static int smctr_make_upstream_neighbor_addr(struct net_device *dev, @@ -3436,7 +3438,7 @@ static int smctr_make_upstream_neighbor_addr(struct net_device *dev, tsv->svv[4] = MSB(tp->misc_command_data[2]); tsv->svv[5] = LSB(tp->misc_command_data[2]); - return (0); + return 0; } static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv) @@ -3444,7 +3446,7 @@ static int smctr_make_wrap_data(struct net_device *dev, MAC_SUB_VECTOR *tsv) tsv->svi = WRAP_DATA; tsv->svl = S_WRAP_DATA; - return (0); + return 0; } /* @@ -3464,9 +3466,9 @@ static int smctr_open(struct net_device *dev) err = smctr_init_adapter(dev); if(err < 0) - return (err); + return err; - return (err); + return err; } /* Interrupt driven open of Token card. */ @@ -3481,9 +3483,9 @@ static int smctr_open_tr(struct net_device *dev) /* Now we can actually open the adapter. */ if(tp->status == OPEN) - return (0); + return 0; if(tp->status != INITIALIZED) - return (-1); + return -1; /* FIXME: it would work a lot better if we masked the irq sources on the card here, then we could skip the locking and poll nicely */ @@ -3560,7 +3562,7 @@ static int smctr_open_tr(struct net_device *dev) out: spin_unlock_irqrestore(&tp->lock, flags); - return (err); + return err; } /* Check for a network adapter of this type, @@ -3675,7 +3677,7 @@ static int __init smctr_probe1(struct net_device *dev, int ioaddr) dev->netdev_ops = &smctr_netdev_ops; dev->watchdog_timeo = HZ; - return (0); + return 0; out: return err; @@ -3699,13 +3701,13 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, case INIT: if((rcode = smctr_rcv_init(dev, rmf, &correlator)) == HARDWARE_FAILED) { - return (rcode); + return rcode; } if((err = smctr_send_rsp(dev, rmf, rcode, correlator))) { - return (err); + return err; } break; @@ -3713,13 +3715,13 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, if((rcode = smctr_rcv_chg_param(dev, rmf, &correlator)) ==HARDWARE_FAILED) { - return (rcode); + return rcode; } if((err = smctr_send_rsp(dev, rmf, rcode, correlator))) { - return (err); + return err; } break; @@ -3728,16 +3730,16 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, rmf, &correlator)) != POSITIVE_ACK) { if(rcode == HARDWARE_FAILED) - return (rcode); + return rcode; else - return (smctr_send_rsp(dev, rmf, - rcode, correlator)); + return smctr_send_rsp(dev, rmf, + rcode, correlator); } if((err = smctr_send_rpt_addr(dev, rmf, correlator))) { - return (err); + return err; } break; @@ -3746,17 +3748,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, rmf, &correlator)) != POSITIVE_ACK) { if(rcode == HARDWARE_FAILED) - return (rcode); + return rcode; else - return (smctr_send_rsp(dev, rmf, + return smctr_send_rsp(dev, rmf, rcode, - correlator)); + correlator); } if((err = smctr_send_rpt_attch(dev, rmf, correlator))) { - return (err); + return err; } break; @@ -3765,17 +3767,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, rmf, &correlator)) != POSITIVE_ACK) { if(rcode == HARDWARE_FAILED) - return (rcode); + return rcode; else - return (smctr_send_rsp(dev, rmf, + return smctr_send_rsp(dev, rmf, rcode, - correlator)); + correlator); } if((err = smctr_send_rpt_state(dev, rmf, correlator))) { - return (err); + return err; } break; @@ -3786,17 +3788,17 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, != POSITIVE_ACK) { if(rcode == HARDWARE_FAILED) - return (rcode); + return rcode; else - return (smctr_send_rsp(dev, rmf, + return smctr_send_rsp(dev, rmf, rcode, - correlator)); + correlator); } if((err = smctr_send_tx_forward(dev, rmf, &tx_fstatus)) == HARDWARE_FAILED) { - return (err); + return err; } if(err == A_FRAME_WAS_FORWARDED) @@ -3805,7 +3807,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, rmf, tx_fstatus)) == HARDWARE_FAILED) { - return (err); + return err; } } break; @@ -3834,7 +3836,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, if((err = smctr_send_rsp(dev, rmf,rcode, correlator))) { - return (err); + return err; } } @@ -3899,7 +3901,7 @@ static int smctr_process_rx_packet(MAC_HEADER *rmf, __u16 size, err = 0; } - return (err); + return err; } /* Adapter RAM test. Incremental word ODD boundary data test. */ @@ -3942,7 +3944,7 @@ static int smctr_ram_memory_test(struct net_device *dev) err_offset = j; err_word = word_read; err_pattern = word_pattern; - return (RAM_TEST_FAILED); + return RAM_TEST_FAILED; } } } @@ -3966,14 +3968,14 @@ static int smctr_ram_memory_test(struct net_device *dev) err_offset = j; err_word = word_read; err_pattern = word_pattern; - return (RAM_TEST_FAILED); + return RAM_TEST_FAILED; } } } smctr_set_page(dev, (__u8 *)tp->ram_access); - return (0); + return 0; } static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, @@ -3986,7 +3988,7 @@ static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, /* This Frame can only come from a CRS */ if((rmf->dc_sc & SC_MASK) != SC_CRS) - return(E_INAPPROPRIATE_SOURCE_CLASS); + return E_INAPPROPRIATE_SOURCE_CLASS; /* Remove MVID Length from total length. */ vlen = (signed short)rmf->vl - 4; @@ -4058,7 +4060,7 @@ static int smctr_rcv_chg_param(struct net_device *dev, MAC_HEADER *rmf, } } - return (rcode); + return rcode; } static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, @@ -4071,7 +4073,7 @@ static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, /* This Frame can only come from a RPS */ if((rmf->dc_sc & SC_MASK) != SC_RPS) - return (E_INAPPROPRIATE_SOURCE_CLASS); + return E_INAPPROPRIATE_SOURCE_CLASS; /* Remove MVID Length from total length. */ vlen = (signed short)rmf->vl - 4; @@ -4133,7 +4135,7 @@ static int smctr_rcv_init(struct net_device *dev, MAC_HEADER *rmf, } } - return (rcode); + return rcode; } static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) @@ -4145,7 +4147,7 @@ static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) /* This Frame can only come from a CRS */ if((rmf->dc_sc & SC_MASK) != SC_CRS) - return (E_INAPPROPRIATE_SOURCE_CLASS); + return E_INAPPROPRIATE_SOURCE_CLASS; /* Remove MVID Length from total length */ vlen = (signed short)rmf->vl - 4; @@ -4193,7 +4195,7 @@ static int smctr_rcv_tx_forward(struct net_device *dev, MAC_HEADER *rmf) } } - return (rcode); + return rcode; } static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, @@ -4250,7 +4252,7 @@ static int smctr_rcv_rq_addr_state_attch(struct net_device *dev, } } - return (rcode); + return rcode; } static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, @@ -4284,7 +4286,7 @@ static int smctr_rcv_unknown(struct net_device *dev, MAC_HEADER *rmf, rsv = (MAC_SUB_VECTOR *)((__u32)rsv + rsv->svl); } - return (E_UNRECOGNIZED_VECTOR_ID); + return E_UNRECOGNIZED_VECTOR_ID; } /* @@ -4311,7 +4313,7 @@ static int smctr_reset_adapter(struct net_device *dev) */ outb(tp->trc_mask | CSR_CLRTINT | CSR_CLRCBUSY, ioaddr + CSR); - return (0); + return 0; } static int smctr_restart_tx_chain(struct net_device *dev, short queue) @@ -4329,7 +4331,7 @@ static int smctr_restart_tx_chain(struct net_device *dev, short queue) err = smctr_issue_resume_tx_fcb_cmd(dev, queue); } - return (err); + return err; } static int smctr_ring_status_chg(struct net_device *dev) @@ -4371,7 +4373,7 @@ static int smctr_ring_status_chg(struct net_device *dev) } if(!(tp->ring_status_flags & RING_STATUS_CHANGED)) - return (0); + return 0; switch(tp->ring_status) { @@ -4421,7 +4423,7 @@ static int smctr_ring_status_chg(struct net_device *dev) break; } - return (0); + return 0; } static int smctr_rx_frame(struct net_device *dev) @@ -4486,7 +4488,7 @@ static int smctr_rx_frame(struct net_device *dev) break; } - return (err); + return err; } static int smctr_send_dat(struct net_device *dev) @@ -4502,7 +4504,7 @@ static int smctr_send_dat(struct net_device *dev) if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER))) == (FCBlock *)(-1L)) { - return (OUT_OF_RESOURCES); + return OUT_OF_RESOURCES; } /* Initialize DAT Data Fields. */ @@ -4524,7 +4526,7 @@ static int smctr_send_dat(struct net_device *dev) /* Start Transmit. */ if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return (err); + return err; /* Wait for Transmit to Complete */ for(i = 0; i < 10000; i++) @@ -4538,7 +4540,7 @@ static int smctr_send_dat(struct net_device *dev) if(!(fcb->frame_status & FCB_COMMAND_DONE) || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) { - return (INITIALIZE_FAILED); + return INITIALIZE_FAILED; } /* De-allocated Tx FCB and Frame Buffer @@ -4549,7 +4551,7 @@ static int smctr_send_dat(struct net_device *dev) tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; smctr_update_tx_chain(dev, fcb, MAC_QUEUE); - return (0); + return 0; } static void smctr_timeout(struct net_device *dev) @@ -4610,7 +4612,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(struct trh_hdr) + S_WRAP_DATA + S_WRAP_DATA)) == (FCBlock *)(-1L)) { - return (OUT_OF_RESOURCES); + return OUT_OF_RESOURCES; } /* Initialize DAT Data Fields. */ @@ -4639,7 +4641,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) /* Start Transmit. */ tmf->vl = SWAP_BYTES(tmf->vl); if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return (err); + return err; /* Wait for Transmit to Complete. (10 ms). */ for(i=0; i < 10000; i++) @@ -4653,7 +4655,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) if(!(fcb->frame_status & FCB_COMMAND_DONE) || fcb->frame_status & (FCB_TX_STATUS_E | FCB_TX_AC_BITS)) { - return (LOBE_MEDIA_TEST_FAILED); + return LOBE_MEDIA_TEST_FAILED; } /* De-allocated Tx FCB and Frame Buffer @@ -4664,7 +4666,7 @@ static int smctr_send_lobe_media_test(struct net_device *dev) tp->tx_queue_status[MAC_QUEUE] = NOT_TRANSMITING; smctr_update_tx_chain(dev, fcb, MAC_QUEUE); - return (0); + return 0; } static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, @@ -4679,7 +4681,7 @@ static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, + S_ADDRESS_MODIFER + S_GROUP_ADDRESS + S_FUNCTIONAL_ADDRESS)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4722,7 +4724,7 @@ static int smctr_send_rpt_addr(struct net_device *dev, MAC_HEADER *rmf, */ tmf->vl = SWAP_BYTES(tmf->vl); - return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); } static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, @@ -4737,7 +4739,7 @@ static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, + S_AUTHORIZED_FUNCTION_CLASS + S_AUTHORIZED_ACCESS_PRIORITY)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4776,7 +4778,7 @@ static int smctr_send_rpt_attch(struct net_device *dev, MAC_HEADER *rmf, */ tmf->vl = SWAP_BYTES(tmf->vl); - return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); } static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, @@ -4791,7 +4793,7 @@ static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, + S_RING_STATION_STATUS + S_STATION_IDENTIFER)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4826,7 +4828,7 @@ static int smctr_send_rpt_state(struct net_device *dev, MAC_HEADER *rmf, */ tmf->vl = SWAP_BYTES(tmf->vl); - return (smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); } static int smctr_send_rpt_tx_forward(struct net_device *dev, @@ -4839,7 +4841,7 @@ static int smctr_send_rpt_tx_forward(struct net_device *dev, if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + S_TRANSMIT_STATUS_CODE)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4862,7 +4864,7 @@ static int smctr_send_rpt_tx_forward(struct net_device *dev, */ tmf->vl = SWAP_BYTES(tmf->vl); - return(smctr_trc_send_packet(dev, fcb, MAC_QUEUE)); + return smctr_trc_send_packet(dev, fcb, MAC_QUEUE); } static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, @@ -4875,7 +4877,7 @@ static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, sizeof(MAC_HEADER) + S_CORRELATOR + S_RESPONSE_CODE)) == (FCBlock *)(-1L)) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4888,7 +4890,7 @@ static int smctr_send_rsp(struct net_device *dev, MAC_HEADER *rmf, tsv = (MAC_SUB_VECTOR *)((__u32)tmf + sizeof(MAC_HEADER)); smctr_make_corr(dev, tsv, correlator); - return (0); + return 0; } static int smctr_send_rq_init(struct net_device *dev) @@ -4907,7 +4909,7 @@ static int smctr_send_rq_init(struct net_device *dev) + S_RING_STATION_VERSION_NUMBER + S_ADDRESS_MODIFER)) == (FCBlock *)(-1L))) { - return (0); + return 0; } tmf = (MAC_HEADER *)fcb->bdb_ptr->data_block_ptr; @@ -4943,7 +4945,7 @@ static int smctr_send_rq_init(struct net_device *dev) tmf->vl = SWAP_BYTES(tmf->vl); if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return (err); + return err; /* Wait for Transmit to Complete */ for(i = 0; i < 10000; i++) @@ -4957,7 +4959,7 @@ static int smctr_send_rq_init(struct net_device *dev) fstatus = fcb->frame_status; if(!(fstatus & FCB_COMMAND_DONE)) - return (HARDWARE_FAILED); + return HARDWARE_FAILED; if(!(fstatus & FCB_TX_STATUS_E)) count++; @@ -4971,7 +4973,7 @@ static int smctr_send_rq_init(struct net_device *dev) smctr_update_tx_chain(dev, fcb, MAC_QUEUE); } while(count < 4 && ((fstatus & FCB_TX_AC_BITS) ^ FCB_TX_AC_BITS)); - return (smctr_join_complete_state(dev)); + return smctr_join_complete_state(dev); } static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, @@ -4984,13 +4986,13 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, /* Check if this is the END POINT of the Transmit Forward Chain. */ if(rmf->vl <= 18) - return (0); + return 0; /* Allocate Transmit FCB only by requesting 0 bytes * of data buffer. */ if((fcb = smctr_get_tx_fcb(dev, MAC_QUEUE, 0)) == (FCBlock *)(-1L)) - return (0); + return 0; /* Set pointer to Transmit Frame Buffer to the data * portion of the received TX Forward frame, making @@ -5006,7 +5008,7 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, fcb->bdb_ptr->buffer_length = rmf->vl - 4 - 2; if((err = smctr_trc_send_packet(dev, fcb, MAC_QUEUE))) - return (err); + return err; /* Wait for Transmit to Complete */ for(i = 0; i < 10000; i++) @@ -5020,7 +5022,7 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, if(!(fcb->frame_status & FCB_COMMAND_DONE)) { if((err = smctr_issue_resume_tx_fcb_cmd(dev, MAC_QUEUE))) - return (err); + return err; for(i = 0; i < 10000; i++) { @@ -5030,12 +5032,12 @@ static int smctr_send_tx_forward(struct net_device *dev, MAC_HEADER *rmf, } if(!(fcb->frame_status & FCB_COMMAND_DONE)) - return (HARDWARE_FAILED); + return HARDWARE_FAILED; } *tx_fstatus = fcb->frame_status; - return (A_FRAME_WAS_FORWARDED); + return A_FRAME_WAS_FORWARDED; } static int smctr_set_auth_access_pri(struct net_device *dev, @@ -5044,11 +5046,11 @@ static int smctr_set_auth_access_pri(struct net_device *dev, struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_AUTHORIZED_ACCESS_PRIORITY) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; tp->authorized_access_priority = (rsv->svv[0] << 8 | rsv->svv[1]); - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_auth_funct_class(struct net_device *dev, @@ -5057,22 +5059,22 @@ static int smctr_set_auth_funct_class(struct net_device *dev, struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_AUTHORIZED_FUNCTION_CLASS) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; tp->authorized_function_classes = (rsv->svv[0] << 8 | rsv->svv[1]); - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_corr(struct net_device *dev, MAC_SUB_VECTOR *rsv, __u16 *correlator) { if(rsv->svl != S_CORRELATOR) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; *correlator = (rsv->svv[0] << 8 | rsv->svv[1]); - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_error_timer_value(struct net_device *dev, @@ -5082,34 +5084,34 @@ static int smctr_set_error_timer_value(struct net_device *dev, int err; if(rsv->svl != S_ERROR_TIMER_VALUE) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; err_tval = (rsv->svv[0] << 8 | rsv->svv[1])*10; smctr_issue_write_word_cmd(dev, RW_TER_THRESHOLD, &err_tval); if((err = smctr_wait_cmd(dev))) - return (err); + return err; - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_frame_forward(struct net_device *dev, MAC_SUB_VECTOR *rsv, __u8 dc_sc) { if((rsv->svl < 2) || (rsv->svl > S_FRAME_FORWARD)) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; if((dc_sc & DC_MASK) != DC_CRS) { if(rsv->svl >= 2 && rsv->svl < 20) - return (E_TRANSMIT_FORWARD_INVALID); + return E_TRANSMIT_FORWARD_INVALID; if((rsv->svv[0] != 0) || (rsv->svv[1] != 0)) - return (E_TRANSMIT_FORWARD_INVALID); + return E_TRANSMIT_FORWARD_INVALID; } - return (POSITIVE_ACK); + return POSITIVE_ACK; } static int smctr_set_local_ring_num(struct net_device *dev, @@ -5118,13 +5120,13 @@ static int smctr_set_local_ring_num(struct net_device *dev, struct net_local *tp = netdev_priv(dev); if(rsv->svl != S_LOCAL_RING_NUMBER) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; if(tp->ptr_local_ring_num) *(__u16 *)(tp->ptr_local_ring_num) = (rsv->svv[0] << 8 | rsv->svv[1]); - return (POSITIVE_ACK); + return POSITIVE_ACK; } static unsigned short smctr_set_ctrl_attention(struct net_device *dev) @@ -5140,7 +5142,7 @@ static unsigned short smctr_set_ctrl_attention(struct net_device *dev) outb(tp->trc_mask, ioaddr + CSR); } - return (0); + return 0; } static void smctr_set_multicast_list(struct net_device *dev) @@ -5159,7 +5161,7 @@ static int smctr_set_page(struct net_device *dev, __u8 *buf) amask = (__u8)((tptr & PR_PAGE_MASK) >> 8); outb(amask, dev->base_addr + PR); - return (0); + return 0; } static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv) @@ -5167,13 +5169,13 @@ static int smctr_set_phy_drop(struct net_device *dev, MAC_SUB_VECTOR *rsv) int err; if(rsv->svl != S_PHYSICAL_DROP) - return (E_SUB_VECTOR_LENGTH_ERROR); + return E_SUB_VECTOR_LENGTH_ERROR; smctr_issue_write_byte_cmd(dev, RW_PHYSICAL_DROP_NUMBER, &rsv->svv[0]); if((err = smctr_wait_cmd(dev))) - return (err); + return err; - return (POSITIVE_ACK); + return POSITIVE_ACK; } /* Reset the ring speed to the opposite of what it was. This auto-pilot @@ -5195,16 +5197,16 @@ static int smctr_set_ring_speed(struct net_device *dev) smctr_reset_adapter(dev); if((err = smctr_init_card_real(dev))) - return (err); + return err; smctr_enable_bic_int(dev); if((err = smctr_issue_enable_int_cmd(dev, TRC_INTERRUPT_ENABLE_MASK))) - return (err); + return err; smctr_disable_16bit(dev); - return (0); + return 0; } static int smctr_set_rx_look_ahead(struct net_device *dev) @@ -5233,7 +5235,7 @@ static int smctr_set_rx_look_ahead(struct net_device *dev) *((__u16 *)(tp->ram_access)) = sword; } - return (0); + return 0; } static int smctr_set_trc_reset(int ioaddr) @@ -5243,7 +5245,7 @@ static int smctr_set_trc_reset(int ioaddr) r = inb(ioaddr + MSR); outb(MSR_RST | r, ioaddr + MSR); - return (0); + return 0; } /* @@ -5259,10 +5261,10 @@ static int smctr_setup_single_cmd(struct net_device *dev, printk(KERN_DEBUG "%s: smctr_setup_single_cmd\n", dev->name); if((err = smctr_wait_while_cbusy(dev))) - return (err); + return err; if((err = (unsigned int)smctr_wait_cmd(dev))) - return (err); + return err; tp->acb_head->cmd_done_status = 0; tp->acb_head->cmd = command; @@ -5270,7 +5272,7 @@ static int smctr_setup_single_cmd(struct net_device *dev, err = smctr_issue_resume_acb_cmd(dev); - return (err); + return err; } /* @@ -5287,7 +5289,7 @@ static int smctr_setup_single_cmd_w_data(struct net_device *dev, tp->acb_head->data_offset_lo = (__u16)TRC_POINTER(tp->misc_command_data); - return(smctr_issue_resume_acb_cmd(dev)); + return smctr_issue_resume_acb_cmd(dev); } static char *smctr_malloc(struct net_device *dev, __u16 size) @@ -5298,7 +5300,7 @@ static char *smctr_malloc(struct net_device *dev, __u16 size) m = (char *)(tp->ram_access + tp->sh_mem_used); tp->sh_mem_used += (__u32)size; - return (m); + return m; } static int smctr_status_chg(struct net_device *dev) @@ -5333,7 +5335,7 @@ static int smctr_status_chg(struct net_device *dev) break; } - return (0); + return 0; } static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, @@ -5355,7 +5357,7 @@ static int smctr_trc_send_packet(struct net_device *dev, FCBlock *fcb, err = smctr_issue_resume_tx_fcb_cmd(dev, queue); } - return (err); + return err; } static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) @@ -5409,7 +5411,7 @@ static __u16 smctr_tx_complete(struct net_device *dev, __u16 queue) break; } - return (err); + return err; } static unsigned short smctr_tx_move_frame(struct net_device *dev, @@ -5450,7 +5452,7 @@ static unsigned short smctr_tx_move_frame(struct net_device *dev, pbuff += len; } - return (0); + return 0; } /* Update the error statistic counters for this adapter. */ @@ -5493,7 +5495,7 @@ static int smctr_update_err_stats(struct net_device *dev) if(tstat->token_errors) tstat->token_errors += *(tp->misc_command_data + 5) >> 8; - return (0); + return 0; } static int smctr_update_rx_chain(struct net_device *dev, __u16 queue) @@ -5530,7 +5532,7 @@ static int smctr_update_rx_chain(struct net_device *dev, __u16 queue) tp->rx_bdb_curr[queue]->back_ptr->info = BDB_NOT_CHAIN_END; tp->rx_bdb_curr[queue] = bdb; - return (0); + return 0; } static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, @@ -5542,13 +5544,13 @@ static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, printk(KERN_DEBUG "smctr_update_tx_chain\n"); if(tp->num_tx_fcbs_used[queue] <= 0) - return (HARDWARE_FAILED); + return HARDWARE_FAILED; else { if(tp->tx_buff_used[queue] < fcb->memory_alloc) { tp->tx_buff_used[queue] = 0; - return (HARDWARE_FAILED); + return HARDWARE_FAILED; } tp->tx_buff_used[queue] -= fcb->memory_alloc; @@ -5566,7 +5568,7 @@ static int smctr_update_tx_chain(struct net_device *dev, FCBlock *fcb, fcb->frame_status = 0; tp->tx_fcb_end[queue] = fcb->next_ptr; netif_wake_queue(dev); - return (0); + return 0; } } @@ -5587,12 +5589,12 @@ static int smctr_wait_cmd(struct net_device *dev) } if(loop_count == 0) - return(HARDWARE_FAILED); + return HARDWARE_FAILED; if(tp->acb_head->cmd_done_status & 0xff) - return(HARDWARE_FAILED); + return HARDWARE_FAILED; - return (0); + return 0; } static int smctr_wait_while_cbusy(struct net_device *dev) @@ -5624,9 +5626,9 @@ static int smctr_wait_while_cbusy(struct net_device *dev) } if(timeout) - return (0); + return 0; else - return (HARDWARE_FAILED); + return HARDWARE_FAILED; } #ifdef MODULE diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 435ef7d5470fd8e8e6c4849c1d3dc930a13e1b3f..c83f4f6e39e132c7772c4095d68f8e1ccfc6eca6 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c @@ -224,7 +224,7 @@ static int madgemc_sifprobe(struct net_device *dev) chk2 ^= 0x0FE; if(chk1 != chk2) - return (-1); /* No adapter */ + return -1; /* No adapter */ chk1 -= 2; } while(chk1 != 0); /* Repeat 128 times (all byte values) */ @@ -232,7 +232,7 @@ static int madgemc_sifprobe(struct net_device *dev) /* Restore the SIFADR value */ SIFWRITEB(old, SIFADR); - return (0); + return 0; } #endif @@ -271,7 +271,7 @@ int tms380tr_open(struct net_device *dev) { printk(KERN_INFO "%s: Chipset initialization error\n", dev->name); - return (-1); + return -1; } tp->timer.expires = jiffies + 30*HZ; @@ -298,7 +298,7 @@ int tms380tr_open(struct net_device *dev) if(tp->AdapterVirtOpenFlag == 0) { tms380tr_disable_interrupts(dev); - return (-1); + return -1; } tp->StartTime = jiffies; @@ -309,7 +309,7 @@ int tms380tr_open(struct net_device *dev) tp->timer.data = (unsigned long)dev; add_timer(&tp->timer); - return (0); + return 0; } /* @@ -343,23 +343,23 @@ static int tms380tr_chipset_init(struct net_device *dev) printk(KERN_DEBUG "%s: Resetting adapter...\n", dev->name); err = tms380tr_reset_adapter(dev); if(err < 0) - return (-1); + return -1; if(tms380tr_debug > 3) printk(KERN_DEBUG "%s: Bringup diags...\n", dev->name); err = tms380tr_bringup_diags(dev); if(err < 0) - return (-1); + return -1; if(tms380tr_debug > 3) printk(KERN_DEBUG "%s: Init adapter...\n", dev->name); err = tms380tr_init_adapter(dev); if(err < 0) - return (-1); + return -1; if(tms380tr_debug > 3) printk(KERN_DEBUG "%s: Done!\n", dev->name); - return (0); + return 0; } /* @@ -877,7 +877,7 @@ static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqTy IrqType != STS_IRQ_COMMAND_STATUS && IrqType != STS_IRQ_RING_STATUS) { - return (1); /* SSB not involved. */ + return 1; /* SSB not involved. */ } /* Note: All fields of the SSB have been set to all ones (-1) after it @@ -887,21 +887,21 @@ static unsigned char tms380tr_chk_ssb(struct net_local *tp, unsigned short IrqTy */ if(ssb->STS == (unsigned short) -1) - return (0); /* Command field not yet available. */ + return 0; /* Command field not yet available. */ if(IrqType == STS_IRQ_COMMAND_STATUS) - return (1); /* Status fields not always affected. */ + return 1; /* Status fields not always affected. */ if(ssb->Parm[0] == (unsigned short) -1) - return (0); /* Status 1 field not yet available. */ + return 0; /* Status 1 field not yet available. */ if(IrqType == STS_IRQ_RING_STATUS) - return (1); /* Status 2 & 3 fields not affected. */ + return 1; /* Status 2 & 3 fields not affected. */ /* Note: At this point, the interrupt is either TRANSMIT or RECEIVE. */ if(ssb->Parm[1] == (unsigned short) -1) - return (0); /* Status 2 field not yet available. */ + return 0; /* Status 2 field not yet available. */ if(ssb->Parm[2] == (unsigned short) -1) - return (0); /* Status 3 field not yet available. */ + return 0; /* Status 3 field not yet available. */ - return (1); /* All SSB fields have been written by the adapter. */ + return 1; /* All SSB fields have been written by the adapter. */ } /* @@ -1143,7 +1143,7 @@ int tms380tr_close(struct net_device *dev) #endif tms380tr_cancel_tx_queue(tp); - return (0); + return 0; } /* @@ -1154,7 +1154,7 @@ static struct net_device_stats *tms380tr_get_stats(struct net_device *dev) { struct net_local *tp = netdev_priv(dev); - return ((struct net_device_stats *)&tp->MacStat); + return (struct net_device_stats *)&tp->MacStat; } /* @@ -1256,7 +1256,7 @@ static int tms380tr_reset_adapter(struct net_device *dev) if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) { printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", dev->name, "tms380tr.bin"); - return (-1); + return -1; } fw_ptr = (unsigned short *)fw_entry->data; @@ -1321,16 +1321,14 @@ static int tms380tr_reset_adapter(struct net_device *dev) /* Clear CPHALT and start BUD */ SIFWRITEW(c, SIFACL); - if (fw_entry) - release_firmware(fw_entry); - return (1); + release_firmware(fw_entry); + return 1; } } while(count == 0); - if (fw_entry) - release_firmware(fw_entry); + release_firmware(fw_entry); printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name); - return (-1); + return -1; } MODULE_FIRMWARE("tms380tr.bin"); @@ -1365,7 +1363,7 @@ static int tms380tr_bringup_diags(struct net_device *dev) printk(KERN_DEBUG " %04X\n", Status); /* BUD successfully completed */ if(Status == STS_INITIALIZE) - return (1); + return 1; /* Unrecoverable hardware error, BUD not completed? */ } while((loop_cnt > 0) && ((Status & (STS_ERROR | STS_TEST)) != (STS_ERROR | STS_TEST))); @@ -1392,7 +1390,7 @@ static int tms380tr_bringup_diags(struct net_device *dev) else printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f); - return (-1); + return -1; } /* @@ -1466,7 +1464,7 @@ static int tms380tr_init_adapter(struct net_device *dev) { printk(KERN_INFO "%s: DMA failed\n", dev->name); /* DMA data error: wrong data in SCB */ - return (-1); + return -1; } i++; } while(i < 6); @@ -1475,11 +1473,11 @@ static int tms380tr_init_adapter(struct net_device *dev) do { /* Test if contents of SSB is valid */ if(SSB_Test[i] != *(sb_ptr + i)) /* DMA data error: wrong data in SSB */ - return (-1); + return -1; i++; } while (i < 8); - return (1); /* Adapter successfully initialized */ + return 1; /* Adapter successfully initialized */ } else { @@ -1490,7 +1488,7 @@ static int tms380tr_init_adapter(struct net_device *dev) Status &= STS_ERROR_MASK; /* ShowInitialisationErrorCode(Status); */ printk(KERN_INFO "%s: Status error: %d\n", dev->name, Status); - return (-1); /* Unrecoverable error */ + return -1; /* Unrecoverable error */ } else { @@ -1505,7 +1503,7 @@ static int tms380tr_init_adapter(struct net_device *dev) } while(retry_cnt > 0); printk(KERN_INFO "%s: Retry exceeded\n", dev->name); - return (-1); + return -1; } /* diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c index d4c7c0c0a3d64f405be97a242500a1a77d4df6fa..d3e788a9cd1c9ea90c29fd41f31d37e1dd5f9ebe 100644 --- a/drivers/net/tokenring/tmspci.c +++ b/drivers/net/tokenring/tmspci.c @@ -125,18 +125,16 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic dev->irq = pci_irq_line; dev->dma = 0; - printk("%s: %s\n", dev->name, cardinfo->name); - printk("%s: IO: %#4lx IRQ: %d\n", - dev->name, dev->base_addr, dev->irq); + dev_info(&pdev->dev, "%s\n", cardinfo->name); + dev_info(&pdev->dev, " IO: %#4lx IRQ: %d\n", dev->base_addr, dev->irq); tms_pci_read_eeprom(dev); - printk("%s: Ring Station Address: %pM\n", - dev->name, dev->dev_addr); + dev_info(&pdev->dev, " Ring Station Address: %pM\n", dev->dev_addr); ret = tmsdev_init(dev, &pdev->dev); if (ret) { - printk("%s: unable to get memory for dev->priv.\n", dev->name); + dev_info(&pdev->dev, "unable to get memory for dev->priv.\n"); goto err_out_region; } diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index a03730bd1da54aaee6073921e2a6ddd08a137e36..5c633a32eaeba1890b688a05f1ffab740560417f 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -219,7 +219,7 @@ static int tsi108_read_mii(struct tsi108_prv_data *data, int reg) if (i == 100) return 0xffff; else - return (TSI_READ_PHY(TSI108_MAC_MII_DATAIN)); + return TSI_READ_PHY(TSI108_MAC_MII_DATAIN); } static void tsi108_write_mii(struct tsi108_prv_data *data, diff --git a/drivers/net/tulip/Kconfig b/drivers/net/tulip/Kconfig index 516713fa0a0570a4d3faf871fa4cf1089297981b..f3035951422f2cc295b15d4d680f5128c34397ce 100644 --- a/drivers/net/tulip/Kconfig +++ b/drivers/net/tulip/Kconfig @@ -11,8 +11,8 @@ menuconfig NET_TULIP if NET_TULIP config DE2104X - tristate "Early DECchip Tulip (dc2104x) PCI support (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL + tristate "Early DECchip Tulip (dc2104x) PCI support" + depends on PCI select CRC32 ---help--- This driver is developed for the SMC EtherPower series Ethernet diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 6888e3d41462081952c7320b501736f03230ba78..28e1ffb13db99df5b0537a7426b2af3c03980feb 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -948,8 +948,9 @@ static void de_set_media (struct de_private *de) else macmode &= ~FullDuplex; - if (netif_msg_link(de)) { + if (netif_msg_link(de)) dev_info(&de->dev->dev, "set link %s\n", media_name[media]); + if (netif_msg_hw(de)) { dev_info(&de->dev->dev, "mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n", dr32(MacMode), dr32(SIAStatus), dr32(CSR13), dr32(CSR14), dr32(CSR15)); diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 75a64c88cf7aaf9294137e932c40918fff354234..4dbd493b996b0f5b802a061e19d9086dddac3fb8 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -1448,7 +1448,7 @@ de4x5_sw_reset(struct net_device *dev) status = -EIO; } - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; lp->tx_old = lp->tx_new; return status; @@ -1506,7 +1506,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev) lp->stats.tx_bytes += skb->len; outl(POLL_DEMAND, DE4X5_TPD);/* Start the TX */ - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; if (TX_BUFFS_AVAIL) { netif_start_queue(dev); /* Another pkt may be queued */ @@ -1657,7 +1657,7 @@ de4x5_rx(struct net_device *dev) } /* Change buffer ownership for this frame, back to the adapter */ - for (;lp->rx_old!=entry;lp->rx_old=(++lp->rx_old)%lp->rxRingSize) { + for (;lp->rx_old!=entry;lp->rx_old=(lp->rx_old + 1)%lp->rxRingSize) { lp->rx_ring[lp->rx_old].status = cpu_to_le32(R_OWN); barrier(); } @@ -1668,7 +1668,7 @@ de4x5_rx(struct net_device *dev) /* ** Update entry information */ - lp->rx_new = (++lp->rx_new) % lp->rxRingSize; + lp->rx_new = (lp->rx_new + 1) % lp->rxRingSize; } return 0; @@ -1726,7 +1726,7 @@ de4x5_tx(struct net_device *dev) } /* Update all the pointers */ - lp->tx_old = (++lp->tx_old) % lp->txRingSize; + lp->tx_old = (lp->tx_old + 1) % lp->txRingSize; } /* Any resources available? */ @@ -1801,7 +1801,7 @@ de4x5_rx_ovfc(struct net_device *dev) for (; (s32)le32_to_cpu(lp->rx_ring[lp->rx_new].status)>=0;) { lp->rx_ring[lp->rx_new].status = cpu_to_le32(R_OWN); - lp->rx_new = (++lp->rx_new % lp->rxRingSize); + lp->rx_new = (lp->rx_new + 1) % lp->rxRingSize; } outl(omr, DE4X5_OMR); @@ -1932,7 +1932,7 @@ set_multicast_list(struct net_device *dev) load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | SETUP_FRAME_LEN, (struct sk_buff *)1); - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ dev->trans_start = jiffies; /* prevent tx timeout */ } @@ -3119,7 +3119,7 @@ dc2114x_autoconf(struct net_device *dev) if (lp->media == _100Mb) { if ((slnk = test_for_100Mb(dev, 6500)) < 0) { lp->media = SPD_DET; - return (slnk & ~TIMER_CB); + return slnk & ~TIMER_CB; } } else { if (wait_for_link(dev) < 0) { @@ -3484,7 +3484,7 @@ is_spd_100(struct net_device *dev) spd = ((~gep_rd(dev)) & GEP_SLNK); } else { if ((lp->ibn == 2) || !lp->asBitValid) - return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0); + return (lp->chipset == DC21143) ? (~inl(DE4X5_SISR)&SISR_LS100) : 0; spd = (lp->asBitValid & (lp->asPolarity ^ (gep_rd(dev) & lp->asBit))) | (lp->linkOK & ~lp->asBitValid); @@ -3502,15 +3502,15 @@ is_100_up(struct net_device *dev) if (lp->useMII) { /* Double read for sticky bits & temporary drops */ mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS); + return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS; } else if (!lp->useSROM) { /* de500-xa */ - return ((~gep_rd(dev)) & GEP_SLNK); + return (~gep_rd(dev)) & GEP_SLNK; } else { if ((lp->ibn == 2) || !lp->asBitValid) - return ((lp->chipset == DC21143)?(~inl(DE4X5_SISR)&SISR_LS100):0); + return (lp->chipset == DC21143) ? (~inl(DE4X5_SISR)&SISR_LS100) : 0; - return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | - (lp->linkOK & ~lp->asBitValid)); + return (lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | + (lp->linkOK & ~lp->asBitValid); } } @@ -3523,17 +3523,17 @@ is_10_up(struct net_device *dev) if (lp->useMII) { /* Double read for sticky bits & temporary drops */ mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS); + return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII) & MII_SR_LKS; } else if (!lp->useSROM) { /* de500-xa */ - return ((~gep_rd(dev)) & GEP_LNP); + return (~gep_rd(dev)) & GEP_LNP; } else { if ((lp->ibn == 2) || !lp->asBitValid) - return (((lp->chipset & ~0x00ff) == DC2114x) ? + return ((lp->chipset & ~0x00ff) == DC2114x) ? (~inl(DE4X5_SISR)&SISR_LS10): - 0); + 0; - return ((lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | - (lp->linkOK & ~lp->asBitValid)); + return (lp->asBitValid&(lp->asPolarity^(gep_rd(dev)&lp->asBit))) | + (lp->linkOK & ~lp->asBitValid); } } @@ -3544,7 +3544,7 @@ is_anc_capable(struct net_device *dev) u_long iobase = dev->base_addr; if (lp->phy[lp->active].id && (!lp->useSROM || lp->useMII)) { - return (mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII)); + return mii_rd(MII_SR, lp->phy[lp->active].addr, DE4X5_MII); } else if ((lp->chipset & ~0x00ff) == DC2114x) { return (inl(DE4X5_SISR) & SISR_LPN) >> 12; } else { @@ -3568,7 +3568,7 @@ ping_media(struct net_device *dev, int msec) lp->tmp = lp->tx_new; /* Remember the ring position */ load_packet(dev, lp->frame, TD_LS | TD_FS | sizeof(lp->frame), (struct sk_buff *)1); - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; outl(POLL_DEMAND, DE4X5_TPD); } @@ -4930,7 +4930,7 @@ getfrom_mii(u32 command, u_long ioaddr) outl(command | MII_MDC, ioaddr); udelay(1); - return ((inl(ioaddr) >> 19) & 1); + return (inl(ioaddr) >> 19) & 1; } /* @@ -4975,8 +4975,8 @@ mii_get_oui(u_char phyaddr, u_long ioaddr) a.breg[0]=a.breg[1]; a.breg[1]=i; - return ((a.reg<<8)|ret); */ /* SEEQ and Cypress way */ -/* return ((r2<<6)|(u_int)(r3>>10)); */ /* NATIONAL and BROADCOM way */ + return (a.reg<<8)|ret; */ /* SEEQ and Cypress way */ +/* return (r2<<6)|(u_int)(r3>>10); */ /* NATIONAL and BROADCOM way */ return r2; /* (I did it) My way */ } @@ -5144,7 +5144,7 @@ gep_rd(struct net_device *dev) if (lp->chipset == DC21140) { return inl(DE4X5_GEP); } else if ((lp->chipset & ~0x00ff) == DC2114x) { - return (inl(DE4X5_SIGR) & 0x000fffff); + return inl(DE4X5_SIGR) & 0x000fffff; } return 0; @@ -5417,7 +5417,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) /* Set up the descriptor and give ownership to the card */ load_packet(dev, lp->setup_frame, TD_IC | PERFECT_F | TD_SET | SETUP_FRAME_LEN, (struct sk_buff *)1); - lp->tx_new = (++lp->tx_new) % lp->txRingSize; + lp->tx_new = (lp->tx_new + 1) % lp->txRingSize; outl(POLL_DEMAND, DE4X5_TPD); /* Start the TX */ netif_wake_queue(dev); /* Unlock the TX ring */ break; @@ -5474,7 +5474,8 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) tmp.lval[6] = inl(DE4X5_STRR); j+=4; tmp.lval[7] = inl(DE4X5_SIGR); j+=4; ioc->len = j; - if (copy_to_user(ioc->data, tmp.addr, ioc->len)) return -EFAULT; + if (copy_to_user(ioc->data, tmp.lval, ioc->len)) + return -EFAULT; break; #define DE4X5_DUMP 0x0f /* Dump the DE4X5 Status */ diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 0bc4f3030a806e53c7bb9a1528ec1933e62a0e8d..a9f7d5d1a2695f95a968001a93c1449b9ac998be 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -599,7 +599,7 @@ static int dmfe_open(struct DEVICE *dev) init_timer(&db->timer); db->timer.expires = DMFE_TIMER_WUT + HZ * 2; db->timer.data = (unsigned long)dev; - db->timer.function = &dmfe_timer; + db->timer.function = dmfe_timer; add_timer(&db->timer); return 0; diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index 1faf7a4d72024da4ffd864dfddb99502edd6fcc6..0013642903eecda0e8226579176de6f2f93babc5 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -180,21 +180,24 @@ int tulip_poll(struct napi_struct *napi, int budget) dev_warn(&dev->dev, "Oversized Ethernet frame spanned multiple buffers, status %08x!\n", status); - tp->stats.rx_length_errors++; - } + dev->stats.rx_length_errors++; + } } else { /* There was a fatal error. */ if (tulip_debug > 2) printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n", dev->name, status); - tp->stats.rx_errors++; /* end of a packet.*/ - if (pkt_len > 1518 || - (status & RxDescRunt)) - tp->stats.rx_length_errors++; - - if (status & 0x0004) tp->stats.rx_frame_errors++; - if (status & 0x0002) tp->stats.rx_crc_errors++; - if (status & 0x0001) tp->stats.rx_fifo_errors++; + dev->stats.rx_errors++; /* end of a packet.*/ + if (pkt_len > 1518 || + (status & RxDescRunt)) + dev->stats.rx_length_errors++; + + if (status & 0x0004) + dev->stats.rx_frame_errors++; + if (status & 0x0002) + dev->stats.rx_crc_errors++; + if (status & 0x0001) + dev->stats.rx_fifo_errors++; } } else { struct sk_buff *skb; @@ -244,8 +247,8 @@ int tulip_poll(struct napi_struct *napi, int budget) netif_receive_skb(skb); - tp->stats.rx_packets++; - tp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } #ifdef CONFIG_TULIP_NAPI_HW_MITIGATION received++; @@ -404,20 +407,23 @@ static int tulip_rx(struct net_device *dev) dev_warn(&dev->dev, "Oversized Ethernet frame spanned multiple buffers, status %08x!\n", status); - tp->stats.rx_length_errors++; + dev->stats.rx_length_errors++; } } else { /* There was a fatal error. */ if (tulip_debug > 2) printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n", dev->name, status); - tp->stats.rx_errors++; /* end of a packet.*/ + dev->stats.rx_errors++; /* end of a packet.*/ if (pkt_len > 1518 || (status & RxDescRunt)) - tp->stats.rx_length_errors++; - if (status & 0x0004) tp->stats.rx_frame_errors++; - if (status & 0x0002) tp->stats.rx_crc_errors++; - if (status & 0x0001) tp->stats.rx_fifo_errors++; + dev->stats.rx_length_errors++; + if (status & 0x0004) + dev->stats.rx_frame_errors++; + if (status & 0x0002) + dev->stats.rx_crc_errors++; + if (status & 0x0001) + dev->stats.rx_fifo_errors++; } } else { struct sk_buff *skb; @@ -467,8 +473,8 @@ static int tulip_rx(struct net_device *dev) netif_rx(skb); - tp->stats.rx_packets++; - tp->stats.rx_bytes += pkt_len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += pkt_len; } received++; entry = (++tp->cur_rx) % RX_RING_SIZE; @@ -602,18 +608,22 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n", dev->name, status); #endif - tp->stats.tx_errors++; - if (status & 0x4104) tp->stats.tx_aborted_errors++; - if (status & 0x0C00) tp->stats.tx_carrier_errors++; - if (status & 0x0200) tp->stats.tx_window_errors++; - if (status & 0x0002) tp->stats.tx_fifo_errors++; + dev->stats.tx_errors++; + if (status & 0x4104) + dev->stats.tx_aborted_errors++; + if (status & 0x0C00) + dev->stats.tx_carrier_errors++; + if (status & 0x0200) + dev->stats.tx_window_errors++; + if (status & 0x0002) + dev->stats.tx_fifo_errors++; if ((status & 0x0080) && tp->full_duplex == 0) - tp->stats.tx_heartbeat_errors++; + dev->stats.tx_heartbeat_errors++; } else { - tp->stats.tx_bytes += + dev->stats.tx_bytes += tp->tx_buffers[entry].skb->len; - tp->stats.collisions += (status >> 3) & 15; - tp->stats.tx_packets++; + dev->stats.collisions += (status >> 3) & 15; + dev->stats.tx_packets++; } pci_unmap_single(tp->pdev, tp->tx_buffers[entry].mapping, @@ -655,7 +665,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) if (csr5 & AbnormalIntr) { /* Abnormal error summary bit. */ if (csr5 == 0xffffffff) break; - if (csr5 & TxJabber) tp->stats.tx_errors++; + if (csr5 & TxJabber) + dev->stats.tx_errors++; if (csr5 & TxFIFOUnderflow) { if ((tp->csr6 & 0xC000) != 0xC000) tp->csr6 += 0x4000; /* Bump up the Tx threshold */ @@ -672,8 +683,8 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) } } if (csr5 & RxDied) { /* Missed a Rx frame. */ - tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; - tp->stats.rx_errors++; + dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; + dev->stats.rx_errors++; tulip_start_rxtx(tp); } /* @@ -789,7 +800,7 @@ irqreturn_t tulip_interrupt(int irq, void *dev_instance) #endif /* CONFIG_TULIP_NAPI */ if ((missed = ioread32(ioaddr + CSR8) & 0x1ffff)) { - tp->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed; + dev->stats.rx_dropped += missed & 0x10000 ? 0x10000 : missed; } if (tulip_debug > 4) diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index e525875ed67d4b0aaadcea64d4d0a8c87620776f..ed66a16711dceadc550db0316bd52c8bef15688d 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -417,7 +417,6 @@ struct tulip_private { int revision; int flags; struct napi_struct napi; - struct net_device_stats stats; struct timer_list timer; /* Media selection timer. */ struct timer_list oom_timer; /* Out of memory timer. */ u32 mc_filter[2]; @@ -570,7 +569,7 @@ static inline void tulip_tx_timeout_complete(struct tulip_private *tp, void __io /* Trigger an immediate transmit demand. */ iowrite32(0, ioaddr + CSR1); - tp->stats.tx_errors++; + tp->dev->stats.tx_errors++; } #endif /* __NET_TULIP_H__ */ diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 3a8d7efa2acf554c6015de56a66b3390fc7503a1..2c39f25912167fd144f4dae7f9681648e924c446 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -725,7 +725,7 @@ static void tulip_clean_tx_ring(struct tulip_private *tp) int status = le32_to_cpu(tp->tx_ring[entry].status); if (status < 0) { - tp->stats.tx_errors++; /* It wasn't Txed */ + tp->dev->stats.tx_errors++; /* It wasn't Txed */ tp->tx_ring[entry].status = 0; } @@ -781,8 +781,8 @@ static void tulip_down (struct net_device *dev) /* release any unconsumed transmit buffers */ tulip_clean_tx_ring(tp); - if (ioread32 (ioaddr + CSR6) != 0xffffffff) - tp->stats.rx_missed_errors += ioread32 (ioaddr + CSR8) & 0xffff; + if (ioread32(ioaddr + CSR6) != 0xffffffff) + dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; spin_unlock_irqrestore (&tp->lock, flags); @@ -864,12 +864,12 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev) spin_lock_irqsave (&tp->lock, flags); - tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; + dev->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff; spin_unlock_irqrestore(&tp->lock, flags); } - return &tp->stats; + return &dev->stats; } diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 96de5829b940806729f02fa26eeb7537713e821d..74217dbf014330fe3f545775b1481b7ff101fd7f 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c @@ -480,7 +480,7 @@ static int uli526x_open(struct net_device *dev) init_timer(&db->timer); db->timer.expires = ULI526X_TIMER_WUT + HZ * 2; db->timer.data = (unsigned long)dev; - db->timer.function = &uli526x_timer; + db->timer.function = uli526x_timer; add_timer(&db->timer); return 0; @@ -1747,7 +1747,7 @@ static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset) if(cr10_value&0x10000000) break; } - return (cr10_value&0x0ffff); + return cr10_value & 0x0ffff; } static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr, u8 offset, u16 phy_data) diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 66d41cf8da29fb5e233f3be923278142ee61b7a4..f0b231035dee9f2450c43e1b68da0aafafc892ed 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -662,7 +662,7 @@ static int netdev_open(struct net_device *dev) init_timer(&np->timer); np->timer.expires = jiffies + 1*HZ; np->timer.data = (unsigned long)dev; - np->timer.function = &netdev_timer; /* timer handler */ + np->timer.function = netdev_timer; /* timer handler */ add_timer(&np->timer); return 0; out_err: diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c index a439e93be22d24132f29e6b146b9d1a0af430178..5a73752be2ca2cdf455968855f82ae5b3bfa8f9e 100644 --- a/drivers/net/tulip/xircom_cb.c +++ b/drivers/net/tulip/xircom_cb.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -181,19 +180,6 @@ static void print_binary(unsigned int number) } #endif -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - struct xircom_private *private = netdev_priv(dev); - - strcpy(info->driver, "xircom_cb"); - strcpy(info->bus_info, pci_name(private->pdev)); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - static const struct net_device_ops netdev_ops = { .ndo_open = xircom_open, .ndo_stop = xircom_close, @@ -279,7 +265,6 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ setup_descriptors(private); dev->netdev_ops = &netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); pci_set_drvdata(pdev, dev); if (register_netdev(dev)) { diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 2e50077ff450b249a9042259375b5288f41965c6..1cc67138adbf4a248294a029295df268bfbbc710 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -541,7 +541,7 @@ typhoon_process_response(struct typhoon *tp, int resp_size, indexes->respCleared = cpu_to_le32(cleared); wmb(); - return (resp_save == NULL); + return resp_save == NULL; } static inline int @@ -962,36 +962,34 @@ typhoon_do_get_stats(struct typhoon *tp) * The extra status reported would be a good candidate for * ethtool_ops->get_{strings,stats}() */ - stats->tx_packets = le32_to_cpu(s->txPackets); - stats->tx_bytes = le64_to_cpu(s->txBytes); - stats->tx_errors = le32_to_cpu(s->txCarrierLost); - stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost); - stats->collisions = le32_to_cpu(s->txMultipleCollisions); - stats->rx_packets = le32_to_cpu(s->rxPacketsGood); - stats->rx_bytes = le64_to_cpu(s->rxBytesGood); - stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns); + stats->tx_packets = le32_to_cpu(s->txPackets) + + saved->tx_packets; + stats->tx_bytes = le64_to_cpu(s->txBytes) + + saved->tx_bytes; + stats->tx_errors = le32_to_cpu(s->txCarrierLost) + + saved->tx_errors; + stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) + + saved->tx_carrier_errors; + stats->collisions = le32_to_cpu(s->txMultipleCollisions) + + saved->collisions; + stats->rx_packets = le32_to_cpu(s->rxPacketsGood) + + saved->rx_packets; + stats->rx_bytes = le64_to_cpu(s->rxBytesGood) + + saved->rx_bytes; + stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) + + saved->rx_fifo_errors; stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) + - le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors); - stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors); - stats->rx_length_errors = le32_to_cpu(s->rxOversized); + le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) + + saved->rx_errors; + stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) + + saved->rx_crc_errors; + stats->rx_length_errors = le32_to_cpu(s->rxOversized) + + saved->rx_length_errors; tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ? SPEED_100 : SPEED_10; tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF; - /* add in the saved statistics - */ - stats->tx_packets += saved->tx_packets; - stats->tx_bytes += saved->tx_bytes; - stats->tx_errors += saved->tx_errors; - stats->collisions += saved->collisions; - stats->rx_packets += saved->rx_packets; - stats->rx_bytes += saved->rx_bytes; - stats->rx_fifo_errors += saved->rx_fifo_errors; - stats->rx_errors += saved->rx_errors; - stats->rx_crc_errors += saved->rx_crc_errors; - stats->rx_length_errors += saved->rx_length_errors; - return 0; } @@ -1762,7 +1760,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile __le32 * read (TYPHOON_RX_IP_CHK_GOOD | TYPHOON_RX_UDP_CHK_GOOD)) { new_skb->ip_summed = CHECKSUM_UNNECESSARY; } else - new_skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(new_skb); spin_lock(&tp->state_lock); if(tp->vlgrp != NULL && rx->rxStatus & TYPHOON_RX_VLAN) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index d7b7018a1de1d180a003af42e43d967b5441b38e..52ffabe6db0eac43cc39a14ece7326f1d686b5aa 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -358,6 +358,14 @@ config USB_NET_ZAURUS really need this non-conformant variant of CDC Ethernet (or in some cases CDC MDLM) protocol, not "g_ether". +config USB_NET_CX82310_ETH + tristate "Conexant CX82310 USB ethernet port" + depends on USB_USBNET + help + Choose this option if you're using a Conexant CX82310-based ADSL + router with USB ethernet port. This driver is for routers only, + it will not work with ADSL modems (use cxacru driver instead). + config USB_HSO tristate "Option USB High Speed Mobile Devices" depends on USB && RFKILL diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index b13a279663ba11b250a838c85619186d5e08eb56..a19b0259ae16c118165be08720553f0bbfa4d289 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -25,4 +25,5 @@ obj-$(CONFIG_USB_NET_INT51X1) += int51x1.o obj-$(CONFIG_USB_CDC_PHONET) += cdc-phonet.o obj-$(CONFIG_USB_IPHETH) += ipheth.o obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o +obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c new file mode 100644 index 0000000000000000000000000000000000000000..8969f124c18c02f1dabbb2d9aff2f3860bd8d927 --- /dev/null +++ b/drivers/net/usb/cx82310_eth.c @@ -0,0 +1,346 @@ +/* + * Driver for USB ethernet port of Conexant CX82310-based ADSL routers + * Copyright (C) 2010 by Ondrej Zary + * some parts inspired by the cxacru driver + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum cx82310_cmd { + CMD_START = 0x84, /* no effect? */ + CMD_STOP = 0x85, /* no effect? */ + CMD_GET_STATUS = 0x90, /* returns nothing? */ + CMD_GET_MAC_ADDR = 0x91, /* read MAC address */ + CMD_GET_LINK_STATUS = 0x92, /* not useful, link is always up */ + CMD_ETHERNET_MODE = 0x99, /* unknown, needed during init */ +}; + +enum cx82310_status { + STATUS_UNDEFINED, + STATUS_SUCCESS, + STATUS_ERROR, + STATUS_UNSUPPORTED, + STATUS_UNIMPLEMENTED, + STATUS_PARAMETER_ERROR, + STATUS_DBG_LOOPBACK, +}; + +#define CMD_PACKET_SIZE 64 +/* first command after power on can take around 8 seconds */ +#define CMD_TIMEOUT 15000 +#define CMD_REPLY_RETRY 5 + +#define CX82310_MTU 1514 +#define CMD_EP 0x01 + +/* + * execute control command + * - optionally send some data (command parameters) + * - optionally wait for the reply + * - optionally read some data from the reply + */ +static int cx82310_cmd(struct usbnet *dev, enum cx82310_cmd cmd, bool reply, + u8 *wdata, int wlen, u8 *rdata, int rlen) +{ + int actual_len, retries, ret; + struct usb_device *udev = dev->udev; + u8 *buf = kzalloc(CMD_PACKET_SIZE, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + + /* create command packet */ + buf[0] = cmd; + if (wdata) + memcpy(buf + 4, wdata, min_t(int, wlen, CMD_PACKET_SIZE - 4)); + + /* send command packet */ + ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, CMD_EP), buf, + CMD_PACKET_SIZE, &actual_len, CMD_TIMEOUT); + if (ret < 0) { + dev_err(&dev->udev->dev, "send command %#x: error %d\n", + cmd, ret); + goto end; + } + + if (reply) { + /* wait for reply, retry if it's empty */ + for (retries = 0; retries < CMD_REPLY_RETRY; retries++) { + ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, CMD_EP), + buf, CMD_PACKET_SIZE, &actual_len, + CMD_TIMEOUT); + if (ret < 0) { + dev_err(&dev->udev->dev, + "reply receive error %d\n", ret); + goto end; + } + if (actual_len > 0) + break; + } + if (actual_len == 0) { + dev_err(&dev->udev->dev, "no reply to command %#x\n", + cmd); + ret = -EIO; + goto end; + } + if (buf[0] != cmd) { + dev_err(&dev->udev->dev, + "got reply to command %#x, expected: %#x\n", + buf[0], cmd); + ret = -EIO; + goto end; + } + if (buf[1] != STATUS_SUCCESS) { + dev_err(&dev->udev->dev, "command %#x failed: %#x\n", + cmd, buf[1]); + ret = -EIO; + goto end; + } + if (rdata) + memcpy(rdata, buf + 4, + min_t(int, rlen, CMD_PACKET_SIZE - 4)); + } +end: + kfree(buf); + return ret; +} + +#define partial_len data[0] /* length of partial packet data */ +#define partial_rem data[1] /* remaining (missing) data length */ +#define partial_data data[2] /* partial packet data */ + +static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int ret; + char buf[15]; + struct usb_device *udev = dev->udev; + + /* avoid ADSL modems - continue only if iProduct is "USB NET CARD" */ + if (usb_string(udev, udev->descriptor.iProduct, buf, sizeof(buf)) > 0 + && strcmp(buf, "USB NET CARD")) { + dev_info(&udev->dev, "ignoring: probably an ADSL modem\n"); + return -ENODEV; + } + + ret = usbnet_get_endpoints(dev, intf); + if (ret) + return ret; + + /* + * this must not include ethernet header as the device can send partial + * packets with no header (and sometimes even empty URBs) + */ + dev->net->hard_header_len = 0; + /* we can send at most 1514 bytes of data (+ 2-byte header) per URB */ + dev->hard_mtu = CX82310_MTU + 2; + /* we can receive URBs up to 4KB from the device */ + dev->rx_urb_size = 4096; + + dev->partial_data = (unsigned long) kmalloc(dev->hard_mtu, GFP_KERNEL); + if (!dev->partial_data) + return -ENOMEM; + + /* enable ethernet mode (?) */ + ret = cx82310_cmd(dev, CMD_ETHERNET_MODE, true, "\x01", 1, NULL, 0); + if (ret) { + dev_err(&udev->dev, "unable to enable ethernet mode: %d\n", + ret); + goto err; + } + + /* get the MAC address */ + ret = cx82310_cmd(dev, CMD_GET_MAC_ADDR, true, NULL, 0, + dev->net->dev_addr, ETH_ALEN); + if (ret) { + dev_err(&udev->dev, "unable to read MAC address: %d\n", ret); + goto err; + } + + /* start (does not seem to have any effect?) */ + ret = cx82310_cmd(dev, CMD_START, false, NULL, 0, NULL, 0); + if (ret) + goto err; + + return 0; +err: + kfree((void *)dev->partial_data); + return ret; +} + +static void cx82310_unbind(struct usbnet *dev, struct usb_interface *intf) +{ + kfree((void *)dev->partial_data); +} + +/* + * RX is NOT easy - we can receive multiple packets per skb, each having 2-byte + * packet length at the beginning. + * The last packet might be incomplete (when it crosses the 4KB URB size), + * continuing in the next skb (without any headers). + * If a packet has odd length, there is one extra byte at the end (before next + * packet or at the end of the URB). + */ +static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + int len; + struct sk_buff *skb2; + + /* + * If the last skb ended with an incomplete packet, this skb contains + * end of that packet at the beginning. + */ + if (dev->partial_rem) { + len = dev->partial_len + dev->partial_rem; + skb2 = alloc_skb(len, GFP_ATOMIC); + if (!skb2) + return 0; + skb_put(skb2, len); + memcpy(skb2->data, (void *)dev->partial_data, + dev->partial_len); + memcpy(skb2->data + dev->partial_len, skb->data, + dev->partial_rem); + usbnet_skb_return(dev, skb2); + skb_pull(skb, (dev->partial_rem + 1) & ~1); + dev->partial_rem = 0; + if (skb->len < 2) + return 1; + } + + /* a skb can contain multiple packets */ + while (skb->len > 1) { + /* first two bytes are packet length */ + len = skb->data[0] | (skb->data[1] << 8); + skb_pull(skb, 2); + + /* if last packet in the skb, let usbnet to process it */ + if (len == skb->len || len + 1 == skb->len) { + skb_trim(skb, len); + break; + } + + if (len > CX82310_MTU) { + dev_err(&dev->udev->dev, "RX packet too long: %d B\n", + len); + return 0; + } + + /* incomplete packet, save it for the next skb */ + if (len > skb->len) { + dev->partial_len = skb->len; + dev->partial_rem = len - skb->len; + memcpy((void *)dev->partial_data, skb->data, + dev->partial_len); + skb_pull(skb, skb->len); + break; + } + + skb2 = alloc_skb(len, GFP_ATOMIC); + if (!skb2) + return 0; + skb_put(skb2, len); + memcpy(skb2->data, skb->data, len); + /* process the packet */ + usbnet_skb_return(dev, skb2); + + skb_pull(skb, (len + 1) & ~1); + } + + /* let usbnet process the last packet */ + return 1; +} + +/* TX is easy, just add 2 bytes of length at the beginning */ +static struct sk_buff *cx82310_tx_fixup(struct usbnet *dev, struct sk_buff *skb, + gfp_t flags) +{ + int len = skb->len; + + if (skb_headroom(skb) < 2) { + struct sk_buff *skb2 = skb_copy_expand(skb, 2, 0, flags); + dev_kfree_skb_any(skb); + skb = skb2; + if (!skb) + return NULL; + } + skb_push(skb, 2); + + skb->data[0] = len; + skb->data[1] = len >> 8; + + return skb; +} + + +static const struct driver_info cx82310_info = { + .description = "Conexant CX82310 USB ethernet", + .flags = FLAG_ETHER, + .bind = cx82310_bind, + .unbind = cx82310_unbind, + .rx_fixup = cx82310_rx_fixup, + .tx_fixup = cx82310_tx_fixup, +}; + +#define USB_DEVICE_CLASS(vend, prod, cl, sc, pr) \ + .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \ + USB_DEVICE_ID_MATCH_DEV_INFO, \ + .idVendor = (vend), \ + .idProduct = (prod), \ + .bDeviceClass = (cl), \ + .bDeviceSubClass = (sc), \ + .bDeviceProtocol = (pr) + +static const struct usb_device_id products[] = { + { + USB_DEVICE_CLASS(0x0572, 0xcb01, 0xff, 0, 0), + .driver_info = (unsigned long) &cx82310_info + }, + { }, +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver cx82310_driver = { + .name = "cx82310_eth", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, +}; + +static int __init cx82310_init(void) +{ + return usb_register(&cx82310_driver); +} +module_init(cx82310_init); + +static void __exit cx82310_exit(void) +{ + usb_deregister(&cx82310_driver); +} +module_exit(cx82310_exit); + +MODULE_AUTHOR("Ondrej Zary"); +MODULE_DESCRIPTION("Conexant CX82310-based ADSL router USB ethernet driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index b8e957249132c7fe75f56a197e956d51d7e8c2ef..b154a94de03e61927cdc063c8671867108cf7b89 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -843,16 +843,7 @@ static netdev_tx_t hso_net_start_xmit(struct sk_buff *skb, return NETDEV_TX_OK; } -static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) -{ - struct hso_net *odev = netdev_priv(net); - - strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN); - usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info); -} - static const struct ethtool_ops ops = { - .get_drvinfo = hso_get_drvinfo, .get_link = ethtool_op_get_link }; diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 2b7b39cad1ce954f7eec5511fefb7f86611c45a1..5e98643a4a214b2734d738cc7a24b55ef0225298 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -759,14 +759,6 @@ static int kaweth_close(struct net_device *net) return 0; } -static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - struct kaweth_device *kaweth = netdev_priv(dev); - - strlcpy(info->driver, driver_name, sizeof(info->driver)); - usb_make_path(kaweth->dev, info->bus_info, sizeof (info->bus_info)); -} - static u32 kaweth_get_link(struct net_device *dev) { struct kaweth_device *kaweth = netdev_priv(dev); @@ -775,7 +767,6 @@ static u32 kaweth_get_link(struct net_device *dev) } static const struct ethtool_ops ops = { - .get_drvinfo = kaweth_get_drvinfo, .get_link = kaweth_get_link }; diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index ee85c8b9a8582c6e5debff8635ef9ad444794415..d1ac15c95faf6d00803a67c7e4c9294e8299984f 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -203,7 +203,7 @@ static inline void sierra_net_set_private(struct usbnet *dev, /* is packet IPv4 */ static inline int is_ip(struct sk_buff *skb) { - return (skb->protocol == cpu_to_be16(ETH_P_IP)); + return skb->protocol == cpu_to_be16(ETH_P_IP); } /* @@ -354,7 +354,7 @@ static void sierra_net_set_ctx_index(struct sierra_net_data *priv, u8 ctx_ix) static inline int sierra_net_is_valid_addrlen(u8 len) { - return (len == sizeof(struct in_addr)); + return len == sizeof(struct in_addr); } static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 12a3c88c52821fdfb44c05ca964ef3bb022ce3c4..65cb1abfbe577f304f390fe4b7dba650fb5b2574 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -805,8 +805,6 @@ static int smsc95xx_reset(struct usbnet *dev) return ret; } - smsc95xx_init_mac_address(dev); - ret = smsc95xx_set_mac_address(dev); if (ret < 0) return ret; @@ -1047,6 +1045,8 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE; pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE; + smsc95xx_init_mac_address(dev); + /* Init all registers */ ret = smsc95xx_reset(dev); diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 5ec542dd5b5007825cf47991cab64894623767ec..0bbc0c3231358de20f395d9fd34b05279e0e13fd 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -250,7 +250,7 @@ static int veth_close(struct net_device *dev) static int is_valid_veth_mtu(int new_mtu) { - return (new_mtu >= MIN_MTU && new_mtu <= MAX_MTU); + return new_mtu >= MIN_MTU && new_mtu <= MAX_MTU; } static int veth_change_mtu(struct net_device *dev, int new_mtu) diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index f53412368ce1e1745a7796a8cc8181b16027e797..cab96ad49e601488100d744ecacc6a76539f9b34 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -312,13 +312,14 @@ VELOCITY_PARAM(flow_control, "Enable flow control ability"); #define MED_LNK_DEF 0 #define MED_LNK_MIN 0 -#define MED_LNK_MAX 4 +#define MED_LNK_MAX 5 /* speed_duplex[] is used for setting the speed and duplex mode of NIC. 0: indicate autonegotiation for both speed and duplex mode 1: indicate 100Mbps half duplex mode 2: indicate 100Mbps full duplex mode 3: indicate 10Mbps half duplex mode 4: indicate 10Mbps full duplex mode + 5: indicate 1000Mbps full duplex mode Note: if EEPROM have been set to the force mode, this option is ignored @@ -617,6 +618,9 @@ static u32 velocity_get_opt_media_mode(struct velocity_info *vptr) case SPD_DPX_10_HALF: status = VELOCITY_SPEED_10; break; + case SPD_DPX_1000_FULL: + status = VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL; + break; } vptr->mii_status = status; return status; @@ -922,6 +926,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) /* enable AUTO-NEGO mode */ mii_set_auto_on(vptr); } else { + u16 CTRL1000; u16 ANAR; u8 CHIPGCR; @@ -936,7 +941,11 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) BYTE_REG_BITS_ON(CHIPGCR_FCMODE, ®s->CHIPGCR); CHIPGCR = readb(®s->CHIPGCR); - CHIPGCR &= ~CHIPGCR_FCGMII; + + if (mii_status & VELOCITY_SPEED_1000) + CHIPGCR |= CHIPGCR_FCGMII; + else + CHIPGCR &= ~CHIPGCR_FCGMII; if (mii_status & VELOCITY_DUPLEX_FULL) { CHIPGCR |= CHIPGCR_FCFDX; @@ -952,7 +961,13 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) BYTE_REG_BITS_ON(TCR_TB2BDIS, ®s->TCR); } - MII_REG_BITS_OFF(ADVERTISE_1000FULL | ADVERTISE_1000HALF, MII_CTRL1000, vptr->mac_regs); + velocity_mii_read(vptr->mac_regs, MII_CTRL1000, &CTRL1000); + CTRL1000 &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); + if ((mii_status & VELOCITY_SPEED_1000) && + (mii_status & VELOCITY_DUPLEX_FULL)) { + CTRL1000 |= ADVERTISE_1000FULL; + } + velocity_mii_write(vptr->mac_regs, MII_CTRL1000, CTRL1000); if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10)) BYTE_REG_BITS_OFF(TESTCFG_HBDIS, ®s->TESTCFG); @@ -967,7 +982,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) ANAR |= ADVERTISE_100FULL; else ANAR |= ADVERTISE_100HALF; - } else { + } else if (mii_status & VELOCITY_SPEED_10) { if (mii_status & VELOCITY_DUPLEX_FULL) ANAR |= ADVERTISE_10FULL; else @@ -1013,6 +1028,9 @@ static void velocity_print_link_status(struct velocity_info *vptr) } else { VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name); switch (vptr->options.spd_dpx) { + case SPD_DPX_1000_FULL: + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps full duplex\n"); + break; case SPD_DPX_100_HALF: VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n"); break; @@ -1954,7 +1972,7 @@ static int velocity_tx_srv(struct velocity_info *vptr) */ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (rd->rdesc1.CSM & CSM_IPKT) { if (rd->rdesc1.CSM & CSM_IPOK) { @@ -2574,7 +2592,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb, td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16; - if (vptr->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { td_ptr->tdesc1.vlan = cpu_to_le16(vlan_tx_tag_get(skb)); td_ptr->tdesc1.TCR |= TCR0_VETAG; } @@ -3170,6 +3188,37 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; + + cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; + if (vptr->options.spd_dpx == SPD_DPX_AUTO) { + cmd->advertising |= + ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full; + } else { + switch (vptr->options.spd_dpx) { + case SPD_DPX_1000_FULL: + cmd->advertising |= ADVERTISED_1000baseT_Full; + break; + case SPD_DPX_100_HALF: + cmd->advertising |= ADVERTISED_100baseT_Half; + break; + case SPD_DPX_100_FULL: + cmd->advertising |= ADVERTISED_100baseT_Full; + break; + case SPD_DPX_10_HALF: + cmd->advertising |= ADVERTISED_10baseT_Half; + break; + case SPD_DPX_10_FULL: + cmd->advertising |= ADVERTISED_10baseT_Full; + break; + default: + break; + } + } if (status & VELOCITY_SPEED_1000) cmd->speed = SPEED_1000; else if (status & VELOCITY_SPEED_100) @@ -3200,14 +3249,35 @@ static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd curr_status &= (~VELOCITY_LINK_FAIL); new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0); + new_status |= ((cmd->speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0); new_status |= ((cmd->speed == SPEED_100) ? VELOCITY_SPEED_100 : 0); new_status |= ((cmd->speed == SPEED_10) ? VELOCITY_SPEED_10 : 0); new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0); - if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) + if ((new_status & VELOCITY_AUTONEG_ENABLE) && + (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) { ret = -EINVAL; - else + } else { + enum speed_opt spd_dpx; + + if (new_status & VELOCITY_AUTONEG_ENABLE) + spd_dpx = SPD_DPX_AUTO; + else if ((new_status & VELOCITY_SPEED_1000) && + (new_status & VELOCITY_DUPLEX_FULL)) { + spd_dpx = SPD_DPX_1000_FULL; + } else if (new_status & VELOCITY_SPEED_100) + spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ? + SPD_DPX_100_FULL : SPD_DPX_100_HALF; + else if (new_status & VELOCITY_SPEED_10) + spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ? + SPD_DPX_10_FULL : SPD_DPX_10_HALF; + else + return -EOPNOTSUPP; + + vptr->options.spd_dpx = spd_dpx; + velocity_set_media_mode(vptr, new_status); + } return ret; } diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h index f7b33ae7a70301e7c61e49c46e37e6180c316f32..aa2e69b9ff61301569cf1a8e1b3d62259ace2894 100644 --- a/drivers/net/via-velocity.h +++ b/drivers/net/via-velocity.h @@ -848,7 +848,7 @@ enum velocity_owner { * Bits in CHIPGCR register */ -#define CHIPGCR_FCGMII 0x80 +#define CHIPGCR_FCGMII 0x80 /* enable GMII mode */ #define CHIPGCR_FCFDX 0x40 #define CHIPGCR_FCRESV 0x20 #define CHIPGCR_FCMODE 0x10 @@ -1390,7 +1390,8 @@ enum speed_opt { SPD_DPX_100_HALF = 1, SPD_DPX_100_FULL = 2, SPD_DPX_10_HALF = 3, - SPD_DPX_10_FULL = 4 + SPD_DPX_10_FULL = 4, + SPD_DPX_1000_FULL = 5 }; enum velocity_init_type { @@ -1504,22 +1505,25 @@ struct velocity_info { * addresses on this chain then we use the first - multi-IP WOL is not * supported. * - * CHECK ME: locking */ static inline int velocity_get_ip(struct velocity_info *vptr) { - struct in_device *in_dev = (struct in_device *) vptr->dev->ip_ptr; + struct in_device *in_dev; struct in_ifaddr *ifa; + int res = -ENOENT; + rcu_read_lock(); + in_dev = __in_dev_get_rcu(vptr->dev); if (in_dev != NULL) { ifa = (struct in_ifaddr *) in_dev->ifa_list; if (ifa != NULL) { memcpy(vptr->ip_addr, &ifa->ifa_address, 4); - return 0; + res = 0; } } - return -ENOENT; + rcu_read_unlock(); + return res; } /** diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 4598e9d2608f7ca4c098d8745432a8a6151de757..bb6b67f6b0cc731df707cbfc06006a2c8c39b198 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -705,19 +705,6 @@ static int virtnet_close(struct net_device *dev) return 0; } -static void virtnet_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *drvinfo) -{ - struct virtnet_info *vi = netdev_priv(dev); - struct virtio_device *vdev = vi->vdev; - - strncpy(drvinfo->driver, KBUILD_MODNAME, ARRAY_SIZE(drvinfo->driver)); - strncpy(drvinfo->version, "N/A", ARRAY_SIZE(drvinfo->version)); - strncpy(drvinfo->fw_version, "N/A", ARRAY_SIZE(drvinfo->fw_version)); - strncpy(drvinfo->bus_info, dev_name(&vdev->dev), - ARRAY_SIZE(drvinfo->bus_info)); -} - static int virtnet_set_tx_csum(struct net_device *dev, u32 data) { struct virtnet_info *vi = netdev_priv(dev); @@ -830,7 +817,6 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid) } static const struct ethtool_ops virtnet_ethtool_ops = { - .get_drvinfo = virtnet_get_drvinfo, .set_tx_csum = virtnet_set_tx_csum, .set_sg = ethtool_op_set_sg, .set_tso = ethtool_op_set_tso, diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index abe0ff53daf353c1be44876b19cf37f4cefe4403..3f60e0e3097bdee3237ebdae7ef2d66844ce1669 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -1042,11 +1042,11 @@ vmxnet3_rx_csum(struct vmxnet3_adapter *adapter, skb->csum = htons(gdesc->rcd.csum); skb->ip_summed = CHECKSUM_PARTIAL; } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } } else { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); } } @@ -1548,23 +1548,6 @@ vmxnet3_free_irqs(struct vmxnet3_adapter *adapter) } } - -inline void set_flag_le16(__le16 *data, u16 flag) -{ - *data = cpu_to_le16(le16_to_cpu(*data) | flag); -} - -inline void set_flag_le64(__le64 *data, u64 flag) -{ - *data = cpu_to_le64(le64_to_cpu(*data) | flag); -} - -inline void reset_flag_le64(__le64 *data, u64 flag) -{ - *data = cpu_to_le64(le64_to_cpu(*data) & ~flag); -} - - static void vmxnet3_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) { @@ -1634,7 +1617,7 @@ vmxnet3_restore_vlan(struct vmxnet3_adapter *adapter) u32 *vfTable = adapter->shared->devRead.rxFilterConf.vfTable; bool activeVlan = false; - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (vlan_group_get_device(adapter->vlan_grp, vid)) { VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid); activeVlan = true; diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 2121c735cabd6ab3fddf335d302f7803cef87a76..c88ea5cbba0d064a85563f78780016a42badeb05 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -353,9 +353,20 @@ struct vmxnet3_adapter { #define VMXNET3_MAX_ETH_HDR_SIZE 22 #define VMXNET3_MAX_SKB_BUF_SIZE (3*1024) -void set_flag_le16(__le16 *data, u16 flag); -void set_flag_le64(__le64 *data, u64 flag); -void reset_flag_le64(__le64 *data, u64 flag); +static inline void set_flag_le16(__le16 *data, u16 flag) +{ + *data = cpu_to_le16(le16_to_cpu(*data) | flag); +} + +static inline void set_flag_le64(__le64 *data, u64 flag) +{ + *data = cpu_to_le64(le64_to_cpu(*data) | flag); +} + +static inline void reset_flag_le64(__le64 *data, u64 flag) +{ + *data = cpu_to_le64(le64_to_cpu(*data) & ~flag); +} int vmxnet3_quiesce_dev(struct vmxnet3_adapter *adapter); diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index c7c5605b3728384069e0e3aa187a30b0e85bd512..a69542ecb68de8592e7f9791d4c627104caba046 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -501,7 +501,7 @@ vxge_rx_1b_compl(struct __vxge_hw_ring *ringh, void *dtr, ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK) skb->ip_summed = CHECKSUM_UNNECESSARY; else - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); vxge_rx_complete(ring, skb, ext_info.vlan, pkt_length, &ext_info); @@ -822,7 +822,7 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev) dev->name, __func__, __LINE__, fifo_hw, dtr, dtr_priv); - if (vdev->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { u16 vlan_tag = vlan_tx_tag_get(skb); vxge_hw_fifo_txdl_vlan_set(dtr, vlan_tag); } @@ -1862,7 +1862,7 @@ enum vxge_hw_status vxge_restore_vpath_vid_table(struct vxge_vpath *vpath) if (vdev->vlgrp && vpath->is_open) { - for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { + for (vid = 0; vid < VLAN_N_VID; vid++) { if (!vlan_group_get_device(vdev->vlgrp, vid)) continue; /* Add these vlan to the vid table */ @@ -2159,8 +2159,8 @@ static int vxge_alloc_msix(struct vxgedev *vdev) /* Alarm MSIX Vectors count */ vdev->intr_cnt++; - vdev->entries = kzalloc(vdev->intr_cnt * sizeof(struct msix_entry), - GFP_KERNEL); + vdev->entries = kcalloc(vdev->intr_cnt, sizeof(struct msix_entry), + GFP_KERNEL); if (!vdev->entries) { vxge_debug_init(VXGE_ERR, "%s: memory allocation failed", @@ -2169,9 +2169,9 @@ static int vxge_alloc_msix(struct vxgedev *vdev) goto alloc_entries_failed; } - vdev->vxge_entries = - kzalloc(vdev->intr_cnt * sizeof(struct vxge_msix_entry), - GFP_KERNEL); + vdev->vxge_entries = kcalloc(vdev->intr_cnt, + sizeof(struct vxge_msix_entry), + GFP_KERNEL); if (!vdev->vxge_entries) { vxge_debug_init(VXGE_ERR, "%s: memory allocation failed", VXGE_DRIVER_NAME); @@ -2914,26 +2914,18 @@ static int vxge_change_mtu(struct net_device *dev, int new_mtu) } /** - * vxge_get_stats + * vxge_get_stats64 * @dev: pointer to the device structure + * @stats: pointer to struct rtnl_link_stats64 * - * Updates the device statistics structure. This function updates the device - * statistics structure in the net_device structure and returns a pointer - * to the same. */ -static struct net_device_stats * -vxge_get_stats(struct net_device *dev) +static struct rtnl_link_stats64 * +vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) { - struct vxgedev *vdev; - struct net_device_stats *net_stats; + struct vxgedev *vdev = netdev_priv(dev); int k; - vdev = netdev_priv(dev); - - net_stats = &vdev->stats.net_stats; - - memset(net_stats, 0, sizeof(struct net_device_stats)); - + /* net_stats already zeroed by caller */ for (k = 0; k < vdev->no_of_vpath; k++) { net_stats->rx_packets += vdev->vpaths[k].ring.stats.rx_frms; net_stats->rx_bytes += vdev->vpaths[k].ring.stats.rx_bytes; @@ -3102,7 +3094,7 @@ vxge_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) static const struct net_device_ops vxge_netdev_ops = { .ndo_open = vxge_open, .ndo_stop = vxge_close, - .ndo_get_stats = vxge_get_stats, + .ndo_get_stats64 = vxge_get_stats64, .ndo_start_xmit = vxge_xmit, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = vxge_set_multicast, diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h index 2e3b064b8e4ba0322772f5487a6524e28a9f0665..d4be07eaacd72d007faa4cfdeba4dc61bf645ee8 100644 --- a/drivers/net/vxge/vxge-main.h +++ b/drivers/net/vxge/vxge-main.h @@ -172,7 +172,6 @@ struct vxge_msix_entry { struct vxge_sw_stats { /* Network Stats (interface stats) */ - struct net_device_stats net_stats; /* Tx */ u64 tx_frms; diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 0bd898c947594fbdef1affaccbd86734f80aacc8..4ac85a09c5a6724785435dbf640ec4450afe5f24 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -264,7 +264,7 @@ static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) new_line.clock_type != CLOCK_TXFROMRX && new_line.clock_type != CLOCK_INT && new_line.clock_type != CLOCK_TXINT) - return -EINVAL; /* No such clock setting */ + return -EINVAL; /* No such clock setting */ if (new_line.loopback != 0 && new_line.loopback != 1) return -EINVAL; diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c index a5ddc6c8963e3e189f65e8213e0110b9941841e6..164c3624ba895c0720a6604638a7983947a242af 100644 --- a/drivers/net/wan/cycx_drv.c +++ b/drivers/net/wan/cycx_drv.c @@ -73,7 +73,7 @@ static int reset_cyc2x(void __iomem *addr); static int detect_cyc2x(void __iomem *addr); /* Miscellaneous functions */ -static int get_option_index(long *optlist, long optval); +static int get_option_index(const long *optlist, long optval); static u16 checksum(u8 *buf, u32 len); #define wait_cyc(addr) cycx_exec(addr + CMD_OFFSET) @@ -81,23 +81,23 @@ static u16 checksum(u8 *buf, u32 len); /* Global Data */ /* private data */ -static char modname[] = "cycx_drv"; -static char fullname[] = "Cyclom 2X Support Module"; -static char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " +static const char modname[] = "cycx_drv"; +static const char fullname[] = "Cyclom 2X Support Module"; +static const char copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " ""; /* Hardware configuration options. * These are arrays of configuration options used by verification routines. * The first element of each array is its size (i.e. number of options). */ -static long cyc2x_dpmbase_options[] = { +static const long cyc2x_dpmbase_options[] = { 20, 0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, 0xB8000, 0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, 0xD0000, 0xD4000, 0xD8000, 0xDC000, 0xE0000, 0xE4000, 0xE8000, 0xEC000 }; -static long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 }; +static const long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 }; /* Kernel Loadable Module Entry Points */ /* Module 'insert' entry point. @@ -529,7 +529,7 @@ static int detect_cyc2x(void __iomem *addr) /* Miscellaneous */ /* Get option's index into the options list. * Return option's index (1 .. N) or zero if option is invalid. */ -static int get_option_index(long *optlist, long optval) +static int get_option_index(const long *optlist, long optval) { int i = 1; diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c index a0e8611ad8e81e167ac5cf566f82ab7dcf1eeb84..859dba9b972ea883da8a91b7fef0cb0d9d5ded35 100644 --- a/drivers/net/wan/cycx_main.c +++ b/drivers/net/wan/cycx_main.c @@ -81,9 +81,9 @@ static irqreturn_t cycx_isr(int irq, void *dev_id); */ /* private data */ -static char cycx_drvname[] = "cyclomx"; -static char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver"; -static char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " +static const char cycx_drvname[] = "cyclomx"; +static const char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver"; +static const char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo " ""; static int cycx_ncards = CONFIG_CYCX_CARDS; static struct cycx_device *cycx_card_array; /* adapter data space */ diff --git a/drivers/net/wan/dlci.c b/drivers/net/wan/dlci.c index 421d0715310e2a859b13ec17c21f07f6131086ff..1481a446fefbf6f058c14b6591501b3249ae2d8b 100644 --- a/drivers/net/wan/dlci.c +++ b/drivers/net/wan/dlci.c @@ -97,11 +97,11 @@ static int dlci_header(struct sk_buff *skb, struct net_device *dev, dest = skb_push(skb, hlen); if (!dest) - return(0); + return 0; memcpy(dest, &hdr, hlen); - return(hlen); + return hlen; } static void dlci_receive(struct sk_buff *skb, struct net_device *dev) @@ -211,14 +211,14 @@ static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, in if (copy_from_user(&config, conf, sizeof(struct dlci_conf))) return -EFAULT; if (config.flags & ~DLCI_VALID_FLAGS) - return(-EINVAL); + return -EINVAL; memcpy(&dlp->config, &config, sizeof(struct dlci_conf)); dlp->configured = 1; } err = (*flp->dlci_conf)(dlp->slave, dev, get); if (err) - return(err); + return err; if (get) { @@ -226,7 +226,7 @@ static int dlci_config(struct net_device *dev, struct dlci_conf __user *conf, in return -EFAULT; } - return(0); + return 0; } static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -234,7 +234,7 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) struct dlci_local *dlp; if (!capable(CAP_NET_ADMIN)) - return(-EPERM); + return -EPERM; dlp = netdev_priv(dev); @@ -242,7 +242,7 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { case DLCI_GET_SLAVE: if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; strncpy(ifr->ifr_slave, dlp->slave->name, sizeof(ifr->ifr_slave)); break; @@ -250,15 +250,15 @@ static int dlci_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) case DLCI_GET_CONF: case DLCI_SET_CONF: if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; - return(dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF)); + return dlci_config(dev, ifr->ifr_data, cmd == DLCI_GET_CONF); break; default: - return(-EOPNOTSUPP); + return -EOPNOTSUPP; } - return(0); + return 0; } static int dlci_change_mtu(struct net_device *dev, int new_mtu) @@ -277,15 +277,15 @@ static int dlci_open(struct net_device *dev) dlp = netdev_priv(dev); if (!*(short *)(dev->dev_addr)) - return(-EINVAL); + return -EINVAL; if (!netif_running(dlp->slave)) - return(-ENOTCONN); + return -ENOTCONN; flp = netdev_priv(dlp->slave); err = (*flp->activate)(dlp->slave, dev); if (err) - return(err); + return err; netif_start_queue(dev); @@ -365,14 +365,14 @@ static int dlci_add(struct dlci_add *dlci) list_add(&dlp->list, &dlci_devs); rtnl_unlock(); - return(0); + return 0; err2: rtnl_unlock(); free_netdev(master); err1: dev_put(slave); - return(err); + return err; } static int dlci_del(struct dlci_add *dlci) @@ -385,10 +385,10 @@ static int dlci_del(struct dlci_add *dlci) /* validate slave device */ master = __dev_get_by_name(&init_net, dlci->devname); if (!master) - return(-ENODEV); + return -ENODEV; if (netif_running(master)) { - return(-EBUSY); + return -EBUSY; } dlp = netdev_priv(master); @@ -406,7 +406,7 @@ static int dlci_del(struct dlci_add *dlci) } rtnl_unlock(); - return(err); + return err; } static int dlci_ioctl(unsigned int cmd, void __user *arg) @@ -415,7 +415,7 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg) int err; if (!capable(CAP_NET_ADMIN)) - return(-EPERM); + return -EPERM; if (copy_from_user(&add, arg, sizeof(struct dlci_add))) return -EFAULT; @@ -438,7 +438,7 @@ static int dlci_ioctl(unsigned int cmd, void __user *arg) err = -EINVAL; } - return(err); + return err; } static const struct header_ops dlci_header_ops = { diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index b38ffa149aba218200c64194ae0a1a597dfc9113..b1e5e5b69c2a3370e88aadee23b7840566005d44 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -191,7 +191,8 @@ static int cisco_rx(struct sk_buff *skb) switch (ntohl (cisco_data->type)) { case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ - in_dev = dev->ip_ptr; + rcu_read_lock(); + in_dev = __in_dev_get_rcu(dev); addr = 0; mask = ~cpu_to_be32(0); /* is the mask correct? */ @@ -211,6 +212,7 @@ static int cisco_rx(struct sk_buff *skb) cisco_keepalive_send(dev, CISCO_ADDR_REPLY, addr, mask); } + rcu_read_unlock(); dev_kfree_skb_any(skb); return NET_RX_SUCCESS; diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 4d4dc38c72902e9ca62e8b7655cb9b70388a1a17..7f5bb913c8b928ad20b8aa9bb8a0b84b5adcbbab 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -46,7 +46,7 @@ #include -static char bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; +static const u8 bcast_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; /* If this number is made larger, check that the temporary string buffer * in lapbeth_new_device is large enough to store the probe device name.*/ diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index e2c6f7f4f51c16a36bea5d11daff068200ed125d..70feb84df6701267211180e2f9763f9c35ec7dd5 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -1022,7 +1022,7 @@ static int lmc_open(struct net_device *dev) if (sc->lmc_ok){ lmc_trace(dev, "lmc_open lmc_ok out"); - return (0); + return 0; } lmc_softreset (sc); @@ -1105,12 +1105,12 @@ static int lmc_open(struct net_device *dev) init_timer (&sc->timer); sc->timer.expires = jiffies + HZ; sc->timer.data = (unsigned long) dev; - sc->timer.function = &lmc_watchdog; + sc->timer.function = lmc_watchdog; add_timer (&sc->timer); lmc_trace(dev, "lmc_open out"); - return (0); + return 0; } /* Total reset to compensate for the AdTran DSU doing bad things diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index 5394b51bdb2f768f36d3d4ac705d46abc23b7187..17d408fe693f6233437d1016bae2d294f80a380b 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -282,7 +282,7 @@ static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) new_line.clock_type != CLOCK_TXFROMRX && new_line.clock_type != CLOCK_INT && new_line.clock_type != CLOCK_TXINT) - return -EINVAL; /* No such clock setting */ + return -EINVAL; /* No such clock setting */ if (new_line.loopback != 0 && new_line.loopback != 1) return -EINVAL; @@ -379,14 +379,14 @@ static int __init n2_run(unsigned long io, unsigned long irq, if (request_irq(irq, sca_intr, 0, devname, card)) { printk(KERN_ERR "n2: could not allocate IRQ\n"); n2_destroy_card(card); - return(-EBUSY); + return -EBUSY; } card->irq = irq; if (!request_mem_region(winbase, USE_WINDOWSIZE, devname)) { printk(KERN_ERR "n2: could not request RAM window\n"); n2_destroy_card(card); - return(-EBUSY); + return -EBUSY; } card->phy_winbase = winbase; card->winbase = ioremap(winbase, USE_WINDOWSIZE); diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c index c6aa66e5b52f34aedd5736e3c7e8c967870c24d2..f875cfae309337a5d34c28b725332440b18e0911 100644 --- a/drivers/net/wan/pc300_drv.c +++ b/drivers/net/wan/pc300_drv.c @@ -1,5 +1,5 @@ #define USE_PCI_CLOCK -static char rcsid[] = +static const char rcsid[] = "Revision: 3.4.5 Date: 2002/03/07 "; /* @@ -451,11 +451,11 @@ static int dma_get_rx_frame_size(pc300_t * card, int ch) if ((status & DST_EOM) || (first_bd == card->chan[ch].rx_last_bd)) { /* Return the size of a good frame or incomplete bad frame * (dma_buf_read will clean the buffer descriptors in this case). */ - return (rcvd); + return rcvd; } ptdescr = (card->hw.rambase + cpc_readl(&ptdescr->next)); } - return (-1); + return -1; } /* @@ -557,7 +557,7 @@ static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb) cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch), RX_BD_ADDR(ch, chan->rx_last_bd)); } - return (rcvd); + return rcvd; } static void tx_dma_stop(pc300_t * card, int ch) @@ -1733,7 +1733,7 @@ static u16 falc_pattern_test_error(pc300_t * card, int ch) pc300ch_t *chan = (pc300ch_t *) & card->chan[ch]; falc_t *pfalc = (falc_t *) & chan->falc; - return (pfalc->bec); + return pfalc->bec; } /**********************************/ @@ -2819,7 +2819,7 @@ static int clock_rate_calc(u32 rate, u32 clock, int *br_io) *br_io = 0; if (rate == 0) - return (0); + return 0; for (br = 0, br_pwr = 1; br <= 9; br++, br_pwr <<= 1) { if ((tc = clock / br_pwr / rate) <= 0xff) { @@ -2832,11 +2832,11 @@ static int clock_rate_calc(u32 rate, u32 clock, int *br_io) error = ((rate - (clock / br_pwr / rate)) / rate) * 1000; /* Errors bigger than +/- 1% won't be tolerated */ if (error < -10 || error > 10) - return (-1); + return -1; else - return (tc); + return tc; } else { - return (-1); + return -1; } } @@ -3207,7 +3207,7 @@ static u32 detect_ram(pc300_t * card) break; } } - return (i); + return i; } static void plx_init(pc300_t * card) diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 4293889e287e7ff28a00020d7279c67b596a9d2a..515d9b8af01e6e8c409a4fcd9e6488918d8a4981 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -540,7 +540,7 @@ static int cpc_tty_chars_in_buffer(struct tty_struct *tty) return -ENODEV; } - return(0); + return 0; } static int pc300_tiocmset(struct tty_struct *tty, struct file *file, diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index e2cff64a446a1bb102cabdcb263b260c2b59ecc3..fd7375955e41f07d583becc71be10c437e153c0a 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -220,7 +220,7 @@ static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) new_line.clock_type != CLOCK_TXFROMRX && new_line.clock_type != CLOCK_INT && new_line.clock_type != CLOCK_TXINT) - return -EINVAL; /* No such clock setting */ + return -EINVAL; /* No such clock setting */ if (new_line.loopback != 0 && new_line.loopback != 1) return -EINVAL; diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index f4125da2762fe9c395dcf479a91303a8c6892bbd..3f4e2b5684db29a2a11069b87d9f38c5371061f9 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -178,7 +178,7 @@ static char sdla_byte(struct net_device *dev, int addr) byte = *temp; spin_unlock_irqrestore(&sdla_lock, flags); - return(byte); + return byte; } static void sdla_stop(struct net_device *dev) @@ -267,7 +267,7 @@ static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char r resp = *temp; } } - return(time_before(jiffies, done) ? jiffies - start : -1); + return time_before(jiffies, done) ? jiffies - start : -1; } /* constants for Z80 CPU speed */ @@ -283,13 +283,13 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) sdla_start(dev); if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0) - return(-EIO); + return -EIO; data = LOADER_READY; sdla_write(dev, 0, &data, 1); if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0) - return(-EIO); + return -EIO; sdla_stop(dev); sdla_read(dev, 0, &data, 1); @@ -297,11 +297,11 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) if (data == Z80_SCC_BAD) { printk("%s: SCC bad\n", dev->name); - return(-EIO); + return -EIO; } if (data != Z80_SCC_OK) - return(-EINVAL); + return -EINVAL; if (jiffs < 165) ifr->ifr_mtu = SDLA_CPU_16M; @@ -316,7 +316,7 @@ static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr) else ifr->ifr_mtu = SDLA_CPU_3M; - return(0); + return 0; } /************************************************ @@ -493,7 +493,7 @@ static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, if (ret != SDLA_RET_OK) sdla_errors(dev, cmd, dlci, ret, len, &status); - return(ret); + return ret; } /*********************************************** @@ -516,14 +516,14 @@ static int sdla_activate(struct net_device *slave, struct net_device *master) break; if (i == CONFIG_DLCI_MAX) - return(-ENODEV); + return -ENODEV; flp->dlci[i] = abs(flp->dlci[i]); if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE)) sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); - return(0); + return 0; } static int sdla_deactivate(struct net_device *slave, struct net_device *master) @@ -538,14 +538,14 @@ static int sdla_deactivate(struct net_device *slave, struct net_device *master) break; if (i == CONFIG_DLCI_MAX) - return(-ENODEV); + return -ENODEV; flp->dlci[i] = -abs(flp->dlci[i]); if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE)) sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL); - return(0); + return 0; } static int sdla_assoc(struct net_device *slave, struct net_device *master) @@ -554,7 +554,7 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master) int i; if (master->type != ARPHRD_DLCI) - return(-EINVAL); + return -EINVAL; flp = netdev_priv(slave); @@ -563,11 +563,11 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master) if (!flp->master[i]) break; if (abs(flp->dlci[i]) == *(short *)(master->dev_addr)) - return(-EADDRINUSE); + return -EADDRINUSE; } if (i == CONFIG_DLCI_MAX) - return(-EMLINK); /* #### Alan: Comments on this ?? */ + return -EMLINK; /* #### Alan: Comments on this ?? */ flp->master[i] = master; @@ -581,7 +581,7 @@ static int sdla_assoc(struct net_device *slave, struct net_device *master) sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL); } - return(0); + return 0; } static int sdla_deassoc(struct net_device *slave, struct net_device *master) @@ -596,7 +596,7 @@ static int sdla_deassoc(struct net_device *slave, struct net_device *master) break; if (i == CONFIG_DLCI_MAX) - return(-ENODEV); + return -ENODEV; flp->master[i] = NULL; flp->dlci[i] = 0; @@ -609,7 +609,7 @@ static int sdla_deassoc(struct net_device *slave, struct net_device *master) sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL); } - return(0); + return 0; } static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get) @@ -626,7 +626,7 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i break; if (i == CONFIG_DLCI_MAX) - return(-ENODEV); + return -ENODEV; dlp = netdev_priv(master); @@ -641,7 +641,7 @@ static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, i &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL); } - return(ret == SDLA_RET_OK ? 0 : -EIO); + return ret == SDLA_RET_OK ? 0 : -EIO; } /************************** @@ -986,7 +986,7 @@ static int sdla_close(struct net_device *dev) netif_stop_queue(dev); - return(0); + return 0; } struct conf_data { @@ -1006,10 +1006,10 @@ static int sdla_open(struct net_device *dev) flp = netdev_priv(dev); if (!flp->initialized) - return(-EPERM); + return -EPERM; if (!flp->configured) - return(-EPERM); + return -EPERM; /* time to send in the configuration */ len = 0; @@ -1087,7 +1087,7 @@ static int sdla_open(struct net_device *dev) netif_start_queue(dev); - return(0); + return 0; } static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get) @@ -1098,48 +1098,48 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in short size; if (dev->type == 0xFFFF) - return(-EUNATCH); + return -EUNATCH; flp = netdev_priv(dev); if (!get) { if (netif_running(dev)) - return(-EBUSY); + return -EBUSY; if(copy_from_user(&data.config, conf, sizeof(struct frad_conf))) return -EFAULT; if (data.config.station & ~FRAD_STATION_NODE) - return(-EINVAL); + return -EINVAL; if (data.config.flags & ~FRAD_VALID_FLAGS) - return(-EINVAL); + return -EINVAL; if ((data.config.kbaud < 0) || ((data.config.kbaud > 128) && (flp->type != SDLA_S508))) - return(-EINVAL); + return -EINVAL; if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232)) - return(-EINVAL); + return -EINVAL; if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU)) - return(-EINVAL); + return -EINVAL; if ((data.config.T391 < 5) || (data.config.T391 > 30)) - return(-EINVAL); + return -EINVAL; if ((data.config.T392 < 5) || (data.config.T392 > 30)) - return(-EINVAL); + return -EINVAL; if ((data.config.N391 < 1) || (data.config.N391 > 255)) - return(-EINVAL); + return -EINVAL; if ((data.config.N392 < 1) || (data.config.N392 > 10)) - return(-EINVAL); + return -EINVAL; if ((data.config.N393 < 1) || (data.config.N393 > 10)) - return(-EINVAL); + return -EINVAL; memcpy(&flp->config, &data.config, sizeof(struct frad_conf)); flp->config.flags |= SDLA_DIRECT_RECV; @@ -1171,7 +1171,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in { size = sizeof(data); if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK) - return(-EIO); + return -EIO; } else if (flp->configured) @@ -1185,7 +1185,7 @@ static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, in return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0; } - return(0); + return 0; } static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read) @@ -1200,7 +1200,7 @@ static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int r { temp = kzalloc(mem.len, GFP_KERNEL); if (!temp) - return(-ENOMEM); + return -ENOMEM; sdla_read(dev, mem.addr, temp, mem.len); if(copy_to_user(mem.data, temp, mem.len)) { @@ -1217,7 +1217,7 @@ static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int r sdla_write(dev, mem.addr, temp, mem.len); kfree(temp); } - return(0); + return 0; } static int sdla_reconfig(struct net_device *dev) @@ -1241,7 +1241,7 @@ static int sdla_reconfig(struct net_device *dev) sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL); sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL); - return(0); + return 0; } static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -1254,20 +1254,20 @@ static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) flp = netdev_priv(dev); if (!flp->initialized) - return(-EINVAL); + return -EINVAL; switch (cmd) { case FRAD_GET_CONF: case FRAD_SET_CONF: - return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF)); + return sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF); case SDLA_IDENTIFY: ifr->ifr_flags = flp->type; break; case SDLA_CPUSPEED: - return(sdla_cpuspeed(dev, ifr)); + return sdla_cpuspeed(dev, ifr); /* ========================================================== NOTE: This is rather a useless action right now, as the @@ -1277,7 +1277,7 @@ NOTE: This is rather a useless action right now, as the ============================================================*/ case SDLA_PROTOCOL: if (flp->configured) - return(-EALREADY); + return -EALREADY; switch (ifr->ifr_flags) { @@ -1285,7 +1285,7 @@ NOTE: This is rather a useless action right now, as the dev->type = ifr->ifr_flags; break; default: - return(-ENOPROTOOPT); + return -ENOPROTOOPT; } break; @@ -1297,7 +1297,7 @@ NOTE: This is rather a useless action right now, as the case SDLA_READMEM: if(!capable(CAP_SYS_RAWIO)) return -EPERM; - return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM)); + return sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM); case SDLA_START: sdla_start(dev); @@ -1308,9 +1308,9 @@ NOTE: This is rather a useless action right now, as the break; default: - return(-EOPNOTSUPP); + return -EOPNOTSUPP; } - return(0); + return 0; } static int sdla_change_mtu(struct net_device *dev, int new_mtu) @@ -1320,10 +1320,10 @@ static int sdla_change_mtu(struct net_device *dev, int new_mtu) flp = netdev_priv(dev); if (netif_running(dev)) - return(-EBUSY); + return -EBUSY; /* for now, you can't change the MTU! */ - return(-EOPNOTSUPP); + return -EOPNOTSUPP; } static int sdla_set_config(struct net_device *dev, struct ifmap *map) @@ -1337,18 +1337,18 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map) flp = netdev_priv(dev); if (flp->initialized) - return(-EINVAL); + return -EINVAL; for(i=0; i < ARRAY_SIZE(valid_port); i++) if (valid_port[i] == map->base_addr) break; if (i == ARRAY_SIZE(valid_port)) - return(-EINVAL); + return -EINVAL; if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){ printk(KERN_WARNING "SDLA: io-port 0x%04lx in use\n", dev->base_addr); - return(-EINVAL); + return -EINVAL; } base = map->base_addr; diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index e47f5a986b1c213c7f14e43b38dda541504c8b7d..d81ad83978855ac4929a93f082139afd63f8cc41 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -648,7 +648,7 @@ static int x25_asy_esc(unsigned char *s, unsigned char *d, int len) } } *ptr++ = X25_END; - return (ptr - d); + return ptr - d; } static void x25_asy_unesc(struct x25_asy *sl, unsigned char s) diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c index fbf5e843d48c1fd9f88b55ef993ea74474488041..93956861ea210eb08d773461827a172b7493294f 100644 --- a/drivers/net/wan/z85230.c +++ b/drivers/net/wan/z85230.c @@ -766,7 +766,7 @@ irqreturn_t z8530_interrupt(int irq, void *dev_id) EXPORT_SYMBOL(z8530_interrupt); -static char reg_init[16]= +static const u8 reg_init[16]= { 0,0,0,0, 0,0,0,0, @@ -1206,7 +1206,7 @@ EXPORT_SYMBOL(z8530_sync_txdma_close); * it exists... */ -static char *z8530_type_name[]={ +static const char *z8530_type_name[]={ "Z8530", "Z85C30", "Z85230" diff --git a/drivers/net/wd.c b/drivers/net/wd.c index eb72c67699abb50f30e8b8bf7d30b43c52b73daa..f1549fff0edc981662addc0a486cfd1b069c3e5f 100644 --- a/drivers/net/wd.c +++ b/drivers/net/wd.c @@ -342,10 +342,10 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr) printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n", model_name, dev->irq, dev->mem_start, dev->mem_end-1); - ei_status.reset_8390 = &wd_reset_8390; - ei_status.block_input = &wd_block_input; - ei_status.block_output = &wd_block_output; - ei_status.get_8390_hdr = &wd_get_8390_hdr; + ei_status.reset_8390 = wd_reset_8390; + ei_status.block_input = wd_block_input; + ei_status.block_output = wd_block_output; + ei_status.get_8390_hdr = wd_get_8390_hdr; dev->netdev_ops = &wd_netdev_ops; NS8390_init(dev, 0); diff --git a/drivers/net/wimax/i2400m/control.c b/drivers/net/wimax/i2400m/control.c index 9fb03082153a2ea8a409ccbae96d3b5d242c4445..12b84ed0e38a3f87800e789c65523ca28d617440 100644 --- a/drivers/net/wimax/i2400m/control.c +++ b/drivers/net/wimax/i2400m/control.c @@ -98,7 +98,7 @@ MODULE_PARM_DESC(power_save_disabled, "False by default (so the device is told to do power " "saving)."); -int i2400m_passive_mode; /* 0 (passive mode disabled) by default */ +static int i2400m_passive_mode; /* 0 (passive mode disabled) by default */ module_param_named(passive_mode, i2400m_passive_mode, int, 0644); MODULE_PARM_DESC(passive_mode, "If true, the driver will not do any device setup " @@ -558,8 +558,9 @@ void i2400m_report_hook(struct i2400m *i2400m, * processing should be done in the function that calls the * command. This is here for some cases where it can't happen... */ -void i2400m_msg_ack_hook(struct i2400m *i2400m, - const struct i2400m_l3l4_hdr *l3l4_hdr, size_t size) +static void i2400m_msg_ack_hook(struct i2400m *i2400m, + const struct i2400m_l3l4_hdr *l3l4_hdr, + size_t size) { int result; struct device *dev = i2400m_dev(i2400m); @@ -1135,7 +1136,7 @@ int i2400m_cmd_exit_idle(struct i2400m *i2400m) * i2400m_report_state_hook() to parse the answer. This will set the * carrier state, as well as the RF Kill switches state. */ -int i2400m_cmd_get_state(struct i2400m *i2400m) +static int i2400m_cmd_get_state(struct i2400m *i2400m) { int result; struct device *dev = i2400m_dev(i2400m); @@ -1177,8 +1178,6 @@ int i2400m_cmd_get_state(struct i2400m *i2400m) error_alloc: return result; } -EXPORT_SYMBOL_GPL(i2400m_cmd_get_state); - /** * Set basic configuration settings @@ -1190,8 +1189,9 @@ EXPORT_SYMBOL_GPL(i2400m_cmd_get_state); * right endianess (LE). * @arg_size: number of pointers in the @args array */ -int i2400m_set_init_config(struct i2400m *i2400m, - const struct i2400m_tlv_hdr **arg, size_t args) +static int i2400m_set_init_config(struct i2400m *i2400m, + const struct i2400m_tlv_hdr **arg, + size_t args) { int result; struct device *dev = i2400m_dev(i2400m); @@ -1258,8 +1258,6 @@ int i2400m_set_init_config(struct i2400m *i2400m, return result; } -EXPORT_SYMBOL_GPL(i2400m_set_init_config); - /** * i2400m_set_idle_timeout - Set the device's idle mode timeout diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index 9c8b78d4abd2f2b416c15cf3511f3bcdc11ca25e..cdedab46ba2160390a06d25a9cbd8241494e9670 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c @@ -122,7 +122,7 @@ struct i2400m_work *__i2400m_work_setup( * works struct was already queued, but we have just allocated it, so * it should not happen. */ -int i2400m_schedule_work(struct i2400m *i2400m, +static int i2400m_schedule_work(struct i2400m *i2400m, void (*fn)(struct work_struct *), gfp_t gfp_flags, const void *pl, size_t pl_size) { diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h index 360d4fb195f475aff73e9880d64bc1c212c0fb9f..1d63ffdedfde6b89fc63515c10c2c1974ff6b056 100644 --- a/drivers/net/wimax/i2400m/i2400m-sdio.h +++ b/drivers/net/wimax/i2400m/i2400m-sdio.h @@ -140,7 +140,6 @@ void i2400ms_init(struct i2400ms *i2400ms) extern int i2400ms_rx_setup(struct i2400ms *); extern void i2400ms_rx_release(struct i2400ms *); -extern ssize_t __i2400ms_rx_get_size(struct i2400ms *); extern int i2400ms_tx_setup(struct i2400ms *); extern void i2400ms_tx_release(struct i2400ms *); diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index fa74777fd65f6cc79e9d59dbe679373a886ed91e..59ac7705e76ed682a72b3296eb127e6d1e888df4 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -910,28 +910,19 @@ struct i2400m_work { u8 pl[0]; }; -extern int i2400m_schedule_work(struct i2400m *, - void (*)(struct work_struct *), gfp_t, - const void *, size_t); - extern int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *, char *, size_t); extern int i2400m_msg_size_check(struct i2400m *, const struct i2400m_l3l4_hdr *, size_t); extern struct sk_buff *i2400m_msg_to_dev(struct i2400m *, const void *, size_t); extern void i2400m_msg_to_dev_cancel_wait(struct i2400m *, int); -extern void i2400m_msg_ack_hook(struct i2400m *, - const struct i2400m_l3l4_hdr *, size_t); extern void i2400m_report_hook(struct i2400m *, const struct i2400m_l3l4_hdr *, size_t); extern void i2400m_report_hook_work(struct work_struct *); extern int i2400m_cmd_enter_powersave(struct i2400m *); -extern int i2400m_cmd_get_state(struct i2400m *); extern int i2400m_cmd_exit_idle(struct i2400m *); extern struct sk_buff *i2400m_get_device_info(struct i2400m *); extern int i2400m_firmware_check(struct i2400m *); -extern int i2400m_set_init_config(struct i2400m *, - const struct i2400m_tlv_hdr **, size_t); extern int i2400m_set_idle_timeout(struct i2400m *, unsigned); static inline diff --git a/drivers/net/wimax/i2400m/rx.c b/drivers/net/wimax/i2400m/rx.c index 1737d1488b35704f3196975a76bcc919e943808b..844133b44af04eb8b36436c8c7147e8c995685a4 100644 --- a/drivers/net/wimax/i2400m/rx.c +++ b/drivers/net/wimax/i2400m/rx.c @@ -922,7 +922,7 @@ void i2400m_roq_queue_update_ws(struct i2400m *i2400m, struct i2400m_roq *roq, * rx_roq_refcount becomes zero. This routine gets executed when * rx_roq_refcount becomes zero. */ -void i2400m_rx_roq_destroy(struct kref *ref) +static void i2400m_rx_roq_destroy(struct kref *ref) { unsigned itr; struct i2400m *i2400m diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c index 8b809c2ead6c928ce1d0a5143ae3e0d53756c73e..fb6396dd115f859a94ebf777e0d3115444977532 100644 --- a/drivers/net/wimax/i2400m/sdio-rx.c +++ b/drivers/net/wimax/i2400m/sdio-rx.c @@ -87,7 +87,7 @@ static const __le32 i2400m_ACK_BARKER[4] = { * * sdio_readl() doesn't work. */ -ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms) +static ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms) { int ret, cnt, val; ssize_t rx_size; diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 174e3442d5190df936544854787b919d3e0f4945..4de4410cd38ed7fd34e5d74adc5bba8b77ba3f23 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -279,6 +279,7 @@ source "drivers/net/wireless/libertas/Kconfig" source "drivers/net/wireless/orinoco/Kconfig" source "drivers/net/wireless/p54/Kconfig" source "drivers/net/wireless/rt2x00/Kconfig" +source "drivers/net/wireless/wl1251/Kconfig" source "drivers/net/wireless/wl12xx/Kconfig" source "drivers/net/wireless/zd1211rw/Kconfig" diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 5d4ce4d2b32bd9a71a63a1b6c25606f647b3d0bc..06f8ca26c5c17d9006b1ef8bdba3b59e50e1931d 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -49,6 +49,8 @@ obj-$(CONFIG_ATH_COMMON) += ath/ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o +obj-$(CONFIG_WL1251) += wl1251/ obj-$(CONFIG_WL12XX) += wl12xx/ +obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/ obj-$(CONFIG_IWM) += iwmc3200wifi/ diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index ce77575e88b3182b0ad06592ba391488d5ca228f..a36e7870b03eeefe86347fa1bacb4e7118c8b4c0 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -105,7 +105,7 @@ static struct pci_driver airo_driver = { of statistics in the /proc filesystem */ #define IGNLABEL(comment) NULL -static char *statsLabels[] = { +static const char *statsLabels[] = { "RxOverrun", IGNLABEL("RxPlcpCrcErr"), IGNLABEL("RxPlcpFormatErr"), @@ -217,7 +217,6 @@ static char *statsLabels[] = { (no spaces) list of rates (up to 8). */ static int rates[8]; -static int basic_rate; static char *ssids[3]; static int io[4]; @@ -250,7 +249,6 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350"); module_param_array(io, int, NULL, 0); module_param_array(irq, int, NULL, 0); -module_param(basic_rate, int, 0); module_param_array(rates, int, NULL, 0); module_param_array(ssids, charp, NULL, 0); module_param(auto_wep, int, 0); @@ -932,7 +930,7 @@ typedef struct aironet_ioctl { unsigned char __user *data; // d-data } aironet_ioctl; -static char swversion[] = "2.1"; +static const char swversion[] = "2.1"; #endif /* CISCO_EXT */ #define NUM_MODULES 2 @@ -1374,7 +1372,7 @@ static int micsetup(struct airo_info *ai) { return SUCCESS; } -static char micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; +static const u8 micsnap[] = {0xAA,0xAA,0x03,0x00,0x40,0x96,0x00,0x02}; /*=========================================================================== * Description: Mic a packet @@ -2723,9 +2721,8 @@ static int airo_networks_allocate(struct airo_info *ai) if (ai->networks) return 0; - ai->networks = - kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement), - GFP_KERNEL); + ai->networks = kcalloc(AIRO_MAX_NETWORK_COUNT, sizeof(BSSListElement), + GFP_KERNEL); if (!ai->networks) { airo_print_warn("", "Out of memory allocating beacons"); return -ENOMEM; @@ -3884,15 +3881,6 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) ai->config.rates[i] = rates[i]; } } - if ( basic_rate > 0 ) { - for( i = 0; i < 8; i++ ) { - if ( ai->config.rates[i] == basic_rate || - !ai->config.rates ) { - ai->config.rates[i] = basic_rate | 0x80; - break; - } - } - } set_bit (FLAG_COMMIT, &ai->flags); } @@ -5032,7 +5020,7 @@ static void proc_config_on_close(struct inode *inode, struct file *file) airo_config_commit(dev, NULL, NULL, NULL); } -static char *get_rmode(__le16 mode) +static const char *get_rmode(__le16 mode) { switch(mode & RXMODE_MASK) { case RXMODE_RFMON: return "rfmon"; diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 1128fa8c9ed5ef3d0b9be5191edc4bd7320baf90..1476314afa8a5dfb2811d4805d36c3eef2602d5b 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c @@ -1525,8 +1525,7 @@ static void at76_rx_tasklet(unsigned long param) if (priv->device_unplugged) { at76_dbg(DBG_DEVSTART, "device unplugged"); - if (urb) - at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); + at76_dbg(DBG_DEVSTART, "urb status %d", urb->status); return; } @@ -2061,11 +2060,12 @@ static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, int i; - at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d " + at76_dbg(DBG_MAC80211, "%s(): cmd %d key->cipher %d key->keyidx %d " "key->keylen %d", - __func__, cmd, key->alg, key->keyidx, key->keylen); + __func__, cmd, key->cipher, key->keyidx, key->keylen); - if (key->alg != ALG_WEP) + if ((key->cipher != WLAN_CIPHER_SUITE_WEP40) && + (key->cipher != WLAN_CIPHER_SUITE_WEP104)) return -EOPNOTSUPP; key->hw_key_idx = key->keyidx; diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 0a75be027afaa5c7604cfc257093979a636653ab..92c216263ee9d7304745f934c82e14dc3059f21b 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -25,5 +25,6 @@ config ATH_DEBUG source "drivers/net/wireless/ath/ath5k/Kconfig" source "drivers/net/wireless/ath/ath9k/Kconfig" source "drivers/net/wireless/ath/ar9170/Kconfig" +source "drivers/net/wireless/ath/carl9170/Kconfig" endif diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index 8113a5042afac6e99904ab668b6a4491f901a363..6d711ec97ec2fd48f3f69d31b441dffc545821c4 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -1,11 +1,13 @@ obj-$(CONFIG_ATH5K) += ath5k/ obj-$(CONFIG_ATH9K_HW) += ath9k/ obj-$(CONFIG_AR9170_USB) += ar9170/ +obj-$(CONFIG_CARL9170) += carl9170/ obj-$(CONFIG_ATH_COMMON) += ath.o ath-objs := main.o \ regd.o \ - hw.o + hw.o \ + key.o ath-$(CONFIG_ATH_DEBUG) += debug.o diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index debfb0fbc7c5e7316931b2e0ac0c4913ff7428d6..32bf79e6a320ff2b04722b8a17d9cd7b38088303 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c @@ -1190,14 +1190,13 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) if (info->control.hw_key) { icv = info->control.hw_key->icv_len; - switch (info->control.hw_key->alg) { - case ALG_WEP: + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: keytype = AR9170_TX_MAC_ENCR_RC4; break; - case ALG_TKIP: - keytype = AR9170_TX_MAC_ENCR_RC4; - break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: keytype = AR9170_TX_MAC_ENCR_AES; break; default: @@ -1778,17 +1777,17 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if ((!ar->vif) || (ar->disable_offload)) return -EOPNOTSUPP; - switch (key->alg) { - case ALG_WEP: - if (key->keylen == WLAN_KEY_LEN_WEP40) - ktype = AR9170_ENC_ALG_WEP64; - else - ktype = AR9170_ENC_ALG_WEP128; + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + ktype = AR9170_ENC_ALG_WEP64; + break; + case WLAN_CIPHER_SUITE_WEP104: + ktype = AR9170_ENC_ALG_WEP128; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: ktype = AR9170_ENC_ALG_TKIP; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: ktype = AR9170_ENC_ALG_AESCCMP; break; default: @@ -1827,7 +1826,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (err) goto out; - if (key->alg == ALG_TKIP) { + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 1, key->key + 16, 16); if (err) @@ -1864,7 +1863,7 @@ static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (err) goto out; - if (key->alg == ALG_TKIP) { + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { err = ar9170_upload_key(ar, key->hw_key_idx, NULL, AR9170_ENC_ALG_NONE, 1, diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index a93dc18a45c3fc9e0911197f7292948518741927..5dbb5361fd516808fccc79bc9c2dbd2fc22c5963 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -54,8 +54,6 @@ MODULE_AUTHOR("Christian Lamparter "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); MODULE_FIRMWARE("ar9170.fw"); -MODULE_FIRMWARE("ar9170-1.fw"); -MODULE_FIRMWARE("ar9170-2.fw"); enum ar9170_requirements { AR9170_REQ_FW1_ONLY = 1, diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index d32f2828b098ee63241e3b1e83c82d96ab2944df..501050c0296f10a3e7ea6abb4a45170fffa2b095 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -19,6 +19,7 @@ #include #include +#include #include /* @@ -35,7 +36,6 @@ static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; struct ath_ani { bool caldone; - int16_t noise_floor; unsigned int longcal_timer; unsigned int shortcal_timer; unsigned int resetcal_timer; @@ -43,6 +43,13 @@ struct ath_ani { struct timer_list timer; }; +struct ath_cycle_counters { + u32 cycles; + u32 rx_busy; + u32 rx_frame; + u32 tx_frame; +}; + enum ath_device_state { ATH_HW_UNAVAILABLE, ATH_HW_INITIALIZED, @@ -71,20 +78,44 @@ struct ath_regulatory { struct reg_dmn_pair_mapping *regpair; }; +enum ath_crypt_caps { + ATH_CRYPT_CAP_CIPHER_AESCCM = BIT(0), + ATH_CRYPT_CAP_MIC_COMBINED = BIT(1), +}; + +struct ath_keyval { + u8 kv_type; + u8 kv_pad; + u16 kv_len; + u8 kv_val[16]; /* TK */ + u8 kv_mic[8]; /* Michael MIC key */ + u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware + * supports both MIC keys in the same key cache entry; + * in that case, kv_mic is the RX key) */ +}; + +enum ath_cipher { + ATH_CIPHER_WEP = 0, + ATH_CIPHER_AES_OCB = 1, + ATH_CIPHER_AES_CCM = 2, + ATH_CIPHER_CKIP = 3, + ATH_CIPHER_TKIP = 4, + ATH_CIPHER_CLR = 5, + ATH_CIPHER_MIC = 127 +}; + /** * struct ath_ops - Register read/write operations * * @read: Register read * @write: Register write * @enable_write_buffer: Enable multiple register writes - * @disable_write_buffer: Disable multiple register writes - * @write_flush: Flush buffered register writes + * @write_flush: flush buffered register writes and disable buffering */ struct ath_ops { unsigned int (*read)(void *, u32 reg_offset); void (*write)(void *, u32 val, u32 reg_offset); void (*enable_write_buffer)(void *); - void (*disable_write_buffer)(void *); void (*write_flush) (void *); }; @@ -119,7 +150,14 @@ struct ath_common { u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); - u8 splitmic; + DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); + enum ath_crypt_caps crypt_caps; + + unsigned int clockrate; + + spinlock_t cc_lock; + struct ath_cycle_counters cc_ani; + struct ath_cycle_counters cc_survey; struct ath_regulatory regulatory; const struct ath_ops *ops; @@ -131,5 +169,13 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, gfp_t gfp_mask); void ath_hw_setbssidmask(struct ath_common *common); +void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key); +int ath_key_config(struct ath_common *common, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); +bool ath_hw_keyreset(struct ath_common *common, u16 entry); +void ath_hw_cycle_counters_update(struct ath_common *common); +int32_t ath_hw_get_listen_time(struct ath_common *common); #endif /* ATH_H */ diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index 26dbe65fedb05fbc8dfe737d381b49b61bd24eaf..f1419198a479511f995b9e290b2316b0181bd677 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c @@ -355,41 +355,28 @@ ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) /** - * ath5k_hw_ani_get_listen_time() - Calculate time spent listening + * ath5k_hw_ani_get_listen_time() - Update counters and return listening time * * Return an approximation of the time spent "listening" in milliseconds (ms) - * since the last call of this function by deducting the cycles spent - * transmitting and receiving from the total cycle count. - * Save profile count values for debugging/statistics and because we might want - * to use them later. - * - * We assume no one else clears these registers! + * since the last call of this function. + * Save a snapshot of the counter values for debugging/statistics. */ static int ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) { + struct ath_common *common = ath5k_hw_common(ah); int listen; - /* freeze */ - ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC); - /* read */ - as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE); - as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR); - as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX); - as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX); - /* clear */ - ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); - ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); - ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); - ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); - /* un-freeze */ - ath5k_hw_reg_write(ah, 0, AR5K_MIBC); - - /* TODO: where does 44000 come from? (11g clock rate?) */ - listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000; - - if (as->pfc_cycles == 0 || listen < 0) - return 0; + spin_lock_bh(&common->cc_lock); + + ath_hw_cycle_counters_update(common); + memcpy(&as->last_cc, &common->cc_ani, sizeof(as->last_cc)); + + /* clears common->cc_ani */ + listen = ath_hw_get_listen_time(common); + + spin_unlock_bh(&common->cc_lock); + return listen; } @@ -552,9 +539,9 @@ ath5k_ani_mib_intr(struct ath5k_hw *ah) if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) return; - /* if one of the errors triggered, we can get a superfluous second - * interrupt, even though we have already reset the register. the - * function detects that so we can return early */ + /* If one of the errors triggered, we can get a superfluous second + * interrupt, even though we have already reset the register. The + * function detects that so we can return early. */ if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) return; diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h index 55cf26d8522c7d78c1bffe4b7dddb3bb85913317..d0a664039c877c2f4e8f064c499833a9bf0a3883 100644 --- a/drivers/net/wireless/ath/ath5k/ani.h +++ b/drivers/net/wireless/ath/ath5k/ani.h @@ -75,10 +75,7 @@ struct ath5k_ani_state { unsigned int cck_errors; /* debug/statistics only: numbers from last ANI calibration */ - unsigned int pfc_tx; - unsigned int pfc_rx; - unsigned int pfc_busy; - unsigned int pfc_cycles; + struct ath_cycle_counters last_cc; unsigned int last_listen; unsigned int last_ofdm_errors; unsigned int last_cck_errors; diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ea6362a8988de33a51d4c916c5f82c55cd576e2e..4a367cdb3eb93b93d369f56aa40f81f5d3a95f43 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h @@ -175,7 +175,7 @@ #define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0 #define AR5K_TUNE_RADAR_ALERT false #define AR5K_TUNE_MIN_TX_FIFO_THRES 1 -#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1) +#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_FRAME_LEN / 64) + 1) #define AR5K_TUNE_REGISTER_TIMEOUT 20000 /* Register for RSSI threshold has a mask of 0xff, so 255 seems to * be the max value. */ @@ -206,6 +206,8 @@ #define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ #define ATH5K_TUNE_CALIBRATION_INTERVAL_NF 60000 /* 60 sec */ +#define ATH5K_TX_COMPLETE_POLL_INT 3000 /* 3 sec */ + #define AR5K_INIT_CARR_SENSE_EN 1 /*Swap RX/TX Descriptor for big endian archs*/ @@ -256,8 +258,6 @@ (AR5K_INIT_PROG_IFS_TURBO) \ ) -/* token to use for aifs, cwmin, cwmax in MadWiFi */ -#define AR5K_TXQ_USEDEFAULT ((u32) -1) /* GENERIC CHIPSET DEFINITIONS */ @@ -343,9 +343,6 @@ struct ath5k_srev_name { #define AR5K_SREV_PHY_5413 0x61 #define AR5K_SREV_PHY_2425 0x70 -/* IEEE defs */ -#define IEEE80211_MAX_LEN 2500 - /* TODO add support to mac80211 for vendor-specific rates and modes */ /* @@ -531,9 +528,9 @@ struct ath5k_txq_info { enum ath5k_tx_queue tqi_type; enum ath5k_tx_queue_subtype tqi_subtype; u16 tqi_flags; /* Tx queue flags (see above) */ - u32 tqi_aifs; /* Arbitrated Interframe Space */ - s32 tqi_cw_min; /* Minimum Contention Window */ - s32 tqi_cw_max; /* Maximum Contention Window */ + u8 tqi_aifs; /* Arbitrated Interframe Space */ + u16 tqi_cw_min; /* Minimum Contention Window */ + u16 tqi_cw_max; /* Maximum Contention Window */ u32 tqi_cbr_period; /* Constant bit rate period */ u32 tqi_cbr_overflow_limit; u32 tqi_burst_time; @@ -1031,8 +1028,6 @@ struct ath5k_hw { bool ah_turbo; bool ah_calibration; bool ah_single_chip; - bool ah_aes_support; - bool ah_combined_mic; enum ath5k_version ah_version; enum ath5k_radio ah_radio; @@ -1046,10 +1041,6 @@ struct ath5k_hw { #define ah_modes ah_capabilities.cap_mode #define ah_ee_version ah_capabilities.cap_eeprom.ee_version - u32 ah_atim_window; - u32 ah_aifs; - u32 ah_cw_min; - u32 ah_cw_max; u32 ah_limit_tx_retries; u8 ah_coverage_class; @@ -1190,7 +1181,7 @@ extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); /* BSSID Functions */ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); -void ath5k_hw_set_associd(struct ath5k_hw *ah); +void ath5k_hw_set_bssid(struct ath5k_hw *ah); void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); /* Receive start/stop functions */ void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); @@ -1204,17 +1195,13 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); void ath5k_hw_reset_tsf(struct ath5k_hw *ah); void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); +bool ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval); /* ACK bit rate */ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); /* Clock rate related functions */ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); -unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); -/* Key table (WEP) functions */ -int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); -int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, - const struct ieee80211_key_conf *key, const u8 *mac); -int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); +void ath5k_hw_set_clockrate(struct ath5k_hw *ah); /* Queue Control Unit, DFS Control Unit Functions */ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index b32e28caeee2b6c730a48c2c91aefb7b5708be25..cd0b14a0a93abc3e0bf320c065cac21b30cc0a4d 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -118,9 +118,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) ah->ah_turbo = false; ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; ah->ah_imr = 0; - ah->ah_atim_window = 0; - ah->ah_aifs = AR5K_TUNE_AIFS; - ah->ah_cw_min = AR5K_TUNE_CWMIN; ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; ah->ah_software_retry = false; ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; @@ -139,12 +136,12 @@ int ath5k_hw_attach(struct ath5k_softc *sc) else ah->ah_version = AR5K_AR5212; - /*Fill the ath5k_hw struct with the needed functions*/ + /* Fill the ath5k_hw struct with the needed functions */ ret = ath5k_hw_init_desc_functions(ah); if (ret) goto err_free; - /* Bring device out of sleep and reset it's units */ + /* Bring device out of sleep and reset its units */ ret = ath5k_hw_nic_wakeup(ah, 0, true); if (ret) goto err_free; @@ -158,7 +155,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) CHANNEL_5GHZ); ah->ah_phy = AR5K_PHY(0); - /* Try to identify radio chip based on it's srev */ + /* Try to identify radio chip based on its srev */ switch (ah->ah_radio_5ghz_revision & 0xf0) { case AR5K_SREV_RAD_5111: ah->ah_radio = AR5K_RF5111; @@ -314,12 +311,16 @@ int ath5k_hw_attach(struct ath5k_softc *sc) } /* Crypto settings */ - ah->ah_aes_support = srev >= AR5K_SREV_AR5212_V4 && - (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && - !AR5K_EEPROM_AES_DIS(ee->ee_misc5)); + common->keymax = (sc->ah->ah_version == AR5K_AR5210 ? + AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211); + + if (srev >= AR5K_SREV_AR5212_V4 && + (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 && + !AR5K_EEPROM_AES_DIS(ee->ee_misc5))) + common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; if (srev >= AR5K_SREV_AR2414) { - ah->ah_combined_mic = true; + common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE, AR5K_MISC_MODE_COMBINED_MIC); } @@ -329,7 +330,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); - ath5k_hw_set_associd(ah); + ath5k_hw_set_bssid(ah); ath5k_hw_set_opmode(ah, sc->opmode); ath5k_hw_rfgain_opt_init(ah); diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index d77ce9906b6ccb1bf1031b1260dfd2510fd9e116..f1ae75d35d5d4680085c2a9d8148fc2a04233a6b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -52,6 +52,7 @@ #include #include #include +#include #include @@ -61,6 +62,7 @@ #include "reg.h" #include "debug.h" #include "ani.h" +#include "../debug.h" static int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); @@ -70,11 +72,6 @@ static int modparam_all_channels; module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); - -/******************\ -* Internal defines * -\******************/ - /* Module info */ MODULE_AUTHOR("Jiri Slaby"); MODULE_AUTHOR("Nick Kossifidis"); @@ -83,6 +80,10 @@ MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); +static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); +static int ath5k_beacon_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); +static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); /* Known PCI ids */ static DEFINE_PCI_DEVICE_TABLE(ath5k_pci_id_table) = { @@ -190,129 +191,6 @@ static const struct ieee80211_rate ath5k_rates[] = { /* XR missing */ }; -/* - * Prototypes - PCI stack related functions - */ -static int __devinit ath5k_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id); -static void __devexit ath5k_pci_remove(struct pci_dev *pdev); -#ifdef CONFIG_PM_SLEEP -static int ath5k_pci_suspend(struct device *dev); -static int ath5k_pci_resume(struct device *dev); - -static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); -#define ATH5K_PM_OPS (&ath5k_pm_ops) -#else -#define ATH5K_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ - -static struct pci_driver ath5k_pci_driver = { - .name = KBUILD_MODNAME, - .id_table = ath5k_pci_id_table, - .probe = ath5k_pci_probe, - .remove = __devexit_p(ath5k_pci_remove), - .driver.pm = ATH5K_PM_OPS, -}; - - - -/* - * Prototypes - MAC 802.11 stack related functions - */ -static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq); -static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan); -static int ath5k_start(struct ieee80211_hw *hw); -static void ath5k_stop(struct ieee80211_hw *hw); -static int ath5k_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static void ath5k_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static int ath5k_config(struct ieee80211_hw *hw, u32 changed); -static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list); -static void ath5k_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *new_flags, - u64 multicast); -static int ath5k_set_key(struct ieee80211_hw *hw, - enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key); -static int ath5k_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats); -static int ath5k_get_survey(struct ieee80211_hw *hw, - int idx, struct survey_info *survey); -static u64 ath5k_get_tsf(struct ieee80211_hw *hw); -static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); -static void ath5k_reset_tsf(struct ieee80211_hw *hw); -static int ath5k_beacon_update(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); -static void ath5k_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes); -static void ath5k_sw_scan_start(struct ieee80211_hw *hw); -static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); -static void ath5k_set_coverage_class(struct ieee80211_hw *hw, - u8 coverage_class); - -static const struct ieee80211_ops ath5k_hw_ops = { - .tx = ath5k_tx, - .start = ath5k_start, - .stop = ath5k_stop, - .add_interface = ath5k_add_interface, - .remove_interface = ath5k_remove_interface, - .config = ath5k_config, - .prepare_multicast = ath5k_prepare_multicast, - .configure_filter = ath5k_configure_filter, - .set_key = ath5k_set_key, - .get_stats = ath5k_get_stats, - .get_survey = ath5k_get_survey, - .conf_tx = NULL, - .get_tsf = ath5k_get_tsf, - .set_tsf = ath5k_set_tsf, - .reset_tsf = ath5k_reset_tsf, - .bss_info_changed = ath5k_bss_info_changed, - .sw_scan_start = ath5k_sw_scan_start, - .sw_scan_complete = ath5k_sw_scan_complete, - .set_coverage_class = ath5k_set_coverage_class, -}; - -/* - * Prototypes - Internal functions - */ -/* Attach detach */ -static int ath5k_attach(struct pci_dev *pdev, - struct ieee80211_hw *hw); -static void ath5k_detach(struct pci_dev *pdev, - struct ieee80211_hw *hw); -/* Channel/mode setup */ -static inline short ath5k_ieee2mhz(short chan); -static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, - struct ieee80211_channel *channels, - unsigned int mode, - unsigned int max); -static int ath5k_setup_bands(struct ieee80211_hw *hw); -static int ath5k_chan_set(struct ath5k_softc *sc, - struct ieee80211_channel *chan); -static void ath5k_setcurmode(struct ath5k_softc *sc, - unsigned int mode); -static void ath5k_mode_setup(struct ath5k_softc *sc); - -/* Descriptor setup */ -static int ath5k_desc_alloc(struct ath5k_softc *sc, - struct pci_dev *pdev); -static void ath5k_desc_free(struct ath5k_softc *sc, - struct pci_dev *pdev); -/* Buffers setup */ -static int ath5k_rxbuf_setup(struct ath5k_softc *sc, - struct ath5k_buf *bf); -static int ath5k_txbuf_setup(struct ath5k_softc *sc, - struct ath5k_buf *bf, - struct ath5k_txq *txq, int padsize); - static inline void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf) { @@ -345,35 +223,6 @@ static inline void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, } -/* Queues setup */ -static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc, - int qtype, int subtype); -static int ath5k_beaconq_setup(struct ath5k_hw *ah); -static int ath5k_beaconq_config(struct ath5k_softc *sc); -static void ath5k_txq_drainq(struct ath5k_softc *sc, - struct ath5k_txq *txq); -static void ath5k_txq_cleanup(struct ath5k_softc *sc); -static void ath5k_txq_release(struct ath5k_softc *sc); -/* Rx handling */ -static int ath5k_rx_start(struct ath5k_softc *sc); -static void ath5k_rx_stop(struct ath5k_softc *sc); -static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc, - struct sk_buff *skb, - struct ath5k_rx_status *rs); -static void ath5k_tasklet_rx(unsigned long data); -/* Tx handling */ -static void ath5k_tx_processq(struct ath5k_softc *sc, - struct ath5k_txq *txq); -static void ath5k_tasklet_tx(unsigned long data); -/* Beacon handling */ -static int ath5k_beacon_setup(struct ath5k_softc *sc, - struct ath5k_buf *bf); -static void ath5k_beacon_send(struct ath5k_softc *sc); -static void ath5k_beacon_config(struct ath5k_softc *sc); -static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); -static void ath5k_tasklet_beacon(unsigned long data); -static void ath5k_tasklet_ani(unsigned long data); - static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) { u64 tsf = ath5k_hw_get_tsf64(ah); @@ -384,50 +233,6 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) return (tsf & ~0x7fff) | rstamp; } -/* Interrupt handling */ -static int ath5k_init(struct ath5k_softc *sc); -static int ath5k_stop_locked(struct ath5k_softc *sc); -static int ath5k_stop_hw(struct ath5k_softc *sc); -static irqreturn_t ath5k_intr(int irq, void *dev_id); -static void ath5k_reset_work(struct work_struct *work); - -static void ath5k_tasklet_calibrate(unsigned long data); - -/* - * Module init/exit functions - */ -static int __init -init_ath5k_pci(void) -{ - int ret; - - ath5k_debug_init(); - - ret = pci_register_driver(&ath5k_pci_driver); - if (ret) { - printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); - return ret; - } - - return 0; -} - -static void __exit -exit_ath5k_pci(void) -{ - pci_unregister_driver(&ath5k_pci_driver); - - ath5k_debug_finish(); -} - -module_init(init_ath5k_pci); -module_exit(exit_ath5k_pci); - - -/********************\ -* PCI Initialization * -\********************/ - static const char * ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) { @@ -466,757 +271,387 @@ static const struct ath_ops ath5k_common_ops = { .write = ath5k_iowrite32, }; -static int __devinit -ath5k_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) +/***********************\ +* Driver Initialization * +\***********************/ + +static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) { - void __iomem *mem; - struct ath5k_softc *sc; - struct ath_common *common; - struct ieee80211_hw *hw; - int ret; - u8 csz; + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath5k_softc *sc = hw->priv; + struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah); - /* - * L0s needs to be disabled on all ath5k cards. - * - * For distributions shipping with CONFIG_PCIEASPM (this will be enabled - * by default in the future in 2.6.36) this will also mean both L1 and - * L0s will be disabled when a pre 1.1 PCIe device is detected. We do - * know L1 works correctly even for all ath5k pre 1.1 PCIe devices - * though but cannot currently undue the effect of a blacklist, for - * details you can read pcie_aspm_sanity_check() and see how it adjusts - * the device link capability. - * - * It may be possible in the future to implement some PCI API to allow - * drivers to override blacklists for pre 1.1 PCIe but for now it is - * best to accept that both L0s and L1 will be disabled completely for - * distributions shipping with CONFIG_PCIEASPM rather than having this - * issue present. Motivation for adding this new API will be to help - * with power consumption for some of these devices. - */ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); + return ath_reg_notifier_apply(wiphy, request, regulatory); +} - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, "can't enable device\n"); - goto err; - } +/********************\ +* Channel/mode setup * +\********************/ - /* XXX 32-bit addressing only */ - ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (ret) { - dev_err(&pdev->dev, "32-bit DMA not available\n"); - goto err_dis; - } +/* + * Convert IEEE channel number to MHz frequency. + */ +static inline short +ath5k_ieee2mhz(short chan) +{ + if (chan <= 14 || chan >= 27) + return ieee80211chan2mhz(chan); + else + return 2212 + chan * 20; +} - /* - * Cache line size is used to size and align various - * structures used to communicate with the hardware. - */ - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); - if (csz == 0) { - /* - * Linux 2.4.18 (at least) writes the cache line size - * register as a 16-bit wide register which is wrong. - * We must have this setup properly for rx buffer - * DMA to work so force a reasonable value here if it - * comes up zero. - */ - csz = L1_CACHE_BYTES >> 2; - pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); - } - /* - * The default setting of latency timer yields poor results, - * set it to the value used by other systems. It may be worth - * tweaking this setting more. - */ - pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); +/* + * Returns true for the channel numbers used without all_channels modparam. + */ +static bool ath5k_is_standard_channel(short chan) +{ + return ((chan <= 14) || + /* UNII 1,2 */ + ((chan & 3) == 0 && chan >= 36 && chan <= 64) || + /* midband */ + ((chan & 3) == 0 && chan >= 100 && chan <= 140) || + /* UNII-3 */ + ((chan & 3) == 1 && chan >= 149 && chan <= 165)); +} - /* Enable bus mastering */ - pci_set_master(pdev); +static unsigned int +ath5k_copy_channels(struct ath5k_hw *ah, + struct ieee80211_channel *channels, + unsigned int mode, + unsigned int max) +{ + unsigned int i, count, size, chfreq, freq, ch; - /* - * Disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state. - */ - pci_write_config_byte(pdev, 0x41, 0); + if (!test_bit(mode, ah->ah_modes)) + return 0; - ret = pci_request_region(pdev, 0, "ath5k"); - if (ret) { - dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); - goto err_dis; + switch (mode) { + case AR5K_MODE_11A: + case AR5K_MODE_11A_TURBO: + /* 1..220, but 2GHz frequencies are filtered by check_channel */ + size = 220 ; + chfreq = CHANNEL_5GHZ; + break; + case AR5K_MODE_11B: + case AR5K_MODE_11G: + case AR5K_MODE_11G_TURBO: + size = 26; + chfreq = CHANNEL_2GHZ; + break; + default: + ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n"); + return 0; } - mem = pci_iomap(pdev, 0, 0); - if (!mem) { - dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; - ret = -EIO; - goto err_reg; - } + for (i = 0, count = 0; i < size && max > 0; i++) { + ch = i + 1 ; + freq = ath5k_ieee2mhz(ch); - /* - * Allocate hw (mac80211 main struct) - * and hw->priv (driver private data) - */ - hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); - if (hw == NULL) { - dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); - ret = -ENOMEM; - goto err_map; - } + /* Check if channel is supported by the chipset */ + if (!ath5k_channel_ok(ah, freq, chfreq)) + continue; - dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); - - /* Initialize driver private data */ - SET_IEEE80211_DEV(hw, &pdev->dev); - hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | - IEEE80211_HW_SIGNAL_DBM; - - hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_MESH_POINT); + if (!modparam_all_channels && !ath5k_is_standard_channel(ch)) + continue; - hw->extra_tx_headroom = 2; - hw->channel_change_time = 5000; - sc = hw->priv; - sc->hw = hw; - sc->pdev = pdev; + /* Write channel info and increment counter */ + channels[count].center_freq = freq; + channels[count].band = (chfreq == CHANNEL_2GHZ) ? + IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; + switch (mode) { + case AR5K_MODE_11A: + case AR5K_MODE_11G: + channels[count].hw_value = chfreq | CHANNEL_OFDM; + break; + case AR5K_MODE_11A_TURBO: + case AR5K_MODE_11G_TURBO: + channels[count].hw_value = chfreq | + CHANNEL_OFDM | CHANNEL_TURBO; + break; + case AR5K_MODE_11B: + channels[count].hw_value = CHANNEL_B; + } - ath5k_debug_init_device(sc); + count++; + max--; + } - /* - * Mark the device as detached to avoid processing - * interrupts until setup is complete. - */ - __set_bit(ATH_STAT_INVALID, sc->status); + return count; +} - sc->iobase = mem; /* So we can unmap it on detach */ - sc->opmode = NL80211_IFTYPE_STATION; - sc->bintval = 1000; - mutex_init(&sc->lock); - spin_lock_init(&sc->rxbuflock); - spin_lock_init(&sc->txbuflock); - spin_lock_init(&sc->block); +static void +ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b) +{ + u8 i; - /* Set private data */ - pci_set_drvdata(pdev, sc); + for (i = 0; i < AR5K_MAX_RATES; i++) + sc->rate_idx[b->band][i] = -1; - /* Setup interrupt handler */ - ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); - if (ret) { - ATH5K_ERR(sc, "request_irq failed\n"); - goto err_free; + for (i = 0; i < b->n_bitrates; i++) { + sc->rate_idx[b->band][b->bitrates[i].hw_value] = i; + if (b->bitrates[i].hw_value_short) + sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i; } +} - /*If we passed the test malloc a ath5k_hw struct*/ - sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); - if (!sc->ah) { - ret = -ENOMEM; - ATH5K_ERR(sc, "out of memory\n"); - goto err_irq; - } +static int +ath5k_setup_bands(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ieee80211_supported_band *sband; + int max_c, count_c = 0; + int i; - sc->ah->ah_sc = sc; - sc->ah->ah_iobase = sc->iobase; - common = ath5k_hw_common(sc->ah); - common->ops = &ath5k_common_ops; - common->ah = sc->ah; - common->hw = hw; - common->cachelsz = csz << 2; /* convert to bytes */ + BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); + max_c = ARRAY_SIZE(sc->channels); - /* Initialize device */ - ret = ath5k_hw_attach(sc); - if (ret) { - goto err_free_ah; - } + /* 2GHz band */ + sband = &sc->sbands[IEEE80211_BAND_2GHZ]; + sband->band = IEEE80211_BAND_2GHZ; + sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0]; - /* set up multi-rate retry capabilities */ - if (sc->ah->ah_version == AR5K_AR5212) { - hw->max_rates = 4; - hw->max_rate_tries = 11; - } + if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { + /* G mode */ + memcpy(sband->bitrates, &ath5k_rates[0], + sizeof(struct ieee80211_rate) * 12); + sband->n_bitrates = 12; - /* Finish private driver data initialization */ - ret = ath5k_attach(pdev, hw); - if (ret) - goto err_ah; + sband->channels = sc->channels; + sband->n_channels = ath5k_copy_channels(ah, sband->channels, + AR5K_MODE_11G, max_c); - ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", - ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), - sc->ah->ah_mac_srev, - sc->ah->ah_phy_revision); + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + count_c = sband->n_channels; + max_c -= count_c; + } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) { + /* B mode */ + memcpy(sband->bitrates, &ath5k_rates[0], + sizeof(struct ieee80211_rate) * 4); + sband->n_bitrates = 4; - if (!sc->ah->ah_single_chip) { - /* Single chip radio (!RF5111) */ - if (sc->ah->ah_radio_5ghz_revision && - !sc->ah->ah_radio_2ghz_revision) { - /* No 5GHz support -> report 2GHz radio */ - if (!test_bit(AR5K_MODE_11A, - sc->ah->ah_capabilities.cap_mode)) { - ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - /* No 2GHz support (5110 and some - * 5Ghz only cards) -> report 5Ghz radio */ - } else if (!test_bit(AR5K_MODE_11B, - sc->ah->ah_capabilities.cap_mode)) { - ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - /* Multiband radio */ - } else { - ATH5K_INFO(sc, "RF%s multiband radio found" - " (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); + /* 5211 only supports B rates and uses 4bit rate codes + * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B) + * fix them up here: + */ + if (ah->ah_version == AR5K_AR5211) { + for (i = 0; i < 4; i++) { + sband->bitrates[i].hw_value = + sband->bitrates[i].hw_value & 0xF; + sband->bitrates[i].hw_value_short = + sband->bitrates[i].hw_value_short & 0xF; } } - /* Multi chip radio (RF5111 - RF2111) -> - * report both 2GHz/5GHz radios */ - else if (sc->ah->ah_radio_5ghz_revision && - sc->ah->ah_radio_2ghz_revision){ - ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_5ghz_revision), - sc->ah->ah_radio_5ghz_revision); - ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", - ath5k_chip_name(AR5K_VERSION_RAD, - sc->ah->ah_radio_2ghz_revision), - sc->ah->ah_radio_2ghz_revision); - } - } + sband->channels = sc->channels; + sband->n_channels = ath5k_copy_channels(ah, sband->channels, + AR5K_MODE_11B, max_c); - /* ready to process interrupts */ - __clear_bit(ATH_STAT_INVALID, sc->status); + hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; + count_c = sband->n_channels; + max_c -= count_c; + } + ath5k_setup_rate_idx(sc, sband); - return 0; -err_ah: - ath5k_hw_detach(sc->ah); -err_irq: - free_irq(pdev->irq, sc); -err_free_ah: - kfree(sc->ah); -err_free: - ieee80211_free_hw(hw); -err_map: - pci_iounmap(pdev, mem); -err_reg: - pci_release_region(pdev, 0); -err_dis: - pci_disable_device(pdev); -err: - return ret; -} + /* 5GHz band, A mode */ + if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { + sband = &sc->sbands[IEEE80211_BAND_5GHZ]; + sband->band = IEEE80211_BAND_5GHZ; + sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0]; -static void __devexit -ath5k_pci_remove(struct pci_dev *pdev) -{ - struct ath5k_softc *sc = pci_get_drvdata(pdev); + memcpy(sband->bitrates, &ath5k_rates[4], + sizeof(struct ieee80211_rate) * 8); + sband->n_bitrates = 8; - ath5k_debug_finish_device(sc); - ath5k_detach(pdev, sc->hw); - ath5k_hw_detach(sc->ah); - kfree(sc->ah); - free_irq(pdev->irq, sc); - pci_iounmap(pdev, sc->iobase); - pci_release_region(pdev, 0); - pci_disable_device(pdev); - ieee80211_free_hw(sc->hw); -} + sband->channels = &sc->channels[count_c]; + sband->n_channels = ath5k_copy_channels(ah, sband->channels, + AR5K_MODE_11A, max_c); -#ifdef CONFIG_PM_SLEEP -static int ath5k_pci_suspend(struct device *dev) -{ - struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; + } + ath5k_setup_rate_idx(sc, sband); + + ath5k_debug_dump_bands(sc); - ath5k_led_off(sc); return 0; } -static int ath5k_pci_resume(struct device *dev) -{ - struct pci_dev *pdev = to_pci_dev(dev); - struct ath5k_softc *sc = pci_get_drvdata(pdev); - - /* - * Suspend/Resume resets the PCI configuration space, so we have to - * re-disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state - */ - pci_write_config_byte(pdev, 0x41, 0); +/* + * Set/change channels. We always reset the chip. + * To accomplish this we must first cleanup any pending DMA, + * then restart stuff after a la ath5k_init. + * + * Called with sc->lock. + */ +static int +ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) +{ + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "channel set, resetting (%u -> %u MHz)\n", + sc->curchan->center_freq, chan->center_freq); - ath5k_led_enable(sc); - return 0; + /* + * To switch channels clear any pending DMA operations; + * wait long enough for the RX fifo to drain, reset the + * hardware at the new frequency, and then re-enable + * the relevant bits of the h/w. + */ + return ath5k_reset(sc, chan); } -#endif /* CONFIG_PM_SLEEP */ - - -/***********************\ -* Driver Initialization * -\***********************/ -static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +static void +ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) { - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath5k_softc *sc = hw->priv; - struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah); + sc->curmode = mode; - return ath_reg_notifier_apply(wiphy, request, regulatory); + if (mode == AR5K_MODE_11A) { + sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; + } else { + sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; + } } -static int -ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); - u8 mac[ETH_ALEN] = {}; - int ret; - - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); +struct ath_vif_iter_data { + const u8 *hw_macaddr; + u8 mask[ETH_ALEN]; + u8 active_mac[ETH_ALEN]; /* first active MAC */ + bool need_set_hw_addr; + bool found_active; + bool any_assoc; + enum nl80211_iftype opmode; +}; - /* - * Check if the MAC has multi-rate retry support. - * We do this by trying to setup a fake extended - * descriptor. MAC's that don't have support will - * return false w/o doing anything. MAC's that do - * support it will return true w/o doing anything. - */ - ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); +static void ath_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath_vif_iter_data *iter_data = data; + int i; + struct ath5k_vif *avf = (void *)vif->drv_priv; - if (ret < 0) - goto err; - if (ret > 0) - __set_bit(ATH_STAT_MRRETRY, sc->status); + if (iter_data->hw_macaddr) + for (i = 0; i < ETH_ALEN; i++) + iter_data->mask[i] &= + ~(iter_data->hw_macaddr[i] ^ mac[i]); - /* - * Collect the channel list. The 802.11 layer - * is resposible for filtering this list based - * on settings like the phy mode and regulatory - * domain restrictions. - */ - ret = ath5k_setup_bands(hw); - if (ret) { - ATH5K_ERR(sc, "can't get channels\n"); - goto err; + if (!iter_data->found_active) { + iter_data->found_active = true; + memcpy(iter_data->active_mac, mac, ETH_ALEN); } - /* NB: setup here so ath5k_rate_update is happy */ - if (test_bit(AR5K_MODE_11A, ah->ah_modes)) - ath5k_setcurmode(sc, AR5K_MODE_11A); - else - ath5k_setcurmode(sc, AR5K_MODE_11B); + if (iter_data->need_set_hw_addr && iter_data->hw_macaddr) + if (compare_ether_addr(iter_data->hw_macaddr, mac) == 0) + iter_data->need_set_hw_addr = false; - /* - * Allocate tx+rx descriptors and populate the lists. - */ - ret = ath5k_desc_alloc(sc, pdev); - if (ret) { - ATH5K_ERR(sc, "can't allocate descriptors\n"); - goto err; + if (!iter_data->any_assoc) { + if (avf->assoc) + iter_data->any_assoc = true; } - /* - * Allocate hardware transmit queues: one queue for - * beacon frames and one data queue for each QoS - * priority. Note that hw functions handle reseting - * these queues at the needed time. + /* Calculate combined mode - when APs are active, operate in AP mode. + * Otherwise use the mode of the new interface. This can currently + * only deal with combinations of APs and STAs. Only one ad-hoc + * interfaces is allowed above. */ - ret = ath5k_beaconq_setup(ah); - if (ret < 0) { - ATH5K_ERR(sc, "can't setup a beacon xmit queue\n"); - goto err_desc; - } - sc->bhalq = ret; - sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0); - if (IS_ERR(sc->cabq)) { - ATH5K_ERR(sc, "can't setup cab queue\n"); - ret = PTR_ERR(sc->cabq); - goto err_bhal; - } - - sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); - if (IS_ERR(sc->txq)) { - ATH5K_ERR(sc, "can't setup xmit queue\n"); - ret = PTR_ERR(sc->txq); - goto err_queues; - } - - tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); - tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); - tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); - tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); - tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); + if (avf->opmode == NL80211_IFTYPE_AP) + iter_data->opmode = NL80211_IFTYPE_AP; + else + if (iter_data->opmode == NL80211_IFTYPE_UNSPECIFIED) + iter_data->opmode = avf->opmode; +} - INIT_WORK(&sc->reset_work, ath5k_reset_work); +static void ath_do_set_opmode(struct ath5k_softc *sc) +{ + struct ath5k_hw *ah = sc->ah; + ath5k_hw_set_opmode(ah, sc->opmode); + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d (%s)\n", + sc->opmode, ath_opmode_to_string(sc->opmode)); +} - ret = ath5k_eeprom_read_mac(ah, mac); - if (ret) { - ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", - sc->pdev->device); - goto err_queues; - } +void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, + struct ieee80211_vif *vif) +{ + struct ath_common *common = ath5k_hw_common(sc->ah); + struct ath_vif_iter_data iter_data; - SET_IEEE80211_PERM_ADDR(hw, mac); - /* All MAC address bits matter for ACKs */ - memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN); - ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); + /* + * Use the hardware MAC address as reference, the hardware uses it + * together with the BSSID mask when matching addresses. + */ + iter_data.hw_macaddr = common->macaddr; + memset(&iter_data.mask, 0xff, ETH_ALEN); + iter_data.found_active = false; + iter_data.need_set_hw_addr = true; + iter_data.opmode = NL80211_IFTYPE_UNSPECIFIED; - regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; - ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); - if (ret) { - ATH5K_ERR(sc, "can't initialize regulatory system\n"); - goto err_queues; - } + if (vif) + ath_vif_iter(&iter_data, vif->addr, vif); - ret = ieee80211_register_hw(hw); - if (ret) { - ATH5K_ERR(sc, "can't register ieee80211 hw\n"); - goto err_queues; - } + /* Get list of all active MAC addresses */ + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, + &iter_data); + memcpy(sc->bssidmask, iter_data.mask, ETH_ALEN); - if (!ath_is_world_regd(regulatory)) - regulatory_hint(hw->wiphy, regulatory->alpha2); + sc->opmode = iter_data.opmode; + if (sc->opmode == NL80211_IFTYPE_UNSPECIFIED) + /* Nothing active, default to station mode */ + sc->opmode = NL80211_IFTYPE_STATION; - ath5k_init_leds(sc); + ath_do_set_opmode(sc); - ath5k_sysfs_register(sc); + if (iter_data.need_set_hw_addr && iter_data.found_active) + ath5k_hw_set_lladdr(sc->ah, iter_data.active_mac); - return 0; -err_queues: - ath5k_txq_release(sc); -err_bhal: - ath5k_hw_release_tx_queue(ah, sc->bhalq); -err_desc: - ath5k_desc_free(sc, pdev); -err: - return ret; + if (ath5k_hw_hasbssidmask(sc->ah)) + ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask); } static void -ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) +ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif) { - struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + u32 rfilt; - /* - * NB: the order of these is important: - * o call the 802.11 layer before detaching ath5k_hw to - * insure callbacks into the driver to delete global - * key cache entries can be handled - * o reclaim the tx queue data structures after calling - * the 802.11 layer as we'll get called back to reclaim - * node state and potentially want to use them - * o to cleanup the tx queues the hal is called, so detach - * it last - * XXX: ??? detach ath5k_hw ??? - * Other than that, it's straightforward... - */ - ieee80211_unregister_hw(hw); - ath5k_desc_free(sc, pdev); - ath5k_txq_release(sc); - ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); - ath5k_unregister_leds(sc); + /* configure rx filter */ + rfilt = sc->filter_flags; + ath5k_hw_set_rx_filter(ah, rfilt); + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); - ath5k_sysfs_unregister(sc); - /* - * NB: can't reclaim these until after ieee80211_ifdetach - * returns because we'll get called back to reclaim node - * state and potentially want to use them. - */ + ath5k_update_bssid_mask_and_opmode(sc, vif); } +static inline int +ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) +{ + int rix; + /* return base rate on errors */ + if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES, + "hw_rix out of bounds: %x\n", hw_rix)) + return 0; + rix = sc->rate_idx[sc->curband->band][hw_rix]; + if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) + rix = 0; -/********************\ -* Channel/mode setup * -\********************/ - -/* - * Convert IEEE channel number to MHz frequency. - */ -static inline short -ath5k_ieee2mhz(short chan) -{ - if (chan <= 14 || chan >= 27) - return ieee80211chan2mhz(chan); - else - return 2212 + chan * 20; + return rix; } -/* - * Returns true for the channel numbers used without all_channels modparam. - */ -static bool ath5k_is_standard_channel(short chan) -{ - return ((chan <= 14) || - /* UNII 1,2 */ - ((chan & 3) == 0 && chan >= 36 && chan <= 64) || - /* midband */ - ((chan & 3) == 0 && chan >= 100 && chan <= 140) || - /* UNII-3 */ - ((chan & 3) == 1 && chan >= 149 && chan <= 165)); -} +/***************\ +* Buffers setup * +\***************/ -static unsigned int -ath5k_copy_channels(struct ath5k_hw *ah, - struct ieee80211_channel *channels, - unsigned int mode, - unsigned int max) +static +struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) { - unsigned int i, count, size, chfreq, freq, ch; + struct ath_common *common = ath5k_hw_common(sc->ah); + struct sk_buff *skb; - if (!test_bit(mode, ah->ah_modes)) - return 0; - - switch (mode) { - case AR5K_MODE_11A: - case AR5K_MODE_11A_TURBO: - /* 1..220, but 2GHz frequencies are filtered by check_channel */ - size = 220 ; - chfreq = CHANNEL_5GHZ; - break; - case AR5K_MODE_11B: - case AR5K_MODE_11G: - case AR5K_MODE_11G_TURBO: - size = 26; - chfreq = CHANNEL_2GHZ; - break; - default: - ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n"); - return 0; - } - - for (i = 0, count = 0; i < size && max > 0; i++) { - ch = i + 1 ; - freq = ath5k_ieee2mhz(ch); - - /* Check if channel is supported by the chipset */ - if (!ath5k_channel_ok(ah, freq, chfreq)) - continue; - - if (!modparam_all_channels && !ath5k_is_standard_channel(ch)) - continue; - - /* Write channel info and increment counter */ - channels[count].center_freq = freq; - channels[count].band = (chfreq == CHANNEL_2GHZ) ? - IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; - switch (mode) { - case AR5K_MODE_11A: - case AR5K_MODE_11G: - channels[count].hw_value = chfreq | CHANNEL_OFDM; - break; - case AR5K_MODE_11A_TURBO: - case AR5K_MODE_11G_TURBO: - channels[count].hw_value = chfreq | - CHANNEL_OFDM | CHANNEL_TURBO; - break; - case AR5K_MODE_11B: - channels[count].hw_value = CHANNEL_B; - } - - count++; - max--; - } - - return count; -} - -static void -ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b) -{ - u8 i; - - for (i = 0; i < AR5K_MAX_RATES; i++) - sc->rate_idx[b->band][i] = -1; - - for (i = 0; i < b->n_bitrates; i++) { - sc->rate_idx[b->band][b->bitrates[i].hw_value] = i; - if (b->bitrates[i].hw_value_short) - sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i; - } -} - -static int -ath5k_setup_bands(struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ieee80211_supported_band *sband; - int max_c, count_c = 0; - int i; - - BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); - max_c = ARRAY_SIZE(sc->channels); - - /* 2GHz band */ - sband = &sc->sbands[IEEE80211_BAND_2GHZ]; - sband->band = IEEE80211_BAND_2GHZ; - sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0]; - - if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { - /* G mode */ - memcpy(sband->bitrates, &ath5k_rates[0], - sizeof(struct ieee80211_rate) * 12); - sband->n_bitrates = 12; - - sband->channels = sc->channels; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, - AR5K_MODE_11G, max_c); - - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; - count_c = sband->n_channels; - max_c -= count_c; - } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) { - /* B mode */ - memcpy(sband->bitrates, &ath5k_rates[0], - sizeof(struct ieee80211_rate) * 4); - sband->n_bitrates = 4; - - /* 5211 only supports B rates and uses 4bit rate codes - * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B) - * fix them up here: - */ - if (ah->ah_version == AR5K_AR5211) { - for (i = 0; i < 4; i++) { - sband->bitrates[i].hw_value = - sband->bitrates[i].hw_value & 0xF; - sband->bitrates[i].hw_value_short = - sband->bitrates[i].hw_value_short & 0xF; - } - } - - sband->channels = sc->channels; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, - AR5K_MODE_11B, max_c); - - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; - count_c = sband->n_channels; - max_c -= count_c; - } - ath5k_setup_rate_idx(sc, sband); - - /* 5GHz band, A mode */ - if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { - sband = &sc->sbands[IEEE80211_BAND_5GHZ]; - sband->band = IEEE80211_BAND_5GHZ; - sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0]; - - memcpy(sband->bitrates, &ath5k_rates[4], - sizeof(struct ieee80211_rate) * 8); - sband->n_bitrates = 8; - - sband->channels = &sc->channels[count_c]; - sband->n_channels = ath5k_copy_channels(ah, sband->channels, - AR5K_MODE_11A, max_c); - - hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; - } - ath5k_setup_rate_idx(sc, sband); - - ath5k_debug_dump_bands(sc); - - return 0; -} - -/* - * Set/change channels. We always reset the chip. - * To accomplish this we must first cleanup any pending DMA, - * then restart stuff after a la ath5k_init. - * - * Called with sc->lock. - */ -static int -ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) -{ - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, - "channel set, resetting (%u -> %u MHz)\n", - sc->curchan->center_freq, chan->center_freq); - - /* - * To switch channels clear any pending DMA operations; - * wait long enough for the RX fifo to drain, reset the - * hardware at the new frequency, and then re-enable - * the relevant bits of the h/w. - */ - return ath5k_reset(sc, chan); -} - -static void -ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) -{ - sc->curmode = mode; - - if (mode == AR5K_MODE_11A) { - sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ]; - } else { - sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ]; - } -} - -static void -ath5k_mode_setup(struct ath5k_softc *sc) -{ - struct ath5k_hw *ah = sc->ah; - u32 rfilt; - - /* configure rx filter */ - rfilt = sc->filter_flags; - ath5k_hw_set_rx_filter(ah, rfilt); - - if (ath5k_hw_hasbssidmask(ah)) - ath5k_hw_set_bssid_mask(ah, sc->bssidmask); - - /* configure operational mode */ - ath5k_hw_set_opmode(ah, sc->opmode); - - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); -} - -static inline int -ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) -{ - int rix; - - /* return base rate on errors */ - if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES, - "hw_rix out of bounds: %x\n", hw_rix)) - return 0; - - rix = sc->rate_idx[sc->curband->band][hw_rix]; - if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix)) - rix = 0; - - return rix; -} - -/***************\ -* Buffers setup * -\***************/ - -static -struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr) -{ - struct ath_common *common = ath5k_hw_common(sc->ah); - struct sk_buff *skb; - - /* - * Allocate buffer with headroom_needed space for the - * fake physical layer header at the start. - */ - skb = ath_rxbuf_alloc(common, - common->rx_bufsize, - GFP_ATOMIC); + /* + * Allocate buffer with headroom_needed space for the + * fake physical layer header at the start. + */ + skb = ath_rxbuf_alloc(common, + common->rx_bufsize, + GFP_ATOMIC); if (!skb) { ATH5K_ERR(sc, "can't alloc skbuff of size %u\n", @@ -1352,13 +787,13 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, flags |= AR5K_TXDESC_RTSENA; cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; duration = le16_to_cpu(ieee80211_rts_duration(sc->hw, - sc->vif, pktlen, info)); + info->control.vif, pktlen, info)); } if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { flags |= AR5K_TXDESC_CTSENA; cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value; duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw, - sc->vif, pktlen, info)); + info->control.vif, pktlen, info)); } ret = ah->ah_setup_tx_desc(ah, ds, pktlen, ieee80211_get_hdrlen_from_skb(skb), padsize, @@ -1391,6 +826,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, spin_lock_bh(&txq->lock); list_add_tail(&bf->list, &txq->q); + txq->txq_len++; if (txq->link == NULL) /* is this first packet? */ ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); else /* no, so only link it */ @@ -1459,10 +895,13 @@ ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev) list_add_tail(&bf->list, &sc->txbuf); } - /* beacon buffer */ - bf->desc = ds; - bf->daddr = da; - sc->bbuf = bf; + /* beacon buffers */ + INIT_LIST_HEAD(&sc->bcbuf); + for (i = 0; i < ATH_BCBUF; i++, bf++, ds++, da += sizeof(*ds)) { + bf->desc = ds; + bf->daddr = da; + list_add_tail(&bf->list, &sc->bcbuf); + } return 0; err_free: @@ -1477,11 +916,12 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) { struct ath5k_buf *bf; - ath5k_txbuf_free_skb(sc, sc->bbuf); list_for_each_entry(bf, &sc->txbuf, list) ath5k_txbuf_free_skb(sc, bf); list_for_each_entry(bf, &sc->rxbuf, list) ath5k_rxbuf_free_skb(sc, bf); + list_for_each_entry(bf, &sc->bcbuf, list) + ath5k_txbuf_free_skb(sc, bf); /* Free memory associated with all descriptors */ pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr); @@ -1490,13 +930,9 @@ ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev) kfree(sc->bufptr); sc->bufptr = NULL; - sc->bbuf = NULL; } - - - /**************\ * Queues setup * \**************/ @@ -1509,16 +945,18 @@ ath5k_txq_setup(struct ath5k_softc *sc, struct ath5k_txq *txq; struct ath5k_txq_info qi = { .tqi_subtype = subtype, - .tqi_aifs = AR5K_TXQ_USEDEFAULT, - .tqi_cw_min = AR5K_TXQ_USEDEFAULT, - .tqi_cw_max = AR5K_TXQ_USEDEFAULT + /* XXX: default values not correct for B and XR channels, + * but who cares? */ + .tqi_aifs = AR5K_TUNE_AIFS, + .tqi_cw_min = AR5K_TUNE_CWMIN, + .tqi_cw_max = AR5K_TUNE_CWMAX }; int qnum; /* * Enable interrupts only for EOL and DESC conditions. * We mark tx descriptors to receive a DESC interrupt - * when a tx queue gets deep; otherwise waiting for the + * when a tx queue gets deep; otherwise we wait for the * EOL to reap descriptors. Note that this is done to * reduce interrupt load and this only defers reaping * descriptors, never transmitting frames. Aside from @@ -1550,6 +988,9 @@ ath5k_txq_setup(struct ath5k_softc *sc, INIT_LIST_HEAD(&txq->q); spin_lock_init(&txq->lock); txq->setup = true; + txq->txq_len = 0; + txq->txq_poll_mark = false; + txq->txq_stuck = 0; } return &sc->txqs[qnum]; } @@ -1558,9 +999,11 @@ static int ath5k_beaconq_setup(struct ath5k_hw *ah) { struct ath5k_txq_info qi = { - .tqi_aifs = AR5K_TXQ_USEDEFAULT, - .tqi_cw_min = AR5K_TXQ_USEDEFAULT, - .tqi_cw_max = AR5K_TXQ_USEDEFAULT, + /* XXX: default values not correct for B and XR channels, + * but who cares? */ + .tqi_aifs = AR5K_TUNE_AIFS, + .tqi_cw_min = AR5K_TUNE_CWMIN, + .tqi_cw_max = AR5K_TUNE_CWMAX, /* NB: for dynamic turbo, don't enable any other interrupts */ .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE }; @@ -1594,7 +1037,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) */ qi.tqi_aifs = 0; qi.tqi_cw_min = 0; - qi.tqi_cw_max = 2 * ah->ah_cw_min; + qi.tqi_cw_max = 2 * AR5K_TUNE_CWMIN; } ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, @@ -1644,9 +1087,11 @@ ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq) spin_lock_bh(&sc->txbuflock); list_move_tail(&bf->list, &sc->txbuf); sc->txbuf_len++; + txq->txq_len--; spin_unlock_bh(&sc->txbuflock); } txq->link = NULL; + txq->txq_poll_mark = false; spin_unlock_bh(&txq->lock); } @@ -1696,8 +1141,6 @@ ath5k_txq_release(struct ath5k_softc *sc) } - - /*************\ * RX Handling * \*************/ @@ -1713,7 +1156,7 @@ ath5k_rx_start(struct ath5k_softc *sc) struct ath5k_buf *bf; int ret; - common->rx_bufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz); + common->rx_bufsize = roundup(IEEE80211_MAX_FRAME_LEN, common->cachelsz); ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rx_bufsize %u\n", common->cachelsz, common->rx_bufsize); @@ -1732,7 +1175,7 @@ ath5k_rx_start(struct ath5k_softc *sc) spin_unlock_bh(&sc->rxbuflock); ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ - ath5k_mode_setup(sc); /* set filters, etc. */ + ath5k_mode_setup(sc, NULL); /* set filters, etc. */ ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ return 0; @@ -1840,6 +1283,15 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, */ if (hw_tu >= sc->nexttbtt) ath5k_beacon_update_timers(sc, bc_tstamp); + + /* Check if the beacon timers are still correct, because a TSF + * update might have created a window between them - for a + * longer description see the comment of this function: */ + if (!ath5k_hw_check_beacon_timers(sc->ah, sc->bintval)) { + ath5k_beacon_update_timers(sc, bc_tstamp); + ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, + "fixed beacon timers after beacon receive\n"); + } } } @@ -1863,7 +1315,7 @@ ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) } /* - * Compute padding position. skb must contains an IEEE 802.11 frame + * Compute padding position. skb must contain an IEEE 802.11 frame */ static int ath5k_common_padpos(struct sk_buff *skb) { @@ -1882,10 +1334,9 @@ static int ath5k_common_padpos(struct sk_buff *skb) } /* - * This function expects a 802.11 frame and returns the number of - * bytes added, or -1 if we don't have enought header room. + * This function expects an 802.11 frame and returns the number of + * bytes added, or -1 if we don't have enough header room. */ - static int ath5k_add_padding(struct sk_buff *skb) { int padpos = ath5k_common_padpos(skb); @@ -1905,10 +1356,18 @@ static int ath5k_add_padding(struct sk_buff *skb) } /* - * This function expects a 802.11 frame and returns the number of - * bytes removed + * The MAC header is padded to have 32-bit boundary if the + * packet payload is non-zero. The general calculation for + * padsize would take into account odd header lengths: + * padsize = 4 - (hdrlen & 3); however, since only + * even-length headers are used, padding can only be 0 or 2 + * bytes and we can optimize this a bit. We must not try to + * remove padding from short control frames that do not have a + * payload. + * + * This function expects an 802.11 frame and returns the number of + * bytes removed. */ - static int ath5k_remove_padding(struct sk_buff *skb) { int padpos = ath5k_common_padpos(skb); @@ -1929,14 +1388,6 @@ ath5k_receive_frame(struct ath5k_softc *sc, struct sk_buff *skb, { struct ieee80211_rx_status *rxs; - /* The MAC header is padded to have 32-bit boundary if the - * packet payload is non-zero. The general calculation for - * padsize would take into account odd header lengths: - * padsize = (4 - hdrlen % 4) % 4; However, since only - * even-length headers are used, padding can only be 0 or 2 - * bytes and we can optimize this a bit. In addition, we must - * not try to remove padding from short control frames that do - * not have payload. */ ath5k_remove_padding(skb); rxs = IEEE80211_SKB_RXCB(skb); @@ -2007,6 +1458,7 @@ static bool ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) { sc->stats.rx_all_count++; + sc->stats.rx_bytes_count += rs->rs_datalen; if (unlikely(rs->rs_status)) { if (rs->rs_status & AR5K_RXERR_CRC) @@ -2040,9 +1492,8 @@ ath5k_receive_frame_ok(struct ath5k_softc *sc, struct ath5k_rx_status *rs) return true; } - /* let crypto-error packets fall through in MNTR */ - if ((rs->rs_status & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || - sc->opmode != NL80211_IFTYPE_MONITOR) + /* reject any frames with non-crypto errors */ + if (rs->rs_status & ~(AR5K_RXERR_DECRYPT)) return false; } @@ -2123,103 +1574,170 @@ ath5k_tasklet_rx(unsigned long data) * TX Handling * \*************/ -static void -ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) +static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, + struct ath5k_txq *txq) { - struct ath5k_tx_status ts = {}; - struct ath5k_buf *bf, *bf0; - struct ath5k_desc *ds; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - int i, ret; - - spin_lock(&txq->lock); - list_for_each_entry_safe(bf, bf0, &txq->q, list) { - ds = bf->desc; + struct ath5k_softc *sc = hw->priv; + struct ath5k_buf *bf; + unsigned long flags; + int padsize; - /* - * It's possible that the hardware can say the buffer is - * completed when it hasn't yet loaded the ds_link from - * host memory and moved on. If there are more TX - * descriptors in the queue, wait for TXDP to change - * before processing this one. - */ - if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr && - !list_is_last(&bf->list, &txq->q)) - break; + ath5k_debug_dump_skb(sc, skb, "TX ", 1); - ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); - if (unlikely(ret == -EINPROGRESS)) - break; - else if (unlikely(ret)) { - ATH5K_ERR(sc, "error %d while processing queue %u\n", - ret, txq->qnum); - break; - } + /* + * The hardware expects the header padded to 4 byte boundaries. + * If this is not the case, we add the padding after the header. + */ + padsize = ath5k_add_padding(skb); + if (padsize < 0) { + ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" + " headroom to pad"); + goto drop_packet; + } - sc->stats.tx_all_count++; - skb = bf->skb; - info = IEEE80211_SKB_CB(skb); + if (txq->txq_len >= ATH5K_TXQ_LEN_MAX) + ieee80211_stop_queue(hw, txq->qnum); + + spin_lock_irqsave(&sc->txbuflock, flags); + if (list_empty(&sc->txbuf)) { + ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); + spin_unlock_irqrestore(&sc->txbuflock, flags); + ieee80211_stop_queues(hw); + goto drop_packet; + } + bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); + list_del(&bf->list); + sc->txbuf_len--; + if (list_empty(&sc->txbuf)) + ieee80211_stop_queues(hw); + spin_unlock_irqrestore(&sc->txbuflock, flags); + + bf->skb = skb; + + if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { bf->skb = NULL; + spin_lock_irqsave(&sc->txbuflock, flags); + list_add_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; + spin_unlock_irqrestore(&sc->txbuflock, flags); + goto drop_packet; + } + return NETDEV_TX_OK; - pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, - PCI_DMA_TODEVICE); +drop_packet: + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} - ieee80211_tx_info_clear_status(info); - for (i = 0; i < 4; i++) { - struct ieee80211_tx_rate *r = - &info->status.rates[i]; +static void +ath5k_tx_frame_completed(struct ath5k_softc *sc, struct sk_buff *skb, + struct ath5k_tx_status *ts) +{ + struct ieee80211_tx_info *info; + int i; - if (ts.ts_rate[i]) { - r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); - r->count = ts.ts_retry[i]; - } else { - r->idx = -1; - r->count = 0; - } - } + sc->stats.tx_all_count++; + sc->stats.tx_bytes_count += skb->len; + info = IEEE80211_SKB_CB(skb); - /* count the successful attempt as well */ - info->status.rates[ts.ts_final_idx].count++; + ieee80211_tx_info_clear_status(info); + for (i = 0; i < 4; i++) { + struct ieee80211_tx_rate *r = + &info->status.rates[i]; - if (unlikely(ts.ts_status)) { - sc->stats.ack_fail++; - if (ts.ts_status & AR5K_TXERR_FILT) { - info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - sc->stats.txerr_filt++; - } - if (ts.ts_status & AR5K_TXERR_XRETRY) - sc->stats.txerr_retry++; - if (ts.ts_status & AR5K_TXERR_FIFO) - sc->stats.txerr_fifo++; + if (ts->ts_rate[i]) { + r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]); + r->count = ts->ts_retry[i]; } else { - info->flags |= IEEE80211_TX_STAT_ACK; - info->status.ack_signal = ts.ts_rssi; + r->idx = -1; + r->count = 0; } + } - /* - * Remove MAC header padding before giving the frame - * back to mac80211. - */ - ath5k_remove_padding(skb); + /* count the successful attempt as well */ + info->status.rates[ts->ts_final_idx].count++; - if (ts.ts_antenna > 0 && ts.ts_antenna < 5) - sc->stats.antenna_tx[ts.ts_antenna]++; - else - sc->stats.antenna_tx[0]++; /* invalid */ + if (unlikely(ts->ts_status)) { + sc->stats.ack_fail++; + if (ts->ts_status & AR5K_TXERR_FILT) { + info->flags |= IEEE80211_TX_STAT_TX_FILTERED; + sc->stats.txerr_filt++; + } + if (ts->ts_status & AR5K_TXERR_XRETRY) + sc->stats.txerr_retry++; + if (ts->ts_status & AR5K_TXERR_FIFO) + sc->stats.txerr_fifo++; + } else { + info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = ts->ts_rssi; + } + + /* + * Remove MAC header padding before giving the frame + * back to mac80211. + */ + ath5k_remove_padding(skb); - ieee80211_tx_status(sc->hw, skb); + if (ts->ts_antenna > 0 && ts->ts_antenna < 5) + sc->stats.antenna_tx[ts->ts_antenna]++; + else + sc->stats.antenna_tx[0]++; /* invalid */ - spin_lock(&sc->txbuflock); - list_move_tail(&bf->list, &sc->txbuf); - sc->txbuf_len++; - spin_unlock(&sc->txbuflock); + ieee80211_tx_status(sc->hw, skb); +} + +static void +ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) +{ + struct ath5k_tx_status ts = {}; + struct ath5k_buf *bf, *bf0; + struct ath5k_desc *ds; + struct sk_buff *skb; + int ret; + + spin_lock(&txq->lock); + list_for_each_entry_safe(bf, bf0, &txq->q, list) { + + txq->txq_poll_mark = false; + + /* skb might already have been processed last time. */ + if (bf->skb != NULL) { + ds = bf->desc; + + ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); + if (unlikely(ret == -EINPROGRESS)) + break; + else if (unlikely(ret)) { + ATH5K_ERR(sc, + "error %d while processing " + "queue %u\n", ret, txq->qnum); + break; + } + + skb = bf->skb; + bf->skb = NULL; + pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, + PCI_DMA_TODEVICE); + ath5k_tx_frame_completed(sc, skb, &ts); + } + + /* + * It's possible that the hardware can say the buffer is + * completed when it hasn't yet loaded the ds_link from + * host memory and moved on. + * Always keep the last descriptor to avoid HW races... + */ + if (ath5k_hw_get_txdp(sc->ah, txq->qnum) != bf->daddr) { + spin_lock(&sc->txbuflock); + list_move_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; + txq->txq_len--; + spin_unlock(&sc->txbuflock); + } } - if (likely(list_empty(&txq->q))) - txq->link = NULL; spin_unlock(&txq->lock); - if (sc->txbuf_len > ATH_TXBUF / 5) - ieee80211_wake_queues(sc->hw); + if (txq->txq_len < ATH5K_TXQ_LEN_LOW && txq->qnum < 4) + ieee80211_wake_queue(sc->hw, txq->qnum); } static void @@ -2285,10 +1803,11 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) * default antenna which is supposed to be an omni. * * Note2: On sectored scenarios it's possible to have - * multiple antennas (1omni -the default- and 14 sectors) - * so if we choose to actually support this mode we need - * to allow user to set how many antennas we have and tweak - * the code below to send beacons on all of them. + * multiple antennas (1 omni -- the default -- and 14 + * sectors), so if we choose to actually support this + * mode, we need to allow the user to set how many antennas + * we have and tweak the code below to send beacons + * on all of them. */ if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP) antenna = sc->bsent & 4 ? 2 : 1; @@ -2313,6 +1832,44 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) return ret; } +/* + * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, + * this is called only once at config_bss time, for AP we do it every + * SWBA interrupt so that the TIM will reflect buffered frames. + * + * Called with the beacon lock. + */ +static int +ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + int ret; + struct ath5k_softc *sc = hw->priv; + struct ath5k_vif *avf = (void *)vif->drv_priv; + struct sk_buff *skb; + + if (WARN_ON(!vif)) { + ret = -EINVAL; + goto out; + } + + skb = ieee80211_beacon_get(hw, vif); + + if (!skb) { + ret = -ENOMEM; + goto out; + } + + ath5k_debug_dump_skb(sc, skb, "BC ", 1); + + ath5k_txbuf_free_skb(sc, avf->bbuf); + avf->bbuf->skb = skb; + ret = ath5k_beacon_setup(sc, avf->bbuf); + if (ret) + avf->bbuf->skb = NULL; +out: + return ret; +} + /* * Transmit a beacon frame at SWBA. Dynamic updates to the * frame contents are done as needed and the slot time is @@ -2324,20 +1881,17 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) static void ath5k_beacon_send(struct ath5k_softc *sc) { - struct ath5k_buf *bf = sc->bbuf; struct ath5k_hw *ah = sc->ah; + struct ieee80211_vif *vif; + struct ath5k_vif *avf; + struct ath5k_buf *bf; struct sk_buff *skb; ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); - if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || - sc->opmode == NL80211_IFTYPE_MONITOR)) { - ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); - return; - } /* * Check if the previous beacon has gone out. If - * not don't don't try to post another, skip this + * not, don't don't try to post another: skip this * period and wait for the next. Missed beacons * indicate a problem and should not occur. If we * miss too many consecutive beacons reset the device. @@ -2363,6 +1917,28 @@ ath5k_beacon_send(struct ath5k_softc *sc) sc->bmisscount = 0; } + if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { + u64 tsf = ath5k_hw_get_tsf64(ah); + u32 tsftu = TSF_TO_TU(tsf); + int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; + vif = sc->bslot[(slot + 1) % ATH_BCBUF]; + ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, + "tsf %llx tsftu %x intval %u slot %u vif %p\n", + (unsigned long long)tsf, tsftu, sc->bintval, slot, vif); + } else /* only one interface */ + vif = sc->bslot[0]; + + if (!vif) + return; + + avf = (void *)vif->drv_priv; + bf = avf->bbuf; + if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || + sc->opmode == NL80211_IFTYPE_MONITOR)) { + ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); + return; + } + /* * Stop any current dma and put the new frame on the queue. * This should never fail since we check above that no frames @@ -2375,23 +1951,22 @@ ath5k_beacon_send(struct ath5k_softc *sc) /* refresh the beacon for AP mode */ if (sc->opmode == NL80211_IFTYPE_AP) - ath5k_beacon_update(sc->hw, sc->vif); + ath5k_beacon_update(sc->hw, vif); ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); ath5k_hw_start_tx_dma(ah, sc->bhalq); ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", sc->bhalq, (unsigned long long)bf->daddr, bf->desc); - skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); + skb = ieee80211_get_buffered_bc(sc->hw, vif); while (skb) { ath5k_tx_queue(sc->hw, skb, sc->cabq); - skb = ieee80211_get_buffered_bc(sc->hw, sc->vif); + skb = ieee80211_get_buffered_bc(sc->hw, vif); } sc->bsent++; } - /** * ath5k_beacon_update_timers - update beacon timers * @@ -2416,6 +1991,12 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) u64 hw_tsf; intval = sc->bintval & AR5K_BEACON_PERIOD; + if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { + intval /= ATH_BCBUF; /* staggered multi-bss beacons */ + if (intval < 15) + ATH5K_WARN(sc, "intval %u is too low, min 15\n", + intval); + } if (WARN_ON(!intval)) return; @@ -2426,8 +2007,11 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) hw_tsf = ath5k_hw_get_tsf64(ah); hw_tu = TSF_TO_TU(hw_tsf); -#define FUDGE 3 - /* we use FUDGE to make sure the next TBTT is ahead of the current TU */ +#define FUDGE AR5K_TUNE_SW_BEACON_RESP + 3 + /* We use FUDGE to make sure the next TBTT is ahead of the current TU. + * Since we later substract AR5K_TUNE_SW_BEACON_RESP (10) in the timer + * configuration we need to make sure it is bigger than that. */ + if (bc_tsf == -1) { /* * no beacons received, called internally. @@ -2493,7 +2077,6 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : ""); } - /** * ath5k_beacon_config - Configure the beacon queues and interrupts * @@ -2572,186 +2155,37 @@ static void ath5k_tasklet_beacon(unsigned long data) * Interrupt handling * \********************/ -static int -ath5k_init(struct ath5k_softc *sc) +static void +ath5k_intr_calibration_poll(struct ath5k_hw *ah) { - struct ath5k_hw *ah = sc->ah; - int ret, i; - - mutex_lock(&sc->lock); - - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); - - /* - * Stop anything previously setup. This is safe - * no matter this is the first time through or not. - */ - ath5k_stop_locked(sc); - - /* - * The basic interface to setting the hardware in a good - * state is ``reset''. On return the hardware is known to - * be powered up and with interrupts disabled. This must - * be followed by initialization of the appropriate bits - * and then setup of the interrupt mask. - */ - sc->curchan = sc->hw->conf.channel; - sc->curband = &sc->sbands[sc->curchan->band]; - sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | - AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | - AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; - - ret = ath5k_reset(sc, NULL); - if (ret) - goto done; - - ath5k_rfkill_hw_start(ah); - - /* - * Reset the key cache since some parts do not reset the - * contents on initial power up or resume from suspend. - */ - for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) - ath5k_hw_reset_key(ah, i); + if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) && + !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL)) { + /* run ANI only when full calibration is not active */ + ah->ah_cal_next_ani = jiffies + + msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI); + tasklet_schedule(&ah->ah_sc->ani_tasklet); - ath5k_hw_set_ack_bitrate_high(ah, true); - ret = 0; -done: - mmiowb(); - mutex_unlock(&sc->lock); - return ret; + } else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) { + ah->ah_cal_next_full = jiffies + + msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL); + tasklet_schedule(&ah->ah_sc->calib); + } + /* we could use SWI to generate enough interrupts to meet our + * calibration interval requirements, if necessary: + * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ } -static int -ath5k_stop_locked(struct ath5k_softc *sc) +static irqreturn_t +ath5k_intr(int irq, void *dev_id) { + struct ath5k_softc *sc = dev_id; struct ath5k_hw *ah = sc->ah; + enum ath5k_int status; + unsigned int counter = 1000; - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n", - test_bit(ATH_STAT_INVALID, sc->status)); - - /* - * Shutdown the hardware and driver: - * stop output from above - * disable interrupts - * turn off timers - * turn off the radio - * clear transmit machinery - * clear receive machinery - * drain and release tx queues - * reclaim beacon resources - * power down hardware - * - * Note that some of this work is not possible if the - * hardware is gone (invalid). - */ - ieee80211_stop_queues(sc->hw); - - if (!test_bit(ATH_STAT_INVALID, sc->status)) { - ath5k_led_off(sc); - ath5k_hw_set_imr(ah, 0); - synchronize_irq(sc->pdev->irq); - } - ath5k_txq_cleanup(sc); - if (!test_bit(ATH_STAT_INVALID, sc->status)) { - ath5k_rx_stop(sc); - ath5k_hw_phy_disable(ah); - } - - return 0; -} - -static void stop_tasklets(struct ath5k_softc *sc) -{ - tasklet_kill(&sc->rxtq); - tasklet_kill(&sc->txtq); - tasklet_kill(&sc->calib); - tasklet_kill(&sc->beacontq); - tasklet_kill(&sc->ani_tasklet); -} - -/* - * Stop the device, grabbing the top-level lock to protect - * against concurrent entry through ath5k_init (which can happen - * if another thread does a system call and the thread doing the - * stop is preempted). - */ -static int -ath5k_stop_hw(struct ath5k_softc *sc) -{ - int ret; - - mutex_lock(&sc->lock); - ret = ath5k_stop_locked(sc); - if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { - /* - * Don't set the card in full sleep mode! - * - * a) When the device is in this state it must be carefully - * woken up or references to registers in the PCI clock - * domain may freeze the bus (and system). This varies - * by chip and is mostly an issue with newer parts - * (madwifi sources mentioned srev >= 0x78) that go to - * sleep more quickly. - * - * b) On older chips full sleep results a weird behaviour - * during wakeup. I tested various cards with srev < 0x78 - * and they don't wake up after module reload, a second - * module reload is needed to bring the card up again. - * - * Until we figure out what's going on don't enable - * full chip reset on any chip (this is what Legacy HAL - * and Sam's HAL do anyway). Instead Perform a full reset - * on the device (same as initial state after attach) and - * leave it idle (keep MAC/BB on warm reset) */ - ret = ath5k_hw_on_hold(sc->ah); - - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, - "putting device to sleep\n"); - } - ath5k_txbuf_free_skb(sc, sc->bbuf); - - mmiowb(); - mutex_unlock(&sc->lock); - - stop_tasklets(sc); - - ath5k_rfkill_hw_stop(sc->ah); - - return ret; -} - -static void -ath5k_intr_calibration_poll(struct ath5k_hw *ah) -{ - if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) && - !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL)) { - /* run ANI only when full calibration is not active */ - ah->ah_cal_next_ani = jiffies + - msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI); - tasklet_schedule(&ah->ah_sc->ani_tasklet); - - } else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) { - ah->ah_cal_next_full = jiffies + - msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL); - tasklet_schedule(&ah->ah_sc->calib); - } - /* we could use SWI to generate enough interrupts to meet our - * calibration interval requirements, if necessary: - * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ -} - -static irqreturn_t -ath5k_intr(int irq, void *dev_id) -{ - struct ath5k_softc *sc = dev_id; - struct ath5k_hw *ah = sc->ah; - enum ath5k_int status; - unsigned int counter = 1000; - - if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) || - !ath5k_hw_is_intr_pending(ah))) - return IRQ_NONE; + if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) || + !ath5k_hw_is_intr_pending(ah))) + return IRQ_NONE; do { ath5k_hw_get_isr(ah, &status); /* NB: clears IRQ too */ @@ -2857,14 +2291,13 @@ ath5k_tasklet_calibrate(unsigned long data) sc->curchan->center_freq)); /* Noise floor calibration interrupts rx/tx path while I/Q calibration - * doesn't. We stop the queues so that calibration doesn't interfere - * with TX and don't run it as often */ + * doesn't. + * TODO: We should stop TX here, so that it doesn't interfere. + * Note that stopping the queues is not enough to stop TX! */ if (time_is_before_eq_jiffies(ah->ah_cal_next_nf)) { ah->ah_cal_next_nf = jiffies + msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_NF); - ieee80211_stop_queues(sc->hw); ath5k_hw_update_noise_floor(ah); - ieee80211_wake_queues(sc->hw); } ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; @@ -2883,671 +2316,1439 @@ ath5k_tasklet_ani(unsigned long data) } -/********************\ -* Mac80211 functions * -\********************/ - -static int -ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +static void +ath5k_tx_complete_poll_work(struct work_struct *work) { - struct ath5k_softc *sc = hw->priv; + struct ath5k_softc *sc = container_of(work, struct ath5k_softc, + tx_complete_work.work); + struct ath5k_txq *txq; + int i; + bool needreset = false; + + for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) { + if (sc->txqs[i].setup) { + txq = &sc->txqs[i]; + spin_lock_bh(&txq->lock); + if (txq->txq_len > 1) { + if (txq->txq_poll_mark) { + ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, + "TX queue stuck %d\n", + txq->qnum); + needreset = true; + txq->txq_stuck++; + spin_unlock_bh(&txq->lock); + break; + } else { + txq->txq_poll_mark = true; + } + } + spin_unlock_bh(&txq->lock); + } + } - return ath5k_tx_queue(hw, skb, sc->txq); + if (needreset) { + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "TX queues stuck, resetting\n"); + ath5k_reset(sc, sc->curchan); + } + + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, + msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); } -static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, - struct ath5k_txq *txq) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_buf *bf; - unsigned long flags; - int padsize; - ath5k_debug_dump_skb(sc, skb, "TX ", 1); +/*************************\ +* Initialization routines * +\*************************/ + +static int +ath5k_stop_locked(struct ath5k_softc *sc) +{ + struct ath5k_hw *ah = sc->ah; - if (sc->opmode == NL80211_IFTYPE_MONITOR) - ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n", + test_bit(ATH_STAT_INVALID, sc->status)); /* - * the hardware expects the header padded to 4 byte boundaries - * if this is not the case we add the padding after the header + * Shutdown the hardware and driver: + * stop output from above + * disable interrupts + * turn off timers + * turn off the radio + * clear transmit machinery + * clear receive machinery + * drain and release tx queues + * reclaim beacon resources + * power down hardware + * + * Note that some of this work is not possible if the + * hardware is gone (invalid). */ - padsize = ath5k_add_padding(skb); - if (padsize < 0) { - ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" - " headroom to pad"); - goto drop_packet; - } + ieee80211_stop_queues(sc->hw); - spin_lock_irqsave(&sc->txbuflock, flags); - if (list_empty(&sc->txbuf)) { - ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); - spin_unlock_irqrestore(&sc->txbuflock, flags); - ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); - goto drop_packet; + if (!test_bit(ATH_STAT_INVALID, sc->status)) { + ath5k_led_off(sc); + ath5k_hw_set_imr(ah, 0); + synchronize_irq(sc->pdev->irq); } - bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list); - list_del(&bf->list); - sc->txbuf_len--; - if (list_empty(&sc->txbuf)) - ieee80211_stop_queues(hw); - spin_unlock_irqrestore(&sc->txbuflock, flags); - - bf->skb = skb; - - if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { - bf->skb = NULL; - spin_lock_irqsave(&sc->txbuflock, flags); - list_add_tail(&bf->list, &sc->txbuf); - sc->txbuf_len++; - spin_unlock_irqrestore(&sc->txbuflock, flags); - goto drop_packet; + ath5k_txq_cleanup(sc); + if (!test_bit(ATH_STAT_INVALID, sc->status)) { + ath5k_rx_stop(sc); + ath5k_hw_phy_disable(ah); } - return NETDEV_TX_OK; -drop_packet: - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; + return 0; } -/* - * Reset the hardware. If chan is not NULL, then also pause rx/tx - * and change to the given channel. - * - * This should be called with sc->lock. - */ static int -ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) +ath5k_init(struct ath5k_softc *sc) { struct ath5k_hw *ah = sc->ah; - int ret; - - ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); + struct ath_common *common = ath5k_hw_common(ah); + int ret, i; - ath5k_hw_set_imr(ah, 0); - synchronize_irq(sc->pdev->irq); - stop_tasklets(sc); + mutex_lock(&sc->lock); - if (chan) { - ath5k_txq_cleanup(sc); - ath5k_rx_stop(sc); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode); - sc->curchan = chan; - sc->curband = &sc->sbands[chan->band]; - } - ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL); - if (ret) { - ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); - goto err; - } + /* + * Stop anything previously setup. This is safe + * no matter this is the first time through or not. + */ + ath5k_stop_locked(sc); - ret = ath5k_rx_start(sc); - if (ret) { - ATH5K_ERR(sc, "can't start recv logic\n"); - goto err; - } + /* + * The basic interface to setting the hardware in a good + * state is ``reset''. On return the hardware is known to + * be powered up and with interrupts disabled. This must + * be followed by initialization of the appropriate bits + * and then setup of the interrupt mask. + */ + sc->curchan = sc->hw->conf.channel; + sc->curband = &sc->sbands[sc->curchan->band]; + sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | + AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | + AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; - ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); + ret = ath5k_reset(sc, NULL); + if (ret) + goto done; - ah->ah_cal_next_full = jiffies; - ah->ah_cal_next_ani = jiffies; - ah->ah_cal_next_nf = jiffies; + ath5k_rfkill_hw_start(ah); /* - * Change channels and update the h/w rate map if we're switching; - * e.g. 11a to 11b/g. - * - * We may be doing a reset in response to an ioctl that changes the - * channel so update any state that might change as a result. - * - * XXX needed? + * Reset the key cache since some parts do not reset the + * contents on initial power up or resume from suspend. */ -/* ath5k_chan_change(sc, c); */ + for (i = 0; i < common->keymax; i++) + ath_hw_keyreset(common, (u16) i); - ath5k_beacon_config(sc); - /* intrs are enabled by ath5k_beacon_config */ + ath5k_hw_set_ack_bitrate_high(ah, true); - ieee80211_wake_queues(sc->hw); + for (i = 0; i < ARRAY_SIZE(sc->bslot); i++) + sc->bslot[i] = NULL; - return 0; -err: - return ret; -} - -static void ath5k_reset_work(struct work_struct *work) -{ - struct ath5k_softc *sc = container_of(work, struct ath5k_softc, - reset_work); - - mutex_lock(&sc->lock); - ath5k_reset(sc, sc->curchan); + ret = 0; +done: + mmiowb(); mutex_unlock(&sc->lock); -} -static int ath5k_start(struct ieee80211_hw *hw) -{ - return ath5k_init(hw->priv); + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, + msecs_to_jiffies(ATH5K_TX_COMPLETE_POLL_INT)); + + return ret; } -static void ath5k_stop(struct ieee80211_hw *hw) +static void stop_tasklets(struct ath5k_softc *sc) { - ath5k_stop_hw(hw->priv); + tasklet_kill(&sc->rxtq); + tasklet_kill(&sc->txtq); + tasklet_kill(&sc->calib); + tasklet_kill(&sc->beacontq); + tasklet_kill(&sc->ani_tasklet); } -static int ath5k_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +/* + * Stop the device, grabbing the top-level lock to protect + * against concurrent entry through ath5k_init (which can happen + * if another thread does a system call and the thread doing the + * stop is preempted). + */ +static int +ath5k_stop_hw(struct ath5k_softc *sc) { - struct ath5k_softc *sc = hw->priv; int ret; mutex_lock(&sc->lock); - if (sc->vif) { - ret = 0; - goto end; - } - - sc->vif = vif; + ret = ath5k_stop_locked(sc); + if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) { + /* + * Don't set the card in full sleep mode! + * + * a) When the device is in this state it must be carefully + * woken up or references to registers in the PCI clock + * domain may freeze the bus (and system). This varies + * by chip and is mostly an issue with newer parts + * (madwifi sources mentioned srev >= 0x78) that go to + * sleep more quickly. + * + * b) On older chips full sleep results a weird behaviour + * during wakeup. I tested various cards with srev < 0x78 + * and they don't wake up after module reload, a second + * module reload is needed to bring the card up again. + * + * Until we figure out what's going on don't enable + * full chip reset on any chip (this is what Legacy HAL + * and Sam's HAL do anyway). Instead Perform a full reset + * on the device (same as initial state after attach) and + * leave it idle (keep MAC/BB on warm reset) */ + ret = ath5k_hw_on_hold(sc->ah); - switch (vif->type) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_MONITOR: - sc->opmode = vif->type; - break; - default: - ret = -EOPNOTSUPP; - goto end; + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, + "putting device to sleep\n"); } - ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); - - ath5k_hw_set_lladdr(sc->ah, vif->addr); - ath5k_mode_setup(sc); - - ret = 0; -end: + mmiowb(); mutex_unlock(&sc->lock); - return ret; -} -static void -ath5k_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct ath5k_softc *sc = hw->priv; - u8 mac[ETH_ALEN] = {}; + stop_tasklets(sc); - mutex_lock(&sc->lock); - if (sc->vif != vif) - goto end; + cancel_delayed_work_sync(&sc->tx_complete_work); - ath5k_hw_set_lladdr(sc->ah, mac); - sc->vif = NULL; -end: - mutex_unlock(&sc->lock); + ath5k_rfkill_hw_stop(sc->ah); + + return ret; } /* - * TODO: Phy disable/diversity etc + * Reset the hardware. If chan is not NULL, then also pause rx/tx + * and change to the given channel. + * + * This should be called with sc->lock. */ static int -ath5k_config(struct ieee80211_hw *hw, u32 changed) +ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) { - struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; - struct ieee80211_conf *conf = &hw->conf; - int ret = 0; + int ret; - mutex_lock(&sc->lock); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ret = ath5k_chan_set(sc, conf->channel); - if (ret < 0) - goto unlock; - } + ath5k_hw_set_imr(ah, 0); + synchronize_irq(sc->pdev->irq); + stop_tasklets(sc); - if ((changed & IEEE80211_CONF_CHANGE_POWER) && - (sc->power_level != conf->power_level)) { - sc->power_level = conf->power_level; + if (chan) { + ath5k_txq_cleanup(sc); + ath5k_rx_stop(sc); - /* Half dB steps */ - ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); + sc->curchan = chan; + sc->curband = &sc->sbands[chan->band]; + } + ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL); + if (ret) { + ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); + goto err; } - /* TODO: - * 1) Move this on config_interface and handle each case - * separately eg. when we have only one STA vif, use - * AR5K_ANTMODE_SINGLE_AP - * - * 2) Allow the user to change antenna mode eg. when only - * one antenna is present + ret = ath5k_rx_start(sc); + if (ret) { + ATH5K_ERR(sc, "can't start recv logic\n"); + goto err; + } + + ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); + + ah->ah_cal_next_full = jiffies; + ah->ah_cal_next_ani = jiffies; + ah->ah_cal_next_nf = jiffies; + + /* + * Change channels and update the h/w rate map if we're switching; + * e.g. 11a to 11b/g. * - * 3) Allow the user to set default/tx antenna when possible + * We may be doing a reset in response to an ioctl that changes the + * channel so update any state that might change as a result. * - * 4) Default mode should handle 90% of the cases, together - * with fixed a/b and single AP modes we should be able to - * handle 99%. Sectored modes are extreme cases and i still - * haven't found a usage for them. If we decide to support them, - * then we must allow the user to set how many tx antennas we - * have available + * XXX needed? */ - ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); +/* ath5k_chan_change(sc, c); */ -unlock: - mutex_unlock(&sc->lock); + ath5k_beacon_config(sc); + /* intrs are enabled by ath5k_beacon_config */ + + ieee80211_wake_queues(sc->hw); + + return 0; +err: return ret; } -static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, - struct netdev_hw_addr_list *mc_list) +static void ath5k_reset_work(struct work_struct *work) { - u32 mfilt[2], val; - u8 pos; - struct netdev_hw_addr *ha; - - mfilt[0] = 0; - mfilt[1] = 1; - - netdev_hw_addr_list_for_each(ha, mc_list) { - /* calculate XOR of eight 6-bit values */ - val = get_unaligned_le32(ha->addr + 0); - pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; - val = get_unaligned_le32(ha->addr + 3); - pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; - pos &= 0x3f; - mfilt[pos / 32] |= (1 << (pos % 32)); - /* XXX: we might be able to just do this instead, - * but not sure, needs testing, if we do use this we'd - * neet to inform below to not reset the mcast */ - /* ath5k_hw_set_mcast_filterindex(ah, - * ha->addr[5]); */ - } + struct ath5k_softc *sc = container_of(work, struct ath5k_softc, + reset_work); - return ((u64)(mfilt[1]) << 32) | mfilt[0]; + mutex_lock(&sc->lock); + ath5k_reset(sc, sc->curchan); + mutex_unlock(&sc->lock); } -#define SUPPORTED_FIF_FLAGS \ - FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ - FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ - FIF_BCN_PRBRESP_PROMISC -/* - * o always accept unicast, broadcast, and multicast traffic - * o multicast traffic for all BSSIDs will be enabled if mac80211 - * says it should be - * o maintain current state of phy ofdm or phy cck error reception. - * If the hardware detects any of these type of errors then - * ath5k_hw_get_rx_filter() will pass to us the respective - * hardware filters to be able to receive these type of frames. - * o probe request frames are accepted only when operating in - * hostap, adhoc, or monitor modes - * o enable promiscuous mode according to the interface state - * o accept beacons: - * - when operating in adhoc mode so the 802.11 layer creates - * node table entries for peers, - * - when operating in station mode for collecting rssi data when - * the station is otherwise quiet, or - * - when scanning - */ -static void ath5k_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *new_flags, - u64 multicast) +static int +ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) { struct ath5k_softc *sc = hw->priv; struct ath5k_hw *ah = sc->ah; - u32 mfilt[2], rfilt; + struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah); + struct ath5k_txq *txq; + u8 mac[ETH_ALEN] = {}; + int ret; - mutex_lock(&sc->lock); + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device); - mfilt[0] = multicast; - mfilt[1] = multicast >> 32; + /* + * Check if the MAC has multi-rate retry support. + * We do this by trying to setup a fake extended + * descriptor. MACs that don't have support will + * return false w/o doing anything. MACs that do + * support it will return true w/o doing anything. + */ + ret = ath5k_hw_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); - /* Only deal with supported flags */ - changed_flags &= SUPPORTED_FIF_FLAGS; - *new_flags &= SUPPORTED_FIF_FLAGS; + if (ret < 0) + goto err; + if (ret > 0) + __set_bit(ATH_STAT_MRRETRY, sc->status); - /* If HW detects any phy or radar errors, leave those filters on. - * Also, always enable Unicast, Broadcasts and Multicast - * XXX: move unicast, bssid broadcasts and multicast to mac80211 */ - rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) | - (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | - AR5K_RX_FILTER_MCAST); + /* + * Collect the channel list. The 802.11 layer + * is resposible for filtering this list based + * on settings like the phy mode and regulatory + * domain restrictions. + */ + ret = ath5k_setup_bands(hw); + if (ret) { + ATH5K_ERR(sc, "can't get channels\n"); + goto err; + } - if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { - if (*new_flags & FIF_PROMISC_IN_BSS) { - __set_bit(ATH_STAT_PROMISC, sc->status); - } else { - __clear_bit(ATH_STAT_PROMISC, sc->status); - } + /* NB: setup here so ath5k_rate_update is happy */ + if (test_bit(AR5K_MODE_11A, ah->ah_modes)) + ath5k_setcurmode(sc, AR5K_MODE_11A); + else + ath5k_setcurmode(sc, AR5K_MODE_11B); + + /* + * Allocate tx+rx descriptors and populate the lists. + */ + ret = ath5k_desc_alloc(sc, pdev); + if (ret) { + ATH5K_ERR(sc, "can't allocate descriptors\n"); + goto err; } - if (test_bit(ATH_STAT_PROMISC, sc->status)) - rfilt |= AR5K_RX_FILTER_PROM; + /* + * Allocate hardware transmit queues: one queue for + * beacon frames and one data queue for each QoS + * priority. Note that hw functions handle resetting + * these queues at the needed time. + */ + ret = ath5k_beaconq_setup(ah); + if (ret < 0) { + ATH5K_ERR(sc, "can't setup a beacon xmit queue\n"); + goto err_desc; + } + sc->bhalq = ret; + sc->cabq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_CAB, 0); + if (IS_ERR(sc->cabq)) { + ATH5K_ERR(sc, "can't setup cab queue\n"); + ret = PTR_ERR(sc->cabq); + goto err_bhal; + } - /* Note, AR5K_RX_FILTER_MCAST is already enabled */ - if (*new_flags & FIF_ALLMULTI) { - mfilt[0] = ~0; - mfilt[1] = ~0; + /* This order matches mac80211's queue priority, so we can + * directly use the mac80211 queue number without any mapping */ + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VO); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_VI); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BE); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; + } + txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK); + if (IS_ERR(txq)) { + ATH5K_ERR(sc, "can't setup xmit queue\n"); + ret = PTR_ERR(txq); + goto err_queues; } + hw->queues = 4; - /* This is the best we can do */ - if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)) - rfilt |= AR5K_RX_FILTER_PHYERR; + tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc); + tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); + tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); + tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); + tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); - /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons - * and probes for any BSSID, this needs testing */ - if (*new_flags & FIF_BCN_PRBRESP_PROMISC) - rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ; + INIT_WORK(&sc->reset_work, ath5k_reset_work); + INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work); - /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not - * set we should only pass on control frames for this - * station. This needs testing. I believe right now this - * enables *all* control frames, which is OK.. but - * but we should see if we can improve on granularity */ - if (*new_flags & FIF_CONTROL) - rfilt |= AR5K_RX_FILTER_CONTROL; + ret = ath5k_eeprom_read_mac(ah, mac); + if (ret) { + ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", + sc->pdev->device); + goto err_queues; + } - /* Additional settings per mode -- this is per ath5k */ + SET_IEEE80211_PERM_ADDR(hw, mac); + memcpy(&sc->lladdr, mac, ETH_ALEN); + /* All MAC address bits matter for ACKs */ + ath5k_update_bssid_mask_and_opmode(sc, NULL); - /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ + regulatory->current_rd = ah->ah_capabilities.cap_eeprom.ee_regdomain; + ret = ath_regd_init(regulatory, hw->wiphy, ath5k_reg_notifier); + if (ret) { + ATH5K_ERR(sc, "can't initialize regulatory system\n"); + goto err_queues; + } - switch (sc->opmode) { - case NL80211_IFTYPE_MESH_POINT: - case NL80211_IFTYPE_MONITOR: - rfilt |= AR5K_RX_FILTER_CONTROL | - AR5K_RX_FILTER_BEACON | - AR5K_RX_FILTER_PROBEREQ | - AR5K_RX_FILTER_PROM; - break; + ret = ieee80211_register_hw(hw); + if (ret) { + ATH5K_ERR(sc, "can't register ieee80211 hw\n"); + goto err_queues; + } + + if (!ath_is_world_regd(regulatory)) + regulatory_hint(hw->wiphy, regulatory->alpha2); + + ath5k_init_leds(sc); + + ath5k_sysfs_register(sc); + + return 0; +err_queues: + ath5k_txq_release(sc); +err_bhal: + ath5k_hw_release_tx_queue(ah, sc->bhalq); +err_desc: + ath5k_desc_free(sc, pdev); +err: + return ret; +} + +static void +ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + + /* + * NB: the order of these is important: + * o call the 802.11 layer before detaching ath5k_hw to + * ensure callbacks into the driver to delete global + * key cache entries can be handled + * o reclaim the tx queue data structures after calling + * the 802.11 layer as we'll get called back to reclaim + * node state and potentially want to use them + * o to cleanup the tx queues the hal is called, so detach + * it last + * XXX: ??? detach ath5k_hw ??? + * Other than that, it's straightforward... + */ + ieee80211_unregister_hw(hw); + ath5k_desc_free(sc, pdev); + ath5k_txq_release(sc); + ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); + ath5k_unregister_leds(sc); + + ath5k_sysfs_unregister(sc); + /* + * NB: can't reclaim these until after ieee80211_ifdetach + * returns because we'll get called back to reclaim node + * state and potentially want to use them. + */ +} + +/********************\ +* Mac80211 functions * +\********************/ + +static int +ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct ath5k_softc *sc = hw->priv; + u16 qnum = skb_get_queue_mapping(skb); + + if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) { + dev_kfree_skb_any(skb); + return 0; + } + + return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]); +} + +static int ath5k_start(struct ieee80211_hw *hw) +{ + return ath5k_init(hw->priv); +} + +static void ath5k_stop(struct ieee80211_hw *hw) +{ + ath5k_stop_hw(hw->priv); +} + +static int ath5k_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct ath5k_softc *sc = hw->priv; + int ret; + struct ath5k_vif *avf = (void *)vif->drv_priv; + + mutex_lock(&sc->lock); + + if ((vif->type == NL80211_IFTYPE_AP || + vif->type == NL80211_IFTYPE_ADHOC) + && (sc->num_ap_vifs + sc->num_adhoc_vifs) >= ATH_BCBUF) { + ret = -ELNRNG; + goto end; + } + + /* Don't allow other interfaces if one ad-hoc is configured. + * TODO: Fix the problems with ad-hoc and multiple other interfaces. + * We would need to operate the HW in ad-hoc mode to allow TSF updates + * for the IBSS, but this breaks with additional AP or STA interfaces + * at the moment. */ + if (sc->num_adhoc_vifs || + (sc->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) { + ATH5K_ERR(sc, "Only one single ad-hoc interface is allowed.\n"); + ret = -ELNRNG; + goto end; + } + + switch (vif->type) { case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_ADHOC: - rfilt |= AR5K_RX_FILTER_PROBEREQ | - AR5K_RX_FILTER_BEACON; + case NL80211_IFTYPE_MESH_POINT: + avf->opmode = vif->type; break; - case NL80211_IFTYPE_STATION: - if (sc->assoc) - rfilt |= AR5K_RX_FILTER_BEACON; default: - break; + ret = -EOPNOTSUPP; + goto end; } - /* Set filters */ - ath5k_hw_set_rx_filter(ah, rfilt); + sc->nvifs++; + ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", avf->opmode); - /* Set multicast bits */ - ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); - /* Set the cached hw filter flags, this will alter actually - * be set in HW */ - sc->filter_flags = rfilt; + /* Assign the vap/adhoc to a beacon xmit slot. */ + if ((avf->opmode == NL80211_IFTYPE_AP) || + (avf->opmode == NL80211_IFTYPE_ADHOC)) { + int slot; + + WARN_ON(list_empty(&sc->bcbuf)); + avf->bbuf = list_first_entry(&sc->bcbuf, struct ath5k_buf, + list); + list_del(&avf->bbuf->list); + + avf->bslot = 0; + for (slot = 0; slot < ATH_BCBUF; slot++) { + if (!sc->bslot[slot]) { + avf->bslot = slot; + break; + } + } + BUG_ON(sc->bslot[avf->bslot] != NULL); + sc->bslot[avf->bslot] = vif; + if (avf->opmode == NL80211_IFTYPE_AP) + sc->num_ap_vifs++; + else + sc->num_adhoc_vifs++; + } + + /* Any MAC address is fine, all others are included through the + * filter. + */ + memcpy(&sc->lladdr, vif->addr, ETH_ALEN); + ath5k_hw_set_lladdr(sc->ah, vif->addr); + memcpy(&avf->lladdr, vif->addr, ETH_ALEN); + + ath5k_mode_setup(sc, vif); + + ret = 0; +end: mutex_unlock(&sc->lock); + return ret; } -static int -ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) +static void +ath5k_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - int ret = 0; + struct ath5k_vif *avf = (void *)vif->drv_priv; + unsigned int i; - if (modparam_nohwcrypt) - return -EOPNOTSUPP; + mutex_lock(&sc->lock); + sc->nvifs--; + + if (avf->bbuf) { + ath5k_txbuf_free_skb(sc, avf->bbuf); + list_add_tail(&avf->bbuf->list, &sc->bcbuf); + for (i = 0; i < ATH_BCBUF; i++) { + if (sc->bslot[i] == vif) { + sc->bslot[i] = NULL; + break; + } + } + avf->bbuf = NULL; + } + if (avf->opmode == NL80211_IFTYPE_AP) + sc->num_ap_vifs--; + else if (avf->opmode == NL80211_IFTYPE_ADHOC) + sc->num_adhoc_vifs--; - if (sc->opmode == NL80211_IFTYPE_AP) - return -EOPNOTSUPP; + ath5k_update_bssid_mask_and_opmode(sc, NULL); + mutex_unlock(&sc->lock); +} - switch (key->alg) { - case ALG_WEP: - case ALG_TKIP: - break; - case ALG_CCMP: - if (sc->ah->ah_aes_support) - break; +/* + * TODO: Phy disable/diversity etc + */ +static int +ath5k_config(struct ieee80211_hw *hw, u32 changed) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ieee80211_conf *conf = &hw->conf; + int ret = 0; + + mutex_lock(&sc->lock); + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + ret = ath5k_chan_set(sc, conf->channel); + if (ret < 0) + goto unlock; + } + + if ((changed & IEEE80211_CONF_CHANGE_POWER) && + (sc->power_level != conf->power_level)) { + sc->power_level = conf->power_level; + + /* Half dB steps */ + ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2)); + } + + /* TODO: + * 1) Move this on config_interface and handle each case + * separately eg. when we have only one STA vif, use + * AR5K_ANTMODE_SINGLE_AP + * + * 2) Allow the user to change antenna mode eg. when only + * one antenna is present + * + * 3) Allow the user to set default/tx antenna when possible + * + * 4) Default mode should handle 90% of the cases, together + * with fixed a/b and single AP modes we should be able to + * handle 99%. Sectored modes are extreme cases and i still + * haven't found a usage for them. If we decide to support them, + * then we must allow the user to set how many tx antennas we + * have available + */ + ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); + +unlock: + mutex_unlock(&sc->lock); + return ret; +} + +static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, + struct netdev_hw_addr_list *mc_list) +{ + u32 mfilt[2], val; + u8 pos; + struct netdev_hw_addr *ha; + + mfilt[0] = 0; + mfilt[1] = 1; + + netdev_hw_addr_list_for_each(ha, mc_list) { + /* calculate XOR of eight 6-bit values */ + val = get_unaligned_le32(ha->addr + 0); + pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; + val = get_unaligned_le32(ha->addr + 3); + pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; + pos &= 0x3f; + mfilt[pos / 32] |= (1 << (pos % 32)); + /* XXX: we might be able to just do this instead, + * but not sure, needs testing, if we do use this we'd + * neet to inform below to not reset the mcast */ + /* ath5k_hw_set_mcast_filterindex(ah, + * ha->addr[5]); */ + } + + return ((u64)(mfilt[1]) << 32) | mfilt[0]; +} + +static bool ath_any_vif_assoc(struct ath5k_softc *sc) +{ + struct ath_vif_iter_data iter_data; + iter_data.hw_macaddr = NULL; + iter_data.any_assoc = false; + iter_data.need_set_hw_addr = false; + iter_data.found_active = true; + + ieee80211_iterate_active_interfaces_atomic(sc->hw, ath_vif_iter, + &iter_data); + return iter_data.any_assoc; +} + +#define SUPPORTED_FIF_FLAGS \ + FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \ + FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \ + FIF_BCN_PRBRESP_PROMISC +/* + * o always accept unicast, broadcast, and multicast traffic + * o multicast traffic for all BSSIDs will be enabled if mac80211 + * says it should be + * o maintain current state of phy ofdm or phy cck error reception. + * If the hardware detects any of these type of errors then + * ath5k_hw_get_rx_filter() will pass to us the respective + * hardware filters to be able to receive these type of frames. + * o probe request frames are accepted only when operating in + * hostap, adhoc, or monitor modes + * o enable promiscuous mode according to the interface state + * o accept beacons: + * - when operating in adhoc mode so the 802.11 layer creates + * node table entries for peers, + * - when operating in station mode for collecting rssi data when + * the station is otherwise quiet, or + * - when scanning + */ +static void ath5k_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, + u64 multicast) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + u32 mfilt[2], rfilt; + + mutex_lock(&sc->lock); + + mfilt[0] = multicast; + mfilt[1] = multicast >> 32; + + /* Only deal with supported flags */ + changed_flags &= SUPPORTED_FIF_FLAGS; + *new_flags &= SUPPORTED_FIF_FLAGS; + + /* If HW detects any phy or radar errors, leave those filters on. + * Also, always enable Unicast, Broadcasts and Multicast + * XXX: move unicast, bssid broadcasts and multicast to mac80211 */ + rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) | + (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | + AR5K_RX_FILTER_MCAST); + + if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) { + if (*new_flags & FIF_PROMISC_IN_BSS) { + __set_bit(ATH_STAT_PROMISC, sc->status); + } else { + __clear_bit(ATH_STAT_PROMISC, sc->status); + } + } + + if (test_bit(ATH_STAT_PROMISC, sc->status)) + rfilt |= AR5K_RX_FILTER_PROM; + + /* Note, AR5K_RX_FILTER_MCAST is already enabled */ + if (*new_flags & FIF_ALLMULTI) { + mfilt[0] = ~0; + mfilt[1] = ~0; + } + + /* This is the best we can do */ + if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL)) + rfilt |= AR5K_RX_FILTER_PHYERR; + + /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons + * and probes for any BSSID */ + if ((*new_flags & FIF_BCN_PRBRESP_PROMISC) || (sc->nvifs > 1)) + rfilt |= AR5K_RX_FILTER_BEACON; + + /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not + * set we should only pass on control frames for this + * station. This needs testing. I believe right now this + * enables *all* control frames, which is OK.. but + * but we should see if we can improve on granularity */ + if (*new_flags & FIF_CONTROL) + rfilt |= AR5K_RX_FILTER_CONTROL; + + /* Additional settings per mode -- this is per ath5k */ + + /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ + + switch (sc->opmode) { + case NL80211_IFTYPE_MESH_POINT: + rfilt |= AR5K_RX_FILTER_CONTROL | + AR5K_RX_FILTER_BEACON | + AR5K_RX_FILTER_PROBEREQ | + AR5K_RX_FILTER_PROM; + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_ADHOC: + rfilt |= AR5K_RX_FILTER_PROBEREQ | + AR5K_RX_FILTER_BEACON; + break; + case NL80211_IFTYPE_STATION: + if (sc->assoc) + rfilt |= AR5K_RX_FILTER_BEACON; + default: + break; + } + + /* Set filters */ + ath5k_hw_set_rx_filter(ah, rfilt); + + /* Set multicast bits */ + ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]); + /* Set the cached hw filter flags, this will later actually + * be set in HW */ + sc->filter_flags = rfilt; + mutex_unlock(&sc->lock); +} + +static int +ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + int ret = 0; + + if (modparam_nohwcrypt) + return -EOPNOTSUPP; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + break; + case WLAN_CIPHER_SUITE_CCMP: + if (common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM) + break; return -EOPNOTSUPP; default: WARN_ON(1); return -EINVAL; } - mutex_lock(&sc->lock); + mutex_lock(&sc->lock); + + switch (cmd) { + case SET_KEY: + ret = ath_key_config(common, vif, sta, key); + if (ret >= 0) { + key->hw_key_idx = ret; + /* push IV and Michael MIC generation to stack */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + if (key->cipher == WLAN_CIPHER_SUITE_CCMP) + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; + ret = 0; + } + break; + case DISABLE_KEY: + ath_key_delete(common, key); + break; + default: + ret = -EINVAL; + } + + mmiowb(); + mutex_unlock(&sc->lock); + return ret; +} + +static int +ath5k_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + struct ath5k_softc *sc = hw->priv; + + /* Force update */ + ath5k_hw_update_mib_counters(sc->ah); + + stats->dot11ACKFailureCount = sc->stats.ack_fail; + stats->dot11RTSFailureCount = sc->stats.rts_fail; + stats->dot11RTSSuccessCount = sc->stats.rts_ok; + stats->dot11FCSErrorCount = sc->stats.fcs_error; + + return 0; +} + +static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct ath5k_softc *sc = hw->priv; + struct ieee80211_conf *conf = &hw->conf; + + if (idx != 0) + return -ENOENT; + + survey->channel = conf->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = sc->ah->ah_noise_floor; + + return 0; +} + +static u64 +ath5k_get_tsf(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + + return ath5k_hw_get_tsf64(sc->ah); +} + +static void +ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) +{ + struct ath5k_softc *sc = hw->priv; + + ath5k_hw_set_tsf64(sc->ah, tsf); +} + +static void +ath5k_reset_tsf(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + + /* + * in IBSS mode we need to update the beacon timers too. + * this will also reset the TSF if we call it with 0 + */ + if (sc->opmode == NL80211_IFTYPE_ADHOC) + ath5k_beacon_update_timers(sc, 0); + else + ath5k_hw_reset_tsf(sc->ah); +} + +static void +set_beacon_filter(struct ieee80211_hw *hw, bool enable) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + u32 rfilt; + rfilt = ath5k_hw_get_rx_filter(ah); + if (enable) + rfilt |= AR5K_RX_FILTER_BEACON; + else + rfilt &= ~AR5K_RX_FILTER_BEACON; + ath5k_hw_set_rx_filter(ah, rfilt); + sc->filter_flags = rfilt; +} + +static void ath5k_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) +{ + struct ath5k_vif *avf = (void *)vif->drv_priv; + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath_common *common = ath5k_hw_common(ah); + unsigned long flags; + + mutex_lock(&sc->lock); + + if (changes & BSS_CHANGED_BSSID) { + /* Cache for later use during resets */ + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + common->curaid = 0; + ath5k_hw_set_bssid(ah); + mmiowb(); + } + + if (changes & BSS_CHANGED_BEACON_INT) + sc->bintval = bss_conf->beacon_int; + + if (changes & BSS_CHANGED_ASSOC) { + avf->assoc = bss_conf->assoc; + if (bss_conf->assoc) + sc->assoc = bss_conf->assoc; + else + sc->assoc = ath_any_vif_assoc(sc); + + if (sc->opmode == NL80211_IFTYPE_STATION) + set_beacon_filter(hw, sc->assoc); + ath5k_hw_set_ledstate(sc->ah, sc->assoc ? + AR5K_LED_ASSOC : AR5K_LED_INIT); + if (bss_conf->assoc) { + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, + "Bss Info ASSOC %d, bssid: %pM\n", + bss_conf->aid, common->curbssid); + common->curaid = bss_conf->aid; + ath5k_hw_set_bssid(ah); + /* Once ANI is available you would start it here */ + } + } + + if (changes & BSS_CHANGED_BEACON) { + spin_lock_irqsave(&sc->block, flags); + ath5k_beacon_update(hw, vif); + spin_unlock_irqrestore(&sc->block, flags); + } + + if (changes & BSS_CHANGED_BEACON_ENABLED) + sc->enable_beacon = bss_conf->enable_beacon; + + if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | + BSS_CHANGED_BEACON_INT)) + ath5k_beacon_config(sc); + + mutex_unlock(&sc->lock); +} + +static void ath5k_sw_scan_start(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + if (!sc->assoc) + ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN); +} + +static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) +{ + struct ath5k_softc *sc = hw->priv; + ath5k_hw_set_ledstate(sc->ah, sc->assoc ? + AR5K_LED_ASSOC : AR5K_LED_INIT); +} + +/** + * ath5k_set_coverage_class - Set IEEE 802.11 coverage class + * + * @hw: struct ieee80211_hw pointer + * @coverage_class: IEEE 802.11 coverage class number + * + * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given + * coverage class. The values are persistent, they are restored after device + * reset. + */ +static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) +{ + struct ath5k_softc *sc = hw->priv; + + mutex_lock(&sc->lock); + ath5k_hw_set_coverage_class(sc->ah, coverage_class); + mutex_unlock(&sc->lock); +} + +static int ath5k_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *params) +{ + struct ath5k_softc *sc = hw->priv; + struct ath5k_hw *ah = sc->ah; + struct ath5k_txq_info qi; + int ret = 0; + + if (queue >= ah->ah_capabilities.cap_queues.q_tx_num) + return 0; + + mutex_lock(&sc->lock); + + ath5k_hw_get_tx_queueprops(ah, queue, &qi); + + qi.tqi_aifs = params->aifs; + qi.tqi_cw_min = params->cw_min; + qi.tqi_cw_max = params->cw_max; + qi.tqi_burst_time = params->txop; + + ATH5K_DBG(sc, ATH5K_DEBUG_ANY, + "Configure tx [queue %d], " + "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", + queue, params->aifs, params->cw_min, + params->cw_max, params->txop); + + if (ath5k_hw_set_tx_queueprops(ah, queue, &qi)) { + ATH5K_ERR(sc, + "Unable to update hardware queue %u!\n", queue); + ret = -EIO; + } else + ath5k_hw_reset_tx_queue(ah, queue); + + mutex_unlock(&sc->lock); + + return ret; +} + +static const struct ieee80211_ops ath5k_hw_ops = { + .tx = ath5k_tx, + .start = ath5k_start, + .stop = ath5k_stop, + .add_interface = ath5k_add_interface, + .remove_interface = ath5k_remove_interface, + .config = ath5k_config, + .prepare_multicast = ath5k_prepare_multicast, + .configure_filter = ath5k_configure_filter, + .set_key = ath5k_set_key, + .get_stats = ath5k_get_stats, + .get_survey = ath5k_get_survey, + .conf_tx = ath5k_conf_tx, + .get_tsf = ath5k_get_tsf, + .set_tsf = ath5k_set_tsf, + .reset_tsf = ath5k_reset_tsf, + .bss_info_changed = ath5k_bss_info_changed, + .sw_scan_start = ath5k_sw_scan_start, + .sw_scan_complete = ath5k_sw_scan_complete, + .set_coverage_class = ath5k_set_coverage_class, +}; + +/********************\ +* PCI Initialization * +\********************/ + +static int __devinit +ath5k_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + void __iomem *mem; + struct ath5k_softc *sc; + struct ath_common *common; + struct ieee80211_hw *hw; + int ret; + u8 csz; + + /* + * L0s needs to be disabled on all ath5k cards. + * + * For distributions shipping with CONFIG_PCIEASPM (this will be enabled + * by default in the future in 2.6.36) this will also mean both L1 and + * L0s will be disabled when a pre 1.1 PCIe device is detected. We do + * know L1 works correctly even for all ath5k pre 1.1 PCIe devices + * though but cannot currently undue the effect of a blacklist, for + * details you can read pcie_aspm_sanity_check() and see how it adjusts + * the device link capability. + * + * It may be possible in the future to implement some PCI API to allow + * drivers to override blacklists for pre 1.1 PCIe but for now it is + * best to accept that both L0s and L1 will be disabled completely for + * distributions shipping with CONFIG_PCIEASPM rather than having this + * issue present. Motivation for adding this new API will be to help + * with power consumption for some of these devices. + */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); + + ret = pci_enable_device(pdev); + if (ret) { + dev_err(&pdev->dev, "can't enable device\n"); + goto err; + } + + /* XXX 32-bit addressing only */ + ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&pdev->dev, "32-bit DMA not available\n"); + goto err_dis; + } + + /* + * Cache line size is used to size and align various + * structures used to communicate with the hardware. + */ + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); + if (csz == 0) { + /* + * Linux 2.4.18 (at least) writes the cache line size + * register as a 16-bit wide register which is wrong. + * We must have this setup properly for rx buffer + * DMA to work so force a reasonable value here if it + * comes up zero. + */ + csz = L1_CACHE_BYTES >> 2; + pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); + } + /* + * The default setting of latency timer yields poor results, + * set it to the value used by other systems. It may be worth + * tweaking this setting more. + */ + pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); + + /* Enable bus mastering */ + pci_set_master(pdev); + + /* + * Disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state. + */ + pci_write_config_byte(pdev, 0x41, 0); + + ret = pci_request_region(pdev, 0, "ath5k"); + if (ret) { + dev_err(&pdev->dev, "cannot reserve PCI memory region\n"); + goto err_dis; + } + + mem = pci_iomap(pdev, 0, 0); + if (!mem) { + dev_err(&pdev->dev, "cannot remap PCI memory region\n") ; + ret = -EIO; + goto err_reg; + } + + /* + * Allocate hw (mac80211 main struct) + * and hw->priv (driver private data) + */ + hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops); + if (hw == NULL) { + dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n"); + ret = -ENOMEM; + goto err_map; + } + + dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy)); + + /* Initialize driver private data */ + SET_IEEE80211_DEV(hw, &pdev->dev); + hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | + IEEE80211_HW_SIGNAL_DBM; + + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_MESH_POINT); + + hw->extra_tx_headroom = 2; + hw->channel_change_time = 5000; + sc = hw->priv; + sc->hw = hw; + sc->pdev = pdev; + + /* + * Mark the device as detached to avoid processing + * interrupts until setup is complete. + */ + __set_bit(ATH_STAT_INVALID, sc->status); + + sc->iobase = mem; /* So we can unmap it on detach */ + sc->opmode = NL80211_IFTYPE_STATION; + sc->bintval = 1000; + mutex_init(&sc->lock); + spin_lock_init(&sc->rxbuflock); + spin_lock_init(&sc->txbuflock); + spin_lock_init(&sc->block); + + /* Set private data */ + pci_set_drvdata(pdev, sc); + + /* Setup interrupt handler */ + ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc); + if (ret) { + ATH5K_ERR(sc, "request_irq failed\n"); + goto err_free; + } + + /* If we passed the test, malloc an ath5k_hw struct */ + sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); + if (!sc->ah) { + ret = -ENOMEM; + ATH5K_ERR(sc, "out of memory\n"); + goto err_irq; + } + + sc->ah->ah_sc = sc; + sc->ah->ah_iobase = sc->iobase; + common = ath5k_hw_common(sc->ah); + common->ops = &ath5k_common_ops; + common->ah = sc->ah; + common->hw = hw; + common->cachelsz = csz << 2; /* convert to bytes */ + + /* Initialize device */ + ret = ath5k_hw_attach(sc); + if (ret) { + goto err_free_ah; + } + + /* set up multi-rate retry capabilities */ + if (sc->ah->ah_version == AR5K_AR5212) { + hw->max_rates = 4; + hw->max_rate_tries = 11; + } + + hw->vif_data_size = sizeof(struct ath5k_vif); + + /* Finish private driver data initialization */ + ret = ath5k_attach(pdev, hw); + if (ret) + goto err_ah; + + ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", + ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), + sc->ah->ah_mac_srev, + sc->ah->ah_phy_revision); + + if (!sc->ah->ah_single_chip) { + /* Single chip radio (!RF5111) */ + if (sc->ah->ah_radio_5ghz_revision && + !sc->ah->ah_radio_2ghz_revision) { + /* No 5GHz support -> report 2GHz radio */ + if (!test_bit(AR5K_MODE_11A, + sc->ah->ah_capabilities.cap_mode)) { + ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + /* No 2GHz support (5110 and some + * 5Ghz only cards) -> report 5Ghz radio */ + } else if (!test_bit(AR5K_MODE_11B, + sc->ah->ah_capabilities.cap_mode)) { + ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + /* Multiband radio */ + } else { + ATH5K_INFO(sc, "RF%s multiband radio found" + " (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + } + } + /* Multi chip radio (RF5111 - RF2111) -> + * report both 2GHz/5GHz radios */ + else if (sc->ah->ah_radio_5ghz_revision && + sc->ah->ah_radio_2ghz_revision){ + ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_5ghz_revision), + sc->ah->ah_radio_5ghz_revision); + ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n", + ath5k_chip_name(AR5K_VERSION_RAD, + sc->ah->ah_radio_2ghz_revision), + sc->ah->ah_radio_2ghz_revision); + } + } + + ath5k_debug_init_device(sc); - switch (cmd) { - case SET_KEY: - ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, - sta ? sta->addr : NULL); - if (ret) { - ATH5K_ERR(sc, "can't set the key\n"); - goto unlock; - } - __set_bit(key->keyidx, common->keymap); - key->hw_key_idx = key->keyidx; - key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV | - IEEE80211_KEY_FLAG_GENERATE_MMIC); - break; - case DISABLE_KEY: - ath5k_hw_reset_key(sc->ah, key->keyidx); - __clear_bit(key->keyidx, common->keymap); - break; - default: - ret = -EINVAL; - goto unlock; - } + /* ready to process interrupts */ + __clear_bit(ATH_STAT_INVALID, sc->status); -unlock: - mmiowb(); - mutex_unlock(&sc->lock); + return 0; +err_ah: + ath5k_hw_detach(sc->ah); +err_free_ah: + kfree(sc->ah); +err_irq: + free_irq(pdev->irq, sc); +err_free: + ieee80211_free_hw(hw); +err_map: + pci_iounmap(pdev, mem); +err_reg: + pci_release_region(pdev, 0); +err_dis: + pci_disable_device(pdev); +err: return ret; } -static int -ath5k_get_stats(struct ieee80211_hw *hw, - struct ieee80211_low_level_stats *stats) +static void __devexit +ath5k_pci_remove(struct pci_dev *pdev) { - struct ath5k_softc *sc = hw->priv; - - /* Force update */ - ath5k_hw_update_mib_counters(sc->ah); - - stats->dot11ACKFailureCount = sc->stats.ack_fail; - stats->dot11RTSFailureCount = sc->stats.rts_fail; - stats->dot11RTSSuccessCount = sc->stats.rts_ok; - stats->dot11FCSErrorCount = sc->stats.fcs_error; + struct ath5k_softc *sc = pci_get_drvdata(pdev); - return 0; + ath5k_debug_finish_device(sc); + ath5k_detach(pdev, sc->hw); + ath5k_hw_detach(sc->ah); + kfree(sc->ah); + free_irq(pdev->irq, sc); + pci_iounmap(pdev, sc->iobase); + pci_release_region(pdev, 0); + pci_disable_device(pdev); + ieee80211_free_hw(sc->hw); } -static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) +#ifdef CONFIG_PM_SLEEP +static int ath5k_pci_suspend(struct device *dev) { - struct ath5k_softc *sc = hw->priv; - struct ieee80211_conf *conf = &hw->conf; - - if (idx != 0) - return -ENOENT; - - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = sc->ah->ah_noise_floor; + struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); + ath5k_led_off(sc); return 0; } -static u64 -ath5k_get_tsf(struct ieee80211_hw *hw) +static int ath5k_pci_resume(struct device *dev) { - struct ath5k_softc *sc = hw->priv; - - return ath5k_hw_get_tsf64(sc->ah); -} + struct pci_dev *pdev = to_pci_dev(dev); + struct ath5k_softc *sc = pci_get_drvdata(pdev); -static void -ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf) -{ - struct ath5k_softc *sc = hw->priv; + /* + * Suspend/Resume resets the PCI configuration space, so we have to + * re-disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state + */ + pci_write_config_byte(pdev, 0x41, 0); - ath5k_hw_set_tsf64(sc->ah, tsf); + ath5k_led_enable(sc); + return 0; } -static void -ath5k_reset_tsf(struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; +static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); +#define ATH5K_PM_OPS (&ath5k_pm_ops) +#else +#define ATH5K_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ - /* - * in IBSS mode we need to update the beacon timers too. - * this will also reset the TSF if we call it with 0 - */ - if (sc->opmode == NL80211_IFTYPE_ADHOC) - ath5k_beacon_update_timers(sc, 0); - else - ath5k_hw_reset_tsf(sc->ah); -} +static struct pci_driver ath5k_pci_driver = { + .name = KBUILD_MODNAME, + .id_table = ath5k_pci_id_table, + .probe = ath5k_pci_probe, + .remove = __devexit_p(ath5k_pci_remove), + .driver.pm = ATH5K_PM_OPS, +}; /* - * Updates the beacon that is sent by ath5k_beacon_send. For adhoc, - * this is called only once at config_bss time, for AP we do it every - * SWBA interrupt so that the TIM will reflect buffered frames. - * - * Called with the beacon lock. + * Module init/exit functions */ -static int -ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +static int __init +init_ath5k_pci(void) { int ret; - struct ath5k_softc *sc = hw->priv; - struct sk_buff *skb; - - if (WARN_ON(!vif)) { - ret = -EINVAL; - goto out; - } - - skb = ieee80211_beacon_get(hw, vif); - - if (!skb) { - ret = -ENOMEM; - goto out; - } - - ath5k_debug_dump_skb(sc, skb, "BC ", 1); - - ath5k_txbuf_free_skb(sc, sc->bbuf); - sc->bbuf->skb = skb; - ret = ath5k_beacon_setup(sc, sc->bbuf); - if (ret) - sc->bbuf->skb = NULL; -out: - return ret; -} - -static void -set_beacon_filter(struct ieee80211_hw *hw, bool enable) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - u32 rfilt; - rfilt = ath5k_hw_get_rx_filter(ah); - if (enable) - rfilt |= AR5K_RX_FILTER_BEACON; - else - rfilt &= ~AR5K_RX_FILTER_BEACON; - ath5k_hw_set_rx_filter(ah, rfilt); - sc->filter_flags = rfilt; -} - -static void ath5k_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) -{ - struct ath5k_softc *sc = hw->priv; - struct ath5k_hw *ah = sc->ah; - struct ath_common *common = ath5k_hw_common(ah); - unsigned long flags; - - mutex_lock(&sc->lock); - if (WARN_ON(sc->vif != vif)) - goto unlock; - - if (changes & BSS_CHANGED_BSSID) { - /* Cache for later use during resets */ - memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); - common->curaid = 0; - ath5k_hw_set_associd(ah); - mmiowb(); - } - - if (changes & BSS_CHANGED_BEACON_INT) - sc->bintval = bss_conf->beacon_int; - - if (changes & BSS_CHANGED_ASSOC) { - sc->assoc = bss_conf->assoc; - if (sc->opmode == NL80211_IFTYPE_STATION) - set_beacon_filter(hw, sc->assoc); - ath5k_hw_set_ledstate(sc->ah, sc->assoc ? - AR5K_LED_ASSOC : AR5K_LED_INIT); - if (bss_conf->assoc) { - ATH5K_DBG(sc, ATH5K_DEBUG_ANY, - "Bss Info ASSOC %d, bssid: %pM\n", - bss_conf->aid, common->curbssid); - common->curaid = bss_conf->aid; - ath5k_hw_set_associd(ah); - /* Once ANI is available you would start it here */ - } - } - if (changes & BSS_CHANGED_BEACON) { - spin_lock_irqsave(&sc->block, flags); - ath5k_beacon_update(hw, vif); - spin_unlock_irqrestore(&sc->block, flags); + ret = pci_register_driver(&ath5k_pci_driver); + if (ret) { + printk(KERN_ERR "ath5k_pci: can't register pci driver\n"); + return ret; } - if (changes & BSS_CHANGED_BEACON_ENABLED) - sc->enable_beacon = bss_conf->enable_beacon; - - if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED | - BSS_CHANGED_BEACON_INT)) - ath5k_beacon_config(sc); - - unlock: - mutex_unlock(&sc->lock); -} - -static void ath5k_sw_scan_start(struct ieee80211_hw *hw) -{ - struct ath5k_softc *sc = hw->priv; - if (!sc->assoc) - ath5k_hw_set_ledstate(sc->ah, AR5K_LED_SCAN); + return 0; } -static void ath5k_sw_scan_complete(struct ieee80211_hw *hw) +static void __exit +exit_ath5k_pci(void) { - struct ath5k_softc *sc = hw->priv; - ath5k_hw_set_ledstate(sc->ah, sc->assoc ? - AR5K_LED_ASSOC : AR5K_LED_INIT); + pci_unregister_driver(&ath5k_pci_driver); } -/** - * ath5k_set_coverage_class - Set IEEE 802.11 coverage class - * - * @hw: struct ieee80211_hw pointer - * @coverage_class: IEEE 802.11 coverage class number - * - * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given - * coverage class. The values are persistent, they are restored after device - * reset. - */ -static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) -{ - struct ath5k_softc *sc = hw->priv; - - mutex_lock(&sc->lock); - ath5k_hw_set_coverage_class(sc->ah, coverage_class); - mutex_unlock(&sc->lock); -} +module_init(init_ath5k_pci); +module_exit(exit_ath5k_pci); diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index dc1241f9c4e83b9a331e6f6661ce689ef9dca226..9a79773cdc2a43f59ccbddf2a53f51172e06d8a6 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h @@ -58,7 +58,9 @@ #define ATH_RXBUF 40 /* number of RX buffers */ #define ATH_TXBUF 200 /* number of TX buffers */ -#define ATH_BCBUF 1 /* number of beacon buffers */ +#define ATH_BCBUF 4 /* number of beacon buffers */ +#define ATH5K_TXQ_LEN_MAX (ATH_TXBUF / 4) /* bufs per queue */ +#define ATH5K_TXQ_LEN_LOW (ATH5K_TXQ_LEN_MAX / 2) /* low mark */ struct ath5k_buf { struct list_head list; @@ -83,6 +85,9 @@ struct ath5k_txq { struct list_head q; /* transmit queue */ spinlock_t lock; /* lock on q and link */ bool setup; + int txq_len; /* number of queued buffers */ + bool txq_poll_mark; + unsigned int txq_stuck; /* informational counter */ }; #define ATH5K_LED_MAX_NAME_LEN 31 @@ -116,6 +121,13 @@ struct ath5k_statistics { /* frame errors */ unsigned int rx_all_count; /* all RX frames, including errors */ unsigned int tx_all_count; /* all TX frames, including errors */ + unsigned int rx_bytes_count; /* all RX bytes, including errored pks + * and the MAC headers for each packet + */ + unsigned int tx_bytes_count; /* all TX bytes, including errored pkts + * and the MAC headers and padding for + * each packet. + */ unsigned int rxerr_crc; unsigned int rxerr_phy; unsigned int rxerr_phy_code[32]; @@ -146,6 +158,14 @@ struct ath5k_statistics { #define ATH_CHAN_MAX (14+14+14+252+20) #endif +struct ath5k_vif { + bool assoc; /* are we associated or not */ + enum nl80211_iftype opmode; + int bslot; + struct ath5k_buf *bbuf; /* beacon buffer */ + u8 lladdr[ETH_ALEN]; +}; + /* Software Carrier, keeps track of the driver state * associated with an instance of a device */ struct ath5k_softc { @@ -182,10 +202,11 @@ struct ath5k_softc { unsigned int curmode; /* current phy mode */ struct ieee80211_channel *curchan; /* current h/w channel */ - struct ieee80211_vif *vif; + u16 nvifs; enum ath5k_int imask; /* interrupt mask copy */ + u8 lladdr[ETH_ALEN]; u8 bssidmask[ETH_ALEN]; unsigned int led_pin, /* GPIO pin for driving LED */ @@ -204,7 +225,6 @@ struct ath5k_softc { spinlock_t txbuflock; unsigned int txbuf_len; /* buf count in txbuf list */ struct ath5k_txq txqs[AR5K_NUM_TX_QUEUES]; /* tx queues */ - struct ath5k_txq *txq; /* main tx queue */ struct tasklet_struct txtq; /* tx intr tasklet */ struct ath5k_led tx_led; /* tx led */ @@ -214,7 +234,10 @@ struct ath5k_softc { spinlock_t block; /* protects beacon */ struct tasklet_struct beacontq; /* beacon intr tasklet */ - struct ath5k_buf *bbuf; /* beacon buffer */ + struct list_head bcbuf; /* beacon buffer */ + struct ieee80211_vif *bslot[ATH_BCBUF]; + u16 num_ap_vifs; + u16 num_adhoc_vifs; unsigned int bhalq, /* SW q for outgoing beacons */ bmisscount, /* missed beacon transmits */ bintval, /* beacon interval in TU */ @@ -230,6 +253,8 @@ struct ath5k_softc { struct ath5k_ani_state ani_state; struct tasklet_struct ani_tasklet; /* ANI calibration */ + + struct delayed_work tx_complete_work; }; #define ath5k_hw_hasbssidmask(_ah) \ diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index fb339c3852ee6859b327a5d366165b1c45d8eea5..acda56ee521bdf0d2d42102fa8e14188e480fb05 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -60,6 +60,7 @@ #include "base.h" #include "debug.h" +#include "../debug.h" static unsigned int ath5k_debug; module_param_named(debug, ath5k_debug, uint, 0); @@ -71,8 +72,6 @@ module_param_named(debug, ath5k_debug, uint, 0); #include "reg.h" #include "ani.h" -static struct dentry *ath5k_global_debugfs; - static int ath5k_debugfs_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; @@ -314,6 +313,7 @@ static const struct { { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, + { ATH5K_DEBUG_DESC, "desc", "descriptor chains" }, { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, }; @@ -486,6 +486,60 @@ static const struct file_operations fops_antenna = { .llseek = default_llseek, }; +/* debugfs: misc */ + +static ssize_t read_file_misc(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath5k_softc *sc = file->private_data; + char buf[700]; + unsigned int len = 0; + u32 filt = ath5k_hw_get_rx_filter(sc->ah); + + len += snprintf(buf+len, sizeof(buf)-len, "bssid-mask: %pM\n", + sc->bssidmask); + len += snprintf(buf+len, sizeof(buf)-len, "filter-flags: 0x%x ", + filt); + if (filt & AR5K_RX_FILTER_UCAST) + len += snprintf(buf+len, sizeof(buf)-len, " UCAST"); + if (filt & AR5K_RX_FILTER_MCAST) + len += snprintf(buf+len, sizeof(buf)-len, " MCAST"); + if (filt & AR5K_RX_FILTER_BCAST) + len += snprintf(buf+len, sizeof(buf)-len, " BCAST"); + if (filt & AR5K_RX_FILTER_CONTROL) + len += snprintf(buf+len, sizeof(buf)-len, " CONTROL"); + if (filt & AR5K_RX_FILTER_BEACON) + len += snprintf(buf+len, sizeof(buf)-len, " BEACON"); + if (filt & AR5K_RX_FILTER_PROM) + len += snprintf(buf+len, sizeof(buf)-len, " PROM"); + if (filt & AR5K_RX_FILTER_XRPOLL) + len += snprintf(buf+len, sizeof(buf)-len, " XRPOLL"); + if (filt & AR5K_RX_FILTER_PROBEREQ) + len += snprintf(buf+len, sizeof(buf)-len, " PROBEREQ"); + if (filt & AR5K_RX_FILTER_PHYERR_5212) + len += snprintf(buf+len, sizeof(buf)-len, " PHYERR-5212"); + if (filt & AR5K_RX_FILTER_RADARERR_5212) + len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5212"); + if (filt & AR5K_RX_FILTER_PHYERR_5211) + snprintf(buf+len, sizeof(buf)-len, " PHYERR-5211"); + if (filt & AR5K_RX_FILTER_RADARERR_5211) + len += snprintf(buf+len, sizeof(buf)-len, " RADARERR-5211"); + + len += snprintf(buf+len, sizeof(buf)-len, "\nopmode: %s (%d)\n", + ath_opmode_to_string(sc->opmode), sc->opmode); + + if (len > sizeof(buf)) + len = sizeof(buf); + + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static const struct file_operations fops_misc = { + .read = read_file_misc, + .open = ath5k_debugfs_open, + .owner = THIS_MODULE, +}; + /* debugfs: frameerrors */ @@ -537,6 +591,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, st->rxerr_jumbo*100/st->rx_all_count : 0); len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", st->rx_all_count); + len += snprintf(buf+len, sizeof(buf)-len, "RX-all-bytes\t%d\n", + st->rx_bytes_count); len += snprintf(buf+len, sizeof(buf)-len, "\nTX\n---------------------\n"); @@ -554,6 +610,8 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, st->txerr_filt*100/st->tx_all_count : 0); len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", st->tx_all_count); + len += snprintf(buf+len, sizeof(buf)-len, "TX-all-bytes\t%d\n", + st->tx_bytes_count); if (len > sizeof(buf)) len = sizeof(buf); @@ -662,20 +720,21 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, len += snprintf(buf+len, sizeof(buf)-len, "beacon RSSI average:\t%d\n", sc->ah->ah_beacon_rssi_avg.avg); + +#define CC_PRINT(_struct, _field) \ + _struct._field, \ + _struct.cycles > 0 ? \ + _struct._field*100/_struct.cycles : 0 + len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n", - as->pfc_tx, - as->pfc_cycles > 0 ? - as->pfc_tx*100/as->pfc_cycles : 0); + CC_PRINT(as->last_cc, tx_frame)); len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n", - as->pfc_rx, - as->pfc_cycles > 0 ? - as->pfc_rx*100/as->pfc_cycles : 0); + CC_PRINT(as->last_cc, rx_frame)); len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n", - as->pfc_busy, - as->pfc_cycles > 0 ? - as->pfc_busy*100/as->pfc_cycles : 0); + CC_PRINT(as->last_cc, rx_busy)); +#undef CC_PRINT len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n", - as->pfc_cycles); + as->last_cc.cycles); len += snprintf(buf+len, sizeof(buf)-len, "listen time\t\t%d\tlast: %d\n", as->listen_time, as->last_listen); @@ -768,7 +827,7 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, struct ath5k_txq *txq; struct ath5k_buf *bf, *bf0; - int i, n = 0; + int i, n; len += snprintf(buf+len, sizeof(buf)-len, "available txbuffers: %d\n", sc->txbuf_len); @@ -782,9 +841,16 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, if (!txq->setup) continue; + n = 0; + spin_lock_bh(&txq->lock); list_for_each_entry_safe(bf, bf0, &txq->q, list) n++; - len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n); + spin_unlock_bh(&txq->lock); + + len += snprintf(buf+len, sizeof(buf)-len, + " len: %d bufs: %d\n", txq->txq_len, n); + len += snprintf(buf+len, sizeof(buf)-len, + " stuck: %d\n", txq->txq_stuck); } if (len > sizeof(buf)) @@ -821,21 +887,13 @@ static const struct file_operations fops_queue = { }; -/* init */ - -void -ath5k_debug_init(void) -{ - ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL); -} - void ath5k_debug_init_device(struct ath5k_softc *sc) { sc->debug.level = ath5k_debug; - sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy), - ath5k_global_debugfs); + sc->debug.debugfs_phydir = debugfs_create_dir("ath5k", + sc->hw->wiphy->debugfsdir); sc->debug.debugfs_debug = debugfs_create_file("debug", S_IWUSR | S_IRUSR, @@ -855,6 +913,10 @@ ath5k_debug_init_device(struct ath5k_softc *sc) S_IWUSR | S_IRUSR, sc->debug.debugfs_phydir, sc, &fops_antenna); + sc->debug.debugfs_misc = debugfs_create_file("misc", + S_IRUSR, + sc->debug.debugfs_phydir, sc, &fops_misc); + sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, sc->debug.debugfs_phydir, sc, @@ -871,12 +933,6 @@ ath5k_debug_init_device(struct ath5k_softc *sc) &fops_queue); } -void -ath5k_debug_finish(void) -{ - debugfs_remove(ath5k_global_debugfs); -} - void ath5k_debug_finish_device(struct ath5k_softc *sc) { @@ -885,6 +941,7 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) debugfs_remove(sc->debug.debugfs_beacon); debugfs_remove(sc->debug.debugfs_reset); debugfs_remove(sc->debug.debugfs_antenna); + debugfs_remove(sc->debug.debugfs_misc); debugfs_remove(sc->debug.debugfs_frameerrors); debugfs_remove(sc->debug.debugfs_ani); debugfs_remove(sc->debug.debugfs_queue); @@ -962,7 +1019,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) struct ath5k_rx_status rs = {}; int status; - if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) + if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC))) return; printk(KERN_DEBUG "rxdp %x, rxlink %p\n", @@ -1004,7 +1061,7 @@ ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) struct ath5k_tx_status ts = {}; int done; - if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET))) + if (likely(!(sc->debug.level & ATH5K_DEBUG_DESC))) return; done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts); diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 606ae94a9157806b736f3c9d890c36a2f1edb762..236edbd2507ddaa4a7a26eecadc79aadfe4f9219 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h @@ -75,6 +75,7 @@ struct ath5k_dbg_info { struct dentry *debugfs_beacon; struct dentry *debugfs_reset; struct dentry *debugfs_antenna; + struct dentry *debugfs_misc; struct dentry *debugfs_frameerrors; struct dentry *debugfs_ani; struct dentry *debugfs_queue; @@ -95,6 +96,7 @@ struct ath5k_dbg_info { * @ATH5K_DEBUG_DUMP_TX: print transmit skb content * @ATH5K_DEBUG_DUMPBANDS: dump bands * @ATH5K_DEBUG_TRACE: trace function calls + * @ATH5K_DEBUG_DESC: descriptor setup * @ATH5K_DEBUG_ANY: show at any debug level * * The debug level is used to control the amount and type of debugging output @@ -117,6 +119,7 @@ enum ath5k_debug_level { ATH5K_DEBUG_DUMP_TX = 0x00000200, ATH5K_DEBUG_DUMPBANDS = 0x00000400, ATH5K_DEBUG_ANI = 0x00002000, + ATH5K_DEBUG_DESC = 0x00004000, ATH5K_DEBUG_ANY = 0xffffffff }; @@ -134,15 +137,9 @@ enum ath5k_debug_level { __func__, __LINE__, ##__VA_ARGS__); \ } while (0) -void -ath5k_debug_init(void); - void ath5k_debug_init_device(struct ath5k_softc *sc); -void -ath5k_debug_finish(void); - void ath5k_debug_finish_device(struct ath5k_softc *sc); @@ -170,15 +167,9 @@ static inline void __attribute__ ((format (printf, 3, 4))) ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {} -static inline void -ath5k_debug_init(void) {} - static inline void ath5k_debug_init_device(struct ath5k_softc *sc) {} -static inline void -ath5k_debug_finish(void) {} - static inline void ath5k_debug_finish_device(struct ath5k_softc *sc) {} diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index 484f31870ba8f2c287e8817a22563a4d61f40f4e..923c9ca5c4f0fe424186ff978839eca80c9c2617 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -244,7 +244,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) /* Force channel idle high */ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, - AR5K_DIAG_SW_CHANEL_IDLE_HIGH); + AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); /* Wait a while and disable mechanism */ udelay(200); @@ -261,7 +261,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) } while (--i && pending); AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, - AR5K_DIAG_SW_CHANEL_IDLE_HIGH); + AR5K_DIAG_SW_CHANNEL_IDLE_HIGH); } /* Clear register */ @@ -377,11 +377,11 @@ int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) * * This function increases/decreases the tx trigger level for the tx fifo * buffer (aka FIFO threshold) that is used to indicate when PCU flushes - * the buffer and transmits it's data. Lowering this results sending small + * the buffer and transmits its data. Lowering this results sending small * frames more quickly but can lead to tx underruns, raising it a lot can * result other problems (i think bmiss is related). Right now we start with * the lowest possible (64Bytes) and if we get tx underrun we increase it using - * the increase flag. Returns -EIO if we have have reached maximum/minimum. + * the increase flag. Returns -EIO if we have reached maximum/minimum. * * XXX: Link this with tx DMA size ? * XXX: Use it to save interrupts ? diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index ae316fec4a6ae527817bda21cfd214210111e3b0..39722dd73e433ae606f2ef6804b18c1ff23b70fa 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -661,7 +661,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset) * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC * steps that match with the power values we read from eeprom. On * older eeprom versions (< 3.2) these steps are equaly spaced at - * 10% of the pcdac curve -until the curve reaches it's maximum- + * 10% of the pcdac curve -until the curve reaches its maximum- * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2) * these 11 steps are spaced in a different way. This function returns * the pcdac steps based on eeprom version and curve min/max so that we @@ -1113,7 +1113,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode) */ /* For RF2413 power calibration data doesn't start on a fixed location and - * if a mode is not supported, it's section is missing -not zeroed-. + * if a mode is not supported, its section is missing -not zeroed-. * So we need to calculate the starting offset for each section by using * these two functions */ diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index 86fdb6ddfaaa52d0abba9116c989438c0b44f851..074b4c644399c8f5f3790a1d6ff0f8be9f8b2ccc 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c @@ -137,11 +137,11 @@ void ath5k_hw_update_mib_counters(struct ath5k_hw *ah) * ath5k_hw_set_ack_bitrate - set bitrate for ACKs * * @ah: The &struct ath5k_hw - * @high: Flag to determine if we want to use high transmition rate + * @high: Flag to determine if we want to use high transmission rate * for ACKs or not * * If high flag is set, we tell hw to use a set of control rates based on - * the current transmition rate (check out control_rates array inside reset.c). + * the current transmission rate (check out control_rates array inside reset.c). * If not hw just uses the lowest rate available for the current modulation * scheme being used (1Mbit for CCK and 6Mbits for OFDM). */ @@ -207,7 +207,8 @@ static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) */ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) { - return usec * ath5k_hw_get_clockrate(ah); + struct ath_common *common = ath5k_hw_common(ah); + return usec * common->clockrate; } /** @@ -216,17 +217,19 @@ unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec) */ unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock) { - return clock / ath5k_hw_get_clockrate(ah); + struct ath_common *common = ath5k_hw_common(ah); + return clock / common->clockrate; } /** - * ath5k_hw_get_clockrate - Get the clock rate for current mode + * ath5k_hw_set_clockrate - Set common->clockrate for the current channel * * @ah: The &struct ath5k_hw */ -unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) +void ath5k_hw_set_clockrate(struct ath5k_hw *ah) { struct ieee80211_channel *channel = ah->ah_current_channel; + struct ath_common *common = ath5k_hw_common(ah); int clock; if (channel->hw_value & CHANNEL_5GHZ) @@ -240,7 +243,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) if (channel->hw_value & CHANNEL_TURBO) clock *= 2; - return clock; + common->clockrate = clock; } /** @@ -308,27 +311,26 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) } /** - * ath5k_hw_set_associd - Set BSSID for association + * ath5k_hw_set_bssid - Set current BSSID on hw * * @ah: The &struct ath5k_hw - * @bssid: BSSID - * @assoc_id: Assoc id * - * Sets the BSSID which trigers the "SME Join" operation + * Sets the current BSSID and BSSID mask we have from the + * common struct into the hardware */ -void ath5k_hw_set_associd(struct ath5k_hw *ah) +void ath5k_hw_set_bssid(struct ath5k_hw *ah) { struct ath_common *common = ath5k_hw_common(ah); u16 tim_offset = 0; /* - * Set simple BSSID mask on 5212 + * Set BSSID mask on 5212 */ if (ah->ah_version == AR5K_AR5212) ath_hw_setbssidmask(common); /* - * Set BSSID which triggers the "SME Join" operation + * Set BSSID */ ath5k_hw_reg_write(ah, get_unaligned_le32(common->curbssid), @@ -496,6 +498,10 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) { u32 tsf_lower, tsf_upper1, tsf_upper2; int i; + unsigned long flags; + + /* This code is time critical - we don't want to be interrupted here */ + local_irq_save(flags); /* * While reading TSF upper and then lower part, the clock is still @@ -518,6 +524,8 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) tsf_upper1 = tsf_upper2; } + local_irq_restore(flags); + WARN_ON( i == ATH5K_MAX_TSF_READ ); return (((u64)tsf_upper1 << 32) | tsf_lower); @@ -601,7 +609,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) /* Timer3 marks the end of our ATIM window * a zero length window is not allowed because * we 'll get no beacons */ - timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1); + timer3 = next_beacon + 1; /* * Set the beacon register and enable all timers. @@ -641,198 +649,95 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) } - -/*********************\ -* Key table functions * -\*********************/ - -/* - * Reset a key entry on the table +/** + * ath5k_check_timer_win - Check if timer B is timer A + window + * + * @a: timer a (before b) + * @b: timer b (after a) + * @window: difference between a and b + * @intval: timers are increased by this interval + * + * This helper function checks if timer B is timer A + window and covers + * cases where timer A or B might have already been updated or wrapped + * around (Timers are 16 bit). + * + * Returns true if O.K. */ -int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) +static inline bool +ath5k_check_timer_win(int a, int b, int window, int intval) { - unsigned int i, type; - u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; - - AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); - - type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry)); - - for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) - ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); - - /* Reset associated MIC entry if TKIP - * is enabled located at offset (entry + 64) */ - if (type == AR5K_KEYTABLE_TYPE_TKIP) { - AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE); - for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++) - ath5k_hw_reg_write(ah, 0, - AR5K_KEYTABLE_OFF(micentry, i)); - } - /* - * Set NULL encryption on AR5212+ - * - * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5) - * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007 - * - * Note2: Windows driver (ndiswrapper) sets this to - * 0x00000714 instead of 0x00000007 + * 1.) usually B should be A + window + * 2.) A already updated, B not updated yet + * 3.) A already updated and has wrapped around + * 4.) B has wrapped around */ - if (ah->ah_version >= AR5K_AR5211) { - ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, - AR5K_KEYTABLE_TYPE(entry)); - - if (type == AR5K_KEYTABLE_TYPE_TKIP) { - ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, - AR5K_KEYTABLE_TYPE(micentry)); - } - } - - return 0; + if ((b - a == window) || /* 1.) */ + (a - b == intval - window) || /* 2.) */ + ((a | 0x10000) - b == intval - window) || /* 3.) */ + ((b | 0x10000) - a == window)) /* 4.) */ + return true; /* O.K. */ + return false; } -static -int ath5k_keycache_type(const struct ieee80211_key_conf *key) -{ - switch (key->alg) { - case ALG_TKIP: - return AR5K_KEYTABLE_TYPE_TKIP; - case ALG_CCMP: - return AR5K_KEYTABLE_TYPE_CCM; - case ALG_WEP: - if (key->keylen == WLAN_KEY_LEN_WEP40) - return AR5K_KEYTABLE_TYPE_40; - else if (key->keylen == WLAN_KEY_LEN_WEP104) - return AR5K_KEYTABLE_TYPE_104; - return -EINVAL; - default: - return -EINVAL; - } - return -EINVAL; -} - -/* - * Set a key entry on the table +/** + * ath5k_hw_check_beacon_timers - Check if the beacon timers are correct + * + * @ah: The &struct ath5k_hw + * @intval: beacon interval + * + * This is a workaround for IBSS mode: + * + * The need for this function arises from the fact that we have 4 separate + * HW timer registers (TIMER0 - TIMER3), which are closely related to the + * next beacon target time (NBTT), and that the HW updates these timers + * seperately based on the current TSF value. The hardware increments each + * timer by the beacon interval, when the local TSF coverted to TU is equal + * to the value stored in the timer. + * + * The reception of a beacon with the same BSSID can update the local HW TSF + * at any time - this is something we can't avoid. If the TSF jumps to a + * time which is later than the time stored in a timer, this timer will not + * be updated until the TSF in TU wraps around at 16 bit (the size of the + * timers) and reaches the time which is stored in the timer. + * + * The problem is that these timers are closely related to TIMER0 (NBTT) and + * that they define a time "window". When the TSF jumps between two timers + * (e.g. ATIM and NBTT), the one in the past will be left behind (not + * updated), while the one in the future will be updated every beacon + * interval. This causes the window to get larger, until the TSF wraps + * around as described above and the timer which was left behind gets + * updated again. But - because the beacon interval is usually not an exact + * divisor of the size of the timers (16 bit), an unwanted "window" between + * these timers has developed! + * + * This is especially important with the ATIM window, because during + * the ATIM window only ATIM frames and no data frames are allowed to be + * sent, which creates transmission pauses after each beacon. This symptom + * has been described as "ramping ping" because ping times increase linearly + * for some time and then drop down again. A wrong window on the DMA beacon + * timer has the same effect, so we check for these two conditions. + * + * Returns true if O.K. */ -int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, - const struct ieee80211_key_conf *key, const u8 *mac) -{ - unsigned int i; - int keylen; - __le32 key_v[5] = {}; - __le32 key0 = 0, key1 = 0; - __le32 *rxmic, *txmic; - int keytype; - u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET; - bool is_tkip; - const u8 *key_ptr; - - is_tkip = (key->alg == ALG_TKIP); - - /* - * key->keylen comes in from mac80211 in bytes. - * TKIP is 128 bit + 128 bit mic - */ - keylen = (is_tkip) ? (128 / 8) : key->keylen; - - if (entry > AR5K_KEYTABLE_SIZE || - (is_tkip && micentry > AR5K_KEYTABLE_SIZE)) - return -EOPNOTSUPP; - - if (unlikely(keylen > 16)) - return -EOPNOTSUPP; - - keytype = ath5k_keycache_type(key); - if (keytype < 0) - return keytype; - - /* - * each key block is 6 bytes wide, written as pairs of - * alternating 32 and 16 bit le values. - */ - key_ptr = key->key; - for (i = 0; keylen >= 6; keylen -= 6) { - memcpy(&key_v[i], key_ptr, 6); - i += 2; - key_ptr += 6; - } - if (keylen) - memcpy(&key_v[i], key_ptr, keylen); - - /* intentionally corrupt key until mic is installed */ - if (is_tkip) { - key0 = key_v[0] = ~key_v[0]; - key1 = key_v[1] = ~key_v[1]; - } - - for (i = 0; i < ARRAY_SIZE(key_v); i++) - ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), - AR5K_KEYTABLE_OFF(entry, i)); - - ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry)); - - if (is_tkip) { - /* Install rx/tx MIC */ - rxmic = (__le32 *) &key->key[16]; - txmic = (__le32 *) &key->key[24]; - - if (ah->ah_combined_mic) { - key_v[0] = rxmic[0]; - key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16); - key_v[2] = rxmic[1]; - key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff); - key_v[4] = txmic[1]; - } else { - key_v[0] = rxmic[0]; - key_v[1] = 0; - key_v[2] = rxmic[1]; - key_v[3] = 0; - key_v[4] = 0; - } - for (i = 0; i < ARRAY_SIZE(key_v); i++) - ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), - AR5K_KEYTABLE_OFF(micentry, i)); - - ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, - AR5K_KEYTABLE_TYPE(micentry)); - ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry)); - ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry)); - - /* restore first 2 words of key */ - ath5k_hw_reg_write(ah, le32_to_cpu(~key0), - AR5K_KEYTABLE_OFF(entry, 0)); - ath5k_hw_reg_write(ah, le32_to_cpu(~key1), - AR5K_KEYTABLE_OFF(entry, 1)); - } - - return ath5k_hw_set_key_lladdr(ah, entry, mac); -} - -int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) +bool +ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval) { - u32 low_id, high_id; - - /* Invalid entry (key table overflow) */ - AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); + unsigned int nbtt, atim, dma; - /* - * MAC may be NULL if it's a broadcast key. In this case no need to - * to compute get_unaligned_le32 and get_unaligned_le16 as we - * already know it. - */ - if (!mac) { - low_id = 0xffffffff; - high_id = 0xffff | AR5K_KEYTABLE_VALID; - } else { - low_id = get_unaligned_le32(mac); - high_id = get_unaligned_le16(mac + 4) | AR5K_KEYTABLE_VALID; - } + nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0); + atim = ath5k_hw_reg_read(ah, AR5K_TIMER3); + dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3; - ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry)); - ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry)); + /* NOTE: SWBA is different. Having a wrong window there does not + * stop us from sending data and this condition is catched thru + * other means (SWBA interrupt) */ - return 0; + if (ath5k_check_timer_win(nbtt, atim, 1, intval) && + ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP, + intval)) + return true; /* O.K. */ + return false; } /** diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 6284c389ba18ba6480b65dbf61c17e1f9f4632e0..219367884e640a60a99a99eba59478aaba9bc1da 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -115,7 +115,7 @@ static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah, \**********************/ /* - * This code is used to optimize rf gain on different environments + * This code is used to optimize RF gain on different environments * (temperature mostly) based on feedback from a power detector. * * It's only used on RF5111 and RF5112, later RF chips seem to have @@ -302,7 +302,7 @@ static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah) } /* Perform gain_F adjustment by choosing the right set - * of parameters from rf gain optimization ladder */ + * of parameters from RF gain optimization ladder */ static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) { const struct ath5k_gain_opt *go; @@ -367,7 +367,7 @@ static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah) return ret; } -/* Main callback for thermal rf gain calibration engine +/* Main callback for thermal RF gain calibration engine * Check for a new gain reading and schedule an adjustment * if needed. * @@ -433,7 +433,7 @@ enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah) return ah->ah_gain.g_state; } -/* Write initial rf gain table to set the RF sensitivity +/* Write initial RF gain table to set the RF sensitivity * this one works on all RF chips and has nothing to do * with gain_F calibration */ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) @@ -496,7 +496,7 @@ int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) /* - * Setup RF registers by writing rf buffer on hw + * Setup RF registers by writing RF buffer on hw */ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode) @@ -571,7 +571,7 @@ int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, return -EINVAL; } - /* If it's the first time we set rf buffer, allocate + /* If it's the first time we set RF buffer, allocate * ah->ah_rf_banks based on ah->ah_rf_banks_size * we set above */ if (ah->ah_rf_banks == NULL) { @@ -1093,6 +1093,7 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) ah->ah_current_channel = channel; ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false; + ath5k_hw_set_clockrate(ah); return 0; } @@ -1257,7 +1258,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, * Disable beacons and RX/TX queues, wait */ AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210, - AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); + AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210); beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); @@ -1336,7 +1337,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, * Re-enable RX/TX and beacons */ AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210, - AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210); + AR5K_DIAG_SW_DIS_TX_5210 | AR5K_DIAG_SW_DIS_RX_5210); ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210); return 0; @@ -1377,7 +1378,7 @@ ath5k_hw_rf511x_iq_calibrate(struct ath5k_hw *ah) /* protect against divide by 0 and loss of sign bits */ if (i_coffd == 0 || q_coffd < 2) - return -1; + return 0; i_coff = (-iq_corr) / i_coffd; i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ @@ -1582,7 +1583,7 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, else if (curr_sym_off >= 31 && curr_sym_off <= 46) mag_mask[2] |= plt_mag_map << (curr_sym_off - 31) * 2; - else if (curr_sym_off >= 46 && curr_sym_off <= 53) + else if (curr_sym_off >= 47 && curr_sym_off <= 53) mag_mask[3] |= plt_mag_map << (curr_sym_off - 47) * 2; @@ -2987,7 +2988,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, /* - * Set transmition power + * Set transmission power */ int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, @@ -3035,9 +3036,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, /* Limit max power if we have a CTL available */ ath5k_get_max_ctl_power(ah, channel); - /* FIXME: Tx power limit for this regdomain - * XXX: Mac80211/CRDA will do that anyway ? */ - /* FIXME: Antenna reduction stuff */ /* FIXME: Limit power on turbo modes */ diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 4186ff4c6e9c80a69d23824a356e35529c55b4c7..84c717ded1c5de8aad2a952f4d6afb507da8d261 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c @@ -35,25 +35,59 @@ int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, return 0; } +/* + * Make sure cw is a power of 2 minus 1 and smaller than 1024 + */ +static u16 ath5k_cw_validate(u16 cw_req) +{ + u32 cw = 1; + cw_req = min(cw_req, (u16)1023); + + while (cw < cw_req) + cw = (cw << 1) | 1; + + return cw; +} + /* * Set properties for a transmit queue */ int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, - const struct ath5k_txq_info *queue_info) + const struct ath5k_txq_info *qinfo) { + struct ath5k_txq_info *qi; + AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); - if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) + qi = &ah->ah_txq[queue]; + + if (qi->tqi_type == AR5K_TX_QUEUE_INACTIVE) return -EIO; - memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info)); + /* copy and validate values */ + qi->tqi_type = qinfo->tqi_type; + qi->tqi_subtype = qinfo->tqi_subtype; + qi->tqi_flags = qinfo->tqi_flags; + /* + * According to the docs: Although the AIFS field is 8 bit wide, + * the maximum supported value is 0xFC. Setting it higher than that + * will cause the DCU to hang. + */ + qi->tqi_aifs = min(qinfo->tqi_aifs, (u8)0xFC); + qi->tqi_cw_min = ath5k_cw_validate(qinfo->tqi_cw_min); + qi->tqi_cw_max = ath5k_cw_validate(qinfo->tqi_cw_max); + qi->tqi_cbr_period = qinfo->tqi_cbr_period; + qi->tqi_cbr_overflow_limit = qinfo->tqi_cbr_overflow_limit; + qi->tqi_burst_time = qinfo->tqi_burst_time; + qi->tqi_ready_time = qinfo->tqi_ready_time; /*XXX: Is this supported on 5210 ?*/ - if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA && - ((queue_info->tqi_subtype == AR5K_WME_AC_VI) || - (queue_info->tqi_subtype == AR5K_WME_AC_VO))) || - queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD) - ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; + /*XXX: Is this correct for AR5K_WME_AC_VI,VO ???*/ + if ((qinfo->tqi_type == AR5K_TX_QUEUE_DATA && + ((qinfo->tqi_subtype == AR5K_WME_AC_VI) || + (qinfo->tqi_subtype == AR5K_WME_AC_VO))) || + qinfo->tqi_type == AR5K_TX_QUEUE_UAPSD) + qi->tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; return 0; } @@ -186,7 +220,7 @@ void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) */ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) { - u32 cw_min, cw_max, retry_lg, retry_sh; + u32 retry_lg, retry_sh; struct ath5k_txq_info *tq = &ah->ah_txq[queue]; AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); @@ -217,14 +251,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /* Set IFS0 */ if (ah->ah_turbo) { ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + - (ah->ah_aifs + tq->tqi_aifs) * - AR5K_INIT_SLOT_TIME_TURBO) << + tq->tqi_aifs * AR5K_INIT_SLOT_TIME_TURBO) << AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, AR5K_IFS0); } else { ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS + - (ah->ah_aifs + tq->tqi_aifs) * - AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) | + tq->tqi_aifs * AR5K_INIT_SLOT_TIME) << + AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS, AR5K_IFS0); } @@ -247,35 +280,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) AR5K_PHY_FRAME_CTL_5210); } - /* - * Calculate cwmin/max by channel mode - */ - cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN; - cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX; - ah->ah_aifs = AR5K_TUNE_AIFS; - /*XR is only supported on 5212*/ - if (IS_CHAN_XR(ah->ah_current_channel) && - ah->ah_version == AR5K_AR5212) { - cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR; - cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR; - ah->ah_aifs = AR5K_TUNE_AIFS_XR; - /*B mode is not supported on 5210*/ - } else if (IS_CHAN_B(ah->ah_current_channel) && - ah->ah_version != AR5K_AR5210) { - cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B; - cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B; - ah->ah_aifs = AR5K_TUNE_AIFS_11B; - } - - cw_min = 1; - while (cw_min < ah->ah_cw_min) - cw_min = (cw_min << 1) | 1; - - cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) : - ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1); - cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) : - ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1); - /* * Calculate and set retry limits */ @@ -292,7 +296,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /*No QCU/DCU [5210]*/ if (ah->ah_version == AR5K_AR5210) { ath5k_hw_reg_write(ah, - (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) + (tq->tqi_cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, AR5K_NODCU_RETRY_LMT_SLG_RETRY) | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, @@ -314,14 +318,13 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) /*===Rest is also for QCU/DCU only [5211+]===*/ /* - * Set initial content window (cw_min/cw_max) + * Set contention window (cw_min/cw_max) * and arbitrated interframe space (aifs)... */ ath5k_hw_reg_write(ah, - AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | - AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | - AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs, - AR5K_DCU_LCL_IFS_AIFS), + AR5K_REG_SM(tq->tqi_cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | + AR5K_REG_SM(tq->tqi_cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | + AR5K_REG_SM(tq->tqi_aifs, AR5K_DCU_LCL_IFS_AIFS), AR5K_QUEUE_DFS_LOCAL_IFS(queue)); /* diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 55b4ac6d236f1d93192ae72ae6323acbdc9f670c..a34929f065330ba01f0e416952d4f7c2b3bf06c0 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -1387,10 +1387,9 @@ /* - * PCU control register + * PCU Diagnostic register * - * Only DIS_RX is used in the code, the rest i guess are - * for tweaking/diagnostics. + * Used for tweaking/diagnostics. */ #define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */ #define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */ @@ -1399,22 +1398,22 @@ #define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001 /* Disable ACKs if WEP key is invalid */ #define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs */ #define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs */ -#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption */ -#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption */ -#define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */ -#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */ +#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable HW encryption */ +#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable HW decryption */ +#define AR5K_DIAG_SW_DIS_TX_5210 0x00000020 /* Disable transmit [5210] */ +#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable receive */ #define AR5K_DIAG_SW_DIS_RX_5211 0x00000020 #define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211) -#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */ +#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* TX Data Loopback (i guess it goes with DIS_TX) [5210] */ #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) -#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */ +#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Generate invalid TX FCS */ #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) -#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */ +#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Add 56 bytes of channel info before the frame data in the RX buffer */ #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) @@ -1426,17 +1425,17 @@ #define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */ #define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask */ #define AR5K_DIAG_SW_SCRAM_SEED_S 10 -#define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ +#define AR5K_DIAG_SW_DIS_SEQ_INC_5210 0x00040000 /* Disable seqnum increment (?)[5210] */ #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ #define AR5K_DIAG_SW_OBSPT_S 18 -#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */ -#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */ -#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */ -#define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */ +#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x00100000 /* Ignore carrier sense */ +#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x00200000 /* Ignore virtual carrier sense */ +#define AR5K_DIAG_SW_CHANNEL_IDLE_HIGH 0x00400000 /* Force channel idle high */ +#define AR5K_DIAG_SW_PHEAR_ME 0x00800000 /* ??? */ /* * TSF (clock) register (lower 32 bits) @@ -1822,50 +1821,8 @@ /*===5212 end===*/ -/* - * Key table (WEP) register - */ -#define AR5K_KEYTABLE_0_5210 0x9000 -#define AR5K_KEYTABLE_0_5211 0x8800 -#define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5)) -#define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5)) -#define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \ - AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n)) -#define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2)) -#define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5) -#define AR5K_KEYTABLE_TYPE_40 0x00000000 -#define AR5K_KEYTABLE_TYPE_104 0x00000001 -#define AR5K_KEYTABLE_TYPE_128 0x00000003 -#define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */ -#define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */ -#define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */ -#define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */ -#define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */ -#define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6) -#define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7) -#define AR5K_KEYTABLE_VALID 0x00008000 - -/* If key type is TKIP and MIC is enabled - * MIC key goes in offset entry + 64 */ -#define AR5K_KEYTABLE_MIC_OFFSET 64 - -/* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit - * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit - * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit - * - * Some vendors have introduced bigger WEP keys to address - * security vulnerabilities in WEP. This includes: - * - * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit - * - * We can expand this if we find ar5k Atheros cards with a larger - * key table size. - */ #define AR5K_KEYTABLE_SIZE_5210 64 #define AR5K_KEYTABLE_SIZE_5211 128 -#define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \ - AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211) - /*===PHY REGISTERS===*/ @@ -1911,7 +1868,7 @@ #define AR5K_PHY_TURBO 0x9804 /* Register Address */ #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ -#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */ +#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo */ /* * PHY agility command register diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 498aa28ea9e69bd58ba12cf889b1f2df23e3ed30..5b179d01f97db16c64bddc97fc0ade0005bf57ee 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c @@ -167,7 +167,7 @@ static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, * ieee80211_duration() for a brief description of * what rate we should choose to TX ACKs. */ tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, - sc->vif, 10, rate)); + NULL, 10, rate)); ath5k_hw_reg_write(ah, tx_time, reg); @@ -326,7 +326,7 @@ static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, * register). After this MAC and Baseband are * disabled and a full reset is needed to come * back. This way we save as much power as possible - * without puting the card on full sleep. + * without putting the card on full sleep. */ int ath5k_hw_on_hold(struct ath5k_hw *ah) { @@ -344,7 +344,7 @@ int ath5k_hw_on_hold(struct ath5k_hw *ah) /* * Put chipset on warm reset... * - * Note: puting PCI core on warm reset on PCI-E cards + * Note: putting PCI core on warm reset on PCI-E cards * results card to hang and always return 0xffff... so * we ingore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. @@ -400,7 +400,7 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) /* * Put chipset on warm reset... * - * Note: puting PCI core on warm reset on PCI-E cards + * Note: putting PCI core on warm reset on PCI-E cards * results card to hang and always return 0xffff... so * we ingore that flag for PCI-E cards. On PCI cards * this flag gets cleared after 64 PCI clocks. @@ -959,7 +959,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, AR5K_QUEUE_DCU_SEQNUM(0)); } - /* TSF accelerates on AR5211 durring reset + /* TSF accelerates on AR5211 during reset * As a workaround save it here and restore * it later so that it's back in time after * reset. This way it'll get re-synced on the @@ -1060,7 +1060,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * XXX: rethink this after new mode changes to * mac80211 are integrated */ if (ah->ah_version == AR5K_AR5212 && - ah->ah_sc->vif != NULL) + ah->ah_sc->nvifs) ath5k_hw_write_rate_duration(ah, mode); /* @@ -1080,7 +1080,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, return ret; /* Spur info is available only from EEPROM versions - * bigger than 5.3 but but the EEPOM routines will use + * greater than 5.3, but the EEPROM routines will use * static values for older versions */ if (ah->ah_mac_srev >= AR5K_SREV_AR5424) ath5k_hw_set_spur_mitigation_filter(ah, @@ -1160,7 +1160,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, */ /* Restore bssid and bssid mask */ - ath5k_hw_set_associd(ah); + ath5k_hw_set_bssid(ah); /* Set PCU config */ ath5k_hw_set_opmode(ah, op_mode); @@ -1173,11 +1173,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* Set RSSI/BRSSI thresholds * * Note: If we decide to set this value - * dynamicaly, have in mind that when AR5K_RSSI_THR - * register is read it might return 0x40 if we haven't - * wrote anything to it plus BMISS RSSI threshold is zeroed. + * dynamically, keep in mind that when AR5K_RSSI_THR + * register is read, it might return 0x40 if we haven't + * written anything to it. Also, BMISS RSSI threshold is zeroed. * So doing a save/restore procedure here isn't the right - * choice. Instead store it on ath5k_hw */ + * choice. Instead, store it in ath5k_hw */ ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S), @@ -1235,7 +1235,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, /* * Perform ADC test to see if baseband is ready - * Set tx hold and check adc test register + * Set TX hold and check ADC test register */ phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); @@ -1254,15 +1254,15 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, * * This method is used to calibrate some static offsets * used together with on-the fly I/Q calibration (the - * one performed via ath5k_hw_phy_calibrate), that doesn't + * one performed via ath5k_hw_phy_calibrate), which doesn't * interrupt rx path. * * While rx path is re-routed to the power detector we also - * start a noise floor calibration, to measure the + * start a noise floor calibration to measure the * card's noise floor (the noise we measure when we are not - * transmiting or receiving anything). + * transmitting or receiving anything). * - * If we are in a noisy environment AGC calibration may time + * If we are in a noisy environment, AGC calibration may time * out and/or noise floor calibration might timeout. */ AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h index e50baff66175a969a36110b36256b31f59c7c195..3ac4cff4239de9d8457246e8089caf8a9b5906c2 100644 --- a/drivers/net/wireless/ath/ath5k/rfbuffer.h +++ b/drivers/net/wireless/ath/ath5k/rfbuffer.h @@ -25,10 +25,10 @@ * * We don't write on those registers directly but * we send a data packet on the chip, using a special register, - * that holds all the settings we need. After we 've sent the + * that holds all the settings we need. After we've sent the * data packet, we write on another special register to notify hw * to apply the settings. This is done so that control registers - * can be dynamicaly programmed during operation and the settings + * can be dynamically programmed during operation and the settings * are applied faster on the hw. * * We call each data packet an "RF Bank" and all the data we write diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 35f23bdc442f243e485da8acb70d9f4fecd28977..ad57a6d2311067cc798889fef2336f9e63949511 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -32,6 +32,14 @@ config ATH9K_DEBUGFS Also required for changing debug message flags at run time. +config ATH9K_RATE_CONTROL + bool "Atheros ath9k rate control" + depends on ATH9K + default y + ---help--- + Say Y, if you want to use the ath9k specific rate control + module instead of minstrel_ht. + config ATH9K_HTC tristate "Atheros HTC based wireless cards support" depends on USB && MAC80211 diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 973ae4f49f35fbd122f5eeec4c352a397c10c33e..aca01621c205213a1b6503047f68c6d7da6dc25e 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -5,8 +5,8 @@ ath9k-y += beacon.o \ recv.o \ xmit.o \ virtual.o \ - rc.o +ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o ath9k-$(CONFIG_PCI) += pci.o ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o @@ -46,6 +46,7 @@ ath9k_htc-y += htc_hst.o \ htc_drv_txrx.o \ htc_drv_main.o \ htc_drv_beacon.o \ - htc_drv_init.o + htc_drv_init.o \ + htc_drv_gpio.o obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index a3d95cca8f0c5be9a32c76d57082da1206cd44d1..63ccb39cdcd4abc42717ea4bccc5c442c6c97f39 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -14,6 +14,7 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include "hw.h" #include "hw-ops.h" @@ -48,7 +49,7 @@ static const struct ani_ofdm_level_entry ofdm_level_table[] = { { 7, 8, 0 } /* lvl 9 */ }; #define ATH9K_ANI_OFDM_NUM_LEVEL \ - (sizeof(ofdm_level_table)/sizeof(ofdm_level_table[0])) + ARRAY_SIZE(ofdm_level_table) #define ATH9K_ANI_OFDM_MAX_LEVEL \ (ATH9K_ANI_OFDM_NUM_LEVEL-1) #define ATH9K_ANI_OFDM_DEF_LEVEL \ @@ -94,7 +95,7 @@ static const struct ani_cck_level_entry cck_level_table[] = { }; #define ATH9K_ANI_CCK_NUM_LEVEL \ - (sizeof(cck_level_table)/sizeof(cck_level_table[0])) + ARRAY_SIZE(cck_level_table) #define ATH9K_ANI_CCK_MAX_LEVEL \ (ATH9K_ANI_CCK_NUM_LEVEL-1) #define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \ @@ -102,31 +103,9 @@ static const struct ani_cck_level_entry cck_level_table[] = { #define ATH9K_ANI_CCK_DEF_LEVEL \ 2 /* default level - matches the INI settings */ -/* Private to ani.c */ -static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) +static bool use_new_ani(struct ath_hw *ah) { - ath9k_hw_private_ops(ah)->ani_lower_immunity(ah); -} - -int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { - if (ah->ani[i].c && - ah->ani[i].c->channel == chan->channel) - return i; - if (ah->ani[i].c == NULL) { - ah->ani[i].c = chan; - return i; - } - } - - ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, - "No more channel states left. Using channel 0\n"); - - return 0; + return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani; } static void ath9k_hw_update_mibstats(struct ath_hw *ah, @@ -139,82 +118,34 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah, stats->beacons += REG_READ(ah, AR_BEACON_CNT); } -static void ath9k_ani_restart_old(struct ath_hw *ah) +static void ath9k_ani_restart(struct ath_hw *ah) { struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); + u32 ofdm_base = 0, cck_base = 0; if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; aniState->listenTime = 0; - if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) { - aniState->ofdmPhyErrBase = 0; - ath_print(common, ATH_DBG_ANI, - "OFDM Trigger is too high for hw counters\n"); - } else { - aniState->ofdmPhyErrBase = - AR_PHY_COUNTMAX - aniState->ofdmTrigHigh; - } - if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) { - aniState->cckPhyErrBase = 0; - ath_print(common, ATH_DBG_ANI, - "CCK Trigger is too high for hw counters\n"); - } else { - aniState->cckPhyErrBase = - AR_PHY_COUNTMAX - aniState->cckTrigHigh; + if (!use_new_ani(ah)) { + ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; + cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; } - ath_print(common, ATH_DBG_ANI, - "Writing ofdmbase=%u cckbase=%u\n", - aniState->ofdmPhyErrBase, - aniState->cckPhyErrBase); - - ENABLE_REGWRITE_BUFFER(ah); - - REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); - REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); - - REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); - - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - - aniState->ofdmPhyErrCount = 0; - aniState->cckPhyErrCount = 0; -} - -static void ath9k_ani_restart_new(struct ath_hw *ah) -{ - struct ar5416AniState *aniState; - struct ath_common *common = ath9k_hw_common(ah); - - if (!DO_ANI(ah)) - return; - - aniState = ah->curani; - aniState->listenTime = 0; - - aniState->ofdmPhyErrBase = 0; - aniState->cckPhyErrBase = 0; ath_print(common, ATH_DBG_ANI, - "Writing ofdmbase=%08x cckbase=%08x\n", - aniState->ofdmPhyErrBase, - aniState->cckPhyErrBase); + "Writing ofdmbase=%u cckbase=%u\n", ofdm_base, cck_base); ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); + REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); + REG_WRITE(ah, AR_PHY_ERR_2, cck_base); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); @@ -228,10 +159,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) struct ar5416AniState *aniState; int32_t rssi; - if (!DO_ANI(ah)) - return; - - aniState = ah->curani; + aniState = &ah->curchan->ani; if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, @@ -300,10 +228,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) struct ar5416AniState *aniState; int32_t rssi; - if (!DO_ANI(ah)) - return; - - aniState = ah->curani; + aniState = &ah->curchan->ani; if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, aniState->noiseImmunityLevel + 1)) { @@ -335,7 +260,7 @@ static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) /* Adjust the OFDM Noise Immunity Level */ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; @@ -380,14 +305,19 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) } } -static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah) +static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) { struct ar5416AniState *aniState; if (!DO_ANI(ah)) return; - aniState = ah->curani; + if (!use_new_ani(ah)) { + ath9k_hw_ani_ofdm_err_trigger_old(ah); + return; + } + + aniState = &ah->curchan->ani; if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1); @@ -398,7 +328,7 @@ static void ath9k_hw_ani_ofdm_err_trigger_new(struct ath_hw *ah) */ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; @@ -437,14 +367,19 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) entry_cck->mrc_cck_on); } -static void ath9k_hw_ani_cck_err_trigger_new(struct ath_hw *ah) +static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) { struct ar5416AniState *aniState; if (!DO_ANI(ah)) return; - aniState = ah->curani; + if (!use_new_ani(ah)) { + ath9k_hw_ani_cck_err_trigger_old(ah); + return; + } + + aniState = &ah->curchan->ani; if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1); @@ -455,7 +390,7 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) struct ar5416AniState *aniState; int32_t rssi; - aniState = ah->curani; + aniState = &ah->curchan->ani; if (ah->opmode == NL80211_IFTYPE_AP) { if (aniState->firstepLevel > 0) { @@ -507,11 +442,16 @@ static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) * only lower either OFDM or CCK errors per turn * we lower the other one next time */ -static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah) +static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) { struct ar5416AniState *aniState; - aniState = ah->curani; + aniState = &ah->curchan->ani; + + if (!use_new_ani(ah)) { + ath9k_hw_ani_lower_immunity_old(ah); + return; + } /* lower OFDM noise immunity */ if (aniState->ofdmNoiseImmunityLevel > 0 && @@ -525,87 +465,18 @@ static void ath9k_hw_ani_lower_immunity_new(struct ath_hw *ah) ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); } -static u8 ath9k_hw_chan_2_clockrate_mhz(struct ath_hw *ah) -{ - struct ath9k_channel *chan = ah->curchan; - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; - u8 clockrate; /* in MHz */ - - if (!ah->curchan) /* should really check for CCK instead */ - clockrate = ATH9K_CLOCK_RATE_CCK; - else if (conf->channel->band == IEEE80211_BAND_2GHZ) - clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; - else if (IS_CHAN_A_FAST_CLOCK(ah, chan)) - clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; - else - clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; - - if (conf_is_ht40(conf)) - return clockrate * 2; - - return clockrate; -} - -static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah) -{ - struct ar5416AniState *aniState; - struct ath_common *common = ath9k_hw_common(ah); - u32 txFrameCount, rxFrameCount, cycleCount; - int32_t listenTime; - - txFrameCount = REG_READ(ah, AR_TFCNT); - rxFrameCount = REG_READ(ah, AR_RFCNT); - cycleCount = REG_READ(ah, AR_CCCNT); - - aniState = ah->curani; - if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) { - listenTime = 0; - ah->stats.ast_ani_lzero++; - ath_print(common, ATH_DBG_ANI, - "1st call: aniState->cycleCount=%d\n", - aniState->cycleCount); - } else { - int32_t ccdelta = cycleCount - aniState->cycleCount; - int32_t rfdelta = rxFrameCount - aniState->rxFrameCount; - int32_t tfdelta = txFrameCount - aniState->txFrameCount; - int32_t clock_rate; - - /* - * convert HW counter values to ms using mode - * specifix clock rate - */ - clock_rate = ath9k_hw_chan_2_clockrate_mhz(ah) * 1000;; - - listenTime = (ccdelta - rfdelta - tfdelta) / clock_rate; - - ath_print(common, ATH_DBG_ANI, - "cyclecount=%d, rfcount=%d, " - "tfcount=%d, listenTime=%d CLOCK_RATE=%d\n", - ccdelta, rfdelta, tfdelta, listenTime, clock_rate); - } - - aniState->cycleCount = cycleCount; - aniState->txFrameCount = txFrameCount; - aniState->rxFrameCount = rxFrameCount; - - return listenTime; -} - static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) { struct ar5416AniState *aniState; struct ath9k_channel *chan = ah->curchan; struct ath_common *common = ath9k_hw_common(ah); - int index; if (!DO_ANI(ah)) return; - index = ath9k_hw_get_ani_channel_idx(ah, chan); - aniState = &ah->ani[index]; - ah->curani = aniState; + aniState = &ah->curchan->ani; - if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION + if (ah->opmode != NL80211_IFTYPE_STATION && ah->opmode != NL80211_IFTYPE_ADHOC) { ath_print(common, ATH_DBG_ANI, "Reset ANI state opmode %u\n", ah->opmode); @@ -634,17 +505,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) | ATH9K_RX_FILTER_PHYERR); - if (ah->opmode == NL80211_IFTYPE_AP) { - ah->curani->ofdmTrigHigh = - ah->config.ofdm_trig_high; - ah->curani->ofdmTrigLow = - ah->config.ofdm_trig_low; - ah->curani->cckTrigHigh = - ah->config.cck_trig_high; - ah->curani->cckTrigLow = - ah->config.cck_trig_low; - } - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); return; } @@ -666,7 +527,7 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & ~ATH9K_RX_FILTER_PHYERR); - ath9k_ani_restart_old(ah); + ath9k_ani_restart(ah); ENABLE_REGWRITE_BUFFER(ah); @@ -674,7 +535,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } /* @@ -682,15 +542,18 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) * This routine should be called for every hardware reset and for * every channel change. */ -static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) +void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; struct ath9k_channel *chan = ah->curchan; struct ath_common *common = ath9k_hw_common(ah); if (!DO_ANI(ah)) return; + if (!use_new_ani(ah)) + return ath9k_ani_reset_old(ah, is_scanning); + BUG_ON(aniState == NULL); ah->stats.ast_ani_reset++; @@ -760,7 +623,7 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) * enable phy counters if hw supports or if not, enable phy * interrupts (so we can count each one) */ - ath9k_ani_restart_new(ah); + ath9k_ani_restart(ah); ENABLE_REGWRITE_BUFFER(ah); @@ -768,28 +631,30 @@ static void ath9k_ani_reset_new(struct ath_hw *ah, bool is_scanning) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } -static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, - struct ath9k_channel *chan) +static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) { - struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); - int32_t listenTime; - u32 phyCnt1, phyCnt2; + struct ar5416AniState *aniState = &ah->curchan->ani; + u32 ofdm_base = 0; + u32 cck_base = 0; u32 ofdmPhyErrCnt, cckPhyErrCnt; + u32 phyCnt1, phyCnt2; + int32_t listenTime; - if (!DO_ANI(ah)) - return; - - aniState = ah->curani; + ath_hw_cycle_counters_update(common); + listenTime = ath_hw_get_listen_time(common); - listenTime = ath9k_hw_ani_get_listen_time(ah); - if (listenTime < 0) { + if (listenTime <= 0) { ah->stats.ast_ani_lneg++; - ath9k_ani_restart_old(ah); - return; + ath9k_ani_restart(ah); + return false; + } + + if (!use_new_ani(ah)) { + ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; + cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; } aniState->listenTime += listenTime; @@ -799,145 +664,55 @@ static void ath9k_hw_ani_monitor_old(struct ath_hw *ah, phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - if (phyCnt1 < aniState->ofdmPhyErrBase || - phyCnt2 < aniState->cckPhyErrBase) { - if (phyCnt1 < aniState->ofdmPhyErrBase) { + if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { + if (phyCnt1 < ofdm_base) { ath_print(common, ATH_DBG_ANI, "phyCnt1 0x%x, resetting " "counter value to 0x%x\n", - phyCnt1, - aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_1, - aniState->ofdmPhyErrBase); + phyCnt1, ofdm_base); + REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); } - if (phyCnt2 < aniState->cckPhyErrBase) { + if (phyCnt2 < cck_base) { ath_print(common, ATH_DBG_ANI, "phyCnt2 0x%x, resetting " "counter value to 0x%x\n", - phyCnt2, - aniState->cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, - aniState->cckPhyErrBase); + phyCnt2, cck_base); + REG_WRITE(ah, AR_PHY_ERR_2, cck_base); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); } - return; + return false; } - ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; + ofdmPhyErrCnt = phyCnt1 - ofdm_base; ah->stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; aniState->ofdmPhyErrCount = ofdmPhyErrCnt; - cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; + cckPhyErrCnt = phyCnt2 - cck_base; ah->stats.ast_ani_cckerrs += cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; - - if (aniState->listenTime > 5 * ah->aniperiod) { - if (aniState->ofdmPhyErrCount <= aniState->listenTime * - aniState->ofdmTrigLow / 1000 && - aniState->cckPhyErrCount <= aniState->listenTime * - aniState->cckTrigLow / 1000) - ath9k_hw_ani_lower_immunity(ah); - ath9k_ani_restart_old(ah); - } else if (aniState->listenTime > ah->aniperiod) { - if (aniState->ofdmPhyErrCount > aniState->listenTime * - aniState->ofdmTrigHigh / 1000) { - ath9k_hw_ani_ofdm_err_trigger_old(ah); - ath9k_ani_restart_old(ah); - } else if (aniState->cckPhyErrCount > - aniState->listenTime * aniState->cckTrigHigh / - 1000) { - ath9k_hw_ani_cck_err_trigger_old(ah); - ath9k_ani_restart_old(ah); - } - } + return true; } -static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, - struct ath9k_channel *chan) +void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) { struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); - int32_t listenTime; - u32 phyCnt1, phyCnt2; - u32 ofdmPhyErrCnt, cckPhyErrCnt; u32 ofdmPhyErrRate, cckPhyErrRate; if (!DO_ANI(ah)) return; - aniState = ah->curani; + aniState = &ah->curchan->ani; if (WARN_ON(!aniState)) return; - listenTime = ath9k_hw_ani_get_listen_time(ah); - if (listenTime <= 0) { - ah->stats.ast_ani_lneg++; - /* restart ANI period if listenTime is invalid */ - ath_print(common, ATH_DBG_ANI, - "listenTime=%d - on new ani monitor\n", - listenTime); - ath9k_ani_restart_new(ah); - return; - } - - aniState->listenTime += listenTime; - - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - - phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); - phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - - if (phyCnt1 < aniState->ofdmPhyErrBase || - phyCnt2 < aniState->cckPhyErrBase) { - if (phyCnt1 < aniState->ofdmPhyErrBase) { - ath_print(common, ATH_DBG_ANI, - "phyCnt1 0x%x, resetting " - "counter value to 0x%x\n", - phyCnt1, - aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_1, - aniState->ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_MASK_1, - AR_PHY_ERR_OFDM_TIMING); - } - if (phyCnt2 < aniState->cckPhyErrBase) { - ath_print(common, ATH_DBG_ANI, - "phyCnt2 0x%x, resetting " - "counter value to 0x%x\n", - phyCnt2, - aniState->cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, - aniState->cckPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_MASK_2, - AR_PHY_ERR_CCK_TIMING); - } + if (!ath9k_hw_ani_read_counters(ah)) return; - } - - ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; - ah->stats.ast_ani_ofdmerrs += - ofdmPhyErrCnt - aniState->ofdmPhyErrCount; - aniState->ofdmPhyErrCount = ofdmPhyErrCnt; - - cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; - ah->stats.ast_ani_cckerrs += - cckPhyErrCnt - aniState->cckPhyErrCount; - aniState->cckPhyErrCount = cckPhyErrCnt; - - ath_print(common, ATH_DBG_ANI, - "Errors: OFDM=0x%08x-0x%08x=%d " - "CCK=0x%08x-0x%08x=%d\n", - phyCnt1, - aniState->ofdmPhyErrBase, - ofdmPhyErrCnt, - phyCnt2, - aniState->cckPhyErrBase, - cckPhyErrCnt); ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 / aniState->listenTime; @@ -947,61 +722,34 @@ static void ath9k_hw_ani_monitor_new(struct ath_hw *ah, ath_print(common, ATH_DBG_ANI, "listenTime=%d OFDM:%d errs=%d/s CCK:%d " "errs=%d/s ofdm_turn=%d\n", - listenTime, aniState->ofdmNoiseImmunityLevel, + aniState->listenTime, + aniState->ofdmNoiseImmunityLevel, ofdmPhyErrRate, aniState->cckNoiseImmunityLevel, cckPhyErrRate, aniState->ofdmsTurn); if (aniState->listenTime > 5 * ah->aniperiod) { - if (ofdmPhyErrRate <= aniState->ofdmTrigLow && - cckPhyErrRate <= aniState->cckTrigLow) { - ath_print(common, ATH_DBG_ANI, - "1. listenTime=%d OFDM:%d errs=%d/s(<%d) " - "CCK:%d errs=%d/s(<%d) -> " - "ath9k_hw_ani_lower_immunity()\n", - aniState->listenTime, - aniState->ofdmNoiseImmunityLevel, - ofdmPhyErrRate, - aniState->ofdmTrigLow, - aniState->cckNoiseImmunityLevel, - cckPhyErrRate, - aniState->cckTrigLow); + if (ofdmPhyErrRate <= ah->config.ofdm_trig_low && + cckPhyErrRate <= ah->config.cck_trig_low) { ath9k_hw_ani_lower_immunity(ah); aniState->ofdmsTurn = !aniState->ofdmsTurn; } - ath_print(common, ATH_DBG_ANI, - "1 listenTime=%d ofdm=%d/s cck=%d/s - " - "calling ath9k_ani_restart_new()\n", - aniState->listenTime, ofdmPhyErrRate, cckPhyErrRate); - ath9k_ani_restart_new(ah); + ath9k_ani_restart(ah); } else if (aniState->listenTime > ah->aniperiod) { /* check to see if need to raise immunity */ - if (ofdmPhyErrRate > aniState->ofdmTrigHigh && - (cckPhyErrRate <= aniState->cckTrigHigh || + if (ofdmPhyErrRate > ah->config.ofdm_trig_high && + (cckPhyErrRate <= ah->config.cck_trig_high || aniState->ofdmsTurn)) { - ath_print(common, ATH_DBG_ANI, - "2 listenTime=%d OFDM:%d errs=%d/s(>%d) -> " - "ath9k_hw_ani_ofdm_err_trigger_new()\n", - aniState->listenTime, - aniState->ofdmNoiseImmunityLevel, - ofdmPhyErrRate, - aniState->ofdmTrigHigh); - ath9k_hw_ani_ofdm_err_trigger_new(ah); - ath9k_ani_restart_new(ah); + ath9k_hw_ani_ofdm_err_trigger(ah); + ath9k_ani_restart(ah); aniState->ofdmsTurn = false; - } else if (cckPhyErrRate > aniState->cckTrigHigh) { - ath_print(common, ATH_DBG_ANI, - "3 listenTime=%d CCK:%d errs=%d/s(>%d) -> " - "ath9k_hw_ani_cck_err_trigger_new()\n", - aniState->listenTime, - aniState->cckNoiseImmunityLevel, - cckPhyErrRate, - aniState->cckTrigHigh); - ath9k_hw_ani_cck_err_trigger_new(ah); - ath9k_ani_restart_new(ah); + } else if (cckPhyErrRate > ah->config.cck_trig_high) { + ath9k_hw_ani_cck_err_trigger(ah); + ath9k_ani_restart(ah); aniState->ofdmsTurn = true; } } } +EXPORT_SYMBOL(ath9k_hw_ani_monitor); void ath9k_enable_mib_counters(struct ath_hw *ah) { @@ -1022,7 +770,6 @@ void ath9k_enable_mib_counters(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } /* Freeze the MIB counters, get the stats and then clear them */ @@ -1040,53 +787,12 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); -u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, - u32 *rxc_pcnt, - u32 *rxf_pcnt, - u32 *txf_pcnt) -{ - struct ath_common *common = ath9k_hw_common(ah); - static u32 cycles, rx_clear, rx_frame, tx_frame; - u32 good = 1; - - u32 rc = REG_READ(ah, AR_RCCNT); - u32 rf = REG_READ(ah, AR_RFCNT); - u32 tf = REG_READ(ah, AR_TFCNT); - u32 cc = REG_READ(ah, AR_CCCNT); - - if (cycles == 0 || cycles > cc) { - ath_print(common, ATH_DBG_ANI, - "cycle counter wrap. ExtBusy = 0\n"); - good = 0; - } else { - u32 cc_d = cc - cycles; - u32 rc_d = rc - rx_clear; - u32 rf_d = rf - rx_frame; - u32 tf_d = tf - tx_frame; - - if (cc_d != 0) { - *rxc_pcnt = rc_d * 100 / cc_d; - *rxf_pcnt = rf_d * 100 / cc_d; - *txf_pcnt = tf_d * 100 / cc_d; - } else { - good = 0; - } - } - - cycles = cc; - rx_frame = rf; - rx_clear = rc; - tx_frame = tf; - - return good; -} - /* * Process a MIB interrupt. We may potentially be invoked because * any of the MIB counters overflow/trigger so don't assume we're * here because a PHY error counter triggered. */ -static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) +void ath9k_hw_proc_mib_event(struct ath_hw *ah) { u32 phyCnt1, phyCnt2; @@ -1114,72 +820,15 @@ static void ath9k_hw_proc_mib_event_old(struct ath_hw *ah) phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { - struct ar5416AniState *aniState = ah->curani; - u32 ofdmPhyErrCnt, cckPhyErrCnt; - - /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ - ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; - ah->stats.ast_ani_ofdmerrs += - ofdmPhyErrCnt - aniState->ofdmPhyErrCount; - aniState->ofdmPhyErrCount = ofdmPhyErrCnt; - cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase; - ah->stats.ast_ani_cckerrs += - cckPhyErrCnt - aniState->cckPhyErrCount; - aniState->cckPhyErrCount = cckPhyErrCnt; + if (!use_new_ani(ah)) + ath9k_hw_ani_read_counters(ah); - /* - * NB: figure out which counter triggered. If both - * trigger we'll only deal with one as the processing - * clobbers the error counter so the trigger threshold - * check will never be true. - */ - if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) - ath9k_hw_ani_ofdm_err_trigger_new(ah); - if (aniState->cckPhyErrCount > aniState->cckTrigHigh) - ath9k_hw_ani_cck_err_trigger_old(ah); /* NB: always restart to insure the h/w counters are reset */ - ath9k_ani_restart_old(ah); - } -} - -/* - * Process a MIB interrupt. We may potentially be invoked because - * any of the MIB counters overflow/trigger so don't assume we're - * here because a PHY error counter triggered. - */ -static void ath9k_hw_proc_mib_event_new(struct ath_hw *ah) -{ - u32 phyCnt1, phyCnt2; - - /* Reset these counters regardless */ - REG_WRITE(ah, AR_FILT_OFDM, 0); - REG_WRITE(ah, AR_FILT_CCK, 0); - if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) - REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); - - /* Clear the mib counters and save them in the stats */ - ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); - - if (!DO_ANI(ah)) { - /* - * We must always clear the interrupt cause by - * resetting the phy error regs. - */ - REG_WRITE(ah, AR_PHY_ERR_1, 0); - REG_WRITE(ah, AR_PHY_ERR_2, 0); - return; + ath9k_ani_restart(ah); } - - /* NB: these are not reset-on-read */ - phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); - phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - - /* NB: always restart to insure the h/w counters are reset */ - if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || - ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) - ath9k_ani_restart_new(ah); } +EXPORT_SYMBOL(ath9k_hw_proc_mib_event); void ath9k_hw_ani_setup(struct ath_hw *ah) { @@ -1205,61 +854,58 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ath_print(common, ATH_DBG_ANI, "Initialize ANI\n"); - memset(ah->ani, 0, sizeof(ah->ani)); - for (i = 0; i < ARRAY_SIZE(ah->ani); i++) { - if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { - ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; - ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_NEW; + if (use_new_ani(ah)) { + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW; - ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_NEW; - ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_NEW; + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW; + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW; + } else { + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD; - ah->ani[i].spurImmunityLevel = - ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD; + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD; + } - ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + for (i = 0; i < ARRAY_SIZE(ah->channels); i++) { + struct ath9k_channel *chan = &ah->channels[i]; + struct ar5416AniState *ani = &chan->ani; - ah->ani[i].ofdmPhyErrBase = 0; - ah->ani[i].cckPhyErrBase = 0; + if (use_new_ani(ah)) { + ani->spurImmunityLevel = + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + + ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; if (AR_SREV_9300_20_OR_LATER(ah)) - ah->ani[i].mrcCCKOff = + ani->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; else - ah->ani[i].mrcCCKOff = true; + ani->mrcCCKOff = true; - ah->ani[i].ofdmsTurn = true; + ani->ofdmsTurn = true; } else { - ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; - ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW_OLD; - - ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH_OLD; - ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW_OLD; - - ah->ani[i].spurImmunityLevel = + ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_OLD; - ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; + ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; - ah->ani[i].ofdmPhyErrBase = - AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH_OLD; - ah->ani[i].cckPhyErrBase = - AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH_OLD; - ah->ani[i].cckWeakSigThreshold = + ani->cckWeakSigThreshold = ATH9K_ANI_CCK_WEAK_SIG_THR; } - ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; - ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; - ah->ani[i].ofdmWeakSigDetectOff = + ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; + ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; + ani->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; - ah->ani[i].cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; + ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; } /* * since we expect some ongoing maintenance on the tables, let's sanity * check here default level should not modify INI setting. */ - if (AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani) { + if (use_new_ani(ah)) { const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; @@ -1273,50 +919,9 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD; } - ath_print(common, ATH_DBG_ANI, - "Setting OfdmErrBase = 0x%08x\n", - ah->ani[0].ofdmPhyErrBase); - ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n", - ah->ani[0].cckPhyErrBase); - - ENABLE_REGWRITE_BUFFER(ah); - - REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase); - REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase); - - REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); - - ath9k_enable_mib_counters(ah); - if (ah->config.enable_ani) ah->proc_phyerr |= HAL_PROCESS_ANI; -} - -void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah) -{ - struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); - struct ath_hw_ops *ops = ath9k_hw_ops(ah); - - priv_ops->ani_reset = ath9k_ani_reset_old; - priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_old; - - ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_old; - ops->ani_monitor = ath9k_hw_ani_monitor_old; - ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v1\n"); -} - -void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah) -{ - struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); - struct ath_hw_ops *ops = ath9k_hw_ops(ah); - - priv_ops->ani_reset = ath9k_ani_reset_new; - priv_ops->ani_lower_immunity = ath9k_hw_ani_lower_immunity_new; - - ops->ani_proc_mib_event = ath9k_hw_proc_mib_event_new; - ops->ani_monitor = ath9k_hw_ani_monitor_new; - - ath_print(ath9k_hw_common(ah), ATH_DBG_ANY, "Using ANI v2\n"); + ath9k_ani_restart(ah); + ath9k_enable_mib_counters(ah); } diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index f4d0a4d48b37b18ec3e3f0f828f6b30743d19147..0cd6783de883668d2f433bfb07f5ffe0c47863cb 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h @@ -19,7 +19,7 @@ #define HAL_PROCESS_ANI 0x00000001 -#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI)) +#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan) #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) @@ -123,20 +123,11 @@ struct ar5416AniState { u8 ofdmWeakSigDetectOff; u8 cckWeakSigThreshold; u32 listenTime; - u32 ofdmTrigHigh; - u32 ofdmTrigLow; - int32_t cckTrigHigh; - int32_t cckTrigLow; int32_t rssiThrLow; int32_t rssiThrHigh; u32 noiseFloor; - u32 txFrameCount; - u32 rxFrameCount; - u32 cycleCount; u32 ofdmPhyErrCount; u32 cckPhyErrCount; - u32 ofdmPhyErrBase; - u32 cckPhyErrBase; int16_t pktRssi[2]; int16_t ofdmErrRssi[2]; int16_t cckErrRssi[2]; @@ -166,8 +157,6 @@ struct ar5416Stats { void ath9k_enable_mib_counters(struct ath_hw *ah); void ath9k_hw_disable_mib_counters(struct ath_hw *ah); -u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, - u32 *rxf_pcnt, u32 *txf_pcnt); void ath9k_hw_ani_setup(struct ath_hw *ah); void ath9k_hw_ani_init(struct ath_hw *ah); int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 3d2c8679bc85301f83f3499a161d3cbe91fbd1e3..ea9f4497f58c79bd491d84181a605e7b251f4b91 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -118,7 +118,7 @@ static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) if (!AR_SREV_5416(ah) || synth_freq >= 3000) return; - BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); + BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); if (synth_freq < 2412) new_bias = 0; @@ -454,7 +454,7 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); - BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); + BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); @@ -484,7 +484,7 @@ static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah) bank = NULL; \ } while (0); - BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); + BUG_ON(AR_SREV_9280_20_OR_LATER(ah)); ATH_FREE_BANK(ah->analogBank0Data); ATH_FREE_BANK(ah->analogBank1Data); @@ -525,7 +525,7 @@ static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, * for single chip devices, that is AR9280 or anything * after that. */ - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) return true; /* Setup rf parameters */ @@ -613,14 +613,11 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah) rx_chainmask = ah->rxchainmask; tx_chainmask = ah->txchainmask; - ENABLE_REGWRITE_BUFFER(ah); switch (rx_chainmask) { case 0x5: - DISABLE_REGWRITE_BUFFER(ah); REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, AR_PHY_SWAP_ALT_CHAIN); - ENABLE_REGWRITE_BUFFER(ah); case 0x3: if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); @@ -630,17 +627,18 @@ static void ar5008_hw_init_chain_masks(struct ath_hw *ah) case 0x1: case 0x2: case 0x7: + ENABLE_REGWRITE_BUFFER(ah); REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); break; default: + ENABLE_REGWRITE_BUFFER(ah); break; } REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (tx_chainmask == 0x5) { REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, @@ -663,20 +661,20 @@ static void ar5008_hw_override_ini(struct ath_hw *ah, */ REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { val = REG_READ(ah, AR_PCU_MISC_MODE2); if (!AR_SREV_9271(ah)) val &= ~AR_PCU_MISC_MODE2_HWWAR1; - if (AR_SREV_9287_10_OR_LATER(ah)) + if (AR_SREV_9287_11_OR_LATER(ah)) val = val & (~AR_PCU_MISC_MODE2_HWWAR2); REG_WRITE(ah, AR_PCU_MISC_MODE2, val); } if (!AR_SREV_5416_20_OR_LATER(ah) || - AR_SREV_9280_10_OR_LATER(ah)) + AR_SREV_9280_20_OR_LATER(ah)) return; /* * Disable BB clock gating @@ -701,7 +699,7 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah, u32 phymode; u32 enableDacFifo = 0; - if (AR_SREV_9285_10_OR_LATER(ah)) + if (AR_SREV_9285_12_OR_LATER(ah)) enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & AR_PHY_FC_ENABLE_DAC_FIFO); @@ -726,7 +724,6 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah, REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } @@ -818,13 +815,12 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); - if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah)) + if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah)) REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) || - AR_SREV_9287_10_OR_LATER(ah)) + AR_SREV_9287_11_OR_LATER(ah)) REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); if (AR_SREV_9271_10(ah)) @@ -849,7 +845,6 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (AR_SREV_9271(ah)) { if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) @@ -900,7 +895,7 @@ static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; - if (!AR_SREV_9280_10_OR_LATER(ah)) + if (!AR_SREV_9280_20_OR_LATER(ah)) rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; @@ -1053,7 +1048,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) { - struct ar5416AniState *aniState = ah->curani; + struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); switch (cmd & ah->ani_function) { @@ -1225,8 +1220,7 @@ static bool ar5008_hw_ani_control_old(struct ath_hw *ah, aniState->firstepLevel, aniState->listenTime); ath_print(common, ATH_DBG_ANI, - "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", - aniState->cycleCount, + "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); @@ -1237,9 +1231,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) { - struct ar5416AniState *aniState = ah->curani; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; + struct ar5416AniState *aniState = &chan->ani; s32 value, value2; switch (cmd & ah->ani_function) { @@ -1478,15 +1472,13 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, ath_print(common, ATH_DBG_ANI, "ANI parameters: SI=%d, ofdmWS=%s FS=%d " - "MRCcck=%s listenTime=%d CC=%d listen=%d " + "MRCcck=%s listenTime=%d " "ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, !aniState->ofdmWeakSigDetectOff ? "on" : "off", aniState->firstepLevel, !aniState->mrcCCKOff ? "on" : "off", aniState->listenTime, - aniState->cycleCount, - aniState->listenTime, aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); return true; @@ -1526,16 +1518,12 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah, */ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) { - struct ar5416AniState *aniState; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; + struct ar5416AniState *aniState = &chan->ani; struct ath9k_ani_default *iniDef; - int index; u32 val; - index = ath9k_hw_get_ani_channel_idx(ah, chan); - aniState = &ah->ani[index]; - ah->curani = aniState; iniDef = &aniState->iniDef; ath_print(common, ATH_DBG_ANI, @@ -1579,8 +1567,6 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; aniState->mrcCCKOff = true; /* not available on pre AR9003 */ - - aniState->cycleCount = 0; } static void ar5008_hw_set_nf_limits(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index fe7418aefc4a994b00109e98bac4edc7d0e67a6e..15f62cd0cc38a239ceac760e55eff1c9d4c1db92 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -20,6 +20,13 @@ #define AR9285_CLCAL_REDO_THRESH 1 +enum ar9002_cal_types { + ADC_GAIN_CAL = BIT(0), + ADC_DC_CAL = BIT(1), + IQ_MISMATCH_CAL = BIT(2), +}; + + static void ar9002_hw_setup_calibration(struct ath_hw *ah, struct ath9k_cal_list *currCal) { @@ -45,13 +52,6 @@ static void ar9002_hw_setup_calibration(struct ath_hw *ah, ath_print(common, ATH_DBG_CALIBRATE, "starting ADC DC Calibration\n"); break; - case ADC_DC_INIT_CAL: - REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); - ath_print(common, ATH_DBG_CALIBRATE, - "starting Init ADC DC Calibration\n"); - break; - case TEMP_COMP_CAL: - break; /* Not supported */ } REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), @@ -96,25 +96,6 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah, return iscaldone; } -/* Assumes you are talking about the currently configured channel */ -static bool ar9002_hw_iscal_supported(struct ath_hw *ah, - enum ath9k_cal_types calType) -{ - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; - - switch (calType & ah->supp_cals) { - case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ - return true; - case ADC_GAIN_CAL: - case ADC_DC_CAL: - if (!(conf->channel->band == IEEE80211_BAND_2GHZ && - conf_is_ht20(conf))) - return true; - break; - } - return false; -} - static void ar9002_hw_iqcal_collect(struct ath_hw *ah) { int i; @@ -541,7 +522,6 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset) REG_WRITE(ah, regList[i][0], regList[i][1]); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) @@ -567,11 +547,6 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) AR5416_EEP_TXGAIN_HIGH_POWER) return; - if (AR_SREV_9285_11(ah)) { - REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); - udelay(10); - } - for (i = 0; i < ARRAY_SIZE(regList); i++) regList[i][1] = REG_READ(ah, regList[i][0]); @@ -651,10 +626,6 @@ static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) REG_WRITE(ah, regList[i][0], regList[i][1]); REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org); - - if (AR_SREV_9285_11(ah)) - REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); - } static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset) @@ -664,7 +635,7 @@ static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset) ar9271_hw_pa_cal(ah, is_reset); else ah->pacal_info.skipcount--; - } else if (AR_SREV_9285_11_OR_LATER(ah)) { + } else if (AR_SREV_9285_12_OR_LATER(ah)) { if (is_reset || !ah->pacal_info.skipcount) ar9285_hw_pa_cal(ah, is_reset); else @@ -841,8 +812,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) if (!ar9285_hw_clc(ah, chan)) return false; } else { - if (AR_SREV_9280_10_OR_LATER(ah)) { - if (!AR_SREV_9287_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) { + if (!AR_SREV_9287_11_OR_LATER(ah)) REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, @@ -864,8 +835,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) return false; } - if (AR_SREV_9280_10_OR_LATER(ah)) { - if (!AR_SREV_9287_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) { + if (!AR_SREV_9287_11_OR_LATER(ah)) REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, @@ -886,24 +857,28 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) /* Enable IQ, ADC Gain and ADC DC offset CALs */ if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { - if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) { + ah->supp_cals = IQ_MISMATCH_CAL; + + if (AR_SREV_9160_10_OR_LATER(ah) && + !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) { + ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL; + + INIT_CAL(&ah->adcgain_caldata); INSERT_CAL(ah, &ah->adcgain_caldata); ath_print(common, ATH_DBG_CALIBRATE, "enabling ADC Gain Calibration.\n"); - } - if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) { + INIT_CAL(&ah->adcdc_caldata); INSERT_CAL(ah, &ah->adcdc_caldata); ath_print(common, ATH_DBG_CALIBRATE, "enabling ADC DC Calibration.\n"); } - if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { - INIT_CAL(&ah->iq_caldata); - INSERT_CAL(ah, &ah->iq_caldata); - ath_print(common, ATH_DBG_CALIBRATE, - "enabling IQ Calibration.\n"); - } + + INIT_CAL(&ah->iq_caldata); + INSERT_CAL(ah, &ah->iq_caldata); + ath_print(common, ATH_DBG_CALIBRATE, + "enabling IQ Calibration.\n"); ah->cal_list_curr = ah->cal_list; @@ -959,13 +934,6 @@ static const struct ath9k_percal_data adc_dc_cal_single_sample = { ar9002_hw_adc_dccal_collect, ar9002_hw_adc_dccal_calibrate }; -static const struct ath9k_percal_data adc_init_dc_cal = { - ADC_DC_INIT_CAL, - MIN_CAL_SAMPLES, - INIT_LOG_COUNT, - ar9002_hw_adc_dccal_collect, - ar9002_hw_adc_dccal_calibrate -}; static void ar9002_hw_init_cal_settings(struct ath_hw *ah) { @@ -976,22 +944,18 @@ static void ar9002_hw_init_cal_settings(struct ath_hw *ah) } if (AR_SREV_9160_10_OR_LATER(ah)) { - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { ah->iq_caldata.calData = &iq_cal_single_sample; ah->adcgain_caldata.calData = &adc_gain_cal_single_sample; ah->adcdc_caldata.calData = &adc_dc_cal_single_sample; - ah->adcdc_calinitdata.calData = - &adc_init_dc_cal; } else { ah->iq_caldata.calData = &iq_cal_multi_sample; ah->adcgain_caldata.calData = &adc_gain_cal_multi_sample; ah->adcdc_caldata.calData = &adc_dc_cal_multi_sample; - ah->adcdc_calinitdata.calData = - &adc_init_dc_cal; } ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; } @@ -1005,7 +969,6 @@ void ar9002_hw_attach_calib_ops(struct ath_hw *ah) priv_ops->init_cal_settings = ar9002_hw_init_cal_settings; priv_ops->init_cal = ar9002_hw_init_cal; priv_ops->setup_calibration = ar9002_hw_setup_calibration; - priv_ops->iscal_supported = ar9002_hw_iscal_supported; ops->calibrate = ar9002_hw_calibrate; } diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 303c63da5ea384b56f4eefbdb21dfb770fddda27..a0471f2e1c7a0e8cadb92adb09aa06d3b0b7a1ef 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -371,7 +371,6 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } udelay(1000); @@ -468,7 +467,6 @@ static int ar9002_hw_get_radiorev(struct ath_hw *ah) REG_WRITE(ah, AR_PHY(0x20), 0x00010000); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); @@ -569,14 +567,57 @@ void ar9002_hw_attach_ops(struct ath_hw *ah) ops->config_pci_powersave = ar9002_hw_configpcipowersave; ar5008_hw_attach_phy_ops(ah); - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) ar9002_hw_attach_phy_ops(ah); ar9002_hw_attach_calib_ops(ah); ar9002_hw_attach_mac_ops(ah); +} + +void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) +{ + u32 modesIndex; + int i; + + switch (chan->chanmode) { + case CHANNEL_A: + case CHANNEL_A_HT20: + modesIndex = 1; + break; + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + modesIndex = 2; + break; + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_B: + modesIndex = 4; + break; + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + modesIndex = 3; + break; + + default: + return; + } + + ENABLE_REGWRITE_BUFFER(ah); - if (modparam_force_new_ani) - ath9k_hw_attach_ani_ops_new(ah); - else - ath9k_hw_attach_ani_ops_old(ah); + for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) { + u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0); + u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex); + u32 val_orig; + + if (reg == AR_PHY_CCK_DETECT) { + val_orig = REG_READ(ah, reg); + val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK; + val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK; + + REG_WRITE(ah, reg, val|val_orig); + } else + REG_WRITE(ah, reg, val); + } + + REGWRITE_BUFFER_FLUSH(ah); } diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index adbf031fbc5a7bd37c90590870c908d3719e8be7..c00cdc67b55ba5291f9ebc758d342f7dfb3184a1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -415,7 +415,6 @@ static void ar9002_hw_spur_mitigate(struct ath_hw *ah, REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static void ar9002_olc_init(struct ath_hw *ah) @@ -530,3 +529,38 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah) ar9002_hw_set_nf_limits(ah); } + +void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf) +{ + u32 regval; + + regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); + antconf->main_lna_conf = (regval & AR_PHY_9285_ANT_DIV_MAIN_LNACONF) >> + AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S; + antconf->alt_lna_conf = (regval & AR_PHY_9285_ANT_DIV_ALT_LNACONF) >> + AR_PHY_9285_ANT_DIV_ALT_LNACONF_S; + antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >> + AR_PHY_9285_FAST_DIV_BIAS_S; +} +EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get); + +void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf) +{ + u32 regval; + + regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL); + regval &= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF | + AR_PHY_9285_ANT_DIV_ALT_LNACONF | + AR_PHY_9285_FAST_DIV_BIAS); + regval |= ((antconf->main_lna_conf << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S) + & AR_PHY_9285_ANT_DIV_MAIN_LNACONF); + regval |= ((antconf->alt_lna_conf << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S) + & AR_PHY_9285_ANT_DIV_ALT_LNACONF); + regval |= ((antconf->fast_div_bias << AR_PHY_9285_FAST_DIV_BIAS_S) + & AR_PHY_9285_FAST_DIV_BIAS); + + REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval); +} +EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h index c5151a4dd10bb01e742e7d9aaa2932519d40afd8..37663dbbcf57959f9b9afb15fe5b15e0efd613cd 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h @@ -302,6 +302,8 @@ #define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 #define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac +#define AR_PHY_9285_FAST_DIV_BIAS 0x00007E00 +#define AR_PHY_9285_FAST_DIV_BIAS_S 9 #define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000 #define AR_PHY_9285_ANT_DIV_CTL 0x01000000 #define AR_PHY_9285_ANT_DIV_CTL_S 24 diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h deleted file mode 100644 index d3375fc4ce8b22f6dda995d7a0ffacbd09bc6892..0000000000000000000000000000000000000000 --- a/drivers/net/wireless/ath/ath9k/ar9003_2p0_initvals.h +++ /dev/null @@ -1,1784 +0,0 @@ -/* - * Copyright (c) 2010 Atheros Communications Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef INITVALS_9003_2P0_H -#define INITVALS_9003_2P0_H - -/* AR9003 2.0 */ - -static const u32 ar9300_2p0_radio_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, - {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, - {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, - {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, - {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, - {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, -}; - -static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, - {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, - {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, - {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, - {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, - {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, - {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, - {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, - {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, - {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, - {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, - {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, - {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -}; - -static const u32 ar9300Modes_fast_clock_2p0[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00001030, 0x00000268, 0x000004d0}, - {0x00001070, 0x0000018c, 0x00000318}, - {0x000010b0, 0x00000fd0, 0x00001fa0}, - {0x00008014, 0x044c044c, 0x08980898}, - {0x0000801c, 0x148ec02b, 0x148ec057}, - {0x00008318, 0x000044c0, 0x00008980}, - {0x00009e00, 0x03721821, 0x03721821}, - {0x0000a230, 0x0000000b, 0x00000016}, - {0x0000a254, 0x00000898, 0x00001130}, -}; - -static const u32 ar9300_2p0_radio_core[][2] = { - /* Addr allmodes */ - {0x00016000, 0x36db6db6}, - {0x00016004, 0x6db6db40}, - {0x00016008, 0x73f00000}, - {0x0001600c, 0x00000000}, - {0x00016040, 0x7f80fff8}, - {0x0001604c, 0x76d005b5}, - {0x00016050, 0x556cf031}, - {0x00016054, 0x13449440}, - {0x00016058, 0x0c51c92c}, - {0x0001605c, 0x3db7fffc}, - {0x00016060, 0xfffffffc}, - {0x00016064, 0x000f0278}, - {0x0001606c, 0x6db60000}, - {0x00016080, 0x00000000}, - {0x00016084, 0x0e48048c}, - {0x00016088, 0x54214514}, - {0x0001608c, 0x119f481e}, - {0x00016090, 0x24926490}, - {0x00016098, 0xd2888888}, - {0x000160a0, 0x0a108ffe}, - {0x000160a4, 0x812fc370}, - {0x000160a8, 0x423c8000}, - {0x000160b4, 0x92480080}, - {0x000160c0, 0x00adb6d0}, - {0x000160c4, 0x6db6db60}, - {0x000160c8, 0x6db6db6c}, - {0x000160cc, 0x01e6c000}, - {0x00016100, 0x3fffbe01}, - {0x00016104, 0xfff80000}, - {0x00016108, 0x00080010}, - {0x00016144, 0x02084080}, - {0x00016148, 0x00000000}, - {0x00016280, 0x058a0001}, - {0x00016284, 0x3d840208}, - {0x00016288, 0x05a20408}, - {0x0001628c, 0x00038c07}, - {0x00016290, 0x40000004}, - {0x00016294, 0x458aa14f}, - {0x00016380, 0x00000000}, - {0x00016384, 0x00000000}, - {0x00016388, 0x00800700}, - {0x0001638c, 0x00800700}, - {0x00016390, 0x00800700}, - {0x00016394, 0x00000000}, - {0x00016398, 0x00000000}, - {0x0001639c, 0x00000000}, - {0x000163a0, 0x00000001}, - {0x000163a4, 0x00000001}, - {0x000163a8, 0x00000000}, - {0x000163ac, 0x00000000}, - {0x000163b0, 0x00000000}, - {0x000163b4, 0x00000000}, - {0x000163b8, 0x00000000}, - {0x000163bc, 0x00000000}, - {0x000163c0, 0x000000a0}, - {0x000163c4, 0x000c0000}, - {0x000163c8, 0x14021402}, - {0x000163cc, 0x00001402}, - {0x000163d0, 0x00000000}, - {0x000163d4, 0x00000000}, - {0x00016400, 0x36db6db6}, - {0x00016404, 0x6db6db40}, - {0x00016408, 0x73f00000}, - {0x0001640c, 0x00000000}, - {0x00016440, 0x7f80fff8}, - {0x0001644c, 0x76d005b5}, - {0x00016450, 0x556cf031}, - {0x00016454, 0x13449440}, - {0x00016458, 0x0c51c92c}, - {0x0001645c, 0x3db7fffc}, - {0x00016460, 0xfffffffc}, - {0x00016464, 0x000f0278}, - {0x0001646c, 0x6db60000}, - {0x00016500, 0x3fffbe01}, - {0x00016504, 0xfff80000}, - {0x00016508, 0x00080010}, - {0x00016544, 0x02084080}, - {0x00016548, 0x00000000}, - {0x00016780, 0x00000000}, - {0x00016784, 0x00000000}, - {0x00016788, 0x00800700}, - {0x0001678c, 0x00800700}, - {0x00016790, 0x00800700}, - {0x00016794, 0x00000000}, - {0x00016798, 0x00000000}, - {0x0001679c, 0x00000000}, - {0x000167a0, 0x00000001}, - {0x000167a4, 0x00000001}, - {0x000167a8, 0x00000000}, - {0x000167ac, 0x00000000}, - {0x000167b0, 0x00000000}, - {0x000167b4, 0x00000000}, - {0x000167b8, 0x00000000}, - {0x000167bc, 0x00000000}, - {0x000167c0, 0x000000a0}, - {0x000167c4, 0x000c0000}, - {0x000167c8, 0x14021402}, - {0x000167cc, 0x00001402}, - {0x000167d0, 0x00000000}, - {0x000167d4, 0x00000000}, - {0x00016800, 0x36db6db6}, - {0x00016804, 0x6db6db40}, - {0x00016808, 0x73f00000}, - {0x0001680c, 0x00000000}, - {0x00016840, 0x7f80fff8}, - {0x0001684c, 0x76d005b5}, - {0x00016850, 0x556cf031}, - {0x00016854, 0x13449440}, - {0x00016858, 0x0c51c92c}, - {0x0001685c, 0x3db7fffc}, - {0x00016860, 0xfffffffc}, - {0x00016864, 0x000f0278}, - {0x0001686c, 0x6db60000}, - {0x00016900, 0x3fffbe01}, - {0x00016904, 0xfff80000}, - {0x00016908, 0x00080010}, - {0x00016944, 0x02084080}, - {0x00016948, 0x00000000}, - {0x00016b80, 0x00000000}, - {0x00016b84, 0x00000000}, - {0x00016b88, 0x00800700}, - {0x00016b8c, 0x00800700}, - {0x00016b90, 0x00800700}, - {0x00016b94, 0x00000000}, - {0x00016b98, 0x00000000}, - {0x00016b9c, 0x00000000}, - {0x00016ba0, 0x00000001}, - {0x00016ba4, 0x00000001}, - {0x00016ba8, 0x00000000}, - {0x00016bac, 0x00000000}, - {0x00016bb0, 0x00000000}, - {0x00016bb4, 0x00000000}, - {0x00016bb8, 0x00000000}, - {0x00016bbc, 0x00000000}, - {0x00016bc0, 0x000000a0}, - {0x00016bc4, 0x000c0000}, - {0x00016bc8, 0x14021402}, - {0x00016bcc, 0x00001402}, - {0x00016bd0, 0x00000000}, - {0x00016bd4, 0x00000000}, -}; - -static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x02000101}, - {0x0000a004, 0x02000102}, - {0x0000a008, 0x02000103}, - {0x0000a00c, 0x02000104}, - {0x0000a010, 0x02000200}, - {0x0000a014, 0x02000201}, - {0x0000a018, 0x02000202}, - {0x0000a01c, 0x02000203}, - {0x0000a020, 0x02000204}, - {0x0000a024, 0x02000205}, - {0x0000a028, 0x02000208}, - {0x0000a02c, 0x02000302}, - {0x0000a030, 0x02000303}, - {0x0000a034, 0x02000304}, - {0x0000a038, 0x02000400}, - {0x0000a03c, 0x02010300}, - {0x0000a040, 0x02010301}, - {0x0000a044, 0x02010302}, - {0x0000a048, 0x02000500}, - {0x0000a04c, 0x02010400}, - {0x0000a050, 0x02020300}, - {0x0000a054, 0x02020301}, - {0x0000a058, 0x02020302}, - {0x0000a05c, 0x02020303}, - {0x0000a060, 0x02020400}, - {0x0000a064, 0x02030300}, - {0x0000a068, 0x02030301}, - {0x0000a06c, 0x02030302}, - {0x0000a070, 0x02030303}, - {0x0000a074, 0x02030400}, - {0x0000a078, 0x02040300}, - {0x0000a07c, 0x02040301}, - {0x0000a080, 0x02040302}, - {0x0000a084, 0x02040303}, - {0x0000a088, 0x02030500}, - {0x0000a08c, 0x02040400}, - {0x0000a090, 0x02050203}, - {0x0000a094, 0x02050204}, - {0x0000a098, 0x02050205}, - {0x0000a09c, 0x02040500}, - {0x0000a0a0, 0x02050301}, - {0x0000a0a4, 0x02050302}, - {0x0000a0a8, 0x02050303}, - {0x0000a0ac, 0x02050400}, - {0x0000a0b0, 0x02050401}, - {0x0000a0b4, 0x02050402}, - {0x0000a0b8, 0x02050403}, - {0x0000a0bc, 0x02050500}, - {0x0000a0c0, 0x02050501}, - {0x0000a0c4, 0x02050502}, - {0x0000a0c8, 0x02050503}, - {0x0000a0cc, 0x02050504}, - {0x0000a0d0, 0x02050600}, - {0x0000a0d4, 0x02050601}, - {0x0000a0d8, 0x02050602}, - {0x0000a0dc, 0x02050603}, - {0x0000a0e0, 0x02050604}, - {0x0000a0e4, 0x02050700}, - {0x0000a0e8, 0x02050701}, - {0x0000a0ec, 0x02050702}, - {0x0000a0f0, 0x02050703}, - {0x0000a0f4, 0x02050704}, - {0x0000a0f8, 0x02050705}, - {0x0000a0fc, 0x02050708}, - {0x0000a100, 0x02050709}, - {0x0000a104, 0x0205070a}, - {0x0000a108, 0x0205070b}, - {0x0000a10c, 0x0205070c}, - {0x0000a110, 0x0205070d}, - {0x0000a114, 0x02050710}, - {0x0000a118, 0x02050711}, - {0x0000a11c, 0x02050712}, - {0x0000a120, 0x02050713}, - {0x0000a124, 0x02050714}, - {0x0000a128, 0x02050715}, - {0x0000a12c, 0x02050730}, - {0x0000a130, 0x02050731}, - {0x0000a134, 0x02050732}, - {0x0000a138, 0x02050733}, - {0x0000a13c, 0x02050734}, - {0x0000a140, 0x02050735}, - {0x0000a144, 0x02050750}, - {0x0000a148, 0x02050751}, - {0x0000a14c, 0x02050752}, - {0x0000a150, 0x02050753}, - {0x0000a154, 0x02050754}, - {0x0000a158, 0x02050755}, - {0x0000a15c, 0x02050770}, - {0x0000a160, 0x02050771}, - {0x0000a164, 0x02050772}, - {0x0000a168, 0x02050773}, - {0x0000a16c, 0x02050774}, - {0x0000a170, 0x02050775}, - {0x0000a174, 0x00000776}, - {0x0000a178, 0x00000776}, - {0x0000a17c, 0x00000776}, - {0x0000a180, 0x00000776}, - {0x0000a184, 0x00000776}, - {0x0000a188, 0x00000776}, - {0x0000a18c, 0x00000776}, - {0x0000a190, 0x00000776}, - {0x0000a194, 0x00000776}, - {0x0000a198, 0x00000776}, - {0x0000a19c, 0x00000776}, - {0x0000a1a0, 0x00000776}, - {0x0000a1a4, 0x00000776}, - {0x0000a1a8, 0x00000776}, - {0x0000a1ac, 0x00000776}, - {0x0000a1b0, 0x00000776}, - {0x0000a1b4, 0x00000776}, - {0x0000a1b8, 0x00000776}, - {0x0000a1bc, 0x00000776}, - {0x0000a1c0, 0x00000776}, - {0x0000a1c4, 0x00000776}, - {0x0000a1c8, 0x00000776}, - {0x0000a1cc, 0x00000776}, - {0x0000a1d0, 0x00000776}, - {0x0000a1d4, 0x00000776}, - {0x0000a1d8, 0x00000776}, - {0x0000a1dc, 0x00000776}, - {0x0000a1e0, 0x00000776}, - {0x0000a1e4, 0x00000776}, - {0x0000a1e8, 0x00000776}, - {0x0000a1ec, 0x00000776}, - {0x0000a1f0, 0x00000776}, - {0x0000a1f4, 0x00000776}, - {0x0000a1f8, 0x00000776}, - {0x0000a1fc, 0x00000776}, - {0x0000b000, 0x02000101}, - {0x0000b004, 0x02000102}, - {0x0000b008, 0x02000103}, - {0x0000b00c, 0x02000104}, - {0x0000b010, 0x02000200}, - {0x0000b014, 0x02000201}, - {0x0000b018, 0x02000202}, - {0x0000b01c, 0x02000203}, - {0x0000b020, 0x02000204}, - {0x0000b024, 0x02000205}, - {0x0000b028, 0x02000208}, - {0x0000b02c, 0x02000302}, - {0x0000b030, 0x02000303}, - {0x0000b034, 0x02000304}, - {0x0000b038, 0x02000400}, - {0x0000b03c, 0x02010300}, - {0x0000b040, 0x02010301}, - {0x0000b044, 0x02010302}, - {0x0000b048, 0x02000500}, - {0x0000b04c, 0x02010400}, - {0x0000b050, 0x02020300}, - {0x0000b054, 0x02020301}, - {0x0000b058, 0x02020302}, - {0x0000b05c, 0x02020303}, - {0x0000b060, 0x02020400}, - {0x0000b064, 0x02030300}, - {0x0000b068, 0x02030301}, - {0x0000b06c, 0x02030302}, - {0x0000b070, 0x02030303}, - {0x0000b074, 0x02030400}, - {0x0000b078, 0x02040300}, - {0x0000b07c, 0x02040301}, - {0x0000b080, 0x02040302}, - {0x0000b084, 0x02040303}, - {0x0000b088, 0x02030500}, - {0x0000b08c, 0x02040400}, - {0x0000b090, 0x02050203}, - {0x0000b094, 0x02050204}, - {0x0000b098, 0x02050205}, - {0x0000b09c, 0x02040500}, - {0x0000b0a0, 0x02050301}, - {0x0000b0a4, 0x02050302}, - {0x0000b0a8, 0x02050303}, - {0x0000b0ac, 0x02050400}, - {0x0000b0b0, 0x02050401}, - {0x0000b0b4, 0x02050402}, - {0x0000b0b8, 0x02050403}, - {0x0000b0bc, 0x02050500}, - {0x0000b0c0, 0x02050501}, - {0x0000b0c4, 0x02050502}, - {0x0000b0c8, 0x02050503}, - {0x0000b0cc, 0x02050504}, - {0x0000b0d0, 0x02050600}, - {0x0000b0d4, 0x02050601}, - {0x0000b0d8, 0x02050602}, - {0x0000b0dc, 0x02050603}, - {0x0000b0e0, 0x02050604}, - {0x0000b0e4, 0x02050700}, - {0x0000b0e8, 0x02050701}, - {0x0000b0ec, 0x02050702}, - {0x0000b0f0, 0x02050703}, - {0x0000b0f4, 0x02050704}, - {0x0000b0f8, 0x02050705}, - {0x0000b0fc, 0x02050708}, - {0x0000b100, 0x02050709}, - {0x0000b104, 0x0205070a}, - {0x0000b108, 0x0205070b}, - {0x0000b10c, 0x0205070c}, - {0x0000b110, 0x0205070d}, - {0x0000b114, 0x02050710}, - {0x0000b118, 0x02050711}, - {0x0000b11c, 0x02050712}, - {0x0000b120, 0x02050713}, - {0x0000b124, 0x02050714}, - {0x0000b128, 0x02050715}, - {0x0000b12c, 0x02050730}, - {0x0000b130, 0x02050731}, - {0x0000b134, 0x02050732}, - {0x0000b138, 0x02050733}, - {0x0000b13c, 0x02050734}, - {0x0000b140, 0x02050735}, - {0x0000b144, 0x02050750}, - {0x0000b148, 0x02050751}, - {0x0000b14c, 0x02050752}, - {0x0000b150, 0x02050753}, - {0x0000b154, 0x02050754}, - {0x0000b158, 0x02050755}, - {0x0000b15c, 0x02050770}, - {0x0000b160, 0x02050771}, - {0x0000b164, 0x02050772}, - {0x0000b168, 0x02050773}, - {0x0000b16c, 0x02050774}, - {0x0000b170, 0x02050775}, - {0x0000b174, 0x00000776}, - {0x0000b178, 0x00000776}, - {0x0000b17c, 0x00000776}, - {0x0000b180, 0x00000776}, - {0x0000b184, 0x00000776}, - {0x0000b188, 0x00000776}, - {0x0000b18c, 0x00000776}, - {0x0000b190, 0x00000776}, - {0x0000b194, 0x00000776}, - {0x0000b198, 0x00000776}, - {0x0000b19c, 0x00000776}, - {0x0000b1a0, 0x00000776}, - {0x0000b1a4, 0x00000776}, - {0x0000b1a8, 0x00000776}, - {0x0000b1ac, 0x00000776}, - {0x0000b1b0, 0x00000776}, - {0x0000b1b4, 0x00000776}, - {0x0000b1b8, 0x00000776}, - {0x0000b1bc, 0x00000776}, - {0x0000b1c0, 0x00000776}, - {0x0000b1c4, 0x00000776}, - {0x0000b1c8, 0x00000776}, - {0x0000b1cc, 0x00000776}, - {0x0000b1d0, 0x00000776}, - {0x0000b1d4, 0x00000776}, - {0x0000b1d8, 0x00000776}, - {0x0000b1dc, 0x00000776}, - {0x0000b1e0, 0x00000776}, - {0x0000b1e4, 0x00000776}, - {0x0000b1e8, 0x00000776}, - {0x0000b1ec, 0x00000776}, - {0x0000b1f0, 0x00000776}, - {0x0000b1f4, 0x00000776}, - {0x0000b1f8, 0x00000776}, - {0x0000b1fc, 0x00000776}, -}; - -static const u32 ar9300_2p0_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, -}; - -static const u32 ar9300_2p0_soc_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, -}; - -static const u32 ar9200_merlin_2p0_radio_core[][2] = { - /* Addr allmodes */ - {0x00007800, 0x00040000}, - {0x00007804, 0xdb005012}, - {0x00007808, 0x04924914}, - {0x0000780c, 0x21084210}, - {0x00007810, 0x6d801300}, - {0x00007814, 0x0019beff}, - {0x00007818, 0x07e41000}, - {0x0000781c, 0x00392000}, - {0x00007820, 0x92592480}, - {0x00007824, 0x00040000}, - {0x00007828, 0xdb005012}, - {0x0000782c, 0x04924914}, - {0x00007830, 0x21084210}, - {0x00007834, 0x6d801300}, - {0x00007838, 0x0019beff}, - {0x0000783c, 0x07e40000}, - {0x00007840, 0x00392000}, - {0x00007844, 0x92592480}, - {0x00007848, 0x00100000}, - {0x0000784c, 0x773f0567}, - {0x00007850, 0x54214514}, - {0x00007854, 0x12035828}, - {0x00007858, 0x92592692}, - {0x0000785c, 0x00000000}, - {0x00007860, 0x56400000}, - {0x00007864, 0x0a8e370e}, - {0x00007868, 0xc0102850}, - {0x0000786c, 0x812d4000}, - {0x00007870, 0x807ec400}, - {0x00007874, 0x001b6db0}, - {0x00007878, 0x00376b63}, - {0x0000787c, 0x06db6db6}, - {0x00007880, 0x006d8000}, - {0x00007884, 0xffeffffe}, - {0x00007888, 0xffeffffe}, - {0x0000788c, 0x00010000}, - {0x00007890, 0x02060aeb}, - {0x00007894, 0x5a108000}, -}; - -static const u32 ar9300_2p0_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, - {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, - {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, - {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, - {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, - {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, - {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, - {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, - {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, - {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, - {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, - {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, - {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, - {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, - {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, - {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, - {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0}, - {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, - {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, - {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, - {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, - {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, - {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, - {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, - {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, - {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, - {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, - {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, - {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, - {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, - {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, - {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, - {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, -}; - -static const u32 ar9300_2p0_baseband_core[][2] = { - /* Addr allmodes */ - {0x00009800, 0xafe68e30}, - {0x00009804, 0xfd14e000}, - {0x00009808, 0x9c0a9f6b}, - {0x0000980c, 0x04900000}, - {0x00009814, 0x9280c00a}, - {0x00009818, 0x00000000}, - {0x0000981c, 0x00020028}, - {0x00009834, 0x5f3ca3de}, - {0x00009838, 0x0108ecff}, - {0x0000983c, 0x14750600}, - {0x00009880, 0x201fff00}, - {0x00009884, 0x00001042}, - {0x000098a4, 0x00200400}, - {0x000098b0, 0x52440bbe}, - {0x000098d0, 0x004b6a8e}, - {0x000098d4, 0x00000820}, - {0x000098dc, 0x00000000}, - {0x000098f0, 0x00000000}, - {0x000098f4, 0x00000000}, - {0x00009c04, 0xff55ff55}, - {0x00009c08, 0x0320ff55}, - {0x00009c0c, 0x00000000}, - {0x00009c10, 0x00000000}, - {0x00009c14, 0x00046384}, - {0x00009c18, 0x05b6b440}, - {0x00009c1c, 0x00b6b440}, - {0x00009d00, 0xc080a333}, - {0x00009d04, 0x40206c10}, - {0x00009d08, 0x009c4060}, - {0x00009d0c, 0x9883800a}, - {0x00009d10, 0x01834061}, - {0x00009d14, 0x00c0040b}, - {0x00009d18, 0x00000000}, - {0x00009e08, 0x0038230c}, - {0x00009e24, 0x990bb515}, - {0x00009e28, 0x0c6f0000}, - {0x00009e30, 0x06336f77}, - {0x00009e34, 0x6af6532f}, - {0x00009e38, 0x0cc80c00}, - {0x00009e3c, 0xcf946222}, - {0x00009e40, 0x0d261820}, - {0x00009e4c, 0x00001004}, - {0x00009e50, 0x00ff03f1}, - {0x00009e54, 0x00000000}, - {0x00009fc0, 0x803e4788}, - {0x00009fc4, 0x0001efb5}, - {0x00009fcc, 0x40000014}, - {0x00009fd0, 0x01193b93}, - {0x0000a20c, 0x00000000}, - {0x0000a220, 0x00000000}, - {0x0000a224, 0x00000000}, - {0x0000a228, 0x10002310}, - {0x0000a22c, 0x01036a1e}, - {0x0000a234, 0x10000fff}, - {0x0000a23c, 0x00000000}, - {0x0000a244, 0x0c000000}, - {0x0000a2a0, 0x00000001}, - {0x0000a2c0, 0x00000001}, - {0x0000a2c8, 0x00000000}, - {0x0000a2cc, 0x18c43433}, - {0x0000a2d4, 0x00000000}, - {0x0000a2dc, 0x00000000}, - {0x0000a2e0, 0x00000000}, - {0x0000a2e4, 0x00000000}, - {0x0000a2e8, 0x00000000}, - {0x0000a2ec, 0x00000000}, - {0x0000a2f0, 0x00000000}, - {0x0000a2f4, 0x00000000}, - {0x0000a2f8, 0x00000000}, - {0x0000a344, 0x00000000}, - {0x0000a34c, 0x00000000}, - {0x0000a350, 0x0000a000}, - {0x0000a364, 0x00000000}, - {0x0000a370, 0x00000000}, - {0x0000a390, 0x00000001}, - {0x0000a394, 0x00000444}, - {0x0000a398, 0x001f0e0f}, - {0x0000a39c, 0x0075393f}, - {0x0000a3a0, 0xb79f6427}, - {0x0000a3a4, 0x00000000}, - {0x0000a3a8, 0xaaaaaaaa}, - {0x0000a3ac, 0x3c466478}, - {0x0000a3c0, 0x20202020}, - {0x0000a3c4, 0x22222220}, - {0x0000a3c8, 0x20200020}, - {0x0000a3cc, 0x20202020}, - {0x0000a3d0, 0x20202020}, - {0x0000a3d4, 0x20202020}, - {0x0000a3d8, 0x20202020}, - {0x0000a3dc, 0x20202020}, - {0x0000a3e0, 0x20202020}, - {0x0000a3e4, 0x20202020}, - {0x0000a3e8, 0x20202020}, - {0x0000a3ec, 0x20202020}, - {0x0000a3f0, 0x00000000}, - {0x0000a3f4, 0x00000246}, - {0x0000a3f8, 0x0cdbd380}, - {0x0000a3fc, 0x000f0f01}, - {0x0000a400, 0x8fa91f01}, - {0x0000a404, 0x00000000}, - {0x0000a408, 0x0e79e5c6}, - {0x0000a40c, 0x00820820}, - {0x0000a414, 0x1ce739ce}, - {0x0000a418, 0x2d001dce}, - {0x0000a41c, 0x1ce739ce}, - {0x0000a420, 0x000001ce}, - {0x0000a424, 0x1ce739ce}, - {0x0000a428, 0x000001ce}, - {0x0000a42c, 0x1ce739ce}, - {0x0000a430, 0x1ce739ce}, - {0x0000a434, 0x00000000}, - {0x0000a438, 0x00001801}, - {0x0000a43c, 0x00000000}, - {0x0000a440, 0x00000000}, - {0x0000a444, 0x00000000}, - {0x0000a448, 0x04000080}, - {0x0000a44c, 0x00000001}, - {0x0000a450, 0x00010000}, - {0x0000a458, 0x00000000}, - {0x0000a600, 0x00000000}, - {0x0000a604, 0x00000000}, - {0x0000a608, 0x00000000}, - {0x0000a60c, 0x00000000}, - {0x0000a610, 0x00000000}, - {0x0000a614, 0x00000000}, - {0x0000a618, 0x00000000}, - {0x0000a61c, 0x00000000}, - {0x0000a620, 0x00000000}, - {0x0000a624, 0x00000000}, - {0x0000a628, 0x00000000}, - {0x0000a62c, 0x00000000}, - {0x0000a630, 0x00000000}, - {0x0000a634, 0x00000000}, - {0x0000a638, 0x00000000}, - {0x0000a63c, 0x00000000}, - {0x0000a640, 0x00000000}, - {0x0000a644, 0x3fad9d74}, - {0x0000a648, 0x0048060a}, - {0x0000a64c, 0x00000637}, - {0x0000a670, 0x03020100}, - {0x0000a674, 0x09080504}, - {0x0000a678, 0x0d0c0b0a}, - {0x0000a67c, 0x13121110}, - {0x0000a680, 0x31301514}, - {0x0000a684, 0x35343332}, - {0x0000a688, 0x00000036}, - {0x0000a690, 0x00000838}, - {0x0000a7c0, 0x00000000}, - {0x0000a7c4, 0xfffffffc}, - {0x0000a7c8, 0x00000000}, - {0x0000a7cc, 0x00000000}, - {0x0000a7d0, 0x00000000}, - {0x0000a7d4, 0x00000004}, - {0x0000a7dc, 0x00000001}, - {0x0000a8d0, 0x004b6a8e}, - {0x0000a8d4, 0x00000820}, - {0x0000a8dc, 0x00000000}, - {0x0000a8f0, 0x00000000}, - {0x0000a8f4, 0x00000000}, - {0x0000b2d0, 0x00000080}, - {0x0000b2d4, 0x00000000}, - {0x0000b2dc, 0x00000000}, - {0x0000b2e0, 0x00000000}, - {0x0000b2e4, 0x00000000}, - {0x0000b2e8, 0x00000000}, - {0x0000b2ec, 0x00000000}, - {0x0000b2f0, 0x00000000}, - {0x0000b2f4, 0x00000000}, - {0x0000b2f8, 0x00000000}, - {0x0000b408, 0x0e79e5c0}, - {0x0000b40c, 0x00820820}, - {0x0000b420, 0x00000000}, - {0x0000b8d0, 0x004b6a8e}, - {0x0000b8d4, 0x00000820}, - {0x0000b8dc, 0x00000000}, - {0x0000b8f0, 0x00000000}, - {0x0000b8f4, 0x00000000}, - {0x0000c2d0, 0x00000080}, - {0x0000c2d4, 0x00000000}, - {0x0000c2dc, 0x00000000}, - {0x0000c2e0, 0x00000000}, - {0x0000c2e4, 0x00000000}, - {0x0000c2e8, 0x00000000}, - {0x0000c2ec, 0x00000000}, - {0x0000c2f0, 0x00000000}, - {0x0000c2f4, 0x00000000}, - {0x0000c2f8, 0x00000000}, - {0x0000c408, 0x0e79e5c0}, - {0x0000c40c, 0x00820820}, - {0x0000c420, 0x00000000}, -}; - -static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, - {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, - {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, - {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, - {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, - {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, - {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, - {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, - {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, - {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, - {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, - {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, - {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, - {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, - {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, - {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, - {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, -}; - -static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, - {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, - {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, - {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, - {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, - {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, - {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, - {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, - {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, - {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, - {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, - {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, - {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, - {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, - {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, - {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, - {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, - {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, - {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, - {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, - {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, - {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, - {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, - {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, - {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, - {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, - {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, - {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, - {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, - {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, - {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, - {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, - {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, - {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, - {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, - {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, - {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, - {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, - {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -}; - -static const u32 ar9300Common_rx_gain_table_2p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x01910190}, - {0x0000a030, 0x01930192}, - {0x0000a034, 0x01950194}, - {0x0000a038, 0x038a0196}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x22222229}, - {0x0000a084, 0x1d1d1d1d}, - {0x0000a088, 0x1d1d1d1d}, - {0x0000a08c, 0x1d1d1d1d}, - {0x0000a090, 0x171d1d1d}, - {0x0000a094, 0x11111717}, - {0x0000a098, 0x00030311}, - {0x0000a09c, 0x00000000}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x32323232}, - {0x0000b084, 0x2f2f3232}, - {0x0000b088, 0x23282a2d}, - {0x0000b08c, 0x1c1e2123}, - {0x0000b090, 0x14171919}, - {0x0000b094, 0x0e0e1214}, - {0x0000b098, 0x03050707}, - {0x0000b09c, 0x00030303}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; - -static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, - {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, - {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, - {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, - {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, - {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, - {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, - {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, - {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, - {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, - {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, - {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, - {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, - {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, - {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, - {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, - {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, - {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, - {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, - {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, - {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, - {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, - {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, - {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, - {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, - {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, - {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, - {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, - {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, - {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, - {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, - {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, - {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, - {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, - {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, - {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, - {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, - {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, - {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, - {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, - {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, - {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, - {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, - {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, - {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, - {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, - {0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, - {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, -}; - -static const u32 ar9300_2p0_mac_core[][2] = { - /* Addr allmodes */ - {0x00000008, 0x00000000}, - {0x00000030, 0x00020085}, - {0x00000034, 0x00000005}, - {0x00000040, 0x00000000}, - {0x00000044, 0x00000000}, - {0x00000048, 0x00000008}, - {0x0000004c, 0x00000010}, - {0x00000050, 0x00000000}, - {0x00001040, 0x002ffc0f}, - {0x00001044, 0x002ffc0f}, - {0x00001048, 0x002ffc0f}, - {0x0000104c, 0x002ffc0f}, - {0x00001050, 0x002ffc0f}, - {0x00001054, 0x002ffc0f}, - {0x00001058, 0x002ffc0f}, - {0x0000105c, 0x002ffc0f}, - {0x00001060, 0x002ffc0f}, - {0x00001064, 0x002ffc0f}, - {0x000010f0, 0x00000100}, - {0x00001270, 0x00000000}, - {0x000012b0, 0x00000000}, - {0x000012f0, 0x00000000}, - {0x0000143c, 0x00000000}, - {0x0000147c, 0x00000000}, - {0x00008000, 0x00000000}, - {0x00008004, 0x00000000}, - {0x00008008, 0x00000000}, - {0x0000800c, 0x00000000}, - {0x00008018, 0x00000000}, - {0x00008020, 0x00000000}, - {0x00008038, 0x00000000}, - {0x0000803c, 0x00000000}, - {0x00008040, 0x00000000}, - {0x00008044, 0x00000000}, - {0x00008048, 0x00000000}, - {0x0000804c, 0xffffffff}, - {0x00008054, 0x00000000}, - {0x00008058, 0x00000000}, - {0x0000805c, 0x000fc78f}, - {0x00008060, 0x0000000f}, - {0x00008064, 0x00000000}, - {0x00008070, 0x00000310}, - {0x00008074, 0x00000020}, - {0x00008078, 0x00000000}, - {0x0000809c, 0x0000000f}, - {0x000080a0, 0x00000000}, - {0x000080a4, 0x02ff0000}, - {0x000080a8, 0x0e070605}, - {0x000080ac, 0x0000000d}, - {0x000080b0, 0x00000000}, - {0x000080b4, 0x00000000}, - {0x000080b8, 0x00000000}, - {0x000080bc, 0x00000000}, - {0x000080c0, 0x2a800000}, - {0x000080c4, 0x06900168}, - {0x000080c8, 0x13881c20}, - {0x000080cc, 0x01f40000}, - {0x000080d0, 0x00252500}, - {0x000080d4, 0x00a00000}, - {0x000080d8, 0x00400000}, - {0x000080dc, 0x00000000}, - {0x000080e0, 0xffffffff}, - {0x000080e4, 0x0000ffff}, - {0x000080e8, 0x3f3f3f3f}, - {0x000080ec, 0x00000000}, - {0x000080f0, 0x00000000}, - {0x000080f4, 0x00000000}, - {0x000080fc, 0x00020000}, - {0x00008100, 0x00000000}, - {0x00008108, 0x00000052}, - {0x0000810c, 0x00000000}, - {0x00008110, 0x00000000}, - {0x00008114, 0x000007ff}, - {0x00008118, 0x000000aa}, - {0x0000811c, 0x00003210}, - {0x00008124, 0x00000000}, - {0x00008128, 0x00000000}, - {0x0000812c, 0x00000000}, - {0x00008130, 0x00000000}, - {0x00008134, 0x00000000}, - {0x00008138, 0x00000000}, - {0x0000813c, 0x0000ffff}, - {0x00008144, 0xffffffff}, - {0x00008168, 0x00000000}, - {0x0000816c, 0x00000000}, - {0x00008170, 0x18486200}, - {0x00008174, 0x33332210}, - {0x00008178, 0x00000000}, - {0x0000817c, 0x00020000}, - {0x000081c0, 0x00000000}, - {0x000081c4, 0x33332210}, - {0x000081c8, 0x00000000}, - {0x000081cc, 0x00000000}, - {0x000081d4, 0x00000000}, - {0x000081ec, 0x00000000}, - {0x000081f0, 0x00000000}, - {0x000081f4, 0x00000000}, - {0x000081f8, 0x00000000}, - {0x000081fc, 0x00000000}, - {0x00008240, 0x00100000}, - {0x00008244, 0x0010f424}, - {0x00008248, 0x00000800}, - {0x0000824c, 0x0001e848}, - {0x00008250, 0x00000000}, - {0x00008254, 0x00000000}, - {0x00008258, 0x00000000}, - {0x0000825c, 0x40000000}, - {0x00008260, 0x00080922}, - {0x00008264, 0x98a00010}, - {0x00008268, 0xffffffff}, - {0x0000826c, 0x0000ffff}, - {0x00008270, 0x00000000}, - {0x00008274, 0x40000000}, - {0x00008278, 0x003e4180}, - {0x0000827c, 0x00000004}, - {0x00008284, 0x0000002c}, - {0x00008288, 0x0000002c}, - {0x0000828c, 0x000000ff}, - {0x00008294, 0x00000000}, - {0x00008298, 0x00000000}, - {0x0000829c, 0x00000000}, - {0x00008300, 0x00000140}, - {0x00008314, 0x00000000}, - {0x0000831c, 0x0000010d}, - {0x00008328, 0x00000000}, - {0x0000832c, 0x00000007}, - {0x00008330, 0x00000302}, - {0x00008334, 0x00000700}, - {0x00008338, 0x00ff0000}, - {0x0000833c, 0x02400000}, - {0x00008340, 0x000107ff}, - {0x00008344, 0xaa48105b}, - {0x00008348, 0x008f0000}, - {0x0000835c, 0x00000000}, - {0x00008360, 0xffffffff}, - {0x00008364, 0xffffffff}, - {0x00008368, 0x00000000}, - {0x00008370, 0x00000000}, - {0x00008374, 0x000000ff}, - {0x00008378, 0x00000000}, - {0x0000837c, 0x00000000}, - {0x00008380, 0xffffffff}, - {0x00008384, 0xffffffff}, - {0x00008390, 0xffffffff}, - {0x00008394, 0xffffffff}, - {0x00008398, 0x00000000}, - {0x0000839c, 0x00000000}, - {0x000083a0, 0x00000000}, - {0x000083a4, 0x0000fa14}, - {0x000083a8, 0x000f0c00}, - {0x000083ac, 0x33332210}, - {0x000083b0, 0x33332210}, - {0x000083b4, 0x33332210}, - {0x000083b8, 0x33332210}, - {0x000083bc, 0x00000000}, - {0x000083c0, 0x00000000}, - {0x000083c4, 0x00000000}, - {0x000083c8, 0x00000000}, - {0x000083cc, 0x00000200}, - {0x000083d0, 0x000301ff}, -}; - -static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00010000}, - {0x0000a004, 0x00030002}, - {0x0000a008, 0x00050004}, - {0x0000a00c, 0x00810080}, - {0x0000a010, 0x00830082}, - {0x0000a014, 0x01810180}, - {0x0000a018, 0x01830182}, - {0x0000a01c, 0x01850184}, - {0x0000a020, 0x01890188}, - {0x0000a024, 0x018b018a}, - {0x0000a028, 0x018d018c}, - {0x0000a02c, 0x03820190}, - {0x0000a030, 0x03840383}, - {0x0000a034, 0x03880385}, - {0x0000a038, 0x038a0389}, - {0x0000a03c, 0x038c038b}, - {0x0000a040, 0x0390038d}, - {0x0000a044, 0x03920391}, - {0x0000a048, 0x03940393}, - {0x0000a04c, 0x03960395}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x29292929}, - {0x0000a084, 0x29292929}, - {0x0000a088, 0x29292929}, - {0x0000a08c, 0x29292929}, - {0x0000a090, 0x22292929}, - {0x0000a094, 0x1d1d2222}, - {0x0000a098, 0x0c111117}, - {0x0000a09c, 0x00030303}, - {0x0000a0a0, 0x00000000}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {0x0000a0b4, 0x00000000}, - {0x0000a0b8, 0x00000000}, - {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x001f0000}, - {0x0000a0c4, 0x01000101}, - {0x0000a0c8, 0x011e011f}, - {0x0000a0cc, 0x011c011d}, - {0x0000a0d0, 0x02030204}, - {0x0000a0d4, 0x02010202}, - {0x0000a0d8, 0x021f0200}, - {0x0000a0dc, 0x0302021e}, - {0x0000a0e0, 0x03000301}, - {0x0000a0e4, 0x031e031f}, - {0x0000a0e8, 0x0402031d}, - {0x0000a0ec, 0x04000401}, - {0x0000a0f0, 0x041e041f}, - {0x0000a0f4, 0x0502041d}, - {0x0000a0f8, 0x05000501}, - {0x0000a0fc, 0x051e051f}, - {0x0000a100, 0x06010602}, - {0x0000a104, 0x061f0600}, - {0x0000a108, 0x061d061e}, - {0x0000a10c, 0x07020703}, - {0x0000a110, 0x07000701}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x01000101}, - {0x0000a148, 0x011e011f}, - {0x0000a14c, 0x011c011d}, - {0x0000a150, 0x02030204}, - {0x0000a154, 0x02010202}, - {0x0000a158, 0x021f0200}, - {0x0000a15c, 0x0302021e}, - {0x0000a160, 0x03000301}, - {0x0000a164, 0x031e031f}, - {0x0000a168, 0x0402031d}, - {0x0000a16c, 0x04000401}, - {0x0000a170, 0x041e041f}, - {0x0000a174, 0x0502041d}, - {0x0000a178, 0x05000501}, - {0x0000a17c, 0x051e051f}, - {0x0000a180, 0x06010602}, - {0x0000a184, 0x061f0600}, - {0x0000a188, 0x061d061e}, - {0x0000a18c, 0x07020703}, - {0x0000a190, 0x07000701}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000196}, - {0x0000b000, 0x00010000}, - {0x0000b004, 0x00030002}, - {0x0000b008, 0x00050004}, - {0x0000b00c, 0x00810080}, - {0x0000b010, 0x00830082}, - {0x0000b014, 0x01810180}, - {0x0000b018, 0x01830182}, - {0x0000b01c, 0x01850184}, - {0x0000b020, 0x02810280}, - {0x0000b024, 0x02830282}, - {0x0000b028, 0x02850284}, - {0x0000b02c, 0x02890288}, - {0x0000b030, 0x028b028a}, - {0x0000b034, 0x0388028c}, - {0x0000b038, 0x038a0389}, - {0x0000b03c, 0x038c038b}, - {0x0000b040, 0x0390038d}, - {0x0000b044, 0x03920391}, - {0x0000b048, 0x03940393}, - {0x0000b04c, 0x03960395}, - {0x0000b050, 0x00000000}, - {0x0000b054, 0x00000000}, - {0x0000b058, 0x00000000}, - {0x0000b05c, 0x00000000}, - {0x0000b060, 0x00000000}, - {0x0000b064, 0x00000000}, - {0x0000b068, 0x00000000}, - {0x0000b06c, 0x00000000}, - {0x0000b070, 0x00000000}, - {0x0000b074, 0x00000000}, - {0x0000b078, 0x00000000}, - {0x0000b07c, 0x00000000}, - {0x0000b080, 0x32323232}, - {0x0000b084, 0x2f2f3232}, - {0x0000b088, 0x23282a2d}, - {0x0000b08c, 0x1c1e2123}, - {0x0000b090, 0x14171919}, - {0x0000b094, 0x0e0e1214}, - {0x0000b098, 0x03050707}, - {0x0000b09c, 0x00030303}, - {0x0000b0a0, 0x00000000}, - {0x0000b0a4, 0x00000000}, - {0x0000b0a8, 0x00000000}, - {0x0000b0ac, 0x00000000}, - {0x0000b0b0, 0x00000000}, - {0x0000b0b4, 0x00000000}, - {0x0000b0b8, 0x00000000}, - {0x0000b0bc, 0x00000000}, - {0x0000b0c0, 0x003f0020}, - {0x0000b0c4, 0x00400041}, - {0x0000b0c8, 0x0140005f}, - {0x0000b0cc, 0x0160015f}, - {0x0000b0d0, 0x017e017f}, - {0x0000b0d4, 0x02410242}, - {0x0000b0d8, 0x025f0240}, - {0x0000b0dc, 0x027f0260}, - {0x0000b0e0, 0x0341027e}, - {0x0000b0e4, 0x035f0340}, - {0x0000b0e8, 0x037f0360}, - {0x0000b0ec, 0x04400441}, - {0x0000b0f0, 0x0460045f}, - {0x0000b0f4, 0x0541047f}, - {0x0000b0f8, 0x055f0540}, - {0x0000b0fc, 0x057f0560}, - {0x0000b100, 0x06400641}, - {0x0000b104, 0x0660065f}, - {0x0000b108, 0x067e067f}, - {0x0000b10c, 0x07410742}, - {0x0000b110, 0x075f0740}, - {0x0000b114, 0x077f0760}, - {0x0000b118, 0x07800781}, - {0x0000b11c, 0x07a0079f}, - {0x0000b120, 0x07c107bf}, - {0x0000b124, 0x000007c0}, - {0x0000b128, 0x00000000}, - {0x0000b12c, 0x00000000}, - {0x0000b130, 0x00000000}, - {0x0000b134, 0x00000000}, - {0x0000b138, 0x00000000}, - {0x0000b13c, 0x00000000}, - {0x0000b140, 0x003f0020}, - {0x0000b144, 0x00400041}, - {0x0000b148, 0x0140005f}, - {0x0000b14c, 0x0160015f}, - {0x0000b150, 0x017e017f}, - {0x0000b154, 0x02410242}, - {0x0000b158, 0x025f0240}, - {0x0000b15c, 0x027f0260}, - {0x0000b160, 0x0341027e}, - {0x0000b164, 0x035f0340}, - {0x0000b168, 0x037f0360}, - {0x0000b16c, 0x04400441}, - {0x0000b170, 0x0460045f}, - {0x0000b174, 0x0541047f}, - {0x0000b178, 0x055f0540}, - {0x0000b17c, 0x057f0560}, - {0x0000b180, 0x06400641}, - {0x0000b184, 0x0660065f}, - {0x0000b188, 0x067e067f}, - {0x0000b18c, 0x07410742}, - {0x0000b190, 0x075f0740}, - {0x0000b194, 0x077f0760}, - {0x0000b198, 0x07800781}, - {0x0000b19c, 0x07a0079f}, - {0x0000b1a0, 0x07c107bf}, - {0x0000b1a4, 0x000007c0}, - {0x0000b1a8, 0x00000000}, - {0x0000b1ac, 0x00000000}, - {0x0000b1b0, 0x00000000}, - {0x0000b1b4, 0x00000000}, - {0x0000b1b8, 0x00000000}, - {0x0000b1bc, 0x00000000}, - {0x0000b1c0, 0x00000000}, - {0x0000b1c4, 0x00000000}, - {0x0000b1c8, 0x00000000}, - {0x0000b1cc, 0x00000000}, - {0x0000b1d0, 0x00000000}, - {0x0000b1d4, 0x00000000}, - {0x0000b1d8, 0x00000000}, - {0x0000b1dc, 0x00000000}, - {0x0000b1e0, 0x00000000}, - {0x0000b1e4, 0x00000000}, - {0x0000b1e8, 0x00000000}, - {0x0000b1ec, 0x00000000}, - {0x0000b1f0, 0x00000396}, - {0x0000b1f4, 0x00000396}, - {0x0000b1f8, 0x00000396}, - {0x0000b1fc, 0x00000196}, -}; - -static const u32 ar9300_2p0_soc_preamble[][2] = { - /* Addr allmodes */ - {0x000040a4, 0x00a0c1c9}, - {0x00007008, 0x00000000}, - {0x00007020, 0x00000000}, - {0x00007034, 0x00000002}, - {0x00007038, 0x000004c2}, -}; - -static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = { - /* Addr allmodes */ - {0x00004040, 0x08212e5e}, - {0x00004040, 0x0008003b}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = { - /* Addr allmodes */ - {0x00004040, 0x08253e5e}, - {0x00004040, 0x0008003b}, - {0x00004044, 0x00000000}, -}; - -static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = { - /* Addr allmodes */ - {0x00004040, 0x08213e5e}, - {0x00004040, 0x0008003b}, - {0x00004044, 0x00000000}, -}; - -#endif /* INITVALS_9003_2P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 4674ea8c9c99497add7587ff30c6f94c7f7f6ef1..9e6edffe0bd125544bce11b4d1dbcea470173add 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -18,6 +18,11 @@ #include "hw-ops.h" #include "ar9003_phy.h" +enum ar9003_cal_types { + IQ_MISMATCH_CAL = BIT(0), + TEMP_COMP_CAL = BIT(1), +}; + static void ar9003_hw_setup_calibration(struct ath_hw *ah, struct ath9k_cal_list *currCal) { @@ -50,11 +55,6 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah, ath_print(common, ATH_DBG_CALIBRATE, "starting Temperature Compensation Calibration\n"); break; - case ADC_DC_INIT_CAL: - case ADC_GAIN_CAL: - case ADC_DC_CAL: - /* Not yet */ - break; } } @@ -314,27 +314,6 @@ static const struct ath9k_percal_data iq_cal_single_sample = { static void ar9003_hw_init_cal_settings(struct ath_hw *ah) { ah->iq_caldata.calData = &iq_cal_single_sample; - ah->supp_cals = IQ_MISMATCH_CAL; -} - -static bool ar9003_hw_iscal_supported(struct ath_hw *ah, - enum ath9k_cal_types calType) -{ - switch (calType & ah->supp_cals) { - case IQ_MISMATCH_CAL: - /* - * XXX: Run IQ Mismatch for non-CCK only - * Note that CHANNEL_B is never set though. - */ - return true; - case ADC_GAIN_CAL: - case ADC_DC_CAL: - return false; - case TEMP_COMP_CAL: - return true; - } - - return false; } /* @@ -773,15 +752,16 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, /* Initialize list pointers */ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; + ah->supp_cals = IQ_MISMATCH_CAL; - if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { + if (ah->supp_cals & IQ_MISMATCH_CAL) { INIT_CAL(&ah->iq_caldata); INSERT_CAL(ah, &ah->iq_caldata); ath_print(common, ATH_DBG_CALIBRATE, "enabling IQ Calibration.\n"); } - if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) { + if (ah->supp_cals & TEMP_COMP_CAL) { INIT_CAL(&ah->tempCompCalData); INSERT_CAL(ah, &ah->tempCompCalData); ath_print(common, ATH_DBG_CALIBRATE, @@ -808,7 +788,6 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah) priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; priv_ops->init_cal = ar9003_hw_init_cal; priv_ops->setup_calibration = ar9003_hw_setup_calibration; - priv_ops->iscal_supported = ar9003_hw_iscal_supported; ops->calibrate = ar9003_hw_calibrate; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 057fb69ddf7fbc56e76b010a1cc21833fdc2b078..c4182359bee46603cffc46e9781750087f2a5f0f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -968,7 +968,7 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah) } static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah, - enum ieee80211_band freq_band) + enum ath9k_hal_freq_band freq_band) { return 1; } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 064168909108005531e90e9ea657f51a43866794..c2a057156bfa19c7c9db6862bb3233254fb0d452 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -16,7 +16,6 @@ #include "hw.h" #include "ar9003_mac.h" -#include "ar9003_2p0_initvals.h" #include "ar9003_2p2_initvals.h" /* General hardware code for the AR9003 hadware family */ @@ -32,79 +31,12 @@ static bool ar9003_hw_macversion_supported(u32 macversion) return false; } -/* AR9003 2.0 */ -static void ar9003_2p0_hw_init_mode_regs(struct ath_hw *ah) -{ - /* mac */ - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], - ar9300_2p0_mac_core, - ARRAY_SIZE(ar9300_2p0_mac_core), 2); - INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], - ar9300_2p0_mac_postamble, - ARRAY_SIZE(ar9300_2p0_mac_postamble), 5); - - /* bb */ - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], - ar9300_2p0_baseband_core, - ARRAY_SIZE(ar9300_2p0_baseband_core), 2); - INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], - ar9300_2p0_baseband_postamble, - ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5); - - /* radio */ - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], - ar9300_2p0_radio_core, - ARRAY_SIZE(ar9300_2p0_radio_core), 2); - INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], - ar9300_2p0_radio_postamble, - ARRAY_SIZE(ar9300_2p0_radio_postamble), 5); - - /* soc */ - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], - ar9300_2p0_soc_preamble, - ARRAY_SIZE(ar9300_2p0_soc_preamble), 2); - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); - INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], - ar9300_2p0_soc_postamble, - ARRAY_SIZE(ar9300_2p0_soc_postamble), 5); - - /* rx/tx gain */ - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p0, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2); - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), - 5); - - /* Load PCIE SERDES settings from INI */ - - /* Awake Setting */ - - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9300PciePhy_pll_on_clkreq_disable_L1_2p0, - ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0), - 2); - - /* Sleep Setting */ - - INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9300PciePhy_clkreq_enable_L1_2p0, - ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0), - 2); - - /* Fast clock modal settings */ - INIT_INI_ARRAY(&ah->iniModesAdditional, - ar9300Modes_fast_clock_2p0, - ARRAY_SIZE(ar9300Modes_fast_clock_2p0), - 3); -} - -/* AR9003 2.2 */ -static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah) +/* + * The AR9003 family uses a new INI format (pre, core, post + * arrays per subsystem). This provides support for the + * AR9003 2.2 chipsets. + */ +static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); @@ -174,57 +106,27 @@ static void ar9003_2p2_hw_init_mode_regs(struct ath_hw *ah) 3); } -/* - * The AR9003 family uses a new INI format (pre, core, post - * arrays per subsystem). - */ -static void ar9003_hw_init_mode_regs(struct ath_hw *ah) -{ - if (AR_SREV_9300_20(ah)) - ar9003_2p0_hw_init_mode_regs(ah); - else - ar9003_2p2_hw_init_mode_regs(ah); -} - static void ar9003_tx_gain_table_apply(struct ath_hw *ah) { switch (ar9003_hw_get_tx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_lowest_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), - 5); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_lowest_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), + 5); break; case 1: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_high_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_high_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), - 5); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_high_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), + 5); break; case 2: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_low_ob_db_tx_gain_table_2p0, - ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0), - 5); - else - INIT_INI_ARRAY(&ah->iniModesTxGain, - ar9300Modes_low_ob_db_tx_gain_table_2p2, - ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), - 5); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_low_ob_db_tx_gain_table_2p2, + ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), + 5); break; } } @@ -234,28 +136,16 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) switch (ar9003_hw_get_rx_gain_idx(ah)) { case 0: default: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p0, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), - 2); - else - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), - 2); + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), + 2); break; case 1: - if (AR_SREV_9300_20(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_wo_xlna_rx_gain_table_2p0, - ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0), - 2); - else - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9300Common_wo_xlna_rx_gain_table_2p2, - ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), - 2); + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9300Common_wo_xlna_rx_gain_table_2p2, + ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), + 2); break; } } @@ -333,6 +223,4 @@ void ar9003_hw_attach_ops(struct ath_hw *ah) ar9003_hw_attach_phy_ops(ah); ar9003_hw_attach_calib_ops(ah); ar9003_hw_attach_mac_ops(ah); - - ath9k_hw_attach_ani_ops_new(ah); } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 5b995bee70ae4a931e6337c6723618edef4df725..3b424ca1ba844855b798e757e0d0727dd29e9e27 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -185,7 +185,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) ath_print(common, ATH_DBG_INTERRUPT, "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); - REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); + REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR); } @@ -616,7 +616,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_status |= ATH9K_RXERR_DECRYPT; } else if (rxsp->status11 & AR_MichaelErr) { rxs->rs_status |= ATH9K_RXERR_MIC; - } + } else if (rxsp->status11 & AR_KeyMiss) + rxs->rs_status |= ATH9K_RXERR_DECRYPT; } return 0; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index a491854fa38aa7173c5b976c54da6551f4f96aa9..669b777729b314161a99987812ed1b93ef16c168 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -747,9 +747,9 @@ static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) static bool ar9003_hw_ani_control(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) { - struct ar5416AniState *aniState = ah->curani; struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; + struct ar5416AniState *aniState = &chan->ani; s32 value, value2; switch (cmd & ah->ani_function) { @@ -1005,15 +1005,13 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, ath_print(common, ATH_DBG_ANI, "ANI parameters: SI=%d, ofdmWS=%s FS=%d " - "MRCcck=%s listenTime=%d CC=%d listen=%d " + "MRCcck=%s listenTime=%d " "ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, !aniState->ofdmWeakSigDetectOff ? "on" : "off", aniState->firstepLevel, !aniState->mrcCCKOff ? "on" : "off", aniState->listenTime, - aniState->cycleCount, - aniState->listenTime, aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); return true; @@ -1067,12 +1065,9 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) struct ath_common *common = ath9k_hw_common(ah); struct ath9k_channel *chan = ah->curchan; struct ath9k_ani_default *iniDef; - int index; u32 val; - index = ath9k_hw_get_ani_channel_idx(ah, chan); - aniState = &ah->ani[index]; - ah->curani = aniState; + aniState = &ah->curchan->ani; iniDef = &aniState->iniDef; ath_print(common, ATH_DBG_ANI, @@ -1116,8 +1111,6 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; - - aniState->cycleCount = 0; } void ar9003_hw_attach_phy_ops(struct ath_hw *ah) @@ -1232,7 +1225,7 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah) void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status; + u32 status; if (likely(!(common->debug_mask & ATH_DBG_RESET))) return; @@ -1261,11 +1254,12 @@ void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) "** BB mode: BB_gen_controls=0x%08x **\n", REG_READ(ah, AR_PHY_GEN_CTRL)); - if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt)) +#define PCT(_field) (common->cc_survey._field * 100 / common->cc_survey.cycles) + if (common->cc_survey.cycles) ath_print(common, ATH_DBG_RESET, "** BB busy times: rx_clear=%d%%, " "rx_frame=%d%%, tx_frame=%d%% **\n", - rxc_pcnt, rxf_pcnt, txf_pcnt); + PCT(rx_busy), PCT(rx_frame), PCT(tx_frame)); ath_print(common, ATH_DBG_RESET, "==== BB update: done ====\n\n"); diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 07f26ee7a7235ac0f3c48c7966630ce849217cfc..973c919fdd27f5ece00c29a023c598f9054d4f2f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -239,13 +239,11 @@ struct ath_buf { struct sk_buff *bf_mpdu; /* enclosing frame structure */ void *bf_desc; /* virtual addr of desc */ dma_addr_t bf_daddr; /* physical addr of desc */ - dma_addr_t bf_buf_addr; /* physical addr of data buffer */ + dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */ bool bf_stale; - bool bf_isnullfunc; bool bf_tx_aborted; u16 bf_flags; struct ath_buf_state bf_state; - dma_addr_t bf_dmacontext; struct ath_wiphy *aphy; }; @@ -254,7 +252,7 @@ struct ath_atx_tid { struct list_head buf_q; struct ath_node *an; struct ath_atx_ac *ac; - struct ath_buf *tx_buf[ATH_TID_MAX_BUFS]; + unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)]; u16 seq_start; u16 seq_next; u16 baw_size; @@ -345,12 +343,10 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, void ath_tx_tasklet(struct ath_softc *sc); void ath_tx_edma_tasklet(struct ath_softc *sc); void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); -bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); -void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, - u16 tid, u16 *ssn); +int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, + u16 tid, u16 *ssn); void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); -void ath9k_enable_ps(struct ath_softc *sc); /********/ /* VIFs */ @@ -423,6 +419,7 @@ int ath_beaconq_config(struct ath_softc *sc); #define ATH_AP_SHORT_CALINTERVAL 100 /* 100 ms */ #define ATH_ANI_POLLINTERVAL_OLD 100 /* 100 ms */ #define ATH_ANI_POLLINTERVAL_NEW 1000 /* 1000 ms */ +#define ATH_LONG_CALINTERVAL_INT 1000 /* 1000 ms */ #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ @@ -436,14 +433,6 @@ void ath_ani_calibrate(unsigned long data); /* BTCOEX */ /**********/ -/* Defines the BT AR_BT_COEX_WGHT used */ -enum ath_stomp_type { - ATH_BTCOEX_NO_STOMP, - ATH_BTCOEX_STOMP_ALL, - ATH_BTCOEX_STOMP_LOW, - ATH_BTCOEX_STOMP_NONE -}; - struct ath_btcoex { bool hw_timer_enabled; spinlock_t btcoex_lock; @@ -488,6 +477,60 @@ struct ath_led { void ath_init_leds(struct ath_softc *sc); void ath_deinit_leds(struct ath_softc *sc); +/* Antenna diversity/combining */ +#define ATH_ANT_RX_CURRENT_SHIFT 4 +#define ATH_ANT_RX_MAIN_SHIFT 2 +#define ATH_ANT_RX_MASK 0x3 + +#define ATH_ANT_DIV_COMB_SHORT_SCAN_INTR 50 +#define ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT 0x100 +#define ATH_ANT_DIV_COMB_MAX_PKTCOUNT 0x200 +#define ATH_ANT_DIV_COMB_INIT_COUNT 95 +#define ATH_ANT_DIV_COMB_MAX_COUNT 100 +#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30 +#define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20 + +#define ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA -3 +#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1 +#define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4 +#define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2 +#define ATH_ANT_DIV_COMB_LNA1_DELTA_LOW 2 + +enum ath9k_ant_div_comb_lna_conf { + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2, + ATH_ANT_DIV_COMB_LNA2, + ATH_ANT_DIV_COMB_LNA1, + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2, +}; + +struct ath_ant_comb { + u16 count; + u16 total_pkt_count; + bool scan; + bool scan_not_start; + int main_total_rssi; + int alt_total_rssi; + int alt_recv_cnt; + int main_recv_cnt; + int rssi_lna1; + int rssi_lna2; + int rssi_add; + int rssi_sub; + int rssi_first; + int rssi_second; + int rssi_third; + bool alt_good; + int quick_scan_cnt; + int main_conf; + enum ath9k_ant_div_comb_lna_conf first_quick_scan_conf; + enum ath9k_ant_div_comb_lna_conf second_quick_scan_conf; + int first_bias; + int second_bias; + bool first_ratio; + bool second_ratio; + unsigned long scan_start_time; +}; + /********************/ /* Main driver core */ /********************/ @@ -516,7 +559,6 @@ void ath_deinit_leds(struct ath_softc *sc); #define SC_OP_RXFLUSH BIT(7) #define SC_OP_LED_ASSOCIATED BIT(8) #define SC_OP_LED_ON BIT(9) -#define SC_OP_SCANNING BIT(10) #define SC_OP_TSF_RESET BIT(11) #define SC_OP_BT_PRIORITY_DETECTED BIT(12) #define SC_OP_BT_SCAN BIT(13) @@ -528,8 +570,6 @@ void ath_deinit_leds(struct ath_softc *sc); #define PS_WAIT_FOR_PSPOLL_DATA BIT(2) #define PS_WAIT_FOR_TX_ACK BIT(3) #define PS_BEACON_SYNC BIT(4) -#define PS_NULLFUNC_COMPLETED BIT(5) -#define PS_ENABLED BIT(6) struct ath_wiphy; struct ath_rate_table; @@ -552,6 +592,8 @@ struct ath_softc { struct delayed_work wiphy_work; unsigned long wiphy_scheduler_int; int wiphy_scheduler_index; + struct survey_info *cur_survey; + struct survey_info survey[ATH9K_NUM_CHANNELS]; struct tasklet_struct intr_tq; struct tasklet_struct bcon_tasklet; @@ -580,8 +622,6 @@ struct ath_softc { struct ath_rx rx; struct ath_tx tx; struct ath_beacon beacon; - const struct ath_rate_table *cur_rate_table; - enum wireless_mode cur_rate_mode; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; struct ath_led radio_led; @@ -604,6 +644,8 @@ struct ath_softc { struct ath_btcoex btcoex; struct ath_descdma txsdma; + + struct ath_ant_comb ant_comb; }; struct ath_wiphy { @@ -670,7 +712,7 @@ static inline void ath_ahb_exit(void) {}; void ath9k_ps_wakeup(struct ath_softc *sc); void ath9k_ps_restore(struct ath_softc *sc); -void ath9k_set_bssid_mask(struct ieee80211_hw *hw); +void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int ath9k_wiphy_add(struct ath_softc *sc); int ath9k_wiphy_del(struct ath_wiphy *aphy); void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 4d4b22d52dfd230a7a61b3f0dd8b5b612c38af1f..4ed010d4ef96d9f3288cc9d1c81dbcd8d24e50fa 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -136,9 +136,10 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, bf = avp->av_bcbuf; skb = bf->bf_mpdu; if (skb) { - dma_unmap_single(sc->dev, bf->bf_dmacontext, + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); + bf->bf_buf_addr = 0; } /* Get a new beacon from mac80211 */ @@ -162,12 +163,12 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); } - bf->bf_buf_addr = bf->bf_dmacontext = - dma_map_single(sc->dev, skb->data, - skb->len, DMA_TO_DEVICE); + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, + skb->len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n"); return NULL; @@ -252,10 +253,11 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) bf = avp->av_bcbuf; if (bf->bf_mpdu != NULL) { skb = bf->bf_mpdu; - dma_unmap_single(sc->dev, bf->bf_dmacontext, + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; } /* NB: the beacon data buffer must be 32-bit aligned. */ @@ -296,12 +298,12 @@ int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif) avp->tsf_adjust = cpu_to_le64(0); bf->bf_mpdu = skb; - bf->bf_buf_addr = bf->bf_dmacontext = - dma_map_single(sc->dev, skb->data, - skb->len, DMA_TO_DEVICE); + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, + skb->len, DMA_TO_DEVICE); if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error on beacon alloc\n"); return -ENOMEM; @@ -324,10 +326,11 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) bf = avp->av_bcbuf; if (bf->bf_mpdu != NULL) { struct sk_buff *skb = bf->bf_mpdu; - dma_unmap_single(sc->dev, bf->bf_dmacontext, + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; } list_add_tail(&bf->list, &sc->beacon.bbuf); @@ -359,11 +362,12 @@ void ath_beacon_tasklet(unsigned long data) sc->beacon.bmisscnt++; if (sc->beacon.bmisscnt < BSTUCK_THRESH) { - ath_print(common, ATH_DBG_BEACON, + ath_print(common, ATH_DBG_BSTUCK, "missed %u consecutive beacons\n", sc->beacon.bmisscnt); + ath9k_hw_bstuck_nfcal(ah); } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { - ath_print(common, ATH_DBG_BEACON, + ath_print(common, ATH_DBG_BSTUCK, "beacon is officially stuck\n"); sc->sc_flags |= SC_OP_TSF_RESET; ath_reset(sc, false); @@ -373,7 +377,7 @@ void ath_beacon_tasklet(unsigned long data) } if (sc->beacon.bmisscnt != 0) { - ath_print(common, ATH_DBG_BEACON, + ath_print(common, ATH_DBG_BSTUCK, "resume beacon xmit after %u misses\n", sc->beacon.bmisscnt); sc->beacon.bmisscnt = 0; diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index fb4ac15f3b9317487f060e0b7b51cbe59ef09654..6a92e57fddf0dc2c8127ef544dcdfd36d4d41d38 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c @@ -168,6 +168,7 @@ EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; + u32 val; /* * Program coex mode and weight registers to @@ -177,6 +178,12 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); + if (AR_SREV_9271(ah)) { + val = REG_READ(ah, 0x50040); + val &= 0xFFFFFEFF; + REG_WRITE(ah, 0x50040, val); + } + REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 45208690c0ec3d5cf747d0ac18218ddeedaf20f8..6d509484b5f6144babfc5646412bc0f8d7edaef9 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -19,8 +19,7 @@ /* Common calibration code */ -/* We can tune this as we go by monitoring really low values */ -#define ATH9K_NF_TOO_LOW -60 +#define ATH9K_NF_TOO_HIGH -60 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) { @@ -45,11 +44,39 @@ static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer) return nfval; } -static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, +static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct ath_hw *ah, + struct ath9k_channel *chan) +{ + struct ath_nf_limits *limit; + + if (!chan || IS_CHAN_2GHZ(chan)) + limit = &ah->nf_2g; + else + limit = &ah->nf_5g; + + return limit; +} + +static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, + struct ath9k_channel *chan) +{ + return ath9k_hw_get_nf_limits(ah, chan)->nominal; +} + + +static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, + struct ath9k_hw_cal_data *cal, int16_t *nfarray) { + struct ath_common *common = ath9k_hw_common(ah); + struct ath_nf_limits *limit; + struct ath9k_nfcal_hist *h; + bool high_nf_mid = false; int i; + h = cal->nfCalHist; + limit = ath9k_hw_get_nf_limits(ah, ah->curchan); + for (i = 0; i < NUM_NF_READINGS; i++) { h[i].nfCalBuffer[h[i].currIndex] = nfarray[i]; @@ -63,7 +90,39 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, h[i].privNF = ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); } + + if (!h[i].privNF) + continue; + + if (h[i].privNF > limit->max) { + high_nf_mid = true; + + ath_print(common, ATH_DBG_CALIBRATE, + "NFmid[%d] (%d) > MAX (%d), %s\n", + i, h[i].privNF, limit->max, + (cal->nfcal_interference ? + "not corrected (due to interference)" : + "correcting to MAX")); + + /* + * Normally we limit the average noise floor by the + * hardware specific maximum here. However if we have + * encountered stuck beacons because of interference, + * we bypass this limit here in order to better deal + * with our environment. + */ + if (!cal->nfcal_interference) + h[i].privNF = limit->max; + } } + + /* + * If the noise floor seems normal for all chains, assume that + * there is no significant interference in the environment anymore. + * Re-enable the enforcement of the NF maximum again. + */ + if (!high_nf_mid) + cal->nfcal_interference = false; } static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah, @@ -104,19 +163,6 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah, ah->cal_samples = 0; } -static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - struct ath_nf_limits *limit; - - if (!chan || IS_CHAN_2GHZ(chan)) - limit = &ah->nf_2g; - else - limit = &ah->nf_5g; - - return limit->nominal; -} - /* This is done for the currently configured channel */ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) { @@ -140,7 +186,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) return true; } - if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType)) + if (!(ah->supp_cals & currCal->calData->calType)) return true; ath_print(common, ATH_DBG_CALIBRATE, @@ -254,7 +300,6 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) } } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } @@ -277,10 +322,10 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) "NF calibrated [%s] [chain %d] is %d\n", (i >= 3 ? "ext" : "ctl"), i % 3, nf[i]); - if (nf[i] > limit->max) { + if (nf[i] > ATH9K_NF_TOO_HIGH) { ath_print(common, ATH_DBG_CALIBRATE, "NF[%d] (%d) > MAX (%d), correcting to MAX", - i, nf[i], limit->max); + i, nf[i], ATH9K_NF_TOO_HIGH); nf[i] = limit->max; } else if (nf[i] < limit->min) { ath_print(common, ATH_DBG_CALIBRATE, @@ -300,34 +345,34 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) struct ieee80211_channel *c = chan->chan; struct ath9k_hw_cal_data *caldata = ah->caldata; - if (!caldata) - return false; - chan->channelFlags &= (~CHANNEL_CW_INT); if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) { ath_print(common, ATH_DBG_CALIBRATE, "NF did not complete in calibration window\n"); - nf = 0; - caldata->rawNoiseFloor = nf; return false; - } else { - ath9k_hw_do_getnf(ah, nfarray); - ath9k_hw_nf_sanitize(ah, nfarray); - nf = nfarray[0]; - if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) - && nf > nfThresh) { - ath_print(common, ATH_DBG_CALIBRATE, - "noise floor failed detected; " - "detected %d, threshold %d\n", - nf, nfThresh); - chan->channelFlags |= CHANNEL_CW_INT; - } + } + + ath9k_hw_do_getnf(ah, nfarray); + ath9k_hw_nf_sanitize(ah, nfarray); + nf = nfarray[0]; + if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) + && nf > nfThresh) { + ath_print(common, ATH_DBG_CALIBRATE, + "noise floor failed detected; " + "detected %d, threshold %d\n", + nf, nfThresh); + chan->channelFlags |= CHANNEL_CW_INT; + } + + if (!caldata) { + chan->noisefloor = nf; + return false; } h = caldata->nfCalHist; caldata->nfcal_pending = false; - ath9k_hw_update_nfcal_hist_buffer(h, nfarray); - caldata->rawNoiseFloor = h[0].privNF; + ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray); + chan->noisefloor = h[0].privNF; return true; } @@ -355,9 +400,34 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) { - if (!ah->caldata || !ah->caldata->rawNoiseFloor) + if (!ah->curchan || !ah->curchan->noisefloor) return ath9k_hw_get_default_nf(ah, chan); - return ah->caldata->rawNoiseFloor; + return ah->curchan->noisefloor; } EXPORT_SYMBOL(ath9k_hw_getchan_noise); + +void ath9k_hw_bstuck_nfcal(struct ath_hw *ah) +{ + struct ath9k_hw_cal_data *caldata = ah->caldata; + + if (unlikely(!caldata)) + return; + + /* + * If beacons are stuck, the most likely cause is interference. + * Triggering a noise floor calibration at this point helps the + * hardware adapt to a noisy environment much faster. + * To ensure that we recover from stuck beacons quickly, let + * the baseband update the internal NF value itself, similar to + * what is being done after a full reset. + */ + if (!caldata->nfcal_pending) + ath9k_hw_start_nfcal(ah, true); + else if (!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)) + ath9k_hw_getnf(ah, ah->curchan); + + caldata->nfcal_interference = true; +} +EXPORT_SYMBOL(ath9k_hw_bstuck_nfcal); + diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 0a304b3eeeb6dad1e414ee362888900a9d811e24..b8973eb8d858bb3414c41bea41e01970aeb28a62 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -58,14 +58,6 @@ struct ar5416IniArray { } \ } while (0) -enum ath9k_cal_types { - ADC_DC_INIT_CAL = 0x1, - ADC_GAIN_CAL = 0x2, - ADC_DC_CAL = 0x4, - IQ_MISMATCH_CAL = 0x8, - TEMP_COMP_CAL = 0x10, -}; - enum ath9k_cal_state { CAL_INACTIVE, CAL_WAITING, @@ -80,7 +72,7 @@ enum ath9k_cal_state { #define PER_MAX_LOG_COUNT 10 struct ath9k_percal_data { - enum ath9k_cal_types calType; + u32 calType; u32 calNumSamples; u32 calCountMax; void (*calCollect) (struct ath_hw *); @@ -113,6 +105,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan); void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, struct ath9k_channel *chan); +void ath9k_hw_bstuck_nfcal(struct ath_hw *ah); s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); void ath9k_hw_reset_calibration(struct ath_hw *ah, struct ath9k_cal_list *currCal); diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index c86f7d3593ab48a3c1c1248443f0f2f599a327f8..f43a2d98421c37731118c0bda90c37538608409a 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -46,12 +46,17 @@ int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); if (tx_info->control.hw_key) { - if (tx_info->control.hw_key->alg == ALG_WEP) + switch (tx_info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: return ATH9K_KEY_TYPE_WEP; - else if (tx_info->control.hw_key->alg == ALG_TKIP) + case WLAN_CIPHER_SUITE_TKIP: return ATH9K_KEY_TYPE_TKIP; - else if (tx_info->control.hw_key->alg == ALG_CCMP) + case WLAN_CIPHER_SUITE_CCMP: return ATH9K_KEY_TYPE_AES; + default: + break; + } } return ATH9K_KEY_TYPE_CLEAR; @@ -143,276 +148,49 @@ struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, } EXPORT_SYMBOL(ath9k_cmn_get_curchannel); -static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, - struct ath9k_keyval *hk, const u8 *addr, - bool authenticator) -{ - struct ath_hw *ah = common->ah; - const u8 *key_rxmic; - const u8 *key_txmic; - - key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; - key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; - - if (addr == NULL) { - /* - * Group key installation - only two key cache entries are used - * regardless of splitmic capability since group key is only - * used either for TX or RX. - */ - if (authenticator) { - memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); - } else { - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); - } - return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); - } - if (!common->splitmic) { - /* TX and RX keys share the same key cache entry. */ - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); - return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); - } - - /* Separate key cache entries for TX and RX */ - - /* TX key goes at first index, RX key at +32. */ - memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); - if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { - /* TX MIC entry failed. No need to proceed further */ - ath_print(common, ATH_DBG_FATAL, - "Setting TX MIC Key Failed\n"); - return 0; - } - - memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); - /* XXX delete tx key on failure? */ - return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); -} - -static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) -{ - int i; - - for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { - if (test_bit(i, common->keymap) || - test_bit(i + 64, common->keymap)) - continue; /* At least one part of TKIP key allocated */ - if (common->splitmic && - (test_bit(i + 32, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - continue; /* At least one part of TKIP key allocated */ - - /* Found a free slot for a TKIP key */ - return i; - } - return -1; -} - -static int ath_reserve_key_cache_slot(struct ath_common *common, - enum ieee80211_key_alg alg) +int ath9k_cmn_count_streams(unsigned int chainmask, int max) { - int i; - - if (alg == ALG_TKIP) - return ath_reserve_key_cache_slot_tkip(common); - - /* First, try to find slots that would not be available for TKIP. */ - if (common->splitmic) { - for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { - if (!test_bit(i, common->keymap) && - (test_bit(i + 32, common->keymap) || - test_bit(i + 64, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i; - if (!test_bit(i + 32, common->keymap) && - (test_bit(i, common->keymap) || - test_bit(i + 64, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i + 32; - if (!test_bit(i + 64, common->keymap) && - (test_bit(i , common->keymap) || - test_bit(i + 32, common->keymap) || - test_bit(i + 64 + 32, common->keymap))) - return i + 64; - if (!test_bit(i + 64 + 32, common->keymap) && - (test_bit(i, common->keymap) || - test_bit(i + 32, common->keymap) || - test_bit(i + 64, common->keymap))) - return i + 64 + 32; - } - } else { - for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { - if (!test_bit(i, common->keymap) && - test_bit(i + 64, common->keymap)) - return i; - if (test_bit(i, common->keymap) && - !test_bit(i + 64, common->keymap)) - return i + 64; - } - } - - /* No partially used TKIP slots, pick any available slot */ - for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { - /* Do not allow slots that could be needed for TKIP group keys - * to be used. This limitation could be removed if we know that - * TKIP will not be used. */ - if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) - continue; - if (common->splitmic) { - if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) - continue; - if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) - continue; - } + int streams = 0; - if (!test_bit(i, common->keymap)) - return i; /* Found a free slot for a key */ - } + do { + if (++streams == max) + break; + } while ((chainmask = chainmask & (chainmask - 1))); - /* No free slot found */ - return -1; + return streams; } +EXPORT_SYMBOL(ath9k_cmn_count_streams); /* - * Configure encryption in the HW. + * Configures appropriate weight based on stomp type. */ -int ath9k_cmn_key_config(struct ath_common *common, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key) +void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, + enum ath_stomp_type stomp_type) { struct ath_hw *ah = common->ah; - struct ath9k_keyval hk; - const u8 *mac = NULL; - u8 gmac[ETH_ALEN]; - int ret = 0; - int idx; - memset(&hk, 0, sizeof(hk)); - - switch (key->alg) { - case ALG_WEP: - hk.kv_type = ATH9K_CIPHER_WEP; + switch (stomp_type) { + case ATH_BTCOEX_STOMP_ALL: + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_ALL_WLAN_WGHT); break; - case ALG_TKIP: - hk.kv_type = ATH9K_CIPHER_TKIP; + case ATH_BTCOEX_STOMP_LOW: + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); break; - case ALG_CCMP: - hk.kv_type = ATH9K_CIPHER_AES_CCM; + case ATH_BTCOEX_STOMP_NONE: + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_NONE_WLAN_WGHT); break; default: - return -EOPNOTSUPP; - } - - hk.kv_len = key->keylen; - memcpy(hk.kv_val, key->key, key->keylen); - - if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { - switch (vif->type) { - case NL80211_IFTYPE_AP: - memcpy(gmac, vif->addr, ETH_ALEN); - gmac[0] |= 0x01; - mac = gmac; - idx = ath_reserve_key_cache_slot(common, key->alg); - break; - case NL80211_IFTYPE_ADHOC: - if (!sta) { - idx = key->keyidx; - break; - } - memcpy(gmac, sta->addr, ETH_ALEN); - gmac[0] |= 0x01; - mac = gmac; - idx = ath_reserve_key_cache_slot(common, key->alg); - break; - default: - idx = key->keyidx; - break; - } - } else if (key->keyidx) { - if (WARN_ON(!sta)) - return -EOPNOTSUPP; - mac = sta->addr; - - if (vif->type != NL80211_IFTYPE_AP) { - /* Only keyidx 0 should be used with unicast key, but - * allow this for client mode for now. */ - idx = key->keyidx; - } else - return -EIO; - } else { - if (WARN_ON(!sta)) - return -EOPNOTSUPP; - mac = sta->addr; - - idx = ath_reserve_key_cache_slot(common, key->alg); - } - - if (idx < 0) - return -ENOSPC; /* no free key cache entries */ - - if (key->alg == ALG_TKIP) - ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, - vif->type == NL80211_IFTYPE_AP); - else - ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); - - if (!ret) - return -EIO; - - set_bit(idx, common->keymap); - if (key->alg == ALG_TKIP) { - set_bit(idx + 64, common->keymap); - if (common->splitmic) { - set_bit(idx + 32, common->keymap); - set_bit(idx + 64 + 32, common->keymap); - } - } - - return idx; -} -EXPORT_SYMBOL(ath9k_cmn_key_config); - -/* - * Delete Key. - */ -void ath9k_cmn_key_delete(struct ath_common *common, - struct ieee80211_key_conf *key) -{ - struct ath_hw *ah = common->ah; - - ath9k_hw_keyreset(ah, key->hw_key_idx); - if (key->hw_key_idx < IEEE80211_WEP_NKID) - return; - - clear_bit(key->hw_key_idx, common->keymap); - if (key->alg != ALG_TKIP) - return; - - clear_bit(key->hw_key_idx + 64, common->keymap); - if (common->splitmic) { - ath9k_hw_keyreset(ah, key->hw_key_idx + 32); - clear_bit(key->hw_key_idx + 32, common->keymap); - clear_bit(key->hw_key_idx + 64 + 32, common->keymap); + ath_print(common, ATH_DBG_BTCOEX, + "Invalid Stomptype\n"); + break; } -} -EXPORT_SYMBOL(ath9k_cmn_key_delete); - -int ath9k_cmn_count_streams(unsigned int chainmask, int max) -{ - int streams = 0; - - do { - if (++streams == max) - break; - } while ((chainmask = chainmask & (chainmask - 1))); - return streams; + ath9k_hw_btcoex_enable(ah); } -EXPORT_SYMBOL(ath9k_cmn_count_streams); +EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp); static int __init ath9k_cmn_init(void) { diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 97809d39c73fc81f1eb59ea14879a1d9618fb404..fea3b3315391d3e1e0af5fc9d51a3d82ffb69004 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -52,16 +52,20 @@ #define ATH_EP_RND(x, mul) \ ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) +/* Defines the BT AR_BT_COEX_WGHT used */ +enum ath_stomp_type { + ATH_BTCOEX_NO_STOMP, + ATH_BTCOEX_STOMP_ALL, + ATH_BTCOEX_STOMP_LOW, + ATH_BTCOEX_STOMP_NONE +}; + int ath9k_cmn_padpos(__le16 frame_control); int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, struct ath9k_channel *ichan); struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, struct ath_hw *ah); -int ath9k_cmn_key_config(struct ath_common *common, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key); -void ath9k_cmn_key_delete(struct ath_common *common, - struct ieee80211_key_conf *key); int ath9k_cmn_count_streams(unsigned int chainmask, int max); +void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, + enum ath_stomp_type stomp_type); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index cf500bf25ad578d6c205c63bd70a9d281a72a7b5..43e71a944cb17331340e2460b9f0fae79323e9da 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -383,96 +383,6 @@ static const struct file_operations fops_interrupt = { .llseek = default_llseek, }; -void ath_debug_stat_rc(struct ath_softc *sc, int final_rate) -{ - struct ath_rc_stats *stats; - - stats = &sc->debug.stats.rcstats[final_rate]; - stats->success++; -} - -void ath_debug_stat_retries(struct ath_softc *sc, int rix, - int xretries, int retries, u8 per) -{ - struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix]; - - stats->xretries += xretries; - stats->retries += retries; - stats->per = per; -} - -static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - char *buf; - unsigned int len = 0, max; - int i = 0; - ssize_t retval; - - if (sc->cur_rate_table == NULL) - return 0; - - max = 80 + sc->cur_rate_table->rate_cnt * 1024 + 1; - buf = kmalloc(max, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - len += sprintf(buf, "%6s %6s %6s " - "%10s %10s %10s %10s\n", - "HT", "MCS", "Rate", - "Success", "Retries", "XRetries", "PER"); - - for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) { - u32 ratekbps = sc->cur_rate_table->info[i].ratekbps; - struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i]; - char mcs[5]; - char htmode[5]; - int used_mcs = 0, used_htmode = 0; - - if (WLAN_RC_PHY_HT(sc->cur_rate_table->info[i].phy)) { - used_mcs = snprintf(mcs, 5, "%d", - sc->cur_rate_table->info[i].ratecode); - - if (WLAN_RC_PHY_40(sc->cur_rate_table->info[i].phy)) - used_htmode = snprintf(htmode, 5, "HT40"); - else if (WLAN_RC_PHY_20(sc->cur_rate_table->info[i].phy)) - used_htmode = snprintf(htmode, 5, "HT20"); - else - used_htmode = snprintf(htmode, 5, "????"); - } - - mcs[used_mcs] = '\0'; - htmode[used_htmode] = '\0'; - - len += snprintf(buf + len, max - len, - "%6s %6s %3u.%d: " - "%10u %10u %10u %10u\n", - htmode, - mcs, - ratekbps / 1000, - (ratekbps % 1000) / 100, - stats->success, - stats->retries, - stats->xretries, - stats->per); - } - - if (len > max) - len = max; - - retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - return retval; -} - -static const struct file_operations fops_rcstat = { - .read = read_file_rcstat, - .open = ath9k_debugfs_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - static const char * ath_wiphy_state_str(enum ath_wiphy_state state) { switch (state) { @@ -494,26 +404,20 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; + struct ath_wiphy *aphy = sc->pri_wiphy; + struct ieee80211_channel *chan = aphy->hw->conf.channel; char buf[512]; unsigned int len = 0; int i; u8 addr[ETH_ALEN]; + u32 tmp; len += snprintf(buf + len, sizeof(buf) - len, "primary: %s (%s chan=%d ht=%d)\n", wiphy_name(sc->pri_wiphy->hw->wiphy), ath_wiphy_state_str(sc->pri_wiphy->state), - sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht); - for (i = 0; i < sc->num_sec_wiphy; i++) { - struct ath_wiphy *aphy = sc->sec_wiphy[i]; - if (aphy == NULL) - continue; - len += snprintf(buf + len, sizeof(buf) - len, - "secondary: %s (%s chan=%d ht=%d)\n", - wiphy_name(aphy->hw->wiphy), - ath_wiphy_state_str(aphy->state), - aphy->chan_idx, aphy->chan_is_ht); - } + ieee80211_frequency_to_channel(chan->center_freq), + aphy->chan_is_ht); put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr); put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4); @@ -523,7 +427,51 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf, put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4); len += snprintf(buf + len, sizeof(buf) - len, "addrmask: %pM\n", addr); - + tmp = ath9k_hw_getrxfilter(sc->sc_ah); + len += snprintf(buf + len, sizeof(buf) - len, + "rfilt: 0x%x", tmp); + if (tmp & ATH9K_RX_FILTER_UCAST) + len += snprintf(buf + len, sizeof(buf) - len, " UCAST"); + if (tmp & ATH9K_RX_FILTER_MCAST) + len += snprintf(buf + len, sizeof(buf) - len, " MCAST"); + if (tmp & ATH9K_RX_FILTER_BCAST) + len += snprintf(buf + len, sizeof(buf) - len, " BCAST"); + if (tmp & ATH9K_RX_FILTER_CONTROL) + len += snprintf(buf + len, sizeof(buf) - len, " CONTROL"); + if (tmp & ATH9K_RX_FILTER_BEACON) + len += snprintf(buf + len, sizeof(buf) - len, " BEACON"); + if (tmp & ATH9K_RX_FILTER_PROM) + len += snprintf(buf + len, sizeof(buf) - len, " PROM"); + if (tmp & ATH9K_RX_FILTER_PROBEREQ) + len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); + if (tmp & ATH9K_RX_FILTER_PHYERR) + len += snprintf(buf + len, sizeof(buf) - len, " PHYERR"); + if (tmp & ATH9K_RX_FILTER_MYBEACON) + len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON"); + if (tmp & ATH9K_RX_FILTER_COMP_BAR) + len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR"); + if (tmp & ATH9K_RX_FILTER_PSPOLL) + len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL"); + if (tmp & ATH9K_RX_FILTER_PHYRADAR) + len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); + if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL) + len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL\n"); + else + len += snprintf(buf + len, sizeof(buf) - len, "\n"); + + /* Put variable-length stuff down here, and check for overflows. */ + for (i = 0; i < sc->num_sec_wiphy; i++) { + struct ath_wiphy *aphy = sc->sec_wiphy[i]; + if (aphy == NULL) + continue; + chan = aphy->hw->conf.channel; + len += snprintf(buf + len, sizeof(buf) - len, + "secondary: %s (%s chan=%d ht=%d)\n", + wiphy_name(aphy->hw->wiphy), + ath_wiphy_state_str(aphy->state), + ieee80211_frequency_to_channel(chan->center_freq), + aphy->chan_is_ht); + } if (len > sizeof(buf)) len = sizeof(buf); @@ -670,6 +618,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("DESC CFG Error: ", desc_cfg_err); PR("DATA Underrun: ", data_underrun); PR("DELIM Underrun: ", delim_underrun); + PR("TX-Pkts-All: ", tx_pkts_all); + PR("TX-Bytes-All: ", tx_bytes_all); if (len > size) len = size; @@ -683,6 +633,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, struct ath_tx_status *ts) { + TX_STAT_INC(txq->axq_qnum, tx_pkts_all); + sc->debug.stats.txstats[txq->axq_qnum].tx_bytes_all += bf->bf_mpdu->len; + if (bf_isampdu(bf)) { if (bf_isxretried(bf)) TX_STAT_INC(txq->axq_qnum, a_xretries); @@ -778,6 +731,13 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL); PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL); + len += snprintf(buf + len, size - len, + "%18s : %10u\n", "RX-Pkts-All", + sc->debug.stats.rxstats.rx_pkts_all); + len += snprintf(buf + len, size - len, + "%18s : %10u\n", "RX-Bytes-All", + sc->debug.stats.rxstats.rx_bytes_all); + if (len > size) len = size; @@ -796,6 +756,9 @@ void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) u32 phyerr; + RX_STAT_INC(rx_pkts_all); + sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen; + if (rs->rs_status & ATH9K_RXERR_CRC) RX_STAT_INC(crc_err); if (rs->rs_status & ATH9K_RXERR_DECRYPT) @@ -935,10 +898,6 @@ int ath9k_init_debug(struct ath_hw *ah) sc, &fops_interrupt)) goto err; - if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy, - sc, &fops_rcstat)) - goto err; - if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_wiphy)) goto err; diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 5d21704e87fff40c078382e1010f4b1fc529efcf..bb0823242ba008e0ccc4cbe0b169539ffa8c8dd3 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -80,15 +80,12 @@ struct ath_interrupt_stats { u32 bb_watchdog; }; -struct ath_rc_stats { - u32 success; - u32 retries; - u32 xretries; - u8 per; -}; - /** * struct ath_tx_stats - Statistics about TX + * @tx_pkts_all: No. of total frames transmitted, including ones that + may have had errors. + * @tx_bytes_all: No. of total bytes transmitted, including ones that + may have had errors. * @queued: Total MPDUs (non-aggr) queued * @completed: Total MPDUs (non-aggr) completed * @a_aggr: Total no. of aggregates queued @@ -107,6 +104,8 @@ struct ath_rc_stats { * @delim_urn: TX delimiter underrun errors */ struct ath_tx_stats { + u32 tx_pkts_all; + u32 tx_bytes_all; u32 queued; u32 completed; u32 a_aggr; @@ -124,6 +123,10 @@ struct ath_tx_stats { /** * struct ath_rx_stats - RX Statistics + * @rx_pkts_all: No. of total frames received, including ones that + may have had errors. + * @rx_bytes_all: No. of total bytes received, including ones that + may have had errors. * @crc_err: No. of frames with incorrect CRC value * @decrypt_crc_err: No. of frames whose CRC check failed after decryption process completed @@ -136,6 +139,8 @@ struct ath_tx_stats { * @phy_err_stats: Individual PHY error statistics */ struct ath_rx_stats { + u32 rx_pkts_all; + u32 rx_bytes_all; u32 crc_err; u32 decrypt_crc_err; u32 phy_err; @@ -148,7 +153,6 @@ struct ath_rx_stats { struct ath_stats { struct ath_interrupt_stats istats; - struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; struct ath_rx_stats rxstats; }; @@ -165,12 +169,9 @@ void ath9k_exit_debug(struct ath_hw *ah); int ath9k_debug_create_root(void); void ath9k_debug_remove_root(void); void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); -void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, struct ath_tx_status *ts); void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); -void ath_debug_stat_retries(struct ath_softc *sc, int rix, - int xretries, int retries, u8 per); #else @@ -197,11 +198,6 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc, { } -static inline void ath_debug_stat_rc(struct ath_softc *sc, - int final_rate) -{ -} - static inline void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, @@ -214,11 +210,6 @@ static inline void ath_debug_stat_rx(struct ath_softc *sc, { } -static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, - int xretries, int retries, u8 per) -{ -} - #endif /* CONFIG_ATH9K_DEBUGFS */ #endif /* DEBUG_H */ diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 0b09db0f8e7d99b1c22c94803884a67043e2187e..dacb45e1b9063b620736475b6116975fcb60cf4d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -101,7 +101,7 @@ #define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) -#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_10_OR_LATER(ah) && \ +#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) #define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c @@ -266,6 +266,8 @@ enum eeprom_param { EEP_INTERNAL_REGULATOR, EEP_SWREG, EEP_PAPRD, + EEP_MODAL_VER, + EEP_ANT_DIV_CTL1, }; enum ar5416_rates { @@ -670,7 +672,8 @@ struct eeprom_ops { bool (*fill_eeprom)(struct ath_hw *hw); int (*get_eeprom_ver)(struct ath_hw *hw); int (*get_eeprom_rev)(struct ath_hw *hw); - u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band); + u8 (*get_num_ant_config)(struct ath_hw *hw, + enum ath9k_hal_freq_band band); u32 (*get_eeprom_antenna_cfg)(struct ath_hw *hw, struct ath9k_channel *chan); void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan); diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 9cccd12e8f2131aa176740b7cc9e940d6e3a582f..4fa4d8e28c64236ffa5d7547ad5d5234565658bc 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -179,6 +179,9 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k; struct modal_eep_4k_header *pModal = &eep->modalHeader; struct base_eep_header_4k *pBase = &eep->baseEepHeader; + u16 ver_minor; + + ver_minor = pBase->version & AR5416_EEP_VER_MINOR_MASK; switch (param) { case EEP_NFTHRESH_2: @@ -204,7 +207,7 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, case EEP_DB_2: return pModal->db1_1; case EEP_MINOR_REV: - return pBase->version & AR5416_EEP_VER_MINOR_MASK; + return ver_minor; case EEP_TX_MASK: return pBase->txMask; case EEP_RX_MASK: @@ -213,6 +216,15 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, return 0; case EEP_PWR_TABLE_OFFSET: return AR5416_PWR_TABLE_OFFSET_DB; + case EEP_MODAL_VER: + return pModal->version; + case EEP_ANT_DIV_CTL1: + return pModal->antdiv_ctl1; + case EEP_TXGAIN_TYPE: + if (ver_minor >= AR5416_EEP_MINOR_VER_19) + return pBase->txGainType; + else + return AR5416_EEP_TXGAIN_ORIGINAL; default: return 0; } @@ -329,7 +341,7 @@ static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah, } if (i == 0) { - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) ss = (int16_t)(0 - (minPwrT4[i] / 2)); else ss = 0; @@ -496,7 +508,6 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } } @@ -757,7 +768,7 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, regulatory->max_power_level = ratesArray[i]; - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { for (i = 0; i < Ar5416RateSize; i++) ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; } @@ -828,7 +839,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static void ath9k_hw_4k_set_addac(struct ath_hw *ah, @@ -905,9 +915,6 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); - - if (AR_SREV_9285_11(ah)) - REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); } /* @@ -1105,9 +1112,6 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, } - if (AR_SREV_9285_11(ah)) - REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); - REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, pModal->switchSettling); REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, @@ -1157,7 +1161,7 @@ static u32 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah, } static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah, - enum ieee80211_band freq_band) + enum ath9k_hal_freq_band freq_band) { return 1; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index dff2da777312bbb0e5b1c8902b370e79c41f75b4..966b9496a9dd4b51cf5c1f850fc987ea4b6ffff2 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -324,7 +324,7 @@ static void ath9k_hw_get_ar9287_gain_boundaries_pdadcs(struct ath_hw *ah, minDelta = 0; if (i == 0) { - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) ss = (int16_t)(0 - (minPwrT4[i] / 2)); else ss = 0; @@ -883,7 +883,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, ratesArray[i] = AR9287_MAX_RATE_POWER; } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { for (i = 0; i < Ar5416RateSize; i++) ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2; } @@ -977,7 +977,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah, else i = rate6mb; - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) regulatory->max_power_level = ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2; else @@ -1126,7 +1126,7 @@ static void ath9k_hw_ar9287_set_board_values(struct ath_hw *ah, } static u8 ath9k_hw_ar9287_get_num_ant_config(struct ath_hw *ah, - enum ieee80211_band freq_band) + enum ath9k_hal_freq_band freq_band) { return 1; } diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index afa2b73ddbdde865bb91491f283dd7eceb6cdf49..76b4d65472dd2b37dbf98ff69b57646e53443c61 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -223,7 +223,7 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) } /* Enable fixup for AR_AN_TOP2 if necessary */ - if (AR_SREV_9280_10_OR_LATER(ah) && + if (AR_SREV_9280_20_OR_LATER(ah) && (eep->baseEepHeader.version & 0xff) > 0x0a && eep->baseEepHeader.pwdclkind == 0) ah->need_an_top2_fixup = 1; @@ -317,7 +317,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah, if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { txRxAttenLocal = pModal->txRxAttenCh[i]; - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[i]); @@ -344,7 +344,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah, } } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); @@ -408,7 +408,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, regChainOffset, i); } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { if (IS_CHAN_2GHZ(chan)) { ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0, AR_AN_RF2G1_CH0_OB, @@ -461,7 +461,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize); - if (!AR_SREV_9280_10_OR_LATER(ah)) + if (!AR_SREV_9280_20_OR_LATER(ah)) REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_PGA, pModal->pgaDesiredSize); @@ -478,7 +478,7 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn); - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62, pModal->thresh62); REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, @@ -696,7 +696,7 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, } if (i == 0) { - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) ss = (int16_t)(0 - (minPwrT4[i] / 2)); else ss = 0; @@ -1291,7 +1291,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, ratesArray[i] = AR5416_MAX_RATE_POWER; } - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { for (i = 0; i < Ar5416RateSize; i++) { int8_t pwr_table_offset; @@ -1395,7 +1395,7 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, else if (IS_CHAN_HT20(chan)) i = rateHt20_0; - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) regulatory->max_power_level = ratesArray[i] + AR5416_PWR_TABLE_OFFSET_DB * 2; else @@ -1418,11 +1418,11 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah, } static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, - enum ieee80211_band freq_band) + enum ath9k_hal_freq_band freq_band) { struct ar5416_eeprom_def *eep = &ah->eeprom.def; struct modal_eep_header *pModal = - &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]); + &(eep->modalHeader[freq_band]); struct base_eep_header *pBase = &eep->baseEepHeader; u8 num_ant_config; diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 3a8ee999da5dc111414b6aebf284930dff75cae9..4a9a68bba324790b5a549332e71723867a46eaf4 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -251,36 +251,6 @@ static void ath_detect_bt_priority(struct ath_softc *sc) } } -/* - * Configures appropriate weight based on stomp type. - */ -static void ath9k_btcoex_bt_stomp(struct ath_softc *sc, - enum ath_stomp_type stomp_type) -{ - struct ath_hw *ah = sc->sc_ah; - - switch (stomp_type) { - case ATH_BTCOEX_STOMP_ALL: - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_ALL_WLAN_WGHT); - break; - case ATH_BTCOEX_STOMP_LOW: - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_LOW_WLAN_WGHT); - break; - case ATH_BTCOEX_STOMP_NONE: - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_NONE_WLAN_WGHT); - break; - default: - ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, - "Invalid Stomptype\n"); - break; - } - - ath9k_hw_btcoex_enable(ah); -} - static void ath9k_gen_timer_start(struct ath_hw *ah, struct ath_gen_timer *timer, u32 timer_next, @@ -319,6 +289,7 @@ static void ath_btcoex_period_timer(unsigned long data) struct ath_softc *sc = (struct ath_softc *) data; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_common *common = ath9k_hw_common(ah); u32 timer_period; bool is_btscan; @@ -328,7 +299,7 @@ static void ath_btcoex_period_timer(unsigned long data) spin_lock_bh(&btcoex->btcoex_lock); - ath9k_btcoex_bt_stomp(sc, is_btscan ? ATH_BTCOEX_STOMP_ALL : + ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : btcoex->bt_stomp_type); spin_unlock_bh(&btcoex->btcoex_lock); @@ -359,17 +330,18 @@ static void ath_btcoex_no_stomp_timer(void *arg) struct ath_softc *sc = (struct ath_softc *)arg; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_common *common = ath9k_hw_common(ah); bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; - ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + ath_print(common, ATH_DBG_BTCOEX, "no stomp timer running\n"); spin_lock_bh(&btcoex->btcoex_lock); if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) - ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE); + ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) - ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW); + ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); spin_unlock_bh(&btcoex->btcoex_lock); } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 17e7a9a367e70340a42d13c57beb167bfd4979d3..728d904c74d7d30408231c90b46a2cfe95f3e2a9 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -92,10 +92,10 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, cmd->skb = skb; cmd->hif_dev = hif_dev; - usb_fill_int_urb(urb, hif_dev->udev, - usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE), + usb_fill_bulk_urb(urb, hif_dev->udev, + usb_sndbulkpipe(hif_dev->udev, USB_REG_OUT_PIPE), skb->data, skb->len, - hif_usb_regout_cb, cmd, 1); + hif_usb_regout_cb, cmd); usb_anchor_urb(urb, &hif_dev->regout_submitted); ret = usb_submit_urb(urb, GFP_KERNEL); @@ -541,7 +541,8 @@ static void ath9k_hif_usb_reg_in_cb(struct urb *urb) } usb_fill_int_urb(urb, hif_dev->udev, - usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), + usb_rcvbulkpipe(hif_dev->udev, + USB_REG_IN_PIPE), nskb->data, MAX_REG_IN_BUF_SIZE, ath9k_hif_usb_reg_in_cb, nskb, 1); @@ -720,7 +721,8 @@ static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) goto err; usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev, - usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), + usb_rcvbulkpipe(hif_dev->udev, + USB_REG_IN_PIPE), skb->data, MAX_REG_IN_BUF_SIZE, ath9k_hif_usb_reg_in_cb, skb, 1); @@ -822,7 +824,9 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { - int ret; + int ret, idx; + struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; + struct usb_endpoint_descriptor *endp; /* Request firmware */ ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name, @@ -850,6 +854,22 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) goto err_fw_download; } + /* On downloading the firmware to the target, the USB descriptor of EP4 + * is 'patched' to change the type of the endpoint to Bulk. This will + * bring down CPU usage during the scan period. + */ + for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) { + endp = &alt->endpoint[idx].desc; + if (((endp->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) + == 0x04) && + ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT)) { + endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK; + endp->bmAttributes |= USB_ENDPOINT_XFER_BULK; + endp->bInterval = 0; + } + } + return 0; err_fw_download: @@ -920,7 +940,8 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, } ret = ath9k_htc_hw_init(hif_dev->htc_handle, - &hif_dev->udev->dev, hif_dev->device_id); + &hif_dev->udev->dev, hif_dev->device_id, + hif_dev->udev->product); if (ret) { ret = -EINVAL; goto err_htc_hw_init; diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 43b9e21bc56284da1246ec1020cd23907a11d0df..75ecf6a30d25c6ac68d346c5ac862a0255ba4be1 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -316,17 +316,32 @@ struct htc_beacon_config { u8 dtim_count; }; -#define OP_INVALID BIT(0) -#define OP_SCANNING BIT(1) -#define OP_FULL_RESET BIT(2) -#define OP_LED_ASSOCIATED BIT(3) -#define OP_LED_ON BIT(4) -#define OP_PREAMBLE_SHORT BIT(5) -#define OP_PROTECT_ENABLE BIT(6) -#define OP_ASSOCIATED BIT(7) -#define OP_ENABLE_BEACON BIT(8) -#define OP_LED_DEINIT BIT(9) -#define OP_UNPLUGGED BIT(10) +struct ath_btcoex { + u32 bt_priority_cnt; + unsigned long bt_priority_time; + int bt_stomp_type; /* Types of BT stomping */ + u32 btcoex_no_stomp; + u32 btcoex_period; + u32 btscan_no_stomp; +}; + +void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv); +void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv); +void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); + +#define OP_INVALID BIT(0) +#define OP_SCANNING BIT(1) +#define OP_FULL_RESET BIT(2) +#define OP_LED_ASSOCIATED BIT(3) +#define OP_LED_ON BIT(4) +#define OP_PREAMBLE_SHORT BIT(5) +#define OP_PROTECT_ENABLE BIT(6) +#define OP_ASSOCIATED BIT(7) +#define OP_ENABLE_BEACON BIT(8) +#define OP_LED_DEINIT BIT(9) +#define OP_UNPLUGGED BIT(10) +#define OP_BT_PRIORITY_DETECTED BIT(11) +#define OP_BT_SCAN BIT(12) struct ath9k_htc_priv { struct device *dev; @@ -391,6 +406,9 @@ struct ath9k_htc_priv { int cabq; int hwq_map[WME_NUM_AC]; + struct ath_btcoex btcoex; + struct delayed_work coex_period_work; + struct delayed_work duty_cycle_work; #ifdef CONFIG_ATH9K_HTC_DEBUGFS struct ath9k_debug debug; #endif @@ -443,7 +461,7 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv); void ath9k_deinit_leds(struct ath9k_htc_priv *priv); int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, - u16 devid); + u16 devid, char *product); void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); #ifdef CONFIG_PM int ath9k_htc_resume(struct htc_target *htc_handle); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index bd1506e69105d77ad77396e4cef62da89fb75ced..1b72aa482ac742aeaf7705929ea3cdbadf718232 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -235,7 +235,14 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) ath9k_hw_get_txq_props(ah, qnum, &qi_be); qi.tqi_aifs = qi_be.tqi_aifs; - qi.tqi_cwmin = 4*qi_be.tqi_cwmin; + /* For WIFI Beacon Distribution + * Long slot time : 2x cwmin + * Short slot time : 4x cwmin + */ + if (ah->slottime == ATH9K_SLOT_TIME_20) + qi.tqi_cwmin = 2*qi_be.tqi_cwmin; + else + qi.tqi_cwmin = 4*qi_be.tqi_cwmin; qi.tqi_cwmax = qi_be.tqi_cwmax; if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) { diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c new file mode 100644 index 0000000000000000000000000000000000000000..50eec9a3b88c14890d1a93b9a5d6f84c64d30ed0 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -0,0 +1,134 @@ +#include "htc.h" + +/******************/ +/* BTCOEX */ +/******************/ + +/* + * Detects if there is any priority bt traffic + */ +static void ath_detect_bt_priority(struct ath9k_htc_priv *priv) +{ + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_hw *ah = priv->ah; + + if (ath9k_hw_gpio_get(ah, ah->btcoex_hw.btpriority_gpio)) + btcoex->bt_priority_cnt++; + + if (time_after(jiffies, btcoex->bt_priority_time + + msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { + priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); + /* Detect if colocated bt started scanning */ + if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { + ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "BT scan detected"); + priv->op_flags |= (OP_BT_SCAN | + OP_BT_PRIORITY_DETECTED); + } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { + ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "BT priority traffic detected"); + priv->op_flags |= OP_BT_PRIORITY_DETECTED; + } + + btcoex->bt_priority_cnt = 0; + btcoex->bt_priority_time = jiffies; + } +} + +/* + * This is the master bt coex work which runs for every + * 45ms, bt traffic will be given priority during 55% of this + * period while wlan gets remaining 45% + */ +static void ath_btcoex_period_work(struct work_struct *work) +{ + struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, + coex_period_work.work); + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_common *common = ath9k_hw_common(priv->ah); + u32 timer_period; + bool is_btscan; + int ret; + u8 cmd_rsp, aggr; + + ath_detect_bt_priority(priv); + + is_btscan = !!(priv->op_flags & OP_BT_SCAN); + + aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED; + + WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr); + + ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : + btcoex->bt_stomp_type); + + timer_period = is_btscan ? btcoex->btscan_no_stomp : + btcoex->btcoex_no_stomp; + ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work, + msecs_to_jiffies(timer_period)); + ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, + msecs_to_jiffies(btcoex->btcoex_period)); +} + +/* + * Work to time slice between wlan and bt traffic and + * configure weight registers + */ +static void ath_btcoex_duty_cycle_work(struct work_struct *work) +{ + struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, + duty_cycle_work.work); + struct ath_hw *ah = priv->ah; + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_common *common = ath9k_hw_common(ah); + bool is_btscan = priv->op_flags & OP_BT_SCAN; + + ath_print(common, ATH_DBG_BTCOEX, + "time slice work for bt and wlan\n"); + + if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) + ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); + else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) + ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); +} + +void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) +{ + struct ath_btcoex *btcoex = &priv->btcoex; + + btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; + btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * + btcoex->btcoex_period / 100; + btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * + btcoex->btcoex_period / 100; + INIT_DELAYED_WORK(&priv->coex_period_work, ath_btcoex_period_work); + INIT_DELAYED_WORK(&priv->duty_cycle_work, ath_btcoex_duty_cycle_work); +} + +/* + * (Re)start btcoex work + */ + +void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) +{ + struct ath_btcoex *btcoex = &priv->btcoex; + struct ath_hw *ah = priv->ah; + + ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, + "Starting btcoex work"); + + btcoex->bt_priority_cnt = 0; + btcoex->bt_priority_time = jiffies; + priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); + ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, 0); +} + + +/* + * Cancel btcoex and bt duty cycle work. + */ +void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) +{ + cancel_delayed_work_sync(&priv->coex_period_work); + cancel_delayed_work_sync(&priv->duty_cycle_work); +} diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 2d4279191d7a7d6d1690d12a809cf9eb6dd8ef8a..3d7b97f1b3aeebe5840c438b5ccf631de702d6c2 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -41,6 +41,8 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); .max_power = 20, \ } +#define ATH_HTC_BTCOEX_PRODUCT_ID "wb193" + static struct ieee80211_channel ath9k_2ghz_channels[] = { CHAN2G(2412, 0), /* Channel 1 */ CHAN2G(2417, 1), /* Channel 2 */ @@ -378,15 +380,6 @@ static void ath9k_enable_regwrite_buffer(void *hw_priv) atomic_inc(&priv->wmi->mwrite_cnt); } -static void ath9k_disable_regwrite_buffer(void *hw_priv) -{ - struct ath_hw *ah = (struct ath_hw *) hw_priv; - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; - - atomic_dec(&priv->wmi->mwrite_cnt); -} - static void ath9k_regwrite_flush(void *hw_priv) { struct ath_hw *ah = (struct ath_hw *) hw_priv; @@ -395,6 +388,8 @@ static void ath9k_regwrite_flush(void *hw_priv) u32 rsp_status; int r; + atomic_dec(&priv->wmi->mwrite_cnt); + mutex_lock(&priv->wmi->multi_write_mutex); if (priv->wmi->multi_write_idx) { @@ -418,7 +413,6 @@ static const struct ath_ops ath9k_common_ops = { .read = ath9k_regread, .write = ath9k_regwrite, .enable_write_buffer = ath9k_enable_regwrite_buffer, - .disable_write_buffer = ath9k_disable_regwrite_buffer, .write_flush = ath9k_regwrite_flush, }; @@ -559,17 +553,20 @@ static void ath9k_init_crypto(struct ath9k_htc_priv *priv) common->keymax = ATH_KEYMAX; } + if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) + common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; + /* * Reset the key cache since some parts do not * reset the contents on initial power up. */ for (i = 0; i < common->keymax; i++) - ath9k_hw_keyreset(priv->ah, (u16) i); + ath_hw_keyreset(common, (u16) i); } static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) { - if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) { + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { priv->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_channels; priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; @@ -580,7 +577,7 @@ static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) ARRAY_SIZE(ath9k_legacy_rates); } - if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) { + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { priv->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_channels; priv->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; priv->sbands[IEEE80211_BAND_5GHZ].n_channels = @@ -599,13 +596,36 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv) common->tx_chainmask = priv->ah->caps.tx_chainmask; common->rx_chainmask = priv->ah->caps.rx_chainmask; - if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); + memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); priv->ah->opmode = NL80211_IFTYPE_STATION; } -static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid) +static void ath9k_init_btcoex(struct ath9k_htc_priv *priv) +{ + int qnum; + + switch (priv->ah->btcoex_hw.scheme) { + case ATH_BTCOEX_CFG_NONE: + break; + case ATH_BTCOEX_CFG_3WIRE: + priv->ah->btcoex_hw.btactive_gpio = 7; + priv->ah->btcoex_hw.btpriority_gpio = 6; + priv->ah->btcoex_hw.wlanactive_gpio = 8; + priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; + ath9k_hw_btcoex_init_3wire(priv->ah); + ath_htc_init_btcoex_work(priv); + qnum = priv->hwq_map[WME_AC_BE]; + ath9k_hw_init_btcoex_hw(priv->ah, qnum); + break; + default: + WARN_ON(1); + break; + } +} + +static int ath9k_init_priv(struct ath9k_htc_priv *priv, + u16 devid, char *product) { struct ath_hw *ah = NULL; struct ath_common *common; @@ -672,6 +692,11 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid) ath9k_init_channels_rates(priv); ath9k_init_misc(priv); + if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { + ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; + ath9k_init_btcoex(priv); + } + return 0; err_queues: @@ -715,18 +740,18 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) + sizeof(struct htc_frame_hdr) + 4; - if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->sbands[IEEE80211_BAND_2GHZ]; - if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->sbands[IEEE80211_BAND_5GHZ]; if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) setup_ht_cap(priv, &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap); - if (test_bit(ATH9K_MODE_11A, priv->ah->caps.wireless_modes)) + if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) setup_ht_cap(priv, &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); } @@ -734,7 +759,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } -static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid) +static int ath9k_init_device(struct ath9k_htc_priv *priv, + u16 devid, char *product) { struct ieee80211_hw *hw = priv->hw; struct ath_common *common; @@ -743,7 +769,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid) struct ath_regulatory *reg; /* Bring up device */ - error = ath9k_init_priv(priv, devid); + error = ath9k_init_priv(priv, devid, product); if (error != 0) goto err_init; @@ -801,7 +827,7 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid) } int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, - u16 devid) + u16 devid, char *product) { struct ieee80211_hw *hw; struct ath9k_htc_priv *priv; @@ -835,7 +861,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, /* The device may have been unplugged earlier. */ priv->op_flags &= ~OP_UNPLUGGED; - ret = ath9k_init_device(priv, devid); + ret = ath9k_init_device(priv, devid, product); if (ret) goto err_init; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index bc2ca7d898e9c269c565cd71c0eaa6928fde4f21..9a3be8da755d2f7181ada323e5ec9054b58a0a9e 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -137,8 +137,6 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, if (priv->op_flags & OP_FULL_RESET) fastcc = false; - /* Fiddle around with fastcc later on, for now just use full reset */ - fastcc = false; ath9k_htc_ps_wakeup(priv); htc_stop(priv->htc); WMI_CMD(WMI_DISABLE_INTR_CMDID); @@ -146,9 +144,10 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, WMI_CMD(WMI_STOP_RECV_CMDID); ath_print(common, ATH_DBG_CONFIG, - "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n", + "(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n", priv->ah->curchan->channel, - channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf)); + channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf), + fastcc); caldata = &priv->caldata[channel->hw_value]; ret = ath9k_hw_reset(ah, hchan, caldata, fastcc); @@ -764,23 +763,12 @@ void ath9k_ani_work(struct work_struct *work) ath9k_hw_ani_monitor(ah, ah->curchan); /* Perform calibration if necessary */ - if (longcal || shortcal) { + if (longcal || shortcal) common->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan, common->rx_chainmask, longcal); - if (longcal) - common->ani.noise_floor = - ath9k_hw_getchan_noise(ah, ah->curchan); - - ath_print(common, ATH_DBG_ANI, - " calibrate chan %u/%x nf: %d\n", - ah->curchan->channel, - ah->curchan->channelFlags, - common->ani.noise_floor); - } - ath9k_htc_ps_restore(priv); } @@ -1213,6 +1201,12 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ieee80211_wake_queues(hw); + if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) { + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); + ath9k_hw_btcoex_enable(ah); + ath_htc_resume_btcoex_work(priv); + } mutex_unlock(&priv->mutex); return ret; @@ -1236,7 +1230,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) /* Cancel all the running timers/work .. */ cancel_work_sync(&priv->ps_work); - cancel_delayed_work_sync(&priv->ath9k_ani_work); cancel_delayed_work_sync(&priv->ath9k_led_blink_work); ath9k_led_stop_brightness(priv); @@ -1257,6 +1250,12 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) "Monitor interface removed\n"); } + if (ah->btcoex_hw.enabled) { + ath9k_hw_btcoex_disable(ah); + if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) + ath_htc_cancel_btcoex_work(priv); + } + ath9k_hw_phy_disable(ah); ath9k_hw_disable(ah); ath9k_hw_configpcipowersave(ah, 1, 1); @@ -1458,6 +1457,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) FIF_PSPOLL | \ FIF_OTHER_BSS | \ FIF_BCN_PRBRESP_PROMISC | \ + FIF_PROBE_REQ | \ FIF_FCSFAIL) static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, @@ -1583,20 +1583,21 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: - ret = ath9k_cmn_key_config(common, vif, sta, key); + ret = ath_key_config(common, vif, sta, key); if (ret >= 0) { key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (key->alg == ALG_TKIP) + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP) + if (priv->ah->sw_mgmt_crypto && + key->cipher == WLAN_CIPHER_SUITE_CCMP) key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; ret = 0; } break; case DISABLE_KEY: - ath9k_cmn_key_delete(common, key); + ath_key_delete(common, key); break; default: ret = -EINVAL; @@ -1777,7 +1778,8 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) priv->op_flags |= OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); cancel_work_sync(&priv->ps_work); - cancel_delayed_work_sync(&priv->ath9k_ani_work); + if (priv->op_flags & OP_ASSOCIATED) + cancel_delayed_work_sync(&priv->ath9k_ani_work); mutex_unlock(&priv->mutex); } @@ -1791,9 +1793,10 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) priv->op_flags &= ~OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); priv->op_flags |= OP_FULL_RESET; - if (priv->op_flags & OP_ASSOCIATED) + if (priv->op_flags & OP_ASSOCIATED) { ath9k_htc_beacon_config(priv, priv->vif); - ath_start_ani(priv); + ath_start_ani(priv); + } ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 2a6e45a293a90f38b7add877b0ca231c603ebe1b..3d19b5bc937f9c1c285e23645fcbf6a929037b21 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -369,8 +369,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | ATH9K_RX_FILTER_MCAST; - /* If not a STA, enable processing of Probe Requests */ - if (ah->opmode != NL80211_IFTYPE_STATION) + if (priv->rxfilter & FIF_PROBE_REQ) rfilt |= ATH9K_RX_FILTER_PROBEREQ; /* @@ -415,8 +414,7 @@ static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) ath9k_hw_setrxfilter(ah, rfilt); /* configure bssid mask */ - if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath_hw_setbssidmask(common); + ath_hw_setbssidmask(common); /* configure operational mode */ ath9k_hw_setopmode(ah); diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 705c0f342e1c0342ea4000c5ea747ececf31dfce..861ec92693096d07bfca64d4a16e0076fa390ce6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -462,9 +462,9 @@ void ath9k_htc_hw_free(struct htc_target *htc) } int ath9k_htc_hw_init(struct htc_target *target, - struct device *dev, u16 devid) + struct device *dev, u16 devid, char *product) { - if (ath9k_htc_probe_device(target, dev, devid)) { + if (ath9k_htc_probe_device(target, dev, devid, product)) { printk(KERN_ERR "Failed to initialize the device\n"); return -ENODEV; } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h index faba6790328b42ae20520ffee47cf90799e788f0..07b6509d58964681a141c92266fa5fb9c8a6cfff 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.h +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h @@ -239,7 +239,7 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, struct device *dev); void ath9k_htc_hw_free(struct htc_target *htc); int ath9k_htc_hw_init(struct htc_target *target, - struct device *dev, u16 devid); + struct device *dev, u16 devid, char *product); void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug); #endif /* HTC_HST_H */ diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index ffecbadaea4a592450da48c3e849b9bdd1961b07..0a4ad348b6997d90594201b0d8a3aaadc3c11bca 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -128,17 +128,6 @@ static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); } -static inline void ath9k_hw_procmibevent(struct ath_hw *ah) -{ - ath9k_hw_ops(ah)->ani_proc_mib_event(ah); -} - -static inline void ath9k_hw_ani_monitor(struct ath_hw *ah, - struct ath9k_channel *chan) -{ - ath9k_hw_ops(ah)->ani_monitor(ah, chan); -} - /* Private hardware call ops */ /* PHY ops */ @@ -276,15 +265,4 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah, ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal); } -static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah, - enum ath9k_cal_types calType) -{ - return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType); -} - -static inline void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) -{ - ath9k_hw_private_ops(ah)->ani_reset(ah, is_scanning); -} - #endif /* ATH9K_HW_OPS_H */ diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 3384ca1645622e4d3307d957ff193198f6b7e888..cc13ee1178237da72617f92bf7b3a103c82e772b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -88,29 +88,32 @@ static void ath9k_hw_ani_cache_ini_regs(struct ath_hw *ah) /* Helper Functions */ /********************/ -static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) +static void ath9k_hw_set_clockrate(struct ath_hw *ah) { struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; + struct ath_common *common = ath9k_hw_common(ah); + unsigned int clockrate; if (!ah->curchan) /* should really check for CCK instead */ - return usecs *ATH9K_CLOCK_RATE_CCK; - if (conf->channel->band == IEEE80211_BAND_2GHZ) - return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; - - if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) - return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; + clockrate = ATH9K_CLOCK_RATE_CCK; + else if (conf->channel->band == IEEE80211_BAND_2GHZ) + clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; + else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) + clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; else - return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM; + clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; + + if (conf_is_ht40(conf)) + clockrate *= 2; + + common->clockrate = clockrate; } static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) { - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; + struct ath_common *common = ath9k_hw_common(ah); - if (conf_is_ht40(conf)) - return ath9k_hw_mac_clks(ah, usecs) * 2; - else - return ath9k_hw_mac_clks(ah, usecs); + return usecs * common->clockrate; } bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout) @@ -299,7 +302,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } /* This should work for all families including legacy */ @@ -371,10 +373,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.pcie_clock_req = 0; ah->config.pcie_waen = 0; ah->config.analog_shiftreg = 1; - ah->config.ofdm_trig_low = 200; - ah->config.ofdm_trig_high = 500; - ah->config.cck_trig_high = 200; - ah->config.cck_trig_low = 100; ah->config.enable_ani = true; for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { @@ -565,7 +563,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) ath9k_hw_init_cal_settings(ah); ah->ani_function = ATH9K_ANI_ALL; - if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; if (!AR_SREV_9300_20_OR_LATER(ah)) ah->ani_function &= ~ATH9K_ANI_MRC_CCK; @@ -676,7 +674,6 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } static void ath9k_hw_init_pll(struct ath_hw *ah, @@ -741,7 +738,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (AR_SREV_9300_20_OR_LATER(ah)) { REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0); @@ -885,7 +881,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); /* * Restore TX Trigger Level to its pre-reset value. @@ -933,7 +928,6 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (AR_SREV_9300_20_OR_LATER(ah)) ath9k_hw_reset_txstatus_ring(ah); @@ -1031,7 +1025,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) REG_WRITE(ah, AR_RTC_RC, rst_flags); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); udelay(50); @@ -1070,7 +1063,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) udelay(2); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (!AR_SREV_9300_20_OR_LATER(ah)) udelay(2); @@ -1167,6 +1159,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, "Failed to set channel\n"); return false; } + ath9k_hw_set_clockrate(ah); ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(regulatory, chan), @@ -1190,7 +1183,7 @@ bool ath9k_hw_check_alive(struct ath_hw *ah) int count = 50; u32 reg; - if (AR_SREV_9285_10_OR_LATER(ah)) + if (AR_SREV_9285_12_OR_LATER(ah)) return true; do { @@ -1239,7 +1232,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) return -EIO; - if (curchan && !ah->chip_fullsleep && ah->caldata) + if (curchan && !ah->chip_fullsleep) ath9k_hw_getnf(ah, curchan); ah->caldata = caldata; @@ -1258,11 +1251,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, (chan->channel != ah->curchan->channel) && ((chan->channelFlags & CHANNEL_ALL) == (ah->curchan->channelFlags & CHANNEL_ALL)) && - !AR_SREV_9280(ah)) { + (!AR_SREV_9280(ah) || AR_DEVID_7010(ah))) { if (ath9k_hw_channel_change(ah, chan)) { ath9k_hw_loadnf(ah, ah->curchan); ath9k_hw_start_nfcal(ah, true); + if (AR_SREV_9271(ah)) + ar9002_hw_load_ani_reg(ah, chan); return 0; } } @@ -1310,7 +1305,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, if (tsf) ath9k_hw_settsf64(ah, tsf); - if (AR_SREV_9280_10_OR_LATER(ah)) + if (AR_SREV_9280_20_OR_LATER(ah)) REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); if (!AR_SREV_9300_20_OR_LATER(ah)) @@ -1372,19 +1367,19 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); r = ath9k_hw_rf_set_freq(ah, chan); if (r) return r; + ath9k_hw_set_clockrate(ah); + ENABLE_REGWRITE_BUFFER(ah); for (i = 0; i < AR_NUM_DCU; i++) REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); ah->intr_txqs = 0; for (i = 0; i < ah->caps.total_queues; i++) @@ -1432,7 +1427,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); /* * For big endian systems turn on swapping for descriptors @@ -1474,283 +1468,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, } EXPORT_SYMBOL(ath9k_hw_reset); -/************************/ -/* Key Cache Management */ -/************************/ - -bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry) -{ - u32 keyType; - - if (entry >= ah->caps.keycache_size) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "keychache entry %u out of range\n", entry); - return false; - } - - keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); - - REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); - REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); - REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); - - if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { - u16 micentry = entry + 64; - - REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); - - } - - return true; -} -EXPORT_SYMBOL(ath9k_hw_keyreset); - -static bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac) -{ - u32 macHi, macLo; - u32 unicast_flag = AR_KEYTABLE_VALID; - - if (entry >= ah->caps.keycache_size) { - ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, - "keychache entry %u out of range\n", entry); - return false; - } - - if (mac != NULL) { - /* - * AR_KEYTABLE_VALID indicates that the address is a unicast - * address, which must match the transmitter address for - * decrypting frames. - * Not setting this bit allows the hardware to use the key - * for multicast frame decryption. - */ - if (mac[0] & 0x01) - unicast_flag = 0; - - macHi = (mac[5] << 8) | mac[4]; - macLo = (mac[3] << 24) | - (mac[2] << 16) | - (mac[1] << 8) | - mac[0]; - macLo >>= 1; - macLo |= (macHi & 1) << 31; - macHi >>= 1; - } else { - macLo = macHi = 0; - } - REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); - REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); - - return true; -} - -bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, - const struct ath9k_keyval *k, - const u8 *mac) -{ - const struct ath9k_hw_capabilities *pCap = &ah->caps; - struct ath_common *common = ath9k_hw_common(ah); - u32 key0, key1, key2, key3, key4; - u32 keyType; - - if (entry >= pCap->keycache_size) { - ath_print(common, ATH_DBG_FATAL, - "keycache entry %u out of range\n", entry); - return false; - } - - switch (k->kv_type) { - case ATH9K_CIPHER_AES_OCB: - keyType = AR_KEYTABLE_TYPE_AES; - break; - case ATH9K_CIPHER_AES_CCM: - if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) { - ath_print(common, ATH_DBG_ANY, - "AES-CCM not supported by mac rev 0x%x\n", - ah->hw_version.macRev); - return false; - } - keyType = AR_KEYTABLE_TYPE_CCM; - break; - case ATH9K_CIPHER_TKIP: - keyType = AR_KEYTABLE_TYPE_TKIP; - if (ATH9K_IS_MIC_ENABLED(ah) - && entry + 64 >= pCap->keycache_size) { - ath_print(common, ATH_DBG_ANY, - "entry %u inappropriate for TKIP\n", entry); - return false; - } - break; - case ATH9K_CIPHER_WEP: - if (k->kv_len < WLAN_KEY_LEN_WEP40) { - ath_print(common, ATH_DBG_ANY, - "WEP key length %u too small\n", k->kv_len); - return false; - } - if (k->kv_len <= WLAN_KEY_LEN_WEP40) - keyType = AR_KEYTABLE_TYPE_40; - else if (k->kv_len <= WLAN_KEY_LEN_WEP104) - keyType = AR_KEYTABLE_TYPE_104; - else - keyType = AR_KEYTABLE_TYPE_128; - break; - case ATH9K_CIPHER_CLR: - keyType = AR_KEYTABLE_TYPE_CLR; - break; - default: - ath_print(common, ATH_DBG_FATAL, - "cipher %u not supported\n", k->kv_type); - return false; - } - - key0 = get_unaligned_le32(k->kv_val + 0); - key1 = get_unaligned_le16(k->kv_val + 4); - key2 = get_unaligned_le32(k->kv_val + 6); - key3 = get_unaligned_le16(k->kv_val + 10); - key4 = get_unaligned_le32(k->kv_val + 12); - if (k->kv_len <= WLAN_KEY_LEN_WEP104) - key4 &= 0xff; - - /* - * Note: Key cache registers access special memory area that requires - * two 32-bit writes to actually update the values in the internal - * memory. Consequently, the exact order and pairs used here must be - * maintained. - */ - - if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) { - u16 micentry = entry + 64; - - /* - * Write inverted key[47:0] first to avoid Michael MIC errors - * on frames that could be sent or received at the same time. - * The correct key will be written in the end once everything - * else is ready. - */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); - - /* Write key[95:48] */ - REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); - REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); - - /* Write key[127:96] and key type */ - REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); - REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); - - /* Write MAC address for the entry */ - (void) ath9k_hw_keysetmac(ah, entry, mac); - - if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) { - /* - * TKIP uses two key cache entries: - * Michael MIC TX/RX keys in the same key cache entry - * (idx = main index + 64): - * key0 [31:0] = RX key [31:0] - * key1 [15:0] = TX key [31:16] - * key1 [31:16] = reserved - * key2 [31:0] = RX key [63:32] - * key3 [15:0] = TX key [15:0] - * key3 [31:16] = reserved - * key4 [31:0] = TX key [63:32] - */ - u32 mic0, mic1, mic2, mic3, mic4; - - mic0 = get_unaligned_le32(k->kv_mic + 0); - mic2 = get_unaligned_le32(k->kv_mic + 4); - mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff; - mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; - mic4 = get_unaligned_le32(k->kv_txmic + 4); - - /* Write RX[31:0] and TX[31:16] */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); - - /* Write RX[63:32] and TX[15:0] */ - REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); - REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); - - /* Write TX[63:32] and keyType(reserved) */ - REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); - REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), - AR_KEYTABLE_TYPE_CLR); - - } else { - /* - * TKIP uses four key cache entries (two for group - * keys): - * Michael MIC TX/RX keys are in different key cache - * entries (idx = main index + 64 for TX and - * main index + 32 + 96 for RX): - * key0 [31:0] = TX/RX MIC key [31:0] - * key1 [31:0] = reserved - * key2 [31:0] = TX/RX MIC key [63:32] - * key3 [31:0] = reserved - * key4 [31:0] = reserved - * - * Upper layer code will call this function separately - * for TX and RX keys when these registers offsets are - * used. - */ - u32 mic0, mic2; - - mic0 = get_unaligned_le32(k->kv_mic + 0); - mic2 = get_unaligned_le32(k->kv_mic + 4); - - /* Write MIC key[31:0] */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); - - /* Write MIC key[63:32] */ - REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); - REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); - - /* Write TX[63:32] and keyType(reserved) */ - REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), - AR_KEYTABLE_TYPE_CLR); - } - - /* MAC address registers are reserved for the MIC entry */ - REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); - REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); - - /* - * Write the correct (un-inverted) key[47:0] last to enable - * TKIP now that all other registers are set with correct - * values. - */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); - } else { - /* Write key[47:0] */ - REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); - REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); - - /* Write key[95:48] */ - REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); - REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); - - /* Write key[127:96] and key type */ - REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); - REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); - - /* Write MAC address for the entry */ - (void) ath9k_hw_keysetmac(ah, entry, mac); - } - - return true; -} -EXPORT_SYMBOL(ath9k_hw_set_keycache_entry); - /******************************/ /* Power Management (Chipset) */ /******************************/ @@ -1959,7 +1676,6 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); beacon_period &= ~ATH9K_BEACON_ENA; if (beacon_period & ATH9K_BEACON_RESET_TSF) { @@ -1987,7 +1703,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); @@ -2033,7 +1748,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); REG_SET_BIT(ah, AR_TIMER_MODE, AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | @@ -2056,12 +1770,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; u16 capField = 0, eeval; + u8 ant_div_ctl1; eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); regulatory->current_rd = eeval; eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1); - if (AR_SREV_9285_10_OR_LATER(ah)) + if (AR_SREV_9285_12_OR_LATER(ah)) eeval |= AR9285_RDEXT_DEFAULT; regulatory->current_rd_ext = eeval; @@ -2085,37 +1800,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) return -EINVAL; } - bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX); + if (eeval & AR5416_OPFLAGS_11A) + pCap->hw_caps |= ATH9K_HW_CAP_5GHZ; - if (eeval & AR5416_OPFLAGS_11A) { - set_bit(ATH9K_MODE_11A, pCap->wireless_modes); - if (ah->config.ht_enable) { - if (!(eeval & AR5416_OPFLAGS_N_5G_HT20)) - set_bit(ATH9K_MODE_11NA_HT20, - pCap->wireless_modes); - if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) { - set_bit(ATH9K_MODE_11NA_HT40PLUS, - pCap->wireless_modes); - set_bit(ATH9K_MODE_11NA_HT40MINUS, - pCap->wireless_modes); - } - } - } - - if (eeval & AR5416_OPFLAGS_11G) { - set_bit(ATH9K_MODE_11G, pCap->wireless_modes); - if (ah->config.ht_enable) { - if (!(eeval & AR5416_OPFLAGS_N_2G_HT20)) - set_bit(ATH9K_MODE_11NG_HT20, - pCap->wireless_modes); - if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) { - set_bit(ATH9K_MODE_11NG_HT40PLUS, - pCap->wireless_modes); - set_bit(ATH9K_MODE_11NG_HT40MINUS, - pCap->wireless_modes); - } - } - } + if (eeval & AR5416_OPFLAGS_11G) + pCap->hw_caps |= ATH9K_HW_CAP_2GHZ; pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); /* @@ -2131,8 +1820,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) /* Use rx_chainmask from EEPROM. */ pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); - if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0))) - ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA; + ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA; pCap->low_2ghz_chan = 2312; pCap->high_2ghz_chan = 2732; @@ -2140,24 +1828,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->low_5ghz_chan = 4920; pCap->high_5ghz_chan = 6100; - pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP; - pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP; - pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM; - - pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP; - pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP; - pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM; + common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM; if (ah->config.ht_enable) pCap->hw_caps |= ATH9K_HW_CAP_HT; else pCap->hw_caps &= ~ATH9K_HW_CAP_HT; - pCap->hw_caps |= ATH9K_HW_CAP_GTT; - pCap->hw_caps |= ATH9K_HW_CAP_VEOL; - pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK; - pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH; - if (capField & AR_EEPROM_EEPCAP_MAXQCU) pCap->total_queues = MS(capField, AR_EEPROM_EEPCAP_MAXQCU); @@ -2170,8 +1847,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) else pCap->keycache_size = AR_KEYTABLE_SIZE; - pCap->hw_caps |= ATH9K_HW_CAP_FASTCC; - if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1; else @@ -2181,9 +1856,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->num_gpio_pins = AR9271_NUM_GPIO; else if (AR_DEVID_7010(ah)) pCap->num_gpio_pins = AR7010_NUM_GPIO; - else if (AR_SREV_9285_10_OR_LATER(ah)) + else if (AR_SREV_9285_12_OR_LATER(ah)) pCap->num_gpio_pins = AR9285_NUM_GPIO; - else if (AR_SREV_9280_10_OR_LATER(ah)) + else if (AR_SREV_9280_20_OR_LATER(ah)) pCap->num_gpio_pins = AR928X_NUM_GPIO; else pCap->num_gpio_pins = AR_NUM_GPIO; @@ -2240,7 +1915,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->num_antcfg_2ghz = ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ); - if (AR_SREV_9280_10_OR_LATER(ah) && + if (AR_SREV_9280_20_OR_LATER(ah) && ath9k_hw_btcoex_supported(ah)) { btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; @@ -2277,9 +1952,17 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9300_20_OR_LATER(ah)) pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; - if (AR_SREV_9287_10_OR_LATER(ah) || AR_SREV_9271(ah)) + if (AR_SREV_9287_11_OR_LATER(ah) || AR_SREV_9271(ah)) pCap->hw_caps |= ATH9K_HW_CAP_SGI_20; + if (AR_SREV_9285(ah)) + if (ah->eep_ops->get_eeprom(ah, EEP_MODAL_VER) >= 3) { + ant_div_ctl1 = + ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); + if ((ant_div_ctl1 & 0x1) && ((ant_div_ctl1 >> 3) & 0x1)) + pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; + } + return 0; } @@ -2353,11 +2036,11 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) return MS_REG_READ(AR9300, gpio) != 0; else if (AR_SREV_9271(ah)) return MS_REG_READ(AR9271, gpio) != 0; - else if (AR_SREV_9287_10_OR_LATER(ah)) + else if (AR_SREV_9287_11_OR_LATER(ah)) return MS_REG_READ(AR9287, gpio) != 0; - else if (AR_SREV_9285_10_OR_LATER(ah)) + else if (AR_SREV_9285_12_OR_LATER(ah)) return MS_REG_READ(AR9285, gpio) != 0; - else if (AR_SREV_9280_10_OR_LATER(ah)) + else if (AR_SREV_9280_20_OR_LATER(ah)) return MS_REG_READ(AR928X, gpio) != 0; else return MS_REG_READ(AR, gpio) != 0; @@ -2456,7 +2139,6 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } EXPORT_SYMBOL(ath9k_hw_setrxfilter); @@ -2854,7 +2536,7 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len) int used; /* chipsets >= AR9280 are single-chip */ - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { used = snprintf(hw_name, len, "Atheros AR%s Rev:%x", ath9k_hw_mac_bb_name(ah->hw_version.macVersion), diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 399f7c1283cdf32ba4cdb5eef198c4cd2ed085bd..d032939768b073aa80e672641f805ac416e1ce22 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -61,6 +61,8 @@ #define ATH9K_RSSI_BAD -128 +#define ATH9K_NUM_CHANNELS 38 + /* Register read/write primitives */ #define REG_WRITE(_ah, _reg, _val) \ ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg)) @@ -70,19 +72,13 @@ #define ENABLE_REGWRITE_BUFFER(_ah) \ do { \ - if (AR_SREV_9271(_ah)) \ + if (ath9k_hw_common(_ah)->ops->enable_write_buffer) \ ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \ } while (0) -#define DISABLE_REGWRITE_BUFFER(_ah) \ - do { \ - if (AR_SREV_9271(_ah)) \ - ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \ - } while (0) - #define REGWRITE_BUFFER_FLUSH(_ah) \ do { \ - if (AR_SREV_9271(_ah)) \ + if (ath9k_hw_common(_ah)->ops->write_flush) \ ath9k_hw_common(_ah)->ops->write_flush((_ah)); \ } while (0) @@ -168,47 +164,26 @@ enum ath_ini_subsys { ATH_INI_NUM_SPLIT, }; -enum wireless_mode { - ATH9K_MODE_11A = 0, - ATH9K_MODE_11G, - ATH9K_MODE_11NA_HT20, - ATH9K_MODE_11NG_HT20, - ATH9K_MODE_11NA_HT40PLUS, - ATH9K_MODE_11NA_HT40MINUS, - ATH9K_MODE_11NG_HT40PLUS, - ATH9K_MODE_11NG_HT40MINUS, - ATH9K_MODE_MAX, -}; - enum ath9k_hw_caps { - ATH9K_HW_CAP_MIC_AESCCM = BIT(0), - ATH9K_HW_CAP_MIC_CKIP = BIT(1), - ATH9K_HW_CAP_MIC_TKIP = BIT(2), - ATH9K_HW_CAP_CIPHER_AESCCM = BIT(3), - ATH9K_HW_CAP_CIPHER_CKIP = BIT(4), - ATH9K_HW_CAP_CIPHER_TKIP = BIT(5), - ATH9K_HW_CAP_VEOL = BIT(6), - ATH9K_HW_CAP_BSSIDMASK = BIT(7), - ATH9K_HW_CAP_MCAST_KEYSEARCH = BIT(8), - ATH9K_HW_CAP_HT = BIT(9), - ATH9K_HW_CAP_GTT = BIT(10), - ATH9K_HW_CAP_FASTCC = BIT(11), - ATH9K_HW_CAP_RFSILENT = BIT(12), - ATH9K_HW_CAP_CST = BIT(13), - ATH9K_HW_CAP_ENHANCEDPM = BIT(14), - ATH9K_HW_CAP_AUTOSLEEP = BIT(15), - ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16), - ATH9K_HW_CAP_EDMA = BIT(17), - ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18), - ATH9K_HW_CAP_LDPC = BIT(19), - ATH9K_HW_CAP_FASTCLOCK = BIT(20), - ATH9K_HW_CAP_SGI_20 = BIT(21), - ATH9K_HW_CAP_PAPRD = BIT(22), + ATH9K_HW_CAP_HT = BIT(0), + ATH9K_HW_CAP_RFSILENT = BIT(1), + ATH9K_HW_CAP_CST = BIT(2), + ATH9K_HW_CAP_ENHANCEDPM = BIT(3), + ATH9K_HW_CAP_AUTOSLEEP = BIT(4), + ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(5), + ATH9K_HW_CAP_EDMA = BIT(6), + ATH9K_HW_CAP_RAC_SUPPORTED = BIT(7), + ATH9K_HW_CAP_LDPC = BIT(8), + ATH9K_HW_CAP_FASTCLOCK = BIT(9), + ATH9K_HW_CAP_SGI_20 = BIT(10), + ATH9K_HW_CAP_PAPRD = BIT(11), + ATH9K_HW_CAP_ANT_DIV_COMB = BIT(12), + ATH9K_HW_CAP_2GHZ = BIT(13), + ATH9K_HW_CAP_5GHZ = BIT(14), }; struct ath9k_hw_capabilities { u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ - DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */ u16 total_queues; u16 keycache_size; u16 low_5ghz_chan, high_5ghz_chan; @@ -352,9 +327,9 @@ struct ath9k_hw_cal_data { int32_t CalValid; int8_t iCoff; int8_t qCoff; - int16_t rawNoiseFloor; bool paprd_done; bool nfcal_pending; + bool nfcal_interference; u16 small_signal_gain[AR9300_MAX_CHAINS]; u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; @@ -362,9 +337,11 @@ struct ath9k_hw_cal_data { struct ath9k_channel { struct ieee80211_channel *chan; + struct ar5416AniState ani; u16 channel; u32 channelFlags; u32 chanmode; + s16 noisefloor; }; #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ @@ -494,6 +471,12 @@ struct ath_gen_timer_table { } timer_mask; }; +struct ath_hw_antcomb_conf { + u8 main_lna_conf; + u8 alt_lna_conf; + u8 fast_div_bias; +}; + /** * struct ath_hw_private_ops - callbacks used internally by hardware code * @@ -517,14 +500,6 @@ struct ath_gen_timer_table { * @setup_calibration: set up calibration * @iscal_supported: used to query if a type of calibration is supported * - * @ani_reset: reset ANI parameters to default values - * @ani_lower_immunity: lower the noise immunity level. The level controls - * the power-based packet detection on hardware. If a power jump is - * detected the adapter takes it as an indication that a packet has - * arrived. The level ranges from 0-5. Each level corresponds to a - * few dB more of noise immunity. If you have a strong time-varying - * interference that is causing false detections (OFDM timing errors or - * CCK timing errors) the level can be increased. * @ani_cache_ini_regs: cache the values for ANI from the initial * register settings through the register initialization. */ @@ -538,8 +513,6 @@ struct ath_hw_private_ops { bool (*macversion_supported)(u32 macversion); void (*setup_calibration)(struct ath_hw *ah, struct ath9k_cal_list *currCal); - bool (*iscal_supported)(struct ath_hw *ah, - enum ath9k_cal_types calType); /* PHY ops */ int (*rf_set_freq)(struct ath_hw *ah, @@ -571,8 +544,6 @@ struct ath_hw_private_ops { void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); /* ANI */ - void (*ani_reset)(struct ath_hw *ah, bool is_scanning); - void (*ani_lower_immunity)(struct ath_hw *ah); void (*ani_cache_ini_regs)(struct ath_hw *ah); }; @@ -584,11 +555,6 @@ struct ath_hw_private_ops { * * @config_pci_powersave: * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC - * - * @ani_proc_mib_event: process MIB events, this would happen upon specific ANI - * thresholds being reached or having overflowed. - * @ani_monitor: called periodically by the core driver to collect - * MIB stats and adjust ANI if specific thresholds have been reached. */ struct ath_hw_ops { void (*config_pci_powersave)(struct ath_hw *ah, @@ -629,9 +595,6 @@ struct ath_hw_ops { u32 burstDuration); void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, u32 vmf); - - void (*ani_proc_mib_event)(struct ath_hw *ah); - void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan); }; struct ath_nf_limits { @@ -646,7 +609,7 @@ struct ath_hw { struct ath9k_hw_version hw_version; struct ath9k_ops_config config; struct ath9k_hw_capabilities caps; - struct ath9k_channel channels[38]; + struct ath9k_channel channels[ATH9K_NUM_CHANNELS]; struct ath9k_channel *curchan; union { @@ -692,10 +655,9 @@ struct ath_hw { u32 atim_window; /* Calibration */ - enum ath9k_cal_types supp_cals; + u32 supp_cals; struct ath9k_cal_list iq_caldata; struct ath9k_cal_list adcgain_caldata; - struct ath9k_cal_list adcdc_calinitdata; struct ath9k_cal_list adcdc_caldata; struct ath9k_cal_list tempCompCalData; struct ath9k_cal_list *cal_list; @@ -764,8 +726,6 @@ struct ath_hw { /* ANI */ u32 proc_phyerr; u32 aniperiod; - struct ar5416AniState *curani; - struct ar5416AniState ani[255]; int totalSizeDesired[5]; int coarse_high[5]; int coarse_low[5]; @@ -873,12 +833,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, int ath9k_hw_fill_cap_info(struct ath_hw *ah); u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); -/* Key Cache Management */ -bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); -bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry, - const struct ath9k_keyval *k, - const u8 *mac); - /* GPIO / RFKILL / Antennae */ void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio); u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio); @@ -887,6 +841,10 @@ void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio, void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val); u32 ath9k_hw_getdefantenna(struct ath_hw *ah); void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna); +void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf); +void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, + struct ath_hw_antcomb_conf *antconf); /* General Operation */ bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); @@ -984,6 +942,7 @@ void ar9003_hw_attach_calib_ops(struct ath_hw *ah); void ar9002_hw_attach_ops(struct ath_hw *ah); void ar9003_hw_attach_ops(struct ath_hw *ah); +void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); /* * ANI work can be shared between all families but a next * generation implementation of ANI will be used only for AR9003 only @@ -992,8 +951,9 @@ void ar9003_hw_attach_ops(struct ath_hw *ah); * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani. */ extern int modparam_force_new_ani; -void ath9k_hw_attach_ani_ops_old(struct ath_hw *ah); -void ath9k_hw_attach_ani_ops_new(struct ath_hw *ah); +void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); +void ath9k_hw_proc_mib_event(struct ath_hw *ah); +void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); #define ATH_PCIE_CAP_LINK_CTRL 0x70 #define ATH_PCIE_CAP_LINK_L0S 1 diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 243c1775f343f0b3400b0675708ee292bcb54e74..bc6c4df9712c5b921041fdc7d1f49a1214a5a091 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -33,7 +33,7 @@ int modparam_nohwcrypt; module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); -int led_blink = 1; +int led_blink; module_param_named(blink, led_blink, int, 0444); MODULE_PARM_DESC(blink, "Enable LED blink on activity"); @@ -56,7 +56,7 @@ MODULE_PARM_DESC(blink, "Enable LED blink on activity"); * on 5 MHz steps, we support the channels which we know * we have calibration data for all cards though to make * this static */ -static struct ieee80211_channel ath9k_2ghz_chantable[] = { +static const struct ieee80211_channel ath9k_2ghz_chantable[] = { CHAN2G(2412, 0), /* Channel 1 */ CHAN2G(2417, 1), /* Channel 2 */ CHAN2G(2422, 2), /* Channel 3 */ @@ -77,7 +77,7 @@ static struct ieee80211_channel ath9k_2ghz_chantable[] = { * on 5 MHz steps, we support the channels which we know * we have calibration data for all cards though to make * this static */ -static struct ieee80211_channel ath9k_5ghz_chantable[] = { +static const struct ieee80211_channel ath9k_5ghz_chantable[] = { /* _We_ call this UNII 1 */ CHAN5G(5180, 14), /* Channel 36 */ CHAN5G(5200, 15), /* Channel 40 */ @@ -211,7 +211,7 @@ static void setup_ht_cap(struct ath_softc *sc, else max_streams = 2; - if (AR_SREV_9280_10_OR_LATER(ah)) { + if (AR_SREV_9280_20_OR_LATER(ah)) { if (max_streams >= 2) ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); @@ -381,7 +381,7 @@ static void ath9k_init_crypto(struct ath_softc *sc) * reset the contents on initial power up. */ for (i = 0; i < common->keymax; i++) - ath9k_hw_keyreset(sc->sc_ah, (u16) i); + ath_hw_keyreset(common, (u16) i); /* * Check whether the separate key cache entries @@ -389,8 +389,8 @@ static void ath9k_init_crypto(struct ath_softc *sc) * With split mic keys the number of stations is limited * to 27 otherwise 59. */ - if (!(sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)) - common->splitmic = 1; + if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) + common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED; } static int ath9k_init_btcoex(struct ath_softc *sc) @@ -477,10 +477,21 @@ static int ath9k_init_queues(struct ath_softc *sc) return -EIO; } -static void ath9k_init_channels_rates(struct ath_softc *sc) +static int ath9k_init_channels_rates(struct ath_softc *sc) { - if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) { - sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable; + void *channels; + + BUILD_BUG_ON(ARRAY_SIZE(ath9k_2ghz_chantable) + + ARRAY_SIZE(ath9k_5ghz_chantable) != + ATH9K_NUM_CHANNELS); + + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) { + channels = kmemdup(ath9k_2ghz_chantable, + sizeof(ath9k_2ghz_chantable), GFP_KERNEL); + if (!channels) + return -ENOMEM; + + sc->sbands[IEEE80211_BAND_2GHZ].channels = channels; sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; sc->sbands[IEEE80211_BAND_2GHZ].n_channels = ARRAY_SIZE(ath9k_2ghz_chantable); @@ -489,8 +500,16 @@ static void ath9k_init_channels_rates(struct ath_softc *sc) ARRAY_SIZE(ath9k_legacy_rates); } - if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) { - sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable; + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) { + channels = kmemdup(ath9k_5ghz_chantable, + sizeof(ath9k_5ghz_chantable), GFP_KERNEL); + if (!channels) { + if (sc->sbands[IEEE80211_BAND_2GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); + return -ENOMEM; + } + + sc->sbands[IEEE80211_BAND_5GHZ].channels = channels; sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; sc->sbands[IEEE80211_BAND_5GHZ].n_channels = ARRAY_SIZE(ath9k_5ghz_chantable); @@ -499,6 +518,7 @@ static void ath9k_init_channels_rates(struct ath_softc *sc) sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates = ARRAY_SIZE(ath9k_legacy_rates) - 4; } + return 0; } static void ath9k_init_misc(struct ath_softc *sc) @@ -506,7 +526,6 @@ static void ath9k_init_misc(struct ath_softc *sc) struct ath_common *common = ath9k_hw_common(sc->sc_ah); int i = 0; - common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR; setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); sc->config.txpowlimit = ATH_TXPOWER_MAX; @@ -522,8 +541,7 @@ static void ath9k_init_misc(struct ath_softc *sc) ath9k_hw_set_diversity(sc->sc_ah, true); sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); + memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); sc->beacon.slottime = ATH9K_SLOT_TIME_9; @@ -531,6 +549,9 @@ static void ath9k_init_misc(struct ath_softc *sc) sc->beacon.bslot[i] = NULL; sc->beacon.bslot_aphy[i] = NULL; } + + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) + sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT; } static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, @@ -593,8 +614,11 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, if (ret) goto err_btcoex; + ret = ath9k_init_channels_rates(sc); + if (ret) + goto err_btcoex; + ath9k_init_crypto(sc); - ath9k_init_channels_rates(sc); ath9k_init_misc(sc); return 0; @@ -637,11 +661,13 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_WDS) | BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); - hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + if (AR_SREV_5416(sc->sc_ah)) + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; hw->queues = 4; hw->max_rates = 4; @@ -651,19 +677,21 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vif); +#ifdef CONFIG_ATH9K_RATE_CONTROL hw->rate_control_algorithm = "ath9k_rate_control"; +#endif - if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &sc->sbands[IEEE80211_BAND_2GHZ]; - if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &sc->sbands[IEEE80211_BAND_5GHZ]; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap); - if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap); } @@ -751,6 +779,12 @@ static void ath9k_deinit_softc(struct ath_softc *sc) { int i = 0; + if (sc->sbands[IEEE80211_BAND_2GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_2GHZ].channels); + + if (sc->sbands[IEEE80211_BAND_5GHZ].channels) + kfree(sc->sbands[IEEE80211_BAND_5GHZ].channels); + if ((sc->btcoex.no_stomp_timer) && sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer); diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e955bb9d98cbe0380ef5d070005b373c1a132b8d..8c13479b17cd9d418f7d7f496b01dbf7445ba202 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -40,7 +40,6 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); } u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) @@ -492,8 +491,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) REG_WRITE(ah, AR_DMISC(q), AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); - REGWRITE_BUFFER_FLUSH(ah); - if (qi->tqi_cbrPeriod) { REG_WRITE(ah, AR_QCBRCFG(q), SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | @@ -509,8 +506,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) AR_Q_RDYTIMECFG_EN); } - REGWRITE_BUFFER_FLUSH(ah); - REG_WRITE(ah, AR_DCHNTIME(q), SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); @@ -530,7 +525,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) } REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { REG_WRITE(ah, AR_DMISC(q), @@ -553,7 +547,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | AR_D_MISC_POST_FR_BKOFF_DIS); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); /* * cwmin and cwmax should be 0 for beacon queue @@ -585,7 +578,6 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); REGWRITE_BUFFER_FLUSH(ah); - DISABLE_REGWRITE_BUFFER(ah); break; case ATH9K_TX_QUEUE_PSPOLL: @@ -711,8 +703,11 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_phyerr = phyerr; } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; - else if (ads.ds_rxstatus8 & AR_MichaelErr) + else if ((ads.ds_rxstatus8 & AR_MichaelErr) && + rs->rs_keyix != ATH9K_RXKEYIX_INVALID) rs->rs_status |= ATH9K_RXERR_MIC; + else if (ads.ds_rxstatus8 & AR_KeyMiss) + rs->rs_status |= ATH9K_RXERR_DECRYPT; } return 0; diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 2633896d39983499f931b576db97bfdbe5da2e31..7c1a34d64f6debb70b23cd1c1cfe387fdb17868d 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -660,17 +660,6 @@ struct ath9k_11n_rate_series { u32 RateFlags; }; -struct ath9k_keyval { - u8 kv_type; - u8 kv_pad; - u16 kv_len; - u8 kv_val[16]; /* TK */ - u8 kv_mic[8]; /* Michael MIC key */ - u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware - * supports both MIC keys in the same key cache entry; - * in that case, kv_mic is the RX key) */ -}; - enum ath9k_key_type { ATH9K_KEY_TYPE_CLEAR, ATH9K_KEY_TYPE_WEP, @@ -678,16 +667,6 @@ enum ath9k_key_type { ATH9K_KEY_TYPE_TKIP, }; -enum ath9k_cipher { - ATH9K_CIPHER_WEP = 0, - ATH9K_CIPHER_AES_OCB = 1, - ATH9K_CIPHER_AES_CCM = 2, - ATH9K_CIPHER_CKIP = 3, - ATH9K_CIPHER_TKIP = 4, - ATH9K_CIPHER_CLR = 5, - ATH9K_CIPHER_MIC = 127 -}; - struct ath_hw; struct ath9k_channel; diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 3caa32316e7b4567c5cbb7372aef8330b8d2a747..3ff0e476c2b3d7ad4cc209360042c6c5097d87a8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -18,36 +18,6 @@ #include "ath9k.h" #include "btcoex.h" -static void ath_cache_conf_rate(struct ath_softc *sc, - struct ieee80211_conf *conf) -{ - switch (conf->channel->band) { - case IEEE80211_BAND_2GHZ: - if (conf_is_ht20(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NG_HT20; - else if (conf_is_ht40_minus(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NG_HT40MINUS; - else if (conf_is_ht40_plus(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NG_HT40PLUS; - else - sc->cur_rate_mode = ATH9K_MODE_11G; - break; - case IEEE80211_BAND_5GHZ: - if (conf_is_ht20(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NA_HT20; - else if (conf_is_ht40_minus(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NA_HT40MINUS; - else if (conf_is_ht40_plus(conf)) - sc->cur_rate_mode = ATH9K_MODE_11NA_HT40PLUS; - else - sc->cur_rate_mode = ATH9K_MODE_11A; - break; - default: - BUG_ON(1); - break; - } -} - static void ath_update_txpow(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; @@ -121,6 +91,7 @@ bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) void ath9k_ps_wakeup(struct ath_softc *sc) { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); unsigned long flags; spin_lock_irqsave(&sc->sc_pm_lock, flags); @@ -129,18 +100,33 @@ void ath9k_ps_wakeup(struct ath_softc *sc) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); + /* + * While the hardware is asleep, the cycle counters contain no + * useful data. Better clear them now so that they don't mess up + * survey data results. + */ + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + memset(&common->cc_survey, 0, sizeof(common->cc_survey)); + spin_unlock(&common->cc_lock); + unlock: spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } void ath9k_ps_restore(struct ath_softc *sc) { + struct ath_common *common = ath9k_hw_common(sc->sc_ah); unsigned long flags; spin_lock_irqsave(&sc->sc_pm_lock, flags); if (--sc->ps_usecount != 0) goto unlock; + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); + spin_unlock(&common->cc_lock); + if (sc->ps_idle) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); else if (sc->ps_enabled && @@ -175,6 +161,45 @@ static void ath_start_ani(struct ath_common *common) msecs_to_jiffies((u32)ah->config.ani_poll_interval)); } +static void ath_update_survey_nf(struct ath_softc *sc, int channel) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath9k_channel *chan = &ah->channels[channel]; + struct survey_info *survey = &sc->survey[channel]; + + if (chan->noisefloor) { + survey->filled |= SURVEY_INFO_NOISE_DBM; + survey->noise = chan->noisefloor; + } +} + +static void ath_update_survey_stats(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + int pos = ah->curchan - &ah->channels[0]; + struct survey_info *survey = &sc->survey[pos]; + struct ath_cycle_counters *cc = &common->cc_survey; + unsigned int div = common->clockrate * 1000; + + if (ah->power_mode == ATH9K_PM_AWAKE) + ath_hw_cycle_counters_update(common); + + if (cc->cycles > 0) { + survey->filled |= SURVEY_INFO_CHANNEL_TIME | + SURVEY_INFO_CHANNEL_TIME_BUSY | + SURVEY_INFO_CHANNEL_TIME_RX | + SURVEY_INFO_CHANNEL_TIME_TX; + survey->channel_time += cc->cycles / div; + survey->channel_time_busy += cc->rx_busy / div; + survey->channel_time_rx += cc->rx_frame / div; + survey->channel_time_tx += cc->tx_frame / div; + } + memset(cc, 0, sizeof(*cc)); + + ath_update_survey_nf(sc, pos); +} + /* * Set/change channels. If the channel is really being changed, it's done * by reseting the chip. To accomplish this we must first cleanup any pending @@ -226,9 +251,10 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, caldata = &aphy->caldata; ath_print(common, ATH_DBG_CONFIG, - "(%u MHz) -> (%u MHz), conf_is_ht40: %d\n", + "(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n", sc->sc_ah->curchan->channel, - channel->center_freq, conf_is_ht40(conf)); + channel->center_freq, conf_is_ht40(conf), + fastcc); spin_lock_bh(&sc->sc_resetlock); @@ -250,14 +276,13 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, goto ps_restore; } - ath_cache_conf_rate(sc, &hw->conf); ath_update_txpow(sc); ath9k_hw_set_interrupts(ah, ah->imask); - if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) { - ath_start_ani(common); - ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); + if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) { ath_beacon_config(sc, NULL); + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); + ath_start_ani(common); } ps_restore: @@ -269,6 +294,7 @@ static void ath_paprd_activate(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; struct ath9k_hw_cal_data *caldata = ah->caldata; + struct ath_common *common = ath9k_hw_common(ah); int chain; if (!caldata || !caldata->paprd_done) @@ -277,7 +303,7 @@ static void ath_paprd_activate(struct ath_softc *sc) ath9k_ps_wakeup(sc); ar9003_paprd_enable(ah, false); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->caps.tx_chainmask & BIT(chain))) + if (!(common->tx_chainmask & BIT(chain))) continue; ar9003_paprd_populate_single_table(ah, caldata, chain); @@ -299,6 +325,7 @@ void ath_paprd_calibrate(struct work_struct *work) struct ieee80211_supported_band *sband = &sc->sbands[band]; struct ath_tx_control txctl; struct ath9k_hw_cal_data *caldata = ah->caldata; + struct ath_common *common = ath9k_hw_common(ah); int qnum, ftype; int chain_ok = 0; int chain; @@ -332,7 +359,7 @@ void ath_paprd_calibrate(struct work_struct *work) ath9k_ps_wakeup(sc); ar9003_paprd_init_table(ah); for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { - if (!(ah->caps.tx_chainmask & BIT(chain))) + if (!(common->tx_chainmask & BIT(chain))) continue; chain_ok = 0; @@ -395,7 +422,13 @@ void ath_ani_calibrate(unsigned long data) bool shortcal = false; bool aniflag = false; unsigned int timestamp = jiffies_to_msecs(jiffies); - u32 cal_interval, short_cal_interval; + u32 cal_interval, short_cal_interval, long_cal_interval; + unsigned long flags; + + if (ah->caldata && ah->caldata->nfcal_interference) + long_cal_interval = ATH_LONG_CALINTERVAL_INT; + else + long_cal_interval = ATH_LONG_CALINTERVAL; short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ? ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL; @@ -407,7 +440,7 @@ void ath_ani_calibrate(unsigned long data) ath9k_ps_wakeup(sc); /* Long calibration runs independently of short calibration. */ - if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { + if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) { longcal = true; ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); common->ani.longcal_timer = timestamp; @@ -441,8 +474,12 @@ void ath_ani_calibrate(unsigned long data) /* Skip all processing if there's nothing to do. */ if (longcal || shortcal || aniflag) { /* Call ANI routine if necessary */ - if (aniflag) + if (aniflag) { + spin_lock_irqsave(&common->cc_lock, flags); ath9k_hw_ani_monitor(ah, ah->curchan); + ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); + } /* Perform calibration if necessary */ if (longcal || shortcal) { @@ -451,16 +488,6 @@ void ath_ani_calibrate(unsigned long data) ah->curchan, common->rx_chainmask, longcal); - - if (longcal) - common->ani.noise_floor = ath9k_hw_getchan_noise(ah, - ah->curchan); - - ath_print(common, ATH_DBG_ANI, - " calibrate chan %u/%x nf: %d\n", - ah->curchan->channel, - ah->curchan->channelFlags, - common->ani.noise_floor); } } @@ -637,6 +664,7 @@ irqreturn_t ath_isr(int irq, void *dev) struct ath_softc *sc = dev; struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); enum ath9k_int status; bool sched = false; @@ -686,7 +714,12 @@ irqreturn_t ath_isr(int irq, void *dev) if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && (status & ATH9K_INT_BB_WATCHDOG)) { + + spin_lock(&common->cc_lock); + ath_hw_cycle_counters_update(common); ar9003_hw_bb_watchdog_dbg_info(ah); + spin_unlock(&common->cc_lock); + goto chip_reset; } @@ -715,7 +748,9 @@ irqreturn_t ath_isr(int irq, void *dev) * it will clear whatever condition caused * the interrupt. */ - ath9k_hw_procmibevent(ah); + spin_lock(&common->cc_lock); + ath9k_hw_proc_mib_event(ah); + spin_unlock(&common->cc_lock); ath9k_hw_set_interrupts(ah, ah->imask); } @@ -947,11 +982,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) * that changes the channel so update any state that * might change as a result. */ - ath_cache_conf_rate(sc, &hw->conf); - ath_update_txpow(sc); - if (sc->sc_flags & SC_OP_BEACONS) + if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL))) ath_beacon_config(sc, NULL); /* restart beacons */ ath9k_hw_set_interrupts(ah, ah->imask); @@ -1150,14 +1183,11 @@ static int ath9k_start(struct ieee80211_hw *hw) else ah->imask |= ATH9K_INT_RX; - if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) - ah->imask |= ATH9K_INT_GTT; + ah->imask |= ATH9K_INT_GTT; if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) ah->imask |= ATH9K_INT_CST; - ath_cache_conf_rate(sc, &hw->conf); - sc->sc_flags &= ~SC_OP_INVALID; /* Disable BMISS interrupt when we're not associated */ @@ -1373,16 +1403,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); - if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) && - sc->nvifs > 0) { - ret = -ENOBUFS; - goto out; - } - switch (vif->type) { case NL80211_IFTYPE_STATION: ic_opmode = NL80211_IFTYPE_STATION; break; + case NL80211_IFTYPE_WDS: + ic_opmode = NL80211_IFTYPE_WDS; + break; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_MESH_POINT: @@ -1408,8 +1435,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, sc->nvifs++; - if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath9k_set_bssid_mask(hw); + ath9k_set_bssid_mask(hw, vif); if (sc->nvifs > 1) goto out; /* skip global settings for secondary vif */ @@ -1491,7 +1517,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&sc->mutex); } -void ath9k_enable_ps(struct ath_softc *sc) +static void ath9k_enable_ps(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; @@ -1505,13 +1531,33 @@ void ath9k_enable_ps(struct ath_softc *sc) } } +static void ath9k_disable_ps(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + + sc->ps_enabled = false; + ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); + if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { + ath9k_hw_setrxabort(ah, 0); + sc->ps_flags &= ~(PS_WAIT_FOR_BEACON | + PS_WAIT_FOR_CAB | + PS_WAIT_FOR_PSPOLL_DATA | + PS_WAIT_FOR_TX_ACK); + if (ah->imask & ATH9K_INT_TIM_TIMER) { + ah->imask &= ~ATH9K_INT_TIM_TIMER; + ath9k_hw_set_interrupts(ah, ah->imask); + } + } + +} + static int ath9k_config(struct ieee80211_hw *hw, u32 changed) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ieee80211_conf *conf = &hw->conf; struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_conf *conf = &hw->conf; bool disable_radio; mutex_lock(&sc->mutex); @@ -1556,35 +1602,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) * IEEE80211_CONF_CHANGE_PS is only passed by mac80211 for STA mode. */ if (changed & IEEE80211_CONF_CHANGE_PS) { - if (conf->flags & IEEE80211_CONF_PS) { - sc->ps_flags |= PS_ENABLED; - /* - * At this point we know hardware has received an ACK - * of a previously sent null data frame. - */ - if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) { - sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; - ath9k_enable_ps(sc); - } - } else { - sc->ps_enabled = false; - sc->ps_flags &= ~(PS_ENABLED | - PS_NULLFUNC_COMPLETED); - ath9k_setpower(sc, ATH9K_PM_AWAKE); - if (!(ah->caps.hw_caps & - ATH9K_HW_CAP_AUTOSLEEP)) { - ath9k_hw_setrxabort(sc->sc_ah, 0); - sc->ps_flags &= ~(PS_WAIT_FOR_BEACON | - PS_WAIT_FOR_CAB | - PS_WAIT_FOR_PSPOLL_DATA | - PS_WAIT_FOR_TX_ACK); - if (ah->imask & ATH9K_INT_TIM_TIMER) { - ah->imask &= ~ATH9K_INT_TIM_TIMER; - ath9k_hw_set_interrupts(sc->sc_ah, - ah->imask); - } - } - } + unsigned long flags; + spin_lock_irqsave(&sc->sc_pm_lock, flags); + if (conf->flags & IEEE80211_CONF_PS) + ath9k_enable_ps(sc); + else + ath9k_disable_ps(sc); + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) { @@ -1598,6 +1622,11 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; + int old_pos = -1; + unsigned long flags; + + if (ah->curchan) + old_pos = ah->curchan - &ah->channels[0]; aphy->chan_idx = pos; aphy->chan_is_ht = conf_is_ht(conf); @@ -1625,12 +1654,45 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ath_update_chainmask(sc, conf_is_ht(conf)); + /* update survey stats for the old channel before switching */ + spin_lock_irqsave(&common->cc_lock, flags); + ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); + + /* + * If the operating channel changes, change the survey in-use flags + * along with it. + * Reset the survey data for the new channel, unless we're switching + * back to the operating channel from an off-channel operation. + */ + if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && + sc->cur_survey != &sc->survey[pos]) { + + if (sc->cur_survey) + sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE; + + sc->cur_survey = &sc->survey[pos]; + + memset(sc->cur_survey, 0, sizeof(struct survey_info)); + sc->cur_survey->filled |= SURVEY_INFO_IN_USE; + } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) { + memset(&sc->survey[pos], 0, sizeof(struct survey_info)); + } + if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { ath_print(common, ATH_DBG_FATAL, "Unable to set channel\n"); mutex_unlock(&sc->mutex); return -EINVAL; } + + /* + * The most recent snapshot of channel->noisefloor for the old + * channel is only available after the hardware reset. Copy it to + * the survey stats now. + */ + if (old_pos >= 0) + ath_update_survey_nf(sc, old_pos); } skip_chan_change: @@ -1661,6 +1723,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) FIF_PSPOLL | \ FIF_OTHER_BSS | \ FIF_BCN_PRBRESP_PROMISC | \ + FIF_PROBE_REQ | \ FIF_FCSFAIL) /* FIXME: sc->sc_full_reset ? */ @@ -1771,20 +1834,21 @@ static int ath9k_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: - ret = ath9k_cmn_key_config(common, vif, sta, key); + ret = ath_key_config(common, vif, sta, key); if (ret >= 0) { key->hw_key_idx = ret; /* push IV and Michael MIC generation to stack */ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - if (key->alg == ALG_TKIP) + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP) + if (sc->sc_ah->sw_mgmt_crypto && + key->cipher == WLAN_CIPHER_SUITE_CCMP) key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; ret = 0; } break; case DISABLE_KEY: - ath9k_cmn_key_delete(common, key); + ath_key_delete(common, key); break; default: ret = -EINVAL; @@ -1968,8 +2032,9 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, break; case IEEE80211_AMPDU_TX_START: ath9k_ps_wakeup(sc); - ath_tx_aggr_start(sc, sta, tid, ssn); - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ret = ath_tx_aggr_start(sc, sta, tid, ssn); + if (!ret) + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); ath9k_ps_restore(sc); break; case IEEE80211_AMPDU_TX_STOP: @@ -1998,16 +2063,35 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_conf *conf = &hw->conf; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ieee80211_supported_band *sband; + struct ieee80211_channel *chan; + unsigned long flags; + int pos; - if (idx != 0) + spin_lock_irqsave(&common->cc_lock, flags); + if (idx == 0) + ath_update_survey_stats(sc); + + sband = hw->wiphy->bands[IEEE80211_BAND_2GHZ]; + if (sband && idx >= sband->n_channels) { + idx -= sband->n_channels; + sband = NULL; + } + + if (!sband) + sband = hw->wiphy->bands[IEEE80211_BAND_5GHZ]; + + if (!sband || idx >= sband->n_channels) { + spin_unlock_irqrestore(&common->cc_lock, flags); return -ENOENT; + } - survey->channel = conf->channel; - survey->filled = SURVEY_INFO_NOISE_DBM; - survey->noise = common->ani.noise_floor; + chan = &sband->channels[idx]; + pos = chan->hw_value; + memcpy(survey, &sc->survey[pos], sizeof(*survey)); + survey->channel = chan; + spin_unlock_irqrestore(&common->cc_lock, flags); return 0; } @@ -2032,7 +2116,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw) aphy->state = ATH_WIPHY_SCAN; ath9k_wiphy_pause_all_forced(sc, aphy); - sc->sc_flags |= SC_OP_SCANNING; mutex_unlock(&sc->mutex); } @@ -2047,7 +2130,6 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) mutex_lock(&sc->mutex); aphy->state = ATH_WIPHY_ACTIVE; - sc->sc_flags &= ~SC_OP_SCANNING; mutex_unlock(&sc->mutex); } diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index e724c2c1ae2a320eb5e17e7c4d419a346c5b1bdf..17969af842f6153a269acb36a7872bbf3356c05d 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h @@ -45,9 +45,6 @@ } \ } while (0) -#define ATH9K_IS_MIC_ENABLED(ah) \ - ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE) - #define ANTSWAP_AB 0x0001 #define REDUCE_CHAIN_0 0x00000050 #define REDUCE_CHAIN_1 0x00000051 diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index e49be733d5461820c8dba6aec394e53700166c66..0cee90cf8dc9dcb4529db6e783a10f2cc819161a 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -302,7 +302,7 @@ static const struct ath_rate_table ar5416_11ng_ratetable = { [64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000, 205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */ [65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000, - 224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */ + 224700, 20, 20, 8, 64, 65, 65 }, /* 270 Mb */ [66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000, 263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */ [67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000, @@ -378,17 +378,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = { 0, /* Phy rates allowed initially */ }; -static const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX] = { - [ATH9K_MODE_11A] = &ar5416_11a_ratetable, - [ATH9K_MODE_11G] = &ar5416_11g_ratetable, - [ATH9K_MODE_11NA_HT20] = &ar5416_11na_ratetable, - [ATH9K_MODE_11NG_HT20] = &ar5416_11ng_ratetable, - [ATH9K_MODE_11NA_HT40PLUS] = &ar5416_11na_ratetable, - [ATH9K_MODE_11NA_HT40MINUS] = &ar5416_11na_ratetable, - [ATH9K_MODE_11NG_HT40PLUS] = &ar5416_11ng_ratetable, - [ATH9K_MODE_11NG_HT40MINUS] = &ar5416_11ng_ratetable, -}; - static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, struct ieee80211_tx_rate *rate); @@ -791,7 +780,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, */ try_per_rate = 4; - rate_table = sc->cur_rate_table; + rate_table = ath_rc_priv->rate_table; rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); /* @@ -1026,6 +1015,16 @@ static bool ath_rc_update_per(struct ath_softc *sc, return state_change; } +static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, + int xretries, int retries, u8 per) +{ + struct ath_rc_stats *stats = &rc->rcstats[rix]; + + stats->xretries += xretries; + stats->retries += retries; + stats->per = per; +} + /* Update PER, RSSI and whatever else that the code thinks it is doing. If you can make sense of all this, you really need to go out more. */ @@ -1038,7 +1037,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, int rate; u8 last_per; bool state_change = false; - const struct ath_rate_table *rate_table = sc->cur_rate_table; + const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; int size = ath_rc_priv->rate_table_size; if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) @@ -1098,7 +1097,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ath_rc_priv->per_down_time = now_msec; } - ath_debug_stat_retries(sc, tx_rate, xretries, retries, + ath_debug_stat_retries(ath_rc_priv, tx_rate, xretries, retries, ath_rc_priv->per[tx_rate]); } @@ -1140,7 +1139,7 @@ static void ath_rc_tx_status(struct ath_softc *sc, u8 flags; u32 i = 0, rix; - rate_table = sc->cur_rate_table; + rate_table = ath_rc_priv->rate_table; /* * If the first rate is not the final index, there @@ -1190,39 +1189,23 @@ static void ath_rc_tx_status(struct ath_softc *sc, static const struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc, enum ieee80211_band band, - bool is_ht, - bool is_cw_40) + bool is_ht) { - int mode = 0; struct ath_common *common = ath9k_hw_common(sc->sc_ah); switch(band) { case IEEE80211_BAND_2GHZ: - mode = ATH9K_MODE_11G; if (is_ht) - mode = ATH9K_MODE_11NG_HT20; - if (is_cw_40) - mode = ATH9K_MODE_11NG_HT40PLUS; - break; + return &ar5416_11ng_ratetable; + return &ar5416_11g_ratetable; case IEEE80211_BAND_5GHZ: - mode = ATH9K_MODE_11A; if (is_ht) - mode = ATH9K_MODE_11NA_HT20; - if (is_cw_40) - mode = ATH9K_MODE_11NA_HT40PLUS; - break; + return &ar5416_11na_ratetable; + return &ar5416_11a_ratetable; default: ath_print(common, ATH_DBG_CONFIG, "Invalid band\n"); return NULL; } - - BUG_ON(mode >= ATH9K_MODE_MAX); - - ath_print(common, ATH_DBG_CONFIG, - "Choosing rate table for mode: %d\n", mode); - - sc->cur_rate_mode = mode; - return hw_rate_table[mode]; } static void ath_rc_init(struct ath_softc *sc, @@ -1293,7 +1276,7 @@ static void ath_rc_init(struct ath_softc *sc, ath_rc_priv->max_valid_rate = k; ath_rc_sort_validrates(rate_table, ath_rc_priv); ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4]; - sc->cur_rate_table = rate_table; + ath_rc_priv->rate_table = rate_table; ath_print(common, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n", @@ -1320,10 +1303,35 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta, return caps; } +static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, + u8 tidno) +{ + struct ath_atx_tid *txtid; + + if (!(sc->sc_flags & SC_OP_TXAGGR)) + return false; + + txtid = ATH_AN_2_TID(an, tidno); + + if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS))) + return true; + return false; +} + + /***********************************/ /* mac80211 Rate Control callbacks */ /***********************************/ +static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) +{ + struct ath_rc_stats *stats; + + stats = &rc->rcstats[final_rate]; + stats->success++; +} + + static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, struct ieee80211_sta *sta, void *priv_sta, struct sk_buff *skb) @@ -1359,6 +1367,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) return; + if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) { + tx_info->status.ampdu_ack_len = + (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); + tx_info->status.ampdu_len = 1; + } + /* * If an underrun error is seen assume it as an excessive retry only * if max frame trigger level has been reached (2 KB for singel stream, @@ -1397,8 +1411,9 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, } } - ath_debug_stat_rc(sc, ath_rc_get_rateindex(sc->cur_rate_table, - &tx_info->status.rates[final_ts_idx])); + ath_debug_stat_rc(ath_rc_priv, + ath_rc_get_rateindex(ath_rc_priv->rate_table, + &tx_info->status.rates[final_ts_idx])); } static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, @@ -1438,14 +1453,8 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, /* Choose rate table first */ - if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) || - (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) || - (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) { - rate_table = ath_choose_rate_table(sc, sband->band, - sta->ht_cap.ht_supported, is_cw40); - } else { - rate_table = hw_rate_table[sc->cur_rate_mode]; - } + rate_table = ath_choose_rate_table(sc, sband->band, + sta->ht_cap.ht_supported); ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi); ath_rc_init(sc, priv_sta, sband, sta, rate_table); @@ -1485,8 +1494,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, if ((local_cw40 != oper_cw40) || (local_sgi != oper_sgi)) { rate_table = ath_choose_rate_table(sc, sband->band, - sta->ht_cap.ht_supported, - oper_cw40); + sta->ht_cap.ht_supported); ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, oper_cw40, oper_sgi); ath_rc_init(sc, priv_sta, sband, sta, rate_table); @@ -1494,11 +1502,98 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, "Operating HT Bandwidth changed to: %d\n", sc->hw->conf.channel_type); - sc->cur_rate_table = hw_rate_table[sc->cur_rate_mode]; } } } +#ifdef CONFIG_ATH9K_DEBUGFS + +static int ath9k_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath_rate_priv *rc = file->private_data; + char *buf; + unsigned int len = 0, max; + int i = 0; + ssize_t retval; + + if (rc->rate_table == NULL) + return 0; + + max = 80 + rc->rate_table->rate_cnt * 1024 + 1; + buf = kmalloc(max, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + len += sprintf(buf, "%6s %6s %6s " + "%10s %10s %10s %10s\n", + "HT", "MCS", "Rate", + "Success", "Retries", "XRetries", "PER"); + + for (i = 0; i < rc->rate_table->rate_cnt; i++) { + u32 ratekbps = rc->rate_table->info[i].ratekbps; + struct ath_rc_stats *stats = &rc->rcstats[i]; + char mcs[5]; + char htmode[5]; + int used_mcs = 0, used_htmode = 0; + + if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) { + used_mcs = snprintf(mcs, 5, "%d", + rc->rate_table->info[i].ratecode); + + if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy)) + used_htmode = snprintf(htmode, 5, "HT40"); + else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy)) + used_htmode = snprintf(htmode, 5, "HT20"); + else + used_htmode = snprintf(htmode, 5, "????"); + } + + mcs[used_mcs] = '\0'; + htmode[used_htmode] = '\0'; + + len += snprintf(buf + len, max - len, + "%6s %6s %3u.%d: " + "%10u %10u %10u %10u\n", + htmode, + mcs, + ratekbps / 1000, + (ratekbps % 1000) / 100, + stats->success, + stats->retries, + stats->xretries, + stats->per); + } + + if (len > max) + len = max; + + retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); + kfree(buf); + return retval; +} + +static const struct file_operations fops_rcstat = { + .read = read_file_rcstat, + .open = ath9k_debugfs_open, + .owner = THIS_MODULE +}; + +static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta, + struct dentry *dir) +{ + struct ath_rate_priv *rc = priv_sta; + debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat); +} + +#endif /* CONFIG_ATH9K_DEBUGFS */ + static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { struct ath_wiphy *aphy = hw->priv; @@ -1545,6 +1640,9 @@ static struct rate_control_ops ath_rate_ops = { .free = ath_rate_free, .alloc_sta = ath_rate_alloc_sta, .free_sta = ath_rate_free_sta, +#ifdef CONFIG_ATH9K_DEBUGFS + .add_sta_debugfs = ath_rate_add_sta_debugfs, +#endif }; int ath_rate_control_register(void) diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index dc1082654501145e15cda7f0a9b17395b001d9ef..2f46a2266ba1d2e0efeb32caef1a50eb0c13ef80 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h @@ -135,20 +135,21 @@ enum { /** * struct ath_rate_table - Rate Control table - * @valid: valid for use in rate control - * @valid_single_stream: valid for use in rate control for - * single stream operation - * @phy: CCK/OFDM + * @rate_cnt: total number of rates for the given wireless mode + * @mcs_start: MCS rate index offset + * @rate_flags: Rate Control flags + * @phy: CCK/OFDM/HT20/HT40 * @ratekbps: rate in Kbits per second * @user_ratekbps: user rate in Kbits per second * @ratecode: rate that goes into HW descriptors - * @short_preamble: Mask for enabling short preamble in ratecode for CCK * @dot11rate: value that goes into supported * rates info element of MLME * @ctrl_rate: Index of next lower basic rate, used for duration computation - * @max_4ms_framelen: maximum frame length(bytes) for tx duration + * @cw40index: Index of rates having 40MHz channel width + * @sgi_index: Index of rates having Short Guard Interval + * @ht_index: high throughput rates having 40MHz channel width and + * Short Guard Interval * @probe_interval: interval for rate control to probe for other rates - * @rssi_reduce_interval: interval for rate control to reduce rssi * @initial_ratemax: initial ratemax value */ struct ath_rate_table { @@ -175,6 +176,13 @@ struct ath_rateset { u8 rs_rates[ATH_RATE_MAX]; }; +struct ath_rc_stats { + u32 success; + u32 retries; + u32 xretries; + u8 per; +}; + /** * struct ath_rate_priv - Rate Control priv data * @state: RC state @@ -211,6 +219,10 @@ struct ath_rate_priv { struct ath_rateset neg_rates; struct ath_rateset neg_ht_rates; struct ath_rate_softc *asc; + const struct ath_rate_table *rate_table; + + struct dentry *debugfs_rcstats; + struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; }; #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) @@ -224,7 +236,18 @@ enum ath9k_internal_frame_type { ATH9K_IFT_UNPAUSE }; +#ifdef CONFIG_ATH9K_RATE_CONTROL int ath_rate_control_register(void); void ath_rate_control_unregister(void); +#else +static inline int ath_rate_control_register(void) +{ + return 0; +} + +static inline void ath_rate_control_unregister(void) +{ +} +#endif #endif /* RC_H */ diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a3fc987ebab003bd5fda0545fa581863b71ba806..fe73fc50082a2c4d681dab51058615a66ceacdfd 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -19,6 +19,15 @@ #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) +static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, + int mindelta, int main_rssi_avg, + int alt_rssi_avg, int pkt_count) +{ + return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + maxdelta)) || + (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50); +} + static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) { return sc->ps_enabled && @@ -110,8 +119,7 @@ static void ath_opmode_init(struct ath_softc *sc) ath9k_hw_setrxfilter(ah, rfilt); /* configure bssid mask */ - if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) - ath_hw_setbssidmask(common); + ath_hw_setbssidmask(common); /* configure operational mode */ ath9k_hw_setopmode(ah); @@ -260,6 +268,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error() on RX init\n"); error = -ENOMEM; @@ -292,7 +301,7 @@ static void ath_edma_start_recv(struct ath_softc *sc) ath_opmode_init(sc); - ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_SCANNING)); + ath9k_hw_startpcureceive(sc->sc_ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); } static void ath_edma_stop_recv(struct ath_softc *sc) @@ -350,12 +359,12 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) bf->bf_buf_addr))) { dev_kfree_skb_any(skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error() on RX init\n"); error = -ENOMEM; goto err; } - bf->bf_dmacontext = bf->bf_buf_addr; } sc->rx.rxlink = NULL; } @@ -385,6 +394,8 @@ void ath_rx_cleanup(struct ath_softc *sc) common->rx_bufsize, DMA_FROM_DEVICE); dev_kfree_skb(skb); + bf->bf_buf_addr = 0; + bf->bf_mpdu = NULL; } } @@ -422,8 +433,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | ATH9K_RX_FILTER_MCAST; - /* If not a STA, enable processing of Probe Requests */ - if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) + if (sc->rx.rxfilter & FIF_PROBE_REQ) rfilt |= ATH9K_RX_FILTER_PROBEREQ; /* @@ -440,13 +450,14 @@ u32 ath_calcrxfilter(struct ath_softc *sc) rfilt |= ATH9K_RX_FILTER_CONTROL; if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && + (sc->nvifs <= 1) && !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)) rfilt |= ATH9K_RX_FILTER_MYBEACON; else rfilt |= ATH9K_RX_FILTER_BEACON; - if ((AR_SREV_9280_10_OR_LATER(sc->sc_ah) || - AR_SREV_9285_10_OR_LATER(sc->sc_ah)) && + if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) || + AR_SREV_9285_12_OR_LATER(sc->sc_ah)) && (sc->sc_ah->opmode == NL80211_IFTYPE_AP) && (sc->rx.rxfilter & FIF_PSPOLL)) rfilt |= ATH9K_RX_FILTER_PSPOLL; @@ -454,9 +465,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc) if (conf_is_ht(&sc->hw->conf)) rfilt |= ATH9K_RX_FILTER_COMP_BAR; - if (sc->sec_wiphy || (sc->rx.rxfilter & FIF_OTHER_BSS)) { - /* TODO: only needed if more than one BSSID is in use in - * station/adhoc mode */ + if (sc->sec_wiphy || (sc->nvifs > 1) || + (sc->rx.rxfilter & FIF_OTHER_BSS)) { /* The following may also be needed for other older chips */ if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) rfilt |= ATH9K_RX_FILTER_PROM; @@ -498,7 +508,7 @@ int ath_startrecv(struct ath_softc *sc) start_recv: spin_unlock_bh(&sc->rx.rxbuflock); ath_opmode_init(sc); - ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_SCANNING)); + ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL)); return 0; } @@ -631,7 +641,7 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb) * No more broadcast/multicast frames to be received at this * point. */ - sc->ps_flags &= ~PS_WAIT_FOR_CAB; + sc->ps_flags &= ~(PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON); ath_print(common, ATH_DBG_PS, "All PS CAB frames received, back to sleep\n"); } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) && @@ -870,15 +880,18 @@ static bool ath9k_rx_accept(struct ath_common *common, if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { *decrypt_error = true; } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { - if (ieee80211_is_ctl(fc)) - /* - * Sometimes, we get invalid - * MIC failures on valid control frames. - * Remove these mic errors. - */ - rx_stats->rs_status &= ~ATH9K_RXERR_MIC; - else + /* + * The MIC error bit is only valid if the frame + * is not a control frame or fragment, and it was + * decrypted using a valid TKIP key. + */ + if (!ieee80211_is_ctl(fc) && + !ieee80211_has_morefrags(fc) && + !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && + test_bit(rx_stats->rs_keyix, common->tkip_keymap)) rxs->flag |= RX_FLAG_MMIC_ERROR; + else + rx_stats->rs_status &= ~ATH9K_RXERR_MIC; } /* * Reject error frames with the exception of @@ -966,7 +979,11 @@ static void ath9k_process_rssi(struct ath_common *common, * at least one sdata of a wiphy on mac80211 but with ath9k virtual * wiphy you'd have to iterate over every wiphy and each sdata. */ - sta = ieee80211_find_sta_by_hw(hw, hdr->addr2); + if (is_multicast_ether_addr(hdr->addr1)) + sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, NULL); + else + sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr2, hdr->addr1); + if (sta) { an = (struct ath_node *) sta->drv_priv; if (rx_stats->rs_rssi != ATH9K_RSSI_BAD && @@ -1073,6 +1090,539 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common, rxs->flag &= ~RX_FLAG_DECRYPTED; } +static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb, + struct ath_hw_antcomb_conf ant_conf, + int main_rssi_avg) +{ + antcomb->quick_scan_cnt = 0; + + if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = main_rssi_avg; + else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = main_rssi_avg; + + switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) { + case (0x10): /* LNA2 A-B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; + break; + case (0x20): /* LNA1 A-B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; + break; + case (0x21): /* LNA1 LNA2 */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case (0x12): /* LNA2 LNA1 */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case (0x13): /* LNA2 A+B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1; + break; + case (0x23): /* LNA1 A+B */ + antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + antcomb->first_quick_scan_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2; + break; + default: + break; + } +} + +static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, + struct ath_hw_antcomb_conf *div_ant_conf, + int main_rssi_avg, int alt_rssi_avg, + int alt_ratio) +{ + /* alt_good */ + switch (antcomb->quick_scan_cnt) { + case 0: + /* set alt to main, and alt to first conf */ + div_ant_conf->main_lna_conf = antcomb->main_conf; + div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf; + break; + case 1: + /* set alt to main, and alt to first conf */ + div_ant_conf->main_lna_conf = antcomb->main_conf; + div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf; + antcomb->rssi_first = main_rssi_avg; + antcomb->rssi_second = alt_rssi_avg; + + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { + /* main is LNA1 */ + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_HI, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_MID, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } else { + if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + + ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || + (alt_rssi_avg > main_rssi_avg)) && + (antcomb->total_pkt_count > 50)) + antcomb->first_ratio = true; + else + antcomb->first_ratio = false; + } + break; + case 2: + antcomb->alt_good = false; + antcomb->scan_not_start = false; + antcomb->scan = false; + antcomb->rssi_first = main_rssi_avg; + antcomb->rssi_third = alt_rssi_avg; + + if (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = alt_rssi_avg; + else if (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = alt_rssi_avg; + else if (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2) { + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) + antcomb->rssi_lna2 = main_rssi_avg; + else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) + antcomb->rssi_lna1 = main_rssi_avg; + } + + if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) + div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; + else + div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; + + if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_HI, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) { + if (ath_is_alt_ant_ratio_better(alt_ratio, + ATH_ANT_DIV_COMB_LNA1_DELTA_MID, + ATH_ANT_DIV_COMB_LNA1_DELTA_LOW, + main_rssi_avg, alt_rssi_avg, + antcomb->total_pkt_count)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } else { + if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) && + (alt_rssi_avg > main_rssi_avg + + ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) || + (alt_rssi_avg > main_rssi_avg)) && + (antcomb->total_pkt_count > 50)) + antcomb->second_ratio = true; + else + antcomb->second_ratio = false; + } + + /* set alt to the conf with maximun ratio */ + if (antcomb->first_ratio && antcomb->second_ratio) { + if (antcomb->rssi_second > antcomb->rssi_third) { + /* first alt*/ + if ((antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2*/ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->first_quick_scan_conf; + } else if ((antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) { + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } else { + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->second_quick_scan_conf; + } + } else if (antcomb->first_ratio) { + /* first alt */ + if ((antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->first_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->first_quick_scan_conf; + } else if (antcomb->second_ratio) { + /* second alt */ + if ((antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA1) || + (antcomb->second_quick_scan_conf == + ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = + antcomb->second_quick_scan_conf; + } else { + /* main is largest */ + if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) || + (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)) + /* Set alt LNA1 or LNA2 */ + if (div_ant_conf->main_lna_conf == + ATH_ANT_DIV_COMB_LNA2) + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else + div_ant_conf->alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + else + /* Set alt to A+B or A-B */ + div_ant_conf->alt_lna_conf = antcomb->main_conf; + } + break; + default: + break; + } +} + +static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf) +{ + /* Adjust the fast_div_bias based on main and alt lna conf */ + switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) { + case (0x01): /* A-B LNA2 */ + ant_conf->fast_div_bias = 0x3b; + break; + case (0x02): /* A-B LNA1 */ + ant_conf->fast_div_bias = 0x3d; + break; + case (0x03): /* A-B A+B */ + ant_conf->fast_div_bias = 0x1; + break; + case (0x10): /* LNA2 A-B */ + ant_conf->fast_div_bias = 0x7; + break; + case (0x12): /* LNA2 LNA1 */ + ant_conf->fast_div_bias = 0x2; + break; + case (0x13): /* LNA2 A+B */ + ant_conf->fast_div_bias = 0x7; + break; + case (0x20): /* LNA1 A-B */ + ant_conf->fast_div_bias = 0x6; + break; + case (0x21): /* LNA1 LNA2 */ + ant_conf->fast_div_bias = 0x0; + break; + case (0x23): /* LNA1 A+B */ + ant_conf->fast_div_bias = 0x6; + break; + case (0x30): /* A+B A-B */ + ant_conf->fast_div_bias = 0x1; + break; + case (0x31): /* A+B LNA2 */ + ant_conf->fast_div_bias = 0x3b; + break; + case (0x32): /* A+B LNA1 */ + ant_conf->fast_div_bias = 0x3d; + break; + default: + break; + } +} + +/* Antenna diversity and combining */ +static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) +{ + struct ath_hw_antcomb_conf div_ant_conf; + struct ath_ant_comb *antcomb = &sc->ant_comb; + int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; + int curr_main_set, curr_bias; + int main_rssi = rs->rs_rssi_ctl0; + int alt_rssi = rs->rs_rssi_ctl1; + int rx_ant_conf, main_ant_conf; + bool short_scan = false; + + rx_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_CURRENT_SHIFT) & + ATH_ANT_RX_MASK; + main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) & + ATH_ANT_RX_MASK; + + /* Record packet only when alt_rssi is positive */ + if (alt_rssi > 0) { + antcomb->total_pkt_count++; + antcomb->main_total_rssi += main_rssi; + antcomb->alt_total_rssi += alt_rssi; + if (main_ant_conf == rx_ant_conf) + antcomb->main_recv_cnt++; + else + antcomb->alt_recv_cnt++; + } + + /* Short scan check */ + if (antcomb->scan && antcomb->alt_good) { + if (time_after(jiffies, antcomb->scan_start_time + + msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR))) + short_scan = true; + else + if (antcomb->total_pkt_count == + ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) { + alt_ratio = ((antcomb->alt_recv_cnt * 100) / + antcomb->total_pkt_count); + if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO) + short_scan = true; + } + } + + if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) || + rs->rs_moreaggr) && !short_scan) + return; + + if (antcomb->total_pkt_count) { + alt_ratio = ((antcomb->alt_recv_cnt * 100) / + antcomb->total_pkt_count); + main_rssi_avg = (antcomb->main_total_rssi / + antcomb->total_pkt_count); + alt_rssi_avg = (antcomb->alt_total_rssi / + antcomb->total_pkt_count); + } + + + ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); + curr_alt_set = div_ant_conf.alt_lna_conf; + curr_main_set = div_ant_conf.main_lna_conf; + curr_bias = div_ant_conf.fast_div_bias; + + antcomb->count++; + + if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) { + if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { + ath_lnaconf_alt_good_scan(antcomb, div_ant_conf, + main_rssi_avg); + antcomb->alt_good = true; + } else { + antcomb->alt_good = false; + } + + antcomb->count = 0; + antcomb->scan = true; + antcomb->scan_not_start = true; + } + + if (!antcomb->scan) { + if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) { + if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) { + /* Switch main and alt LNA */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + + goto div_comb_done; + } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) && + (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) { + /* Set alt to another LNA */ + if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + + goto div_comb_done; + } + + if ((alt_rssi_avg < (main_rssi_avg + + ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA))) + goto div_comb_done; + } + + if (!antcomb->scan_not_start) { + switch (curr_alt_set) { + case ATH_ANT_DIV_COMB_LNA2: + antcomb->rssi_lna2 = alt_rssi_avg; + antcomb->rssi_lna1 = main_rssi_avg; + antcomb->scan = true; + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1: + antcomb->rssi_lna1 = alt_rssi_avg; + antcomb->rssi_lna2 = main_rssi_avg; + antcomb->scan = true; + /* set to A+B */ + div_ant_conf.main_lna_conf = ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2: + antcomb->rssi_add = alt_rssi_avg; + antcomb->scan = true; + /* set to A-B */ + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + break; + case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2: + antcomb->rssi_sub = alt_rssi_avg; + antcomb->scan = false; + if (antcomb->rssi_lna2 > + (antcomb->rssi_lna1 + + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { + /* use LNA2 as main LNA */ + if ((antcomb->rssi_add > antcomb->rssi_lna1) && + (antcomb->rssi_add > antcomb->rssi_sub)) { + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + } else if (antcomb->rssi_sub > + antcomb->rssi_lna1) { + /* set to A-B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + } else { + /* set to LNA1 */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } + } else { + /* use LNA1 as main LNA */ + if ((antcomb->rssi_add > antcomb->rssi_lna2) && + (antcomb->rssi_add > antcomb->rssi_sub)) { + /* set to A+B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2; + } else if (antcomb->rssi_sub > + antcomb->rssi_lna1) { + /* set to A-B */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2; + } else { + /* set to LNA2 */ + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + } + break; + default: + break; + } + } else { + if (!antcomb->alt_good) { + antcomb->scan_not_start = false; + /* Set alt to another LNA */ + if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) { + div_ant_conf.main_lna_conf = + ATH_ANT_DIV_COMB_LNA1; + div_ant_conf.alt_lna_conf = + ATH_ANT_DIV_COMB_LNA2; + } + goto div_comb_done; + } + } + + ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf, + main_rssi_avg, alt_rssi_avg, + alt_ratio); + + antcomb->quick_scan_cnt++; + +div_comb_done: + ath_ant_div_conf_fast_divbias(&div_ant_conf); + + ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf); + + antcomb->scan_start_time = jiffies; + antcomb->total_pkt_count = 0; + antcomb->main_total_rssi = 0; + antcomb->alt_total_rssi = 0; + antcomb->main_recv_cnt = 0; + antcomb->alt_recv_cnt = 0; +} + int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) { struct ath_buf *bf; @@ -1096,6 +1646,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) u8 rx_status_len = ah->caps.rx_status_len; u64 tsf = 0; u32 tsf_lower = 0; + unsigned long flags; if (edma) dma_type = DMA_BIDIRECTIONAL; @@ -1186,12 +1737,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) bf->bf_buf_addr))) { dev_kfree_skb_any(requeue_skb); bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(common, ATH_DBG_FATAL, "dma_mapping_error() on RX\n"); ath_rx_send_to_mac80211(hw, sc, skb, rxs); break; } - bf->bf_dmacontext = bf->bf_buf_addr; /* * change the default rx antenna if rx diversity chooses the @@ -1204,11 +1755,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) sc->rx.rxotherant = 0; } + spin_lock_irqsave(&sc->sc_pm_lock, flags); if (unlikely(ath9k_check_auto_sleep(sc) || (sc->ps_flags & (PS_WAIT_FOR_BEACON | PS_WAIT_FOR_CAB | PS_WAIT_FOR_PSPOLL_DATA)))) ath_rx_ps(sc, skb); + spin_unlock_irqrestore(&sc->sc_pm_lock, flags); + + if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) + ath_ant_comb_scan(sc, &rs); ath_rx_send_to_mac80211(hw, sc, skb, rxs); diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index d01c4adab8d67bef80e37dce242c668210a783b4..42976b0a01c115692566fe0f7f416c5aa9949b9f 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -107,12 +107,6 @@ #define AR_RXCFG_DMASZ_256B 6 #define AR_RXCFG_DMASZ_512B 7 -#define AR_MIBC 0x0040 -#define AR_MIBC_COW 0x00000001 -#define AR_MIBC_FMC 0x00000002 -#define AR_MIBC_CMC 0x00000004 -#define AR_MIBC_MCS 0x00000008 - #define AR_TOPS 0x0044 #define AR_TOPS_MASK 0x0000FFFF @@ -819,49 +813,23 @@ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11)) #define AR_SREV_9280(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280)) -#define AR_SREV_9280_10_OR_LATER(_ah) \ +#define AR_SREV_9280_20_OR_LATER(_ah) \ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280)) #define AR_SREV_9280_20(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)) -#define AR_SREV_9280_20_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))) + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280)) #define AR_SREV_9285(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285)) -#define AR_SREV_9285_10_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285)) -#define AR_SREV_9285_11(_ah) \ - (AR_SREV_9285(ah) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11)) -#define AR_SREV_9285_11_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \ - (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \ - AR_SREV_REVISION_9285_11))) -#define AR_SREV_9285_12(_ah) \ - (AR_SREV_9285(ah) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12)) #define AR_SREV_9285_12_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \ - (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \ - AR_SREV_REVISION_9285_12))) + (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285)) #define AR_SREV_9287(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287)) -#define AR_SREV_9287_10_OR_LATER(_ah) \ +#define AR_SREV_9287_11_OR_LATER(_ah) \ (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9287)) -#define AR_SREV_9287_10(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_10)) #define AR_SREV_9287_11(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_11)) -#define AR_SREV_9287_11_OR_LATER(_ah) \ - (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ - ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11))) #define AR_SREV_9287_12(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_12)) @@ -885,9 +853,6 @@ #define AR_SREV_9300(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) -#define AR_SREV_9300_20(_ah) \ - (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ - ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20)) #define AR_SREV_9300_20_OR_LATER(_ah) \ (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ @@ -1550,11 +1515,6 @@ enum { #define AR_TPC_CHIRP 0x003f0000 #define AR_TPC_CHIRP_S 0x16 -#define AR_TFCNT 0x80ec -#define AR_RFCNT 0x80f0 -#define AR_RCCNT 0x80f4 -#define AR_CCCNT 0x80f8 - #define AR_QUIET1 0x80fc #define AR_QUIET1_NEXT_QUIET_S 0 #define AR_QUIET1_NEXT_QUIET_M 0x0000ffff diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index fd20241f57d8ef8239aa3cdc62bec57198e2ec46..ec7cf5ee56bc3ac9a850f7ee56fab95251b88d6d 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c @@ -19,45 +19,36 @@ #include "ath9k.h" struct ath9k_vif_iter_data { - int count; - u8 *addr; + const u8 *hw_macaddr; + u8 mask[ETH_ALEN]; }; static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { struct ath9k_vif_iter_data *iter_data = data; - u8 *nbuf; - - nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN, - GFP_ATOMIC); - if (nbuf == NULL) - return; + int i; - memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN); - iter_data->addr = nbuf; - iter_data->count++; + for (i = 0; i < ETH_ALEN; i++) + iter_data->mask[i] &= ~(iter_data->hw_macaddr[i] ^ mac[i]); } -void ath9k_set_bssid_mask(struct ieee80211_hw *hw) +void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct ath_wiphy *aphy = hw->priv; struct ath_softc *sc = aphy->sc; struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath9k_vif_iter_data iter_data; - int i, j; - u8 mask[ETH_ALEN]; + int i; /* - * Add primary MAC address even if it is not in active use since it - * will be configured to the hardware as the starting point and the - * BSSID mask will need to be changed if another address is active. + * Use the hardware MAC address as reference, the hardware uses it + * together with the BSSID mask when matching addresses. */ - iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC); - if (iter_data.addr) { - memcpy(iter_data.addr, common->macaddr, ETH_ALEN); - iter_data.count = 1; - } else - iter_data.count = 0; + iter_data.hw_macaddr = common->macaddr; + memset(&iter_data.mask, 0xff, ETH_ALEN); + + if (vif) + ath9k_vif_iter(&iter_data, vif->addr, vif); /* Get list of all active MAC addresses */ spin_lock_bh(&sc->wiphy_lock); @@ -71,31 +62,7 @@ void ath9k_set_bssid_mask(struct ieee80211_hw *hw) } spin_unlock_bh(&sc->wiphy_lock); - /* Generate an address mask to cover all active addresses */ - memset(mask, 0, ETH_ALEN); - for (i = 0; i < iter_data.count; i++) { - u8 *a1 = iter_data.addr + i * ETH_ALEN; - for (j = i + 1; j < iter_data.count; j++) { - u8 *a2 = iter_data.addr + j * ETH_ALEN; - mask[0] |= a1[0] ^ a2[0]; - mask[1] |= a1[1] ^ a2[1]; - mask[2] |= a1[2] ^ a2[2]; - mask[3] |= a1[3] ^ a2[3]; - mask[4] |= a1[4] ^ a2[4]; - mask[5] |= a1[5] ^ a2[5]; - } - } - - kfree(iter_data.addr); - - /* Invert the mask and configure hardware */ - common->bssidmask[0] = ~mask[0]; - common->bssidmask[1] = ~mask[1]; - common->bssidmask[2] = ~mask[2]; - common->bssidmask[3] = ~mask[3]; - common->bssidmask[4] = ~mask[4]; - common->bssidmask[5] = ~mask[5]; - + memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); ath_hw_setbssidmask(common); } diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 6260faa658a262ebd16017425deb2cdd28aa48ae..93a8bda09c251bfeef67a738249a758a12b088c4 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -85,6 +85,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) return "WMI_TGT_DETACH_CMDID"; case WMI_TGT_TXQ_ENABLE_CMDID: return "WMI_TGT_TXQ_ENABLE_CMDID"; + case WMI_AGGR_LIMIT_CMD: + return "WMI_AGGR_LIMIT_CMD"; } return "Bogus"; @@ -122,55 +124,11 @@ void ath9k_wmi_tasklet(unsigned long data) { struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; struct ath_common *common = ath9k_hw_common(priv->ah); - struct wmi_cmd_hdr *hdr; - struct wmi_swba *swba_hdr; - enum wmi_event_id event; - struct sk_buff *skb; - void *wmi_event; - unsigned long flags; -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - __be32 txrate; -#endif - spin_lock_irqsave(&priv->wmi->wmi_lock, flags); - skb = priv->wmi->wmi_skb; - spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); + ath_print(common, ATH_DBG_WMI, "SWBA Event received\n"); - hdr = (struct wmi_cmd_hdr *) skb->data; - event = be16_to_cpu(hdr->command_id); - wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); + ath9k_htc_swba(priv, priv->wmi->beacon_pending); - ath_print(common, ATH_DBG_WMI, - "WMI Event: 0x%x\n", event); - - switch (event) { - case WMI_TGT_RDY_EVENTID: - break; - case WMI_SWBA_EVENTID: - swba_hdr = (struct wmi_swba *) wmi_event; - ath9k_htc_swba(priv, swba_hdr->beacon_pending); - break; - case WMI_FATAL_EVENTID: - break; - case WMI_TXTO_EVENTID: - break; - case WMI_BMISS_EVENTID: - break; - case WMI_WLAN_TXCOMP_EVENTID: - break; - case WMI_DELBA_EVENTID: - break; - case WMI_TXRATE_EVENTID: -#ifdef CONFIG_ATH9K_HTC_DEBUGFS - txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; - priv->debug.txrate = be32_to_cpu(txrate); -#endif - break; - default: - break; - } - - kfree_skb(skb); } static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb) @@ -189,6 +147,10 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, struct wmi *wmi = (struct wmi *) priv; struct wmi_cmd_hdr *hdr; u16 cmd_id; + void *wmi_event; +#ifdef CONFIG_ATH9K_HTC_DEBUGFS + __be32 txrate; +#endif if (unlikely(wmi->stopped)) goto free_skb; @@ -197,10 +159,22 @@ static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, cmd_id = be16_to_cpu(hdr->command_id); if (cmd_id & 0x1000) { - spin_lock(&wmi->wmi_lock); - wmi->wmi_skb = skb; - spin_unlock(&wmi->wmi_lock); - tasklet_schedule(&wmi->drv_priv->wmi_tasklet); + wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); + switch (cmd_id) { + case WMI_SWBA_EVENTID: + wmi->beacon_pending = *(u8 *)wmi_event; + tasklet_schedule(&wmi->drv_priv->wmi_tasklet); + break; + case WMI_TXRATE_EVENTID: +#ifdef CONFIG_ATH9K_HTC_DEBUGFS + txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; + wmi->drv_priv->debug.txrate = be32_to_cpu(txrate); +#endif + break; + default: + break; + } + kfree_skb(skb); return; } diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 765db5faa2d3d01291f790680bb87ca76bc8736d..ac61074af8ac72898fb6e385e0bd63a596db21ca 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -31,10 +31,6 @@ struct wmi_cmd_hdr { __be16 seq_no; } __packed; -struct wmi_swba { - u8 beacon_pending; -} __packed; - enum wmi_cmd_id { WMI_ECHO_CMDID = 0x0001, WMI_ACCESS_MEMORY_CMDID, @@ -71,6 +67,7 @@ enum wmi_cmd_id { WMI_TX_AGGR_ENABLE_CMDID, WMI_TGT_DETACH_CMDID, WMI_TGT_TXQ_ENABLE_CMDID, + WMI_AGGR_LIMIT_CMD = 0x0026, }; enum wmi_event_id { @@ -103,7 +100,7 @@ struct wmi { u32 cmd_rsp_len; bool stopped; - struct sk_buff *wmi_skb; + u8 beacon_pending; spinlock_t wmi_lock; atomic_t mwrite_cnt; diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 4dda14e3622781babd1d7e296e395ed18bca135c..d077186da870ea2ccc507b168fba81d21ffcac8d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -61,6 +61,8 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, int txok); static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, int nbad, int txok, bool update_rc); +static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, + int seqno); enum { MCS_HT20, @@ -143,18 +145,23 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum]; struct ath_buf *bf; struct list_head bf_head; - INIT_LIST_HEAD(&bf_head); + struct ath_tx_status ts; - WARN_ON(!tid->paused); + INIT_LIST_HEAD(&bf_head); + memset(&ts, 0, sizeof(ts)); spin_lock_bh(&txq->axq_lock); - tid->paused = false; while (!list_empty(&tid->buf_q)) { bf = list_first_entry(&tid->buf_q, struct ath_buf, list); - BUG_ON(bf_isretried(bf)); list_move_tail(&bf->list, &bf_head); - ath_tx_send_ht_normal(sc, txq, tid, &bf_head); + + if (bf_isretried(bf)) { + ath_tx_update_baw(sc, tid, bf->bf_seqno); + ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); + } else { + ath_tx_send_ht_normal(sc, txq, tid, &bf_head); + } } spin_unlock_bh(&txq->axq_lock); @@ -168,9 +175,9 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, index = ATH_BA_INDEX(tid->seq_start, seqno); cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); - tid->tx_buf[cindex] = NULL; + __clear_bit(cindex, tid->tx_buf); - while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) { + while (tid->baw_head != tid->baw_tail && !test_bit(tid->baw_head, tid->tx_buf)) { INCR(tid->seq_start, IEEE80211_SEQ_MAX); INCR(tid->baw_head, ATH_TID_MAX_BUFS); } @@ -186,9 +193,7 @@ static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid, index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno); cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); - - BUG_ON(tid->tx_buf[cindex] != NULL); - tid->tx_buf[cindex] = bf; + __set_bit(cindex, tid->tx_buf); if (index >= ((tid->baw_tail - tid->baw_head) & (ATH_TID_MAX_BUFS - 1))) { @@ -289,7 +294,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) tbf->bf_buf_addr = bf->bf_buf_addr; memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); tbf->bf_state = bf->bf_state; - tbf->bf_dmacontext = bf->bf_dmacontext; return tbf; } @@ -312,6 +316,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; struct ieee80211_tx_rate rates[4]; + int nframes; skb = bf->bf_mpdu; hdr = (struct ieee80211_hdr *)skb->data; @@ -320,11 +325,11 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, hw = bf->aphy->hw; memcpy(rates, tx_info->control.rates, sizeof(rates)); + nframes = bf->bf_nframes; rcu_read_lock(); - /* XXX: use ieee80211_find_sta! */ - sta = ieee80211_find_sta_by_hw(hw, hdr->addr1); + sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); if (!sta) { rcu_read_unlock(); @@ -337,7 +342,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, !bf->bf_stale || bf_next != NULL) list_move_tail(&bf->list, &bf_head); - ath_tx_rc_status(bf, ts, 0, 0, false); + ath_tx_rc_status(bf, ts, 1, 0, false); ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0, 0); @@ -431,7 +436,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, list_move_tail(&bf->list, &bf_head); } - if (!txpending) { + if (!txpending || (tid->state & AGGR_CLEANUP)) { /* * complete the acked-ones/xretried ones; update * block-ack window @@ -442,6 +447,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { memcpy(tx_info->control.rates, rates, sizeof(rates)); + bf->bf_nframes = nframes; ath_tx_rc_status(bf, ts, nbad, txok, true); rc_update = false; } else { @@ -510,15 +516,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, } if (tid->state & AGGR_CLEANUP) { + ath_tx_flush_tid(sc, tid); + if (tid->baw_head == tid->baw_tail) { tid->state &= ~AGGR_ADDBA_COMPLETE; tid->state &= ~AGGR_CLEANUP; - - /* send buffered frames as singles */ - ath_tx_flush_tid(sc, tid); } - rcu_read_unlock(); - return; } rcu_read_unlock(); @@ -785,17 +788,23 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, status != ATH_AGGR_BAW_CLOSED); } -void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, - u16 tid, u16 *ssn) +int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, + u16 tid, u16 *ssn) { struct ath_atx_tid *txtid; struct ath_node *an; an = (struct ath_node *)sta->drv_priv; txtid = ATH_AN_2_TID(an, tid); + + if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE)) + return -EAGAIN; + txtid->state |= AGGR_ADDBA_PROGRESS; txtid->paused = true; *ssn = txtid->seq_start; + + return 0; } void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) @@ -803,12 +812,6 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) struct ath_node *an = (struct ath_node *)sta->drv_priv; struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; - struct ath_tx_status ts; - struct ath_buf *bf; - struct list_head bf_head; - - memset(&ts, 0, sizeof(ts)); - INIT_LIST_HEAD(&bf_head); if (txtid->state & AGGR_CLEANUP) return; @@ -818,31 +821,22 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) return; } - /* drop all software retried frames and mark this TID */ spin_lock_bh(&txq->axq_lock); txtid->paused = true; - while (!list_empty(&txtid->buf_q)) { - bf = list_first_entry(&txtid->buf_q, struct ath_buf, list); - if (!bf_isretried(bf)) { - /* - * NB: it's based on the assumption that - * software retried frame will always stay - * at the head of software queue. - */ - break; - } - list_move_tail(&bf->list, &bf_head); - ath_tx_update_baw(sc, txtid, bf->bf_seqno); - ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); - } - spin_unlock_bh(&txq->axq_lock); - if (txtid->baw_head != txtid->baw_tail) { + /* + * If frames are still being transmitted for this TID, they will be + * cleaned up during tx completion. To prevent race conditions, this + * TID can only be reused after all in-progress subframes have been + * completed. + */ + if (txtid->baw_head != txtid->baw_tail) txtid->state |= AGGR_CLEANUP; - } else { + else txtid->state &= ~AGGR_ADDBA_COMPLETE; - ath_tx_flush_tid(sc, txtid); - } + spin_unlock_bh(&txq->axq_lock); + + ath_tx_flush_tid(sc, txtid); } void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) @@ -862,20 +856,6 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid } } -bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno) -{ - struct ath_atx_tid *txtid; - - if (!(sc->sc_flags & SC_OP_TXAGGR)) - return false; - - txtid = ATH_AN_2_TID(an, tidno); - - if (!(txtid->state & (AGGR_ADDBA_COMPLETE | AGGR_ADDBA_PROGRESS))) - return true; - return false; -} - /********************/ /* Queue Management */ /********************/ @@ -1407,22 +1387,6 @@ static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) return htype; } -static int get_hw_crypto_keytype(struct sk_buff *skb) -{ - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - - if (tx_info->control.hw_key) { - if (tx_info->control.hw_key->alg == ALG_WEP) - return ATH9K_KEY_TYPE_WEP; - else if (tx_info->control.hw_key->alg == ALG_TKIP) - return ATH9K_KEY_TYPE_TKIP; - else if (tx_info->control.hw_key->alg == ALG_CCMP) - return ATH9K_KEY_TYPE_AES; - } - - return ATH9K_KEY_TYPE_CLEAR; -} - static void assign_aggr_tid_seqno(struct sk_buff *skb, struct ath_buf *bf) { @@ -1661,7 +1625,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_state.bfs_paprd_timestamp = jiffies; bf->bf_flags = setup_tx_flags(skb, use_ldpc); - bf->bf_keytype = get_hw_crypto_keytype(skb); + bf->bf_keytype = ath9k_cmn_get_hw_crypto_keytype(skb); if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { bf->bf_frmlen += tx_info->control.hw_key->icv_len; bf->bf_keyix = tx_info->control.hw_key->hw_key_idx; @@ -1675,24 +1639,16 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, bf->bf_mpdu = skb; - bf->bf_dmacontext = dma_map_single(sc->dev, skb->data, - skb->len, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) { + bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, + skb->len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { bf->bf_mpdu = NULL; + bf->bf_buf_addr = 0; ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, "dma_mapping_error() on TX\n"); return -ENOMEM; } - bf->bf_buf_addr = bf->bf_dmacontext; - - /* tag if this is a nullfunc frame to enable PS when AP acks it */ - if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { - bf->bf_isnullfunc = true; - sc->ps_flags &= ~PS_NULLFUNC_COMPLETED; - } else - bf->bf_isnullfunc = false; - bf->bf_tx_aborted = false; return 0; @@ -1956,7 +1912,8 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, tx_flags |= ATH_TX_XRETRY; } - dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); + dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); + bf->bf_buf_addr = 0; if (bf->bf_state.bfs_paprd) { if (time_after(jiffies, @@ -1966,9 +1923,13 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, else complete(&sc->paprd_complete); } else { - ath_tx_complete(sc, skb, bf->aphy, tx_flags); ath_debug_stat_tx(sc, txq, bf, ts); + ath_tx_complete(sc, skb, bf->aphy, tx_flags); } + /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't + * accidentally reference it later. + */ + bf->bf_mpdu = NULL; /* * Return the list of ath_buf of this mpdu to free queue @@ -2024,9 +1985,15 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, if (ts->ts_status & ATH9K_TXERR_FILT) tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) { tx_info->flags |= IEEE80211_TX_STAT_AMPDU; + BUG_ON(nbad > bf->bf_nframes); + + tx_info->status.ampdu_len = bf->bf_nframes; + tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; + } + if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { if (ieee80211_is_data(hdr->frame_control)) { @@ -2036,8 +2003,6 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, if ((ts->ts_status & ATH9K_TXERR_XRETRY) || (ts->ts_status & ATH9K_TXERR_FIFO)) tx_info->pad[0] |= ATH_TX_INFO_XRETRY; - tx_info->status.ampdu_len = bf->bf_nframes; - tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; } } @@ -2119,18 +2084,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) break; } - /* - * We now know the nullfunc frame has been ACKed so we - * can disable RX. - */ - if (bf->bf_isnullfunc && - (ts.ts_status & ATH9K_TX_ACKED)) { - if ((sc->ps_flags & PS_ENABLED)) - ath9k_enable_ps(sc); - else - sc->ps_flags |= PS_NULLFUNC_COMPLETED; - } - /* * Remove ath_buf's of the same transmit unit from txq, * however leave the last descriptor back as the holding @@ -2159,7 +2112,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) */ if (ts.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, &ts, 0, txok, true); + ath_tx_rc_status(bf, &ts, txok ? 0 : 1, txok, true); } if (bf_isampdu(bf)) @@ -2274,21 +2227,10 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) txok = !(txs.ts_status & ATH9K_TXERR_MASK); - /* - * Make sure null func frame is acked before configuring - * hw into ps mode. - */ - if (bf->bf_isnullfunc && txok) { - if ((sc->ps_flags & PS_ENABLED)) - ath9k_enable_ps(sc); - else - sc->ps_flags |= PS_NULLFUNC_COMPLETED; - } - if (!bf_isampdu(bf)) { if (txs.ts_status & ATH9K_TXERR_XRETRY) bf->bf_state.bf_type |= BUF_XRETRY; - ath_tx_rc_status(bf, &txs, 0, txok, true); + ath_tx_rc_status(bf, &txs, txok ? 0 : 1, txok, true); } if (bf_isampdu(bf)) diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..2d1b821b440d6ebda30969fd240c07fbee3ce12b --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/Kconfig @@ -0,0 +1,41 @@ +config CARL9170 + tristate "Linux Community AR9170 802.11n USB support" + depends on USB && MAC80211 && EXPERIMENTAL + select FW_LOADER + select CRC32 + help + This is another driver for the Atheros "otus" 802.11n USB devices. + + This driver provides more features than the original, + but it needs a special firmware (carl9170-1.fw) to do that. + + The firmware can be downloaded from our wiki here: + + + If you choose to build a module, it'll be called carl9170. + +config CARL9170_LEDS + bool "SoftLED Support" + depends on CARL9170 + select MAC80211_LEDS + select LEDS_CLASS + select NEW_LEDS + default y + help + This option is necessary, if you want your device' LEDs to blink + + Say Y, unless you need the LEDs for firmware debugging. + +config CARL9170_DEBUGFS + bool "DebugFS Support" + depends on CARL9170 && DEBUG_FS && MAC80211_DEBUGFS + default n + help + Export several driver and device internals to user space. + + Say N. + +config CARL9170_WPC + bool + depends on CARL9170 && (INPUT = y || INPUT = CARL9170) + default y diff --git a/drivers/net/wireless/ath/carl9170/Makefile b/drivers/net/wireless/ath/carl9170/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..f64ed76af8adb10caa44a2d78d5e75fd7420a45c --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/Makefile @@ -0,0 +1,4 @@ +carl9170-objs := main.o usb.o cmd.o mac.o phy.o led.o fw.o tx.o rx.o +carl9170-$(CONFIG_CARL9170_DEBUGFS) += debug.o + +obj-$(CONFIG_CARL9170) += carl9170.o diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h new file mode 100644 index 0000000000000000000000000000000000000000..6cf0c9ef47aa4e7ae005abc034edca2fb40d30e6 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -0,0 +1,628 @@ +/* + * Atheros CARL9170 driver + * + * Driver specific definitions + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __CARL9170_H +#define __CARL9170_H + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_CARL9170_LEDS +#include +#endif /* CONFIG_CARL170_LEDS */ +#ifdef CONFIG_CARL9170_WPC +#include +#endif /* CONFIG_CARL9170_WPC */ +#include "eeprom.h" +#include "wlan.h" +#include "hw.h" +#include "fwdesc.h" +#include "fwcmd.h" +#include "../regd.h" + +#ifdef CONFIG_CARL9170_DEBUGFS +#include "debug.h" +#endif /* CONFIG_CARL9170_DEBUGFS */ + +#define CARL9170FW_NAME "carl9170-1.fw" + +#define PAYLOAD_MAX (CARL9170_MAX_CMD_LEN / 4 - 1) + +enum carl9170_rf_init_mode { + CARL9170_RFI_NONE, + CARL9170_RFI_WARM, + CARL9170_RFI_COLD, +}; + +#define CARL9170_MAX_RX_BUFFER_SIZE 8192 + +enum carl9170_device_state { + CARL9170_UNKNOWN_STATE, + CARL9170_STOPPED, + CARL9170_IDLE, + CARL9170_STARTED, +}; + +#define CARL9170_NUM_TID 16 +#define WME_BA_BMP_SIZE 64 +#define CARL9170_TX_USER_RATE_TRIES 3 + +#define WME_AC_BE 2 +#define WME_AC_BK 3 +#define WME_AC_VI 1 +#define WME_AC_VO 0 + +#define TID_TO_WME_AC(_tid) \ + ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ + (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ + (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ + WME_AC_VO) + +#define SEQ_DIFF(_start, _seq) \ + (((_start) - (_seq)) & 0x0fff) +#define SEQ_PREV(_seq) \ + (((_seq) - 1) & 0x0fff) +#define SEQ_NEXT(_seq) \ + (((_seq) + 1) & 0x0fff) +#define BAW_WITHIN(_start, _bawsz, _seqno) \ + ((((_seqno) - (_start)) & 0xfff) < (_bawsz)) + +enum carl9170_tid_state { + CARL9170_TID_STATE_INVALID, + CARL9170_TID_STATE_KILLED, + CARL9170_TID_STATE_SHUTDOWN, + CARL9170_TID_STATE_SUSPEND, + CARL9170_TID_STATE_PROGRESS, + CARL9170_TID_STATE_IDLE, + CARL9170_TID_STATE_XMIT, +}; + +#define CARL9170_BAW_BITS (2 * WME_BA_BMP_SIZE) +#define CARL9170_BAW_SIZE (BITS_TO_LONGS(CARL9170_BAW_BITS)) +#define CARL9170_BAW_LEN (DIV_ROUND_UP(CARL9170_BAW_BITS, BITS_PER_BYTE)) + +struct carl9170_sta_tid { + /* must be the first entry! */ + struct list_head list; + + /* temporary list for RCU unlink procedure */ + struct list_head tmp_list; + + /* lock for the following data structures */ + spinlock_t lock; + + unsigned int counter; + enum carl9170_tid_state state; + u8 tid; /* TID number ( 0 - 15 ) */ + u16 max; /* max. AMPDU size */ + + u16 snx; /* awaiting _next_ frame */ + u16 hsn; /* highest _queued_ sequence */ + u16 bsn; /* base of the tx/agg bitmap */ + unsigned long bitmap[CARL9170_BAW_SIZE]; + + /* Preaggregation reorder queue */ + struct sk_buff_head queue; +}; + +#define CARL9170_QUEUE_TIMEOUT 256 +#define CARL9170_BUMP_QUEUE 1000 +#define CARL9170_TX_TIMEOUT 2500 +#define CARL9170_JANITOR_DELAY 128 +#define CARL9170_QUEUE_STUCK_TIMEOUT 5500 + +#define CARL9170_NUM_TX_AGG_MAX 30 + +/* + * Tradeoff between stability/latency and speed. + * + * AR9170_TXQ_DEPTH is devised by dividing the amount of available + * tx buffers with the size of a full ethernet frame + overhead. + * + * Naturally: The higher the limit, the faster the device CAN send. + * However, even a slight over-commitment at the wrong time and the + * hardware is doomed to send all already-queued frames at suboptimal + * rates. This in turn leads to an enourmous amount of unsuccessful + * retries => Latency goes up, whereas the throughput goes down. CRASH! + */ +#define CARL9170_NUM_TX_LIMIT_HARD ((AR9170_TXQ_DEPTH * 3) / 2) +#define CARL9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH) + +struct carl9170_tx_queue_stats { + unsigned int count; + unsigned int limit; + unsigned int len; +}; + +struct carl9170_vif { + unsigned int id; + struct ieee80211_vif *vif; +}; + +struct carl9170_vif_info { + struct list_head list; + bool active; + unsigned int id; + struct sk_buff *beacon; + bool enable_beacon; +}; + +#define AR9170_NUM_RX_URBS 16 +#define AR9170_NUM_RX_URBS_MUL 2 +#define AR9170_NUM_TX_URBS 8 +#define AR9170_NUM_RX_URBS_POOL (AR9170_NUM_RX_URBS_MUL * AR9170_NUM_RX_URBS) + +enum carl9170_device_features { + CARL9170_WPS_BUTTON = BIT(0), + CARL9170_ONE_LED = BIT(1), +}; + +#ifdef CONFIG_CARL9170_LEDS +struct ar9170; + +struct carl9170_led { + struct ar9170 *ar; + struct led_classdev l; + char name[32]; + unsigned int toggled; + bool last_state; + bool registered; +}; +#endif /* CONFIG_CARL9170_LEDS */ + +enum carl9170_restart_reasons { + CARL9170_RR_NO_REASON = 0, + CARL9170_RR_FATAL_FIRMWARE_ERROR, + CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS, + CARL9170_RR_WATCHDOG, + CARL9170_RR_STUCK_TX, + CARL9170_RR_SLOW_SYSTEM, + CARL9170_RR_COMMAND_TIMEOUT, + CARL9170_RR_TOO_MANY_PHY_ERRORS, + CARL9170_RR_LOST_RSP, + CARL9170_RR_INVALID_RSP, + CARL9170_RR_USER_REQUEST, + + __CARL9170_RR_LAST, +}; + +enum carl9170_erp_modes { + CARL9170_ERP_INVALID, + CARL9170_ERP_AUTO, + CARL9170_ERP_MAC80211, + CARL9170_ERP_OFF, + CARL9170_ERP_CTS, + CARL9170_ERP_RTS, + __CARL9170_ERP_NUM, +}; + +struct ar9170 { + struct ath_common common; + struct ieee80211_hw *hw; + struct mutex mutex; + enum carl9170_device_state state; + spinlock_t state_lock; + enum carl9170_restart_reasons last_reason; + bool registered; + + /* USB */ + struct usb_device *udev; + struct usb_interface *intf; + struct usb_anchor rx_anch; + struct usb_anchor rx_work; + struct usb_anchor rx_pool; + struct usb_anchor tx_wait; + struct usb_anchor tx_anch; + struct usb_anchor tx_cmd; + struct usb_anchor tx_err; + struct tasklet_struct usb_tasklet; + atomic_t tx_cmd_urbs; + atomic_t tx_anch_urbs; + atomic_t rx_anch_urbs; + atomic_t rx_work_urbs; + atomic_t rx_pool_urbs; + kernel_ulong_t features; + + /* firmware settings */ + struct completion fw_load_wait; + struct completion fw_boot_wait; + struct { + const struct carl9170fw_desc_head *desc; + const struct firmware *fw; + unsigned int offset; + unsigned int address; + unsigned int cmd_bufs; + unsigned int api_version; + unsigned int vif_num; + unsigned int err_counter; + unsigned int bug_counter; + u32 beacon_addr; + unsigned int beacon_max_len; + bool rx_stream; + bool tx_stream; + bool rx_filter; + unsigned int mem_blocks; + unsigned int mem_block_size; + unsigned int rx_size; + } fw; + + /* reset / stuck frames/queue detection */ + struct work_struct restart_work; + unsigned int restart_counter; + unsigned long queue_stop_timeout[__AR9170_NUM_TXQ]; + unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ]; + bool needs_full_reset; + atomic_t pending_restarts; + + /* interface mode settings */ + struct list_head vif_list; + unsigned long vif_bitmap; + unsigned int vifs; + struct carl9170_vif vif_priv[AR9170_MAX_VIRTUAL_MAC]; + + /* beaconing */ + spinlock_t beacon_lock; + unsigned int global_pretbtt; + unsigned int global_beacon_int; + struct carl9170_vif_info *beacon_iter; + unsigned int beacon_enabled; + + /* cryptographic engine */ + u64 usedkeys; + bool rx_software_decryption; + bool disable_offload; + + /* filter settings */ + u64 cur_mc_hash; + u32 cur_filter; + unsigned int filter_state; + unsigned int rx_filter_caps; + bool sniffer_enabled; + + /* MAC */ + enum carl9170_erp_modes erp_mode; + + /* PHY */ + struct ieee80211_channel *channel; + int noise[4]; + unsigned int chan_fail; + unsigned int total_chan_fail; + u8 heavy_clip; + u8 ht_settings; + + /* power calibration data */ + u8 power_5G_leg[4]; + u8 power_2G_cck[4]; + u8 power_2G_ofdm[4]; + u8 power_5G_ht20[8]; + u8 power_5G_ht40[8]; + u8 power_2G_ht20[8]; + u8 power_2G_ht40[8]; + +#ifdef CONFIG_CARL9170_LEDS + /* LED */ + struct delayed_work led_work; + struct carl9170_led leds[AR9170_NUM_LEDS]; +#endif /* CONFIG_CARL9170_LEDS */ + + /* qos queue settings */ + spinlock_t tx_stats_lock; + struct carl9170_tx_queue_stats tx_stats[__AR9170_NUM_TXQ]; + struct ieee80211_tx_queue_params edcf[5]; + struct completion tx_flush; + + /* CMD */ + int cmd_seq; + int readlen; + u8 *readbuf; + spinlock_t cmd_lock; + struct completion cmd_wait; + union { + __le32 cmd_buf[PAYLOAD_MAX + 1]; + struct carl9170_cmd cmd; + struct carl9170_rsp rsp; + }; + + /* statistics */ + unsigned int tx_dropped; + unsigned int tx_ack_failures; + unsigned int tx_fcs_errors; + unsigned int rx_dropped; + + /* EEPROM */ + struct ar9170_eeprom eeprom; + + /* tx queuing */ + struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; + struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; + struct delayed_work tx_janitor; + unsigned long tx_janitor_last_run; + bool tx_schedule; + + /* tx ampdu */ + struct work_struct ampdu_work; + spinlock_t tx_ampdu_list_lock; + struct carl9170_sta_tid *tx_ampdu_iter; + struct list_head tx_ampdu_list; + atomic_t tx_ampdu_upload; + atomic_t tx_ampdu_scheduler; + atomic_t tx_total_pending; + atomic_t tx_total_queued; + unsigned int tx_ampdu_list_len; + int current_density; + int current_factor; + bool tx_ampdu_schedule; + + /* internal memory management */ + spinlock_t mem_lock; + unsigned long *mem_bitmap; + atomic_t mem_free_blocks; + atomic_t mem_allocs; + + /* rxstream mpdu merge */ + struct ar9170_rx_head rx_plcp; + bool rx_has_plcp; + struct sk_buff *rx_failover; + int rx_failover_missing; + +#ifdef CONFIG_CARL9170_WPC + struct { + bool pbc_state; + struct input_dev *pbc; + char name[32]; + char phys[32]; + } wps; +#endif /* CONFIG_CARL9170_WPC */ + +#ifdef CONFIG_CARL9170_DEBUGFS + struct carl9170_debug debug; + struct dentry *debug_dir; +#endif /* CONFIG_CARL9170_DEBUGFS */ + + /* PSM */ + struct work_struct ps_work; + struct { + unsigned int dtim_counter; + unsigned long last_beacon; + unsigned long last_action; + unsigned long last_slept; + unsigned int sleep_ms; + unsigned int off_override; + bool state; + } ps; +}; + +enum carl9170_ps_off_override_reasons { + PS_OFF_VIF = BIT(0), + PS_OFF_BCN = BIT(1), + PS_OFF_5GHZ = BIT(2), +}; + +struct carl9170_ba_stats { + u8 ampdu_len; + u8 ampdu_ack_len; + bool clear; +}; + +struct carl9170_sta_info { + bool ht_sta; + unsigned int ampdu_max_len; + struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; + struct carl9170_ba_stats stats[CARL9170_NUM_TID]; +}; + +struct carl9170_tx_info { + unsigned long timeout; + struct ar9170 *ar; + struct kref ref; +}; + +#define CHK_DEV_STATE(a, s) (((struct ar9170 *)a)->state >= (s)) +#define IS_INITIALIZED(a) (CHK_DEV_STATE(a, CARL9170_STOPPED)) +#define IS_ACCEPTING_CMD(a) (CHK_DEV_STATE(a, CARL9170_IDLE)) +#define IS_STARTED(a) (CHK_DEV_STATE(a, CARL9170_STARTED)) + +static inline void __carl9170_set_state(struct ar9170 *ar, + enum carl9170_device_state newstate) +{ + ar->state = newstate; +} + +static inline void carl9170_set_state(struct ar9170 *ar, + enum carl9170_device_state newstate) +{ + unsigned long flags; + + spin_lock_irqsave(&ar->state_lock, flags); + __carl9170_set_state(ar, newstate); + spin_unlock_irqrestore(&ar->state_lock, flags); +} + +static inline void carl9170_set_state_when(struct ar9170 *ar, + enum carl9170_device_state min, enum carl9170_device_state newstate) +{ + unsigned long flags; + + spin_lock_irqsave(&ar->state_lock, flags); + if (CHK_DEV_STATE(ar, min)) + __carl9170_set_state(ar, newstate); + spin_unlock_irqrestore(&ar->state_lock, flags); +} + +/* exported interface */ +void *carl9170_alloc(size_t priv_size); +int carl9170_register(struct ar9170 *ar); +void carl9170_unregister(struct ar9170 *ar); +void carl9170_free(struct ar9170 *ar); +void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r); +void carl9170_ps_check(struct ar9170 *ar); + +/* USB back-end */ +int carl9170_usb_open(struct ar9170 *ar); +void carl9170_usb_stop(struct ar9170 *ar); +void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb); +void carl9170_usb_handle_tx_err(struct ar9170 *ar); +int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids, + u32 plen, void *payload, u32 rlen, void *resp); +int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, + const bool free_buf); +int carl9170_usb_restart(struct ar9170 *ar); +void carl9170_usb_reset(struct ar9170 *ar); + +/* MAC */ +int carl9170_init_mac(struct ar9170 *ar); +int carl9170_set_qos(struct ar9170 *ar); +int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hast); +int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id, + const u8 *mac); +int carl9170_set_operating_mode(struct ar9170 *ar); +int carl9170_set_beacon_timers(struct ar9170 *ar); +int carl9170_set_dyn_sifs_ack(struct ar9170 *ar); +int carl9170_set_rts_cts_rate(struct ar9170 *ar); +int carl9170_set_ampdu_settings(struct ar9170 *ar); +int carl9170_set_slot_time(struct ar9170 *ar); +int carl9170_set_mac_rates(struct ar9170 *ar); +int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); +int carl9170_update_beacon(struct ar9170 *ar, const bool submit); +int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, + const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); +int carl9170_disable_key(struct ar9170 *ar, const u8 id); + +/* RX */ +void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); +void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len); + +/* TX */ +int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb); +void carl9170_tx_janitor(struct work_struct *work); +void carl9170_tx_process_status(struct ar9170 *ar, + const struct carl9170_rsp *cmd); +void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, + const bool success); +void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb); +void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb); +void carl9170_tx_scheduler(struct ar9170 *ar); +void carl9170_tx_get_skb(struct sk_buff *skb); +int carl9170_tx_put_skb(struct sk_buff *skb); + +/* LEDs */ +#ifdef CONFIG_CARL9170_LEDS +int carl9170_led_register(struct ar9170 *ar); +void carl9170_led_unregister(struct ar9170 *ar); +#endif /* CONFIG_CARL9170_LEDS */ +int carl9170_led_init(struct ar9170 *ar); +int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state); + +/* PHY / RF */ +int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, + enum nl80211_channel_type bw, enum carl9170_rf_init_mode rfi); +int carl9170_get_noisefloor(struct ar9170 *ar); + +/* FW */ +int carl9170_parse_firmware(struct ar9170 *ar); +int carl9170_fw_fix_eeprom(struct ar9170 *ar); + +extern struct ieee80211_rate __carl9170_ratetable[]; +extern int modparam_noht; + +static inline struct ar9170 *carl9170_get_priv(struct carl9170_vif *carl_vif) +{ + return container_of(carl_vif, struct ar9170, + vif_priv[carl_vif->id]); +} + +static inline struct ieee80211_hdr *carl9170_get_hdr(struct sk_buff *skb) +{ + return (void *)((struct _carl9170_tx_superframe *) + skb->data)->frame_data; +} + +static inline u16 get_seq_h(struct ieee80211_hdr *hdr) +{ + return le16_to_cpu(hdr->seq_ctrl) >> 4; +} + +static inline u16 carl9170_get_seq(struct sk_buff *skb) +{ + return get_seq_h(carl9170_get_hdr(skb)); +} + +static inline u16 get_tid_h(struct ieee80211_hdr *hdr) +{ + return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; +} + +static inline u16 carl9170_get_tid(struct sk_buff *skb) +{ + return get_tid_h(carl9170_get_hdr(skb)); +} + +static inline struct ieee80211_vif * +carl9170_get_vif(struct carl9170_vif_info *priv) +{ + return container_of((void *)priv, struct ieee80211_vif, drv_priv); +} + +/* Protected by ar->mutex or RCU */ +static inline struct ieee80211_vif *carl9170_get_main_vif(struct ar9170 *ar) +{ + struct carl9170_vif_info *cvif; + + list_for_each_entry_rcu(cvif, &ar->vif_list, list) { + if (cvif->active) + return carl9170_get_vif(cvif); + } + + return NULL; +} + +static inline bool is_main_vif(struct ar9170 *ar, struct ieee80211_vif *vif) +{ + bool ret; + + rcu_read_lock(); + ret = (carl9170_get_main_vif(ar) == vif); + rcu_read_unlock(); + return ret; +} + +#endif /* __CARL9170_H */ diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c new file mode 100644 index 0000000000000000000000000000000000000000..c21f3364bfecbfc0ea860fb8b9e05d952895e4be --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/cmd.c @@ -0,0 +1,188 @@ +/* + * Atheros CARL9170 driver + * + * Basic HW register/memory/command access functions + * + * Copyright 2008, Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "carl9170.h" +#include "cmd.h" + +int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val) +{ + __le32 buf[2] = { + cpu_to_le32(reg), + cpu_to_le32(val), + }; + int err; + + err = carl9170_exec_cmd(ar, CARL9170_CMD_WREG, sizeof(buf), + (u8 *) buf, 0, NULL); + if (err) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "writing reg %#x " + "(val %#x) failed (%d)\n", reg, val, err); + } + } + return err; +} + +int carl9170_read_mreg(struct ar9170 *ar, const int nregs, + const u32 *regs, u32 *out) +{ + int i, err; + __le32 *offs, *res; + + /* abuse "out" for the register offsets, must be same length */ + offs = (__le32 *)out; + for (i = 0; i < nregs; i++) + offs[i] = cpu_to_le32(regs[i]); + + /* also use the same buffer for the input */ + res = (__le32 *)out; + + err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG, + 4 * nregs, (u8 *)offs, + 4 * nregs, (u8 *)res); + if (err) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "reading regs failed (%d)\n", + err); + } + return err; + } + + /* convert result to cpu endian */ + for (i = 0; i < nregs; i++) + out[i] = le32_to_cpu(res[i]); + + return 0; +} + +int carl9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val) +{ + return carl9170_read_mreg(ar, 1, ®, val); +} + +int carl9170_echo_test(struct ar9170 *ar, const u32 v) +{ + u32 echores; + int err; + + err = carl9170_exec_cmd(ar, CARL9170_CMD_ECHO, + 4, (u8 *)&v, + 4, (u8 *)&echores); + if (err) + return err; + + if (v != echores) { + wiphy_info(ar->hw->wiphy, "wrong echo %x != %x", v, echores); + return -EINVAL; + } + + return 0; +} + +struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, + const enum carl9170_cmd_oids cmd, const unsigned int len) +{ + struct carl9170_cmd *tmp; + + tmp = kzalloc(sizeof(struct carl9170_cmd_head) + len, GFP_ATOMIC); + if (tmp) { + tmp->hdr.cmd = cmd; + tmp->hdr.len = len; + } + + return tmp; +} + +int carl9170_reboot(struct ar9170 *ar) +{ + struct carl9170_cmd *cmd; + int err; + + cmd = carl9170_cmd_buf(ar, CARL9170_CMD_REBOOT_ASYNC, 0); + if (!cmd) + return -ENOMEM; + + err = __carl9170_exec_cmd(ar, (struct carl9170_cmd *)cmd, true); + return err; +} + +int carl9170_mac_reset(struct ar9170 *ar) +{ + return carl9170_exec_cmd(ar, CARL9170_CMD_SWRST, + 0, NULL, 0, NULL); +} + +int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id, + const u32 mode, const u32 addr, const u32 len) +{ + struct carl9170_cmd *cmd; + + cmd = carl9170_cmd_buf(ar, CARL9170_CMD_BCN_CTRL_ASYNC, + sizeof(struct carl9170_bcn_ctrl_cmd)); + if (!cmd) + return -ENOMEM; + + cmd->bcn_ctrl.vif_id = cpu_to_le32(vif_id); + cmd->bcn_ctrl.mode = cpu_to_le32(mode); + cmd->bcn_ctrl.bcn_addr = cpu_to_le32(addr); + cmd->bcn_ctrl.bcn_len = cpu_to_le32(len); + + return __carl9170_exec_cmd(ar, cmd, true); +} + +int carl9170_powersave(struct ar9170 *ar, const bool ps) +{ + struct carl9170_cmd *cmd; + u32 state; + + cmd = carl9170_cmd_buf(ar, CARL9170_CMD_PSM_ASYNC, + sizeof(struct carl9170_psm)); + if (!cmd) + return -ENOMEM; + + if (ps) { + /* Sleep until next TBTT */ + state = CARL9170_PSM_SLEEP | 1; + } else { + /* wake up immediately */ + state = 1; + } + + cmd->psm.state = cpu_to_le32(state); + return __carl9170_exec_cmd(ar, cmd, true); +} diff --git a/drivers/net/wireless/ath/carl9170/cmd.h b/drivers/net/wireless/ath/carl9170/cmd.h new file mode 100644 index 0000000000000000000000000000000000000000..f78728c38294e07c6098853e8fb902f3c24d9bb7 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/cmd.h @@ -0,0 +1,168 @@ +/* + * Atheros CARL9170 driver + * + * Basic HW register/memory/command access functions + * + * Copyright 2008, Johannes Berg + * Copyright 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __CMD_H +#define __CMD_H + +#include "carl9170.h" + +/* basic HW access */ +int carl9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val); +int carl9170_read_reg(struct ar9170 *ar, const u32 reg, u32 *val); +int carl9170_read_mreg(struct ar9170 *ar, const int nregs, + const u32 *regs, u32 *out); +int carl9170_echo_test(struct ar9170 *ar, u32 v); +int carl9170_reboot(struct ar9170 *ar); +int carl9170_mac_reset(struct ar9170 *ar); +int carl9170_powersave(struct ar9170 *ar, const bool power_on); +int carl9170_bcn_ctrl(struct ar9170 *ar, const unsigned int vif_id, + const u32 mode, const u32 addr, const u32 len); + +static inline int carl9170_flush_cab(struct ar9170 *ar, + const unsigned int vif_id) +{ + return carl9170_bcn_ctrl(ar, vif_id, CARL9170_BCN_CTRL_DRAIN, 0, 0); +} + +static inline int carl9170_rx_filter(struct ar9170 *ar, + const unsigned int _rx_filter) +{ + __le32 rx_filter = cpu_to_le32(_rx_filter); + + return carl9170_exec_cmd(ar, CARL9170_CMD_RX_FILTER, + sizeof(rx_filter), (u8 *)&rx_filter, + 0, NULL); +} + +struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, + const enum carl9170_cmd_oids cmd, const unsigned int len); + +/* + * Macros to facilitate writing multiple registers in a single + * write-combining USB command. Note that when the first group + * fails the whole thing will fail without any others attempted, + * but you won't know which write in the group failed. + */ +#define carl9170_regwrite_begin(ar) \ +do { \ + int __nreg = 0, __err = 0; \ + struct ar9170 *__ar = ar; + +#define carl9170_regwrite(r, v) do { \ + __ar->cmd_buf[2 * __nreg + 1] = cpu_to_le32(r); \ + __ar->cmd_buf[2 * __nreg + 2] = cpu_to_le32(v); \ + __nreg++; \ + if ((__nreg >= PAYLOAD_MAX/2)) { \ + if (IS_ACCEPTING_CMD(__ar)) \ + __err = carl9170_exec_cmd(__ar, \ + CARL9170_CMD_WREG, 8 * __nreg, \ + (u8 *) &__ar->cmd_buf[1], 0, NULL); \ + else \ + goto __regwrite_out; \ + \ + __nreg = 0; \ + if (__err) \ + goto __regwrite_out; \ + } \ +} while (0) + +#define carl9170_regwrite_finish() \ +__regwrite_out : \ + if (__err == 0 && __nreg) { \ + if (IS_ACCEPTING_CMD(__ar)) \ + __err = carl9170_exec_cmd(__ar, \ + CARL9170_CMD_WREG, 8 * __nreg, \ + (u8 *) &__ar->cmd_buf[1], 0, NULL); \ + __nreg = 0; \ + } + +#define carl9170_regwrite_result() \ + __err; \ +} while (0); + + +#define carl9170_async_get_buf() \ +do { \ + __cmd = carl9170_cmd_buf(__carl, CARL9170_CMD_WREG_ASYNC, \ + CARL9170_MAX_CMD_PAYLOAD_LEN); \ + if (__cmd == NULL) { \ + __err = -ENOMEM; \ + goto __async_regwrite_out; \ + } \ +} while (0); + +#define carl9170_async_regwrite_begin(carl) \ +do { \ + int __nreg = 0, __err = 0; \ + struct ar9170 *__carl = carl; \ + struct carl9170_cmd *__cmd; \ + carl9170_async_get_buf(); \ + +#define carl9170_async_regwrite(r, v) do { \ + __cmd->wreg.regs[__nreg].addr = cpu_to_le32(r); \ + __cmd->wreg.regs[__nreg].val = cpu_to_le32(v); \ + __nreg++; \ + if ((__nreg >= PAYLOAD_MAX/2)) { \ + if (IS_ACCEPTING_CMD(__carl)) { \ + __cmd->hdr.len = 8 * __nreg; \ + __err = __carl9170_exec_cmd(__carl, __cmd, true);\ + __cmd = NULL; \ + carl9170_async_get_buf(); \ + } else { \ + goto __async_regwrite_out; \ + } \ + __nreg = 0; \ + if (__err) \ + goto __async_regwrite_out; \ + } \ +} while (0) + +#define carl9170_async_regwrite_finish() \ +__async_regwrite_out : \ + if (__err == 0 && __nreg) { \ + __cmd->hdr.len = 8 * __nreg; \ + if (IS_ACCEPTING_CMD(__carl)) \ + __err = __carl9170_exec_cmd(__carl, __cmd, true);\ + __nreg = 0; \ + } + +#define carl9170_async_regwrite_result() \ + __err; \ +} while (0); + +#endif /* __CMD_H */ diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c new file mode 100644 index 0000000000000000000000000000000000000000..0ac1124c2a0b74b3bcaa09eb7174b4e2b599f4e7 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/debug.c @@ -0,0 +1,902 @@ +/* + * Atheros CARL9170 driver + * + * debug(fs) probing + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2008-2009 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "carl9170.h" +#include "cmd.h" + +#define ADD(buf, off, max, fmt, args...) \ + off += snprintf(&buf[off], max - off, fmt, ##args); + +static int carl9170_debugfs_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + return 0; +} + +struct carl9170_debugfs_fops { + unsigned int read_bufsize; + mode_t attr; + char *(*read)(struct ar9170 *ar, char *buf, size_t bufsize, + ssize_t *len); + ssize_t (*write)(struct ar9170 *aru, const char *buf, size_t size); + const struct file_operations fops; + + enum carl9170_device_state req_dev_state; +}; + +static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + struct carl9170_debugfs_fops *dfops; + struct ar9170 *ar; + char *buf = NULL, *res_buf = NULL; + ssize_t ret = 0; + int err = 0; + + if (!count) + return 0; + + ar = file->private_data; + + if (!ar) + return -ENODEV; + dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); + + if (!dfops->read) + return -ENOSYS; + + if (dfops->read_bufsize) { + buf = vmalloc(dfops->read_bufsize); + if (!buf) + return -ENOMEM; + } + + mutex_lock(&ar->mutex); + if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) { + err = -ENODEV; + res_buf = buf; + goto out_free; + } + + res_buf = dfops->read(ar, buf, dfops->read_bufsize, &ret); + + if (ret > 0) + err = simple_read_from_buffer(userbuf, count, ppos, + res_buf, ret); + else + err = ret; + + WARN_ON_ONCE(dfops->read_bufsize && (res_buf != buf)); + +out_free: + vfree(res_buf); + mutex_unlock(&ar->mutex); + return err; +} + +static ssize_t carl9170_debugfs_write(struct file *file, + const char __user *userbuf, size_t count, loff_t *ppos) +{ + struct carl9170_debugfs_fops *dfops; + struct ar9170 *ar; + char *buf = NULL; + int err = 0; + + if (!count) + return 0; + + if (count > PAGE_SIZE) + return -E2BIG; + + ar = file->private_data; + + if (!ar) + return -ENODEV; + dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops); + + if (!dfops->write) + return -ENOSYS; + + buf = vmalloc(count); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, userbuf, count)) { + err = -EFAULT; + goto out_free; + } + + if (mutex_trylock(&ar->mutex) == 0) { + err = -EAGAIN; + goto out_free; + } + + if (!CHK_DEV_STATE(ar, dfops->req_dev_state)) { + err = -ENODEV; + goto out_unlock; + } + + err = dfops->write(ar, buf, count); + if (err) + goto out_unlock; + +out_unlock: + mutex_unlock(&ar->mutex); + +out_free: + vfree(buf); + return err; +} + +#define __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \ + _attr, _dstate) \ +static const struct carl9170_debugfs_fops carl_debugfs_##name ##_ops = {\ + .read_bufsize = _read_bufsize, \ + .read = _read, \ + .write = _write, \ + .attr = _attr, \ + .req_dev_state = _dstate, \ + .fops = { \ + .open = carl9170_debugfs_open, \ + .read = carl9170_debugfs_read, \ + .write = carl9170_debugfs_write, \ + .owner = THIS_MODULE \ + }, \ +} + +#define DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, _attr) \ + __DEBUGFS_DECLARE_FILE(name, _read, _write, _read_bufsize, \ + _attr, CARL9170_STARTED) \ + +#define DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) \ + DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ + NULL, _read_bufsize, S_IRUSR) + +#define DEBUGFS_DECLARE_WO_FILE(name) \ + DEBUGFS_DECLARE_FILE(name, NULL, carl9170_debugfs_##name ##_write,\ + 0, S_IWUSR) + +#define DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize) \ + DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ + carl9170_debugfs_##name ##_write, \ + _read_bufsize, S_IRUSR | S_IWUSR) + +#define __DEBUGFS_DECLARE_RW_FILE(name, _read_bufsize, _dstate) \ + __DEBUGFS_DECLARE_FILE(name, carl9170_debugfs_##name ##_read, \ + carl9170_debugfs_##name ##_write, \ + _read_bufsize, S_IRUSR | S_IWUSR, _dstate) + +#define DEBUGFS_READONLY_FILE(name, _read_bufsize, fmt, value...) \ +static char *carl9170_debugfs_ ##name ## _read(struct ar9170 *ar, \ + char *buf, size_t buf_size,\ + ssize_t *len) \ +{ \ + ADD(buf, *len, buf_size, fmt "\n", ##value); \ + return buf; \ +} \ +DEBUGFS_DECLARE_RO_FILE(name, _read_bufsize) + +static char *carl9170_debugfs_mem_usage_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + ADD(buf, *len, bufsize, "jar: ["); + + spin_lock_bh(&ar->mem_lock); + + *len += bitmap_scnprintf(&buf[*len], bufsize - *len, + ar->mem_bitmap, ar->fw.mem_blocks); + + ADD(buf, *len, bufsize, "]\n"); + + ADD(buf, *len, bufsize, "cookies: used:%3d / total:%3d, allocs:%d\n", + bitmap_weight(ar->mem_bitmap, ar->fw.mem_blocks), + ar->fw.mem_blocks, atomic_read(&ar->mem_allocs)); + + ADD(buf, *len, bufsize, "memory: free:%3d (%3d KiB) / total:%3d KiB)\n", + atomic_read(&ar->mem_free_blocks), + (atomic_read(&ar->mem_free_blocks) * ar->fw.mem_block_size) / 1024, + (ar->fw.mem_blocks * ar->fw.mem_block_size) / 1024); + + spin_unlock_bh(&ar->mem_lock); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(mem_usage, 512); + +static char *carl9170_debugfs_qos_stat_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + ADD(buf, *len, bufsize, "%s QoS AC\n", modparam_noht ? "Hardware" : + "Software"); + + ADD(buf, *len, bufsize, "[ VO VI " + " BE BK ]\n"); + + spin_lock_bh(&ar->tx_stats_lock); + ADD(buf, *len, bufsize, "[length/limit length/limit " + "length/limit length/limit ]\n" + "[ %3d/%3d %3d/%3d " + " %3d/%3d %3d/%3d ]\n\n", + ar->tx_stats[0].len, ar->tx_stats[0].limit, + ar->tx_stats[1].len, ar->tx_stats[1].limit, + ar->tx_stats[2].len, ar->tx_stats[2].limit, + ar->tx_stats[3].len, ar->tx_stats[3].limit); + + ADD(buf, *len, bufsize, "[ total total " + " total total ]\n" + "[%10d %10d %10d %10d ]\n\n", + ar->tx_stats[0].count, ar->tx_stats[1].count, + ar->tx_stats[2].count, ar->tx_stats[3].count); + + spin_unlock_bh(&ar->tx_stats_lock); + + ADD(buf, *len, bufsize, "[ pend/waittx pend/waittx " + " pend/waittx pend/waittx]\n" + "[ %3d/%3d %3d/%3d " + " %3d/%3d %3d/%3d ]\n\n", + skb_queue_len(&ar->tx_pending[0]), + skb_queue_len(&ar->tx_status[0]), + skb_queue_len(&ar->tx_pending[1]), + skb_queue_len(&ar->tx_status[1]), + skb_queue_len(&ar->tx_pending[2]), + skb_queue_len(&ar->tx_status[2]), + skb_queue_len(&ar->tx_pending[3]), + skb_queue_len(&ar->tx_status[3])); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(qos_stat, 512); + +static void carl9170_debugfs_format_frame(struct ar9170 *ar, + struct sk_buff *skb, const char *prefix, char *buf, + ssize_t *off, ssize_t bufsize) +{ + struct _carl9170_tx_superframe *txc = (void *) skb->data; + struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); + struct carl9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; + struct ieee80211_hdr *hdr = (void *) txc->frame_data; + + ADD(buf, *off, bufsize, "%s %p, c:%2x, DA:%pM, sq:%4d, mc:%.4x, " + "pc:%.8x, to:%d ms\n", prefix, skb, txc->s.cookie, + ieee80211_get_DA(hdr), get_seq_h(hdr), + le16_to_cpu(txc->f.mac_control), le32_to_cpu(txc->f.phy_control), + jiffies_to_msecs(jiffies - arinfo->timeout)); +} + + +static char *carl9170_debugfs_ampdu_state_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + struct carl9170_sta_tid *iter; + struct sk_buff *skb; + int cnt = 0, fc; + int offset; + + rcu_read_lock(); + list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { + + spin_lock_bh(&iter->lock); + ADD(buf, *len, bufsize, "Entry: #%2d TID:%1d, BSN:%4d, " + "SNX:%4d, HSN:%4d, BAW:%2d, state:%1d, toggles:%d\n", + cnt, iter->tid, iter->bsn, iter->snx, iter->hsn, + iter->max, iter->state, iter->counter); + + ADD(buf, *len, bufsize, "\tWindow: ["); + + *len += bitmap_scnprintf(&buf[*len], bufsize - *len, + iter->bitmap, CARL9170_BAW_BITS); + +#define BM_STR_OFF(offset) \ + ((CARL9170_BAW_BITS - (offset) - 1) / 4 + \ + (CARL9170_BAW_BITS - (offset) - 1) / 32 + 1) + + ADD(buf, *len, bufsize, ",W]\n"); + + offset = BM_STR_OFF(0); + ADD(buf, *len, bufsize, "\tBase Seq: %*s\n", offset, "T"); + + offset = BM_STR_OFF(SEQ_DIFF(iter->snx, iter->bsn)); + ADD(buf, *len, bufsize, "\tNext Seq: %*s\n", offset, "W"); + + offset = BM_STR_OFF(((int)iter->hsn - (int)iter->bsn) % + CARL9170_BAW_BITS); + ADD(buf, *len, bufsize, "\tLast Seq: %*s\n", offset, "N"); + + ADD(buf, *len, bufsize, "\tPre-Aggregation reorder buffer: " + " currently queued:%d\n", skb_queue_len(&iter->queue)); + + fc = 0; + skb_queue_walk(&iter->queue, skb) { + char prefix[32]; + + snprintf(prefix, sizeof(prefix), "\t\t%3d :", fc); + carl9170_debugfs_format_frame(ar, skb, prefix, buf, + len, bufsize); + + fc++; + } + spin_unlock_bh(&iter->lock); + cnt++; + } + rcu_read_unlock(); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(ampdu_state, 8000); + +static void carl9170_debugfs_queue_dump(struct ar9170 *ar, char *buf, + ssize_t *len, size_t bufsize, struct sk_buff_head *queue) +{ + struct sk_buff *skb; + char prefix[16]; + int fc = 0; + + spin_lock_bh(&queue->lock); + skb_queue_walk(queue, skb) { + snprintf(prefix, sizeof(prefix), "%3d :", fc); + carl9170_debugfs_format_frame(ar, skb, prefix, buf, + len, bufsize); + fc++; + } + spin_unlock_bh(&queue->lock); +} + +#define DEBUGFS_QUEUE_DUMP(q, qi) \ +static char *carl9170_debugfs_##q ##_##qi ##_read(struct ar9170 *ar, \ + char *buf, size_t bufsize, ssize_t *len) \ +{ \ + carl9170_debugfs_queue_dump(ar, buf, len, bufsize, &ar->q[qi]); \ + return buf; \ +} \ +DEBUGFS_DECLARE_RO_FILE(q##_##qi, 8000); + +static char *carl9170_debugfs_sta_psm_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + ADD(buf, *len, bufsize, "psm state: %s\n", (ar->ps.off_override ? + "FORCE CAM" : (ar->ps.state ? "PSM" : "CAM"))); + + ADD(buf, *len, bufsize, "sleep duration: %d ms.\n", ar->ps.sleep_ms); + ADD(buf, *len, bufsize, "last power-state transition: %d ms ago.\n", + jiffies_to_msecs(jiffies - ar->ps.last_action)); + ADD(buf, *len, bufsize, "last CAM->PSM transition: %d ms ago.\n", + jiffies_to_msecs(jiffies - ar->ps.last_slept)); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(sta_psm, 160); + +static char *carl9170_debugfs_tx_stuck_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + int i; + + for (i = 0; i < ar->hw->queues; i++) { + ADD(buf, *len, bufsize, "TX queue [%d]: %10d max:%10d ms.\n", + i, ieee80211_queue_stopped(ar->hw, i) ? + jiffies_to_msecs(jiffies - ar->queue_stop_timeout[i]) : 0, + jiffies_to_msecs(ar->max_queue_stop_timeout[i])); + + ar->max_queue_stop_timeout[i] = 0; + } + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(tx_stuck, 180); + +static char *carl9170_debugfs_phy_noise_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + int err; + + err = carl9170_get_noisefloor(ar); + if (err) { + *len = err; + return buf; + } + + ADD(buf, *len, bufsize, "Chain 0: %10d dBm, ext. chan.:%10d dBm\n", + ar->noise[0], ar->noise[2]); + ADD(buf, *len, bufsize, "Chain 2: %10d dBm, ext. chan.:%10d dBm\n", + ar->noise[1], ar->noise[3]); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(phy_noise, 180); + +static char *carl9170_debugfs_vif_dump_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *len) +{ + struct carl9170_vif_info *iter; + int i = 0; + + ADD(buf, *len, bufsize, "registered VIFs:%d \\ %d\n", + ar->vifs, ar->fw.vif_num); + + ADD(buf, *len, bufsize, "VIF bitmap: ["); + + *len += bitmap_scnprintf(&buf[*len], bufsize - *len, + &ar->vif_bitmap, ar->fw.vif_num); + + ADD(buf, *len, bufsize, "]\n"); + + rcu_read_lock(); + list_for_each_entry_rcu(iter, &ar->vif_list, list) { + struct ieee80211_vif *vif = carl9170_get_vif(iter); + ADD(buf, *len, bufsize, "\t%d = [%s VIF, id:%d, type:%x " + " mac:%pM %s]\n", i, (carl9170_get_main_vif(ar) == vif ? + "Master" : " Slave"), iter->id, vif->type, vif->addr, + iter->enable_beacon ? "beaconing " : ""); + i++; + } + rcu_read_unlock(); + + return buf; +} +DEBUGFS_DECLARE_RO_FILE(vif_dump, 8000); + +#define UPDATE_COUNTER(ar, name) ({ \ + u32 __tmp[ARRAY_SIZE(name##_regs)]; \ + unsigned int __i, __err = -ENODEV; \ + \ + for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \ + __tmp[__i] = name##_regs[__i].reg; \ + ar->debug.stats.name##_counter[__i] = 0; \ + } \ + \ + if (IS_STARTED(ar)) \ + __err = carl9170_read_mreg(ar, ARRAY_SIZE(name##_regs), \ + __tmp, ar->debug.stats.name##_counter); \ + (__err); }) + +#define TALLY_SUM_UP(ar, name) do { \ + unsigned int __i; \ + \ + for (__i = 0; __i < ARRAY_SIZE(name##_regs); __i++) { \ + ar->debug.stats.name##_sum[__i] += \ + ar->debug.stats.name##_counter[__i]; \ + } \ +} while (0) + +#define DEBUGFS_HW_TALLY_FILE(name, f) \ +static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \ + char *dum, size_t bufsize, ssize_t *ret) \ +{ \ + char *buf; \ + int i, max_len, err; \ + \ + max_len = ARRAY_SIZE(name##_regs) * 80; \ + buf = vmalloc(max_len); \ + if (!buf) \ + return NULL; \ + \ + err = UPDATE_COUNTER(ar, name); \ + if (err) { \ + *ret = err; \ + return buf; \ + } \ + \ + TALLY_SUM_UP(ar, name); \ + \ + for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \ + ADD(buf, *ret, max_len, "%22s = %" f "[+%" f "]\n", \ + name##_regs[i].nreg, ar->debug.stats.name ##_sum[i],\ + ar->debug.stats.name ##_counter[i]); \ + } \ + \ + return buf; \ +} \ +DEBUGFS_DECLARE_RO_FILE(name, 0); + +#define DEBUGFS_HW_REG_FILE(name, f) \ +static char *carl9170_debugfs_##name ## _read(struct ar9170 *ar, \ + char *dum, size_t bufsize, ssize_t *ret) \ +{ \ + char *buf; \ + int i, max_len, err; \ + \ + max_len = ARRAY_SIZE(name##_regs) * 80; \ + buf = vmalloc(max_len); \ + if (!buf) \ + return NULL; \ + \ + err = UPDATE_COUNTER(ar, name); \ + if (err) { \ + *ret = err; \ + return buf; \ + } \ + \ + for (i = 0; i < ARRAY_SIZE(name##_regs); i++) { \ + ADD(buf, *ret, max_len, "%22s = %" f "\n", \ + name##_regs[i].nreg, \ + ar->debug.stats.name##_counter[i]); \ + } \ + \ + return buf; \ +} \ +DEBUGFS_DECLARE_RO_FILE(name, 0); + +static ssize_t carl9170_debugfs_hw_ioread32_write(struct ar9170 *ar, + const char *buf, size_t count) +{ + int err = 0, i, n = 0, max_len = 32, res; + unsigned int reg, tmp; + + if (!count) + return 0; + + if (count > max_len) + return -E2BIG; + + res = sscanf(buf, "0x%X %d", ®, &n); + if (res < 1) { + err = -EINVAL; + goto out; + } + + if (res == 1) + n = 1; + + if (n > 15) { + err = -EMSGSIZE; + goto out; + } + + if ((reg >= 0x280000) || ((reg + (n << 2)) >= 0x280000)) { + err = -EADDRNOTAVAIL; + goto out; + } + + if (reg & 3) { + err = -EINVAL; + goto out; + } + + for (i = 0; i < n; i++) { + err = carl9170_read_reg(ar, reg + (i << 2), &tmp); + if (err) + goto out; + + ar->debug.ring[ar->debug.ring_tail].reg = reg + (i << 2); + ar->debug.ring[ar->debug.ring_tail].value = tmp; + ar->debug.ring_tail++; + ar->debug.ring_tail %= CARL9170_DEBUG_RING_SIZE; + } + +out: + return err ? err : count; +} + +static char *carl9170_debugfs_hw_ioread32_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *ret) +{ + int i = 0; + + while (ar->debug.ring_head != ar->debug.ring_tail) { + ADD(buf, *ret, bufsize, "%.8x = %.8x\n", + ar->debug.ring[ar->debug.ring_head].reg, + ar->debug.ring[ar->debug.ring_head].value); + + ar->debug.ring_head++; + ar->debug.ring_head %= CARL9170_DEBUG_RING_SIZE; + + if (i++ == 64) + break; + } + ar->debug.ring_head = ar->debug.ring_tail; + return buf; +} +DEBUGFS_DECLARE_RW_FILE(hw_ioread32, CARL9170_DEBUG_RING_SIZE * 40); + +static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf, + size_t count) +{ + int err; + + if (count < 1) + return -EINVAL; + + switch (buf[0]) { + case 'F': + ar->needs_full_reset = true; + break; + + case 'R': + if (!IS_STARTED(ar)) { + err = -EAGAIN; + goto out; + } + + ar->needs_full_reset = false; + break; + + case 'M': + err = carl9170_mac_reset(ar); + if (err < 0) + count = err; + + goto out; + + case 'P': + err = carl9170_set_channel(ar, ar->hw->conf.channel, + ar->hw->conf.channel_type, CARL9170_RFI_COLD); + if (err < 0) + count = err; + + goto out; + + default: + return -EINVAL; + } + + carl9170_restart(ar, CARL9170_RR_USER_REQUEST); + +out: + return count; +} + +static char *carl9170_debugfs_bug_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *ret) +{ + ADD(buf, *ret, bufsize, "[P]hy reinit, [R]estart, [F]ull usb reset, " + "[M]ac reset\n"); + ADD(buf, *ret, bufsize, "firmware restarts:%d, last reason:%d\n", + ar->restart_counter, ar->last_reason); + ADD(buf, *ret, bufsize, "phy reinit errors:%d (%d)\n", + ar->total_chan_fail, ar->chan_fail); + ADD(buf, *ret, bufsize, "reported firmware errors:%d\n", + ar->fw.err_counter); + ADD(buf, *ret, bufsize, "reported firmware BUGs:%d\n", + ar->fw.bug_counter); + ADD(buf, *ret, bufsize, "pending restart requests:%d\n", + atomic_read(&ar->pending_restarts)); + return buf; +} +__DEBUGFS_DECLARE_RW_FILE(bug, 400, CARL9170_STOPPED); + +static const char *erp_modes[] = { + [CARL9170_ERP_INVALID] = "INVALID", + [CARL9170_ERP_AUTO] = "Automatic", + [CARL9170_ERP_MAC80211] = "Set by MAC80211", + [CARL9170_ERP_OFF] = "Force Off", + [CARL9170_ERP_RTS] = "Force RTS", + [CARL9170_ERP_CTS] = "Force CTS" +}; + +static char *carl9170_debugfs_erp_read(struct ar9170 *ar, char *buf, + size_t bufsize, ssize_t *ret) +{ + ADD(buf, *ret, bufsize, "ERP Setting: (%d) -> %s\n", ar->erp_mode, + erp_modes[ar->erp_mode]); + return buf; +} + +static ssize_t carl9170_debugfs_erp_write(struct ar9170 *ar, const char *buf, + size_t count) +{ + int res, val; + + if (count < 1) + return -EINVAL; + + res = sscanf(buf, "%d", &val); + if (res != 1) + return -EINVAL; + + if (!((val > CARL9170_ERP_INVALID) && + (val < __CARL9170_ERP_NUM))) + return -EINVAL; + + ar->erp_mode = val; + return count; +} + +DEBUGFS_DECLARE_RW_FILE(erp, 80); + +static ssize_t carl9170_debugfs_hw_iowrite32_write(struct ar9170 *ar, + const char *buf, size_t count) +{ + int err = 0, max_len = 22, res; + u32 reg, val; + + if (!count) + return 0; + + if (count > max_len) + return -E2BIG; + + res = sscanf(buf, "0x%X 0x%X", ®, &val); + if (res != 2) { + err = -EINVAL; + goto out; + } + + if (reg <= 0x100000 || reg >= 0x280000) { + err = -EADDRNOTAVAIL; + goto out; + } + + if (reg & 3) { + err = -EINVAL; + goto out; + } + + err = carl9170_write_reg(ar, reg, val); + if (err) + goto out; + +out: + return err ? err : count; +} +DEBUGFS_DECLARE_WO_FILE(hw_iowrite32); + +DEBUGFS_HW_TALLY_FILE(hw_tx_tally, "u"); +DEBUGFS_HW_TALLY_FILE(hw_rx_tally, "u"); +DEBUGFS_HW_TALLY_FILE(hw_phy_errors, "u"); +DEBUGFS_HW_REG_FILE(hw_wlan_queue, ".8x"); +DEBUGFS_HW_REG_FILE(hw_pta_queue, ".8x"); +DEBUGFS_HW_REG_FILE(hw_ampdu_info, ".8x"); +DEBUGFS_QUEUE_DUMP(tx_status, 0); +DEBUGFS_QUEUE_DUMP(tx_status, 1); +DEBUGFS_QUEUE_DUMP(tx_status, 2); +DEBUGFS_QUEUE_DUMP(tx_status, 3); +DEBUGFS_QUEUE_DUMP(tx_pending, 0); +DEBUGFS_QUEUE_DUMP(tx_pending, 1); +DEBUGFS_QUEUE_DUMP(tx_pending, 2); +DEBUGFS_QUEUE_DUMP(tx_pending, 3); +DEBUGFS_READONLY_FILE(usb_tx_anch_urbs, 20, "%d", + atomic_read(&ar->tx_anch_urbs)); +DEBUGFS_READONLY_FILE(usb_rx_anch_urbs, 20, "%d", + atomic_read(&ar->rx_anch_urbs)); +DEBUGFS_READONLY_FILE(usb_rx_work_urbs, 20, "%d", + atomic_read(&ar->rx_work_urbs)); +DEBUGFS_READONLY_FILE(usb_rx_pool_urbs, 20, "%d", + atomic_read(&ar->rx_pool_urbs)); + +DEBUGFS_READONLY_FILE(tx_total_queued, 20, "%d", + atomic_read(&ar->tx_total_queued)); +DEBUGFS_READONLY_FILE(tx_ampdu_scheduler, 20, "%d", + atomic_read(&ar->tx_ampdu_scheduler)); + +DEBUGFS_READONLY_FILE(tx_total_pending, 20, "%d", + atomic_read(&ar->tx_total_pending)); + +DEBUGFS_READONLY_FILE(tx_ampdu_list_len, 20, "%d", + ar->tx_ampdu_list_len); + +DEBUGFS_READONLY_FILE(tx_ampdu_upload, 20, "%d", + atomic_read(&ar->tx_ampdu_upload)); + +DEBUGFS_READONLY_FILE(tx_janitor_last_run, 64, "last run:%d ms ago", + jiffies_to_msecs(jiffies - ar->tx_janitor_last_run)); + +DEBUGFS_READONLY_FILE(tx_dropped, 20, "%d", ar->tx_dropped); + +DEBUGFS_READONLY_FILE(rx_dropped, 20, "%d", ar->rx_dropped); + +DEBUGFS_READONLY_FILE(sniffer_enabled, 20, "%d", ar->sniffer_enabled); +DEBUGFS_READONLY_FILE(rx_software_decryption, 20, "%d", + ar->rx_software_decryption); +DEBUGFS_READONLY_FILE(ampdu_factor, 20, "%d", + ar->current_factor); +DEBUGFS_READONLY_FILE(ampdu_density, 20, "%d", + ar->current_density); + +DEBUGFS_READONLY_FILE(beacon_int, 20, "%d TU", ar->global_beacon_int); +DEBUGFS_READONLY_FILE(pretbtt, 20, "%d TU", ar->global_pretbtt); + +void carl9170_debugfs_register(struct ar9170 *ar) +{ + ar->debug_dir = debugfs_create_dir(KBUILD_MODNAME, + ar->hw->wiphy->debugfsdir); + +#define DEBUGFS_ADD(name) \ + debugfs_create_file(#name, carl_debugfs_##name ##_ops.attr, \ + ar->debug_dir, ar, \ + &carl_debugfs_##name ## _ops.fops); + + DEBUGFS_ADD(usb_tx_anch_urbs); + DEBUGFS_ADD(usb_rx_pool_urbs); + DEBUGFS_ADD(usb_rx_anch_urbs); + DEBUGFS_ADD(usb_rx_work_urbs); + + DEBUGFS_ADD(tx_total_queued); + DEBUGFS_ADD(tx_total_pending); + DEBUGFS_ADD(tx_dropped); + DEBUGFS_ADD(tx_stuck); + DEBUGFS_ADD(tx_ampdu_upload); + DEBUGFS_ADD(tx_ampdu_scheduler); + DEBUGFS_ADD(tx_ampdu_list_len); + + DEBUGFS_ADD(rx_dropped); + DEBUGFS_ADD(sniffer_enabled); + DEBUGFS_ADD(rx_software_decryption); + + DEBUGFS_ADD(mem_usage); + DEBUGFS_ADD(qos_stat); + DEBUGFS_ADD(sta_psm); + DEBUGFS_ADD(ampdu_state); + + DEBUGFS_ADD(hw_tx_tally); + DEBUGFS_ADD(hw_rx_tally); + DEBUGFS_ADD(hw_phy_errors); + DEBUGFS_ADD(phy_noise); + + DEBUGFS_ADD(hw_wlan_queue); + DEBUGFS_ADD(hw_pta_queue); + DEBUGFS_ADD(hw_ampdu_info); + + DEBUGFS_ADD(ampdu_density); + DEBUGFS_ADD(ampdu_factor); + + DEBUGFS_ADD(tx_janitor_last_run); + + DEBUGFS_ADD(tx_status_0); + DEBUGFS_ADD(tx_status_1); + DEBUGFS_ADD(tx_status_2); + DEBUGFS_ADD(tx_status_3); + + DEBUGFS_ADD(tx_pending_0); + DEBUGFS_ADD(tx_pending_1); + DEBUGFS_ADD(tx_pending_2); + DEBUGFS_ADD(tx_pending_3); + + DEBUGFS_ADD(hw_ioread32); + DEBUGFS_ADD(hw_iowrite32); + DEBUGFS_ADD(bug); + + DEBUGFS_ADD(erp); + + DEBUGFS_ADD(vif_dump); + + DEBUGFS_ADD(beacon_int); + DEBUGFS_ADD(pretbtt); + +#undef DEBUGFS_ADD +} + +void carl9170_debugfs_unregister(struct ar9170 *ar) +{ + debugfs_remove_recursive(ar->debug_dir); +} diff --git a/drivers/net/wireless/ath/carl9170/debug.h b/drivers/net/wireless/ath/carl9170/debug.h new file mode 100644 index 0000000000000000000000000000000000000000..ea4b97524122bf35921de8cb90aacd229f4c77b7 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/debug.h @@ -0,0 +1,134 @@ +/* + * Atheros CARL9170 driver + * + * debug header + * + * Copyright 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __DEBUG_H +#define __DEBUG_H + +#include "eeprom.h" +#include "wlan.h" +#include "hw.h" +#include "fwdesc.h" +#include "fwcmd.h" +#include "../regd.h" + +struct hw_stat_reg_entry { + u32 reg; + char nreg[32]; +}; + +#define STAT_MAC_REG(reg) \ + { (AR9170_MAC_REG_##reg), #reg } + +#define STAT_PTA_REG(reg) \ + { (AR9170_PTA_REG_##reg), #reg } + +#define STAT_USB_REG(reg) \ + { (AR9170_USB_REG_##reg), #reg } + +static const struct hw_stat_reg_entry hw_rx_tally_regs[] = { + STAT_MAC_REG(RX_CRC32), STAT_MAC_REG(RX_CRC16), + STAT_MAC_REG(RX_TIMEOUT_COUNT), STAT_MAC_REG(RX_ERR_DECRYPTION_UNI), + STAT_MAC_REG(RX_ERR_DECRYPTION_MUL), STAT_MAC_REG(RX_MPDU), + STAT_MAC_REG(RX_DROPPED_MPDU), STAT_MAC_REG(RX_DEL_MPDU), +}; + +static const struct hw_stat_reg_entry hw_phy_errors_regs[] = { + STAT_MAC_REG(RX_PHY_MISC_ERROR), STAT_MAC_REG(RX_PHY_XR_ERROR), + STAT_MAC_REG(RX_PHY_OFDM_ERROR), STAT_MAC_REG(RX_PHY_CCK_ERROR), + STAT_MAC_REG(RX_PHY_HT_ERROR), STAT_MAC_REG(RX_PHY_TOTAL), +}; + +static const struct hw_stat_reg_entry hw_tx_tally_regs[] = { + STAT_MAC_REG(TX_TOTAL), STAT_MAC_REG(TX_UNDERRUN), + STAT_MAC_REG(TX_RETRY), +}; + +static const struct hw_stat_reg_entry hw_wlan_queue_regs[] = { + STAT_MAC_REG(DMA_STATUS), STAT_MAC_REG(DMA_TRIGGER), + STAT_MAC_REG(DMA_TXQ0_ADDR), STAT_MAC_REG(DMA_TXQ0_CURR_ADDR), + STAT_MAC_REG(DMA_TXQ1_ADDR), STAT_MAC_REG(DMA_TXQ1_CURR_ADDR), + STAT_MAC_REG(DMA_TXQ2_ADDR), STAT_MAC_REG(DMA_TXQ2_CURR_ADDR), + STAT_MAC_REG(DMA_TXQ3_ADDR), STAT_MAC_REG(DMA_TXQ3_CURR_ADDR), + STAT_MAC_REG(DMA_RXQ_ADDR), STAT_MAC_REG(DMA_RXQ_CURR_ADDR), +}; + +static const struct hw_stat_reg_entry hw_ampdu_info_regs[] = { + STAT_MAC_REG(AMPDU_DENSITY), STAT_MAC_REG(AMPDU_FACTOR), +}; + +static const struct hw_stat_reg_entry hw_pta_queue_regs[] = { + STAT_PTA_REG(DN_CURR_ADDRH), STAT_PTA_REG(DN_CURR_ADDRL), + STAT_PTA_REG(UP_CURR_ADDRH), STAT_PTA_REG(UP_CURR_ADDRL), + STAT_PTA_REG(DMA_STATUS), STAT_PTA_REG(DMA_MODE_CTRL), +}; + +#define DEFINE_TALLY(name) \ + u32 name##_sum[ARRAY_SIZE(name##_regs)], \ + name##_counter[ARRAY_SIZE(name##_regs)] \ + +#define DEFINE_STAT(name) \ + u32 name##_counter[ARRAY_SIZE(name##_regs)] \ + +struct ath_stats { + DEFINE_TALLY(hw_tx_tally); + DEFINE_TALLY(hw_rx_tally); + DEFINE_TALLY(hw_phy_errors); + DEFINE_STAT(hw_wlan_queue); + DEFINE_STAT(hw_pta_queue); + DEFINE_STAT(hw_ampdu_info); +}; + +struct carl9170_debug_mem_rbe { + u32 reg; + u32 value; +}; + +#define CARL9170_DEBUG_RING_SIZE 64 + +struct carl9170_debug { + struct ath_stats stats; + struct carl9170_debug_mem_rbe ring[CARL9170_DEBUG_RING_SIZE]; + struct mutex ring_lock; + unsigned int ring_head, ring_tail; + struct delayed_work update_tally; +}; + +struct ar9170; + +void carl9170_debugfs_register(struct ar9170 *ar); +void carl9170_debugfs_unregister(struct ar9170 *ar); +#endif /* __DEBUG_H */ diff --git a/drivers/net/wireless/ath/carl9170/eeprom.h b/drivers/net/wireless/ath/carl9170/eeprom.h new file mode 100644 index 0000000000000000000000000000000000000000..7cff40ac7759420908d00130ca2b2a224c591709 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/eeprom.h @@ -0,0 +1,216 @@ +/* + * Shared Atheros AR9170 Header + * + * EEPROM layout + * + * Copyright 2008, Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#ifndef __CARL9170_SHARED_EEPROM_H +#define __CARL9170_SHARED_EEPROM_H + +#define AR9170_EEPROM_START 0x1600 + +#define AR5416_MAX_CHAINS 2 +#define AR5416_MODAL_SPURS 5 + +struct ar9170_eeprom_modal { + __le32 antCtrlChain[AR5416_MAX_CHAINS]; + __le32 antCtrlCommon; + s8 antennaGainCh[AR5416_MAX_CHAINS]; + u8 switchSettling; + u8 txRxAttenCh[AR5416_MAX_CHAINS]; + u8 rxTxMarginCh[AR5416_MAX_CHAINS]; + s8 adcDesiredSize; + s8 pgaDesiredSize; + u8 xlnaGainCh[AR5416_MAX_CHAINS]; + u8 txEndToXpaOff; + u8 txEndToRxOn; + u8 txFrameToXpaOn; + u8 thresh62; + s8 noiseFloorThreshCh[AR5416_MAX_CHAINS]; + u8 xpdGain; + u8 xpd; + s8 iqCalICh[AR5416_MAX_CHAINS]; + s8 iqCalQCh[AR5416_MAX_CHAINS]; + u8 pdGainOverlap; + u8 ob; + u8 db; + u8 xpaBiasLvl; + u8 pwrDecreaseFor2Chain; + u8 pwrDecreaseFor3Chain; + u8 txFrameToDataStart; + u8 txFrameToPaOn; + u8 ht40PowerIncForPdadc; + u8 bswAtten[AR5416_MAX_CHAINS]; + u8 bswMargin[AR5416_MAX_CHAINS]; + u8 swSettleHt40; + u8 reserved[22]; + struct spur_channel { + __le16 spurChan; + u8 spurRangeLow; + u8 spurRangeHigh; + } __packed spur_channels[AR5416_MODAL_SPURS]; +} __packed; + +#define AR5416_NUM_PD_GAINS 4 +#define AR5416_PD_GAIN_ICEPTS 5 + +struct ar9170_calibration_data_per_freq { + u8 pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; + u8 vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; +} __packed; + +#define AR5416_NUM_5G_CAL_PIERS 8 +#define AR5416_NUM_2G_CAL_PIERS 4 + +#define AR5416_NUM_5G_TARGET_PWRS 8 +#define AR5416_NUM_2G_CCK_TARGET_PWRS 3 +#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4 +#define AR5416_MAX_NUM_TGT_PWRS 8 + +struct ar9170_calibration_target_power_legacy { + u8 freq; + u8 power[4]; +} __packed; + +struct ar9170_calibration_target_power_ht { + u8 freq; + u8 power[8]; +} __packed; + +#define AR5416_NUM_CTLS 24 + +struct ar9170_calctl_edges { + u8 channel; +#define AR9170_CALCTL_EDGE_FLAGS 0xC0 + u8 power_flags; +} __packed; + +#define AR5416_NUM_BAND_EDGES 8 + +struct ar9170_calctl_data { + struct ar9170_calctl_edges + control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; +} __packed; + +struct ar9170_eeprom { + __le16 length; + __le16 checksum; + __le16 version; + u8 operating_flags; +#define AR9170_OPFLAG_5GHZ 1 +#define AR9170_OPFLAG_2GHZ 2 + u8 misc; + __le16 reg_domain[2]; + u8 mac_address[6]; + u8 rx_mask; + u8 tx_mask; + __le16 rf_silent; + __le16 bluetooth_options; + __le16 device_capabilities; + __le32 build_number; + u8 deviceType; + u8 reserved[33]; + + u8 customer_data[64]; + + struct ar9170_eeprom_modal + modal_header[2]; + + u8 cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS]; + u8 cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS]; + + struct ar9170_calibration_data_per_freq + cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS], + cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS]; + + /* power calibration data */ + struct ar9170_calibration_target_power_legacy + cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS]; + struct ar9170_calibration_target_power_ht + cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS], + cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS]; + + struct ar9170_calibration_target_power_legacy + cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS], + cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS]; + struct ar9170_calibration_target_power_ht + cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS], + cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS]; + + /* conformance testing limits */ + u8 ctl_index[AR5416_NUM_CTLS]; + struct ar9170_calctl_data + ctl_data[AR5416_NUM_CTLS]; + + u8 pad; + __le16 subsystem_id; +} __packed; + +#define AR9170_LED_MODE_POWER_ON 0x0001 +#define AR9170_LED_MODE_RESERVED 0x0002 +#define AR9170_LED_MODE_DISABLE_STATE 0x0004 +#define AR9170_LED_MODE_OFF_IN_PSM 0x0008 + +/* AR9170_LED_MODE BIT is set */ +#define AR9170_LED_MODE_FREQUENCY_S 4 +#define AR9170_LED_MODE_FREQUENCY 0x0030 +#define AR9170_LED_MODE_FREQUENCY_1HZ 0x0000 +#define AR9170_LED_MODE_FREQUENCY_0_5HZ 0x0010 +#define AR9170_LED_MODE_FREQUENCY_0_25HZ 0x0020 +#define AR9170_LED_MODE_FREQUENCY_0_125HZ 0x0030 + +/* AR9170_LED_MODE BIT is not set */ +#define AR9170_LED_MODE_CONN_STATE_S 4 +#define AR9170_LED_MODE_CONN_STATE 0x0030 +#define AR9170_LED_MODE_CONN_STATE_FORCE_OFF 0x0000 +#define AR9170_LED_MODE_CONN_STATE_FORCE_ON 0x0010 +/* Idle off / Active on */ +#define AR9170_LED_MODE_CONN_STATE_IOFF_AON 0x0020 +/* Idle on / Active off */ +#define AR9170_LED_MODE_CONN_STATE_ION_AOFF 0x0010 + +#define AR9170_LED_MODE_MODE 0x0040 +#define AR9170_LED_MODE_RESERVED2 0x0080 + +#define AR9170_LED_MODE_TON_SCAN_S 8 +#define AR9170_LED_MODE_TON_SCAN 0x0f00 + +#define AR9170_LED_MODE_TOFF_SCAN_S 12 +#define AR9170_LED_MODE_TOFF_SCAN 0xf000 + +struct ar9170_led_mode { + __le16 led; +}; + +#endif /* __CARL9170_SHARED_EEPROM_H */ diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c new file mode 100644 index 0000000000000000000000000000000000000000..ae6c006bbc56c03bd76f0e1cc56c46a927db1db9 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -0,0 +1,402 @@ +/* + * Atheros CARL9170 driver + * + * firmware parser + * + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + */ + +#include +#include +#include +#include "carl9170.h" +#include "fwcmd.h" +#include "version.h" + +#define MAKE_STR(symbol) #symbol +#define TO_STR(symbol) MAKE_STR(symbol) +#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER) +MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT); + +static const u8 otus_magic[4] = { OTUS_MAGIC }; + +static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], + const unsigned int len, const u8 compatible_revision) +{ + const struct carl9170fw_desc_head *iter; + + carl9170fw_for_each_hdr(iter, ar->fw.desc) { + if (carl9170fw_desc_cmp(iter, descid, len, + compatible_revision)) + return (void *)iter; + } + + /* needed to find the LAST desc */ + if (carl9170fw_desc_cmp(iter, descid, len, + compatible_revision)) + return (void *)iter; + + return NULL; +} + +static int carl9170_fw_verify_descs(struct ar9170 *ar, + const struct carl9170fw_desc_head *head, unsigned int max_len) +{ + const struct carl9170fw_desc_head *pos; + unsigned long pos_addr, end_addr; + unsigned int pos_length; + + if (max_len < sizeof(*pos)) + return -ENODATA; + + max_len = min_t(unsigned int, CARL9170FW_DESC_MAX_LENGTH, max_len); + + pos = head; + pos_addr = (unsigned long) pos; + end_addr = pos_addr + max_len; + + while (pos_addr < end_addr) { + if (pos_addr + sizeof(*head) > end_addr) + return -E2BIG; + + pos_length = le16_to_cpu(pos->length); + + if (pos_length < sizeof(*head)) + return -EBADMSG; + + if (pos_length > max_len) + return -EOVERFLOW; + + if (pos_addr + pos_length > end_addr) + return -EMSGSIZE; + + if (carl9170fw_desc_cmp(pos, LAST_MAGIC, + CARL9170FW_LAST_DESC_SIZE, + CARL9170FW_LAST_DESC_CUR_VER)) + return 0; + + pos_addr += pos_length; + pos = (void *)pos_addr; + max_len -= pos_length; + } + return -EINVAL; +} + +static void carl9170_fw_info(struct ar9170 *ar) +{ + const struct carl9170fw_motd_desc *motd_desc; + unsigned int str_ver_len; + u32 fw_date; + + dev_info(&ar->udev->dev, "driver API: %s 2%03d-%02d-%02d [%d-%d]\n", + CARL9170FW_VERSION_GIT, CARL9170FW_VERSION_YEAR, + CARL9170FW_VERSION_MONTH, CARL9170FW_VERSION_DAY, + CARL9170FW_API_MIN_VER, CARL9170FW_API_MAX_VER); + + motd_desc = carl9170_fw_find_desc(ar, MOTD_MAGIC, + sizeof(*motd_desc), CARL9170FW_MOTD_DESC_CUR_VER); + + if (motd_desc) { + str_ver_len = strnlen(motd_desc->release, + CARL9170FW_MOTD_RELEASE_LEN); + + fw_date = le32_to_cpu(motd_desc->fw_year_month_day); + + dev_info(&ar->udev->dev, "firmware API: %.*s 2%03d-%02d-%02d\n", + str_ver_len, motd_desc->release, + CARL9170FW_GET_YEAR(fw_date), + CARL9170FW_GET_MONTH(fw_date), + CARL9170FW_GET_DAY(fw_date)); + + strlcpy(ar->hw->wiphy->fw_version, motd_desc->release, + sizeof(ar->hw->wiphy->fw_version)); + } +} + +static bool valid_dma_addr(const u32 address) +{ + if (address >= AR9170_SRAM_OFFSET && + address < (AR9170_SRAM_OFFSET + AR9170_SRAM_SIZE)) + return true; + + return false; +} + +static bool valid_cpu_addr(const u32 address) +{ + if (valid_dma_addr(address) || (address >= AR9170_PRAM_OFFSET && + address < (AR9170_PRAM_OFFSET + AR9170_PRAM_SIZE))) + return true; + + return false; +} + +static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) +{ + const struct carl9170fw_otus_desc *otus_desc; + const struct carl9170fw_chk_desc *chk_desc; + const struct carl9170fw_last_desc *last_desc; + + last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, + sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); + if (!last_desc) + return -EINVAL; + + otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC, + sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER); + if (!otus_desc) { + dev_err(&ar->udev->dev, "failed to find compatible firmware " + "descriptor.\n"); + return -ENODATA; + } + + chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC, + sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER); + + if (chk_desc) { + unsigned long fin, diff; + unsigned int dsc_len; + u32 crc32; + + dsc_len = min_t(unsigned int, len, + (unsigned long)chk_desc - (unsigned long)otus_desc); + + fin = (unsigned long) last_desc + sizeof(*last_desc); + diff = fin - (unsigned long) otus_desc; + + if (diff < len) + len -= diff; + + if (len < 256) + return -EIO; + + crc32 = crc32_le(~0, data, len); + if (cpu_to_le32(crc32) != chk_desc->fw_crc32) { + dev_err(&ar->udev->dev, "fw checksum test failed.\n"); + return -ENOEXEC; + } + + crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len); + if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) { + dev_err(&ar->udev->dev, "descriptor check failed.\n"); + return -EINVAL; + } + } else { + dev_warn(&ar->udev->dev, "Unprotected firmware image.\n"); + } + +#define SUPP(feat) \ + (carl9170fw_supports(otus_desc->feature_set, feat)) + + if (!SUPP(CARL9170FW_DUMMY_FEATURE)) { + dev_err(&ar->udev->dev, "invalid firmware descriptor " + "format detected.\n"); + return -EINVAL; + } + + ar->fw.api_version = otus_desc->api_ver; + + if (ar->fw.api_version < CARL9170FW_API_MIN_VER || + ar->fw.api_version > CARL9170FW_API_MAX_VER) { + dev_err(&ar->udev->dev, "unsupported firmware api version.\n"); + return -EINVAL; + } + + if (!SUPP(CARL9170FW_COMMAND_PHY) || SUPP(CARL9170FW_UNUSABLE) || + !SUPP(CARL9170FW_HANDLE_BACK_REQ)) { + dev_err(&ar->udev->dev, "firmware does support " + "mandatory features.\n"); + return -ECANCELED; + } + + if (ilog2(le32_to_cpu(otus_desc->feature_set)) >= + __CARL9170FW_FEATURE_NUM) { + dev_warn(&ar->udev->dev, "driver does not support all " + "firmware features.\n"); + } + + if (!SUPP(CARL9170FW_COMMAND_CAM)) { + dev_info(&ar->udev->dev, "crypto offloading is disabled " + "by firmware.\n"); + ar->disable_offload = true; + } + + if (SUPP(CARL9170FW_PSM)) + ar->hw->flags |= IEEE80211_HW_SUPPORTS_PS; + + if (!SUPP(CARL9170FW_USB_INIT_FIRMWARE)) { + dev_err(&ar->udev->dev, "firmware does not provide " + "mandatory interfaces.\n"); + return -EINVAL; + } + + if (SUPP(CARL9170FW_MINIBOOT)) + ar->fw.offset = le16_to_cpu(otus_desc->miniboot_size); + else + ar->fw.offset = 0; + + if (SUPP(CARL9170FW_USB_DOWN_STREAM)) { + ar->hw->extra_tx_headroom += sizeof(struct ar9170_stream); + ar->fw.tx_stream = true; + } + + if (SUPP(CARL9170FW_USB_UP_STREAM)) + ar->fw.rx_stream = true; + + if (SUPP(CARL9170FW_RX_FILTER)) { + ar->fw.rx_filter = true; + ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL | + FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS | + FIF_PROMISC_IN_BSS; + } + + ar->fw.vif_num = otus_desc->vif_num; + ar->fw.cmd_bufs = otus_desc->cmd_bufs; + ar->fw.address = le32_to_cpu(otus_desc->fw_address); + ar->fw.rx_size = le16_to_cpu(otus_desc->rx_max_frame_len); + ar->fw.mem_blocks = min_t(unsigned int, otus_desc->tx_descs, 0xfe); + atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks); + ar->fw.mem_block_size = le16_to_cpu(otus_desc->tx_frag_len); + + if (ar->fw.vif_num >= AR9170_MAX_VIRTUAL_MAC || !ar->fw.vif_num || + ar->fw.mem_blocks < 16 || !ar->fw.cmd_bufs || + ar->fw.mem_block_size < 64 || ar->fw.mem_block_size > 512 || + ar->fw.rx_size > 32768 || ar->fw.rx_size < 4096 || + !valid_cpu_addr(ar->fw.address)) { + dev_err(&ar->udev->dev, "firmware shows obvious signs of " + "malicious tampering.\n"); + return -EINVAL; + } + + ar->fw.beacon_addr = le32_to_cpu(otus_desc->bcn_addr); + ar->fw.beacon_max_len = le16_to_cpu(otus_desc->bcn_len); + + if (valid_dma_addr(ar->fw.beacon_addr) && ar->fw.beacon_max_len >= + AR9170_MAC_BCN_LENGTH_MAX) { + ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); + + if (SUPP(CARL9170FW_WLANTX_CAB)) { + ar->hw->wiphy->interface_modes |= + BIT(NL80211_IFTYPE_AP); + } + } + +#undef SUPPORTED + return 0; +} + +static struct carl9170fw_desc_head * +carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len) + +{ + int scan = 0, found = 0; + + if (!carl9170fw_size_check(len)) { + dev_err(&ar->udev->dev, "firmware size is out of bound.\n"); + return NULL; + } + + while (scan < len - sizeof(struct carl9170fw_desc_head)) { + if (fw_data[scan++] == otus_magic[found]) + found++; + else + found = 0; + + if (scan >= len) + break; + + if (found == sizeof(otus_magic)) + break; + } + + if (found != sizeof(otus_magic)) + return NULL; + + return (void *)&fw_data[scan - found]; +} + +int carl9170_fw_fix_eeprom(struct ar9170 *ar) +{ + const struct carl9170fw_fix_desc *fix_desc = NULL; + unsigned int i, n, off; + u32 *data = (void *)&ar->eeprom; + + fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC, + sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER); + + if (!fix_desc) + return 0; + + n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) / + sizeof(struct carl9170fw_fix_entry); + + for (i = 0; i < n; i++) { + off = le32_to_cpu(fix_desc->data[i].address) - + AR9170_EEPROM_START; + + if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) { + dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i); + continue; + } + + data[off / sizeof(*data)] &= + le32_to_cpu(fix_desc->data[i].mask); + data[off / sizeof(*data)] |= + le32_to_cpu(fix_desc->data[i].value); + } + + return 0; +} + +int carl9170_parse_firmware(struct ar9170 *ar) +{ + const struct carl9170fw_desc_head *fw_desc = NULL; + const struct firmware *fw = ar->fw.fw; + unsigned long header_offset = 0; + int err; + + if (WARN_ON(!fw)) + return -EINVAL; + + fw_desc = carl9170_find_fw_desc(ar, fw->data, fw->size); + + if (!fw_desc) { + dev_err(&ar->udev->dev, "unsupported firmware.\n"); + return -ENODATA; + } + + header_offset = (unsigned long)fw_desc - (unsigned long)fw->data; + + err = carl9170_fw_verify_descs(ar, fw_desc, fw->size - header_offset); + if (err) { + dev_err(&ar->udev->dev, "damaged firmware (%d).\n", err); + return err; + } + + ar->fw.desc = fw_desc; + + carl9170_fw_info(ar); + + err = carl9170_fw(ar, fw->data, fw->size); + if (err) { + dev_err(&ar->udev->dev, "failed to parse firmware (%d).\n", + err); + return err; + } + + return 0; +} diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h new file mode 100644 index 0000000000000000000000000000000000000000..d552166db5059149cd8e653fb2e1154dfba85173 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/fwcmd.h @@ -0,0 +1,284 @@ +/* + * Shared Atheros AR9170 Header + * + * Firmware command interface definitions + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CARL9170_SHARED_FWCMD_H +#define __CARL9170_SHARED_FWCMD_H + +#define CARL9170_MAX_CMD_LEN 64 +#define CARL9170_MAX_CMD_PAYLOAD_LEN 60 + +#define CARL9170FW_API_MIN_VER 1 +#define CARL9170FW_API_MAX_VER 1 + +enum carl9170_cmd_oids { + CARL9170_CMD_RREG = 0x00, + CARL9170_CMD_WREG = 0x01, + CARL9170_CMD_ECHO = 0x02, + CARL9170_CMD_SWRST = 0x03, + CARL9170_CMD_REBOOT = 0x04, + CARL9170_CMD_BCN_CTRL = 0x05, + CARL9170_CMD_READ_TSF = 0x06, + CARL9170_CMD_RX_FILTER = 0x07, + + /* CAM */ + CARL9170_CMD_EKEY = 0x10, + CARL9170_CMD_DKEY = 0x11, + + /* RF / PHY */ + CARL9170_CMD_FREQUENCY = 0x20, + CARL9170_CMD_RF_INIT = 0x21, + CARL9170_CMD_SYNTH = 0x22, + CARL9170_CMD_FREQ_START = 0x23, + CARL9170_CMD_PSM = 0x24, + + /* Asychronous command flag */ + CARL9170_CMD_ASYNC_FLAG = 0x40, + CARL9170_CMD_WREG_ASYNC = (CARL9170_CMD_WREG | + CARL9170_CMD_ASYNC_FLAG), + CARL9170_CMD_REBOOT_ASYNC = (CARL9170_CMD_REBOOT | + CARL9170_CMD_ASYNC_FLAG), + CARL9170_CMD_BCN_CTRL_ASYNC = (CARL9170_CMD_BCN_CTRL | + CARL9170_CMD_ASYNC_FLAG), + CARL9170_CMD_PSM_ASYNC = (CARL9170_CMD_PSM | + CARL9170_CMD_ASYNC_FLAG), + + /* responses and traps */ + CARL9170_RSP_FLAG = 0xc0, + CARL9170_RSP_PRETBTT = 0xc0, + CARL9170_RSP_TXCOMP = 0xc1, + CARL9170_RSP_BEACON_CONFIG = 0xc2, + CARL9170_RSP_ATIM = 0xc3, + CARL9170_RSP_WATCHDOG = 0xc6, + CARL9170_RSP_TEXT = 0xca, + CARL9170_RSP_HEXDUMP = 0xcc, + CARL9170_RSP_RADAR = 0xcd, + CARL9170_RSP_GPIO = 0xce, + CARL9170_RSP_BOOT = 0xcf, +}; + +struct carl9170_set_key_cmd { + __le16 user; + __le16 keyId; + __le16 type; + u8 macAddr[6]; + u32 key[4]; +} __packed; +#define CARL9170_SET_KEY_CMD_SIZE 28 + +struct carl9170_disable_key_cmd { + __le16 user; + __le16 padding; +} __packed; +#define CARL9170_DISABLE_KEY_CMD_SIZE 4 + +struct carl9170_u32_list { + u32 vals[0]; +} __packed; + +struct carl9170_reg_list { + __le32 regs[0]; +} __packed; + +struct carl9170_write_reg { + struct { + __le32 addr; + __le32 val; + } regs[0] __packed; +} __packed; + +#define CARL9170FW_PHY_HT_ENABLE 0x4 +#define CARL9170FW_PHY_HT_DYN2040 0x8 +#define CARL9170FW_PHY_HT_EXT_CHAN_OFF 0x3 +#define CARL9170FW_PHY_HT_EXT_CHAN_OFF_S 2 + +struct carl9170_rf_init { + __le32 freq; + u8 ht_settings; + u8 padding2[3]; + __le32 delta_slope_coeff_exp; + __le32 delta_slope_coeff_man; + __le32 delta_slope_coeff_exp_shgi; + __le32 delta_slope_coeff_man_shgi; + __le32 finiteLoopCount; +} __packed; +#define CARL9170_RF_INIT_SIZE 28 + +struct carl9170_rf_init_result { + __le32 ret; /* AR9170_PHY_REG_AGC_CONTROL */ +} __packed; +#define CARL9170_RF_INIT_RESULT_SIZE 4 + +#define CARL9170_PSM_SLEEP 0x1000 +#define CARL9170_PSM_SOFTWARE 0 +#define CARL9170_PSM_WAKE 0 /* internally used. */ +#define CARL9170_PSM_COUNTER 0xfff +#define CARL9170_PSM_COUNTER_S 0 + +struct carl9170_psm { + __le32 state; +} __packed; +#define CARL9170_PSM_SIZE 4 + +struct carl9170_rx_filter_cmd { + __le32 rx_filter; +} __packed; +#define CARL9170_RX_FILTER_CMD_SIZE 4 + +#define CARL9170_RX_FILTER_BAD 0x01 +#define CARL9170_RX_FILTER_OTHER_RA 0x02 +#define CARL9170_RX_FILTER_DECRY_FAIL 0x04 +#define CARL9170_RX_FILTER_CTL_OTHER 0x08 +#define CARL9170_RX_FILTER_CTL_PSPOLL 0x10 +#define CARL9170_RX_FILTER_CTL_BACKR 0x20 +#define CARL9170_RX_FILTER_MGMT 0x40 +#define CARL9170_RX_FILTER_DATA 0x80 + +struct carl9170_bcn_ctrl_cmd { + __le32 vif_id; + __le32 mode; + __le32 bcn_addr; + __le32 bcn_len; +} __packed; +#define CARL9170_BCN_CTRL_CMD_SIZE 16 + +#define CARL9170_BCN_CTRL_DRAIN 0 +#define CARL9170_BCN_CTRL_CAB_TRIGGER 1 + +struct carl9170_cmd_head { + union { + struct { + u8 len; + u8 cmd; + u8 seq; + u8 ext; + } __packed; + + u32 hdr_data; + } __packed; +} __packed; + +struct carl9170_cmd { + struct carl9170_cmd_head hdr; + union { + struct carl9170_set_key_cmd setkey; + struct carl9170_disable_key_cmd disablekey; + struct carl9170_u32_list echo; + struct carl9170_reg_list rreg; + struct carl9170_write_reg wreg; + struct carl9170_rf_init rf_init; + struct carl9170_psm psm; + struct carl9170_bcn_ctrl_cmd bcn_ctrl; + struct carl9170_rx_filter_cmd rx_filter; + u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; + } __packed; +} __packed; + +#define CARL9170_TX_STATUS_QUEUE 3 +#define CARL9170_TX_STATUS_QUEUE_S 0 +#define CARL9170_TX_STATUS_RIX_S 2 +#define CARL9170_TX_STATUS_RIX (3 << CARL9170_TX_STATUS_RIX_S) +#define CARL9170_TX_STATUS_TRIES_S 4 +#define CARL9170_TX_STATUS_TRIES (7 << CARL9170_TX_STATUS_TRIES_S) +#define CARL9170_TX_STATUS_SUCCESS 0x80 + +/* + * NOTE: + * Both structs [carl9170_tx_status and _carl9170_tx_status] + * need to be "bit for bit" in sync. + */ +struct carl9170_tx_status { + /* + * Beware of compiler bugs in all gcc pre 4.4! + */ + + u8 cookie; + u8 queue:2; + u8 rix:2; + u8 tries:3; + u8 success:1; +} __packed; +struct _carl9170_tx_status { + /* + * This version should be immune to all alignment bugs. + */ + + u8 cookie; + u8 info; +} __packed; +#define CARL9170_TX_STATUS_SIZE 2 + +#define CARL9170_RSP_TX_STATUS_NUM (CARL9170_MAX_CMD_PAYLOAD_LEN / \ + sizeof(struct _carl9170_tx_status)) + +#define CARL9170_TX_MAX_RATE_TRIES 7 + +#define CARL9170_TX_MAX_RATES 4 +#define CARL9170_TX_MAX_RETRY_RATES (CARL9170_TX_MAX_RATES - 1) +#define CARL9170_ERR_MAGIC "ERR:" +#define CARL9170_BUG_MAGIC "BUG:" + +struct carl9170_gpio { + __le32 gpio; +} __packed; +#define CARL9170_GPIO_SIZE 4 + +struct carl9170_tsf_rsp { + union { + __le32 tsf[2]; + __le64 tsf_64; + } __packed; +} __packed; +#define CARL9170_TSF_RSP_SIZE 8 + +struct carl9170_rsp { + struct carl9170_cmd_head hdr; + + union { + struct carl9170_rf_init_result rf_init_res; + struct carl9170_u32_list rreg_res; + struct carl9170_u32_list echo; + struct carl9170_tx_status tx_status[0]; + struct _carl9170_tx_status _tx_status[0]; + struct carl9170_gpio gpio; + struct carl9170_tsf_rsp tsf; + struct carl9170_psm psm; + u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN]; + } __packed; +} __packed; + +#endif /* __CARL9170_SHARED_FWCMD_H */ diff --git a/drivers/net/wireless/ath/carl9170/fwdesc.h b/drivers/net/wireless/ath/carl9170/fwdesc.h new file mode 100644 index 0000000000000000000000000000000000000000..71f3821f60581d721bd203cea46ed31245e26679 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/fwdesc.h @@ -0,0 +1,241 @@ +/* + * Shared CARL9170 Header + * + * Firmware descriptor format + * + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + */ + +#ifndef __CARL9170_SHARED_FWDESC_H +#define __CARL9170_SHARED_FWDESC_H + +/* NOTE: Don't mess with the order of the flags! */ +enum carl9170fw_feature_list { + /* Always set */ + CARL9170FW_DUMMY_FEATURE, + + /* + * Indicates that this image has special boot block which prevents + * legacy drivers to drive the firmware. + */ + CARL9170FW_MINIBOOT, + + /* usb registers are initialized by the firmware */ + CARL9170FW_USB_INIT_FIRMWARE, + + /* command traps & notifications are send through EP2 */ + CARL9170FW_USB_RESP_EP2, + + /* usb download (app -> fw) stream */ + CARL9170FW_USB_DOWN_STREAM, + + /* usb upload (fw -> app) stream */ + CARL9170FW_USB_UP_STREAM, + + /* unusable - reserved to flag non-functional debug firmwares */ + CARL9170FW_UNUSABLE, + + /* AR9170_CMD_RF_INIT, AR9170_CMD_FREQ_START, AR9170_CMD_FREQUENCY */ + CARL9170FW_COMMAND_PHY, + + /* AR9170_CMD_EKEY, AR9170_CMD_DKEY */ + CARL9170FW_COMMAND_CAM, + + /* Firmware has a software Content After Beacon Queueing mechanism */ + CARL9170FW_WLANTX_CAB, + + /* The firmware is capable of responding to incoming BAR frames */ + CARL9170FW_HANDLE_BACK_REQ, + + /* GPIO Interrupt | CARL9170_RSP_GPIO */ + CARL9170FW_GPIO_INTERRUPT, + + /* Firmware PSM support | CARL9170_CMD_PSM */ + CARL9170FW_PSM, + + /* Firmware RX filter | CARL9170_CMD_RX_FILTER */ + CARL9170FW_RX_FILTER, + + /* KEEP LAST */ + __CARL9170FW_FEATURE_NUM +}; + +#define OTUS_MAGIC "OTAR" +#define MOTD_MAGIC "MOTD" +#define FIX_MAGIC "FIX\0" +#define DBG_MAGIC "DBG\0" +#define CHK_MAGIC "CHK\0" +#define LAST_MAGIC "LAST" + +#define CARL9170FW_SET_DAY(d) (((d) - 1) % 31) +#define CARL9170FW_SET_MONTH(m) ((((m) - 1) % 12) * 31) +#define CARL9170FW_SET_YEAR(y) (((y) - 10) * 372) + +#define CARL9170FW_GET_DAY(d) (((d) % 31) + 1) +#define CARL9170FW_GET_MONTH(m) ((((m) / 31) % 12) + 1) +#define CARL9170FW_GET_YEAR(y) ((y) / 372 + 10) + +struct carl9170fw_desc_head { + u8 magic[4]; + __le16 length; + u8 min_ver; + u8 cur_ver; +} __packed; +#define CARL9170FW_DESC_HEAD_SIZE \ + (sizeof(struct carl9170fw_desc_head)) + +#define CARL9170FW_OTUS_DESC_MIN_VER 6 +#define CARL9170FW_OTUS_DESC_CUR_VER 6 +struct carl9170fw_otus_desc { + struct carl9170fw_desc_head head; + __le32 feature_set; + __le32 fw_address; + __le32 bcn_addr; + __le16 bcn_len; + __le16 miniboot_size; + __le16 tx_frag_len; + __le16 rx_max_frame_len; + u8 tx_descs; + u8 cmd_bufs; + u8 api_ver; + u8 vif_num; +} __packed; +#define CARL9170FW_OTUS_DESC_SIZE \ + (sizeof(struct carl9170fw_otus_desc)) + +#define CARL9170FW_MOTD_STRING_LEN 24 +#define CARL9170FW_MOTD_RELEASE_LEN 20 +#define CARL9170FW_MOTD_DESC_MIN_VER 1 +#define CARL9170FW_MOTD_DESC_CUR_VER 2 +struct carl9170fw_motd_desc { + struct carl9170fw_desc_head head; + __le32 fw_year_month_day; + char desc[CARL9170FW_MOTD_STRING_LEN]; + char release[CARL9170FW_MOTD_RELEASE_LEN]; +} __packed; +#define CARL9170FW_MOTD_DESC_SIZE \ + (sizeof(struct carl9170fw_motd_desc)) + +#define CARL9170FW_FIX_DESC_MIN_VER 1 +#define CARL9170FW_FIX_DESC_CUR_VER 2 +struct carl9170fw_fix_entry { + __le32 address; + __le32 mask; + __le32 value; +} __packed; + +struct carl9170fw_fix_desc { + struct carl9170fw_desc_head head; + struct carl9170fw_fix_entry data[0]; +} __packed; +#define CARL9170FW_FIX_DESC_SIZE \ + (sizeof(struct carl9170fw_fix_desc)) + +#define CARL9170FW_DBG_DESC_MIN_VER 1 +#define CARL9170FW_DBG_DESC_CUR_VER 3 +struct carl9170fw_dbg_desc { + struct carl9170fw_desc_head head; + + __le32 bogoclock_addr; + __le32 counter_addr; + __le32 rx_total_addr; + __le32 rx_overrun_addr; + __le32 rx_filter; + + /* Put your debugging definitions here */ +} __packed; +#define CARL9170FW_DBG_DESC_SIZE \ + (sizeof(struct carl9170fw_dbg_desc)) + +#define CARL9170FW_CHK_DESC_MIN_VER 1 +#define CARL9170FW_CHK_DESC_CUR_VER 2 +struct carl9170fw_chk_desc { + struct carl9170fw_desc_head head; + __le32 fw_crc32; + __le32 hdr_crc32; +} __packed; +#define CARL9170FW_CHK_DESC_SIZE \ + (sizeof(struct carl9170fw_chk_desc)) + +#define CARL9170FW_LAST_DESC_MIN_VER 1 +#define CARL9170FW_LAST_DESC_CUR_VER 2 +struct carl9170fw_last_desc { + struct carl9170fw_desc_head head; +} __packed; +#define CARL9170FW_LAST_DESC_SIZE \ + (sizeof(struct carl9170fw_fix_desc)) + +#define CARL9170FW_DESC_MAX_LENGTH 8192 + +#define CARL9170FW_FILL_DESC(_magic, _length, _min_ver, _cur_ver) \ + .head = { \ + .magic = _magic, \ + .length = cpu_to_le16(_length), \ + .min_ver = _min_ver, \ + .cur_ver = _cur_ver, \ + } + +static inline void carl9170fw_fill_desc(struct carl9170fw_desc_head *head, + u8 magic[4], __le16 length, + u8 min_ver, u8 cur_ver) +{ + head->magic[0] = magic[0]; + head->magic[1] = magic[1]; + head->magic[2] = magic[2]; + head->magic[3] = magic[3]; + + head->length = length; + head->min_ver = min_ver; + head->cur_ver = cur_ver; +} + +#define carl9170fw_for_each_hdr(desc, fw_desc) \ + for (desc = fw_desc; \ + memcmp(desc->magic, LAST_MAGIC, 4) && \ + le16_to_cpu(desc->length) >= CARL9170FW_DESC_HEAD_SIZE && \ + le16_to_cpu(desc->length) < CARL9170FW_DESC_MAX_LENGTH; \ + desc = (void *)((unsigned long)desc + le16_to_cpu(desc->length))) + +#define CHECK_HDR_VERSION(head, _min_ver) \ + (((head)->cur_ver < _min_ver) || ((head)->min_ver > _min_ver)) \ + +static inline bool carl9170fw_supports(__le32 list, u8 feature) +{ + return le32_to_cpu(list) & BIT(feature); +} + +static inline bool carl9170fw_desc_cmp(const struct carl9170fw_desc_head *head, + const u8 descid[4], u16 min_len, + u8 compatible_revision) +{ + if (descid[0] == head->magic[0] && descid[1] == head->magic[1] && + descid[2] == head->magic[2] && descid[3] == head->magic[3] && + !CHECK_HDR_VERSION(head, compatible_revision) && + (le16_to_cpu(head->length) >= min_len)) + return true; + + return false; +} + +#define CARL9170FW_MIN_SIZE 32 +#define CARL9170FW_MAX_SIZE 16384 + +static inline bool carl9170fw_size_check(unsigned int len) +{ + return (len <= CARL9170FW_MAX_SIZE && len >= CARL9170FW_MIN_SIZE); +} + +#endif /* __CARL9170_SHARED_FWDESC_H */ diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h new file mode 100644 index 0000000000000000000000000000000000000000..2f471b3f05afdec737ab6e1d293ac40bb7c0db5c --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/hw.h @@ -0,0 +1,739 @@ +/* + * Shared Atheros AR9170 Header + * + * Register map, hardware-specific definitions + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CARL9170_SHARED_HW_H +#define __CARL9170_SHARED_HW_H + +/* High Speed UART */ +#define AR9170_UART_REG_BASE 0x1c0000 + +/* Definitions of interrupt registers */ +#define AR9170_UART_REG_RX_BUFFER (AR9170_UART_REG_BASE + 0x000) +#define AR9170_UART_REG_TX_HOLDING (AR9170_UART_REG_BASE + 0x004) +#define AR9170_UART_REG_FIFO_CONTROL (AR9170_UART_REG_BASE + 0x010) +#define AR9170_UART_FIFO_CTRL_RESET_RX_FIFO 0x02 +#define AR9170_UART_FIFO_CTRL_RESET_TX_FIFO 0x04 + +#define AR9170_UART_REG_LINE_CONTROL (AR9170_UART_REG_BASE + 0x014) +#define AR9170_UART_REG_MODEM_CONTROL (AR9170_UART_REG_BASE + 0x018) +#define AR9170_UART_MODEM_CTRL_DTR_BIT 0x01 +#define AR9170_UART_MODEM_CTRL_RTS_BIT 0x02 +#define AR9170_UART_MODEM_CTRL_INTERNAL_LOOP_BACK 0x10 +#define AR9170_UART_MODEM_CTRL_AUTO_RTS 0x20 +#define AR9170_UART_MODEM_CTRL_AUTO_CTR 0x40 + +#define AR9170_UART_REG_LINE_STATUS (AR9170_UART_REG_BASE + 0x01c) +#define AR9170_UART_LINE_STS_RX_DATA_READY 0x01 +#define AR9170_UART_LINE_STS_RX_BUFFER_OVERRUN 0x02 +#define AR9170_UART_LINE_STS_RX_BREAK_IND 0x10 +#define AR9170_UART_LINE_STS_TX_FIFO_NEAR_EMPTY 0x20 +#define AR9170_UART_LINE_STS_TRANSMITTER_EMPTY 0x40 + +#define AR9170_UART_REG_MODEM_STATUS (AR9170_UART_REG_BASE + 0x020) +#define AR9170_UART_MODEM_STS_CTS_CHANGE 0x01 +#define AR9170_UART_MODEM_STS_DSR_CHANGE 0x02 +#define AR9170_UART_MODEM_STS_DCD_CHANGE 0x08 +#define AR9170_UART_MODEM_STS_CTS_COMPL 0x10 +#define AR9170_UART_MODEM_STS_DSR_COMPL 0x20 +#define AR9170_UART_MODEM_STS_DCD_COMPL 0x80 + +#define AR9170_UART_REG_SCRATCH (AR9170_UART_REG_BASE + 0x024) +#define AR9170_UART_REG_DIVISOR_LSB (AR9170_UART_REG_BASE + 0x028) +#define AR9170_UART_REG_DIVISOR_MSB (AR9170_UART_REG_BASE + 0x02c) +#define AR9170_UART_REG_WORD_RX_BUFFER (AR9170_UART_REG_BASE + 0x034) +#define AR9170_UART_REG_WORD_TX_HOLDING (AR9170_UART_REG_BASE + 0x038) +#define AR9170_UART_REG_FIFO_COUNT (AR9170_UART_REG_BASE + 0x03c) +#define AR9170_UART_REG_REMAINDER (AR9170_UART_REG_BASE + 0x04c) + +/* Timer */ +#define AR9170_TIMER_REG_BASE 0x1c1000 + +#define AR9170_TIMER_REG_WATCH_DOG (AR9170_TIMER_REG_BASE + 0x000) +#define AR9170_TIMER_REG_TIMER0 (AR9170_TIMER_REG_BASE + 0x010) +#define AR9170_TIMER_REG_TIMER1 (AR9170_TIMER_REG_BASE + 0x014) +#define AR9170_TIMER_REG_TIMER2 (AR9170_TIMER_REG_BASE + 0x018) +#define AR9170_TIMER_REG_TIMER3 (AR9170_TIMER_REG_BASE + 0x01c) +#define AR9170_TIMER_REG_TIMER4 (AR9170_TIMER_REG_BASE + 0x020) +#define AR9170_TIMER_REG_CONTROL (AR9170_TIMER_REG_BASE + 0x024) +#define AR9170_TIMER_CTRL_DISABLE_CLOCK 0x100 + +#define AR9170_TIMER_REG_INTERRUPT (AR9170_TIMER_REG_BASE + 0x028) +#define AR9170_TIMER_INT_TIMER0 0x001 +#define AR9170_TIMER_INT_TIMER1 0x002 +#define AR9170_TIMER_INT_TIMER2 0x004 +#define AR9170_TIMER_INT_TIMER3 0x008 +#define AR9170_TIMER_INT_TIMER4 0x010 +#define AR9170_TIMER_INT_TICK_TIMER 0x100 + +#define AR9170_TIMER_REG_TICK_TIMER (AR9170_TIMER_REG_BASE + 0x030) +#define AR9170_TIMER_REG_CLOCK_LOW (AR9170_TIMER_REG_BASE + 0x040) +#define AR9170_TIMER_REG_CLOCK_HIGH (AR9170_TIMER_REG_BASE + 0x044) + +#define AR9170_MAC_REG_BASE 0x1c3000 + +#define AR9170_MAC_REG_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x500) +#define AR9170_MAC_POWER_STATE_CTRL_RESET 0x20 + +#define AR9170_MAC_REG_MAC_POWER_STATE_CTRL (AR9170_MAC_REG_BASE + 0x50c) + +#define AR9170_MAC_REG_INT_CTRL (AR9170_MAC_REG_BASE + 0x510) +#define AR9170_MAC_INT_TXC BIT(0) +#define AR9170_MAC_INT_RXC BIT(1) +#define AR9170_MAC_INT_RETRY_FAIL BIT(2) +#define AR9170_MAC_INT_WAKEUP BIT(3) +#define AR9170_MAC_INT_ATIM BIT(4) +#define AR9170_MAC_INT_DTIM BIT(5) +#define AR9170_MAC_INT_CFG_BCN BIT(6) +#define AR9170_MAC_INT_ABORT BIT(7) +#define AR9170_MAC_INT_QOS BIT(8) +#define AR9170_MAC_INT_MIMO_PS BIT(9) +#define AR9170_MAC_INT_KEY_GEN BIT(10) +#define AR9170_MAC_INT_DECRY_NOUSER BIT(11) +#define AR9170_MAC_INT_RADAR BIT(12) +#define AR9170_MAC_INT_QUIET_FRAME BIT(13) +#define AR9170_MAC_INT_PRETBTT BIT(14) + +#define AR9170_MAC_REG_TSF_L (AR9170_MAC_REG_BASE + 0x514) +#define AR9170_MAC_REG_TSF_H (AR9170_MAC_REG_BASE + 0x518) + +#define AR9170_MAC_REG_ATIM_WINDOW (AR9170_MAC_REG_BASE + 0x51c) +#define AR9170_MAC_ATIM_PERIOD_S 0 +#define AR9170_MAC_ATIM_PERIOD 0x0000ffff + +#define AR9170_MAC_REG_BCN_PERIOD (AR9170_MAC_REG_BASE + 0x520) +#define AR9170_MAC_BCN_PERIOD_S 0 +#define AR9170_MAC_BCN_PERIOD 0x0000ffff +#define AR9170_MAC_BCN_DTIM_S 16 +#define AR9170_MAC_BCN_DTIM 0x00ff0000 +#define AR9170_MAC_BCN_AP_MODE BIT(24) +#define AR9170_MAC_BCN_IBSS_MODE BIT(25) +#define AR9170_MAC_BCN_PWR_MGT BIT(26) +#define AR9170_MAC_BCN_STA_PS BIT(27) + +#define AR9170_MAC_REG_PRETBTT (AR9170_MAC_REG_BASE + 0x524) +#define AR9170_MAC_PRETBTT_S 0 +#define AR9170_MAC_PRETBTT 0x0000ffff +#define AR9170_MAC_PRETBTT2_S 16 +#define AR9170_MAC_PRETBTT2 0xffff0000 + +#define AR9170_MAC_REG_MAC_ADDR_L (AR9170_MAC_REG_BASE + 0x610) +#define AR9170_MAC_REG_MAC_ADDR_H (AR9170_MAC_REG_BASE + 0x614) +#define AR9170_MAC_REG_BSSID_L (AR9170_MAC_REG_BASE + 0x618) +#define AR9170_MAC_REG_BSSID_H (AR9170_MAC_REG_BASE + 0x61c) + +#define AR9170_MAC_REG_GROUP_HASH_TBL_L (AR9170_MAC_REG_BASE + 0x624) +#define AR9170_MAC_REG_GROUP_HASH_TBL_H (AR9170_MAC_REG_BASE + 0x628) + +#define AR9170_MAC_REG_RX_TIMEOUT (AR9170_MAC_REG_BASE + 0x62c) + +#define AR9170_MAC_REG_BASIC_RATE (AR9170_MAC_REG_BASE + 0x630) +#define AR9170_MAC_REG_MANDATORY_RATE (AR9170_MAC_REG_BASE + 0x634) +#define AR9170_MAC_REG_RTS_CTS_RATE (AR9170_MAC_REG_BASE + 0x638) +#define AR9170_MAC_REG_BACKOFF_PROTECT (AR9170_MAC_REG_BASE + 0x63c) +#define AR9170_MAC_REG_RX_THRESHOLD (AR9170_MAC_REG_BASE + 0x640) +#define AR9170_MAC_REG_AFTER_PNP (AR9170_MAC_REG_BASE + 0x648) +#define AR9170_MAC_REG_RX_PE_DELAY (AR9170_MAC_REG_BASE + 0x64c) + +#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK (AR9170_MAC_REG_BASE + 0x658) +#define AR9170_MAC_REG_SNIFFER (AR9170_MAC_REG_BASE + 0x674) +#define AR9170_MAC_SNIFFER_ENABLE_PROMISC BIT(0) +#define AR9170_MAC_SNIFFER_DEFAULTS 0x02000000 +#define AR9170_MAC_REG_ENCRYPTION (AR9170_MAC_REG_BASE + 0x678) +#define AR9170_MAC_ENCRYPTION_RX_SOFTWARE BIT(3) +#define AR9170_MAC_ENCRYPTION_DEFAULTS 0x70 + +#define AR9170_MAC_REG_MISC_680 (AR9170_MAC_REG_BASE + 0x680) +#define AR9170_MAC_REG_MISC_684 (AR9170_MAC_REG_BASE + 0x684) +#define AR9170_MAC_REG_TX_UNDERRUN (AR9170_MAC_REG_BASE + 0x688) + +#define AR9170_MAC_REG_FRAMETYPE_FILTER (AR9170_MAC_REG_BASE + 0x68c) +#define AR9170_MAC_FTF_ASSOC_REQ BIT(0) +#define AR9170_MAC_FTF_ASSOC_RESP BIT(1) +#define AR9170_MAC_FTF_REASSOC_REQ BIT(2) +#define AR9170_MAC_FTF_REASSOC_RESP BIT(3) +#define AR9170_MAC_FTF_PRB_REQ BIT(4) +#define AR9170_MAC_FTF_PRB_RESP BIT(5) +#define AR9170_MAC_FTF_BIT6 BIT(6) +#define AR9170_MAC_FTF_BIT7 BIT(7) +#define AR9170_MAC_FTF_BEACON BIT(8) +#define AR9170_MAC_FTF_ATIM BIT(9) +#define AR9170_MAC_FTF_DEASSOC BIT(10) +#define AR9170_MAC_FTF_AUTH BIT(11) +#define AR9170_MAC_FTF_DEAUTH BIT(12) +#define AR9170_MAC_FTF_BIT13 BIT(13) +#define AR9170_MAC_FTF_BIT14 BIT(14) +#define AR9170_MAC_FTF_BIT15 BIT(15) +#define AR9170_MAC_FTF_BAR BIT(24) +#define AR9170_MAC_FTF_BA BIT(25) +#define AR9170_MAC_FTF_PSPOLL BIT(26) +#define AR9170_MAC_FTF_RTS BIT(27) +#define AR9170_MAC_FTF_CTS BIT(28) +#define AR9170_MAC_FTF_ACK BIT(29) +#define AR9170_MAC_FTF_CFE BIT(30) +#define AR9170_MAC_FTF_CFE_ACK BIT(31) +#define AR9170_MAC_FTF_DEFAULTS 0x0500ffff +#define AR9170_MAC_FTF_MONITOR 0xff00ffff + +#define AR9170_MAC_REG_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0x690) +#define AR9170_MAC_REG_ACK_TPC (AR9170_MAC_REG_BASE + 0x694) +#define AR9170_MAC_REG_EIFS_AND_SIFS (AR9170_MAC_REG_BASE + 0x698) +#define AR9170_MAC_REG_RX_TIMEOUT_COUNT (AR9170_MAC_REG_BASE + 0x69c) +#define AR9170_MAC_REG_RX_TOTAL (AR9170_MAC_REG_BASE + 0x6a0) +#define AR9170_MAC_REG_RX_CRC32 (AR9170_MAC_REG_BASE + 0x6a4) +#define AR9170_MAC_REG_RX_CRC16 (AR9170_MAC_REG_BASE + 0x6a8) +#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI (AR9170_MAC_REG_BASE + 0x6ac) +#define AR9170_MAC_REG_RX_OVERRUN (AR9170_MAC_REG_BASE + 0x6b0) +#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL (AR9170_MAC_REG_BASE + 0x6bc) +#define AR9170_MAC_REG_TX_BLOCKACKS (AR9170_MAC_REG_BASE + 0x6c0) +#define AR9170_MAC_REG_NAV_COUNT (AR9170_MAC_REG_BASE + 0x6c4) +#define AR9170_MAC_REG_BACKOFF_STATUS (AR9170_MAC_REG_BASE + 0x6c8) +#define AR9170_MAC_REG_TX_RETRY (AR9170_MAC_REG_BASE + 0x6cc) + +#define AR9170_MAC_REG_TX_COMPLETE (AR9170_MAC_REG_BASE + 0x6d4) + +#define AR9170_MAC_REG_CHANNEL_BUSY (AR9170_MAC_REG_BASE + 0x6e8) +#define AR9170_MAC_REG_EXT_BUSY (AR9170_MAC_REG_BASE + 0x6ec) + +#define AR9170_MAC_REG_SLOT_TIME (AR9170_MAC_REG_BASE + 0x6f0) +#define AR9170_MAC_REG_TX_TOTAL (AR9170_MAC_REG_BASE + 0x6f4) +#define AR9170_MAC_REG_ACK_FC (AR9170_MAC_REG_BASE + 0x6f8) + +#define AR9170_MAC_REG_CAM_MODE (AR9170_MAC_REG_BASE + 0x700) +#define AR9170_MAC_CAM_IBSS 0xe0 +#define AR9170_MAC_CAM_AP 0xa1 +#define AR9170_MAC_CAM_STA 0x2 +#define AR9170_MAC_CAM_AP_WDS 0x3 +#define AR9170_MAC_CAM_DEFAULTS (0xf << 24) +#define AR9170_MAC_CAM_HOST_PENDING 0x80000000 + +#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_L (AR9170_MAC_REG_BASE + 0x704) +#define AR9170_MAC_REG_CAM_ROLL_CALL_TBL_H (AR9170_MAC_REG_BASE + 0x708) + +#define AR9170_MAC_REG_CAM_ADDR (AR9170_MAC_REG_BASE + 0x70c) +#define AR9170_MAC_CAM_ADDR_WRITE 0x80000000 +#define AR9170_MAC_REG_CAM_DATA0 (AR9170_MAC_REG_BASE + 0x720) +#define AR9170_MAC_REG_CAM_DATA1 (AR9170_MAC_REG_BASE + 0x724) +#define AR9170_MAC_REG_CAM_DATA2 (AR9170_MAC_REG_BASE + 0x728) +#define AR9170_MAC_REG_CAM_DATA3 (AR9170_MAC_REG_BASE + 0x72c) + +#define AR9170_MAC_REG_CAM_DBG0 (AR9170_MAC_REG_BASE + 0x730) +#define AR9170_MAC_REG_CAM_DBG1 (AR9170_MAC_REG_BASE + 0x734) +#define AR9170_MAC_REG_CAM_DBG2 (AR9170_MAC_REG_BASE + 0x738) +#define AR9170_MAC_REG_CAM_STATE (AR9170_MAC_REG_BASE + 0x73c) +#define AR9170_MAC_CAM_STATE_READ_PENDING 0x40000000 +#define AR9170_MAC_CAM_STATE_WRITE_PENDING 0x80000000 + +#define AR9170_MAC_REG_CAM_TXKEY (AR9170_MAC_REG_BASE + 0x740) +#define AR9170_MAC_REG_CAM_RXKEY (AR9170_MAC_REG_BASE + 0x750) + +#define AR9170_MAC_REG_CAM_TX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x760) +#define AR9170_MAC_REG_CAM_RX_ENC_TYPE (AR9170_MAC_REG_BASE + 0x770) +#define AR9170_MAC_REG_CAM_TX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x780) +#define AR9170_MAC_REG_CAM_RX_SERACH_HIT (AR9170_MAC_REG_BASE + 0x790) + +#define AR9170_MAC_REG_AC0_CW (AR9170_MAC_REG_BASE + 0xb00) +#define AR9170_MAC_REG_AC1_CW (AR9170_MAC_REG_BASE + 0xb04) +#define AR9170_MAC_REG_AC2_CW (AR9170_MAC_REG_BASE + 0xb08) +#define AR9170_MAC_REG_AC3_CW (AR9170_MAC_REG_BASE + 0xb0c) +#define AR9170_MAC_REG_AC4_CW (AR9170_MAC_REG_BASE + 0xb10) +#define AR9170_MAC_REG_AC2_AC1_AC0_AIFS (AR9170_MAC_REG_BASE + 0xb14) +#define AR9170_MAC_REG_AC4_AC3_AC2_AIFS (AR9170_MAC_REG_BASE + 0xb18) +#define AR9170_MAC_REG_TXOP_ACK_EXTENSION (AR9170_MAC_REG_BASE + 0xb1c) +#define AR9170_MAC_REG_TXOP_ACK_INTERVAL (AR9170_MAC_REG_BASE + 0xb20) +#define AR9170_MAC_REG_CONTENTION_POINT (AR9170_MAC_REG_BASE + 0xb24) +#define AR9170_MAC_REG_RETRY_MAX (AR9170_MAC_REG_BASE + 0xb28) +#define AR9170_MAC_REG_TID_CFACK_CFEND_RATE (AR9170_MAC_REG_BASE + 0xb2c) +#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND (AR9170_MAC_REG_BASE + 0xb30) +#define AR9170_MAC_REG_TKIP_TSC (AR9170_MAC_REG_BASE + 0xb34) +#define AR9170_MAC_REG_TXOP_DURATION (AR9170_MAC_REG_BASE + 0xb38) +#define AR9170_MAC_REG_TX_QOS_THRESHOLD (AR9170_MAC_REG_BASE + 0xb3c) +#define AR9170_MAC_REG_QOS_PRIORITY_VIRTUAL_CCA (AR9170_MAC_REG_BASE + 0xb40) +#define AR9170_MAC_VIRTUAL_CCA_Q0 BIT(15) +#define AR9170_MAC_VIRTUAL_CCA_Q1 BIT(16) +#define AR9170_MAC_VIRTUAL_CCA_Q2 BIT(17) +#define AR9170_MAC_VIRTUAL_CCA_Q3 BIT(18) +#define AR9170_MAC_VIRTUAL_CCA_Q4 BIT(19) +#define AR9170_MAC_VIRTUAL_CCA_ALL (0xf8000) + +#define AR9170_MAC_REG_AC1_AC0_TXOP (AR9170_MAC_REG_BASE + 0xb44) +#define AR9170_MAC_REG_AC3_AC2_TXOP (AR9170_MAC_REG_BASE + 0xb48) + +#define AR9170_MAC_REG_AMPDU_COUNT (AR9170_MAC_REG_BASE + 0xb88) +#define AR9170_MAC_REG_MPDU_COUNT (AR9170_MAC_REG_BASE + 0xb8c) + +#define AR9170_MAC_REG_AMPDU_FACTOR (AR9170_MAC_REG_BASE + 0xb9c) +#define AR9170_MAC_AMPDU_FACTOR 0x7f0000 +#define AR9170_MAC_AMPDU_FACTOR_S 16 +#define AR9170_MAC_REG_AMPDU_DENSITY (AR9170_MAC_REG_BASE + 0xba0) +#define AR9170_MAC_AMPDU_DENSITY 0x7 +#define AR9170_MAC_AMPDU_DENSITY_S 0 + +#define AR9170_MAC_REG_FCS_SELECT (AR9170_MAC_REG_BASE + 0xbb0) +#define AR9170_MAC_FCS_SWFCS 0x1 +#define AR9170_MAC_FCS_FIFO_PROT 0x4 + +#define AR9170_MAC_REG_RTS_CTS_TPC (AR9170_MAC_REG_BASE + 0xbb4) +#define AR9170_MAC_REG_CFEND_QOSNULL_TPC (AR9170_MAC_REG_BASE + 0xbb8) + +#define AR9170_MAC_REG_ACK_TABLE (AR9170_MAC_REG_BASE + 0xc00) +#define AR9170_MAC_REG_RX_CONTROL (AR9170_MAC_REG_BASE + 0xc40) +#define AR9170_MAC_RX_CTRL_DEAGG 0x1 +#define AR9170_MAC_RX_CTRL_SHORT_FILTER 0x2 +#define AR9170_MAC_RX_CTRL_SA_DA_SEARCH 0x20 +#define AR9170_MAC_RX_CTRL_PASS_TO_HOST BIT(28) +#define AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER BIT(30) + +#define AR9170_MAC_REG_RX_CONTROL_1 (AR9170_MAC_REG_BASE + 0xc44) + +#define AR9170_MAC_REG_AMPDU_RX_THRESH (AR9170_MAC_REG_BASE + 0xc50) + +#define AR9170_MAC_REG_RX_MPDU (AR9170_MAC_REG_BASE + 0xca0) +#define AR9170_MAC_REG_RX_DROPPED_MPDU (AR9170_MAC_REG_BASE + 0xca4) +#define AR9170_MAC_REG_RX_DEL_MPDU (AR9170_MAC_REG_BASE + 0xca8) +#define AR9170_MAC_REG_RX_PHY_MISC_ERROR (AR9170_MAC_REG_BASE + 0xcac) +#define AR9170_MAC_REG_RX_PHY_XR_ERROR (AR9170_MAC_REG_BASE + 0xcb0) +#define AR9170_MAC_REG_RX_PHY_OFDM_ERROR (AR9170_MAC_REG_BASE + 0xcb4) +#define AR9170_MAC_REG_RX_PHY_CCK_ERROR (AR9170_MAC_REG_BASE + 0xcb8) +#define AR9170_MAC_REG_RX_PHY_HT_ERROR (AR9170_MAC_REG_BASE + 0xcbc) +#define AR9170_MAC_REG_RX_PHY_TOTAL (AR9170_MAC_REG_BASE + 0xcc0) + +#define AR9170_MAC_REG_DMA_TXQ_ADDR (AR9170_MAC_REG_BASE + 0xd00) +#define AR9170_MAC_REG_DMA_TXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04) +#define AR9170_MAC_REG_DMA_TXQ0_ADDR (AR9170_MAC_REG_BASE + 0xd00) +#define AR9170_MAC_REG_DMA_TXQ0_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd04) +#define AR9170_MAC_REG_DMA_TXQ1_ADDR (AR9170_MAC_REG_BASE + 0xd08) +#define AR9170_MAC_REG_DMA_TXQ1_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd0c) +#define AR9170_MAC_REG_DMA_TXQ2_ADDR (AR9170_MAC_REG_BASE + 0xd10) +#define AR9170_MAC_REG_DMA_TXQ2_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd14) +#define AR9170_MAC_REG_DMA_TXQ3_ADDR (AR9170_MAC_REG_BASE + 0xd18) +#define AR9170_MAC_REG_DMA_TXQ3_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd1c) +#define AR9170_MAC_REG_DMA_TXQ4_ADDR (AR9170_MAC_REG_BASE + 0xd20) +#define AR9170_MAC_REG_DMA_TXQ4_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd24) +#define AR9170_MAC_REG_DMA_RXQ_ADDR (AR9170_MAC_REG_BASE + 0xd28) +#define AR9170_MAC_REG_DMA_RXQ_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd2c) + +#define AR9170_MAC_REG_DMA_TRIGGER (AR9170_MAC_REG_BASE + 0xd30) +#define AR9170_DMA_TRIGGER_TXQ0 BIT(0) +#define AR9170_DMA_TRIGGER_TXQ1 BIT(1) +#define AR9170_DMA_TRIGGER_TXQ2 BIT(2) +#define AR9170_DMA_TRIGGER_TXQ3 BIT(3) +#define AR9170_DMA_TRIGGER_TXQ4 BIT(4) +#define AR9170_DMA_TRIGGER_RXQ BIT(8) + +#define AR9170_MAC_REG_DMA_WLAN_STATUS (AR9170_MAC_REG_BASE + 0xd38) +#define AR9170_MAC_REG_DMA_STATUS (AR9170_MAC_REG_BASE + 0xd3c) + +#define AR9170_MAC_REG_TXRX_MPI (AR9170_MAC_REG_BASE + 0xd7c) +#define AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f +#define AR9170_MAC_TXRX_MPI_TX_TO_MASK 0x0000fff0 +#define AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000 +#define AR9170_MAC_TXRX_MPI_RX_TO_MASK 0xfff00000 + +#define AR9170_MAC_REG_BCN_ADDR (AR9170_MAC_REG_BASE + 0xd84) +#define AR9170_MAC_REG_BCN_LENGTH (AR9170_MAC_REG_BASE + 0xd88) +#define AR9170_MAC_BCN_LENGTH_MAX 256 + +#define AR9170_MAC_REG_BCN_STATUS (AR9170_MAC_REG_BASE + 0xd8c) + +#define AR9170_MAC_REG_BCN_PLCP (AR9170_MAC_REG_BASE + 0xd90) +#define AR9170_MAC_REG_BCN_CTRL (AR9170_MAC_REG_BASE + 0xd94) +#define AR9170_BCN_CTRL_READY 0x01 +#define AR9170_BCN_CTRL_LOCK 0x02 + +#define AR9170_MAC_REG_BCN_CURR_ADDR (AR9170_MAC_REG_BASE + 0xd98) +#define AR9170_MAC_REG_BCN_COUNT (AR9170_MAC_REG_BASE + 0xd9c) + + +#define AR9170_MAC_REG_BCN_HT1 (AR9170_MAC_REG_BASE + 0xda0) +#define AR9170_MAC_REG_BCN_HT2 (AR9170_MAC_REG_BASE + 0xda4) + +#define AR9170_MAC_REG_DMA_TXQX_ADDR_CURR (AR9170_MAC_REG_BASE + 0xdc0) + +/* Random number generator */ +#define AR9170_RAND_REG_BASE 0x1d0000 + +#define AR9170_RAND_REG_NUM (AR9170_RAND_REG_BASE + 0x000) +#define AR9170_RAND_REG_MODE (AR9170_RAND_REG_BASE + 0x004) +#define AR9170_RAND_MODE_MANUAL 0x000 +#define AR9170_RAND_MODE_FREE 0x001 + +/* GPIO */ +#define AR9170_GPIO_REG_BASE 0x1d0100 +#define AR9170_GPIO_REG_PORT_TYPE (AR9170_GPIO_REG_BASE + 0x000) +#define AR9170_GPIO_REG_PORT_DATA (AR9170_GPIO_REG_BASE + 0x004) +#define AR9170_GPIO_PORT_LED_0 1 +#define AR9170_GPIO_PORT_LED_1 2 +/* WPS Button GPIO for TP-Link TL-WN821N */ +#define AR9170_GPIO_PORT_WPS_BUTTON_PRESSED 4 + +/* Memory Controller */ +#define AR9170_MC_REG_BASE 0x1d1000 + +#define AR9170_MC_REG_FLASH_WAIT_STATE (AR9170_MC_REG_BASE + 0x000) +#define AR9170_MC_REG_SEEPROM_WP0 (AR9170_MC_REG_BASE + 0x400) +#define AR9170_MC_REG_SEEPROM_WP1 (AR9170_MC_REG_BASE + 0x404) +#define AR9170_MC_REG_SEEPROM_WP2 (AR9170_MC_REG_BASE + 0x408) + +/* Interrupt Controller */ +#define AR9170_MAX_INT_SRC 9 +#define AR9170_INT_REG_BASE 0x1d2000 + +#define AR9170_INT_REG_FLAG (AR9170_INT_REG_BASE + 0x000) +#define AR9170_INT_REG_FIQ_MASK (AR9170_INT_REG_BASE + 0x004) +#define AR9170_INT_REG_IRQ_MASK (AR9170_INT_REG_BASE + 0x008) +/* INT_REG_FLAG, INT_REG_FIQ_MASK and INT_REG_IRQ_MASK */ +#define AR9170_INT_FLAG_WLAN 0x001 +#define AR9170_INT_FLAG_PTAB_BIT 0x002 +#define AR9170_INT_FLAG_SE_BIT 0x004 +#define AR9170_INT_FLAG_UART_BIT 0x008 +#define AR9170_INT_FLAG_TIMER_BIT 0x010 +#define AR9170_INT_FLAG_EXT_BIT 0x020 +#define AR9170_INT_FLAG_SW_BIT 0x040 +#define AR9170_INT_FLAG_USB_BIT 0x080 +#define AR9170_INT_FLAG_ETHERNET_BIT 0x100 + +#define AR9170_INT_REG_PRIORITY1 (AR9170_INT_REG_BASE + 0x00c) +#define AR9170_INT_REG_PRIORITY2 (AR9170_INT_REG_BASE + 0x010) +#define AR9170_INT_REG_PRIORITY3 (AR9170_INT_REG_BASE + 0x014) +#define AR9170_INT_REG_EXT_INT_CONTROL (AR9170_INT_REG_BASE + 0x018) +#define AR9170_INT_REG_SW_INT_CONTROL (AR9170_INT_REG_BASE + 0x01c) +#define AR9170_INT_SW_INT_ENABLE 0x1 + +#define AR9170_INT_REG_FIQ_ENCODE (AR9170_INT_REG_BASE + 0x020) +#define AR9170_INT_INT_IRQ_ENCODE (AR9170_INT_REG_BASE + 0x024) + +/* Power Management */ +#define AR9170_PWR_REG_BASE 0x1d4000 + +#define AR9170_PWR_REG_POWER_STATE (AR9170_PWR_REG_BASE + 0x000) + +#define AR9170_PWR_REG_RESET (AR9170_PWR_REG_BASE + 0x004) +#define AR9170_PWR_RESET_COMMIT_RESET_MASK BIT(0) +#define AR9170_PWR_RESET_WLAN_MASK BIT(1) +#define AR9170_PWR_RESET_DMA_MASK BIT(2) +#define AR9170_PWR_RESET_BRIDGE_MASK BIT(3) +#define AR9170_PWR_RESET_AHB_MASK BIT(9) +#define AR9170_PWR_RESET_BB_WARM_RESET BIT(10) +#define AR9170_PWR_RESET_BB_COLD_RESET BIT(11) +#define AR9170_PWR_RESET_ADDA_CLK_COLD_RESET BIT(12) +#define AR9170_PWR_RESET_PLL BIT(13) +#define AR9170_PWR_RESET_USB_PLL BIT(14) + +#define AR9170_PWR_REG_CLOCK_SEL (AR9170_PWR_REG_BASE + 0x008) +#define AR9170_PWR_CLK_AHB_40MHZ 0 +#define AR9170_PWR_CLK_AHB_20_22MHZ 1 +#define AR9170_PWR_CLK_AHB_40_44MHZ 2 +#define AR9170_PWR_CLK_AHB_80_88MHZ 3 +#define AR9170_PWR_CLK_DAC_160_INV_DLY 0x70 + +#define AR9170_PWR_REG_CHIP_REVISION (AR9170_PWR_REG_BASE + 0x010) +#define AR9170_PWR_REG_PLL_ADDAC (AR9170_PWR_REG_BASE + 0x014) +#define AR9170_PWR_REG_WATCH_DOG_MAGIC (AR9170_PWR_REG_BASE + 0x020) + +/* Faraday USB Controller */ +#define AR9170_USB_REG_BASE 0x1e1000 + +#define AR9170_USB_REG_MAIN_CTRL (AR9170_USB_REG_BASE + 0x000) +#define AR9170_USB_MAIN_CTRL_REMOTE_WAKEUP BIT(0) +#define AR9170_USB_MAIN_CTRL_ENABLE_GLOBAL_INT BIT(2) +#define AR9170_USB_MAIN_CTRL_HIGHSPEED BIT(6) + +#define AR9170_USB_REG_DEVICE_ADDRESS (AR9170_USB_REG_BASE + 0x001) +#define AR9170_USB_DEVICE_ADDRESS_CONFIGURE BIT(7) + +#define AR9170_USB_REG_TEST (AR9170_USB_REG_BASE + 0x002) +#define AR9170_USB_REG_PHY_TEST_SELECT (AR9170_USB_REG_BASE + 0x008) +#define AR9170_USB_REG_CX_CONFIG_STATUS (AR9170_USB_REG_BASE + 0x00b) +#define AR9170_USB_REG_EP0_DATA (AR9170_USB_REG_BASE + 0x00c) +#define AR9170_USB_REG_EP0_DATA1 (AR9170_USB_REG_BASE + 0x00c) +#define AR9170_USB_REG_EP0_DATA2 (AR9170_USB_REG_BASE + 0x00d) + +#define AR9170_USB_REG_INTR_MASK_BYTE_0 (AR9170_USB_REG_BASE + 0x011) +#define AR9170_USB_REG_INTR_MASK_BYTE_1 (AR9170_USB_REG_BASE + 0x012) +#define AR9170_USB_REG_INTR_MASK_BYTE_2 (AR9170_USB_REG_BASE + 0x013) +#define AR9170_USB_REG_INTR_MASK_BYTE_3 (AR9170_USB_REG_BASE + 0x014) +#define AR9170_USB_REG_INTR_MASK_BYTE_4 (AR9170_USB_REG_BASE + 0x015) +#define AR9170_USB_INTR_DISABLE_OUT_INT (BIT(7) | BIT(6)) + +#define AR9170_USB_REG_INTR_MASK_BYTE_5 (AR9170_USB_REG_BASE + 0x016) +#define AR9170_USB_REG_INTR_MASK_BYTE_6 (AR9170_USB_REG_BASE + 0x017) +#define AR9170_USB_INTR_DISABLE_IN_INT BIT(6) + +#define AR9170_USB_REG_INTR_MASK_BYTE_7 (AR9170_USB_REG_BASE + 0x018) + +#define AR9170_USB_REG_INTR_GROUP (AR9170_USB_REG_BASE + 0x020) + +#define AR9170_USB_REG_INTR_SOURCE_0 (AR9170_USB_REG_BASE + 0x021) +#define AR9170_USB_REG_INTR_SOURCE_1 (AR9170_USB_REG_BASE + 0x022) +#define AR9170_USB_REG_INTR_SOURCE_2 (AR9170_USB_REG_BASE + 0x023) +#define AR9170_USB_REG_INTR_SOURCE_3 (AR9170_USB_REG_BASE + 0x024) +#define AR9170_USB_REG_INTR_SOURCE_4 (AR9170_USB_REG_BASE + 0x025) +#define AR9170_USB_REG_INTR_SOURCE_5 (AR9170_USB_REG_BASE + 0x026) +#define AR9170_USB_REG_INTR_SOURCE_6 (AR9170_USB_REG_BASE + 0x027) +#define AR9170_USB_REG_INTR_SOURCE_7 (AR9170_USB_REG_BASE + 0x028) + +#define AR9170_USB_REG_EP_MAP (AR9170_USB_REG_BASE + 0x030) +#define AR9170_USB_REG_EP1_MAP (AR9170_USB_REG_BASE + 0x030) +#define AR9170_USB_REG_EP2_MAP (AR9170_USB_REG_BASE + 0x031) +#define AR9170_USB_REG_EP3_MAP (AR9170_USB_REG_BASE + 0x032) +#define AR9170_USB_REG_EP4_MAP (AR9170_USB_REG_BASE + 0x033) +#define AR9170_USB_REG_EP5_MAP (AR9170_USB_REG_BASE + 0x034) +#define AR9170_USB_REG_EP6_MAP (AR9170_USB_REG_BASE + 0x035) +#define AR9170_USB_REG_EP7_MAP (AR9170_USB_REG_BASE + 0x036) +#define AR9170_USB_REG_EP8_MAP (AR9170_USB_REG_BASE + 0x037) +#define AR9170_USB_REG_EP9_MAP (AR9170_USB_REG_BASE + 0x038) +#define AR9170_USB_REG_EP10_MAP (AR9170_USB_REG_BASE + 0x039) + +#define AR9170_USB_REG_EP_IN_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x03f) +#define AR9170_USB_EP_IN_TOGGLE 0x10 + +#define AR9170_USB_REG_EP_IN_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x03e) + +#define AR9170_USB_REG_EP_OUT_MAX_SIZE_HIGH (AR9170_USB_REG_BASE + 0x05f) +#define AR9170_USB_EP_OUT_TOGGLE 0x10 + +#define AR9170_USB_REG_EP_OUT_MAX_SIZE_LOW (AR9170_USB_REG_BASE + 0x05e) + +#define AR9170_USB_REG_EP3_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0ae) +#define AR9170_USB_REG_EP3_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0be) +#define AR9170_USB_REG_EP4_BYTE_COUNT_HIGH (AR9170_USB_REG_BASE + 0x0af) +#define AR9170_USB_REG_EP4_BYTE_COUNT_LOW (AR9170_USB_REG_BASE + 0x0bf) + +#define AR9170_USB_REG_FIFO_MAP (AR9170_USB_REG_BASE + 0x080) +#define AR9170_USB_REG_FIFO0_MAP (AR9170_USB_REG_BASE + 0x080) +#define AR9170_USB_REG_FIFO1_MAP (AR9170_USB_REG_BASE + 0x081) +#define AR9170_USB_REG_FIFO2_MAP (AR9170_USB_REG_BASE + 0x082) +#define AR9170_USB_REG_FIFO3_MAP (AR9170_USB_REG_BASE + 0x083) +#define AR9170_USB_REG_FIFO4_MAP (AR9170_USB_REG_BASE + 0x084) +#define AR9170_USB_REG_FIFO5_MAP (AR9170_USB_REG_BASE + 0x085) +#define AR9170_USB_REG_FIFO6_MAP (AR9170_USB_REG_BASE + 0x086) +#define AR9170_USB_REG_FIFO7_MAP (AR9170_USB_REG_BASE + 0x087) +#define AR9170_USB_REG_FIFO8_MAP (AR9170_USB_REG_BASE + 0x088) +#define AR9170_USB_REG_FIFO9_MAP (AR9170_USB_REG_BASE + 0x089) + +#define AR9170_USB_REG_FIFO_CONFIG (AR9170_USB_REG_BASE + 0x090) +#define AR9170_USB_REG_FIFO0_CONFIG (AR9170_USB_REG_BASE + 0x090) +#define AR9170_USB_REG_FIFO1_CONFIG (AR9170_USB_REG_BASE + 0x091) +#define AR9170_USB_REG_FIFO2_CONFIG (AR9170_USB_REG_BASE + 0x092) +#define AR9170_USB_REG_FIFO3_CONFIG (AR9170_USB_REG_BASE + 0x093) +#define AR9170_USB_REG_FIFO4_CONFIG (AR9170_USB_REG_BASE + 0x094) +#define AR9170_USB_REG_FIFO5_CONFIG (AR9170_USB_REG_BASE + 0x095) +#define AR9170_USB_REG_FIFO6_CONFIG (AR9170_USB_REG_BASE + 0x096) +#define AR9170_USB_REG_FIFO7_CONFIG (AR9170_USB_REG_BASE + 0x097) +#define AR9170_USB_REG_FIFO8_CONFIG (AR9170_USB_REG_BASE + 0x098) +#define AR9170_USB_REG_FIFO9_CONFIG (AR9170_USB_REG_BASE + 0x099) + +#define AR9170_USB_REG_EP3_DATA (AR9170_USB_REG_BASE + 0x0f8) +#define AR9170_USB_REG_EP4_DATA (AR9170_USB_REG_BASE + 0x0fc) + +#define AR9170_USB_REG_FIFO_SIZE (AR9170_USB_REG_BASE + 0x100) +#define AR9170_USB_REG_DMA_CTL (AR9170_USB_REG_BASE + 0x108) +#define AR9170_USB_DMA_CTL_ENABLE_TO_DEVICE BIT(0) +#define AR9170_USB_DMA_CTL_ENABLE_FROM_DEVICE BIT(1) +#define AR9170_USB_DMA_CTL_HIGH_SPEED BIT(2) +#define AR9170_USB_DMA_CTL_UP_PACKET_MODE BIT(3) +#define AR9170_USB_DMA_CTL_UP_STREAM_S 4 +#define AR9170_USB_DMA_CTL_UP_STREAM (BIT(4) | BIT(5)) +#define AR9170_USB_DMA_CTL_UP_STREAM_4K (0) +#define AR9170_USB_DMA_CTL_UP_STREAM_8K BIT(4) +#define AR9170_USB_DMA_CTL_UP_STREAM_16K BIT(5) +#define AR9170_USB_DMA_CTL_UP_STREAM_32K (BIT(4) | BIT(5)) +#define AR9170_USB_DMA_CTL_DOWN_STREAM BIT(6) + +#define AR9170_USB_REG_DMA_STATUS (AR9170_USB_REG_BASE + 0x10c) +#define AR9170_USB_DMA_STATUS_UP_IDLE BIT(8) +#define AR9170_USB_DMA_STATUS_DN_IDLE BIT(16) + +#define AR9170_USB_REG_MAX_AGG_UPLOAD (AR9170_USB_REG_BASE + 0x110) +#define AR9170_USB_REG_UPLOAD_TIME_CTL (AR9170_USB_REG_BASE + 0x114) +#define AR9170_USB_REG_CBUS_CTRL (AR9170_USB_REG_BASE + 0x1f0) +#define AR9170_USB_CBUS_CTRL_BUFFER_END (BIT(1)) + +/* PCI/USB to AHB Bridge */ +#define AR9170_PTA_REG_BASE 0x1e2000 + +#define AR9170_PTA_REG_CMD (AR9170_PTA_REG_BASE + 0x000) +#define AR9170_PTA_REG_PARAM1 (AR9170_PTA_REG_BASE + 0x004) +#define AR9170_PTA_REG_PARAM2 (AR9170_PTA_REG_BASE + 0x008) +#define AR9170_PTA_REG_PARAM3 (AR9170_PTA_REG_BASE + 0x00c) +#define AR9170_PTA_REG_RSP (AR9170_PTA_REG_BASE + 0x010) +#define AR9170_PTA_REG_STATUS1 (AR9170_PTA_REG_BASE + 0x014) +#define AR9170_PTA_REG_STATUS2 (AR9170_PTA_REG_BASE + 0x018) +#define AR9170_PTA_REG_STATUS3 (AR9170_PTA_REG_BASE + 0x01c) +#define AR9170_PTA_REG_AHB_INT_FLAG (AR9170_PTA_REG_BASE + 0x020) +#define AR9170_PTA_REG_AHB_INT_MASK (AR9170_PTA_REG_BASE + 0x024) +#define AR9170_PTA_REG_AHB_INT_ACK (AR9170_PTA_REG_BASE + 0x028) +#define AR9170_PTA_REG_AHB_SCRATCH1 (AR9170_PTA_REG_BASE + 0x030) +#define AR9170_PTA_REG_AHB_SCRATCH2 (AR9170_PTA_REG_BASE + 0x034) +#define AR9170_PTA_REG_AHB_SCRATCH3 (AR9170_PTA_REG_BASE + 0x038) +#define AR9170_PTA_REG_AHB_SCRATCH4 (AR9170_PTA_REG_BASE + 0x03c) + +#define AR9170_PTA_REG_SHARE_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124) + +/* + * PCI to AHB Bridge + */ + +#define AR9170_PTA_REG_INT_FLAG (AR9170_PTA_REG_BASE + 0x100) +#define AR9170_PTA_INT_FLAG_DN 0x01 +#define AR9170_PTA_INT_FLAG_UP 0x02 +#define AR9170_PTA_INT_FLAG_CMD 0x04 + +#define AR9170_PTA_REG_INT_MASK (AR9170_PTA_REG_BASE + 0x104) +#define AR9170_PTA_REG_DN_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x108) +#define AR9170_PTA_REG_DN_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x10c) +#define AR9170_PTA_REG_UP_DMA_ADDRL (AR9170_PTA_REG_BASE + 0x110) +#define AR9170_PTA_REG_UP_DMA_ADDRH (AR9170_PTA_REG_BASE + 0x114) +#define AR9170_PTA_REG_DN_PEND_TIME (AR9170_PTA_REG_BASE + 0x118) +#define AR9170_PTA_REG_UP_PEND_TIME (AR9170_PTA_REG_BASE + 0x11c) +#define AR9170_PTA_REG_CONTROL (AR9170_PTA_REG_BASE + 0x120) +#define AR9170_PTA_CTRL_4_BEAT_BURST 0x00 +#define AR9170_PTA_CTRL_8_BEAT_BURST 0x01 +#define AR9170_PTA_CTRL_16_BEAT_BURST 0x02 +#define AR9170_PTA_CTRL_LOOPBACK_MODE 0x10 + +#define AR9170_PTA_REG_MEM_CTRL (AR9170_PTA_REG_BASE + 0x124) +#define AR9170_PTA_REG_MEM_ADDR (AR9170_PTA_REG_BASE + 0x128) +#define AR9170_PTA_REG_DN_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x12c) +#define AR9170_PTA_REG_UP_DMA_TRIGGER (AR9170_PTA_REG_BASE + 0x130) +#define AR9170_PTA_REG_DMA_STATUS (AR9170_PTA_REG_BASE + 0x134) +#define AR9170_PTA_REG_DN_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x138) +#define AR9170_PTA_REG_DN_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x13c) +#define AR9170_PTA_REG_UP_CURR_ADDRL (AR9170_PTA_REG_BASE + 0x140) +#define AR9170_PTA_REG_UP_CURR_ADDRH (AR9170_PTA_REG_BASE + 0x144) +#define AR9170_PTA_REG_DMA_MODE_CTRL (AR9170_PTA_REG_BASE + 0x148) +#define AR9170_PTA_DMA_MODE_CTRL_RESET BIT(0) +#define AR9170_PTA_DMA_MODE_CTRL_DISABLE_USB BIT(1) + +/* Protocol Controller Module */ +#define AR9170_MAC_REG_PC_REG_BASE (AR9170_MAC_REG_BASE + 0xe00) + + +#define AR9170_NUM_LEDS 2 + +/* CAM */ +#define AR9170_CAM_MAX_USER 64 +#define AR9170_CAM_MAX_KEY_LENGTH 16 + +#define AR9170_SRAM_OFFSET 0x100000 +#define AR9170_SRAM_SIZE 0x18000 + +#define AR9170_PRAM_OFFSET 0x200000 +#define AR9170_PRAM_SIZE 0x8000 + +enum cpu_clock { + AHB_STATIC_40MHZ = 0, + AHB_GMODE_22MHZ = 1, + AHB_AMODE_20MHZ = 1, + AHB_GMODE_44MHZ = 2, + AHB_AMODE_40MHZ = 2, + AHB_GMODE_88MHZ = 3, + AHB_AMODE_80MHZ = 3 +}; + +/* USB endpoints */ +enum ar9170_usb_ep { + /* + * Control EP is always EP 0 (USB SPEC) + * + * The weird thing is: the original firmware has a few + * comments that suggest that the actual EP numbers + * are in the 1 to 10 range?! + */ + AR9170_USB_EP_CTRL = 0, + + AR9170_USB_EP_TX, + AR9170_USB_EP_RX, + AR9170_USB_EP_IRQ, + AR9170_USB_EP_CMD, + AR9170_USB_NUM_EXTRA_EP = 4, + + __AR9170_USB_NUM_EP, + + __AR9170_USB_NUM_MAX_EP = 10 +}; + +enum ar9170_usb_fifo { + __AR9170_USB_NUM_MAX_FIFO = 10 +}; + +enum ar9170_tx_queues { + AR9170_TXQ0 = 0, + AR9170_TXQ1, + AR9170_TXQ2, + AR9170_TXQ3, + AR9170_TXQ_SPECIAL, + + /* keep last */ + __AR9170_NUM_TX_QUEUES = 5 +}; + +#define AR9170_TX_STREAM_TAG 0x697e +#define AR9170_RX_STREAM_TAG 0x4e00 +#define AR9170_RX_STREAM_MAX_SIZE 0xffff + +struct ar9170_stream { + __le16 length; + __le16 tag; + + u8 payload[0]; +}; + +#define AR9170_MAX_ACKTABLE_ENTRIES 8 +#define AR9170_MAX_VIRTUAL_MAC 7 + +#define AR9170_USB_EP_CTRL_MAX 64 +#define AR9170_USB_EP_TX_MAX 512 +#define AR9170_USB_EP_RX_MAX 512 +#define AR9170_USB_EP_IRQ_MAX 64 +#define AR9170_USB_EP_CMD_MAX 64 + +/* Trigger PRETBTT interrupt 6 Kus earlier */ +#define CARL9170_PRETBTT_KUS 6 + +#define AR5416_MAX_RATE_POWER 63 + +#define SET_VAL(reg, value, newvalue) \ + (value = ((value) & ~reg) | (((newvalue) << reg##_S) & reg)) + +#define SET_CONSTVAL(reg, newvalue) \ + (((newvalue) << reg##_S) & reg) + +#define MOD_VAL(reg, value, newvalue) \ + (((value) & ~reg) | (((newvalue) << reg##_S) & reg)) +#endif /* __CARL9170_SHARED_HW_H */ diff --git a/drivers/net/wireless/ath/carl9170/led.c b/drivers/net/wireless/ath/carl9170/led.c new file mode 100644 index 0000000000000000000000000000000000000000..4bb2cbd8bd9b9ccf7975613e021c6f19c18d6d38 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/led.c @@ -0,0 +1,190 @@ +/* + * Atheros CARL9170 driver + * + * LED handling + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "carl9170.h" +#include "cmd.h" + +int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state) +{ + return carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_DATA, led_state); +} + +int carl9170_led_init(struct ar9170 *ar) +{ + int err; + + /* disable LEDs */ + /* GPIO [0/1 mode: output, 2/3: input] */ + err = carl9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3); + if (err) + goto out; + + /* GPIO 0/1 value: off */ + err = carl9170_led_set_state(ar, 0); + +out: + return err; +} + +#ifdef CONFIG_CARL9170_LEDS +static void carl9170_led_update(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, led_work.work); + int i, tmp = 300, blink_delay = 1000; + u32 led_val = 0; + bool rerun = false; + + if (!IS_ACCEPTING_CMD(ar)) + return; + + mutex_lock(&ar->mutex); + for (i = 0; i < AR9170_NUM_LEDS; i++) { + if (ar->leds[i].registered) { + if (ar->leds[i].last_state || + ar->leds[i].toggled) { + + if (ar->leds[i].toggled) + tmp = 70 + 200 / (ar->leds[i].toggled); + + if (tmp < blink_delay) + blink_delay = tmp; + + led_val |= 1 << i; + ar->leds[i].toggled = 0; + rerun = true; + } + } + } + + carl9170_led_set_state(ar, led_val); + mutex_unlock(&ar->mutex); + + if (!rerun) + return; + + ieee80211_queue_delayed_work(ar->hw, + &ar->led_work, + msecs_to_jiffies(blink_delay)); +} + +static void carl9170_led_set_brightness(struct led_classdev *led, + enum led_brightness brightness) +{ + struct carl9170_led *arl = container_of(led, struct carl9170_led, l); + struct ar9170 *ar = arl->ar; + + if (!arl->registered) + return; + + if (arl->last_state != !!brightness) { + arl->toggled++; + arl->last_state = !!brightness; + } + + if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) + ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10); +} + +static int carl9170_led_register_led(struct ar9170 *ar, int i, char *name, + char *trigger) +{ + int err; + + snprintf(ar->leds[i].name, sizeof(ar->leds[i].name), + "carl9170-%s::%s", wiphy_name(ar->hw->wiphy), name); + + ar->leds[i].ar = ar; + ar->leds[i].l.name = ar->leds[i].name; + ar->leds[i].l.brightness_set = carl9170_led_set_brightness; + ar->leds[i].l.brightness = 0; + ar->leds[i].l.default_trigger = trigger; + + err = led_classdev_register(wiphy_dev(ar->hw->wiphy), + &ar->leds[i].l); + if (err) { + wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n", + ar->leds[i].name, err); + } else { + ar->leds[i].registered = true; + } + + return err; +} + +void carl9170_led_unregister(struct ar9170 *ar) +{ + int i; + + for (i = 0; i < AR9170_NUM_LEDS; i++) + if (ar->leds[i].registered) { + led_classdev_unregister(&ar->leds[i].l); + ar->leds[i].registered = false; + ar->leds[i].toggled = 0; + } + + cancel_delayed_work_sync(&ar->led_work); +} + +int carl9170_led_register(struct ar9170 *ar) +{ + int err; + + INIT_DELAYED_WORK(&ar->led_work, carl9170_led_update); + + err = carl9170_led_register_led(ar, 0, "tx", + ieee80211_get_tx_led_name(ar->hw)); + if (err) + goto fail; + + if (ar->features & CARL9170_ONE_LED) + return 0; + + err = carl9170_led_register_led(ar, 1, "assoc", + ieee80211_get_assoc_led_name(ar->hw)); + if (err) + goto fail; + + return 0; + +fail: + carl9170_led_unregister(ar); + return err; +} + +#endif /* CONFIG_CARL9170_LEDS */ diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c new file mode 100644 index 0000000000000000000000000000000000000000..2305bc27151c0a327def9ab3d8d9e196af98cd34 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -0,0 +1,604 @@ +/* + * Atheros CARL9170 driver + * + * MAC programming + * + * Copyright 2008, Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include "carl9170.h" +#include "cmd.h" + +int carl9170_set_dyn_sifs_ack(struct ar9170 *ar) +{ + u32 val; + + if (conf_is_ht40(&ar->hw->conf)) + val = 0x010a; + else { + if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) + val = 0x105; + else + val = 0x104; + } + + return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val); +} + +int carl9170_set_rts_cts_rate(struct ar9170 *ar) +{ + u32 rts_rate, cts_rate; + + if (conf_is_ht(&ar->hw->conf)) { + /* 12 mbit OFDM */ + rts_rate = 0x1da; + cts_rate = 0x10a; + } else { + if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + /* 11 mbit CCK */ + rts_rate = 033; + cts_rate = 003; + } else { + /* 6 mbit OFDM */ + rts_rate = 0x1bb; + cts_rate = 0x10b; + } + } + + return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE, + rts_rate | (cts_rate) << 16); +} + +int carl9170_set_slot_time(struct ar9170 *ar) +{ + struct ieee80211_vif *vif; + u32 slottime = 20; + + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + if (!vif) { + rcu_read_unlock(); + return 0; + } + + if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) || + vif->bss_conf.use_short_slot) + slottime = 9; + + rcu_read_unlock(); + + return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, + slottime << 10); +} + +int carl9170_set_mac_rates(struct ar9170 *ar) +{ + struct ieee80211_vif *vif; + u32 basic, mandatory; + + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + + if (!vif) { + rcu_read_unlock(); + return 0; + } + + basic = (vif->bss_conf.basic_rates & 0xf); + basic |= (vif->bss_conf.basic_rates & 0xff0) << 4; + rcu_read_unlock(); + + if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) + mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */ + else + mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */ + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic); + carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory); + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +int carl9170_set_qos(struct ar9170 *ar) +{ + carl9170_regwrite_begin(ar); + + carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min | + (ar->edcf[0].cw_max << 16)); + carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min | + (ar->edcf[1].cw_max << 16)); + carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min | + (ar->edcf[2].cw_max << 16)); + carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min | + (ar->edcf[3].cw_max << 16)); + carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min | + (ar->edcf[4].cw_max << 16)); + + carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS, + ((ar->edcf[0].aifs * 9 + 10)) | + ((ar->edcf[1].aifs * 9 + 10) << 12) | + ((ar->edcf[2].aifs * 9 + 10) << 24)); + carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS, + ((ar->edcf[2].aifs * 9 + 10) >> 8) | + ((ar->edcf[3].aifs * 9 + 10) << 4) | + ((ar->edcf[4].aifs * 9 + 10) << 16)); + + carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP, + ar->edcf[0].txop | ar->edcf[1].txop << 16); + carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP, + ar->edcf[2].txop | ar->edcf[3].txop << 16 | + ar->edcf[4].txop << 24); + + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +int carl9170_init_mac(struct ar9170 *ar) +{ + carl9170_regwrite_begin(ar); + + /* switch MAC to OTUS interface */ + carl9170_regwrite(0x1c3600, 0x3); + + carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40); + + carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0); + + carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, + AR9170_MAC_FTF_MONITOR); + + /* enable MMIC */ + carl9170_regwrite(AR9170_MAC_REG_SNIFFER, + AR9170_MAC_SNIFFER_DEFAULTS); + + carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80); + + carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70); + carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000); + carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10); + + /* CF-END & CF-ACK rate => 24M OFDM */ + carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000); + + /* NAV protects ACK only (in TXOP) */ + carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201); + + /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */ + /* OTUS set AM to 0x1 */ + carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170); + + carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105); + + /* Aggregation MAX number and timeout */ + carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa); + carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00); + + carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER, + AR9170_MAC_FTF_DEFAULTS); + + carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, + AR9170_MAC_RX_CTRL_DEAGG | + AR9170_MAC_RX_CTRL_SHORT_FILTER); + + /* rate sets */ + carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f); + carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f); + carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033); + + /* MIMO response control */ + carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e); + + carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff); + + /* set PHY register read timeout (??) */ + carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008); + + /* Disable Rx TimeOut, workaround for BB. */ + carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0); + + /* Set WLAN DMA interrupt mode: generate int per packet */ + carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011); + + carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT, + AR9170_MAC_FCS_FIFO_PROT); + + /* Disables the CF_END frame, undocumented register */ + carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND, + 0x141e0f48); + + /* reset group hash table */ + carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff); + carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff); + + /* disable PRETBTT interrupt */ + carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0); + carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0); + + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +static int carl9170_set_mac_reg(struct ar9170 *ar, + const u32 reg, const u8 *mac) +{ + static const u8 zero[ETH_ALEN] = { 0 }; + + if (!mac) + mac = zero; + + carl9170_regwrite_begin(ar); + + carl9170_regwrite(reg, get_unaligned_le32(mac)); + carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4)); + + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id, + const u8 *mac) +{ + if (WARN_ON(id >= ar->fw.vif_num)) + return -EINVAL; + + return carl9170_set_mac_reg(ar, + AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac); +} + +int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash) +{ + int err; + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32); + carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash); + carl9170_regwrite_finish(); + err = carl9170_regwrite_result(); + if (err) + return err; + + ar->cur_mc_hash = mc_hash; + return 0; +} + +int carl9170_set_operating_mode(struct ar9170 *ar) +{ + struct ieee80211_vif *vif; + struct ath_common *common = &ar->common; + u8 *mac_addr, *bssid; + u32 cam_mode = AR9170_MAC_CAM_DEFAULTS; + u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS; + u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG | + AR9170_MAC_RX_CTRL_SHORT_FILTER; + u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS; + int err = 0; + + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + + if (vif) { + mac_addr = common->macaddr; + bssid = common->curbssid; + + switch (vif->type) { + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_ADHOC: + cam_mode |= AR9170_MAC_CAM_IBSS; + break; + case NL80211_IFTYPE_AP: + cam_mode |= AR9170_MAC_CAM_AP; + + /* iwlagn 802.11n STA Workaround */ + rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; + break; + case NL80211_IFTYPE_WDS: + cam_mode |= AR9170_MAC_CAM_AP_WDS; + rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; + break; + case NL80211_IFTYPE_STATION: + cam_mode |= AR9170_MAC_CAM_STA; + rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST; + break; + default: + WARN(1, "Unsupported operation mode %x\n", vif->type); + err = -EOPNOTSUPP; + break; + } + } else { + mac_addr = NULL; + bssid = NULL; + } + rcu_read_unlock(); + + if (err) + return err; + + if (ar->rx_software_decryption) + enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; + + if (ar->sniffer_enabled) { + rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER; + sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC; + enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE; + } + + err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr); + if (err) + return err; + + err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid); + if (err) + return err; + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer); + carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode); + carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode); + carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl); + carl9170_regwrite_finish(); + + return carl9170_regwrite_result(); +} + +int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry) +{ + u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111); + + return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp); +} + +int carl9170_set_beacon_timers(struct ar9170 *ar) +{ + struct ieee80211_vif *vif; + u32 v = 0; + u32 pretbtt = 0; + + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + + if (vif) { + struct carl9170_vif_info *mvif; + mvif = (void *) vif->drv_priv; + + if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) { + ar->global_beacon_int = vif->bss_conf.beacon_int / + ar->beacon_enabled; + + SET_VAL(AR9170_MAC_BCN_DTIM, v, + vif->bss_conf.dtim_period); + + switch (vif->type) { + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_ADHOC: + v |= AR9170_MAC_BCN_IBSS_MODE; + break; + case NL80211_IFTYPE_AP: + v |= AR9170_MAC_BCN_AP_MODE; + break; + default: + WARN_ON_ONCE(1); + break; + } + } else if (vif->type == NL80211_IFTYPE_STATION) { + ar->global_beacon_int = vif->bss_conf.beacon_int; + + SET_VAL(AR9170_MAC_BCN_DTIM, v, + ar->hw->conf.ps_dtim_period); + + v |= AR9170_MAC_BCN_STA_PS | + AR9170_MAC_BCN_PWR_MGT; + } + + if (ar->global_beacon_int) { + if (ar->global_beacon_int < 15) { + rcu_read_unlock(); + return -ERANGE; + } + + ar->global_pretbtt = ar->global_beacon_int - + CARL9170_PRETBTT_KUS; + } else { + ar->global_pretbtt = 0; + } + } else { + ar->global_beacon_int = 0; + ar->global_pretbtt = 0; + } + + rcu_read_unlock(); + + SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int); + SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt); + SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt); + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt); + carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v); + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +int carl9170_update_beacon(struct ar9170 *ar, const bool submit) +{ + struct sk_buff *skb; + struct carl9170_vif_info *cvif; + __le32 *data, *old = NULL; + u32 word, off, addr, len; + int i = 0, err = 0; + + rcu_read_lock(); + cvif = rcu_dereference(ar->beacon_iter); +retry: + if (ar->vifs == 0 || !cvif) + goto out_unlock; + + list_for_each_entry_continue_rcu(cvif, &ar->vif_list, list) { + if (cvif->active && cvif->enable_beacon) + goto found; + } + + if (!ar->beacon_enabled || i++) + goto out_unlock; + + goto retry; + +found: + rcu_assign_pointer(ar->beacon_iter, cvif); + + skb = ieee80211_beacon_get_tim(ar->hw, carl9170_get_vif(cvif), + NULL, NULL); + + if (!skb) { + err = -ENOMEM; + goto out_unlock; + } + + spin_lock_bh(&ar->beacon_lock); + data = (__le32 *)skb->data; + if (cvif->beacon) + old = (__le32 *)cvif->beacon->data; + + off = cvif->id * AR9170_MAC_BCN_LENGTH_MAX; + addr = ar->fw.beacon_addr + off; + len = roundup(skb->len + FCS_LEN, 4); + + if ((off + len) > ar->fw.beacon_max_len) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "beacon does not " + "fit into device memory!\n"); + } + + spin_unlock_bh(&ar->beacon_lock); + dev_kfree_skb_any(skb); + err = -EINVAL; + goto out_unlock; + } + + if (len > AR9170_MAC_BCN_LENGTH_MAX) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "no support for beacons " + "bigger than %d (yours:%d).\n", + AR9170_MAC_BCN_LENGTH_MAX, len); + } + + spin_unlock_bh(&ar->beacon_lock); + dev_kfree_skb_any(skb); + err = -EMSGSIZE; + goto out_unlock; + } + + carl9170_async_regwrite_begin(ar); + + /* XXX: use skb->cb info */ + if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, + ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400); + } else { + carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, + ((skb->len + FCS_LEN) << 16) + 0x001b); + } + + for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) { + /* + * XXX: This accesses beyond skb data for up + * to the last 3 bytes!! + */ + + if (old && (data[i] == old[i])) + continue; + + word = le32_to_cpu(data[i]); + carl9170_async_regwrite(addr + 4 * i, word); + } + carl9170_async_regwrite_finish(); + + dev_kfree_skb_any(cvif->beacon); + cvif->beacon = NULL; + + err = carl9170_async_regwrite_result(); + if (!err) + cvif->beacon = skb; + spin_unlock_bh(&ar->beacon_lock); + if (err) + goto out_unlock; + + if (submit) { + err = carl9170_bcn_ctrl(ar, cvif->id, + CARL9170_BCN_CTRL_CAB_TRIGGER, + addr, skb->len + FCS_LEN); + + if (err) + goto out_unlock; + } +out_unlock: + rcu_read_unlock(); + return err; +} + +int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, + const u8 ktype, const u8 keyidx, const u8 *keydata, + const int keylen) +{ + struct carl9170_set_key_cmd key = { }; + static const u8 bcast[ETH_ALEN] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + mac = mac ? : bcast; + + key.user = cpu_to_le16(id); + key.keyId = cpu_to_le16(keyidx); + key.type = cpu_to_le16(ktype); + memcpy(&key.macAddr, mac, ETH_ALEN); + if (keydata) + memcpy(&key.key, keydata, keylen); + + return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY, + sizeof(key), (u8 *)&key, 0, NULL); +} + +int carl9170_disable_key(struct ar9170 *ar, const u8 id) +{ + struct carl9170_disable_key_cmd key = { }; + + key.user = cpu_to_le16(id); + + return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, + sizeof(key), (u8 *)&key, 0, NULL); +} diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c new file mode 100644 index 0000000000000000000000000000000000000000..3cc99f3f7ab5728af8eeb40c759f954a319671b7 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -0,0 +1,1891 @@ +/* + * Atheros CARL9170 driver + * + * mac80211 interaction code + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "hw.h" +#include "carl9170.h" +#include "cmd.h" + +static int modparam_nohwcrypt; +module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); +MODULE_PARM_DESC(nohwcrypt, "Disable hardware crypto offload."); + +int modparam_noht; +module_param_named(noht, modparam_noht, int, S_IRUGO); +MODULE_PARM_DESC(noht, "Disable MPDU aggregation."); + +#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ + .bitrate = (_bitrate), \ + .flags = (_flags), \ + .hw_value = (_hw_rate) | (_txpidx) << 4, \ +} + +struct ieee80211_rate __carl9170_ratetable[] = { + RATE(10, 0, 0, 0), + RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE), + RATE(60, 0xb, 0, 0), + RATE(90, 0xf, 0, 0), + RATE(120, 0xa, 0, 0), + RATE(180, 0xe, 0, 0), + RATE(240, 0x9, 0, 0), + RATE(360, 0xd, 1, 0), + RATE(480, 0x8, 2, 0), + RATE(540, 0xc, 3, 0), +}; +#undef RATE + +#define carl9170_g_ratetable (__carl9170_ratetable + 0) +#define carl9170_g_ratetable_size 12 +#define carl9170_a_ratetable (__carl9170_ratetable + 4) +#define carl9170_a_ratetable_size 8 + +/* + * NB: The hw_value is used as an index into the carl9170_phy_freq_params + * array in phy.c so that we don't have to do frequency lookups! + */ +#define CHAN(_freq, _idx) { \ + .center_freq = (_freq), \ + .hw_value = (_idx), \ + .max_power = 18, /* XXX */ \ +} + +static struct ieee80211_channel carl9170_2ghz_chantable[] = { + CHAN(2412, 0), + CHAN(2417, 1), + CHAN(2422, 2), + CHAN(2427, 3), + CHAN(2432, 4), + CHAN(2437, 5), + CHAN(2442, 6), + CHAN(2447, 7), + CHAN(2452, 8), + CHAN(2457, 9), + CHAN(2462, 10), + CHAN(2467, 11), + CHAN(2472, 12), + CHAN(2484, 13), +}; + +static struct ieee80211_channel carl9170_5ghz_chantable[] = { + CHAN(4920, 14), + CHAN(4940, 15), + CHAN(4960, 16), + CHAN(4980, 17), + CHAN(5040, 18), + CHAN(5060, 19), + CHAN(5080, 20), + CHAN(5180, 21), + CHAN(5200, 22), + CHAN(5220, 23), + CHAN(5240, 24), + CHAN(5260, 25), + CHAN(5280, 26), + CHAN(5300, 27), + CHAN(5320, 28), + CHAN(5500, 29), + CHAN(5520, 30), + CHAN(5540, 31), + CHAN(5560, 32), + CHAN(5580, 33), + CHAN(5600, 34), + CHAN(5620, 35), + CHAN(5640, 36), + CHAN(5660, 37), + CHAN(5680, 38), + CHAN(5700, 39), + CHAN(5745, 40), + CHAN(5765, 41), + CHAN(5785, 42), + CHAN(5805, 43), + CHAN(5825, 44), + CHAN(5170, 45), + CHAN(5190, 46), + CHAN(5210, 47), + CHAN(5230, 48), +}; +#undef CHAN + +#define CARL9170_HT_CAP \ +{ \ + .ht_supported = true, \ + .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ + IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ + IEEE80211_HT_CAP_SGI_40 | \ + IEEE80211_HT_CAP_DSSSCCK40 | \ + IEEE80211_HT_CAP_SM_PS, \ + .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, \ + .ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \ + .mcs = { \ + .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \ + .rx_highest = cpu_to_le16(300), \ + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \ + }, \ +} + +static struct ieee80211_supported_band carl9170_band_2GHz = { + .channels = carl9170_2ghz_chantable, + .n_channels = ARRAY_SIZE(carl9170_2ghz_chantable), + .bitrates = carl9170_g_ratetable, + .n_bitrates = carl9170_g_ratetable_size, + .ht_cap = CARL9170_HT_CAP, +}; + +static struct ieee80211_supported_band carl9170_band_5GHz = { + .channels = carl9170_5ghz_chantable, + .n_channels = ARRAY_SIZE(carl9170_5ghz_chantable), + .bitrates = carl9170_a_ratetable, + .n_bitrates = carl9170_a_ratetable_size, + .ht_cap = CARL9170_HT_CAP, +}; + +static void carl9170_ampdu_gc(struct ar9170 *ar) +{ + struct carl9170_sta_tid *tid_info; + LIST_HEAD(tid_gc); + + rcu_read_lock(); + list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) { + spin_lock_bh(&ar->tx_ampdu_list_lock); + if (tid_info->state == CARL9170_TID_STATE_SHUTDOWN) { + tid_info->state = CARL9170_TID_STATE_KILLED; + list_del_rcu(&tid_info->list); + ar->tx_ampdu_list_len--; + list_add_tail(&tid_info->tmp_list, &tid_gc); + } + spin_unlock_bh(&ar->tx_ampdu_list_lock); + + } + rcu_assign_pointer(ar->tx_ampdu_iter, tid_info); + rcu_read_unlock(); + + synchronize_rcu(); + + while (!list_empty(&tid_gc)) { + struct sk_buff *skb; + tid_info = list_first_entry(&tid_gc, struct carl9170_sta_tid, + tmp_list); + + while ((skb = __skb_dequeue(&tid_info->queue))) + carl9170_tx_status(ar, skb, false); + + list_del_init(&tid_info->tmp_list); + kfree(tid_info); + } +} + +static void carl9170_flush(struct ar9170 *ar, bool drop_queued) +{ + if (drop_queued) { + int i; + + /* + * We can only drop frames which have not been uploaded + * to the device yet. + */ + + for (i = 0; i < ar->hw->queues; i++) { + struct sk_buff *skb; + + while ((skb = skb_dequeue(&ar->tx_pending[i]))) { + struct ieee80211_tx_info *info; + + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_AMPDU) + atomic_dec(&ar->tx_ampdu_upload); + + carl9170_tx_status(ar, skb, false); + } + } + } + + /* Wait for all other outstanding frames to timeout. */ + if (atomic_read(&ar->tx_total_queued)) + WARN_ON(wait_for_completion_timeout(&ar->tx_flush, HZ) == 0); +} + +static void carl9170_flush_ba(struct ar9170 *ar) +{ + struct sk_buff_head free; + struct carl9170_sta_tid *tid_info; + struct sk_buff *skb; + + __skb_queue_head_init(&free); + + rcu_read_lock(); + spin_lock_bh(&ar->tx_ampdu_list_lock); + list_for_each_entry_rcu(tid_info, &ar->tx_ampdu_list, list) { + if (tid_info->state > CARL9170_TID_STATE_SUSPEND) { + tid_info->state = CARL9170_TID_STATE_SUSPEND; + + spin_lock(&tid_info->lock); + while ((skb = __skb_dequeue(&tid_info->queue))) + __skb_queue_tail(&free, skb); + spin_unlock(&tid_info->lock); + } + } + spin_unlock_bh(&ar->tx_ampdu_list_lock); + rcu_read_unlock(); + + while ((skb = __skb_dequeue(&free))) + carl9170_tx_status(ar, skb, false); +} + +static void carl9170_zap_queues(struct ar9170 *ar) +{ + struct carl9170_vif_info *cvif; + unsigned int i; + + carl9170_ampdu_gc(ar); + + carl9170_flush_ba(ar); + carl9170_flush(ar, true); + + for (i = 0; i < ar->hw->queues; i++) { + spin_lock_bh(&ar->tx_status[i].lock); + while (!skb_queue_empty(&ar->tx_status[i])) { + struct sk_buff *skb; + + skb = skb_peek(&ar->tx_status[i]); + carl9170_tx_get_skb(skb); + spin_unlock_bh(&ar->tx_status[i].lock); + carl9170_tx_drop(ar, skb); + spin_lock_bh(&ar->tx_status[i].lock); + carl9170_tx_put_skb(skb); + } + spin_unlock_bh(&ar->tx_status[i].lock); + } + + BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_SOFT < 1); + BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD < CARL9170_NUM_TX_LIMIT_SOFT); + BUILD_BUG_ON(CARL9170_NUM_TX_LIMIT_HARD >= CARL9170_BAW_BITS); + + /* reinitialize queues statistics */ + memset(&ar->tx_stats, 0, sizeof(ar->tx_stats)); + for (i = 0; i < ar->hw->queues; i++) + ar->tx_stats[i].limit = CARL9170_NUM_TX_LIMIT_HARD; + + for (i = 0; i < DIV_ROUND_UP(ar->fw.mem_blocks, BITS_PER_LONG); i++) + ar->mem_bitmap[i] = 0; + + rcu_read_lock(); + list_for_each_entry_rcu(cvif, &ar->vif_list, list) { + spin_lock_bh(&ar->beacon_lock); + dev_kfree_skb_any(cvif->beacon); + cvif->beacon = NULL; + spin_unlock_bh(&ar->beacon_lock); + } + rcu_read_unlock(); + + atomic_set(&ar->tx_ampdu_upload, 0); + atomic_set(&ar->tx_ampdu_scheduler, 0); + atomic_set(&ar->tx_total_pending, 0); + atomic_set(&ar->tx_total_queued, 0); + atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks); +} + +#define CARL9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop) \ +do { \ + queue.aifs = ai_fs; \ + queue.cw_min = cwmin; \ + queue.cw_max = cwmax; \ + queue.txop = _txop; \ +} while (0) + +static int carl9170_op_start(struct ieee80211_hw *hw) +{ + struct ar9170 *ar = hw->priv; + int err, i; + + mutex_lock(&ar->mutex); + + carl9170_zap_queues(ar); + + /* reset QoS defaults */ + CARL9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023, 0); /* BEST EFFORT */ + CARL9170_FILL_QUEUE(ar->edcf[1], 2, 7, 15, 94); /* VIDEO */ + CARL9170_FILL_QUEUE(ar->edcf[2], 2, 3, 7, 47); /* VOICE */ + CARL9170_FILL_QUEUE(ar->edcf[3], 7, 15, 1023, 0); /* BACKGROUND */ + CARL9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ + + ar->current_factor = ar->current_density = -1; + /* "The first key is unique." */ + ar->usedkeys = 1; + ar->filter_state = 0; + ar->ps.last_action = jiffies; + ar->ps.last_slept = jiffies; + ar->erp_mode = CARL9170_ERP_AUTO; + ar->rx_software_decryption = false; + ar->disable_offload = false; + + for (i = 0; i < ar->hw->queues; i++) { + ar->queue_stop_timeout[i] = jiffies; + ar->max_queue_stop_timeout[i] = 0; + } + + atomic_set(&ar->mem_allocs, 0); + + err = carl9170_usb_open(ar); + if (err) + goto out; + + err = carl9170_init_mac(ar); + if (err) + goto out; + + err = carl9170_set_qos(ar); + if (err) + goto out; + + if (ar->fw.rx_filter) { + err = carl9170_rx_filter(ar, CARL9170_RX_FILTER_OTHER_RA | + CARL9170_RX_FILTER_CTL_OTHER | CARL9170_RX_FILTER_BAD); + if (err) + goto out; + } + + err = carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, + AR9170_DMA_TRIGGER_RXQ); + if (err) + goto out; + + /* Clear key-cache */ + for (i = 0; i < AR9170_CAM_MAX_USER + 4; i++) { + err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE, + 0, NULL, 0); + if (err) + goto out; + + err = carl9170_upload_key(ar, i, NULL, AR9170_ENC_ALG_NONE, + 1, NULL, 0); + if (err) + goto out; + + if (i < AR9170_CAM_MAX_USER) { + err = carl9170_disable_key(ar, i); + if (err) + goto out; + } + } + + carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STARTED); + + ieee80211_wake_queues(ar->hw); + err = 0; + +out: + mutex_unlock(&ar->mutex); + return err; +} + +static void carl9170_cancel_worker(struct ar9170 *ar) +{ + cancel_delayed_work_sync(&ar->tx_janitor); +#ifdef CONFIG_CARL9170_LEDS + cancel_delayed_work_sync(&ar->led_work); +#endif /* CONFIG_CARL9170_LEDS */ + cancel_work_sync(&ar->ps_work); + cancel_work_sync(&ar->ampdu_work); +} + +static void carl9170_op_stop(struct ieee80211_hw *hw) +{ + struct ar9170 *ar = hw->priv; + + carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE); + + ieee80211_stop_queues(ar->hw); + + mutex_lock(&ar->mutex); + if (IS_ACCEPTING_CMD(ar)) { + rcu_assign_pointer(ar->beacon_iter, NULL); + + carl9170_led_set_state(ar, 0); + + /* stop DMA */ + carl9170_write_reg(ar, AR9170_MAC_REG_DMA_TRIGGER, 0); + carl9170_usb_stop(ar); + } + + carl9170_zap_queues(ar); + mutex_unlock(&ar->mutex); + + carl9170_cancel_worker(ar); +} + +static void carl9170_restart_work(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, + restart_work); + int err; + + ar->usedkeys = 0; + ar->filter_state = 0; + carl9170_cancel_worker(ar); + + mutex_lock(&ar->mutex); + err = carl9170_usb_restart(ar); + if (net_ratelimit()) { + if (err) { + dev_err(&ar->udev->dev, "Failed to restart device " + " (%d).\n", err); + } else { + dev_info(&ar->udev->dev, "device restarted " + "successfully.\n"); + } + } + + carl9170_zap_queues(ar); + mutex_unlock(&ar->mutex); + if (!err) { + ar->restart_counter++; + atomic_set(&ar->pending_restarts, 0); + + ieee80211_restart_hw(ar->hw); + } else { + /* + * The reset was unsuccessful and the device seems to + * be dead. But there's still one option: a low-level + * usb subsystem reset... + */ + + carl9170_usb_reset(ar); + } +} + +void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r) +{ + carl9170_set_state_when(ar, CARL9170_STARTED, CARL9170_IDLE); + + /* + * Sometimes, an error can trigger several different reset events. + * By ignoring these *surplus* reset events, the device won't be + * killed again, right after it has recovered. + */ + if (atomic_inc_return(&ar->pending_restarts) > 1) { + dev_dbg(&ar->udev->dev, "ignoring restart (%d)\n", r); + return; + } + + ieee80211_stop_queues(ar->hw); + + dev_err(&ar->udev->dev, "restart device (%d)\n", r); + + if (!WARN_ON(r == CARL9170_RR_NO_REASON) || + !WARN_ON(r >= __CARL9170_RR_LAST)) + ar->last_reason = r; + + if (!ar->registered) + return; + + if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset) + ieee80211_queue_work(ar->hw, &ar->restart_work); + else + carl9170_usb_reset(ar); + + /* + * At this point, the device instance might have vanished/disabled. + * So, don't put any code which access the ar9170 struct + * without proper protection. + */ +} + +static int carl9170_init_interface(struct ar9170 *ar, + struct ieee80211_vif *vif) +{ + struct ath_common *common = &ar->common; + int err; + + if (!vif) { + WARN_ON_ONCE(IS_STARTED(ar)); + return 0; + } + + memcpy(common->macaddr, vif->addr, ETH_ALEN); + + if (modparam_nohwcrypt || + ((vif->type != NL80211_IFTYPE_STATION) && + (vif->type != NL80211_IFTYPE_AP))) { + ar->rx_software_decryption = true; + ar->disable_offload = true; + } + + err = carl9170_set_operating_mode(ar); + return err; +} + +static int carl9170_op_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; + struct ieee80211_vif *main_vif; + struct ar9170 *ar = hw->priv; + int vif_id = -1, err = 0; + + mutex_lock(&ar->mutex); + rcu_read_lock(); + if (vif_priv->active) { + /* + * Skip the interface structure initialization, + * if the vif survived the _restart call. + */ + vif_id = vif_priv->id; + vif_priv->enable_beacon = false; + + spin_lock_bh(&ar->beacon_lock); + dev_kfree_skb_any(vif_priv->beacon); + vif_priv->beacon = NULL; + spin_unlock_bh(&ar->beacon_lock); + + goto init; + } + + main_vif = carl9170_get_main_vif(ar); + + if (main_vif) { + switch (main_vif->type) { + case NL80211_IFTYPE_STATION: + if (vif->type == NL80211_IFTYPE_STATION) + break; + + err = -EBUSY; + rcu_read_unlock(); + + goto unlock; + + case NL80211_IFTYPE_AP: + if ((vif->type == NL80211_IFTYPE_STATION) || + (vif->type == NL80211_IFTYPE_WDS) || + (vif->type == NL80211_IFTYPE_AP)) + break; + + err = -EBUSY; + rcu_read_unlock(); + goto unlock; + + default: + rcu_read_unlock(); + goto unlock; + } + } + + vif_id = bitmap_find_free_region(&ar->vif_bitmap, ar->fw.vif_num, 0); + + if (vif_id < 0) { + rcu_read_unlock(); + + err = -ENOSPC; + goto unlock; + } + + BUG_ON(ar->vif_priv[vif_id].id != vif_id); + + vif_priv->active = true; + vif_priv->id = vif_id; + vif_priv->enable_beacon = false; + ar->vifs++; + list_add_tail_rcu(&vif_priv->list, &ar->vif_list); + rcu_assign_pointer(ar->vif_priv[vif_id].vif, vif); + +init: + if (carl9170_get_main_vif(ar) == vif) { + rcu_assign_pointer(ar->beacon_iter, vif_priv); + rcu_read_unlock(); + + err = carl9170_init_interface(ar, vif); + if (err) + goto unlock; + } else { + err = carl9170_mod_virtual_mac(ar, vif_id, vif->addr); + rcu_read_unlock(); + + if (err) + goto unlock; + } + +unlock: + if (err && (vif_id != -1)) { + vif_priv->active = false; + bitmap_release_region(&ar->vif_bitmap, vif_id, 0); + ar->vifs--; + rcu_assign_pointer(ar->vif_priv[vif_id].vif, NULL); + list_del_rcu(&vif_priv->list); + mutex_unlock(&ar->mutex); + synchronize_rcu(); + } else { + if (ar->vifs > 1) + ar->ps.off_override |= PS_OFF_VIF; + + mutex_unlock(&ar->mutex); + } + + return err; +} + +static void carl9170_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct carl9170_vif_info *vif_priv = (void *) vif->drv_priv; + struct ieee80211_vif *main_vif; + struct ar9170 *ar = hw->priv; + unsigned int id; + + mutex_lock(&ar->mutex); + + if (WARN_ON_ONCE(!vif_priv->active)) + goto unlock; + + ar->vifs--; + + rcu_read_lock(); + main_vif = carl9170_get_main_vif(ar); + + id = vif_priv->id; + + vif_priv->active = false; + WARN_ON(vif_priv->enable_beacon); + vif_priv->enable_beacon = false; + list_del_rcu(&vif_priv->list); + rcu_assign_pointer(ar->vif_priv[id].vif, NULL); + + if (vif == main_vif) { + rcu_read_unlock(); + + if (ar->vifs) { + WARN_ON(carl9170_init_interface(ar, + carl9170_get_main_vif(ar))); + } else { + carl9170_set_operating_mode(ar); + } + } else { + rcu_read_unlock(); + + WARN_ON(carl9170_mod_virtual_mac(ar, id, NULL)); + } + + carl9170_update_beacon(ar, false); + carl9170_flush_cab(ar, id); + + spin_lock_bh(&ar->beacon_lock); + dev_kfree_skb_any(vif_priv->beacon); + vif_priv->beacon = NULL; + spin_unlock_bh(&ar->beacon_lock); + + bitmap_release_region(&ar->vif_bitmap, id, 0); + + carl9170_set_beacon_timers(ar); + + if (ar->vifs == 1) + ar->ps.off_override &= ~PS_OFF_VIF; + +unlock: + mutex_unlock(&ar->mutex); + + synchronize_rcu(); +} + +void carl9170_ps_check(struct ar9170 *ar) +{ + ieee80211_queue_work(ar->hw, &ar->ps_work); +} + +/* caller must hold ar->mutex */ +static int carl9170_ps_update(struct ar9170 *ar) +{ + bool ps = false; + int err = 0; + + if (!ar->ps.off_override) + ps = (ar->hw->conf.flags & IEEE80211_CONF_PS); + + if (ps != ar->ps.state) { + err = carl9170_powersave(ar, ps); + if (err) + return err; + + if (ar->ps.state && !ps) { + ar->ps.sleep_ms = jiffies_to_msecs(jiffies - + ar->ps.last_action); + } + + if (ps) + ar->ps.last_slept = jiffies; + + ar->ps.last_action = jiffies; + ar->ps.state = ps; + } + + return 0; +} + +static void carl9170_ps_work(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, + ps_work); + mutex_lock(&ar->mutex); + if (IS_STARTED(ar)) + WARN_ON_ONCE(carl9170_ps_update(ar) != 0); + mutex_unlock(&ar->mutex); +} + + +static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) +{ + struct ar9170 *ar = hw->priv; + int err = 0; + + mutex_lock(&ar->mutex); + if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { + /* TODO */ + err = 0; + } + + if (changed & IEEE80211_CONF_CHANGE_PS) { + err = carl9170_ps_update(ar); + if (err) + goto out; + } + + if (changed & IEEE80211_CONF_CHANGE_POWER) { + /* TODO */ + err = 0; + } + + if (changed & IEEE80211_CONF_CHANGE_SMPS) { + /* TODO */ + err = 0; + } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + /* adjust slot time for 5 GHz */ + err = carl9170_set_slot_time(ar); + if (err) + goto out; + + err = carl9170_set_channel(ar, hw->conf.channel, + hw->conf.channel_type, CARL9170_RFI_NONE); + if (err) + goto out; + + err = carl9170_set_dyn_sifs_ack(ar); + if (err) + goto out; + + err = carl9170_set_rts_cts_rate(ar); + if (err) + goto out; + } + +out: + mutex_unlock(&ar->mutex); + return err; +} + +static u64 carl9170_op_prepare_multicast(struct ieee80211_hw *hw, + struct netdev_hw_addr_list *mc_list) +{ + struct netdev_hw_addr *ha; + u64 mchash; + + /* always get broadcast frames */ + mchash = 1ULL << (0xff >> 2); + + netdev_hw_addr_list_for_each(ha, mc_list) + mchash |= 1ULL << (ha->addr[5] >> 2); + + return mchash; +} + +static void carl9170_op_configure_filter(struct ieee80211_hw *hw, + unsigned int changed_flags, + unsigned int *new_flags, + u64 multicast) +{ + struct ar9170 *ar = hw->priv; + + /* mask supported flags */ + *new_flags &= FIF_ALLMULTI | ar->rx_filter_caps; + + if (!IS_ACCEPTING_CMD(ar)) + return; + + mutex_lock(&ar->mutex); + + ar->filter_state = *new_flags; + /* + * We can support more by setting the sniffer bit and + * then checking the error flags, later. + */ + + if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI) + multicast = ~0ULL; + + if (multicast != ar->cur_mc_hash) + WARN_ON(carl9170_update_multicast(ar, multicast)); + + if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) { + ar->sniffer_enabled = !!(*new_flags & + (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)); + + WARN_ON(carl9170_set_operating_mode(ar)); + } + + if (ar->fw.rx_filter && changed_flags & ar->rx_filter_caps) { + u32 rx_filter = 0; + + if (!(*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))) + rx_filter |= CARL9170_RX_FILTER_BAD; + + if (!(*new_flags & FIF_CONTROL)) + rx_filter |= CARL9170_RX_FILTER_CTL_OTHER; + + if (!(*new_flags & FIF_PSPOLL)) + rx_filter |= CARL9170_RX_FILTER_CTL_PSPOLL; + + if (!(*new_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))) { + rx_filter |= CARL9170_RX_FILTER_OTHER_RA; + rx_filter |= CARL9170_RX_FILTER_DECRY_FAIL; + } + + WARN_ON(carl9170_rx_filter(ar, rx_filter)); + } + + mutex_unlock(&ar->mutex); +} + + +static void carl9170_op_bss_info_changed(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changed) +{ + struct ar9170 *ar = hw->priv; + struct ath_common *common = &ar->common; + int err = 0; + struct carl9170_vif_info *vif_priv; + struct ieee80211_vif *main_vif; + + mutex_lock(&ar->mutex); + vif_priv = (void *) vif->drv_priv; + main_vif = carl9170_get_main_vif(ar); + if (WARN_ON(!main_vif)) + goto out; + + if (changed & BSS_CHANGED_BEACON_ENABLED) { + struct carl9170_vif_info *iter; + int i = 0; + + vif_priv->enable_beacon = bss_conf->enable_beacon; + rcu_read_lock(); + list_for_each_entry_rcu(iter, &ar->vif_list, list) { + if (iter->active && iter->enable_beacon) + i++; + + } + rcu_read_unlock(); + + ar->beacon_enabled = i; + } + + if (changed & BSS_CHANGED_BEACON) { + err = carl9170_update_beacon(ar, false); + if (err) + goto out; + } + + if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON | + BSS_CHANGED_BEACON_INT)) { + + if (main_vif != vif) { + bss_conf->beacon_int = main_vif->bss_conf.beacon_int; + bss_conf->dtim_period = main_vif->bss_conf.dtim_period; + } + + /* + * Therefore a hard limit for the broadcast traffic should + * prevent false alarms. + */ + if (vif->type != NL80211_IFTYPE_STATION && + (bss_conf->beacon_int * bss_conf->dtim_period >= + (CARL9170_QUEUE_STUCK_TIMEOUT / 2))) { + err = -EINVAL; + goto out; + } + + err = carl9170_set_beacon_timers(ar); + if (err) + goto out; + } + + if (changed & BSS_CHANGED_HT) { + /* TODO */ + err = 0; + if (err) + goto out; + } + + if (main_vif != vif) + goto out; + + /* + * The following settings can only be changed by the + * master interface. + */ + + if (changed & BSS_CHANGED_BSSID) { + memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); + err = carl9170_set_operating_mode(ar); + if (err) + goto out; + } + + if (changed & BSS_CHANGED_ASSOC) { + ar->common.curaid = bss_conf->aid; + err = carl9170_set_beacon_timers(ar); + if (err) + goto out; + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + err = carl9170_set_slot_time(ar); + if (err) + goto out; + } + + if (changed & BSS_CHANGED_BASIC_RATES) { + err = carl9170_set_mac_rates(ar); + if (err) + goto out; + } + +out: + WARN_ON_ONCE(err && IS_STARTED(ar)); + mutex_unlock(&ar->mutex); +} + +static u64 carl9170_op_get_tsf(struct ieee80211_hw *hw) +{ + struct ar9170 *ar = hw->priv; + struct carl9170_tsf_rsp tsf; + int err; + + mutex_lock(&ar->mutex); + err = carl9170_exec_cmd(ar, CARL9170_CMD_READ_TSF, + 0, NULL, sizeof(tsf), &tsf); + mutex_unlock(&ar->mutex); + if (WARN_ON(err)) + return 0; + + return le64_to_cpu(tsf.tsf_64); +} + +static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct ar9170 *ar = hw->priv; + int err = 0, i; + u8 ktype; + + if (ar->disable_offload || !vif) + return -EOPNOTSUPP; + + /* + * We have to fall back to software encryption, whenever + * the user choose to participates in an IBSS or is connected + * to more than one network. + * + * This is very unfortunate, because some machines cannot handle + * the high througput speed in 802.11n networks. + */ + + if (!is_main_vif(ar, vif)) + goto err_softw; + + /* + * While the hardware supports *catch-all* key, for offloading + * group-key en-/de-cryption. The way of how the hardware + * decides which keyId maps to which key, remains a mystery... + */ + if ((vif->type != NL80211_IFTYPE_STATION && + vif->type != NL80211_IFTYPE_ADHOC) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) + return -EOPNOTSUPP; + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + ktype = AR9170_ENC_ALG_WEP64; + break; + case WLAN_CIPHER_SUITE_WEP104: + ktype = AR9170_ENC_ALG_WEP128; + break; + case WLAN_CIPHER_SUITE_TKIP: + ktype = AR9170_ENC_ALG_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + ktype = AR9170_ENC_ALG_AESCCMP; + break; + default: + return -EOPNOTSUPP; + } + + mutex_lock(&ar->mutex); + if (cmd == SET_KEY) { + if (!IS_STARTED(ar)) { + err = -EOPNOTSUPP; + goto out; + } + + if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + sta = NULL; + + i = 64 + key->keyidx; + } else { + for (i = 0; i < 64; i++) + if (!(ar->usedkeys & BIT(i))) + break; + if (i == 64) + goto err_softw; + } + + key->hw_key_idx = i; + + err = carl9170_upload_key(ar, i, sta ? sta->addr : NULL, + ktype, 0, key->key, + min_t(u8, 16, key->keylen)); + if (err) + goto out; + + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { + err = carl9170_upload_key(ar, i, sta ? sta->addr : + NULL, ktype, 1, + key->key + 16, 16); + if (err) + goto out; + + /* + * hardware is not capable generating MMIC + * of fragmented frames! + */ + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + } + + if (i < 64) + ar->usedkeys |= BIT(i); + + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + } else { + if (!IS_STARTED(ar)) { + /* The device is gone... together with the key ;-) */ + err = 0; + goto out; + } + + if (key->hw_key_idx < 64) { + ar->usedkeys &= ~BIT(key->hw_key_idx); + } else { + err = carl9170_upload_key(ar, key->hw_key_idx, NULL, + AR9170_ENC_ALG_NONE, 0, + NULL, 0); + if (err) + goto out; + + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { + err = carl9170_upload_key(ar, key->hw_key_idx, + NULL, + AR9170_ENC_ALG_NONE, + 1, NULL, 0); + if (err) + goto out; + } + + } + + err = carl9170_disable_key(ar, key->hw_key_idx); + if (err) + goto out; + } + +out: + mutex_unlock(&ar->mutex); + return err; + +err_softw: + if (!ar->rx_software_decryption) { + ar->rx_software_decryption = true; + carl9170_set_operating_mode(ar); + } + mutex_unlock(&ar->mutex); + return -ENOSPC; +} + +static int carl9170_op_sta_add(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; + unsigned int i; + + if (sta->ht_cap.ht_supported) { + if (sta->ht_cap.ampdu_density > 6) { + /* + * HW does support 16us AMPDU density. + * No HT-Xmit for station. + */ + + return 0; + } + + for (i = 0; i < CARL9170_NUM_TID; i++) + rcu_assign_pointer(sta_info->agg[i], NULL); + + sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); + sta_info->ht_sta = true; + } + + return 0; +} + +static int carl9170_op_sta_remove(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct ar9170 *ar = hw->priv; + struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; + unsigned int i; + bool cleanup = false; + + if (sta->ht_cap.ht_supported) { + + sta_info->ht_sta = false; + + rcu_read_lock(); + for (i = 0; i < CARL9170_NUM_TID; i++) { + struct carl9170_sta_tid *tid_info; + + tid_info = rcu_dereference(sta_info->agg[i]); + rcu_assign_pointer(sta_info->agg[i], NULL); + + if (!tid_info) + continue; + + spin_lock_bh(&ar->tx_ampdu_list_lock); + if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN) + tid_info->state = CARL9170_TID_STATE_SHUTDOWN; + spin_unlock_bh(&ar->tx_ampdu_list_lock); + cleanup = true; + } + rcu_read_unlock(); + + if (cleanup) + carl9170_ampdu_gc(ar); + } + + return 0; +} + +static int carl9170_op_conf_tx(struct ieee80211_hw *hw, u16 queue, + const struct ieee80211_tx_queue_params *param) +{ + struct ar9170 *ar = hw->priv; + int ret; + + mutex_lock(&ar->mutex); + if (queue < ar->hw->queues) { + memcpy(&ar->edcf[ar9170_qmap[queue]], param, sizeof(*param)); + ret = carl9170_set_qos(ar); + } else { + ret = -EINVAL; + } + + mutex_unlock(&ar->mutex); + return ret; +} + +static void carl9170_ampdu_work(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, + ampdu_work); + + if (!IS_STARTED(ar)) + return; + + mutex_lock(&ar->mutex); + carl9170_ampdu_gc(ar); + mutex_unlock(&ar->mutex); +} + +static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum ieee80211_ampdu_mlme_action action, + struct ieee80211_sta *sta, + u16 tid, u16 *ssn) +{ + struct ar9170 *ar = hw->priv; + struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; + struct carl9170_sta_tid *tid_info; + + if (modparam_noht) + return -EOPNOTSUPP; + + switch (action) { + case IEEE80211_AMPDU_TX_START: + if (!sta_info->ht_sta) + return -EOPNOTSUPP; + + rcu_read_lock(); + if (rcu_dereference(sta_info->agg[tid])) { + rcu_read_unlock(); + return -EBUSY; + } + + tid_info = kzalloc(sizeof(struct carl9170_sta_tid), + GFP_ATOMIC); + if (!tid_info) { + rcu_read_unlock(); + return -ENOMEM; + } + + tid_info->hsn = tid_info->bsn = tid_info->snx = (*ssn); + tid_info->state = CARL9170_TID_STATE_PROGRESS; + tid_info->tid = tid; + tid_info->max = sta_info->ampdu_max_len; + + INIT_LIST_HEAD(&tid_info->list); + INIT_LIST_HEAD(&tid_info->tmp_list); + skb_queue_head_init(&tid_info->queue); + spin_lock_init(&tid_info->lock); + + spin_lock_bh(&ar->tx_ampdu_list_lock); + ar->tx_ampdu_list_len++; + list_add_tail_rcu(&tid_info->list, &ar->tx_ampdu_list); + rcu_assign_pointer(sta_info->agg[tid], tid_info); + spin_unlock_bh(&ar->tx_ampdu_list_lock); + rcu_read_unlock(); + + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); + break; + + case IEEE80211_AMPDU_TX_STOP: + rcu_read_lock(); + tid_info = rcu_dereference(sta_info->agg[tid]); + if (tid_info) { + spin_lock_bh(&ar->tx_ampdu_list_lock); + if (tid_info->state > CARL9170_TID_STATE_SHUTDOWN) + tid_info->state = CARL9170_TID_STATE_SHUTDOWN; + spin_unlock_bh(&ar->tx_ampdu_list_lock); + } + + rcu_assign_pointer(sta_info->agg[tid], NULL); + rcu_read_unlock(); + + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + ieee80211_queue_work(ar->hw, &ar->ampdu_work); + break; + + case IEEE80211_AMPDU_TX_OPERATIONAL: + rcu_read_lock(); + tid_info = rcu_dereference(sta_info->agg[tid]); + + sta_info->stats[tid].clear = true; + + if (tid_info) { + bitmap_zero(tid_info->bitmap, CARL9170_BAW_SIZE); + tid_info->state = CARL9170_TID_STATE_IDLE; + } + rcu_read_unlock(); + + if (WARN_ON_ONCE(!tid_info)) + return -EFAULT; + + break; + + case IEEE80211_AMPDU_RX_START: + case IEEE80211_AMPDU_RX_STOP: + /* Handled by hardware */ + break; + + default: + return -EOPNOTSUPP; + } + + return 0; +} + +#ifdef CONFIG_CARL9170_WPC +static int carl9170_register_wps_button(struct ar9170 *ar) +{ + struct input_dev *input; + int err; + + if (!(ar->features & CARL9170_WPS_BUTTON)) + return 0; + + input = input_allocate_device(); + if (!input) + return -ENOMEM; + + snprintf(ar->wps.name, sizeof(ar->wps.name), "%s WPS Button", + wiphy_name(ar->hw->wiphy)); + + snprintf(ar->wps.phys, sizeof(ar->wps.phys), + "ieee80211/%s/input0", wiphy_name(ar->hw->wiphy)); + + input->name = ar->wps.name; + input->phys = ar->wps.phys; + input->id.bustype = BUS_USB; + input->dev.parent = &ar->hw->wiphy->dev; + + input_set_capability(input, EV_KEY, KEY_WPS_BUTTON); + + err = input_register_device(input); + if (err) { + input_free_device(input); + return err; + } + + ar->wps.pbc = input; + return 0; +} +#endif /* CONFIG_CARL9170_WPC */ + +static int carl9170_op_get_survey(struct ieee80211_hw *hw, int idx, + struct survey_info *survey) +{ + struct ar9170 *ar = hw->priv; + int err; + + if (idx != 0) + return -ENOENT; + + mutex_lock(&ar->mutex); + err = carl9170_get_noisefloor(ar); + mutex_unlock(&ar->mutex); + if (err) + return err; + + survey->channel = ar->channel; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = ar->noise[0]; + return 0; +} + +static void carl9170_op_flush(struct ieee80211_hw *hw, bool drop) +{ + struct ar9170 *ar = hw->priv; + unsigned int vid; + + mutex_lock(&ar->mutex); + for_each_set_bit(vid, &ar->vif_bitmap, ar->fw.vif_num) + carl9170_flush_cab(ar, vid); + + carl9170_flush(ar, drop); + mutex_unlock(&ar->mutex); +} + +static int carl9170_op_get_stats(struct ieee80211_hw *hw, + struct ieee80211_low_level_stats *stats) +{ + struct ar9170 *ar = hw->priv; + + memset(stats, 0, sizeof(*stats)); + stats->dot11ACKFailureCount = ar->tx_ack_failures; + stats->dot11FCSErrorCount = ar->tx_fcs_errors; + return 0; +} + +static void carl9170_op_sta_notify(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum sta_notify_cmd cmd, + struct ieee80211_sta *sta) +{ + struct ar9170 *ar = hw->priv; + struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; + struct sk_buff *skb, *tmp; + struct sk_buff_head free; + int i; + + switch (cmd) { + case STA_NOTIFY_SLEEP: + /* + * Since the peer is no longer listening, we have to return + * as many SKBs as possible back to the mac80211 stack. + * It will deal with the retry procedure, once the peer + * has become available again. + * + * NB: Ideally, the driver should return the all frames in + * the correct, ascending order. However, I think that this + * functionality should be implemented in the stack and not + * here... + */ + + __skb_queue_head_init(&free); + + if (sta->ht_cap.ht_supported) { + rcu_read_lock(); + for (i = 0; i < CARL9170_NUM_TID; i++) { + struct carl9170_sta_tid *tid_info; + + tid_info = rcu_dereference(sta_info->agg[i]); + + if (!tid_info) + continue; + + spin_lock_bh(&ar->tx_ampdu_list_lock); + if (tid_info->state > + CARL9170_TID_STATE_SUSPEND) + tid_info->state = + CARL9170_TID_STATE_SUSPEND; + spin_unlock_bh(&ar->tx_ampdu_list_lock); + + spin_lock_bh(&tid_info->lock); + while ((skb = __skb_dequeue(&tid_info->queue))) + __skb_queue_tail(&free, skb); + spin_unlock_bh(&tid_info->lock); + } + rcu_read_unlock(); + } + + for (i = 0; i < ar->hw->queues; i++) { + spin_lock_bh(&ar->tx_pending[i].lock); + skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) { + struct _carl9170_tx_superframe *super; + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *info; + + super = (void *) skb->data; + hdr = (void *) super->frame_data; + + if (compare_ether_addr(hdr->addr1, sta->addr)) + continue; + + __skb_unlink(skb, &ar->tx_pending[i]); + + info = IEEE80211_SKB_CB(skb); + if (info->flags & IEEE80211_TX_CTL_AMPDU) + atomic_dec(&ar->tx_ampdu_upload); + + carl9170_tx_status(ar, skb, false); + } + spin_unlock_bh(&ar->tx_pending[i].lock); + } + + while ((skb = __skb_dequeue(&free))) + carl9170_tx_status(ar, skb, false); + + break; + + case STA_NOTIFY_AWAKE: + if (!sta->ht_cap.ht_supported) + return; + + rcu_read_lock(); + for (i = 0; i < CARL9170_NUM_TID; i++) { + struct carl9170_sta_tid *tid_info; + + tid_info = rcu_dereference(sta_info->agg[i]); + + if (!tid_info) + continue; + + if ((tid_info->state == CARL9170_TID_STATE_SUSPEND)) + tid_info->state = CARL9170_TID_STATE_IDLE; + } + rcu_read_unlock(); + break; + } +} + +static const struct ieee80211_ops carl9170_ops = { + .start = carl9170_op_start, + .stop = carl9170_op_stop, + .tx = carl9170_op_tx, + .flush = carl9170_op_flush, + .add_interface = carl9170_op_add_interface, + .remove_interface = carl9170_op_remove_interface, + .config = carl9170_op_config, + .prepare_multicast = carl9170_op_prepare_multicast, + .configure_filter = carl9170_op_configure_filter, + .conf_tx = carl9170_op_conf_tx, + .bss_info_changed = carl9170_op_bss_info_changed, + .get_tsf = carl9170_op_get_tsf, + .set_key = carl9170_op_set_key, + .sta_add = carl9170_op_sta_add, + .sta_remove = carl9170_op_sta_remove, + .sta_notify = carl9170_op_sta_notify, + .get_survey = carl9170_op_get_survey, + .get_stats = carl9170_op_get_stats, + .ampdu_action = carl9170_op_ampdu_action, +}; + +void *carl9170_alloc(size_t priv_size) +{ + struct ieee80211_hw *hw; + struct ar9170 *ar; + struct sk_buff *skb; + int i; + + /* + * this buffer is used for rx stream reconstruction. + * Under heavy load this device (or the transport layer?) + * tends to split the streams into separate rx descriptors. + */ + + skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL); + if (!skb) + goto err_nomem; + + hw = ieee80211_alloc_hw(priv_size, &carl9170_ops); + if (!hw) + goto err_nomem; + + ar = hw->priv; + ar->hw = hw; + ar->rx_failover = skb; + + memset(&ar->rx_plcp, 0, sizeof(struct ar9170_rx_head)); + ar->rx_has_plcp = false; + + /* + * Here's a hidden pitfall! + * + * All 4 AC queues work perfectly well under _legacy_ operation. + * However as soon as aggregation is enabled, the traffic flow + * gets very bumpy. Therefore we have to _switch_ to a + * software AC with a single HW queue. + */ + hw->queues = __AR9170_NUM_TXQ; + + mutex_init(&ar->mutex); + spin_lock_init(&ar->beacon_lock); + spin_lock_init(&ar->cmd_lock); + spin_lock_init(&ar->tx_stats_lock); + spin_lock_init(&ar->tx_ampdu_list_lock); + spin_lock_init(&ar->mem_lock); + spin_lock_init(&ar->state_lock); + atomic_set(&ar->pending_restarts, 0); + ar->vifs = 0; + for (i = 0; i < ar->hw->queues; i++) { + skb_queue_head_init(&ar->tx_status[i]); + skb_queue_head_init(&ar->tx_pending[i]); + } + INIT_WORK(&ar->ps_work, carl9170_ps_work); + INIT_WORK(&ar->restart_work, carl9170_restart_work); + INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work); + INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor); + INIT_LIST_HEAD(&ar->tx_ampdu_list); + rcu_assign_pointer(ar->tx_ampdu_iter, + (struct carl9170_sta_tid *) &ar->tx_ampdu_list); + + bitmap_zero(&ar->vif_bitmap, ar->fw.vif_num); + INIT_LIST_HEAD(&ar->vif_list); + init_completion(&ar->tx_flush); + + /* + * Note: + * IBSS/ADHOC and AP mode are only enabled, if the firmware + * supports these modes. The code which will add the + * additional interface_modes is in fw.c. + */ + hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + + hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_REPORTS_TX_ACK_STATUS | + IEEE80211_HW_SUPPORTS_PS | + IEEE80211_HW_PS_NULLFUNC_STACK | + IEEE80211_HW_SIGNAL_DBM; + + if (!modparam_noht) { + /* + * see the comment above, why we allow the user + * to disable HT by a module parameter. + */ + hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; + } + + hw->extra_tx_headroom = sizeof(struct _carl9170_tx_superframe); + hw->sta_data_size = sizeof(struct carl9170_sta_info); + hw->vif_data_size = sizeof(struct carl9170_vif_info); + + hw->max_rates = CARL9170_TX_MAX_RATES; + hw->max_rate_tries = CARL9170_TX_USER_RATE_TRIES; + + for (i = 0; i < ARRAY_SIZE(ar->noise); i++) + ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ + + hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + return ar; + +err_nomem: + kfree_skb(skb); + return ERR_PTR(-ENOMEM); +} + +static int carl9170_read_eeprom(struct ar9170 *ar) +{ +#define RW 8 /* number of words to read at once */ +#define RB (sizeof(u32) * RW) + u8 *eeprom = (void *)&ar->eeprom; + __le32 offsets[RW]; + int i, j, err; + + BUILD_BUG_ON(sizeof(ar->eeprom) & 3); + + BUILD_BUG_ON(RB > CARL9170_MAX_CMD_LEN - 4); +#ifndef __CHECKER__ + /* don't want to handle trailing remains */ + BUILD_BUG_ON(sizeof(ar->eeprom) % RB); +#endif + + for (i = 0; i < sizeof(ar->eeprom)/RB; i++) { + for (j = 0; j < RW; j++) + offsets[j] = cpu_to_le32(AR9170_EEPROM_START + + RB * i + 4 * j); + + err = carl9170_exec_cmd(ar, CARL9170_CMD_RREG, + RB, (u8 *) &offsets, + RB, eeprom + RB * i); + if (err) + return err; + } + +#undef RW +#undef RB + return 0; +} + +static int carl9170_parse_eeprom(struct ar9170 *ar) +{ + struct ath_regulatory *regulatory = &ar->common.regulatory; + unsigned int rx_streams, tx_streams, tx_params = 0; + int bands = 0; + + if (ar->eeprom.length == cpu_to_le16(0xffff)) + return -ENODATA; + + rx_streams = hweight8(ar->eeprom.rx_mask); + tx_streams = hweight8(ar->eeprom.tx_mask); + + if (rx_streams != tx_streams) { + tx_params = IEEE80211_HT_MCS_TX_RX_DIFF; + + WARN_ON(!(tx_streams >= 1 && tx_streams <= + IEEE80211_HT_MCS_TX_MAX_STREAMS)); + + tx_params = (tx_streams - 1) << + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT; + + carl9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params; + carl9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params; + } + + if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) { + ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = + &carl9170_band_2GHz; + bands++; + } + if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) { + ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &carl9170_band_5GHz; + bands++; + } + + /* + * I measured this, a bandswitch takes roughly + * 135 ms and a frequency switch about 80. + * + * FIXME: measure these values again once EEPROM settings + * are used, that will influence them! + */ + if (bands == 2) + ar->hw->channel_change_time = 135 * 1000; + else + ar->hw->channel_change_time = 80 * 1000; + + regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]); + regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]); + + /* second part of wiphy init */ + SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address); + + return bands ? 0 : -EINVAL; +} + +static int carl9170_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ar9170 *ar = hw->priv; + + return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory); +} + +int carl9170_register(struct ar9170 *ar) +{ + struct ath_regulatory *regulatory = &ar->common.regulatory; + int err = 0, i; + + if (WARN_ON(ar->mem_bitmap)) + return -EINVAL; + + ar->mem_bitmap = kzalloc(roundup(ar->fw.mem_blocks, BITS_PER_LONG) * + sizeof(unsigned long), GFP_KERNEL); + + if (!ar->mem_bitmap) + return -ENOMEM; + + /* try to read EEPROM, init MAC addr */ + err = carl9170_read_eeprom(ar); + if (err) + return err; + + err = carl9170_fw_fix_eeprom(ar); + if (err) + return err; + + err = carl9170_parse_eeprom(ar); + if (err) + return err; + + err = ath_regd_init(regulatory, ar->hw->wiphy, + carl9170_reg_notifier); + if (err) + return err; + + if (modparam_noht) { + carl9170_band_2GHz.ht_cap.ht_supported = false; + carl9170_band_5GHz.ht_cap.ht_supported = false; + } + + for (i = 0; i < ar->fw.vif_num; i++) { + ar->vif_priv[i].id = i; + ar->vif_priv[i].vif = NULL; + } + + err = ieee80211_register_hw(ar->hw); + if (err) + return err; + + /* mac80211 interface is now registered */ + ar->registered = true; + + if (!ath_is_world_regd(regulatory)) + regulatory_hint(ar->hw->wiphy, regulatory->alpha2); + +#ifdef CONFIG_CARL9170_DEBUGFS + carl9170_debugfs_register(ar); +#endif /* CONFIG_CARL9170_DEBUGFS */ + + err = carl9170_led_init(ar); + if (err) + goto err_unreg; + +#ifdef CONFIG_CARL9170_LEDS + err = carl9170_led_register(ar); + if (err) + goto err_unreg; +#endif /* CONFIG_CAR9L170_LEDS */ + +#ifdef CONFIG_CARL9170_WPC + err = carl9170_register_wps_button(ar); + if (err) + goto err_unreg; +#endif /* CONFIG_CARL9170_WPC */ + + dev_info(&ar->udev->dev, "Atheros AR9170 is registered as '%s'\n", + wiphy_name(ar->hw->wiphy)); + + return 0; + +err_unreg: + carl9170_unregister(ar); + return err; +} + +void carl9170_unregister(struct ar9170 *ar) +{ + if (!ar->registered) + return; + + ar->registered = false; + +#ifdef CONFIG_CARL9170_LEDS + carl9170_led_unregister(ar); +#endif /* CONFIG_CARL9170_LEDS */ + +#ifdef CONFIG_CARL9170_DEBUGFS + carl9170_debugfs_unregister(ar); +#endif /* CONFIG_CARL9170_DEBUGFS */ + +#ifdef CONFIG_CARL9170_WPC + if (ar->wps.pbc) { + input_unregister_device(ar->wps.pbc); + ar->wps.pbc = NULL; + } +#endif /* CONFIG_CARL9170_WPC */ + + carl9170_cancel_worker(ar); + cancel_work_sync(&ar->restart_work); + + ieee80211_unregister_hw(ar->hw); +} + +void carl9170_free(struct ar9170 *ar) +{ + WARN_ON(ar->registered); + WARN_ON(IS_INITIALIZED(ar)); + + kfree_skb(ar->rx_failover); + ar->rx_failover = NULL; + + kfree(ar->mem_bitmap); + ar->mem_bitmap = NULL; + + mutex_destroy(&ar->mutex); + + ieee80211_free_hw(ar->hw); +} diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c new file mode 100644 index 0000000000000000000000000000000000000000..89deca37a9888963d4e9cca97b5173c84a528946 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -0,0 +1,1810 @@ +/* + * Atheros CARL9170 driver + * + * PHY and RF code + * + * Copyright 2008, Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include "carl9170.h" +#include "cmd.h" +#include "phy.h" + +static int carl9170_init_power_cal(struct ar9170 *ar) +{ + carl9170_regwrite_begin(ar); + + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE_MAX, 0x7f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE1, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE2, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE3, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE4, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE5, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE6, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE7, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE8, 0x3f3f3f3f); + carl9170_regwrite(AR9170_PHY_REG_POWER_TX_RATE9, 0x3f3f3f3f); + + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +struct carl9170_phy_init { + u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20; +}; + +static struct carl9170_phy_init ar5416_phy_init[] = { + { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, + { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, }, + { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, }, + { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, }, + { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, }, + { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, }, + { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, }, + { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, + { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, }, + { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, + { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, }, + { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, + { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, }, + { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, }, + { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, }, + { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, }, + { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, }, + { 0x1c5850, 0x6c48b4e4, 0x6d48b4e4, 0x6d48b0e4, 0x6c48b0e4, }, + { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, }, + { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, }, + { 0x1c585c, 0x31395c5e, 0x3139605e, 0x3139605e, 0x31395c5e, }, + { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, }, + { 0x1c5864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, }, + { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, }, + { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, }, + { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, }, + { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, }, + { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, }, + { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, }, + { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, }, + { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, + { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, + { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, }, + { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, }, + { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, }, + { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, }, + { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, }, + { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, }, + { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, + { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, }, + { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, }, + { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, + { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, + { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, }, + { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, }, + { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, }, + { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, }, + { 0x1c59bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, }, + { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, }, + { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, }, + { 0x1c59c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, }, + { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, }, + { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, }, + { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, }, + { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, }, + { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, }, + { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, }, + { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, }, + { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, }, + { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, }, + { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, }, + { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, }, + { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, }, + { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, }, + { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, }, + { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, }, + { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, }, + { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, + { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, }, + { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, }, + { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, }, + { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, }, + { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, }, + { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, }, + { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, }, + { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, }, + { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, }, + { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, }, + { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, }, + { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, }, + { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, }, + { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, }, + { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, }, + { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, }, + { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, }, + { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, }, + { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, }, + { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, }, + { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, }, + { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, }, + { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, }, + { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, }, + { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, }, + { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, }, + { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, }, + { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, }, + { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, }, + { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, }, + { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, + { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, }, + { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, }, + { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, }, + { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, }, + { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, }, + { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, }, + { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, }, + { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, }, + { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, }, + { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, }, + { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, + { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, }, + { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, }, + { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, }, + { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, }, + { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, }, + { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, }, + { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, }, + { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, + { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, }, + { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, }, + { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, }, + { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, }, + { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, }, + { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, }, + { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, }, + { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, }, + { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, }, + { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, }, + { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, }, + { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, }, + { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, }, + { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, }, + { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, }, + { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, }, + { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, }, + { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, }, + { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, }, + { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, }, + { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, }, + { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, }, + { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, }, + { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, }, + { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, }, + { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, }, + { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, + { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, }, + { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, }, + { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, }, + { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, }, + { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, }, + { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, }, + { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, }, + { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, }, + { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, }, + { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, }, + { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, }, + { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, }, + { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, }, + { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, }, + { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, }, + { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, }, + { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, }, + { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, }, + { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, + { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, }, + { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, + { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, }, + { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, }, + { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, }, + { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, }, + { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, }, + { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, }, + { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, }, + { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, }, + { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, }, + { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, }, + { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, }, + { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, }, + { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, + { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, + { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, }, + { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, }, + { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, }, + { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, }, + { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, + { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, }, + { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, }, + { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, }, + { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }, + { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, }, + { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, }, + { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, + { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, + { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, + { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, + { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, + { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, }, + { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, }, + { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, }, + { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, }, + { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, }, +/* { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */ + { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, }, + { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, }, + { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, }, + { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, }, + { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, }, + { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, }, + { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, }, + { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, }, + { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, }, + { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, }, + { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, }, + { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, }, + { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, }, + { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, }, + { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, }, + { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, } +}; + +/* + * look up a certain register in ar5416_phy_init[] and return the init. value + * for the band and bandwidth given. Return 0 if register address not found. + */ +static u32 carl9170_def_val(u32 reg, bool is_2ghz, bool is_40mhz) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { + if (ar5416_phy_init[i].reg != reg) + continue; + + if (is_2ghz) { + if (is_40mhz) + return ar5416_phy_init[i]._2ghz_40; + else + return ar5416_phy_init[i]._2ghz_20; + } else { + if (is_40mhz) + return ar5416_phy_init[i]._5ghz_40; + else + return ar5416_phy_init[i]._5ghz_20; + } + } + return 0; +} + +/* + * initialize some phy regs from eeprom values in modal_header[] + * acc. to band and bandwith + */ +static int carl9170_init_phy_from_eeprom(struct ar9170 *ar, + bool is_2ghz, bool is_40mhz) +{ + static const u8 xpd2pd[16] = { + 0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2, + 0x2, 0x3, 0x7, 0x2, 0xb, 0x2, 0x2, 0x2 + }; + /* pointer to the modal_header acc. to band */ + struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz]; + u32 val; + + carl9170_regwrite_begin(ar); + + /* ant common control (index 0) */ + carl9170_regwrite(AR9170_PHY_REG_SWITCH_COM, + le32_to_cpu(m->antCtrlCommon)); + + /* ant control chain 0 (index 1) */ + carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_0, + le32_to_cpu(m->antCtrlChain[0])); + + /* ant control chain 2 (index 2) */ + carl9170_regwrite(AR9170_PHY_REG_SWITCH_CHAIN_2, + le32_to_cpu(m->antCtrlChain[1])); + + /* SwSettle (index 3) */ + if (!is_40mhz) { + val = carl9170_def_val(AR9170_PHY_REG_SETTLING, + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_SETTLING_SWITCH, val, m->switchSettling); + carl9170_regwrite(AR9170_PHY_REG_SETTLING, val); + } + + /* adcDesired, pdaDesired (index 4) */ + val = carl9170_def_val(AR9170_PHY_REG_DESIRED_SZ, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_DESIRED_SZ_PGA, val, m->pgaDesiredSize); + SET_VAL(AR9170_PHY_DESIRED_SZ_ADC, val, m->adcDesiredSize); + carl9170_regwrite(AR9170_PHY_REG_DESIRED_SZ, val); + + /* TxEndToXpaOff, TxFrameToXpaOn (index 5) */ + val = carl9170_def_val(AR9170_PHY_REG_RF_CTL4, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF, val, m->txEndToXpaOff); + SET_VAL(AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF, val, m->txEndToXpaOff); + SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAB_ON, val, m->txFrameToXpaOn); + SET_VAL(AR9170_PHY_RF_CTL4_FRAME_XPAA_ON, val, m->txFrameToXpaOn); + carl9170_regwrite(AR9170_PHY_REG_RF_CTL4, val); + + /* TxEndToRxOn (index 6) */ + val = carl9170_def_val(AR9170_PHY_REG_RF_CTL3, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON, val, m->txEndToRxOn); + carl9170_regwrite(AR9170_PHY_REG_RF_CTL3, val); + + /* thresh62 (index 7) */ + val = carl9170_def_val(0x1c8864, is_2ghz, is_40mhz); + val = (val & ~0x7f000) | (m->thresh62 << 12); + carl9170_regwrite(0x1c8864, val); + + /* tx/rx attenuation chain 0 (index 8) */ + val = carl9170_def_val(AR9170_PHY_REG_RXGAIN, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[0]); + carl9170_regwrite(AR9170_PHY_REG_RXGAIN, val); + + /* tx/rx attenuation chain 2 (index 9) */ + val = carl9170_def_val(AR9170_PHY_REG_RXGAIN_CHAIN_2, + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_RXGAIN_TXRX_ATTEN, val, m->txRxAttenCh[1]); + carl9170_regwrite(AR9170_PHY_REG_RXGAIN_CHAIN_2, val); + + /* tx/rx margin chain 0 (index 10) */ + val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[0]); + /* bsw margin chain 0 for 5GHz only */ + if (!is_2ghz) + SET_VAL(AR9170_PHY_GAIN_2GHZ_BSW_MARGIN, val, m->bswMargin[0]); + carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ, val); + + /* tx/rx margin chain 2 (index 11) */ + val = carl9170_def_val(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN, val, m->rxTxMarginCh[1]); + carl9170_regwrite(AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2, val); + + /* iqCall, iqCallq chain 0 (index 12) */ + val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(0), + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[0]); + SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[0]); + carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(0), val); + + /* iqCall, iqCallq chain 2 (index 13) */ + val = carl9170_def_val(AR9170_PHY_REG_TIMING_CTRL4(2), + is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, val, m->iqCalICh[1]); + SET_VAL(AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, val, m->iqCalQCh[1]); + carl9170_regwrite(AR9170_PHY_REG_TIMING_CTRL4(2), val); + + /* xpd gain mask (index 14) */ + val = carl9170_def_val(AR9170_PHY_REG_TPCRG1, is_2ghz, is_40mhz); + SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_1, val, + xpd2pd[m->xpdGain & 0xf] & 3); + SET_VAL(AR9170_PHY_TPCRG1_PD_GAIN_2, val, + xpd2pd[m->xpdGain & 0xf] >> 2); + carl9170_regwrite(AR9170_PHY_REG_TPCRG1, val); + + carl9170_regwrite(AR9170_PHY_REG_RX_CHAINMASK, ar->eeprom.rx_mask); + carl9170_regwrite(AR9170_PHY_REG_CAL_CHAINMASK, ar->eeprom.rx_mask); + + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +static int carl9170_init_phy(struct ar9170 *ar, enum ieee80211_band band) +{ + int i, err; + u32 val; + bool is_2ghz = band == IEEE80211_BAND_2GHZ; + bool is_40mhz = conf_is_ht40(&ar->hw->conf); + + carl9170_regwrite_begin(ar); + + for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) { + if (is_40mhz) { + if (is_2ghz) + val = ar5416_phy_init[i]._2ghz_40; + else + val = ar5416_phy_init[i]._5ghz_40; + } else { + if (is_2ghz) + val = ar5416_phy_init[i]._2ghz_20; + else + val = ar5416_phy_init[i]._5ghz_20; + } + + carl9170_regwrite(ar5416_phy_init[i].reg, val); + } + + carl9170_regwrite_finish(); + err = carl9170_regwrite_result(); + if (err) + return err; + + err = carl9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz); + if (err) + return err; + + err = carl9170_init_power_cal(ar); + if (err) + return err; + + /* XXX: remove magic! */ + if (is_2ghz) + err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5163); + else + err = carl9170_write_reg(ar, AR9170_PWR_REG_PLL_ADDAC, 0x5143); + + return err; +} + +struct carl9170_rf_initvals { + u32 reg, _5ghz, _2ghz; +}; + +static struct carl9170_rf_initvals carl9170_rf_initval[] = { + /* bank 0 */ + { 0x1c58b0, 0x1e5795e5, 0x1e5795e5}, + { 0x1c58e0, 0x02008020, 0x02008020}, + /* bank 1 */ + { 0x1c58b0, 0x02108421, 0x02108421}, + { 0x1c58ec, 0x00000008, 0x00000008}, + /* bank 2 */ + { 0x1c58b0, 0x0e73ff17, 0x0e73ff17}, + { 0x1c58e0, 0x00000420, 0x00000420}, + /* bank 3 */ + { 0x1c58f0, 0x01400018, 0x01c00018}, + /* bank 4 */ + { 0x1c58b0, 0x000001a1, 0x000001a1}, + { 0x1c58e8, 0x00000001, 0x00000001}, + /* bank 5 */ + { 0x1c58b0, 0x00000013, 0x00000013}, + { 0x1c58e4, 0x00000002, 0x00000002}, + /* bank 6 */ + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00004000, 0x00004000}, + { 0x1c58b0, 0x00006c00, 0x00006c00}, + { 0x1c58b0, 0x00002c00, 0x00002c00}, + { 0x1c58b0, 0x00004800, 0x00004800}, + { 0x1c58b0, 0x00004000, 0x00004000}, + { 0x1c58b0, 0x00006000, 0x00006000}, + { 0x1c58b0, 0x00001000, 0x00001000}, + { 0x1c58b0, 0x00004000, 0x00004000}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00087c00, 0x00087c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00005400, 0x00005400}, + { 0x1c58b0, 0x00000c00, 0x00000c00}, + { 0x1c58b0, 0x00001800, 0x00001800}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00006c00, 0x00006c00}, + { 0x1c58b0, 0x00006c00, 0x00006c00}, + { 0x1c58b0, 0x00007c00, 0x00007c00}, + { 0x1c58b0, 0x00002c00, 0x00002c00}, + { 0x1c58b0, 0x00003c00, 0x00003c00}, + { 0x1c58b0, 0x00003800, 0x00003800}, + { 0x1c58b0, 0x00001c00, 0x00001c00}, + { 0x1c58b0, 0x00000800, 0x00000800}, + { 0x1c58b0, 0x00000408, 0x00000408}, + { 0x1c58b0, 0x00004c15, 0x00004c15}, + { 0x1c58b0, 0x00004188, 0x00004188}, + { 0x1c58b0, 0x0000201e, 0x0000201e}, + { 0x1c58b0, 0x00010408, 0x00010408}, + { 0x1c58b0, 0x00000801, 0x00000801}, + { 0x1c58b0, 0x00000c08, 0x00000c08}, + { 0x1c58b0, 0x0000181e, 0x0000181e}, + { 0x1c58b0, 0x00001016, 0x00001016}, + { 0x1c58b0, 0x00002800, 0x00002800}, + { 0x1c58b0, 0x00004010, 0x00004010}, + { 0x1c58b0, 0x0000081c, 0x0000081c}, + { 0x1c58b0, 0x00000115, 0x00000115}, + { 0x1c58b0, 0x00000015, 0x00000015}, + { 0x1c58b0, 0x00000066, 0x00000066}, + { 0x1c58b0, 0x0000001c, 0x0000001c}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000004, 0x00000004}, + { 0x1c58b0, 0x00000015, 0x00000015}, + { 0x1c58b0, 0x0000001f, 0x0000001f}, + { 0x1c58e0, 0x00000000, 0x00000400}, + /* bank 7 */ + { 0x1c58b0, 0x000000a0, 0x000000a0}, + { 0x1c58b0, 0x00000000, 0x00000000}, + { 0x1c58b0, 0x00000040, 0x00000040}, + { 0x1c58f0, 0x0000001c, 0x0000001c}, +}; + +static int carl9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz) +{ + int err, i; + + carl9170_regwrite_begin(ar); + + for (i = 0; i < ARRAY_SIZE(carl9170_rf_initval); i++) + carl9170_regwrite(carl9170_rf_initval[i].reg, + band5ghz ? carl9170_rf_initval[i]._5ghz + : carl9170_rf_initval[i]._2ghz); + + carl9170_regwrite_finish(); + err = carl9170_regwrite_result(); + if (err) + wiphy_err(ar->hw->wiphy, "rf init failed\n"); + + return err; +} + +struct carl9170_phy_freq_params { + u8 coeff_exp; + u16 coeff_man; + u8 coeff_exp_shgi; + u16 coeff_man_shgi; +}; + +enum carl9170_bw { + CARL9170_BW_20, + CARL9170_BW_40_BELOW, + CARL9170_BW_40_ABOVE, + + __CARL9170_NUM_BW, +}; + +struct carl9170_phy_freq_entry { + u16 freq; + struct carl9170_phy_freq_params params[__CARL9170_NUM_BW]; +}; + +/* NB: must be in sync with channel tables in main! */ +static const struct carl9170_phy_freq_entry carl9170_phy_freq_params[] = { +/* + * freq, + * 20MHz, + * 40MHz (below), + * 40Mhz (above), + */ + { 2412, { + { 3, 21737, 3, 19563, }, + { 3, 21827, 3, 19644, }, + { 3, 21647, 3, 19482, }, + } }, + { 2417, { + { 3, 21692, 3, 19523, }, + { 3, 21782, 3, 19604, }, + { 3, 21602, 3, 19442, }, + } }, + { 2422, { + { 3, 21647, 3, 19482, }, + { 3, 21737, 3, 19563, }, + { 3, 21558, 3, 19402, }, + } }, + { 2427, { + { 3, 21602, 3, 19442, }, + { 3, 21692, 3, 19523, }, + { 3, 21514, 3, 19362, }, + } }, + { 2432, { + { 3, 21558, 3, 19402, }, + { 3, 21647, 3, 19482, }, + { 3, 21470, 3, 19323, }, + } }, + { 2437, { + { 3, 21514, 3, 19362, }, + { 3, 21602, 3, 19442, }, + { 3, 21426, 3, 19283, }, + } }, + { 2442, { + { 3, 21470, 3, 19323, }, + { 3, 21558, 3, 19402, }, + { 3, 21382, 3, 19244, }, + } }, + { 2447, { + { 3, 21426, 3, 19283, }, + { 3, 21514, 3, 19362, }, + { 3, 21339, 3, 19205, }, + } }, + { 2452, { + { 3, 21382, 3, 19244, }, + { 3, 21470, 3, 19323, }, + { 3, 21295, 3, 19166, }, + } }, + { 2457, { + { 3, 21339, 3, 19205, }, + { 3, 21426, 3, 19283, }, + { 3, 21252, 3, 19127, }, + } }, + { 2462, { + { 3, 21295, 3, 19166, }, + { 3, 21382, 3, 19244, }, + { 3, 21209, 3, 19088, }, + } }, + { 2467, { + { 3, 21252, 3, 19127, }, + { 3, 21339, 3, 19205, }, + { 3, 21166, 3, 19050, }, + } }, + { 2472, { + { 3, 21209, 3, 19088, }, + { 3, 21295, 3, 19166, }, + { 3, 21124, 3, 19011, }, + } }, + { 2484, { + { 3, 21107, 3, 18996, }, + { 3, 21192, 3, 19073, }, + { 3, 21022, 3, 18920, }, + } }, + { 4920, { + { 4, 21313, 4, 19181, }, + { 4, 21356, 4, 19220, }, + { 4, 21269, 4, 19142, }, + } }, + { 4940, { + { 4, 21226, 4, 19104, }, + { 4, 21269, 4, 19142, }, + { 4, 21183, 4, 19065, }, + } }, + { 4960, { + { 4, 21141, 4, 19027, }, + { 4, 21183, 4, 19065, }, + { 4, 21098, 4, 18988, }, + } }, + { 4980, { + { 4, 21056, 4, 18950, }, + { 4, 21098, 4, 18988, }, + { 4, 21014, 4, 18912, }, + } }, + { 5040, { + { 4, 20805, 4, 18725, }, + { 4, 20846, 4, 18762, }, + { 4, 20764, 4, 18687, }, + } }, + { 5060, { + { 4, 20723, 4, 18651, }, + { 4, 20764, 4, 18687, }, + { 4, 20682, 4, 18614, }, + } }, + { 5080, { + { 4, 20641, 4, 18577, }, + { 4, 20682, 4, 18614, }, + { 4, 20601, 4, 18541, }, + } }, + { 5180, { + { 4, 20243, 4, 18219, }, + { 4, 20282, 4, 18254, }, + { 4, 20204, 4, 18183, }, + } }, + { 5200, { + { 4, 20165, 4, 18148, }, + { 4, 20204, 4, 18183, }, + { 4, 20126, 4, 18114, }, + } }, + { 5220, { + { 4, 20088, 4, 18079, }, + { 4, 20126, 4, 18114, }, + { 4, 20049, 4, 18044, }, + } }, + { 5240, { + { 4, 20011, 4, 18010, }, + { 4, 20049, 4, 18044, }, + { 4, 19973, 4, 17976, }, + } }, + { 5260, { + { 4, 19935, 4, 17941, }, + { 4, 19973, 4, 17976, }, + { 4, 19897, 4, 17907, }, + } }, + { 5280, { + { 4, 19859, 4, 17873, }, + { 4, 19897, 4, 17907, }, + { 4, 19822, 4, 17840, }, + } }, + { 5300, { + { 4, 19784, 4, 17806, }, + { 4, 19822, 4, 17840, }, + { 4, 19747, 4, 17772, }, + } }, + { 5320, { + { 4, 19710, 4, 17739, }, + { 4, 19747, 4, 17772, }, + { 4, 19673, 4, 17706, }, + } }, + { 5500, { + { 4, 19065, 4, 17159, }, + { 4, 19100, 4, 17190, }, + { 4, 19030, 4, 17127, }, + } }, + { 5520, { + { 4, 18996, 4, 17096, }, + { 4, 19030, 4, 17127, }, + { 4, 18962, 4, 17065, }, + } }, + { 5540, { + { 4, 18927, 4, 17035, }, + { 4, 18962, 4, 17065, }, + { 4, 18893, 4, 17004, }, + } }, + { 5560, { + { 4, 18859, 4, 16973, }, + { 4, 18893, 4, 17004, }, + { 4, 18825, 4, 16943, }, + } }, + { 5580, { + { 4, 18792, 4, 16913, }, + { 4, 18825, 4, 16943, }, + { 4, 18758, 4, 16882, }, + } }, + { 5600, { + { 4, 18725, 4, 16852, }, + { 4, 18758, 4, 16882, }, + { 4, 18691, 4, 16822, }, + } }, + { 5620, { + { 4, 18658, 4, 16792, }, + { 4, 18691, 4, 16822, }, + { 4, 18625, 4, 16762, }, + } }, + { 5640, { + { 4, 18592, 4, 16733, }, + { 4, 18625, 4, 16762, }, + { 4, 18559, 4, 16703, }, + } }, + { 5660, { + { 4, 18526, 4, 16673, }, + { 4, 18559, 4, 16703, }, + { 4, 18493, 4, 16644, }, + } }, + { 5680, { + { 4, 18461, 4, 16615, }, + { 4, 18493, 4, 16644, }, + { 4, 18428, 4, 16586, }, + } }, + { 5700, { + { 4, 18396, 4, 16556, }, + { 4, 18428, 4, 16586, }, + { 4, 18364, 4, 16527, }, + } }, + { 5745, { + { 4, 18252, 4, 16427, }, + { 4, 18284, 4, 16455, }, + { 4, 18220, 4, 16398, }, + } }, + { 5765, { + { 4, 18189, 5, 32740, }, + { 4, 18220, 4, 16398, }, + { 4, 18157, 5, 32683, }, + } }, + { 5785, { + { 4, 18126, 5, 32626, }, + { 4, 18157, 5, 32683, }, + { 4, 18094, 5, 32570, }, + } }, + { 5805, { + { 4, 18063, 5, 32514, }, + { 4, 18094, 5, 32570, }, + { 4, 18032, 5, 32458, }, + } }, + { 5825, { + { 4, 18001, 5, 32402, }, + { 4, 18032, 5, 32458, }, + { 4, 17970, 5, 32347, }, + } }, + { 5170, { + { 4, 20282, 4, 18254, }, + { 4, 20321, 4, 18289, }, + { 4, 20243, 4, 18219, }, + } }, + { 5190, { + { 4, 20204, 4, 18183, }, + { 4, 20243, 4, 18219, }, + { 4, 20165, 4, 18148, }, + } }, + { 5210, { + { 4, 20126, 4, 18114, }, + { 4, 20165, 4, 18148, }, + { 4, 20088, 4, 18079, }, + } }, + { 5230, { + { 4, 20049, 4, 18044, }, + { 4, 20088, 4, 18079, }, + { 4, 20011, 4, 18010, }, + } }, +}; + +static int carl9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz, + u32 freq, enum carl9170_bw bw) +{ + int err; + u32 d0, d1, td0, td1, fd0, fd1; + u8 chansel; + u8 refsel0 = 1, refsel1 = 0; + u8 lf_synth = 0; + + switch (bw) { + case CARL9170_BW_40_ABOVE: + freq += 10; + break; + case CARL9170_BW_40_BELOW: + freq -= 10; + break; + case CARL9170_BW_20: + break; + default: + BUG(); + return -ENOSYS; + } + + if (band5ghz) { + if (freq % 10) { + chansel = (freq - 4800) / 5; + } else { + chansel = ((freq - 4800) / 10) * 2; + refsel0 = 0; + refsel1 = 1; + } + chansel = byte_rev_table[chansel]; + } else { + if (freq == 2484) { + chansel = 10 + (freq - 2274) / 5; + lf_synth = 1; + } else + chansel = 16 + (freq - 2272) / 5; + chansel *= 4; + chansel = byte_rev_table[chansel]; + } + + d1 = chansel; + d0 = 0x21 | + refsel0 << 3 | + refsel1 << 2 | + lf_synth << 1; + td0 = d0 & 0x1f; + td1 = d1 & 0x1f; + fd0 = td1 << 5 | td0; + + td0 = (d0 >> 5) & 0x7; + td1 = (d1 >> 5) & 0x7; + fd1 = td1 << 5 | td0; + + carl9170_regwrite_begin(ar); + + carl9170_regwrite(0x1c58b0, fd0); + carl9170_regwrite(0x1c58e8, fd1); + + carl9170_regwrite_finish(); + err = carl9170_regwrite_result(); + if (err) + return err; + + msleep(20); + + return 0; +} + +static const struct carl9170_phy_freq_params * +carl9170_get_hw_dyn_params(struct ieee80211_channel *channel, + enum carl9170_bw bw) +{ + unsigned int chanidx = 0; + u16 freq = 2412; + + if (channel) { + chanidx = channel->hw_value; + freq = channel->center_freq; + } + + BUG_ON(chanidx >= ARRAY_SIZE(carl9170_phy_freq_params)); + + BUILD_BUG_ON(__CARL9170_NUM_BW != 3); + + WARN_ON(carl9170_phy_freq_params[chanidx].freq != freq); + + return &carl9170_phy_freq_params[chanidx].params[bw]; +} + +static int carl9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f) +{ + int idx = nfreqs - 2; + + while (idx >= 0) { + if (f >= freqs[idx]) + return idx; + idx--; + } + + return 0; +} + +static s32 carl9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) +{ + /* nothing to interpolate, it's horizontal */ + if (y2 == y1) + return y1; + + /* check if we hit one of the edges */ + if (x == x1) + return y1; + if (x == x2) + return y2; + + /* x1 == x2 is bad, hopefully == x */ + if (x2 == x1) + return y1; + + return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1)); +} + +static u8 carl9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2) +{ +#define SHIFT 8 + s32 y; + + y = carl9170_interpolate_s32(x << SHIFT, x1 << SHIFT, + y1 << SHIFT, x2 << SHIFT, y2 << SHIFT); + + /* + * XXX: unwrap this expression + * Isn't it just DIV_ROUND_UP(y, 1<> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1)); +#undef SHIFT +} + +static u8 carl9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array) +{ + int i; + + for (i = 0; i < 3; i++) { + if (x <= x_array[i + 1]) + break; + } + + return carl9170_interpolate_u8(x, x_array[i], y_array[i], + x_array[i + 1], y_array[i + 1]); +} + +static int carl9170_set_freq_cal_data(struct ar9170 *ar, + struct ieee80211_channel *channel) +{ + u8 *cal_freq_pier; + u8 vpds[2][AR5416_PD_GAIN_ICEPTS]; + u8 pwrs[2][AR5416_PD_GAIN_ICEPTS]; + int chain, idx, i; + u32 phy_data = 0; + u8 f, tmp; + + switch (channel->band) { + case IEEE80211_BAND_2GHZ: + f = channel->center_freq - 2300; + cal_freq_pier = ar->eeprom.cal_freq_pier_2G; + i = AR5416_NUM_2G_CAL_PIERS - 1; + break; + + case IEEE80211_BAND_5GHZ: + f = (channel->center_freq - 4800) / 5; + cal_freq_pier = ar->eeprom.cal_freq_pier_5G; + i = AR5416_NUM_5G_CAL_PIERS - 1; + break; + + default: + return -EINVAL; + break; + } + + for (; i >= 0; i--) { + if (cal_freq_pier[i] != 0xff) + break; + } + if (i < 0) + return -EINVAL; + + idx = carl9170_find_freq_idx(i, cal_freq_pier, f); + + carl9170_regwrite_begin(ar); + + for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) { + for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) { + struct ar9170_calibration_data_per_freq *cal_pier_data; + int j; + + switch (channel->band) { + case IEEE80211_BAND_2GHZ: + cal_pier_data = &ar->eeprom. + cal_pier_data_2G[chain][idx]; + break; + + case IEEE80211_BAND_5GHZ: + cal_pier_data = &ar->eeprom. + cal_pier_data_5G[chain][idx]; + break; + + default: + return -EINVAL; + } + + for (j = 0; j < 2; j++) { + vpds[j][i] = carl9170_interpolate_u8(f, + cal_freq_pier[idx], + cal_pier_data->vpd_pdg[j][i], + cal_freq_pier[idx + 1], + cal_pier_data[1].vpd_pdg[j][i]); + + pwrs[j][i] = carl9170_interpolate_u8(f, + cal_freq_pier[idx], + cal_pier_data->pwr_pdg[j][i], + cal_freq_pier[idx + 1], + cal_pier_data[1].pwr_pdg[j][i]) / 2; + } + } + + for (i = 0; i < 76; i++) { + if (i < 25) { + tmp = carl9170_interpolate_val(i, &pwrs[0][0], + &vpds[0][0]); + } else { + tmp = carl9170_interpolate_val(i - 12, + &pwrs[1][0], + &vpds[1][0]); + } + + phy_data |= tmp << ((i & 3) << 3); + if ((i & 3) == 3) { + carl9170_regwrite(0x1c6280 + chain * 0x1000 + + (i & ~3), phy_data); + phy_data = 0; + } + } + + for (i = 19; i < 32; i++) + carl9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2), + 0x0); + } + + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +static u8 carl9170_get_max_edge_power(struct ar9170 *ar, + u32 freq, struct ar9170_calctl_edges edges[]) +{ + int i; + u8 rc = AR5416_MAX_RATE_POWER; + u8 f; + if (freq < 3000) + f = freq - 2300; + else + f = (freq - 4800) / 5; + + for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { + if (edges[i].channel == 0xff) + break; + if (f == edges[i].channel) { + /* exact freq match */ + rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS; + break; + } + if (i > 0 && f < edges[i].channel) { + if (f > edges[i - 1].channel && + edges[i - 1].power_flags & + AR9170_CALCTL_EDGE_FLAGS) { + /* lower channel has the inband flag set */ + rc = edges[i - 1].power_flags & + ~AR9170_CALCTL_EDGE_FLAGS; + } + break; + } + } + + if (i == AR5416_NUM_BAND_EDGES) { + if (f > edges[i - 1].channel && + edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) { + /* lower channel has the inband flag set */ + rc = edges[i - 1].power_flags & + ~AR9170_CALCTL_EDGE_FLAGS; + } + } + return rc; +} + +static u8 carl9170_get_heavy_clip(struct ar9170 *ar, u32 freq, + enum carl9170_bw bw, struct ar9170_calctl_edges edges[]) +{ + u8 f; + int i; + u8 rc = 0; + + if (freq < 3000) + f = freq - 2300; + else + f = (freq - 4800) / 5; + + if (bw == CARL9170_BW_40_BELOW || bw == CARL9170_BW_40_ABOVE) + rc |= 0xf0; + + for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) { + if (edges[i].channel == 0xff) + break; + if (f == edges[i].channel) { + if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS)) + rc |= 0x0f; + break; + } + } + + return rc; +} + +/* + * calculate the conformance test limits and the heavy clip parameter + * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706) + */ +static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) +{ + u8 ctl_grp; /* CTL group */ + u8 ctl_idx; /* CTL index */ + int i, j; + struct ctl_modes { + u8 ctl_mode; + u8 max_power; + u8 *pwr_cal_data; + int pwr_cal_len; + } *modes; + + /* + * order is relevant in the mode_list_*: we fall back to the + * lower indices if any mode is missed in the EEPROM. + */ + struct ctl_modes mode_list_2ghz[] = { + { CTL_11B, 0, ar->power_2G_cck, 4 }, + { CTL_11G, 0, ar->power_2G_ofdm, 4 }, + { CTL_2GHT20, 0, ar->power_2G_ht20, 8 }, + { CTL_2GHT40, 0, ar->power_2G_ht40, 8 }, + }; + struct ctl_modes mode_list_5ghz[] = { + { CTL_11A, 0, ar->power_5G_leg, 4 }, + { CTL_5GHT20, 0, ar->power_5G_ht20, 8 }, + { CTL_5GHT40, 0, ar->power_5G_ht40, 8 }, + }; + int nr_modes; + +#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n]) + + ar->heavy_clip = 0; + + /* + * TODO: investigate the differences between OTUS' + * hpreg.c::zfHpGetRegulatoryDomain() and + * ath/regd.c::ath_regd_get_band_ctl() - + * e.g. for FCC3_WORLD the OTUS procedure + * always returns CTL_FCC, while the one in ath/ delivers + * CTL_ETSI for 2GHz and CTL_FCC for 5GHz. + */ + ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory, + ar->hw->conf.channel->band); + + /* ctl group not found - either invalid band (NO_CTL) or ww roaming */ + if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL) + ctl_grp = CTL_FCC; + + if (ctl_grp != CTL_FCC) + /* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */ + return; + + if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) { + modes = mode_list_2ghz; + nr_modes = ARRAY_SIZE(mode_list_2ghz); + } else { + modes = mode_list_5ghz; + nr_modes = ARRAY_SIZE(mode_list_5ghz); + } + + for (i = 0; i < nr_modes; i++) { + u8 c = ctl_grp | modes[i].ctl_mode; + for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++) + if (c == ar->eeprom.ctl_index[ctl_idx]) + break; + if (ctl_idx < AR5416_NUM_CTLS) { + int f_off = 0; + + /* + * determine heavy clip parameter + * from the 11G edges array + */ + if (modes[i].ctl_mode == CTL_11G) { + ar->heavy_clip = + carl9170_get_heavy_clip(ar, + freq, bw, EDGES(ctl_idx, 1)); + } + + /* adjust freq for 40MHz */ + if (modes[i].ctl_mode == CTL_2GHT40 || + modes[i].ctl_mode == CTL_5GHT40) { + if (bw == CARL9170_BW_40_BELOW) + f_off = -10; + else + f_off = 10; + } + + modes[i].max_power = + carl9170_get_max_edge_power(ar, + freq+f_off, EDGES(ctl_idx, 1)); + + /* + * TODO: check if the regulatory max. power is + * controlled by cfg80211 for DFS. + * (hpmain applies it to max_power itself for DFS freq) + */ + + } else { + /* + * Workaround in otus driver, hpmain.c, line 3906: + * if no data for 5GHT20 are found, take the + * legacy 5G value. We extend this here to fallback + * from any other HT* or 11G, too. + */ + int k = i; + + modes[i].max_power = AR5416_MAX_RATE_POWER; + while (k-- > 0) { + if (modes[k].max_power != + AR5416_MAX_RATE_POWER) { + modes[i].max_power = modes[k].max_power; + break; + } + } + } + + /* apply max power to pwr_cal_data (ar->power_*) */ + for (j = 0; j < modes[i].pwr_cal_len; j++) { + modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j], + modes[i].max_power); + } + } + + if (ar->heavy_clip & 0xf0) { + ar->power_2G_ht40[0]--; + ar->power_2G_ht40[1]--; + ar->power_2G_ht40[2]--; + } + if (ar->heavy_clip & 0xf) { + ar->power_2G_ht20[0]++; + ar->power_2G_ht20[1]++; + ar->power_2G_ht20[2]++; + } + +#undef EDGES +} + +static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, + enum carl9170_bw bw) +{ + struct ar9170_calibration_target_power_legacy *ctpl; + struct ar9170_calibration_target_power_ht *ctph; + u8 *ctpres; + int ntargets; + int idx, i, n; + u8 ackpower, ackchains, f; + u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; + + if (freq < 3000) + f = freq - 2300; + else + f = (freq - 4800)/5; + + /* + * cycle through the various modes + * + * legacy modes first: 5G, 2G CCK, 2G OFDM + */ + for (i = 0; i < 3; i++) { + switch (i) { + case 0: /* 5 GHz legacy */ + ctpl = &ar->eeprom.cal_tgt_pwr_5G[0]; + ntargets = AR5416_NUM_5G_TARGET_PWRS; + ctpres = ar->power_5G_leg; + break; + case 1: /* 2.4 GHz CCK */ + ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0]; + ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS; + ctpres = ar->power_2G_cck; + break; + case 2: /* 2.4 GHz OFDM */ + ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0]; + ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; + ctpres = ar->power_2G_ofdm; + break; + default: + BUG(); + } + + for (n = 0; n < ntargets; n++) { + if (ctpl[n].freq == 0xff) + break; + pwr_freqs[n] = ctpl[n].freq; + } + ntargets = n; + idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f); + for (n = 0; n < 4; n++) + ctpres[n] = carl9170_interpolate_u8(f, + ctpl[idx + 0].freq, ctpl[idx + 0].power[n], + ctpl[idx + 1].freq, ctpl[idx + 1].power[n]); + } + + /* HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40 */ + for (i = 0; i < 4; i++) { + switch (i) { + case 0: /* 5 GHz HT 20 */ + ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0]; + ntargets = AR5416_NUM_5G_TARGET_PWRS; + ctpres = ar->power_5G_ht20; + break; + case 1: /* 5 GHz HT 40 */ + ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0]; + ntargets = AR5416_NUM_5G_TARGET_PWRS; + ctpres = ar->power_5G_ht40; + break; + case 2: /* 2.4 GHz HT 20 */ + ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0]; + ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; + ctpres = ar->power_2G_ht20; + break; + case 3: /* 2.4 GHz HT 40 */ + ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0]; + ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS; + ctpres = ar->power_2G_ht40; + break; + default: + BUG(); + } + + for (n = 0; n < ntargets; n++) { + if (ctph[n].freq == 0xff) + break; + pwr_freqs[n] = ctph[n].freq; + } + ntargets = n; + idx = carl9170_find_freq_idx(ntargets, pwr_freqs, f); + for (n = 0; n < 8; n++) + ctpres[n] = carl9170_interpolate_u8(f, + ctph[idx + 0].freq, ctph[idx + 0].power[n], + ctph[idx + 1].freq, ctph[idx + 1].power[n]); + } + + /* calc. conformance test limits and apply to ar->power*[] */ + carl9170_calc_ctl(ar, freq, bw); + + /* set ACK/CTS TX power */ + carl9170_regwrite_begin(ar); + + if (ar->eeprom.tx_mask != 1) + ackchains = AR9170_TX_PHY_TXCHAIN_2; + else + ackchains = AR9170_TX_PHY_TXCHAIN_1; + + if (freq < 3000) + ackpower = ar->power_2G_ofdm[0] & 0x3f; + else + ackpower = ar->power_5G_leg[0] & 0x3f; + + carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, + 0x3c1e | ackpower << 20 | ackchains << 26); + carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, + ackpower << 5 | ackchains << 11 | + ackpower << 21 | ackchains << 27); + + carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, + ackpower << 5 | ackchains << 11 | + ackpower << 21 | ackchains << 27); + + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} + +/* TODO: replace this with sign_extend32(noise, 8) */ +static int carl9170_calc_noise_dbm(u32 raw_noise) +{ + if (raw_noise & 0x100) + return ~0x1ff | raw_noise; + else + return raw_noise; +} + +int carl9170_get_noisefloor(struct ar9170 *ar) +{ + static const u32 phy_regs[] = { + AR9170_PHY_REG_CCA, AR9170_PHY_REG_CH2_CCA, + AR9170_PHY_REG_EXT_CCA, AR9170_PHY_REG_CH2_EXT_CCA }; + u32 phy_res[ARRAY_SIZE(phy_regs)]; + int err, i; + + BUILD_BUG_ON(ARRAY_SIZE(phy_regs) != ARRAY_SIZE(ar->noise)); + + err = carl9170_read_mreg(ar, ARRAY_SIZE(phy_regs), phy_regs, phy_res); + if (err) + return err; + + for (i = 0; i < 2; i++) { + ar->noise[i] = carl9170_calc_noise_dbm( + (phy_res[i] >> 19) & 0x1ff); + + ar->noise[i + 2] = carl9170_calc_noise_dbm( + (phy_res[i + 2] >> 23) & 0x1ff); + } + + return 0; +} + +static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type) +{ + switch (type) { + case NL80211_CHAN_NO_HT: + case NL80211_CHAN_HT20: + return CARL9170_BW_20; + case NL80211_CHAN_HT40MINUS: + return CARL9170_BW_40_BELOW; + case NL80211_CHAN_HT40PLUS: + return CARL9170_BW_40_ABOVE; + default: + BUG(); + } +} + +int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, + enum nl80211_channel_type _bw, + enum carl9170_rf_init_mode rfi) +{ + const struct carl9170_phy_freq_params *freqpar; + struct carl9170_rf_init_result rf_res; + struct carl9170_rf_init rf; + u32 cmd, tmp, offs = 0, new_ht = 0; + int err; + enum carl9170_bw bw; + bool warm_reset; + struct ieee80211_channel *old_channel = NULL; + + bw = nl80211_to_carl(_bw); + + if (conf_is_ht(&ar->hw->conf)) + new_ht |= CARL9170FW_PHY_HT_ENABLE; + + if (conf_is_ht40(&ar->hw->conf)) + new_ht |= CARL9170FW_PHY_HT_DYN2040; + + /* may be NULL at first setup */ + if (ar->channel) { + old_channel = ar->channel; + warm_reset = (old_channel->band != channel->band) || + (old_channel->center_freq == + channel->center_freq) || + (ar->ht_settings != new_ht); + + ar->channel = NULL; + } else { + warm_reset = true; + } + + /* HW workaround */ + if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] && + channel->center_freq <= 2417) + warm_reset = true; + + if (rfi != CARL9170_RFI_NONE || warm_reset) { + u32 val; + + if (rfi == CARL9170_RFI_COLD) + val = AR9170_PWR_RESET_BB_COLD_RESET; + else + val = AR9170_PWR_RESET_BB_WARM_RESET; + + /* warm/cold reset BB/ADDA */ + err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, val); + if (err) + return err; + + err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0); + if (err) + return err; + + err = carl9170_init_phy(ar, channel->band); + if (err) + return err; + + err = carl9170_init_rf_banks_0_7(ar, + channel->band == IEEE80211_BAND_5GHZ); + if (err) + return err; + + cmd = CARL9170_CMD_RF_INIT; + + msleep(100); + + err = carl9170_echo_test(ar, 0xaabbccdd); + if (err) + return err; + } else { + cmd = CARL9170_CMD_FREQUENCY; + } + + err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL); + if (err) + return err; + + err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE, + 0x200); + + err = carl9170_init_rf_bank4_pwr(ar, + channel->band == IEEE80211_BAND_5GHZ, + channel->center_freq, bw); + if (err) + return err; + + tmp = AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 | + AR9170_PHY_TURBO_FC_HT_EN; + + switch (bw) { + case CARL9170_BW_20: + break; + case CARL9170_BW_40_BELOW: + tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN | + AR9170_PHY_TURBO_FC_SHORT_GI_40; + offs = 3; + break; + case CARL9170_BW_40_ABOVE: + tmp |= AR9170_PHY_TURBO_FC_DYN2040_EN | + AR9170_PHY_TURBO_FC_SHORT_GI_40 | + AR9170_PHY_TURBO_FC_DYN2040_PRI_CH; + offs = 1; + break; + default: + BUG(); + return -ENOSYS; + } + + if (ar->eeprom.tx_mask != 1) + tmp |= AR9170_PHY_TURBO_FC_WALSH; + + err = carl9170_write_reg(ar, AR9170_PHY_REG_TURBO, tmp); + if (err) + return err; + + err = carl9170_set_freq_cal_data(ar, channel); + if (err) + return err; + + err = carl9170_set_power_cal(ar, channel->center_freq, bw); + if (err) + return err; + + freqpar = carl9170_get_hw_dyn_params(channel, bw); + + rf.ht_settings = new_ht; + if (conf_is_ht40(&ar->hw->conf)) + SET_VAL(CARL9170FW_PHY_HT_EXT_CHAN_OFF, rf.ht_settings, offs); + + rf.freq = cpu_to_le32(channel->center_freq * 1000); + rf.delta_slope_coeff_exp = cpu_to_le32(freqpar->coeff_exp); + rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man); + rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi); + rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi); + + if (rfi != CARL9170_RFI_NONE) + rf.finiteLoopCount = cpu_to_le32(2000); + else + rf.finiteLoopCount = cpu_to_le32(1000); + + err = carl9170_exec_cmd(ar, cmd, sizeof(rf), &rf, + sizeof(rf_res), &rf_res); + if (err) + return err; + + err = le32_to_cpu(rf_res.ret); + if (err != 0) { + ar->chan_fail++; + ar->total_chan_fail++; + + wiphy_err(ar->hw->wiphy, "channel change: %d -> %d " + "failed (%d).\n", old_channel ? + old_channel->center_freq : -1, channel->center_freq, + err); + + if ((rfi == CARL9170_RFI_COLD) || (ar->chan_fail > 3)) { + /* + * We have tried very hard to change to _another_ + * channel and we've failed to do so! + * Chances are that the PHY/RF is no longer + * operable (due to corruptions/fatal events/bugs?) + * and we need to reset at a higher level. + */ + carl9170_restart(ar, CARL9170_RR_TOO_MANY_PHY_ERRORS); + return 0; + } + + err = carl9170_set_channel(ar, channel, _bw, + CARL9170_RFI_COLD); + if (err) + return err; + } else { + ar->chan_fail = 0; + } + + err = carl9170_get_noisefloor(ar); + if (err) + return err; + + if (ar->heavy_clip) { + err = carl9170_write_reg(ar, AR9170_PHY_REG_HEAVY_CLIP_ENABLE, + 0x200 | ar->heavy_clip); + if (err) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "failed to set " + "heavy clip\n"); + } + + return err; + } + } + + /* FIXME: PSM does not work in 5GHz Band */ + if (channel->band == IEEE80211_BAND_5GHZ) + ar->ps.off_override |= PS_OFF_5GHZ; + else + ar->ps.off_override &= ~PS_OFF_5GHZ; + + ar->channel = channel; + ar->ht_settings = new_ht; + return 0; +} diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h new file mode 100644 index 0000000000000000000000000000000000000000..02c34eb4ebdec5fe64eb0730e24e89393c8f800f --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/phy.h @@ -0,0 +1,564 @@ +/* + * Shared Atheros AR9170 Header + * + * PHY register map + * + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CARL9170_SHARED_PHY_H +#define __CARL9170_SHARED_PHY_H + +#define AR9170_PHY_REG_BASE (0x1bc000 + 0x9800) +#define AR9170_PHY_REG(_n) (AR9170_PHY_REG_BASE + \ + ((_n) << 2)) + +#define AR9170_PHY_REG_TEST (AR9170_PHY_REG_BASE + 0x0000) +#define AR9170_PHY_TEST_AGC_CLR 0x10000000 +#define AR9170_PHY_TEST_RFSILENT_BB 0x00002000 + +#define AR9170_PHY_REG_TURBO (AR9170_PHY_REG_BASE + 0x0004) +#define AR9170_PHY_TURBO_FC_TURBO_MODE 0x00000001 +#define AR9170_PHY_TURBO_FC_TURBO_SHORT 0x00000002 +#define AR9170_PHY_TURBO_FC_DYN2040_EN 0x00000004 +#define AR9170_PHY_TURBO_FC_DYN2040_PRI_ONLY 0x00000008 +#define AR9170_PHY_TURBO_FC_DYN2040_PRI_CH 0x00000010 +/* For 25 MHz channel spacing -- not used but supported by hw */ +#define AR9170_PHY_TURBO_FC_DYN2040_EXT_CH 0x00000020 +#define AR9170_PHY_TURBO_FC_HT_EN 0x00000040 +#define AR9170_PHY_TURBO_FC_SHORT_GI_40 0x00000080 +#define AR9170_PHY_TURBO_FC_WALSH 0x00000100 +#define AR9170_PHY_TURBO_FC_SINGLE_HT_LTF1 0x00000200 +#define AR9170_PHY_TURBO_FC_ENABLE_DAC_FIFO 0x00000800 + +#define AR9170_PHY_REG_TEST2 (AR9170_PHY_REG_BASE + 0x0008) + +#define AR9170_PHY_REG_TIMING2 (AR9170_PHY_REG_BASE + 0x0010) +#define AR9170_PHY_TIMING2_USE_FORCE 0x00001000 +#define AR9170_PHY_TIMING2_FORCE 0x00000fff +#define AR9170_PHY_TIMING2_FORCE_S 0 + +#define AR9170_PHY_REG_TIMING3 (AR9170_PHY_REG_BASE + 0x0014) +#define AR9170_PHY_TIMING3_DSC_EXP 0x0001e000 +#define AR9170_PHY_TIMING3_DSC_EXP_S 13 +#define AR9170_PHY_TIMING3_DSC_MAN 0xfffe0000 +#define AR9170_PHY_TIMING3_DSC_MAN_S 17 + +#define AR9170_PHY_REG_CHIP_ID (AR9170_PHY_REG_BASE + 0x0018) +#define AR9170_PHY_CHIP_ID_REV_0 0x80 +#define AR9170_PHY_CHIP_ID_REV_1 0x81 +#define AR9170_PHY_CHIP_ID_9160_REV_0 0xb0 + +#define AR9170_PHY_REG_ACTIVE (AR9170_PHY_REG_BASE + 0x001c) +#define AR9170_PHY_ACTIVE_EN 0x00000001 +#define AR9170_PHY_ACTIVE_DIS 0x00000000 + +#define AR9170_PHY_REG_RF_CTL2 (AR9170_PHY_REG_BASE + 0x0024) +#define AR9170_PHY_RF_CTL2_TX_END_DATA_START 0x000000ff +#define AR9170_PHY_RF_CTL2_TX_END_DATA_START_S 0 +#define AR9170_PHY_RF_CTL2_TX_END_PA_ON 0x0000ff00 +#define AR9170_PHY_RF_CTL2_TX_END_PA_ON_S 8 + +#define AR9170_PHY_REG_RF_CTL3 (AR9170_PHY_REG_BASE + 0x0028) +#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON 0x00ff0000 +#define AR9170_PHY_RF_CTL3_TX_END_TO_A2_RX_ON_S 16 + +#define AR9170_PHY_REG_ADC_CTL (AR9170_PHY_REG_BASE + 0x002c) +#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 +#define AR9170_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 +#define AR9170_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 +#define AR9170_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 +#define AR9170_PHY_ADC_CTL_OFF_PWDADC 0x00008000 +#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000 +#define AR9170_PHY_ADC_CTL_ON_INBUFGAIN_S 16 + +#define AR9170_PHY_REG_ADC_SERIAL_CTL (AR9170_PHY_REG_BASE + 0x0030) +#define AR9170_PHY_ADC_SCTL_SEL_INTERNAL_ADDAC 0x00000000 +#define AR9170_PHY_ADC_SCTL_SEL_EXTERNAL_RADIO 0x00000001 + +#define AR9170_PHY_REG_RF_CTL4 (AR9170_PHY_REG_BASE + 0x0034) +#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF 0xff000000 +#define AR9170_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 +#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00ff0000 +#define AR9170_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 +#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000ff00 +#define AR9170_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 +#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000ff +#define AR9170_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 + +#define AR9170_PHY_REG_TSTDAC_CONST (AR9170_PHY_REG_BASE + 0x003c) + +#define AR9170_PHY_REG_SETTLING (AR9170_PHY_REG_BASE + 0x0044) +#define AR9170_PHY_SETTLING_SWITCH 0x00003f80 +#define AR9170_PHY_SETTLING_SWITCH_S 7 + +#define AR9170_PHY_REG_RXGAIN (AR9170_PHY_REG_BASE + 0x0048) +#define AR9170_PHY_REG_RXGAIN_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2048) +#define AR9170_PHY_RXGAIN_TXRX_ATTEN 0x0003f000 +#define AR9170_PHY_RXGAIN_TXRX_ATTEN_S 12 +#define AR9170_PHY_RXGAIN_TXRX_RF_MAX 0x007c0000 +#define AR9170_PHY_RXGAIN_TXRX_RF_MAX_S 18 + +#define AR9170_PHY_REG_DESIRED_SZ (AR9170_PHY_REG_BASE + 0x0050) +#define AR9170_PHY_DESIRED_SZ_ADC 0x000000ff +#define AR9170_PHY_DESIRED_SZ_ADC_S 0 +#define AR9170_PHY_DESIRED_SZ_PGA 0x0000ff00 +#define AR9170_PHY_DESIRED_SZ_PGA_S 8 +#define AR9170_PHY_DESIRED_SZ_TOT_DES 0x0ff00000 +#define AR9170_PHY_DESIRED_SZ_TOT_DES_S 20 + +#define AR9170_PHY_REG_FIND_SIG (AR9170_PHY_REG_BASE + 0x0058) +#define AR9170_PHY_FIND_SIG_FIRSTEP 0x0003f000 +#define AR9170_PHY_FIND_SIG_FIRSTEP_S 12 +#define AR9170_PHY_FIND_SIG_FIRPWR 0x03fc0000 +#define AR9170_PHY_FIND_SIG_FIRPWR_S 18 + +#define AR9170_PHY_REG_AGC_CTL1 (AR9170_PHY_REG_BASE + 0x005c) +#define AR9170_PHY_AGC_CTL1_COARSE_LOW 0x00007f80 +#define AR9170_PHY_AGC_CTL1_COARSE_LOW_S 7 +#define AR9170_PHY_AGC_CTL1_COARSE_HIGH 0x003f8000 +#define AR9170_PHY_AGC_CTL1_COARSE_HIGH_S 15 + +#define AR9170_PHY_REG_AGC_CONTROL (AR9170_PHY_REG_BASE + 0x0060) +#define AR9170_PHY_AGC_CONTROL_CAL 0x00000001 +#define AR9170_PHY_AGC_CONTROL_NF 0x00000002 +#define AR9170_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 +#define AR9170_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 +#define AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 + +#define AR9170_PHY_REG_CCA (AR9170_PHY_REG_BASE + 0x0064) +#define AR9170_PHY_CCA_MINCCA_PWR 0x0ff80000 +#define AR9170_PHY_CCA_MINCCA_PWR_S 19 +#define AR9170_PHY_CCA_THRESH62 0x0007f000 +#define AR9170_PHY_CCA_THRESH62_S 12 + +#define AR9170_PHY_REG_SFCORR (AR9170_PHY_REG_BASE + 0x0068) +#define AR9170_PHY_SFCORR_M2COUNT_THR 0x0000001f +#define AR9170_PHY_SFCORR_M2COUNT_THR_S 0 +#define AR9170_PHY_SFCORR_M1_THRESH 0x00fe0000 +#define AR9170_PHY_SFCORR_M1_THRESH_S 17 +#define AR9170_PHY_SFCORR_M2_THRESH 0x7f000000 +#define AR9170_PHY_SFCORR_M2_THRESH_S 24 + +#define AR9170_PHY_REG_SFCORR_LOW (AR9170_PHY_REG_BASE + 0x006c) +#define AR9170_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 +#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003f00 +#define AR9170_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 +#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001fc000 +#define AR9170_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 +#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0fe00000 +#define AR9170_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 + +#define AR9170_PHY_REG_SLEEP_CTR_CONTROL (AR9170_PHY_REG_BASE + 0x0070) +#define AR9170_PHY_REG_SLEEP_CTR_LIMIT (AR9170_PHY_REG_BASE + 0x0074) +#define AR9170_PHY_REG_SLEEP_SCAL (AR9170_PHY_REG_BASE + 0x0078) + +#define AR9170_PHY_REG_PLL_CTL (AR9170_PHY_REG_BASE + 0x007c) +#define AR9170_PHY_PLL_CTL_40 0xaa +#define AR9170_PHY_PLL_CTL_40_5413 0x04 +#define AR9170_PHY_PLL_CTL_44 0xab +#define AR9170_PHY_PLL_CTL_44_2133 0xeb +#define AR9170_PHY_PLL_CTL_40_2133 0xea + +#define AR9170_PHY_REG_BIN_MASK_1 (AR9170_PHY_REG_BASE + 0x0100) +#define AR9170_PHY_REG_BIN_MASK_2 (AR9170_PHY_REG_BASE + 0x0104) +#define AR9170_PHY_REG_BIN_MASK_3 (AR9170_PHY_REG_BASE + 0x0108) +#define AR9170_PHY_REG_MASK_CTL (AR9170_PHY_REG_BASE + 0x010c) + +/* analogue power on time (100ns) */ +#define AR9170_PHY_REG_RX_DELAY (AR9170_PHY_REG_BASE + 0x0114) +#define AR9170_PHY_REG_SEARCH_START_DELAY (AR9170_PHY_REG_BASE + 0x0118) +#define AR9170_PHY_RX_DELAY_DELAY 0x00003fff + +#define AR9170_PHY_REG_TIMING_CTRL4(_i) (AR9170_PHY_REG_BASE + \ + (0x0120 + ((_i) << 12))) +#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01f +#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 +#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7e0 +#define AR9170_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 +#define AR9170_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800 +#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xf000 +#define AR9170_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 +#define AR9170_PHY_TIMING_CTRL4_DO_IQCAL 0x10000 +#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000 +#define AR9170_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000 +#define AR9170_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000 +#define AR9170_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000 + +#define AR9170_PHY_REG_TIMING5 (AR9170_PHY_REG_BASE + 0x0124) +#define AR9170_PHY_TIMING5_CYCPWR_THR1 0x000000fe +#define AR9170_PHY_TIMING5_CYCPWR_THR1_S 1 + +#define AR9170_PHY_REG_POWER_TX_RATE1 (AR9170_PHY_REG_BASE + 0x0134) +#define AR9170_PHY_REG_POWER_TX_RATE2 (AR9170_PHY_REG_BASE + 0x0138) +#define AR9170_PHY_REG_POWER_TX_RATE_MAX (AR9170_PHY_REG_BASE + 0x013c) +#define AR9170_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 + +#define AR9170_PHY_REG_FRAME_CTL (AR9170_PHY_REG_BASE + 0x0144) +#define AR9170_PHY_FRAME_CTL_TX_CLIP 0x00000038 +#define AR9170_PHY_FRAME_CTL_TX_CLIP_S 3 + +#define AR9170_PHY_REG_SPUR_REG (AR9170_PHY_REG_BASE + 0x014c) +#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL (0xff << 18) +#define AR9170_PHY_SPUR_REG_MASK_RATE_CNTL_S 18 +#define AR9170_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 +#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT (0xff << 9) +#define AR9170_PHY_SPUR_REG_MASK_RATE_SELECT_S 9 +#define AR9170_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100 +#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7f +#define AR9170_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 + +#define AR9170_PHY_REG_RADAR_EXT (AR9170_PHY_REG_BASE + 0x0140) +#define AR9170_PHY_RADAR_EXT_ENA 0x00004000 + +#define AR9170_PHY_REG_RADAR_0 (AR9170_PHY_REG_BASE + 0x0154) +#define AR9170_PHY_RADAR_0_ENA 0x00000001 +#define AR9170_PHY_RADAR_0_FFT_ENA 0x80000000 +/* inband pulse threshold */ +#define AR9170_PHY_RADAR_0_INBAND 0x0000003e +#define AR9170_PHY_RADAR_0_INBAND_S 1 +/* pulse RSSI threshold */ +#define AR9170_PHY_RADAR_0_PRSSI 0x00000fc0 +#define AR9170_PHY_RADAR_0_PRSSI_S 6 +/* pulse height threshold */ +#define AR9170_PHY_RADAR_0_HEIGHT 0x0003f000 +#define AR9170_PHY_RADAR_0_HEIGHT_S 12 +/* radar RSSI threshold */ +#define AR9170_PHY_RADAR_0_RRSSI 0x00fc0000 +#define AR9170_PHY_RADAR_0_RRSSI_S 18 +/* radar firepower threshold */ +#define AR9170_PHY_RADAR_0_FIRPWR 0x7f000000 +#define AR9170_PHY_RADAR_0_FIRPWR_S 24 + +#define AR9170_PHY_REG_RADAR_1 (AR9170_PHY_REG_BASE + 0x0158) +#define AR9170_PHY_RADAR_1_RELPWR_ENA 0x00800000 +#define AR9170_PHY_RADAR_1_USE_FIR128 0x00400000 +#define AR9170_PHY_RADAR_1_RELPWR_THRESH 0x003f0000 +#define AR9170_PHY_RADAR_1_RELPWR_THRESH_S 16 +#define AR9170_PHY_RADAR_1_BLOCK_CHECK 0x00008000 +#define AR9170_PHY_RADAR_1_MAX_RRSSI 0x00004000 +#define AR9170_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 +#define AR9170_PHY_RADAR_1_RELSTEP_THRESH 0x00001f00 +#define AR9170_PHY_RADAR_1_RELSTEP_THRESH_S 8 +#define AR9170_PHY_RADAR_1_MAXLEN 0x000000ff +#define AR9170_PHY_RADAR_1_MAXLEN_S 0 + +#define AR9170_PHY_REG_SWITCH_CHAIN_0 (AR9170_PHY_REG_BASE + 0x0160) +#define AR9170_PHY_REG_SWITCH_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2160) + +#define AR9170_PHY_REG_SWITCH_COM (AR9170_PHY_REG_BASE + 0x0164) + +#define AR9170_PHY_REG_CCA_THRESHOLD (AR9170_PHY_REG_BASE + 0x0168) + +#define AR9170_PHY_REG_SIGMA_DELTA (AR9170_PHY_REG_BASE + 0x016c) +#define AR9170_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 +#define AR9170_PHY_SIGMA_DELTA_ADC_SEL_S 0 +#define AR9170_PHY_SIGMA_DELTA_FILT2 0x000000f8 +#define AR9170_PHY_SIGMA_DELTA_FILT2_S 3 +#define AR9170_PHY_SIGMA_DELTA_FILT1 0x00001f00 +#define AR9170_PHY_SIGMA_DELTA_FILT1_S 8 +#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP 0x01ffe000 +#define AR9170_PHY_SIGMA_DELTA_ADC_CLIP_S 13 + +#define AR9170_PHY_REG_RESTART (AR9170_PHY_REG_BASE + 0x0170) +#define AR9170_PHY_RESTART_DIV_GC 0x001c0000 +#define AR9170_PHY_RESTART_DIV_GC_S 18 + +#define AR9170_PHY_REG_RFBUS_REQ (AR9170_PHY_REG_BASE + 0x017c) +#define AR9170_PHY_RFBUS_REQ_EN 0x00000001 + +#define AR9170_PHY_REG_TIMING7 (AR9170_PHY_REG_BASE + 0x0180) +#define AR9170_PHY_REG_TIMING8 (AR9170_PHY_REG_BASE + 0x0184) +#define AR9170_PHY_TIMING8_PILOT_MASK_2 0x000fffff +#define AR9170_PHY_TIMING8_PILOT_MASK_2_S 0 + +#define AR9170_PHY_REG_BIN_MASK2_1 (AR9170_PHY_REG_BASE + 0x0188) +#define AR9170_PHY_REG_BIN_MASK2_2 (AR9170_PHY_REG_BASE + 0x018c) +#define AR9170_PHY_REG_BIN_MASK2_3 (AR9170_PHY_REG_BASE + 0x0190) +#define AR9170_PHY_REG_BIN_MASK2_4 (AR9170_PHY_REG_BASE + 0x0194) +#define AR9170_PHY_BIN_MASK2_4_MASK_4 0x00003fff +#define AR9170_PHY_BIN_MASK2_4_MASK_4_S 0 + +#define AR9170_PHY_REG_TIMING9 (AR9170_PHY_REG_BASE + 0x0198) +#define AR9170_PHY_REG_TIMING10 (AR9170_PHY_REG_BASE + 0x019c) +#define AR9170_PHY_TIMING10_PILOT_MASK_2 0x000fffff +#define AR9170_PHY_TIMING10_PILOT_MASK_2_S 0 + +#define AR9170_PHY_REG_TIMING11 (AR9170_PHY_REG_BASE + 0x01a0) +#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE 0x000fffff +#define AR9170_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 +#define AR9170_PHY_TIMING11_SPUR_FREQ_SD 0x3ff00000 +#define AR9170_PHY_TIMING11_SPUR_FREQ_SD_S 20 +#define AR9170_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000 +#define AR9170_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000 + +#define AR9170_PHY_REG_RX_CHAINMASK (AR9170_PHY_REG_BASE + 0x01a4) +#define AR9170_PHY_REG_NEW_ADC_DC_GAIN_CORR(_i) (AR9170_PHY_REG_BASE + \ + 0x01b4 + ((_i) << 12)) +#define AR9170_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 +#define AR9170_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 + +#define AR9170_PHY_REG_MULTICHAIN_GAIN_CTL (AR9170_PHY_REG_BASE + 0x01ac) +#define AR9170_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000 +#define AR9170_PHY_9285_ANT_DIV_CTL 0x01000000 +#define AR9170_PHY_9285_ANT_DIV_CTL_S 24 +#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000 +#define AR9170_PHY_9285_ANT_DIV_ALT_LNACONF_S 25 +#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000 +#define AR9170_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27 +#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000 +#define AR9170_PHY_9285_ANT_DIV_ALT_GAINTB_S 29 +#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000 +#define AR9170_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30 +#define AR9170_PHY_9285_ANT_DIV_LNA1 2 +#define AR9170_PHY_9285_ANT_DIV_LNA2 1 +#define AR9170_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3 +#define AR9170_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0 +#define AR9170_PHY_9285_ANT_DIV_GAINTB_0 0 +#define AR9170_PHY_9285_ANT_DIV_GAINTB_1 1 + +#define AR9170_PHY_REG_EXT_CCA0 (AR9170_PHY_REG_BASE + 0x01b8) +#define AR9170_PHY_REG_EXT_CCA0_THRESH62 0x000000ff +#define AR9170_PHY_REG_EXT_CCA0_THRESH62_S 0 + +#define AR9170_PHY_REG_EXT_CCA (AR9170_PHY_REG_BASE + 0x01bc) +#define AR9170_PHY_EXT_CCA_CYCPWR_THR1 0x0000fe00 +#define AR9170_PHY_EXT_CCA_CYCPWR_THR1_S 9 +#define AR9170_PHY_EXT_CCA_THRESH62 0x007f0000 +#define AR9170_PHY_EXT_CCA_THRESH62_S 16 +#define AR9170_PHY_EXT_MINCCA_PWR 0xff800000 +#define AR9170_PHY_EXT_MINCCA_PWR_S 23 + +#define AR9170_PHY_REG_SFCORR_EXT (AR9170_PHY_REG_BASE + 0x01c0) +#define AR9170_PHY_SFCORR_EXT_M1_THRESH 0x0000007f +#define AR9170_PHY_SFCORR_EXT_M1_THRESH_S 0 +#define AR9170_PHY_SFCORR_EXT_M2_THRESH 0x00003f80 +#define AR9170_PHY_SFCORR_EXT_M2_THRESH_S 7 +#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001fc000 +#define AR9170_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 +#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0fe00000 +#define AR9170_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 +#define AR9170_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 + +#define AR9170_PHY_REG_HALFGI (AR9170_PHY_REG_BASE + 0x01d0) +#define AR9170_PHY_HALFGI_DSC_MAN 0x0007fff0 +#define AR9170_PHY_HALFGI_DSC_MAN_S 4 +#define AR9170_PHY_HALFGI_DSC_EXP 0x0000000f +#define AR9170_PHY_HALFGI_DSC_EXP_S 0 + +#define AR9170_PHY_REG_CHANNEL_MASK_01_30 (AR9170_PHY_REG_BASE + 0x01d4) +#define AR9170_PHY_REG_CHANNEL_MASK_31_60 (AR9170_PHY_REG_BASE + 0x01d8) + +#define AR9170_PHY_REG_CHAN_INFO_MEMORY (AR9170_PHY_REG_BASE + 0x01dc) +#define AR9170_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 + +#define AR9170_PHY_REG_HEAVY_CLIP_ENABLE (AR9170_PHY_REG_BASE + 0x01e0) +#define AR9170_PHY_REG_HEAVY_CLIP_FACTOR_RIFS (AR9170_PHY_REG_BASE + 0x01ec) +#define AR9170_PHY_RIFS_INIT_DELAY 0x03ff0000 + +#define AR9170_PHY_REG_CALMODE (AR9170_PHY_REG_BASE + 0x01f0) +#define AR9170_PHY_CALMODE_IQ 0x00000000 +#define AR9170_PHY_CALMODE_ADC_GAIN 0x00000001 +#define AR9170_PHY_CALMODE_ADC_DC_PER 0x00000002 +#define AR9170_PHY_CALMODE_ADC_DC_INIT 0x00000003 + +#define AR9170_PHY_REG_REFCLKDLY (AR9170_PHY_REG_BASE + 0x01f4) +#define AR9170_PHY_REG_REFCLKPD (AR9170_PHY_REG_BASE + 0x01f8) + + +#define AR9170_PHY_REG_CAL_MEAS_0(_i) (AR9170_PHY_REG_BASE + \ + 0x0410 + ((_i) << 12)) +#define AR9170_PHY_REG_CAL_MEAS_1(_i) (AR9170_PHY_REG_BASE + \ + 0x0414 \ + ((_i) << 12)) +#define AR9170_PHY_REG_CAL_MEAS_2(_i) (AR9170_PHY_REG_BASE + \ + 0x0418 + ((_i) << 12)) +#define AR9170_PHY_REG_CAL_MEAS_3(_i) (AR9170_PHY_REG_BASE + \ + 0x041c + ((_i) << 12)) + +#define AR9170_PHY_REG_CURRENT_RSSI (AR9170_PHY_REG_BASE + 0x041c) + +#define AR9170_PHY_REG_RFBUS_GRANT (AR9170_PHY_REG_BASE + 0x0420) +#define AR9170_PHY_RFBUS_GRANT_EN 0x00000001 + +#define AR9170_PHY_REG_CHAN_INFO_GAIN_DIFF (AR9170_PHY_REG_BASE + 0x04f4) +#define AR9170_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 + +#define AR9170_PHY_REG_CHAN_INFO_GAIN (AR9170_PHY_REG_BASE + 0x04fc) + +#define AR9170_PHY_REG_MODE (AR9170_PHY_REG_BASE + 0x0a00) +#define AR9170_PHY_MODE_ASYNCFIFO 0x80 +#define AR9170_PHY_MODE_AR2133 0x08 +#define AR9170_PHY_MODE_AR5111 0x00 +#define AR9170_PHY_MODE_AR5112 0x08 +#define AR9170_PHY_MODE_DYNAMIC 0x04 +#define AR9170_PHY_MODE_RF2GHZ 0x02 +#define AR9170_PHY_MODE_RF5GHZ 0x00 +#define AR9170_PHY_MODE_CCK 0x01 +#define AR9170_PHY_MODE_OFDM 0x00 +#define AR9170_PHY_MODE_DYN_CCK_DISABLE 0x100 + +#define AR9170_PHY_REG_CCK_TX_CTRL (AR9170_PHY_REG_BASE + 0x0a04) +#define AR9170_PHY_CCK_TX_CTRL_JAPAN 0x00000010 +#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000c +#define AR9170_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2 + +#define AR9170_PHY_REG_CCK_DETECT (AR9170_PHY_REG_BASE + 0x0a08) +#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003f +#define AR9170_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 +/* [12:6] settling time for antenna switch */ +#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001fc0 +#define AR9170_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 +#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 +#define AR9170_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 + +#define AR9170_PHY_REG_GAIN_2GHZ (AR9170_PHY_REG_BASE + 0x0a0c) +#define AR9170_PHY_REG_GAIN_2GHZ_CHAIN_2 (AR9170_PHY_REG_BASE + 0x2a0c) +#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00fc0000 +#define AR9170_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 +#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003c00 +#define AR9170_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 +#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001f +#define AR9170_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 +#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003e0000 +#define AR9170_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17 +#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001f000 +#define AR9170_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12 +#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000fc0 +#define AR9170_PHY_GAIN_2GHZ_XATTEN2_DB_S 6 +#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003f +#define AR9170_PHY_GAIN_2GHZ_XATTEN1_DB_S 0 + +#define AR9170_PHY_REG_CCK_RXCTRL4 (AR9170_PHY_REG_BASE + 0x0a1c) +#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01f80000 +#define AR9170_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 + +#define AR9170_PHY_REG_DAG_CTRLCCK (AR9170_PHY_REG_BASE + 0x0a28) +#define AR9170_REG_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 +#define AR9170_REG_DAG_CTRLCCK_RSSI_THR 0x0001fc00 +#define AR9170_REG_DAG_CTRLCCK_RSSI_THR_S 10 + +#define AR9170_PHY_REG_FORCE_CLKEN_CCK (AR9170_PHY_REG_BASE + 0x0a2c) +#define AR9170_FORCE_CLKEN_CCK_MRC_MUX 0x00000040 + +#define AR9170_PHY_REG_POWER_TX_RATE3 (AR9170_PHY_REG_BASE + 0x0a34) +#define AR9170_PHY_REG_POWER_TX_RATE4 (AR9170_PHY_REG_BASE + 0x0a38) + +#define AR9170_PHY_REG_SCRM_SEQ_XR (AR9170_PHY_REG_BASE + 0x0a3c) +#define AR9170_PHY_REG_HEADER_DETECT_XR (AR9170_PHY_REG_BASE + 0x0a40) +#define AR9170_PHY_REG_CHIRP_DETECTED_XR (AR9170_PHY_REG_BASE + 0x0a44) +#define AR9170_PHY_REG_BLUETOOTH (AR9170_PHY_REG_BASE + 0x0a54) + +#define AR9170_PHY_REG_TPCRG1 (AR9170_PHY_REG_BASE + 0x0a58) +#define AR9170_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 +#define AR9170_PHY_TPCRG1_NUM_PD_GAIN_S 14 +#define AR9170_PHY_TPCRG1_PD_GAIN_1 0x00030000 +#define AR9170_PHY_TPCRG1_PD_GAIN_1_S 16 +#define AR9170_PHY_TPCRG1_PD_GAIN_2 0x000c0000 +#define AR9170_PHY_TPCRG1_PD_GAIN_2_S 18 +#define AR9170_PHY_TPCRG1_PD_GAIN_3 0x00300000 +#define AR9170_PHY_TPCRG1_PD_GAIN_3_S 20 +#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 +#define AR9170_PHY_TPCRG1_PD_CAL_ENABLE_S 22 + +#define AR9170_PHY_REG_TX_PWRCTRL4 (AR9170_PHY_REG_BASE + 0x0a64) +#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 +#define AR9170_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0 +#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001fe +#define AR9170_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1 + +#define AR9170_PHY_REG_ANALOG_SWAP (AR9170_PHY_REG_BASE + 0x0a68) +#define AR9170_PHY_ANALOG_SWAP_AB 0x0001 +#define AR9170_PHY_ANALOG_SWAP_ALT_CHAIN 0x00000040 + +#define AR9170_PHY_REG_TPCRG5 (AR9170_PHY_REG_BASE + 0x0a6c) +#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000f +#define AR9170_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003f0 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000fc00 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003f0000 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0fc00000 +#define AR9170_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 + +#define AR9170_PHY_REG_TX_PWRCTRL6_0 (AR9170_PHY_REG_BASE + 0x0a70) +#define AR9170_PHY_REG_TX_PWRCTRL6_1 (AR9170_PHY_REG_BASE + 0x1a70) +#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000 +#define AR9170_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 + +#define AR9170_PHY_REG_TX_PWRCTRL7 (AR9170_PHY_REG_BASE + 0x0a74) +#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01f80000 +#define AR9170_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 + +#define AR9170_PHY_REG_TX_PWRCTRL9 (AR9170_PHY_REG_BASE + 0x0a7c) +#define AR9170_PHY_TX_DESIRED_SCALE_CCK 0x00007c00 +#define AR9170_PHY_TX_DESIRED_SCALE_CCK_S 10 +#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 +#define AR9170_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31 + +#define AR9170_PHY_REG_TX_GAIN_TBL1 (AR9170_PHY_REG_BASE + 0x0b00) +#define AR9170_PHY_TX_GAIN 0x0007f000 +#define AR9170_PHY_TX_GAIN_S 12 + +/* Carrier leak calibration control, do it after AGC calibration */ +#define AR9170_PHY_REG_CL_CAL_CTL (AR9170_PHY_REG_BASE + 0x0b58) +#define AR9170_PHY_CL_CAL_ENABLE 0x00000002 +#define AR9170_PHY_CL_CAL_PARALLEL_CAL_ENABLE 0x00000001 + +#define AR9170_PHY_REG_POWER_TX_RATE5 (AR9170_PHY_REG_BASE + 0x0b8c) +#define AR9170_PHY_REG_POWER_TX_RATE6 (AR9170_PHY_REG_BASE + 0x0b90) + +#define AR9170_PHY_REG_CH0_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x0b98) +#define AR9170_PHY_REG_CH1_TX_PWRCTRL11 (AR9170_PHY_REG_BASE + 0x1b98) +#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP 0x0000fc00 +#define AR9170_PHY_TX_CHX_PWRCTRL_OLPC_TEMP_COMP_S 10 + +#define AR9170_PHY_REG_CAL_CHAINMASK (AR9170_PHY_REG_BASE + 0x0b9c) +#define AR9170_PHY_REG_VIT_MASK2_M_46_61 (AR9170_PHY_REG_BASE + 0x0ba0) +#define AR9170_PHY_REG_MASK2_M_31_45 (AR9170_PHY_REG_BASE + 0x0ba4) +#define AR9170_PHY_REG_MASK2_M_16_30 (AR9170_PHY_REG_BASE + 0x0ba8) +#define AR9170_PHY_REG_MASK2_M_00_15 (AR9170_PHY_REG_BASE + 0x0bac) +#define AR9170_PHY_REG_PILOT_MASK_01_30 (AR9170_PHY_REG_BASE + 0x0bb0) +#define AR9170_PHY_REG_PILOT_MASK_31_60 (AR9170_PHY_REG_BASE + 0x0bb4) +#define AR9170_PHY_REG_MASK2_P_15_01 (AR9170_PHY_REG_BASE + 0x0bb8) +#define AR9170_PHY_REG_MASK2_P_30_16 (AR9170_PHY_REG_BASE + 0x0bbc) +#define AR9170_PHY_REG_MASK2_P_45_31 (AR9170_PHY_REG_BASE + 0x0bc0) +#define AR9170_PHY_REG_MASK2_P_61_45 (AR9170_PHY_REG_BASE + 0x0bc4) +#define AR9170_PHY_REG_POWER_TX_SUB (AR9170_PHY_REG_BASE + 0x0bc8) +#define AR9170_PHY_REG_POWER_TX_RATE7 (AR9170_PHY_REG_BASE + 0x0bcc) +#define AR9170_PHY_REG_POWER_TX_RATE8 (AR9170_PHY_REG_BASE + 0x0bd0) +#define AR9170_PHY_REG_POWER_TX_RATE9 (AR9170_PHY_REG_BASE + 0x0bd4) +#define AR9170_PHY_REG_XPA_CFG (AR9170_PHY_REG_BASE + 0x0bd8) +#define AR9170_PHY_FORCE_XPA_CFG 0x000000001 +#define AR9170_PHY_FORCE_XPA_CFG_S 0 + +#define AR9170_PHY_REG_CH1_CCA (AR9170_PHY_REG_BASE + 0x1064) +#define AR9170_PHY_CH1_MINCCA_PWR 0x0ff80000 +#define AR9170_PHY_CH1_MINCCA_PWR_S 19 + +#define AR9170_PHY_REG_CH2_CCA (AR9170_PHY_REG_BASE + 0x2064) +#define AR9170_PHY_CH2_MINCCA_PWR 0x0ff80000 +#define AR9170_PHY_CH2_MINCCA_PWR_S 19 + +#define AR9170_PHY_REG_CH1_EXT_CCA (AR9170_PHY_REG_BASE + 0x11bc) +#define AR9170_PHY_CH1_EXT_MINCCA_PWR 0xff800000 +#define AR9170_PHY_CH1_EXT_MINCCA_PWR_S 23 + +#define AR9170_PHY_REG_CH2_EXT_CCA (AR9170_PHY_REG_BASE + 0x21bc) +#define AR9170_PHY_CH2_EXT_MINCCA_PWR 0xff800000 +#define AR9170_PHY_CH2_EXT_MINCCA_PWR_S 23 + +#endif /* __CARL9170_SHARED_PHY_H */ diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c new file mode 100644 index 0000000000000000000000000000000000000000..939a0e96ed1f512f8ce22cacfd8b0c49a4633ed1 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -0,0 +1,938 @@ +/* + * Atheros CARL9170 driver + * + * 802.11 & command trap routines + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include "carl9170.h" +#include "hw.h" +#include "cmd.h" + +static void carl9170_dbg_message(struct ar9170 *ar, const char *buf, u32 len) +{ + bool restart = false; + enum carl9170_restart_reasons reason = CARL9170_RR_NO_REASON; + + if (len > 3) { + if (memcmp(buf, CARL9170_ERR_MAGIC, 3) == 0) { + ar->fw.err_counter++; + if (ar->fw.err_counter > 3) { + restart = true; + reason = CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS; + } + } + + if (memcmp(buf, CARL9170_BUG_MAGIC, 3) == 0) { + ar->fw.bug_counter++; + restart = true; + reason = CARL9170_RR_FATAL_FIRMWARE_ERROR; + } + } + + wiphy_info(ar->hw->wiphy, "FW: %.*s\n", len, buf); + + if (restart) + carl9170_restart(ar, reason); +} + +static void carl9170_handle_ps(struct ar9170 *ar, struct carl9170_rsp *rsp) +{ + u32 ps; + bool new_ps; + + ps = le32_to_cpu(rsp->psm.state); + + new_ps = (ps & CARL9170_PSM_COUNTER) != CARL9170_PSM_WAKE; + if (ar->ps.state != new_ps) { + if (!new_ps) { + ar->ps.sleep_ms = jiffies_to_msecs(jiffies - + ar->ps.last_action); + } + + ar->ps.last_action = jiffies; + + ar->ps.state = new_ps; + } +} + +static int carl9170_check_sequence(struct ar9170 *ar, unsigned int seq) +{ + if (ar->cmd_seq < -1) + return 0; + + /* + * Initialize Counter + */ + if (ar->cmd_seq < 0) + ar->cmd_seq = seq; + + /* + * The sequence is strictly monotonic increasing and it never skips! + * + * Therefore we can safely assume that whenever we received an + * unexpected sequence we have lost some valuable data. + */ + if (seq != ar->cmd_seq) { + int count; + + count = (seq - ar->cmd_seq) % ar->fw.cmd_bufs; + + wiphy_err(ar->hw->wiphy, "lost %d command responses/traps! " + "w:%d g:%d\n", count, ar->cmd_seq, seq); + + carl9170_restart(ar, CARL9170_RR_LOST_RSP); + return -EIO; + } + + ar->cmd_seq = (ar->cmd_seq + 1) % ar->fw.cmd_bufs; + return 0; +} + +static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer) +{ + /* + * Some commands may have a variable response length + * and we cannot predict the correct length in advance. + * So we only check if we provided enough space for the data. + */ + if (unlikely(ar->readlen != (len - 4))) { + dev_warn(&ar->udev->dev, "received invalid command response:" + "got %d, instead of %d\n", len - 4, ar->readlen); + print_hex_dump_bytes("carl9170 cmd:", DUMP_PREFIX_OFFSET, + ar->cmd_buf, (ar->cmd.hdr.len + 4) & 0x3f); + print_hex_dump_bytes("carl9170 rsp:", DUMP_PREFIX_OFFSET, + buffer, len); + /* + * Do not complete. The command times out, + * and we get a stack trace from there. + */ + carl9170_restart(ar, CARL9170_RR_INVALID_RSP); + } + + spin_lock(&ar->cmd_lock); + if (ar->readbuf) { + if (len >= 4) + memcpy(ar->readbuf, buffer + 4, len - 4); + + ar->readbuf = NULL; + } + complete(&ar->cmd_wait); + spin_unlock(&ar->cmd_lock); +} + +void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) +{ + struct carl9170_rsp *cmd = (void *) buf; + struct ieee80211_vif *vif; + + if (carl9170_check_sequence(ar, cmd->hdr.seq)) + return; + + if ((cmd->hdr.cmd & CARL9170_RSP_FLAG) != CARL9170_RSP_FLAG) { + if (!(cmd->hdr.cmd & CARL9170_CMD_ASYNC_FLAG)) + carl9170_cmd_callback(ar, len, buf); + + return; + } + + if (unlikely(cmd->hdr.len != (len - 4))) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "FW: received over-/under" + "sized event %x (%d, but should be %d).\n", + cmd->hdr.cmd, cmd->hdr.len, len - 4); + + print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, + buf, len); + } + + return; + } + + /* hardware event handlers */ + switch (cmd->hdr.cmd) { + case CARL9170_RSP_PRETBTT: + /* pre-TBTT event */ + rcu_read_lock(); + vif = carl9170_get_main_vif(ar); + + if (!vif) { + rcu_read_unlock(); + break; + } + + switch (vif->type) { + case NL80211_IFTYPE_STATION: + carl9170_handle_ps(ar, cmd); + break; + + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_ADHOC: + carl9170_update_beacon(ar, true); + break; + + default: + break; + } + rcu_read_unlock(); + + break; + + + case CARL9170_RSP_TXCOMP: + /* TX status notification */ + carl9170_tx_process_status(ar, cmd); + break; + + case CARL9170_RSP_BEACON_CONFIG: + /* + * (IBSS) beacon send notification + * bytes: 04 c2 XX YY B4 B3 B2 B1 + * + * XX always 80 + * YY always 00 + * B1-B4 "should" be the number of send out beacons. + */ + break; + + case CARL9170_RSP_ATIM: + /* End of Atim Window */ + break; + + case CARL9170_RSP_WATCHDOG: + /* Watchdog Interrupt */ + carl9170_restart(ar, CARL9170_RR_WATCHDOG); + break; + + case CARL9170_RSP_TEXT: + /* firmware debug */ + carl9170_dbg_message(ar, (char *)buf + 4, len - 4); + break; + + case CARL9170_RSP_HEXDUMP: + wiphy_dbg(ar->hw->wiphy, "FW: HD %d\n", len - 4); + print_hex_dump_bytes("FW:", DUMP_PREFIX_NONE, + (char *)buf + 4, len - 4); + break; + + case CARL9170_RSP_RADAR: + if (!net_ratelimit()) + break; + + wiphy_info(ar->hw->wiphy, "FW: RADAR! Please report this " + "incident to linux-wireless@vger.kernel.org !\n"); + break; + + case CARL9170_RSP_GPIO: +#ifdef CONFIG_CARL9170_WPC + if (ar->wps.pbc) { + bool state = !!(cmd->gpio.gpio & cpu_to_le32( + AR9170_GPIO_PORT_WPS_BUTTON_PRESSED)); + + if (state != ar->wps.pbc_state) { + ar->wps.pbc_state = state; + input_report_key(ar->wps.pbc, KEY_WPS_BUTTON, + state); + input_sync(ar->wps.pbc); + } + } +#endif /* CONFIG_CARL9170_WPC */ + break; + + case CARL9170_RSP_BOOT: + complete(&ar->fw_boot_wait); + break; + + default: + wiphy_err(ar->hw->wiphy, "FW: received unhandled event %x\n", + cmd->hdr.cmd); + print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len); + break; + } +} + +static int carl9170_rx_mac_status(struct ar9170 *ar, + struct ar9170_rx_head *head, struct ar9170_rx_macstatus *mac, + struct ieee80211_rx_status *status) +{ + struct ieee80211_channel *chan; + u8 error, decrypt; + + BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12); + BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4); + + error = mac->error; + + if (error & AR9170_RX_ERROR_WRONG_RA) { + if (!ar->sniffer_enabled) + return -EINVAL; + } + + if (error & AR9170_RX_ERROR_PLCP) { + if (!(ar->filter_state & FIF_PLCPFAIL)) + return -EINVAL; + + status->flag |= RX_FLAG_FAILED_PLCP_CRC; + } + + if (error & AR9170_RX_ERROR_FCS) { + ar->tx_fcs_errors++; + + if (!(ar->filter_state & FIF_FCSFAIL)) + return -EINVAL; + + status->flag |= RX_FLAG_FAILED_FCS_CRC; + } + + decrypt = ar9170_get_decrypt_type(mac); + if (!(decrypt & AR9170_RX_ENC_SOFTWARE) && + decrypt != AR9170_ENC_ALG_NONE) { + if ((decrypt == AR9170_ENC_ALG_TKIP) && + (error & AR9170_RX_ERROR_MMIC)) + status->flag |= RX_FLAG_MMIC_ERROR; + + status->flag |= RX_FLAG_DECRYPTED; + } + + if (error & AR9170_RX_ERROR_DECRYPT && !ar->sniffer_enabled) + return -ENODATA; + + error &= ~(AR9170_RX_ERROR_MMIC | + AR9170_RX_ERROR_FCS | + AR9170_RX_ERROR_WRONG_RA | + AR9170_RX_ERROR_DECRYPT | + AR9170_RX_ERROR_PLCP); + + /* drop any other error frames */ + if (unlikely(error)) { + /* TODO: update netdevice's RX dropped/errors statistics */ + + if (net_ratelimit()) + wiphy_dbg(ar->hw->wiphy, "received frame with " + "suspicious error code (%#x).\n", error); + + return -EINVAL; + } + + chan = ar->channel; + if (chan) { + status->band = chan->band; + status->freq = chan->center_freq; + } + + switch (mac->status & AR9170_RX_STATUS_MODULATION) { + case AR9170_RX_STATUS_MODULATION_CCK: + if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE) + status->flag |= RX_FLAG_SHORTPRE; + switch (head->plcp[0]) { + case AR9170_RX_PHY_RATE_CCK_1M: + status->rate_idx = 0; + break; + case AR9170_RX_PHY_RATE_CCK_2M: + status->rate_idx = 1; + break; + case AR9170_RX_PHY_RATE_CCK_5M: + status->rate_idx = 2; + break; + case AR9170_RX_PHY_RATE_CCK_11M: + status->rate_idx = 3; + break; + default: + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "invalid plcp cck " + "rate (%x).\n", head->plcp[0]); + } + + return -EINVAL; + } + break; + + case AR9170_RX_STATUS_MODULATION_DUPOFDM: + case AR9170_RX_STATUS_MODULATION_OFDM: + switch (head->plcp[0] & 0xf) { + case AR9170_TXRX_PHY_RATE_OFDM_6M: + status->rate_idx = 0; + break; + case AR9170_TXRX_PHY_RATE_OFDM_9M: + status->rate_idx = 1; + break; + case AR9170_TXRX_PHY_RATE_OFDM_12M: + status->rate_idx = 2; + break; + case AR9170_TXRX_PHY_RATE_OFDM_18M: + status->rate_idx = 3; + break; + case AR9170_TXRX_PHY_RATE_OFDM_24M: + status->rate_idx = 4; + break; + case AR9170_TXRX_PHY_RATE_OFDM_36M: + status->rate_idx = 5; + break; + case AR9170_TXRX_PHY_RATE_OFDM_48M: + status->rate_idx = 6; + break; + case AR9170_TXRX_PHY_RATE_OFDM_54M: + status->rate_idx = 7; + break; + default: + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "invalid plcp ofdm " + "rate (%x).\n", head->plcp[0]); + } + + return -EINVAL; + } + if (status->band == IEEE80211_BAND_2GHZ) + status->rate_idx += 4; + break; + + case AR9170_RX_STATUS_MODULATION_HT: + if (head->plcp[3] & 0x80) + status->flag |= RX_FLAG_40MHZ; + if (head->plcp[6] & 0x80) + status->flag |= RX_FLAG_SHORT_GI; + + status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f); + status->flag |= RX_FLAG_HT; + break; + + default: + BUG(); + return -ENOSYS; + } + + return 0; +} + +static void carl9170_rx_phy_status(struct ar9170 *ar, + struct ar9170_rx_phystatus *phy, struct ieee80211_rx_status *status) +{ + int i; + + BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20); + + for (i = 0; i < 3; i++) + if (phy->rssi[i] != 0x80) + status->antenna |= BIT(i); + + /* post-process RSSI */ + for (i = 0; i < 7; i++) + if (phy->rssi[i] & 0x80) + phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f; + + /* TODO: we could do something with phy_errors */ + status->signal = ar->noise[0] + phy->rssi_combined; +} + +static struct sk_buff *carl9170_rx_copy_data(u8 *buf, int len) +{ + struct sk_buff *skb; + int reserved = 0; + struct ieee80211_hdr *hdr = (void *) buf; + + if (ieee80211_is_data_qos(hdr->frame_control)) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + reserved += NET_IP_ALIGN; + + if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) + reserved += NET_IP_ALIGN; + } + + if (ieee80211_has_a4(hdr->frame_control)) + reserved += NET_IP_ALIGN; + + reserved = 32 + (reserved & NET_IP_ALIGN); + + skb = dev_alloc_skb(len + reserved); + if (likely(skb)) { + skb_reserve(skb, reserved); + memcpy(skb_put(skb, len), buf, len); + } + + return skb; +} + +static u8 *carl9170_find_ie(u8 *data, unsigned int len, u8 ie) +{ + struct ieee80211_mgmt *mgmt = (void *)data; + u8 *pos, *end; + + pos = (u8 *)mgmt->u.beacon.variable; + end = data + len; + while (pos < end) { + if (pos + 2 + pos[1] > end) + return NULL; + + if (pos[0] == ie) + return pos; + + pos += 2 + pos[1]; + } + return NULL; +} + +/* + * NOTE: + * + * The firmware is in charge of waking up the device just before + * the AP is expected to transmit the next beacon. + * + * This leaves the driver with the important task of deciding when + * to set the PHY back to bed again. + */ +static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len) +{ + struct ieee80211_hdr *hdr = (void *) data; + struct ieee80211_tim_ie *tim_ie; + u8 *tim; + u8 tim_len; + bool cam; + + if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS))) + return; + + /* check if this really is a beacon */ + if (!ieee80211_is_beacon(hdr->frame_control)) + return; + + /* min. beacon length + FCS_LEN */ + if (len <= 40 + FCS_LEN) + return; + + /* and only beacons from the associated BSSID, please */ + if (compare_ether_addr(hdr->addr3, ar->common.curbssid) || + !ar->common.curaid) + return; + + ar->ps.last_beacon = jiffies; + + tim = carl9170_find_ie(data, len - FCS_LEN, WLAN_EID_TIM); + if (!tim) + return; + + if (tim[1] < sizeof(*tim_ie)) + return; + + tim_len = tim[1]; + tim_ie = (struct ieee80211_tim_ie *) &tim[2]; + + if (!WARN_ON_ONCE(!ar->hw->conf.ps_dtim_period)) + ar->ps.dtim_counter = (tim_ie->dtim_count - 1) % + ar->hw->conf.ps_dtim_period; + + /* Check whenever the PHY can be turned off again. */ + + /* 1. What about buffered unicast traffic for our AID? */ + cam = ieee80211_check_tim(tim_ie, tim_len, ar->common.curaid); + + /* 2. Maybe the AP wants to send multicast/broadcast data? */ + cam = !!(tim_ie->bitmap_ctrl & 0x01); + + if (!cam) { + /* back to low-power land. */ + ar->ps.off_override &= ~PS_OFF_BCN; + carl9170_ps_check(ar); + } else { + /* force CAM */ + ar->ps.off_override |= PS_OFF_BCN; + } +} + +static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms) +{ + __le16 fc; + + if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) { + /* + * This frame is not part of an aMPDU. + * Therefore it is not subjected to any + * of the following content restrictions. + */ + return true; + } + + /* + * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts + * certain frame types can be part of an aMPDU. + * + * In order to keep the processing cost down, I opted for a + * stateless filter solely based on the frame control field. + */ + + fc = ((struct ieee80211_hdr *)buf)->frame_control; + if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc)) + return true; + + if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) || + ieee80211_is_back_req(fc)) + return true; + + if (ieee80211_is_action(fc)) + return true; + + return false; +} + +/* + * If the frame alignment is right (or the kernel has + * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there + * is only a single MPDU in the USB frame, then we could + * submit to mac80211 the SKB directly. However, since + * there may be multiple packets in one SKB in stream + * mode, and we need to observe the proper ordering, + * this is non-trivial. + */ + +static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) +{ + struct ar9170_rx_head *head; + struct ar9170_rx_macstatus *mac; + struct ar9170_rx_phystatus *phy = NULL; + struct ieee80211_rx_status status; + struct sk_buff *skb; + int mpdu_len; + u8 mac_status; + + if (!IS_STARTED(ar)) + return; + + if (unlikely(len < sizeof(*mac))) + goto drop; + + mpdu_len = len - sizeof(*mac); + + mac = (void *)(buf + mpdu_len); + mac_status = mac->status; + switch (mac_status & AR9170_RX_STATUS_MPDU) { + case AR9170_RX_STATUS_MPDU_FIRST: + /* Aggregated MPDUs start with an PLCP header */ + if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { + head = (void *) buf; + + /* + * The PLCP header needs to be cached for the + * following MIDDLE + LAST A-MPDU packets. + * + * So, if you are wondering why all frames seem + * to share a common RX status information, + * then you have the answer right here... + */ + memcpy(&ar->rx_plcp, (void *) buf, + sizeof(struct ar9170_rx_head)); + + mpdu_len -= sizeof(struct ar9170_rx_head); + buf += sizeof(struct ar9170_rx_head); + + ar->rx_has_plcp = true; + } else { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "plcp info " + "is clipped.\n"); + } + + goto drop; + } + break; + + case AR9170_RX_STATUS_MPDU_LAST: + /* + * The last frame of an A-MPDU has an extra tail + * which does contain the phy status of the whole + * aggregate. + */ + + if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { + mpdu_len -= sizeof(struct ar9170_rx_phystatus); + phy = (void *)(buf + mpdu_len); + } else { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "frame tail " + "is clipped.\n"); + } + + goto drop; + } + + case AR9170_RX_STATUS_MPDU_MIDDLE: + /* These are just data + mac status */ + if (unlikely(!ar->rx_has_plcp)) { + if (!net_ratelimit()) + return; + + wiphy_err(ar->hw->wiphy, "rx stream does not start " + "with a first_mpdu frame tag.\n"); + + goto drop; + } + + head = &ar->rx_plcp; + break; + + case AR9170_RX_STATUS_MPDU_SINGLE: + /* single mpdu has both: plcp (head) and phy status (tail) */ + head = (void *) buf; + + mpdu_len -= sizeof(struct ar9170_rx_head); + mpdu_len -= sizeof(struct ar9170_rx_phystatus); + + buf += sizeof(struct ar9170_rx_head); + phy = (void *)(buf + mpdu_len); + break; + + default: + BUG_ON(1); + break; + } + + /* FC + DU + RA + FCS */ + if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN))) + goto drop; + + memset(&status, 0, sizeof(status)); + if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) + goto drop; + + if (!carl9170_ampdu_check(ar, buf, mac_status)) + goto drop; + + if (phy) + carl9170_rx_phy_status(ar, phy, &status); + + carl9170_ps_beacon(ar, buf, mpdu_len); + + skb = carl9170_rx_copy_data(buf, mpdu_len); + if (!skb) + goto drop; + + memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); + ieee80211_rx(ar->hw, skb); + return; + +drop: + ar->rx_dropped++; +} + +static void carl9170_rx_untie_cmds(struct ar9170 *ar, const u8 *respbuf, + const unsigned int resplen) +{ + struct carl9170_rsp *cmd; + int i = 0; + + while (i < resplen) { + cmd = (void *) &respbuf[i]; + + i += cmd->hdr.len + 4; + if (unlikely(i > resplen)) + break; + + carl9170_handle_command_response(ar, cmd, cmd->hdr.len + 4); + } + + if (unlikely(i != resplen)) { + if (!net_ratelimit()) + return; + + wiphy_err(ar->hw->wiphy, "malformed firmware trap:\n"); + print_hex_dump_bytes("rxcmd:", DUMP_PREFIX_OFFSET, + respbuf, resplen); + } +} + +static void __carl9170_rx(struct ar9170 *ar, u8 *buf, unsigned int len) +{ + unsigned int i = 0; + + /* weird thing, but this is the same in the original driver */ + while (len > 2 && i < 12 && buf[0] == 0xff && buf[1] == 0xff) { + i += 2; + len -= 2; + buf += 2; + } + + if (unlikely(len < 4)) + return; + + /* found the 6 * 0xffff marker? */ + if (i == 12) + carl9170_rx_untie_cmds(ar, buf, len); + else + carl9170_handle_mpdu(ar, buf, len); +} + +static void carl9170_rx_stream(struct ar9170 *ar, void *buf, unsigned int len) +{ + unsigned int tlen, wlen = 0, clen = 0; + struct ar9170_stream *rx_stream; + u8 *tbuf; + + tbuf = buf; + tlen = len; + + while (tlen >= 4) { + rx_stream = (void *) tbuf; + clen = le16_to_cpu(rx_stream->length); + wlen = ALIGN(clen, 4); + + /* check if this is stream has a valid tag.*/ + if (rx_stream->tag != cpu_to_le16(AR9170_RX_STREAM_TAG)) { + /* + * TODO: handle the highly unlikely event that the + * corrupted stream has the TAG at the right position. + */ + + /* check if the frame can be repaired. */ + if (!ar->rx_failover_missing) { + + /* this is not "short read". */ + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, + "missing tag!\n"); + } + + __carl9170_rx(ar, tbuf, tlen); + return; + } + + if (ar->rx_failover_missing > tlen) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, + "possible multi " + "stream corruption!\n"); + goto err_telluser; + } else { + goto err_silent; + } + } + + memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); + ar->rx_failover_missing -= tlen; + + if (ar->rx_failover_missing <= 0) { + /* + * nested carl9170_rx_stream call! + * + * termination is guranteed, even when the + * combined frame also have an element with + * a bad tag. + */ + + ar->rx_failover_missing = 0; + carl9170_rx_stream(ar, ar->rx_failover->data, + ar->rx_failover->len); + + skb_reset_tail_pointer(ar->rx_failover); + skb_trim(ar->rx_failover, 0); + } + + return; + } + + /* check if stream is clipped */ + if (wlen > tlen - 4) { + if (ar->rx_failover_missing) { + /* TODO: handle double stream corruption. */ + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "double rx " + "stream corruption!\n"); + goto err_telluser; + } else { + goto err_silent; + } + } + + /* + * save incomplete data set. + * the firmware will resend the missing bits when + * the rx - descriptor comes round again. + */ + + memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen); + ar->rx_failover_missing = clen - tlen; + return; + } + __carl9170_rx(ar, rx_stream->payload, clen); + + tbuf += wlen + 4; + tlen -= wlen + 4; + } + + if (tlen) { + if (net_ratelimit()) { + wiphy_err(ar->hw->wiphy, "%d bytes of unprocessed " + "data left in rx stream!\n", tlen); + } + + goto err_telluser; + } + + return; + +err_telluser: + wiphy_err(ar->hw->wiphy, "damaged RX stream data [want:%d, " + "data:%d, rx:%d, pending:%d ]\n", clen, wlen, tlen, + ar->rx_failover_missing); + + if (ar->rx_failover_missing) + print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET, + ar->rx_failover->data, + ar->rx_failover->len); + + print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET, + buf, len); + + wiphy_err(ar->hw->wiphy, "please check your hardware and cables, if " + "you see this message frequently.\n"); + +err_silent: + if (ar->rx_failover_missing) { + skb_reset_tail_pointer(ar->rx_failover); + skb_trim(ar->rx_failover, 0); + ar->rx_failover_missing = 0; + } +} + +void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len) +{ + if (ar->fw.rx_stream) + carl9170_rx_stream(ar, buf, len); + else + __carl9170_rx(ar, buf, len); +} diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c new file mode 100644 index 0000000000000000000000000000000000000000..b575c865142d64f82f8e072518c0de44e46039cc --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -0,0 +1,1335 @@ +/* + * Atheros CARL9170 driver + * + * 802.11 xmit & status routines + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "carl9170.h" +#include "hw.h" +#include "cmd.h" + +static inline unsigned int __carl9170_get_queue(struct ar9170 *ar, + unsigned int queue) +{ + if (unlikely(modparam_noht)) { + return queue; + } else { + /* + * This is just another workaround, until + * someone figures out how to get QoS and + * AMPDU to play nicely together. + */ + + return 2; /* AC_BE */ + } +} + +static inline unsigned int carl9170_get_queue(struct ar9170 *ar, + struct sk_buff *skb) +{ + return __carl9170_get_queue(ar, skb_get_queue_mapping(skb)); +} + +static bool is_mem_full(struct ar9170 *ar) +{ + return (DIV_ROUND_UP(IEEE80211_MAX_FRAME_LEN, ar->fw.mem_block_size) > + atomic_read(&ar->mem_free_blocks)); +} + +static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb) +{ + int queue, i; + bool mem_full; + + atomic_inc(&ar->tx_total_queued); + + queue = skb_get_queue_mapping(skb); + spin_lock_bh(&ar->tx_stats_lock); + + /* + * The driver has to accept the frame, regardless if the queue is + * full to the brim, or not. We have to do the queuing internally, + * since mac80211 assumes that a driver which can operate with + * aggregated frames does not reject frames for this reason. + */ + ar->tx_stats[queue].len++; + ar->tx_stats[queue].count++; + + mem_full = is_mem_full(ar); + for (i = 0; i < ar->hw->queues; i++) { + if (mem_full || ar->tx_stats[i].len >= ar->tx_stats[i].limit) { + ieee80211_stop_queue(ar->hw, i); + ar->queue_stop_timeout[i] = jiffies; + } + } + + spin_unlock_bh(&ar->tx_stats_lock); +} + +static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) +{ + struct ieee80211_tx_info *txinfo; + int queue; + + txinfo = IEEE80211_SKB_CB(skb); + queue = skb_get_queue_mapping(skb); + + spin_lock_bh(&ar->tx_stats_lock); + + ar->tx_stats[queue].len--; + + if (!is_mem_full(ar)) { + unsigned int i; + for (i = 0; i < ar->hw->queues; i++) { + if (ar->tx_stats[i].len >= CARL9170_NUM_TX_LIMIT_SOFT) + continue; + + if (ieee80211_queue_stopped(ar->hw, i)) { + unsigned long tmp; + + tmp = jiffies - ar->queue_stop_timeout[i]; + if (tmp > ar->max_queue_stop_timeout[i]) + ar->max_queue_stop_timeout[i] = tmp; + } + + ieee80211_wake_queue(ar->hw, i); + } + } + + spin_unlock_bh(&ar->tx_stats_lock); + if (atomic_dec_and_test(&ar->tx_total_queued)) + complete(&ar->tx_flush); +} + +static int carl9170_alloc_dev_space(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super = (void *) skb->data; + unsigned int chunks; + int cookie = -1; + + atomic_inc(&ar->mem_allocs); + + chunks = DIV_ROUND_UP(skb->len, ar->fw.mem_block_size); + if (unlikely(atomic_sub_return(chunks, &ar->mem_free_blocks) < 0)) { + atomic_add(chunks, &ar->mem_free_blocks); + return -ENOSPC; + } + + spin_lock_bh(&ar->mem_lock); + cookie = bitmap_find_free_region(ar->mem_bitmap, ar->fw.mem_blocks, 0); + spin_unlock_bh(&ar->mem_lock); + + if (unlikely(cookie < 0)) { + atomic_add(chunks, &ar->mem_free_blocks); + return -ENOSPC; + } + + super = (void *) skb->data; + + /* + * Cookie #0 serves two special purposes: + * 1. The firmware might use it generate BlockACK frames + * in responds of an incoming BlockAckReqs. + * + * 2. Prevent double-free bugs. + */ + super->s.cookie = (u8) cookie + 1; + return 0; +} + +static void carl9170_release_dev_space(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super = (void *) skb->data; + int cookie; + + /* make a local copy of the cookie */ + cookie = super->s.cookie; + /* invalidate cookie */ + super->s.cookie = 0; + + /* + * Do a out-of-bounds check on the cookie: + * + * * cookie "0" is reserved and won't be assigned to any + * out-going frame. Internally however, it is used to + * mark no longer/un-accounted frames and serves as a + * cheap way of preventing frames from being freed + * twice by _accident_. NB: There is a tiny race... + * + * * obviously, cookie number is limited by the amount + * of available memory blocks, so the number can + * never execeed the mem_blocks count. + */ + if (unlikely(WARN_ON_ONCE(cookie == 0) || + WARN_ON_ONCE(cookie > ar->fw.mem_blocks))) + return; + + atomic_add(DIV_ROUND_UP(skb->len, ar->fw.mem_block_size), + &ar->mem_free_blocks); + + spin_lock_bh(&ar->mem_lock); + bitmap_release_region(ar->mem_bitmap, cookie - 1, 0); + spin_unlock_bh(&ar->mem_lock); +} + +/* Called from any context */ +static void carl9170_tx_release(struct kref *ref) +{ + struct ar9170 *ar; + struct carl9170_tx_info *arinfo; + struct ieee80211_tx_info *txinfo; + struct sk_buff *skb; + + arinfo = container_of(ref, struct carl9170_tx_info, ref); + txinfo = container_of((void *) arinfo, struct ieee80211_tx_info, + rate_driver_data); + skb = container_of((void *) txinfo, struct sk_buff, cb); + + ar = arinfo->ar; + if (WARN_ON_ONCE(!ar)) + return; + + BUILD_BUG_ON( + offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23); + + memset(&txinfo->status.ampdu_ack_len, 0, + sizeof(struct ieee80211_tx_info) - + offsetof(struct ieee80211_tx_info, status.ampdu_ack_len)); + + if (atomic_read(&ar->tx_total_queued)) + ar->tx_schedule = true; + + if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) { + if (!atomic_read(&ar->tx_ampdu_upload)) + ar->tx_ampdu_schedule = true; + + if (txinfo->flags & IEEE80211_TX_STAT_AMPDU) { + txinfo->status.ampdu_len = txinfo->pad[0]; + txinfo->status.ampdu_ack_len = txinfo->pad[1]; + txinfo->pad[0] = txinfo->pad[1] = 0; + } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) { + /* + * drop redundant tx_status reports: + * + * 1. ampdu_ack_len of the final tx_status does + * include the feedback of this particular frame. + * + * 2. tx_status_irqsafe only queues up to 128 + * tx feedback reports and discards the rest. + * + * 3. minstrel_ht is picky, it only accepts + * reports of frames with the TX_STATUS_AMPDU flag. + */ + + dev_kfree_skb_any(skb); + return; + } else { + /* + * Frame has failed, but we want to keep it in + * case it was lost due to a power-state + * transition. + */ + } + } + + skb_pull(skb, sizeof(struct _carl9170_tx_superframe)); + ieee80211_tx_status_irqsafe(ar->hw, skb); +} + +void carl9170_tx_get_skb(struct sk_buff *skb) +{ + struct carl9170_tx_info *arinfo = (void *) + (IEEE80211_SKB_CB(skb))->rate_driver_data; + kref_get(&arinfo->ref); +} + +int carl9170_tx_put_skb(struct sk_buff *skb) +{ + struct carl9170_tx_info *arinfo = (void *) + (IEEE80211_SKB_CB(skb))->rate_driver_data; + + return kref_put(&arinfo->ref, carl9170_tx_release); +} + +/* Caller must hold the tid_info->lock & rcu_read_lock */ +static void carl9170_tx_shift_bm(struct ar9170 *ar, + struct carl9170_sta_tid *tid_info, u16 seq) +{ + u16 off; + + off = SEQ_DIFF(seq, tid_info->bsn); + + if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS)) + return; + + /* + * Sanity check. For each MPDU we set the bit in bitmap and + * clear it once we received the tx_status. + * But if the bit is already cleared then we've been bitten + * by a bug. + */ + WARN_ON_ONCE(!test_and_clear_bit(off, tid_info->bitmap)); + + off = SEQ_DIFF(tid_info->snx, tid_info->bsn); + if (WARN_ON_ONCE(off >= CARL9170_BAW_BITS)) + return; + + if (!bitmap_empty(tid_info->bitmap, off)) + off = find_first_bit(tid_info->bitmap, off); + + tid_info->bsn += off; + tid_info->bsn &= 0x0fff; + + bitmap_shift_right(tid_info->bitmap, tid_info->bitmap, + off, CARL9170_BAW_BITS); +} + +static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, + struct sk_buff *skb, struct ieee80211_tx_info *txinfo) +{ + struct _carl9170_tx_superframe *super = (void *) skb->data; + struct ieee80211_hdr *hdr = (void *) super->frame_data; + struct ieee80211_tx_info *tx_info; + struct carl9170_tx_info *ar_info; + struct carl9170_sta_info *sta_info; + struct ieee80211_sta *sta; + struct carl9170_sta_tid *tid_info; + struct ieee80211_vif *vif; + unsigned int vif_id; + u8 tid; + + if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || + txinfo->flags & IEEE80211_TX_CTL_INJECTED) + return; + + tx_info = IEEE80211_SKB_CB(skb); + ar_info = (void *) tx_info->rate_driver_data; + + vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> + CARL9170_TX_SUPER_MISC_VIF_ID_S; + + if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) + return; + + rcu_read_lock(); + vif = rcu_dereference(ar->vif_priv[vif_id].vif); + if (unlikely(!vif)) + goto out_rcu; + + /* + * Normally we should use wrappers like ieee80211_get_DA to get + * the correct peer ieee80211_sta. + * + * But there is a problem with indirect traffic (broadcasts, or + * data which is designated for other stations) in station mode. + * The frame will be directed to the AP for distribution and not + * to the actual destination. + */ + sta = ieee80211_find_sta(vif, hdr->addr1); + if (unlikely(!sta)) + goto out_rcu; + + tid = get_tid_h(hdr); + + sta_info = (void *) sta->drv_priv; + tid_info = rcu_dereference(sta_info->agg[tid]); + if (!tid_info) + goto out_rcu; + + spin_lock_bh(&tid_info->lock); + if (likely(tid_info->state >= CARL9170_TID_STATE_IDLE)) + carl9170_tx_shift_bm(ar, tid_info, get_seq_h(hdr)); + + if (sta_info->stats[tid].clear) { + sta_info->stats[tid].clear = false; + sta_info->stats[tid].ampdu_len = 0; + sta_info->stats[tid].ampdu_ack_len = 0; + } + + sta_info->stats[tid].ampdu_len++; + if (txinfo->status.rates[0].count == 1) + sta_info->stats[tid].ampdu_ack_len++; + + if (super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_IMM_BA)) { + txinfo->pad[0] = sta_info->stats[tid].ampdu_len; + txinfo->pad[1] = sta_info->stats[tid].ampdu_ack_len; + txinfo->flags |= IEEE80211_TX_STAT_AMPDU; + sta_info->stats[tid].clear = true; + } + spin_unlock_bh(&tid_info->lock); + +out_rcu: + rcu_read_unlock(); +} + +void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, + const bool success) +{ + struct ieee80211_tx_info *txinfo; + + carl9170_tx_accounting_free(ar, skb); + + txinfo = IEEE80211_SKB_CB(skb); + + if (success) + txinfo->flags |= IEEE80211_TX_STAT_ACK; + else + ar->tx_ack_failures++; + + if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) + carl9170_tx_status_process_ampdu(ar, skb, txinfo); + + carl9170_tx_put_skb(skb); +} + +/* This function may be called form any context */ +void carl9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) +{ + struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); + + atomic_dec(&ar->tx_total_pending); + + if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) + atomic_dec(&ar->tx_ampdu_upload); + + if (carl9170_tx_put_skb(skb)) + tasklet_hi_schedule(&ar->usb_tasklet); +} + +static struct sk_buff *carl9170_get_queued_skb(struct ar9170 *ar, u8 cookie, + struct sk_buff_head *queue) +{ + struct sk_buff *skb; + + spin_lock_bh(&queue->lock); + skb_queue_walk(queue, skb) { + struct _carl9170_tx_superframe *txc = (void *) skb->data; + + if (txc->s.cookie != cookie) + continue; + + __skb_unlink(skb, queue); + spin_unlock_bh(&queue->lock); + + carl9170_release_dev_space(ar, skb); + return skb; + } + spin_unlock_bh(&queue->lock); + + return NULL; +} + +static void carl9170_tx_fill_rateinfo(struct ar9170 *ar, unsigned int rix, + unsigned int tries, struct ieee80211_tx_info *txinfo) +{ + unsigned int i; + + for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { + if (txinfo->status.rates[i].idx < 0) + break; + + if (i == rix) { + txinfo->status.rates[i].count = tries; + i++; + break; + } + } + + for (; i < IEEE80211_TX_MAX_RATES; i++) { + txinfo->status.rates[i].idx = -1; + txinfo->status.rates[i].count = 0; + } +} + +static void carl9170_check_queue_stop_timeout(struct ar9170 *ar) +{ + int i; + struct sk_buff *skb; + struct ieee80211_tx_info *txinfo; + struct carl9170_tx_info *arinfo; + bool restart = false; + + for (i = 0; i < ar->hw->queues; i++) { + spin_lock_bh(&ar->tx_status[i].lock); + + skb = skb_peek(&ar->tx_status[i]); + + if (!skb) + goto next; + + txinfo = IEEE80211_SKB_CB(skb); + arinfo = (void *) txinfo->rate_driver_data; + + if (time_is_before_jiffies(arinfo->timeout + + msecs_to_jiffies(CARL9170_QUEUE_STUCK_TIMEOUT)) == true) + restart = true; + +next: + spin_unlock_bh(&ar->tx_status[i].lock); + } + + if (restart) { + /* + * At least one queue has been stuck for long enough. + * Give the device a kick and hope it gets back to + * work. + * + * possible reasons may include: + * - frames got lost/corrupted (bad connection to the device) + * - stalled rx processing/usb controller hiccups + * - firmware errors/bugs + * - every bug you can think of. + * - all bugs you can't... + * - ... + */ + carl9170_restart(ar, CARL9170_RR_STUCK_TX); + } +} + +void carl9170_tx_janitor(struct work_struct *work) +{ + struct ar9170 *ar = container_of(work, struct ar9170, + tx_janitor.work); + if (!IS_STARTED(ar)) + return; + + ar->tx_janitor_last_run = jiffies; + + carl9170_check_queue_stop_timeout(ar); + + if (!atomic_read(&ar->tx_total_queued)) + return; + + ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor, + msecs_to_jiffies(CARL9170_TX_TIMEOUT)); +} + +static void __carl9170_tx_process_status(struct ar9170 *ar, + const uint8_t cookie, const uint8_t info) +{ + struct sk_buff *skb; + struct ieee80211_tx_info *txinfo; + struct carl9170_tx_info *arinfo; + unsigned int r, t, q; + bool success = true; + + q = ar9170_qmap[info & CARL9170_TX_STATUS_QUEUE]; + + skb = carl9170_get_queued_skb(ar, cookie, &ar->tx_status[q]); + if (!skb) { + /* + * We have lost the race to another thread. + */ + + return ; + } + + txinfo = IEEE80211_SKB_CB(skb); + arinfo = (void *) txinfo->rate_driver_data; + + if (!(info & CARL9170_TX_STATUS_SUCCESS)) + success = false; + + r = (info & CARL9170_TX_STATUS_RIX) >> CARL9170_TX_STATUS_RIX_S; + t = (info & CARL9170_TX_STATUS_TRIES) >> CARL9170_TX_STATUS_TRIES_S; + + carl9170_tx_fill_rateinfo(ar, r, t, txinfo); + carl9170_tx_status(ar, skb, success); +} + +void carl9170_tx_process_status(struct ar9170 *ar, + const struct carl9170_rsp *cmd) +{ + unsigned int i; + + for (i = 0; i < cmd->hdr.ext; i++) { + if (WARN_ON(i > ((cmd->hdr.len / 2) + 1))) { + print_hex_dump_bytes("UU:", DUMP_PREFIX_NONE, + (void *) cmd, cmd->hdr.len + 4); + break; + } + + __carl9170_tx_process_status(ar, cmd->_tx_status[i].cookie, + cmd->_tx_status[i].info); + } +} + +static __le32 carl9170_tx_physet(struct ar9170 *ar, + struct ieee80211_tx_info *info, struct ieee80211_tx_rate *txrate) +{ + struct ieee80211_rate *rate = NULL; + u32 power, chains; + __le32 tmp; + + tmp = cpu_to_le32(0); + + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ << + AR9170_TX_PHY_BW_S); + /* this works because 40 MHz is 2 and dup is 3 */ + if (txrate->flags & IEEE80211_TX_RC_DUP_DATA) + tmp |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP << + AR9170_TX_PHY_BW_S); + + if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) + tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI); + + if (txrate->flags & IEEE80211_TX_RC_MCS) { + u32 r = txrate->idx; + u8 *txpower; + + /* heavy clip control */ + tmp |= cpu_to_le32((r & 0x7) << + AR9170_TX_PHY_TX_HEAVY_CLIP_S); + + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) { + if (info->band == IEEE80211_BAND_5GHZ) + txpower = ar->power_5G_ht40; + else + txpower = ar->power_2G_ht40; + } else { + if (info->band == IEEE80211_BAND_5GHZ) + txpower = ar->power_5G_ht20; + else + txpower = ar->power_2G_ht20; + } + + power = txpower[r & 7]; + + /* +1 dBm for HT40 */ + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + power += 2; + + r <<= AR9170_TX_PHY_MCS_S; + BUG_ON(r & ~AR9170_TX_PHY_MCS); + + tmp |= cpu_to_le32(r & AR9170_TX_PHY_MCS); + tmp |= cpu_to_le32(AR9170_TX_PHY_MOD_HT); + + /* + * green field preamble does not work. + * + * if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) + * tmp |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD); + */ + } else { + u8 *txpower; + u32 mod; + u32 phyrate; + u8 idx = txrate->idx; + + if (info->band != IEEE80211_BAND_2GHZ) { + idx += 4; + txpower = ar->power_5G_leg; + mod = AR9170_TX_PHY_MOD_OFDM; + } else { + if (idx < 4) { + txpower = ar->power_2G_cck; + mod = AR9170_TX_PHY_MOD_CCK; + } else { + mod = AR9170_TX_PHY_MOD_OFDM; + txpower = ar->power_2G_ofdm; + } + } + + rate = &__carl9170_ratetable[idx]; + + phyrate = rate->hw_value & 0xF; + power = txpower[(rate->hw_value & 0x30) >> 4]; + phyrate <<= AR9170_TX_PHY_MCS_S; + + tmp |= cpu_to_le32(mod); + tmp |= cpu_to_le32(phyrate); + + /* + * short preamble seems to be broken too. + * + * if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) + * tmp |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE); + */ + } + power <<= AR9170_TX_PHY_TX_PWR_S; + power &= AR9170_TX_PHY_TX_PWR; + tmp |= cpu_to_le32(power); + + /* set TX chains */ + if (ar->eeprom.tx_mask == 1) { + chains = AR9170_TX_PHY_TXCHAIN_1; + } else { + chains = AR9170_TX_PHY_TXCHAIN_2; + + /* >= 36M legacy OFDM - use only one chain */ + if (rate && rate->bitrate >= 360 && + !(txrate->flags & IEEE80211_TX_RC_MCS)) + chains = AR9170_TX_PHY_TXCHAIN_1; + } + tmp |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_S); + + return tmp; +} + +static bool carl9170_tx_rts_check(struct ar9170 *ar, + struct ieee80211_tx_rate *rate, + bool ampdu, bool multi) +{ + switch (ar->erp_mode) { + case CARL9170_ERP_AUTO: + if (ampdu) + break; + + case CARL9170_ERP_MAC80211: + if (!(rate->flags & IEEE80211_TX_RC_USE_RTS_CTS)) + break; + + case CARL9170_ERP_RTS: + if (likely(!multi)) + return true; + + default: + break; + } + + return false; +} + +static bool carl9170_tx_cts_check(struct ar9170 *ar, + struct ieee80211_tx_rate *rate) +{ + switch (ar->erp_mode) { + case CARL9170_ERP_AUTO: + case CARL9170_ERP_MAC80211: + if (!(rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) + break; + + case CARL9170_ERP_CTS: + return true; + + default: + break; + } + + return false; +} + +static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) +{ + struct ieee80211_hdr *hdr; + struct _carl9170_tx_superframe *txc; + struct carl9170_vif_info *cvif; + struct ieee80211_tx_info *info; + struct ieee80211_tx_rate *txrate; + struct ieee80211_sta *sta; + struct carl9170_tx_info *arinfo; + unsigned int hw_queue; + int i; + __le16 mac_tmp; + u16 len; + bool ampdu, no_ack; + + BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); + BUILD_BUG_ON(sizeof(struct _carl9170_tx_superdesc) != + CARL9170_TX_SUPERDESC_LEN); + + BUILD_BUG_ON(sizeof(struct _ar9170_tx_hwdesc) != + AR9170_TX_HWDESC_LEN); + + BUILD_BUG_ON(IEEE80211_TX_MAX_RATES < CARL9170_TX_MAX_RATES); + + BUILD_BUG_ON(AR9170_MAX_VIRTUAL_MAC > + ((CARL9170_TX_SUPER_MISC_VIF_ID >> + CARL9170_TX_SUPER_MISC_VIF_ID_S) + 1)); + + hw_queue = ar9170_qmap[carl9170_get_queue(ar, skb)]; + + hdr = (void *)skb->data; + info = IEEE80211_SKB_CB(skb); + len = skb->len; + + /* + * Note: If the frame was sent through a monitor interface, + * the ieee80211_vif pointer can be NULL. + */ + if (likely(info->control.vif)) + cvif = (void *) info->control.vif->drv_priv; + else + cvif = NULL; + + sta = info->control.sta; + + txc = (void *)skb_push(skb, sizeof(*txc)); + memset(txc, 0, sizeof(*txc)); + + SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, txc->s.misc, hw_queue); + + if (likely(cvif)) + SET_VAL(CARL9170_TX_SUPER_MISC_VIF_ID, txc->s.misc, cvif->id); + + if (unlikely(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM)) + txc->s.misc |= CARL9170_TX_SUPER_MISC_CAB; + + if (unlikely(ieee80211_is_probe_resp(hdr->frame_control))) + txc->s.misc |= CARL9170_TX_SUPER_MISC_FILL_IN_TSF; + + mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | + AR9170_TX_MAC_BACKOFF); + mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) && + AR9170_TX_MAC_QOS); + + no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); + if (unlikely(no_ack)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_NO_ACK); + + if (info->control.hw_key) { + len += info->control.hw_key->icv_len; + + switch (info->control.hw_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_ENCR_RC4); + break; + case WLAN_CIPHER_SUITE_CCMP: + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_ENCR_AES); + break; + default: + WARN_ON(1); + goto err_out; + } + } + + ampdu = !!(info->flags & IEEE80211_TX_CTL_AMPDU); + if (ampdu) { + unsigned int density, factor; + + if (unlikely(!sta || !cvif)) + goto err_out; + + factor = min_t(unsigned int, 1u, + info->control.sta->ht_cap.ampdu_factor); + + density = info->control.sta->ht_cap.ampdu_density; + + if (density) { + /* + * Watch out! + * + * Otus uses slightly different density values than + * those from the 802.11n spec. + */ + + density = max_t(unsigned int, density + 1, 7u); + } + + SET_VAL(CARL9170_TX_SUPER_AMPDU_DENSITY, + txc->s.ampdu_settings, density); + + SET_VAL(CARL9170_TX_SUPER_AMPDU_FACTOR, + txc->s.ampdu_settings, factor); + + for (i = 0; i < CARL9170_TX_MAX_RATES; i++) { + txrate = &info->control.rates[i]; + if (txrate->idx >= 0) { + txc->s.ri[i] = + CARL9170_TX_SUPER_RI_AMPDU; + + if (WARN_ON(!(txrate->flags & + IEEE80211_TX_RC_MCS))) { + /* + * Not sure if it's even possible + * to aggregate non-ht rates with + * this HW. + */ + goto err_out; + } + continue; + } + + txrate->idx = 0; + txrate->count = ar->hw->max_rate_tries; + } + + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_AGGR); + } + + /* + * NOTE: For the first rate, the ERP & AMPDU flags are directly + * taken from mac_control. For all fallback rate, the firmware + * updates the mac_control flags from the rate info field. + */ + for (i = 1; i < CARL9170_TX_MAX_RATES; i++) { + txrate = &info->control.rates[i]; + if (txrate->idx < 0) + break; + + SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[i], + txrate->count); + + if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) + txc->s.ri[i] |= (AR9170_TX_MAC_PROT_RTS << + CARL9170_TX_SUPER_RI_ERP_PROT_S); + else if (carl9170_tx_cts_check(ar, txrate)) + txc->s.ri[i] |= (AR9170_TX_MAC_PROT_CTS << + CARL9170_TX_SUPER_RI_ERP_PROT_S); + + txc->s.rr[i - 1] = carl9170_tx_physet(ar, info, txrate); + } + + txrate = &info->control.rates[0]; + SET_VAL(CARL9170_TX_SUPER_RI_TRIES, txc->s.ri[0], txrate->count); + + if (carl9170_tx_rts_check(ar, txrate, ampdu, no_ack)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS); + else if (carl9170_tx_cts_check(ar, txrate)) + mac_tmp |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS); + + txc->s.len = cpu_to_le16(skb->len); + txc->f.length = cpu_to_le16(len + FCS_LEN); + txc->f.mac_control = mac_tmp; + txc->f.phy_control = carl9170_tx_physet(ar, info, txrate); + + arinfo = (void *)info->rate_driver_data; + arinfo->timeout = jiffies; + arinfo->ar = ar; + kref_init(&arinfo->ref); + return 0; + +err_out: + skb_pull(skb, sizeof(*txc)); + return -EINVAL; +} + +static void carl9170_set_immba(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super; + + super = (void *) skb->data; + super->f.mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_BA); +} + +static void carl9170_set_ampdu_params(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super; + int tmp; + + super = (void *) skb->data; + + tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_DENSITY) << + CARL9170_TX_SUPER_AMPDU_DENSITY_S; + + /* + * If you haven't noticed carl9170_tx_prepare has already filled + * in all ampdu spacing & factor parameters. + * Now it's the time to check whenever the settings have to be + * updated by the firmware, or if everything is still the same. + * + * There's no sane way to handle different density values with + * this hardware, so we may as well just do the compare in the + * driver. + */ + + if (tmp != ar->current_density) { + ar->current_density = tmp; + super->s.ampdu_settings |= + CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY; + } + + tmp = (super->s.ampdu_settings & CARL9170_TX_SUPER_AMPDU_FACTOR) << + CARL9170_TX_SUPER_AMPDU_FACTOR_S; + + if (tmp != ar->current_factor) { + ar->current_factor = tmp; + super->s.ampdu_settings |= + CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR; + } +} + +static bool carl9170_tx_rate_check(struct ar9170 *ar, struct sk_buff *_dest, + struct sk_buff *_src) +{ + struct _carl9170_tx_superframe *dest, *src; + + dest = (void *) _dest->data; + src = (void *) _src->data; + + /* + * The mac80211 rate control algorithm expects that all MPDUs in + * an AMPDU share the same tx vectors. + * This is not really obvious right now, because the hardware + * does the AMPDU setup according to its own rulebook. + * Our nicely assembled, strictly monotonic increasing mpdu + * chains will be broken up, mashed back together... + */ + + return (dest->f.phy_control == src->f.phy_control); +} + +static void carl9170_tx_ampdu(struct ar9170 *ar) +{ + struct sk_buff_head agg; + struct carl9170_sta_tid *tid_info; + struct sk_buff *skb, *first; + unsigned int i = 0, done_ampdus = 0; + u16 seq, queue, tmpssn; + + atomic_inc(&ar->tx_ampdu_scheduler); + ar->tx_ampdu_schedule = false; + + if (atomic_read(&ar->tx_ampdu_upload)) + return; + + if (!ar->tx_ampdu_list_len) + return; + + __skb_queue_head_init(&agg); + + rcu_read_lock(); + tid_info = rcu_dereference(ar->tx_ampdu_iter); + if (WARN_ON_ONCE(!tid_info)) { + rcu_read_unlock(); + return; + } + +retry: + list_for_each_entry_continue_rcu(tid_info, &ar->tx_ampdu_list, list) { + i++; + + if (tid_info->state < CARL9170_TID_STATE_PROGRESS) + continue; + + queue = TID_TO_WME_AC(tid_info->tid); + + spin_lock_bh(&tid_info->lock); + if (tid_info->state != CARL9170_TID_STATE_XMIT) + goto processed; + + tid_info->counter++; + first = skb_peek(&tid_info->queue); + tmpssn = carl9170_get_seq(first); + seq = tid_info->snx; + + if (unlikely(tmpssn != seq)) { + tid_info->state = CARL9170_TID_STATE_IDLE; + + goto processed; + } + + while ((skb = skb_peek(&tid_info->queue))) { + /* strict 0, 1, ..., n - 1, n frame sequence order */ + if (unlikely(carl9170_get_seq(skb) != seq)) + break; + + /* don't upload more than AMPDU FACTOR allows. */ + if (unlikely(SEQ_DIFF(tid_info->snx, tid_info->bsn) >= + (tid_info->max - 1))) + break; + + if (!carl9170_tx_rate_check(ar, skb, first)) + break; + + atomic_inc(&ar->tx_ampdu_upload); + tid_info->snx = seq = SEQ_NEXT(seq); + __skb_unlink(skb, &tid_info->queue); + + __skb_queue_tail(&agg, skb); + + if (skb_queue_len(&agg) >= CARL9170_NUM_TX_AGG_MAX) + break; + } + + if (skb_queue_empty(&tid_info->queue) || + carl9170_get_seq(skb_peek(&tid_info->queue)) != + tid_info->snx) { + /* + * stop TID, if A-MPDU frames are still missing, + * or whenever the queue is empty. + */ + + tid_info->state = CARL9170_TID_STATE_IDLE; + } + done_ampdus++; + +processed: + spin_unlock_bh(&tid_info->lock); + + if (skb_queue_empty(&agg)) + continue; + + /* apply ampdu spacing & factor settings */ + carl9170_set_ampdu_params(ar, skb_peek(&agg)); + + /* set aggregation push bit */ + carl9170_set_immba(ar, skb_peek_tail(&agg)); + + spin_lock_bh(&ar->tx_pending[queue].lock); + skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]); + spin_unlock_bh(&ar->tx_pending[queue].lock); + ar->tx_schedule = true; + } + if ((done_ampdus++ == 0) && (i++ == 0)) + goto retry; + + rcu_assign_pointer(ar->tx_ampdu_iter, tid_info); + rcu_read_unlock(); +} + +static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar, + struct sk_buff_head *queue) +{ + struct sk_buff *skb; + struct ieee80211_tx_info *info; + struct carl9170_tx_info *arinfo; + + BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data)); + + spin_lock_bh(&queue->lock); + skb = skb_peek(queue); + if (unlikely(!skb)) + goto err_unlock; + + if (carl9170_alloc_dev_space(ar, skb)) + goto err_unlock; + + __skb_unlink(skb, queue); + spin_unlock_bh(&queue->lock); + + info = IEEE80211_SKB_CB(skb); + arinfo = (void *) info->rate_driver_data; + + arinfo->timeout = jiffies; + + /* + * increase ref count to "2". + * Ref counting is the easiest way to solve the race between + * the the urb's completion routine: carl9170_tx_callback and + * wlan tx status functions: carl9170_tx_status/janitor. + */ + carl9170_tx_get_skb(skb); + + return skb; + +err_unlock: + spin_unlock_bh(&queue->lock); + return NULL; +} + +void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb) +{ + struct _carl9170_tx_superframe *super; + uint8_t q = 0; + + ar->tx_dropped++; + + super = (void *)skb->data; + SET_VAL(CARL9170_TX_SUPER_MISC_QUEUE, q, + ar9170_qmap[carl9170_get_queue(ar, skb)]); + __carl9170_tx_process_status(ar, super->s.cookie, q); +} + +static void carl9170_tx(struct ar9170 *ar) +{ + struct sk_buff *skb; + unsigned int i, q; + bool schedule_garbagecollector = false; + + ar->tx_schedule = false; + + if (unlikely(!IS_STARTED(ar))) + return; + + carl9170_usb_handle_tx_err(ar); + + for (i = 0; i < ar->hw->queues; i++) { + while (!skb_queue_empty(&ar->tx_pending[i])) { + skb = carl9170_tx_pick_skb(ar, &ar->tx_pending[i]); + if (unlikely(!skb)) + break; + + atomic_inc(&ar->tx_total_pending); + + q = __carl9170_get_queue(ar, i); + /* + * NB: tx_status[i] vs. tx_status[q], + * TODO: Move into pick_skb or alloc_dev_space. + */ + skb_queue_tail(&ar->tx_status[q], skb); + + carl9170_usb_tx(ar, skb); + schedule_garbagecollector = true; + } + } + + if (!schedule_garbagecollector) + return; + + ieee80211_queue_delayed_work(ar->hw, &ar->tx_janitor, + msecs_to_jiffies(CARL9170_TX_TIMEOUT)); +} + +static bool carl9170_tx_ampdu_queue(struct ar9170 *ar, + struct ieee80211_sta *sta, struct sk_buff *skb) +{ + struct carl9170_sta_info *sta_info; + struct carl9170_sta_tid *agg; + struct sk_buff *iter; + unsigned int max; + u16 tid, seq, qseq, off; + bool run = false; + + tid = carl9170_get_tid(skb); + seq = carl9170_get_seq(skb); + sta_info = (void *) sta->drv_priv; + + rcu_read_lock(); + agg = rcu_dereference(sta_info->agg[tid]); + max = sta_info->ampdu_max_len; + + if (!agg) + goto err_unlock_rcu; + + spin_lock_bh(&agg->lock); + if (unlikely(agg->state < CARL9170_TID_STATE_IDLE)) + goto err_unlock; + + /* check if sequence is within the BA window */ + if (unlikely(!BAW_WITHIN(agg->bsn, CARL9170_BAW_BITS, seq))) + goto err_unlock; + + if (WARN_ON_ONCE(!BAW_WITHIN(agg->snx, CARL9170_BAW_BITS, seq))) + goto err_unlock; + + off = SEQ_DIFF(seq, agg->bsn); + if (WARN_ON_ONCE(test_and_set_bit(off, agg->bitmap))) + goto err_unlock; + + if (likely(BAW_WITHIN(agg->hsn, CARL9170_BAW_BITS, seq))) { + __skb_queue_tail(&agg->queue, skb); + agg->hsn = seq; + goto queued; + } + + skb_queue_reverse_walk(&agg->queue, iter) { + qseq = carl9170_get_seq(iter); + + if (BAW_WITHIN(qseq, CARL9170_BAW_BITS, seq)) { + __skb_queue_after(&agg->queue, iter, skb); + goto queued; + } + } + + __skb_queue_head(&agg->queue, skb); +queued: + + if (unlikely(agg->state != CARL9170_TID_STATE_XMIT)) { + if (agg->snx == carl9170_get_seq(skb_peek(&agg->queue))) { + agg->state = CARL9170_TID_STATE_XMIT; + run = true; + } + } + + spin_unlock_bh(&agg->lock); + rcu_read_unlock(); + + return run; + +err_unlock: + spin_unlock_bh(&agg->lock); + +err_unlock_rcu: + rcu_read_unlock(); + carl9170_tx_status(ar, skb, false); + ar->tx_dropped++; + return false; +} + +int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) +{ + struct ar9170 *ar = hw->priv; + struct ieee80211_tx_info *info; + struct ieee80211_sta *sta; + bool run; + + if (unlikely(!IS_STARTED(ar))) + goto err_free; + + info = IEEE80211_SKB_CB(skb); + sta = info->control.sta; + + if (unlikely(carl9170_tx_prepare(ar, skb))) + goto err_free; + + carl9170_tx_accounting(ar, skb); + /* + * from now on, one has to use carl9170_tx_status to free + * all ressouces which are associated with the frame. + */ + + if (info->flags & IEEE80211_TX_CTL_AMPDU) { + if (WARN_ON_ONCE(!sta)) + goto err_free; + + run = carl9170_tx_ampdu_queue(ar, sta, skb); + if (run) + carl9170_tx_ampdu(ar); + + } else { + unsigned int queue = skb_get_queue_mapping(skb); + + skb_queue_tail(&ar->tx_pending[queue], skb); + } + + carl9170_tx(ar); + return NETDEV_TX_OK; + +err_free: + ar->tx_dropped++; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} + +void carl9170_tx_scheduler(struct ar9170 *ar) +{ + + if (ar->tx_ampdu_schedule) + carl9170_tx_ampdu(ar); + + if (ar->tx_schedule) + carl9170_tx(ar); +} diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c new file mode 100644 index 0000000000000000000000000000000000000000..c7f6193934eaabe82cbe8cb5acdbd23afda48662 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -0,0 +1,1136 @@ +/* + * Atheros CARL9170 driver + * + * USB - frontend + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "carl9170.h" +#include "cmd.h" +#include "hw.h" +#include "fwcmd.h" + +MODULE_AUTHOR("Johannes Berg "); +MODULE_AUTHOR("Christian Lamparter "); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); +MODULE_FIRMWARE(CARL9170FW_NAME); +MODULE_ALIAS("ar9170usb"); +MODULE_ALIAS("arusb_lnx"); + +/* + * Note: + * + * Always update our wiki's device list (located at: + * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ), + * whenever you add a new device. + */ +static struct usb_device_id carl9170_usb_ids[] = { + /* Atheros 9170 */ + { USB_DEVICE(0x0cf3, 0x9170) }, + /* Atheros TG121N */ + { USB_DEVICE(0x0cf3, 0x1001) }, + /* TP-Link TL-WN821N v2 */ + { USB_DEVICE(0x0cf3, 0x1002), .driver_info = CARL9170_WPS_BUTTON | + CARL9170_ONE_LED }, + /* 3Com Dual Band 802.11n USB Adapter */ + { USB_DEVICE(0x0cf3, 0x1010) }, + /* H3C Dual Band 802.11n USB Adapter */ + { USB_DEVICE(0x0cf3, 0x1011) }, + /* Cace Airpcap NX */ + { USB_DEVICE(0xcace, 0x0300) }, + /* D-Link DWA 160 A1 */ + { USB_DEVICE(0x07d1, 0x3c10) }, + /* D-Link DWA 160 A2 */ + { USB_DEVICE(0x07d1, 0x3a09) }, + /* Netgear WNA1000 */ + { USB_DEVICE(0x0846, 0x9040) }, + /* Netgear WNDA3100 */ + { USB_DEVICE(0x0846, 0x9010) }, + /* Netgear WN111 v2 */ + { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED }, + /* Zydas ZD1221 */ + { USB_DEVICE(0x0ace, 0x1221) }, + /* Proxim ORiNOCO 802.11n USB */ + { USB_DEVICE(0x1435, 0x0804) }, + /* WNC Generic 11n USB Dongle */ + { USB_DEVICE(0x1435, 0x0326) }, + /* ZyXEL NWD271N */ + { USB_DEVICE(0x0586, 0x3417) }, + /* Z-Com UB81 BG */ + { USB_DEVICE(0x0cde, 0x0023) }, + /* Z-Com UB82 ABG */ + { USB_DEVICE(0x0cde, 0x0026) }, + /* Sphairon Homelink 1202 */ + { USB_DEVICE(0x0cde, 0x0027) }, + /* Arcadyan WN7512 */ + { USB_DEVICE(0x083a, 0xf522) }, + /* Planex GWUS300 */ + { USB_DEVICE(0x2019, 0x5304) }, + /* IO-Data WNGDNUS2 */ + { USB_DEVICE(0x04bb, 0x093f) }, + /* NEC WL300NU-G */ + { USB_DEVICE(0x0409, 0x0249) }, + /* AVM FRITZ!WLAN USB Stick N */ + { USB_DEVICE(0x057c, 0x8401) }, + /* AVM FRITZ!WLAN USB Stick N 2.4 */ + { USB_DEVICE(0x057c, 0x8402) }, + /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ + { USB_DEVICE(0x1668, 0x1200) }, + + /* terminate */ + {} +}; +MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); + +static void carl9170_usb_submit_data_urb(struct ar9170 *ar) +{ + struct urb *urb; + int err; + + if (atomic_inc_return(&ar->tx_anch_urbs) > AR9170_NUM_TX_URBS) + goto err_acc; + + urb = usb_get_from_anchor(&ar->tx_wait); + if (!urb) + goto err_acc; + + usb_anchor_urb(urb, &ar->tx_anch); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err)) { + if (net_ratelimit()) { + dev_err(&ar->udev->dev, "tx submit failed (%d)\n", + urb->status); + } + + usb_unanchor_urb(urb); + usb_anchor_urb(urb, &ar->tx_err); + } + + usb_free_urb(urb); + + if (likely(err == 0)) + return; + +err_acc: + atomic_dec(&ar->tx_anch_urbs); +} + +static void carl9170_usb_tx_data_complete(struct urb *urb) +{ + struct ar9170 *ar = (struct ar9170 *) + usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); + + if (WARN_ON_ONCE(!ar)) { + dev_kfree_skb_irq(urb->context); + return; + } + + atomic_dec(&ar->tx_anch_urbs); + + switch (urb->status) { + /* everything is fine */ + case 0: + carl9170_tx_callback(ar, (void *)urb->context); + break; + + /* disconnect */ + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + /* + * Defer the frame clean-up to the tasklet worker. + * This is necessary, because carl9170_tx_drop + * does not work in an irqsave context. + */ + usb_anchor_urb(urb, &ar->tx_err); + return; + + /* a random transmission error has occurred? */ + default: + if (net_ratelimit()) { + dev_err(&ar->udev->dev, "tx failed (%d)\n", + urb->status); + } + + usb_anchor_urb(urb, &ar->tx_err); + break; + } + + if (likely(IS_STARTED(ar))) + carl9170_usb_submit_data_urb(ar); +} + +static int carl9170_usb_submit_cmd_urb(struct ar9170 *ar) +{ + struct urb *urb; + int err; + + if (atomic_inc_return(&ar->tx_cmd_urbs) != 1) { + atomic_dec(&ar->tx_cmd_urbs); + return 0; + } + + urb = usb_get_from_anchor(&ar->tx_cmd); + if (!urb) { + atomic_dec(&ar->tx_cmd_urbs); + return 0; + } + + usb_anchor_urb(urb, &ar->tx_anch); + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err)) { + usb_unanchor_urb(urb); + atomic_dec(&ar->tx_cmd_urbs); + } + usb_free_urb(urb); + + return err; +} + +static void carl9170_usb_cmd_complete(struct urb *urb) +{ + struct ar9170 *ar = urb->context; + int err = 0; + + if (WARN_ON_ONCE(!ar)) + return; + + atomic_dec(&ar->tx_cmd_urbs); + + switch (urb->status) { + /* everything is fine */ + case 0: + break; + + /* disconnect */ + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + return; + + default: + err = urb->status; + break; + } + + if (!IS_INITIALIZED(ar)) + return; + + if (err) + dev_err(&ar->udev->dev, "submit cmd cb failed (%d).\n", err); + + err = carl9170_usb_submit_cmd_urb(ar); + if (err) + dev_err(&ar->udev->dev, "submit cmd failed (%d).\n", err); +} + +static void carl9170_usb_rx_irq_complete(struct urb *urb) +{ + struct ar9170 *ar = urb->context; + + if (WARN_ON_ONCE(!ar)) + return; + + switch (urb->status) { + /* everything is fine */ + case 0: + break; + + /* disconnect */ + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + return; + + default: + goto resubmit; + } + + carl9170_handle_command_response(ar, urb->transfer_buffer, + urb->actual_length); + +resubmit: + usb_anchor_urb(urb, &ar->rx_anch); + if (unlikely(usb_submit_urb(urb, GFP_ATOMIC))) + usb_unanchor_urb(urb); +} + +static int carl9170_usb_submit_rx_urb(struct ar9170 *ar, gfp_t gfp) +{ + struct urb *urb; + int err = 0, runs = 0; + + while ((atomic_read(&ar->rx_anch_urbs) < AR9170_NUM_RX_URBS) && + (runs++ < AR9170_NUM_RX_URBS)) { + err = -ENOSPC; + urb = usb_get_from_anchor(&ar->rx_pool); + if (urb) { + usb_anchor_urb(urb, &ar->rx_anch); + err = usb_submit_urb(urb, gfp); + if (unlikely(err)) { + usb_unanchor_urb(urb); + usb_anchor_urb(urb, &ar->rx_pool); + } else { + atomic_dec(&ar->rx_pool_urbs); + atomic_inc(&ar->rx_anch_urbs); + } + usb_free_urb(urb); + } + } + + return err; +} + +static void carl9170_usb_rx_work(struct ar9170 *ar) +{ + struct urb *urb; + int i; + + for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) { + urb = usb_get_from_anchor(&ar->rx_work); + if (!urb) + break; + + atomic_dec(&ar->rx_work_urbs); + if (IS_INITIALIZED(ar)) { + carl9170_rx(ar, urb->transfer_buffer, + urb->actual_length); + } + + usb_anchor_urb(urb, &ar->rx_pool); + atomic_inc(&ar->rx_pool_urbs); + + usb_free_urb(urb); + + carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC); + } +} + +void carl9170_usb_handle_tx_err(struct ar9170 *ar) +{ + struct urb *urb; + + while ((urb = usb_get_from_anchor(&ar->tx_err))) { + struct sk_buff *skb = (void *)urb->context; + + carl9170_tx_drop(ar, skb); + carl9170_tx_callback(ar, skb); + usb_free_urb(urb); + } +} + +static void carl9170_usb_tasklet(unsigned long data) +{ + struct ar9170 *ar = (struct ar9170 *) data; + + if (!IS_INITIALIZED(ar)) + return; + + carl9170_usb_rx_work(ar); + + /* + * Strictly speaking: The tx scheduler is not part of the USB system. + * But the rx worker returns frames back to the mac80211-stack and + * this is the _perfect_ place to generate the next transmissions. + */ + if (IS_STARTED(ar)) + carl9170_tx_scheduler(ar); +} + +static void carl9170_usb_rx_complete(struct urb *urb) +{ + struct ar9170 *ar = (struct ar9170 *)urb->context; + int err; + + if (WARN_ON_ONCE(!ar)) + return; + + atomic_dec(&ar->rx_anch_urbs); + + switch (urb->status) { + case 0: + /* rx path */ + usb_anchor_urb(urb, &ar->rx_work); + atomic_inc(&ar->rx_work_urbs); + break; + + case -ENOENT: + case -ECONNRESET: + case -ENODEV: + case -ESHUTDOWN: + /* handle disconnect events*/ + return; + + default: + /* handle all other errors */ + usb_anchor_urb(urb, &ar->rx_pool); + atomic_inc(&ar->rx_pool_urbs); + break; + } + + err = carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC); + if (unlikely(err)) { + /* + * usb_submit_rx_urb reported a problem. + * In case this is due to a rx buffer shortage, + * elevate the tasklet worker priority to + * the highest available level. + */ + tasklet_hi_schedule(&ar->usb_tasklet); + + if (atomic_read(&ar->rx_anch_urbs) == 0) { + /* + * The system is too slow to cope with + * the enormous workload. We have simply + * run out of active rx urbs and this + * unfortunatly leads to an unpredictable + * device. + */ + + carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM); + } + } else { + /* + * Using anything less than _high_ priority absolutely + * kills the rx performance my UP-System... + */ + tasklet_hi_schedule(&ar->usb_tasklet); + } +} + +static struct urb *carl9170_usb_alloc_rx_urb(struct ar9170 *ar, gfp_t gfp) +{ + struct urb *urb; + void *buf; + + buf = kmalloc(ar->fw.rx_size, gfp); + if (!buf) + return NULL; + + urb = usb_alloc_urb(0, gfp); + if (!urb) { + kfree(buf); + return NULL; + } + + usb_fill_bulk_urb(urb, ar->udev, usb_rcvbulkpipe(ar->udev, + AR9170_USB_EP_RX), buf, ar->fw.rx_size, + carl9170_usb_rx_complete, ar); + + urb->transfer_flags |= URB_FREE_BUFFER; + + return urb; +} + +static int carl9170_usb_send_rx_irq_urb(struct ar9170 *ar) +{ + struct urb *urb = NULL; + void *ibuf; + int err = -ENOMEM; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + goto out; + + ibuf = kmalloc(AR9170_USB_EP_CTRL_MAX, GFP_KERNEL); + if (!ibuf) + goto out; + + usb_fill_int_urb(urb, ar->udev, usb_rcvintpipe(ar->udev, + AR9170_USB_EP_IRQ), ibuf, AR9170_USB_EP_CTRL_MAX, + carl9170_usb_rx_irq_complete, ar, 1); + + urb->transfer_flags |= URB_FREE_BUFFER; + + usb_anchor_urb(urb, &ar->rx_anch); + err = usb_submit_urb(urb, GFP_KERNEL); + if (err) + usb_unanchor_urb(urb); + +out: + usb_free_urb(urb); + return err; +} + +static int carl9170_usb_init_rx_bulk_urbs(struct ar9170 *ar) +{ + struct urb *urb; + int i, err = -EINVAL; + + /* + * The driver actively maintains a second shadow + * pool for inactive, but fully-prepared rx urbs. + * + * The pool should help the driver to master huge + * workload spikes without running the risk of + * undersupplying the hardware or wasting time by + * processing rx data (streams) inside the urb + * completion (hardirq context). + */ + for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) { + urb = carl9170_usb_alloc_rx_urb(ar, GFP_KERNEL); + if (!urb) { + err = -ENOMEM; + goto err_out; + } + + usb_anchor_urb(urb, &ar->rx_pool); + atomic_inc(&ar->rx_pool_urbs); + usb_free_urb(urb); + } + + err = carl9170_usb_submit_rx_urb(ar, GFP_KERNEL); + if (err) + goto err_out; + + /* the device now waiting for the firmware. */ + carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE); + return 0; + +err_out: + + usb_scuttle_anchored_urbs(&ar->rx_pool); + usb_scuttle_anchored_urbs(&ar->rx_work); + usb_kill_anchored_urbs(&ar->rx_anch); + return err; +} + +static int carl9170_usb_flush(struct ar9170 *ar) +{ + struct urb *urb; + int ret, err = 0; + + while ((urb = usb_get_from_anchor(&ar->tx_wait))) { + struct sk_buff *skb = (void *)urb->context; + carl9170_tx_drop(ar, skb); + carl9170_tx_callback(ar, skb); + usb_free_urb(urb); + } + + ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, HZ); + if (ret == 0) + err = -ETIMEDOUT; + + /* lets wait a while until the tx - queues are dried out */ + ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, HZ); + if (ret == 0) + err = -ETIMEDOUT; + + usb_kill_anchored_urbs(&ar->tx_anch); + carl9170_usb_handle_tx_err(ar); + + return err; +} + +static void carl9170_usb_cancel_urbs(struct ar9170 *ar) +{ + int err; + + carl9170_set_state(ar, CARL9170_UNKNOWN_STATE); + + err = carl9170_usb_flush(ar); + if (err) + dev_err(&ar->udev->dev, "stuck tx urbs!\n"); + + usb_poison_anchored_urbs(&ar->tx_anch); + carl9170_usb_handle_tx_err(ar); + usb_poison_anchored_urbs(&ar->rx_anch); + + tasklet_kill(&ar->usb_tasklet); + + usb_scuttle_anchored_urbs(&ar->rx_work); + usb_scuttle_anchored_urbs(&ar->rx_pool); + usb_scuttle_anchored_urbs(&ar->tx_cmd); +} + +int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, + const bool free_buf) +{ + struct urb *urb; + + if (!IS_INITIALIZED(ar)) + return -EPERM; + + if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) + return -EINVAL; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + return -ENOMEM; + + usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, + AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, + carl9170_usb_cmd_complete, ar, 1); + + if (free_buf) + urb->transfer_flags |= URB_FREE_BUFFER; + + usb_anchor_urb(urb, &ar->tx_cmd); + usb_free_urb(urb); + + return carl9170_usb_submit_cmd_urb(ar); +} + +int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, + unsigned int plen, void *payload, unsigned int outlen, void *out) +{ + int err = -ENOMEM; + + if (!IS_ACCEPTING_CMD(ar)) + return -EIO; + + if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) + might_sleep(); + + ar->cmd.hdr.len = plen; + ar->cmd.hdr.cmd = cmd; + /* writing multiple regs fills this buffer already */ + if (plen && payload != (u8 *)(ar->cmd.data)) + memcpy(ar->cmd.data, payload, plen); + + spin_lock_bh(&ar->cmd_lock); + ar->readbuf = (u8 *)out; + ar->readlen = outlen; + spin_unlock_bh(&ar->cmd_lock); + + err = __carl9170_exec_cmd(ar, &ar->cmd, false); + + if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) { + err = wait_for_completion_timeout(&ar->cmd_wait, HZ); + if (err == 0) { + err = -ETIMEDOUT; + goto err_unbuf; + } + + if (ar->readlen != outlen) { + err = -EMSGSIZE; + goto err_unbuf; + } + } + + return 0; + +err_unbuf: + /* Maybe the device was removed in the moment we were waiting? */ + if (IS_STARTED(ar)) { + dev_err(&ar->udev->dev, "no command feedback " + "received (%d).\n", err); + + /* provide some maybe useful debug information */ + print_hex_dump_bytes("carl9170 cmd: ", DUMP_PREFIX_NONE, + &ar->cmd, plen + 4); + + carl9170_restart(ar, CARL9170_RR_COMMAND_TIMEOUT); + } + + /* invalidate to avoid completing the next command prematurely */ + spin_lock_bh(&ar->cmd_lock); + ar->readbuf = NULL; + ar->readlen = 0; + spin_unlock_bh(&ar->cmd_lock); + + return err; +} + +void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) +{ + struct urb *urb; + struct ar9170_stream *tx_stream; + void *data; + unsigned int len; + + if (!IS_STARTED(ar)) + goto err_drop; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + goto err_drop; + + if (ar->fw.tx_stream) { + tx_stream = (void *) (skb->data - sizeof(*tx_stream)); + + len = skb->len + sizeof(*tx_stream); + tx_stream->length = cpu_to_le16(len); + tx_stream->tag = cpu_to_le16(AR9170_TX_STREAM_TAG); + data = tx_stream; + } else { + data = skb->data; + len = skb->len; + } + + usb_fill_bulk_urb(urb, ar->udev, usb_sndbulkpipe(ar->udev, + AR9170_USB_EP_TX), data, len, + carl9170_usb_tx_data_complete, skb); + + urb->transfer_flags |= URB_ZERO_PACKET; + + usb_anchor_urb(urb, &ar->tx_wait); + + usb_free_urb(urb); + + carl9170_usb_submit_data_urb(ar); + return; + +err_drop: + carl9170_tx_drop(ar, skb); + carl9170_tx_callback(ar, skb); +} + +static void carl9170_release_firmware(struct ar9170 *ar) +{ + if (ar->fw.fw) { + release_firmware(ar->fw.fw); + memset(&ar->fw, 0, sizeof(ar->fw)); + } +} + +void carl9170_usb_stop(struct ar9170 *ar) +{ + int ret; + + carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STOPPED); + + ret = carl9170_usb_flush(ar); + if (ret) + dev_err(&ar->udev->dev, "kill pending tx urbs.\n"); + + usb_poison_anchored_urbs(&ar->tx_anch); + carl9170_usb_handle_tx_err(ar); + + /* kill any pending command */ + spin_lock_bh(&ar->cmd_lock); + ar->readlen = 0; + spin_unlock_bh(&ar->cmd_lock); + complete_all(&ar->cmd_wait); + + /* This is required to prevent an early completion on _start */ + INIT_COMPLETION(ar->cmd_wait); + + /* + * Note: + * So far we freed all tx urbs, but we won't dare to touch any rx urbs. + * Else we would end up with a unresponsive device... + */ +} + +int carl9170_usb_open(struct ar9170 *ar) +{ + usb_unpoison_anchored_urbs(&ar->tx_anch); + + carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE); + return 0; +} + +static int carl9170_usb_load_firmware(struct ar9170 *ar) +{ + const u8 *data; + u8 *buf; + unsigned int transfer; + size_t len; + u32 addr; + int err = 0; + + buf = kmalloc(4096, GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto err_out; + } + + data = ar->fw.fw->data; + len = ar->fw.fw->size; + addr = ar->fw.address; + + /* this removes the miniboot image */ + data += ar->fw.offset; + len -= ar->fw.offset; + + while (len) { + transfer = min_t(unsigned int, len, 4096u); + memcpy(buf, data, transfer); + + err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0), + 0x30 /* FW DL */, 0x40 | USB_DIR_OUT, + addr >> 8, 0, buf, transfer, 100); + + if (err < 0) { + kfree(buf); + goto err_out; + } + + len -= transfer; + data += transfer; + addr += transfer; + } + kfree(buf); + + err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0), + 0x31 /* FW DL COMPLETE */, + 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 200); + + if (wait_for_completion_timeout(&ar->fw_boot_wait, HZ) == 0) { + err = -ETIMEDOUT; + goto err_out; + } + + err = carl9170_echo_test(ar, 0x4a110123); + if (err) + goto err_out; + + /* firmware restarts cmd counter */ + ar->cmd_seq = -1; + + return 0; + +err_out: + dev_err(&ar->udev->dev, "firmware upload failed (%d).\n", err); + return err; +} + +int carl9170_usb_restart(struct ar9170 *ar) +{ + int err = 0; + + if (ar->intf->condition != USB_INTERFACE_BOUND) + return 0; + + /* Disable command response sequence counter. */ + ar->cmd_seq = -2; + + err = carl9170_reboot(ar); + + carl9170_usb_stop(ar); + + if (err) + goto err_out; + + tasklet_schedule(&ar->usb_tasklet); + + /* The reboot procedure can take quite a while to complete. */ + msleep(1100); + + err = carl9170_usb_open(ar); + if (err) + goto err_out; + + err = carl9170_usb_load_firmware(ar); + if (err) + goto err_out; + + return 0; + +err_out: + carl9170_usb_cancel_urbs(ar); + return err; +} + +void carl9170_usb_reset(struct ar9170 *ar) +{ + /* + * This is the last resort to get the device going again + * without any *user replugging action*. + * + * But there is a catch: usb_reset really is like a physical + * *reconnect*. The mac80211 state will be lost in the process. + * Therefore a userspace application, which is monitoring + * the link must step in. + */ + carl9170_usb_cancel_urbs(ar); + + carl9170_usb_stop(ar); + + usb_queue_reset_device(ar->intf); +} + +static int carl9170_usb_init_device(struct ar9170 *ar) +{ + int err; + + err = carl9170_usb_send_rx_irq_urb(ar); + if (err) + goto err_out; + + err = carl9170_usb_init_rx_bulk_urbs(ar); + if (err) + goto err_unrx; + + mutex_lock(&ar->mutex); + err = carl9170_usb_load_firmware(ar); + mutex_unlock(&ar->mutex); + if (err) + goto err_unrx; + + return 0; + +err_unrx: + carl9170_usb_cancel_urbs(ar); + +err_out: + return err; +} + +static void carl9170_usb_firmware_failed(struct ar9170 *ar) +{ + struct device *parent = ar->udev->dev.parent; + struct usb_device *udev; + + /* + * Store a copy of the usb_device pointer locally. + * This is because device_release_driver initiates + * carl9170_usb_disconnect, which in turn frees our + * driver context (ar). + */ + udev = ar->udev; + + complete(&ar->fw_load_wait); + + /* unbind anything failed */ + if (parent) + device_lock(parent); + + device_release_driver(&udev->dev); + if (parent) + device_unlock(parent); + + usb_put_dev(udev); +} + +static void carl9170_usb_firmware_finish(struct ar9170 *ar) +{ + int err; + + err = carl9170_parse_firmware(ar); + if (err) + goto err_freefw; + + err = carl9170_usb_init_device(ar); + if (err) + goto err_freefw; + + err = carl9170_usb_open(ar); + if (err) + goto err_unrx; + + err = carl9170_register(ar); + + carl9170_usb_stop(ar); + if (err) + goto err_unrx; + + complete(&ar->fw_load_wait); + usb_put_dev(ar->udev); + return; + +err_unrx: + carl9170_usb_cancel_urbs(ar); + +err_freefw: + carl9170_release_firmware(ar); + carl9170_usb_firmware_failed(ar); +} + +static void carl9170_usb_firmware_step2(const struct firmware *fw, + void *context) +{ + struct ar9170 *ar = context; + + if (fw) { + ar->fw.fw = fw; + carl9170_usb_firmware_finish(ar); + return; + } + + dev_err(&ar->udev->dev, "firmware not found.\n"); + carl9170_usb_firmware_failed(ar); +} + +static int carl9170_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct ar9170 *ar; + struct usb_device *udev; + int err; + + err = usb_reset_device(interface_to_usbdev(intf)); + if (err) + return err; + + ar = carl9170_alloc(sizeof(*ar)); + if (IS_ERR(ar)) + return PTR_ERR(ar); + + udev = interface_to_usbdev(intf); + usb_get_dev(udev); + ar->udev = udev; + ar->intf = intf; + ar->features = id->driver_info; + + usb_set_intfdata(intf, ar); + SET_IEEE80211_DEV(ar->hw, &intf->dev); + + init_usb_anchor(&ar->rx_anch); + init_usb_anchor(&ar->rx_pool); + init_usb_anchor(&ar->rx_work); + init_usb_anchor(&ar->tx_wait); + init_usb_anchor(&ar->tx_anch); + init_usb_anchor(&ar->tx_cmd); + init_usb_anchor(&ar->tx_err); + init_completion(&ar->cmd_wait); + init_completion(&ar->fw_boot_wait); + init_completion(&ar->fw_load_wait); + tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet, + (unsigned long)ar); + + atomic_set(&ar->tx_cmd_urbs, 0); + atomic_set(&ar->tx_anch_urbs, 0); + atomic_set(&ar->rx_work_urbs, 0); + atomic_set(&ar->rx_anch_urbs, 0); + atomic_set(&ar->rx_pool_urbs, 0); + ar->cmd_seq = -2; + + usb_get_dev(ar->udev); + + carl9170_set_state(ar, CARL9170_STOPPED); + + return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, + &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); +} + +static void carl9170_usb_disconnect(struct usb_interface *intf) +{ + struct ar9170 *ar = usb_get_intfdata(intf); + struct usb_device *udev; + + if (WARN_ON(!ar)) + return; + + udev = ar->udev; + wait_for_completion(&ar->fw_load_wait); + + if (IS_INITIALIZED(ar)) { + carl9170_reboot(ar); + carl9170_usb_stop(ar); + } + + carl9170_usb_cancel_urbs(ar); + carl9170_unregister(ar); + + usb_set_intfdata(intf, NULL); + + carl9170_release_firmware(ar); + carl9170_free(ar); + usb_put_dev(udev); +} + +#ifdef CONFIG_PM +static int carl9170_usb_suspend(struct usb_interface *intf, + pm_message_t message) +{ + struct ar9170 *ar = usb_get_intfdata(intf); + + if (!ar) + return -ENODEV; + + carl9170_usb_cancel_urbs(ar); + + /* + * firmware automatically reboots for usb suspend. + */ + + return 0; +} + +static int carl9170_usb_resume(struct usb_interface *intf) +{ + struct ar9170 *ar = usb_get_intfdata(intf); + int err; + + if (!ar) + return -ENODEV; + + usb_unpoison_anchored_urbs(&ar->rx_anch); + + err = carl9170_usb_init_device(ar); + if (err) + goto err_unrx; + + err = carl9170_usb_open(ar); + if (err) + goto err_unrx; + + return 0; + +err_unrx: + carl9170_usb_cancel_urbs(ar); + + return err; +} +#endif /* CONFIG_PM */ + +static struct usb_driver carl9170_driver = { + .name = KBUILD_MODNAME, + .probe = carl9170_usb_probe, + .disconnect = carl9170_usb_disconnect, + .id_table = carl9170_usb_ids, + .soft_unbind = 1, +#ifdef CONFIG_PM + .suspend = carl9170_usb_suspend, + .resume = carl9170_usb_resume, +#endif /* CONFIG_PM */ +}; + +static int __init carl9170_usb_init(void) +{ + return usb_register(&carl9170_driver); +} + +static void __exit carl9170_usb_exit(void) +{ + usb_deregister(&carl9170_driver); +} + +module_init(carl9170_usb_init); +module_exit(carl9170_usb_exit); diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h new file mode 100644 index 0000000000000000000000000000000000000000..ff53f078a0b5eaff1080bd7e27840940ae1cc0d1 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/version.h @@ -0,0 +1,7 @@ +#ifndef __CARL9170_SHARED_VERSION_H +#define __CARL9170_SHARED_VERSION_H +#define CARL9170FW_VERSION_YEAR 10 +#define CARL9170FW_VERSION_MONTH 9 +#define CARL9170FW_VERSION_DAY 28 +#define CARL9170FW_VERSION_GIT "1.8.8.3" +#endif /* __CARL9170_SHARED_VERSION_H */ diff --git a/drivers/net/wireless/ath/carl9170/wlan.h b/drivers/net/wireless/ath/carl9170/wlan.h new file mode 100644 index 0000000000000000000000000000000000000000..24d63b583b6b08459d657055d70836c621106177 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/wlan.h @@ -0,0 +1,420 @@ +/* + * Shared Atheros AR9170 Header + * + * RX/TX meta descriptor format + * + * Copyright 2008, Johannes Berg + * Copyright 2009, 2010, Christian Lamparter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, see + * http://www.gnu.org/licenses/. + * + * This file incorporates work covered by the following copyright and + * permission notice: + * Copyright (c) 2007-2008 Atheros Communications, Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __CARL9170_SHARED_WLAN_H +#define __CARL9170_SHARED_WLAN_H + +#include "fwcmd.h" + +#define AR9170_RX_PHY_RATE_CCK_1M 0x0a +#define AR9170_RX_PHY_RATE_CCK_2M 0x14 +#define AR9170_RX_PHY_RATE_CCK_5M 0x37 +#define AR9170_RX_PHY_RATE_CCK_11M 0x6e + +#define AR9170_ENC_ALG_NONE 0x0 +#define AR9170_ENC_ALG_WEP64 0x1 +#define AR9170_ENC_ALG_TKIP 0x2 +#define AR9170_ENC_ALG_AESCCMP 0x4 +#define AR9170_ENC_ALG_WEP128 0x5 +#define AR9170_ENC_ALG_WEP256 0x6 +#define AR9170_ENC_ALG_CENC 0x7 + +#define AR9170_RX_ENC_SOFTWARE 0x8 + +#define AR9170_RX_STATUS_MODULATION 0x03 +#define AR9170_RX_STATUS_MODULATION_S 0 +#define AR9170_RX_STATUS_MODULATION_CCK 0x00 +#define AR9170_RX_STATUS_MODULATION_OFDM 0x01 +#define AR9170_RX_STATUS_MODULATION_HT 0x02 +#define AR9170_RX_STATUS_MODULATION_DUPOFDM 0x03 + +/* depends on modulation */ +#define AR9170_RX_STATUS_SHORT_PREAMBLE 0x08 +#define AR9170_RX_STATUS_GREENFIELD 0x08 + +#define AR9170_RX_STATUS_MPDU 0x30 +#define AR9170_RX_STATUS_MPDU_S 4 +#define AR9170_RX_STATUS_MPDU_SINGLE 0x00 +#define AR9170_RX_STATUS_MPDU_FIRST 0x20 +#define AR9170_RX_STATUS_MPDU_MIDDLE 0x30 +#define AR9170_RX_STATUS_MPDU_LAST 0x10 + +#define AR9170_RX_STATUS_CONT_AGGR 0x40 +#define AR9170_RX_STATUS_TOTAL_ERROR 0x80 + +#define AR9170_RX_ERROR_RXTO 0x01 +#define AR9170_RX_ERROR_OVERRUN 0x02 +#define AR9170_RX_ERROR_DECRYPT 0x04 +#define AR9170_RX_ERROR_FCS 0x08 +#define AR9170_RX_ERROR_WRONG_RA 0x10 +#define AR9170_RX_ERROR_PLCP 0x20 +#define AR9170_RX_ERROR_MMIC 0x40 + +/* these are either-or */ +#define AR9170_TX_MAC_PROT_RTS 0x0001 +#define AR9170_TX_MAC_PROT_CTS 0x0002 +#define AR9170_TX_MAC_PROT 0x0003 + +#define AR9170_TX_MAC_NO_ACK 0x0004 +/* if unset, MAC will only do SIFS space before frame */ +#define AR9170_TX_MAC_BACKOFF 0x0008 +#define AR9170_TX_MAC_BURST 0x0010 +#define AR9170_TX_MAC_AGGR 0x0020 + +/* encryption is a two-bit field */ +#define AR9170_TX_MAC_ENCR_NONE 0x0000 +#define AR9170_TX_MAC_ENCR_RC4 0x0040 +#define AR9170_TX_MAC_ENCR_CENC 0x0080 +#define AR9170_TX_MAC_ENCR_AES 0x00c0 + +#define AR9170_TX_MAC_MMIC 0x0100 +#define AR9170_TX_MAC_HW_DURATION 0x0200 +#define AR9170_TX_MAC_QOS_S 10 +#define AR9170_TX_MAC_QOS 0x0c00 +#define AR9170_TX_MAC_DISABLE_TXOP 0x1000 +#define AR9170_TX_MAC_TXOP_RIFS 0x2000 +#define AR9170_TX_MAC_IMM_BA 0x4000 + +/* either-or */ +#define AR9170_TX_PHY_MOD_CCK 0x00000000 +#define AR9170_TX_PHY_MOD_OFDM 0x00000001 +#define AR9170_TX_PHY_MOD_HT 0x00000002 + +/* depends on modulation */ +#define AR9170_TX_PHY_SHORT_PREAMBLE 0x00000004 +#define AR9170_TX_PHY_GREENFIELD 0x00000004 + +#define AR9170_TX_PHY_BW_S 3 +#define AR9170_TX_PHY_BW (3 << AR9170_TX_PHY_BW_SHIFT) +#define AR9170_TX_PHY_BW_20MHZ 0 +#define AR9170_TX_PHY_BW_40MHZ 2 +#define AR9170_TX_PHY_BW_40MHZ_DUP 3 + +#define AR9170_TX_PHY_TX_HEAVY_CLIP_S 6 +#define AR9170_TX_PHY_TX_HEAVY_CLIP (7 << \ + AR9170_TX_PHY_TX_HEAVY_CLIP_S) + +#define AR9170_TX_PHY_TX_PWR_S 9 +#define AR9170_TX_PHY_TX_PWR (0x3f << \ + AR9170_TX_PHY_TX_PWR_S) + +#define AR9170_TX_PHY_TXCHAIN_S 15 +#define AR9170_TX_PHY_TXCHAIN (7 << \ + AR9170_TX_PHY_TXCHAIN_S) +#define AR9170_TX_PHY_TXCHAIN_1 1 +/* use for cck, ofdm 6/9/12/18/24 and HT if capable */ +#define AR9170_TX_PHY_TXCHAIN_2 5 + +#define AR9170_TX_PHY_MCS_S 18 +#define AR9170_TX_PHY_MCS (0x7f << \ + AR9170_TX_PHY_MCS_S) + +#define AR9170_TX_PHY_RATE_CCK_1M 0x0 +#define AR9170_TX_PHY_RATE_CCK_2M 0x1 +#define AR9170_TX_PHY_RATE_CCK_5M 0x2 +#define AR9170_TX_PHY_RATE_CCK_11M 0x3 + +/* same as AR9170_RX_PHY_RATE */ +#define AR9170_TXRX_PHY_RATE_OFDM_6M 0xb +#define AR9170_TXRX_PHY_RATE_OFDM_9M 0xf +#define AR9170_TXRX_PHY_RATE_OFDM_12M 0xa +#define AR9170_TXRX_PHY_RATE_OFDM_18M 0xe +#define AR9170_TXRX_PHY_RATE_OFDM_24M 0x9 +#define AR9170_TXRX_PHY_RATE_OFDM_36M 0xd +#define AR9170_TXRX_PHY_RATE_OFDM_48M 0x8 +#define AR9170_TXRX_PHY_RATE_OFDM_54M 0xc + +#define AR9170_TXRX_PHY_RATE_HT_MCS0 0x0 +#define AR9170_TXRX_PHY_RATE_HT_MCS1 0x1 +#define AR9170_TXRX_PHY_RATE_HT_MCS2 0x2 +#define AR9170_TXRX_PHY_RATE_HT_MCS3 0x3 +#define AR9170_TXRX_PHY_RATE_HT_MCS4 0x4 +#define AR9170_TXRX_PHY_RATE_HT_MCS5 0x5 +#define AR9170_TXRX_PHY_RATE_HT_MCS6 0x6 +#define AR9170_TXRX_PHY_RATE_HT_MCS7 0x7 +#define AR9170_TXRX_PHY_RATE_HT_MCS8 0x8 +#define AR9170_TXRX_PHY_RATE_HT_MCS9 0x9 +#define AR9170_TXRX_PHY_RATE_HT_MCS10 0xa +#define AR9170_TXRX_PHY_RATE_HT_MCS11 0xb +#define AR9170_TXRX_PHY_RATE_HT_MCS12 0xc +#define AR9170_TXRX_PHY_RATE_HT_MCS13 0xd +#define AR9170_TXRX_PHY_RATE_HT_MCS14 0xe +#define AR9170_TXRX_PHY_RATE_HT_MCS15 0xf + +#define AR9170_TX_PHY_SHORT_GI 0x80000000 + +#ifdef __CARL9170FW__ +struct ar9170_tx_hw_mac_control { + union { + struct { + /* + * Beware of compiler bugs in all gcc pre 4.4! + */ + + u8 erp_prot:2; + u8 no_ack:1; + u8 backoff:1; + u8 burst:1; + u8 ampdu:1; + + u8 enc_mode:2; + + u8 hw_mmic:1; + u8 hw_duration:1; + + u8 qos_queue:2; + + u8 disable_txop:1; + u8 txop_rifs:1; + + u8 ba_end:1; + u8 probe:1; + } __packed; + + __le16 set; + } __packed; +} __packed; + +struct ar9170_tx_hw_phy_control { + union { + struct { + /* + * Beware of compiler bugs in all gcc pre 4.4! + */ + + u8 modulation:2; + u8 preamble:1; + u8 bandwidth:2; + u8:1; + u8 heavy_clip:3; + u8 tx_power:6; + u8 chains:3; + u8 mcs:7; + u8:6; + u8 short_gi:1; + } __packed; + + __le32 set; + } __packed; +} __packed; + +struct ar9170_tx_rate_info { + u8 tries:3; + u8 erp_prot:2; + u8 ampdu:1; + u8 free:2; /* free for use (e.g.:RIFS/TXOP/AMPDU) */ +} __packed; + +struct carl9170_tx_superdesc { + __le16 len; + u8 rix; + u8 cnt; + u8 cookie; + u8 ampdu_density:3; + u8 ampdu_factor:2; + u8 ampdu_commit_density:1; + u8 ampdu_commit_factor:1; + u8 ampdu_unused_bit:1; + u8 queue:2; + u8 reserved:1; + u8 vif_id:3; + u8 fill_in_tsf:1; + u8 cab:1; + u8 padding2; + struct ar9170_tx_rate_info ri[CARL9170_TX_MAX_RATES]; + struct ar9170_tx_hw_phy_control rr[CARL9170_TX_MAX_RETRY_RATES]; +} __packed; + +struct ar9170_tx_hwdesc { + __le16 length; + struct ar9170_tx_hw_mac_control mac; + struct ar9170_tx_hw_phy_control phy; +} __packed; + +struct ar9170_tx_frame { + struct ar9170_tx_hwdesc hdr; + + union { + struct ieee80211_hdr i3e; + u8 payload[0]; + } data; +} __packed; + +struct carl9170_tx_superframe { + struct carl9170_tx_superdesc s; + struct ar9170_tx_frame f; +} __packed; + +#endif /* __CARL9170FW__ */ + +struct _ar9170_tx_hwdesc { + __le16 length; + __le16 mac_control; + __le32 phy_control; +} __packed; + +#define CARL9170_TX_SUPER_AMPDU_DENSITY_S 0 +#define CARL9170_TX_SUPER_AMPDU_DENSITY 0x7 +#define CARL9170_TX_SUPER_AMPDU_FACTOR 0x18 +#define CARL9170_TX_SUPER_AMPDU_FACTOR_S 3 +#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY 0x20 +#define CARL9170_TX_SUPER_AMPDU_COMMIT_DENSITY_S 5 +#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR 0x40 +#define CARL9170_TX_SUPER_AMPDU_COMMIT_FACTOR_S 6 + +#define CARL9170_TX_SUPER_MISC_QUEUE 0x3 +#define CARL9170_TX_SUPER_MISC_QUEUE_S 0 +#define CARL9170_TX_SUPER_MISC_VIF_ID 0x38 +#define CARL9170_TX_SUPER_MISC_VIF_ID_S 3 +#define CARL9170_TX_SUPER_MISC_FILL_IN_TSF 0x40 +#define CARL9170_TX_SUPER_MISC_CAB 0x80 + +#define CARL9170_TX_SUPER_RI_TRIES 0x7 +#define CARL9170_TX_SUPER_RI_TRIES_S 0 +#define CARL9170_TX_SUPER_RI_ERP_PROT 0x18 +#define CARL9170_TX_SUPER_RI_ERP_PROT_S 3 +#define CARL9170_TX_SUPER_RI_AMPDU 0x20 +#define CARL9170_TX_SUPER_RI_AMPDU_S 5 + +struct _carl9170_tx_superdesc { + __le16 len; + u8 rix; + u8 cnt; + u8 cookie; + u8 ampdu_settings; + u8 misc; + u8 padding; + u8 ri[CARL9170_TX_MAX_RATES]; + __le32 rr[CARL9170_TX_MAX_RETRY_RATES]; +} __packed; + +struct _carl9170_tx_superframe { + struct _carl9170_tx_superdesc s; + struct _ar9170_tx_hwdesc f; + u8 frame_data[0]; +} __packed; + +#define CARL9170_TX_SUPERDESC_LEN 24 +#define AR9170_TX_HWDESC_LEN 8 +#define CARL9170_TX_SUPERFRAME_LEN (CARL9170_TX_SUPERDESC_LEN + \ + AR9170_TX_HWDESC_LEN) + +struct ar9170_rx_head { + u8 plcp[12]; +} __packed; + +#define AR9170_RX_HEAD_LEN 12 + +struct ar9170_rx_phystatus { + union { + struct { + u8 rssi_ant0, rssi_ant1, rssi_ant2, + rssi_ant0x, rssi_ant1x, rssi_ant2x, + rssi_combined; + } __packed; + u8 rssi[7]; + } __packed; + + u8 evm_stream0[6], evm_stream1[6]; + u8 phy_err; +} __packed; + +#define AR9170_RX_PHYSTATUS_LEN 20 + +struct ar9170_rx_macstatus { + u8 SAidx, DAidx; + u8 error; + u8 status; +} __packed; + +#define AR9170_RX_MACSTATUS_LEN 4 + +struct ar9170_rx_frame_single { + struct ar9170_rx_head phy_head; + struct ieee80211_hdr i3e; + struct ar9170_rx_phystatus phy_tail; + struct ar9170_rx_macstatus macstatus; +} __packed; + +struct ar9170_rx_frame_head { + struct ar9170_rx_head phy_head; + struct ieee80211_hdr i3e; + struct ar9170_rx_macstatus macstatus; +} __packed; + +struct ar9170_rx_frame_middle { + struct ieee80211_hdr i3e; + struct ar9170_rx_macstatus macstatus; +} __packed; + +struct ar9170_rx_frame_tail { + struct ieee80211_hdr i3e; + struct ar9170_rx_phystatus phy_tail; + struct ar9170_rx_macstatus macstatus; +} __packed; + +struct ar9170_rx_frame { + union { + struct ar9170_rx_frame_single single; + struct ar9170_rx_frame_head head; + struct ar9170_rx_frame_middle middle; + struct ar9170_rx_frame_tail tail; + } __packed; +} __packed; + +static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t) +{ + return (t->SAidx & 0xc0) >> 4 | + (t->DAidx & 0xc0) >> 6; +} + +enum ar9170_txq { + AR9170_TXQ_BE, + + AR9170_TXQ_VI, + AR9170_TXQ_VO, + AR9170_TXQ_BK, + + __AR9170_NUM_TXQ, +}; + +static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 2, 1, 0, 3 }; + +#define AR9170_TXQ_DEPTH 32 + +#endif /* __CARL9170_SHARED_WLAN_H */ diff --git a/drivers/net/wireless/ath/debug.c b/drivers/net/wireless/ath/debug.c index 53e77bd131b925937cd432f347b31e16855be9a8..dacfb234f491053278dce7b502f763d07bda4d48 100644 --- a/drivers/net/wireless/ath/debug.c +++ b/drivers/net/wireless/ath/debug.c @@ -30,3 +30,32 @@ void ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) va_end(args); } EXPORT_SYMBOL(ath_print); + +const char *ath_opmode_to_string(enum nl80211_iftype opmode) +{ + switch (opmode) { + case NL80211_IFTYPE_UNSPECIFIED: + return "UNSPEC"; + case NL80211_IFTYPE_ADHOC: + return "ADHOC"; + case NL80211_IFTYPE_STATION: + return "STATION"; + case NL80211_IFTYPE_AP: + return "AP"; + case NL80211_IFTYPE_AP_VLAN: + return "AP-VLAN"; + case NL80211_IFTYPE_WDS: + return "WDS"; + case NL80211_IFTYPE_MONITOR: + return "MONITOR"; + case NL80211_IFTYPE_MESH_POINT: + return "MESH"; + case NL80211_IFTYPE_P2P_CLIENT: + return "P2P-CLIENT"; + case NL80211_IFTYPE_P2P_GO: + return "P2P-GO"; + default: + return "UNKNOWN"; + } +} +EXPORT_SYMBOL(ath_opmode_to_string); diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index 873bf526e11f7f1ec5507112660bc53953c53436..64e4af2c2887338b597412421f717099ff5bc078 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h @@ -36,6 +36,7 @@ * @ATH_DBG_PS: power save processing * @ATH_DBG_HWTIMER: hardware timer handling * @ATH_DBG_BTCOEX: bluetooth coexistance + * @ATH_DBG_BSTUCK: stuck beacons * @ATH_DBG_ANY: enable all debugging * * The debug level is used to control the amount and type of debugging output @@ -60,6 +61,7 @@ enum ATH_DEBUG { ATH_DBG_HWTIMER = 0x00001000, ATH_DBG_BTCOEX = 0x00002000, ATH_DBG_WMI = 0x00004000, + ATH_DBG_BSTUCK = 0x00008000, ATH_DBG_ANY = 0xffffffff }; @@ -75,4 +77,14 @@ ath_print(struct ath_common *common, int dbg_mask, const char *fmt, ...) } #endif /* CONFIG_ATH_DEBUG */ +/** Returns string describing opmode, or NULL if unknown mode. */ +#ifdef CONFIG_ATH_DEBUG +const char *ath_opmode_to_string(enum nl80211_iftype opmode); +#else +static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode) +{ + return "UNKNOWN"; +} +#endif + #endif /* ATH_DEBUG_H */ diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index a8f81ea09f143cc56c981f80db73469196ddb4c6..183c28281385b255a0cd86d579cfc33885882abd 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c @@ -124,3 +124,62 @@ void ath_hw_setbssidmask(struct ath_common *common) REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU); } EXPORT_SYMBOL(ath_hw_setbssidmask); + + +/** + * ath_hw_cycle_counters_update - common function to update cycle counters + * + * @common: the ath_common struct for the device. + * + * This function is used to update all cycle counters in one place. + * It has to be called while holding common->cc_lock! + */ +void ath_hw_cycle_counters_update(struct ath_common *common) +{ + u32 cycles, busy, rx, tx; + void *ah = common->ah; + + /* freeze */ + REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC); + + /* read */ + cycles = REG_READ(ah, AR_CCCNT); + busy = REG_READ(ah, AR_RCCNT); + rx = REG_READ(ah, AR_RFCNT); + tx = REG_READ(ah, AR_TFCNT); + + /* clear */ + REG_WRITE(ah, 0, AR_CCCNT); + REG_WRITE(ah, 0, AR_RFCNT); + REG_WRITE(ah, 0, AR_RCCNT); + REG_WRITE(ah, 0, AR_TFCNT); + + /* unfreeze */ + REG_WRITE(ah, 0, AR_MIBC); + + /* update all cycle counters here */ + common->cc_ani.cycles += cycles; + common->cc_ani.rx_busy += busy; + common->cc_ani.rx_frame += rx; + common->cc_ani.tx_frame += tx; + + common->cc_survey.cycles += cycles; + common->cc_survey.rx_busy += busy; + common->cc_survey.rx_frame += rx; + common->cc_survey.tx_frame += tx; +} +EXPORT_SYMBOL(ath_hw_cycle_counters_update); + +int32_t ath_hw_get_listen_time(struct ath_common *common) +{ + struct ath_cycle_counters *cc = &common->cc_ani; + int32_t listen_time; + + listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) / + (common->clockrate * 1000); + + memset(cc, 0, sizeof(*cc)); + + return listen_time; +} +EXPORT_SYMBOL(ath_hw_get_listen_time); diff --git a/drivers/net/wireless/ath/key.c b/drivers/net/wireless/ath/key.c new file mode 100644 index 0000000000000000000000000000000000000000..bd21a4d82085b5131cb89497bff4d939275c3748 --- /dev/null +++ b/drivers/net/wireless/ath/key.c @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2009 Atheros Communications Inc. + * Copyright (c) 2010 Bruno Randolf + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "ath.h" +#include "reg.h" +#include "debug.h" + +#define REG_READ (common->ops->read) +#define REG_WRITE(_ah, _reg, _val) (common->ops->write)(_ah, _val, _reg) + +#define IEEE80211_WEP_NKID 4 /* number of key ids */ + +/************************/ +/* Key Cache Management */ +/************************/ + +bool ath_hw_keyreset(struct ath_common *common, u16 entry) +{ + u32 keyType; + void *ah = common->ah; + + if (entry >= common->keymax) { + ath_print(common, ATH_DBG_FATAL, + "keychache entry %u out of range\n", entry); + return false; + } + + keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry)); + + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR); + REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0); + REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0); + + if (keyType == AR_KEYTABLE_TYPE_TKIP) { + u16 micentry = entry + 64; + + REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); + + } + + return true; +} +EXPORT_SYMBOL(ath_hw_keyreset); + +bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac) +{ + u32 macHi, macLo; + u32 unicast_flag = AR_KEYTABLE_VALID; + void *ah = common->ah; + + if (entry >= common->keymax) { + ath_print(common, ATH_DBG_FATAL, + "keychache entry %u out of range\n", entry); + return false; + } + + if (mac != NULL) { + /* + * AR_KEYTABLE_VALID indicates that the address is a unicast + * address, which must match the transmitter address for + * decrypting frames. + * Not setting this bit allows the hardware to use the key + * for multicast frame decryption. + */ + if (mac[0] & 0x01) + unicast_flag = 0; + + macHi = (mac[5] << 8) | mac[4]; + macLo = (mac[3] << 24) | + (mac[2] << 16) | + (mac[1] << 8) | + mac[0]; + macLo >>= 1; + macLo |= (macHi & 1) << 31; + macHi >>= 1; + } else { + macLo = macHi = 0; + } + REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo); + REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag); + + return true; +} + +bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, + const struct ath_keyval *k, + const u8 *mac) +{ + void *ah = common->ah; + u32 key0, key1, key2, key3, key4; + u32 keyType; + + if (entry >= common->keymax) { + ath_print(common, ATH_DBG_FATAL, + "keycache entry %u out of range\n", entry); + return false; + } + + switch (k->kv_type) { + case ATH_CIPHER_AES_OCB: + keyType = AR_KEYTABLE_TYPE_AES; + break; + case ATH_CIPHER_AES_CCM: + if (!(common->crypt_caps & ATH_CRYPT_CAP_CIPHER_AESCCM)) { + ath_print(common, ATH_DBG_ANY, + "AES-CCM not supported by this mac rev\n"); + return false; + } + keyType = AR_KEYTABLE_TYPE_CCM; + break; + case ATH_CIPHER_TKIP: + keyType = AR_KEYTABLE_TYPE_TKIP; + if (entry + 64 >= common->keymax) { + ath_print(common, ATH_DBG_ANY, + "entry %u inappropriate for TKIP\n", entry); + return false; + } + break; + case ATH_CIPHER_WEP: + if (k->kv_len < WLAN_KEY_LEN_WEP40) { + ath_print(common, ATH_DBG_ANY, + "WEP key length %u too small\n", k->kv_len); + return false; + } + if (k->kv_len <= WLAN_KEY_LEN_WEP40) + keyType = AR_KEYTABLE_TYPE_40; + else if (k->kv_len <= WLAN_KEY_LEN_WEP104) + keyType = AR_KEYTABLE_TYPE_104; + else + keyType = AR_KEYTABLE_TYPE_128; + break; + case ATH_CIPHER_CLR: + keyType = AR_KEYTABLE_TYPE_CLR; + break; + default: + ath_print(common, ATH_DBG_FATAL, + "cipher %u not supported\n", k->kv_type); + return false; + } + + key0 = get_unaligned_le32(k->kv_val + 0); + key1 = get_unaligned_le16(k->kv_val + 4); + key2 = get_unaligned_le32(k->kv_val + 6); + key3 = get_unaligned_le16(k->kv_val + 10); + key4 = get_unaligned_le32(k->kv_val + 12); + if (k->kv_len <= WLAN_KEY_LEN_WEP104) + key4 &= 0xff; + + /* + * Note: Key cache registers access special memory area that requires + * two 32-bit writes to actually update the values in the internal + * memory. Consequently, the exact order and pairs used here must be + * maintained. + */ + + if (keyType == AR_KEYTABLE_TYPE_TKIP) { + u16 micentry = entry + 64; + + /* + * Write inverted key[47:0] first to avoid Michael MIC errors + * on frames that could be sent or received at the same time. + * The correct key will be written in the end once everything + * else is ready. + */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1); + + /* Write key[95:48] */ + REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); + REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); + + /* Write key[127:96] and key type */ + REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); + REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); + + /* Write MAC address for the entry */ + (void) ath_hw_keysetmac(common, entry, mac); + + if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { + /* + * TKIP uses two key cache entries: + * Michael MIC TX/RX keys in the same key cache entry + * (idx = main index + 64): + * key0 [31:0] = RX key [31:0] + * key1 [15:0] = TX key [31:16] + * key1 [31:16] = reserved + * key2 [31:0] = RX key [63:32] + * key3 [15:0] = TX key [15:0] + * key3 [31:16] = reserved + * key4 [31:0] = TX key [63:32] + */ + u32 mic0, mic1, mic2, mic3, mic4; + + mic0 = get_unaligned_le32(k->kv_mic + 0); + mic2 = get_unaligned_le32(k->kv_mic + 4); + mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff; + mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff; + mic4 = get_unaligned_le32(k->kv_txmic + 4); + + /* Write RX[31:0] and TX[31:16] */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1); + + /* Write RX[63:32] and TX[15:0] */ + REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); + REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3); + + /* Write TX[63:32] and keyType(reserved) */ + REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4); + REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), + AR_KEYTABLE_TYPE_CLR); + + } else { + /* + * TKIP uses four key cache entries (two for group + * keys): + * Michael MIC TX/RX keys are in different key cache + * entries (idx = main index + 64 for TX and + * main index + 32 + 96 for RX): + * key0 [31:0] = TX/RX MIC key [31:0] + * key1 [31:0] = reserved + * key2 [31:0] = TX/RX MIC key [63:32] + * key3 [31:0] = reserved + * key4 [31:0] = reserved + * + * Upper layer code will call this function separately + * for TX and RX keys when these registers offsets are + * used. + */ + u32 mic0, mic2; + + mic0 = get_unaligned_le32(k->kv_mic + 0); + mic2 = get_unaligned_le32(k->kv_mic + 4); + + /* Write MIC key[31:0] */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0); + + /* Write MIC key[63:32] */ + REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2); + REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0); + + /* Write TX[63:32] and keyType(reserved) */ + REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry), + AR_KEYTABLE_TYPE_CLR); + } + + /* MAC address registers are reserved for the MIC entry */ + REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0); + REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0); + + /* + * Write the correct (un-inverted) key[47:0] last to enable + * TKIP now that all other registers are set with correct + * values. + */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); + } else { + /* Write key[47:0] */ + REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0); + REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1); + + /* Write key[95:48] */ + REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2); + REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3); + + /* Write key[127:96] and key type */ + REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4); + REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType); + + /* Write MAC address for the entry */ + (void) ath_hw_keysetmac(common, entry, mac); + } + + return true; +} + +static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, + struct ath_keyval *hk, const u8 *addr, + bool authenticator) +{ + const u8 *key_rxmic; + const u8 *key_txmic; + + key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; + key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; + + if (addr == NULL) { + /* + * Group key installation - only two key cache entries are used + * regardless of splitmic capability since group key is only + * used either for TX or RX. + */ + if (authenticator) { + memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); + memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); + } else { + memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); + memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); + } + return ath_hw_set_keycache_entry(common, keyix, hk, addr); + } + if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) { + /* TX and RX keys share the same key cache entry. */ + memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); + memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); + return ath_hw_set_keycache_entry(common, keyix, hk, addr); + } + + /* Separate key cache entries for TX and RX */ + + /* TX key goes at first index, RX key at +32. */ + memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); + if (!ath_hw_set_keycache_entry(common, keyix, hk, NULL)) { + /* TX MIC entry failed. No need to proceed further */ + ath_print(common, ATH_DBG_FATAL, + "Setting TX MIC Key Failed\n"); + return 0; + } + + memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); + /* XXX delete tx key on failure? */ + return ath_hw_set_keycache_entry(common, keyix + 32, hk, addr); +} + +static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) +{ + int i; + + for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { + if (test_bit(i, common->keymap) || + test_bit(i + 64, common->keymap)) + continue; /* At least one part of TKIP key allocated */ + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) && + (test_bit(i + 32, common->keymap) || + test_bit(i + 64 + 32, common->keymap))) + continue; /* At least one part of TKIP key allocated */ + + /* Found a free slot for a TKIP key */ + return i; + } + return -1; +} + +static int ath_reserve_key_cache_slot(struct ath_common *common, + u32 cipher) +{ + int i; + + if (cipher == WLAN_CIPHER_SUITE_TKIP) + return ath_reserve_key_cache_slot_tkip(common); + + /* First, try to find slots that would not be available for TKIP. */ + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { + for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { + if (!test_bit(i, common->keymap) && + (test_bit(i + 32, common->keymap) || + test_bit(i + 64, common->keymap) || + test_bit(i + 64 + 32, common->keymap))) + return i; + if (!test_bit(i + 32, common->keymap) && + (test_bit(i, common->keymap) || + test_bit(i + 64, common->keymap) || + test_bit(i + 64 + 32, common->keymap))) + return i + 32; + if (!test_bit(i + 64, common->keymap) && + (test_bit(i , common->keymap) || + test_bit(i + 32, common->keymap) || + test_bit(i + 64 + 32, common->keymap))) + return i + 64; + if (!test_bit(i + 64 + 32, common->keymap) && + (test_bit(i, common->keymap) || + test_bit(i + 32, common->keymap) || + test_bit(i + 64, common->keymap))) + return i + 64 + 32; + } + } else { + for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { + if (!test_bit(i, common->keymap) && + test_bit(i + 64, common->keymap)) + return i; + if (test_bit(i, common->keymap) && + !test_bit(i + 64, common->keymap)) + return i + 64; + } + } + + /* No partially used TKIP slots, pick any available slot */ + for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { + /* Do not allow slots that could be needed for TKIP group keys + * to be used. This limitation could be removed if we know that + * TKIP will not be used. */ + if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) + continue; + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { + if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) + continue; + if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) + continue; + } + + if (!test_bit(i, common->keymap)) + return i; /* Found a free slot for a key */ + } + + /* No free slot found */ + return -1; +} + +/* + * Configure encryption in the HW. + */ +int ath_key_config(struct ath_common *common, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key) +{ + struct ath_keyval hk; + const u8 *mac = NULL; + u8 gmac[ETH_ALEN]; + int ret = 0; + int idx; + + memset(&hk, 0, sizeof(hk)); + + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + hk.kv_type = ATH_CIPHER_WEP; + break; + case WLAN_CIPHER_SUITE_TKIP: + hk.kv_type = ATH_CIPHER_TKIP; + break; + case WLAN_CIPHER_SUITE_CCMP: + hk.kv_type = ATH_CIPHER_AES_CCM; + break; + default: + return -EOPNOTSUPP; + } + + hk.kv_len = key->keylen; + memcpy(hk.kv_val, key->key, key->keylen); + + if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + switch (vif->type) { + case NL80211_IFTYPE_AP: + memcpy(gmac, vif->addr, ETH_ALEN); + gmac[0] |= 0x01; + mac = gmac; + idx = ath_reserve_key_cache_slot(common, key->cipher); + break; + case NL80211_IFTYPE_ADHOC: + if (!sta) { + idx = key->keyidx; + break; + } + memcpy(gmac, sta->addr, ETH_ALEN); + gmac[0] |= 0x01; + mac = gmac; + idx = ath_reserve_key_cache_slot(common, key->cipher); + break; + default: + idx = key->keyidx; + break; + } + } else if (key->keyidx) { + if (WARN_ON(!sta)) + return -EOPNOTSUPP; + mac = sta->addr; + + if (vif->type != NL80211_IFTYPE_AP) { + /* Only keyidx 0 should be used with unicast key, but + * allow this for client mode for now. */ + idx = key->keyidx; + } else + return -EIO; + } else { + if (WARN_ON(!sta)) + return -EOPNOTSUPP; + mac = sta->addr; + + idx = ath_reserve_key_cache_slot(common, key->cipher); + } + + if (idx < 0) + return -ENOSPC; /* no free key cache entries */ + + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) + ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, + vif->type == NL80211_IFTYPE_AP); + else + ret = ath_hw_set_keycache_entry(common, idx, &hk, mac); + + if (!ret) + return -EIO; + + set_bit(idx, common->keymap); + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { + set_bit(idx + 64, common->keymap); + set_bit(idx, common->tkip_keymap); + set_bit(idx + 64, common->tkip_keymap); + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { + set_bit(idx + 32, common->keymap); + set_bit(idx + 64 + 32, common->keymap); + set_bit(idx + 32, common->tkip_keymap); + set_bit(idx + 64 + 32, common->tkip_keymap); + } + } + + return idx; +} +EXPORT_SYMBOL(ath_key_config); + +/* + * Delete Key. + */ +void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) +{ + ath_hw_keyreset(common, key->hw_key_idx); + if (key->hw_key_idx < IEEE80211_WEP_NKID) + return; + + clear_bit(key->hw_key_idx, common->keymap); + if (key->cipher != WLAN_CIPHER_SUITE_TKIP) + return; + + clear_bit(key->hw_key_idx + 64, common->keymap); + + clear_bit(key->hw_key_idx, common->tkip_keymap); + clear_bit(key->hw_key_idx + 64, common->tkip_keymap); + + if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) { + ath_hw_keyreset(common, key->hw_key_idx + 32); + clear_bit(key->hw_key_idx + 32, common->keymap); + clear_bit(key->hw_key_idx + 64 + 32, common->keymap); + + clear_bit(key->hw_key_idx + 32, common->tkip_keymap); + clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap); + } +} +EXPORT_SYMBOL(ath_key_delete); diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h index dfe1fbec24f5fbfa3dade5ac2a9e040b45143348..298e53f3fa4834939ae75fdaf6a531467d10839a 100644 --- a/drivers/net/wireless/ath/reg.h +++ b/drivers/net/wireless/ath/reg.h @@ -17,6 +17,12 @@ #ifndef ATH_REGISTERS_H #define ATH_REGISTERS_H +#define AR_MIBC 0x0040 +#define AR_MIBC_COW 0x00000001 +#define AR_MIBC_FMC 0x00000002 +#define AR_MIBC_CMC 0x00000004 +#define AR_MIBC_MCS 0x00000008 + /* * BSSID mask registers. See ath_hw_set_bssid_mask() * for detailed documentation about these registers. @@ -24,4 +30,32 @@ #define AR_BSSMSKL 0x80e0 #define AR_BSSMSKU 0x80e4 +#define AR_TFCNT 0x80ec +#define AR_RFCNT 0x80f0 +#define AR_RCCNT 0x80f4 +#define AR_CCCNT 0x80f8 + +#define AR_KEYTABLE_0 0x8800 +#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) +#define AR_KEY_CACHE_SIZE 128 +#define AR_RSVD_KEYTABLE_ENTRIES 4 +#define AR_KEY_TYPE 0x00000007 +#define AR_KEYTABLE_TYPE_40 0x00000000 +#define AR_KEYTABLE_TYPE_104 0x00000001 +#define AR_KEYTABLE_TYPE_128 0x00000003 +#define AR_KEYTABLE_TYPE_TKIP 0x00000004 +#define AR_KEYTABLE_TYPE_AES 0x00000005 +#define AR_KEYTABLE_TYPE_CCM 0x00000006 +#define AR_KEYTABLE_TYPE_CLR 0x00000007 +#define AR_KEYTABLE_ANT 0x00000008 +#define AR_KEYTABLE_VALID 0x00008000 +#define AR_KEYTABLE_KEY0(_n) (AR_KEYTABLE(_n) + 0) +#define AR_KEYTABLE_KEY1(_n) (AR_KEYTABLE(_n) + 4) +#define AR_KEYTABLE_KEY2(_n) (AR_KEYTABLE(_n) + 8) +#define AR_KEYTABLE_KEY3(_n) (AR_KEYTABLE(_n) + 12) +#define AR_KEYTABLE_KEY4(_n) (AR_KEYTABLE(_n) + 16) +#define AR_KEYTABLE_TYPE(_n) (AR_KEYTABLE(_n) + 20) +#define AR_KEYTABLE_MAC0(_n) (AR_KEYTABLE(_n) + 24) +#define AR_KEYTABLE_MAC1(_n) (AR_KEYTABLE(_n) + 28) + #endif /* ATH_REGISTERS_H */ diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index 5e83b6f0a3a013aeeb8cd090fd2bcd9267223356..69d4af09a6cbc9e08fca385fb9a7c1d33665326a 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile @@ -1,6 +1,8 @@ b43-y += main.o b43-y += tables.o b43-$(CONFIG_B43_NPHY) += tables_nphy.o +b43-$(CONFIG_B43_NPHY) += radio_2055.o +b43-$(CONFIG_B43_NPHY) += radio_2056.o b43-y += phy_common.o b43-y += phy_g.o b43-y += phy_a.o diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 8674a99356af644349a17f0e221ce5a22d27b0aa..72821c456b02fcf480525846ffce55e185486c73 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -186,7 +186,8 @@ enum { #define B43_SHM_SH_PHYTXNOI 0x006E /* PHY noise directly after TX (lower 8bit only) */ #define B43_SHM_SH_RFRXSP1 0x0072 /* RF RX SP Register 1 */ #define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ -#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5Ghz channel */ +#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */ +#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */ #define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ /* TSSI information */ #define B43_SHM_SH_TSSI_CCK 0x0058 /* TSSI for last 4 CCK frames (32bit) */ diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 20631ae2ddd77bb5893ec101912f79152eb28957..a1186525c70d03f33a936ff15dc90a6bda877e1a 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2280,6 +2280,7 @@ static int b43_request_firmware(struct b43_wldev *dev) static int b43_upload_microcode(struct b43_wldev *dev) { + struct wiphy *wiphy = dev->wl->hw->wiphy; const size_t hdr_len = sizeof(struct b43_fw_header); const __be32 *data; unsigned int i, len; @@ -2405,6 +2406,10 @@ static int b43_upload_microcode(struct b43_wldev *dev) } } + snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", + dev->fw.rev, dev->fw.patch); + wiphy->hw_version = dev->dev->id.coreid; + if (b43_is_old_txhdr_format(dev)) { /* We're over the deadline, but we keep support for old fw * until it turns out to be in major conflict with something new. */ @@ -3754,17 +3759,17 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } err = -EINVAL; - switch (key->alg) { - case ALG_WEP: - if (key->keylen == WLAN_KEY_LEN_WEP40) - algorithm = B43_SEC_ALGO_WEP40; - else - algorithm = B43_SEC_ALGO_WEP104; + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + algorithm = B43_SEC_ALGO_WEP40; + break; + case WLAN_CIPHER_SUITE_WEP104: + algorithm = B43_SEC_ALGO_WEP104; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: algorithm = B43_SEC_ALGO_TKIP; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: algorithm = B43_SEC_ALGO_AES; break; default: @@ -4250,6 +4255,10 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED); if (!dev || b43_status(dev) != B43_STAT_INITIALIZED) return; + + /* Unregister HW RNG driver */ + b43_rng_exit(dev->wl); + b43_set_status(dev, B43_STAT_UNINIT); /* Stop the microcode PSM. */ @@ -4379,6 +4388,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev) b43_set_status(dev, B43_STAT_INITIALIZED); + /* Register HW RNG driver */ + b43_rng_init(dev->wl); + out: return err; @@ -4984,7 +4996,6 @@ static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id) if (err) goto err_one_core_detach; b43_leds_register(wl->current_dev); - b43_rng_init(wl); } out: @@ -5020,7 +5031,6 @@ static void b43_remove(struct ssb_device *dev) b43_one_core_detach(dev); if (list_empty(&wl->devlist)) { - b43_rng_exit(wl); b43_leds_unregister(wl); /* Last core on the chip unregistered. * We can destroy common struct b43_wl. diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 8f7d7eff2d803a79649e4a340f15a6d806089adb..7b2ea67814574152009f654c60c7a60771d7d189 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c @@ -294,8 +294,10 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel) */ channelcookie = new_channel; if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) - channelcookie |= 0x100; - //FIXME set 40Mhz flag if required + channelcookie |= B43_SHM_SH_CHAN_5GHZ; + /* FIXME: set 40Mhz flag if required */ + if (0) + channelcookie |= B43_SHM_SH_CHAN_40MHZ; savedcookie = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN); b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_CHAN, channelcookie); diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index bd480b481bfc387da47d8744e2174e3f5da7111f..0e6194228845565e89adf54ec92b5553c3baf776 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -2,6 +2,7 @@ #define LINUX_B43_PHY_COMMON_H_ #include +#include struct b43_wldev; @@ -250,8 +251,10 @@ struct b43_phy { * check is needed. */ unsigned long next_txpwr_check_time; - /* current channel */ + /* Current channel */ unsigned int channel; + u16 channel_freq; + enum nl80211_channel_type channel_type; /* PHY TX errors counter. */ atomic_t txerr_cnt; diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 5a725703770cb6d9a01236f0121b052f6cd0cc4b..dfec5496055e410b7beffdb02e8d2cac556e016f 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -29,6 +29,8 @@ #include "b43.h" #include "phy_n.h" #include "tables_nphy.h" +#include "radio_2055.h" +#include "radio_2056.h" #include "main.h" struct nphy_txgains { @@ -73,21 +75,12 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field, u16 value, u8 core, bool off); static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, u16 value, u8 core); -static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel); -static inline bool b43_empty_chanspec(struct b43_chanspec *chanspec) +static inline bool b43_channel_type_is_40mhz( + enum nl80211_channel_type channel_type) { - return !chanspec->channel && !chanspec->sideband && - !chanspec->b_width && !chanspec->b_freq; -} - -static inline bool b43_eq_chanspecs(struct b43_chanspec *chanspec1, - struct b43_chanspec *chanspec2) -{ - return (chanspec1->channel == chanspec2->channel && - chanspec1->sideband == chanspec2->sideband && - chanspec1->b_width == chanspec2->b_width && - chanspec1->b_freq == chanspec2->b_freq); + return (channel_type == NL80211_CHAN_HT40MINUS || + channel_type == NL80211_CHAN_HT40PLUS); } void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) @@ -223,7 +216,7 @@ static void b43_radio_init2055_post(struct b43_wldev *dev) if (i) b43err(dev->wl, "radio post init timeout\n"); b43_radio_mask(dev, B2055_CAL_LPOCTL, 0xFF7F); - nphy_channel_switch(dev, dev->phy.channel); + b43_switch_channel(dev, dev->phy.channel); b43_radio_write(dev, B2055_C1_RX_BB_LPF, 0x9); b43_radio_write(dev, B2055_C2_RX_BB_LPF, 0x9); b43_radio_write(dev, B2055_C1_RX_BB_MIDACHP, 0x83); @@ -782,7 +775,7 @@ static void b43_nphy_spur_workaround(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; - u8 channel = nphy->radio_chanspec.channel; + u8 channel = dev->phy.channel; int tone[2] = { 57, 58 }; u32 noise[2] = { 0x3FF, 0x3FF }; @@ -856,9 +849,9 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) gain[0] = 6; gain[1] = 6; } else { - tmp = 40370 - 315 * nphy->radio_chanspec.channel; + tmp = 40370 - 315 * dev->phy.channel; gain[0] = ((tmp >> 13) + ((tmp >> 12) & 1)); - tmp = 23242 - 224 * nphy->radio_chanspec.channel; + tmp = 23242 - 224 * dev->phy.channel; gain[1] = ((tmp >> 13) + ((tmp >> 12) & 1)); } } else { @@ -893,7 +886,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/WorkaroundsGainCtrl */ -static void b43_nphy_gain_crtl_workarounds(struct b43_wldev *dev) +static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) { struct b43_phy_n *nphy = dev->phy.n; u8 i, j; @@ -1094,11 +1087,12 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7); b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7); - b43_nphy_gain_crtl_workarounds(dev); + b43_nphy_gain_ctrl_workarounds(dev); if (dev->phy.rev < 2) { if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2) - ; /*TODO: b43_mhf(dev, 2, 0x0010, 0x0010, 3);*/ + b43_hf_write(dev, b43_hf_read(dev) | + B43_HF_MLADVW); } else if (dev->phy.rev == 2) { b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0); b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0); @@ -1182,7 +1176,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, len = bw << 1; } - samples = kzalloc(len * sizeof(struct b43_c32), GFP_KERNEL); + samples = kcalloc(len, sizeof(struct b43_c32), GFP_KERNEL); if (!samples) { b43err(dev->wl, "allocation for samples generation failed\n"); return 0; @@ -2083,12 +2077,12 @@ static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev) u16 *rssical_phy_regs = NULL; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - if (b43_empty_chanspec(&nphy->rssical_chanspec_2G)) + if (!nphy->rssical_chanspec_2G.center_freq) return; rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; } else { - if (b43_empty_chanspec(&nphy->rssical_chanspec_5G)) + if (!nphy->rssical_chanspec_5G.center_freq) return; rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; @@ -2544,8 +2538,9 @@ static void b43_nphy_save_cal(struct b43_wldev *dev) txcal_radio_regs[2] = b43_radio_read(dev, 0x8D); txcal_radio_regs[3] = b43_radio_read(dev, 0xBC); } - *iqcal_chanspec = nphy->radio_chanspec; - b43_ntab_write_bulk(dev, B43_NTAB16(15, 80), 8, table); + iqcal_chanspec->center_freq = dev->phy.channel_freq; + iqcal_chanspec->channel_type = dev->phy.channel_type; + b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 8, table); if (nphy->hang_avoid) b43_nphy_stay_in_carrier_search(dev, 0); @@ -2565,12 +2560,12 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev) struct b43_phy_n_iq_comp *rxcal_coeffs = NULL; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - if (b43_empty_chanspec(&nphy->iqcal_chanspec_2G)) + if (!nphy->iqcal_chanspec_2G.center_freq) return; table = nphy->cal_cache.txcal_coeffs_2G; loft = &nphy->cal_cache.txcal_coeffs_2G[5]; } else { - if (b43_empty_chanspec(&nphy->iqcal_chanspec_5G)) + if (!nphy->iqcal_chanspec_5G.center_freq) return; table = nphy->cal_cache.txcal_coeffs_5G; loft = &nphy->cal_cache.txcal_coeffs_5G[5]; @@ -2815,7 +2810,10 @@ static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, b43_ntab_read_bulk(dev, B43_NTAB16(15, 96), length, nphy->txiqlocal_bestc); nphy->txiqlocal_coeffsvalid = true; - nphy->txiqlocal_chanspec = nphy->radio_chanspec; + nphy->txiqlocal_chanspec.center_freq = + dev->phy.channel_freq; + nphy->txiqlocal_chanspec.channel_type = + dev->phy.channel_type; } else { length = 11; if (dev->phy.rev < 3) @@ -2851,7 +2849,8 @@ static void b43_nphy_reapply_tx_cal_coeffs(struct b43_wldev *dev) bool equal = true; if (!nphy->txiqlocal_coeffsvalid || - b43_eq_chanspecs(&nphy->txiqlocal_chanspec, &nphy->radio_chanspec)) + nphy->txiqlocal_chanspec.center_freq != dev->phy.channel_freq || + nphy->txiqlocal_chanspec.channel_type != dev->phy.channel_type) return; b43_ntab_read_bulk(dev, B43_NTAB16(15, 80), 7, buffer); @@ -3073,6 +3072,57 @@ static int b43_nphy_cal_rx_iq(struct b43_wldev *dev, return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ +static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on) +{ + u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW); + if (on) + tmslow |= SSB_TMSLOW_PHYCLK; + else + tmslow &= ~SSB_TMSLOW_PHYCLK; + ssb_write32(dev->dev, SSB_TMSLOW, tmslow); +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */ +static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) +{ + struct b43_phy *phy = &dev->phy; + struct b43_phy_n *nphy = phy->n; + u16 buf[16]; + + nphy->phyrxchain = mask; + + if (0 /* FIXME clk */) + return; + + b43_mac_suspend(dev); + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, true); + + b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_RXEN, + (mask & 0x3) << B43_NPHY_RFSEQCA_RXEN_SHIFT); + + if ((mask & 0x3) != 0x3) { + b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 1); + if (dev->phy.rev >= 3) { + /* TODO */ + } + } else { + b43_phy_write(dev, B43_NPHY_HPANT_SWTHRES, 0x1E); + if (dev->phy.rev >= 3) { + /* TODO */ + } + } + + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, false); + + b43_mac_enable(dev); +} + /* * Init N-PHY * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N @@ -3173,7 +3223,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA); b43_nphy_bmac_clock_fgc(dev, 0); - /* TODO N PHY MAC PHY Clock Set with argument 1 */ + b43_nphy_mac_phy_clock_set(dev, true); b43_nphy_pa_override(dev, false); b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); @@ -3199,18 +3249,16 @@ int b43_phy_initn(struct b43_wldev *dev) } if (nphy->phyrxchain != 3) - ;/* TODO N PHY RX Core Set State with phyrxchain as argument */ + b43_nphy_set_rx_core_state(dev, nphy->phyrxchain); if (nphy->mphase_cal_phase_id > 0) ;/* TODO PHY Periodic Calibration Multi-Phase Restart */ do_rssi_cal = false; if (phy->rev >= 3) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - do_rssi_cal = - b43_empty_chanspec(&nphy->rssical_chanspec_2G); + do_rssi_cal = !nphy->rssical_chanspec_2G.center_freq; else - do_rssi_cal = - b43_empty_chanspec(&nphy->rssical_chanspec_5G); + do_rssi_cal = !nphy->rssical_chanspec_5G.center_freq; if (do_rssi_cal) b43_nphy_rssi_cal(dev); @@ -3222,9 +3270,9 @@ int b43_phy_initn(struct b43_wldev *dev) if (!((nphy->measure_hold & 0x6) != 0)) { if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_2G); + do_cal = !nphy->iqcal_chanspec_2G.center_freq; else - do_cal = b43_empty_chanspec(&nphy->iqcal_chanspec_5G); + do_cal = !nphy->iqcal_chanspec_5G.center_freq; if (nphy->mute) do_cal = false; @@ -3272,24 +3320,25 @@ int b43_phy_initn(struct b43_wldev *dev) } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ -static void b43_nphy_chanspec_setup(struct b43_wldev *dev, +static void b43_nphy_channel_setup(struct b43_wldev *dev, const struct b43_phy_n_sfo_cfg *e, - struct b43_chanspec chanspec) + struct ieee80211_channel *new_channel) { struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = dev->phy.n; - u16 tmp; + u16 old_band_5ghz; u32 tmp32; - tmp = b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; - if (chanspec.b_freq == 1 && tmp == 0) { + old_band_5ghz = + b43_phy_read(dev, B43_NPHY_BANDCTL) & B43_NPHY_BANDCTL_5GHZ; + if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); b43_phy_set(dev, B43_PHY_B_BBCFG, 0xC000); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32); b43_phy_set(dev, B43_NPHY_BANDCTL, B43_NPHY_BANDCTL_5GHZ); - } else if (chanspec.b_freq == 1) { + } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) { b43_phy_mask(dev, B43_NPHY_BANDCTL, ~B43_NPHY_BANDCTL_5GHZ); tmp32 = b43_read32(dev, B43_MMIO_PSM_PHY_HDR); b43_write32(dev, B43_MMIO_PSM_PHY_HDR, tmp32 | 4); @@ -3299,19 +3348,12 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev, b43_chantab_phy_upload(dev, e); - tmp = chanspec.channel; - if (chanspec.b_freq == 1) - tmp |= 0x0100; - if (chanspec.b_width == 3) - tmp |= 0x0200; - b43_shm_write16(dev, B43_SHM_SHARED, 0xA0, tmp); - - if (nphy->radio_chanspec.channel == 14) { + if (new_channel->hw_value == 14) { b43_nphy_classifier(dev, 2, 0); b43_phy_set(dev, B43_PHY_B_TEST, 0x0800); } else { b43_nphy_classifier(dev, 2, 2); - if (chanspec.b_freq == 2) + if (new_channel->band == IEEE80211_BAND_2GHZ) b43_phy_mask(dev, B43_PHY_B_TEST, ~0x840); } @@ -3334,70 +3376,62 @@ static void b43_nphy_chanspec_setup(struct b43_wldev *dev, } /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetChanspec */ -static int b43_nphy_set_chanspec(struct b43_wldev *dev, - struct b43_chanspec chanspec) +static int b43_nphy_set_channel(struct b43_wldev *dev, + struct ieee80211_channel *channel, + enum nl80211_channel_type channel_type) { + struct b43_phy *phy = &dev->phy; struct b43_phy_n *nphy = dev->phy.n; const struct b43_nphy_channeltab_entry_rev2 *tabent_r2; const struct b43_nphy_channeltab_entry_rev3 *tabent_r3; u8 tmp; - u8 channel = chanspec.channel; if (dev->phy.rev >= 3) { - /* TODO */ + tabent_r3 = b43_nphy_get_chantabent_rev3(dev, + channel->center_freq); tabent_r3 = NULL; if (!tabent_r3) return -ESRCH; } else { - tabent_r2 = b43_nphy_get_chantabent_rev2(dev, channel); + tabent_r2 = b43_nphy_get_chantabent_rev2(dev, + channel->hw_value); if (!tabent_r2) return -ESRCH; } - nphy->radio_chanspec = chanspec; + /* Channel is set later in common code, but we need to set it on our + own to let this function's subcalls work properly. */ + phy->channel = channel->hw_value; + phy->channel_freq = channel->center_freq; - if (chanspec.b_width != nphy->b_width) - ; /* TODO: BMAC BW Set (chanspec.b_width) */ + if (b43_channel_type_is_40mhz(phy->channel_type) != + b43_channel_type_is_40mhz(channel_type)) + ; /* TODO: BMAC BW Set (channel_type) */ - /* TODO: use defines */ - if (chanspec.b_width == 3) { - if (chanspec.sideband == 2) - b43_phy_set(dev, B43_NPHY_RXCTL, - B43_NPHY_RXCTL_BSELU20); - else - b43_phy_mask(dev, B43_NPHY_RXCTL, - ~B43_NPHY_RXCTL_BSELU20); - } + if (channel_type == NL80211_CHAN_HT40PLUS) + b43_phy_set(dev, B43_NPHY_RXCTL, + B43_NPHY_RXCTL_BSELU20); + else if (channel_type == NL80211_CHAN_HT40MINUS) + b43_phy_mask(dev, B43_NPHY_RXCTL, + ~B43_NPHY_RXCTL_BSELU20); if (dev->phy.rev >= 3) { - tmp = (chanspec.b_freq == 1) ? 4 : 0; + tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 4 : 0; b43_radio_maskset(dev, 0x08, 0xFFFB, tmp); /* TODO: PHY Radio2056 Setup (dev, tabent_r3); */ - b43_nphy_chanspec_setup(dev, &(tabent_r3->phy_regs), chanspec); + b43_nphy_channel_setup(dev, &(tabent_r3->phy_regs), channel); } else { - tmp = (chanspec.b_freq == 1) ? 0x0020 : 0x0050; + tmp = (channel->band == IEEE80211_BAND_5GHZ) ? 0x0020 : 0x0050; b43_radio_maskset(dev, B2055_MASTER1, 0xFF8F, tmp); b43_radio_2055_setup(dev, tabent_r2); - b43_nphy_chanspec_setup(dev, &(tabent_r2->phy_regs), chanspec); + b43_nphy_channel_setup(dev, &(tabent_r2->phy_regs), channel); } return 0; } -/* Tune the hardware to a new channel */ -static int nphy_channel_switch(struct b43_wldev *dev, unsigned int channel) -{ - struct b43_phy_n *nphy = dev->phy.n; - - struct b43_chanspec chanspec; - chanspec = nphy->radio_chanspec; - chanspec.channel = channel; - - return b43_nphy_set_chanspec(dev, chanspec); -} - static int b43_nphy_op_allocate(struct b43_wldev *dev) { struct b43_phy_n *nphy; @@ -3518,7 +3552,7 @@ static void b43_nphy_op_software_rfkill(struct b43_wldev *dev, } else { if (dev->phy.rev >= 3) { b43_radio_init2056(dev); - b43_nphy_set_chanspec(dev, nphy->radio_chanspec); + b43_switch_channel(dev, dev->phy.channel); } else { b43_radio_init2055(dev); } @@ -3534,6 +3568,9 @@ static void b43_nphy_op_switch_analog(struct b43_wldev *dev, bool on) static int b43_nphy_op_switch_channel(struct b43_wldev *dev, unsigned int new_channel) { + struct ieee80211_channel *channel = dev->wl->hw->conf.channel; + enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type; + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { if ((new_channel < 1) || (new_channel > 14)) return -EINVAL; @@ -3542,7 +3579,7 @@ static int b43_nphy_op_switch_channel(struct b43_wldev *dev, return -EINVAL; } - return nphy_channel_switch(dev, new_channel); + return b43_nphy_set_channel(dev, channel, channel_type); } static unsigned int b43_nphy_op_get_default_chan(struct b43_wldev *dev) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 8b6d570dd0aa963878b31e8b76fda75e9ea92d1b..c144e59a708bc5b4257181fd8044a4f757a11996 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -714,223 +714,11 @@ #define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) /* BB config */ #define B43_PHY_B_TEST B43_PHY_N_BMODE(0x00A) - -/* Broadcom 2055 radio registers */ - -#define B2055_GEN_SPARE 0x00 /* GEN spare */ -#define B2055_SP_PINPD 0x02 /* SP PIN PD */ -#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */ -#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */ -#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */ -#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */ -#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */ -#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */ -#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */ -#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */ -#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */ -#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */ -#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */ -#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */ -#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */ -#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */ -#define B2055_MASTER1 0x11 /* Master control 1 */ -#define B2055_MASTER2 0x12 /* Master control 2 */ -#define B2055_PD_LGEN 0x13 /* PD LGEN */ -#define B2055_PD_PLLTS 0x14 /* PD PLL TS */ -#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */ -#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */ -#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */ -#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */ -#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */ -#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */ -#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */ -#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */ -#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */ -#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */ -#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */ -#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */ -#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */ -#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */ -#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */ -#define B2055_CAL_MISC 0x24 /* CAL MISC */ -#define B2055_CAL_COUT 0x25 /* CAL Counter out */ -#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */ -#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */ -#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */ -#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */ -#define B2055_CAL_TS 0x2A /* CAL TS */ -#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */ -#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */ -#define B2055_PADDRV 0x2D /* PAD driver */ -#define B2055_XOCTL1 0x2E /* XO Control 1 */ -#define B2055_XOCTL2 0x2F /* XO Control 2 */ -#define B2055_XOREGUL 0x30 /* XO Regulator */ -#define B2055_XOMISC 0x31 /* XO misc */ -#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */ -#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */ -#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */ -#define B2055_PLL_REF 0x35 /* PLL reference */ -#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */ -#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */ -#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */ -#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */ -#define B2055_PLL_RCAL 0x3A /* PLL RCAL */ -#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */ -#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */ -#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */ -#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */ -#define B2055_RF_MMDSP 0x3F /* RF MMD spare */ -#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */ -#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */ -#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */ -#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */ -#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */ -#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */ -#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */ -#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */ -#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */ -#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */ -#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */ -#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */ -#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */ -#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */ -#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */ -#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */ -#define B2055_VCO_KVCO 0x50 /* VCO KVCO */ -#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */ -#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */ -#define B2055_VCO_REG 0x53 /* VCO Regulator */ -#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */ -#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */ -#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */ -#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */ -#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */ -#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */ -#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */ -#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */ -#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */ -#define B2055_LGEN_DIV 0x5D /* LGEN div */ -#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */ -#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */ -#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */ -#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */ -#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */ -#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */ -#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */ -#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */ -#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */ -#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */ -#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */ -#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */ -#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */ -#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */ -#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */ -#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */ -#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */ -#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */ -#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */ -#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */ -#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */ -#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */ -#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */ -#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */ -#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */ -#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */ -#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */ -#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */ -#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */ -#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */ -#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */ -#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */ -#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */ -#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */ -#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */ -#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */ -#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */ -#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */ -#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */ -#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */ -#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */ -#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */ -#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */ -#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */ -#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */ -#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */ -#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */ -#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */ -#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */ -#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */ -#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */ -#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */ -#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */ -#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */ -#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */ -#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */ -#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */ -#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */ -#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */ -#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */ -#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */ -#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */ -#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */ -#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */ -#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */ -#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */ -#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */ -#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */ -#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */ -#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */ -#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */ -#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */ -#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */ -#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */ -#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */ -#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */ -#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */ -#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */ -#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */ -#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */ -#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */ -#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */ -#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */ -#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */ -#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */ -#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */ -#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */ -#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */ -#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */ -#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */ -#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */ -#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */ -#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */ -#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */ -#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */ -#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */ -#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */ -#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */ -#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */ -#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */ -#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */ -#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */ -#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */ -#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */ -#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */ -#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */ -#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */ -#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */ -#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */ -#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */ -#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */ - - - struct b43_wldev; struct b43_chanspec { - u8 channel; - u8 sideband; - u8 b_width; - u8 b_freq; + u16 center_freq; + enum nl80211_channel_type channel_type; }; struct b43_phy_n_iq_comp { @@ -984,8 +772,6 @@ struct b43_phy_n { u16 papd_epsilon_offset[2]; s32 preamble_override; u32 bb_mult_save; - u8 b_width; - struct b43_chanspec radio_chanspec; bool gain_boost; bool elna_gain_config; diff --git a/drivers/net/wireless/b43/radio_2055.c b/drivers/net/wireless/b43/radio_2055.c new file mode 100644 index 0000000000000000000000000000000000000000..1b5316586cbffd6134909b919c1da3db28d8ebfd --- /dev/null +++ b/drivers/net/wireless/b43/radio_2055.c @@ -0,0 +1,1332 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n PHY and radio device data tables + + Copyright (c) 2008 Michael Buesch + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "b43.h" +#include "radio_2055.h" +#include "phy_common.h" + +struct b2055_inittab_entry { + /* Value to write if we use the 5GHz band. */ + u16 ghz5; + /* Value to write if we use the 2.4GHz band. */ + u16 ghz2; + /* Flags */ + u8 flags; +#define B2055_INITTAB_ENTRY_OK 0x01 +#define B2055_INITTAB_UPLOAD 0x02 +}; +#define UPLOAD .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD +#define NOUPLOAD .flags = B2055_INITTAB_ENTRY_OK + +static const struct b2055_inittab_entry b2055_inittab [] = { + [B2055_SP_PINPD] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, + [B2055_C1_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, }, + [B2055_C2_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, }, + [B2055_C1_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, }, + [B2055_C1_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2055_C2_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, }, + [B2055_C2_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, + [B2055_C1_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_C2_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_C1_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, }, + [B2055_C1_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, + [B2055_C2_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, }, + [B2055_C2_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, + [B2055_MASTER1] = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, }, + [B2055_MASTER2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2055_PD_LGEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PD_PLLTS] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, + [B2055_C1_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PWRDET_LGEN] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, + [B2055_C1_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, + [B2055_C1_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, + [B2055_C2_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, + [B2055_C2_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, + [B2055_RRCCAL_CS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_RRCCAL_NOPTSEL] = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, }, + [B2055_CAL_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_COUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_COUT2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_CVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_RVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_LPOCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_TS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_RCCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_CAL_RCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PADDRV] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, + [B2055_XOCTL1] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, + [B2055_XOCTL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_XOREGUL] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, + [B2055_XOMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PLL_LFC1] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_PLL_CALVTH] = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, }, + [B2055_PLL_LFC2] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, }, + [B2055_PLL_REF] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, + [B2055_PLL_LFR1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, + [B2055_PLL_PFDCP] = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, }, + [B2055_PLL_IDAC_CPOPAMP] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_PLL_CPREG] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, + [B2055_PLL_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_RF_PLLMOD0] = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, }, + [B2055_RF_PLLMOD1] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, }, + [B2055_RF_MMDIDAC1] = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, }, + [B2055_RF_MMDIDAC0] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_RF_MMDSP] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL3] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, + [B2055_VCO_CAL4] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2055_VCO_CAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, + [B2055_VCO_CAL6] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, }, + [B2055_VCO_CAL7] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, }, + [B2055_VCO_CAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, + [B2055_VCO_CAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, + [B2055_VCO_CAL10] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_VCO_CAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_VCO_CAL12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_CAL16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_VCO_KVCO] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_VCO_CAPTAIL] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_VCO_IDACVCO] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_VCO_REG] = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, }, + [B2055_PLL_RFVTH] = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, }, + [B2055_LGBUF_CENBUF] = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, }, + [B2055_LGEN_TUNE1] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, + [B2055_LGEN_TUNE2] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, + [B2055_LGEN_IDAC1] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_LGEN_IDAC2] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_LGEN_BIASC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_LGEN_BIASIDAC] = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, }, + [B2055_LGEN_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_LGEN_DIV] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, + [B2055_LGEN_SPARE2] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, + [B2055_C1_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, }, + [B2055_C1_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C1_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C1_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, }, + [B2055_C1_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C1_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, }, + [B2055_C1_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, }, + [B2055_C1_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_C1_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2055_C1_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C1_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, }, + [B2055_C1_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_C1_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, + [B2055_C1_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C1_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, }, + [B2055_C1_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, }, + [B2055_C1_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, }, + [B2055_C1_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, }, + [B2055_C1_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, }, + [B2055_C1_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, + [B2055_C1_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C1_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_C1_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_C1_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_C1_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2055_C1_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, }, + [B2055_C1_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_C1_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, }, + [B2055_C1_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, }, + [B2055_C1_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C1_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C1_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, + [B2055_C1_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_C1_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, + [B2055_C1_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C1_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, + [B2055_C1_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C1_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, }, + [B2055_C1_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, }, + [B2055_C1_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, }, + [B2055_C2_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C2_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C2_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, }, + [B2055_C2_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C2_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, }, + [B2055_C2_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, }, + [B2055_C2_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_C2_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, + [B2055_C2_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C2_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, }, + [B2055_C2_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_C2_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, + [B2055_C2_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C2_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, }, + [B2055_C2_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, }, + [B2055_C2_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, }, + [B2055_C2_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, }, + [B2055_C2_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, }, + [B2055_C2_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, + [B2055_C2_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C2_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_C2_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, + [B2055_C2_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, + [B2055_C2_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, + [B2055_C2_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, }, + [B2055_C2_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, + [B2055_C2_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, }, + [B2055_C2_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, }, + [B2055_C2_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [B2055_C2_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, + [B2055_C2_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, + [B2055_C2_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, + [B2055_C2_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, + [B2055_C2_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, + [B2055_C2_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, + [B2055_C2_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C2_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, }, + [B2055_C2_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, }, + [B2055_C2_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_PRG_GCHP21] = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, }, + [B2055_PRG_GCHP22] = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, }, + [B2055_PRG_GCHP23] = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, }, + [B2055_PRG_GCHP24] = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, }, + [B2055_PRG_GCHP25] = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, }, + [B2055_PRG_GCHP26] = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, }, + [B2055_PRG_GCHP27] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, + [B2055_PRG_GCHP28] = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, }, + [B2055_PRG_GCHP29] = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, }, + [B2055_PRG_GCHP30] = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, }, + [0xC7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xC8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xC9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C1_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [0xD3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C1_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, + [B2055_C2_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, + [0xDF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xE0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [0xE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, + [B2055_C2_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, +}; + +#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \ + r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \ + .radio_pll_ref = r0, \ + .radio_rf_pllmod0 = r1, \ + .radio_rf_pllmod1 = r2, \ + .radio_vco_captail = r3, \ + .radio_vco_cal1 = r4, \ + .radio_vco_cal2 = r5, \ + .radio_pll_lfc1 = r6, \ + .radio_pll_lfr1 = r7, \ + .radio_pll_lfc2 = r8, \ + .radio_lgbuf_cenbuf = r9, \ + .radio_lgen_tune1 = r10, \ + .radio_lgen_tune2 = r11, \ + .radio_c1_lgbuf_atune = r12, \ + .radio_c1_lgbuf_gtune = r13, \ + .radio_c1_rx_rfr1 = r14, \ + .radio_c1_tx_pgapadtn = r15, \ + .radio_c1_tx_mxbgtrim = r16, \ + .radio_c2_lgbuf_atune = r17, \ + .radio_c2_lgbuf_gtune = r18, \ + .radio_c2_rx_rfr1 = r19, \ + .radio_c2_tx_pgapadtn = r20, \ + .radio_c2_tx_mxbgtrim = r21 + +#define PHYREGS(r0, r1, r2, r3, r4, r5) \ + .phy_regs.phy_bw1a = r0, \ + .phy_regs.phy_bw2 = r1, \ + .phy_regs.phy_bw3 = r2, \ + .phy_regs.phy_bw4 = r3, \ + .phy_regs.phy_bw5 = r4, \ + .phy_regs.phy_bw6 = r5 + +static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab_rev2[] = { + { .channel = 184, + .freq = 4920, /* MHz */ + .unk2 = 3280, + RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602), + }, + { .channel = 186, + .freq = 4930, /* MHz */ + .unk2 = 3287, + RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502), + }, + { .channel = 188, + .freq = 4940, /* MHz */ + .unk2 = 3293, + RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402), + }, + { .channel = 190, + .freq = 4950, /* MHz */ + .unk2 = 3300, + RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302), + }, + { .channel = 192, + .freq = 4960, /* MHz */ + .unk2 = 3307, + RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202), + }, + { .channel = 194, + .freq = 4970, /* MHz */ + .unk2 = 3313, + RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102), + }, + { .channel = 196, + .freq = 4980, /* MHz */ + .unk2 = 3320, + RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02), + }, + { .channel = 198, + .freq = 4990, /* MHz */ + .unk2 = 3327, + RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02), + }, + { .channel = 200, + .freq = 5000, /* MHz */ + .unk2 = 3333, + RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02), + }, + { .channel = 202, + .freq = 5010, /* MHz */ + .unk2 = 3340, + RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02), + }, + { .channel = 204, + .freq = 5020, /* MHz */ + .unk2 = 3347, + RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02), + }, + { .channel = 206, + .freq = 5030, /* MHz */ + .unk2 = 3353, + RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02), + }, + { .channel = 208, + .freq = 5040, /* MHz */ + .unk2 = 3360, + RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902), + }, + { .channel = 210, + .freq = 5050, /* MHz */ + .unk2 = 3367, + RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, + 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), + PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802), + }, + { .channel = 212, + .freq = 5060, /* MHz */ + .unk2 = 3373, + RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, + 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), + PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702), + }, + { .channel = 214, + .freq = 5070, /* MHz */ + .unk2 = 3380, + RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A, + 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, + 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), + PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602), + }, + { .channel = 216, + .freq = 5080, /* MHz */ + .unk2 = 3387, + RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, + 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), + PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502), + }, + { .channel = 218, + .freq = 5090, /* MHz */ + .unk2 = 3393, + RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, + 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), + PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402), + }, + { .channel = 220, + .freq = 5100, /* MHz */ + .unk2 = 3400, + RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, + 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), + PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302), + }, + { .channel = 222, + .freq = 5110, /* MHz */ + .unk2 = 3407, + RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A, + 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, + 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), + PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202), + }, + { .channel = 224, + .freq = 5120, /* MHz */ + .unk2 = 3413, + RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, + 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), + PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102), + }, + { .channel = 226, + .freq = 5130, /* MHz */ + .unk2 = 3420, + RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, + 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), + PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002), + }, + { .channel = 228, + .freq = 5140, /* MHz */ + .unk2 = 3427, + RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A, + 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, + 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B), + PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01), + }, + { .channel = 32, + .freq = 5160, /* MHz */ + .unk2 = 3440, + RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, + 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), + PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01), + }, + { .channel = 34, + .freq = 5170, /* MHz */ + .unk2 = 3447, + RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, + 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), + PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01), + }, + { .channel = 36, + .freq = 5180, /* MHz */ + .unk2 = 3453, + RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, + 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), + PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01), + }, + { .channel = 38, + .freq = 5190, /* MHz */ + .unk2 = 3460, + RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A, + 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, + 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), + PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01), + }, + { .channel = 40, + .freq = 5200, /* MHz */ + .unk2 = 3467, + RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, + 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), + PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901), + }, + { .channel = 42, + .freq = 5210, /* MHz */ + .unk2 = 3473, + RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, + 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), + PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801), + }, + { .channel = 44, + .freq = 5220, /* MHz */ + .unk2 = 3480, + RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, + 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), + PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701), + }, + { .channel = 46, + .freq = 5230, /* MHz */ + .unk2 = 3487, + RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A, + 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, + 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), + PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601), + }, + { .channel = 48, + .freq = 5240, /* MHz */ + .unk2 = 3493, + RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, + 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), + PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501), + }, + { .channel = 50, + .freq = 5250, /* MHz */ + .unk2 = 3500, + RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, + 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), + PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401), + }, + { .channel = 52, + .freq = 5260, /* MHz */ + .unk2 = 3507, + RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, + 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), + PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301), + }, + { .channel = 54, + .freq = 5270, /* MHz */ + .unk2 = 3513, + RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A, + 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, + 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), + PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201), + }, + { .channel = 56, + .freq = 5280, /* MHz */ + .unk2 = 3520, + RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, + 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), + PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101), + }, + { .channel = 58, + .freq = 5290, /* MHz */ + .unk2 = 3527, + RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, + 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), + PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001), + }, + { .channel = 60, + .freq = 5300, /* MHz */ + .unk2 = 3533, + RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, + 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), + PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001), + }, + { .channel = 62, + .freq = 5310, /* MHz */ + .unk2 = 3540, + RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A, + 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, + 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), + PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01), + }, + { .channel = 64, + .freq = 5320, /* MHz */ + .unk2 = 3547, + RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, + 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), + PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01), + }, + { .channel = 66, + .freq = 5330, /* MHz */ + .unk2 = 3553, + RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, + 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), + PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01), + }, + { .channel = 68, + .freq = 5340, /* MHz */ + .unk2 = 3560, + RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, + 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), + PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01), + }, + { .channel = 70, + .freq = 5350, /* MHz */ + .unk2 = 3567, + RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A, + 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, + 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), + PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01), + }, + { .channel = 72, + .freq = 5360, /* MHz */ + .unk2 = 3573, + RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, + 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), + PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01), + }, + { .channel = 74, + .freq = 5370, /* MHz */ + .unk2 = 3580, + RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, + 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), + PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901), + }, + { .channel = 76, + .freq = 5380, /* MHz */ + .unk2 = 3587, + RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, + 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), + PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801), + }, + { .channel = 78, + .freq = 5390, /* MHz */ + .unk2 = 3593, + RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A, + 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, + 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), + PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701), + }, + { .channel = 80, + .freq = 5400, /* MHz */ + .unk2 = 3600, + RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, + 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), + PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601), + }, + { .channel = 82, + .freq = 5410, /* MHz */ + .unk2 = 3607, + RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, + 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), + PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501), + }, + { .channel = 84, + .freq = 5420, /* MHz */ + .unk2 = 3613, + RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, + 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), + PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501), + }, + { .channel = 86, + .freq = 5430, /* MHz */ + .unk2 = 3620, + RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A, + 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, + 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), + PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401), + }, + { .channel = 88, + .freq = 5440, /* MHz */ + .unk2 = 3627, + RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, + 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), + PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301), + }, + { .channel = 90, + .freq = 5450, /* MHz */ + .unk2 = 3633, + RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, + 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), + PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201), + }, + { .channel = 92, + .freq = 5460, /* MHz */ + .unk2 = 3640, + RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, + 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), + PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101), + }, + { .channel = 94, + .freq = 5470, /* MHz */ + .unk2 = 3647, + RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A, + 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, + 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), + PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001), + }, + { .channel = 96, + .freq = 5480, /* MHz */ + .unk2 = 3653, + RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, + 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), + PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01), + }, + { .channel = 98, + .freq = 5490, /* MHz */ + .unk2 = 3660, + RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, + 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), + PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01), + }, + { .channel = 100, + .freq = 5500, /* MHz */ + .unk2 = 3667, + RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, + 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), + PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01), + }, + { .channel = 102, + .freq = 5510, /* MHz */ + .unk2 = 3673, + RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A, + 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, + 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), + PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01), + }, + { .channel = 104, + .freq = 5520, /* MHz */ + .unk2 = 3680, + RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), + PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01), + }, + { .channel = 106, + .freq = 5530, /* MHz */ + .unk2 = 3687, + RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), + PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01), + }, + { .channel = 108, + .freq = 5540, /* MHz */ + .unk2 = 3693, + RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), + PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01), + }, + { .channel = 110, + .freq = 5550, /* MHz */ + .unk2 = 3700, + RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A, + 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, + 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), + PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901), + }, + { .channel = 112, + .freq = 5560, /* MHz */ + .unk2 = 3707, + RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, + 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801), + }, + { .channel = 114, + .freq = 5570, /* MHz */ + .unk2 = 3713, + RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, + 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701), + }, + { .channel = 116, + .freq = 5580, /* MHz */ + .unk2 = 3720, + RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, + 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701), + }, + { .channel = 118, + .freq = 5590, /* MHz */ + .unk2 = 3727, + RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A, + 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, + 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601), + }, + { .channel = 120, + .freq = 5600, /* MHz */ + .unk2 = 3733, + RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, + 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501), + }, + { .channel = 122, + .freq = 5610, /* MHz */ + .unk2 = 3740, + RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, + 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), + PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401), + }, + { .channel = 124, + .freq = 5620, /* MHz */ + .unk2 = 3747, + RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301), + }, + { .channel = 126, + .freq = 5630, /* MHz */ + .unk2 = 3753, + RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A, + 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201), + }, + { .channel = 128, + .freq = 5640, /* MHz */ + .unk2 = 3760, + RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201), + }, + { .channel = 130, + .freq = 5650, /* MHz */ + .unk2 = 3767, + RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101), + }, + { .channel = 132, + .freq = 5660, /* MHz */ + .unk2 = 3773, + RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001), + }, + { .channel = 134, + .freq = 5670, /* MHz */ + .unk2 = 3780, + RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01), + }, + { .channel = 136, + .freq = 5680, /* MHz */ + .unk2 = 3787, + RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01), + }, + { .channel = 138, + .freq = 5690, /* MHz */ + .unk2 = 3793, + RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01), + }, + { .channel = 140, + .freq = 5700, /* MHz */ + .unk2 = 3800, + RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01), + }, + { .channel = 142, + .freq = 5710, /* MHz */ + .unk2 = 3807, + RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01), + }, + { .channel = 144, + .freq = 5720, /* MHz */ + .unk2 = 3813, + RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01), + }, + { .channel = 145, + .freq = 5725, /* MHz */ + .unk2 = 3817, + RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01), + }, + { .channel = 146, + .freq = 5730, /* MHz */ + .unk2 = 3820, + RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01), + }, + { .channel = 147, + .freq = 5735, /* MHz */ + .unk2 = 3823, + RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01), + }, + { .channel = 148, + .freq = 5740, /* MHz */ + .unk2 = 3827, + RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901), + }, + { .channel = 149, + .freq = 5745, /* MHz */ + .unk2 = 3830, + RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901), + }, + { .channel = 150, + .freq = 5750, /* MHz */ + .unk2 = 3833, + RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901), + }, + { .channel = 151, + .freq = 5755, /* MHz */ + .unk2 = 3837, + RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801), + }, + { .channel = 152, + .freq = 5760, /* MHz */ + .unk2 = 3840, + RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801), + }, + { .channel = 153, + .freq = 5765, /* MHz */ + .unk2 = 3843, + RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801), + }, + { .channel = 154, + .freq = 5770, /* MHz */ + .unk2 = 3847, + RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701), + }, + { .channel = 155, + .freq = 5775, /* MHz */ + .unk2 = 3850, + RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701), + }, + { .channel = 156, + .freq = 5780, /* MHz */ + .unk2 = 3853, + RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601), + }, + { .channel = 157, + .freq = 5785, /* MHz */ + .unk2 = 3857, + RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601), + }, + { .channel = 158, + .freq = 5790, /* MHz */ + .unk2 = 3860, + RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601), + }, + { .channel = 159, + .freq = 5795, /* MHz */ + .unk2 = 3863, + RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501), + }, + { .channel = 160, + .freq = 5800, /* MHz */ + .unk2 = 3867, + RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501), + }, + { .channel = 161, + .freq = 5805, /* MHz */ + .unk2 = 3870, + RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401), + }, + { .channel = 162, + .freq = 5810, /* MHz */ + .unk2 = 3873, + RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401), + }, + { .channel = 163, + .freq = 5815, /* MHz */ + .unk2 = 3877, + RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401), + }, + { .channel = 164, + .freq = 5820, /* MHz */ + .unk2 = 3880, + RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301), + }, + { .channel = 165, + .freq = 5825, /* MHz */ + .unk2 = 3883, + RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301), + }, + { .channel = 166, + .freq = 5830, /* MHz */ + .unk2 = 3887, + RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201), + }, + { .channel = 168, + .freq = 5840, /* MHz */ + .unk2 = 3893, + RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201), + }, + { .channel = 170, + .freq = 5850, /* MHz */ + .unk2 = 3900, + RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101), + }, + { .channel = 172, + .freq = 5860, /* MHz */ + .unk2 = 3907, + RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001), + }, + { .channel = 174, + .freq = 5870, /* MHz */ + .unk2 = 3913, + RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01), + }, + { .channel = 176, + .freq = 5880, /* MHz */ + .unk2 = 3920, + RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01), + }, + { .channel = 178, + .freq = 5890, /* MHz */ + .unk2 = 3927, + RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01), + }, + { .channel = 180, + .freq = 5900, /* MHz */ + .unk2 = 3933, + RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01), + }, + { .channel = 182, + .freq = 5910, /* MHz */ + .unk2 = 3940, + RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A, + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), + PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01), + }, + { .channel = 1, + .freq = 2412, /* MHz */ + .unk2 = 3216, + RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, + 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80), + PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304), + }, + { .channel = 2, + .freq = 2417, /* MHz */ + .unk2 = 3223, + RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, + 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80), + PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104), + }, + { .channel = 3, + .freq = 2422, /* MHz */ + .unk2 = 3229, + RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, + 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), + PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04), + }, + { .channel = 4, + .freq = 2427, /* MHz */ + .unk2 = 3236, + RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, + 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), + PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04), + }, + { .channel = 5, + .freq = 2432, /* MHz */ + .unk2 = 3243, + RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, + 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80), + PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04), + }, + { .channel = 6, + .freq = 2437, /* MHz */ + .unk2 = 3249, + RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, + 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80), + PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804), + }, + { .channel = 7, + .freq = 2442, /* MHz */ + .unk2 = 3256, + RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, + 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80), + PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604), + }, + { .channel = 8, + .freq = 2447, /* MHz */ + .unk2 = 3263, + RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, + 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80), + PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404), + }, + { .channel = 9, + .freq = 2452, /* MHz */ + .unk2 = 3269, + RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, + 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80), + PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104), + }, + { .channel = 10, + .freq = 2457, /* MHz */ + .unk2 = 3276, + RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, + 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80), + PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04), + }, + { .channel = 11, + .freq = 2462, /* MHz */ + .unk2 = 3283, + RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, + 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80), + PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04), + }, + { .channel = 12, + .freq = 2467, /* MHz */ + .unk2 = 3289, + RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, + 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80), + PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04), + }, + { .channel = 13, + .freq = 2472, /* MHz */ + .unk2 = 3296, + RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, + 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80), + PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904), + }, + { .channel = 14, + .freq = 2484, /* MHz */ + .unk2 = 3312, + RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15, + 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, + 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80), + PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404), + }, +}; + +void b2055_upload_inittab(struct b43_wldev *dev, + bool ghz5, bool ignore_uploadflag) +{ + const struct b2055_inittab_entry *e; + unsigned int i; + u16 value; + + for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) { + e = &(b2055_inittab[i]); + if (!(e->flags & B2055_INITTAB_ENTRY_OK)) + continue; + if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) { + if (ghz5) + value = e->ghz5; + else + value = e->ghz2; + b43_radio_write16(dev, i, value); + } + } +} + +const struct b43_nphy_channeltab_entry_rev2 * +b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel) +{ + const struct b43_nphy_channeltab_entry_rev2 *e; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev2); i++) { + e = &(b43_nphy_channeltab_rev2[i]); + if (e->channel == channel) + return e; + } + + return NULL; +} diff --git a/drivers/net/wireless/b43/radio_2055.h b/drivers/net/wireless/b43/radio_2055.h new file mode 100644 index 0000000000000000000000000000000000000000..d9bfa0f21b723ce7b34b2605ec5d65a8491715d2 --- /dev/null +++ b/drivers/net/wireless/b43/radio_2055.h @@ -0,0 +1,254 @@ +#ifndef B43_RADIO_2055_H_ +#define B43_RADIO_2055_H_ + +#include + +#include "tables_nphy.h" + +#define B2055_GEN_SPARE 0x00 /* GEN spare */ +#define B2055_SP_PINPD 0x02 /* SP PIN PD */ +#define B2055_C1_SP_RSSI 0x03 /* SP RSSI Core 1 */ +#define B2055_C1_SP_PDMISC 0x04 /* SP PD MISC Core 1 */ +#define B2055_C2_SP_RSSI 0x05 /* SP RSSI Core 2 */ +#define B2055_C2_SP_PDMISC 0x06 /* SP PD MISC Core 2 */ +#define B2055_C1_SP_RXGC1 0x07 /* SP RX GC1 Core 1 */ +#define B2055_C1_SP_RXGC2 0x08 /* SP RX GC2 Core 1 */ +#define B2055_C2_SP_RXGC1 0x09 /* SP RX GC1 Core 2 */ +#define B2055_C2_SP_RXGC2 0x0A /* SP RX GC2 Core 2 */ +#define B2055_C1_SP_LPFBWSEL 0x0B /* SP LPF BW select Core 1 */ +#define B2055_C2_SP_LPFBWSEL 0x0C /* SP LPF BW select Core 2 */ +#define B2055_C1_SP_TXGC1 0x0D /* SP TX GC1 Core 1 */ +#define B2055_C1_SP_TXGC2 0x0E /* SP TX GC2 Core 1 */ +#define B2055_C2_SP_TXGC1 0x0F /* SP TX GC1 Core 2 */ +#define B2055_C2_SP_TXGC2 0x10 /* SP TX GC2 Core 2 */ +#define B2055_MASTER1 0x11 /* Master control 1 */ +#define B2055_MASTER2 0x12 /* Master control 2 */ +#define B2055_PD_LGEN 0x13 /* PD LGEN */ +#define B2055_PD_PLLTS 0x14 /* PD PLL TS */ +#define B2055_C1_PD_LGBUF 0x15 /* PD Core 1 LGBUF */ +#define B2055_C1_PD_TX 0x16 /* PD Core 1 TX */ +#define B2055_C1_PD_RXTX 0x17 /* PD Core 1 RXTX */ +#define B2055_C1_PD_RSSIMISC 0x18 /* PD Core 1 RSSI MISC */ +#define B2055_C2_PD_LGBUF 0x19 /* PD Core 2 LGBUF */ +#define B2055_C2_PD_TX 0x1A /* PD Core 2 TX */ +#define B2055_C2_PD_RXTX 0x1B /* PD Core 2 RXTX */ +#define B2055_C2_PD_RSSIMISC 0x1C /* PD Core 2 RSSI MISC */ +#define B2055_PWRDET_LGEN 0x1D /* PWRDET LGEN */ +#define B2055_C1_PWRDET_LGBUF 0x1E /* PWRDET LGBUF Core 1 */ +#define B2055_C1_PWRDET_RXTX 0x1F /* PWRDET RXTX Core 1 */ +#define B2055_C2_PWRDET_LGBUF 0x20 /* PWRDET LGBUF Core 2 */ +#define B2055_C2_PWRDET_RXTX 0x21 /* PWRDET RXTX Core 2 */ +#define B2055_RRCCAL_CS 0x22 /* RRCCAL Control spare */ +#define B2055_RRCCAL_NOPTSEL 0x23 /* RRCCAL N OPT SEL */ +#define B2055_CAL_MISC 0x24 /* CAL MISC */ +#define B2055_CAL_COUT 0x25 /* CAL Counter out */ +#define B2055_CAL_COUT2 0x26 /* CAL Counter out 2 */ +#define B2055_CAL_CVARCTL 0x27 /* CAL CVAR Control */ +#define B2055_CAL_RVARCTL 0x28 /* CAL RVAR Control */ +#define B2055_CAL_LPOCTL 0x29 /* CAL LPO Control */ +#define B2055_CAL_TS 0x2A /* CAL TS */ +#define B2055_CAL_RCCALRTS 0x2B /* CAL RCCAL READ TS */ +#define B2055_CAL_RCALRTS 0x2C /* CAL RCAL READ TS */ +#define B2055_PADDRV 0x2D /* PAD driver */ +#define B2055_XOCTL1 0x2E /* XO Control 1 */ +#define B2055_XOCTL2 0x2F /* XO Control 2 */ +#define B2055_XOREGUL 0x30 /* XO Regulator */ +#define B2055_XOMISC 0x31 /* XO misc */ +#define B2055_PLL_LFC1 0x32 /* PLL LF C1 */ +#define B2055_PLL_CALVTH 0x33 /* PLL CAL VTH */ +#define B2055_PLL_LFC2 0x34 /* PLL LF C2 */ +#define B2055_PLL_REF 0x35 /* PLL reference */ +#define B2055_PLL_LFR1 0x36 /* PLL LF R1 */ +#define B2055_PLL_PFDCP 0x37 /* PLL PFD CP */ +#define B2055_PLL_IDAC_CPOPAMP 0x38 /* PLL IDAC CPOPAMP */ +#define B2055_PLL_CPREG 0x39 /* PLL CP Regulator */ +#define B2055_PLL_RCAL 0x3A /* PLL RCAL */ +#define B2055_RF_PLLMOD0 0x3B /* RF PLL MOD0 */ +#define B2055_RF_PLLMOD1 0x3C /* RF PLL MOD1 */ +#define B2055_RF_MMDIDAC1 0x3D /* RF MMD IDAC 1 */ +#define B2055_RF_MMDIDAC0 0x3E /* RF MMD IDAC 0 */ +#define B2055_RF_MMDSP 0x3F /* RF MMD spare */ +#define B2055_VCO_CAL1 0x40 /* VCO cal 1 */ +#define B2055_VCO_CAL2 0x41 /* VCO cal 2 */ +#define B2055_VCO_CAL3 0x42 /* VCO cal 3 */ +#define B2055_VCO_CAL4 0x43 /* VCO cal 4 */ +#define B2055_VCO_CAL5 0x44 /* VCO cal 5 */ +#define B2055_VCO_CAL6 0x45 /* VCO cal 6 */ +#define B2055_VCO_CAL7 0x46 /* VCO cal 7 */ +#define B2055_VCO_CAL8 0x47 /* VCO cal 8 */ +#define B2055_VCO_CAL9 0x48 /* VCO cal 9 */ +#define B2055_VCO_CAL10 0x49 /* VCO cal 10 */ +#define B2055_VCO_CAL11 0x4A /* VCO cal 11 */ +#define B2055_VCO_CAL12 0x4B /* VCO cal 12 */ +#define B2055_VCO_CAL13 0x4C /* VCO cal 13 */ +#define B2055_VCO_CAL14 0x4D /* VCO cal 14 */ +#define B2055_VCO_CAL15 0x4E /* VCO cal 15 */ +#define B2055_VCO_CAL16 0x4F /* VCO cal 16 */ +#define B2055_VCO_KVCO 0x50 /* VCO KVCO */ +#define B2055_VCO_CAPTAIL 0x51 /* VCO CAP TAIL */ +#define B2055_VCO_IDACVCO 0x52 /* VCO IDAC VCO */ +#define B2055_VCO_REG 0x53 /* VCO Regulator */ +#define B2055_PLL_RFVTH 0x54 /* PLL RF VTH */ +#define B2055_LGBUF_CENBUF 0x55 /* LGBUF CEN BUF */ +#define B2055_LGEN_TUNE1 0x56 /* LGEN tune 1 */ +#define B2055_LGEN_TUNE2 0x57 /* LGEN tune 2 */ +#define B2055_LGEN_IDAC1 0x58 /* LGEN IDAC 1 */ +#define B2055_LGEN_IDAC2 0x59 /* LGEN IDAC 2 */ +#define B2055_LGEN_BIASC 0x5A /* LGEN BIAS counter */ +#define B2055_LGEN_BIASIDAC 0x5B /* LGEN BIAS IDAC */ +#define B2055_LGEN_RCAL 0x5C /* LGEN RCAL */ +#define B2055_LGEN_DIV 0x5D /* LGEN div */ +#define B2055_LGEN_SPARE2 0x5E /* LGEN spare 2 */ +#define B2055_C1_LGBUF_ATUNE 0x5F /* Core 1 LGBUF A tune */ +#define B2055_C1_LGBUF_GTUNE 0x60 /* Core 1 LGBUF G tune */ +#define B2055_C1_LGBUF_DIV 0x61 /* Core 1 LGBUF div */ +#define B2055_C1_LGBUF_AIDAC 0x62 /* Core 1 LGBUF A IDAC */ +#define B2055_C1_LGBUF_GIDAC 0x63 /* Core 1 LGBUF G IDAC */ +#define B2055_C1_LGBUF_IDACFO 0x64 /* Core 1 LGBUF IDAC filter override */ +#define B2055_C1_LGBUF_SPARE 0x65 /* Core 1 LGBUF spare */ +#define B2055_C1_RX_RFSPC1 0x66 /* Core 1 RX RF SPC1 */ +#define B2055_C1_RX_RFR1 0x67 /* Core 1 RX RF reg 1 */ +#define B2055_C1_RX_RFR2 0x68 /* Core 1 RX RF reg 2 */ +#define B2055_C1_RX_RFRCAL 0x69 /* Core 1 RX RF RCAL */ +#define B2055_C1_RX_BB_BLCMP 0x6A /* Core 1 RX Baseband BUFI LPF CMP */ +#define B2055_C1_RX_BB_LPF 0x6B /* Core 1 RX Baseband LPF */ +#define B2055_C1_RX_BB_MIDACHP 0x6C /* Core 1 RX Baseband MIDAC High-pass */ +#define B2055_C1_RX_BB_VGA1IDAC 0x6D /* Core 1 RX Baseband VGA1 IDAC */ +#define B2055_C1_RX_BB_VGA2IDAC 0x6E /* Core 1 RX Baseband VGA2 IDAC */ +#define B2055_C1_RX_BB_VGA3IDAC 0x6F /* Core 1 RX Baseband VGA3 IDAC */ +#define B2055_C1_RX_BB_BUFOCTL 0x70 /* Core 1 RX Baseband BUFO Control */ +#define B2055_C1_RX_BB_RCCALCTL 0x71 /* Core 1 RX Baseband RCCAL Control */ +#define B2055_C1_RX_BB_RSSICTL1 0x72 /* Core 1 RX Baseband RSSI Control 1 */ +#define B2055_C1_RX_BB_RSSICTL2 0x73 /* Core 1 RX Baseband RSSI Control 2 */ +#define B2055_C1_RX_BB_RSSICTL3 0x74 /* Core 1 RX Baseband RSSI Control 3 */ +#define B2055_C1_RX_BB_RSSICTL4 0x75 /* Core 1 RX Baseband RSSI Control 4 */ +#define B2055_C1_RX_BB_RSSICTL5 0x76 /* Core 1 RX Baseband RSSI Control 5 */ +#define B2055_C1_RX_BB_REG 0x77 /* Core 1 RX Baseband Regulator */ +#define B2055_C1_RX_BB_SPARE1 0x78 /* Core 1 RX Baseband spare 1 */ +#define B2055_C1_RX_TXBBRCAL 0x79 /* Core 1 RX TX BB RCAL */ +#define B2055_C1_TX_RF_SPGA 0x7A /* Core 1 TX RF SGM PGA */ +#define B2055_C1_TX_RF_SPAD 0x7B /* Core 1 TX RF SGM PAD */ +#define B2055_C1_TX_RF_CNTPGA1 0x7C /* Core 1 TX RF counter PGA 1 */ +#define B2055_C1_TX_RF_CNTPAD1 0x7D /* Core 1 TX RF counter PAD 1 */ +#define B2055_C1_TX_RF_PGAIDAC 0x7E /* Core 1 TX RF PGA IDAC */ +#define B2055_C1_TX_PGAPADTN 0x7F /* Core 1 TX PGA PAD TN */ +#define B2055_C1_TX_PADIDAC1 0x80 /* Core 1 TX PAD IDAC 1 */ +#define B2055_C1_TX_PADIDAC2 0x81 /* Core 1 TX PAD IDAC 2 */ +#define B2055_C1_TX_MXBGTRIM 0x82 /* Core 1 TX MX B/G TRIM */ +#define B2055_C1_TX_RF_RCAL 0x83 /* Core 1 TX RF RCAL */ +#define B2055_C1_TX_RF_PADTSSI1 0x84 /* Core 1 TX RF PAD TSSI1 */ +#define B2055_C1_TX_RF_PADTSSI2 0x85 /* Core 1 TX RF PAD TSSI2 */ +#define B2055_C1_TX_RF_SPARE 0x86 /* Core 1 TX RF spare */ +#define B2055_C1_TX_RF_IQCAL1 0x87 /* Core 1 TX RF I/Q CAL 1 */ +#define B2055_C1_TX_RF_IQCAL2 0x88 /* Core 1 TX RF I/Q CAL 2 */ +#define B2055_C1_TXBB_RCCAL 0x89 /* Core 1 TXBB RC CAL Control */ +#define B2055_C1_TXBB_LPF1 0x8A /* Core 1 TXBB LPF 1 */ +#define B2055_C1_TX_VOSCNCL 0x8B /* Core 1 TX VOS CNCL */ +#define B2055_C1_TX_LPF_MXGMIDAC 0x8C /* Core 1 TX LPF MXGM IDAC */ +#define B2055_C1_TX_BB_MXGM 0x8D /* Core 1 TX BB MXGM */ +#define B2055_C2_LGBUF_ATUNE 0x8E /* Core 2 LGBUF A tune */ +#define B2055_C2_LGBUF_GTUNE 0x8F /* Core 2 LGBUF G tune */ +#define B2055_C2_LGBUF_DIV 0x90 /* Core 2 LGBUF div */ +#define B2055_C2_LGBUF_AIDAC 0x91 /* Core 2 LGBUF A IDAC */ +#define B2055_C2_LGBUF_GIDAC 0x92 /* Core 2 LGBUF G IDAC */ +#define B2055_C2_LGBUF_IDACFO 0x93 /* Core 2 LGBUF IDAC filter override */ +#define B2055_C2_LGBUF_SPARE 0x94 /* Core 2 LGBUF spare */ +#define B2055_C2_RX_RFSPC1 0x95 /* Core 2 RX RF SPC1 */ +#define B2055_C2_RX_RFR1 0x96 /* Core 2 RX RF reg 1 */ +#define B2055_C2_RX_RFR2 0x97 /* Core 2 RX RF reg 2 */ +#define B2055_C2_RX_RFRCAL 0x98 /* Core 2 RX RF RCAL */ +#define B2055_C2_RX_BB_BLCMP 0x99 /* Core 2 RX Baseband BUFI LPF CMP */ +#define B2055_C2_RX_BB_LPF 0x9A /* Core 2 RX Baseband LPF */ +#define B2055_C2_RX_BB_MIDACHP 0x9B /* Core 2 RX Baseband MIDAC High-pass */ +#define B2055_C2_RX_BB_VGA1IDAC 0x9C /* Core 2 RX Baseband VGA1 IDAC */ +#define B2055_C2_RX_BB_VGA2IDAC 0x9D /* Core 2 RX Baseband VGA2 IDAC */ +#define B2055_C2_RX_BB_VGA3IDAC 0x9E /* Core 2 RX Baseband VGA3 IDAC */ +#define B2055_C2_RX_BB_BUFOCTL 0x9F /* Core 2 RX Baseband BUFO Control */ +#define B2055_C2_RX_BB_RCCALCTL 0xA0 /* Core 2 RX Baseband RCCAL Control */ +#define B2055_C2_RX_BB_RSSICTL1 0xA1 /* Core 2 RX Baseband RSSI Control 1 */ +#define B2055_C2_RX_BB_RSSICTL2 0xA2 /* Core 2 RX Baseband RSSI Control 2 */ +#define B2055_C2_RX_BB_RSSICTL3 0xA3 /* Core 2 RX Baseband RSSI Control 3 */ +#define B2055_C2_RX_BB_RSSICTL4 0xA4 /* Core 2 RX Baseband RSSI Control 4 */ +#define B2055_C2_RX_BB_RSSICTL5 0xA5 /* Core 2 RX Baseband RSSI Control 5 */ +#define B2055_C2_RX_BB_REG 0xA6 /* Core 2 RX Baseband Regulator */ +#define B2055_C2_RX_BB_SPARE1 0xA7 /* Core 2 RX Baseband spare 1 */ +#define B2055_C2_RX_TXBBRCAL 0xA8 /* Core 2 RX TX BB RCAL */ +#define B2055_C2_TX_RF_SPGA 0xA9 /* Core 2 TX RF SGM PGA */ +#define B2055_C2_TX_RF_SPAD 0xAA /* Core 2 TX RF SGM PAD */ +#define B2055_C2_TX_RF_CNTPGA1 0xAB /* Core 2 TX RF counter PGA 1 */ +#define B2055_C2_TX_RF_CNTPAD1 0xAC /* Core 2 TX RF counter PAD 1 */ +#define B2055_C2_TX_RF_PGAIDAC 0xAD /* Core 2 TX RF PGA IDAC */ +#define B2055_C2_TX_PGAPADTN 0xAE /* Core 2 TX PGA PAD TN */ +#define B2055_C2_TX_PADIDAC1 0xAF /* Core 2 TX PAD IDAC 1 */ +#define B2055_C2_TX_PADIDAC2 0xB0 /* Core 2 TX PAD IDAC 2 */ +#define B2055_C2_TX_MXBGTRIM 0xB1 /* Core 2 TX MX B/G TRIM */ +#define B2055_C2_TX_RF_RCAL 0xB2 /* Core 2 TX RF RCAL */ +#define B2055_C2_TX_RF_PADTSSI1 0xB3 /* Core 2 TX RF PAD TSSI1 */ +#define B2055_C2_TX_RF_PADTSSI2 0xB4 /* Core 2 TX RF PAD TSSI2 */ +#define B2055_C2_TX_RF_SPARE 0xB5 /* Core 2 TX RF spare */ +#define B2055_C2_TX_RF_IQCAL1 0xB6 /* Core 2 TX RF I/Q CAL 1 */ +#define B2055_C2_TX_RF_IQCAL2 0xB7 /* Core 2 TX RF I/Q CAL 2 */ +#define B2055_C2_TXBB_RCCAL 0xB8 /* Core 2 TXBB RC CAL Control */ +#define B2055_C2_TXBB_LPF1 0xB9 /* Core 2 TXBB LPF 1 */ +#define B2055_C2_TX_VOSCNCL 0xBA /* Core 2 TX VOS CNCL */ +#define B2055_C2_TX_LPF_MXGMIDAC 0xBB /* Core 2 TX LPF MXGM IDAC */ +#define B2055_C2_TX_BB_MXGM 0xBC /* Core 2 TX BB MXGM */ +#define B2055_PRG_GCHP21 0xBD /* PRG GC HPVGA23 21 */ +#define B2055_PRG_GCHP22 0xBE /* PRG GC HPVGA23 22 */ +#define B2055_PRG_GCHP23 0xBF /* PRG GC HPVGA23 23 */ +#define B2055_PRG_GCHP24 0xC0 /* PRG GC HPVGA23 24 */ +#define B2055_PRG_GCHP25 0xC1 /* PRG GC HPVGA23 25 */ +#define B2055_PRG_GCHP26 0xC2 /* PRG GC HPVGA23 26 */ +#define B2055_PRG_GCHP27 0xC3 /* PRG GC HPVGA23 27 */ +#define B2055_PRG_GCHP28 0xC4 /* PRG GC HPVGA23 28 */ +#define B2055_PRG_GCHP29 0xC5 /* PRG GC HPVGA23 29 */ +#define B2055_PRG_GCHP30 0xC6 /* PRG GC HPVGA23 30 */ +#define B2055_C1_LNA_GAINBST 0xCD /* Core 1 LNA GAINBST */ +#define B2055_C1_B0NB_RSSIVCM 0xD2 /* Core 1 B0 narrow-band RSSI VCM */ +#define B2055_C1_GENSPARE2 0xD6 /* Core 1 GEN spare 2 */ +#define B2055_C2_LNA_GAINBST 0xD9 /* Core 2 LNA GAINBST */ +#define B2055_C2_B0NB_RSSIVCM 0xDE /* Core 2 B0 narrow-band RSSI VCM */ +#define B2055_C2_GENSPARE2 0xE2 /* Core 2 GEN spare 2 */ + +struct b43_nphy_channeltab_entry_rev2 { + /* The channel number */ + u8 channel; + /* The channel frequency in MHz */ + u16 freq; + /* An unknown value */ + u16 unk2; + /* Radio register values on channelswitch */ + u8 radio_pll_ref; + u8 radio_rf_pllmod0; + u8 radio_rf_pllmod1; + u8 radio_vco_captail; + u8 radio_vco_cal1; + u8 radio_vco_cal2; + u8 radio_pll_lfc1; + u8 radio_pll_lfr1; + u8 radio_pll_lfc2; + u8 radio_lgbuf_cenbuf; + u8 radio_lgen_tune1; + u8 radio_lgen_tune2; + u8 radio_c1_lgbuf_atune; + u8 radio_c1_lgbuf_gtune; + u8 radio_c1_rx_rfr1; + u8 radio_c1_tx_pgapadtn; + u8 radio_c1_tx_mxbgtrim; + u8 radio_c2_lgbuf_atune; + u8 radio_c2_lgbuf_gtune; + u8 radio_c2_rx_rfr1; + u8 radio_c2_tx_pgapadtn; + u8 radio_c2_tx_mxbgtrim; + /* PHY register values on channelswitch */ + struct b43_phy_n_sfo_cfg phy_regs; +}; + +/* Upload the default register value table. + * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz + * table is uploaded. If "ignore_uploadflag" is true, we upload any value + * and ignore the "UPLOAD" flag. */ +void b2055_upload_inittab(struct b43_wldev *dev, + bool ghz5, bool ignore_uploadflag); + +#endif /* B43_RADIO_2055_H_ */ diff --git a/drivers/net/wireless/b43/radio_2056.c b/drivers/net/wireless/b43/radio_2056.c new file mode 100644 index 0000000000000000000000000000000000000000..d8563192ce56cc538086e3171fd68fed6472c24f --- /dev/null +++ b/drivers/net/wireless/b43/radio_2056.c @@ -0,0 +1,43 @@ +/* + + Broadcom B43 wireless driver + IEEE 802.11n 2056 radio device data tables + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "b43.h" +#include "radio_2056.h" +#include "phy_common.h" + +static const struct b43_nphy_channeltab_entry_rev3 b43_nphy_channeltab_rev3[] = { +}; + +const struct b43_nphy_channeltab_entry_rev3 * +b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq) +{ + const struct b43_nphy_channeltab_entry_rev3 *e; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab_rev3); i++) { + e = &(b43_nphy_channeltab_rev3[i]); + if (e->freq == freq) + return e; + } + + return NULL; +} diff --git a/drivers/net/wireless/b43/radio_2056.h b/drivers/net/wireless/b43/radio_2056.h new file mode 100644 index 0000000000000000000000000000000000000000..fda6dafecb8cb683faef59118a38661e04e340c9 --- /dev/null +++ b/drivers/net/wireless/b43/radio_2056.h @@ -0,0 +1,42 @@ +/* + + Broadcom B43 wireless driver + + Copyright (c) 2010 Rafał Miłecki + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef B43_RADIO_2056_H_ +#define B43_RADIO_2056_H_ + +#include + +#include "tables_nphy.h" + +struct b43_nphy_channeltab_entry_rev3 { + /* The channel number */ + u8 channel; + /* The channel frequency in MHz */ + u16 freq; + /* Radio register values on channelswitch */ + /* TODO */ + /* PHY register values on channelswitch */ + struct b43_phy_n_sfo_cfg phy_regs; +}; + +#endif /* B43_RADIO_2056_H_ */ diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index d96e870ab8fe8cea97c821c27076b2b99a47dfc8..d60db078eae20127f394bc9fd1a0591d5d7f0e73 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -1,7 +1,7 @@ /* Broadcom B43 wireless driver - IEEE 802.11n PHY and radio device data tables + IEEE 802.11n PHY data tables Copyright (c) 2008 Michael Buesch @@ -27,1315 +27,6 @@ #include "phy_common.h" #include "phy_n.h" - -struct b2055_inittab_entry { - /* Value to write if we use the 5GHz band. */ - u16 ghz5; - /* Value to write if we use the 2.4GHz band. */ - u16 ghz2; - /* Flags */ - u8 flags; -#define B2055_INITTAB_ENTRY_OK 0x01 -#define B2055_INITTAB_UPLOAD 0x02 -}; -#define UPLOAD .flags = B2055_INITTAB_ENTRY_OK | B2055_INITTAB_UPLOAD -#define NOUPLOAD .flags = B2055_INITTAB_ENTRY_OK - -static const struct b2055_inittab_entry b2055_inittab [] = { - [B2055_SP_PINPD] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, - [B2055_C1_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, }, - [B2055_C2_SP_RSSI] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_SP_PDMISC] = { .ghz5 = 0x0027, .ghz2 = 0x0027, NOUPLOAD, }, - [B2055_C1_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, }, - [B2055_C1_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, - [B2055_C2_SP_RXGC1] = { .ghz5 = 0x007F, .ghz2 = 0x007F, UPLOAD, }, - [B2055_C2_SP_RXGC2] = { .ghz5 = 0x0007, .ghz2 = 0x0007, UPLOAD, }, - [B2055_C1_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_C2_SP_LPFBWSEL] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_C1_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, }, - [B2055_C1_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, - [B2055_C2_SP_TXGC1] = { .ghz5 = 0x004F, .ghz2 = 0x004F, UPLOAD, }, - [B2055_C2_SP_TXGC2] = { .ghz5 = 0x0005, .ghz2 = 0x0005, UPLOAD, }, - [B2055_MASTER1] = { .ghz5 = 0x00D0, .ghz2 = 0x00D0, NOUPLOAD, }, - [B2055_MASTER2] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, - [B2055_PD_LGEN] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PD_PLLTS] = { .ghz5 = 0x0040, .ghz2 = 0x0040, NOUPLOAD, }, - [B2055_C1_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_PD_LGBUF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_PD_TX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_PD_RXTX] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_PD_RSSIMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PWRDET_LGEN] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, - [B2055_C1_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, - [B2055_C1_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, - [B2055_C2_PWRDET_LGBUF] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, - [B2055_C2_PWRDET_RXTX] = { .ghz5 = 0x00C0, .ghz2 = 0x00C0, NOUPLOAD, }, - [B2055_RRCCAL_CS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_RRCCAL_NOPTSEL] = { .ghz5 = 0x002C, .ghz2 = 0x002C, NOUPLOAD, }, - [B2055_CAL_MISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_COUT] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_COUT2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_CVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_RVARCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_LPOCTL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_TS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_RCCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_CAL_RCALRTS] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PADDRV] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, - [B2055_XOCTL1] = { .ghz5 = 0x0038, .ghz2 = 0x0038, NOUPLOAD, }, - [B2055_XOCTL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_XOREGUL] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, - [B2055_XOMISC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PLL_LFC1] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_PLL_CALVTH] = { .ghz5 = 0x0087, .ghz2 = 0x0087, NOUPLOAD, }, - [B2055_PLL_LFC2] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, }, - [B2055_PLL_REF] = { .ghz5 = 0x0070, .ghz2 = 0x0070, NOUPLOAD, }, - [B2055_PLL_LFR1] = { .ghz5 = 0x0011, .ghz2 = 0x0011, NOUPLOAD, }, - [B2055_PLL_PFDCP] = { .ghz5 = 0x0018, .ghz2 = 0x0018, UPLOAD, }, - [B2055_PLL_IDAC_CPOPAMP] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_PLL_CPREG] = { .ghz5 = 0x0004, .ghz2 = 0x0004, UPLOAD, }, - [B2055_PLL_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_RF_PLLMOD0] = { .ghz5 = 0x009E, .ghz2 = 0x009E, NOUPLOAD, }, - [B2055_RF_PLLMOD1] = { .ghz5 = 0x0009, .ghz2 = 0x0009, NOUPLOAD, }, - [B2055_RF_MMDIDAC1] = { .ghz5 = 0x00C8, .ghz2 = 0x00C8, UPLOAD, }, - [B2055_RF_MMDIDAC0] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_RF_MMDSP] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL3] = { .ghz5 = 0x0001, .ghz2 = 0x0001, NOUPLOAD, }, - [B2055_VCO_CAL4] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, - [B2055_VCO_CAL5] = { .ghz5 = 0x0096, .ghz2 = 0x0096, NOUPLOAD, }, - [B2055_VCO_CAL6] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, }, - [B2055_VCO_CAL7] = { .ghz5 = 0x003E, .ghz2 = 0x003E, NOUPLOAD, }, - [B2055_VCO_CAL8] = { .ghz5 = 0x0013, .ghz2 = 0x0013, NOUPLOAD, }, - [B2055_VCO_CAL9] = { .ghz5 = 0x0002, .ghz2 = 0x0002, NOUPLOAD, }, - [B2055_VCO_CAL10] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_VCO_CAL11] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_VCO_CAL12] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL13] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL14] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL15] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_CAL16] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_VCO_KVCO] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_VCO_CAPTAIL] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_VCO_IDACVCO] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_VCO_REG] = { .ghz5 = 0x0084, .ghz2 = 0x0084, UPLOAD, }, - [B2055_PLL_RFVTH] = { .ghz5 = 0x00C3, .ghz2 = 0x00C3, NOUPLOAD, }, - [B2055_LGBUF_CENBUF] = { .ghz5 = 0x008F, .ghz2 = 0x008F, NOUPLOAD, }, - [B2055_LGEN_TUNE1] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, - [B2055_LGEN_TUNE2] = { .ghz5 = 0x00FF, .ghz2 = 0x00FF, NOUPLOAD, }, - [B2055_LGEN_IDAC1] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_LGEN_IDAC2] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_LGEN_BIASC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_LGEN_BIASIDAC] = { .ghz5 = 0x00CC, .ghz2 = 0x00CC, NOUPLOAD, }, - [B2055_LGEN_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_LGEN_DIV] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, - [B2055_LGEN_SPARE2] = { .ghz5 = 0x0080, .ghz2 = 0x0080, NOUPLOAD, }, - [B2055_C1_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, }, - [B2055_C1_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C1_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C1_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, }, - [B2055_C1_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C1_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, }, - [B2055_C1_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, }, - [B2055_C1_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_C1_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, - [B2055_C1_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C1_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, }, - [B2055_C1_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_C1_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, - [B2055_C1_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C1_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, }, - [B2055_C1_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, }, - [B2055_C1_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, }, - [B2055_C1_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, }, - [B2055_C1_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, }, - [B2055_C1_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, - [B2055_C1_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C1_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_C1_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_C1_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_C1_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, - [B2055_C1_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, }, - [B2055_C1_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_C1_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, }, - [B2055_C1_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, }, - [B2055_C1_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C1_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C1_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, - [B2055_C1_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_C1_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, - [B2055_C1_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C1_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, - [B2055_C1_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C1_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, }, - [B2055_C1_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, }, - [B2055_C1_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_LGBUF_ATUNE] = { .ghz5 = 0x00F8, .ghz2 = 0x00F8, NOUPLOAD, }, - [B2055_C2_LGBUF_GTUNE] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C2_LGBUF_DIV] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C2_LGBUF_AIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0008, UPLOAD, }, - [B2055_C2_LGBUF_GIDAC] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C2_LGBUF_IDACFO] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_LGBUF_SPARE] = { .ghz5 = 0x0001, .ghz2 = 0x0001, UPLOAD, }, - [B2055_C2_RX_RFSPC1] = { .ghz5 = 0x008A, .ghz2 = 0x008A, NOUPLOAD, }, - [B2055_C2_RX_RFR1] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_C2_RX_RFR2] = { .ghz5 = 0x0083, .ghz2 = 0x0083, NOUPLOAD, }, - [B2055_C2_RX_RFRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C2_RX_BB_BLCMP] = { .ghz5 = 0x00A0, .ghz2 = 0x00A0, NOUPLOAD, }, - [B2055_C2_RX_BB_LPF] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_C2_RX_BB_MIDACHP] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, - [B2055_C2_RX_BB_VGA1IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_RX_BB_VGA2IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_RX_BB_VGA3IDAC] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_RX_BB_BUFOCTL] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_RX_BB_RCCALCTL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C2_RX_BB_RSSICTL1] = { .ghz5 = 0x006A, .ghz2 = 0x006A, UPLOAD, }, - [B2055_C2_RX_BB_RSSICTL2] = { .ghz5 = 0x00AB, .ghz2 = 0x00AB, UPLOAD, }, - [B2055_C2_RX_BB_RSSICTL3] = { .ghz5 = 0x0013, .ghz2 = 0x0013, UPLOAD, }, - [B2055_C2_RX_BB_RSSICTL4] = { .ghz5 = 0x00C1, .ghz2 = 0x00C1, UPLOAD, }, - [B2055_C2_RX_BB_RSSICTL5] = { .ghz5 = 0x00AA, .ghz2 = 0x00AA, UPLOAD, }, - [B2055_C2_RX_BB_REG] = { .ghz5 = 0x0087, .ghz2 = 0x0087, UPLOAD, }, - [B2055_C2_RX_BB_SPARE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_RX_TXBBRCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C2_TX_RF_SPGA] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_C2_TX_RF_SPAD] = { .ghz5 = 0x0007, .ghz2 = 0x0007, NOUPLOAD, }, - [B2055_C2_TX_RF_CNTPGA1] = { .ghz5 = 0x0015, .ghz2 = 0x0015, NOUPLOAD, }, - [B2055_C2_TX_RF_CNTPAD1] = { .ghz5 = 0x0055, .ghz2 = 0x0055, NOUPLOAD, }, - [B2055_C2_TX_RF_PGAIDAC] = { .ghz5 = 0x0097, .ghz2 = 0x0097, UPLOAD, }, - [B2055_C2_TX_PGAPADTN] = { .ghz5 = 0x0008, .ghz2 = 0x0008, NOUPLOAD, }, - [B2055_C2_TX_PADIDAC1] = { .ghz5 = 0x0014, .ghz2 = 0x0014, UPLOAD, }, - [B2055_C2_TX_PADIDAC2] = { .ghz5 = 0x0033, .ghz2 = 0x0033, NOUPLOAD, }, - [B2055_C2_TX_MXBGTRIM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [B2055_C2_TX_RF_RCAL] = { .ghz5 = 0x0006, .ghz2 = 0x0006, NOUPLOAD, }, - [B2055_C2_TX_RF_PADTSSI1] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, - [B2055_C2_TX_RF_PADTSSI2] = { .ghz5 = 0x000A, .ghz2 = 0x000A, NOUPLOAD, }, - [B2055_C2_TX_RF_SPARE] = { .ghz5 = 0x0003, .ghz2 = 0x0003, UPLOAD, }, - [B2055_C2_TX_RF_IQCAL1] = { .ghz5 = 0x002A, .ghz2 = 0x002A, NOUPLOAD, }, - [B2055_C2_TX_RF_IQCAL2] = { .ghz5 = 0x00A4, .ghz2 = 0x00A4, NOUPLOAD, }, - [B2055_C2_TXBB_RCCAL] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C2_TXBB_LPF1] = { .ghz5 = 0x0028, .ghz2 = 0x0028, NOUPLOAD, }, - [B2055_C2_TX_VOSCNCL] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_TX_LPF_MXGMIDAC] = { .ghz5 = 0x004A, .ghz2 = 0x004A, NOUPLOAD, }, - [B2055_C2_TX_BB_MXGM] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_PRG_GCHP21] = { .ghz5 = 0x0071, .ghz2 = 0x0071, NOUPLOAD, }, - [B2055_PRG_GCHP22] = { .ghz5 = 0x0072, .ghz2 = 0x0072, NOUPLOAD, }, - [B2055_PRG_GCHP23] = { .ghz5 = 0x0073, .ghz2 = 0x0073, NOUPLOAD, }, - [B2055_PRG_GCHP24] = { .ghz5 = 0x0074, .ghz2 = 0x0074, NOUPLOAD, }, - [B2055_PRG_GCHP25] = { .ghz5 = 0x0075, .ghz2 = 0x0075, NOUPLOAD, }, - [B2055_PRG_GCHP26] = { .ghz5 = 0x0076, .ghz2 = 0x0076, NOUPLOAD, }, - [B2055_PRG_GCHP27] = { .ghz5 = 0x0077, .ghz2 = 0x0077, NOUPLOAD, }, - [B2055_PRG_GCHP28] = { .ghz5 = 0x0078, .ghz2 = 0x0078, NOUPLOAD, }, - [B2055_PRG_GCHP29] = { .ghz5 = 0x0079, .ghz2 = 0x0079, NOUPLOAD, }, - [B2055_PRG_GCHP30] = { .ghz5 = 0x007A, .ghz2 = 0x007A, NOUPLOAD, }, - [0xC7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xC8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xC9] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCE] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xCF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD1] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C1_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [0xD3] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD4] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD5] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C1_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD7] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xD8] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_LNA_GAINBST] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDA] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDB] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDC] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xDD] = { .ghz5 = 0x0018, .ghz2 = 0x0018, NOUPLOAD, }, - [B2055_C2_B0NB_RSSIVCM] = { .ghz5 = 0x0088, .ghz2 = 0x0088, NOUPLOAD, }, - [0xDF] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xE0] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [0xE1] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, - [B2055_C2_GENSPARE2] = { .ghz5 = 0x0000, .ghz2 = 0x0000, NOUPLOAD, }, -}; - - -void b2055_upload_inittab(struct b43_wldev *dev, - bool ghz5, bool ignore_uploadflag) -{ - const struct b2055_inittab_entry *e; - unsigned int i; - u16 value; - - for (i = 0; i < ARRAY_SIZE(b2055_inittab); i++) { - e = &(b2055_inittab[i]); - if (!(e->flags & B2055_INITTAB_ENTRY_OK)) - continue; - if ((e->flags & B2055_INITTAB_UPLOAD) || ignore_uploadflag) { - if (ghz5) - value = e->ghz5; - else - value = e->ghz2; - b43_radio_write16(dev, i, value); - } - } -} - - -#define RADIOREGS(r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, \ - r12, r13, r14, r15, r16, r17, r18, r19, r20, r21) \ - .radio_pll_ref = r0, \ - .radio_rf_pllmod0 = r1, \ - .radio_rf_pllmod1 = r2, \ - .radio_vco_captail = r3, \ - .radio_vco_cal1 = r4, \ - .radio_vco_cal2 = r5, \ - .radio_pll_lfc1 = r6, \ - .radio_pll_lfr1 = r7, \ - .radio_pll_lfc2 = r8, \ - .radio_lgbuf_cenbuf = r9, \ - .radio_lgen_tune1 = r10, \ - .radio_lgen_tune2 = r11, \ - .radio_c1_lgbuf_atune = r12, \ - .radio_c1_lgbuf_gtune = r13, \ - .radio_c1_rx_rfr1 = r14, \ - .radio_c1_tx_pgapadtn = r15, \ - .radio_c1_tx_mxbgtrim = r16, \ - .radio_c2_lgbuf_atune = r17, \ - .radio_c2_lgbuf_gtune = r18, \ - .radio_c2_rx_rfr1 = r19, \ - .radio_c2_tx_pgapadtn = r20, \ - .radio_c2_tx_mxbgtrim = r21 - -#define PHYREGS(r0, r1, r2, r3, r4, r5) \ - .phy_regs.phy_bw1a = r0, \ - .phy_regs.phy_bw2 = r1, \ - .phy_regs.phy_bw3 = r2, \ - .phy_regs.phy_bw4 = r3, \ - .phy_regs.phy_bw5 = r4, \ - .phy_regs.phy_bw6 = r5 - -static const struct b43_nphy_channeltab_entry_rev2 b43_nphy_channeltab[] = { - { .channel = 184, - .freq = 4920, /* MHz */ - .unk2 = 3280, - RADIOREGS(0x71, 0x01, 0xEC, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xB407, 0xB007, 0xAC07, 0x1402, 0x1502, 0x1602), - }, - { .channel = 186, - .freq = 4930, /* MHz */ - .unk2 = 3287, - RADIOREGS(0x71, 0x01, 0xED, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xFF, 0xFF, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xB807, 0xB407, 0xB007, 0x1302, 0x1402, 0x1502), - }, - { .channel = 188, - .freq = 4940, /* MHz */ - .unk2 = 3293, - RADIOREGS(0x71, 0x01, 0xEE, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xBC07, 0xB807, 0xB407, 0x1202, 0x1302, 0x1402), - }, - { .channel = 190, - .freq = 4950, /* MHz */ - .unk2 = 3300, - RADIOREGS(0x71, 0x01, 0xEF, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC007, 0xBC07, 0xB807, 0x1102, 0x1202, 0x1302), - }, - { .channel = 192, - .freq = 4960, /* MHz */ - .unk2 = 3307, - RADIOREGS(0x71, 0x01, 0xF0, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC407, 0xC007, 0xBC07, 0x0F02, 0x1102, 0x1202), - }, - { .channel = 194, - .freq = 4970, /* MHz */ - .unk2 = 3313, - RADIOREGS(0x71, 0x01, 0xF1, 0x0F, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xEE, 0xEE, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xC807, 0xC407, 0xC007, 0x0E02, 0x0F02, 0x1102), - }, - { .channel = 196, - .freq = 4980, /* MHz */ - .unk2 = 3320, - RADIOREGS(0x71, 0x01, 0xF2, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xCC07, 0xC807, 0xC407, 0x0D02, 0x0E02, 0x0F02), - }, - { .channel = 198, - .freq = 4990, /* MHz */ - .unk2 = 3327, - RADIOREGS(0x71, 0x01, 0xF3, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD007, 0xCC07, 0xC807, 0x0C02, 0x0D02, 0x0E02), - }, - { .channel = 200, - .freq = 5000, /* MHz */ - .unk2 = 3333, - RADIOREGS(0x71, 0x01, 0xF4, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD407, 0xD007, 0xCC07, 0x0B02, 0x0C02, 0x0D02), - }, - { .channel = 202, - .freq = 5010, /* MHz */ - .unk2 = 3340, - RADIOREGS(0x71, 0x01, 0xF5, 0x0E, 0xFF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xDD, 0xDD, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xD807, 0xD407, 0xD007, 0x0A02, 0x0B02, 0x0C02), - }, - { .channel = 204, - .freq = 5020, /* MHz */ - .unk2 = 3347, - RADIOREGS(0x71, 0x01, 0xF6, 0x0E, 0xF7, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xDC07, 0xD807, 0xD407, 0x0902, 0x0A02, 0x0B02), - }, - { .channel = 206, - .freq = 5030, /* MHz */ - .unk2 = 3353, - RADIOREGS(0x71, 0x01, 0xF7, 0x0E, 0xF7, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE007, 0xDC07, 0xD807, 0x0802, 0x0902, 0x0A02), - }, - { .channel = 208, - .freq = 5040, /* MHz */ - .unk2 = 3360, - RADIOREGS(0x71, 0x01, 0xF8, 0x0D, 0xEF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE407, 0xE007, 0xDC07, 0x0702, 0x0802, 0x0902), - }, - { .channel = 210, - .freq = 5050, /* MHz */ - .unk2 = 3367, - RADIOREGS(0x71, 0x01, 0xF9, 0x0D, 0xEF, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xCC, 0xCC, 0xFF, 0x00, 0x0F, 0x0F, - 0x8F, 0xFF, 0x00, 0x0F, 0x0F, 0x8F), - PHYREGS(0xE807, 0xE407, 0xE007, 0x0602, 0x0702, 0x0802), - }, - { .channel = 212, - .freq = 5060, /* MHz */ - .unk2 = 3373, - RADIOREGS(0x71, 0x01, 0xFA, 0x0D, 0xE6, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, - 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), - PHYREGS(0xEC07, 0xE807, 0xE407, 0x0502, 0x0602, 0x0702), - }, - { .channel = 214, - .freq = 5070, /* MHz */ - .unk2 = 3380, - RADIOREGS(0x71, 0x01, 0xFB, 0x0D, 0xE6, 0x01, 0x04, 0x0A, - 0x00, 0x8F, 0xBB, 0xBB, 0xFF, 0x00, 0x0E, 0x0F, - 0x8E, 0xFF, 0x00, 0x0E, 0x0F, 0x8E), - PHYREGS(0xF007, 0xEC07, 0xE807, 0x0402, 0x0502, 0x0602), - }, - { .channel = 216, - .freq = 5080, /* MHz */ - .unk2 = 3387, - RADIOREGS(0x71, 0x01, 0xFC, 0x0D, 0xDE, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, - 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), - PHYREGS(0xF407, 0xF007, 0xEC07, 0x0302, 0x0402, 0x0502), - }, - { .channel = 218, - .freq = 5090, /* MHz */ - .unk2 = 3393, - RADIOREGS(0x71, 0x01, 0xFD, 0x0D, 0xDE, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xBB, 0xBB, 0xEE, 0x00, 0x0E, 0x0F, - 0x8D, 0xEE, 0x00, 0x0E, 0x0F, 0x8D), - PHYREGS(0xF807, 0xF407, 0xF007, 0x0202, 0x0302, 0x0402), - }, - { .channel = 220, - .freq = 5100, /* MHz */ - .unk2 = 3400, - RADIOREGS(0x71, 0x01, 0xFE, 0x0C, 0xD6, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, - 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), - PHYREGS(0xFC07, 0xF807, 0xF407, 0x0102, 0x0202, 0x0302), - }, - { .channel = 222, - .freq = 5110, /* MHz */ - .unk2 = 3407, - RADIOREGS(0x71, 0x01, 0xFF, 0x0C, 0xD6, 0x01, 0x04, 0x0A, - 0x00, 0x8E, 0xAA, 0xAA, 0xEE, 0x00, 0x0D, 0x0F, - 0x8D, 0xEE, 0x00, 0x0D, 0x0F, 0x8D), - PHYREGS(0x0008, 0xFC07, 0xF807, 0x0002, 0x0102, 0x0202), - }, - { .channel = 224, - .freq = 5120, /* MHz */ - .unk2 = 3413, - RADIOREGS(0x71, 0x02, 0x00, 0x0C, 0xCE, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, - 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), - PHYREGS(0x0408, 0x0008, 0xFC07, 0xFF01, 0x0002, 0x0102), - }, - { .channel = 226, - .freq = 5130, /* MHz */ - .unk2 = 3420, - RADIOREGS(0x71, 0x02, 0x01, 0x0C, 0xCE, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0xAA, 0xAA, 0xDD, 0x00, 0x0D, 0x0F, - 0x8C, 0xDD, 0x00, 0x0D, 0x0F, 0x8C), - PHYREGS(0x0808, 0x0408, 0x0008, 0xFE01, 0xFF01, 0x0002), - }, - { .channel = 228, - .freq = 5140, /* MHz */ - .unk2 = 3427, - RADIOREGS(0x71, 0x02, 0x02, 0x0C, 0xC6, 0x01, 0x04, 0x0A, - 0x00, 0x8D, 0x99, 0x99, 0xDD, 0x00, 0x0C, 0x0E, - 0x8B, 0xDD, 0x00, 0x0C, 0x0E, 0x8B), - PHYREGS(0x0C08, 0x0808, 0x0408, 0xFD01, 0xFE01, 0xFF01), - }, - { .channel = 32, - .freq = 5160, /* MHz */ - .unk2 = 3440, - RADIOREGS(0x71, 0x02, 0x04, 0x0B, 0xBE, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, - 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), - PHYREGS(0x1408, 0x1008, 0x0C08, 0xFB01, 0xFC01, 0xFD01), - }, - { .channel = 34, - .freq = 5170, /* MHz */ - .unk2 = 3447, - RADIOREGS(0x71, 0x02, 0x05, 0x0B, 0xBE, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x99, 0x99, 0xCC, 0x00, 0x0B, 0x0D, - 0x8A, 0xCC, 0x00, 0x0B, 0x0D, 0x8A), - PHYREGS(0x1808, 0x1408, 0x1008, 0xFA01, 0xFB01, 0xFC01), - }, - { .channel = 36, - .freq = 5180, /* MHz */ - .unk2 = 3453, - RADIOREGS(0x71, 0x02, 0x06, 0x0B, 0xB6, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, - 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), - PHYREGS(0x1C08, 0x1808, 0x1408, 0xF901, 0xFA01, 0xFB01), - }, - { .channel = 38, - .freq = 5190, /* MHz */ - .unk2 = 3460, - RADIOREGS(0x71, 0x02, 0x07, 0x0B, 0xB6, 0x01, 0x04, 0x0A, - 0x00, 0x8C, 0x88, 0x88, 0xCC, 0x00, 0x0B, 0x0C, - 0x89, 0xCC, 0x00, 0x0B, 0x0C, 0x89), - PHYREGS(0x2008, 0x1C08, 0x1808, 0xF801, 0xF901, 0xFA01), - }, - { .channel = 40, - .freq = 5200, /* MHz */ - .unk2 = 3467, - RADIOREGS(0x71, 0x02, 0x08, 0x0B, 0xAF, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, - 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), - PHYREGS(0x2408, 0x2008, 0x1C08, 0xF701, 0xF801, 0xF901), - }, - { .channel = 42, - .freq = 5210, /* MHz */ - .unk2 = 3473, - RADIOREGS(0x71, 0x02, 0x09, 0x0B, 0xAF, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x88, 0x88, 0xBB, 0x00, 0x0A, 0x0B, - 0x89, 0xBB, 0x00, 0x0A, 0x0B, 0x89), - PHYREGS(0x2808, 0x2408, 0x2008, 0xF601, 0xF701, 0xF801), - }, - { .channel = 44, - .freq = 5220, /* MHz */ - .unk2 = 3480, - RADIOREGS(0x71, 0x02, 0x0A, 0x0A, 0xA7, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, - 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), - PHYREGS(0x2C08, 0x2808, 0x2408, 0xF501, 0xF601, 0xF701), - }, - { .channel = 46, - .freq = 5230, /* MHz */ - .unk2 = 3487, - RADIOREGS(0x71, 0x02, 0x0B, 0x0A, 0xA7, 0x01, 0x04, 0x0A, - 0x00, 0x8B, 0x77, 0x77, 0xBB, 0x00, 0x09, 0x0A, - 0x88, 0xBB, 0x00, 0x09, 0x0A, 0x88), - PHYREGS(0x3008, 0x2C08, 0x2808, 0xF401, 0xF501, 0xF601), - }, - { .channel = 48, - .freq = 5240, /* MHz */ - .unk2 = 3493, - RADIOREGS(0x71, 0x02, 0x0C, 0x0A, 0xA0, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, - 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), - PHYREGS(0x3408, 0x3008, 0x2C08, 0xF301, 0xF401, 0xF501), - }, - { .channel = 50, - .freq = 5250, /* MHz */ - .unk2 = 3500, - RADIOREGS(0x71, 0x02, 0x0D, 0x0A, 0xA0, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x77, 0x77, 0xAA, 0x00, 0x09, 0x0A, - 0x87, 0xAA, 0x00, 0x09, 0x0A, 0x87), - PHYREGS(0x3808, 0x3408, 0x3008, 0xF201, 0xF301, 0xF401), - }, - { .channel = 52, - .freq = 5260, /* MHz */ - .unk2 = 3507, - RADIOREGS(0x71, 0x02, 0x0E, 0x0A, 0x98, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, - 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), - PHYREGS(0x3C08, 0x3808, 0x3408, 0xF101, 0xF201, 0xF301), - }, - { .channel = 54, - .freq = 5270, /* MHz */ - .unk2 = 3513, - RADIOREGS(0x71, 0x02, 0x0F, 0x0A, 0x98, 0x01, 0x04, 0x0A, - 0x00, 0x8A, 0x66, 0x66, 0xAA, 0x00, 0x08, 0x09, - 0x87, 0xAA, 0x00, 0x08, 0x09, 0x87), - PHYREGS(0x4008, 0x3C08, 0x3808, 0xF001, 0xF101, 0xF201), - }, - { .channel = 56, - .freq = 5280, /* MHz */ - .unk2 = 3520, - RADIOREGS(0x71, 0x02, 0x10, 0x09, 0x91, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, - 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), - PHYREGS(0x4408, 0x4008, 0x3C08, 0xF001, 0xF001, 0xF101), - }, - { .channel = 58, - .freq = 5290, /* MHz */ - .unk2 = 3527, - RADIOREGS(0x71, 0x02, 0x11, 0x09, 0x91, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x66, 0x66, 0x99, 0x00, 0x08, 0x08, - 0x86, 0x99, 0x00, 0x08, 0x08, 0x86), - PHYREGS(0x4808, 0x4408, 0x4008, 0xEF01, 0xF001, 0xF001), - }, - { .channel = 60, - .freq = 5300, /* MHz */ - .unk2 = 3533, - RADIOREGS(0x71, 0x02, 0x12, 0x09, 0x8A, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, - 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), - PHYREGS(0x4C08, 0x4808, 0x4408, 0xEE01, 0xEF01, 0xF001), - }, - { .channel = 62, - .freq = 5310, /* MHz */ - .unk2 = 3540, - RADIOREGS(0x71, 0x02, 0x13, 0x09, 0x8A, 0x01, 0x04, 0x0A, - 0x00, 0x89, 0x55, 0x55, 0x99, 0x00, 0x08, 0x07, - 0x85, 0x99, 0x00, 0x08, 0x07, 0x85), - PHYREGS(0x5008, 0x4C08, 0x4808, 0xED01, 0xEE01, 0xEF01), - }, - { .channel = 64, - .freq = 5320, /* MHz */ - .unk2 = 3547, - RADIOREGS(0x71, 0x02, 0x14, 0x09, 0x83, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, - 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), - PHYREGS(0x5408, 0x5008, 0x4C08, 0xEC01, 0xED01, 0xEE01), - }, - { .channel = 66, - .freq = 5330, /* MHz */ - .unk2 = 3553, - RADIOREGS(0x71, 0x02, 0x15, 0x09, 0x83, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x55, 0x55, 0x88, 0x00, 0x07, 0x07, - 0x84, 0x88, 0x00, 0x07, 0x07, 0x84), - PHYREGS(0x5808, 0x5408, 0x5008, 0xEB01, 0xEC01, 0xED01), - }, - { .channel = 68, - .freq = 5340, /* MHz */ - .unk2 = 3560, - RADIOREGS(0x71, 0x02, 0x16, 0x08, 0x7C, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, - 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), - PHYREGS(0x5C08, 0x5808, 0x5408, 0xEA01, 0xEB01, 0xEC01), - }, - { .channel = 70, - .freq = 5350, /* MHz */ - .unk2 = 3567, - RADIOREGS(0x71, 0x02, 0x17, 0x08, 0x7C, 0x01, 0x04, 0x0A, - 0x00, 0x88, 0x44, 0x44, 0x88, 0x00, 0x07, 0x06, - 0x84, 0x88, 0x00, 0x07, 0x06, 0x84), - PHYREGS(0x6008, 0x5C08, 0x5808, 0xE901, 0xEA01, 0xEB01), - }, - { .channel = 72, - .freq = 5360, /* MHz */ - .unk2 = 3573, - RADIOREGS(0x71, 0x02, 0x18, 0x08, 0x75, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, - 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), - PHYREGS(0x6408, 0x6008, 0x5C08, 0xE801, 0xE901, 0xEA01), - }, - { .channel = 74, - .freq = 5370, /* MHz */ - .unk2 = 3580, - RADIOREGS(0x71, 0x02, 0x19, 0x08, 0x75, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x44, 0x44, 0x77, 0x00, 0x06, 0x05, - 0x83, 0x77, 0x00, 0x06, 0x05, 0x83), - PHYREGS(0x6808, 0x6408, 0x6008, 0xE701, 0xE801, 0xE901), - }, - { .channel = 76, - .freq = 5380, /* MHz */ - .unk2 = 3587, - RADIOREGS(0x71, 0x02, 0x1A, 0x08, 0x6E, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, - 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), - PHYREGS(0x6C08, 0x6808, 0x6408, 0xE601, 0xE701, 0xE801), - }, - { .channel = 78, - .freq = 5390, /* MHz */ - .unk2 = 3593, - RADIOREGS(0x71, 0x02, 0x1B, 0x08, 0x6E, 0x01, 0x04, 0x0A, - 0x00, 0x87, 0x33, 0x33, 0x77, 0x00, 0x06, 0x04, - 0x82, 0x77, 0x00, 0x06, 0x04, 0x82), - PHYREGS(0x7008, 0x6C08, 0x6808, 0xE501, 0xE601, 0xE701), - }, - { .channel = 80, - .freq = 5400, /* MHz */ - .unk2 = 3600, - RADIOREGS(0x71, 0x02, 0x1C, 0x07, 0x67, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, - 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), - PHYREGS(0x7408, 0x7008, 0x6C08, 0xE501, 0xE501, 0xE601), - }, - { .channel = 82, - .freq = 5410, /* MHz */ - .unk2 = 3607, - RADIOREGS(0x71, 0x02, 0x1D, 0x07, 0x67, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x33, 0x33, 0x66, 0x00, 0x05, 0x04, - 0x81, 0x66, 0x00, 0x05, 0x04, 0x81), - PHYREGS(0x7808, 0x7408, 0x7008, 0xE401, 0xE501, 0xE501), - }, - { .channel = 84, - .freq = 5420, /* MHz */ - .unk2 = 3613, - RADIOREGS(0x71, 0x02, 0x1E, 0x07, 0x61, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, - 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), - PHYREGS(0x7C08, 0x7808, 0x7408, 0xE301, 0xE401, 0xE501), - }, - { .channel = 86, - .freq = 5430, /* MHz */ - .unk2 = 3620, - RADIOREGS(0x71, 0x02, 0x1F, 0x07, 0x61, 0x01, 0x04, 0x0A, - 0x00, 0x86, 0x22, 0x22, 0x66, 0x00, 0x05, 0x03, - 0x80, 0x66, 0x00, 0x05, 0x03, 0x80), - PHYREGS(0x8008, 0x7C08, 0x7808, 0xE201, 0xE301, 0xE401), - }, - { .channel = 88, - .freq = 5440, /* MHz */ - .unk2 = 3627, - RADIOREGS(0x71, 0x02, 0x20, 0x07, 0x5A, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, - 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), - PHYREGS(0x8408, 0x8008, 0x7C08, 0xE101, 0xE201, 0xE301), - }, - { .channel = 90, - .freq = 5450, /* MHz */ - .unk2 = 3633, - RADIOREGS(0x71, 0x02, 0x21, 0x07, 0x5A, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x22, 0x22, 0x55, 0x00, 0x04, 0x02, - 0x80, 0x55, 0x00, 0x04, 0x02, 0x80), - PHYREGS(0x8808, 0x8408, 0x8008, 0xE001, 0xE101, 0xE201), - }, - { .channel = 92, - .freq = 5460, /* MHz */ - .unk2 = 3640, - RADIOREGS(0x71, 0x02, 0x22, 0x06, 0x53, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, - 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), - PHYREGS(0x8C08, 0x8808, 0x8408, 0xDF01, 0xE001, 0xE101), - }, - { .channel = 94, - .freq = 5470, /* MHz */ - .unk2 = 3647, - RADIOREGS(0x71, 0x02, 0x23, 0x06, 0x53, 0x01, 0x04, 0x0A, - 0x00, 0x85, 0x11, 0x11, 0x55, 0x00, 0x04, 0x01, - 0x80, 0x55, 0x00, 0x04, 0x01, 0x80), - PHYREGS(0x9008, 0x8C08, 0x8808, 0xDE01, 0xDF01, 0xE001), - }, - { .channel = 96, - .freq = 5480, /* MHz */ - .unk2 = 3653, - RADIOREGS(0x71, 0x02, 0x24, 0x06, 0x4D, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, - 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9408, 0x9008, 0x8C08, 0xDD01, 0xDE01, 0xDF01), - }, - { .channel = 98, - .freq = 5490, /* MHz */ - .unk2 = 3660, - RADIOREGS(0x71, 0x02, 0x25, 0x06, 0x4D, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x11, 0x11, 0x44, 0x00, 0x03, 0x00, - 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9808, 0x9408, 0x9008, 0xDD01, 0xDD01, 0xDE01), - }, - { .channel = 100, - .freq = 5500, /* MHz */ - .unk2 = 3667, - RADIOREGS(0x71, 0x02, 0x26, 0x06, 0x47, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, - 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0x9C08, 0x9808, 0x9408, 0xDC01, 0xDD01, 0xDD01), - }, - { .channel = 102, - .freq = 5510, /* MHz */ - .unk2 = 3673, - RADIOREGS(0x71, 0x02, 0x27, 0x06, 0x47, 0x01, 0x04, 0x0A, - 0x00, 0x84, 0x00, 0x00, 0x44, 0x00, 0x03, 0x00, - 0x80, 0x44, 0x00, 0x03, 0x00, 0x80), - PHYREGS(0xA008, 0x9C08, 0x9808, 0xDB01, 0xDC01, 0xDD01), - }, - { .channel = 104, - .freq = 5520, /* MHz */ - .unk2 = 3680, - RADIOREGS(0x71, 0x02, 0x28, 0x05, 0x40, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xA408, 0xA008, 0x9C08, 0xDA01, 0xDB01, 0xDC01), - }, - { .channel = 106, - .freq = 5530, /* MHz */ - .unk2 = 3687, - RADIOREGS(0x71, 0x02, 0x29, 0x05, 0x40, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xA808, 0xA408, 0xA008, 0xD901, 0xDA01, 0xDB01), - }, - { .channel = 108, - .freq = 5540, /* MHz */ - .unk2 = 3693, - RADIOREGS(0x71, 0x02, 0x2A, 0x05, 0x3A, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xAC08, 0xA808, 0xA408, 0xD801, 0xD901, 0xDA01), - }, - { .channel = 110, - .freq = 5550, /* MHz */ - .unk2 = 3700, - RADIOREGS(0x71, 0x02, 0x2B, 0x05, 0x3A, 0x01, 0x04, 0x0A, - 0x00, 0x83, 0x00, 0x00, 0x33, 0x00, 0x02, 0x00, - 0x80, 0x33, 0x00, 0x02, 0x00, 0x80), - PHYREGS(0xB008, 0xAC08, 0xA808, 0xD701, 0xD801, 0xD901), - }, - { .channel = 112, - .freq = 5560, /* MHz */ - .unk2 = 3707, - RADIOREGS(0x71, 0x02, 0x2C, 0x05, 0x34, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xB408, 0xB008, 0xAC08, 0xD701, 0xD701, 0xD801), - }, - { .channel = 114, - .freq = 5570, /* MHz */ - .unk2 = 3713, - RADIOREGS(0x71, 0x02, 0x2D, 0x05, 0x34, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xB808, 0xB408, 0xB008, 0xD601, 0xD701, 0xD701), - }, - { .channel = 116, - .freq = 5580, /* MHz */ - .unk2 = 3720, - RADIOREGS(0x71, 0x02, 0x2E, 0x04, 0x2E, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xBC08, 0xB808, 0xB408, 0xD501, 0xD601, 0xD701), - }, - { .channel = 118, - .freq = 5590, /* MHz */ - .unk2 = 3727, - RADIOREGS(0x71, 0x02, 0x2F, 0x04, 0x2E, 0x01, 0x04, 0x0A, - 0x00, 0x82, 0x00, 0x00, 0x22, 0x00, 0x01, 0x00, - 0x80, 0x22, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC008, 0xBC08, 0xB808, 0xD401, 0xD501, 0xD601), - }, - { .channel = 120, - .freq = 5600, /* MHz */ - .unk2 = 3733, - RADIOREGS(0x71, 0x02, 0x30, 0x04, 0x28, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, - 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC408, 0xC008, 0xBC08, 0xD301, 0xD401, 0xD501), - }, - { .channel = 122, - .freq = 5610, /* MHz */ - .unk2 = 3740, - RADIOREGS(0x71, 0x02, 0x31, 0x04, 0x28, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, - 0x80, 0x11, 0x00, 0x01, 0x00, 0x80), - PHYREGS(0xC808, 0xC408, 0xC008, 0xD201, 0xD301, 0xD401), - }, - { .channel = 124, - .freq = 5620, /* MHz */ - .unk2 = 3747, - RADIOREGS(0x71, 0x02, 0x32, 0x04, 0x21, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xCC08, 0xC808, 0xC408, 0xD201, 0xD201, 0xD301), - }, - { .channel = 126, - .freq = 5630, /* MHz */ - .unk2 = 3753, - RADIOREGS(0x71, 0x02, 0x33, 0x04, 0x21, 0x01, 0x04, 0x0A, - 0x00, 0x81, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x80, 0x11, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD008, 0xCC08, 0xC808, 0xD101, 0xD201, 0xD201), - }, - { .channel = 128, - .freq = 5640, /* MHz */ - .unk2 = 3760, - RADIOREGS(0x71, 0x02, 0x34, 0x03, 0x1C, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD408, 0xD008, 0xCC08, 0xD001, 0xD101, 0xD201), - }, - { .channel = 130, - .freq = 5650, /* MHz */ - .unk2 = 3767, - RADIOREGS(0x71, 0x02, 0x35, 0x03, 0x1C, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xD808, 0xD408, 0xD008, 0xCF01, 0xD001, 0xD101), - }, - { .channel = 132, - .freq = 5660, /* MHz */ - .unk2 = 3773, - RADIOREGS(0x71, 0x02, 0x36, 0x03, 0x16, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xDC08, 0xD808, 0xD408, 0xCE01, 0xCF01, 0xD001), - }, - { .channel = 134, - .freq = 5670, /* MHz */ - .unk2 = 3780, - RADIOREGS(0x71, 0x02, 0x37, 0x03, 0x16, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE008, 0xDC08, 0xD808, 0xCE01, 0xCE01, 0xCF01), - }, - { .channel = 136, - .freq = 5680, /* MHz */ - .unk2 = 3787, - RADIOREGS(0x71, 0x02, 0x38, 0x03, 0x10, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE408, 0xE008, 0xDC08, 0xCD01, 0xCE01, 0xCE01), - }, - { .channel = 138, - .freq = 5690, /* MHz */ - .unk2 = 3793, - RADIOREGS(0x71, 0x02, 0x39, 0x03, 0x10, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xE808, 0xE408, 0xE008, 0xCC01, 0xCD01, 0xCE01), - }, - { .channel = 140, - .freq = 5700, /* MHz */ - .unk2 = 3800, - RADIOREGS(0x71, 0x02, 0x3A, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xEC08, 0xE808, 0xE408, 0xCB01, 0xCC01, 0xCD01), - }, - { .channel = 142, - .freq = 5710, /* MHz */ - .unk2 = 3807, - RADIOREGS(0x71, 0x02, 0x3B, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF008, 0xEC08, 0xE808, 0xCA01, 0xCB01, 0xCC01), - }, - { .channel = 144, - .freq = 5720, /* MHz */ - .unk2 = 3813, - RADIOREGS(0x71, 0x02, 0x3C, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF408, 0xF008, 0xEC08, 0xC901, 0xCA01, 0xCB01), - }, - { .channel = 145, - .freq = 5725, /* MHz */ - .unk2 = 3817, - RADIOREGS(0x72, 0x04, 0x79, 0x02, 0x03, 0x01, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF608, 0xF208, 0xEE08, 0xC901, 0xCA01, 0xCB01), - }, - { .channel = 146, - .freq = 5730, /* MHz */ - .unk2 = 3820, - RADIOREGS(0x71, 0x02, 0x3D, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xF808, 0xF408, 0xF008, 0xC901, 0xC901, 0xCA01), - }, - { .channel = 147, - .freq = 5735, /* MHz */ - .unk2 = 3823, - RADIOREGS(0x72, 0x04, 0x7B, 0x02, 0x03, 0x01, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFA08, 0xF608, 0xF208, 0xC801, 0xC901, 0xCA01), - }, - { .channel = 148, - .freq = 5740, /* MHz */ - .unk2 = 3827, - RADIOREGS(0x71, 0x02, 0x3E, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFC08, 0xF808, 0xF408, 0xC801, 0xC901, 0xC901), - }, - { .channel = 149, - .freq = 5745, /* MHz */ - .unk2 = 3830, - RADIOREGS(0x72, 0x04, 0x7D, 0x02, 0xFE, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0xFE08, 0xFA08, 0xF608, 0xC801, 0xC801, 0xC901), - }, - { .channel = 150, - .freq = 5750, /* MHz */ - .unk2 = 3833, - RADIOREGS(0x71, 0x02, 0x3F, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0009, 0xFC08, 0xF808, 0xC701, 0xC801, 0xC901), - }, - { .channel = 151, - .freq = 5755, /* MHz */ - .unk2 = 3837, - RADIOREGS(0x72, 0x04, 0x7F, 0x02, 0xFE, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0209, 0xFE08, 0xFA08, 0xC701, 0xC801, 0xC801), - }, - { .channel = 152, - .freq = 5760, /* MHz */ - .unk2 = 3840, - RADIOREGS(0x71, 0x02, 0x40, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0409, 0x0009, 0xFC08, 0xC601, 0xC701, 0xC801), - }, - { .channel = 153, - .freq = 5765, /* MHz */ - .unk2 = 3843, - RADIOREGS(0x72, 0x04, 0x81, 0x02, 0xF8, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0609, 0x0209, 0xFE08, 0xC601, 0xC701, 0xC801), - }, - { .channel = 154, - .freq = 5770, /* MHz */ - .unk2 = 3847, - RADIOREGS(0x71, 0x02, 0x41, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0809, 0x0409, 0x0009, 0xC601, 0xC601, 0xC701), - }, - { .channel = 155, - .freq = 5775, /* MHz */ - .unk2 = 3850, - RADIOREGS(0x72, 0x04, 0x83, 0x02, 0xF8, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0A09, 0x0609, 0x0209, 0xC501, 0xC601, 0xC701), - }, - { .channel = 156, - .freq = 5780, /* MHz */ - .unk2 = 3853, - RADIOREGS(0x71, 0x02, 0x42, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0C09, 0x0809, 0x0409, 0xC501, 0xC601, 0xC601), - }, - { .channel = 157, - .freq = 5785, /* MHz */ - .unk2 = 3857, - RADIOREGS(0x72, 0x04, 0x85, 0x02, 0xF2, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x0E09, 0x0A09, 0x0609, 0xC401, 0xC501, 0xC601), - }, - { .channel = 158, - .freq = 5790, /* MHz */ - .unk2 = 3860, - RADIOREGS(0x71, 0x02, 0x43, 0x02, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1009, 0x0C09, 0x0809, 0xC401, 0xC501, 0xC601), - }, - { .channel = 159, - .freq = 5795, /* MHz */ - .unk2 = 3863, - RADIOREGS(0x72, 0x04, 0x87, 0x02, 0xF2, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1209, 0x0E09, 0x0A09, 0xC401, 0xC401, 0xC501), - }, - { .channel = 160, - .freq = 5800, /* MHz */ - .unk2 = 3867, - RADIOREGS(0x71, 0x02, 0x44, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1409, 0x1009, 0x0C09, 0xC301, 0xC401, 0xC501), - }, - { .channel = 161, - .freq = 5805, /* MHz */ - .unk2 = 3870, - RADIOREGS(0x72, 0x04, 0x89, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1609, 0x1209, 0x0E09, 0xC301, 0xC401, 0xC401), - }, - { .channel = 162, - .freq = 5810, /* MHz */ - .unk2 = 3873, - RADIOREGS(0x71, 0x02, 0x45, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1809, 0x1409, 0x1009, 0xC201, 0xC301, 0xC401), - }, - { .channel = 163, - .freq = 5815, /* MHz */ - .unk2 = 3877, - RADIOREGS(0x72, 0x04, 0x8B, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1A09, 0x1609, 0x1209, 0xC201, 0xC301, 0xC401), - }, - { .channel = 164, - .freq = 5820, /* MHz */ - .unk2 = 3880, - RADIOREGS(0x71, 0x02, 0x46, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1C09, 0x1809, 0x1409, 0xC201, 0xC201, 0xC301), - }, - { .channel = 165, - .freq = 5825, /* MHz */ - .unk2 = 3883, - RADIOREGS(0x72, 0x04, 0x8D, 0x01, 0xED, 0x00, 0x03, 0x14, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x1E09, 0x1A09, 0x1609, 0xC101, 0xC201, 0xC301), - }, - { .channel = 166, - .freq = 5830, /* MHz */ - .unk2 = 3887, - RADIOREGS(0x71, 0x02, 0x47, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2009, 0x1C09, 0x1809, 0xC101, 0xC201, 0xC201), - }, - { .channel = 168, - .freq = 5840, /* MHz */ - .unk2 = 3893, - RADIOREGS(0x71, 0x02, 0x48, 0x01, 0x0A, 0x01, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2409, 0x2009, 0x1C09, 0xC001, 0xC101, 0xC201), - }, - { .channel = 170, - .freq = 5850, /* MHz */ - .unk2 = 3900, - RADIOREGS(0x71, 0x02, 0x49, 0x01, 0xE0, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2809, 0x2409, 0x2009, 0xBF01, 0xC001, 0xC101), - }, - { .channel = 172, - .freq = 5860, /* MHz */ - .unk2 = 3907, - RADIOREGS(0x71, 0x02, 0x4A, 0x01, 0xDE, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x2C09, 0x2809, 0x2409, 0xBF01, 0xBF01, 0xC001), - }, - { .channel = 174, - .freq = 5870, /* MHz */ - .unk2 = 3913, - RADIOREGS(0x71, 0x02, 0x4B, 0x00, 0xDB, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3009, 0x2C09, 0x2809, 0xBE01, 0xBF01, 0xBF01), - }, - { .channel = 176, - .freq = 5880, /* MHz */ - .unk2 = 3920, - RADIOREGS(0x71, 0x02, 0x4C, 0x00, 0xD8, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3409, 0x3009, 0x2C09, 0xBD01, 0xBE01, 0xBF01), - }, - { .channel = 178, - .freq = 5890, /* MHz */ - .unk2 = 3927, - RADIOREGS(0x71, 0x02, 0x4D, 0x00, 0xD6, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3809, 0x3409, 0x3009, 0xBC01, 0xBD01, 0xBE01), - }, - { .channel = 180, - .freq = 5900, /* MHz */ - .unk2 = 3933, - RADIOREGS(0x71, 0x02, 0x4E, 0x00, 0xD3, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x3C09, 0x3809, 0x3409, 0xBC01, 0xBC01, 0xBD01), - }, - { .channel = 182, - .freq = 5910, /* MHz */ - .unk2 = 3940, - RADIOREGS(0x71, 0x02, 0x4F, 0x00, 0xD6, 0x00, 0x04, 0x0A, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0x00, 0x00, 0x00, 0x00, 0x80), - PHYREGS(0x4009, 0x3C09, 0x3809, 0xBB01, 0xBC01, 0xBC01), - }, - { .channel = 1, - .freq = 2412, /* MHz */ - .unk2 = 3216, - RADIOREGS(0x73, 0x09, 0x6C, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0D, 0x0C, - 0x80, 0xFF, 0x88, 0x0D, 0x0C, 0x80), - PHYREGS(0xC903, 0xC503, 0xC103, 0x3A04, 0x3F04, 0x4304), - }, - { .channel = 2, - .freq = 2417, /* MHz */ - .unk2 = 3223, - RADIOREGS(0x73, 0x09, 0x71, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0B, - 0x80, 0xFF, 0x88, 0x0C, 0x0B, 0x80), - PHYREGS(0xCB03, 0xC703, 0xC303, 0x3804, 0x3D04, 0x4104), - }, - { .channel = 3, - .freq = 2422, /* MHz */ - .unk2 = 3229, - RADIOREGS(0x73, 0x09, 0x76, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, - 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), - PHYREGS(0xCD03, 0xC903, 0xC503, 0x3604, 0x3A04, 0x3F04), - }, - { .channel = 4, - .freq = 2427, /* MHz */ - .unk2 = 3236, - RADIOREGS(0x73, 0x09, 0x7B, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x0A, - 0x80, 0xFF, 0x88, 0x0C, 0x0A, 0x80), - PHYREGS(0xCF03, 0xCB03, 0xC703, 0x3404, 0x3804, 0x3D04), - }, - { .channel = 5, - .freq = 2432, /* MHz */ - .unk2 = 3243, - RADIOREGS(0x73, 0x09, 0x80, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0C, 0x09, - 0x80, 0xFF, 0x88, 0x0C, 0x09, 0x80), - PHYREGS(0xD103, 0xCD03, 0xC903, 0x3104, 0x3604, 0x3A04), - }, - { .channel = 6, - .freq = 2437, /* MHz */ - .unk2 = 3249, - RADIOREGS(0x73, 0x09, 0x85, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0B, 0x08, - 0x80, 0xFF, 0x88, 0x0B, 0x08, 0x80), - PHYREGS(0xD303, 0xCF03, 0xCB03, 0x2F04, 0x3404, 0x3804), - }, - { .channel = 7, - .freq = 2442, /* MHz */ - .unk2 = 3256, - RADIOREGS(0x73, 0x09, 0x8A, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x07, - 0x80, 0xFF, 0x88, 0x0A, 0x07, 0x80), - PHYREGS(0xD503, 0xD103, 0xCD03, 0x2D04, 0x3104, 0x3604), - }, - { .channel = 8, - .freq = 2447, /* MHz */ - .unk2 = 3263, - RADIOREGS(0x73, 0x09, 0x8F, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x0A, 0x06, - 0x80, 0xFF, 0x88, 0x0A, 0x06, 0x80), - PHYREGS(0xD703, 0xD303, 0xCF03, 0x2B04, 0x2F04, 0x3404), - }, - { .channel = 9, - .freq = 2452, /* MHz */ - .unk2 = 3269, - RADIOREGS(0x73, 0x09, 0x94, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x09, 0x06, - 0x80, 0xFF, 0x88, 0x09, 0x06, 0x80), - PHYREGS(0xD903, 0xD503, 0xD103, 0x2904, 0x2D04, 0x3104), - }, - { .channel = 10, - .freq = 2457, /* MHz */ - .unk2 = 3276, - RADIOREGS(0x73, 0x09, 0x99, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x05, - 0x80, 0xFF, 0x88, 0x08, 0x05, 0x80), - PHYREGS(0xDB03, 0xD703, 0xD303, 0x2704, 0x2B04, 0x2F04), - }, - { .channel = 11, - .freq = 2462, /* MHz */ - .unk2 = 3283, - RADIOREGS(0x73, 0x09, 0x9E, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x04, - 0x80, 0xFF, 0x88, 0x08, 0x04, 0x80), - PHYREGS(0xDD03, 0xD903, 0xD503, 0x2404, 0x2904, 0x2D04), - }, - { .channel = 12, - .freq = 2467, /* MHz */ - .unk2 = 3289, - RADIOREGS(0x73, 0x09, 0xA3, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x08, 0x03, - 0x80, 0xFF, 0x88, 0x08, 0x03, 0x80), - PHYREGS(0xDF03, 0xDB03, 0xD703, 0x2204, 0x2704, 0x2B04), - }, - { .channel = 13, - .freq = 2472, /* MHz */ - .unk2 = 3296, - RADIOREGS(0x73, 0x09, 0xA8, 0x0F, 0x00, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x03, - 0x80, 0xFF, 0x88, 0x07, 0x03, 0x80), - PHYREGS(0xE103, 0xDD03, 0xD903, 0x2004, 0x2404, 0x2904), - }, - { .channel = 14, - .freq = 2484, /* MHz */ - .unk2 = 3312, - RADIOREGS(0x73, 0x09, 0xB4, 0x0F, 0xFF, 0x01, 0x07, 0x15, - 0x01, 0x8F, 0xFF, 0xFF, 0xFF, 0x88, 0x07, 0x01, - 0x80, 0xFF, 0x88, 0x07, 0x01, 0x80), - PHYREGS(0xE603, 0xE203, 0xDE03, 0x1B04, 0x1F04, 0x2404), - }, -}; - -const struct b43_nphy_channeltab_entry_rev2 * -b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel) -{ - const struct b43_nphy_channeltab_entry_rev2 *e; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(b43_nphy_channeltab); i++) { - e = &(b43_nphy_channeltab[i]); - if (e->channel == channel) - return e; - } - - return NULL; -} - - static const u8 b43_ntab_adjustpower0[] = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 8fc1da9f8fe57bce8bf0a531f4ef56b2d248dac9..4ec593ba3eef16930974ee0aeaf4dea64e2eaa53 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -3,7 +3,6 @@ #include - struct b43_phy_n_sfo_cfg { u16 phy_bw1a; u16 phy_bw2; @@ -13,52 +12,6 @@ struct b43_phy_n_sfo_cfg { u16 phy_bw6; }; -struct b43_nphy_channeltab_entry_rev2 { - /* The channel number */ - u8 channel; - /* The channel frequency in MHz */ - u16 freq; - /* An unknown value */ - u16 unk2; - /* Radio register values on channelswitch */ - u8 radio_pll_ref; - u8 radio_rf_pllmod0; - u8 radio_rf_pllmod1; - u8 radio_vco_captail; - u8 radio_vco_cal1; - u8 radio_vco_cal2; - u8 radio_pll_lfc1; - u8 radio_pll_lfr1; - u8 radio_pll_lfc2; - u8 radio_lgbuf_cenbuf; - u8 radio_lgen_tune1; - u8 radio_lgen_tune2; - u8 radio_c1_lgbuf_atune; - u8 radio_c1_lgbuf_gtune; - u8 radio_c1_rx_rfr1; - u8 radio_c1_tx_pgapadtn; - u8 radio_c1_tx_mxbgtrim; - u8 radio_c2_lgbuf_atune; - u8 radio_c2_lgbuf_gtune; - u8 radio_c2_rx_rfr1; - u8 radio_c2_tx_pgapadtn; - u8 radio_c2_tx_mxbgtrim; - /* PHY register values on channelswitch */ - struct b43_phy_n_sfo_cfg phy_regs; -}; - -struct b43_nphy_channeltab_entry_rev3 { - /* The channel number */ - u8 channel; - /* The channel frequency in MHz */ - u16 freq; - /* Radio register values on channelswitch */ - /* TODO */ - /* PHY register values on channelswitch */ - struct b43_phy_n_sfo_cfg phy_regs; -}; - - struct b43_wldev; struct nphy_txiqcal_ladder { @@ -82,18 +35,12 @@ struct nphy_rf_control_override_rev3 { u8 val_addr1; }; -/* Upload the default register value table. - * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz - * table is uploaded. If "ignore_uploadflag" is true, we upload any value - * and ignore the "UPLOAD" flag. */ -void b2055_upload_inittab(struct b43_wldev *dev, - bool ghz5, bool ignore_uploadflag); - - -/* Get the NPHY Channel Switch Table entry for a channel number. +/* Get the NPHY Channel Switch Table entry for a channel. * Returns NULL on failure to find an entry. */ const struct b43_nphy_channeltab_entry_rev2 * b43_nphy_get_chantabent_rev2(struct b43_wldev *dev, u8 channel); +const struct b43_nphy_channeltab_entry_rev3 * +b43_nphy_get_chantabent_rev3(struct b43_wldev *dev, u16 freq); /* The N-PHY tables. */ diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 1713f5f7a58b0571c57876cdee4ac6b4f4b63019..67f18ecdb3bf5ae366743454484f2ed5a30b4b4b 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c @@ -1623,6 +1623,7 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) { + struct wiphy *wiphy = dev->wl->hw->wiphy; const size_t hdr_len = sizeof(struct b43legacy_fw_header); const __be32 *data; unsigned int i; @@ -1732,6 +1733,10 @@ static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) dev->fw.rev = fwrev; dev->fw.patch = fwpatch; + snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", + dev->fw.rev, dev->fw.patch); + wiphy->hw_version = dev->dev->id.coreid; + return 0; error: diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index a85e43a8d75823142bdc3b986adf7954e1e65d61..6038633ef361fa824595531c5466969303c08e62 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c @@ -1696,7 +1696,7 @@ static int prism2_request_scan(struct net_device *dev) hostap_set_word(dev, HFA384X_RID_CNFROAMINGMODE, HFA384X_ROAMING_FIRMWARE); - return 0; + return ret; } #else /* !PRISM2_NO_STATION_MODES */ diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 996e9d7d7586b240847526bec92e721ef8a20d9c..61915f371416e490cbf73d89d65595aadc1e6a98 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1921,9 +1921,9 @@ static int ipw2100_net_init(struct net_device *dev) bg_band->band = IEEE80211_BAND_2GHZ; bg_band->n_channels = geo->bg_channels; - bg_band->channels = - kzalloc(geo->bg_channels * - sizeof(struct ieee80211_channel), GFP_KERNEL); + bg_band->channels = kcalloc(geo->bg_channels, + sizeof(struct ieee80211_channel), + GFP_KERNEL); if (!bg_band->channels) { ipw2100_down(priv); return -ENOMEM; @@ -3056,9 +3056,9 @@ static void ipw2100_tx_send_commands(struct ipw2100_priv *priv) packet = list_entry(element, struct ipw2100_tx_packet, list); - IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n", + IPW_DEBUG_TX("using TBD at virt=%p, phys=%04X\n", &txq->drv[txq->next], - (void *)(txq->nic + txq->next * + (u32) (txq->nic + txq->next * sizeof(struct ipw2100_bd))); packet->index = txq->next; diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index cb2552a6777c1a26573b5684320933486747d20c..8d6ed5f6f46f4a423e31943dc70b70fd3727569f 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11467,9 +11467,13 @@ static int ipw_net_init(struct net_device *dev) bg_band->band = IEEE80211_BAND_2GHZ; bg_band->n_channels = geo->bg_channels; - bg_band->channels = - kzalloc(geo->bg_channels * - sizeof(struct ieee80211_channel), GFP_KERNEL); + bg_band->channels = kcalloc(geo->bg_channels, + sizeof(struct ieee80211_channel), + GFP_KERNEL); + if (!bg_band->channels) { + rc = -ENOMEM; + goto out; + } /* translate geo->bg to bg_band.channels */ for (i = 0; i < geo->bg_channels; i++) { bg_band->channels[i].band = IEEE80211_BAND_2GHZ; @@ -11502,9 +11506,13 @@ static int ipw_net_init(struct net_device *dev) a_band->band = IEEE80211_BAND_5GHZ; a_band->n_channels = geo->a_channels; - a_band->channels = - kzalloc(geo->a_channels * - sizeof(struct ieee80211_channel), GFP_KERNEL); + a_band->channels = kcalloc(geo->a_channels, + sizeof(struct ieee80211_channel), + GFP_KERNEL); + if (!a_band->channels) { + rc = -ENOMEM; + goto out; + } /* translate geo->bg to a_band.channels */ for (i = 0; i < geo->a_channels; i++) { a_band->channels[i].band = IEEE80211_BAND_2GHZ; diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index a51e4da1bdfc5d7149074c8adc7555d51fac0250..b82364258dc5e180133985df9a2d1a48a8a2ba95 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig @@ -3,6 +3,9 @@ config IWLWIFI depends on PCI && MAC80211 select FW_LOADER +menu "Debugging Options" + depends on IWLWIFI + config IWLWIFI_DEBUG bool "Enable full debugging output in iwlagn and iwl3945 drivers" depends on IWLWIFI @@ -36,6 +39,12 @@ config IWLWIFI_DEBUGFS is a low-impact option that allows getting insight into the driver's state at runtime. +config IWLWIFI_DEBUG_EXPERIMENTAL_UCODE + bool "Experimental uCode support" + depends on IWLWIFI && IWLWIFI_DEBUG + ---help--- + Enable use of experimental ucode for testing and debugging. + config IWLWIFI_DEVICE_TRACING bool "iwlwifi device access tracing" depends on IWLWIFI @@ -53,6 +62,7 @@ config IWLWIFI_DEVICE_TRACING If unsure, say Y so we can help you better when problems occur. +endmenu config IWLAGN tristate "Intel Wireless WiFi Next Gen AGN (iwlagn)" diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 728bb858ba9760cefc0367618cf262d42fb529ee..63edbe2e557f7544163597741ef44484f23a06bf 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_IWLAGN) += iwlagn.o iwlagn-objs := iwl-agn.o iwl-agn-rs.o iwl-agn-led.o iwl-agn-ict.o iwlagn-objs += iwl-agn-ucode.o iwl-agn-hcmd.o iwl-agn-tx.o iwlagn-objs += iwl-agn-lib.o iwl-agn-rx.o iwl-agn-calib.o +iwlagn-objs += iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o iwlagn-$(CONFIG_IWL4965) += iwl-4965.o diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 0b779a41a1426b9153a55f30a59a052a9e66f618..db540910b1104d42b5d20d15e542c3fc5da7649c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -50,14 +50,20 @@ /* Highest firmware API version supported */ #define IWL1000_UCODE_API_MAX 3 +#define IWL100_UCODE_API_MAX 5 /* Lowest firmware API version supported */ #define IWL1000_UCODE_API_MIN 1 +#define IWL100_UCODE_API_MIN 5 #define IWL1000_FW_PRE "iwlwifi-1000-" #define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" #define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api) +#define IWL100_FW_PRE "iwlwifi-100-" +#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" +#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api) + /* * For 1000, use advance thermal throttling critical temperature threshold, @@ -120,17 +126,17 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -145,8 +151,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + iwl1000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ /* Set initial calibration set */ @@ -189,9 +194,7 @@ static struct iwl_lib_ops iwl1000_lib = { .update_chain_flags = iwl_update_chain_flags, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl1000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { @@ -203,7 +206,6 @@ static struct iwl_lib_ops iwl1000_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, @@ -214,21 +216,26 @@ static struct iwl_lib_ops iwl1000_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, - .set_ct_kill = iwl1000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } }; static const struct iwl_ops iwl1000_ops = { @@ -238,29 +245,16 @@ static const struct iwl_ops iwl1000_ops = { .led = &iwlagn_led_ops, }; -struct iwl_cfg iwl1000_bgn_cfg = { - .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", - .fw_name_pre = IWL1000_FW_PRE, - .ucode_api_max = IWL1000_UCODE_API_MAX, - .ucode_api_min = IWL1000_UCODE_API_MIN, - .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl1000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, - .eeprom_ver = EEPROM_1000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, +static struct iwl_base_params iwl1000_base_params = { .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, + .eeprom_size = OTP_LOW_IMAGE_SIZE, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, .set_l0s = true, .use_bsm = false, .max_ll_items = OTP_MAX_LL_ITEMS_1000, .shadow_ram_support = false, - .ht_greenfield_support = true, .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, @@ -271,6 +265,26 @@ struct iwl_cfg iwl1000_bgn_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, }; +static struct iwl_ht_params iwl1000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ +}; + +struct iwl_cfg iwl1000_bgn_cfg = { + .name = "Intel(R) Centrino(R) Wireless-N 1000 BGN", + .fw_name_pre = IWL1000_FW_PRE, + .ucode_api_max = IWL1000_UCODE_API_MAX, + .ucode_api_min = IWL1000_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, + .eeprom_ver = EEPROM_1000_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, + .ops = &iwl1000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl1000_base_params, + .ht_params = &iwl1000_ht_params, +}; struct iwl_cfg iwl1000_bg_cfg = { .name = "Intel(R) Centrino(R) Wireless-N 1000 BG", @@ -278,30 +292,45 @@ struct iwl_cfg iwl1000_bg_cfg = { .ucode_api_max = IWL1000_UCODE_API_MAX, .ucode_api_min = IWL1000_UCODE_API_MIN, .sku = IWL_SKU_G, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, + .eeprom_ver = EEPROM_1000_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, .ops = &iwl1000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl1000_base_params, +}; + +struct iwl_cfg iwl100_bgn_cfg = { + .name = "Intel(R) 100 Series 1x1 BGN", + .fw_name_pre = IWL100_FW_PRE, + .ucode_api_max = IWL100_UCODE_API_MAX, + .ucode_api_min = IWL100_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, .eeprom_ver = EEPROM_1000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl1000_ops, .mod_params = &iwlagn_mod_params, + .base_params = &iwl1000_base_params, + .ht_params = &iwl1000_ht_params, +}; + +struct iwl_cfg iwl100_bg_cfg = { + .name = "Intel(R) 100 Series 1x1 BG", + .fw_name_pre = IWL100_FW_PRE, + .ucode_api_max = IWL100_UCODE_API_MAX, + .ucode_api_min = IWL100_UCODE_API_MIN, + .sku = IWL_SKU_G, .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .max_ll_items = OTP_MAX_LL_ITEMS_1000, - .shadow_ram_support = false, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 128, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .valid_rx_ant = ANT_A, + .eeprom_ver = EEPROM_1000_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION, + .ops = &iwl1000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl1000_base_params, }; MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL100_MODULE_FIRMWARE(IWL100_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h index 7c731a79363252915243fc01350b8077b50bce58..65b5834da28c719b516fb8e55c022ad1beed08e7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h @@ -62,7 +62,7 @@ *****************************************************************************/ /* * Please use this file (iwl-3945-hw.h) only for hardware-related definitions. - * Please use iwl-3945-commands.h for uCode API definitions. + * Please use iwl-commands.h for uCode API definitions. * Please use iwl-3945.h for driver implementation definitions. */ @@ -226,6 +226,7 @@ struct iwl3945_eeprom { /* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */ #define IWL39_NUM_QUEUES 5 +#define IWL39_CMD_QUEUE_NUM 4 #define IWL_DEFAULT_TX_RETRY 15 diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index 293e1dbc166c4cb5027ad3cef324d07ab1f1164a..1f3e7e34fbc716523226e4282e6d9f50e1fcdcf9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -343,7 +343,7 @@ void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 s int i; IWL_DEBUG_INFO(priv, "enter\n"); - if (sta_id == priv->hw_params.bcast_sta_id) + if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) goto out; psta = (struct iwl3945_sta_priv *) sta->drv_priv; @@ -933,7 +933,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) rcu_read_lock(); - sta = ieee80211_find_sta(priv->vif, + sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif, priv->stations[sta_id].sta.sta.addr); if (!sta) { IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n"); @@ -950,7 +950,8 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) switch (priv->band) { case IEEE80211_BAND_2GHZ: /* TODO: this always does G, not a regression */ - if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { + if (priv->contexts[IWL_RXON_CTX_BSS].active.flags & + RXON_FLG_TGG_PROTECT_MSK) { rs_sta->tgg = 1; rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; } else diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 8ccfcd08218d894895524c3995fca28f2695aa6c..176e525776734bbabbdcf3f0801b3720779688b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -87,6 +87,15 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = { IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */ }; +static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) +{ + u8 rate = iwl3945_rates[rate_index].prev_ieee; + + if (rate == IWL_RATE_INVALID) + rate = rate_index; + return rate; +} + /* 1 = enable the iwl3945_disable_events() function */ #define IWL_EVT_DISABLE (0) #define IWL_EVT_DISABLE_SIZE (1532/32) @@ -245,7 +254,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate) break; case IEEE80211_BAND_2GHZ: if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && - iwl_is_associated(priv)) { + iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { if (rate == IWL_RATE_11M_INDEX) next_rate = IWL_RATE_5M_INDEX; } @@ -273,7 +282,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, struct iwl_queue *q = &txq->q; struct iwl_tx_info *tx_info; - BUG_ON(txq_id == IWL_CMD_QUEUE_NUM); + BUG_ON(txq_id == IWL39_CMD_QUEUE_NUM); for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index; q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { @@ -285,7 +294,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, } if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && - (txq_id != IWL_CMD_QUEUE_NUM) && + (txq_id != IWL39_CMD_QUEUE_NUM) && priv->mac80211_registered) iwl_wake_queue(priv, txq_id); } @@ -339,7 +348,7 @@ static void iwl3945_rx_reply_tx(struct iwl_priv *priv, IWL_DEBUG_TX_REPLY(priv, "Tx queue reclaim %d\n", index); iwl3945_tx_queue_reclaim(priv, txq_id, index); - if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) + if (status & TX_ABORT_REQUIRED_MSK) IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); } @@ -406,7 +415,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv, unsigned int plcp_msec; unsigned long plcp_received_jiffies; - if (priv->cfg->plcp_delta_threshold == + if (priv->cfg->base_params->plcp_delta_threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); return rc; @@ -432,7 +441,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv, if ((combined_plcp_delta > 0) && ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->plcp_delta_threshold) { + priv->cfg->base_params->plcp_delta_threshold) { /* * if plcp_err exceed the threshold, the following * data is printed in csv format: @@ -444,7 +453,7 @@ static bool iwl3945_good_plcp_health(struct iwl_priv *priv, */ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " "%u, %d, %u mSecs\n", - priv->cfg->plcp_delta_threshold, + priv->cfg->base_params->plcp_delta_threshold, le32_to_cpu(current_stat.rx.ofdm.plcp_err), combined_plcp_delta, plcp_msec); /* @@ -760,7 +769,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, data_retry_limit = IWL_DEFAULT_TX_RETRY; tx_cmd->data_retry_limit = data_retry_limit; - if (tx_id >= IWL_CMD_QUEUE_NUM) + if (tx_id >= IWL39_CMD_QUEUE_NUM) rts_retry_limit = 3; else rts_retry_limit = 7; @@ -807,9 +816,12 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate) return sta_id; } -static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) +static void iwl3945_set_pwr_vmain(struct iwl_priv *priv) { - if (src == IWL_PWR_SRC_VAUX) { +/* + * (for documentation purposes) + * to set power to V_AUX, do + if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) { iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VAUX, @@ -819,16 +831,14 @@ static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) CSR_GPIO_IN_VAL_VAUX_PWR_SRC, CSR_GPIO_IN_BIT_AUX_POWER, 5000); } - } else { - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, - ~APMG_PS_CTRL_MSK_PWR_SRC); + */ - iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, - CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ - } + iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, + ~APMG_PS_CTRL_MSK_PWR_SRC); - return 0; + iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC, + CSR_GPIO_IN_BIT_AUX_POWER, 5000); /* uS */ } static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) @@ -909,7 +919,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv) /* Tx queue(s) */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? + slots_num = (txq_id == IWL39_CMD_QUEUE_NUM) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, txq_id); @@ -1022,9 +1032,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv) priv->cfg->ops->lib->apm_ops.init(priv); spin_unlock_irqrestore(&priv->lock, flags); - rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); - if (rc) - return rc; + iwl3945_set_pwr_vmain(priv); priv->cfg->ops->lib->apm_ops.config(priv); @@ -1072,7 +1080,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv) if (priv->txq) for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) - if (txq_id == IWL_CMD_QUEUE_NUM) + if (txq_id == IWL39_CMD_QUEUE_NUM) iwl_cmd_queue_free(priv); else iwl_tx_queue_free(priv, txq_id); @@ -1439,17 +1447,18 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv) int rate_idx, i; const struct iwl_channel_info *ch_info = NULL; struct iwl3945_txpowertable_cmd txpower = { - .channel = priv->active_rxon.channel, + .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel, }; + u16 chan; + + chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel); txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; - ch_info = iwl_get_channel_info(priv, - priv->band, - le16_to_cpu(priv->active_rxon.channel)); + ch_info = iwl_get_channel_info(priv, priv->band, chan); if (!ch_info) { IWL_ERR(priv, "Failed to get channel info for channel %d [%d]\n", - le16_to_cpu(priv->active_rxon.channel), priv->band); + chan, priv->band); return -EINVAL; } @@ -1710,7 +1719,8 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) return 0; } -static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) +static int iwl3945_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int rc = 0; struct iwl_rx_packet *pkt; @@ -1721,8 +1731,8 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) .flags = CMD_WANT_SKB, .data = &rxon_assoc, }; - const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; - const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; + const struct iwl_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_rxon_cmd *rxon2 = &ctx->active; if ((rxon1->flags == rxon2->flags) && (rxon1->filter_flags == rxon2->filter_flags) && @@ -1732,10 +1742,10 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) return 0; } - rxon_assoc.flags = priv->staging_rxon.flags; - rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; - rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; rxon_assoc.reserved = 0; rc = iwl_send_cmd_sync(priv, &cmd); @@ -1761,14 +1771,13 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) * function correctly transitions out of the RXON_ASSOC_MSK state if * a HW tune is required based on the RXON structure changes. */ -static int iwl3945_commit_rxon(struct iwl_priv *priv) +int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ - struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; - struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon; + struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active; + struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging; int rc = 0; - bool new_assoc = - !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); + bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK); if (!iwl_is_alive(priv)) return -1; @@ -1781,7 +1790,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); staging_rxon->flags |= iwl3945_get_antenna_flags(priv); - rc = iwl_check_rxon_cmd(priv); + rc = iwl_check_rxon_cmd(priv, ctx); if (rc) { IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); return -EINVAL; @@ -1790,8 +1799,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) /* If we don't need to send a full RXON, we can use * iwl3945_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv)) { - rc = iwl_send_rxon_assoc(priv); + if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) { + rc = iwl_send_rxon_assoc(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); if (rc) { IWL_ERR(priv, "Error setting RXON_ASSOC " "configuration (%d).\n", rc); @@ -1807,7 +1817,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) * an RXON_ASSOC and the new config wants the associated mask enabled, * we must clear the associated from the active configuration * before we apply the new config */ - if (iwl_is_associated(priv) && new_assoc) { + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) { IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; @@ -1819,7 +1829,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) active_rxon->reserved5 = 0; rc = iwl_send_cmd_pdu(priv, REPLY_RXON, sizeof(struct iwl3945_rxon_cmd), - &priv->active_rxon); + &priv->contexts[IWL_RXON_CTX_BSS].active); /* If the mask clearing failed then we set * active_rxon back to what it was previously */ @@ -1829,8 +1839,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) "configuration (%d).\n", rc); return rc; } - iwl_clear_ucode_stations(priv); - iwl_restore_stations(priv); + iwl_clear_ucode_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); } IWL_DEBUG_INFO(priv, "Sending RXON\n" @@ -1848,7 +1859,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) staging_rxon->reserved4 = 0; staging_rxon->reserved5 = 0; - iwl_set_rxon_hwcrypto(priv, !iwl3945_mod_params.sw_crypto); + iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto); /* Apply the new configuration */ rc = iwl_send_cmd_pdu(priv, REPLY_RXON, @@ -1862,8 +1873,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); if (!new_assoc) { - iwl_clear_ucode_stations(priv); - iwl_restore_stations(priv); + iwl_clear_ucode_stations(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); + iwl_restore_stations(priv, &priv->contexts[IWL_RXON_CTX_BSS]); } /* If we issue a new RXON command which required a tune then we must @@ -2295,6 +2307,32 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) return (u16)sizeof(struct iwl3945_addsta_cmd); } +static int iwl3945_add_bssid_station(struct iwl_priv *priv, + const u8 *addr, u8 *sta_id_r) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + int ret; + u8 sta_id; + unsigned long flags; + + if (sta_id_r) + *sta_id_r = IWL_INVALID_STATION; + + ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM\n", addr); + return ret; + } + + if (sta_id_r) + *sta_id_r = sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].used |= IWL_STA_LOCAL; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} static int iwl3945_manage_ibss_station(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add) { @@ -2302,8 +2340,8 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv, int ret; if (add) { - ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false, - &vif_priv->ibss_bssid_sta_id); + ret = iwl3945_add_bssid_station(priv, vif->bss_conf.bssid, + &vif_priv->ibss_bssid_sta_id); if (ret) return ret; @@ -2366,7 +2404,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv) * 1M CCK rates */ if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && - iwl_is_associated(priv)) { + iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { index = IWL_FIRST_CCK_RATE; for (i = IWL_RATE_6M_INDEX_TABLE; @@ -2414,14 +2452,16 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv) } /* Assign number of Usable TX queues */ - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_3K); priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; priv->hw_params.max_stations = IWL3945_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID; + + priv->sta_key_max_num = STA_KEY_MAX_NUM; priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; @@ -2439,7 +2479,8 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); - tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; + tx_beacon_cmd->tx.sta_id = + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; frame_size = iwl3945_fill_beacon_frame(priv, @@ -2663,9 +2704,7 @@ static struct iwl_lib_ops iwl3945_lib = { .dump_nic_error_log = iwl3945_dump_nic_error_log, .apm_ops = { .init = iwl3945_apm_init, - .stop = iwl_apm_stop, .config = iwl3945_nic_config, - .set_pwr_src = iwl3945_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { @@ -2677,7 +2716,6 @@ static struct iwl_lib_ops iwl3945_lib = { EEPROM_REGULATORY_BAND_NO_HT40, EEPROM_REGULATORY_BAND_NO_HT40, }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwl3945_eeprom_acquire_semaphore, .release_semaphore = iwl3945_eeprom_release_semaphore, .query_addr = iwlcore_eeprom_query_addr, @@ -2703,6 +2741,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = { .build_addsta_hcmd = iwl3945_build_addsta_hcmd, .tx_cmd_protection = iwlcore_tx_cmd_protection, .request_scan = iwl3945_request_scan, + .post_scan = iwl3945_post_scan, }; static const struct iwl_ops iwl3945_ops = { @@ -2712,22 +2751,13 @@ static const struct iwl_ops iwl3945_ops = { .led = &iwl3945_led_ops, }; -static struct iwl_cfg iwl3945_bg_cfg = { - .name = "3945BG", - .fw_name_pre = IWL3945_FW_PRE, - .ucode_api_max = IWL3945_UCODE_API_MAX, - .ucode_api_min = IWL3945_UCODE_API_MIN, - .sku = IWL_SKU_G, +static struct iwl_base_params iwl3945_base_params = { .eeprom_size = IWL3945_EEPROM_IMG_SIZE, - .eeprom_ver = EEPROM_3945_EEPROM_VERSION, - .ops = &iwl3945_ops, .num_of_queues = IWL39_NUM_QUEUES, - .mod_params = &iwl3945_mod_params, .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL, .set_l0s = false, .use_bsm = true, .use_isr_legacy = true, - .ht_greenfield_support = false, .led_compensation = 64, .broken_powersave = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, @@ -2736,25 +2766,28 @@ static struct iwl_cfg iwl3945_bg_cfg = { .tx_power_by_driver = true, }; +static struct iwl_cfg iwl3945_bg_cfg = { + .name = "3945BG", + .fw_name_pre = IWL3945_FW_PRE, + .ucode_api_max = IWL3945_UCODE_API_MAX, + .ucode_api_min = IWL3945_UCODE_API_MIN, + .sku = IWL_SKU_G, + .eeprom_ver = EEPROM_3945_EEPROM_VERSION, + .ops = &iwl3945_ops, + .mod_params = &iwl3945_mod_params, + .base_params = &iwl3945_base_params, +}; + static struct iwl_cfg iwl3945_abg_cfg = { .name = "3945ABG", .fw_name_pre = IWL3945_FW_PRE, .ucode_api_max = IWL3945_UCODE_API_MAX, .ucode_api_min = IWL3945_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .eeprom_size = IWL3945_EEPROM_IMG_SIZE, .eeprom_ver = EEPROM_3945_EEPROM_VERSION, .ops = &iwl3945_ops, - .num_of_queues = IWL39_NUM_QUEUES, .mod_params = &iwl3945_mod_params, - .use_isr_legacy = true, - .ht_greenfield_support = false, - .led_compensation = 64, - .broken_powersave = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 512, - .tx_power_by_driver = true, + .base_params = &iwl3945_base_params, }; DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = { diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index bb2aeebf3652c1ce38bb8620f822a64e3f2f4782..09391f0ee61f03c9d486a75f5f3c195b04381e24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -138,8 +138,6 @@ enum iwl3945_antenna { #define DEFAULT_SHORT_RETRY_LIMIT 7U #define DEFAULT_LONG_RETRY_LIMIT 4U -#include "iwl-agn-rs.h" - #define IWL_TX_FIFO_AC0 0 #define IWL_TX_FIFO_AC1 1 #define IWL_TX_FIFO_AC2 2 @@ -271,6 +269,9 @@ extern void iwl3945_post_associate(struct iwl_priv *priv, extern void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif); +extern int iwl3945_commit_rxon(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); + /** * iwl3945_hw_find_station - Find station id for a given BSSID * @bssid: MAC address of station ID to find @@ -295,7 +296,11 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info( extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); /* scanning */ -void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +void iwl3945_post_scan(struct iwl_priv *priv); + +/* rates */ +extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; /* Requires full declaration of iwl_priv before including */ #include "iwl-io.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d92b729092336523a5c0a2a541bfbd7cb1b4b640..b207e3e9299f11dd6b8d02edf7e4b148b07c98d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -43,7 +43,7 @@ #include "iwl-core.h" #include "iwl-io.h" #include "iwl-helpers.h" -#include "iwl-calib.h" +#include "iwl-agn-calib.h" #include "iwl-sta.h" #include "iwl-agn-led.h" #include "iwl-agn.h" @@ -347,7 +347,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv) struct iwl_chain_noise_data *data = &(priv->chain_noise_data); if ((data->state == IWL_CHAIN_NOISE_ALIVE) && - iwl_is_associated(priv)) { + iwl_is_any_associated(priv)) { struct iwl_calib_diff_gain_cmd cmd; /* clear data for chain noise calibration algorithm */ @@ -576,7 +576,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) /* Activate all Tx DMA/FIFO channels */ priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6)); - iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); + iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0); /* make sure all queue are not stopped */ memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); @@ -587,6 +587,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) priv->txq_ctx_active_msk = 0; /* Map each Tx/cmd queue to its corresponding fifo */ BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7); + for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) { int ac = default_queue_to_tx_fifo[i]; @@ -646,17 +647,17 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwl4965_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWL4965_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID; priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; @@ -668,8 +669,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant); priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + + iwl4965_set_ct_threshold(priv); priv->hw_params.sens = &iwl4965_sensitivity; priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; @@ -1374,6 +1375,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) u8 band = 0; bool is_ht40 = false; u8 ctrl_chan_high = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; if (test_bit(STATUS_SCANNING, &priv->status)) { /* If this gets hit a lot, switch it to a BUG() and catch @@ -1385,17 +1387,16 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) band = priv->band == IEEE80211_BAND_2GHZ; - is_ht40 = is_ht40_channel(priv->active_rxon.flags); + is_ht40 = is_ht40_channel(ctx->active.flags); - if (is_ht40 && - (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) ctrl_chan_high = 1; cmd.band = band; - cmd.channel = priv->active_rxon.channel; + cmd.channel = ctx->active.channel; ret = iwl4965_fill_txpower_tbl(priv, band, - le16_to_cpu(priv->active_rxon.channel), + le16_to_cpu(ctx->active.channel), is_ht40, ctrl_chan_high, &cmd.tx_power); if (ret) goto out; @@ -1406,12 +1407,13 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv) return ret; } -static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) +static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int ret = 0; struct iwl4965_rxon_assoc_cmd rxon_assoc; - const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; - const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; + const struct iwl_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_rxon_cmd *rxon2 = &ctx->active; if ((rxon1->flags == rxon2->flags) && (rxon1->filter_flags == rxon2->filter_flags) && @@ -1426,16 +1428,16 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) return 0; } - rxon_assoc.flags = priv->staging_rxon.flags; - rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; - rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; rxon_assoc.reserved = 0; rxon_assoc.ofdm_ht_single_stream_basic_rates = - priv->staging_rxon.ofdm_ht_single_stream_basic_rates; + ctx->staging.ofdm_ht_single_stream_basic_rates; rxon_assoc.ofdm_ht_dual_stream_basic_rates = - priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; - rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; + ctx->staging.ofdm_ht_dual_stream_basic_rates; + rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, sizeof(rxon_assoc), &rxon_assoc, NULL); @@ -1448,6 +1450,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) static int iwl4965_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch) { + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; int rc; u8 band = 0; bool is_ht40 = false; @@ -1458,22 +1461,22 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 ch; u32 tsf_low; u8 switch_count; - u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); - struct ieee80211_vif *vif = priv->vif; + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); + struct ieee80211_vif *vif = ctx->vif; band = priv->band == IEEE80211_BAND_2GHZ; - is_ht40 = is_ht40_channel(priv->staging_rxon.flags); + is_ht40 = is_ht40_channel(ctx->staging.flags); if (is_ht40 && - (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) + (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) ctrl_chan_high = 1; cmd.band = band; cmd.expect_beacon = 0; - ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + ch = ch_switch->channel->hw_value; cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = priv->staging_rxon.flags; - cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -1508,7 +1511,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); return -EFAULT; } @@ -1721,13 +1724,13 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, u8 tx_fifo) { if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || - (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues - <= txq_id)) { + (IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { IWL_WARN(priv, "queue number out of range: %d, must be %d to %d\n", txq_id, IWL49_FIRST_AMPDU_QUEUE, IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->num_of_ampdu_queues - 1); + priv->cfg->base_params->num_of_ampdu_queues - 1); return -EINVAL; } @@ -1789,13 +1792,13 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, int ret; if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) || - (IWL49_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues - <= txq_id)) { + (IWL49_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { IWL_WARN(priv, "queue number out of range: %d, must be %d to %d\n", txq_id, IWL49_FIRST_AMPDU_QUEUE, IWL49_FIRST_AMPDU_QUEUE + - priv->cfg->num_of_ampdu_queues - 1); + priv->cfg->base_params->num_of_ampdu_queues - 1); return -EINVAL; } @@ -2007,7 +2010,7 @@ static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) start = IWL_STA_ID; if (is_broadcast_ether_addr(addr)) - return priv->hw_params.bcast_sta_id; + return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; spin_lock_irqsave(&priv->sta_lock, flags); for (i = start; i < priv->hw_params.max_stations; i++) @@ -2213,11 +2216,23 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) static struct iwl_hcmd_ops iwl4965_hcmd = { .rxon_assoc = iwl4965_send_rxon_assoc, - .commit_rxon = iwl_commit_rxon, - .set_rxon_chain = iwl_set_rxon_chain, + .commit_rxon = iwlagn_commit_rxon, + .set_rxon_chain = iwlagn_set_rxon_chain, .send_bt_config = iwl_send_bt_config, }; +static void iwl4965_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwlcore_commit_rxon(priv, ctx); +} + static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { .get_hcmd_size = iwl4965_get_hcmd_size, .build_addsta_hcmd = iwl4965_build_addsta_hcmd, @@ -2226,6 +2241,7 @@ static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { .tx_cmd_protection = iwlcore_tx_cmd_protection, .calc_rssi = iwl4965_calc_rssi, .request_scan = iwlagn_request_scan, + .post_scan = iwl4965_post_scan, }; static struct iwl_lib_ops iwl4965_lib = { @@ -2250,9 +2266,7 @@ static struct iwl_lib_ops iwl4965_lib = { .set_channel_switch = iwl4965_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl4965_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { @@ -2264,7 +2278,6 @@ static struct iwl_lib_ops iwl4965_lib = { EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS, EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwl4965_eeprom_calib_version, @@ -2277,15 +2290,15 @@ static struct iwl_lib_ops iwl4965_lib = { .isr = iwl_isr_legacy, .temp_ops = { .temperature = iwl4965_temperature_calib, - .set_ct_kill = iwl4965_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, @@ -2298,26 +2311,14 @@ static const struct iwl_ops iwl4965_ops = { .led = &iwlagn_led_ops, }; -struct iwl_cfg iwl4965_agn_cfg = { - .name = "Intel(R) Wireless WiFi Link 4965AGN", - .fw_name_pre = IWL4965_FW_PRE, - .ucode_api_max = IWL4965_UCODE_API_MAX, - .ucode_api_min = IWL4965_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, +static struct iwl_base_params iwl4965_base_params = { .eeprom_size = IWL4965_EEPROM_IMG_SIZE, - .eeprom_ver = EEPROM_4965_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, - .ops = &iwl4965_ops, .num_of_queues = IWL49_NUM_QUEUES, .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_ABC, .pll_cfg_val = 0, .set_l0s = true, .use_bsm = true, .use_isr_legacy = true, - .ht_greenfield_support = false, .broken_powersave = true, .led_compensation = 61, .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, @@ -2329,6 +2330,21 @@ struct iwl_cfg iwl4965_agn_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, +}; + +struct iwl_cfg iwl4965_agn_cfg = { + .name = "Intel(R) Wireless WiFi Link 4965AGN", + .fw_name_pre = IWL4965_FW_PRE, + .ucode_api_max = IWL4965_UCODE_API_MAX, + .ucode_api_min = IWL4965_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_ABC, + .eeprom_ver = EEPROM_4965_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION, + .ops = &iwl4965_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl4965_base_params, /* * Force use of chains B and C for scan RX on 5 GHz band * because the device has off-channel reception on chain A. diff --git a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 146e6431ae950686b266f6d42f38c42b2be06470..3975e45e750065fd76df7417a441208184e7a1d4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -62,7 +62,7 @@ *****************************************************************************/ /* * Please use this file (iwl-5000-hw.h) only for hardware-related definitions. - * Use iwl-5000-commands.h for uCode API definitions. + * Use iwl-commands.h for uCode API definitions. */ #ifndef __iwl_5000_hw_h__ diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 48bdcd8d2e94c3355c877a55d8e7815249350fdc..fd9fbc93ea1b21d20b9d494f7f7a6a04422e679b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -170,17 +170,17 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -195,8 +195,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + iwl5000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ /* Set initial calibration set */ @@ -217,17 +216,17 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -242,8 +241,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + iwl5150_set_ct_threshold(priv); /* Set initial sensitivity parameters */ /* Set initial calibration set */ @@ -275,14 +273,19 @@ static void iwl5150_temperature(struct iwl_priv *priv) static int iwl5000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch) { + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl5000_channel_switch_cmd cmd; const struct iwl_channel_info *ch_info; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; u8 switch_count; - u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); - struct ieee80211_vif *vif = priv->vif; + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); + struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, .len = sizeof(cmd), @@ -291,12 +294,12 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; - ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + ch = ch_switch->channel->hw_value; IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = priv->staging_rxon.flags; - cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -331,7 +334,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); return -EFAULT; } priv->switch_rxon.channel = cmd.channel; @@ -365,9 +368,7 @@ static struct iwl_lib_ops iwl5000_lib = { .set_channel_switch = iwl5000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl5000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { @@ -379,7 +380,6 @@ static struct iwl_lib_ops iwl5000_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, @@ -390,21 +390,26 @@ static struct iwl_lib_ops iwl5000_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, - .set_ct_kill = iwl5000_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } }; static struct iwl_lib_ops iwl5150_lib = { @@ -431,9 +436,7 @@ static struct iwl_lib_ops iwl5150_lib = { .set_channel_switch = iwl5000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl5000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { @@ -445,7 +448,6 @@ static struct iwl_lib_ops iwl5150_lib = { EEPROM_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, @@ -456,20 +458,26 @@ static struct iwl_lib_ops iwl5150_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwl5150_temperature, - .set_ct_kill = iwl5150_set_ct_threshold, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } }; static const struct iwl_ops iwl5000_ops = { @@ -486,27 +494,14 @@ static const struct iwl_ops iwl5150_ops = { .led = &iwlagn_led_ops, }; -struct iwl_cfg iwl5300_agn_cfg = { - .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", - .fw_name_pre = IWL5000_FW_PRE, - .ucode_api_max = IWL5000_UCODE_API_MAX, - .ucode_api_min = IWL5000_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5000_ops, +static struct iwl_base_params iwl5000_base_params = { .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, - .eeprom_ver = EEPROM_5000_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, .set_l0s = true, .use_bsm = false, - .ht_greenfield_support = true, .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, .chain_noise_scale = 1000, @@ -516,6 +511,26 @@ struct iwl_cfg iwl5300_agn_cfg = { .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, }; +static struct iwl_ht_params iwl5000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ +}; + +struct iwl_cfg iwl5300_agn_cfg = { + .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", + .fw_name_pre = IWL5000_FW_PRE, + .ucode_api_max = IWL5000_UCODE_API_MAX, + .ucode_api_min = IWL5000_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_ABC, + .valid_rx_ant = ANT_ABC, + .eeprom_ver = EEPROM_5000_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, + .ops = &iwl5000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, +}; struct iwl_cfg iwl5100_bgn_cfg = { .name = "Intel(R) WiFi Link 5100 BGN", @@ -523,29 +538,14 @@ struct iwl_cfg iwl5100_bgn_cfg = { .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5000_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_B, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, }; struct iwl_cfg iwl5100_abg_cfg = { @@ -554,27 +554,13 @@ struct iwl_cfg iwl5100_abg_cfg = { .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl5000_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_B, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, }; struct iwl_cfg iwl5100_agn_cfg = { @@ -583,29 +569,14 @@ struct iwl_cfg iwl5100_agn_cfg = { .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5000_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_B, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_B, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, }; struct iwl_cfg iwl5350_agn_cfg = { @@ -614,29 +585,14 @@ struct iwl_cfg iwl5350_agn_cfg = { .ucode_api_max = IWL5000_UCODE_API_MAX, .ucode_api_min = IWL5000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5000_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_ABC, + .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, }; struct iwl_cfg iwl5150_agn_cfg = { @@ -645,29 +601,14 @@ struct iwl_cfg iwl5150_agn_cfg = { .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl5150_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5150_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, + .ht_params = &iwl5000_ht_params, .need_dc_calib = true, }; @@ -677,27 +618,13 @@ struct iwl_cfg iwl5150_abg_cfg = { .ucode_api_max = IWL5150_UCODE_API_MAX, .ucode_api_min = IWL5150_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl5150_ops, - .eeprom_size = IWLAGN_EEPROM_IMG_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_5050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl5150_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = CSR50_ANA_PLL_CFG_VAL, - .set_l0s = true, - .use_bsm = false, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl5000_base_params, .need_dc_calib = true, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h index ddba39999997a05027b78b4b44f95ed302eba422..47891e16a75805f3d8c40ba98ae01099a58d0e27 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-6000-hw.h @@ -62,7 +62,7 @@ *****************************************************************************/ /* * Please use this file (iwl-6000-hw.h) only for hardware-related definitions. - * Use iwl-5000-commands.h for uCode API definitions. + * Use iwl-commands.h for uCode API definitions. */ #ifndef __iwl_6000_hw_h__ diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index cee06b968de807a642adb4db4e08e62cfe2237ab..11e6532fc573d1ed93d5ec4aaf886342d0fe8073 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -51,13 +51,15 @@ /* Highest firmware API version supported */ #define IWL6000_UCODE_API_MAX 4 -#define IWL6050_UCODE_API_MAX 4 -#define IWL6000G2_UCODE_API_MAX 4 +#define IWL6050_UCODE_API_MAX 5 +#define IWL6000G2_UCODE_API_MAX 5 +#define IWL130_UCODE_API_MAX 5 /* Lowest firmware API version supported */ #define IWL6000_UCODE_API_MIN 4 #define IWL6050_UCODE_API_MIN 4 #define IWL6000G2_UCODE_API_MIN 4 +#define IWL130_UCODE_API_MIN 5 #define IWL6000_FW_PRE "iwlwifi-6000-" #define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" @@ -75,6 +77,9 @@ #define _IWL6000G2B_MODULE_FIRMWARE(api) IWL6000G2B_FW_PRE #api ".ucode" #define IWL6000G2B_MODULE_FIRMWARE(api) _IWL6000G2B_MODULE_FIRMWARE(api) +#define IWL130_FW_PRE "iwlwifi-130-" +#define _IWL130_MODULE_FIRMWARE(api) IWL130_FW_PRE #api ".ucode" +#define IWL130_MODULE_FIRMWARE(api) _IWL130_MODULE_FIRMWARE(api) static void iwl6000_set_ct_threshold(struct iwl_priv *priv) { @@ -83,15 +88,24 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; } -/* Indicate calibration version to uCode. */ -static void iwl6000_set_calib_version(struct iwl_priv *priv) +static void iwl6050_additional_nic_config(struct iwl_priv *priv) { - if (priv->cfg->need_dc_calib && - (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)) + /* Indicate calibration version to uCode. */ + if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) iwl_set_bit(priv, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); } +static void iwl6050g2_additional_nic_config(struct iwl_priv *priv) +{ + /* Indicate calibration version to uCode. */ + if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) + iwl_set_bit(priv, CSR_GP_DRIVER_REG, + CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); + iwl_set_bit(priv, CSR_GP_DRIVER_REG, + CSR_GP_DRIVER_REG_BIT_6050_1x2); +} + /* NIC configuration for 6000 series */ static void iwl6000_nic_config(struct iwl_priv *priv) { @@ -117,9 +131,11 @@ static void iwl6000_nic_config(struct iwl_priv *priv) iwl_write32(priv, CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); } - /* else do nothing, uCode configured */ - if (priv->cfg->ops->lib->temp_ops.set_calib_version) - priv->cfg->ops->lib->temp_ops.set_calib_version(priv); + /* do additional nic configuration if needed */ + if (priv->cfg->ops->nic && + priv->cfg->ops->nic->additional_nic_config) { + priv->cfg->ops->nic->additional_nic_config(priv); + } } static struct iwl_sensitivity_ranges iwl6000_sensitivity = { @@ -151,17 +167,17 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) { if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) - priv->cfg->num_of_queues = + priv->cfg->base_params->num_of_queues = priv->cfg->mod_params->num_of_queues; - priv->hw_params.max_txq_num = priv->cfg->num_of_queues; + priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; priv->hw_params.scd_bc_tbls_size = - priv->cfg->num_of_queues * + priv->cfg->base_params->num_of_queues * sizeof(struct iwlagn_scd_bc_tbl); priv->hw_params.tfd_size = sizeof(struct iwl_tfd); priv->hw_params.max_stations = IWLAGN_STATION_COUNT; - priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; @@ -176,8 +192,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant; priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant; - if (priv->cfg->ops->lib->temp_ops.set_ct_kill) - priv->cfg->ops->lib->temp_ops.set_ct_kill(priv); + iwl6000_set_ct_threshold(priv); /* Set initial sensitivity parameters */ /* Set initial calibration set */ @@ -188,7 +203,9 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) BIT(IWL_CALIB_TX_IQ) | BIT(IWL_CALIB_BASE_BAND); if (priv->cfg->need_dc_calib) - priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_DC); + priv->hw_params.calib_rt_cfg |= BIT(IWL_CALIB_CFG_DC_IDX); + if (priv->cfg->need_temp_offset_calib) + priv->hw_params.calib_init_cfg |= BIT(IWL_CALIB_TEMP_OFFSET); priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS; @@ -198,14 +215,19 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) static int iwl6000_hw_channel_switch(struct iwl_priv *priv, struct ieee80211_channel_switch *ch_switch) { + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl6000_channel_switch_cmd cmd; const struct iwl_channel_info *ch_info; u32 switch_time_in_usec, ucode_switch_time; u16 ch; u32 tsf_low; u8 switch_count; - u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); - struct ieee80211_vif *vif = priv->vif; + u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); + struct ieee80211_vif *vif = ctx->vif; struct iwl_host_cmd hcmd = { .id = REPLY_CHANNEL_SWITCH, .len = sizeof(cmd), @@ -214,12 +236,12 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, }; cmd.band = priv->band == IEEE80211_BAND_2GHZ; - ch = ieee80211_frequency_to_channel(ch_switch->channel->center_freq); + ch = ch_switch->channel->hw_value; IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); cmd.channel = cpu_to_le16(ch); - cmd.rxon_flags = priv->staging_rxon.flags; - cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; + cmd.rxon_flags = ctx->staging.flags; + cmd.rxon_filter_flags = ctx->staging.filter_flags; switch_count = ch_switch->count; tsf_low = ch_switch->timestamp & 0x0ffffffff; /* @@ -254,7 +276,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, cmd.expect_beacon = is_channel_radar(ch_info); else { IWL_ERR(priv, "invalid channel switch from %u to %u\n", - priv->active_rxon.channel, ch); + ctx->active.channel, ch); return -EFAULT; } priv->switch_rxon.channel = cmd.channel; @@ -288,9 +310,7 @@ static struct iwl_lib_ops iwl6000_lib = { .set_channel_switch = iwl6000_hw_channel_switch, .apm_ops = { .init = iwl_apm_init, - .stop = iwl_apm_stop, .config = iwl6000_nic_config, - .set_pwr_src = iwl_set_pwr_src, }, .eeprom_ops = { .regulatory_bands = { @@ -302,7 +322,6 @@ static struct iwl_lib_ops iwl6000_lib = { EEPROM_6000_REG_BAND_24_HT40_CHANNELS, EEPROM_REG_BAND_52_HT40_CHANNELS }, - .verify_signature = iwlcore_eeprom_verify_signature, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore, .calib_version = iwlagn_eeprom_calib_version, @@ -314,22 +333,105 @@ static struct iwl_lib_ops iwl6000_lib = { .config_ap = iwl_config_ap, .temp_ops = { .temperature = iwlagn_temperature, - .set_ct_kill = iwl6000_set_ct_threshold, - .set_calib_version = iwl6000_set_calib_version, }, .manage_ibss_station = iwlagn_manage_ibss_station, - .update_bcast_station = iwl_update_bcast_station, + .update_bcast_stations = iwl_update_bcast_stations, + .debugfs_ops = { + .rx_stats_read = iwl_ucode_rx_stats_read, + .tx_stats_read = iwl_ucode_tx_stats_read, + .general_stats_read = iwl_ucode_general_stats_read, + .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, + }, + .recover_from_tx_stall = iwl_bg_monitor_recover, + .check_plcp_health = iwl_good_plcp_health, + .check_ack_health = iwl_good_ack_health, + .txfifo_flush = iwlagn_txfifo_flush, + .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } +}; + +static struct iwl_lib_ops iwl6000g2b_lib = { + .set_hw_params = iwl6000_hw_set_hw_params, + .txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl, + .txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl, + .txq_set_sched = iwlagn_txq_set_sched, + .txq_agg_enable = iwlagn_txq_agg_enable, + .txq_agg_disable = iwlagn_txq_agg_disable, + .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd, + .txq_free_tfd = iwl_hw_txq_free_tfd, + .txq_init = iwl_hw_tx_queue_init, + .rx_handler_setup = iwlagn_bt_rx_handler_setup, + .setup_deferred_work = iwlagn_bt_setup_deferred_work, + .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, + .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, + .load_ucode = iwlagn_load_ucode, + .dump_nic_event_log = iwl_dump_nic_event_log, + .dump_nic_error_log = iwl_dump_nic_error_log, + .dump_csr = iwl_dump_csr, + .dump_fh = iwl_dump_fh, + .init_alive_start = iwlagn_init_alive_start, + .alive_notify = iwlagn_alive_notify, + .send_tx_power = iwlagn_send_tx_power, + .update_chain_flags = iwl_update_chain_flags, + .set_channel_switch = iwl6000_hw_channel_switch, + .apm_ops = { + .init = iwl_apm_init, + .config = iwl6000_nic_config, + }, + .eeprom_ops = { + .regulatory_bands = { + EEPROM_REG_BAND_1_CHANNELS, + EEPROM_REG_BAND_2_CHANNELS, + EEPROM_REG_BAND_3_CHANNELS, + EEPROM_REG_BAND_4_CHANNELS, + EEPROM_REG_BAND_5_CHANNELS, + EEPROM_6000_REG_BAND_24_HT40_CHANNELS, + EEPROM_REG_BAND_52_HT40_CHANNELS + }, + .acquire_semaphore = iwlcore_eeprom_acquire_semaphore, + .release_semaphore = iwlcore_eeprom_release_semaphore, + .calib_version = iwlagn_eeprom_calib_version, + .query_addr = iwlagn_eeprom_query_addr, + .update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, + }, + .post_associate = iwl_post_associate, + .isr = iwl_isr_ict, + .config_ap = iwl_config_ap, + .temp_ops = { + .temperature = iwlagn_temperature, + }, + .manage_ibss_station = iwlagn_manage_ibss_station, + .update_bcast_stations = iwl_update_bcast_stations, .debugfs_ops = { .rx_stats_read = iwl_ucode_rx_stats_read, .tx_stats_read = iwl_ucode_tx_stats_read, .general_stats_read = iwl_ucode_general_stats_read, .bt_stats_read = iwl_ucode_bt_stats_read, + .reply_tx_error = iwl_reply_tx_error_read, }, .recover_from_tx_stall = iwl_bg_monitor_recover, .check_plcp_health = iwl_good_plcp_health, .check_ack_health = iwl_good_ack_health, .txfifo_flush = iwlagn_txfifo_flush, .dev_txfifo_flush = iwlagn_dev_txfifo_flush, + .tt_ops = { + .lower_power_detection = iwl_tt_is_low_power_state, + .tt_power_mode = iwl_tt_current_power_mode, + .ct_kill_check = iwl_check_for_ct_kill, + } +}; + +static struct iwl_nic_ops iwl6050_nic_ops = { + .additional_nic_config = &iwl6050_additional_nic_config, +}; + +static struct iwl_nic_ops iwl6050g2_nic_ops = { + .additional_nic_config = &iwl6050g2_additional_nic_config, }; static const struct iwl_ops iwl6000_ops = { @@ -339,49 +441,39 @@ static const struct iwl_ops iwl6000_ops = { .led = &iwlagn_led_ops, }; -static void do_not_send_bt_config(struct iwl_priv *priv) -{ -} +static const struct iwl_ops iwl6050_ops = { + .lib = &iwl6000_lib, + .hcmd = &iwlagn_hcmd, + .utils = &iwlagn_hcmd_utils, + .led = &iwlagn_led_ops, + .nic = &iwl6050_nic_ops, +}; -static struct iwl_hcmd_ops iwl6000g2b_hcmd = { - .rxon_assoc = iwlagn_send_rxon_assoc, - .commit_rxon = iwl_commit_rxon, - .set_rxon_chain = iwl_set_rxon_chain, - .set_tx_ant = iwlagn_send_tx_ant_config, - .send_bt_config = do_not_send_bt_config, +static const struct iwl_ops iwl6050g2_ops = { + .lib = &iwl6000_lib, + .hcmd = &iwlagn_hcmd, + .utils = &iwlagn_hcmd_utils, + .led = &iwlagn_led_ops, + .nic = &iwl6050g2_nic_ops, }; static const struct iwl_ops iwl6000g2b_ops = { - .lib = &iwl6000_lib, - .hcmd = &iwl6000g2b_hcmd, + .lib = &iwl6000g2b_lib, + .hcmd = &iwlagn_bt_hcmd, .utils = &iwlagn_hcmd_utils, .led = &iwlagn_led_ops, }; -struct iwl_cfg iwl6000g2a_2agn_cfg = { - .name = "6000 Series 2x2 AGN Gen2a", - .fw_name_pre = IWL6000G2A_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, +static struct iwl_base_params iwl6000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .pll_cfg_val = 0, .set_l0s = true, .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, - .ht_greenfield_support = true, .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, .supports_idle = true, .adv_thermal_throttle = true, @@ -393,29 +485,16 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, - .need_dc_calib = true, }; -struct iwl_cfg iwl6000g2a_2abg_cfg = { - .name = "6000 Series 2x2 ABG Gen2a", - .fw_name_pre = IWL6000G2A_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6000_ops, +static struct iwl_base_params iwl6050_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .pll_cfg_val = 0, .set_l0s = true, .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, + .max_ll_items = OTP_MAX_LL_ITEMS_6x50, .shadow_ram_support = true, .led_compensation = 51, .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, @@ -423,33 +502,20 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { .adv_thermal_throttle = true, .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, + .chain_noise_scale = 1500, .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 512, + .max_event_log_size = 1024, + .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, - .need_dc_calib = true, }; - -struct iwl_cfg iwl6000g2a_2bg_cfg = { - .name = "6000 Series 2x2 BG Gen2a", - .fw_name_pre = IWL6000G2A_FW_PRE, - .ucode_api_max = IWL6000G2_UCODE_API_MAX, - .ucode_api_min = IWL6000G2_UCODE_API_MIN, - .sku = IWL_SKU_G, - .ops = &iwl6000_ops, +static struct iwl_base_params iwl6000_coex_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, - .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, - .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, .num_of_queues = IWLAGN_NUM_QUEUES, .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, - .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, .pll_cfg_val = 0, .set_l0s = true, .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, .max_ll_items = OTP_MAX_LL_ITEMS_6x00, .shadow_ram_support = true, .led_compensation = 51, @@ -459,11 +525,76 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { .support_ct_kill_exit = true, .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, + .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, .max_event_log_size = 512, + .ucode_tracing = true, .sensitivity_calib_by_driver = true, .chain_noise_calib_by_driver = true, +}; + +static struct iwl_ht_params iwl6000_ht_params = { + .ht_greenfield_support = true, + .use_rts_for_aggregation = true, /* use rts/cts protection */ +}; + +static struct iwl_bt_params iwl6000_bt_params = { + .bt_statistics = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .advanced_bt_coexist = true, + .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, + .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, +}; + +struct iwl_cfg iwl6000g2a_2agn_cfg = { + .name = "6000 Series 2x2 AGN Gen2a", + .fw_name_pre = IWL6000G2A_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_base_params, + .ht_params = &iwl6000_ht_params, + .need_dc_calib = true, + .need_temp_offset_calib = true, +}; + +struct iwl_cfg iwl6000g2a_2abg_cfg = { + .name = "6000 Series 2x2 ABG Gen2a", + .fw_name_pre = IWL6000G2A_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_A|IWL_SKU_G, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_base_params, + .need_dc_calib = true, + .need_temp_offset_calib = true, +}; + +struct iwl_cfg iwl6000g2a_2bg_cfg = { + .name = "6000 Series 2x2 BG Gen2a", + .fw_name_pre = IWL6000G2A_FW_PRE, + .ucode_api_max = IWL6000G2_UCODE_API_MAX, + .ucode_api_min = IWL6000G2_UCODE_API_MIN, + .sku = IWL_SKU_G, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_base_params, .need_dc_calib = true, + .need_temp_offset_calib = true, }; struct iwl_cfg iwl6000g2b_2agn_cfg = { @@ -472,36 +603,19 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_coex_base_params, + .bt_params = &iwl6000_bt_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, - .bt_statistics = true, + .need_temp_offset_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; struct iwl_cfg iwl6000g2b_2abg_cfg = { @@ -510,34 +624,18 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_coex_base_params, + .bt_params = &iwl6000_bt_params, .need_dc_calib = true, - .bt_statistics = true, + .need_temp_offset_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; struct iwl_cfg iwl6000g2b_2bgn_cfg = { @@ -546,36 +644,19 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_coex_base_params, + .bt_params = &iwl6000_bt_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, - .bt_statistics = true, + .need_temp_offset_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; struct iwl_cfg iwl6000g2b_2bg_cfg = { @@ -584,34 +665,18 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_coex_base_params, + .bt_params = &iwl6000_bt_params, .need_dc_calib = true, - .bt_statistics = true, + .need_temp_offset_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; struct iwl_cfg iwl6000g2b_bgn_cfg = { @@ -620,36 +685,19 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_coex_base_params, + .bt_params = &iwl6000_bt_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, - .bt_statistics = true, + .need_temp_offset_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; struct iwl_cfg iwl6000g2b_bg_cfg = { @@ -658,34 +706,18 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { .ucode_api_max = IWL6000G2_UCODE_API_MAX, .ucode_api_min = IWL6000G2_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl6000g2b_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000g2b_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, - .max_event_log_size = 512, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_coex_base_params, + .bt_params = &iwl6000_bt_params, .need_dc_calib = true, - .bt_statistics = true, + .need_temp_offset_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; /* @@ -697,35 +729,15 @@ struct iwl_cfg iwl6000i_2agn_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_BC, + .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, + .base_params = &iwl6000_base_params, + .ht_params = &iwl6000_ht_params, .pa_type = IWL_PA_INTERNAL, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; struct iwl_cfg iwl6000i_2abg_cfg = { @@ -734,33 +746,14 @@ struct iwl_cfg iwl6000i_2abg_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_BC, + .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, + .base_params = &iwl6000_base_params, .pa_type = IWL_PA_INTERNAL, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; struct iwl_cfg iwl6000i_2bg_cfg = { @@ -769,33 +762,14 @@ struct iwl_cfg iwl6000i_2bg_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, .sku = IWL_SKU_G, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_BC, + .valid_rx_ant = ANT_BC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_BC, - .valid_rx_ant = ANT_BC, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, + .base_params = &iwl6000_base_params, .pa_type = IWL_PA_INTERNAL, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, }; struct iwl_cfg iwl6050_2agn_cfg = { @@ -804,35 +778,14 @@ struct iwl_cfg iwl6050_2agn_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, + .ops = &iwl6050_ops, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x50, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1500, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6050_base_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, }; @@ -842,35 +795,14 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050G2_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050G2_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6050g2_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_A, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x50, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1500, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6050_base_params, + .ht_params = &iwl6000_ht_params, .need_dc_calib = true, }; @@ -880,33 +812,13 @@ struct iwl_cfg iwl6050_2abg_cfg = { .ucode_api_max = IWL6050_UCODE_API_MAX, .ucode_api_min = IWL6050_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_AB, + .valid_rx_ant = ANT_AB, .eeprom_ver = EEPROM_6050_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6050_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_AB, - .valid_rx_ant = ANT_AB, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x50, - .shadow_ram_support = true, - .led_compensation = 51, - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1500, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6050_base_params, .need_dc_calib = true, }; @@ -916,38 +828,58 @@ struct iwl_cfg iwl6000_3agn_cfg = { .ucode_api_max = IWL6000_UCODE_API_MAX, .ucode_api_min = IWL6000_UCODE_API_MIN, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, - .ops = &iwl6000_ops, - .eeprom_size = OTP_LOW_IMAGE_SIZE, + .valid_tx_ant = ANT_ABC, + .valid_rx_ant = ANT_ABC, .eeprom_ver = EEPROM_6000_EEPROM_VERSION, .eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, - .num_of_queues = IWLAGN_NUM_QUEUES, - .num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES, + .ops = &iwl6000_ops, .mod_params = &iwlagn_mod_params, - .valid_tx_ant = ANT_ABC, - .valid_rx_ant = ANT_ABC, - .pll_cfg_val = 0, - .set_l0s = true, - .use_bsm = false, - .pa_type = IWL_PA_SYSTEM, - .max_ll_items = OTP_MAX_LL_ITEMS_6x00, - .shadow_ram_support = true, - .ht_greenfield_support = true, - .led_compensation = 51, - .use_rts_for_aggregation = true, /* use rts/cts protection */ - .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, - .supports_idle = true, - .adv_thermal_throttle = true, - .support_ct_kill_exit = true, - .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, - .chain_noise_scale = 1000, - .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, - .max_event_log_size = 1024, - .ucode_tracing = true, - .sensitivity_calib_by_driver = true, - .chain_noise_calib_by_driver = true, + .base_params = &iwl6000_base_params, + .ht_params = &iwl6000_ht_params, + .need_dc_calib = true, +}; + +struct iwl_cfg iwl130_bgn_cfg = { + .name = "Intel(R) 130 Series 1x1 BGN", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL130_UCODE_API_MAX, + .ucode_api_min = IWL130_UCODE_API_MIN, + .sku = IWL_SKU_G|IWL_SKU_N, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000g2b_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_coex_base_params, + .bt_params = &iwl6000_bt_params, + .ht_params = &iwl6000_ht_params, + .need_dc_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, +}; + +struct iwl_cfg iwl130_bg_cfg = { + .name = "Intel(R) 130 Series 1x2 BG", + .fw_name_pre = IWL6000G2B_FW_PRE, + .ucode_api_max = IWL130_UCODE_API_MAX, + .ucode_api_min = IWL130_UCODE_API_MIN, + .sku = IWL_SKU_G, + .valid_tx_ant = ANT_A, + .valid_rx_ant = ANT_A, + .eeprom_ver = EEPROM_6000G2_EEPROM_VERSION, + .eeprom_calib_ver = EEPROM_6000G2_TX_POWER_VERSION, + .ops = &iwl6000g2b_ops, + .mod_params = &iwlagn_mod_params, + .base_params = &iwl6000_coex_base_params, + .bt_params = &iwl6000_bt_params, + .need_dc_calib = true, + /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ + .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, }; MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6000G2B_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL130_MODULE_FIRMWARE(IWL130_UCODE_API_MAX)); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index c4c5691032a601a0dcc34e9d7f44fa8f81f1eab2..e2019e756936e2280fa8f1365fe31ca0bb295a51 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -65,7 +65,7 @@ #include "iwl-dev.h" #include "iwl-core.h" -#include "iwl-calib.h" +#include "iwl-agn-calib.h" /***************************************************************************** * INIT calibrations framework @@ -625,13 +625,14 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp) data = &(priv->sensitivity_data); - if (!iwl_is_associated(priv)) { + if (!iwl_is_any_associated(priv)) { IWL_DEBUG_CALIB(priv, "<< - not associated\n"); return; } spin_lock_irqsave(&priv->lock, flags); - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { rx_info = &(((struct iwl_bt_notif_statistics *)resp)-> rx.general.common); ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm); @@ -763,6 +764,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) unsigned long flags; struct statistics_rx_non_phy *rx_info; u8 first_chain; + /* + * MULTI-FIXME: + * When we support multiple interfaces on different channels, + * this must be modified/fixed. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; if (priv->disable_chain_noise_cal) return; @@ -780,7 +787,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) } spin_lock_irqsave(&priv->lock, flags); - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)-> rx.general.common); } else { @@ -793,9 +801,10 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) return; } - rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK); - rxon_chnum = le16_to_cpu(priv->staging_rxon.channel); - if (priv->cfg->bt_statistics) { + rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK); + rxon_chnum = le16_to_cpu(ctx->staging.channel); + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { stat_band24 = !!(((struct iwl_bt_notif_statistics *) stat_resp)->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK); @@ -855,16 +864,17 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) /* If this is the "chain_noise_num_beacons", determine: * 1) Disconnected antennas (using signal strengths) * 2) Differential gain (using silence noise) to balance receivers */ - if (data->beacon_count != priv->cfg->chain_noise_num_beacons) + if (data->beacon_count != + priv->cfg->base_params->chain_noise_num_beacons) return; /* Analyze signal for disconnected antenna */ - average_sig[0] = - (data->chain_signal_a) / priv->cfg->chain_noise_num_beacons; - average_sig[1] = - (data->chain_signal_b) / priv->cfg->chain_noise_num_beacons; - average_sig[2] = - (data->chain_signal_c) / priv->cfg->chain_noise_num_beacons; + average_sig[0] = data->chain_signal_a / + priv->cfg->base_params->chain_noise_num_beacons; + average_sig[1] = data->chain_signal_b / + priv->cfg->base_params->chain_noise_num_beacons; + average_sig[2] = data->chain_signal_c / + priv->cfg->base_params->chain_noise_num_beacons; if (average_sig[0] >= average_sig[1]) { max_average_sig = average_sig[0]; @@ -914,7 +924,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) * To be safe, simply mask out any chains that we know * are not on the device. */ - active_chains &= priv->hw_params.valid_rx_ant; + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + active_chains &= first_antenna(priv->hw_params.valid_rx_ant); + } else + active_chains &= priv->hw_params.valid_rx_ant; num_tx_chains = 0; for (i = 0; i < NUM_RX_CHAINS; i++) { @@ -957,12 +973,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp) active_chains); /* Analyze noise for rx balance */ - average_noise[0] = - ((data->chain_noise_a) / priv->cfg->chain_noise_num_beacons); - average_noise[1] = - ((data->chain_noise_b) / priv->cfg->chain_noise_num_beacons); - average_noise[2] = - ((data->chain_noise_c) / priv->cfg->chain_noise_num_beacons); + average_noise[0] = data->chain_noise_a / + priv->cfg->base_params->chain_noise_num_beacons; + average_noise[1] = data->chain_noise_b / + priv->cfg->base_params->chain_noise_num_beacons; + average_noise[2] = data->chain_noise_c / + priv->cfg->base_params->chain_noise_num_beacons; for (i = 0; i < NUM_RX_CHAINS; i++) { if (!(data->disconn_array[i]) && diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h similarity index 95% rename from drivers/net/wireless/iwlwifi/iwl-calib.h rename to drivers/net/wireless/iwlwifi/iwl-agn-calib.h index ba9523fbb300dcc6974f0a526c4ebe91877b37c9..e37ae72616308f785cf87e8a37d02c3001d83d44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -79,4 +79,8 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv) priv->cfg->ops->utils->chain_noise_reset(priv); } +int iwl_send_calib_results(struct iwl_priv *priv); +int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); +void iwl_calib_free_results(struct iwl_priv *priv); + #endif /* __iwl_calib_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c index d706b8afbe5abd7f54b570d1a414a7f9c3c9aac5..a358d4334a1a356f6cecbe2407359c8829792350 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c @@ -25,15 +25,22 @@ * Intel Linux Wireless * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 *****************************************************************************/ - +#include "iwl-agn.h" #include "iwl-agn-debugfs.h" +static const char *fmt_value = " %-30s %10u\n"; +static const char *fmt_hex = " %-30s 0x%02X\n"; +static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; +static const char *fmt_header = + "%-32s current cumulative delta max\n"; + static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) { int p = 0; u32 flag; - if (priv->cfg->bt_statistics) + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) flag = le32_to_cpu(priv->_agn.statistics_bt.flag); else flag = le32_to_cpu(priv->_agn.statistics.flag); @@ -82,7 +89,8 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { ofdm = &priv->_agn.statistics_bt.rx.ofdm; cck = &priv->_agn.statistics_bt.rx.cck; general = &priv->_agn.statistics_bt.rx.general.common; @@ -121,436 +129,380 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, } pos += iwl_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - OFDM:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_cnt:", le32_to_cpu(ofdm->ina_cnt), + fmt_header, "Statistics_Rx - OFDM:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ina_cnt:", + le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt, delta_ofdm->ina_cnt, max_ofdm->ina_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_cnt:", + fmt_table, "fina_cnt:", le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, delta_ofdm->fina_cnt, max_ofdm->fina_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "plcp_err:", + fmt_table, "plcp_err:", le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, delta_ofdm->plcp_err, max_ofdm->plcp_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "crc32_err:", + fmt_table, "crc32_err:", le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, delta_ofdm->crc32_err, max_ofdm->crc32_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "overrun_err:", + fmt_table, "overrun_err:", le32_to_cpu(ofdm->overrun_err), accum_ofdm->overrun_err, delta_ofdm->overrun_err, max_ofdm->overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", + fmt_table, "early_overrun_err:", le32_to_cpu(ofdm->early_overrun_err), accum_ofdm->early_overrun_err, delta_ofdm->early_overrun_err, max_ofdm->early_overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", le32_to_cpu(ofdm->crc32_good), + fmt_table, "crc32_good:", + le32_to_cpu(ofdm->crc32_good), accum_ofdm->crc32_good, delta_ofdm->crc32_good, max_ofdm->crc32_good); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "false_alarm_cnt:", + fmt_table, "false_alarm_cnt:", le32_to_cpu(ofdm->false_alarm_cnt), accum_ofdm->false_alarm_cnt, delta_ofdm->false_alarm_cnt, max_ofdm->false_alarm_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_sync_err_cnt:", + fmt_table, "fina_sync_err_cnt:", le32_to_cpu(ofdm->fina_sync_err_cnt), accum_ofdm->fina_sync_err_cnt, delta_ofdm->fina_sync_err_cnt, max_ofdm->fina_sync_err_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sfd_timeout:", + fmt_table, "sfd_timeout:", le32_to_cpu(ofdm->sfd_timeout), accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout, max_ofdm->sfd_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "fina_timeout:", + fmt_table, "fina_timeout:", le32_to_cpu(ofdm->fina_timeout), accum_ofdm->fina_timeout, delta_ofdm->fina_timeout, max_ofdm->fina_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unresponded_rts:", + fmt_table, "unresponded_rts:", le32_to_cpu(ofdm->unresponded_rts), accum_ofdm->unresponded_rts, delta_ofdm->unresponded_rts, max_ofdm->unresponded_rts); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rxe_frame_lmt_ovrun:", + fmt_table, "rxe_frame_lmt_ovrun:", le32_to_cpu(ofdm->rxe_frame_limit_overrun), accum_ofdm->rxe_frame_limit_overrun, delta_ofdm->rxe_frame_limit_overrun, max_ofdm->rxe_frame_limit_overrun); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:", + fmt_table, "sent_ack_cnt:", le32_to_cpu(ofdm->sent_ack_cnt), accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt, max_ofdm->sent_ack_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:", + fmt_table, "sent_cts_cnt:", le32_to_cpu(ofdm->sent_cts_cnt), accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt, max_ofdm->sent_cts_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sent_ba_rsp_cnt:", + fmt_table, "sent_ba_rsp_cnt:", le32_to_cpu(ofdm->sent_ba_rsp_cnt), accum_ofdm->sent_ba_rsp_cnt, delta_ofdm->sent_ba_rsp_cnt, max_ofdm->sent_ba_rsp_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:", + fmt_table, "dsp_self_kill:", le32_to_cpu(ofdm->dsp_self_kill), accum_ofdm->dsp_self_kill, delta_ofdm->dsp_self_kill, max_ofdm->dsp_self_kill); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "mh_format_err:", + fmt_table, "mh_format_err:", le32_to_cpu(ofdm->mh_format_err), accum_ofdm->mh_format_err, delta_ofdm->mh_format_err, max_ofdm->mh_format_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "re_acq_main_rssi_sum:", + fmt_table, "re_acq_main_rssi_sum:", le32_to_cpu(ofdm->re_acq_main_rssi_sum), accum_ofdm->re_acq_main_rssi_sum, delta_ofdm->re_acq_main_rssi_sum, max_ofdm->re_acq_main_rssi_sum); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - CCK:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_cnt:", + fmt_header, "Statistics_Rx - CCK:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "ina_cnt:", le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, delta_cck->ina_cnt, max_cck->ina_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_cnt:", + fmt_table, "fina_cnt:", le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, delta_cck->fina_cnt, max_cck->fina_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "plcp_err:", + fmt_table, "plcp_err:", le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, delta_cck->plcp_err, max_cck->plcp_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_err:", + fmt_table, "crc32_err:", le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, delta_cck->crc32_err, max_cck->crc32_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "overrun_err:", + fmt_table, "overrun_err:", le32_to_cpu(cck->overrun_err), accum_cck->overrun_err, delta_cck->overrun_err, max_cck->overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", + fmt_table, "early_overrun_err:", le32_to_cpu(cck->early_overrun_err), accum_cck->early_overrun_err, delta_cck->early_overrun_err, max_cck->early_overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", + fmt_table, "crc32_good:", le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, delta_cck->crc32_good, max_cck->crc32_good); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "false_alarm_cnt:", + fmt_table, "false_alarm_cnt:", le32_to_cpu(cck->false_alarm_cnt), accum_cck->false_alarm_cnt, delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "fina_sync_err_cnt:", + fmt_table, "fina_sync_err_cnt:", le32_to_cpu(cck->fina_sync_err_cnt), accum_cck->fina_sync_err_cnt, delta_cck->fina_sync_err_cnt, max_cck->fina_sync_err_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sfd_timeout:", + fmt_table, "sfd_timeout:", le32_to_cpu(cck->sfd_timeout), accum_cck->sfd_timeout, delta_cck->sfd_timeout, max_cck->sfd_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "fina_timeout:", + fmt_table, "fina_timeout:", le32_to_cpu(cck->fina_timeout), accum_cck->fina_timeout, delta_cck->fina_timeout, max_cck->fina_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unresponded_rts:", + fmt_table, "unresponded_rts:", le32_to_cpu(cck->unresponded_rts), accum_cck->unresponded_rts, delta_cck->unresponded_rts, max_cck->unresponded_rts); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rxe_frame_lmt_ovrun:", + fmt_table, "rxe_frame_lmt_ovrun:", le32_to_cpu(cck->rxe_frame_limit_overrun), accum_cck->rxe_frame_limit_overrun, delta_cck->rxe_frame_limit_overrun, max_cck->rxe_frame_limit_overrun); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_ack_cnt:", + fmt_table, "sent_ack_cnt:", le32_to_cpu(cck->sent_ack_cnt), accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt, max_cck->sent_ack_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_cts_cnt:", + fmt_table, "sent_cts_cnt:", le32_to_cpu(cck->sent_cts_cnt), accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt, max_cck->sent_cts_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "sent_ba_rsp_cnt:", + fmt_table, "sent_ba_rsp_cnt:", le32_to_cpu(cck->sent_ba_rsp_cnt), accum_cck->sent_ba_rsp_cnt, delta_cck->sent_ba_rsp_cnt, max_cck->sent_ba_rsp_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "dsp_self_kill:", + fmt_table, "dsp_self_kill:", le32_to_cpu(cck->dsp_self_kill), accum_cck->dsp_self_kill, delta_cck->dsp_self_kill, max_cck->dsp_self_kill); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "mh_format_err:", + fmt_table, "mh_format_err:", le32_to_cpu(cck->mh_format_err), accum_cck->mh_format_err, delta_cck->mh_format_err, max_cck->mh_format_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "re_acq_main_rssi_sum:", + fmt_table, "re_acq_main_rssi_sum:", le32_to_cpu(cck->re_acq_main_rssi_sum), accum_cck->re_acq_main_rssi_sum, delta_cck->re_acq_main_rssi_sum, max_cck->re_acq_main_rssi_sum); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - GENERAL:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "bogus_cts:", + fmt_header, "Statistics_Rx - GENERAL:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "bogus_cts:", le32_to_cpu(general->bogus_cts), accum_general->bogus_cts, delta_general->bogus_cts, max_general->bogus_cts); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", "bogus_ack:", + fmt_table, "bogus_ack:", le32_to_cpu(general->bogus_ack), accum_general->bogus_ack, delta_general->bogus_ack, max_general->bogus_ack); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "non_bssid_frames:", + fmt_table, "non_bssid_frames:", le32_to_cpu(general->non_bssid_frames), accum_general->non_bssid_frames, delta_general->non_bssid_frames, max_general->non_bssid_frames); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "filtered_frames:", + fmt_table, "filtered_frames:", le32_to_cpu(general->filtered_frames), accum_general->filtered_frames, delta_general->filtered_frames, max_general->filtered_frames); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "non_channel_beacons:", + fmt_table, "non_channel_beacons:", le32_to_cpu(general->non_channel_beacons), accum_general->non_channel_beacons, delta_general->non_channel_beacons, max_general->non_channel_beacons); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "channel_beacons:", + fmt_table, "channel_beacons:", le32_to_cpu(general->channel_beacons), accum_general->channel_beacons, delta_general->channel_beacons, max_general->channel_beacons); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "num_missed_bcon:", + fmt_table, "num_missed_bcon:", le32_to_cpu(general->num_missed_bcon), accum_general->num_missed_bcon, delta_general->num_missed_bcon, max_general->num_missed_bcon); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "adc_rx_saturation_time:", + fmt_table, "adc_rx_saturation_time:", le32_to_cpu(general->adc_rx_saturation_time), accum_general->adc_rx_saturation_time, delta_general->adc_rx_saturation_time, max_general->adc_rx_saturation_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ina_detect_search_tm:", + fmt_table, "ina_detect_search_tm:", le32_to_cpu(general->ina_detection_search_time), accum_general->ina_detection_search_time, delta_general->ina_detection_search_time, max_general->ina_detection_search_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_silence_rssi_a:", + fmt_table, "beacon_silence_rssi_a:", le32_to_cpu(general->beacon_silence_rssi_a), accum_general->beacon_silence_rssi_a, delta_general->beacon_silence_rssi_a, max_general->beacon_silence_rssi_a); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_silence_rssi_b:", + fmt_table, "beacon_silence_rssi_b:", le32_to_cpu(general->beacon_silence_rssi_b), accum_general->beacon_silence_rssi_b, delta_general->beacon_silence_rssi_b, max_general->beacon_silence_rssi_b); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_silence_rssi_c:", + fmt_table, "beacon_silence_rssi_c:", le32_to_cpu(general->beacon_silence_rssi_c), accum_general->beacon_silence_rssi_c, delta_general->beacon_silence_rssi_c, max_general->beacon_silence_rssi_c); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "interference_data_flag:", + fmt_table, "interference_data_flag:", le32_to_cpu(general->interference_data_flag), accum_general->interference_data_flag, delta_general->interference_data_flag, max_general->interference_data_flag); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "channel_load:", + fmt_table, "channel_load:", le32_to_cpu(general->channel_load), accum_general->channel_load, delta_general->channel_load, max_general->channel_load); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "dsp_false_alarms:", + fmt_table, "dsp_false_alarms:", le32_to_cpu(general->dsp_false_alarms), accum_general->dsp_false_alarms, delta_general->dsp_false_alarms, max_general->dsp_false_alarms); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_rssi_a:", + fmt_table, "beacon_rssi_a:", le32_to_cpu(general->beacon_rssi_a), accum_general->beacon_rssi_a, delta_general->beacon_rssi_a, max_general->beacon_rssi_a); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_rssi_b:", + fmt_table, "beacon_rssi_b:", le32_to_cpu(general->beacon_rssi_b), accum_general->beacon_rssi_b, delta_general->beacon_rssi_b, max_general->beacon_rssi_b); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_rssi_c:", + fmt_table, "beacon_rssi_c:", le32_to_cpu(general->beacon_rssi_c), accum_general->beacon_rssi_c, delta_general->beacon_rssi_c, max_general->beacon_rssi_c); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_energy_a:", + fmt_table, "beacon_energy_a:", le32_to_cpu(general->beacon_energy_a), accum_general->beacon_energy_a, delta_general->beacon_energy_a, max_general->beacon_energy_a); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_energy_b:", + fmt_table, "beacon_energy_b:", le32_to_cpu(general->beacon_energy_b), accum_general->beacon_energy_b, delta_general->beacon_energy_b, max_general->beacon_energy_b); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "beacon_energy_c:", + fmt_table, "beacon_energy_c:", le32_to_cpu(general->beacon_energy_c), accum_general->beacon_energy_c, delta_general->beacon_energy_c, max_general->beacon_energy_c); - pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Rx - OFDM_HT:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "plcp_err:", + fmt_header, "Statistics_Rx - OFDM_HT:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "plcp_err:", le32_to_cpu(ht->plcp_err), accum_ht->plcp_err, delta_ht->plcp_err, max_ht->plcp_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "overrun_err:", + fmt_table, "overrun_err:", le32_to_cpu(ht->overrun_err), accum_ht->overrun_err, delta_ht->overrun_err, max_ht->overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "early_overrun_err:", + fmt_table, "early_overrun_err:", le32_to_cpu(ht->early_overrun_err), accum_ht->early_overrun_err, delta_ht->early_overrun_err, max_ht->early_overrun_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_good:", + fmt_table, "crc32_good:", le32_to_cpu(ht->crc32_good), accum_ht->crc32_good, delta_ht->crc32_good, max_ht->crc32_good); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "crc32_err:", + fmt_table, "crc32_err:", le32_to_cpu(ht->crc32_err), accum_ht->crc32_err, delta_ht->crc32_err, max_ht->crc32_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "mh_format_err:", + fmt_table, "mh_format_err:", le32_to_cpu(ht->mh_format_err), accum_ht->mh_format_err, delta_ht->mh_format_err, max_ht->mh_format_err); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg_crc32_good:", + fmt_table, "agg_crc32_good:", le32_to_cpu(ht->agg_crc32_good), accum_ht->agg_crc32_good, delta_ht->agg_crc32_good, max_ht->agg_crc32_good); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg_mpdu_cnt:", + fmt_table, "agg_mpdu_cnt:", le32_to_cpu(ht->agg_mpdu_cnt), accum_ht->agg_mpdu_cnt, delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg_cnt:", + fmt_table, "agg_cnt:", le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt, delta_ht->agg_cnt, max_ht->agg_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "unsupport_mcs:", + fmt_table, "unsupport_mcs:", le32_to_cpu(ht->unsupport_mcs), accum_ht->unsupport_mcs, delta_ht->unsupport_mcs, max_ht->unsupport_mcs); @@ -584,7 +536,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { tx = &priv->_agn.statistics_bt.tx; accum_tx = &priv->_agn.accum_statistics_bt.tx; delta_tx = &priv->_agn.delta_statistics_bt.tx; @@ -597,166 +550,141 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, } pos += iwl_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_Tx:"); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "preamble:", + fmt_header, "Statistics_Tx:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "preamble:", le32_to_cpu(tx->preamble_cnt), accum_tx->preamble_cnt, delta_tx->preamble_cnt, max_tx->preamble_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rx_detected_cnt:", + fmt_table, "rx_detected_cnt:", le32_to_cpu(tx->rx_detected_cnt), accum_tx->rx_detected_cnt, delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bt_prio_defer_cnt:", + fmt_table, "bt_prio_defer_cnt:", le32_to_cpu(tx->bt_prio_defer_cnt), accum_tx->bt_prio_defer_cnt, delta_tx->bt_prio_defer_cnt, max_tx->bt_prio_defer_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "bt_prio_kill_cnt:", + fmt_table, "bt_prio_kill_cnt:", le32_to_cpu(tx->bt_prio_kill_cnt), accum_tx->bt_prio_kill_cnt, delta_tx->bt_prio_kill_cnt, max_tx->bt_prio_kill_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "few_bytes_cnt:", + fmt_table, "few_bytes_cnt:", le32_to_cpu(tx->few_bytes_cnt), accum_tx->few_bytes_cnt, delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "cts_timeout:", + fmt_table, "cts_timeout:", le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, delta_tx->cts_timeout, max_tx->cts_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ack_timeout:", + fmt_table, "ack_timeout:", le32_to_cpu(tx->ack_timeout), accum_tx->ack_timeout, delta_tx->ack_timeout, max_tx->ack_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "expected_ack_cnt:", + fmt_table, "expected_ack_cnt:", le32_to_cpu(tx->expected_ack_cnt), accum_tx->expected_ack_cnt, delta_tx->expected_ack_cnt, max_tx->expected_ack_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "actual_ack_cnt:", + fmt_table, "actual_ack_cnt:", le32_to_cpu(tx->actual_ack_cnt), accum_tx->actual_ack_cnt, delta_tx->actual_ack_cnt, max_tx->actual_ack_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "dump_msdu_cnt:", + fmt_table, "dump_msdu_cnt:", le32_to_cpu(tx->dump_msdu_cnt), accum_tx->dump_msdu_cnt, delta_tx->dump_msdu_cnt, max_tx->dump_msdu_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "abort_nxt_frame_mismatch:", + fmt_table, "abort_nxt_frame_mismatch:", le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), accum_tx->burst_abort_next_frame_mismatch_cnt, delta_tx->burst_abort_next_frame_mismatch_cnt, max_tx->burst_abort_next_frame_mismatch_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "abort_missing_nxt_frame:", + fmt_table, "abort_missing_nxt_frame:", le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), accum_tx->burst_abort_missing_next_frame_cnt, delta_tx->burst_abort_missing_next_frame_cnt, max_tx->burst_abort_missing_next_frame_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "cts_timeout_collision:", + fmt_table, "cts_timeout_collision:", le32_to_cpu(tx->cts_timeout_collision), accum_tx->cts_timeout_collision, delta_tx->cts_timeout_collision, max_tx->cts_timeout_collision); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "ack_ba_timeout_collision:", + fmt_table, "ack_ba_timeout_collision:", le32_to_cpu(tx->ack_or_ba_timeout_collision), accum_tx->ack_or_ba_timeout_collision, delta_tx->ack_or_ba_timeout_collision, max_tx->ack_or_ba_timeout_collision); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg ba_timeout:", + fmt_table, "agg ba_timeout:", le32_to_cpu(tx->agg.ba_timeout), accum_tx->agg.ba_timeout, delta_tx->agg.ba_timeout, max_tx->agg.ba_timeout); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg ba_resched_frames:", + fmt_table, "agg ba_resched_frames:", le32_to_cpu(tx->agg.ba_reschedule_frames), accum_tx->agg.ba_reschedule_frames, delta_tx->agg.ba_reschedule_frames, max_tx->agg.ba_reschedule_frames); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg scd_query_agg_frame:", + fmt_table, "agg scd_query_agg_frame:", le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), accum_tx->agg.scd_query_agg_frame_cnt, delta_tx->agg.scd_query_agg_frame_cnt, max_tx->agg.scd_query_agg_frame_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg scd_query_no_agg:", + fmt_table, "agg scd_query_no_agg:", le32_to_cpu(tx->agg.scd_query_no_agg), accum_tx->agg.scd_query_no_agg, delta_tx->agg.scd_query_no_agg, max_tx->agg.scd_query_no_agg); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg scd_query_agg:", + fmt_table, "agg scd_query_agg:", le32_to_cpu(tx->agg.scd_query_agg), accum_tx->agg.scd_query_agg, delta_tx->agg.scd_query_agg, max_tx->agg.scd_query_agg); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg scd_query_mismatch:", + fmt_table, "agg scd_query_mismatch:", le32_to_cpu(tx->agg.scd_query_mismatch), accum_tx->agg.scd_query_mismatch, delta_tx->agg.scd_query_mismatch, max_tx->agg.scd_query_mismatch); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg frame_not_ready:", + fmt_table, "agg frame_not_ready:", le32_to_cpu(tx->agg.frame_not_ready), accum_tx->agg.frame_not_ready, delta_tx->agg.frame_not_ready, max_tx->agg.frame_not_ready); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg underrun:", + fmt_table, "agg underrun:", le32_to_cpu(tx->agg.underrun), accum_tx->agg.underrun, delta_tx->agg.underrun, max_tx->agg.underrun); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg bt_prio_kill:", + fmt_table, "agg bt_prio_kill:", le32_to_cpu(tx->agg.bt_prio_kill), accum_tx->agg.bt_prio_kill, delta_tx->agg.bt_prio_kill, max_tx->agg.bt_prio_kill); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "agg rx_ba_rsp_cnt:", + fmt_table, "agg rx_ba_rsp_cnt:", le32_to_cpu(tx->agg.rx_ba_rsp_cnt), accum_tx->agg.rx_ba_rsp_cnt, delta_tx->agg.rx_ba_rsp_cnt, @@ -767,15 +695,15 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, "tx power: (1/2 dB step)\n"); if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) pos += scnprintf(buf + pos, bufsz - pos, - "\tantenna A: 0x%X\n", + fmt_hex, "antenna A:", tx->tx_power.ant_a); if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) pos += scnprintf(buf + pos, bufsz - pos, - "\tantenna B: 0x%X\n", + fmt_hex, "antenna B:", tx->tx_power.ant_b); if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) pos += scnprintf(buf + pos, bufsz - pos, - "\tantenna C: 0x%X\n", + fmt_hex, "antenna C:", tx->tx_power.ant_c); } ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); @@ -809,7 +737,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, * the last statistics notification from uCode * might not reflect the current uCode activity */ - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { general = &priv->_agn.statistics_bt.general.common; dbg = &priv->_agn.statistics_bt.general.common.dbg; div = &priv->_agn.statistics_bt.general.common.div; @@ -838,84 +767,72 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, } pos += iwl_statistics_flag(priv, buf, bufsz); - pos += scnprintf(buf + pos, bufsz - pos, "%-32s current" - "acumulative delta max\n", - "Statistics_General:"); - pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n", - "temperature:", + pos += scnprintf(buf + pos, bufsz - pos, + fmt_header, "Statistics_General:"); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_value, "temperature:", le32_to_cpu(general->temperature)); - pos += scnprintf(buf + pos, bufsz - pos, " %-30s %10u\n", - "temperature_m:", + pos += scnprintf(buf + pos, bufsz - pos, + fmt_value, "temperature_m:", le32_to_cpu(general->temperature_m)); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "burst_check:", + fmt_value, "ttl_timestamp:", + le32_to_cpu(general->ttl_timestamp)); + pos += scnprintf(buf + pos, bufsz - pos, + fmt_table, "burst_check:", le32_to_cpu(dbg->burst_check), accum_dbg->burst_check, delta_dbg->burst_check, max_dbg->burst_check); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "burst_count:", + fmt_table, "burst_count:", le32_to_cpu(dbg->burst_count), accum_dbg->burst_count, delta_dbg->burst_count, max_dbg->burst_count); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "wait_for_silence_timeout_count:", + fmt_table, "wait_for_silence_timeout_count:", le32_to_cpu(dbg->wait_for_silence_timeout_cnt), accum_dbg->wait_for_silence_timeout_cnt, delta_dbg->wait_for_silence_timeout_cnt, max_dbg->wait_for_silence_timeout_cnt); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "sleep_time:", + fmt_table, "sleep_time:", le32_to_cpu(general->sleep_time), accum_general->sleep_time, delta_general->sleep_time, max_general->sleep_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "slots_out:", + fmt_table, "slots_out:", le32_to_cpu(general->slots_out), accum_general->slots_out, delta_general->slots_out, max_general->slots_out); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "slots_idle:", + fmt_table, "slots_idle:", le32_to_cpu(general->slots_idle), accum_general->slots_idle, delta_general->slots_idle, max_general->slots_idle); - pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", - le32_to_cpu(general->ttl_timestamp)); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "tx_on_a:", + fmt_table, "tx_on_a:", le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, delta_div->tx_on_a, max_div->tx_on_a); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "tx_on_b:", + fmt_table, "tx_on_b:", le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, delta_div->tx_on_b, max_div->tx_on_b); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "exec_time:", + fmt_table, "exec_time:", le32_to_cpu(div->exec_time), accum_div->exec_time, delta_div->exec_time, max_div->exec_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "probe_time:", + fmt_table, "probe_time:", le32_to_cpu(div->probe_time), accum_div->probe_time, delta_div->probe_time, max_div->probe_time); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "rx_enable_counter:", + fmt_table, "rx_enable_counter:", le32_to_cpu(general->rx_enable_counter), accum_general->rx_enable_counter, delta_general->rx_enable_counter, max_general->rx_enable_counter); pos += scnprintf(buf + pos, bufsz - pos, - " %-30s %10u %10u %10u %10u\n", - "num_of_sos_states:", + fmt_table, "num_of_sos_states:", le32_to_cpu(general->num_of_sos_states), accum_general->num_of_sos_states, delta_general->num_of_sos_states, @@ -1011,3 +928,147 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file, kfree(buf); return ret; } + +ssize_t iwl_reply_tx_error_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + int pos = 0; + char *buf; + int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) + + (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; + ssize_t ret; + + if (!iwl_is_alive(priv)) + return -EAGAIN; + + buf = kzalloc(bufsz, GFP_KERNEL); + if (!buf) { + IWL_ERR(priv, "Can not allocate Buffer\n"); + return -ENOMEM; + } + + pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n"); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY), + priv->_agn.reply_tx_stats.pp_delay); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES), + priv->_agn.reply_tx_stats.pp_few_bytes); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO), + priv->_agn.reply_tx_stats.pp_bt_prio); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD), + priv->_agn.reply_tx_stats.pp_quiet_period); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK), + priv->_agn.reply_tx_stats.pp_calc_ttak); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_tx_fail_reason( + TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY), + priv->_agn.reply_tx_stats.int_crossed_retry); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT), + priv->_agn.reply_tx_stats.short_limit); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT), + priv->_agn.reply_tx_stats.long_limit); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN), + priv->_agn.reply_tx_stats.fifo_underrun); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW), + priv->_agn.reply_tx_stats.drain_flow); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH), + priv->_agn.reply_tx_stats.rfkill_flush); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE), + priv->_agn.reply_tx_stats.life_expire); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS), + priv->_agn.reply_tx_stats.dest_ps); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED), + priv->_agn.reply_tx_stats.host_abort); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY), + priv->_agn.reply_tx_stats.pp_delay); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID), + priv->_agn.reply_tx_stats.sta_invalid); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED), + priv->_agn.reply_tx_stats.frag_drop); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE), + priv->_agn.reply_tx_stats.tid_disable); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED), + priv->_agn.reply_tx_stats.fifo_flush); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_tx_fail_reason( + TX_STATUS_FAIL_INSUFFICIENT_CF_POLL), + priv->_agn.reply_tx_stats.insuff_cf_poll); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX), + priv->_agn.reply_tx_stats.fail_hw_drop); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_tx_fail_reason( + TX_STATUS_FAIL_NO_BEACON_ON_RADAR), + priv->_agn.reply_tx_stats.sta_color_mismatch); + pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", + priv->_agn.reply_tx_stats.unknown); + + pos += scnprintf(buf + pos, bufsz - pos, + "\nStatistics_Agg_TX_Error:\n"); + + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK), + priv->_agn.reply_agg_tx_stats.underrun); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK), + priv->_agn.reply_agg_tx_stats.bt_prio); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK), + priv->_agn.reply_agg_tx_stats.few_bytes); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK), + priv->_agn.reply_agg_tx_stats.abort); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_agg_tx_fail_reason( + AGG_TX_STATE_LAST_SENT_TTL_MSK), + priv->_agn.reply_agg_tx_stats.last_sent_ttl); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_agg_tx_fail_reason( + AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK), + priv->_agn.reply_agg_tx_stats.last_sent_try); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_agg_tx_fail_reason( + AGG_TX_STATE_LAST_SENT_BT_KILL_MSK), + priv->_agn.reply_agg_tx_stats.last_sent_bt_kill); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK), + priv->_agn.reply_agg_tx_stats.scd_query); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", + iwl_get_agg_tx_fail_reason( + AGG_TX_STATE_TEST_BAD_CRC32_MSK), + priv->_agn.reply_agg_tx_stats.bad_crc32); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK), + priv->_agn.reply_agg_tx_stats.response); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK), + priv->_agn.reply_agg_tx_stats.dump_tx); + pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", + iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK), + priv->_agn.reply_agg_tx_stats.delay_tx); + pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", + priv->_agn.reply_agg_tx_stats.unknown); + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + kfree(buf); + return ret; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h index bbdce5913ac77a51d52fb02cbef8a587287b6b8e..f2573b5486cd20bc958367c33cf0a9e577ba643a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h @@ -39,6 +39,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); +ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); #else static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -60,4 +62,9 @@ static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, { return 0; } +static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + return 0; +} #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c new file mode 100644 index 0000000000000000000000000000000000000000..a650baba0809d1bf1d56d86f687f7dc07cf53d1b --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c @@ -0,0 +1,454 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + + +#include +#include +#include +#include + +#include + +#include "iwl-commands.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-debug.h" +#include "iwl-agn.h" +#include "iwl-io.h" + +/************************** EEPROM BANDS **************************** + * + * The iwl_eeprom_band definitions below provide the mapping from the + * EEPROM contents to the specific channel number supported for each + * band. + * + * For example, iwl_priv->eeprom.band_3_channels[4] from the band_3 + * definition below maps to physical channel 42 in the 5.2GHz spectrum. + * The specific geography and calibration information for that channel + * is contained in the eeprom map itself. + * + * During init, we copy the eeprom information and channel map + * information into priv->channel_info_24/52 and priv->channel_map_24/52 + * + * channel_map_24/52 provides the index in the channel_info array for a + * given channel. We have to have two separate maps as there is channel + * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and + * band_2 + * + * A value of 0xff stored in the channel_map indicates that the channel + * is not supported by the hardware at all. + * + * A value of 0xfe in the channel_map indicates that the channel is not + * valid for Tx with the current hardware. This means that + * while the system can tune and receive on a given channel, it may not + * be able to associate or transmit any frames on that + * channel. There is no corresponding channel information for that + * entry. + * + *********************************************************************/ + +/** + * struct iwl_txpwr_section: eeprom section information + * @offset: indirect address into eeprom image + * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section + * @band: band type for the section + * @is_common - true: common section, false: channel section + * @is_cck - true: cck section, false: not cck section + * @is_ht_40 - true: all channel in the section are HT40 channel, + * false: legacy or HT 20 MHz + * ignore if it is common section + * @iwl_eeprom_section_channel: channel array in the section, + * ignore if common section + */ +struct iwl_txpwr_section { + u32 offset; + u8 count; + enum ieee80211_band band; + bool is_common; + bool is_cck; + bool is_ht40; + u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS]; +}; + +/** + * section 1 - 3 are regulatory tx power apply to all channels based on + * modulation: CCK, OFDM + * Band: 2.4GHz, 5.2GHz + * section 4 - 10 are regulatory tx power apply to specified channels + * For example: + * 1L - Channel 1 Legacy + * 1HT - Channel 1 HT + * (1,+1) - Channel 1 HT40 "_above_" + * + * Section 1: all CCK channels + * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels + * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels + * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT + * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) + * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT + * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1) + * Section 8: 2.4 GHz channel: 13L, 13HT + * Section 9: 2.4 GHz channel: 140L, 140HT + * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1) + * + */ +static const struct iwl_txpwr_section enhinfo[] = { + { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false }, + { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false }, + { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false }, + { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ, + false, false, false, + {1, 1, 2, 2, 10, 10, 11, 11 } }, + { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ, + false, false, true, + { 1, 2, 6, 7, 9 } }, + { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ, + false, false, false, + { 36, 64, 100, 36, 64, 100 } }, + { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ, + false, false, true, + { 36, 60, 100 } }, + { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ, + false, false, false, + { 13, 13 } }, + { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ, + false, false, false, + { 140, 140 } }, + { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ, + false, false, true, + { 132, 44 } }, +}; + +/****************************************************************************** + * + * EEPROM related functions + * +******************************************************************************/ + +/* + * The device's EEPROM semaphore prevents conflicts between driver and uCode + * when accessing the EEPROM; each access is a series of pulses to/from the + * EEPROM chip, not a single event, so even reads could conflict if they + * weren't arbitrated by the semaphore. + */ +int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) +{ + u16 count; + int ret; + + for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { + /* Request semaphore */ + iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); + + /* See if we got it */ + ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, + EEPROM_SEM_TIMEOUT); + if (ret >= 0) { + IWL_DEBUG_IO(priv, + "Acquired semaphore after %d tries.\n", + count+1); + return ret; + } + } + + return ret; +} + +void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv) +{ + iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); + +} + +int iwl_eeprom_check_version(struct iwl_priv *priv) +{ + u16 eeprom_ver; + u16 calib_ver; + + eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); + calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv); + + if (eeprom_ver < priv->cfg->eeprom_ver || + calib_ver < priv->cfg->eeprom_calib_ver) + goto err; + + IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", + eeprom_ver, calib_ver); + + return 0; +err: + IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x " + "CALIB=0x%x < 0x%x\n", + eeprom_ver, priv->cfg->eeprom_ver, + calib_ver, priv->cfg->eeprom_calib_ver); + return -EINVAL; + +} + +void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) +{ + const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, + EEPROM_MAC_ADDRESS); + memcpy(mac, addr, ETH_ALEN); +} + +/** + * iwl_get_max_txpower_avg - get the highest tx power from all chains. + * find the highest tx power from all chains for the channel + */ +static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, + int element, s8 *max_txpower_in_half_dbm) +{ + s8 max_txpower_avg = 0; /* (dBm) */ + + IWL_DEBUG_INFO(priv, "%d - " + "chain_a: %d dB chain_b: %d dB " + "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n", + element, + enhanced_txpower[element].chain_a_max >> 1, + enhanced_txpower[element].chain_b_max >> 1, + enhanced_txpower[element].chain_c_max >> 1, + enhanced_txpower[element].mimo2_max >> 1, + enhanced_txpower[element].mimo3_max >> 1); + /* Take the highest tx power from any valid chains */ + if ((priv->cfg->valid_tx_ant & ANT_A) && + (enhanced_txpower[element].chain_a_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_a_max; + if ((priv->cfg->valid_tx_ant & ANT_B) && + (enhanced_txpower[element].chain_b_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_b_max; + if ((priv->cfg->valid_tx_ant & ANT_C) && + (enhanced_txpower[element].chain_c_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].chain_c_max; + if (((priv->cfg->valid_tx_ant == ANT_AB) | + (priv->cfg->valid_tx_ant == ANT_BC) | + (priv->cfg->valid_tx_ant == ANT_AC)) && + (enhanced_txpower[element].mimo2_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].mimo2_max; + if ((priv->cfg->valid_tx_ant == ANT_ABC) && + (enhanced_txpower[element].mimo3_max > max_txpower_avg)) + max_txpower_avg = enhanced_txpower[element].mimo3_max; + + /* + * max. tx power in EEPROM is in 1/2 dBm format + * convert from 1/2 dBm to dBm (round-up convert) + * but we also do not want to loss 1/2 dBm resolution which + * will impact performance + */ + *max_txpower_in_half_dbm = max_txpower_avg; + return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); +} + +/** + * iwl_update_common_txpower: update channel tx power + * update tx power per band based on EEPROM enhanced tx power info. + */ +static s8 iwl_update_common_txpower(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, + int section, int element, s8 *max_txpower_in_half_dbm) +{ + struct iwl_channel_info *ch_info; + int ch; + bool is_ht40 = false; + s8 max_txpower_avg; /* (dBm) */ + + /* it is common section, contain all type (Legacy, HT and HT40) + * based on the element in the section to determine + * is it HT 40 or not + */ + if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX) + is_ht40 = true; + max_txpower_avg = + iwl_get_max_txpower_avg(priv, enhanced_txpower, + element, max_txpower_in_half_dbm); + + ch_info = priv->channel_info; + + for (ch = 0; ch < priv->channel_count; ch++) { + /* find matching band and update tx power if needed */ + if ((ch_info->band == enhinfo[section].band) && + (ch_info->max_power_avg < max_txpower_avg) && + (!is_ht40)) { + /* Update regulatory-based run-time data */ + ch_info->max_power_avg = ch_info->curr_txpow = + max_txpower_avg; + ch_info->scan_power = max_txpower_avg; + } + if ((ch_info->band == enhinfo[section].band) && is_ht40 && + (ch_info->ht40_max_power_avg < max_txpower_avg)) { + /* Update regulatory-based run-time data */ + ch_info->ht40_max_power_avg = max_txpower_avg; + } + ch_info++; + } + return max_txpower_avg; +} + +/** + * iwl_update_channel_txpower: update channel tx power + * update channel tx power based on EEPROM enhanced tx power info. + */ +static s8 iwl_update_channel_txpower(struct iwl_priv *priv, + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, + int section, int element, s8 *max_txpower_in_half_dbm) +{ + struct iwl_channel_info *ch_info; + int ch; + u8 channel; + s8 max_txpower_avg; /* (dBm) */ + + channel = enhinfo[section].iwl_eeprom_section_channel[element]; + max_txpower_avg = + iwl_get_max_txpower_avg(priv, enhanced_txpower, + element, max_txpower_in_half_dbm); + + ch_info = priv->channel_info; + for (ch = 0; ch < priv->channel_count; ch++) { + /* find matching channel and update tx power if needed */ + if (ch_info->channel == channel) { + if ((ch_info->max_power_avg < max_txpower_avg) && + (!enhinfo[section].is_ht40)) { + /* Update regulatory-based run-time data */ + ch_info->max_power_avg = max_txpower_avg; + ch_info->curr_txpow = max_txpower_avg; + ch_info->scan_power = max_txpower_avg; + } + if ((enhinfo[section].is_ht40) && + (ch_info->ht40_max_power_avg < max_txpower_avg)) { + /* Update regulatory-based run-time data */ + ch_info->ht40_max_power_avg = max_txpower_avg; + } + break; + } + ch_info++; + } + return max_txpower_avg; +} + +/** + * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info + */ +void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) +{ + int eeprom_section_count = 0; + int section, element; + struct iwl_eeprom_enhanced_txpwr *enhanced_txpower; + u32 offset; + s8 max_txpower_avg; /* (dBm) */ + s8 max_txpower_in_half_dbm; /* (half-dBm) */ + + /* Loop through all the sections + * adjust bands and channel's max tx power + * Set the tx_power_user_lmt to the highest power + * supported by any channels and chains + */ + for (section = 0; section < ARRAY_SIZE(enhinfo); section++) { + eeprom_section_count = enhinfo[section].count; + offset = enhinfo[section].offset; + enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *) + iwl_eeprom_query_addr(priv, offset); + + /* + * check for valid entry - + * different version of EEPROM might contain different set + * of enhanced tx power table + * always check for valid entry before process + * the information + */ + if (!enhanced_txpower->common || enhanced_txpower->reserved) + continue; + + for (element = 0; element < eeprom_section_count; element++) { + if (enhinfo[section].is_common) + max_txpower_avg = + iwl_update_common_txpower(priv, + enhanced_txpower, section, + element, + &max_txpower_in_half_dbm); + else + max_txpower_avg = + iwl_update_channel_txpower(priv, + enhanced_txpower, section, + element, + &max_txpower_in_half_dbm); + + /* Update the tx_power_user_lmt to the highest power + * supported by any channel */ + if (max_txpower_avg > priv->tx_power_user_lmt) + priv->tx_power_user_lmt = max_txpower_avg; + + /* + * Update the tx_power_lmt_in_half_dbm to + * the highest power supported by any channel + */ + if (max_txpower_in_half_dbm > + priv->tx_power_lmt_in_half_dbm) + priv->tx_power_lmt_in_half_dbm = + max_txpower_in_half_dbm; + } + } +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index 75b901b3eb1ebff8cb5a7adbbd380db5cd8bc88f..ffb2f4111ad0bbbec4db0b19c7edd74425a8d476 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c @@ -37,12 +37,13 @@ #include "iwl-io.h" #include "iwl-agn.h" -int iwlagn_send_rxon_assoc(struct iwl_priv *priv) +int iwlagn_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int ret = 0; struct iwl5000_rxon_assoc_cmd rxon_assoc; - const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; - const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; + const struct iwl_rxon_cmd *rxon1 = &ctx->staging; + const struct iwl_rxon_cmd *rxon2 = &ctx->active; if ((rxon1->flags == rxon2->flags) && (rxon1->filter_flags == rxon2->filter_flags) && @@ -60,23 +61,23 @@ int iwlagn_send_rxon_assoc(struct iwl_priv *priv) return 0; } - rxon_assoc.flags = priv->staging_rxon.flags; - rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; - rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; - rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; + rxon_assoc.flags = ctx->staging.flags; + rxon_assoc.filter_flags = ctx->staging.filter_flags; + rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; + rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; rxon_assoc.reserved1 = 0; rxon_assoc.reserved2 = 0; rxon_assoc.reserved3 = 0; rxon_assoc.ofdm_ht_single_stream_basic_rates = - priv->staging_rxon.ofdm_ht_single_stream_basic_rates; + ctx->staging.ofdm_ht_single_stream_basic_rates; rxon_assoc.ofdm_ht_dual_stream_basic_rates = - priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; - rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; + ctx->staging.ofdm_ht_dual_stream_basic_rates; + rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; rxon_assoc.ofdm_ht_triple_stream_basic_rates = - priv->staging_rxon.ofdm_ht_triple_stream_basic_rates; - rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data; + ctx->staging.ofdm_ht_triple_stream_basic_rates; + rxon_assoc.acquisition_data = ctx->staging.acquisition_data; - ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, + ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, sizeof(rxon_assoc), &rxon_assoc, NULL); if (ret) return ret; @@ -136,7 +137,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv, continue; } - delta_g = (priv->cfg->chain_noise_scale * + delta_g = (priv->cfg->base_params->chain_noise_scale * ((s32)average_noise[default_chain] - (s32)average_noise[i])) / 1500; @@ -184,7 +185,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv) int ret; if ((data->state == IWL_CHAIN_NOISE_ALIVE) && - iwl_is_associated(priv)) { + iwl_is_any_associated(priv)) { struct iwl_calib_chain_noise_reset_cmd cmd; /* clear data for chain noise calibration algorithm */ @@ -221,7 +222,8 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, return; } - if (priv->cfg->use_rts_for_aggregation && + if (priv->cfg->ht_params && + priv->cfg->ht_params->use_rts_for_aggregation && info->flags & IEEE80211_TX_CTL_AMPDU) { *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; return; @@ -235,13 +237,13 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, /* data from PHY/DSP regarding signal strength, etc., * contents are always there, not configurable by host */ - struct iwl5000_non_cfg_phy *ncphy = - (struct iwl5000_non_cfg_phy *)rx_resp->non_cfg_phy_buf; + struct iwlagn_non_cfg_phy *ncphy = + (struct iwlagn_non_cfg_phy *)rx_resp->non_cfg_phy_buf; u32 val, rssi_a, rssi_b, rssi_c, max_rssi; u8 agc; - val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_AGC_IDX]); - agc = (val & IWL50_OFDM_AGC_MSK) >> IWL50_OFDM_AGC_BIT_POS; + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_AGC_IDX]); + agc = (val & IWLAGN_OFDM_AGC_MSK) >> IWLAGN_OFDM_AGC_BIT_POS; /* Find max rssi among 3 possible receivers. * These values are measured by the digital signal processor (DSP). @@ -249,11 +251,14 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, * if the radio's automatic gain control (AGC) is working right. * AGC value (see below) will provide the "interesting" info. */ - val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_AB_IDX]); - rssi_a = (val & IWL50_OFDM_RSSI_A_MSK) >> IWL50_OFDM_RSSI_A_BIT_POS; - rssi_b = (val & IWL50_OFDM_RSSI_B_MSK) >> IWL50_OFDM_RSSI_B_BIT_POS; - val = le32_to_cpu(ncphy->non_cfg_phy[IWL50_RX_RES_RSSI_C_IDX]); - rssi_c = (val & IWL50_OFDM_RSSI_C_MSK) >> IWL50_OFDM_RSSI_C_BIT_POS; + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_AB_IDX]); + rssi_a = (val & IWLAGN_OFDM_RSSI_INBAND_A_BITMSK) >> + IWLAGN_OFDM_RSSI_A_BIT_POS; + rssi_b = (val & IWLAGN_OFDM_RSSI_INBAND_B_BITMSK) >> + IWLAGN_OFDM_RSSI_B_BIT_POS; + val = le32_to_cpu(ncphy->non_cfg_phy[IWLAGN_RX_RES_RSSI_C_IDX]); + rssi_c = (val & IWLAGN_OFDM_RSSI_INBAND_C_BITMSK) >> + IWLAGN_OFDM_RSSI_C_BIT_POS; max_rssi = max_t(u32, rssi_a, rssi_b); max_rssi = max_t(u32, max_rssi, rssi_c); @@ -266,12 +271,109 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, return max_rssi - agc - IWLAGN_RSSI_OFFSET; } +static int iwlagn_set_pan_params(struct iwl_priv *priv) +{ + struct iwl_wipan_params_cmd cmd; + struct iwl_rxon_context *ctx_bss, *ctx_pan; + int slot0 = 300, slot1 = 0; + int ret; + + if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS)) + return 0; + + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); + + lockdep_assert_held(&priv->mutex); + + ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS]; + ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN]; + + /* + * If the PAN context is inactive, then we don't need + * to update the PAN parameters, the last thing we'll + * have done before it goes inactive is making the PAN + * parameters be WLAN-only. + */ + if (!ctx_pan->is_active) + return 0; + + memset(&cmd, 0, sizeof(cmd)); + + /* only 2 slots are currently allowed */ + cmd.num_slots = 2; + + cmd.slots[0].type = 0; /* BSS */ + cmd.slots[1].type = 1; /* PAN */ + + if (ctx_bss->vif && ctx_pan->vif) { + int bcnint = ctx_pan->vif->bss_conf.beacon_int; + + /* should be set, but seems unused?? */ + cmd.flags |= cpu_to_le16(IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE); + + if (ctx_pan->vif->type == NL80211_IFTYPE_AP && + bcnint && + bcnint != ctx_bss->vif->bss_conf.beacon_int) { + IWL_ERR(priv, + "beacon intervals don't match (%d, %d)\n", + ctx_bss->vif->bss_conf.beacon_int, + ctx_pan->vif->bss_conf.beacon_int); + } else + bcnint = max_t(int, bcnint, + ctx_bss->vif->bss_conf.beacon_int); + if (!bcnint) + bcnint = DEFAULT_BEACON_INTERVAL; + slot0 = bcnint / 2; + slot1 = bcnint - slot0; + + if (test_bit(STATUS_SCAN_HW, &priv->status) || + (!ctx_bss->vif->bss_conf.idle && + !ctx_bss->vif->bss_conf.assoc)) { + slot0 = bcnint * 3 - 20; + slot1 = 20; + } else if (!ctx_pan->vif->bss_conf.idle && + !ctx_pan->vif->bss_conf.assoc) { + slot1 = bcnint * 3 - 20; + slot0 = 20; + } + } else if (ctx_pan->vif) { + slot0 = 0; + slot1 = max_t(int, 1, ctx_pan->vif->bss_conf.dtim_period) * + ctx_pan->vif->bss_conf.beacon_int; + slot1 = max_t(int, DEFAULT_BEACON_INTERVAL, slot1); + + if (test_bit(STATUS_SCAN_HW, &priv->status)) { + slot0 = slot1 * 3 - 20; + slot1 = 20; + } + } + + cmd.slots[0].width = cpu_to_le16(slot0); + cmd.slots[1].width = cpu_to_le16(slot1); + + ret = iwl_send_cmd_pdu(priv, REPLY_WIPAN_PARAMS, sizeof(cmd), &cmd); + if (ret) + IWL_ERR(priv, "Error setting PAN parameters (%d)\n", ret); + + return ret; +} + struct iwl_hcmd_ops iwlagn_hcmd = { .rxon_assoc = iwlagn_send_rxon_assoc, - .commit_rxon = iwl_commit_rxon, - .set_rxon_chain = iwl_set_rxon_chain, + .commit_rxon = iwlagn_commit_rxon, + .set_rxon_chain = iwlagn_set_rxon_chain, .set_tx_ant = iwlagn_send_tx_ant_config, .send_bt_config = iwl_send_bt_config, + .set_pan_params = iwlagn_set_pan_params, +}; + +struct iwl_hcmd_ops iwlagn_bt_hcmd = { + .rxon_assoc = iwlagn_send_rxon_assoc, + .commit_rxon = iwlagn_commit_rxon, + .set_rxon_chain = iwlagn_set_rxon_chain, + .set_tx_ant = iwlagn_send_tx_ant_config, + .send_bt_config = iwlagn_send_advance_bt_config, + .set_pan_params = iwlagn_set_pan_params, }; struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { @@ -282,4 +384,5 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { .tx_cmd_protection = iwlagn_tx_cmd_protection, .calc_rssi = iwlagn_calc_rssi, .request_scan = iwlagn_request_scan, + .post_scan = iwlagn_post_scan, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c index c92b2c0cbd9130ee1ba35a1ac160dfd5f0baa0ca..a5dbfea1bfade7da2f53e04c3f9c2c36a681a808 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ict.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ict.c @@ -59,7 +59,7 @@ void iwl_free_isr_ict(struct iwl_priv *priv) int iwl_alloc_isr_ict(struct iwl_priv *priv) { - if (priv->cfg->use_isr_legacy) + if (priv->cfg->base_params->use_isr_legacy) return 0; /* allocate shrared data table */ priv->_agn.ict_tbl_vir = diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 8fd00a6e512019075e966a038d2c5d09539ccf85..b555edd533547e3bf98eed8e948a276ef141aace 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -40,22 +40,195 @@ #include "iwl-agn.h" #include "iwl-sta.h" -static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) +static inline u32 iwlagn_get_scd_ssn(struct iwlagn_tx_resp *tx_resp) { return le32_to_cpup((__le32 *)&tx_resp->status + tx_resp->frame_count) & MAX_SN; } +static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) +{ + status &= TX_STATUS_MSK; + + switch (status) { + case TX_STATUS_POSTPONE_DELAY: + priv->_agn.reply_tx_stats.pp_delay++; + break; + case TX_STATUS_POSTPONE_FEW_BYTES: + priv->_agn.reply_tx_stats.pp_few_bytes++; + break; + case TX_STATUS_POSTPONE_BT_PRIO: + priv->_agn.reply_tx_stats.pp_bt_prio++; + break; + case TX_STATUS_POSTPONE_QUIET_PERIOD: + priv->_agn.reply_tx_stats.pp_quiet_period++; + break; + case TX_STATUS_POSTPONE_CALC_TTAK: + priv->_agn.reply_tx_stats.pp_calc_ttak++; + break; + case TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY: + priv->_agn.reply_tx_stats.int_crossed_retry++; + break; + case TX_STATUS_FAIL_SHORT_LIMIT: + priv->_agn.reply_tx_stats.short_limit++; + break; + case TX_STATUS_FAIL_LONG_LIMIT: + priv->_agn.reply_tx_stats.long_limit++; + break; + case TX_STATUS_FAIL_FIFO_UNDERRUN: + priv->_agn.reply_tx_stats.fifo_underrun++; + break; + case TX_STATUS_FAIL_DRAIN_FLOW: + priv->_agn.reply_tx_stats.drain_flow++; + break; + case TX_STATUS_FAIL_RFKILL_FLUSH: + priv->_agn.reply_tx_stats.rfkill_flush++; + break; + case TX_STATUS_FAIL_LIFE_EXPIRE: + priv->_agn.reply_tx_stats.life_expire++; + break; + case TX_STATUS_FAIL_DEST_PS: + priv->_agn.reply_tx_stats.dest_ps++; + break; + case TX_STATUS_FAIL_HOST_ABORTED: + priv->_agn.reply_tx_stats.host_abort++; + break; + case TX_STATUS_FAIL_BT_RETRY: + priv->_agn.reply_tx_stats.bt_retry++; + break; + case TX_STATUS_FAIL_STA_INVALID: + priv->_agn.reply_tx_stats.sta_invalid++; + break; + case TX_STATUS_FAIL_FRAG_DROPPED: + priv->_agn.reply_tx_stats.frag_drop++; + break; + case TX_STATUS_FAIL_TID_DISABLE: + priv->_agn.reply_tx_stats.tid_disable++; + break; + case TX_STATUS_FAIL_FIFO_FLUSHED: + priv->_agn.reply_tx_stats.fifo_flush++; + break; + case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL: + priv->_agn.reply_tx_stats.insuff_cf_poll++; + break; + case TX_STATUS_FAIL_PASSIVE_NO_RX: + priv->_agn.reply_tx_stats.fail_hw_drop++; + break; + case TX_STATUS_FAIL_NO_BEACON_ON_RADAR: + priv->_agn.reply_tx_stats.sta_color_mismatch++; + break; + default: + priv->_agn.reply_tx_stats.unknown++; + break; + } +} + +static void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status) +{ + status &= AGG_TX_STATUS_MSK; + + switch (status) { + case AGG_TX_STATE_UNDERRUN_MSK: + priv->_agn.reply_agg_tx_stats.underrun++; + break; + case AGG_TX_STATE_BT_PRIO_MSK: + priv->_agn.reply_agg_tx_stats.bt_prio++; + break; + case AGG_TX_STATE_FEW_BYTES_MSK: + priv->_agn.reply_agg_tx_stats.few_bytes++; + break; + case AGG_TX_STATE_ABORT_MSK: + priv->_agn.reply_agg_tx_stats.abort++; + break; + case AGG_TX_STATE_LAST_SENT_TTL_MSK: + priv->_agn.reply_agg_tx_stats.last_sent_ttl++; + break; + case AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK: + priv->_agn.reply_agg_tx_stats.last_sent_try++; + break; + case AGG_TX_STATE_LAST_SENT_BT_KILL_MSK: + priv->_agn.reply_agg_tx_stats.last_sent_bt_kill++; + break; + case AGG_TX_STATE_SCD_QUERY_MSK: + priv->_agn.reply_agg_tx_stats.scd_query++; + break; + case AGG_TX_STATE_TEST_BAD_CRC32_MSK: + priv->_agn.reply_agg_tx_stats.bad_crc32++; + break; + case AGG_TX_STATE_RESPONSE_MSK: + priv->_agn.reply_agg_tx_stats.response++; + break; + case AGG_TX_STATE_DUMP_TX_MSK: + priv->_agn.reply_agg_tx_stats.dump_tx++; + break; + case AGG_TX_STATE_DELAY_TX_MSK: + priv->_agn.reply_agg_tx_stats.delay_tx++; + break; + default: + priv->_agn.reply_agg_tx_stats.unknown++; + break; + } +} + +static void iwlagn_set_tx_status(struct iwl_priv *priv, + struct ieee80211_tx_info *info, + struct iwlagn_tx_resp *tx_resp, + int txq_id, bool is_agg) +{ + u16 status = le16_to_cpu(tx_resp->status.status); + + info->status.rates[0].count = tx_resp->failure_frame + 1; + if (is_agg) + info->flags &= ~IEEE80211_TX_CTL_AMPDU; + info->flags |= iwl_tx_status_to_mac80211(status); + iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), + info); + if (!iwl_is_tx_success(status)) + iwlagn_count_tx_err_status(priv, status); + + IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " + "0x%x retries %d\n", + txq_id, + iwl_get_tx_fail_reason(status), status, + le32_to_cpu(tx_resp->rate_n_flags), + tx_resp->failure_frame); +} + +#ifdef CONFIG_IWLWIFI_DEBUG +#define AGG_TX_STATE_FAIL(x) case AGG_TX_STATE_ ## x: return #x + +const char *iwl_get_agg_tx_fail_reason(u16 status) +{ + status &= AGG_TX_STATUS_MSK; + switch (status) { + case AGG_TX_STATE_TRANSMITTED: + return "SUCCESS"; + AGG_TX_STATE_FAIL(UNDERRUN_MSK); + AGG_TX_STATE_FAIL(BT_PRIO_MSK); + AGG_TX_STATE_FAIL(FEW_BYTES_MSK); + AGG_TX_STATE_FAIL(ABORT_MSK); + AGG_TX_STATE_FAIL(LAST_SENT_TTL_MSK); + AGG_TX_STATE_FAIL(LAST_SENT_TRY_CNT_MSK); + AGG_TX_STATE_FAIL(LAST_SENT_BT_KILL_MSK); + AGG_TX_STATE_FAIL(SCD_QUERY_MSK); + AGG_TX_STATE_FAIL(TEST_BAD_CRC32_MSK); + AGG_TX_STATE_FAIL(RESPONSE_MSK); + AGG_TX_STATE_FAIL(DUMP_TX_MSK); + AGG_TX_STATE_FAIL(DELAY_TX_MSK); + } + + return "UNKNOWN"; +} +#endif /* CONFIG_IWLWIFI_DEBUG */ + static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, struct iwl_ht_agg *agg, - struct iwl5000_tx_resp *tx_resp, + struct iwlagn_tx_resp *tx_resp, int txq_id, u16 start_idx) { u16 status; struct agg_tx_status *frame_status = &tx_resp->status; - struct ieee80211_tx_info *info = NULL; struct ieee80211_hdr *hdr = NULL; - u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); int i, sh, idx; u16 seq; @@ -64,31 +237,20 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, agg->frame_count = tx_resp->frame_count; agg->start_idx = start_idx; - agg->rate_n_flags = rate_n_flags; + agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); agg->bitmap = 0; /* # frames attempted by Tx command */ if (agg->frame_count == 1) { /* Only one frame was attempted; no block-ack will arrive */ - status = le16_to_cpu(frame_status[0].status); idx = start_idx; - /* FIXME: code repetition */ IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n", agg->frame_count, agg->start_idx, idx); - - info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb); - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags &= ~IEEE80211_TX_CTL_AMPDU; - info->flags |= iwl_tx_status_to_mac80211(status); - iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info); - - /* FIXME: code repetition end */ - - IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n", - status & 0xff, tx_resp->failure_frame); - IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags); - + iwlagn_set_tx_status(priv, + IEEE80211_SKB_CB( + priv->txq[txq_id].txb[idx].skb), + tx_resp, txq_id, true); agg->wait_for_ba = 0; } else { /* Two or more frames were attempted; expect block-ack */ @@ -109,12 +271,20 @@ static int iwlagn_tx_status_reply_tx(struct iwl_priv *priv, idx = SEQ_TO_INDEX(seq); txq_id = SEQ_TO_QUEUE(seq); + if (status & AGG_TX_STATUS_MSK) + iwlagn_count_agg_tx_err_status(priv, status); + if (status & (AGG_TX_STATE_FEW_BYTES_MSK | AGG_TX_STATE_ABORT_MSK)) continue; IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n", agg->frame_count, txq_id, idx); + IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), " + "try-count (0x%08x)\n", + iwl_get_agg_tx_fail_reason(status), + status & AGG_TX_STATUS_MSK, + status & AGG_TX_TRY_MSK); hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx); if (!hdr) { @@ -220,7 +390,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, int index = SEQ_TO_INDEX(sequence); struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct ieee80211_tx_info *info; - struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; + struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; u32 status = le16_to_cpu(tx_resp->status.status); int tid; int sta_id; @@ -238,8 +408,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb); memset(&info->status, 0, sizeof(info->status)); - tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; - sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; + tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >> + IWLAGN_TX_RES_TID_POS; + sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> + IWLAGN_TX_RES_RA_POS; spin_lock_irqsave(&priv->sta_lock, flags); if (txq->sched_retry) { @@ -247,7 +419,15 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_ht_agg *agg; agg = &priv->stations[sta_id].tid[tid].agg; - + /* + * If the BT kill count is non-zero, we'll get this + * notification again. + */ + if (tx_resp->bt_kill_count && tx_resp->frame_count == 1 && + priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + IWL_WARN(priv, "receive reply tx with bt_kill\n"); + } iwlagn_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); /* check if BAR is needed */ @@ -274,20 +454,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, } } else { BUG_ON(txq_id != txq->swq_id); - - info->status.rates[0].count = tx_resp->failure_frame + 1; - info->flags |= iwl_tx_status_to_mac80211(status); - iwlagn_hwrate_to_tx_control(priv, - le32_to_cpu(tx_resp->rate_n_flags), - info); - - IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " - "0x%x retries %d\n", - txq_id, - iwl_get_tx_fail_reason(status), status, - le32_to_cpu(tx_resp->rate_n_flags), - tx_resp->failure_frame); - + iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false); freed = iwlagn_tx_queue_reclaim(priv, txq_id, index); iwl_free_tfds_in_queue(priv, sta_id, tid, freed); @@ -326,7 +493,7 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr) int iwlagn_send_tx_power(struct iwl_priv *priv) { - struct iwl5000_tx_power_dbm_cmd tx_power_cmd; + struct iwlagn_tx_power_dbm_cmd tx_power_cmd; u8 tx_ant_cfg_cmd; /* half dBm need to multiply */ @@ -347,8 +514,8 @@ int iwlagn_send_tx_power(struct iwl_priv *priv) */ tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm; } - tx_power_cmd.flags = IWL50_TX_POWER_NO_CLOSED; - tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; + tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED; + tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO; if (IWL_UCODE_API(priv->ucode_ver) == 1) tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1; @@ -425,7 +592,7 @@ const u8 *iwlagn_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { u32 address = eeprom_indirect_address(priv, offset); - BUG_ON(address >= priv->cfg->eeprom_size); + BUG_ON(address >= priv->cfg->base_params->eeprom_size); return &priv->eeprom[address]; } @@ -473,7 +640,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */ - if (!priv->cfg->use_isr_legacy) + if (!priv->cfg->base_params->use_isr_legacy) rb_timeout = RX_RB_TIMEOUT; if (priv->cfg->mod_params->amsdu_size_8K) @@ -518,6 +685,23 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) return 0; } +static void iwlagn_set_pwr_vmain(struct iwl_priv *priv) +{ +/* + * (for documentation purposes) + * to set power to V_AUX, do: + + if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) + iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VAUX, + ~APMG_PS_CTRL_MSK_PWR_SRC); + */ + + iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, + APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, + ~APMG_PS_CTRL_MSK_PWR_SRC); +} + int iwlagn_hw_nic_init(struct iwl_priv *priv) { unsigned long flags; @@ -533,7 +717,7 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); - ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); + iwlagn_set_pwr_vmain(priv); priv->cfg->ops->lib->apm_ops.config(priv); @@ -1098,7 +1282,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, if (chan->band != band) continue; - channel = ieee80211_frequency_to_channel(chan->center_freq); + channel = chan->hw_value; scan_ch->channel = cpu_to_le16(channel); ch_info = iwl_get_channel_info(priv, band, channel); @@ -1147,7 +1331,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv, return added; } -void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) +int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_host_cmd cmd = { .id = REPLY_SCAN_CMD, @@ -1155,7 +1339,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) .flags = CMD_SIZE_HUGE, }; struct iwl_scan_cmd *scan; - struct ieee80211_conf *conf = NULL; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u32 rate_flags = 0; u16 cmd_len; u16 rx_chain = 0; @@ -1167,48 +1351,12 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) int chan_mod; u8 active_chains; u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; + int ret; - conf = ieee80211_get_hw_conf(priv->hw); - - cancel_delayed_work(&priv->scan_check); - - if (!iwl_is_ready(priv)) { - IWL_WARN(priv, "request scan called when driver not ready.\n"); - goto done; - } - - /* Make sure the scan wasn't canceled before this queued work - * was given the chance to run... */ - if (!test_bit(STATUS_SCANNING, &priv->status)) - goto done; - - /* This should never be called or scheduled if there is currently - * a scan active in the hardware. */ - if (test_bit(STATUS_SCAN_HW, &priv->status)) { - IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. " - "Ignoring second request.\n"); - goto done; - } - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n"); - goto done; - } - - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_HC(priv, "Scan request while abort pending. Queuing.\n"); - goto done; - } - - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n"); - goto done; - } + lockdep_assert_held(&priv->mutex); - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_DEBUG_HC(priv, "Scan request while uninitialized. Queuing.\n"); - goto done; - } + if (vif) + ctx = iwl_rxon_ctx_from_vif(vif); if (!priv->scan_cmd) { priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) + @@ -1216,7 +1364,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (!priv->scan_cmd) { IWL_DEBUG_SCAN(priv, "fail to allocate memory for scan\n"); - goto done; + return -ENOMEM; } } scan = priv->scan_cmd; @@ -1225,7 +1373,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - if (iwl_is_associated(priv)) { + if (iwl_is_any_associated(priv)) { u16 interval = 0; u32 extra; u32 suspend_time = 100; @@ -1276,13 +1424,15 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; + scan->tx_cmd.sta_id = ctx->bcast_sta_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; switch (priv->scan_band) { case IEEE80211_BAND_2GHZ: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; - chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK) + chan_mod = le32_to_cpu( + priv->contexts[IWL_RXON_CTX_BSS].active.flags & + RXON_FLG_CHANNEL_MODE_MSK) >> RXON_FLG_CHANNEL_MODE_POS; if (chan_mod == CHANNEL_MODE_PURE_40) { rate = IWL_RATE_6M_PLCP; @@ -1290,35 +1440,42 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rate = IWL_RATE_1M_PLCP; rate_flags = RATE_MCS_CCK_MSK; } - scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED; + /* + * Internal scans are passive, so we can indiscriminately set + * the BT ignore flag on 2.4 GHz since it applies to TX only. + */ + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) + scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT; break; case IEEE80211_BAND_5GHZ: rate = IWL_RATE_6M_PLCP; - /* - * If active scanning is requested but a certain channel is - * marked passive, we can do active scanning if we detect - * transmissions. - * - * There is an issue with some firmware versions that triggers - * a sysassert on a "good CRC threshold" of zero (== disabled), - * on a radar channel even though this means that we should NOT - * send probes. - * - * The "good CRC threshold" is the number of frames that we - * need to receive during our dwell time on a channel before - * sending out probes -- setting this to a huge value will - * mean we never reach it, but at the same time work around - * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER - * here instead of IWL_GOOD_CRC_TH_DISABLED. - */ - scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_NEVER; break; default: - IWL_WARN(priv, "Invalid scan band count\n"); - goto done; + IWL_WARN(priv, "Invalid scan band\n"); + return -EIO; } + /* + * If active scanning is requested but a certain channel is + * marked passive, we can do active scanning if we detect + * transmissions. + * + * There is an issue with some firmware versions that triggers + * a sysassert on a "good CRC threshold" of zero (== disabled), + * on a radar channel even though this means that we should NOT + * send probes. + * + * The "good CRC threshold" is the number of frames that we + * need to receive during our dwell time on a channel before + * sending out probes -- setting this to a huge value will + * mean we never reach it, but at the same time work around + * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER + * here instead of IWL_GOOD_CRC_TH_DISABLED. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_NEVER; + band = priv->scan_band; if (priv->cfg->scan_rx_antennas[band]) @@ -1327,6 +1484,14 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (priv->cfg->scan_tx_antennas[band]) scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + scan_tx_antennas = first_antenna( + priv->cfg->scan_tx_antennas[band]); + } + priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band], scan_tx_antennas); rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]); @@ -1345,6 +1510,13 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) rx_ant = first_antenna(active_chains); } + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + rx_ant = first_antenna(rx_ant); + } + /* MIMO is not used here, but value is required */ rx_chain |= priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS; @@ -1385,7 +1557,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) } if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); - goto done; + return -EIO; } cmd.len += le16_to_cpu(scan->tx_cmd.len) + @@ -1393,25 +1565,39 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) cmd.data = scan; scan->len = cpu_to_le16(cmd.len); + /* set scan bit here for PAN params */ set_bit(STATUS_SCAN_HW, &priv->status); - if (iwl_send_cmd_sync(priv, &cmd)) - goto done; - queue_delayed_work(priv->workqueue, &priv->scan_check, - IWL_SCAN_CHECK_WATCHDOG); - - return; - - done: - /* Cannot perform scan. Make sure we clear scanning - * bits from status so next scan request can be performed. - * If we don't clear scanning status bit here all next scan - * will fail - */ - clear_bit(STATUS_SCAN_HW, &priv->status); - clear_bit(STATUS_SCANNING, &priv->status); - /* inform mac80211 scan aborted */ - queue_work(priv->workqueue, &priv->abort_scan); + if (priv->cfg->ops->hcmd->set_pan_params) { + ret = priv->cfg->ops->hcmd->set_pan_params(priv); + if (ret) + return ret; + } + + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) { + clear_bit(STATUS_SCAN_HW, &priv->status); + if (priv->cfg->ops->hcmd->set_pan_params) + priv->cfg->ops->hcmd->set_pan_params(priv); + } + + return ret; +} + +void iwlagn_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + for_each_context(priv, ctx) + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwlagn_commit_rxon(priv, ctx); + + if (priv->cfg->ops->hcmd->set_pan_params) + priv->cfg->ops->hcmd->set_pan_params(priv); } int iwlagn_manage_ibss_station(struct iwl_priv *priv, @@ -1420,8 +1606,9 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; if (add) - return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true, - &vif_priv->ibss_bssid_sta_id); + return iwlagn_add_bssid_station(priv, vif_priv->ctx, + vif->bss_conf.bssid, + &vif_priv->ibss_bssid_sta_id); return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, vif->bss_conf.bssid); } @@ -1453,7 +1640,7 @@ int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv) /* waiting for all the tx frames complete might take a while */ for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { - if (cnt == IWL_CMD_QUEUE_NUM) + if (cnt == priv->cmd_queue) continue; txq = &priv->txq[cnt]; q = &txq->q; @@ -1518,3 +1705,669 @@ void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) ieee80211_wake_queues(priv->hw); mutex_unlock(&priv->mutex); } + +/* + * BT coex + */ +/* + * Macros to access the lookup table. + * + * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req, +* wifi_prio, wifi_txrx and wifi_sh_ant_req. + * + * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH + * + * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits + * one after another in 32-bit registers, and "registers" 0 through 7 contain + * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order). + * + * These macros encode that format. + */ +#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \ + wifi_txrx, wifi_sh_ant_req) \ + (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \ + (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6)) + +#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \ + lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f))) +#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, \ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req)))) +#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req)) +#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req) \ + LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \ + bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req)) + +#define LUT_WLAN_KILL_OP(lut, op, val) \ + lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e))) +#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)))) +#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) +#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) + +#define LUT_ANT_SWITCH_OP(lut, op, val) \ + lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1))) +#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, \ + wifi_sh_ant_req)))) +#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) +#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \ + wifi_prio, wifi_txrx, wifi_sh_ant_req) \ + LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \ + wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req)) + +static const __le32 iwlagn_def_3w_lookup[12] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaeaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xc0004000), + cpu_to_le32(0x00004000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0004000), +}; + +static const __le32 iwlagn_concurrent_lookup[12] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), +}; + +void iwlagn_send_advance_bt_config(struct iwl_priv *priv) +{ + struct iwlagn_bt_cmd bt_cmd = { + .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT, + .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT, + .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT, + .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT, + }; + + BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) != + sizeof(bt_cmd.bt3_lookup_table)); + + if (priv->cfg->bt_params) + bt_cmd.prio_boost = priv->cfg->bt_params->bt_prio_boost; + else + bt_cmd.prio_boost = 0; + bt_cmd.kill_ack_mask = priv->kill_ack_mask; + bt_cmd.kill_cts_mask = priv->kill_cts_mask; + bt_cmd.valid = priv->bt_valid; + bt_cmd.tx_prio_boost = 0; + bt_cmd.rx_prio_boost = 0; + + /* + * Configure BT coex mode to "no coexistence" when the + * user disabled BT coexistence, we have no interface + * (might be in monitor mode), or the interface is in + * IBSS mode (no proper uCode support for coex then). + */ + if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { + bt_cmd.flags = 0; + } else { + bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << + IWLAGN_BT_FLAG_COEX_MODE_SHIFT; + if (priv->bt_ch_announce) + bt_cmd.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION; + IWL_DEBUG_INFO(priv, "BT coex flag: 0X%x\n", bt_cmd.flags); + } + if (priv->bt_full_concurrent) + memcpy(bt_cmd.bt3_lookup_table, iwlagn_concurrent_lookup, + sizeof(iwlagn_concurrent_lookup)); + else + memcpy(bt_cmd.bt3_lookup_table, iwlagn_def_3w_lookup, + sizeof(iwlagn_def_3w_lookup)); + + IWL_DEBUG_INFO(priv, "BT coex %s in %s mode\n", + bt_cmd.flags ? "active" : "disabled", + priv->bt_full_concurrent ? + "full concurrency" : "3-wire"); + + if (iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG, sizeof(bt_cmd), &bt_cmd)) + IWL_ERR(priv, "failed to send BT Coex Config\n"); + + /* + * When we are doing a restart, need to also reconfigure BT + * SCO to the device. If not doing a restart, bt_sco_active + * will always be false, so there's no need to have an extra + * variable to check for it. + */ + if (priv->bt_sco_active) { + struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; + + if (priv->bt_sco_active) + sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE; + if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_SCO, + sizeof(sco_cmd), &sco_cmd)) + IWL_ERR(priv, "failed to send BT SCO command\n"); + } +} + +static void iwlagn_bt_traffic_change_work(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, bt_traffic_change_work); + struct iwl_rxon_context *ctx; + int smps_request = -1; + + IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", + priv->bt_traffic_load); + + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + smps_request = IEEE80211_SMPS_AUTOMATIC; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + smps_request = IEEE80211_SMPS_DYNAMIC; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + smps_request = IEEE80211_SMPS_STATIC; + break; + default: + IWL_ERR(priv, "Invalid BT traffic load: %d\n", + priv->bt_traffic_load); + break; + } + + mutex_lock(&priv->mutex); + + if (priv->cfg->ops->lib->update_chain_flags) + priv->cfg->ops->lib->update_chain_flags(priv); + + if (smps_request != -1) { + for_each_context(priv, ctx) { + if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) + ieee80211_request_smps(ctx->vif, smps_request); + } + } + + mutex_unlock(&priv->mutex); +} + +static void iwlagn_print_uartmsg(struct iwl_priv *priv, + struct iwl_bt_uart_msg *uart_msg) +{ + IWL_DEBUG_NOTIF(priv, "Message Type = 0x%X, SSN = 0x%X, " + "Update Req = 0x%X", + (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1MSGTYPE_POS, + (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1SSN_POS, + (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >> + BT_UART_MSG_FRAME1UPDATEREQ_POS); + + IWL_DEBUG_NOTIF(priv, "Open connections = 0x%X, Traffic load = 0x%X, " + "Chl_SeqN = 0x%X, In band = 0x%X", + (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2OPENCONNECTIONS_POS, + (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2TRAFFICLOAD_POS, + (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2CHLSEQN_POS, + (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >> + BT_UART_MSG_FRAME2INBAND_POS); + + IWL_DEBUG_NOTIF(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, " + "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X", + (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3SCOESCO_POS, + (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3SNIFF_POS, + (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3A2DP_POS, + (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3ACL_POS, + (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3MASTER_POS, + (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >> + BT_UART_MSG_FRAME3OBEX_POS); + + IWL_DEBUG_NOTIF(priv, "Idle duration = 0x%X", + (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >> + BT_UART_MSG_FRAME4IDLEDURATION_POS); + + IWL_DEBUG_NOTIF(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, " + "eSCO Retransmissions = 0x%X", + (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5TXACTIVITY_POS, + (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5RXACTIVITY_POS, + (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >> + BT_UART_MSG_FRAME5ESCORETRANSMIT_POS); + + IWL_DEBUG_NOTIF(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X", + (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >> + BT_UART_MSG_FRAME6SNIFFINTERVAL_POS, + (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >> + BT_UART_MSG_FRAME6DISCOVERABLE_POS); + + IWL_DEBUG_NOTIF(priv, "Sniff Activity = 0x%X, Inquiry/Page SR Mode = " + "0x%X, Connectable = 0x%X", + (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7SNIFFACTIVITY_POS, + (BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS, + (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >> + BT_UART_MSG_FRAME7CONNECTABLE_POS); +} + +static void iwlagn_set_kill_ack_msk(struct iwl_priv *priv, + struct iwl_bt_uart_msg *uart_msg) +{ + u8 kill_ack_msk; + __le32 bt_kill_ack_msg[2] = { + cpu_to_le32(0xFFFFFFF), cpu_to_le32(0xFFFFFC00) }; + + kill_ack_msk = (((BT_UART_MSG_FRAME3A2DP_MSK | + BT_UART_MSG_FRAME3SNIFF_MSK | + BT_UART_MSG_FRAME3SCOESCO_MSK) & + uart_msg->frame3) == 0) ? 1 : 0; + if (priv->kill_ack_mask != bt_kill_ack_msg[kill_ack_msk]) { + priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK; + priv->kill_ack_mask = bt_kill_ack_msg[kill_ack_msk]; + /* schedule to send runtime bt_config */ + queue_work(priv->workqueue, &priv->bt_runtime_config); + } + +} + +void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + unsigned long flags; + struct iwl_rx_packet *pkt = rxb_addr(rxb); + struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; + struct iwlagn_bt_sco_cmd sco_cmd = { .flags = 0 }; + struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; + u8 last_traffic_load; + + IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); + IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); + IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); + IWL_DEBUG_NOTIF(priv, " CI compliance: %d\n", + coex->bt_ci_compliance); + iwlagn_print_uartmsg(priv, uart_msg); + + last_traffic_load = priv->notif_bt_traffic_load; + priv->notif_bt_traffic_load = coex->bt_traffic_load; + if (priv->iw_mode != NL80211_IFTYPE_ADHOC) { + if (priv->bt_status != coex->bt_status || + last_traffic_load != coex->bt_traffic_load) { + if (coex->bt_status) { + /* BT on */ + if (!priv->bt_ch_announce) + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_HIGH; + else + priv->bt_traffic_load = + coex->bt_traffic_load; + } else { + /* BT off */ + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_NONE; + } + priv->bt_status = coex->bt_status; + queue_work(priv->workqueue, + &priv->bt_traffic_change_work); + } + if (priv->bt_sco_active != + (uart_msg->frame3 & BT_UART_MSG_FRAME3SCOESCO_MSK)) { + priv->bt_sco_active = uart_msg->frame3 & + BT_UART_MSG_FRAME3SCOESCO_MSK; + if (priv->bt_sco_active) + sco_cmd.flags |= IWLAGN_BT_SCO_ACTIVE; + iwl_send_cmd_pdu_async(priv, REPLY_BT_COEX_SCO, + sizeof(sco_cmd), &sco_cmd, NULL); + } + } + + iwlagn_set_kill_ack_msk(priv, uart_msg); + + /* FIXME: based on notification, adjust the prio_boost */ + + spin_lock_irqsave(&priv->lock, flags); + priv->bt_ci_compliance = coex->bt_ci_compliance; + spin_unlock_irqrestore(&priv->lock, flags); +} + +void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv) +{ + iwlagn_rx_handler_setup(priv); + priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] = + iwlagn_bt_coex_profile_notif; +} + +void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv) +{ + iwlagn_setup_deferred_work(priv); + + INIT_WORK(&priv->bt_traffic_change_work, + iwlagn_bt_traffic_change_work); +} + +void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv) +{ + cancel_work_sync(&priv->bt_traffic_change_work); +} + +static bool is_single_rx_stream(struct iwl_priv *priv) +{ + return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC || + priv->current_ht_config.single_chain_sufficient; +} + +#define IWL_NUM_RX_CHAINS_MULTIPLE 3 +#define IWL_NUM_RX_CHAINS_SINGLE 2 +#define IWL_NUM_IDLE_CHAINS_DUAL 2 +#define IWL_NUM_IDLE_CHAINS_SINGLE 1 + +/* + * Determine how many receiver/antenna chains to use. + * + * More provides better reception via diversity. Fewer saves power + * at the expense of throughput, but only when not in powersave to + * start with. + * + * MIMO (dual stream) requires at least 2, but works better with 3. + * This does not determine *which* chains to use, just how many. + */ +static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) +{ + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + (priv->bt_full_concurrent || + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { + /* + * only use chain 'A' in bt high traffic load or + * full concurrency mode + */ + return IWL_NUM_RX_CHAINS_SINGLE; + } + /* # of Rx chains to use when expecting MIMO. */ + if (is_single_rx_stream(priv)) + return IWL_NUM_RX_CHAINS_SINGLE; + else + return IWL_NUM_RX_CHAINS_MULTIPLE; +} + +/* + * When we are in power saving mode, unless device support spatial + * multiplexing power save, use the active count for rx chain count. + */ +static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) +{ + /* # Rx chains when idling, depending on SMPS mode */ + switch (priv->current_ht_config.smps) { + case IEEE80211_SMPS_STATIC: + case IEEE80211_SMPS_DYNAMIC: + return IWL_NUM_IDLE_CHAINS_SINGLE; + case IEEE80211_SMPS_OFF: + return active_cnt; + default: + WARN(1, "invalid SMPS mode %d", + priv->current_ht_config.smps); + return active_cnt; + } +} + +/* up to 4 chains */ +static u8 iwl_count_chain_bitmap(u32 chain_bitmap) +{ + u8 res; + res = (chain_bitmap & BIT(0)) >> 0; + res += (chain_bitmap & BIT(1)) >> 1; + res += (chain_bitmap & BIT(2)) >> 2; + res += (chain_bitmap & BIT(3)) >> 3; + return res; +} + +/** + * iwlagn_set_rxon_chain - Set up Rx chain usage in "staging" RXON image + * + * Selects how many and which Rx receivers/antennas/chains to use. + * This should not be used for scan command ... it puts data in wrong place. + */ +void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx) +{ + bool is_single = is_single_rx_stream(priv); + bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); + u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt; + u32 active_chains; + u16 rx_chain; + + /* Tell uCode which antennas are actually connected. + * Before first association, we assume all antennas are connected. + * Just after first association, iwl_chain_noise_calibration() + * checks which antennas actually *are* connected. */ + if (priv->chain_noise_data.active_chains) + active_chains = priv->chain_noise_data.active_chains; + else + active_chains = priv->hw_params.valid_rx_ant; + + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + (priv->bt_full_concurrent || + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) { + /* + * only use chain 'A' in bt high traffic load or + * full concurrency mode + */ + active_chains = first_antenna(active_chains); + } + + rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS; + + /* How many receivers should we use? */ + active_rx_cnt = iwl_get_active_rx_chain_count(priv); + idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); + + + /* correct rx chain count according hw settings + * and chain noise calibration + */ + valid_rx_cnt = iwl_count_chain_bitmap(active_chains); + if (valid_rx_cnt < active_rx_cnt) + active_rx_cnt = valid_rx_cnt; + + if (valid_rx_cnt < idle_rx_cnt) + idle_rx_cnt = valid_rx_cnt; + + rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; + rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; + + ctx->staging.rx_chain = cpu_to_le16(rx_chain); + + if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) + ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; + else + ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; + + IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n", + ctx->staging.rx_chain, + active_rx_cnt, idle_rx_cnt); + + WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || + active_rx_cnt < idle_rx_cnt); +} + +u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) +{ + int i; + u8 ind = ant; + + if (priv->band == IEEE80211_BAND_2GHZ && + priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) + return 0; + + for (i = 0; i < RATE_ANT_NUM - 1; i++) { + ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; + if (valid & BIT(ind)) + return ind; + } + return ant; +} + +static const char *get_csr_string(int cmd) +{ + switch (cmd) { + IWL_CMD(CSR_HW_IF_CONFIG_REG); + IWL_CMD(CSR_INT_COALESCING); + IWL_CMD(CSR_INT); + IWL_CMD(CSR_INT_MASK); + IWL_CMD(CSR_FH_INT_STATUS); + IWL_CMD(CSR_GPIO_IN); + IWL_CMD(CSR_RESET); + IWL_CMD(CSR_GP_CNTRL); + IWL_CMD(CSR_HW_REV); + IWL_CMD(CSR_EEPROM_REG); + IWL_CMD(CSR_EEPROM_GP); + IWL_CMD(CSR_OTP_GP_REG); + IWL_CMD(CSR_GIO_REG); + IWL_CMD(CSR_GP_UCODE_REG); + IWL_CMD(CSR_GP_DRIVER_REG); + IWL_CMD(CSR_UCODE_DRV_GP1); + IWL_CMD(CSR_UCODE_DRV_GP2); + IWL_CMD(CSR_LED_REG); + IWL_CMD(CSR_DRAM_INT_TBL_REG); + IWL_CMD(CSR_GIO_CHICKEN_BITS); + IWL_CMD(CSR_ANA_PLL_CFG); + IWL_CMD(CSR_HW_REV_WA_REG); + IWL_CMD(CSR_DBG_HPET_MEM_REG); + default: + return "UNKNOWN"; + } +} + +void iwl_dump_csr(struct iwl_priv *priv) +{ + int i; + u32 csr_tbl[] = { + CSR_HW_IF_CONFIG_REG, + CSR_INT_COALESCING, + CSR_INT, + CSR_INT_MASK, + CSR_FH_INT_STATUS, + CSR_GPIO_IN, + CSR_RESET, + CSR_GP_CNTRL, + CSR_HW_REV, + CSR_EEPROM_REG, + CSR_EEPROM_GP, + CSR_OTP_GP_REG, + CSR_GIO_REG, + CSR_GP_UCODE_REG, + CSR_GP_DRIVER_REG, + CSR_UCODE_DRV_GP1, + CSR_UCODE_DRV_GP2, + CSR_LED_REG, + CSR_DRAM_INT_TBL_REG, + CSR_GIO_CHICKEN_BITS, + CSR_ANA_PLL_CFG, + CSR_HW_REV_WA_REG, + CSR_DBG_HPET_MEM_REG + }; + IWL_ERR(priv, "CSR values:\n"); + IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is " + "CSR_INT_PERIODIC_REG)\n"); + for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { + IWL_ERR(priv, " %25s: 0X%08x\n", + get_csr_string(csr_tbl[i]), + iwl_read32(priv, csr_tbl[i])); + } +} + +static const char *get_fh_string(int cmd) +{ + switch (cmd) { + IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); + IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); + IWL_CMD(FH_RSCSR_CHNL0_WPTR); + IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); + IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); + IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); + IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); + IWL_CMD(FH_TSSR_TX_STATUS_REG); + IWL_CMD(FH_TSSR_TX_ERROR_REG); + default: + return "UNKNOWN"; + } +} + +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) +{ + int i; +#ifdef CONFIG_IWLWIFI_DEBUG + int pos = 0; + size_t bufsz = 0; +#endif + u32 fh_tbl[] = { + FH_RSCSR_CHNL0_STTS_WPTR_REG, + FH_RSCSR_CHNL0_RBDCB_BASE_REG, + FH_RSCSR_CHNL0_WPTR, + FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_MEM_RSSR_SHARED_CTRL_REG, + FH_MEM_RSSR_RX_STATUS_REG, + FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, + FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_ERROR_REG + }; +#ifdef CONFIG_IWLWIFI_DEBUG + if (display) { + bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; + *buf = kmalloc(bufsz, GFP_KERNEL); + if (!*buf) + return -ENOMEM; + pos += scnprintf(*buf + pos, bufsz - pos, + "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + pos += scnprintf(*buf + pos, bufsz - pos, + " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(priv, fh_tbl[i])); + } + return pos; + } +#endif + IWL_ERR(priv, "FH register values:\n"); + for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { + IWL_ERR(priv, " %34s: 0X%08x\n", + get_fh_string(fh_tbl[i]), + iwl_read_direct32(priv, fh_tbl[i])); + } + return 0; +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index a4378ba31ef6c8092d7a9830ae6956a022ea1eea..065553629de507639c29a1bd6d1ea82eba9e174a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -39,6 +39,7 @@ #include "iwl-dev.h" #include "iwl-sta.h" #include "iwl-core.h" +#include "iwl-agn.h" #define RS_NAME "iwl-agn-rs" @@ -76,12 +77,81 @@ static const u8 ant_toggle_lookup[] = { /*ANT_ABC -> */ ANT_ABC, }; +#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ + [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ + IWL_RATE_SISO_##s##M_PLCP, \ + IWL_RATE_MIMO2_##s##M_PLCP,\ + IWL_RATE_MIMO3_##s##M_PLCP,\ + IWL_RATE_##r##M_IEEE, \ + IWL_RATE_##ip##M_INDEX, \ + IWL_RATE_##in##M_INDEX, \ + IWL_RATE_##rp##M_INDEX, \ + IWL_RATE_##rn##M_INDEX, \ + IWL_RATE_##pp##M_INDEX, \ + IWL_RATE_##np##M_INDEX } + +/* + * Parameter order: + * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate + * + * If there isn't a valid next or previous rate then INV is used which + * maps to IWL_RATE_INVALID + * + */ +const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { + IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ + IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ + IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ + IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */ + IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */ + IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */ + IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */ + IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */ + IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */ + IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */ + IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ + IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ + IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ + /* FIXME:RS: ^^ should be INV (legacy) */ +}; + +static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) +{ + int idx = 0; + + /* HT rate format */ + if (rate_n_flags & RATE_MCS_HT_MSK) { + idx = (rate_n_flags & 0xff); + + if (idx >= IWL_RATE_MIMO3_6M_PLCP) + idx = idx - IWL_RATE_MIMO3_6M_PLCP; + else if (idx >= IWL_RATE_MIMO2_6M_PLCP) + idx = idx - IWL_RATE_MIMO2_6M_PLCP; + + idx += IWL_FIRST_OFDM_RATE; + /* skip 9M not supported in ht*/ + if (idx >= IWL_RATE_9M_INDEX) + idx += 1; + if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) + return idx; + + /* legacy rate format, search for match in table */ + } else { + for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) + if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) + return idx; + } + + return -1; +} + static void rs_rate_scale_perform(struct iwl_priv *priv, struct sk_buff *skb, struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta); static void rs_fill_link_cmd(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, u32 rate_n_flags); +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); #ifdef CONFIG_MAC80211_DEBUGFS @@ -300,7 +370,19 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, struct ieee80211_sta *sta) { int ret = -EAGAIN; - u32 load = rs_tl_get_load(lq_data, tid); + u32 load; + + /* + * Don't create TX aggregation sessions when in high + * BT traffic, as they would just be disrupted by BT. + */ + if (priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) { + IWL_ERR(priv, "BT traffic (%d), no aggregation allowed\n", + priv->bt_traffic_load); + return ret; + } + + load = rs_tl_get_load(lq_data, tid); if (load > IWL_AGG_LOAD_THRESHOLD) { IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", @@ -502,6 +584,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); u8 mcs; + memset(tbl, 0, sizeof(struct iwl_scale_tbl_info)); *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); if (*rate_idx == IWL_RATE_INVALID) { @@ -588,11 +671,13 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, * Green-field mode is valid if the station supports it and * there are no non-GF stations present in the BSS. */ -static inline u8 rs_use_green(struct ieee80211_sta *sta, - struct iwl_ht_config *ht_conf) +static bool rs_use_green(struct ieee80211_sta *sta) { + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; + return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && - !(ht_conf->non_GF_STA_present); + !(ctx->ht.non_gf_sta_present); } /** @@ -744,6 +829,32 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, (a->is_SGI == b->is_SGI); } +static void rs_bt_update_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct iwl_lq_sta *lq_sta) +{ + struct iwl_scale_tbl_info *tbl; + bool full_concurrent; + unsigned long flags; + + spin_lock_irqsave(&priv->lock, flags); + if (priv->bt_ci_compliance && priv->bt_ant_couple_ok) + full_concurrent = true; + else + full_concurrent = false; + spin_unlock_irqrestore(&priv->lock, flags); + + if (priv->bt_full_concurrent != full_concurrent) { + priv->bt_full_concurrent = full_concurrent; + + /* Update uCode's rate table. */ + tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); + + queue_work(priv->workqueue, &priv->bt_full_concurrency); + } +} + /* * mac80211 sends us Tx status */ @@ -763,6 +874,8 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, u32 tx_rate; struct iwl_scale_tbl_info tbl_type; struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n"); @@ -829,7 +942,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, lq_sta->missed_rate_counter++; if (lq_sta->missed_rate_counter > IWL_MISSED_RATE_MAX) { lq_sta->missed_rate_counter = 0; - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); } /* Regardless, ignore this status info for outdated rate */ return; @@ -848,7 +961,20 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, other_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); } else { IWL_DEBUG_RATE(priv, "Neither active nor search matches tx rate\n"); - return; + tmp_tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); + IWL_DEBUG_RATE(priv, "active- lq:%x, ant:%x, SGI:%d\n", + tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI); + tmp_tbl = &(lq_sta->lq_info[1 - lq_sta->active_tbl]); + IWL_DEBUG_RATE(priv, "search- lq:%x, ant:%x, SGI:%d\n", + tmp_tbl->lq_type, tmp_tbl->ant_type, tmp_tbl->is_SGI); + IWL_DEBUG_RATE(priv, "actual- lq:%x, ant:%x, SGI:%d\n", + tbl_type.lq_type, tbl_type.ant_type, tbl_type.is_SGI); + /* + * no matching table found, let's by-pass the data collection + * and continue to perform rate scale to find the rate table + */ + rs_stay_in_table(lq_sta, true); + goto done; } /* @@ -909,10 +1035,14 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, } /* The last TX rate is cached in lq_sta; it's set in if/else above */ lq_sta->last_rate_n_flags = tx_rate; - +done: /* See if there's a better rate or modulation mode to try. */ if (sta && sta->supp_rates[sband->band]) rs_rate_scale_perform(priv, skb, sta, lq_sta); + + /* Is there a need to switch between full concurrency and 3-wire? */ + if (priv->bt_ant_couple_ok) + rs_bt_update_lq(priv, ctx, lq_sta); } /* @@ -1106,6 +1236,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, u16 rate_mask; s32 rate; s8 is_green = lq_sta->is_green; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1126,7 +1258,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, tbl->max_search = IWL_MAX_SEARCH; rate_mask = lq_sta->active_mimo2_rate; - if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) + if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1160,6 +1292,8 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, u16 rate_mask; s32 rate; s8 is_green = lq_sta->is_green; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1180,7 +1314,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv, tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH; rate_mask = lq_sta->active_mimo3_rate; - if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) + if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1215,6 +1349,8 @@ static int rs_switch_to_siso(struct iwl_priv *priv, u16 rate_mask; u8 is_green = lq_sta->is_green; s32 rate; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported) return -1; @@ -1227,7 +1363,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, tbl->max_search = IWL_MAX_SEARCH; rate_mask = lq_sta->active_siso_rate; - if (iwl_is_ht40_tx_allowed(priv, &sta->ht_cap)) + if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) tbl->is_ht40 = 1; else tbl->is_ht40 = 0; @@ -1265,18 +1401,52 @@ static int rs_move_legacy_other(struct iwl_priv *priv, struct iwl_rate_scale_data *window = &(tbl->win[index]); u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); - u8 start_action = tbl->action; + u8 start_action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; int ret = 0; u8 update_search_tbl_counter = 0; + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2) + tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2 && + tbl->action != IWL_LEGACY_SWITCH_SISO) + tbl->action = IWL_LEGACY_SWITCH_SISO; + break; + default: + IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); + break; + } + if (!iwl_ht_enabled(priv)) /* stay in Legacy */ tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; else if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && tbl->action > IWL_LEGACY_SWITCH_SISO) tbl->action = IWL_LEGACY_SWITCH_SISO; + + /* configure as 1x1 if bt full concurrency */ + if (priv->bt_full_concurrent) { + if (!iwl_ht_enabled(priv)) + tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; + else if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) + tbl->action = IWL_LEGACY_SWITCH_SISO; + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + } + + start_action = tbl->action; for (; ;) { lq_sta->action_counter++; switch (tbl->action) { @@ -1291,7 +1461,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv, break; /* Don't change antenna if success has been great */ - if (window->success_ratio >= IWL_RS_GOOD_RATIO) + if (window->success_ratio >= IWL_RS_GOOD_RATIO && + !priv->bt_full_concurrent && + priv->bt_traffic_load == + IWL_BT_COEX_TRAFFIC_LOAD_NONE) break; /* Set up search table to try other antenna */ @@ -1403,31 +1576,64 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); - u8 start_action = tbl->action; + u8 start_action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 update_search_tbl_counter = 0; int ret; + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + break; + default: + IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); + break; + } + if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE && tbl->action > IWL_SISO_SWITCH_ANTENNA2) { /* stay in SISO */ tbl->action = IWL_SISO_SWITCH_ANTENNA1; } + + /* configure as 1x1 if bt full concurrency */ + if (priv->bt_full_concurrent) { + valid_tx_ant = first_antenna(priv->hw_params.valid_tx_ant); + if (tbl->action >= IWL_LEGACY_SWITCH_ANTENNA2) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + } + + start_action = tbl->action; for (;;) { lq_sta->action_counter++; switch (tbl->action) { case IWL_SISO_SWITCH_ANTENNA1: case IWL_SISO_SWITCH_ANTENNA2: IWL_DEBUG_RATE(priv, "LQ: SISO toggle Antenna\n"); - if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && - tx_chains_num <= 1) || + tx_chains_num <= 1) || (tbl->action == IWL_SISO_SWITCH_ANTENNA2 && - tx_chains_num <= 2)) + tx_chains_num <= 2)) break; - if (window->success_ratio >= IWL_RS_GOOD_RATIO) + if (window->success_ratio >= IWL_RS_GOOD_RATIO && + !priv->bt_full_concurrent && + priv->bt_traffic_load == + IWL_BT_COEX_TRAFFIC_LOAD_NONE) break; memcpy(search_tbl, tbl, sz); @@ -1541,18 +1747,47 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); - u8 start_action = tbl->action; + u8 start_action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; u8 update_search_tbl_counter = 0; int ret; + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + if (tbl->action != IWL_MIMO2_SWITCH_SISO_A) + tbl->action = IWL_MIMO2_SWITCH_SISO_A; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + if (tbl->action == IWL_MIMO2_SWITCH_SISO_B || + tbl->action == IWL_MIMO2_SWITCH_SISO_C) + tbl->action = IWL_MIMO2_SWITCH_SISO_A; + break; + default: + IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); + break; + } + if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) && (tbl->action < IWL_MIMO2_SWITCH_SISO_A || tbl->action > IWL_MIMO2_SWITCH_SISO_C)) { /* switch in SISO */ tbl->action = IWL_MIMO2_SWITCH_SISO_A; } + + /* configure as 1x1 if bt full concurrency */ + if (priv->bt_full_concurrent && + (tbl->action < IWL_MIMO2_SWITCH_SISO_A || + tbl->action > IWL_MIMO2_SWITCH_SISO_C)) + tbl->action = IWL_MIMO2_SWITCH_SISO_A; + + start_action = tbl->action; for (;;) { lq_sta->action_counter++; switch (tbl->action) { @@ -1682,18 +1917,47 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); - u8 start_action = tbl->action; + u8 start_action; u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 tx_chains_num = priv->hw_params.tx_chains_num; int ret; u8 update_search_tbl_counter = 0; + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + if (tbl->action != IWL_MIMO3_SWITCH_SISO_A) + tbl->action = IWL_MIMO3_SWITCH_SISO_A; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + if (tbl->action == IWL_MIMO3_SWITCH_SISO_B || + tbl->action == IWL_MIMO3_SWITCH_SISO_C) + tbl->action = IWL_MIMO3_SWITCH_SISO_A; + break; + default: + IWL_ERR(priv, "Invalid BT load %d", priv->bt_traffic_load); + break; + } + if ((iwl_tx_ant_restriction(priv) == IWL_ANT_OK_SINGLE) && (tbl->action < IWL_MIMO3_SWITCH_SISO_A || tbl->action > IWL_MIMO3_SWITCH_SISO_C)) { /* switch in SISO */ tbl->action = IWL_MIMO3_SWITCH_SISO_A; } + + /* configure as 1x1 if bt full concurrency */ + if (priv->bt_full_concurrent && + (tbl->action < IWL_MIMO3_SWITCH_SISO_A || + tbl->action > IWL_MIMO3_SWITCH_SISO_C)) + tbl->action = IWL_MIMO3_SWITCH_SISO_A; + + start_action = tbl->action; for (;;) { lq_sta->action_counter++; switch (tbl->action) { @@ -1820,7 +2084,7 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv, * 2) # times calling this function * 3) elapsed time in this mode (not used, for now) */ -static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) +static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) { struct iwl_scale_tbl_info *tbl; int i; @@ -1851,7 +2115,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) * allow a new search. Also (below) reset all bitmaps and * stats in active history. */ - if ((lq_sta->total_failed > lq_sta->max_failure_limit) || + if (force_search || + (lq_sta->total_failed > lq_sta->max_failure_limit) || (lq_sta->total_success > lq_sta->max_success_limit) || ((!lq_sta->search_better_tbl) && (lq_sta->flush_timer) && (flush_interval_passed))) { @@ -1900,6 +2165,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) * return rate_n_flags as used in the table */ static u32 rs_update_rate_tbl(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, struct iwl_lq_sta *lq_sta, struct iwl_scale_tbl_info *tbl, int index, u8 is_green) @@ -1909,7 +2175,7 @@ static u32 rs_update_rate_tbl(struct iwl_priv *priv, /* Update uCode's rate table. */ rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); rs_fill_link_cmd(priv, lq_sta, rate); - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); return rate; } @@ -1948,6 +2214,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, s32 sr; u8 tid = MAX_TID_COUNT; struct iwl_tid_data *tid_data; + struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_rxon_context *ctx = sta_priv->common.ctx; IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n"); @@ -1986,7 +2254,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, if (is_legacy(tbl->lq_type)) lq_sta->is_green = 0; else - lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); + lq_sta->is_green = rs_use_green(sta); is_green = lq_sta->is_green; /* current tx rate */ @@ -2025,7 +2293,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); /* get "active" rate info */ index = iwl_hwrate_to_plcp_idx(tbl->current_rate); - rate = rs_update_rate_tbl(priv, lq_sta, + rate = rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green); } return; @@ -2067,7 +2335,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, /* Should we stay with this modulation mode, * or search for a new one? */ - rs_stay_in_table(lq_sta); + rs_stay_in_table(lq_sta, false); goto out; } @@ -2215,6 +2483,28 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, if (iwl_tx_ant_restriction(priv) != IWL_ANT_OK_MULTI && (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) scale_action = -1; + + if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && + (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) { + if (lq_sta->last_bt_traffic > priv->bt_traffic_load) { + /* + * don't set scale_action, don't want to scale up if + * the rate scale doesn't otherwise think that is a + * good idea. + */ + } else if (lq_sta->last_bt_traffic <= priv->bt_traffic_load) { + scale_action = -1; + } + } + lq_sta->last_bt_traffic = priv->bt_traffic_load; + + if ((priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && + (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type))) { + /* search for a new modulation */ + rs_stay_in_table(lq_sta, true); + goto lq_update; + } + switch (scale_action) { case -1: /* Decrease starting rate, update uCode's rate table */ @@ -2245,13 +2535,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, lq_update: /* Replace uCode's rate table for the destination station. */ if (update_lq) - rate = rs_update_rate_tbl(priv, lq_sta, + rate = rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green); if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) { /* Should we stay with this modulation mode, * or search for a new one? */ - rs_stay_in_table(lq_sta); + rs_stay_in_table(lq_sta, false); } /* * Search for new modulation mode if we're: @@ -2287,7 +2577,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, IWL_DEBUG_RATE(priv, "Switch current mcs: %X index: %d\n", tbl->current_rate, index); rs_fill_link_cmd(priv, lq_sta, tbl->current_rate); - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false); } else done_search = 1; } @@ -2357,12 +2647,17 @@ static void rs_initialize_lq(struct iwl_priv *priv, int rate_idx; int i; u32 rate; - u8 use_green = rs_use_green(sta, &priv->current_ht_config); + u8 use_green = rs_use_green(sta); u8 active_tbl = 0; u8 valid_tx_ant; + struct iwl_station_priv *sta_priv; + struct iwl_rxon_context *ctx; if (!sta || !lq_sta) - goto out; + return; + + sta_priv = (void *)sta->drv_priv; + ctx = sta_priv->common.ctx; i = lq_sta->last_txrate_idx; @@ -2394,9 +2689,7 @@ static void rs_initialize_lq(struct iwl_priv *priv, rs_set_expected_tpt_table(lq_sta, tbl); rs_fill_link_cmd(NULL, lq_sta, rate); priv->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq; - iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_SYNC, true); - out: - return; + iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_SYNC, true); } static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, @@ -2524,7 +2817,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i lq_sta->is_dup = 0; lq_sta->max_rate_idx = -1; lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; - lq_sta->is_green = rs_use_green(sta, &priv->current_ht_config); + lq_sta->is_green = rs_use_green(sta); lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); lq_sta->band = priv->band; /* @@ -2594,10 +2887,15 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, rs_dbgfs_set_mcs(lq_sta, &new_rate, index); /* Interpret new_rate (rate_n_flags) */ - memset(&tbl_type, 0, sizeof(tbl_type)); rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, &rate_idx); + if (priv && priv->bt_full_concurrent) { + /* 1x1 only */ + tbl_type.ant_type = + first_antenna(priv->hw_params.valid_tx_ant); + } + /* How many times should we repeat the initial rate? */ if (is_legacy(tbl_type.lq_type)) { ant_toggle_cnt = 1; @@ -2622,9 +2920,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, index++; repeat_rate--; - - if (priv) - valid_tx_ant = priv->hw_params.valid_tx_ant; + if (priv) { + if (priv->bt_full_concurrent) + valid_tx_ant = ANT_A; + else + valid_tx_ant = priv->hw_params.valid_tx_ant; + } /* Fill rest of rate table */ while (index < LINK_QUAL_MAX_RETRY_NUM) { @@ -2639,7 +2940,7 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, rs_toggle_antenna(valid_tx_ant, &new_rate, &tbl_type)) ant_toggle_cnt = 1; -} + } /* Override next rate if needed for debug purposes */ rs_dbgfs_set_mcs(lq_sta, &new_rate, index); @@ -2654,6 +2955,12 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, &rate_idx); + if (priv && priv->bt_full_concurrent) { + /* 1x1 only */ + tbl_type.ant_type = + first_antenna(priv->hw_params.valid_tx_ant); + } + /* Indicate to uCode which entries might be MIMO. * If initial rate was MIMO, this will finally end up * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ @@ -2694,8 +3001,21 @@ static void rs_fill_link_cmd(struct iwl_priv *priv, lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; + lq_cmd->agg_params.agg_time_limit = cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); + /* + * overwrite if needed, pass aggregation time limit + * to uCode in uSec + */ + if (priv && priv->cfg->bt_params && + priv->cfg->bt_params->agg_time_limit && + priv->cfg->bt_params->agg_time_limit >= + LINK_QUAL_AGG_TIME_LIMIT_MIN && + priv->cfg->bt_params->agg_time_limit <= + LINK_QUAL_AGG_TIME_LIMIT_MAX) + lq_cmd->agg_params.agg_time_limit = + cpu_to_le16(priv->cfg->bt_params->agg_time_limit); } static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) @@ -2760,6 +3080,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, char buf[64]; int buf_size; u32 parsed_rate; + struct iwl_station_priv *sta_priv = + container_of(lq_sta, struct iwl_station_priv, lq_sta); + struct iwl_rxon_context *ctx = sta_priv->common.ctx; priv = lq_sta->drv; memset(buf, 0, sizeof(buf)); @@ -2782,7 +3105,8 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, if (lq_sta->dbg_fixed_rate) { rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); - iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false); + iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, + false); } return count; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 8292f6d48ec62067cb5dec7f4076038ad0b46430..75e50d33ecb3a14a9d304b0ffe0342dc0d81a81d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -299,7 +299,6 @@ enum { #define TIME_WRAP_AROUND(x, y) (((y) > (x)) ? (y) - (x) : (0-(x)) + (y)) extern const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT]; -extern const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945]; enum iwl_table_type { LQ_NONE, @@ -432,6 +431,8 @@ struct iwl_lq_sta { u32 last_rate_n_flags; /* packets destined for this STA are aggregated */ u8 is_agg; + /* BT traffic this sta was last updated in */ + u8 last_bt_traffic; }; static inline u8 num_of_ant(u8 mask) @@ -451,24 +452,6 @@ static inline u8 first_antenna(u8 mask) } -static inline u8 iwl_get_prev_ieee_rate(u8 rate_index) -{ - u8 rate = iwl_rates[rate_index].prev_ieee; - - if (rate == IWL_RATE_INVALID) - rate = rate_index; - return rate; -} - -static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) -{ - u8 rate = iwl3945_rates[rate_index].prev_ieee; - - if (rate == IWL_RATE_INVALID) - rate = rate_index; - return rate; -} - /** * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info * diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index 9490eced1198ad178f6191389156565ceca9cbd1..bbd40b7dd597996ca0c9313a7338ee37448dcd91 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -34,7 +34,7 @@ #include "iwl-dev.h" #include "iwl-core.h" -#include "iwl-calib.h" +#include "iwl-agn-calib.h" #include "iwl-sta.h" #include "iwl-io.h" #include "iwl-helpers.h" @@ -73,7 +73,8 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv) int bcn_silence_a, bcn_silence_b, bcn_silence_c; int last_rx_noise; - if (priv->cfg->bt_statistics) + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) rx_info = &(priv->_agn.statistics_bt.rx.general.common); else rx_info = &(priv->_agn.statistics.rx.general); @@ -124,7 +125,8 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv, struct statistics_general_common *general, *accum_general; struct statistics_tx *tx, *accum_tx; - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { prev_stats = (__le32 *)&priv->_agn.statistics_bt; accum_stats = (u32 *)&priv->_agn.accum_statistics_bt; size = sizeof(struct iwl_bt_notif_statistics); @@ -183,7 +185,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, unsigned int plcp_msec; unsigned long plcp_received_jiffies; - if (priv->cfg->plcp_delta_threshold == + if (priv->cfg->base_params->plcp_delta_threshold == IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE) { IWL_DEBUG_RADIO(priv, "plcp_err check disabled\n"); return rc; @@ -205,7 +207,8 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, struct statistics_rx_phy *ofdm; struct statistics_rx_ht_phy *ofdm_ht; - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { ofdm = &pkt->u.stats_bt.rx.ofdm; ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht; combined_plcp_delta = @@ -229,7 +232,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, if ((combined_plcp_delta > 0) && ((combined_plcp_delta * 100) / plcp_msec) > - priv->cfg->plcp_delta_threshold) { + priv->cfg->base_params->plcp_delta_threshold) { /* * if plcp_err exceed the threshold, * the following data is printed in csv format: @@ -242,13 +245,13 @@ bool iwl_good_plcp_health(struct iwl_priv *priv, * plcp_msec */ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, " - "%u, %u, %u, %u, %d, %u mSecs\n", - priv->cfg->plcp_delta_threshold, - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - le32_to_cpu(ofdm_ht->plcp_err), - combined_plcp_delta, plcp_msec); + "%u, %u, %u, %u, %d, %u mSecs\n", + priv->cfg->base_params->plcp_delta_threshold, + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + le32_to_cpu(ofdm_ht->plcp_err), + combined_plcp_delta, plcp_msec); rc = false; } @@ -262,7 +265,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, int change; struct iwl_rx_packet *pkt = rxb_addr(rxb); - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n", (int)sizeof(struct iwl_bt_notif_statistics), @@ -300,7 +304,8 @@ void iwl_rx_statistics(struct iwl_priv *priv, iwl_recover_from_statistics(priv, pkt); - if (priv->cfg->bt_statistics) + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt, sizeof(priv->_agn.statistics_bt)); else diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c new file mode 100644 index 0000000000000000000000000000000000000000..35a30d2e07348e0740e5e538dc42bb3bd32ffefb --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -0,0 +1,716 @@ +/****************************************************************************** + * + * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + *****************************************************************************/ + +#include + +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-sta.h" +#include "iwl-agn.h" + +static struct iwl_link_quality_cmd * +iwl_sta_alloc_lq(struct iwl_priv *priv, u8 sta_id) +{ + int i, r; + struct iwl_link_quality_cmd *link_cmd; + u32 rate_flags = 0; + __le32 rate_n_flags; + + link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); + if (!link_cmd) { + IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); + return NULL; + } + /* Set up the rate scaling to start at selected rate, fall back + * all the way down to 1M in IEEE order, and then spin on 1M */ + if (priv->band == IEEE80211_BAND_5GHZ) + r = IWL_RATE_6M_INDEX; + else + r = IWL_RATE_1M_INDEX; + + if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) + rate_flags |= RATE_MCS_CCK_MSK; + + rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << + RATE_MCS_ANT_POS; + rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) + link_cmd->rs_table[i].rate_n_flags = rate_n_flags; + + link_cmd->general_params.single_stream_ant_msk = + first_antenna(priv->hw_params.valid_tx_ant); + + link_cmd->general_params.dual_stream_ant_msk = + priv->hw_params.valid_tx_ant & + ~first_antenna(priv->hw_params.valid_tx_ant); + if (!link_cmd->general_params.dual_stream_ant_msk) { + link_cmd->general_params.dual_stream_ant_msk = ANT_AB; + } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { + link_cmd->general_params.dual_stream_ant_msk = + priv->hw_params.valid_tx_ant; + } + + link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; + link_cmd->agg_params.agg_time_limit = + cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); + + link_cmd->sta_id = sta_id; + + return link_cmd; +} + +/* + * iwlagn_add_bssid_station - Add the special IBSS BSSID station + * + * Function sleeps. + */ +int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, u8 *sta_id_r) +{ + int ret; + u8 sta_id; + struct iwl_link_quality_cmd *link_cmd; + unsigned long flags; + + if (sta_id_r) + *sta_id_r = IWL_INVALID_STATION; + + ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id); + if (ret) { + IWL_ERR(priv, "Unable to add station %pM\n", addr); + return ret; + } + + if (sta_id_r) + *sta_id_r = sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].used |= IWL_STA_LOCAL; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + /* Set up default rate scaling table in device's station table */ + link_cmd = iwl_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n", + addr); + return -ENOMEM; + } + + ret = iwl_send_lq_cmd(priv, ctx, link_cmd, CMD_SYNC, true); + if (ret) + IWL_ERR(priv, "Link quality command failed (%d)\n", ret); + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + bool send_if_empty) +{ + int i, not_empty = 0; + u8 buff[sizeof(struct iwl_wep_cmd) + + sizeof(struct iwl_wep_key) * WEP_KEYS_MAX]; + struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; + size_t cmd_size = sizeof(struct iwl_wep_cmd); + struct iwl_host_cmd cmd = { + .id = ctx->wep_key_cmd, + .data = wep_cmd, + .flags = CMD_SYNC, + }; + + might_sleep(); + + memset(wep_cmd, 0, cmd_size + + (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); + + for (i = 0; i < WEP_KEYS_MAX ; i++) { + wep_cmd->key[i].key_index = i; + if (ctx->wep_keys[i].key_size) { + wep_cmd->key[i].key_offset = i; + not_empty = 1; + } else { + wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; + } + + wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size; + memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key, + ctx->wep_keys[i].key_size); + } + + wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; + wep_cmd->num_keys = WEP_KEYS_MAX; + + cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; + + cmd.len = cmd_size; + + if (not_empty || send_if_empty) + return iwl_send_cmd(priv, &cmd); + else + return 0; +} + +int iwl_restore_default_wep_keys(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + lockdep_assert_held(&priv->mutex); + + return iwl_send_static_wepkey_cmd(priv, ctx, false); +} + +int iwl_remove_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", + keyconf->keyidx); + + memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0])); + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); + /* but keys in device are clear anyway so return success */ + return 0; + } + ret = iwl_send_static_wepkey_cmd(priv, ctx, 1); + IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", + keyconf->keyidx, ret); + + return ret; +} + +int iwl_set_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + if (keyconf->keylen != WEP_KEY_LEN_128 && + keyconf->keylen != WEP_KEY_LEN_64) { + IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen); + return -EINVAL; + } + + keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->hw_key_idx = HW_KEY_DEFAULT; + priv->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher; + + ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; + memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key, + keyconf->keylen); + + ret = iwl_send_static_wepkey_cmd(priv, ctx, false); + IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", + keyconf->keylen, keyconf->keyidx, ret); + + return ret; +} + +static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; + + key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (keyconf->keylen == WEP_KEY_LEN_128) + key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx; + + memcpy(priv->stations[sta_id].keyinfo.key, + keyconf->key, keyconf->keylen); + + memcpy(&priv->stations[sta_id].sta.key.key[3], + keyconf->key, keyconf->keylen); + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + __le16 key_flags = 0; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; + + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, + keyconf->keylen); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, + keyconf->keylen); + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + int ret = 0; + __le16 key_flags = 0; + + key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); + key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); + key_flags &= ~STA_KEY_FLG_INVALID; + + if (sta_id == ctx->bcast_sta_id) + key_flags |= STA_KEY_MULTICAST_MSK; + + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; + priv->stations[sta_id].keyinfo.keylen = 16; + + if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) + == STA_KEY_FLG_NO_ENC) + priv->stations[sta_id].sta.key.key_offset = + iwl_get_free_ucode_key_index(priv); + /* else, we are overriding an existing key => no need to allocated room + * in uCode. */ + + WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, + "no space for a new key"); + + priv->stations[sta_id].sta.key.key_flags = key_flags; + + + /* This copy is acutally not needed: we get the key with each TX */ + memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); + + memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return ret; +} + +void iwl_update_tkip_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) +{ + u8 sta_id; + unsigned long flags; + int i; + + if (iwl_scan_cancel(priv)) { + /* cancel scan failed, just live w/ bad key and rely + briefly on SW decryption */ + return; + } + + sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta); + if (sta_id == IWL_INVALID_STATION) + return; + + spin_lock_irqsave(&priv->sta_lock, flags); + + priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; + + for (i = 0; i < 5; i++) + priv->stations[sta_id].sta.key.tkip_rx_ttak[i] = + cpu_to_le16(phase1key[i]); + + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + + spin_unlock_irqrestore(&priv->sta_lock, flags); + +} + +int iwl_remove_dynamic_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + u8 sta_id) +{ + unsigned long flags; + u16 key_flags; + u8 keyidx; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + ctx->key_mapping_keys--; + + spin_lock_irqsave(&priv->sta_lock, flags); + key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); + keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; + + IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n", + keyconf->keyidx, sta_id); + + if (keyconf->keyidx != keyidx) { + /* We need to remove a key with index different that the one + * in the uCode. This means that the key we need to remove has + * been replaced by another one with different index. + * Don't do anything and return ok + */ + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + + if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { + IWL_WARN(priv, "Removing wrong key %d 0x%x\n", + keyconf->keyidx, key_flags); + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + + if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, + &priv->ucode_key_table)) + IWL_ERR(priv, "index %d not used in uCode key table.\n", + priv->stations[sta_id].sta.key.key_offset); + memset(&priv->stations[sta_id].keyinfo, 0, + sizeof(struct iwl_hw_key)); + memset(&priv->stations[sta_id].sta.key, 0, + sizeof(struct iwl4965_keyinfo)); + priv->stations[sta_id].sta.key.key_flags = + STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; + priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + return 0; + } + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, u8 sta_id) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + ctx->key_mapping_keys++; + keyconf->hw_key_idx = HW_KEY_DYNAMIC; + + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: + ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_TKIP: + ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id); + break; + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id); + break; + default: + IWL_ERR(priv, + "Unknown alg: %s cipher = %x\n", __func__, + keyconf->cipher); + ret = -EINVAL; + } + + IWL_DEBUG_WEP(priv, "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n", + keyconf->cipher, keyconf->keylen, keyconf->keyidx, + sta_id, ret); + + return ret; +} + +/** + * iwlagn_alloc_bcast_station - add broadcast station into driver's station table. + * + * This adds the broadcast station into the driver's station table + * and marks it driver active, so that it will be restored to the + * device at the next best time. + */ +int iwlagn_alloc_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + struct iwl_link_quality_cmd *link_cmd; + unsigned long flags; + u8 sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Unable to prepare broadcast station\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return -EINVAL; + } + + priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; + priv->stations[sta_id].used |= IWL_STA_BCAST; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + link_cmd = iwl_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, + "Unable to initialize rate scaling for bcast station.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +/** + * iwl_update_bcast_station - update broadcast station's LQ command + * + * Only used by iwlagn. Placed here to have all bcast station management + * code together. + */ +static int iwl_update_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) +{ + unsigned long flags; + struct iwl_link_quality_cmd *link_cmd; + u8 sta_id = ctx->bcast_sta_id; + + link_cmd = iwl_sta_alloc_lq(priv, sta_id); + if (!link_cmd) { + IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); + return -ENOMEM; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + if (priv->stations[sta_id].lq) + kfree(priv->stations[sta_id].lq); + else + IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); + priv->stations[sta_id].lq = link_cmd; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + +int iwl_update_bcast_stations(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx; + int ret = 0; + + for_each_context(priv, ctx) { + ret = iwl_update_bcast_station(priv, ctx); + if (ret) + break; + } + + return ret; +} + +/** + * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table + */ +int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) +{ + unsigned long flags; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + /* Remove "disable" flag, to enable Tx for this TID */ + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; + priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid, u16 ssn) +{ + unsigned long flags; + int sta_id; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + sta_id = iwl_sta_id(sta); + if (sta_id == IWL_INVALID_STATION) + return -ENXIO; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags_msk = 0; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; + priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; + priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid) +{ + unsigned long flags; + int sta_id; + struct iwl_addsta_cmd sta_cmd; + + lockdep_assert_held(&priv->mutex); + + sta_id = iwl_sta_id(sta); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); + return -ENXIO; + } + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags_msk = 0; + priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; + priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); +} + +void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.sta.modify_mask = 0; + priv->stations[sta_id].sta.sleep_tx_count = 0; + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + spin_unlock_irqrestore(&priv->sta_lock, flags); + +} + +void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->sta_lock, flags); + priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; + priv->stations[sta_id].sta.sta.modify_mask = + STA_MODIFY_SLEEP_TX_COUNT_MSK; + priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); + priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); + spin_unlock_irqrestore(&priv->sta_lock, flags); + +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c new file mode 100644 index 0000000000000000000000000000000000000000..e3a8216a033cf574d31fdca786d488edd78d5bfe --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -0,0 +1,699 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ + + +#include +#include +#include +#include + +#include + +#include "iwl-eeprom.h" +#include "iwl-dev.h" +#include "iwl-core.h" +#include "iwl-io.h" +#include "iwl-commands.h" +#include "iwl-debug.h" +#include "iwl-agn-tt.h" + +/* default Thermal Throttling transaction table + * Current state | Throttling Down | Throttling Up + *============================================================================= + * Condition Nxt State Condition Nxt State Condition Nxt State + *----------------------------------------------------------------------------- + * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A + * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 + * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 + * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 + *============================================================================= + */ +static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = { + {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104}, + {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1}, + {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} +}; +static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = { + {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95}, + {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1}, + {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} +}; +static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = { + {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100}, + {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}, + {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} +}; +static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = { + {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD}, + {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}, + {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX} +}; + +/* Advance Thermal Throttling default restriction table */ +static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = { + {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true }, + {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true }, + {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false }, + {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false } +}; + +bool iwl_tt_is_low_power_state(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + if (tt->state >= IWL_TI_1) + return true; + return false; +} + +u8 iwl_tt_current_power_mode(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + return tt->tt_power_mode; +} + +bool iwl_ht_enabled(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + struct iwl_tt_restriction *restriction; + + if (!priv->thermal_throttle.advanced_tt) + return true; + restriction = tt->restriction + tt->state; + return restriction->is_ht; +} + +static bool iwl_within_ct_kill_margin(struct iwl_priv *priv) +{ + s32 temp = priv->temperature; /* degrees CELSIUS except specified */ + bool within_margin = false; + + if (priv->cfg->base_params->temperature_kelvin) + temp = KELVIN_TO_CELSIUS(priv->temperature); + + if (!priv->thermal_throttle.advanced_tt) + within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >= + CT_KILL_THRESHOLD_LEGACY) ? true : false; + else + within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >= + CT_KILL_THRESHOLD) ? true : false; + return within_margin; +} + +bool iwl_check_for_ct_kill(struct iwl_priv *priv) +{ + bool is_ct_kill = false; + + if (iwl_within_ct_kill_margin(priv)) { + iwl_tt_enter_ct_kill(priv); + is_ct_kill = true; + } + return is_ct_kill; +} + +enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + struct iwl_tt_restriction *restriction; + + if (!priv->thermal_throttle.advanced_tt) + return IWL_ANT_OK_MULTI; + restriction = tt->restriction + tt->state; + return restriction->tx_stream; +} + +enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + struct iwl_tt_restriction *restriction; + + if (!priv->thermal_throttle.advanced_tt) + return IWL_ANT_OK_MULTI; + restriction = tt->restriction + tt->state; + return restriction->rx_stream; +} + +#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */ +#define CT_KILL_WAITING_DURATION (300) /* 300ms duration */ + +/* + * toggle the bit to wake up uCode and check the temperature + * if the temperature is below CT, uCode will stay awake and send card + * state notification with CT_KILL bit clear to inform Thermal Throttling + * Management to change state. Otherwise, uCode will go back to sleep + * without doing anything, driver should continue the 5 seconds timer + * to wake up uCode for temperature check until temperature drop below CT + */ +static void iwl_tt_check_exit_ct_kill(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + unsigned long flags; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (tt->state == IWL_TI_CT_KILL) { + if (priv->thermal_throttle.ct_kill_toggle) { + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + priv->thermal_throttle.ct_kill_toggle = false; + } else { + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + priv->thermal_throttle.ct_kill_toggle = true; + } + iwl_read32(priv, CSR_UCODE_DRV_GP1); + spin_lock_irqsave(&priv->reg_lock, flags); + if (!iwl_grab_nic_access(priv)) + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->reg_lock, flags); + + /* Reschedule the ct_kill timer to occur in + * CT_KILL_EXIT_DURATION seconds to ensure we get a + * thermal update */ + IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n"); + mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, + jiffies + CT_KILL_EXIT_DURATION * HZ); + } +} + +static void iwl_perform_ct_kill_task(struct iwl_priv *priv, + bool stop) +{ + if (stop) { + IWL_DEBUG_POWER(priv, "Stop all queues\n"); + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + IWL_DEBUG_POWER(priv, + "Schedule 5 seconds CT_KILL Timer\n"); + mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, + jiffies + CT_KILL_EXIT_DURATION * HZ); + } else { + IWL_DEBUG_POWER(priv, "Wake all queues\n"); + if (priv->mac80211_registered) + ieee80211_wake_queues(priv->hw); + } +} + +static void iwl_tt_ready_for_ct_kill(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* temperature timer expired, ready to go into CT_KILL state */ + if (tt->state != IWL_TI_CT_KILL) { + IWL_DEBUG_POWER(priv, "entering CT_KILL state when " + "temperature timer expired\n"); + tt->state = IWL_TI_CT_KILL; + set_bit(STATUS_CT_KILL, &priv->status); + iwl_perform_ct_kill_task(priv, true); + } +} + +static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) +{ + IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); + /* make request to retrieve statistics information */ + iwl_send_statistics_request(priv, CMD_SYNC, false); + /* Reschedule the ct_kill wait timer */ + mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm, + jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION)); +} + +#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY) +#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100) +#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90) + +/* + * Legacy thermal throttling + * 1) Avoid NIC destruction due to high temperatures + * Chip will identify dangerously high temperatures that can + * harm the device and will power down + * 2) Avoid the NIC power down due to high temperature + * Throttle early enough to lower the power consumption before + * drastic steps are needed + */ +static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + enum iwl_tt_state old_state; + +#ifdef CONFIG_IWLWIFI_DEBUG + if ((tt->tt_previous_temp) && + (temp > tt->tt_previous_temp) && + ((temp - tt->tt_previous_temp) > + IWL_TT_INCREASE_MARGIN)) { + IWL_DEBUG_POWER(priv, + "Temperature increase %d degree Celsius\n", + (temp - tt->tt_previous_temp)); + } +#endif + old_state = tt->state; + /* in Celsius */ + if (temp >= IWL_MINIMAL_POWER_THRESHOLD) + tt->state = IWL_TI_CT_KILL; + else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2) + tt->state = IWL_TI_2; + else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1) + tt->state = IWL_TI_1; + else + tt->state = IWL_TI_0; + +#ifdef CONFIG_IWLWIFI_DEBUG + tt->tt_previous_temp = temp; +#endif + /* stop ct_kill_waiting_tm timer */ + del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); + if (tt->state != old_state) { + switch (tt->state) { + case IWL_TI_0: + /* + * When the system is ready to go back to IWL_TI_0 + * we only have to call iwl_power_update_mode() to + * do so. + */ + break; + case IWL_TI_1: + tt->tt_power_mode = IWL_POWER_INDEX_3; + break; + case IWL_TI_2: + tt->tt_power_mode = IWL_POWER_INDEX_4; + break; + default: + tt->tt_power_mode = IWL_POWER_INDEX_5; + break; + } + mutex_lock(&priv->mutex); + if (old_state == IWL_TI_CT_KILL) + clear_bit(STATUS_CT_KILL, &priv->status); + if (tt->state != IWL_TI_CT_KILL && + iwl_power_update_mode(priv, true)) { + /* TT state not updated + * try again during next temperature read + */ + if (old_state == IWL_TI_CT_KILL) + set_bit(STATUS_CT_KILL, &priv->status); + tt->state = old_state; + IWL_ERR(priv, "Cannot update power mode, " + "TT state not updated\n"); + } else { + if (tt->state == IWL_TI_CT_KILL) { + if (force) { + set_bit(STATUS_CT_KILL, &priv->status); + iwl_perform_ct_kill_task(priv, true); + } else { + iwl_prepare_ct_kill_task(priv); + tt->state = old_state; + } + } else if (old_state == IWL_TI_CT_KILL && + tt->state != IWL_TI_CT_KILL) + iwl_perform_ct_kill_task(priv, false); + IWL_DEBUG_POWER(priv, "Temperature state changed %u\n", + tt->state); + IWL_DEBUG_POWER(priv, "Power Index change to %u\n", + tt->tt_power_mode); + } + mutex_unlock(&priv->mutex); + } +} + +/* + * Advance thermal throttling + * 1) Avoid NIC destruction due to high temperatures + * Chip will identify dangerously high temperatures that can + * harm the device and will power down + * 2) Avoid the NIC power down due to high temperature + * Throttle early enough to lower the power consumption before + * drastic steps are needed + * Actions include relaxing the power down sleep thresholds and + * decreasing the number of TX streams + * 3) Avoid throughput performance impact as much as possible + * + *============================================================================= + * Condition Nxt State Condition Nxt State Condition Nxt State + *----------------------------------------------------------------------------- + * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A + * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 + * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 + * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 + *============================================================================= + */ +static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + int i; + bool changed = false; + enum iwl_tt_state old_state; + struct iwl_tt_trans *transaction; + + old_state = tt->state; + for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) { + /* based on the current TT state, + * find the curresponding transaction table + * each table has (IWL_TI_STATE_MAX - 1) entries + * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1)) + * will advance to the correct table. + * then based on the current temperature + * find the next state need to transaction to + * go through all the possible (IWL_TI_STATE_MAX - 1) entries + * in the current table to see if transaction is needed + */ + transaction = tt->transaction + + ((old_state * (IWL_TI_STATE_MAX - 1)) + i); + if (temp >= transaction->tt_low && + temp <= transaction->tt_high) { +#ifdef CONFIG_IWLWIFI_DEBUG + if ((tt->tt_previous_temp) && + (temp > tt->tt_previous_temp) && + ((temp - tt->tt_previous_temp) > + IWL_TT_INCREASE_MARGIN)) { + IWL_DEBUG_POWER(priv, + "Temperature increase %d " + "degree Celsius\n", + (temp - tt->tt_previous_temp)); + } + tt->tt_previous_temp = temp; +#endif + if (old_state != + transaction->next_state) { + changed = true; + tt->state = + transaction->next_state; + } + break; + } + } + /* stop ct_kill_waiting_tm timer */ + del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); + if (changed) { + if (tt->state >= IWL_TI_1) { + /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */ + tt->tt_power_mode = IWL_POWER_INDEX_5; + + if (!iwl_ht_enabled(priv)) { + struct iwl_rxon_context *ctx; + + for_each_context(priv, ctx) { + struct iwl_rxon_cmd *rxon; + + rxon = &ctx->staging; + + /* disable HT */ + rxon->flags &= ~( + RXON_FLG_CHANNEL_MODE_MSK | + RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | + RXON_FLG_HT40_PROT_MSK | + RXON_FLG_HT_PROT_MSK); + } + } else { + /* check HT capability and set + * according to the system HT capability + * in case get disabled before */ + iwl_set_rxon_ht(priv, &priv->current_ht_config); + } + + } else { + /* + * restore system power setting -- it will be + * recalculated automatically. + */ + + /* check HT capability and set + * according to the system HT capability + * in case get disabled before */ + iwl_set_rxon_ht(priv, &priv->current_ht_config); + } + mutex_lock(&priv->mutex); + if (old_state == IWL_TI_CT_KILL) + clear_bit(STATUS_CT_KILL, &priv->status); + if (tt->state != IWL_TI_CT_KILL && + iwl_power_update_mode(priv, true)) { + /* TT state not updated + * try again during next temperature read + */ + IWL_ERR(priv, "Cannot update power mode, " + "TT state not updated\n"); + if (old_state == IWL_TI_CT_KILL) + set_bit(STATUS_CT_KILL, &priv->status); + tt->state = old_state; + } else { + IWL_DEBUG_POWER(priv, + "Thermal Throttling to new state: %u\n", + tt->state); + if (old_state != IWL_TI_CT_KILL && + tt->state == IWL_TI_CT_KILL) { + if (force) { + IWL_DEBUG_POWER(priv, + "Enter IWL_TI_CT_KILL\n"); + set_bit(STATUS_CT_KILL, &priv->status); + iwl_perform_ct_kill_task(priv, true); + } else { + iwl_prepare_ct_kill_task(priv); + tt->state = old_state; + } + } else if (old_state == IWL_TI_CT_KILL && + tt->state != IWL_TI_CT_KILL) { + IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n"); + iwl_perform_ct_kill_task(priv, false); + } + } + mutex_unlock(&priv->mutex); + } +} + +/* Card State Notification indicated reach critical temperature + * if PSP not enable, no Thermal Throttling function will be performed + * just set the GP1 bit to acknowledge the event + * otherwise, go into IWL_TI_CT_KILL state + * since Card State Notification will not provide any temperature reading + * for Legacy mode + * so just pass the CT_KILL temperature to iwl_legacy_tt_handler() + * for advance mode + * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state + */ +static void iwl_bg_ct_enter(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!iwl_is_ready(priv)) + return; + + if (tt->state != IWL_TI_CT_KILL) { + IWL_ERR(priv, "Device reached critical temperature " + "- ucode going to sleep!\n"); + if (!priv->thermal_throttle.advanced_tt) + iwl_legacy_tt_handler(priv, + IWL_MINIMAL_POWER_THRESHOLD, + true); + else + iwl_advance_tt_handler(priv, + CT_KILL_THRESHOLD + 1, true); + } +} + +/* Card State Notification indicated out of critical temperature + * since Card State Notification will not provide any temperature reading + * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature + * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state + */ +static void iwl_bg_ct_exit(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (!iwl_is_ready(priv)) + return; + + /* stop ct_kill_exit_tm timer */ + del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm); + + if (tt->state == IWL_TI_CT_KILL) { + IWL_ERR(priv, + "Device temperature below critical" + "- ucode awake!\n"); + /* + * exit from CT_KILL state + * reset the current temperature reading + */ + priv->temperature = 0; + if (!priv->thermal_throttle.advanced_tt) + iwl_legacy_tt_handler(priv, + IWL_REDUCED_PERFORMANCE_THRESHOLD_2, + true); + else + iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD, + true); + } +} + +void iwl_tt_enter_ct_kill(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); + queue_work(priv->workqueue, &priv->ct_enter); +} + +void iwl_tt_exit_ct_kill(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); + queue_work(priv->workqueue, &priv->ct_exit); +} + +static void iwl_bg_tt_work(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); + s32 temp = priv->temperature; /* degrees CELSIUS except specified */ + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + if (priv->cfg->base_params->temperature_kelvin) + temp = KELVIN_TO_CELSIUS(priv->temperature); + + if (!priv->thermal_throttle.advanced_tt) + iwl_legacy_tt_handler(priv, temp, false); + else + iwl_advance_tt_handler(priv, temp, false); +} + +void iwl_tt_handler(struct iwl_priv *priv) +{ + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); + queue_work(priv->workqueue, &priv->tt_work); +} + +/* Thermal throttling initialization + * For advance thermal throttling: + * Initialize Thermal Index and temperature threshold table + * Initialize thermal throttling restriction table + */ +void iwl_tt_initialize(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); + struct iwl_tt_trans *transaction; + + IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n"); + + memset(tt, 0, sizeof(struct iwl_tt_mgmt)); + + tt->state = IWL_TI_0; + init_timer(&priv->thermal_throttle.ct_kill_exit_tm); + priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv; + priv->thermal_throttle.ct_kill_exit_tm.function = + iwl_tt_check_exit_ct_kill; + init_timer(&priv->thermal_throttle.ct_kill_waiting_tm); + priv->thermal_throttle.ct_kill_waiting_tm.data = + (unsigned long)priv; + priv->thermal_throttle.ct_kill_waiting_tm.function = + iwl_tt_ready_for_ct_kill; + /* setup deferred ct kill work */ + INIT_WORK(&priv->tt_work, iwl_bg_tt_work); + INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); + INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); + + if (priv->cfg->base_params->adv_thermal_throttle) { + IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); + tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * + IWL_TI_STATE_MAX, GFP_KERNEL); + tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) * + IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1), + GFP_KERNEL); + if (!tt->restriction || !tt->transaction) { + IWL_ERR(priv, "Fallback to Legacy Throttling\n"); + priv->thermal_throttle.advanced_tt = false; + kfree(tt->restriction); + tt->restriction = NULL; + kfree(tt->transaction); + tt->transaction = NULL; + } else { + transaction = tt->transaction + + (IWL_TI_0 * (IWL_TI_STATE_MAX - 1)); + memcpy(transaction, &tt_range_0[0], size); + transaction = tt->transaction + + (IWL_TI_1 * (IWL_TI_STATE_MAX - 1)); + memcpy(transaction, &tt_range_1[0], size); + transaction = tt->transaction + + (IWL_TI_2 * (IWL_TI_STATE_MAX - 1)); + memcpy(transaction, &tt_range_2[0], size); + transaction = tt->transaction + + (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1)); + memcpy(transaction, &tt_range_3[0], size); + size = sizeof(struct iwl_tt_restriction) * + IWL_TI_STATE_MAX; + memcpy(tt->restriction, + &restriction_range[0], size); + priv->thermal_throttle.advanced_tt = true; + } + } else { + IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); + priv->thermal_throttle.advanced_tt = false; + } +} + +/* cleanup thermal throttling management related memory and timer */ +void iwl_tt_exit(struct iwl_priv *priv) +{ + struct iwl_tt_mgmt *tt = &priv->thermal_throttle; + + /* stop ct_kill_exit_tm timer if activated */ + del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm); + /* stop ct_kill_waiting_tm timer if activated */ + del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); + cancel_work_sync(&priv->tt_work); + cancel_work_sync(&priv->ct_enter); + cancel_work_sync(&priv->ct_exit); + + if (priv->thermal_throttle.advanced_tt) { + /* free advance thermal throttling memory */ + kfree(tt->restriction); + tt->restriction = NULL; + kfree(tt->transaction); + tt->transaction = NULL; + } +} diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h new file mode 100644 index 0000000000000000000000000000000000000000..d55060427cace536cd7917492dbf1f4800a08fcd --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved. + * + * Portions of this file are derived from the ipw3945 project, as well + * as portions of the ieee80211 subsystem header files. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + *****************************************************************************/ +#ifndef __iwl_tt_setting_h__ +#define __iwl_tt_setting_h__ + +#include "iwl-commands.h" + +#define IWL_ABSOLUTE_ZERO 0 +#define IWL_ABSOLUTE_MAX 0xFFFFFFFF +#define IWL_TT_INCREASE_MARGIN 5 +#define IWL_TT_CT_KILL_MARGIN 3 + +enum iwl_antenna_ok { + IWL_ANT_OK_NONE, + IWL_ANT_OK_SINGLE, + IWL_ANT_OK_MULTI, +}; + +/* Thermal Throttling State Machine states */ +enum iwl_tt_state { + IWL_TI_0, /* normal temperature, system power state */ + IWL_TI_1, /* high temperature detect, low power state */ + IWL_TI_2, /* higher temperature detected, lower power state */ + IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */ + IWL_TI_STATE_MAX +}; + +/** + * struct iwl_tt_restriction - Thermal Throttling restriction table + * @tx_stream: number of tx stream allowed + * @is_ht: ht enable/disable + * @rx_stream: number of rx stream allowed + * + * This table is used by advance thermal throttling management + * based on the current thermal throttling state, and determines + * the number of tx/rx streams and the status of HT operation. + */ +struct iwl_tt_restriction { + enum iwl_antenna_ok tx_stream; + enum iwl_antenna_ok rx_stream; + bool is_ht; +}; + +/** + * struct iwl_tt_trans - Thermal Throttling transaction table + * @next_state: next thermal throttling mode + * @tt_low: low temperature threshold to change state + * @tt_high: high temperature threshold to change state + * + * This is used by the advanced thermal throttling algorithm + * to determine the next thermal state to go based on the + * current temperature. + */ +struct iwl_tt_trans { + enum iwl_tt_state next_state; + u32 tt_low; + u32 tt_high; +}; + +/** + * struct iwl_tt_mgnt - Thermal Throttling Management structure + * @advanced_tt: advanced thermal throttle required + * @state: current Thermal Throttling state + * @tt_power_mode: Thermal Throttling power mode index + * being used to set power level when + * when thermal throttling state != IWL_TI_0 + * the tt_power_mode should set to different + * power mode based on the current tt state + * @tt_previous_temperature: last measured temperature + * @iwl_tt_restriction: ptr to restriction tbl, used by advance + * thermal throttling to determine how many tx/rx streams + * should be used in tt state; and can HT be enabled or not + * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling + * state transaction + * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature + * @ct_kill_exit_tm: timer to exit thermal kill + */ +struct iwl_tt_mgmt { + enum iwl_tt_state state; + bool advanced_tt; + u8 tt_power_mode; + bool ct_kill_toggle; +#ifdef CONFIG_IWLWIFI_DEBUG + s32 tt_previous_temp; +#endif + struct iwl_tt_restriction *restriction; + struct iwl_tt_trans *transaction; + struct timer_list ct_kill_exit_tm; + struct timer_list ct_kill_waiting_tm; +}; + +u8 iwl_tt_current_power_mode(struct iwl_priv *priv); +bool iwl_tt_is_low_power_state(struct iwl_priv *priv); +bool iwl_ht_enabled(struct iwl_priv *priv); +bool iwl_check_for_ct_kill(struct iwl_priv *priv); +enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv); +enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv); +void iwl_tt_enter_ct_kill(struct iwl_priv *priv); +void iwl_tt_exit_ct_kill(struct iwl_priv *priv); +void iwl_tt_handler(struct iwl_priv *priv); +void iwl_tt_initialize(struct iwl_priv *priv); +void iwl_tt_exit(struct iwl_priv *priv); + +#endif /* __iwl_tt_setting_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 69155aa448fb80f8c042b212567679b905e20513..db57aea629d93857e6a3b068ce74059b87c0d771 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -71,18 +71,6 @@ static const u8 tid_to_ac[] = { 2, 3, 3, 2, 1, 1, 0, 0 }; -static const u8 ac_to_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, -}; - -static inline int get_fifo_from_ac(u8 ac) -{ - return ac_to_fifo[ac]; -} - static inline int get_ac_from_tid(u16 tid) { if (likely(tid < ARRAY_SIZE(tid_to_ac))) @@ -92,10 +80,10 @@ static inline int get_ac_from_tid(u16 tid) return -EINVAL; } -static inline int get_fifo_from_tid(u16 tid) +static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid) { if (likely(tid < ARRAY_SIZE(tid_to_ac))) - return get_fifo_from_ac(tid_to_ac[tid]); + return ctx->ac_to_fifo[tid_to_ac[tid]]; /* no support for TIDs 8-15 yet */ return -EINVAL; @@ -118,7 +106,7 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv, WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); - if (txq_id != IWL_CMD_QUEUE_NUM) { + if (txq_id != priv->cmd_queue) { sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id; sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl; @@ -155,7 +143,7 @@ void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); - if (txq_id != IWL_CMD_QUEUE_NUM) + if (txq_id != priv->cmd_queue) sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; bc_ent = cpu_to_le16(1 | (sta_id << 12)); @@ -236,13 +224,13 @@ int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int ret; if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || - (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues - <= txq_id)) { + (IWLAGN_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { IWL_WARN(priv, "queue number out of range: %d, must be %d to %d\n", txq_id, IWLAGN_FIRST_AMPDU_QUEUE, IWLAGN_FIRST_AMPDU_QUEUE + - priv->cfg->num_of_ampdu_queues - 1); + priv->cfg->base_params->num_of_ampdu_queues - 1); return -EINVAL; } @@ -298,13 +286,13 @@ int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, u8 tx_fifo) { if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || - (IWLAGN_FIRST_AMPDU_QUEUE + priv->cfg->num_of_ampdu_queues - <= txq_id)) { + (IWLAGN_FIRST_AMPDU_QUEUE + + priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { IWL_ERR(priv, "queue number out of range: %d, must be %d to %d\n", txq_id, IWLAGN_FIRST_AMPDU_QUEUE, IWLAGN_FIRST_AMPDU_QUEUE + - priv->cfg->num_of_ampdu_queues - 1); + priv->cfg->base_params->num_of_ampdu_queues - 1); return -EINVAL; } @@ -333,19 +321,15 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask) iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask); } -static inline int get_queue_from_ac(u16 ac) -{ - return ac; -} - /* * handle build REPLY_TX command notification. */ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, - struct iwl_tx_cmd *tx_cmd, - struct ieee80211_tx_info *info, - struct ieee80211_hdr *hdr, - u8 std_id) + struct sk_buff *skb, + struct iwl_tx_cmd *tx_cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, + u8 std_id) { __le16 fc = hdr->frame_control; __le32 tx_flags = tx_cmd->tx_flags; @@ -365,6 +349,13 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, if (ieee80211_is_back_req(fc)) tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; + else if (info->band == IEEE80211_BAND_2GHZ && + priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) || + ieee80211_is_reassoc_req(fc) || + skb->protocol == cpu_to_be16(ETH_P_PAE))) + tx_flags |= TX_CMD_FLG_IGNORE_BT; tx_cmd->sta_id = std_id; @@ -454,7 +445,14 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv, rate_flags |= RATE_MCS_CCK_MSK; /* Set up antennas */ - priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_full_concurrent) { + /* operated as 1x1 in full concurrency mode */ + priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, + first_antenna(priv->hw_params.valid_tx_ant)); + } else + priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, priv->hw_params.valid_tx_ant); rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); @@ -470,8 +468,8 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, { struct ieee80211_key_conf *keyconf = info->control.hw_key; - switch (keyconf->alg) { - case ALG_CCMP: + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: tx_cmd->sec_ctl = TX_CMD_SEC_CCM; memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); if (info->flags & IEEE80211_TX_CTL_AMPDU) @@ -479,20 +477,20 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; ieee80211_get_tkip_key(keyconf, skb_frag, IEEE80211_TKIP_P2_KEY, tx_cmd->key); IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); break; - case ALG_WEP: + case WLAN_CIPHER_SUITE_WEP104: + tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; + /* fall through */ + case WLAN_CIPHER_SUITE_WEP40: tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP | (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT); - if (keyconf->keylen == WEP_KEY_LEN_128) - tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; - memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen); IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " @@ -500,7 +498,7 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, break; default: - IWL_ERR(priv, "Unknown encode alg %d\n", keyconf->alg); + IWL_ERR(priv, "Unknown encode cipher %x\n", keyconf->cipher); break; } } @@ -519,6 +517,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; struct iwl_tx_cmd *tx_cmd; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; int swq_id, txq_id; dma_addr_t phys_addr; dma_addr_t txcmd_phys; @@ -533,6 +532,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) u8 *qc = NULL; unsigned long flags; + if (info->control.vif) + ctx = iwl_rxon_ctx_from_vif(info->control.vif); + spin_lock_irqsave(&priv->lock, flags); if (iwl_is_rfkill(priv)) { IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); @@ -553,7 +555,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); + sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -565,8 +567,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) if (sta) sta_priv = (void *)sta->drv_priv; - if (sta_priv && sta_id != priv->hw_params.bcast_sta_id && - sta_priv->asleep) { + if (sta_priv && sta_priv->asleep) { WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)); /* * This sends an asynchronous command to the device, @@ -580,7 +581,20 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); } - txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); + /* + * Send this frame after DTIM -- there's a special queue + * reserved for this for contexts that support AP mode. + */ + if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { + txq_id = ctx->mcast_queue; + /* + * The microcode will clear the more data + * bit in the last frame it transmits. + */ + hdr->frame_control |= + cpu_to_le16(IEEE80211_FCTL_MOREDATA); + } else + txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; /* irqs already disabled/saved above when locking priv->lock */ spin_lock(&priv->sta_lock); @@ -625,6 +639,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); txq->txb[q->write_ptr].skb = skb; + txq->txb[q->write_ptr].ctx = ctx; /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[q->write_ptr]; @@ -655,7 +670,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); /* TODO need this for burst mode later on */ - iwlagn_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id); + iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id); iwl_dbg_log_tx_data_frame(priv, len, hdr); iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc); @@ -813,7 +828,7 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv) /* Tx queues */ if (priv->txq) { for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) - if (txq_id == IWL_CMD_QUEUE_NUM) + if (txq_id == priv->cmd_queue) iwl_cmd_queue_free(priv); else iwl_tx_queue_free(priv, txq_id); @@ -870,9 +885,9 @@ int iwlagn_txq_ctx_alloc(struct iwl_priv *priv) spin_unlock_irqrestore(&priv->lock, flags); - /* Alloc and init all Tx queues, including the command queue (#4) */ + /* Alloc and init all Tx queues, including the command queue (#4/#9) */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? + slots_num = (txq_id == priv->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, txq_id); @@ -910,7 +925,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv) /* Alloc and init all Tx queues, including the command queue (#4) */ for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { - slots_num = txq_id == IWL_CMD_QUEUE_NUM ? + slots_num = txq_id == priv->cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); } @@ -968,7 +983,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, unsigned long flags; struct iwl_tid_data *tid_data; - tx_fifo = get_fifo_from_tid(tid); + tx_fifo = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid); if (unlikely(tx_fifo < 0)) return tx_fifo; @@ -1024,12 +1039,12 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, struct ieee80211_sta *sta, u16 tid) { - int tx_fifo_id, txq_id, sta_id, ssn = -1; + int tx_fifo_id, txq_id, sta_id, ssn; struct iwl_tid_data *tid_data; int write_ptr, read_ptr; unsigned long flags; - tx_fifo_id = get_fifo_from_tid(tid); + tx_fifo_id = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid); if (unlikely(tx_fifo_id < 0)) return tx_fifo_id; @@ -1042,21 +1057,26 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, spin_lock_irqsave(&priv->sta_lock, flags); - if (priv->stations[sta_id].tid[tid].agg.state == - IWL_EMPTYING_HW_QUEUE_ADDBA) { - IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; - spin_unlock_irqrestore(&priv->sta_lock, flags); - return 0; - } - - if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) - IWL_WARN(priv, "Stopping AGG while state not ON or starting\n"); - tid_data = &priv->stations[sta_id].tid[tid]; ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; txq_id = tid_data->agg.txq_id; + + switch (priv->stations[sta_id].tid[tid].agg.state) { + case IWL_EMPTYING_HW_QUEUE_ADDBA: + /* + * This can happen if the peer stops aggregation + * again before we've had a chance to drain the + * queue we selected previously, i.e. before the + * session was really started completely. + */ + IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); + goto turn_off; + case IWL_AGG_ON: + break; + default: + IWL_WARN(priv, "Stopping AGG while state not ON or starting\n"); + } + write_ptr = priv->txq[txq_id].q.write_ptr; read_ptr = priv->txq[txq_id].q.read_ptr; @@ -1070,6 +1090,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, } IWL_DEBUG_HT(priv, "HW queue is empty\n"); + turn_off: priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; /* do not restore/save irqs */ @@ -1098,6 +1119,9 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, struct iwl_queue *q = &priv->txq[txq_id].q; u8 *addr = priv->stations[sta_id].sta.sta.addr; struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; + struct iwl_rxon_context *ctx; + + ctx = &priv->contexts[priv->stations[sta_id].ctxid]; lockdep_assert_held(&priv->sta_lock); @@ -1108,12 +1132,12 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, if ((txq_id == tid_data->agg.txq_id) && (q->read_ptr == q->write_ptr)) { u16 ssn = SEQ_TO_SN(tid_data->seq_number); - int tx_fifo = get_fifo_from_tid(tid); + int tx_fifo = get_fifo_from_tid(ctx, tid); IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, tx_fifo); tid_data->agg.state = IWL_AGG_OFF; - ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid); + ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid); } break; case IWL_EMPTYING_HW_QUEUE_ADDBA: @@ -1121,7 +1145,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, if (tid_data->tfds_in_queue == 0) { IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n"); tid_data->agg.state = IWL_AGG_ON; - ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid); + ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid); } break; } @@ -1129,14 +1153,14 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, return 0; } -static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) +static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data; struct ieee80211_sta *sta; struct iwl_station_priv *sta_priv; rcu_read_lock(); - sta = ieee80211_find_sta(priv->vif, hdr->addr1); + sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1); if (sta) { sta_priv = (void *)sta->drv_priv; /* avoid atomic ops if this isn't a client */ @@ -1146,7 +1170,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) } rcu_read_unlock(); - ieee80211_tx_status_irqsafe(priv->hw, skb); + ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb); } int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) @@ -1169,7 +1193,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { tx_info = &txq->txb[txq->q.read_ptr]; - iwlagn_tx_status(priv, tx_info->skb); + iwlagn_tx_status(priv, tx_info); hdr = (struct ieee80211_hdr *)tx_info->skb->data; if (hdr && ieee80211_is_data_qos(hdr->frame_control)) @@ -1367,3 +1391,43 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, spin_unlock_irqrestore(&priv->sta_lock, flags); } + +#ifdef CONFIG_IWLWIFI_DEBUG +const char *iwl_get_tx_fail_reason(u32 status) +{ +#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x +#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x + + switch (status & TX_STATUS_MSK) { + case TX_STATUS_SUCCESS: + return "SUCCESS"; + TX_STATUS_POSTPONE(DELAY); + TX_STATUS_POSTPONE(FEW_BYTES); + TX_STATUS_POSTPONE(BT_PRIO); + TX_STATUS_POSTPONE(QUIET_PERIOD); + TX_STATUS_POSTPONE(CALC_TTAK); + TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY); + TX_STATUS_FAIL(SHORT_LIMIT); + TX_STATUS_FAIL(LONG_LIMIT); + TX_STATUS_FAIL(FIFO_UNDERRUN); + TX_STATUS_FAIL(DRAIN_FLOW); + TX_STATUS_FAIL(RFKILL_FLUSH); + TX_STATUS_FAIL(LIFE_EXPIRE); + TX_STATUS_FAIL(DEST_PS); + TX_STATUS_FAIL(HOST_ABORTED); + TX_STATUS_FAIL(BT_RETRY); + TX_STATUS_FAIL(STA_INVALID); + TX_STATUS_FAIL(FRAG_DROPPED); + TX_STATUS_FAIL(TID_DISABLE); + TX_STATUS_FAIL(FIFO_FLUSHED); + TX_STATUS_FAIL(INSUFFICIENT_CF_POLL); + TX_STATUS_FAIL(PASSIVE_NO_RX); + TX_STATUS_FAIL(NO_BEACON_ON_RADAR); + } + + return "UNKNOWN"; + +#undef TX_STATUS_FAIL +#undef TX_STATUS_POSTPONE +} +#endif /* CONFIG_IWLWIFI_DEBUG */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c index 6f77441cb65a3f734260e23b1a38a08574d4a668..703621107dac8cbcb7f10a5f1265576c169fb48b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c @@ -38,6 +38,7 @@ #include "iwl-helpers.h" #include "iwl-agn-hw.h" #include "iwl-agn.h" +#include "iwl-agn-calib.h" static const s8 iwlagn_default_queue_to_tx_fifo[] = { IWL_TX_FIFO_VO, @@ -52,6 +53,19 @@ static const s8 iwlagn_default_queue_to_tx_fifo[] = { IWL_TX_FIFO_UNUSED, }; +static const s8 iwlagn_ipan_queue_to_tx_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, + IWL_TX_FIFO_BK_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWL_TX_FIFO_VI_IPAN, + IWL_TX_FIFO_VO_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWLAGN_CMD_FIFO_NUM, +}; + static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP, 0, COEX_UNASSOC_IDLE_FLAGS}, @@ -201,6 +215,25 @@ static int iwlagn_set_Xtal_calib(struct iwl_priv *priv) (u8 *)&cmd, sizeof(cmd)); } +static int iwlagn_set_temperature_offset_calib(struct iwl_priv *priv) +{ + struct iwl_calib_temperature_offset_cmd cmd; + __le16 *offset_calib = + (__le16 *)iwl_eeprom_query_addr(priv, EEPROM_5000_TEMPERATURE); + cmd.hdr.op_code = IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD; + cmd.hdr.first_group = 0; + cmd.hdr.groups_num = 1; + cmd.hdr.data_valid = 1; + cmd.radio_sensor_offset = le16_to_cpu(offset_calib[1]); + if (!(cmd.radio_sensor_offset)) + cmd.radio_sensor_offset = DEFAULT_RADIO_SENSOR_OFFSET; + cmd.reserved = 0; + IWL_DEBUG_CALIB(priv, "Radio sensor offset: %d\n", + cmd.radio_sensor_offset); + return iwl_calib_set(&priv->calib_results[IWL_CALIB_TEMP_OFFSET], + (u8 *)&cmd, sizeof(cmd)); +} + static int iwlagn_send_calib_cfg(struct iwl_priv *priv) { struct iwl_calib_cfg_cmd calib_cfg_cmd; @@ -294,7 +327,27 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) goto restart; } + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + /* + * Tell uCode we are ready to perform calibration + * need to perform this before any calibration + * no need to close the envlope since we are going + * to load the runtime uCode later. + */ + iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + + } iwlagn_send_calib_cfg(priv); + + /** + * temperature offset calibration is only needed for runtime ucode, + * so prepare the value now. + */ + if (priv->cfg->need_temp_offset_calib) + iwlagn_set_temperature_offset_calib(priv); + return; restart: @@ -306,7 +359,7 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv) { struct iwl_wimax_coex_cmd coex_cmd; - if (priv->cfg->support_wimax_coexist) { + if (priv->cfg->base_params->support_wimax_coexist) { /* UnMask wake up src at associated sleep */ coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK; @@ -329,8 +382,54 @@ static int iwlagn_send_wimax_coex(struct iwl_priv *priv) sizeof(coex_cmd), &coex_cmd); } +static const u8 iwlagn_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { + ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_LOW << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_HIGH << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (1 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_BYPASS << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_COEX_OFF << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + ((BT_COEX_PRIO_TBL_PRIO_COEX_ON << IWL_BT_COEX_PRIO_TBL_PRIO_POS) | + (0 << IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS)), + 0, 0, 0, 0, 0, 0, 0 +}; + +void iwlagn_send_prio_tbl(struct iwl_priv *priv) +{ + struct iwl_bt_coex_prio_table_cmd prio_tbl_cmd; + + memcpy(prio_tbl_cmd.prio_tbl, iwlagn_bt_prio_tbl, + sizeof(iwlagn_bt_prio_tbl)); + if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PRIO_TABLE, + sizeof(prio_tbl_cmd), &prio_tbl_cmd)) + IWL_ERR(priv, "failed to send BT prio tbl command\n"); +} + +void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) +{ + struct iwl_bt_coex_prot_env_cmd env_cmd; + + env_cmd.action = action; + env_cmd.type = type; + if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, + sizeof(env_cmd), &env_cmd)) + IWL_ERR(priv, "failed to send BT env command\n"); +} + + int iwlagn_alive_notify(struct iwl_priv *priv) { + const s8 *queues; u32 a; unsigned long flags; int i, chan; @@ -365,7 +464,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv) reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); iwl_write_prph(priv, IWLAGN_SCD_QUEUECHAIN_SEL, - IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv->hw_params.max_txq_num)); + IWLAGN_SCD_QUEUECHAIN_SEL_ALL(priv)); iwl_write_prph(priv, IWLAGN_SCD_AGGR_SEL, 0); /* initiate the queues */ @@ -391,7 +490,13 @@ int iwlagn_alive_notify(struct iwl_priv *priv) /* Activate all Tx DMA/FIFO channels */ priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7)); - iwlagn_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0); + /* map queues to FIFOs */ + if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) + queues = iwlagn_ipan_queue_to_tx_fifo; + else + queues = iwlagn_default_queue_to_tx_fifo; + + iwlagn_set_wr_ptrs(priv, priv->cmd_queue, 0); /* make sure all queue are not stopped */ memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped)); @@ -400,11 +505,12 @@ int iwlagn_alive_notify(struct iwl_priv *priv) /* reset to 0 to enable all the queue first */ priv->txq_ctx_active_msk = 0; - /* map qos queues to fifos one-to-one */ + BUILD_BUG_ON(ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo) != 10); + BUILD_BUG_ON(ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo) != 10); - for (i = 0; i < ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); i++) { - int ac = iwlagn_default_queue_to_tx_fifo[i]; + for (i = 0; i < 10; i++) { + int ac = queues[i]; iwl_txq_ctx_activate(priv, i); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 10d7b9b7f064f529af9d0cdc6aa2b0a144d9438d..c2636a7ab9eed9840f1fe0ec0aa466ec610aee57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,7 @@ #include "iwl-io.h" #include "iwl-helpers.h" #include "iwl-sta.h" -#include "iwl-calib.h" +#include "iwl-agn-calib.h" #include "iwl-agn.h" @@ -86,29 +87,36 @@ MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); MODULE_LICENSE("GPL"); MODULE_ALIAS("iwl4965"); +static int iwlagn_ant_coupling; +static bool iwlagn_bt_ch_announce = 1; + /** - * iwl_commit_rxon - commit staging_rxon to hardware + * iwlagn_commit_rxon - commit staging_rxon to hardware * * The RXON command in staging_rxon is committed to the hardware and * the active_rxon structure is updated with the new data. This * function correctly transitions out of the RXON_ASSOC_MSK state if * a HW tune is required based on the RXON structure changes. */ -int iwl_commit_rxon(struct iwl_priv *priv) +int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { /* cast away the const for active_rxon in this function */ - struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; + struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active; int ret; bool new_assoc = - !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); + !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK); + bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK); if (!iwl_is_alive(priv)) return -EBUSY; + if (!ctx->is_active) + return 0; + /* always get timestamp with Rx frame */ - priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; + ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK; - ret = iwl_check_rxon_cmd(priv); + ret = iwl_check_rxon_cmd(priv, ctx); if (ret) { IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); return -EINVAL; @@ -119,7 +127,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) * abort any previous channel switch if still in process */ if (priv->switch_rxon.switch_in_progress && - (priv->switch_rxon.channel != priv->staging_rxon.channel)) { + (priv->switch_rxon.channel != ctx->staging.channel)) { IWL_DEBUG_11H(priv, "abort channel switch on %d\n", le16_to_cpu(priv->switch_rxon.channel)); iwl_chswitch_done(priv, false); @@ -128,15 +136,15 @@ int iwl_commit_rxon(struct iwl_priv *priv) /* If we don't need to send a full RXON, we can use * iwl_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ - if (!iwl_full_rxon_required(priv)) { - ret = iwl_send_rxon_assoc(priv); + if (!iwl_full_rxon_required(priv, ctx)) { + ret = iwl_send_rxon_assoc(priv, ctx); if (ret) { IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); return ret; } - memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); - iwl_print_rx_config_cmd(priv); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_print_rx_config_cmd(priv, ctx); return 0; } @@ -144,13 +152,13 @@ int iwl_commit_rxon(struct iwl_priv *priv) * an RXON_ASSOC and the new config wants the associated mask enabled, * we must clear the associated from the active configuration * before we apply the new config */ - if (iwl_is_associated(priv) && new_assoc) { + if (iwl_is_associated_ctx(ctx) && new_assoc) { IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; - ret = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), - &priv->active_rxon); + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), + active_rxon); /* If the mask clearing failed then we set * active_rxon back to what it was previously */ @@ -159,9 +167,9 @@ int iwl_commit_rxon(struct iwl_priv *priv) IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); return ret; } - iwl_clear_ucode_stations(priv); - iwl_restore_stations(priv); - ret = iwl_restore_default_wep_keys(priv); + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); if (ret) { IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); return ret; @@ -173,47 +181,65 @@ int iwl_commit_rxon(struct iwl_priv *priv) "* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"), - le16_to_cpu(priv->staging_rxon.channel), - priv->staging_rxon.bssid_addr); + le16_to_cpu(ctx->staging.channel), + ctx->staging.bssid_addr); + + iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); - iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); + if (!old_assoc) { + /* + * First of all, before setting associated, we need to + * send RXON timing so the device knows about the DTIM + * period and other timing values + */ + ret = iwl_send_rxon_timing(priv, ctx); + if (ret) { + IWL_ERR(priv, "Error setting RXON timing!\n"); + return ret; + } + } + + if (priv->cfg->ops->hcmd->set_pan_params) { + ret = priv->cfg->ops->hcmd->set_pan_params(priv); + if (ret) + return ret; + } /* Apply the new configuration * RXON unassoc clears the station table in uCode so restoration of * stations is needed after it (the RXON command) completes */ if (!new_assoc) { - ret = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); return ret; } IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); - memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); - iwl_clear_ucode_stations(priv); - iwl_restore_stations(priv); - ret = iwl_restore_default_wep_keys(priv); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); + iwl_clear_ucode_stations(priv, ctx); + iwl_restore_stations(priv, ctx); + ret = iwl_restore_default_wep_keys(priv, ctx); if (ret) { IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); return ret; } } - - priv->start_calib = 0; if (new_assoc) { + priv->start_calib = 0; /* Apply the new configuration * RXON assoc doesn't clear the station table in uCode, */ - ret = iwl_send_cmd_pdu(priv, REPLY_RXON, - sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); + ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, + sizeof(struct iwl_rxon_cmd), &ctx->staging); if (ret) { IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); return ret; } - memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); + memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); } - iwl_print_rx_config_cmd(priv); + iwl_print_rx_config_cmd(priv, ctx); iwl_init_sensitivity(priv); @@ -230,10 +256,14 @@ int iwl_commit_rxon(struct iwl_priv *priv) void iwl_update_chain_flags(struct iwl_priv *priv) { + struct iwl_rxon_context *ctx; - if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); - iwlcore_commit_rxon(priv); + if (priv->cfg->ops->hcmd->set_rxon_chain) { + for_each_context(priv, ctx) { + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlcore_commit_rxon(priv, ctx); + } + } } static void iwl_clear_free_frames(struct iwl_priv *priv) @@ -284,24 +314,26 @@ static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame) } static u32 iwl_fill_beacon_frame(struct iwl_priv *priv, - struct ieee80211_hdr *hdr, - int left) + struct ieee80211_hdr *hdr, + int left) { - if (!priv->ibss_beacon) + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_skb) return 0; - if (priv->ibss_beacon->len > left) + if (priv->beacon_skb->len > left) return 0; - memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len); + memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); - return priv->ibss_beacon->len; + return priv->beacon_skb->len; } /* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */ static void iwl_set_beacon_tim(struct iwl_priv *priv, - struct iwl_tx_beacon_cmd *tx_beacon_cmd, - u8 *beacon, u32 frame_size) + struct iwl_tx_beacon_cmd *tx_beacon_cmd, + u8 *beacon, u32 frame_size) { u16 tim_idx; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon; @@ -337,6 +369,13 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, * beacon contents. */ + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_ctx) { + IWL_ERR(priv, "trying to build beacon w/o beacon context!\n"); + return 0; + } + /* Initialize memory */ tx_beacon_cmd = &frame->u.beacon; memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); @@ -346,20 +385,22 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv, sizeof(frame->u) - sizeof(*tx_beacon_cmd)); if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE)) return 0; + if (!frame_size) + return 0; /* Set up TX command fields */ tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); - tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; + tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id; tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; /* Set up TX beacon command fields */ iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame, - frame_size); + frame_size); /* Set up packet rate and flags */ - rate = iwl_rate_get_lowest_plcp(priv); + rate = iwl_rate_get_lowest_plcp(priv, priv->beacon_ctx); priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, priv->hw_params.valid_tx_ant); rate_flags = iwl_ant_idx_to_flags(priv->mgmt_tx_ant); @@ -592,23 +633,83 @@ static void iwl_bg_beacon_update(struct work_struct *work) container_of(work, struct iwl_priv, beacon_update); struct sk_buff *beacon; - /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ - beacon = ieee80211_beacon_get(priv->hw, priv->vif); + mutex_lock(&priv->mutex); + if (!priv->beacon_ctx) { + IWL_ERR(priv, "updating beacon w/o beacon context!\n"); + goto out; + } + + if (priv->beacon_ctx->vif->type != NL80211_IFTYPE_AP) { + /* + * The ucode will send beacon notifications even in + * IBSS mode, but we don't want to process them. But + * we need to defer the type check to here due to + * requiring locking around the beacon_ctx access. + */ + goto out; + } + /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ + beacon = ieee80211_beacon_get(priv->hw, priv->beacon_ctx->vif); if (!beacon) { - IWL_ERR(priv, "update beacon failed\n"); - return; + IWL_ERR(priv, "update beacon failed -- keeping old\n"); + goto out; } - mutex_lock(&priv->mutex); /* new beacon skb is allocated every time; dispose previous.*/ - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + dev_kfree_skb(priv->beacon_skb); - priv->ibss_beacon = beacon; - mutex_unlock(&priv->mutex); + priv->beacon_skb = beacon; iwl_send_beacon_cmd(priv); + out: + mutex_unlock(&priv->mutex); +} + +static void iwl_bg_bt_runtime_config(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, bt_runtime_config); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* dont send host command if rf-kill is on */ + if (!iwl_is_ready_rf(priv)) + return; + priv->cfg->ops->hcmd->send_bt_config(priv); +} + +static void iwl_bg_bt_full_concurrency(struct work_struct *work) +{ + struct iwl_priv *priv = + container_of(work, struct iwl_priv, bt_full_concurrency); + struct iwl_rxon_context *ctx; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + /* dont send host command if rf-kill is on */ + if (!iwl_is_ready_rf(priv)) + return; + + IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", + priv->bt_full_concurrent ? + "full concurrency" : "3-wire"); + + /* + * LQ & RXON updated cmds must be sent before BT Config cmd + * to avoid 3-wire collisions + */ + mutex_lock(&priv->mutex); + for_each_context(priv, ctx) { + if (priv->cfg->ops->hcmd->set_rxon_chain) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); + iwlcore_commit_rxon(priv, ctx); + } + mutex_unlock(&priv->mutex); + + priv->cfg->ops->hcmd->send_bt_config(priv); } /** @@ -763,10 +864,10 @@ static void iwl_bg_ucode_trace(unsigned long data) static void iwl_rx_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl4965_beacon_notif *beacon = (struct iwl4965_beacon_notif *)pkt->u.raw; +#ifdef CONFIG_IWLWIFI_DEBUG u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " @@ -778,8 +879,9 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv, le32_to_cpu(beacon->low_tsf), rate); #endif - if ((priv->iw_mode == NL80211_IFTYPE_AP) && - (!test_bit(STATUS_EXIT_PENDING, &priv->status))) + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) queue_work(priv->workqueue, &priv->beacon_update); } @@ -836,22 +938,6 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv, wake_up_interruptible(&priv->wait_command_queue); } -int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) -{ - if (src == IWL_PWR_SRC_VAUX) { - if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VAUX, - ~APMG_PS_CTRL_MSK_PWR_SRC); - } else { - iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG, - APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, - ~APMG_PS_CTRL_MSK_PWR_SRC); - } - - return 0; -} - static void iwl_bg_tx_flush(struct work_struct *work) { struct iwl_priv *priv = @@ -1181,7 +1267,6 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv) IWL_ERR(priv, "Microcode SW error detected. " " Restarting 0x%X.\n", inta); priv->isr_stats.sw++; - priv->isr_stats.sw_err = inta; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } @@ -1362,7 +1447,6 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) IWL_ERR(priv, "Microcode SW error detected. " " Restarting 0x%X.\n", inta); priv->isr_stats.sw++; - priv->isr_stats.sw_err = inta; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } @@ -1650,30 +1734,44 @@ static void iwl_nic_start(struct iwl_priv *priv) struct iwlagn_ucode_capabilities { u32 max_probe_length; u32 standard_phy_calibration_size; + bool pan; }; static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); static int iwl_mac_setup_register(struct iwl_priv *priv, struct iwlagn_ucode_capabilities *capa); +#define UCODE_EXPERIMENTAL_INDEX 100 +#define UCODE_EXPERIMENTAL_TAG "exp" + static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) { const char *name_pre = priv->cfg->fw_name_pre; + char tag[8]; - if (first) + if (first) { +#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE + priv->fw_index = UCODE_EXPERIMENTAL_INDEX; + strcpy(tag, UCODE_EXPERIMENTAL_TAG); + } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { +#endif priv->fw_index = priv->cfg->ucode_api_max; - else + sprintf(tag, "%d", priv->fw_index); + } else { priv->fw_index--; + sprintf(tag, "%d", priv->fw_index); + } if (priv->fw_index < priv->cfg->ucode_api_min) { IWL_ERR(priv, "no suitable firmware found!\n"); return -ENOENT; } - sprintf(priv->firmware_name, "%s%d%s", - name_pre, priv->fw_index, ".ucode"); + sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); - IWL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n", + IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", + (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? "EXPERIMENTAL " : "", priv->firmware_name); return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, @@ -1874,6 +1972,11 @@ static int iwlagn_load_firmware(struct iwl_priv *priv, capa->max_probe_length = le32_to_cpup((__le32 *)tlv_data); break; + case IWL_UCODE_TLV_PAN: + if (tlv_len) + goto invalid_tlv_len; + capa->pan = true; + break; case IWL_UCODE_TLV_INIT_EVTLOG_PTR: if (tlv_len != sizeof(u32)) goto invalid_tlv_len; @@ -1962,14 +2065,16 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) struct iwlagn_ucode_capabilities ucode_capa = { .max_probe_length = 200, .standard_phy_calibration_size = - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE, + IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, }; memset(&pieces, 0, sizeof(pieces)); if (!ucode_raw) { - IWL_ERR(priv, "request for firmware file '%s' failed.\n", - priv->firmware_name); + if (priv->fw_index <= priv->cfg->ucode_api_max) + IWL_ERR(priv, + "request for firmware file '%s' failed.\n", + priv->firmware_name); goto try_again; } @@ -2002,21 +2107,28 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) * firmware filename ... but we don't check for that and only rely * on the API version read from firmware header from here on forward */ - if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(priv, "Driver unable to support your firmware API. " - "Driver supports v%u, firmware is v%u.\n", - api_max, api_ver); - goto try_again; - } + /* no api version check required for experimental uCode */ + if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, + "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + goto try_again; + } - if (api_ver != api_max) - IWL_ERR(priv, "Firmware has old API version. Expected v%u, " - "got v%u. New firmware can be obtained " - "from http://www.intellinuxwireless.org.\n", - api_max, api_ver); + if (api_ver != api_max) + IWL_ERR(priv, + "Firmware has old API version. Expected v%u, " + "got v%u. New firmware can be obtained " + "from http://www.intellinuxwireless.org.\n", + api_max, api_ver); + } if (build) - sprintf(buildstr, " build %u", build); + sprintf(buildstr, " build %u%s", build, + (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); else buildstr[0] = '\0'; @@ -2136,15 +2248,23 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) if (pieces.init_evtlog_size) priv->_agn.init_evtlog_size = (pieces.init_evtlog_size - 16)/12; else - priv->_agn.init_evtlog_size = priv->cfg->max_event_log_size; + priv->_agn.init_evtlog_size = + priv->cfg->base_params->max_event_log_size; priv->_agn.init_errlog_ptr = pieces.init_errlog_ptr; priv->_agn.inst_evtlog_ptr = pieces.inst_evtlog_ptr; if (pieces.inst_evtlog_size) priv->_agn.inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; else - priv->_agn.inst_evtlog_size = priv->cfg->max_event_log_size; + priv->_agn.inst_evtlog_size = + priv->cfg->base_params->max_event_log_size; priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; + if (ucode_capa.pan) { + priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); + priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; + } else + priv->sta_key_max_num = STA_KEY_MAX_NUM; + /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ @@ -2341,6 +2461,7 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) } desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); + priv->isr_stats.err_code = desc; pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32)); blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32)); blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32)); @@ -2543,6 +2664,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, return pos; } + /* enable/disable bt channel announcement */ + priv->bt_ch_announce = iwlagn_bt_ch_announce; + #ifdef CONFIG_IWLWIFI_DEBUG if (!(iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) && !full_log) size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES) @@ -2589,6 +2713,69 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, return pos; } +static void iwl_rf_kill_ct_config(struct iwl_priv *priv) +{ + struct iwl_ct_kill_config cmd; + struct iwl_ct_kill_throttling_config adv_cmd; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + spin_unlock_irqrestore(&priv->lock, flags); + priv->thermal_throttle.ct_kill_toggle = false; + + if (priv->cfg->base_params->support_ct_kill_exit) { + adv_cmd.critical_temperature_enter = + cpu_to_le32(priv->hw_params.ct_kill_threshold); + adv_cmd.critical_temperature_exit = + cpu_to_le32(priv->hw_params.ct_kill_exit_threshold); + + ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, + sizeof(adv_cmd), &adv_cmd); + if (ret) + IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); + else + IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " + "succeeded, " + "critical temperature enter is %d," + "exit is %d\n", + priv->hw_params.ct_kill_threshold, + priv->hw_params.ct_kill_exit_threshold); + } else { + cmd.critical_temperature_R = + cpu_to_le32(priv->hw_params.ct_kill_threshold); + + ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, + sizeof(cmd), &cmd); + if (ret) + IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); + else + IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " + "succeeded, " + "critical temperature is %d\n", + priv->hw_params.ct_kill_threshold); + } +} + +static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) +{ + struct iwl_calib_cfg_cmd calib_cfg_cmd; + struct iwl_host_cmd cmd = { + .id = CALIBRATION_CFG_CMD, + .len = sizeof(struct iwl_calib_cfg_cmd), + .data = &calib_cfg_cmd, + }; + + memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd)); + calib_cfg_cmd.ucd_calib_cfg.once.is_enable = IWL_CALIB_INIT_CFG_ALL; + calib_cfg_cmd.ucd_calib_cfg.once.start = cpu_to_le32(cfg); + + return iwl_send_cmd(priv, &cmd); +} + + /** * iwl_alive_start - called after REPLY_ALIVE notification received * from protocol/runtime uCode (initialization uCode's @@ -2597,6 +2784,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, static void iwl_alive_start(struct iwl_priv *priv) { int ret = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); @@ -2624,6 +2812,7 @@ static void iwl_alive_start(struct iwl_priv *priv) goto restart; } + /* After the ALIVE response, we can send host commands to the uCode */ set_bit(STATUS_ALIVE, &priv->status); @@ -2631,12 +2820,33 @@ static void iwl_alive_start(struct iwl_priv *priv) /* Enable timer to monitor the driver queues */ mod_timer(&priv->monitor_recover, jiffies + - msecs_to_jiffies(priv->cfg->monitor_recover_period)); + msecs_to_jiffies( + priv->cfg->base_params->monitor_recover_period)); } if (iwl_is_rfkill(priv)) return; + /* download priority table before any calibration request */ + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + /* Configure Bluetooth device coexistence support */ + priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; + priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; + priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; + priv->cfg->ops->hcmd->send_bt_config(priv); + priv->bt_valid = IWLAGN_BT_VALID_ENABLE_FLAGS; + iwlagn_send_prio_tbl(priv); + + /* FIXME: w/a to force change uCode BT state machine */ + iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + } + if (priv->hw_params.calib_rt_cfg) + iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); + ieee80211_wake_queues(priv->hw); priv->active_rate = IWL_RATES_MASK; @@ -2645,27 +2855,32 @@ static void iwl_alive_start(struct iwl_priv *priv) if (priv->cfg->ops->hcmd->set_tx_ant) priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant); - if (iwl_is_associated(priv)) { + if (iwl_is_associated_ctx(ctx)) { struct iwl_rxon_cmd *active_rxon = - (struct iwl_rxon_cmd *)&priv->active_rxon; + (struct iwl_rxon_cmd *)&ctx->active; /* apply any changes in staging */ - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { + struct iwl_rxon_context *tmp; /* Initialize our rx_config data */ - iwl_connection_init_rx_config(priv, NULL); + for_each_context(priv, tmp) + iwl_connection_init_rx_config(priv, tmp); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } - /* Configure Bluetooth device coexistence support */ - priv->cfg->ops->hcmd->send_bt_config(priv); + if (priv->cfg->bt_params && + !priv->cfg->bt_params->advanced_bt_coexist) { + /* Configure Bluetooth device coexistence support */ + priv->cfg->ops->hcmd->send_bt_config(priv); + } iwl_reset_run_time_calib(priv); /* Configure the adapter for unassociated operation */ - iwlcore_commit_rxon(priv); + iwlcore_commit_rxon(priv, ctx); /* At this point, the NIC is initialized and operational */ iwl_rf_kill_ct_config(priv); @@ -2695,13 +2910,30 @@ static void __iwl_down(struct iwl_priv *priv) IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); - if (!exit_pending) - set_bit(STATUS_EXIT_PENDING, &priv->status); + iwl_scan_cancel_timeout(priv, 200); - iwl_clear_ucode_stations(priv); - iwl_dealloc_bcast_station(priv); + exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); + + /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set + * to prevent rearm timer */ + if (priv->cfg->ops->lib->recover_from_tx_stall) + del_timer_sync(&priv->monitor_recover); + + iwl_clear_ucode_stations(priv, NULL); + iwl_dealloc_bcast_stations(priv); iwl_clear_driver_stations(priv); + /* reset BT coex data */ + priv->bt_status = 0; + if (priv->cfg->bt_params) + priv->bt_traffic_load = + priv->cfg->bt_params->bt_init_traffic_load; + else + priv->bt_traffic_load = 0; + priv->bt_sco_active = false; + priv->bt_full_concurrent = false; + priv->bt_ci_compliance = 0; + /* Unblock any waiting calls */ wake_up_interruptible_all(&priv->wait_command_queue); @@ -2759,14 +2991,13 @@ static void __iwl_down(struct iwl_priv *priv) iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); exit: memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - priv->ibss_beacon = NULL; + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = NULL; /* clear out any free frames */ iwl_clear_free_frames(priv); @@ -2834,6 +3065,7 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv) static int __iwl_up(struct iwl_priv *priv) { + struct iwl_rxon_context *ctx; int i; int ret; @@ -2847,9 +3079,13 @@ static int __iwl_up(struct iwl_priv *priv) return -EIO; } - ret = iwl_alloc_bcast_station(priv, true); - if (ret) - return ret; + for_each_context(priv, ctx) { + ret = iwlagn_alloc_bcast_station(priv, ctx); + if (ret) { + iwl_dealloc_bcast_stations(priv); + return ret; + } + } iwl_prepare_card_hw(priv); @@ -2874,6 +3110,12 @@ static int __iwl_up(struct iwl_priv *priv) iwl_write32(priv, CSR_INT, 0xFFFFFFFF); + /* must be initialised before iwl_hw_nic_init */ + if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)) + priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; + else + priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + ret = iwlagn_hw_nic_init(priv); if (ret) { IWL_ERR(priv, "Unable to init nic\n"); @@ -2980,7 +3222,8 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) } if (priv->start_calib) { - if (priv->cfg->bt_statistics) { + if (priv->cfg->bt_params && + priv->cfg->bt_params->bt_statistics) { iwl_chain_noise_calibration(priv, (void *)&priv->_agn.statistics_bt); iwl_sensitivity_calibration(priv, @@ -3004,11 +3247,42 @@ static void iwl_bg_restart(struct work_struct *data) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + struct iwl_rxon_context *ctx; + bool bt_sco, bt_full_concurrent; + u8 bt_ci_compliance; + u8 bt_load; + u8 bt_status; + mutex_lock(&priv->mutex); - priv->vif = NULL; + for_each_context(priv, ctx) + ctx->vif = NULL; priv->is_open = 0; + + /* + * __iwl_down() will clear the BT status variables, + * which is correct, but when we restart we really + * want to keep them so restore them afterwards. + * + * The restart process will later pick them up and + * re-configure the hw when we reconfigure the BT + * command. + */ + bt_sco = priv->bt_sco_active; + bt_full_concurrent = priv->bt_full_concurrent; + bt_ci_compliance = priv->bt_ci_compliance; + bt_load = priv->bt_traffic_load; + bt_status = priv->bt_status; + + __iwl_down(priv); + + priv->bt_sco_active = bt_sco; + priv->bt_full_concurrent = bt_full_concurrent; + priv->bt_ci_compliance = bt_ci_compliance; + priv->bt_traffic_load = bt_load; + priv->bt_status = bt_status; + mutex_unlock(&priv->mutex); - iwl_down(priv); + iwl_cancel_deferred_work(priv); ieee80211_restart_hw(priv->hw); } else { iwl_down(priv); @@ -3039,12 +3313,15 @@ static void iwl_bg_rx_replenish(struct work_struct *data) void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx; struct ieee80211_conf *conf = NULL; int ret = 0; if (!vif || !priv->is_open) return; + ctx = iwl_rxon_ctx_from_vif(vif); + if (vif->type == NL80211_IFTYPE_AP) { IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); return; @@ -3057,44 +3334,42 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) conf = ieee80211_get_hw_conf(priv->hw); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); - iwl_setup_rxon_timing(priv, vif); - ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), &priv->rxon_timing); + ret = iwl_send_rxon_timing(priv, ctx); if (ret) - IWL_WARN(priv, "REPLY_RXON_TIMING failed - " + IWL_WARN(priv, "RXON timing - " "Attempting to continue.\n"); - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; iwl_set_rxon_ht(priv, &priv->current_ht_config); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid); + ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", vif->bss_conf.aid, vif->bss_conf.beacon_int); if (vif->bss_conf.use_short_preamble) - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - iwlcore_commit_rxon(priv); + iwlcore_commit_rxon(priv, ctx); IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - vif->bss_conf.aid, priv->active_rxon.bssid_addr); + vif->bss_conf.aid, ctx->active.bssid_addr); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -3137,14 +3412,17 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, { int ret; struct ieee80211_hw *hw = priv->hw; + struct iwl_rxon_context *ctx; + hw->rate_control_algorithm = "iwl-agn-rs"; /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION | + IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SPECTRUM_MGMT; - if (!priv->cfg->broken_powersave) + if (!priv->cfg->base_params->broken_powersave) hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; @@ -3155,9 +3433,10 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, hw->sta_data_size = sizeof(struct iwl_station_priv); hw->vif_data_size = sizeof(struct iwl_vif_priv); - hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); + for_each_context(priv, ctx) { + hw->wiphy->interface_modes |= ctx->interface_modes; + hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; + } hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; @@ -3247,15 +3526,6 @@ static void iwl_mac_stop(struct ieee80211_hw *hw) priv->is_open = 0; - if (iwl_is_ready_rf(priv) || test_bit(STATUS_SCAN_HW, &priv->status)) { - /* stop mac, cancel any scan request and clear - * RXON_FILTER_ASSOC_MSK BIT - */ - mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); - mutex_unlock(&priv->mutex); - } - iwl_down(priv); flush_workqueue(priv->workqueue); @@ -3285,24 +3555,25 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); int ret = 0; + lockdep_assert_held(&priv->mutex); + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* The following should be done only at AP bring up */ - if (!iwl_is_associated(priv)) { + if (!iwl_is_associated_ctx(ctx)) { /* RXON - unassoc (to set timing command) */ - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); /* RXON Timing */ - iwl_setup_rxon_timing(priv, vif); - ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), &priv->rxon_timing); + ret = iwl_send_rxon_timing(priv, ctx); if (ret) - IWL_WARN(priv, "REPLY_RXON_TIMING failed - " + IWL_WARN(priv, "RXON timing failed - " "Attempting to continue.\n"); /* AP has all antennas */ @@ -3310,28 +3581,30 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) priv->hw_params.valid_rx_ant; iwl_set_rxon_ht(priv, &priv->current_ht_config); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - priv->staging_rxon.assoc_id = 0; + ctx->staging.assoc_id = 0; if (vif->bss_conf.use_short_preamble) - priv->staging_rxon.flags |= + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } + /* need to send beacon cmd before committing assoc RXON! */ + iwl_send_beacon_cmd(priv); /* restore RXON assoc */ - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); } iwl_send_beacon_cmd(priv); @@ -3348,9 +3621,11 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + IWL_DEBUG_MAC80211(priv, "enter\n"); - iwl_update_tkip_key(priv, keyconf, sta, + iwl_update_tkip_key(priv, vif_priv->ctx, keyconf, sta, iv32, phase1key); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -3362,6 +3637,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct ieee80211_key_conf *key) { struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + struct iwl_rxon_context *ctx = vif_priv->ctx; int ret; u8 sta_id; bool is_default_wep_key = false; @@ -3373,7 +3650,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - sta_id = iwl_sta_id_or_broadcast(priv, sta); + sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta); if (sta_id == IWL_INVALID_STATION) return -EINVAL; @@ -3386,9 +3663,11 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, * in 1X mode. * In legacy wep mode, we use another host command to the uCode. */ - if (key->alg == ALG_WEP && !sta && vif->type != NL80211_IFTYPE_AP) { + if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) && + !sta) { if (cmd == SET_KEY) - is_default_wep_key = !priv->key_mapping_key; + is_default_wep_key = !ctx->key_mapping_keys; else is_default_wep_key = (key->hw_key_idx == HW_KEY_DEFAULT); @@ -3397,17 +3676,18 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (cmd) { case SET_KEY: if (is_default_wep_key) - ret = iwl_set_default_wep_key(priv, key); + ret = iwl_set_default_wep_key(priv, vif_priv->ctx, key); else - ret = iwl_set_dynamic_key(priv, key, sta_id); + ret = iwl_set_dynamic_key(priv, vif_priv->ctx, + key, sta_id); IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); break; case DISABLE_KEY: if (is_default_wep_key) - ret = iwl_remove_default_wep_key(priv, key); + ret = iwl_remove_default_wep_key(priv, ctx, key); else - ret = iwl_remove_dynamic_key(priv, key, sta_id); + ret = iwl_remove_dynamic_key(priv, ctx, key, sta_id); IWL_DEBUG_MAC80211(priv, "disable hwcrypto key\n"); break; @@ -3467,7 +3747,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, } if (test_bit(STATUS_EXIT_PENDING, &priv->status)) ret = 0; - if (priv->cfg->use_rts_for_aggregation) { + if (priv->cfg->ht_params && + priv->cfg->ht_params->use_rts_for_aggregation) { struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; /* @@ -3476,12 +3757,13 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, sta_priv->lq_sta.lq.general_params.flags &= ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; - iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq, - CMD_ASYNC, false); + iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), + &sta_priv->lq_sta.lq, CMD_ASYNC, false); } break; case IEEE80211_AMPDU_TX_OPERATIONAL: - if (priv->cfg->use_rts_for_aggregation) { + if (priv->cfg->ht_params && + priv->cfg->ht_params->use_rts_for_aggregation) { struct iwl_station_priv *sta_priv = (void *) sta->drv_priv; @@ -3492,8 +3774,8 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw, sta_priv->lq_sta.lq.general_params.flags |= LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; - iwl_send_lq_cmd(priv, &sta_priv->lq_sta.lq, - CMD_ASYNC, false); + iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), + &sta_priv->lq_sta.lq, CMD_ASYNC, false); } ret = 0; break; @@ -3539,6 +3821,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; bool is_ap = vif->type == NL80211_IFTYPE_STATION; int ret; u8 sta_id; @@ -3554,8 +3837,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_AP) sta_priv->client = true; - ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, - &sta_id); + ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr, + is_ap, sta, &sta_id); if (ret) { IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); @@ -3581,7 +3864,17 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, struct iwl_priv *priv = hw->priv; const struct iwl_channel_info *ch_info; struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = ch_switch->channel; struct iwl_ht_config *ht_conf = &priv->current_ht_config; + /* + * MULTI-FIXME + * When we add support for multiple interfaces, we need to + * revisit this. The channel switch command in the device + * only affects the BSS context, but what does that really + * mean? And what if we get a CSA on the second interface? + * This needs a lot of work. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u16 ch; unsigned long flags = 0; @@ -3594,7 +3887,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, test_bit(STATUS_SCANNING, &priv->status)) goto out_exit; - if (!iwl_is_associated(priv)) + if (!iwl_is_associated_ctx(ctx)) goto out_exit; /* channel switch in progress */ @@ -3604,11 +3897,10 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); if (priv->cfg->ops->lib->set_channel_switch) { - ch = ieee80211_frequency_to_channel( - ch_switch->channel->center_freq); - if (le16_to_cpu(priv->active_rxon.channel) != ch) { + ch = channel->hw_value; + if (le16_to_cpu(ctx->active.channel) != ch) { ch_info = iwl_get_channel_info(priv, - conf->channel->band, + channel->band, ch); if (!is_channel_valid(ch_info)) { IWL_DEBUG_MAC80211(priv, "invalid channel\n"); @@ -3619,34 +3911,31 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, priv->current_ht_config.smps = conf->smps_mode; /* Configure HT40 channels */ - ht_conf->is_ht = conf_is_ht(conf); - if (ht_conf->is_ht) { + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { if (conf_is_ht40_minus(conf)) { - ht_conf->extension_chan_offset = + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ht_conf->is_40mhz = true; + ctx->ht.is_40mhz = true; } else if (conf_is_ht40_plus(conf)) { - ht_conf->extension_chan_offset = + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ht_conf->is_40mhz = true; + ctx->ht.is_40mhz = true; } else { - ht_conf->extension_chan_offset = + ctx->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; - ht_conf->is_40mhz = false; + ctx->ht.is_40mhz = false; } } else - ht_conf->is_40mhz = false; + ctx->ht.is_40mhz = false; - /* if we are switching from ht to 2.4 clear flags - * from any ht related info since 2.4 does not - * support ht */ - if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) - priv->staging_rxon.flags = 0; + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; - iwl_set_rxon_channel(priv, conf->channel); + iwl_set_rxon_channel(priv, channel, ctx); iwl_set_rxon_ht(priv, ht_conf); - iwl_set_flags_for_band(priv, conf->channel->band, - priv->vif); + iwl_set_flags_for_band(priv, ctx, channel->band, + ctx->vif); spin_unlock_irqrestore(&priv->lock, flags); iwl_set_rate(priv); @@ -3663,7 +3952,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, mutex_unlock(&priv->mutex); out_exit: if (!priv->switch_rxon.switch_in_progress) - ieee80211_chswitch_done(priv->vif, false); + ieee80211_chswitch_done(ctx->vif, false); IWL_DEBUG_MAC80211(priv, "leave\n"); } @@ -3674,6 +3963,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; __le32 filter_or = 0, filter_nand = 0; + struct iwl_rxon_context *ctx; #define CHK(test, flag) do { \ if (*total_flags & (test)) \ @@ -3693,10 +3983,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - priv->staging_rxon.filter_flags &= ~filter_nand; - priv->staging_rxon.filter_flags |= filter_or; - - iwlcore_commit_rxon(priv); + for_each_context(priv, ctx) { + ctx->staging.filter_flags &= ~filter_nand; + ctx->staging.filter_flags |= filter_or; + iwlcore_commit_rxon(priv, ctx); + } mutex_unlock(&priv->mutex); @@ -3765,6 +4056,8 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update); INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); + INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); + INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); @@ -3788,7 +4081,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) priv->cfg->ops->lib->recover_from_tx_stall; } - if (!priv->cfg->use_isr_legacy) + if (!priv->cfg->base_params->use_isr_legacy) tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) iwl_irq_tasklet, (unsigned long)priv); else @@ -3802,15 +4095,17 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) priv->cfg->ops->lib->cancel_deferred_work(priv); cancel_delayed_work_sync(&priv->init_alive_start); - cancel_delayed_work(&priv->scan_check); - cancel_work_sync(&priv->start_internal_scan); cancel_delayed_work(&priv->alive_start); cancel_work_sync(&priv->run_time_calib_work); cancel_work_sync(&priv->beacon_update); + + iwl_cancel_scan_deferred_work(priv); + + cancel_work_sync(&priv->bt_full_concurrency); + cancel_work_sync(&priv->bt_runtime_config); + del_timer_sync(&priv->statistics_periodic); del_timer_sync(&priv->ucode_trace); - if (priv->cfg->ops->lib->recover_from_tx_stall) - del_timer_sync(&priv->monitor_recover); } static void iwl_init_hw_rates(struct iwl_priv *priv, @@ -3838,8 +4133,6 @@ static int iwl_init_drv(struct iwl_priv *priv) { int ret; - priv->ibss_beacon = NULL; - spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); @@ -3865,10 +4158,23 @@ static int iwl_init_drv(struct iwl_priv *priv) /* Choose which receivers/antennas to use */ if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); iwl_init_scan_params(priv); + /* init bt coex */ + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist) { + priv->kill_ack_mask = IWLAGN_BT_KILL_ACK_MASK_DEFAULT; + priv->kill_cts_mask = IWLAGN_BT_KILL_CTS_MASK_DEFAULT; + priv->bt_valid = IWLAGN_BT_ALL_VALID_MSK; + priv->bt_on_thresh = BT_ON_THRESHOLD_DEF; + priv->bt_duration = BT_DURATION_LIMIT_DEF; + priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; + priv->dynamic_agg_thresh = BT_AGG_THRESHOLD_DEF; + } + /* Set the tx_power_user_lmt to the lowest power level * this value will get overwritten by channel max power avg * from eeprom */ @@ -3923,11 +4229,60 @@ static struct ieee80211_ops iwl_hw_ops = { .sta_remove = iwl_mac_sta_remove, .channel_switch = iwl_mac_channel_switch, .flush = iwl_mac_flush, + .tx_last_beacon = iwl_mac_tx_last_beacon, +}; + +static void iwl_hw_detect(struct iwl_priv *priv) +{ + priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); + priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); + pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); + IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id); +} + +static int iwl_set_hw_params(struct iwl_priv *priv) +{ + priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; + priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; + if (priv->cfg->mod_params->amsdu_size_8K) + priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); + else + priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); + + priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; + + if (priv->cfg->mod_params->disable_11n) + priv->cfg->sku &= ~IWL_SKU_N; + + /* Device-specific setup */ + return priv->cfg->ops->lib->set_hw_params(priv); +} + +static const u8 iwlagn_bss_ac_to_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, +}; + +static const u8 iwlagn_bss_ac_to_queue[] = { + 0, 1, 2, 3, +}; + +static const u8 iwlagn_pan_ac_to_fifo[] = { + IWL_TX_FIFO_VO_IPAN, + IWL_TX_FIFO_VI_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWL_TX_FIFO_BK_IPAN, +}; + +static const u8 iwlagn_pan_ac_to_queue[] = { + 7, 6, 5, 4, }; static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int err = 0; + int err = 0, i; struct iwl_priv *priv; struct ieee80211_hw *hw; struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); @@ -3941,9 +4296,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Disabling hardware scan means that mac80211 will perform scans * "the hard way", rather than using device's scan. */ if (cfg->mod_params->disable_hw_scan) { - if (iwl_debug_level & IWL_DL_INFO) - dev_printk(KERN_DEBUG, &(pdev->dev), - "Disabling hw_scan\n"); + dev_printk(KERN_DEBUG, &(pdev->dev), + "sw scan support is deprecated\n"); iwl_hw_ops.hw_scan = NULL; } @@ -3955,6 +4309,53 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv = hw->priv; /* At this point both hw and priv are allocated. */ + /* + * The default context is always valid, + * more may be discovered when firmware + * is loaded. + */ + priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); + + for (i = 0; i < NUM_IWL_RXON_CTX; i++) + priv->contexts[i].ctxid = i; + + priv->contexts[IWL_RXON_CTX_BSS].always_active = true; + priv->contexts[IWL_RXON_CTX_BSS].is_active = true; + priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; + priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; + priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].ac_to_fifo = iwlagn_bss_ac_to_fifo; + priv->contexts[IWL_RXON_CTX_BSS].ac_to_queue = iwlagn_bss_ac_to_queue; + priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = + BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].interface_modes = + BIT(NL80211_IFTYPE_STATION); + priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; + priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; + priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; + + priv->contexts[IWL_RXON_CTX_PAN].rxon_cmd = REPLY_WIPAN_RXON; + priv->contexts[IWL_RXON_CTX_PAN].rxon_timing_cmd = REPLY_WIPAN_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_PAN].rxon_assoc_cmd = REPLY_WIPAN_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_PAN].qos_cmd = REPLY_WIPAN_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_PAN].ap_sta_id = IWL_AP_ID_PAN; + priv->contexts[IWL_RXON_CTX_PAN].wep_key_cmd = REPLY_WIPAN_WEPKEY; + priv->contexts[IWL_RXON_CTX_PAN].bcast_sta_id = IWLAGN_PAN_BCAST_ID; + priv->contexts[IWL_RXON_CTX_PAN].station_flags = STA_FLG_PAN_STATION; + priv->contexts[IWL_RXON_CTX_PAN].ac_to_fifo = iwlagn_pan_ac_to_fifo; + priv->contexts[IWL_RXON_CTX_PAN].ac_to_queue = iwlagn_pan_ac_to_queue; + priv->contexts[IWL_RXON_CTX_PAN].mcast_queue = IWL_IPAN_MCAST_QUEUE; + priv->contexts[IWL_RXON_CTX_PAN].interface_modes = + BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP); + priv->contexts[IWL_RXON_CTX_PAN].ap_devtype = RXON_DEV_TYPE_CP; + priv->contexts[IWL_RXON_CTX_PAN].station_devtype = RXON_DEV_TYPE_2STA; + priv->contexts[IWL_RXON_CTX_PAN].unused_devtype = RXON_DEV_TYPE_P2P; + + BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); + SET_IEEE80211_DEV(hw, &pdev->dev); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); @@ -3962,12 +4363,23 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) priv->pci_dev = pdev; priv->inta_mask = CSR_INI_SET_MASK; + /* is antenna coupling more than 35dB ? */ + priv->bt_ant_couple_ok = + (iwlagn_ant_coupling > IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? + true : false; + + /* enable/disable bt channel announcement */ + priv->bt_ch_announce = iwlagn_bt_ch_announce; + if (iwl_alloc_traffic_mem(priv)) IWL_ERR(priv, "Not enough memory to generate traffic log\n"); /************************** * 2. Initializing PCI bus **************************/ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + if (pci_enable_device(pdev)) { err = -ENODEV; goto out_ieee80211_free_hw; @@ -4190,7 +4602,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) * paths to avoid running iwl_down() at all before leaving driver. * This (inexpensive) call *makes sure* device is reset. */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); iwl_tt_exit(priv); @@ -4233,8 +4645,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) iwl_free_isr_ict(priv); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + dev_kfree_skb(priv->beacon_skb); ieee80211_free_hw(priv->hw); } @@ -4398,6 +4809,22 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x0083, 0x1326, iwl1000_bg_cfg)}, {IWL_PCI_DEVICE(0x0084, 0x1216, iwl1000_bg_cfg)}, {IWL_PCI_DEVICE(0x0084, 0x1316, iwl1000_bg_cfg)}, + +/* 100 Series WiFi */ + {IWL_PCI_DEVICE(0x08AE, 0x1005, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AF, 0x1015, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1025, iwl100_bgn_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1007, iwl100_bg_cfg)}, + {IWL_PCI_DEVICE(0x08AE, 0x1017, iwl100_bg_cfg)}, + +/* 130 Series WiFi */ + {IWL_PCI_DEVICE(0x0896, 0x5005, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5007, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5015, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0897, 0x5017, iwl130_bg_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5025, iwl130_bgn_cfg)}, + {IWL_PCI_DEVICE(0x0896, 0x5027, iwl130_bg_cfg)}, + #endif /* CONFIG_IWL5000 */ {0} @@ -4486,9 +4913,18 @@ module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO); MODULE_PARM_DESC(fw_restart, "restart firmware in case of error"); module_param_named( disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); +MODULE_PARM_DESC(disable_hw_scan, + "disable hardware scanning (default 0) (deprecated)"); module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int, S_IRUGO); MODULE_PARM_DESC(ucode_alternative, "specify ucode alternative to use from ucode file"); + +module_param_named(antenna_coupling, iwlagn_ant_coupling, int, S_IRUGO); +MODULE_PARM_DESC(antenna_coupling, + "specify antenna coupling in dB (defualt: 0 dB)"); + +module_param_named(bt_ch_announce, iwlagn_bt_ch_announce, bool, S_IRUGO); +MODULE_PARM_DESC(bt_ch_announce, + "Enable BT channel announcement mode (default: enable)"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index cc6464dc72e592bd57302423b84784f0b4b63d8d..f525d55f2c0fb208c92b5e60d56ab5386da4acc4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -92,9 +92,14 @@ extern struct iwl_cfg iwl6050_2abg_cfg; extern struct iwl_cfg iwl6050g2_bgn_cfg; extern struct iwl_cfg iwl1000_bgn_cfg; extern struct iwl_cfg iwl1000_bg_cfg; +extern struct iwl_cfg iwl100_bgn_cfg; +extern struct iwl_cfg iwl100_bg_cfg; +extern struct iwl_cfg iwl130_bgn_cfg; +extern struct iwl_cfg iwl130_bg_cfg; extern struct iwl_mod_params iwlagn_mod_params; extern struct iwl_hcmd_ops iwlagn_hcmd; +extern struct iwl_hcmd_ops iwlagn_bt_hcmd; extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils; int iwl_reset_ict(struct iwl_priv *priv); @@ -124,6 +129,10 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask); void iwl_free_tfds_in_queue(struct iwl_priv *priv, int sta_id, int tid, int freed); +/* RXON */ +int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); + /* uCode */ int iwlagn_load_ucode(struct iwl_priv *priv); void iwlagn_rx_calib_result(struct iwl_priv *priv, @@ -133,6 +142,8 @@ void iwlagn_rx_calib_complete(struct iwl_priv *priv, void iwlagn_init_alive_start(struct iwl_priv *priv); int iwlagn_alive_notify(struct iwl_priv *priv); int iwl_verify_ucode(struct iwl_priv *priv); +void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); +void iwlagn_send_prio_tbl(struct iwl_priv *priv); /* lib */ void iwl_check_abort_status(struct iwl_priv *priv, @@ -151,6 +162,8 @@ int iwlagn_hw_nic_init(struct iwl_priv *priv); int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv); int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); +void iwl_dump_csr(struct iwl_priv *priv); +int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); /* rx */ void iwlagn_rx_queue_restock(struct iwl_priv *priv); @@ -164,8 +177,15 @@ void iwlagn_rx_reply_rx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); +void iwl_rx_handle(struct iwl_priv *priv); /* tx */ +void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); +int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, u8 reset, u8 pad); +int iwl_hw_tx_queue_init(struct iwl_priv *priv, + struct iwl_tx_queue *txq); void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, struct ieee80211_tx_info *info); int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb); @@ -205,6 +225,8 @@ static inline bool iwl_is_tx_success(u32 status) (status == TX_STATUS_DIRECT_DONE); } +u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); + /* rx */ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); @@ -216,14 +238,84 @@ void iwl_reply_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /* scan */ -void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif); +void iwlagn_post_scan(struct iwl_priv *priv); /* station mgmt */ int iwlagn_manage_ibss_station(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add); /* hcmd */ -int iwlagn_send_rxon_assoc(struct iwl_priv *priv); +int iwlagn_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); +/* bt coex */ +void iwlagn_send_advance_bt_config(struct iwl_priv *priv); +void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb); +void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv); +void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv); +void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv); + +#ifdef CONFIG_IWLWIFI_DEBUG +const char *iwl_get_tx_fail_reason(u32 status); +const char *iwl_get_agg_tx_fail_reason(u16 status); +#else +static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; } +static inline const char *iwl_get_agg_tx_fail_reason(u16 status) { return ""; } +#endif + +/* station management */ +int iwlagn_alloc_bcast_station(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +int iwlagn_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, u8 *sta_id_r); +int iwl_remove_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key); +int iwl_set_default_wep_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key); +int iwl_restore_default_wep_keys(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key, u8 sta_id); +int iwl_remove_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *key, u8 sta_id); +void iwl_update_tkip_key(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_key_conf *keyconf, + struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); +int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); +int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid, u16 ssn); +int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, + int tid); +void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); +void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); +int iwl_update_bcast_stations(struct iwl_priv *priv); + +/* rate */ +static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) +{ + return BIT(ant_idx) << RATE_MCS_ANT_POS; +} + +static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) +{ + return le32_to_cpu(rate_n_flags) & 0xFF; +} + +static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) +{ + return cpu_to_le32(flags|(u32)rate); +} + +/* eeprom */ +void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv); +void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); +int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); +void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); + #endif /* __iwl_agn_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 60725a5c1b694b689d42fe6e782c9c141a47ac74..424801abc80eae92a5d39a777c08a73baf13c7a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -62,7 +62,7 @@ *****************************************************************************/ /* * Please use this file (iwl-commands.h) only for uCode API definitions. - * Please use iwl-4965-hw.h for hardware-related definitions. + * Please use iwl-xxxx-hw.h for hardware-related definitions. * Please use iwl-dev.h for driver implementation definitions. */ @@ -173,6 +173,23 @@ enum { REPLY_RX_MPDU_CMD = 0xc1, REPLY_RX = 0xc3, REPLY_COMPRESSED_BA = 0xc5, + + /* BT Coex */ + REPLY_BT_COEX_PRIO_TABLE = 0xcc, + REPLY_BT_COEX_PROT_ENV = 0xcd, + REPLY_BT_COEX_PROFILE_NOTIF = 0xce, + REPLY_BT_COEX_SCO = 0xcf, + + /* PAN commands */ + REPLY_WIPAN_PARAMS = 0xb2, + REPLY_WIPAN_RXON = 0xb3, /* use REPLY_RXON structure */ + REPLY_WIPAN_RXON_TIMING = 0xb4, /* use REPLY_RXON_TIMING structure */ + REPLY_WIPAN_RXON_ASSOC = 0xb6, /* use REPLY_RXON_ASSOC structure */ + REPLY_WIPAN_QOS_PARAM = 0xb7, /* use REPLY_QOS_PARAM structure */ + REPLY_WIPAN_WEPKEY = 0xb8, /* use REPLY_WEPKEY structure */ + REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9, + REPLY_WIPAN_NOA_NOTIFICATION = 0xbc, + REPLY_MAX = 0xff }; @@ -403,12 +420,12 @@ struct iwl4965_tx_power_db { /** * Command REPLY_TX_POWER_DBM_CMD = 0x98 - * struct iwl5000_tx_power_dbm_cmd + * struct iwlagn_tx_power_dbm_cmd */ -#define IWL50_TX_POWER_AUTO 0x7f -#define IWL50_TX_POWER_NO_CLOSED (0x1 << 6) +#define IWLAGN_TX_POWER_AUTO 0x7f +#define IWLAGN_TX_POWER_NO_CLOSED (0x1 << 6) -struct iwl5000_tx_power_dbm_cmd { +struct iwlagn_tx_power_dbm_cmd { s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ u8 flags; s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ @@ -600,6 +617,9 @@ enum { RXON_DEV_TYPE_ESS = 3, RXON_DEV_TYPE_IBSS = 4, RXON_DEV_TYPE_SNIFFER = 6, + RXON_DEV_TYPE_CP = 7, + RXON_DEV_TYPE_2STA = 8, + RXON_DEV_TYPE_P2P = 9, }; @@ -816,7 +836,8 @@ struct iwl_rxon_time_cmd { __le16 atim_window; __le32 beacon_init_val; __le16 listen_interval; - __le16 reserved; + u8 dtim_period; + u8 delta_cp_bss_tbtts; } __packed; /* @@ -953,11 +974,13 @@ struct iwl_qosparam_cmd { /* Special, dedicated locations within device's station table */ #define IWL_AP_ID 0 +#define IWL_AP_ID_PAN 1 #define IWL_STA_ID 2 #define IWL3945_BROADCAST_ID 24 #define IWL3945_STATION_COUNT 25 #define IWL4965_BROADCAST_ID 31 #define IWL4965_STATION_COUNT 32 +#define IWLAGN_PAN_BCAST_ID 14 #define IWLAGN_BROADCAST_ID 15 #define IWLAGN_STATION_COUNT 16 @@ -966,6 +989,7 @@ struct iwl_qosparam_cmd { #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) #define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) +#define STA_FLG_PAN_STATION cpu_to_le32(1 << 13) #define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17) #define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18) #define STA_FLG_MAX_AGG_SIZE_POS (19) @@ -994,6 +1018,7 @@ struct iwl_qosparam_cmd { #define STA_KEY_FLG_KEY_SIZE_MSK cpu_to_le16(0x1000) #define STA_KEY_MULTICAST_MSK cpu_to_le16(0x4000) #define STA_KEY_MAX_NUM 8 +#define STA_KEY_MAX_NUM_PAN 16 /* Flags indicate whether to modify vs. don't change various station params */ #define STA_MODIFY_KEY_MASK 0x01 @@ -1017,7 +1042,7 @@ struct iwl4965_keyinfo { u8 key[16]; /* 16-byte unicast decryption key */ } __packed; -/* 5000 */ +/* agn */ struct iwl_keyinfo { __le16 key_flags; u8 tkip_rx_tsc_byte2; /* TSC[2] for key mix ph1 detection */ @@ -1056,7 +1081,8 @@ struct sta_id_modify { * * The device contains an internal table of per-station information, * with info on security keys, aggregation parameters, and Tx rates for - * initial Tx attempt and any retries (4965 uses REPLY_TX_LINK_QUALITY_CMD, + * initial Tx attempt and any retries (agn devices uses + * REPLY_TX_LINK_QUALITY_CMD, * 3945 uses REPLY_RATE_SCALE to set up rate tables). * * REPLY_ADD_STA sets up the table entry for one station, either creating @@ -1142,7 +1168,7 @@ struct iwl4965_addsta_cmd { __le16 reserved2; } __packed; -/* 5000 */ +/* agn */ struct iwl_addsta_cmd { u8 mode; /* 1: modify existing, 0: add new station */ u8 reserved[3]; @@ -1367,21 +1393,24 @@ struct iwl4965_rx_non_cfg_phy { } __packed; -#define IWL50_RX_RES_PHY_CNT 8 -#define IWL50_RX_RES_AGC_IDX 1 -#define IWL50_RX_RES_RSSI_AB_IDX 2 -#define IWL50_RX_RES_RSSI_C_IDX 3 -#define IWL50_OFDM_AGC_MSK 0xfe00 -#define IWL50_OFDM_AGC_BIT_POS 9 -#define IWL50_OFDM_RSSI_A_MSK 0x00ff -#define IWL50_OFDM_RSSI_A_BIT_POS 0 -#define IWL50_OFDM_RSSI_B_MSK 0xff0000 -#define IWL50_OFDM_RSSI_B_BIT_POS 16 -#define IWL50_OFDM_RSSI_C_MSK 0x00ff -#define IWL50_OFDM_RSSI_C_BIT_POS 0 +#define IWLAGN_RX_RES_PHY_CNT 8 +#define IWLAGN_RX_RES_AGC_IDX 1 +#define IWLAGN_RX_RES_RSSI_AB_IDX 2 +#define IWLAGN_RX_RES_RSSI_C_IDX 3 +#define IWLAGN_OFDM_AGC_MSK 0xfe00 +#define IWLAGN_OFDM_AGC_BIT_POS 9 +#define IWLAGN_OFDM_RSSI_INBAND_A_BITMSK 0x00ff +#define IWLAGN_OFDM_RSSI_ALLBAND_A_BITMSK 0xff00 +#define IWLAGN_OFDM_RSSI_A_BIT_POS 0 +#define IWLAGN_OFDM_RSSI_INBAND_B_BITMSK 0xff0000 +#define IWLAGN_OFDM_RSSI_ALLBAND_B_BITMSK 0xff000000 +#define IWLAGN_OFDM_RSSI_B_BIT_POS 16 +#define IWLAGN_OFDM_RSSI_INBAND_C_BITMSK 0x00ff +#define IWLAGN_OFDM_RSSI_ALLBAND_C_BITMSK 0xff00 +#define IWLAGN_OFDM_RSSI_C_BIT_POS 0 -struct iwl5000_non_cfg_phy { - __le32 non_cfg_phy[IWL50_RX_RES_PHY_CNT]; /* up to 8 phy entries */ +struct iwlagn_non_cfg_phy { + __le32 non_cfg_phy[IWLAGN_RX_RES_PHY_CNT]; /* up to 8 phy entries */ } __packed; @@ -1401,7 +1430,7 @@ struct iwl_rx_phy_res { u8 non_cfg_phy_buf[32]; /* for various implementations of non_cfg_phy */ __le32 rate_n_flags; /* RATE_MCS_* */ __le16 byte_count; /* frame's byte-count */ - __le16 reserved3; + __le16 frame_time; /* frame's time on the air */ } __packed; struct iwl_rx_mpdu_res_start { @@ -1424,12 +1453,12 @@ struct iwl_rx_mpdu_res_start { * uCode handles all timing and protocol related to control frames * (RTS/CTS/ACK), based on flags in the Tx command. uCode and Tx scheduler * handle reception of block-acks; uCode updates the host driver via - * REPLY_COMPRESSED_BA (4965). + * REPLY_COMPRESSED_BA. * * uCode handles retrying Tx when an ACK is expected but not received. * This includes trying lower data rates than the one requested in the Tx * command, as set up by the REPLY_RATE_SCALE (for 3945) or - * REPLY_TX_LINK_QUALITY_CMD (4965). + * REPLY_TX_LINK_QUALITY_CMD (agn). * * Driver sets up transmit power for various rates via REPLY_TX_PWR_TABLE_CMD. * This command must be executed after every RXON command, before Tx can occur. @@ -1465,7 +1494,7 @@ struct iwl_rx_mpdu_res_start { * Set this for unicast frames, but not broadcast/multicast. */ #define TX_CMD_FLG_ACK_MSK cpu_to_le32(1 << 3) -/* For 4965: +/* For agn devices: * 1: Use rate scale table (see REPLY_TX_LINK_QUALITY_CMD). * Tx command's initial_rate_index indicates first rate to try; * uCode walks through table for additional Tx attempts. @@ -1484,7 +1513,7 @@ struct iwl_rx_mpdu_res_start { */ #define TX_CMD_FLG_FULL_TXOP_PROT_MSK cpu_to_le32(1 << 7) -/* Tx antenna selection field; used only for 3945, reserved (0) for 4965. +/* Tx antenna selection field; used only for 3945, reserved (0) for agn devices. * Set field to "0" to allow 3945 uCode to select antenna (normal usage). */ #define TX_CMD_FLG_ANT_SEL_MSK cpu_to_le32(0xf00) #define TX_CMD_FLG_ANT_A_MSK cpu_to_le32(1 << 8) @@ -1791,13 +1820,8 @@ enum { TX_STATUS_FAIL_TID_DISABLE = 0x8d, TX_STATUS_FAIL_FIFO_FLUSHED = 0x8e, TX_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f, - /* uCode drop due to FW drop request */ - TX_STATUS_FAIL_FW_DROP = 0x90, - /* - * uCode drop due to station color mismatch - * between tx command and station table - */ - TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP = 0x91, + TX_STATUS_FAIL_PASSIVE_NO_RX = 0x90, + TX_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91, }; #define TX_PACKET_MODE_REGULAR 0x0000 @@ -1839,6 +1863,9 @@ enum { AGG_TX_STATE_DELAY_TX_MSK = 0x400 }; +#define AGG_TX_STATUS_MSK 0x00000fff /* bits 0:11 */ +#define AGG_TX_TRY_MSK 0x0000f000 /* bits 12:15 */ + #define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \ AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ AGG_TX_STATE_LAST_SENT_BT_KILL_MSK) @@ -1867,9 +1894,10 @@ enum { * frame in this new agg block failed in previous agg block(s). * * Note that, for aggregation, ACK (block-ack) status is not delivered here; - * block-ack has not been received by the time the 4965 records this status. + * block-ack has not been received by the time the agn device records + * this status. * This status relates to reasons the tx might have been blocked or aborted - * within the sending station (this 4965), rather than whether it was + * within the sending station (this agn device), rather than whether it was * received successfully by the destination station. */ struct agg_tx_status { @@ -1931,12 +1959,12 @@ struct iwl4965_tx_resp { #define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80 /* refer to ra_tid */ -#define IWL50_TX_RES_TID_POS 0 -#define IWL50_TX_RES_TID_MSK 0x0f -#define IWL50_TX_RES_RA_POS 4 -#define IWL50_TX_RES_RA_MSK 0xf0 +#define IWLAGN_TX_RES_TID_POS 0 +#define IWLAGN_TX_RES_TID_MSK 0x0f +#define IWLAGN_TX_RES_RA_POS 4 +#define IWLAGN_TX_RES_RA_MSK 0xf0 -struct iwl5000_tx_resp { +struct iwlagn_tx_resp { u8 frame_count; /* 1 no aggregation, >1 aggregation */ u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ u8 failure_rts; /* # failures due to unsuccessful RTS */ @@ -2092,8 +2120,8 @@ struct iwl_link_qual_general_params { } __packed; #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ -#define LINK_QUAL_AGG_TIME_LIMIT_MAX (65535) -#define LINK_QUAL_AGG_TIME_LIMIT_MIN (0) +#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) +#define LINK_QUAL_AGG_TIME_LIMIT_MIN (100) #define LINK_QUAL_AGG_DISABLE_START_DEF (3) #define LINK_QUAL_AGG_DISABLE_START_MAX (255) @@ -2110,8 +2138,10 @@ struct iwl_link_qual_general_params { */ struct iwl_link_qual_agg_params { - /* Maximum number of uSec in aggregation. - * Driver should set this to 4000 (4 milliseconds). */ + /* + *Maximum number of uSec in aggregation. + * default set to 4000 (4 milliseconds) if not configured in .cfg + */ __le16 agg_time_limit; /* @@ -2135,14 +2165,16 @@ struct iwl_link_qual_agg_params { /* * REPLY_TX_LINK_QUALITY_CMD = 0x4e (command, has simple generic response) * - * For 4965 only; 3945 uses REPLY_RATE_SCALE. + * For agn devices only; 3945 uses REPLY_RATE_SCALE. * - * Each station in the 4965's internal station table has its own table of 16 + * Each station in the agn device's internal station table has its own table + * of 16 * Tx rates and modulation modes (e.g. legacy/SISO/MIMO) for retrying Tx when * an ACK is not received. This command replaces the entire table for * one station. * - * NOTE: Station must already be in 4965's station table. Use REPLY_ADD_STA. + * NOTE: Station must already be in agn device's station table. + * Use REPLY_ADD_STA. * * The rate scaling procedures described below work well. Of course, other * procedures are possible, and may work better for particular environments. @@ -2179,12 +2211,12 @@ struct iwl_link_qual_agg_params { * * ACCUMULATING HISTORY * - * The rate scaling algorithm for 4965, as implemented in Linux driver, uses - * two sets of frame Tx success history: One for the current/active modulation - * mode, and one for a speculative/search mode that is being attempted. If the - * speculative mode turns out to be more effective (i.e. actual transfer - * rate is better), then the driver continues to use the speculative mode - * as the new current active mode. + * The rate scaling algorithm for agn devices, as implemented in Linux driver, + * uses two sets of frame Tx success history: One for the current/active + * modulation mode, and one for a speculative/search mode that is being + * attempted. If the speculative mode turns out to be more effective (i.e. + * actual transfer rate is better), then the driver continues to use the + * speculative mode as the new current active mode. * * Each history set contains, separately for each possible rate, data for a * sliding window of the 62 most recent tx attempts at that rate. The data @@ -2195,12 +2227,12 @@ struct iwl_link_qual_agg_params { * The driver uses the bit map to remove successes from the success sum, as * the oldest tx attempts fall out of the window. * - * When the 4965 makes multiple tx attempts for a given frame, each attempt - * might be at a different rate, and have different modulation characteristics - * (e.g. antenna, fat channel, short guard interval), as set up in the rate - * scaling table in the Link Quality command. The driver must determine - * which rate table entry was used for each tx attempt, to determine which - * rate-specific history to update, and record only those attempts that + * When the agn device makes multiple tx attempts for a given frame, each + * attempt might be at a different rate, and have different modulation + * characteristics (e.g. antenna, fat channel, short guard interval), as set + * up in the rate scaling table in the Link Quality command. The driver must + * determine which rate table entry was used for each tx attempt, to determine + * which rate-specific history to update, and record only those attempts that * match the modulation characteristics of the history set. * * When using block-ack (aggregation), all frames are transmitted at the same @@ -2330,7 +2362,7 @@ struct iwl_link_quality_cmd { /* * Rate info; when using rate-scaling, Tx command's initial_rate_index * specifies 1st Tx rate attempted, via index into this table. - * 4965 works its way through table when retrying Tx. + * agn devices works its way through table when retrying Tx. */ struct { __le32 rate_n_flags; /* RATE_MCS_*, IWL_RATE_* */ @@ -2363,10 +2395,26 @@ struct iwl_link_quality_cmd { #define BT_MAX_KILL_DEF (0x5) #define BT_MAX_KILL_MAX (0xFF) +#define BT_DURATION_LIMIT_DEF 625 +#define BT_DURATION_LIMIT_MAX 1250 +#define BT_DURATION_LIMIT_MIN 625 + +#define BT_ON_THRESHOLD_DEF 4 +#define BT_ON_THRESHOLD_MAX 1000 +#define BT_ON_THRESHOLD_MIN 1 + +#define BT_FRAG_THRESHOLD_DEF 0 +#define BT_FRAG_THRESHOLD_MAX 0 +#define BT_FRAG_THRESHOLD_MIN 0 + +#define BT_AGG_THRESHOLD_DEF 0 +#define BT_AGG_THRESHOLD_MAX 0 +#define BT_AGG_THRESHOLD_MIN 0 + /* * REPLY_BT_CONFIG = 0x9b (command, has simple generic response) * - * 3945 and 4965 support hardware handshake with Bluetooth device on + * 3945 and agn devices support hardware handshake with Bluetooth device on * same platform. Bluetooth device alerts wireless device when it will Tx; * wireless device can delay or kill its own Tx to accommodate. */ @@ -2379,6 +2427,79 @@ struct iwl_bt_cmd { __le32 kill_cts_mask; } __packed; +#define IWLAGN_BT_FLAG_CHANNEL_INHIBITION BIT(0) + +#define IWLAGN_BT_FLAG_COEX_MODE_MASK (BIT(3)|BIT(4)|BIT(5)) +#define IWLAGN_BT_FLAG_COEX_MODE_SHIFT 3 +#define IWLAGN_BT_FLAG_COEX_MODE_DISABLED 0 +#define IWLAGN_BT_FLAG_COEX_MODE_LEGACY_2W 1 +#define IWLAGN_BT_FLAG_COEX_MODE_3W 2 +#define IWLAGN_BT_FLAG_COEX_MODE_4W 3 + +#define IWLAGN_BT_FLAG_UCODE_DEFAULT BIT(6) +#define IWLAGN_BT_FLAG_NOCOEX_NOTIF BIT(7) + +#define IWLAGN_BT_PRIO_BOOST_MAX 0xFF +#define IWLAGN_BT_PRIO_BOOST_MIN 0x00 +#define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0 + +#define IWLAGN_BT_MAX_KILL_DEFAULT 5 + +#define IWLAGN_BT3_T7_DEFAULT 1 + +#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffffffff) +#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffffffff) + +#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 + +#define IWLAGN_BT3_T2_DEFAULT 0xc + +#define IWLAGN_BT_VALID_ENABLE_FLAGS cpu_to_le16(BIT(0)) +#define IWLAGN_BT_VALID_BOOST cpu_to_le16(BIT(1)) +#define IWLAGN_BT_VALID_MAX_KILL cpu_to_le16(BIT(2)) +#define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3)) +#define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4)) +#define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5)) +#define IWLAGN_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6)) +#define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7)) + +#define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \ + IWLAGN_BT_VALID_BOOST | \ + IWLAGN_BT_VALID_MAX_KILL | \ + IWLAGN_BT_VALID_3W_TIMERS | \ + IWLAGN_BT_VALID_KILL_ACK_MASK | \ + IWLAGN_BT_VALID_KILL_CTS_MASK | \ + IWLAGN_BT_VALID_BT4_TIMES | \ + IWLAGN_BT_VALID_3W_LUT) + +struct iwlagn_bt_cmd { + u8 flags; + u8 ledtime; /* unused */ + u8 max_kill; + u8 bt3_timer_t7_value; + __le32 kill_ack_mask; + __le32 kill_cts_mask; + u8 bt3_prio_sample_time; + u8 bt3_timer_t2_value; + __le16 bt4_reaction_time; /* unused */ + __le32 bt3_lookup_table[12]; + __le16 bt4_decision_time; /* unused */ + __le16 valid; + u8 prio_boost; + /* + * set IWLAGN_BT_VALID_BOOST to "1" in "valid" bitmask + * if configure the following patterns + */ + u8 tx_prio_boost; /* SW boost of WiFi tx priority */ + __le16 rx_prio_boost; /* SW boost of WiFi rx priority */ +}; + +#define IWLAGN_BT_SCO_ACTIVE cpu_to_le32(BIT(0)) + +struct iwlagn_bt_sco_cmd { + __le32 flags; +}; + /****************************************************************************** * (6) * Spectrum Management (802.11h) Commands, Responses, Notifications: @@ -2567,7 +2688,7 @@ struct iwl_powertable_cmd { /* * PM_SLEEP_NOTIFICATION = 0x7A (notification only, not a command) - * 3945 and 4965 identical. + * all devices identical. */ struct iwl_sleep_notification { u8 pm_sleep_mode; @@ -2578,7 +2699,7 @@ struct iwl_sleep_notification { __le32 bcon_timer; } __packed; -/* Sleep states. 3945 and 4965 identical. */ +/* Sleep states. all devices identical. */ enum { IWL_PM_NO_SLEEP = 0, IWL_PM_SLP_MAC = 1, @@ -2887,6 +3008,12 @@ struct iwl_scanstart_notification { #define SCAN_OWNER_STATUS 0x1; #define MEASURE_OWNER_STATUS 0x2; +#define IWL_PROBE_STATUS_OK 0 +#define IWL_PROBE_STATUS_TX_FAILED BIT(0) +/* error statuses combined with TX_FAILED */ +#define IWL_PROBE_STATUS_FAIL_TTL BIT(1) +#define IWL_PROBE_STATUS_FAIL_BT BIT(2) + #define NUMBER_OF_STATISTICS 1 /* first __le32 is good CRC */ /* * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) @@ -2894,7 +3021,8 @@ struct iwl_scanstart_notification { struct iwl_scanresults_notification { u8 channel; u8 band; - u8 reserved[2]; + u8 probe_status; + u8 num_probe_not_sent; /* not enough time to send */ __le32 tsf_low; __le32 tsf_high; __le32 statistics[NUMBER_OF_STATISTICS]; @@ -2906,7 +3034,7 @@ struct iwl_scanresults_notification { struct iwl_scancomplete_notification { u8 scanned_channels; u8 status; - u8 reserved; + u8 bt_status; /* BT On/Off status */ u8 last_channel; __le32 tsf_low; __le32 tsf_high; @@ -2919,6 +3047,11 @@ struct iwl_scancomplete_notification { * *****************************************************************************/ +enum iwl_ibss_manager { + IWL_NOT_IBSS_MANAGER = 0, + IWL_IBSS_MANAGER = 1, +}; + /* * BEACON_NOTIFICATION = 0x90 (notification only, not a command) */ @@ -3260,7 +3393,7 @@ struct statistics_general_bt { /* * REPLY_STATISTICS_CMD = 0x9c, - * 3945 and 4965 identical. + * all devices identical. * * This command triggers an immediate response containing uCode statistics. * The response is in the same format as STATISTICS_NOTIFICATION 0x9d, below. @@ -3598,7 +3731,7 @@ struct iwl_enhance_sensitivity_cmd { /** * REPLY_PHY_CALIBRATION_CMD = 0xb0 (command, has simple generic response) * - * This command sets the relative gains of 4965's 3 radio receiver chains. + * This command sets the relative gains of agn device's 3 radio receiver chains. * * After the first association, driver should accumulate signal and noise * statistics from the STATISTICS_NOTIFICATIONs that follow the first 20 @@ -3651,7 +3784,8 @@ struct iwl_enhance_sensitivity_cmd { */ /* Phy calibration command for series */ - +/* The default calibrate table size if not specified by firmware */ +#define IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE 18 enum { IWL_PHY_CALIBRATE_DIFF_GAIN_CMD = 7, IWL_PHY_CALIBRATE_DC_CMD = 8, @@ -3660,13 +3794,29 @@ enum { IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15, IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16, IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17, - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 18, + IWL_PHY_CALIBRATE_TEMP_OFFSET_CMD = 18, + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 19, }; #define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253) #define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff) +/* This enum defines the bitmap of various calibrations to enable in both + * init ucode and runtime ucode through CALIBRATION_CFG_CMD. + */ +enum iwl_ucode_calib_cfg { + IWL_CALIB_CFG_RX_BB_IDX, + IWL_CALIB_CFG_DC_IDX, + IWL_CALIB_CFG_TX_IQ_IDX, + IWL_CALIB_CFG_RX_IQ_IDX, + IWL_CALIB_CFG_NOISE_IDX, + IWL_CALIB_CFG_CRYSTAL_IDX, + IWL_CALIB_CFG_TEMPERATURE_IDX, + IWL_CALIB_CFG_PAPD_IDX, +}; + + struct iwl_calib_cfg_elmnt_s { __le32 is_enable; __le32 start; @@ -3715,6 +3865,13 @@ struct iwl_calib_xtal_freq_cmd { u8 pad[2]; } __packed; +#define DEFAULT_RADIO_SENSOR_OFFSET 2700 +struct iwl_calib_temperature_offset_cmd { + struct iwl_calib_hdr hdr; + s16 radio_sensor_offset; + s16 reserved; +} __packed; + /* IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD */ struct iwl_calib_chain_noise_reset_cmd { struct iwl_calib_hdr hdr; @@ -3954,6 +4111,201 @@ struct iwl_coex_event_resp { } __packed; +/****************************************************************************** + * Bluetooth Coexistence commands + * + *****************************************************************************/ + +/* + * BT Status notification + * REPLY_BT_COEX_PROFILE_NOTIF = 0xce + */ +enum iwl_bt_coex_profile_traffic_load { + IWL_BT_COEX_TRAFFIC_LOAD_NONE = 0, + IWL_BT_COEX_TRAFFIC_LOAD_LOW = 1, + IWL_BT_COEX_TRAFFIC_LOAD_HIGH = 2, + IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS = 3, +/* + * There are no more even though below is a u8, the + * indication from the BT device only has two bits. + */ +}; + +#define BT_UART_MSG_FRAME1MSGTYPE_POS (0) +#define BT_UART_MSG_FRAME1MSGTYPE_MSK \ + (0x7 << BT_UART_MSG_FRAME1MSGTYPE_POS) +#define BT_UART_MSG_FRAME1SSN_POS (3) +#define BT_UART_MSG_FRAME1SSN_MSK \ + (0x3 << BT_UART_MSG_FRAME1SSN_POS) +#define BT_UART_MSG_FRAME1UPDATEREQ_POS (5) +#define BT_UART_MSG_FRAME1UPDATEREQ_MSK \ + (0x1 << BT_UART_MSG_FRAME1UPDATEREQ_POS) +#define BT_UART_MSG_FRAME1RESERVED_POS (6) +#define BT_UART_MSG_FRAME1RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME1RESERVED_POS) + +#define BT_UART_MSG_FRAME2OPENCONNECTIONS_POS (0) +#define BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK \ + (0x3 << BT_UART_MSG_FRAME2OPENCONNECTIONS_POS) +#define BT_UART_MSG_FRAME2TRAFFICLOAD_POS (2) +#define BT_UART_MSG_FRAME2TRAFFICLOAD_MSK \ + (0x3 << BT_UART_MSG_FRAME2TRAFFICLOAD_POS) +#define BT_UART_MSG_FRAME2CHLSEQN_POS (4) +#define BT_UART_MSG_FRAME2CHLSEQN_MSK \ + (0x1 << BT_UART_MSG_FRAME2CHLSEQN_POS) +#define BT_UART_MSG_FRAME2INBAND_POS (5) +#define BT_UART_MSG_FRAME2INBAND_MSK \ + (0x1 << BT_UART_MSG_FRAME2INBAND_POS) +#define BT_UART_MSG_FRAME2RESERVED_POS (6) +#define BT_UART_MSG_FRAME2RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME2RESERVED_POS) + +#define BT_UART_MSG_FRAME3SCOESCO_POS (0) +#define BT_UART_MSG_FRAME3SCOESCO_MSK \ + (0x1 << BT_UART_MSG_FRAME3SCOESCO_POS) +#define BT_UART_MSG_FRAME3SNIFF_POS (1) +#define BT_UART_MSG_FRAME3SNIFF_MSK \ + (0x1 << BT_UART_MSG_FRAME3SNIFF_POS) +#define BT_UART_MSG_FRAME3A2DP_POS (2) +#define BT_UART_MSG_FRAME3A2DP_MSK \ + (0x1 << BT_UART_MSG_FRAME3A2DP_POS) +#define BT_UART_MSG_FRAME3ACL_POS (3) +#define BT_UART_MSG_FRAME3ACL_MSK \ + (0x1 << BT_UART_MSG_FRAME3ACL_POS) +#define BT_UART_MSG_FRAME3MASTER_POS (4) +#define BT_UART_MSG_FRAME3MASTER_MSK \ + (0x1 << BT_UART_MSG_FRAME3MASTER_POS) +#define BT_UART_MSG_FRAME3OBEX_POS (5) +#define BT_UART_MSG_FRAME3OBEX_MSK \ + (0x1 << BT_UART_MSG_FRAME3OBEX_POS) +#define BT_UART_MSG_FRAME3RESERVED_POS (6) +#define BT_UART_MSG_FRAME3RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME3RESERVED_POS) + +#define BT_UART_MSG_FRAME4IDLEDURATION_POS (0) +#define BT_UART_MSG_FRAME4IDLEDURATION_MSK \ + (0x3F << BT_UART_MSG_FRAME4IDLEDURATION_POS) +#define BT_UART_MSG_FRAME4RESERVED_POS (6) +#define BT_UART_MSG_FRAME4RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME4RESERVED_POS) + +#define BT_UART_MSG_FRAME5TXACTIVITY_POS (0) +#define BT_UART_MSG_FRAME5TXACTIVITY_MSK \ + (0x3 << BT_UART_MSG_FRAME5TXACTIVITY_POS) +#define BT_UART_MSG_FRAME5RXACTIVITY_POS (2) +#define BT_UART_MSG_FRAME5RXACTIVITY_MSK \ + (0x3 << BT_UART_MSG_FRAME5RXACTIVITY_POS) +#define BT_UART_MSG_FRAME5ESCORETRANSMIT_POS (4) +#define BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK \ + (0x3 << BT_UART_MSG_FRAME5ESCORETRANSMIT_POS) +#define BT_UART_MSG_FRAME5RESERVED_POS (6) +#define BT_UART_MSG_FRAME5RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME5RESERVED_POS) + +#define BT_UART_MSG_FRAME6SNIFFINTERVAL_POS (0) +#define BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK \ + (0x1F << BT_UART_MSG_FRAME6SNIFFINTERVAL_POS) +#define BT_UART_MSG_FRAME6DISCOVERABLE_POS (5) +#define BT_UART_MSG_FRAME6DISCOVERABLE_MSK \ + (0x1 << BT_UART_MSG_FRAME6DISCOVERABLE_POS) +#define BT_UART_MSG_FRAME6RESERVED_POS (6) +#define BT_UART_MSG_FRAME6RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME6RESERVED_POS) + +#define BT_UART_MSG_FRAME7SNIFFACTIVITY_POS (0) +#define BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK \ + (0x7 << BT_UART_MSG_FRAME7SNIFFACTIVITY_POS) +#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS (3) +#define BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_MSK \ + (0x3 << BT_UART_MSG_FRAME7INQUIRYPAGESRMODE_POS) +#define BT_UART_MSG_FRAME7CONNECTABLE_POS (5) +#define BT_UART_MSG_FRAME7CONNECTABLE_MSK \ + (0x1 << BT_UART_MSG_FRAME7CONNECTABLE_POS) +#define BT_UART_MSG_FRAME7RESERVED_POS (6) +#define BT_UART_MSG_FRAME7RESERVED_MSK \ + (0x3 << BT_UART_MSG_FRAME7RESERVED_POS) + + +struct iwl_bt_uart_msg { + u8 header; + u8 frame1; + u8 frame2; + u8 frame3; + u8 frame4; + u8 frame5; + u8 frame6; + u8 frame7; +} __attribute__((packed)); + +struct iwl_bt_coex_profile_notif { + struct iwl_bt_uart_msg last_bt_uart_msg; + u8 bt_status; /* 0 - off, 1 - on */ + u8 bt_traffic_load; /* 0 .. 3? */ + u8 bt_ci_compliance; /* 0 - not complied, 1 - complied */ + u8 reserved; +} __attribute__((packed)); + +#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_POS 0 +#define IWL_BT_COEX_PRIO_TBL_SHARED_ANTENNA_MSK 0x1 +#define IWL_BT_COEX_PRIO_TBL_PRIO_POS 1 +#define IWL_BT_COEX_PRIO_TBL_PRIO_MASK 0x0e +#define IWL_BT_COEX_PRIO_TBL_RESERVED_POS 4 +#define IWL_BT_COEX_PRIO_TBL_RESERVED_MASK 0xf0 +#define IWL_BT_COEX_PRIO_TBL_PRIO_SHIFT 1 + +/* + * BT Coexistence Priority table + * REPLY_BT_COEX_PRIO_TABLE = 0xcc + */ +enum bt_coex_prio_table_events { + BT_COEX_PRIO_TBL_EVT_INIT_CALIB1 = 0, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2 = 1, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW1 = 2, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_LOW2 = 3, /* DC calib */ + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH1 = 4, + BT_COEX_PRIO_TBL_EVT_PERIODIC_CALIB_HIGH2 = 5, + BT_COEX_PRIO_TBL_EVT_DTIM = 6, + BT_COEX_PRIO_TBL_EVT_SCAN52 = 7, + BT_COEX_PRIO_TBL_EVT_SCAN24 = 8, + BT_COEX_PRIO_TBL_EVT_RESERVED0 = 9, + BT_COEX_PRIO_TBL_EVT_RESERVED1 = 10, + BT_COEX_PRIO_TBL_EVT_RESERVED2 = 11, + BT_COEX_PRIO_TBL_EVT_RESERVED3 = 12, + BT_COEX_PRIO_TBL_EVT_RESERVED4 = 13, + BT_COEX_PRIO_TBL_EVT_RESERVED5 = 14, + BT_COEX_PRIO_TBL_EVT_RESERVED6 = 15, + /* BT_COEX_PRIO_TBL_EVT_MAX should always be last */ + BT_COEX_PRIO_TBL_EVT_MAX, +}; + +enum bt_coex_prio_table_priorities { + BT_COEX_PRIO_TBL_DISABLED = 0, + BT_COEX_PRIO_TBL_PRIO_LOW = 1, + BT_COEX_PRIO_TBL_PRIO_HIGH = 2, + BT_COEX_PRIO_TBL_PRIO_BYPASS = 3, + BT_COEX_PRIO_TBL_PRIO_COEX_OFF = 4, + BT_COEX_PRIO_TBL_PRIO_COEX_ON = 5, + BT_COEX_PRIO_TBL_PRIO_RSRVD1 = 6, + BT_COEX_PRIO_TBL_PRIO_RSRVD2 = 7, + BT_COEX_PRIO_TBL_MAX, +}; + +struct iwl_bt_coex_prio_table_cmd { + u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; +} __attribute__((packed)); + +#define IWL_BT_COEX_ENV_CLOSE 0 +#define IWL_BT_COEX_ENV_OPEN 1 +/* + * BT Protection Envelope + * REPLY_BT_COEX_PROT_ENV = 0xcd + */ +struct iwl_bt_coex_prot_env_cmd { + u8 action; /* 0 = closed, 1 = open */ + u8 type; /* 0 .. 15 */ + u8 reserved[2]; +} __attribute__((packed)); + /****************************************************************************** * (13) * Union of all expected notifications/responses: @@ -3993,6 +4345,7 @@ struct iwl_rx_packet { struct iwl_missed_beacon_notif missed_beacon; struct iwl_coex_medium_notification coex_medium_notif; struct iwl_coex_event_resp coex_event; + struct iwl_bt_coex_profile_notif bt_coex_profile_notif; __le32 status; u8 raw[0]; } u; @@ -4000,4 +4353,94 @@ struct iwl_rx_packet { int iwl_agn_check_rxon_cmd(struct iwl_priv *priv); +/* + * REPLY_WIPAN_PARAMS = 0xb2 (Commands and Notification) + */ + +/** + * struct iwl_wipan_slot + * @width: Time in TU + * @type: + * 0 - BSS + * 1 - PAN + */ +struct iwl_wipan_slot { + __le16 width; + u8 type; + u8 reserved; +} __packed; + +#define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_CTS BIT(1) /* reserved */ +#define IWL_WIPAN_PARAMS_FLG_LEAVE_CHANNEL_QUIET BIT(2) /* reserved */ +#define IWL_WIPAN_PARAMS_FLG_SLOTTED_MODE BIT(3) /* reserved */ +#define IWL_WIPAN_PARAMS_FLG_FILTER_BEACON_NOTIF BIT(4) +#define IWL_WIPAN_PARAMS_FLG_FULL_SLOTTED_MODE BIT(5) + +/** + * struct iwl_wipan_params_cmd + * @flags: + * bit0: reserved + * bit1: CP leave channel with CTS + * bit2: CP leave channel qith Quiet + * bit3: slotted mode + * 1 - work in slotted mode + * 0 - work in non slotted mode + * bit4: filter beacon notification + * bit5: full tx slotted mode. if this flag is set, + * uCode will perform leaving channel methods in context switch + * also when working in same channel mode + * @num_slots: 1 - 10 + */ +struct iwl_wipan_params_cmd { + __le16 flags; + u8 reserved; + u8 num_slots; + struct iwl_wipan_slot slots[10]; +} __packed; + +/* + * REPLY_WIPAN_P2P_CHANNEL_SWITCH = 0xb9 + * + * TODO: Figure out what this is used for, + * it can only switch between 2.4 GHz + * channels!! + */ + +struct iwl_wipan_p2p_channel_switch_cmd { + __le16 channel; + __le16 reserved; +}; + +/* + * REPLY_WIPAN_NOA_NOTIFICATION = 0xbc + * + * This is used by the device to notify us of the + * NoA schedule it determined so we can forward it + * to userspace for inclusion in probe responses. + * + * In beacons, the NoA schedule is simply appended + * to the frame we give the device. + */ + +struct iwl_wipan_noa_descriptor { + u8 count; + __le32 duration; + __le32 interval; + __le32 starttime; +} __packed; + +struct iwl_wipan_noa_attribute { + u8 id; + __le16 length; + u8 index; + u8 ct_window; + struct iwl_wipan_noa_descriptor descr0, descr1; + u8 reserved; +} __packed; + +struct iwl_wipan_noa_notification { + u32 noa_active; + struct iwl_wipan_noa_attribute noa_attribute; +} __packed; + #endif /* __iwl_commands_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index e23c4060a0f093e966ca355af1d466880f65b0ee..25fb3912342ceff334f6c2d82cb61defc5b0ee75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -64,97 +64,14 @@ MODULE_LICENSE("GPL"); * * default: bt_coex_active = true (BT_COEX_ENABLE) */ -static bool bt_coex_active = true; +bool bt_coex_active = true; +EXPORT_SYMBOL_GPL(bt_coex_active); module_param(bt_coex_active, bool, S_IRUGO); MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist"); -#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ - [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ - IWL_RATE_SISO_##s##M_PLCP, \ - IWL_RATE_MIMO2_##s##M_PLCP,\ - IWL_RATE_MIMO3_##s##M_PLCP,\ - IWL_RATE_##r##M_IEEE, \ - IWL_RATE_##ip##M_INDEX, \ - IWL_RATE_##in##M_INDEX, \ - IWL_RATE_##rp##M_INDEX, \ - IWL_RATE_##rn##M_INDEX, \ - IWL_RATE_##pp##M_INDEX, \ - IWL_RATE_##np##M_INDEX } - u32 iwl_debug_level; EXPORT_SYMBOL(iwl_debug_level); -/* - * Parameter order: - * rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate - * - * If there isn't a valid next or previous rate then INV is used which - * maps to IWL_RATE_INVALID - * - */ -const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { - IWL_DECLARE_RATE_INFO(1, INV, INV, 2, INV, 2, INV, 2), /* 1mbps */ - IWL_DECLARE_RATE_INFO(2, INV, 1, 5, 1, 5, 1, 5), /* 2mbps */ - IWL_DECLARE_RATE_INFO(5, INV, 2, 6, 2, 11, 2, 11), /*5.5mbps */ - IWL_DECLARE_RATE_INFO(11, INV, 9, 12, 9, 12, 5, 18), /* 11mbps */ - IWL_DECLARE_RATE_INFO(6, 6, 5, 9, 5, 11, 5, 11), /* 6mbps */ - IWL_DECLARE_RATE_INFO(9, 6, 6, 11, 6, 11, 5, 11), /* 9mbps */ - IWL_DECLARE_RATE_INFO(12, 12, 11, 18, 11, 18, 11, 18), /* 12mbps */ - IWL_DECLARE_RATE_INFO(18, 18, 12, 24, 12, 24, 11, 24), /* 18mbps */ - IWL_DECLARE_RATE_INFO(24, 24, 18, 36, 18, 36, 18, 36), /* 24mbps */ - IWL_DECLARE_RATE_INFO(36, 36, 24, 48, 24, 48, 24, 48), /* 36mbps */ - IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ - IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ - IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ - /* FIXME:RS: ^^ should be INV (legacy) */ -}; -EXPORT_SYMBOL(iwl_rates); - -int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) -{ - int idx = 0; - - /* HT rate format */ - if (rate_n_flags & RATE_MCS_HT_MSK) { - idx = (rate_n_flags & 0xff); - - if (idx >= IWL_RATE_MIMO3_6M_PLCP) - idx = idx - IWL_RATE_MIMO3_6M_PLCP; - else if (idx >= IWL_RATE_MIMO2_6M_PLCP) - idx = idx - IWL_RATE_MIMO2_6M_PLCP; - - idx += IWL_FIRST_OFDM_RATE; - /* skip 9M not supported in ht*/ - if (idx >= IWL_RATE_9M_INDEX) - idx += 1; - if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) - return idx; - - /* legacy rate format, search for match in table */ - } else { - for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) - if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) - return idx; - } - - return -1; -} -EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); - -u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid) -{ - int i; - u8 ind = ant; - - for (i = 0; i < RATE_ANT_NUM - 1; i++) { - ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0; - if (valid & BIT(ind)) - return ind; - } - return ant; -} -EXPORT_SYMBOL(iwl_toggle_tx_ant); - const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; EXPORT_SYMBOL(iwl_bcast_addr); @@ -183,38 +100,33 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, } EXPORT_SYMBOL(iwl_alloc_all); -void iwl_hw_detect(struct iwl_priv *priv) -{ - priv->hw_rev = _iwl_read32(priv, CSR_HW_REV); - priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG); - pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id); -} -EXPORT_SYMBOL(iwl_hw_detect); - /* * QoS support */ -static void iwl_update_qos(struct iwl_priv *priv) +static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - priv->qos_data.def_qos_parm.qos_flags = 0; + if (!ctx->is_active) + return; + + ctx->qos_data.def_qos_parm.qos_flags = 0; - if (priv->qos_data.qos_active) - priv->qos_data.def_qos_parm.qos_flags |= + if (ctx->qos_data.qos_active) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_UPDATE_EDCA_MSK; - if (priv->current_ht_config.is_ht) - priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; + if (ctx->ht.enabled) + ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n", - priv->qos_data.qos_active, - priv->qos_data.def_qos_parm.qos_flags); + ctx->qos_data.qos_active, + ctx->qos_data.def_qos_parm.qos_flags); - iwl_send_cmd_pdu_async(priv, REPLY_QOS_PARAM, + iwl_send_cmd_pdu_async(priv, ctx->qos_cmd, sizeof(struct iwl_qosparam_cmd), - &priv->qos_data.def_qos_parm, NULL); + &ctx->qos_data.def_qos_parm, NULL); } #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ @@ -232,7 +144,8 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, ht_info->ht_supported = true; - if (priv->cfg->ht_greenfield_support) + if (priv->cfg->ht_params && + priv->cfg->ht_params->ht_greenfield_support) ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; ht_info->cap |= IEEE80211_HT_CAP_SGI_20; max_bit_rate = MAX_BIT_RATE_20_MHZ; @@ -247,7 +160,11 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; + if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_factor) + ht_info->ampdu_factor = priv->cfg->bt_params->ampdu_factor; ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; + if (priv->cfg->bt_params && priv->cfg->bt_params->ampdu_density) + ht_info->ampdu_density = priv->cfg->bt_params->ampdu_density; ht_info->mcs.rx_mask[0] = 0xFF; if (rx_chains_num >= 2) @@ -434,21 +351,15 @@ void iwlcore_tx_cmd_protection(struct iwl_priv *priv, EXPORT_SYMBOL(iwlcore_tx_cmd_protection); -static bool is_single_rx_stream(struct iwl_priv *priv) -{ - return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC || - priv->current_ht_config.single_chain_sufficient; -} - -static u8 iwl_is_channel_extension(struct iwl_priv *priv, - enum ieee80211_band band, - u16 channel, u8 extension_chan_offset) +static bool iwl_is_channel_extension(struct iwl_priv *priv, + enum ieee80211_band band, + u16 channel, u8 extension_chan_offset) { const struct iwl_channel_info *ch_info; ch_info = iwl_get_channel_info(priv, band, channel); if (!is_channel_valid(ch_info)) - return 0; + return false; if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE) return !(ch_info->ht40_extension_channel & @@ -457,38 +368,59 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv, return !(ch_info->ht40_extension_channel & IEEE80211_CHAN_NO_HT40MINUS); - return 0; + return false; } -u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, - struct ieee80211_sta_ht_cap *sta_ht_inf) +bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_sta_ht_cap *ht_cap) { - struct iwl_ht_config *ht_conf = &priv->current_ht_config; - - if (!ht_conf->is_ht || !ht_conf->is_40mhz) - return 0; + if (!ctx->ht.enabled || !ctx->ht.is_40mhz) + return false; - /* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 + /* + * We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40 * the bit will not set if it is pure 40MHz case */ - if (sta_ht_inf) { - if (!sta_ht_inf->ht_supported) - return 0; - } + if (ht_cap && !ht_cap->ht_supported) + return false; + #ifdef CONFIG_IWLWIFI_DEBUGFS if (priv->disable_ht40) - return 0; + return false; #endif + return iwl_is_channel_extension(priv, priv->band, - le16_to_cpu(priv->staging_rxon.channel), - ht_conf->extension_chan_offset); + le16_to_cpu(ctx->staging.channel), + ctx->ht.extension_chan_offset); } EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) { - u16 new_val = 0; - u16 beacon_factor = 0; + u16 new_val; + u16 beacon_factor; + + /* + * If mac80211 hasn't given us a beacon interval, program + * the default into the device (not checking this here + * would cause the adjustment below to return the maximum + * value, which may break PAN.) + */ + if (!beacon_val) + return DEFAULT_BEACON_INTERVAL; + + /* + * If the beacon interval we obtained from the peer + * is too large, we'll have to wake up more often + * (and in IBSS case, we'll beacon too much) + * + * For example, if max_beacon_val is 4096, and the + * requested beacon interval is 7000, we'll have to + * use 3500 to be able to wake up on the beacons. + * + * This could badly influence beacon detection stats. + */ beacon_factor = (beacon_val + max_beacon_val) / max_beacon_val; new_val = beacon_val / beacon_factor; @@ -499,51 +431,76 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val) return new_val; } -void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif) +int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { u64 tsf; s32 interval_tm, rem; - unsigned long flags; struct ieee80211_conf *conf = NULL; u16 beacon_int; + struct ieee80211_vif *vif = ctx->vif; conf = ieee80211_get_hw_conf(priv->hw); - spin_lock_irqsave(&priv->lock, flags); - priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp); - priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval); + lockdep_assert_held(&priv->mutex); - beacon_int = vif->bss_conf.beacon_int; + memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd)); - if (vif->type == NL80211_IFTYPE_ADHOC) { - /* TODO: we need to get atim_window from upper stack - * for now we set to 0 */ - priv->rxon_timing.atim_window = 0; - } else { - priv->rxon_timing.atim_window = 0; - } + ctx->timing.timestamp = cpu_to_le64(priv->timestamp); + ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval); - beacon_int = iwl_adjust_beacon_interval(beacon_int, + beacon_int = vif ? vif->bss_conf.beacon_int : 0; + + /* + * TODO: For IBSS we need to get atim_window from mac80211, + * for now just always use 0 + */ + ctx->timing.atim_window = 0; + + if (ctx->ctxid == IWL_RXON_CTX_PAN && + (!ctx->vif || ctx->vif->type != NL80211_IFTYPE_STATION) && + iwl_is_associated(priv, IWL_RXON_CTX_BSS) && + priv->contexts[IWL_RXON_CTX_BSS].vif && + priv->contexts[IWL_RXON_CTX_BSS].vif->bss_conf.beacon_int) { + ctx->timing.beacon_interval = + priv->contexts[IWL_RXON_CTX_BSS].timing.beacon_interval; + beacon_int = le16_to_cpu(ctx->timing.beacon_interval); + } else if (ctx->ctxid == IWL_RXON_CTX_BSS && + iwl_is_associated(priv, IWL_RXON_CTX_PAN) && + priv->contexts[IWL_RXON_CTX_PAN].vif && + priv->contexts[IWL_RXON_CTX_PAN].vif->bss_conf.beacon_int && + (!iwl_is_associated_ctx(ctx) || !ctx->vif || + !ctx->vif->bss_conf.beacon_int)) { + ctx->timing.beacon_interval = + priv->contexts[IWL_RXON_CTX_PAN].timing.beacon_interval; + beacon_int = le16_to_cpu(ctx->timing.beacon_interval); + } else { + beacon_int = iwl_adjust_beacon_interval(beacon_int, priv->hw_params.max_beacon_itrvl * TIME_UNIT); - priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int); + ctx->timing.beacon_interval = cpu_to_le16(beacon_int); + } tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ interval_tm = beacon_int * TIME_UNIT; rem = do_div(tsf, interval_tm); - priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem); + ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem); + + ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ?: 1) : 1; - spin_unlock_irqrestore(&priv->lock, flags); IWL_DEBUG_ASSOC(priv, "beacon interval %d beacon timer %d beacon tim %d\n", - le16_to_cpu(priv->rxon_timing.beacon_interval), - le32_to_cpu(priv->rxon_timing.beacon_init_val), - le16_to_cpu(priv->rxon_timing.atim_window)); + le16_to_cpu(ctx->timing.beacon_interval), + le32_to_cpu(ctx->timing.beacon_init_val), + le16_to_cpu(ctx->timing.atim_window)); + + return iwl_send_cmd_pdu(priv, ctx->rxon_timing_cmd, + sizeof(ctx->timing), &ctx->timing); } -EXPORT_SYMBOL(iwl_setup_rxon_timing); +EXPORT_SYMBOL(iwl_send_rxon_timing); -void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) +void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + int hw_decrypt) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl_rxon_cmd *rxon = &ctx->staging; if (hw_decrypt) rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; @@ -553,76 +510,74 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) } EXPORT_SYMBOL(iwl_set_rxon_hwcrypto); -/** - * iwl_check_rxon_cmd - validate RXON structure is valid - * - * NOTE: This is really only useful during development and can eventually - * be #ifdef'd out once the driver is stable and folks aren't actively - * making changes - */ -int iwl_check_rxon_cmd(struct iwl_priv *priv) +/* validate RXON structure is valid */ +int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { - int error = 0; - int counter = 1; - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl_rxon_cmd *rxon = &ctx->staging; + bool error = false; if (rxon->flags & RXON_FLG_BAND_24G_MSK) { - error |= le32_to_cpu(rxon->flags & - (RXON_FLG_TGJ_NARROW_BAND_MSK | - RXON_FLG_RADAR_DETECT_MSK)); - if (error) - IWL_WARN(priv, "check 24G fields %d | %d\n", - counter++, error); + if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { + IWL_WARN(priv, "check 2.4G: wrong narrow\n"); + error = true; + } + if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { + IWL_WARN(priv, "check 2.4G: wrong radar\n"); + error = true; + } } else { - error |= (rxon->flags & RXON_FLG_SHORT_SLOT_MSK) ? - 0 : le32_to_cpu(RXON_FLG_SHORT_SLOT_MSK); - if (error) - IWL_WARN(priv, "check 52 fields %d | %d\n", - counter++, error); - error |= le32_to_cpu(rxon->flags & RXON_FLG_CCK_MSK); - if (error) - IWL_WARN(priv, "check 52 CCK %d | %d\n", - counter++, error); - } - error |= (rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1; - if (error) - IWL_WARN(priv, "check mac addr %d | %d\n", counter++, error); + if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { + IWL_WARN(priv, "check 5.2G: not short slot!\n"); + error = true; + } + if (rxon->flags & RXON_FLG_CCK_MSK) { + IWL_WARN(priv, "check 5.2G: CCK!\n"); + error = true; + } + } + if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { + IWL_WARN(priv, "mac/bssid mcast!\n"); + error = true; + } /* make sure basic rates 6Mbps and 1Mbps are supported */ - error |= (((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0) && - ((rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0)); - if (error) - IWL_WARN(priv, "check basic rate %d | %d\n", counter++, error); + if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 && + (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) { + IWL_WARN(priv, "neither 1 nor 6 are basic\n"); + error = true; + } - error |= (le16_to_cpu(rxon->assoc_id) > 2007); - if (error) - IWL_WARN(priv, "check assoc id %d | %d\n", counter++, error); + if (le16_to_cpu(rxon->assoc_id) > 2007) { + IWL_WARN(priv, "aid > 2007\n"); + error = true; + } - error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) - == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)); - if (error) - IWL_WARN(priv, "check CCK and short slot %d | %d\n", - counter++, error); + if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) + == (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { + IWL_WARN(priv, "CCK and short slot\n"); + error = true; + } - error |= ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) - == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)); - if (error) - IWL_WARN(priv, "check CCK & auto detect %d | %d\n", - counter++, error); + if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) + == (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { + IWL_WARN(priv, "CCK and auto detect"); + error = true; + } - error |= ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | - RXON_FLG_TGG_PROTECT_MSK)) == RXON_FLG_TGG_PROTECT_MSK); - if (error) - IWL_WARN(priv, "check TGG and auto detect %d | %d\n", - counter++, error); + if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | + RXON_FLG_TGG_PROTECT_MSK)) == + RXON_FLG_TGG_PROTECT_MSK) { + IWL_WARN(priv, "TGg but no auto-detect\n"); + error = true; + } if (error) IWL_WARN(priv, "Tuning to channel %d\n", le16_to_cpu(rxon->channel)); if (error) { - IWL_ERR(priv, "Not a valid iwl_rxon_assoc_cmd field values\n"); - return -1; + IWL_ERR(priv, "Invalid RXON\n"); + return -EINVAL; } return 0; } @@ -636,66 +591,83 @@ EXPORT_SYMBOL(iwl_check_rxon_cmd); * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. */ -int iwl_full_rxon_required(struct iwl_priv *priv) +int iwl_full_rxon_required(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { + const struct iwl_rxon_cmd *staging = &ctx->staging; + const struct iwl_rxon_cmd *active = &ctx->active; + +#define CHK(cond) \ + if ((cond)) { \ + IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n"); \ + return 1; \ + } + +#define CHK_NEQ(c1, c2) \ + if ((c1) != (c2)) { \ + IWL_DEBUG_INFO(priv, "need full RXON - " \ + #c1 " != " #c2 " - %d != %d\n", \ + (c1), (c2)); \ + return 1; \ + } /* These items are only settable from the full RXON command */ - if (!(iwl_is_associated(priv)) || - compare_ether_addr(priv->staging_rxon.bssid_addr, - priv->active_rxon.bssid_addr) || - compare_ether_addr(priv->staging_rxon.node_addr, - priv->active_rxon.node_addr) || - compare_ether_addr(priv->staging_rxon.wlap_bssid_addr, - priv->active_rxon.wlap_bssid_addr) || - (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) || - (priv->staging_rxon.channel != priv->active_rxon.channel) || - (priv->staging_rxon.air_propagation != - priv->active_rxon.air_propagation) || - (priv->staging_rxon.ofdm_ht_single_stream_basic_rates != - priv->active_rxon.ofdm_ht_single_stream_basic_rates) || - (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != - priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || - (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates != - priv->active_rxon.ofdm_ht_triple_stream_basic_rates) || - (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) - return 1; + CHK(!iwl_is_associated_ctx(ctx)); + CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); + CHK(compare_ether_addr(staging->node_addr, active->node_addr)); + CHK(compare_ether_addr(staging->wlap_bssid_addr, + active->wlap_bssid_addr)); + CHK_NEQ(staging->dev_type, active->dev_type); + CHK_NEQ(staging->channel, active->channel); + CHK_NEQ(staging->air_propagation, active->air_propagation); + CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates, + active->ofdm_ht_single_stream_basic_rates); + CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates, + active->ofdm_ht_dual_stream_basic_rates); + CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates, + active->ofdm_ht_triple_stream_basic_rates); + CHK_NEQ(staging->assoc_id, active->assoc_id); /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can * be updated with the RXON_ASSOC command -- however only some * flag transitions are allowed using RXON_ASSOC */ /* Check if we are not switching bands */ - if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) != - (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)) - return 1; + CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK, + active->flags & RXON_FLG_BAND_24G_MSK); /* Check if we are switching association toggle */ - if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) != - (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) - return 1; + CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK, + active->filter_flags & RXON_FILTER_ASSOC_MSK); + +#undef CHK +#undef CHK_NEQ return 0; } EXPORT_SYMBOL(iwl_full_rxon_required); -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) +u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { /* * Assign the lowest rate -- should really get this from * the beacon skb from mac80211. */ - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) return IWL_RATE_1M_PLCP; else return IWL_RATE_6M_PLCP; } EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); -void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) +static void _iwl_set_rxon_ht(struct iwl_priv *priv, + struct iwl_ht_config *ht_conf, + struct iwl_rxon_context *ctx) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl_rxon_cmd *rxon = &ctx->staging; - if (!ht_conf->is_ht) { + if (!ctx->ht.enabled) { rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK | @@ -703,22 +675,22 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) return; } - /* FIXME: if the definition of ht_protection changed, the "translation" + /* FIXME: if the definition of ht.protection changed, the "translation" * will be needed for rxon->flags */ - rxon->flags |= cpu_to_le32(ht_conf->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS); + rxon->flags |= cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS); /* Set up channel bandwidth: * 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */ /* clear the HT channel mode before set the mode */ rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); - if (iwl_is_ht40_tx_allowed(priv, NULL)) { + if (iwl_is_ht40_tx_allowed(priv, ctx, NULL)) { /* pure ht40 */ - if (ht_conf->ht_protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { + if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) { rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40; /* Note: control channel is opposite of extension channel */ - switch (ht_conf->extension_chan_offset) { + switch (ctx->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; break; @@ -728,7 +700,7 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) } } else { /* Note: control channel is opposite of extension channel */ - switch (ht_conf->extension_chan_offset) { + switch (ctx->ht.extension_chan_offset) { case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED; @@ -749,162 +721,58 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) } if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " "extension channel offset 0x%x\n", - le32_to_cpu(rxon->flags), ht_conf->ht_protection, - ht_conf->extension_chan_offset); -} -EXPORT_SYMBOL(iwl_set_rxon_ht); - -#define IWL_NUM_RX_CHAINS_MULTIPLE 3 -#define IWL_NUM_RX_CHAINS_SINGLE 2 -#define IWL_NUM_IDLE_CHAINS_DUAL 2 -#define IWL_NUM_IDLE_CHAINS_SINGLE 1 - -/* - * Determine how many receiver/antenna chains to use. - * - * More provides better reception via diversity. Fewer saves power - * at the expense of throughput, but only when not in powersave to - * start with. - * - * MIMO (dual stream) requires at least 2, but works better with 3. - * This does not determine *which* chains to use, just how many. - */ -static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) -{ - /* # of Rx chains to use when expecting MIMO. */ - if (is_single_rx_stream(priv)) - return IWL_NUM_RX_CHAINS_SINGLE; - else - return IWL_NUM_RX_CHAINS_MULTIPLE; -} - -/* - * When we are in power saving mode, unless device support spatial - * multiplexing power save, use the active count for rx chain count. - */ -static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) -{ - /* # Rx chains when idling, depending on SMPS mode */ - switch (priv->current_ht_config.smps) { - case IEEE80211_SMPS_STATIC: - case IEEE80211_SMPS_DYNAMIC: - return IWL_NUM_IDLE_CHAINS_SINGLE; - case IEEE80211_SMPS_OFF: - return active_cnt; - default: - WARN(1, "invalid SMPS mode %d", - priv->current_ht_config.smps); - return active_cnt; - } + le32_to_cpu(rxon->flags), ctx->ht.protection, + ctx->ht.extension_chan_offset); } -/* up to 4 chains */ -static u8 iwl_count_chain_bitmap(u32 chain_bitmap) +void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) { - u8 res; - res = (chain_bitmap & BIT(0)) >> 0; - res += (chain_bitmap & BIT(1)) >> 1; - res += (chain_bitmap & BIT(2)) >> 2; - res += (chain_bitmap & BIT(3)) >> 3; - return res; -} - -/** - * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image - * - * Selects how many and which Rx receivers/antennas/chains to use. - * This should not be used for scan command ... it puts data in wrong place. - */ -void iwl_set_rxon_chain(struct iwl_priv *priv) -{ - bool is_single = is_single_rx_stream(priv); - bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); - u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt; - u32 active_chains; - u16 rx_chain; - - /* Tell uCode which antennas are actually connected. - * Before first association, we assume all antennas are connected. - * Just after first association, iwl_chain_noise_calibration() - * checks which antennas actually *are* connected. */ - if (priv->chain_noise_data.active_chains) - active_chains = priv->chain_noise_data.active_chains; - else - active_chains = priv->hw_params.valid_rx_ant; - - rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS; - - /* How many receivers should we use? */ - active_rx_cnt = iwl_get_active_rx_chain_count(priv); - idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); - - - /* correct rx chain count according hw settings - * and chain noise calibration - */ - valid_rx_cnt = iwl_count_chain_bitmap(active_chains); - if (valid_rx_cnt < active_rx_cnt) - active_rx_cnt = valid_rx_cnt; - - if (valid_rx_cnt < idle_rx_cnt) - idle_rx_cnt = valid_rx_cnt; - - rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; - rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; - - priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); - - if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) - priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; - else - priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; + struct iwl_rxon_context *ctx; - IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n", - priv->staging_rxon.rx_chain, - active_rx_cnt, idle_rx_cnt); - - WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || - active_rx_cnt < idle_rx_cnt); + for_each_context(priv, ctx) + _iwl_set_rxon_ht(priv, ht_conf, ctx); } -EXPORT_SYMBOL(iwl_set_rxon_chain); +EXPORT_SYMBOL(iwl_set_rxon_ht); -/* Return valid channel */ +/* Return valid, unused, channel for a passive scan to reset the RF */ u8 iwl_get_single_channel_number(struct iwl_priv *priv, - enum ieee80211_band band) + enum ieee80211_band band) { const struct iwl_channel_info *ch_info; int i; u8 channel = 0; + u8 min, max; + struct iwl_rxon_context *ctx; - /* only scan single channel, good enough to reset the RF */ - /* pick the first valid not in-use channel */ if (band == IEEE80211_BAND_5GHZ) { - for (i = 14; i < priv->channel_count; i++) { - if (priv->channel_info[i].channel != - le16_to_cpu(priv->staging_rxon.channel)) { - channel = priv->channel_info[i].channel; - ch_info = iwl_get_channel_info(priv, - band, channel); - if (is_channel_valid(ch_info)) - break; - } - } + min = 14; + max = priv->channel_count; } else { - for (i = 0; i < 14; i++) { - if (priv->channel_info[i].channel != - le16_to_cpu(priv->staging_rxon.channel)) { - channel = - priv->channel_info[i].channel; - ch_info = iwl_get_channel_info(priv, - band, channel); - if (is_channel_valid(ch_info)) - break; - } + min = 0; + max = 14; + } + + for (i = min; i < max; i++) { + bool busy = false; + + for_each_context(priv, ctx) { + busy = priv->channel_info[i].channel == + le16_to_cpu(ctx->staging.channel); + if (busy) + break; } + + if (busy) + continue; + + channel = priv->channel_info[i].channel; + ch_info = iwl_get_channel_info(priv, band, channel); + if (is_channel_valid(ch_info)) + break; } return channel; @@ -912,35 +780,27 @@ u8 iwl_get_single_channel_number(struct iwl_priv *priv, EXPORT_SYMBOL(iwl_get_single_channel_number); /** - * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON - * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz - * @channel: Any channel valid for the requested phymode + * iwl_set_rxon_channel - Set the band and channel values in staging RXON + * @ch: requested channel as a pointer to struct ieee80211_channel - * In addition to setting the staging RXON, priv->phymode is also set. - * * NOTE: Does not commit to the hardware; it sets appropriate bit fields - * in the staging RXON flag structure based on the phymode + * in the staging RXON flag structure based on the ch->band */ -int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) +int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, + struct iwl_rxon_context *ctx) { enum ieee80211_band band = ch->band; - u16 channel = ieee80211_frequency_to_channel(ch->center_freq); + u16 channel = ch->hw_value; - if (!iwl_get_channel_info(priv, band, channel)) { - IWL_DEBUG_INFO(priv, "Could not set channel to %d [%d]\n", - channel, band); - return -EINVAL; - } - - if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && + if ((le16_to_cpu(ctx->staging.channel) == channel) && (priv->band == band)) return 0; - priv->staging_rxon.channel = cpu_to_le16(channel); + ctx->staging.channel = cpu_to_le16(channel); if (band == IEEE80211_BAND_5GHZ) - priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; + ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK; else - priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; + ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; priv->band = band; @@ -951,24 +811,25 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) EXPORT_SYMBOL(iwl_set_rxon_channel); void iwl_set_flags_for_band(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, enum ieee80211_band band, struct ieee80211_vif *vif) { if (band == IEEE80211_BAND_5GHZ) { - priv->staging_rxon.flags &= + ctx->staging.flags &= ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_CCK_MSK); - priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; } else { /* Copied from iwl_post_associate() */ if (vif && vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; - priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; - priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; - priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; + ctx->staging.flags |= RXON_FLG_BAND_24G_MSK; + ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK; + ctx->staging.flags &= ~RXON_FLG_CCK_MSK; } } EXPORT_SYMBOL(iwl_set_flags_for_band); @@ -977,35 +838,34 @@ EXPORT_SYMBOL(iwl_set_flags_for_band); * initialize rxon structure with default values from eeprom */ void iwl_connection_init_rx_config(struct iwl_priv *priv, - struct ieee80211_vif *vif) + struct iwl_rxon_context *ctx) { const struct iwl_channel_info *ch_info; - enum nl80211_iftype type = NL80211_IFTYPE_STATION; - if (vif) - type = vif->type; + memset(&ctx->staging, 0, sizeof(ctx->staging)); - memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); - - switch (type) { + if (!ctx->vif) { + ctx->staging.dev_type = ctx->unused_devtype; + } else switch (ctx->vif->type) { case NL80211_IFTYPE_AP: - priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; + ctx->staging.dev_type = ctx->ap_devtype; break; case NL80211_IFTYPE_STATION: - priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS; - priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; + ctx->staging.dev_type = ctx->station_devtype; + ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; break; case NL80211_IFTYPE_ADHOC: - priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS; - priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK; - priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK | + ctx->staging.dev_type = ctx->ibss_devtype; + ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK; break; default: - IWL_ERR(priv, "Unsupported interface type %d\n", type); + IWL_ERR(priv, "Unsupported interface type %d\n", + ctx->vif->type); break; } @@ -1013,37 +873,36 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, /* TODO: Figure out when short_preamble would be set and cache from * that */ if (!hw_to_local(priv->hw)->short_preamble) - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; #endif ch_info = iwl_get_channel_info(priv, priv->band, - le16_to_cpu(priv->active_rxon.channel)); + le16_to_cpu(ctx->active.channel)); if (!ch_info) ch_info = &priv->channel_info[0]; - priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); + ctx->staging.channel = cpu_to_le16(ch_info->channel); priv->band = ch_info->band; - iwl_set_flags_for_band(priv, priv->band, vif); + iwl_set_flags_for_band(priv, ctx, priv->band, ctx->vif); - priv->staging_rxon.ofdm_basic_rates = + ctx->staging.ofdm_basic_rates = (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; - priv->staging_rxon.cck_basic_rates = + ctx->staging.cck_basic_rates = (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; /* clear both MIX and PURE40 mode flag */ - priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | + ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40); + if (ctx->vif) + memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN); - if (vif) - memcpy(priv->staging_rxon.node_addr, vif->addr, ETH_ALEN); - - priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; - priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; - priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff; + ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff; + ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff; + ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff; } EXPORT_SYMBOL(iwl_connection_init_rx_config); @@ -1051,6 +910,7 @@ void iwl_set_rate(struct iwl_priv *priv) { const struct ieee80211_supported_band *hw = NULL; struct ieee80211_rate *rate; + struct iwl_rxon_context *ctx; int i; hw = iwl_get_hw_mode(priv, priv->band); @@ -1069,21 +929,29 @@ void iwl_set_rate(struct iwl_priv *priv) IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate); - priv->staging_rxon.cck_basic_rates = - (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; + for_each_context(priv, ctx) { + ctx->staging.cck_basic_rates = + (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; - priv->staging_rxon.ofdm_basic_rates = - (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; + ctx->staging.ofdm_basic_rates = + (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; + } } EXPORT_SYMBOL(iwl_set_rate); void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) { + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; if (priv->switch_rxon.switch_in_progress) { - ieee80211_chswitch_done(priv->vif, is_success); + ieee80211_chswitch_done(ctx->vif, is_success); mutex_lock(&priv->mutex); priv->switch_rxon.switch_in_progress = false; mutex_unlock(&priv->mutex); @@ -1094,14 +962,19 @@ EXPORT_SYMBOL(iwl_chswitch_done); void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon; struct iwl_csa_notification *csa = &(pkt->u.csa_notif); + /* + * MULTI-FIXME + * See iwl_mac_channel_switch. + */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + struct iwl_rxon_cmd *rxon = (void *)&ctx->active; if (priv->switch_rxon.switch_in_progress) { if (!le32_to_cpu(csa->status) && (csa->channel == priv->switch_rxon.channel)) { rxon->channel = csa->channel; - priv->staging_rxon.channel = csa->channel; + ctx->staging.channel = csa->channel; IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", le16_to_cpu(csa->channel)); iwl_chswitch_done(priv, true); @@ -1115,9 +988,10 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) EXPORT_SYMBOL(iwl_rx_csa); #ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv) +void iwl_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; + struct iwl_rxon_cmd *rxon = &ctx->staging; IWL_DEBUG_RADIO(priv, "RX CONFIG:\n"); iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); @@ -1157,7 +1031,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv) priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) - iwl_print_rx_config_cmd(priv); + iwl_print_rx_config_cmd(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); #endif wake_up_interruptible(&priv->wait_command_queue); @@ -1261,7 +1136,7 @@ int iwl_apm_init(struct iwl_priv *priv) * If not (unlikely), enable L0S, so there is at least some * power savings, even without L1. */ - if (priv->cfg->set_l0s) { + if (priv->cfg->base_params->set_l0s) { lctl = iwl_pcie_link_ctl(priv); if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) { @@ -1278,8 +1153,9 @@ int iwl_apm_init(struct iwl_priv *priv) } /* Configure analog phase-lock-loop before activating to D0A */ - if (priv->cfg->pll_cfg_val) - iwl_set_bit(priv, CSR_ANA_PLL_CFG, priv->cfg->pll_cfg_val); + if (priv->cfg->base_params->pll_cfg_val) + iwl_set_bit(priv, CSR_ANA_PLL_CFG, + priv->cfg->base_params->pll_cfg_val); /* * Set "initialization complete" bit to move adapter from @@ -1310,7 +1186,7 @@ int iwl_apm_init(struct iwl_priv *priv) * do not disable clocks. This preserves any hardware bits already * set by default in "CLK_CTRL_REG" after reset. */ - if (priv->cfg->use_bsm) + if (priv->cfg->base_params->use_bsm) iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT); else @@ -1328,25 +1204,6 @@ int iwl_apm_init(struct iwl_priv *priv) EXPORT_SYMBOL(iwl_apm_init); -int iwl_set_hw_params(struct iwl_priv *priv) -{ - priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; - priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; - if (priv->cfg->mod_params->amsdu_size_8K) - priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); - else - priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); - - priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; - - if (priv->cfg->mod_params->disable_11n) - priv->cfg->sku &= ~IWL_SKU_N; - - /* Device-specific setup */ - return priv->cfg->ops->lib->set_hw_params(priv); -} -EXPORT_SYMBOL(iwl_set_hw_params); - int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret = 0; @@ -1496,76 +1353,6 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear) } EXPORT_SYMBOL(iwl_send_statistics_request); -void iwl_rf_kill_ct_config(struct iwl_priv *priv) -{ - struct iwl_ct_kill_config cmd; - struct iwl_ct_kill_throttling_config adv_cmd; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, - CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - spin_unlock_irqrestore(&priv->lock, flags); - priv->thermal_throttle.ct_kill_toggle = false; - - if (priv->cfg->support_ct_kill_exit) { - adv_cmd.critical_temperature_enter = - cpu_to_le32(priv->hw_params.ct_kill_threshold); - adv_cmd.critical_temperature_exit = - cpu_to_le32(priv->hw_params.ct_kill_exit_threshold); - - ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, - sizeof(adv_cmd), &adv_cmd); - if (ret) - IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); - else - IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " - "succeeded, " - "critical temperature enter is %d," - "exit is %d\n", - priv->hw_params.ct_kill_threshold, - priv->hw_params.ct_kill_exit_threshold); - } else { - cmd.critical_temperature_R = - cpu_to_le32(priv->hw_params.ct_kill_threshold); - - ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, - sizeof(cmd), &cmd); - if (ret) - IWL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n"); - else - IWL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD " - "succeeded, " - "critical temperature is %d\n", - priv->hw_params.ct_kill_threshold); - } -} -EXPORT_SYMBOL(iwl_rf_kill_ct_config); - - -/* - * CARD_STATE_CMD - * - * Use: Sets the device's internal card state to enable, disable, or halt - * - * When in the 'enable' state the card operates as normal. - * When in the 'disable' state, the card enters into a low power mode. - * When in the 'halt' state, the card is shut down and must be fully - * restarted to come back on. - */ -int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_CARD_STATE_CMD, - .len = sizeof(u32), - .data = &flags, - .flags = meta_flag, - }; - - return iwl_send_cmd(priv, &cmd); -} - void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { @@ -1614,6 +1401,7 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx; unsigned long flags; int q; @@ -1633,13 +1421,21 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, spin_lock_irqsave(&priv->lock, flags); - priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min); - priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max); - priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; - priv->qos_data.def_qos_parm.ac[q].edca_txop = - cpu_to_le16((params->txop * 32)); + /* + * MULTI-FIXME + * This may need to be done per interface in nl80211/cfg80211/mac80211. + */ + for_each_context(priv, ctx) { + ctx->qos_data.def_qos_parm.ac[q].cw_min = + cpu_to_le16(params->cw_min); + ctx->qos_data.def_qos_parm.ac[q].cw_max = + cpu_to_le16(params->cw_max); + ctx->qos_data.def_qos_parm.ac[q].aifsn = params->aifs; + ctx->qos_data.def_qos_parm.ac[q].edca_txop = + cpu_to_le16((params->txop * 32)); - priv->qos_data.def_qos_parm.ac[q].reserved1 = 0; + ctx->qos_data.def_qos_parm.ac[q].reserved1 = 0; + } spin_unlock_irqrestore(&priv->lock, flags); @@ -1648,21 +1444,30 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, } EXPORT_SYMBOL(iwl_mac_conf_tx); +int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw) +{ + struct iwl_priv *priv = hw->priv; + + return priv->ibss_manager == IWL_IBSS_MANAGER; +} +EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); + static void iwl_ht_conf(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_ht_config *ht_conf = &priv->current_ht_config; struct ieee80211_sta *sta; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); IWL_DEBUG_MAC80211(priv, "enter:\n"); - if (!ht_conf->is_ht) + if (!ctx->ht.enabled) return; - ht_conf->ht_protection = + ctx->ht.protection = bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION; - ht_conf->non_GF_STA_present = + ctx->ht.non_gf_sta_present = !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); ht_conf->single_chain_sufficient = false; @@ -1706,49 +1511,63 @@ static void iwl_ht_conf(struct iwl_priv *priv, IWL_DEBUG_MAC80211(priv, "leave\n"); } -static inline void iwl_set_no_assoc(struct iwl_priv *priv) +static inline void iwl_set_no_assoc(struct iwl_priv *priv, + struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + iwl_led_disassociate(priv); /* * inform the ucode that there is no longer an * association and that no more packets should be * sent */ - priv->staging_rxon.filter_flags &= - ~RXON_FILTER_ASSOC_MSK; - priv->staging_rxon.assoc_id = 0; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + ctx->staging.assoc_id = 0; + iwlcore_commit_rxon(priv, ctx); } -static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) +static void iwlcore_beacon_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; unsigned long flags; __le64 timestamp; + struct sk_buff *skb = ieee80211_beacon_get(hw, vif); - IWL_DEBUG_MAC80211(priv, "enter\n"); + if (!skb) + return; - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); - return -EIO; + IWL_DEBUG_ASSOC(priv, "enter\n"); + + lockdep_assert_held(&priv->mutex); + + if (!priv->beacon_ctx) { + IWL_ERR(priv, "update beacon but no beacon context!\n"); + dev_kfree_skb(skb); + return; } spin_lock_irqsave(&priv->lock, flags); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); - priv->ibss_beacon = skb; + priv->beacon_skb = skb; timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; priv->timestamp = le64_to_cpu(timestamp); - IWL_DEBUG_MAC80211(priv, "leave\n"); + IWL_DEBUG_ASSOC(priv, "leave\n"); + spin_unlock_irqrestore(&priv->lock, flags); - priv->cfg->ops->lib->post_associate(priv, priv->vif); + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n"); + return; + } - return 0; + priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif); } void iwl_bss_info_changed(struct ieee80211_hw *hw, @@ -1757,6 +1576,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, u32 changes) { struct iwl_priv *priv = hw->priv; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); int ret; IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); @@ -1770,20 +1590,31 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, unsigned long flags; spin_lock_irqsave(&priv->lock, flags); - priv->qos_data.qos_active = bss_conf->qos; - iwl_update_qos(priv); + ctx->qos_data.qos_active = bss_conf->qos; + iwl_update_qos(priv, ctx); spin_unlock_irqrestore(&priv->lock, flags); } - if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { - dev_kfree_skb(priv->ibss_beacon); - priv->ibss_beacon = ieee80211_beacon_get(hw, vif); + if (changes & BSS_CHANGED_BEACON_ENABLED) { + /* + * the add_interface code must make sure we only ever + * have a single interface that could be beaconing at + * any time. + */ + if (vif->bss_conf.enable_beacon) + priv->beacon_ctx = ctx; + else + priv->beacon_ctx = NULL; } - if (changes & BSS_CHANGED_BEACON_INT) { - /* TODO: in AP mode, do something to make this take effect */ + if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) { + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = ieee80211_beacon_get(hw, vif); } + if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP) + iwl_send_rxon_timing(priv, ctx); + if (changes & BSS_CHANGED_BSSID) { IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid); @@ -1801,13 +1632,13 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, /* mac80211 only sets assoc when in STATION mode */ if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { - memcpy(priv->staging_rxon.bssid_addr, + memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); /* currently needed in a few places */ memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); } else { - priv->staging_rxon.filter_flags &= + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } @@ -1818,33 +1649,28 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, * mac80211 decides to do both changes at once because * it will invoke post_associate. */ - if (vif->type == NL80211_IFTYPE_ADHOC && - changes & BSS_CHANGED_BEACON) { - struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); - - if (beacon) - iwl_mac_beacon_update(hw, beacon); - } + if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON) + iwlcore_beacon_update(hw, vif); if (changes & BSS_CHANGED_ERP_PREAMBLE) { IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", bss_conf->use_short_preamble); if (bss_conf->use_short_preamble) - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; } if (changes & BSS_CHANGED_ERP_CTS_PROT) { IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) - priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; + ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; + ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK; if (bss_conf->use_cts_prot) - priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; + ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; else - priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; + ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN; } if (changes & BSS_CHANGED_BASIC_RATES) { @@ -1854,12 +1680,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, * like this here: * if (A-band) - priv->staging_rxon.ofdm_basic_rates = + ctx->staging.ofdm_basic_rates = bss_conf->basic_rates; else - priv->staging_rxon.ofdm_basic_rates = + ctx->staging.ofdm_basic_rates = bss_conf->basic_rates >> 4; - priv->staging_rxon.cck_basic_rates = + ctx->staging.cck_basic_rates = bss_conf->basic_rates & 0xF; */ } @@ -1868,7 +1694,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, iwl_ht_conf(priv, vif); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } if (changes & BSS_CHANGED_ASSOC) { @@ -1881,29 +1707,30 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, if (!iwl_is_rfkill(priv)) priv->cfg->ops->lib->post_associate(priv, vif); } else - iwl_set_no_assoc(priv); + iwl_set_no_assoc(priv, vif); } - if (changes && iwl_is_associated(priv) && bss_conf->aid) { + if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) { IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", changes); - ret = iwl_send_rxon_assoc(priv); + ret = iwl_send_rxon_assoc(priv, ctx); if (!ret) { /* Sync active_rxon with latest change. */ - memcpy((void *)&priv->active_rxon, - &priv->staging_rxon, + memcpy((void *)&ctx->active, + &ctx->staging, sizeof(struct iwl_rxon_cmd)); } } if (changes & BSS_CHANGED_BEACON_ENABLED) { if (vif->bss_conf.enable_beacon) { - memcpy(priv->staging_rxon.bssid_addr, + memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN); memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); + iwl_led_associate(priv); iwlcore_config_ap(priv, vif); } else - iwl_set_no_assoc(priv); + iwl_set_no_assoc(priv, vif); } if (changes & BSS_CHANGED_IBSS) { @@ -1915,6 +1742,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw, bss_conf->bssid); } + if (changes & BSS_CHANGED_IDLE && + priv->cfg->ops->hcmd->set_pan_params) { + if (priv->cfg->ops->hcmd->set_pan_params(priv)) + IWL_ERR(priv, "failed to update PAN params\n"); + } + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -1923,17 +1756,21 @@ EXPORT_SYMBOL(iwl_bss_info_changed); static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) { - iwl_connection_init_rx_config(priv, vif); + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); + + iwl_connection_init_rx_config(priv, ctx); if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); - return iwlcore_commit_rxon(priv); + return iwlcore_commit_rxon(priv, ctx); } int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + struct iwl_rxon_context *tmp, *ctx = NULL; int err = 0; IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", @@ -1941,28 +1778,72 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) mutex_lock(&priv->mutex); - if (WARN_ON(!iwl_is_ready_rf(priv))) { + if (!iwl_is_ready_rf(priv)) { + IWL_WARN(priv, "Try to add interface when device not ready\n"); err = -EINVAL; goto out; } - if (priv->vif) { - IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); + for_each_context(priv, tmp) { + u32 possible_modes = + tmp->interface_modes | tmp->exclusive_interface_modes; + + if (tmp->vif) { + /* check if this busy context is exclusive */ + if (tmp->exclusive_interface_modes & + BIT(tmp->vif->type)) { + err = -EINVAL; + goto out; + } + continue; + } + + if (!(possible_modes & BIT(vif->type))) + continue; + + /* have maybe usable context w/o interface */ + ctx = tmp; + break; + } + + if (!ctx) { err = -EOPNOTSUPP; goto out; } - priv->vif = vif; + vif_priv->ctx = ctx; + ctx->vif = vif; + /* + * This variable will be correct only when there's just + * a single context, but all code using it is for hardware + * that supports only one context. + */ priv->iw_mode = vif->type; + ctx->is_active = true; + err = iwl_set_mode(priv, vif); - if (err) + if (err) { + if (!ctx->always_active) + ctx->is_active = false; goto out_err; + } + + if (priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + vif->type == NL80211_IFTYPE_ADHOC) { + /* + * pretend to have high BT traffic as long as we + * are operating in IBSS mode, as this will cause + * the rate scaling etc. to behave as intended. + */ + priv->bt_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_HIGH; + } goto out; out_err: - priv->vif = NULL; + ctx->vif = NULL; priv->iw_mode = NL80211_IFTYPE_STATION; out: mutex_unlock(&priv->mutex); @@ -1976,30 +1857,36 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_priv *priv = hw->priv; - bool scan_completed = false; + struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->mutex); - if (iwl_is_ready_rf(priv)) { - iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); - } - if (priv->vif == vif) { - priv->vif = NULL; - if (priv->scan_vif == vif) { - scan_completed = true; - priv->scan_vif = NULL; - priv->scan_request = NULL; - } - memset(priv->bssid, 0, ETH_ALEN); + WARN_ON(ctx->vif != vif); + ctx->vif = NULL; + + if (priv->scan_vif == vif) { + iwl_scan_cancel_timeout(priv, 200); + iwl_force_scan_end(priv); } - mutex_unlock(&priv->mutex); + iwl_set_mode(priv, vif); - if (scan_completed) - ieee80211_scan_completed(priv->hw, true); + if (!ctx->always_active) + ctx->is_active = false; + + /* + * When removing the IBSS interface, overwrite the + * BT traffic load with the stored one from the last + * notification, if any. If this is a device that + * doesn't implement this, this has no effect since + * both values are the same and zero. + */ + if (vif->type == NL80211_IFTYPE_ADHOC) + priv->bt_traffic_load = priv->notif_bt_traffic_load; + + memset(priv->bssid, 0, ETH_ALEN); + mutex_unlock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -2014,7 +1901,9 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) struct iwl_priv *priv = hw->priv; const struct iwl_channel_info *ch_info; struct ieee80211_conf *conf = &hw->conf; + struct ieee80211_channel *channel = conf->channel; struct iwl_ht_config *ht_conf = &priv->current_ht_config; + struct iwl_rxon_context *ctx; unsigned long flags = 0; int ret = 0; u16 ch; @@ -2023,7 +1912,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", - conf->channel->hw_value, changed); + channel->hw_value, changed); if (unlikely(!priv->cfg->mod_params->disable_hw_scan && test_bit(STATUS_SCANNING, &priv->status))) { @@ -2044,7 +1933,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) * configured. */ if (priv->cfg->ops->hcmd->set_rxon_chain) - priv->cfg->ops->hcmd->set_rxon_chain(priv); + for_each_context(priv, ctx) + priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); } /* during scanning mac80211 will delay channel setting until @@ -2054,8 +1944,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if (scan_active) goto set_ch_out; - ch = ieee80211_frequency_to_channel(conf->channel->center_freq); - ch_info = iwl_get_channel_info(priv, conf->channel->band, ch); + ch = channel->hw_value; + ch_info = iwl_get_channel_info(priv, channel->band, ch); if (!is_channel_valid(ch_info)) { IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n"); ret = -EINVAL; @@ -2064,42 +1954,49 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) spin_lock_irqsave(&priv->lock, flags); - /* Configure HT40 channels */ - ht_conf->is_ht = conf_is_ht(conf); - if (ht_conf->is_ht) { - if (conf_is_ht40_minus(conf)) { - ht_conf->extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_BELOW; - ht_conf->is_40mhz = true; - } else if (conf_is_ht40_plus(conf)) { - ht_conf->extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - ht_conf->is_40mhz = true; - } else { - ht_conf->extension_chan_offset = - IEEE80211_HT_PARAM_CHA_SEC_NONE; - ht_conf->is_40mhz = false; - } - } else - ht_conf->is_40mhz = false; - /* Default to no protection. Protection mode will later be set - * from BSS config in iwl_ht_conf */ - ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; + for_each_context(priv, ctx) { + /* Configure HT40 channels */ + ctx->ht.enabled = conf_is_ht(conf); + if (ctx->ht.enabled) { + if (conf_is_ht40_minus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_BELOW; + ctx->ht.is_40mhz = true; + } else if (conf_is_ht40_plus(conf)) { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_ABOVE; + ctx->ht.is_40mhz = true; + } else { + ctx->ht.extension_chan_offset = + IEEE80211_HT_PARAM_CHA_SEC_NONE; + ctx->ht.is_40mhz = false; + } + } else + ctx->ht.is_40mhz = false; - /* if we are switching from ht to 2.4 clear flags - * from any ht related info since 2.4 does not - * support ht */ - if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) - priv->staging_rxon.flags = 0; + /* + * Default to no protection. Protection mode will + * later be set from BSS config in iwl_ht_conf + */ + ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; - iwl_set_rxon_channel(priv, conf->channel); - iwl_set_rxon_ht(priv, ht_conf); + /* if we are switching from ht to 2.4 clear flags + * from any ht related info since 2.4 does not + * support ht */ + if ((le16_to_cpu(ctx->staging.channel) != ch)) + ctx->staging.flags = 0; + + iwl_set_rxon_channel(priv, channel, ctx); + iwl_set_rxon_ht(priv, ht_conf); + + iwl_set_flags_for_band(priv, ctx, channel->band, + ctx->vif); + } - iwl_set_flags_for_band(priv, conf->channel->band, priv->vif); spin_unlock_irqrestore(&priv->lock, flags); - if (priv->cfg->ops->lib->update_bcast_station) - ret = priv->cfg->ops->lib->update_bcast_station(priv); + if (priv->cfg->ops->lib->update_bcast_stations) + ret = priv->cfg->ops->lib->update_bcast_stations(priv); set_ch_out: /* The list of supported rates and rate mask can be different @@ -2130,12 +2027,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) if (scan_active) goto out; - if (memcmp(&priv->active_rxon, - &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwlcore_commit_rxon(priv); - else - IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n"); - + for_each_context(priv, ctx) { + if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging))) + iwlcore_commit_rxon(priv, ctx); + else + IWL_DEBUG_INFO(priv, + "Not re-sending same RXON configuration.\n"); + } out: IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -2148,6 +2046,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) { struct iwl_priv *priv = hw->priv; unsigned long flags; + /* IBSS can only be the IWL_RXON_CTX_BSS context */ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; mutex_lock(&priv->mutex); IWL_DEBUG_MAC80211(priv, "enter\n"); @@ -2159,15 +2059,16 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) spin_lock_irqsave(&priv->lock, flags); /* new association get rid of ibss beacon skb */ - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); - priv->ibss_beacon = NULL; + priv->beacon_skb = NULL; priv->timestamp = 0; spin_unlock_irqrestore(&priv->lock, flags); + iwl_scan_cancel_timeout(priv, 100); if (!iwl_is_ready_rf(priv)) { IWL_DEBUG_MAC80211(priv, "leave - not ready\n"); mutex_unlock(&priv->mutex); @@ -2177,9 +2078,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw) /* we are restarting association process * clear RXON_FILTER_ASSOC_MSK bit */ - iwl_scan_cancel_timeout(priv, 100); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwlcore_commit_rxon(priv, ctx); iwl_set_rate(priv); @@ -2193,7 +2093,8 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv) { if (!priv->txq) priv->txq = kzalloc( - sizeof(struct iwl_tx_queue) * priv->cfg->num_of_queues, + sizeof(struct iwl_tx_queue) * + priv->cfg->base_params->num_of_queues, GFP_KERNEL); if (!priv->txq) { IWL_ERR(priv, "Not enough memory for txq\n"); @@ -2449,146 +2350,12 @@ void iwl_update_stats(struct iwl_priv *priv, bool is_tx, __le16 fc, u16 len) EXPORT_SYMBOL(iwl_update_stats); #endif -static const char *get_csr_string(int cmd) -{ - switch (cmd) { - IWL_CMD(CSR_HW_IF_CONFIG_REG); - IWL_CMD(CSR_INT_COALESCING); - IWL_CMD(CSR_INT); - IWL_CMD(CSR_INT_MASK); - IWL_CMD(CSR_FH_INT_STATUS); - IWL_CMD(CSR_GPIO_IN); - IWL_CMD(CSR_RESET); - IWL_CMD(CSR_GP_CNTRL); - IWL_CMD(CSR_HW_REV); - IWL_CMD(CSR_EEPROM_REG); - IWL_CMD(CSR_EEPROM_GP); - IWL_CMD(CSR_OTP_GP_REG); - IWL_CMD(CSR_GIO_REG); - IWL_CMD(CSR_GP_UCODE_REG); - IWL_CMD(CSR_GP_DRIVER_REG); - IWL_CMD(CSR_UCODE_DRV_GP1); - IWL_CMD(CSR_UCODE_DRV_GP2); - IWL_CMD(CSR_LED_REG); - IWL_CMD(CSR_DRAM_INT_TBL_REG); - IWL_CMD(CSR_GIO_CHICKEN_BITS); - IWL_CMD(CSR_ANA_PLL_CFG); - IWL_CMD(CSR_HW_REV_WA_REG); - IWL_CMD(CSR_DBG_HPET_MEM_REG); - default: - return "UNKNOWN"; - - } -} - -void iwl_dump_csr(struct iwl_priv *priv) -{ - int i; - u32 csr_tbl[] = { - CSR_HW_IF_CONFIG_REG, - CSR_INT_COALESCING, - CSR_INT, - CSR_INT_MASK, - CSR_FH_INT_STATUS, - CSR_GPIO_IN, - CSR_RESET, - CSR_GP_CNTRL, - CSR_HW_REV, - CSR_EEPROM_REG, - CSR_EEPROM_GP, - CSR_OTP_GP_REG, - CSR_GIO_REG, - CSR_GP_UCODE_REG, - CSR_GP_DRIVER_REG, - CSR_UCODE_DRV_GP1, - CSR_UCODE_DRV_GP2, - CSR_LED_REG, - CSR_DRAM_INT_TBL_REG, - CSR_GIO_CHICKEN_BITS, - CSR_ANA_PLL_CFG, - CSR_HW_REV_WA_REG, - CSR_DBG_HPET_MEM_REG - }; - IWL_ERR(priv, "CSR values:\n"); - IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is " - "CSR_INT_PERIODIC_REG)\n"); - for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { - IWL_ERR(priv, " %25s: 0X%08x\n", - get_csr_string(csr_tbl[i]), - iwl_read32(priv, csr_tbl[i])); - } -} -EXPORT_SYMBOL(iwl_dump_csr); - -static const char *get_fh_string(int cmd) -{ - switch (cmd) { - IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG); - IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG); - IWL_CMD(FH_RSCSR_CHNL0_WPTR); - IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG); - IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG); - IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG); - IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV); - IWL_CMD(FH_TSSR_TX_STATUS_REG); - IWL_CMD(FH_TSSR_TX_ERROR_REG); - default: - return "UNKNOWN"; - - } -} - -int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) -{ - int i; -#ifdef CONFIG_IWLWIFI_DEBUG - int pos = 0; - size_t bufsz = 0; -#endif - u32 fh_tbl[] = { - FH_RSCSR_CHNL0_STTS_WPTR_REG, - FH_RSCSR_CHNL0_RBDCB_BASE_REG, - FH_RSCSR_CHNL0_WPTR, - FH_MEM_RCSR_CHNL0_CONFIG_REG, - FH_MEM_RSSR_SHARED_CTRL_REG, - FH_MEM_RSSR_RX_STATUS_REG, - FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV, - FH_TSSR_TX_STATUS_REG, - FH_TSSR_TX_ERROR_REG - }; -#ifdef CONFIG_IWLWIFI_DEBUG - if (display) { - bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40; - *buf = kmalloc(bufsz, GFP_KERNEL); - if (!*buf) - return -ENOMEM; - pos += scnprintf(*buf + pos, bufsz - pos, - "FH register values:\n"); - for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { - pos += scnprintf(*buf + pos, bufsz - pos, - " %34s: 0X%08x\n", - get_fh_string(fh_tbl[i]), - iwl_read_direct32(priv, fh_tbl[i])); - } - return pos; - } -#endif - IWL_ERR(priv, "FH register values:\n"); - for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { - IWL_ERR(priv, " %34s: 0X%08x\n", - get_fh_string(fh_tbl[i]), - iwl_read_direct32(priv, fh_tbl[i])); - } - return 0; -} -EXPORT_SYMBOL(iwl_dump_fh); - static void iwl_force_rf_reset(struct iwl_priv *priv) { if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (!iwl_is_associated(priv)) { + if (!iwl_is_any_associated(priv)) { IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); return; } @@ -2613,11 +2380,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return -EINVAL; - if (test_bit(STATUS_SCANNING, &priv->status)) { - IWL_DEBUG_INFO(priv, "scan in progress.\n"); - return -EINVAL; - } - if (mode >= IWL_MAX_FORCE_RESET) { IWL_DEBUG_INFO(priv, "invalid reset request.\n"); return -EINVAL; @@ -2668,7 +2430,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) } return 0; } -EXPORT_SYMBOL(iwl_force_reset); /** * iwl_bg_monitor_recover - Timer callback to check for stuck queue and recover @@ -2704,29 +2465,31 @@ static int iwl_check_stuck_queue(struct iwl_priv *priv, int cnt) txq = &priv->txq[cnt]; q = &txq->q; /* queue is empty, skip */ - if (q->read_ptr != q->write_ptr) { - if (q->read_ptr == q->last_read_ptr) { - /* a queue has not been read from last time */ - if (q->repeat_same_read_ptr > MAX_REPEAT) { - IWL_ERR(priv, - "queue %d stuck %d time. Fw reload.\n", - q->id, q->repeat_same_read_ptr); - q->repeat_same_read_ptr = 0; - iwl_force_reset(priv, IWL_FW_RESET, false); - } else { - q->repeat_same_read_ptr++; - IWL_DEBUG_RADIO(priv, - "queue %d, not read %d time\n", - q->id, - q->repeat_same_read_ptr); - mod_timer(&priv->monitor_recover, jiffies + - msecs_to_jiffies(IWL_ONE_HUNDRED_MSECS)); - } - return 1; - } else { - q->last_read_ptr = q->read_ptr; + if (q->read_ptr == q->write_ptr) + return 0; + + if (q->read_ptr == q->last_read_ptr) { + /* a queue has not been read from last time */ + if (q->repeat_same_read_ptr > MAX_REPEAT) { + IWL_ERR(priv, + "queue %d stuck %d time. Fw reload.\n", + q->id, q->repeat_same_read_ptr); q->repeat_same_read_ptr = 0; + iwl_force_reset(priv, IWL_FW_RESET, false); + } else { + q->repeat_same_read_ptr++; + IWL_DEBUG_RADIO(priv, + "queue %d, not read %d time\n", + q->id, + q->repeat_same_read_ptr); + mod_timer(&priv->monitor_recover, + jiffies + msecs_to_jiffies( + IWL_ONE_HUNDRED_MSECS)); + return 1; } + } else { + q->last_read_ptr = q->read_ptr; + q->repeat_same_read_ptr = 0; } return 0; } @@ -2740,25 +2503,27 @@ void iwl_bg_monitor_recover(unsigned long data) return; /* monitor and check for stuck cmd queue */ - if (iwl_check_stuck_queue(priv, IWL_CMD_QUEUE_NUM)) + if (iwl_check_stuck_queue(priv, priv->cmd_queue)) return; /* monitor and check for other stuck queues */ - if (iwl_is_associated(priv)) { + if (iwl_is_any_associated(priv)) { for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { /* skip as we already checked the command queue */ - if (cnt == IWL_CMD_QUEUE_NUM) + if (cnt == priv->cmd_queue) continue; if (iwl_check_stuck_queue(priv, cnt)) return; } } - /* - * Reschedule the timer to occur in - * priv->cfg->monitor_recover_period - */ - mod_timer(&priv->monitor_recover, - jiffies + msecs_to_jiffies(priv->cfg->monitor_recover_period)); + if (priv->cfg->base_params->monitor_recover_period) { + /* + * Reschedule the timer to occur in + * priv->cfg->base_params->monitor_recover_period + */ + mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( + priv->cfg->base_params->monitor_recover_period)); + } } EXPORT_SYMBOL(iwl_bg_monitor_recover); @@ -2830,7 +2595,7 @@ int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state) * it will not call apm_ops.stop() to stop the DMA operation. * Calling apm_ops.stop here to make sure we stop the DMA. */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); pci_save_state(pdev); pci_disable_device(pdev); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 5e6ee3da6bbf740846033e4a57e44956e326a73c..64527def059f7de76ac0e4bdcadd0147576805c1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -88,11 +88,13 @@ struct iwl_cmd; #define IWL_CMD(x) case x: return #x struct iwl_hcmd_ops { - int (*rxon_assoc)(struct iwl_priv *priv); - int (*commit_rxon)(struct iwl_priv *priv); - void (*set_rxon_chain)(struct iwl_priv *priv); + int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); + int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); + void (*set_rxon_chain)(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); void (*send_bt_config)(struct iwl_priv *priv); + int (*set_pan_params)(struct iwl_priv *priv); }; struct iwl_hcmd_utils_ops { @@ -109,14 +111,13 @@ struct iwl_hcmd_utils_ops { __le16 fc, __le32 *tx_flags); int (*calc_rssi)(struct iwl_priv *priv, struct iwl_rx_phy_res *rx_resp); - void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); + int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); + void (*post_scan)(struct iwl_priv *priv); }; struct iwl_apm_ops { int (*init)(struct iwl_priv *priv); - void (*stop)(struct iwl_priv *priv); void (*config)(struct iwl_priv *priv); - int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src); }; struct iwl_debugfs_ops { @@ -128,12 +129,18 @@ struct iwl_debugfs_ops { size_t count, loff_t *ppos); ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf, size_t count, loff_t *ppos); + ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos); }; struct iwl_temp_ops { void (*temperature)(struct iwl_priv *priv); - void (*set_ct_kill)(struct iwl_priv *priv); - void (*set_calib_version)(struct iwl_priv *priv); +}; + +struct iwl_tt_ops { + bool (*lower_power_detection)(struct iwl_priv *priv); + u8 (*tt_power_mode)(struct iwl_priv *priv); + bool (*ct_kill_check)(struct iwl_priv *priv); }; struct iwl_lib_ops { @@ -199,7 +206,7 @@ struct iwl_lib_ops { /* station management */ int (*manage_ibss_station)(struct iwl_priv *priv, struct ieee80211_vif *vif, bool add); - int (*update_bcast_station)(struct iwl_priv *priv); + int (*update_bcast_stations)(struct iwl_priv *priv); /* recover from tx queue stall */ void (*recover_from_tx_stall)(unsigned long data); /* check for plcp health */ @@ -212,6 +219,9 @@ struct iwl_lib_ops { void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); struct iwl_debugfs_ops debugfs_ops; + + /* thermal throttling */ + struct iwl_tt_ops tt_ops; }; struct iwl_led_ops { @@ -220,11 +230,17 @@ struct iwl_led_ops { int (*off)(struct iwl_priv *priv); }; +/* NIC specific ops */ +struct iwl_nic_ops { + void (*additional_nic_config)(struct iwl_priv *priv); +}; + struct iwl_ops { const struct iwl_lib_ops *lib; const struct iwl_hcmd_ops *hcmd; const struct iwl_hcmd_utils_ops *utils; const struct iwl_led_ops *led; + const struct iwl_nic_ops *nic; }; struct iwl_mod_params { @@ -237,20 +253,12 @@ struct iwl_mod_params { int restart_fw; /* def: 1 = restart firmware */ }; -/** - * struct iwl_cfg - * @fw_name_pre: Firmware filename prefix. The api version and extension - * (.ucode) will be added to filename before loading from disk. The - * filename is constructed as fw_name_pre.ucode. - * @ucode_api_max: Highest version of uCode API supported by driver. - * @ucode_api_min: Lowest version of uCode API supported by driver. - * @pa_type: used by 6000 series only to identify the type of Power Amplifier +/* * @max_ll_items: max number of OTP blocks * @shadow_ram_support: shadow support for OTP memory * @led_compensation: compensate on the led on/off time per HW according * to the deviation to achieve the desired led frequency. * The detail algorithm is described in iwl-led.c - * @use_rts_for_aggregation: use rts/cts protection for HT traffic * @chain_noise_num_beacons: number of beacons used to compute chain noise * @adv_thermal_throttle: support advance thermal throttle * @support_ct_kill_exit: support ct kill exit condition @@ -268,6 +276,73 @@ struct iwl_mod_params { * sensitivity calibration operation * @chain_noise_calib_by_driver: driver has the capability to perform * chain noise calibration operation +*/ +struct iwl_base_params { + int eeprom_size; + int num_of_queues; /* def: HW dependent */ + int num_of_ampdu_queues;/* def: HW dependent */ + /* for iwl_apm_init() */ + u32 pll_cfg_val; + bool set_l0s; + bool use_bsm; + + bool use_isr_legacy; + const u16 max_ll_items; + const bool shadow_ram_support; + u16 led_compensation; + const bool broken_powersave; + int chain_noise_num_beacons; + const bool supports_idle; + bool adv_thermal_throttle; + bool support_ct_kill_exit; + const bool support_wimax_coexist; + u8 plcp_delta_threshold; + s32 chain_noise_scale; + /* timer period for monitor the driver queues */ + u32 monitor_recover_period; + bool temperature_kelvin; + u32 max_event_log_size; + const bool tx_power_by_driver; + const bool ucode_tracing; + const bool sensitivity_calib_by_driver; + const bool chain_noise_calib_by_driver; +}; +/* + * @advanced_bt_coexist: support advanced bt coexist + * @bt_init_traffic_load: specify initial bt traffic load + * @bt_prio_boost: default bt priority boost value + * @bt_statistics: use BT version of statistics notification + * @agg_time_limit: maximum number of uSec in aggregation + * @ampdu_factor: Maximum A-MPDU length factor + * @ampdu_density: Minimum A-MPDU spacing +*/ +struct iwl_bt_params { + bool advanced_bt_coexist; + u8 bt_init_traffic_load; + u8 bt_prio_boost; + const bool bt_statistics; + u16 agg_time_limit; + u8 ampdu_factor; + u8 ampdu_density; +}; +/* + * @use_rts_for_aggregation: use rts/cts protection for HT traffic +*/ +struct iwl_ht_params { + const bool ht_greenfield_support; /* if used set to true */ + bool use_rts_for_aggregation; +}; + +/** + * struct iwl_cfg + * @fw_name_pre: Firmware filename prefix. The api version and extension + * (.ucode) will be added to filename before loading from disk. The + * filename is constructed as fw_name_pre.ucode. + * @ucode_api_max: Highest version of uCode API supported by driver. + * @ucode_api_min: Lowest version of uCode API supported by driver. + * @pa_type: used by 6000 series only to identify the type of Power Amplifier + * @need_dc_calib: need to perform init dc calibration + * @need_temp_offset_calib: need to perform temperature offset calibration * @scan_antennas: available antenna for scan operation * * We enable the driver to be backward compatible wrt API version. The @@ -279,9 +354,9 @@ struct iwl_mod_params { * * For example, * if (IWL_UCODE_API(priv->ucode_ver) >= 2) { - * Driver interacts with Firmware API version >= 2. + * Driver interacts with Firmware API version >= 2. * } else { - * Driver interacts with Firmware API version 1. + * Driver interacts with Firmware API version 1. * } * * The ideal usage of this infrastructure is to treat a new ucode API @@ -292,53 +367,29 @@ struct iwl_mod_params { * */ struct iwl_cfg { + /* params specific to an individual device within a device family */ const char *name; const char *fw_name_pre; const unsigned int ucode_api_max; const unsigned int ucode_api_min; + u8 valid_tx_ant; + u8 valid_rx_ant; unsigned int sku; - int eeprom_size; u16 eeprom_ver; u16 eeprom_calib_ver; - int num_of_queues; /* def: HW dependent */ - int num_of_ampdu_queues;/* def: HW dependent */ const struct iwl_ops *ops; + /* module based parameters which can be set from modprobe cmd */ const struct iwl_mod_params *mod_params; - u8 valid_tx_ant; - u8 valid_rx_ant; - - /* for iwl_apm_init() */ - u32 pll_cfg_val; - bool set_l0s; - bool use_bsm; - - bool use_isr_legacy; - enum iwl_pa_type pa_type; - const u16 max_ll_items; - const bool shadow_ram_support; - const bool ht_greenfield_support; - u16 led_compensation; - const bool broken_powersave; - bool use_rts_for_aggregation; - int chain_noise_num_beacons; - const bool supports_idle; - bool adv_thermal_throttle; - bool support_ct_kill_exit; - const bool support_wimax_coexist; - u8 plcp_delta_threshold; - s32 chain_noise_scale; - /* timer period for monitor the driver queues */ - u32 monitor_recover_period; - bool temperature_kelvin; - u32 max_event_log_size; - const bool tx_power_by_driver; - const bool ucode_tracing; - const bool sensitivity_calib_by_driver; - const bool chain_noise_calib_by_driver; + /* params not likely to change within a device family */ + struct iwl_base_params *base_params; + /* params likely to change within a device family */ + struct iwl_ht_params *ht_params; + struct iwl_bt_params *bt_params; + enum iwl_pa_type pa_type; /* if used set to IWL_PA_SYSTEM */ + const bool need_dc_calib; /* if used set to true */ + const bool need_temp_offset_calib; /* if used set to true */ u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; - const bool need_dc_calib; - const bool bt_statistics; }; /*************************** @@ -347,38 +398,38 @@ struct iwl_cfg { struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg, struct ieee80211_ops *hw_ops); -void iwl_hw_detect(struct iwl_priv *priv); -void iwl_activate_qos(struct iwl_priv *priv); int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params); -void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); -int iwl_check_rxon_cmd(struct iwl_priv *priv); -int iwl_full_rxon_required(struct iwl_priv *priv); -void iwl_set_rxon_chain(struct iwl_priv *priv); -int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); +int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); +void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + int hw_decrypt); +int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, + struct iwl_rxon_context *ctx); void iwl_set_flags_for_band(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, enum ieee80211_band band, struct ieee80211_vif *vif); u8 iwl_get_single_channel_number(struct iwl_priv *priv, enum ieee80211_band band); void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); -u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, - struct ieee80211_sta_ht_cap *sta_ht_inf); +bool iwl_is_ht40_tx_allowed(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, + struct ieee80211_sta_ht_cap *ht_cap); void iwl_connection_init_rx_config(struct iwl_priv *priv, - struct ieee80211_vif *vif); + struct iwl_rxon_context *ctx); void iwl_set_rate(struct iwl_priv *priv); int iwl_set_decrypted_flag(struct iwl_priv *priv, struct ieee80211_hdr *hdr, u32 decrypt_res, struct ieee80211_rx_status *stats); void iwl_irq_handle_error(struct iwl_priv *priv); -int iwl_set_hw_params(struct iwl_priv *priv); void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif); void iwl_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes); -int iwl_commit_rxon(struct iwl_priv *priv); int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void iwl_mac_remove_interface(struct ieee80211_hw *hw, @@ -455,7 +506,6 @@ void iwl_rx_reply_error(struct iwl_priv *priv, ******************************************************/ void iwl_cmd_queue_free(struct iwl_priv *priv); int iwl_rx_queue_alloc(struct iwl_priv *priv); -void iwl_rx_handle(struct iwl_priv *priv); void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q); int iwl_rx_queue_space(const struct iwl_rx_queue *q); @@ -473,12 +523,6 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); /***************************************************** * TX ******************************************************/ -void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq); -int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, - struct iwl_tx_queue *txq, - dma_addr_t addr, u16 len, u8 reset, u8 pad); -int iwl_hw_tx_queue_init(struct iwl_priv *priv, - struct iwl_tx_queue *txq); void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, int slots_num, u32 txq_id); @@ -494,29 +538,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); * Rate ******************************************************************************/ -int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); - -u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv); - -u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid); - -static inline u32 iwl_ant_idx_to_flags(u8 ant_idx) -{ - return BIT(ant_idx) << RATE_MCS_ANT_POS; -} - -static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) -{ - return le32_to_cpu(rate_n_flags) & 0xFF; -} -static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags) -{ - return le32_to_cpu(rate_n_flags) & 0x1FFFF; -} -static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) -{ - return cpu_to_le32(flags|(u32)rate); -} +u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); /******************************************************************************* * Scanning @@ -524,10 +547,10 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) void iwl_init_scan_params(struct iwl_priv *priv); int iwl_scan_cancel(struct iwl_priv *priv); int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); +void iwl_force_scan_end(struct iwl_priv *priv); int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_scan_request *req); -void iwl_bg_start_internal_scan(struct work_struct *work); void iwl_internal_short_hw_scan(struct iwl_priv *priv); int iwl_force_reset(struct iwl_priv *priv, int mode, bool external); u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, @@ -539,10 +562,8 @@ u16 iwl_get_active_dwell_time(struct iwl_priv *priv, u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, struct ieee80211_vif *vif); -void iwl_bg_scan_check(struct work_struct *data); -void iwl_bg_abort_scan(struct work_struct *work); -void iwl_bg_scan_completed(struct work_struct *work); void iwl_setup_scan_deferred_work(struct iwl_priv *priv); +void iwl_cancel_scan_deferred_work(struct iwl_priv *priv); /* For faster active scanning, scan will move to the next channel if fewer than * PLCP_QUIET_THRESH packets are heard on this channel within @@ -555,13 +576,6 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv); #define IWL_SCAN_CHECK_WATCHDOG (HZ * 7) -/******************************************************************************* - * Calibrations - implemented in iwl-calib.c - ******************************************************************************/ -int iwl_send_calib_results(struct iwl_priv *priv); -int iwl_calib_set(struct iwl_calib_result *res, const u8 *buf, int len); -void iwl_calib_free_results(struct iwl_priv *priv); - /***************************************************** * S e n d i n g H o s t C o m m a n d s * *****************************************************/ @@ -580,8 +594,6 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); -int iwl_send_card_state(struct iwl_priv *priv, u32 flags, - u8 meta_flag); /***************************************************** * PCI * @@ -613,12 +625,12 @@ int iwl_pci_resume(struct pci_dev *pdev); void iwl_dump_nic_error_log(struct iwl_priv *priv); int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, char **buf, bool display); -void iwl_dump_csr(struct iwl_priv *priv); -int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); #ifdef CONFIG_IWLWIFI_DEBUG -void iwl_print_rx_config_cmd(struct iwl_priv *priv); +void iwl_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); #else -static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv) +static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { } #endif @@ -695,23 +707,22 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv) return iwl_is_ready(priv); } -extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); extern void iwl_send_bt_config(struct iwl_priv *priv); extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear); -extern int iwl_send_lq_cmd(struct iwl_priv *priv, - struct iwl_link_quality_cmd *lq, u8 flags, bool init); void iwl_apm_stop(struct iwl_priv *priv); int iwl_apm_init(struct iwl_priv *priv); -void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif); -static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) +int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +static inline int iwl_send_rxon_assoc(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { - return priv->cfg->ops->hcmd->rxon_assoc(priv); + return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx); } -static inline int iwlcore_commit_rxon(struct iwl_priv *priv) +static inline int iwlcore_commit_rxon(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { - return priv->cfg->ops->hcmd->commit_rxon(priv); + return priv->cfg->ops->hcmd->commit_rxon(priv, ctx); } static inline void iwlcore_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) @@ -723,4 +734,8 @@ static inline const struct ieee80211_supported_band *iwl_get_hw_mode( { return priv->hw->wiphy->bands[band]; } + +extern bool bt_coex_active; +extern bool bt_siso_mode; + #endif /* __iwl_core_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index ecf98e7ac4edac798b90bc3db4116ff1a7b923dc..2aa15ab13892541fab426e0dac361e2d3b279adb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -371,7 +371,8 @@ #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000) #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001) #define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002) -#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) +#define CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6 (0x00000004) +#define CSR_GP_DRIVER_REG_BIT_6050_1x2 (0x00000008) /* GIO Chicken Bits (PCI Express bus link power management) */ #define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index a32d5d3376497bdcd3e5a82386785bb31d9caf5f..8fdd4efdb1d36bf273cc62b1f4a9a25af59b1f17 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -39,7 +39,6 @@ #include "iwl-debug.h" #include "iwl-core.h" #include "iwl-io.h" -#include "iwl-calib.h" /* create and remove of files */ #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ @@ -359,7 +358,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file, const u8 *ptr; char *buf; u16 eeprom_ver; - size_t eeprom_len = priv->cfg->eeprom_size; + size_t eeprom_len = priv->cfg->base_params->eeprom_size; buf_size = 4 * eeprom_len + 256; if (eeprom_len % 16) { @@ -470,8 +469,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, for (i = 0; i < supp_band->n_channels; i++) pos += scnprintf(buf + pos, bufsz - pos, "%d: %ddBm: BSS%s%s, %s.\n", - ieee80211_frequency_to_channel( - channels[i].center_freq), + channels[i].hw_value, channels[i].max_power, channels[i].flags & IEEE80211_CHAN_RADAR ? " (IEEE 802.11h required)" : "", @@ -494,8 +492,7 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, for (i = 0; i < supp_band->n_channels; i++) pos += scnprintf(buf + pos, bufsz - pos, "%d: %ddBm: BSS%s%s, %s.\n", - ieee80211_frequency_to_channel( - channels[i].center_freq), + channels[i].hw_value, channels[i].max_power, channels[i].flags & IEEE80211_CHAN_RADAR ? " (IEEE 802.11h required)" : "", @@ -580,10 +577,10 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file, priv->isr_stats.hw); pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", priv->isr_stats.sw); - if (priv->isr_stats.sw > 0) { + if (priv->isr_stats.sw || priv->isr_stats.hw) { pos += scnprintf(buf + pos, bufsz - pos, "\tLast Restarting Code: 0x%X\n", - priv->isr_stats.sw_err); + priv->isr_stats.err_code); } #ifdef CONFIG_IWLWIFI_DEBUG pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", @@ -648,19 +645,25 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct iwl_priv *priv = file->private_data; + struct iwl_rxon_context *ctx; int pos = 0, i; - char buf[256]; + char buf[256 * NUM_IWL_RXON_CTX]; const size_t bufsz = sizeof(buf); - for (i = 0; i < AC_NUM; i++) { - pos += scnprintf(buf + pos, bufsz - pos, - "\tcw_min\tcw_max\taifsn\ttxop\n"); - pos += scnprintf(buf + pos, bufsz - pos, + for_each_context(priv, ctx) { + pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", + ctx->ctxid); + for (i = 0; i < AC_NUM; i++) { + pos += scnprintf(buf + pos, bufsz - pos, + "\tcw_min\tcw_max\taifsn\ttxop\n"); + pos += scnprintf(buf + pos, bufsz - pos, "AC[%d]\t%u\t%u\t%u\t%u\n", i, - priv->qos_data.def_qos_parm.ac[i].cw_min, - priv->qos_data.def_qos_parm.ac[i].cw_max, - priv->qos_data.def_qos_parm.ac[i].aifsn, - priv->qos_data.def_qos_parm.ac[i].edca_txop); + ctx->qos_data.def_qos_parm.ac[i].cw_min, + ctx->qos_data.def_qos_parm.ac[i].cw_max, + ctx->qos_data.def_qos_parm.ac[i].aifsn, + ctx->qos_data.def_qos_parm.ac[i].edca_txop); + } + pos += scnprintf(buf + pos, bufsz - pos, "\n"); } return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -735,7 +738,7 @@ static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, return -EFAULT; if (sscanf(buf, "%d", &ht40) != 1) return -EFAULT; - if (!iwl_is_associated(priv)) + if (!iwl_is_any_associated(priv)) priv->disable_ht40 = ht40 ? true : false; else { IWL_ERR(priv, "Sta associated with AP - " @@ -871,7 +874,7 @@ static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, struct iwl_rx_queue *rxq = &priv->rxq; char *buf; int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + - (priv->cfg->num_of_queues * 32 * 8) + 400; + (priv->cfg->base_params->num_of_queues * 32 * 8) + 400; const u8 *ptr; ssize_t ret; @@ -970,7 +973,8 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, int pos = 0; int cnt; int ret; - const size_t bufsz = sizeof(char) * 64 * priv->cfg->num_of_queues; + const size_t bufsz = sizeof(char) * 64 * + priv->cfg->base_params->num_of_queues; if (!priv->txq) { IWL_ERR(priv, "txq not ready\n"); @@ -1324,7 +1328,8 @@ static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, int len = 0; char buf[20]; - len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags)); + len = sprintf(buf, "0x%04X\n", + le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1337,7 +1342,7 @@ static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, char buf[20]; len = sprintf(buf, "0x%04X\n", - le32_to_cpu(priv->active_rxon.filter_flags)); + le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags)); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1413,7 +1418,7 @@ static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, const size_t bufsz = sizeof(buf); pos += scnprintf(buf + pos, bufsz - pos, "%u\n", - priv->cfg->plcp_delta_threshold); + priv->cfg->base_params->plcp_delta_threshold); return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } @@ -1435,10 +1440,10 @@ static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, return -EINVAL; if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) - priv->cfg->plcp_delta_threshold = + priv->cfg->base_params->plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; else - priv->cfg->plcp_delta_threshold = plcp; + priv->cfg->base_params->plcp_delta_threshold = plcp; return count; } @@ -1532,6 +1537,135 @@ static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, user_buf, count, ppos); } +static ssize_t iwl_dbgfs_monitor_period_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int period; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &period) != 1) + return -EINVAL; + if (period < 0 || period > IWL_MAX_MONITORING_PERIOD) + priv->cfg->base_params->monitor_recover_period = + IWL_DEF_MONITORING_PERIOD; + else + priv->cfg->base_params->monitor_recover_period = period; + + if (priv->cfg->base_params->monitor_recover_period) + mod_timer(&priv->monitor_recover, jiffies + msecs_to_jiffies( + priv->cfg->base_params->monitor_recover_period)); + else + del_timer_sync(&priv->monitor_recover); + return count; +} + +static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + int pos = 0; + char buf[200]; + const size_t bufsz = sizeof(buf); + ssize_t ret; + + pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n", + priv->bt_full_concurrent ? "full concurrency" : "3-wire"); + pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " + "last traffic notif: %d\n", + priv->bt_status ? "On" : "Off", priv->notif_bt_traffic_load); + pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " + "sco_active: %d, kill_ack_mask: %x, " + "kill_cts_mask: %x\n", + priv->bt_ch_announce, priv->bt_sco_active, + priv->kill_ack_mask, priv->kill_cts_mask); + + pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: "); + switch (priv->bt_traffic_load) { + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n"); + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + pos += scnprintf(buf + pos, bufsz - pos, "High\n"); + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + pos += scnprintf(buf + pos, bufsz - pos, "Low\n"); + break; + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + default: + pos += scnprintf(buf + pos, bufsz - pos, "None\n"); + break; + } + + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); + return ret; +} + +static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = (struct iwl_priv *)file->private_data; + + int pos = 0; + char buf[40]; + const size_t bufsz = sizeof(buf); + + if (priv->cfg->ht_params) + pos += scnprintf(buf + pos, bufsz - pos, + "use %s for aggregation\n", + (priv->cfg->ht_params->use_rts_for_aggregation) ? + "rts/cts" : "cts-to-self"); + else + pos += scnprintf(buf + pos, bufsz - pos, "N/A"); + + return simple_read_from_buffer(user_buf, count, ppos, buf, pos); +} + +static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { + + struct iwl_priv *priv = file->private_data; + char buf[8]; + int buf_size; + int rts; + + if (!priv->cfg->ht_params) + return -EINVAL; + + memset(buf, 0, sizeof(buf)); + buf_size = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + if (sscanf(buf, "%d", &rts) != 1) + return -EINVAL; + if (rts) + priv->cfg->ht_params->use_rts_for_aggregation = true; + else + priv->cfg->ht_params->use_rts_for_aggregation = false; + return count; +} + +static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct iwl_priv *priv = file->private_data; + + if (priv->cfg->ops->lib->debugfs_ops.reply_tx_error) + return priv->cfg->ops->lib->debugfs_ops.reply_tx_error( + file, user_buf, count, ppos); + else + return -ENODATA; +} DEBUGFS_READ_FILE_OPS(rx_statistics); DEBUGFS_READ_FILE_OPS(tx_statistics); DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); @@ -1555,6 +1689,10 @@ DEBUGFS_READ_FILE_OPS(rxon_flags); DEBUGFS_READ_FILE_OPS(rxon_filter_flags); DEBUGFS_WRITE_FILE_OPS(txfifo_flush); DEBUGFS_READ_FILE_OPS(ucode_bt_stats); +DEBUGFS_WRITE_FILE_OPS(monitor_period); +DEBUGFS_READ_FILE_OPS(bt_traffic); +DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); +DEBUGFS_READ_FILE_OPS(reply_tx_error); /* * Create the debugfs files and directories @@ -1590,7 +1728,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR); - if (!priv->cfg->broken_powersave) { + if (!priv->cfg->base_params->broken_powersave) { DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); @@ -1615,24 +1753,29 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); if (priv->cfg->ops->lib->dev_txfifo_flush) DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); + DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); - if (priv->cfg->sensitivity_calib_by_driver) + if (priv->cfg->base_params->sensitivity_calib_by_driver) DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); - if (priv->cfg->chain_noise_calib_by_driver) + if (priv->cfg->base_params->chain_noise_calib_by_driver) DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); - if (priv->cfg->ucode_tracing) + if (priv->cfg->base_params->ucode_tracing) DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); - if (priv->cfg->bt_statistics) + if (priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics) DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); + DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); - if (priv->cfg->sensitivity_calib_by_driver) + DEBUGFS_ADD_FILE(monitor_period, dir_debug, S_IWUSR); + if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist) + DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); + if (priv->cfg->base_params->sensitivity_calib_by_driver) DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal); - if (priv->cfg->chain_noise_calib_by_driver) + if (priv->cfg->base_params->chain_noise_calib_by_driver) DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, &priv->disable_chain_noise_cal); - if (priv->cfg->tx_power_by_driver) + if (priv->cfg->base_params->tx_power_by_driver) DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &priv->disable_tx_power_cal); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 2e97cd2fa98a6e0c7d9cdc6d98582ac54fe28459..70e07fa48405b5558a4cb95a6535178cb7265f1f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -47,6 +47,7 @@ #include "iwl-led.h" #include "iwl-power.h" #include "iwl-agn-rs.h" +#include "iwl-agn-tt.h" struct iwl_tx_queue; @@ -143,6 +144,7 @@ struct iwl_queue { /* One for each TFD */ struct iwl_tx_info { struct sk_buff *skb; + struct iwl_rxon_context *ctx; }; /** @@ -252,10 +254,14 @@ struct iwl_channel_info { struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; }; -#define IWL_TX_FIFO_BK 0 +#define IWL_TX_FIFO_BK 0 /* shared */ #define IWL_TX_FIFO_BE 1 -#define IWL_TX_FIFO_VI 2 +#define IWL_TX_FIFO_VI 2 /* shared */ #define IWL_TX_FIFO_VO 3 +#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK +#define IWL_TX_FIFO_BE_IPAN 4 +#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI +#define IWL_TX_FIFO_VO_IPAN 5 #define IWL_TX_FIFO_UNUSED -1 /* Minimum number of queues. MAX_NUM is defined in hw specific files. @@ -264,18 +270,17 @@ struct iwl_channel_info { #define IWL_MIN_NUM_QUEUES 10 /* - * Queue #4 is the command queue for 3945/4965/5x00/1000/6x00, - * the driver maps it into the appropriate device FIFO for the - * uCode. + * Command queue depends on iPAN support. */ -#define IWL_CMD_QUEUE_NUM 4 +#define IWL_DEFAULT_CMD_QUEUE_NUM 4 +#define IWL_IPAN_CMD_QUEUE_NUM 9 -/* Power management (not Tx power) structures */ - -enum iwl_pwr_src { - IWL_PWR_SRC_VMAIN, - IWL_PWR_SRC_VAUX, -}; +/* + * This queue number is required for proper operation + * because the ucode will stop/start the scheduler as + * required. + */ +#define IWL_IPAN_MCAST_QUEUE 8 #define IEEE80211_DATA_LEN 2304 #define IEEE80211_4ADDR_LEN 30 @@ -420,7 +425,7 @@ struct iwl_tid_data { }; struct iwl_hw_key { - enum ieee80211_key_alg alg; + u32 cipher; int keylen; u8 keyidx; u8 key[32]; @@ -434,7 +439,13 @@ union iwl_ht_rate_supp { }; }; -#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) +#define CFG_HT_RX_AMPDU_FACTOR_8K (0x0) +#define CFG_HT_RX_AMPDU_FACTOR_16K (0x1) +#define CFG_HT_RX_AMPDU_FACTOR_32K (0x2) +#define CFG_HT_RX_AMPDU_FACTOR_64K (0x3) +#define CFG_HT_RX_AMPDU_FACTOR_DEF CFG_HT_RX_AMPDU_FACTOR_64K +#define CFG_HT_RX_AMPDU_FACTOR_MAX CFG_HT_RX_AMPDU_FACTOR_64K +#define CFG_HT_RX_AMPDU_FACTOR_MIN CFG_HT_RX_AMPDU_FACTOR_8K /* * Maximal MPDU density for TX aggregation @@ -443,19 +454,17 @@ union iwl_ht_rate_supp { * 6 - 8us density * 7 - 16us density */ +#define CFG_HT_MPDU_DENSITY_2USEC (0x4) #define CFG_HT_MPDU_DENSITY_4USEC (0x5) +#define CFG_HT_MPDU_DENSITY_8USEC (0x6) +#define CFG_HT_MPDU_DENSITY_16USEC (0x7) #define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC +#define CFG_HT_MPDU_DENSITY_MAX CFG_HT_MPDU_DENSITY_16USEC +#define CFG_HT_MPDU_DENSITY_MIN (0x1) struct iwl_ht_config { - /* self configuration data */ - bool is_ht; - bool is_40mhz; bool single_chain_sufficient; enum ieee80211_smps_mode smps; /* current smps mode */ - /* BSS related data */ - u8 extension_chan_offset; - u8 ht_protection; - u8 non_GF_STA_present; }; /* QoS structures */ @@ -473,12 +482,13 @@ struct iwl_qos_info { struct iwl_station_entry { struct iwl_addsta_cmd sta; struct iwl_tid_data tid[MAX_TID_COUNT]; - u8 used; + u8 used, ctxid; struct iwl_hw_key keyinfo; struct iwl_link_quality_cmd *lq; }; struct iwl_station_priv_common { + struct iwl_rxon_context *ctx; u8 sta_id; }; @@ -507,6 +517,7 @@ struct iwl_station_priv { * space for us to put data into. */ struct iwl_vif_priv { + struct iwl_rxon_context *ctx; u8 ibss_bssid_sta_id; }; @@ -564,6 +575,7 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_INIT_DATA = 4, IWL_UCODE_TLV_BOOT = 5, IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ + IWL_UCODE_TLV_PAN = 7, IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, @@ -658,7 +670,6 @@ struct iwl_sensitivity_ranges { * @rx_page_order: Rx buffer page order * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR * @max_stations: - * @bcast_sta_id: * @ht40_channel: is 40MHz width possible in band 2.4 * BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ) * @sw_crypto: 0 for hw, 1 for sw @@ -666,6 +677,7 @@ struct iwl_sensitivity_ranges { * @ct_kill_threshold: temperature threshold * @beacon_time_tsf_bits: number of valid tsf bits for beacon time * @calib_init_cfg: setup initial calibrations for the hw + * @calib_rt_cfg: setup runtime calibrations for the hw * @struct iwl_sensitivity_ranges: range of sensitivity values */ struct iwl_hw_params { @@ -682,7 +694,6 @@ struct iwl_hw_params { u32 rx_page_order; u32 rx_wrt_ptr_reg; u8 max_stations; - u8 bcast_sta_id; u8 ht40_channel; u8 max_beacon_itrvl; /* in 1024 ms */ u32 max_inst_size; @@ -693,6 +704,7 @@ struct iwl_hw_params { /* for 1000, 6000 series and up */ u16 beacon_time_tsf_bits; u32 calib_init_cfg; + u32 calib_rt_cfg; const struct iwl_sensitivity_ranges *sens; }; @@ -713,7 +725,6 @@ struct iwl_hw_params { * ****************************************************************************/ extern void iwl_update_chain_flags(struct iwl_priv *priv); -extern int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); extern const u8 iwl_bcast_addr[ETH_ALEN]; extern int iwl_rxq_stop(struct iwl_priv *priv); extern void iwl_txq_ctx_stop(struct iwl_priv *priv); @@ -824,6 +835,7 @@ enum iwl_calib { IWL_CALIB_TX_IQ, IWL_CALIB_TX_IQ_PERD, IWL_CALIB_BASE_BAND, + IWL_CALIB_TEMP_OFFSET, IWL_CALIB_MAX }; @@ -928,7 +940,7 @@ enum iwl_pa_type { struct isr_statistics { u32 hw; u32 sw; - u32 sw_err; + u32 err_code; u32 sch; u32 alive; u32 rfkill; @@ -940,6 +952,50 @@ struct isr_statistics { u32 unhandled; }; +/* reply_tx_statistics (for _agn devices) */ +struct reply_tx_error_statistics { + u32 pp_delay; + u32 pp_few_bytes; + u32 pp_bt_prio; + u32 pp_quiet_period; + u32 pp_calc_ttak; + u32 int_crossed_retry; + u32 short_limit; + u32 long_limit; + u32 fifo_underrun; + u32 drain_flow; + u32 rfkill_flush; + u32 life_expire; + u32 dest_ps; + u32 host_abort; + u32 bt_retry; + u32 sta_invalid; + u32 frag_drop; + u32 tid_disable; + u32 fifo_flush; + u32 insuff_cf_poll; + u32 fail_hw_drop; + u32 sta_color_mismatch; + u32 unknown; +}; + +/* reply_agg_tx_statistics (for _agn devices) */ +struct reply_agg_tx_error_statistics { + u32 underrun; + u32 bt_prio; + u32 few_bytes; + u32 abort; + u32 last_sent_ttl; + u32 last_sent_try; + u32 last_sent_bt_kill; + u32 scd_query; + u32 bad_crc32; + u32 response; + u32 dump_tx; + u32 delay_tx; + u32 unknown; +}; + #ifdef CONFIG_IWLWIFI_DEBUGFS /* management statistics */ enum iwl_mgmt_stats { @@ -1052,7 +1108,10 @@ struct iwl_event_log { #define IWL_DEF_MONITORING_PERIOD (1000) #define IWL_LONG_MONITORING_PERIOD (5000) #define IWL_ONE_HUNDRED_MSECS (100) -#define IWL_SIXTY_SECS (60000) +#define IWL_MAX_MONITORING_PERIOD (60000) + +/* BT Antenna Coupling Threshold (dB) */ +#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) enum iwl_reset { IWL_RF_RESET = 0, @@ -1082,6 +1141,64 @@ struct iwl_force_reset { */ #define IWLAGN_EXT_BEACON_TIME_POS 22 +enum iwl_rxon_context_id { + IWL_RXON_CTX_BSS, + IWL_RXON_CTX_PAN, + + NUM_IWL_RXON_CTX +}; + +struct iwl_rxon_context { + struct ieee80211_vif *vif; + + const u8 *ac_to_fifo; + const u8 *ac_to_queue; + u8 mcast_queue; + + /* + * We could use the vif to indicate active, but we + * also need it to be active during disabling when + * we already removed the vif for type setting. + */ + bool always_active, is_active; + + enum iwl_rxon_context_id ctxid; + + u32 interface_modes, exclusive_interface_modes; + u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype; + + /* + * We declare this const so it can only be + * changed via explicit cast within the + * routines that actually update the physical + * hardware. + */ + const struct iwl_rxon_cmd active; + struct iwl_rxon_cmd staging; + + struct iwl_rxon_time_cmd timing; + + struct iwl_qos_info qos_data; + + u8 bcast_sta_id, ap_sta_id; + + u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd; + u8 qos_cmd; + u8 wep_key_cmd; + + struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; + u8 key_mapping_keys; + + __le32 station_flags; + + struct { + bool non_gf_sta_present; + u8 protection; + bool enabled, is_40mhz; + u8 extension_chan_offset; + } ht; +}; + struct iwl_priv { /* ieee device used by generic ieee processing code */ @@ -1110,6 +1227,9 @@ struct iwl_priv { u32 ucode_beacon_time; int missed_beacon_threshold; + /* track IBSS manager (last beacon) status */ + u32 ibss_manager; + /* storing the jiffies when the plcp error rate is received */ unsigned long plcp_jiffies; @@ -1155,6 +1275,15 @@ struct iwl_priv { u32 hw_wa_rev; u8 rev_id; + /* microcode/device supports multiple contexts */ + u8 valid_contexts; + + /* command queue number */ + u8 cmd_queue; + + /* max number of station keys */ + u8 sta_key_max_num; + /* EEPROM MAC addresses */ struct mac_address addresses[2]; @@ -1172,15 +1301,7 @@ struct iwl_priv { u8 ucode_write_complete; /* the image write is complete */ char firmware_name[25]; - - struct iwl_rxon_time_cmd rxon_timing; - - /* We declare this const so it can only be - * changed via explicit cast within the - * routines that actually update the physical - * hardware */ - const struct iwl_rxon_cmd active_rxon; - struct iwl_rxon_cmd staging_rxon; + struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; struct iwl_switch_rxon switch_rxon; @@ -1242,8 +1363,6 @@ struct iwl_priv { spinlock_t sta_lock; int num_stations; struct iwl_station_entry stations[IWL_STATION_COUNT]; - struct iwl_wep_key wep_keys[WEP_KEYS_MAX]; /* protected by mutex */ - u8 key_mapping_key; unsigned long ucode_key_table; /* queue refcounts */ @@ -1264,11 +1383,8 @@ struct iwl_priv { enum nl80211_iftype iw_mode; - struct sk_buff *ibss_beacon; - /* Last Rx'd beacon timestamp */ u64 timestamp; - struct ieee80211_vif *vif; union { #if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE) @@ -1336,6 +1452,9 @@ struct iwl_priv { struct iwl_notif_statistics statistics; struct iwl_bt_notif_statistics statistics_bt; + /* counts reply_tx error */ + struct reply_tx_error_statistics reply_tx_stats; + struct reply_agg_tx_error_statistics reply_agg_tx_stats; #ifdef CONFIG_IWLWIFI_DEBUGFS struct iwl_notif_statistics accum_statistics; struct iwl_notif_statistics delta_statistics; @@ -1348,24 +1467,45 @@ struct iwl_priv { #endif }; + /* bt coex */ + u8 bt_status; + u8 bt_traffic_load, notif_bt_traffic_load; + bool bt_ch_announce; + bool bt_sco_active; + bool bt_full_concurrent; + bool bt_ant_couple_ok; + __le32 kill_ack_mask; + __le32 kill_cts_mask; + __le16 bt_valid; + u16 bt_on_thresh; + u16 bt_duration; + u16 dynamic_frag_thresh; + u16 dynamic_agg_thresh; + u8 bt_ci_compliance; + struct work_struct bt_traffic_change_work; + struct iwl_hw_params hw_params; u32 inta_mask; - struct iwl_qos_info qos_data; - struct workqueue_struct *workqueue; struct work_struct restart; struct work_struct scan_completed; struct work_struct rx_replenish; struct work_struct abort_scan; + struct work_struct beacon_update; + struct iwl_rxon_context *beacon_ctx; + struct sk_buff *beacon_skb; + struct work_struct tt_work; struct work_struct ct_enter; struct work_struct ct_exit; struct work_struct start_internal_scan; struct work_struct tx_flush; + struct work_struct bt_full_concurrency; + struct work_struct bt_runtime_config; struct tasklet_struct irq_tasklet; @@ -1419,7 +1559,6 @@ static inline void iwl_txq_ctx_deactivate(struct iwl_priv *priv, int txq_id) } #ifdef CONFIG_IWLWIFI_DEBUG -const char *iwl_get_tx_fail_reason(u32 status); /* * iwl_get_debug_level: Return active debug level for device * @@ -1435,8 +1574,6 @@ static inline u32 iwl_get_debug_level(struct iwl_priv *priv) return iwl_debug_level; } #else -static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; } - static inline u32 iwl_get_debug_level(struct iwl_priv *priv) { return iwl_debug_level; @@ -1453,10 +1590,34 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, return NULL; } +static inline struct iwl_rxon_context * +iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif) +{ + struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; + + return vif_priv->ctx; +} + +#define for_each_context(priv, ctx) \ + for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \ + ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \ + if (priv->valid_contexts & BIT(ctx->ctxid)) + +static inline int iwl_is_associated(struct iwl_priv *priv, + enum iwl_rxon_context_id ctxid) +{ + return (priv->contexts[ctxid].active.filter_flags & + RXON_FILTER_ASSOC_MSK) ? 1 : 0; +} + +static inline int iwl_is_any_associated(struct iwl_priv *priv) +{ + return iwl_is_associated(priv, IWL_RXON_CTX_BSS); +} -static inline int iwl_is_associated(struct iwl_priv *priv) +static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx) { - return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; + return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; } static inline int is_channel_valid(const struct iwl_channel_info *ch_info) diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index a45d02e555cfffbcd3d174deb5dbdc4352ff6bef..87cd10ff285d0800dd0b575324a41553dab59110 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -136,85 +136,13 @@ static const u8 iwl_eeprom_band_7[] = { /* 5.2 ht40 channel */ 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157 }; -/** - * struct iwl_txpwr_section: eeprom section information - * @offset: indirect address into eeprom image - * @count: number of "struct iwl_eeprom_enhanced_txpwr" in this section - * @band: band type for the section - * @is_common - true: common section, false: channel section - * @is_cck - true: cck section, false: not cck section - * @is_ht_40 - true: all channel in the section are HT40 channel, - * false: legacy or HT 20 MHz - * ignore if it is common section - * @iwl_eeprom_section_channel: channel array in the section, - * ignore if common section - */ -struct iwl_txpwr_section { - u32 offset; - u8 count; - enum ieee80211_band band; - bool is_common; - bool is_cck; - bool is_ht40; - u8 iwl_eeprom_section_channel[EEPROM_MAX_TXPOWER_SECTION_ELEMENTS]; -}; - -/** - * section 1 - 3 are regulatory tx power apply to all channels based on - * modulation: CCK, OFDM - * Band: 2.4GHz, 5.2GHz - * section 4 - 10 are regulatory tx power apply to specified channels - * For example: - * 1L - Channel 1 Legacy - * 1HT - Channel 1 HT - * (1,+1) - Channel 1 HT40 "_above_" - * - * Section 1: all CCK channels - * Section 2: all 2.4 GHz OFDM (Legacy, HT and HT40) channels - * Section 3: all 5.2 GHz OFDM (Legacy, HT and HT40) channels - * Section 4: 2.4 GHz 20MHz channels: 1L, 1HT, 2L, 2HT, 10L, 10HT, 11L, 11HT - * Section 5: 2.4 GHz 40MHz channels: (1,+1) (2,+1) (6,+1) (7,+1) (9,+1) - * Section 6: 5.2 GHz 20MHz channels: 36L, 64L, 100L, 36HT, 64HT, 100HT - * Section 7: 5.2 GHz 40MHz channels: (36,+1) (60,+1) (100,+1) - * Section 8: 2.4 GHz channel: 13L, 13HT - * Section 9: 2.4 GHz channel: 140L, 140HT - * Section 10: 2.4 GHz 40MHz channels: (132,+1) (44,+1) - * - */ -static const struct iwl_txpwr_section enhinfo[] = { - { EEPROM_LB_CCK_20_COMMON, 1, IEEE80211_BAND_2GHZ, true, true, false }, - { EEPROM_LB_OFDM_COMMON, 3, IEEE80211_BAND_2GHZ, true, false, false }, - { EEPROM_HB_OFDM_COMMON, 3, IEEE80211_BAND_5GHZ, true, false, false }, - { EEPROM_LB_OFDM_20_BAND, 8, IEEE80211_BAND_2GHZ, - false, false, false, - {1, 1, 2, 2, 10, 10, 11, 11 } }, - { EEPROM_LB_OFDM_HT40_BAND, 5, IEEE80211_BAND_2GHZ, - false, false, true, - { 1, 2, 6, 7, 9 } }, - { EEPROM_HB_OFDM_20_BAND, 6, IEEE80211_BAND_5GHZ, - false, false, false, - { 36, 64, 100, 36, 64, 100 } }, - { EEPROM_HB_OFDM_HT40_BAND, 3, IEEE80211_BAND_5GHZ, - false, false, true, - { 36, 60, 100 } }, - { EEPROM_LB_OFDM_20_CHANNEL_13, 2, IEEE80211_BAND_2GHZ, - false, false, false, - { 13, 13 } }, - { EEPROM_HB_OFDM_20_CHANNEL_140, 2, IEEE80211_BAND_5GHZ, - false, false, false, - { 140, 140 } }, - { EEPROM_HB_OFDM_HT40_BAND_1, 2, IEEE80211_BAND_5GHZ, - false, false, true, - { 132, 44 } }, -}; - /****************************************************************************** * * EEPROM related functions * ******************************************************************************/ -int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) +static int iwl_eeprom_verify_signature(struct iwl_priv *priv) { u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; int ret = 0; @@ -246,7 +174,6 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv) } return ret; } -EXPORT_SYMBOL(iwlcore_eeprom_verify_signature); static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode) { @@ -290,49 +217,9 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv) return nvm_type; } -/* - * The device's EEPROM semaphore prevents conflicts between driver and uCode - * when accessing the EEPROM; each access is a series of pulses to/from the - * EEPROM chip, not a single event, so even reads could conflict if they - * weren't arbitrated by the semaphore. - */ -int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) -{ - u16 count; - int ret; - - for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { - /* Request semaphore */ - iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); - - /* See if we got it */ - ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, - EEPROM_SEM_TIMEOUT); - if (ret >= 0) { - IWL_DEBUG_IO(priv, "Acquired semaphore after %d tries.\n", - count+1); - return ret; - } - } - - return ret; -} -EXPORT_SYMBOL(iwlcore_eeprom_acquire_semaphore); - -void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv) -{ - iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); - -} -EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore); - const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { - BUG_ON(offset >= priv->cfg->eeprom_size); + BUG_ON(offset >= priv->cfg->base_params->eeprom_size); return &priv->eeprom[offset]; } EXPORT_SYMBOL(iwlcore_eeprom_query_addr); @@ -364,7 +251,7 @@ static int iwl_init_otp_access(struct iwl_priv *priv) * CSR auto clock gate disable bit - * this is only applicable for HW with OTP shadow RAM */ - if (priv->cfg->shadow_ram_support) + if (priv->cfg->base_params->shadow_ram_support) iwl_set_bit(priv, CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); } @@ -484,13 +371,27 @@ static int iwl_find_otp_image(struct iwl_priv *priv, } /* more in the link list, continue */ usedblocks++; - } while (usedblocks <= priv->cfg->max_ll_items); + } while (usedblocks <= priv->cfg->base_params->max_ll_items); /* OTP has no valid blocks */ IWL_DEBUG_INFO(priv, "OTP has no valid blocks\n"); return -EINVAL; } +const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) +{ + return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); +} +EXPORT_SYMBOL(iwl_eeprom_query_addr); + +u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) +{ + if (!priv->eeprom) + return 0; + return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); +} +EXPORT_SYMBOL(iwl_eeprom_query16); + /** * iwl_eeprom_init - read EEPROM contents * @@ -512,8 +413,8 @@ int iwl_eeprom_init(struct iwl_priv *priv) if (priv->nvm_device_type == -ENOENT) return -ENOENT; /* allocate eeprom */ - IWL_DEBUG_INFO(priv, "NVM size = %d\n", priv->cfg->eeprom_size); - sz = priv->cfg->eeprom_size; + sz = priv->cfg->base_params->eeprom_size; + IWL_DEBUG_INFO(priv, "NVM size = %d\n", sz); priv->eeprom = kzalloc(sz, GFP_KERNEL); if (!priv->eeprom) { ret = -ENOMEM; @@ -523,7 +424,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) priv->cfg->ops->lib->apm_ops.init(priv); - ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv); + ret = iwl_eeprom_verify_signature(priv); if (ret < 0) { IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); ret = -ENOENT; @@ -554,7 +455,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ - if (!priv->cfg->shadow_ram_support) { + if (!priv->cfg->base_params->shadow_ram_support) { if (iwl_find_otp_image(priv, &validblockaddr)) { ret = -ENOENT; goto done; @@ -604,7 +505,7 @@ int iwl_eeprom_init(struct iwl_priv *priv) if (ret) iwl_eeprom_free(priv); /* Reset chip to save power until we load uCode during "up". */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); alloc_err: return ret; } @@ -617,53 +518,6 @@ void iwl_eeprom_free(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_eeprom_free); -int iwl_eeprom_check_version(struct iwl_priv *priv) -{ - u16 eeprom_ver; - u16 calib_ver; - - eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); - calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv); - - if (eeprom_ver < priv->cfg->eeprom_ver || - calib_ver < priv->cfg->eeprom_calib_ver) - goto err; - - IWL_INFO(priv, "device EEPROM VER=0x%x, CALIB=0x%x\n", - eeprom_ver, calib_ver); - - return 0; -err: - IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n", - eeprom_ver, priv->cfg->eeprom_ver, - calib_ver, priv->cfg->eeprom_calib_ver); - return -EINVAL; - -} -EXPORT_SYMBOL(iwl_eeprom_check_version); - -const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) -{ - return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset); -} -EXPORT_SYMBOL(iwl_eeprom_query_addr); - -u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset) -{ - if (!priv->eeprom) - return 0; - return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8); -} -EXPORT_SYMBOL(iwl_eeprom_query16); - -void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) -{ - const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv, - EEPROM_MAC_ADDRESS); - memcpy(mac, addr, ETH_ALEN); -} -EXPORT_SYMBOL(iwl_eeprom_get_mac); - static void iwl_init_band_reference(const struct iwl_priv *priv, int eep_band, int *eeprom_ch_count, const struct iwl_eeprom_channel **eeprom_ch_info, @@ -722,7 +576,6 @@ static void iwl_init_band_reference(const struct iwl_priv *priv, #define CHECK_AND_PRINT(x) ((eeprom_ch->flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") - /** * iwl_mod_ht40_chan_info - Copy ht40 channel info into driver's priv. * @@ -766,205 +619,6 @@ static int iwl_mod_ht40_chan_info(struct iwl_priv *priv, return 0; } -/** - * iwl_get_max_txpower_avg - get the highest tx power from all chains. - * find the highest tx power from all chains for the channel - */ -static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int element, s8 *max_txpower_in_half_dbm) -{ - s8 max_txpower_avg = 0; /* (dBm) */ - - IWL_DEBUG_INFO(priv, "%d - " - "chain_a: %d dB chain_b: %d dB " - "chain_c: %d dB mimo2: %d dB mimo3: %d dB\n", - element, - enhanced_txpower[element].chain_a_max >> 1, - enhanced_txpower[element].chain_b_max >> 1, - enhanced_txpower[element].chain_c_max >> 1, - enhanced_txpower[element].mimo2_max >> 1, - enhanced_txpower[element].mimo3_max >> 1); - /* Take the highest tx power from any valid chains */ - if ((priv->cfg->valid_tx_ant & ANT_A) && - (enhanced_txpower[element].chain_a_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_a_max; - if ((priv->cfg->valid_tx_ant & ANT_B) && - (enhanced_txpower[element].chain_b_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_b_max; - if ((priv->cfg->valid_tx_ant & ANT_C) && - (enhanced_txpower[element].chain_c_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].chain_c_max; - if (((priv->cfg->valid_tx_ant == ANT_AB) | - (priv->cfg->valid_tx_ant == ANT_BC) | - (priv->cfg->valid_tx_ant == ANT_AC)) && - (enhanced_txpower[element].mimo2_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].mimo2_max; - if ((priv->cfg->valid_tx_ant == ANT_ABC) && - (enhanced_txpower[element].mimo3_max > max_txpower_avg)) - max_txpower_avg = enhanced_txpower[element].mimo3_max; - - /* - * max. tx power in EEPROM is in 1/2 dBm format - * convert from 1/2 dBm to dBm (round-up convert) - * but we also do not want to loss 1/2 dBm resolution which - * will impact performance - */ - *max_txpower_in_half_dbm = max_txpower_avg; - return (max_txpower_avg & 0x01) + (max_txpower_avg >> 1); -} - -/** - * iwl_update_common_txpower: update channel tx power - * update tx power per band based on EEPROM enhanced tx power info. - */ -static s8 iwl_update_common_txpower(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int section, int element, s8 *max_txpower_in_half_dbm) -{ - struct iwl_channel_info *ch_info; - int ch; - bool is_ht40 = false; - s8 max_txpower_avg; /* (dBm) */ - - /* it is common section, contain all type (Legacy, HT and HT40) - * based on the element in the section to determine - * is it HT 40 or not - */ - if (element == EEPROM_TXPOWER_COMMON_HT40_INDEX) - is_ht40 = true; - max_txpower_avg = - iwl_get_max_txpower_avg(priv, enhanced_txpower, - element, max_txpower_in_half_dbm); - - ch_info = priv->channel_info; - - for (ch = 0; ch < priv->channel_count; ch++) { - /* find matching band and update tx power if needed */ - if ((ch_info->band == enhinfo[section].band) && - (ch_info->max_power_avg < max_txpower_avg) && - (!is_ht40)) { - /* Update regulatory-based run-time data */ - ch_info->max_power_avg = ch_info->curr_txpow = - max_txpower_avg; - ch_info->scan_power = max_txpower_avg; - } - if ((ch_info->band == enhinfo[section].band) && is_ht40 && - (ch_info->ht40_max_power_avg < max_txpower_avg)) { - /* Update regulatory-based run-time data */ - ch_info->ht40_max_power_avg = max_txpower_avg; - } - ch_info++; - } - return max_txpower_avg; -} - -/** - * iwl_update_channel_txpower: update channel tx power - * update channel tx power based on EEPROM enhanced tx power info. - */ -static s8 iwl_update_channel_txpower(struct iwl_priv *priv, - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower, - int section, int element, s8 *max_txpower_in_half_dbm) -{ - struct iwl_channel_info *ch_info; - int ch; - u8 channel; - s8 max_txpower_avg; /* (dBm) */ - - channel = enhinfo[section].iwl_eeprom_section_channel[element]; - max_txpower_avg = - iwl_get_max_txpower_avg(priv, enhanced_txpower, - element, max_txpower_in_half_dbm); - - ch_info = priv->channel_info; - for (ch = 0; ch < priv->channel_count; ch++) { - /* find matching channel and update tx power if needed */ - if (ch_info->channel == channel) { - if ((ch_info->max_power_avg < max_txpower_avg) && - (!enhinfo[section].is_ht40)) { - /* Update regulatory-based run-time data */ - ch_info->max_power_avg = max_txpower_avg; - ch_info->curr_txpow = max_txpower_avg; - ch_info->scan_power = max_txpower_avg; - } - if ((enhinfo[section].is_ht40) && - (ch_info->ht40_max_power_avg < max_txpower_avg)) { - /* Update regulatory-based run-time data */ - ch_info->ht40_max_power_avg = max_txpower_avg; - } - break; - } - ch_info++; - } - return max_txpower_avg; -} - -/** - * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info - */ -void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) -{ - int eeprom_section_count = 0; - int section, element; - struct iwl_eeprom_enhanced_txpwr *enhanced_txpower; - u32 offset; - s8 max_txpower_avg; /* (dBm) */ - s8 max_txpower_in_half_dbm; /* (half-dBm) */ - - /* Loop through all the sections - * adjust bands and channel's max tx power - * Set the tx_power_user_lmt to the highest power - * supported by any channels and chains - */ - for (section = 0; section < ARRAY_SIZE(enhinfo); section++) { - eeprom_section_count = enhinfo[section].count; - offset = enhinfo[section].offset; - enhanced_txpower = (struct iwl_eeprom_enhanced_txpwr *) - iwl_eeprom_query_addr(priv, offset); - - /* - * check for valid entry - - * different version of EEPROM might contain different set - * of enhanced tx power table - * always check for valid entry before process - * the information - */ - if (!enhanced_txpower->common || enhanced_txpower->reserved) - continue; - - for (element = 0; element < eeprom_section_count; element++) { - if (enhinfo[section].is_common) - max_txpower_avg = - iwl_update_common_txpower(priv, - enhanced_txpower, section, - element, - &max_txpower_in_half_dbm); - else - max_txpower_avg = - iwl_update_channel_txpower(priv, - enhanced_txpower, section, - element, - &max_txpower_in_half_dbm); - - /* Update the tx_power_user_lmt to the highest power - * supported by any channel */ - if (max_txpower_avg > priv->tx_power_user_lmt) - priv->tx_power_user_lmt = max_txpower_avg; - - /* - * Update the tx_power_lmt_in_half_dbm to - * the highest power supported by any channel - */ - if (max_txpower_in_half_dbm > - priv->tx_power_lmt_in_half_dbm) - priv->tx_power_lmt_in_half_dbm = - max_txpower_in_half_dbm; - } - } -} -EXPORT_SYMBOL(iwlcore_eeprom_enhanced_txpower); - #define CHECK_AND_PRINT_I(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \ ? # x " " : "") @@ -1162,4 +816,3 @@ const struct iwl_channel_info *iwl_get_channel_info(const struct iwl_priv *priv, return NULL; } EXPORT_SYMBOL(iwl_get_channel_info); - diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index a4772aff51fe0479fc5e522a4a1c59df18a68de2..d9b590625ae4eb16ba996d0bbd8d794acc30dae9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -493,7 +493,6 @@ struct iwl_eeprom_calib_info { struct iwl_eeprom_ops { const u32 regulatory_bands[7]; - int (*verify_signature) (struct iwl_priv *priv); int (*acquire_semaphore) (struct iwl_priv *priv); void (*release_semaphore) (struct iwl_priv *priv); u16 (*calib_version) (struct iwl_priv *priv); @@ -502,18 +501,13 @@ struct iwl_eeprom_ops { }; -void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); int iwl_eeprom_init(struct iwl_priv *priv); void iwl_eeprom_free(struct iwl_priv *priv); int iwl_eeprom_check_version(struct iwl_priv *priv); const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); -u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); - int iwlcore_eeprom_verify_signature(struct iwl_priv *priv); -int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); -void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); +u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset); const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset); -void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv); int iwl_init_channel_map(struct iwl_priv *priv); void iwl_free_channel_map(struct iwl_priv *priv); const struct iwl_channel_info *iwl_get_channel_info( diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 258d059ef41f44ae01e4199327133655b5e6df1e..c373b53babeaee1cd1c4e7781151e683e305f2ba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c @@ -97,6 +97,17 @@ const char *get_cmd_string(u8 cmd) IWL_CMD(REPLY_TX_POWER_DBM_CMD); IWL_CMD(TEMPERATURE_NOTIFICATION); IWL_CMD(TX_ANT_CONFIGURATION_CMD); + IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF); + IWL_CMD(REPLY_BT_COEX_PRIO_TABLE); + IWL_CMD(REPLY_BT_COEX_PROT_ENV); + IWL_CMD(REPLY_WIPAN_PARAMS); + IWL_CMD(REPLY_WIPAN_RXON); + IWL_CMD(REPLY_WIPAN_RXON_TIMING); + IWL_CMD(REPLY_WIPAN_RXON_ASSOC); + IWL_CMD(REPLY_WIPAN_QOS_PARAM); + IWL_CMD(REPLY_WIPAN_WEPKEY); + IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH); + IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION); default: return "UNKNOWN"; @@ -229,7 +240,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) * in later, it will possibly set an invalid * address (cmd->meta.source). */ - priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_idx].flags &= + priv->txq[priv->cmd_queue].meta[cmd_idx].flags &= ~CMD_WANT_SKB; } fail: diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h index 621abe3c5afce3fc2b73b66e37c82c7b4d8fcf66..1aaef70deaecf58d85c7fac8d218578dee97c025 100644 --- a/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -44,11 +44,6 @@ static inline struct ieee80211_conf *ieee80211_get_hw_conf( return &hw->conf; } -static inline int iwl_check_bits(unsigned long field, unsigned long mask) -{ - return ((field & mask) == mask) ? 1 : 0; -} - static inline unsigned long elapsed_jiffies(unsigned long start, unsigned long end) { diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index db5bfcb036ca274a2f1183e4f5e7ff963568998d..86c2b6fed0c6beeeb920ccc4adfb54dd5e0b990f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -108,13 +108,13 @@ static int iwl_led_pattern(struct iwl_priv *priv, unsigned int idx) BUG_ON(idx > IWL_MAX_BLINK_TBL); IWL_DEBUG_LED(priv, "Led blink time compensation= %u\n", - priv->cfg->led_compensation); + priv->cfg->base_params->led_compensation); led_cmd.on = iwl_blink_compensation(priv, blink_tbl[idx].on_time, - priv->cfg->led_compensation); + priv->cfg->base_params->led_compensation); led_cmd.off = iwl_blink_compensation(priv, blink_tbl[idx].off_time, - priv->cfg->led_compensation); + priv->cfg->base_params->led_compensation); return priv->cfg->ops->led->cmd(priv, &led_cmd); } diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index cda6a94d6cc92234f901470fb3c8fe93650c61e6..49d7788937a9eccc80891c703ea4220c1a98f100 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -192,47 +192,6 @@ static void iwl_static_sleep_cmd(struct iwl_priv *priv, IWL_DEBUG_POWER(priv, "Sleep command for index %d\n", lvl + 1); } -/* default Thermal Throttling transaction table - * Current state | Throttling Down | Throttling Up - *============================================================================= - * Condition Nxt State Condition Nxt State Condition Nxt State - *----------------------------------------------------------------------------- - * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A - * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 - * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 - * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 - *============================================================================= - */ -static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = { - {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104}, - {IWL_TI_1, 105, CT_KILL_THRESHOLD - 1}, - {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} -}; -static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = { - {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95}, - {IWL_TI_2, 110, CT_KILL_THRESHOLD - 1}, - {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} -}; -static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = { - {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100}, - {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX}, - {IWL_TI_CT_KILL, CT_KILL_THRESHOLD, IWL_ABSOLUTE_MAX} -}; -static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = { - {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD}, - {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}, - {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX} -}; - -/* Advance Thermal Throttling default restriction table */ -static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = { - {IWL_ANT_OK_MULTI, IWL_ANT_OK_MULTI, true }, - {IWL_ANT_OK_SINGLE, IWL_ANT_OK_MULTI, true }, - {IWL_ANT_OK_SINGLE, IWL_ANT_OK_SINGLE, false }, - {IWL_ANT_OK_NONE, IWL_ANT_OK_NONE, false } -}; - - static void iwl_power_sleep_cam_cmd(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) { @@ -308,7 +267,6 @@ static int iwl_set_power(struct iwl_priv *priv, struct iwl_powertable_cmd *cmd) int iwl_power_update_mode(struct iwl_priv *priv, bool force) { int ret = 0; - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; bool enabled = priv->hw->conf.flags & IEEE80211_CONF_PS; bool update_chains; struct iwl_powertable_cmd cmd; @@ -320,14 +278,18 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) dtimper = priv->hw->conf.ps_dtim_period ?: 1; - if (priv->cfg->broken_powersave) + if (priv->cfg->base_params->broken_powersave) iwl_power_sleep_cam_cmd(priv, &cmd); - else if (priv->cfg->supports_idle && + else if (priv->cfg->base_params->supports_idle && priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, &cmd, IWL_POWER_INDEX_5, 20); - else if (tt->state >= IWL_TI_1) - iwl_static_sleep_cmd(priv, &cmd, tt->tt_power_mode, dtimper); - else if (!enabled) + else if (priv->cfg->ops->lib->tt_ops.lower_power_detection && + priv->cfg->ops->lib->tt_ops.tt_power_mode && + priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) { + /* in thermal throttling low power state */ + iwl_static_sleep_cmd(priv, &cmd, + priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper); + } else if (!enabled) iwl_power_sleep_cam_cmd(priv, &cmd); else if (priv->power_data.debug_sleep_level_override >= 0) iwl_static_sleep_cmd(priv, &cmd, @@ -367,592 +329,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) } EXPORT_SYMBOL(iwl_power_update_mode); -bool iwl_ht_enabled(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - struct iwl_tt_restriction *restriction; - - if (!priv->thermal_throttle.advanced_tt) - return true; - restriction = tt->restriction + tt->state; - return restriction->is_ht; -} -EXPORT_SYMBOL(iwl_ht_enabled); - -bool iwl_within_ct_kill_margin(struct iwl_priv *priv) -{ - s32 temp = priv->temperature; /* degrees CELSIUS except specified */ - bool within_margin = false; - - if (priv->cfg->temperature_kelvin) - temp = KELVIN_TO_CELSIUS(priv->temperature); - - if (!priv->thermal_throttle.advanced_tt) - within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >= - CT_KILL_THRESHOLD_LEGACY) ? true : false; - else - within_margin = ((temp + IWL_TT_CT_KILL_MARGIN) >= - CT_KILL_THRESHOLD) ? true : false; - return within_margin; -} - -enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - struct iwl_tt_restriction *restriction; - - if (!priv->thermal_throttle.advanced_tt) - return IWL_ANT_OK_MULTI; - restriction = tt->restriction + tt->state; - return restriction->tx_stream; -} -EXPORT_SYMBOL(iwl_tx_ant_restriction); - -enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - struct iwl_tt_restriction *restriction; - - if (!priv->thermal_throttle.advanced_tt) - return IWL_ANT_OK_MULTI; - restriction = tt->restriction + tt->state; - return restriction->rx_stream; -} - -#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */ -#define CT_KILL_WAITING_DURATION (300) /* 300ms duration */ - -/* - * toggle the bit to wake up uCode and check the temperature - * if the temperature is below CT, uCode will stay awake and send card - * state notification with CT_KILL bit clear to inform Thermal Throttling - * Management to change state. Otherwise, uCode will go back to sleep - * without doing anything, driver should continue the 5 seconds timer - * to wake up uCode for temperature check until temperature drop below CT - */ -static void iwl_tt_check_exit_ct_kill(unsigned long data) -{ - struct iwl_priv *priv = (struct iwl_priv *)data; - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - unsigned long flags; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (tt->state == IWL_TI_CT_KILL) { - if (priv->thermal_throttle.ct_kill_toggle) { - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, - CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - priv->thermal_throttle.ct_kill_toggle = false; - } else { - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, - CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - priv->thermal_throttle.ct_kill_toggle = true; - } - iwl_read32(priv, CSR_UCODE_DRV_GP1); - spin_lock_irqsave(&priv->reg_lock, flags); - if (!iwl_grab_nic_access(priv)) - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->reg_lock, flags); - - /* Reschedule the ct_kill timer to occur in - * CT_KILL_EXIT_DURATION seconds to ensure we get a - * thermal update */ - IWL_DEBUG_POWER(priv, "schedule ct_kill exit timer\n"); - mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies + - CT_KILL_EXIT_DURATION * HZ); - } -} - -static void iwl_perform_ct_kill_task(struct iwl_priv *priv, - bool stop) -{ - if (stop) { - IWL_DEBUG_POWER(priv, "Stop all queues\n"); - if (priv->mac80211_registered) - ieee80211_stop_queues(priv->hw); - IWL_DEBUG_POWER(priv, - "Schedule 5 seconds CT_KILL Timer\n"); - mod_timer(&priv->thermal_throttle.ct_kill_exit_tm, jiffies + - CT_KILL_EXIT_DURATION * HZ); - } else { - IWL_DEBUG_POWER(priv, "Wake all queues\n"); - if (priv->mac80211_registered) - ieee80211_wake_queues(priv->hw); - } -} - -static void iwl_tt_ready_for_ct_kill(unsigned long data) -{ - struct iwl_priv *priv = (struct iwl_priv *)data; - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - /* temperature timer expired, ready to go into CT_KILL state */ - if (tt->state != IWL_TI_CT_KILL) { - IWL_DEBUG_POWER(priv, "entering CT_KILL state when temperature timer expired\n"); - tt->state = IWL_TI_CT_KILL; - set_bit(STATUS_CT_KILL, &priv->status); - iwl_perform_ct_kill_task(priv, true); - } -} - -static void iwl_prepare_ct_kill_task(struct iwl_priv *priv) -{ - IWL_DEBUG_POWER(priv, "Prepare to enter IWL_TI_CT_KILL\n"); - /* make request to retrieve statistics information */ - iwl_send_statistics_request(priv, CMD_SYNC, false); - /* Reschedule the ct_kill wait timer */ - mod_timer(&priv->thermal_throttle.ct_kill_waiting_tm, - jiffies + msecs_to_jiffies(CT_KILL_WAITING_DURATION)); -} - -#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY) -#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100) -#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90) - -/* - * Legacy thermal throttling - * 1) Avoid NIC destruction due to high temperatures - * Chip will identify dangerously high temperatures that can - * harm the device and will power down - * 2) Avoid the NIC power down due to high temperature - * Throttle early enough to lower the power consumption before - * drastic steps are needed - */ -static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp, bool force) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - enum iwl_tt_state old_state; - -#ifdef CONFIG_IWLWIFI_DEBUG - if ((tt->tt_previous_temp) && - (temp > tt->tt_previous_temp) && - ((temp - tt->tt_previous_temp) > - IWL_TT_INCREASE_MARGIN)) { - IWL_DEBUG_POWER(priv, - "Temperature increase %d degree Celsius\n", - (temp - tt->tt_previous_temp)); - } -#endif - old_state = tt->state; - /* in Celsius */ - if (temp >= IWL_MINIMAL_POWER_THRESHOLD) - tt->state = IWL_TI_CT_KILL; - else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2) - tt->state = IWL_TI_2; - else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1) - tt->state = IWL_TI_1; - else - tt->state = IWL_TI_0; - -#ifdef CONFIG_IWLWIFI_DEBUG - tt->tt_previous_temp = temp; -#endif - /* stop ct_kill_waiting_tm timer */ - del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); - if (tt->state != old_state) { - switch (tt->state) { - case IWL_TI_0: - /* - * When the system is ready to go back to IWL_TI_0 - * we only have to call iwl_power_update_mode() to - * do so. - */ - break; - case IWL_TI_1: - tt->tt_power_mode = IWL_POWER_INDEX_3; - break; - case IWL_TI_2: - tt->tt_power_mode = IWL_POWER_INDEX_4; - break; - default: - tt->tt_power_mode = IWL_POWER_INDEX_5; - break; - } - mutex_lock(&priv->mutex); - if (old_state == IWL_TI_CT_KILL) - clear_bit(STATUS_CT_KILL, &priv->status); - if (tt->state != IWL_TI_CT_KILL && - iwl_power_update_mode(priv, true)) { - /* TT state not updated - * try again during next temperature read - */ - if (old_state == IWL_TI_CT_KILL) - set_bit(STATUS_CT_KILL, &priv->status); - tt->state = old_state; - IWL_ERR(priv, "Cannot update power mode, " - "TT state not updated\n"); - } else { - if (tt->state == IWL_TI_CT_KILL) { - if (force) { - set_bit(STATUS_CT_KILL, &priv->status); - iwl_perform_ct_kill_task(priv, true); - } else { - iwl_prepare_ct_kill_task(priv); - tt->state = old_state; - } - } else if (old_state == IWL_TI_CT_KILL && - tt->state != IWL_TI_CT_KILL) - iwl_perform_ct_kill_task(priv, false); - IWL_DEBUG_POWER(priv, "Temperature state changed %u\n", - tt->state); - IWL_DEBUG_POWER(priv, "Power Index change to %u\n", - tt->tt_power_mode); - } - mutex_unlock(&priv->mutex); - } -} - -/* - * Advance thermal throttling - * 1) Avoid NIC destruction due to high temperatures - * Chip will identify dangerously high temperatures that can - * harm the device and will power down - * 2) Avoid the NIC power down due to high temperature - * Throttle early enough to lower the power consumption before - * drastic steps are needed - * Actions include relaxing the power down sleep thresholds and - * decreasing the number of TX streams - * 3) Avoid throughput performance impact as much as possible - * - *============================================================================= - * Condition Nxt State Condition Nxt State Condition Nxt State - *----------------------------------------------------------------------------- - * IWL_TI_0 T >= 114 CT_KILL 114>T>=105 TI_1 N/A N/A - * IWL_TI_1 T >= 114 CT_KILL 114>T>=110 TI_2 T<=95 TI_0 - * IWL_TI_2 T >= 114 CT_KILL T<=100 TI_1 - * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0 - *============================================================================= - */ -static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - int i; - bool changed = false; - enum iwl_tt_state old_state; - struct iwl_tt_trans *transaction; - - old_state = tt->state; - for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) { - /* based on the current TT state, - * find the curresponding transaction table - * each table has (IWL_TI_STATE_MAX - 1) entries - * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1)) - * will advance to the correct table. - * then based on the current temperature - * find the next state need to transaction to - * go through all the possible (IWL_TI_STATE_MAX - 1) entries - * in the current table to see if transaction is needed - */ - transaction = tt->transaction + - ((old_state * (IWL_TI_STATE_MAX - 1)) + i); - if (temp >= transaction->tt_low && - temp <= transaction->tt_high) { -#ifdef CONFIG_IWLWIFI_DEBUG - if ((tt->tt_previous_temp) && - (temp > tt->tt_previous_temp) && - ((temp - tt->tt_previous_temp) > - IWL_TT_INCREASE_MARGIN)) { - IWL_DEBUG_POWER(priv, - "Temperature increase %d " - "degree Celsius\n", - (temp - tt->tt_previous_temp)); - } - tt->tt_previous_temp = temp; -#endif - if (old_state != - transaction->next_state) { - changed = true; - tt->state = - transaction->next_state; - } - break; - } - } - /* stop ct_kill_waiting_tm timer */ - del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); - if (changed) { - struct iwl_rxon_cmd *rxon = &priv->staging_rxon; - - if (tt->state >= IWL_TI_1) { - /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */ - tt->tt_power_mode = IWL_POWER_INDEX_5; - if (!iwl_ht_enabled(priv)) - /* disable HT */ - rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | - RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | - RXON_FLG_HT40_PROT_MSK | - RXON_FLG_HT_PROT_MSK); - else { - /* check HT capability and set - * according to the system HT capability - * in case get disabled before */ - iwl_set_rxon_ht(priv, &priv->current_ht_config); - } - - } else { - /* - * restore system power setting -- it will be - * recalculated automatically. - */ - - /* check HT capability and set - * according to the system HT capability - * in case get disabled before */ - iwl_set_rxon_ht(priv, &priv->current_ht_config); - } - mutex_lock(&priv->mutex); - if (old_state == IWL_TI_CT_KILL) - clear_bit(STATUS_CT_KILL, &priv->status); - if (tt->state != IWL_TI_CT_KILL && - iwl_power_update_mode(priv, true)) { - /* TT state not updated - * try again during next temperature read - */ - IWL_ERR(priv, "Cannot update power mode, " - "TT state not updated\n"); - if (old_state == IWL_TI_CT_KILL) - set_bit(STATUS_CT_KILL, &priv->status); - tt->state = old_state; - } else { - IWL_DEBUG_POWER(priv, - "Thermal Throttling to new state: %u\n", - tt->state); - if (old_state != IWL_TI_CT_KILL && - tt->state == IWL_TI_CT_KILL) { - if (force) { - IWL_DEBUG_POWER(priv, - "Enter IWL_TI_CT_KILL\n"); - set_bit(STATUS_CT_KILL, &priv->status); - iwl_perform_ct_kill_task(priv, true); - } else { - iwl_prepare_ct_kill_task(priv); - tt->state = old_state; - } - } else if (old_state == IWL_TI_CT_KILL && - tt->state != IWL_TI_CT_KILL) { - IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n"); - iwl_perform_ct_kill_task(priv, false); - } - } - mutex_unlock(&priv->mutex); - } -} - -/* Card State Notification indicated reach critical temperature - * if PSP not enable, no Thermal Throttling function will be performed - * just set the GP1 bit to acknowledge the event - * otherwise, go into IWL_TI_CT_KILL state - * since Card State Notification will not provide any temperature reading - * for Legacy mode - * so just pass the CT_KILL temperature to iwl_legacy_tt_handler() - * for advance mode - * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state - */ -static void iwl_bg_ct_enter(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_enter); - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!iwl_is_ready(priv)) - return; - - if (tt->state != IWL_TI_CT_KILL) { - IWL_ERR(priv, "Device reached critical temperature " - "- ucode going to sleep!\n"); - if (!priv->thermal_throttle.advanced_tt) - iwl_legacy_tt_handler(priv, - IWL_MINIMAL_POWER_THRESHOLD, - true); - else - iwl_advance_tt_handler(priv, - CT_KILL_THRESHOLD + 1, true); - } -} - -/* Card State Notification indicated out of critical temperature - * since Card State Notification will not provide any temperature reading - * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature - * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state - */ -static void iwl_bg_ct_exit(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, ct_exit); - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (!iwl_is_ready(priv)) - return; - - /* stop ct_kill_exit_tm timer */ - del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm); - - if (tt->state == IWL_TI_CT_KILL) { - IWL_ERR(priv, - "Device temperature below critical" - "- ucode awake!\n"); - /* - * exit from CT_KILL state - * reset the current temperature reading - */ - priv->temperature = 0; - if (!priv->thermal_throttle.advanced_tt) - iwl_legacy_tt_handler(priv, - IWL_REDUCED_PERFORMANCE_THRESHOLD_2, - true); - else - iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD, - true); - } -} - -void iwl_tt_enter_ct_kill(struct iwl_priv *priv) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - IWL_DEBUG_POWER(priv, "Queueing critical temperature enter.\n"); - queue_work(priv->workqueue, &priv->ct_enter); -} -EXPORT_SYMBOL(iwl_tt_enter_ct_kill); - -void iwl_tt_exit_ct_kill(struct iwl_priv *priv) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - IWL_DEBUG_POWER(priv, "Queueing critical temperature exit.\n"); - queue_work(priv->workqueue, &priv->ct_exit); -} -EXPORT_SYMBOL(iwl_tt_exit_ct_kill); - -static void iwl_bg_tt_work(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, tt_work); - s32 temp = priv->temperature; /* degrees CELSIUS except specified */ - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - if (priv->cfg->temperature_kelvin) - temp = KELVIN_TO_CELSIUS(priv->temperature); - - if (!priv->thermal_throttle.advanced_tt) - iwl_legacy_tt_handler(priv, temp, false); - else - iwl_advance_tt_handler(priv, temp, false); -} - -void iwl_tt_handler(struct iwl_priv *priv) -{ - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - IWL_DEBUG_POWER(priv, "Queueing thermal throttling work.\n"); - queue_work(priv->workqueue, &priv->tt_work); -} -EXPORT_SYMBOL(iwl_tt_handler); - -/* Thermal throttling initialization - * For advance thermal throttling: - * Initialize Thermal Index and temperature threshold table - * Initialize thermal throttling restriction table - */ -void iwl_tt_initialize(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1); - struct iwl_tt_trans *transaction; - - IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling\n"); - - memset(tt, 0, sizeof(struct iwl_tt_mgmt)); - - tt->state = IWL_TI_0; - init_timer(&priv->thermal_throttle.ct_kill_exit_tm); - priv->thermal_throttle.ct_kill_exit_tm.data = (unsigned long)priv; - priv->thermal_throttle.ct_kill_exit_tm.function = - iwl_tt_check_exit_ct_kill; - init_timer(&priv->thermal_throttle.ct_kill_waiting_tm); - priv->thermal_throttle.ct_kill_waiting_tm.data = (unsigned long)priv; - priv->thermal_throttle.ct_kill_waiting_tm.function = - iwl_tt_ready_for_ct_kill; - /* setup deferred ct kill work */ - INIT_WORK(&priv->tt_work, iwl_bg_tt_work); - INIT_WORK(&priv->ct_enter, iwl_bg_ct_enter); - INIT_WORK(&priv->ct_exit, iwl_bg_ct_exit); - - if (priv->cfg->adv_thermal_throttle) { - IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n"); - tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) * - IWL_TI_STATE_MAX, GFP_KERNEL); - tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) * - IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1), - GFP_KERNEL); - if (!tt->restriction || !tt->transaction) { - IWL_ERR(priv, "Fallback to Legacy Throttling\n"); - priv->thermal_throttle.advanced_tt = false; - kfree(tt->restriction); - tt->restriction = NULL; - kfree(tt->transaction); - tt->transaction = NULL; - } else { - transaction = tt->transaction + - (IWL_TI_0 * (IWL_TI_STATE_MAX - 1)); - memcpy(transaction, &tt_range_0[0], size); - transaction = tt->transaction + - (IWL_TI_1 * (IWL_TI_STATE_MAX - 1)); - memcpy(transaction, &tt_range_1[0], size); - transaction = tt->transaction + - (IWL_TI_2 * (IWL_TI_STATE_MAX - 1)); - memcpy(transaction, &tt_range_2[0], size); - transaction = tt->transaction + - (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1)); - memcpy(transaction, &tt_range_3[0], size); - size = sizeof(struct iwl_tt_restriction) * - IWL_TI_STATE_MAX; - memcpy(tt->restriction, - &restriction_range[0], size); - priv->thermal_throttle.advanced_tt = true; - } - } else { - IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n"); - priv->thermal_throttle.advanced_tt = false; - } -} -EXPORT_SYMBOL(iwl_tt_initialize); - -/* cleanup thermal throttling management related memory and timer */ -void iwl_tt_exit(struct iwl_priv *priv) -{ - struct iwl_tt_mgmt *tt = &priv->thermal_throttle; - - /* stop ct_kill_exit_tm timer if activated */ - del_timer_sync(&priv->thermal_throttle.ct_kill_exit_tm); - /* stop ct_kill_waiting_tm timer if activated */ - del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); - cancel_work_sync(&priv->tt_work); - cancel_work_sync(&priv->ct_enter); - cancel_work_sync(&priv->ct_exit); - - if (priv->thermal_throttle.advanced_tt) { - /* free advance thermal throttling memory */ - kfree(tt->restriction); - tt->restriction = NULL; - kfree(tt->transaction); - tt->transaction = NULL; - } -} -EXPORT_SYMBOL(iwl_tt_exit); - /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) { diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 5db91c10dcc8ca602a4f1760ac4dbd395105bdae..df81565a7cc49c7414a6acd2421a2f3bd0f85930 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -30,90 +30,6 @@ #include "iwl-commands.h" -#define IWL_ABSOLUTE_ZERO 0 -#define IWL_ABSOLUTE_MAX 0xFFFFFFFF -#define IWL_TT_INCREASE_MARGIN 5 -#define IWL_TT_CT_KILL_MARGIN 3 - -enum iwl_antenna_ok { - IWL_ANT_OK_NONE, - IWL_ANT_OK_SINGLE, - IWL_ANT_OK_MULTI, -}; - -/* Thermal Throttling State Machine states */ -enum iwl_tt_state { - IWL_TI_0, /* normal temperature, system power state */ - IWL_TI_1, /* high temperature detect, low power state */ - IWL_TI_2, /* higher temperature detected, lower power state */ - IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */ - IWL_TI_STATE_MAX -}; - -/** - * struct iwl_tt_restriction - Thermal Throttling restriction table - * @tx_stream: number of tx stream allowed - * @is_ht: ht enable/disable - * @rx_stream: number of rx stream allowed - * - * This table is used by advance thermal throttling management - * based on the current thermal throttling state, and determines - * the number of tx/rx streams and the status of HT operation. - */ -struct iwl_tt_restriction { - enum iwl_antenna_ok tx_stream; - enum iwl_antenna_ok rx_stream; - bool is_ht; -}; - -/** - * struct iwl_tt_trans - Thermal Throttling transaction table - * @next_state: next thermal throttling mode - * @tt_low: low temperature threshold to change state - * @tt_high: high temperature threshold to change state - * - * This is used by the advanced thermal throttling algorithm - * to determine the next thermal state to go based on the - * current temperature. - */ -struct iwl_tt_trans { - enum iwl_tt_state next_state; - u32 tt_low; - u32 tt_high; -}; - -/** - * struct iwl_tt_mgnt - Thermal Throttling Management structure - * @advanced_tt: advanced thermal throttle required - * @state: current Thermal Throttling state - * @tt_power_mode: Thermal Throttling power mode index - * being used to set power level when - * when thermal throttling state != IWL_TI_0 - * the tt_power_mode should set to different - * power mode based on the current tt state - * @tt_previous_temperature: last measured temperature - * @iwl_tt_restriction: ptr to restriction tbl, used by advance - * thermal throttling to determine how many tx/rx streams - * should be used in tt state; and can HT be enabled or not - * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling - * state transaction - * @ct_kill_toggle: used to toggle the CSR bit when checking uCode temperature - * @ct_kill_exit_tm: timer to exit thermal kill - */ -struct iwl_tt_mgmt { - enum iwl_tt_state state; - bool advanced_tt; - u8 tt_power_mode; - bool ct_kill_toggle; -#ifdef CONFIG_IWLWIFI_DEBUG - s32 tt_previous_temp; -#endif - struct iwl_tt_restriction *restriction; - struct iwl_tt_trans *transaction; - struct timer_list ct_kill_exit_tm; - struct timer_list ct_kill_waiting_tm; -}; - enum iwl_power_level { IWL_POWER_INDEX_1, IWL_POWER_INDEX_2, @@ -130,15 +46,6 @@ struct iwl_power_mgr { }; int iwl_power_update_mode(struct iwl_priv *priv, bool force); -bool iwl_ht_enabled(struct iwl_priv *priv); -bool iwl_within_ct_kill_margin(struct iwl_priv *priv); -enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv); -enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv); -void iwl_tt_enter_ct_kill(struct iwl_priv *priv); -void iwl_tt_exit_ct_kill(struct iwl_priv *priv); -void iwl_tt_handler(struct iwl_priv *priv); -void iwl_tt_initialize(struct iwl_priv *priv); -void iwl_tt_exit(struct iwl_priv *priv); void iwl_power_initialize(struct iwl_priv *priv); extern bool no_sleep_autoadjust; diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index b1f101caf19d2f063386453c7cd1f8e045e7b10d..5469655646aebaa72cf673a942e4f127bd3fa5e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -306,7 +306,7 @@ * at a time, until receiving ACK from receiving station, or reaching * retry limit and giving up. * - * The command queue (#4) must use this mode! + * The command queue (#4/#9) must use this mode! * This mode does not require use of the Byte Count table in host DRAM. * * Driver controls scheduler operation via 3 means: @@ -322,7 +322,7 @@ * (1024 bytes for each queue). * * After receiving "Alive" response from uCode, driver must initialize - * the scheduler (especially for queue #4, the command queue, otherwise + * the scheduler (especially for queue #4/#9, the command queue, otherwise * the driver can't issue commands!): */ @@ -555,8 +555,9 @@ #define IWLAGN_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \ ((IWLAGN_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffc) -#define IWLAGN_SCD_QUEUECHAIN_SEL_ALL(x) (((1<<(x)) - 1) &\ - (~(1<hw_params.max_txq_num) - 1) &\ + (~(1<<(priv)->cmd_queue))) #define IWLAGN_SCD_BASE (PRPH_BASE + 0xa02c00) diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 79773e353baaa56478a6d173fdc5f0f70cf837fa..f436270ca39af6adb3290a137cd68a84138d4835 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -36,7 +36,6 @@ #include "iwl-core.h" #include "iwl-sta.h" #include "iwl-io.h" -#include "iwl-calib.h" #include "iwl-helpers.h" /************************** RX-FUNCTIONS ****************************/ /* @@ -228,7 +227,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv, { if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; - if (iwl_is_associated(priv)) { + if (iwl_is_any_associated(priv)) { if (priv->cfg->ops->lib->check_ack_health) { if (!priv->cfg->ops->lib->check_ack_health( priv, pkt)) { @@ -266,7 +265,12 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, { u16 fc = le16_to_cpu(hdr->frame_control); - if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) + /* + * All contexts have the same setting here due to it being + * a module parameter, so OK to check any context. + */ + if (priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags & + RXON_FILTER_DIS_DECRYPT_MSK) return 0; if (!(fc & IEEE80211_FCTL_PROTECTED)) diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a4b3663a262fb40857c521126d8d1df73f8f72be..67da31295781192a6e8446e46634772426735949 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -54,100 +54,133 @@ #define IWL_PASSIVE_DWELL_BASE (100) #define IWL_CHANNEL_TUNE_TIME 5 +static int iwl_send_scan_abort(struct iwl_priv *priv) +{ + int ret; + struct iwl_rx_packet *pkt; + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_ABORT_CMD, + .flags = CMD_WANT_SKB, + }; + /* Exit instantly with error when device is not ready + * to receive scan abort command or it does not perform + * hardware scan currently */ + if (!test_bit(STATUS_READY, &priv->status) || + !test_bit(STATUS_GEO_CONFIGURED, &priv->status) || + !test_bit(STATUS_SCAN_HW, &priv->status) || + test_bit(STATUS_FW_ERROR, &priv->status) || + test_bit(STATUS_EXIT_PENDING, &priv->status)) + return -EIO; -/** - * iwl_scan_cancel - Cancel any currently executing HW scan - * - * NOTE: priv->mutex is not required before calling this function - */ -int iwl_scan_cancel(struct iwl_priv *priv) + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) + return ret; + + pkt = (struct iwl_rx_packet *)cmd.reply_page; + if (pkt->u.status != CAN_ABORT_STATUS) { + /* The scan abort will return 1 for success or + * 2 for "failure". A failure condition can be + * due to simply not being in an active scan which + * can occur if we send the scan abort before we + * the microcode has notified us that a scan is + * completed. */ + IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status); + ret = -EIO; + } + + iwl_free_pages(priv, cmd.reply_page); + return ret; +} + +static void iwl_complete_scan(struct iwl_priv *priv, bool aborted) { - if (!test_bit(STATUS_SCAN_HW, &priv->status)) { - clear_bit(STATUS_SCANNING, &priv->status); - return 0; + /* check if scan was requested from mac80211 */ + if (priv->scan_request) { + IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n"); + ieee80211_scan_completed(priv->hw, aborted); } - if (test_bit(STATUS_SCANNING, &priv->status)) { - if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n"); - queue_work(priv->workqueue, &priv->abort_scan); + priv->is_internal_short_scan = false; + priv->scan_vif = NULL; + priv->scan_request = NULL; +} - } else - IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n"); +void iwl_force_scan_end(struct iwl_priv *priv) +{ + lockdep_assert_held(&priv->mutex); - return test_bit(STATUS_SCANNING, &priv->status); + if (!test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n"); + return; } + IWL_DEBUG_SCAN(priv, "Forcing scan end\n"); + clear_bit(STATUS_SCANNING, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + iwl_complete_scan(priv, true); +} + +static void iwl_do_scan_abort(struct iwl_priv *priv) +{ + int ret; + + lockdep_assert_held(&priv->mutex); + + if (!test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n"); + return; + } + + if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan abort in progress\n"); + return; + } + + ret = iwl_send_scan_abort(priv); + if (ret) { + IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret); + iwl_force_scan_end(priv); + } else + IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n"); +} + +/** + * iwl_scan_cancel - Cancel any currently executing HW scan + */ +int iwl_scan_cancel(struct iwl_priv *priv) +{ + IWL_DEBUG_SCAN(priv, "Queuing abort scan\n"); + queue_work(priv->workqueue, &priv->abort_scan); return 0; } EXPORT_SYMBOL(iwl_scan_cancel); + /** * iwl_scan_cancel_timeout - Cancel any currently executing HW scan * @ms: amount of time to wait (in milliseconds) for scan to abort * - * NOTE: priv->mutex must be held before calling this function */ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) { - unsigned long now = jiffies; - int ret; - - ret = iwl_scan_cancel(priv); - if (ret && ms) { - mutex_unlock(&priv->mutex); - while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && - test_bit(STATUS_SCANNING, &priv->status)) - msleep(1); - mutex_lock(&priv->mutex); - - return test_bit(STATUS_SCANNING, &priv->status); - } + unsigned long timeout = jiffies + msecs_to_jiffies(ms); - return ret; -} -EXPORT_SYMBOL(iwl_scan_cancel_timeout); + lockdep_assert_held(&priv->mutex); -static int iwl_send_scan_abort(struct iwl_priv *priv) -{ - int ret = 0; - struct iwl_rx_packet *pkt; - struct iwl_host_cmd cmd = { - .id = REPLY_SCAN_ABORT_CMD, - .flags = CMD_WANT_SKB, - }; + IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n"); - /* If there isn't a scan actively going on in the hardware - * then we are in between scan bands and not actually - * actively scanning, so don't send the abort command */ - if (!test_bit(STATUS_SCAN_HW, &priv->status)) { - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - return 0; - } + iwl_do_scan_abort(priv); - ret = iwl_send_cmd_sync(priv, &cmd); - if (ret) { - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - return ret; - } - - pkt = (struct iwl_rx_packet *)cmd.reply_page; - if (pkt->u.status != CAN_ABORT_STATUS) { - /* The scan abort will return 1 for success or - * 2 for "failure". A failure condition can be - * due to simply not being in an active scan which - * can occur if we send the scan abort before we - * the microcode has notified us that a scan is - * completed. */ - IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status); - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - clear_bit(STATUS_SCAN_HW, &priv->status); + while (time_before_eq(jiffies, timeout)) { + if (!test_bit(STATUS_SCAN_HW, &priv->status)) + break; + msleep(20); } - iwl_free_pages(priv, cmd.reply_page); - - return ret; + return test_bit(STATUS_SCAN_HW, &priv->status); } +EXPORT_SYMBOL(iwl_scan_cancel_timeout); /* Service response to REPLY_SCAN_CMD (0x80) */ static void iwl_rx_reply_scan(struct iwl_priv *priv, @@ -158,7 +191,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv, struct iwl_scanreq_notification *notif = (struct iwl_scanreq_notification *)pkt->u.raw; - IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status); + IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status); #endif } @@ -206,7 +239,6 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv, static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; @@ -214,29 +246,38 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, scan_notif->scanned_channels, scan_notif->tsf_low, scan_notif->tsf_high, scan_notif->status); -#endif /* The HW is no longer scanning */ clear_bit(STATUS_SCAN_HW, &priv->status); - IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n", + IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n", (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2", jiffies_to_msecs(elapsed_jiffies (priv->scan_start, jiffies))); - /* - * If a request to abort was given, or the scan did not succeed - * then we reset the scan state machine and terminate, - * re-queuing another scan if one has been requested - */ - if (test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status)) - IWL_DEBUG_INFO(priv, "Aborted scan completed.\n"); - - IWL_DEBUG_INFO(priv, "Setting scan to off\n"); - - clear_bit(STATUS_SCANNING, &priv->status); - queue_work(priv->workqueue, &priv->scan_completed); + + if (priv->iw_mode != NL80211_IFTYPE_ADHOC && + priv->cfg->bt_params && + priv->cfg->bt_params->advanced_bt_coexist && + priv->bt_status != scan_notif->bt_status) { + if (scan_notif->bt_status) { + /* BT on */ + if (!priv->bt_ch_announce) + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_HIGH; + /* + * otherwise, no traffic load information provided + * no changes made + */ + } else { + /* BT off */ + priv->bt_traffic_load = + IWL_BT_COEX_TRAFFIC_LOAD_NONE; + } + priv->bt_status = scan_notif->bt_status; + queue_work(priv->workqueue, &priv->bt_traffic_change_work); + } } void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) @@ -268,18 +309,28 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, enum ieee80211_band band, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx; u16 passive = (band == IEEE80211_BAND_2GHZ) ? IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; - if (iwl_is_associated(priv)) { - /* If we're associated, we clamp the maximum passive - * dwell time to be 98% of the beacon interval (minus - * 2 * channel tune time) */ - passive = vif ? vif->bss_conf.beacon_int : 0; - if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) - passive = IWL_PASSIVE_DWELL_BASE; - passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + if (iwl_is_any_associated(priv)) { + /* + * If we're associated, we clamp the maximum passive + * dwell time to be 98% of the smallest beacon interval + * (minus 2 * channel tune time) + */ + for_each_context(priv, ctx) { + u16 value; + + if (!iwl_is_associated_ctx(ctx)) + continue; + value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0; + if ((value > IWL_PASSIVE_DWELL_BASE) || !value) + value = IWL_PASSIVE_DWELL_BASE; + value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + passive = min(value, passive); + } } return passive; @@ -296,19 +347,53 @@ void iwl_init_scan_params(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_init_scan_params); -static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif) +static int __must_check iwl_scan_initiate(struct iwl_priv *priv, + struct ieee80211_vif *vif, + bool internal, + enum ieee80211_band band) { + int ret; + lockdep_assert_held(&priv->mutex); - IWL_DEBUG_INFO(priv, "Starting scan...\n"); + if (WARN_ON(!priv->cfg->ops->utils->request_scan)) + return -EOPNOTSUPP; + + cancel_delayed_work(&priv->scan_check); + + if (!iwl_is_ready_rf(priv)) { + IWL_WARN(priv, "Request scan called when driver not ready.\n"); + return -EIO; + } + + if (test_bit(STATUS_SCAN_HW, &priv->status)) { + IWL_DEBUG_SCAN(priv, + "Multiple concurrent scan requests in parallel.\n"); + return -EBUSY; + } + + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n"); + return -EBUSY; + } + + IWL_DEBUG_SCAN(priv, "Starting %sscan...\n", + internal ? "internal short " : ""); + set_bit(STATUS_SCANNING, &priv->status); - priv->is_internal_short_scan = false; + priv->is_internal_short_scan = internal; priv->scan_start = jiffies; + priv->scan_band = band; - if (WARN_ON(!priv->cfg->ops->utils->request_scan)) - return -EOPNOTSUPP; + ret = priv->cfg->ops->utils->request_scan(priv, vif); + if (ret) { + clear_bit(STATUS_SCANNING, &priv->status); + priv->is_internal_short_scan = false; + return ret; + } - priv->cfg->ops->utils->request_scan(priv, vif); + queue_delayed_work(priv->workqueue, &priv->scan_check, + IWL_SCAN_CHECK_WATCHDOG); return 0; } @@ -327,12 +412,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - if (!iwl_is_ready_rf(priv)) { - ret = -EIO; - IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n"); - goto out_unlock; - } - if (test_bit(STATUS_SCANNING, &priv->status) && !priv->is_internal_short_scan) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); @@ -340,14 +419,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, goto out_unlock; } - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); - ret = -EAGAIN; - goto out_unlock; - } - /* mac80211 will only ask for one band at a time */ - priv->scan_band = req->channels[0]->band; priv->scan_request = req; priv->scan_vif = vif; @@ -355,10 +427,12 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw, * If an internal scan is in progress, just set * up the scan_request as per above. */ - if (priv->is_internal_short_scan) + if (priv->is_internal_short_scan) { + IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n"); ret = 0; - else - ret = iwl_scan_initiate(priv, vif); + } else + ret = iwl_scan_initiate(priv, vif, false, + req->channels[0]->band); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -378,11 +452,13 @@ void iwl_internal_short_hw_scan(struct iwl_priv *priv) queue_work(priv->workqueue, &priv->start_internal_scan); } -void iwl_bg_start_internal_scan(struct work_struct *work) +static void iwl_bg_start_internal_scan(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, start_internal_scan); + IWL_DEBUG_SCAN(priv, "Start internal scan\n"); + mutex_lock(&priv->mutex); if (priv->is_internal_short_scan == true) { @@ -390,56 +466,31 @@ void iwl_bg_start_internal_scan(struct work_struct *work) goto unlock; } - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_SCAN(priv, "not ready or exit pending\n"); - goto unlock; - } - if (test_bit(STATUS_SCANNING, &priv->status)) { IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); goto unlock; } - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); - goto unlock; - } - - priv->scan_band = priv->band; - - IWL_DEBUG_SCAN(priv, "Start internal short scan...\n"); - set_bit(STATUS_SCANNING, &priv->status); - priv->is_internal_short_scan = true; - - if (WARN_ON(!priv->cfg->ops->utils->request_scan)) - goto unlock; - - priv->cfg->ops->utils->request_scan(priv, NULL); + if (iwl_scan_initiate(priv, NULL, true, priv->band)) + IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n"); unlock: mutex_unlock(&priv->mutex); } -EXPORT_SYMBOL(iwl_bg_start_internal_scan); -void iwl_bg_scan_check(struct work_struct *data) +static void iwl_bg_scan_check(struct work_struct *data) { struct iwl_priv *priv = container_of(data, struct iwl_priv, scan_check.work); - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; + IWL_DEBUG_SCAN(priv, "Scan check work\n"); + /* Since we are here firmware does not finish scan and + * most likely is in bad shape, so we don't bother to + * send abort command, just force scan complete to mac80211 */ mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCANNING, &priv->status) && - !test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n", - jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); - - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - iwl_send_scan_abort(priv); - } + iwl_force_scan_end(priv); mutex_unlock(&priv->mutex); } -EXPORT_SYMBOL(iwl_bg_scan_check); /** * iwl_fill_probe_req - fill in all required fields and IE for probe request @@ -489,73 +540,78 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame, } EXPORT_SYMBOL(iwl_fill_probe_req); -void iwl_bg_abort_scan(struct work_struct *work) +static void iwl_bg_abort_scan(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); - if (!test_bit(STATUS_READY, &priv->status) || - !test_bit(STATUS_GEO_CONFIGURED, &priv->status)) - return; - - cancel_delayed_work(&priv->scan_check); + IWL_DEBUG_SCAN(priv, "Abort scan work\n"); + /* We keep scan_check work queued in case when firmware will not + * report back scan completed notification */ mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) - iwl_send_scan_abort(priv); + iwl_scan_cancel_timeout(priv, 200); mutex_unlock(&priv->mutex); } -EXPORT_SYMBOL(iwl_bg_abort_scan); -void iwl_bg_scan_completed(struct work_struct *work) +static void iwl_bg_scan_completed(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); - bool internal = false; + bool aborted; - IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); + IWL_DEBUG_SCAN(priv, "Completed %sscan.\n", + priv->is_internal_short_scan ? "internal short " : ""); cancel_delayed_work(&priv->scan_check); mutex_lock(&priv->mutex); - if (priv->is_internal_short_scan) { - priv->is_internal_short_scan = false; - IWL_DEBUG_SCAN(priv, "internal short scan completed\n"); - internal = true; - } else { - priv->scan_request = NULL; - priv->scan_vif = NULL; + + aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status); + if (aborted) + IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n"); + + if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN(priv, "Scan already completed.\n"); + goto out_settings; } - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + if (priv->is_internal_short_scan && !aborted) { + int err; + + /* Check if mac80211 requested scan during our internal scan */ + if (priv->scan_request == NULL) + goto out_complete; + + /* If so request a new scan */ + err = iwl_scan_initiate(priv, priv->scan_vif, false, + priv->scan_request->channels[0]->band); + if (err) { + IWL_DEBUG_SCAN(priv, + "failed to initiate pending scan: %d\n", err); + aborted = true; + goto out_complete; + } + goto out; + } + +out_complete: + iwl_complete_scan(priv, aborted); - if (internal && priv->scan_request) - iwl_scan_initiate(priv, priv->scan_vif); +out_settings: + /* Can we still talk to firmware ? */ + if (!iwl_is_ready_rf(priv)) + goto out; /* Since setting the TXPOWER may have been deferred while * performing the scan, fire one off */ iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); - /* - * Since setting the RXON may have been deferred while - * performing the scan, fire one off if needed - */ - if (memcmp(&priv->active_rxon, - &priv->staging_rxon, sizeof(priv->staging_rxon))) - iwlcore_commit_rxon(priv); + priv->cfg->ops->utils->post_scan(priv); out: mutex_unlock(&priv->mutex); - - /* - * Do not hold mutex here since this will cause mac80211 to call - * into driver again into functions that will attempt to take - * mutex. - */ - if (!internal) - ieee80211_scan_completed(priv->hw, false); } -EXPORT_SYMBOL(iwl_bg_scan_completed); void iwl_setup_scan_deferred_work(struct iwl_priv *priv) { @@ -566,3 +622,16 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_setup_scan_deferred_work); +void iwl_cancel_scan_deferred_work(struct iwl_priv *priv) +{ + cancel_work_sync(&priv->start_internal_scan); + cancel_work_sync(&priv->abort_scan); + cancel_work_sync(&priv->scan_completed); + + if (cancel_delayed_work_sync(&priv->scan_check)) { + mutex_lock(&priv->mutex); + iwl_force_scan_end(priv); + mutex_unlock(&priv->mutex); + } +} +EXPORT_SYMBOL(iwl_cancel_scan_deferred_work); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 7e0829be5e783a0e49957a89414d61a413a79407..7c7f7dcb1b1e190611a8134177966729cf04d60e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -172,12 +172,14 @@ int iwl_send_add_sta(struct iwl_priv *priv, EXPORT_SYMBOL(iwl_send_add_sta); static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, - struct ieee80211_sta_ht_cap *sta_ht_inf) + struct ieee80211_sta *sta, + struct iwl_rxon_context *ctx) { + struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap; __le32 sta_flags; u8 mimo_ps_mode; - if (!sta_ht_inf || !sta_ht_inf->ht_supported) + if (!sta || !sta_ht_inf->ht_supported) goto done; mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2; @@ -211,7 +213,7 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, sta_flags |= cpu_to_le32( (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS); - if (iwl_is_ht40_tx_allowed(priv, sta_ht_inf)) + if (iwl_is_ht40_tx_allowed(priv, ctx, &sta->ht_cap)) sta_flags |= STA_FLG_HT40_EN_MSK; else sta_flags &= ~STA_FLG_HT40_EN_MSK; @@ -226,9 +228,8 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, * * should be called with sta_lock held */ -static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr, - bool is_ap, - struct ieee80211_sta_ht_cap *ht_info) +u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, struct ieee80211_sta *sta) { struct iwl_station_entry *station; int i; @@ -236,9 +237,9 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr, u16 rate; if (is_ap) - sta_id = IWL_AP_ID; + sta_id = ctx->ap_sta_id; else if (is_broadcast_ether_addr(addr)) - sta_id = priv->hw_params.bcast_sta_id; + sta_id = ctx->bcast_sta_id; else for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { if (!compare_ether_addr(priv->stations[i].sta.sta.addr, @@ -289,14 +290,22 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr, memcpy(station->sta.sta.addr, addr, ETH_ALEN); station->sta.mode = 0; station->sta.sta.sta_id = sta_id; - station->sta.station_flags = 0; + station->sta.station_flags = ctx->station_flags; + station->ctxid = ctx->ctxid; + + if (sta) { + struct iwl_station_priv_common *sta_priv; + + sta_priv = (void *)sta->drv_priv; + sta_priv->ctx = ctx; + } /* * OK to call unconditionally, since local stations (IBSS BSSID - * STA and broadcast STA) pass in a NULL ht_info, and mac80211 + * STA and broadcast STA) pass in a NULL sta, and mac80211 * doesn't allow HT IBSS. */ - iwl_set_ht_add_station(priv, sta_id, ht_info); + iwl_set_ht_add_station(priv, sta_id, sta, ctx); /* 3945 only */ rate = (priv->band == IEEE80211_BAND_5GHZ) ? @@ -307,16 +316,16 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr, return sta_id; } +EXPORT_SYMBOL_GPL(iwl_prep_station); #define STA_WAIT_TIMEOUT (HZ/2) /** * iwl_add_station_common - */ -int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, - bool is_ap, - struct ieee80211_sta_ht_cap *ht_info, - u8 *sta_id_r) +int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, + struct ieee80211_sta *sta, u8 *sta_id_r) { unsigned long flags_spin; int ret = 0; @@ -325,7 +334,7 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, *sta_id_r = 0; spin_lock_irqsave(&priv->sta_lock, flags_spin); - sta_id = iwl_prep_station(priv, addr, is_ap, ht_info); + sta_id = iwl_prep_station(priv, ctx, addr, is_ap, sta); if (sta_id == IWL_INVALID_STATION) { IWL_ERR(priv, "Unable to prepare station %pM for addition\n", addr); @@ -372,111 +381,6 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, } EXPORT_SYMBOL(iwl_add_station_common); -static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv, - u8 sta_id) -{ - int i, r; - struct iwl_link_quality_cmd *link_cmd; - u32 rate_flags; - - link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); - if (!link_cmd) { - IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); - return NULL; - } - /* Set up the rate scaling to start at selected rate, fall back - * all the way down to 1M in IEEE order, and then spin on 1M */ - if (priv->band == IEEE80211_BAND_5GHZ) - r = IWL_RATE_6M_INDEX; - else - r = IWL_RATE_1M_INDEX; - - for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { - rate_flags = 0; - if (r >= IWL_FIRST_CCK_RATE && r <= IWL_LAST_CCK_RATE) - rate_flags |= RATE_MCS_CCK_MSK; - - rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) << - RATE_MCS_ANT_POS; - - link_cmd->rs_table[i].rate_n_flags = - iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); - r = iwl_get_prev_ieee_rate(r); - } - - link_cmd->general_params.single_stream_ant_msk = - first_antenna(priv->hw_params.valid_tx_ant); - - link_cmd->general_params.dual_stream_ant_msk = - priv->hw_params.valid_tx_ant & - ~first_antenna(priv->hw_params.valid_tx_ant); - if (!link_cmd->general_params.dual_stream_ant_msk) { - link_cmd->general_params.dual_stream_ant_msk = ANT_AB; - } else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) { - link_cmd->general_params.dual_stream_ant_msk = - priv->hw_params.valid_tx_ant; - } - - link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; - link_cmd->agg_params.agg_time_limit = - cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); - - link_cmd->sta_id = sta_id; - - return link_cmd; -} - -/* - * iwl_add_bssid_station - Add the special IBSS BSSID station - * - * Function sleeps. - */ -int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs, - u8 *sta_id_r) -{ - int ret; - u8 sta_id; - struct iwl_link_quality_cmd *link_cmd; - unsigned long flags; - - if (sta_id_r) - *sta_id_r = IWL_INVALID_STATION; - - ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id); - if (ret) { - IWL_ERR(priv, "Unable to add station %pM\n", addr); - return ret; - } - - if (sta_id_r) - *sta_id_r = sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].used |= IWL_STA_LOCAL; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - if (init_rs) { - /* Set up default rate scaling table in device's station table */ - link_cmd = iwl_sta_alloc_lq(priv, sta_id); - if (!link_cmd) { - IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n", - addr); - return -ENOMEM; - } - - ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true); - if (ret) - IWL_ERR(priv, "Link quality command failed (%d)\n", ret); - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->sta_lock, flags); - } - - return 0; -} -EXPORT_SYMBOL(iwl_add_bssid_station); - /** * iwl_sta_ucode_deactivate - deactivate ucode status for a station * @@ -616,7 +520,8 @@ EXPORT_SYMBOL_GPL(iwl_remove_station); * other than explicit station management would cause this in * the ucode, e.g. unassociated RXON. */ -void iwl_clear_ucode_stations(struct iwl_priv *priv) +void iwl_clear_ucode_stations(struct iwl_priv *priv, + struct iwl_rxon_context *ctx) { int i; unsigned long flags_spin; @@ -626,6 +531,9 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv) spin_lock_irqsave(&priv->sta_lock, flags_spin); for (i = 0; i < priv->hw_params.max_stations; i++) { + if (ctx && ctx->ctxid != priv->stations[i].ctxid) + continue; + if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) { IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i); priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; @@ -647,7 +555,7 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations); * * Function sleeps. */ -void iwl_restore_stations(struct iwl_priv *priv) +void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx) { struct iwl_addsta_cmd sta_cmd; struct iwl_link_quality_cmd lq; @@ -665,6 +573,8 @@ void iwl_restore_stations(struct iwl_priv *priv) IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n"); spin_lock_irqsave(&priv->sta_lock, flags_spin); for (i = 0; i < priv->hw_params.max_stations; i++) { + if (ctx->ctxid != priv->stations[i].ctxid) + continue; if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) && !(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) { IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n", @@ -700,7 +610,7 @@ void iwl_restore_stations(struct iwl_priv *priv) * current LQ command */ if (send_lq) - iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true); + iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true); spin_lock_irqsave(&priv->sta_lock, flags_spin); priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; } @@ -718,7 +628,7 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { int i; - for (i = 0; i < STA_KEY_MAX_NUM; i++) + for (i = 0; i < priv->sta_key_max_num; i++) if (!test_and_set_bit(i, &priv->ucode_key_table)) return i; @@ -726,393 +636,25 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_get_free_ucode_key_index); -static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty) -{ - int i, not_empty = 0; - u8 buff[sizeof(struct iwl_wep_cmd) + - sizeof(struct iwl_wep_key) * WEP_KEYS_MAX]; - struct iwl_wep_cmd *wep_cmd = (struct iwl_wep_cmd *)buff; - size_t cmd_size = sizeof(struct iwl_wep_cmd); - struct iwl_host_cmd cmd = { - .id = REPLY_WEPKEY, - .data = wep_cmd, - .flags = CMD_SYNC, - }; - - might_sleep(); - - memset(wep_cmd, 0, cmd_size + - (sizeof(struct iwl_wep_key) * WEP_KEYS_MAX)); - - for (i = 0; i < WEP_KEYS_MAX ; i++) { - wep_cmd->key[i].key_index = i; - if (priv->wep_keys[i].key_size) { - wep_cmd->key[i].key_offset = i; - not_empty = 1; - } else { - wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET; - } - - wep_cmd->key[i].key_size = priv->wep_keys[i].key_size; - memcpy(&wep_cmd->key[i].key[3], priv->wep_keys[i].key, - priv->wep_keys[i].key_size); - } - - wep_cmd->global_key_type = WEP_KEY_WEP_TYPE; - wep_cmd->num_keys = WEP_KEYS_MAX; - - cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX; - - cmd.len = cmd_size; - - if (not_empty || send_if_empty) - return iwl_send_cmd(priv, &cmd); - else - return 0; -} - -int iwl_restore_default_wep_keys(struct iwl_priv *priv) -{ - lockdep_assert_held(&priv->mutex); - - return iwl_send_static_wepkey_cmd(priv, 0); -} -EXPORT_SYMBOL(iwl_restore_default_wep_keys); - -int iwl_remove_default_wep_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf) -{ - int ret; - - lockdep_assert_held(&priv->mutex); - - IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n", - keyconf->keyidx); - - memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n"); - /* but keys in device are clear anyway so return success */ - return 0; - } - ret = iwl_send_static_wepkey_cmd(priv, 1); - IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", - keyconf->keyidx, ret); - - return ret; -} -EXPORT_SYMBOL(iwl_remove_default_wep_key); - -int iwl_set_default_wep_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf) +void iwl_dealloc_bcast_stations(struct iwl_priv *priv) { - int ret; - - lockdep_assert_held(&priv->mutex); - - if (keyconf->keylen != WEP_KEY_LEN_128 && - keyconf->keylen != WEP_KEY_LEN_64) { - IWL_DEBUG_WEP(priv, "Bad WEP key length %d\n", keyconf->keylen); - return -EINVAL; - } - - keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; - keyconf->hw_key_idx = HW_KEY_DEFAULT; - priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; - - priv->wep_keys[keyconf->keyidx].key_size = keyconf->keylen; - memcpy(&priv->wep_keys[keyconf->keyidx].key, &keyconf->key, - keyconf->keylen); - - ret = iwl_send_static_wepkey_cmd(priv, 0); - IWL_DEBUG_WEP(priv, "Set default WEP key: len=%d idx=%d ret=%d\n", - keyconf->keylen, keyconf->keyidx, ret); - - return ret; -} -EXPORT_SYMBOL(iwl_set_default_wep_key); - -static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - __le16 key_flags = 0; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; - - key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - key_flags &= ~STA_KEY_FLG_INVALID; - - if (keyconf->keylen == WEP_KEY_LEN_128) - key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; - - if (sta_id == priv->hw_params.bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - spin_lock_irqsave(&priv->sta_lock, flags); - - priv->stations[sta_id].keyinfo.alg = keyconf->alg; - priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; - priv->stations[sta_id].keyinfo.keyidx = keyconf->keyidx; - - memcpy(priv->stations[sta_id].keyinfo.key, - keyconf->key, keyconf->keylen); - - memcpy(&priv->stations[sta_id].sta.key.key[3], - keyconf->key, keyconf->keylen); - - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) - == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - /* else, we are overriding an existing key => no need to allocated room - * in uCode. */ - - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, - "no space for a new key"); - - priv->stations[sta_id].sta.key.key_flags = key_flags; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} - -static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - __le16 key_flags = 0; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - key_flags &= ~STA_KEY_FLG_INVALID; - - if (sta_id == priv->hw_params.bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.alg = keyconf->alg; - priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; - - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, - keyconf->keylen); - - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, - keyconf->keylen); - - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) - == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - /* else, we are overriding an existing key => no need to allocated room - * in uCode. */ - - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, - "no space for a new key"); - - priv->stations[sta_id].sta.key.key_flags = key_flags; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} - -static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - int ret = 0; - __le16 key_flags = 0; - - key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); - key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - key_flags &= ~STA_KEY_FLG_INVALID; - - if (sta_id == priv->hw_params.bcast_sta_id) - key_flags |= STA_KEY_MULTICAST_MSK; - - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; - keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; - - spin_lock_irqsave(&priv->sta_lock, flags); - - priv->stations[sta_id].keyinfo.alg = keyconf->alg; - priv->stations[sta_id].keyinfo.keylen = 16; - - if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK) - == STA_KEY_FLG_NO_ENC) - priv->stations[sta_id].sta.key.key_offset = - iwl_get_free_ucode_key_index(priv); - /* else, we are overriding an existing key => no need to allocated room - * in uCode. */ - - WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET, - "no space for a new key"); - - priv->stations[sta_id].sta.key.key_flags = key_flags; - - - /* This copy is acutally not needed: we get the key with each TX */ - memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, 16); - - memcpy(priv->stations[sta_id].sta.key.key, keyconf->key, 16); - - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return ret; -} - -void iwl_update_tkip_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) -{ - u8 sta_id; unsigned long flags; int i; - if (iwl_scan_cancel(priv)) { - /* cancel scan failed, just live w/ bad key and rely - briefly on SW decryption */ - return; - } - - sta_id = iwl_sta_id_or_broadcast(priv, sta); - if (sta_id == IWL_INVALID_STATION) - return; - spin_lock_irqsave(&priv->sta_lock, flags); + for (i = 0; i < priv->hw_params.max_stations; i++) { + if (!(priv->stations[i].used & IWL_STA_BCAST)) + continue; - priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; - - for (i = 0; i < 5; i++) - priv->stations[sta_id].sta.key.tkip_rx_ttak[i] = - cpu_to_le16(phase1key[i]); - - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - - spin_unlock_irqrestore(&priv->sta_lock, flags); - -} -EXPORT_SYMBOL(iwl_update_tkip_key); - -int iwl_remove_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - u8 sta_id) -{ - unsigned long flags; - u16 key_flags; - u8 keyidx; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - priv->key_mapping_key--; - - spin_lock_irqsave(&priv->sta_lock, flags); - key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); - keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; - - IWL_DEBUG_WEP(priv, "Remove dynamic key: idx=%d sta=%d\n", - keyconf->keyidx, sta_id); - - if (keyconf->keyidx != keyidx) { - /* We need to remove a key with index different that the one - * in the uCode. This means that the key we need to remove has - * been replaced by another one with different index. - * Don't do anything and return ok - */ - spin_unlock_irqrestore(&priv->sta_lock, flags); - return 0; - } - - if (priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { - IWL_WARN(priv, "Removing wrong key %d 0x%x\n", - keyconf->keyidx, key_flags); - spin_unlock_irqrestore(&priv->sta_lock, flags); - return 0; - } - - if (!test_and_clear_bit(priv->stations[sta_id].sta.key.key_offset, - &priv->ucode_key_table)) - IWL_ERR(priv, "index %d not used in uCode key table.\n", - priv->stations[sta_id].sta.key.key_offset); - memset(&priv->stations[sta_id].keyinfo, 0, - sizeof(struct iwl_hw_key)); - memset(&priv->stations[sta_id].sta.key, 0, - sizeof(struct iwl4965_keyinfo)); - priv->stations[sta_id].sta.key.key_flags = - STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; - priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled.\n"); - spin_unlock_irqrestore(&priv->sta_lock, flags); - return 0; + priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; + priv->num_stations--; + BUG_ON(priv->num_stations < 0); + kfree(priv->stations[i].lq); + priv->stations[i].lq = NULL; } - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} -EXPORT_SYMBOL(iwl_remove_dynamic_key); - -int iwl_set_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, u8 sta_id) -{ - int ret; - - lockdep_assert_held(&priv->mutex); - - priv->key_mapping_key++; - keyconf->hw_key_idx = HW_KEY_DYNAMIC; - - switch (keyconf->alg) { - case ALG_CCMP: - ret = iwl_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); - break; - case ALG_TKIP: - ret = iwl_set_tkip_dynamic_key_info(priv, keyconf, sta_id); - break; - case ALG_WEP: - ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id); - break; - default: - IWL_ERR(priv, - "Unknown alg: %s alg = %d\n", __func__, keyconf->alg); - ret = -EINVAL; - } - - IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n", - keyconf->alg, keyconf->keylen, keyconf->keyidx, - sta_id, ret); - - return ret; } -EXPORT_SYMBOL(iwl_set_dynamic_key); +EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations); #ifdef CONFIG_IWLWIFI_DEBUG static void iwl_dump_lq_cmd(struct iwl_priv *priv, @@ -1147,16 +689,16 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv, * RXON flags are updated and when LQ command is updated. */ static bool is_lq_table_valid(struct iwl_priv *priv, + struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq) { int i; - struct iwl_ht_config *ht_conf = &priv->current_ht_config; - if (ht_conf->is_ht) + if (ctx->ht.enabled) return true; IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n", - priv->active_rxon.channel); + ctx->active.channel); for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) { IWL_DEBUG_INFO(priv, @@ -1178,7 +720,7 @@ static bool is_lq_table_valid(struct iwl_priv *priv, * this case to clear the state indicating that station creation is in * progress. */ -int iwl_send_lq_cmd(struct iwl_priv *priv, +int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, struct iwl_link_quality_cmd *lq, u8 flags, bool init) { int ret = 0; @@ -1197,7 +739,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, iwl_dump_lq_cmd(priv, lq); BUG_ON(init && (cmd.flags & CMD_ASYNC)); - if (is_lq_table_valid(priv, lq)) + if (is_lq_table_valid(priv, ctx, lq)) ret = iwl_send_cmd(priv, &cmd); else ret = -EINVAL; @@ -1216,207 +758,6 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_send_lq_cmd); -/** - * iwl_alloc_bcast_station - add broadcast station into driver's station table. - * - * This adds the broadcast station into the driver's station table - * and marks it driver active, so that it will be restored to the - * device at the next best time. - */ -int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq) -{ - struct iwl_link_quality_cmd *link_cmd; - unsigned long flags; - u8 sta_id; - - spin_lock_irqsave(&priv->sta_lock, flags); - sta_id = iwl_prep_station(priv, iwl_bcast_addr, false, NULL); - if (sta_id == IWL_INVALID_STATION) { - IWL_ERR(priv, "Unable to prepare broadcast station\n"); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return -EINVAL; - } - - priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; - priv->stations[sta_id].used |= IWL_STA_BCAST; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - if (init_lq) { - link_cmd = iwl_sta_alloc_lq(priv, sta_id); - if (!link_cmd) { - IWL_ERR(priv, - "Unable to initialize rate scaling for bcast station.\n"); - return -ENOMEM; - } - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->sta_lock, flags); - } - - return 0; -} -EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station); - -/** - * iwl_update_bcast_station - update broadcast station's LQ command - * - * Only used by iwlagn. Placed here to have all bcast station management - * code together. - */ -int iwl_update_bcast_station(struct iwl_priv *priv) -{ - unsigned long flags; - struct iwl_link_quality_cmd *link_cmd; - u8 sta_id = priv->hw_params.bcast_sta_id; - - link_cmd = iwl_sta_alloc_lq(priv, sta_id); - if (!link_cmd) { - IWL_ERR(priv, "Unable to initialize rate scaling for bcast station.\n"); - return -ENOMEM; - } - - spin_lock_irqsave(&priv->sta_lock, flags); - if (priv->stations[sta_id].lq) - kfree(priv->stations[sta_id].lq); - else - IWL_DEBUG_INFO(priv, "Bcast station rate scaling has not been initialized yet.\n"); - priv->stations[sta_id].lq = link_cmd; - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return 0; -} -EXPORT_SYMBOL_GPL(iwl_update_bcast_station); - -void iwl_dealloc_bcast_station(struct iwl_priv *priv) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&priv->sta_lock, flags); - for (i = 0; i < priv->hw_params.max_stations; i++) { - if (!(priv->stations[i].used & IWL_STA_BCAST)) - continue; - - priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; - priv->num_stations--; - BUG_ON(priv->num_stations < 0); - kfree(priv->stations[i].lq); - priv->stations[i].lq = NULL; - } - spin_unlock_irqrestore(&priv->sta_lock, flags); -} -EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station); - -/** - * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table - */ -int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid) -{ - unsigned long flags; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - /* Remove "disable" flag, to enable Tx for this TID */ - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; - priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} -EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); - -int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, - int tid, u16 ssn) -{ - unsigned long flags; - int sta_id; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - sta_id = iwl_sta_id(sta); - if (sta_id == IWL_INVALID_STATION) - return -ENXIO; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.station_flags_msk = 0; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK; - priv->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid; - priv->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn); - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} -EXPORT_SYMBOL(iwl_sta_rx_agg_start); - -int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, - int tid) -{ - unsigned long flags; - int sta_id; - struct iwl_addsta_cmd sta_cmd; - - lockdep_assert_held(&priv->mutex); - - sta_id = iwl_sta_id(sta); - if (sta_id == IWL_INVALID_STATION) { - IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid); - return -ENXIO; - } - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.station_flags_msk = 0; - priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; - priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd)); - spin_unlock_irqrestore(&priv->sta_lock, flags); - - return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); -} -EXPORT_SYMBOL(iwl_sta_rx_agg_stop); - -void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id) -{ - unsigned long flags; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.station_flags &= ~STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.sta.modify_mask = 0; - priv->stations[sta_id].sta.sleep_tx_count = 0; - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->sta_lock, flags); - -} -EXPORT_SYMBOL(iwl_sta_modify_ps_wake); - -void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt) -{ - unsigned long flags; - - spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK; - priv->stations[sta_id].sta.sta.modify_mask = - STA_MODIFY_SLEEP_TX_COUNT_MSK; - priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); - priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; - iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); - spin_unlock_irqrestore(&priv->sta_lock, flags); - -} -EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); - int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index d38a350ba0bd46a7d98e09810346243dea2be528..06475872eee4e2690023206918b3e944f5e7e5d8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -43,44 +43,26 @@ #define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */ -int iwl_remove_default_wep_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key); -int iwl_set_default_wep_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key); -int iwl_restore_default_wep_keys(struct iwl_priv *priv); -int iwl_set_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key, u8 sta_id); -int iwl_remove_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key, u8 sta_id); -void iwl_update_tkip_key(struct iwl_priv *priv, - struct ieee80211_key_conf *keyconf, - struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); - -void iwl_restore_stations(struct iwl_priv *priv); -void iwl_clear_ucode_stations(struct iwl_priv *priv); -int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq); -void iwl_dealloc_bcast_station(struct iwl_priv *priv); -int iwl_update_bcast_station(struct iwl_priv *priv); +void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx); +void iwl_clear_ucode_stations(struct iwl_priv *priv, + struct iwl_rxon_context *ctx); +void iwl_dealloc_bcast_stations(struct iwl_priv *priv); int iwl_get_free_ucode_key_index(struct iwl_priv *priv); int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_addsta_cmd *sta, u8 flags); -int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs, - u8 *sta_id_r); -int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, - bool is_ap, - struct ieee80211_sta_ht_cap *ht_info, - u8 *sta_id_r); +int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, + struct ieee80211_sta *sta, u8 *sta_id_r); int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, const u8 *addr); int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -int iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid); -int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta, - int tid, u16 ssn); -int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta, - int tid); -void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id); -void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); + +u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + const u8 *addr, bool is_ap, struct ieee80211_sta *sta); + +int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, + struct iwl_link_quality_cmd *lq, u8 flags, bool init); /** * iwl_clear_driver_stations - clear knowledge of all stations from driver @@ -94,20 +76,25 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt); static inline void iwl_clear_driver_stations(struct iwl_priv *priv) { unsigned long flags; + struct iwl_rxon_context *ctx; spin_lock_irqsave(&priv->sta_lock, flags); memset(priv->stations, 0, sizeof(priv->stations)); priv->num_stations = 0; - /* - * Remove all key information that is not stored as part of station - * information since mac80211 may not have had a - * chance to remove all the keys. When device is reconfigured by - * mac80211 after an error all keys will be reconfigured. - */ priv->ucode_key_table = 0; - priv->key_mapping_key = 0; - memset(priv->wep_keys, 0, sizeof(priv->wep_keys)); + + for_each_context(priv, ctx) { + /* + * Remove all key information that is not stored as part + * of station information since mac80211 may not have had + * a chance to remove all the keys. When device is + * reconfigured by mac80211 after an error all keys will + * be reconfigured. + */ + memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys)); + ctx->key_mapping_keys = 0; + } spin_unlock_irqrestore(&priv->sta_lock, flags); } @@ -123,6 +110,7 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) /** * iwl_sta_id_or_broadcast - return sta_id or broadcast sta * @priv: iwl priv + * @context: the current context * @sta: mac80211 station * * In certain circumstances mac80211 passes a station pointer @@ -131,12 +119,13 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta) * inline wraps that pattern. */ static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv, + struct iwl_rxon_context *context, struct ieee80211_sta *sta) { int sta_id; if (!sta) - return priv->hw_params.bcast_sta_id; + return context->bcast_sta_id; sta_id = iwl_sta_id(sta); diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index a81989c0698336dab5ebd0127ed01b93de698e57..7261ee49f282f2c1e3a6d027a2aad2954c9b85a3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -134,7 +134,7 @@ EXPORT_SYMBOL(iwl_tx_queue_free); */ void iwl_cmd_queue_free(struct iwl_priv *priv) { - struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; struct iwl_queue *q = &txq->q; struct device *dev = &priv->pci_dev->dev; int i; @@ -271,7 +271,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv, /* Driver private data, only for Tx (not command) queues, * not shared with device. */ - if (id != IWL_CMD_QUEUE_NUM) { + if (id != priv->cmd_queue) { txq->txb = kzalloc(sizeof(txq->txb[0]) * TFD_QUEUE_SIZE_MAX, GFP_KERNEL); if (!txq->txb) { @@ -314,13 +314,13 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, /* * Alloc buffer array for commands (Tx or other types of commands). - * For the command queue (#4), allocate command space + one big + * For the command queue (#4/#9), allocate command space + one big * command for scan, since scan command is very huge; the system will * not have two scans at the same time, so only one is needed. * For normal Tx queues (all other queues), no super-size command * space is needed. */ - if (txq_id == IWL_CMD_QUEUE_NUM) + if (txq_id == priv->cmd_queue) actual_slots++; txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots, @@ -355,7 +355,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, * need an swq_id so don't set one to catch errors, all others can * be set up to the identity mapping. */ - if (txq_id != IWL_CMD_QUEUE_NUM) + if (txq_id != priv->cmd_queue) txq->swq_id = txq_id; /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise @@ -385,7 +385,7 @@ void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, { int actual_slots = slots_num; - if (txq_id == IWL_CMD_QUEUE_NUM) + if (txq_id == priv->cmd_queue) actual_slots++; memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); @@ -413,7 +413,7 @@ EXPORT_SYMBOL(iwl_tx_queue_reset); */ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) { - struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; struct iwl_queue *q = &txq->q; struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; @@ -422,6 +422,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) int len; u32 idx; u16 fix_size; + bool is_ct_kill = false; cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len); fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr)); @@ -443,9 +444,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { IWL_ERR(priv, "No space in command queue\n"); - if (iwl_within_ct_kill_margin(priv)) - iwl_tt_enter_ct_kill(priv); - else { + if (priv->cfg->ops->lib->tt_ops.ct_kill_check) { + is_ct_kill = + priv->cfg->ops->lib->tt_ops.ct_kill_check(priv); + } + if (!is_ct_kill) { IWL_ERR(priv, "Restarting adapter due to queue full\n"); queue_work(priv->workqueue, &priv->restart); } @@ -480,7 +483,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) * information */ out_cmd->hdr.flags = 0; - out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | + out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) | INDEX_TO_SEQ(q->write_ptr)); if (cmd->flags & CMD_SIZE_HUGE) out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; @@ -497,15 +500,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) get_cmd_string(out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), fix_size, - q->write_ptr, idx, IWL_CMD_QUEUE_NUM); - break; + q->write_ptr, idx, priv->cmd_queue); + break; default: IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, " "%d bytes at %d[%d]:%d\n", get_cmd_string(out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), fix_size, - q->write_ptr, idx, IWL_CMD_QUEUE_NUM); + q->write_ptr, idx, priv->cmd_queue); } #endif txq->need_update = 1; @@ -584,16 +587,16 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; - struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; + struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced * in the queue management code. */ - if (WARN(txq_id != IWL_CMD_QUEUE_NUM, - "wrong command queue %d, sequence 0x%X readp=%d writep=%d\n", - txq_id, sequence, - priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr, - priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) { + if (WARN(txq_id != priv->cmd_queue, + "wrong command queue %d (should be %d), sequence 0x%X readp=%d writep=%d\n", + txq_id, priv->cmd_queue, sequence, + priv->txq[priv->cmd_queue].q.read_ptr, + priv->txq[priv->cmd_queue].q.write_ptr)) { iwl_print_hex_error(priv, pkt, 32); return; } @@ -633,41 +636,3 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) meta->flags = 0; } EXPORT_SYMBOL(iwl_tx_cmd_complete); - -#ifdef CONFIG_IWLWIFI_DEBUG -#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x -#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x - -const char *iwl_get_tx_fail_reason(u32 status) -{ - switch (status & TX_STATUS_MSK) { - case TX_STATUS_SUCCESS: - return "SUCCESS"; - TX_STATUS_POSTPONE(DELAY); - TX_STATUS_POSTPONE(FEW_BYTES); - TX_STATUS_POSTPONE(BT_PRIO); - TX_STATUS_POSTPONE(QUIET_PERIOD); - TX_STATUS_POSTPONE(CALC_TTAK); - TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY); - TX_STATUS_FAIL(SHORT_LIMIT); - TX_STATUS_FAIL(LONG_LIMIT); - TX_STATUS_FAIL(FIFO_UNDERRUN); - TX_STATUS_FAIL(DRAIN_FLOW); - TX_STATUS_FAIL(RFKILL_FLUSH); - TX_STATUS_FAIL(LIFE_EXPIRE); - TX_STATUS_FAIL(DEST_PS); - TX_STATUS_FAIL(HOST_ABORTED); - TX_STATUS_FAIL(BT_RETRY); - TX_STATUS_FAIL(STA_INVALID); - TX_STATUS_FAIL(FRAG_DROPPED); - TX_STATUS_FAIL(TID_DISABLE); - TX_STATUS_FAIL(FIFO_FLUSHED); - TX_STATUS_FAIL(INSUFFICIENT_CF_POLL); - TX_STATUS_FAIL(FW_DROP); - TX_STATUS_FAIL(STA_COLOR_MISMATCH_DROP); - } - - return "UNKNOWN"; -} -EXPORT_SYMBOL(iwl_get_tx_fail_reason); -#endif /* CONFIG_IWLWIFI_DEBUG */ diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index d31661c1ce778259996b5428f9cff95b87f1a3db..8f8c4b73f8b9667a245f764360058be740f38b03 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -143,7 +144,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); - if (sta_id == priv->hw_params.bcast_sta_id) + if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id) key_flags |= STA_KEY_MULTICAST_MSK; keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; @@ -151,7 +152,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv, key_flags &= ~STA_KEY_FLG_INVALID; spin_lock_irqsave(&priv->sta_lock, flags); - priv->stations[sta_id].keyinfo.alg = keyconf->alg; + priv->stations[sta_id].keyinfo.cipher = keyconf->cipher; priv->stations[sta_id].keyinfo.keylen = keyconf->keylen; memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key, keyconf->keylen); @@ -222,23 +223,25 @@ static int iwl3945_set_dynamic_key(struct iwl_priv *priv, keyconf->hw_key_idx = HW_KEY_DYNAMIC; - switch (keyconf->alg) { - case ALG_CCMP: + switch (keyconf->cipher) { + case WLAN_CIPHER_SUITE_CCMP: ret = iwl3945_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: ret = iwl3945_set_tkip_dynamic_key_info(priv, keyconf, sta_id); break; - case ALG_WEP: + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: ret = iwl3945_set_wep_dynamic_key_info(priv, keyconf, sta_id); break; default: - IWL_ERR(priv, "Unknown alg: %s alg = %d\n", __func__, keyconf->alg); + IWL_ERR(priv, "Unknown alg: %s alg=%x\n", __func__, + keyconf->cipher); ret = -EINVAL; } - IWL_DEBUG_WEP(priv, "Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n", - keyconf->alg, keyconf->keylen, keyconf->keyidx, + IWL_DEBUG_WEP(priv, "Set dynamic key: alg=%x len=%d idx=%d sta=%d ret=%d\n", + keyconf->cipher, keyconf->keylen, keyconf->keyidx, sta_id, ret); return ret; @@ -254,10 +257,11 @@ static int iwl3945_remove_static_key(struct iwl_priv *priv) static int iwl3945_set_static_key(struct iwl_priv *priv, struct ieee80211_key_conf *key) { - if (key->alg == ALG_WEP) + if (key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) return -EOPNOTSUPP; - IWL_ERR(priv, "Static key invalid: alg %d\n", key->alg); + IWL_ERR(priv, "Static key invalid: cipher %x\n", key->cipher); return -EINVAL; } @@ -313,15 +317,15 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv, int left) { - if (!iwl_is_associated(priv) || !priv->ibss_beacon) + if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb) return 0; - if (priv->ibss_beacon->len > left) + if (priv->beacon_skb->len > left) return 0; - memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len); + memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); - return priv->ibss_beacon->len; + return priv->beacon_skb->len; } static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) @@ -339,7 +343,8 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) return -ENOMEM; } - rate = iwl_rate_get_lowest_plcp(priv); + rate = iwl_rate_get_lowest_plcp(priv, + &priv->contexts[IWL_RXON_CTX_BSS]); frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); @@ -369,23 +374,25 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, struct iwl3945_tx_cmd *tx_cmd = (struct iwl3945_tx_cmd *)cmd->cmd.payload; struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo; - switch (keyinfo->alg) { - case ALG_CCMP: + tx_cmd->sec_ctl = 0; + + switch (keyinfo->cipher) { + case WLAN_CIPHER_SUITE_CCMP: tx_cmd->sec_ctl = TX_CMD_SEC_CCM; memcpy(tx_cmd->key, keyinfo->key, keyinfo->keylen); IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: break; - case ALG_WEP: - tx_cmd->sec_ctl = TX_CMD_SEC_WEP | + case WLAN_CIPHER_SUITE_WEP104: + tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; + /* fall through */ + case WLAN_CIPHER_SUITE_WEP40: + tx_cmd->sec_ctl |= TX_CMD_SEC_WEP | (info->control.hw_key->hw_key_idx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT; - if (keyinfo->keylen == 13) - tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128; - memcpy(&tx_cmd->key[3], keyinfo->key, keyinfo->keylen); IWL_DEBUG_TX(priv, "Configuring packet for WEP encryption " @@ -393,7 +400,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, break; default: - IWL_ERR(priv, "Unknown encode alg %d\n", keyinfo->alg); + IWL_ERR(priv, "Unknown encode cipher %x\n", keyinfo->cipher); break; } } @@ -506,7 +513,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) hdr_len = ieee80211_hdrlen(fc); /* Find index into station table for destination station */ - sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); + sta_id = iwl_sta_id_or_broadcast( + priv, &priv->contexts[IWL_RXON_CTX_BSS], + info->control.sta); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -536,6 +545,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* Set up driver data for this TFD */ memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); txq->txb[q->write_ptr].skb = skb; + txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS]; /* Init first empty entry in queue's array of Tx/cmd buffers */ out_cmd = txq->cmd[idx]; @@ -677,11 +687,12 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, int rc; int spectrum_resp_status; int duration = le16_to_cpu(params->duration); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - if (iwl_is_associated(priv)) + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) add_time = iwl_usecs_to_beacons(priv, le64_to_cpu(params->start_time) - priv->_3945.last_tsf, - le16_to_cpu(priv->rxon_timing.beacon_interval)); + le16_to_cpu(ctx->timing.beacon_interval)); memset(&spectrum, 0, sizeof(spectrum)); @@ -692,18 +703,18 @@ static int iwl3945_get_measurement(struct iwl_priv *priv, cmd.len = sizeof(spectrum); spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); - if (iwl_is_associated(priv)) + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) spectrum.start_time = iwl_add_beacon_time(priv, priv->_3945.last_beacon_time, add_time, - le16_to_cpu(priv->rxon_timing.beacon_interval)); + le16_to_cpu(ctx->timing.beacon_interval)); else spectrum.start_time = 0; spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); spectrum.channels[0].channel = params->channel; spectrum.channels[0].type = type; - if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK) + if (ctx->active.flags & RXON_FLG_BAND_24G_MSK) spectrum.flags |= RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; @@ -792,7 +803,8 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) struct sk_buff *beacon; /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ - beacon = ieee80211_beacon_get(priv->hw, priv->vif); + beacon = ieee80211_beacon_get(priv->hw, + priv->contexts[IWL_RXON_CTX_BSS].vif); if (!beacon) { IWL_ERR(priv, "update beacon failed\n"); @@ -801,10 +813,10 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) mutex_lock(&priv->mutex); /* new beacon skb is allocated every time; dispose previous.*/ - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); - priv->ibss_beacon = beacon; + priv->beacon_skb = beacon; mutex_unlock(&priv->mutex); iwl3945_send_beacon_cmd(priv); @@ -813,9 +825,9 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { -#ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status); +#ifdef CONFIG_IWLWIFI_DEBUG u8 rate = beacon->beacon_notify_hdr.rate; IWL_DEBUG_RX(priv, "beacon status %x retries %d iss %d " @@ -827,6 +839,8 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv, le32_to_cpu(beacon->low_tsf), rate); #endif + priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status); + if ((priv->iw_mode == NL80211_IFTYPE_AP) && (!test_bit(STATUS_EXIT_PENDING, &priv->status))) queue_work(priv->workqueue, &priv->beacon_update); @@ -1567,16 +1581,16 @@ int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log, num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32))); next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32))); - if (capacity > priv->cfg->max_event_log_size) { + if (capacity > priv->cfg->base_params->max_event_log_size) { IWL_ERR(priv, "Log capacity %d is bogus, limit to %d entries\n", - capacity, priv->cfg->max_event_log_size); - capacity = priv->cfg->max_event_log_size; + capacity, priv->cfg->base_params->max_event_log_size); + capacity = priv->cfg->base_params->max_event_log_size; } - if (next_entry > priv->cfg->max_event_log_size) { + if (next_entry > priv->cfg->base_params->max_event_log_size) { IWL_ERR(priv, "Log write index %d is bogus, limit to %d\n", - next_entry, priv->cfg->max_event_log_size); - next_entry = priv->cfg->max_event_log_size; + next_entry, priv->cfg->base_params->max_event_log_size); + next_entry = priv->cfg->base_params->max_event_log_size; } size = num_wraps ? capacity : next_entry; @@ -1716,7 +1730,6 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv) IWL_ERR(priv, "Microcode SW error detected. " "Restarting 0x%X.\n", inta); priv->isr_stats.sw++; - priv->isr_stats.sw_err = inta; iwl_irq_handle_error(priv); handled |= CSR_INT_BIT_SW_ERR; } @@ -2460,6 +2473,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) { int thermal_spin = 0; u32 rfkill; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); @@ -2505,7 +2519,8 @@ static void iwl3945_alive_start(struct iwl_priv *priv) /* Enable timer to monitor the driver queues */ mod_timer(&priv->monitor_recover, jiffies + - msecs_to_jiffies(priv->cfg->monitor_recover_period)); + msecs_to_jiffies( + priv->cfg->base_params->monitor_recover_period)); } if (iwl_is_rfkill(priv)) @@ -2517,22 +2532,22 @@ static void iwl3945_alive_start(struct iwl_priv *priv) iwl_power_update_mode(priv, true); - if (iwl_is_associated(priv)) { + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { struct iwl3945_rxon_cmd *active_rxon = - (struct iwl3945_rxon_cmd *)(&priv->active_rxon); + (struct iwl3945_rxon_cmd *)(&ctx->active); - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; } else { /* Initialize our rx_config data */ - iwl_connection_init_rx_config(priv, NULL); + iwl_connection_init_rx_config(priv, ctx); } /* Configure Bluetooth device coexistence support */ priv->cfg->ops->hcmd->send_bt_config(priv); /* Configure the adapter for unassociated operation */ - iwlcore_commit_rxon(priv); + iwl3945_commit_rxon(priv, ctx); iwl3945_reg_txpower_periodic(priv); @@ -2553,19 +2568,22 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv); static void __iwl3945_down(struct iwl_priv *priv) { unsigned long flags; - int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); - struct ieee80211_conf *conf = NULL; + int exit_pending; IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); - conf = ieee80211_get_hw_conf(priv->hw); + iwl_scan_cancel_timeout(priv, 200); - if (!exit_pending) - set_bit(STATUS_EXIT_PENDING, &priv->status); + exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status); + + /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set + * to prevent rearm timer */ + if (priv->cfg->ops->lib->recover_from_tx_stall) + del_timer_sync(&priv->monitor_recover); /* Station information will now be cleared in device */ - iwl_clear_ucode_stations(priv); - iwl_dealloc_bcast_station(priv); + iwl_clear_ucode_stations(priv, NULL); + iwl_dealloc_bcast_stations(priv); iwl_clear_driver_stations(priv); /* Unblock any waiting calls */ @@ -2619,14 +2637,14 @@ static void __iwl3945_down(struct iwl_priv *priv) udelay(5); /* Stop the device, and put it in low power state */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); exit: memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); - priv->ibss_beacon = NULL; + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); + priv->beacon_skb = NULL; /* clear out any free frames */ iwl3945_clear_free_frames(priv); @@ -2643,11 +2661,33 @@ static void iwl3945_down(struct iwl_priv *priv) #define MAX_HW_RESTARTS 5 +static int iwl3945_alloc_bcast_station(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; + unsigned long flags; + u8 sta_id; + + spin_lock_irqsave(&priv->sta_lock, flags); + sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); + if (sta_id == IWL_INVALID_STATION) { + IWL_ERR(priv, "Unable to prepare broadcast station\n"); + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return -EINVAL; + } + + priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; + priv->stations[sta_id].used |= IWL_STA_BCAST; + spin_unlock_irqrestore(&priv->sta_lock, flags); + + return 0; +} + static int __iwl3945_up(struct iwl_priv *priv) { int rc, i; - rc = iwl_alloc_bcast_station(priv, false); + rc = iwl3945_alloc_bcast_station(priv); if (rc) return rc; @@ -2799,7 +2839,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data) } -void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) +int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) { struct iwl_host_cmd cmd = { .id = REPLY_SCAN_CMD, @@ -2807,61 +2847,19 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) .flags = CMD_SIZE_HUGE, }; struct iwl3945_scan_cmd *scan; - struct ieee80211_conf *conf = NULL; u8 n_probes = 0; enum ieee80211_band band; bool is_active = false; + int ret; - conf = ieee80211_get_hw_conf(priv->hw); - - cancel_delayed_work(&priv->scan_check); - - if (!iwl_is_ready(priv)) { - IWL_WARN(priv, "request scan called when driver not ready.\n"); - goto done; - } - - /* Make sure the scan wasn't canceled before this queued work - * was given the chance to run... */ - if (!test_bit(STATUS_SCANNING, &priv->status)) - goto done; - - /* This should never be called or scheduled if there is currently - * a scan active in the hardware. */ - if (test_bit(STATUS_SCAN_HW, &priv->status)) { - IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests " - "Ignoring second request.\n"); - goto done; - } - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n"); - goto done; - } - - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_HC(priv, - "Scan request while abort pending. Queuing.\n"); - goto done; - } - - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n"); - goto done; - } - - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_DEBUG_HC(priv, - "Scan request while uninitialized. Queuing.\n"); - goto done; - } + lockdep_assert_held(&priv->mutex); if (!priv->scan_cmd) { priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) + IWL_MAX_SCAN_SIZE, GFP_KERNEL); if (!priv->scan_cmd) { IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n"); - goto done; + return -ENOMEM; } } scan = priv->scan_cmd; @@ -2870,7 +2868,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - if (iwl_is_associated(priv)) { + if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) { u16 interval = 0; u32 extra; u32 suspend_time = 100; @@ -2931,7 +2929,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) /* We don't build a direct scan probe request; the uCode will do * that based on the direct_mask added to each channel entry */ scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; + scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id; scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; /* flags + rate selection */ @@ -2940,25 +2938,25 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) case IEEE80211_BAND_2GHZ: scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; scan->tx_cmd.rate = IWL_RATE_1M_PLCP; - scan->good_CRC_th = 0; band = IEEE80211_BAND_2GHZ; break; case IEEE80211_BAND_5GHZ: scan->tx_cmd.rate = IWL_RATE_6M_PLCP; - /* - * If active scaning is requested but a certain channel - * is marked passive, we can do active scanning if we - * detect transmissions. - */ - scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : - IWL_GOOD_CRC_TH_DISABLED; band = IEEE80211_BAND_5GHZ; break; default: IWL_WARN(priv, "Invalid scan band\n"); - goto done; + return -EIO; } + /* + * If active scaning is requested but a certain channel + * is marked passive, we can do active scanning if we + * detect transmissions. + */ + scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : + IWL_GOOD_CRC_TH_DISABLED; + if (!priv->is_internal_short_scan) { scan->tx_cmd.len = cpu_to_le16( iwl_fill_probe_req(priv, @@ -2991,7 +2989,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) if (scan->channel_count == 0) { IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); - goto done; + return -EIO; } cmd.len += le16_to_cpu(scan->tx_cmd.len) + @@ -3000,25 +2998,22 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) scan->len = cpu_to_le16(cmd.len); set_bit(STATUS_SCAN_HW, &priv->status); - if (iwl_send_cmd_sync(priv, &cmd)) - goto done; - - queue_delayed_work(priv->workqueue, &priv->scan_check, - IWL_SCAN_CHECK_WATCHDOG); + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) + clear_bit(STATUS_SCAN_HW, &priv->status); + return ret; +} - return; +void iwl3945_post_scan(struct iwl_priv *priv) +{ + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - done: - /* can not perform scan make sure we clear scanning - * bits from status so next scan request can be performed. - * if we dont clear scanning status bit here all next scan - * will fail - */ - clear_bit(STATUS_SCAN_HW, &priv->status); - clear_bit(STATUS_SCANNING, &priv->status); - - /* inform mac80211 scan aborted */ - queue_work(priv->workqueue, &priv->abort_scan); + /* + * Since setting the RXON may have been deferred while + * performing the scan, fire one off if needed + */ + if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) + iwl3945_commit_rxon(priv, ctx); } static void iwl3945_bg_restart(struct work_struct *data) @@ -3029,8 +3024,10 @@ static void iwl3945_bg_restart(struct work_struct *data) return; if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { + struct iwl_rxon_context *ctx; mutex_lock(&priv->mutex); - priv->vif = NULL; + for_each_context(priv, ctx) + ctx->vif = NULL; priv->is_open = 0; mutex_unlock(&priv->mutex); iwl3945_down(priv); @@ -3064,6 +3061,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) { int rc = 0; struct ieee80211_conf *conf = NULL; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; if (!vif || !priv->is_open) return; @@ -3074,7 +3072,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) } IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", - vif->bss_conf.aid, priv->active_rxon.bssid_addr); + vif->bss_conf.aid, ctx->active.bssid_addr); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -3083,37 +3081,34 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) conf = ieee80211_get_hw_conf(priv->hw); - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); - iwl_setup_rxon_timing(priv, vif); - rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), &priv->rxon_timing); + rc = iwl_send_rxon_timing(priv, ctx); if (rc) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; - priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid); + ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid); IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", vif->bss_conf.aid, vif->bss_conf.beacon_int); if (vif->bss_conf.use_short_preamble) - priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } - iwlcore_commit_rxon(priv); + iwl3945_commit_rxon(priv, ctx); switch (vif->type) { case NL80211_IFTYPE_STATION: @@ -3212,15 +3207,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw) priv->is_open = 0; - if (iwl_is_ready_rf(priv)) { - /* stop mac, cancel any scan request and clear - * RXON_FILTER_ASSOC_MSK BIT - */ - mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); - mutex_unlock(&priv->mutex); - } - iwl3945_down(priv); flush_workqueue(priv->workqueue); @@ -3250,48 +3236,45 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) { + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; int rc = 0; if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; /* The following should be done only at AP bring up */ - if (!(iwl_is_associated(priv))) { + if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) { /* RXON - unassoc (to set timing command) */ - priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); /* RXON Timing */ - memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); - iwl_setup_rxon_timing(priv, vif); - rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, - sizeof(priv->rxon_timing), - &priv->rxon_timing); + rc = iwl_send_rxon_timing(priv, ctx); if (rc) IWL_WARN(priv, "REPLY_RXON_TIMING failed - " "Attempting to continue.\n"); - priv->staging_rxon.assoc_id = 0; + ctx->staging.assoc_id = 0; if (vif->bss_conf.use_short_preamble) - priv->staging_rxon.flags |= + ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; else - priv->staging_rxon.flags &= + ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; - if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { + if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) { if (vif->bss_conf.use_short_slot) - priv->staging_rxon.flags |= + ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; else - priv->staging_rxon.flags &= + ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; } /* restore RXON assoc */ - priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - iwlcore_commit_rxon(priv); + ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; + iwl3945_commit_rxon(priv, ctx); } iwl3945_send_beacon_cmd(priv); @@ -3317,10 +3300,11 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, return -EOPNOTSUPP; } - static_key = !iwl_is_associated(priv); + static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); if (!static_key) { - sta_id = iwl_sta_id_or_broadcast(priv, sta); + sta_id = iwl_sta_id_or_broadcast( + priv, &priv->contexts[IWL_RXON_CTX_BSS], sta); if (sta_id == IWL_INVALID_STATION) return -EINVAL; } @@ -3371,8 +3355,8 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, sta_priv->common.sta_id = IWL_INVALID_STATION; - ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, - &sta_id); + ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS], + sta->addr, is_ap, sta, &sta_id); if (ret) { IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); @@ -3399,6 +3383,7 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, { struct iwl_priv *priv = hw->priv; __le32 filter_or = 0, filter_nand = 0; + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; #define CHK(test, flag) do { \ if (*total_flags & (test)) \ @@ -3418,8 +3403,8 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); - priv->staging_rxon.filter_flags &= ~filter_nand; - priv->staging_rxon.filter_flags |= filter_or; + ctx->staging.filter_flags &= ~filter_nand; + ctx->staging.filter_flags |= filter_or; /* * Committing directly here breaks for some reason, @@ -3533,8 +3518,9 @@ static ssize_t show_flags(struct device *d, struct device_attribute *attr, char *buf) { struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); + return sprintf(buf, "0x%04X\n", ctx->active.flags); } static ssize_t store_flags(struct device *d, @@ -3543,17 +3529,18 @@ static ssize_t store_flags(struct device *d, { struct iwl_priv *priv = dev_get_drvdata(d); u32 flags = simple_strtoul(buf, NULL, 0); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; mutex_lock(&priv->mutex); - if (le32_to_cpu(priv->staging_rxon.flags) != flags) { + if (le32_to_cpu(ctx->staging.flags) != flags) { /* Cancel any currently running scans... */ if (iwl_scan_cancel_timeout(priv, 100)) IWL_WARN(priv, "Could not cancel scan.\n"); else { IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", flags); - priv->staging_rxon.flags = cpu_to_le32(flags); - iwlcore_commit_rxon(priv); + ctx->staging.flags = cpu_to_le32(flags); + iwl3945_commit_rxon(priv, ctx); } } mutex_unlock(&priv->mutex); @@ -3567,9 +3554,10 @@ static ssize_t show_filter_flags(struct device *d, struct device_attribute *attr, char *buf) { struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; return sprintf(buf, "0x%04X\n", - le32_to_cpu(priv->active_rxon.filter_flags)); + le32_to_cpu(ctx->active.filter_flags)); } static ssize_t store_filter_flags(struct device *d, @@ -3577,19 +3565,20 @@ static ssize_t store_filter_flags(struct device *d, const char *buf, size_t count) { struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; u32 filter_flags = simple_strtoul(buf, NULL, 0); mutex_lock(&priv->mutex); - if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { + if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) { /* Cancel any currently running scans... */ if (iwl_scan_cancel_timeout(priv, 100)) IWL_WARN(priv, "Could not cancel scan.\n"); else { IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " "0x%04X\n", filter_flags); - priv->staging_rxon.filter_flags = + ctx->staging.filter_flags = cpu_to_le32(filter_flags); - iwlcore_commit_rxon(priv); + iwl3945_commit_rxon(priv, ctx); } } mutex_unlock(&priv->mutex); @@ -3637,8 +3626,9 @@ static ssize_t store_measurement(struct device *d, const char *buf, size_t count) { struct iwl_priv *priv = dev_get_drvdata(d); + struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct ieee80211_measurement_params params = { - .channel = le16_to_cpu(priv->active_rxon.channel), + .channel = le16_to_cpu(ctx->active.channel), .start_time = cpu_to_le64(priv->_3945.last_tsf), .duration = cpu_to_le16(1), }; @@ -3785,10 +3775,8 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv) INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start); INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll); - INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); - INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); - INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan); - INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); + + iwl_setup_scan_deferred_work(priv); iwl3945_hw_setup_deferred_work(priv); @@ -3808,12 +3796,10 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv) iwl3945_hw_cancel_deferred_work(priv); cancel_delayed_work_sync(&priv->init_alive_start); - cancel_delayed_work(&priv->scan_check); cancel_delayed_work(&priv->alive_start); - cancel_work_sync(&priv->start_internal_scan); cancel_work_sync(&priv->beacon_update); - if (priv->cfg->ops->lib->recover_from_tx_stall) - del_timer_sync(&priv->monitor_recover); + + iwl_cancel_scan_deferred_work(priv); } static struct attribute *iwl3945_sysfs_entries[] = { @@ -3853,6 +3839,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { .hw_scan = iwl_mac_hw_scan, .sta_add = iwl3945_mac_sta_add, .sta_remove = iwl_mac_sta_remove, + .tx_last_beacon = iwl_mac_tx_last_beacon, }; static int iwl3945_init_drv(struct iwl_priv *priv) @@ -3861,7 +3848,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; priv->retry_rate = 1; - priv->ibss_beacon = NULL; + priv->beacon_skb = NULL; spin_lock_init(&priv->sta_lock); spin_lock_init(&priv->hcmd_lock); @@ -3928,13 +3915,12 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT; - if (!priv->cfg->broken_powersave) + if (!priv->cfg->base_params->broken_powersave) hw->flags |= IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].interface_modes; hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS; @@ -3966,7 +3952,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - int err = 0; + int err = 0, i; struct iwl_priv *priv; struct ieee80211_hw *hw; struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); @@ -3988,12 +3974,33 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e priv = hw->priv; SET_IEEE80211_DEV(hw, &pdev->dev); + priv->cmd_queue = IWL39_CMD_QUEUE_NUM; + + /* 3945 has only one valid context */ + priv->valid_contexts = BIT(IWL_RXON_CTX_BSS); + + for (i = 0; i < NUM_IWL_RXON_CTX; i++) + priv->contexts[i].ctxid = i; + + priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON; + priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING; + priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC; + priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; + priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; + priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].interface_modes = + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC); + priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS; + priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS; + priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS; + /* * Disabling hardware scan means that mac80211 will perform scans * "the hard way", rather than using device's scan. */ if (iwl3945_mod_params.disable_hw_scan) { - IWL_DEBUG_INFO(priv, "Disabling hw_scan\n"); + IWL_ERR(priv, "sw scan support is deprecated\n"); iwl3945_hw_ops.hw_scan = NULL; } @@ -4009,6 +4016,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e /*************************** * 2. Initializing PCI bus * *************************/ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + if (pci_enable_device(pdev)) { err = -ENODEV; goto out_ieee80211_free_hw; @@ -4120,7 +4130,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e } iwl_set_rxon_channel(priv, - &priv->bands[IEEE80211_BAND_2GHZ].channels[5]); + &priv->bands[IEEE80211_BAND_2GHZ].channels[5], + &priv->contexts[IWL_RXON_CTX_BSS]); iwl3945_setup_deferred_work(priv); iwl3945_setup_rx_handlers(priv); iwl_power_initialize(priv); @@ -4201,7 +4212,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) * paths to avoid running iwl_down() at all before leaving driver. * This (inexpensive) call *makes sure* device is reset. */ - priv->cfg->ops->lib->apm_ops.stop(priv); + iwl_apm_stop(priv); /* make sure we flush any pending irq or * tasklet for the driver @@ -4245,8 +4256,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) iwl_free_channel_map(priv); iwlcore_free_geos(priv); kfree(priv->scan_cmd); - if (priv->ibss_beacon) - dev_kfree_skb(priv->ibss_beacon); + if (priv->beacon_skb) + dev_kfree_skb(priv->beacon_skb); ieee80211_free_hw(priv->hw); } @@ -4314,7 +4325,8 @@ MODULE_PARM_DESC(debug, "debug output mask"); #endif module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, S_IRUGO); -MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); +MODULE_PARM_DESC(disable_hw_scan, + "disable hardware scanning (default 0) (deprecated)"); module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, S_IRUGO); MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error"); diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index 60619678f4ec1cb39c94dd5b97c3977082c168f3..c6c0eff9b5ed33f32c51223629ddc1e2cf118d71 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -161,7 +161,7 @@ static int iwm_key_init(struct iwm_key *key, u8 key_index, } static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, const u8 *mac_addr, + u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) { struct iwm_priv *iwm = ndev_to_iwm(ndev); @@ -181,7 +181,8 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, } static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, const u8 *mac_addr, void *cookie, + u8 key_index, bool pairwise, const u8 *mac_addr, + void *cookie, void (*callback)(void *cookie, struct key_params*)) { @@ -206,7 +207,7 @@ static int iwm_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, const u8 *mac_addr) + u8 key_index, bool pairwise, const u8 *mac_addr) { struct iwm_priv *iwm = ndev_to_iwm(ndev); struct iwm_key *key = &iwm->keys[key_index]; diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index c02fcedea9fafc5e80375832d9e8bc7c70867317..a944893ae3ca78d9b3371102ffc85ad9b5cea65e 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c @@ -1195,11 +1195,8 @@ static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf, IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: " "oid is 0x%x\n", hdr->oid); - if (hdr->oid <= WIFI_IF_NTFY_MAX) { - set_bit(hdr->oid, &iwm->wifi_ntfy[0]); - wake_up_interruptible(&iwm->wifi_ntfy_queue); - } else - return -EINVAL; + set_bit(hdr->oid, &iwm->wifi_ntfy[0]); + wake_up_interruptible(&iwm->wifi_ntfy_queue); switch (hdr->oid) { case UMAC_WIFI_IF_CMD_SET_PROFILE: diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 3e82f162720972d8c6bd732fa437c7fc7046bde6..5046a00050348cc03fa4d10a566144449542bf36 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -480,7 +481,6 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, struct cmd_ds_802_11_scan_rsp *scanresp = (void *)resp; int bsssize; const u8 *pos; - u16 nr_sets; const u8 *tsfdesc; int tsfsize; int i; @@ -489,12 +489,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, lbs_deb_enter(LBS_DEB_CFG80211); bsssize = get_unaligned_le16(&scanresp->bssdescriptsize); - nr_sets = le16_to_cpu(scanresp->nr_sets); lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n", - nr_sets, bsssize, le16_to_cpu(resp->size)); + scanresp->nr_sets, bsssize, le16_to_cpu(resp->size)); - if (nr_sets == 0) { + if (scanresp->nr_sets == 0) { ret = 0; goto done; } @@ -526,20 +525,31 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, pos = scanresp->bssdesc_and_tlvbuffer; + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_RSP", scanresp->bssdesc_and_tlvbuffer, + scanresp->bssdescriptsize); + tsfdesc = pos + bsssize; tsfsize = 4 + 8 * scanresp->nr_sets; + lbs_deb_hex(LBS_DEB_SCAN, "SCAN_TSF", (u8 *) tsfdesc, tsfsize); /* Validity check: we expect a Marvell-Local TLV */ i = get_unaligned_le16(tsfdesc); tsfdesc += 2; - if (i != TLV_TYPE_TSFTIMESTAMP) + if (i != TLV_TYPE_TSFTIMESTAMP) { + lbs_deb_scan("scan response: invalid TSF Timestamp %d\n", i); goto done; + } + /* Validity check: the TLV holds TSF values with 8 bytes each, so * the size in the TLV must match the nr_sets value */ i = get_unaligned_le16(tsfdesc); tsfdesc += 2; - if (i / 8 != scanresp->nr_sets) + if (i / 8 != scanresp->nr_sets) { + lbs_deb_scan("scan response: invalid number of TSF timestamp " + "sets (expected %d got %d)\n", scanresp->nr_sets, + i / 8); goto done; + } for (i = 0; i < scanresp->nr_sets; i++) { const u8 *bssid; @@ -581,8 +591,11 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, id = *pos++; elen = *pos++; left -= 2; - if (elen > left || elen == 0) + if (elen > left || elen == 0) { + lbs_deb_scan("scan response: invalid IE fmt\n"); goto done; + } + if (id == WLAN_EID_DS_PARAMS) chan_no = *pos; if (id == WLAN_EID_SSID) { @@ -613,7 +626,9 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, capa, intvl, ie, ielen, LBS_SCAN_RSSI_TO_MBM(rssi), GFP_KERNEL); - } + } else + lbs_deb_scan("scan response: missing BSS channel IE\n"); + tsfdesc += 8; } ret = 0; @@ -1103,7 +1118,7 @@ static int lbs_associate(struct lbs_private *priv, lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp); /* add auth type TLV */ - if (priv->fwrelease >= 0x09000000) + if (MRVL_FW_MAJOR_REV(priv->fwrelease) >= 9) pos += lbs_add_auth_type_tlv(pos, sme->auth_type); /* add WPA/WPA2 TLV */ @@ -1114,6 +1129,9 @@ static int lbs_associate(struct lbs_private *priv, (u16)(pos - (u8 *) &cmd->iebuf); cmd->hdr.size = cpu_to_le16(len); + lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_CMD", (u8 *) cmd, + le16_to_cpu(cmd->hdr.size)); + /* store for later use */ memcpy(priv->assoc_bss, bss->bssid, ETH_ALEN); @@ -1121,14 +1139,28 @@ static int lbs_associate(struct lbs_private *priv, if (ret) goto done; - /* generate connect message to cfg80211 */ resp = (void *) cmd; /* recast for easier field access */ status = le16_to_cpu(resp->statuscode); - /* Convert statis code of old firmware */ - if (priv->fwrelease < 0x09000000) + /* Older FW versions map the IEEE 802.11 Status Code in the association + * response to the following values returned in resp->statuscode: + * + * IEEE Status Code Marvell Status Code + * 0 -> 0x0000 ASSOC_RESULT_SUCCESS + * 13 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 14 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 15 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * 16 -> 0x0004 ASSOC_RESULT_AUTH_REFUSED + * others -> 0x0003 ASSOC_RESULT_REFUSED + * + * Other response codes: + * 0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused) + * 0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for + * association response from the AP) + */ + if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) { switch (status) { case 0: break; @@ -1150,11 +1182,16 @@ static int lbs_associate(struct lbs_private *priv, break; default: lbs_deb_assoc("association failure %d\n", status); - status = WLAN_STATUS_UNSPECIFIED_FAILURE; + /* v5 OLPC firmware does return the AP status code if + * it's not one of the values above. Let that through. + */ + break; + } } - lbs_deb_assoc("status %d, capability 0x%04x\n", status, - le16_to_cpu(resp->capability)); + lbs_deb_assoc("status %d, statuscode 0x%04x, capability 0x%04x, " + "aid 0x%04x\n", status, le16_to_cpu(resp->statuscode), + le16_to_cpu(resp->capability), le16_to_cpu(resp->aid)); resp_ie_len = le16_to_cpu(resp->hdr.size) - sizeof(resp->hdr) @@ -1174,7 +1211,6 @@ static int lbs_associate(struct lbs_private *priv, netif_tx_wake_all_queues(priv->dev); } - done: lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); return ret; @@ -1404,7 +1440,7 @@ static int lbs_cfg_set_default_key(struct wiphy *wiphy, static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev, - u8 idx, const u8 *mac_addr, + u8 idx, bool pairwise, const u8 *mac_addr, struct key_params *params) { struct lbs_private *priv = wiphy_priv(wiphy); @@ -1464,7 +1500,7 @@ static int lbs_cfg_add_key(struct wiphy *wiphy, struct net_device *netdev, static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr) + u8 key_index, bool pairwise, const u8 *mac_addr) { lbs_deb_enter(LBS_DEB_CFG80211); diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h index 1d141fefd7673bf89c9a5554aa6f6bcbb49aac9e..2ae752d1006555318bb421b39fea2a9b6d37d735 100644 --- a/drivers/net/wireless/libertas/decl.h +++ b/drivers/net/wireless/libertas/decl.h @@ -8,7 +8,14 @@ #define _LBS_DECL_H_ #include +#include +/* Should be terminated by a NULL entry */ +struct lbs_fw_table { + int model; + const char *helper; + const char *fwname; +}; struct lbs_private; struct sk_buff; @@ -53,4 +60,10 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv); u32 lbs_fw_index_to_data_rate(u8 index); u8 lbs_data_rate_to_fw_index(u32 rate); +int lbs_get_firmware(struct device *dev, const char *user_helper, + const char *user_mainfw, u32 card_model, + const struct lbs_fw_table *fw_table, + const struct firmware **helper, + const struct firmware **mainfw); + #endif diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index ff1280f413362847b364fa8a5cf4f680a21fd354..fc8121190d38e89f22553f0360b812f90e587cfb 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -47,7 +47,6 @@ MODULE_AUTHOR("Holger Schurig "); MODULE_DESCRIPTION("Driver for Marvell 83xx compact flash WLAN cards"); MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("libertas_cs_helper.fw"); @@ -60,9 +59,34 @@ struct if_cs_card { struct lbs_private *priv; void __iomem *iobase; bool align_regs; + u32 model; }; +enum { + MODEL_UNKNOWN = 0x00, + MODEL_8305 = 0x01, + MODEL_8381 = 0x02, + MODEL_8385 = 0x03 +}; + +static const struct lbs_fw_table fw_table[] = { + { MODEL_8305, "libertas/cf8305.bin", NULL }, + { MODEL_8305, "libertas_cs_helper.fw", NULL }, + { MODEL_8381, "libertas/cf8381_helper.bin", "libertas/cf8381.bin" }, + { MODEL_8381, "libertas_cs_helper.fw", "libertas_cs.fw" }, + { MODEL_8385, "libertas/cf8385_helper.bin", "libertas/cf8385.bin" }, + { MODEL_8385, "libertas_cs_helper.fw", "libertas_cs.fw" }, + { 0, NULL, NULL } +}; +MODULE_FIRMWARE("libertas/cf8305.bin"); +MODULE_FIRMWARE("libertas/cf8381_helper.bin"); +MODULE_FIRMWARE("libertas/cf8381.bin"); +MODULE_FIRMWARE("libertas/cf8385_helper.bin"); +MODULE_FIRMWARE("libertas/cf8385.bin"); +MODULE_FIRMWARE("libertas_cs_helper.fw"); +MODULE_FIRMWARE("libertas_cs.fw"); + /********************************************************************/ /* Hardware access */ @@ -288,22 +312,19 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r #define CF8385_MANFID 0x02df #define CF8385_CARDID 0x8103 -static inline int if_cs_hw_is_cf8305(struct pcmcia_device *p_dev) -{ - return (p_dev->manf_id == CF8305_MANFID && - p_dev->card_id == CF8305_CARDID); -} - -static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev) -{ - return (p_dev->manf_id == CF8381_MANFID && - p_dev->card_id == CF8381_CARDID); -} - -static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev) +/* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when + * that gets fixed. Currently there's no way to access it from the probe hook. + */ +static inline u32 get_model(u16 manf_id, u16 card_id) { - return (p_dev->manf_id == CF8385_MANFID && - p_dev->card_id == CF8385_CARDID); + /* NOTE: keep in sync with if_cs_ids */ + if (manf_id == CF8305_MANFID && card_id == CF8305_CARDID) + return MODEL_8305; + else if (manf_id == CF8381_MANFID && card_id == CF8381_CARDID) + return MODEL_8381; + else if (manf_id == CF8385_MANFID && card_id == CF8385_CARDID) + return MODEL_8385; + return MODEL_UNKNOWN; } /********************************************************************/ @@ -557,12 +578,11 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) * * Return 0 on success */ -static int if_cs_prog_helper(struct if_cs_card *card) +static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw) { int ret = 0; int sent = 0; u8 scratch; - const struct firmware *fw; lbs_deb_enter(LBS_DEB_CS); @@ -588,14 +608,6 @@ static int if_cs_prog_helper(struct if_cs_card *card) goto done; } - /* TODO: make firmware file configurable */ - ret = request_firmware(&fw, "libertas_cs_helper.fw", - &card->p_dev->dev); - if (ret) { - lbs_pr_err("can't load helper firmware\n"); - ret = -ENODEV; - goto done; - } lbs_deb_cs("helper size %td\n", fw->size); /* "Set the 5 bytes of the helper image to 0" */ @@ -634,7 +646,7 @@ static int if_cs_prog_helper(struct if_cs_card *card) if (ret < 0) { lbs_pr_err("can't download helper at 0x%x, ret %d\n", sent, ret); - goto err_release; + goto done; } if (count == 0) @@ -643,17 +655,14 @@ static int if_cs_prog_helper(struct if_cs_card *card) sent += count; } -err_release: - release_firmware(fw); done: lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); return ret; } -static int if_cs_prog_real(struct if_cs_card *card) +static int if_cs_prog_real(struct if_cs_card *card, const struct firmware *fw) { - const struct firmware *fw; int ret = 0; int retry = 0; int len = 0; @@ -661,21 +670,13 @@ static int if_cs_prog_real(struct if_cs_card *card) lbs_deb_enter(LBS_DEB_CS); - /* TODO: make firmware file configurable */ - ret = request_firmware(&fw, "libertas_cs.fw", - &card->p_dev->dev); - if (ret) { - lbs_pr_err("can't load firmware\n"); - ret = -ENODEV; - goto done; - } lbs_deb_cs("fw size %td\n", fw->size); ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, IF_CS_SQ_HELPER_OK); if (ret < 0) { lbs_pr_err("helper firmware doesn't answer\n"); - goto err_release; + goto done; } for (sent = 0; sent < fw->size; sent += len) { @@ -690,7 +691,7 @@ static int if_cs_prog_real(struct if_cs_card *card) if (retry > 20) { lbs_pr_err("could not download firmware\n"); ret = -ENODEV; - goto err_release; + goto done; } if (retry) { sent -= len; @@ -709,7 +710,7 @@ static int if_cs_prog_real(struct if_cs_card *card) IF_CS_BIT_COMMAND); if (ret < 0) { lbs_pr_err("can't download firmware at 0x%x\n", sent); - goto err_release; + goto done; } } @@ -717,9 +718,6 @@ static int if_cs_prog_real(struct if_cs_card *card) if (ret < 0) lbs_pr_err("firmware download failed\n"); -err_release: - release_firmware(fw); - done: lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); return ret; @@ -795,6 +793,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev) unsigned int prod_id; struct lbs_private *priv; struct if_cs_card *card; + const struct firmware *helper = NULL; + const struct firmware *mainfw = NULL; lbs_deb_enter(LBS_DEB_CS); @@ -845,34 +845,47 @@ static int if_cs_probe(struct pcmcia_device *p_dev) */ card->align_regs = 0; + card->model = get_model(p_dev->manf_id, p_dev->card_id); + if (card->model == MODEL_UNKNOWN) { + lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n", + p_dev->manf_id, p_dev->card_id); + goto out2; + } + /* Check if we have a current silicon */ prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID); - if (if_cs_hw_is_cf8305(p_dev)) { + if (card->model == MODEL_8305) { card->align_regs = 1; if (prod_id < IF_CS_CF8305_B1_REV) { - lbs_pr_err("old chips like 8305 rev B3 " - "aren't supported\n"); + lbs_pr_err("8305 rev B0 and older are not supported\n"); ret = -ENODEV; goto out2; } } - if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) { - lbs_pr_err("old chips like 8381 rev B3 aren't supported\n"); + if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) { + lbs_pr_err("8381 rev B2 and older are not supported\n"); ret = -ENODEV; goto out2; } - if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) { - lbs_pr_err("old chips like 8385 rev B1 aren't supported\n"); + if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) { + lbs_pr_err("8385 rev B0 and older are not supported\n"); ret = -ENODEV; goto out2; } + ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model, + &fw_table[0], &helper, &mainfw); + if (ret) { + lbs_pr_err("failed to find firmware (%d)\n", ret); + goto out2; + } + /* Load the firmware early, before calling into libertas.ko */ - ret = if_cs_prog_helper(card); - if (ret == 0 && !if_cs_hw_is_cf8305(p_dev)) - ret = if_cs_prog_real(card); + ret = if_cs_prog_helper(card, helper); + if (ret == 0 && (card->model != MODEL_8305)) + ret = if_cs_prog_real(card, mainfw); if (ret) goto out2; @@ -921,6 +934,11 @@ static int if_cs_probe(struct pcmcia_device *p_dev) out1: pcmcia_disable_device(p_dev); out: + if (helper) + release_firmware(helper); + if (mainfw) + release_firmware(mainfw); + lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret); return ret; } @@ -951,6 +969,7 @@ static struct pcmcia_device_id if_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID), PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID), PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID), + /* NOTE: keep in sync with get_model() */ PCMCIA_DEVICE_NULL, }; MODULE_DEVICE_TABLE(pcmcia, if_cs_ids); diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 87b634978b357797ed6ceb22f7dec9643f6c7054..296fd00a5129f2bb9f47e3475bf25d35c67e7f20 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -76,36 +76,32 @@ static const struct sdio_device_id if_sdio_ids[] = { MODULE_DEVICE_TABLE(sdio, if_sdio_ids); -struct if_sdio_model { - int model; - const char *helper; - const char *firmware; -}; - -static struct if_sdio_model if_sdio_models[] = { - { - /* 8385 */ - .model = IF_SDIO_MODEL_8385, - .helper = "sd8385_helper.bin", - .firmware = "sd8385.bin", - }, - { - /* 8686 */ - .model = IF_SDIO_MODEL_8686, - .helper = "sd8686_helper.bin", - .firmware = "sd8686.bin", - }, - { - /* 8688 */ - .model = IF_SDIO_MODEL_8688, - .helper = "sd8688_helper.bin", - .firmware = "sd8688.bin", - }, +#define MODEL_8385 0x04 +#define MODEL_8686 0x0b +#define MODEL_8688 0x10 + +static const struct lbs_fw_table fw_table[] = { + { MODEL_8385, "libertas/sd8385_helper.bin", "libertas/sd8385.bin" }, + { MODEL_8385, "sd8385_helper.bin", "sd8385.bin" }, + { MODEL_8686, "libertas/sd8686_v9_helper.bin", "libertas/sd8686_v9.bin" }, + { MODEL_8686, "libertas/sd8686_v8_helper.bin", "libertas/sd8686_v8.bin" }, + { MODEL_8686, "sd8686_helper.bin", "sd8686.bin" }, + { MODEL_8688, "libertas/sd8688_helper.bin", "libertas/sd8688.bin" }, + { MODEL_8688, "sd8688_helper.bin", "sd8688.bin" }, + { 0, NULL, NULL } }; +MODULE_FIRMWARE("libertas/sd8385_helper.bin"); +MODULE_FIRMWARE("libertas/sd8385.bin"); MODULE_FIRMWARE("sd8385_helper.bin"); MODULE_FIRMWARE("sd8385.bin"); +MODULE_FIRMWARE("libertas/sd8686_v9_helper.bin"); +MODULE_FIRMWARE("libertas/sd8686_v9.bin"); +MODULE_FIRMWARE("libertas/sd8686_v8_helper.bin"); +MODULE_FIRMWARE("libertas/sd8686_v8.bin"); MODULE_FIRMWARE("sd8686_helper.bin"); MODULE_FIRMWARE("sd8686.bin"); +MODULE_FIRMWARE("libertas/sd8688_helper.bin"); +MODULE_FIRMWARE("libertas/sd8688.bin"); MODULE_FIRMWARE("sd8688_helper.bin"); MODULE_FIRMWARE("sd8688.bin"); @@ -187,11 +183,11 @@ static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err) u16 rx_len; switch (card->model) { - case IF_SDIO_MODEL_8385: - case IF_SDIO_MODEL_8686: + case MODEL_8385: + case MODEL_8686: rx_len = if_sdio_read_scratch(card, &ret); break; - case IF_SDIO_MODEL_8688: + case MODEL_8688: default: /* for newer chipsets */ rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret); if (!ret) @@ -288,7 +284,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card, lbs_deb_enter(LBS_DEB_SDIO); - if (card->model == IF_SDIO_MODEL_8385) { + if (card->model == MODEL_8385) { event = sdio_readb(card->func, IF_SDIO_EVENT, &ret); if (ret) goto out; @@ -466,10 +462,10 @@ static void if_sdio_host_to_card_worker(struct work_struct *work) #define FW_DL_READY_STATUS (IF_SDIO_IO_RDY | IF_SDIO_DL_RDY) -static int if_sdio_prog_helper(struct if_sdio_card *card) +static int if_sdio_prog_helper(struct if_sdio_card *card, + const struct firmware *fw) { int ret; - const struct firmware *fw; unsigned long timeout; u8 *chunk_buffer; u32 chunk_size; @@ -478,16 +474,10 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) lbs_deb_enter(LBS_DEB_SDIO); - ret = request_firmware(&fw, card->helper, &card->func->dev); - if (ret) { - lbs_pr_err("can't load helper firmware\n"); - goto out; - } - chunk_buffer = kzalloc(64, GFP_KERNEL); if (!chunk_buffer) { ret = -ENOMEM; - goto release_fw; + goto out; } sdio_claim_host(card->func); @@ -562,22 +552,19 @@ static int if_sdio_prog_helper(struct if_sdio_card *card) release: sdio_release_host(card->func); kfree(chunk_buffer); -release_fw: - release_firmware(fw); out: if (ret) lbs_pr_err("failed to load helper firmware\n"); lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - return ret; } -static int if_sdio_prog_real(struct if_sdio_card *card) +static int if_sdio_prog_real(struct if_sdio_card *card, + const struct firmware *fw) { int ret; - const struct firmware *fw; unsigned long timeout; u8 *chunk_buffer; u32 chunk_size; @@ -586,16 +573,10 @@ static int if_sdio_prog_real(struct if_sdio_card *card) lbs_deb_enter(LBS_DEB_SDIO); - ret = request_firmware(&fw, card->firmware, &card->func->dev); - if (ret) { - lbs_pr_err("can't load firmware\n"); - goto out; - } - chunk_buffer = kzalloc(512, GFP_KERNEL); if (!chunk_buffer) { ret = -ENOMEM; - goto release_fw; + goto out; } sdio_claim_host(card->func); @@ -685,15 +666,12 @@ static int if_sdio_prog_real(struct if_sdio_card *card) release: sdio_release_host(card->func); kfree(chunk_buffer); -release_fw: - release_firmware(fw); out: if (ret) lbs_pr_err("failed to load firmware\n"); lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); - return ret; } @@ -701,6 +679,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) { int ret; u16 scratch; + const struct firmware *helper = NULL; + const struct firmware *mainfw = NULL; lbs_deb_enter(LBS_DEB_SDIO); @@ -718,11 +698,18 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) goto success; } - ret = if_sdio_prog_helper(card); + ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name, + card->model, &fw_table[0], &helper, &mainfw); + if (ret) { + lbs_pr_err("failed to find firmware (%d)\n", ret); + goto out; + } + + ret = if_sdio_prog_helper(card, helper); if (ret) goto out; - ret = if_sdio_prog_real(card); + ret = if_sdio_prog_real(card, mainfw); if (ret) goto out; @@ -733,8 +720,12 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card) ret = 0; out: - lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); + if (helper) + release_firmware(helper); + if (mainfw) + release_firmware(mainfw); + lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret); return ret; } @@ -938,7 +929,7 @@ static int if_sdio_probe(struct sdio_func *func, "ID: %x", &model) == 1) break; if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) { - model = IF_SDIO_MODEL_8385; + model = MODEL_8385; break; } } @@ -956,13 +947,13 @@ static int if_sdio_probe(struct sdio_func *func, card->model = model; switch (card->model) { - case IF_SDIO_MODEL_8385: + case MODEL_8385: card->scratch_reg = IF_SDIO_SCRATCH_OLD; break; - case IF_SDIO_MODEL_8686: + case MODEL_8686: card->scratch_reg = IF_SDIO_SCRATCH; break; - case IF_SDIO_MODEL_8688: + case MODEL_8688: default: /* for newer chipsets */ card->scratch_reg = IF_SDIO_FW_STATUS; break; @@ -972,49 +963,17 @@ static int if_sdio_probe(struct sdio_func *func, card->workqueue = create_workqueue("libertas_sdio"); INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker); - for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) { - if (card->model == if_sdio_models[i].model) + /* Check if we support this card */ + for (i = 0; i < ARRAY_SIZE(fw_table); i++) { + if (card->model == fw_table[i].model) break; } - - if (i == ARRAY_SIZE(if_sdio_models)) { + if (i == ARRAY_SIZE(fw_table)) { lbs_pr_err("unknown card model 0x%x\n", card->model); ret = -ENODEV; goto free; } - card->helper = if_sdio_models[i].helper; - card->firmware = if_sdio_models[i].firmware; - - kparam_block_sysfs_write(helper_name); - if (lbs_helper_name) { - char *helper = kstrdup(lbs_helper_name, GFP_KERNEL); - if (!helper) { - kparam_unblock_sysfs_write(helper_name); - ret = -ENOMEM; - goto free; - } - lbs_deb_sdio("overriding helper firmware: %s\n", - lbs_helper_name); - card->helper = helper; - card->helper_allocated = true; - } - kparam_unblock_sysfs_write(helper_name); - - kparam_block_sysfs_write(fw_name); - if (lbs_fw_name) { - char *fw_name = kstrdup(lbs_fw_name, GFP_KERNEL); - if (!fw_name) { - kparam_unblock_sysfs_write(fw_name); - ret = -ENOMEM; - goto free; - } - lbs_deb_sdio("overriding firmware: %s\n", lbs_fw_name); - card->firmware = fw_name; - card->firmware_allocated = true; - } - kparam_unblock_sysfs_write(fw_name); - sdio_claim_host(func); ret = sdio_enable_func(func); @@ -1028,7 +987,7 @@ static int if_sdio_probe(struct sdio_func *func, /* For 1-bit transfers to the 8686 model, we need to enable the * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 * bit to allow access to non-vendor registers. */ - if ((card->model == IF_SDIO_MODEL_8686) && + if ((card->model == MODEL_8686) && (host->caps & MMC_CAP_SDIO_IRQ) && (host->ios.bus_width == MMC_BUS_WIDTH_1)) { u8 reg; @@ -1091,8 +1050,8 @@ static int if_sdio_probe(struct sdio_func *func, * Get rx_unit if the chip is SD8688 or newer. * SD8385 & SD8686 do not have rx_unit. */ - if ((card->model != IF_SDIO_MODEL_8385) - && (card->model != IF_SDIO_MODEL_8686)) + if ((card->model != MODEL_8385) + && (card->model != MODEL_8686)) card->rx_unit = if_sdio_read_rx_unit(card); else card->rx_unit = 0; @@ -1108,7 +1067,7 @@ static int if_sdio_probe(struct sdio_func *func, /* * FUNC_INIT is required for SD8688 WLAN/BT multiple functions */ - if (card->model == IF_SDIO_MODEL_8688) { + if (card->model == MODEL_8688) { struct cmd_header cmd; memset(&cmd, 0, sizeof(cmd)); @@ -1165,7 +1124,7 @@ static void if_sdio_remove(struct sdio_func *func) card = sdio_get_drvdata(func); - if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) { + if (user_rmmod && (card->model == MODEL_8688)) { /* * FUNC_SHUTDOWN is required for SD8688 WLAN/BT * multiple functions diff --git a/drivers/net/wireless/libertas/if_sdio.h b/drivers/net/wireless/libertas/if_sdio.h index 12179c1dc9c9b27583bafb90f73c7b22af9c516a..62fda3592f6784f191e484a8f0c1b515b002a035 100644 --- a/drivers/net/wireless/libertas/if_sdio.h +++ b/drivers/net/wireless/libertas/if_sdio.h @@ -12,10 +12,6 @@ #ifndef _LBS_IF_SDIO_H #define _LBS_IF_SDIO_H -#define IF_SDIO_MODEL_8385 0x04 -#define IF_SDIO_MODEL_8686 0x0b -#define IF_SDIO_MODEL_8688 0x10 - #define IF_SDIO_IOPORT 0x00 #define IF_SDIO_H_INT_MASK 0x04 diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index fe3f08028eb3a07881ea62bc33cc34b931d34883..79bcb4e5d2ca03c7ccb82621576296a6ea68b5d0 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -39,9 +39,6 @@ struct if_spi_card { struct lbs_private *priv; struct libertas_spi_platform_data *pdata; - char helper_fw_name[IF_SPI_FW_NAME_MAX]; - char main_fw_name[IF_SPI_FW_NAME_MAX]; - /* The card ID and card revision, as reported by the hardware. */ u16 card_id; u8 card_rev; @@ -70,10 +67,28 @@ static void free_if_spi_card(struct if_spi_card *card) kfree(card); } -static struct chip_ident chip_id_to_device_name[] = { - { .chip_id = 0x04, .name = 8385 }, - { .chip_id = 0x0b, .name = 8686 }, +#define MODEL_8385 0x04 +#define MODEL_8686 0x0b +#define MODEL_8688 0x10 + +static const struct lbs_fw_table fw_table[] = { + { MODEL_8385, "libertas/gspi8385_helper.bin", "libertas/gspi8385.bin" }, + { MODEL_8385, "libertas/gspi8385_hlp.bin", "libertas/gspi8385.bin" }, + { MODEL_8686, "libertas/gspi8686_v9_helper.bin", "libertas/gspi8686_v9.bin" }, + { MODEL_8686, "libertas/gspi8686_hlp.bin", "libertas/gspi8686.bin" }, + { MODEL_8688, "libertas/gspi8688_helper.bin", "libertas/gspi8688.bin" }, + { 0, NULL, NULL } }; +MODULE_FIRMWARE("libertas/gspi8385_helper.bin"); +MODULE_FIRMWARE("libertas/gspi8385_hlp.bin"); +MODULE_FIRMWARE("libertas/gspi8385.bin"); +MODULE_FIRMWARE("libertas/gspi8686_v9_helper.bin"); +MODULE_FIRMWARE("libertas/gspi8686_v9.bin"); +MODULE_FIRMWARE("libertas/gspi8686_hlp.bin"); +MODULE_FIRMWARE("libertas/gspi8686.bin"); +MODULE_FIRMWARE("libertas/gspi8688_helper.bin"); +MODULE_FIRMWARE("libertas/gspi8688.bin"); + /* * SPI Interface Unit Routines @@ -399,26 +414,20 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes) * Firmware Loading */ -static int if_spi_prog_helper_firmware(struct if_spi_card *card) +static int if_spi_prog_helper_firmware(struct if_spi_card *card, + const struct firmware *firmware) { int err = 0; - const struct firmware *firmware = NULL; int bytes_remaining; const u8 *fw; u8 temp[HELPER_FW_LOAD_CHUNK_SZ]; - struct spi_device *spi = card->spi; lbs_deb_enter(LBS_DEB_SPI); err = spu_set_interrupt_mode(card, 1, 0); if (err) goto out; - /* Get helper firmware image */ - err = request_firmware(&firmware, card->helper_fw_name, &spi->dev); - if (err) { - lbs_pr_err("request_firmware failed with err = %d\n", err); - goto out; - } + bytes_remaining = firmware->size; fw = firmware->data; @@ -429,13 +438,13 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card) err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, HELPER_FW_LOAD_CHUNK_SZ); if (err) - goto release_firmware; + goto out; err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, IF_SPI_HIST_CMD_DOWNLOAD_RDY, IF_SPI_HIST_CMD_DOWNLOAD_RDY); if (err) - goto release_firmware; + goto out; /* Feed the data into the command read/write port reg * in chunks of 64 bytes */ @@ -446,16 +455,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card) err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, temp, HELPER_FW_LOAD_CHUNK_SZ); if (err) - goto release_firmware; + goto out; /* Interrupt the boot code */ err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); if (err) - goto release_firmware; + goto out; err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_CMD_DOWNLOAD_OVER); if (err) - goto release_firmware; + goto out; bytes_remaining -= HELPER_FW_LOAD_CHUNK_SZ; fw += HELPER_FW_LOAD_CHUNK_SZ; } @@ -465,18 +474,16 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card) * bootloader. This completes the helper download. */ err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); if (err) - goto release_firmware; + goto out; err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); if (err) - goto release_firmware; + goto out; err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_CMD_DOWNLOAD_OVER); - goto release_firmware; + goto out; lbs_deb_spi("waiting for helper to boot...\n"); -release_firmware: - release_firmware(firmware); out: if (err) lbs_pr_err("failed to load helper firmware (err=%d)\n", err); @@ -523,13 +530,12 @@ static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, return len; } -static int if_spi_prog_main_firmware(struct if_spi_card *card) +static int if_spi_prog_main_firmware(struct if_spi_card *card, + const struct firmware *firmware) { int len, prev_len; int bytes, crc_err = 0, err = 0; - const struct firmware *firmware = NULL; const u8 *fw; - struct spi_device *spi = card->spi; u16 num_crc_errs; lbs_deb_enter(LBS_DEB_SPI); @@ -538,19 +544,11 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) if (err) goto out; - /* Get firmware image */ - err = request_firmware(&firmware, card->main_fw_name, &spi->dev); - if (err) { - lbs_pr_err("%s: can't get firmware '%s' from kernel. " - "err = %d\n", __func__, card->main_fw_name, err); - goto out; - } - err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0); if (err) { lbs_pr_err("%s: timed out waiting for initial " "scratch reg = 0\n", __func__); - goto release_firmware; + goto out; } num_crc_errs = 0; @@ -560,7 +558,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) while ((len = if_spi_prog_main_firmware_check_len(card, &crc_err))) { if (len < 0) { err = len; - goto release_firmware; + goto out; } if (bytes < 0) { /* If there are no more bytes left, we would normally @@ -575,7 +573,7 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) lbs_pr_err("Too many CRC errors encountered " "in firmware load.\n"); err = -EIO; - goto release_firmware; + goto out; } } else { /* Previous transfer succeeded. Advance counters. */ @@ -590,15 +588,15 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG, 0); if (err) - goto release_firmware; + goto out; err = spu_write(card, IF_SPI_CMD_RDWRPORT_REG, card->cmd_buffer, len); if (err) - goto release_firmware; + goto out; err = spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG , IF_SPI_CIC_CMD_DOWNLOAD_OVER); if (err) - goto release_firmware; + goto out; prev_len = len; } if (bytes > prev_len) { @@ -611,12 +609,9 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card) SUCCESSFUL_FW_DOWNLOAD_MAGIC); if (err) { lbs_pr_err("failed to confirm the firmware download\n"); - goto release_firmware; + goto out; } -release_firmware: - release_firmware(firmware); - out: if (err) lbs_pr_err("failed to load firmware (err=%d)\n", err); @@ -800,14 +795,16 @@ static int lbs_spi_thread(void *data) goto err; } - if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) + if (hiStatus & IF_SPI_HIST_CMD_UPLOAD_RDY) { err = if_spi_c2h_cmd(card); if (err) goto err; - if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) + } + if (hiStatus & IF_SPI_HIST_RX_UPLOAD_RDY) { err = if_spi_c2h_data(card); if (err) goto err; + } /* workaround: in PS mode, the card does not set the Command * Download Ready bit, but it sets TX Download Ready. */ @@ -886,37 +883,16 @@ static irqreturn_t if_spi_host_interrupt(int irq, void *dev_id) * SPI callbacks */ -static int if_spi_calculate_fw_names(u16 card_id, - char *helper_fw, char *main_fw) -{ - int i; - for (i = 0; i < ARRAY_SIZE(chip_id_to_device_name); ++i) { - if (card_id == chip_id_to_device_name[i].chip_id) - break; - } - if (i == ARRAY_SIZE(chip_id_to_device_name)) { - lbs_pr_err("Unsupported chip_id: 0x%02x\n", card_id); - return -EAFNOSUPPORT; - } - snprintf(helper_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d_hlp.bin", - chip_id_to_device_name[i].name); - snprintf(main_fw, IF_SPI_FW_NAME_MAX, "libertas/gspi%d.bin", - chip_id_to_device_name[i].name); - return 0; -} -MODULE_FIRMWARE("libertas/gspi8385_hlp.bin"); -MODULE_FIRMWARE("libertas/gspi8385.bin"); -MODULE_FIRMWARE("libertas/gspi8686_hlp.bin"); -MODULE_FIRMWARE("libertas/gspi8686.bin"); - static int __devinit if_spi_probe(struct spi_device *spi) { struct if_spi_card *card; struct lbs_private *priv = NULL; struct libertas_spi_platform_data *pdata = spi->dev.platform_data; - int err = 0; + int err = 0, i; u32 scratch; struct sched_param param = { .sched_priority = 1 }; + const struct firmware *helper = NULL; + const struct firmware *mainfw = NULL; lbs_deb_enter(LBS_DEB_SPI); @@ -961,10 +937,25 @@ static int __devinit if_spi_probe(struct spi_device *spi) lbs_deb_spi("Firmware is already loaded for " "Marvell WLAN 802.11 adapter\n"); else { - err = if_spi_calculate_fw_names(card->card_id, - card->helper_fw_name, card->main_fw_name); - if (err) + /* Check if we support this card */ + for (i = 0; i < ARRAY_SIZE(fw_table); i++) { + if (card->card_id == fw_table[i].model) + break; + } + if (i == ARRAY_SIZE(fw_table)) { + lbs_pr_err("Unsupported chip_id: 0x%02x\n", + card->card_id); + err = -ENODEV; goto free_card; + } + + err = lbs_get_firmware(&card->spi->dev, NULL, NULL, + card->card_id, &fw_table[0], &helper, + &mainfw); + if (err) { + lbs_pr_err("failed to find firmware (%d)\n", err); + goto free_card; + } lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " "(chip_id = 0x%04x, chip_rev = 0x%02x) " @@ -973,10 +964,10 @@ static int __devinit if_spi_probe(struct spi_device *spi) card->card_id, card->card_rev, spi->master->bus_num, spi->chip_select, spi->max_speed_hz); - err = if_spi_prog_helper_firmware(card); + err = if_spi_prog_helper_firmware(card, helper); if (err) goto free_card; - err = if_spi_prog_main_firmware(card); + err = if_spi_prog_main_firmware(card, mainfw); if (err) goto free_card; lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); @@ -1044,6 +1035,11 @@ static int __devinit if_spi_probe(struct spi_device *spi) free_card: free_if_spi_card(card); out: + if (helper) + release_firmware(helper); + if (mainfw) + release_firmware(mainfw); + lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); return err; } diff --git a/drivers/net/wireless/libertas/if_spi.h b/drivers/net/wireless/libertas/if_spi.h index f87eec410848fb023416170c0241a84938949f55..8b1417d3b71b6a1533ff100bde95a7752e391893 100644 --- a/drivers/net/wireless/libertas/if_spi.h +++ b/drivers/net/wireless/libertas/if_spi.h @@ -25,11 +25,6 @@ #define IF_SPI_FW_NAME_MAX 30 -struct chip_ident { - u16 chip_id; - u16 name; -}; - #define MAX_MAIN_FW_LOAD_CRC_ERR 10 /* Chunk size when loading the helper firmware */ diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 3ff61063671a099a944fd4fd840e62c582d9a7c6..efaf850322089b3f6ef1c40219dc547020976767 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -26,15 +26,25 @@ #define MESSAGE_HEADER_LEN 4 -static char *lbs_fw_name = "usb8388.bin"; +static char *lbs_fw_name = NULL; module_param_named(fw_name, lbs_fw_name, charp, 0644); +MODULE_FIRMWARE("libertas/usb8388_v9.bin"); +MODULE_FIRMWARE("libertas/usb8388_v5.bin"); +MODULE_FIRMWARE("libertas/usb8388.bin"); +MODULE_FIRMWARE("libertas/usb8682.bin"); MODULE_FIRMWARE("usb8388.bin"); +enum { + MODEL_UNKNOWN = 0x0, + MODEL_8388 = 0x1, + MODEL_8682 = 0x2 +}; + static struct usb_device_id if_usb_table[] = { /* Enter the device signature inside */ - { USB_DEVICE(0x1286, 0x2001) }, - { USB_DEVICE(0x05a3, 0x8388) }, + { USB_DEVICE(0x1286, 0x2001), .driver_info = MODEL_8388 }, + { USB_DEVICE(0x05a3, 0x8388), .driver_info = MODEL_8388 }, {} /* Terminating entry */ }; @@ -66,6 +76,8 @@ static ssize_t if_usb_firmware_set(struct device *dev, struct if_usb_card *cardp = priv->card; int ret; + BUG_ON(buf == NULL); + ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_FW); if (ret == 0) return count; @@ -91,6 +103,8 @@ static ssize_t if_usb_boot2_set(struct device *dev, struct if_usb_card *cardp = priv->card; int ret; + BUG_ON(buf == NULL); + ret = if_usb_prog_firmware(cardp, buf, BOOT_CMD_UPDATE_BOOT2); if (ret == 0) return count; @@ -244,6 +258,7 @@ static int if_usb_probe(struct usb_interface *intf, init_waitqueue_head(&cardp->fw_wq); cardp->udev = udev; + cardp->model = (uint32_t) id->driver_info; iface_desc = intf->cur_altsetting; lbs_deb_usbd(&udev->dev, "bcdUSB = 0x%X bDeviceClass = 0x%X" @@ -472,11 +487,12 @@ static int if_usb_reset_device(struct if_usb_card *cardp) */ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb) { - int ret = -1; + int ret; /* check if device is removed */ if (cardp->surprise_removed) { lbs_deb_usbd(&cardp->udev->dev, "Device removed\n"); + ret = -ENODEV; goto tx_ret; } @@ -489,7 +505,6 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb if ((ret = usb_submit_urb(cardp->tx_urb, GFP_ATOMIC))) { lbs_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); - ret = -1; } else { lbs_deb_usb2(&cardp->udev->dev, "usb_submit_urb success\n"); ret = 0; @@ -924,6 +939,38 @@ static int if_usb_prog_firmware(struct if_usb_card *cardp, return ret; } +/* table of firmware file names */ +static const struct { + u32 model; + const char *fwname; +} fw_table[] = { + { MODEL_8388, "libertas/usb8388_v9.bin" }, + { MODEL_8388, "libertas/usb8388_v5.bin" }, + { MODEL_8388, "libertas/usb8388.bin" }, + { MODEL_8388, "usb8388.bin" }, + { MODEL_8682, "libertas/usb8682.bin" } +}; + +static int get_fw(struct if_usb_card *cardp, const char *fwname) +{ + int i; + + /* Try user-specified firmware first */ + if (fwname) + return request_firmware(&cardp->fw, fwname, &cardp->udev->dev); + + /* Otherwise search for firmware to use */ + for (i = 0; i < ARRAY_SIZE(fw_table); i++) { + if (fw_table[i].model != cardp->model) + continue; + if (request_firmware(&cardp->fw, fw_table[i].fwname, + &cardp->udev->dev) == 0) + return 0; + } + + return -ENOENT; +} + static int __if_usb_prog_firmware(struct if_usb_card *cardp, const char *fwname, int cmd) { @@ -933,10 +980,9 @@ static int __if_usb_prog_firmware(struct if_usb_card *cardp, lbs_deb_enter(LBS_DEB_USB); - ret = request_firmware(&cardp->fw, fwname, &cardp->udev->dev); - if (ret < 0) { - lbs_pr_err("request_firmware() failed with %#x\n", ret); - lbs_pr_err("firmware %s not found\n", fwname); + ret = get_fw(cardp, fwname); + if (ret) { + lbs_pr_err("failed to find firmware (%d)\n", ret); goto done; } diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h index 5ba0aee0eb2f7e6eac289583a990f51fc1daf2f6..d819e7e3c9aaff43c53d866d73547e6fdc0373fc 100644 --- a/drivers/net/wireless/libertas/if_usb.h +++ b/drivers/net/wireless/libertas/if_usb.h @@ -43,6 +43,7 @@ struct bootcmdresp /** USB card description structure*/ struct if_usb_card { struct usb_device *udev; + uint32_t model; /* MODEL_* */ struct urb *rx_urb, *tx_urb; struct lbs_private *priv; diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 24958a86747b3261d76c13d235b7f63211740ed8..47ce5a6ba120e9b9d707c56e93a79d35c1b5a3ea 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c @@ -1047,6 +1047,111 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx) } EXPORT_SYMBOL_GPL(lbs_notify_command_response); +/** + * @brief Retrieves two-stage firmware + * + * @param dev A pointer to device structure + * @param user_helper User-defined helper firmware file + * @param user_mainfw User-defined main firmware file + * @param card_model Bus-specific card model ID used to filter firmware table + * elements + * @param fw_table Table of firmware file names and device model numbers + * terminated by an entry with a NULL helper name + * @param helper On success, the helper firmware; caller must free + * @param mainfw On success, the main firmware; caller must free + * + * @return 0 on success, non-zero on failure + */ +int lbs_get_firmware(struct device *dev, const char *user_helper, + const char *user_mainfw, u32 card_model, + const struct lbs_fw_table *fw_table, + const struct firmware **helper, + const struct firmware **mainfw) +{ + const struct lbs_fw_table *iter; + int ret; + + BUG_ON(helper == NULL); + BUG_ON(mainfw == NULL); + + /* Try user-specified firmware first */ + if (user_helper) { + ret = request_firmware(helper, user_helper, dev); + if (ret) { + lbs_pr_err("couldn't find helper firmware %s", + user_helper); + goto fail; + } + } + if (user_mainfw) { + ret = request_firmware(mainfw, user_mainfw, dev); + if (ret) { + lbs_pr_err("couldn't find main firmware %s", + user_mainfw); + goto fail; + } + } + + if (*helper && *mainfw) + return 0; + + /* Otherwise search for firmware to use. If neither the helper or + * the main firmware were specified by the user, then we need to + * make sure that found helper & main are from the same entry in + * fw_table. + */ + iter = fw_table; + while (iter && iter->helper) { + if (iter->model != card_model) + goto next; + + if (*helper == NULL) { + ret = request_firmware(helper, iter->helper, dev); + if (ret) + goto next; + + /* If the device has one-stage firmware (ie cf8305) and + * we've got it then we don't need to bother with the + * main firmware. + */ + if (iter->fwname == NULL) + return 0; + } + + if (*mainfw == NULL) { + ret = request_firmware(mainfw, iter->fwname, dev); + if (ret && !user_helper) { + /* Clear the helper if it wasn't user-specified + * and the main firmware load failed, to ensure + * we don't have mismatched firmware pairs. + */ + release_firmware(*helper); + *helper = NULL; + } + } + + if (*helper && *mainfw) + return 0; + + next: + iter++; + } + + fail: + /* Failed */ + if (*helper) { + release_firmware(*helper); + *helper = NULL; + } + if (*mainfw) { + release_firmware(*mainfw); + *mainfw = NULL; + } + + return -ENOENT; +} +EXPORT_SYMBOL_GPL(lbs_get_firmware); + static int __init lbs_init_module(void) { lbs_deb_enter(LBS_DEB_MAIN); diff --git a/drivers/net/wireless/libertas/mesh.c b/drivers/net/wireless/libertas/mesh.c index 194762ab014250feb61b710f66b6fda737b08f2b..acf3bf63ee338286a3af92225cdd0849a4828ae0 100644 --- a/drivers/net/wireless/libertas/mesh.c +++ b/drivers/net/wireless/libertas/mesh.c @@ -574,7 +574,7 @@ int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) memset(&cmd, 0, sizeof(cmd)); cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT); - cmd.id = !!inverted; + cmd.id = cpu_to_le32(!!inverted); ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd); diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index 41a4f214ade1271e66b526cc4c936daf2059736a..ba7d96584cb6695120e548763dc4be8a976066ec 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -54,7 +54,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp); /** * if_usb_wrike_bulk_callback - call back to handle URB status * - * @param urb pointer to urb structure + * @param urb pointer to urb structure */ static void if_usb_write_bulk_callback(struct urb *urb) { @@ -178,16 +178,19 @@ static int if_usb_probe(struct usb_interface *intf, le16_to_cpu(endpoint->wMaxPacketSize); cardp->ep_in = usb_endpoint_num(endpoint); - lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n", cardp->ep_in); - lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n", cardp->ep_in_size); + lbtf_deb_usbd(&udev->dev, "in_endpoint = %d\n", + cardp->ep_in); + lbtf_deb_usbd(&udev->dev, "Bulk in size is %d\n", + cardp->ep_in_size); } else if (usb_endpoint_is_bulk_out(endpoint)) { cardp->ep_out_size = le16_to_cpu(endpoint->wMaxPacketSize); cardp->ep_out = usb_endpoint_num(endpoint); - lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", cardp->ep_out); + lbtf_deb_usbd(&udev->dev, "out_endpoint = %d\n", + cardp->ep_out); lbtf_deb_usbd(&udev->dev, "Bulk out size is %d\n", - cardp->ep_out_size); + cardp->ep_out_size); } } if (!cardp->ep_out_size || !cardp->ep_in_size) { @@ -318,10 +321,12 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp) if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_DATA_TO_RECV)) { lbtf_deb_usb2(&cardp->udev->dev, "There are data to follow\n"); - lbtf_deb_usb2(&cardp->udev->dev, "seqnum = %d totalbytes = %d\n", - cardp->fwseqnum, cardp->totalbytes); + lbtf_deb_usb2(&cardp->udev->dev, + "seqnum = %d totalbytes = %d\n", + cardp->fwseqnum, cardp->totalbytes); } else if (fwdata->hdr.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) { - lbtf_deb_usb2(&cardp->udev->dev, "Host has finished FW downloading\n"); + lbtf_deb_usb2(&cardp->udev->dev, + "Host has finished FW downloading\n"); lbtf_deb_usb2(&cardp->udev->dev, "Donwloading FW JUMP BLOCK\n"); /* Host has finished FW downloading @@ -367,7 +372,7 @@ EXPORT_SYMBOL_GPL(if_usb_reset_device); /** * usb_tx_block - transfer data to the device * - * @priv pointer to struct lbtf_private + * @priv pointer to struct lbtf_private * @payload pointer to payload data * @nb data length * @data non-zero for data, zero for commands @@ -400,7 +405,8 @@ static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, urb->transfer_flags |= URB_ZERO_PACKET; if (usb_submit_urb(urb, GFP_ATOMIC)) { - lbtf_deb_usbd(&cardp->udev->dev, "usb_submit_urb failed: %d\n", ret); + lbtf_deb_usbd(&cardp->udev->dev, + "usb_submit_urb failed: %d\n", ret); goto tx_ret; } @@ -438,10 +444,12 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp, cardp->rx_urb->transfer_flags |= URB_ZERO_PACKET; - lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", cardp->rx_urb); + lbtf_deb_usb2(&cardp->udev->dev, "Pointer for rx_urb %p\n", + cardp->rx_urb); ret = usb_submit_urb(cardp->rx_urb, GFP_ATOMIC); if (ret) { - lbtf_deb_usbd(&cardp->udev->dev, "Submit Rx URB failed: %d\n", ret); + lbtf_deb_usbd(&cardp->udev->dev, + "Submit Rx URB failed: %d\n", ret); kfree_skb(skb); cardp->rx_skb = NULL; lbtf_deb_leave(LBTF_DEB_USB); @@ -522,14 +530,14 @@ static void if_usb_receive_fwload(struct urb *urb) } } else if (bcmdresp.cmd != BOOT_CMD_FW_BY_USB) { pr_info("boot cmd response cmd_tag error (%d)\n", - bcmdresp.cmd); + bcmdresp.cmd); } else if (bcmdresp.result != BOOT_CMD_RESP_OK) { pr_info("boot cmd response result error (%d)\n", - bcmdresp.result); + bcmdresp.result); } else { cardp->bootcmdresp = 1; lbtf_deb_usbd(&cardp->udev->dev, - "Received valid boot command response\n"); + "Received valid boot command response\n"); } kfree_skb(skb); @@ -541,19 +549,23 @@ static void if_usb_receive_fwload(struct urb *urb) syncfwheader = kmemdup(skb->data, sizeof(struct fwsyncheader), GFP_ATOMIC); if (!syncfwheader) { - lbtf_deb_usbd(&cardp->udev->dev, "Failure to allocate syncfwheader\n"); + lbtf_deb_usbd(&cardp->udev->dev, + "Failure to allocate syncfwheader\n"); kfree_skb(skb); lbtf_deb_leave(LBTF_DEB_USB); return; } if (!syncfwheader->cmd) { - lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk with correct CRC\n"); - lbtf_deb_usb2(&cardp->udev->dev, "FW received Blk seqnum = %d\n", - le32_to_cpu(syncfwheader->seqnum)); + lbtf_deb_usb2(&cardp->udev->dev, + "FW received Blk with correct CRC\n"); + lbtf_deb_usb2(&cardp->udev->dev, + "FW received Blk seqnum = %d\n", + le32_to_cpu(syncfwheader->seqnum)); cardp->CRC_OK = 1; } else { - lbtf_deb_usbd(&cardp->udev->dev, "FW received Blk with CRC error\n"); + lbtf_deb_usbd(&cardp->udev->dev, + "FW received Blk with CRC error\n"); cardp->CRC_OK = 0; } @@ -666,7 +678,8 @@ static void if_usb_receive(struct urb *urb) { /* Event cause handling */ u32 event_cause = le32_to_cpu(pkt[1]); - lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", event_cause); + lbtf_deb_usbd(&cardp->udev->dev, "**EVENT** 0x%X\n", + event_cause); /* Icky undocumented magic special case */ if (event_cause & 0xffff0000) { @@ -689,7 +702,7 @@ static void if_usb_receive(struct urb *urb) } default: lbtf_deb_usbd(&cardp->udev->dev, - "libertastf: unknown command type 0x%X\n", recvtype); + "libertastf: unknown command type 0x%X\n", recvtype); kfree_skb(skb); break; } diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 86fa8abdd66fda1cba26ef0e2bfe90a249d14128..7eaaa3bab54780a334bcd70c99fb2d42b5862b92 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -9,7 +9,8 @@ /* * TODO: - * - IBSS mode simulation (Beacon transmission with competition for "air time") + * - Add TSF sync and fix IBSS beacon transmission by adding + * competition for "air time" at TBTT * - RX filtering based on filter configuration (data->rx_filter) */ @@ -594,17 +595,34 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", - __func__, vif->type, vif->addr); + __func__, ieee80211_vif_type_p2p(vif), + vif->addr); hwsim_set_magic(vif); return 0; } +static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype newtype, + bool newp2p) +{ + newtype = ieee80211_iftype_p2p(newtype, newp2p); + wiphy_debug(hw->wiphy, + "%s (old type=%d, new type=%d, mac_addr=%pM)\n", + __func__, ieee80211_vif_type_p2p(vif), + newtype, vif->addr); + hwsim_check_magic(vif); + + return 0; +} + static void mac80211_hwsim_remove_interface( struct ieee80211_hw *hw, struct ieee80211_vif *vif) { wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n", - __func__, vif->type, vif->addr); + __func__, ieee80211_vif_type_p2p(vif), + vif->addr); hwsim_check_magic(vif); hwsim_clear_magic(vif); } @@ -620,7 +638,8 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, hwsim_check_magic(vif); if (vif->type != NL80211_IFTYPE_AP && - vif->type != NL80211_IFTYPE_MESH_POINT) + vif->type != NL80211_IFTYPE_MESH_POINT && + vif->type != NL80211_IFTYPE_ADHOC) return; skb = ieee80211_beacon_get(hw, vif); @@ -1025,6 +1044,7 @@ static struct ieee80211_ops mac80211_hwsim_ops = .start = mac80211_hwsim_start, .stop = mac80211_hwsim_stop, .add_interface = mac80211_hwsim_add_interface, + .change_interface = mac80211_hwsim_change_interface, .remove_interface = mac80211_hwsim_remove_interface, .config = mac80211_hwsim_config, .configure_filter = mac80211_hwsim_configure_filter, @@ -1295,6 +1315,9 @@ static int __init init_mac80211_hwsim(void) hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); hw->flags = IEEE80211_HW_MFP_CAPABLE | diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 077baa86756b07db035799d319fa366abdd01490..b4772c1c6135c40fcad9859b6510eff0e1224182 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c @@ -762,14 +762,17 @@ int orinoco_hw_get_act_bitrate(struct orinoco_private *priv, int *bitrate) case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */ case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */ for (i = 0; i < BITRATE_TABLE_SIZE; i++) - if (bitrate_table[i].intersil_txratectrl == val) + if (bitrate_table[i].intersil_txratectrl == val) { + *bitrate = bitrate_table[i].bitrate * 100000; break; + } - if (i >= BITRATE_TABLE_SIZE) + if (i >= BITRATE_TABLE_SIZE) { printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n", priv->ndev->name, val); + err = -EIO; + } - *bitrate = bitrate_table[i].bitrate * 100000; break; default: BUG(); diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index cf7be1eb612495b699dc2e0cdc8fe17650c26736..93505f93bf97711019e86bbe27f39f4f727bce01 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c @@ -589,8 +589,15 @@ static int orinoco_ioctl_getrate(struct net_device *dev, /* If the interface is running we try to find more about the current mode */ - if (netif_running(dev)) - err = orinoco_hw_get_act_bitrate(priv, &bitrate); + if (netif_running(dev)) { + int act_bitrate; + int lerr; + + /* Ignore errors if we can't get the actual bitrate */ + lerr = orinoco_hw_get_act_bitrate(priv, &act_bitrate); + if (!lerr) + bitrate = act_bitrate; + } orinoco_unlock(priv, &flags); diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig index b0342a520bf160ca9daf2bd0df1a21406bad6f18..e5f45cb2a7a2334d839560d7c6366227f83c0030 100644 --- a/drivers/net/wireless/p54/Kconfig +++ b/drivers/net/wireless/p54/Kconfig @@ -2,6 +2,7 @@ config P54_COMMON tristate "Softmac Prism54 support" depends on MAC80211 && EXPERIMENTAL select FW_LOADER + select CRC_CCITT ---help--- This is common code for isl38xx/stlc45xx based modules. This module does nothing by itself - the USB/PCI/SPI front-ends @@ -48,6 +49,23 @@ config P54_SPI If you choose to build a module, it'll be called p54spi. +config P54_SPI_DEFAULT_EEPROM + bool "Include fallback EEPROM blob" + depends on P54_SPI + default n + ---help--- + Unlike the PCI or USB devices, the SPI variants don't have + a dedicated EEPROM chip to store all device specific values + for calibration, country and interface settings. + + The driver will try to load the image "3826.eeprom", if the + file is put at the right place. (usually /lib/firmware.) + + Only if this request fails, this option will provide a + backup set of generic values to get the device working. + + Enabling this option adds about 4k to p54spi. + config P54_LEDS bool depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON) diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 78347041ec40a3c51d094328495c8d86cb5c5a3b..35b09aa0529bf6cb6f142680d045c0e894c44df9 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c @@ -23,6 +23,7 @@ #include #include +#include #include "p54.h" #include "eeprom.h" @@ -260,8 +261,10 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) list->max_entries = max_channel_num; list->channels = kzalloc(sizeof(struct p54_channel_entry) * max_channel_num, GFP_KERNEL); - if (!list->channels) + if (!list->channels) { + ret = -ENOMEM; goto free; + } for (i = 0; i < max_channel_num; i++) { if (i < priv->iq_autocal_len) { @@ -540,6 +543,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) int err; u8 *end = (u8 *)eeprom + len; u16 synth = 0; + u16 crc16 = ~0; wrap = (struct eeprom_pda_wrap *) eeprom; entry = (void *)wrap->data + le16_to_cpu(wrap->len); @@ -655,16 +659,29 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) } break; case PDR_END: - /* make it overrun */ - entry_len = len; + crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry)); + if (crc16 != le16_to_cpup((__le16 *)entry->data)) { + wiphy_err(dev->wiphy, "eeprom failed checksum " + "test!\n"); + err = -ENOMSG; + goto err; + } else { + goto good_eeprom; + } break; default: break; } - entry = (void *)entry + (entry_len + 1)*2; + crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2); + entry = (void *)entry + (entry_len + 1) * 2; } + wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n"); + err = -ENODATA; + goto err; + +good_eeprom: if (!synth || !priv->iq_autocal || !priv->output_limit || !priv->curve_data) { wiphy_err(dev->wiphy, diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 15b20c29a6042ae6e3dc5c99dae07e8c317127ca..92b9b1f05fd536d4ed529a73b92d1ea198189923 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c @@ -123,10 +123,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) bootrec = (struct bootrec *)&bootrec->data[len]; } - if (fw_version) + if (fw_version) { wiphy_info(priv->hw->wiphy, "FW rev %s - Softmac protocol %x.%x\n", fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); + snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version), + "%s - %x.%x", fw_version, + priv->fw_var >> 8, priv->fw_var & 0xff); + } if (priv->fw_var < 0x500) wiphy_info(priv->hw->wiphy, diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 47db439b63bfd9d3f2b9330095b4c4b606160479..622d27b6d8f214a1e69b92b93c4c570a7b22b8df 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -429,8 +429,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, mutex_lock(&priv->conf_mutex); if (cmd == SET_KEY) { - switch (key->alg) { - case ALG_TKIP: + switch (key->cipher) { + case WLAN_CIPHER_SUITE_TKIP: if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL | BR_DESC_PRIV_CAP_TKIP))) { ret = -EOPNOTSUPP; @@ -439,7 +439,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; algo = P54_CRYPTO_TKIPMICHAEL; break; - case ALG_WEP: + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) { ret = -EOPNOTSUPP; goto out_unlock; @@ -447,7 +448,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd, key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; algo = P54_CRYPTO_WEP; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) { ret = -EOPNOTSUPP; goto out_unlock; diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 087bf0698a5af7aee75a8c47fac852fe4cd35fa1..18d24b7b1e3475c7f42c70204fa6d45105e07b81 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -32,11 +32,14 @@ #include #include "p54spi.h" -#include "p54spi_eeprom.h" #include "p54.h" #include "lmac.h" +#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM +#include "p54spi_eeprom.h" +#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */ + MODULE_FIRMWARE("3826.arm"); MODULE_ALIAS("stlc45xx"); @@ -195,9 +198,13 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev) ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev); if (ret < 0) { +#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM dev_info(&priv->spi->dev, "loading default eeprom...\n"); ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom, sizeof(p54spi_eeprom)); +#else + dev_err(&priv->spi->dev, "Failed to request user eeprom\n"); +#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */ } else { dev_info(&priv->spi->dev, "loading user eeprom...\n"); ret = p54_parse_eeprom(dev, (void *) eeprom->data, diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h index 1ea1050911d97a54c456e566c6b539e249af8f29..d592cbd34d78069911d0fc9c12dca390b09e970a 100644 --- a/drivers/net/wireless/p54/p54spi_eeprom.h +++ b/drivers/net/wireless/p54/p54spi_eeprom.h @@ -671,7 +671,7 @@ static unsigned char p54spi_eeprom[] = { 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, /* PDR_END */ - 0xa8, 0xf5 /* bogus data */ + 0x67, 0x99, }; #endif /* P54SPI_EEPROM_H */ diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index ad595958b7df19f144a38671cc0424551aaba709..d5bc21e5a02c7520d6599ad5822eafe85b267823 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -33,8 +33,17 @@ MODULE_ALIAS("prism54usb"); MODULE_FIRMWARE("isl3886usb"); MODULE_FIRMWARE("isl3887usb"); +/* + * Note: + * + * Always update our wiki's device list (located at: + * http://wireless.kernel.org/en/users/Drivers/p54/devices ), + * whenever you add a new device. + */ + static struct usb_device_id p54u_table[] __devinitdata = { /* Version 1 devices (pci chip + net2280) */ + {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ @@ -47,7 +56,9 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ + {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ + {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ @@ -60,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ + {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ @@ -80,6 +92,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ + {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ @@ -930,8 +943,8 @@ static int __devinit p54u_probe(struct usb_interface *intf, #ifdef CONFIG_PM /* ISL3887 needs a full reset on resume */ udev->reset_resume = 1; +#endif /* CONFIG_PM */ err = p54u_device_reset(dev); -#endif priv->hw_type = P54U_3887; dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr); diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 0e937dc0c9c41df6cff985c6b538f6cb17cf1091..76b2318a7dc776a460c335133289953cff8806fc 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c @@ -275,15 +275,15 @@ static int p54_rssi_to_dbm(struct p54_common *priv, int rssi) { int band = priv->hw->conf.channel->band; - if (priv->rxhw != 5) + if (priv->rxhw != 5) { return ((rssi * priv->rssical_db[band].mul) / 64 + priv->rssical_db[band].add) / 4; - else + } else { /* * TODO: find the correct formula */ - return ((rssi * priv->rssical_db[band].mul) / 64 + - priv->rssical_db[band].add) / 4; + return rssi / 2 - 110; + } } /* @@ -683,14 +683,15 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb, } } -static u8 p54_convert_algo(enum ieee80211_key_alg alg) +static u8 p54_convert_algo(u32 cipher) { - switch (alg) { - case ALG_WEP: + switch (cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: return P54_CRYPTO_WEP; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: return P54_CRYPTO_TKIPMICHAEL; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: return P54_CRYPTO_AESCCMP; default: return 0; @@ -731,7 +732,7 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) if (info->control.hw_key) { crypt_offset = ieee80211_get_hdrlen_from_skb(skb); - if (info->control.hw_key->alg == ALG_TKIP) { + if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { u8 *iv = (u8 *)(skb->data + crypt_offset); /* * The firmware excepts that the IV has to have @@ -827,10 +828,10 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) hdr->tries = ridx; txhdr->rts_rate_idx = 0; if (info->control.hw_key) { - txhdr->key_type = p54_convert_algo(info->control.hw_key->alg); + txhdr->key_type = p54_convert_algo(info->control.hw_key->cipher); txhdr->key_len = min((u8)16, info->control.hw_key->keylen); memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len); - if (info->control.hw_key->alg == ALG_TKIP) { + if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { /* reserve space for the MIC key */ len += 8; memcpy(skb_put(skb, 8), &(info->control.hw_key->key diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 77cd65db8500b2363496721702777cd280e3bb15..d97a2caf582b3997f2378434117758a928cefbd3 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -3234,7 +3234,7 @@ prism54_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) switch (cmd) { case PRISM54_HOSTAPD: if (!capable(CAP_NET_ADMIN)) - return -EPERM; + return -EPERM; ret = prism54_hostapd(ndev, &wrq->u.data); return ret; } diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 46da03753fd5ee25874c92752bbc241b0e3a0fef..97007d9e2c1fa23b9a22152260931465b21f7cb8 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -79,8 +78,6 @@ static int ray_dev_config(struct net_device *dev, struct ifmap *map); static struct net_device_stats *ray_get_stats(struct net_device *dev); static int ray_dev_init(struct net_device *dev); -static const struct ethtool_ops netdev_ethtool_ops; - static int ray_open(struct net_device *dev); static netdev_tx_t ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev); @@ -189,7 +186,7 @@ module_param(bc, int, 0); module_param(phy_addr, charp, 0); module_param(ray_mem_speed, int, 0); -static UCHAR b5_default_startup_parms[] = { +static const UCHAR b5_default_startup_parms[] = { 0, 0, /* Adhoc station */ 'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */ 0, 0, 0, 0, 0, 0, 0, 0, @@ -224,7 +221,7 @@ static UCHAR b5_default_startup_parms[] = { 2, 0, 0, 0, 0, 0, 0, 0 /* basic rate set */ }; -static UCHAR b4_default_startup_parms[] = { +static const UCHAR b4_default_startup_parms[] = { 0, 0, /* Adhoc station */ 'L', 'I', 'N', 'U', 'X', 0, 0, 0, /* 32 char ESSID */ 0, 0, 0, 0, 0, 0, 0, 0, @@ -256,9 +253,9 @@ static UCHAR b4_default_startup_parms[] = { }; /*===========================================================================*/ -static unsigned char eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 }; +static const u8 eth2_llc[] = { 0xaa, 0xaa, 3, 0, 0, 0 }; -static char hop_pattern_length[] = { 1, +static const char hop_pattern_length[] = { 1, USA_HOP_MOD, EUROPE_HOP_MOD, JAPAN_HOP_MOD, KOREA_HOP_MOD, SPAIN_HOP_MOD, FRANCE_HOP_MOD, @@ -266,7 +263,7 @@ static char hop_pattern_length[] = { 1, JAPAN_TEST_HOP_MOD }; -static char rcsid[] = +static const char rcsid[] = "Raylink/WebGear wireless LAN - Corey "; static const struct net_device_ops ray_netdev_ops = { @@ -316,7 +313,6 @@ static int ray_probe(struct pcmcia_device *p_dev) /* Raylink entries in the device structure */ dev->netdev_ops = &ray_netdev_ops; - SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); dev->wireless_handlers = &ray_handler_def; #ifdef WIRELESS_SPY local->wireless_data.spy_data = &local->spy_data; @@ -575,7 +571,7 @@ static int dl_startup_params(struct net_device *dev) /* Start kernel timer to wait for dl startup to complete. */ local->timer.expires = jiffies + HZ / 2; local->timer.data = (long)local; - local->timer.function = &verify_dl_startup; + local->timer.function = verify_dl_startup; add_timer(&local->timer); dev_dbg(&link->dev, "ray_cs dl_startup_params started timer for verify_dl_startup\n"); @@ -1025,18 +1021,6 @@ AP to AP 1 1 dest AP src AP dest source } } /* end encapsulate_frame */ -/*===========================================================================*/ - -static void netdev_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "ray_cs"); -} - -static const struct ethtool_ops netdev_ethtool_ops = { - .get_drvinfo = netdev_get_drvinfo, -}; - /*====================================================================*/ /*------------------------------------------------------------------*/ @@ -1960,12 +1944,12 @@ static irqreturn_t ray_interrupt(int irq, void *dev_id) dev_dbg(&link->dev, "ray_cs interrupt network \"%s\" start failed\n", local->sparm.b4.a_current_ess_id); - local->timer.function = &start_net; + local->timer.function = start_net; } else { dev_dbg(&link->dev, "ray_cs interrupt network \"%s\" join failed\n", local->sparm.b4.a_current_ess_id); - local->timer.function = &join_net; + local->timer.function = join_net; } add_timer(&local->timer); } @@ -2433,9 +2417,9 @@ static void authenticate(ray_dev_t *local) del_timer(&local->timer); if (build_auth_frame(local, local->bss_id, OPEN_AUTH_REQUEST)) { - local->timer.function = &join_net; + local->timer.function = join_net; } else { - local->timer.function = &authenticate_timeout; + local->timer.function = authenticate_timeout; } local->timer.expires = jiffies + HZ * 2; local->timer.data = (long)local; @@ -2520,7 +2504,7 @@ static void associate(ray_dev_t *local) del_timer(&local->timer); local->timer.expires = jiffies + HZ * 2; local->timer.data = (long)local; - local->timer.function = &join_net; + local->timer.function = join_net; add_timer(&local->timer); local->card_status = CARD_ASSOC_FAILED; return; @@ -2554,7 +2538,7 @@ static void clear_interrupt(ray_dev_t *local) #ifdef CONFIG_PROC_FS #define MAXDATA (PAGE_SIZE - 80) -static char *card_status[] = { +static const char *card_status[] = { "Card inserted - uninitialized", /* 0 */ "Card not downloaded", /* 1 */ "Waiting for download parameters", /* 2 */ @@ -2571,8 +2555,8 @@ static char *card_status[] = { "Association failed" /* 16 */ }; -static char *nettype[] = { "Adhoc", "Infra " }; -static char *framing[] = { "Encapsulation", "Translation" } +static const char *nettype[] = { "Adhoc", "Infra " }; +static const char *framing[] = { "Encapsulation", "Translation" } ; /*===========================================================================*/ diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 719573bbbf81fce6e21560465702cbff814847f4..71b5971da5970b2300c29a185c9836f394f227af 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -540,11 +540,11 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type); static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr, - struct key_params *params); + u8 key_index, bool pairwise, const u8 *mac_addr, + struct key_params *params); static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr); + u8 key_index, bool pairwise, const u8 *mac_addr); static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); @@ -2308,8 +2308,8 @@ static int rndis_set_channel(struct wiphy *wiphy, struct net_device *netdev, } static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr, - struct key_params *params) + u8 key_index, bool pairwise, const u8 *mac_addr, + struct key_params *params) { struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; @@ -2344,7 +2344,7 @@ static int rndis_add_key(struct wiphy *wiphy, struct net_device *netdev, } static int rndis_del_key(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr) + u8 key_index, bool pairwise, const u8 *mac_addr) { struct rndis_wlan_private *priv = wiphy_priv(wiphy); struct usbnet *usbdev = priv->usbdev; diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 5063e01410e5b76640946aea9d1722d0543c2aa5..4f420a9ec5dc26f9b8f1bb663a3c39aaccf54330 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -321,7 +321,8 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { int preamble_mask; u32 reg; @@ -329,59 +330,72 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, /* * When short preamble is enabled, we should set bit 0x08 */ - preamble_mask = erp->short_preamble << 3; - - rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); - rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); - rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); - rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); - rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); - rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); - rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); - rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); - rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); - rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); - rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); - rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); - rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); - rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); - rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); - rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); - rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); - - rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + preamble_mask = erp->short_preamble << 3; + + rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); + rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x1ff); + rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0x13a); + rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); + rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); + rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); + rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 10)); + rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); + rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); + rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 20)); + rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); + rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); + rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 55)); + rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); + rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); + rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 110)); + rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); + } - rt2x00pci_register_read(rt2x00dev, CSR11, ®); - rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); - rt2x00pci_register_read(rt2x00dev, CSR12, ®); - rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); - rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, CSR12, reg); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); + rt2x00pci_register_write(rt2x00dev, CSR11, reg); - rt2x00pci_register_read(rt2x00dev, CSR18, ®); - rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); - rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); - rt2x00pci_register_write(rt2x00dev, CSR18, reg); + rt2x00pci_register_read(rt2x00dev, CSR18, ®); + rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); + rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); + rt2x00pci_register_write(rt2x00dev, CSR18, reg); + + rt2x00pci_register_read(rt2x00dev, CSR19, ®); + rt2x00_set_field32(®, CSR19_DIFS, erp->difs); + rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); + rt2x00pci_register_write(rt2x00dev, CSR19, reg); + } - rt2x00pci_register_read(rt2x00dev, CSR19, ®); - rt2x00_set_field32(®, CSR19_DIFS, erp->difs); - rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, CSR19, reg); + if (changed & BSS_CHANGED_BEACON_INT) { + rt2x00pci_register_read(rt2x00dev, CSR12, ®); + rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, + erp->beacon_int * 16); + rt2x00pci_register_write(rt2x00dev, CSR12, reg); + } } static void rt2400pci_config_ant(struct rt2x00_dev *rt2x00dev, @@ -1007,12 +1021,11 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2400pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1091,12 +1104,12 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, CSR14, reg); - rt2x00queue_map_txskb(rt2x00dev, entry->skb); + rt2x00queue_map_txskb(entry); /* * Write the TX descriptor for the beacon. */ - rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt2400pci_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -1112,24 +1125,24 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, rt2x00pci_register_write(rt2x00dev, CSR14, reg); } -static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue) +static void rt2400pci_kick_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); - rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); } -static void rt2400pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt2400pci_kill_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; - if (qid == QID_BEACON) { + if (queue->qid == QID_BEACON) { rt2x00pci_register_write(rt2x00dev, CSR14, 0); } else { rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); @@ -1481,15 +1494,17 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER); + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } return 0; } diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index c2a555d5376b3bbe4738813225a695d8fd81eac0..97feb7aef80929946714e97ed8931bf514487109 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c @@ -327,7 +327,8 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { int preamble_mask; u32 reg; @@ -335,59 +336,73 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, /* * When short preamble is enabled, we should set bit 0x08 */ - preamble_mask = erp->short_preamble << 3; - - rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); - rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); - rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); - rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); - rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); - rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); - rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); - rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); - rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); - rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); - rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); - rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); - rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); - rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); - rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); - - rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); - rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); - rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); - rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); - rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); - - rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + preamble_mask = erp->short_preamble << 3; + + rt2x00pci_register_read(rt2x00dev, TXCSR1, ®); + rt2x00_set_field32(®, TXCSR1_ACK_TIMEOUT, 0x162); + rt2x00_set_field32(®, TXCSR1_ACK_CONSUME_TIME, 0xa2); + rt2x00_set_field32(®, TXCSR1_TSF_OFFSET, IEEE80211_HEADER); + rt2x00_set_field32(®, TXCSR1_AUTORESPONDER, 1); + rt2x00pci_register_write(rt2x00dev, TXCSR1, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); + rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); + rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 10)); + rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); + rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); + rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 20)); + rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); + rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); + rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 55)); + rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); + + rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); + rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); + rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); + rt2x00_set_field32(®, ARCSR2_LENGTH, + GET_DURATION(ACK_SIZE, 110)); + rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); + } - rt2x00pci_register_read(rt2x00dev, CSR11, ®); - rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, CSR11, reg); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); - rt2x00pci_register_read(rt2x00dev, CSR12, ®); - rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, erp->beacon_int * 16); - rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, CSR12, reg); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2x00pci_register_read(rt2x00dev, CSR11, ®); + rt2x00_set_field32(®, CSR11_SLOT_TIME, erp->slot_time); + rt2x00pci_register_write(rt2x00dev, CSR11, reg); - rt2x00pci_register_read(rt2x00dev, CSR18, ®); - rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); - rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); - rt2x00pci_register_write(rt2x00dev, CSR18, reg); + rt2x00pci_register_read(rt2x00dev, CSR18, ®); + rt2x00_set_field32(®, CSR18_SIFS, erp->sifs); + rt2x00_set_field32(®, CSR18_PIFS, erp->pifs); + rt2x00pci_register_write(rt2x00dev, CSR18, reg); + + rt2x00pci_register_read(rt2x00dev, CSR19, ®); + rt2x00_set_field32(®, CSR19_DIFS, erp->difs); + rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); + rt2x00pci_register_write(rt2x00dev, CSR19, reg); + } + + if (changed & BSS_CHANGED_BEACON_INT) { + rt2x00pci_register_read(rt2x00dev, CSR12, ®); + rt2x00_set_field32(®, CSR12_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2x00_set_field32(®, CSR12_CFP_MAX_DURATION, + erp->beacon_int * 16); + rt2x00pci_register_write(rt2x00dev, CSR12, reg); + } - rt2x00pci_register_read(rt2x00dev, CSR19, ®); - rt2x00_set_field32(®, CSR19_DIFS, erp->difs); - rt2x00_set_field32(®, CSR19_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, CSR19, reg); } static void rt2500pci_config_ant(struct rt2x00_dev *rt2x00dev, @@ -1161,12 +1176,11 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2500pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1244,12 +1258,12 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, rt2x00_set_field32(®, CSR14_BEACON_GEN, 0); rt2x00pci_register_write(rt2x00dev, CSR14, reg); - rt2x00queue_map_txskb(rt2x00dev, entry->skb); + rt2x00queue_map_txskb(entry); /* * Write the TX descriptor for the beacon. */ - rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt2500pci_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -1265,24 +1279,24 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, rt2x00pci_register_write(rt2x00dev, CSR14, reg); } -static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue) +static void rt2500pci_kick_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); - rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue == QID_AC_BE)); - rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue == QID_AC_BK)); - rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue == QID_ATIM)); + rt2x00_set_field32(®, TXCSR0_KICK_PRIO, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, TXCSR0_KICK_TX, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, TXCSR0_KICK_ATIM, (queue->qid == QID_ATIM)); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); } -static void rt2500pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt2500pci_kill_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; - if (qid == QID_BEACON) { + if (queue->qid == QID_BEACON) { rt2x00pci_register_write(rt2x00dev, CSR14, 0); } else { rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); @@ -1795,19 +1809,23 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } if (spec->num_channels > 14) { - for (i = 14; i < spec->num_channels; i++) - info[i].tx_power1 = DEFAULT_TXPOWER; + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = DEFAULT_TXPOWER; + } } return 0; diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index cdaf93f48263c012649b30d6b72604ac0b853f64..93e44c7f3a749ac5962fb4c6079ee7e8f0493163 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c @@ -355,7 +355,9 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, * it is known that not work at least on some hardware. * SW crypto will be used in that case. */ - if (key->alg == ALG_WEP && key->keyidx != 0) + if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 || + key->cipher == WLAN_CIPHER_SUITE_WEP104) && + key->keyidx != 0) return -EOPNOTSUPP; /* @@ -492,24 +494,34 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { u16 reg; - rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); - rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, - !!erp->short_preamble); - rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rt2500usb_register_read(rt2x00dev, TXRX_CSR10, ®); + rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, + !!erp->short_preamble); + rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); + } - rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2500usb_register_write(rt2x00dev, TXRX_CSR11, + erp->basic_rates); - rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); - rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, erp->beacon_int * 4); - rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); + if (changed & BSS_CHANGED_BEACON_INT) { + rt2500usb_register_read(rt2x00dev, TXRX_CSR18, ®); + rt2x00_set_field16(®, TXRX_CSR18_INTERVAL, + erp->beacon_int * 4); + rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg); + } - rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time); - rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs); - rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time); + rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs); + rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs); + } } static void rt2500usb_config_ant(struct rt2x00_dev *rt2x00dev, @@ -1039,12 +1051,11 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2500usb_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txd = (__le32 *) skb->data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + __le32 *txd = (__le32 *) entry->skb->data; u32 word; /* @@ -1127,7 +1138,7 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, /* * Write the TX descriptor for the beacon. */ - rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt2500usb_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -1195,6 +1206,14 @@ static int rt2500usb_get_tx_data_len(struct queue_entry *entry) return length; } +static void rt2500usb_kill_tx_queue(struct data_queue *queue) +{ + if (queue->qid == QID_BEACON) + rt2500usb_register_write(queue->rt2x00dev, TXRX_CSR19, 0); + + rt2x00usb_kill_tx_queue(queue); +} + /* * RX control handlers */ @@ -1655,10 +1674,15 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Initialize all hw fields. + * + * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are + * capable of sending the buffered frames out after the DTIM + * transmission using rt2x00lib_beacondone. This will send out + * multicast and broadcast traffic immediately instead of buffering it + * infinitly and thus dropping it after some time. */ rt2x00dev->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK; @@ -1698,19 +1722,23 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } if (spec->num_channels > 14) { - for (i = 14; i < spec->num_channels; i++) - info[i].tx_power1 = DEFAULT_TXPOWER; + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = DEFAULT_TXPOWER; + } } return 0; @@ -1789,7 +1817,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { .write_beacon = rt2500usb_write_beacon, .get_tx_data_len = rt2500usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2x00usb_kill_tx_queue, + .kill_tx_queue = rt2500usb_kill_tx_queue, .fill_rxdone = rt2500usb_fill_rxdone, .config_shared_key = rt2500usb_config_key, .config_pairwise_key = rt2500usb_config_key, diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index ed4ebcdde7c9c4155c58807cd5aae839a39ea63e..eb8b6cab992516fa8bdf58d2feabcf44950585f3 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2004 - 2010 Ivo van Doorn + Copyright (C) 2010 Willow Garage Copyright (C) 2009 Alban Browaeys Copyright (C) 2009 Felix Fietkau Copyright (C) 2009 Luis Correia @@ -638,6 +639,18 @@ #define LED_CFG_Y_LED_MODE FIELD32(0x30000000) #define LED_CFG_LED_POLAR FIELD32(0x40000000) +/* + * AMPDU_BA_WINSIZE: Force BlockAck window size + * FORCE_WINSIZE_ENABLE: + * 0: Disable forcing of BlockAck window size + * 1: Enable forcing of BlockAck window size, overwrites values BlockAck + * window size values in the TXWI + * FORCE_WINSIZE: BlockAck window size + */ +#define AMPDU_BA_WINSIZE 0x1040 +#define AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE FIELD32(0x00000020) +#define AMPDU_BA_WINSIZE_FORCE_WINSIZE FIELD32(0x0000001f) + /* * XIFS_TIME_CFG: MAC timing * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX @@ -698,8 +711,14 @@ /* * TBTT_SYNC_CFG: + * BCN_AIFSN: Beacon AIFSN after TBTT interrupt in slots + * BCN_CWMIN: Beacon CWMin after TBTT interrupt in slots */ #define TBTT_SYNC_CFG 0x1118 +#define TBTT_SYNC_CFG_TBTT_ADJUST FIELD32(0x000000ff) +#define TBTT_SYNC_CFG_BCN_EXP_WIN FIELD32(0x0000ff00) +#define TBTT_SYNC_CFG_BCN_AIFSN FIELD32(0x000f0000) +#define TBTT_SYNC_CFG_BCN_CWMIN FIELD32(0x00f00000) /* * TSF_TIMER_DW0: Local lsb TSF timer, read-only @@ -735,15 +754,20 @@ #define INT_TIMER_EN_GP_TIMER FIELD32(0x00000002) /* - * CH_IDLE_STA: channel idle time + * CH_IDLE_STA: channel idle time (in us) */ #define CH_IDLE_STA 0x1130 /* - * CH_BUSY_STA: channel busy time + * CH_BUSY_STA: channel busy time on primary channel (in us) */ #define CH_BUSY_STA 0x1134 +/* + * CH_BUSY_STA_SEC: channel busy time on secondary channel in HT40 mode (in us) + */ +#define CH_BUSY_STA_SEC 0x1138 + /* * MAC_STATUS_CFG: * BBP_RF_BUSY: When set to 0, BBP and RF are stable. @@ -1318,11 +1342,34 @@ #define TX_STA_CNT2_TX_UNDER_FLOW_COUNT FIELD32(0xffff0000) /* - * TX_STA_FIFO: TX Result for specific PID status fifo register + * TX_STA_FIFO: TX Result for specific PID status fifo register. + * + * This register is implemented as FIFO with 16 entries in the HW. Each + * register read fetches the next tx result. If the FIFO is full because + * it wasn't read fast enough after the according interrupt (TX_FIFO_STATUS) + * triggered, the hw seems to simply drop further tx results. + * + * VALID: 1: this tx result is valid + * 0: no valid tx result -> driver should stop reading + * PID_TYPE: The PID latched from the PID field in the TXWI, can be used + * to match a frame with its tx result (even though the PID is + * only 4 bits wide). + * PID_QUEUE: Part of PID_TYPE, this is the queue index number (0-3) + * PID_ENTRY: Part of PID_TYPE, this is the queue entry index number (1-3) + * This identification number is calculated by ((idx % 3) + 1). + * TX_SUCCESS: Indicates tx success (1) or failure (0) + * TX_AGGRE: Indicates if the frame was part of an aggregate (1) or not (0) + * TX_ACK_REQUIRED: Indicates if the frame needed to get ack'ed (1) or not (0) + * WCID: The wireless client ID. + * MCS: The tx rate used during the last transmission of this frame, be it + * successful or not. + * PHYMODE: The phymode used for the transmission. */ #define TX_STA_FIFO 0x1718 #define TX_STA_FIFO_VALID FIELD32(0x00000001) #define TX_STA_FIFO_PID_TYPE FIELD32(0x0000001e) +#define TX_STA_FIFO_PID_QUEUE FIELD32(0x00000006) +#define TX_STA_FIFO_PID_ENTRY FIELD32(0x00000018) #define TX_STA_FIFO_TX_SUCCESS FIELD32(0x00000020) #define TX_STA_FIFO_TX_AGGRE FIELD32(0x00000040) #define TX_STA_FIFO_TX_ACK_REQUIRED FIELD32(0x00000080) @@ -1405,6 +1452,24 @@ /* * Security key table memory. + * + * The pairwise key table shares some memory with the beacon frame + * buffers 6 and 7. That basically means that when beacon 6 & 7 + * are used we should only use the reduced pairwise key table which + * has a maximum of 222 entries. + * + * --------------------------------------------- + * |0x4000 | Pairwise Key | Reduced Pairwise | + * | | Table | Key Table | + * | | Size: 256 * 32 | Size: 222 * 32 | + * |0x5BC0 | |------------------- + * | | | Beacon 6 | + * |0x5DC0 | |------------------- + * | | | Beacon 7 | + * |0x5FC0 | |------------------- + * |0x5FFF | | + * -------------------------- + * * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry @@ -1554,7 +1619,8 @@ struct mac_iveiv_entry { * 2. Extract memory from FCE table for BCN 4~5 * 3. Extract memory from Pair-wise key table for BCN 6~7 * It occupied those memory of wcid 238~253 for BCN 6 - * and wcid 222~237 for BCN 7 + * and wcid 222~237 for BCN 7 (see Security key table memory + * for more info). * * IMPORTANT NOTE: Not sure why legacy driver does this, * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6. @@ -1840,6 +1906,13 @@ struct mac_iveiv_entry { #define EEPROM_RSSI_A2_OFFSET2 FIELD16(0x00ff) #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) +/* + * EEPROM Maximum TX power values + */ +#define EEPROM_MAX_TX_POWER 0x0027 +#define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff) +#define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00) + /* * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. * This is delta in 40MHZ. @@ -1926,8 +1999,17 @@ struct mac_iveiv_entry { * FRAG: 1 To inform TKIP engine this is a fragment. * MIMO_PS: The remote peer is in dynamic MIMO-PS mode * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs - * BW: Channel bandwidth 20MHz or 40 MHz + * BW: Channel bandwidth 0:20MHz, 1:40 MHz (for legacy rates this will + * duplicate the frame to both channels). * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED + * AMPDU: 1: this frame is eligible for AMPDU aggregation, the hw will + * aggregate consecutive frames with the same RA and QoS TID. If + * a frame A with the same RA and QoS TID but AMPDU=0 is queued + * directly after a frame B with AMPDU=1, frame A might still + * get aggregated into the AMPDU started by frame B. So, setting + * AMPDU to 0 does _not_ necessarily mean the frame is sent as + * MPDU, it can still end up in an AMPDU if the previous frame + * was tagged as AMPDU. */ #define TXWI_W0_FRAG FIELD32(0x00000001) #define TXWI_W0_MIMO_PS FIELD32(0x00000002) @@ -1945,6 +2027,19 @@ struct mac_iveiv_entry { /* * Word1 + * ACK: 0: No Ack needed, 1: Ack needed + * NSEQ: 0: Don't assign hw sequence number, 1: Assign hw sequence number + * BW_WIN_SIZE: BA windows size of the recipient + * WIRELESS_CLI_ID: Client ID for WCID table access + * MPDU_TOTAL_BYTE_COUNT: Length of 802.11 frame + * PACKETID: Will be latched into the TX_STA_FIFO register once the according + * frame was processed. If multiple frames are aggregated together + * (AMPDU==1) the reported tx status will always contain the packet + * id of the first frame. 0: Don't report tx status for this frame. + * PACKETID_QUEUE: Part of PACKETID, This is the queue index (0-3) + * PACKETID_ENTRY: Part of PACKETID, THis is the queue entry index (1-3) + * This identification number is calculated by ((idx % 3) + 1). + * The (+1) is required to prevent PACKETID to become 0. */ #define TXWI_W1_ACK FIELD32(0x00000001) #define TXWI_W1_NSEQ FIELD32(0x00000002) @@ -1952,6 +2047,8 @@ struct mac_iveiv_entry { #define TXWI_W1_WIRELESS_CLI_ID FIELD32(0x0000ff00) #define TXWI_W1_MPDU_TOTAL_BYTE_COUNT FIELD32(0x0fff0000) #define TXWI_W1_PACKETID FIELD32(0xf0000000) +#define TXWI_W1_PACKETID_QUEUE FIELD32(0x30000000) +#define TXWI_W1_PACKETID_ENTRY FIELD32(0xc0000000) /* * Word2 diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index b66e0fd8f0fa178f2d18544a2dc3e192c7c00b93..5f00e00789d823bad28752516a4789da7057d8f9 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -1,4 +1,5 @@ /* + Copyright (C) 2010 Willow Garage Copyright (C) 2010 Ivo van Doorn Copyright (C) 2009 Bartlomiej Zolnierkiewicz Copyright (C) 2009 Gertjan van Wingerde @@ -254,6 +255,23 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2800_mcu_request); +int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev) +{ + unsigned int i = 0; + u32 reg; + + for (i = 0; i < REGISTER_BUSY_COUNT; i++) { + rt2800_register_read(rt2x00dev, MAC_CSR0, ®); + if (reg && reg != ~0) + return 0; + msleep(1); + } + + ERROR(rt2x00dev, "Unstable hardware.\n"); + return -EBUSY; +} +EXPORT_SYMBOL_GPL(rt2800_wait_csr_ready); + int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) { unsigned int i; @@ -367,19 +385,16 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, u32 reg; /* - * Wait for stable hardware. + * If driver doesn't wake up firmware here, + * rt2800_load_firmware will hang forever when interface is up again. */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (reg && reg != ~0) - break; - msleep(1); - } + rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "Unstable hardware.\n"); + /* + * Wait for stable hardware. + */ + if (rt2800_wait_csr_ready(rt2x00dev)) return -EBUSY; - } if (rt2x00_is_pci(rt2x00dev)) rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); @@ -427,8 +442,10 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, } EXPORT_SYMBOL_GPL(rt2800_load_firmware); -void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) +void rt2800_write_tx_data(struct queue_entry *entry, + struct txentry_desc *txdesc) { + __le32 *txwi = rt2800_drv_get_txwi(entry); u32 word; /* @@ -437,7 +454,8 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) rt2x00_desc_read(txwi, 0, &word); rt2x00_set_field32(&word, TXWI_W0_FRAG, test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); - rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0); + rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, + test_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags)); rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0); rt2x00_set_field32(&word, TXWI_W0_TS, test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags)); @@ -465,7 +483,8 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) txdesc->key_idx : 0xff); rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT, txdesc->length); - rt2x00_set_field32(&word, TXWI_W1_PACKETID, txdesc->queue + 1); + rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, txdesc->qid); + rt2x00_set_field32(&word, TXWI_W1_PACKETID_ENTRY, (entry->entry_idx % 3) + 1); rt2x00_desc_write(txwi, 1, word); /* @@ -478,9 +497,9 @@ void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */); _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */); } -EXPORT_SYMBOL_GPL(rt2800_write_txwi); +EXPORT_SYMBOL_GPL(rt2800_write_tx_data); -static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) +static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, u32 rxwi_w2) { int rssi0 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI0); int rssi1 = rt2x00_get_field32(rxwi_w2, RXWI_W2_RSSI1); @@ -490,7 +509,7 @@ static int rt2800_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxwi_w2) u8 offset1; u8 offset2; - if (rt2x00dev->rx_status.band == IEEE80211_BAND_2GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) { rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &eeprom); offset0 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET0); offset1 = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG_OFFSET1); @@ -569,6 +588,181 @@ void rt2800_process_rxwi(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2800_process_rxwi); +static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) +{ + __le32 *txwi; + u32 word; + int wcid, ack, pid; + int tx_wcid, tx_ack, tx_pid; + + wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); + ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); + + /* + * This frames has returned with an IO error, + * so the status report is not intended for this + * frame. + */ + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + return false; + } + + /* + * Validate if this TX status report is intended for + * this entry by comparing the WCID/ACK/PID fields. + */ + txwi = rt2800_drv_get_txwi(entry); + + rt2x00_desc_read(txwi, 1, &word); + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); + tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); + tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); + + if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { + WARNING(entry->queue->rt2x00dev, + "TX status report missed for queue %d entry %d\n", + entry->queue->qid, entry->entry_idx); + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); + return false; + } + + return true; +} + +void rt2800_txdone_entry(struct queue_entry *entry, u32 status) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct txdone_entry_desc txdesc; + u32 word; + u16 mcs, real_mcs; + int aggr, ampdu; + __le32 *txwi; + + /* + * Obtain the status about this packet. + */ + txdesc.flags = 0; + txwi = rt2800_drv_get_txwi(entry); + rt2x00_desc_read(txwi, 0, &word); + + mcs = rt2x00_get_field32(word, TXWI_W0_MCS); + ampdu = rt2x00_get_field32(word, TXWI_W0_AMPDU); + + real_mcs = rt2x00_get_field32(status, TX_STA_FIFO_MCS); + aggr = rt2x00_get_field32(status, TX_STA_FIFO_TX_AGGRE); + + /* + * If a frame was meant to be sent as a single non-aggregated MPDU + * but ended up in an aggregate the used tx rate doesn't correlate + * with the one specified in the TXWI as the whole aggregate is sent + * with the same rate. + * + * For example: two frames are sent to rt2x00, the first one sets + * AMPDU=1 and requests MCS7 whereas the second frame sets AMDPU=0 + * and requests MCS15. If the hw aggregates both frames into one + * AMDPU the tx status for both frames will contain MCS7 although + * the frame was sent successfully. + * + * Hence, replace the requested rate with the real tx rate to not + * confuse the rate control algortihm by providing clearly wrong + * data. + */ + if (aggr == 1 && ampdu == 0 && real_mcs != mcs) { + skbdesc->tx_rate_idx = real_mcs; + mcs = real_mcs; + } + + /* + * Ralink has a retry mechanism using a global fallback + * table. We setup this fallback table to try the immediate + * lower rate for all rates. In the TX_STA_FIFO, the MCS field + * always contains the MCS used for the last transmission, be + * it successful or not. + */ + if (rt2x00_get_field32(status, TX_STA_FIFO_TX_SUCCESS)) { + /* + * Transmission succeeded. The number of retries is + * mcs - real_mcs + */ + __set_bit(TXDONE_SUCCESS, &txdesc.flags); + txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); + } else { + /* + * Transmission failed. The number of retries is + * always 7 in this case (for a total number of 8 + * frames sent). + */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + txdesc.retry = rt2x00dev->long_retry; + } + + /* + * the frame was retried at least once + * -> hw used fallback rates + */ + if (txdesc.retry) + __set_bit(TXDONE_FALLBACK, &txdesc.flags); + + rt2x00lib_txdone(entry, &txdesc); +} +EXPORT_SYMBOL_GPL(rt2800_txdone_entry); + +void rt2800_txdone(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + struct queue_entry *entry; + u32 reg; + u8 pid; + int i; + + /* + * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO + * at most X times and also stop processing once the TX_STA_FIFO_VALID + * flag is not set anymore. + * + * The legacy drivers use X=TX_RING_SIZE but state in a comment + * that the TX_STA_FIFO stack has a size of 16. We stick to our + * tx ring size for now. + */ + for (i = 0; i < TX_ENTRIES; i++) { + rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); + if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) + break; + + /* + * Skip this entry when it contains an invalid + * queue identication number. + */ + pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); + if (pid >= QID_RX) + continue; + + queue = rt2x00queue_get_queue(rt2x00dev, pid); + if (unlikely(!queue)) + continue; + + /* + * Inside each queue, we process each entry in a chronological + * order. We first check that the queue is not empty. + */ + entry = NULL; + while (!rt2x00queue_empty(queue)) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (rt2800_txdone_entry_check(entry, reg)) + break; + } + + if (!entry || rt2x00queue_empty(queue)) + break; + + rt2800_txdone_entry(entry, reg); + } +} +EXPORT_SYMBOL_GPL(rt2800_txdone); + void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; @@ -600,7 +794,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) /* * Add the TXWI for the beacon to the skb. */ - rt2800_write_txwi((__le32 *)entry->skb->data, txdesc); + rt2800_write_tx_data(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -871,8 +1065,12 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev, * 1 pairwise key is possible per AID, this means that the AID * equals our hw_key_idx. Make sure the WCID starts _after_ the * last possible shared key entry. + * + * Since parts of the pairwise key table might be shared with + * the beacon frame buffers 6 & 7 we should only write into the + * first 222 entries. */ - if (crypto->aid > (256 - 32)) + if (crypto->aid > (222 - 32)) return -ENOSPC; key->hw_key_idx = 32 + crypto->aid; @@ -975,19 +1173,23 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, } if (flags & CONFIG_UPDATE_MAC) { - reg = le32_to_cpu(conf->mac[1]); - rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); - conf->mac[1] = cpu_to_le32(reg); + if (!is_zero_ether_addr((const u8 *)conf->mac)) { + reg = le32_to_cpu(conf->mac[1]); + rt2x00_set_field32(®, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff); + conf->mac[1] = cpu_to_le32(reg); + } rt2800_register_multiwrite(rt2x00dev, MAC_ADDR_DW0, conf->mac, sizeof(conf->mac)); } if (flags & CONFIG_UPDATE_BSSID) { - reg = le32_to_cpu(conf->bssid[1]); - rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); - rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); - conf->bssid[1] = cpu_to_le32(reg); + if (!is_zero_ether_addr((const u8 *)conf->bssid)) { + reg = le32_to_cpu(conf->bssid[1]); + rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_ID_MASK, 3); + rt2x00_set_field32(®, MAC_BSSID_DW1_BSS_BCN_NUM, 7); + conf->bssid[1] = cpu_to_le32(reg); + } rt2800_register_multiwrite(rt2x00dev, MAC_BSSID_DW0, conf->bssid, sizeof(conf->bssid)); @@ -995,38 +1197,149 @@ void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, } EXPORT_SYMBOL_GPL(rt2800_config_intf); -void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp) +static void rt2800_config_ht_opmode(struct rt2x00_dev *rt2x00dev, + struct rt2x00lib_erp *erp) { + bool any_sta_nongf = !!(erp->ht_opmode & + IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); + u8 protection = erp->ht_opmode & IEEE80211_HT_OP_MODE_PROTECTION; + u8 mm20_mode, mm40_mode, gf20_mode, gf40_mode; + u16 mm20_rate, mm40_rate, gf20_rate, gf40_rate; u32 reg; - rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); - rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, - !!erp->short_preamble); - rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, - !!erp->short_preamble); - rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); + /* default protection rate for HT20: OFDM 24M */ + mm20_rate = gf20_rate = 0x4004; - rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); - rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, - erp->cts_protection ? 2 : 0); - rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); + /* default protection rate for HT40: duplicate OFDM 24M */ + mm40_rate = gf40_rate = 0x4084; - rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, - erp->basic_rates); - rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); + switch (protection) { + case IEEE80211_HT_OP_MODE_PROTECTION_NONE: + /* + * All STAs in this BSS are HT20/40 but there might be + * STAs not supporting greenfield mode. + * => Disable protection for HT transmissions. + */ + mm20_mode = mm40_mode = gf20_mode = gf40_mode = 0; - rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); - rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time); - rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); + break; + case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ: + /* + * All STAs in this BSS are HT20 or HT20/40 but there + * might be STAs not supporting greenfield mode. + * => Protect all HT40 transmissions. + */ + mm20_mode = gf20_mode = 0; + mm40_mode = gf40_mode = 2; - rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); - rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); - rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); + break; + case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER: + /* + * Nonmember protection: + * According to 802.11n we _should_ protect all + * HT transmissions (but we don't have to). + * + * But if cts_protection is enabled we _shall_ protect + * all HT transmissions using a CCK rate. + * + * And if any station is non GF we _shall_ protect + * GF transmissions. + * + * We decide to protect everything + * -> fall through to mixed mode. + */ + case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED: + /* + * Legacy STAs are present + * => Protect all HT transmissions. + */ + mm20_mode = mm40_mode = gf20_mode = gf40_mode = 2; - rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, - erp->beacon_int * 16); - rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + /* + * If erp protection is needed we have to protect HT + * transmissions with CCK 11M long preamble. + */ + if (erp->cts_protection) { + /* don't duplicate RTS/CTS in CCK mode */ + mm20_rate = mm40_rate = 0x0003; + gf20_rate = gf40_rate = 0x0003; + } + break; + }; + + /* check for STAs not supporting greenfield mode */ + if (any_sta_nongf) + gf20_mode = gf40_mode = 2; + + /* Update HT protection config */ + rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); + rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, mm20_rate); + rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, mm20_mode); + rt2800_register_write(rt2x00dev, MM20_PROT_CFG, reg); + + rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); + rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, mm40_rate); + rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, mm40_mode); + rt2800_register_write(rt2x00dev, MM40_PROT_CFG, reg); + + rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); + rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, gf20_rate); + rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, gf20_mode); + rt2800_register_write(rt2x00dev, GF20_PROT_CFG, reg); + + rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); + rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, gf40_rate); + rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, gf40_mode); + rt2800_register_write(rt2x00dev, GF40_PROT_CFG, reg); +} + +void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, + u32 changed) +{ + u32 reg; + + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rt2800_register_read(rt2x00dev, AUTO_RSP_CFG, ®); + rt2x00_set_field32(®, AUTO_RSP_CFG_BAC_ACK_POLICY, + !!erp->short_preamble); + rt2x00_set_field32(®, AUTO_RSP_CFG_AR_PREAMBLE, + !!erp->short_preamble); + rt2800_register_write(rt2x00dev, AUTO_RSP_CFG, reg); + } + + if (changed & BSS_CHANGED_ERP_CTS_PROT) { + rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); + rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, + erp->cts_protection ? 2 : 0); + rt2800_register_write(rt2x00dev, OFDM_PROT_CFG, reg); + } + + if (changed & BSS_CHANGED_BASIC_RATES) { + rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, + erp->basic_rates); + rt2800_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003); + } + + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2800_register_read(rt2x00dev, BKOFF_SLOT_CFG, ®); + rt2x00_set_field32(®, BKOFF_SLOT_CFG_SLOT_TIME, + erp->slot_time); + rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); + + rt2800_register_read(rt2x00dev, XIFS_TIME_CFG, ®); + rt2x00_set_field32(®, XIFS_TIME_CFG_EIFS, erp->eifs); + rt2800_register_write(rt2x00dev, XIFS_TIME_CFG, reg); + } + + if (changed & BSS_CHANGED_BEACON_INT) { + rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } + + if (changed & BSS_CHANGED_HT) + rt2800_config_ht_opmode(rt2x00dev, erp); } EXPORT_SYMBOL_GPL(rt2800_config_erp); @@ -1120,27 +1433,23 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, * double meaning, and we should set a 7DBm boost flag. */ rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST, - (info->tx_power1 >= 0)); + (info->default_power1 >= 0)); - if (info->tx_power1 < 0) - info->tx_power1 += 7; + if (info->default_power1 < 0) + info->default_power1 += 7; - rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, - TXPOWER_A_TO_DEV(info->tx_power1)); + rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A, info->default_power1); rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST, - (info->tx_power2 >= 0)); + (info->default_power2 >= 0)); - if (info->tx_power2 < 0) - info->tx_power2 += 7; + if (info->default_power2 < 0) + info->default_power2 += 7; - rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, - TXPOWER_A_TO_DEV(info->tx_power2)); + rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A, info->default_power2); } else { - rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, - TXPOWER_G_TO_DEV(info->tx_power1)); - rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, - TXPOWER_G_TO_DEV(info->tx_power2)); + rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G, info->default_power1); + rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G, info->default_power2); } rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf)); @@ -1180,13 +1489,11 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, - TXPOWER_G_TO_DEV(info->tx_power1)); + rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, info->default_power1); rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, - TXPOWER_G_TO_DEV(info->tx_power2)); + rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, info->default_power2); rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); @@ -1210,10 +1517,19 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, unsigned int tx_pin; u8 bbp; + if (rf->channel <= 14) { + info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); + info->default_power2 = TXPOWER_G_TO_DEV(info->default_power2); + } else { + info->default_power1 = TXPOWER_A_TO_DEV(info->default_power1); + info->default_power2 = TXPOWER_A_TO_DEV(info->default_power2); + } + if (rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3020) || rt2x00_rf(rt2x00dev, RF3021) || - rt2x00_rf(rt2x00dev, RF3022)) + rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3052)) rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); else rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); @@ -1536,7 +1852,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner); /* * Initialization functions. */ -int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) +static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; u16 eeprom; @@ -1728,8 +2044,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); - rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, - !rt2x00_is_usb(rt2x00dev)); + rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0); rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1); rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); @@ -1885,6 +2200,14 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, LG_FBK_CFG0_CCKMCS3FBK, 2); rt2800_register_write(rt2x00dev, LG_FBK_CFG1, reg); + /* + * Do not force the BA window size, we use the TXWI to set it + */ + rt2800_register_read(rt2x00dev, AMPDU_BA_WINSIZE, ®); + rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE_ENABLE, 0); + rt2x00_set_field32(®, AMPDU_BA_WINSIZE_FORCE_WINSIZE, 0); + rt2800_register_write(rt2x00dev, AMPDU_BA_WINSIZE, reg); + /* * We must clear the error counters. * These registers are cleared on read, @@ -1906,7 +2229,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) return 0; } -EXPORT_SYMBOL_GPL(rt2800_init_registers); static int rt2800_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev) { @@ -1949,7 +2271,7 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) return -EACCES; } -int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) +static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) { unsigned int i; u16 eeprom; @@ -2044,7 +2366,6 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) return 0; } -EXPORT_SYMBOL_GPL(rt2800_init_bbp); static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, bool bw40, u8 rfcsr24, u8 filter_target) @@ -2106,7 +2427,7 @@ static u8 rt2800_init_rx_filter(struct rt2x00_dev *rt2x00dev, return rfcsr24; } -int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) +static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) { u8 rfcsr; u8 bbp; @@ -2360,7 +2681,100 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) return 0; } -EXPORT_SYMBOL_GPL(rt2800_init_rfcsr); + +int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + u16 word; + + /* + * Initialize all registers. + */ + if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || + rt2800_init_registers(rt2x00dev) || + rt2800_init_bbp(rt2x00dev) || + rt2800_init_rfcsr(rt2x00dev))) + return -EIO; + + /* + * Send signal to firmware during boot time. + */ + rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); + + if (rt2x00_is_usb(rt2x00dev) && + (rt2x00_rt(rt2x00dev, RT3070) || + rt2x00_rt(rt2x00dev, RT3071) || + rt2x00_rt(rt2x00dev, RT3572))) { + udelay(200); + rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); + udelay(10); + } + + /* + * Enable RX. + */ + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + udelay(50); + + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); + rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); + rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + /* + * Initialize LED control + */ + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, + word & 0xff, (word >> 8) & 0xff); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, + word & 0xff, (word >> 8) & 0xff); + + rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); + rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, + word & 0xff, (word >> 8) & 0xff); + + return 0; +} +EXPORT_SYMBOL_GPL(rt2800_enable_radio); + +void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + + /* Wait for DMA, ignore error */ + rt2800_wait_wpdma_ready(rt2x00dev); + + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 0); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); + rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); + rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); +} +EXPORT_SYMBOL_GPL(rt2800_disable_radio); int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) { @@ -2516,6 +2930,13 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) default_lna_gain); rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); + rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word); + if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff) + rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER); + if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff) + rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER); + rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word); + return 0; } EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); @@ -2755,9 +3176,10 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) { struct hw_mode_spec *spec = &rt2x00dev->spec; struct channel_info *info; - char *tx_power1; - char *tx_power2; + char *default_power1; + char *default_power2; unsigned int i; + unsigned short max_power; u16 eeprom; /* @@ -2770,11 +3192,20 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) * Initialize all hw fields. */ rt2x00dev->hw->flags = - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | IEEE80211_HW_AMPDU_AGGREGATION; + /* + * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING for USB devices + * unless we are capable of sending the buffered frames out after the + * DTIM transmission using rt2x00lib_beacondone. This will send out + * multicast and broadcast traffic immediately instead of buffering it + * infinitly and thus dropping it after some time. + */ + if (!rt2x00_is_usb(rt2x00dev)) + rt2x00dev->hw->flags |= + IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, @@ -2785,12 +3216,13 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) * As rt2800 has a global fallback table we cannot specify * more then one tx rate per frame but since the hw will * try several rates (based on the fallback table) we should - * still initialize max_rates to the maximum number of rates + * initialize max_report_rates to the maximum number of rates * we are going to try. Otherwise mac80211 will truncate our * reported tx rates and the rc algortihm will end up with * incorrect data. */ - rt2x00dev->hw->max_rates = 7; + rt2x00dev->hw->max_rates = 1; + rt2x00dev->hw->max_report_rates = 7; rt2x00dev->hw->max_rate_tries = 1; rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom); @@ -2865,27 +3297,32 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; spec->channels_info = info; - tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); - tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); + rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom); + max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ); + default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); + default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); for (i = 0; i < 14; i++) { - info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]); - info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]); + info[i].max_power = max_power; + info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]); + info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]); } if (spec->num_channels > 14) { - tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); - tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); + max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ); + default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); + default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); for (i = 14; i < spec->num_channels; i++) { - info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]); - info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]); + info[i].max_power = max_power; + info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]); + info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]); } } @@ -3042,8 +3479,12 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, switch (action) { case IEEE80211_AMPDU_RX_START: case IEEE80211_AMPDU_RX_STOP: - /* we don't support RX aggregation yet */ - ret = -ENOTSUPP; + /* + * The hw itself takes care of setting up BlockAck mechanisms. + * So, we only have to allow mac80211 to nagotiate a BlockAck + * agreement. Once that is done, the hw will BlockAck incoming + * AMPDUs without further setup. + */ break; case IEEE80211_AMPDU_TX_START: ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 091641e3c5e2ec95eb4d89449490f7b45c41d18d..81cbc92e7857ed040c6bf123897a5f908857c819 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h @@ -1,4 +1,6 @@ /* + Copyright (C) 2010 Willow Garage + Copyright (C) 2010 Ivo van Doorn Copyright (C) 2009 Bartlomiej Zolnierkiewicz This program is free software; you can redistribute it and/or modify @@ -44,6 +46,7 @@ struct rt2800_ops { int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len); int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); + __le32 *(*drv_get_txwi)(struct queue_entry *entry); }; static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, @@ -126,18 +129,32 @@ static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev) return rt2800ops->drv_init_registers(rt2x00dev); } +static inline __le32 *rt2800_drv_get_txwi(struct queue_entry *entry) +{ + const struct rt2800_ops *rt2800ops = entry->queue->rt2x00dev->ops->drv; + + return rt2800ops->drv_get_txwi(entry); +} + void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, const u8 command, const u8 token, const u8 arg0, const u8 arg1); +int rt2800_wait_csr_ready(struct rt2x00_dev *rt2x00dev); +int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); + int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len); int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, const u8 *data, const size_t len); -void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc); +void rt2800_write_tx_data(struct queue_entry *entry, + struct txentry_desc *txdesc); void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); +void rt2800_txdone(struct rt2x00_dev *rt2x00dev); +void rt2800_txdone_entry(struct queue_entry *entry, u32 status); + void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); extern const struct rt2x00debug rt2800_rt2x00debug; @@ -153,7 +170,8 @@ void rt2800_config_filter(struct rt2x00_dev *rt2x00dev, const unsigned int filter_flags); void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, struct rt2x00intf_conf *conf, const unsigned int flags); -void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp); +void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, + u32 changed); void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant); void rt2800_config(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_conf *libconf, @@ -163,10 +181,8 @@ void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual); void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, const u32 count); -int rt2800_init_registers(struct rt2x00_dev *rt2x00dev); -int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); -int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); -int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev); +int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev); +void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 39b3846fa340a83704a69d8a252bb7a6d6fa87b5..b267395359863ca10a55fe8a39f186e5bf08deb9 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2009 Ivo van Doorn + Copyright (C) 2009 - 2010 Ivo van Doorn Copyright (C) 2009 Alban Browaeys Copyright (C) 2009 Felix Fietkau Copyright (C) 2009 Luis Correia @@ -196,8 +196,6 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, { u32 reg; - rt2800_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0x00000000); - /* * enable Host program ram write selection */ @@ -243,6 +241,7 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) { struct queue_entry_priv_pci *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; u32 word; if (entry->queue->qid == QID_RX) { @@ -253,6 +252,13 @@ static void rt2800pci_clear_entry(struct queue_entry *entry) rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0); rt2x00_desc_write(entry_priv->desc, 1, word); + + /* + * Set RX IDX in register to inform hardware that we have + * handled this entry and it is available for reuse again. + */ + rt2800_register_write(rt2x00dev, RX_CRX_IDX, + entry->entry_idx); } else { rt2x00_desc_read(entry_priv->desc, 1, &word); rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); @@ -344,24 +350,24 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, } rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); - rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, mask); - rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, mask); + rt2x00_set_field32(®, INT_MASK_CSR_RXDELAYINT, 0); + rt2x00_set_field32(®, INT_MASK_CSR_TXDELAYINT, 0); rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_AC0_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_AC1_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_AC2_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_AC3_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_HCCA_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_MGMT_DMA_DONE, mask); - rt2x00_set_field32(®, INT_MASK_CSR_MCU_COMMAND, mask); - rt2x00_set_field32(®, INT_MASK_CSR_RXTX_COHERENT, mask); + rt2x00_set_field32(®, INT_MASK_CSR_AC0_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC1_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC2_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_AC3_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_HCCA_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_MGMT_DMA_DONE, 0); + rt2x00_set_field32(®, INT_MASK_CSR_MCU_COMMAND, 0); + rt2x00_set_field32(®, INT_MASK_CSR_RXTX_COHERENT, 0); rt2x00_set_field32(®, INT_MASK_CSR_TBTT, mask); rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, mask); rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, mask); rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, mask); - rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, mask); - rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, mask); - rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, mask); + rt2x00_set_field32(®, INT_MASK_CSR_GPTIMER, 0); + rt2x00_set_field32(®, INT_MASK_CSR_RX_COHERENT, 0); + rt2x00_set_field32(®, INT_MASK_CSR_TX_COHERENT, 0); rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); } @@ -399,78 +405,18 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) { - u32 reg; - u16 word; - - /* - * Initialize all registers. - */ if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || - rt2800pci_init_queues(rt2x00dev) || - rt2800_init_registers(rt2x00dev) || - rt2800_wait_wpdma_ready(rt2x00dev) || - rt2800_init_bbp(rt2x00dev) || - rt2800_init_rfcsr(rt2x00dev))) + rt2800pci_init_queues(rt2x00dev))) return -EIO; - /* - * Send signal to firmware during boot time. - */ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); - - /* - * Enable RX. - */ - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); - rt2x00_set_field32(®, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 2); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - /* - * Initialize LED control - */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, - word & 0xff, (word >> 8) & 0xff); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, - word & 0xff, (word >> 8) & 0xff); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, - word & 0xff, (word >> 8) & 0xff); - - return 0; + return rt2800_enable_radio(rt2x00dev); } static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) { u32 reg; - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); - rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); + rt2800_disable_radio(rt2x00dev); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001280); @@ -486,9 +432,6 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); - - /* Wait for DMA, ignore error */ - rt2800_wait_wpdma_ready(rt2x00dev); } static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, @@ -566,21 +509,16 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2800pci_write_tx_data(struct queue_entry* entry, - struct txentry_desc *txdesc) +static __le32 *rt2800pci_get_txwi(struct queue_entry *entry) { - __le32 *txwi = (__le32 *) entry->skb->data; - - rt2800_write_txwi(txwi, txdesc); + return (__le32 *) entry->skb->data; } - -static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2800pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -600,7 +538,7 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_write(txd, 0, word); rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_SD_LEN1, skb->len); + rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len); rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W1_BURST, @@ -631,41 +569,35 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, /* * TX data initialization */ -static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue_idx) +static void rt2800pci_kick_tx_queue(struct data_queue *queue) { - struct data_queue *queue; - unsigned int idx, qidx = 0; + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); + unsigned int qidx; - if (queue_idx > QID_HCCA && queue_idx != QID_MGMT) - return; - - queue = rt2x00queue_get_queue(rt2x00dev, queue_idx); - idx = queue->index[Q_INDEX]; - - if (queue_idx == QID_MGMT) + if (queue->qid == QID_MGMT) qidx = 5; else - qidx = queue_idx; + qidx = queue->qid; - rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), idx); + rt2800_register_write(rt2x00dev, TX_CTX_IDX(qidx), entry->entry_idx); } -static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt2800pci_kill_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; - if (qid == QID_BEACON) { + if (queue->qid == QID_BEACON) { rt2800_register_write(rt2x00dev, BCN_TIME_CFG, 0); return; } rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (qid == QID_AC_BE)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (qid == QID_AC_BK)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (qid == QID_AC_VI)); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (qid == QID_AC_VO)); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, (queue->qid == QID_AC_VI)); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, (queue->qid == QID_AC_VO)); rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); } @@ -675,7 +607,6 @@ static void rt2800pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, static void rt2800pci_fill_rxdone(struct queue_entry *entry, struct rxdone_entry_desc *rxdesc) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *rxd = entry_priv->desc; u32 word; @@ -717,127 +648,74 @@ static void rt2800pci_fill_rxdone(struct queue_entry *entry, * Process the RXWI structure that is at the start of the buffer. */ rt2800_process_rxwi(entry, rxdesc); - - /* - * Set RX IDX in register to inform hardware that we have handled - * this entry and it is available for reuse again. - */ - rt2800_register_write(rt2x00dev, RX_CRX_IDX, entry->entry_idx); } /* * Interrupt functions. */ +static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) +{ + struct ieee80211_conf conf = { .flags = 0 }; + struct rt2x00lib_conf libconf = { .conf = &conf }; + + rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); +} + static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; struct queue_entry *entry; - __le32 *txwi; - struct txdone_entry_desc txdesc; - u32 word; - u32 reg; - int wcid, ack, pid, tx_wcid, tx_ack, tx_pid; - u16 mcs, real_mcs; - int i; - - /* - * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO - * at most X times and also stop processing once the TX_STA_FIFO_VALID - * flag is not set anymore. - * - * The legacy drivers use X=TX_RING_SIZE but state in a comment - * that the TX_STA_FIFO stack has a size of 16. We stick to our - * tx ring size for now. - */ - for (i = 0; i < TX_ENTRIES; i++) { - rt2800_register_read(rt2x00dev, TX_STA_FIFO, ®); - if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID)) + u32 status; + u8 qid; + + while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) { + /* Now remove the tx status from the FIFO */ + if (kfifo_out(&rt2x00dev->txstatus_fifo, &status, + sizeof(status)) != sizeof(status)) { + WARN_ON(1); break; + } - wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); - ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); - pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); - - /* - * Skip this entry when it contains an invalid - * queue identication number. - */ - if (pid <= 0 || pid > QID_RX) - continue; - - queue = rt2x00queue_get_queue(rt2x00dev, pid - 1); - if (unlikely(!queue)) - continue; - - /* - * Inside each queue, we process each entry in a chronological - * order. We first check that the queue is not empty. - */ - if (rt2x00queue_empty(queue)) - continue; - entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - - /* Check if we got a match by looking at WCID/ACK/PID - * fields */ - txwi = (__le32 *) entry->skb->data; - - rt2x00_desc_read(txwi, 1, &word); - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); - tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); - tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); - - if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) - WARNING(rt2x00dev, "invalid TX_STA_FIFO content\n"); - - /* - * Obtain the status about this packet. - */ - txdesc.flags = 0; - rt2x00_desc_read(txwi, 0, &word); - mcs = rt2x00_get_field32(word, TXWI_W0_MCS); - real_mcs = rt2x00_get_field32(reg, TX_STA_FIFO_MCS); - - /* - * Ralink has a retry mechanism using a global fallback - * table. We setup this fallback table to try the immediate - * lower rate for all rates. In the TX_STA_FIFO, the MCS field - * always contains the MCS used for the last transmission, be - * it successful or not. - */ - if (rt2x00_get_field32(reg, TX_STA_FIFO_TX_SUCCESS)) { + qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); + if (qid >= QID_RX) { /* - * Transmission succeeded. The number of retries is - * mcs - real_mcs + * Unknown queue, this shouldn't happen. Just drop + * this tx status. */ - __set_bit(TXDONE_SUCCESS, &txdesc.flags); - txdesc.retry = ((mcs > real_mcs) ? mcs - real_mcs : 0); - } else { + WARNING(rt2x00dev, "Got TX status report with " + "unexpected pid %u, dropping", qid); + break; + } + + queue = rt2x00queue_get_queue(rt2x00dev, qid); + if (unlikely(queue == NULL)) { /* - * Transmission failed. The number of retries is - * always 7 in this case (for a total number of 8 - * frames sent). + * The queue is NULL, this shouldn't happen. Stop + * processing here and drop the tx status */ - __set_bit(TXDONE_FAILURE, &txdesc.flags); - txdesc.retry = 7; + WARNING(rt2x00dev, "Got TX status for an unavailable " + "queue %u, dropping", qid); + break; } - /* - * the frame was retried at least once - * -> hw used fallback rates - */ - if (txdesc.retry) - __set_bit(TXDONE_FALLBACK, &txdesc.flags); + if (rt2x00queue_empty(queue)) { + /* + * The queue is empty. Stop processing here + * and drop the tx status. + */ + WARNING(rt2x00dev, "Got TX status for an empty " + "queue %u, dropping", qid); + break; + } - rt2x00lib_txdone(entry, &txdesc); + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + rt2800_txdone_entry(entry, status); } } -static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) +static void rt2800pci_txstatus_tasklet(unsigned long data) { - struct ieee80211_conf conf = { .flags = 0 }; - struct rt2x00lib_conf libconf = { .conf = &conf }; - - rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); + rt2800pci_txdone((struct rt2x00_dev *)data); } static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) @@ -864,13 +742,7 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) rt2x00pci_rxdone(rt2x00dev); /* - * 4 - Tx done interrupt. - */ - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) - rt2800pci_txdone(rt2x00dev); - - /* - * 5 - Auto wakeup interrupt. + * 4 - Auto wakeup interrupt. */ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) rt2800pci_wakeup(rt2x00dev); @@ -882,10 +754,58 @@ static irqreturn_t rt2800pci_interrupt_thread(int irq, void *dev_instance) return IRQ_HANDLED; } +static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) +{ + u32 status; + int i; + + /* + * The TX_FIFO_STATUS interrupt needs special care. We should + * read TX_STA_FIFO but we should do it immediately as otherwise + * the register can overflow and we would lose status reports. + * + * Hence, read the TX_STA_FIFO register and copy all tx status + * reports into a kernel FIFO which is handled in the txstatus + * tasklet. We use a tasklet to process the tx status reports + * because we can schedule the tasklet multiple times (when the + * interrupt fires again during tx status processing). + * + * Furthermore we don't disable the TX_FIFO_STATUS + * interrupt here but leave it enabled so that the TX_STA_FIFO + * can also be read while the interrupt thread gets executed. + * + * Since we have only one producer and one consumer we don't + * need to lock the kfifo. + */ + for (i = 0; i < TX_ENTRIES; i++) { + rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status); + + if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) + break; + + if (kfifo_is_full(&rt2x00dev->txstatus_fifo)) { + WARNING(rt2x00dev, "TX status FIFO overrun," + " drop tx status report.\n"); + break; + } + + if (kfifo_in(&rt2x00dev->txstatus_fifo, &status, + sizeof(status)) != sizeof(status)) { + WARNING(rt2x00dev, "TX status FIFO overrun," + "drop tx status report.\n"); + break; + } + } + + /* Schedule the tasklet for processing the tx status. */ + tasklet_schedule(&rt2x00dev->txstatus_tasklet); +} + static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) { struct rt2x00_dev *rt2x00dev = dev_instance; u32 reg; + irqreturn_t ret = IRQ_HANDLED; /* Read status and ACK all interrupts */ rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, ®); @@ -897,15 +817,38 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) return IRQ_HANDLED; - /* Store irqvalue for use in the interrupt thread. */ - rt2x00dev->irqvalue[0] = reg; + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) + rt2800pci_txstatus_interrupt(rt2x00dev); - /* Disable interrupts, will be enabled again in the interrupt thread. */ - rt2x00dev->ops->lib->set_device_state(rt2x00dev, - STATE_RADIO_IRQ_OFF_ISR); + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT) || + rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT) || + rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE) || + rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) { + /* + * All other interrupts are handled in the interrupt thread. + * Store irqvalue for use in the interrupt thread. + */ + rt2x00dev->irqvalue[0] = reg; + + /* + * Disable interrupts, will be enabled again in the + * interrupt thread. + */ + rt2x00dev->ops->lib->set_device_state(rt2x00dev, + STATE_RADIO_IRQ_OFF_ISR); + + /* + * Leave the TX_FIFO_STATUS interrupt enabled to not lose any + * tx status reports. + */ + rt2800_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); + rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); + ret = IRQ_WAKE_THREAD; + } - return IRQ_WAKE_THREAD; + return ret; } /* @@ -968,6 +911,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); + __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); if (!modparam_nohwcrypt) __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); @@ -1011,11 +955,13 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { .regbusy_read = rt2x00pci_regbusy_read, .drv_write_firmware = rt2800pci_write_firmware, .drv_init_registers = rt2800pci_init_registers, + .drv_get_txwi = rt2800pci_get_txwi, }; static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .irq_handler = rt2800pci_interrupt, .irq_handler_thread = rt2800pci_interrupt_thread, + .txstatus_tasklet = rt2800pci_txstatus_tasklet, .probe_hw = rt2800pci_probe_hw, .get_firmware_name = rt2800pci_get_firmware_name, .check_firmware = rt2800_check_firmware, @@ -1030,7 +976,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .reset_tuner = rt2800_reset_tuner, .link_tuner = rt2800_link_tuner, .write_tx_desc = rt2800pci_write_tx_desc, - .write_tx_data = rt2800pci_write_tx_data, + .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, .kick_tx_queue = rt2800pci_kick_tx_queue, .kill_tx_queue = rt2800pci_kill_tx_queue, diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 5a2dfe87c6b61b5f48ec9d55ad95fea5208ab4ca..3dff56ec195abaa60e9500611a6a020da2dc199f 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2009 - 2010 Ivo van Doorn Copyright (C) 2009 Mattias Nissler Copyright (C) 2009 Felix Fietkau Copyright (C) 2009 Xose Vazquez Perez @@ -100,19 +101,6 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev, msleep(10); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); - /* - * Send signal to firmware during boot time. - */ - rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); - - if (rt2x00_rt(rt2x00dev, RT3070) || - rt2x00_rt(rt2x00dev, RT3071) || - rt2x00_rt(rt2x00dev, RT3572)) { - udelay(200); - rt2800_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0); - udelay(10); - } - return 0; } @@ -134,26 +122,18 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) { u32 reg; - int i; /* * Wait until BBP and RF are ready. */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - if (reg && reg != ~0) - break; - msleep(1); - } - - if (i == REGISTER_BUSY_COUNT) { - ERROR(rt2x00dev, "Unstable hardware.\n"); + if (rt2800_wait_csr_ready(rt2x00dev)) return -EBUSY; - } rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); + rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); + rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); @@ -172,30 +152,10 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) { u32 reg; - u16 word; - /* - * Initialize all registers. - */ - if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || - rt2800_init_registers(rt2x00dev) || - rt2800_init_bbp(rt2x00dev) || - rt2800_init_rfcsr(rt2x00dev))) + if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev))) return -EIO; - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - udelay(50); - - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - rt2800_register_read(rt2x00dev, USB_DMA_CFG, ®); rt2x00_set_field32(®, USB_DMA_CFG_PHY_CLEAR, 0); rt2x00_set_field32(®, USB_DMA_CFG_RX_BULK_AGG_EN, 0); @@ -210,45 +170,12 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, USB_DMA_CFG_TX_BULK_EN, 1); rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg); - rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_TX, 1); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - /* - * Initialize LED control - */ - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_1, 0xff, - word & 0xff, (word >> 8) & 0xff); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_2, 0xff, - word & 0xff, (word >> 8) & 0xff); - - rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word); - rt2800_mcu_request(rt2x00dev, MCU_LED_3, 0xff, - word & 0xff, (word >> 8) & 0xff); - - return 0; + return rt2800_enable_radio(rt2x00dev); } static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev) { - u32 reg; - - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - - rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0); - rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0); - rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); - - /* Wait for DMA, ignore error */ - rt2800_wait_wpdma_ready(rt2x00dev); - + rt2800_disable_radio(rt2x00dev); rt2x00usb_disable_radio(rt2x00dev); } @@ -320,21 +247,19 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt2800usb_write_tx_data(struct queue_entry* entry, - struct txentry_desc *txdesc) +static __le32 *rt2800usb_get_txwi(struct queue_entry *entry) { - __le32 *txwi = (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); - - rt2800_write_txwi(txwi, txdesc); + if (entry->queue->qid == QID_BEACON) + return (__le32 *) (entry->skb->data); + else + return (__le32 *) (entry->skb->data + TXINFO_DESC_SIZE); } - -static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt2800usb_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txi = (__le32 *) skb->data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + __le32 *txi = (__le32 *) entry->skb->data; u32 word; /* @@ -342,7 +267,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, */ rt2x00_desc_read(txi, 0, &word); rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, - skb->len - TXINFO_DESC_SIZE); + entry->skb->len - TXINFO_DESC_SIZE); rt2x00_set_field32(&word, TXINFO_W0_WIV, !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); @@ -378,6 +303,46 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) return length; } +/* + * TX control handlers + */ +static void rt2800usb_work_txdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, txdone_work); + struct data_queue *queue; + struct queue_entry *entry; + + rt2800_txdone(rt2x00dev); + + /* + * Process any trailing TX status reports for IO failures, + * we loop until we find the first non-IO error entry. This + * can either be a frame which is free, is being uploaded, + * or has completed the upload but didn't have an entry + * in the TX_STAT_FIFO register yet. + */ + tx_queue_for_each(rt2x00dev, queue) { + while (!rt2x00queue_empty(queue)) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || + !test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + break; + + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + } + } +} + +static void rt2800usb_kill_tx_queue(struct data_queue *queue) +{ + if (queue->qid == QID_BEACON) + rt2x00usb_register_write(queue->rt2x00dev, BCN_TIME_CFG, 0); + + rt2x00usb_kill_tx_queue(queue); +} + /* * RX control handlers */ @@ -514,6 +479,11 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET; + /* + * Overwrite TX done handler + */ + PREPARE_WORK(&rt2x00dev->txdone_work, rt2800usb_work_txdone); + return 0; } @@ -549,6 +519,7 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = { .regbusy_read = rt2x00usb_regbusy_read, .drv_write_firmware = rt2800usb_write_firmware, .drv_init_registers = rt2800usb_init_registers, + .drv_get_txwi = rt2800usb_get_txwi, }; static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { @@ -566,11 +537,11 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .link_tuner = rt2800_link_tuner, .watchdog = rt2x00usb_watchdog, .write_tx_desc = rt2800usb_write_tx_desc, - .write_tx_data = rt2800usb_write_tx_data, + .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, .get_tx_data_len = rt2800usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2x00usb_kill_tx_queue, + .kill_tx_queue = rt2800usb_kill_tx_queue, .fill_rxdone = rt2800usb_fill_rxdone, .config_shared_key = rt2800_config_shared_key, .config_pairwise_key = rt2800_config_pairwise_key, diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index c21af38cc5af57364694c8bc46e19867e2c8150d..94fe589acfaabff06eac097fe7e3ae3e2f7ea310 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2004 - 2010 Ivo van Doorn Copyright (C) 2004 - 2009 Gertjan van Wingerde @@ -35,6 +36,7 @@ #include #include #include +#include #include @@ -212,8 +214,9 @@ struct channel_info { unsigned int flags; #define GEOGRAPHY_ALLOWED 0x00000001 - short tx_power1; - short tx_power2; + short max_power; + short default_power1; + short default_power2; }; /* @@ -335,6 +338,11 @@ struct link { /* * Work structure for scheduling periodic watchdog monitoring. + * This work must be scheduled on the kernel workqueue, while + * all other work structures must be queued on the mac80211 + * workqueue. This guarantees that the watchdog can schedule + * other work structures and wait for their completion in order + * to bring the device/driver back into the desired state. */ struct delayed_work watchdog_work; }; @@ -455,6 +463,7 @@ struct rt2x00lib_erp { short eifs; u16 beacon_int; + u16 ht_opmode; }; /* @@ -519,6 +528,11 @@ struct rt2x00lib_ops { */ irq_handler_t irq_handler_thread; + /* + * TX status tasklet handler. + */ + void (*txstatus_tasklet) (unsigned long data); + /* * Device init handlers. */ @@ -558,18 +572,15 @@ struct rt2x00lib_ops { /* * TX control handlers */ - void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, + void (*write_tx_desc) (struct queue_entry *entry, struct txentry_desc *txdesc); void (*write_tx_data) (struct queue_entry *entry, struct txentry_desc *txdesc); void (*write_beacon) (struct queue_entry *entry, struct txentry_desc *txdesc); int (*get_tx_data_len) (struct queue_entry *entry); - void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue); - void (*kill_tx_queue) (struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue); + void (*kick_tx_queue) (struct data_queue *queue); + void (*kill_tx_queue) (struct data_queue *queue); /* * RX control handlers @@ -597,7 +608,8 @@ struct rt2x00lib_ops { #define CONFIG_UPDATE_BSSID ( 1 << 3 ) void (*config_erp) (struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp); + struct rt2x00lib_erp *erp, + u32 changed); void (*config_ant) (struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant); void (*config) (struct rt2x00_dev *rt2x00dev, @@ -651,6 +663,7 @@ enum rt2x00_flags { DRIVER_REQUIRE_DMA, DRIVER_REQUIRE_COPY_IV, DRIVER_REQUIRE_L2PAD, + DRIVER_REQUIRE_TXSTATUS_FIFO, /* * Driver features @@ -698,6 +711,7 @@ struct rt2x00_dev { struct ieee80211_hw *hw; struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; enum ieee80211_band curr_band; + int curr_freq; /* * If enabled, the debugfs interface structures @@ -849,11 +863,6 @@ struct rt2x00_dev { */ struct ieee80211_low_level_stats low_level_stats; - /* - * RX configuration information. - */ - struct ieee80211_rx_status rx_status; - /* * Scheduled work. * NOTE: intf_work will use ieee80211_iterate_active_interfaces() @@ -862,6 +871,12 @@ struct rt2x00_dev { */ struct work_struct intf_work; + /** + * Scheduled work for TX/RX done handling (USB devices) + */ + struct work_struct rxdone_work; + struct work_struct txdone_work; + /* * Data queue arrays for RX, TX and Beacon. * The Beacon array also contains the Atim queue @@ -882,6 +897,16 @@ struct rt2x00_dev { * and interrupt thread routine. */ u32 irqvalue[2]; + + /* + * FIFO for storing tx status reports between isr and tasklet. + */ + struct kfifo txstatus_fifo; + + /* + * Tasklet for processing tx status reports (rt2800pci). + */ + struct tasklet_struct txstatus_tasklet; }; /* @@ -1016,17 +1041,15 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev) /** * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to map. + * @entry: Pointer to &struct queue_entry */ -void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); +void rt2x00queue_map_txskb(struct queue_entry *entry); /** * rt2x00queue_unmap_skb - Unmap a skb from DMA. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to unmap. + * @entry: Pointer to &struct queue_entry */ -void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); +void rt2x00queue_unmap_skb(struct queue_entry *entry); /** * rt2x00queue_get_queue - Convert queue index to queue pointer @@ -1069,10 +1092,11 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, */ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev); +void rt2x00lib_dmadone(struct queue_entry *entry); void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc); -void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry); +void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status); +void rt2x00lib_rxdone(struct queue_entry *entry); /* * mac80211 handlers. diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 953dc4f2c6affa5f808928718089aa1e12bde312..54ffb5aeb34e4b808f1a94bcf8e6de7463883893 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -81,7 +81,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, - struct ieee80211_bss_conf *bss_conf) + struct ieee80211_bss_conf *bss_conf, + u32 changed) { struct rt2x00lib_erp erp; @@ -102,7 +103,10 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, /* Update global beacon interval time, this is needed for PS support */ rt2x00dev->beacon_int = bss_conf->beacon_int; - rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); + if (changed & BSS_CHANGED_HT) + erp.ht_opmode = bss_conf->ht_operation_mode; + + rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed); } static inline @@ -126,25 +130,17 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, * ANTENNA_SW_DIVERSITY state to the driver. * If that happens, fallback to hardware defaults, * or our own default. - * If diversity handling is active for a particular antenna, - * we shouldn't overwrite that antenna. - * The calls to rt2x00lib_config_antenna_check() - * might have caused that we restore back to the already - * active setting. If that has happened we can quit. */ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); - else + else if(config.rx == ANTENNA_SW_DIVERSITY) config.rx = active->rx; if (!(ant->flags & ANTENNA_TX_DIVERSITY)) config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); - else + else if (config.tx == ANTENNA_SW_DIVERSITY) config.tx = active->tx; - if (config.rx == active->rx && config.tx == active->tx) - return; - /* * Antenna setup changes require the RX to be disabled, * else the changes will be ignored by the device. @@ -209,10 +205,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, rt2x00link_reset_tuner(rt2x00dev, false); rt2x00dev->curr_band = conf->channel->band; + rt2x00dev->curr_freq = conf->channel->center_freq; rt2x00dev->tx_power = conf->power_level; rt2x00dev->short_retry = conf->short_frame_max_tx_count; rt2x00dev->long_retry = conf->long_frame_max_tx_count; - - rt2x00dev->rx_status.band = conf->channel->band; - rt2x00dev->rx_status.freq = conf->channel->center_freq; } diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 583dacd8d2419dadc08af51dbaa8d7f9e30b7760..5e9074bf2b8efbb7eac0ad72db70474604557a72 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c @@ -31,15 +31,14 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key) { - switch (key->alg) { - case ALG_WEP: - if (key->keylen == WLAN_KEY_LEN_WEP40) - return CIPHER_WEP64; - else - return CIPHER_WEP128; - case ALG_TKIP: + switch (key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + return CIPHER_WEP64; + case WLAN_CIPHER_SUITE_WEP104: + return CIPHER_WEP128; + case WLAN_CIPHER_SUITE_TKIP: return CIPHER_TKIP; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: return CIPHER_AES; default: return CIPHER_NONE; @@ -95,7 +94,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, overhead += key->iv_len; if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { - if (key->alg == ALG_TKIP) + if (key->cipher == WLAN_CIPHER_SUITE_TKIP) overhead += 8; } diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index cea81e4c5c82d7b40c9a6987f36b749b9c69ecc7..fcdb6b0dc40f88d4e90ca5a064a70e6516cc6f30 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -334,12 +334,12 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, if (*offset) return 0; - data = kzalloc(lines * MAX_LINE_LENGTH, GFP_KERNEL); + data = kcalloc(lines, MAX_LINE_LENGTH, GFP_KERNEL); if (!data) return -ENOMEM; temp = data + - sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdone\tcrypto\n"); + sprintf(data, "qid\tcount\tlimit\tlength\tindex\tdma done\tdone\n"); queue_for_each(intf->rt2x00dev, queue) { spin_lock_irqsave(&queue->lock, irqflags); @@ -347,8 +347,8 @@ static ssize_t rt2x00debug_read_queue_stats(struct file *file, temp += sprintf(temp, "%d\t%d\t%d\t%d\t%d\t%d\t%d\n", queue->qid, queue->count, queue->limit, queue->length, queue->index[Q_INDEX], - queue->index[Q_INDEX_DONE], - queue->index[Q_INDEX_CRYPTO]); + queue->index[Q_INDEX_DMA_DONE], + queue->index[Q_INDEX_DONE]); spin_unlock_irqrestore(&queue->lock, irqflags); } @@ -382,7 +382,7 @@ static ssize_t rt2x00debug_read_crypto_stats(struct file *file, loff_t *offset) { struct rt2x00debug_intf *intf = file->private_data; - char *name[] = { "WEP64", "WEP128", "TKIP", "AES" }; + static const char * const name[] = { "WEP64", "WEP128", "TKIP", "AES" }; char *data; char *temp; size_t size; @@ -484,6 +484,9 @@ static ssize_t rt2x00debug_write_##__name(struct file *file, \ if (index >= debug->__name.word_count) \ return -EINVAL; \ \ + if (length > sizeof(line)) \ + return -EINVAL; \ + \ if (copy_from_user(line, buf, length)) \ return -EFAULT; \ \ diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 585e8166f22a635f628a5524d040d0f1807b3805..5ba79b935f09f5bed56f999653338501584cf141 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2004 - 2010 Ivo van Doorn This program is free software; you can redistribute it and/or modify @@ -250,6 +251,13 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) } EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); +void rt2x00lib_dmadone(struct queue_entry *entry) +{ + clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); + rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE); +} +EXPORT_SYMBOL_GPL(rt2x00lib_dmadone); + void rt2x00lib_txdone(struct queue_entry *entry, struct txdone_entry_desc *txdesc) { @@ -266,7 +274,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, /* * Unmap the skb. */ - rt2x00queue_unmap_skb(rt2x00dev, entry->skb); + rt2x00queue_unmap_skb(entry); /* * Remove the extra tx headroom from the skb. @@ -383,15 +391,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, * send the status report back. */ if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) - /* - * Only PCI and SOC devices process the tx status in process - * context. Hence use ieee80211_tx_status for PCI and SOC - * devices and stick to ieee80211_tx_status_irqsafe for USB. - */ - if (rt2x00_is_usb(rt2x00dev)) - ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); - else - ieee80211_tx_status(rt2x00dev->hw, entry->skb); + ieee80211_tx_status(rt2x00dev->hw, entry->skb); else dev_kfree_skb_any(entry->skb); @@ -403,7 +403,6 @@ void rt2x00lib_txdone(struct queue_entry *entry, rt2x00dev->ops->lib->clear_entry(entry); - clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); /* @@ -416,65 +415,89 @@ void rt2x00lib_txdone(struct queue_entry *entry, } EXPORT_SYMBOL_GPL(rt2x00lib_txdone); +void rt2x00lib_txdone_noinfo(struct queue_entry *entry, u32 status) +{ + struct txdone_entry_desc txdesc; + + txdesc.flags = 0; + __set_bit(status, &txdesc.flags); + txdesc.retry = 0; + + rt2x00lib_txdone(entry, &txdesc); +} +EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo); + static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev, struct rxdone_entry_desc *rxdesc) { struct ieee80211_supported_band *sband; const struct rt2x00_rate *rate; unsigned int i; - int signal; - int type; + int signal = rxdesc->signal; + int type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK); - /* - * For non-HT rates the MCS value needs to contain the - * actually used rate modulation (CCK or OFDM). - */ - if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS) - signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal); - else - signal = rxdesc->signal; - - type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK); - - sband = &rt2x00dev->bands[rt2x00dev->curr_band]; - for (i = 0; i < sband->n_bitrates; i++) { - rate = rt2x00_get_rate(sband->bitrates[i].hw_value); - - if (((type == RXDONE_SIGNAL_PLCP) && - (rate->plcp == signal)) || - ((type == RXDONE_SIGNAL_BITRATE) && - (rate->bitrate == signal)) || - ((type == RXDONE_SIGNAL_MCS) && - (rate->mcs == signal))) { - return i; + switch (rxdesc->rate_mode) { + case RATE_MODE_CCK: + case RATE_MODE_OFDM: + /* + * For non-HT rates the MCS value needs to contain the + * actually used rate modulation (CCK or OFDM). + */ + if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS) + signal = RATE_MCS(rxdesc->rate_mode, signal); + + sband = &rt2x00dev->bands[rt2x00dev->curr_band]; + for (i = 0; i < sband->n_bitrates; i++) { + rate = rt2x00_get_rate(sband->bitrates[i].hw_value); + if (((type == RXDONE_SIGNAL_PLCP) && + (rate->plcp == signal)) || + ((type == RXDONE_SIGNAL_BITRATE) && + (rate->bitrate == signal)) || + ((type == RXDONE_SIGNAL_MCS) && + (rate->mcs == signal))) { + return i; + } } + break; + case RATE_MODE_HT_MIX: + case RATE_MODE_HT_GREENFIELD: + if (signal >= 0 && signal <= 76) + return signal; + break; + default: + break; } WARNING(rt2x00dev, "Frame received with unrecognized signal, " - "signal=0x%.4x, type=%d.\n", signal, type); + "mode=0x%.4x, signal=0x%.4x, type=%d.\n", + rxdesc->rate_mode, signal, type); return 0; } -void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry) +void rt2x00lib_rxdone(struct queue_entry *entry) { + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct rxdone_entry_desc rxdesc; struct sk_buff *skb; - struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; + struct ieee80211_rx_status *rx_status; unsigned int header_length; int rate_idx; + + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + goto submit_entry; + /* * Allocate a new sk_buffer. If no new buffer available, drop the * received frame and reuse the existing buffer. */ - skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry); + skb = rt2x00queue_alloc_rxskb(entry); if (!skb) - return; + goto submit_entry; /* * Unmap the skb. */ - rt2x00queue_unmap_skb(rt2x00dev, entry->skb); + rt2x00queue_unmap_skb(entry); /* * Extract the RXD details. @@ -509,57 +532,44 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, skb_trim(entry->skb, rxdesc.size); /* - * Check if the frame was received using HT. In that case, - * the rate is the MCS index and should be passed to mac80211 - * directly. Otherwise we need to translate the signal to - * the correct bitrate index. + * Translate the signal to the correct bitrate index. */ - if (rxdesc.rate_mode == RATE_MODE_CCK || - rxdesc.rate_mode == RATE_MODE_OFDM) { - rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc); - } else { + rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc); + if (rxdesc.rate_mode == RATE_MODE_HT_MIX || + rxdesc.rate_mode == RATE_MODE_HT_GREENFIELD) rxdesc.flags |= RX_FLAG_HT; - rate_idx = rxdesc.signal; - } /* * Update extra components */ rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc); rt2x00debug_update_crypto(rt2x00dev, &rxdesc); + rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); + /* + * Initialize RX status information, and send frame + * to mac80211. + */ + rx_status = IEEE80211_SKB_RXCB(entry->skb); rx_status->mactime = rxdesc.timestamp; + rx_status->band = rt2x00dev->curr_band; + rx_status->freq = rt2x00dev->curr_freq; rx_status->rate_idx = rate_idx; rx_status->signal = rxdesc.rssi; rx_status->flag = rxdesc.flags; rx_status->antenna = rt2x00dev->link.ant.active.rx; - /* - * Send frame to mac80211 & debugfs. - * mac80211 will clean up the skb structure. - */ - rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); - memcpy(IEEE80211_SKB_RXCB(entry->skb), rx_status, sizeof(*rx_status)); - - /* - * Currently only PCI and SOC devices handle rx interrupts in process - * context. Hence, use ieee80211_rx_irqsafe for USB and ieee80211_rx_ni - * for PCI and SOC devices. - */ - if (rt2x00_is_usb(rt2x00dev)) - ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb); - else - ieee80211_rx_ni(rt2x00dev->hw, entry->skb); + ieee80211_rx_ni(rt2x00dev->hw, entry->skb); /* * Replace the skb with the freshly allocated one. */ entry->skb = skb; - entry->flags = 0; +submit_entry: rt2x00dev->ops->lib->clear_entry(entry); - rt2x00queue_index_inc(entry->queue, Q_INDEX); + rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); } EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); @@ -710,7 +720,7 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, for (i = 0; i < spec->num_channels; i++) { rt2x00lib_channel(&channels[i], spec->channels[i].channel, - spec->channels_info[i].tx_power1, i); + spec->channels_info[i].max_power, i); } /* @@ -805,6 +815,30 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE; + /* + * Allocate tx status FIFO for driver use. + */ + if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) && + rt2x00dev->ops->lib->txstatus_tasklet) { + /* + * Allocate txstatus fifo and tasklet, we use a size of 512 + * for the kfifo which is big enough to store 512/4=128 tx + * status reports. In the worst case (tx status for all tx + * queues gets reported before we've got a chance to handle + * them) 24*4=384 tx status reports need to be cached. + */ + status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512, + GFP_KERNEL); + if (status) + return status; + + /* tasklet for processing the tx status reports. */ + tasklet_init(&rt2x00dev->txstatus_tasklet, + rt2x00dev->ops->lib->txstatus_tasklet, + (unsigned long)rt2x00dev); + + } + /* * Register HW. */ @@ -902,10 +936,8 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) /* Enable the radio */ retval = rt2x00lib_enable_radio(rt2x00dev); - if (retval) { - rt2x00queue_uninitialize(rt2x00dev); + if (retval) return retval; - } set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); @@ -1017,6 +1049,18 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) * Stop all work. */ cancel_work_sync(&rt2x00dev->intf_work); + cancel_work_sync(&rt2x00dev->rxdone_work); + cancel_work_sync(&rt2x00dev->txdone_work); + + /* + * Free the tx status fifo. + */ + kfifo_free(&rt2x00dev->txstatus_fifo); + + /* + * Kill the tx status tasklet. + */ + tasklet_kill(&rt2x00dev->txstatus_tasklet); /* * Uninitialize device. diff --git a/drivers/net/wireless/rt2x00/rt2x00firmware.c b/drivers/net/wireless/rt2x00/rt2x00firmware.c index b818a43c4672733792295f2dec5163137e860ce4..f0e1eb72befc0abff02c5f7e2f33d8d610c70cdd 100644 --- a/drivers/net/wireless/rt2x00/rt2x00firmware.c +++ b/drivers/net/wireless/rt2x00/rt2x00firmware.c @@ -63,6 +63,9 @@ static int rt2x00lib_request_firmware(struct rt2x00_dev *rt2x00dev) INFO(rt2x00dev, "Firmware detected - version: %d.%d.\n", fw->data[fw->size - 4], fw->data[fw->size - 3]); + snprintf(rt2x00dev->hw->wiphy->fw_version, + sizeof(rt2x00dev->hw->wiphy->fw_version), "%d.%d", + fw->data[fw->size - 4], fw->data[fw->size - 3]); retval = rt2x00dev->ops->lib->check_firmware(rt2x00dev, fw->data, fw->size); switch (retval) { diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index c004cd3a8847c852c5b007ec5cdf2faf220c16f5..c637bcaec5f8d6ef37320950f5bf9964f4bde675 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c @@ -54,6 +54,17 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, */ if (txrate->flags & IEEE80211_TX_RC_MCS) { txdesc->mcs = txrate->idx; + + /* + * MIMO PS should be set to 1 for STA's using dynamic SM PS + * when using more then one tx stream (>MCS7). + */ + if (tx_info->control.sta && txdesc->mcs > 7 && + ((tx_info->control.sta->ht_cap.cap & + IEEE80211_HT_CAP_SM_PS) >> + IEEE80211_HT_CAP_SM_PS_SHIFT) == + WLAN_HT_CAP_SM_PS_DYNAMIC) + __set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags); } else { txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) @@ -62,9 +73,11 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, /* - * Convert flags + * This frame is eligible for an AMPDU, however, don't aggregate + * frames that are intended to probe a specific tx rate. */ - if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU && + !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)) __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags); /* @@ -74,7 +87,13 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, txdesc->rate_mode = RATE_MODE_HT_MIX; if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD) txdesc->rate_mode = RATE_MODE_HT_GREENFIELD; - if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) + + /* + * Set 40Mhz mode if necessary (for legacy rates this will + * duplicate the frame to both channels). + */ + if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH || + txrate->flags & IEEE80211_TX_RC_DUP_DATA) __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags); if (txrate->flags & IEEE80211_TX_RC_SHORT_GI) __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags); diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index dc5c6574aaf4f13efb6f43213da5fce85d8040be..619da23b7b56004cec3e3d327100449e9269b500 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -86,7 +86,8 @@ void rt2x00lib_config_intf(struct rt2x00_dev *rt2x00dev, const u8 *mac, const u8 *bssid); void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, - struct ieee80211_bss_conf *conf); + struct ieee80211_bss_conf *conf, + u32 changed); void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, struct antenna_setup ant); void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, @@ -99,18 +100,15 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, /** * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @queue: The queue for which the skb will be applicable. + * @entry: The entry for which the skb will be applicable. */ -struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry); +struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry); /** * rt2x00queue_free_skb - free a skb - * @rt2x00dev: Pointer to &struct rt2x00_dev. - * @skb: The skb to free. + * @entry: The entry for which the skb will be applicable. */ -void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); +void rt2x00queue_free_skb(struct queue_entry *entry); /** * rt2x00queue_align_frame - Align 802.11 frame to 4-byte boundary diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 666cef3f8472e3da35bfd98d6dd74eba1d8d162e..b971d8798ebf8ce23e7efbc2d7b1c7b88233d107 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -188,7 +188,6 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev) static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) { struct link_ant *ant = &rt2x00dev->link.ant; - unsigned int flags = ant->flags; /* * Determine if software diversity is enabled for @@ -196,13 +195,13 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) * Always perform this check since within the link * tuner interval the configuration might have changed. */ - flags &= ~ANTENNA_RX_DIVERSITY; - flags &= ~ANTENNA_TX_DIVERSITY; + ant->flags &= ~ANTENNA_RX_DIVERSITY; + ant->flags &= ~ANTENNA_TX_DIVERSITY; if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY) - flags |= ANTENNA_RX_DIVERSITY; + ant->flags |= ANTENNA_RX_DIVERSITY; if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) - flags |= ANTENNA_TX_DIVERSITY; + ant->flags |= ANTENNA_TX_DIVERSITY; if (!(ant->flags & ANTENNA_RX_DIVERSITY) && !(ant->flags & ANTENNA_TX_DIVERSITY)) { @@ -210,9 +209,6 @@ static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) return true; } - /* Update flags */ - ant->flags = flags; - /* * If we have only sampled the data over the last period * we should now harvest the data. Otherwise just evaluate @@ -239,6 +235,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, struct link_ant *ant = &rt2x00dev->link.ant; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + /* + * No need to update the stats for !=STA interfaces + */ + if (!rt2x00dev->intf_sta_count) + return; + /* * Frame was received successfully since non-succesfull * frames would have been dropped by the hardware. @@ -415,8 +417,7 @@ void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev) !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags)) return; - ieee80211_queue_delayed_work(rt2x00dev->hw, - &link->watchdog_work, WATCHDOG_INTERVAL); + schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL); } void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev) @@ -440,8 +441,7 @@ static void rt2x00link_watchdog(struct work_struct *work) rt2x00dev->ops->lib->watchdog(rt2x00dev); if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - ieee80211_queue_delayed_work(rt2x00dev->hw, - &link->watchdog_work, WATCHDOG_INTERVAL); + schedule_delayed_work(&link->watchdog_work, WATCHDOG_INTERVAL); } void rt2x00link_register(struct rt2x00_dev *rt2x00dev) diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 235e037e65092045d07db64893b7cbdaa29b5785..c3c206a97d54c608da497256a7fcadd44293d9df 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -669,8 +669,10 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, * When the erp information has changed, we should perform * additional configuration steps. For all other changes we are done. */ - if (changes & ~(BSS_CHANGED_ASSOC | BSS_CHANGED_HT)) - rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); + if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | + BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES | + BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT)) + rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes); } EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 63c2cc408e154705967677b287e0b4da85a5e727..2449d785cf8d5b4d9b5260a0a2e4f79d0506fdd9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -84,7 +84,7 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) /* * Send the frame to rt2x00lib for further processing. */ - rt2x00lib_rxdone(rt2x00dev, entry); + rt2x00lib_rxdone(entry); } } EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index a3401d301058870745879c6ec0b19fa2d29ebfda..e360d287defb01ae61672feae4e3618b3a8bea79 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2004 - 2010 Ivo van Doorn Copyright (C) 2004 - 2009 Gertjan van Wingerde @@ -32,9 +33,9 @@ #include "rt2x00.h" #include "rt2x00lib.h" -struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, - struct queue_entry *entry) +struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry) { + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct sk_buff *skb; struct skb_frame_desc *skbdesc; unsigned int frame_size; @@ -96,41 +97,42 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, return skb; } -void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) +void rt2x00queue_map_txskb(struct queue_entry *entry) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + struct device *dev = entry->queue->rt2x00dev->dev; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); skbdesc->skb_dma = - dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); + dma_map_single(dev, entry->skb->data, entry->skb->len, DMA_TO_DEVICE); skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; } EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); -void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) +void rt2x00queue_unmap_skb(struct queue_entry *entry) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); + struct device *dev = entry->queue->rt2x00dev->dev; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { - dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, + dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len, DMA_FROM_DEVICE); skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX; - } - - if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { - dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, + } else if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { + dma_unmap_single(dev, skbdesc->skb_dma, entry->skb->len, DMA_TO_DEVICE); skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; } } EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb); -void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) +void rt2x00queue_free_skb(struct queue_entry *entry) { - if (!skb) + if (!entry->skb) return; - rt2x00queue_unmap_skb(rt2x00dev, skb); - dev_kfree_skb_any(skb); + rt2x00queue_unmap_skb(entry); + dev_kfree_skb_any(entry->skb); + entry->skb = NULL; } void rt2x00queue_align_frame(struct sk_buff *skb) @@ -311,7 +313,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Initialize information from queue */ - txdesc->queue = entry->queue->qid; + txdesc->qid = entry->queue->qid; txdesc->cw_min = entry->queue->cw_min; txdesc->cw_max = entry->queue->cw_max; txdesc->aifs = entry->queue->aifs; @@ -439,7 +441,7 @@ static int rt2x00queue_write_tx_data(struct queue_entry *entry, * Map the skb to DMA. */ if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) - rt2x00queue_map_txskb(rt2x00dev, entry->skb); + rt2x00queue_map_txskb(entry); return 0; } @@ -448,15 +450,14 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) { struct data_queue *queue = entry->queue; - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); + queue->rt2x00dev->ops->lib->write_tx_desc(entry, txdesc); /* * All processing on the frame has been completed, this means * it is now ready to be dumped to userspace through debugfs. */ - rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); + rt2x00debug_dump_frame(queue->rt2x00dev, DUMP_FRAME_TX, entry->skb); } static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, @@ -476,7 +477,7 @@ static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, */ if (rt2x00queue_threshold(queue) || !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) - rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); + rt2x00dev->ops->lib->kick_tx_queue(queue); } int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, @@ -491,7 +492,8 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, if (unlikely(rt2x00queue_full(queue))) return -ENOBUFS; - if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { + if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, + &entry->flags))) { ERROR(queue->rt2x00dev, "Arrived at non-free entry in the non-full queue %d.\n" "Please file bug report to %s.\n", @@ -586,11 +588,10 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, /* * Clean up the beacon skb. */ - rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb); - intf->beacon->skb = NULL; + rt2x00queue_free_skb(intf->beacon); if (!enable_beacon) { - rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_BEACON); + rt2x00dev->ops->lib->kill_tx_queue(intf->beacon->queue); mutex_unlock(&intf->beacon_skb_mutex); return 0; } @@ -625,6 +626,51 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, return 0; } +void rt2x00queue_for_each_entry(struct data_queue *queue, + enum queue_index start, + enum queue_index end, + void (*fn)(struct queue_entry *entry)) +{ + unsigned long irqflags; + unsigned int index_start; + unsigned int index_end; + unsigned int i; + + if (unlikely(start >= Q_INDEX_MAX || end >= Q_INDEX_MAX)) { + ERROR(queue->rt2x00dev, + "Entry requested from invalid index range (%d - %d)\n", + start, end); + return; + } + + /* + * Only protect the range we are going to loop over, + * if during our loop a extra entry is set to pending + * it should not be kicked during this run, since it + * is part of another TX operation. + */ + spin_lock_irqsave(&queue->lock, irqflags); + index_start = queue->index[start]; + index_end = queue->index[end]; + spin_unlock_irqrestore(&queue->lock, irqflags); + + /* + * Start from the TX done pointer, this guarentees that we will + * send out all frames in the correct order. + */ + if (index_start < index_end) { + for (i = index_start; i < index_end; i++) + fn(&queue->entries[i]); + } else { + for (i = index_start; i < queue->limit; i++) + fn(&queue->entries[i]); + + for (i = 0; i < index_end; i++) + fn(&queue->entries[i]); + } +} +EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry); + struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue) { @@ -686,13 +732,13 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) if (queue->index[index] >= queue->limit) queue->index[index] = 0; + queue->last_action[index] = jiffies; + if (index == Q_INDEX) { queue->length++; - queue->last_index = jiffies; } else if (index == Q_INDEX_DONE) { queue->length--; queue->count++; - queue->last_index_done = jiffies; } spin_unlock_irqrestore(&queue->lock, irqflags); @@ -701,14 +747,17 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) static void rt2x00queue_reset(struct data_queue *queue) { unsigned long irqflags; + unsigned int i; spin_lock_irqsave(&queue->lock, irqflags); queue->count = 0; queue->length = 0; - queue->last_index = jiffies; - queue->last_index_done = jiffies; - memset(queue->index, 0, sizeof(queue->index)); + + for (i = 0; i < Q_INDEX_MAX; i++) { + queue->index[i] = 0; + queue->last_action[i] = jiffies; + } spin_unlock_irqrestore(&queue->lock, irqflags); } @@ -718,7 +767,7 @@ void rt2x00queue_stop_queues(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; txall_queue_for_each(rt2x00dev, queue) - rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, queue->qid); + rt2x00dev->ops->lib->kill_tx_queue(queue); } void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) @@ -730,9 +779,9 @@ void rt2x00queue_init_queues(struct rt2x00_dev *rt2x00dev) rt2x00queue_reset(queue); for (i = 0; i < queue->limit; i++) { - queue->entries[i].flags = 0; - rt2x00dev->ops->lib->clear_entry(&queue->entries[i]); + if (queue->qid == QID_RX) + rt2x00queue_index_inc(queue, Q_INDEX); } } } @@ -755,7 +804,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, * Allocate all queue entries. */ entry_size = sizeof(*entries) + qdesc->priv_size; - entries = kzalloc(queue->limit * entry_size, GFP_KERNEL); + entries = kcalloc(queue->limit, entry_size, GFP_KERNEL); if (!entries) return -ENOMEM; @@ -780,8 +829,7 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, return 0; } -static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static void rt2x00queue_free_skbs(struct data_queue *queue) { unsigned int i; @@ -789,19 +837,17 @@ static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, return; for (i = 0; i < queue->limit; i++) { - if (queue->entries[i].skb) - rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb); + rt2x00queue_free_skb(&queue->entries[i]); } } -static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static int rt2x00queue_alloc_rxskbs(struct data_queue *queue) { unsigned int i; struct sk_buff *skb; for (i = 0; i < queue->limit; i++) { - skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]); + skb = rt2x00queue_alloc_rxskb(&queue->entries[i]); if (!skb) return -ENOMEM; queue->entries[i].skb = skb; @@ -836,7 +882,7 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) goto exit; } - status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx); + status = rt2x00queue_alloc_rxskbs(rt2x00dev->rx); if (status) goto exit; @@ -854,7 +900,7 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) { struct data_queue *queue; - rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx); + rt2x00queue_free_skbs(rt2x00dev->rx); queue_for_each(rt2x00dev, queue) { kfree(queue->entries); @@ -891,7 +937,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim; - queue = kzalloc(rt2x00dev->data_queues * sizeof(*queue), GFP_KERNEL); + queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL); if (!queue) { ERROR(rt2x00dev, "Queue allocation failed.\n"); return -ENOMEM; diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index 191e7775a9c0b418f791a134ca13217b6f91b25d..d81d85f3486611cb79b18571694727c9616d7885 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2004 - 2010 Ivo van Doorn This program is free software; you can redistribute it and/or modify @@ -268,6 +268,7 @@ struct txdone_entry_desc { * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU. * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth. * @ENTRY_TXD_HT_SHORT_GI: Use short GI. + * @ENTRY_TXD_HT_MIMO_PS: The receiving STA is in dynamic SM PS mode. */ enum txentry_desc_flags { ENTRY_TXD_RTS_FRAME, @@ -286,6 +287,7 @@ enum txentry_desc_flags { ENTRY_TXD_HT_AMPDU, ENTRY_TXD_HT_BW_40, ENTRY_TXD_HT_SHORT_GI, + ENTRY_TXD_HT_MIMO_PS, }; /** @@ -294,7 +296,7 @@ enum txentry_desc_flags { * Summary of information for the frame descriptor before sending a TX frame. * * @flags: Descriptor flags (See &enum queue_entry_flags). - * @queue: Queue identification (See &enum data_queue_qid). + * @qid: Queue identification (See &enum data_queue_qid). * @length: Length of the entire frame. * @header_length: Length of 802.11 header. * @length_high: PLCP length high word. @@ -320,7 +322,7 @@ enum txentry_desc_flags { struct txentry_desc { unsigned long flags; - enum data_queue_qid queue; + enum data_queue_qid qid; u16 length; u16 header_length; @@ -358,17 +360,17 @@ struct txentry_desc { * @ENTRY_OWNER_DEVICE_DATA: This entry is owned by the device for data * transfer (either TX or RX depending on the queue). The entry should * only be touched after the device has signaled it is done with it. - * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data - * encryption or decryption. The entry should only be touched after - * the device has signaled it is done with it. * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting * for the signal to start sending. + * @ENTRY_DATA_IO_FAILED: Hardware indicated that an IO error occured + * while transfering the data to the hardware. No TX status report will + * be expected from the hardware. */ enum queue_entry_flags { ENTRY_BCN_ASSIGNED, ENTRY_OWNER_DEVICE_DATA, - ENTRY_OWNER_DEVICE_CRYPTO, ENTRY_DATA_PENDING, + ENTRY_DATA_IO_FAILED }; /** @@ -399,18 +401,18 @@ struct queue_entry { * * @Q_INDEX: Index pointer to the current entry in the queue, if this entry is * owned by the hardware then the queue is considered to be full. + * @Q_INDEX_DMA_DONE: Index pointer for the next entry which will have been + * transfered to the hardware. * @Q_INDEX_DONE: Index pointer to the next entry which will be completed by * the hardware and for which we need to run the txdone handler. If this * entry is not owned by the hardware the queue is considered to be empty. - * @Q_INDEX_CRYPTO: Index pointer to the next entry which encryption/decription - * will be completed by the hardware next. * @Q_INDEX_MAX: Keep last, used in &struct data_queue to determine the size * of the index array. */ enum queue_index { Q_INDEX, + Q_INDEX_DMA_DONE, Q_INDEX_DONE, - Q_INDEX_CRYPTO, Q_INDEX_MAX, }; @@ -446,13 +448,12 @@ struct data_queue { enum data_queue_qid qid; spinlock_t lock; - unsigned long last_index; - unsigned long last_index_done; unsigned int count; unsigned short limit; unsigned short threshold; unsigned short length; unsigned short index[Q_INDEX_MAX]; + unsigned long last_action[Q_INDEX_MAX]; unsigned short txop; unsigned short aifs; @@ -564,6 +565,22 @@ struct data_queue_desc { #define txall_queue_for_each(__dev, __entry) \ queue_loop(__entry, (__dev)->tx, queue_end(__dev)) +/** + * rt2x00queue_for_each_entry - Loop through all entries in the queue + * @queue: Pointer to @data_queue + * @start: &enum queue_index Pointer to start index + * @end: &enum queue_index Pointer to end index + * @fn: The function to call for each &struct queue_entry + * + * This will walk through all entries in the queue, in chronological + * order. This means it will start at the current @start pointer + * and will walk through the queue until it reaches the @end pointer. + */ +void rt2x00queue_for_each_entry(struct data_queue *queue, + enum queue_index start, + enum queue_index end, + void (*fn)(struct queue_entry *entry)); + /** * rt2x00queue_empty - Check if the queue is empty. * @queue: Queue to check if empty. @@ -601,12 +618,23 @@ static inline int rt2x00queue_threshold(struct data_queue *queue) } /** - * rt2x00queue_timeout - Check if a timeout occured for this queue + * rt2x00queue_timeout - Check if a timeout occured for STATUS reorts * @queue: Queue to check. */ static inline int rt2x00queue_timeout(struct data_queue *queue) { - return time_after(queue->last_index, queue->last_index_done + (HZ / 10)); + return time_after(queue->last_action[Q_INDEX_DMA_DONE], + queue->last_action[Q_INDEX_DONE] + (HZ / 10)); +} + +/** + * rt2x00queue_timeout - Check if a timeout occured for DMA transfers + * @queue: Queue to check. + */ +static inline int rt2x00queue_dma_timeout(struct data_queue *queue) +{ + return time_after(queue->last_action[Q_INDEX], + queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10)); } /** diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index ff3a36622d1b88de75353a72f8abc35ee5d26c44..b3317df7a7d4afdd88169c8ad16f2ad99984bc9e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -1,5 +1,6 @@ /* - Copyright (C) 2004 - 2009 Ivo van Doorn + Copyright (C) 2010 Willow Garage + Copyright (C) 2004 - 2010 Ivo van Doorn This program is free software; you can redistribute it and/or modify @@ -167,137 +168,137 @@ EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read); /* * TX data handlers. */ -static void rt2x00usb_interrupt_txdone(struct urb *urb) +static void rt2x00usb_work_txdone_entry(struct queue_entry *entry) { - struct queue_entry *entry = (struct queue_entry *)urb->context; - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct txdone_entry_desc txdesc; - - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || - !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) - return; - /* - * Obtain the status about this packet. - * Note that when the status is 0 it does not mean the + * If the transfer to hardware succeeded, it does not mean the * frame was send out correctly. It only means the frame * was succesfully pushed to the hardware, we have no * way to determine the transmission status right now. * (Only indirectly by looking at the failed TX counters * in the register). */ - txdesc.flags = 0; - if (!urb->status) - __set_bit(TXDONE_UNKNOWN, &txdesc.flags); + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); else - __set_bit(TXDONE_FAILURE, &txdesc.flags); - txdesc.retry = 0; - - rt2x00lib_txdone(entry, &txdesc); + rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); } -static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) +static void rt2x00usb_work_txdone(struct work_struct *work) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); - struct queue_entry_priv_usb *entry_priv = entry->priv_data; - u32 length; + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, txdone_work); + struct data_queue *queue; + struct queue_entry *entry; - if (test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) { - /* - * USB devices cannot blindly pass the skb->len as the - * length of the data to usb_fill_bulk_urb. Pass the skb - * to the driver to determine what the length should be. - */ - length = rt2x00dev->ops->lib->get_tx_data_len(entry); + tx_queue_for_each(rt2x00dev, queue) { + while (!rt2x00queue_empty(queue)) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); - usb_fill_bulk_urb(entry_priv->urb, usb_dev, - usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), - entry->skb->data, length, - rt2x00usb_interrupt_txdone, entry); + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + break; - usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + rt2x00usb_work_txdone_entry(entry); + } } } -void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt2x00usb_interrupt_txdone(struct urb *urb) { - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); - unsigned long irqflags; - unsigned int index; - unsigned int index_done; - unsigned int i; + struct queue_entry *entry = (struct queue_entry *)urb->context; + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + + if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + return; /* - * Only protect the range we are going to loop over, - * if during our loop a extra entry is set to pending - * it should not be kicked during this run, since it - * is part of another TX operation. + * Report the frame as DMA done */ - spin_lock_irqsave(&queue->lock, irqflags); - index = queue->index[Q_INDEX]; - index_done = queue->index[Q_INDEX_DONE]; - spin_unlock_irqrestore(&queue->lock, irqflags); + rt2x00lib_dmadone(entry); /* - * Start from the TX done pointer, this guarentees that we will - * send out all frames in the correct order. + * Check if the frame was correctly uploaded */ - if (index_done < index) { - for (i = index_done; i < index; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); - } else { - for (i = index_done; i < queue->limit; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); + if (urb->status) + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); - for (i = 0; i < index; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); - } + /* + * Schedule the delayed work for reading the TX status + * from the device. + */ + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->txdone_work); } -EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); -void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt2x00usb_kick_tx_entry(struct queue_entry *entry) { - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); - struct queue_entry_priv_usb *entry_priv; - struct queue_entry_priv_usb_bcn *bcn_priv; - unsigned int i; - bool kill_guard; + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); + struct queue_entry_priv_usb *entry_priv = entry->priv_data; + u32 length; + + if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) + return; /* - * When killing the beacon queue, we must also kill - * the beacon guard byte. + * USB devices cannot blindly pass the skb->len as the + * length of the data to usb_fill_bulk_urb. Pass the skb + * to the driver to determine what the length should be. */ - kill_guard = - (qid == QID_BEACON) && - (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)); + length = rt2x00dev->ops->lib->get_tx_data_len(entry); + + usb_fill_bulk_urb(entry_priv->urb, usb_dev, + usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint), + entry->skb->data, length, + rt2x00usb_interrupt_txdone, entry); + + if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) { + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + rt2x00lib_dmadone(entry); + } +} + +void rt2x00usb_kick_tx_queue(struct data_queue *queue) +{ + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00usb_kick_tx_entry); +} +EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); + +static void rt2x00usb_kill_tx_entry(struct queue_entry *entry) +{ + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct queue_entry_priv_usb *entry_priv = entry->priv_data; + struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data; + + if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + return; + + usb_kill_urb(entry_priv->urb); /* - * Cancel all entries. + * Kill guardian urb (if required by driver). */ - for (i = 0; i < queue->limit; i++) { - entry_priv = queue->entries[i].priv_data; - usb_kill_urb(entry_priv->urb); + if ((entry->queue->qid == QID_BEACON) && + (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))) + usb_kill_urb(bcn_priv->guardian_urb); +} - /* - * Kill guardian urb (if required by driver). - */ - if (kill_guard) { - bcn_priv = queue->entries[i].priv_data; - usb_kill_urb(bcn_priv->guardian_urb); - } - } +void rt2x00usb_kill_tx_queue(struct data_queue *queue) +{ + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, + rt2x00usb_kill_tx_entry); } EXPORT_SYMBOL_GPL(rt2x00usb_kill_tx_queue); -static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) +static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { - struct queue_entry_priv_usb *entry_priv; + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; unsigned short threshold = queue->threshold; - WARNING(queue->rt2x00dev, "TX queue %d timed out, invoke reset", queue->qid); + WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," + " invoke forced forced reset", queue->qid); /* * Temporarily disable the TX queue, this will force mac80211 @@ -307,20 +308,33 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) * queue from being enabled during the txdone handler. */ queue->threshold = queue->limit; - ieee80211_stop_queue(queue->rt2x00dev->hw, queue->qid); + ieee80211_stop_queue(rt2x00dev->hw, queue->qid); /* - * Reset all currently uploaded TX frames. + * Kill all entries in the queue, afterwards we need to + * wait a bit for all URBs to be cancelled. */ - while (!rt2x00queue_empty(queue)) { - entry_priv = rt2x00queue_get_entry(queue, Q_INDEX_DONE)->priv_data; - usb_kill_urb(entry_priv->urb); + rt2x00usb_kill_tx_queue(queue); - /* - * We need a short delay here to wait for - * the URB to be canceled and invoked the tx_done handler. - */ - udelay(200); + /* + * In case that a driver has overriden the txdone_work + * function, we invoke the TX done through there. + */ + rt2x00dev->txdone_work.func(&rt2x00dev->txdone_work); + + /* + * Security measure: if the driver did override the + * txdone_work function, and the hardware did arrive + * in a state which causes it to malfunction, it is + * possible that the driver couldn't handle the txdone + * event correctly. So after giving the driver the + * chance to cleanup, we now force a cleanup of any + * leftovers. + */ + if (!rt2x00queue_empty(queue)) { + WARNING(queue->rt2x00dev, "TX queue %d DMA timed out," + " status handling failed, invoke hard reset", queue->qid); + rt2x00usb_work_txdone(&rt2x00dev->txdone_work); } /* @@ -328,7 +342,15 @@ static void rt2x00usb_watchdog_reset_tx(struct data_queue *queue) * queue again. */ queue->threshold = threshold; - ieee80211_wake_queue(queue->rt2x00dev->hw, queue->qid); + ieee80211_wake_queue(rt2x00dev->hw, queue->qid); +} + +static void rt2x00usb_watchdog_tx_status(struct data_queue *queue) +{ + WARNING(queue->rt2x00dev, "TX queue %d status timed out," + " invoke forced tx handler", queue->qid); + + ieee80211_queue_work(queue->rt2x00dev->hw, &queue->rt2x00dev->txdone_work); } void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) @@ -336,8 +358,12 @@ void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; tx_queue_for_each(rt2x00dev, queue) { - if (rt2x00queue_timeout(queue)) - rt2x00usb_watchdog_reset_tx(queue); + if (!rt2x00queue_empty(queue)) { + if (rt2x00queue_dma_timeout(queue)) + rt2x00usb_watchdog_tx_dma(queue); + if (rt2x00queue_timeout(queue)) + rt2x00usb_watchdog_tx_status(queue); + } } } EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); @@ -345,38 +371,62 @@ EXPORT_SYMBOL_GPL(rt2x00usb_watchdog); /* * RX data handlers. */ +static void rt2x00usb_work_rxdone(struct work_struct *work) +{ + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, rxdone_work); + struct queue_entry *entry; + struct skb_frame_desc *skbdesc; + u8 rxd[32]; + + while (!rt2x00queue_empty(rt2x00dev->rx)) { + entry = rt2x00queue_get_entry(rt2x00dev->rx, Q_INDEX_DONE); + + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + break; + + /* + * Fill in desc fields of the skb descriptor + */ + skbdesc = get_skb_frame_desc(entry->skb); + skbdesc->desc = rxd; + skbdesc->desc_len = entry->queue->desc_size; + + /* + * Send the frame to rt2x00lib for further processing. + */ + rt2x00lib_rxdone(entry); + } +} + static void rt2x00usb_interrupt_rxdone(struct urb *urb) { struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - u8 rxd[32]; - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || - !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) + if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; /* - * Check if the received data is simply too small - * to be actually valid, or if the urb is signaling - * a problem. + * Report the frame as DMA done */ - if (urb->actual_length < entry->queue->desc_size || urb->status) { - set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - usb_submit_urb(urb, GFP_ATOMIC); - return; - } + rt2x00lib_dmadone(entry); /* - * Fill in desc fields of the skb descriptor + * Check if the received data is simply too small + * to be actually valid, or if the urb is signaling + * a problem. */ - skbdesc->desc = rxd; - skbdesc->desc_len = entry->queue->desc_size; + if (urb->actual_length < entry->queue->desc_size || urb->status) + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); /* - * Send the frame to rt2x00lib for further processing. + * Schedule the delayed work for reading the RX status + * from the device. */ - rt2x00lib_rxdone(rt2x00dev, entry); + if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && + test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->rxdone_work); } /* @@ -391,7 +441,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) * The USB version of kill_tx_queue also works * on the RX queue. */ - rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev, QID_RX); + rt2x00dev->ops->lib->kill_tx_queue(rt2x00dev->rx); } EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); @@ -405,6 +455,8 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) struct queue_entry_priv_usb *entry_priv = entry->priv_data; int pipe; + entry->flags = 0; + if (entry->queue->qid == QID_RX) { pipe = usb_rcvbulkpipe(usb_dev, entry->queue->usb_endpoint); usb_fill_bulk_urb(entry_priv->urb, usb_dev, pipe, @@ -412,9 +464,10 @@ void rt2x00usb_clear_entry(struct queue_entry *entry) rt2x00usb_interrupt_rxdone, entry); set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - usb_submit_urb(entry_priv->urb, GFP_ATOMIC); - } else { - entry->flags = 0; + if (usb_submit_urb(entry_priv->urb, GFP_ATOMIC)) { + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + rt2x00lib_dmadone(entry); + } } } EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry); @@ -489,9 +542,9 @@ static int rt2x00usb_find_endpoints(struct rt2x00_dev *rt2x00dev) return 0; } -static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static int rt2x00usb_alloc_entries(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv; struct queue_entry_priv_usb_bcn *bcn_priv; unsigned int i; @@ -508,7 +561,7 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, * no guardian byte was required for the beacon, * then we are done. */ - if (rt2x00dev->bcn != queue || + if (queue->qid != QID_BEACON || !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) return 0; @@ -522,9 +575,9 @@ static int rt2x00usb_alloc_urb(struct rt2x00_dev *rt2x00dev, return 0; } -static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, - struct data_queue *queue) +static void rt2x00usb_free_entries(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; struct queue_entry_priv_usb *entry_priv; struct queue_entry_priv_usb_bcn *bcn_priv; unsigned int i; @@ -543,7 +596,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, * no guardian byte was required for the beacon, * then we are done. */ - if (rt2x00dev->bcn != queue || + if (queue->qid != QID_BEACON || !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) return; @@ -570,7 +623,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) * Allocate DMA */ queue_for_each(rt2x00dev, queue) { - status = rt2x00usb_alloc_urb(rt2x00dev, queue); + status = rt2x00usb_alloc_entries(queue); if (status) goto exit; } @@ -589,7 +642,7 @@ void rt2x00usb_uninitialize(struct rt2x00_dev *rt2x00dev) struct data_queue *queue; queue_for_each(rt2x00dev, queue) - rt2x00usb_free_urb(rt2x00dev, queue); + rt2x00usb_free_entries(queue); } EXPORT_SYMBOL_GPL(rt2x00usb_uninitialize); @@ -659,6 +712,9 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_USB); + INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone); + INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone); + retval = rt2x00usb_alloc_reg(rt2x00dev); if (retval) goto exit_free_device; diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index d3d3ddc408759d755a8e55df993ee0c4853084c8..c2d997f67b3e718a9bc2fe063e5245acff3a852e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -379,25 +379,21 @@ struct queue_entry_priv_usb_bcn { /** * rt2x00usb_kick_tx_queue - Kick data queue - * @rt2x00dev: Pointer to &struct rt2x00_dev - * @qid: Data queue to kick + * @queue: Data queue to kick * * This will walk through all entries of the queue and push all pending * frames to the hardware as a single burst. */ -void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid); +void rt2x00usb_kick_tx_queue(struct data_queue *queue); /** * rt2x00usb_kill_tx_queue - Kill data queue - * @rt2x00dev: Pointer to &struct rt2x00_dev - * @qid: Data queue to kill + * @queue: Data queue to kill * * This will walk through all entries of the queue and kill all * previously kicked frames before they can be send. */ -void rt2x00usb_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid); +void rt2x00usb_kill_tx_queue(struct data_queue *queue); /** * rt2x00usb_watchdog - Watchdog for USB communication diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index e539c6cb636fd5d429f30c50fba98e1a6512b70c..af548c87f1084a6d641430bfd5fbf84bef52b8a0 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -594,7 +594,8 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { u32 reg; @@ -603,28 +604,36 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); - rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); - rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); - rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, - !!erp->short_preamble); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, ®); + rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); + rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, + !!erp->short_preamble); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); + } - rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, + erp->basic_rates); - rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); - rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, - erp->beacon_int * 16); - rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + if (changed & BSS_CHANGED_BEACON_INT) { + rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); + } - rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); - rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); - rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2x00pci_register_read(rt2x00dev, MAC_CSR9, ®); + rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); + rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg); - rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); - rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); - rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); - rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); - rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); + rt2x00pci_register_read(rt2x00dev, MAC_CSR8, ®); + rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); + rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); + rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); + rt2x00pci_register_write(rt2x00dev, MAC_CSR8, reg); + } } static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev, @@ -1050,7 +1059,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, /* * Determine r17 bounds. */ - if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { low_bound = 0x28; up_bound = 0x48; if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { @@ -1645,6 +1654,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, ®); rt2x00_set_field32(®, INT_MASK_CSR_TXDONE, mask); rt2x00_set_field32(®, INT_MASK_CSR_RXDONE, mask); + rt2x00_set_field32(®, INT_MASK_CSR_BEACON_DONE, mask); rt2x00_set_field32(®, INT_MASK_CSR_ENABLE_MITIGATION, mask); rt2x00_set_field32(®, INT_MASK_CSR_MITIGATION_PERIOD, 0xff); rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg); @@ -1658,6 +1668,7 @@ static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, MCU_INT_MASK_CSR_5, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_6, mask); rt2x00_set_field32(®, MCU_INT_MASK_CSR_7, mask); + rt2x00_set_field32(®, MCU_INT_MASK_CSR_TWAKEUP, mask); rt2x00pci_register_write(rt2x00dev, MCU_INT_MASK_CSR, reg); } @@ -1766,12 +1777,11 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt61pci_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_pci *entry_priv = entry->priv_data; __le32 *txd = entry_priv->desc; u32 word; @@ -1779,7 +1789,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, * Start writing the descriptor words. */ rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); + rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); @@ -1802,15 +1812,15 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, } rt2x00_desc_read(txd, 5, &word); - rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid); + rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, skbdesc->entry->entry_idx); rt2x00_set_field32(&word, TXD_W5_TX_POWER, - TXPOWER_TO_DEV(rt2x00dev->tx_power)); + TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_desc_write(txd, 5, word); - if (txdesc->queue != QID_BEACON) { + if (txdesc->qid != QID_BEACON) { rt2x00_desc_read(txd, 6, &word); rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, skbdesc->skb_dma); @@ -1857,7 +1867,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, */ skbdesc->desc = txd; skbdesc->desc_len = - (txdesc->queue == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; + (txdesc->qid == QID_BEACON) ? TXINFO_SIZE : TXD_DESC_SIZE; } /* @@ -1882,7 +1892,7 @@ static void rt61pci_write_beacon(struct queue_entry *entry, /* * Write the TX descriptor for the beacon. */ - rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt61pci_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -1918,34 +1928,34 @@ static void rt61pci_write_beacon(struct queue_entry *entry, entry->skb = NULL; } -static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid queue) +static void rt61pci_kick_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI)); - rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue->qid == QID_AC_VI)); + rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue->qid == QID_AC_VO)); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); } -static void rt61pci_kill_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) +static void rt61pci_kill_tx_queue(struct data_queue *queue) { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; u32 reg; - if (qid == QID_BEACON) { + if (queue->qid == QID_BEACON) { rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, 0); return; } rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (qid == QID_AC_BE)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (qid == QID_AC_BK)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (qid == QID_AC_VI)); - rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (qid == QID_AC_VO)); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC0, (queue->qid == QID_AC_BE)); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC1, (queue->qid == QID_AC_BK)); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, (queue->qid == QID_AC_VI)); + rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, (queue->qid == QID_AC_VO)); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); } @@ -1972,7 +1982,7 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) return 0; } - if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { if (lna == 3 || lna == 2) offset += 10; } @@ -2107,11 +2117,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) "TX status report missed for entry %d\n", entry_done->entry_idx); - txdesc.flags = 0; - __set_bit(TXDONE_UNKNOWN, &txdesc.flags); - txdesc.retry = 0; - - rt2x00lib_txdone(entry_done, &txdesc); + rt2x00lib_txdone_noinfo(entry_done, TXDONE_UNKNOWN); entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); } @@ -2624,12 +2630,13 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) * As rt61 has a global fallback table we cannot specify * more then one tx rate per frame but since the hw will * try several rates (based on the fallback table) we should - * still initialize max_rates to the maximum number of rates + * initialize max_report_rates to the maximum number of rates * we are going to try. Otherwise mac80211 will truncate our * reported tx rates and the rc algortihm will end up with * incorrect data. */ - rt2x00dev->hw->max_rates = 7; + rt2x00dev->hw->max_rates = 1; + rt2x00dev->hw->max_report_rates = 7; rt2x00dev->hw->max_rate_tries = 1; /* @@ -2654,20 +2661,24 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } if (spec->num_channels > 14) { tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); - for (i = 14; i < spec->num_channels; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } } return 0; diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index aa9de18fd410f016c452008e7852abcf5adc937c..9be8089317e4b1a6ffe7921f9d46bae9336b7cc7 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -545,7 +545,8 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, } static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, - struct rt2x00lib_erp *erp) + struct rt2x00lib_erp *erp, + u32 changed) { u32 reg; @@ -554,28 +555,36 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(®, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER); rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg); - rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); - rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); - rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, - !!erp->short_preamble); - rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg); + if (changed & BSS_CHANGED_ERP_PREAMBLE) { + rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, ®); + rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_ENABLE, 1); + rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, + !!erp->short_preamble); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg); + } - rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates); + if (changed & BSS_CHANGED_BASIC_RATES) + rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, + erp->basic_rates); - rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); - rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, - erp->beacon_int * 16); - rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + if (changed & BSS_CHANGED_BEACON_INT) { + rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); + rt2x00_set_field32(®, TXRX_CSR9_BEACON_INTERVAL, + erp->beacon_int * 16); + rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); + } - rt2x00usb_register_read(rt2x00dev, MAC_CSR9, ®); - rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); - rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg); + if (changed & BSS_CHANGED_ERP_SLOT) { + rt2x00usb_register_read(rt2x00dev, MAC_CSR9, ®); + rt2x00_set_field32(®, MAC_CSR9_SLOT_TIME, erp->slot_time); + rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg); - rt2x00usb_register_read(rt2x00dev, MAC_CSR8, ®); - rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); - rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); - rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); - rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg); + rt2x00usb_register_read(rt2x00dev, MAC_CSR8, ®); + rt2x00_set_field32(®, MAC_CSR8_SIFS, erp->sifs); + rt2x00_set_field32(®, MAC_CSR8_SIFS_AFTER_RX_OFDM, 3); + rt2x00_set_field32(®, MAC_CSR8_EIFS, erp->eifs); + rt2x00usb_register_write(rt2x00dev, MAC_CSR8, reg); + } } static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, @@ -929,7 +938,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, /* * Determine r17 bounds. */ - if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { low_bound = 0x28; up_bound = 0x48; @@ -1426,12 +1435,11 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, /* * TX descriptor initialization */ -static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static void rt73usb_write_tx_desc(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); - __le32 *txd = (__le32 *) skb->data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + __le32 *txd = (__le32 *) entry->skb->data; u32 word; /* @@ -1464,7 +1472,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_write(txd, 0, word); rt2x00_desc_read(txd, 1, &word); - rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->queue); + rt2x00_set_field32(&word, TXD_W1_HOST_Q_ID, txdesc->qid); rt2x00_set_field32(&word, TXD_W1_AIFSN, txdesc->aifs); rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min); rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); @@ -1487,7 +1495,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_read(txd, 5, &word); rt2x00_set_field32(&word, TXD_W5_TX_POWER, - TXPOWER_TO_DEV(rt2x00dev->tx_power)); + TXPOWER_TO_DEV(entry->queue->rt2x00dev->tx_power)); rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); rt2x00_desc_write(txd, 5, word); @@ -1526,7 +1534,7 @@ static void rt73usb_write_beacon(struct queue_entry *entry, /* * Write the TX descriptor for the beacon. */ - rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); + rt73usb_write_tx_desc(entry, txdesc); /* * Dump beacon to userspace through debugfs. @@ -1574,6 +1582,14 @@ static int rt73usb_get_tx_data_len(struct queue_entry *entry) return length; } +static void rt73usb_kill_tx_queue(struct data_queue *queue) +{ + if (queue->qid == QID_BEACON) + rt2x00usb_register_write(queue->rt2x00dev, TXRX_CSR9, 0); + + rt2x00usb_kill_tx_queue(queue); +} + /* * RX control handlers */ @@ -1597,7 +1613,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) return 0; } - if (rt2x00dev->rx_status.band == IEEE80211_BAND_5GHZ) { + if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) { if (lna == 3 || lna == 2) offset += 10; @@ -2047,9 +2063,14 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Initialize all hw fields. + * + * Don't set IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING unless we are + * capable of sending the buffered frames out after the DTIM + * transmission using rt2x00lib_beacondone. This will send out + * multicast and broadcast traffic immediately instead of buffering it + * infinitly and thus dropping it after some time. */ rt2x00dev->hw->flags = - IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK; @@ -2084,20 +2105,24 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL); + info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_G_START); - for (i = 0; i < 14; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 0; i < 14; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } if (spec->num_channels > 14) { tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); - for (i = 14; i < spec->num_channels; i++) - info[i].tx_power1 = TXPOWER_FROM_DEV(tx_power[i]); + for (i = 14; i < spec->num_channels; i++) { + info[i].max_power = MAX_TXPOWER; + info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); + } } return 0; @@ -2259,7 +2284,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { .write_beacon = rt73usb_write_beacon, .get_tx_data_len = rt73usb_get_tx_data_len, .kick_tx_queue = rt2x00usb_kick_tx_queue, - .kill_tx_queue = rt2x00usb_kill_tx_queue, + .kill_tx_queue = rt73usb_kill_tx_queue, .fill_rxdone = rt73usb_fill_rxdone, .config_shared_key = rt73usb_config_shared_key, .config_pairwise_key = rt73usb_config_pairwise_key, @@ -2345,6 +2370,7 @@ static struct usb_device_id rt73usb_device_table[] = { { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) }, /* CEIVA */ { USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) }, /* CNet */ diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index 30107ce78dfb6cc8613c83c5ca525a5e8bf42314..707c688da618f7728d988dccbccb8b78ea52ab22 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c @@ -783,6 +783,7 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, struct rtl8180_priv *priv = dev->priv; struct rtl8180_vif *vif_priv; int i; + u8 reg; vif_priv = (struct rtl8180_vif *)&vif->drv_priv; @@ -791,12 +792,14 @@ static void rtl8180_bss_info_changed(struct ieee80211_hw *dev, rtl818x_iowrite8(priv, &priv->map->BSSID[i], info->bssid[i]); - if (is_valid_ether_addr(info->bssid)) - rtl818x_iowrite8(priv, &priv->map->MSR, - RTL818X_MSR_INFRA); - else - rtl818x_iowrite8(priv, &priv->map->MSR, - RTL818X_MSR_NO_LINK); + if (is_valid_ether_addr(info->bssid)) { + if (vif->type == NL80211_IFTYPE_ADHOC) + reg = RTL818X_MSR_ADHOC; + else + reg = RTL818X_MSR_INFRA; + } else + reg = RTL818X_MSR_NO_LINK; + rtl818x_iowrite8(priv, &priv->map->MSR, reg); } if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp) diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 98e0351c1dd6923214b17919161793c873d89967..38fa8244cc96d93d26f7d7201d4d2d1a85c129c9 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -1176,13 +1176,12 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev, else reg = 0; - if (is_valid_ether_addr(info->bssid)) { + if (is_valid_ether_addr(info->bssid)) reg |= RTL818X_MSR_INFRA; - rtl818x_iowrite8(priv, &priv->map->MSR, reg); - } else { + else reg |= RTL818X_MSR_NO_LINK; - rtl818x_iowrite8(priv, &priv->map->MSR, reg); - } + + rtl818x_iowrite8(priv, &priv->map->MSR, reg); mutex_unlock(&priv->conf_mutex); } diff --git a/drivers/net/wireless/wl1251/Kconfig b/drivers/net/wireless/wl1251/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..1fb65849414f347899b40bb8fcb26c212a121d1e --- /dev/null +++ b/drivers/net/wireless/wl1251/Kconfig @@ -0,0 +1,33 @@ +menuconfig WL1251 + tristate "TI wl1251 driver support" + depends on MAC80211 && EXPERIMENTAL && GENERIC_HARDIRQS + select FW_LOADER + select CRC7 + ---help--- + This will enable TI wl1251 driver support. The drivers make + use of the mac80211 stack. + + If you choose to build a module, it'll be called wl1251. Say + N if unsure. + +config WL1251_SPI + tristate "TI wl1251 SPI support" + depends on WL1251 && SPI_MASTER + ---help--- + This module adds support for the SPI interface of adapters using + TI wl1251 chipset. Select this if your platform is using + the SPI bus. + + If you choose to build a module, it'll be called wl1251_spi. + Say N if unsure. + +config WL1251_SDIO + tristate "TI wl1251 SDIO support" + depends on WL1251 && MMC + ---help--- + This module adds support for the SDIO interface of adapters using + TI wl1251 chipset. Select this if your platform is using + the SDIO bus. + + If you choose to build a module, it'll be called + wl1251_sdio. Say N if unsure. diff --git a/drivers/net/wireless/wl1251/Makefile b/drivers/net/wireless/wl1251/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4fe246824db33c5ea47813d049699136958a89e9 --- /dev/null +++ b/drivers/net/wireless/wl1251/Makefile @@ -0,0 +1,6 @@ +wl1251-objs = main.o event.o tx.o rx.o ps.o cmd.o \ + acx.o boot.o init.o debugfs.o io.o + +obj-$(CONFIG_WL1251) += wl1251.o +obj-$(CONFIG_WL1251_SPI) += spi.o +obj-$(CONFIG_WL1251_SDIO) += sdio.o diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl1251/acx.c similarity index 99% rename from drivers/net/wireless/wl12xx/wl1251_acx.c rename to drivers/net/wireless/wl1251/acx.c index 91891f9280706266b2ab8e6f8d283e587d833c70..64a0214cfb29b2b23df56b988e882841e2743edb 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.c +++ b/drivers/net/wireless/wl1251/acx.c @@ -1,13 +1,13 @@ -#include "wl1251_acx.h" +#include "acx.h" #include #include #include #include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_cmd.h" -#include "wl1251_ps.h" +#include "reg.h" +#include "cmd.h" +#include "ps.h" int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod, u8 mgt_rate, u8 mgt_mod) @@ -380,7 +380,7 @@ int wl1251_acx_pd_threshold(struct wl1251 *wl) out: kfree(pd); - return 0; + return ret; } int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time) diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.h b/drivers/net/wireless/wl1251/acx.h similarity index 99% rename from drivers/net/wireless/wl12xx/wl1251_acx.h rename to drivers/net/wireless/wl1251/acx.h index 842df310d92a61554f44184273b3470608b9a165..e54b21a4f8b195b014998faa2f8bd50875a19ea4 100644 --- a/drivers/net/wireless/wl12xx/wl1251_acx.h +++ b/drivers/net/wireless/wl1251/acx.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -26,7 +24,7 @@ #define __WL1251_ACX_H__ #include "wl1251.h" -#include "wl1251_cmd.h" +#include "cmd.h" /* Target's information element */ struct acx_header { @@ -37,7 +35,7 @@ struct acx_header { /* payload length (not including headers */ u16 len; -}; +} __packed; struct acx_error_counter { struct acx_header header; @@ -459,8 +457,8 @@ struct acx_beacon_filter_ie_table { struct acx_header header; u8 num_ie; - u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; u8 pad[3]; + u8 table[BEACON_FILTER_TABLE_MAX_SIZE]; } __packed; #define SYNCH_FAIL_DEFAULT_THRESHOLD 10 /* number of beacons */ @@ -471,7 +469,7 @@ struct acx_conn_monit_params { u32 synch_fail_thold; /* number of beacons missed */ u32 bss_lose_timeout; /* number of TU's from synch fail */ -}; +} __packed; enum { SG_ENABLE = 0, @@ -1056,7 +1054,7 @@ struct acx_rate_class { u8 long_retry_limit; u8 aflags; u8 reserved; -}; +} __packed; struct acx_rate_policy { struct acx_header header; diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.c b/drivers/net/wireless/wl1251/boot.c similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251_boot.c rename to drivers/net/wireless/wl1251/boot.c index 65e0416be5b6975642ea589a105b39bda95b5e32..61572dfa1f6059916f068ba7f334c6cd6a9f031d 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.c +++ b/drivers/net/wireless/wl1251/boot.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -24,12 +22,12 @@ #include #include -#include "wl1251_reg.h" -#include "wl1251_boot.h" -#include "wl1251_io.h" -#include "wl1251_spi.h" -#include "wl1251_event.h" -#include "wl1251_acx.h" +#include "reg.h" +#include "boot.h" +#include "io.h" +#include "spi.h" +#include "event.h" +#include "acx.h" void wl1251_boot_target_enable_interrupts(struct wl1251 *wl) { @@ -302,7 +300,7 @@ int wl1251_boot_run_firmware(struct wl1251 *wl) ROAMING_TRIGGER_LOW_RSSI_EVENT_ID | ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID | REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID | - BT_PTA_PREDICTION_EVENT_ID; + BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID; ret = wl1251_event_unmask(wl); if (ret < 0) { diff --git a/drivers/net/wireless/wl12xx/wl1251_boot.h b/drivers/net/wireless/wl1251/boot.h similarity index 96% rename from drivers/net/wireless/wl12xx/wl1251_boot.h rename to drivers/net/wireless/wl1251/boot.h index 90063697e8f279f9590af39aff1e735ce408ffc7..7661bc5e46627182fe040af0e73b6265e17d9aee 100644 --- a/drivers/net/wireless/wl12xx/wl1251_boot.h +++ b/drivers/net/wireless/wl1251/boot.h @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl1251/cmd.c similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251_cmd.c rename to drivers/net/wireless/wl1251/cmd.c index ce3722f4c3e38e532c587051bce253257bcd89eb..0ade4bd617c03bcf5486354ea91e66aee55a2567 100644 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.c +++ b/drivers/net/wireless/wl1251/cmd.c @@ -1,14 +1,14 @@ -#include "wl1251_cmd.h" +#include "cmd.h" #include #include #include #include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" -#include "wl1251_ps.h" -#include "wl1251_acx.h" +#include "reg.h" +#include "io.h" +#include "ps.h" +#include "acx.h" /** * send command to firmware @@ -200,7 +200,7 @@ int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, out: kfree(vbm); - return 0; + return ret; } int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl1251/cmd.h similarity index 99% rename from drivers/net/wireless/wl12xx/wl1251_cmd.h rename to drivers/net/wireless/wl1251/cmd.h index a9e4991369be5d47d3a1de2f9029649476b324f0..e5c74c631374cd0c051574dff620b0a200f3d83a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.h +++ b/drivers/net/wireless/wl1251/cmd.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -111,7 +109,7 @@ struct wl1251_cmd_header { struct wl1251_command { struct wl1251_cmd_header header; u8 parameters[MAX_CMD_PARAMS]; -}; +} __packed; enum { CMD_MAILBOX_IDLE = 0, @@ -164,7 +162,7 @@ struct cmd_read_write_memory { of this field is the Host in WRITE command or the Wilink in READ command. */ u8 value[MAX_READ_SIZE]; -}; +} __packed; #define CMDMBOX_HEADER_LEN 4 #define CMDMBOX_INFO_ELEM_HEADER_LEN 4 @@ -339,7 +337,7 @@ struct wl1251_cmd_trigger_scan_to { struct wl1251_cmd_header header; u32 timeout; -}; +} __packed; /* HW encryption keys */ #define NUM_ACCESS_CATEGORIES_COPY 4 diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.c b/drivers/net/wireless/wl1251/debugfs.c similarity index 99% rename from drivers/net/wireless/wl12xx/wl1251_debugfs.c rename to drivers/net/wireless/wl1251/debugfs.c index fa620a5e53036a148ad0a99369b4a4dc3b8cc8de..6c274007d200f53fa950a4a737387d9714fb32e6 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.c +++ b/drivers/net/wireless/wl1251/debugfs.c @@ -3,8 +3,6 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -21,14 +19,14 @@ * */ -#include "wl1251_debugfs.h" +#include "debugfs.h" #include #include #include "wl1251.h" -#include "wl1251_acx.h" -#include "wl1251_ps.h" +#include "acx.h" +#include "ps.h" /* ms */ #define WL1251_DEBUGFS_STATS_LIFETIME 1000 diff --git a/drivers/net/wireless/wl12xx/wl1251_debugfs.h b/drivers/net/wireless/wl1251/debugfs.h similarity index 95% rename from drivers/net/wireless/wl12xx/wl1251_debugfs.h rename to drivers/net/wireless/wl1251/debugfs.h index 6dc3d080853c47950cb9dad1fe069f3a226f247b..b3417c02a218e597e3136fb65c8f02667b02d30a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_debugfs.h +++ b/drivers/net/wireless/wl1251/debugfs.h @@ -3,8 +3,6 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_event.c b/drivers/net/wireless/wl1251/event.c similarity index 81% rename from drivers/net/wireless/wl12xx/wl1251_event.c rename to drivers/net/wireless/wl1251/event.c index 020d764f9c135d38838297a241b3709ba02b62a1..712372e50a8794ae550f91709a31589d83e4b90a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.c +++ b/drivers/net/wireless/wl1251/event.c @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -23,10 +21,10 @@ */ #include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" -#include "wl1251_event.h" -#include "wl1251_ps.h" +#include "reg.h" +#include "io.h" +#include "event.h" +#include "ps.h" static int wl1251_event_scan_complete(struct wl1251 *wl, struct event_mailbox *mbox) @@ -36,9 +34,7 @@ static int wl1251_event_scan_complete(struct wl1251 *wl, mbox->scheduled_scan_channels); if (wl->scanning) { - mutex_unlock(&wl->mutex); ieee80211_scan_completed(wl->hw, false); - mutex_lock(&wl->mutex); wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan completed"); wl->scanning = false; } @@ -97,6 +93,35 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) return 0; } +/* + * Poll the mailbox event field until any of the bits in the mask is set or a + * timeout occurs (WL1251_EVENT_TIMEOUT in msecs) + */ +int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms) +{ + u32 events_vector, event; + unsigned long timeout; + + timeout = jiffies + msecs_to_jiffies(timeout_ms); + + do { + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + msleep(1); + + /* read from both event fields */ + wl1251_mem_read(wl, wl->mbox_ptr[0], &events_vector, + sizeof(events_vector)); + event = events_vector & mask; + wl1251_mem_read(wl, wl->mbox_ptr[1], &events_vector, + sizeof(events_vector)); + event |= events_vector & mask; + } while (!event); + + return 0; +} + int wl1251_event_unmask(struct wl1251 *wl) { int ret; diff --git a/drivers/net/wireless/wl12xx/wl1251_event.h b/drivers/net/wireless/wl1251/event.h similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251_event.h rename to drivers/net/wireless/wl1251/event.h index f48a2b66bc5a670b673b45d19a35c5b77b14de9b..30eb5d150bf75d8ca8a653a4adc27f59f186d0a7 100644 --- a/drivers/net/wireless/wl12xx/wl1251_event.h +++ b/drivers/net/wireless/wl1251/event.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -117,5 +115,6 @@ struct event_mailbox { int wl1251_event_unmask(struct wl1251 *wl); void wl1251_event_mbox_config(struct wl1251 *wl); int wl1251_event_handle(struct wl1251 *wl, u8 mbox); +int wl1251_event_wait(struct wl1251 *wl, u32 mask, int timeout_ms); #endif diff --git a/drivers/net/wireless/wl12xx/wl1251_init.c b/drivers/net/wireless/wl1251/init.c similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251_init.c rename to drivers/net/wireless/wl1251/init.c index b538bdd7b320f41e8abdf2516d755179d780f94e..89b43d35473c662a6f5763c992dbb1f35e8f18c0 100644 --- a/drivers/net/wireless/wl12xx/wl1251_init.c +++ b/drivers/net/wireless/wl1251/init.c @@ -3,8 +3,6 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -25,11 +23,11 @@ #include #include -#include "wl1251_init.h" +#include "init.h" #include "wl12xx_80211.h" -#include "wl1251_acx.h" -#include "wl1251_cmd.h" -#include "wl1251_reg.h" +#include "acx.h" +#include "cmd.h" +#include "reg.h" int wl1251_hw_init_hwenc_config(struct wl1251 *wl) { diff --git a/drivers/net/wireless/wl12xx/wl1251_init.h b/drivers/net/wireless/wl1251/init.h similarity index 97% rename from drivers/net/wireless/wl12xx/wl1251_init.h rename to drivers/net/wireless/wl1251/init.h index 269cefb3e7d43f20d96e3ca1902b1388fd5049e3..543f17582eadfda1375239011b5eb2efc03c050f 100644 --- a/drivers/net/wireless/wl12xx/wl1251_init.h +++ b/drivers/net/wireless/wl1251/init.h @@ -3,8 +3,6 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_io.c b/drivers/net/wireless/wl1251/io.c similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251_io.c rename to drivers/net/wireless/wl1251/io.c index f1c232e0887fb65b2e1c51af82e3e9c9a89eac78..cdcadbf6ac2cfff37a99fa31d34d71933cd34339 100644 --- a/drivers/net/wireless/wl12xx/wl1251_io.c +++ b/drivers/net/wireless/wl1251/io.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -22,8 +20,8 @@ */ #include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" +#include "reg.h" +#include "io.h" /* FIXME: this is static data nowadays and the table can be removed */ static enum wl12xx_acx_int_reg wl1251_io_reg_table[ACX_REG_TABLE_LEN] = { diff --git a/drivers/net/wireless/wl12xx/wl1251_io.h b/drivers/net/wireless/wl1251/io.h similarity index 100% rename from drivers/net/wireless/wl12xx/wl1251_io.h rename to drivers/net/wireless/wl1251/io.h diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl1251/main.c similarity index 96% rename from drivers/net/wireless/wl12xx/wl1251_main.c rename to drivers/net/wireless/wl1251/main.c index 861a5f33761e9ea94d15d355a360835a0766ade0..7a8762553cdcb54470d5b430fa7019fabf6b471c 100644 --- a/drivers/net/wireless/wl12xx/wl1251_main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008-2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -33,16 +31,16 @@ #include "wl1251.h" #include "wl12xx_80211.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" -#include "wl1251_cmd.h" -#include "wl1251_event.h" -#include "wl1251_tx.h" -#include "wl1251_rx.h" -#include "wl1251_ps.h" -#include "wl1251_init.h" -#include "wl1251_debugfs.h" -#include "wl1251_boot.h" +#include "reg.h" +#include "io.h" +#include "cmd.h" +#include "event.h" +#include "tx.h" +#include "rx.h" +#include "ps.h" +#include "init.h" +#include "debugfs.h" +#include "boot.h" void wl1251_enable_interrupts(struct wl1251 *wl) { @@ -293,14 +291,14 @@ static void wl1251_irq_work(struct work_struct *work) wl1251_tx_complete(wl); } - if (intr & (WL1251_ACX_INTR_EVENT_A | - WL1251_ACX_INTR_EVENT_B)) { - wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", - intr); - if (intr & WL1251_ACX_INTR_EVENT_A) - wl1251_event_handle(wl, 0); - else - wl1251_event_handle(wl, 1); + if (intr & WL1251_ACX_INTR_EVENT_A) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A"); + wl1251_event_handle(wl, 0); + } + + if (intr & WL1251_ACX_INTR_EVENT_B) { + wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_B"); + wl1251_event_handle(wl, 1); } if (intr & WL1251_ACX_INTR_INIT_COMPLETE) @@ -339,11 +337,9 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel, if (ret < 0) goto out; - /* - * FIXME: we should wait for JOIN_EVENT_COMPLETE_ID but to simplify - * locking we just sleep instead, for now - */ - msleep(10); + ret = wl1251_event_wait(wl, JOIN_EVENT_COMPLETE_ID, 100); + if (ret < 0) + wl1251_warning("join timeout"); out: return ret; @@ -379,6 +375,7 @@ static void wl1251_filter_work(struct work_struct *work) static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1251 *wl = hw->priv; + unsigned long flags; skb_queue_tail(&wl->tx_queue, skb); @@ -393,16 +390,13 @@ static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * The workqueue is slow to process the tx_queue and we need stop * the queue here, otherwise the queue will get too long. */ - if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_MAX_LENGTH) { + if (skb_queue_len(&wl->tx_queue) >= WL1251_TX_QUEUE_HIGH_WATERMARK) { wl1251_debug(DEBUG_TX, "op_tx: tx_queue full, stop queues"); - ieee80211_stop_queues(wl->hw); - /* - * FIXME: this is racy, the variable is not properly - * protected. Maybe fix this by removing the stupid - * variable altogether and checking the real queue state? - */ + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_stop_queues(wl->hw); wl->tx_queue_stopped = true; + spin_unlock_irqrestore(&wl->wl_lock, flags); } return NETDEV_TX_OK; @@ -471,9 +465,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) WARN_ON(wl->state != WL1251_STATE_ON); if (wl->scanning) { - mutex_unlock(&wl->mutex); ieee80211_scan_completed(wl->hw, true); - mutex_lock(&wl->mutex); wl->scanning = false; } @@ -725,8 +717,9 @@ static int wl1251_set_key_type(struct wl1251 *wl, struct ieee80211_key_conf *mac80211_key, const u8 *addr) { - switch (mac80211_key->alg) { - case ALG_WEP: + switch (mac80211_key->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: if (is_broadcast_ether_addr(addr)) key->key_type = KEY_WEP_DEFAULT; else @@ -734,7 +727,7 @@ static int wl1251_set_key_type(struct wl1251 *wl, mac80211_key->hw_key_idx = mac80211_key->keyidx; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: if (is_broadcast_ether_addr(addr)) key->key_type = KEY_TKIP_MIC_GROUP; else @@ -742,7 +735,7 @@ static int wl1251_set_key_type(struct wl1251 *wl, mac80211_key->hw_key_idx = mac80211_key->keyidx; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: if (is_broadcast_ether_addr(addr)) key->key_type = KEY_AES_GROUP; else @@ -750,7 +743,7 @@ static int wl1251_set_key_type(struct wl1251 *wl, mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; break; default: - wl1251_error("Unknown key algo 0x%x", mac80211_key->alg); + wl1251_error("Unknown key cipher 0x%x", mac80211_key->cipher); return -EOPNOTSUPP; } @@ -783,7 +776,7 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wl1251_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); wl1251_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); wl1251_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", - key->alg, key->keyidx, key->keylen, key->flags); + key->cipher, key->keyidx, key->keylen, key->flags); wl1251_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen); if (is_zero_ether_addr(addr)) { @@ -1438,5 +1431,5 @@ EXPORT_SYMBOL_GPL(wl1251_free_hw); MODULE_DESCRIPTION("TI wl1251 Wireles LAN Driver Core"); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); +MODULE_AUTHOR("Kalle Valo "); MODULE_FIRMWARE(WL1251_FW_NAME); diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl1251/ps.c similarity index 96% rename from drivers/net/wireless/wl12xx/wl1251_ps.c rename to drivers/net/wireless/wl1251/ps.c index b55cb2bd459aa0d278556f3b81d5ca7701fe209d..5ed47c8373d2ae846db307b9d7306781f69564a6 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.c +++ b/drivers/net/wireless/wl1251/ps.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -21,10 +19,10 @@ * */ -#include "wl1251_reg.h" -#include "wl1251_ps.h" -#include "wl1251_cmd.h" -#include "wl1251_io.h" +#include "reg.h" +#include "ps.h" +#include "cmd.h" +#include "io.h" /* in ms */ #define WL1251_WAKEUP_TIMEOUT 100 diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.h b/drivers/net/wireless/wl1251/ps.h similarity index 93% rename from drivers/net/wireless/wl12xx/wl1251_ps.h rename to drivers/net/wireless/wl1251/ps.h index c688ac57aee480cc2378c93c50f14f0f32272113..55c3dda75e699f45f13beb0f43ed00ad0cee2c14 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.h +++ b/drivers/net/wireless/wl1251/ps.h @@ -1,14 +1,9 @@ -#ifndef __WL1251_PS_H__ -#define __WL1251_PS_H__ - /* * This file is part of wl1251 * * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -25,8 +20,11 @@ * */ +#ifndef __WL1251_PS_H__ +#define __WL1251_PS_H__ + #include "wl1251.h" -#include "wl1251_acx.h" +#include "acx.h" int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode); void wl1251_ps_elp_sleep(struct wl1251 *wl); diff --git a/drivers/net/wireless/wl12xx/wl1251_reg.h b/drivers/net/wireless/wl1251/reg.h similarity index 99% rename from drivers/net/wireless/wl12xx/wl1251_reg.h rename to drivers/net/wireless/wl1251/reg.h index d16edd9bf06c1bf9e61cb397068ba381f1da22ca..a5809019c5c19a5ced3d1f4d0b674b1e3bee6779 100644 --- a/drivers/net/wireless/wl12xx/wl1251_reg.h +++ b/drivers/net/wireless/wl1251/reg.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.c b/drivers/net/wireless/wl1251/rx.c similarity index 96% rename from drivers/net/wireless/wl12xx/wl1251_rx.c rename to drivers/net/wireless/wl1251/rx.c index 1b6294b3b996fd9f660d17c02bc1543b9bd428dd..efa53607d5c9ac9e5ef2f572739f46b562334117 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.c +++ b/drivers/net/wireless/wl1251/rx.c @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -27,11 +25,11 @@ #include #include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_io.h" -#include "wl1251_rx.h" -#include "wl1251_cmd.h" -#include "wl1251_acx.h" +#include "reg.h" +#include "io.h" +#include "rx.h" +#include "cmd.h" +#include "acx.h" static void wl1251_rx_header(struct wl1251 *wl, struct wl1251_rx_descriptor *desc) diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl1251/rx.h similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251_rx.h rename to drivers/net/wireless/wl1251/rx.h index da4e53406a0ead9810568785a1f8d5fd3a3c3b1f..4448f635a4d8e8462643ac820226b95b34ee623e 100644 --- a/drivers/net/wireless/wl12xx/wl1251_rx.h +++ b/drivers/net/wireless/wl1251/rx.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. diff --git a/drivers/net/wireless/wl12xx/wl1251_sdio.c b/drivers/net/wireless/wl1251/sdio.c similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251_sdio.c rename to drivers/net/wireless/wl1251/sdio.c index b901b6135654f0ce00974411ad4f69628963f596..74ba9ced5393fd35901643a53a5607ec68bf4747 100644 --- a/drivers/net/wireless/wl12xx/wl1251_sdio.c +++ b/drivers/net/wireless/wl1251/sdio.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include "wl1251.h" @@ -339,4 +339,4 @@ module_init(wl1251_sdio_init); module_exit(wl1251_sdio_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); +MODULE_AUTHOR("Kalle Valo "); diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.c b/drivers/net/wireless/wl1251/spi.c similarity index 97% rename from drivers/net/wireless/wl12xx/wl1251_spi.c rename to drivers/net/wireless/wl1251/spi.c index 27fdfaaeb0742c780d82ccaaf2138ed485675cec..88fa8e69d0d1d30b06c76a64cdc8d00f5592754a 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.c +++ b/drivers/net/wireless/wl1251/spi.c @@ -3,8 +3,6 @@ * * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -26,11 +24,11 @@ #include #include #include -#include +#include #include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_spi.h" +#include "reg.h" +#include "spi.h" static irqreturn_t wl1251_irq(int irq, void *cookie) { @@ -344,5 +342,5 @@ module_init(wl1251_spi_init); module_exit(wl1251_spi_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Kalle Valo "); +MODULE_AUTHOR("Kalle Valo "); MODULE_ALIAS("spi:wl1251"); diff --git a/drivers/net/wireless/wl12xx/wl1251_spi.h b/drivers/net/wireless/wl1251/spi.h similarity index 94% rename from drivers/net/wireless/wl12xx/wl1251_spi.h rename to drivers/net/wireless/wl1251/spi.h index 2e273a97e7f3ac25853485e2037aa486e88896fb..16d506955cc0515f797838dd4414e6e0f30b1dcc 100644 --- a/drivers/net/wireless/wl12xx/wl1251_spi.h +++ b/drivers/net/wireless/wl1251/spi.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -25,9 +23,9 @@ #ifndef __WL1251_SPI_H__ #define __WL1251_SPI_H__ -#include "wl1251_cmd.h" -#include "wl1251_acx.h" -#include "wl1251_reg.h" +#include "cmd.h" +#include "acx.h" +#include "reg.h" #define WSPI_CMD_READ 0x40000000 #define WSPI_CMD_WRITE 0x00000000 diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.c b/drivers/net/wireless/wl1251/tx.c similarity index 95% rename from drivers/net/wireless/wl12xx/wl1251_tx.c rename to drivers/net/wireless/wl1251/tx.c index a38ec199187a99ee7ebb475d547b218b43b8f9fc..554b4f9a3d3ecf3141ebdec2e0773fb967fcefa6 100644 --- a/drivers/net/wireless/wl12xx/wl1251_tx.c +++ b/drivers/net/wireless/wl1251/tx.c @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -26,10 +24,10 @@ #include #include "wl1251.h" -#include "wl1251_reg.h" -#include "wl1251_tx.h" -#include "wl1251_ps.h" -#include "wl1251_io.h" +#include "reg.h" +#include "tx.h" +#include "ps.h" +#include "io.h" static bool wl1251_tx_double_buffer_busy(struct wl1251 *wl, u32 data_out_count) { @@ -189,7 +187,7 @@ static int wl1251_tx_send_packet(struct wl1251 *wl, struct sk_buff *skb, tx_hdr = (struct tx_double_buffer_desc *) skb->data; if (control->control.hw_key && - control->control.hw_key->alg == ALG_TKIP) { + control->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen; __le16 fc; u16 length; @@ -322,11 +320,6 @@ void wl1251_tx_work(struct work_struct *work) ret = wl1251_tx_frame(wl, skb); if (ret == -EBUSY) { - /* firmware buffer is full, stop queues */ - wl1251_debug(DEBUG_TX, "tx_work: fw buffer full, " - "stop queues"); - ieee80211_stop_queues(wl->hw); - wl->tx_queue_stopped = true; skb_queue_head(&wl->tx_queue, skb); goto out; } else if (ret < 0) { @@ -399,7 +392,7 @@ static void wl1251_tx_packet_cb(struct wl1251 *wl, */ frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc)); if (info->control.hw_key && - info->control.hw_key->alg == ALG_TKIP) { + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { hdrlen = ieee80211_get_hdrlen_from_skb(skb); memmove(frame + WL1251_TKIP_IV_SPACE, frame, hdrlen); skb_pull(skb, WL1251_TKIP_IV_SPACE); @@ -449,6 +442,7 @@ void wl1251_tx_complete(struct wl1251 *wl) { int i, result_index, num_complete = 0; struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr; + unsigned long flags; if (unlikely(wl->state != WL1251_STATE_ON)) return; @@ -477,6 +471,20 @@ void wl1251_tx_complete(struct wl1251 *wl) } } + if (wl->tx_queue_stopped + && + skb_queue_len(&wl->tx_queue) <= WL1251_TX_QUEUE_LOW_WATERMARK){ + + /* firmware buffer has space, restart queues */ + wl1251_debug(DEBUG_TX, "tx_complete: waking queues"); + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_wake_queues(wl->hw); + wl->tx_queue_stopped = false; + spin_unlock_irqrestore(&wl->wl_lock, flags); + ieee80211_queue_work(wl->hw, &wl->tx_work); + + } + /* Every completed frame needs to be acknowledged */ if (num_complete) { /* diff --git a/drivers/net/wireless/wl12xx/wl1251_tx.h b/drivers/net/wireless/wl1251/tx.h similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251_tx.h rename to drivers/net/wireless/wl1251/tx.h index f40eeb37f5aaf590a84a989a3bfdd93636fe5205..81338d39b43e367300dd139c532eb5f0f908b360 100644 --- a/drivers/net/wireless/wl12xx/wl1251_tx.h +++ b/drivers/net/wireless/wl1251/tx.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -26,7 +24,7 @@ #define __WL1251_TX_H__ #include -#include "wl1251_acx.h" +#include "acx.h" /* * diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl1251/wl1251.h similarity index 98% rename from drivers/net/wireless/wl12xx/wl1251.h rename to drivers/net/wireless/wl1251/wl1251.h index 6b942a28e6a5dd02e87cebd8f20273e234cdea10..e113d4c1fb357924d20a342d4ec214b6fde33c85 100644 --- a/drivers/net/wireless/wl12xx/wl1251.h +++ b/drivers/net/wireless/wl1251/wl1251.h @@ -4,8 +4,6 @@ * Copyright (c) 1998-2007 Texas Instruments Incorporated * Copyright (C) 2008-2009 Nokia Corporation * - * Contact: Kalle Valo - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. @@ -274,6 +272,8 @@ struct wl1251 { int irq; bool use_eeprom; + spinlock_t wl_lock; + enum wl1251_state state; struct mutex mutex; @@ -401,7 +401,8 @@ void wl1251_disable_interrupts(struct wl1251 *wl); #define WL1251_DEFAULT_POWER_LEVEL 20 -#define WL1251_TX_QUEUE_MAX_LENGTH 20 +#define WL1251_TX_QUEUE_LOW_WATERMARK 10 +#define WL1251_TX_QUEUE_HIGH_WATERMARK 25 #define WL1251_DEFAULT_BEACON_INT 100 #define WL1251_DEFAULT_DTIM_PERIOD 1 diff --git a/drivers/net/wireless/wl1251/wl12xx_80211.h b/drivers/net/wireless/wl1251/wl12xx_80211.h new file mode 100644 index 0000000000000000000000000000000000000000..1846280272139ec110e5089d84f70a95b60ffd8b --- /dev/null +++ b/drivers/net/wireless/wl1251/wl12xx_80211.h @@ -0,0 +1,156 @@ +#ifndef __WL12XX_80211_H__ +#define __WL12XX_80211_H__ + +#include /* ETH_ALEN */ + +/* RATES */ +#define IEEE80211_CCK_RATE_1MB 0x02 +#define IEEE80211_CCK_RATE_2MB 0x04 +#define IEEE80211_CCK_RATE_5MB 0x0B +#define IEEE80211_CCK_RATE_11MB 0x16 +#define IEEE80211_OFDM_RATE_6MB 0x0C +#define IEEE80211_OFDM_RATE_9MB 0x12 +#define IEEE80211_OFDM_RATE_12MB 0x18 +#define IEEE80211_OFDM_RATE_18MB 0x24 +#define IEEE80211_OFDM_RATE_24MB 0x30 +#define IEEE80211_OFDM_RATE_36MB 0x48 +#define IEEE80211_OFDM_RATE_48MB 0x60 +#define IEEE80211_OFDM_RATE_54MB 0x6C +#define IEEE80211_BASIC_RATE_MASK 0x80 + +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) + +#define IEEE80211_CCK_RATES_MASK 0x0000000F +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ + IEEE80211_CCK_RATE_2MB_MASK) +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ + IEEE80211_CCK_RATE_5MB_MASK | \ + IEEE80211_CCK_RATE_11MB_MASK) + +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ + IEEE80211_OFDM_RATE_12MB_MASK | \ + IEEE80211_OFDM_RATE_24MB_MASK) +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ + IEEE80211_OFDM_RATE_9MB_MASK | \ + IEEE80211_OFDM_RATE_18MB_MASK | \ + IEEE80211_OFDM_RATE_36MB_MASK | \ + IEEE80211_OFDM_RATE_48MB_MASK | \ + IEEE80211_OFDM_RATE_54MB_MASK) +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ + IEEE80211_CCK_DEFAULT_RATES_MASK) + + +/* This really should be 8, but not for our firmware */ +#define MAX_SUPPORTED_RATES 32 +#define COUNTRY_STRING_LEN 3 +#define MAX_COUNTRY_TRIPLETS 32 + +/* Headers */ +struct ieee80211_header { + __le16 frame_ctl; + __le16 duration_id; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; +} __packed; + +struct wl12xx_ie_header { + u8 id; + u8 len; +} __packed; + +/* IEs */ + +struct wl12xx_ie_ssid { + struct wl12xx_ie_header header; + char ssid[IW_ESSID_MAX_SIZE]; +} __packed; + +struct wl12xx_ie_rates { + struct wl12xx_ie_header header; + u8 rates[MAX_SUPPORTED_RATES]; +} __packed; + +struct wl12xx_ie_ds_params { + struct wl12xx_ie_header header; + u8 channel; +} __packed; + +struct country_triplet { + u8 channel; + u8 num_channels; + u8 max_tx_power; +} __packed; + +struct wl12xx_ie_country { + struct wl12xx_ie_header header; + u8 country_string[COUNTRY_STRING_LEN]; + struct country_triplet triplets[MAX_COUNTRY_TRIPLETS]; +} __packed; + + +/* Templates */ + +struct wl12xx_beacon_template { + struct ieee80211_header header; + __le32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + struct wl12xx_ie_ssid ssid; + struct wl12xx_ie_rates rates; + struct wl12xx_ie_rates ext_rates; + struct wl12xx_ie_ds_params ds_params; + struct wl12xx_ie_country country; +} __packed; + +struct wl12xx_null_data_template { + struct ieee80211_header header; +} __packed; + +struct wl12xx_ps_poll_template { + __le16 fc; + __le16 aid; + u8 bssid[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} __packed; + +struct wl12xx_qos_null_data_template { + struct ieee80211_header header; + __le16 qos_ctl; +} __packed; + +struct wl12xx_probe_req_template { + struct ieee80211_header header; + struct wl12xx_ie_ssid ssid; + struct wl12xx_ie_rates rates; + struct wl12xx_ie_rates ext_rates; +} __packed; + + +struct wl12xx_probe_resp_template { + struct ieee80211_header header; + __le32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + struct wl12xx_ie_ssid ssid; + struct wl12xx_ie_rates rates; + struct wl12xx_ie_rates ext_rates; + struct wl12xx_ie_ds_params ds_params; + struct wl12xx_ie_country country; +} __packed; + +#endif diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 2f98058be4510f217f17c5f09a0f832d5c5e8198..b447559f1db52dbf2780afff4ca3454fbecf6dbd 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig @@ -5,40 +5,6 @@ menuconfig WL12XX This will enable TI wl12xx driver support. The drivers make use of the mac80211 stack. -config WL1251 - tristate "TI wl1251 support" - depends on WL12XX && GENERIC_HARDIRQS - select FW_LOADER - select CRC7 - ---help--- - This module adds support for wireless adapters based on - TI wl1251 chipset. - - If you choose to build a module, it'll be called wl1251. Say - N if unsure. - -config WL1251_SPI - tristate "TI wl1251 SPI support" - depends on WL1251 && SPI_MASTER - ---help--- - This module adds support for the SPI interface of adapters using - TI wl1251 chipset. Select this if your platform is using - the SPI bus. - - If you choose to build a module, it'll be called wl1251_spi. - Say N if unsure. - -config WL1251_SDIO - tristate "TI wl1251 SDIO support" - depends on WL1251 && MMC - ---help--- - This module adds support for the SDIO interface of adapters using - TI wl1251 chipset. Select this if your platform is using - the SDIO bus. - - If you choose to build a module, it'll be called - wl1251_sdio. Say N if unsure. - config WL1271 tristate "TI wl1271 support" depends on WL12XX && GENERIC_HARDIRQS @@ -74,4 +40,7 @@ config WL1271_SDIO If you choose to build a module, it'll be called wl1271_sdio. Say N if unsure. - +config WL12XX_PLATFORM_DATA + bool + depends on WL1271_SDIO != n + default y diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile index 078b4398ac1f6e46f6a65158c2a45a1f4c50aedf..3a807444b2af425f251f41ae026bfa1d350100e7 100644 --- a/drivers/net/wireless/wl12xx/Makefile +++ b/drivers/net/wireless/wl12xx/Makefile @@ -1,12 +1,3 @@ -wl1251-objs = wl1251_main.o wl1251_event.o \ - wl1251_tx.o wl1251_rx.o wl1251_ps.o wl1251_cmd.o \ - wl1251_acx.o wl1251_boot.o wl1251_init.o \ - wl1251_debugfs.o wl1251_io.o - -obj-$(CONFIG_WL1251) += wl1251.o -obj-$(CONFIG_WL1251_SPI) += wl1251_spi.o -obj-$(CONFIG_WL1251_SDIO) += wl1251_sdio.o - wl1271-objs = wl1271_main.o wl1271_cmd.o wl1271_io.o \ wl1271_event.o wl1271_tx.o wl1271_rx.o \ wl1271_ps.o wl1271_acx.o wl1271_boot.o \ @@ -16,3 +7,6 @@ wl1271-$(CONFIG_NL80211_TESTMODE) += wl1271_testmode.o obj-$(CONFIG_WL1271) += wl1271.o obj-$(CONFIG_WL1271_SPI) += wl1271_spi.o obj-$(CONFIG_WL1271_SDIO) += wl1271_sdio.o + +# small builtin driver bit +obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx_platform_data.o diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index dd3cee6ea5bb6d486b27973d95f9fa5a35e842f1..8a4cd763e5a24c49080a97a0100f994e1f4993d0 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h @@ -117,10 +117,7 @@ enum { #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) -/* - * Enable/disable 802.11a support for WL1273 - */ -#undef WL1271_80211A_ENABLED +#define WL1271_CIPHER_SUITE_GEM 0x00147201 #define WL1271_BUSY_WORD_CNT 1 #define WL1271_BUSY_WORD_LEN (WL1271_BUSY_WORD_CNT * sizeof(u32)) @@ -133,6 +130,8 @@ enum { #define ACX_TX_DESCRIPTORS 32 +#define WL1271_AGGR_BUFFER_SIZE (4 * PAGE_SIZE) + enum wl1271_state { WL1271_STATE_OFF, WL1271_STATE_ON, @@ -301,6 +300,7 @@ struct wl1271_rx_mem_pool_addr { struct wl1271_scan { struct cfg80211_scan_request *req; bool *scanned_ch; + bool failed; u8 state; u8 ssid[IW_ESSID_MAX_SIZE+1]; size_t ssid_len; @@ -313,7 +313,7 @@ struct wl1271_if_operations { bool fixed); void (*reset)(struct wl1271 *wl); void (*init)(struct wl1271 *wl); - void (*power)(struct wl1271 *wl, bool enable); + int (*power)(struct wl1271 *wl, bool enable); struct device* (*dev)(struct wl1271 *wl); void (*enable_irq)(struct wl1271 *wl); void (*disable_irq)(struct wl1271 *wl); @@ -330,6 +330,7 @@ struct wl1271 { void (*set_power)(bool enable); int irq; + int ref_clock; spinlock_t wl_lock; @@ -349,6 +350,7 @@ struct wl1271 { #define WL1271_FLAG_IDLE (10) #define WL1271_FLAG_IDLE_REQUESTED (11) #define WL1271_FLAG_PSPOLL_FAILURE (12) +#define WL1271_FLAG_STA_STATE_SENT (13) unsigned long flags; struct wl1271_partition_set part; @@ -361,6 +363,7 @@ struct wl1271 { u8 *fw; size_t fw_len; struct wl1271_nvs_file *nvs; + size_t nvs_len; s8 hw_pg_ver; @@ -407,9 +410,15 @@ struct wl1271 { /* Rx memory pool address */ struct wl1271_rx_mem_pool_addr rx_mem_pool_addr; + /* Intermediate buffer, used for packet aggregation */ + u8 *aggr_buf; + /* The target interrupt mask */ struct work_struct irq_work; + /* Hardware recovery work */ + struct work_struct recovery_work; + /* The mbox event mask */ u32 event_mask; @@ -418,6 +427,7 @@ struct wl1271 { /* Are we currently scanning */ struct wl1271_scan scan; + struct delayed_work scan_complete_work; /* Our association ID */ u16 aid; @@ -474,6 +484,8 @@ struct wl1271 { bool sg_enabled; + bool enable_11a; + struct list_head list; /* Most recently reported noise in dBm */ @@ -497,14 +509,4 @@ int wl1271_plt_stop(struct wl1271 *wl); #define WL1271_PRE_POWER_ON_SLEEP 20 /* in miliseconds */ #define WL1271_POWER_ON_SLEEP 200 /* in miliseconds */ -static inline bool wl1271_11a_enabled(void) -{ - /* FIXME: this could be determined based on the NVS-INI file */ -#ifdef WL1271_80211A_ENABLED - return true; -#else - return false; -#endif -} - #endif diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.c b/drivers/net/wireless/wl12xx/wl1271_acx.c index bb245f05af496a2535ea5324b4113f4d499a4628..6189934052629d61b528ba771d30f94865e51f6f 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.c +++ b/drivers/net/wireless/wl12xx/wl1271_acx.c @@ -86,40 +86,6 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) return ret; } -int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len) -{ - struct acx_revision *rev; - int ret; - - wl1271_debug(DEBUG_ACX, "acx fw rev"); - - rev = kzalloc(sizeof(*rev), GFP_KERNEL); - if (!rev) { - ret = -ENOMEM; - goto out; - } - - ret = wl1271_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev)); - if (ret < 0) { - wl1271_warning("ACX_FW_REV interrogate failed"); - goto out; - } - - /* be careful with the buffer sizes */ - strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version))); - - /* - * if the firmware version string is exactly - * sizeof(rev->fw_version) long or fw_len is less than - * sizeof(rev->fw_version) it won't be null terminated - */ - buf[min(len, sizeof(rev->fw_version)) - 1] = '\0'; - -out: - kfree(rev); - return ret; -} - int wl1271_acx_tx_power(struct wl1271 *wl, int power) { struct acx_current_tx_power *acx; @@ -269,7 +235,7 @@ int wl1271_acx_pd_threshold(struct wl1271 *wl) out: kfree(pd); - return 0; + return ret; } int wl1271_acx_slot(struct wl1271 *wl, enum acx_slot_type slot_time) diff --git a/drivers/net/wireless/wl12xx/wl1271_acx.h b/drivers/net/wireless/wl12xx/wl1271_acx.h index 4235bc56f750eb4b40b036952cd246dc2e67db6c..ebb341d36e8c01a88f2fe423908c2a0994e6be1d 100644 --- a/drivers/net/wireless/wl12xx/wl1271_acx.h +++ b/drivers/net/wireless/wl12xx/wl1271_acx.h @@ -100,35 +100,6 @@ struct acx_error_counter { __le32 seq_num_miss; } __packed; -struct acx_revision { - struct acx_header header; - - /* - * The WiLink firmware version, an ASCII string x.x.x.x, - * that uniquely identifies the current firmware. - * The left most digit is incremented each time a - * significant change is made to the firmware, such as - * code redesign or new platform support. - * The second digit is incremented when major enhancements - * are added or major fixes are made. - * The third digit is incremented for each GA release. - * The fourth digit is incremented for each build. - * The first two digits identify a firmware release version, - * in other words, a unique set of features. - * The first three digits identify a GA release. - */ - char fw_version[20]; - - /* - * This 4 byte field specifies the WiLink hardware version. - * bits 0 - 15: Reserved. - * bits 16 - 23: Version ID - The WiLink version ID - * (1 = first spin, 2 = second spin, and so on). - * bits 24 - 31: Chip ID - The WiLink chip ID. - */ - __le32 hw_version; -} __packed; - enum wl1271_psm_mode { /* Active mode */ WL1271_PSM_CAM = 0, @@ -1060,7 +1031,6 @@ enum { ACX_PEER_HT_CAP = 0x0057, ACX_HT_BSS_OPERATION = 0x0058, ACX_COEX_ACTIVITY = 0x0059, - ACX_SET_SMART_REFLEX_DEBUG = 0x005A, ACX_SET_DCO_ITRIM_PARAMS = 0x0061, DOT11_RX_MSDU_LIFE_TIME = 0x1004, DOT11_CUR_TX_PWR = 0x100D, @@ -1077,7 +1047,6 @@ enum { int wl1271_acx_wake_up_conditions(struct wl1271 *wl); int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth); -int wl1271_acx_fw_version(struct wl1271 *wl, char *buf, size_t len); int wl1271_acx_tx_power(struct wl1271 *wl, int power); int wl1271_acx_feature_cfg(struct wl1271 *wl); int wl1271_acx_mem_map(struct wl1271 *wl, diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.c b/drivers/net/wireless/wl12xx/wl1271_boot.c index f36430b0336d87d3c118962f0e573132ef7afa07..b910212420985cd3ecf28dfa18dd3584b03b1cb7 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.c +++ b/drivers/net/wireless/wl12xx/wl1271_boot.c @@ -225,6 +225,28 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) if (wl->nvs == NULL) return -ENODEV; + /* + * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band + * configurations) can be removed when those NVS files stop floating + * around. + */ + if (wl->nvs_len == sizeof(struct wl1271_nvs_file) || + wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) { + if (wl->nvs->general_params.dual_mode_select) + wl->enable_11a = true; + } + + if (wl->nvs_len != sizeof(struct wl1271_nvs_file) && + (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE || + wl->enable_11a)) { + wl1271_error("nvs size is not as expected: %zu != %zu", + wl->nvs_len, sizeof(struct wl1271_nvs_file)); + kfree(wl->nvs); + wl->nvs = NULL; + wl->nvs_len = 0; + return -EILSEQ; + } + /* only the first part of the NVS needs to be uploaded */ nvs_len = sizeof(wl->nvs->nvs); nvs_ptr = (u8 *)wl->nvs->nvs; @@ -251,8 +273,10 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) burst_len = nvs_ptr[0]; dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8)); - /* FIXME: Due to our new wl1271_translate_reg_addr function, - we need to add the REGISTER_BASE to the destination */ + /* + * Due to our new wl1271_translate_reg_addr function, + * we need to add the REGISTER_BASE to the destination + */ dest_addr += REGISTERS_BASE; /* We move our pointer to the data */ @@ -274,31 +298,21 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl) /* * We've reached the first zero length, the first NVS table - * is 7 bytes further. + * is located at an aligned offset which is at least 7 bytes further. */ - nvs_ptr += 7; + nvs_ptr = (u8 *)wl->nvs->nvs + + ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4); nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs; - nvs_len = ALIGN(nvs_len, 4); - /* FIXME: The driver sets the partition here, but this is not needed, - since it sets to the same one as currently in use */ /* Now we must set the partition correctly */ wl1271_set_partition(wl, &part_table[PART_WORK]); /* Copy the NVS tables to a new block to ensure alignment */ - /* FIXME: We jump 3 more bytes before uploading the NVS. It seems - that our NVS files have three extra zeros here. I'm not sure whether - the problem is in our NVS generation or we should really jumpt these - 3 bytes here */ - nvs_ptr += 3; - - nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); if - (!nvs_aligned) return -ENOMEM; + nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); + if (!nvs_aligned) + return -ENOMEM; /* And finally we upload the NVS tables */ - /* FIXME: In wl1271, we upload everything at once. - No endianness handling needed here?! The ref driver doesn't do - anything about it at this point */ wl1271_write(wl, CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, false); kfree(nvs_aligned); @@ -457,17 +471,20 @@ int wl1271_boot(struct wl1271 *wl) { int ret = 0; u32 tmp, clk, pause; + int ref_clock = wl->ref_clock; wl1271_boot_hw_version(wl); - if (REF_CLOCK == 0 || REF_CLOCK == 2 || REF_CLOCK == 4) + if (ref_clock == 0 || ref_clock == 2 || ref_clock == 4) /* ref clk: 19.2/38.4/38.4-XTAL */ clk = 0x3; - else if (REF_CLOCK == 1 || REF_CLOCK == 3) + else if (ref_clock == 1 || ref_clock == 3) /* ref clk: 26/52 */ clk = 0x5; + else + return -EINVAL; - if (REF_CLOCK != 0) { + if (ref_clock != 0) { u16 val; /* Set clock type (open drain) */ val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE); @@ -493,10 +510,7 @@ int wl1271_boot(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); - pause &= ~(WU_COUNTER_PAUSE_VAL); /* FIXME: This should probably be - * WU_COUNTER_PAUSE_VAL instead of - * 0x3ff (magic number ). How does - * this work?! */ + pause &= ~(WU_COUNTER_PAUSE_VAL); pause |= WU_COUNTER_PAUSE_VAL; wl1271_write32(wl, WU_COUNTER_PAUSE, pause); @@ -516,7 +530,7 @@ int wl1271_boot(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); /* 2 */ - clk |= (REF_CLOCK << 1) << 4; + clk |= (ref_clock << 1) << 4; wl1271_write32(wl, DRPW_SCRATCH_START, clk); wl1271_set_partition(wl, &part_table[PART_WORK]); @@ -550,7 +564,6 @@ int wl1271_boot(struct wl1271 *wl) if (ret < 0) goto out; - /* FIXME: Need to check whether this is really what we want */ wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); diff --git a/drivers/net/wireless/wl12xx/wl1271_boot.h b/drivers/net/wireless/wl12xx/wl1271_boot.h index f829699d597e1c00faff1eee7afe9c642e951b40..f73b0b15a280c3c1e0c20cc2019ff88fd8f1dbd9 100644 --- a/drivers/net/wireless/wl12xx/wl1271_boot.h +++ b/drivers/net/wireless/wl12xx/wl1271_boot.h @@ -46,7 +46,6 @@ struct wl1271_static_data { /* delay between retries */ #define INIT_LOOP_DELAY 50 -#define REF_CLOCK 2 #define WU_COUNTER_PAUSE_VAL 0x3FF #define WELP_ARM_COMMAND_VAL 0x4 diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c index ce503ddd5a41e8504d894cd5516973d078af8769..5d3e8485ea4e51dfca8757ec116cfb8f63736fdf 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c @@ -94,6 +94,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, status = le16_to_cpu(cmd->status); if (status != CMD_STATUS_SUCCESS) { wl1271_error("command execute failure %d", status); + ieee80211_queue_work(wl->hw, &wl->recovery_work); ret = -EIO; } @@ -107,6 +108,8 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, int wl1271_cmd_general_parms(struct wl1271 *wl) { struct wl1271_general_parms_cmd *gen_parms; + struct wl1271_ini_general_params *gp = &wl->nvs->general_params; + bool answer = false; int ret; if (!wl->nvs) @@ -118,13 +121,24 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM; - memcpy(&gen_parms->general_params, &wl->nvs->general_params, - sizeof(struct wl1271_ini_general_params)); + memcpy(&gen_parms->general_params, gp, sizeof(*gp)); - ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0); - if (ret < 0) + if (gp->tx_bip_fem_auto_detect) + answer = true; + + ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer); + if (ret < 0) { wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed"); + goto out; + } + + gp->tx_bip_fem_manufacturer = + gen_parms->general_params.tx_bip_fem_manufacturer; + + wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", + answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); +out: kfree(gen_parms); return ret; } @@ -170,6 +184,39 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) return ret; } +int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) +{ + struct wl1271_ext_radio_parms_cmd *ext_radio_parms; + struct conf_rf_settings *rf = &wl->conf.rf; + int ret; + + if (!wl->nvs) + return -ENODEV; + + ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL); + if (!ext_radio_parms) + return -ENOMEM; + + ext_radio_parms->test.id = TEST_CMD_INI_FILE_RF_EXTENDED_PARAM; + + memcpy(ext_radio_parms->tx_per_channel_power_compensation_2, + rf->tx_per_channel_power_compensation_2, + CONF_TX_PWR_COMPENSATION_LEN_2); + memcpy(ext_radio_parms->tx_per_channel_power_compensation_5, + rf->tx_per_channel_power_compensation_5, + CONF_TX_PWR_COMPENSATION_LEN_5); + + wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_EXT_RADIO_PARAM: ", + ext_radio_parms, sizeof(*ext_radio_parms)); + + ret = wl1271_cmd_test(wl, ext_radio_parms, sizeof(*ext_radio_parms), 0); + if (ret < 0) + wl1271_warning("TEST_CMD_INI_FILE_RF_EXTENDED_PARAM failed"); + + kfree(ext_radio_parms); + return ret; +} + /* * Poll the mailbox event field until any of the bits in the mask is set or a * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) @@ -182,8 +229,10 @@ static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); do { - if (time_after(jiffies, timeout)) + if (time_after(jiffies, timeout)) { + ieee80211_queue_work(wl->hw, &wl->recovery_work); return -ETIMEDOUT; + } msleep(1); @@ -390,18 +439,11 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) return ret; } -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) +int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) { struct wl1271_cmd_ps_params *ps_params = NULL; int ret = 0; - /* FIXME: this should be in ps.c */ - ret = wl1271_acx_wake_up_conditions(wl); - if (ret < 0) { - wl1271_error("couldn't set wake up conditions"); - goto out; - } - wl1271_debug(DEBUG_CMD, "cmd set ps mode"); ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); @@ -412,9 +454,9 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) ps_params->ps_mode = ps_mode; ps_params->send_null_data = send; - ps_params->retries = 5; - ps_params->hang_over_period = 1; - ps_params->null_data_rate = cpu_to_le32(wl->basic_rate_set); + ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries; + ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period; + ps_params->null_data_rate = cpu_to_le32(rates); ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, sizeof(*ps_params), 0); @@ -428,41 +470,6 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send) return ret; } -int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, - size_t len) -{ - struct cmd_read_write_memory *cmd; - int ret = 0; - - wl1271_debug(DEBUG_CMD, "cmd read memory"); - - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - if (!cmd) { - ret = -ENOMEM; - goto out; - } - - WARN_ON(len > MAX_READ_SIZE); - len = min_t(size_t, len, MAX_READ_SIZE); - - cmd->addr = cpu_to_le32(addr); - cmd->size = cpu_to_le32(len); - - ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd), - sizeof(*cmd)); - if (ret < 0) { - wl1271_error("read memory command failed: %d", ret); - goto out; - } - - /* the read command got in */ - memcpy(answer, cmd->value, len); - -out: - kfree(cmd); - return ret; -} - int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, void *buf, size_t buf_len, int index, u32 rates) { @@ -523,7 +530,7 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl) } ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, ptr, size, 0, - WL1271_RATE_AUTOMATIC); + wl->basic_rate); out: dev_kfree_skb(skb); @@ -546,7 +553,7 @@ int wl1271_cmd_build_klv_null_data(struct wl1271 *wl) ret = wl1271_cmd_template_set(wl, CMD_TEMPL_KLV, skb->data, skb->len, CMD_TEMPL_KLV_IDX_NULL_DATA, - WL1271_RATE_AUTOMATIC); + wl->basic_rate); out: dev_kfree_skb(skb); @@ -623,7 +630,7 @@ int wl1271_build_qos_null_data(struct wl1271 *wl) return wl1271_cmd_template_set(wl, CMD_TEMPL_QOS_NULL_DATA, &template, sizeof(template), 0, - WL1271_RATE_AUTOMATIC); + wl->basic_rate); } int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) @@ -746,3 +753,31 @@ int wl1271_cmd_disconnect(struct wl1271 *wl) out: return ret; } + +int wl1271_cmd_set_sta_state(struct wl1271 *wl) +{ + struct wl1271_cmd_set_sta_state *cmd; + int ret = 0; + + wl1271_debug(DEBUG_CMD, "cmd set sta state"); + + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + if (!cmd) { + ret = -ENOMEM; + goto out; + } + + cmd->state = WL1271_CMD_STA_STATE_CONNECTED; + + ret = wl1271_cmd_send(wl, CMD_SET_STA_STATE, cmd, sizeof(*cmd), 0); + if (ret < 0) { + wl1271_error("failed to send set STA state command"); + goto out_free; + } + +out_free: + kfree(cmd); + +out: + return ret; +} diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.h b/drivers/net/wireless/wl12xx/wl1271_cmd.h index af577ee8eb0257c4585c86518f776b98d380e387..a0caf4fc37b1a4936917b3287442e72d1fa5fdd8 100644 --- a/drivers/net/wireless/wl12xx/wl1271_cmd.h +++ b/drivers/net/wireless/wl12xx/wl1271_cmd.h @@ -33,12 +33,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, size_t res_len); int wl1271_cmd_general_parms(struct wl1271 *wl); int wl1271_cmd_radio_parms(struct wl1271 *wl); +int wl1271_cmd_ext_radio_parms(struct wl1271 *wl); int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type); int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); -int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send); +int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send); int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, size_t len); int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, @@ -55,6 +56,7 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, u8 key_size, const u8 *key, const u8 *addr, u32 tx_seq_32, u16 tx_seq_16); int wl1271_cmd_disconnect(struct wl1271 *wl); +int wl1271_cmd_set_sta_state(struct wl1271 *wl); enum wl1271_commands { CMD_INTERROGATE = 1, /*use this to read information elements*/ @@ -160,41 +162,6 @@ enum { MAX_COMMAND_STATUS = 0xff }; - -/* - * CMD_READ_MEMORY - * - * The host issues this command to read the WiLink device memory/registers. - * - * Note: The Base Band address has special handling (16 bits registers and - * addresses). For more information, see the hardware specification. - */ -/* - * CMD_WRITE_MEMORY - * - * The host issues this command to write the WiLink device memory/registers. - * - * The Base Band address has special handling (16 bits registers and - * addresses). For more information, see the hardware specification. - */ -#define MAX_READ_SIZE 256 - -struct cmd_read_write_memory { - struct wl1271_cmd_header header; - - /* The address of the memory to read from or write to.*/ - __le32 addr; - - /* The amount of data in bytes to read from or write to the WiLink - * device.*/ - __le32 size; - - /* The actual value read from or written to the Wilink. The source - of this field is the Host in WRITE command or the Wilink in READ - command. */ - u8 value[MAX_READ_SIZE]; -} __packed; - #define CMDMBOX_HEADER_LEN 4 #define CMDMBOX_INFO_ELEM_HEADER_LEN 4 @@ -313,7 +280,7 @@ enum wl1271_cmd_key_type { KEY_WEP = 1, KEY_TKIP = 2, KEY_AES = 3, - KEY_GEM = 4 + KEY_GEM = 4, }; /* FIXME: Add description for key-types */ @@ -358,13 +325,14 @@ enum wl1271_channel_tune_bands { WL1271_CHANNEL_TUNE_BAND_4_9 }; -#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 +#define WL1271_PD_REFERENCE_POINT_BAND_B_G 0 -#define TEST_CMD_P2G_CAL 0x02 -#define TEST_CMD_CHANNEL_TUNE 0x0d -#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d -#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19 -#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E +#define TEST_CMD_P2G_CAL 0x02 +#define TEST_CMD_CHANNEL_TUNE 0x0d +#define TEST_CMD_UPDATE_PD_REFERENCE_POINT 0x1d +#define TEST_CMD_INI_FILE_RADIO_PARAM 0x19 +#define TEST_CMD_INI_FILE_GENERAL_PARAM 0x1E +#define TEST_CMD_INI_FILE_RF_EXTENDED_PARAM 0x26 struct wl1271_general_parms_cmd { struct wl1271_cmd_header header; @@ -397,6 +365,16 @@ struct wl1271_radio_parms_cmd { u8 padding3[2]; } __packed; +struct wl1271_ext_radio_parms_cmd { + struct wl1271_cmd_header header; + + struct wl1271_cmd_test_header test; + + u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2]; + u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; + u8 padding[3]; +} __packed; + struct wl1271_cmd_cal_channel_tune { struct wl1271_cmd_header header; @@ -469,4 +447,13 @@ struct wl1271_cmd_disconnect { u8 padding; } __packed; +#define WL1271_CMD_STA_STATE_CONNECTED 1 + +struct wl1271_cmd_set_sta_state { + struct wl1271_cmd_header header; + + u8 state; + u8 padding[3]; +} __packed; + #endif /* __WL1271_CMD_H__ */ diff --git a/drivers/net/wireless/wl12xx/wl1271_conf.h b/drivers/net/wireless/wl12xx/wl1271_conf.h index 0435ffda8f7340b14cbe9dfcee73f492a80c6b3e..5f78a6cb14334b55f5e195d3df838d80ec3c7649 100644 --- a/drivers/net/wireless/wl12xx/wl1271_conf.h +++ b/drivers/net/wireless/wl12xx/wl1271_conf.h @@ -595,7 +595,7 @@ struct conf_tx_ac_category { u16 tx_op_limit; }; -#define CONF_TX_MAX_TID_COUNT 7 +#define CONF_TX_MAX_TID_COUNT 8 enum { CONF_CHANNEL_TYPE_DCF = 0, /* DC/LEGACY*/ @@ -911,6 +911,22 @@ struct conf_conn_settings { */ u8 psm_entry_retries; + /* + * Specifies the maximum number of times to try transmit the PSM entry + * null-func frame for each PSM entry attempt + * + * Range 0 - 255 + */ + u8 psm_entry_nullfunc_retries; + + /* + * Specifies the time to linger in active mode after successfully + * transmitting the PSM entry null-func frame. + * + * Range 0 - 255 TU's + */ + u8 psm_entry_hangover_period; + /* * * Specifies the interval of the connection keep-alive null-func @@ -1016,6 +1032,64 @@ struct conf_roam_trigger_settings { u8 avg_weight_snr_data; }; +struct conf_scan_settings { + /* + * The minimum time to wait on each channel for active scans + * + * Range: 0 - 65536 tu + */ + u16 min_dwell_time_active; + + /* + * The maximum time to wait on each channel for active scans + * + * Range: 0 - 65536 tu + */ + u16 max_dwell_time_active; + + /* + * The maximum time to wait on each channel for passive scans + * + * Range: 0 - 65536 tu + */ + u16 min_dwell_time_passive; + + /* + * The maximum time to wait on each channel for passive scans + * + * Range: 0 - 65536 tu + */ + u16 max_dwell_time_passive; + + /* + * Number of probe requests to transmit on each active scan channel + * + * Range: u8 + */ + u16 num_probe_reqs; + +}; + +/* these are number of channels on the band divided by two, rounded up */ +#define CONF_TX_PWR_COMPENSATION_LEN_2 7 +#define CONF_TX_PWR_COMPENSATION_LEN_5 18 + +struct conf_rf_settings { + /* + * Per channel power compensation for 2.4GHz + * + * Range: s8 + */ + u8 tx_per_channel_power_compensation_2[CONF_TX_PWR_COMPENSATION_LEN_2]; + + /* + * Per channel power compensation for 5GHz + * + * Range: s8 + */ + u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5]; +}; + struct conf_drv_settings { struct conf_sg_settings sg; struct conf_rx_settings rx; @@ -1024,6 +1098,8 @@ struct conf_drv_settings { struct conf_itrim_settings itrim; struct conf_pm_config_settings pm_config; struct conf_roam_trigger_settings roam_trigger; + struct conf_scan_settings scan; + struct conf_rf_settings rf; }; #endif diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index 25ce2cd5e3f3fa406f1d7fb3aa574da9d5113631..7b3f503829631018630ca21e9faa67f840db10c8 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c @@ -41,6 +41,9 @@ void wl1271_pspoll_work(struct work_struct *work) mutex_lock(&wl->mutex); + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags)) goto out; @@ -52,7 +55,7 @@ void wl1271_pspoll_work(struct work_struct *work) * delivery failure occurred, and no-one changed state since, so * we should go back to powersave. */ - wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true); + wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true); out: mutex_unlock(&wl->mutex); @@ -70,7 +73,8 @@ static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl) /* force active mode receive data from the AP */ if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { - ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true); + ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, + wl->basic_rate, true); if (ret < 0) return; set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags); @@ -91,6 +95,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl, bool *beacon_loss) { int ret = 0; + u32 total_retries = wl->conf.conn.psm_entry_retries; wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status); @@ -104,10 +109,10 @@ static int wl1271_event_ps_report(struct wl1271 *wl, break; } - if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) { + if (wl->psm_entry_retry < total_retries) { wl->psm_entry_retry++; ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - true); + wl->basic_rate, true); } else { wl1271_info("No ack to nullfunc from AP."); wl->psm_entry_retry = 0; @@ -143,7 +148,7 @@ static int wl1271_event_ps_report(struct wl1271 *wl, /* make sure the firmware goes to active mode - the frame to be sent next will indicate to the AP, that we are active. */ ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - false); + wl->basic_rate, false); break; case EVENT_EXIT_POWER_SAVE_SUCCESS: default: diff --git a/drivers/net/wireless/wl12xx/wl1271_init.c b/drivers/net/wireless/wl12xx/wl1271_init.c index 4447af1557f5c2af3d95ff7576118e543b8e0ea1..8044bba70ee789b377e1183cef516cd34d36d02b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_init.c +++ b/drivers/net/wireless/wl12xx/wl1271_init.c @@ -53,6 +53,7 @@ static int wl1271_init_hwenc_config(struct wl1271 *wl) int wl1271_init_templates_config(struct wl1271 *wl) { int ret, i; + size_t size; /* send empty templates for fw memory reservation */ ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, NULL, @@ -61,14 +62,12 @@ int wl1271_init_templates_config(struct wl1271 *wl) if (ret < 0) return ret; - if (wl1271_11a_enabled()) { - size_t size = sizeof(struct wl12xx_probe_req_template); - ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, - NULL, size, 0, - WL1271_RATE_AUTOMATIC); - if (ret < 0) - return ret; - } + size = sizeof(struct wl12xx_probe_req_template); + ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5, + NULL, size, 0, + WL1271_RATE_AUTOMATIC); + if (ret < 0) + return ret; ret = wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, NULL, sizeof(struct wl12xx_null_data_template), @@ -223,6 +222,10 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) return ret; + ret = wl1271_cmd_ext_radio_parms(wl); + if (ret < 0) + return ret; + /* Template settings */ ret = wl1271_init_templates_config(wl); if (ret < 0) @@ -291,8 +294,16 @@ int wl1271_hw_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; - /* Default TID configuration */ + /* Default TID/AC configuration */ + BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { + conf_ac = &wl->conf.tx.ac_conf[i]; + ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, + conf_ac->cw_max, conf_ac->aifsn, + conf_ac->tx_op_limit); + if (ret < 0) + goto out_free_memmap; + conf_tid = &wl->conf.tx.tid_conf[i]; ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, conf_tid->channel_type, @@ -305,16 +316,6 @@ int wl1271_hw_init(struct wl1271 *wl) goto out_free_memmap; } - /* Default AC configuration */ - for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { - conf_ac = &wl->conf.tx.ac_conf[i]; - ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, - conf_ac->cw_max, conf_ac->aifsn, - conf_ac->tx_op_limit); - if (ret < 0) - goto out_free_memmap; - } - /* Configure TX rate classes */ ret = wl1271_acx_rate_policies(wl); if (ret < 0) diff --git a/drivers/net/wireless/wl12xx/wl1271_io.h b/drivers/net/wireless/wl12xx/wl1271_io.h index bc806c74c63ab4214d70008bb58fa95a22546395..c1f92e65ded0b8c2895cce3b634562bb2b329b97 100644 --- a/drivers/net/wireless/wl12xx/wl1271_io.h +++ b/drivers/net/wireless/wl12xx/wl1271_io.h @@ -144,10 +144,13 @@ static inline void wl1271_power_off(struct wl1271 *wl) clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); } -static inline void wl1271_power_on(struct wl1271 *wl) +static inline int wl1271_power_on(struct wl1271 *wl) { - wl->if_ops->power(wl, true); - set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + int ret = wl->if_ops->power(wl, true); + if (ret == 0) + set_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + + return ret; } diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 9d68f0012f05af67317ff6cfc9668b833e1c9d00..48a4b9961ae6e1bea44a4985bca56e46bdf1ee32 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c @@ -124,28 +124,28 @@ static struct conf_drv_settings default_conf = { }, .ac_conf_count = 4, .ac_conf = { - [0] = { + [CONF_TX_AC_BE] = { .ac = CONF_TX_AC_BE, .cw_min = 15, .cw_max = 63, .aifsn = 3, .tx_op_limit = 0, }, - [1] = { + [CONF_TX_AC_BK] = { .ac = CONF_TX_AC_BK, .cw_min = 15, .cw_max = 63, .aifsn = 7, .tx_op_limit = 0, }, - [2] = { + [CONF_TX_AC_VI] = { .ac = CONF_TX_AC_VI, .cw_min = 15, .cw_max = 63, .aifsn = CONF_TX_AIFS_PIFS, .tx_op_limit = 3008, }, - [3] = { + [CONF_TX_AC_VO] = { .ac = CONF_TX_AC_VO, .cw_min = 15, .cw_max = 63, @@ -153,64 +153,40 @@ static struct conf_drv_settings default_conf = { .tx_op_limit = 1504, }, }, - .tid_conf_count = 7, + .tid_conf_count = 4, .tid_conf = { - [0] = { - .queue_id = 0, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - }, - [1] = { - .queue_id = 1, - .channel_type = CONF_CHANNEL_TYPE_DCF, + [CONF_TX_AC_BE] = { + .queue_id = CONF_TX_AC_BE, + .channel_type = CONF_CHANNEL_TYPE_EDCF, .tsid = CONF_TX_AC_BE, .ps_scheme = CONF_PS_SCHEME_LEGACY, .ack_policy = CONF_ACK_POLICY_LEGACY, .apsd_conf = {0, 0}, }, - [2] = { - .queue_id = 2, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, + [CONF_TX_AC_BK] = { + .queue_id = CONF_TX_AC_BK, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_BK, .ps_scheme = CONF_PS_SCHEME_LEGACY, .ack_policy = CONF_ACK_POLICY_LEGACY, .apsd_conf = {0, 0}, }, - [3] = { - .queue_id = 3, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - }, - [4] = { - .queue_id = 4, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, + [CONF_TX_AC_VI] = { + .queue_id = CONF_TX_AC_VI, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_VI, .ps_scheme = CONF_PS_SCHEME_LEGACY, .ack_policy = CONF_ACK_POLICY_LEGACY, .apsd_conf = {0, 0}, }, - [5] = { - .queue_id = 5, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, + [CONF_TX_AC_VO] = { + .queue_id = CONF_TX_AC_VO, + .channel_type = CONF_CHANNEL_TYPE_EDCF, + .tsid = CONF_TX_AC_VO, .ps_scheme = CONF_PS_SCHEME_LEGACY, .ack_policy = CONF_ACK_POLICY_LEGACY, .apsd_conf = {0, 0}, }, - [6] = { - .queue_id = 6, - .channel_type = CONF_CHANNEL_TYPE_DCF, - .tsid = CONF_TX_AC_BE, - .ps_scheme = CONF_PS_SCHEME_LEGACY, - .ack_policy = CONF_ACK_POLICY_LEGACY, - .apsd_conf = {0, 0}, - } }, .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD, .tx_compl_timeout = 700, @@ -238,7 +214,9 @@ static struct conf_drv_settings default_conf = { .ps_poll_recovery_period = 700, .bet_enable = CONF_BET_MODE_ENABLE, .bet_max_consecutive = 10, - .psm_entry_retries = 3, + .psm_entry_retries = 5, + .psm_entry_nullfunc_retries = 3, + .psm_entry_hangover_period = 1, .keep_alive_interval = 55000, .max_listen_interval = 20, }, @@ -251,15 +229,34 @@ static struct conf_drv_settings default_conf = { .host_fast_wakeup_support = false }, .roam_trigger = { - /* FIXME: due to firmware bug, must use value 1 for now */ .trigger_pacing = 1, .avg_weight_rssi_beacon = 20, .avg_weight_rssi_data = 10, .avg_weight_snr_beacon = 20, .avg_weight_snr_data = 10 - } + }, + .scan = { + .min_dwell_time_active = 7500, + .max_dwell_time_active = 30000, + .min_dwell_time_passive = 30000, + .max_dwell_time_passive = 60000, + .num_probe_reqs = 2, + }, + .rf = { + .tx_per_channel_power_compensation_2 = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + .tx_per_channel_power_compensation_5 = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }, + }, }; +static void __wl1271_op_remove_interface(struct wl1271 *wl); + + static void wl1271_device_release(struct device *dev) { @@ -277,6 +274,67 @@ static struct platform_device wl1271_device = { static LIST_HEAD(wl_list); +static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, + void *arg) +{ + struct net_device *dev = arg; + struct wireless_dev *wdev; + struct wiphy *wiphy; + struct ieee80211_hw *hw; + struct wl1271 *wl; + struct wl1271 *wl_temp; + int ret = 0; + + /* Check that this notification is for us. */ + if (what != NETDEV_CHANGE) + return NOTIFY_DONE; + + wdev = dev->ieee80211_ptr; + if (wdev == NULL) + return NOTIFY_DONE; + + wiphy = wdev->wiphy; + if (wiphy == NULL) + return NOTIFY_DONE; + + hw = wiphy_priv(wiphy); + if (hw == NULL) + return NOTIFY_DONE; + + wl_temp = hw->priv; + list_for_each_entry(wl, &wl_list, list) { + if (wl == wl_temp) + break; + } + if (wl != wl_temp) + return NOTIFY_DONE; + + mutex_lock(&wl->mutex); + + if (wl->state == WL1271_STATE_OFF) + goto out; + + if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + goto out; + + ret = wl1271_ps_elp_wakeup(wl, false); + if (ret < 0) + goto out; + + if ((dev->operstate == IF_OPER_UP) && + !test_and_set_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags)) { + wl1271_cmd_set_sta_state(wl); + wl1271_info("Association completed."); + } + + wl1271_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); + + return NOTIFY_OK; +} + static void wl1271_conf_init(struct wl1271 *wl) { @@ -309,6 +367,10 @@ static int wl1271_plt_init(struct wl1271 *wl) if (ret < 0) return ret; + ret = wl1271_cmd_ext_radio_parms(wl); + if (ret < 0) + return ret; + ret = wl1271_init_templates_config(wl); if (ret < 0) return ret; @@ -346,8 +408,16 @@ static int wl1271_plt_init(struct wl1271 *wl) if (ret < 0) goto out_free_memmap; - /* Default TID configuration */ + /* Default TID/AC configuration */ + BUG_ON(wl->conf.tx.tid_conf_count != wl->conf.tx.ac_conf_count); for (i = 0; i < wl->conf.tx.tid_conf_count; i++) { + conf_ac = &wl->conf.tx.ac_conf[i]; + ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, + conf_ac->cw_max, conf_ac->aifsn, + conf_ac->tx_op_limit); + if (ret < 0) + goto out_free_memmap; + conf_tid = &wl->conf.tx.tid_conf[i]; ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id, conf_tid->channel_type, @@ -360,16 +430,6 @@ static int wl1271_plt_init(struct wl1271 *wl) goto out_free_memmap; } - /* Default AC configuration */ - for (i = 0; i < wl->conf.tx.ac_conf_count; i++) { - conf_ac = &wl->conf.tx.ac_conf[i]; - ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min, - conf_ac->cw_max, conf_ac->aifsn, - conf_ac->tx_op_limit); - if (ret < 0) - goto out_free_memmap; - } - /* Enable data path */ ret = wl1271_cmd_data_path(wl, 1); if (ret < 0) @@ -562,20 +622,6 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) return ret; } - /* - * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band - * configurations) can be removed when those NVS files stop floating - * around. - */ - if (fw->size != sizeof(struct wl1271_nvs_file) && - (fw->size != WL1271_INI_LEGACY_NVS_FILE_SIZE || - wl1271_11a_enabled())) { - wl1271_error("nvs size is not as expected: %zu != %zu", - fw->size, sizeof(struct wl1271_nvs_file)); - ret = -EILSEQ; - goto out; - } - wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL); if (!wl->nvs) { @@ -584,12 +630,37 @@ static int wl1271_fetch_nvs(struct wl1271 *wl) goto out; } + wl->nvs_len = fw->size; + out: release_firmware(fw); return ret; } +static void wl1271_recovery_work(struct work_struct *work) +{ + struct wl1271 *wl = + container_of(work, struct wl1271, recovery_work); + + mutex_lock(&wl->mutex); + + if (wl->state != WL1271_STATE_ON) + goto out; + + wl1271_info("Hardware recovery in progress."); + + if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) + ieee80211_connection_loss(wl->vif); + + /* reboot the chipset */ + __wl1271_op_remove_interface(wl); + ieee80211_restart_hw(wl->hw); + +out: + mutex_unlock(&wl->mutex); +} + static void wl1271_fw_wakeup(struct wl1271 *wl) { u32 elp_reg; @@ -610,8 +681,6 @@ static int wl1271_setup(struct wl1271 *wl) return -ENOMEM; } - INIT_WORK(&wl->irq_work, wl1271_irq_work); - INIT_WORK(&wl->tx_work, wl1271_tx_work); return 0; } @@ -621,7 +690,9 @@ static int wl1271_chip_wakeup(struct wl1271 *wl) int ret = 0; msleep(WL1271_PRE_POWER_ON_SLEEP); - wl1271_power_on(wl); + ret = wl1271_power_on(wl); + if (ret < 0) + goto out; msleep(WL1271_POWER_ON_SLEEP); wl1271_io_reset(wl); wl1271_io_init(wl); @@ -766,10 +837,12 @@ int wl1271_plt_stop(struct wl1271 *wl) out: mutex_unlock(&wl->mutex); + cancel_work_sync(&wl->irq_work); + cancel_work_sync(&wl->recovery_work); + return ret; } - static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1271 *wl = hw->priv; @@ -812,6 +885,10 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) return NETDEV_TX_OK; } +static struct notifier_block wl1271_dev_notifier = { + .notifier_call = wl1271_dev_notify, +}; + static int wl1271_op_start(struct ieee80211_hw *hw) { wl1271_debug(DEBUG_MAC80211, "mac80211 start"); @@ -928,13 +1005,10 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, return ret; } -static void wl1271_op_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static void __wl1271_op_remove_interface(struct wl1271 *wl) { - struct wl1271 *wl = hw->priv; int i; - mutex_lock(&wl->mutex); wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); wl1271_info("down"); @@ -948,12 +1022,10 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, ieee80211_enable_dyn_ps(wl->vif); if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { - mutex_unlock(&wl->mutex); - ieee80211_scan_completed(wl->hw, true); - mutex_lock(&wl->mutex); wl->scan.state = WL1271_SCAN_STATE_IDLE; kfree(wl->scan.scanned_ch); wl->scan.scanned_ch = NULL; + ieee80211_scan_completed(wl->hw, true); } wl->state = WL1271_STATE_OFF; @@ -962,9 +1034,11 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, mutex_unlock(&wl->mutex); + cancel_delayed_work_sync(&wl->scan_complete_work); cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); cancel_delayed_work_sync(&wl->pspoll_work); + cancel_delayed_work_sync(&wl->elp_work); mutex_lock(&wl->mutex); @@ -1006,8 +1080,19 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, wl->tx_res_if = NULL; kfree(wl->target_mem_map); wl->target_mem_map = NULL; +} +static void wl1271_op_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct wl1271 *wl = hw->priv; + + mutex_lock(&wl->mutex); + WARN_ON(wl->vif != vif); + __wl1271_op_remove_interface(wl); mutex_unlock(&wl->mutex); + + cancel_work_sync(&wl->recovery_work); } static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters) @@ -1289,7 +1374,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { wl1271_debug(DEBUG_PSM, "psm enabled"); ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, - true); + wl->basic_rate, true); } } else if (!(conf->flags & IEEE80211_CONF_PS) && test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) { @@ -1299,7 +1384,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (test_bit(WL1271_FLAG_PSM, &wl->flags)) ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, - true); + wl->basic_rate, true); } if (conf->power_level != wl->power_level) { @@ -1439,7 +1524,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wl1271_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd); wl1271_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN); wl1271_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x", - key_conf->alg, key_conf->keyidx, + key_conf->cipher, key_conf->keyidx, key_conf->keylen, key_conf->flags); wl1271_dump(DEBUG_CRYPT, "KEY: ", key_conf->key, key_conf->keylen); @@ -1455,28 +1540,34 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ret < 0) goto out_unlock; - switch (key_conf->alg) { - case ALG_WEP: + switch (key_conf->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: key_type = KEY_WEP; key_conf->hw_key_idx = key_conf->keyidx; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: key_type = KEY_TKIP; key_conf->hw_key_idx = key_conf->keyidx; tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: key_type = KEY_AES; key_conf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); break; + case WL1271_CIPHER_SUITE_GEM: + key_type = KEY_GEM; + tx_seq_32 = WL1271_TX_SECURITY_HI32(wl->tx_security_seq); + tx_seq_16 = WL1271_TX_SECURITY_LO16(wl->tx_security_seq); + break; default: - wl1271_error("Unknown key algo 0x%x", key_conf->alg); + wl1271_error("Unknown key algo 0x%x", key_conf->cipher); ret = -EOPNOTSUPP; goto out_sleep; @@ -1558,10 +1649,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, if (ret < 0) goto out; - if (wl1271_11a_enabled()) - ret = wl1271_scan(hw->priv, ssid, len, req); - else - ret = wl1271_scan(hw->priv, ssid, len, req); + ret = wl1271_scan(hw->priv, ssid, len, req); wl1271_ps_elp_sleep(wl); @@ -1633,7 +1721,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (ret < 0) goto out; - if ((changed && BSS_CHANGED_BEACON_INT) && + if ((changed & BSS_CHANGED_BEACON_INT) && (wl->bss_type == BSS_TYPE_IBSS)) { wl1271_debug(DEBUG_ADHOC, "ad-hoc beacon interval updated: %d", bss_conf->beacon_int); @@ -1642,7 +1730,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, do_join = true; } - if ((changed && BSS_CHANGED_BEACON) && + if ((changed & BSS_CHANGED_BEACON) && (wl->bss_type == BSS_TYPE_IBSS)) { struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); @@ -1776,12 +1864,15 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) && !test_bit(WL1271_FLAG_PSM, &wl->flags)) { mode = STATION_POWER_SAVE_MODE; - ret = wl1271_ps_set_mode(wl, mode, true); + ret = wl1271_ps_set_mode(wl, mode, + wl->basic_rate, + true); if (ret < 0) goto out_sleep; } } else { /* use defaults when not associated */ + clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags); clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags); wl->aid = 0; @@ -1993,21 +2084,24 @@ static struct ieee80211_rate wl1271_rates[] = { .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, }; -/* can't be const, mac80211 writes to this */ +/* + * Can't be const, mac80211 writes to this. The order of the channels here + * is designed to improve scanning. + */ static struct ieee80211_channel wl1271_channels[] = { { .hw_value = 1, .center_freq = 2412, .max_power = 25 }, - { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, - { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, - { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, { .hw_value = 5, .center_freq = 2432, .max_power = 25 }, - { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, - { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, - { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, { .hw_value = 9, .center_freq = 2452, .max_power = 25 }, - { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, - { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, - { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, { .hw_value = 13, .center_freq = 2472, .max_power = 25 }, + { .hw_value = 4, .center_freq = 2427, .max_power = 25 }, + { .hw_value = 8, .center_freq = 2447, .max_power = 25 }, + { .hw_value = 12, .center_freq = 2467, .max_power = 25 }, + { .hw_value = 3, .center_freq = 2422, .max_power = 25 }, + { .hw_value = 7, .center_freq = 2442, .max_power = 25 }, + { .hw_value = 11, .center_freq = 2462, .max_power = 25 }, + { .hw_value = 2, .center_freq = 2417, .max_power = 25 }, + { .hw_value = 6, .center_freq = 2437, .max_power = 25 }, + { .hw_value = 10, .center_freq = 2457, .max_power = 25 }, }; /* mapping to indexes for wl1271_rates */ @@ -2076,49 +2170,52 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = { .hw_value_short = CONF_HW_BIT_RATE_54MBPS, }, }; -/* 5 GHz band channels for WL1273 */ +/* + * 5 GHz band channels for WL1273 - can't be const, mac80211 writes to this. + * The order of the channels here is designed to improve scanning. + */ static struct ieee80211_channel wl1271_channels_5ghz[] = { { .hw_value = 183, .center_freq = 4915}, - { .hw_value = 184, .center_freq = 4920}, - { .hw_value = 185, .center_freq = 4925}, - { .hw_value = 187, .center_freq = 4935}, { .hw_value = 188, .center_freq = 4940}, - { .hw_value = 189, .center_freq = 4945}, - { .hw_value = 192, .center_freq = 4960}, - { .hw_value = 196, .center_freq = 4980}, - { .hw_value = 7, .center_freq = 5035}, { .hw_value = 8, .center_freq = 5040}, - { .hw_value = 9, .center_freq = 5045}, - { .hw_value = 11, .center_freq = 5055}, - { .hw_value = 12, .center_freq = 5060}, - { .hw_value = 16, .center_freq = 5080}, { .hw_value = 34, .center_freq = 5170}, - { .hw_value = 36, .center_freq = 5180}, - { .hw_value = 38, .center_freq = 5190}, - { .hw_value = 40, .center_freq = 5200}, - { .hw_value = 42, .center_freq = 5210}, { .hw_value = 44, .center_freq = 5220}, - { .hw_value = 46, .center_freq = 5230}, - { .hw_value = 48, .center_freq = 5240}, - { .hw_value = 52, .center_freq = 5260}, - { .hw_value = 56, .center_freq = 5280}, { .hw_value = 60, .center_freq = 5300}, - { .hw_value = 64, .center_freq = 5320}, - { .hw_value = 100, .center_freq = 5500}, - { .hw_value = 104, .center_freq = 5520}, - { .hw_value = 108, .center_freq = 5540}, { .hw_value = 112, .center_freq = 5560}, - { .hw_value = 116, .center_freq = 5580}, - { .hw_value = 120, .center_freq = 5600}, - { .hw_value = 124, .center_freq = 5620}, - { .hw_value = 128, .center_freq = 5640}, { .hw_value = 132, .center_freq = 5660}, + { .hw_value = 157, .center_freq = 5785}, + { .hw_value = 184, .center_freq = 4920}, + { .hw_value = 189, .center_freq = 4945}, + { .hw_value = 9, .center_freq = 5045}, + { .hw_value = 36, .center_freq = 5180}, + { .hw_value = 46, .center_freq = 5230}, + { .hw_value = 64, .center_freq = 5320}, + { .hw_value = 116, .center_freq = 5580}, { .hw_value = 136, .center_freq = 5680}, + { .hw_value = 192, .center_freq = 4960}, + { .hw_value = 11, .center_freq = 5055}, + { .hw_value = 38, .center_freq = 5190}, + { .hw_value = 48, .center_freq = 5240}, + { .hw_value = 100, .center_freq = 5500}, + { .hw_value = 120, .center_freq = 5600}, { .hw_value = 140, .center_freq = 5700}, + { .hw_value = 185, .center_freq = 4925}, + { .hw_value = 196, .center_freq = 4980}, + { .hw_value = 12, .center_freq = 5060}, + { .hw_value = 40, .center_freq = 5200}, + { .hw_value = 52, .center_freq = 5260}, + { .hw_value = 104, .center_freq = 5520}, + { .hw_value = 124, .center_freq = 5620}, { .hw_value = 149, .center_freq = 5745}, - { .hw_value = 153, .center_freq = 5765}, - { .hw_value = 157, .center_freq = 5785}, { .hw_value = 161, .center_freq = 5805}, + { .hw_value = 187, .center_freq = 4935}, + { .hw_value = 7, .center_freq = 5035}, + { .hw_value = 16, .center_freq = 5080}, + { .hw_value = 42, .center_freq = 5210}, + { .hw_value = 56, .center_freq = 5280}, + { .hw_value = 108, .center_freq = 5540}, + { .hw_value = 128, .center_freq = 5640}, + { .hw_value = 153, .center_freq = 5765}, { .hw_value = 165, .center_freq = 5825}, }; @@ -2211,8 +2308,7 @@ static ssize_t wl1271_sysfs_show_bt_coex_state(struct device *dev, struct wl1271 *wl = dev_get_drvdata(dev); ssize_t len; - /* FIXME: what's the maximum length of buf? page size?*/ - len = 500; + len = PAGE_SIZE; mutex_lock(&wl->mutex); len = snprintf(buf, len, "%d\n\n0 - off\n1 - on\n", @@ -2273,8 +2369,7 @@ static ssize_t wl1271_sysfs_show_hw_pg_ver(struct device *dev, struct wl1271 *wl = dev_get_drvdata(dev); ssize_t len; - /* FIXME: what's the maximum length of buf? page size?*/ - len = 500; + len = PAGE_SIZE; mutex_lock(&wl->mutex); if (wl->hw_pg_ver >= 0) @@ -2306,6 +2401,8 @@ int wl1271_register_hw(struct wl1271 *wl) wl->mac80211_registered = true; + register_netdevice_notifier(&wl1271_dev_notifier); + wl1271_notice("loaded"); return 0; @@ -2314,6 +2411,7 @@ EXPORT_SYMBOL_GPL(wl1271_register_hw); void wl1271_unregister_hw(struct wl1271 *wl) { + unregister_netdevice_notifier(&wl1271_dev_notifier); ieee80211_unregister_hw(wl->hw); wl->mac80211_registered = false; @@ -2322,6 +2420,14 @@ EXPORT_SYMBOL_GPL(wl1271_unregister_hw); int wl1271_init_ieee80211(struct wl1271 *wl) { + static const u32 cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, + WL1271_CIPHER_SUITE_GEM, + }; + /* The tx descriptor buffer and the TKIP space. */ wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE + sizeof(struct wl1271_tx_hw_descr); @@ -2339,13 +2445,14 @@ int wl1271_init_ieee80211(struct wl1271 *wl) IEEE80211_HW_CONNECTION_MONITOR | IEEE80211_HW_SUPPORTS_CQM_RSSI; + wl->hw->wiphy->cipher_suites = cipher_suites; + wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); wl->hw->wiphy->max_scan_ssids = 1; wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; - - if (wl1271_11a_enabled()) - wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; + wl->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl1271_band_5ghz; wl->hw->queues = 4; wl->hw->max_rates = 1; @@ -2364,6 +2471,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) struct platform_device *plat_dev = NULL; struct wl1271 *wl; int i, ret; + unsigned int order; hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops); if (!hw) { @@ -2391,6 +2499,10 @@ struct ieee80211_hw *wl1271_alloc_hw(void) INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); + INIT_WORK(&wl->irq_work, wl1271_irq_work); + INIT_WORK(&wl->tx_work, wl1271_tx_work); + INIT_WORK(&wl->recovery_work, wl1271_recovery_work); + INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); wl->channel = WL1271_DEFAULT_CHANNEL; wl->beacon_int = WL1271_DEFAULT_BEACON_INT; wl->default_key = 0; @@ -2422,11 +2534,18 @@ struct ieee80211_hw *wl1271_alloc_hw(void) wl1271_debugfs_init(wl); + order = get_order(WL1271_AGGR_BUFFER_SIZE); + wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); + if (!wl->aggr_buf) { + ret = -ENOMEM; + goto err_hw; + } + /* Register platform device */ ret = platform_device_register(wl->plat_dev); if (ret) { wl1271_error("couldn't register platform device"); - goto err_hw; + goto err_aggr; } dev_set_drvdata(&wl->plat_dev->dev, wl); @@ -2452,6 +2571,9 @@ struct ieee80211_hw *wl1271_alloc_hw(void) err_platform: platform_device_unregister(wl->plat_dev); +err_aggr: + free_pages((unsigned long)wl->aggr_buf, order); + err_hw: wl1271_debugfs_exit(wl); kfree(plat_dev); @@ -2468,6 +2590,8 @@ EXPORT_SYMBOL_GPL(wl1271_alloc_hw); int wl1271_free_hw(struct wl1271 *wl) { platform_device_unregister(wl->plat_dev); + free_pages((unsigned long)wl->aggr_buf, + get_order(WL1271_AGGR_BUFFER_SIZE)); kfree(wl->plat_dev); wl1271_debugfs_exit(wl); diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c index a5e60e0403e5ad90f2b35f6900dbfa71aafe52ea..e3c332e2f97c06646174e6661241f723e546b561 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ b/drivers/net/wireless/wl12xx/wl1271_ps.c @@ -39,6 +39,9 @@ void wl1271_elp_work(struct work_struct *work) mutex_lock(&wl->mutex); + if (unlikely(wl->state == WL1271_STATE_OFF)) + goto out; + if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) || (!test_bit(WL1271_FLAG_PSM, &wl->flags) && !test_bit(WL1271_FLAG_IDLE, &wl->flags))) @@ -61,7 +64,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) test_bit(WL1271_FLAG_IDLE, &wl->flags)) { cancel_delayed_work(&wl->elp_work); ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, - msecs_to_jiffies(ELP_ENTRY_DELAY)); + msecs_to_jiffies(ELP_ENTRY_DELAY)); } } @@ -96,6 +99,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) &compl, msecs_to_jiffies(WL1271_WAKEUP_TIMEOUT)); if (ret == 0) { wl1271_error("ELP wakeup timeout!"); + ieee80211_queue_work(wl->hw, &wl->recovery_work); ret = -ETIMEDOUT; goto err; } else if (ret < 0) { @@ -121,7 +125,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) } int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, - bool send) + u32 rates, bool send) { int ret; @@ -129,7 +133,14 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, case STATION_POWER_SAVE_MODE: wl1271_debug(DEBUG_PSM, "entering psm"); - ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send); + ret = wl1271_acx_wake_up_conditions(wl); + if (ret < 0) { + wl1271_error("couldn't set wake up conditions"); + return ret; + } + + ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, + rates, send); if (ret < 0) return ret; @@ -152,7 +163,8 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, if (ret < 0) return ret; - ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send); + ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, + rates, send); if (ret < 0) return ret; diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h index 940276f517a40bef3d649cc0522f5d989b9ba43f..6ba7b032736f260aa5c418b1c32710b025c70496 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.h +++ b/drivers/net/wireless/wl12xx/wl1271_ps.h @@ -28,7 +28,7 @@ #include "wl1271_acx.h" int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, - bool send); + u32 rates, bool send); void wl1271_ps_elp_sleep(struct wl1271 *wl); int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); void wl1271_elp_work(struct work_struct *work); diff --git a/drivers/net/wireless/wl12xx/wl1271_rx.c b/drivers/net/wireless/wl12xx/wl1271_rx.c index 019aa79cd9dfc8cdc25c49973c93d5ecf6592d0f..bea133b6e4893e2d61cbeff1e4d1f31d1faa42c4 100644 --- a/drivers/net/wireless/wl12xx/wl1271_rx.c +++ b/drivers/net/wireless/wl12xx/wl1271_rx.c @@ -74,9 +74,8 @@ static void wl1271_rx_status(struct wl1271 *wl, } } -static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) +static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) { - struct ieee80211_rx_status rx_status; struct wl1271_rx_descriptor *desc; struct sk_buff *skb; u16 *fc; @@ -88,16 +87,16 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) * workaround this by not retrieving them at all. */ if (unlikely(wl->state == WL1271_STATE_PLT)) - return; + return -EINVAL; skb = __dev_alloc_skb(length, GFP_KERNEL); if (!skb) { wl1271_error("Couldn't allocate RX frame"); - return; + return -ENOMEM; } buf = skb_put(skb, length); - wl1271_read(wl, WL1271_SLV_MEM_DATA, buf, length, true); + memcpy(buf, data, length); /* the data read starts with the descriptor */ desc = (struct wl1271_rx_descriptor *) buf; @@ -109,15 +108,16 @@ static void wl1271_rx_handle_data(struct wl1271 *wl, u32 length) if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) beacon = 1; - wl1271_rx_status(wl, desc, &rx_status, beacon); + wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon); wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len, beacon ? "beacon" : ""); skb_trim(skb, skb->len - desc->pad_len); - memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); ieee80211_rx_ni(wl->hw, skb); + + return 0; } void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) @@ -126,31 +126,60 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) u32 buf_size; u32 fw_rx_counter = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK; u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; + u32 rx_counter; u32 mem_block; + u32 pkt_length; + u32 pkt_offset; while (drv_rx_counter != fw_rx_counter) { - mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter); - buf_size = wl1271_rx_get_buf_size(status, drv_rx_counter); + buf_size = 0; + rx_counter = drv_rx_counter; + while (rx_counter != fw_rx_counter) { + pkt_length = wl1271_rx_get_buf_size(status, rx_counter); + if (buf_size + pkt_length > WL1271_AGGR_BUFFER_SIZE) + break; + buf_size += pkt_length; + rx_counter++; + rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; + } if (buf_size == 0) { wl1271_warning("received empty data"); break; } + /* + * Choose the block we want to read + * For aggregated packets, only the first memory block should + * be retrieved. The FW takes care of the rest. + */ + mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter); wl->rx_mem_pool_addr.addr = (mem_block << 8) + le32_to_cpu(wl_mem_map->packet_memory_pool_start); wl->rx_mem_pool_addr.addr_extra = wl->rx_mem_pool_addr.addr + 4; - - /* Choose the block we want to read */ wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr, - sizeof(wl->rx_mem_pool_addr), false); - - wl1271_rx_handle_data(wl, buf_size); - - wl->rx_counter++; - drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK; + sizeof(wl->rx_mem_pool_addr), false); + + /* Read all available packets at once */ + wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, + buf_size, true); + + /* Split data into separate packets */ + pkt_offset = 0; + while (pkt_offset < buf_size) { + pkt_length = wl1271_rx_get_buf_size(status, + drv_rx_counter); + if (wl1271_rx_handle_data(wl, + wl->aggr_buf + pkt_offset, + pkt_length) < 0) + break; + wl->rx_counter++; + drv_rx_counter++; + drv_rx_counter &= NUM_RX_PKT_DESC_MOD_MASK; + pkt_offset += pkt_length; + } } - - wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); + wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, + cpu_to_le32(wl->rx_counter)); } diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index fec43eed8c553424231c6b990132b35bf8b7167b..909bb47995b6907ee8afad05c3acf37500043d4a 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c @@ -28,11 +28,43 @@ #include "wl1271_scan.h" #include "wl1271_acx.h" +void wl1271_scan_complete_work(struct work_struct *work) +{ + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, scan_complete_work); + + wl1271_debug(DEBUG_SCAN, "Scanning complete"); + + mutex_lock(&wl->mutex); + + if (wl->scan.state == WL1271_SCAN_STATE_IDLE) { + mutex_unlock(&wl->mutex); + return; + } + + wl->scan.state = WL1271_SCAN_STATE_IDLE; + kfree(wl->scan.scanned_ch); + wl->scan.scanned_ch = NULL; + mutex_unlock(&wl->mutex); + + ieee80211_scan_completed(wl->hw, false); + + if (wl->scan.failed) { + wl1271_info("Scan completed due to error."); + ieee80211_queue_work(wl->hw, &wl->recovery_work); + } +} + + static int wl1271_get_scan_channels(struct wl1271 *wl, struct cfg80211_scan_request *req, struct basic_scan_channel_params *channels, enum ieee80211_band band, bool passive) { + struct conf_scan_settings *c = &wl->conf.scan; int i, j; u32 flags; @@ -60,10 +92,17 @@ static int wl1271_get_scan_channels(struct wl1271 *wl, wl1271_debug(DEBUG_SCAN, "beacon_found %d", req->channels[i]->beacon_found); - channels[j].min_duration = - cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); - channels[j].max_duration = - cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); + if (!passive) { + channels[j].min_duration = + cpu_to_le32(c->min_dwell_time_active); + channels[j].max_duration = + cpu_to_le32(c->max_dwell_time_active); + } else { + channels[j].min_duration = + cpu_to_le32(c->min_dwell_time_passive); + channels[j].max_duration = + cpu_to_le32(c->max_dwell_time_passive); + } channels[j].early_termination = 0; channels[j].tx_power_att = req->channels[i]->max_power; channels[j].channel = req->channels[i]->hw_value; @@ -100,8 +139,11 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, /* We always use high priority scans */ scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; - if(passive) + + /* No SSIDs means that we have a forced passive scan */ + if (passive || wl->scan.req->n_ssids == 0) scan_options |= WL1271_SCAN_OPT_PASSIVE; + cmd->params.scan_options = cpu_to_le16(scan_options); cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, @@ -117,7 +159,7 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); - cmd->params.n_probe_reqs = WL1271_SCAN_PROBE_REQS; + cmd->params.n_probe_reqs = wl->conf.scan.num_probe_reqs; cmd->params.tx_rate = cpu_to_le32(basic_rate); cmd->params.tid_trigger = 0; cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; @@ -165,7 +207,7 @@ static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, void wl1271_scan_stm(struct wl1271 *wl) { - int ret; + int ret = 0; switch (wl->scan.state) { case WL1271_SCAN_STATE_IDLE: @@ -185,7 +227,7 @@ void wl1271_scan_stm(struct wl1271 *wl) ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, wl->conf.tx.basic_rate); if (ret == WL1271_NOTHING_TO_SCAN) { - if (wl1271_11a_enabled()) + if (wl->enable_11a) wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; else wl->scan.state = WL1271_SCAN_STATE_DONE; @@ -215,20 +257,22 @@ void wl1271_scan_stm(struct wl1271 *wl) break; case WL1271_SCAN_STATE_DONE: - mutex_unlock(&wl->mutex); - ieee80211_scan_completed(wl->hw, false); - mutex_lock(&wl->mutex); - - kfree(wl->scan.scanned_ch); - wl->scan.scanned_ch = NULL; - - wl->scan.state = WL1271_SCAN_STATE_IDLE; + wl->scan.failed = false; + cancel_delayed_work(&wl->scan_complete_work); + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(0)); break; default: wl1271_error("invalid scan state"); break; } + + if (ret < 0) { + cancel_delayed_work(&wl->scan_complete_work); + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(0)); + } } int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, @@ -248,9 +292,14 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, wl->scan.req = req; - wl->scan.scanned_ch = kzalloc(req->n_channels * + wl->scan.scanned_ch = kcalloc(req->n_channels, sizeof(*wl->scan.scanned_ch), GFP_KERNEL); + /* we assume failure so that timeout scenarios are handled correctly */ + wl->scan.failed = true; + ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work, + msecs_to_jiffies(WL1271_SCAN_TIMEOUT)); + wl1271_scan_stm(wl); return 0; diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h index f1815700f5f9da97464cba2f727920fd45d8f219..6d57127b5e6be10b438d73f51faacf49e86c75b0 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.h +++ b/drivers/net/wireless/wl12xx/wl1271_scan.h @@ -32,6 +32,7 @@ int wl1271_scan_build_probe_req(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len, u8 band); void wl1271_scan_stm(struct wl1271 *wl); +void wl1271_scan_complete_work(struct work_struct *work); #define WL1271_SCAN_MAX_CHANNELS 24 #define WL1271_SCAN_DEFAULT_TAG 1 @@ -39,11 +40,10 @@ void wl1271_scan_stm(struct wl1271 *wl); #define WL1271_SCAN_OPT_ACTIVE 0 #define WL1271_SCAN_OPT_PASSIVE 1 #define WL1271_SCAN_OPT_PRIORITY_HIGH 4 -#define WL1271_SCAN_CHAN_MIN_DURATION 30000 /* TU */ -#define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */ #define WL1271_SCAN_BAND_2_4_GHZ 0 #define WL1271_SCAN_BAND_5_GHZ 1 -#define WL1271_SCAN_PROBE_REQS 3 + +#define WL1271_SCAN_TIMEOUT 10000 /* msec */ enum { WL1271_SCAN_STATE_IDLE, diff --git a/drivers/net/wireless/wl12xx/wl1271_sdio.c b/drivers/net/wireless/wl12xx/wl1271_sdio.c index 7059b5cccf0f8fff9651017607e4d18b75d78b30..784ef343264139082d12286a816e7c8fa1dc65f1 100644 --- a/drivers/net/wireless/wl12xx/wl1271_sdio.c +++ b/drivers/net/wireless/wl12xx/wl1271_sdio.c @@ -29,14 +29,13 @@ #include #include #include +#include +#include #include "wl1271.h" #include "wl12xx_80211.h" #include "wl1271_io.h" - -#define RX71_WL1271_IRQ_GPIO 42 - #ifndef SDIO_VENDOR_ID_TI #define SDIO_VENDOR_ID_TI 0x0097 #endif @@ -107,6 +106,8 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, int ret; struct sdio_func *func = wl_to_func(wl); + sdio_claim_host(func); + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", @@ -122,9 +123,10 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); } + sdio_release_host(func); + if (ret) wl1271_error("sdio read failed (%d)", ret); - } static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, @@ -133,6 +135,8 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, int ret; struct sdio_func *func = wl_to_func(wl); + sdio_claim_host(func); + if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", @@ -147,26 +151,49 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, else ret = sdio_memcpy_toio(func, addr, buf, len); } + + sdio_release_host(func); + if (ret) wl1271_error("sdio write failed (%d)", ret); +} +static int wl1271_sdio_power_on(struct wl1271 *wl) +{ + struct sdio_func *func = wl_to_func(wl); + int ret; + + /* Power up the card */ + ret = pm_runtime_get_sync(&func->dev); + if (ret < 0) + goto out; + + sdio_claim_host(func); + sdio_enable_func(func); + sdio_release_host(func); + +out: + return ret; } -static void wl1271_sdio_set_power(struct wl1271 *wl, bool enable) +static int wl1271_sdio_power_off(struct wl1271 *wl) { struct sdio_func *func = wl_to_func(wl); - /* Let the SDIO stack handle wlan_enable control, so we - * keep host claimed while wlan is in use to keep wl1271 - * alive. - */ - if (enable) { - sdio_claim_host(func); - sdio_enable_func(func); - } else { - sdio_disable_func(func); - sdio_release_host(func); - } + sdio_claim_host(func); + sdio_disable_func(func); + sdio_release_host(func); + + /* Power down the card */ + return pm_runtime_put_sync(&func->dev); +} + +static int wl1271_sdio_set_power(struct wl1271 *wl, bool enable) +{ + if (enable) + return wl1271_sdio_power_on(wl); + else + return wl1271_sdio_power_off(wl); } static struct wl1271_if_operations sdio_ops = { @@ -184,6 +211,7 @@ static int __devinit wl1271_probe(struct sdio_func *func, const struct sdio_device_id *id) { struct ieee80211_hw *hw; + const struct wl12xx_platform_data *wlan_data; struct wl1271 *wl; int ret; @@ -203,13 +231,16 @@ static int __devinit wl1271_probe(struct sdio_func *func, /* Grab access to FN0 for ELP reg. */ func->card->quirks |= MMC_QUIRK_LENIENT_FN0; - wl->irq = gpio_to_irq(RX71_WL1271_IRQ_GPIO); - if (wl->irq < 0) { - ret = wl->irq; - wl1271_error("could not get irq!"); + wlan_data = wl12xx_get_platform_data(); + if (IS_ERR(wlan_data)) { + ret = PTR_ERR(wlan_data); + wl1271_error("missing wlan platform data: %d", ret); goto out_free; } + wl->irq = wlan_data->irq; + wl->ref_clock = wlan_data->board_ref_clock; + ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); @@ -230,6 +261,9 @@ static int __devinit wl1271_probe(struct sdio_func *func, sdio_set_drvdata(func, wl); + /* Tell PM core that we don't need the card to be powered now */ + pm_runtime_put_noidle(&func->dev); + wl1271_notice("initialized"); return 0; @@ -248,17 +282,39 @@ static void __devexit wl1271_remove(struct sdio_func *func) { struct wl1271 *wl = sdio_get_drvdata(func); - free_irq(wl->irq, wl); + /* Undo decrement done above in wl1271_probe */ + pm_runtime_get_noresume(&func->dev); wl1271_unregister_hw(wl); + free_irq(wl->irq, wl); wl1271_free_hw(wl); } +static int wl1271_suspend(struct device *dev) +{ + /* Tell MMC/SDIO core it's OK to power down the card + * (if it isn't already), but not to remove it completely */ + return 0; +} + +static int wl1271_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops wl1271_sdio_pm_ops = { + .suspend = wl1271_suspend, + .resume = wl1271_resume, +}; + static struct sdio_driver wl1271_sdio_driver = { .name = "wl1271_sdio", .id_table = wl1271_devices, .probe = wl1271_probe, .remove = __devexit_p(wl1271_remove), + .drv = { + .pm = &wl1271_sdio_pm_ops, + }, }; static int __init wl1271_init(void) diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c index 4cb99c541e2abb528f63492a3c3736691242be04..ef801680773f623017d7e4e514d5a827daa85d98 100644 --- a/drivers/net/wireless/wl12xx/wl1271_spi.c +++ b/drivers/net/wireless/wl12xx/wl1271_spi.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "wl1271.h" @@ -63,6 +63,11 @@ ((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32)) #define HW_ACCESS_WSPI_INIT_CMD_MASK 0 +/* HW limitation: maximum possible chunk size is 4095 bytes */ +#define WSPI_MAX_CHUNK_SIZE 4092 + +#define WSPI_MAX_NUM_OF_CHUNKS (WL1271_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + static inline struct spi_device *wl_to_spi(struct wl1271 *wl) { return wl->if_priv; @@ -202,90 +207,117 @@ static int wl1271_spi_read_busy(struct wl1271 *wl) static void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf, size_t len, bool fixed) { - struct spi_transfer t[3]; + struct spi_transfer t[2]; struct spi_message m; u32 *busy_buf; u32 *cmd; + u32 chunk_len; - cmd = &wl->buffer_cmd; - busy_buf = wl->buffer_busyword; + while (len > 0) { + chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); - *cmd = 0; - *cmd |= WSPI_CMD_READ; - *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; - *cmd |= addr & WSPI_CMD_BYTE_ADDR; + cmd = &wl->buffer_cmd; + busy_buf = wl->buffer_busyword; - if (fixed) - *cmd |= WSPI_CMD_FIXED; + *cmd = 0; + *cmd |= WSPI_CMD_READ; + *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) & + WSPI_CMD_BYTE_LENGTH; + *cmd |= addr & WSPI_CMD_BYTE_ADDR; - spi_message_init(&m); - memset(t, 0, sizeof(t)); + if (fixed) + *cmd |= WSPI_CMD_FIXED; - t[0].tx_buf = cmd; - t[0].len = 4; - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); + spi_message_init(&m); + memset(t, 0, sizeof(t)); - /* Busy and non busy words read */ - t[1].rx_buf = busy_buf; - t[1].len = WL1271_BUSY_WORD_LEN; - t[1].cs_change = true; - spi_message_add_tail(&t[1], &m); + t[0].tx_buf = cmd; + t[0].len = 4; + t[0].cs_change = true; + spi_message_add_tail(&t[0], &m); - spi_sync(wl_to_spi(wl), &m); + /* Busy and non busy words read */ + t[1].rx_buf = busy_buf; + t[1].len = WL1271_BUSY_WORD_LEN; + t[1].cs_change = true; + spi_message_add_tail(&t[1], &m); - if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && - wl1271_spi_read_busy(wl)) { - memset(buf, 0, len); - return; - } + spi_sync(wl_to_spi(wl), &m); - spi_message_init(&m); - memset(t, 0, sizeof(t)); + if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && + wl1271_spi_read_busy(wl)) { + memset(buf, 0, chunk_len); + return; + } - t[0].rx_buf = buf; - t[0].len = len; - t[0].cs_change = true; - spi_message_add_tail(&t[0], &m); + spi_message_init(&m); + memset(t, 0, sizeof(t)); - spi_sync(wl_to_spi(wl), &m); + t[0].rx_buf = buf; + t[0].len = chunk_len; + t[0].cs_change = true; + spi_message_add_tail(&t[0], &m); - wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); - wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); + spi_sync(wl_to_spi(wl), &m); + + wl1271_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); + wl1271_dump(DEBUG_SPI, "spi_read buf <- ", buf, chunk_len); + + if (!fixed) + addr += chunk_len; + buf += chunk_len; + len -= chunk_len; + } } static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, size_t len, bool fixed) { - struct spi_transfer t[2]; + struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; struct spi_message m; + u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; u32 *cmd; + u32 chunk_len; + int i; - cmd = &wl->buffer_cmd; - - *cmd = 0; - *cmd |= WSPI_CMD_WRITE; - *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; - *cmd |= addr & WSPI_CMD_BYTE_ADDR; - - if (fixed) - *cmd |= WSPI_CMD_FIXED; + WARN_ON(len > WL1271_AGGR_BUFFER_SIZE); spi_message_init(&m); memset(t, 0, sizeof(t)); - t[0].tx_buf = cmd; - t[0].len = sizeof(*cmd); - spi_message_add_tail(&t[0], &m); + cmd = &commands[0]; + i = 0; + while (len > 0) { + chunk_len = min((size_t)WSPI_MAX_CHUNK_SIZE, len); - t[1].tx_buf = buf; - t[1].len = len; - spi_message_add_tail(&t[1], &m); + *cmd = 0; + *cmd |= WSPI_CMD_WRITE; + *cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) & + WSPI_CMD_BYTE_LENGTH; + *cmd |= addr & WSPI_CMD_BYTE_ADDR; - spi_sync(wl_to_spi(wl), &m); + if (fixed) + *cmd |= WSPI_CMD_FIXED; + + t[i].tx_buf = cmd; + t[i].len = sizeof(*cmd); + spi_message_add_tail(&t[i++], &m); + + t[i].tx_buf = buf; + t[i].len = chunk_len; + spi_message_add_tail(&t[i++], &m); - wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); - wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); + wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); + wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, chunk_len); + + if (!fixed) + addr += chunk_len; + buf += chunk_len; + len -= chunk_len; + cmd++; + } + + spi_sync(wl_to_spi(wl), &m); } static irqreturn_t wl1271_irq(int irq, void *cookie) @@ -312,10 +344,12 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) return IRQ_HANDLED; } -static void wl1271_spi_set_power(struct wl1271 *wl, bool enable) +static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) { if (wl->set_power) wl->set_power(enable); + + return 0; } static struct wl1271_if_operations spi_ops = { @@ -370,6 +404,8 @@ static int __devinit wl1271_probe(struct spi_device *spi) goto out_free; } + wl->ref_clock = pdata->board_ref_clock; + wl->irq = spi->irq; if (wl->irq < 0) { wl1271_error("irq missing in platform data"); @@ -412,9 +448,8 @@ static int __devexit wl1271_remove(struct spi_device *spi) { struct wl1271 *wl = dev_get_drvdata(&spi->dev); - free_irq(wl->irq, wl); - wl1271_unregister_hw(wl); + free_irq(wl->irq, wl); wl1271_free_hw(wl); return 0; diff --git a/drivers/net/wireless/wl12xx/wl1271_testmode.c b/drivers/net/wireless/wl12xx/wl1271_testmode.c index 6e0952f79e9a79e942a4ed3182ab6f419cba07c6..a3aa84386c88b3aef93cbfe4210e796797738974 100644 --- a/drivers/net/wireless/wl12xx/wl1271_testmode.c +++ b/drivers/net/wireless/wl12xx/wl1271_testmode.c @@ -199,19 +199,6 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) buf = nla_data(tb[WL1271_TM_ATTR_DATA]); len = nla_len(tb[WL1271_TM_ATTR_DATA]); - /* - * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band - * configurations) can be removed when those NVS files stop floating - * around. - */ - if (len != sizeof(struct wl1271_nvs_file) && - (len != WL1271_INI_LEGACY_NVS_FILE_SIZE || - wl1271_11a_enabled())) { - wl1271_error("nvs size is not as expected: %zu != %zu", - len, sizeof(struct wl1271_nvs_file)); - return -EMSGSIZE; - } - mutex_lock(&wl->mutex); kfree(wl->nvs); @@ -224,6 +211,7 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[]) } memcpy(wl->nvs, buf, len); + wl->nvs_len = len; wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs"); diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index c592cc2e9fe88690bcfb97014a423489fbbedb6d..e3dc13c4d01ad0b572267526efae5f666b5bf757 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -43,13 +43,17 @@ static int wl1271_tx_id(struct wl1271 *wl, struct sk_buff *skb) return -EBUSY; } -static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) +static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra, + u32 buf_offset) { struct wl1271_tx_hw_descr *desc; u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra; u32 total_blocks; int id, ret = -EBUSY; + if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE) + return -EBUSY; + /* allocate free identifier for the packet */ id = wl1271_tx_id(wl, skb); if (id < 0) @@ -82,7 +86,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra) return ret; } -static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, +static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, u32 extra, struct ieee80211_tx_info *control) { struct timespec ts; @@ -110,9 +114,9 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, /* configure the tx attributes */ tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER; - /* queue */ + /* queue (we use same identifiers for tid's and ac's */ ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); - desc->tid = wl1271_tx_ac_to_tid(ac); + desc->tid = ac; desc->aid = TX_HW_DEFAULT_AID; desc->reserved = 0; @@ -133,59 +137,17 @@ static int wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb, desc->tx_attr = cpu_to_le16(tx_attr); wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d", pad); - return 0; -} - -static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb, - struct ieee80211_tx_info *control) -{ - - struct wl1271_tx_hw_descr *desc; - int len; - - /* FIXME: This is a workaround for getting non-aligned packets. - This happens at least with EAPOL packets from the user space. - Our DMA requires packets to be aligned on a 4-byte boundary. - */ - if (unlikely((long)skb->data & 0x03)) { - int offset = (4 - (long)skb->data) & 0x03; - wl1271_debug(DEBUG_TX, "skb offset %d", offset); - - /* check whether the current skb can be used */ - if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) { - unsigned char *src = skb->data; - - /* align the buffer on a 4-byte boundary */ - skb_reserve(skb, offset); - memmove(skb->data, src, skb->len); - } else { - wl1271_info("No handler, fixme!"); - return -EINVAL; - } - } - - len = WL1271_TX_ALIGN(skb->len); - - /* perform a fixed address block write with the packet */ - wl1271_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true); - - /* write packet new counter into the write access register */ - wl->tx_packets_count++; - - desc = (struct wl1271_tx_hw_descr *) skb->data; - wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)", - desc->id, skb, len, desc->length); - - return 0; } /* caller must hold wl->mutex */ -static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb) +static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct sk_buff *skb, + u32 buf_offset) { struct ieee80211_tx_info *info; u32 extra = 0; int ret = 0; u8 idx; + u32 total_len; if (!skb) return -EINVAL; @@ -193,7 +155,7 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb) info = IEEE80211_SKB_CB(skb); if (info->control.hw_key && - info->control.hw_key->alg == ALG_TKIP) + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) extra = WL1271_TKIP_IV_SPACE; if (info->control.hw_key) { @@ -208,19 +170,22 @@ static int wl1271_tx_frame(struct wl1271 *wl, struct sk_buff *skb) } } - ret = wl1271_tx_allocate(wl, skb, extra); + ret = wl1271_tx_allocate(wl, skb, extra, buf_offset); if (ret < 0) return ret; - ret = wl1271_tx_fill_hdr(wl, skb, extra, info); - if (ret < 0) - return ret; + wl1271_tx_fill_hdr(wl, skb, extra, info); - ret = wl1271_tx_send_packet(wl, skb, info); - if (ret < 0) - return ret; + /* + * The length of each packet is stored in terms of words. Thus, we must + * pad the skb data to make sure its length is aligned. + * The number of padding bytes is computed and set in wl1271_tx_fill_hdr + */ + total_len = WL1271_TX_ALIGN(skb->len); + memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len); + memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len); - return ret; + return total_len; } u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) @@ -245,7 +210,7 @@ void wl1271_tx_work(struct work_struct *work) struct sk_buff *skb; bool woken_up = false; u32 sta_rates = 0; - u32 prev_tx_packets_count; + u32 buf_offset; int ret; /* check if the rates supported by the AP have changed */ @@ -262,14 +227,15 @@ void wl1271_tx_work(struct work_struct *work) if (unlikely(wl->state == WL1271_STATE_OFF)) goto out; - prev_tx_packets_count = wl->tx_packets_count; - /* if rates have changed, re-configure the rate policy */ if (unlikely(sta_rates)) { wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); wl1271_acx_rate_policies(wl); } + /* Prepare the transfer buffer, by aggregating all + * available packets */ + buf_offset = 0; while ((skb = skb_dequeue(&wl->tx_queue))) { if (!woken_up) { ret = wl1271_ps_elp_wakeup(wl, false); @@ -278,21 +244,30 @@ void wl1271_tx_work(struct work_struct *work) woken_up = true; } - ret = wl1271_tx_frame(wl, skb); + ret = wl1271_prepare_tx_frame(wl, skb, buf_offset); if (ret == -EBUSY) { - /* firmware buffer is full, lets stop transmitting. */ + /* + * Either the firmware buffer is full, or the + * aggregation buffer is. + * Queue back last skb, and stop aggregating. + */ skb_queue_head(&wl->tx_queue, skb); goto out_ack; } else if (ret < 0) { dev_kfree_skb(skb); goto out_ack; } + buf_offset += ret; + wl->tx_packets_count++; } out_ack: - /* interrupt the firmware with the new packets */ - if (prev_tx_packets_count != wl->tx_packets_count) + if (buf_offset) { + wl1271_write(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); + /* interrupt the firmware with the new packets */ wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); + } out: if (woken_up) @@ -347,7 +322,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, /* remove TKIP header space if present */ if (info->control.hw_key && - info->control.hw_key->alg == ALG_TKIP) { + info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { int hdrlen = ieee80211_get_hdrlen_from_skb(skb); memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, hdrlen); skb_pull(skb, WL1271_TKIP_IV_SPACE); @@ -422,8 +397,6 @@ void wl1271_tx_reset(struct wl1271 *wl) struct sk_buff *skb; /* TX failure */ -/* control->flags = 0; FIXME */ - while ((skb = skb_dequeue(&wl->tx_queue))) { wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); ieee80211_tx_status(wl->hw, skb); diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.h b/drivers/net/wireless/wl12xx/wl1271_tx.h index 48bf92621c03390f9d6e40efa51f79674c766108..d12a129ad11cc79716e46ef771112c7429faa3c6 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.h +++ b/drivers/net/wireless/wl12xx/wl1271_tx.h @@ -139,23 +139,6 @@ static inline int wl1271_tx_get_queue(int queue) } } -/* wl1271 tx descriptor needs the tid and we need to convert it from ac */ -static inline int wl1271_tx_ac_to_tid(int ac) -{ - switch (ac) { - case 0: - return 0; - case 1: - return 2; - case 2: - return 4; - case 3: - return 6; - default: - return 0; - } -} - void wl1271_tx_work(struct work_struct *work); void wl1271_tx_complete(struct wl1271 *wl); void wl1271_tx_reset(struct wl1271 *wl); diff --git a/drivers/net/wireless/wl12xx/wl12xx_platform_data.c b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c new file mode 100644 index 0000000000000000000000000000000000000000..973b11060a8f2674d2ff75b72209c51d4ec95ace --- /dev/null +++ b/drivers/net/wireless/wl12xx/wl12xx_platform_data.c @@ -0,0 +1,28 @@ +#include +#include +#include + +static const struct wl12xx_platform_data *platform_data; + +int __init wl12xx_set_platform_data(const struct wl12xx_platform_data *data) +{ + if (platform_data) + return -EBUSY; + if (!data) + return -EINVAL; + + platform_data = kmemdup(data, sizeof(*data), GFP_KERNEL); + if (!platform_data) + return -ENOMEM; + + return 0; +} + +const struct wl12xx_platform_data *wl12xx_get_platform_data(void) +{ + if (!platform_data) + return ERR_PTR(-ENODEV); + + return platform_data; +} +EXPORT_SYMBOL(wl12xx_get_platform_data); diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index ca3f8961fa27fd07a6d31f44740b77467fe5df93..ee82df62e64660dc347380c810fa404b52d5123a 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -1403,15 +1402,6 @@ static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev) return wstats; } -static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) -{ - strlcpy(info->driver, "wl3501_cs", sizeof(info->driver)); -} - -static const struct ethtool_ops ops = { - .get_drvinfo = wl3501_get_drvinfo -}; - /** * wl3501_detach - deletes a driver "instance" * @link - FILL_IN @@ -1887,7 +1877,6 @@ static int wl3501_probe(struct pcmcia_device *p_dev) this->p_dev = p_dev; dev->wireless_data = &this->wireless_data; dev->wireless_handlers = &wl3501_handler_def; - SET_ETHTOOL_OPS(dev, &ops); netif_stop_queue(dev); p_dev->priv = dev; diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index b2af3c549bb39e21010051f55a3eaa21df00a30a..87a95bcfee5735f593489cf52011068f4d92e0e1 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -973,6 +973,7 @@ static void dump_fw_registers(struct zd_chip *chip) static int print_fw_version(struct zd_chip *chip) { + struct wiphy *wiphy = zd_chip_to_mac(chip)->hw->wiphy; int r; u16 version; @@ -982,6 +983,10 @@ static int print_fw_version(struct zd_chip *chip) return r; dev_info(zd_chip_dev(chip),"firmware version %04hx\n", version); + + snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), + "%04hx", version); + return 0; } diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index b50fedcef8ac9dd9872a51ed63cb0b6c3135c778..630fb866476811b4b69cd7eab6f1cfce0aee346a 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -135,7 +135,7 @@ static void skb_entry_set_link(union skb_entry *list, unsigned short id) static int skb_entry_is_link(const union skb_entry *list) { BUILD_BUG_ON(sizeof(list->skb) != sizeof(list->link)); - return ((unsigned long)list->skb < PAGE_OFFSET); + return (unsigned long)list->skb < PAGE_OFFSET; } /* @@ -203,8 +203,8 @@ static void rx_refill_timeout(unsigned long data) static int netfront_tx_slot_available(struct netfront_info *np) { - return ((np->tx.req_prod_pvt - np->tx.rsp_cons) < - (TX_MAX_TARGET - MAX_SKB_FRAGS - 2)); + return (np->tx.req_prod_pvt - np->tx.rsp_cons) < + (TX_MAX_TARGET - MAX_SKB_FRAGS - 2); } static void xennet_maybe_wake_tx(struct net_device *dev) @@ -1395,7 +1395,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) } /* Common code used when first setting up, and when resuming. */ -static int talk_to_backend(struct xenbus_device *dev, +static int talk_to_netback(struct xenbus_device *dev, struct netfront_info *info) { const char *message; @@ -1545,7 +1545,7 @@ static int xennet_connect(struct net_device *dev) return -ENODEV; } - err = talk_to_backend(np->xbdev, np); + err = talk_to_netback(np->xbdev, np); if (err) return err; @@ -1599,7 +1599,7 @@ static int xennet_connect(struct net_device *dev) /** * Callback received when the backend's state changes. */ -static void backend_changed(struct xenbus_device *dev, +static void netback_changed(struct xenbus_device *dev, enum xenbus_state backend_state) { struct netfront_info *np = dev_get_drvdata(&dev->dev); @@ -1801,7 +1801,7 @@ static struct xenbus_driver netfront_driver = { .probe = netfront_probe, .remove = __devexit_p(xennet_remove), .resume = netfront_resume, - .otherend_changed = backend_changed, + .otherend_changed = netback_changed, }; static int __init netif_init(void) diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index ecbbb688eba08a1b337447a406284c5fd42d7fe2..f3f8be5a35fac0a47a40a40f14ee6d40bb055549 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -641,7 +641,7 @@ static void xemaclite_rx_handler(struct net_device *dev) skb_put(skb, len); /* Tell the skb how much data we got */ skb->protocol = eth_type_trans(skb, dev); - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += len; @@ -1269,6 +1269,16 @@ static int __devexit xemaclite_of_remove(struct platform_device *of_dev) return 0; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void +xemaclite_poll_controller(struct net_device *ndev) +{ + disable_irq(ndev->irq); + xemaclite_interrupt(ndev->irq, ndev); + enable_irq(ndev->irq); +} +#endif + static struct net_device_ops xemaclite_netdev_ops = { .ndo_open = xemaclite_open, .ndo_stop = xemaclite_close, @@ -1276,6 +1286,9 @@ static struct net_device_ops xemaclite_netdev_ops = { .ndo_set_mac_address = xemaclite_set_mac_address, .ndo_tx_timeout = xemaclite_tx_timeout, .ndo_get_stats = xemaclite_get_stats, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = xemaclite_poll_controller, +#endif }; /* Match table for OF platform binding */ diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 4eb67aed68ddaf020d8e0f61020bb3bab7f55a67..cd1b3dcd61db67671e28df47cae7a19293fa881f 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -646,7 +646,7 @@ static int yellowfin_open(struct net_device *dev) init_timer(&yp->timer); yp->timer.expires = jiffies + 3*HZ; yp->timer.data = (unsigned long)dev; - yp->timer.function = &yellowfin_timer; /* timer handler */ + yp->timer.function = yellowfin_timer; /* timer handler */ add_timer(&yp->timer); return 0; diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index f0037eefd44e62532c5b5c23be9cd30100bd7999..0f4ef8769a3dfb9b74670a7eb4270ade36192215 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -208,6 +208,7 @@ struct qdio_dev_perf_stat { unsigned int eqbs_partial; unsigned int sqbs; unsigned int sqbs_partial; + unsigned int int_discarded; } ____cacheline_aligned; struct qdio_queue_perf_stat { @@ -222,6 +223,10 @@ struct qdio_queue_perf_stat { unsigned int nr_sbal_total; }; +enum qdio_queue_irq_states { + QDIO_QUEUE_IRQS_DISABLED, +}; + struct qdio_input_q { /* input buffer acknowledgement flag */ int polling; @@ -231,6 +236,10 @@ struct qdio_input_q { int ack_count; /* last time of noticing incoming data */ u64 timestamp; + /* upper-layer polling flag */ + unsigned long queue_irq_state; + /* callback to start upper-layer polling */ + void (*queue_start_poll) (struct ccw_device *, int, unsigned long); }; struct qdio_output_q { @@ -399,6 +408,26 @@ static inline int multicast_outbound(struct qdio_q *q) #define sub_buf(bufnr, dec) \ ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK) +#define queue_irqs_enabled(q) \ + (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) == 0) +#define queue_irqs_disabled(q) \ + (test_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state) != 0) + +#define TIQDIO_SHARED_IND 63 + +/* device state change indicators */ +struct indicator_t { + u32 ind; /* u32 because of compare-and-swap performance */ + atomic_t count; /* use count, 0 or 1 for non-shared indicators */ +}; + +extern struct indicator_t *q_indicators; + +static inline int shared_ind(struct qdio_irq *irq_ptr) +{ + return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; +} + /* prototypes for thin interrupt */ void qdio_setup_thinint(struct qdio_irq *irq_ptr); int qdio_establish_thinint(struct qdio_irq *irq_ptr); diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index 6ce83f56d5371c5acdd0a216b9992019188a6e69..28868e7471a50122260c4c2bf7aa36784d7b460e 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -56,9 +56,16 @@ static int qstat_show(struct seq_file *m, void *v) seq_printf(m, "DSCI: %d nr_used: %d\n", *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used)); - seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move); - seq_printf(m, "polling: %d ack start: %d ack count: %d\n", - q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count); + seq_printf(m, "ftc: %d last_move: %d\n", + q->first_to_check, q->last_move); + if (q->is_input_q) { + seq_printf(m, "polling: %d ack start: %d ack count: %d\n", + q->u.in.polling, q->u.in.ack_start, + q->u.in.ack_count); + seq_printf(m, "IRQs disabled: %u\n", + test_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)); + } seq_printf(m, "SBAL states:\n"); seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); @@ -113,22 +120,6 @@ static int qstat_show(struct seq_file *m, void *v) return 0; } -static ssize_t qstat_seq_write(struct file *file, const char __user *buf, - size_t count, loff_t *off) -{ - struct seq_file *seq = file->private_data; - struct qdio_q *q = seq->private; - - if (!q) - return 0; - if (q->is_input_q) - xchg(q->irq_ptr->dsci, 1); - local_bh_disable(); - tasklet_schedule(&q->tasklet); - local_bh_enable(); - return count; -} - static int qstat_seq_open(struct inode *inode, struct file *filp) { return single_open(filp, qstat_show, @@ -139,7 +130,6 @@ static const struct file_operations debugfs_fops = { .owner = THIS_MODULE, .open = qstat_seq_open, .read = seq_read, - .write = qstat_seq_write, .llseek = seq_lseek, .release = single_release, }; @@ -166,7 +156,8 @@ static char *qperf_names[] = { "QEBSM eqbs", "QEBSM eqbs partial", "QEBSM sqbs", - "QEBSM sqbs partial" + "QEBSM sqbs partial", + "Discarded interrupts" }; static int qperf_show(struct seq_file *m, void *v) diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 00520f9a7a8e0ae2240d10855835ef13531a8284..5fcfa7f9e9ef7d4530e94ec79d2328d6349e95d9 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -884,8 +884,19 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) return; - for_each_input_queue(irq_ptr, q, i) - tasklet_schedule(&q->tasklet); + for_each_input_queue(irq_ptr, q, i) { + if (q->u.in.queue_start_poll) { + /* skip if polling is enabled or already in work */ + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) { + qperf_inc(q, int_discarded); + continue; + } + q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, + q->irq_ptr->int_parm); + } else + tasklet_schedule(&q->tasklet); + } if (!(irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED)) return; @@ -1519,6 +1530,129 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags, } EXPORT_SYMBOL_GPL(do_QDIO); +/** + * qdio_start_irq - process input buffers + * @cdev: associated ccw_device for the qdio subchannel + * @nr: input queue number + * + * Return codes + * 0 - success + * 1 - irqs not started since new data is available + */ +int qdio_start_irq(struct ccw_device *cdev, int nr) +{ + struct qdio_q *q; + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + + if (!irq_ptr) + return -ENODEV; + q = irq_ptr->input_qs[nr]; + + WARN_ON(queue_irqs_enabled(q)); + + if (!shared_ind(q->irq_ptr)) + xchg(q->irq_ptr->dsci, 0); + + qdio_stop_polling(q); + clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state); + + /* + * We need to check again to not lose initiative after + * resetting the ACK state. + */ + if (!shared_ind(q->irq_ptr) && *q->irq_ptr->dsci) + goto rescan; + if (!qdio_inbound_q_done(q)) + goto rescan; + return 0; + +rescan: + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) + return 0; + else + return 1; + +} +EXPORT_SYMBOL(qdio_start_irq); + +/** + * qdio_get_next_buffers - process input buffers + * @cdev: associated ccw_device for the qdio subchannel + * @nr: input queue number + * @bufnr: first filled buffer number + * @error: buffers are in error state + * + * Return codes + * < 0 - error + * = 0 - no new buffers found + * > 0 - number of processed buffers + */ +int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr, + int *error) +{ + struct qdio_q *q; + int start, end; + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + + if (!irq_ptr) + return -ENODEV; + q = irq_ptr->input_qs[nr]; + WARN_ON(queue_irqs_enabled(q)); + + qdio_sync_after_thinint(q); + + /* + * The interrupt could be caused by a PCI request. Check the + * PCI capable outbound queues. + */ + qdio_check_outbound_after_thinint(q); + + if (!qdio_inbound_q_moved(q)) + return 0; + + /* Note: upper-layer MUST stop processing immediately here ... */ + if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) + return -EIO; + + start = q->first_to_kick; + end = q->first_to_check; + *bufnr = start; + *error = q->qdio_error; + + /* for the next time */ + q->first_to_kick = end; + q->qdio_error = 0; + return sub_buf(end, start); +} +EXPORT_SYMBOL(qdio_get_next_buffers); + +/** + * qdio_stop_irq - disable interrupt processing for the device + * @cdev: associated ccw_device for the qdio subchannel + * @nr: input queue number + * + * Return codes + * 0 - interrupts were already disabled + * 1 - interrupts successfully disabled + */ +int qdio_stop_irq(struct ccw_device *cdev, int nr) +{ + struct qdio_q *q; + struct qdio_irq *irq_ptr = cdev->private->qdio_data; + + if (!irq_ptr) + return -ENODEV; + q = irq_ptr->input_qs[nr]; + + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) + return 0; + else + return 1; +} +EXPORT_SYMBOL(qdio_stop_irq); + static int __init init_QDIO(void) { int rc; diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 34c7e4046df456897f4ebbfaa6ad8e970a2869ca..a13cf7ec64b2b0e0ab558694e4d77e8487a9ab36 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -161,6 +161,7 @@ static void setup_queues(struct qdio_irq *irq_ptr, setup_queues_misc(q, irq_ptr, qdio_init->input_handler, i); q->is_input_q = 1; + q->u.in.queue_start_poll = qdio_init->queue_start_poll; setup_storage_lists(q, irq_ptr, input_sbal_array, i); input_sbal_array += QDIO_MAX_BUFFERS_PER_Q; diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 8daf1b99f15391a27f41e48e0407b1eefa01647c..752dbee06af582a4c2ac8481cb079658579bfcaa 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -25,24 +25,20 @@ */ #define TIQDIO_NR_NONSHARED_IND 63 #define TIQDIO_NR_INDICATORS (TIQDIO_NR_NONSHARED_IND + 1) -#define TIQDIO_SHARED_IND 63 /* list of thin interrupt input queues */ static LIST_HEAD(tiq_list); DEFINE_MUTEX(tiq_list_lock); /* adapter local summary indicator */ -static unsigned char *tiqdio_alsi; +static u8 *tiqdio_alsi; -/* device state change indicators */ -struct indicator_t { - u32 ind; /* u32 because of compare-and-swap performance */ - atomic_t count; /* use count, 0 or 1 for non-shared indicators */ -}; -static struct indicator_t *q_indicators; +struct indicator_t *q_indicators; static int css_qdio_omit_svs; +static u64 last_ai_time; + static inline unsigned long do_clear_global_summary(void) { register unsigned long __fn asm("1") = 3; @@ -116,59 +112,73 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) } } -static inline int shared_ind(struct qdio_irq *irq_ptr) +static inline int shared_ind_used(void) { - return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; + return atomic_read(&q_indicators[TIQDIO_SHARED_IND].count); } /** * tiqdio_thinint_handler - thin interrupt handler for qdio - * @ind: pointer to adapter local summary indicator - * @drv_data: NULL + * @alsi: pointer to adapter local summary indicator + * @data: NULL */ -static void tiqdio_thinint_handler(void *ind, void *drv_data) +static void tiqdio_thinint_handler(void *alsi, void *data) { struct qdio_q *q; + last_ai_time = S390_lowcore.int_clock; + /* * SVS only when needed: issue SVS to benefit from iqdio interrupt - * avoidance (SVS clears adapter interrupt suppression overwrite) + * avoidance (SVS clears adapter interrupt suppression overwrite). */ if (!css_qdio_omit_svs) do_clear_global_summary(); - /* - * reset local summary indicator (tiqdio_alsi) to stop adapter - * interrupts for now - */ - xchg((u8 *)ind, 0); + /* reset local summary indicator */ + if (shared_ind_used()) + xchg(tiqdio_alsi, 0); /* protect tiq_list entries, only changed in activate or shutdown */ rcu_read_lock(); /* check for work on all inbound thinint queues */ - list_for_each_entry_rcu(q, &tiq_list, entry) + list_for_each_entry_rcu(q, &tiq_list, entry) { + /* only process queues from changed sets */ - if (*q->irq_ptr->dsci) { - qperf_inc(q, adapter_int); + if (!*q->irq_ptr->dsci) + continue; + if (q->u.in.queue_start_poll) { + /* skip if polling is enabled or already in work */ + if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, + &q->u.in.queue_irq_state)) { + qperf_inc(q, int_discarded); + continue; + } + + /* avoid dsci clear here, done after processing */ + q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, + q->irq_ptr->int_parm); + } else { /* only clear it if the indicator is non-shared */ if (!shared_ind(q->irq_ptr)) xchg(q->irq_ptr->dsci, 0); /* - * don't call inbound processing directly since - * that could starve other thinint queues + * Call inbound processing but not directly + * since that could starve other thinint queues. */ tasklet_schedule(&q->tasklet); } - + qperf_inc(q, adapter_int); + } rcu_read_unlock(); /* - * if we used the shared indicator clear it now after all queues - * were processed + * If the shared indicator was used clear it now after all queues + * were processed. */ - if (atomic_read(&q_indicators[TIQDIO_SHARED_IND].count)) { + if (shared_ind_used()) { xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 0); /* prevent racing */ diff --git a/drivers/s390/net/Kconfig b/drivers/s390/net/Kconfig index 977bb4d4ed15425b6b780649c5c15d98e977c964..456b1874339765b1104fab2726a2d47358549559 100644 --- a/drivers/s390/net/Kconfig +++ b/drivers/s390/net/Kconfig @@ -100,6 +100,6 @@ config QETH_IPV6 config CCWGROUP tristate - default (LCS || CTCM || QETH) + default (LCS || CTCM || QETH || CLAW) endmenu diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index 2861e78773cb5f0e4ee319e4cc0928a00953c717..b64881f33f23341ba7c2ce798e223d816d62475c 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -540,7 +540,7 @@ void ctc_mpc_dealloc_ch(int port_num) CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_DEBUG, "%s: %s: refcount = %d\n", - CTCM_FUNTAIL, dev->name, atomic_read(&dev->refcnt)); + CTCM_FUNTAIL, dev->name, netdev_refcnt_read(dev)); fsm_deltimer(&priv->restart_timer); grp->channels_terminating = 0; diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index d1257768be90053f1a6d93c4c048b2de0bb89bd4..6be43eb126b40077ab4bc0298ef7179bea0c9496 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -676,6 +676,7 @@ enum qeth_discipline_id { }; struct qeth_discipline { + void (*start_poll)(struct ccw_device *, int, unsigned long); qdio_handler_t *input_handler; qdio_handler_t *output_handler; int (*recover)(void *ptr); @@ -702,6 +703,16 @@ struct qeth_skb_data { #define QETH_SKB_MAGIC 0x71657468 #define QETH_SIGA_CC2_RETRIES 3 +struct qeth_rx { + int b_count; + int b_index; + struct qdio_buffer_element *b_element; + int e_offset; + int qdio_err; +}; + +#define QETH_NAPI_WEIGHT 128 + struct qeth_card { struct list_head list; enum qeth_card_states state; @@ -749,6 +760,8 @@ struct qeth_card { debug_info_t *debug; struct mutex conf_mutex; struct mutex discipline_mutex; + struct napi_struct napi; + struct qeth_rx rx; }; struct qeth_card_list_struct { @@ -831,6 +844,10 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *, struct qdio_buffer *, struct qdio_buffer_element **, int *, struct qeth_hdr **); void qeth_schedule_recovery(struct qeth_card *); +void qeth_qdio_start_poll(struct ccw_device *, int, unsigned long); +void qeth_qdio_input_handler(struct ccw_device *, + unsigned int, unsigned int, int, + int, unsigned long); void qeth_qdio_output_handler(struct ccw_device *, unsigned int, int, int, int, unsigned long); void qeth_clear_ipacmd_list(struct qeth_card *); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 3a5a18a0fc283de5a987365e80dead90a9b6a9ea..764267062601b8812017f9552350b0ad6480ba23 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -2911,6 +2911,27 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue) } } +void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue, + unsigned long card_ptr) +{ + struct qeth_card *card = (struct qeth_card *)card_ptr; + + if (card->dev) + napi_schedule(&card->napi); +} +EXPORT_SYMBOL_GPL(qeth_qdio_start_poll); + +void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err, + unsigned int queue, int first_element, int count, + unsigned long card_ptr) +{ + struct qeth_card *card = (struct qeth_card *)card_ptr; + + if (qdio_err) + qeth_schedule_recovery(card); +} +EXPORT_SYMBOL_GPL(qeth_qdio_input_handler); + void qeth_qdio_output_handler(struct ccw_device *ccwdev, unsigned int qdio_error, int __queue, int first_element, int count, unsigned long card_ptr) @@ -3843,6 +3864,7 @@ static int qeth_qdio_establish(struct qeth_card *card) init_data.no_output_qs = card->qdio.no_out_queues; init_data.input_handler = card->discipline.input_handler; init_data.output_handler = card->discipline.output_handler; + init_data.queue_start_poll = card->discipline.start_poll; init_data.int_parm = (unsigned long) card; init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; @@ -4513,8 +4535,8 @@ static struct { /* 20 */{"queue 1 buffer usage"}, {"queue 2 buffer usage"}, {"queue 3 buffer usage"}, - {"rx handler time"}, - {"rx handler count"}, + {"rx poll time"}, + {"rx poll count"}, {"rx do_QDIO time"}, {"rx do_QDIO count"}, {"tx handler time"}, diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 830d63524d612ff8bc665f918d6b01400e5c0c88..847e8797073c7c407171b47ab36677582ed22071 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -310,6 +310,8 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) struct qeth_vlan_vid *id; QETH_CARD_TEXT_(card, 4, "aid:%d", vid); + if (!vid) + return; if (card->info.type == QETH_CARD_TYPE_OSM) { QETH_CARD_TEXT(card, 3, "aidOSM"); return; @@ -407,29 +409,25 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) return rc; } -static void qeth_l2_process_inbound_buffer(struct qeth_card *card, - struct qeth_qdio_buffer *buf, int index) +static int qeth_l2_process_inbound_buffer(struct qeth_card *card, + int budget, int *done) { - struct qdio_buffer_element *element; + int work_done = 0; struct sk_buff *skb; struct qeth_hdr *hdr; - int offset; unsigned int len; - /* get first element of current buffer */ - element = (struct qdio_buffer_element *)&buf->buffer->element[0]; - offset = 0; - if (card->options.performance_stats) - card->perf_stats.bufs_rec++; - while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element, - &offset, &hdr))) { - skb->dev = card->dev; - /* is device UP ? */ - if (!(card->dev->flags & IFF_UP)) { - dev_kfree_skb_any(skb); - continue; + *done = 0; + BUG_ON(!budget); + while (budget) { + skb = qeth_core_get_next_skb(card, + card->qdio.in_q->bufs[card->rx.b_index].buffer, + &card->rx.b_element, &card->rx.e_offset, &hdr); + if (!skb) { + *done = 1; + break; } - + skb->dev = card->dev; switch (hdr->hdr.l2.id) { case QETH_HEADER_TYPE_LAYER2: skb->pkt_type = PACKET_HOST; @@ -441,7 +439,7 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card, if (skb->protocol == htons(ETH_P_802_2)) *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; len = skb->len; - netif_rx(skb); + netif_receive_skb(skb); break; case QETH_HEADER_TYPE_OSN: if (card->info.type == QETH_CARD_TYPE_OSN) { @@ -459,9 +457,87 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card, QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN); continue; } + work_done++; + budget--; card->stats.rx_packets++; card->stats.rx_bytes += len; } + return work_done; +} + +static int qeth_l2_poll(struct napi_struct *napi, int budget) +{ + struct qeth_card *card = container_of(napi, struct qeth_card, napi); + int work_done = 0; + struct qeth_qdio_buffer *buffer; + int done; + int new_budget = budget; + + if (card->options.performance_stats) { + card->perf_stats.inbound_cnt++; + card->perf_stats.inbound_start_time = qeth_get_micros(); + } + + while (1) { + if (!card->rx.b_count) { + card->rx.qdio_err = 0; + card->rx.b_count = qdio_get_next_buffers( + card->data.ccwdev, 0, &card->rx.b_index, + &card->rx.qdio_err); + if (card->rx.b_count <= 0) { + card->rx.b_count = 0; + break; + } + card->rx.b_element = + &card->qdio.in_q->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + + while (card->rx.b_count) { + buffer = &card->qdio.in_q->bufs[card->rx.b_index]; + if (!(card->rx.qdio_err && + qeth_check_qdio_errors(card, buffer->buffer, + card->rx.qdio_err, "qinerr"))) + work_done += qeth_l2_process_inbound_buffer( + card, new_budget, &done); + else + done = 1; + + if (done) { + if (card->options.performance_stats) + card->perf_stats.bufs_rec++; + qeth_put_buffer_pool_entry(card, + buffer->pool_entry); + qeth_queue_input_buffer(card, card->rx.b_index); + card->rx.b_count--; + if (card->rx.b_count) { + card->rx.b_index = + (card->rx.b_index + 1) % + QDIO_MAX_BUFFERS_PER_Q; + card->rx.b_element = + &card->qdio.in_q + ->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + } + + if (work_done >= budget) + goto out; + else + new_budget = budget - work_done; + } + } + + napi_complete(napi); + if (qdio_start_irq(card->data.ccwdev, 0)) + napi_schedule(&card->napi); +out: + if (card->options.performance_stats) + card->perf_stats.inbound_time += qeth_get_micros() - + card->perf_stats.inbound_start_time; + return work_done; } static int qeth_l2_send_setdelmac(struct qeth_card *card, __u8 *mac, @@ -755,49 +831,10 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static void qeth_l2_qdio_input_handler(struct ccw_device *ccwdev, - unsigned int qdio_err, unsigned int queue, - int first_element, int count, unsigned long card_ptr) -{ - struct net_device *net_dev; - struct qeth_card *card; - struct qeth_qdio_buffer *buffer; - int index; - int i; - - card = (struct qeth_card *) card_ptr; - net_dev = card->dev; - if (card->options.performance_stats) { - card->perf_stats.inbound_cnt++; - card->perf_stats.inbound_start_time = qeth_get_micros(); - } - if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { - QETH_CARD_TEXT(card, 1, "qdinchk"); - QETH_CARD_TEXT_(card, 1, "%04X%04X", first_element, - count); - QETH_CARD_TEXT_(card, 1, "%04X", queue); - qeth_schedule_recovery(card); - return; - } - for (i = first_element; i < (first_element + count); ++i) { - index = i % QDIO_MAX_BUFFERS_PER_Q; - buffer = &card->qdio.in_q->bufs[index]; - if (!(qdio_err && - qeth_check_qdio_errors(card, buffer->buffer, qdio_err, - "qinerr"))) - qeth_l2_process_inbound_buffer(card, buffer, index); - /* clear buffer and give back to hardware */ - qeth_put_buffer_pool_entry(card, buffer->pool_entry); - qeth_queue_input_buffer(card, index); - } - if (card->options.performance_stats) - card->perf_stats.inbound_time += qeth_get_micros() - - card->perf_stats.inbound_start_time; -} - static int qeth_l2_open(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; + int rc = 0; QETH_CARD_TEXT(card, 4, "qethopen"); if (card->state != CARD_STATE_SOFTSETUP) @@ -814,18 +851,24 @@ static int qeth_l2_open(struct net_device *dev) if (!card->lan_online && netif_carrier_ok(dev)) netif_carrier_off(dev); - return 0; + if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { + napi_enable(&card->napi); + napi_schedule(&card->napi); + } else + rc = -EIO; + return rc; } - static int qeth_l2_stop(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; QETH_CARD_TEXT(card, 4, "qethstop"); netif_tx_disable(dev); - if (card->state == CARD_STATE_UP) + if (card->state == CARD_STATE_UP) { card->state = CARD_STATE_SOFTSETUP; + napi_disable(&card->napi); + } return 0; } @@ -836,8 +879,9 @@ static int qeth_l2_probe_device(struct ccwgroup_device *gdev) INIT_LIST_HEAD(&card->vid_list); INIT_LIST_HEAD(&card->mc_list); card->options.layer2 = 1; + card->discipline.start_poll = qeth_qdio_start_poll; card->discipline.input_handler = (qdio_handler_t *) - qeth_l2_qdio_input_handler; + qeth_qdio_input_handler; card->discipline.output_handler = (qdio_handler_t *) qeth_qdio_output_handler; card->discipline.recover = qeth_l2_recover; @@ -923,6 +967,7 @@ static int qeth_l2_setup_netdev(struct qeth_card *card) card->info.broadcast_capable = 1; qeth_l2_request_initial_mac(card); SET_NETDEV_DEV(card->dev, &card->gdev->dev); + netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT); return register_netdev(card->dev); } @@ -955,6 +1000,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) qeth_l2_send_setmac(card, &card->dev->dev_addr[0]); card->state = CARD_STATE_HARDSETUP; + memset(&card->rx, 0, sizeof(struct qeth_rx)); qeth_print_status_message(card); /* softsetup */ @@ -1086,9 +1132,6 @@ static int qeth_l2_recover(void *ptr) card->use_hard_stop = 1; __qeth_l2_set_offline(card->gdev, 1); rc = __qeth_l2_set_online(card->gdev, 1); - /* don't run another scheduled recovery */ - qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); - qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); if (!rc) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); @@ -1099,6 +1142,8 @@ static int qeth_l2_recover(void *ptr) dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } + qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); + qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); return 0; } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index e22ae248f613eea825eaf8fe48f02bbd078f9818..74d1401a5d5e37065ba722914cf8549ad8718d9c 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -103,12 +103,7 @@ int qeth_l3_string_to_ipaddr4(const char *buf, __u8 *addr) void qeth_l3_ipaddr6_to_string(const __u8 *addr, char *buf) { - sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x" - ":%02x%02x:%02x%02x:%02x%02x:%02x%02x", - addr[0], addr[1], addr[2], addr[3], - addr[4], addr[5], addr[6], addr[7], - addr[8], addr[9], addr[10], addr[11], - addr[12], addr[13], addr[14], addr[15]); + sprintf(buf, "%pI6", addr); } int qeth_l3_string_to_ipaddr6(const char *buf, __u8 *addr) @@ -1825,7 +1820,7 @@ static void qeth_l3_add_vlan_mc(struct qeth_card *card) return; vg = card->vlangrp; - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { struct net_device *netdev = vlan_group_get_device(vg, i); if (netdev == NULL || !(netdev->flags & IFF_UP)) @@ -1888,7 +1883,7 @@ static void qeth_l3_add_vlan_mc6(struct qeth_card *card) return; vg = card->vlangrp; - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { struct net_device *netdev = vlan_group_get_device(vg, i); if (netdev == NULL || !(netdev->flags & IFF_UP)) @@ -2018,13 +2013,14 @@ static void qeth_l3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) qeth_l3_set_multicast_list(card->dev); } -static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, - struct sk_buff *skb, struct qeth_hdr *hdr) +static inline int qeth_l3_rebuild_skb(struct qeth_card *card, + struct sk_buff *skb, struct qeth_hdr *hdr, + unsigned short *vlan_id) { - unsigned short vlan_id = 0; __be16 prot; struct iphdr *ip_hdr; unsigned char tg_addr[MAX_ADDR_LEN]; + int is_vlan = 0; if (!(hdr->hdr.l3.flags & QETH_HDR_PASSTHRU)) { prot = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 : @@ -2087,8 +2083,9 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, if (hdr->hdr.l3.ext_flags & (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) { - vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)? + *vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME) ? hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]); + is_vlan = 1; } switch (card->options.checksum_type) { @@ -2109,54 +2106,44 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card, skb->ip_summed = CHECKSUM_NONE; } - return vlan_id; + return is_vlan; } -static void qeth_l3_process_inbound_buffer(struct qeth_card *card, - struct qeth_qdio_buffer *buf, int index) +static int qeth_l3_process_inbound_buffer(struct qeth_card *card, + int budget, int *done) { - struct qdio_buffer_element *element; + int work_done = 0; struct sk_buff *skb; struct qeth_hdr *hdr; - int offset; __u16 vlan_tag = 0; + int is_vlan; unsigned int len; - /* get first element of current buffer */ - element = (struct qdio_buffer_element *)&buf->buffer->element[0]; - offset = 0; - if (card->options.performance_stats) - card->perf_stats.bufs_rec++; - while ((skb = qeth_core_get_next_skb(card, buf->buffer, &element, - &offset, &hdr))) { - skb->dev = card->dev; - /* is device UP ? */ - if (!(card->dev->flags & IFF_UP)) { - dev_kfree_skb_any(skb); - continue; - } + *done = 0; + BUG_ON(!budget); + while (budget) { + skb = qeth_core_get_next_skb(card, + card->qdio.in_q->bufs[card->rx.b_index].buffer, + &card->rx.b_element, &card->rx.e_offset, &hdr); + if (!skb) { + *done = 1; + break; + } + skb->dev = card->dev; switch (hdr->hdr.l3.id) { case QETH_HEADER_TYPE_LAYER3: - vlan_tag = qeth_l3_rebuild_skb(card, skb, hdr); + is_vlan = qeth_l3_rebuild_skb(card, skb, hdr, + &vlan_tag); len = skb->len; - if (vlan_tag && !card->options.sniffer) - if (card->vlangrp) - vlan_hwaccel_rx(skb, card->vlangrp, - vlan_tag); - else { - dev_kfree_skb_any(skb); - continue; - } + if (is_vlan && !card->options.sniffer) + vlan_gro_receive(&card->napi, card->vlangrp, + vlan_tag, skb); else - netif_rx(skb); + napi_gro_receive(&card->napi, skb); break; case QETH_HEADER_TYPE_LAYER2: /* for HiperSockets sniffer */ skb->pkt_type = PACKET_HOST; skb->protocol = eth_type_trans(skb, skb->dev); - if (card->options.checksum_type == NO_CHECKSUMMING) - skb->ip_summed = CHECKSUM_UNNECESSARY; - else - skb->ip_summed = CHECKSUM_NONE; len = skb->len; netif_receive_skb(skb); break; @@ -2166,10 +2153,87 @@ static void qeth_l3_process_inbound_buffer(struct qeth_card *card, QETH_DBF_HEX(CTRL, 3, hdr, QETH_DBF_CTRL_LEN); continue; } - + work_done++; + budget--; card->stats.rx_packets++; card->stats.rx_bytes += len; } + return work_done; +} + +static int qeth_l3_poll(struct napi_struct *napi, int budget) +{ + struct qeth_card *card = container_of(napi, struct qeth_card, napi); + int work_done = 0; + struct qeth_qdio_buffer *buffer; + int done; + int new_budget = budget; + + if (card->options.performance_stats) { + card->perf_stats.inbound_cnt++; + card->perf_stats.inbound_start_time = qeth_get_micros(); + } + + while (1) { + if (!card->rx.b_count) { + card->rx.qdio_err = 0; + card->rx.b_count = qdio_get_next_buffers( + card->data.ccwdev, 0, &card->rx.b_index, + &card->rx.qdio_err); + if (card->rx.b_count <= 0) { + card->rx.b_count = 0; + break; + } + card->rx.b_element = + &card->qdio.in_q->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + + while (card->rx.b_count) { + buffer = &card->qdio.in_q->bufs[card->rx.b_index]; + if (!(card->rx.qdio_err && + qeth_check_qdio_errors(card, buffer->buffer, + card->rx.qdio_err, "qinerr"))) + work_done += qeth_l3_process_inbound_buffer( + card, new_budget, &done); + else + done = 1; + + if (done) { + if (card->options.performance_stats) + card->perf_stats.bufs_rec++; + qeth_put_buffer_pool_entry(card, + buffer->pool_entry); + qeth_queue_input_buffer(card, card->rx.b_index); + card->rx.b_count--; + if (card->rx.b_count) { + card->rx.b_index = + (card->rx.b_index + 1) % + QDIO_MAX_BUFFERS_PER_Q; + card->rx.b_element = + &card->qdio.in_q + ->bufs[card->rx.b_index] + .buffer->element[0]; + card->rx.e_offset = 0; + } + } + + if (work_done >= budget) + goto out; + else + new_budget = budget - work_done; + } + } + + napi_complete(napi); + if (qdio_start_irq(card->data.ccwdev, 0)) + napi_schedule(&card->napi); +out: + if (card->options.performance_stats) + card->perf_stats.inbound_time += qeth_get_micros() - + card->perf_stats.inbound_start_time; + return work_done; } static int qeth_l3_verify_vlan_dev(struct net_device *dev, @@ -2183,7 +2247,7 @@ static int qeth_l3_verify_vlan_dev(struct net_device *dev, if (!vg) return rc; - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { if (vlan_group_get_device(vg, i) == dev) { rc = QETH_VLAN_CARD; break; @@ -3103,6 +3167,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) static int qeth_l3_open(struct net_device *dev) { struct qeth_card *card = dev->ml_priv; + int rc = 0; QETH_CARD_TEXT(card, 4, "qethopen"); if (card->state != CARD_STATE_SOFTSETUP) @@ -3113,7 +3178,12 @@ static int qeth_l3_open(struct net_device *dev) if (!card->lan_online && netif_carrier_ok(dev)) netif_carrier_off(dev); - return 0; + if (qdio_stop_irq(card->data.ccwdev, 0) >= 0) { + napi_enable(&card->napi); + napi_schedule(&card->napi); + } else + rc = -EIO; + return rc; } static int qeth_l3_stop(struct net_device *dev) @@ -3122,8 +3192,10 @@ static int qeth_l3_stop(struct net_device *dev) QETH_CARD_TEXT(card, 4, "qethstop"); netif_tx_disable(dev); - if (card->state == CARD_STATE_UP) + if (card->state == CARD_STATE_UP) { card->state = CARD_STATE_SOFTSETUP; + napi_disable(&card->napi); + } return 0; } @@ -3293,57 +3365,19 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) card->dev->gso_max_size = 15 * PAGE_SIZE; SET_NETDEV_DEV(card->dev, &card->gdev->dev); + netif_napi_add(card->dev, &card->napi, qeth_l3_poll, QETH_NAPI_WEIGHT); return register_netdev(card->dev); } -static void qeth_l3_qdio_input_handler(struct ccw_device *ccwdev, - unsigned int qdio_err, unsigned int queue, int first_element, - int count, unsigned long card_ptr) -{ - struct net_device *net_dev; - struct qeth_card *card; - struct qeth_qdio_buffer *buffer; - int index; - int i; - - card = (struct qeth_card *) card_ptr; - net_dev = card->dev; - if (card->options.performance_stats) { - card->perf_stats.inbound_cnt++; - card->perf_stats.inbound_start_time = qeth_get_micros(); - } - if (qdio_err & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { - QETH_CARD_TEXT(card, 1, "qdinchk"); - QETH_CARD_TEXT_(card, 1, "%04X%04X", - first_element, count); - QETH_CARD_TEXT_(card, 1, "%04X", queue); - qeth_schedule_recovery(card); - return; - } - for (i = first_element; i < (first_element + count); ++i) { - index = i % QDIO_MAX_BUFFERS_PER_Q; - buffer = &card->qdio.in_q->bufs[index]; - if (!(qdio_err && - qeth_check_qdio_errors(card, buffer->buffer, - qdio_err, "qinerr"))) - qeth_l3_process_inbound_buffer(card, buffer, index); - /* clear buffer and give back to hardware */ - qeth_put_buffer_pool_entry(card, buffer->pool_entry); - qeth_queue_input_buffer(card, index); - } - if (card->options.performance_stats) - card->perf_stats.inbound_time += qeth_get_micros() - - card->perf_stats.inbound_start_time; -} - static int qeth_l3_probe_device(struct ccwgroup_device *gdev) { struct qeth_card *card = dev_get_drvdata(&gdev->dev); qeth_l3_create_device_attributes(&gdev->dev); card->options.layer2 = 0; + card->discipline.start_poll = qeth_qdio_start_poll; card->discipline.input_handler = (qdio_handler_t *) - qeth_l3_qdio_input_handler; + qeth_qdio_input_handler; card->discipline.output_handler = (qdio_handler_t *) qeth_qdio_output_handler; card->discipline.recover = qeth_l3_recover; @@ -3402,6 +3436,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) } card->state = CARD_STATE_HARDSETUP; + memset(&card->rx, 0, sizeof(struct qeth_rx)); qeth_print_status_message(card); /* softsetup */ @@ -3538,9 +3573,6 @@ static int qeth_l3_recover(void *ptr) card->use_hard_stop = 1; __qeth_l3_set_offline(card->gdev, 1); rc = __qeth_l3_set_online(card->gdev, 1); - /* don't run another scheduled recovery */ - qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); - qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); if (!rc) dev_info(&card->gdev->dev, "Device successfully recovered!\n"); @@ -3551,6 +3583,8 @@ static int qeth_l3_recover(void *ptr) dev_warn(&card->gdev->dev, "The qeth device driver " "failed to recover an error on the device\n"); } + qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD); + qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD); return 0; } diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 60e6e5714eb94a3a07cda134b4bcbf2db1d46ee4..a0554beb4179efde170b463689f53b1fbf637290 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -279,16 +279,12 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req) static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, struct zfcp_qdio *qdio) { - + memset(id, 0, sizeof(*id)); id->cdev = qdio->adapter->ccw_device; id->q_format = QDIO_ZFCP_QFMT; memcpy(id->adapter_name, dev_name(&id->cdev->dev), 8); ASCEBC(id->adapter_name, 8); id->qib_rflags = QIB_RFLAGS_ENABLE_DATA_DIV; - id->qib_param_field_format = 0; - id->qib_param_field = NULL; - id->input_slib_elements = NULL; - id->output_slib_elements = NULL; id->no_input_qs = 1; id->no_output_qs = 1; id->input_handler = zfcp_qdio_int_resp; diff --git a/drivers/scsi/bnx2i/57xx_iscsi_constants.h b/drivers/scsi/bnx2i/57xx_iscsi_constants.h index 2fceb19eb27b7fefe74545d61fff364991c4259e..1b6f86b2482d6cf7c2e81faf56c555dfa14547d6 100644 --- a/drivers/scsi/bnx2i/57xx_iscsi_constants.h +++ b/drivers/scsi/bnx2i/57xx_iscsi_constants.h @@ -120,6 +120,8 @@ /* additional LOM specific iSCSI license not installed */ #define ISCSI_KCQE_COMPLETION_STATUS_LOM_ISCSI_NOT_ENABLED (0x51) +#define ISCSI_KCQE_COMPLETION_STATUS_CID_BUSY (0x80) + /* SQ/RQ/CQ DB structure sizes */ #define ISCSI_SQ_DB_SIZE (16) #define ISCSI_RQ_DB_SIZE (16) diff --git a/drivers/scsi/bnx2i/bnx2i.h b/drivers/scsi/bnx2i/bnx2i.h index b6345d91bb66fc5ef29e469ddec3caddb9b9fd5e..a44b1b33fa18badd49bb92831e82300385f224cb 100644 --- a/drivers/scsi/bnx2i/bnx2i.h +++ b/drivers/scsi/bnx2i/bnx2i.h @@ -58,6 +58,8 @@ #define MAX_PAGES_PER_CTRL_STRUCT_POOL 8 #define BNX2I_RESERVED_SLOW_PATH_CMD_SLOTS 4 +#define BNX2I_5771X_DBELL_PAGE_SIZE 128 + /* 5706/08 hardware has limit on maximum buffer size per BD it can handle */ #define MAX_BD_LENGTH 65535 #define BD_SPLIT_SIZE 32768 diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 90cef716b796e901d9b952ef65504d8bdf1a29d7..8d9dbb33972f2d63cd5d7f336f6e4afdbb8e2ca0 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -2406,7 +2406,8 @@ int bnx2i_map_ep_dbell_regs(struct bnx2i_endpoint *ep) if (test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type)) { reg_base = pci_resource_start(ep->hba->pcidev, BNX2X_DOORBELL_PCI_BAR); - reg_off = PAGE_SIZE * (cid_num & 0x1FFFF) + DPM_TRIGER_TYPE; + reg_off = BNX2I_5771X_DBELL_PAGE_SIZE * (cid_num & 0x1FFFF) + + DPM_TRIGER_TYPE; ep->qp.ctx_base = ioremap_nocache(reg_base + reg_off, 4); goto arm_cq; } diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 5af23cc5ea9fe6cf8c9ded25ccea29f172dc5a8e..f383cb42b1d76c779f5fa91f5cac8d3599f16bba 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -1344,8 +1344,24 @@ static struct usbatm_driver cxacru_driver = { .tx_padding = 11, }; -static int cxacru_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +static int cxacru_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) { + struct usb_device *usb_dev = interface_to_usbdev(intf); + char buf[15]; + + /* Avoid ADSL routers (cx82310_eth). + * Abort if bDeviceClass is 0xff and iProduct is "USB NET CARD". + */ + if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC + && usb_string(usb_dev, usb_dev->descriptor.iProduct, + buf, sizeof(buf)) > 0) { + if (!strcmp(buf, "USB NET CARD")) { + dev_info(&intf->dev, "ignoring cx82310_eth device\n"); + return -ENODEV; + } + } + return usbatm_usb_probe(intf, id, &cxacru_driver); } diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 861af4a8b79cd0b1968ffa91019934b460b61821..4b4da5b86ff99337fc0d81afeb48363918df65c3 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -246,7 +246,7 @@ static int get_rx_bufs(struct vhost_virtqueue *vq, int r, nlogs = 0; while (datalen > 0) { - if (unlikely(seg >= VHOST_NET_MAX_SG)) { + if (unlikely(seg >= UIO_MAXIOV)) { r = -ENOBUFS; goto err; } diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 8b5a1b33d0fed906ef6d0873027a3275858e8c2c..94701ff3a23ad957a9c675bd3ccd74418c2f989e 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -212,6 +212,45 @@ static int vhost_worker(void *data) } } +/* Helper to allocate iovec buffers for all vqs. */ +static long vhost_dev_alloc_iovecs(struct vhost_dev *dev) +{ + int i; + for (i = 0; i < dev->nvqs; ++i) { + dev->vqs[i].indirect = kmalloc(sizeof *dev->vqs[i].indirect * + UIO_MAXIOV, GFP_KERNEL); + dev->vqs[i].log = kmalloc(sizeof *dev->vqs[i].log * UIO_MAXIOV, + GFP_KERNEL); + dev->vqs[i].heads = kmalloc(sizeof *dev->vqs[i].heads * + UIO_MAXIOV, GFP_KERNEL); + + if (!dev->vqs[i].indirect || !dev->vqs[i].log || + !dev->vqs[i].heads) + goto err_nomem; + } + return 0; +err_nomem: + for (; i >= 0; --i) { + kfree(dev->vqs[i].indirect); + kfree(dev->vqs[i].log); + kfree(dev->vqs[i].heads); + } + return -ENOMEM; +} + +static void vhost_dev_free_iovecs(struct vhost_dev *dev) +{ + int i; + for (i = 0; i < dev->nvqs; ++i) { + kfree(dev->vqs[i].indirect); + dev->vqs[i].indirect = NULL; + kfree(dev->vqs[i].log); + dev->vqs[i].log = NULL; + kfree(dev->vqs[i].heads); + dev->vqs[i].heads = NULL; + } +} + long vhost_dev_init(struct vhost_dev *dev, struct vhost_virtqueue *vqs, int nvqs) { @@ -229,6 +268,9 @@ long vhost_dev_init(struct vhost_dev *dev, dev->worker = NULL; for (i = 0; i < dev->nvqs; ++i) { + dev->vqs[i].log = NULL; + dev->vqs[i].indirect = NULL; + dev->vqs[i].heads = NULL; dev->vqs[i].dev = dev; mutex_init(&dev->vqs[i].mutex); vhost_vq_reset(dev, dev->vqs + i); @@ -295,6 +337,10 @@ static long vhost_dev_set_owner(struct vhost_dev *dev) if (err) goto err_cgroup; + err = vhost_dev_alloc_iovecs(dev); + if (err) + goto err_cgroup; + return 0; err_cgroup: kthread_stop(worker); @@ -345,6 +391,7 @@ void vhost_dev_cleanup(struct vhost_dev *dev) fput(dev->vqs[i].call); vhost_vq_reset(dev, dev->vqs + i); } + vhost_dev_free_iovecs(dev); if (dev->log_ctx) eventfd_ctx_put(dev->log_ctx); dev->log_ctx = NULL; @@ -372,7 +419,7 @@ static int log_access_ok(void __user *log_base, u64 addr, unsigned long sz) /* Make sure 64 bit math will not overflow. */ if (a > ULONG_MAX - (unsigned long)log_base || a + (unsigned long)log_base > ULONG_MAX) - return -EFAULT; + return 0; return access_ok(VERIFY_WRITE, log_base + a, (sz + VHOST_PAGE_SIZE * 8 - 1) / VHOST_PAGE_SIZE / 8); @@ -957,7 +1004,7 @@ static int get_indirect(struct vhost_dev *dev, struct vhost_virtqueue *vq, } ret = translate_desc(dev, indirect->addr, indirect->len, vq->indirect, - ARRAY_SIZE(vq->indirect)); + UIO_MAXIOV); if (unlikely(ret < 0)) { vq_err(vq, "Translation failure %d in indirect.\n", ret); return ret; diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h index af3c11ded5fd4910ed0dccea161a801298036731..073d06ae091f26efc519323f37b94d9ab56c2817 100644 --- a/drivers/vhost/vhost.h +++ b/drivers/vhost/vhost.h @@ -15,11 +15,6 @@ struct vhost_device; -enum { - /* Enough place for all fragments, head, and virtio net header. */ - VHOST_NET_MAX_SG = MAX_SKB_FRAGS + 2, -}; - struct vhost_work; typedef void (*vhost_work_fn_t)(struct vhost_work *work); @@ -93,12 +88,15 @@ struct vhost_virtqueue { bool log_used; u64 log_addr; - struct iovec indirect[VHOST_NET_MAX_SG]; - struct iovec iov[VHOST_NET_MAX_SG]; - struct iovec hdr[VHOST_NET_MAX_SG]; + struct iovec iov[UIO_MAXIOV]; + /* hdr is used to store the virtio header. + * Since each iovec has >= 1 byte length, we never need more than + * header length entries to store the header. */ + struct iovec hdr[sizeof(struct virtio_net_hdr_mrg_rxbuf)]; + struct iovec *indirect; size_t vhost_hlen; size_t sock_hlen; - struct vring_used_elem heads[VHOST_NET_MAX_SG]; + struct vring_used_elem *heads; /* We use a kind of RCU to access private pointer. * All readers access it from worker, which makes it possible to * flush the vhost_work instead of synchronize_rcu. Therefore readers do @@ -109,7 +107,7 @@ struct vhost_virtqueue { void __rcu *private_data; /* Log write descriptors */ void __user *log_base; - struct vhost_log log[VHOST_NET_MAX_SG]; + struct vhost_log *log; }; struct vhost_dev { diff --git a/firmware/Makefile b/firmware/Makefile index 9c2d19452d0bf08a4c3642c7596d6056a8456797..74d47cd0886c036f81733d79a07af772a128c1b9 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -32,12 +32,14 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \ adaptec/starfire_tx.bin fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw -fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-5.2.13.0.fw bnx2x-e1h-5.2.13.0.fw -fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-5.0.0.j15.fw \ - bnx2/bnx2-rv2p-09-5.0.0.j10.fw \ - bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw \ - bnx2/bnx2-mips-06-5.0.0.j6.fw \ - bnx2/bnx2-rv2p-06-5.0.0.j3.fw +fw-shipped-$(CONFIG_BNX2X) += bnx2x/bnx2x-e1-6.0.34.0.fw \ + bnx2x/bnx2x-e1h-6.0.34.0.fw \ + bnx2x/bnx2x-e2-6.0.34.0.fw +fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-6.0.17.fw \ + bnx2/bnx2-rv2p-09-6.0.17.fw \ + bnx2/bnx2-rv2p-09ax-6.0.17.fw \ + bnx2/bnx2-mips-06-6.0.15.fw \ + bnx2/bnx2-rv2p-06-6.0.15.fw fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \ diff --git a/firmware/WHENCE b/firmware/WHENCE index ae5f8a47f2920751e2c8b5760e6050b3e6e7fd55..f22c4dfd0733c40ab6f28c439fc2d38608fb0b68 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -679,8 +679,8 @@ Found in hex form in kernel source. Driver: bnx2x: Broadcom Everest -File: bnx2x-e1-5.2.13.0.fw -File: bnx2x-e1h-5.2.13.0.fw +File: bnx2x/bnx2x-e1-5.2.13.0.fw +File: bnx2x/bnx2x-e1h-5.2.13.0.fw License: Copyright (c) 2007-2010 Broadcom Corporation @@ -699,15 +699,16 @@ Found in hex form in kernel source. Driver: BNX2 - Broadcom NetXtremeII -File: bnx2/bnx2-mips-06-4.6.16.fw -File: bnx2/bnx2-rv2p-06-4.6.16.fw -File: bnx2/bnx2-mips-09-4.6.17.fw -File: bnx2/bnx2-rv2p-09-4.6.15.fw +File: bnx2/bnx2-mips-06-6.0.15.fw +File: bnx2/bnx2-rv2p-06-6.0.15.fw +File: bnx2/bnx2-mips-09-6.0.17.fw +File: bnx2/bnx2-rv2p-09-6.0.17.fw +File: bnx2/bnx2-rv2p-09ax-6.0.17.fw Licence: This file contains firmware data derived from proprietary unpublished - source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + source code, Copyright (c) 2004 - 2010 Broadcom Corporation. Permission is hereby granted for the distribution of this firmware data in hexadecimal or equivalent format, provided this copyright notice is diff --git a/firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex b/firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex deleted file mode 100644 index 8d379bffbfef1c3bf543199b208e4f9cdea390b9..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-mips-06-5.0.0.j6.fw.ihex +++ /dev/null @@ -1,5908 +0,0 @@ -:10000000080001100800000000004CC8000000C8F3 -:1000100000000000000000000000000008004CC8C4 -:100020000000001400004D90080000880800000047 -:10003000000058C400004DA408005A40000000848D -:100040000000A668080058C4000001540000A6EC97 -:10005000080031D808000000000075340000A840F6 -:1000600000000000000000000000000008007534DF -:100070000000002400011D7408000488080004002A -:100080000000175C00011D98000000000000000047 -:100090000000000000000000000000000000000060 -:1000A000080000A80800000000003B38000134F4FC -:1000B0000000000000000000000000000000000040 -:0800C000000000000000000038 -:0800C8000A00004400000000E2 -:1000D000000000000000000D636F6D352E302E30E3 -:1000E0006A36000005000002000000000000000366 -:1000F00000000014000000320000000300000000B7 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000100000030C -:1001E000000000000000000D0000000D3C020800AF -:1001F00024424D003C03080024634DFCAC40000049 -:100200000043202B1480FFFD244200043C1D080005 -:1002100037BD7FFC03A0F0213C1008002610011020 -:100220003C1C0800279C4D000E000214000000003A -:100230000000000D27BDFFE8AFBF0014AFB00010F5 -:100240009742010830437000240220001062000B26 -:10025000286220011440002F0000102124024000D9 -:1002600010620025000000002402600010620026D9 -:10027000000010210A0000948FBF001427500100D5 -:10028000920200091040001A240300013C020800F9 -:100290008C42002010400016000018210E00052B93 -:1002A00000000000960300083C06080094C64DBEFE -:1002B0008E0400188F8200209605000C00031C009D -:1002C00000661825AC440000AC450004240400017D -:1002D000AC400008AC40000CAC400010AC40001436 -:1002E000AC4000180E000550AC43001C0000182163 -:1002F0000A000093006010210E0003BD0000000002 -:100300000A000093000010210E000F810000000081 -:10031000000010218FBF00148FB0001003E0000810 -:1003200027BD001827BDFFE0AFB00010AFBF001819 -:10033000AFB10014275001009203000B2402001AF1 -:10034000961100081462005B00002821322200018F -:1003500010400008000000008E0200009603001408 -:10036000000211C200021040005A10210A0000DBF6 -:10037000A44300803C0208008C420020104000286A -:10038000000000000E00052B00000000974201084D -:100390009743010C8F8500203042003E3063FFFF01 -:1003A0000002140000431025ACA200008F4201009F -:1003B0003C06080094C64DBEACA20004974301164B -:1003C0009744010E3C02200000031C003084FFFF14 -:1003D00000641825ACA3000800C230259742011024 -:1003E0009743011224040001000214003063FFFF50 -:1003F00000431025ACA2000C974201143042FFFFCD -:10040000ACA200108F420118ACA200149342010B61 -:10041000304200FFACA200180E000550ACA6001C34 -:100420003C0208008C420040244200013C010800CC -:10043000AC2200403C0308008C63004432220002DE -:1004400032240004246300013C010800AC23004472 -:10045000108000180002282B8F4202B804430008C5 -:100460008E0200203C0208008C4200602442000101 -:100470003C010800AC2200600A0000FB24050001DA -:100480009603001600002821AF4202808E0200046D -:10049000A7430284AF4202883C021000AF4202B878 -:1004A0003C0208008C42005C244200013C01080030 -:1004B000AC22005C8FBF00188FB100148FB0001009 -:1004C00000A0102103E0000827BD002027BDFFE0A9 -:1004D000AFB00010AFBF0018AFB10014275001003B -:1004E0009203000B24020003961100081462006DB1 -:1004F000000020213222000110400008000000000E -:100500008E02000096030014000211C20002104087 -:10051000005A10210A000142A44300803C02080056 -:100520008C42002010400025000000000E00052B2A -:1005300000000000974201089743010C8F850020BE -:100540003042003E3063FFFF0002140000431025DC -:10055000ACA200008F4201003C06080094C64DBECC -:10056000ACA20004974301169744010E3C02200000 -:1005700000031C003084FFFF00641825ACA30008B2 -:1005800000C2302597420110974301122404000154 -:10059000000214003063FFFF00431025ACA2000CE2 -:1005A000974201143042FFFFACA20010ACA000142F -:1005B000ACA000180E000550ACA6001C3C020800C0 -:1005C0008C420040244200013C010800AC22004063 -:1005D0003C0208008C420044322300042442000103 -:1005E0003C010800AC2200441060001A32220002D4 -:1005F0008F4202B8044300088E0200203C0208002B -:100600008C420060244200013C010800AC220060E2 -:100610000A0001772404000196030016000020213F -:10062000AF4202808E020004A7430284AF420288D8 -:100630003C021000AF4202B83C0208008C42005C51 -:10064000244200013C010800AC22005C0A00017851 -:100650008FBF001810400013000020218F430104B9 -:100660003C026020AC4300148C420004240301FED1 -:10067000304203FF1443000B000020218F42010091 -:10068000000211C02442FFFC2C420008104000026E -:100690002403000200031F403C026000AC436914C5 -:1006A000000020218FBF00188FB100148FB0001000 -:1006B0000080102103E0000827BD00208F430100C7 -:1006C0002402010050620003000311C20000000D6B -:1006D000000311C200021040005A1021A440008003 -:1006E00003E00008000010219362000003E000080E -:1006F000AF80000003E000080000102103E00008C4 -:1007000000001021240201001482000800000000F3 -:100710003C0208008C4200FC244200013C0108001D -:10072000AC2200FC0A00019F30A200203C0208001D -:100730008C420084244200013C010800AC22008469 -:1007400030A200201040000830A300103C02080036 -:100750008C420108244200013C010800AC2201083F -:1007600003E0000800000000106000080000000026 -:100770003C0208008C420104244200013C010800B4 -:10078000AC22010403E00008000000003C02080065 -:100790008C420100244200013C010800AC2201000F -:1007A00003E000080000000027BDFFE8AFBF001015 -:1007B0002744010094830008306200041040001BAD -:1007C000306600028F4202B804410008240500018F -:1007D0003C0208008C420060244200013C010800F9 -:1007E000AC2200600A0001EB8FBF00108C82002059 -:1007F0009483001600002821AF4202808C820004FE -:10080000A7430284AF4202883C021000AF4202B804 -:100810003C0208008C42005C244200013C010800BC -:10082000AC22005C0A0001EB8FBF001010C0000674 -:10083000006028218F4401000E00018F000000009D -:100840000A0001EA240500018F8200088F43010499 -:1008500050430007000028218F4401000E00018F43 -:10086000000000008F420104AF8200080000282130 -:100870008FBF001000A0102103E0000827BD001862 -:100880003C0208008C420088274301009465000C5C -:10089000244200013C010800AC2200888C6400184E -:1008A0000345102190454000AF4400388C62001C85 -:1008B0002403FFF800052E000043102434420004F6 -:1008C000AF42003C3C020005AF4200300000000097 -:1008D0000000000000000000AF450404000000001C -:1008E00000000000000000003C020006344200014D -:1008F000AF420030000000000000000000000000D7 -:100900008F420000304200101040FFFD0000102117 -:1009100003E000080000000027BDFFE0AFB20018B0 -:100920003C036010AFBF001CAFB10014AFB00010AB -:100930008C6450002402FF7F3C1A80000082202437 -:100940003484380C24020037AC6450003C12080098 -:1009500026524D38AF42000824020C80AF420024DA -:100960003C1B80083C06080024C6062C02401021CF -:100970002404001C2484FFFFAC4600000481FFFD1A -:10098000244200043C0208002442016C3C0108009F -:10099000AC224D403C020800244204043C01080003 -:1009A000AC224D443C020800244207B83C01080038 -:1009B000AC224D883C0208002442025C3C03080043 -:1009C000246306343C040800248406E03C05080047 -:1009D00024A53B503C010800AC224DA03C0208007D -:1009E000244205F43C010800AC264D843C0108007B -:1009F000AC254D943C010800AC234D9C3C01080003 -:100A0000AC244DA43C010800AC224DA83C010800D8 -:100A1000AC234D3C3C010800AC204D483C01080093 -:100A2000AC204D4C3C010800AC204D503C0108006E -:100A3000AC204D543C010800AC204D583C0108004E -:100A4000AC204D5C3C010800AC204D603C0108002E -:100A5000AC244D643C010800AC204D683C0108000A -:100A6000AC204D6C3C010800AC204D703C010800EE -:100A7000AC204D743C010800AC204D783C010800CE -:100A8000AC264D7C3C010800AC264D803C010800A2 -:100A9000AC204D8C3C010800AC254D903C01080079 -:100AA000AC234D980E0006BB000000003C02800005 -:100AB000344200708C420000AF8200143C030800F6 -:100AC0008C6300208F820004104300043C028000ED -:100AD0000E0004F3AF8300043C0280003446007033 -:100AE0003C0308008C6300A03C0208008C4200A478 -:100AF000104300048F8400143C010800AC2300A4C0 -:100B0000A743009E8CCA00003C0308008C6300BC15 -:100B10003C0208008C4200B80144202300641821E4 -:100B2000000040210064202B0048102100441021C7 -:100B30003C010800AC2300BC3C010800AC2200B81A -:100B40008F510000322200071040FFDCAF8A0014F2 -:100B50008CC600003C0508008CA500BC3C040800C5 -:100B60008C8400B800CA302300A628210000102180 -:100B700000A6302B00822021008620213227000190 -:100B80003C010800AC2500BC3C010800AC2400B8C6 -:100B900010E0001F322200028F420100AF4200200D -:100BA0008F420104AF4200A89342010B0E0001885E -:100BB000305000FF2E02001D544000040010108031 -:100BC0000E00018B0A0002C5000000000052102137 -:100BD0008C4200000040F8090000000010400005B1 -:100BE0003C0240008F4301043C026020AC430014EF -:100BF0003C024000AF4201383C0208008C42003405 -:100C0000244200013C010800AC22003432220002E0 -:100C10001040000E322200048F4201400E00018875 -:100C2000AF4200200E00034B000000003C024000D9 -:100C3000AF4201783C0208008C4200382442000197 -:100C40003C010800AC220038322200041040FF981A -:100C50003C0280008F4201800E000188AF420020DC -:100C60008F43018024020F00146200050000000081 -:100C70008F420188A742009C0A0002FA3C02400011 -:100C80009362000024030050304200FF1443000828 -:100C90003C0240000E00032D000000005440000400 -:100CA0003C0240000E000E0D000000003C0240001F -:100CB000AF4201B83C0208008C42003C24420001D3 -:100CC0003C010800AC22003C0A00027A3C02800091 -:100CD0003C0290003442000100822025AF440020F5 -:100CE0008F4200200440FFFE0000000003E00008E7 -:100CF000000000003C0280003442000100822025F8 -:100D000003E00008AF44002027BDFFE0AFB10014AE -:100D1000AFB0001000808821AFBF00180E000302A2 -:100D200030B000FF9362007D022020210202802566 -:100D3000A370007D8F7000743C0280000E00030BD6 -:100D400002028024160000098FBF00188F4201F8AC -:100D50000440FFFE24020002AF5101C0A34201C4BF -:100D60003C021000AF4201F88FBF00188FB1001491 -:100D70008FB0001003E0000827BD002027BDFFE86A -:100D8000AFBF0010974201843042020010400005BE -:100D9000000020210E001042000000000A00034164 -:100DA000240400018F420188044000098FBF001015 -:100DB0008F4201883C03FF00004310243C030400E1 -:100DC00014430003240400019362003E8FBF00100F -:100DD0000080102103E0000827BD00182402000154 -:100DE000A3600022A76200168F4401400A0003108E -:100DF0002405000127BDFFE8AFBF0014AFB000100D -:100E000093620000304400FF3883002038820030B5 -:100E10000003182B0002102B00621824106000033E -:100E200024020050148200628FBF001493420148D4 -:100E3000304200FF2443FFFF2C6200051040005C9D -:100E40008FBF0014000310803C03080024634CC8CB -:100E5000004310218C420000004000080000000008 -:100E60000E0003028F4401408F70000C8F4201443A -:100E70001602000224020001AF62000C0E00030BF8 -:100E80008F4401408F420144145000048FBF00146E -:100E90008FB000100A000FB827BD00188F62000C39 -:100EA0000A0003B300000000976200108F43014462 -:100EB0003042FFFF1462000900000000240200011C -:100EC000A76200108F420140AF4202003C021000B6 -:100ED000AF4202380A0003BA8FBF001497620010B5 -:100EE0000A0003B3000000000E0003028F4401401B -:100EF000976200128F4301443050FFFF1603000237 -:100F000024020001A76200120E00030B8F4401406F -:100F10008F420144160200048FBF00148FB00010EE -:100F20000A00034527BD0018976200120A0003B3A8 -:100F300000000000976200148F4301443042FFFF1D -:100F4000146200068FBF0014240200018FB000104D -:100F5000A76200140A0012E227BD0018976200146D -:100F60000A0003B300000000976200168F4301449B -:100F70003042FFFF14620006240200018FBF0014FC -:100F80008FB00010A76200160A000BAA27BD001838 -:100F900097620016144000068FBF00143C02080040 -:100FA0008C420070244200013C010800AC22007019 -:100FB0008FB0001003E0000827BD001827BDFFE830 -:100FC000AFBF0014AFB000108F500100936200005B -:100FD00093430109304400FF2402001F106200A562 -:100FE0002862002010400018240200382862000AFD -:100FF0001040000C2402000B286200081040002C56 -:1010000000000000046000E528620002144000288F -:1010100024020006106200268FBF00140A0004B7E5 -:101020008FB000101062005E2862000B144000DCDC -:101030008FBF00142402000E106200738FB00010E6 -:101040000A0004B700000000106200C028620039E6 -:101050001040000A2402008024020036106200CAF8 -:1010600028620037104000B424020035106200C12D -:101070008FBF00140A0004B78FB000101062002B5D -:101080002862008110400006240200C824020039B2 -:10109000106200B48FBF00140A0004B78FB00010B4 -:1010A000106200998FBF00140A0004B78FB00010BF -:1010B0003C0208008C420020104000B98FBF001491 -:1010C0000E00052B000000008F4201008F830020DE -:1010D0009745010C97460108AC6200008F4201045D -:1010E0003C04080094844DBE00052C00AC62000452 -:1010F0008F4201180006340000C43025AC6200089D -:101100008F42011C24040001AC62000C9342010ACE -:1011100000A22825AC650010AC600014AC6000187B -:10112000AC66001C0A00048D8FBF00143C0208004E -:101130008C4200201040009A8FBF00140E00052B37 -:1011400000000000974401083C03080094634DBE72 -:101150009745010C000422029746010E8F82002061 -:10116000000426000083202500052C003C0300809D -:1011700000A6282500832025AC400000AC400004D8 -:10118000AC400008AC40000CAC450010AC40001472 -:10119000AC400018AC44001C0A00048C240400017C -:1011A0009742010C144000150000000093620005F6 -:1011B0003042001014400011000000000E00030235 -:1011C0000200202193620005020020213442001019 -:1011D0000E00030BA36200059362000024030020AD -:1011E000304200FF1043006D020020218FBF001429 -:1011F0008FB000100A00105827BD00180000000D25 -:101200000A0004B68FBF00143C0208008C42002084 -:10121000104000638FBF00140E00052B000000007B -:101220008F4201048F8300209744010C3C05080085 -:1012300094A54DBEAC6200009762002C000424000F -:101240003042FFFF008220253C02400E00A22825EC -:10125000AC640004AC600008AC60000CAC60001032 -:10126000AC600014AC600018AC65001C0A00048C73 -:10127000240400010E00030202002021A7600008E0 -:101280000E00030B02002021020020210E0003109B -:10129000240500013C0208008C4200201040004060 -:1012A0008FBF00140E00052B000000009742010CB8 -:1012B0008F8300203C05080094A54DBE0002140059 -:1012C000AC700000AC620004AC6000088F64004C9D -:1012D0003C02401F00A22825AC64000C8F62005025 -:1012E00024040001AC6200108F620054AC62001450 -:1012F000AC600018AC65001C8FBF00148FB00010EC -:101300000A00055027BD0018240200205082002545 -:101310008FB000100E000FA202002021104000200C -:101320008FBF0014020020218FB000100000282180 -:101330000A00031027BD0018020020218FBF0014EF -:101340008FB000100A00061827BD00189745010C41 -:10135000020020218FBF00148FB000100A00063851 -:1013600027BD0018020020218FB000100A00065D82 -:1013700027BD00189345010D020020218FB00010F9 -:101380000A0006A727BD0018020020218FBF001405 -:101390008FB000100A00068327BD00188FBF00140D -:1013A0008FB0001003E0000827BD00188F420278BC -:1013B0000440FFFE2402000234840080AF44024057 -:1013C000A34202443C02100003E00008AF4202784E -:1013D0003C04080094844DCA3C0208008C424DD461 -:1013E0003083FFFF000318C000431021AF42003CD0 -:1013F0003C0208008C424DD0AF4200383C02005005 -:1014000034420008AF42003000000000000000003D -:10141000000000008F420000304200201040FFFD1D -:10142000000000008F4204003C010800AC224DC0C7 -:101430008F4204043C010800AC224DC43C02002051 -:10144000AF420030000000003C02080094424DC84A -:101450003C03080094634DCC3C05080094A54DCE98 -:1014600024840001004310213083FFFF3C01080069 -:10147000A4224DC83C010800A4244DCA14650003F1 -:10148000000000003C010800A4204DCA03E0000851 -:10149000000000003C05000A27BDFFE803452821A5 -:1014A0003C04080024844DB0AFBF00100E0005B509 -:1014B0002406000A3C02080094424DB23C03080096 -:1014C00094634DCE3042000F2442000300431804C1 -:1014D00024027FFF0043102B10400002AF83001C4A -:1014E0000000000D0E0004C2000000003C020800D5 -:1014F00094424DBA8FBF001027BD001803E00008CA -:10150000A74200A23C02000A0342102194430006B5 -:101510003C02080094424DBA3C010800A4234DB699 -:10152000004310238F83001C0002140000021403E8 -:101530000043102B03E000083842000127BDFFE8FC -:10154000AFBF00103C02000A034210219442000683 -:101550003C010800A4224DB60E00050F000000005B -:101560005440FFF93C02000A8FBF001003E000085E -:1015700027BD001827BDFFE8AFBF00100E00050F04 -:101580000000000010400003000000000E00051DD8 -:10159000000000003C0208008C424DC08FBF0010CC -:1015A00027430400AF4200383C0208008C424DC47F -:1015B00027BD0018AF830020AF42003C3C0200056D -:1015C000AF42003003E00008AF8000188F8200189F -:1015D0003C0300060002114000431025AF420030DA -:1015E0000000000000000000000000008F4200002A -:1015F000304200101040FFFD27420400AF8200205F -:1016000003E00008AF8000183C0608008CC64DC4FB -:101610008F8500188F8300203C02080094424DBA49 -:1016200027BDFFE024A5000124630020244200011F -:1016300024C70020AFB10014AFB00010AFBF001836 -:10164000AF850018AF8300203C010800A4224DBAEA -:10165000309000FF3C010800AC274DC404C10008D5 -:101660000000882104E00006000000003C020800A1 -:101670008C424DC0244200013C010800AC224DC008 -:101680003C02080094424DBA3C03080094634DC8E4 -:101690000010202B004310262C420001004410258E -:1016A000144000048F830018240200101462000FFD -:1016B000000000000E000541241100013C03080059 -:1016C00094634DBA3C02080094424DC81462000372 -:1016D000000000000E0004C200000000160000031D -:1016E000000000000E00052B000000003C03080075 -:1016F00094634DBE3C02080094424DBC246300013B -:101700003064FFFF3C010800A4234DBE1482000397 -:10171000000000003C010800A4204DBE120000069D -:10172000000000003C02080094424DBAA74200A20B -:101730000A0005A3022010210E00050F0000000082 -:1017400010400004022010210E00051D00000000C2 -:10175000022010218FBF00188FB100148FB000102D -:1017600003E0000827BD00203084FFFF30A5FFFF05 -:1017700000001821108000070000000030820001E6 -:101780001040000200042042006518210A0005AB49 -:101790000005284003E000080060102110C000068A -:1017A00024C6FFFF8CA2000024A50004AC82000028 -:1017B0000A0005B52484000403E0000800000000CE -:1017C00010A0000824A3FFFFAC860000000000006A -:1017D000000000002402FFFF2463FFFF1462FFFAF1 -:1017E0002484000403E0000800000000240200013B -:1017F000AF62000CA7620010A7620012A76200147B -:1018000003E00008A76200163082007F0342102127 -:101810003C08000E004818213C0208008C420020C1 -:1018200027BDFFD82407FF80AFB3001CAFB200185C -:10183000AFB10014AFB00010AFBF00200080802116 -:1018400030B100FF0087202430D200FF1040002F6D -:1018500000009821AF44002C906200002403005047 -:10186000304200FF1443000E000000003C0208005C -:101870008C4200E00202102100471024AF42002CED -:101880003C0208008C4200E0020210213042007F3E -:101890000342102100481021944200D43053FFFF2E -:1018A0000E00052B000000003C02080094424DBED3 -:1018B0008F8300200011340000C2302500122C005C -:1018C0003C02400000C2302534A50001AC7000008D -:1018D0008FBF0020AC6000048FB20018AC7300080A -:1018E0008FB10014AC60000C8FB3001CAC6500100D -:1018F0008FB00010AC60001424040001AC6000182C -:1019000027BD00280A000550AC66001C8FBF0020D0 -:101910008FB3001C8FB200188FB100148FB000106D -:1019200003E0000827BD00289343010F24020010A4 -:101930001062000E2865001110A00007240200129A -:10194000240200082405003A10620006000030213D -:1019500003E0000800000000240500351462FFFCCD -:10196000000030210A0005D0000000008F42007402 -:1019700024420FA003E00008AF62000C27BDFFE87F -:10198000AFBF00100E000310240500018FBF001030 -:1019900024020001A762001227BD001824020001E2 -:1019A00003E00008A360002227BDFFE0AFB10014F0 -:1019B000AFB00010AFBF001830B1FFFF0E00030240 -:1019C000008080219362003F24030004304200FF26 -:1019D0001443000C02002021122000082402000AF7 -:1019E0000E0005C900000000936200052403FFFEFD -:1019F00000431024A362000524020012A362003FEA -:101A0000020020210E00030BA360008116200003BA -:101A1000020020210E00062D0000000002002021FF -:101A2000322600FF8FBF00188FB100148FB0001056 -:101A3000240500380A0005D027BD002027BDFFE09F -:101A4000AFBF001CAFB20018AFB10014AFB00010B0 -:101A50000E000302008080210E0005C90000000076 -:101A60009362003F24120018305100FF123200032D -:101A70000200202124020012A362003F93620005AD -:101A80002403FFFE004310240E00030BA362000595 -:101A9000020020212405002016320007000030211A -:101AA0008FBF001C8FB200188FB100148FB00010D0 -:101AB0000A00031027BD00208FBF001C8FB2001842 -:101AC0008FB100148FB00010240500390A0005D032 -:101AD00027BD002027BDFFE8AFB00010AFBF001446 -:101AE0009742010C2405003600808021144000102C -:101AF000304600FF0E000302000000002402001226 -:101B0000A362003F93620005344200100E0005C935 -:101B1000A36200050E00030B020020210200202119 -:101B20000E000310240500200A00069C000000009F -:101B30000E0005D0000000000E000302020020216C -:101B4000936200232403FF9F0200202100431024FE -:101B50008FBF00148FB00010A36200230A00030B94 -:101B600027BD001827BDFFE0AFBF0018AFB10014BC -:101B7000AFB0001030B100FF0E00030200808021E2 -:101B8000240200120E0005C9A362003F0E00030BE1 -:101B90000200202102002021022030218FBF0018E6 -:101BA0008FB100148FB00010240500350A0005D055 -:101BB00027BD0020A380002C03E00008A380002D97 -:101BC0008F4202780440FFFE8F820034AF42024011 -:101BD00024020002A34202443C02100003E0000879 -:101BE000AF4202783C0360008C625400304200082F -:101BF0001440FFFD000000008C625408AF82000C0E -:101C000024020052AC605408AC645430AC625434CA -:101C10002402000803E00008AC6254003C026000AB -:101C20008C42540030420008104000053C03600024 -:101C30008C625400304200081440FFFD0000000098 -:101C40008F83000C3C02600003E00008AC435408A2 -:101C500090A3000024020005008040213063003F73 -:101C600000004821146200050000502190A2001CD1 -:101C700094A3001E304900FF306AFFFFAD00000C46 -:101C8000AD000010AD000024950200148D05001C6D -:101C90008D0400183042FFFF00491023000211009C -:101CA000000237C3004038210086202300A2102BF9 -:101CB0000082202300A72823AD05001CAD040018D6 -:101CC000A5090014A5090020A50A001603E00008D4 -:101CD000A50A00228F4201F80440FFFE2402000200 -:101CE000AF4401C0A34201C43C02100003E000085D -:101CF000AF4201F83C0208008C4200B427BDFFE867 -:101D0000AFBF001424420001AFB000103C01080036 -:101D1000AC2200B48F4300243C02001F30AA00FF15 -:101D20003442FF8030D800FF006280240080F82118 -:101D300030EF00FF1158003B01405821240CFF8078 -:101D40003C19000A3163007F000310C000031940F2 -:101D5000006218213C0208008C4200DC256800016A -:101D6000310D007F03E21021004310213043007F3A -:101D700003431821004C102400794821AF4200246D -:101D80008D220024016C1824006C7026AD22000CFA -:101D90008D220024310800FFAD220010952200148E -:101DA000952300208D27001C3042FFFF3063FFFF8A -:101DB0008D2600180043102300021100000227C3E3 -:101DC0000040282100C4302300E2102B00C2302341 -:101DD00000E53823AD27001CAD2600189522002011 -:101DE000A522001495220022154B000AA5220016F8 -:101DF0008D2300248D2200082546000131450080F6 -:101E00001462000430C4007F108F000238AA0080E2 -:101E100000C0502151AF000131C800FF1518FFC9A3 -:101E2000010058218F8400343082007F0342182142 -:101E30003C02000A006218212402FF800082202454 -:101E4000AF440024A06A0079A06A00838C6200502D -:101E50008F840034AC6200708C6500743C027FFF9C -:101E60003442FFFF00A228240E000703AC65007473 -:101E7000AF5000248FBF00148FB0001003E00008A3 -:101E800027BD001827BDFFC0AFBE0038AFB7003474 -:101E9000AFB5002CAFB20020AFB1001CAFB000183E -:101EA000AFBF003CAFB60030AFB40028AFB30024E2 -:101EB0008F4500248F4600288F43002C3C02001FD2 -:101EC0003442FF800062182400C230240080A82120 -:101ED000AFA3001400A2F0240E0006C7AFA60010A6 -:101EE0003C0208008C4200E02410FF80036088213F -:101EF00002A2102100501024AF4200243C0208002E -:101F00008C4200E002A210213042007F03421821DF -:101F10003C02000A00629021924200D29363008446 -:101F2000305700FF306300FF2402000110620034CC -:101F30000360202124020002146200360000000029 -:101F40000E0012AE024028219223008392220083C9 -:101F50003063007F3042007F000210C00003194050 -:101F6000006218213C0208008C4200DC02A2102111 -:101F70000043382100F01024AF4200289225007859 -:101F80009224008330E2007F034218213C02000CBF -:101F900014850007006280212402FFFFA24200F1A5 -:101FA0002402FFFFA64200F20A0007BF2402FFFF3F -:101FB00096020020A24200F196020022A64200F200 -:101FC0008E020024AE4200F492220083A24200F06E -:101FD0008E4200C8AE4200FC8E4200C4AE4200F801 -:101FE0008E220050AE4201008E4200CCAE4201046F -:101FF000922200853042003F0A00081A3442004015 -:102000000E0012D102402821922200850A00081AEF -:102010003042003F936200852403FFDF3042003FDF -:10202000A36200859362008500431024A3620085AB -:102030009363008393620078307400FF304200FFA6 -:1020400010540036240AFF803C0C000C3283007FC1 -:10205000000310C000031940006218213C02080070 -:102060008C4200DC268800013109007F02A2102189 -:102070000043382130E2007F0342182100EA102497 -:10208000AF420028006C80218E020024028A1824AE -:10209000006A5826AE02000C8E020024310800FFB0 -:1020A000AE02001096020014960300208E07001C5A -:1020B0003042FFFF3063FFFF8E06001800431023FD -:1020C00000021100000227C30040282100C4302371 -:1020D00000E2102B00C2302300E53823AE07001CBD -:1020E000AE06001896020020A602001496020022F6 -:1020F000A602001692220079304200FF1054000719 -:102100000000000051370001316800FF9222007882 -:10211000304200FF1448FFCD0100A021922200832D -:10212000A22200798E2200500A00087AAE220070A6 -:10213000A22200858E22004C2405FF80AE42010CB5 -:102140009222008534420020A2220085924200D1D2 -:102150003C0308008C6300DC305400FF3C020800A4 -:102160008C4200E400143140001420C002A3182166 -:1021700000C4202102A21021006438210046102151 -:102180000045182400E52824AF450028AF43002C63 -:102190003042007F924400D030E3007F0342282188 -:1021A000034318213C02000C006280213C02000E17 -:1021B000309600FF00A298211296002A000000002D -:1021C0008E02000C02002021026028211040002510 -:1021D000261000280E0006E2000000009262000DAA -:1021E00026830001307400FF3042007FA262000DA0 -:1021F0002404FF801697FFF0267300203C0208009D -:102200008C4200DC0000A02102A210210044102416 -:10221000AF4200283C0208008C4200E43C03080066 -:102220008C6300DC02A2102100441024AF42002C79 -:102230003C0208008C4200E402A318213063007FB6 -:1022400002A210213042007F0342202103431821C3 -:102250003C02000C006280213C02000E0A00083C97 -:10226000008298218E4200D8AE2200508E4200D8C3 -:10227000AE22007092250083924600D19223008303 -:10228000924400D12402FF8000A228243063007F02 -:10229000308400FF00A628250064182A1060000280 -:1022A00030A500FF38A50080A2250083A225007973 -:1022B0000E0006D5000000009222007E02A0202120 -:1022C000A222007A8E2300743C027FFF3442FFFF7B -:1022D000006218240E000703AE2300748FA20010C2 -:1022E000AF5E00248FBF003CAF4200288FBE003895 -:1022F0008FA200148FB700348FB600308FB5002C3A -:102300008FB400288FB300248FB200208FB1001C3F -:102310008FB0001827BD004003E00008AF42002C3A -:1023200090A2000024420001A0A200003C0308008B -:102330008C6300F4304200FF1443000F0080302112 -:10234000A0A000003C0208008C4200E48F8400340E -:10235000008220213082007F034218213C02000CC1 -:10236000006218212402FF8000822024ACC30000F8 -:1023700003E00008AF4400288C82000024420020C3 -:1023800003E00008AC82000094C200003C08080092 -:10239000950800CA30E7FFFF0080482101021021A4 -:1023A000A4C2000094C200003042FFFF00E2102BE4 -:1023B00054400001A4C7000094A200003C030800A0 -:1023C0008C6300CC24420001A4A2000094A200006F -:1023D0003042FFFF544300078F8600280107102B6F -:1023E000A4A000005440000101003821A4C700004F -:1023F0008F8600288CC4001CAF44003C94A20000CF -:102400008F43003C3042FFFF000210C000621821E1 -:10241000AF43003C8F42003C008220231880000420 -:10242000000000008CC200180A0008DB24420001F2 -:102430008CC20018AF4200383C02005034420010F9 -:10244000AF4200300000000000000000000000006B -:102450008F420000304200201040FFFD00000000CD -:102460008F420404AD2200048F420400AD2200001C -:102470003C020020AF42003003E0000800000000F2 -:1024800027BDFFE0AFB20018AFB10014AFB000102D -:10249000AFBF001C94C2000000C080213C120800A5 -:1024A000965200C624420001A602000096030000D6 -:1024B00094E2000000E03021144300058FB10030A9 -:1024C0000E0008B0024038210A00090D000000008B -:1024D0008C8300048C8200042442004004610007C5 -:1024E000AC8200048C820004044000040000000060 -:1024F0008C82000024420001AC82000096020000A1 -:102500003042FFFF50520001A6000000962200005A -:1025100024420001A62200008F820028962300009A -:1025200094420016144300048FBF001C24020001D3 -:10253000A62200008FBF001C8FB200188FB10014BC -:102540008FB0001003E0000827BD00208F8900280D -:1025500027BDFFE0AFBF00188D22002827480400E8 -:1025600030E700FFAF4200388D22002CAF880030EA -:10257000AF42003C3C020005AF42003000000000CA -:10258000000000000000000000000000000000004B -:10259000000000008C82000C8C82000CAD02000058 -:1025A0008C820010AD0200048C820018AD0200087D -:1025B0008C82001CAD02000C8CA20014AD02001035 -:1025C0008C820020AD02001490820005304200FF92 -:1025D00000021200AD0200188CA20018AD02001C0F -:1025E0008CA2000CAD0200208CA20010AD020024D1 -:1025F0008CA2001CAD0200288CA20020AD02002C91 -:10260000AD060030AD000034978300263402FFFF92 -:1026100014620002006020213404FFFF10E000116A -:10262000AD040038952300369524003624020001BD -:102630003063FFFF000318C2006918219065004055 -:10264000308400070082100400451025A06200407D -:102650008F820028944200563042FFFF0A0009741E -:10266000AD02003C9523003695240036240200017B -:102670003063FFFF000318C2006918219065004015 -:102680003084000700821004000210270045102447 -:10269000A0620040AD00003C00000000000000000F -:1026A000000000003C02000634420040AF4200300F -:1026B0000000000000000000000000008F42000049 -:1026C000304200101040FFFD8F860028AF88003098 -:1026D00024C2005624C7003C24C4002824C500326C -:1026E00024C600360E0008EEAFA200108FBF0018FF -:1026F00003E0000827BD00208F8300243C0608006B -:102700008CC600E88F82003430633FFF00031980DD -:1027100000461021004310212403FF803046007F33 -:1027200000431024AF420028034618213C02000C4D -:102730000062302190C2000D30A500FF000038215A -:1027400034420010A0C2000D8F8900288F8A002417 -:1027500095230036000A138230480003240200014A -:10276000A4C3000E1102000B290200021040000554 -:10277000240200021100000C240300010A0009B821 -:102780000000182111020006000000000A0009B82C -:10279000000018218CC2002C0A0009B82443000153 -:1027A0008CC20014244300018CC200180043102B7B -:1027B00050400009240700012402002714A200034E -:1027C000000000000A0009C4240700019522003E11 -:1027D00024420001A522003E000A13823043000378 -:1027E0002C620002104000090080282114600004BF -:1027F0000000000094C200360A0009D43046FFFFF2 -:102800008CC600380A0009D400802821000030213D -:102810003C04080024844DD80A000921000000006F -:10282000274901008D22000C95230006012020215C -:10283000000216023046003F3063FFFF24020027EB -:1028400000C0282128C7002810C2000EAF83002432 -:1028500010E00008240200312402002110C2000907 -:102860002402002510C200079382002D0A0009F3FC -:102870000000000010C200059382002D0A0009F339 -:10288000000000000A00098C000000000A0006BEDB -:102890000000000095230006912400058D25000C02 -:1028A0008D2600108D2700188D28001C8D290020F2 -:1028B000244200013C010800A4234DDE3C01080035 -:1028C000A0244DDD3C010800AC254DE43C0108008E -:1028D000AC264DE83C010800AC274DF03C01080057 -:1028E000AC284DF43C010800AC294DF803E0000889 -:1028F000A382002D8F87002827BDFFC0AFB300340F -:10290000AFB20030AFB1002CAFB00028AFBF00387D -:102910003C0208008C4200D094E3003030B0FFFF4E -:10292000005010073045FFFF3063FFFF00C09821C3 -:10293000A7A200103C110800963100C614A300069F -:102940003092FFFF8CE2002424420030AF42003C72 -:102950000A000A2C8CE2002094E200323042FFFF91 -:1029600054A2000827A400188CE2002C2442003056 -:10297000AF42003C8CE20028AF4200380A000A3A1D -:102980008F84002827A5001027A6002002203821C8 -:102990000E0008B0A7A000208FA20018244200302B -:1029A000AF4200388FA2001CAF42003C8F84002849 -:1029B0003C020005AF4200309482003427430400FB -:1029C0003042FFFF0202102B14400007AF8300309B -:1029D0009482005494830034020210210043102397 -:1029E0000A000A4E3043FFFF94830054948200345F -:1029F0000223182100501023006218233063FFFFC8 -:102A0000948200163042FFFF1443000300000000D0 -:102A10000A000A5C24030001948200163042FFFF82 -:102A20000043102B104000058F8200309482001666 -:102A3000006210233043FFFF8F820030AC53000050 -:102A4000AC400004AC520008AC43000C3C02000651 -:102A500034420010AF4200300000000000000000CF -:102A6000000000008F420000304200101040FFFDC7 -:102A7000001018C20064182190650040320400075D -:102A8000240200018FBF00388FB300348FB20030B2 -:102A90008FB1002C8FB00028008210040045102553 -:102AA00027BD004003E00008A062004027BDFFA84A -:102AB000AFB60050AFB5004CAFB40048AFB3004460 -:102AC000AFB1003CAFBF0054AFB20040AFB0003870 -:102AD0008C9000003C0208008C4200E88F86003495 -:102AE000960300022413FF8000C2302130633FFFB1 -:102AF0000003198000C3382100F3102490B20000B5 -:102B0000AF42002C9203000230E2007F03423021EA -:102B10003C02000E00C28821306300C02402004045 -:102B20000080A82100A0B021146200260000A0218E -:102B30008E3400388E220018144000022402000156 -:102B4000AE2200189202000D304200201440001501 -:102B50008F8200343C0308008C6300DC001238C014 -:102B6000001231400043102100C7302100463821B7 -:102B700030E300073C02008030E6007800C23025D8 -:102B80000343182100F31024AF4208002463090016 -:102B9000AF4608108E2200188C63000800431021F5 -:102BA000AE2200188E22002C8E2300182442000131 -:102BB0000062182B1060003D000000000A000B109E -:102BC00000000000920300022402FFC00043102412 -:102BD000304200FF1440000524020001AE2200181C -:102BE000962200360A000AF93054FFFF8E220014A4 -:102BF00024420001AE2200189202000000021600DA -:102C000000021603044100290000000096020002A1 -:102C100027A4001000802821A7A200169602000217 -:102C200024070001000030213042FFFFAF82002462 -:102C30000E000921AFA0001C960300023C0408000E -:102C40008C8400E88F82003430633FFF00031980DA -:102C500000441021004310213043007F3C05000C4C -:102C60000053102403431821AF42002800651821A7 -:102C70009062000D001221403042007FA062000DE2 -:102C80003C0308008C6300E48F8200340043102171 -:102C90000044382130E2007F03421021004510211A -:102CA00000F31824AF430028AEA200009222000DCA -:102CB000304200101040001302A020218F83002812 -:102CC0008EA40000028030219462003E2442FFFF67 -:102CD000A462003E948400029625000E3084FFFF1B -:102CE0000E000A0B30A5FFFF8F82002894430034AA -:102CF0009622000E1443000302A0202124020001AA -:102D0000A382002C02C028210E00089600000000BB -:102D10008FBF00548FB600508FB5004C8FB4004861 -:102D20008FB300448FB200408FB1003C8FB00038A9 -:102D300003E0000827BD00588F82002827BDFFD080 -:102D4000AFB40028AFB20020AFBF002CAFB3002457 -:102D5000AFB1001CAFB00018904400D0904300D138 -:102D60000000A021309200FFA3A30010306300FFF9 -:102D70008C5100D88C5300DC1072002B240200010F -:102D80003C0308008C6300E493A400108F8200349D -:102D90002406FF800004214000431021004410213C -:102DA0003043007F00461024AF420028034318211F -:102DB0003C02000C006218218C62000427A400145D -:102DC00027A5001002228021027010230440001564 -:102DD000AFA300149062000D00C21024304200FF27 -:102DE00014400007020088219062000D3442004028 -:102DF0000E000896A062000D0A000B5593A2001069 -:102E00000E000A79241400018F830028AC7000D8CA -:102E100093A20010A06200D193A200101452FFD818 -:102E20000000000024020001168200048FBF002C65 -:102E30000E0006BE000000008FBF002C8FB40028DB -:102E40008FB300248FB200208FB1001C8FB0001808 -:102E500003E0000827BD003027BDFFD8AFB3001C3A -:102E6000AFB20018AFB10014AFB00010AFBF002078 -:102E70000080982100E0802130B1FFFF0E00052B7B -:102E800030D200FF00000000000000000000000041 -:102E90008F820020AC510000AC520004AC530008FB -:102EA000AC40000CAC400010AC400014AC4000182A -:102EB0003C03080094634DBE02038025AC50001C07 -:102EC00000000000000000000000000024040001D9 -:102ED0008FBF00208FB3001C8FB200188FB1001479 -:102EE0008FB000100A00055027BD002827BDFFE85D -:102EF000AFB00010AFBF001430A5FFFF30C600FF19 -:102F00000080802124020C80AF42002400000000D9 -:102F100000000000000000000000000000000000B1 -:102F20000E000B64000000003C040800248400E054 -:102F30008C8200002403FF808FBF00140202102146 -:102F400000431024AF4200248C8200003C03000A9E -:102F5000020280213210007F035010218FB0001038 -:102F60000043102127BD001803E00008AF820028AD -:102F700027BDFFE8AFBF00108F4401403C030800AD -:102F80008C6300E02402FF80AF84003400831821AA -:102F900000621024AF4200243C020008034240219A -:102FA000950500023063007F3C02000A03431821AC -:102FB0000062182130A5FFFF3402FFFF000030211E -:102FC0003C07602010A20006AF8300282402FFFF08 -:102FD000A5020002946500D40E000B8930A5FFFF06 -:102FE0008FBF001024020C8027BD001803E00008EA -:102FF000AF4200243C020008034240219502000237 -:103000003C0A0800954A00C63046FFFF14C000077E -:103010003402FFFF8F8200288F8400343C07602039 -:10302000944500D40A000BF230A5FFFF10C2002423 -:103030008F87002894E2005494E400163045FFFF87 -:1030400000A6102300A6182B3089FFFF1060000493 -:103050003044FFFF00C51023012210233044FFFF3E -:10306000008A102B1040000C012A102324020001BA -:10307000A50200162402FFFFA502000294E500D479 -:103080008F8400340000302130A5FFFF3C07602012 -:103090000A000B89000000000044102A10400008BC -:1030A00000000000950200163042000110400004AC -:1030B000000000009742007E24420014A502001682 -:1030C00003E00008000000008F84002827BDFFE017 -:1030D000AFBF0018948200349483003E1060001A41 -:1030E0003048FFFF9383002C240200011462002764 -:1030F0008FBF00188F820028000818C2310800070F -:10310000006218212447003A244900542444002036 -:10311000244500302446003490620040304200FFD5 -:103120000102100730420001104000168FBF001846 -:103130000E0008EEAFA900108F82002894420034E0 -:103140000A000C0B3048FFFF948300369482003451 -:103150001043000E8FBF001894820036A482003402 -:1031600094820056A48200548C82002CAC820024ED -:1031700094820032A48200309482003CA482003AFF -:103180008FBF00180A000BCB27BD002003E000080A -:1031900027BD002027BDFFE8AFBF00108F4A010008 -:1031A0003C0508008CA500E03C02080090424DE47C -:1031B0003C0C0800958C4DDE01452821304B003F2A -:1031C00030A2007F03424021396900323C02000AEC -:1031D0003963003F2C630001010240212D290001C9 -:1031E0002402FF8000A2282401234825AF8A00344E -:1031F00000801821AF4500240000302100802821E4 -:1032000024070001AF8800283C04080024844DD81E -:10321000AF8C002415200007A380002D240200207D -:103220005562000F006020213402FFFF5582000C20 -:10323000006020212402002015620005000000002B -:103240008C6300142402FFFF1062000700000000DE -:103250000E000921000000000A000C6800000000B8 -:103260000E00098C016028210E000C0000000000F7 -:103270008FBF001024020C8027BD001803E0000857 -:10328000AF4200243C0208008C4200E027BDFFA0B2 -:10329000AFB1003C008210212411FF80AFBE005866 -:1032A000AFB70054AFB20040AFB00038AFBF005C62 -:1032B000AFB60050AFB5004CAFB40048AFB3004458 -:1032C000005110248F4800248F4900288F47002880 -:1032D000AF4200243C0208008C4200E000809021B4 -:1032E00024060006008210213042007F034218218C -:1032F0003C02000A006280213C02001F3442FF8031 -:1033000000E2382427A40010260500F00122F02452 -:103310000102B8240E0005B5AFA700308FA2001837 -:10332000AE0200C48FA2001CAE0200C88FA200240F -:10333000AE0200CC93A40010920300D12402FF80BF -:103340000082102400431025304900FF3083007FA5 -:103350003122007F0062102A10400004000310C0D8 -:1033600001311026304900FF000310C0000319404E -:10337000006218213C0208008C4200DC920400D25A -:10338000024210210043102100511024AF420028B6 -:1033900093A300103063007F000310C000031940A6 -:1033A000006218213C0208008C4200DC024210211D -:1033B000004310213042007F034218213C02000CE0 -:1033C000006240218FA300142402FFFF106200302E -:1033D000309500FF93A2001195030014304400FFC4 -:1033E0003063FFFF0064182B1060000D0000000028 -:1033F000950400148D07001C8D0600183084FFFF13 -:1034000000442023000421000000102100E43821A2 -:1034100000E4202B00C230210A000CE200C430215D -:10342000950400148D07001C8D0600183084FFFFE2 -:1034300000822023000421000000102100801821B8 -:1034400000C2302300E4202B00C4302300E33823E3 -:10345000AD07001CAD06001893A20011A5020014D0 -:1034600097A20012A50200168FA20014AD02001050 -:103470008FA20014AD02000C93A20011A50200203F -:1034800097A20012A50200228FA20014AD02002410 -:103490002406FF80024610243256007FAF420024EB -:1034A000035618213C02000A006280218E02004C63 -:1034B0008FA200203124007F000428C0AE020050FB -:1034C0008FA200200004214000852821AE02007058 -:1034D00093A2001001208821A202008393A2001071 -:1034E000A2020079920200853042003FA2020085CC -:1034F0003C0208008C4200DC0242102100451021F1 -:1035000000461024AF42002C3C0208008C4200E42C -:103510003C0308008C6300DC0242102100441021AF -:1035200000461024AF4200283C0208008C4200E410 -:103530000243182100651821024210210044102185 -:103540003042007F3063007F93A5001003422021AA -:10355000034318213C02000E006240213C02000C93 -:1035600010B1008C008248213233007F16600019B0 -:103570002404FF803C0208008C4200DC024210213F -:1035800000441024AF42002C3C0208008C4200E4AE -:103590003C0308008C6300DC02421021004410242C -:1035A000AF4200283C0208008C4200E4024318218C -:1035B0003063007F024210213042007F034220210D -:1035C000034318213C02000E006240213C02000C23 -:1035D000008248219124000D2414FF800000102156 -:1035E00000942025A124000D9504000295050014E7 -:1035F0008D07001C3084FFFF30A5FFFF8D060018EB -:10360000008520230004210000E4382100C230217D -:1036100000E4202B00C43021AD07001CAD060018CB -:1036200095020002A5020014A50000168D020008F4 -:10363000AD0200108D020008AD02000C95020002E0 -:10364000A5020020A50000228D020008AD02002482 -:103650009122000D3042004010400042262200011D -:103660003C0208008C4200E0A3B300283C10000A92 -:103670000242102100541024AF4200243C020800F2 -:103680008C4200E0A380002C27A4002C02421021D1 -:103690003042007F03421821007018218C6200D84C -:1036A0008D26000427A50028AFA9002C0046102174 -:1036B000AC6200D80E000A79AF83002893A30028DB -:1036C0008F8200280E0006BEA04300D10E000C0021 -:1036D0000000000002541024AF4200243C02080005 -:1036E0008C4200DC00132940001320C000A42021DC -:1036F000024210210044102100541024AF42002C3B -:103700003C0208008C4200E43C0308008C6300DCAF -:10371000035630210242102100451021005410248C -:10372000AF4200283C0208008C4200E4024318210A -:103730000064182102421021004510213042007F10 -:103740003063007F03422021034318213C02000E16 -:10375000006240213C02000C00D080210082482100 -:10376000262200013043007F14750005304400FF1D -:103770002403FF800223102400431026304400FF5E -:1037800093A2001000808821250800281444FF76A9 -:103790002529002093A400108FA300142402FFFF0A -:1037A0001062000A308900FF248200012483000196 -:1037B0003042007F14550005306900FF2403FF806C -:1037C0000083102400431026304900FF9202007845 -:1037D000305300FF11330032012088213C020800E1 -:1037E0008C4200DC3225007F000520C00005294006 -:1037F00000A42021024210212406FF800044102151 -:1038000000461024AF42002C3C0308008C6300DC0F -:103810003C0208008C4200E40243182102421021BD -:103820000045102100641821004610243063007FF9 -:10383000AF420028034318213C02000E00624021E1 -:103840003C0208008C4200E48D06000C010020219F -:1038500002421021004510213042007F034218210E -:103860003C02000C0062482110C0000D01202821FC -:103870000E0006E2000000002402FF80022218244D -:1038800026240001006228263082007F14550002A1 -:10389000308300FF30A300FF1473FFD00060882145 -:1038A0008E0300743C027FFF3442FFFF0062182445 -:1038B000AE0300740E00070302402021AF5700241E -:1038C0008FA20030AF5E00288FBF005C8FBE005813 -:1038D0008FB700548FB600508FB5004C8FB400489E -:1038E0008FB300448FB200408FB1003C8FB00038DE -:1038F00027BD006003E00008AF42002C27BDFFD8C1 -:10390000AFB1001CAFBF0020AFB000182751018835 -:10391000922200032408FF803C03000A3047007F06 -:10392000A3A700108F4601803C0208008C4200E0F3 -:10393000AF86003400C2282100A81024AF42002422 -:103940009224000030A2007F034210210043102186 -:10395000AF8200283084007F2402000214820025F8 -:10396000000719403C0208008C4200E400C210210C -:103970000043282130A2007F0342182100A8102410 -:10398000AF4200283C02000C006218219062000D3A -:10399000AFA3001400481025A062000D8FA30014EF -:1039A0009062000D304200405040006A8FBF0020FE -:1039B0008F860028A380002C27A400148CC200D876 -:1039C0008C63000427A50010004310210E000A7923 -:1039D000ACC200D893A300108F8200280E0006BE50 -:1039E000A04300D10E000C00000000000A000EA34E -:1039F0008FBF00200E0006C700C020210E0006D594 -:103A0000000000003C0200080342802192230001D4 -:103A10009202007B1443004F8FBF002092220000CF -:103A20003044007F24020004108200172882000521 -:103A30001040000624020005240200031082000743 -:103A40008FB1001C0A000EA40000000010820012BA -:103A50008FBF00200A000EA48FB1001C92050083C6 -:103A6000920600788E0700748F84003430A500FF22 -:103A700000073E0230C600FF0E00070B30E7007F54 -:103A80000A000EA38FBF00200E000C6F8F8400343D -:103A90000A000EA38FBF002024020C80AF42002436 -:103AA0009202003E30420040104000200000000022 -:103AB0009202003E000216000002160304410006B6 -:103AC000000000008F8400340E00063824050093A7 -:103AD0000A000EA38FBF00209202003F24030018AB -:103AE000304200FF1443000C8F8400342405003959 -:103AF0000E0005D0000030210E0003028F84003438 -:103B000024020012A202003F0E00030B8F84003437 -:103B10000A000EA38FBF0020240500360E0005D03A -:103B2000000030210A000EA38FBF00200E00030208 -:103B30008F8400349202000534420020A202000566 -:103B40000E00030B8F8400340E0010588F84003455 -:103B50008FBF00208FB1001C8FB0001824020C8092 -:103B600027BD002803E00008AF42002427BDFFE87E -:103B7000AFB00010AFBF00142743010094620008EB -:103B8000000214000002140304410002000080211E -:103B90002410000194620008304200801040001A96 -:103BA00002001021946200083042200010400016EC -:103BB000020010218C6300183C021C2D344219EDC8 -:103BC000240600061062000F3C0760213C0208003A -:103BD0008C4200D4104000078F8200288F83002879 -:103BE000906200623042000F34420040A0620062E6 -:103BF0008F8200288F840034944500D40E000B89F6 -:103C000030A5FFFF020010218FBF00148FB00010FD -:103C100003E0000827BD001827BDFFE0AFB1001486 -:103C2000AFB00010A380002CAFBF00188F4501007B -:103C30003C0308008C6300E02402FF80AF85003461 -:103C400000A318213064007F03442021006218245F -:103C50003C02000A00822021AF43002427500100CB -:103C60008E0200148C8300DCAF84002800431023F4 -:103C700018400004000088218E0200140E000B1C66 -:103C8000AC8200DC9202000B24030002304200FFF1 -:103C90001443002F0000000096020008304300FF8C -:103CA0002402008214620005240200840E0009D65A -:103CB000000000000A000F2F00000000146200093D -:103CC000240200818F8200288F8400343C07602109 -:103CD000944500D49206000530A5FFFF0A000F1E90 -:103CE00030C600FF14620027000000009202000AA4 -:103CF000304300FF3062002010400004306200407A -:103D00008F8400340A000F1A24060040104000047B -:103D1000000316008F8400340A000F1A24060041A5 -:103D200000021603044100178F8400342406004269 -:103D30008F8200283C076019944500D430A5FFFF0E -:103D40000E000B89000000000A000F2F0000000089 -:103D50009202000B24030016304200FF10430006BD -:103D6000000000009202000B24030017304200FF05 -:103D700014430004000000000E000EA90000000023 -:103D8000004088210E000C00000000009202000A92 -:103D9000304200081040000624020C808F85002865 -:103DA0003C0400080E0012860344202124020C80EB -:103DB000AF4200248FBF0018022010218FB00010E6 -:103DC0008FB1001403E0000827BD002027BDFFE8E5 -:103DD000AFBF0014AFB000108F5000243C030800A8 -:103DE0008C6300E08F4501002402FF8000A31821AE -:103DF0003064007F03442021006218243C02000A42 -:103E000000822021AF850034AF43002490820062FD -:103E1000AF8400283042000F34420050A08200627C -:103E20003C02001F3442FF800E0006BE02028024C6 -:103E3000AF5000248FBF00148FB0001003E00008C3 -:103E400027BD00183C0208008C4200201040001DD5 -:103E50002745010090A300093C02000803422021ED -:103E600024020018546200033C0200080A000F708C -:103E700024020008034220212402001614620005D7 -:103E80002402001724020012A082003F0A000F7AC9 -:103E900094A700085462000694A7000893620005E6 -:103EA0002403FFFE00431024A362000594A700082A -:103EB00090A6001B8CA4000094A500060A000B64C9 -:103EC00000073C0003E00008000000002744010058 -:103ED00094820008304500FF38A3008238A2008495 -:103EE0002C6300012C4200010062182510600006BE -:103EF000240200839382002D1040000D000000007A -:103F00000A000C330000000014A2000524A2FF8068 -:103F10008F4301043C02602003E00008AC4300141E -:103F2000304200FF2C420002104000032402002215 -:103F30000A000ED40000000014A2000300000000DC -:103F40000A000F41000000000A000F5F000000009F -:103F50009363007E9362007A1443000900002021DD -:103F60009362000024030050304200FF1443000419 -:103F7000240400019362007E24420001A362007EBB -:103F800003E00008008010218F4201F80440FFFE8A -:103F900024020002AF4401C0A34201C43C0210004D -:103FA00003E00008AF4201F827BDFFE8AFBF0010F3 -:103FB0009362003F2403000A304200FF144300468E -:103FC000000000008F6300548F62004C1062007D7F -:103FD000036030219362000024030050304200FF50 -:103FE0001443002F000000008F4401403C020800F1 -:103FF0008C4200E02403FF80008210210043102443 -:10400000AF4200243C0208008C4200E08F6500545F -:104010003C03000A008220213084007F03441021E9 -:1040200000431021AC4501089762003C8F63004CAF -:104030003042FFFF0002104000621821AF63005CB5 -:104040008F6300548F64004C9762003C0064182317 -:104050003042FFFF00031843000210400043102AC3 -:1040600010400006000000008F6200548F63004C77 -:10407000004310230A000FF0000210439762003C37 -:104080003042FFFF00021040ACC200642402000175 -:10409000A0C0007CA0C2008424020C80AF42002497 -:1040A0000E000FA28F440140104000478FBF001048 -:1040B0008F4301408F4201F80440FFFE24020002BA -:1040C000AF4301C0A34201C43C021000AF4201F85B -:1040D0000A0010408FBF00109362003F24030010BD -:1040E000304200FF14430004000000008F440140F0 -:1040F0000A00102C000028219362003F24030016C0 -:10410000304200FF1443000424020014A362003F65 -:104110000A00103A000000008F62004C8F630050CC -:1041200000431023044100288FBF001093620081D8 -:1041300024420001A3620081936200812C420004AA -:1041400014400010000000009362003F24030004AC -:10415000304200FF14430006000000008F4401407D -:104160008FBF0010240500930A00063827BD0018F1 -:104170008F440140240500938FBF00100A0006A75A -:1041800027BD00188F4401400E000302000000000C -:104190008F6200542442FFFFAF6200548F620050D0 -:1041A0002442FFFFAF6200500E00030B8F4401401A -:1041B0008F4401408FBF0010240500040A00031043 -:1041C00027BD00188FBF001003E0000827BD0018AE -:1041D0008F4201889363007E00021402304400FF86 -:1041E000306300FF1464000D000000009362008043 -:1041F000304200FF1044000900000000A36400806A -:104200009362000024030050304200FF1443000476 -:10421000000000000A00076F8F440180A364008043 -:1042200003E000080000000027BDFFE8AFB0001069 -:10423000AFBF001493620005240300303042003009 -:1042400014430089008080213C0208008C42002039 -:1042500010400080020020210E00052B000000000D -:104260008F850020ACB000009362003E9363003F56 -:10427000304200FF00021200306300FF00431025AF -:10428000ACA2000493620082000216000002160332 -:1042900004410005000000003C0308008C63004856 -:1042A0000A00107E000000009362003E3042004091 -:1042B000144000030000182193620081304300FF86 -:1042C0009362008200031E00304200FF00021400CF -:1042D00000621825ACA300088F620040ACA2000C5D -:1042E0008F620048ACA200108F62004CACA2001498 -:1042F0008F6200508F63004C004310230441000381 -:10430000000000000A0010928F62004C8F62005083 -:10431000ACA200183C02080094424DBE3C03C00B06 -:1043200000002021004310250E000550ACA2001C07 -:104330008F6200548F840020AC8200008F6200588E -:10434000AC8200048F62005CAC8200088F62006067 -:104350008F43007400431021AC82000C8F62006414 -:10436000AC820010976300689762006A00031C002B -:104370003042FFFF00621825AC8300149362008274 -:1043800024030080304200FF1443000300000000BB -:104390000A0010C6AC8000188F63000C24020001D4 -:1043A0001062000E2402FFFF9362003E3042004084 -:1043B0001440000A2402FFFF8F63000C8F42007438 -:1043C000006218233C02080000621024144000021E -:1043D000000028210060282100051043AC8200184D -:1043E0003C02080094424DBE3C03C00C000020215A -:1043F000004310258F8300200E000550AC62001C86 -:104400008F6200188F8300203C05080094A54DBEE4 -:1044100024040001AC620000AC6000048F66006CF4 -:104420003C02400D00A22825AC6600088F6200DC2B -:10443000AC62000CAC600010936200050002160034 -:10444000AC620014AC6000180E000550AC65001C96 -:10445000020020218FBF00148FB00010A360000560 -:104460000A0004B927BD00188FBF00148FB00010D8 -:1044700003E0000827BD00189742007C30C600FF0B -:10448000A08600843047FFFF2402000514C2000B01 -:1044900024E3465090A201122C420007104000076E -:1044A00024E30A0090A30112240200140062100405 -:1044B00000E210210A0010FE3047FFFF3067FFFFC7 -:1044C00003E00008A4870014AC87004C8CA201080C -:1044D0000080402100A0482100E2102330C600FFE8 -:1044E0001840000393AA001324E2FFFCACA20108C9 -:1044F00030C2000110400008000000008D02005092 -:1045000000E2102304410013240600058D0200542C -:1045100010E20010000000008D02005414E2001AA6 -:10452000000000003C0208008C4200D8304200200D -:104530001040000A240200019103007891020083D8 -:10454000144300062402000101002021012028213B -:10455000240600040A0010EC00000000A100008402 -:1045600011400009A50200148F4301008F4201F899 -:104570000440FFFE24020002AF4301C0A34201C475 -:104580003C021000AF4201F803E000080000000008 -:1045900027BDFFE88FA90028AFBF00100080402191 -:1045A00000E918231860007330C600FFA080007C6B -:1045B000A08000818CA2010800E210230440004D7D -:1045C000000000008C8200509483003C8C840064C6 -:1045D000004748233063FFFF012318210083202B6D -:1045E00010800004000000008D0200640A00114FDA -:1045F00000E210219502003C3042FFFF0122102111 -:1046000000E21021AD02005C9502003C8D03005CCD -:104610003042FFFF0002104000E210210043102B47 -:1046200010400003000000000A00115E8D02005CD3 -:104630009502003C3042FFFF0002104000E21021D2 -:10464000AD02005CA1000084AD07004C8CA2010803 -:1046500000E210231840000224E2FFFCACA2010893 -:1046600030C200011040000A000000008D0200501E -:1046700000E2102304410004010020218D020054B7 -:1046800014E20003000000000A0011802406000567 -:104690008D02005414E200478FBF00103C02080056 -:1046A0008C4200D8304200201040000A2402000151 -:1046B0009103007891020083144300062402000154 -:1046C00001002021240600048FBF00100A0010EC16 -:1046D00027BD0018A1000084A50200148F4301002B -:1046E0008F4201F80440FFFE240200020A0011A5D7 -:1046F000000000008C82005C004910230043102B56 -:1047000054400001AC87005C9502003C3042FFFF42 -:104710000062102B14400007240200029502003CA6 -:104720008D03005C3042FFFF00621821AD03005C86 -:1047300024020002AD07004CA10200840E000FA26B -:104740008F4401001040001B8FBF00108F430100F9 -:104750008F4201F80440FFFE24020002AF4301C073 -:10476000A34201C43C021000AF4201F80A0011BB91 -:104770008FBF001030C200101040000E8FBF00101D -:104780008C83005C9482003C006918233042FFFF58 -:10479000006218213C023FFF3444FFFF0083102BCE -:1047A000544000010080182101231021AD02005C5B -:1047B0008FBF001003E0000827BD001827BDFFE8E9 -:1047C0008FAA0028AFBF00100080402100EA4823D4 -:1047D0001920002130C600FF8C83005C8C820064AD -:1047E000006A18230043102B504000100069182164 -:1047F00094A2011001221021A4A2011094A2011080 -:104800003042FFFF0043102B1440000A3C023FFFE0 -:1048100094A2011000431023A4A201109482003C32 -:104820003042FFFF0A0011DA00621821A4A0011033 -:104830003C023FFF3444FFFF0083102B5440000133 -:104840000080182100671021AD02005CA100007CEF -:104850000A001222A100008130C200101040003C6A -:10486000000000008C820050004A102318400038DD -:10487000000000009082007C24420001A082007CA5 -:104880009082007C3C0308008C630024304200FFCF -:104890000043102B1440005C8FBF00108CA2010855 -:1048A00000E2102318400058000000008C830054E0 -:1048B0009482003C006A18233042FFFF0003184333 -:1048C000000210400043102A1040000500000000C4 -:1048D0008C820054004A10230A001209000210437F -:1048E0009482003C3042FFFF00021040AD020064A1 -:1048F0009502003C8D0400649503003C3042FFFFAC -:1049000000021040008220213063FFFF0083182145 -:1049100001431021AD02005C8D020054ACA20108DD -:1049200024020002A10200840E000FA28F440100A5 -:10493000104000358FBF00108F4301008F4201F8F7 -:104940000440FFFE240200020A00124B0000000097 -:10495000AD07004C8CA2010800E2102318400002B1 -:1049600024E2FFFCACA2010830C200011040000AA2 -:10497000000000008D02005000E2102304410004FA -:10498000010020218D02005414E200030000000009 -:104990000A001242240600058D02005414E2001A97 -:1049A0008FBF00103C0208008C4200D8304200202B -:1049B0001040000A24020001910300789102008354 -:1049C00014430006240200010100202124060004F3 -:1049D0008FBF00100A0010EC27BD0018A100008452 -:1049E000A50200148F4301008F4201F80440FFFE2E -:1049F00024020002AF4301C0A34201C43C021000E4 -:104A0000AF4201F88FBF001003E0000827BD001877 -:104A10008FAA00108C8200500080402130C600FF19 -:104A2000004A102300A048211840000700E0182188 -:104A300024020001A0800084A0A00112A48200141E -:104A40000A0011BDAFAA0010A0800081AD07004C84 -:104A50008CA2010800E210231840000224E2FFFCAF -:104A6000ACA2010830C200011040000800000000A4 -:104A70008D0200500062102304410013240600053B -:104A80008D02005410620010000000008D020054DE -:104A900014620011000000003C0208008C4200D8A3 -:104AA000304200201040000A2402000191030078E7 -:104AB000910200831443000624020001010020211A -:104AC00001202821240600040A0010EC0000000048 -:104AD000A1000084A502001403E00008000000000B -:104AE00027BDFFE0AFBF0018274201009046000A33 -:104AF0008C4800148C8B004C9082008430C900FFDD -:104B000001681823304A00FF1C60001A2D46000679 -:104B1000240200010142100410C0001630430003BB -:104B2000012030210100382114600007304C000CB6 -:104B300015800009304200301440000B8FBF001870 -:104B40000A0012AC000000000E0011BDAFAB001057 -:104B50000A0012AC8FBF00180E001132AFAB00106C -:104B60000A0012AC8FBF0018AFAB00100E0012523B -:104B7000AFAA00148FBF001803E0000827BD002073 -:104B800024020003A08200848C82005403E0000809 -:104B9000ACA201083C020008034218219062008187 -:104BA000240600433C07601924420001A0620081F2 -:104BB000906300813C0208008C4200C0306300FF1B -:104BC000146200102403FF803C0208008C4200E0C5 -:104BD0000082102100431024AF4200243C02080050 -:104BE0008C4200E03C03000A008210213042007F2A -:104BF0000342102100431021944500D40A000B8980 -:104C000030A5FFFF03E000080000000027BDFFE023 -:104C1000AFBF0018AFB10014AFB000108F420180D9 -:104C20000080802100A088210E0012B300402021C6 -:104C3000A20000848E0200548FBF00188FB00010B5 -:104C4000AE2201088FB1001403E0000827BD002048 -:104C500027BDFFE03C020008AFB00010AFBF001856 -:104C6000AFB10014034280218F51014092030084B0 -:104C70008E0400508E02004C14820040306600FF0B -:104C80003C0208008C4200E02403FF800222102135 -:104C900000431024AF4200243C0208008C4200E094 -:104CA0009744007C92050081022210213042007F4F -:104CB000034218213C02000A0062182114A0000BD4 -:104CC0003084FFFF2402000554C20014248205DC56 -:104CD0009062011224420001A062011224020C80A1 -:104CE000AF4200240A00130B24020005A060011249 -:104CF0002402000514C20009248205DC920200810E -:104D00002C4200075040000524820A0092030081D3 -:104D10002402001400621004008210213044FFFFBE -:104D2000A60400140E0012B3022020219602003CBB -:104D30008E03004C022020213042FFFF0002104071 -:104D4000006218210E000302AE03005C9202007D97 -:104D500002202021344200400E00030BA202007DFD -:104D60008F4201F80440FFFE24020002AF5101C04F -:104D7000A34201C43C021000AF4201F88FBF0018EB -:104D80008FB100148FB0001003E0000827BD002091 -:104D900008000D9808000DE008000E2008000E6CB9 -:044DA00008000EA059 -:0C4DA4000A0000220000000000000000D7 -:104DB0000000000D6370352E302E306A3600000082 -:104DC00005000004000000000000000000000000DA -:104DD00000000000000000000000000000000000D3 -:104DE00000000000000000000000000000000020A3 -:104DF00000000000000000000000000000000000B3 -:104E000000000000000000000000000000000000A2 -:104E10000000000000000000000000000000000191 -:104E20000000002B00000000000000000000000057 -:104E300010000003000000000000000D0000000D45 -:104E40003C02080024425AC43C03080024636190D9 -:104E5000AC4000000043202B1480FFFD24420004DE -:104E60003C1D080037BD7FFC03A0F0213C1008006A -:104E7000261000883C1C0800279C5AC40E0001A67E -:104E8000000000000000000D27BDFFE83C0960188D -:104E9000AFBF00108D2C5000240DFF7F240800317F -:104EA000018D5824356A380C24070C003C1A800008 -:104EB000AD2A50003C04800AAF4800083C1B800823 -:104EC000AF4700240E000935AF8400100E0008F82B -:104ED000000000000E000845000000000E0012DC7B -:104EE000000000003C0460168C8500003C06FFFFBB -:104EF0003C02535300A618241062004734867C00FD -:104F000094C201F2A780002C10400003A78000CCBF -:104F100038581E1EA798002C94C201F810400004B7 -:104F2000978300CC38591E1EA79900CC978300CCDC -:104F30002C7F006753E00001240300669784002C57 -:104F40002C82040114400002006028212404040083 -:104F50003C0760008CE904382403103C3128FFFF33 -:104F60001103001F30B9FFFF57200010A38000CEAF -:104F700024020050A38200CE939F00CE53E0000F86 -:104F8000A78500CCA78000CC978500CC8FBF0010F0 -:104F9000A780002CA7800034A78000E63C01080011 -:104FA000AC25008003E0000827BD0018939F00CEC9 -:104FB00057E0FFF5A78000CCA78500CC978500CCF3 -:104FC0008FBF0010A784002CA7800034A78000E6C4 -:104FD0003C010800AC25008003E0000827BD001854 -:104FE000A38000CE8CCB003C316A00011140000E42 -:104FF0000000000030A7FFFF10E0FFDE2402005099 -:105000008CCC00C83186000114C0FFDC939F00CE19 -:105010000A000074240200518C8F00043C0E6000D2 -:105020000A00005701EE30218CEF0808240D5708C4 -:10503000000F740211CD000430B8FFFF2405006694 -:105040000A000075240404001700FFCC939F00CED3 -:105050000A000074240200508F8600103089FFFF80 -:10506000000939408CC300103C08005000E820259E -:10507000AF4300388CC5001427420400AF82001CE7 -:10508000AF45003CAF4400300000000000000000CD -:105090000000000000000000000000000000000010 -:1050A00000000000000000008F4B0000316A00206B -:1050B0001140FFFD0000000003E0000800000000B8 -:1050C0008F840010948A001A8C8700243149FFFFD6 -:1050D000000940C000E83021AF46003C8C85002428 -:1050E0008F43003C00A3102318400029000000005B -:1050F0008C8B0020256200013C0D005035AC00086F -:10510000AF420038AF4C003000000000000000004B -:10511000000000000000000000000000000000008F -:1051200000000000000000008F4F000031EE002062 -:1051300011C0FFFD000000008F4A04003C08002061 -:10514000AC8A00108F490404AC890014AF480030C9 -:1051500000000000948600189487001C00C71821E6 -:10516000A48300189485001A24A20001A482001AC6 -:105170009498001A9499001E133800030000000050 -:1051800003E000080000000003E00008A480001A0B -:105190008C8200200A0000D63C0D00500A0000C797 -:1051A000000000003C0308008C6300208F82001880 -:1051B00027BDFFE810620008AFBF00100E0000FE20 -:1051C000AF8300183C0308008C6300202404000116 -:1051D000106400048F8900108FBF001003E00008E6 -:1051E00027BD00188FBF00103C076012A520000AE1 -:1051F0009528000A34E5001027BD00183106FFFF8E -:1052000003E00008ACA600903C0208008C4200209D -:1052100027BDFFC8AFBF0034AFBE0030AFB7002C12 -:10522000AFB60028AFB50024AFB40020AFB3001C68 -:10523000AFB20018AFB1001410400050AFB0001072 -:105240008F840010948600069483000A00C32823EC -:1052500030B6FFFF12C0004A8FBF00349489001897 -:10526000948A000A012A40233102FFFF02C2382B30 -:1052700014E0000202C02021004020212C8C0005F7 -:10528000158000020080A021241400040E0000AD4F -:10529000028020218F87001002809821AF800014A7 -:1052A00094ED000A028088211280004E31B2FFFF87 -:1052B0003C1770003C1540003C1E60008F8F001CA6 -:1052C0008DEE000001D718245075005002202021D7 -:1052D00002A3802B160000353C18200050780047B0 -:1052E00002202021241000018F8300141460003953 -:1052F000029158230230F8230250C82133F1FFFFF6 -:105300001620FFEE3332FFFF8F8700103C11002084 -:10531000AF5100300000000094E6000A3C1E60120D -:1053200037D5001002662821A4E5000A94E2000A9D -:1053300094F2000A94F400183057FFFF1292003BD9 -:10534000AEB700908CED00148CE400100013714097 -:1053500001AE4021000E5FC3010E502B008B48218F -:10536000012A1821ACE80014ACE3001002D3382362 -:1053700030F6FFFF16C0FFB98F8400108FBF0034D6 -:105380008FBE00308FB7002C8FB600288FB5002459 -:105390008FB400208FB3001C8FB200188FB100149F -:1053A0008FB0001003E0000827BD0038107E001BFE -:1053B000000000001477FFCC241000010E00162717 -:1053C000000000008F8300141060FFCB0230F82330 -:1053D000029158238F870010017020210A0001914B -:1053E0003093FFFF8F8300141460FFCB3C1100202B -:1053F000AF5100300A00015D000000000E00079E62 -:10540000024028210A000151004080210E00034B78 -:10541000024028210A000151004080210E0014EFB3 -:10542000022020210A000151004080210E0000C707 -:10543000000000000A00017302D3382327BDFFE8F3 -:10544000AFB00010AFBF00140E0000390000000024 -:105450003C028000345000700A0001B48E06000047 -:105460008F4F000039EE000131C2000110400024CE -:105470008F8600A88E0700003C0C08008D8C003C35 -:105480003C0908008D29003800E66823018D282199 -:105490000000502100AD302B012A402101062021BF -:1054A0003C010800AC25003CAF8700A83C01080087 -:1054B000AC2400380E000100000000003C0308008E -:1054C0008C6300701060FFE6006020213C0508003E -:1054D0008CA500683C0608008CC6006C0E0015B652 -:1054E000000000003C010800AC2000708F4F00005D -:1054F00039EE000131C200011440FFDE8F8600A8A2 -:105500008E0A00008F8B00A83C0508008CA5003C8B -:105510003C0408008C840038014B482300A9382142 -:105520000082182100E9402B006810213C0108008E -:10553000AC27003C3C010800AC2200388F5F010022 -:105540002419FF0024180C0003F9202410980012DD -:10555000AF840000AF440020936D0000240C0020B5 -:1055600031A600FF10CC0012240E005010CE000413 -:105570003C194000AF5901380A0001AD000000009D -:105580000E001252000000003C194000AF590138D3 -:105590000A0001AD000000000E000119000000002B -:1055A0003C194000AF5901380A0001AD000000006D -:1055B0008F58010000802821330F00FF01E02021D7 -:1055C0000E0002F8AF8F00043C194000AF590138BB -:1055D0000A0001AD0000000000A4102B240300010C -:1055E00010400009000030210005284000A4102BC5 -:1055F00004A00003000318405440FFFC00052840AD -:105600005060000A0004182B0085382B54E0000479 -:105610000003184200C330250085202300031842F0 -:105620001460FFF9000528420004182B03E000086D -:1056300000C310213084FFFF30A5FFFF8F4201B867 -:105640000440FFFE3C074080008730253C031000EB -:10565000AF400180AF450184AF46018803E00008F8 -:10566000AF4301B83084FFFF8F4201B80440FFFE12 -:105670003C0740388CA60000008728253C0310001A -:10568000AF460180AF45018803E00008AF4301B891 -:105690008F8300388F8600301066000B0080402119 -:1056A0003C07080024E75C38000328C000A710214D -:1056B0008C44000024630001108800053063000F53 -:1056C0005466FFFA000328C003E000080000102120 -:1056D0003C07080024E75C3C00A7302103E00008F9 -:1056E0008CC200003C03900034620001008220253F -:1056F000AF4400208F45002004A0FFFE0000000002 -:1057000003E00008000000003C0380003462000158 -:105710000082202503E00008AF44002027BDFFE001 -:10572000AFB100143091FFFFAFB00010AFBF001851 -:105730001220001500A080218CA5000010A00013ED -:10574000240400020E000C7C24060140AE00000080 -:105750008F4201B80440000D000028213C064000A3 -:10576000022620258FBF00188FB100148FB00010C3 -:105770003C03100027BD0020AF450180AF440188E5 -:1057800003E00008AF4301B88CA500008F4201B8C8 -:105790000440FFFE3C064000022620258FBF001873 -:1057A0008FB100148FB000103C03100027BD002003 -:1057B000AF450180AF44018803E00008AF4301B862 -:1057C0003086FFFF8F4201B80440FFFE3C094006CF -:1057D0008CA8000000C93825AF4801808CA40004C3 -:1057E0003C031000AF440184AF47018803E0000888 -:1057F000AF4301B827BDFFE0AFB00010AFBF001846 -:10580000AFB100149363003E008080210080282106 -:1058100030620040000020211040000F8E11000077 -:105820000E0008710220202193670000240400501C -:1058300030E500FF50A400128E0F0000022020214E -:105840008FBF00188FB100148FB00010A762013C09 -:105850000A00093127BD00200E0002870000000069 -:105860000E000871022020219367000024040050DC -:1058700030E500FF14A4FFF2022020218E0F00006B -:105880003C1008008E1000503C0D000C240BFF80D3 -:1058900001F05021314E007F01DA6021018D40215D -:1058A000014B4824AF490028022020218FBF001857 -:1058B0008FB100148FB00010A50200D627BD0020C4 -:1058C0000A000931AF8800D027BDFFE0AFBF001844 -:1058D000AFB10014AFB000109366000100808021CA -:1058E0000E00025030D1000493640005001029C25C -:1058F000A765000034830040A36300050E00025931 -:10590000020020210E0009330200202124020001A0 -:10591000AF62000C02002821A762001024040002DC -:10592000A762001224060140A76200140E000C7C3E -:10593000A76200161620000F8FBF0018978C003446 -:105940003C0B08008D6B00782588FFFF3109FFFFB5 -:10595000256A0001012A382B10E00006A7880034D0 -:105960003C0F6006240E001635ED0010ADAE005061 -:105970008FBF00188FB100148FB0001003E0000833 -:1059800027BD002027BDFFE0AFB10014AFBF001856 -:10599000AFB0001000A088211080000A3C03600016 -:1059A0002402008010820012000000000000000DA0 -:1059B0008FBF00188FB100148FB0001003E00008F3 -:1059C00027BD00208C682BF80500FFFE00000000BA -:1059D000AC712BC08FBF00188FB100148FB00010B6 -:1059E0003C09100027BD002003E00008AC692BF83B -:1059F0000E00025000A02021936500050220202106 -:105A00000E00025930B000FF2403003E1603FFE7EA -:105A1000000000008F4401780480FFFE2407000787 -:105A20003C061000AF51014002202021A347014451 -:105A30008FBF00188FB100148FB00010AF460178EF -:105A40000A0002C927BD002027BDFFE8AFBF001430 -:105A5000AFB000108F500020000000000E0009338E -:105A6000AF440020AF5000208FBF00148FB0001053 -:105A700003E0000827BD00183084FFFF8F4201B803 -:105A80000440FFFE3C074035008730253C031000F2 -:105A9000AF450180AF400184AF46018803E00008B4 -:105AA000AF4301B83084FFFF8F4201B80440FFFECE -:105AB0003C074036008730253C031000AF4501808D -:105AC000AF400184AF46018803E00008AF4301B84E -:105AD00027BDFFD0AFB3001C3093FFFFAFB500244C -:105AE000AFB20018AFBF0028AFB40020AFB10014B0 -:105AF000AFB0001030B5FFFF12600027000090210A -:105B00008F90001C8E0300003C06800024020040A1 -:105B100000033E0200032C0230E4007F006688246C -:105B20001482001D30A500FF8F8300282C68000A16 -:105B3000510000108F910014000358803C0C0800A5 -:105B4000258C58C4016C50218D49000001200008AB -:105B50000000000002B218213065FFFF0E00022491 -:105B600024040084162000028F90001CAF800028BF -:105B70008F910014260C0020264B0001018080210B -:105B80003172FFFF16200004AF8C001C0253282B3B -:105B900014A0FFDC00000000024010218FBF00288D -:105BA0008FB500248FB400208FB3001C8FB2001873 -:105BB0008FB100148FB0001003E0000827BD003043 -:105BC000240D003414AD00F600000000920B000E0E -:105BD000240A16803C07000CA36B00219203000DE1 -:105BE0000347F8213C066000A363002096110012D1 -:105BF0003C057FFF34ACFFFFA771003C960200100C -:105C0000240B00053054FFFFAF7400848E19001C74 -:105C1000AF4A00288FF800008CCF44480319702643 -:105C200001EE3021AF66004C8F69004C24CD00019D -:105C30003C197F00AF6900508F640050AF6400547E -:105C4000AF660070AF6D00588F6800582404005094 -:105C5000AF68005CA3600023AF6C0064A36B0037E7 -:105C60008E030014AF6300488F710048AF710024A9 -:105C70008E020018AF62006C9214000CA374003600 -:105C8000936A003E355F0020A37F003E8F7800744A -:105C90000319782435EE4000AF6E0074936900005C -:105CA000313000FF1204022C2418FF803C0408004D -:105CB00024845CB80E000294000000002406000456 -:105CC000240700013C0408008C845CB8A366007DB6 -:105CD000A36700058F4A01780540FFFE24020002F9 -:105CE000AF440140A34201448F90001C3C141000BB -:105CF000AF5401780A000373AF8000282CAD003741 -:105D000051A0FF9C8F9100140005A0803C18080052 -:105D1000271858EC029878218DEE000001C0000889 -:105D2000000000002406000614A600110000000078 -:105D30003C1F08008FFF5CB824040005AF5F002003 -:105D40008E190018AF7900188F78004CAF78001CBE -:105D50008F6F0050122000C2AF6F00700A000373F3 -:105D6000AF840028240A000710AA00842403000638 -:105D70003C05080024A55CB80E00025E24040081E6 -:105D80008F90001C0011102B0A000373AF820028B3 -:105D90002402000414A2FFF6240A00503C09080063 -:105DA0008D295CB8AF4900208E040008AF64004024 -:105DB0008E060008AF6600448E07000CAF670048EF -:105DC0008E0D0010AF6D004C8E080010AF6800847F -:105DD0008E050014AF6500508E0C0018AF6C005497 -:105DE0008E0B001CAF6B005893740000328300FFD1 -:105DF000106A01EE000000008F6700488F660040C7 -:105E000000E6682305A000042404008C1620FFDEB1 -:105E100024020003240400823C05080024A55CB889 -:105E20000E000287000000008F90001C000010216F -:105E30000A000373AF8200282404000514A4FFCCD9 -:105E4000240520003C1F08008FFF5CB8AF5F0020D6 -:105E50008E190004AF79005C921800082410000825 -:105E6000A37800218F8F001C91EE0009A36E002003 -:105E70008F86001C90C9000A312400FF109000108A -:105E8000288A00091540006C24020002240C00201E -:105E9000108C000B340580002885002114A0000818 -:105EA0002405400024080040108800053C0500013E -:105EB000240D0080108D00023C05000224054000E6 -:105EC0008F6E00743C0FFF0001CF48240125802510 -:105ED000AF70007490C4000BA36400818F84001C19 -:105EE0009487000C10E0019400000000948E000CD8 -:105EF000241FFFBF24060004A76E003C9089000EFB -:105F0000A369003E8F90001C9204000FA364003F21 -:105F10008F94001C8E8D00108F47007401A74023C2 -:105F2000AF6800608E850014AF650064968C001821 -:105F3000A76C0068968B001AA76B006A8E83001C02 -:105F4000AF63006C96820002A762013E928A000E47 -:105F5000A36A003E9379003E033FC02412200167EC -:105F6000A378003E8F90001C0A000373AF860028C0 -:105F70002414002214B4FF7E240300073C0208000E -:105F80008C425CB81220000CAF4200200A00037360 -:105F9000AF830028240C003310AC00142405002823 -:105FA0003C05080024A55CB80E00023024040081E2 -:105FB0000A0003F88F90001C3C04080024845CB89D -:105FC0000E00029400000000936B000024110050AA -:105FD000316300FF10710151000000008F90001C20 -:105FE000000018210A000373AF8300283C08080052 -:105FF0008D085CB824040081AF480020A3650034FC -:106000003C05080024A55CB80E000230000000002A -:106010008F90001C240200090A000373AF8200283D -:1060200002B288213225FFFF0E00022424040084DE -:106030000A0003738F90001C1082FFA12405040046 -:10604000288300031060016F240B00042414000156 -:106050005494FF9B240540000A00044724050100D6 -:106060003C04080024845CB88F62004C0E0002944B -:106070008F6300508F90001C000020210A000373E2 -:10608000AF8400288E1000042404008AAF50002042 -:10609000936E000531C900021520015E020028211F -:1060A0009378002302002821330F002015E00159C6 -:1060B0002404008D9362003F24190012305F00FF1A -:1060C00013F90154240400810E0002500200202123 -:1060D00093740023240A0004020020213683004226 -:1060E000A36300230E000259A36A007D8F4B017841 -:1060F0000560FFFE24050002AF500140A3450144A6 -:106100008F90001C3C0C1000AF4C01780A0003F982 -:106110000011102B8E1000042404008AAF500020C0 -:10612000936D000531A80002150000160200282119 -:106130009364003F2407000402002821308600FFFA -:1061400010C70010240400810E000250020020211C -:10615000937F002324180012240FFFFE37F900203C -:10616000A3790023A378003F936E0005020020214D -:1061700001CF48240E000259A3690005020028211E -:10618000000020210E000340000000000A0003F878 -:106190008F90001C8E0500043C0F0008034F402127 -:1061A000AF450020910E00002406005031C900FFC9 -:1061B00011260176240400888F5901B80720FFFEBC -:1061C0003C0C400E008C58253C031000AF4501806C -:1061D000AF400184AF4B0188AF4301B8910200008A -:1061E000240AFF8024040004004AF825A11F0000AF -:1061F0000E000C7C240600300A0003F88F90001C6F -:106200008E0F00043C14080026945CB83C01080082 -:10621000AC2F5CB8AF4F0020920E000331C90004D0 -:10622000112000022402001224020006A362003F93 -:106230009203001B240AFFC03062003F004AF82589 -:10624000A37F003E92190003333800011700011CA0 -:10625000000000008E020008AE8200083C02080028 -:106260008C425CC01040011B00000000000221C2F3 -:10627000A76400088E0D000C240B000124140014E8 -:10628000AF6D002C8E080010AF6800309605001628 -:10629000A7650038960C0014A76C003AAF6B000C91 -:1062A000A76B0010A76B0012A76B0014A76B00165A -:1062B00012200146A37400349206000330C7000286 -:1062C0002CF00001260200088F90001C0A000373C6 -:1062D000AF8200288E14000424030081AF540020F4 -:1062E000936800233105001010A001070000000092 -:1062F0008F4401B80480FFFE3C06401F0011382B7C -:10630000006610253C111000AF540180AF870028B3 -:10631000AF400184AF420188AF5101B80A00037455 -:106320008F9100148E0600043C19000803592021A7 -:10633000AF4600208E07000890980000240F005000 -:10634000331400FF128F0102240500888F4401B826 -:106350000480FFFE3C0D40090011602B00AD1025AC -:106360003C111000AF460180AF8C0028AF4701847C -:10637000AF420188AF5101B80A0003748F91001435 -:106380008E04001C0E00023B00000000104000E8DC -:10639000004048218F90001C240500898F4D01B8D2 -:1063A00005A0FFFE00000000AF4901808E0F001C19 -:1063B0003C1440010011702B00B448253C11100022 -:1063C000AF4F0184AF8E0028AF490188AF5101B8AB -:1063D0000A0003748F910014961900023C140800FF -:1063E00026945CB8333800041300008E3C02600031 -:1063F0008E1F001C3C010800AC3F5CB8AF5F002062 -:10640000920C0010240B0014318400FF148B00B890 -:106410000000000096090002312D000115A0014E78 -:10642000000000008E020004AE8200083C0E08004E -:106430008DCE5CC011C00144000000008F69007463 -:106440003C0E800024040001012E6825AF6D00740D -:10645000A3600005AF64000C3C0C08008D8C5CC090 -:106460008F88001CA7640010000C59C2A76400129A -:10647000A7640014A7640016A76B00088D0300082A -:1064800024040002AF63002C8D0A000CAF6A0030B8 -:1064900091070010A36700348F82001C9045001103 -:1064A000A36500358F86001C90D00012A3700036C3 -:1064B0008F9F001C93F90013A37900378F90001C65 -:1064C00096180014A778003896140016A774003A9E -:1064D0008E0F0018AF6F00245620FDA5AF84002852 -:1064E0003C05080024A55CB80E00025E00002021D7 -:1064F0008F90001C0A0004B6000020213C05080013 -:1065000024A55CB80E000287240400828F90001C32 -:10651000000030210A000373AF8600283C04080005 -:106520008C845CB80E001574000000008F90001C75 -:106530000A000490000018213C05080024A55CB85E -:106540000E0002872404008B8F90001C0011302B5A -:106550000A000373AF8600283C1908008F395CB825 -:106560003C1F08008FFF005024CCFFFE033F782122 -:1065700001F87024AF4E00283C0408008C845CB8FD -:106580003C0908008D2900500089682131A8007F4E -:10659000011A282100A78021AE0600D8AF9000D0B4 -:1065A000AE0000DC0A0003C2AE0C0108AF6000843C -:1065B0003C0508008CA55CB83C0808008D0800501C -:1065C000240CFF803C02000C00A8A021028C58245F -:1065D000AF4B00288E1F00143283007F007A5021B9 -:1065E00001427021ADDF00D88E190014AF8E00D0AB -:1065F000ADD900DC8E180010270FFFFE0A0004152D -:10660000ADCF0108548BFE2E240540000A0004473C -:10661000240510000E000335000000000A0003F8F6 -:106620008F90001C8C46442C3C056C6234B0797011 -:106630003C010800AC205CB814D00008240400021F -:1066400097880034978A002C02802821010A382B71 -:1066500010E0001124040092240400020E000C9AA1 -:10666000240501403C010800AC225CB8AF42002088 -:106670003C0308008C635CB81060000524040083B0 -:106680000E0008650000000010400009240400838B -:106690003C05080024A55CB80E00025E0000000066 -:1066A0008F90001C0011202B0A000373AF84002878 -:1066B0000E000869000000000A0005978F90001C7A -:1066C0008E0400080E00023B000000000A00052EA8 -:1066D000AE8200083C05080024A55CB80E0002301C -:1066E000240400878F90001C0A00054A0011102B1B -:1066F0000E00086D000000003C05080024A55CB8F1 -:106700000A00063D2404008B0E0002500280202166 -:106710009370002302802021360D00100E000259D4 -:10672000A36D00238F90001C0A0005530000182160 -:10673000240400040E000C9A240500301440002AA2 -:10674000004048218F90001C0A00057E240500832C -:106750009205000C30BF000113E0000300000000B0 -:106760009602000EA482002C920A000C314800020E -:106770001100FEF600002821960B00128E03001473 -:10678000A48B001A0A00056AAC83001C8F830038B2 -:106790008F8700301067FE88000020213C09080028 -:1067A00025295C3C000320C0008930218CD40000E6 -:1067B0001285005E247800013303000F5467FFFA4E -:1067C000000320C00A000505000020213C05080048 -:1067D00024A55CB80E000287240400828F90001C60 -:1067E0000A00054A000010213C0B0008034B202141 -:1067F00024030050240A0001AF420020A0830000BF -:10680000A08A00018F88001C91070004A08700184F -:106810008F82001C90450005A08500198F86001C02 -:1068200090DF0006A09F001A8F99001C9338000784 -:10683000A098001B8F94001C928F0008A08F001C52 -:106840008F90001C920E0009A08E001D8F8D001CE1 -:1068500091AC000AA08C001E8F8B001C3C0C080021 -:10686000258C5C3C9163000B3C0B0800256B5C386D -:10687000A083001F8F8A001C9148000CA088002074 -:106880008F87001C90E5000DA08500218F82001CE1 -:10689000240546469046000EA08600228F9F001CCD -:1068A00093F9000FA09900238F98001C93140010F7 -:1068B000A09400248F8F001C91F00011A09000255F -:1068C0008F90001C8F8E00308F990038960D001429 -:1068D000000E18C025C80001A48D0028960A0016D5 -:1068E000006C3021006BF821A48A002A960700185A -:1068F0003108000FA487002CA485002E8E02001CF6 -:10690000ACC90000AF88003011190003AFE20000ED -:106910000A00057E00002821250C00013184000FAB -:10692000000028210A00057EAF8400383C070800DB -:1069300024E75C380087802100002021ACC00000E3 -:106940000A000505AE0000003C05080024A55CB85F -:106950000A00063D240400878E0400040E00023B5A -:10696000000000000A0005A2AE8200083084FFFF8C -:1069700030C600FF8F4201B80440FFFE000644000D -:10698000010430253C07200000C720253C031000EF -:10699000AF400180AF450184AF44018803E00008A7 -:1069A000AF4301B827BDFFE8AFB00010AFBF001480 -:1069B0003C076000240600021080000600A0802131 -:1069C0000010102B8FBF00148FB0001003E00008E0 -:1069D00027BD00183C09600EAD2000348CE5201C5A -:1069E0008F82001C2408FFFC00A81824ACE3201CA4 -:1069F0000E0006F28C45000C0010102B8FBF001407 -:106A00008FB0001003E0000827BD00183C02600EA4 -:106A10003447010024090018274A04000000000040 -:106A200000000000000000003C06005034C30200DB -:106A3000AF440038AF45003CAF430030014018215F -:106A40008F4B0000316800201100FFFD2406007FFD -:106A50002408FFFF8C6C000024C6FFFF24630004A1 -:106A6000ACEC000014C8FFFB24E7000400000000A9 -:106A700000000000000000003C0F0020AF4F00307D -:106A80000000000024AD020001A5702B2529FFFFA6 -:106A9000008E20211520FFE101A0282103E000083D -:106AA0000000000027BDFFE0AFB10014AFBF001829 -:106AB000AFB000103C05600E8CA20034008088212D -:106AC000144000063C0460008C87201C2408FFFC56 -:106AD00000E8302434C30001AC83201C8F8B001CE1 -:106AE00024090001ACA90034956900028D650014E9 -:106AF0008D70000C2D2400818D6700048D660008C8 -:106B0000108000078D6A00102D2C00041580000EE7 -:106B100030CE0007312D000311A0000B0000000053 -:106B20002404008B020028210E0006F22406000334 -:106B30000011102B8FBF00188FB100148FB0001000 -:106B400003E0000827BD002015C0FFF62404008BD9 -:106B50003C030020AF43003000000000240200018D -:106B6000AF820014000000000000000000000000E0 -:106B70003C1F0150013FC825253800033C0F600E23 -:106B8000AF47003800181882AF46003C35E8003C9B -:106B9000AF590030274704008F44000030860020A2 -:106BA00010C0FFFD00000000106000082466FFFF19 -:106BB0002403FFFF8CEB000024C6FFFF24E7000442 -:106BC000AD0B000014C3FFFB250800043C08600E59 -:106BD000AD090038000000000000000000000000C7 -:106BE0003C070020AF470030000000000E00071AED -:106BF0000140202102002821000020210E0006F281 -:106C0000240600030011102B8FBF00188FB1001451 -:106C10008FB0001003E0000827BD002027BDFFD87B -:106C2000AFB200183092FFFFAFB10014AFBF002029 -:106C3000AFB3001CAFB000101240002C0000882140 -:106C40000A0007B22413000150B300408CE5000C89 -:106C50000000000D263900013331FFFF24F8002029 -:106C60000232382B10E00021AF98001C8F820014F4 -:106C70001440001E8F87001C3C0670003C0320005F -:106C80008CE400000086282414A300188F85003CA3 -:106C9000000444023C0980000089802414A0FFEA1B -:106CA000310600FF240A000210CA002E28CB000380 -:106CB00011600016240C000314D3FFE726390001ED -:106CC000020028210E000700240400018F87001C09 -:106CD000AF82003C263900013331FFFF24F8002049 -:106CE0000232382B14E0FFE1AF98001C0220102183 -:106CF0008FBF00208FB3001C8FB200188FB100141B -:106D00008FB0001003E0000827BD002810CC001A47 -:106D1000240D000414CDFFD026390001308EFFFF72 -:106D2000000E19C08F4401B80480FFFE3C0F100014 -:106D30003C102004AF430180AF400184AF50018874 -:106D4000AF4F01B80A0007AD263900010E0006F268 -:106D5000240400841600FFBF8F87001C0A0007ACC4 -:106D6000AF80003C020028210E0007000000202117 -:106D70000A0007CB8F87001C0E000740020020216D -:106D80008F87001C0A0007CCAF82003C3082FFFFD7 -:106D90001440000300001821000424022403001002 -:106DA000308500FF14A000053087000F246600081E -:106DB0000004220230C300FF3087000F14E00005FA -:106DC000308900032468000400042102310300FF1D -:106DD0003089000315200005388B0001246A000269 -:106DE00000042082314300FF388B00013164000130 -:106DF00010800002246C0001318300FF03E00008D2 -:106E000000601021308BFFFF000B394230E600FF9D -:106E10003C09080025295BB8000640800109602173 -:106E20008D8700003164001F240A0001008A1804C5 -:106E300030A500FF00E3202514A000020003102766 -:106E400000E22024240F000100CF70040109682112 -:106E5000000E282714800005ADA400008F86000CCA -:106E600000A6102403E00008AF82000C8F88000CFD -:106E700001C8102503E00008AF82000C3C06001F8B -:106E80003C0360003084FFFF34C5FF8024020020F3 -:106E9000AC602008AC60200CAC602010AC65201405 -:106EA000AC642018AC62200000000000000000006C -:106EB00003E000080000000027BDFFE82402FFFFF8 -:106EC000AFBF0010AF82000C000020213C0608007C -:106ED00024C65BB82405FFFF24890001000440801C -:106EE0003124FFFF010618212C87002014E0FFFA4F -:106EF000AC6500000E0008360000202124020001CD -:106F00003C04600024050020AC822018AC852000E1 -:106F1000000000000000000000000000244A000102 -:106F20003142FFFF2C46040014C0FFF78FBF001052 -:106F300003E0000827BD00188F8300082C620400BE -:106F400003E00008384200018F830008246200013A -:106F500003E00008AF8200088F8300082462FFFF6F -:106F600003E00008AF82000827BDFFE0AFB10014C6 -:106F7000AFBF0018AFB000108F6B00303C06600050 -:106F800000808821ACCB20088F6A002C3C02800056 -:106F900024030008ACCA200C9769003A97680038AF -:106FA00000092C003107FFFF00A72025ACC42010EA -:106FB000ACC22014ACC320000000000000000000A0 -:106FC000000000003C0360008C6D200031AC000824 -:106FD0001580FFF9000000008C6E201405C0002011 -:106FE000000000000E0007FA8F84000C00024080B1 -:106FF0003C09080025295BB8010938218CE4000010 -:107000000E0007FA00028140020220213090FFFFAB -:10701000020020210E000818000028213C0C8000EE -:10702000022C58253210FFFF3C116000240A00207A -:10703000AE2B2014AE302018AE2A20000000000035 -:107040000000000000000000020010218FBF0018A7 -:107050008FB100148FB0001003E0000827BD00209E -:107060008C6620143C02001F3443FF803C1FFFE865 -:1070700000C3C02437F9080003198021001079C229 -:107080003C0C8000022C582531F0FFFF3C116000C1 -:10709000240A0020AE2B2014AE302018AE2A200087 -:1070A00000000000000000000000000002001021AD -:1070B0008FBF00188FB100148FB0001003E00008DC -:1070C00027BD002027BDFFE8AFB000103402FFFF4E -:1070D0003090FFFFAFBF0014120200060200202113 -:1070E0000E00083600000000020020210E000818E3 -:1070F000240500018F8400088FBF00148FB000109A -:107100002483FFFF27BD001803E00008AF830008B9 -:10711000000439C230E6003F00043B42000718403B -:10712000240210002CC4002024C8FFE0AF42002C31 -:10713000246300011480000330A900FF00071840F9 -:10714000310600FF0003608024080001019A5821E5 -:107150003C0A000E00C82804016A382111200005ED -:10716000000530278CE900000125302503E00008E8 -:10717000ACE600008CEE000001C6682403E00008C5 -:10718000ACED000027BDFFE8AFBF0014AFB00010AA -:107190003C0460008C8508083403F00030A2F00045 -:1071A00050430006240200018C8708083404E000E4 -:1071B00030E6F00010C4001E24020002AF8200403E -:1071C0003C1060003C0A0200AE0A081424091000BA -:1071D0003C08000E8E03440003482021AF49002CD8 -:1071E000240501200E000CE0000030218F830040B8 -:1071F000106000043C021691240B0001106B000E7D -:107200003C023D6C344F0090AE0F44088FBF001419 -:107210008FB000103C0C6000240E10003C0D0200EA -:1072200027BD0018AD8E442003E00008AD8D081086 -:107230000A000907AF8000403C0218DA344F009082 -:10724000AE0F44088FBF00148FB000103C0C6000DC -:10725000240E10003C0D020027BD0018AD8E442006 -:1072600003E00008AD8D08100A0008DB24050001CA -:107270000A0008DB000028213C08080025085FC43C -:107280002404FFFF010018212402001E2442FFFFF6 -:10729000AC6400000441FFFD246300043C070800C7 -:1072A00024E760408CE5FFFC2404001C2406000158 -:1072B000308A001F01464804248400010009102779 -:1072C0002C8300201460FFFA00A22824ACE5FFFC08 -:1072D0003C05666634A4616E3C06080024C6610065 -:1072E000AF840058AF88009C2404FFFF00C0182121 -:1072F0002402001F2442FFFFAC6400000441FFFD94 -:10730000246300043C0766663C05080024A560C0B1 -:10731000AF86004834E6616EAF8600982404FFFF14 -:1073200000A018212402000F2442FFFFAC640000DB -:107330000441FFFD246300043C0B66663C06080024 -:1073400024C660403568616EAF8500A4AF880070C8 -:107350002404FFFF00C018212402001F2442FFFF65 -:10736000AC6400000441FFFD246300043C0D66662C -:107370003C0A0800254A618035AC616EAF860090FA -:10738000AF8C005C2404FFFF01401821240200039D -:107390002442FFFFAC6400000441FFFD24630004AD -:1073A0003C090800252961908D27FFFC2404000674 -:1073B000240500013099001F0325C0042484000126 -:1073C000001878272C8E002015C0FFFA00EF382413 -:1073D000AD27FFFC3C09666624030400240403DC9B -:1073E00024050200240600663522616E3C08080070 -:1073F00025085CC4AF820074AF830044AF83006C87 -:10740000AF830050AF830084AF8A008CAF840064E8 -:10741000AF85004CAF860054AF840078AF85006024 -:10742000AF86008001001821240200022442FFFFE1 -:10743000AC6000000441FFFD246300042404000349 -:107440002403000C3C0A0800254A5CD0AF8A00687F -:107450000A0009AE2405FFFF0004188024840001FF -:10746000006858212C8700C014E0FFFBAD650000C8 -:107470003C0E666635CD616E240C17A024081800FA -:10748000AF8D0088AF8C009403E00008AF88007CCB -:107490002484007F000421C200004021000030212C -:1074A00000003821000028210A0009C5AF8400A08F -:1074B0001060000624E7000100C4302124A500016B -:1074C0002CC20BF51440FFFA2CA300663C090800FF -:1074D0002529618001201821240200032442FFFF96 -:1074E000AC6000000441FFFD2463000410E0001ABA -:1074F00024E3FFFF0003294210A0000A000020211E -:107500002406FFFF3C0308002463618024840001FB -:107510000085502BAC660000250800011540FFFBDC -:107520002463000430E2001F104000080008688057 -:10753000240C0001004C38040008588001692821FF -:1075400024E6FFFF03E00008ACA6000001A94021EB -:107550002409FFFFAD09000003E00008000000005F -:10756000AF4400283C04000C03442021000528827D -:107570000A000CE000003021000421803C03600080 -:10758000AC6410080000000000052980AC65100CF8 -:107590000000000003E000088C62100C27BDFFE82B -:1075A0000080282124040038AFBF00140E0009F524 -:1075B000AFB0001024040E00AF4400283C10000CB3 -:1075C00003502021240500100E000CE000003021A3 -:1075D00003501021AC400000AC40000424040038EB -:1075E0008FBF00148FB0001024053FFF27BD001887 -:1075F0000A0009F58C430000000421803C03600070 -:10760000AC641008000000008C62100C03E000085D -:107610000002118227BDFFC8AFB400208F9400681C -:10762000AFBE0030AFB7002CAFB600280000B821C5 -:107630000080B021241E00C0AFBF0034AFB50024CD -:10764000AFB3001CAFB20018AFB10014AFB0001060 -:107650000A000A32AFA5003C504000018F94006838 -:1076600027DEFFFF13C00028269400048E9200003E -:107670003C03080024635FC01240FFF70283102B15 -:107680003C04080024845CC4028410230002A8C0C7 -:10769000000098210A000A412411000100118840CD -:1076A000122000260000000002B38021025128248D -:1076B0000200202110A0FFF9267300010E0009FE30 -:1076C000000000000016684032EC000101AC2021EF -:1076D0000E0009F5020028218F89009426F7000189 -:1076E0008FA6003C3AEB0001316A00012528FFFF1C -:1076F0000011382702CAB021AF88009416E6FFE7D0 -:1077000002479024AE92000002E010218FBF0034A7 -:107710008FBE00308FB7002C8FB600288FB50024A5 -:107720008FB400208FB3001C8FB200188FB10014EB -:107730008FB0001003E0000827BD00383C0E0800A1 -:1077400025CE5FC0028E102B0A000A2DAE920000DB -:1077500027BDFFD8AFB10014AFB00010AFBF0020FD -:10776000AFB3001CAFB2001800A0882110A0001F0A -:10777000000480403C13080026735CC40A000A7AA7 -:107780002412000112200019261000010E000A1513 -:1077900002002021000231422444FFA0000618808C -:1077A0003045001F2C8217A1007318212631FFFFDE -:1077B0001040FFF400B230048C6900000200202168 -:1077C00024053FFF012640241500FFEE0126382541 -:1077D0000E0009F5AC6700008F8A009426100001A6 -:1077E000254700011620FFE9AF8700948FBF0020D6 -:1077F0008FB3001C8FB200188FB100148FB000102F -:1078000003E0000827BD00288F85009C00805821D8 -:107810000000402100004821240A001F3C0C080001 -:10782000258C603C3C0D080025AD5FC48CA6000093 -:1078300050C000140000402100AD1023000238C0E9 -:10784000240300010A000AB30000202115000003F0 -:1078500000E41021244820240000482125290001AB -:10786000512B00132506DFDC106000062484000184 -:1078700000C3702415C0FFF5000318400A000AB1C8 -:107880000000402110AC002624A300040060282141 -:10789000254AFFFF1540FFE5AF85009C512B0004F2 -:1078A0002506DFDC0000402103E000080100102174 -:1078B0000006614230C5001F000C50803C070800E4 -:1078C00024E75FC424040001014730211120000F88 -:1078D00000A420043C05080024A560401480000595 -:1078E0002529FFFF24C6000410C500110000000078 -:1078F000240400018CCF00000004C02700042040B5 -:1079000001F868241520FFF5ACCD00008F990078B0 -:1079100001001021032B482303E00008AF89007801 -:107920003C05080024A55FC40A000ABB00004021F2 -:107930003C06080024C65FC40A000AD424040001DF -:10794000308800FF240200021102000A2403000311 -:107950001103005C8F8900A4240400041104005F5B -:1079600024050005110500670000182103E0000848 -:10797000006010218F8900483C0C0800258C6100B4 -:107980003C04080024846180240300201060000F60 -:1079900000005821240D0002240E00033C0F0800B3 -:1079A00025EF61008D27000014E0000B30F9FFFF88 -:1079B000252900040124C02B530000010180482127 -:1079C0002463FFFF5460FFF88D2700000160182139 -:1079D00003E0000800601021132000323C0500FF86 -:1079E00030E200FF004030211040004200005021F2 -:1079F00024050001000020210005C84000A6C02485 -:107A000017000003332500FF14A0FFFB24840001AE -:107A1000012CC023001828C000AA6021008C50212E -:107A20003144001F240C0001008C180400031027AF -:107A300000E23024110D0041AD260000110E004C73 -:107A4000000A1840110D00368F87006C510E005649 -:107A50008F8C0060240D0004110D005A8F8E00845D -:107A6000240E0005150EFFDA01601821240B1430D6 -:107A700011400006000018218F8400A0246300013B -:107A8000006A402B1500FFFD016458218F8A008099 -:107A9000AF89008C016018212549FFFF0A000B0BFC -:107AA000AF89008000E52024000736021080FFD057 -:107AB000240A001800075402314600FF0A000B1385 -:107AC000240A00103C0C0800258C60C03C0408000F -:107AD000248461000A000AFA240300103C0C080008 -:107AE000258C60403C040800248460C00A000AF928 -:107AF0008F89009000071A02306600FF0A000B13FE -:107B0000240A00088F89008C3C0C0800258C6180B9 -:107B10003C040800248461900A000AFA240300044B -:107B2000000A4080250B003024E6FFFF0160182189 -:107B3000AF8900480A000B0BAF86006C000AC982AF -:107B4000001978803C07080024E760C001E7202185 -:107B5000000A18428C8F00003079001F032C380473 -:107B60000007C02701F860240A000B28AC8C000035 -:107B7000000331420006288000AF28213062001F38 -:107B80008CB8000024630001004CC80400032142AB -:107B9000001938270004108003073024004F2021EB -:107BA0000A000B6CACA60000000A68C025AB0032CE -:107BB000258AFFFF01601821AF8900A40A000B0B82 -:107BC000AF8A0060254B1030AF890090016018210A -:107BD00025C9FFFF0A000B0BAF8900843086000720 -:107BE0002CC2000610400014000000000006408077 -:107BF0003C030800246359C8010338218CE40000C9 -:107C000000800008000000002409000310A9000EF5 -:107C100000000000240A000510AA000B000000006C -:107C2000240B000110AB0008000000008F8C00A0A6 -:107C300010AC00050000000003E000080000102167 -:107C40000A000A9900A020210A000AE700C02021AA -:107C500027BDFFE8308400FF240300021083000BDF -:107C6000AFBF0010240600031086003A2408000469 -:107C700010880068240E0005108E007F2CAF143091 -:107C80008FBF001003E0000827BD00182CA20030B1 -:107C90001440FFFC8FBF001024A5FFD0000531C2A7 -:107CA000000668803C07080024E7610001A7302136 -:107CB0008CC900000005288230AC001F240B000195 -:107CC000018B50048F840048012A4025ACC8000075 -:107CD0008C83000050600001AF8600488F98006CD4 -:107CE00030AE000124A6FFFF270F000115C00002DF -:107CF000AF8F006C24A600010006414200082080DE -:107D0000008718218C79000030C2001F2406000172 -:107D10000046F804033F382410E0FFDA8FBF00105C -:107D20000005C182001870803C0F080025EF60C07C -:107D300001CF48218D2B00000005684231A5001FAE -:107D400000A66004016C502527BD001803E0000860 -:107D5000AD2A00002CA7003014E0FFCA8FBF00102E -:107D600030B900071723FFC724A8FFCE00086A0216 -:107D7000000D60803C0B0800256B60C0018B30213A -:107D80008CC40000000828C230AA001F240800018B -:107D9000014848048F8200A400891825ACC3000064 -:107DA0008C5F000053E00001AF8600A40005704026 -:107DB000000E7942000F28803C04080024846100F2 -:107DC00000A418218C6B000025DF000131CD001FBD -:107DD000001F514201A86004016C4825000A108070 -:107DE000AC690000004428218CA600008F98006038 -:107DF00033F9001F8FBF00100328380400C778250F -:107E0000270E000127BD0018ACAF000003E00008FA -:107E1000AF8E006024A5EFD02CB804001300FF99AA -:107E20008FBF001000053142000658803C0A080050 -:107E3000254A6040016A30218CC4000030A3001F35 -:107E400024090001006910048F9900900082F82530 -:107E5000ACDF00008F27000050E00001AF860090EB -:107E60008F8D00848FBF001027BD001825AC000146 -:107E700003E00008AF8C008415E0FF828FBF001084 -:107E80008F8600A0000610400046F821001F210048 -:107E900003E4C8210019384024F8143000B8402BFE -:107EA0001100FF788FBF001024A4EBD00E00020D4C -:107EB00000C0282100027942000F70803C0D0800AC -:107EC00025AD618001CD20218C8B0000304C001F3E -:107ED00024060001018618048F89008C0163502557 -:107EE000AC8A00008D25000050A00001AF84008CFA -:107EF0008F9800808FBF001027BD00182708000151 -:107F000003E00008AF88008030A5000724030003C9 -:107F100010A3001028A20004144000082407000247 -:107F20002403000410A300152408000510A8000F66 -:107F30008F8500A003E000080000000014A7FFFDEB -:107F40000080282114C3FFFB240400020A000BABAD -:107F500000000000240900050080282110C9FFFB53 -:107F60002404000303E000080000000014C5FFF132 -:107F7000008028210A000BAB24040005240A00011C -:107F80000080282110CAFFF12404000403E0000847 -:107F90000000000027BDFFE0AFB00010000581C267 -:107FA0002603FFD024C5003F2C6223D024C6007FC7 -:107FB000AFB20018AFB10014AFBF001C309100FF8A -:107FC000000691C20005298202002021104000080D -:107FD0002403FFFF0E000A6B0000000002002021B6 -:107FE000022028210E000C590240302100001821E7 -:107FF0008FBF001C8FB200188FB100148FB000101B -:108000000060102103E0000827BD002027BDFFD835 -:1080100024A2007FAFB3001CAFB20018000299C2C7 -:10802000309200FF24A3003F02402021026028215B -:10803000AFB10014AFB00010AFBF00200E000B8E28 -:108040000003898200408021004020210220282155 -:1080500014400009000018218FBF00208FB3001CBE -:108060008FB200188FB100148FB000100060102183 -:1080700003E0000827BD00280E000A1C00000000D5 -:1080800000402821020020211051FFF3001019C0E8 -:108090000E000A6B0000000002002021024028218F -:1080A0000E000C59026030218FBF00208FB3001CDE -:1080B0008FB200188FB100148FB00010000018218B -:1080C0000060102103E0000827BD00283084FFFF76 -:1080D00030A5FFFF1080000700001821308200014A -:1080E0001040000200042042006518211480FFFBAC -:1080F0000005284003E000080060102110C00007C0 -:10810000000000008CA2000024C6FFFF24A500048C -:10811000AC82000014C0FFFB2484000403E00008CC -:108120000000000010A0000824A3FFFFAC860000A0 -:1081300000000000000000002402FFFF2463FFFF96 -:108140001462FFFA2484000403E000080000000029 -:1081500030A5FFFF8F4201B80440FFFE3C076015C9 -:1081600000A730253C031000AF440180AF400184DC -:10817000AF46018803E00008AF4301B88F8500D007 -:108180002C864000008018218CA700840087102BCB -:1081900014400010000000008CA800842D06400050 -:1081A00050C0000F240340008CAA0084008A482B92 -:1081B000512000018CA3008400035A42000B208050 -:1081C0003C05080024A55A400085182103E000085A -:1081D0008C62000014C0FFF4000000002403400083 -:1081E00000035A42000B20803C05080024A55A4099 -:1081F0000085182103E000088C6200008F8300D006 -:10820000906600D024C50001A06500D08F8500D005 -:10821000906400D090A200D210440017000000002B -:10822000936C00788F8B00BC318A00FFA16A000C30 -:1082300025490001938700C4312200FF3048007FA8 -:108240001107000B00026827A36200788F4E0178A7 -:1082500005C0FFFE8F9900B0241800023C0F1000EB -:10826000AF590140A358014403E00008AF4F017823 -:108270000A000D2931A20080A0A000D00A000D1F25 -:108280000000000027BDFFD8AFB200188F9200B8E1 -:10829000AFBF0020AFB3001CAFB00010AFB10014EF -:1082A0008F9300B48E5900283C1000803C0EFFEFE5 -:1082B000AE7900008E580024A260000A35CDFFFF81 -:1082C000AE7800049251002C3C0BFF9F356AFFFFF3 -:1082D000A271000C8E6F000C3C080040A271000BD4 -:1082E00001F06025018D4824012A382400E830255A -:1082F000AE66000C8E450004AE6000183C0400FF22 -:10830000AE6500148E43002C3482FFFFA660000887 -:108310000062F824AE7F00108E5900088F9000B0E4 -:10832000964E0012AE7900208E51000C31D83FFFDE -:1083300000187980AE7100248E4D001401F0602188 -:1083400031CB0001AE6D00288E4A0018000C41C2EE -:10835000000B4B80AE6A002C8E46001C01093821B0 -:10836000A667001CAE660030964500028E440020D1 -:10837000A665001EAE6400349243003330620004F0 -:1083800054400005924600008F8300D08C7F007C13 -:10839000AE7F0030924600008F8500BCA0A6000092 -:1083A000924400333082000250400007924E000198 -:1083B0008F8700BC240AFF8090E90000012A402535 -:1083C000A0E80000924E00018F8D00BC2409FFBF81 -:1083D0002404FFDFA1AE00018F8A00BC914C000D88 -:1083E000318B007FA14B000D8F8600BC90C8000D23 -:1083F00001093824A0C7000D8F9100BC8E650014C0 -:108400009223000D2CA200010002F9400064C82450 -:10841000033FC025A238000D8F8800BC9650001283 -:108420008F8700D0A51000028E45000490ED00BC9F -:1084300030AF0003000F702331CC000300AC1021DB -:1084400031AB0002156000022444003424440030A3 -:1084500090F100BC00B18024320F000415E000024E -:1084600024830004008018218F8900AC240A0002B4 -:10847000AD030004A12A00009248003F8F8700ACA2 -:10848000A0E800018F9100AC9246003F8E440004AA -:10849000A62600029765003C0E000CF630B0FFFFE8 -:1084A00000021380005020253C0342000083F82581 -:1084B000AE3F00048F8500AC8E590038ACB900186F -:1084C0008E580034ACB8001CACA0000CACA000105E -:1084D000A4A00014A4A00016A4A00020A4A0002220 -:1084E000ACA000248E620014504000012402000160 -:1084F0008FBF00208FB3001C8FB200188FB1001403 -:108500008FB00010ACA200080A000D1627BD00288D -:108510008F8600D027BDFFD0AFBF002CAFB600289C -:10852000AFB50024AFB40020AFB3001CAFB2001849 -:10853000AFB10014AFB0001094C300E094C200E2E9 -:10854000104300412405FFFF3C16000E90C400D0EC -:1085500090C800D1309200FF310400FF0244382B54 -:1085600010E0004426490001108900378F9800B0C0 -:108570003C0508008CA5005C2414FF8000B8602135 -:1085800001946824AF4D002C94CA00E2318B007F27 -:10859000017A482131447FFF013640210004104018 -:1085A0000048A82196A700003C1F08008FFF005834 -:1085B00030F53FFF0015198003E3C8210319882116 -:1085C0003233007F027A782102348024AF50002CAD -:1085D00001F69821926E000D31C5000410A00048EC -:1085E0000000000094C300E294C300E294D800E2CB -:1085F00024048000307F7FFF27F9000133317FFFA3 -:108600000304802402117825A4CF00E294CE00E276 -:108610003C1208008E52006031D47FFF129200DFBE -:10862000000000008E720018000028212646FFFF7F -:10863000AE66002C8F8600D094C800E094C900E29A -:108640001528FFC2000000008FBF002C8FB6002845 -:108650008FB500248FB400208FB3001C8FB2001898 -:108660008FB100148FB0001000A0102103E00008AB -:1086700027BD003090CD00D2264A000131AC00FF6A -:10868000008C5821116AFFF08F9800B03C0508005B -:108690008CA5005C2414FF8000B86021019468243C -:1086A000AF4D002C94CA00E2318B007F017A482143 -:1086B00031447FFF01364021000410400048A821CA -:1086C00096A700003C1F08008FFF005830F53FFFC1 -:1086D0000015198003E3C821031988213233007F74 -:1086E000027A782102348024AF50002C01F69821C0 -:1086F000926E000D31C5000414A0FFBA0000000006 -:108700008E6600100012C0C08E6E003000129140C4 -:1087100002587821036F582100CE6823256C008809 -:1087200024020002AE6D0010AF8C00ACA162008884 -:10873000976A003C8E6400308F9100AC0E000CF6FE -:108740003150FFFF00022380009048253C03420087 -:1087500001234025AE2800048E6700048F8C00ACF6 -:108760008E7F0000240D0008AD87001CAD9F00180F -:10877000AD80000CAD8000109265000A30B900FF9A -:10878000A5990014967800083C05000CA5980016E1 -:108790009271000A322F00FFA58F0020967000080A -:1087A00024110005A5900022AD800024926E000BDC -:1087B0002410C00031C600FFA5860002A18D000173 -:1087C0008E6B00308F8200AC8F8800B0AC4B0008FD -:1087D0003C0A08008D4A0054014820210094482496 -:1087E000AF4900283C0308008C630054006838211E -:1087F00030FF007F03FAC8210325C02102587821E9 -:10880000AF8F00BCAF9800C0A1F100008F8B00BCFF -:108810002403FFBF2405FFDF956E000201D0A024D2 -:1088200002959025A57200029166000230CD003FAE -:1088300035AC0040A16C00028F8800BC8F8200D054 -:108840003C0C7FFFAD0000048C4A007C358BFFFFA1 -:108850003C028000AD0A00089104000D3089007FC1 -:10886000A109000D8F9F00BC93F5000D02A33824D1 -:10887000A3E7000D8F9100BC9239000D0325C024A1 -:10888000A238000D8E6F00348F8D00BCADAF00108C -:108890008E6E002C8E70003001D0A023ADB4001479 -:1088A00091B200183246007FA1A600188F8700BC45 -:1088B0008E6A00308CE40018014B4824008240246A -:1088C0000109A825ACF500189263000AA0E3001C7A -:1088D000967F00088F8500BC8F9900D0A4BF001E32 -:1088E0008E7000308E6400300E00020D8F250084E3 -:1088F0008F8500D0000289400002C10090AE00BC0C -:10890000023878210040302131D400021280000367 -:10891000020F80210002A8800215802190B200BCC5 -:1089200032540004128000020006C880021980211F -:108930008E6F00308F8B00BC2406800031EE000368 -:10894000000E682331AC0003020C1021AD6200045C -:1089500094A400E294AA00E294A300E231507FFFC5 -:108960002604000130897FFF006640240109882524 -:10897000A4B100E294A700E23C1308008E730060EB -:1089800030FF7FFF13F30012000000000E000D16F1 -:10899000000000000A000E240000282194CD00E20F -:1089A00001A46024A4CC00E290CB00E290C200E2DB -:1089B000316A00FF000A49C200092027000441C0B3 -:1089C0003055007F02A838250A000E20A0C700E21B -:1089D00094B100E202263824A4A700E290BF00E28E -:1089E00090B400E233F300FF0013C9C200199027CE -:1089F0003298007F0012A9C0031530250E000D1615 -:108A0000A0A600E20A000E24000028213084FFFF07 -:108A100030A5FFFFAF440018AF45001C03E000087D -:108A20008F42001427BDFFB0AFB000288F9000D058 -:108A3000AFB40038AFBF004CAFBE0048AFB7004482 -:108A4000AFB60040AFB5003CAFB30034AFB20030BA -:108A5000AFB1002CA7A00014920600D1920500D05F -:108A60003094FFFF30C400FF30A300FF0064102BE0 -:108A7000A7A0001E10400071AFA00010920900D006 -:108A80000014982B312800FF0088382324F2FFFFC0 -:108A90000012882B0233782451E000758FB2001049 -:108AA00096180012961900100014F4000319B82348 -:108AB0000017B400001614030282A82A16A00002B0 -:108AC000001E2403004020210244F82B13E0000282 -:108AD00000801821024018210003340000061C0306 -:108AE0003065FFFF2CA200091440000200609821AD -:108AF000241300088E090008001359808E08000C0A -:108B00003164FFFF3C0A0010008A3825274A040020 -:108B1000AF490038AF8A00B8AF48003CAF470030DB -:108B20000000000000000000000000000000000045 -:108B30000000000000000000000000000000000035 -:108B40008F4D000031AC00201180FFFD0013702A12 -:108B500001D110240000A821104001C00000000035 -:108B60008F9800B03C0B08008D6B00542411FF80DF -:108B7000921E00D00178202100911024921900D07B -:108B8000AF4200288D4500103C0608008CC60058F6 -:108B90003C1708008EF7005430A73FFF00071980EC -:108BA00000C34021030820210091F824920B00D03B -:108BB000AF5F002C9148000033D600FF332F00FF39 -:108BC00002F8702100166140000F68C031C9007FB3 -:108BD000018D3821013A2821316300FF3086007F62 -:108BE0003C02000C00A2B021000389400367C821A9 -:108BF00000DAF8213108003F3C1E000E0236B82191 -:108C00002738008803FE88212D0F0008AF9800AC9C -:108C1000AF9700BCAF9600C011E0018FAF9100B4D8 -:108C2000000868803C0E080025CE59E001AE6021A6 -:108C30008D8900000120000800000000920E00D283 -:108C4000920D00D00014982B31CA00FF31AC00FF08 -:108C5000008C5823014B20212492FFFF0012882B07 -:108C60000233782415E0FF8E000000008FB2001060 -:108C70008FBF004C8FBE00483A4200018FB70044BE -:108C80008FB600408FB5003C8FB400388FB30034EE -:108C90008FB200308FB1002C8FB0002803E00008A5 -:108CA00027BD0050915800013317002012E0020444 -:108CB00024160001921F00BC0000B02133F900010E -:108CC0001320000D241E00018D4800148E03008423 -:108CD0000103B02B16C00002010030218E06008473 -:108CE0008E05006400C5382B14E0000200C020216E -:108CF0008E0400640080B0218D4200148E0B00644D -:108D0000004B302B14C00002004020218E04006470 -:108D10000096B82356E00001241E0002025E202BBC -:108D200014800148000018218D5900388E2F000C46 -:108D30003C180080AE3900008D5000343C0EFF9F7F -:108D400001F86025AE3000049149003F35CDFFFFAA -:108D5000018D20243C0A00203C0BFFEFA229000BD0 -:108D6000008A38253562FFFF00E228243C0600080F -:108D70008F8700B800A6C825AE39000C8CE300141C -:108D8000AE2000183C08FFFBAE2300148CF800183E -:108D9000351FFFFF033F7024AE38001C8CEF000826 -:108DA00002D78021AE2F00248CED000CAE30002CB9 -:108DB000AE2E000CAE2D0020AE200028A6200038DC -:108DC000A620003A8CEC001401964823013750236A -:108DD00011400011AE2A001090EE003D8E2C0004D0 -:108DE0008E240000000E6900018D28210000502112 -:108DF00000AD302B008A582101661021AE250004F9 -:108E0000AE22000090E3003DA223000A8F8800B844 -:108E1000951F0006A63F00088F8B00AC24060002B9 -:108E200002C02021A16600009765003C8F9000AC35 -:108E300030A2FFFF0E000CF6AFA200208FA300208F -:108E4000000243808F8500B80103C8253C1F420003 -:108E5000033FC025AE1800048F8400AC8CAF0038EF -:108E6000AC8F00188CB00034AC90001CAC80000CAF -:108E7000AC800010A4800014A4800016A480002000 -:108E8000A4800022AC80002490A7003FA4870002A9 -:108E900012C00210240D000152E0000290A2003D19 -:108EA00090A2003E244A0001A08A00018F8400ACF9 -:108EB000AC9600088F8300D024070034906F00BC6C -:108EC00031EE000251C00001240700308F8200B84B -:108ED0008F9900BC906800BC905F000024100004D3 -:108EE00032CF0003A33F00008F9800B88F8C00BCE6 -:108EF000020F7023930D00012405C00031CA000346 -:108F0000A18D00018F9000BC8F8900B800F6382138 -:108F1000960400029526001200EA382100855824A4 -:108F200030C33FFF01631025A6020002921F00021A -:108F30003108000433F9003F37380040A21800021E -:108F400012C000028F8500BC00E838218F8600D057 -:108F5000ACA70004241FFFBF8CC3007C2ECB0001F4 -:108F6000240FFFDFACA3000890A8000D000B6940A0 -:108F70003102007FA0A2000D8F9000BC9219000D5D -:108F8000033FC024A218000D8F8A00BC914E000D33 -:108F900001CF6024018D4825A149000D8F8600B8BE -:108FA0008F8B00BC8CC70020AD6700108CC50024DF -:108FB000AD6500148CC40028AD6400188CC3002C6F -:108FC0000E000D16AD63001C2408000257C8009C5B -:108FD0008F9000D08F8F00D08F8A00C002E02021B8 -:108FE00091E800D091EB00D091E700D0311000FF64 -:108FF000316E00FF00106940000E28C001A5182145 -:1090000030E900FF0363C8210009314000CAF8219C -:1090100027220088AF8200ACAF9F00BCA33E00882F -:109020000E000CF68F9000AC8FB800200002638019 -:109030003C0F4200019840258F8C00B8010F582545 -:10904000AE0B00048D8400388F8B00AC000028210B -:1090500000053900AD6400188D8E00343C0F7FFF91 -:1090600035E8FFFFAD6E001C9183003E8D69001C4A -:109070008D6600180003510000036F02012AC02111 -:1090800000ED1025030AF82B00C2C821033F802100 -:10909000AD78001CAD700018AD60000CAD60001024 -:1090A0009184003E241F00052410C000A564001414 -:1090B000958E000402E8402402E02021A56E0016EF -:1090C0009185003EA5650020958D0004A56D0022C8 -:1090D000AD6000249187003FA56700029183003EA8 -:1090E0009189003D0123502325460001A16600011E -:1090F0008F8200AC8F9900BCAC570008A33F0000E2 -:109100008F8A00BC8F9800B8954F0002970E00120E -:109110002418FFBF020F682431C53FFF01A5382581 -:10912000A5470002914C00022405FFDF3189003F72 -:1091300035230040A14300028F9900BC8F8600D0E8 -:109140002409FFFFAF2000048CCB007C2403FF80A8 -:10915000AF2B00089322000D3C0B8000305F007F96 -:10916000A33F000D8F8E00BC91D0000D0218782413 -:10917000A1CF000D8F8C00BC918D000D01A538246E -:10918000A187000D8F8600BCACC90010ACD60014BE -:1091900090CA00180143B025A0D600188F8F00BCDC -:1091A0008F9800B88DE20018004BF82403E8C8251A -:1091B000ADF900189310003EA1F0001C8F8E00B88E -:1091C0008F8D00BC8F8700D095C50004A5A5001E1B -:1091D0000E00020D8CE500848F8700D000026140F4 -:1091E0000002210090EA00BC0184482100402821AF -:1091F0003156000212C0000302E930210002B080A3 -:1092000000D6302190EC00BC3184000410800003B3 -:1092100032EA00030005C08000D830212409000490 -:109220008F9700BC012A1023305F000300DFC821A4 -:10923000AEF900040E000D16A62500388F9000D060 -:1092400003C01821146000020060B02100009021CA -:1092500056C000868F9700B80012882B9609001020 -:10926000029550233C14002002A91021A6020010F0 -:10927000AF5400303154FFFF00000000961300107F -:10928000961F001213F30011000000008E17000C4F -:109290008E0C00080015C98002F94021001927C36F -:1092A0000119B02B0184782101F65821AE08000C79 -:1092B000AE0B00080014A82B023580241200FE6BB0 -:1092C0008F9000D00A000F3F00000000960B0014A2 -:1092D0008E0500043163FFFF000370C000AE38212B -:1092E000AF47003C8E0600048F4D003C00CDF023BC -:1092F0001BC00036000000008E080000250200019F -:109300003C16001036CF0008AF420038AF4F003097 -:10931000000000000000000000000000000000004D -:10932000000000000000000000000000000000003D -:109330008F440000308C00201180FFFD00000000F1 -:109340008F5904003C170020AE1900088F55040403 -:10935000AE15000CAF570030000000003C060800BE -:109360008CC600442418000110D800D3000000006F -:10937000960700123C0508008CA5004000A7682154 -:10938000A60D0012961E001427C90001A60900149C -:10939000960200143044FFFF5486FFC70014A82B28 -:1093A00030A5FFFF0E000F1AA60000143C030800B2 -:1093B0008C630024960500120043702300AE302316 -:1093C000A60600120A0011450014A82B8E02000008 -:1093D0000A0011583C16001091560001241000019B -:1093E0000016784215F0001C97A8001E8D5F00142F -:1093F0002411C00033FE3FFF0111C8243C180800AF -:109400008F180060033EB82532E53FFF00B8502BAF -:1094100011400011A7B7001E3C1008008E10005824 -:109420008F8F00B000057180240CFF80020F68212F -:1094300001AE48213124007F012C5824009A2821B4 -:109440003C02000EAF4B002C00A2302190C7000D53 -:1094500034E30004A0C3000D0E000D38000000002E -:109460008F9000D0240300018F9700B826B9000127 -:109470000019AC00024390230015AC0326F800400D -:1094800002B3202A0012882B240C00010300502173 -:1094900000911024AF9800B80A000F6DAFAC001017 -:1094A000955600128F8400B032C5FFFF0E000CEB02 -:1094B000A7B600148F9000D00A0011B10000182147 -:1094C0008D590038A620000824040003AE3900009E -:1094D0008D570034A220000A8F9800B8AE370004E0 -:1094E0003C0F0080930C003FA224000C8E28000C3F -:1094F0003C0BFF9FA22C000B010F1825356EFFFFC0 -:109500003C05FFEF8F9700B8006E682434A7FFFF7B -:1095100001A73024AE26000C8EFE001496FF001228 -:109520008F8200B0AE3E00108EF00014AE20001806 -:10953000AE200020AE300014AE2000248EE90018CA -:1095400033F03FFF00105180AE2900288EF900084B -:109550000142C02133EC0001AE3900308EEB000C2B -:109560008F8500AC001879C2000C238001E44021F3 -:10957000240E0002A628001CA6200036AE2B002CCC -:10958000A0AE00009767003C8F8A00AC3C0342000D -:1095900030EDFFFF01A33025AD4600048F9E00B8DB -:1095A000240200012408C0008FD1003824060034B2 -:1095B000AD5100188FC90034AD49001CAD40000CFE -:1095C000AD400010A5400014A5400016A5400020A5 -:1095D000A5400022AD400024A5560002A142000192 -:1095E0008F9F00AC8F9900B88F9800BCAFF6000831 -:1095F00093370000A31700008F8C00B88F8F00BC3A -:1096000091840001A1E400018F8D00BC95AB0002A4 -:109610000168702401D02825A5A5000291A70002A9 -:1096200030E3003FA1A300028F8300D08F8400BCF1 -:10963000907100BC323E000253C00001240600308D -:10964000AC8600048C6F007C2403FFBFAC8F000845 -:109650009088000D310B007FA08B000D8F8700BC20 -:1096600090EE000D01C32824A0E5000D8F9E00BCE4 -:1096700093CD000D35A60020A3C6000D8F8A00B83B -:109680008F9100BC8D500020AE3000108D49002419 -:10969000AE2900148D420028AE2200188D5F002CE8 -:1096A000AE3F001C0E000D16000000008F9000D091 -:1096B0000A00112B02C01821960A00123C1F080054 -:1096C0008FFF002403EA9821A61300120A00114517 -:1096D0000014A82BA08D00018F8900AC240C000180 -:1096E000AD2C00080A0010458F8300D027BDFFE095 -:1096F0003C1808008F180050AFB00010AFBF001822 -:10970000AFB10014AF8400B09371007403047821EA -:109710002410FF8031EE007F3225007F01F05824B5 -:1097200001DA68213C0C000AA38500C401AC2821A1 -:10973000AF4B002494A900109768000690A6006221 -:1097400000803821240200300109202330C300F0BA -:10975000AF8500D0106200193090FFFF90AE00621C -:10976000240DFFF0240A005001AE6024318B00FF6D -:10977000116A002F0000000016000007241F0C00D3 -:10978000AF5F00248FB100148FBF00188FB000109E -:1097900003E0000827BD00200E000F20020020215A -:1097A000241F0C00AF5F00248FB100148FBF00187E -:1097B0008FB0001003E0000827BD002094A200E055 -:1097C00094A400E290BF0113008218263079FFFFB5 -:1097D00033E700C014E000092F3100011600003803 -:1097E000000000005620FFE6241F0C000E000DDBD9 -:1097F000000000000A001277241F0C001620FFDE74 -:10980000000000000E000DDB000000001440FFDC33 -:10981000241F0C00160000228F8300D090690113D2 -:109820003122003FA06201130A001277241F0C00AE -:1098300094AF00D48F8600D400E0282124040005D2 -:109840000E000C7C31F0FFFF1440000524030003E0 -:10985000979100E6000018212625FFFFA78500E666 -:109860008F5801B80700FFFE3C196013AF4001801C -:10987000241F0C00AF500184007938253C101000E3 -:10988000AF4701888FB10014AF5001B8AF5F00241B -:109890008FB000108FBF001803E0000827BD002024 -:1098A0000E000F20020020215040FFB5241F0C00A5 -:1098B0008F8300D0906901130A0012A03122003F6B -:1098C0000E000F20020020211440FFAD241F0C00C9 -:1098D000122000078F8300D0906801133106003FEB -:1098E00034C20040A06201130A001277241F0C004A -:1098F0000E000DDB000000005040FFA1241F0C00F3 -:109900008F8300D0906801133106003F0A0012D007 -:1099100034C20040AF9B00C803E00008AF8000ECF9 -:109920003089FFFF000940422D02004100092980D3 -:10993000144000020009504024080040000879400B -:109940000008C0C001F85821256701A800EF702168 -:1099500025CC007F240DFF80018D18240065302167 -:1099600000CA282125640088240A00883C010800D8 -:10997000AC2A004C3C010800AC240050AF8500D458 -:109980003C010800AC2900603C010800AC280064E0 -:109990003C010800AC2700543C010800AC230058EF -:1099A0003C010800AC26005C03E000080000000059 -:1099B000308300FF30C6FFFF30E400FF8F4201B864 -:1099C0000440FFFE00034C00012438253C086000E1 -:1099D00000E820253C031000AF450180AF4601841C -:1099E000AF44018803E00008AF4301B88F86001C34 -:1099F0003C096012352700108CCB00043C0C600E33 -:109A000035850010316A00062D480001ACE800C41D -:109A10008CC40004ACA431808CC2000894C3000242 -:109A2000ACA2318403E00008A78300E43C030800F3 -:109A30008C6300508F8400E88F86001C2402FF8016 -:109A40000064C0210302C824AF5900288CCD000453 -:109A50003305007F00BA78213C0E000C01EE28216E -:109A6000ACAD00588CC80008AF8500D03C07601230 -:109A7000ACA8005C8CCC001034E80010ACAC000C3E -:109A80008CCB000CACAB000894AA00143C0208007C -:109A90008C42004425490001A4A9001494A4001498 -:109AA0003083FFFF106200178F8400D03C0A08004B -:109AB0008D4A0040A4AA00128CCE0018AC8E00245F -:109AC0008CCD0014AC8D00208CC70018AC87002C06 -:109AD0008CCC001424060001AC8C00288D0B00BC3B -:109AE0005166001A8D0200B48D0200B8A482003ABB -:109AF000948F003AA48F003C948800D403E00008BF -:109B00003102FFFF3C0908008D290024A4A00014A5 -:109B10008F8400D0A4A900128CCE0018AC8E002433 -:109B20008CCD0014AC8D00208CC70018AC87002CA5 -:109B30008CCC001424060001AC8C00288D0B00BCDA -:109B40005566FFEA8D0200B88D0200B4A482003A87 -:109B5000948F003AA48F003C948800D403E000085E -:109B60003102FFFF8F86001C3C0C08008D8C0050DA -:109B7000240BFF808CCD00083C03000C000D51C06D -:109B8000018A4021010B4824AF8A00E8AF49002830 -:109B900090C700073105007F00BA1021004328213B -:109BA00030E400041080002FAF8500D090CF000774 -:109BB00031EE000811C0003C000000008CD9000C00 -:109BC0008CC400140324C02B1300002600000000E6 -:109BD0008CC2000CACA200648CCD00182402FFF8EB -:109BE000ACAD00688CCC0010ACAC00808CCB000C11 -:109BF000ACAB00848CCA001CACAA007C90A900BC51 -:109C000001224024A0A800BC90C3000730670008D0 -:109C100010E000048F8500D090AF00BC35EE00014D -:109C2000A0AE00BC90D90007333800011300000F2C -:109C30008F8400D024070020908200BC34490002A9 -:109C4000A08900BC8F8400D090880062310300F0AE -:109C500014670006240A0034AC8A00C00A0013B25C -:109C6000000000000A00138C8CC2001490CB000787 -:109C70003166000210C0000500000000908D00BC9D -:109C800035AC0004A08C00BC8F8400D090980113E8 -:109C9000330F003FA08F01138F8E00D095C500D4E5 -:109CA00003E0000830A2FFFFACA000640A00138D9F -:109CB0000000000027BDFFD8AFB000108F90001C3F -:109CC000AFBF0024AFB40020AFB20018AFB1001492 -:109CD000AFB3001C9613000E3C07600A3C146006EC -:109CE0003264FFFF369300100E0012DF34F40410CC -:109CF0008F8400D43C11600E0E0009BB3631001079 -:109D0000920E00153C0708008CE700603C126012C0 -:109D100031CD000FA38D00F08E0E00048E0D0008D3 -:109D200096080012961F00109619001A9618001E29 -:109D3000960F001C310CFFFF33EBFFFF332AFFFFB0 -:109D40003309FFFF31E6FFFF3C010800AC2B004068 -:109D50003C010800AC2C00243C010800AC2A004463 -:109D6000AE293178AE26317C92020015960300169A -:109D700036520010304400FF3065FFFF3C060800FB -:109D80008CC60064AE243188AE4500B4920800143D -:109D900096190018241F0001011FC004332FFFFF74 -:109DA0003C0508008CA50058AE5800B8AE4F00BC6A -:109DB000920C0014AF8E00D8AF8D00DC318B00FF09 -:109DC000AE4B00C0920A0015AE670048AE66004C6C -:109DD000314900FFAE4900C8AE65007C3C03080075 -:109DE0008C6300503C0408008C84004C3C08080044 -:109DF0008D0800543C0208008C42005C8FBF002498 -:109E0000AE6300808FB00010AE8300748FB3001C6F -:109E1000AE22319CAE4200DCAE2731A0AE2631A48A -:109E2000AE24318CAE233190AE283194AE253198DA -:109E3000AE870050AE860054AE8500708FB100141E -:109E4000AE4700E0AE4600E4AE4400CCAE4300D0E6 -:109E5000AE4800D4AE4500D88FB400208FB20018B1 -:109E600003E0000827BD002827BDFFE0AFB10014C4 -:109E7000AFBF0018241100010E000865AFB000103C -:109E800010510005978400E6978300CC0083102BC7 -:109E9000144000088F8500D4240700028FBF0018EB -:109EA0008FB100148FB0001000E0102103E0000813 -:109EB00027BD00200E000C9A24040005AF8200E8A4 -:109EC0001040FFF6240700020E0008698F90001C66 -:109ED000979F00E68F9900E88F8D00C827EF00015B -:109EE000240E0050AF590020A78F00E6A1AE00005D -:109EF0003C0C08008D8C00648F8600C8240A80000A -:109F0000000C5E00ACCB0074A4C0000694C9000A2B -:109F1000241FFF803C0D000C012AC024A4D8000A95 -:109F200090C8000A24182000011F1825A0C3000AA9 -:109F30008F8700C8A0E000788F8500C80000382116 -:109F4000A0A000833C0208008C4200508F8400E8EF -:109F50000044782101FFC824AF590028960B000265 -:109F600031EE007F01DA6021018D3021A4CB00D4D5 -:109F7000960A0002AF8600D03C0E00042549240159 -:109F8000A4C900E68E080004ACC800048E030008D3 -:109F9000ACC30000A4C00010A4C00014A0C000D036 -:109FA0008F8500D02403FFBFA0A000D13C0408008F -:109FB0008C8400648F8200D0A04400D28E1F000CDD -:109FC0008F8A00D0978F00E4AD5F001C8E190010BF -:109FD00024100030AD590018A5400030A5510054A0 -:109FE000A5510056A54F0016AD4E0068AD58008033 -:109FF000AD580084914D006231AC000F358B0010DC -:10A00000A14B00628F8600D090C900633128007F89 -:10A01000A0C800638F8400D02406FFFF90850063F2 -:10A0200000A31024A08200638F9100D000E01021D3 -:10A03000923F00BC37F90001A23900BC8F8A00D0E2 -:10A04000938F00F0AD580064AD5000C0914E00D326 -:10A05000000F690031CC000F018D5825A14B00D3B2 -:10A060008F8500D08F8900DCACA900E88F8800D8EC -:10A070008FBF00188FB100148FB0001027BD0020D3 -:10A08000ACA800ECA4A600D6A4A000E0A4A000E226 -:10A0900003E000080000000027BDFFE0AFB00010A3 -:10A0A0008F90001CAFB10014AFBF00188E190004D0 -:10A0B0003C1808008F180050240FFF80001989C039 -:10A0C0000238702131CD007F01CF602401BA5021C8 -:10A0D0003C0B000CAF4C0028014B4021950900D4EB -:10A0E000950400D68E0700043131FFFFAF8800D001 -:10A0F0000E000933000721C08E0600048F8300C8BC -:10A10000000629C0AF4500209064003E3082004028 -:10A11000144000068F8400D0341FFFFF948300D6C4 -:10A120003062FFFF145F000400000000948400D63A -:10A130000E0008C83084FFFF8E0500040220302185 -:10A140008FBF00188FB100148FB0001024040022BC -:10A1500000003821000529C00A00130327BD002094 -:10A1600027BDFFE0AFB100143091FFFFAFB000108A -:10A17000AFBF00181220001D000080218F86001C38 -:10A180008CC500002403000600053F0200051402F0 -:10A1900030E4000714830015304500FF2CA80006AA -:10A1A0001100004D000558803C0C0800258C5A0019 -:10A1B000016C50218D4900000120000800000000C2 -:10A1C0008F8E00EC240D000111CD0059000000001D -:10A1D000260B00013170FFFF24CA00200211202B42 -:10A1E000014030211480FFE6AF8A001C02001021DC -:10A1F0008FBF00188FB100148FB0001003E000086B -:10A2000027BD0020938700CE14E0003824040014FA -:10A210000E0013C4000000008F86001C2402000101 -:10A220000A00150BAF8200EC8F8900EC24080002B5 -:10A230001128003B240400130000282100003021D5 -:10A24000240700010E001303000000000A00150B94 -:10A250008F86001C8F8700EC2405000214E5FFF6B2 -:10A26000240400120E001370000000008F8500E827 -:10A2700000403021240400120E0013030000382196 -:10A280000A00150B8F86001C8F8300EC241F00032F -:10A29000147FFFD0260B00010E00132200000000E7 -:10A2A0008F8500E8004030212402000224040010C1 -:10A2B00000003821AF8200EC0E0013030000000004 -:10A2C0000A00150B8F86001C8F8F00EC24060002FD -:10A2D00011E6000B000000002404001000002821FB -:10A2E000000030210A001528240700010000282161 -:10A2F0000E001303000030210A00150B8F86001C8E -:10A300000E00143100000000144000128F99001C50 -:10A310008F86001C240200030A00150BAF8200EC9C -:10A320000E0014BD000000000A00150B8F86001CF3 -:10A330000E00131200000000240200022404001486 -:10A340000000282100003021000038210A001545B6 -:10A35000AF8200EC0040382124040010973800023E -:10A36000000028210E0013033306FFFF0A00150B1F -:10A370008F86001C8F8400C83C077FFF34E6FFFFF8 -:10A380008C8500742402000100A61824AC8300749C -:10A3900003E00008A082000510A000362CA2008077 -:10A3A000274A04003C0B00052409008010400007E8 -:10A3B0002408008030A6000F00C540212D03008135 -:10A3C0001460000200A0482124080080AF4B003038 -:10A3D0000000000000000000000000001100000963 -:10A3E00000003821014030218C8D000024E700045A -:10A3F00000E8602BACCD0000248400041580FFFA37 -:10A4000024C600040000000000000000000000005E -:10A410003C0E0006010E3825AF470030000000005A -:10A4200000000000000000008F4F000031E8001025 -:10A430001100FFFD000000008F42003C8F43003CF4 -:10A440000049C8210323C02B1300000400000000B2 -:10A450008F4C003825860001AF4600388F47003CFE -:10A4600000A9282300E96821AF4D003C14A0FFCECD -:10A470002CA2008003E000080000000027BDFFD0F0 -:10A480003C020002AFB100143C11000CAF45003893 -:10A49000AFB3001CAF46003C00809821AF420030B3 -:10A4A00024050088AF44002803512021AFBF0028B5 -:10A4B000AFB50024AFB40020AFB200180E00157D78 -:10A4C000AFB000103C1F08008FFF004C3C18080084 -:10A4D0008F1800642410FF8003F3A82132B9007F95 -:10A4E00002B078240018A0C0033A702100189140EF -:10A4F00001D12021AF4F00280E00157D02542821E4 -:10A500003C0D08008DAD00502405012001B35821F9 -:10A51000316C007F01705024019A482101312021C3 -:10A520000E00157DAF4A00283C0808008D08005435 -:10A530003C0508008CA500640113382130E6007F3B -:10A5400000F0182400DA202100912021AF430028D8 -:10A550000E00157D000529403C0208008C42005881 -:10A560003C1008008E1000601200001C005388216F -:10A570002415FF800A0016003C14000C3226007FD0 -:10A580000235182400DA202102402821AF43002898 -:10A59000009420210E00157D2610FFC01200000F30 -:10A5A000023288212E05004110A0FFF42412100071 -:10A5B0003226007F001091800235182400DA202115 -:10A5C00002402821AF430028009420210E00157D71 -:10A5D000000080211600FFF3023288213C0B0800A6 -:10A5E0008D6B005C240AFF8024050002017340216A -:10A5F000010A4824AF4900283C0408009484006202 -:10A600003110007F021A88213C07000C0E000CCA92 -:10A610000227982100402821026020218FBF0028B6 -:10A620008FB500248FB400208FB3001C8FB20018A8 -:10A630008FB100148FB000100A00157D27BD0030C7 -:10A640008F83001C8C620004104000030000000097 -:10A6500003E00008000000008C6400108C65000816 -:08A660000A0015B68C66000C1F -:08A66800000000000000001BCF -:10A670000000000F0000000A0000000800000006B3 -:10A6800000000005000000050000000400000004B8 -:10A6900000000003000000030000000300000003AE -:10A6A00000000003000000020000000200000002A1 -:10A6B0000000000200000002000000020000000292 -:10A6C0000000000200000002000000020000000282 -:10A6D0000000000200000002000000020000000272 -:0CA6E0000000000100000001000000016B -:04A6EC0008000F58FB -:10A6F00008000DB008000FEC0800109408000F804F -:10A7000008000FC0080011CC08000DCC080011F0A3 -:10A7100008000E1C08001634080015DC08000DCCDB -:10A7200008000DCC08000DCC0800127C0800127C3B -:10A7300008000DCC08000DCC0800158008000DCCD9 -:10A7400008000DCC08000DCC08000DCC080013F05B -:10A7500008000DCC08000DCC08000DCC08000DCC75 -:10A7600008000DCC08000DCC08000DCC08000DCC65 -:10A7700008000DCC08000DCC08000DCC08000DCC55 -:10A7800008000DCC08000DCC08000FE008000DCC2F -:10A7900008000DCC0800153008000DCC08000DCCC9 -:10A7A00008000DCC08000DCC08000DCC08000DCC25 -:10A7B00008000DCC08000DCC08000DCC08000DCC15 -:10A7C00008000DCC08000DCC08000DCC08000DCC05 -:10A7D00008000DCC08000DCC08000DCC0800145C5E -:10A7E00008000DCC08000DCC08001370080012E022 -:10A7F00008002E9408002E9C08002E6408002E707D -:10A8000008002E7C08002E88080046B408003F008F -:10A8100008004634080046B4080046B4080044B4B2 -:10A82000080046B4080046FC08005524080054E41B -:10A83000080054B008005484080054600800541CF8 -:10A840000A000C7600000000000000000000000D6F -:10A85000727870352E302E306A3600000500000305 -:10A8600000000000000000010000000000000000E7 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000000000000000000000000000077 -:10D9B0000000000000000000000000000000000067 -:10D9C0000000000000000000000000000000000057 -:10D9D0000000000000000000000000000000000047 -:10D9E0000000000000000000000000000000000037 -:10D9F0000000000000000000000000000000000027 -:10DA00000000000000000000000000000000000016 -:10DA100000000000000000000000000010000003F3 -:10DA2000000000000000000D0000000D3C02080096 -:10DA3000244275803C03080024637A28AC4000002F -:10DA40000043202B1480FFFD244200043C1D0800ED -:10DA500037BD7FFC03A0F0213C100800261031D810 -:10DA60003C1C0800279C75800E0010EF0000000091 -:10DA70000000000D30A5FFFF30C600FF27430180E6 -:10DA80008F4201B80440FFFE24020002AC64000093 -:10DA9000A4650008A066000AA062000B3C0210000A -:10DAA000AC67001803E00008AF4201B83C03600017 -:10DAB0008C624FF80440FFFE3C020200AC644FC091 -:10DAC000AC624FC43C02100003E00008AC624FF8A7 -:10DAD0009482000C2486001400A038210002130256 -:10DAE000000210800082402100C8102B1040005717 -:10DAF0000000000090C300002C620009504000515B -:10DB000090C20001000310803C03080024637534B8 -:10DB1000004310218C42000000400008000000007B -:10DB200090C300012402000A1462003A00000000C1 -:10DB3000010610232C42000A1440003624C60002BD -:10DB40008CE2000034420100ACE2000090C2000010 -:10DB500090C3000190C4000290C5000300031C00A4 -:10DB60000002160000431025000422000044102586 -:10DB70000045102524C60004ACE2000490C2000059 -:10DB800090C3000190C4000290C50003000216007B -:10DB900000031C000043102500042200004410254F -:10DBA0000045102524C600040A000CAAACE20008B7 -:10DBB00090C30001240200041462001624C600026F -:10DBC00090C2000090C400018CE30000000212002B -:10DBD000004410253463000424C60002ACE2000CAB -:10DBE0000A000CAAACE3000090C300012402000369 -:10DBF0001462000824C600028CE2000090C30000FA -:10DC000024C6000134420008A0E300100A000CAA58 -:10DC1000ACE2000003E000082402000190C3000110 -:10DC2000240200021062000224C40002010020212C -:10DC30000A000CAA008030210A000CAA24C60001A8 -:10DC400090C200010A000CAA00C2302103E00008C3 -:10DC50000000102127BDFFE8AFBF0014AFB00010D7 -:10DC60000E00130E00808021936200052403FFFE46 -:10DC700002002021004310248FBF00148FB0001039 -:10DC8000A36200050A00131727BD001827BDFFE88F -:10DC9000AFB00010AFBF00140E000F0E0080802147 -:10DCA0009362000024030050304200FF144300043C -:10DCB00024020100AF4201800A000D22020020214F -:10DCC000AF400180020020218FBF00148FB00010F0 -:10DCD0000A000FAD27BD001827BDFF80AFBE00783A -:10DCE000AFB70074AFB30064AFBF007CAFB60070D5 -:10DCF000AFB5006CAFB40068AFB20060AFB1005C0C -:10DD0000AFB000588F5001289363003F9362000525 -:10DD10000000F021307300FF0002102730420001A4 -:10DD20000000B82114400066AFA0005093420116D5 -:10DD300093430112304200FF306300FF0342202171 -:10DD400003431021244540008F82001C104000181E -:10DD5000249140008F4201043C0300010043102441 -:10DD600010400013000000008CA3000C8F620030F4 -:10DD7000146201B5240200018CA300108F62002CF4 -:10DD8000146201B1240200019762003A94834000BA -:10DD90003042FFFF146201AC240200019762003898 -:10DDA000962300023042FFFF146201A72402000103 -:10DDB00093620000304300FF24020020106200053F -:10DDC0002402005010620006000000000A000D6CE2 -:10DDD000000000000000000D0A000D75AFA000302B -:10DDE0003C1E080027DE75E80A000D75AFA0003064 -:10DDF0003C0208008C4200DC244200013C01080087 -:10DE0000AC2200DC0E0013D8000000000A000F0353 -:10DE10008FBF007C8F4201043C0300209234000D30 -:10DE2000004310240002202B00042140AFA4003046 -:10DE30008F4301043C020040006218241460000279 -:10DE4000348700400080382132820020AFA70030A4 -:10DE50001440000234E6008000E0302110C0000BC6 -:10DE6000AFA6003093C500088F67004C0200202148 -:10DE700000052B0034A5008130A5F0810E000C8D2B -:10DE800030C600FF0A000F00000000009362003E51 -:10DE9000304200401040000E24020004566200068A -:10DEA00024020012020020210E0014E6022030217C -:10DEB0000A000F038FBF007C1662000500000000FF -:10DEC0000E000D13000020210A000F038FBF007CFD -:10DED0009743011A9624000E9362003532850004A0 -:10DEE0003076FFFF00442004AFA400548E320004BB -:10DEF00010A000158E3500089362003E30420040AD -:10DF000010400007000000000E00142802402021ED -:10DF10001040000D000000000A000F00000000008B -:10DF20008F620044024210230440014500000000BB -:10DF30008F6200480242102304410141240400166C -:10DF40000A000E038FC200048F62004802421023B1 -:10DF500004400008000000003C0208008C42310030 -:10DF6000244200013C010800AC2231000A000EF5F9 -:10DF7000000000008F620040024210231840000998 -:10DF80002402000C3C0208008C423100329400FC58 -:10DF90000000B021244200013C010800AC22310005 -:10DFA0002402000CAFA200308F62004000522023F8 -:10DFB0001880000D02C4102A144001160000000051 -:10DFC0001496000602C410233A8200013042000178 -:10DFD000144001100000000002C4102302449021EC -:10DFE0000A000DEB3056FFFF0000202132820002B4 -:10DFF0001040001A328200109362003E304200400E -:10E00000504000118FC200040E00130E02002021A8 -:10E0100024020018A362003F936200052403FFFE60 -:10E0200002002021004310240E001317A3620005F4 -:10E0300024040039000028210E00141124060018C1 -:10E040000A000F0224020001240400170040F8090E -:10E05000000000000A000F0224020001104000F836 -:10E06000000000008F63004C8F62005402A2102356 -:10E070001C4000F302A31023044200010060A82109 -:10E08000AFA40018AFB20010AFB600149342012045 -:10E090008F6500409763003C304200FF034210212F -:10E0A000004410218FA400543063FFFF244240003D -:10E0B0000083182B8FA40030AFA20020AFA500284A -:10E0C00000832025AFA40030AFA50024AFA0002C12 -:10E0D000AFB500349362003E30420008504000115A -:10E0E0008FC200000220202127A500380E000CA4BA -:10E0F000AFA000385440000B8FC200008FA2003840 -:10E1000030420100504000078FC200008FA3003C46 -:10E110008F6200600062102304430001AF6300605F -:10E120008FC200000040F80927A400108FA2003021 -:10E130003042000254400001329400FE9362003EDF -:10E1400030420040104000378FA300148F6200540B -:10E1500016A2001A3282000124020014126200107A -:10E160002A62001510400006240200162402000C4A -:10E1700012620007328200010A000E5F00000000F8 -:10E1800012620005328200010A000E5F00000000EA -:10E190000A000E5A2417000E0A000E5A2417001007 -:10E1A0000A000E5E24170012936200232403FFBDB1 -:10E1B00000431024A36200233282000110400019A2 -:10E1C0008FA300142402000C1262000E2A62000DBC -:10E1D000104000062402000E2402000A126200070A -:10E1E0008FA200240A000E77244200011262000868 -:10E1F0008FA200240A000E77244200010A000E7547 -:10E20000241700082402000E16E20002241700164C -:10E21000241700108FA2002424420001AFA2002482 -:10E220008FA300148FA200248F730040004310219D -:10E23000AF6200408FA20054936400368F630040A9 -:10E2400002A288213402FFFF00821004006218211C -:10E25000AF6300488FA6003030C200081040000EA7 -:10E26000000000008F6200581622000430C600FF34 -:10E270009742011A5040000134C6001093C50008AF -:10E280008FA700340200202100052B0034A5008058 -:10E290000E000C8D30A5F0808F62004000531023DB -:10E2A000184000178FA200183C0208008C423198D9 -:10E2B00030420010104000092402000197620068FB -:10E2C0001440000624020001A76200689742007A09 -:10E2D0002442000A0A000EBBA7620012A7620012C5 -:10E2E0000E00130E020020219362007D2403000122 -:10E2F00002002021344200010A000EB9AFA30050F1 -:10E300001840000A000000000E00130E0200202139 -:10E310009362007D2403000102002021AFA300507E -:10E32000344200040E001317A362007D9362003E86 -:10E33000304200401440000C328200011040000ABC -:10E34000000000008F6300408FC200042404001806 -:10E35000246300010040F809AF6300408FA2003041 -:10E360000A000F02304200048F6200581051001062 -:10E37000000000008F620018024210231C400008B9 -:10E38000240400018F6200181642000900000000FA -:10E390008F62001C02A21023044000050000000050 -:10E3A000AF710058AFA40050AF720018AF75001CD9 -:10E3B00012E0000B8FA200500E00130E020020216D -:10E3C000A377003F0E0013170200202102E0302146 -:10E3D000240400370E001411000028218FA20050E1 -:10E3E00010400003000000000E000C9B02002021E2 -:10E3F00012C00005000018218FA200303042000436 -:10E400005040001100601021240300010A000F0297 -:10E41000006010210E00130E020020219362007D87 -:10E4200002002021344200040E001317A362007D75 -:10E430000E000C9B020020210A000F0224020001A2 -:10E44000AF400044240200018FBF007C8FBE0078E3 -:10E450008FB700748FB600708FB5006C8FB40068F2 -:10E460008FB300648FB200608FB1005C8FB0005832 -:10E4700003E0000827BD00808F4201B80440FFFE82 -:10E4800024020800AF4201B803E0000800000000C9 -:10E4900030A5FFFF30C6FFFF8F4201B80440FFFEEA -:10E4A0003C020008AF44018003421021AF44002029 -:10E4B000944200483044FFFF1080001924020003FA -:10E4C00024A200120082102B104000152402000329 -:10E4D000934201202403001AA343018B304200FF22 -:10E4E0002447FFFE8F8200000087182B386300014D -:10E4F0000002138200431024104000058F830004A3 -:10E5000034620001A74701940A000F39AF8200046A -:10E510002402FFFE006210240A000F39AF820004BB -:10E52000A342018B24020002A742018C8F820000CB -:10E530008F840004A745018EA74201908F82000CB2 -:10E5400030838000AF4201A8A74601881060000E0A -:10E550008F82000493420116304200FC24420004E2 -:10E56000005A10218C4240003042FFFF1440000648 -:10E570008F8200043C02FFFF34427FFF00821024A0 -:10E58000AF8200048F8200042403BFFF978400023F -:10E5900000431024A74201A69742010C0002140078 -:10E5A00000441025AF4201AC3C021000AF4201B85C -:10E5B00003E00008000000008F4700709342011242 -:10E5C0008F83000027BDFFF0304200FF0002288249 -:10E5D00030620100000030211040004324A40003F9 -:10E5E00030624000104000103062200000041080B3 -:10E5F000005A10218C43400024A400040004108021 -:10E60000AFA30000005A10218C424000AFA20004CA -:10E6100093420116304200FC005A10218C42400007 -:10E620000A000F86AFA200081040002F0000302122 -:10E6300000041080005A10218C43400024A40004E0 -:10E6400000041080AFA30000005A10218C4240004B -:10E65000AFA00008AFA200048FA80008000030217E -:10E6600000002021240A00083C0908002529010097 -:10E6700003A41021148A000300042A001100000AD8 -:10E680000000000090420000248400012C83000C54 -:10E6900000A2102100021080004910218C420000CD -:10E6A0001460FFF300C230263C0408008C8431045F -:10E6B0008F4200702C83002010600009004738232F -:10E6C0003C0308002463310800041080004310213B -:10E6D00024830001AC4700003C010800AC23310456 -:10E6E000AF86000C2406000100C0102103E00008E2 -:10E6F00027BD00103C0208008C42003827BDFFD027 -:10E70000AFB60028AFB40020AFB20018AFBF002CE6 -:10E71000AFB50024AFB3001CAFB10014AFB0001010 -:10E72000000090213C16080026D600381440000254 -:10E730002454FFFF0000A0219742010E8F840000A7 -:10E740003042FFFF308340001060000A2453000471 -:10E750003C020020008210245040000730828000DC -:10E760008F8200042403BFFF008318240A000FD700 -:10E7700034421000308280001040000A3C02002029 -:10E7800000821024104000078F8200043C03FFFF2A -:10E7900034637FFF0083182434428000AF8200047A -:10E7A000AF8300000E000F5E000000001440000761 -:10E7B000000000009743011E9742011C3063FFFFD9 -:10E7C0000002140000621825AF83000C9742010C70 -:10E7D0008F4340003046FFFF3402FFFF1462000306 -:10E7E000000000000A000FEF241200208F424000BA -:10E7F0003042010054400001241200108F840000B8 -:10E800003082100050400014365200013082002047 -:10E810001440000B3C021000008210245040000EF7 -:10E82000365200013C030E003C020DFF0083182409 -:10E830003442FFFF0043102B5040000736520001C6 -:10E840003C0208008C42002C244200013C010800DC -:10E85000AC22002C365200053C0508008CA5003483 -:10E8600054A000408F8400008F8200105440003D6F -:10E870008F8400008F8200043042400054400039F1 -:10E880008F8400003C021F01008210243C03100012 -:10E89000144300348F84000030C202001440003260 -:10E8A0003C0200013265FFFF364600028F4201B88C -:10E8B0000440FFFE3C020008AF40018003421021EB -:10E8C000944200483043FFFF10600019AF830008F6 -:10E8D00024A200120062102B104000162402000334 -:10E8E000934201202403001AA343018B304200FF0E -:10E8F0002443FFFE8F820000304240001040000899 -:10E900008F8200048F8200080043102B1440000403 -:10E910008F820004A74301940A00103A3442000198 -:10E920002403FFFE004310240A00103EAF820004BF -:10E9300024020003A342018B8F8300042402BFFF43 -:10E940000062182424020002A742018C8F8200007A -:10E95000A745018EA7460188A74301A60A0010D942 -:10E96000A74201903C020001008210241040000BDD -:10E970003C0210003C0208008C4200D89745010E72 -:10E98000240400802442000130A5FFFF3C01080060 -:10E99000AC2200D80A0010E22406000300821024F2 -:10E9A00010400041000000003C0208008C42003092 -:10E9B0001040000C8F8200043042400010400009DB -:10E9C0003C030F00008318243C0201000043102B7D -:10E9D00014400004364600023265FFFF0A0010E2D0 -:10E9E0002404008010A0000D308201001040000BB4 -:10E9F0003C020F00008210243C0302001043000779 -:10EA00008F82000C00541024005610219042000404 -:10EA1000244200040A001097000221C000000000F8 -:10EA20008F8600003C0508008CA500D00006160269 -:10EA30003050000F38A200012C4200012E03000CC0 -:10EA40000043102414400015001021C02602FFFCD2 -:10EA50002C420004544000110000202138A2000282 -:10EA60002C42000100431024104000030006124213 -:10EA70000A001097000020210010182B00431024DA -:10EA800050400006001021C0000020213265FFFF29 -:10EA90000E000F143246FFFB001021C03265FFFF4D -:10EAA0000A0010E2364600028F4240003C11080086 -:10EAB0008E310024304201001040003E322200011D -:10EAC0000220802110A00014325500043082010081 -:10EAD00010400012240200013C020F0000821024AA -:10EAE0003C0302001043000C8F82000C02403021D6 -:10EAF0003265FFFF0054102400561021904400049A -:10EB00003252FFFB248400040E000F14000421C0C5 -:10EB10002402FFFE022280242402000116020007C4 -:10EB2000320200013242000450400001365200021D -:10EB30003265FFFF0A0010E102403021104000075B -:10EB40003202000402403021000020210E000F1488 -:10EB50003265FFFF3252FFFB320200041040000713 -:10EB60008F82000030420800104000043265FFFF31 -:10EB7000024030210E000F142404010016A00015DD -:10EB80008FBF002C274301808F4201B80440FFFE55 -:10EB900024022000A462000824020002A062000BEC -:10EBA000A46000103C021000AF4201B80A0010E55A -:10EBB0008FBF002C104000078FBF002C3265FFFF75 -:10EBC00036460002000020210E000F140000000055 -:10EBD0008FBF002C8FB600288FB500248FB4002083 -:10EBE0008FB3001C8FB200188FB100148FB00010CB -:10EBF0000000102103E0000827BD003027BDFFC83A -:10EC0000AFB000103C04600CAFBF0030AFB7002CB9 -:10EC1000AFB60028AFB50024AFB40020AFB3001CDE -:10EC2000AFB20018AFB100148C8250002403FF7FF4 -:10EC30003C1A8000004310243442380CAC8250004F -:10EC4000240200033C106000AF4200088E02080856 -:10EC50003C1B80083C010800AC2000203042FFF043 -:10EC6000384200102C4200010E001C46AF82001CEE -:10EC70003C04FFFF3C020400348308063442000CCD -:10EC8000AE021948AE03194C3C0560168E0219807D -:10EC90008CA300003442020000641824AE021980E4 -:10ECA0003C0253531462000334A47C008CA2000481 -:10ECB000005020218C82007C8C830078AF82001869 -:10ECC000AF8300143C028000344200708C4300008B -:10ECD00000403821AF830020006030218CE8000024 -:10ECE0003C0508008CA500FC3C0408008C8400F85E -:10ECF000010630230000102100A6282100A6302B99 -:10ED000000822021008620213C010800AC2500FC67 -:10ED10003C010800AC2400F88F56000032C200030A -:10ED20001040FFEE010030218CE600003C05080099 -:10ED30008CA500FC3C0408008C8400F800C830233B -:10ED400000A628210000102100A6302B00822021DF -:10ED50000086202132C700013C010800AC2500FCE0 -:10ED6000AF8800203C010800AC2400F810E0016BE3 -:10ED700032C200028F4301283C02000803421021E6 -:10ED8000AF4300208F4301048F44010094420048A8 -:10ED9000AF830000AF8400043042FFFF0E000F0E6F -:10EDA000AF8200083C0208008C4200C010400008FE -:10EDB0008F8400003C0208008C4200C42442000101 -:10EDC0003C010800AC2200C40A0012AF00000000A1 -:10EDD0003C02001000821024144001358F8300048F -:10EDE0003C0208008C4200203C0308008C63003881 -:10EDF00000009021244200013C010800AC220020C8 -:10EE00003C17080026F70038146000022474FFFF46 -:10EE10000000A0219742010E308340003042FFFFE6 -:10EE20001060000A245300043C02002000821024D9 -:10EE300050400007308280008F8200042403BFFF0F -:10EE4000008318240A00118D3442100030828000A3 -:10EE50001040000A3C0200200082102410400007ED -:10EE60008F8200043C03FFFF34637FFF008318247C -:10EE700034428000AF820004AF8300000E000F5EBA -:10EE80000000000014400007000000009743011E2E -:10EE90009742011C3063FFFF000214000062182536 -:10EEA000AF83000C9742010C8F4340003046FFFFB8 -:10EEB0003402FFFF14620003000000000A0011A5E5 -:10EEC000241200208F4240003042010054400001D3 -:10EED000241200108F840000308210005040001473 -:10EEE00036520001308200201440000B3C0210001A -:10EEF000008210245040000E365200013C030E00E8 -:10EF00003C020DFF008318243442FFFF0043102B06 -:10EF100050400007365200013C0208008C42002C91 -:10EF2000244200013C010800AC22002C36520005AE -:10EF30003C0508008CA5003454A000408F840000DC -:10EF40008F8200105440003D8F8400008F820004A7 -:10EF500030424000544000398F8400003C021F01C1 -:10EF6000008210243C031000144300348F840000FE -:10EF700030C20200144000323C0200013265FFFF43 -:10EF8000364600028F4201B80440FFFE3C020008F2 -:10EF9000AF40018003421021944200483043FFFFFC -:10EFA00010600019AF83000824A200120062102B29 -:10EFB0001040001624020003934201202403001A8B -:10EFC000A343018B304200FF2443FFFE8F820000E9 -:10EFD00030424000104000088F8200048F820008F9 -:10EFE0000043102B144000048F820004A7430194B7 -:10EFF0000A0011F0344200012403FFFE00431024F4 -:10F000000A0011F4AF82000424020003A342018B22 -:10F010008F8300042402BFFF006218242402000230 -:10F02000A742018C8F820000A745018EA746018868 -:10F03000A74301A60A00128FA74201903C020001DB -:10F04000008210245040000B3C0210003C020800DB -:10F050008C4200D89745010E240400802442000110 -:10F0600030A5FFFF3C010800AC2200D80A0012982E -:10F07000240600030082102410400041000000001C -:10F080003C0208008C4200301040000C8F820004CB -:10F0900030424000104000093C030F000083182458 -:10F0A0003C0201000043102B1440000436460002CD -:10F0B0003265FFFF0A0012982404008010A0000DA2 -:10F0C000308201001040000B3C020F00008210242F -:10F0D0003C030200104300078F82000C00541024F0 -:10F0E0000057102190420004244200040A00124DEF -:10F0F000000221C0000000008F8600003C050800CF -:10F100008CA500D0000616023050000F38A2000176 -:10F110002C4200012E03000C004310241440001563 -:10F12000001021C02602FFFC2C42000454400011B4 -:10F130000000202138A200022C42000100431024CC -:10F1400050400003000612420A00124D0000202128 -:10F150000010182B0043102450400006001021C05E -:10F16000000020213265FFFF0E000F143246FFFB26 -:10F17000001021C03265FFFF0A00129836460002D7 -:10F180008F4240003C1108008E31002430420100C3 -:10F190001040003E322200010220802110A0001405 -:10F1A0003255000430820100104000122402000198 -:10F1B0003C020F00008210243C0302001043000CAC -:10F1C0008F82000C024030213265FFFF0054102472 -:10F1D00000571021904400043252FFFB24840004A5 -:10F1E0000E000F14000421C02402FFFE022280241E -:10F1F000240200011602000732020001324200041C -:10F2000050400001365200023265FFFF0A0012979B -:10F210000240302110400007320200040240302139 -:10F22000000020210E000F143265FFFF3252FFFB59 -:10F2300032020004104000078F82000030420800B4 -:10F24000104000043265FFFF024030210E000F1411 -:10F250002404010016A0002E3C0240002743018038 -:10F260008F4201B80440FFFE24022000A46200087F -:10F2700024020002A062000BA46000103C021000F7 -:10F28000AF4201B80A0012B43C02400050400020D6 -:10F290003C0240003265FFFF36460002000020219C -:10F2A0000E000F14000000000A0012B43C024000DF -:10F2B0002402BFFF0062102410400008000000007C -:10F2C000240287FF00621024144000083C02006002 -:10F2D0000082102410400005000000000E000D26E2 -:10F2E000000000000A0012AD000000000E0012F83D -:10F2F00000000000104000063C0240008F43012443 -:10F300003C026020AC430014000000003C024000BE -:10F31000AF4201380000000032C200021040FE6A15 -:10F320003C0280008F4201403C044000AF4200207C -:10F330008F4301483C027000006218241064002DC5 -:10F34000000000000083102B144000063C02600007 -:10F350003C022000106200073C0240000A0012F448 -:10F360000000000010620027000000000A0012F4F4 -:10F370003C0240008F4201482403000400021402B2 -:10F38000304200FF1443000B274401808F430140AB -:10F390008F4201B80440FFFE2402001CAC83000031 -:10F3A000A082000B3C021000AF4201B80A0012F428 -:10F3B0003C0240008F4201B80440FFFE0000000004 -:10F3C0008F42014800021402A482000824020002B5 -:10F3D000A082000B8F420148A48200108F4201449A -:10F3E000AC8200243C021000AF4201B80A0012F4C3 -:10F3F0003C0240000E00131C000000000A0012F442 -:10F400003C0240000E001C53000000003C02400083 -:10F41000AF420178000000000A0011223C02800087 -:10F420008F4201003042003E1440001124020001CE -:10F43000AF4000488F420100304207C01040000535 -:10F4400000000000AF40004CAF40005003E0000857 -:10F4500024020001AF400054AF4000408F42010041 -:10F460003042380054400001AF4000442402000103 -:10F4700003E00008000000003C029000344200015C -:10F4800000822025AF4400208F4200200440FFFE70 -:10F490000000000003E00008000000003C028000C3 -:10F4A000344200010082202503E00008AF44002020 -:10F4B00027BDFFE0AFB20018AFBF001CAFB1001412 -:10F4C000AFB000108F5001408F5101483C028000C6 -:10F4D0000011940202222024324300FF2402000E75 -:10F4E0001062008A2862000F104000122862003764 -:10F4F000240200061062003B28620007104000074B -:10F50000240200091060001A240200011062002584 -:10F51000000000000A0013D1000000001062007B10 -:10F520002402000B1062005B3222FFFF0A0013D19D -:10F530000000000010400008240200382862003556 -:10F54000104000802402001F1062007E00000000B6 -:10F550000A0013D1000000001062007A240200802B -:10F5600010620042000000000A0013D100000000F9 -:10F570008F4201B80440FFFE24020001AF50018019 -:10F58000AF400184A7520188A342018A24020002ED -:10F59000A342018BA75101908F4201440A0013CC72 -:10F5A000AF4201A41080000A240200023C010800BE -:10F5B000A02275D83C010800AC3075E08F420144B0 -:10F5C0003C010800AC2275DC0A0013D38FBF001C7D -:10F5D0008F4201B80440FFFE240200020A0013B665 -:10F5E000000000008F4201B80440FFFE0000000050 -:10F5F000AF5001803C020800904275D810400003D3 -:10F60000000018213C0308008C6375E0AF430184BF -:10F61000A75201883C020800904275D800001821CA -:10F6200034420001A342018A24020002A342018B5A -:10F63000A75101908F420144AF4201A43C0208004F -:10F64000904275D8104000033C0210003C030800B3 -:10F650008C6375DCAF4301A8AF4201B83C010800E0 -:10F66000A02075D80A0013D38FBF001C8F4201B8A9 -:10F670000440FFFE24020002A342018BA75201882E -:10F68000A75101908F420144A74201920A0013CE74 -:10F690003C0210001440001D0000000093620005B1 -:10F6A0003042000414400037000000000E00130E2A -:10F6B0000200202193620005020020213442000450 -:10F6C0000E001317A3620005936200053042000488 -:10F6D00014400002000000000000000D93620000D2 -:10F6E00024030020304200FF144300080000000003 -:10F6F0008F4201B80440FFFE24020005AF50018094 -:10F70000A342018B3C021000AF4201B88F4201B806 -:10F710000440FFFE24020002AF400180AF5001848C -:10F72000A7520188A342018AA342018BA7510190ED -:10F73000AF4001A48F420144AF4201A80A0013CE9A -:10F740003C0210008F4201B80440FFFE2402000179 -:10F75000AF500180AF400184A7520188A342018AC3 -:10F7600024020002A342018BA7510190AF4001A4E3 -:10F77000AF4001A83C021000AF4201B80A0013D309 -:10F780008FBF001C0000000D8FBF001C8FB200183F -:10F790008FB100148FB0001003E0000827BD0020D7 -:10F7A00027BDFFE8AFBF00100E000F0E00000000E5 -:10F7B000AF4001808FBF0010000020210A000FAD74 -:10F7C00027BD00183084FFFF30A5FFFF000018217F -:10F7D000108000070000000030820001104000028D -:10F7E00000042042006518210A0013E400052840A7 -:10F7F00003E000080060102110C0000624C6FFFFCF -:10F800008CA2000024A50004AC8200000A0013EEC4 -:10F810002484000403E000080000000010A0000899 -:10F8200024A3FFFFAC8600000000000000000000E1 -:10F830002402FFFF2463FFFF1462FFFA2484000404 -:10F8400003E000080000000027BDFFE8AFBF001480 -:10F85000AFB000100E00130E008080219362007D77 -:10F8600002002021344200200E001317A362007D05 -:10F87000020020218FBF00148FB000100A000C9BE3 -:10F8800027BD0018308300FF30A500FF30C600FF01 -:10F89000274701808F4201B80440FFFE00000000AE -:10F8A0008F42012834634000ACE2000024020001D2 -:10F8B000ACE00004A4E30008A0E2000A2402000275 -:10F8C000A0E2000B3C021000A4E50010ACE0002414 -:10F8D000ACE00028A4E6001203E00008AF4201B843 -:10F8E00027BDFFE8AFBF00109362003F2403001262 -:10F8F000304200FF1043000D008030218F62004431 -:10F90000008210230440000A8FBF00108F6200485D -:10F91000240400390000282100C2102304410004FF -:10F92000240600120E001411000000008FBF00100A -:10F930002402000103E0000827BD001827BDFFC80E -:10F94000AFB1002C00A08821AFB2003027A5001075 -:10F950000080902102202021AFBF0034AFB00028EA -:10F960000E000CA4AFA0001010400009024020219E -:10F970008E220008AF6200840E001402AF600040C7 -:10F98000240400382405008D0A0014DD240600122A -:10F990009362003E304200081040000F8FA200101A -:10F9A00030420100104000078FA300148F620060F6 -:10F9B0000062102304430008AF6300600A0014666D -:10F9C00000000000AF6000609362003E2403FFF778 -:10F9D00000431024A362003E9362003E30420008C0 -:10F9E000144000022406000300003021936200341A -:10F9F000936300378F640084304200FF306300FF60 -:10FA000000661821000318800043282100A4202B41 -:10FA10001080000B000000009763003C8F620084A0 -:10FA20003063FFFF004510230062182B14600004B0 -:10FA3000000000008F6200840A00148200458023C9 -:10FA40009762003C3050FFFF8FA30010306200042B -:10FA500010400004000628808FA2001C0A00148AAF -:10FA60000202102B2E02021850400003240202183A -:10FA70000A00149302051023306300041060000391 -:10FA8000004510238FA2001C004510230040802158 -:10FA90002C42008054400001241000800E00130E00 -:10FAA0000240202124020001AF62000C9362003E5C -:10FAB000001020403042007FA362003E8E220004EE -:10FAC00024420001AF620040A770003C8F620050EA -:10FAD0009623000E00431021AF6200588F62005041 -:10FAE00000441021AF62005C8E220004AF62001857 -:10FAF0008E220008AF62001C8FA200103042000866 -:10FB00005440000A93A20020A3600036936200369E -:10FB10002403FFDFA36200359362003E00431024FC -:10FB2000A362003E0A0014BD8E220008A3620035C5 -:10FB30008E220008AF62004C8F6200248F63004069 -:10FB400000431021AF62004893620000240300507C -:10FB5000304200FF144300122403FF803C020800DF -:10FB60008C4231A00242102100431024AF420028F1 -:10FB70003C0208008C4231A08E2400083C03000C9B -:10FB8000024210213042007F034210210043102125 -:10FB9000AC4400D88E230008AF820028AC4300DCC0 -:10FBA0000E001317024020212404003800002821F1 -:10FBB0002406000A0E001411000000008FBF00345C -:10FBC0008FB200308FB1002C8FB0002824020001CA -:10FBD00003E0000827BD003827BDFFE8AFBF0010D5 -:10FBE00090C7000D00C0282130E6001010C0000AA8 -:10FBF00030E200058CA300088F62005410620006FA -:10FC000030E20005144000178FBF001000002021D3 -:10FC10000A000D1327BD00181040000D30E300123C -:10FC200010C000108FBF00108CA300088F6200541A -:10FC30001462000D24020001240400382405008D04 -:10FC40000E001411240600120A0015098FBF0010BF -:10FC500024020012146200038FBF00100A00143F38 -:10FC600027BD00182402000103E0000827BD00188A -:10FC700027BDFFF827420180AFA20000308A00FFB5 -:10FC80008F4201B80440FFFE000000008F460128AB -:10FC90003C0208008C4231A02403FF80AF86005054 -:10FCA00000C2102100431024AF4200243C0208008F -:10FCB0008C4231A08FA900008FA8000000C2102143 -:10FCC0003042007F034218213C02000A00621821E2 -:10FCD000946400D48FA700008FA5000024020002C6 -:10FCE000AF830028A0A2000B8FA300003542600064 -:10FCF0003084FFFFA4E200083C021000AD260000A3 -:10FD0000AD040004AC60002427BD0008AF4201B878 -:10FD100003E00008240200018C8200048F83002885 -:10FD200000451023AC820004906200633042007FE3 -:10FD3000A06200638C820020938300308F850028AE -:10FD400034420002AF830044A7800042AC8200200E -:10FD5000A4A000E490A200632403FFBF004310248A -:10FD600003E00008A0A20063274301808F4201B88E -:10FD70000440FFFE8F820050AC6200008F420124DD -:10FD8000AC62000424026083A46200082402000222 -:10FD9000A062000B3C02100003E00008AF4201B873 -:10FDA0008F880044938200308F8300283C0708002E -:10FDB00024E779F400481023304200FF304900FC6A -:10FDC000246500888F860048304A0003112000090E -:10FDD00000002021248200048CA30000304400FF96 -:10FDE0000089102AACE3000024A500041440FFF9A8 -:10FDF00024E70004114000090000202124820001B2 -:10FE000090A30000304400FF008A102BA0E3000004 -:10FE100024A500011440FFF924E7000130C20003CB -:10FE2000144000048F850044310200031040000D8F -:10FE30000000000010A00009000020212482000121 -:10FE400090C30000304400FF0085102BA0E30000A9 -:10FE500024C600011440FFF924E7000103E0000874 -:10FE6000000000001100FFFD00002021248200049A -:10FE70008CC30000304400FF0088102BACE300006E -:10FE800024C600041440FFF924E7000403E000083E -:10FE9000000000008F8300449382003030C600FFD2 -:10FEA00030A500FF00431023304300FF8F8200285D -:10FEB000008038210043102114C00002244800882B -:10FEC0000083382130E200031440000530A2000313 -:10FED00014400003306200031040000D00000000D9 -:10FEE00010A00009000020212482000190E30000FE -:10FEF000304400FF0085102BA103000024E700011F -:10FF00001440FFF92508000103E00008000000008C -:10FF100010A0FFFD00002021248200048CE30000DB -:10FF2000304400FF0085102BAD03000024E70004DF -:10FF30001440FFF92508000403E000080000000059 -:10FF400027BDFFF82402FFFFAFA200000080382188 -:10FF50002405002F3C090800252975F4240800FF1A -:10FF60002406FFFF90E2000024A3FFFF0006220208 -:10FF700000C21026304200FF00021080004910210C -:10FF80008C420000306500FF24E7000114A8FFF553 -:10FF90000082302600061027AFA20004AFA20000A6 -:10FFA0000000282127A6000400C510239044000368 -:10FFB00024A2000100BD1821304500FF2CA200043E -:10FFC0001440FFF9A06400008FA2000003E00008C5 -:10FFD00027BD00080080482130AAFFFF30C600FF7F -:10FFE00030E7FFFF274801808F4201B80440FFFE41 -:10FFF0008F820050AD0200008F420124AD02000448 -:020000040001F9 -:100000008D220020A5070008A102000A2402001684 -:10001000A102000B934301208D2200088D240004CF -:10002000306300FF004310219783004200441021F9 -:100030008D250024004310233C0308008C6331A06D -:100040008F840028A502000C246300E82402FFFF2F -:10005000A50A000EA5030010A5060012AD050018A4 -:10006000AD020024948201142403FFF73042FFFF05 -:10007000AD0200288C820118AD02002C3C02100059 -:10008000AD000030AF4201B88D22002000431024A3 -:1000900003E00008AD2200208F82002830E7FFFF38 -:1000A00000804821904200D330A5FFFF30C600FFFA -:1000B0000002110030420F0000E23825274801807D -:1000C0008F4201B80440FFFE8F820050AD02000055 -:1000D0008F420124AD0200048D220020A5070008F4 -:1000E000A102000A24020017A102000B9343012081 -:1000F0008D2200088D240004306300FF004310218E -:1001000097830042004410218F840028004310236D -:100110003C0308008C6331A0A502000CA505000E6D -:10012000246300E8A5030010A5060012AD0000142A -:100130008D220024AD0200188C82005CAD02001CF0 -:100140008C820058AD0200202402FFFFAD02002483 -:10015000948200E63042FFFFAD02002894820060E6 -:10016000948300BE30427FFF3063FFFF0002120025 -:1001700000431021AD02002C3C021000AD00003005 -:10018000AF4201B8948200BE2403FFF700A2102101 -:10019000A48200BE8D2200200043102403E000084A -:1001A000AD220020274301808F4201B80440FFFEAA -:1001B00024020018AC640000A062000B8F820028AB -:1001C000944200E6A46200103C021000AC600030D3 -:1001D00003E00008AF4201B8274301808F4201B815 -:1001E0000440FFFE8F82002C9442001C3042FFFF2F -:1001F000000211C0AC62000024020019A062000BD2 -:100200003C021000AC60003003E00008AF4201B8CF -:100210008F87003430C300FF8F4201B80440FFFED7 -:100220008F82005034636000ACA200009382004CC7 -:10023000A0A200058CE20010A4A20006A4A300085E -:100240008C8200202403FFF7A0A2000A24020002EF -:10025000A0A2000B8CE20000ACA200108CE2000413 -:10026000ACA200148CE2001CACA200248CE20020A2 -:10027000ACA200288CE2002CACA2002C8C820024C2 -:10028000ACA200183C021000AF4201B88C820020E2 -:100290000043102403E00008AC8200209382004C4D -:1002A0002403000127BDFFE8004330042C42002056 -:1002B000AFB00010AFBF00142410FFFE10400005C7 -:1002C000274501803C0208008C4231900A0016A8A4 -:1002D000004610243C0208008C4231940046102451 -:1002E00014400007240600848F8300282410FFFF99 -:1002F000906200623042000F34420040A06200620F -:100300000E00167400000000020010218FBF0014C0 -:100310008FB0001003E0000827BD00188F83002C69 -:1003200027BDFFE0AFB20018AFB10014AFB00010AE -:10033000AFBF001C9062000D00A0902130D100FFE3 -:100340003042007FA062000D8F8500288E43001888 -:10035000008080218CA2007C146200052402000E23 -:1003600090A20063344200200A0016D1A0A20063CC -:100370000E001697A382004C2403FFFF1043004792 -:100380002404FFFF52200045000020218E4300007E -:100390003C02001000621024504000043C0200089F -:1003A000020020210A0016E0240200150062102439 -:1003B000504000098E450000020020212402001454 -:1003C0000E001697A382004C2403FFFF1043003356 -:1003D0002404FFFF8E4500003C02000200A210240E -:1003E000104000163C0200048F86002C8CC20014C2 -:1003F0008CC300108CC40014004310230044102B45 -:1004000050400005020020218E43002C8CC20010B9 -:1004100010620003020020210A00171124020012BA -:100420003C02000400A210245040001C00002021C7 -:10043000020020210A0017112402001300A2102438 -:10044000104000068F83002C8C6200105040001377 -:10045000000020210A00170B020020218C620010EE -:10046000504000048E42002C020020210A00171187 -:100470002402001150400009000020210200202128 -:10048000240200170E001697A382004C2403FFFFDE -:10049000104300022404FFFF000020218FBF001C36 -:1004A0008FB200188FB100148FB00010008010219F -:1004B00003E0000827BD00209383003027BDFFE044 -:1004C00024020034AFB20018AFB10014AFBF001C5B -:1004D000AFB00010008088211462000C00A09021B1 -:1004E0008F8400340E0015C08C900030120200077B -:1004F00024020005022020210E001697A382004C42 -:100500002403FFFF104300602404FFFF9242000415 -:10051000104000098F820028022020212402000CB4 -:100520000E001697A382004C2403FFFF10430056D1 -:100530002404FFFF8F820028A38000248E43000440 -:100540008C4400803C0200FF3442FFFF006218240C -:100550000083202B10800008AF83003C0220202164 -:10056000240200190E001697A382004C2403FFFFFB -:10057000104300452404FFFF978200428F87004408 -:100580008F85003C0047202310A0003AA78400423A -:100590008F86002830A200030002102390C300BC05 -:1005A0003050000300B02821000318823071000190 -:1005B0000011108000A228213C0308008C6331A0A8 -:1005C0008F8200503084FFFF0085202B00431021D4 -:1005D00010800010244200888F8400341082000DA7 -:1005E0003C033F018E420000004310243C032500E1 -:1005F0001443000630E500FF8C820000ACC2008886 -:100600008C8200100A001775ACC200980E00159578 -:1006100000003021938200248F8500288F830048BA -:10062000020238218F820044A387002494A400E4AE -:10063000006218218F82003C34841000AF83004890 -:1006400000503021A4A400E41220000EAF86004424 -:1006500024E20004A382002494A200E424C3000442 -:10066000AF83004434422000A4A200E40A001792A1 -:10067000000020218F820048AF80004400471021F5 -:10068000AF820048000020218FBF001C8FB20018ED -:100690008FB100148FB000100080102103E000081B -:1006A00027BD00208F86002827BDFFE8AFBF0014BC -:1006B000AFB0001090C2006330420020104000082C -:1006C00030A500FF8CC2007C2403FFDF2442000120 -:1006D000ACC2007C90C2006300431024A0C200633F -:1006E00010A000238F8300282750018002002821BA -:1006F0000E001674240600828F8200289042006348 -:100700003042004050400019A380004C8F830034D9 -:100710008F4201B80440FFFE8F820050AE020000FD -:1007200024026082A602000824020002A202000B3A -:100730008C620008AE0200108C62000CAE02001445 -:100740008C620014AE0200188C620018AE02002405 -:100750008C620024AE0200288C620028AE02002CBD -:100760003C021000AF4201B8A380004C8F830028E8 -:100770008FBF00148FB000109062006327BD001877 -:100780003042007FA0620063978200428F8600445F -:100790008F8500289383003000461023A7820042F3 -:1007A000A4A000E490A400638F820048AF830044BB -:1007B0002403FFBF0046102100832024AF8200489D -:1007C000A0A400638F820028A04000BD8F82002873 -:1007D00003E00008A44000BE8F8A002827BDFFE088 -:1007E000AFB10014AFB000108F880044AFBF001845 -:1007F00093890024954200E430D100FF0109182BB1 -:100800000080802130AC00FF3047FFFF00005821FE -:1008100014600003310600FF012030210109582334 -:10082000978300420068102B144000320000000043 -:1008300014680007240200018E0200202403FFFB3D -:1008400034E7800000431024AE020020240200019F -:1008500034E70880158200053165FFFF0E0015E5BD -:10086000020020210A001827020020210E0016167F -:10087000020020210E0016598F8400508F8400281A -:100880009482006024420001A4820060948200608F -:100890003C0308008C63318830427FFF5443000FD3 -:1008A0000200202194820060240380000043102471 -:1008B000A48200609082006090830060304200FF5C -:1008C000000211C200021027000211C03063007F35 -:1008D00000621825A0830060020020210220282148 -:1008E0008FBF00188FB100148FB000100A00179945 -:1008F00027BD0020914200632403FF8000431025A0 -:10090000A1420063978200423048FFFF110000209F -:10091000938300248F840028004B1023304600FF6F -:10092000948300E42402EFFF0168282B006218245E -:10093000A48300E414A000038E02002001005821CB -:10094000000030212403FFFB34E780000043102423 -:10095000AE02002024020001158200053165FFFF70 -:100960000E0015E5020020210A00184F978300426F -:100970000E00161602002021978300428F82004449 -:10098000A780004200431023AF82004493830024D9 -:100990008F8200288FBF00188FB100148FB0001015 -:1009A00027BD002003E00008A04300BD8F8200287F -:1009B00090430088904500BD244900883063003F83 -:1009C0002463FFE024020001006238042C6300204D -:1009D00030E80019A385002410600010AF890034AE -:1009E0003C0280003442000224050001240600017C -:1009F0001500000800E218240000282114600005FA -:100A000030E200201040000524050001912600017D -:100A100030C600010A0017E60000000003E00008ED -:100A20000000000027BDFFD8AFB000108F90003449 -:100A3000AFB40020AFB10014AFBF0024AFB3001CAF -:100A4000AFB200188E0500103C0208008C4231B095 -:100A50008F86003830A33FFF0062182B8CD3001420 -:100A6000008088218CD20020106000780000A02136 -:100A700090C3000D2402FF8000431024304200FF89 -:100A800050400073022020210005138230420003F1 -:100A90005440006F0220202194C3001C8F82002844 -:100AA0008E050028A44301148CC200100262182392 -:100AB000146500072402001F8F82003C0062102191 -:100AC0000262102B104000088F83002C24020018B3 -:100AD0000E001697A382004C2403FFFF1043006F03 -:100AE0002404FFFF8F83002C8F84003C8C62001055 -:100AF0000244902100441023AC6200108F82002831 -:100B0000AC7200208C4200680052102B104000098B -:100B10008F830038022020212402001D0E0016972A -:100B2000A382004C2403FFFF1043005C2404FFFF5A -:100B30008F8300388E0200248C630024104300074A -:100B4000022020212402001C0E001697A382004CD4 -:100B50002403FFFF104300512404FFFF8F84002C67 -:100B60008C82002424420001AC8200241253000431 -:100B70008F8200288C4200685642000E8E020000D0 -:100B80008E0200003C030080004310241440000D3E -:100B90002402001A022020210E001697A382004C86 -:100BA0002403FFFF1043003D2404FFFF0A0018E365 -:100BB0008E0200143C0300800043102450400003C8 -:100BC0008E020014AC8000208E0200142412FFFF5D -:100BD000105200062402001B022020210E0016974E -:100BE000A382004C1052002D2404FFFF8E0300004E -:100BF0003C020001006210241040001F3C020080F3 -:100C00000062102414400008022020212402001A4F -:100C10000E001697A382004C2403FFFF1043001F11 -:100C20002404FFFF02202021020028210E0016B715 -:100C3000240600012403FFFF2404FFFF1443000ED9 -:100C4000241400010A0019188FBF0024022020215B -:100C50002402000D8FBF00248FB400208FB3001C2E -:100C60008FB200188FB100148FB0001027BD00287C -:100C70000A001697A382004C8F83002C02202021AB -:100C800002803021946200362405000124420001D4 -:100C90000E0017E6A4620036000020218FBF00245A -:100CA0008FB400208FB3001C8FB200188FB10014D6 -:100CB0008FB000100080102103E0000827BD00283D -:100CC0008F83002827BDFFD8AFB40020AFB3001C2E -:100CD000AFB20018AFB10014AFB00010AFBF002426 -:100CE000906200638F9100342412FFFF3442004071 -:100CF00092250000A06200638E22001000809821DF -:100D000030B0003F105200060360A0212402000D05 -:100D10000E001697A382004C105200522404FFFFCD -:100D20008F8300288E2200188C63007C10430007FC -:100D3000026020212402000E0E001697A382004CB0 -:100D40002403FFFF104300472404FFFF2404002076 -:100D5000120400048F830028906200633442002054 -:100D6000A06200638F85003C10A0001E0000000000 -:100D7000560400048F820028026020210A001962B4 -:100D80002402000A9683000A2404FFFD94420060B6 -:100D90003042FFFF104300348FBF00243C020800A4 -:100DA0008C42318C0045102B14400006026020213B -:100DB000000028210E0017E6240600010A00198908 -:100DC000000020212402002D0E001697A382004C63 -:100DD0002403FFFF104300232404FFFF0A001989A6 -:100DE00000002021160400058F8400288E230014A3 -:100DF0002402FFFF506200180260202194820060EC -:100E000024420001A4820060948200603C03080038 -:100E10008C63318830427FFF5443000F02602021F1 -:100E2000948200602403800000431024A4820060A8 -:100E30009082006090830060304200FF000211C287 -:100E400000021027000211C03063007F00621825E5 -:100E5000A0830060026020210E0017992405000184 -:100E6000000020218FBF00248FB400208FB3001C0E -:100E70008FB200188FB100148FB0001000801021C5 -:100E800003E0000827BD00288F83002827BDFFE866 -:100E9000AFB00010AFBF0014906200638F870034C2 -:100EA00000808021344200408CE60010A062006384 -:100EB0003C0308008C6331B030C23FFF0043102B6D -:100EC0001040004E8F8500382402FF8090A3000D53 -:100ED00000431024304200FF50400049020020210E -:100EE0000006138230480003240200025502004429 -:100EF0000200202194A2001C8F85002824030023D7 -:100F0000A4A201148CE60000000616023042003F45 -:100F1000104300103C0300838CE300188CA2007C7B -:100F2000106200062402000E0E001697A382004CE9 -:100F30002403FFFF104300382404FFFF8F830028A1 -:100F40009062006334420020A06200630A0019CE60 -:100F50008F83002C00C31024144300078F83002CC0 -:100F600090A200623042000F34420020A0A2006232 -:100F7000A38800408F83002C9062000D3042007FD8 -:100F8000A062000D8F83003C106000180200202139 -:100F90008F8400388C8200100043102B1040000911 -:100FA00024020018020020210E001697A382004C94 -:100FB0002403FFFF104300182404FFFF0A0019F662 -:100FC000000020218C820010240500010200202155 -:100FD000004310238F83002C240600010E0017E627 -:100FE000AC6200100A0019F6000020210E001799CB -:100FF000240500010A0019F600002021020020212A -:101000002402000D8FBF00148FB0001027BD001800 -:101010000A001697A382004C8FBF00148FB00010F7 -:101020000080102103E0000827BD001827BDFFD86D -:10103000AFB000108F900034AFB3001CAFBF0020E2 -:10104000AFB20018AFB100148E1200103C030800BC -:101050008C6331B032423FFF0043102B1040007CC4 -:10106000008098218F8500382402FF8090A3000D16 -:1010700000431024304200FF5040007602602021DF -:101080000012138230420003240300015443007114 -:101090000260202190A2000D30420008544000035D -:1010A0008F82003C0A001A262402002450400003CC -:1010B0008E03000C0A001A26240200278CA20020AE -:1010C00014620005240200208E0300088CA2002474 -:1010D00010620008240200200E001697A382004C24 -:1010E0002403FFFF1043006A2404FFFF0A001A5183 -:1010F0008F84002C8E0200142411FFFF1451000372 -:101100008F8700280A001A4C240200258E0300183D -:101110008CE2007C146200162402000E8E03002470 -:101120008CA2002814620012240200218E060028DE -:101130008CA2002C14C2000E2402001F8E03002C6F -:101140001060000B240200238CE200680043102B87 -:1011500014400007240200268CA200140066182107 -:101160000043102B504000078F84002C24020022E3 -:101170000E001697A382004C105100452404FFFF77 -:101180008F84002C2403FFF79082000D004310246D -:10119000A082000D8F8600283C0308008C6331ACD0 -:1011A0008F82005094C400E08F85002C00431021F2 -:1011B00030847FFF00042040004410213043007F32 -:1011C000034320213C03000E008320212403FF80E1 -:1011D00000431024AF42002CA49200008CA20028EF -:1011E00024420001ACA200288CA2002C8E03002C0B -:1011F00000431021ACA2002C8E02002CACA20030C7 -:101200008E020014ACA2003494A2003A24420001E1 -:10121000A4A2003A94C600E03C0208008C4231B01F -:1012200024C4000130837FFF14620013008030214A -:10123000240280000082302430C2FFFF000213C26B -:10124000304200FF000210270A001A8E000233C04D -:10125000026020212402000D8FBF00208FB3001CEC -:101260008FB200188FB100148FB0001027BD002876 -:101270000A001697A382004C8F820028026020216A -:10128000240500010E001799A44600E0000020216B -:101290008FBF00208FB3001C8FB200188FB10014D5 -:1012A0008FB000100080102103E0000827BD002847 -:1012B00027BDFFE0AFB100148F910034AFB0001034 -:1012C000AFBF00188E2600103C0308008C6331B0BD -:1012D00030C23FFF0043102B1040005E0080802191 -:1012E0008F8500382402FF8090A3000D0043102456 -:1012F000304200FF50400058020020218F82003C05 -:1013000010400008000613828F8200289763000AAD -:101310002404FFFD944200603042FFFF104300555B -:1013200000061382304200031440000E000000004B -:1013300092220002104000058E2300245060001508 -:10134000922300030A001AC7020020218CA2002465 -:101350005062001092230003020020210A001ACFDD -:101360002402000F90A2000D3042000854400009F2 -:101370009223000302002021240200100E00169781 -:10138000A382004C2403FFFF1043003A2404FFFF14 -:1013900092230003240200025462000C92220003F4 -:1013A0008F82003C54400009922200030200202159 -:1013B0002402002C0E001697A382004C2403FFFF8A -:1013C0001043002C2404FFFF922200030220282156 -:1013D00002002021384600102CC600012C420001DA -:1013E0000E0016B7004630252411FFFF10510021D2 -:1013F0002404FFFF8F83003C1060001202002021B4 -:101400003C0208008C42318C0043102B1440000633 -:1014100000000000000028210E0017E6240600014D -:101420000A001B0D000020212402002D0E0016973B -:10143000A382004C1051000F2404FFFF0A001B0D73 -:10144000000020210E001799240500010A001B0D41 -:1014500000002021020020212402000D8FBF00186F -:101460008FB100148FB0001027BD00200A0016971E -:10147000A382004C8FBF00188FB100148FB00010F2 -:101480000080102103E0000827BD00209383004066 -:1014900027BDFFE024020002AFB10014AFB000107E -:1014A00000808821AFBF0018000080211062008CEE -:1014B0002404FFFD978500428F83004430A2FFFF84 -:1014C0000043102B5440007D8F8400480E001558B7 -:1014D000000000003C020800244279F40220202190 -:1014E000004028210E00171EAF8200342409FFFFA0 -:1014F0001049007B2404FFFF3C0808008D087A0493 -:101500003C0208008C4231B03C030800906379F43F -:1015100031043FFF0082102B1040001B3067003F5A -:101520003C0208008C4231A88F83005000042180C7 -:1015300000621821006418213062007F03422821D4 -:101540003C02000C00A228213C0200803442000131 -:101550003066007800C230252402FF80006210242B -:10156000AF42002830640007AF4208048F82002891 -:101570000344202124840940AF460814AF85002C81 -:10158000AF840038AC430118938300402402000369 -:101590001462003B240200012402002610E2003DF8 -:1015A00028E2002710400013240200322402002207 -:1015B00010E2003828E20023104000082402002432 -:1015C0002402002010E200242402002110E2001E68 -:1015D000022020210A001B8C2402000B10E2002DA7 -:1015E0002402002510E20010022020210A001B8C9A -:1015F0002402000B10E2001A28E20033104000061B -:101600002402003F2402003110E2000B02202021BE -:101610000A001B8C2402000B10E200110220202182 -:101620000A001B8C2402000B0E00187902202021D6 -:101630000A001BA7004080210E0019FB0220202178 -:101640000A001BA7004080210E001A9C02202021C6 -:101650000A001BA7004080211509000E00000000B1 -:101660000E001920022020210A001BA70040802123 -:101670000E001697A382004C0A001BA70040802191 -:1016800014620017020020212402002314E2000546 -:101690002402000B0E001992022020210A001BA731 -:1016A0000040802102202021A382004C0E001697CA -:1016B0002410FFFF0A001BA80200202130A500FF14 -:1016C0000E00159524060001978300428F82004486 -:1016D000A780004200431023AF8200440200202173 -:1016E0008FBF00188FB100148FB000100080102140 -:1016F00003E0000827BD002027BDFFE0AFB10014C4 -:10170000AFBF0018AFB000108F4601283C0308009F -:101710008C6331A02402FF80AF86005000C31821E3 -:101720003065007F03452821006218243C02000A2E -:10173000AF43002400A2282190A2006200808821EB -:10174000AF850028304200FF00021102A382004052 -:1017500090A200BC30420002144000022403003476 -:10176000240300308F820028A3830030938300403D -:101770008C4200C0A380004CAF82004424020004CD -:10178000106200308F8400448E2400045080002DAD -:101790008F8400448E2200103083FFFFA784004214 -:1017A0001060001FAF8200488F8300282405FF804F -:1017B000022020219062006300A21024304200FF2A -:1017C0001440000D000000000E001B139790004213 -:1017D00010400010004018212402FFFD5462001147 -:1017E0008E230020020028210E0015360220202121 -:1017F0000A001BF98E2300209062006300A21024CF -:10180000304200FF10400003022020210E00185B30 -:1018100000000000978200421440FFE48F830028FC -:101820008E23002030620004104000068F840044A4 -:101830002402FFFB006210240E00154AAE22002095 -:101840008F8400448F8300288FBF00188FB100144D -:101850008FB000102402000127BD002003E0000823 -:10186000AC6400C030A500FF2403000124A90001DE -:101870000069102B1040000C00004021240A0001D8 -:1018800000A31023004A38042463000130820001C1 -:101890000069302B1040000200042042010740255F -:1018A00054C0FFF800A3102303E00008010010213A -:1018B00027BDFFE03C021EDCAFB20018AFB1001440 -:1018C000AFBF001CAFB0001034526F410000882140 -:1018D000240500080E001C09022020210011808030 -:1018E0003C07080024E775F40002160002071821DF -:1018F000AC6200000000282124A200013045FFFF57 -:101900008C6200002CA60008044100020002204066 -:101910000092202614C0FFF8AC640000020780216A -:101920008E0400000E001C0924050020262300015F -:101930003071FFFF2E2301001460FFE5AE020000AE -:101940008FBF001C8FB200188FB100148FB0001031 -:1019500003E0000827BD00203C02080024426EB8C6 -:101960003C010800AC2275E83C02080024425430D7 -:101970003C010800AC2275EC240200063C01080082 -:10198000A02275F00A001C1C0000000027BDFFD833 -:10199000AFB3001CAFB20018AFBF0020AFB100144E -:1019A000AFB000108F5101408F48014800089402E9 -:1019B000324300FF311300FF8F4201B80440FFFEA5 -:1019C00027500180AE1100008F420144AE02000496 -:1019D00024020002A6120008A202000B2402001436 -:1019E000AE13002410620025286200151040000884 -:1019F000240200152402001010620030240200129C -:101A0000106200098FBF00200A001D468FB3001C22 -:101A10001062007024020022106200378FBF002085 -:101A20000A001D468FB3001C3C0208008C4231A006 -:101A30002403FF800222102100431024AF4200241F -:101A40003C0208008C4231A0022210213042007F6B -:101A5000034218213C02000A00621821166000BCF3 -:101A6000AF830028906200623042000F34420030A1 -:101A7000A06200620A001D458FBF00203C04600088 -:101A80008C832C083C02F0033442FFFF00621824D0 -:101A9000AC832C083C0208008C4231A08C832C08BB -:101AA0002442007400021082000214800062182593 -:101AB000AC832C080A001D458FBF00203C020800A3 -:101AC0008C4231A02403FF80022210210043102405 -:101AD000AF4200243C0208008C4231A03C03000AC3 -:101AE000022210213042007F0342102100431021C6 -:101AF0000A001D44AF8200283C0208008C4231A03D -:101B00002405FF800222102100451024AF4200244A -:101B10003C0208008C4231A0022210213042007F9A -:101B2000034218213C02000A0062182190620063FF -:101B300000A21024304200FF10400085AF8300282F -:101B400024620088944300123C0208008C4231A8B1 -:101B500030633FFF0003198002221021004310214F -:101B60003043007F03432021004510243C03000C38 -:101B700000832021AF4200289082000D00A2102493 -:101B8000304200FF10400072AF84002C9082000DA4 -:101B9000304200101440006F8FBF00200E00166608 -:101BA000000000008F4201B80440FFFE000000006A -:101BB000AE1100008F420144AE0200042402000274 -:101BC000A6120008A202000BAE1300240A001D4555 -:101BD0008FBF00202406FF8002261024AF42002081 -:101BE0003C0208008C4231A031043FFF00042180F8 -:101BF0000222102100461024AF4200243C030800BA -:101C00008C6331A83C0208008C4231A03227007F4F -:101C10000223182102221021006418213042007F83 -:101C20003064007F034228213C02000A0066182429 -:101C300000A22821034420213C02000C0082202124 -:101C4000AF4300283C02000803471821006290219E -:101C5000AF850028AF84002C0E001666010080219D -:101C60008F4201B80440FFFE8F82002C8F84002831 -:101C7000274501809042000DACB10000A4B00006E1 -:101C8000000216000002160300021027000237C2ED -:101C900014C00016248200889442001232033FFFD1 -:101CA00030423FFF1443001224026082908300639D -:101CB0002402FF8000431024304200FF5040000CFB -:101CC00024026082908200623042000F3442004061 -:101CD000A082006224026084A4A200082402000DF5 -:101CE000A0A200050A001D2F3C02270024026082EA -:101CF000A4A20008A0A000053C02270000061C00CA -:101D00000062182524020002A0A2000BACA3001060 -:101D1000ACA00014ACA00024ACA00028ACA0002C07 -:101D20008E42004C8F84002CACA200189083000DD2 -:101D30002402FF8000431024304200FF10400005C1 -:101D40008FBF00209082000D3042007FA082000DE6 -:101D50008FBF00208FB3001C8FB200188FB100140A -:101D60008FB000103C02100027BD002803E00008DF -:041D7000AF4201B8C5 -:0C1D7400080033F8080033F80800337052 -:101D8000080033A8080033DC0800340008003400E1 -:081D900008003400080032E0F5 -:081D98000A0001220000000016 -:101DA000000000000000000D747061352E302E30F0 -:101DB0006A3600000500000100000000000000007D -:101DC0000000000000000000000000000000000013 -:101DD0000000000000000000000000000000000003 -:101DE00000000000000000000000000000000000F3 -:101DF00000000000000000000000000000000000E3 -:101E000000000000000000000000000000000000D2 -:101E100000000000000000000000000000000000C2 -:101E20000000000010000003000000000000000D92 -:101E30000000000D3C02080024421B803C03080007 -:101E400024632014AC4000000043202B1480FFFDCD -:101E5000244200043C1D080037BD2FFC03A0F021E4 -:101E60003C100800261004883C1C0800279C1B809E -:101E70000E00015A000000000000000D3084FFFF3A -:101E8000308200078F85001810400002248300076D -:101E90003064FFF80085302130C41FFF034418214F -:101EA000247B4000AF85001CAF84001803E00008CD -:101EB000AF4400843084FFFF308200078F8500200C -:101EC0008F86002810400002248300073064FFF84A -:101ED000008520210086182B14600002AF850024A5 -:101EE000008620230344282134068000AF8400208C -:101EF000AF44008000A6202103E00008AF84003832 -:101F000027BDFFD8AFB3001CAFB20018AFB00010B0 -:101F1000AFBF0024AFB40020AFB100143C0860088C -:101F20008D1450002418FF7F3C1A800002989824DA -:101F30003672380CAD1250008F5100083C07601CFF -:101F40003C08600036300001AF500008AF80001838 -:101F5000AF400080AF4000848CE600088D0F080879 -:101F60003C0760168CEC000031EEFFF039CA00101F -:101F70003C0DFFFF340B80003C030080034B4821E5 -:101F80002D440001018D28243C0253533C010800DC -:101F9000AC230420AF890038AF860028AF8400103E -:101FA000275B400014A2000334E37C008CF900049A -:101FB000032818218C7F007C8C6500783C0280000F -:101FC00034520070AF85003CAF9F00403C130800C6 -:101FD00026731BC40240A0218E4800008F460000DB -:101FE00038C300013064000110800017AF8800344E -:101FF000028048218D2D00003C1908008F39045CB7 -:102000003C1108008E31045801A8F823033F7821C1 -:10201000000040210228382101FF802B00F07021B0 -:102020003C010800AC2F045C3C010800AC2E0458B5 -:102030008F4C0000398B0001316A00011540FFED23 -:1020400001A04021AF8D00348E4E00003C0C0800F2 -:102050008D8C045C3C0A08008D4A045801C8682332 -:10206000018D28210000582100AD302B014B20218B -:10207000008610213C010800AC25045C3C010800EE -:10208000AC2204588F4501088F44010030A920007C -:10209000AF850000AF84000C1120000A00A03021A1 -:1020A0003C0708008CE7042C24EF00013C010800E9 -:1020B000AC2F042C3C104000AF5001380A000190B6 -:1020C0000000000030B002001600001424110F00C0 -:1020D0001091001224070D001087023330B0000663 -:1020E0005200FFF53C104000936D0000240C0010DE -:1020F00031A600F010CC0269240E007010CE02DD73 -:102100008F8B001425670001AF8700143C1040003E -:10211000AF5001380A000190000000009748010408 -:102120001100FFE53C10400030B84000170000A24D -:10213000000000008F5901780720FFFE8F870038CC -:1021400024090008240508008CE30008AF45017845 -:10215000A7490140A7400142974201048F86000031 -:102160003049FFFF30DF000113E002D5012040219C -:102170002524FFFE240A0002A74A01463088FFFFFB -:10218000A74401483C0B08008D6B043C156002C459 -:102190008F8F000C30C3002014600002240400095B -:1021A0002404000130CD0C00240C040051AC0001CB -:1021B00034840004A744014A3C0508008CA504208F -:1021C0003C0200483C19000100A2F82530D800026A -:1021D00003F9282513000004000018213C04010025 -:1021E00000A428252403000130CA00045140000542 -:1021F000AF8300083C06001000A628252403000138 -:10220000AF830008AF451000000000000000000090 -:1022100000000000000000008F8300081060002311 -:10222000000000008F4B10000561FFFE0000000061 -:102230001060001E000000008F4D10003C030020C5 -:1022400001A36024118000198F8F000031EE00027D -:1022500011C0001600000000975010141600001363 -:10226000000000009745100830BFFFFF27F8000668 -:102270000018C8820019308000C7282133110001DE -:1022800033030003122003208CA200000000000D85 -:1022900000C7F821AFE200003C1908008F39043074 -:1022A000272600013C010800AC2604308F6A00009C -:1022B0003405FFFFAF8A00048CE200001045029A4B -:1022C000000020218CE5000030BF010013E0027EF9 -:1022D000010020213C0708008CE704743C10080032 -:1022E0008E10044C00E858213C1808008F18047028 -:1022F0000168882B3C0808008D08044800007821FC -:1023000002046021030F18210184702B010F682142 -:102310000071502101AE10213C010800AC2C044C8E -:102320003C010800AC2204483C010800AC2B0474BA -:102330003C010800AC2A04708F8D00180120302168 -:102340003129000725AE000831C21FFF034260217A -:10235000AF8D001CAF820018259B4000AF42008467 -:10236000112000038F90002024C800073106FFF8D9 -:102370008F84002800D0282100A4782B15E00002CB -:10238000AF90002400A428230345202134038000BB -:10239000008310213C061000AF850020AF8200387A -:1023A000AF450080AF4601788F8B00142567000190 -:1023B0000A0001DDAF8700148F6200088F670000FC -:1023C000241100300007C602330300F0107100A290 -:1023D000241900401479FF4B8F8B00148F4A017829 -:1023E0000540FFFE30A7020014E000030005128242 -:1023F0000000000D0005128230500003001049005B -:1024000001307021000E688001B06021000C5880FE -:10241000017380218E0800001500000200000000FA -:102420000000000D8F6F000405E202B19203000668 -:1024300092070005920F00043C020001000728806B -:1024400000B060218D8900182771000825EE000575 -:1024500001226821000E3082AD8D0018022020215B -:102460000E00058026050014920B00068F7F0004E5 -:102470003C087FFF000B2080009130218CC30004BA -:10248000350AFFFF03EAC8240079C021ACD8000454 -:102490009207000592090004960D000800072880A5 -:1024A00000B1F8218FEF0000974201043C07FFFFC5 -:1024B00001E75024304EFFFF01C96021018D5823F0 -:1024C0003168FFFF01482025AFE4000092030007B8 -:1024D00024190001107902692406000310660279AC -:1024E000000000008E190010241F000AA75F0140A1 -:1024F000A7590142920300048F86000024070001BF -:10250000A7430144A74001469758010430D1000277 -:102510003C050041A758014800001821A747014A7F -:102520001220000330CA00043C05014124030001CD -:1025300051400005AF8300083C08001000A8282582 -:1025400024030001AF830008AF4510000000000025 -:102550000000000000000000000000008F8B000859 -:1025600011600004000000008F4410000481FFFE91 -:10257000000000008F6A0000920700043C0508007C -:102580008CA50444AF8A0004975F01043C0F080047 -:102590008DEF044030E300FF33F9FFFF0079C021E5 -:1025A00000B868210000102124E6000A30C8FFFFAF -:1025B00001B8482B01E2702101C9602131100007E8 -:1025C0003C010800AC2D04443C010800AC2C044044 -:1025D000120000038F8D0018250B00073168FFF8EB -:1025E000010D702131CC1FFFAF8D001CAF8C001886 -:1025F000AF4C008497440104034C80213084FFFFDA -:102600003088000711000003261B400024890007C2 -:102610003124FFF88F8200208F850028008220213E -:102620000085782B15E00002AF820024008520236E -:102630000344882134058000022510213C06100047 -:10264000AF840020AF820038AF440080AF460178ED -:102650000A0002858F8B00148F5F017807E0FFFE70 -:1026600030AA020015400003000542820000000D60 -:1026700000054282310200030002710001C268219C -:10268000000D6080018248210009288000B380216C -:102690008E0B000011600002000000000000000D21 -:1026A0008F6F000C05E001F38F87003824190001BB -:1026B000AE1900008CE30008A20000078F78000428 -:1026C00000181C02306600FF24D100050011308282 -:1026D0002CC4004114800002A20300040000000D7D -:1026E0008F6B00043C0EFFFF00E028213164FFFFE8 -:1026F000248F000B000F4082000810800047482103 -:102700008D2D000026040014A60B000801AE6024E5 -:102710000E000580AD2C00008F5F01083C0A100000 -:1027200003EA382410E001A30000000097460104EA -:102730009203000724D1FFEC346500023224FFFF2E -:10274000A2050007960600082CC7001354E00005F8 -:1027500092030007920A0007355F0001A21F0007DD -:1027600092030007240B0001106B01BA2409000337 -:10277000106901CD8F88003830CFFFFF25E40002BB -:102780000004C883333F00FF001F2880A219000502 -:1027900000A858218D780000975101043C03FFFFE9 -:1027A000030360243222FFFF004F702325CDFFFE7C -:1027B000018D4825AD690000920600053C02FFF638 -:1027C000344EFFFF30CA00FF000A388000F020219D -:1027D000909900143C1FFF7F37E7FFFF3323000F62 -:1027E0000066782131F800FF0018288000B08821A9 -:1027F0008E2D002000A86021A20F000601AE482403 -:10280000AE0D000CAD89000C920B00068E04000C7E -:102810000127F824000B50800150C821972600267C -:102820000148C02100874024AF260024AE08000CD8 -:10283000AF3F0020AF0600108F860000240C001070 -:1028400024090002A74C0140A7400142A7400144CF -:10285000A7490146974B01042407000130C8000234 -:10286000256AFFFEA74A01483C050009A747014A1F -:1028700011000003000018213C0501092403000198 -:1028800030CD000451A00005AF8300083C060010C5 -:1028900000A6282524030001AF830008AF451000DF -:1028A0000000000000000000000000000000000028 -:1028B0009218000427110002322F0007000F102386 -:1028C000304E0007AE0E00108F900008120000047A -:1028D000000000008F4310000461FFFE00000000B4 -:1028E0008F7800008F8F00183C1008008E10044471 -:1028F000AF9800049751010425E6001030CA1FFF6D -:102900003222FFFFAF8F001CAF8A0018AF4A00844D -:102910002449FFFE3C0B08008D6B0440974E0104D8 -:1029200001206821000967C3020D282131C9FFFF7A -:1029300000AD402B016C382100E82021034AF8212A -:10294000313900073C010800AC2504443C01080073 -:10295000AC2404401320000327FB4000252300077C -:102960003069FFF88F9F00208F840028013F3821B5 -:1029700000E4C82B17200002AF9F002400E4382396 -:102980000347202134058000008510213C061000FB -:10299000AF870020AF820038AF470080AF46017894 -:1029A0000A0002858F8B0014975801041300FDC2A2 -:1029B0003C1040008F4301780460FFFE30B94000B6 -:1029C000132000033C0400080000000D3C04000834 -:1029D000AF44014024080800AF4801788F8B000005 -:1029E000974A0104317F000113E000E93146FFFFFF -:1029F00024D0FFFE240C0002A74C0146A75001483A -:102A00008F8F00182405000DA745014A8F71000023 -:102A100025E2000830491FFF0349702130CD00072F -:102A2000AF910004AF8F001CAF89001800C038219F -:102A3000AF49008411A0000325DB400024C6000735 -:102A400030C7FFF88F9800208F84002800F83021CD -:102A500000C4382B14E00002AF98002400C43023D7 -:102A60008F8A001403465821340880000168F82139 -:102A7000255900013C0310003C104000AF860020A7 -:102A8000AF9F0038AF460080AF430178AF99001484 -:102A9000AF5001380A000190000000008F6900006B -:102AA000974401043127FFFF3088FFFF8F4F0178E3 -:102AB00005E0FFFE30FF0007001F182330780007F5 -:102AC00024E6FFFE2419000AA7590140A758014235 -:102AD000A7460144A7400146A74801488F42010884 -:102AE00030510020162000022403000924030001B5 -:102AF00030AA0002A743014A3C04004111400003F0 -:102B0000000018213C0401412403000130AB000403 -:102B100051600005AF8300083C05001000852025AA -:102B200024030001AF830008AF4410000000000040 -:102B30000000000000000000000000008F9000086E -:102B400012000004000000008F4C10000581FFFE01 -:102B5000000000008F780000276200088F8D003C85 -:102B6000AF980004944600089451000A944F000C5A -:102B700030CEFFFF0011240031E9FFFF11CD00A28C -:102B8000008920253C0308008C6304443C1808009D -:102B90008F18044000E85021255FFFFE007F782158 -:102BA0000000102101FF302B03028821022648215A -:102BB0003C010800AC2F04443C010800AC2904404F -:102BC00024EB00083162FFFF3047000710E00003EC -:102BD0008F850018245000073202FFF83106FFFFEE -:102BE00030C800070045702131CD1FFF034D602123 -:102BF000AF85001CAF8D0018259B4000AF4D0084B1 -:102C0000110000038F8F002024C400073086FFF8D6 -:102C10008F84002800CF282100A4482B1520000213 -:102C2000AF8F002400A42823AF850020AF4500808B -:102C30003C1108008E3104340345C0213402800069 -:102C40000302302112200005AF860038938300175D -:102C50002419000E1079000D241F043F3C0A1000B7 -:102C6000AF4A01788F8B0014256700010A0001DD4F -:102C7000AF8700140E0005A63C1040008F8B001497 -:102C8000256700010A0001DEAF8700143C0A10002E -:102C9000A75F0148AF4A01780A0004B48F8B001483 -:102CA000240E0F0011EE003D30D10020162000024E -:102CB00024030009240300010A000208A743014A73 -:102CC0000A0001FBA740014694E5000894E2000ACF -:102CD00094EB000C8F86003C0002FC00316AFFFF81 -:102CE00030B9FFFF1326003703EA20253C05080012 -:102CF0008CA504443C1F08008FFF044000005021B5 -:102D000000A8382100E8302B03EAC8210326C0219F -:102D10003C010800AC2704443C010800AC380440E6 -:102D20000A0002698F8D00183C1908008F39047C55 -:102D30003C0308008C6304543C0608008CC60478ED -:102D40003C0F08008DEF04500328382100686821EB -:102D500000E8C02B00C4882101A8402B01E47021A9 -:102D60000238582101C860213C010800AC2D0454F0 -:102D70003C010800AC2C04503C010800AC27047C4A -:102D80003C010800AC2B04780A0002698F8D001802 -:102D9000A74001460A00041B8F8F001830D0002086 -:102DA0001600FFC52403000D240300050A000208D5 -:102DB000A743014A975901042738FFF00A00036B23 -:102DC0003304FFFF8F8C0040148CFFC8000080216B -:102DD0003C1108008E31046C3C0408008C840468AB -:102DE0000228702101C8782B00904021010F682132 -:102DF0003C010800AC2E046C3C010800AC2D0468BA -:102E00000A0002698F8D00188F9900401499FF5DA8 -:102E1000000060213C0508008CA5046C3C100800F3 -:102E20008E10046800E82021248EFFFE00AEF821F9 -:102E300003EE582B020C5021014B18213C010800D5 -:102E4000AC3F046C3C010800AC2304680A00048B0E -:102E500024EB00088F8800383C02FFFF8D0E000C29 -:102E600001C2682401A46025AD0C000C0A0003799E -:102E700030CFFFFF0A0003A9AE000000974B01040A -:102E8000920400048E2A000C01644021251FFFF2E9 -:102E90000147182433F9FFFF0079C025AE38000C34 -:102EA0000A0002D48E1900103C03FFFF8D110010A0 -:102EB0000223282400A47825AD0F00100A0003790E -:102EC00030CFFFFF97450104920600048E2F0010BB -:102ED00000A610212449FFEE01E76824312EFFFFF0 -:102EE00001AE6025AE2C00100A0002D48E1900102D -:102EF0008E06000CAE0000000003C0800310882185 -:102F00000A0002A6AE2600201460000D3050FFFF1C -:102F10003C04FFFF0044602401846826000D582B08 -:102F2000000C502B014B1024104000020000000048 -:102F30000000000D8CA300000A00023E0064102572 -:102F40003A11FFFF0011782B0010702B01CF2024C5 -:102F500010800002000000000000000D8CB800008E -:102F60000A00023E3702FFFF3084FFFF30A5FFFF5B -:102F7000108000070000182130820001104000027C -:102F800000042042006518211480FFFB0005284042 -:102F900003E000080060102110C0000700000000DE -:102FA0008CA2000024C6FFFF24A50004AC82000010 -:102FB00014C0FFFB2484000403E0000800000000AC -:102FC00010A0000824A3FFFFAC8600000000000052 -:102FD000000000002402FFFF2463FFFF1462FFFAD9 -:102FE0002484000403E0000800000000308EFFFF8E -:102FF00030D8FFFF00057C0001F8602539CDFFFFC8 -:1030000001AC5021014C582B014B482100094402CE -:103010003127FFFF00E830210006240230C5FFFF02 -:1030200000A418213862FFFF03E000083042FFFFD0 -:103030003C0C08008D8C0484240BFF8027BDFFD03E -:1030400001845021014B4824AF4900203C0808006E -:103050008D080484AFB20020AFB00018AFBF0028C5 -:10306000AFB30024AFB1001C936600040104382103 -:1030700030E4007F009A10213C03000800439021B7 -:1030800030C50020036080213C080111277B000827 -:1030900014A00002264600702646006C921300041D -:1030A00097510104920F00043267000F322EFFFF88 -:1030B00031ED004001C7282311A000050000482180 -:1030C000925900BC33380004170000900000000043 -:1030D000924300BC307F000413E0000F00000000AA -:1030E00010A0000D00000000960E0002240AFF80D0 -:1030F00000A7602125CDFFFEA74D1016920B0004FE -:10310000014B2024308200FF10400085010C402537 -:103110003C0F0400010F40258F5301780660FFFE2D -:103120002404000AA7440140960D0002240400096B -:1031300031AC0007000C5823316A0007A74A01424E -:10314000960200022443FFFEA7430144A740014624 -:10315000975F0104A75F01488F59010833380020A9 -:103160005300000124040001920F000431EE00100E -:1031700015C000023483001000801821A743014AC3 -:10318000000000000000000000000000000000003F -:10319000AF48100000000000000000000000000028 -:1031A000000000008F5110000621FFFE3113FFFFC9 -:1031B00012600003000000008F481018ACC8000027 -:1031C00096030006307FFFFF27F90002001998825E -:1031D00000138880023B30218CD800001520005756 -:1031E00000183402920300042405FF8000A3F82491 -:1031F00033F100FF1220002C00000000924700BCB9 -:1032000030F200021240002800000000974B100C22 -:103210002562FFFEA7421016000000003C0A0400D1 -:1032200035490030AF4910000000000000000000E8 -:1032300000000000000000008F4C10000581FFFE20 -:10324000000000009749100C8F51101C00C0202175 -:103250003127FFFF24F2003000121882000328807B -:1032600000BBF8213226FFFFAFF100000E000595EC -:1032700000112C020013C880033B98218E780000B7 -:1032800000027400AFB800108FA80010310FFFFFCC -:10329000AFAF00108FA4001001C46825AFAD0010BF -:1032A0008FA60010AE66000097730008976D000AA5 -:1032B0009766000C8F8A003C000D5C0030CCFFFF4D -:1032C0003262FFFF104A0036016C2025960600028C -:1032D0003C10100024D300080E0001393264FFFFB7 -:1032E000974C01040E0001473184FFFFAF50017875 -:1032F0008FBF00288FB300248FB200208FB1001C35 -:103300008FB0001803E0000827BD003010A0FF7048 -:103310000000000024A5FFFC0A0005CE24090004DB -:103320008CD10000AF5110188F5301780660FF7ADE -:103330002404000A0A0005E30000000000A7C821D9 -:103340008F8800388F4E101C0019C08200187880BA -:1033500001E82021AC8E0000000E2C0200C02021CC -:103360000E00059531C6FFFF023B28218CAD000001 -:103370000002540000403021AFAD00108FAC0010AF -:10338000318BFFFFAFAB00108FA200100142482528 -:10339000AFA900108FA700100A000613ACA7000009 -:1033A0008F8F0040148FFFC9000000009742010476 -:1033B000960B00023C0508008CA5046C3049FFFF09 -:1033C000316AFFFF3C1108008E310468012A382160 -:1033D00024F2FFFE00B240210012FFC30112C82BED -:1033E000023FC021031920213C010800AC28046CD5 -:1033F0003C010800AC2404680A00064D00000000EF -:1034000000A4102B104000092403000100052840EF -:1034100000A4102B04A00003000318405440FFFC3C -:103420000005284010600007000000000085302BD8 -:1034300014C0000200031842008520231460FFFB23 -:103440000005284203E00008008010218F85002C31 -:1034500027BDFFE8000530272CC300012CA4000283 -:103460000083102510400003AFBF00102405007F2B -:10347000AF85002C0005282730A5FFFF0E0005743E -:10348000240426F58F830030240402BD004030213F -:103490000083382B10E000092405000100042040BF -:1034A0000083102B04800003000528405440FFFCDB -:1034B0000004204010A0000800C350210064402BED -:1034C00015000002000528420064182314A0FFFB29 -:1034D0000004204200C350218FBF0010000A4C029C -:1034E000312200FF27BD0018AF8A002C03E000083E -:0434F000AF89003070 -:0C34F4000A00002A000000000000000098 -:103500000000000D747870352E302E306A360000C1 -:10351000050000000000000A000001360000EA601B -:10352000000000000000000000000000000000009B -:10353000000000000000000000000000000000008B -:10354000000000000000000000000000000000007B -:103550000000000000000016000000000000000055 -:10356000000000000000000000000000000000005B -:10357000000000000000000000000000000000004B -:1035800000000000000000000000000000001388A0 -:1035900000000000000005DC00000000000000004A -:1035A00010000003000000000000000D0000000DEE -:1035B0003C02080024423B603C03080024633D14A5 -:1035C000AC4000000043202B1480FFFD2442000487 -:1035D0003C1D080037BD7FFC03A0F0213C10080013 -:1035E000261000A83C1C0800279C3B600E0002BA75 -:1035F000000000000000000D8F8300383C088000B0 -:10360000350700708CE50000008330253C029000F7 -:1036100000C22025AF850030AF4400208F49002034 -:103620000520FFFE3C038000346200708C450000E2 -:103630008F8600303C1908008F39007C3C0E080052 -:103640008DCE007800A62023032458210000782185 -:103650000164682B01CF6021018D50213C010800DD -:10366000AC2B007C3C010800AC2A007803E0000889 -:10367000000000000A000041240400018F8400388B -:103680003C05800034A200010082182503E00008F8 -:10369000AF43002003E00008000010213084FFFF4A -:1036A00030A5FFFF108000070000182130820001C4 -:1036B0001040000200042042006518211480FFFB26 -:1036C0000005284003E000080060102110C000073A -:1036D000000000008CA2000024C6FFFF24A5000407 -:1036E000AC82000014C0FFFB2484000403E0000847 -:1036F0000000000010A0000824A3FFFFAC8600001B -:1037000000000000000000002402FFFF2463FFFF10 -:103710001462FFFA2484000403E0000800000000A3 -:10372000308AFFFF93A80013A74A014497490E1659 -:1037300030C600FF3C021000A7490146AF450148D2 -:10374000A3460152A748015AAF4701608FA4001851 -:103750008FA30014A7440158AF43015403E00008AD -:10376000AF42017803E00008000000003C03800045 -:10377000346200708C4900008F88000024840007A8 -:1037800027BDFFF83084FFF8AF890030974D008ADD -:1037900031ACFFFFAFAC00008FAB000001685023DD -:1037A0002547FFFF30E61FFF00C4282B14A0FFF7BA -:1037B0003C0C8000358B00708D6A00003C070800CF -:1037C0008CE700843C0608008CC60080000810824C -:1037D000014918230002788000E3702100002021B5 -:1037E00001C3C82B00C4C02101FA4021031948219C -:1037F0002502400027BD00083C010800AC2E0084D3 -:103800003C010800AC29008003E000080000000033 -:103810008F8200002486000730C5FFF800A218211F -:1038200030641FFF03E00008AF8400008F8700387A -:103830008F8A004027BDFFB88F860044AFB6004096 -:10384000AFBF0044AFB5003CAFB40038AFB30034F5 -:10385000AFB20030AFB1002CAFB000288F450104EB -:103860008D4900ACAF4700808CC8002000A93823E8 -:103870000000B021AF480E108F440E100000482108 -:10388000AF440E148CC20024AF420E188F430E18A2 -:10389000AF430E1C10E001252D230001936B00089F -:1038A000116000D400000000976E001031CDFFFFC2 -:1038B00000ED602B158000CF000000009770001015 -:1038C000320FFFFFAF4F0E008F5200003251000841 -:1038D0001220FFFD0000000097540E088F460E04D2 -:1038E0003285FFFF30B3000112600132000000009A -:1038F0000000000D30B8A04024150040131500C092 -:1039000030A9A0001120012D00000000937F0008C5 -:1039100013E000080000000097630010306BFFFF09 -:1039200000CB402B1100000330AC0040118001237C -:1039300000000000A785003CAF86003493660008B5 -:1039400000E02821AFA7002014C0012427B30020E5 -:10395000AF60000C9782003C3047400014E000024A -:10396000240300162403000E24194007A363000A51 -:10397000AF790014938A003E8F7400143158000709 -:103980000018AA4002959025AF7200149784003C5D -:103990008F7000143091001002117825AF6F001461 -:1039A000978E003C31CD000811A00147000028216E -:1039B0008F6700143C0210003C0C810000E22825B7 -:1039C000AF65001497460E0A2408000E3405FFFC6C -:1039D00030C3FFFF006C5825AF6B0004A3680002E2 -:1039E000937F000A27E90004A369000A9786003C38 -:1039F0009363000A30CC1F00000C598301634021FF -:103A0000251F0028A37F000997490E0CA769001005 -:103A100093790009272A0002315800070018A823CB -:103A200032B10007A371000B937400099764001072 -:103A30008F910034978F003C329200FF0244802126 -:103A40000205702131ED004011A0000531C4FFFFD7 -:103A50000091282B3C12800010A000140000A0212F -:103A60000224382B14E0011B8FA500208F4D0E146B -:103A7000AF4D0E108F420E1CAF420E18AF440E0019 -:103A80008F4F000031EE000811C0FFFD0000000064 -:103A900097540E080080882100009021A794003CD4 -:103AA0008F500E0424140001AF900034976400106E -:103AB0003095FFFF8E6800000111F82317E0000920 -:103AC000AE7F00008F6500148F8B004434A6004049 -:103AD000AF6600148F4C0E10AD6C00208F430E1893 -:103AE000AD6300249367000814E000D200000000DA -:103AF0000E00009E240400108F8900483C0832000C -:103B000000402821312600FF0006FC0003E8502574 -:103B100025390001AF990048AC4A000093780009AC -:103B20009370000A330400FF00047400320F00FF9A -:103B300001CF6825AC4D00048F820048064000EAA2 -:103B4000ACA20008ACA0000C9783003C306B0008CE -:103B5000156000022628000626280002974E0E1443 -:103B60008F450E1C8F670004936D000231C4FFFF68 -:103B700031A200FFAFA200108F6C0014AFA8001894 -:103B80000E00008BAFAC0014240400100E0000C720 -:103B9000000000008E7200001640000500000000CA -:103BA0008F6400142405FFBF00859824AF730014B0 -:103BB0008F79000C03353821AF67000C937500082E -:103BC00016A000080000000012800006000000009F -:103BD0008F7F00143C0BEFFF3568FFFE03E848249D -:103BE000AF690014A37400088FA500200A000246E4 -:103BF00002202021AF470E000A0000F5000000005F -:103C00008F5901780720FFFE241F08008F840000D1 -:103C1000AF5F0178974B008A316AFFFF0144482368 -:103C20002528FFFF31021FFF2C4300081460FFF915 -:103C3000000000008F8E00488F8D003800C04821A2 -:103C40000344202125C60001240C0F00AF86004844 -:103C500000E938232486400031CA00FF11AC00057A -:103C6000240800019391003E3230000700107A4092 -:103C700035E80001000AAC003C18010002B8A0259C -:103C8000AC9440008F93004830B2003630A4000856 -:103C9000ACD300041080009701123025974E0E0A15 -:103CA0008F8D00003C02810031CCFFFF25AB000866 -:103CB000018240253C03100031651FFF25390006B5 -:103CC000241F000EAF48016000C33025A75F015AD2 -:103CD000AF850000A759015814E0000A8F930038FF -:103CE00024120F00527200022416000134C6004054 -:103CF0008F580E108F940044AE9800208F550E18E8 -:103D0000AE9500248F450E14AF4501448F590E1C0B -:103D1000AF590148A34A01523C0A1000AF46015472 -:103D2000AF4A017814E0FEDD2D2300010076A025C6 -:103D3000128000178FBF00448F84003824160F00B4 -:103D400010960084000000008F45017804A0FFFE5B -:103D500024150F001095006E000000008F470E1410 -:103D6000240202403C1F1000AF4701448F440E1C48 -:103D7000AF440148A3400152A740015AAF4001603F -:103D8000A7400158AF420154AF5F01788FBF004494 -:103D90008FB600408FB5003C8FB400388FB300342D -:103DA0008FB200308FB1002C8FB0002803E00008E4 -:103DB00027BD004814C0FED030B8A0408F420E147A -:103DC0008F84004400004821AC8200208F510E1CDB -:103DD000AC9100240A00020E2D2300018F910034C3 -:103DE000978A003C3C1280000220A82131580040F4 -:103DF0001700FF300000A021976900108F92003457 -:103E00003139FFFF133200350000202100804821A6 -:103E10001480FEA000A038218F420E148F8400442D -:103E2000AC8200208F510E1CAC9100240A00020EBF -:103E30002D230001936A00099378000B315000FF95 -:103E4000330F00FF020F702125C2000A3050FFFF20 -:103E50000E00009E020020218F8600483C1F41007A -:103E600024CD0001AF8D0048936C000930C600FFDF -:103E700000064400318300FF246B0002010B48253B -:103E8000013FC825AC5900008F67000C97440E1401 -:103E900000F22825AC4500048F450E1C8F670004F6 -:103EA000936A00023084FFFF315800FFAFB8001062 -:103EB0008F6F0014AFB100180E00008BAFAF00146D -:103EC0000A0001A602002021AF6000040A00013EA2 -:103ED000A36000020A000246000020210000902199 -:103EE0000A000170241400013C1280000A000195B0 -:103EF000ACB2000C8F91000025240002A7440158A9 -:103F000026300008320F1FFF0A0001F9AF8F0000B2 -:103F1000AF40014C1120002C000000008F590E1002 -:103F2000AF5901448F430E18240200403C1F10007B -:103F3000AF430148A3400152A740015AAF4001607E -:103F4000A7400158AF420154AF5F01780A00022731 -:103F50008FBF0044112000060000000097460E08A5 -:103F600030CC004015800002000000000000000D71 -:103F70008F4D017805A0FFFE0000000097530E1042 -:103F80003C120500240E2000326AFFFF0152C025BA -:103F9000AF58014C8F4F0E143C021000AF4F01443C -:103FA0008F500E1CAF500148A34001528F8400383F -:103FB000A740015AAF400160A7400158AF4E0154DD -:103FC0000A000215AF4201788F490E14AF4901442F -:103FD0008F430E1C0A00028E240200403C0E20FF7C -:103FE00027BDFFE03C1A80003C0F800835CDFFFD67 -:103FF000AFBF001CAFB20018AFB10014AFB00010DB -:10400000AF8F0040AF4D0E00000000000000000028 -:104010000000000000000000000000003C0C00FF59 -:10402000358BFFFDAF4B0E003C0660048CC9500081 -:10403000240AFF7F3C116000012A40243507380C18 -:10404000ACC750008E24043824050009AF45000891 -:104050003083FFFF38622F712450C0B3AF80004817 -:104060000E000068AF80000052000001AE20442C1A -:104070000E0004353C1180000E000EA83630007092 -:104080008F8A00403C12080026523BC8020088215B -:104090008E0800008F5F00003BF9000133380001FB -:1040A00013000017AF880030022048218D27000040 -:1040B0003C0F08008DEF006C3C0C08008D8C0068F4 -:1040C00000E8C02301F828210000682100B8302B47 -:1040D000018D5821016640213C010800AC25006C8F -:1040E0003C010800AC2800688F44000038830001C0 -:1040F000306200011440FFED00E04021AF87003046 -:104100008E0C00003C0508008CA5006C3C040800E7 -:104110008C8400680188302300A63821000010211B -:1041200000E6402B008218210068F8213C010800BD -:10413000AC27006C3C010800AC3F00688F490100CF -:1041400025590088AF990044AF890038AF49002055 -:104150008E070000AF8700308F4D017805A0FFFE6D -:10416000000000008E0600003C0B08008D6B007400 -:104170003C0408008C84007000C728230165F821E6 -:104180000000102103E5402B0082382100E8C821FF -:10419000240908003C010800AC3F00743C01080001 -:1041A000AC390070AF49017893580108A398003EDC -:1041B000938F003E31EE000115C000158F8300384B -:1041C000240E0D00106E0019240F0F00106F001D3B -:1041D000000000009159000024180050332900FF0E -:1041E000113800043C1F4000AF5F01380A0002E7AD -:1041F000000000000E0008EE000000008F8A004062 -:104200003C1F4000AF5F01380A0002E700000000D9 -:10421000938D003E31AC0006000C51000E0000CE24 -:104220000152D8210A0003438F8A00403C1B08003A -:10423000277B3C480E0000CE000000000A0003432C -:104240008F8A00403C1B0800277B3C680E0000CE94 -:10425000000000000A0003438F8A004090AA00017A -:104260008FAB00108CAC00103C0300FF8D68000485 -:10427000AD6C00208CAD001400E060213462FFFFC3 -:10428000AD6D00248CA700183C09FF000109C02473 -:10429000AD6700288CAE001C0182C8240319782564 -:1042A000AD6F0004AD6E002C8CAD0008314A00FFEC -:1042B000AD6D001C94A900023128FFFFAD6800100D -:1042C00090A70000A5600002A1600004A1670000A3 -:1042D00090A30002306200FF000219821060000506 -:1042E000240500011065000E0000000003E0000836 -:1042F000A16A00018CD80028354A0080AD780018EA -:104300008CCF0014AD6F00148CCE0030AD6E000861 -:104310008CC4002CA16A000103E00008AD64000C0D -:104320008CCD001CAD6D00188CC90014AD69001453 -:104330008CC80024AD6800088CC70020AD67000C55 -:104340008CC200148C8300640043C82B1320000728 -:10435000000000008CC20014144CFFE400000000B8 -:10436000354A008003E00008A16A00018C820064E5 -:104370000A0003990000000090AA000027BDFFF882 -:104380008FA9001CA3AA00008FAE00003C0FFF8085 -:104390008FA8001835E2FFFF8CCD002C01C26024ED -:1043A000AFAC0000A120000400E06021A7A0000243 -:1043B0008FB800008D2700040188182100A0582123 -:1043C00000C05021006D28263C06FF7F3C0F00FFF7 -:1043D0002CAD000135EEFFFF34D9FFFF3C02FF009A -:1043E00003193024000D1DC0010EC82400E2C024B2 -:1043F00000C3702503197825AD2E0000AD2F0004F1 -:104400008D450024AFAE0000AD2500088D4D002085 -:104410002405FFFFAD2D000C956800023107FFFF5A -:10442000AD2700109166001830C200FF000219C2CB -:10443000506000018D450034AD2500148D670008E3 -:1044400027BD0008AD27001C8C8B00CCAD2C0028AC -:10445000AD20002CAD2B0024AD20001803E0000897 -:10446000AD20002027BDFFE0AFB20018AFB10014AF -:10447000AFB00010AFBF001C9098000000C08821B2 -:104480003C0D00FF330F007FA0CF0000908E000195 -:1044900035ACFFFF3C0AFF00A0CE000194A6001E31 -:1044A000A22000048CAB00148E29000400A08021FF -:1044B000016C2824012A4024008090210105202538 -:1044C000A6260002AE2400042605002026240008AB -:1044D0000E00007624060002924700002605002800 -:1044E0002624001400071E000003160324060004FF -:1044F000044000032403FFFF965900023323FFFF0B -:104500000E000076AE230010262400248FBF001C6E -:104510008FB200188FB100148FB000102405000373 -:10452000000030210A00008027BD002027BDFFD8F1 -:10453000AFB1001CAFB00018AFBF002090A80000C2 -:10454000240200018FB0003C3103003F008088212D -:10455000106200148FAA0038240B0005506B00165F -:10456000AFAA001000A0202100C028210E0003DC0B -:1045700002003021922400BC30830002106000034E -:1045800026060030ACC0000024C600048FBF002007 -:104590008FB1001C8FB0001800C0102103E000088C -:1045A00027BD0028014038210E00035AAFB000108B -:1045B0000A000420000000000E0003A1AFB00014A8 -:1045C0000A000420000000003C02000A03421821F7 -:1045D0003C04080024843CAC2405001A000030216F -:1045E0000A000080AF8300543C03800034620070F6 -:1045F0008C48000000A0582100C04821308A00FFEC -:10460000AF8800308F4401780480FFFE3C0C8000AE -:10461000358600708CC500003C0308008C63007474 -:104620003C1808008F18007000A82023006468213F -:104630000000C82101A4782B0319702101CF60214B -:104640003C010800AC2D00743C010800AC2C00704B -:104650008F480E14AF480144AF47014CA34A0152A2 -:10466000A74B01589346010830C5000854A000012B -:1046700035291000934B090024070050316A00FFD0 -:1046800011470007000000008F450E1CAF45014890 -:10469000AF4901543C09100003E00008AF4901781C -:1046A000934D010831A8000811000010000000001F -:1046B000934F010831EE001051C000013529000868 -:1046C0003C04080090843D10A34401508F4309A48A -:1046D000AF4301488F4209A0AF420144AF490154A2 -:1046E0003C09100003E00008AF4901783C190800BC -:1046F0008F393CCC333800085700FFF135290008CA -:104700000A0004730000000024070040AF470814AB -:10471000AF4008108F4209448F4309508F44095419 -:104720008F45095C8F46094CAF820064AF8300500F -:10473000AF84004CAF85005C03E00008AF860060EA -:104740009346010930C5007F000518C000052140CF -:104750000083102103E00008244200883C0A08007E -:10476000914A3CD13C09080095293CCA3C051100FE -:10477000000A3C002528000200E8302500C5182565 -:1047800024820008AC83000003E00008AC80000431 -:104790008F4A002C974E09083C0F000E034F38211A -:1047A00031CDFFFF000D41C0AF48002C97430908F1 -:1047B00094EC001A0080402124020001318BFFFF9D -:1047C000AC8B00008CE9001C00A0582100C06021C7 -:1047D000AC8900048CE40020AD04000890E30019CB -:1047E00030630003106200400000000028650002F2 -:1047F00014A00073240600021066004E00000000A2 -:104800002418000310780057000000003C0908003D -:1048100095293CC093450934934609213C0E080074 -:1048200095CE3CC630A200FF0002C88294E5002A63 -:1048300030C400FF978700580019C60000041C0010 -:10484000312FFFFF0303102501CF6821004DC8253C -:1048500000A720213C0640000326C02500044C0090 -:10486000AD090004AD180000934F09203C03000679 -:1048700025090014000F760001C36825AD0D00085E -:104880008F42092C24E5000130A67FFFAD02000C09 -:104890008F59093025020028A7860058AD1900104D -:1048A0008F440938AD040014AD2B00048F58094023 -:1048B000AD380008934F09373C0D080091AD3CD04E -:1048C000AD20001031EE00FF01CC1821000367007D -:1048D000000D4400018858253567FFFFAD27000C07 -:1048E00003E00008AF4A002C3C09080095293CC0B1 -:1048F0003C05080094A53CCA3C0F080095EF3CBC61 -:1049000094E400243126FFFF00A6702101CF682324 -:1049100000041C0025A2FFF20062C825241808002C -:10492000AD19000CAD180014AD0000100A0004C849 -:104930002508001894E6002494E500283C090800A6 -:1049400095293CC000067C000005740035ED81000F -:1049500035C40800AD0D000CAD0400100A0004C8F9 -:10496000250800143C09080095293CC03C020800B9 -:1049700094423CCA3C06080094C63CBC94E4002423 -:104980003125FFFF94F800280045C821032678232D -:1049900000181C0000046C0025EEFFEE006EC82518 -:1049A00035A2810024180800AD02000CAD190010DA -:1049B000AD180018AD0000140A0004C82508001C3A -:1049C0001460FF920000000094E300243C090800FA -:1049D00095293CC00003140034590800AD19000C9F -:1049E0000A0004C82508001003E00008240201F4AE -:1049F00027BDFFE8AFB00010AFBF00140E0000608D -:104A00000080802124050040AF4508148F830050AA -:104A10008F84004C8F85005C007018210064102387 -:104A200018400004AF830050AF6300548F660054F9 -:104A3000AF86004C1200000C000000008F44007490 -:104A4000936800813409FA002D07000710E0000583 -:104A500000891021936C0081240B01F4018B500418 -:104A600001441021AF62000C8F4E095C01C5682320 -:104A700019A000048FBF00148F4F095CAF8F005C3A -:104A80008FBF00148FB000100A00006227BD00180D -:104A90008F8400648F8300508F82004CAF64004489 -:104AA000AF63005003E00008AF6200543C03800095 -:104AB000346200708C43000027BDFFF8308700FF90 -:104AC00030A900FF30C800FFAF8300308F44017869 -:104AD0000480FFFE3C028000345900708F380000D3 -:104AE000A3A700033C0708008CE700748FAC00000C -:104AF0003C0608008CC60070030378233C0E7FFF41 -:104B000000EFC82135CDFFFF00005021018D282482 -:104B100000CA1821000847C0032F202B00A8102529 -:104B20000064C021AFA200003C010800AC39007451 -:104B30003C010800AC380070934F010AA3A00002AA -:104B40003C0E80FFA3AF00018FAC0000312B007F33 -:104B500035CDFFFF018D4824000B5600012A40256A -:104B6000240730002406FF803C05100027BD000804 -:104B7000AF48014CAF470154A7400158A34601522A -:104B800003E00008AF45017827BDFFE8AFBF001480 -:104B9000AFB000108F6500743C068000309000FFBD -:104BA00000A620250E000060AF640074936300052A -:104BB000346200080E000062A3620005020020219A -:104BC0008FBF00148FB000102405000524060001DB -:104BD0000A00056E27BD001827BDFFE03C038000DA -:104BE000AFB00010AFBF0018AFB100143462007056 -:104BF0008C470000309000FF30A800FFAF870030E6 -:104C00008F4401780480FFFE3C188000371100704B -:104C10008E2F00003C0D08008DAD00743C0A08008A -:104C20008D4A007001E7702301AE28210000582151 -:104C300000AE302B014B4821012638213C010800F1 -:104C4000AC250074000088213C010800AC270070EE -:104C50001100000F000000008F6200742619FFFF92 -:104C60003208007F0002FE0233E5007F15000006D7 -:104C7000332200FF2407FF800207202624A3FFFF22 -:104C800000838025320200FF00408021241110089B -:104C90000E000060000000008F4908183125000454 -:104CA00014A0FFFD3218007F001878C00018714072 -:104CB00001CF682125AC0088AF4C0818274A09802D -:104CC0008D4B0020AF4B01448D460024AF46014878 -:104CD000A35001500E000062A7400158022010218D -:104CE0008FBF00188FB100148FB0001003E00008D0 -:104CF00027BD002027BDFFE8308400FFAFBF0010B4 -:104D00000E0005B930A500FF8F8300508FBF001043 -:104D1000344500402404FF903C02100027BD0018D9 -:104D2000AF43014CA3440152AF45015403E00008D6 -:104D3000AF4201789343093E306200081040000DF5 -:104D40003C0901013528080AAC8800008F4700742F -:104D5000AC8700043C06080090C63CD030C500106B -:104D600050A00006AC8000088F6A0060AC8A000882 -:104D70002484000C03E00008008010210A000620B3 -:104D80002484000C27BDFFE8AFBF0014AFB00010B3 -:104D90009346093F00A05021000528800085382354 -:104DA00030C200FF240300063C09080095293CC6D8 -:104DB00024E8FFD82405000410430037240600022D -:104DC0009750093C3C0F020400063400320EFFFFEE -:104DD00001CF6825AC8D0000934C093E318B00203B -:104DE0001160000800000000934309363C020103F3 -:104DF000345F0300307900FF033FC025240500081D -:104E0000AC98000493430934935909210005F882B2 -:104E1000306200FF0002C082332F00FF00186E00D6 -:104E2000000F740001AE6025018920253C09400077 -:104E300000898025ACF0FFD8934309378F4F09488C -:104E40008F580940306200FF004AC821033F70219B -:104E500001F86023000E6F0001A650253185FFFF89 -:104E6000001F58800145482501683821AD09002000 -:104E70000E00006024F00028240400040E000062EC -:104E8000A364003F020010218FBF00148FB00010F8 -:104E900003E0000827BD00180A00063324060012AC -:104EA00027BDFFD024090010AFB60028AFB50024FD -:104EB000AFB40020AFB10014AFB000103C01080047 -:104EC000A0293CD0AFBF002CAFB3001CAFB200187C -:104ED00097480908309500FF3C02000E3107FFFF9C -:104EE000000731C0AF46002C974409089344010BDA -:104EF00030B400FF03428021308300300000B02135 -:104F00001060010700008821240C00043C01080007 -:104F1000A02C3CD0934B093E000B5600000A2E03F8 -:104F200004A0014B00000000AF400048934F010B6C -:104F300031EE002011C00006000000009358093E29 -:104F400000189E00001396030640016B000000004D -:104F50009344010B30830040106000038F93005096 -:104F60008F8200502453FFFF9347093E30E600082C -:104F700014C0000224120003000090219619002C96 -:104F800093580934934F0937A7990058330C00FF01 -:104F900031EE00FF024E6821000D5880016C502157 -:104FA000015140213C010800A4283CC6920500188C -:104FB00030A900FF010918213C010800A4233CC8C6 -:104FC00092110018162000032467000A0000000D4B -:104FD0002467000A30F0FFFF3C010800A4233CCA0C -:104FE0003C010800A4203CC03C010800A4203CBCBB -:104FF0000E00009E020020210E00049A0040202195 -:105000008F4B002C974A09083C0C000E034C3821AA -:105010003145FFFF000549C0AF49002C97430908FF -:1050200094F1001A00404021241F00013226FFFFA6 -:10503000AC4600008CE2001CAD0200048CE40020B1 -:10504000AD04000890E3001930630003107F00D620 -:10505000286D000215A0011C240E0002106E010E26 -:10506000240F0003106F00E3000000003C0908005B -:1050700095293CC0934E0934935109213C0A0800FC -:10508000954A3CC631CD00FF94F9002A000D1882E4 -:1050900097870058322C00FF00032E00000C2400DC -:1050A0003126FFFF3142FFFF00A4F82500464821CA -:1050B00003E97825032770213C18400001F8682592 -:1050C000000E8C00AD0D0000AD110004934C0920C2 -:1050D0003C03000625110014000C2E0000A310252F -:1050E000AD0200088F49092C24E40001309F7FFFA6 -:1050F000AD09000C8F46093025090028A79F0058EC -:10510000AD0600108F59093801203021AD19001467 -:10511000AE3300048F580940AE380008934F09376A -:105120003C0C0800918C3CD0AE20001031EE00FF0A -:1051300001D26821000D2F00000C1C0000A31025D7 -:105140003447FFFFAE27000CAF4B002C934B093EBA -:10515000317300081260000D3C0F010135E7080AA9 -:10516000AD0700288F4B0074AD2B00043C130800E2 -:1051700092733CD03268001051000003AD2000084B -:105180008F780060AD3800082526000C12C000386A -:1051900000000000935F093F241600062407000466 -:1051A00033F900FF133600D2240800029743093C6C -:1051B0003C0C02043064FFFF008C2825ACC50000C5 -:1051C0009342093E304900201120000800000000F1 -:1051D000934B09363C130103366E0300316D00FF1B -:1051E00001AE8825ACD10004240700089349093496 -:1051F00093590921314BFFFF313F00FF001FB0825F -:10520000333800FF0016560000187C00014F982527 -:1052100000122880026B68253C0E400000C5502318 -:1052200001AE8825AD51FFD8934309378F5F0948F8 -:105230008F490940306C00FF019210210007208245 -:105240000044C82103E978230019C7000008B4000E -:105250000316402531E7FFFF010730250E000060EF -:10526000AD46FFF8241200040E000062A372003F56 -:105270000E0000C7020020213C12080092523CD0D0 -:10528000325000031200000F02A020218F82005034 -:1052900024470001AF870050AF6700508F6800546B -:1052A0000107302318C0000200E020218F64005461 -:1052B000AF6400548F4C0074258401F4AF64000C7B -:1052C00002A0202102802821A76000680E0005B9F5 -:1052D0003C1410008F8D005034550006AF4D014C2A -:1052E0008F9100488FBF002C8FB600282623000125 -:1052F000AF8300488FB3001CA35101528FB2001836 -:10530000AF5501548FB10014AF5401788FB500240C -:105310008FB400208FB0001003E0000827BD0030DC -:105320009358093E00189E00001396030642005150 -:105330002411000293440923308300021060FEFB15 -:105340008F8600608F82005014C2FEF800000000BB -:105350000E000060000000009369003F2407001663 -:10536000312800FF1107000C240500083C0C080040 -:10537000918C3CD0358B00013C010800A02B3CD027 -:10538000936A003F314300FF10650065240D000A59 -:10539000106D005E2402000C0E0000620000000090 -:1053A0000A00068E000000003C09080095293CC058 -:1053B0003C04080094843CCA3C1F080097FF3CBC96 -:1053C00094F800243123FFFF0083C821033F782392 -:1053D00000186C0025EEFFF201AE6025240A0800DB -:1053E000AD0C000CAD0A0014AD0000100A0006E080 -:1053F000250800183C09080095293CC03C1F0800FE -:1054000097FF3CCA3C19080097393CBC94EF002434 -:105410003124FFFF94EE002803E4C0210319682320 -:10542000000F2C00000E540025ACFFEE014C882527 -:1054300034A2810024060800AD02000CAD1100105A -:10544000AD060018AD0000140A0006E02508001C97 -:105450008F6E00848F4D094011A0FEB3AF8E0050B7 -:10546000240F00143C010800A02F3CD00A00068D38 -:10547000000000003C010800A0313CD0935F093ED1 -:105480002416000133F900201720FEA8241100087B -:105490000A00068E2411000494E5002494F10028EB -:1054A0003C09080095293CC0000514000011340097 -:1054B0003444810034C30800AD04000CAD03001077 -:1054C0000A0006E0250800141460FEE80000000051 -:1054D00094FF00243C09080095293CC0001FCC0023 -:1054E00037380800AD18000C0A0006E02508001047 -:1054F0000A00072E240800128F7F004CAF7F005453 -:105500008F7900540A000697AF790050A362003FDC -:105510000E000062000000000A00068E000000007D -:10552000240200140A000807A362003F27BDFFE819 -:10553000308400FFAFBF00100E0005B930A500FF9A -:105540009378007E9379007F936E00809368007A51 -:10555000332F00FF00186600000F6C0031CB00FFF6 -:10556000018D4825000B52008FBF0010012A3825FD -:10557000310600FF3444700000E628252402FF8134 -:105580003C03100027BD0018AF45014CAF44015447 -:10559000A342015203E00008AF43017827BDFFD8C2 -:1055A000AFB20018AFB10014AFB00010AFBF002011 -:1055B000AFB3001C93420109308600FF30B000FFFA -:1055C000000618C232040002307100011480000588 -:1055D000305200FF9367000530E5000810A0000D71 -:1055E00030C80010024020210E0005A5022028210D -:1055F000240400018FBF00208FB3001C8FB200185D -:105600008FB100148FB000100080102103E000085B -:1056100027BD002815000032000000009343010957 -:10562000000028213062007F000220C00002F94003 -:1056300003E4982126790088033B98218E78002482 -:105640008E6F0008130F0046000000008F64008476 -:10565000241800020004FD8233F900031338007C93 -:105660000000000093660083934A0109514600043C -:105670003205007C10A00060000000003205007CB4 -:1056800014A000530240202116200006320400011D -:105690008E7F00248F59010417F9FFD600002021C6 -:1056A000320400011080000A024020218F4209408C -:1056B0008F93006410530006000000000E00066B7C -:1056C000022028218F430940AF630044024020217B -:1056D0000E000600022028210A00084024040001D0 -:1056E0003C0908008D290064252600013C010800C2 -:1056F000AC26006416000012000000008F6D0084CC -:105700003C0E00C001AE602415800005024020213F -:105710000E00080E022028210A000840240400017F -:10572000240500040E00056E24060001024020211D -:105730000E00080E022028210A000840240400015F -:105740000E00004124040001936B007D020B5025E4 -:105750000E000062A36A007D0A0008838F6D00843A -:105760008F6600748F4801048E67002400064E0285 -:105770001507FFB63126007F936B00832644000196 -:10578000308A007F11460043316300FF5464FFB04C -:105790008F6400842645000130B1007F30A200FFF5 -:1057A0001226000424050001004090210A0008563A -:1057B00024110001240FFF80024F702401CF902696 -:1057C000324200FF004090210A00085624110001D7 -:1057D0000E00066B02202821321800301300FFAAA9 -:1057E00032100082024020210E0005A5022028214F -:1057F0000A000840240400018F6E00743C0F8000F2 -:105800002405000301CF9025AF72007493710083CB -:10581000240600010E00056E322400FF0E00004138 -:1058200024040001936D007D020D60250E000062CE -:10583000A36C007D3C0B08008D6B005425700001AB -:105840003C010800AC3000540A0008402404000168 -:105850008F6800743C098000240500040109382584 -:10586000AF67007493630083240600010E00056E89 -:10587000306400FF0E000041240400019362007DAB -:10588000020298250E000062A373007D0A00084002 -:1058900024040001324D008039AC0080546CFF6C50 -:1058A0008F6400840A0008A92645000127BDFFC8AF -:1058B0003C0A0008AFBF0030AFB5002CAFB40028E1 -:1058C000AFB30024AFB20020AFB1001CAFB00018DE -:1058D000034AD82124090040AF490814AF400810FA -:1058E0008F4209448F4309508F4609548F47095C02 -:1058F0008F48094C934401089345010BAF82006423 -:10590000308400FF30A500FFAF830050AF86004C0D -:10591000AF87005C0E00082AAF8800601440017455 -:105920008FBF0030A7600068934D0900240B005022 -:105930003C15080026B53C8831AC00FF3C1208003D -:1059400026523C98118B0003000000000000A821A3 -:1059500000009021935101098F9F005024040010F2 -:10596000322E007F000E68C0000E6140018D28219C -:1059700024B40088AF5408188F4901048F4A09A441 -:105980003C0B000E034BC021012A10233C010800F0 -:10599000AC223CAC8F4309583C010800A0243CD009 -:1059A00097470908007F30233C010800AC263CB033 -:1059B00030E8FFFF0008C9C03C010800AC3F3CD400 -:1059C000AF59002C974209089710002C8EB10000A7 -:1059D000930F001803749821A7900058AF930044C8 -:1059E0000220F80931F000FF304E000215C001A975 -:1059F000304F000111E0015D000000009343093EBB -:105A00003066000814C00002241400030000A02126 -:105A10008F5809A4241300013C010800AC383CD87D -:105A2000934F09349351093731EC00FF322E00FFB8 -:105A3000028E6821000D288000AC502101505821B1 -:105A40003C010800A42B3CC83C010800A42A3CC629 -:105A500093490934312200FF0202202124900010D2 -:105A60003C010800A4303CC4240700068F9F00506E -:105A70003C010800AC273CCC8F88005C8F5909584A -:105A800000008021011F282304A00151033F20238F -:105A90000480014F00A4302B10C001510000000011 -:105AA0003C010800AC253CB08E4200000040F809E3 -:105AB0000000000030430002146000F10040882123 -:105AC00030440001548000108E4200043C0908005C -:105AD0008D293CB43C0AC000012A8025AF500E003D -:105AE0008F45000030AB00081160FFFD0000000092 -:105AF000974D0E0824100001A78D003C8F4C0E041A -:105B0000AF8C00348E4200040040F8090000000011 -:105B100002228825322E000215C0016F000000000D -:105B20003C09080095293CBC3C06080094C63CC8CA -:105B30003C04080094843CBE3C1808008F183CB418 -:105B4000012658213C0F08008DEF3CD83C1F08006F -:105B500097FF3CD2016418218F4D09400309C821E9 -:105B6000246E0002033F282101F860213C01080057 -:105B7000A42B3CCAAF8D00643C010800AC2C3CD87F -:105B80003C010800A4253CC00E00009E31C4FFFF6C -:105B90008F870048004020213C010800A0273CD10D -:105BA0008E42000824E80001AF8800480040F80950 -:105BB000000000008F4B002C974909083C0A000E9A -:105BC000034A38213124FFFF000419C08F8A005096 -:105BD000AF43002C9743090894E6001A0040402187 -:105BE00030DFFFFFAC5F00008CF9001CAC590004F3 -:105BF0008CF80020AC58000890EF001931E3000346 -:105C0000107300FB0000000028620002144001171E -:105C10002405000210650109240C0003106C00BC6F -:105C2000000000003C09080095293CC0935F09343E -:105C3000934C09213C0D080095AD3CC633F900FF9B -:105C400094E5002A0019C082318F00FF978C00581C -:105C500000181600000F74003124FFFF004E382595 -:105C600001A4302100E6F82500ACC8213C03400027 -:105C700003E3C02500194C00AD180000AD09000475 -:105C8000934F09203C0E000625090014000F6E00FA -:105C900001AE2825AD0500088F46092C258200019C -:105CA00030477FFFAD06000C8F440930A7870058AE -:105CB00025060028AD0400108F43093800C02021BC -:105CC000AD030014AD2A00048F5F0940AD3F00080A -:105CD000935909373C0E080091CE3CD0AD200010FE -:105CE000333800FF03147821000F6700000E6C00AA -:105CF000018D282534A2FFFFAD22000CAF4B002CF4 -:105D00009347093E30EA00085140000F8E58000CBE -:105D10003C0301013469080AAD0900288F4A007468 -:105D2000ACCA00043C0B0800916B3CD031680010F9 -:105D300051000003ACC000088F650060ACC50008CE -:105D400024C4000C8E58000C0300F8090000000069 -:105D50003C0F080095EF3CCA3C02080094423CBE50 -:105D600001E2702125C400020E0000C73084FFFF4D -:105D70003C0608008CC63CAC3C0D08008DAD3CB424 -:105D800000CD38233C010800AC273CAC14E00006F1 -:105D9000000000003C1908008F393CCC372C004033 -:105DA0003C010800AC2C3CCC120000858F8B0044D9 -:105DB0008F480E108F900044AE0800208F5F0E18A1 -:105DC000AE1F00243C10080096103CC00E0000607E -:105DD0000000000024050040AF4508148F830050E8 -:105DE0008F89004C0070182100695023194000046D -:105DF000AF830050AF6300548F670054AF87004CEF -:105E00001200000C000000008F440074936D0081AC -:105E1000340EFA002DA6000710C00005008E1821D0 -:105E200093780081240201F40302780401E418212C -:105E3000AF63000C8F4C095C8F99005C01992023A3 -:105E400018800003000000008F50095CAF90005CD8 -:105E50000E000062000000008F8B00508E48001082 -:105E60003C010800AC2B3CD40100F8090000000004 -:105E70003C1F08008FFF3CAC17E0FEFC2407000627 -:105E80008F450024974209088F8A00648F94005040 -:105E90003C0F001F978700588F8300548F93004C4E -:105EA000304DFFFF35EEFF8000AE4824000D31C0BD -:105EB00032320010AF460024A467002CAF49002402 -:105EC000AF6A0044AF740050AF7300545640007E78 -:105ED0008EB8000432240040548000328EB1000895 -:105EE0008EAC000C0180F809000000008FBF00306C -:105EF0008FB5002C8FB400288FB300248FB2002000 -:105F00008FB1001C8FB0001803E0000827BD0038D7 -:105F10003C09080095293CC03C04080094843CCA14 -:105F20003C1F080097FF3CBC94F800243123FFFF7E -:105F300094EF00280083C821033F702300182C0031 -:105F4000000F640025CDFFEE018D302534A28100C5 -:105F500024030800AD02000CAD060010AD030018CC -:105F6000AD0000140A0009CE2508001C9347010962 -:105F70008F8800380007FE0003E8C825AF5900806D -:105F80008F5809A08F5309A4AFB80010AF580E1452 -:105F90008FB40010AF540E10AF530E1C0A0009420C -:105FA000AF530E180220F809000000008EAC000C60 -:105FB0000180F809000000000A000A7F8FBF00304E -:105FC000A5600020A57300220A000A34AD730024E6 -:105FD0003C010800AC203CB00A00096E8E42000073 -:105FE0003C010800AC243CB00A00096E8E4200005F -:105FF0003C09080095293CC03C1F080097FF3CCA9B -:106000003C19080097393CBC94EF00243124FFFF71 -:1060100003E4C02103197023000F640025CDFFF2B3 -:10602000018D2825AC45000C24020800AD020014A7 -:10603000AD0000100A0009CE2508001894E60024DF -:1060400094E300283C09080095293CC00006240080 -:106050000003FC003499810037F80800AD19000CEA -:10606000AD1800100A0009CE250800141460FEEDDA -:106070000000000094EF00243C09080095293CC072 -:10608000000F740035CD0800AD0D000C0A0009CEDC -:106090002508001093520109000028210E00060077 -:1060A000324400FF8FBF00308FB5002C8FB4002822 -:1060B0008FB300248FB200208FB1001C8FB0001866 -:1060C00003E0000827BD00380300F80900000000C5 -:1060D0000A000A79322400401200FF690000000023 -:1060E0008F540E148F920044AE5400208F530E1C18 -:1060F0000A000A63AE5300248F82001C00804021F6 -:106100003C0401009047008530E300201060000946 -:10611000000000003C0708008CE73CD48F83001887 -:1061200000E32023048000089389000414E30003A3 -:106130000100202103E00008008010213C04010040 -:1061400003E00008008010211120000B00673823B5 -:106150008F8C002024090034918B00BC316A00022E -:10616000514000012409003000E9682B15A0FFF11F -:106170000100202100E938232419FFFC00B9C024C4 -:1061800000F9782400F8702B15C0FFEA01E82021FF -:1061900030C200030002182314C00012306900034B -:1061A0000000302100A9702101C6682100ED602B9C -:1061B0001180FFE03C0401002D2F00010006482B58 -:1061C0000105382101E9302414C0FFDA24E4FFFC82 -:1061D0002419FFFC00B9C0240308202103E00008B3 -:1061E000008010218F8B002024060004916A00BCDF -:1061F000314400041480FFEC00A970210A000B2D2B -:106200000000302127BDFFE8AFBF00108F4601001E -:10621000934A01093C1F08008FFF00902407FF806C -:10622000314F00FF31E8007F0008614003E6C821DC -:10623000032CC02127090120012770243C010800FC -:10624000A02F3D10AF4E080C3C0D08008DAD009006 -:106250003C0400803482000301A65821016C1821FF -:106260002465012030AA007801424025AF48081C6F -:106270003C1F08008FFF00908F88004003E6C0217C -:106280003319000703074824033A7821AF4900284F -:1062900025E909C0952E00023C0D08008DAD008C4B -:1062A0003C0A08008D4A009031CC3FFF01A618211E -:1062B000000C5980006B282100A72024AF44002C3B -:1062C000952200023C1F08008FFF008C910700857B -:1062D00030593FFF03E678210019C1800146702143 -:1062E00001F8682131CC007F31AB007F019A282171 -:1062F000017A50213C03000C3C04000E00A328212D -:106300000144102130E6002027470980AF82002C8D -:10631000AF88001CAF890024AF85002010C00006A4 -:10632000AF8700288D0200508CA4010C004430235C -:1063300018C0007700000000910C0085240DFFDFDD -:10634000018D3824A10700858F8B001C8F890024C4 -:106350008F8700288D65004CAF850018912F000DA8 -:1063600031EE002011C000170000000024090001D8 -:10637000A3890004AF80000C8CE400248F85000CFE -:10638000240A0008AF800008AF8000103C0108001C -:10639000A42A3CBE3C010800A4203CD20E000B0104 -:1063A000000030218F8500248FBF0010AF820014C1 -:1063B00090A8000D27BD00180008394203E000082E -:1063C00030E20001913F00022418000133F900FF80 -:1063D0000019218210980039240800021088005BFF -:1063E0008F86002C8CE5002414A0001B8F9F0020BA -:1063F00091220000240A00053046003F10CA0047E1 -:10640000240400018F860008A3840004AF860010D6 -:10641000AF86000C8CE400248F85000C240A000851 -:106420003C010800A42A3CBE3C010800A4203CD248 -:106430000E000B01000000008F8500248FBF0010AC -:10644000AF82001490A8000D27BD00180008394243 -:1064500003E0000830E200018CF800088CF9002409 -:106460008FEE00C4A38000048CE40024AF8E000CE7 -:106470008F85000C8F86000803197823240A0008F2 -:10648000AF8F00103C010800A42A3CBE3C0108006C -:10649000A4203CD20E000B01000000008F850024D8 -:1064A0008FBF0010AF82001490A8000D27BD001808 -:1064B0000008394203E0000830E2000191230000A7 -:1064C0003062003F104400278F8500208CE40024B8 -:1064D00014800021000000008D2E00183C187FFF62 -:1064E0008F850020370FFFFF01CF1824AF830008EE -:1064F0008F9F00088CA8008403E8C82B1720000297 -:1065000003E020218CA400840A000BBCAF840008A7 -:106510008CA3010C0A000B9AAF8300188D2C001875 -:106520008F8600083C0D7FFF8F89002035A3FFFF79 -:106530000183582424040001AF8B0010AD2000CC4F -:10654000A38400040A000BC8AF86000C8CCA001498 -:106550000A000BBCAF8A00088CA300C80A000BFF1E -:10656000AF8300088F84002C8CAC00648C8D0014E9 -:10657000018D582B11600004000000008CA2006403 -:106580000A000BFFAF8200088C8200140A000BFF88 -:10659000AF8200088F85000C27BDFFE0AFBF001859 -:1065A000AFB1001414A00007AFB000108F86002414 -:1065B0002402000590C400003083003F106200B642 -:1065C0008F8400208F91000800A080218F8C0028EC -:1065D0003C0508008CA53CB08D8B000431663FFF64 -:1065E00000C5502B5540000100C02821938D0004A8 -:1065F00011A0007300B0F82B8F9800202404003401 -:10660000930F00BC31EE000251C0000124040030A1 -:1066100000A4C82B172000D10000000000A42823EC -:1066200000B0F82B3C010800A4243CBC17E0006833 -:10663000020020213C0308008C633CAC0083102B3B -:1066400054400001008018218F8800243C0108007C -:10665000AC233CB4000048219104000D308300209D -:10666000506000018F490E188F8300140123382BCE -:1066700010E00059000000003C0408008C843CB489 -:1066800000895821006B502B114000560090602B60 -:106690000069302300C020213C010800AC263CB436 -:1066A00012000003241FFFFC1090008A3227000311 -:1066B000009FC8243C010800AC393CB43C010800F0 -:1066C000A4203CD28F84000C120400078F8300208A -:1066D000AF910008020020218C7100CCAF90000C1B -:1066E00026300001AC7000CC3C0208008C423CB467 -:1066F0008F8A0010240700180082202301422823DB -:10670000AF84000C10800002AF8500102407001039 -:106710008F86001C3C010800A0273CD024070040C5 -:1067200090CC0085318B00C0116700408F8D001424 -:1067300014A0001500002021934A01098F4209741A -:10674000314500FF0002260224A300013090007FA3 -:106750003071007F1230007A2407FF80A0C30083CD -:106760003C0908008D293CCC8F880024240D0002B0 -:10677000352C00083C010800A02D3D113C0108000B -:10678000AC2C3CCC24040010910E000D31C600202E -:1067900010C0000500801821240800013C010800F9 -:1067A000AC283CB4348300018FBF00188FB10014B3 -:1067B0008FB000100060102103E0000827BD00200A -:1067C0003C010800A4203CBC13E0FF9A02002021F9 -:1067D0000A000C5000A020213C0408008C843CB42A -:1067E0000090602B1180FFAE000000003C0F0800FD -:1067F00095EF3CBC01E4702101C6682B11A0000795 -:106800002C8200043C1F60008FF954043338003F91 -:106810001700FFE5240300422C8200041040FFA073 -:10682000240300420A000CAE8FBF0018152DFFC0D4 -:10683000000000008CDF00743C0380002405FF8012 -:1068400003E3C825ACD9007490D80085240E000459 -:1068500024040010330F003F01E54025A0C8008547 -:106860008F8800243C010800A02E3D112403000164 -:106870009106000D30C90020152000030000000023 -:106880003C0308008C633CB43C010800AC233CACE6 -:106890000A000CA5000000008F8700108C8800847F -:1068A00000E8282B14A0000200E088218C910084CD -:1068B00024090001A38900048F440E180220282116 -:1068C0000E000B0102203021022080210A000C362C -:1068D000AF82001400071823306600033C01080053 -:1068E000A4263CD2122000058F8C0020918B00BC86 -:1068F000316A00041540001524CD00043C0F080047 -:1069000095EF3CD201E4702100AE302B50C0FF6EF9 -:106910008F84000C2C85000514A0FFA324030042E3 -:106920003098000317000002009818232483FFFC0E -:106930003C010800AC233CB40A000C7200000000CB -:1069400000A758240A000C9A016718263C01080089 -:10695000A42D3CD20A000D02000000003C010800FA -:10696000AC203CB40A000CAD240300428F8300101D -:1069700014600007000010218F8800242405000502 -:106980009106000030C400FF1085000300000000E5 -:1069900003E0000800000000910A0018314900FFE0 -:1069A000000939C214E0FFFA8F85001C3C0408007E -:1069B00094843CBC3C0308008C633CD43C19080024 -:1069C0008F393CB43C0F080095EF3CD20064C021E5 -:1069D0008CAD00540319702101CF6021018D582323 -:1069E0001960001D00000000910E001C8F8C002C0F -:1069F000974B0E1031CD00FF8D850004016D3023C3 -:106A00008D88000030CEFFFF000E510000AAC82183 -:106A10000000382101072021032A182B0083C02100 -:106A2000AD990004AD980000918F000A01CF682154 -:106A3000A18D000A8F88002C974B0E12A50B000821 -:106A4000950A003825490001A50900389107000D75 -:106A500034E60008A106000D03E000080000000075 -:106A600027BDFFE0938700048F8F00248FAD0014B3 -:106A70003C0E7FFF8F89000C35C8FFFFAFBF001CA5 -:106A8000AFB0001801A8182491EA000D000717C044 -:106A90003C1FBFFF006258252D2E00018F9000186B -:106AA00037F9FFFF3C1808008F183CD43C0F080052 -:106AB00095EF3CCA01796824000E47803C07EFFF40 -:106AC0003C05F0FF01A818253149002034E2FFFF02 -:106AD00034ACFFFF0310582327A500102406000242 -:106AE00025EA00020062182400808021152000029F -:106AF000000040218F480E1CA7AA00120560003735 -:106B00002407000030FF00FF001FCF008F8B001C08 -:106B100000793825AFA70014916F00853C08080064 -:106B200091083CD13C18DFFF31EE00C0370AFFFF6F -:106B3000000E182B3C1F080097FF3CC400EA682495 -:106B4000A3A800110003174001A248258FB9001027 -:106B5000AFA900143C0A0800914A3CD3A7BF001615 -:106B60008FA80014032CC0243C0B01003C0F0FFF26 -:106B7000030B18253147000335EEFFFF010C682495 -:106B800000071600006EF8243C09700001A2C82519 -:106B900003E95825AFB90014AFAB00100E00007622 -:106BA000A3A000158F8C0024260200089186000DFA -:106BB00030C40020108000068FBF001C3C05080078 -:106BC00094A53CC024B0FFFF3C010800A4303CC0A9 -:106BD0008FB0001803E0000827BD00208F98001434 -:106BE0000118502B5540FFC7240700010A000D85EE -:106BF00030FF00FF9382000427BDFFE0AFBF001805 -:106C00001040000F008050218F880024240B0005C5 -:106C10008F890008910700008F840020010028213F -:106C200030E3003F8F86002C106B000800003821F5 -:106C3000AFA900100E00040EAFAA0014A380000438 -:106C40008FBF001803E0000827BD00208D19001831 -:106C50003C0F08008DEF3CB48F9800103C027FFF82 -:106C60008D080014345FFFFF033F682401F8702192 -:106C700001AE602301883821AFA900100E00040E78 -:106C8000AFAA00140A000DD3A38000048F8700244C -:106C90003C05080094A53CD23C0208008C423CCC48 -:106CA00090E6000D0005240030C300201060002C89 -:106CB000004440258F85001C00006021240B00014A -:106CC00090A3008500004821240A00013C0F8000A9 -:106CD00035EE00708DC70000AF8700308F58017807 -:106CE0000700FFFE3C038000347900708F380000FD -:106CF0003C0508008CA500743C0D08008DAD0070AB -:106D00000307782300AF38210000102100EF302B5B -:106D100001A22021008618213C010800AC27007444 -:106D20003C010800AC230070AF4B01483C1908003F -:106D30008F393CD4A7490144A74A0146AF59014CB9 -:106D40003C0B0800916B3CD1A34B0152AF4801545E -:106D50003C081000A74C015803E00008AF48017838 -:106D60008F4B0E1C3C0A08008D4A3CB497490E1606 -:106D7000974D0E1401456021312AFFFF0A000DF6E0 -:106D800031A9FFFF8F8300249064000D3082002022 -:106D900010400029000000000000482100005021A0 -:106DA000000040213C07800034EB00708D6700003C -:106DB000AF8700308F4C01780580FFFE3C0D8000CE -:106DC00035AC00708D8B00003C0508008CA500746C -:106DD0003C0408008C8400700167302300A67821F1 -:106DE0000000102101E6C82B0082C0210319702188 -:106DF0003C010800AC2F00743C010800AC2E007070 -:106E0000AF4901483C0D08008DAD3CD4A748014472 -:106E100024090040A74A01463C081000240AFF91BB -:106E2000AF4D014CA34A0152AF490154A74001584C -:106E300003E00008AF4801788F490E1897460E12FC -:106E400097450E1030CAFFFF0A000E2C30A8FFFF36 -:106E50008F83002427BDFFF89064000D308200204E -:106E60001040003A00000000240B000100004821FF -:106E7000240A00013C088000350700708CE3000004 -:106E8000AF8300308F4C01780580FFFE3C0E800000 -:106E90003C04080090843D1035C700708CEC000065 -:106EA0003C0508008CA50074A3A400033C1908004D -:106EB0008F3900708FAD00000183302300A6382188 -:106EC000000010210322782100E6C02B01F8602188 -:106ED00001AE4025AFA800003C010800AC270074BB -:106EE0003C010800AC2C00709346010A3C040800E9 -:106EF00090843D11A3A00002A3A600018FA300006F -:106F00003C0580FF3099007F34A2FFFF00627824A7 -:106F10000019C60001F87025240D3000AF4E014C59 -:106F200027BD0008AF4D0154A7400158AF4B0148A1 -:106F3000A7490144A74A01463C091000240AFF80E2 -:106F4000A34A015203E00008AF4901788F4B0E18A5 -:106F500097460E1297450E1030CAFFFF0A000E60CA -:106F600030A9FFFF8F85001C2402008090A40085BB -:106F7000308300C0106200058F8600208F880008D3 -:106F80008F87000CACC800C8ACC700C403E0000881 -:106F9000000000003C0A0800254A38903C0908001F -:106FA0002529395C3C08080025082D103C070800FD -:106FB00024E73A703C06080024C637003C05080068 -:106FC00024A534783C040800248430A03C03080045 -:106FD000246337983C0208002442356C3C010800C9 -:106FE000AC2A3C903C010800AC293C8C3C010800D8 -:106FF000AC283C883C010800AC273C943C010800CC -:10700000AC263CA43C010800AC253C9C3C0108009B -:10701000AC243C983C010800AC233CA83C0108008F -:0C702000AC223CA003E0000800000000CF -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex new file mode 100644 index 0000000000000000000000000000000000000000..e9bbdc3b0397c13241dd41643fcd778bbc663601 --- /dev/null +++ b/firmware/bnx2/bnx2-mips-06-6.0.15.fw.ihex @@ -0,0 +1,5815 @@ +:10000000080001180800000000004A68000000C84D +:1000100000000000000000000000000008004A6826 +:100020000000001400004B30080000A00800000091 +:100030000000568800004B4408005800000000846F +:100040000000A1CC08005688000001580000A25012 +:100050000800321008000000000072D00000A3A8C1 +:10006000000000000000000000000000080072D046 +:100070000000002400011678080004900800040025 +:10008000000017D40001169C0000000000000000D2 +:100090000000000000000000000000000000000060 +:1000A000080000A80800000000003BFC00012E70C2 +:1000B0000000000000000000000000000000000040 +:0800C000000000000000000038 +:0800C8000A00004600000000E0 +:1000D000000000000000000D636F6D362E302E31E1 +:1000E0003500000006000F020000000000000003C1 +:1000F000000000C800000032000000030000000003 +:1001000000000000000000000000000000000000EF +:1001100000000010000001360000EA600000000549 +:1001200000000000000000000000000000000008C7 +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000020000000000000000000000008D +:10017000000000000000000000000000000000007F +:10018000000000000000000000000010000000005F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E0000000000010000003000000000000000DEF +:1001F0000000000D3C02080024424AA03C03080015 +:1002000024634B9CAC4000000043202B1480FFFD76 +:10021000244200043C1D080037BD7FFC03A0F021F0 +:100220003C100800261001183C1C0800279C4AA01E +:100230000E000168000000000000000D27470100CB +:1002400090E3000B2402001A94E5000814620028D1 +:10025000000020218CE200003C0308008C63004475 +:1002600094E60014000211C20002104030A4000203 +:10027000005A10212463000130A50004A446008028 +:100280003C010800AC23004410A000190004202BFE +:100290008F4202B804410008240400013C02080017 +:1002A0008C420060244200013C010800AC22006046 +:1002B00003E00008008010218CE2002094E3001687 +:1002C00000002021AF4202808CE20004A743028498 +:1002D000AF4202883C021000AF4202B83C02080064 +:1002E0008C42005C244200013C010800AC22005C0E +:1002F00003E00008008010212747010090E3000B75 +:100300002402000394E50008146200280000202164 +:100310008CE200003C0308008C63004494E6001467 +:10032000000211C20002104030A40002005A102145 +:100330002463000130A50004A44600803C010800AD +:10034000AC23004410A000190004202B8F4202B8F7 +:1003500004410008240400013C0208008C420060B3 +:10036000244200013C010800AC22006003E00008C8 +:10037000008010218CE2002094E300160000202170 +:10038000AF4202808CE20004A7430284AF4202889D +:100390003C021000AF4202B83C0208008C42005CF4 +:1003A000244200013C010800AC22005C03E000088C +:1003B000008010218F4301002402010050620003DD +:1003C000000311C20000000D000311C20002104022 +:1003D000005A1021A440008003E000080000102112 +:1003E0009362000003E00008AF80000003E0000813 +:1003F0000000102103E00008000010212402010089 +:1004000014820008000000003C0208008C4200FC3E +:10041000244200013C010800AC2200FC0A0000DD7F +:1004200030A200203C0208008C42008424420001DB +:100430003C010800AC22008430A2002010400008DB +:1004400030A300103C0208008C4201082442000145 +:100450003C010800AC22010803E000080000000095 +:1004600010600008000000003C0208008C420104FB +:10047000244200013C010800AC22010403E0000812 +:10048000000000003C0208008C42010024420001F0 +:100490003C010800AC22010003E00008000000005D +:1004A00027BDFFE8AFBF0010274401009483000878 +:1004B000306200041040001B306600028F4202B818 +:1004C00004410008240500013C0208008C42006041 +:1004D000244200013C010800AC2200600A0001290E +:1004E0008FBF00108C82002094830016000028210A +:1004F000AF4202808C820004A7430284AF4202888C +:100500003C021000AF4202B83C0208008C42005C82 +:10051000244200013C010800AC22005C0A000129D1 +:100520008FBF001010C00006006028218F4401001A +:100530000E0000CD000000000A0001282405000183 +:100540008F8200088F4301045043000700002821D8 +:100550008F4401000E0000CD000000008F42010416 +:10056000AF820008000028218FBF001000A01021DA +:1005700003E0000827BD001827BDFFE8AFBF001447 +:10058000AFB00010974201083043700024022000F1 +:100590001062000B286220011440002F000010217F +:1005A00024024000106200250000000024026000C8 +:1005B00010620026000010210A0001658FBF0014A0 +:1005C00027500100920200091040001A2403000184 +:1005D0003C0208008C420020104000160000182148 +:1005E0000E00049300000000960300083C0608007B +:1005F00094C64B5E8E0400188F8200209605000C76 +:1006000000031C0000661825AC440000AC45000443 +:1006100024040001AC400008AC40000CAC400010C9 +:10062000AC400014AC4000180E0004B8AC43001CF1 +:10063000000018210A000164006010210E0003254B +:10064000000000000A000164000010210E000EE905 +:1006500000000000000010218FBF00148FB00010B8 +:1006600003E0000827BD001827BDFFE0AFB2001867 +:100670003C036010AFBF001CAFB10014AFB000105E +:100680008C6450002402FF7F3C1A800000822024EA +:100690003484380C24020037AC6450003C1208004B +:1006A00026524AD8AF42000824020C80AF420024F0 +:1006B0003C1B80083C06080024C60324024010218D +:1006C0002404001D2484FFFFAC4600000481FFFDCC +:1006D000244200043C020800244204B03C0108000B +:1006E000AC224AE03C020800244202303C010800EF +:1006F000AC224AE43C020800244201743C03080096 +:100700002463032C3C040800248403D83C0508001F +:1007100024A538F03C010800AC224B403C02080004 +:10072000244202EC3C010800AC264B243C010800AA +:10073000AC254B343C010800AC234B3C3C01080089 +:10074000AC244B443C010800AC224B483C0108005F +:10075000AC234ADC3C010800AC204AE83C0108001C +:10076000AC204AEC3C010800AC204AF03C010800F7 +:10077000AC204AF43C010800AC204AF83C010800D7 +:10078000AC204AFC3C010800AC204B003C010800B6 +:10079000AC244B043C010800AC204B083C01080091 +:1007A000AC204B0C3C010800AC204B103C01080075 +:1007B000AC204B143C010800AC204B183C01080055 +:1007C000AC264B1C3C010800AC264B203C01080029 +:1007D000AC254B303C010800AC234B380E000623FF +:1007E000000000003C028000344200708C42000097 +:1007F000AF8200143C0308008C6300208F82000449 +:10080000104300043C0280000E00045BAF83000430 +:100810003C028000344600703C0308008C6300A05A +:100820003C0208008C4200A4104300048F84001492 +:100830003C010800AC2300A4A743009E8CCA000022 +:100840003C0308008C6300BC3C0208008C4200B8EA +:100850000144202300641821000040210064202B63 +:1008600000481021004410213C010800AC2300BCCA +:100870003C010800AC2200B88F5100003222000772 +:100880001040FFDCAF8A00148CC600003C05080055 +:100890008CA500BC3C0408008C8400B800CA30233E +:1008A00000A628210000102100A6302B0082202164 +:1008B00000862021322700013C010800AC2500BC45 +:1008C0003C010800AC2400B810E0001F32220002F6 +:1008D0008F420100AF4200208F420104AF4200A8C6 +:1008E0009342010B0E0000C6305000FF2E02001E86 +:1008F00054400004001010800E0000C90A000213CA +:1009000000000000005210218C4200000040F80955 +:1009100000000000104000053C0240008F4301042D +:100920003C026020AC4300143C024000AF4201385E +:100930003C0208008C420034244200013C010800C3 +:10094000AC220034322200021040000E3222000499 +:100950008F4201400E0000C6AF4200200E000295FB +:10096000000000003C024000AF4201783C02080059 +:100970008C420038244200013C010800AC220038BF +:10098000322200041040FF983C0280008F42018018 +:100990000E0000C6AF4200208F43018024020F00EA +:1009A00014620005000000008F420188A742009CED +:1009B0000A0002483C0240009362000024030050F9 +:1009C000304200FF144300083C0240000E00027B4E +:1009D00000000000544000043C0240000E000D7571 +:1009E000000000003C024000AF4201B83C02080099 +:1009F0008C42003C244200013C010800AC22003C37 +:100A00000A0001C83C0280003C0290003442000110 +:100A100000822025AF4400208F4200200440FFFECA +:100A20000000000003E00008000000003C0280001D +:100A3000344200010082202503E00008AF4400207A +:100A400027BDFFE0AFB10014AFB0001000808821D7 +:100A5000AFBF00180E00025030B000FF9362007D5F +:100A60000220202102028025A370007D8F70007477 +:100A70003C0280000E000259020280241600000988 +:100A80008FBF00188F4201F80440FFFE24020002CD +:100A9000AF5101C0A34201C43C021000AF4201F8B3 +:100AA0008FBF00188FB100148FB0001003E0000852 +:100AB00027BD002027BDFFE8AFBF0010974201848B +:100AC0008F440188304202001040000500002821B8 +:100AD0000E000FAA000000000A00028D240500018C +:100AE0003C02FF0004800005008218243C02040040 +:100AF000506200019362003E240500018FBF001088 +:100B000000A0102103E0000827BD0018A360002208 +:100B10008F4401400A00025E2405000127BDFFE862 +:100B2000AFBF0014AFB0001093620000304400FF6C +:100B300038830020388200300003182B0002102B6D +:100B40000062182410600003240200501482008008 +:100B50008FBF001493620005304200011040007CFA +:100B60008FBF0014934201482443FFFF2C6200050D +:100B7000104000788FB00010000310803C03080084 +:100B800024634A68004310218C42000000400008A2 +:100B9000000000000E0002508F4401408F70000CD6 +:100BA0008F4201441602000224020001AF62000CD1 +:100BB0000E0002598F4401408F420144145000043A +:100BC0008FBF00148FB000100A000F2027BD00183F +:100BD0008F62000C0A0003040000000097620010FE +:100BE0008F4301443042FFFF1462001A00000000EE +:100BF00024020001A76200108F4202380443001053 +:100C00008F4201403C02003F3446F0003C0560004A +:100C10003C04FFC08CA22BBC0044182400461024C6 +:100C20000002130200031D82106200390000000060 +:100C30008F4202380440FFF7000000008F4201405D +:100C4000AF4202003C021000AF4202380A00032209 +:100C50008FBF0014976200100A0003040000000018 +:100C60000E0002508F440140976200128F430144EE +:100C70003050FFFF1603000224020001A762001299 +:100C80000E0002598F4401408F42014416020004B5 +:100C90008FBF00148FB000100A00029127BD00180A +:100CA000976200120A00030400000000976200141B +:100CB0008F4301443042FFFF14620006240200010A +:100CC0008FBF00148FB00010A76200140A00124AF0 +:100CD00027BD0018976200141440001D8FBF001438 +:100CE0000A00031C00000000976200168F430144B5 +:100CF0003042FFFF1462000B240200018FBF00147A +:100D00008FB00010A76200160A000B1227BD001852 +:100D10009742007824420004A76200100A000322D0 +:100D20008FBF001497620016240300013042FFFFBA +:100D3000144300078FBF00143C0208008C4200706F +:100D4000244200013C010800AC2200708FBF001457 +:100D50008FB0001003E0000827BD001827BDFFE892 +:100D6000AFBF0014AFB000108F50010093620000BD +:100D700093430109304400FF2402001F106200A5C4 +:100D80002862002010400018240200382862000A5F +:100D90001040000C2402000B286200081040002CB8 +:100DA00000000000046000E52862000214400028F2 +:100DB00024020006106200268FBF00140A00041FE0 +:100DC0008FB000101062005E2862000B144000DC3F +:100DD0008FBF00142402000E106200738FB0001049 +:100DE0000A00041F00000000106200C028620039E1 +:100DF0001040000A2402008024020036106200CA5B +:100E000028620037104000B424020035106200C18F +:100E10008FBF00140A00041F8FB000101062002B57 +:100E20002862008110400006240200C82402003914 +:100E3000106200B48FBF00140A00041F8FB00010AE +:100E4000106200998FBF00140A00041F8FB00010B9 +:100E50003C0208008C420020104000B98FBF0014F3 +:100E60000E000493000000008F4201008F830020D9 +:100E70009745010C97460108AC6200008F420104BF +:100E80003C04080094844B5E00052C00AC62000416 +:100E90008F4201180006340000C43025AC620008FF +:100EA0008F42011C24040001AC62000C9342010A31 +:100EB00000A22825AC650010AC600014AC600018DE +:100EC000AC66001C0A0003F58FBF00143C0208004A +:100ED0008C4200201040009A8FBF00140E00049333 +:100EE00000000000974401083C03080094634B5E37 +:100EF0009745010C000422029746010E8F820020C4 +:100F0000000426000083202500052C003C030080FF +:100F100000A6282500832025AC400000AC4000043A +:100F2000AC400008AC40000CAC450010AC400014D4 +:100F3000AC400018AC44001C0A0003F42404000177 +:100F40009742010C14400015000000009362000558 +:100F50003042001014400011000000000E0002504A +:100F6000020020219362000502002021344200107B +:100F70000E000259A36200059362000024030020C2 +:100F8000304200FF1043006D020020218FBF00148B +:100F90008FB000100A000FC027BD00180000000D20 +:100FA0000A00041E8FBF00143C0208008C4200207F +:100FB000104000638FBF00140E0004930000000077 +:100FC0008F4201048F8300209744010C3C050800E8 +:100FD00094A54B5EAC6200009762002C00042400D4 +:100FE0003042FFFF008220253C02400E00A228254F +:100FF000AC640004AC600008AC60000CAC60001095 +:10100000AC600014AC600018AC65001C0A0003F46E +:10101000240400010E00025002002021A7600008F5 +:101020000E00025902002021020020210E00025E63 +:10103000240500013C0208008C42002010400040C2 +:101040008FBF00140E000493000000009742010CB3 +:101050008F8300203C05080094A54B5E000214001D +:10106000AC700000AC620004AC6000088F64004CFF +:101070003C02401F00A22825AC64000C8F62005087 +:1010800024040001AC6200108F620054AC620014B2 +:10109000AC600018AC65001C8FBF00148FB000104E +:1010A0000A0004B827BD0018240200205082002541 +:1010B0008FB000100E000F0A020020211040002007 +:1010C0008FBF0014020020218FB0001000002821E3 +:1010D0000A00025E27BD0018020020218FBF001405 +:1010E0008FB000100A00058027BD00189745010C3D +:1010F000020020218FBF00148FB000100A0005A04D +:1011000027BD0018020020218FB000100A0005C57D +:1011100027BD00189345010D020020218FB000105B +:101120000A00060F27BD0018020020218FBF0014FF +:101130008FB000100A0005EB27BD00188FBF001408 +:101140008FB0001003E0000827BD00188F4202781E +:101150000440FFFE2402000234840080AF440240B9 +:10116000A34202443C02100003E00008AF420278B0 +:101170003C04080094844B6A3C0208008C424B7487 +:101180003083FFFF000318C000431021AF42003C32 +:101190003C0208008C424B70AF4200383C020050C9 +:1011A00034420008AF4200300000000000000000A0 +:1011B000000000008F420000304200201040FFFD80 +:1011C000000000008F4204003C010800AC224B608C +:1011D0008F4204043C010800AC224B643C02002016 +:1011E000AF420030000000003C02080094424B680F +:1011F0003C03080094634B6C3C05080094A54B6EBF +:1012000024840001004310213083FFFF3C010800CB +:10121000A4224B683C010800A4244B6A1465000317 +:10122000000000003C010800A4204B6A03E0000815 +:10123000000000003C05000A27BDFFE80345282107 +:101240003C04080024844B50AFBF00100E00051D65 +:101250002406000A3C02080094424B523C0308005A +:1012600094634B6E3042000F244200030043180485 +:1012700024027FFF0043102B10400002AF83001CAC +:101280000000000D0E00042A000000003C020800CF +:1012900094424B5A8FBF001027BD001803E000088E +:1012A000A74200A23C02000A034210219443000618 +:1012B0003C02080094424B5A3C010800A4234B56C0 +:1012C000004310238F83001C00021400000214034B +:1012D0000043102B03E000083842000127BDFFE85F +:1012E000AFBF00103C02000A0342102194420006E6 +:1012F0003C010800A4224B560E00047700000000B9 +:101300005440FFF93C02000A8FBF001003E00008C0 +:1013100027BD001827BDFFE8AFBF00100E000477FF +:101320000000000010400003000000000E000485D3 +:10133000000000003C0208008C424B608FBF001090 +:1013400027430400AF4200383C0208008C424B6443 +:1013500027BD0018AF830020AF42003C3C020005CF +:10136000AF42003003E00008AF8000188F82001801 +:101370003C0300060002114000431025AF4200303C +:101380000000000000000000000000008F4200008C +:10139000304200101040FFFD27420400AF820020C1 +:1013A00003E00008AF8000183C0608008CC64B64C0 +:1013B0008F8500188F8300203C02080094424B5A0E +:1013C00027BDFFE024A50001246300202442000182 +:1013D00024C70020AFB10014AFB00010AFBF001899 +:1013E000AF850018AF8300203C010800A4224B5AAF +:1013F000309000FF3C010800AC274B6404C100089A +:101400000000882104E00006000000003C02080003 +:101410008C424B60244200013C010800AC224B602E +:101420003C02080094424B5A3C03080094634B680A +:101430000010202B004310262C42000100441025F0 +:10144000144000048F830018240200101462000F5F +:10145000000000000E0004A9241100013C03080054 +:1014600094634B5A3C02080094424B681462000398 +:10147000000000000E00042A000000001600000317 +:10148000000000000E000493000000003C03080070 +:1014900094634B5E3C02080094424B5C2463000161 +:1014A0003064FFFF3C010800A4234B5E148200035C +:1014B000000000003C010800A4204B5E1200000662 +:1014C000000000003C02080094424B5AA74200A2D0 +:1014D0000A00050B022010210E0004770000000016 +:1014E00010400004022010210E00048500000000BE +:1014F000022010218FBF00188FB100148FB0001090 +:1015000003E0000827BD00203084FFFF30A5FFFF67 +:101510000000182110800007000000003082000148 +:101520001040000200042042006518210A00051343 +:101530000005284003E000080060102110C00006EC +:1015400024C6FFFF8CA2000024A50004AC8200008A +:101550000A00051D2484000403E0000800000000C8 +:1015600010A0000824A3FFFFAC86000000000000CC +:10157000000000002402FFFF2463FFFF1462FFFA53 +:101580002484000403E0000800000000240200019D +:10159000AF62000CA7620010A7620012A7620014DD +:1015A00003E00008A76200163082007F034210218A +:1015B0003C08000E004818213C0208008C42002024 +:1015C00027BDFFD82407FF80AFB3001CAFB20018BF +:1015D000AFB10014AFB00010AFBF00200080802179 +:1015E00030B100FF0087202430D200FF1040002FD0 +:1015F00000009821AF44002C9062000024030050AA +:10160000304200FF1443000E000000003C020800BE +:101610008C4200E00202102100471024AF42002C4F +:101620003C0208008C4200E0020210213042007FA0 +:101630000342102100481021944200D43053FFFF90 +:101640000E000493000000003C02080094424B5E30 +:101650008F8300200011340000C2302500122C00BE +:101660003C02400000C2302534A50001AC700000EF +:101670008FBF0020AC6000048FB20018AC7300086C +:101680008FB10014AC60000C8FB3001CAC6500106F +:101690008FB00010AC60001424040001AC6000188E +:1016A00027BD00280A0004B8AC66001C8FBF0020CC +:1016B0008FB3001C8FB200188FB100148FB00010D0 +:1016C00003E0000827BD00289343010F2402001007 +:1016D0001062000E2865001110A0000724020012FD +:1016E000240200082405003A1062000600003021A0 +:1016F00003E0000800000000240500351462FFFC30 +:10170000000030210A000538000000008F420074FC +:1017100024420FA003E00008AF62000C27BDFFE8E1 +:10172000AFBF00100E00025E240500018FBF001045 +:1017300024020001A762001227BD00182402000144 +:1017400003E00008A360002227BDFFE0AFB1001452 +:10175000AFB00010AFBF001830B1FFFF0E00025055 +:10176000008080219362003F24030004304200FF88 +:101770001443000C02002021122000082402000A59 +:101780000E00053100000000936200052403FFFEF7 +:1017900000431024A362000524020012A362003F4C +:1017A000020020210E000259A360008116200003D0 +:1017B000020020210E0005950000000002002021FB +:1017C000322600FF8FBF00188FB100148FB00010B9 +:1017D000240500380A00053827BD002027BDFFE09A +:1017E000AFBF001CAFB20018AFB10014AFB0001013 +:1017F0000E000250008080210E0005310000000024 +:101800009362003F24120018305100FF123200038F +:101810000200202124020012A362003F936200050F +:101820002403FFFE004310240E000259A3620005AA +:10183000020020212405002016320007000030217C +:101840008FBF001C8FB200188FB100148FB0001032 +:101850000A00025E27BD00208FBF001C8FB2001857 +:101860008FB100148FB00010240500390A0005382C +:1018700027BD002027BDFFE8AFB00010AFBF0014A8 +:101880009742010C2405003600808021144000108E +:10189000304600FF0E00025000000000240200123B +:1018A000A362003F93620005344200100E00053130 +:1018B000A36200050E00025902002021020020212F +:1018C0000E00025E240500200A000604000000004D +:1018D0000E000538000000000E000250020020211A +:1018E000936200232403FF9F020020210043102461 +:1018F0008FBF00148FB00010A36200230A000259AA +:1019000027BD001827BDFFE0AFBF0018AFB100141E +:10191000AFB0001030B100FF0E00025000808021F7 +:10192000240200120E000531A362003F0E0002598E +:101930000200202102002021022030218FBF001848 +:101940008FB100148FB00010240500350A0005384F +:1019500027BD0020A380002C03E00008A380002DF9 +:101960008F4202780440FFFE8F820034AF42024073 +:1019700024020002A34202443C02100003E00008DB +:10198000AF4202783C0360008C6254003042000891 +:101990001440FFFD000000008C625408AF82000C70 +:1019A00024020052AC605408AC645430AC6254342D +:1019B0002402000803E00008AC6254003C0260000E +:1019C0008C42540030420008104000053C03600087 +:1019D0008C625400304200081440FFFD00000000FB +:1019E0008F83000C3C02600003E00008AC43540805 +:1019F00090A3000024020005008040213063003FD6 +:101A000000004821146200050000502190A2001C33 +:101A100094A3001E304900FF306AFFFFAD00000CA8 +:101A2000AD000010AD000024950200148D05001CCF +:101A30008D0400183042FFFF0049102300021100FE +:101A4000000237C3004038210086202300A2102B5B +:101A50000082202300A72823AD05001CAD04001838 +:101A6000A5090014A5090020A50A001603E0000836 +:101A7000A50A00228F4201F80440FFFE2402000262 +:101A8000AF4401C0A34201C43C02100003E00008BF +:101A9000AF4201F83C0208008C4200B427BDFFE8C9 +:101AA000AFBF001424420001AFB000103C01080099 +:101AB000AC2200B48F4300243C02001F30AA00FF78 +:101AC0003442FF8030D800FF006280240080F8217B +:101AD00030EF00FF1158003B01405821240CFF80DB +:101AE0003C19000A3163007F000310C00003194055 +:101AF000006218213C0208008C4200DC25680001CD +:101B0000310D007F03E21021004310213043007F9C +:101B100003431821004C102400794821AF420024CF +:101B20008D220024016C1824006C7026AD22000C5C +:101B30008D220024310800FFAD22001095220014F0 +:101B4000952300208D27001C3042FFFF3063FFFFEC +:101B50008D2600180043102300021100000227C345 +:101B60000040282100C4302300E2102B00C23023A3 +:101B700000E53823AD27001CAD2600189522002073 +:101B8000A522001495220022154B000AA52200165A +:101B90008D2300248D220008254600013145008058 +:101BA0001462000430C4007F108F000238AA008045 +:101BB00000C0502151AF000131C800FF1518FFC906 +:101BC000010058218F8400343082007F03421821A5 +:101BD0003C02000A006218212402FF8000822024B7 +:101BE000AF440024A06A0079A06A00838C62005090 +:101BF0008F840034AC6200708C6500743C027FFFFF +:101C00003442FFFF00A228240E00066BAC6500746E +:101C1000AF5000248FBF00148FB0001003E0000805 +:101C200027BD001827BDFFC0AFBE0038AFB70034D6 +:101C3000AFB5002CAFB20020AFB1001CAFB00018A0 +:101C4000AFBF003CAFB60030AFB40028AFB3002444 +:101C50008F4500248F4600288F43002C3C02001F34 +:101C60003442FF800062182400C230240080A82182 +:101C7000AFA3001400A2F0240E00062FAFA60010A0 +:101C80003C0208008C4200E02410FF8003608821A1 +:101C900002A2102100501024AF4200243C02080090 +:101CA0008C4200E002A210213042007F0342182142 +:101CB0003C02000A00629021924200D293630084A9 +:101CC000305700FF306300FF24020001106200342F +:101CD000036020212402000214620036000000008C +:101CE0000E001216024028219223008392220083C4 +:101CF0003063007F3042007F000210C000031940B3 +:101D0000006218213C0208008C4200DC02A2102173 +:101D10000043382100F01024AF42002892250078BB +:101D20009224008330E2007F034218213C02000C21 +:101D300014850007006280212402FFFFA24200F107 +:101D40002402FFFFA64200F20A0007272402FFFF39 +:101D500096020020A24200F196020022A64200F262 +:101D60008E020024AE4200F492220083A24200F0D0 +:101D70008E4200C8AE4200FC8E4200C4AE4200F863 +:101D80008E220050AE4201008E4200CCAE420104D1 +:101D9000922200853042003F0A0007823442004010 +:101DA0000E00123902402821922200850A00078283 +:101DB0003042003F936200852403FFDF3042003F42 +:101DC000A36200859362008500431024A36200850E +:101DD0009363008393620078307400FF304200FF09 +:101DE00010540036240AFF803C0C000C3283007F24 +:101DF000000310C000031940006218213C020800D3 +:101E00008C4200DC268800013109007F02A21021EB +:101E10000043382130E2007F0342182100EA1024F9 +:101E2000AF420028006C80218E020024028A182410 +:101E3000006A5826AE02000C8E020024310800FF12 +:101E4000AE02001096020014960300208E07001CBC +:101E50003042FFFF3063FFFF8E060018004310235F +:101E600000021100000227C30040282100C43023D3 +:101E700000E2102B00C2302300E53823AE07001C1F +:101E8000AE06001896020020A60200149602002258 +:101E9000A602001692220079304200FF105400077B +:101EA0000000000051370001316800FF92220078E5 +:101EB000304200FF1448FFCD0100A0219222008390 +:101EC000A22200798E2200500A0007E2AE220070A2 +:101ED000A22200858E22004C2405FF80AE42010C18 +:101EE0009222008534420020A2220085924200D135 +:101EF0003C0308008C6300DC305400FF3C02080007 +:101F00008C4200E400143140001420C002A31821C8 +:101F100000C4202102A210210064382100461021B3 +:101F20000045182400E52824AF450028AF43002CC5 +:101F30003042007F924400D030E3007F03422821EA +:101F4000034318213C02000C006280213C02000E79 +:101F5000309600FF00A298211296002A000000008F +:101F60008E02000C02002021026028211040002572 +:101F7000261000280E00064A000000009262000DA4 +:101F800026830001307400FF3042007FA262000D02 +:101F90002404FF801697FFF0267300203C020800FF +:101FA0008C4200DC0000A02102A210210044102479 +:101FB000AF4200283C0208008C4200E43C030800C9 +:101FC0008C6300DC02A2102100441024AF42002CDC +:101FD0003C0208008C4200E402A318213063007F19 +:101FE00002A210213042007F034220210343182126 +:101FF0003C02000C006280213C02000E0A0007A493 +:10200000008298218E4200D8AE2200508E4200D825 +:10201000AE22007092250083924600D19223008365 +:10202000924400D12402FF8000A228243063007F64 +:10203000308400FF00A628250064182A10600002E2 +:1020400030A500FF38A50080A2250083A2250079D5 +:102050000E00063D000000009222007E02A020211A +:10206000A222007A8E2300743C027FFF3442FFFFDD +:10207000006218240E00066BAE2300748FA20010BD +:10208000AF5E00248FBF003CAF4200288FBE0038F7 +:102090008FA200148FB700348FB600308FB5002C9C +:1020A0008FB400288FB300248FB200208FB1001CA2 +:1020B0008FB0001827BD004003E00008AF42002C9D +:1020C00090A2000024420001A0A200003C030800EE +:1020D0008C6300F4304200FF1443000F0080302175 +:1020E000A0A000003C0208008C4200E48F84003471 +:1020F000008220213082007F034218213C02000C24 +:10210000006218212402FF8000822024ACC300005A +:1021100003E00008AF4400288C8200002442002025 +:1021200003E00008AC82000094C200003C080800F4 +:10213000950800CA30E7FFFF008048210102102106 +:10214000A4C2000094C200003042FFFF00E2102B46 +:1021500054400001A4C7000094A200003C03080002 +:102160008C6300CC24420001A4A2000094A20000D1 +:102170003042FFFF544300078F8600280107102BD1 +:10218000A4A000005440000101003821A4C70000B1 +:102190008F8600288CC4001CAF44003C94A2000031 +:1021A0008F43003C3042FFFF000210C00062182144 +:1021B000AF43003C8F42003C008220231880000483 +:1021C000000000008CC200180A00084324420001ED +:1021D0008CC20018AF4200383C020050344200105C +:1021E000AF420030000000000000000000000000CE +:1021F0008F420000304200201040FFFD0000000030 +:102200008F420404AD2200048F420400AD2200007E +:102210003C020020AF42003003E000080000000054 +:1022200027BDFFE0AFB20018AFB10014AFB000108F +:10223000AFBF001C94C2000000C080213C12080007 +:10224000965200C624420001A60200009603000038 +:1022500094E2000000E03021144300058FB100300B +:102260000E000818024038210A000875000000001E +:102270008C8300048C820004244200400461000727 +:10228000AC8200048C8200040440000400000000C2 +:102290008C82000024420001AC8200009602000003 +:1022A0003042FFFF50520001A600000096220000BD +:1022B00024420001A62200008F82002896230000FD +:1022C00094420016144300048FBF001C2402000136 +:1022D000A62200008FBF001C8FB200188FB100141F +:1022E0008FB0001003E0000827BD00208F89002870 +:1022F00027BDFFE0AFBF00188D220028274804004B +:1023000030E700FFAF4200388D22002CAF8800304C +:10231000AF42003C3C020005AF420030000000002C +:1023200000000000000000000000000000000000AD +:10233000000000008C82000C8C82000CAD020000BA +:102340008C820010AD0200048C820018AD020008DF +:102350008C82001CAD02000C8CA20014AD02001097 +:102360008C820020AD02001490820005304200FFF4 +:1023700000021200AD0200188CA20018AD02001C71 +:102380008CA2000CAD0200208CA20010AD02002433 +:102390008CA2001CAD0200288CA20020AD02002CF3 +:1023A000AD060030AD000034978300263402FFFFF5 +:1023B00014620002006020213404FFFF10E00011CD +:1023C000AD04003895230036952400362402000120 +:1023D0003063FFFF000318C20069182190650040B8 +:1023E000308400070082100400451025A0620040E0 +:1023F0008F820028944200563042FFFF0A0008DC1A +:10240000AD02003C952300369524003624020001DD +:102410003063FFFF000318C2006918219065004077 +:1024200030840007008210040002102700451024A9 +:10243000A0620040AD00003C000000000000000071 +:10244000000000003C02000634420040AF42003071 +:102450000000000000000000000000008F420000AB +:10246000304200101040FFFD8F860028AF880030FA +:1024700024C2005624C7003C24C4002824C50032CE +:1024800024C600360E000856AFA200108FBF0018F9 +:1024900003E0000827BD00208F8300243C060800CD +:1024A0008CC600E88F82003430633FFF0003198040 +:1024B00000461021004310212403FF803046007F96 +:1024C00000431024AF420028034618213C02000CB0 +:1024D0000062302190C2000D30A500FF00003821BD +:1024E00034420010A0C2000D8F8900288F8A00247A +:1024F00095230036000A13823048000324020001AD +:10250000A4C3000E1102000B2902000210400005B6 +:10251000240200021100000C240300010A0009201B +:102520000000182111020006000000000A00092026 +:10253000000018218CC2002C0A000920244300014D +:102540008CC20014244300018CC200180043102BDD +:1025500050400009240700012402002714A20003B0 +:10256000000000000A00092C240700019522003E0B +:1025700024420001A522003E000A138230430003DA +:102580002C62000210400009008028211460000421 +:102590000000000094C200360A00093C3046FFFFEC +:1025A0008CC600380A00093C008028210000302138 +:1025B0003C04080024844B780A00088900000000CD +:1025C000274901008D22000C9523000601202021BF +:1025D000000216023046003F3063FFFF240200274E +:1025E00000C0282128C7002810C2000EAF83002495 +:1025F00010E00008240200312402002110C200096A +:102600002402002510C200079382002D0A00095BF6 +:102610000000000010C200059382002D0A00095B33 +:10262000000000000A0008F4000000000A0006266E +:102630000000000095230006912400058D25000C64 +:102640008D2600108D2700188D28001C8D29002054 +:10265000244200013C010800A4234B7E3C010800F9 +:10266000A0244B7D3C010800AC254B843C010800B4 +:10267000AC264B883C010800AC274B903C0108007D +:10268000AC284B943C010800AC294B9803E00008AF +:10269000A382002D8F87002827BDFFC0AFB3003471 +:1026A000AFB20030AFB1002CAFB00028AFBF0038E0 +:1026B0003C0208008C4200D094E3003030B0FFFFB1 +:1026C000005010073045FFFF3063FFFF00C0982126 +:1026D000A7A200103C110800963100C614A3000602 +:1026E0003092FFFF8CE2002424420030AF42003CD5 +:1026F0000A0009948CE2002094E200323042FFFF8D +:1027000054A2000827A400188CE2002C24420030B8 +:10271000AF42003C8CE20028AF4200380A0009A218 +:102720008F84002827A5001027A60020022038212A +:102730000E000818A7A000208FA200182442003025 +:10274000AF4200388FA2001CAF42003C8F840028AB +:102750003C020005AF42003094820034274304005D +:102760003042FFFF0202102B14400007AF830030FD +:1027700094820054948300340202102100431023F9 +:102780000A0009B63043FFFF94830054948200345A +:102790000223182100501023006218233063FFFF2A +:1027A000948200163042FFFF144300030000000033 +:1027B0000A0009C424030001948200163042FFFF7E +:1027C0000043102B104000058F82003094820016C9 +:1027D000006210233043FFFF8F820030AC530000B3 +:1027E000AC400004AC520008AC43000C3C020006B4 +:1027F00034420010AF420030000000000000000032 +:10280000000000008F420000304200101040FFFD29 +:10281000001018C2006418219065004032040007BF +:10282000240200018FBF00388FB300348FB2003014 +:102830008FB1002C8FB000280082100400451025B5 +:1028400027BD004003E00008A062004027BDFFA8AC +:10285000AFB60050AFB5004CAFB40048AFB30044C2 +:10286000AFB1003CAFBF0054AFB20040AFB00038D2 +:102870008C9000003C0208008C4200E88F860034F7 +:10288000960300022413FF8000C2302130633FFF13 +:102890000003198000C3382100F3102490B2000017 +:1028A000AF42002C9203000230E2007F034230214D +:1028B0003C02000E00C28821306300C024020040A8 +:1028C0000080A82100A0B021146200260000A021F1 +:1028D0008E3400388E2200181440000224020001B9 +:1028E000AE2200189202000D304200201440001564 +:1028F0008F8200343C0308008C6300DC001238C077 +:10290000001231400043102100C730210046382119 +:1029100030E300073C02008030E6007800C230253A +:102920000343182100F31024AF4208002463090078 +:10293000AF4608108E2200188C6300080043102157 +:10294000AE2200188E22002C8E2300182442000193 +:102950000062182B1060003D000000000A000A7899 +:1029600000000000920300022402FFC00043102474 +:10297000304200FF1440000524020001AE2200187E +:10298000962200360A000A613054FFFF8E2200149E +:1029900024420001AE22001892020000000216003C +:1029A0000002160304410029000000009602000204 +:1029B00027A4001000802821A7A20016960200027A +:1029C00024070001000030213042FFFFAF820024C5 +:1029D0000E000889AFA0001C960300023C0408000A +:1029E0008C8400E88F82003430633FFF000319803D +:1029F00000441021004310213043007F3C05000CAF +:102A00000053102403431821AF4200280065182109 +:102A10009062000D001221403042007FA062000D44 +:102A20003C0308008C6300E48F82003400431021D3 +:102A30000044382130E2007F03421021004510217C +:102A400000F31824AF430028AEA200009222000D2C +:102A5000304200101040001302A020218F83002874 +:102A60008EA40000028030219462003E2442FFFFC9 +:102A7000A462003E948400029625000E3084FFFF7D +:102A80000E00097330A5FFFF8F82002894430034A5 +:102A90009622000E1443000302A02021240200010C +:102AA000A382002C02C028210E0007FE00000000B7 +:102AB0008FBF00548FB600508FB5004C8FB40048C4 +:102AC0008FB300448FB200408FB1003C8FB000380C +:102AD00003E0000827BD00588F82002827BDFFD0E3 +:102AE000AFB40028AFB20020AFBF002CAFB30024BA +:102AF000AFB1001CAFB00018904400D0904300D19B +:102B00000000A021309200FFA3A30010306300FF5B +:102B10008C5100D88C5300DC1072002B2402000171 +:102B20003C0308008C6300E493A400108F820034FF +:102B30002406FF800004214000431021004410219E +:102B40003043007F00461024AF4200280343182181 +:102B50003C02000C006218218C62000427A40014BF +:102B600027A50010022280210270102304400015C6 +:102B7000AFA300149062000D00C21024304200FF89 +:102B800014400007020088219062000D344200408A +:102B90000E0007FEA062000D0A000ABD93A20010FD +:102BA0000E0009E1241400018F830028AC7000D8C6 +:102BB00093A20010A06200D193A200101452FFD87B +:102BC0000000000024020001168200048FBF002CC8 +:102BD0000E000626000000008FBF002C8FB40028D6 +:102BE0008FB300248FB200208FB1001C8FB000186B +:102BF00003E0000827BD003027BDFFD8AFB3001C9D +:102C0000AFB20018AFB10014AFB00010AFBF0020DA +:102C10000080982100E0802130B1FFFF0E00049376 +:102C200030D200FF000000000000000000000000A3 +:102C30008F820020AC510000AC520004AC5300085D +:102C4000AC40000CAC400010AC400014AC4000188C +:102C50003C03080094634B5E02038025AC50001CCB +:102C6000000000000000000000000000240400013B +:102C70008FBF00208FB3001C8FB200188FB10014DB +:102C80008FB000100A0004B827BD002827BDFFE858 +:102C9000AFB00010AFBF001430A5FFFF30C600FF7B +:102CA0000080802124020C80AF420024000000003C +:102CB0000000000000000000000000000000000014 +:102CC0000E000ACC000000003C040800248400E050 +:102CD0008C8200002403FF808FBF001402021021A9 +:102CE00000431024AF4200248C8200003C03000A01 +:102CF000020280213210007F035010218FB000109B +:102D00000043102127BD001803E00008AF8200280F +:102D100027BDFFE8AFBF00108F4401403C0308000F +:102D20008C6300E02402FF80AF840034008318210C +:102D300000621024AF4200243C02000803424021FC +:102D4000950500023063007F3C02000A034318210E +:102D50000062182130A5FFFF3402FFFF0000302180 +:102D60003C07602010A20006AF8300282402FFFF6A +:102D7000A5020002946500D40E000AF130A5FFFF01 +:102D80008FBF001024020C8027BD001803E000084C +:102D9000AF4200243C020008034240219502000299 +:102DA0003C0A0800954A00C63046FFFF14C00007E1 +:102DB0003402FFFF8F8200288F8400343C0760209C +:102DC000944500D40A000B5A30A5FFFF10C200241E +:102DD0008F87002894E2005494E400163045FFFFEA +:102DE00000A6102300A6182B3089FFFF10600004F6 +:102DF0003044FFFF00C51023012210233044FFFFA1 +:102E0000008A102B1040000C012A1023240200011C +:102E1000A50200162402FFFFA502000294E500D4DB +:102E20008F8400340000302130A5FFFF3C07602074 +:102E30000A000AF1000000000044102A10400008B7 +:102E4000000000009502001630420001104000040E +:102E5000000000009742007E24420014A5020016E4 +:102E600003E00008000000008F84002827BDFFE079 +:102E7000AFBF0018948200349483003E1060001AA3 +:102E80003048FFFF9383002C2402000114620027C6 +:102E90008FBF00188F820028000818C23108000771 +:102EA000006218212447003A244900542444002099 +:102EB000244500302446003490620040304200FF38 +:102EC0000102100730420001104000168FBF0018A9 +:102ED0000E000856AFA900108F82002894420034DB +:102EE0000A000B733048FFFF94830036948200344D +:102EF0001043000E8FBF001894820036A482003465 +:102F000094820056A48200548C82002CAC8200244F +:102F100094820032A48200309482003CA482003A61 +:102F20008FBF00180A000B3327BD002003E0000804 +:102F300027BD002027BDFFE8AFBF00108F4A01006A +:102F40003C0508008CA500E03C02080090424B8440 +:102F50003C0C0800958C4B7E01452821304B003FEE +:102F600030A2007F03424021396900323C02000A4E +:102F70003963003F2C630001010240212D2900012B +:102F80002402FF8000A2282401234825AF8A0034B0 +:102F900000801821AF450024000030210080282146 +:102FA00024070001AF8800283C04080024844B78E3 +:102FB000AF8C002415200007A380002D24020020E0 +:102FC0005562000F006020213402FFFF5582000C83 +:102FD000006020212402002015620005000000008E +:102FE0008C6300142402FFFF106200070000000041 +:102FF0000E000889000000000A000BD0000000004D +:103000000E0008F4016028210E000B68000000008B +:103010008FBF001024020C8027BD001803E00008B9 +:10302000AF4200243C0208008C4200E027BDFFA014 +:10303000AFB1003C008210212411FF80AFBE0058C8 +:10304000AFB70054AFB20040AFB00038AFBF005CC4 +:10305000AFB60050AFB5004CAFB40048AFB30044BA +:10306000005110248F4800248F4900288F470028E2 +:10307000AF4200243C0208008C4200E00080902116 +:1030800024060006008210213042007F03421821EE +:103090003C02000A006280213C02001F3442FF8093 +:1030A00000E2382427A40010260500F00122F024B5 +:1030B0000102B8240E00051DAFA700308FA2001832 +:1030C000AE0200C48FA2001CAE0200C88FA2002472 +:1030D000AE0200CC93A40010920300D12402FF8022 +:1030E0000082102400431025304900FF3083007F08 +:1030F0003122007F0062102A10400004000310C03B +:1031000001311026304900FF000310C000031940B0 +:10311000006218213C0208008C4200DC920400D2BC +:10312000024210210043102100511024AF42002818 +:1031300093A300103063007F000310C00003194008 +:10314000006218213C0208008C4200DC024210217F +:10315000004310213042007F034218213C02000C42 +:10316000006240218FA300142402FFFF1062003090 +:10317000309500FF93A2001195030014304400FF26 +:103180003063FFFF0064182B1060000D000000008A +:10319000950400148D07001C8D0600183084FFFF75 +:1031A00000442023000421000000102100E4382105 +:1031B00000E4202B00C230210A000C4A00C4302158 +:1031C000950400148D07001C8D0600183084FFFF45 +:1031D000008220230004210000001021008018211B +:1031E00000C2302300E4202B00C4302300E3382346 +:1031F000AD07001CAD06001893A20011A502001433 +:1032000097A20012A50200168FA20014AD020010B2 +:103210008FA20014AD02000C93A20011A5020020A1 +:1032200097A20012A50200228FA20014AD02002472 +:103230002406FF80024610243256007FAF4200244D +:10324000035618213C02000A006280218E02004CC5 +:103250008FA200203124007F000428C0AE0200505D +:103260008FA200200004214000852821AE020070BA +:1032700093A2001001208821A202008393A20010D3 +:10328000A2020079920200853042003FA20200852E +:103290003C0208008C4200DC024210210045102153 +:1032A00000461024AF42002C3C0208008C4200E48F +:1032B0003C0308008C6300DC024210210044102112 +:1032C00000461024AF4200283C0208008C4200E473 +:1032D00002431821006518210242102100441021E8 +:1032E0003042007F3063007F93A50010034220210D +:1032F000034318213C02000E006240213C02000CF6 +:1033000010B1008C008248213233007F1660001912 +:103310002404FF803C0208008C4200DC02421021A1 +:1033200000441024AF42002C3C0208008C4200E410 +:103330003C0308008C6300DC02421021004410248E +:10334000AF4200283C0208008C4200E402431821EE +:103350003063007F024210213042007F034220216F +:10336000034318213C02000E006240213C02000C85 +:10337000008248219124000D2414FF8000001021B8 +:1033800000942025A124000D950400029505001449 +:103390008D07001C3084FFFF30A5FFFF8D0600184D +:1033A000008520230004210000E4382100C23021E0 +:1033B00000E4202B00C43021AD07001CAD0600182E +:1033C00095020002A5020014A50000168D02000857 +:1033D000AD0200108D020008AD02000C9502000243 +:1033E000A5020020A50000228D020008AD020024E5 +:1033F0009122000D30420040104000422622000180 +:103400003C0208008C4200E0A3B300283C10000AF4 +:103410000242102100541024AF4200243C02080054 +:103420008C4200E0A380002C27A4002C0242102133 +:103430003042007F03421821007018218C6200D8AE +:103440008D26000427A50028AFA9002C00461021D6 +:10345000AC6200D80E0009E1AF83002893A30028D6 +:103460008F8200280E000626A04300D10E000B68B4 +:103470000000000002541024AF4200243C02080067 +:103480008C4200DC00132940001320C000A420213E +:10349000024210210044102100541024AF42002C9D +:1034A0003C0208008C4200E43C0308008C6300DC12 +:1034B00003563021024210210045102100541024EF +:1034C000AF4200283C0208008C4200E4024318216D +:1034D0000064182102421021004510213042007F73 +:1034E0003063007F03422021034318213C02000E79 +:1034F000006240213C02000C00D080210082482163 +:10350000262200013043007F14750005304400FF7F +:103510002403FF800223102400431026304400FFC0 +:1035200093A2001000808821250800281444FF760B +:103530002529002093A400108FA300142402FFFF6C +:103540001062000A308900FF2482000124830001F8 +:103550003042007F14550005306900FF2403FF80CE +:103560000083102400431026304900FF92020078A7 +:10357000305300FF11330032012088213C02080043 +:103580008C4200DC3225007F000520C00005294068 +:1035900000A42021024210212406FF8000441021B3 +:1035A00000461024AF42002C3C0308008C6300DC72 +:1035B0003C0208008C4200E4024318210242102120 +:1035C0000045102100641821004610243063007F5C +:1035D000AF420028034318213C02000E0062402144 +:1035E0003C0208008C4200E48D06000C0100202102 +:1035F00002421021004510213042007F0342182171 +:103600003C02000C0062482110C0000D012028215E +:103610000E00064A000000002402FF800222182447 +:1036200026240001006228263082007F1455000203 +:10363000308300FF30A300FF1473FFD000608821A7 +:103640008E0300743C027FFF3442FFFF00621824A7 +:10365000AE0300740E00066B02402021AF57002419 +:103660008FA20030AF5E00288FBF005C8FBE005875 +:103670008FB700548FB600508FB5004C8FB4004800 +:103680008FB300448FB200408FB1003C8FB0003840 +:1036900027BD006003E00008AF42002C27BDFFD823 +:1036A000AFB1001CAFBF0020AFB000182751018898 +:1036B000922200032408FF803C03000A3047007F69 +:1036C000A3A700108F4601803C0208008C4200E056 +:1036D000AF86003400C2282100A81024AF42002485 +:1036E0009224000030A2007F0342102100431021E9 +:1036F000AF8200283084007F24020002148200255B +:10370000000719403C0208008C4200E400C210216E +:103710000043282130A2007F0342182100A8102472 +:10372000AF4200283C02000C006218219062000D9C +:10373000AFA3001400481025A062000D8FA3001451 +:103740009062000D304200405040006A8FBF002060 +:103750008F860028A380002C27A400148CC200D8D8 +:103760008C63000427A50010004310210E0009E11E +:10377000ACC200D893A300108F8200280E0006264A +:10378000A04300D10E000B68000000000A000E0BE1 +:103790008FBF00200E00062F00C020210E00063D26 +:1037A000000000003C020008034280219223000137 +:1037B0009202007B1443004F8FBF00209222000032 +:1037C0003044007F24020004108200172882000584 +:1037D00010400006240200052402000310820007A6 +:1037E0008FB1001C0A000E0C0000000010820012B5 +:1037F0008FBF00200A000E0C8FB1001C92050083C1 +:10380000920600788E0700748F84003430A500FF84 +:1038100000073E0230C600FF0E00067330E7007F4F +:103820000A000E0B8FBF00200E000BD78F840034D0 +:103830000A000E0B8FBF002024020C80AF42002430 +:103840009202003E30420040104000200000000084 +:103850009202003E00021600000216030441000618 +:10386000000000008F8400340E0005A024050093A2 +:103870000A000E0B8FBF00209202003F24030018A5 +:10388000304200FF1443000C8F84003424050039BB +:103890000E000538000030210E0002508F840034E5 +:1038A00024020012A202003F0E0002598F8400344D +:1038B0000A000E0B8FBF0020240500360E000538CD +:1038C000000030210A000E0B8FBF00200E000250B6 +:1038D0008F8400349202000534420020A2020005C9 +:1038E0000E0002598F8400340E000FC08F84003404 +:1038F0008FBF00208FB1001C8FB0001824020C80F5 +:1039000027BD002803E00008AF42002427BDFFE8E0 +:10391000AFB00010AFBF001427430100946200084D +:103920000002140000021403044100020000802180 +:103930002410000194620008304200801040001AF8 +:10394000020010219462000830422000104000164E +:10395000020010218C6300183C021C2D344219ED2A +:10396000240600061062000F3C0760213C0208009C +:103970008C4200D4104000078F8200288F830028DB +:10398000906200623042000F34420040A062006248 +:103990008F8200288F840034944500D40E000AF1F1 +:1039A00030A5FFFF020010218FBF00148FB0001060 +:1039B00003E0000827BD001827BDFFE0AFB10014E9 +:1039C000AFB00010A380002CAFBF00188F450100DE +:1039D0003C0308008C6300E02402FF80AF850034C4 +:1039E00000A318213064007F0344202100621824C2 +:1039F0003C02000A00822021AF430024275001002E +:103A00008E0200148C8300DCAF8400280043102356 +:103A100018400004000088218E0200140E000A8461 +:103A2000AC8200DC9202000B24030002304200FF53 +:103A30001443002F0000000096020008304300FFEE +:103A40002402008214620005240200840E00093E54 +:103A5000000000000A000E97000000001462000938 +:103A6000240200818F8200288F8400343C0760216B +:103A7000944500D49206000530A5FFFF0A000E868B +:103A800030C600FF14620027000000009202000A06 +:103A9000304300FF306200201040000430620040DC +:103AA0008F8400340A000E82240600401040000477 +:103AB000000316008F8400340A000E8224060041A1 +:103AC00000021603044100178F84003424060042CC +:103AD0008F8200283C076019944500D430A5FFFF71 +:103AE0000E000AF1000000000A000E97000000001E +:103AF0009202000B24030016304200FF1043000620 +:103B0000000000009202000B24030017304200FF67 +:103B100014430004000000000E000E11000000001D +:103B2000004088210E000B68000000009202000A8D +:103B3000304200081040000624020C808F850028C7 +:103B40003C0400080E0011EE0344202124020C80E6 +:103B5000AF4200248FBF0018022010218FB0001048 +:103B60008FB1001403E0000827BD002027BDFFE847 +:103B7000AFBF0014AFB000108F5000243C0308000A +:103B80008C6300E08F4501002402FF8000A3182110 +:103B90003064007F03442021006218243C02000AA4 +:103BA00000822021AF850034AF4300249082006260 +:103BB000AF8400283042000F34420050A0820062DF +:103BC0003C02001F3442FF800E00062602028024C1 +:103BD000AF5000248FBF00148FB0001003E0000826 +:103BE00027BD00183C0208008C4200201040001D38 +:103BF0002745010090A300093C0200080342202150 +:103C000024020018546200033C0200080A000ED887 +:103C10002402000803422021240200161462000539 +:103C20002402001724020012A082003F0A000EE2C4 +:103C300094A700085462000694A700089362000548 +:103C40002403FFFE00431024A362000594A700088C +:103C500090A6001B8CA4000094A500060A000ACCC4 +:103C600000073C0003E000080000000027440100BA +:103C700094820008304500FF38A3008238A20084F7 +:103C80002C6300012C420001006218251060000620 +:103C9000240200839382002D1040000D00000000DC +:103CA0000A000B9B0000000014A2000524A2FF8064 +:103CB0008F4301043C02602003E00008AC43001481 +:103CC000304200FF2C420002104000032402002278 +:103CD0000A000E3C0000000014A2000300000000D7 +:103CE0000A000EA9000000000A000EC70000000034 +:103CF0009363007E9362007A144300090000202140 +:103D00009362000024030050304200FF144300047B +:103D1000240400019362007E24420001A362007E1D +:103D200003E00008008010218F4201F80440FFFEEC +:103D300024020002AF4401C0A34201C43C021000AF +:103D400003E00008AF4201F827BDFFE8AFBF001055 +:103D50009362003F2403000A304200FF14430046F0 +:103D6000000000008F6300548F62004C1062007DE1 +:103D7000036030219362000024030050304200FFB2 +:103D80001443002F000000008F4401403C02080053 +:103D90008C4200E02403FF800082102100431024A5 +:103DA000AF4200243C0208008C4200E08F650054C2 +:103DB0003C03000A008220213084007F034410214C +:103DC00000431021AC4501089762003C8F63004C12 +:103DD0003042FFFF0002104000621821AF63005C18 +:103DE0008F6300548F64004C9762003C006418237A +:103DF0003042FFFF00031843000210400043102A26 +:103E000010400006000000008F6200548F63004CD9 +:103E1000004310230A000F58000210439762003C31 +:103E20003042FFFF00021040ACC2006424020001D7 +:103E3000A0C0007CA0C2008424020C80AF420024F9 +:103E40000E000F0A8F440140104000478FBF001042 +:103E50008F4301408F4201F80440FFFE240200021C +:103E6000AF4301C0A34201C43C021000AF4201F8BD +:103E70000A000FA88FBF00109362003F24030010B8 +:103E8000304200FF14430004000000008F44014052 +:103E90000A000F94000028219362003F24030016BB +:103EA000304200FF1443000424020014A362003FC8 +:103EB0000A000FA2000000008F62004C8F630050C8 +:103EC00000431023044100288FBF0010936200813B +:103ED00024420001A3620081936200812C4200040D +:103EE00014400010000000009362003F240300040F +:103EF000304200FF14430006000000008F440140E0 +:103F00008FBF0010240500930A0005A027BD0018EC +:103F10008F440140240500938FBF00100A00060F54 +:103F200027BD00188F4401400E0002500000000021 +:103F30008F6200542442FFFFAF6200548F62005032 +:103F40002442FFFFAF6200500E0002598F4401402F +:103F50008F4401408FBF0010240500040A00025E58 +:103F600027BD00188FBF001003E0000827BD001810 +:103F70008F4201889363007E00021402304400FFE8 +:103F8000306300FF1464000D0000000093620080A5 +:103F9000304200FF1044000900000000A3640080CC +:103FA0009362000024030050304200FF14430004D9 +:103FB000000000000A0006D78F440180A36400803F +:103FC00003E000080000000027BDFFE8AFB00010CC +:103FD000AFBF00149362000524030030304200306C +:103FE00014430089008080213C0208008C4200209C +:103FF00010400080020020210E0004930000000009 +:104000008F850020ACB000009362003E9363003FB8 +:10401000304200FF00021200306300FF0043102511 +:10402000ACA2000493620082000216000002160394 +:1040300004410005000000003C0308008C630048B8 +:104040000A000FE6000000009362003E304200408C +:10405000144000030000182193620081304300FFE8 +:104060009362008200031E00304200FF0002140031 +:1040700000621825ACA300088F620040ACA2000CBF +:104080008F620048ACA200108F62004CACA20014FA +:104090008F6200508F63004C0043102304410003E3 +:1040A000000000000A000FFA8F62004C8F6200507F +:1040B000ACA200183C02080094424B5E3C03C00BCB +:1040C00000002021004310250E0004B8ACA2001C03 +:1040D0008F6200548F840020AC8200008F620058F1 +:1040E000AC8200048F62005CAC8200088F620060CA +:1040F0008F43007400431021AC82000C8F62006477 +:10410000AC820010976300689762006A00031C008D +:104110003042FFFF00621825AC83001493620082D6 +:1041200024030080304200FF14430003000000001D +:104130000A00102EAC8000188F63000C24020001CE +:104140001062000E2402FFFF9362003E30420040E6 +:104150001440000A2402FFFF8F63000C8F4200749A +:10416000006218233C020800006210241440000280 +:10417000000028210060282100051043AC820018AF +:104180003C02080094424B5E3C03C00C000020211E +:10419000004310258F8300200E0004B8AC62001C81 +:1041A0008F6200188F8300203C05080094A54B5EA9 +:1041B00024040001AC620000AC6000048F66006C57 +:1041C0003C02400D00A22825AC6600088F6200DC8E +:1041D000AC62000CAC600010936200050002160097 +:1041E000AC620014AC6000180E0004B8AC65001C92 +:1041F000020020218FBF00148FB00010A3600005C3 +:104200000A00042127BD00188FBF00148FB00010D2 +:1042100003E0000827BD00189742007C30C600FF6D +:10422000A08600843047FFFF2402000514C2000B63 +:1042300024E3465090A201122C42000710400007D0 +:1042400024E30A0090A30112240200140062100467 +:1042500000E210210A0010663047FFFF3067FFFFC1 +:1042600003E00008A4870014AC87004C8CA201086E +:104270000080402100A0482100E2102330C600FF4A +:104280001840000393AA001324E2FFFCACA201082B +:1042900030C2000110400008000000008D020050F4 +:1042A00000E2102304410013240600058D0200548F +:1042B00010E20010000000008D02005414E2001A09 +:1042C000000000003C0208008C4200D83042002070 +:1042D0001040000A2402000191030078910200833B +:1042E000144300062402000101002021012028219E +:1042F000240600040A00105400000000A1000084FD +:1043000011400009A50200148F4301008F4201F8FB +:104310000440FFFE24020002AF4301C0A34201C4D7 +:104320003C021000AF4201F803E00008000000006A +:1043300027BDFFE88FA90028AFBF001000804021F3 +:1043400000E918231860007330C600FFA080007CCD +:10435000A08000818CA2010800E210230440004DDF +:10436000000000008C8200509483003C8C84006428 +:10437000004748233063FFFF012318210083202BCF +:1043800010800004000000008D0200640A0010B7D5 +:1043900000E210219502003C3042FFFF0122102173 +:1043A00000E21021AD02005C9502003C8D03005C30 +:1043B0003042FFFF0002104000E210210043102BAA +:1043C00010400003000000000A0010C68D02005CCF +:1043D0009502003C3042FFFF0002104000E2102135 +:1043E000AD02005CA1000084AD07004C8CA2010866 +:1043F00000E210231840000224E2FFFCACA20108F6 +:1044000030C200011040000A000000008D02005080 +:1044100000E2102304410004010020218D02005419 +:1044200014E20003000000000A0010E82406000562 +:104430008D02005414E200478FBF00103C020800B8 +:104440008C4200D8304200201040000A24020001B3 +:1044500091030078910200831443000624020001B6 +:1044600001002021240600048FBF00100A00105410 +:1044700027BD0018A1000084A50200148F4301008D +:104480008F4201F80440FFFE240200020A00110DD1 +:10449000000000008C82005C004910230043102BB8 +:1044A00054400001AC87005C9502003C3042FFFFA5 +:1044B0000062102B14400007240200029502003C09 +:1044C0008D03005C3042FFFF00621821AD03005CE9 +:1044D00024020002AD07004CA10200840E000F0A66 +:1044E0008F4401001040001B8FBF00108F4301005C +:1044F0008F4201F80440FFFE24020002AF4301C0D6 +:10450000A34201C43C021000AF4201F80A0011238B +:104510008FBF001030C200101040000E8FBF00107F +:104520008C83005C9482003C006918233042FFFFBA +:10453000006218213C023FFF3444FFFF0083102B30 +:10454000544000010080182101231021AD02005CBD +:104550008FBF001003E0000827BD001827BDFFE84B +:104560008FAA0028AFBF00100080402100EA482336 +:104570001920002130C600FF8C83005C8C8200640F +:10458000006A18230043102B5040001000691821C6 +:1045900094A2011001221021A4A2011094A20110E2 +:1045A0003042FFFF0043102B1440000A3C023FFF43 +:1045B00094A2011000431023A4A201109482003C95 +:1045C0003042FFFF0A00114200621821A4A001102E +:1045D0003C023FFF3444FFFF0083102B5440000196 +:1045E0000080182100671021AD02005CA100007C52 +:1045F0000A00118AA100008130C200101040003C66 +:10460000000000008C820050004A1023184000383F +:10461000000000009082007C24420001A082007C07 +:104620009082007C3C0308008C630024304200FF31 +:104630000043102B1440005C8FBF00108CA20108B7 +:1046400000E2102318400058000000008C83005442 +:104650009482003C006A18233042FFFF0003184395 +:10466000000210400043102A104000050000000026 +:104670008C820054004A10230A001171000210437A +:104680009482003C3042FFFF00021040AD02006403 +:104690009502003C8D0400649503003C3042FFFF0E +:1046A00000021040008220213063FFFF00831821A8 +:1046B00001431021AD02005C8D020054ACA2010840 +:1046C00024020002A10200840E000F0A8F440100A0 +:1046D000104000358FBF00108F4301008F4201F85A +:1046E0000440FFFE240200020A0011B30000000093 +:1046F000AD07004C8CA2010800E210231840000214 +:1047000024E2FFFCACA2010830C200011040000A04 +:10471000000000008D02005000E21023044100045C +:10472000010020218D02005414E20003000000006B +:104730000A0011AA240600058D02005414E2001A92 +:104740008FBF00103C0208008C4200D8304200208D +:104750001040000A240200019103007891020083B6 +:104760001443000624020001010020212406000455 +:104770008FBF00100A00105427BD0018A10000844C +:10478000A50200148F4301008F4201F80440FFFE90 +:1047900024020002AF4301C0A34201C43C02100046 +:1047A000AF4201F88FBF001003E0000827BD0018DA +:1047B0008FAA00108C8200500080402130C600FF7C +:1047C000004A102300A048211840000700E01821EB +:1047D00024020001A0800084A0A00112A482001481 +:1047E0000A001125AFAA0010A0800081AD07004C7F +:1047F0008CA2010800E210231840000224E2FFFC12 +:10480000ACA2010830C20001104000080000000006 +:104810008D0200500062102304410013240600059D +:104820008D02005410620010000000008D02005440 +:1048300014620011000000003C0208008C4200D805 +:10484000304200201040000A240200019103007849 +:10485000910200831443000624020001010020217C +:1048600001202821240600040A0010540000000042 +:10487000A1000084A502001403E00008000000006D +:1048800027BDFFE0AFBF0018274201009046000A95 +:104890008C4800148C8B004C9082008430C900FF3F +:1048A00001681823304A00FF1C60001A2D460006DC +:1048B000240200010142100410C00016304300031E +:1048C000012030210100382114600007304C000C19 +:1048D00015800009304200301440000B8FBF0018D3 +:1048E0000A001214000000000E001125AFAB0010EA +:1048F0000A0012148FBF00180E00109AAFAB001000 +:104900000A0012148FBF0018AFAB00100E0011BACE +:10491000AFAA00148FBF001803E0000827BD0020D5 +:1049200024020003A08200848C82005403E000086B +:10493000ACA201083C0200080342182190620081E9 +:10494000240600433C07601924420001A062008154 +:10495000906300813C0208008C4200C0306300FF7D +:10496000146200102403FF803C0208008C4200E027 +:104970000082102100431024AF4200243C020800B2 +:104980008C4200E03C03000A008210213042007F8C +:104990000342102100431021944500D40A000AF17B +:1049A00030A5FFFF03E000080000000027BDFFE086 +:1049B000AFBF0018AFB10014AFB000108F4201803C +:1049C0000080802100A088210E00121B00402021C1 +:1049D000A20000848E0200548FBF00188FB0001018 +:1049E000AE2201088FB1001403E0000827BD0020AB +:1049F00027BDFFE03C020008AFB00010AFBF0018B9 +:104A0000AFB10014034280218F5101409203008412 +:104A10008E0400508E02004C14820040306600FF6D +:104A20003C0208008C4200E02403FF800222102197 +:104A300000431024AF4200243C0208008C4200E0F6 +:104A40009744007C92050081022210213042007FB1 +:104A5000034218213C02000A0062182114A0000B36 +:104A60003084FFFF2402000554C20014248205DCB8 +:104A70009062011224420001A062011224020C8003 +:104A8000AF4200240A00127324020005A060011244 +:104A90002402000514C20009248205DC9202008170 +:104AA0002C4200075040000524820A009203008136 +:104AB0002402001400621004008210213044FFFF21 +:104AC000A60400140E00121B022020219602003CB6 +:104AD0008E03004C022020213042FFFF00021040D4 +:104AE000006218210E000250AE03005C9202007DAD +:104AF00002202021344200400E000259A202007D13 +:104B00008F4201F80440FFFE24020002AF5101C0B1 +:104B1000A34201C43C021000AF4201F88FBF00184D +:104B20008FB100148FB0001003E0000827BD0020F3 +:104B300008000ACC08000B1408000B9808000BE4CE +:044B400008000C203D +:0C4B44000A000028000000000000000033 +:104B50000000000D6370362E302E3135000000004D +:104B600006000F040000000000000000000000002C +:104B70000000000000000000000000000000000035 +:104B80000000000000000000000000000000002005 +:104B90000000000000000000000000000000000015 +:104BA0000000000000000000000000000000000005 +:104BB00000000000000000000000000000000001F4 +:104BC0000000002B000000000000000400030D4066 +:104BD00000000000000000000000000000000000D5 +:104BE00000000000000000001000000300000000B2 +:104BF0000000000D0000000D3C0208002442588413 +:104C00003C03080024635F50AC4000000043202BAD +:104C10001480FFFD244200043C1D080037BD7FFCCA +:104C200003A0F0213C100800261000A03C1C080046 +:104C3000279C58840E0001AC000000000000000D0D +:104C400027BDFFE83C096018AFBF00108D2C500055 +:104C5000240DFF7F24080031018D5824356A380C5B +:104C600024070C003C1A8000AD2A50003C04800A46 +:104C7000AF4800083C1B8008AF4700240E00091510 +:104C8000AF8400100E0008D8000000000E000825B8 +:104C9000000000000E001252000000003C046016EC +:104CA0008C8500003C06FFFF3C02535300A61824ED +:104CB0001062004734867C0094C201F2A780002C69 +:104CC00010400003A78000CC38581E1EA798002C67 +:104CD00094C201F810400004978300CC38591E1E7E +:104CE000A79900CC978300CC2C7F006753E000018C +:104CF000240300669784002C2C82040114400002D7 +:104D000000602821240404003C0760008CE904387A +:104D10002403103C3128FFFF1103001F30B9FFFFAF +:104D200057200010A38000CE24020050A38200CEA2 +:104D3000939F00CE53E0000FA78500CCA78000CC46 +:104D4000978500CC8FBF0010A780002CA78000346F +:104D5000A78000E63C010800AC25008003E00008C5 +:104D600027BD0018939F00CE57E0FFF5A78000CC29 +:104D7000A78500CC978500CC8FBF0010A784002C9E +:104D8000A7800034A78000E63C010800AC25008025 +:104D900003E0000827BD0018A38000CE8CCB003CA8 +:104DA000316A00011140000E0000000030A7FFFF33 +:104DB00010E0FFDE240200508CCC00C831860001D8 +:104DC00014C0FFDC939F00CE0A00007A2402005139 +:104DD0008C8F00043C0E60000A00005D01EE302163 +:104DE0008CEF0808240D5708000F740211CD000441 +:104DF00030B8FFFF240500660A00007B240404008D +:104E00001700FFCC939F00CE0A00007A24020050C6 +:104E10008F8600103089FFFF000939408CC30010D5 +:104E20003C08005000E82025AF4300388CC5001432 +:104E300027420400AF82001CAF45003CAF44003065 +:104E40000000000000000000000000000000000062 +:104E50000000000000000000000000000000000052 +:104E60008F4B0000316A00201140FFFD0000000060 +:104E700003E00008000000008F840010948A001AEC +:104E80008C8700243149FFFF000940C000E8302131 +:104E9000AF46003C8C8500248F43003C00A31023C8 +:104EA00018400029000000008C8B002025620001C2 +:104EB0003C0D005035AC0008AF420038AF4C00301C +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE0008F4F000031EE002011C0FFFD00000000D8 +:104EF0008F4A04003C080020AC8A00108F4904044B +:104F0000AC890014AF4800300000000094860018FF +:104F10009487001C00C71821A48300189485001AE8 +:104F200024A20001A482001A9498001A9499001EE9 +:104F3000133800030000000003E000080000000038 +:104F400003E00008A480001A8C8200200A0000DC24 +:104F50003C0D00500A0000CD000000003C0308009A +:104F60008C6300208F82001827BDFFE810620008C4 +:104F7000AFBF00100E000104AF8300183C0308000F +:104F80008C63002024040001106400048F89001049 +:104F90008FBF001003E0000827BD00188FBF00106E +:104FA0003C076012A520000A9528000A34E500108D +:104FB00027BD00183106FFFF03E00008ACA60090F3 +:104FC0003C0208008C42002027BDFFC8AFBF003460 +:104FD000AFBE0030AFB7002CAFB60028AFB500248D +:104FE000AFB40020AFB3001CAFB20018AFB10014D3 +:104FF00010400050AFB000108F840010948600065F +:105000009483000A00C3282330B6FFFF12C0004A71 +:105010008FBF003494890018948A000A012A402323 +:105020003102FFFF02C2382B14E0000202C020212F +:10503000004020212C8C0005158000020080A0215A +:10504000241400040E0000B3028020218F8700107A +:1050500002809821AF80001494ED000A028088211C +:105060001280004E31B2FFFF3C1770003C1540002B +:105070003C1E60008F8F001C8DEE000001D71824AD +:10508000507500500220202102A3802B160000350D +:105090003C182000507800470220202124100001F5 +:1050A0008F83001414600039029158230230F823D2 +:1050B0000250C82133F1FFFF1620FFEE3332FFFF0D +:1050C0008F8700103C110020AF510030000000001D +:1050D00094E6000A3C1E601237D5001002662821B3 +:1050E000A4E5000A94E2000A94F2000A94F400187D +:1050F0003057FFFF1292003BAEB700908CED0014CA +:105100008CE400100013714001AE4021000E5FC31B +:10511000010E502B008B4821012A1821ACE8001405 +:10512000ACE3001002D3382330F6FFFF16C0FFB9FE +:105130008F8400108FBF00348FBE00308FB7002CDB +:105140008FB600288FB500248FB400208FB3001CC9 +:105150008FB200188FB100148FB0001003E0000868 +:1051600027BD0038107E001B000000001477FFCC24 +:10517000241000010E001598000000008F83001419 +:105180001060FFCB0230F823029158238F87001064 +:10519000017020210A0001973093FFFF8F830014D4 +:1051A0001460FFCB3C110020AF5100300A000163B6 +:1051B000000000000E00077D024028210A00015770 +:1051C000004080210E00033A024028210A000157C6 +:1051D000004080210E001460022020210A000157A7 +:1051E000004080210E0000CD000000000A0001797F +:1051F00002D3382327BDFFE8AFB00010AFBF0014C3 +:105200000E00003F000000003C028000345000709F +:105210000A0001BA8E0600008F4F000039EE00012F +:1052200031C20001104000248F8600A88E070000C4 +:105230003C0C08008D8C003C3C0908008D2900388E +:1052400000E66823018D28210000502100AD302B9D +:10525000012A4021010620213C010800AC25003C28 +:10526000AF8700A83C010800AC2400380E000106FE +:10527000000000003C0308008C6300701060FFE633 +:10528000006020213C0508008CA500683C06080051 +:105290008CC6006C0E001527000000003C010800C1 +:1052A000AC2000708F4F000039EE000131C20001C8 +:1052B0001440FFDE8F8600A88E0A00008F8B00A8A6 +:1052C0003C0508008CA5003C3C0408008C84003898 +:1052D000014B482300A938210082182100E9402B06 +:1052E000006810213C010800AC27003C3C0108008C +:1052F000AC2200388F5F01002419FF0024180C0035 +:1053000003F9202410980012AF840000AF4400205D +:10531000936D0000240C002031A600FF10CC001279 +:10532000240E005010CE00043C194000AF59013843 +:105330000A0001B3000000000E0011C800000000C8 +:105340003C194000AF5901380A0001B300000000C9 +:105350000E00011F000000003C194000AF59013849 +:105360000A0001B3000000008F58010000802821CE +:10537000330F00FF01E020210E0002F1AF8F000487 +:105380003C194000AF5901380A0001B30000000089 +:1053900000A4102B2403000110400009000030215C +:1053A0000005284000A4102B04A0000300031840AF +:1053B0005440FFFC000528405060000A0004182BF0 +:1053C0000085382B54E000040003184200C3302548 +:1053D00000852023000318421460FFF900052842CD +:1053E0000004182B03E0000800C310218F4201B80D +:1053F0000440FFFE00000000AF4401803C031000A9 +:1054000024040040AF450184A3440188A3460189D8 +:10541000A747018A03E00008AF4301B83084FFFFCB +:105420000080382130A5FFFF000020210A00022A59 +:10543000240600803087FFFF8CA40000240600387B +:105440000A00022A000028218F8300388F8600304E +:105450001066000B008040213C07080024E759F843 +:10546000000328C000A710218C4400002463000121 +:10547000108800053063000F5466FFFA000328C04F +:1054800003E00008000010213C07080024E759FC55 +:1054900000A7302103E000088CC200003C0390000C +:1054A0003462000100822025AF4400208F45002097 +:1054B00004A0FFFE0000000003E000080000000060 +:1054C0003C038000346200010082202503E00008D4 +:1054D000AF44002027BDFFE0AFB100143091FFFFC3 +:1054E000AFB00010AFBF00181220001300A0802141 +:1054F0008CA2000024040002240601401040000F8A +:10550000004028210E000C5C00000000000010216B +:10551000AE000000022038218FBF00188FB10014A8 +:105520008FB0001000402021000028210000302111 +:105530000A00022A27BD00208CA200000220382188 +:105540008FBF00188FB100148FB0001000402021D1 +:1055500000002821000030210A00022A27BD002077 +:1055600000A010213087FFFF8CA500048C440000B0 +:105570000A00022A2406000627BDFFE0AFB0001093 +:10558000AFBF0018AFB100149363003E00808021CC +:105590000080282130620040000020211040000FD0 +:1055A0008E1100000E000851022020219367000098 +:1055B0002404005030E500FF50A400128E0F0000BC +:1055C000022020218FBF00188FB100148FB000106F +:1055D000A762013C0A00091127BD00200E000287C6 +:1055E000000000000E0008510220202193670000F7 +:1055F0002404005030E500FF14A4FFF20220202113 +:105600008E0F00003C1008008E1000503C0D000C66 +:10561000240BFF8001F05021314E007F01DA602120 +:10562000018D4021014B4824AF4900280220202150 +:105630008FBF00188FB100148FB00010A50200D6E4 +:1056400027BD00200A000911AF8800D027BDFFE068 +:10565000AFBF0018AFB10014AFB0001093660001E7 +:10566000008080210E00025630D1000493640005B2 +:10567000001029C2A765000034830040A363000521 +:105680000E00025F020020210E00091302002021FB +:1056900024020001AF62000C02002821A762001062 +:1056A00024040002A762001224060140A76200142D +:1056B0000E000C5CA76200161620000F8FBF0018AA +:1056C000978C00343C0B08008D6B00782588FFFF19 +:1056D0003109FFFF256A0001012A382B10E000067E +:1056E000A78800343C0F6006240E001635ED00102C +:1056F000ADAE00508FBF00188FB100148FB00010F6 +:1057000003E0000827BD002027BDFFE0AFB1001473 +:10571000AFBF0018AFB0001000A088211080000AB1 +:105720003C03600024020080108200120000000090 +:105730000000000D8FBF00188FB100148FB0001053 +:1057400003E0000827BD00208C682BF80500FFFE51 +:1057500000000000AC712BC08FBF00188FB1001487 +:105760008FB000103C09100027BD002003E00008A6 +:10577000AC692BF80E00025600A0202193650005AD +:10578000022020210E00025F30B000FF2403003E03 +:105790001603FFE7000000008F4401780480FFFE3D +:1057A000240700073C061000AF51014002202021D1 +:1057B000A34701448FBF00188FB100148FB00010B1 +:1057C000AF4601780A0002C227BD002027BDFFE8CE +:1057D000AFBF0014AFB000108F50002000000000D9 +:1057E0000E000913AF440020AF5000208FBF0014FB +:1057F0008FB0001003E0000827BD00183084FFFFC1 +:10580000008038212406003500A020210A00022A49 +:10581000000028213084FFFF008038212406003654 +:1058200000A020210A00022A0000282127BDFFD065 +:10583000AFB3001C3093FFFFAFB50024AFB2001828 +:10584000AFBF0028AFB40020AFB10014AFB000105C +:1058500030B5FFFF12600027000090218F90001CE0 +:105860008E0300003C0680002402004000033E023C +:1058700000032C0230E4007F006688241482001D9F +:1058800030A500FF8F8300282C68000A510000100B +:105890008F910014000358803C0C0800258C56881A +:1058A000016C50218D49000001200008000000001B +:1058B00002B210213045FFFF0E000236240400849E +:1058C000162000028F90001CAF8000288F910014DA +:1058D000260C002026430001018080213072FFFF4A +:1058E00016200004AF8C001C0253502B1540FFDC27 +:1058F00000000000024010218FBF00288FB5002457 +:105900008FB400208FB3001C8FB200188FB1001429 +:105910008FB0001003E0000827BD0030240E0034D3 +:1059200014AE00F9000000009203000E241F168040 +:105930003C07000CA36300219202000D0347C8211D +:105940003C066000A3620020961100123C0A7FFF13 +:10595000354CFFFFA771003C960B00102403000597 +:105960003168FFFFAF6800848E05001CAF5F002820 +:105970008F3800008CC4444803057826008F3021FE +:10598000AF66004C8F69004C24CE00013C057F00BF +:10599000AF6900508F740050AF740054AF66007050 +:1059A000AF6E00588F6D005824140050AF6D005C2E +:1059B000A3600023AF6C0064A36300378E02001461 +:1059C000AF6200488F710048AF7100248E0B001841 +:1059D000AF6B006C9208000CA3680036937F003E0A +:1059E00037F90020A379003E8F78007403058024E6 +:1059F000360F4000AF6F007493640000308900FFE1 +:105A0000513402452404FF803C04080024845A7861 +:105A10000E00028D000000003C1008008E105A7825 +:105A20000E00025602002021240600042407000173 +:105A3000A366007D020020210E00025FA36700051F +:105A40008F5F017807E0FFFE240B0002AF5001409A +:105A5000A34B01448F90001C3C081000AF48017814 +:105A60000A000362AF8000282CAD003751A0FF98D8 +:105A70008F9100140005A0803C180800271856B02C +:105A8000029878218DEE000001C00008000000009F +:105A90002418000614B80011000000003C0808009B +:105AA0008D085A7824040005AF4800208E1F001886 +:105AB000AF7F00188F79004CAF79001C8F650050C4 +:105AC000122000C0AF6500700A000362AF84002896 +:105AD0002406000710A60083240300063C050800E6 +:105AE00024A55A780E000264240400818F90001CC3 +:105AF0000011102B0A000362AF8200282407000463 +:105B000014A7FFF6240500503C1808008F185A7897 +:105B1000AF5800208E0F0008AF6F00408E090008BC +:105B2000AF6900448E14000CAF7400488E0E001054 +:105B3000AF6E004C8E0D0010AF6D00848E0A001405 +:105B4000AF6A00508E0C0018AF6C00548E04001C1D +:105B5000AF64005893630000306B00FF116501D8FB +:105B6000000000008F7400488F6900400289702394 +:105B700005C000042404008C1620FFDE240200036C +:105B8000240400823C05080024A55A780E000287F0 +:105B9000000000008F90001C000010210A0003622A +:105BA000AF820028240F000514AFFFCC240520008D +:105BB0003C0708008CE75A78AF4700208E060004A7 +:105BC000AF66005C9208000824100008A36800215A +:105BD0008F9F001C93F90009A37900208F86001C79 +:105BE00090D8000A330400FF10900011000000005C +:105BF0002885000914A0006924020002240A00205C +:105C0000108A000B34058000288D002115A00008A3 +:105C100024054000240E0040108E00053C050001C4 +:105C200024140080109400023C050002240540006A +:105C30008F7800743C19FF00031980240205782531 +:105C4000AF6F007490C4000BA36400818F84001CAC +:105C50009489000C11200192000000009490000C27 +:105C60002406FFBF24050004A770003C908F000E9F +:105C7000A36F003E8F84001C9089000FA369003F32 +:105C80008F8B001C8D6E00108F54007401D468231C +:105C9000AF6D00608D6A0014AF6A0064956C0018E7 +:105CA000A76C00689563001AA763006A8D62001CE8 +:105CB000AF62006C9167000EA367003E9368003EE0 +:105CC0000106F8241220014BA37F003E8F90001C98 +:105CD0000A000362AF8500282407002214A7FF7F73 +:105CE000240300073C0B08008D6B5A781220000C2F +:105CF000AF4B00200A000362AF830028240C00335E +:105D000010AC0014240A00283C05080024A55A7889 +:105D10000E00023C240400810A0003EB8F90001C5B +:105D20003C04080024845A780E00028D0000000014 +:105D30009363000024110050306200FF10510135C0 +:105D4000000000008F90001C000018210A00036270 +:105D5000AF8300283C0D08008DAD5A7824040081E3 +:105D6000AF4D00203C05080024A55A780E00023CE7 +:105D7000A36A00348F90001C240200090A00036209 +:105D8000AF82002802B288213225FFFF0E000236C2 +:105D9000240400840A0003628F90001C1082FFA478 +:105DA00024050400288B000311600170240C0004FA +:105DB000240300015483FF9E240540000A00043B95 +:105DC000240501003C04080024845A788F62004CAA +:105DD0000E00028D8F6300508F90001C0000202168 +:105DE0000A000362AF8400288E1000042404008A95 +:105DF000AF50002093790005333800021700015F8F +:105E0000020028219368002302002821311F00206E +:105E100017E0015A2404008D9367003F2406001206 +:105E200030E200FF10460155240400810E000256A6 +:105E30000200202193630023240500040200202196 +:105E4000346B0042A36B00230E00025FA365007D4C +:105E50008F4401780480FFFE240A0002AF50014005 +:105E6000A34A01448F90001C3C0C1000AF4C0178F9 +:105E70000A0003EC0011102B8E1000042404008A89 +:105E8000AF500020936E000531CD000215A0001622 +:105E900002002821936F003F2414000402002821EF +:105EA00031E900FF11340010240400810E00025675 +:105EB000020020219362002324080012241FFFFE09 +:105EC00034460020A3660023A368003F93790005B1 +:105ED00002002021033FC0240E00025FA3780005CA +:105EE00002002821000020210E00033400000000E1 +:105EF0000A0003EB8F90001C8E1000043C03000886 +:105F00000343A021AF500020928B000024050050D5 +:105F1000316400FF10850161240700880200202100 +:105F2000000028210E00022A2406000E928D000097 +:105F3000240EFF800200282101AE8025A2900000DF +:105F4000240400040E000C5C240600300A0003EB5D +:105F50008F90001C8E0800043C14080026945A7888 +:105F60003C010800AC285A78AF480020921F00037B +:105F700033F9000413200002240200122402000658 +:105F8000A362003F920B001B2404FFC03165003F59 +:105F900000A43825A367003E9206000330C200012A +:105FA00014400132000000008E020008AE8200089A +:105FB0003C0208008C425A8010400131000249C264 +:105FC000A76900088E14000C240C0001240300149F +:105FD000AF74002C8E0E0010AF6E0030960D0016C0 +:105FE000A76D0038960A0014A76A003AAF6C000C3F +:105FF000A76C0010A76C0012A76C0014A76C001609 +:1060000012200136A3630034920F000331F0000226 +:106010002E1100018F90001C262200080A00036246 +:10602000AF8200288E0400043C0E0008034E30218D +:10603000AF4400208E05000890CD0000240C0050D5 +:1060400031AA00FF114C00862407008824060009AD +:106050000E00022A000000000A0003EB8F90001CD3 +:106060008E04001C0E00024100000000104000F4ED +:10607000004050218F89001C240700890140202105 +:106080008D25001C240600010E00022A00000000DD +:106090000A0003EB8F90001C960D00023C140800D0 +:1060A00026945A7831AA0004514000B83C10600090 +:1060B0008E0E001C3C010800AC2E5A78AF4E00201A +:1060C000920700102408001430E200FF144800D6A4 +:1060D00000000000960B00023163000114600165AE +:1060E000000000008E020004AE8200083C1408008C +:1060F0008E945A801280015B000000008F7400743F +:106100003C0380002404000102835825AF6B007417 +:10611000A3600005AF64000C3C0708008CE75A80C0 +:106120008F86001CA7640010000711C2A76400122C +:10613000A7640014A7640016A76200088CC80008B2 +:1061400024040002AF68002C8CC5000CAF65003041 +:1061500090DF0010A37F00348F99001C9330001152 +:10616000A37000358F98001C930F0012A36F0036A8 +:106170008F89001C912E0013A36E00378F90001C96 +:10618000960D0014A76D0038960A0016A76A003A0B +:106190008E0C0018AF6C00245620FDCCAF84002874 +:1061A0003C05080024A55A780E0002640000202156 +:1061B0008F90001C0A0004A7000020218E1000040C +:1061C00024070081AF500020936900233134001070 +:1061D000128000170000000002002021000028218A +:1061E0002406001F0E00022A000000000A0003EB34 +:1061F0008F90001C3C05080024A55A780E000287E9 +:10620000240400828F90001C000028210A000362F1 +:10621000AF8500283C0408008C845A780E0014E5F1 +:10622000000000008F90001C0A000482000018216A +:106230000E00025602002021937800230200202144 +:10624000370F00100E00025FA36F002300003821FB +:1062500002002021000028210A0005A82406001FB2 +:10626000920F000C31E90001112000030000000032 +:106270009618000EA4D8002C921F000C33F90002CF +:1062800013200005000038218E0200149608001229 +:10629000ACC2001CA4C8001A0A0005432406000969 +:1062A0003C05080024A55A780E0002872404008BC0 +:1062B0008F90001C0011282B0A000362AF85002874 +:1062C000AF6000843C0A08008D4A5A783C0D0800F3 +:1062D0008DAD0050240CFF803C02000C014D1821B4 +:1062E000006C2024AF4400288E070014306B007F20 +:1062F000017A282100A2C821AF2700D88E060014F9 +:10630000AF9900D0AF2600DC8E080010251FFFFEDD +:106310000A000408AF3F01083C0508008CA55A7824 +:106320003C1908008F39005024CCFFFE00B9C02171 +:1063300003047824AF4F00283C1408008E945A7848 +:106340003C0908008D2900500289702131CD007F61 +:1063500001BA502101478021AE0600D8AF9000D08D +:10636000AE0000DC0A0003B1AE0C0108548CFE3014 +:10637000240540000A00043B240510000E00032EF3 +:10638000000000000A0003EB8F90001C8E0F442CCD +:106390003C186C62370979703C010800AC205A78CF +:1063A00015E9000824050140979F00349786002CCA +:1063B0000280282103E6C82B132000112404009238 +:1063C000240501400E000C7A240400023C01080060 +:1063D000AC225A78AF4200203C0508008CA55A78C0 +:1063E00010A00005240400830E00084500000000F2 +:1063F00010400009240400833C05080024A55A78B5 +:106400000E000264000000008F90001C0011202B81 +:106410000A000362AF8400280E0008490000000053 +:106420000A00055F8F90001C0E00084D0000000060 +:106430003C05080024A55A780A00062F2404008B86 +:10644000240400040E000C7A240500301440002AB5 +:10645000004050218F89001C240700830140202127 +:106460008D25001C0A000551240600018E04000839 +:106470000E000241000000000A00051BAE82000869 +:106480003C05080024A55A780E00023C240400872D +:106490008F90001C0A0005360011102B8F830038E6 +:1064A0008F8600301066FE9D000038213C070800F2 +:1064B00024E759FC000320C0008728218CAC000091 +:1064C00011900061246A00013143000F5466FFFA05 +:1064D000000320C00A0004F6000038213C05080033 +:1064E00024A55A780E000287240400828F90001C95 +:1064F0000A000536000010213C0B0008034B202148 +:106500002403005024070001AF420020A0830000B4 +:10651000A08700018F82001C90480004A08800180A +:106520008F85001C90A60005A08600198F9F001C77 +:1065300093F90006A099001A8F90001C921800078A +:10654000A098001B8F94001C928F0008A08F001C45 +:106550008F89001C912E0009A08E001D8F8D001CBC +:1065600091AC000AA08C001E8F8B001C3C0C080014 +:10657000258C59FC9163000B3C0B0800256B59F8E6 +:10658000A083001F8F87001C90E8000CA0880020CB +:106590008F82001C9045000D24024646A0850021F4 +:1065A0008F86001C90DF000EA09F00228F99001C98 +:1065B0009330000FA09000238F98001C93140010BC +:1065C000A09400248F8F001C91E90011A089002560 +:1065D0008F89001C8F8E00308F900038952D00140D +:1065E000000E18C025C80001A48D002895270016AC +:1065F000006C3021006BC821A487002A9525001863 +:106600003108000FA485002CA482002E8D3F001CB1 +:10661000ACCA0000AF88003011100006AF3F000088 +:10662000000038218D25001C014020210A00055161 +:1066300024060001250C00013184000F00003821E0 +:106640000A0006B8AF8400383C07080024E759F870 +:106650000087302100003821ACA000000A0004F6B9 +:10666000ACC000003C05080024A55A780A00062F9B +:10667000240400878E0400040E0002410000000084 +:106680000A00056AAE8200083084FFFF30C600FFB2 +:106690008F4201B80440FFFE00064400010430258B +:1066A0003C07200000C720253C031000AF400180BC +:1066B000AF450184AF44018803E00008AF4301B84F +:1066C00027BDFFE8AFB00010AFBF00143C0760006B +:1066D000240600021080000600A080210010102B6C +:1066E0008FBF00148FB0001003E0000827BD001812 +:1066F0003C09600EAD2000348CE5201C8F82001C0C +:106700002408FFFC00A81824ACE3201C0E0006D1CE +:106710008C45000C0010102B8FBF00148FB00010A0 +:1067200003E0000827BD00183C02600E344701005A +:1067300024090018274A040000000000000000009F +:10674000000000003C06005034C30200AF44003893 +:10675000AF45003CAF430030014018218F4B000093 +:10676000316800201100FFFD2406007F2408FFFF90 +:106770008C6C000024C6FFFF24630004ACEC000016 +:1067800014C8FFFB24E70004000000000000000024 +:10679000000000003C0F0020AF4F00300000000060 +:1067A00024AD020001A5702B2529FFFF008E2021BA +:1067B0001520FFE101A0282103E0000800000000EF +:1067C00027BDFFE0AFB10014AFBF0018AFB000109D +:1067D0003C05600E8CA20034008088211440000625 +:1067E0003C0460008C87201C2408FFFC00E8302457 +:1067F00034C30001AC83201C8F8B001C24090001D2 +:10680000ACA90034956900028D6500148D70000CF0 +:106810002D2400818D6700048D660008108000071C +:106820008D6A00102D2C00041580000E30CE00075C +:10683000312D000311A0000B000000002404008B88 +:10684000020028210E0006D1240600030011102B9F +:106850008FBF00188FB100148FB0001003E0000844 +:1068600027BD002015C0FFF62404008B3C03002048 +:10687000AF4300300000000024020001AF8200148A +:106880000000000000000000000000003C1F01505C +:10689000013FC825253800033C0F600EAF47003884 +:1068A00000181882AF46003C35E8003CAF59003074 +:1068B000274704008F4400003086002010C0FFFDF1 +:1068C00000000000106000082466FFFF2403FFFFA3 +:1068D0008CEB000024C6FFFF24E70004AD0B000092 +:1068E00014C3FFFB250800043C08600EAD09003806 +:1068F0000000000000000000000000003C07002035 +:10690000AF470030000000000E0006F901402021D2 +:1069100002002821000020210E0006D124060003D9 +:106920000011102B8FBF00188FB100148FB0001012 +:1069300003E0000827BD002027BDFFE0AFB200182C +:106940003092FFFFAFB10014AFBF001CAFB000101A +:106950001640000D000088210A0007AA022010211D +:1069600024050001508500278CE5000C0000000D77 +:10697000262300013071FFFF24E200200232382B71 +:1069800010E00019AF82001C8F8200141440001622 +:106990008F87001C3C0670003C0320008CE5000043 +:1069A00000A62024148300108F84003C00054402BC +:1069B0003C09800000A980241480FFE9310600FF13 +:1069C0002CCA00095140FFEB262300010006688015 +:1069D0003C0E080025CE578C01AE60218D8B000047 +:1069E0000160000800000000022010218FBF001C81 +:1069F0008FB200188FB100148FB0001003E00008B0 +:106A000027BD00200E0006D1240400841600FFD804 +:106A10008F87001C0A00078BAF80003C90EF0002BC +:106A200000002021240600090E0006D1000F2E00D0 +:106A30008F87001C0010102B0A00078BAF82003CD0 +:106A4000020028210E0006DF240400018F87001CAD +:106A50000A00078BAF82003C020028210E0006DFEF +:106A6000000020210A0007C38F87001C0E00071FAB +:106A7000020020210A0007C38F87001C30B0FFFFEF +:106A8000001019C08F5801B80700FFFE3C1F2004FA +:106A90003C191000AF430180AF400184AF5F018813 +:106AA000AF5901B80A00078C262300013082FFFF8E +:106AB00014400003000018210004240224030010E5 +:106AC000308500FF14A000053087000F2466000801 +:106AD0000004220230C300FF3087000F14E00005DD +:106AE000308900032468000400042102310300FF00 +:106AF0003089000315200005388B0001246A00024C +:106B000000042082314300FF388B00013164000112 +:106B100010800002246C0001318300FF03E00008B4 +:106B200000601021308BFFFF000B394230E600FF80 +:106B30003C09080025295978000640800109602198 +:106B40008D8700003164001F240A0001008A1804A8 +:106B500030A500FF00E3202514A000020003102749 +:106B600000E22024240F000100CF700401096821F5 +:106B7000000E282714800005ADA400008F86000CAD +:106B800000A6102403E00008AF82000C8F88000CE0 +:106B900001C8102503E00008AF82000C3C06001F6E +:106BA0003C0360003084FFFF34C5FF8024020020D6 +:106BB000AC602008AC60200CAC602010AC652014E8 +:106BC000AC642018AC62200000000000000000004F +:106BD00003E000080000000027BDFFE82402FFFFDB +:106BE000AFBF0010AF82000C000020213C0608005F +:106BF00024C659782405FFFF248900010004408041 +:106C00003124FFFF010618212C87002014E0FFFA31 +:106C1000AC6500000E0008160000202124020001CF +:106C20003C04600024050020AC822018AC852000C4 +:106C3000000000000000000000000000244A0001E5 +:106C40003142FFFF2C46040014C0FFF78FBF001035 +:106C500003E0000827BD00188F8300082C620400A1 +:106C600003E00008384200018F830008246200011D +:106C700003E00008AF8200088F8300082462FFFF52 +:106C800003E00008AF82000827BDFFE0AFB10014A9 +:106C9000AFBF0018AFB000108F6B00303C06600033 +:106CA00000808821ACCB20088F6A002C3C02800039 +:106CB00024030008ACCA200C9769003A9768003892 +:106CC00000092C003107FFFF00A72025ACC42010CD +:106CD000ACC22014ACC32000000000000000000083 +:106CE000000000003C0360008C6D200031AC000807 +:106CF0001580FFF9000000008C6E201405C00020F4 +:106D0000000000000E0007DA8F84000C00024080B3 +:106D10003C09080025295978010938218CE4000034 +:106D20000E0007DA00028140020220213090FFFFAE +:106D3000020020210E0007F8000028213C0C8000F2 +:106D4000022C58253210FFFF3C116000240A00205D +:106D5000AE2B2014AE302018AE2A20000000000018 +:106D60000000000000000000020010218FBF00188A +:106D70008FB100148FB0001003E0000827BD002081 +:106D80008C6620143C02001F3443FF803C1FFFE848 +:106D900000C3C02437F9080003198021001079C20C +:106DA0003C0C8000022C582531F0FFFF3C116000A4 +:106DB000240A0020AE2B2014AE302018AE2A20006A +:106DC0000000000000000000000000000200102190 +:106DD0008FBF00188FB100148FB0001003E00008BF +:106DE00027BD002027BDFFE8AFB000103402FFFF31 +:106DF0003090FFFFAFBF00141202000602002021F6 +:106E00000E00081600000000020020210E0007F806 +:106E1000240500018F8400088FBF00148FB000107C +:106E20002483FFFF27BD001803E00008AF8300089C +:106E3000000439C230E6003F00043B42000718401E +:106E4000240210002CC4002024C8FFE0AF42002C14 +:106E5000246300011480000330A900FF00071840DC +:106E6000310600FF0003608024080001019A5821C8 +:106E70003C0A000E00C82804016A382111200005D0 +:106E8000000530278CE900000125302503E00008CB +:106E9000ACE600008CEE000001C6682403E00008A8 +:106EA000ACED000027BDFFE8AFBF0014AFB000108D +:106EB0003C0460008C8508083403F00030A2F00028 +:106EC00050430006240200018C8708083404E000C7 +:106ED00030E6F00010C4001E24020002AF82004021 +:106EE0003C1060003C0A0200AE0A0814240910009D +:106EF0003C08000E8E03440003482021AF49002CBB +:106F0000240501200E000CC0000030218F830040BA +:106F1000106000043C021691240B0001106B000E5F +:106F20003C023D2C344F0090AE0F44088FBF00143C +:106F30008FB000103C0C6000240E10003C0D0200CD +:106F400027BD0018AD8E442003E00008AD8D081069 +:106F50000A0008E7AF8000403C0218DA344F009086 +:106F6000AE0F44088FBF00148FB000103C0C6000BF +:106F7000240E10003C0D020027BD0018AD8E4420E9 +:106F800003E00008AD8D08100A0008BB24050001CD +:106F90000A0008BB000028213C08080025085D8481 +:106FA0002404FFFF010018212402001E2442FFFFD9 +:106FB000AC6400000441FFFD246300043C070800AA +:106FC00024E75E008CE5FFFC2404001C240600017D +:106FD000308A001F0146480424840001000910275C +:106FE0002C8300201460FFFA00A22824ACE5FFFCEB +:106FF0003C05666634A4616E3C06080024C65EC08B +:10700000AF840058AF88009C2404FFFF00C0182103 +:107010002402001F2442FFFFAC6400000441FFFD76 +:10702000246300043C0766663C05080024A55E80D6 +:10703000AF86004834E6616EAF8600982404FFFFF7 +:1070400000A018212402000F2442FFFFAC640000BE +:107050000441FFFD246300043C0B66663C06080007 +:1070600024C65E003568616EAF8500A4AF880070ED +:107070002404FFFF00C018212402001F2442FFFF48 +:10708000AC6400000441FFFD246300043C0D66660F +:107090003C0A0800254A5F4035AC616EAF8600901F +:1070A000AF8C005C2404FFFF014018212402000380 +:1070B0002442FFFFAC6400000441FFFD2463000490 +:1070C0003C09080025295F508D27FFFC2404000699 +:1070D000240500013099001F0325C0042484000109 +:1070E000001878272C8E002015C0FFFA00EF3824F6 +:1070F000AD27FFFC3C09666624030400240403DC7E +:1071000024050200240600663522616E3C08080052 +:1071100025085A84AF820074AF830044AF83006CAB +:10712000AF830050AF830084AF8A008CAF840064CB +:10713000AF85004CAF860054AF840078AF85006007 +:10714000AF86008001001821240200022442FFFFC4 +:10715000AC6000000441FFFD24630004240400032C +:107160002403000C3C0A0800254A5A90AF8A0068A4 +:107170000A00098E2405FFFF000418802484000102 +:10718000006858212C8700C014E0FFFBAD650000AB +:107190003C0E666635CD616E240C17A024081800DD +:1071A000AF8D0088AF8C009403E00008AF88007CAE +:1071B0002484007F000421C200004021000030210F +:1071C00000003821000028210A0009A5AF8400A092 +:1071D0001060000624E7000100C4302124A500014E +:1071E0002CC20BF51440FFFA2CA300663C090800E2 +:1071F00025295F4001201821240200032442FFFFBB +:10720000AC6000000441FFFD2463000410E0001A9C +:1072100024E3FFFF0003294210A0000A0000202100 +:107220002406FFFF3C03080024635F402484000120 +:107230000085502BAC660000250800011540FFFBBF +:107240002463000430E2001F10400008000868803A +:10725000240C0001004C38040008588001692821E2 +:1072600024E6FFFF03E00008ACA6000001A94021CE +:107270002409FFFFAD09000003E000080000000042 +:10728000AF4400283C04000C034420210005288260 +:107290000A000CC000003021000421803C03600083 +:1072A000AC6410080000000000052980AC65100CDB +:1072B0000000000003E000088C62100C27BDFFE80E +:1072C0000080282124040038AFBF00140E0009D527 +:1072D000AFB0001024040E00AF4400283C10000C96 +:1072E00003502021240500100E000CC000003021A6 +:1072F00003501021AC400000AC40000424040038CE +:107300008FBF00148FB0001024053FFF27BD001869 +:107310000A0009D58C430000000421803C03600072 +:10732000AC641008000000008C62100C03E0000840 +:107330000002118227BDFFC8AFB400208F940068FF +:10734000AFBE0030AFB7002CAFB600280000B821A8 +:107350000080B021241E00C0AFBF0034AFB50024B0 +:10736000AFB3001CAFB20018AFB10014AFB0001043 +:107370000A000A12AFA5003C504000018F9400683B +:1073800027DEFFFF13C00028269400048E92000021 +:107390003C03080024635D801240FFF70283102B3A +:1073A0003C04080024845A84028410230002A8C0EC +:1073B000000098210A000A212411000100118840D0 +:1073C000122000260000000002B380210251282470 +:1073D0000200202110A0FFF9267300010E0009DE33 +:1073E000000000000016684032EC000101AC2021D2 +:1073F0000E0009D5020028218F89009426F700018C +:107400008FA6003C3AEB0001316A00012528FFFFFE +:107410000011382702CAB021AF88009416E6FFE7B2 +:1074200002479024AE92000002E010218FBF00348A +:107430008FBE00308FB7002C8FB600288FB5002488 +:107440008FB400208FB3001C8FB200188FB10014CE +:107450008FB0001003E0000827BD00383C0E080084 +:1074600025CE5D80028E102B0A000A0DAE92000020 +:1074700027BDFFD8AFB10014AFB00010AFBF0020E0 +:10748000AFB3001CAFB2001800A0882110A0001FED +:10749000000480403C13080026735A840A000A5AEC +:1074A0002412000112200019261000010E0009F517 +:1074B00002002021000231422444FFA0000618806F +:1074C0003045001F2C8217A1007318212631FFFFC1 +:1074D0001040FFF400B230048C690000020020214B +:1074E00024053FFF012640241500FFEE0126382524 +:1074F0000E0009D5AC6700008F8A009426100001A9 +:10750000254700011620FFE9AF8700948FBF0020B8 +:107510008FB3001C8FB200188FB100148FB0001011 +:1075200003E0000827BD00288F85009C00805821BB +:107530000000402100004821240A001F3C0C0800E4 +:10754000258C5DFC3C0D080025AD5D848CA60000FB +:1075500050C000140000402100AD1023000238C0CC +:10756000240300010A000A930000202115000003F3 +:1075700000E410212448202400004821252900018E +:10758000512B00132506DFDC106000062484000167 +:1075900000C3702415C0FFF5000318400A000A91CB +:1075A0000000402110AC002624A300040060282124 +:1075B000254AFFFF1540FFE5AF85009C512B0004D5 +:1075C0002506DFDC0000402103E000080100102157 +:1075D0000006614230C5001F000C50803C070800C7 +:1075E00024E75D8424040001014730211120000FAD +:1075F00000A420043C05080024A55E0014800005BA +:107600002529FFFF24C6000410C50011000000005A +:10761000240400018CCF00000004C0270004204097 +:1076200001F868241520FFF5ACCD00008F99007893 +:1076300001001021032B482303E00008AF890078E4 +:107640003C05080024A55D840A000A9B0000402137 +:107650003C06080024C65D840A000AB42404000124 +:10766000308800FF240200021102000A24030003F4 +:107670001103005C8F8900A4240400041104005F3E +:1076800024050005110500670000182103E000082B +:10769000006010218F8900483C0C0800258C5EC0DA +:1076A0003C04080024845F40240300201060000F85 +:1076B00000005821240D0002240E00033C0F080096 +:1076C00025EF5EC08D27000014E0000B30F9FFFFAE +:1076D000252900040124C02B53000001018048210A +:1076E0002463FFFF5460FFF88D270000016018211C +:1076F00003E0000800601021132000323C0500FF69 +:1077000030E200FF004030211040004200005021D4 +:1077100024050001000020210005C84000A6C02467 +:1077200017000003332500FF14A0FFFB2484000191 +:10773000012CC023001828C000AA6021008C502111 +:107740003144001F240C0001008C18040003102792 +:1077500000E23024110D0041AD260000110E004C56 +:10776000000A1840110D00368F87006C510E00562C +:107770008F8C0060240D0004110D005A8F8E008440 +:10778000240E0005150EFFDA01601821240B1430B9 +:1077900011400006000018218F8400A0246300011E +:1077A000006A402B1500FFFD016458218F8A00807C +:1077B000AF89008C016018212549FFFF0A000AEB00 +:1077C000AF89008000E52024000736021080FFD03A +:1077D000240A001800075402314600FF0A000AF389 +:1077E000240A00103C0C0800258C5E803C04080034 +:1077F00024845EC00A000ADA240300103C0C08004E +:10780000258C5E003C04080024845E800A000AD9AE +:107810008F89009000071A02306600FF0A000AF301 +:10782000240A00088F89008C3C0C0800258C5F40DE +:107830003C04080024845F500A000ADA2403000490 +:10784000000A4080250B003024E6FFFF016018216C +:10785000AF8900480A000AEBAF86006C000AC982B3 +:10786000001978803C07080024E75E8001E72021AA +:10787000000A18428C8F00003079001F032C380456 +:107880000007C02701F860240A000B08AC8C000038 +:10789000000331420006288000AF28213062001F1B +:1078A0008CB8000024630001004CC804000321428E +:1078B000001938270004108003073024004F2021CE +:1078C0000A000B4CACA60000000A68C025AB0032D1 +:1078D000258AFFFF01601821AF8900A40A000AEB86 +:1078E000AF8A0060254B1030AF89009001601821ED +:1078F00025C9FFFF0A000AEBAF8900843086000724 +:107900002CC2000610400014000000000006408059 +:107910003C030800246357B0010338218CE40000C5 +:1079200000800008000000002409000310A9000ED8 +:1079300000000000240A000510AA000B000000004F +:10794000240B000110AB0008000000008F8C00A089 +:1079500010AC00050000000003E00008000010214A +:107960000A000A7900A020210A000AC700C02021CD +:1079700027BDFFE8308400FF240300021083000BC2 +:10798000AFBF0010240600031086003A240800044C +:1079900010880068240E0005108E007F2CAF143074 +:1079A0008FBF001003E0000827BD00182CA2003094 +:1079B0001440FFFC8FBF001024A5FFD0000531C28A +:1079C000000668803C07080024E75EC001A730215C +:1079D0008CC900000005288230AC001F240B000178 +:1079E000018B50048F840048012A4025ACC8000058 +:1079F0008C83000050600001AF8600488F98006CB7 +:107A000030AE000124A6FFFF270F000115C00002C1 +:107A1000AF8F006C24A600010006414200082080C0 +:107A2000008718218C79000030C2001F2406000155 +:107A30000046F804033F382410E0FFDA8FBF00103F +:107A40000005C182001870803C0F080025EF5E80A1 +:107A500001CF48218D2B00000005684231A5001F91 +:107A600000A66004016C502527BD001803E0000843 +:107A7000AD2A00002CA7003014E0FFCA8FBF001011 +:107A800030B900071723FFC724A8FFCE00086A02F9 +:107A9000000D60803C0B0800256B5E80018B30215F +:107AA0008CC40000000828C230AA001F240800016E +:107AB000014848048F8200A400891825ACC3000047 +:107AC0008C5F000053E00001AF8600A40005704009 +:107AD000000E7942000F28803C04080024845EC018 +:107AE00000A418218C6B000025DF000131CD001FA0 +:107AF000001F514201A86004016C4825000A108053 +:107B0000AC690000004428218CA600008F9800601A +:107B100033F9001F8FBF00100328380400C77825F1 +:107B2000270E000127BD0018ACAF000003E00008DD +:107B3000AF8E006024A5EFD02CB804001300FF998D +:107B40008FBF001000053142000658803C0A080033 +:107B5000254A5E00016A30218CC4000030A3001F5A +:107B600024090001006910048F9900900082F82513 +:107B7000ACDF00008F27000050E00001AF860090CE +:107B80008F8D00848FBF001027BD001825AC000129 +:107B900003E00008AF8C008415E0FF828FBF001067 +:107BA0008F8600A0000610400046F821001F21002B +:107BB00003E4C8210019384024F8143000B8402BE1 +:107BC0001100FF788FBF001024A4EBD00E00021329 +:107BD00000C0282100027942000F70803C0D08008F +:107BE00025AD5F4001CD20218C8B0000304C001F63 +:107BF00024060001018618048F89008C016350253A +:107C0000AC8A00008D25000050A00001AF84008CDC +:107C10008F9800808FBF001027BD00182708000133 +:107C200003E00008AF88008030A5000724030003AC +:107C300010A3001028A2000414400008240700022A +:107C40002403000410A300152408000510A8000F49 +:107C50008F8500A003E000080000000014A7FFFDCE +:107C60000080282114C3FFFB240400020A000B8BB0 +:107C700000000000240900050080282110C9FFFB36 +:107C80002404000303E000080000000014C5FFF115 +:107C9000008028210A000B8B24040005240A00011F +:107CA0000080282110CAFFF12404000403E000082A +:107CB0000000000027BDFFE0AFB00010000581C24A +:107CC0002603FFD024C5003F2C6223D024C6007FAA +:107CD000AFB20018AFB10014AFBF001C309100FF6D +:107CE000000691C2000529820200202110400008F0 +:107CF0002403FFFF0E000A4B0000000002002021B9 +:107D0000022028210E000C390240302100001821E9 +:107D10008FBF001C8FB200188FB100148FB00010FD +:107D20000060102103E0000827BD002027BDFFD818 +:107D300024A2007FAFB3001CAFB20018000299C2AA +:107D4000309200FF24A3003F02402021026028213E +:107D5000AFB10014AFB00010AFBF00200E000B6E2B +:107D60000003898200408021004020210220282138 +:107D700014400009000018218FBF00208FB3001CA1 +:107D80008FB200188FB100148FB000100060102166 +:107D900003E0000827BD00280E0009FC00000000D9 +:107DA00000402821020020211051FFF3001019C0CB +:107DB0000E000A4B00000000020020210240282192 +:107DC0000E000C39026030218FBF00208FB3001CE1 +:107DD0008FB200188FB100148FB00010000018216E +:107DE0000060102103E0000827BD00283084FFFF59 +:107DF00030A5FFFF1080000700001821308200012D +:107E00001040000200042042006518211480FFFB8E +:107E10000005284003E000080060102110C00007A2 +:107E2000000000008CA2000024C6FFFF24A500046F +:107E3000AC82000014C0FFFB2484000403E00008AF +:107E40000000000010A0000824A3FFFFAC86000083 +:107E500000000000000000002402FFFF2463FFFF79 +:107E60001462FFFA2484000403E00008000000000C +:107E700030A5FFFF8F4201B80440FFFE3C076015AC +:107E800000A730253C031000AF440180AF400184BF +:107E9000AF46018803E00008AF4301B88F8500D0EA +:107EA0002C864000008018218CA700840087102BAE +:107EB00014400010000000008CA800842D06400033 +:107EC00050C0000F240340008CAA0084008A482B75 +:107ED000512000018CA3008400035A42000B208033 +:107EE0003C05080024A558000085182103E000087F +:107EF0008C62000014C0FFF4000000002403400066 +:107F000000035A42000B20803C05080024A55800BD +:107F10000085182103E000088C6200008F8300D0E8 +:107F2000906600D024C50001A06500D08F8500D0E8 +:107F3000906400D090A200D210440017000000000E +:107F4000936C00788F8B00BC318A00FFA16A000C13 +:107F500025490001938700C4312200FF3048007F8B +:107F60001107000B00026827A36200788F4E01788A +:107F700005C0FFFE8F9900B0241800023C0F1000CE +:107F8000AF590140A358014403E00008AF4F017806 +:107F90000A000D0931A20080A0A000D00A000CFF49 +:107FA000000000008F8700D027BDFFC8AFBF0030A2 +:107FB000AFB7002CAFB60028AFB50024AFB4002097 +:107FC000AFB3001CAFB20018AFB10014AFB00010D7 +:107FD00094E300E094E200E2104300D72405FFFFA1 +:107FE0003C047FFF3497FFFF2415FF800A000DF04B +:107FF0003C16000E108A00D18FBF00308F9100B068 +:108000003C1808008F18005C001230C0001291402C +:108010000311702101D57824AF4F002C94EC00E2BD +:1080200031CD007F01BA5821318A7FFF0176482186 +:10803000000A804002091021945300003C08080007 +:108040008D0800580246C02132733FFF001319808B +:10805000010320210224282130BF007F03FAC82118 +:1080600000B5A024AF54002C0336A0218E87001049 +:108070008E8F003003785821256D008800EF702323 +:10808000240C0002AE8E0010AF8D00ACA16C0088F5 +:10809000976A003C8E8400308F9100AC0E000CD6A5 +:1080A0003150FFFF00024B80020940253C02420094 +:1080B00001022025AE2400048E8300048F8D00ACC5 +:1080C0008E860000240E0008ADA3001CADA600188B +:1080D000ADA0000CADA00010929F000A33F900FF84 +:1080E000A5B90014968500083C1F000CA5A5001634 +:1080F0009298000A331100FFA5B100209690000865 +:1081000024180005A5B00022ADA00024928F000B1A +:108110002410C00031E700FFA5A70002A1AE0001B6 +:108120008E8C00308F8B00AC8F8400B0AD6C00085B +:108130003C0A08008D4A005401444821013540247E +:10814000AF4800283C0208008C4200540044302113 +:1081500030C3007F007AC821033F282102458821CF +:10816000AF9100BCAF8500C0A23800008F8A00BC70 +:108170002403FFBF2418FFDF954F000201F03824CD +:1081800000F37025A54E0002914D000231AC003F76 +:10819000358B0040A14B00028F8600BC8F8900D038 +:1081A000ACC000048D28007C3C098000ACC80008ED +:1081B00090C4000D3082007FA0C2000D8F8500BCEE +:1081C00090BF000D03E3C824A0B9000D8F9100BC3F +:1081D0009233000D02789024A232000D8E9000346C +:1081E0008F8B00BCAD7000108E87002C8E8F0030FE +:1081F00000EF7023AD6E0014916D001831AC007F5C +:10820000A16C00188F9F00BC8E8A00308FE8001888 +:10821000015720240109302400C41025AFE20018C2 +:108220009283000AA3E3001C969900088F8500BC86 +:108230008F9800D0A4B9001E8E9000308E8400303C +:108240000E0002138F0500848F8500D0000291403C +:108250000002990090AF00BC0253882100403021F9 +:1082600031E7000210E0000302118021000290803B +:108270000212802190B900BC3327000410E00002F4 +:108280000006F880021F80218E9800308F8B00BC82 +:1082900024068000330F0003000F702331CD00034C +:1082A000020D6021AD6C000494A400E294AA00E2E7 +:1082B00094B000E231497FFF2522000130537FFF57 +:1082C0000206182400734025A4A800E294A400E24A +:1082D0003C1408008E94006030917FFF123400221D +:1082E000000000000E000CF6000000008F8700D098 +:1082F0000000282194F300E094F000E21213000F34 +:108300008FBF003090E900D090E800D1313200FFFB +:10831000310400FF0244302B14C0FF36264A00010E +:1083200090EE00D2264B000131CD00FF008D602180 +:10833000158BFF338F9100B08FBF00308FB7002CAB +:108340008FB600288FB500248FB400208FB3001C97 +:108350008FB200188FB100148FB0001000A0102150 +:1083600003E0000827BD003894A300E20066402423 +:10837000A4A800E290A400E290B900E2309100FFCE +:108380000011A1C20014F827001F39C03332007F4A +:10839000024730250A000DE8A0A600E23084FFFF66 +:1083A00030A5FFFFAF440018AF45001C03E00008F4 +:1083B0008F42001427BDFFB8AFB000208F9000D0CF +:1083C0003084FFFFAFA40010AFBF0044AFBE004039 +:1083D000AFB7003CAFB60038AFB50034AFB4003033 +:1083E000AFB3002CAFB20028AFB10024A7A0001893 +:1083F000920600D1920500D030C400FF30A300FFE8 +:108400000064102B10400122AFA00014920900D08C +:108410008FB50010312800FF0088382324F4FFFFB7 +:108420000014882B0015982B02339024524001260B +:108430008FB40014961E0012961F00108FB7001004 +:1084400003DFC823001714000019C400000224032E +:108450000018140302E2B02A52C00001004020219B +:108460000284282B10A0000200801821028018210D +:1084700000033C0000071C033064FFFF2C8600094A +:1084800014C000020060B821241700088E0A0008FA +:10849000001769808E09000C31ABFFFF3C0C001007 +:1084A000016C402527520400AF4A0038AF9200B853 +:1084B000AF49003CAF480030000000000000000061 +:1084C00000000000000000000000000000000000AC +:1084D00000000000000000008F4F000031EE00207F +:1084E00011C0FFFD0017982A027110240A000E83A4 +:1084F0000000B02155E001019258000131130080C5 +:10850000126001CF012020219655001232A5FFFFF5 +:108510000E000CCBA7B500188F9000D00291A023BD +:1085200026CD00018F9100B8000DB4000016B403F1 +:108530002638004002D7582A0014882B2405000151 +:108540000300902101711024AF9800B8AFA500146A +:10855000104001BC8F8900B03C0C08008D8C005489 +:10856000240BFF80921E00D001895021014B28244A +:10857000921900D0AF4500288E4700103C08080033 +:108580008D0800583C1808008F18005430E33FFF56 +:108590000003218001043021012658212402FF809C +:1085A0000162F824920C00D0AF5F002C92480000CA +:1085B00033D100FF333500FF0309982100117140CA +:1085C000001578C0326D007F01CF382101BA282113 +:1085D000318300FF3164007F3C0A000C00AA88212F +:1085E0000367F02100033140009A10213108003F59 +:1085F0003C1F000E00D1C021005F982127D90088C0 +:108600002D150008AF9100C0AF9900ACAF9800BC29 +:10861000AF9300B412A0018A00008821240E00014B +:10862000010E4004310D005D11A0FFB2310F0002B8 +:108630008E4A00283C0300803C04FFEFAE6A000035 +:108640008E450024A260000A3488FFFFAE65000456 +:108650009247002C3C1FFF9F37FEFFFFA267000CD4 +:108660008E62000C3C180040A267000B00433025CE +:1086700000C8C824033E88240238A825AE75000C23 +:108680008E490004AE6000183C0F00FFAE69001474 +:108690008E4D002C35EEFFFF8F8B00B001AE6024B5 +:1086A000AE6C00108E470008A660000896450012C8 +:1086B000AE6700208E42000C30B03FFF00105180AA +:1086C000AE6200248E5E0014014B182130A400011C +:1086D000AE7E00288E590018000331C2000443808A +:1086E000AE79002C8E51001C00C8F821A67F001C1A +:1086F000AE710030965800028E550020A678001EFC +:10870000AE75003492490033313000045600000544 +:10871000925000008F8C00D08D8B007CAE6B0030AF +:10872000925000008F8F00BCA1F00000924E0033E9 +:1087300031CD000251A00007925E00018F8900BC7C +:108740002418FF80913100000311A825A1350000F5 +:10875000925E00018F9900BC2409FFBF240BFFDF4C +:10876000A33E00018F9500BC92B8000D3311007F2D +:10877000A2B1000D8F8E00BC91D0000D02097824AB +:10878000A1CF000D8F8800BC8E6D0014910A000DE2 +:108790002DAC0001000C2940014B382400E51825C0 +:1087A000A103000D964200128F8800BC8F8700D075 +:1087B000A50200028E45000490FF00BC30A4000317 +:1087C0000004302330DE000300BE102133F9000224 +:1087D00017200002244400342444003090E200BCFE +:1087E00000A2302430DF000417E0000224830004DC +:1087F000008018218F8F00AC24090002AD03000413 +:10880000A1E90000924E003F8F8D00ACA1AE0001A7 +:108810008F9500AC924C003F8E440004A6AC000241 +:10882000976B003C0E000CD63170FFFF00025380A6 +:10883000020A38253C05420000E51825AEA30004D5 +:108840008F8600AC8E480038ACC800188E440034C7 +:10885000ACC4001CACC0000CACC00010A4C0001420 +:10886000A4C00016A4C00020A4C00022ACC00024F4 +:108870008E6400145080000124040001ACC4000880 +:108880000E000CF6241100010A000E768F9000D025 +:10889000920F00D2920E00D08FB5001031EB00FF86 +:1088A00031CD00FF008D6023016C50212554FFFF66 +:1088B0000014882B0015982B023390241640FEDDFF +:1088C000000000008FB400148FBF00448FBE004032 +:1088D0003A8200018FB7003C8FB600388FB5003464 +:1088E0008FB400308FB3002C8FB200288FB10024DA +:1088F0008FB0002003E0000827BD0048331100209E +:10890000122000EF24150001921E00BC241F00015C +:108910000000A82133D900011320000DAFBF001CB7 +:108920008E4400148E0800840088102B144000022E +:10893000008030218E0600848E03006400C3A82BC3 +:1089400016A0000200C020218E0400640080A8212F +:108950008E4700148E05006400E5302B14C0000221 +:1089600000E020218E0400640095F02313C0000471 +:108970008FAC001C240A0002AFAA001C8FAC001CA4 +:10898000028C582B156000A8000018218E4F00386B +:108990008E6D000C3C0E0080AE6F00008E4A0034DD +:1089A0003C10FF9F01AE5825AE6A00049246003F7E +:1089B000360CFFFF016C38243C0500203C03FFEF20 +:1089C000A266000B00E510253468FFFF8F8700B812 +:1089D0000048F8243C04000803E4C825AE79000CE4 +:1089E0008CF80014AE60001802BE7821AE78001436 +:1089F0008CF10018AE71001C8CE90008AE690024EF +:108A00008CEE000CAE6F002CAE600028AE6E002025 +:108A1000A6600038A660003A8CED001401B58023F2 +:108A2000021E902312400011AE72001090EA003D29 +:108A30008E6500048E640000000A310000A6C82183 +:108A4000000010210326402B0082F82103E8C021FA +:108A5000AE790004AE78000090F1003DA271000AEA +:108A60008F8900B895320006A67200088F9800AC76 +:108A70002419000202A02021A31900009769003CDC +:108A80008F9200AC0E000CD63131FFFF00027B80CC +:108A90008F8500B8022F68253C0E420001AE80256C +:108AA000AE5000048F8400AC8CAC0038AC8C001845 +:108AB0008CAB0034AC8B001CAC80000CAC80001084 +:108AC000A4800014A4800016A4800020A4800022AA +:108AD000AC80002490A7003FA487000212A00135BB +:108AE0002403000153C0000290A2003D90A2003E6A +:108AF00024480001A08800018F9F00ACAFF500085A +:108B00008F8300D024070034906600BC30C500027B +:108B100050A00001240700308F9200B88F8A00BC5B +:108B2000906D00BC924B00002412C00032A50003DF +:108B3000A14B00008F8600B88F8800BC240200047F +:108B400090C400010045182330790003A1040001FE +:108B50008F8A00BC8F9F00B800F53821955800021D +:108B600097E9001200F9382103128824312F3FFFC2 +:108B7000022F7025A54E00029150000231A800047A +:108B8000320C003F358B0040A14B000212A00002C6 +:108B90008F8500BC00E838218F8E00D0ACA7000480 +:108BA000240BFFBF8DCD007C2EA400012403FFDF2A +:108BB000ACAD000890B0000D00044140320C007FC5 +:108BC000A0AC000D8F8600BC90CA000D014B102494 +:108BD000A0C2000D8F8700BC90E5000D00A3F82413 +:108BE00003E8C825A0F9000D8F9100B88F8D00BC57 +:108BF0008E380020ADB800108E290024ADA90014D5 +:108C00008E2F0028ADAF00188E2E002C0E000CF613 +:108C1000ADAE001C8FB0001C240C0002120C00EE44 +:108C20008F9000D08FA3001C006088211460000288 +:108C30000060A8210000A02156A0FE390291A023C7 +:108C40000014882B8FA90010960700103C1E0020EE +:108C50000136402302C750213112FFFFA60A00103F +:108C6000AFB20010AF5E0030000000009617001099 +:108C7000961300121277008F000000008E05000C82 +:108C80008E0B00080016698000AD7021000DC7C36F +:108C900001CDA82B0178782101F56021AE0E000CE2 +:108CA000AE0C00088FB300100013B82B02378024DD +:108CB0001200FF048F9000D00A000E3C000000005C +:108CC0008E4D0038A6600008240B0003AE6D000036 +:108CD0008E500034A260000A8F9800B8AE70000475 +:108CE0003C0500809311003FA26B000C8E6F000CBE +:108CF0003C0EFF9FA271000B01E5102535CCFFFF54 +:108D00003C03FFEF8F9200B8004C30243464FFFF27 +:108D100000C4F824AE7F000C8E590014964800124F +:108D20008F8A00B0AE7900108E490014AE60001832 +:108D3000AE600020AE690014AE6000248E470018BB +:108D400031093FFF0009F180AE6700288E4D000811 +:108D500003CA802131180001AE6D00308E4F000C27 +:108D60008F8C00AC001089C200185B80022B282178 +:108D7000240E0002A665001CA6600036AE6F002C13 +:108D8000A18E00009763003C8F8A00AC3C04420037 +:108D90003062FFFF00443025AD4600048F9F00B8CD +:108DA000240700012411C0008FF30038240600348A +:108DB000AD5300188FF90034AD59001CAD40000CC4 +:108DC000AD400010A5400014A5400016A5400020AD +:108DD000A5400022AD400024A5550002A147000196 +:108DE0008F9E00AC8F8800B88F9200BCAFD5000872 +:108DF000910D0000A24D00008F9000B88F8B00BC39 +:108E000092180001A17800018F8400BC94850002B3 +:108E100000B1782401E97025A48E0002908C000234 +:108E20003183003FA08300028F8300D08F8400BC79 +:108E3000906200BC305300025260000124060030F2 +:108E4000AC8600048C6F007C2403FFBF02A0882145 +:108E5000AC8F0008908E000D31CC007FA08C000DEF +:108E60008F8600BC90C2000D00432024A0C4000DDA +:108E70008F8900BC913F000D37F90020A139000D0A +:108E80008F8800B88F9300BC8D070020AE6700105C +:108E90008D0A0024AE6A00148D1E0028AE7E0018D4 +:108EA0008D12002C0E000CF6AE72001C0A00103D54 +:108EB0008F9000D0960E00148E03000431CCFFFF7B +:108EC000000C10C000622021AF44003C8E1F000443 +:108ED0008F46003C03E6C8231B20003C0000000036 +:108EE0008E0F000025E200013C05001034B500089B +:108EF000AF420038AF550030000000000000000015 +:108F00000000000000000000000000000000000061 +:108F100000000000000000008F580000330B00200C +:108F20001160FFFD000000008F5304003C0D002085 +:108F3000AE1300088F570404AE17000CAF4D00307D +:108F4000000000003C0608008CC600442416000106 +:108F500010D600BD00000000961F00123C0508005E +:108F60008CA5004000BFC821A61900129609001464 +:108F700025270001A6070014960A00143144FFFFBC +:108F80005486FF498FB30010A60000140E000E1681 +:108F900030A5FFFF3C0408008C84002496030012D7 +:108FA0000044102300623023A60600120A00105964 +:108FB0008FB30010A08300018F8200AC2404000155 +:108FC000AC4400080A000FF08F8300D08E0200002E +:108FD0000A0010EA3C0500108F8200C08FA7001C19 +:108FE000921800D0920B00D0920E00D0331100FFE7 +:108FF000316900FF00117940000928C001E56021B6 +:1090000031C300FF036C50210003314000C2C8216E +:10901000255F0088AF9F00ACAF9900BCA1470088D6 +:109020009768003C03C020218F9100AC0E000CD645 +:109030003110FFFF00026B80020DC0253C0442008E +:109040008F8D00B803045825AE2B00048DA900387D +:109050008F8B00AC0000882100118100AD690018E1 +:109060008DAF00343C087FFF3504FFFFAD6F001C5F +:1090700091AC003E8D65001C8D660018000C190037 +:10908000000C770200A33821020E102500E3F82B14 +:1090900000C2C821033F5021AD67001CAD6A001813 +:1090A000AD60000CAD60001091B8003E24050005D5 +:1090B00003C45024A578001495A9000403C02021FE +:1090C000A569001691AF003EA56F002095B1000480 +:1090D000A5710022AD60002491AE003FA56E000294 +:1090E00091B0003E91AC003D01901023244300015B +:1090F000A16300018F8600AC8F9F00BCACDE00082E +:10910000A3E500008F9000BC8F9900B82405FFBF35 +:1091100096070002973800120247782433093FFF70 +:1091200001E98825A6110002921200022418FFDF2F +:10913000324E003F35CD0040A20D00028F8600BCAC +:109140008F8C00D02412FFFFACC000048D8B007CFC +:109150003C0C8000ACCB000890C2000D3043007F77 +:10916000A0C3000D8F8700BC90FF000D03E5C8244D +:10917000A0F9000D8F9100BC9229000D01387824D0 +:10918000A22F000D8F9000BCAE120010AE1500147F +:10919000920E00182415FF8002AE6825A20D00185B +:1091A0008F8500BC8F8300B88CAB0018016C102435 +:1091B000004A3025ACA600189068003EA0A8001C0C +:1091C0008F9F00B88F8700BC8F9800D097F900045C +:1091D000A4F9001E0E0002138F0500848F8600D0B4 +:1091E000000279400002490090D200BC01E98821C8 +:1091F000004028213255000212A0000303D1202193 +:109200000002A8800095202190CD00BC31B200045E +:109210001240000333DF0003000540800088202156 +:10922000240600048F9E00BC00DFC8233327000300 +:1092300000875021AFCA00040E000CF6A665003866 +:109240000A0010388F9000D0961E00123C080800CB +:109250008D080024011E9021A61200120A00105948 +:109260008FB3001027BDFFE03C1808008F18005096 +:10927000AFB00010AFBF0018AFB10014AF8400B0A2 +:1092800093710074030478212410FF8031EE007F75 +:109290003225007F01F0582401DA68213C0C000AD5 +:1092A000A38500C401AC2821AF4B002494A9001071 +:1092B0009768000690A600620080382124020030E2 +:1092C0000109202330C300F0AF8500D010620019DF +:1092D0003090FFFF90AE0062240DFFF0240A005092 +:1092E00001AE6024318B00FF116A002F00000000E6 +:1092F00016000007241F0C00AF5F00248FB100147C +:109300008FBF00188FB0001003E0000827BD0020B9 +:109310000E000E1C02002021241F0C00AF5F002451 +:109320008FB100148FBF00188FB0001003E0000849 +:1093300027BD002094A200E094A400E290BF011396 +:10934000008218263079FFFF33E700C014E00009DF +:109350002F31000116000038000000005620FFE603 +:10936000241F0C000E000D18000000000A0011ED73 +:10937000241F0C001620FFDE000000000E000D1858 +:10938000000000001440FFDC241F0C001600002227 +:109390008F8300D0906901133122003FA062011336 +:1093A0000A0011ED241F0C0094AF00D48F8600D466 +:1093B00000E02821240400050E000C5C31F0FFFFC2 +:1093C0001440000524030003979100E600001821D3 +:1093D0002625FFFFA78500E68F5801B80700FFFE8E +:1093E0003C196013AF400180241F0C00AF50018472 +:1093F000007938253C101000AF4701888FB1001468 +:10940000AF5001B8AF5F00248FB000108FBF0018BD +:1094100003E0000827BD00200E000E1C02002021E2 +:109420005040FFB5241F0C008F8300D090690113BA +:109430000A0012163122003F0E000E1C02002021ED +:109440001440FFAD241F0C00122000078F8300D0B2 +:10945000906801133106003F34C20040A06201133E +:109460000A0011ED241F0C000E000D180000000072 +:109470005040FFA1241F0C008F8300D0906801137F +:109480003106003F0A00124634C20040AF9B00C8BC +:1094900003E00008AF8000EC3089FFFF0009404284 +:1094A0002D020041000929801440000200095040AB +:1094B00024080040000879400008C0C001F8582185 +:1094C000256701A800EF702125CC007F240DFF80C7 +:1094D000018D18240065302100CA282125640088E8 +:1094E000240A00883C010800AC2A004C3C0108001A +:1094F000AC240050AF8500D43C010800AC290060CA +:109500003C010800AC2800643C010800AC27005472 +:109510003C010800AC2300583C010800AC26005C6C +:1095200003E0000800000000308300FF30C6FFFFAA +:1095300030E400FF8F4201B80440FFFE00034C00FE +:10954000012438253C08600000E820253C03100079 +:10955000AF450180AF460184AF44018803E00008B5 +:10956000AF4301B88F86001C3C09601235270010FC +:109570008CCB00043C0C600E35850010316A00066F +:109580002D480001ACE800C48CC40004ACA43180B8 +:109590008CC2000894C30002ACA2318403E000082E +:1095A000A78300E43C0308008C6300508F8400E82C +:1095B0008F86001C2402FF800064C0210302C8249F +:1095C000AF5900288CCD00043305007F00BA782104 +:1095D0003C0E000C01EE2821ACAD00588CC80008F0 +:1095E000AF8500D03C076012ACA8005C8CCC0010AA +:1095F00034E80010ACAC000C8CCB000CACAB000819 +:1096000094AA00143C0208008C4200442549000141 +:10961000A4A9001494A400143083FFFF1062001763 +:109620008F8400D03C0A08008D4A0040A4AA001292 +:109630008CCE0018AC8E00248CCD0014AC8D002094 +:109640008CC70018AC87002C8CCC001424060001B9 +:10965000AC8C00288D0B00BC5166001A8D0200B442 +:109660008D0200B8A482003A948F003AA48F003C87 +:10967000948800D403E000083102FFFF3C09080091 +:109680008D290024A4A000148F8400D0A4A9001266 +:109690008CCE0018AC8E00248CCD0014AC8D002034 +:1096A0008CC70018AC87002C8CCC00142406000159 +:1096B000AC8C00288D0B00BC5566FFEA8D0200B80B +:1096C0008D0200B4A482003A948F003AA48F003C2B +:1096D000948800D403E000083102FFFF8F86001C4D +:1096E0003C0C08008D8C0050240BFF808CCD0008B2 +:1096F0003C03000C000D51C0018A4021010B48249D +:10970000AF8A00E8AF49002890C700073105007F05 +:1097100000BA10210043282130E4000410800039F1 +:10972000AF8500D090CF000731EE000811C000389F +:10973000000000008CD9000C8CC400140324C02B42 +:1097400013000030000000008CC2000CACA20064CA +:109750008CCD00182402FFF8ACAD00688CCC001052 +:10976000ACAC00808CCB000CACAB00848CCA001C71 +:10977000ACAA007C90A900BC01224024A0A800BC97 +:1097800090C300073067000810E000048F8500D008 +:1097900090AF00BC35EE0001A0AE00BC90D9000730 +:1097A00033380001130000088F8300D08F8700D06A +:1097B0002404003490E800BC35030002A0E300BCA0 +:1097C0008F8300D0AC6400C090C90007312600022E +:1097D00010C0000500000000906A00BC3542000483 +:1097E000A06200BC8F8300D09065011330AD003FB4 +:1097F000A06D01138F8C00D0958B00D403E000087E +:109800003162FFFF8CC200140A0013020000000046 +:109810000A001303ACA0006427BDFFD8AFB000104E +:109820008F90001CAFBF0024AFB40020AFB200186F +:10983000AFB10014AFB3001C9613000E3C07600AD2 +:109840003C1460063264FFFF369300100E00125580 +:1098500034F404108F8400D43C11600E0E00099B78 +:1098600036310010920E00153C0708008CE70060AE +:109870003C12601231CD000FA38D00F08E0E00045B +:109880008E0D000896080012961F00109619001AF7 +:109890009618001E960F001C310CFFFF33EBFFFFE4 +:1098A000332AFFFF3309FFFF31E6FFFF3C010800C9 +:1098B000AC2B00403C010800AC2C00243C0108000B +:1098C000AC2A0044AE293178AE26317C92020015D4 +:1098D0009603001636520010304400FF3065FFFF3B +:1098E0003C0608008CC60064AE243188AE4500B446 +:1098F0009208001496190018241F0001011FC004CB +:10990000332FFFFF3C0508008CA50058AE5800B867 +:10991000AE4F00BC920C0014AF8E00D8AF8D00DCAF +:10992000318B00FFAE4B00C0920A0015AE670048B5 +:10993000AE66004C314900FFAE4900C8AE65007C00 +:109940003C0308008C6300503C0408008C84004CED +:109950003C0808008D0800543C0208008C42005C62 +:109960008FBF0024AE6300808FB00010AE83007400 +:109970008FB3001CAE22319CAE4200DCAE2731A07A +:10998000AE2631A4AE24318CAE233190AE28319472 +:10999000AE253198AE870050AE860054AE8500707B +:1099A0008FB10014AE4700E0AE4600E4AE4400CCF8 +:1099B000AE4300D0AE4800D4AE4500D88FB40020EE +:1099C0008FB2001803E0000827BD002827BDFFE084 +:1099D000AFB10014AFBF0018241100010E000845FC +:1099E000AFB0001010510005978400E6978300CCBB +:1099F0000083102B144000088F8500D42407000238 +:109A00008FBF00188FB100148FB0001000E010213C +:109A100003E0000827BD00200E000C7A2404000596 +:109A2000AF8200E81040FFF6240700020E0008494C +:109A30008F90001C979F00E68F9900E88F8D00C8DB +:109A400027EF0001240E0050AF590020A78F00E639 +:109A5000A1AE00003C0C08008D8C00648F8600C80D +:109A6000240A8000000C5E00ACCB0074A4C0000689 +:109A700094C9000A241FFF803C0D000C012AC02459 +:109A8000A4D8000A90C8000A24182000011F182535 +:109A9000A0C3000A8F8700C8A0E000788F8500C8A7 +:109AA00000003821A0A000833C0208008C42005036 +:109AB0008F8400E80044782101FFC824AF590028B2 +:109AC000960B000231EE007F01DA6021018D30211A +:109AD000A4CB00D4960A0002AF8600D03C0E00044E +:109AE00025492401A4C900E68E080004ACC800047E +:109AF0008E030008ACC30000A4C00010A4C0001472 +:109B0000A0C000D08F8500D02403FFBFA0A000D14B +:109B10003C0408008C8400648F8200D0A04400D2F2 +:109B20008E1F000C8F8A00D0978F00E4AD5F001C61 +:109B30008E19001024100030AD590018A5400030D7 +:109B4000A5510054A5510056A54F0016AD4E006812 +:109B5000AD580080AD580084914D006231AC000FCB +:109B6000358B0010A14B00628F8600D090C9006336 +:109B70003128007FA0C800638F8400D02406FFFF37 +:109B80009085006300A31024A08200638F9100D011 +:109B900000E01021923F00BC37F90001A23900BC5F +:109BA0008F8A00D0938F00F0AD580064AD5000C094 +:109BB000914E00D3000F690031CC000F018D582564 +:109BC000A14B00D38F8500D08F8900DCACA900E8C1 +:109BD0008F8800D88FBF00188FB100148FB000108D +:109BE00027BD0020ACA800ECA4A600D6A4A000E0ED +:109BF000A4A000E203E000080000000027BDFFE091 +:109C0000AFB000108F90001CAFB10014AFBF0018B0 +:109C10008E1900043C1808008F180050240FFF8094 +:109C2000001989C00238702131CD007F01CF602436 +:109C300001BA50213C0B000CAF4C0028014B4021D5 +:109C4000950900D4950400D68E0700043131FFFF3A +:109C5000AF8800D00E000913000721C08E06000453 +:109C60008F8300C8000629C0AF4500209064003EE5 +:109C700030820040144000068F8400D0341FFFFF64 +:109C8000948300D63062FFFF145F000400000000E0 +:109C9000948400D60E0008A83084FFFF8E050004CF +:109CA000022030218FBF00188FB100148FB0001038 +:109CB0002404002200003821000529C00A0012797E +:109CC00027BD002027BDFFE0AFB100143091FFFF9A +:109CD000AFB00010AFBF00181220001D000080219F +:109CE0008F86001C8CC500002403000600053F027F +:109CF0000005140230E4000714830015304500FF0E +:109D00002CA800061100004D000558803C0C0800EE +:109D1000258C57C8016C50218D4900000120000896 +:109D2000000000008F8E00EC240D000111CD0059C1 +:109D300000000000260B00013170FFFF24CA002044 +:109D40000211202B014030211480FFE6AF8A001C55 +:109D5000020010218FBF00188FB100148FB00010C7 +:109D600003E0000827BD0020938700CE14E00038F0 +:109D7000240400140E001335000000008F86001C20 +:109D8000240200010A00147CAF8200EC8F8900ECF1 +:109D9000240800021128003B24040013000028219D +:109DA00000003021240700010E001279000000009D +:109DB0000A00147C8F86001C8F8700EC24050002AB +:109DC00014E5FFF6240400120E0012E60000000065 +:109DD0008F8500E800403021240400120E00127923 +:109DE000000038210A00147C8F86001C8F8300EC51 +:109DF000241F0003147FFFD0260B00010E001298D1 +:109E0000000000008F8500E800403021240200029D +:109E10002404001000003821AF8200EC0E001279FB +:109E2000000000000A00147C8F86001C8F8F00EC5D +:109E30002406000211E6000B0000000024040010BC +:109E400000002821000030210A0014992407000195 +:109E5000000028210E001279000030210A00147C35 +:109E60008F86001C0E0013A2000000001440001298 +:109E70008F99001C8F86001C240200030A00147CAA +:109E8000AF8200EC0E00142E000000000A00147CCB +:109E90008F86001C0E0012880000000024020002C1 +:109EA0002404001400002821000030210000382183 +:109EB0000A0014B6AF8200EC0040382124040010E0 +:109EC00097380002000028210E0012793306FFFFA8 +:109ED0000A00147C8F86001C8F8400C83C077FFF1B +:109EE00034E6FFFF8C8500742402000100A61824CC +:109EF000AC83007403E00008A082000510A00036C7 +:109F00002CA20080274A04003C0B00052409008095 +:109F1000104000072408008030A6000F00C5402133 +:109F20002D0300811460000200A048212408008055 +:109F3000AF4B0030000000000000000000000000F7 +:109F40001100000900003821014030218C8D0000F3 +:109F500024E7000400E8602BACCD0000248400045A +:109F60001580FFFA24C60004000000000000000075 +:109F7000000000003C0E0006010E3825AF470030FF +:109F80000000000000000000000000008F4F0000F3 +:109F900031E800101100FFFD000000008F42003C7E +:109FA0008F43003C0049C8210323C02B1300000449 +:109FB000000000008F4C003825860001AF460038B5 +:109FC0008F47003C00A9282300E96821AF4D003CE1 +:109FD00014A0FFCE2CA2008003E0000800000000C7 +:109FE00027BDFFD03C020002AFB100143C11000CB1 +:109FF000AF450038AFB3001CAF46003C008098214D +:10A00000AF42003024050088AF44002803512021CE +:10A01000AFBF0028AFB50024AFB40020AFB2001826 +:10A020000E0014EEAFB000103C1F08008FFF004C74 +:10A030003C1808008F1800642410FF8003F3A82147 +:10A0400032B9007F02B078240018A0C0033A702112 +:10A050000018914001D12021AF4F00280E0014EECE +:10A06000025428213C0D08008DAD0050240501202C +:10A0700001B35821316C007F01705024019A4821AE +:10A08000013120210E0014EEAF4A00283C080800E0 +:10A090008D0800543C0508008CA50064011338218C +:10A0A00030E6007F00F0182400DA20210091202102 +:10A0B000AF4300280E0014EE000529403C020800C2 +:10A0C0008C4200583C1008008E1000601200001CEA +:10A0D000005388212415FF800A0015713C14000CE0 +:10A0E0003226007F0235182400DA20210240282180 +:10A0F000AF430028009420210E0014EE2610FFC06C +:10A100001200000F023288212E05004110A0FFF43A +:10A11000241210003226007F00109180023518248E +:10A1200000DA202102402821AF430028009420219A +:10A130000E0014EE000080211600FFF30232882189 +:10A140003C0B08008D6B005C240AFF802405000294 +:10A1500001734021010A4824AF4900283C0408004B +:10A16000948400623110007F021A88213C07000CA1 +:10A170000E000CAA0227982100402821026020210D +:10A180008FBF00288FB500248FB400208FB3001C30 +:10A190008FB200188FB100148FB000100A0014EEB7 +:10A1A00027BD00308F83001C8C6200041040000328 +:10A1B0000000000003E00008000000008C640010B4 +:0CA1C0008C6500080A0015278C66000C56 +:04A1CC00000000008F +:10A1D0000000001B0000000F0000000A0000000843 +:10A1E000000000060000000500000005000000045B +:10A1F0000000000400000003000000030000000352 +:10A200000000000300000003000000020000000244 +:10A210000000000200000002000000020000000236 +:10A220000000000200000002000000020000000226 +:10A230000000000200000002000000020000000216 +:10A240000000000200000001000000010000000109 +:10A2500008000F2408000D6C08000FB808001060FB +:10A2600008000F4C08000F8C0800119408000D889E +:10A27000080011B808000DD8080015540800151C76 +:10A2800008000D8808000D8808000D88080012409D +:10A290000800124008000D8808000D88080014E02E +:10A2A00008000D8808000D8808000D8808000D883A +:10A2B000080013B408000D8808000D8808000D88F8 +:10A2C00008000D8808000D8808000D8808000D881A +:10A2D00008000D8808000D8808000D8808000D880A +:10A2E00008000D8808000D8808000D8808000FACD4 +:10A2F00008000D8808000D880800167808000D88F1 +:10A3000008000D8808000D8808000D8808000D88D9 +:10A3100008000D8808000D8808000D8808000D88C9 +:10A3200008000D8808000D8808000D8808000D88B9 +:10A3300008000D8808000D8808000D8808000D88A9 +:10A340000800141008000D8808000D880800133458 +:10A35000080012A408001E2C08001EFC08001F1490 +:10A3600008001F2808001F3808001E2C08001E2C9B +:10A3700008001E2C08001ED808002E1408002E1CF1 +:10A3800008002DE408002DF008002DFC08002E0820 +:10A39000080052E8080052A8080052740800524809 +:08A3A00008005224080051E0FE +:08A3A8000A000C840000000013 +:10A3B000000000000000000D727870362E302E3143 +:10A3C0003500000006000F0300000000000000013F +:10A3D000000000000000000000000000000000007D +:10A3E000000000000000000000000000000000006D +:10A3F000000000000000000000000000000000005D +:10A40000000000000000000000000000000000004C +:10A41000000000000000000000000000000000003C +:10A42000000000000000000000000000000000002C +:10A43000000000000000000000000000000000001C +:10A44000000000000000000000000000000000000C +:10A4500000000000000000000000000000000000FC +:10A4600000000000000000000000000000000000EC +:10A4700000000000000000000000000000000000DC +:10A4800000000000000000000000000000000000CC +:10A4900000000000000000000000000000000000BC +:10A4A00000000000000000000000000000000000AC +:10A4B000000000000000000000000000000000009C +:10A4C000000000000000000000000000000000008C +:10A4D000000000000000000000000000000000007C +:10A4E000000000000000000000000000000000006C +:10A4F000000000000000000000000000000000005C +:10A50000000000000000000000000000000000004B +:10A51000000000000000000000000000000000003B +:10A52000000000000000000000000000000000002B +:10A53000000000000000000000000000000000001B +:10A54000000000000000000000000000000000000B +:10A5500000000000000000000000000000000000FB +:10A5600000000000000000000000000000000000EB +:10A5700000000000000000000000000000000000DB +:10A5800000000000000000000000000000000000CB +:10A5900000000000000000000000000000000000BB +:10A5A00000000000000000000000000000000000AB +:10A5B000000000000000000000000000000000009B +:10A5C000000000000000000000000000000000008B +:10A5D000000000000000000000000000000000007B +:10A5E000000000000000000000000000000000006B +:10A5F000000000000000000000000000000000005B +:10A60000000000000000000000000000000000004A +:10A61000000000000000000000000000000000003A +:10A62000000000000000000000000000000000002A +:10A63000000000000000000000000000000000001A +:10A64000000000000000000000000000000000000A +:10A6500000000000000000000000000000000000FA +:10A6600000000000000000000000000000000000EA +:10A6700000000000000000000000000000000000DA +:10A6800000000000000000000000000000000000CA +:10A6900000000000000000000000000000000000BA +:10A6A00000000000000000000000000000000000AA +:10A6B000000000000000000000000000000000009A +:10A6C000000000000000000000000000000000008A +:10A6D000000000000000000000000000000000007A +:10A6E000000000000000000000000000000000006A +:10A6F000000000000000000000000000000000005A +:10A700000000000000000000000000000000000049 +:10A710000000000000000000000000000000000039 +:10A720000000000000000000000000000000000029 +:10A730000000000000000000000000000000000019 +:10A740000000000000000000000000000000000009 +:10A7500000000000000000000000000000000000F9 +:10A7600000000000000000000000000000000000E9 +:10A7700000000000000000000000000000000000D9 +:10A7800000000000000000000000000000000000C9 +:10A7900000000000000000000000000000000000B9 +:10A7A00000000000000000000000000000000000A9 +:10A7B0000000000000000000000000000000000099 +:10A7C0000000000000000000000000000000000089 +:10A7D0000000000000000000000000000000000079 +:10A7E0000000000000000000000000000000000069 +:10A7F0000000000000000000000000000000000059 +:10A800000000000000000000000000000000000048 +:10A810000000000000000000000000000000000038 +:10A820000000000000000000000000000000000028 +:10A830000000000000000000000000000000000018 +:10A840000000000000000000000000000000000008 +:10A8500000000000000000000000000000000000F8 +:10A8600000000000000000000000000000000000E8 +:10A8700000000000000000000000000000000000D8 +:10A8800000000000000000000000000000000000C8 +:10A8900000000000000000000000000000000000B8 +:10A8A00000000000000000000000000000000000A8 +:10A8B0000000000000000000000000000000000098 +:10A8C0000000000000000000000000000000000088 +:10A8D0000000000000000000000000000000000078 +:10A8E0000000000000000000000000000000000068 +:10A8F0000000000000000000000000000000000058 +:10A900000000000000000000000000000000000047 +:10A910000000000000000000000000000000000037 +:10A920000000000000000000000000000000000027 +:10A930000000000000000000000000000000000017 +:10A940000000000000000000000000000000000007 +:10A9500000000000000000000000000000000000F7 +:10A9600000000000000000000000000000000000E7 +:10A9700000000000000000000000000000000000D7 +:10A9800000000000000000000000000000000000C7 +:10A9900000000000000000000000000000000000B7 +:10A9A00000000000000000000000000000000000A7 +:10A9B0000000000000000000000000000000000097 +:10A9C0000000000000000000000000000000000087 +:10A9D0000000000000000000000000000000000077 +:10A9E0000000000000000000000000000000000067 +:10A9F0000000000000000000000000000000000057 +:10AA00000000000000000000000000000000000046 +:10AA10000000000000000000000000000000000036 +:10AA20000000000000000000000000000000000026 +:10AA30000000000000000000000000000000000016 +:10AA40000000000000000000000000000000000006 +:10AA500000000000000000000000000000000000F6 +:10AA600000000000000000000000000000000000E6 +:10AA700000000000000000000000000000000000D6 +:10AA800000000000000000000000000000000000C6 +:10AA900000000000000000000000000000000000B6 +:10AAA00000000000000000000000000000000000A6 +:10AAB0000000000000000000000000000000000096 +:10AAC0000000000000000000000000000000000086 +:10AAD0000000000000000000000000000000000076 +:10AAE0000000000000000000000000000000000066 +:10AAF0000000000000000000000000000000000056 +:10AB00000000000000000000000000000000000045 +:10AB10000000000000000000000000000000000035 +:10AB20000000000000000000000000000000000025 +:10AB30000000000000000000000000000000000015 +:10AB40000000000000000000000000000000000005 +:10AB500000000000000000000000000000000000F5 +:10AB600000000000000000000000000000000000E5 +:10AB700000000000000000000000000000000000D5 +:10AB800000000000000000000000000000000000C5 +:10AB900000000000000000000000000000000000B5 +:10ABA00000000000000000000000000000000000A5 +:10ABB0000000000000000000000000000000000095 +:10ABC0000000000000000000000000000000000085 +:10ABD0000000000000000000000000000000000075 +:10ABE0000000000000000000000000000000000065 +:10ABF0000000000000000000000000000000000055 +:10AC00000000000000000000000000000000000044 +:10AC10000000000000000000000000000000000034 +:10AC20000000000000000000000000000000000024 +:10AC30000000000000000000000000000000000014 +:10AC40000000000000000000000000000000000004 +:10AC500000000000000000000000000000000000F4 +:10AC600000000000000000000000000000000000E4 +:10AC700000000000000000000000000000000000D4 +:10AC800000000000000000000000000000000000C4 +:10AC900000000000000000000000000000000000B4 +:10ACA00000000000000000000000000000000000A4 +:10ACB0000000000000000000000000000000000094 +:10ACC0000000000000000000000000000000000084 +:10ACD0000000000000000000000000000000000074 +:10ACE0000000000000000000000000000000000064 +:10ACF0000000000000000000000000000000000054 +:10AD00000000000000000000000000000000000043 +:10AD10000000000000000000000000000000000033 +:10AD20000000000000000000000000000000000023 +:10AD30000000000000000000000000000000000013 +:10AD40000000000000000000000000000000000003 +:10AD500000000000000000000000000000000000F3 +:10AD600000000000000000000000000000000000E3 +:10AD700000000000000000000000000000000000D3 +:10AD800000000000000000000000000000000000C3 +:10AD900000000000000000000000000000000000B3 +:10ADA00000000000000000000000000000000000A3 +:10ADB0000000000000000000000000000000000093 +:10ADC0000000000000000000000000000000000083 +:10ADD0000000000000000000000000000000000073 +:10ADE0000000000000000000000000000000000063 +:10ADF0000000000000000000000000000000000053 +:10AE00000000000000000000000000000000000042 +:10AE10000000000000000000000000000000000032 +:10AE20000000000000000000000000000000000022 +:10AE30000000000000000000000000000000000012 +:10AE40000000000000000000000000000000000002 +:10AE500000000000000000000000000000000000F2 +:10AE600000000000000000000000000000000000E2 +:10AE700000000000000000000000000000000000D2 +:10AE800000000000000000000000000000000000C2 +:10AE900000000000000000000000000000000000B2 +:10AEA00000000000000000000000000000000000A2 +:10AEB0000000000000000000000000000000000092 +:10AEC0000000000000000000000000000000000082 +:10AED0000000000000000000000000000000000072 +:10AEE0000000000000000000000000000000000062 +:10AEF0000000000000000000000000000000000052 +:10AF00000000000000000000000000000000000041 +:10AF10000000000000000000000000000000000031 +:10AF20000000000000000000000000000000000021 +:10AF30000000000000000000000000000000000011 +:10AF40000000000000000000000000000000000001 +:10AF500000000000000000000000000000000000F1 +:10AF600000000000000000000000000000000000E1 +:10AF700000000000000000000000000000000000D1 +:10AF800000000000000000000000000000000000C1 +:10AF900000000000000000000000000000000000B1 +:10AFA00000000000000000000000000000000000A1 +:10AFB0000000000000000000000000000000000091 +:10AFC0000000000000000000000000000000000081 +:10AFD0000000000000000000000000000000000071 +:10AFE0000000000000000000000000000000000061 +:10AFF0000000000000000000000000000000000051 +:10B000000000000000000000000000000000000040 +:10B010000000000000000000000000000000000030 +:10B020000000000000000000000000000000000020 +:10B030000000000000000000000000000000000010 +:10B040000000000000000000000000000000000000 +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000080000000001B +:10D59000000000000000000000000000000000008B +:10D5A0000000000000000000000000000000000A71 +:10D5B0000000000000000000000000001000000358 +:10D5C000000000000000000D0000000D3C020800FB +:10D5D000244273203C030800246377ACAC40000075 +:10D5E0000043202B1480FFFD244200043C1D080052 +:10D5F00037BD7FFC03A0F0213C100800261032103C +:10D600003C1C0800279C73200E0010FE0000000048 +:10D610000000000D30A5FFFF30C600FF274301804A +:10D620008F4201B80440FFFE24020002AC640000F7 +:10D63000A4650008A066000AA062000B3C0210006E +:10D64000AC67001803E00008AF4201B83C0360007B +:10D650008C624FF80440FFFE3C020200AC644FC0F5 +:10D66000AC624FC43C02100003E00008AC624FF80B +:10D670009482000C2486001400A0382100021302BA +:10D68000000210800082402100C8102B104000577B +:10D690000000000090C300002C62000950400051BF +:10D6A00090C20001000310803C030800246372D084 +:10D6B000004310218C4200000040000800000000E0 +:10D6C00090C300012402000A1462003A0000000026 +:10D6D000010610232C42000A1440003624C6000222 +:10D6E0008CE2000034420100ACE2000090C2000075 +:10D6F00090C3000190C4000290C5000300031C0009 +:10D7000000021600004310250004220000441025EA +:10D710000045102524C60004ACE2000490C20000BD +:10D7200090C3000190C4000290C5000300021600DF +:10D7300000031C00004310250004220000441025B3 +:10D740000045102524C600040A000CB8ACE200080D +:10D7500090C30001240200041462001624C60002D3 +:10D7600090C2000090C400018CE30000000212008F +:10D77000004410253463000424C60002ACE2000C0F +:10D780000A000CB8ACE3000090C3000124020003BF +:10D790001462000824C600028CE2000090C300005E +:10D7A00024C6000134420008A0E300100A000CB8AF +:10D7B000ACE2000003E000082402000190C3000175 +:10D7C000240200021062000224C400020100202191 +:10D7D0000A000CB8008030210A000CB824C60001F1 +:10D7E00090C200010A000CB800C2302103E000081A +:10D7F0000000102127BDFFE8AFBF0014AFB000103C +:10D800000E00130200808021936200052403FFFEB6 +:10D8100002002021004310248FBF00148FB000109D +:10D82000A36200050A00130B27BD001827BDFFE8FF +:10D83000AFB00010AFBF00140E000F3C008080217D +:10D840009362000024030050304200FF14430004A0 +:10D8500024020100AF4201800A000D3002002021A5 +:10D86000AF400180020020218FBF00148FB0001054 +:10D870000A000FE727BD001827BDFF80AFBE007864 +:10D88000AFB70074AFB20060AFBF007CAFB600703E +:10D89000AFB5006CAFB40068AFB30064AFB1005C6B +:10D8A000AFB000588F5001283C0208008C4231A0D4 +:10D8B0002403FF809365003F0202102100431024DF +:10D8C000AF4200243C0208008C4231A09364000562 +:10D8D00030B200FF020210213042007F03421821C3 +:10D8E000000420273C02000A006218213084000155 +:10D8F000AF8300140000F0210000B8211480005311 +:10D90000AFA0005093430116934401128F450104C8 +:10D91000306300FF3C020001308400FF00A2282495 +:10D92000034310210344182124564000246740007B +:10D9300014A001CD2402000193620000304300FFD7 +:10D94000240200201062000524020050106200062C +:10D95000000000000A000D74000000000000000D2F +:10D960000A000D7DAFA000303C1E080027DE736C5E +:10D970000A000D7DAFA000303C0208008C4200DCA4 +:10D98000244200013C010800AC2200DC0E00139F81 +:10D99000000000000A000F318FBF007C8F4201049D +:10D9A0003C03002092D3000D004310240002202BE2 +:10D9B00000042140AFA400308F4301043C0200402A +:10D9C0000062182414600002348500400080282181 +:10D9D00032620020AFA500301440000234A600805F +:10D9E00000A0302110C0000BAFA6003093C5000886 +:10D9F0008F67004C0200202100052B0034A5008118 +:10DA000030A5F0810E000C9B30C600FF0A000F2EDF +:10DA1000000000009362003E304200401040000FC2 +:10DA200024020004564200072402001202002021B2 +:10DA300000E028210E0013F702C030210A000F3148 +:10DA40008FBF007C16420005000000000E000D2173 +:10DA5000000020210A000F318FBF007C9743011A7C +:10DA600096C4000E93620035326500043075FFFFE6 +:10DA700000442004AFA400548ED1000410A000156F +:10DA80008ED400089362003E3042004010400007F0 +:10DA9000000000000E0013E0022020211040000DC5 +:10DAA000000000000A000F2E000000008F620044FA +:10DAB000022210230440016A000000008F62004827 +:10DAC0000222102304410166240400160A000E21DC +:10DAD0008FC200048F620048022210230440000815 +:10DAE000000000003C0208008C423100244200018A +:10DAF0003C010800AC2231000A000F2300000000A6 +:10DB00008F62004002221023184000128F840014FC +:10DB10003C0208008C423100327300FC0000A82156 +:10DB2000244200013C010800AC2231008F63004018 +:10DB30009482011C022318233042FFFF0043102A65 +:10DB4000504000102402000C8F6200400A000DF2C9 +:10DB5000022210239483011C9762003C0043102B87 +:10DB600010400006000000009482011C00551023A4 +:10DB7000A482011C0A000DF72402000CA480011CE1 +:10DB80002402000CAFA200308F620040005120231D +:10DB90001880000D02A4102A144001260000000085 +:10DBA0001495000602A410233A62000130420001DD +:10DBB000144001200000000002A410230224882148 +:10DBC0000A000E093055FFFF0000202132620002DA +:10DBD0001040001A326200109362003E3042004052 +:10DBE000504000118FC200040E00130202002021D9 +:10DBF00024020018A362003F936200052403FFFE85 +:10DC000002002021004310240E00130BA362000524 +:10DC100024040039000028210E0013C9240600182E +:10DC20000A000F3024020001240400170040F80904 +:10DC3000000000000A000F3024020001104001081B +:10DC4000000000008F63004C8F620054028210239A +:10DC50001C40010302831023044200010060A02144 +:10DC6000AFA40018AFB10010AFB50014934201206B +:10DC70008F6500409763003C304200FF0342102153 +:10DC8000004410218FA400543063FFFF2442400061 +:10DC90000083182B8FA40030AFA20020AFA500286E +:10DCA00000832025AFA40030AFA50024AFA0002C36 +:10DCB000AFB400349362003E30420008504000117F +:10DCC0008FC2000002C0202127A500380E000CB230 +:10DCD000AFA000385440000B8FC200008FA2003864 +:10DCE00030420100504000078FC200008FA3003C6B +:10DCF0008F6200600062102304430001AF63006084 +:10DD00008FC200000040F80927A400108FA2003045 +:10DD10003042000254400001327300FE9362003E24 +:10DD200030420040104000378FA200248F62005420 +:10DD30001682001A326200012402001412420010FE +:10DD40002A42001510400006240200162402000C8E +:10DD500012420007326200010A000E7D000000003E +:10DD600012420005326200010A000E7D0000000030 +:10DD70000A000E782417000E0A000E7824170010EF +:10DD80000A000E7C24170012936200232403FFBDB7 +:10DD900000431024A36200233262000110400019E6 +:10DDA0008FA200242402000C1242000E2A42000D11 +:10DDB000104000062402000E2402000A124200074E +:10DDC0008FA200240A000E9524420001124200088E +:10DDD0008FA200240A000E95244200010A000E932F +:10DDE000241700082402000E16E200022417001671 +:10DDF000241700108FA2002424420001AFA20024A7 +:10DE00008FA200248FA300148F76004000431021BE +:10DE1000AF6200408F8200149442011C1040000940 +:10DE2000000000008F6200488F6400409763003C50 +:10DE3000004410233063FFFF0043102A1040000805 +:10DE40008FA20054936400368F6300403402FFFCBD +:10DE50000082100400621821AF6300488FA20054B2 +:10DE60008FA600300282902130C200081040000EC0 +:10DE7000000000008F6200581642000430C600FF08 +:10DE80009742011A5040000134C6001093C50008A3 +:10DE90008FA700340200202100052B0034A500804C +:10DEA0000E000C9B30A5F0808F62004000561023BE +:10DEB0001840001B8FA200183C0208008C423198C9 +:10DEC000304200101040000D2402000197620068EB +:10DED0001440000A240200018F8200149442011CA5 +:10DEE0001440000624020001A76200689742007AED +:10DEF000244200640A000EE9A7620012A762001221 +:10DF00000E001302020020219362007D2403000111 +:10DF100002002021344200010A000EE7AFA30050A6 +:10DF20001840000A000000000E0013020200202129 +:10DF30009362007D2403000102002021AFA3005062 +:10DF4000344200040E00130BA362007D9362003E76 +:10DF5000304200401440000C326200011040000AC0 +:10DF6000000000008F6300408FC2000424040018EA +:10DF7000246300010040F809AF6300408FA2003025 +:10DF80000A000F30304200048F6200581052001017 +:10DF9000000000008F620018022210231C400008BD +:10DFA000240400018F6200181622000900000000FE +:10DFB0008F62001C02821023044000050000000054 +:10DFC000AF720058AFA40050AF710018AF74001CBE +:10DFD00012E0000B8FA200500E001302020020215D +:10DFE000A377003F0E00130B0200202102E0302136 +:10DFF000240400370E0013C9000028218FA200500E +:10E0000010400003000000000E000CA902002021B7 +:10E0100012A00005000018218FA200303042000439 +:10E020005040001100601021240300010A000F304D +:10E03000006010210E001302020020219362007D77 +:10E0400002002021344200040E00130BA362007D65 +:10E050000E000CA9020020210A000F30240200014A +:10E06000AF400044240200018FBF007C8FBE0078C7 +:10E070008FB700748FB600708FB5006C8FB40068D6 +:10E080008FB300648FB200608FB1005C8FB0005816 +:10E0900003E0000827BD00808F4201B80440FFFE66 +:10E0A00024020800AF4201B803E0000800000000AD +:10E0B0003C02000803421021944200483084FFFFD4 +:10E0C000248400123045FFFF10A0001700A4102B7D +:10E0D0001040001624020003934201202403001A7A +:10E0E000A343018B304200FF2446FFFE8F820000D5 +:10E0F00000A6182B3863000100021382004310248D +:10E10000104000058F84000434820001A74601946A +:10E1100003E00008AF8200042402FFFE0082102406 +:10E1200003E00008AF8200042402000303E00008BB +:10E13000A342018B27BDFFE0AFB10014AFB00010C8 +:10E14000AFBF001830B0FFFF30D1FFFF8F4201B8E2 +:10E150000440FFFE00000000AF440180AF440020F7 +:10E160000E000F42020020218F8300008F840004E4 +:10E17000A750019AA750018EA74301908F830008F2 +:10E1800030828000AF4301A8A75101881040000EE3 +:10E190008F82000493420116304200FC24420004A6 +:10E1A000005A10218C4240003042FFFF144000060C +:10E1B0008F8200043C02FFFF34427FFF0082102464 +:10E1C000AF8200048F8200042403BFFF00431024A9 +:10E1D000A74201A69743010C8F42010400031C00D3 +:10E1E0003042FFFF00621825AF4301AC3C02100033 +:10E1F000AF4201B88FBF00188FB100148FB000106C +:10E2000003E0000827BD00208F47007093420112F1 +:10E210008F83000027BDFFF0304200FF00022882FC +:10E2200030620100000030211040004324A40003AC +:10E230003062400010400010306220000004108066 +:10E24000005A10218C43400024A4000400041080D4 +:10E25000AFA30000005A10218C424000AFA200047E +:10E2600093420116304200FC005A10218C424000BB +:10E270000A000FC0AFA200081040002F000030219C +:10E2800000041080005A10218C43400024A4000494 +:10E2900000041080AFA30000005A10218C424000FF +:10E2A000AFA00008AFA200048FA800080000302132 +:10E2B00000002021240A00083C090800252901004B +:10E2C00003A41021148A000300042A001100000A8C +:10E2D0000000000090420000248400012C83000C08 +:10E2E00000A2102100021080004910218C42000081 +:10E2F0001460FFF300C230263C0408008C84310413 +:10E300008F4200702C8300201060000900473823E2 +:10E310003C030800246331080004108000431021EE +:10E3200024830001AC4700003C010800AC23310409 +:10E33000AF8600082406000100C0102103E0000899 +:10E3400027BD00103C0208008C42003827BDFFD0DA +:10E35000AFB50024AFB40020AFB10014AFBF0028A8 +:10E36000AFB3001CAFB20018AFB00010000088219E +:10E370003C15080026B50038144000022454FFFF65 +:10E380000000A0219742010E8F8400003042FFFF61 +:10E39000308340001060000A245200043C02002038 +:10E3A0000082102450400007308280008F820004D9 +:10E3B0002403BFFF008318240A0010103442100009 +:10E3C000308280001040000A3C02002000821024AD +:10E3D000104000078F8200043C03FFFF34637FFF7F +:10E3E0000083182434428000AF820004AF83000011 +:10E3F0000E000F980000000014400007000000000D +:10E400009743011E9742011C3063FFFF0002140076 +:10E4100000621825AF8300089742010C8F4340002B +:10E420003045FFFF3402FFFF1462000300000000CC +:10E430000A001028241100208F42400030420100C1 +:10E4400054400001241100108F840000308210001D +:10E450005040001436310001308200201440000B7F +:10E460003C021000008210245040000E36310001A2 +:10E470003C030E003C020DFF008318243442FFFFD2 +:10E480000043102B50400007363100013C020800C9 +:10E490008C42002C244200013C010800AC22002CDC +:10E4A000363100053C0608008CC6003454C00023F9 +:10E4B0008F8500008F820004304240005440001FCE +:10E4C0008F8500003C021F01008210243C031000D5 +:10E4D0005443001A8F85000030A202001440001738 +:10E4E0008F8500003250FFFF363100028F4201B8A5 +:10E4F0000440FFFE00000000AF4001800200202128 +:10E500000E000F42AF4000208F8300042402BFFFA3 +:10E51000A750019A006218248F820000A750018E34 +:10E52000A7510188A74301A6A74201903C02100011 +:10E53000AF4201B80A0010F5000010213C021000A3 +:10E5400000A210241040003A0000000010C0000F8C +:10E550000000000030A201001040000C3C0302004B +:10E560003C020F0000A2102410430008000000002D +:10E570008F8200080054102400551021904200049E +:10E58000244200040A00109F000221C00000000085 +:10E59000000516023050000F3A0300022E4203EF2E +:10E5A000384200012C6300010062182414600073DB +:10E5B000240200013C0308008C6300D02E06000CEE +:10E5C000386200012C42000100461024144000155E +:10E5D000001021C02602FFFC2C4200045440001110 +:10E5E00000002021386200022C4200010046102465 +:10E5F00010400003000512420A00109F0000202175 +:10E600000010182B0043102450400006001021C0B9 +:10E61000000020213245FFFF0E000F633226FFFB72 +:10E62000001021C03245FFFF0A0010F2362600021A +:10E630008F4240003C0308008C63002430420100FC +:10E640001040004630620001322200043070000D9C +:10E65000144000022413000424130002000512C217 +:10E66000384200012E4303EF3042000138630001BD +:10E6700000431025104000033231FFFB2402FFFB52 +:10E680000202802410C000183202000130A20100F2 +:10E6900010400015320200013C020F0000A21024BD +:10E6A0003C0302001043000F8F8200082403FFFE8A +:10E6B00002038024005410240055102190420004CD +:10E6C000023330252442000412000002000221C05F +:10E6D0003226FFFF0E000F633245FFFF12000027B6 +:10E6E00000001021320200011040000D320200042F +:10E6F0002402000112020002023330253226FFFFFD +:10E70000000020210E000F633245FFFF2402FFFEB0 +:10E7100002028024120000190000102132020004BD +:10E72000104000162402000124020004120200021C +:10E73000023330253226FFFF3245FFFF0E000F6304 +:10E74000240401002402FFFB020280241200000BBB +:10E75000000010210A0010F52402000110400007FB +:10E76000000010213245FFFF362600020000202164 +:10E770000E000F6300000000000010218FBF002872 +:10E780008FB500248FB400208FB3001C8FB2001807 +:10E790008FB100148FB0001003E0000827BD0030D7 +:10E7A00027BDFFD0AFB000103C04600CAFBF002C01 +:10E7B000AFB60028AFB50024AFB40020AFB3001C43 +:10E7C000AFB20018AFB100148C8250002403FF7F59 +:10E7D0003C1A8000004310243442380CAC825000B4 +:10E7E000240200033C106000AF4200088E020808BB +:10E7F0003C1B80083C010800AC2000203042FFF0A8 +:10E80000384200102C4200010E001B85AF82001818 +:10E810003C04FFFF3C020400348308063442000C31 +:10E82000AE021948AE03194C3C0560168E021980E1 +:10E830008CA300003442020000641824AE02198048 +:10E840003C0253531462000334A47C008CA20004E5 +:10E85000005020218C82007C8C830078AF820010D5 +:10E86000AF83000C8F55000032A200031040FFFD63 +:10E8700032A200011040013D32A200028F42012865 +:10E88000AF4200208F4201048F430100AF8200009D +:10E890000E000F3CAF8300043C0208008C4200C015 +:10E8A000104000088F8400003C0208008C4200C425 +:10E8B000244200013C010800AC2200C40A00126995 +:10E8C000000000003C020010008210241440010CE3 +:10E8D0008F8300043C0208008C4200203C030800A7 +:10E8E0008C63003800008821244200013C010800AC +:10E8F000AC2200203C16080026D600381460000226 +:10E900002474FFFF0000A0219742010E30834000D5 +:10E910003042FFFF1060000A245200043C02002035 +:10E920000082102450400007308280008F82000453 +:10E930002403BFFF008318240A0011703442100022 +:10E94000308280001040000A3C0200200082102427 +:10E95000104000078F8200043C03FFFF34637FFFF9 +:10E960000083182434428000AF820004AF8300008B +:10E970000E000F9800000000144000070000000087 +:10E980009743011E9742011C3063FFFF00021400F1 +:10E9900000621825AF8300089742010C8F434000A6 +:10E9A0003045FFFF3402FFFF146200030000000047 +:10E9B0000A001188241100208F42400030420100DB +:10E9C00054400001241100108F8400003082100098 +:10E9D0005040001436310001308200201440000BFA +:10E9E0003C021000008210245040000E363100011D +:10E9F0003C030E003C020DFF008318243442FFFF4D +:10EA00000043102B50400007363100013C02080043 +:10EA10008C42002C244200013C010800AC22002C56 +:10EA2000363100053C0608008CC6003454C0002373 +:10EA30008F8500008F820004304240005440001F48 +:10EA40008F8500003C021F01008210243C0310004F +:10EA50005443001A8F85000030A2020014400017B2 +:10EA60008F8500003250FFFF363100028F4201B81F +:10EA70000440FFFE00000000AF40018002002021A2 +:10EA80000E000F42AF4000208F8300042402BFFF1E +:10EA9000A750019A006218248F820000A750018EAF +:10EAA000A7510188A74301A6A74201903C0210008C +:10EAB000AF4201B80A001267000010213C021000AA +:10EAC00000A210241040003A0000000010C0000F07 +:10EAD0000000000030A201001040000C3C030200C6 +:10EAE0003C020F0000A210241043000800000000A8 +:10EAF0008F82000800541024005610219042000418 +:10EB0000244200040A0011FF000221C0000000009E +:10EB1000000516023050000F3A0300022E4203EFA8 +:10EB2000384200012C630001006218241460008543 +:10EB3000240200013C0308008C6300D02E06000C68 +:10EB4000386200012C4200010046102414400015D8 +:10EB5000001021C02602FFFC2C420004544000118A +:10EB600000002021386200022C42000100461024DF +:10EB700050400003000512420A0011FF000020214E +:10EB80000010182B0043102450400006001021C034 +:10EB9000000020213245FFFF0E000F633226FFFBED +:10EBA000001021C03245FFFF0A0012523626000233 +:10EBB0008F4240003C0308008C6300243042010077 +:10EBC0001040004630620001322200043070000D17 +:10EBD000144000022413000424130002000512C292 +:10EBE000384200012E4303EF304200013863000138 +:10EBF00000431025104000033231FFFB2402FFFBCD +:10EC00000202802410C000183202000130A201006C +:10EC100010400015320200013C020F0000A2102437 +:10EC20003C0302001043000F8F8200082403FFFE04 +:10EC30000203802400541024005610219042000446 +:10EC4000023330252442000412000002000221C0D9 +:10EC50003226FFFF0E000F633245FFFF120000391E +:10EC600000001021320200011040000D32020004A9 +:10EC70002402000112020002023330253226FFFF77 +:10EC8000000020210E000F633245FFFF2402FFFE2B +:10EC9000020280241200002B000010213202000426 +:10ECA0001040002824020001240200041202000285 +:10ECB000023330253226FFFF3245FFFF0E000F637F +:10ECC000240401002402FFFB020280241200001D24 +:10ECD000000010210A0012672402000150400019B0 +:10ECE000000010213245FFFF3626000200002021DF +:10ECF0000E000F63000000000A00126700001021E0 +:10ED00002402BFFF00621024104000080000000031 +:10ED1000240287FF00621024144000083C020060B7 +:10ED20000082102410400005000000000E000D3489 +:10ED3000000000000A001267000000000E0012C769 +:10ED400000000000104000063C0240008F430124F8 +:10ED50003C026020AC430014000000003C02400074 +:10ED6000AF4201380000000032A200021040FEBD98 +:10ED7000000000008F4201403C044000AF420020F0 +:10ED80008F4301483C027000006218241064004266 +:10ED9000000000000083102B144000063C026000BD +:10EDA0003C022000106200073C0240000A0012C32F +:10EDB000000000001062003C3C0240000A0012C348 +:10EDC000000000008F4501408F4601448F420148FA +:10EDD00000021402304300FF240200041462000AFF +:10EDE000274401808F4201B80440FFFE2402001C2A +:10EDF000AC850000A082000B3C021000AF4201B8BD +:10EE00000A0012C33C0240002402000914620012EE +:10EE100000061602000229C0AF4500208F4201B84B +:10EE20000440FFFE2402000124030003AF450180DB +:10EE3000A343018BA740018EA740019AA7400190F0 +:10EE4000AF4001A8A7420188A74201A6AF4001AC8C +:10EE50003C021000AF4201B88F4201B80440FFFEEF +:10EE600000000000AC8500008F420148000214023F +:10EE7000A482000824020002A082000B8F420148F5 +:10EE8000A48200103C021000AC860024AF4201B8FE +:10EE90000A0012C33C0240000E00131000000000E4 +:10EEA0000A0012C33C0240000E001BBA0000000022 +:10EEB0003C024000AF420178000000000A00112F20 +:10EEC000000000008F4201003042003E144000115B +:10EED00024020001AF4000488F420100304207C0C9 +:10EEE0001040000500000000AF40004CAF40005053 +:10EEF00003E0000824020001AF400054AF4000408E +:10EF00008F4201003042380054400001AF400044BD +:10EF10002402000103E00008000000008F4201B855 +:10EF20000440FFFE24020001AF440180AF40018491 +:10EF3000A7450188A342018A24020002A342018B53 +:10EF40009742014A14C00004A7420190AF4001A4B7 +:10EF50000A0012EF3C0210008F420144AF4201A4AC +:10EF60003C021000AF4001A803E00008AF4201B826 +:10EF70008F4201B80440FFFE24020002AF4401802A +:10EF8000AF440184A7450188A342018AA342018BB3 +:10EF90009742014AA7420190AF4001A48F42014429 +:10EFA000AF4201A83C02100003E00008AF4201B8E4 +:10EFB0003C0290003442000100822025AF44002032 +:10EFC0008F4200200440FFFE0000000003E0000824 +:10EFD000000000003C028000344200010082202535 +:10EFE00003E00008AF44002027BDFFE8AFBF0014D6 +:10EFF000AFB000108F500140934301499342014844 +:10F0000093440148306300FF304200FF00021200C9 +:10F0100000622825240200191062007630840080E6 +:10F020002862001A1040001C24020020240200085C +:10F0300010620077286200091040000E2402000BC5 +:10F0400024020001106200342862000250400005D2 +:10F050002402000650600034020020210A00139AA6 +:10F060000000000010620030020020210A00139A04 +:10F07000000000001062003B2862000C50400002BB +:10F080002402000E24020009106200560200202112 +:10F090000A00139A00000000106200562862002146 +:10F0A0001040000F240200382402001C1062005897 +:10F0B0002862001D104000062402001F2402001BCD +:10F0C0001062004C000000000A00139A00000000CB +:10F0D0001062004A020020210A00139A000000007A +:10F0E00010620045286200391040000724020080A9 +:10F0F0002462FFCB2C420002104000450200202178 +:10F100000A00139600003021106200090000000080 +:10F110000A00139A000000001480003D0200202124 +:10F120000A0013908FBF00140A00139624060001F2 +:10F130008F4201B80440FFFE24020002A342018B6B +:10F14000A74501889742014AA74201908F42014496 +:10F15000A74201923C021000AF4201B80A00139C82 +:10F160008FBF00149742014A14400029000000009C +:10F1700093620005304200041440002500000000A6 +:10F180000E001302020020219362000502002021DC +:10F19000344200040E00130BA362000593620005C5 +:10F1A0003042000414400002000000000000000D86 +:10F1B0009362000024030020304200FF1443001437 +:10F1C000000000008F4201B80440FFFE2402000549 +:10F1D000AF500180A342018B3C0210000A00139A39 +:10F1E000AF4201B88FBF00148FB000100A0012F2B6 +:10F1F00027BD00180000000D020020210000302172 +:10F200008FBF00148FB000100A0012DD27BD001858 +:10F210000000000D8FBF00148FB0001003E0000845 +:10F2200027BD001827BDFFE8AFBF00100E000F3C40 +:10F2300000000000AF4001808FBF001000002021BF +:10F240000A000FE727BD00183084FFFF30A5FFFF3D +:10F25000000018211080000700000000308200012B +:10F260001040000200042042006518210A0013AB80 +:10F270000005284003E000080060102110C00006CF +:10F2800024C6FFFF8CA2000024A50004AC8200006D +:10F290000A0013B52484000403E000080000000005 +:10F2A00010A0000824A3FFFFAC86000000000000AF +:10F2B000000000002402FFFF2463FFFF1462FFFA36 +:10F2C0002484000403E0000800000000308300FFF5 +:10F2D00030A500FF30C600FF274701808F4201B8EC +:10F2E0000440FFFE000000008F420128346340000C +:10F2F000ACE2000024020001ACE00004A4E300083A +:10F30000A0E2000A24020002A0E2000B3C0210006E +:10F31000A4E50010ACE00024ACE00028A4E6001254 +:10F3200003E00008AF4201B827BDFFE8AFBF0010FF +:10F330009362003F24030012304200FF1043000D8F +:10F34000008030218F620044008210230440000AB4 +:10F350008FBF00108F62004824040039000028216C +:10F3600000C2102304410004240600120E0013C939 +:10F37000000000008FBF00102402000103E000081D +:10F3800027BD001827BDFFC8AFB20030AFB1002CB9 +:10F39000AFBF0034AFB0002890C5000D00809021B1 +:10F3A00030A400101080000B00C088218CC300081E +:10F3B0008F6200541062000730A20005144000B5AF +:10F3C000240400010E000D21000020210A0014BBBE +:10F3D0000040202130A200051040000930A3001297 +:10F3E000108000AC240400018E2300088F620054BA +:10F3F000146200A98FBF00340A00142C24040038C2 +:10F4000024020012146200A324040001022020211F +:10F4100027A500100E000CB2AFA000101040001184 +:10F42000024020218E220008AF620084AF600040BD +:10F430000E001302000000009362007D02402021B4 +:10F44000344200200E00130BA362007D0E000CA9B5 +:10F4500002402021240400382405008D0A0014B83D +:10F46000240600129362003E304200081040000F54 +:10F470008FA2001030420100104000078FA300143B +:10F480008F6200600062102304430008AF630060D5 +:10F490000A00144100000000AF6000609362003E6B +:10F4A0002403FFF700431024A362003E9362003E52 +:10F4B00030420008144000022406000300003021FE +:10F4C00093620034936300378F640084304200FFFE +:10F4D000306300FF006618210003188000432821D4 +:10F4E00000A4202B1080000B000000009763003C5C +:10F4F0008F6200843063FFFF004510230062182BE9 +:10F5000014600004000000008F6200840A00145D93 +:10F51000004580239762003C3050FFFF8FA300100E +:10F520003062000410400004000628808FA2001CF6 +:10F530000A0014650202102B2E020218504000032C +:10F54000240202180A00146E02051023306300041E +:10F5500010600003004510238FA2001C00451023FB +:10F56000004080212C420080544000012410008083 +:10F570000E0013020240202124020001AF62000CA1 +:10F580009362003E001020403042007FA362003EA4 +:10F590008E22000424420001AF620040A770003CAC +:10F5A0008F6200509623000E00431021AF62005876 +:10F5B0008F62005000441021AF62005C8E22000474 +:10F5C000AF6200188E220008AF62001C8FA20010EC +:10F5D000304200085440000A93A20020A360003685 +:10F5E000936200362403FFDFA36200359362003E7E +:10F5F00000431024A362003E0A0014988E220008E3 +:10F60000A36200358E220008AF62004C8F62002496 +:10F610008F63004000431021AF62004893620000F6 +:10F6200024030050304200FF144300122403FF80E3 +:10F630003C0208008C4231A00242102100431024F9 +:10F64000AF4200283C0208008C4231A08E24000802 +:10F650003C03000C024210213042007F0342102183 +:10F6600000431021AC4400D88E230008AF82001460 +:10F67000AC4300DC0E00130B0240202124040038B0 +:10F68000000028212406000A0E0013C90000000013 +:10F69000240400018FBF00348FB200308FB1002CE2 +:10F6A0008FB000280080102103E0000827BD00383B +:10F6B00027BDFFF827420180AFA20000308A00FF7B +:10F6C0008F4201B80440FFFE000000008F46012871 +:10F6D0003C0208008C4231A02403FF80AF86004822 +:10F6E00000C2102100431024AF4200243C02080055 +:10F6F0008C4231A08FA900008FA8000000C2102109 +:10F700003042007F034218213C02000A00621821A7 +:10F71000946400D48FA700008FA50000240200028B +:10F72000AF830014A0A2000B8FA30000354260003D +:10F730003084FFFFA4E200083C021000AD26000068 +:10F74000AD040004AC60002427BD0008AF4201B83E +:10F7500003E00008240200018F88003C9382002807 +:10F760008F8300143C07080024E7777800481023B3 +:10F77000304200FF304900FC246500888F8600403D +:10F78000304A0003112000090000202124820004D7 +:10F790008CA30000304400FF0089102AACE3000075 +:10F7A00024A500041440FFF924E7000411400009D7 +:10F7B000000020212482000190A30000304400FFBB +:10F7C000008A102BA0E3000024A500011440FFF9DB +:10F7D00024E7000130C20003144000048F85003C80 +:10F7E000310200031040000D0000000010A00009CD +:10F7F000000020212482000190C30000304400FF5B +:10F800000085102BA0E3000024C600011440FFF97E +:10F8100024E7000103E00008000000001100FFFDE4 +:10F8200000002021248200048CC30000304400FF2B +:10F830000088102BACE3000024C600041440FFF93C +:10F8400024E7000403E00008000000008F83003C70 +:10F850009382002830C600FF30A500FF004310232C +:10F86000304300FF8F8200140080382100431021B4 +:10F8700014C00002244800880083382130E20003CD +:10F880001440000530A2000314400003306200035E +:10F890001040000D0000000010A000090000202111 +:10F8A0002482000190E30000304400FF0085102B0B +:10F8B000A103000024E700011440FFF9250800011E +:10F8C00003E000080000000010A0FFFD0000202160 +:10F8D000248200048CE30000304400FF0085102BDC +:10F8E000AD03000024E700041440FFF925080004DC +:10F8F00003E00008000000000080482130AAFFFF5C +:10F9000030C600FF30E7FFFF274801808F4201B873 +:10F910000440FFFE8F820048AD0200008F420124A8 +:10F92000AD0200048D220020A5070008A102000AF4 +:10F9300024020016A102000B934301208D2200082F +:10F940008D240004306300FF004310219783003AA8 +:10F95000004410218D250024004310233C0308009F +:10F960008C6331A08F840014A502000C246300E88E +:10F970002402FFFFA50A000EA5030010A506001231 +:10F98000AD050018AD020024948201142403FFF792 +:10F990003042FFFFAD0200288C820118AD02002C1E +:10F9A0003C021000AD000030AF4201B88D220020B3 +:10F9B0000043102403E00008AD2200208F820014D1 +:10F9C00030E7FFFF00804821904200D330A5FFFFC1 +:10F9D00030C600FF0002110030420F0000E238255F +:10F9E000274801808F4201B80440FFFE8F82004803 +:10F9F000AD0200008F420124AD0200048D220020E0 +:10FA0000A5070008A102000A24020017A102000BAA +:10FA1000934301208D2200088D240004306300FFF1 +:10FA2000004310219783003A004410218F84001472 +:10FA3000004310233C0308008C6331A0A502000C96 +:10FA4000A505000E246300E8A5030010A50600121A +:10FA5000AD0000148D220024AD0200188C82005CE1 +:10FA6000AD02001C8C820058AD0200202402FFFF72 +:10FA7000AD020024948200E63042FFFFAD02002870 +:10FA800094820060948300BE30427FFF3063FFFFAA +:10FA90000002120000431021AD02002C3C021000B5 +:10FAA000AD000030AF4201B8948200BE2403FFF7DE +:10FAB00000A21021A48200BE8D2200200043102449 +:10FAC00003E00008AD220020274301808F4201B8E7 +:10FAD0000440FFFE8F8200249442001C3042FFFF4E +:10FAE000000211C0AC62000024020019A062000BE9 +:10FAF0003C021000AC60003003E00008AF4201B8E7 +:10FB00008F87002C30C300FF8F4201B80440FFFEF6 +:10FB10008F82004834636000ACA2000093820044EE +:10FB2000A0A200058CE20010A4A20006A4A3000875 +:10FB30008C8200202403FFF7A0A2000A2402000206 +:10FB4000A0A2000B8CE20000ACA200108CE200042A +:10FB5000ACA200148CE2001CACA200248CE20020B9 +:10FB6000ACA200288CE2002CACA2002C8C820024D9 +:10FB7000ACA200183C021000AF4201B88C820020F9 +:10FB80000043102403E00008AC8200208F8600149C +:10FB900027BDFFE8AFBF0014AFB0001090C20063F4 +:10FBA000304200201040000830A500FF8CC2007CCD +:10FBB0002403FFDF24420001ACC2007C90C200633A +:10FBC00000431024A0C2006310A000238F83001400 +:10FBD00027500180020028210E0015D6240600823D +:10FBE0008F82001490420063304200405040001960 +:10FBF000A38000448F83002C8F4201B80440FFFE95 +:10FC00008F820048AE02000024026082A602000833 +:10FC100024020002A202000B8C620008AE02001057 +:10FC20008C62000CAE0200148C620014AE0200184C +:10FC30008C620018AE0200248C620024AE02002800 +:10FC40008C620028AE02002C3C021000AF4201B8CA +:10FC5000A38000448F8300148FBF00148FB0001066 +:10FC60009062006327BD00183042007FA0620063ED +:10FC70009782003A8F86003C8F850014938300287A +:10FC800000461023A782003AA4A000E490A40063D9 +:10FC90008F820040AF83003C2403FFBF0046102149 +:10FCA00000832024AF820040A0A400638F82001450 +:10FCB000A04000BD8F82001403E00008A44000BEF5 +:10FCC0008F8A001427BDFFE0AFB10014AFB0001061 +:10FCD0008F88003CAFBF00189389001C954200E458 +:10FCE00030D100FF0109182B0080802130AC00FFCB +:10FCF0003047FFFF0000582114600003310600FF69 +:10FD000001203021010958239783003A0068102B05 +:10FD10001440003C000000001468000724020001A9 +:10FD20008E0200202403FFFB34E7800000431024F0 +:10FD3000AE0200202402000134E70880158200058D +:10FD40003165FFFF0E001554020020210A001691B4 +:10FD5000020020210E001585020020218F8400481A +:10FD6000274301808F4201B80440FFFE240200189F +:10FD7000AC640000A062000B8F840014948200E643 +:10FD8000A46200103C021000AC600030AF4201B829 +:10FD90009482006024420001A4820060948200608A +:10FDA0003C0308008C63318830427FFF5443000FCE +:10FDB000020020219482006024038000004310246C +:10FDC000A48200609082006090830060304200FF57 +:10FDD000000211C200021027000211C03063007F30 +:10FDE00000621825A0830060020020210220282143 +:10FDF0008FBF00188FB100148FB000100A0015F9E2 +:10FE000027BD0020914200632403FF80004310259A +:10FE1000A14200639782003A3048FFFF11000020A2 +:10FE20009383001C8F840014004B1023304600FF86 +:10FE3000948300E42402EFFF0168282B0062182459 +:10FE4000A48300E414A000038E02002001005821C6 +:10FE5000000030212403FFFB34E78000004310241E +:10FE6000AE02002024020001158200053165FFFF6B +:10FE70000E001554020020210A0016B99783003A9B +:10FE80000E001585020020219783003A8F82003CE6 +:10FE9000A780003A00431023AF82003C9383001CEC +:10FEA0008F8200148FBF00188FB100148FB0001024 +:10FEB00027BD002003E00008A04300BD938200445A +:10FEC0002403000127BDFFE8004330042C4200203A +:10FED000AFB00010AFBF00142410FFFE10400005AB +:10FEE000274501803C0208008C4231900A0016D65A +:10FEF000004610243C0208008C4231940046102435 +:10FF000014400007240600848F8300142410FFFF90 +:10FF1000906200623042000F34420040A0620062F2 +:10FF20000E0015D600000000020010218FBF001443 +:10FF30008FB0001003E0000827BD00188F83002455 +:10FF400027BDFFE0AFB20018AFB10014AFB0001092 +:10FF5000AFBF001C9062000D00A0902130D100FFC7 +:10FF60003042007FA062000D8F8500148E43001880 +:10FF7000008080218CA2007C146200052402000E07 +:10FF800090A20063344200200A0016FFA0A2006382 +:10FF90000E0016C5A38200442403FFFF1043004750 +:10FFA0002404FFFF52200045000020218E43000062 +:10FFB0003C02001000621024504000043C02000883 +:10FFC000020020210A00170E2402001500621024EE +:10FFD000504000098E450000020020212402001438 +:10FFE0000E0016C5A38200442403FFFF1043003314 +:10FFF0002404FFFF8E4500003C02000200A21024F2 +:020000040001F9 +:10000000104000163C0200048F8600248CC20014AD +:100010008CC300108CC40014004310230044102B28 +:1000200050400005020020218E43002C8CC200109D +:1000300010620003020020210A00173F2402001270 +:100040003C02000400A210245040001C00002021AB +:10005000020020210A00173F2402001300A21024EE +:10006000104000068F8300248C6200105040001363 +:10007000000020210A001739020020218C620010A4 +:10008000504000048E42002C020020210A00173F3D +:10009000240200115040000900002021020020210C +:1000A000240200170E0016C5A38200442403FFFF9C +:1000B000104300022404FFFF000020218FBF001C1A +:1000C0008FB200188FB100148FB000100080102183 +:1000D00003E0000827BD00208F83001427BDFFD850 +:1000E000AFB40020AFB3001CAFB20018AFB1001422 +:1000F000AFB00010AFBF0024906200638F91002C5E +:100100002412FFFF3442004092250000A0620063E9 +:100110008E2200100080982130B0003F105200065F +:100120000360A0212402000D0E0016C5A382004426 +:10013000105200542404FFFF8F8300148E220018F5 +:100140008C63007C10430007026020212402000E13 +:100150000E0016C5A38200442403FFFF104300498C +:100160002404FFFF24040020120400048F830014E1 +:100170009062006334420020A06200638F850034E7 +:1001800010A0002000000000560400048F8200141C +:10019000026020210A0017902402000A9683000AB8 +:1001A000944200603042FFFF144300048F8200201D +:1001B0002404FFFD0A0017B7AF82003C3C02080090 +:1001C0008C42318C0045102B144000060260202127 +:1001D000000028210E001646240600010A0017B769 +:1001E000000020212402002D0E0016C5A382004429 +:1001F0002403FFFF104300232404FFFF0A0017B766 +:1002000000002021160400058F8400148E230014A2 +:100210002402FFFF506200180260202194820060D7 +:1002200024420001A4820060948200603C03080024 +:100230008C63318830427FFF5443000F02602021DD +:10024000948200602403800000431024A482006094 +:100250009082006090830060304200FF000211C273 +:1002600000021027000211C03063007F00621825D1 +:10027000A0830060026020210E0015F92405000112 +:10028000000020218FBF00248FB400208FB3001CFA +:100290008FB200188FB100148FB0001000801021B1 +:1002A00003E0000827BD00288F83001427BDFFE866 +:1002B000AFB00010AFBF0014906200638F87002CB6 +:1002C00000808021344200408CE60010A062006370 +:1002D0003C0308008C6331B030C23FFF0043102B59 +:1002E0001040004E8F8500302402FF8090A3000D47 +:1002F00000431024304200FF5040004902002021FA +:100300000006138230480003240200025502004414 +:100310000200202194A2001C8F85001424030023D6 +:10032000A4A201148CE60000000616023042003F31 +:10033000104300103C0300838CE300188CA2007C67 +:10034000106200062402000E0E0016C5A3820044AF +:100350002403FFFF104300382404FFFF8F830014A1 +:100360009062006334420020A06200630A0017FC20 +:100370008F83002400C31024144300078F830024BC +:1003800090A200623042000F34420020A0A200621E +:10039000A38800388F8300249062000D3042007FD4 +:1003A000A062000D8F83003410600018020020212D +:1003B0008F8400308C8200100043102B1040000905 +:1003C00024020018020020210E0016C5A38200445A +:1003D0002403FFFF104300182404FFFF0A00182421 +:1003E000000020218C820010240500010200202141 +:1003F000004310238F830024240600010E001646BC +:10040000AC6200100A001824000020210E0015F92B +:10041000240500010A0018240000202102002021E8 +:100420002402000D8FBF00148FB0001027BD0018EC +:100430000A0016C5A38200448FBF00148FB00010BD +:100440000080102103E0000827BD001827BDFFC869 +:10045000AFB20020AFBF0034AFB60030AFB5002C54 +:10046000AFB40028AFB30024AFB1001CAFB0001888 +:100470008F4601283C0308008C6331A02402FF80D2 +:10048000AF86004800C318213065007F034528214E +:10049000006218243C02000AAF43002400A2282175 +:1004A00090A2006200809021AF850014304200FFCE +:1004B00000021102A382003890A200BC3042000268 +:1004C0001440000224030034240300308F820014FF +:1004D000A3830028938300388C4200C0A38000448B +:1004E000AF82003C24020004106203148F84003C9D +:1004F0008E440004508003118F84003C8E42001013 +:100500003083FFFFA784003A106002F7AF820040FB +:100510008F8400142403FF80908200630062102403 +:10052000304200FF144002C79785003A9383003899 +:100530002402000230B6FFFF14620005000088218B +:10054000938200282403FFFD0A001B11AF82003CA8 +:100550008F82003C02C2102B144002998F8400400D +:100560000E0014EC00000000938300283C040800F7 +:1005700024847778240200341462002EAF84002C87 +:100580003C0A08008D4A77A82402FFFFAFA20010A2 +:10059000008038212405002F3C09080025297378A4 +:1005A000240800FF2406FFFF90E2000024A3FFFFC1 +:1005B0000006220200C21026304200FF0002108016 +:1005C000004910218C420000306500FF24E7000143 +:1005D00014A8FFF50082302600061027AFA20014F1 +:1005E000AFA200100000282127A7001027A60014A2 +:1005F00000C510239044000324A2000100A7182185 +:10060000304500FF2CA200041440FFF9A064000054 +:100610008FA2001011420007240200050240202191 +:100620000E0016C5A38200442403FFFF104300649C +:100630002404FFFF3C0208009042777C1040000930 +:100640008F820014024020212402000C0E0016C5E7 +:10065000A38200442403FFFF104300592404FFFF3A +:100660008F820014A380001C3C0308008C63777CFD +:100670008C4400803C0200FF3442FFFF00621824DB +:100680000083202B10800008AF830034024020211B +:10069000240200190E0016C5A38200442403FFFFA4 +:1006A000104300472404FFFF8F87003C9782003AE5 +:1006B0008F850034AF8700200047202310A0003B27 +:1006C000A784003A8F86001430A200030002102392 +:1006D00090C300BC3050000300B0282100031882F2 +:1006E000307300010013108000A228213C03080091 +:1006F0008C6331A08F8200483084FFFF0085202B5F +:100700000043102110800011244200888F84002CA7 +:100710001082000E3C033F013C0208008C427778B7 +:10072000004310243C0325001443000630E500FF7D +:100730008C820000ACC200888C8200100A0018E98C +:10074000ACC200980E001529000030219382001CD5 +:100750008F8500148F830040020238218F82003C75 +:10076000A387001C94A400E4006218218F82003447 +:1007700034841000AF83004000503021A4A400E472 +:100780001260000EAF86003C24E20004A382001C2D +:1007900094A200E424C30004AF83003C3442200050 +:1007A000A4A200E40A001906000020218F82004064 +:1007B000AF80003C00471021AF82004000002021A4 +:1007C0002414FFFF109402092403FFFF3C080800D3 +:1007D0008D0877883C0208008C4231B03C03080049 +:1007E0009063777831043FFF0082102B1040001B8C +:1007F0003067003F3C0208008C4231A88F830048DC +:100800000004218000621821006418213062007FFA +:10081000034228213C02000C00A228213C02008057 +:10082000344200013066007800C230252402FF8087 +:1008300000621024AF42002830640007AF42080471 +:100840008F8200140344202124840940AF460814F9 +:10085000AF850024AF840030AC4301189383003887 +:1008600024020003146201C72402000124020026AE +:1008700010E201C928E200271040001324020032D0 +:100880002402002210E201C428E2002310400008E4 +:10089000240200242402002010E201B024020021DE +:1008A00010E2013F024020210A001AF32402000B4B +:1008B00010E201B92402002510E2001002402021BC +:1008C0000A001AF32402000B10E201A628E200330A +:1008D000104000062402003F2402003110E2009282 +:1008E000024020210A001AF32402000B10E2019DAD +:1008F000024020210A001AF32402000B8F90002CE2 +:100900003C0308008C6331B08F8500308E040010EA +:100910000000A8218CB3001430823FFF0043102B4D +:100920008CB10020504001870240202190A3000D8F +:100930002402FF8000431024304200FF5040018118 +:100940000240202100041382304200031440017D44 +:100950000240202194A3001C8F8200148E040028E2 +:10096000A44301148CA20010026218231064000337 +:10097000024020210A00197C2402001F8F820034CB +:10098000006210210262102B104000088F830024A7 +:1009900002402021240200180E0016C5A382004444 +:1009A0001054016C2404FFFF8F8300248F840034D3 +:1009B0008C6200100224882100441023AC620010D5 +:1009C0008F820014AC7100208C4200680051102B03 +:1009D000104000098F830030024020212402001DB6 +:1009E0000E0016C5A38200442403FFFF10430159E3 +:1009F0002404FFFF8F8300308E0200248C630024C8 +:100A000010430007024020212402001C0E0016C5DE +:100A1000A38200442403FFFF1043014E2404FFFF80 +:100A20008F8400248C82002424420001AC820024A4 +:100A3000123300048F8200148C4200685622000E8C +:100A40008E0200008E0200003C0300800043102450 +:100A50001440000D2402001A024020210E0016C589 +:100A6000A38200442403FFFF1043013A2404FFFF44 +:100A70000A0019BA8E0200143C03008000431024BF +:100A8000504000038E020014AC8000208E0200143F +:100A90002411FFFF105100062402001B02402021F8 +:100AA0000E0016C5A38200441051012A2404FFFF42 +:100AB0008E0300003C02000100621024104000126E +:100AC0003C020080006210241440000802402021F3 +:100AD0002402001A0E0016C5A38200442403FFFF5F +:100AE0001043011C2404FFFF0240202102002821A2 +:100AF0000E0016E5240600012403FFFF1043011534 +:100B00002404FFFF241500018F83002402A030215C +:100B10000240202194620036240500012442000195 +:100B20000A001AD7A46200368F90002C3C030800FC +:100B30008C6331B08E13001032623FFF0043102BE4 +:100B4000104000898F8400302402FF809083000DC4 +:100B500000431024304200FF104000842402000DA6 +:100B60000013138230420003240300011443007F6A +:100B70002402000D9082000D304200085440000411 +:100B80008F820034024020210A001A082402002427 +:100B9000504000048E03000C024020210A001A0875 +:100BA000240200278C82002054620006024020218B +:100BB0008E0300088C820024506200098E0200140B +:100BC00002402021240200200E0016C5A38200440A +:100BD000105400712403FFFF0A001A3D8F84002483 +:100BE0002411FFFF145100048F86001402402021BD +:100BF0000A001A38240200258E0300188CC2007CDB +:100C0000106200032402000E0A001A38024020215C +:100C10008E0300248C82002810620003240200212D +:100C20000A001A38024020218E0500288C82002CF0 +:100C300010A200032402001F0A001A3802402021DB +:100C40008E03002C14600003240200230A001A38CB +:100C5000024020218CC200680043102B104000038A +:100C6000240200260A001A38024020218C82001437 +:100C7000006518210043102B104000088F840024C9 +:100C800002402021240200220E0016C5A382004447 +:100C9000105100412403FFFF8F8400242403FFF739 +:100CA0009082000D00431024A082000D8F86001456 +:100CB0003C0308008C6331AC8F82004894C400E090 +:100CC0008F8500240043102130847FFF00042040E2 +:100CD000004410213043007F034320213C03000ED9 +:100CE000008320212403FF8000431024AF42002C06 +:100CF000A49300008CA2002824420001ACA200288A +:100D00008CA2002C8E03002C00431021ACA2002CDE +:100D10008E02002CACA200308E020014ACA2003473 +:100D200094A2003A24420001A4A2003A94C600E032 +:100D30003C0208008C4231B024C4000130837FFFA4 +:100D40001462000F008030212402800000823024D1 +:100D500030C2FFFF000213C2304200FF0002102722 +:100D60000A001A76000233C02402000D024020213E +:100D70000E0016C5A38200440A001A7C0040182108 +:100D80008F82001402402021240500010E0015F975 +:100D9000A44600E0000018210A001B0E0060882114 +:100DA0008F90002C3C0308008C6331B08E0500103E +:100DB00030A23FFF0043102B104000612402FF804F +:100DC0008F8400309083000D00431024304200FFD8 +:100DD0005040005C024020218F8200341040000B04 +:100DE000000513828F8200149763000A944200600A +:100DF0003042FFFF14430005000513828F8200205C +:100E00002404FFFD0A001AEBAF82003C30420003CD +:100E10001440000E00000000920200021040000585 +:100E20008E03002450600015920300030A001AA7E5 +:100E3000024020218C8200245062001092030003A3 +:100E4000024020210A001AAF2402000F9082000DF8 +:100E50003042000854400009920300030240202160 +:100E6000240200100E0016C5A38200442403FFFFD5 +:100E7000104300382404FFFF920300032402000201 +:100E80005462000C920200038F8200345440000927 +:100E900092020003024020212402002C0E0016C5FD +:100EA000A38200442403FFFF1043002A2404FFFF11 +:100EB000920200030200282102402021384600103F +:100EC0002CC600012C4200010E0016E5004630251C +:100ED0002410FFFF1050001F2404FFFF8F830034F5 +:100EE00010600013024020213C0208008C42318C2B +:100EF0000043102B144000070000000000002821D0 +:100F0000240600010E001646000000000A001AEB3D +:100F1000000020212402002D0E0016C5A3820044EB +:100F20001050000C2404FFFF0A001AEB00002021DF +:100F30000E0015F9240500010A001AEB000020211B +:100F4000024020212402000D0E0016C5A382004499 +:100F5000004020210A001B0E008088211514000E7D +:100F6000000000000E00174C024020210A001B0E5A +:100F7000004088210E0016C5A38200440A001B0E03 +:100F80000040882114620017022018212402002347 +:100F900014E200052402000B0E0017C002402021BD +:100FA0000A001B0E0040882102402021A382004439 +:100FB0000E0016C52411FFFF0A001B0F0220182186 +:100FC00030A500FF0E001529240600019783003A82 +:100FD0008F82003CA780003A00431023AF82003C80 +:100FE000022018211220003E9782003A2402FFFDC1 +:100FF0005462003E8E4300208E4200048F83001412 +:1010000000561023AE420004906200633042007F1D +:10101000A06200638E4200208F840014A780003AF3 +:1010200034420002AE420020A48000E490820063BB +:101030002403FFBF00431024A08200630A001B5159 +:101040008E4300209082006300621024304200FF33 +:10105000104000239782003A90820088908300BD60 +:10106000248500883042003F2444FFE02C82002089 +:10107000A383001C10400019AF85002C240200013E +:1010800000821804306200191440000C3C028000F9 +:1010900034420002006210241440000B3062002031 +:1010A0001040000F9782003A90A6000102402021D4 +:1010B000240500010A001B4B30C60001024020211C +:1010C0000A001B4A240500010240202100002821BB +:1010D000240600010E001646000000009782003A28 +:1010E0001440FD0C8F8400148E43002030620004F5 +:1010F000104000128F84003C2402FFFB0062102489 +:10110000AE420020274301808F4201B80440FFFE19 +:101110008F820048AC6200008F420124AC62000460 +:1011200024026083A462000824020002A062000B73 +:101130003C021000AF4201B88F84003C8F83001442 +:101140008FBF00348FB600308FB5002C8FB40028CD +:101150008FB300248FB200208FB1001C8FB0001815 +:101160002402000127BD003803E00008AC6400C081 +:1011700030A500FF2403000124A900010069102B01 +:101180001040000C00004021240A000100A310239D +:10119000004A380424630001308200010069302BCA +:1011A00010400002000420420107402554C0FFF80F +:1011B00000A3102303E00008010010213C020800F6 +:1011C000244260A43C010800AC22736C3C0208007D +:1011D000244253083C010800AC227370240200062C +:1011E00027BDFFE03C010800A02273743C021EDC16 +:1011F000AFB20018AFB10014AFBF001CAFB0001009 +:1012000034526F4100008821240500080E001B7233 +:1012100002202021001180803C07080024E7737819 +:101220000002160002071821AC620000000028210D +:1012300024A200013045FFFF8C6200002CA60008AC +:1012400004410002000220400092202614C0FFF852 +:10125000AC640000020780218E0400000E001B72A7 +:1012600024050020262300013071FFFF2E230100FA +:101270001460FFE5AE0200008FBF001C8FB20018A3 +:101280008FB100148FB0001003E0000827BD0020CC +:1012900027BDFFD8AFB3001CAFB20018AFBF00200E +:1012A000AFB10014AFB000108F5101408F4801481A +:1012B00000089402324300FF311300FF8F4201B84F +:1012C0000440FFFE27500180AE1100008F42014410 +:1012D000AE02000424020002A6120008A202000BC3 +:1012E00024020014AE1300241062002528620015A9 +:1012F0001040000824020015240200101062003083 +:1013000024020012106200098FBF00200A001CADE9 +:101310008FB3001C1062007024020022106200379C +:101320008FBF00200A001CAD8FB3001C3C020800D8 +:101330008C4231A02403FF8002221021004310249C +:10134000AF4200243C0208008C4231A0022210214E +:101350003042007F034218213C02000A006218213B +:10136000166000BCAF830014906200623042000F30 +:1013700034420030A06200620A001CAC8FBF002023 +:101380003C0460008C832C083C02F0033442FFFFD5 +:1013900000621824AC832C083C0208008C4231A067 +:1013A0008C832C08244200740002108200021480F6 +:1013B00000621825AC832C080A001CAC8FBF0020EB +:1013C0003C0208008C4231A02403FF80022210213D +:1013D00000431024AF4200243C0208008C4231A09C +:1013E0003C03000A022210213042007F03421021F8 +:1013F000004310210A001CABAF8200143C0208001D +:101400008C4231A02405FF800222102100451024C7 +:10141000AF4200243C0208008C4231A0022210217D +:101420003042007F034218213C02000A006218216A +:101430009062006300A21024304200FF104000853B +:10144000AF83001424620088944300123C02080019 +:101450008C4231A830633FFF000319800222102123 +:10146000004310213043007F034320210045102416 +:101470003C03000C00832021AF4200289082000D25 +:1014800000A21024304200FF10400072AF840024FC +:101490009082000D304200101440006F8FBF00207A +:1014A0000E0015C8000000008F4201B80440FFFE86 +:1014B00000000000AE1100008F420144AE020004A3 +:1014C00024020002A6120008A202000BAE130024A0 +:1014D0000A001CAC8FBF00202406FF8002261024C7 +:1014E000AF4200203C0208008C4231A031043FFF93 +:1014F000000421800222102100461024AF42002463 +:101500003C0308008C6331A83C0208008C4231A0E7 +:101510003227007F022318210222102100641821A3 +:101520003042007F3064007F034228213C02000AE1 +:101530000066182400A22821034420213C02000C4C +:1015400000822021AF4300283C02000803471821F5 +:1015500000629021AF850014AF8400240E0015C8EE +:10156000010080218F4201B80440FFFE8F820024D9 +:101570008F840014274501809042000DACB100001B +:10158000A4B0000600021600000216030002102795 +:10159000000237C214C00016248200889442001250 +:1015A00032033FFF30423FFF1443001224026082A7 +:1015B000908300632402FF8000431024304200FF28 +:1015C0005040000C24026082908200623042000F82 +:1015D00034420040A082006224026084A4A2000879 +:1015E0002402000DA0A200050A001C963C02270060 +:1015F00024026082A4A20008A0A000053C022700EB +:1016000000061C000062182524020002A0A2000BA4 +:10161000ACA30010ACA00014ACA00024ACA0002827 +:10162000ACA0002C8E42004C8F840024ACA2001889 +:101630009083000D2402FF8000431024304200FFFD +:10164000104000058FBF00209082000D3042007FC7 +:10165000A082000D8FBF00208FB3001C8FB2001836 +:101660008FB100148FB000103C02100027BD00287D +:0816700003E00008AF4201B8DD +:08167800080034300800343092 +:10168000080033A8080033E0080034140800343898 +:0C16900008003438080034380800331813 +:04169C000A0001241B +:1016A00000000000000000000000000D74706136B2 +:1016B0002E302E313500000006000F010000000022 +:1016C000000000000000000000000000000000001A +:1016D000000000000000000000000000000000000A +:1016E00000000000000000000000000000000000FA +:1016F00000000000000000000000000000000000EA +:1017000000000000000000000000000000000000D9 +:1017100000000000000000000000000000000000C9 +:1017200000000000000000000000000000000000B9 +:1017300010000003000000000000000D0000000D7C +:101740003C02080024421C003C030800246320944F +:10175000AC4000000043202B1480FFFD2442000415 +:101760003C1D080037BD2FFC03A0F0213C100800F1 +:10177000261004903C1C0800279C1C000E00015CF5 +:10178000000000000000000D3084FFFF30820007E1 +:101790008F85001810400002248300073064FFF892 +:1017A0000085302130C41FFF03441821247B4000F2 +:1017B000AF85001CAF84001803E00008AF4400842C +:1017C0003084FFFF308200078F8500208F8600283D +:1017D00010400002248300073064FFF800852021B8 +:1017E0000086182B14600002AF8500240086202399 +:1017F0000344282134068000AF840020AF440080D9 +:1018000000A6202103E00008AF84003827BDFFD8E0 +:10181000AFB3001CAFB20018AFB00010AFBF0024D0 +:10182000AFB40020AFB100143C0860088D14500024 +:101830002418FF7F3C1A8000029898243672380CD6 +:10184000AD1250008F5100083C07601C3C0860003E +:1018500036300001AF500008AF800018AF40008064 +:10186000AF4000848CE600088D0F08083C07601626 +:101870008CEC000031EEFFF039CA00103C0DFFFF88 +:10188000340B80003C030080034B48212D440001B1 +:10189000018D28243C0253533C010800AC23042052 +:1018A000AF890038AF860028AF840010275B400066 +:1018B00014A2000334E37C008CF9000403281821EF +:1018C0008C7F007C8C6500783C0280003C0B08001B +:1018D0008D6B048C3C0A08008D4A048834520070D9 +:1018E000AF85003CAF9F00403C13080026731C44AA +:1018F0000240A0218E4800008F46000038C300013E +:101900003064000110800017AF8800340280482145 +:101910008D2F00003C0508008CA5045C3C180800D5 +:101920008F18045801E8102300A280210000C8216C +:101930000202402B03198821022838213C010800AB +:10194000AC30045C3C010800AC2704588F4E00000A +:1019500039CD000131AC00011580FFED01E04021DF +:10196000AF8F00348E5100003C0708008CE7045C08 +:101970003C0D08008DAD04580228802300F0602142 +:10198000000070210190302B01AE1821006620214B +:101990003C010800AC2C045C3C010800AC24045859 +:1019A0008F4601088F47010030C92000AF86000034 +:1019B000AF87000C1120000A00C040213C1808002D +:1019C0008F18042C270800013C010800AC28042CC7 +:1019D0003C184000AF5801380A0001960000000092 +:1019E0009749010400002821014550213122FFFFC1 +:1019F000016258210162F82B015F502130D90200A9 +:101A00003C010800AC2B048C3C010800AC2A048883 +:101A10001720001524040F0010E40013000000003C +:101A200024080D0010E8023B30CD000611A0FFE9AC +:101A30003C184000936E00002409001031C400F0EF +:101A40001089027124020070108202E58F88001450 +:101A5000250F0001AF8F00143C184000AF5801382B +:101A60000A00019600000000974C01041180FFD984 +:101A70003C18400030C34000146000A1000000008A +:101A80008F46017804C0FFFE8F87003824100800BD +:101A9000240F00088CE30008AF500178A74F0140E5 +:101AA000A7400142974E01048F86000031C9FFFF15 +:101AB00030CD000111A002E1012040212531FFFEBF +:101AC00024180002A75801463228FFFFA7510148F9 +:101AD0003C1908008F39043C172002D08F8C000C71 +:101AE00030DF002017E00002240400092404000174 +:101AF00030C20C0024050400504500013484000469 +:101B0000A744014A3C1108008E3104203C180048CB +:101B10003C1000010238182530CF00020070282543 +:101B200011E00004000018213C19010000B928252B +:101B30002403000130DF000453E00005AF830008F8 +:101B40003C06001000A6282524030001AF830008EE +:101B5000AF45100000000000000000000000000081 +:101B6000000000008F8300081060002300000000C8 +:101B70008F45100004A1FFFE000000001060001E51 +:101B8000000000008F4410003C0C0020008C10244A +:101B9000104000198F8E000031CD000211A00016F8 +:101BA00000000000974F101415E000130000000023 +:101BB000975910083338FFFF2711000600111882CB +:101BC0000003308000C72821323000013223000397 +:101BD0001200032C8CA200000000000D00C7F821A9 +:101BE000AFE200003C0508008CA5043024A60001EB +:101BF0003C010800AC2604308F6D00003402FFFF6A +:101C0000AF8D00048CEC0000118202A600002021A0 +:101C10008CED000031AC01001180028A0000000050 +:101C20003C0208008C4204743C0308008C63044CA2 +:101C30003C1F08008FFF04703C1808008F180448F0 +:101C4000004838210068802100E8282B03E4302177 +:101C50000208402B0304882100C570210228782146 +:101C60003C010800AC30044C3C010800AC2F044897 +:101C70003C010800AC2704743C010800AC2E047041 +:101C80008F8400180120302131290007249F00088B +:101C900033F91FFF03594021AF84001CAF9900188E +:101CA000251B4000AF590084112000038F830020C2 +:101CB00024C200073046FFF88F84002800C3282183 +:101CC00000A4302B14C00002AF83002400A42823FA +:101CD00003456021340D8000018D10213C0F100060 +:101CE000AF850020AF820038AF450080AF4F01784C +:101CF0008F880014250F00010A0001EFAF8F001438 +:101D00008F6200088F67000024050030000776020C +:101D100031C300F0106500A7240F0040546FFF4C42 +:101D20008F8800148F4B01780560FFFE00000000D3 +:101D300030CA020015400003000612820000000DA8 +:101D400000061282304D0003000D4900012D1821BC +:101D500000038080020D40210008608001938021F3 +:101D60008E1F000017E00002000000000000000DC0 +:101D70008F6E000405C202BD92070006920E000598 +:101D8000920200043C090001000E18800070F82146 +:101D90008FED0018277100082448000501A9602173 +:101DA00000083082AFEC0018022020210E00059EB2 +:101DB00026050014920A00068F7900043C0B7FFF71 +:101DC000000A2080009178218DF800043566FFFF1D +:101DD0000326282403053821ADE70004920E0005F0 +:101DE000920D0004960C0008000E10800051C821CE +:101DF0008F230000974901043C07FFFF0067582428 +:101E00003128FFFF010DF82103EC50233144FFFF7F +:101E100001643025AF26000092030007241800015A +:101E200010780275240F0003106F02850000000077 +:101E30008E0500102419000AA7590140A745014248 +:101E4000921800048F860000240F0001A758014457 +:101E5000A74001469747010430D100023C050041EC +:101E6000A747014800001821A74F014A122000038C +:101E700030CB00043C050141240300015160000502 +:101E8000AF8300083C06001000A6282524030001AB +:101E9000AF830008AF451000000000000000000004 +:101EA00000000000000000008F8A000811400004BC +:101EB000000000008F4410000481FFFE00000000BD +:101EC0008F6B0000920800043C1108008E3104441E +:101ED000AF8B000497590104311800FF3C0E080035 +:101EE0008DCE04403325FFFF0305382102276021F2 +:101EF00000001021250F000A31E8FFFF0187482B61 +:101F000001C2682101A9F821311000073C01080035 +:101F1000AC2C04443C010800AC3F04401200000318 +:101F20008F8C00182506000730C8FFF8010C6821C7 +:101F300031BF1FFFAF8C001CAF9F0018AF5F008444 +:101F400097440104035F80213084FFFF308A00073B +:101F500011400003261B4000248900073124FFF8AC +:101F60008F8200208F850028008220210085702B21 +:101F700015C00002AF820024008520233C0B08001E +:101F80008D6B048C3C0A08008D4A04880344882128 +:101F900034038000022310213C0F1000AF84002086 +:101FA000AF820038AF440080AF4F01780A0002963C +:101FB0008F8800148F5001780600FFFE30D1020098 +:101FC00016200003000612820000000D0006128297 +:101FD000305F0003001F1900007F302100062080C1 +:101FE000009FC82100194880013380218E1800000D +:101FF00013000002000000000000000D8F6C000CB8 +:10200000058001FB8F870038240E0001AE0E000012 +:102010008CE30008A20000078F650004000554024D +:10202000314D00FF25A80005000830822CCB00416F +:1020300015600002A20A00040000000D8F78000461 +:102040003C03FFFF00E02821330BFFFF256C000B52 +:10205000000C108200022080008748218D3F000084 +:1020600026040014A618000803E3C8240E00059EE9 +:10207000AD3900008F4F01083C11100001F13824E8 +:1020800010E001AB00000000974D0104920800072A +:1020900025AAFFEC350600023144FFFFA206000727 +:1020A000960600082CC7001354E0000592030007B1 +:1020B00092110007362F0001A20F000792030007BC +:1020C00024180001107801C224090003106901D509 +:1020D0008F88003830CBFFFF257100020011788314 +:1020E00031E400FF00042880A20F000500A8482169 +:1020F0008D2D0000974A01043C0EFFFF01AEF8242D +:102100003143FFFF006B1023244CFFFE03ECC82576 +:10211000AD390000920600053C03FFF63462FFFF74 +:1021200030D800FF0018388000F08821922F00146A +:102130003C04FF7F3487FFFF31EE000F01C65821BA +:10214000316500FF00055080015068218DAC0020F2 +:102150000148F821A20B00060182C824AE0C000C35 +:10216000AFF9000C920900068E11000C03277824A9 +:102170000009C0800310702195C60026030828219D +:1021800002272024AE04000CADCF0020ADC60024F1 +:10219000ACA600108F8800003C0B08008D6B048CEF +:1021A0003C0A08008D4A0488241F001024190002EC +:1021B000A75F0140A7400142A7400144A75901463B +:1021C0009749010424070001310600022538FFFE6B +:1021D000A75801483C050009A747014A10C0000361 +:1021E000000018213C05010924030001310C000402 +:1021F00051800005AF8300083C08001000A8282586 +:1022000024030001AF830008AF4510000000000068 +:102210000000000000000000000000009205000423 +:1022200024AE000231CD0007000D182330620007F4 +:10223000AE0200108F9000081200000400000000A1 +:102240008F4F100005E1FFFE000000008F710000BD +:102250008F8E00183C0308008C630444AF91000487 +:102260009745010425CF001031E61FFF30A2FFFF84 +:10227000AF8E001CAF860018AF4600842449FFFED5 +:102280003C0C08008D8C0440974D010401208021F6 +:10229000000947C30070C02131A9FFFF0310F82BCC +:1022A0000188C821033F202103463821313100072E +:1022B0003C010800AC3804443C010800AC24044054 +:1022C0001220000324FB40002527000730E9FFF817 +:1022D0008F8600208F8400280126382100E4C02B3F +:1022E00017000002AF86002400E4382303472021B2 +:1022F00034198000009910213C0F1000AF87002096 +:10230000AF820038AF470080AF4F01780A000296D5 +:102310008F8800149747010410E0FDAE3C18400080 +:102320008F5801780700FFFE30C5400010A0000361 +:102330003C1F00080000000D3C1F0008AF5F01407B +:10234000241008008F860000AF50017897440104E4 +:1023500030D90001132000ED3086FFFF24CCFFFEB2 +:10236000240D0002A74D0146A74C01488F9100188B +:102370002408000DA748014A8F630000262F00089B +:1023800031E21FFF0342702130C90007AF83000410 +:10239000AF91001CAF82001800C03821AF4200840A +:1023A0001120000325DB400024D800073307FFF885 +:1023B0008F8500208F84002800E5302100C4382B51 +:1023C00014E00002AF85002400C430238F84001481 +:1023D0000346F821340C8000AF86002003EC8021F6 +:1023E000AF460080249900013C0610003C184000D4 +:1023F000AF460178AF900038AF990014AF5801385C +:102400000A000196000000008F630000975101044C +:102410003067FFFF3228FFFF8F4F017805E0FFFE96 +:1024200030EC0007000CF82333F0000724F9FFFE1E +:102430002404000AA7440140A7500142A7590144BF +:10244000A7400146A74801488F45010830B8002041 +:1024500017000002240300092403000130CD00020C +:10246000A743014A3C04004111A0000300001821C9 +:102470003C0401412403000130C90004512000053F +:10248000AF8300083C0600100086202524030001CD +:10249000AF830008AF4410000000000000000000FF +:1024A00000000000000000008F8E000811C0000432 +:1024B000000000008F4210000441FFFE00000000F9 +:1024C0008F7F0000276400088F91003CAF9F0004BD +:1024D000948500089490000A9499000C30AFFFFF97 +:1024E0000010C4003323FFFF11F100A603032025D1 +:1024F0003C0E08008DCE04443C0C08008D8C04403A +:1025000000E888212626FFFE01C628210000682158 +:1025100000A6F82B018D2021009F80213C0108009E +:10252000AC2504443C010800AC30044024E200081F +:102530003042FFFF3047000710E000038F83001890 +:10254000244F000731E2FFF83106FFFF30C80007D3 +:102550000043802132191FFF0359C021AF83001CA3 +:10256000AF990018271B4000AF59008411000003E9 +:102570008F8C002024C5000730A6FFF88F84002828 +:1025800000CC282100A4F82B17E00002AF8C002417 +:1025900000A42823AF850020AF4500803C0408003C +:1025A0008C84043403454821340E8000012E6821B8 +:1025B00010800005AF8D0038939100172406000E9F +:1025C000122600112407043F3C021000AF4201789C +:1025D0008F880014250F00010A0001EFAF8F00144F +:1025E0000E0005C400E020218F8800143C0B080079 +:1025F0008D6B048C3C0A08008D4A0488250F00016D +:102600000A0001EFAF8F00143C021000A7470148F9 +:10261000AF4201780A0004CE8F88001424040F0012 +:102620001184003D30CE002015C0000224030009B3 +:10263000240300010A00021AA743014A0A00020DFE +:10264000A740014694EF000894F1000A94F0000CB2 +:102650008F8C003C001174003207FFFF31EDFFFF4B +:1026600011AC003701C720253C1808008F1804441E +:102670003C0F08008DEF0440000080210308682112 +:1026800001A8382B01F0702101C760213C0108002E +:10269000AC2D04443C010800AC2C04400A00027A32 +:1026A0008F8400183C0208008C42047C3C03080024 +:1026B0008C6304543C1F08008FFF04783C1808000A +:1026C0008F180450004838210068802100E8282B2A +:1026D00003E430210208402B0304882100C5702147 +:1026E000022878213C010800AC3004543C01080069 +:1026F000AC2F04503C010800AC27047C3C010800CE +:10270000AC2E04780A00027A8F840018A740014694 +:102710000A0004358F91001830CD002015A0FFC5A8 +:102720002403000D240300050A00021AA743014AEE +:10273000974E010425C5FFF00A00038130A4FFFF76 +:102740008F9800401498FFC8000010213C05080035 +:102750008CA5046C3C1F08008FFF046800A8C821EA +:102760000328302B03E22021008640213C01080091 +:10277000AC39046C3C010800AC2804680A00027AF9 +:102780008F8400188F8C0040148CFF5900E8C821FA +:102790003C1808008F18046C3C1108008E31046846 +:1027A0002723FFFE03034821000010210123302BC3 +:1027B0000222702101C668213C010800AC29046C8A +:1027C0003C010800AC2D04680A0004A524E20008BE +:1027D0008F8800383C03FFFF8D02000C0043F82473 +:1027E00003E4C825AD19000C0A00038F30CBFFFFAE +:1027F0000A0003C3AE000000974A010492040004DB +:102800008E26000C014458212579FFF200C7C02410 +:102810003325FFFF03053825AE27000C0A0002E62A +:102820008E0500103C0DFFFF8D0A0010014D58244D +:1028300001646025AD0C00100A00038F30CBFFFF50 +:1028400097430104920E00048E290010006E10219F +:10285000244DFFEE0127602431A8FFFF0188F825F1 +:10286000AE3F00100A0002E68E0500108E0F000C2D +:10287000AE00000000078880023028210A0002B85C +:10288000ACAF00201460000D3058FFFF3C04FFFF88 +:102890000044682401A47026000E602B000D102B4C +:1028A000004CF82413E00002000000000000000DBE +:1028B0008CAF00000A00025001E410253B03FFFF2B +:1028C0000003882B0018802B0211202410800002A6 +:1028D000000000000000000D8CB900000A0002504A +:1028E0003722FFFF3084FFFF30A5FFFF1080000775 +:1028F0000000182130820001104000020004204234 +:10290000006518211480FFFB0005284003E0000843 +:102910000060102110C00007000000008CA2000021 +:1029200024C6FFFF24A50004AC82000014C0FFFBF6 +:102930002484000403E000080000000010A0000848 +:1029400024A3FFFFAC860000000000000000000090 +:102950002402FFFF2463FFFF1462FFFA24840004B3 +:1029600003E0000800000000308EFFFF30D8FFFFBA +:1029700000057C0001F8602539CDFFFF01AC502136 +:10298000014C582B014B4821000944023127FFFF1D +:1029900000E830210006240230C5FFFF00A4182102 +:1029A0003862FFFF03E000083042FFFF3C0C0800E4 +:1029B0008D8C0484240BFF8027BDFFD0018450211F +:1029C000014B4824AF4900203C0808008D080484CE +:1029D000AFB20020AFB00018AFBF0028AFB30024E3 +:1029E000AFB1001C936600040104382130E4007F7D +:1029F000009A10213C0300080043902130C50020BC +:102A0000036080213C080111277B000814A000020C +:102A1000264600702646006C92130004975101046C +:102A2000920F00043267000F322EFFFF31ED00409D +:102A300001C7282311A0000500004821925900BCBD +:102A4000333800041700009000000000924300BCDF +:102A5000307F000413E0000F0000000010A0000D04 +:102A600000000000960E0002240AFF8000A76021EB +:102A700025CDFFFEA74D1016920B0004014B20241C +:102A8000308200FF10400085010C40253C0F0400FF +:102A9000010F40258F5301780660FFFE2404000AD1 +:102AA000A7440140960D00022404000931AC000740 +:102AB000000C5823316A0007A74A0142960200021F +:102AC0002443FFFEA7430144A7400146975F01044A +:102AD000A75F01488F5901083338002053000001D7 +:102AE00024040001920F000431EE001015C0000212 +:102AF0003483001000801821A743014A0000000021 +:102B0000000000000000000000000000AF481000BE +:102B100000000000000000000000000000000000B5 +:102B20008F5110000621FFFE3113FFFF12600003DA +:102B3000000000008F481018ACC800009603000683 +:102B4000307FFFFF27F90002001998820013888068 +:102B5000023B30218CD800001520005700183402A9 +:102B6000920300042405FF8000A3F82433F100FF42 +:102B70001220002C00000000924700BC30F200023E +:102B80001240002800000000974B100C2562FFFE49 +:102B9000A7421016000000003C0A0400354900302E +:102BA000AF4910000000000000000000000000001D +:102BB000000000008F4C10000581FFFE00000000A7 +:102BC0009749100C8F51101C00C020213127FFFFA6 +:102BD00024F20030001218820003288000BBF82184 +:102BE0003226FFFFAFF100000E0005B300112C02EA +:102BF0000013C880033B98218E7800000002740007 +:102C0000AFB800108FA80010310FFFFFAFAF00105A +:102C10008FA4001001C46825AFAD00108FA600106E +:102C2000AE66000097730008976D000A9766000C67 +:102C30008F8A003C000D5C0030CCFFFF3262FFFF4A +:102C4000104A0036016C2025960600023C10100048 +:102C500024D300080E00013B3264FFFF974C0104AF +:102C60000E0001493184FFFFAF5001788FBF00286B +:102C70008FB300248FB200208FB1001C8FB00018DA +:102C800003E0000827BD003010A0FF700000000026 +:102C900024A5FFFC0A0005EC240900048CD10000E7 +:102CA000AF5110188F5301780660FF7A2404000A90 +:102CB0000A0006010000000000A7C8218F88003824 +:102CC0008F4E101C0019C0820018788001E8202166 +:102CD000AC8E0000000E2C0200C020210E0005B3B7 +:102CE00031C6FFFF023B28218CAD000000025400DA +:102CF00000403021AFAD00108FAC0010318BFFFFD2 +:102D0000AFAB00108FA2001001424825AFA9001000 +:102D10008FA700100A000631ACA700008F8F00407B +:102D2000148FFFC90000000097420104960B0002B7 +:102D30003C0508008CA5046C3049FFFF316AFFFF99 +:102D40003C1108008E310468012A382124F2FFFE6C +:102D500000B240210012FFC30112C82B023FC02164 +:102D6000031920213C010800AC28046C3C01080038 +:102D7000AC2404680A00066B0000000000A4102BBD +:102D800010400009240300010005284000A4102B76 +:102D900004A00003000318405440FFFC0005284035 +:102DA00010600007000000000085302B14C00002F6 +:102DB00000031842008520231460FFFB0005284211 +:102DC00003E00008008010218F85002C27BDFFE85C +:102DD000000530272CC300012CA40002008310251D +:102DE00010400003AFBF00102405007FAF85002C0A +:102DF0000005282730A5FFFF0E000592240426F5C4 +:102E00008F830030240402BD004030210083382B22 +:102E100010E0000924050001000420400083102B6D +:102E200004800003000528405440FFFC00042040BB +:102E300010A0000800C350210064402B15000002C0 +:102E4000000528420064182314A0FFFB0004204260 +:102E500000C350218FBF0010000A4C02312200FF36 +:102E600027BD0018AF8A002C03E00008AF890030AE +:102E70000A00002A00000000000000000000000D11 +:102E8000747870362E302E313500000006000F00A9 +:102E900000000000000001360000EA6000000000B1 +:102EA0000000000000000000000000000000000022 +:102EB0000000000000000000000000000000000012 +:102EC0000000000000000000000000000000000002 +:102ED00000000016000000000000000000000000DC +:102EE00000000000000000000000000000000000E2 +:102EF00000000000000000000000000000000000D2 +:102F00000000000000000000000013880000000026 +:102F1000000005DC000000000000000010000003BD +:102F2000000000000000000D0000000D3C02080041 +:102F300024423C203C03080024633DD4AC40000004 +:102F40000043202B1480FFFD244200043C1D080098 +:102F500037BD7FFC03A0F0213C100800261000A81C +:102F60003C1C0800279C3C200E0002BA0000000018 +:102F70000000000D8F8300383C088000350700708A +:102F80008CE50000008330253C02900000C2202523 +:102F9000AF850030AF4400208F4900200520FFFEA0 +:102FA0003C038000346200708C4500008F86003046 +:102FB0003C1908008F39007C3C0E08008DCE00784B +:102FC00000A6202303245821000078210164682BE7 +:102FD00001CF6021018D50213C010800AC2B007C09 +:102FE0003C010800AC2A007803E000080000000063 +:102FF0000A000041240400018F8400383C05800051 +:1030000034A200010082182503E00008AF4300202D +:1030100003E00008000010213084FFFF30A5FFFF0F +:1030200010800007000018213082000110400002CB +:1030300000042042006518211480FFFB0005284091 +:1030400003E000080060102110C00007000000002D +:103050008CA2000024C6FFFF24A50004AC8200005F +:1030600014C0FFFB2484000403E0000800000000FB +:1030700010A0000824A3FFFFAC86000000000000A1 +:10308000000000002402FFFF2463FFFF1462FFFA28 +:103090002484000403E0000800000000308AFFFFE1 +:1030A00093A80013A74A014497490E1630C600FFA3 +:1030B0003C021000A7490146AF450148A346015212 +:1030C000A748015AAF4701608FA400188FA30014CE +:1030D000A7440158AF43015403E00008AF42017810 +:1030E00003E00008000000003C0380003462007030 +:1030F0008C4900008F8800002484000727BDFFF85A +:103100003084FFF8AF890030974D008A31ACFFFF63 +:10311000AFAC00008FAB0000016850232547FFFFD4 +:1031200030E61FFF00C4282B14A0FFF73C0C8000E2 +:10313000358B00708D6A00003C0708008CE7008426 +:103140003C0608008CC60080000810820149182344 +:103150000002788000E370210000202101C3C82B09 +:1031600000C4C02101FA4021031948212502400072 +:1031700027BD00083C010800AC2E00843C0108007B +:10318000AC29008003E00008000000008F820000EE +:103190002486000730C5FFF800A2182130641FFF05 +:1031A00003E00008AF8400008F8700388F8A00405A +:1031B00027BDFFB88F860044AFB60040AFBF0044C4 +:1031C000AFB5003CAFB40038AFB30034AFB200309D +:1031D000AFB1002CAFB000288F4501048D4900AC81 +:1031E000AF4700808CC8002000A938230000B02120 +:1031F000AF480E108F440E1000004821AF440E144B +:103200008CC20024AF420E188F430E18AF430E1C21 +:1032100010E001252D230001936B0008116000D4FC +:1032200000000000976E001031CDFFFF00ED602B15 +:10323000158000CF0000000097700010320FFFFFD4 +:10324000AF4F0E008F520000325100081220FFFDD8 +:103250000000000097540E088F460E043285FFFFD1 +:1032600030B3000112600132000000000000000DC8 +:1032700030B8A04024150040131500C030A9A000AC +:103280001120012D00000000937F000813E00008CA +:103290000000000097630010306BFFFF00CB402B55 +:1032A0001100000330AC0040118001230000000039 +:1032B000A785003CAF8600349366000800E0282113 +:1032C000AFA7002014C0012427B30020AF60000C7A +:1032D0009782003C3047400014E0000224030016AF +:1032E0002403000E24194007A363000AAF790014D9 +:1032F000938A003E8F740014315800070018AA40CA +:1033000002959025AF7200149784003C8F700014D2 +:103310003091001002117825AF6F0014978E003C99 +:1033200031CD000811A00147000028218F6700144B +:103330003C0210003C0C810000E22825AF6500141F +:1033400097460E0A2408000E3405FFFC30C3FFFF29 +:10335000006C5825AF6B0004A3680002937F000A3D +:1033600027E90004A369000A9786003C9363000ADA +:1033700030CC1F00000C598301634021251F002819 +:10338000A37F000997490E0CA769001093790009E3 +:10339000272A0002315800070018A82332B100077D +:1033A000A371000B93740009976400108F9100348F +:1033B000978F003C329200FF024480210205702169 +:1033C00031ED004011A0000531C4FFFF0091282B12 +:1033D0003C12800010A000140000A0210224382B11 +:1033E00014E0011B8FA500208F4D0E14AF4D0E1061 +:1033F0008F420E1CAF420E18AF440E008F4F0000DC +:1034000031EE000811C0FFFD0000000097540E08C7 +:103410000080882100009021A794003C8F500E046A +:1034200024140001AF900034976400103095FFFF22 +:103430008E6800000111F82317E00009AE7F00003C +:103440008F6500148F8B004434A60040AF660014D3 +:103450008F4C0E10AD6C00208F430E18AD6300240E +:103460009367000814E000D2000000000E00009EE8 +:10347000240400108F8900483C08320000402821B5 +:10348000312600FF0006FC0003E850252539000125 +:10349000AF990048AC4A0000937800099370000A85 +:1034A000330400FF00047400320F00FF01CF6825D1 +:1034B000AC4D00048F820048064000EAACA2000830 +:1034C000ACA0000C9783003C306B00081560000234 +:1034D0002628000626280002974E0E148F450E1C43 +:1034E0008F670004936D000231C4FFFF31A200FF1B +:1034F000AFA200108F6C0014AFA800180E00008B54 +:10350000AFAC0014240400100E0000C7000000003F +:103510008E72000016400005000000008F64001449 +:103520002405FFBF00859824AF7300148F79000C29 +:1035300003353821AF67000C9375000816A000080A +:103540000000000012800006000000008F7F0014C1 +:103550003C0BEFFF3568FFFE03E84824AF69001419 +:10356000A37400088FA500200A0002460220202133 +:10357000AF470E000A0000F5000000008F590178E7 +:103580000720FFFE241F08008F840000AF5F017832 +:10359000974B008A316AFFFF014448232528FFFF2B +:1035A00031021FFF2C4300081460FFF900000000E7 +:1035B0008F8E00488F8D003800C0482103442021A1 +:1035C00025C60001240C0F00AF86004800E938230F +:1035D0002486400031CA00FF11AC00052408000118 +:1035E0009391003E3230000700107A4035E8000128 +:1035F000000AAC003C18010002B8A025AC944000C1 +:103600008F93004830B2003630A40008ACD30004D9 +:103610001080009701123025974E0E0A8F8D000002 +:103620003C02810031CCFFFF25AB00080182402520 +:103630003C03100031651FFF25390006241F000ED2 +:10364000AF48016000C33025A75F015AAF85000075 +:10365000A759015814E0000A8F93003824120F0074 +:10366000527200022416000134C600408F580E101A +:103670008F940044AE9800208F550E18AE9500240C +:103680008F450E14AF4501448F590E1CAF590148A8 +:10369000A34A01523C0A1000AF460154AF4A0178D8 +:1036A00014E0FEDD2D2300010076A0251280001716 +:1036B0008FBF00448F84003824160F0010960084BA +:1036C000000000008F45017804A0FFFE24150F00C4 +:1036D0001095006E000000008F470E142402024077 +:1036E0003C1F1000AF4701448F440E1CAF440148FB +:1036F000A3400152A740015AAF400160A7400158C2 +:10370000AF420154AF5F01788FBF00448FB60040D5 +:103710008FB5003C8FB400388FB300348FB20030C7 +:103720008FB1002C8FB0002803E0000827BD0048AF +:1037300014C0FED030B8A0408F420E148F840044D5 +:1037400000004821AC8200208F510E1CAC91002457 +:103750000A00020E2D2300018F910034978A003C4D +:103760003C1280000220A821315800401700FF3091 +:103770000000A021976900108F9200343139FFFFBB +:103780001332003500002021008048211480FEA063 +:1037900000A038218F420E148F840044AC82002098 +:1037A0008F510E1CAC9100240A00020E2D23000143 +:1037B000936A00099378000B315000FF330F00FF2C +:1037C000020F702125C2000A3050FFFF0E00009E3C +:1037D000020020218F8600483C1F410024CD0001BB +:1037E000AF8D0048936C000930C600FF000644000E +:1037F000318300FF246B0002010B4825013FC825DF +:10380000AC5900008F67000C97440E1400F2282575 +:10381000AC4500048F450E1C8F670004936A0002BC +:103820003084FFFF315800FFAFB800108F6F0014D5 +:10383000AFB100180E00008BAFAF00140A0001A654 +:1038400002002021AF6000040A00013EA3600002D4 +:103850000A00024600002021000090210A000170A9 +:10386000241400013C1280000A000195ACB2000C47 +:103870008F91000025240002A7440158263000083B +:10388000320F1FFF0A0001F9AF8F0000AF40014C5B +:103890001120002C000000008F590E10AF59014478 +:1038A0008F430E18240200403C1F1000AF43014814 +:1038B000A3400152A740015AAF400160A740015800 +:1038C000AF420154AF5F01780A0002278FBF004466 +:1038D000112000060000000097460E0830CC004082 +:1038E00015800002000000000000000D8F4D0178DF +:1038F00005A0FFFE0000000097530E103C120500CB +:10390000240E2000326AFFFF0152C025AF58014C3F +:103910008F4F0E143C021000AF4F01448F500E1C0D +:10392000AF500148A34001528F840038A740015A8C +:10393000AF400160A7400158AF4E01540A00021584 +:10394000AF4201788F490E14AF4901448F430E1CDA +:103950000A00028E240200403C0E20FF27BDFFE03B +:103960003C1A80003C0F800835CDFFFDAFBF001C26 +:10397000AFB20018AFB10014AFB00010AF8F00406D +:10398000AF4D0E000000000000000000000000002D +:1039900000000000000000003C0C00FF358BFFFD24 +:1039A000AF4B0E003C0660048CC95000240AFF7F18 +:1039B0003C116000012A40243507380CACC7500088 +:1039C0008E24043824050009AF4500083083FFFF2A +:1039D00038622F712450C0B3AF8000480E000068D9 +:1039E000AF80000052000001AE20442C0E000435D0 +:1039F0003C1180000E000ED9363000708F8A0040D6 +:103A00003C12080026523C88020088218E080000E3 +:103A10008F5F00003BF900013338000113000017ED +:103A2000AF880030022048218D2700003C0F08009D +:103A30008DEF006C3C0C08008D8C006800E8C02302 +:103A400001F828210000682100B8302B018D582191 +:103A5000016640213C010800AC25006C3C010800D7 +:103A6000AC2800688F4400003883000130620001F8 +:103A70001440FFED00E04021AF8700308E0C0000C5 +:103A80003C0508008CA5006C3C0408008C84006890 +:103A90000188302300A638210000102100E6402BC9 +:103AA000008218210068F8213C010800AC27006C56 +:103AB0003C010800AC3F00688F490100255900888F +:103AC000AF990044AF890038AF4900208E0700004D +:103AD000AF8700308F4D017805A0FFFE0000000089 +:103AE0008E0600003C0B08008D6B00743C0408003F +:103AF0008C84007000C728230165F8210000102184 +:103B000003E5402B0082382100E8C8212409080081 +:103B10003C010800AC3F00743C010800AC39007067 +:103B2000AF49017893580108A398003E938F003E57 +:103B300031EE000115C000158F830038240E0D00F2 +:103B4000106E0019240F0F00106F001D0000000000 +:103B50009159000024180050332900FF1138000447 +:103B60003C1F4000AF5F01380A0002E70000000080 +:103B70000E00090E000000008F8A00403C1F40002C +:103B8000AF5F01380A0002E700000000938D003E9D +:103B900031AC0006000C51000E0000CE0152D821BD +:103BA0000A0003438F8A00403C1B0800277B3D0826 +:103BB0000E0000CE000000000A0003438F8A004080 +:103BC0003C1B0800277B3D280E0000CE00000000B3 +:103BD0000A0003438F8A004090AA00018FAB0010B7 +:103BE0008CAC00103C0300FF8D680004AD6C00201D +:103BF0008CAD001400E060213462FFFFAD6D002445 +:103C00008CA700183C09FF000109C024AD670028FB +:103C10008CAE001C0182C82403197825AD6F000406 +:103C2000AD6E002C8CAD0008314A00FFAD6D001C5C +:103C300094A900023128FFFFAD68001090A7000092 +:103C4000A5600002A1600004A167000090A300022B +:103C5000306200FF00021982106000052405000197 +:103C60001065000E0000000003E00008A16A0001DA +:103C70008CD80028354A0080AD7800188CCF00140D +:103C8000AD6F00148CCE0030AD6E00088CC4002CDB +:103C9000A16A000103E00008AD64000C8CCD001C9B +:103CA000AD6D00188CC90014AD6900148CC80024D7 +:103CB000AD6800088CC70020AD67000C8CC20014F2 +:103CC0008C8300640043C82B132000070000000011 +:103CD0008CC20014144CFFE400000000354A008040 +:103CE00003E00008A16A00018C8200640A000399C5 +:103CF0000000000090AA000027BDFFF88FA9001C5B +:103D0000A3AA00008FAE00003C0FFF808FA8001810 +:103D100035E2FFFF8CCD002C01C26024AFAC000067 +:103D2000A120000400E06021A7A000028FB80000DD +:103D30008D2700040188182100A0582100C05021BF +:103D4000006D28263C06FF7F3C0F00FF2CAD0001D4 +:103D500035EEFFFF34D9FFFF3C02FF00031930248A +:103D6000000D1DC0010EC82400E2C02400C3702550 +:103D700003197825AD2E0000AD2F00048D450024D9 +:103D8000AFAE0000AD2500088D4D00202405FFFFDB +:103D9000AD2D000C956800023107FFFFAD27001024 +:103DA0009166001830C200FF000219C25060000185 +:103DB0008D450034AD2500148D67000827BD00082F +:103DC000AD27001C8C8B00CCAD2C0028AD20002C26 +:103DD000AD2B0024AD20001803E00008AD2000202A +:103DE00027BDFFE0AFB20018AFB10014AFB00010B4 +:103DF000AFBF001C9098000000C088213C0D00FF60 +:103E0000330F007FA0CF0000908E000135ACFFFF84 +:103E10003C0AFF00A0CE000194A6001EA2200004D0 +:103E20008CAB00148E29000400A08021016C282492 +:103E3000012A40240080902101052025A6260002A9 +:103E4000AE24000426050020262400080E0000767B +:103E500024060002924700002605002826240014AC +:103E600000071E000003160324060004044000039C +:103E70002403FFFF965900023323FFFF0E00007654 +:103E8000AE230010262400248FBF001C8FB2001820 +:103E90008FB100148FB00010240500030000302102 +:103EA0000A00008027BD002027BDFFD8AFB1001C4D +:103EB000AFB00018AFBF002090A80000240200019E +:103EC0008FB0003C3103003F008088211062001455 +:103ED0008FAA0038240B0005506B0016AFAA001003 +:103EE00000A0202100C028210E0003DC02003021A8 +:103EF000922400BC308300021060000326060030CC +:103F0000ACC0000024C600048FBF00208FB1001C8D +:103F10008FB0001800C0102103E0000827BD002862 +:103F2000014038210E00035AAFB000100A000420EF +:103F3000000000000E0003A1AFB000140A0004202E +:103F4000000000003C02000A034218213C04080063 +:103F500024843D6C2405001A000030210A000080F2 +:103F6000AF8300543C038000346200708C48000032 +:103F700000A0582100C04821308A00FFAF880030DF +:103F80008F4401780480FFFE3C0C80003586007071 +:103F90008CC500003C0308008C6300743C180800CA +:103FA0008F18007000A82023006468210000C82139 +:103FB00001A4782B0319702101CF60213C01080076 +:103FC000AC2D00743C010800AC2C00708F480E141E +:103FD000AF480144AF47014CA34A0152A74B0158D7 +:103FE0009346010830C5000854A00001352910008F +:103FF000934B090024070050316A00FF1147000766 +:10400000000000008F450E1CAF450148AF49015428 +:104010003C09100003E00008AF490178934D010806 +:1040200031A800081100001000000000934F0108A3 +:1040300031EE001051C00001352900083C04080091 +:1040400090843DD0A34401508F4309A4AF4301485D +:104050008F4209A0AF420144AF4901543C0910000E +:1040600003E00008AF4901783C1908008F393D8C06 +:10407000333800085700FFF1352900080A0004739F +:104080000000000024070040AF470814AF400810AC +:104090008F4209448F4309508F4409548F45095C6E +:1040A0008F46094CAF820064AF830050AF84004C50 +:1040B000AF85005C03E00008AF860060934601090D +:1040C00030C5007F000518C0000521400083102185 +:1040D00003E00008244200883C09080091293D9132 +:1040E00024A800023C05110000093C0000E830252E +:1040F00000C5182524820008AC83000003E00008F6 +:10410000AC8000049347010B8F4A002C974F09089D +:104110003C18000E0358482131EEFFFF000E41C04D +:10412000AF48002C97430908952C001A00804021C5 +:1041300024030001318BFFFFAC8B00008D2D001C90 +:1041400000A0582100C06021AC8D00048D24002007 +:1041500030E70040AD04000891220019304400030C +:10416000108300482885000214A000622406000283 +:104170001086005624190003109900660000000004 +:1041800010E0003A000000003C07080094E73D867C +:1041900024E20001934F0934934709219525002A11 +:1041A00031EE00FF000E488230ED00FF9787005887 +:1041B00000093600000D1C003044FFFF00C310252D +:1041C0000044C02500A778213C1940000319702540 +:1041D000000F4C00AD090004AD0E0000934D092006 +:1041E0003C03000625090014000D360000C32025FD +:1041F000AD0400088F59092C24E5000130A27FFF8F +:10420000AD19000C8F580930A782005825020028EC +:10421000AD1800108F4F0938AD0F0014AD2B0004FE +:104220008F4E0940AD2E0008934D09373C0508001C +:1042300090A53D908F4409488F46094031A700FF63 +:1042400000EC1821008678230003C7000005CC008D +:104250000319602531E8FFFC01885825AD2B000CBF +:10426000AD20001003E00008AF4A002C3C0D080010 +:1042700095AD3D863C0E080095CE3D800A0004C9F0 +:1042800001AE10213C05080094A53D8A3C060800BB +:1042900094C63D803C18080097183D7C952E00245C +:1042A00000A6782101F86823000E240025A2FFF261 +:1042B0000082182524190800AD03000CAD19001464 +:1042C000AD0000100A0004C425080018952600243B +:1042D000952500280006C40000057C00370E8100EB +:1042E00035ED0800AD0E000CAD0D00100A0004C441 +:1042F000250800141480FFA200000000952400246B +:104300000004140034430800AD03000C0A0004C488 +:10431000250800103C03080094633D8A3C05080012 +:1043200094A53D803C06080094C63D7C9539002448 +:1043300095380028006520210086782300196C003C +:104340000018740025E2FFEE01C2202535A381008C +:1043500024190800AD03000CAD040010AD190018BD +:10436000AD0000140A0004C42508001C03E0000886 +:10437000240201F427BDFFE8AFB00010AFBF001466 +:104380000E0000600080802124050040AF45081425 +:104390008F8300508F84004C8F85005C0070182143 +:1043A0000064102318400004AF830050AF63005432 +:1043B0008F660054AF86004C1200000C0000000015 +:1043C0008F440074936800813409FA002D070007B8 +:1043D00010E0000500891021936C0081240B01F48A +:1043E000018B500401441021AF62000C8F4E095C18 +:1043F00001C5682319A000048FBF00148F4F095C0A +:10440000AF8F005C8FBF00148FB000100A000062F5 +:1044100027BD00188F8400648F8300508F82004C6A +:10442000AF640044AF63005003E00008AF62005483 +:104430003C038000346200708C43000027BDFFF80D +:10444000308700FF30A900FF30C800FFAF83003085 +:104450008F4401780480FFFE3C02800034590070D4 +:104460008F380000A3A700033C0708008CE7007406 +:104470008FAC00003C0608008CC600700303782354 +:104480003C0E7FFF00EFC82135CDFFFF000050211B +:10449000018D282400CA1821000847C0032F202BB3 +:1044A00000A810250064C021AFA200003C01080054 +:1044B000AC3900743C010800AC380070934F010A1D +:1044C000A3A000023C0E80FFA3AF00018FAC000050 +:1044D000312B007F35CDFFFF018D4824000B5600A6 +:1044E000012A4025240730002406FF803C051000E7 +:1044F00027BD0008AF48014CAF470154A740015801 +:10450000A346015203E00008AF45017827BDFFE84C +:10451000AFBF0014AFB000108F6500743C06800080 +:10452000309000FF00A620250E000060AF640074EC +:1045300093630005346200080E000062A362000568 +:10454000020020218FBF00148FB000102405000549 +:10455000240600010A00057027BD001827BDFFE0F2 +:104560003C038000AFB00010AFBF0018AFB1001423 +:10457000346200708C470000309000FF30A800FFCC +:10458000AF8700308F4401780480FFFE3C18800024 +:10459000371100708E2F00003C0D08008DAD0074A7 +:1045A0003C0A08008D4A007001E7702301AE282103 +:1045B0000000582100AE302B014B48210126382144 +:1045C0003C010800AC250074000088213C01080073 +:1045D000AC2700701100000F000000008F62007413 +:1045E0002619FFFF3208007F0002FE0233E5007F3C +:1045F00015000006332200FF2407FF800207202653 +:1046000024A3FFFF00838025320200FF00408021A9 +:10461000241110080E000060000000008F490818E7 +:104620003125000414A0FFFD3218007F001878C067 +:104630000018714001CF682125AC0088AF4C0818E4 +:10464000274A09808D4B0020AF4B01448D46002442 +:10465000AF460148A35001500E000062A740015828 +:10466000022010218FBF00188FB100148FB00010EE +:1046700003E0000827BD002027BDFFE8308400FFCD +:10468000AFBF00100E0005BB30A500FF8F830050A8 +:104690008FBF0010344500402404FF903C021000FE +:1046A00027BD0018AF43014CA3440152AF4501544C +:1046B00003E00008AF4201789343093E30620008EE +:1046C0001040000D3C0901013528080AAC880000A3 +:1046D0008F470074AC8700043C06080090C63D90EC +:1046E00030C5001050A00006AC8000088F6A006042 +:1046F000AC8A00082484000C03E00008008010212C +:104700000A0006222484000C27BDFFE8AFBF001476 +:10471000AFB000109346093F00A05021000528804B +:104720000085382330C200FF240300063C0908003E +:1047300095293D8624E8FFD824050004104300375E +:10474000240600029750093C3C0F02040006340086 +:10475000320EFFFF01CF6825AC8D0000934C093E5F +:10476000318B0020116000080000000093430936DF +:104770003C020103345F0300307900FF033FC02592 +:1047800024050008AC980004934309349359092187 +:104790000005F882306200FF0002C082332F00FF64 +:1047A00000186E00000F740001AE602501892025FD +:1047B0003C09400000898025ACF0FFD893430937BD +:1047C0008F4F09488F580940306200FF004AC821C6 +:1047D000033F702101F86023000E6F0001A65025F1 +:1047E0003185FFFC001F58800145482501683821AC +:1047F000AD0900200E00006024F00028240400040D +:104800000E000062A364003F020010218FBF00145D +:104810008FB0001003E0000827BD00180A0006351D +:104820002406001227BDFFD024090010AFB60028CF +:10483000AFB50024AFB40020AFB10014AFB000108A +:104840003C010800A0293D90AFBF002CAFB3001C75 +:10485000AFB2001897480908309400FF3C02000EE0 +:104860003107FFFF000731C0AF46002C974409080D +:104870009344010B30B500FF0342802130830030A8 +:104880000000B0211060012500008821240C0004E4 +:104890003C010800A02C3D90934B093E000B5600B4 +:1048A000000A2E0304A0016000000000AF40004891 +:1048B000934F010B31EE002011C0000600000000F4 +:1048C0009358093E00189E00001396030640018984 +:1048D000000000009344010B30830040106000038F +:1048E0008F9300508F8200502453FFFF9347093E5F +:1048F00030E6000814C000022412000300009021DA +:104900009619002C93580934934F0937A7990058EA +:10491000330C00FF31EE00FF024E6821000D58807D +:10492000016C5021015140213C010800A4283D8622 +:104930009205001830A900FF010918213C01080068 +:10494000A4233D88921100181620000200000000E8 +:104950000000000D3C010800A4233D8A3C01080032 +:10496000A4203D803C010800A4203D7C935F010B06 +:104970003063FFFF33F00040120000022464000A9D +:104980002464000B3091FFFF0E00009E02202021C6 +:104990009358010B3C08080095083D8A00402021EF +:1049A00000185982316700010E00049A010728217E +:1049B000934C010B8F4B002C974E09083C0F000EB7 +:1049C000034F402131CDFFFF000D51C0AF4A002CF5 +:1049D000974309089505001A004038212404000176 +:1049E00030A9FFFFAC4900008D06001C00404821A3 +:1049F000318A0040AC4600048D020020ACE2000881 +:104A00009103001930630003106400EC2879000260 +:104A100017200118241000021070010C241F00033D +:104A2000107F011E00000000114000DE00000000A9 +:104A30003C09080095293D8625220001935F093431 +:104A4000934E09219504002A33F900FF0019C08212 +:104A500031CF00FF978E005800184600000F6C0001 +:104A6000010D80253045FFFF02051025008E5021E5 +:104A70003C03400000433025000A6400ACEC000415 +:104A8000ACE60000935F09203C19000624EC0014FA +:104A9000001FC60003197825ACEF00088F48092CC9 +:104AA00025CD000131A57FFFACE8000C8F50093007 +:104AB000A785005824E80028ACF000108F4409387E +:104AC00001008021ACE40014AD9300048F53094031 +:104AD000AD930008934A09373C19080093393D907B +:104AE0008F4309488F460940314200FF0052F821A8 +:104AF00000667023001F7F000019C40001F82825FC +:104B000031CDFFFC00AD2025AD84000CAD80001040 +:104B1000AF4B002C934B093E317300081260000D1F +:104B20003C06010134CC080AACEC00288F53007419 +:104B3000AD1300043C0B0800916B3D9031670010F1 +:104B400050E00003AD0000088F6A0060AD0A000865 +:104B50002510000C12C0003D000000009343093FE7 +:104B60002416000624060004306200FF105600C917 +:104B7000240700029758093C3C0F0204330DFFFF45 +:104B800001AF4025AE0800009345093E30A4002047 +:104B90001080000800000000935309363C0B01030D +:104BA000357F0300327900FF033F7025AE0E00040D +:104BB00024060008934F093493480921312AFFFF46 +:104BC00031ED00FF000D1082310300FF0002B6003E +:104BD00000032C0002C56025018A98250012208060 +:104BE0003C0940000204502302695825AD4BFFD810 +:104BF000935F09378F4F09488F58094033F900FFF9 +:104C0000033270210006B08201D6682100074400FB +:104C100001F82823000D1F000068302530A2FFFC9A +:104C20002547FFD800C26025001680800207482172 +:104C3000ACEC0020253000280E0000602412000497 +:104C4000A372003F0E000062000000009347010BBA +:104C500030F20040124000053C1900FF8E180000A1 +:104C6000372EFFFF030E3024AE0600000E0000C7F3 +:104C7000022020213C10080092103D9032110003C8 +:104C80001220000F02A028218F8900502533000137 +:104C9000AF930050AF7300508F6B00540173F82333 +:104CA0001BE00002026020218F640054AF640054B6 +:104CB0008F4C0074258401F4AF64000C02A02821FD +:104CC00002802021A76000680E0005BB3C14100084 +:104CD0008F85005034550006AF45014C8F8A00483F +:104CE0008FBF002C8FB3001C25560001AF960048E3 +:104CF0008FB20018A34A01528FB60028AF55015455 +:104D00008FB10014AF5401788FB500248FB4002008 +:104D10008FB0001003E0000827BD00309358093E13 +:104D200000189E000013960306420036241100026C +:104D300093440923308300021060FEDD8F860060FB +:104D40008F82005014C2FEDA000000000E000060E6 +:104D5000000000009369003F24070016312800FF7F +:104D60001107000C240500083C0C0800918C3D90B4 +:104D7000358B00013C010800A02B3D90936A003F59 +:104D8000314300FF10650065240D000A106D005EC0 +:104D90002402000C0E000062000000000A000690D1 +:104DA000000000003C09080095293D863C0A0800E7 +:104DB000954A3D800A0006F3012A10213C090800AB +:104DC00095293D8A3C04080094843D803C060800F7 +:104DD00094C63D7C95030024012410210046F8234D +:104DE0000003CC0027F0FFF20330C025240F080099 +:104DF000ACF8000CACEF0014ACE000100A0006EEBA +:104E000024E700183C010800A0313D90935F093E63 +:104E10002416000133F900201720FEA524110008F4 +:104E20000A000690241100048F6E00848F4D094003 +:104E300011A0FE9EAF8E0050240F00143C0108000C +:104E4000A02F3D900A00068F00000000950E002460 +:104E5000950D0028000E6400000D2C00358981009E +:104E600034A60800ACE9000CACE600100A0006EE1F +:104E700024E700141460FEEC0000000095020024FA +:104E800000021C0034640800ACE4000C0A0006EECA +:104E900024E700100A000741240700123C02080022 +:104EA00094423D8A3C06080094C63D803C030800BD +:104EB00094633D7C95100024951900280046F82144 +:104EC00003E3C02300106C0000197400270FFFEEED +:104ED00001CF282535AC8100ACEC000CACE500100E +:104EE00024070800AD2700182527001C0A0006EE3D +:104EF000AD2000148F7F004CAF7F00548F79005499 +:104F00000A000699AF790050A362003F0E000062CC +:104F1000000000000A0006900000000024020014B7 +:104F20000A000827A362003F27BDFFE8308400FF86 +:104F3000AFBF00100E0005BB30A500FF9378007EC8 +:104F40009379007F936E00809368007A332F00FF7F +:104F500000186600000F6C0031CB00FF018D482562 +:104F6000000B52008FBF0010012A3825310600FFC8 +:104F70003444700000E628252402FF813C03100021 +:104F800027BD0018AF45014CAF440154A342015264 +:104F900003E00008AF43017827BDFFD8AFB2001887 +:104FA000AFB10014AFB00010AFBF0020AFB3001C12 +:104FB00093420109308600FF30B000FF000618C29E +:104FC000320400023071000114800005305200FFED +:104FD0009367000530E5000810A0000D30C80010F0 +:104FE000024020210E0005A70220282124040001F0 +:104FF0008FBF00208FB3001C8FB200188FB1001438 +:105000008FB000100080102103E0000827BD0028A9 +:105010001500003200000000934301090000282120 +:105020003062007F000220C00002F94003E49821B2 +:1050300026790088033B98218E7800248E6F000823 +:10504000130F0046000000008F6400842418000243 +:105050000004FD8233F900031338007C00000000D7 +:1050600093660083934A0109514600043205007C8F +:1050700010A00060000000003205007C14A0005366 +:105080000240202116200006320400018E7F0024F9 +:105090008F59010417F9FFD60000202132040001C6 +:1050A0001080000A024020218F4209408F93006443 +:1050B00010530006000000000E00066D022028219B +:1050C0008F430940AF630044024020210E000602D6 +:1050D000022028210A000860240400013C0908007D +:1050E0008D290064252600013C010800AC260064DF +:1050F00016000012000000008F6D00843C0E00C0FE +:1051000001AE602415800005024020210E00082E0B +:10511000022028210A00086024040001240500045C +:105120000E00057024060001024020210E00082E0A +:10513000022028210A000860240400010E0000411A +:1051400024040001936B007D020B50250E000062C9 +:10515000A36A007D0A0008A38F6D00848F66007427 +:105160008F4801048E67002400064E021507FFB623 +:105170003126007F936B008326440001308A007F34 +:1051800011460043316300FF5464FFB08F64008414 +:105190002645000130B1007F30A200FF1226000436 +:1051A00024050001004090210A0008762411000126 +:1051B000240FFF80024F702401CF9026324200FF5F +:1051C000004090210A000876241100010E00066DAF +:1051D00002202821321800301300FFAA321000826A +:1051E000024020210E0005A7022028210A000860A5 +:1051F000240400018F6E00743C0F8000240500031E +:1052000001CF9025AF7200749371008324060001D2 +:105210000E000570322400FF0E000041240400013E +:10522000936D007D020D60250E000062A36C007D71 +:105230003C0B08008D6B0054257000013C010800F8 +:10524000AC3000540A000860240400018F68007428 +:105250003C0980002405000401093825AF6700746B +:1052600093630083240600010E000570306400FF84 +:105270000E000041240400019362007D0202982583 +:105280000E000062A373007D0A0008602404000180 +:10529000324D008039AC0080546CFF6C8F64008408 +:1052A0000A0008C92645000127BDFFC83C0A0008BE +:1052B000AFBF0030AFB5002CAFB40028AFB30024AF +:1052C000AFB20020AFB1001CAFB00018034AD82124 +:1052D00024090040AF490814AF4008108F42094428 +:1052E0008F4309508F4609548F47095C8F48094CFA +:1052F000934401089345010BAF820064308400FFA2 +:1053000030A500FFAF830050AF86004CAF87005C34 +:105310000E00084AAF8800601440017D8FBF003046 +:10532000A7600068934D0900240B00503C1508004D +:1053300026B53D4831AC00FF3C12080026523D58CE +:10534000118B0003000000000000A8210000902144 +:10535000935101098F9F005024040010322E007FCA +:10536000000E68C0000E6140018D282124B4008821 +:10537000AF5408188F4901048F4A09A43C0B000E52 +:10538000034BC021012A10233C010800AC223D6CD4 +:105390008F4309583C010800A0243D909747090815 +:1053A000007F30233C010800AC263D7030E8FFFF51 +:1053B0000008C9C03C010800AC3F3D94AF59002C27 +:1053C000974209089710002C8EB10000930F001827 +:1053D00003749821A7900058AF9300440220F80965 +:1053E00031F000FF304E000215C001B2304F000115 +:1053F00011E0014F000000009343093E30660008B1 +:1054000014C00002241400030000A0218F5809A436 +:10541000241300013C010800AC383D98934F093437 +:105420009351093731EC00FF322E00FF028E6821C4 +:10543000000D288000AC5021015058213C0108008B +:10544000A42B3D883C010800A42A3D8693490934D9 +:10545000312200FF02022021249000103C010800AC +:10546000A4303D84240700068F9F00503C010800B3 +:10547000AC273D8C8F88005C8F5909580000802133 +:10548000011F282304A00149033F20230480014772 +:1054900000A4302B10C00149000000003C010800AE +:1054A000AC253D708E4200000040F809000000006D +:1054B00030430002146000F80040882130440001AD +:1054C000548000108E4200043C0908008D293D7470 +:1054D0003C0AC000012A8025AF500E008F45000015 +:1054E00030AB00081160FFFD00000000974D0E0872 +:1054F00024100001A78D003C8F4C0E04AF8C0034AB +:105500008E4200040040F8090000000002228825B5 +:10551000322E000215C00180000000003C09080086 +:1055200095293D7C3C06080094C63D883C0A08004D +:10553000954A3D7E3C1908008F393D740126602153 +:105540003C1808008F183D983C03080094633D9276 +:10555000018A20218F4E09400329F821248F00025F +:1055600003E32821031968213C010800A42C3D8A8B +:10557000AF8E00643C010800AC2D3D983C01080052 +:10558000A4253D800E00009E31E4FFFF8F87004878 +:10559000004020213C010800A0273D918E420008D8 +:1055A00024E80001AF8800480040F809000000002E +:1055B0009344010B8F4C002C974A09083C0B000EBA +:1055C000034B40213149FFFF000919C08F8B005068 +:1055D000AF43002C974309089506001A0040382174 +:1055E000308A004030DFFFFFAC5F00008D19001CE7 +:1055F00000404821AC5900048D180020AC58000828 +:10560000910F001931E30003107300F00000000057 +:10561000286200021440010924050002106500FD03 +:10562000240D0003106D010D00000000114000D991 +:10563000000000003C0A0800954A3D862542000112 +:10564000934D093493580921950E002A31A300FF88 +:1056500000032082331F00FF9798005800047E004B +:10566000001FCC0001F940253049FFFF010910253A +:1056700001D830213C0540000045502500066C0053 +:10568000ACED0004ACEA0000934309203C040006A2 +:1056900024ED00140003FE0003E4C825ACF9000863 +:1056A0008F49092C270F000131EE7FFFACE9000C78 +:1056B0008F480930A78E005824E90028ACE8001074 +:1056C0008F45093801204021ACE50014ADAB000442 +:1056D0008F420940ADA20008934B09373C1F0800D8 +:1056E00093FF3D908F4309488F4A0940316600FF80 +:1056F00000D42021006A78230004C700001FCC00DA +:105700000319282531EEFFFC00AE1025ADA2000CD8 +:10571000ADA00010AF4C002C934C093E318B00081B +:105720005160000F8E58000C3C06010134CA080A73 +:10573000ACEA00288F4B0074AD2B00043C0C080031 +:10574000918C3D903187001050E00003AD2000089F +:105750008F620060AD2200082528000C8E58000CD6 +:105760000300F809010020213C19080097393D8AFF +:105770003C1F080097FF3D7E033F782125E900028A +:105780000E0000C73124FFFF3C0E08008DCE3D6C9B +:105790003C0808008D083D7401C828233C0108001E +:1057A000AC253D6C14A00006000000003C0308007E +:1057B0008C633D8C346400403C010800AC243D8C7B +:1057C000120000708F8C00448F470E108F900044A1 +:1057D000AE0700208F4D0E18AE0D00243C100800BF +:1057E00096103D800E000060000000002402004082 +:1057F000AF4208148F8600508F8A004C00D01821C9 +:10580000006A582319600004AF830050AF6300544E +:105810008F650054AF85004C1200000C00000000A2 +:105820008F440074936800813409FA002D0E00073C +:1058300011C0000500891821937F0081241901F40B +:1058400003F9780401E41821AF63000C8F44095C6C +:105850008F83005C0083C0231B0000030000000056 +:105860008F50095CAF90005C0E00006200000000E9 +:105870008F8C00508E4700103C010800AC2C3D94EA +:1058800000E0F809000000003C0D08008DAD3D6C03 +:1058900055A0FEF5240700068F45002497590908F6 +:1058A0008F8B00648F9400503C0F001F978200582C +:1058B0008F8600548F93004C3328FFFF35E9FF801B +:1058C00000A95024000871C032320100AF4E0024FC +:1058D000A4C2002CAF4A0024AF6B0044AF74005048 +:1058E000AF73005416400080323800105700008615 +:1058F0008EA40004322300405460001B8EB10008C7 +:105900008EB0000C0200F809000000008FBF0030CC +:105910008FB5002C8FB400288FB300248FB20020E5 +:105920008FB1001C8FB0001803E0000827BD0038BD +:10593000934701098F8800380007FE0003E8C82557 +:10594000AF5900808F5809A08F5309A4AFB8001039 +:10595000AF580E148FB40010AF540E10AF530E1C7E +:105960000A000962AF530E180220F8090000000077 +:105970008EB0000C0200F809000000000A000AA81E +:105980008FBF0030A5800020A59300220A000A5B8B +:10599000AD9300243C09080095293D863C0608008B +:1059A00094C63D800A0009F4012610213C0108003C +:1059B000AC203D700A00098E8E4200003C010800B8 +:1059C000AC243D700A00098E8E4200003C030800A2 +:1059D00094633D8A3C04080094843D803C1F080089 +:1059E00097FF3D7C951800240064C821033F78236D +:1059F00000186C0025EEFFF201AE2825AC45000C26 +:105A000024020800ACE20014ACE000100A0009EF28 +:105A100024E70018950600249509002800062400B4 +:105A200000091C00349F810034790800ACFF000C91 +:105A3000ACF900100A0009EF24E700141460FEFB23 +:105A4000000000009518002400187C0035EE0800C6 +:105A5000ACEE000C0A0009EF24E700103C07080038 +:105A600094E73D803C04080094843D8A3C03080090 +:105A700094633D7C95190024951800280087F8212F +:105A800003E378232407080000192C0000186C0099 +:105A900025EEFFEE01AE302534A28100AD270018BF +:105AA0002527001CAD22000CAD2600100A0009EFCE +:105AB000AD20001493520109000028210E000602B7 +:105AC000324400FF8FBF00308FB5002C8FB4002808 +:105AD0008FB300248FB200208FB1001C8FB000184C +:105AE00003E0000827BD0038935F010933E400FF9D +:105AF0000E00066D00002821323800105300FF7E92 +:105B0000322300408EA400040080F8090000000049 +:105B10000A000AA2322300401200FF5F00000000CA +:105B20008F540E148F920044AE5400208F530E1CDD +:105B30000A000A8AAE5300248F82001C0080402194 +:105B40003C0401009047008530E30020106000090C +:105B5000000000003C0708008CE73D948F8300188C +:105B600000E32023048000089389000414E3000369 +:105B70000100202103E00008008010213C04010006 +:105B800003E00008008010211120000B006738237B +:105B90008F8C002024090034918B00BC316A0002F4 +:105BA000514000012409003000E9682B15A0FFF1E5 +:105BB0000100202100E938232419FFFC00B9C0248A +:105BC00000F9782400F8702B15C0FFEA01E82021C5 +:105BD00030C200030002182314C000123069000311 +:105BE0000000302100A9702101C6682100ED602B62 +:105BF0001180FFE03C0401002D2F00010006482B1E +:105C00000105382101E9302414C0FFDA24E4FFFC47 +:105C10002419FFFC00B9C0240308202103E0000878 +:105C2000008010218F8B002024060004916A00BCA4 +:105C3000314400041480FFEC00A970210A000B5EBF +:105C40000000302127BDFFE8AFBF00108F460100E4 +:105C5000934A01093C1F08008FFF00902407FF8032 +:105C6000314F00FF31E8007F0008614003E6C821A2 +:105C7000032CC02127090120012770243C010800C2 +:105C8000A02F3DD0AF4E080C3C0D08008DAD00900C +:105C90003C0400803482000301A65821016C1821C5 +:105CA0002465012030AA007801424025AF48081C35 +:105CB0003C1F08008FFF00908F88004003E6C02142 +:105CC0003319000703074824033A7821AF49002815 +:105CD00025E909C0952E00023C0D08008DAD008C11 +:105CE0003C0A08008D4A009031CC3FFF01A61821E4 +:105CF000000C5980006B282100A72024AF44002C01 +:105D0000952200023C1F08008FFF008C9107008540 +:105D100030593FFF03E678210019C1800146702108 +:105D200001F8682131CC007F31AB007F019A282136 +:105D3000017A50213C03000C3C04000E00A32821F2 +:105D40000144102130E6002027470980AF82002C53 +:105D5000AF88001CAF890024AF85002010C000066A +:105D6000AF8700288D0200508CA4010C0044302322 +:105D700018C0007700000000910C0085240DFFDFA3 +:105D8000018D3824A10700858F8B001C8F8900248A +:105D90008F8700288D65004CAF850018912F000D6E +:105DA00031EE002011C0001700000000240900019E +:105DB000A3890004AF80000C8CE400248F85000CC4 +:105DC000240A0008AF800008AF8000103C010800E2 +:105DD000A42A3D7E3C010800A4203D920E000B3217 +:105DE000000030218F8500248FBF0010AF82001487 +:105DF00090A8000D27BD00180008394203E00008F4 +:105E000030E20001913F00022418000133F900FF45 +:105E10000019218210980039240800021088005BC4 +:105E20008F86002C8CE5002414A0001B8F9F00207F +:105E300091220000240A00053046003F10CA0047A6 +:105E4000240400018F860008A3840004AF8600109C +:105E5000AF86000C8CE400248F85000C240A000817 +:105E60003C010800A42A3D7E3C010800A4203D928C +:105E70000E000B32000000008F8500248FBF001041 +:105E8000AF82001490A8000D27BD00180008394209 +:105E900003E0000830E200018CF800088CF90024CF +:105EA0008FEE00C4A38000048CE40024AF8E000CAD +:105EB0008F85000C8F86000803197823240A0008B8 +:105EC000AF8F00103C010800A42A3D7E3C01080071 +:105ED000A4203D920E000B32000000008F850024AC +:105EE0008FBF0010AF82001490A8000D27BD0018CE +:105EF0000008394203E0000830E20001912300006D +:105F00003062003F104400278F8500208CE400247D +:105F100014800021000000008D2E00183C187FFF27 +:105F20008F850020370FFFFF01CF1824AF830008B3 +:105F30008F9F00088CA8008403E8C82B172000025C +:105F400003E020218CA400840A000BEDAF8400083C +:105F50008CA3010C0A000BCBAF8300188D2C00180A +:105F60008F8600083C0D7FFF8F89002035A3FFFF3F +:105F70000183582424040001AF8B0010AD2000CC15 +:105F8000A38400040A000BF9AF86000C8CCA00142D +:105F90000A000BEDAF8A00088CA300C80A000C3081 +:105FA000AF8300088F84002C8CAC00648C8D0014AF +:105FB000018D582B11600004000000008CA20064C9 +:105FC0000A000C30AF8200088C8200140A000C30EA +:105FD000AF8200088F85000C27BDFFE0AFBF00181F +:105FE000AFB1001414A00007AFB000108F860024DA +:105FF0002402000590C400003083003F106200B608 +:106000008F8400208F91000800A080218F8C0028B1 +:106010003C0508008CA53D708D8B000431663FFF68 +:1060200000C5502B5540000100C02821938D00046D +:1060300011A0007300B0F82B8F98002024040034C6 +:10604000930F00BC31EE000251C000012404003067 +:1060500000A4C82B172000D10000000000A42823B2 +:1060600000B0F82B3C010800A4243D7C17E0006838 +:10607000020020213C0308008C633D6C0083102B40 +:1060800054400001008018218F8800243C01080042 +:10609000AC233D74000048219104000D30830020A2 +:1060A000506000018F490E188F8300140123382B94 +:1060B00010E00059000000003C0408008C843D748E +:1060C00000895821006B502B114000560090602B26 +:1060D0000069302300C020213C010800AC263D743B +:1060E00012000003241FFFFC1090008A32270003D7 +:1060F000009FC8243C010800AC393D743C010800F5 +:10610000A4203D928F84000C120400078F8300208E +:10611000AF910008020020218C7100CCAF90000CE0 +:1061200026300001AC7000CC3C0208008C423D746B +:106130008F8A0010240700180082202301422823A0 +:10614000AF84000C10800002AF85001024070010FF +:106150008F86001C3C010800A0273D9024070040CA +:1061600090CC0085318B00C0116700408F8D0014EA +:1061700014A0001500002021934A01098F420974E0 +:10618000314500FF0002260224A300013090007F69 +:106190003071007F1230007A2407FF80A0C3008393 +:1061A0003C0908008D293D8C8F880024240D0002B5 +:1061B000352C00083C010800A02D3DD13C01080011 +:1061C000AC2C3D8C24040010910E000D31C6002033 +:1061D00010C0000500801821240800013C010800BF +:1061E000AC283D74348300018FBF00188FB10014B8 +:1061F0008FB000100060102103E0000827BD0020D0 +:106200003C010800A4203D7C13E0FF9A02002021FD +:106210000A000C8100A020213C0408008C843D74FD +:106220000090602B1180FFAE000000003C0F0800C2 +:1062300095EF3D7C01E4702101C6682B11A0000799 +:106240002C8200043C1F60008FF954043338003F57 +:106250001700FFE5240300422C8200041040FFA039 +:10626000240300420A000CDF8FBF0018152DFFC069 +:10627000000000008CDF00743C0380002405FF80D8 +:1062800003E3C825ACD9007490D80085240E00041F +:1062900024040010330F003F01E54025A0C800850D +:1062A0008F8800243C010800A02E3DD1240300016A +:1062B0009106000D30C900201520000300000000E9 +:1062C0003C0308008C633D743C010800AC233D6C2A +:1062D0000A000CD6000000008F8700108C88008414 +:1062E00000E8282B14A0000200E088218C91008493 +:1062F00024090001A38900048F440E1802202821DC +:106300000E000B3202203021022080210A000C678F +:10631000AF82001400071823306600033C01080018 +:10632000A4263D92122000058F8C0020918B00BC8A +:10633000316A00041540001524CD00043C0F08000C +:1063400095EF3D9201E4702100AE302B50C0FF6EFE +:106350008F84000C2C85000514A0FFA324030042A9 +:106360003098000317000002009818232483FFFCD4 +:106370003C010800AC233D740A000CA3000000009F +:1063800000A758240A000CCB016718263C0108001E +:10639000A42D3D920A000D33000000003C010800CE +:1063A000AC203D740A000CDE240300428F830010F1 +:1063B00014600007000010218F88002424050005C8 +:1063C0009106000030C400FF1085000300000000AB +:1063D00003E0000800000000910A0018314900FFA6 +:1063E000000939C214E0FFFA8F85001C3C04080044 +:1063F00094843D7C3C0308008C633D943C19080068 +:106400008F393D743C0F080095EF3D920064C02128 +:106410008CAD00540319702101CF6021018D5823E8 +:106420001960001D00000000910E001C8F8C002CD4 +:10643000974B0E1031CD00FF8D850004016D302388 +:106440008D88000030CEFFFF000E510000AAC82149 +:106450000000382101072021032A182B0083C021C6 +:10646000AD990004AD980000918F000A01CF68211A +:10647000A18D000A8F88002C974B0E12A50B0008E7 +:10648000950A003825490001A50900389107000D3B +:1064900034E60008A106000D03E00008000000003B +:1064A00027BDFFE0938700048F8F00248FAD001479 +:1064B0003C0E7FFF8F89000C35C8FFFFAFBF001C6B +:1064C000AFB0001801A8182491EA000D000717C00A +:1064D0003C1FBFFF006258252D2E00018F90001831 +:1064E00037F9FFFF3C1808008F183D943C0F080057 +:1064F00095EF3D8A01796824000E47803C07EFFF45 +:106500003C05F0FF01A818253149002034E2FFFFC7 +:1065100034ACFFFF0310582327A500102406000207 +:1065200025EA000200621824008080211520000264 +:10653000000040218F480E1CA7AA001205600037FA +:106540002407000030FF00FF001FCF008F8B001CCE +:1065500000793825AFA70014916F00853C0808002A +:1065600091083D913C18DFFF31EE00C0370AFFFF74 +:10657000000E182B3C1F080097FF3D8400EA68249A +:10658000A3A800110003174001A248258FB90010ED +:10659000AFA900143C0A0800914A3D93A7BF00161A +:1065A0008FA80014032CC0243C0B01003C0F0FFFEC +:1065B000030B18253147000335EEFFFF010C68245B +:1065C00000071600006EF8243C09700001A2C825DF +:1065D00003E95825AFB90014AFAB00100E000076E8 +:1065E000A3A000158F8C0024260200089186000DC0 +:1065F00030C40020108000068FBF001C3C0508003E +:1066000094A53D8024B0FFFF3C010800A4303D80EC +:106610008FB0001803E0000827BD00208F980014F9 +:106620000118502B5540FFC7240700010A000DB682 +:1066300030FF00FF9382000427BDFFE0AFBF0018CA +:106640001040000F008050218F880024240B00058B +:106650008F890008910700008F8400200100282105 +:1066600030E3003F8F86002C106B000800003821BB +:10667000AFA900100E00040EAFAA0014A3800004FE +:106680008FBF001803E0000827BD00208D190018F7 +:106690003C0F08008DEF3D748F9800103C027FFF87 +:1066A0008D080014345FFFFF033F682401F8702158 +:1066B00001AE602301883821AFA900100E00040E3E +:1066C000AFAA00140A000E04A38000048F870024E0 +:1066D0003C05080094A53D923C0208008C423D8C8C +:1066E00090E6000D0005240030C300201060002C4F +:1066F000004440258F85001C00006021240B000110 +:1067000090A3008500004821240A00013C0F80006E +:1067100035EE00708DC70000AF8700308F580178CC +:106720000700FFFE3C038000347900708F380000C2 +:106730003C0508008CA500743C0D08008DAD007070 +:106740000307782300AF38210000102100EF302B21 +:1067500001A22021008618213C010800AC2700740A +:106760003C010800AC230070AF4B01483C19080005 +:106770008F393D94A7490144A74A0146AF59014CBE +:106780003C0B0800916B3D91A34B0152AF48015463 +:106790003C081000A74C015803E00008AF480178FE +:1067A0008F4B0E1C3C0A08008D4A3D7497490E160B +:1067B000974D0E1401456021312AFFFF0A000E2774 +:1067C00031A9FFFF8F8300249064000D30820020E8 +:1067D0001040002900000000000048210000502166 +:1067E000000040213C07800034EB00708D67000002 +:1067F000AF8700308F4C01780580FFFE3C0D800094 +:1068000035AC00708D8B00003C0508008CA5007431 +:106810003C0408008C8400700167302300A67821B6 +:106820000000102101E6C82B0082C021031970214D +:106830003C010800AC2F00743C010800AC2E007035 +:10684000AF4901483C0D08008DAD3D94A748014477 +:1068500024090040A74A01463C081000240AFF9181 +:10686000AF4D014CA34A0152AF490154A740015812 +:1068700003E00008AF4801788F490E1897460E12C2 +:1068800097450E1030CAFFFF0A000E5D30A8FFFFCB +:106890008F83002427BDFFF89064000D3082002014 +:1068A0001040003A00000000240B000100004821C5 +:1068B000240A00013C088000350700708CE30000CA +:1068C000AF8300308F4C01780580FFFE3C0E8000C6 +:1068D0003C04080090843DD035C700708CEC00006B +:1068E0003C0508008CA50074A3A400033C19080013 +:1068F0008F3900708FAD00000183302300A638214E +:10690000000010210322782100E6C02B01F860214D +:1069100001AE4025AFA800003C010800AC27007480 +:106920003C010800AC2C00709346010A3C040800AE +:1069300090843DD1A3A00002A3A600018FA3000074 +:106940003C0580FF3099007F34A2FFFF006278246D +:106950000019C60001F87025240D3000AF4E014C1F +:1069600027BD0008AF4D0154A7400158AF4B014867 +:10697000A7490144A74A01463C091000240AFF80A8 +:10698000A34A015203E00008AF4901788F4B0E186B +:1069900097460E1297450E1030CAFFFF0A000E915F +:1069A00030A9FFFF8F85001C2402008090A4008581 +:1069B000308300C0106200058F8600208F88000899 +:1069C0008F87000CACC800C8ACC700C403E0000847 +:1069D000000000003C0A0800254A39543C09080020 +:1069E00025293A203C08080025082DD43C0708003A +:1069F00024E73B343C06080024C637C43C050800A5 +:106A000024A5353C3C040800248431643C03080080 +:106A10002463385C3C020800244236303C01080004 +:106A2000AC2A3D503C010800AC293D4C3C0108001B +:106A3000AC283D483C010800AC273D543C0108000F +:106A4000AC263D643C010800AC253D5C3C010800DF +:106A5000AC243D583C010800AC233D683C010800D3 +:0C6A6000AC223D6003E0000800000000D4 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex b/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex deleted file mode 100644 index 627baec7cb5c66a720a13c91e3526f970c000688..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-mips-09-5.0.0.j15.fw.ihex +++ /dev/null @@ -1,6081 +0,0 @@ -:100000000800011008000000000051F8000000C8BE -:10001000000000000000000000000000080051F88F -:1000200000000038000052C00800008808000000EE -:100030000000528C000052F8080054800000008438 -:100040000000A5840800528C000001C00000A60832 -:10005000080031D808000000000081080000A7C88F -:1000600000000000000000000000000008008108FF -:1000700000000124000128D00800048808000400C2 -:10008000000017EC000129F400000000000000004F -:100090000000000008001BEC00000004000141E02B -:1000A000080000A808000000000038D0000141E46A -:1000B000000000000000000000000000080038D030 -:0800C0000000003000017AB4D9 -:0800C8000A00004400000000E2 -:1000D000000000000000000D636F6D352E302E30E3 -:1000E0006A31350005000002000000000000000336 -:1000F00000000014000000320000000300000000B7 -:1001000000000000000000000000000000000000EF -:1001100000000010000001360000EA600000000549 -:1001200000000000000000000000000000000008C7 -:1001300000000000000000000000000000000000BF -:1001400000000000000000000000000000000000AF -:10015000000000000000000000000000000000009F -:10016000000000020000000000000000000000008D -:10017000000000000000000000000000000000007F -:10018000000000000000000000000010000000005F -:10019000000000000000000000000000000000005F -:1001A000000000000000000000000000000000004F -:1001B000000000000000000000000000000000003F -:1001C000000000000000000000000000000000002F -:1001D000000000000000000000000000100000030C -:1001E000000000000000000D0000000D3C020800AF -:1001F000244252603C0308002463539CAC4000003E -:100200000043202B1480FFFD244200043C1D080005 -:1002100037BD9FFC03A0F0213C1008002610011000 -:100220003C1C0800279C52600E00026B000000007E -:100230000000000D27BDFFE0AFBF0018AFB10014F4 -:10024000AFB000103C04800094820108304370007D -:10025000240220001062000B2862200114400036A6 -:1002600000001021240240001062002C0000000059 -:10027000240260001062002D000010210A00009D81 -:100280008FBF001834910100922400098E300018AD -:1002900010800020240300012402000914820006BB -:1002A0008F8200243C0280089442001A000214004D -:1002B000020280258F8200248C42000C1040001521 -:1002C000000018210E000D52000000008F83002452 -:1002D000962400088F8200209463001E9625000C4F -:1002E0000004240000832025AC500000AC4500042D -:1002F000AC400008AC40000CAC400010AC40001416 -:10030000AC400018AC44001C0E000D862404000113 -:10031000000018210A00009C006010210E00043B20 -:10032000000000000A00009C000010210E000C726A -:1003300000000000000010218FBF00188FB10014D2 -:100340008FB0001003E0000827BD00208F8200243A -:1003500027BDFFE0AFB00010AFBF0018AFB1001471 -:100360008C42000C3C1080008E11010010400034C3 -:100370008FBF00180E000D52000000008F85002076 -:1003800024047FFF0091202BACB100008E030104F8 -:100390009602010800031C003042FFFF006218258E -:1003A000ACA300049202010A96030114304200FF3C -:1003B0003063FFFF0002140000431025ACA20008C8 -:1003C0009603010C9602010E00031C003042FFFF51 -:1003D00000621825ACA3000C9603011096020112CE -:1003E00000031C003042FFFF00621825ACA3001080 -:1003F0008E020118ACA200148E02011CACA20018DF -:10040000148000088F820024978200003C0420059D -:100410000044182524420001ACA3001C0A0000DBA4 -:10042000A78200003C0340189442001E00431025A0 -:10043000ACA2001C0E000D86240400018FBF001822 -:100440008FB100148FB000100000102103E00008ED -:1004500027BD00203C0680008CC202B824030001A6 -:1004600004410008008028213C0208008C42006002 -:10047000244200013C010800AC22006003E00008B7 -:10048000006010218C83002094820016ACC302808F -:100490002442FFFCA4C202843C0208008C42005C9F -:1004A0008C84000494A3000E244200013C01080047 -:1004B000AC22005C3C021000A4C30286ACC40288DB -:1004C00000001821ACC202B803E00008006010214F -:1004D00027BDFFE0AFB000103C108000AFB20018A5 -:1004E000AFBF001CAFB10014361201009243000BE5 -:1004F0002402001A965100081462005A00002821B4 -:1005000032220001104000188F8200248E42000029 -:10051000000223403C02003F3442FFFF0044102B06 -:10052000104000043C030040964200140A000124DD -:10053000008320218E030100240201005462000682 -:10054000964200143C028008904200043042000FA2 -:10055000000225009642001400821025AE020080A1 -:100560000A000157000000008C42000C10400028D7 -:10057000000000000E000D5200000000960201086D -:100580009603010C8F8500203042003E3063FFFF50 -:100590000002140000431025ACA200008E020100EE -:1005A000ACA20004960301169604010E8F8200246B -:1005B00000031C003084FFFF00641825ACA3000872 -:1005C00096030110960401129446001E00031C00BD -:1005D0003084FFFF00641825ACA3000C3C0220000F -:1005E00000C2302596020114240400013042FFFFAE -:1005F000ACA200108E020118ACA200149202010BF2 -:10060000304200FFACA200180E000D86ACA6001C04 -:100610003C0208008C420040244200013C010800DA -:10062000AC2200403C0308008C63004432220002EC -:1006300032240004246300013C010800AC23004480 -:10064000108000080002282B024020218FBF001CD0 -:100650008FB200188FB100148FB000100A0000E3B1 -:1006600027BD00208FBF001C8FB200188FB100146F -:100670008FB0001000A0102103E0000827BD00206B -:1006800027BDFFE0AFB000103C108000AFB20018F3 -:10069000AFBF001CAFB10014361201009243000B33 -:1006A00024020003965100081462007500002821FE -:1006B00032220001104000178F8200248E43000078 -:1006C0003C02003F3442FFFF000323400044102B54 -:1006D0005040000524020100964200143C030040F3 -:1006E0000A00018F00832021546200069642001404 -:1006F0003C028008904200043042000F00022500B6 -:100700009642001400821025AE0200800A0001BF4C -:10071000000000008C42000C10400025000000008A -:100720000E000D5200000000960201089603010C15 -:100730008F8500203042003E3063FFFF000214002E -:1007400000431025ACA200008E020100ACA2000400 -:10075000960301169604010E8F82002400031C00EC -:100760003084FFFF00641825ACA300089603011035 -:10077000960401129446001E00031C003084FFFF03 -:1007800000641825ACA3000C3C02200000C23025F8 -:1007900096020114240400013042FFFFACA20010B5 -:1007A000ACA00014ACA000180E000D86ACA6001C76 -:1007B0003C0208008C420040244200013C01080039 -:1007C000AC2200403C0208008C420044322300046A -:1007D000244200013C010800AC22004410600008E3 -:1007E00032220002024020218FBF001C8FB200186D -:1007F0008FB100148FB000100A0000E327BD002065 -:100800001040001F000028213C05800034A2007029 -:100810008C4400008F82000C008210232C43012C9A -:1008200010600004AF820010240500010A0001EEF0 -:10083000AF84000C8CA301043C026020AC43001484 -:100840008C420004240301FE304203FF1443000BDA -:10085000AF84000C8CA20100000219C22462FFFCCC -:100860002C42000810400003240400022462FFFD13 -:10087000004420043C026000AC44691400002821BC -:100880008FBF001C8FB200188FB100148FB0001002 -:1008900000A0102103E0000827BD00203C048000D8 -:1008A0008C83010024020100506200033C02800896 -:1008B0000000000D3C02800890430004000010215D -:1008C0003063000F00031D0003E00008AC830080CC -:1008D0002C8407811080000A000028213C0280003F -:1008E00094420108240320003042700014430005A4 -:1008F0002783FFA43C02800890420005304500FF9A -:100900002783FFA40005208000832021000510C05C -:10091000004510238C8400003C0308002463532C02 -:10092000000210C0004310213C038000AC64009022 -:1009300003E00008AF82002403E00008000010215B -:1009400003E00008000010212402010014820008C6 -:10095000000000003C0208008C4200FC2442000120 -:100960003C010800AC2200FC0A00023030A200204A -:100970003C0208008C420084244200013C01080033 -:10098000AC22008430A200201040000830A30010E8 -:100990003C0208008C420108244200013C0108008E -:1009A000AC22010803E0000800000000106000080D -:1009B000000000003C0208008C42010424420001B7 -:1009C0003C010800AC22010403E000080000000024 -:1009D0003C0208008C420100244200013C01080056 -:1009E000AC22010003E000080000000027BDFFE882 -:1009F000AFB000103C108000AFBF001436040100FF -:100A00009483000830620004104000053066000244 -:100A10008FBF00148FB000100A0000E327BD00183C -:100A200010C00006006028218E0401000E00022084 -:100A3000000000000A000267240200018F82000803 -:100A40008E03010410430007000010218E040100F2 -:100A50000E000220000000008E020104AF82000898 -:100A6000000010218FBF00148FB0001003E00008B9 -:100A700027BD001827BDFFD83C036010AFB3001C92 -:100A8000AFBF0020AFB20018AFB10014AFB000107C -:100A90008C6450002402FF7F3C13080026735290A0 -:100AA000008220243484380CAC6450003C02800066 -:100AB00024030037AC4300083C06080024C6087035 -:100AC000026010212404001C2484FFFFAC460000B7 -:100AD0000481FFFD244200043C0208002442016C12 -:100AE0003C010800AC2252983C020800244205B8A0 -:100AF0003C010800AC22529C3C02080024420284C3 -:100B00003C010800AC2252D83C02080024420408F0 -:100B10003C030800246308783C040800248409246A -:100B20003C05080024A52C803C010800AC2252F8AA -:100B30003C020800244207D43C010800AC2652E0E5 -:100B40003C010800AC2552EC3C010800AC2352F4F7 -:100B50003C010800AC2452FC3C010800AC225300CC -:100B60003C010800AC2352943C010800AC2052A088 -:100B70003C010800AC2052A43C010800AC2052A863 -:100B80003C010800AC2052AC3C010800AC2052B043 -:100B90003C010800AC2052B43C010800AC2052B823 -:100BA0003C010800AC2452BC3C010800AC2052C0FF -:100BB0003C010800AC2052C43C010800AC2052C8E3 -:100BC0003C010800AC2052CC3C010800AC2052D0C3 -:100BD0003C010800AC2652D43C010800AC2652DC93 -:100BE0003C010800AC2052E43C010800AC2552E86E -:100BF0003C010800AC2352F00E0005670000000025 -:100C0000AF80000C8F8300043C0208008C4200205F -:100C10001062001F000088212792FFA43C100800EA -:100C20002610532C3C0208008C42002024050001B1 -:100C300002251804004320248F820004004310245E -:100C40005044000C2631000110800008AF900024B1 -:100C50008E4300003C028000AC4300900E000D1952 -:100C6000AE05000C0A0002EB26310001AE00000CBC -:100C7000263100012E220002261000381440FFE920 -:100C8000265200043C0208008C420020AF8200047F -:100C90003C1080008E110000322200071040FFDA65 -:100CA0008F83000432220001104000213222000212 -:100CB0008E020100AE0200208E020104AE0200A8E6 -:100CC0000E0002028E0401009202010B304300FF6D -:100CD0002C62001D54400004000310800E00021C12 -:100CE0000A00030C00000000005310218C42000099 -:100CF0000040F80900000000104000043C028000A1 -:100D00008C4301043C026020AC4300143C02080008 -:100D10008C4200343C0440003C038000244200012B -:100D2000AC6401383C010800AC22003432220002DD -:100D300010400010322200043C1080008E0201405E -:100D4000AE0200200E0002028E0401400E0003A439 -:100D5000000000003C024000AE0201783C020800A6 -:100D60008C420038244200013C010800AC220038CB -:100D7000322200041040FFA48F8300043C10800046 -:100D80008E020180AE0200200E0002028E0401805D -:100D90008E03018024020F00146200073C028008C9 -:100DA0008E0201883C0300E03042FFFF0043102523 -:100DB0000A000348AE0200803442008090420000E6 -:100DC00024030050304200FF1443000700000000DD -:100DD0000E0003810000000014400003000000002A -:100DE0000E00096A000000003C0208008C42003C32 -:100DF0003C0440003C03800024420001AC6401B884 -:100E00003C010800AC22003C0A0002D08F830004A1 -:100E10003C02900034420001008220253C02800008 -:100E2000AC4400203C0380008C6200200440FFFEA4 -:100E30000000000003E00008000000003C02800009 -:100E4000344300010083202503E00008AC44002067 -:100E500027BDFFE0AFB10014AFB0001000808821C3 -:100E6000AFBF00180E00035230B000FF8F83FF9C0D -:100E7000022020219062002502028025A07000251A -:100E80008C7000183C0280000E00035D020280247A -:100E90001600000A8FBF00183C0380008C6201F826 -:100EA0000440FFFE24020002AC7101C0A06201C434 -:100EB0003C021000AC6201F88FBF00188FB1001423 -:100EC0008FB0001003E0000827BD002027BDFFE819 -:100ED000AFBF00103C0380009462018430420200E6 -:100EE00010400005000020210E000FDA0000000075 -:100EF0000A000397240400018C6201880440000A60 -:100F00008FBF00108C6201883C03FF000043102457 -:100F10003C03040014430004240400018F82FF9C5E -:100F2000904200088FBF00100080102103E00008ED -:100F300027BD00188F82FFA02403000124050001B3 -:100F4000A040001A8F82FF9CA44300163C02800040 -:100F50000A0003628C4401408F85FF9C27BDFFE09F -:100F6000AFBF001CAFB20018AFB10014AFB000109B -:100F700090A20000304400FF388300203882003007 -:100F80000003182B0002102B0062182410600005CB -:100F90003C02800024020050148200818FBF001C9C -:100FA0003C02800090420148304200FF2443FFFF92 -:100FB0002C6200051040007A8FBF001C00031080D7 -:100FC0003C03080024635210004310218C420000AF -:100FD00000400008000000003C1180008E24014009 -:100FE0000E0003528F92FF9C8E50000C8E22014403 -:100FF0001602000224020001AE42000C0E00035D46 -:101000008E2401408E220144145000068FBF001C24 -:101010008FB200188FB100148FB000100A000F4675 -:1010200027BD00208E42000C0A00042F00000000A3 -:1010300094A200103C0480008C8301443042FFFFE6 -:10104000146200090000000024020001A4A20010A4 -:101050008C820140AC8202003C021000AC8202385B -:101060000A0004368FBF001C94A200100A00042F4F -:1010700000000000240200201482000E3C118000B9 -:1010800094A200123C0380008C6301443042FFFFB5 -:10109000146200050000000024020001A4A2001256 -:1010A0000A0004098FBF001C94A200120A00042F3A -:1010B000000000008E2401400E0003528F92FF9C1E -:1010C000964200128E2301443050FFFF16030002A7 -:1010D00024020001A64200120E00035D8E2401408E -:1010E0008E220144160200068FBF001C8FB200182A -:1010F0008FB100148FB000100A00039B27BD0020A1 -:10110000964200120A00042F0000000094A200146E -:101110003C0380008C6301443042FFFF14620008EE -:101120008FBF001C240200018FB200188FB1001481 -:101130008FB00010A4A200140A00143127BD0020B3 -:1011400094A200140A00042F0000000094A20016CC -:101150003C0380008C6301443042FFFF14620008AE -:10116000240200018FBF001C8FB200188FB1001441 -:101170008FB00010A4A200160A000B0D27BD00209E -:1011800094A20016144000068FBF001C3C02080009 -:101190008C420070244200013C010800AC22007027 -:1011A0008FB200188FB100148FB0001003E0000858 -:1011B00027BD002027BDFFD8AFB200188F92FF9C3B -:1011C000AFB10014AFBF0020AFB3001CAFB0001030 -:1011D0003C028000345101008C500100924200001A -:1011E00092230009304400FF2402001F106200AB6C -:1011F0002862002010400019240200382862000AEA -:101200001040000D2402000B286200081040002E40 -:101210008F82002404600103286200021440002A27 -:101220008F82002424020006106200268FBF002057 -:101230000A0005598FB3001C106200602862000B81 -:10124000144000F98FBF00202402000E10620078C5 -:101250008F8200240A0005598FB3001C106200D150 -:10126000286200391040000A24020080240200365F -:10127000106200E428620037104000C224020035EA -:10128000106200D88FBF00200A0005598FB3001CE0 -:101290001062002D2862008110400006240200C860 -:1012A00024020039106200C88FBF00200A000559CF -:1012B0008FB3001C106200A28FBF00200A000559E6 -:1012C0008FB3001C8F8200248C42000C104000D68B -:1012D0008FBF00200E000D52000000003C03800074 -:1012E000346301008C6200008F8500209467000841 -:1012F0009466000CACA200008C6400048F82002471 -:1013000000063400ACA400049448001E8C6200184F -:1013100000073C0000E83825ACA200088C62001CE5 -:1013200024040001ACA2000C9062000A00C2302527 -:10133000ACA60010ACA00014ACA00018ACA7001C18 -:101340000A0005188FBF00208F8200248C42000CF9 -:10135000104000B58FBF00200E000D5200000000AD -:101360008F820024962400089625000C9443001ECA -:10137000000422029626000E8F8200200004260020 -:101380000083202500052C003C03008000A62825B2 -:1013900000832025AC400000AC400004AC400008B5 -:1013A000AC40000CAC450010AC400014AC40001840 -:1013B000AC44001C0A000517240400019622000C0E -:1013C0001440001800000000924200053042001056 -:1013D00014400014000000000E00035202002021FF -:1013E0009242000502002021344200100E00035DED -:1013F000A24200059242000024030020304200FF78 -:1014000010430088020020218FBF00208FB3001CF2 -:101410008FB200188FB100148FB000100A00104373 -:1014200027BD00280000000D0A0005588FBF0020CE -:101430008C42000C1040007C8FBF00200E000D522B -:10144000000000008E2200048F8400209623000CF0 -:10145000AC8200003C0280089445002C8F8200245E -:1014600000031C0030A5FFFF9446001E3C02400E06 -:101470000065182500C23025AC830004AC8000084C -:10148000AC80000CAC800010AC800014AC80001864 -:10149000AC86001C0A000517240400010E0003524C -:1014A000020020218F93FFA0020020210E00035D87 -:1014B000A660000C020020210E000362240500013A -:1014C0008F8200248C42000C104000578FBF0020F8 -:1014D0000E000D52000000009622000C8F830020A9 -:1014E00000021400AC700000AC620004AC600008A4 -:1014F0008E4400388F820024AC64000C8E46003C81 -:101500009445001E3C02401FAC66001000A2282536 -:101510008E62000424040001AC620014AC60001868 -:10152000AC65001C8FBF00208FB3001C8FB2001869 -:101530008FB100148FB000100A000D8627BD00285F -:1015400024020020108200398FB3001C0E000F2CE3 -:1015500000000000104000348FBF00203C038000DA -:101560008C6201F80440FFFE24020002AC7001C04E -:10157000A06201C43C021000AC6201F80A000558E8 -:101580008FBF0020020020218FBF00208FB3001CDE -:101590008FB200188FB100148FB000100A000E75C2 -:1015A00027BD00289625000C020020218FBF0020B7 -:1015B0008FB3001C8FB200188FB100148FB00010D1 -:1015C0000A000E9A27BD0028020020218FB3001CBC -:1015D0008FB200188FB100148FB000100A000EC532 -:1015E00027BD00289225000D020020218FB3001C8A -:1015F0008FB200188FB100148FB000100A000F16C0 -:1016000027BD0028020020218FBF00208FB3001CBF -:101610008FB200188FB100148FB000100A000EEDC9 -:1016200027BD00288FBF00208FB3001C8FB2001889 -:101630008FB100148FB0001003E0000827BD002810 -:101640003C0380008C6202780440FFFE240200020A -:10165000AC640240A06202443C02100003E00008B7 -:10166000AC620278A380001803E00008A380001990 -:101670003C0380008C6202780440FFFE8F82001CD5 -:10168000AC62024024020002A06202443C0210004C -:1016900003E00008AC6202783C02600003E000084E -:1016A0008C425404908300302402000500804021C5 -:1016B0003063003F00004821146200050000502103 -:1016C0009082004C9483004E304900FF306AFFFF47 -:1016D000AD00000CAD000010AD0000249502001418 -:1016E0008D05001C8D0400183042FFFF00491023B7 -:1016F00000021100000237C3004038210086202379 -:1017000000A2102B0082202300A72823AD05001C77 -:10171000AD040018A5090014A5090020A50A0016AB -:1017200003E00008A50A002203E000080000000012 -:1017300027BDFFD8AFB200183C128008AFB400201C -:10174000AFB3001CAFB10014AFBF0024AFB00010A6 -:10175000365101003C0260008C4254049222000C7D -:101760003C140800929400F7304300FF240200016B -:1017700010620032008098212402000214620035B9 -:10178000365000800E00140B000000009202004C46 -:101790002403FF803C0480003042007F000211C01F -:1017A000244202400262102100431824AC830094BA -:1017B000924500089204004C3042007F3C038006B2 -:1017C00014850007004380212402FFFFA22200119C -:1017D0002402FFFFA62200120A0005CB2402FFFF0D -:1017E00096020020A222001196020022A6220012D8 -:1017F0008E0200243C048008AE2200143485008050 -:1018000090A2004C34830100A06200108CA2003C26 -:10181000AC6200188C820068AC6200E48C820064C8 -:10182000AC6200E08C82006CAC6200E82402000133 -:10183000A0A200680A0005E73C0480080E001424FA -:101840000000000036420080A04000680A0005E762 -:101850003C048008A2000068A20000690A00062279 -:101860003C028008348300808C620038348501009B -:10187000AC62006C24020001A062006990A200C565 -:1018800090830008305100FF3072007F123200193F -:10189000001111C024420240026210212403FF8083 -:1018A000004318243C048000AC8300943042007F45 -:1018B0003C038006004380218E02000C1040000D86 -:1018C000020020210E000577000000002622000102 -:1018D000305100FF9203003C023410260002102B0E -:1018E000000210233063007F022288240A0005F1E1 -:1018F000A203003C3C088008350401008C8200D023 -:1019000035070080ACE2003C8C8200D0AD020000C4 -:1019100090E5004C908600C590E3004C908400C593 -:101920002402FF8000A228243063007F308400FF5F -:1019300000A628250064182A1060000230A500FFC8 -:1019400038A50080A0E5004CA10500093C028008F4 -:101950009043000E344400803C058000A043000A00 -:101960008C8300183C027FFF3442FFFF0062182482 -:10197000AC8300188CA201F80440FFFE00000000B8 -:10198000ACB301C08FBF00248FB400208FB3001C04 -:101990008FB200188FB100148FB000102402000223 -:1019A000A0A201C427BD00283C02100003E00008EB -:1019B000ACA201F890A2000024420001A0A2000005 -:1019C0003C0308008C6300F4304200FF1443000223 -:1019D00000803021A0A0000090A200008F84001C95 -:1019E000000211C0244202402483004000822021D2 -:1019F0002402FF80008220243063007F3C02800AA2 -:101A0000006218213C028000AC44002403E000087E -:101A1000ACC3000094820006908300058C85000C06 -:101A20008C8600108C8700188C88001C8C84002009 -:101A30003C010800A422530E3C010800A023530DD2 -:101A40003C010800AC2553143C010800AC26531897 -:101A50003C010800AC2753203C010800AC2853246B -:101A60003C010800AC24532803E0000800000000FB -:101A70003C028008344201008C4400343C03800066 -:101A800034650400AC6400388C420038AF8500280F -:101A9000AC62003C3C020005AC620030000000007B -:101AA0000000000003E00008000000003C02000607 -:101AB000308400FF008220253C028000AC440030CE -:101AC0000000000000000000000000003C03800057 -:101AD0008C620000304200101040FFFD34620400B0 -:101AE00003E00008AF82002894C200003C08080010 -:101AF000950800CA30E7FFFF00804821010210214D -:101B0000A4C2000094C200003042FFFF00E2102B8C -:101B100054400001A4C7000094A200003C03080048 -:101B20008C6300CC24420001A4A2000094A2000017 -:101B30003042FFFF144300073C0280080107102BCE -:101B4000A4A000005440000101003821A4C70000F7 -:101B50003C028008344601008CC3002894A2000097 -:101B60003C0480003042FFFE000210C000621021E1 -:101B7000AC82003C8C82003C006218231860000498 -:101B8000000000008CC200240A0006B324420001B9 -:101B90008CC20024AC8200383C0200503442001059 -:101BA0003C038000AC620030000000000000000038 -:101BB000000000008C620000304200201040FFFD59 -:101BC0000000000094A200003C04800030420001AC -:101BD000000210C0004410218C430400AD2300001B -:101BE0008C420404AD2200043C02002003E0000803 -:101BF000AC82003027BDFFE0AFB20018AFB10014D7 -:101C0000AFB00010AFBF001C94C2000000C0802124 -:101C10003C120800965200C624420001A6020000B1 -:101C20009603000094E2000000E030211443000518 -:101C30008FB100300E000688024038210A0006EA03 -:101C4000000000008C8300048C82000424420040C9 -:101C500004610007AC8200048C820004044000048C -:101C6000000000008C82000024420001AC820000D1 -:101C7000960200003042FFFF50520001A600000013 -:101C80009622000024420001A62200003C028008A7 -:101C900034420100962300009442003C14430004A7 -:101CA0008FBF001C24020001A62200008FBF001C71 -:101CB0008FB200188FB100148FB0001003E000083D -:101CC00027BD002027BDFFE03C028008AFBF001801 -:101CD000344201008C4800343C0380003469040025 -:101CE000AC6800388C42003830E700FFAF8900282C -:101CF000AC62003C3C020005AC6200300000000019 -:101D000000000000000000000000000000000000D3 -:101D1000000000008C82000C8C82000C978300165F -:101D2000AD2200008C82001000604021AD22000432 -:101D30008C820018AD2200088C82001CAD22000CA1 -:101D40008CA20014AD2200108C820020AD22001461 -:101D500090820005304200FF00021200AD22001800 -:101D60008CA20018AD22001C8CA2000CAD22002019 -:101D70008CA20010AD2200248CA2001CAD220028F1 -:101D80008CA20020AD22002C3402FFFFAD260030D3 -:101D9000AD200034506200013408FFFFAD28003848 -:101DA00050E000113C0280083C04800834840100AB -:101DB000948200503042FFFFAD22003C94830044E7 -:101DC00094850044240200013063FFFF000318C221 -:101DD000006418219064005430A5000700A210048C -:101DE0000A0007550044102534420100AD20003C94 -:101DF00094430044944400443063FFFF000318C23E -:101E0000006218213084000790650054240200010C -:101E1000008210040002102700451024A062005424 -:101E20000000000000000000000000003C0200066E -:101E3000344200403C038000AC62003000000000EF -:101E400000000000000000008C6200003042001022 -:101E50001040FFFD3C06800834C20150346304008A -:101E600034C7014A34C4013434C5014034C6014486 -:101E7000AFA200100E0006CBAF8300288FBF001862 -:101E800003E0000827BD00208F8300143C060800F3 -:101E90008CC600E88F82001C30633FFF000319806E -:101EA00000461021004310212403FF800043182422 -:101EB0003C068000ACC300283042007F3C03800C0D -:101EC0000043302190C2000D30A500FF00003821F2 -:101ED00034420010A0C2000D8F8900143C0280081B -:101EE0003442010094430044000913823048000347 -:101EF00024020001A4C3000E1102000B29020002FB -:101F000010400005240200021100000C240300010F -:101F10000A00079D000018211102000600000000C1 -:101F20000A00079D000018218CC2002C0A00079DA2 -:101F3000244300018CC20014244300018CC2001809 -:101F40000043102B5040000A240700012402002700 -:101F500014A200033C0380080A0007AA240700011A -:101F6000346301009462004C24420001A462004CDE -:101F700000091382304300032C6200021040000964 -:101F800000802821146000040000000094C2003486 -:101F90000A0007BA3046FFFF8CC600380A0007BAAD -:101FA00000802821000030213C04080024845308CC -:101FB0000A0006FF0000000027BDFF90AFB60068D2 -:101FC000AFB50064AFB40060AFB3005CAFB200580F -:101FD000AFB10054AFBF006CAFB000508C900000A8 -:101FE0000080B0213C0208008C4200E896040032D8 -:101FF0008F83001C2414FF8030843FFF006218216F -:102000000004218000641821007410243C13800017 -:1020100000A0902190A50000AE620028920400323A -:102020003C02800C3063007F00628821308400C055 -:1020300024020040148200320000A8218E350038AE -:102040008E2200181440000224020001AE22001863 -:102050009202003C304200201440000E8F83001C8E -:10206000000511C02442024000621821306400784B -:102070003C0200800082202500741824AE63080012 -:10208000AE6408108E2200188E0300080043102151 -:10209000AE2200188E22002C8E230018244200014C -:1020A0000062182B10600043000000009242000004 -:1020B00024420001A24200003C0308008C6300F4AB -:1020C000304200FF50430001A24000009242000055 -:1020D0008F84001C000211C024420240248300406F -:1020E0003063007F008220213C02800A009420247B -:1020F00000621821AE6400240A0008CBAEC30000C1 -:10210000920300322402FFC000431024304200FF3B -:102110001440000524020001AE220018962200346B -:102120000A00083B3055FFFF8E22001424420001B4 -:10213000AE220018920200300002160000021603C0 -:102140000441001C000000009602003227A4001089 -:1021500000802821A7A2001696020032000030213C -:10216000240700013042FFFFAF8200140E0006FF7B -:10217000AFA0001C960200328F83001C3C040800B4 -:102180008C8400E830423FFF000211800064182177 -:102190000062182100741024AE62002C3063007FAE -:1021A0003C02800E006218219062000D3042007FD8 -:1021B000A062000D9222000D3042001050400078C5 -:1021C000924200003C028008344401009482004C9A -:1021D0008EC300003C130800967300C62442FFFF24 -:1021E000A482004C946200329623000E3054FFFF0C -:1021F0003070FFFF3C0308008C6300D000701807AC -:10220000A7A300389482003E3063FFFF3042FFFFF7 -:1022100014620007000000008C8200303C03800044 -:1022200024420030AC62003C0A0008638C82002C1F -:10223000948200403042FFFF5462000927A400400E -:102240008C8200383C03800024420030AC62003CA9 -:102250008C820034AC6200380A0008723C038000B3 -:1022600027A5003827A60048026038210E000688FE -:10227000A7A000488FA300403C02800024630030E8 -:10228000AC4300388FA30044AC43003C3C038000C7 -:102290003C020005AC6200303C028008344401007E -:1022A00094820042346304003042FFFF0202102B8C -:1022B00014400007AF8300289482004E94830042AC -:1022C00002021021004310230A0008883043FFFF58 -:1022D0009483004E94820042026318210050102320 -:1022E000006218233063FFFF3C0280083444010081 -:1022F0009482003C3042FFFF1443000300000000C2 -:102300000A000898240300019482003C3042FFFF39 -:102310000062102B144000058F8200289482003C3C -:10232000006210233043FFFF8F820028AC5500006D -:10233000AC400004AC540008AC43000C3C02000666 -:10234000344200103C038000AC620030000000000A -:1023500000000000000000008C620000304200100D -:102360001040FFFD3C04800834840100001018C2B6 -:102370000064182190650054320200072406000111 -:102380000046100400451025A062005494830042CA -:102390009622000E50430001A386001892420000CE -:1023A00024420001A24200003C0308008C6300F4B8 -:1023B000304200FF50430001A24000009242000062 -:1023C0008F84001C000211C024420240248300407C -:1023D000008220212402FF80008220243063007FBD -:1023E0003C02800A006218213C028000AC440024B8 -:1023F000AEC300008FBF006C8FB600688FB500645D -:102400008FB400608FB3005C8FB200588FB100545E -:102410008FB0005003E0000827BD007027BDFFD833 -:10242000AFB3001CAFB20018AFB10014AFB00010D2 -:10243000AFBF00200080982100E0802130B1FFFF75 -:102440000E000D5230D200FF00000000000000001E -:10245000000000008F8200208F830024AC51000018 -:10246000AC520004AC530008AC40000CAC4000106F -:10247000AC400014AC4000189463001E0203802599 -:10248000AC50001C00000000000000000000000034 -:10249000240400018FBF00208FB3001C8FB20018EE -:1024A0008FB100148FB000100A000D8627BD0028E0 -:1024B00030A5FFFF0A0008D530C600FF3C028008A7 -:1024C000344301009462000E3C080800950800C6E1 -:1024D0003046FFFF14C000043402FFFF946500DAA9 -:1024E0000A0009228F84001C10C20027000000008F -:1024F0009462004E9464003C3045FFFF00A6102318 -:1025000000A6182B3087FFFF106000043044FFFF47 -:1025100000C5102300E210233044FFFF0088102B79 -:102520001040000E00E810233C02800834440100F3 -:102530002403000134420080A44300162402FFFF5C -:10254000A482000E948500DA8F84001C00003021E4 -:1025500030A5FFFF0A0008FA3C0760200044102A5B -:10256000104000093C028008344300809462001649 -:1025700030420001104000043C0280009442007E82 -:1025800024420014A462001603E0000800000000CA -:1025900027BDFFE03C028008AFBF001CAFB00018B1 -:1025A00034420100944300429442004C1040001910 -:1025B0003068FFFF93830018240200011462002991 -:1025C0008FBF001C3C06800834D00100000810C2F8 -:1025D00000501021904200543103000734C70148D5 -:1025E000304200FF006210073042000134C9014E42 -:1025F00034C4012C34C5013E1040001634C60142DB -:102600000E0006CBAFA90010960200420A00093F57 -:102610003048FFFF3C0280083444010094830044AA -:10262000948200421043000F8FBF001C948200442C -:10263000A482004294820050A482004E8C82003812 -:10264000AC82003094820040A482003E9482004A12 -:10265000A48200488FBF001C8FB000180A0008FD3C -:1026600027BD00208FB0001803E0000827BD002020 -:1026700027BDFFA0AFB1004C3C118000AFBF005898 -:10268000AFB30054AFB20050AFB000483626018857 -:1026900090C200033044007FA3A400108E3201805A -:1026A00090C200003043007F240200031062003B10 -:1026B000AF92001C286200041040000624020004AF -:1026C00024020002106200098FBF00580A000B08A4 -:1026D0008FB300541062004D240200051062014EB9 -:1026E0008FBF00580A000B088FB30054000411C0BC -:1026F000024210212404FF8024420240004410249E -:1027000026430040AE2200243063007F3C02800A52 -:10271000006218219062003CAFA3003C00441025E9 -:10272000A062003C8FA3003C9062003C304200401D -:102730001040016C8FBF00583C108008A380001827 -:10274000361001008E0200D08C63003427A4003CB8 -:1027500027A50010004310210E0007BCAE0200D0D8 -:1027600093A200103C038000A20200C58C62027894 -:102770000440FFFE8F82001CAC6202402402000273 -:10278000A06202443C021000AC6202780E000932E2 -:10279000000000000A000B078FBF00583C058008AE -:1027A00090C3000190A2000B1443014E8FBF00584C -:1027B00034A400808C8200189082004C90A2000803 -:1027C0003C0260008C4254048C8300183C027FFF62 -:1027D0003442FFFF006218243C0208008C4200B41F -:1027E000AC8300183C038000244200013C01080037 -:1027F000AC2200B48C6201F80440FFFE8F82001C02 -:10280000AC6201C00A000ACF240200023C1080081A -:1028100090C300019202000B144301328FBF005895 -:1028200027A4001836050110240600033C026000AE -:102830008C4254040E000E150000000027A400284E -:10284000360501E00E000E15240600038FA20028B5 -:1028500036030100AE0200648FA2002CAE020068B5 -:102860008FA20030AE02006C93A40018906300C5E4 -:102870002402FF800082102400431025304900FF0D -:102880003084007F3122007F0082102A54400001F2 -:1028900039290080000411C0244202402403FF8033 -:1028A0000242102100431024AE2200942642004030 -:1028B0003042007F3C038006004340218FA3001C70 -:1028C0002402FFFFAFA800403C130800927300F7FA -:1028D0001062003393A2001995030014304400FFE6 -:1028E0003063FFFF0064182B106000100000000030 -:1028F000950400148D07001C8D0600183084FFFF1E -:10290000004420230004210000E4382100001021AD -:1029100000E4202B00C2302100C43021AD07001C90 -:10292000AD0600180A000A2893A2001995040014A5 -:102930008D07001C8D0600183084FFFF00822023C5 -:1029400000042100000010210080182100C2302363 -:1029500000E4202B00C4302300E33823AD07001C23 -:10296000AD06001893A200198FA30040A4620014C2 -:1029700097A2001AA46200168FA2001CAC6200107D -:102980008FA2001CAC62000C93A20019A46200206C -:1029900097A2001AA46200228FA2001CAC6200243D -:1029A0003C048008348300808C6200388FA20020B1 -:1029B00001208821AC62003C8FA20020AC82000084 -:1029C00093A20018A062004C93A20018A0820009F4 -:1029D000A060006893A20018105100512407FF80E6 -:1029E0003229007F000911C0244202400242102116 -:1029F0003046007F3C03800000471024AC62009406 -:102A00003C02800600C2302190C2003CAFA60040CC -:102A10000000202100471025A0C2003C8FA80040E4 -:102A200095020002950300148D07001C3042FFFF41 -:102A30003063FFFF8D0600180043102300021100D1 -:102A400000E2382100E2102B00C4302100C2302106 -:102A5000AD07001CAD06001895020002A502001487 -:102A6000A50000168D020008AD0200108D020008BE -:102A7000AD02000C95020002A5020020A500002274 -:102A80008D020008AD0200249102003C304200405B -:102A90001040001A262200013C108008A3A900382B -:102AA000A3800018361001008E0200D08D03003480 -:102AB00027A4004027A50038004310210E0007BCC2 -:102AC000AE0200D093A200383C038000A20200C5F1 -:102AD0008C6202780440FFFE8F82001CAC620240D0 -:102AE00024020002A06202443C021000AC620278A0 -:102AF0000E00093200000000262200013043007F52 -:102B000014730004004020212403FF8002231024BA -:102B10000043202693A200180A000A44309100FFC7 -:102B200093A400188FA3001C2402FFFF1062000A68 -:102B3000308900FF24820001248300013042007F9D -:102B400014530005306900FF2403FF800083102424 -:102B500000431026304900FF3C02800890420008E4 -:102B600001208821305000FF123000193222007FEE -:102B7000000211C002421021244202402403FF80BF -:102B8000004318243C048000AC8300943042007F52 -:102B90003C038006004310218C43000C00402021A0 -:102BA0001060000BAFA200400E000577000000008F -:102BB000262300012405FF803062007F14530002A9 -:102BC00002252024008518260A000AA8307100FF7B -:102BD0003C048008348400808C8300183C027FFF12 -:102BE0003442FFFF00621824AC8300183C038000CD -:102BF0008C6201F80440FFFE00000000AC7201C0CE -:102C000024020002A06201C43C021000AC6201F880 -:102C10000A000B078FBF00583C04800890C30001D6 -:102C20009082000B1443002F8FBF00583490008017 -:102C300092020008304200401040002000000000D6 -:102C4000920200080002160000021603044100056B -:102C5000024020210E000E9A240500930A000B0763 -:102C60008FBF00589202000924030018304200FF71 -:102C70001443000D02402021240500390E000E32BD -:102C8000000030210E0003528F84001C8F82FF9CB5 -:102C900024030012A04300090E00035D8F84001C72 -:102CA0000A000B078FBF0058240500360E000E32B5 -:102CB000000030210A000B078FBF00580E0003529E -:102CC00002402021920200058F84001C3442002023 -:102CD0000E00035DA20200050E0010438F84001C4D -:102CE0008FBF00588FB300548FB200508FB1004C8B -:102CF0008FB0004803E0000827BD00603C02800858 -:102D0000344501003C0280008C42014094A3000E37 -:102D10000000302100402021AF82001C3063FFFF03 -:102D20003402FFFF106200063C0760202402FFFF10 -:102D3000A4A2000E94A500DA0A0008FA30A5FFFF4D -:102D400003E000080000000027BDFFC83C0280002F -:102D50003C068008AFB5002CAFB1001CAFBF0030FF -:102D6000AFB40028AFB30024AFB20020AFB000185A -:102D70003451010034C501008C4301008E2200143F -:102D80008CA400D40000A821AF83001C00441023B1 -:102D900018400052A38000188E2200140000502119 -:102DA000ACA200D490C3000890A200C53073007F8D -:102DB000A3A200108CB200D08CB400D4304200FF2B -:102DC0001053003B93A200108F83001C2407FF8048 -:102DD000000211C00062102124420240246300401E -:102DE000004710243063007F3C0980003C08800AC3 -:102DF00000681821AD2200248C62003427A400143E -:102E000027A50010024280210290102304400028D0 -:102E1000AFA300149062003C00E21024304200FF97 -:102E200014400019020090219062003C344200409E -:102E3000A062003C8F86001C93A3001024C20040B7 -:102E40003042007F004828213C0208008C4200F4F8 -:102E500024630001306400FF14820002A3A3001069 -:102E6000A3A0001093A20010AFA50014000211C08F -:102E70002442024000C2102100471024AD22002449 -:102E80000A000B3E93A200100E0007BC00000000D9 -:102E90003C02800834420100AC5000D093A30010E3 -:102EA000240A0001A04300C50A000B3E93A20010B3 -:102EB00024020001154200093C0380008C62027864 -:102EC0000440FFFE8F82001CAC620240240200021C -:102ED000A06202443C021000AC6202789222000B15 -:102EE00024030002304200FF14430072000000007F -:102EF00096220008304300FF240200821462004042 -:102F0000240200843C028000344901008D22000C20 -:102F100095230006000216023063FFFF3045003F94 -:102F20002402002710A2000FAF83001428A200285B -:102F300010400008240200312402002110A20009E0 -:102F40002402002510A20007938200190A000BB684 -:102F50000000000010A20007938200190A000BB6BF -:102F6000000000000E000770012020210A000C362E -:102F7000000000003C0380008C6202780440FFFEE9 -:102F80008F82001CAC62024024020002A062024454 -:102F90003C021000AC6202780A000C36000000000F -:102FA00095230006912400058D25000C8D26001028 -:102FB0008D2700188D28001C8D2900202442000137 -:102FC0003C010800A423530E3C010800A024530D2B -:102FD0003C010800AC2553143C010800AC265318F2 -:102FE0003C010800AC2753203C010800AC285324C6 -:102FF0003C010800AC2953280A000C36A3820019B2 -:103000001462000A240200813C028008344201005C -:10301000944500DA922600058F84001C30A5FFFF3E -:1030200030C600FF0A000BF73C0760211462005C09 -:10303000000000009222000A304300FF30620020AE -:1030400010400007306200403C028008344201001A -:10305000944500DA8F84001C0A000BF5240600401A -:1030600010400007000316003C02800834420100B3 -:10307000944500DA8F84001C0A000BF524060041F9 -:1030800000021603044100463C028008344201005D -:10309000944500DA8F84001C2406004230A5FFFF0F -:1030A0003C0760190E0008FA000000000A000C3608 -:1030B000000000009222000B24040016304200FFA2 -:1030C000104400063C0680009222000B24030017E7 -:1030D000304200FF144300320000000034C50100FC -:1030E00090A2000B304200FF1444000B000080212E -:1030F0008CA200208CA400202403FF800043102415 -:10310000000211403084007F004410253C03200061 -:1031100000431025ACC2083094A20008000214003D -:1031200000021403044200012410000194A20008CC -:10313000304200805040001A0200A82194A20008EA -:1031400030422000504000160200A8218CA3001835 -:103150003C021C2D344219ED106200110200A8211E -:103160003C0208008C4200D4104000053C0280085C -:103170002403000434420100A04300EC3C02800818 -:1031800034420100944500DA8F84001C24060006B6 -:1031900030A5FFFF0E0008FA3C0760210200A821BD -:1031A0000E000932000000009222000A304200089E -:1031B0001040000402A010210E0013470000000080 -:1031C00002A010218FBF00308FB5002C8FB40028D3 -:1031D0008FB300248FB200208FB1001C8FB0001875 -:1031E00003E0000827BD00382402FF80008220246D -:1031F0003C02900034420007008220253C028000FF -:10320000AC4400203C0380008C6200200440FFFEA0 -:103210000000000003E00008000000003C03800004 -:103220002402FF80008220243462000700822025CF -:10323000AC6400208C6200200440FFFE000000000F -:1032400003E00008000000003C02800824030005A1 -:1032500034420100A04300EC3C0280008C4201009B -:103260003C038000AF82001C8C6202780440FFFEA9 -:103270008F82001CAC62024024020002A062024461 -:103280003C021000AC62027803E00008000000007D -:1032900027BDFFE83C068000AFBF001034C7010027 -:1032A00094E20008304400FF3883008238820084B2 -:1032B0002C6300012C420001006218251060002DD3 -:1032C0002402008393820019504000368FBF001003 -:1032D0003C020800904253148CC401003C060800D4 -:1032E00094C6530E3045003F38A3003238A2003F49 -:1032F0002C6300012C42000100621825AF84001CE1 -:10330000AF860014A38000191460000700E020219C -:103310002402002014A20012000000003402FFFF6B -:1033200014C2000F000000002402002014A20005B7 -:1033300000E028218CE300142402FFFF5062000B00 -:103340008FBF00103C040800248453080000302183 -:103350000E0006FF240700010A000CA98FBF001011 -:103360000E000770000000008FBF00100A00093235 -:1033700027BD0018148200062482FF808CC301043C -:103380003C026020AC4300140A000CDF8FBF001029 -:10339000304200FF2C4200021040000424020022B0 -:1033A0008FBF00100A000B2027BD001814820004F4 -:1033B0008F8200248FBF00100A000C6027BD001808 -:1033C0008C42000C1040001E00E0282190E3000910 -:1033D0002402001814620003240200160A000CCA1A -:1033E00024030008146200072402001724030012BB -:1033F0003C02800834420080A04300090A000CD738 -:1034000094A700085462000794A700088F82FF9CCD -:103410002404FFFE9043000500641824A043000527 -:1034200094A7000890A6001B8CA4000094A5000699 -:103430008FBF001000073C000A0008D527BD001808 -:103440008FBF001003E0000827BD00188F850024FF -:103450003C04800094A2002A8CA30034000230C0F7 -:103460002402FFF000C2102400621821AC83003C4B -:103470008CA200303C038000AC8200383C0200503B -:1034800034420010AC620030000000000000000078 -:10349000000000008C620000304200201040FFFD60 -:1034A00030C20008104000063C0280008C62040814 -:1034B000ACA200208C62040C0A000D02ACA2002415 -:1034C0008C430400ACA300208C420404ACA2002472 -:1034D0003C0300203C028000AC4300303C048000F0 -:1034E0008C820030004310241440FFFD8F8600249E -:1034F0003C020040AC82003094C3002A94C20028F1 -:1035000094C4002C94C5002E2463000100441021B3 -:103510003064FFFFA4C2002814850002A4C3002A5F -:10352000A4C0002A03E00008000000008F840024EB -:1035300027BDFFE83C05800424840010AFBF0010C5 -:103540000E000E152406000A8F84002494820012B7 -:103550009483002E3042000F2442000300431804DD -:1035600024027FFF0043102B10400002AC830000B8 -:103570000000000D0E000CE1000000008F8300240D -:103580008FBF001027BD0018946200149463001AC6 -:103590003042000F00021500006218253C02800036 -:1035A00003E00008AC4300A08F8300243C028004A9 -:1035B000944400069462001A8C650000A46400160E -:1035C000004410233042FFFF0045102B03E00008A9 -:1035D000384200018F8400243C0780049486001A3E -:1035E0008C85000094E20006A482001694E3000695 -:1035F00000C310233042FFFF0045102B384200016A -:103600001440FFF8A483001603E000080000000047 -:103610008F8400243C028004944200069483001AA4 -:103620008C850000A4820016006210233042FFFF48 -:103630000045102B384200015040000D8F850024BA -:10364000006030213C07800494E20006A48200164A -:1036500094E3000600C310233042FFFF0045102B07 -:10366000384200011440FFF8A48300168F8500241F -:103670003C038000346204008CA40020AF82002050 -:10368000AC6400388CA20024AC62003C3C02000513 -:10369000AC62003003E00008ACA000048F8400247A -:1036A0003C0300068C8200040002114000431025F8 -:1036B0003C038000AC62003000000000000000000D -:1036C000000000008C620000304200101040FFFD3E -:1036D00034620400AC80000403E00008AF820020E4 -:1036E0008F86002427BDFFE0AFB10014AFB00010FB -:1036F000AFBF00188CC300048CC500248F8200204B -:10370000309000FF94C4001A24630001244200207A -:103710002484000124A70020ACC30004AF82002051 -:10372000A4C4001AACC7002404A10006000088212C -:1037300004E2000594C2001A8CC200202442000159 -:10374000ACC2002094C2001A94C300282E040001C9 -:10375000004310262C420001004410245040000574 -:1037600094C2001A24020001ACC2000894C2001ADC -:1037700094C300280010202B004310262C42000187 -:103780000044102514400007000000008CC200080F -:1037900014400004240200108CC300041462000FC3 -:1037A0008F8500240E000D75241100018F820024E6 -:1037B000944300289442001A1443000300000000C0 -:1037C0000E000CE100000000160000048F850024AC -:1037D0000E000D52000000008F85002494A2001EF0 -:1037E00094A4001C244200013043FFFF1464000233 -:1037F000A4A2001EA4A0001E1200000A3C02800425 -:1038000094A2001494A3001A3042000F0002150085 -:10381000006218253C028000AC4300A00A000DECB9 -:10382000ACA000089442000694A3001A8CA40000E7 -:10383000A4A20016006210233042FFFF0044102BA8 -:10384000384200011040000D02201021006030219C -:103850003C07800494E20006A4A2001694E300064C -:1038600000C310233042FFFF0044102B38420001F8 -:103870001440FFF8A4A30016022010218FBF0018E7 -:103880008FB100148FB0001003E0000827BD0020A6 -:1038900003E00008000000008F82002C3C030006BB -:1038A00000021140004310253C038000AC62003050 -:1038B0000000000000000000000000008C6200001A -:1038C000304200101040FFFD34620400AF82002837 -:1038D00003E00008AF80002C03E000080000102186 -:1038E00003E00008000000003084FFFF30A5FFFF68 -:1038F0000000182110800007000000003082000145 -:103900001040000200042042006518210A000E0B3E -:103910000005284003E000080060102110C00006E8 -:1039200024C6FFFF8CA2000024A50004AC82000086 -:103930000A000E152484000403E0000800000000C3 -:1039400010A0000824A3FFFFAC86000000000000C8 -:10395000000000002402FFFF2463FFFF1462FFFA4F -:103960002484000403E00008000000003C028008FA -:103970003442008024030001AC43000CA443001037 -:10398000A4430012A443001403E00008A44300165B -:103990008F82002427BDFFD8AFB3001CAFB2001840 -:1039A000AFB10014AFB00010AFBF00208C47000CC7 -:1039B000248200802409FF803C08800E3043007F71 -:1039C000008080213C0A80000049202400681821E2 -:1039D00030B100FF30D200FF10E000290000982134 -:1039E00026020100AD44002C004928243042007F0B -:1039F000004820219062000024030050304200FF64 -:103A00001443000400000000AD45002C948200DA4D -:103A10003053FFFF0E000D52000000008F82002483 -:103A20008F83002000112C009442001E00122400FD -:103A30003484000100A228253C02400000A2282571 -:103A4000AC7000008FBF0020AC6000048FB2001883 -:103A5000AC7300088FB10014AC60000C8FB3001C75 -:103A6000AC6400108FB00010AC600014240400019E -:103A7000AC60001827BD00280A000D86AC65001C4C -:103A80008FBF00208FB3001C8FB200188FB10014BD -:103A90008FB0001003E0000827BD00283C0680001E -:103AA00034C201009043000F240200101062000E87 -:103AB0002865001110A0000724020012240200084B -:103AC0002405003A106200060000302103E00008DF -:103AD00000000000240500351462FFFC00003021C6 -:103AE0000A000E32000000008CC200748F83FF9C1D -:103AF00024420FA003E00008AC62000C27BDFFE8E1 -:103B0000AFBF00100E000362240500013C048008D2 -:103B10008FBF00102402000134830080A4620012D1 -:103B200027BD00182402000103E00008A080001A4D -:103B300027BDFFE0AFB20018AFB10014AFB0001066 -:103B4000AFBF001C30B2FFFF0E000352008088217F -:103B50003C028008345000809202000924030004D3 -:103B6000304200FF1443000C3C0280081240000861 -:103B70002402000A0E000E29000000009202000537 -:103B80002403FFFE00431024A202000524020012B9 -:103B9000A20200093C028008344200800220202159 -:103BA0000E00035DA04000271640000302202021E4 -:103BB0000E000E8D0000000002202021324600FF82 -:103BC0008FBF001C8FB200188FB100148FB000108F -:103BD000240500380A000E3227BD002027BDFFE073 -:103BE000AFBF001CAFB20018AFB10014AFB00010EF -:103BF0000E000352008080210E000E2900000000FC -:103C00003C0280083445008090A20009241200186C -:103C1000305100FF12320003020020212402001262 -:103C2000A0A2000990A200052403FFFE0043102477 -:103C30000E00035DA0A20005020020212405002043 -:103C400016320007000030218FBF001C8FB2001811 -:103C50008FB100148FB000100A00036227BD00204E -:103C60008FBF001C8FB200188FB100148FB00010EE -:103C7000240500390A000E3227BD002027BDFFE8C9 -:103C80003C028000AFB00010AFBF0014344201000E -:103C90009442000C2405003600808021144000125C -:103CA000304600FF0E000352000000003C02800876 -:103CB0003442008024030012A04300099043000511 -:103CC000346300100E000E29A04300050E00035DB2 -:103CD00002002021020020210E00036224050020A2 -:103CE0000A000F0A000000000E000E320000000063 -:103CF0000E000352020020213C0280089043001B6A -:103D00002405FF9F02002021006518248FBF0014A6 -:103D10008FB00010A043001B0A00035D27BD0018F0 -:103D200027BDFFE0AFBF0018AFB10014AFB0001067 -:103D300030B100FF0E000352008080213C02800859 -:103D400024030012344200800E000E29A043000913 -:103D50000E00035D020020210200202102203021FC -:103D60008FBF00188FB100148FB0001024050035EC -:103D70000A000E3227BD00203C0480089083000E0C -:103D80009082000A1443000B000028218F82FF9CC0 -:103D9000240300502405000190420000304200FF3F -:103DA00014430004000000009082000E2442000131 -:103DB000A082000E03E0000800A010213C03800058 -:103DC0008C6201F80440FFFE24020002AC6401C0D2 -:103DD000A06201C43C02100003E00008AC6201F8DC -:103DE00027BDFFE0AFB200183C128008AFB100144D -:103DF000AFBF001CAFB00010365100809222000906 -:103E00002403000A304200FF1443003E000000007B -:103E10008E4300048E220038506200808FBF001C49 -:103E20009222000024030050304200FF144300257A -:103E30003C0280008C4201408E4300043642010067 -:103E400002202821AC43001C9622005C8E230038FF -:103E50003042FFFF0002104000621821AE23001C18 -:103E60008E4300048E2400389622005C00641823E0 -:103E70003042FFFF00031843000210400043102AA5 -:103E800010400006000000008E4200048E2300381F -:103E9000004310230A000F78000220439622005CA2 -:103EA0003042FFFF000220403C0280083443010002 -:103EB00034420080ACA4002CA04000242402000165 -:103EC000A062000C0E000F2C0000000010400053F8 -:103ED0008FBF001C3C0280008C4401403C038000EA -:103EE0008C6201F80440FFFE24020002AC6401C0B1 -:103EF000A06201C43C021000AC6201F80A000FD5B8 -:103F00008FBF001C9222000924030010304200FFE2 -:103F1000144300043C0280008C4401400A000FBCA2 -:103F2000000028219222000924030016304200FFDD -:103F30001443000624020014A22200093C0280005F -:103F40008C4401400A000FCF8FBF001C8E22003826 -:103F50008E23003C00431023044100308FBF001C1F -:103F60009222002724420001A22200279222002749 -:103F70002C420004144000163C10800092220009DC -:103F800024030004304200FF144300093C02800077 -:103F90008C4401408FBF001C8FB200188FB10014F9 -:103FA0008FB00010240500930A000E9A27BD002050 -:103FB0008C440140240500938FBF001C8FB2001871 -:103FC0008FB100148FB000100A000F1627BD00201B -:103FD0008E0401400E000352000000008E420004D7 -:103FE0002442FFFFAE4200048E22003C2442FFFF29 -:103FF000AE22003C0E00035D8E0401408E040140A1 -:104000008FBF001C8FB200188FB100148FB000104A -:10401000240500040A00036227BD00208FB20018A7 -:104020008FB100148FB0001003E0000827BD0020FE -:104030003C0680008CC201883C0380083465008007 -:104040009063000E00021402304400FF306300FF52 -:104050001464000E3C02800890A20026304200FF4B -:10406000104400098F82FF9CA0A400262403005066 -:1040700090420000304200FF1443000600000000A0 -:104080000A00059A8CC401803C02800834420080FA -:10409000A044002603E000080000000027BDFFE068 -:1040A00030E700FFAFB20018AFBF001CAFB1001483 -:1040B000AFB000100080902114E0000630C600FF71 -:1040C000000000000000000D000000000A00102E9B -:1040D0002400010E3C0380089062000E304200FF75 -:1040E000144600233462008090420026304200FFD4 -:1040F0001446001F000000009062000F304200FFD5 -:104100001446001B000000009062000A304200FFCD -:10411000144600038F90FF9C0000000D8F90FF9CC1 -:104120008F82FFA03C118000AE05003CAC45000032 -:10413000A066000A0E0003528E240100A200002493 -:104140000E00035D8E2401003C0380008C6201F8A8 -:104150000440FFFE24020002AC7201C0A06201C450 -:104160003C021000AC6201F80A00102F8FBF001C47 -:10417000000000000000000D0000000024000137D6 -:104180008FBF001C8FB200188FB100148FB00010C9 -:1041900003E0000827BD00208F83FF9C3C028000C5 -:1041A0008C440100344201008C65003C9046001BA9 -:1041B0000A000FF5240700013C0280089043000E1E -:1041C0009042000A00431026304200FF03E000083E -:1041D0000002102B27BDFFE03C028008AFB10014A5 -:1041E000AFB00010AFBF001834500080920200053D -:1041F00024030030304200301443008500808821C1 -:104200008F8200248C42000C104000828FBF001867 -:104210000E000D52000000008F860020ACD100007F -:104220009202000892030009304200FF00021200CF -:10423000306300FF00431025ACC200049202004D21 -:1042400000021600000216030441000500000000F1 -:104250003C0308008C6300480A00106D3C10800885 -:104260009202000830420040144000030000182170 -:1042700092020027304300FF3C1080083611008076 -:104280009222004D00031E00304200FF0002140085 -:1042900000621825ACC300088E2400308F820024F1 -:1042A000ACC4000C8E2500349443001E3C02C00BAD -:1042B000ACC50010006218258E22003800002021B5 -:1042C000ACC200148E22003CACC200180E000D8659 -:1042D000ACC3001C8E0200048F8400203C058000CB -:1042E000AC8200008E220020AC8200048E22001CD2 -:1042F000AC8200088E2200588CA300740043102169 -:10430000AC82000C8E22002CAC8200108E22004069 -:104310008E2300440002140000431025AC820014D8 -:104320009222004D24030080304200FF1443000419 -:1043300000000000AC8000180A0010B18F82002439 -:104340008E23000C240200011062000E2402FFFFE5 -:1043500092220008304200401440000A2402FFFF6D -:104360008E23000C8CA20074006218233C0208000B -:10437000006210241440000200002821006028215F -:1043800000051043AC8200188F8200240000202119 -:104390009443001E3C02C00C006218258F8200204E -:1043A0000E000D86AC43001C3C0380083462010003 -:1043B0008C4200008F850020346300808FBF00187E -:1043C000ACA20000ACA000048C6400488F820024E2 -:1043D0008FB10014ACA40008ACA0000CACA000107D -:1043E000906300059446001E3C02400D00031E0031 -:1043F00000C23025ACA300148FB00010ACA0001890 -:1044000024040001ACA6001C0A000D8627BD002074 -:104410008FBF00188FB100148FB0001003E00008A8 -:1044200027BD00203C0280009443007C3C028008B1 -:1044300034460100308400FF3065FFFF2402000590 -:1044400024A34650A0C4000C5482000C3065FFFF2A -:1044500090C2000D2C4200071040000724A30A0060 -:1044600090C3000D240200140062100400A2102169 -:104470000A0010ED3045FFFF3065FFFF3C02800869 -:104480003442008003E00008A44500143C03800887 -:1044900034680080AD050038346701008CE2001CF0 -:1044A000308400FF00A210231840000330C600FF34 -:1044B00024A2FFFCACE2001C308200015040000846 -:1044C0003C0380088D02003C00A21023044100122E -:1044D000240400058C62000410A2000F3C03800835 -:1044E0008C62000414A2001E000000003C020800C0 -:1044F0008C4200D830420020104000093C02800865 -:1045000034620080906300089042004C1443000421 -:104510003C028008240400040A0010D700000000B8 -:104520003443008034420100A040000C240200010A -:10453000A462001410C0000A3C0280008C440100F8 -:104540003C0380008C6201F80440FFFE240200025C -:10455000AC6401C0A06201C43C021000AC6201F86E -:1045600003E000080000000027BDFFE800A61823B4 -:10457000AFBF001018600080308800FF3C02800848 -:1045800034470080A0E0002434440100A0E000276C -:104590008C82001C00A21023044000560000000082 -:1045A0008CE2003C94E3005C8CE4002C004530235A -:1045B0003063FFFF00C318210083202B108000040C -:1045C00000E018218CE2002C0A00114600A2102104 -:1045D00094E2005C3042FFFF00C2102100A21021D3 -:1045E000AC62001C3C028008344400809482005C71 -:1045F0008C83001C3042FFFF0002104000A21021FB -:104600000043102B10400004000000008C82001CAE -:104610000A0011593C0680089482005C3042FFFF7A -:104620000002104000A210213C06800834C30100A3 -:1046300034C70080AC82001CA060000CACE50038E0 -:104640008C62001C00A210231840000224A2FFFC70 -:10465000AC62001C31020001104000083C038008DD -:104660008CE2003C00A21023044100122404000547 -:104670008CC2000410A200108FBF00108C620004D6 -:1046800014A2004F8FBF00103C0208008C4200D8DB -:10469000304200201040000A3C0280083462008052 -:1046A000906300089042004C144300053C028008CF -:1046B000240400048FBF00100A0010D727BD001883 -:1046C0003443008034420100A040000C2402000169 -:1046D000A46200143C0280008C4401003C03800072 -:1046E0008C6201F80440FFFE240200020A0011A6B9 -:1046F000000000008CE2001C004610230043102B39 -:1047000054400001ACE5001C94E2005C3042FFFF25 -:104710000062102B144000072402000294E2005CA7 -:104720008CE3001C3042FFFF00621821ACE3001C48 -:1047300024020002ACE500380E000F2CA082000C11 -:104740001040001F8FBF00103C0280008C4401000D -:104750003C0380008C6201F80440FFFE240200024A -:10476000AC6401C0A06201C43C021000AC6201F85C -:104770000A0011BE8FBF001031020010104000105F -:104780008FBF00103C028008344500808CA3001CC1 -:1047900094A2005C006618233042FFFF00621821DB -:1047A0003C023FFF3444FFFF0083102B54400001C4 -:1047B0000080182100C31021ACA2001C8FBF001084 -:1047C00003E0000827BD001827BDFFE800C0402116 -:1047D00000A63023AFBF001018C00026308A00FFAB -:1047E0003C028008344900808D24001C8D23002C5D -:1047F000008820230064182B1060000F344701004C -:104800008CE2002000461021ACE200208CE2002067 -:104810000044102B1440000B3C023FFF8CE20020B0 -:1048200000441023ACE200209522005C3042FFFFE0 -:104830000A0011DE00822021ACE000200086202149 -:104840003C023FFF3443FFFF0064102B5440000143 -:10485000006020213C02800834420080008518213D -:10486000AC43001CA0400024A04000270A001230E6 -:104870003C03800831420010104000433C03800894 -:104880003C06800834C400808C82003C0048102321 -:104890005840003E3466008090820024244200018B -:1048A000A0820024908200243C0308008C63002432 -:1048B000304200FF0043102B144000688FBF0010EF -:1048C00034C201008C42001C00A210231840006377 -:1048D000000000008CC300049482005C0068182370 -:1048E0003042FFFF00031843000210400043102A2B -:1048F00010400005000000008CC200040048102396 -:104900000A001213000210439482005C3042FFFF41 -:10491000000210403C068008AC82002C34C50080A8 -:1049200094A2005C8CA4002C94A3005C3042FFFF96 -:1049300000021040008220213063FFFF008320210D -:1049400001041021ACA2001C8CC2000434C601007A -:10495000ACC2001C240200020E000F2CA0C2000CEE -:104960001040003E8FBF00103C0280008C440100CC -:104970003C0380008C6201F80440FFFE2402000228 -:104980000A0012600000000034660080ACC50038E8 -:10499000346401008C82001C00A210231840000225 -:1049A00024A2FFFCAC82001C314200015040000AEE -:1049B0003C0380088CC2003C00A210230443001476 -:1049C000240400058C62000414A200033C03800848 -:1049D0000A001252240400058C62000414A2001F75 -:1049E0008FBF00103C0208008C4200D830420020EB -:1049F0001040000A3C028008346200809063000886 -:104A00009042004C144300053C028008240400043A -:104A10008FBF00100A0010D727BD00183443008054 -:104A200034420100A040000C24020001A4620014E2 -:104A30003C0280008C4401003C0380008C6201F841 -:104A40000440FFFE24020002AC6401C0A06201C465 -:104A50003C021000AC6201F88FBF001003E00008B8 -:104A600027BD001827BDFFE83C0A8008AFBF001033 -:104A7000354900808D22003C00C04021308400FF79 -:104A8000004610231840009D30E700FF3547010025 -:104A90002402000100A63023A0E0000CA0E0000DDD -:104AA000A522001418C00024308200108D23001CA1 -:104AB0008D22002C006818230043102B1040000F9B -:104AC000000000008CE2002000461021ACE2002033 -:104AD0008CE200200043102B1440000B3C023FFFEF -:104AE0008CE2002000431023ACE200209522005C01 -:104AF0003042FFFF0A00128F00621821ACE0002054 -:104B0000006618213C023FFF3446FFFF00C3102B14 -:104B10005440000100C018213C028008344200804B -:104B200000651821AC43001CA0400024A0400027D1 -:104B30000A0012DD3C038008104000403C0380085E -:104B40008D22003C004810235840003D346700800F -:104B50009122002424420001A12200249122002459 -:104B60003C0308008C630024304200FF0043102BFC -:104B70001440009A8FBF00108CE2001C00A210238A -:104B800018400096000000008D4300049522005C50 -:104B9000006818233042FFFF000318430002104052 -:104BA0000043102A10400005012020218D420004FE -:104BB000004810230A0012C0000210439522005C36 -:104BC0003042FFFF000210403C068008AC82002CFF -:104BD00034C5008094A2005C8CA4002C94A3005CDB -:104BE0003042FFFF00021040008220213063FFFFAF -:104BF0000083182101031021ACA2001C8CC2000408 -:104C000034C60100ACC2001C240200020E000F2CAE -:104C1000A0C2000C104000718FBF00103C02800049 -:104C20008C4401003C0380008C6201F80440FFFECC -:104C3000240200020A00130700000000346700800D -:104C4000ACE50038346601008CC2001C00A21023C1 -:104C50001840000224A2FFFCACC2001C30820001FC -:104C6000504000083C0380088CE2003C00A2102366 -:104C700004430051240400058C62000410A2003E8D -:104C80003C0380088C62000454A200548FBF0010C3 -:104C90003C0208008C4200D8304200201040000640 -:104CA0003C02800834620080906300089042004C0F -:104CB000104300403C02800834430080344201002D -:104CC000A040000C24020001A46200143C028000F9 -:104CD0008C4401003C0380008C6201F80440FFFE1C -:104CE00024020002AC6401C0A06201C43C021000B6 -:104CF000AC6201F80A0013458FBF001024020005C2 -:104D0000A120002714E2000A3C038008354301007B -:104D10009062000D2C420006504000053C038008C4 -:104D20009062000D24420001A062000D3C03800847 -:104D300034670080ACE50038346601008CC2001C8A -:104D400000A210231840000224A2FFFCACC2001CE9 -:104D5000308200015040000A3C0380088CE2003C95 -:104D600000A2102304410014240400058C620004F6 -:104D700014A200033C0380080A00133C240400052D -:104D80008C62000414A200158FBF00103C020800C2 -:104D90008C4200D8304200201040000A3C028008BB -:104DA00034620080906300089042004C1443000578 -:104DB0003C028008240400048FBF00100A0010D7B2 -:104DC00027BD00183443008034420100A040000C8D -:104DD00024020001A46200148FBF001003E0000849 -:104DE00027BD00183C0B800827BDFFE83C0280006F -:104DF000AFBF001034420100356A00809044000AC1 -:104E0000356901008C4500148D4800389123000C51 -:104E1000308400FF010510231C4000B3306700FF01 -:104E20002CE20006504000B18FBF001024020001A8 -:104E300000E2300430C200035440000800A83023D0 -:104E400030C2000C144000A130C20030144000A356 -:104E50008FBF00100A0014090000000018C00024D1 -:104E6000308200108D43001C8D42002C00681823F6 -:104E70000043102B1040000F000000008D22002086 -:104E800000461021AD2200208D2200200043102B6F -:104E90001440000B3C023FFF8D22002000431023F2 -:104EA000AD2200209542005C3042FFFF0A00137DD6 -:104EB00000621821AD200020006618213C023FFF4F -:104EC0003446FFFF00C3102B5440000100C01821DE -:104ED0003C0280083442008000651821AC43001C6D -:104EE000A0400024A04000270A0013CB3C03800808 -:104EF000104000403C0380088D42003C00481023D5 -:104F00001840003D34670080914200242442000193 -:104F1000A1420024914200243C0308008C63002439 -:104F2000304200FF0043102B144000708FBF001070 -:104F30008D22001C00A210231840006C000000000D -:104F40008D6300049542005C006818233042FFFF27 -:104F500000031843000210400043102A10400005CF -:104F6000014020218D620004004810230A0013AE86 -:104F7000000210439542005C3042FFFF00021040E7 -:104F80003C068008AC82002C34C5008094A2005CF2 -:104F90008CA4002C94A3005C3042FFFF0002104060 -:104FA000008220213063FFFF0083182101031021BC -:104FB000ACA2001C8CC2000434C60100ACC2001CB0 -:104FC000240200020E000F2CA0C2000C104000476B -:104FD0008FBF00103C0280008C4401003C03800025 -:104FE0008C6201F80440FFFE240200020A0013FB59 -:104FF0000000000034670080ACE500383466010032 -:105000008CC2001C00A210231840000224A2FFFC46 -:10501000ACC2001C308200015040000A3C038008F2 -:105020008CE2003C00A21023044300142404000579 -:105030008C62000414A200033C0380080A0013EDF4 -:10504000240400058C62000414A200288FBF001005 -:105050003C0208008C4200D8304200201040000A78 -:105060003C02800834620080906300089042004C4B -:10507000144300053C028008240400048FBF001084 -:105080000A0010D727BD00183443008034420100C5 -:10509000A040000C24020001A46200143C02800025 -:1050A0008C4401003C0380008C6201F80440FFFE48 -:1050B00024020002AC6401C0A06201C43C021000E2 -:1050C000AC6201F80A0014098FBF00108FBF0010F6 -:1050D000010030210A00112827BD001801003021ED -:1050E0000A00126727BD00188FBF001003E00008F8 -:1050F00027BD00183C03800834640100240200032B -:10510000A082000C8C62000403E00008AC82001C4A -:105110003C05800834A300809062002734A501007C -:105120002406004324420001A06200279063002768 -:105130003C0208008C420048306300FF1462000407 -:105140003C07602194A500DA0A0008FA30A5FFFFA9 -:1051500003E000080000000027BDFFE8AFBF00101B -:105160003C0280000E0014128C4401803C02800836 -:1051700034430100A060000C8C4200048FBF00107B -:1051800027BD001803E00008AC62001C27BDFFE04B -:105190003C028008AFBF0018AFB10014AFB00010E0 -:1051A00034450080344601003C0880008D090140F0 -:1051B00090C3000C8CA4003C8CA200381482003BED -:1051C000306700FF9502007C90A30027146000095F -:1051D0003045FFFF2402000554E200083C0480082B -:1051E00090C2000D24420001A0C2000D0A00144D1F -:1051F0003C048008A0C0000D3C04800834820100FB -:105200009042000C24030005304200FF1443000AC2 -:1052100024A205DC34830080906200272C42000722 -:105220005040000524A20A009063002724020014C5 -:105230000062100400A210213C108008361000808B -:105240003045FFFF012020210E001412A605001496 -:105250009602005C8E0300383C1180003042FFFF54 -:105260000002104000621821AE03001C0E00035221 -:105270008E2401409202002534420040A202002503 -:105280000E00035D8E2401408E2401403C0380000B -:105290008C6201F80440FFFE24020002AC6401C0ED -:1052A000A06201C43C021000AC6201F88FBF00187C -:1052B0008FB100148FB0001003E0000827BD00205C -:1052C00080080100800800808008000000000C8039 -:1052D000000032008008024008000F1008000F682C -:1052E00008000FAC0800104408001084800801007A -:0852F000800800808008000026 -:0852F8000A0000220000000082 -:10530000000000000000000D6370352E302E306A62 -:10531000313500000500000400000000000000001E -:1053200000000000000000000000000038003C0009 -:10533000000000000000000000000000000000006D -:10534000000000200000000000000000000000003D -:10535000000000000000000000000000000000004D -:1053600000000000000000000000000021003800E4 -:10537000000000010000002B000000000000000001 -:105380000000000010000003000000000000000DFD -:105390000000000D3C020800244255043C030800B4 -:1053A00024635744AC4000000043202B1480FFFDD1 -:1053B000244200043C1D080037BD9FFC03A0F021DF -:1053C0003C100800261000883C1C0800279C55044F -:1053D0000E00029A000000000000000D00A018213D -:1053E00000801021008028213C0460003C07600000 -:1053F0002406000810600006348420788C420000E7 -:10540000ACE220088C63000003E00008ACE3200C51 -:105410000A000E6000000000240300403C0260000F -:1054200003E00008AC4320003C0760008F860004C6 -:105430008CE520740086102100A2182B1460000750 -:10544000000028218F8AFD9024050001A14400134B -:105450008F89000401244021AF88000403E0000884 -:1054600000A010218F84FD908F850004908600138A -:1054700030C300FF00A31023AF82000403E0000844 -:10548000A08000138F84FD9027BDFFE8AFB000100F -:10549000AFBF0014908900119087001124020028EA -:1054A000312800FF3906002830E300FF2485002C56 -:1054B0002CD00001106200162484001C0E0000395C -:1054C000000000008F8FFD903C0560002402020464 -:1054D00095EE003E95ED003C000E5C0031ACFFFF08 -:1054E000016C5025ACAA20105200000124020004D7 -:1054F000ACA220000000000000000000000000003E -:105500008FBF00148FB0001003E0000827BD001803 -:105510000A000071000028218F85FD9027BDFFD86B -:10552000AFBF0020AFB3001CAFB20018AFB1001482 -:10553000AFB000100080982190A4001124B0001C8E -:1055400024B1002C308300FF386200280E00005B7D -:105550002C5200010E000063000000000200202118 -:105560001240000202202821000028210E000039EC -:10557000000000008F8DFD903C0880003C0560001D -:1055800095AC003E95AB003C02683025000C4C0009 -:10559000316AFFFF012A3825ACA72010240202023D -:1055A000ACA6201452400001240200028FBF00204C -:1055B0008FB3001C8FB200188FB100148FB0001091 -:1055C00027BD002803E00008ACA2200027BDFFE0B3 -:1055D000AFB20018AFB10014AFB00010AFBF001CE5 -:1055E0003C1160008E2320748F82000430D0FFFFB6 -:1055F00030F2FFFF1062000C2406008F0E0000390D -:10560000000000003C06801F0010440034C5FF006D -:105610000112382524040002AE272010000030219A -:10562000AE252014AE2420008FBF001C8FB20018BE -:105630008FB100148FB0001000C0102103E00008EB -:1056400027BD002027BDFFE0AFB0001030D0FFFF26 -:10565000AFBF0018AFB100140E00003930F1FFFFEA -:1056600000102400009180253C036000AC702010E5 -:105670008FBF00188FB100148FB0001024020004F7 -:10568000AC62200027BD002003E0000800001021CC -:1056900027BDFFE83C0B6018AFBF00108D6F5000B6 -:1056A0002418FF7F340C807101F8702435CD380C3C -:1056B000240A00313C098000AD6D50003C08800A8E -:1056C000AD6C53BCAD2A00080E0004D1AF88004079 -:1056D0000E00048F000000000E00004800000000D3 -:1056E0003C0760008CE508082406FFF03C035709DE -:1056F00000A620243462F000108200622419000108 -:10570000AF80004C0E000BF2000000003C0660165B -:105710003C0760148CC400008CE500A03C03FFFF34 -:10572000008310243C1F535300052FC2105F004F0D -:1057300034C77C0094E201F2A780006410400003AB -:10574000A7800074384B1E1EA78B006494E201F8FA -:10575000104000048F8D004C384C1E1EA78C007426 -:105760008F8D004C11A0000497840074240E00203B -:10577000A78E0064978400742C8F008151E0000193 -:1057800024040080978600642CD804015300000193 -:10579000240604003C0260008C4504382419103CA7 -:1057A00030BFFFFF13F900033083FFFF10600018C4 -:1057B00024080050A38000769389007651200019B8 -:1057C000A7840074A7800074978C00748FBF0010AA -:1057D0003C0A600E24EB0388354600100000382197 -:1057E0000000202127BD0018A78000643C010800AC -:1057F000AC2C0080AF8B0010AF860048A780006CF7 -:10580000A780008AAF87001803E00008AF84001467 -:10581000A3880076938900765520FFEBA78000745B -:10582000A7840074978C00748FBF00103C0A600E30 -:1058300024EB0388A7860064000038213546001059 -:105840000000202127BD00183C010800AC2C00807E -:10585000AF8B0010AF860048A780006CA780008A3D -:10586000AF87001803E00008AF84001400055080E3 -:10587000014648218D2800043C0660000A00010F03 -:10588000010638210A000103AF99004C3083FFFF65 -:105890008F8800408F87003C000321403C0580003A -:1058A0003C020050008248253C0660003C0A010092 -:1058B00034AC04008CCD08E001AA58241160000526 -:1058C000000000008CCF08E024E7000101EA702509 -:1058D000ACCE08E08D19001001805821ACB9003819 -:1058E0008D180014ACB8003CACA9003000000000DA -:1058F00000000000000000000000000000000000A8 -:105900000000000000000000000000003C038000D8 -:105910008C640000308200201040FFFD3C0F6000CE -:105920008DED08E03C0E010001AE18241460FFE18B -:1059300000000000AF87003C03E00008AF8B005080 -:105940008F850040240BFFF03C06800094A7001ACE -:105950008CA9002430ECFFFF000C38C000EB502471 -:10596000012A4021ACC8003C8CA400248CC3003C1C -:105970000083102318400033000000008CAD00208D -:1059800025A200013C0F0050ACC2003835EE0010DB -:105990003C068000ACCE003000000000000000009B -:1059A00000000000000000000000000000000000F7 -:1059B00000000000000000003C0480008C99000002 -:1059C000333800201300FFFD30E2000810400017BC -:1059D0003C0980008C880408ACA800108C83040C5F -:1059E000ACA300143C1900203C188000AF19003013 -:1059F00094AE001894AF001C01CF3021A4A600186B -:105A000094AD001A25A70001A4A7001A94AB001AB0 -:105A100094AC001E118B00030000000003E000089E -:105A20000000000003E00008A4A0001A8D2A040072 -:105A3000ACAA00108D240404ACA400140A0001BC1C -:105A40003C1900208CA200200A0001A43C0F005049 -:105A50000A0001920000000027BDFFE8AFBF001060 -:105A60000E0001D6000000008F8900408FBF00109B -:105A70003C038000A520000A9528000A9527000411 -:105A800027BD00183105FFFF30E6000F00061500A6 -:105A900000A2202503E00008AC6400803C0508005B -:105AA0008CA500208F83000C27BDFFE8AFB000104D -:105AB000AFBF001410A300100000802124040001D7 -:105AC0000204300400A6202400C310245044000621 -:105AD00026100001001018802787FD941480000A0A -:105AE00000671821261000012E0900025520FFF33F -:105AF0008F83000CAF85000C8FBF00148FB0001097 -:105B000003E0000827BD00188C6800003C058000F9 -:105B1000ACA800240E0001D8261000013C050800A6 -:105B20008CA500200A0001FD2E09000224050001B9 -:105B3000008518043C0408008C84002027BDFFC8A1 -:105B4000AFBF003400831024AFBE0030AFB7002CCD -:105B5000AFB60028AFB50024AFB40020AFB3001C2F -:105B6000AFB20018AFB1001410400051AFB0001038 -:105B70008F840040948700069488000A00E8302350 -:105B800030D5FFFF12A0004B8FBF0034948B00185C -:105B9000948C000A016C50233142FFFF02A2482B73 -:105BA0001520000202A02021004020212C8F00059A -:105BB00015E0000200809821241300040E00016506 -:105BC000026020218F87004002609021AF80004456 -:105BD00094F4000A026080211260004E3291FFFFAF -:105BE0003C1670003C1440003C1E20003C17600036 -:105BF0008F9900508F380000031618241074004F3E -:105C00000283F82B17E0003600000000107E0047EA -:105C10008F86004414C0003A2403000102031023BD -:105C2000022320213050FFFF1600FFF13091FFFFCB -:105C30008F8700403C1100203C108000AE110030E6 -:105C400094EB000A3C178000024B5021A4EA000AA2 -:105C500094E9000A94E800043123FFFF3106000FA5 -:105C600000062D000065F025AEFE008094F3000ACA -:105C700094F6001812D30036001221408CFF001455 -:105C80008CF4001003E468210000C02101A4782BEB -:105C90000298702101CF6021ACED0014ACEC001033 -:105CA00002B2382330F5FFFF16A0FFB88F84004002 -:105CB0008FBF00348FBE00308FB7002C8FB6002806 -:105CC0008FB500248FB400208FB3001C8FB2001852 -:105CD0008FB100148FB0001003E0000827BD00381A -:105CE0001477FFCC8F8600440E000DC102002021E6 -:105CF000004018218F86004410C0FFC90203102302 -:105D0000027070238F87004001C368210A00028857 -:105D100031B2FFFF8F86004414C0FFC93C11002040 -:105D20003C1080000A000252AE1100300E0003FA4F -:105D3000020020210A00027F0040182102002021D9 -:105D40000E000811022028210A00027F00401821BD -:105D50000E000192000000000A00026B02B238231C -:105D600027BDFFC8AFB7002CAFB60028AFB50024E1 -:105D7000AFB40020AFB3001CAFB20018AFB1001435 -:105D8000AFB00010AFBF00300E0000E624130001DA -:105D90003C047FFF3C0380083C0220003C010800DB -:105DA000AC2000703497FFFF34750080345200033C -:105DB0003C1612C0241400013C1080002411FF8006 -:105DC0000E0001E9000000008F8700488F8B00184B -:105DD0008F8900148CEA00EC8CE800E8014B302B32 -:105DE0000109282300A6102314400006014B1823A4 -:105DF0001440000E3C05800002C3602B1180000B94 -:105E0000000000003C0560008CEE00EC8CED00E82A -:105E10008CA4180CAF8E001804800045AF8D0014C0 -:105E20008F8F0010ADF400003C0580008CBF000097 -:105E30003BF90001333800011700FFE13C0380000B -:105E40008C62010024060C001046000900000000CE -:105E50008C6801002D043080548000103C048000C8 -:105E60008C6901002D2331811060000C3C048000FE -:105E70008CAA010011460004000020218CA601001C -:105E800024C5FF8130A400FF8E0B01000E00020D1F -:105E9000AE0B00240A0002F33C0480008C8E01004B -:105EA000240C0020AC8E002092AD000031A300FF36 -:105EB000106C00232407005010670026000000002B -:105EC0003C0480008C8F010015E0000300000000FE -:105ED000566000143C0440008C8701008C8D01004A -:105EE0000000982100F17024000E594031AC007F71 -:105EF000016C302500D22825AC8508308C8A010041 -:105F00008C83010025490100013110240002F94071 -:105F10003068007F03E8C8250332C025AC980830FC -:105F20003C044000AE0401380A0002B20000000048 -:105F300000973824ACA7180C0A0002CB8F8F0010F2 -:105F40008C8501000E0007C3240400800A0002F3C0 -:105F50003C0480008C8401000E001420000000002E -:105F60000A0002F33C04800000A4102B240300016B -:105F700010400009000030210005284000A4102B2B -:105F800004A00003000318405440FFFC0005284013 -:105F90005060000A0004182B0085382B54E00004E0 -:105FA0000003184200C33025008520230003184257 -:105FB0001460FFF9000528420004182B03E00008D4 -:105FC00000C310213084FFFF30C600FF3C07800073 -:105FD0008CE201B80440FFFE00064C00012430258D -:105FE0003C08200000C820253C031000ACE00180E4 -:105FF000ACE50184ACE4018803E00008ACE301B83F -:106000003C0660008CC5201C2402FFF03083020097 -:10601000308601001060000E00A2282434A5000183 -:106020003087300010E0000530830C0034A50004F8 -:106030003C04600003E00008AC85201C1060FFFDFC -:106040003C04600034A5000803E00008AC85201C77 -:1060500054C0FFF334A500020A00034B3087300020 -:1060600027BDFFE8AFB00010AFBF00143C076000D1 -:10607000240600021080001100A080218F830050B0 -:106080000E0003428C6400188F8200500000202113 -:10609000240600018C45000C0E00033300000000B4 -:1060A0001600000224020003000010218FBF00141C -:1060B0008FB0001003E0000827BD00188CE8201CFA -:1060C0002409FFF001092824ACE5201C8F8700502B -:1060D0000A0003688CE5000C3C02600E0080402141 -:1060E00034460100240900180000000000000000F0 -:1060F000000000003C0A00503C03800035470200CD -:10610000AC68003834640400AC65003CAC67003017 -:106110008C6C0000318B00201160FFFD2407FFFF15 -:106120002403007F8C8D00002463FFFF248400047F -:10613000ACCD00001467FFFB24C600040000000083 -:10614000000000000000000024A402000085282BAD -:106150003C0300203C0E80002529FFFF0105402163 -:10616000ADC300301520FFE00080282103E00008C7 -:10617000000000008F82005027BDFFD8AFB3001C85 -:10618000AFBF0020AFB20018AFB10014AFB0001025 -:1061900094460002008098218C5200182CC3008184 -:1061A0008C4800048C4700088C51000C8C4900106E -:1061B000106000078C4A00142CC4000414800013E3 -:1061C00030EB000730C5000310A0001000000000F5 -:1061D0002410008B02002021022028210E0003330E -:1061E00024060003166000022402000300001021B0 -:1061F0008FBF00208FB3001C8FB200188FB1001426 -:106200008FB0001003E0000827BD00281560FFF1E3 -:106210002410008B3C0C80003C030020241F000154 -:10622000AD830030AF9F004400000000000000007C -:10623000000000002419FFF024D8000F031978246F -:106240003C1000D0AD88003801F0702524CD00034B -:106250003C08600EAD87003C35850400AD8E0030F3 -:10626000000D38823504003C3C0380008C6B00003C -:10627000316200201040FFFD0000000010E0000827 -:1062800024E3FFFF2407FFFF8CA800002463FFFF27 -:1062900024A50004AC8800001467FFFB24840004DC -:1062A0003C04600EAC8600380000000000000000D6 -:1062B000000000003C0700203C0680000120202157 -:1062C00001402821ACC700300E0003780000802177 -:1062D0000E000342024020210A0003B802002021E0 -:1062E00027BDFFE0AFB200183092FFFFAFB100143E -:1062F000AFBF001CAFB000101640000D0000882199 -:106300000A000427022010212405000350850027DD -:106310008CE5000C0000000D262C00013191FFFFE0 -:1063200024EB00200232502B11400019AF8B00509B -:106330008F820044144000168F8700503C06700086 -:106340003C0320008CE5000000A6202414830010EC -:106350008F840058000544023C09800000A9802475 -:106360001480FFE9310600FF2CCA000B1140FFEB3F -:10637000262C0001000668803C0E080025CE52A0A5 -:1063800001AE60218D8B000001600008000000005C -:10639000022010218FBF001C8FB200188FB1001493 -:1063A0008FB0001003E0000827BD00200E0003336B -:1063B000240400841600FFD88F8700500A000408C8 -:1063C000AF800058020028210E00035A2404000167 -:1063D0008F8700500A000408AF820058020028216D -:1063E0000E00035A000020210A0004378F87005056 -:1063F0000E00039F020020218F8700500A0004082E -:10640000AF82005830AFFFFF000F19C03C0480007E -:106410008C9001B80600FFFE3C1920043C181000C7 -:10642000AC830180AC800184AC990188AC9801B840 -:106430000A000409262C000190E2000290FF0003EC -:106440000000202100023A0000FF28252406000851 -:106450000E000333000000001600FFDD24020003DD -:106460008F870050000010210A000408AF820058F6 -:1064700090E50002000020210A00045624060009CD -:1064800094E5000490E9000390E300020005340065 -:106490000009420000C82025008328252406000AA0 -:1064A0000A0004560000202190E50002000020218F -:1064B0000A0004562406000B000449C23127003F9D -:1064C000000443423C028000000820402403168060 -:1064D0002CE60020AC43002C24EAFFE024820001DB -:1064E00014C0000330A900FF00801021314700FFD5 -:1064F000000260803C0D8000240A0001018D2021F3 -:106500003C0B000E00EA2804008B3021112000050E -:10651000000538278CCE000001C5382503E00008AF -:10652000ACC700008CD800000307782403E0000803 -:10653000ACCF000027BDFFE0AFB10014AFB000103A -:10654000AFBF00183C0760008CE408083402F0007C -:106550003C1160003083F000240501C03C04800E33 -:106560000000302110620006241000018CEA0808A7 -:106570003149F0003928E0000008382B000780403E -:106580003C0D0200AE2D0814240C16803C0B80003C -:106590008E2744000E000E6AAD6C002C1200000421 -:1065A0003C02169124050001120500103C023D6CCE -:1065B000345800E0AE3844083C1108008E31007CAD -:1065C0008FBF00183C06600000118540360F168012 -:1065D0008FB100148FB000103C0E020027BD0020C8 -:1065E000ACCF442003E00008ACCE08103C0218DA1F -:1065F000345800E0AE3844083C1108008E31007C6D -:106600008FBF00183C06600000118540360F1680D1 -:106610008FB100148FB000103C0E020027BD002087 -:10662000ACCF442003E00008ACCE08100A00047090 -:10663000240500010A00047000002821240204003F -:10664000A7820024A780001C000020213C0608002F -:1066500024C655A82405FFFF2489000100044080BA -:106660003124FFFF010618212C87002014E0FFFAD7 -:10667000AC65000024040400A7840026A780001E47 -:10668000000020213C06080024C656282405FFFFF0 -:10669000248D00010004608031A4FFFF0186582191 -:1066A0002C8A00201540FFFAAD650000A780002865 -:1066B000A7800020A7800022000020213C060800BF -:1066C00024C656A82405FFFF249900010004C080B9 -:1066D0003324FFFF030678212C8E000415C0FFFA37 -:1066E000ADE500003C0560008CA73D002403E08F71 -:1066F00000E310243446014003E00008ACA63D004E -:106700002487007F000731C224C5FFFF000518C29F -:10671000246400013082FFFF000238C0A7840030EB -:106720003C010800AC270030AF80002C000028217D -:1067300000002021000030212489000100A7282129 -:106740003124FFFF2CA81701110000032C830080C7 -:106750001460FFF924C6000100C02821AF86002C78 -:1067600010C0001DA786002A24CAFFFF000A11429C -:106770003C080800250856A81040000A0000202107 -:10678000004030212407FFFF248E000100046880B0 -:1067900031C4FFFF01A860210086582B1560FFFA65 -:1067A000AD87000030A2001F504000080004308078 -:1067B000240300010043C80400041080004878212D -:1067C0002738FFFF03E00008ADF8000000C82021D3 -:1067D0002405FFFFAC85000003E000080000000076 -:1067E00030A5FFFF30C6FFFF30A8001F00806021EA -:1067F00030E700FF000529420000502110C0001DB5 -:1068000024090001240B000125180001010B2004BC -:10681000330800FF01267826390E00202DED0001F7 -:106820002DC2000101A218251060000D0144502561 -:106830000005C880032C40210100182110E0000F42 -:10684000000A20278D040000008A1825AD030000EF -:1068500024AD0001000040210000502131A5FFFFC0 -:10686000252E000131C9FFFF00C9102B1040FFE7A2 -:106870002518000103E00008000000008D0A000058 -:10688000014440240A000556AC68000027BDFFE81B -:1068900030A5FFFF30C6FFFFAFB00010AFBF001440 -:1068A00030E7FFFF000050213410FFFF000060219F -:1068B00024AF001F00C04821241800012419002023 -:1068C00005E0001601E010210002F943019F682A4B -:1068D0000009702B01AE402411000017000C188035 -:1068E0000064102110E000058C4B000000F840040B -:1068F0000008382301675824000038211540004162 -:1069000000004021556000163169FFFF258B000112 -:10691000316CFFFF05E1FFEC01E0102124A2003EF5 -:106920000002F943019F682A0009702B01AE402440 -:106930001500FFEB000C1880154600053402FFFF20 -:10694000020028210E00053A000038210200102123 -:106950008FBF00148FB0001003E0000827BD00189F -:106960001520000301601821000B1C0224080010F0 -:10697000306A00FF15400005306E000F250D00083D -:1069800000031A0231A800FF306E000F15C0000589 -:10699000307F00032510000400031902320800FFB5 -:1069A000307F000317E0000538690001250200026E -:1069B00000031882304800FF3869000131230001CC -:1069C00010600004310300FF250A0001314800FF78 -:1069D000310300FF000C694001A34021240A00019B -:1069E00010CAFFD53110FFFF246E000131C800FF2F -:1069F0001119FFC638C900012D1F002053E0001CEB -:106A0000258B0001240D00010A0005CD240E002075 -:106A100051460017258B000125090001312800FF90 -:106A20002D09002051200012258B00012543000173 -:106A3000010D5004014B1024250900011440FFF4FE -:106A4000306AFFFF3127FFFF10EE000C2582FFFFA9 -:106A5000304CFFFF000050213410FFFF312800FFB1 -:106A60002D0900205520FFF225430001258B000150 -:106A7000014648260A000587316CFFFF00003821D7 -:106A8000000050210A0005D93410FFFF27BDFFD8B0 -:106A9000AFB0001030F0FFFFAFB10014001039426A -:106AA0003211FFE000071080AFB3001C00B12823B3 -:106AB00030D3FFFFAFB2001830A5FFFF0080902158 -:106AC0000260302100442021AFBF00200E00056588 -:106AD0003207001F022288213403FFFF02402021D9 -:106AE00002002821026030210000382110430009F3 -:106AF0003231FFFF022010218FBF00208FB3001C16 -:106B00008FB200188FB100148FB0001003E000089E -:106B100027BD00280E000565000000000040882108 -:106B2000022010218FBF00208FB3001C8FB20018ED -:106B30008FB100148FB0001003E0000827BD0028BB -:106B4000000424003C036000AC603D0810A000027B -:106B5000348210063482101603E00008AC623D0453 -:106B600027BDFFE0AFB00010309000FF2E020006FE -:106B7000AFBF001810400008AFB100140010308003 -:106B80003C030800246352CC00C328218CA40000DD -:106B90000080000800000000000020218FBF0018C6 -:106BA0008FB100148FB000100080102103E00008A6 -:106BB00027BD00209791002A1620005100002021B7 -:106BC0003C020800904200330A000640000000002A -:106BD000978D002615A00031000020210A000640F4 -:106BE000240200089787002414E0001A00001821EE -:106BF00000602021240200011080FFE98FBF0018EF -:106C0000000429C20045302100A6582B1160FFE482 -:106C10003C0880003C072000000569C001A76025F2 -:106C2000AD0C00203C0380082402001F2442FFFF1B -:106C3000AC6000000441FFFD2463000424A50001B2 -:106C400000A6702B15C0FFF5000569C00A00062AD2 -:106C50008FBF00189787001C3C040800248455A8A7 -:106C6000240504000E0005E524060001978B00248E -:106C700024440001308AFFFF2569FFFF2D480400EE -:106C80000040282115000040A789002424AC3800CA -:106C9000000C19C00A00063EA780001C9787001E42 -:106CA0003C04080024845628240504000E0005E551 -:106CB0002406000197990026244400013098FFFF24 -:106CC000272FFFFF2F0E04000040882115C0002C45 -:106CD000A78F0026A780001E3A0200032624010089 -:106CE0003084FFFF0E0006122C4500010011F8C091 -:106CF00027F00100001021C00A000640240200080D -:106D00009785002E978700223C040800248456A80B -:106D10000E0005E5240600019787002A8F89002CC4 -:106D20002445000130A8FFFF24E3FFFF0109302BB9 -:106D30000040802114C00018A783002AA7800022E9 -:106D4000978500300E000E5402002021244A0500D1 -:106D50003144FFFF0E000612240500013C05080027 -:106D600094A500320E000E5402002021244521007B -:106D70003C020800904200330A000640000521C092 -:106D80000A000678A784001E24AC3800000C19C045 -:106D90000A00063EA784001C0A000692A78500226E -:106DA000308400FF27BDFFE82C820006AFBF00142F -:106DB000AFB000101040001500A038210004408042 -:106DC0003C030800246352E4010328218CA4000042 -:106DD000008000080000000024CC007F000751C2A2 -:106DE000000C59C23170FFFF2547C40030E5FFFF9A -:106DF0002784001C020030210E00053A2407000100 -:106E00009786002802062021A78400288FBF00143F -:106E10008FB0001003E0000827BD00183C050800F3 -:106E20008CA50030000779C20E00031C25E4DF00AA -:106E30003045FFFF3C040800248456A824060001C6 -:106E40000E00053A24070001978E002A8FBF001418 -:106E50008FB0001025CD000127BD001803E0000809 -:106E6000A78D002A0007C9C22738FF00001878C282 -:106E700031F0FFFF3C04080024845628020028213A -:106E8000240600010E00053A24070001978D002614 -:106E9000260E0100000E840025AC00013C0B6000B2 -:106EA000A78C0026AD603D083604000600003021A6 -:106EB0003C0760008CE23D04305F000617E0FFFDF8 -:106EC00024C9000100061B00312600FF0064402594 -:106ED0002CC50004ACE83D0414A0FFF68FBF0014DD -:106EE0008FB0001003E0000827BD0018000751C252 -:106EF0002549C80024060001240700013C040800BD -:106F0000248455A80E00053A3125FFFF97870024F9 -:106F10008FBF00148FB0001024E6000127BD0018B9 -:106F200003E00008A78600243084FFFF30A5FFFFA0 -:106F30003C0680008CC201B80440FFFE3C08408043 -:106F4000008838253C031000ACC00180ACC501842A -:106F5000ACC7018803E00008ACC301B83084FFFF70 -:106F60003C0680008CC201B80440FFFE3C0840385B -:106F70008CA70000008828253C031000ACC70180C6 -:106F8000ACC5018803E00008ACC301B88F83007072 -:106F90008F8600681066000B008040213C070800C7 -:106FA00024E756B8000328C000A710218C44000035 -:106FB00024630001108800053063000F5466FFFA57 -:106FC000000328C003E00008000010213C0708006F -:106FD00024E756BC00A7302103E000088CC2000063 -:106FE0003C03900034620001008220253C038000B5 -:106FF000AC6400208C65002004A0FFFE00000000AF -:1070000003E00008000000003C028000344300015F -:107010000083202503E00008AC44002027BDFFE0EA -:10702000AFB100143091FFFFAFB00010AFBF001838 -:107030001220001200A080218CA5000014A00011D5 -:10704000240400023C0680008CC201B80440FFFE0C -:107050003C074000022720258FBF00188FB1001485 -:107060008FB000103C03100027BD0020ACC501808C -:10707000ACC4018803E00008ACC301B80A000753A0 -:107080008CA500000E0006AA24060200000028219C -:107090000A000753AE0000003087FFFF3C06800067 -:1070A0008CC201B80440FFFE3C0A40068CA90000D7 -:1070B00000EA4025ACC901808CA400043C03100008 -:1070C000ACC40184ACC8018803E00008ACC301B8BB -:1070D0008F83FD8C27BDFFE8AFBF0014AFB0001059 -:1070E00090670008008010210080282130E60040D1 -:1070F0000000202110C000088C5000000E00008805 -:1071000002002021020020218FBF00148FB0001048 -:107110000A0004CD27BD00180E000768000000001B -:107120000E00008802002021020020218FBF0014E1 -:107130008FB000100A0004CD27BD001827BDFFE066 -:10714000AFB000108F90FD8CAFBF001CAFB2001825 -:10715000AFB1001492060001008088210E00073AAA -:1071600030D2000492040005001129C2A6050000D7 -:1071700034830040A20300050E00074402202021B2 -:107180000E0004CF0220202124020001AE02000CD8 -:1071900002202821A602001024040002A6020012E8 -:1071A00024060200A60200140E0006AAA60200167B -:1071B0001640000F8FBF001C978C006C3C0B080022 -:1071C0008D6B00782588FFFF3109FFFF256A0001DC -:1071D000012A382B10E00006A788006C3C0F6006DF -:1071E000240E001635ED0010ADAE00508FBF001C10 -:1071F0008FB200188FB100148FB0001003E00008A8 -:1072000027BD002027BDFFE0AFB10014AFBF0018BD -:10721000AFB000101080000400A08821240200807C -:1072200010820007000000000000000D8FBF001852 -:107230008FB100148FB0001003E0000827BD0020BC -:107240000E00073A00A020218F86FD8C022020210D -:1072500090C500050E00074430B000FF2403003E37 -:107260001603FFF1000000003C0580008CA40178AB -:107270000480FFFE240800073C071000ACB1014069 -:1072800002202021A0A801448FBF00188FB1001454 -:107290008FB00010ACA701780A00079127BD00202D -:1072A00027BDFFE0AFB00010AFBF0018AFB10014B2 -:1072B0003C1080008E110020000000000E0004CF62 -:1072C000AE040020AE1100208FBF00188FB1001453 -:1072D0008FB0001003E0000827BD00203084FFFFBE -:1072E0003C0680008CC201B80440FFFE3C084035DB -:1072F000008838253C031000ACC50180ACC0018477 -:10730000ACC7018803E00008ACC301B83084FFFFBC -:107310003C0680008CC201B80440FFFE3C084036A9 -:10732000008838253C031000ACC50180ACC0018446 -:10733000ACC7018803E00008ACC301B827BDFFD08B -:10734000AFB500243095FFFFAFB60028AFB40020E2 -:10735000AFBF002CAFB3001CAFB20018AFB1001428 -:10736000AFB0001030B6FFFF12A000270000A02130 -:107370008F9200508E4300003C06800024020040A3 -:1073800000033E0200032C0230E4007F00669824D4 -:107390001482001D30A500FF8F8300602C68000A56 -:1073A000510000108F860044000358803C0C0800F8 -:1073B000258C5300016C50218D49000001200008EC -:1073C0000000000002D4702131C5FFFF0E00070C41 -:1073D00024040084166000028F920050AF80006089 -:1073E0008F860044264F00202689000101E090216D -:1073F0003134FFFF14C00004AF8F00500295282BDA -:1074000014A0FFDC00000000028010218FBF002CC0 -:107410008FB600288FB500248FB400208FB3001CD6 -:107420008FB200188FB100148FB0001003E0000875 -:1074300027BD00302407003414A7014600000000D7 -:107440009247000E8F98FD908F90FD8C240F1600B0 -:10745000A30700199244000D3C0880003C07800CF3 -:10746000A3040018965F00123C0960003C117FFFE6 -:10747000A61F005C965900103622FFFF2404000569 -:107480003325FFFFAE0500548E46001CAD0F0028CB -:107490008CEE00008D2D444801C6182601A3302132 -:1074A000AE0600388E0C003824CA00013C0D7F0067 -:1074B000AE0C003C8E0B003CAF0B0004AE0A00206B -:1074C0008E130020AE13001CA300001BAE02002C84 -:1074D000A30400128E5F001424130050AE1F00346A -:1074E0008E190034AF1900148E450018AE050048FF -:1074F000924F000CA20F004E92090008352E00207A -:10750000A20E00088E030018006D6024358B400029 -:10751000AE0B0018920A0000315200FF125302A66F -:107520002413FF803C040800248457380E0007769B -:1075300000000000240C0004240800013C050800A1 -:107540008CA557383C048000A20C0025A208000539 -:107550008C9001780600FFFE8F920050240D0002EF -:107560003C031000AC850140A08D0144AC83017840 -:107570000A00083AAF8000602CAD003711A0FF99D7 -:107580008F860044000580803C1108002631532876 -:10759000021178218DEE000001C0000800000000FB -:1075A0002410000414B0008E3C0780003C0B08003F -:1075B0008D6B57388F86FD8CACEB00208E43000816 -:1075C0008F8FFD90240E0050ACC300308E4A00080F -:1075D000ACCA00508E42000CACC200348E44001085 -:1075E000ACC400388E5F0010ACDF00548E5900141C -:1075F000ACD9003C8E580018ADF800048E51001C28 -:10760000ACD1002090C5000030A900FF112E0276F9 -:10761000000000008CC500348CD1003000B1302354 -:1076200004C000F32404008C126000F02402000364 -:107630000A00083AAF820060240F000514AF00680A -:107640003C0B80003C0308008C6357388F86FD8C10 -:10765000AD6300208E4A00048F99FD90240720001E -:10766000ACCA001C9242000824120008A322001990 -:107670008F840050909F0009A33F00188F85005011 -:1076800090B8000A330400FF10920010288C000903 -:10769000158000BC24080002240E0020108E000B70 -:1076A00034078000288900211520000824074000A5 -:1076B00024110040109100053C070001240F0080B8 -:1076C000108F00023C070002240740008CDF0018E6 -:1076D0003C04FF0003E4C8240327C025ACD80018ED -:1076E00090B2000BA0D200278F8300509465000C4D -:1076F00010A0022A000000009467000C3C198000D2 -:10770000240BFFBFA4C7005C9062000E2407000496 -:10771000A0C200088F840050909F000FA0DF0009D6 -:107720008F8C00508D9200108F38007402582823DF -:10773000ACC500588D8F0014ACCF002C959100186B -:107740003229FFFFACC90040958E001A31D0FFFFEF -:10775000ACD000448D8D001CACCD00489588000253 -:10776000A4C800789183000EA0C3000890CA000846 -:10777000014B1024126001D4A0C200088F92005067 -:107780000A00083AAF8700602406000614A6001419 -:107790003C0D80003C1008008E1057388F8CFD88FF -:1077A000ADB000208E4800188F86FD8C8F8AFD902A -:1077B000AD8800008CC3003824040005AD830004AC -:1077C0008CCB003C12600081AD4B00000A00083AEF -:1077D000AF840060240E000710AE004B24040006A6 -:1077E0003C05080024A557380E00074924040081F1 -:1077F0008F9200500013102B0A00083AAF820060ED -:107800002419002314B9FFF63C0B80003C0C08003F -:107810008D8C57388F8AFD90AD6C00208F91FD8C38 -:107820008E4600042544002026450014AE2600287C -:10783000240600030E000E60255000308F87005094 -:1078400002002021240600030E000E6024E500083B -:107850003C040800248457380E000776000000001E -:1078600092220000241F0050304400FF549FFFE18B -:107870008F9200500E000E4B000000000A00093FDE -:107880008F9200502403003314A300323C02800086 -:107890003C1108008E3157388F8EFD90AC5100207E -:1078A0008E440008240900288F88FD8CADC4003068 -:1078B0008E5F000C24060009ADDF00348E590010E5 -:1078C000ADD900388E580014ADD800208E45001870 -:1078D000ADC500248E4F001CADCF0028A1C90011FA -:1078E0008E4D000412600031AD0D00288F920050C3 -:1078F0000A00083AAF8600602409002214A9FFB8E4 -:1079000000000000240400073C0F08008DEF5738EA -:107910003C118000AE2F00205660FEB1AF840060A5 -:107920003C040800248457380E00077624130050C6 -:107930008F98FD8C93120000324500FF10B301694F -:10794000000000008F920050000020210A00083A39 -:10795000AF8400603C05080024A557380E000719C5 -:10796000240400810A00093F8F92005002D498211C -:107970003265FFFF0E00070C240400840A00083A59 -:107980008F9200501088FF512407040028870003BD -:1079900010E001A324100004240D0001548DFF4BBE -:1079A000240740000A0008F5240701003C050800F0 -:1079B00024A557380E000768240400828F920050D7 -:1079C000000030210A00083AAF8600603C0408003D -:1079D000248457388CC200380E0007768CC3003CD4 -:1079E0008F9200500A000995000020212404008293 -:1079F0003C05080024A557380E0007680000000069 -:107A00008F920050000010210A00083AAF820060F7 -:107A10008E5000048F91FD8C3C0A8000AD500020F8 -:107A200092220005020028213046000214C0018085 -:107A30002404008A8F92FD90020028212404008DE6 -:107A4000924B001B3163002014600179000000009C -:107A5000922D0009240C001231A800FF110C0174B2 -:107A6000240400810E00073A020020219245001BE9 -:107A7000240E00040200202134A90042A249001B68 -:107A80000E000744A22E00253C0480008C91017852 -:107A90000620FFFE24180002AC900140A09801448B -:107AA0008F9200503C0F1000AC8F01780A00094003 -:107AB0000013102B8E5000048F91FD8C3C1F800012 -:107AC000AFF0002092390005020028213327000280 -:107AD00014E000172404008A9224000924120004F0 -:107AE00002002821308600FF10D2001124040081FA -:107AF0000E00073A020020218F8CFD90240B00120B -:107B00002403FFFE918D001B0200202135A80020D8 -:107B1000A188001BA22B0009922A00050143102412 -:107B20000E000744A22200050200282100002021A7 -:107B30000E000805000000000A00093F8F92005067 -:107B40008E5100043C0280003C100800261057387B -:107B5000AC5100203C010800AC315738924600037C -:107B600030C40004108001658F84FD8C240200065F -:107B7000A0820009924D001B2408FFC031AC003FD9 -:107B800001885825A08B000892430003306A000149 -:107B90001540015C000000008E420008AE020008A3 -:107BA0003C0208008C4257401040015B8F8EFD90D4 -:107BB000000281C28F85FD8CA5D0000C8E5F000C69 -:107BC000240F000124090014ADDF002C8E59001091 -:107BD000ADD9001C96470016A5C7003C9658001466 -:107BE000A5D8003EACAF000CA4AF0010A4AF0012AB -:107BF000A4AF0014A4AF00161260015FA1C9001168 -:107C000092440003309200022E5300018F920050E4 -:107C1000266200080A00083AAF8200608E4600041F -:107C20003C0580003C048008ACA600208E4700087C -:107C30009089000024110050312200FF105100B83B -:107C4000240500883C0480008C8F01B805E0FFFE0D -:107C50000013802B3C18400900B81025AF9000603D -:107C60003C101000AC860180AC870184AC82018896 -:107C7000AC9001B80A00083B8F8600448E45000492 -:107C80003C0680003C098008ACC50020913F000004 -:107C90002404005033F900FF132400B024060088A8 -:107CA0003C0480008C8A01B80540FFFE3C0E400E6B -:107CB00000CE68253C081000AC850180AC800184B2 -:107CC000AC8D0188AC8801B8912B0000240CFF809A -:107CD00024040004016C1825240600300E0006AAB6 -:107CE000A12300000A00093F8F9200508E5000042B -:107CF0008F91FD903C0F8000ADF000209225001B7D -:107D000030A900101120007C240300813C04800075 -:107D10008C8701B804E0FFFE3C1F401FAC9001803F -:107D2000007F10250013C82B3C101000AC8001848C -:107D3000AF990060AC820188AC9001B80A00083BA2 -:107D40008F8600448E44001C0E00072500000000B2 -:107D5000104000F8004038218F920050240600891E -:107D60003C0580008CAE01B805C0FFFE000000009D -:107D7000ACA701808E50001C3C1140010013782BF1 -:107D800000D138253C131000ACB00184AF8F0060E7 -:107D9000ACA70188ACB301B80A00083B8F86004449 -:107DA000965900023C10080026105738333800045A -:107DB000130000A33C0460008E5F001C3C068000A2 -:107DC000ACDF00203C010800AC3F5738964F000262 -:107DD00031E7000114E000E3000000008E420004DF -:107DE000AE0200083C1008008E105740120000D967 -:107DF0003C0680008F85FD8C241000018CBF00188C -:107E00008F91FD908F89FD8803E6C825ACB90018D5 -:107E1000A0A00005ACB0000C3C1808008F1857401B -:107E20008F870050A4B00010001879C2A4B00012CF -:107E3000A4B00014A4B00016A62F000C8CEE00080D -:107E40008F8D00508F8C0050AE2E002C8DA8000C12 -:107E500024070002AE28001C918B0010A22B0011F9 -:107E60008F830050906A0011A12A00088F82005071 -:107E700090440012A0A4004E8F920050924600132E -:107E8000A22600128F920050965F0014A63F003C7D -:107E900096590016A639003E8E580018AE380014C8 -:107EA0005660FD4FAF8700603C05080024A5573899 -:107EB0000E000749000020218F9200500000382159 -:107EC0000A00083AAF8700603C05080024A557382F -:107ED0000E000768240400828F9200500A000922D5 -:107EE000000038210E000E4B000000008F92005061 -:107EF0000A000995000020210E00073A0200202107 -:107F00009232001B02002021365800100E00074458 -:107F1000A238001B8F9200500A000A850000182129 -:107F20009243000C306A0001114000030000000081 -:107F3000964B000EA48B002C9248000C310C0002D2 -:107F40001180FF4000002821964E00128E4D001433 -:107F5000A48E001A0A000A53AC8D001C8F83007097 -:107F60008F8700681067FF4E000030213C08080032 -:107F7000250856BC000320C0008830218CD10000A9 -:107F8000122500C8246200013043000F1467FFFA75 -:107F9000000320C00A000A6A000030213C050800E6 -:107FA00024A557380E0007682404008B8F920050D8 -:107FB0000A0009220013382B3C0B08008D6B573840 -:107FC00024D8FFFE25710100322A007F014790214D -:107FD00002331024AD020028AE4600D0AE4000D4DB -:107FE0000A00088BAE58001CACC000543C0E0800C0 -:107FF0008DCE57383C09800C352C0100ACEE0028A2 -:108000008E500014AD9000D08E4D0014AD8D00D474 -:108010008E4800102507FFFE0A0008C7AD87001C28 -:108020005490FDAA240740000A0008F52407100018 -:108030000E0007F9000000000A00093F8F9200506F -:108040008C83442C3C05DEAD34B2BEEF3C0108000D -:10805000AC20573810720090000000003C046C62A5 -:10806000348279701462000824040002978A006C3C -:1080700097830064020028210143482B1120001936 -:1080800024040092240400020E00061A24050200B3 -:108090003C0B8000AD6200203C010800AC22573848 -:1080A0001040000D8F8E0050240C00282404000383 -:1080B00091CD001031A800FF550C000124040001EF -:1080C0000E00004C00000000104000042404008357 -:1080D0000A000AB58F920050240400833C05080072 -:1080E00024A557380E000749000000008F92005069 -:1080F0000013382B0A00083AAF8700600A000A1EF6 -:10810000240200128E4400080E0007250000000023 -:108110000A000A2AAE0200083C05080024A55738C8 -:108120000E000719240400878F9200500A000A47A6 -:108130000013102B240400040E00061A240500303E -:1081400014400014004038218F9200500A000A9A0F -:10815000240600833C05080024A557380A000B7B41 -:10816000240400878E4400040E0007250000000050 -:108170000A000ABBAE0200083C05080024A55738D7 -:108180000E000768240400828F9200500A000A47FC -:10819000000010218F9200503C0880083C0C8000A9 -:1081A000240B0050240A0001AD820020A10B000026 -:1081B000A10A000192490004A10900189244000597 -:1081C000A1040019924300063C040800248456BC14 -:1081D000A103001A924200073C030800246356B82A -:1081E000A102001B92450008A105001C924600094F -:1081F000A106001D925F000AA11F001E9259000BEC -:10820000A119001F9258000CA11800209251000DD6 -:10821000A11100219250000EA1100022924F000FD8 -:10822000A10F0023924E0010A10E0024924D0011C8 -:10823000A10D0025964C0014A50C0028964B0016A5 -:108240008F8A00688F980070A50B002A9649001845 -:10825000000A10C025450001A509002C8E46001C0F -:108260000044C8210043F82130A5000FAFE600000C -:10827000AF27000010B80003AF8500680A000A9A13 -:108280000000302124AD000131A8000F0000302192 -:108290000A000A9AAF8800708C83442C0A000B5A9B -:1082A0003C046C623C07080024E756B80087902124 -:1082B000ACC00000000030210A000A6AAE40000095 -:1082C0003C0482013C03600034820E02AC603D68D5 -:1082D000AF80009003E00008AC623D6C27BDFFE872 -:1082E000AFB000103090FFFF001018422C62004128 -:1082F000AFBF001414400002240400802403004097 -:108300003C010800AC3000603C010800AC23006474 -:108310000E000E5400602821244802BF2409FF806B -:108320000109282400103980001030408FBF00144C -:108330008FB0001000A7202100861821AF8300789D -:108340003C010800AC2500583C010800AC24005C4E -:1083500003E0000827BD0018308300FF30C6FFFF90 -:1083600030E400FF3C0880008D0201B80440FFFEAD -:1083700000035400014438253C09600000E9202531 -:108380003C031000AD050180AD060184AD040188F9 -:1083900003E00008AD0301B88F8600503C0960126D -:1083A000352700108CCB00043C0C600E3585001086 -:1083B000316A00062D480001ACE800C48CC40004FA -:1083C000ACA431808CC2000894C30002ACA23184FA -:1083D00003E00008A78300888F8500508F87FF186F -:1083E0008F86FF208CAE00043C0F601235E8001031 -:1083F000ACEE00688CAD0008ACED006C8CAC0010ED -:10840000ACCC004C8CAB000CACCB004894CA0054F4 -:108410003C0208008C42004425490001A4C90054D4 -:1084200094C400543083FFFF106200170000000066 -:108430003C0208008C420040A4C200528CA30018E9 -:10844000ACE300308CA20014ACE2002C8CB9001814 -:10845000ACF900388CB8001424050001ACF80034E5 -:108460008D0600BC50C500198D0200B48D0200B805 -:10847000A4E2004894E40048A4E4004A94E800DA46 -:1084800003E000083102FFFF3C0208008C42002498 -:10849000A4C00054A4C200528CA30018ACE3003066 -:1084A0008CA20014ACE2002C8CB90018ACF9003896 -:1084B0008CB8001424050001ACF800348D0600BC13 -:1084C00054C5FFEB8D0200B88D0200B4A4E2004851 -:1084D00094E40048A4E4004A94E800DA03E00008C9 -:1084E0003102FFFF8F8600503C0480008CC90008D9 -:1084F0008CC80008000929C0000839C0AC870020DA -:1085000090C30007306200041040003AAF85008C31 -:1085100090CB0007316A0008114000398F87FF1C9B -:108520008CCD000C8CCE001401AE602B118000327B -:10853000000000008CC2000CACE200708CCB001874 -:108540008F85FF188F88FF20ACEB00748CCA001059 -:108550002402FFF8ACAA00C88CC9000CAD09006069 -:108560008CC4001CACA400C090E3007C0062C82452 -:10857000A0F9007C90D80007330F000811E0000438 -:108580000000000090ED007C35AC0001A0EC007C08 -:1085900090CF000731EE000111C00009000000007B -:1085A00090E4007C2418000234820002A0E2007CE7 -:1085B00090A300EC307900FF133800132408003436 -:1085C00090C900073126000210C00004000000001E -:1085D00090EB007C356A0004A0EA007C90ED007D01 -:1085E00031AC003FA0EC007D94A700DA03E0000866 -:1085F00030E2FFFF8F87FF1C0A000C908CC2001432 -:108600000A000C91ACE000700A000CB2ACA800CCDF -:108610008F8C005027BDFFD8AFB3001CAFB200183D -:10862000AFB00010AFBF0020AFB10014918F0015A4 -:108630003C13600E3673001031EB000FA38B0094D7 -:108640008D8F00048D8B0008959F00129599001066 -:108650009584001A9598001E958E001C33EDFFFF3F -:10866000332AFFFF3089FFFF3308FFFF31C7FFFFC9 -:108670003C010800AC2D00243C010800AC2900445A -:108680003C010800AC2A0040AE683178AE67317C0E -:1086900091850015959100163C126012365200101B -:1086A00030A200FF3230FFFFAE623188AE5000B41E -:1086B00091830014959F0018240600010066C804E9 -:1086C00033F8FFFFAE5900B8AE5800BC918E0014CD -:1086D000AF8F007C3C08600631CD00FFAE4D00C07E -:1086E000918A00159584000E3C07600A314900FF0D -:1086F000AF8B00803084FFFFAE4900C835110010F9 -:108700000E000BF934F004103C0208008C420060AB -:108710003C0308008C6300643C0608008CC60058CB -:108720003C0508008CA5005C8F8400788FBF00207A -:10873000AE23004CAE65319CAE030054AE4500DC68 -:10874000AE6231A0AE6331A4AE663198AE2200486D -:108750008FB3001CAE0200508FB10014AE4200E097 -:10876000AE4300E4AE4600D88FB000108FB20018C0 -:108770000A00050227BD00289785008A97830074A8 -:1087800027BDFFE8AFB0001000A3102BAFBF00144F -:10879000240400058F900050104000552409000269 -:1087A0000E00061A8F850078AF82008C2404000327 -:1087B0001040004F240900023C0680000E00004CCF -:1087C000ACC2002024070001240820001040004D06 -:1087D00024040005978E008A8F8AFF1C240900500C -:1087E00025C50001A785008AA14900003C0D0800AD -:1087F0008DAD0064240380008F84FF18000D660097 -:10880000AD4C0018A5400006954B000A8F85FF204F -:108810002402FF8001633024A546000A915F000A0C -:108820000000482103E2C825A159000AA0A00008C1 -:10883000A140004CA08000C59618000297830088D4 -:108840003C020004A49800DA960F00022418FFBF2F -:1088500025EE2401A48E00AE8E0D0004ACAD0044C4 -:108860008E0C0008ACAC0040A4A00050A4A00054A2 -:108870008E0B000C240C0030AC8B00288E060010F0 -:10888000AC860024A480003EA487004EA48700503C -:10889000A483003CAD420074AC8800C8ACA8006062 -:1088A000A08700EC909F00C433F9007FA09900C41A -:1088B000909000C402187824A08F00C4914E007CD0 -:1088C00035CD0001A14D007C938B0094AD48007024 -:1088D000AC8C00CCA08B00C68F8800808F87007C7A -:1088E000AC8800B4AC8700B8A5400078A540007AF9 -:1088F0008FBF00148FB000100120102103E000088A -:1089000027BD00188F85008C0E0006AA8F86007880 -:108910000A000D7E2409000227BDFFE0AFB0001061 -:108920008F900050AFB10014AFBF00188E09000443 -:108930000E0004CF000921C08E0800048F84FF18A8 -:108940008F82FF20000839C03C068000ACC70020A1 -:10895000948500DA904300131460001C30B1FFFFCF -:108960008F8CFF1C918B0008316A00401540000B72 -:10897000000000008E0D0004022030218FBF00187F -:108980008FB100148FB000102404002200003821A1 -:10899000000D29C00A000C1827BD00200E0000633E -:1089A000000000008E0D0004022030218FBF00184F -:1089B0008FB100148FB00010240400220000382171 -:1089C000000D29C00A000C1827BD00200E00005B16 -:1089D000000000008E0D0004022030218FBF00181F -:1089E0008FB100148FB00010240400220000382141 -:1089F000000D29C00A000C1827BD002027BDFFE08C -:108A0000AFB200183092FFFFAFB00010AFBF001C34 -:108A1000AFB100141240001E000080218F8600506C -:108A20008CC500002403000600053F020005140267 -:108A300030E4000714830016304500FF2CA8000620 -:108A400011000040000558803C0C0800258C54049F -:108A5000016C50218D490000012000080000000039 -:108A60008F8E0090240D000111CD005024020002D1 -:108A7000AF820090260900013130FFFF24C800209A -:108A80000212202B010030211480FFE5AF88005036 -:108A9000020010218FBF001C8FB200188FB100148C -:108AA0008FB0001003E0000827BD002093870076F8 -:108AB00054E00034000030210E000CC6000000001D -:108AC0008F8600500A000DDE240200018F8700907F -:108AD0002405000210E500312404001300002821C1 -:108AE00000003021240700010E000C1800000000D7 -:108AF0000A000DDF8F8600508F8300902402000251 -:108B00001462FFF6240400120E000C7B000000002B -:108B10008F85008C00403021240400120E000C18B8 -:108B2000000038210A000DDF8F8600508F830090EF -:108B30002411000310710029241F0002107FFFCEB2 -:108B40002609000124040010000028210000302123 -:108B50000A000DFC240700018F91009024060002FA -:108B60001626FFF9240400100E000D20000000005E -:108B7000144000238F9800508F8600500A000DDEAD -:108B800024020003240400140E000C180000282105 -:108B90008F8600500A000DDE240200020E000D88B0 -:108BA000000000000A000DDF8F8600500E000C2828 -:108BB00000000000241900022404001400002821F1 -:108BC0000000302100003821AF9900900E000C18F1 -:108BD000000000000A000DDF8F8600500E000C38E8 -:108BE000000000008F85008C241900020040302115 -:108BF00024040010000038210A000E35AF990090BF -:108C00000040382124040010970F000200002821A2 -:108C10000E000C1831E6FFFF8F8600500A000DDFB2 -:108C2000AF9100908F84FF1C3C077FFF34E6FFFF6D -:108C30008C8500182402000100A61824AC830018BB -:108C400003E00008A08200053084FFFF30A5FFFF8D -:108C5000108000070000182130820001104000023F -:108C600000042042006518211480FFFB0005284005 -:108C700003E000080060102110C0000700000000A1 -:108C80008CA2000024C6FFFF24A50004AC820000D3 -:108C900014C0FFFB2484000403E00008000000006F -:108CA00010A0000824A3FFFFAC8600000000000015 -:108CB000000000002402FFFF2463FFFF1462FFFA9C -:108CC0002484000403E0000800000000000411C038 -:108CD00003E000082442024027BDFFE8AFB00010C7 -:108CE00000808021AFBF00140E000E7500A020216F -:108CF00000504821240AFF808FBF00148FB000105D -:108D0000012A30243127007F3C08800A3C042100DE -:108D100000E8102100C428253C03800027BD00186E -:108D2000AC650024AF820038AC400000AC65002484 -:108D300003E00008AC4000403C0D08008DAD005839 -:108D400000056180240AFF8001A45821016C48219C -:108D5000012A30243127007F3C08800C3C0421008C -:108D600000E8102100C428253C038000AC650028E1 -:108D7000AF82003403E00008AC40002430A5FFFFC0 -:108D80003C0680008CC201B80440FFFE3C08601520 -:108D900000A838253C031000ACC40180ACC001849D -:108DA000ACC7018803E00008ACC301B83C0D080063 -:108DB0008DAD005800056180240AFF8001A4582170 -:108DC000016C4021010A4824000931403107007F2D -:108DD00000C728253C04200000A418253C02800080 -:108DE000AC43083003E00008AF80003427BDFFE843 -:108DF000AFB0001000808021AFBF00140E000E75D0 -:108E000000A0202100504821240BFF80012B50247A -:108E1000000A39403128007F3C0620008FBF001433 -:108E20008FB0001000E8282534C2000100A21825E8 -:108E30003C04800027BD0018AC83083003E0000824 -:108E4000AF8000383C0580088CA700603C06800895 -:108E50000087102B144000112C8340008CA8006068 -:108E60002D0340001060000F240340008CC90060F7 -:108E70000089282B14A00002008018218CC30060F8 -:108E800000035A42000B30803C0A0800254A5480F7 -:108E900000CA202103E000088C8200001460FFF368 -:108EA0002403400000035A42000B30803C0A0800B3 -:108EB000254A548000CA202103E000088C8200006B -:108EC0003C05800890A60008938400A024C20001FD -:108ED000304200FF3043007F1064000C000238274E -:108EE000A0A200083C0480008C85017804A0FFFE4D -:108EF0008F8A0098240900023C081000AC8A0140C7 -:108F0000A089014403E00008AC8801780A000EFA49 -:108F100030E2008027BDFFD8AFB200188F92009CCE -:108F2000AFBF0020AFB3001CAFB00010AFB1001452 -:108F30008F9300348E5900283C1000803C0EFFEFC8 -:108F4000AE7900008E580024A260000A35CDFFFFE4 -:108F5000AE7800049251002C3C0BFF9F356AFFFF56 -:108F6000A271000C8E6F000C3C080040A271000B37 -:108F700001F06025018D4824012A382400E83025BD -:108F8000AE66000C8E450004AE6000183C0400FF85 -:108F9000AE6500148E43002C3482FFFFA6600008EB -:108FA0000062F824AE7F00108E5900088F90009860 -:108FB000964E0012AE7900208E51000C31D83FFF42 -:108FC00000187980AE7100248E4D001401F06021EC -:108FD00031CB0001AE6D00288E4A0018000C41C252 -:108FE000000B4B80AE6A002C8E46001C0109382114 -:108FF000A667001CAE660030964500028E44002035 -:10900000A665001EAE640034924300333062000453 -:1090100054400006924700003C028008344301009F -:109020008C7F00C0AE7F0030924700008F860038F2 -:10903000A0C700309245003330A4000250800007E2 -:10904000925100018F880038240BFF80910A003074 -:10905000014B4825A1090030925100018F90003842 -:10906000240CFFBF2404FFDFA21100318F8D0038D4 -:109070003C1880083711008091AF003C31EE007F32 -:10908000A1AE003C8F890038912B003C016C50242C -:10909000A12A003C8F9F00388E68001493E6003CA4 -:1090A0002D0700010007114000C4282400A2182544 -:1090B000A3E3003C8F87003896590012A4F90032D0 -:1090C0008E450004922E007C30B0000300107823FF -:1090D00031ED000300AD102131CC000215800002FB -:1090E00024460034244600303C028008344300808B -:1090F000907F007C00BFC8243338000417000002B2 -:1091000024C2000400C010218F98003824190002E6 -:10911000ACE20034A3190000924F003F8F8E00385C -:109120003C0C8008358B0080A1CF00018F91003866 -:10913000924D003F8E440004A62D0002956A005C0B -:109140000E000ED33150FFFF00024B800130382556 -:109150003C08420000E82825AE2500048E44003873 -:109160008F850038ACA400188E460034ACA6001CD5 -:10917000ACA0000CACA00010A4A00014A4A0001689 -:10918000A4A00020A4A00022ACA000248E620014A1 -:1091900050400001240200018FBF00208FB3001C4B -:1091A0008FB200188FB100148FB00010ACA200086D -:1091B0000A000EF227BD002827BDFFC83C05800825 -:1091C00034A40080AFBF0034AFBE0030AFB7002C76 -:1091D000AFB60028AFB50024AFB40020AFB3001C79 -:1091E000AFB20018AFB10014AFB000109483007894 -:1091F0009482007A104300512405FFFF0080F02183 -:109200000A0010020080B821108B004D8FBF00347F -:109210008F8600983C1808008F18005C2411FF808E -:109220003C1680000306782101F18024AED0002C8A -:1092300096EE007A31EC007F3C0D800E31CB7FFF43 -:10924000018D5021000B4840012AA82196A400005E -:109250003C0808008D0800582405FF8030953FFF2A -:1092600001061821001539800067C8210325F8245C -:109270003C02010003E290253338007F3C11800C52 -:10928000AED20028031190219250000D320F00043D -:1092900011E0003702E0982196E3007A96E8007A20 -:1092A00096E5007A2404800031077FFF24E3000163 -:1092B00030627FFF00A4F82403E2C825A6F9007AF3 -:1092C00096E6007A3C1408008E94006030D67FFF4A -:1092D00012D400C1000000008E5800188F8400983E -:1092E00002A028212713FFFF0E000EADAE53002C65 -:1092F00097D5007897D4007A1295001000002821A5 -:109300003C098008352401003C0A80089148000887 -:10931000908700C53114007F30E400FF0284302BB9 -:1093200014C0FFB9268B0001938E00A0268C00018B -:10933000008E682115ACFFB78F8600988FBF003470 -:109340008FBE00308FB7002C8FB600288FB5002459 -:109350008FB400208FB3001C8FB200188FB100149F -:109360008FB0001000A0102103E0000827BD0038D6 -:1093700000C020210E000E78028028218E4B0010A4 -:109380008E4C00308F84003824090002016C502379 -:10939000AE4A0010A089000096E3005C8E440030C5 -:1093A0008F9100380E000ED33070FFFF0002438013 -:1093B000011028253C07420000A71025AE2200041A -:1093C0008E5F00048F8A00388E590000240B00083D -:1093D000AD5F001CAD590018AD40000CAD40001051 -:1093E0009246000A240400052408C00030D000FF83 -:1093F000A550001496580008A55800169251000A6E -:109400003C188008322F00FFA54F0020964E000820 -:1094100037110100A54E0022AD400024924D000BF3 -:1094200031AC00FFA54C0002A14B00018E49003079 -:109430008F830038240BFFBFAC690008A0640030A4 -:109440008F9000382403FFDF9607003200E82824BD -:1094500000B51025A6020032921F003233F9003FFA -:1094600037260040A20600328F8C0038AD800034D1 -:109470008E2F00C0AD8F0038918E003C3C0F7FFFD7 -:1094800031CD007FA18D003C8F84003835EEFFFF89 -:10949000908A003C014B4824A089003C8F8500380D -:1094A00090A8003C01033824A0A7003C8E42003461 -:1094B0008F9100383C038008AE2200408E59002C6A -:1094C0008E5F0030033F3023AE26004492300048C8 -:1094D0003218007FA23800488F8800388E4D003047 -:1094E0008D0C004801AE582401965024014B4825AC -:1094F000AD0900489244000AA104004C96470008B8 -:109500008F850038A4A7004E8E5000308E44003066 -:109510000E00031C8C65006092F9007C0002F9408B -:10952000004028210002110003E2302133360002FE -:1095300012C00003020680210005B08002168021BF -:10954000926D007C31B3000412600002000570804F -:10955000020E80218E4B003024058000316A00030A -:10956000000A482331240003020418218F90003898 -:10957000AE03003496E4007A96E8007A96F1007A19 -:1095800031077FFF24E20001305F7FFF0225C824FE -:10959000033F3025A6E6007A96F8007A3C120800D0 -:1095A0008E520060330F7FFF11F2001800000000A0 -:1095B0008F8400980E000EAD02A028218F840098A1 -:1095C0000E000EBD028028210E000EF200000000E9 -:1095D0000A000FFE0000000096F1007A02248024A9 -:1095E000A6F0007A92EF007A92EB007A31EE00FF5B -:1095F000000E69C2000D6027000C51C03169007F68 -:10960000012A20250A000FF8A2E4007A96E6007AE3 -:1096100000C5C024A6F8007A92EF007A92F3007A8F -:1096200031F200FF001271C2000E6827000DB1C0B8 -:10963000326C007F01962825A2E5007A0A0010AF5F -:109640008F8400983C0380003084FFFF30A5FFFF2B -:10965000AC640018AC65001C03E000088C620014C8 -:1096600027BDFFA83C068008AFBE0050AFBF005426 -:10967000AFB7004CAFB60048AFB50044AFB4004040 -:10968000AFB3003CAFB20038AFB10034AFB0003080 -:1096900034C80100910500C590C70008309EFFFF47 -:1096A00030A500FF30E2007F0045182AA7A0001473 -:1096B000A7A0001E10600053AFA0001090C90008C2 -:1096C0003126007F00A620232493FFFF0013802B68 -:1096D000001E882B0211782451E000848FB3001003 -:1096E0003C1980089736005297370050001EC4007E -:1096F00002D7A8230015A4000014140303C2902A63 -:109700001640000200182C0300402821001314000A -:109710000002240300A4F82A57E0000100A0202141 -:1097200028830009146000020080A021241400088E -:109730003C0A80088D450048001449808D48004C43 -:109740003C0380003124FFFF3C06001000863825D2 -:1097500034710400AC650038AF91009CAC68003CEB -:10976000AC670030000000000000000000000000B6 -:1097700000000000000000000000000000000000E9 -:10978000000000008C6C0000318B00201160FFFD98 -:109790000014682A01B01024104000390000A821EC -:1097A0003C16800892D700083C1280008E440100CD -:1097B00032F6007F0E000E7802C028218E2F001096 -:1097C0008E4401000000902131F73FFF0E000E9003 -:1097D00002E02821922E000031C2003F2C500008E8 -:1097E00052000010000088210002F8803C030800AD -:1097F0002463542C03E3C8218F38000003000008C1 -:109800000000000090CE0008938B00A031CD007FB7 -:1098100000AD6023016C50210A0010F52553FFFFB5 -:10982000000088213C1080008E0401000E000EAD67 -:1098300002E028218E0401000E000EBD02C0282186 -:109840001220000F0013802B8F8A009C26A9000194 -:109850000009AC00027298230015AC0325450040B6 -:1098600002B4B02A0013802B2417000100A0882125 -:1098700002D01024AF85009C1440FFC9AFB7001080 -:109880003C07800894F100503C0580003C06002015 -:1098900002B1C821A4F90050ACA6003094F40050E5 -:1098A00094E3005203D560231074001D319EFFFF26 -:1098B0008CE5004C8CE900480015618000ACB021BB -:1098C0000000A02102CCA82B013450210155B82161 -:1098D000ACF6004CACF70048001E882B021178242F -:1098E00015E0FF803C1980088FB300108FBF005433 -:1098F0008FBE00503A6200018FB7004C8FB600480F -:109900008FB500448FB400408FB3003C8FB2003855 -:109910008FB100348FB0003003E0000827BD00583D -:1099200094F200548CEF0044325FFFFE001FC0C071 -:1099300001F87021ACAE003C8CEB00448CAD003CD7 -:10994000016D40231900003B000000008CE2004044 -:10995000244200013C07005034E400103C03800026 -:10996000ACA20038AC640030000000000000000031 -:1099700000000000000000000000000000000000E7 -:1099800000000000000000008C76000032D70020AC -:1099900012E0FFFD3C118008962800543C0A80002C -:1099A0003C06800831190001001960C0018AA0211D -:1099B0008E8304003C0708008CE700443C1500201F -:1099C000ACC300488E89040424050001ACC9004CD6 -:1099D00010E50259AD550030963F00523C05080095 -:1099E0008CA5004000BFC021A6380052962F00541D -:1099F00025EE0001A62E00549626005430C4FFFF29 -:109A00005487FF34001E882B30A5FFFF0E0010D3B3 -:109A1000A62000543C0408008C84002496270052A1 -:109A20000044102300E29023A63200520A0010F7EF -:109A3000001E882B8CE200400A0011983C07005061 -:109A400092280001240700013102007F1447001C06 -:109A500097AC001E8E2A0014240BC00031443FFF37 -:109A6000018B48243C0608008CC600600124282590 -:109A700030A43FFF0086882B12200011A7A5001EEE -:109A80003C1108008E3100588F82009800044180FC -:109A90002407FF80022218210068F82103E7C82468 -:109AA00033EF007F3C1880003C12800EAF19002C71 -:109AB00001F2682191AE000D35D00004A1B0000D77 -:109AC0000E000F0724120001241100013C10800039 -:109AD0008E0401000E000EAD02E028218E0401006C -:109AE0000E000EBD02C028211620FF588F8A009C50 -:109AF0000A0011620013802B8F86009C90C9000120 -:109B00003125002010A0018A241000013C048008A7 -:109B1000348C0080918B007C8F9100340000902168 -:109B2000316A00011140000FAFB000208CD000144A -:109B30008C8E0060020E682B15A0000302003821F5 -:109B40008C8700603C048008348300808C72007035 -:109B500000F2782B15E0000200E020218C640070F8 -:109B6000008090213C07800834E500808CD90014E7 -:109B70008CBF0070033FC02B170000020320202180 -:109B80008CA400700092182310600003AFA300287B -:109B900024080002AFA800208FA500200265102B2A -:109BA000144000B5000018218CC400388E2F000C22 -:109BB0003C180080AE2400008CCE00343C10FF9F87 -:109BC00001F86025AE2E000490CB003F360DFFFF5C -:109BD000018D48243C0A00203C06FFEFA22B000B1D -:109BE000012A382534C5FFFF00E540243C02000867 -:109BF0008F87009C01022025AE24000C8CE300140A -:109C0000AE2000188FAF0028AE2300148CF8001887 -:109C10003C1FFFFB37F9FFFFAE38001C8CEE00083D -:109C200000996824024F8021AE2E00248CEC000C99 -:109C3000AE2D000CA6200038A620003AAE30002C35 -:109C4000AE2C0020AE2000288CEB00148FAA002838 -:109C500001724823012A302310C00011AE260010E3 -:109C600090F0003D8E2C00048E2A00000010690048 -:109C7000018D28210000102100AD302B0142482128 -:109C800001264021AE250004AE28000090E3003DEF -:109C9000A223000A8F9F009C97F90006A6390008AE -:109CA0008F8A0038240200023C068008A14200008E -:109CB00034C900809525005C024020218F90003837 -:109CC00030A8FFFF0E000ED3AFA800248FA30024FE -:109CD0000002FB808F85009C3C04420003E3C82502 -:109CE0000324C025AE1800048F8400388CAF0038E0 -:109CF000AC8F00188CAE0034AC8E001CAC80000C15 -:109D0000AC800010A4800014A4800016A480002061 -:109D1000A4800022AC80002490A7003FA48700020A -:109D20005240018C240700018FAB002851600002D3 -:109D300090A2003D90A2003E244C0001A08C0001A6 -:109D40008F840038AC9200083C18800837100080DF -:109D5000920F007C31EE000215C00002240700348F -:109D6000240700308F85009C3C088008350900805E -:109D700090A300009128007C32590003A08300309A -:109D80008F9F009C8F9000382404000493F80001FA -:109D900000997823240DC000A21800318F99003853 -:109DA0008F8E009C31E50003972C003295CB00127A -:109DB00000F24821018D502431623FFF01423025DD -:109DC000A7260032932300320125382131080004F0 -:109DD000307F003F37E40040A324003212400002ED -:109DE0008F85003800E838213C0C8008ACA700348F -:109DF000358B01008D6200C02E4400012403FFDF7B -:109E0000ACA2003890AA003C0004C9403146007F53 -:109E1000A0A6003C8F8900382405FFBF9127003C95 -:109E200000E54024A128003C8F8F003891FF003CC2 -:109E300003E3C02403198025A1F0003C8F8B009C14 -:109E40008F8A00388D6E0020AD4E00408D6D00244D -:109E5000AD4D00448D6C0028AD4C00488D62002C47 -:109E60000E000EF2AD42004C8FA600202407000227 -:109E700010C700118FA300200003202B00048023B3 -:109E80000270982400608021006090210A00114B2C -:109E90000010882B962700128F84009800009021D4 -:109EA00030E5FFFFA7A700140E000EA1241100014A -:109EB0000A0011F63C1080003C1980003C0280082A -:109EC0008F240100905800080E000E783305007FA3 -:109ED0008F8E00388FAF00208FA40028A1CF000004 -:109EE0000E000ED38F9000388FAD002400023B800F -:109EF0003C0B420000ED40258F87009C010B202584 -:109F0000AE0400048CE500388F900038000050212A -:109F1000000A1900AE0500188CEC00343C087FFFE5 -:109F20003504FFFFAE0C001C90E9003E8E1F001CA4 -:109F30008E1800180009C9000009370203F96821CA -:109F40000066102501B9782B0302702101CF58213A -:109F5000AE0D001CAE0B0018AE00000CAE000010E1 -:109F600090E5003E8FAF0028240E0005A6050014E2 -:109F700094EC00042405C00001E45824A60C00164B -:109F800090EA003E01E02021A60A002094E60004A9 -:109F9000A6060022AE00002490E3003FA6030002C4 -:109FA00090E9003E90FF003D03E9C82327380001F7 -:109FB000A21800018F8D00383C108008ADAF00085A -:109FC000A1AE00308F9800388F82009C360F0100C0 -:109FD000970C0032944A00122410FF8000AC382401 -:109FE00031463FFF00E61825A703003293090032EF -:109FF0002405FFBF2403FFDF313F003F37F9004056 -:10A00000A31900328F8C00382418FFFFAD80003474 -:10A010008DEE00C0AD8E0038918D003C31A2007FE6 -:10A02000A182003C8F87003890EA003C0145302433 -:10A03000A0E6003C8F9900389329003C0123F824C6 -:10A04000A33F003C8F8D00383C1F8008ADB8004016 -:10A05000ADB2004491AF00483C12800001F0702581 -:10A06000A1AE00488F8700388F86009C8CEC00489A -:10A0700001921024004B5025ACEA004890C5003EE8 -:10A08000A0E5004C8F88009C8F8300389509000460 -:10A09000A469004E8FE500600E00031C0000000064 -:10A0A0008F99FF248FAE002800028140932F007CFF -:10A0B0000002C1000218682131F20002004028218C -:10A0C000164000AA01CD30213C0A800835430080AB -:10A0D0009069007C313F000413E000038FAE00283C -:10A0E0000005608000CC3021240D00048F900038E2 -:10A0F00031C7000301A758233168000300C820219D -:10A10000AE0400343C068008A62500383C058000DB -:10A110008CA4010090D100080E000EBD3225007FF6 -:10A120000E000EF2000000000A0012E08FA30020D3 -:10A130008F8500348CC2003824180003A4A00008C6 -:10A14000ACA200008CDF0034A0A0000A8F92009C1B -:10A15000ACBF00043C040080924F003FA0B8000C4C -:10A160008CAE000C3C0DFF9FA0AF000B01C440253E -:10A1700035ABFFFF3C11FFEF8F98009C010B3024A3 -:10A180003639FFFF00D96024ACAC000C8F030014FB -:10A19000971F00128F870098ACA300108F0900143E -:10A1A000ACA00018ACA00020ACA90014ACA0002406 -:10A1B0008F0A001833E93FFF00091180ACAA00287C -:10A1C0008F1200080047782133EE0001ACB2003056 -:10A1D0008F08000C8F990038000F69C2000E238091 -:10A1E00001A45821241100023C068008A4AB001CE5 -:10A1F000A4A00034ACA8002CA331000034D9008006 -:10A20000972C005C8F8F00383C034200318AFFFF9F -:10A2100001433825ADE700048F82009C241800011B -:10A220002411C0008C5F003824070034ADFF0018F3 -:10A230008C520034ADF2001CADE0000CADE000101B -:10A24000A5E00014A5E00016A5E00020A5E000228E -:10A25000ADE00024A5F00002A1F800018F8B0038CA -:10A260008F8E009CAD70000891CD0000A16D003074 -:10A270008F88009C8F84003891050001A0850031F3 -:10A280008F920038964C00320191502401491825D4 -:10A29000A6430032925F003233E2003FA242003216 -:10A2A0009338007C330F000215E000028F840038E1 -:10A2B000240700303C028008AC870034345201008F -:10A2C0008E5F00C0240EFFBF02009021AC9F0038BB -:10A2D0009098003C330F007FA08F003C8F8800389F -:10A2E000910D003C01AE5824A10B003C8F86003834 -:10A2F00090D1003C36390020A0D9003C8F8A009CC8 -:10A300008F8500380010882B8D4C0020ACAC0040AD -:10A310008D430024ACA300448D490028ACA900481B -:10A320008D47002CACA7004C0E000EF23C108000B4 -:10A330000A00114C0000000094CD00523C0B0800B4 -:10A340008D6B0024016D8821A4D100520A0010F702 -:10A35000001E882BA08700018F840038240D000187 -:10A36000AC8D00080A0012953C188008000290800D -:10A370000A00137400D2302127BDFFE03C0D800895 -:10A38000AFB20018AFB00010AFBF001CAFB10014E7 -:10A3900035B200808E4C001835A80100964B00069F -:10A3A00095A70050910900EC000C56020167282384 -:10A3B0003143007F312600FF24020003A38300A065 -:10A3C000AF84009810C2001B30B0FFFF910600EC74 -:10A3D0002412000530C200FF1052003300000000BC -:10A3E000160000098FBF001C8FB200188FB1001437 -:10A3F0008FB00010240D0C003C0C800027BD002005 -:10A4000003E00008AD8D00240E0010DA02002021C8 -:10A410008FBF001C8FB200188FB100148FB00010D6 -:10A42000240D0C003C0C800027BD002003E0000838 -:10A43000AD8D0024965800789651007A924E007D9A -:10A440000238782631E8FFFF31C400C014800009CB -:10A450002D11000116000037000000005620FFE219 -:10A460008FBF001C0E000FB0000000000A00143C5B -:10A470008FBF001C1620FFDA000000000E000FB096 -:10A48000000000001440FFD88FBF001C16000022FF -:10A4900000000000925F007D33E2003FA242007D99 -:10A4A0000A00143C8FBF001C950900DA8F860078E3 -:10A4B00000802821240400050E0006AA3130FFFF89 -:10A4C0009783008A3C0480002465FFFFA785008AEB -:10A4D0008C8A01B80540FFFE00000000AC800180BE -:10A4E0008FBF001CAC9001848FB200188FB1001494 -:10A4F0008FB000103C0760133C0B1000240D0C00C3 -:10A500003C0C800027BD0020AC870188AC8B01B8D3 -:10A5100003E00008AD8D00240E0010DA02002021B7 -:10A520005040FFB18FBF001C925F007D0A0014698C -:10A5300033E2003F0E0010DA020020211440FFAA8F -:10A540008FBF001C12200007000000009259007D00 -:10A550003330003F36020040A242007D0A00143C26 -:10A560008FBF001C0E000FB0000000005040FF9E87 -:10A570008FBF001C9259007D3330003F0A001498B1 -:04A58000360200405F -:0CA58400000000000000001B0000000FA1 -:10A590000000000A0000000800000006000000059E -:10A5A000000000050000000400000004000000039B -:10A5B000000000030000000300000003000000038F -:10A5C0000000000200000002000000020000000283 -:10A5D0000000000200000002000000020000000273 -:10A5E0000000000200000002000000020000000263 -:10A5F0000000000200000002000000020000000154 -:08A60000000000010000000150 -:08A608008008010080080080B9 -:10A610008008000000000C000000308008001020BE -:10A62000080010CC080010E4080010F80800110C15 -:10A6300008001020080010200800114008001178C0 -:10A6400008001188080011B0080018A0080018A020 -:10A65000080018D8080018D8080018EC080018BC22 -:10A6600008001B1408001AE008001B6C08001B6C93 -:10A6700008001BF408001B24800802400800228008 -:10A68000080020CC080022A80800234008002490DD -:10A69000080024DC08002600080025080800258C96 -:10A6A0000800213C08002AA808002A4C080020E8DD -:10A6B000080020E8080020E8080026740800267436 -:10A6C000080020E8080020E808002924080020E805 -:10A6D000080020E8080020E8080020E80800298495 -:10A6E000080020E8080020E8080020E8080020E82A -:10A6F000080020E8080020E8080020E8080020E81A -:10A70000080020E8080020E8080020E8080020E809 -:10A71000080020E8080020E8080024FC080020E8E1 -:10A72000080020E8080029F4080020E8080020E8D4 -:10A73000080020E8080020E8080020E8080020E8D9 -:10A74000080020E8080020E8080020E8080020E8C9 -:10A75000080020E8080020E8080020E8080020E8B9 -:10A76000080020E8080020E8080020E80800284841 -:10A77000080020E8080020E8080027BC0800271887 -:10A78000080038600800383408003800080037D462 -:10A79000080037B40800376880080100800800808E -:10A7A0008008000080080080080047C808004800B2 -:10A7B00008004748080047C8080047C8080045285F -:08A7C000080047C808004B9C8B -:08A7C8000A000C7600000000FD -:10A7D000000000000000000D727870352E302E3021 -:10A7E0006A31350005000003000000000000000190 -:10A7F0000000000000000000000000000000000059 -:10A800000000000000000000000000000000000048 -:10A810000000000000000000000000000000000038 -:10A820000000000000000000000000000000000028 -:10A830000000000000000000000000000000000018 -:10A840000000000000000000000000000000000008 -:10A8500000000000000000000000000000000000F8 -:10A8600000000000000000000000000000000000E8 -:10A8700000000000000000000000000000000000D8 -:10A8800000000000000000000000000000000000C8 -:10A8900000000000000000000000000000000000B8 -:10A8A00000000000000000000000000000000000A8 -:10A8B0000000000000000000000000000000000098 -:10A8C0000000000000000000000000000000000088 -:10A8D0000000000000000000000000000000000078 -:10A8E0000000000000000000000000000000000068 -:10A8F0000000000000000000000000000000000058 -:10A900000000000000000000000000000000000047 -:10A910000000000000000000000000000000000037 -:10A920000000000000000000000000000000000027 -:10A930000000000000000000000000000000000017 -:10A940000000000000000000000000000000000007 -:10A9500000000000000000000000000000000000F7 -:10A9600000000000000000000000000000000000E7 -:10A9700000000000000000000000000000000000D7 -:10A9800000000000000000000000000000000000C7 -:10A9900000000000000000000000000000000000B7 -:10A9A00000000000000000000000000000000000A7 -:10A9B0000000000000000000000000000000000097 -:10A9C0000000000000000000000000000000000087 -:10A9D0000000000000000000000000000000000077 -:10A9E0000000000000000000000000000000000067 -:10A9F0000000000000000000000000000000000057 -:10AA00000000000000000000000000000000000046 -:10AA10000000000000000000000000000000000036 -:10AA20000000000000000000000000000000000026 -:10AA30000000000000000000000000000000000016 -:10AA40000000000000000000000000000000000006 -:10AA500000000000000000000000000000000000F6 -:10AA600000000000000000000000000000000000E6 -:10AA700000000000000000000000000000000000D6 -:10AA800000000000000000000000000000000000C6 -:10AA900000000000000000000000000000000000B6 -:10AAA00000000000000000000000000000000000A6 -:10AAB0000000000000000000000000000000000096 -:10AAC0000000000000000000000000000000000086 -:10AAD0000000000000000000000000000000000076 -:10AAE0000000000000000000000000000000000066 -:10AAF0000000000000000000000000000000000056 -:10AB00000000000000000000000000000000000045 -:10AB10000000000000000000000000000000000035 -:10AB20000000000000000000000000000000000025 -:10AB30000000000000000000000000000000000015 -:10AB40000000000000000000000000000000000005 -:10AB500000000000000000000000000000000000F5 -:10AB600000000000000000000000000000000000E5 -:10AB700000000000000000000000000000000000D5 -:10AB800000000000000000000000000000000000C5 -:10AB900000000000000000000000000000000000B5 -:10ABA00000000000000000000000000000000000A5 -:10ABB0000000000000000000000000000000000095 -:10ABC0000000000000000000000000000000000085 -:10ABD0000000000000000000000000000000000075 -:10ABE0000000000000000000000000000000000065 -:10ABF0000000000000000000000000000000000055 -:10AC00000000000000000000000000000000000044 -:10AC10000000000000000000000000000000000034 -:10AC20000000000000000000000000000000000024 -:10AC30000000000000000000000000000000000014 -:10AC40000000000000000000000000000000000004 -:10AC500000000000000000000000000000000000F4 -:10AC600000000000000000000000000000000000E4 -:10AC700000000000000000000000000000000000D4 -:10AC800000000000000000000000000000000000C4 -:10AC900000000000000000000000000000000000B4 -:10ACA00000000000000000000000000000000000A4 -:10ACB0000000000000000000000000000000000094 -:10ACC0000000000000000000000000000000000084 -:10ACD0000000000000000000000000000000000074 -:10ACE0000000000000000000000000000000000064 -:10ACF0000000000000000000000000000000000054 -:10AD00000000000000000000000000000000000043 -:10AD10000000000000000000000000000000000033 -:10AD20000000000000000000000000000000000023 -:10AD30000000000000000000000000000000000013 -:10AD40000000000000000000000000000000000003 -:10AD500000000000000000000000000000000000F3 -:10AD600000000000000000000000000000000000E3 -:10AD700000000000000000000000000000000000D3 -:10AD800000000000000000000000000000000000C3 -:10AD900000000000000000000000000000000000B3 -:10ADA00000000000000000000000000000000000A3 -:10ADB0000000000000000000000000000000000093 -:10ADC0000000000000000000000000000000000083 -:10ADD0000000000000000000000000000000000073 -:10ADE0000000000000000000000000000000000063 -:10ADF0000000000000000000000000000000000053 -:10AE00000000000000000000000000000000000042 -:10AE10000000000000000000000000000000000032 -:10AE20000000000000000000000000000000000022 -:10AE30000000000000000000000000000000000012 -:10AE40000000000000000000000000000000000002 -:10AE500000000000000000000000000000000000F2 -:10AE600000000000000000000000000000000000E2 -:10AE700000000000000000000000000000000000D2 -:10AE800000000000000000000000000000000000C2 -:10AE900000000000000000000000000000000000B2 -:10AEA00000000000000000000000000000000000A2 -:10AEB0000000000000000000000000000000000092 -:10AEC0000000000000000000000000000000000082 -:10AED0000000000000000000000000000000000072 -:10AEE0000000000000000000000000000000000062 -:10AEF0000000000000000000000000000000000052 -:10AF00000000000000000000000000000000000041 -:10AF10000000000000000000000000000000000031 -:10AF20000000000000000000000000000000000021 -:10AF30000000000000000000000000000000000011 -:10AF40000000000000000000000000000000000001 -:10AF500000000000000000000000000000000000F1 -:10AF600000000000000000000000000000000000E1 -:10AF700000000000000000000000000000000000D1 -:10AF800000000000000000000000000000000000C1 -:10AF900000000000000000000000000000000000B1 -:10AFA00000000000000000000000000000000000A1 -:10AFB0000000000000000000000000000000000091 -:10AFC0000000000000000000000000000000000081 -:10AFD0000000000000000000000000000000000071 -:10AFE0000000000000000000000000000000000061 -:10AFF0000000000000000000000000000000000051 -:10B000000000000000000000000000000000000040 -:10B010000000000000000000000000000000000030 -:10B020000000000000000000000000000000000020 -:10B030000000000000000000000000000000000010 -:10B040000000000000000000000000000000000000 -:10B0500000000000000000000000000000000000F0 -:10B0600000000000000000000000000000000000E0 -:10B0700000000000000000000000000000000000D0 -:10B0800000000000000000000000000000000000C0 -:10B0900000000000000000000000000000000000B0 -:10B0A00000000000000000000000000000000000A0 -:10B0B0000000000000000000000000000000000090 -:10B0C0000000000000000000000000000000000080 -:10B0D0000000000000000000000000000000000070 -:10B0E0000000000000000000000000000000000060 -:10B0F0000000000000000000000000000000000050 -:10B10000000000000000000000000000000000003F -:10B11000000000000000000000000000000000002F -:10B12000000000000000000000000000000000001F -:10B13000000000000000000000000000000000000F -:10B1400000000000000000000000000000000000FF -:10B1500000000000000000000000000000000000EF -:10B1600000000000000000000000000000000000DF -:10B1700000000000000000000000000000000000CF -:10B1800000000000000000000000000000000000BF -:10B1900000000000000000000000000000000000AF -:10B1A000000000000000000000000000000000009F -:10B1B000000000000000000000000000000000008F -:10B1C000000000000000000000000000000000007F -:10B1D000000000000000000000000000000000006F -:10B1E000000000000000000000000000000000005F -:10B1F000000000000000000000000000000000004F -:10B20000000000000000000000000000000000003E -:10B21000000000000000000000000000000000002E -:10B22000000000000000000000000000000000001E -:10B23000000000000000000000000000000000000E -:10B2400000000000000000000000000000000000FE -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B2800000000000000000000000000000000000BE -:10B2900000000000000000000000000000000000AE -:10B2A000000000000000000000000000000000009E -:10B2B000000000000000000000000000000000008E -:10B2C000000000000000000000000000000000007E -:10B2D000000000000000000000000000000000006E -:10B2E000000000000000000000000000000000005E -:10B2F000000000000000000000000000000000004E -:10B30000000000000000000000000000000000003D -:10B31000000000000000000000000000000000002D -:10B32000000000000000000000000000000000001D -:10B33000000000000000000000000000000000000D -:10B3400000000000000000000000000000000000FD -:10B3500000000000000000000000000000000000ED -:10B3600000000000000000000000000000000000DD -:10B3700000000000000000000000000000000000CD -:10B3800000000000000000000000000000000000BD -:10B3900000000000000000000000000000000000AD -:10B3A000000000000000000000000000000000009D -:10B3B000000000000000000000000000000000008D -:10B3C000000000000000000000000000000000007D -:10B3D000000000000000000000000000000000006D -:10B3E000000000000000000000000000000000005D -:10B3F000000000000000000000000000000000004D -:10B40000000000000000000000000000000000003C -:10B41000000000000000000000000000000000002C -:10B42000000000000000000000000000000000001C -:10B43000000000000000000000000000000000000C -:10B4400000000000000000000000000000000000FC -:10B4500000000000000000000000000000000000EC -:10B4600000000000000000000000000000000000DC -:10B4700000000000000000000000000000000000CC -:10B4800000000000000000000000000000000000BC -:10B4900000000000000000000000000000000000AC -:10B4A000000000000000000000000000000000009C -:10B4B000000000000000000000000000000000008C -:10B4C000000000000000000000000000000000007C -:10B4D000000000000000000000000000000000006C -:10B4E000000000000000000000000000000000005C -:10B4F000000000000000000000000000000000004C -:10B50000000000000000000000000000000000003B -:10B51000000000000000000000000000000000002B -:10B52000000000000000000000000000000000001B -:10B53000000000000000000000000000000000000B -:10B5400000000000000000000000000000000000FB -:10B5500000000000000000000000000000000000EB -:10B5600000000000000000000000000000000000DB -:10B5700000000000000000000000000000000000CB -:10B5800000000000000000000000000000000000BB -:10B5900000000000000000000000000000000000AB -:10B5A000000000000000000000000000000000009B -:10B5B000000000000000000000000000000000008B -:10B5C000000000000000000000000000000000007B -:10B5D000000000000000000000000000000000006B -:10B5E000000000000000000000000000000000005B -:10B5F000000000000000000000000000000000004B -:10B60000000000000000000000000000000000003A -:10B61000000000000000000000000000000000002A -:10B62000000000000000000000000000000000001A -:10B63000000000000000000000000000000000000A -:10B6400000000000000000000000000000000000FA -:10B6500000000000000000000000000000000000EA -:10B6600000000000000000000000000000000000DA -:10B6700000000000000000000000000000000000CA -:10B6800000000000000000000000000000000000BA -:10B6900000000000000000000000000000000000AA -:10B6A000000000000000000000000000000000009A -:10B6B000000000000000000000000000000000008A -:10B6C000000000000000000000000000000000007A -:10B6D000000000000000000000000000000000006A -:10B6E000000000000000000000000000000000005A -:10B6F000000000000000000000000000000000004A -:10B700000000000000000000000000000000000039 -:10B710000000000000000000000000000000000029 -:10B720000000000000000000000000000000000019 -:10B730000000000000000000000000000000000009 -:10B7400000000000000000000000000000000000F9 -:10B7500000000000000000000000000000000000E9 -:10B7600000000000000000000000000000000000D9 -:10B7700000000000000000000000000000000000C9 -:10B7800000000000000000000000000000000000B9 -:10B7900000000000000000000000000000000000A9 -:10B7A0000000000000000000000000000000000099 -:10B7B0000000000000000000000000000000000089 -:10B7C0000000000000000000000000000000000079 -:10B7D0000000000000000000000000000000000069 -:10B7E0000000000000000000000000000000000059 -:10B7F0000000000000000000000000000000000049 -:10B800000000000000000000000000000000000038 -:10B810000000000000000000000000000000000028 -:10B820000000000000000000000000000000000018 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B8500000000000000000000000000000000000E8 -:10B8600000000000000000000000000000000000D8 -:10B8700000000000000000000000000000000000C8 -:10B8800000000000000000000000000000000000B8 -:10B8900000000000000000000000000000000000A8 -:10B8A0000000000000000000000000000000000098 -:10B8B0000000000000000000000000000000000088 -:10B8C0000000000000000000000000000000000078 -:10B8D0000000000000000000000000000000000068 -:10B8E0000000000000000000000000000000000058 -:10B8F0000000000000000000000000000000000048 -:10B900000000000000000000000000000000000037 -:10B910000000000000000000000000000000000027 -:10B920000000000000000000000000000000000017 -:10B930000000000000000000000000000000000007 -:10B9400000000000000000000000000000000000F7 -:10B9500000000000000000000000000000000000E7 -:10B9600000000000000000000000000000000000D7 -:10B9700000000000000000000000000000000000C7 -:10B9800000000000000000000000000000000000B7 -:10B9900000000000000000000000000000000000A7 -:10B9A0000000000000000000000000000000000097 -:10B9B0000000000000000000000000000000000087 -:10B9C0000000000000000000000000000000000077 -:10B9D0000000000000000000000000000000000067 -:10B9E0000000000000000000000000000000000057 -:10B9F0000000000000000000000000000000000047 -:10BA00000000000000000000000000000000000036 -:10BA10000000000000000000000000000000000026 -:10BA20000000000000000000000000000000000016 -:10BA30000000000000000000000000000000000006 -:10BA400000000000000000000000000000000000F6 -:10BA500000000000000000000000000000000000E6 -:10BA600000000000000000000000000000000000D6 -:10BA700000000000000000000000000000000000C6 -:10BA800000000000000000000000000000000000B6 -:10BA900000000000000000000000000000000000A6 -:10BAA0000000000000000000000000000000000096 -:10BAB0000000000000000000000000000000000086 -:10BAC0000000000000000000000000000000000076 -:10BAD0000000000000000000000000000000000066 -:10BAE0000000000000000000000000000000000056 -:10BAF0000000000000000000000000000000000046 -:10BB00000000000000000000000000000000000035 -:10BB10000000000000000000000000000000000025 -:10BB20000000000000000000000000000000000015 -:10BB30000000000000000000000000000000000005 -:10BB400000000000000000000000000000000000F5 -:10BB500000000000000000000000000000000000E5 -:10BB600000000000000000000000000000000000D5 -:10BB700000000000000000000000000000000000C5 -:10BB800000000000000000000000000000000000B5 -:10BB900000000000000000000000000000000000A5 -:10BBA0000000000000000000000000000000000095 -:10BBB0000000000000000000000000000000000085 -:10BBC0000000000000000000000000000000000075 -:10BBD0000000000000000000000000000000000065 -:10BBE0000000000000000000000000000000000055 -:10BBF0000000000000000000000000000000000045 -:10BC00000000000000000000000000000000000034 -:10BC10000000000000000000000000000000000024 -:10BC20000000000000000000000000000000000014 -:10BC30000000000000000000000000000000000004 -:10BC400000000000000000000000000000000000F4 -:10BC500000000000000000000000000000000000E4 -:10BC600000000000000000000000000000000000D4 -:10BC700000000000000000000000000000000000C4 -:10BC800000000000000000000000000000000000B4 -:10BC900000000000000000000000000000000000A4 -:10BCA0000000000000000000000000000000000094 -:10BCB0000000000000000000000000000000000084 -:10BCC0000000000000000000000000000000000074 -:10BCD0000000000000000000000000000000000064 -:10BCE0000000000000000000000000000000000054 -:10BCF0000000000000000000000000000000000044 -:10BD00000000000000000000000000000000000033 -:10BD10000000000000000000000000000000000023 -:10BD20000000000000000000000000000000000013 -:10BD30000000000000000000000000000000000003 -:10BD400000000000000000000000000000000000F3 -:10BD500000000000000000000000000000000000E3 -:10BD600000000000000000000000000000000000D3 -:10BD700000000000000000000000000000000000C3 -:10BD800000000000000000000000000000000000B3 -:10BD900000000000000000000000000000000000A3 -:10BDA0000000000000000000000000000000000093 -:10BDB0000000000000000000000000000000000083 -:10BDC0000000000000000000000000000000000073 -:10BDD0000000000000000000000000000000000063 -:10BDE0000000000000000000000000000000000053 -:10BDF0000000000000000000000000000000000043 -:10BE00000000000000000000000000000000000032 -:10BE10000000000000000000000000000000000022 -:10BE20000000000000000000000000000000000012 -:10BE30000000000000000000000000000000000002 -:10BE400000000000000000000000000000000000F2 -:10BE500000000000000000000000000000000000E2 -:10BE600000000000000000000000000000000000D2 -:10BE700000000000000000000000000000000000C2 -:10BE800000000000000000000000000000000000B2 -:10BE900000000000000000000000000000000000A2 -:10BEA0000000000000000000000000000000000092 -:10BEB0000000000000000000000000000000000082 -:10BEC0000000000000000000000000000000000072 -:10BED0000000000000000000000000000000000062 -:10BEE0000000000000000000000000000000000052 -:10BEF0000000000000000000000000000000000042 -:10BF00000000000000000000000000000000000031 -:10BF10000000000000000000000000000000000021 -:10BF20000000000000000000000000000000000011 -:10BF30000000000000000000000000000000000001 -:10BF400000000000000000000000000000000000F1 -:10BF500000000000000000000000000000000000E1 -:10BF600000000000000000000000000000000000D1 -:10BF700000000000000000000000000000000000C1 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000000000000000D0 -:10C0700000000000000000000000000000000000C0 -:10C0800000000000000000000000000000000000B0 -:10C0900000000000000000000000000000000000A0 -:10C0A0000000000000000000000000000000000090 -:10C0B0000000000000000000000000000000000080 -:10C0C0000000000000000000000000000000000070 -:10C0D0000000000000000000000000000000000060 -:10C0E0000000000000000000000000000000000050 -:10C0F0000000000000000000000000000000000040 -:10C10000000000000000000000000000000000002F -:10C11000000000000000000000000000000000001F -:10C12000000000000000000000000000000000000F -:10C1300000000000000000000000000000000000FF -:10C1400000000000000000000000000000000000EF -:10C1500000000000000000000000000000000000DF -:10C1600000000000000000000000000000000000CF -:10C1700000000000000000000000000000000000BF -:10C1800000000000000000000000000000000000AF -:10C19000000000000000000000000000000000009F -:10C1A000000000000000000000000000000000008F -:10C1B000000000000000000000000000000000007F -:10C1C000000000000000000000000000000000006F -:10C1D000000000000000000000000000000000005F -:10C1E000000000000000000000000000000000004F -:10C1F000000000000000000000000000000000003F -:10C20000000000000000000000000000000000002E -:10C21000000000000000000000000000000000001E -:10C22000000000000000000000000000000000000E -:10C2300000000000000000000000000000000000FE -:10C2400000000000000000000000000000000000EE -:10C2500000000000000000000000000000000000DE -:10C2600000000000000000000000000000000000CE -:10C2700000000000000000000000000000000000BE -:10C2800000000000000000000000000000000000AE -:10C29000000000000000000000000000000000009E -:10C2A000000000000000000000000000000000008E -:10C2B000000000000000000000000000000000007E -:10C2C000000000000000000000000000000000006E -:10C2D000000000000000000000000000000000005E -:10C2E000000000000000000000000000000000004E -:10C2F000000000000000000000000000000000003E -:10C30000000000000000000000000000000000002D -:10C31000000000000000000000000000000000001D -:10C32000000000000000000000000000000000000D -:10C3300000000000000000000000000000000000FD -:10C3400000000000000000000000000000000000ED -:10C3500000000000000000000000000000000000DD -:10C3600000000000000000000000000000000000CD -:10C3700000000000000000000000000000000000BD -:10C3800000000000000000000000000000000000AD -:10C39000000000000000000000000000000000009D -:10C3A000000000000000000000000000000000008D -:10C3B000000000000000000000000000000000007D -:10C3C000000000000000000000000000000000006D -:10C3D000000000000000000000000000000000005D -:10C3E000000000000000000000000000000000004D -:10C3F000000000000000000000000000000000003D -:10C40000000000000000000000000000000000002C -:10C41000000000000000000000000000000000001C -:10C42000000000000000000000000000000000000C -:10C4300000000000000000000000000000000000FC -:10C4400000000000000000000000000000000000EC -:10C4500000000000000000000000000000000000DC -:10C4600000000000000000000000000000000000CC -:10C4700000000000000000000000000000000000BC -:10C4800000000000000000000000000000000000AC -:10C49000000000000000000000000000000000009C -:10C4A000000000000000000000000000000000008C -:10C4B000000000000000000000000000000000007C -:10C4C000000000000000000000000000000000006C -:10C4D000000000000000000000000000000000005C -:10C4E000000000000000000000000000000000004C -:10C4F000000000000000000000000000000000003C -:10C50000000000000000000000000000000000002B -:10C51000000000000000000000000000000000001B -:10C52000000000000000000000000000000000000B -:10C5300000000000000000000000000000000000FB -:10C5400000000000000000000000000000000000EB -:10C5500000000000000000000000000000000000DB -:10C5600000000000000000000000000000000000CB -:10C5700000000000000000000000000000000000BB -:10C5800000000000000000000000000000000000AB -:10C59000000000000000000000000000000000009B -:10C5A000000000000000000000000000000000008B -:10C5B000000000000000000000000000000000007B -:10C5C000000000000000000000000000000000006B -:10C5D000000000000000000000000000000000005B -:10C5E000000000000000000000000000000000004B -:10C5F000000000000000000000000000000000003B -:10C60000000000000000000000000000000000002A -:10C61000000000000000000000000000000000001A -:10C62000000000000000000000000000000000000A -:10C6300000000000000000000000000000000000FA -:10C6400000000000000000000000000000000000EA -:10C6500000000000000000000000000000000000DA -:10C6600000000000000000000000000000000000CA -:10C6700000000000000000000000000000000000BA -:10C6800000000000000000000000000000000000AA -:10C69000000000000000000000000000000000009A -:10C6A000000000000000000000000000000000008A -:10C6B000000000000000000000000000000000007A -:10C6C000000000000000000000000000000000006A -:10C6D000000000000000000000000000000000005A -:10C6E000000000000000000000000000000000004A -:10C6F000000000000000000000000000000000003A -:10C700000000000000000000000000000000000029 -:10C710000000000000000000000000000000000019 -:10C720000000000000000000000000000000000009 -:10C7300000000000000000000000000000000000F9 -:10C7400000000000000000000000000000000000E9 -:10C7500000000000000000000000000000000000D9 -:10C7600000000000000000000000000000000000C9 -:10C7700000000000000000000000000000000000B9 -:10C7800000000000000000000000000000000000A9 -:10C790000000000000000000000000000000000099 -:10C7A0000000000000000000000000000000000089 -:10C7B0000000000000000000000000000000000079 -:10C7C0000000000000000000000000000000000069 -:10C7D0000000000000000000000000000000000059 -:10C7E0000000000000000000000000000000000049 -:10C7F0000000000000000000000000000000000039 -:10C800000000000000000000000000000000000028 -:10C810000000000000000000000000000000000018 -:10C820000000000000000000000000000000000008 -:10C8300000000000000000000000000000000000F8 -:10C8400000000000000000000000000000000000E8 -:10C8500000000000000000000000000000000000D8 -:10C8600000000000000000000000000000000000C8 -:10C8700000000000000000000000000000000000B8 -:10C8800000000000000000000000000000000000A8 -:10C890000000000000000000000000000000000098 -:10C8A0000000000000000000000000000000000088 -:10C8B0000000000000000000000000000000000078 -:10C8C0000000000000000000000000000000000068 -:10C8D0000000000000000000000000000000000058 -:10C8E0000000000000000000000000000000000048 -:10C8F0000000000000000000000000000000000038 -:10C900000000000000000000000000000000000027 -:10C910000000000000000000000000000000000017 -:10C920000000000000000000000000000000000007 -:10C9300000000000000000000000000000000000F7 -:10C9400000000000000000000000000000000000E7 -:10C9500000000000000000000000000000000000D7 -:10C9600000000000000000000000000000000000C7 -:10C9700000000000000000000000000000000000B7 -:10C9800000000000000000000000000000000000A7 -:10C990000000000000000000000000000000000097 -:10C9A0000000000000000000000000000000000087 -:10C9B0000000000000000000000000000000000077 -:10C9C0000000000000000000000000000000000067 -:10C9D0000000000000000000000000000000000057 -:10C9E0000000000000000000000000000000000047 -:10C9F0000000000000000000000000000000000037 -:10CA00000000000000000000000000000000000026 -:10CA10000000000000000000000000000000000016 -:10CA20000000000000000000000000000000000006 -:10CA300000000000000000000000000000000000F6 -:10CA400000000000000000000000000000000000E6 -:10CA500000000000000000000000000000000000D6 -:10CA600000000000000000000000000000000000C6 -:10CA700000000000000000000000000000000000B6 -:10CA800000000000000000000000000000000000A6 -:10CA90000000000000000000000000000000000096 -:10CAA0000000000000000000000000000000000086 -:10CAB0000000000000000000000000000000000076 -:10CAC0000000000000000000000000000000000066 -:10CAD0000000000000000000000000000000000056 -:10CAE0000000000000000000000000000000000046 -:10CAF0000000000000000000000000000000000036 -:10CB00000000000000000000000000000000000025 -:10CB10000000000000000000000000000000000015 -:10CB20000000000000000000000000000000000005 -:10CB300000000000000000000000000000000000F5 -:10CB400000000000000000000000000000000000E5 -:10CB500000000000000000000000000000000000D5 -:10CB600000000000000000000000000000000000C5 -:10CB700000000000000000000000000000000000B5 -:10CB800000000000000000000000000000000000A5 -:10CB90000000000000000000000000000000000095 -:10CBA0000000000000000000000000000000000085 -:10CBB0000000000000000000000000000000000075 -:10CBC0000000000000000000000000000000000065 -:10CBD0000000000000000000000000000000000055 -:10CBE0000000000000000000000000000000000045 -:10CBF0000000000000000000000000000000000035 -:10CC00000000000000000000000000000000000024 -:10CC10000000000000000000000000000000000014 -:10CC20000000000000000000000000000000000004 -:10CC300000000000000000000000000000000000F4 -:10CC400000000000000000000000000000000000E4 -:10CC500000000000000000000000000000000000D4 -:10CC600000000000000000000000000000000000C4 -:10CC700000000000000000000000000000000000B4 -:10CC800000000000000000000000000000000000A4 -:10CC90000000000000000000000000000000000094 -:10CCA0000000000000000000000000000000000084 -:10CCB0000000000000000000000000000000000074 -:10CCC0000000000000000000000000000000000064 -:10CCD0000000000000000000000000000000000054 -:10CCE0000000000000000000000000000000000044 -:10CCF0000000000000000000000000000000000034 -:10CD00000000000000000000000000000000000023 -:10CD10000000000000000000000000000000000013 -:10CD20000000000000000000000000000000000003 -:10CD300000000000000000000000000000000000F3 -:10CD400000000000000000000000000000000000E3 -:10CD500000000000000000000000000000000000D3 -:10CD600000000000000000000000000000000000C3 -:10CD700000000000000000000000000000000000B3 -:10CD800000000000000000000000000000000000A3 -:10CD90000000000000000000000000000000000093 -:10CDA0000000000000000000000000000000000083 -:10CDB0000000000000000000000000000000000073 -:10CDC0000000000000000000000000000000000063 -:10CDD0000000000000000000000000000000000053 -:10CDE0000000000000000000000000000000000043 -:10CDF0000000000000000000000000000000000033 -:10CE00000000000000000000000000000000000022 -:10CE10000000000000000000000000000000000012 -:10CE20000000000000000000000000000000000002 -:10CE300000000000000000000000000000000000F2 -:10CE400000000000000000000000000000000000E2 -:10CE500000000000000000000000000000000000D2 -:10CE600000000000000000000000000000000000C2 -:10CE700000000000000000000000000000000000B2 -:10CE800000000000000000000000000000000000A2 -:10CE90000000000000000000000000000000000092 -:10CEA0000000000000000000000000000000000082 -:10CEB0000000000000000000000000000000000072 -:10CEC0000000000000000000000000000000000062 -:10CED0000000000000000000000000000000000052 -:10CEE0000000000000000000000000000000000042 -:10CEF0000000000000000000000000000000000032 -:10CF00000000000000000000000000000000000021 -:10CF10000000000000000000000000000000000011 -:10CF20000000000000000000000000000000000001 -:10CF300000000000000000000000000000000000F1 -:10CF400000000000000000000000000000000000E1 -:10CF500000000000000000000000000000000000D1 -:10CF600000000000000000000000000000000000C1 -:10CF700000000000000000000000000000000000B1 -:10CF800000000000000000000000000000000000A1 -:10CF90000000000000000000000000000000000091 -:10CFA0000000000000000000000000000000000081 -:10CFB0000000000000000000000000000000000071 -:10CFC0000000000000000000000000000000000061 -:10CFD0000000000000000000000000000000000051 -:10CFE0000000000000000000000000000000000041 -:10CFF0000000000000000000000000000000000031 -:10D000000000000000000000000000000000000020 -:10D010000000000000000000000000000000000010 -:10D020000000000000000000000000000000000000 -:10D0300000000000000000000000000000000000F0 -:10D0400000000000000000000000000000000000E0 -:10D0500000000000000000000000000000000000D0 -:10D0600000000000000000000000000000000000C0 -:10D0700000000000000000000000000000000000B0 -:10D0800000000000000000000000000000000000A0 -:10D090000000000000000000000000000000000090 -:10D0A0000000000000000000000000000000000080 -:10D0B0000000000000000000000000000000000070 -:10D0C0000000000000000000000000000000000060 -:10D0D0000000000000000000000000000000000050 -:10D0E0000000000000000000000000000000000040 -:10D0F0000000000000000000000000000000000030 -:10D10000000000000000000000000000000000001F -:10D11000000000000000000000000000000000000F -:10D1200000000000000000000000000000000000FF -:10D1300000000000000000000000000000000000EF -:10D1400000000000000000000000000000000000DF -:10D1500000000000000000000000000000000000CF -:10D1600000000000000000000000000000000000BF -:10D1700000000000000000000000000000000000AF -:10D18000000000000000000000000000000000009F -:10D19000000000000000000000000000000000008F -:10D1A000000000000000000000000000000000007F -:10D1B000000000000000000000000000000000006F -:10D1C000000000000000000000000000000000005F -:10D1D000000000000000000000000000000000004F -:10D1E000000000000000000000000000000000003F -:10D1F000000000000000000000000000000000002F -:10D20000000000000000000000000000000000001E -:10D21000000000000000000000000000000000000E -:10D2200000000000000000000000000000000000FE -:10D2300000000000000000000000000000000000EE -:10D2400000000000000000000000000000000000DE -:10D2500000000000000000000000000000000000CE -:10D2600000000000000000000000000000000000BE -:10D2700000000000000000000000000000000000AE -:10D28000000000000000000000000000000000009E -:10D29000000000000000000000000000000000008E -:10D2A000000000000000000000000000000000007E -:10D2B000000000000000000000000000000000006E -:10D2C000000000000000000000000000000000005E -:10D2D000000000000000000000000000000000004E -:10D2E000000000000000000000000000000000003E -:10D2F000000000000000000000000000000000002E -:10D30000000000000000000000000000000000001D -:10D31000000000000000000000000000000000000D -:10D3200000000000000000000000000000000000FD -:10D3300000000000000000000000000000000000ED -:10D3400000000000000000000000000000000000DD -:10D3500000000000000000000000000000000000CD -:10D3600000000000000000000000000000000000BD -:10D3700000000000000000000000000000000000AD -:10D38000000000000000000000000000000000009D -:10D39000000000000000000000000000000000008D -:10D3A000000000000000000000000000000000007D -:10D3B000000000000000000000000000000000006D -:10D3C000000000000000000000000000000000005D -:10D3D000000000000000000000000000000000004D -:10D3E000000000000000000000000000000000003D -:10D3F000000000000000000000000000000000002D -:10D40000000000000000000000000000000000001C -:10D41000000000000000000000000000000000000C -:10D4200000000000000000000000000000000000FC -:10D4300000000000000000000000000000000000EC -:10D4400000000000000000000000000000000000DC -:10D4500000000000000000000000000000000000CC -:10D4600000000000000000000000000000000000BC -:10D4700000000000000000000000000000000000AC -:10D48000000000000000000000000000000000009C -:10D49000000000000000000000000000000000008C -:10D4A000000000000000000000000000000000007C -:10D4B000000000000000000000000000000000006C -:10D4C000000000000000000000000000000000005C -:10D4D000000000000000000000000000000000004C -:10D4E000000000000000000000000000000000003C -:10D4F000000000000000000000000000000000002C -:10D50000000000000000000000000000000000001B -:10D51000000000000000000000000000000000000B -:10D5200000000000000000000000000000000000FB -:10D5300000000000000000000000000000000000EB -:10D5400000000000000000000000000000000000DB -:10D5500000000000000000000000000000000000CB -:10D5600000000000000000000000000000000000BB -:10D5700000000000000000000000000000000000AB -:10D58000000000000000000000000000000000009B -:10D59000000000000000000000000000000000008B -:10D5A000000000000000000000000000000000007B -:10D5B000000000000000000000000000000000006B -:10D5C000000000000000000000000000000000005B -:10D5D000000000000000000000000000000000004B -:10D5E000000000000000000000000000000000003B -:10D5F000000000000000000000000000000000002B -:10D60000000000000000000000000000000000001A -:10D61000000000000000000000000000000000000A -:10D6200000000000000000000000000000000000FA -:10D6300000000000000000000000000000000000EA -:10D6400000000000000000000000000000000000DA -:10D6500000000000000000000000000000000000CA -:10D6600000000000000000000000000000000000BA -:10D6700000000000000000000000000000000000AA -:10D68000000000000000000000000000000000009A -:10D69000000000000000000000000000000000008A -:10D6A000000000000000000000000000000000007A -:10D6B000000000000000000000000000000000006A -:10D6C000000000000000000000000000000000005A -:10D6D000000000000000000000000000000000004A -:10D6E000000000000000000000000000000000003A -:10D6F000000000000000000000000000000000002A -:10D700000000000000000000000000000000000019 -:10D710000000000000000000000000000000000009 -:10D7200000000000000000000000000000000000F9 -:10D7300000000000000000000000000000000000E9 -:10D7400000000000000000000000000000000000D9 -:10D7500000000000000000000000000000000000C9 -:10D7600000000000000000000000000000000000B9 -:10D7700000000000000000000000000000000000A9 -:10D780000000000000000000000000000000000099 -:10D790000000000000000000000000000000000089 -:10D7A0000000000000000000000000000000000079 -:10D7B0000000000000000000000000000000000069 -:10D7C0000000000000000000000000000000000059 -:10D7D0000000000000000000000000000000000049 -:10D7E0000000000000000000000000000000000039 -:10D7F0000000000000000000000000000000000029 -:10D800000000000000000000000000000000000018 -:10D810000000000000000000000000000000000008 -:10D8200000000000000000000000000000000000F8 -:10D8300000000000000000000000000000000000E8 -:10D8400000000000000000000000000000000000D8 -:10D8500000000000000000000000000000000000C8 -:10D8600000000000000000000000000000000000B8 -:10D8700000000000000000000000000000000000A8 -:10D880000000000000000000000000000000000098 -:10D890000000000000000000000000000000000088 -:10D8A0000000000000000000000000000000000078 -:10D8B0000000000000000000000000000000000068 -:10D8C0000000000000000000000000000000000058 -:10D8D0000000000000000000000000000000000048 -:10D8E0000000000000000000000000000000000038 -:10D8F0000000000000000000000000000000000028 -:10D900000000000000000000000000000000000017 -:10D910000000000000000000000000000000000007 -:10D9200000000000000000000000000000000000F7 -:10D9300000000000000000000000000000000000E7 -:10D9400000000000000000000000000000000000D7 -:10D9500000000000000000000000000000000000C7 -:10D9600000000000000000000000000000000000B7 -:10D9700000000000000000000000000000000000A7 -:10D980000000000000000000000000000000000097 -:10D990000000000000000000000000000000000087 -:10D9A0000000000010000003000000000000000D57 -:10D9B0000000000D3C020801244282603C03080183 -:10D9C00024638320AC4000000043202B1480FFFD23 -:10D9D000244200043C1D080037BD9FFC03A0F02139 -:10D9E0003C100800261031D83C1C0801279C82609E -:10D9F0000E0011EA000000000000000D3C02800053 -:10DA000030A5FFFF30C600FF344301803C08800092 -:10DA10008D0901B80520FFFE00000000AC64000085 -:10DA200024040002A4650008A066000AA064000B9C -:10DA3000AC6700183C03100003E00008AD0301B818 -:10DA40003C0560008CA24FF80440FFFE000000007F -:10DA5000ACA44FC03C0310003C040200ACA44FC473 -:10DA600003E00008ACA34FF89486000C00A05021FE -:10DA70002488001400062B02000510800044482171 -:10DA80000109182B10600011000000009103000034 -:10DA90002C64000950800009911900010003608086 -:10DAA0003C0D080125AD8108018D58218D670000CE -:10DAB00000E0000800000000911900010119402158 -:10DAC0000109302B54C0FFF29103000003E000086D -:10DAD000000010210A000CBE25080001910F000172 -:10DAE000240E000A15EE00400128C8232F38000A32 -:10DAF0001700003D250D00028D580000250F00067F -:10DB0000370E0100AD4E0000910C000291AB0001F8 -:10DB100091A4000291A60003000C2E00000B3C0013 -:10DB200000A7102500041A000043C8250326C025BD -:10DB3000AD580004910E000691ED000191E700023E -:10DB400091E50003000E5E00000D6400016C3025BD -:10DB50000007220000C41025004518252508000AEA -:10DB60000A000CBEAD430008910F0001250400021D -:10DB70002408000255E80001012020210A000CBE03 -:10DB800000804021910C0001240B0003158B00162E -:10DB9000000000008D580000910E000225080003CF -:10DBA000370D0008A14E00100A000CBEAD4D00005C -:10DBB00091190001240F0004172F000B0000000032 -:10DBC00091070002910400038D43000000072A0022 -:10DBD00000A410253466000425080004AD42000CA2 -:10DBE0000A000CBEAD46000003E00008240200015C -:10DBF00027BDFFE8AFBF0014AFB000100E0014E661 -:10DC0000008080213C0480083485008090A60005B7 -:10DC10002403FFFE0200202100C310248FBF001444 -:10DC20008FB00010A0A200050A0014F027BD001854 -:10DC300027BDFFE8AFB00010AFBF00140E000F4EBD -:10DC4000008080213C06800834C5008090A400003C -:10DC500024020050308300FF106200073C0980005E -:10DC6000020020218FBF00148FB00010AD20018072 -:10DC70000A00101027BD0018240801003C0780008E -:10DC8000020020218FBF00148FB00010ACE801808B -:10DC90000A00101027BD001827BDFF703C0880083F -:10DCA000AFB60080AFB5007CAFB1006CAFBF008CE9 -:10DCB000AFBE0088AFB70084AFB40078AFB30074D4 -:10DCC000AFB20070AFB00068350500803C0780003F -:10DCD0008CF2012890A40009ACE0008490A6000515 -:10DCE000309100FF0000A8210006182730620001D3 -:10DCF0000000B02114400067AFA0005090A90000C0 -:10DD000024050020312400FF10850016240A00504D -:10DD1000108A008C000000003C0C08008D8C00DC98 -:10DD2000258B00013C010800AC2B00DC0E0015DC4B -:10DD3000000000008FBF008C8FBE00888FB700846A -:10DD40008FB600808FB5007C8FB400788FB30074DD -:10DD50008FB200708FB1006C8FB0006803E00008D4 -:10DD600027BD00900000000D3C108000AFA00030E7 -:10DD7000961F01168E1901043C1E002036130C005C -:10DD8000033EC0240018B82B00173140AFA6003066 -:10DD90008E0E010433F4FFFF3C0F004002938021FC -:10DDA00001CF68249213000D11A0004834C4004034 -:10DDB000326200201440000234860080008030214E -:10DDC00014C00093AFA600303C05800834A8008042 -:10DDD0009107000830E6004050C000063C0680086D -:10DDE00024090004122900A2240A0012122A002980 -:10DDF0003C06800834D401003C17800096EF011ADD -:10DE0000960D000E928E0008326B000431F7FFFF72 -:10DE100001CD6004AFAC00548E14000411600031D9 -:10DE20008E1E000834C3008090790008333800400B -:10DE300017000028000000008C730050029390230C -:10DE4000064000063C0C80008C7E0034029E80233D -:10DE5000060200838EA200083C0C8000AD800044C6 -:10DE6000240200018FBF008C8FBE00888FB7008412 -:10DE70008FB600808FB5007C8FB400788FB30074AC -:10DE80008FB200708FB1006C8FB0006803E00008A3 -:10DE900027BD00900E000D1A000020218FBF008CBE -:10DEA0008FBE00888FB700848FB600808FB5007C4E -:10DEB0008FB400788FB300748FB200708FB1006C94 -:10DEC0008FB0006803E0000827BD00900A000D7ABB -:10DED00000C020210E00163D028020211440FFDFEB -:10DEE0003C0C80003C038008346300808C6200346A -:10DEF0000282F82307E00017000000003C1508002C -:10DF00008EB5310026B100013C010800AC31310072 -:10DF10000E0014E6024020213C0B80083570008082 -:10DF2000920A002502402021354200040E0014F020 -:10DF3000A20200250E000C9E024020210A000DA71F -:10DF4000240200013C15080126B583100A000D6962 -:10DF50003C1080008C660030028620231880000868 -:10DF60002409000C3C0808008D083100327300FCC5 -:10DF70000000B821250700013C010800AC27310052 -:10DF8000AFA900308C65003000B4382318E000DB06 -:10DF900002E7502A1540FFDE0000000012E7002AC9 -:10DFA00002E768230287A02131B7FFFF326E00022B -:10DFB00011C00034327F00103C148008369000807D -:10DFC000920F000831F6004052C000CE8EA2000829 -:10DFD000024020210E0014E624130018A2130009A9 -:10DFE000921800052419FFFE024020210319B824CD -:10DFF0000E0014F0A21700052404003900002821A7 -:10E000000E001618240600180A000DA724020001AD -:10E0100092B6000C3C048008348300808C67003882 -:10E020000016AB0036B10081024020213225F0817C -:10E030000E000C8D30C600FF3C0C8000AD8000440B -:10E040000A000DA7240200013A6C0001318B000187 -:10E050001560FFAF0287A0210A000DF80000000044 -:10E060000040F809240400160A000DA7240200014C -:10E07000024020210E00171D020028210A000D5C1D -:10E080008FBF008C13E0FF743C038008346800806D -:10E090008D0400388C66000403C610231C40FF6FFB -:10E0A0003C0C800003C4282304A200010080F0215E -:10E0B000AFB40010AFB70014AFA700183C1F80002A -:10E0C00097E301208D0900309506005C8FB900545C -:10E0D0008FAC00303062FFFF30D8FFFF0047702167 -:10E0E00037EF40000338682B01CF5821018D5025B0 -:10E0F000AFAB0020AFA90028AFAA0030AFA9002421 -:10E10000AFA0002CAFBE00349107000830E4000837 -:10E110001480008F020020218EA200040040F80924 -:10E1200027A400108FA900303128000255000001FB -:10E13000327300FE3C048008348C0080918B000810 -:10E14000316A0040514000128FA400248C8D0004DD -:10E1500011BE00BE240E00143265000110A0000C98 -:10E160008FA400242404000C122400D42A27000DBC -:10E1700010E000CE2409000E2408000A52280001F5 -:10E18000241600088FA2002424440001AFA4002418 -:10E190008FA600143C038008346500800086F821B7 -:10E1A0008CB10030ACBF003090B9004E8CAE003066 -:10E1B0003418FFFF0338780401CF6821ACAD003478 -:10E1C0008FA600308FAC005430CA000803CC582111 -:10E1D0001140000CAFAB00588CA400208FB0005849 -:10E1E0001090009430C600FF92A2000C8FA700345C -:10E1F0000240202100024B00352800800E000C8DCB -:10E200003105F0803C0C8008359000808E0B00308A -:10E210000171502319400070265900803C180800F5 -:10E220008F183198241FFF80033F7824332D007FFF -:10E230003C0680003C0E800433110010ACCF0090EF -:10E240001220003401AE282190A3006B54600032EC -:10E250003C10800824070001A0A7006B94C4007A3A -:10E260002486000AA60600123C0D800835A5008011 -:10E2700090B10008322C0040158000043C03800857 -:10E28000326E000115C0006200000000346400809E -:10E290008C8F00208FB3005811F3000A3463010003 -:10E2A0008C7900000299C0231B0000778FA80058CA -:10E2B000AC880020AC74000024140001AC7E000483 -:10E2C000AFB4005016C00037000000008FA400500B -:10E2D000148000300000000012E00005000018214A -:10E2E0008FA900303137000452E0FE920060102107 -:10E2F000240300010A000D5B006010210A000DF9E3 -:10E30000000038210040F809240400170A000DA776 -:10E31000240200013C10800836100080240900010E -:10E32000024020210E0014E6A609001292080025E2 -:10E3300024050001AFA50050350200010240202154 -:10E340000E0014F0A20200250A000EA93C0D800860 -:10E3500027A50038AFA800600E000CA8AFA00038B9 -:10E360001440FF6D8FA800608FA5003830B0010009 -:10E370005200FF6A8EA200048FA3003C8D07005854 -:10E38000006720230483FF64AD0300580A000E5584 -:10E390008EA200040E000C9E024020210A000EC432 -:10E3A000000000000E0014E6024020213C05800819 -:10E3B00034A30080024020210E0014F0A076000952 -:10E3C00002C03021240400370E0016180000282156 -:10E3D0000A000EC28FA400508FA200185840FFA35D -:10E3E0003C0D80080E0014E602402021920A002510 -:10E3F000240B0001AFAB0050354200040240202145 -:10E400000E0014F0A20200250A000EA93C0D80089F -:10E410008CB600308EBE00082404001826D50001FA -:10E4200003C0F809ACB500308FB200300A000D5BB4 -:10E43000324200043C07800094E5011A50A0FF6AB4 -:10E4400034C600100A000E8992A2000C122E002A77 -:10E450002A2F001511E0001E241900162418000CA4 -:10E460005638FF3E326500013C1F800893E3001BD5 -:10E470002410FFBD2416000E00703024A3E6001BFC -:10E480000A000E65326500018C7F000017F4FF8DD5 -:10E49000000000008C67000403C7302304C1FF8420 -:10E4A0008FA800580A000EBF000000001629FF3692 -:10E4B0008FA200240A000E70241600102411000EF2 -:10E4C00052D1FF30241600100A000E6F24160016D9 -:10E4D0005639FF22326500013C1F800893E3001B80 -:10E4E0002410FFBD2416001000703024A3E6001B8A -:10E4F0000A000E65326500010A000E64241600123F -:10E500003C0380008C6201B80440FFFE2404080034 -:10E51000AC6401B803E000080000000030A5FFFF74 -:10E5200030C6FFFF3C0780008CE201B80440FFFECC -:10E5300034E80180AD040000ACE400203C04800815 -:10E54000948300483063FFFF1060001D3C0B800087 -:10E5500024AA0012006A482B5120001A240A000342 -:10E5600094F901208F890000240C001A3338FFFF32 -:10E570002707FFFE0067782B39EE000100096B8248 -:10E5800001AE5824A10C000B116000478F830004DA -:10E59000A50700148F88000435070001AF87000429 -:10E5A00030CC00405580000F3C0880003C0C8000BF -:10E5B00035840180A485000E0A000F988F8F000C0F -:10E5C000240A00033564018030CC00408F890000AC -:10E5D0008F870004A08A000B5180FFF53C0C80005F -:10E5E0003C088000950301203C08800895180040F5 -:10E5F0003079FFFF272EFFFE330FFFFF01CF682B7F -:10E6000011A0000301C02021950200403044FFFF0B -:10E610003C0B800000A4502335650180A4A4000EAB -:10E62000A4AA00248F8F000C3C05800034AE01802A -:10E630002418000230ED8000A5D8000CA5C90010F8 -:10E64000ADCF0028A5C6000811A0000E3C04800034 -:10E6500094AA01163142FFFC244800040105182148 -:10E660008C7940003326FFFF14C00007240EBFFF43 -:10E670003C0BFFFF35657FFF00E53824AF870004C2 -:10E680003C048000240EBFFF348C018000EE68241F -:10E69000A58D0026AD89002C3C071000AC8701B881 -:10E6A00003E00008000000002402FFFE006238249E -:10E6B0000A000F76AF8700043C05800034A4007088 -:10E6C0008C8A000090A601128F84000027BDFFF005 -:10E6D00030C300FF0003188230820100000038219F -:10E6E00010400039246600033087400050E00039B4 -:10E6F00030882000000610800045C8218F2F400080 -:10E700002478000400187080AFAF000001C56821B4 -:10E710008DAC4000AFAC000494AB01163169FFFC36 -:10E72000012540218D054000AFA500088FA90008F4 -:10E7300000003021000028213C07080024E70100E8 -:10E740000A000FE9240800089042000024A50001F7 -:10E750002CAD000C0062C8210019C080030778218D -:10E760008DEE000011A0000600CE302603A510217A -:10E7700014A8FFF500051A005520FFF49042000090 -:10E780003C048000348700703C0508008CA53104EF -:10E790008CE300002CA8002011000009006A382337 -:10E7A000000558803C0C0800258C3108016C48217C -:10E7B00024AA0001AD2700003C010800AC2A310466 -:10E7C000AF86000C2407000100E0102103E00008E0 -:10E7D00027BD00101100FFFC0000382100066080FA -:10E7E000018558218D6440002469000400093880A7 -:10E7F000AFA4000000E518218C664000AFA000081F -:10E800000A000FD9AFA6000427BDFFD8AFB2001889 -:10E81000AFB00010AFBF0024AFB40020AFB3001CF6 -:10E82000AFB100148F8700003C0480009483010E78 -:10E8300030E2400000008021104000103072FFFFE5 -:10E840003C06002000E6282410A0000D30EA8000DD -:10E850008F8800042409BFFF00E938243503100025 -:10E86000AF87000030F120001620000B3C1400049C -:10E870002418FFBF0A0010380078102430EA800006 -:10E88000154000863C0C002030F120001220FFF8DB -:10E890008F8300043C14000400F498241260FFF5F8 -:10E8A0002418FFBF3462004030F901001320000F2C -:10E8B000AF8200043C02002000E2F82413E00005CF -:10E8C0003C0B80003C04000400E41824106000CFDE -:10E8D00000000000956A011E9569011C3146FFFF8A -:10E8E0000009440000C82825AF85000C3C0E8000BC -:10E8F00095CD010C8DC44000340CFFFF108C00B08E -:10E9000031A5FFFF308F010055E0000124100010F9 -:10E9100030F11000522000083611000130F30020C1 -:10E920001660009F3C18100000F8A0241680009686 -:10E930003C040C003611000130E801001500000B0A -:10E940003C0A00018F8800043109400015200008AE -:10E9500000EA30243C0C1F0100EC58243C0A100053 -:10E96000516A00AE30AD02003C0A000100EA3024DA -:10E9700014C000953C05100000E520240000402153 -:10E98000108000070000902100079E023272000FE5 -:10E99000001278803C0E080125CE82C001EE402195 -:10E9A0008F9400181280004702208021108000916F -:10E9B000000000003C0980009539010E9103000021 -:10E9C000022030213338FFFF2705000410600008C3 -:10E9D0000000A021241F0003107F013A240400023C -:10E9E000910C00011184011830EA00400012A1C00E -:10E9F0008F92001C52400001362600403C138000DC -:10EA00008E6F400031F10100122000CB30D1FFFBAE -:10EA10003C1808008F18002430D20004330600048C -:10EA200014C000CC30B0FFFF564000013631000466 -:10EA300002802021020028210E000F5502203021E3 -:10EA40001640000D00002021366501803C04800046 -:10EA50008C9301B80660FFFE2419200024140002E4 -:10EA6000A4B90008A0B4000BA4A000103C0510003D -:10EA7000AC8501B8000020218FBF00248FB4002096 -:10EA80008FB3001C8FB200188FB100148FB000102C -:10EA90000080102103E0000827BD002800EC582466 -:10EAA0001160FF7A30F120008F8D00043C0FFFFFD2 -:10EAB00035EE7FFF00EE382435A380000A001027D2 -:10EAC000AF8700003C0208008C4200383C0408007C -:10EAD000248400381040004B2449FFFF3C03800091 -:10EAE000946C010E318BFFFF110000A02573000410 -:10EAF0003C1008008E1000301200000A30E60100C1 -:10EB00008F8A000431434000106000063C0F0F0064 -:10EB100000EF70243C0D010001AE402B110000DF1E -:10EB20003265FFFF10C000693C140F0000F4282478 -:10EB30003C18020010B800658F99000C3270FFFF7E -:10EB40000329982402649021924900042527000497 -:10EB5000000721C002002821362600020E000F55B2 -:10EB6000000000008FBF00248FB400208FB3001C72 -:10EB70008FB200188FB100148FB000100000102168 -:10EB800003E0000827BD00283C020BFF00E4182426 -:10EB9000345FFFFF03E3C82B5320FF6736110001EA -:10EBA0003C0608008CC6002C3611000524D000015C -:10EBB0003C010800AC30002C0A00105D30E8010078 -:10EBC0000A00105224100020024028213C120800A4 -:10EBD0008E5200D824040080264D00013C0108001C -:10EBE000AC2D00D80E000F55240600030A0010E8D3 -:10EBF0008FBF00243C080801250882C00A00107C51 -:10EC00003C0980000A0010C5000048210E000FBC1E -:10EC1000000000000A0010498F87000015A0FF5374 -:10EC20003C0A00012645000430AAFFFF36260002F8 -:10EC30003C0380008C7201B80640FFFE8F850008FF -:10EC400034690180AD20000010A000AF3C048000BA -:10EC5000254F001200AF702B51C000AC24030003FD -:10EC6000947801202414001A30F140003313FFFF80 -:10EC7000A134000B122000B62663FFFE00A3C82BB0 -:10EC8000572000B4241FFFFE35080001A5230014FF -:10EC9000AF8800043C108000240CBFFF010C482406 -:10ECA000240B000236080180A50B000CA50A000EFB -:10ECB000A5060008A5090026A50700103C071000BE -:10ECC000AE0701B80A0010E88FBF00243C0308001B -:10ECD0008C6300D02E45000C001221C0386B00015F -:10ECE0002D6200010045F82417E0FF9A3270FFFF03 -:10ECF000264CFFFC2D84000454800050000020218D -:10ED0000386A00022D430001006580241600004A85 -:10ED10003270FFFF00076A420012702B01AE4024E0 -:10ED20005500006300002021001221C002002821AC -:10ED30000A0010E53626000234DF0002028020219E -:10ED400033E6FFFF0E000F5530A5FFFF0A0010ACA1 -:10ED50000000202124040100020028210E000F558C -:10ED6000022030210A001098000000008C6640004C -:10ED700030CF010011E0003D30F801003C120800E6 -:10ED80008E52002413000011323400043C1F0F0087 -:10ED900000FFC8243C0502001325000C8F8C000CDA -:10EDA000022030213265FFFF0189582401641021BF -:10EDB000904900043230FFFB2411FFFE2527000498 -:10EDC0000E000F55000721C00251902424040001B9 -:10EDD00012440052324300011460005802003021F6 -:10EDE000324A0004114000048F8D000031A8080051 -:10EDF0001500005A3265FFFF1680FF5B8FBF0024AD -:10EE00003C138000366501803C0480008C9001B882 -:10EE10000600FFFE24062000240F0002A4A600081E -:10EE2000A0AF000BA4A000103C0E1000AC8E01B8E7 -:10EE30000A0010E88FBF00240000202102002821D2 -:10EE40000A0010E5362600021140FEE90000A0216C -:10EE5000952E0110950D000231C8FFFF51A8FEE468 -:10EE60000012A1C00A00108B8F92001C3C05080004 -:10EE70008CA5002430B800015300FF3B8FBF002455 -:10EE80003265FFFF36260002000020210E000F55DC -:10EE9000000000000A0010E88FBF002436260002A0 -:10EEA0000E000F55240400800A0010E88FBF0024D4 -:10EEB000020028210E000F553226FFFB0A001159CF -:10EEC000001221C091030001240200011062FEEA39 -:10EED00024040001241000021470FEC50000A021CB -:10EEE00030E300401060FEC38F92001C952B011090 -:10EEF000950900023167FFFF1127FEE08FBF002454 -:10EF00000A00108B000000002403000334820180FB -:10EF1000A043000B0A0011343C108000321400049E -:10EF2000168000033265FFFF361200023250FFFFE9 -:10EF3000020030210A0011B1000020210000202130 -:10EF40000E000F553265FFFF0A0011863210FFFBDD -:10EF5000241FFFFE0A001132011F4024020030214D -:10EF60000E000F55240401000A00118C000000005F -:10EF700027BDFFC8AFB00010AFBF00343C10600C1D -:10EF8000AFBE0030AFB7002CAFB60028AFB500243D -:10EF9000AFB40020AFB3001CAFB20018AFB1001483 -:10EFA0008E0E5000240FFF7F3C06800001CF6824A6 -:10EFB00035AC380C240B0003AE0C5000ACCB000871 -:10EFC0003C010800AC2000200E00174900000000A2 -:10EFD0003C0A0010354980513C066016AE09537C4E -:10EFE0008CC700003C0860148D0500A03C03FFFFA7 -:10EFF00000E320243C02535300051FC2108202622A -:10F0000034C57C008CBE007C8CBF00783C02600064 -:10F01000344420203C05080124A581382406000A38 -:10F020003C170098AF9E0014AF9F00100E0015F221 -:10F030003C11800036F600C03C1900103C18600CF2 -:10F040003C158000AF1953FC363E0180AEB6013C42 -:10F050008E300000320400031080FFFD32050001F5 -:10F0600014A000593206000210C0FFF93C048000D1 -:10F070008C92014024100040AC9200208C8F0148FB -:10F08000000F760231C300701070013E2C780041F1 -:10F090005300000824040060241900201079000E99 -:10F0A0003C1F40003C088000AD1F01780A0012227E -:10F0B000000000001464FFFB3C1F40000E001F66B0 -:10F0C000000000003C1F40003C088000AD1F01789C -:10F0D0000A001222000000008C940148241700044A -:10F0E0003488018000144C02312500FF8C830140DC -:10F0F00010B7017024ABFFFA2D6A000651400013CF -:10F100003C0580008C86014430A400FF30C300FF22 -:10F1100030D500FF2C76000816C0000226A7000498 -:10F1200024070003240C0009108C01A8288D000A74 -:10F1300011A001942413000A24050008108500146E -:10F140008F980018000719C03C0580008CA701B8F3 -:10F1500004E0FFFE24140002AD030000A50900082E -:10F16000A114000B8CB701483C0910003C1F400063 -:10F17000A51700108CA40144AD0400243C088000B5 -:10F18000ACA901B8AD1F01780A00122200000000EE -:10F19000000692020007C8803C040801248482C053 -:10F1A00003247821270E0001324500FF24100001BE -:10F1B000A1F2000014B0FFE3AF8E0018000719C0E1 -:10F1C0000A001260AF85001C8E3401283C068008BE -:10F1D000AE3400208E2A01048E29010094C8004814 -:10F1E000AF8A0000AF8900043103FFFF0E000F4E0D -:10F1F000AF8300083C0708008CE700C010E0002443 -:10F200008F8700003C0C08008D8C00C4258B00010A -:10F210003C010800AC2B00C43C1980008F24012461 -:10F220003C186020AF040014000000003C06800081 -:10F230003C174000ACD70138000000005280FF8A24 -:10F240003206000226870140268500802409FF80BF -:10F2500000E9682400A998240013194030AC007F0D -:10F26000000DB14030F5007F3C0B200035620002FC -:10F27000006C402502D550250142A0250102F82549 -:10F28000ACDF0830ACD408300A0012283206000285 -:10F290003C0E001000EE682415A000A68F83000429 -:10F2A0003C1508008EB500203C16800096D2010E59 -:10F2B00026B3000130EF40003255FFFF3C0108004B -:10F2C000AC33002011E000B6000090213C18002073 -:10F2D00000F8B82412E000B330E280008F990004F7 -:10F2E000241FBFFF00FF382437231000AF87000022 -:10F2F00030EA2000114000B5240CFFBF3C0B000495 -:10F3000000EB302410C00002006C10243462004076 -:10F3100030ED010011A0000EAF8200043C0F002070 -:10F3200000EF702411C000043C16000400F698247D -:10F3300012600135000000009622011E963F011C5C -:10F340003058FFFF001FCC000319B825AF97000C01 -:10F350009628010C8E2440003403FFFF108300C860 -:10F360003105FFFF308901005520000124120010F3 -:10F3700030E41000108000133653000130EA002002 -:10F380001540000A3C0B100000EB302410C0000DAB -:10F390003C0F0BFF3C130C0000F3702435EDFFFF16 -:10F3A00001AE602B11800007365300013C160800A7 -:10F3B0008ED6002C3653000526D200013C010800F1 -:10F3C000AC32002C30F7010016E0000B3C060001C7 -:10F3D0008F880004311840005700000800E62824F8 -:10F3E0003C021F0100E2F8243C19100013F9010A45 -:10F3F00030A302003C06000100E6282414A000A26D -:10F400003C09100000E92024000040211080000782 -:10F410000000A821000766023195000F00155880F2 -:10F420003C0A0801254A82C0016A40218F8D0018DC -:10F4300011A0006802609021148000033C09800044 -:10F440003C080801250882C0952E010E910300009A -:10F450000260302131C4FFFF2485000410600008E1 -:10F460000000B821240F0003106F011E24190002B0 -:10F47000911F000113F9002630E200400015B9C0C9 -:10F480008F89001C51200001366600403C16800028 -:10F490008ECB400031730100126000C530D50004EE -:10F4A0003C0C08008D8C002430D3FFFB3186000417 -:10F4B00014C0010630B2FFFF56A0000136730004ED -:10F4C00002E02021024028210E000F550260302169 -:10F4D00016A0000D0000202136C501803C048000EC -:10F4E0008C8D01B805A0FFFE240F2000240E000221 -:10F4F000A4AF0008A0AE000BA4A000103C051000B3 -:10F50000AC8501B8000020210A001367008010219B -:10F510001040FFDB0000B821952A0110950300027E -:10F520003148FFFF5068FFD60015B9C00A00132FFD -:10F530008F89001C2413BFFF0073282410A000072C -:10F54000240E87FF006E48241520000A3C1200603C -:10F5500000F2782411E00007000000000E000D34D6 -:10F56000000000001040FF323C0680000A001295A7 -:10F570003C1980000E0014CF000000000A00136741 -:10F58000000000000E0014F5000000003C1F4000C9 -:10F590003C088000AD1F01780A0012220000000024 -:10F5A00030E280001040FF528F8300043C050020B1 -:10F5B00000E520241080FF4E3C09FFFF35287FFF27 -:10F5C00000E838240A0012C9346380000A0012D20D -:10F5D000006C10243C0408008C8400381480000265 -:10F5E0002489FFFF000048213C0380009476010E2F -:10F5F00032D7FFFF110000EA26F600043C12080093 -:10F600008E5200301240000A30EA01008F99000447 -:10F6100033384000130000063C030F0000E3402491 -:10F620003C0201000048F82B13E000D232C5FFFF76 -:10F630001140002F3C0C0F0000EC30243C0B02006A -:10F6400010CB002B8F8F000C3C0E080025CE00380D -:10F6500032D2FFFF01E9282400AE682191A90004FD -:10F6600025270004000721C0024028213666000239 -:10F670000E000F55000000000A0013670000102163 -:10F680000A0012EA241200203C0308008C6300D810 -:10F6900002A0282124040080246200013C0108000B -:10F6A000AC2200D80E000F55240600030A00136791 -:10F6B000000010218C840140010028213C038000BF -:10F6C0008C7F01B807E0FFFE2402001CACA4000000 -:10F6D000A0A2000B3C081000AC6801B83C1F400021 -:10F6E0003C088000AD1F01780A00122200000000D3 -:10F6F0003C0308008C6300D02EA5000C001521C02F -:10F70000387800012F1200010245B82416E0FFD618 -:10F7100032D2FFFF26B9FFFC2F240004148000081A -:10F7200000002021386800022D0200010045F82465 -:10F7300013E0000600075A4232D2FFFF00002021EA -:10F74000024028210A0013AA366600020015182B71 -:10F75000016350241540000532D2FFFF001521C07F -:10F76000024028210A0013AA366600020000202168 -:10F77000024028210E000F553266FFFB0A0013E6F7 -:10F78000001521C010930068000768802406000B54 -:10F790001486FE6D000719C00007C0803C190801DF -:10F7A000273982C0031930210A001260A0C000016D -:10F7B00034D5000202E0202130A5FFFF0E000F55D6 -:10F7C00032A6FFFF0A001350000020210007A0808E -:10F7D0003C1F080127FF82C0029F102190570000A4 -:10F7E00012E0FE59000719C0A04000008F8A0018DF -:10F7F0002542FFFF1440FE54AF820018000719C0D5 -:10F800000A001260AF80001C0E000FBC0000000058 -:10F810000A0012E28F8700001460FEF73C06000128 -:10F8200026A900043125FFFF366600023C03800054 -:10F830008C7501B806A0FFFE8F8900083C0A800085 -:10F8400035440180AC8000001120009B2418000387 -:10F8500024AC0012012C582B11600097000000000E -:10F86000947201203C138000240F001A324EFFFFD7 -:10F87000366A018030ED4000A14F000B11A00091CD -:10F8800025C3FFFE0123B02B16C0008F2417FFFEF7 -:10F8900035080001A5430014AF880004241FBFFFF2 -:10F8A000011FC82424080002A7C8000CA7C5000E29 -:10F8B000A7C60008A7D90026A7C700103C0710005C -:10F8C000AE2701B80A0013670000102124040100CC -:10F8D000024028210E000F55026030210A00133C1F -:10F8E0000000000091030001241500011075FF06BF -:10F8F00024040001241200021472FEE10000B82169 -:10F9000030F6004052C0FEDF8F89001C95270110A1 -:10F910009518000230F7FFFF1317FEFB0000B82117 -:10F920000A00132F8F89001C3C120801265282C046 -:10F9300001B2702100067A02A1CF00013C0B6000E9 -:10F940008D6318202410000100F098043C05080184 -:10F9500024A582C20073B02501A5A8210006640277 -:10F96000000719C0A6AC0000AD7618200A0012618D -:10F970003C058000366600020E000F55240400800E -:10F980000A001367000010210003A080028698215E -:10F990008E7200043C1160000A00120F02512821EF -:10F9A0008C66400030D5010012A0003730EC010019 -:10F9B0003C1508008EB50024118000133277000436 -:10F9C0003C050F0000E568243C07020011A7000E6B -:10F9D0008F84000C3C180800271800380260302182 -:10F9E000008990240258782191EE000432C5FFFF6F -:10F9F0003272FFFB25C90004000921C00E000F551B -:10FA00002413FFFE02B3A8242419000112B9003008 -:10FA100032A200011040000732A800040240302149 -:10FA2000000020210E000F5532C5FFFF3252FFFBB0 -:10FA300032A80004110000048F8B0000316A080016 -:10FA40005540002B32C5FFFF16E0FEC60000102116 -:10FA50003C16800036C401803C0580008CA301B8B0 -:10FA60000460FFFE240C200024060002A48C000881 -:10FA7000A086000BA48000103C151000ACB501B8A6 -:10FA80000A001367000010213C0D08008DAD002412 -:10FA900031A7000150E0FEB30000102132C5FFFF86 -:10FAA00036660002000020210E000F550000000005 -:10FAB0000A00136700001021A3D8000B0A001436B7 -:10FAC000241FBFFF2417FFFE0A001434011740242F -:10FAD0003257000416E0000332C5FFFF365F000214 -:10FAE00033F2FFFF024030210A0014B80000202149 -:10FAF000024030210E000F55240401000A0014A01A -:10FB0000000000003C0380008C6401003082003E55 -:10FB10001440000800000000AC6000488C66010042 -:10FB200030C507C010A0000500000000AC60004C0C -:10FB3000AC60005003E0000824020001AC600054F7 -:10FB4000AC6000408C6801003107380010E0FFF91C -:10FB5000000000002402000103E00008AC60004443 -:10FB60003C03900034620001008220253C038000A9 -:10FB7000AC6400208C65002004A0FFFE00000000A3 -:10FB800003E00008000000003C0280003443000154 -:10FB90000083202503E00008AC44002027BDFFD8E7 -:10FBA000AFB100143C048000AFBF0020AFB3001C15 -:10FBB000AFB20018AFB000108C9201408C90014899 -:10FBC0002402000E00108C02322300FF1062005944 -:10FBD000020428242866000F10C00013286A00378A -:10FBE000240700061067008E286800075100002DCA -:10FBF00024040009106000783C06800024090001FC -:10FC0000106900B0000000000000000D8FBF002050 -:10FC10008FB3001C8FB200188FB100148FB000108A -:10FC200003E0000827BD002811400059240D0038CA -:10FC3000286B0035116000053C058000240C001F76 -:10FC4000146CFFF1000000003C0580008CB801B886 -:10FC50000700FFFE34B90180AF320000241F00010D -:10FC6000241200023C021000AF200004A73100085B -:10FC7000A33F000AA332000BA7300010AF200024DE -:10FC8000AF200028ACA201B88FBF00208FB3001CAA -:10FC90008FB200188FB100148FB0001003E000087D -:10FCA00027BD0028106400232405000B1465FFD62F -:10FCB0003218FFFF170000203C0580008F93FED014 -:10FCC000927F000533F900041720FFCF00000000E9 -:10FCD0000E0014E602402021926900050240202116 -:10FCE000352800040E0014F0A26800059267000594 -:10FCF00030E2000414400002000000000000000D8B -:10FD0000926B000024060020316A00FF1546000AAD -:10FD10003C0580008CA401B80480FFFE34AD018056 -:10FD2000240E00053C0C1000ADB20000A1AE000B8B -:10FD3000ACAC01B83C0580008CA301B80460FFFEA8 -:10FD400034AF018024130002ADF20000ADF20004D4 -:10FD5000A5F10008A1F3000AA1F3000BA5F0001023 -:10FD6000ADE000248CB101443C101000ADF100283E -:10FD7000ACB001B88FBF00208FB3001C8FB2001849 -:10FD80008FB100148FB0001003E0000827BD0028D9 -:10FD9000106DFFAD240E0080146EFF9B000000006C -:10FDA0003C0580008CA301B80460FFFE34AF0180E5 -:10FDB00024120002A1F2000BA5F10008A5F000102A -:10FDC0008CB301443C021000A5F30012ACA201B8B0 -:10FDD0000A0015318FBF00208CC301B80460FFFEFC -:10FDE00034D30180AE720000AE6000042412000122 -:10FDF000A671000824110002A272000AA271000B71 -:10FE0000A67000108CD001443C0F1000AE7000248E -:10FE1000AE600028ACCF01B80A00156C8FBF00207F -:10FE20003C0380008C6601B804C0FFFE3462018090 -:10FE30003C06080190C68300AC52000010C00003CD -:10FE4000000038213C0708018CE783083C0580004E -:10FE500034AA01802404000234CC0001AC47000421 -:10FE6000A5510008A14C000AA144000BA5500010A8 -:10FE70008CAB01440000202101402821AD4B00241F -:10FE800010C000038FBF00203C0408018C84830451 -:10FE90008FB3001C8FB200188FB100148FB0001008 -:10FEA0003C0E10003C0D800027BD0028ACA40028AB -:10FEB000ADAE01B83C010801A020830003E00008BA -:10FEC0000000000010A0000B3C0680008C9801444C -:10FED000241900023C010801A03983003C010801FB -:10FEE000AC3283083C010801AC3883040A00156C6D -:10FEF0008FBF00208CDF01B807E0FFFE34C7018010 -:10FF000024090002ACF20000ACF20004A4F10008E5 -:10FF1000A0E9000AA0E9000BA4F00010ACE0002466 -:10FF20008CC801443C021000ACE80028ACC201B807 -:10FF30000A00156C8FBF002027BDFFE8AFBF00107F -:10FF40000E000F4E000000003C0280008FBF00102A -:10FF500000002021AC4001800A00101027BD0018CD -:10FF60003084FFFF30A5FFFF10800007000018213C -:10FF70003082000110400002000420420065182178 -:10FF80001480FFFB0005284003E0000800601021FA -:10FF900010C00007000000008CA2000024C6FFFF74 -:10FFA00024A50004AC82000014C0FFFB24840004DC -:10FFB00003E000080000000010A0000824A3FFFFD9 -:10FFC000AC86000000000000000000002402FFFFDB -:10FFD0002463FFFF1462FFFA2484000403E0000896 -:10FFE0000000000027BDFFE8AFBF0014AFB0001055 -:10FFF0000E0014E6008080213C04800834830080D9 -:020000040001F9 -:10000000906500250200202134A200200E0014F08B -:10001000A0620025020020218FBF00148FB00010C5 -:100020000A000C9E27BD00183C03800027BDFFF886 -:1000300034620180AFA20000308C00FF30AD00FFC1 -:1000400030CE00FF3C0B80008D6401B80480FFFEC1 -:10005000000000008FA900008D6801288FAA000011 -:100060008FA700008FA400002405000124020002D5 -:10007000A085000A8FA30000359940003C051000C0 -:10008000A062000B8FB800008FAC00008FA60000AC -:100090008FAF000027BD0008AD280000AD40000470 -:1000A000AD800024ACC00028A4F90008A70D001002 -:1000B000A5EE001203E00008AD6501B83C0680081B -:1000C00027BDFFE834C50080AFBF001090A700092E -:1000D0002402001230E300FF1062000B0080302188 -:1000E0008CA8005000882023048000088FBF0010D7 -:1000F0008CAA0034240400390000282100CA4823B7 -:1001000005200005240600128FBF00102402000104 -:1001100003E0000827BD00180E00161800000000BC -:100120008FBF00102402000103E0000827BD001863 -:1001300027BDFFC8AFB1002C00A08821AFB20030AE -:1001400027A500100080902102202021AFBF00349D -:10015000AFB000280E000CA8AFA000101440009B08 -:100160003C07800834E400809086000830C5000811 -:1001700014A000698FA700103C1880083710008079 -:10018000920F000831EE000815C000022408000399 -:10019000000040213C0B800891650011916A00121B -:1001A000356600808CDF0054314900FF0128202192 -:1001B00030A300FF000410800062282100BFC82B7C -:1001C000132000080000000094D0005C8CCF005485 -:1001D000320DFFFF01E5702301AE602B118000940A -:1001E0000000000094D9005C3323FFFF30FF0004BF -:1001F00013E00074000830808FA8001C0068102BEA -:100200005040004F30E30004006610232C4600806D -:1002100010C0000200408021241000800E0014E66F -:10022000024020213C03800834660080240700013E -:10023000ACC7000C90C8000800106840346701008B -:10024000311F007FA0DF00088E390004273800012D -:10025000ACD80030A4D0005C8CCF003C9630000EAF -:1002600001F07021ACCE00208CCC003C018D5821D7 -:10027000ACCB001C8E2A0004ACEA00008E290008DA -:10028000ACE900048FA5001030A4000854800032AF -:1002900093A60020A0C0004E90C9004E2402FFDFAC -:1002A0003C188008A0E9000890C50008370D0080C0 -:1002B000240A005000A22024A0C400088E3900089F -:1002C000ADB900388F0F00148DB0003001F07021EF -:1002D000ADAE003491AC0000318B00FF116A002CF0 -:1002E000264501000E0014F00240202124040038AD -:1002F000000028210E0016182406000A8FBF0034C3 -:100300008FB200308FB1002C8FB000282402000182 -:1003100003E0000827BD003830E801001100003D6F -:100320008FA300148C8A0058006A48230520FF938D -:100330003C188008AC8300580A00166C8FA7001088 -:10034000240702181060FFB100E610238FA2001CE2 -:100350000A001691004610233C188008370D0080D3 -:10036000A0E600088E390008240A0050ADB9003814 -:100370008F0F00148DB0003001F07021ADAE00344D -:1003800091AC0000318B00FF156AFFD626450100B5 -:100390002406FF8000A610243C098000AD2200281E -:1003A0008E27000830A3007F3C04800C0064F821F5 -:1003B000AFE700D08E280008AF9F00280A0016C7BC -:1003C000AFE800D40A00168E2C6202188E230008B3 -:1003D0003C04800834820080AC4300540240202159 -:1003E0000E001607AC400030240400382405008DB0 -:1003F0000E001618240600128FBF00348FB2003092 -:100400008FB1002C8FB000282402000103E0000807 -:1004100027BD0038AC800058908C0008240DFFF7F1 -:10042000018D5824A08B00080A00166C8FA70010BD -:100430008CD800540A0016890305182327BDFFE84D -:10044000AFBF001090A6000D30C7001010E0000CE8 -:10045000008040213C0280088C4400048CA30008EA -:100460001064000830C9000530C5000510A0001C4C -:100470008FBF00102402000103E0000827BD001810 -:1004800030C900051120001030CB001210E0FFF938 -:100490008FBF00103C0880088CA700088D06000460 -:1004A00014E6FFF524020001240400382405008D21 -:1004B0000E001618240600128FBF0010240200013F -:1004C00003E0000827BD0018240A0012156AFFE99E -:1004D0008FBF0010010020210A00165A27BD001806 -:1004E000000020210A000D1A27BD00183C05080055 -:1004F00024A55D683C04080024847B343C02080089 -:1005000024425D70240300063C010801AC258310E1 -:100510003C010801AC2483143C010801AC2283187F -:100520003C010801A023831C03E000080000000038 -:1005300003E00008240200013C028000308800FF34 -:10054000344701803C0680008CC301B80460FFFE84 -:10055000000000008CC501282418FF803C0D800A93 -:1005600024AF010001F8702431EC007FACCE0024F0 -:10057000018D2021ACE50000948B00DA3509600084 -:1005800024080002316AFFFFACEA000424020001E3 -:10059000A4E90008A0E8000BACE000243C07100030 -:1005A000ACC701B8AF84002803E00008AF85005C49 -:1005B0008C9800048F8C00282409FFBF0305782342 -:1005C000AC8F0004918E00C42403FFEF31CD007F77 -:1005D000A18D00C48C8B00208F860028A780004C42 -:1005E000356A0002A4C000ACAC8A002090C800C4E8 -:1005F00001093824A0C700C48F840028AC8000DC27 -:10060000908500C400A3102403E00008A08200C469 -:100610003C028000344501803C0480008C8301B89A -:100620000460FFFE8F89005C2407608324060002BB -:10063000ACA900008C880124ACA80004A4A7000881 -:10064000A0A6000B3C05100003E00008AC8501B833 -:10065000938800388F8900508F82002830C600FFB1 -:100660000109382330E900FF0122182130A500FFDD -:100670002468007810C0000201243821008038214D -:1006800030E400031480000330AA00031140000D81 -:10069000312B000310A000090000102190ED000094 -:1006A000244E000131C200FF0045602BA10D000067 -:1006B00024E700011580FFF92508000103E0000888 -:1006C000000000001560FFF30000000010A0FFFB19 -:1006D000000010218CF8000024590004332200FF90 -:1006E0000045782BAD18000024E7000415E0FFF961 -:1006F0002508000403E0000800000000938500388E -:10070000938800488F870050000432003103007F37 -:1007100000E5102B30C47F001040000F0064282536 -:100720008F8400283C0980008C8A00DCAD2A00A45C -:100730003C03800000A35825AC6B00A08C6C00A08B -:100740000580FFFE000000008C6D00ACAC8D00DC6D -:1007500003E000088C6200A80A0017DA8F840028E2 -:10076000938800493C02800000805021310300FE44 -:10077000A383004930ABFFFF30CC00FF30E7FFFF21 -:10078000344801803C0980008D2401B80480FFFEBC -:100790008F8D005C24180016AD0D00008D22012401 -:1007A0008F8D0028AD0200048D590020A507000898 -:1007B000240201B4A119000AA118000B952F0120F1 -:1007C0008D4E00088D4700049783004C8D590024FE -:1007D00001CF302100C7282100A320232418FFFFC8 -:1007E000A504000CA50B000EA5020010A50C00121C -:1007F000AD190018AD18002495AF00D83C0B1000BF -:100800002407FFF731EEFFFFAD0E00288DAC00741A -:10081000AD0C002CAD2B01B88D46002000C728245C -:1008200003E00008AD4500208F8800280080582193 -:1008300030E7FFFF910900C63C02800030A5FFFFB2 -:10084000312400FF00041A000067502530C600FF65 -:10085000344701803C0980008D2C01B80580FFFEE3 -:100860008F82005C240F0017ACE200008D39012458 -:10087000ACF900048D780020A4EA0008241901B422 -:10088000A0F8000AA0EF000B952301208D6E000850 -:100890008D6D00049784004C01C35021014D6021EF -:1008A00001841023A4E2000CA4E5000EA4F90010BA -:1008B000A4E60012ACE000148D780024240DFFFFA4 -:1008C000ACF800188D0F006CACEF001C8D0E0068AA -:1008D0003C0F1000ACEE0020ACED0024950A00AEF9 -:1008E000240DFFF73146FFFFACE60028950C0070A1 -:1008F0009504007231837FFF0003CA003082FFFF3E -:100900000322C021ACF8002CAD2F01B8950E007267 -:100910008D6A002000AE3021014D2824A50600720A -:1009200003E00008AD6500203C02800034460180F1 -:100930003C0580008CA301B80460FFFE2409001868 -:10094000ACC40000A0C9000B8F8800283C04100034 -:10095000950700AEA4C70010ACC0003003E000084B -:10096000ACA401B83C028000344501803C04800006 -:100970008C8301B80460FFFE8F8A003424060019BE -:100980009549001C3128FFFF000839C0ACA70000C2 -:10099000A0A6000B3C05100003E00008AC8501B8E0 -:1009A0008F87003C0080402130C400FF3C0680005F -:1009B0008CC201B80440FFFE8F89005C938300580D -:1009C00034996000ACA90000A0A300058CE20010DF -:1009D000240F00022403FFF7A4A20006A4B9000814 -:1009E0008D180020A0B8000AA0AF000B8CEE00000C -:1009F000ACAE00108CED0004ACAD00148CEC001C0F -:100A0000ACAC00248CEB0020ACAB00288CEA002CB2 -:100A10003C071000ACAA002C8D090024ACA90018DA -:100A2000ACC701B88D05002000A3202403E0000816 -:100A3000AD040020938500582403000127BDFFE882 -:100A400000A330042CA20020AFB00010AFBF0014F0 -:100A500000C01821104000132410FFFE3C070800BE -:100A60008CE7319000E610243C08800035050180B9 -:100A700014400005240600848F890028240A0004FD -:100A80002410FFFFA12A00EC0E00187600000000E1 -:100A9000020010218FBF00148FB0001003E0000887 -:100AA00027BD00183C0608008CC631940A0018A81F -:100AB00000C310248F87003427BDFFE0AFB20018B9 -:100AC000AFB10014AFB00010AFBF001C30D000FFBA -:100AD00090E6000D00A088210080902130C5007FA5 -:100AE000A0E5000D8F8500288E2300188CA200C081 -:100AF0001062002E240A000E0E00189BA38A0058D4 -:100B00002409FFFF104900222404FFFF52000020A7 -:100B1000000020218E2600003C0C001000CC582440 -:100B2000156000393C0E000800CE682455A0003F37 -:100B3000024020213C18000200D880241200001F2F -:100B40003C0A00048F8700348CE200148CE3001010 -:100B50008CE500140043F82303E5C82B132000059F -:100B6000024020218E24002C8CF1001010910031C5 -:100B70000240202124020012A38200580E00189B7C -:100B80002412FFFF105200022404FFFF0000202166 -:100B90008FBF001C8FB200188FB100148FB00010EF -:100BA0000080102103E0000827BD002090A800C4A9 -:100BB000350400200A0018D1A0A400C400CA4824AB -:100BC0001520000B8F8B00348F8D00348DAC0010FE -:100BD0001580000B024020218E2E002C51C0FFEC0E -:100BE00000002021024020210A0018EC24020017F6 -:100BF0008D66001050C0FFE6000020210240202139 -:100C00000A0018EC240200110240202124020015E1 -:100C10000E00189BA3820058240FFFFF104FFFDC2B -:100C20002404FFFF0A0018DB8E2600000A001912B8 -:100C3000240200143C08000400C8382450E0FFD40B -:100C400000002021024020210A0018EC2402001399 -:100C50008F86002827BDFFE0AFB10014AFBF00189A -:100C6000AFB0001090C300C430A500FF3062002078 -:100C700010400008008088218CCB00C02409FFDFD1 -:100C8000256A0001ACCA00C090C800C4010938241C -:100C9000A0C700C414A000403C0C80008F84002832 -:100CA000908700C42418FFBF2406FFEF30E3007FC5 -:100CB000A08300C4979F004C8F8200508F8D002826 -:100CC00003E2C823A799004CA5A000AC91AF00C4D3 -:100CD00001F87024A1AE00C48F8C0028A18000C749 -:100CE0008F8A0028A5400072AD4000DC914500C409 -:100CF00000A65824A14B00C48F9000248F8400507C -:100D00009786004C0204282110C0000FAF850024F4 -:100D1000A38000483C0780008E2C000894ED012041 -:100D20008E2B0004018D5021014B802102062023CF -:100D30003086FFFF30C8000F390900013131000152 -:100D400016200009A3880048938600388FBF00183A -:100D50008FB100148FB0001027BD0020AF85005464 -:100D600003E00008AF86005000C870238FBF001852 -:100D7000938600388FB100148FB0001034EF0C0050 -:100D8000010F282127BD0020ACEE0084AF85005460 -:100D900003E00008AF860050359001800200282152 -:100DA0000E001876240600828F840028908600C4E6 -:100DB00030C5004050A0FFBAA38000588F85003C8A -:100DC0003C0680008CCD01B805A0FFFE8F89005C39 -:100DD0002408608224070002AE090000A60800086B -:100DE000A207000B8CA300083C0E1000AE030010FD -:100DF0008CA2000CAE0200148CBF0014AE1F0018B1 -:100E00008CB90018AE1900248CB80024AE18002844 -:100E10008CAF0028AE0F002CACCE01B80A001936FA -:100E2000A38000588F8A002827BDFFE0AFB10014CF -:100E3000AFB000108F880050AFBF00189389002C0E -:100E4000954200AC30D100FF0109182B00808021B1 -:100E500030AC00FF3047FFFF000058211460000352 -:100E6000310600FF01203021010958239783004CEF -:100E70000068202B1480001B000000001068004355 -:100E8000240A0001118A004834E708803165FFFF19 -:100E90000E001818020020210E0018588F84005CE4 -:100EA0008F840028948D007025AC0001A48C007004 -:100EB000948B00703C0608008CC6318831677FFF38 -:100EC00010E6004F0000000002002021022028212F -:100ED0008FBF00188FB100148FB000100A001922C4 -:100EE00027BD0020914400C42406FF800086882589 -:100EF000A15100C49784004C3088FFFF1100001CF2 -:100F00009389002C8F8E00282419EFFF008BF82383 -:100F100095D800AC0168682B33E900FF03197824E9 -:100F2000A5CF00AC51A0002A010058218E05002059 -:100F30002408FFFB2403000100A81024AE020020B7 -:100F40001183002534E78000020020213165FFFF76 -:100F50000E00181801203021978B004C8F8700500D -:100F6000A780004C00EB8023AF9000509389002CA9 -:100F70008F8C00288FBF00188FB100148FB0001025 -:100F800027BD002003E00008A18900C78E080020CB -:100F90002409FFFB34E7800001092824AE05002066 -:100FA000158AFFBA34E70880020020210E0017E6F8 -:100FB0003165FFFF02002021022028218FBF001889 -:100FC0008FB100148FB000100A00192227BD002035 -:100FD0000A0019D900004821020020213165FFFFD5 -:100FE0000E0017E601203021978B004C8F870050B0 -:100FF000A780004C00EB80230A0019E9AF90005055 -:1010000094890070240A8000012A4024A48800707A -:10101000908500709099007030A200FF000219C204 -:101020000003F827001FC1C0332F007F01F870258F -:10103000A08E00700A0019C1020020218F880028AC -:1010400024030001910A0078910500C72509007862 -:101050003147003F24E6FFE000C318042CC2002003 -:1010600030670019A385002C1040001AAF89003C9E -:101070003C0A8000354B00022405000124060001D3 -:1010800014E00016006B1024000028211440000F0B -:10109000306300201060000F240500018D060074ED -:1010A0008D1900742403FF8000C3102400027940CE -:1010B0003338007F01F868253C0E100001AE602532 -:1010C000AD4C083091280001310600010A00199743 -:1010D0000000000003E00008000000008D0F007415 -:1010E0008D0D00742418FF8001F87024000E41401B -:1010F00031AC007F010C50253C0B1000014B382512 -:101100003C0980000A001997AD27083027BDFFD899 -:10111000AFB000108F90003CAFB40020AFB100140E -:10112000AFBF0024AFB3001CAFB200188E05001093 -:101130003C0208008C4231B08F86004030A73FFF50 -:1011400000E2182B8CD20014008088218CD3002060 -:10115000106000070000A02190CB000D240AFF8042 -:10116000014B4824312800FF1500000C0005638264 -:10117000022020212411000DA39100588FBF0024CC -:101180008FB400208FB3001C8FB200188FB10014F1 -:101190008FB000100A00189B27BD0028318500037E -:1011A00054A0FFF40220202194CF001C8F8E002831 -:1011B0008E070028A5CF00D88CCD0010024D30231B -:1011C00010E6005C2402001F0E00189BA38200584A -:1011D000241FFFFF105F004E2404FFFF8F83004495 -:1011E0008F880034026398218D0900100123102399 -:1011F0008F830020AD020010AD1300208C670074B7 -:1012000000F3202B14800062022020218F860040F2 -:101210008E0C00248CC5002411850007022020219B -:10122000240E001C0E00189BA38E0058240DFFFFF7 -:10123000104D00372404FFFF8F8400348C98002465 -:10124000270F0001AC8F0024127200448F990020F8 -:101250008F320074125300413C0A00808E09000056 -:10126000012A10241440003A000000008E040014EB -:101270002412FFFF10920006240B001B02202021E5 -:101280000E00189BA38B0058105200212404FFFF6E -:101290008E0300003C0C0001006C282410A00013F9 -:1012A0003C0600800066A024168000090200282168 -:1012B00002202021240E001A0E00189BA38E005835 -:1012C000240DFFFF104D00122404FFFF020028210F -:1012D000022020210E0018BB240600012410FFFF6D -:1012E0002404FFFF1050000A241400018F8F0034E3 -:1012F000022020210280302195F2003424050001D3 -:10130000265800010E001997A5F80034000020218E -:101310008FBF00248FB400208FB3001C8FB2001841 -:101320008FB100148FB000100080102103E000087E -:1013300027BD00288F83004400E3C8210259C02B39 -:101340001300FFA88F8800340A001A8024020018B6 -:10135000AC8000200A001AAA8E0400148E1F000020 -:101360003C07008003E798241660FFF92408001A60 -:10137000022020210E00189BA38800582403FFFFA1 -:101380001443FFBA2404FFFF0A001AD38FBF0024BE -:10139000240B001D0E00189BA38B0058240AFFFF8E -:1013A000144AFF9A2404FFFF0A001AD38FBF0024B7 -:1013B0008F85002827BDFFD8AFB3001CAFB200183F -:1013C000AFB10014AFB00010AFBF002090A700C4B1 -:1013D0008F90003C2412FFFF34E200409206000090 -:1013E000A0A200C48E030010008098211072000695 -:1013F00030D1003F2408000D0E00189BA388005830 -:10140000105200252404FFFF8F8A00288E0900183F -:101410008D4400C01124000702602021240C000E1E -:101420000E00189BA38C0058240BFFFF104B001AD2 -:101430002404FFFF24040020122400048F8D0028C0 -:1014400091AF00C435EE0020A1AE00C48F850044EA -:1014500010A00019000000001224004A8F980028F4 -:101460008F92FED0971000709651000A52300048BB -:101470008F9300303C1F08008FFF318C03E5C82B91 -:101480001720001E02602021000028210E0019975D -:1014900024060001000020218FBF00208FB3001C14 -:1014A0008FB200188FB100148FB00010008010218F -:1014B00003E0000827BD00285224002A8E050014EE -:1014C0008F840028948A007025490001A489007047 -:1014D000948800703C0208008C42318831077FFFFD -:1014E00010E2000E00000000026020210E00192210 -:1014F000240500010A001B34000020212402002DD5 -:101500000E00189BA38200582403FFFF1443FFE141 -:101510002404FFFF0A001B358FBF00209499007040 -:10152000241F800024050001033FC024A4980070FC -:1015300090920070908E0070325100FF001181C2B5 -:1015400000107827000F69C031CC007F018D58252D -:10155000A08B00700E001922026020210A001B34AB -:10156000000020212406FFFF54A6FFD68F84002808 -:10157000026020210E001922240500010A001B34FC -:1015800000002021026020210A001B4E2402000AD4 -:101590002404FFFD0A001B34AF9300508F880028FD -:1015A00027BDFFE8AFB00010AFBF0014910A00C420 -:1015B0008F87003C00808021354900408CE6001078 -:1015C000A10900C43C0208008C4231B030C53FFF85 -:1015D00000A2182B106000078F850040240DFF80AB -:1015E00090AE000D01AE6024318B00FF1560000845 -:1015F0000006C382020020212403000D8FBF0014C7 -:101600008FB0001027BD00180A00189BA383005854 -:1016100033060003240F000254CFFFF702002021FD -:1016200094A2001C8F85002824190023A4A200D8AE -:101630008CE8000000081E02307F003F13F90035DF -:101640003C0A00838CE800188CA600C01106000834 -:10165000000000002405000E0E00189BA385005812 -:101660002407FFFF104700182404FFFF8F85002880 -:1016700090A900C435240020A0A400C48F8C00349D -:10168000918E000D31CD007FA18D000D8F83004420 -:101690001060001C020020218F8400408C980010F4 -:1016A0000303782B11E0000D2419001802002021FB -:1016B000A39900580E00189B2410FFFF1050000241 -:1016C0002404FFFF000020218FBF00148FB0001002 -:1016D0000080102103E0000827BD00188C86001050 -:1016E0008F9F00340200202100C31023AFE20010BE -:1016F000240500010E001997240600010A001BC0F2 -:10170000000020210E001922240500010A001BC040 -:1017100000002021010A5824156AFFD98F8C00345B -:10172000A0A600EC0A001BADA386004A27BDFFD887 -:10173000AFB000108F90003CAFB20018AFBF0020D8 -:10174000AFB3001CAFB100148E1100103C030800B1 -:101750008C6331B032253FFF00A3102B10400008EE -:10176000008090218F8600402409FF8090CA000DE0 -:10177000012A4024310700FF14E0000B00116B82A6 -:10178000024020212412000DA39200588FBF002098 -:101790008FB3001C8FB200188FB100148FB00010EF -:1017A0000A00189B27BD002831AC0003240B000160 -:1017B000558BFFF40240202190CF000D31EE000840 -:1017C00011C000608F9300441660000924020027B6 -:1017D0008E19000C8CD80020173800052402002038 -:1017E0008E0200088CDF0024105F004024020020DD -:1017F0000E00189BA38200582406FFFF10460033FA -:101800002404FFFF8F990034240AFFF73C13800E55 -:101810009329000D2404FF803C0D8000012AF82448 -:10182000A33F000D8F9900203C0808008D0831ACC3 -:101830008F83005C972700788F9F0034010310216D -:1018400030E57FFF000530400046782131F8007F09 -:101850000313602101E47024ADAE002CA5910000BB -:101860008FEB0028256A0001AFEA00288FE3002CE7 -:101870008E09002C00694021AFE8002C8E07002C57 -:10188000AFE700308E050014AFE5003497E6003A6C -:1018900024C20001A7E2003A973300783C10080008 -:1018A0008E1031B02663000130717FFF12300027A7 -:1018B000006030218F8F002002402021240500018C -:1018C0000E001922A5E60078000020218FBF00201D -:1018D0008FB3001C8FB200188FB100148FB00010AE -:1018E0000080102103E0000827BD00288E050014A9 -:1018F0002413FFFF10B3001D8F8300288E080018EB -:101900008C6700C0150700092402000E8E0A00240F -:101910008CC9002815490005240200218E070028E3 -:101920008CCB002C10EB00132402001F0E00189B20 -:10193000A38200581453FFB32404FFFF0A001C4283 -:101940008FBF00200A001C0A24020024240E8000FD -:10195000006E682431ACFFFF000C5BC2317100FFE8 -:10196000001180270A001C3B001033C00A001C59DC -:10197000240200258E05002C10A0FFEC2402002379 -:101980008F8E00208DCD007401A5602B1580FFE7A0 -:10199000240200268CCF001400A7C02101F8202BC0 -:1019A0001080FF998F990034024020210A001C59B1 -:1019B0002402002227BDFFE0AFB000108F90003C52 -:1019C000AFB10014AFBF00188E0500103C03080033 -:1019D0008C6331B00080882130A43FFF0083102B3E -:1019E000104000078F8600402409FF8090CA000D38 -:1019F000012A4024310700FF14E000098F8B0044C6 -:101A00002410000D02202021A39000588FBF001841 -:101A10008FB100148FB000100A00189B27BD002062 -:101A2000116000070005CB828F8F00288F8EFED0BB -:101A300095EC007095CD000A11AC00578F850030F1 -:101A4000333800031700001000000000921F00024E -:101A500013E00041000000008E06002450C0000F7B -:101A600092040003022020212402000F0E00189B84 -:101A7000A38200582408FFFF144800072404FFFF36 -:101A80000A001CD58FBF001890C7000D30E3000876 -:101A90001060003702202021920400032409000274 -:101AA000308A00FF15490005308500FF8F8B004408 -:101AB0005160003102202021308500FF38B800102D -:101AC0002CAF00012F0E000102002821022020214E -:101AD0000E0018BB01EE30252410FFFF1050000E41 -:101AE0002404FFFF8F830044106000170220202190 -:101AF0003C1F08008FFF318C03E3C82B5720000CDC -:101B00002411002D02202021000028210E00199709 -:101B100024060001000020218FBF00188FB100149F -:101B20008FB000100080102103E0000827BD0020C6 -:101B30000E00189BA39100581450FFF62404FFFFD9 -:101B40000A001CD58FBF00180E00192224050001C1 -:101B50000A001CD4000020218CC400248E02002422 -:101B60005444FFC1022020210A001CB59204000346 -:101B70000A001CA924020010240D002C0E00189B42 -:101B8000A38D0058240CFFFF104CFFE32404FFFF3B -:101B90000A001CBC920400032404FFFD0A001CD4AC -:101BA000AF85005030A500FF2406000124A90001E4 -:101BB00000C9102B1040000C00004021240A000135 -:101BC00000A61823308B000124C60001006A3804E7 -:101BD000000420421160000200C9182B01074025B3 -:101BE0001460FFF800A6182303E00008010010218C -:101BF00027BDFFD8AFB000188F90003CAFB1001CDC -:101C0000AFBF00202403FFFF2411002FAFA300105B -:101C10009206000024050008261000010066202618 -:101C20000E001CF7308400FF00021E003C021EDC88 -:101C300034466F410A001D1F0000102110A000094A -:101C4000008018212445000130A2FFFF2C45000828 -:101C50000461FFFA000320400086202614A0FFF94B -:101C6000008018210E001CF7240500208FA300100F -:101C70002629FFFF313100FF00034202240700FF45 -:101C80001627FFE20102182600035027AFAA00140E -:101C9000AFAA00100000302127A8001027A70014C9 -:101CA00000E6782391ED000324CE000100C86021F6 -:101CB00031C600FF2CCB00041560FFF9A18D000098 -:101CC0008FA200108FBF00208FB1001C8FB00018B2 -:101CD00003E0000827BD00289383003827BDFFE0FC -:101CE00024020034AFB10014AFB00010AFBF001C2D -:101CF000AFB20018008080211062006500A088212A -:101D000092240004148000488F880028A380002CAF -:101D10008E2500048D0700C83C0600FF34C3FFFF7A -:101D200000A3302400E6102B14400050AF8600447E -:101D30008F870050978A004CAF87003001474023BF -:101D400010C00034A788004C8F99002030DF0003BA -:101D5000001F20239332007C309000030206702184 -:101D60000012C082331200010012788001CF682176 -:101D7000310CFFFF018D582B5160005F8F880028C8 -:101D80008F8900248F8200541049007B3C033F015F -:101D90008E2600003C11250000C3282414B10078D1 -:101DA0008F84003C8F8A003C8F8800288D4B000078 -:101DB000AD0B00788D470010AD0700888F8700506D -:101DC0008F860044938C002C01276821020628216D -:101DD000020C1821A383002C950900ACAF8D0024C0 -:101DE00035301000A51000AC1640005024720004DD -:101DF000AF850050000020218FBF001C8FB200185B -:101E00008FB100148FB000100080102103E0000893 -:101E100027BD00208F840024AF8000500087402120 -:101E20000A001D8BAF880024241F000CA39F0058BC -:101E30000E00189B020020212419FFFF1059FFEE0D -:101E40002404FFFF8F880028A380002C8E25000427 -:101E50008D0700C83C0600FF34C3FFFF00A33024F9 -:101E600000E6102B1040FFB2AF8600440200202194 -:101E700024090019A38900580E00189B2410FFFFA5 -:101E80001050FFDD2404FFFF0A001D5A8F86004416 -:101E90008F8400288F87003C8CF20030908600C42D -:101EA00030C5001014A000108F8300502C6800056E -:101EB0001500002600000000908A00C4246BFFFC7F -:101EC0003149001015200008316400FF8F8D005447 -:101ED0008F8C002411AC0004388F000131EE00011A -:101EE00015C0002F000000000E001D0A00000000B9 -:101EF0000A001DE2000000008F890024938C002C52 -:101F00000127682102062821020C1821A383002C36 -:101F1000950900ACAF8D002435301000A51000AC41 -:101F20005240FFB4AF85005024720004A392002CED -:101F3000950F00AC24B80004AF98005035EE200097 -:101F4000A50E00AC0A001D8C000020218C8200DC54 -:101F50001242FF6B0200202124180005A3980058AC -:101F60000E00189B2412FFFF1452FF652404FFFF8C -:101F70000A001D8D8FBF001C0A001DCD8F88002810 -:101F800030E500FF0E0017A2000030218F880028E6 -:101F90008F8700508F8900240A001D7F8F860044A0 -:101FA0000E0017CD000000000A001DE20000000036 -:101FB0009383004A27BDFFE024020002AFB200185D -:101FC000AFB10014AFBF001CAFB00010008088217B -:101FD000106200B6000090219783004C8F8500505E -:101FE0003066FFFF00C5202B1480005B938700380C -:101FF0003C0880009504012010E500528F8A0024DF -:102000008F84005430A500FF0E0017A224060001A3 -:102010008F82005C3C0B80003C1F4080244E017886 -:1020200031D00078240FFF80021F60253578090029 -:1020300031D9000701CF6824AD6D08000338802135 -:10204000AD6C081002202021020028210E001D4442 -:10205000AF90003C2403FFFF104300332404FFFF34 -:102060008E0C00103C0708008CE731B0920600008F -:1020700031843FFF0087282B10A0002330CD003F84 -:102080008F99005C000479803C0408008C8431A89E -:102090002409FF809390004900994021010F2021DD -:1020A00000897824000F51403C098000309F007F58 -:1020B0003C0B00808F880028308E00783578000136 -:1020C000015F282530860007352709403C031000B2 -:1020D0003C02800C01D8582500C7C82100A3502518 -:1020E00003E2C021360E0001AD2F0804AF99004075 -:1020F000AD2B0814AF980034AD2F0028AD04007448 -:10210000AD2A0830A38E00499383004A24100003AF -:102110005070002725A3FFE0240C0001106C001C68 -:1021200024060023024020218FBF001C8FB200181C -:102130008FB100148FB000100080102103E0000860 -:1021400027BD0020314900035520FFAE8F84005485 -:102150000A001E1F8F9000548F840054306500FFCA -:102160000E0017A224060001938E003824070034C5 -:1021700011C700188F8500509783004C3078FFFFFF -:1021800000B87023AF8E00500A001E57A780004C85 -:1021900011A6003200000000022020212411000BB3 -:1021A0000E00189BA39100580A001E570040902172 -:1021B0002C7200201240FFF8000310803C0508013B -:1021C00024A581600045F8218FED000001A00008E2 -:1021D000000000002CB800051700FFE89783004CB2 -:1021E000978A004C3148FFFF00A848232D2B00059B -:1021F00011600003314400FF24AFFFFC31E400FF15 -:102200008F9000548F99002412190004389F000108 -:1022100033ED000115A00029000000008F85002883 -:1022200090A700C434E30010A0A300C49783004C1F -:102230008F8500508F8400283078FFFF00B870230E -:10224000AC8000DCA780004C0A001E57AF8E005007 -:102250002403FFFF11830005000000000E001B7522 -:10226000022020210A001E57004090210E001AFA79 -:10227000022020210A001E57004090210E001C7BE6 -:10228000022020210A001E57004090210E001BD979 -:10229000022020210A001E57004090210E001A51F2 -:1022A000022020210A001E5700409021938500380B -:1022B0002404FFFD0A001E58AF8500500E0017CD04 -:1022C000000000009783004C8F85005000402021C3 -:1022D0003066FFFF00A660232D8200051040FFA896 -:1022E0003078FFFF8F91002800B87023AE2400DC07 -:1022F000A780004C0A001E57AF8E005027BDFFD0AC -:10230000AFB20018AFB00010AFBF0028AFB50024C7 -:10231000AFB40020AFB3001CAFB100143C0C800080 -:102320008D880128240FFF803C07800A25100100BA -:10233000250B0080020F68243205007F016F702496 -:10234000AD8E009000A72821AD8D002490A700EC51 -:102350003169007F3C0A8004012A1821A387004AC2 -:102360009066007C00809021AF83002030C2000284 -:10237000AF88005CAF85002800A01821144000023F -:102380002404003424040030A38400388C6600CC7C -:1023900030F100FF24040004AF8600501224000432 -:1023A000A38000588E5300041660001D3C08800076 -:1023B0009387004930F200011240000F8FBF0028C0 -:1023C0008CB800748CA400742419FF80031988242D -:1023D00000117140308F007F01CF60253C0D20003F -:1023E000018D582530F500FE3C0A8000AD4B0830C9 -:1023F000A39500498FBF00288FB500248FB400201B -:102400008FB3001C8FB200188FB100148FB0001072 -:102410002402000127BD003003E00008ACA600CC78 -:102420008E590008951F01208E460010033FC021E1 -:102430003307FFFF30F5000F32B40001AF860024F0 -:102440001680003BA395004835060C0002A610211B -:1024500000F51823AD030084AF8200548E490004B8 -:102460003128FFFF1100002BA789004C2410FF80AA -:102470003C1580003C1420000A001F442413FFFE7A -:1024800090AE00C4020E682431AC00FF1580002A13 -:1024900002402021938400499786004C308F000130 -:1024A00011E0000B026428248F8900288D2300741A -:1024B0008D280074A3850049007010240002C940D3 -:1024C000311F007F033FC02503148825AEB10830BB -:1024D00010C000108F85002890A700C40207582460 -:1024E000316A00FF1540FFE6024020210E001DFA70 -:1024F0009791004C1040FFE8938400492405FFFDAC -:10250000544500058E430020022028210E00177A32 -:10251000024020218E430020307000041600000A83 -:102520002414FFFB8F8500280A001EFA8F860050B6 -:102530000A001F25AF8600540E001A1D000000007F -:102540000A001F3493840049007498240E001792E7 -:10255000AE5300208F8500280A001EFA8F86005097 -:1025600027BDFFD8AFB3001CAFB10014AFBF002030 -:10257000AFB20018AFB000103C0280008C52014096 -:102580008C4B01483C048000000B8C02322300FF7E -:10259000317300FF8C8501B804A0FFFE34900180E8 -:1025A000AE1200008C8701442464FFF02406000270 -:1025B0002C830013AE070004A6110008A206000B2E -:1025C000AE1300241060004F8FBF0020000448802D -:1025D0003C0A0801254A81E0012A40218D040000BF -:1025E00000800008000000003C1008008E1031A898 -:1025F00031733FFF001389800212C8212405FF8038 -:1026000003312021264C0100264700803C1F80001A -:1026100000E51824318F007F30E9007F308A007F89 -:102620003C18800A3C0E80043C0D800C0085102470 -:1026300001853024014D8021AFE6002401F84021BE -:10264000AFE30090012E9821AFE20028AF90003454 -:10265000AF880028AF9300200E001867016080212A -:102660003C0380008C6B01B80560FFFE8F8700344F -:10267000346501808F86002890E3000DACB2000025 -:10268000A4B00006000316000002FE03001F9027FE -:10269000001227C21080007A24C2007824196082B8 -:1026A000A4B90008A0A00005241F0002A0BF000BD1 -:1026B00000041C008F8B00203C0227000062902544 -:1026C000ACB20010ACA00014ACA00024ACA0002858 -:1026D000ACA0002C8D7300382410FF80ACB3001820 -:1026E00090E4000D02048824322500FF10A00005AC -:1026F0008FBF002090EC000D3188007FA0E8000D16 -:102700008FBF00208FB3001C8FB200188FB1001450 -:102710008FB000103C0D10003C0A800027BD00283F -:1027200003E00008AD4D01B8265F01002405FF80DD -:1027300033F8007F3C06800003E578243C19800ACA -:1027400003192021ACCF0024908E00C400AE682471 -:1027500031AC00FF1180FFEAAF840028248E00789E -:1027600095CD00123C0C08008D8C31A831AB3FFF99 -:1027700001924821000B5180012A402101052024AB -:10278000ACC400283107007F3C06800C00E6202105 -:102790009083000D00A31024304500FF10A0FFD847 -:1027A000AF8400349098000D330F001015E0FFD572 -:1027B0008FBF00200E001867000000003C0380005F -:1027C0008C7901B80720FFFE00000000AE12000067 -:1027D0008C720144AE120004A611000824110002FC -:1027E000A211000BAE1300240A001FCF8FBF0020E0 -:1027F0003C1260008E452C083C03F0033462FFFF5E -:1028000000A2F824AE5F2C088E582C083C1901B0A9 -:1028100003199825AE532C080A001FCF8FBF002044 -:10282000264D010031AF007F3C10800A240EFF804E -:1028300001F0282101AE60243C0B8000AD6C002427 -:102840001660FFAFAF85002824110003A0B100EC93 -:102850000A001FCF8FBF002026480100310A007FE9 -:102860003C0B800A2409FF80014B30210109202400 -:102870003C078000ACE400240A001FCEAF8600288D -:10288000944A001232083FFF314C3FFF1588FF8405 -:102890002419608290CF00C4240EFF8001CF482409 -:1028A000312D00FF11A0FF7E00000000240700046E -:1028B000A0C700EC8F870034241860842406000D24 -:1028C000A4B80008A0A600050A001FB9241F000232 -:1028D0000800330C0800330C080033E8080033BC50 -:1028E000080033A0080032F0080032F0080032F08F -:1028F0000800331480080100800800808008000070 -:102900005F865437E4AC62CC50103A453662198584 -:10291000BF14C0E81BC27A1E84F4B556094EA6FE49 -:102920007DDA01E7C04D748108007A8808007AB426 -:1029300008007A94080079D008007A9408007AD4C4 -:1029400008007A94080079D0080079D0080079D07E -:10295000080079D0080079D0080079D0080079D033 -:10296000080079D0080079D0080079D008007AC42E -:1029700008007AA4080079D0080079D0080079D03E -:10298000080079D0080079D0080079D0080079D003 -:10299000080079D0080079D0080079D0080079D0F3 -:1029A000080079D008007AA40800809008007F38D9 -:1029B0000800805808007F380800802808007E2022 -:1029C00008007F3808007F3808007F3808007F380B -:1029D00008007F3808007F3808007F3808007F38FB -:1029E00008007F3808007F3808007F3808007F38EB -:0429F00008007F60FC -:0C29F4000A0001220000000000000000AA -:102A00000000000D747061352E302E306A313500B3 -:102A100005000001000000000000000000000000B0 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A800010000003000000000000000D0000000D19 -:102A90003C02080024421C203C03080024631FA0C1 -:102AA000AC4000000043202B1480FFFD24420004B2 -:102AB0003C1D080037BD2FFC03A0F0213C1008008E -:102AC000261004883C1C0800279C1C200E0002E2F3 -:102AD000000000000000000D2402FF8027BDFFE081 -:102AE00000821024AFB00010AF420020AFBF00182A -:102AF000AFB10014936500043084007F03441821B3 -:102B00003C0200080062182130A5002003608021EB -:102B10003C080111277B000814A000022466005C19 -:102B200024660058920200049743010492040004B2 -:102B30003047000F3063FFFF3084004000672823D8 -:102B40001080000900004821920200053042000474 -:102B5000104000050000000010A00003000000006D -:102B600024A5FFFC24090004920200053042000461 -:102B7000104000120000000010A000100000000033 -:102B80009602000200A72021010440252442FFFEF6 -:102B9000A7421016920300042402FF800043102471 -:102BA000304200FF104000033C0204000A000172A2 -:102BB000010240258CC20000AF4210188F420178FC -:102BC0000440FFFE2402000AA742014096020002D0 -:102BD000240400093042000700021023304200079D -:102BE000A7420142960200022442FFFEA74201448E -:102BF000A740014697420104A74201488F420108BD -:102C000030420020504000012404000192020004E0 -:102C1000304200101440000234830010008018215C -:102C2000A743014A0000000000000000000000006F -:102C300000000000AF48100000000000000000008D -:102C400000000000000000008F4210000441FFFE61 -:102C50003102FFFF10400007000000009202000454 -:102C60003042004014400003000000008F42101862 -:102C7000ACC20000960200063042FFFF2442000270 -:102C800000021043000210400362882196220000D7 -:102C90001120000D3044FFFF00A710218F83003862 -:102CA0008F45101C0002108200021080004310218A -:102CB000AC45000030A6FFFF0E0002D100052C023B -:102CC00000402021A6220000920300042402FF807D -:102CD00000431024304200FF1040001F000000009D -:102CE00092020005304200021040001B000000006C -:102CF0009742100C2442FFFEA7421016000000006D -:102D00003C02040034420030AF42100000000000DA -:102D10000000000000000000000000008F421000D2 -:102D20000441FFFE000000009742100C8F45101C6C -:102D30003042FFFF24420030000210820002108067 -:102D4000005B1021AC45000030A6FFFF0E0002D151 -:102D500000052C02A622000096040002248400082C -:102D60000E0001E73084FFFF974401040E0001F5D7 -:102D70003084FFFF8FBF00188FB100148FB0001098 -:102D80003C02100027BD002003E00008AF4201789C -:102D90003084FFFF308200078F850024104000023E -:102DA000248300073064FFF800A4102130421FFF85 -:102DB00003421821247B4000AF850028AF82002405 -:102DC00003E00008AF4200843084FFFF3082000F30 -:102DD0008F85002C8F860034104000022483000F62 -:102DE0003064FFF000A410210046182BAF8500309E -:102DF0000046202314600002AF82002CAF84002C18 -:102E00008F82002C340480000342182100641821B2 -:102E1000AF83003803E00008AF4200808F820014C7 -:102E2000104000088F8200048F82FFCC1440000500 -:102E30008F8200043C02FFBF3442FFFF0082202447 -:102E40008F82000430430006240200021062000F4B -:102E50003C0201012C6200035040000524020004E2 -:102E60001060000F3C0200010A00022E000000006A -:102E700010620005240200061462000C3C020111DD -:102E80000A000227008210253C0200110082102552 -:102E9000AF421000240200010A00022EAF82000C93 -:102EA00000821025AF421000AF80000C000000002F -:102EB000000000000000000003E000080000000027 -:102EC0008F82000C10400004000000008F421000B0 -:102ED0000441FFFE0000000003E0000800000000C5 -:102EE0008F8200102443F800000229C224A2FFF0C0 -:102EF0002C63030110600003000210420A00025517 -:102F0000AC8200008F83001800A3102B1440000B2C -:102F10000000382100A31023244600018F82001CEA -:102F2000006210212442FFFF0045102B5440000492 -:102F30002402FFFF0A000255AC8600002402FFFFB6 -:102F40000A00025AAC8200008C8200003C03080098 -:102F500024631C5C000211400043382103E0000898 -:102F600000E010213C0908008D291D80000451401B -:102F70003C19080027391C5C00C0782100806021C2 -:102F8000240EFFFF00003821015940211120003696 -:102F9000000030213C18080027181D983C0D08003F -:102FA00025AD1D9C000F582B0006118000461021F6 -:102FB000000218C0007810218C4200001582002009 -:102FC000006D20218CA20000544000098D020018E1 -:102FD0003C0208008C421D8424420001AC820000A7 -:102FE0003C010800AC221D840A0002CF0000202111 -:102FF0008F47002000003021000211C01160004AFC -:10300000AF4200208D08001C3C0900088CA3000082 -:103010000066182100031880007A10210049102151 -:103020008C44000024C600010068182100CF102B3A -:103030001440FFF6AC6400000A0002CD000000005E -:103040008C840000008E102B5040000424C6000128 -:103050000080702100C0382124C6000100C9102B57 -:103060001440FFD20006118024020001ACA200002F -:103070003C0208008C421D7C3C0308008C631D80D0 -:103080000043102B1440002A2404FFFE0159102194 -:103090008C420018104000262404FFFF0007218006 -:1030A0003C0508008CA51D84008720218D06001892 -:1030B000000420C03C02080024421D980082102118 -:1030C0003C03080024631D9CAC4C000024A50001B7 -:1030D000008318213C02080024421DA0AC650000BA -:1030E000000631C03C010800AC251D84008220216F -:1030F0008F470020AD04001CAF46002011E0000AFD -:10310000000030213C020008034228218CA200006C -:1031100024C6000100CF182BAC82000024A50004B7 -:103120001460FFFA24840004AF470020000020212F -:1031300003E00008008010213084FFFF30C6FFFF4D -:1031400000052C0000A628253882FFFF004510212D -:103150000045282B0045102100021C023042FFFFD1 -:103160000043102100021C023042FFFF00431021E7 -:103170003842FFFF03E000083042FFFF27BDFFC8D1 -:10318000AFBF0030AFB3002CAFB20028AFB1002406 -:10319000AFB000203C0460088C8250002403FF7F05 -:1031A0003C066000004310243442380CAC825000CE -:1031B0008CC24C1C3C1A8000000216023042000FE8 -:1031C00010400007AF82001C8CC34C1C3C02001F47 -:1031D0003442FC0000621824000319C2AF830018B7 -:1031E0008F420008275B400034420001AF420008D4 -:1031F000AF8000243C02601CAF400080AF400084E0 -:103200008C4500088CC3080834028000034220214A -:103210002402FFF0006218243C0200803C010800F8 -:10322000AC2204203C025709AF8400381462000429 -:10323000AF850034240200010A000314AF82001499 -:10324000AF8000142403003D240200043C01080068 -:10325000AC221D943C010800AC231D903C010800E9 -:10326000AC231D8C3C010800AC231D883C130800D6 -:1032700026731C5C240400043C02080024421C74D5 -:10328000240300082463FFFFAC400004AC400000AE -:103290000461FFFC24420020000410C000441021FF -:1032A0002442003D3C010800AC221D902402000194 -:1032B0003C010800AC221D7C2402FFFF3C010800F9 -:1032C000AC221D983C010800AC201D848F420000F8 -:1032D00038420001304200011440FFFC8F8200148C -:1032E0001040001600000000974201041040000545 -:1032F0008F830000146000072462FFFF0A00034B65 -:103300002C62000A2C620010504000048F830000E1 -:1033100024620001AF8200008F8300002C62000A4B -:10332000144000032C6200070A000352AF80FFCC58 -:103330001040000224020001AF82FFCC8F4301083D -:103340008F44010030622000AF8300041040000869 -:10335000AF8400103C0208008C42042C244200017F -:103360003C010800AC22042C0A0006D73C024000B5 -:103370003065020014A0000324020F001482030928 -:1033800024020D0097420104104003713C024000EA -:1033900030624000144000AD8F8200388C44000839 -:1033A0008F4201780440FFFE24020800AF420178FA -:1033B00024020008A7420140A740014297420104AD -:1033C0008F8400043051FFFF30820001104000075D -:1033D000022080212623FFFE240200023070FFFF1E -:1033E000A74201460A00037FA7430148A7400146C0 -:1033F0003C0208008C42043C1440000D8F830010F6 -:10340000308200201440000224030009240300013C -:10341000006020218F830010240209005062000107 -:1034200034840004A744014A0A00039A0000000003 -:1034300024020F00146200053082002014400006B0 -:103440002403000D0A000399240300051440000220 -:103450002403000924030001A743014A3C02080099 -:103460008C4204203C0400480E00020A004420253F -:103470000E000233000000008F82000C1040003E5E -:10348000000000008F4210003C0300200043102485 -:10349000104000398F820004304200021040003694 -:1034A0000000000097421014144000330000000098 -:1034B000974210088F8800383042FFFF24420006F0 -:1034C000000218820003388000E8302130430001F8 -:1034D0008CC4000010600004304200030000000DA6 -:1034E0000A0003DB00E81021544000103084FFFF85 -:1034F0003C05FFFF00852024008518260003182BBB -:103500000004102B004310241040000500000000B0 -:10351000000000000000000D000000002400021C5C -:103520008CC200000A0003DA004520253883FFFF23 -:103530000003182B0004102B00431024104000053A -:1035400000000000000000000000000D000000006E -:10355000240002258CC200003444FFFF00E8102143 -:10356000AC4400003C0208008C42043024420001BC -:103570003C010800AC2204308F6200008F840038C8 -:10358000AF8200088C8300003402FFFF1462000F3A -:10359000000010213C0508008CA504543C040800E0 -:1035A0008C84045000B0282100B0302B00822021F0 -:1035B000008620213C010800AC2504543C01080091 -:1035C000AC2404500A0006CD240400088C820000BC -:1035D000304201001040000F000010213C0508009F -:1035E0008CA5044C3C0408008C84044800B02821BD -:1035F00000B0302B00822021008620213C010800F1 -:10360000AC25044C3C010800AC2404480A0006CD5B -:10361000240400083C0508008CA504443C04080070 -:103620008C84044000B0282100B0302B008220217F -:10363000008620213C010800AC2504443C01080020 -:10364000AC2404400A0006CD240400088F62000860 -:103650008F62000000021602304300F024020030A6 -:1036600010620005240200401062016B8F8200206E -:103670000A0006D52442000114A000050000000045 -:10368000000000000000000D0000000024000250B7 -:103690008F4201780440FFFE000000000E00023B54 -:1036A00027A4001014400005004080210000000005 -:1036B0000000000D00000000240002578E020000F0 -:1036C0001040000500000000000000000000000D98 -:1036D000000000002400025A8F62000C0443000323 -:1036E000240200010A00055DAE000000AE020000E9 -:1036F0008F8200388C450008A20000078F65000CFF -:103700008F64000430A3FFFF0004240200852023FF -:10371000308200FF0043102124420005000288830C -:103720002E220081A605000A14400005A204000410 -:10373000000000000000000D0000000024000272E4 -:103740003C0708008CE71D808FA800102409FFFFAC -:103750000000502110E00013000030213C0C080054 -:10376000258C1D9C01802821000018218CA2FFFCC3 -:103770005102002F006C18218CA400002463020861 -:103780000089102B1040000324A502080080482166 -:1037900000C0502124C6000100C7102B5440FFF484 -:1037A0008CA2FFFC3C0508008CA51D803C02080093 -:1037B0008C421D7C3C09080025291C603C03080044 -:1037C00024631D9800A2102B3C0C0800258C1D9C26 -:1037D0003C0408008C841D843C0B0800256B1DA054 -:1037E0001040001A000831400005118000451021EA -:1037F000000210C000C9382124840001004B302190 -:103800000043182124A50001004C1021AC680000E1 -:10381000ACE600183C010800AC241D84AC44000058 -:103820003C010800AC251D800A0004A88E04001C81 -:103830003C0208008C421D84244200013C01080027 -:10384000AC221D840A0004A7AC620000000A1180AB -:10385000004A1021000210C0004328218CA3000060 -:10386000004C3821248400010003194000C9302194 -:1038700000691821004B1021ACA80000AC600018B2 -:103880003C010800AC241D84ACC20018ACE400006C -:103890008E04001C8F8500380E0006E702203021C0 -:1038A0008F6200048F430108A60200083C0210004A -:1038B0000062182410600008000000009742010414 -:1038C000920300072442FFEC346300023045FFFFFF -:1038D0000A0004BCA2030007974201042442FFF03F -:1038E0003045FFFF960600082CC200135440000527 -:1038F000920300079202000734420001A20200076F -:103900009203000724020001106200052402000354 -:103910001062000B30C7FFFF0A0004DB24E2000244 -:103920008F8200383C04FFFF8C43000C0064182495 -:1039300000651825AC43000C0A0004DA30C7FFFF0D -:103940008F8200383C04FFFF8C4300100064182471 -:1039500000651825AC43001030C7FFFF24E20002C9 -:1039600000021083A20200058F830038304200FF5E -:1039700000021080004330218CC500008CC2000082 -:103980002403000400021702144300130000000087 -:10399000974201043C03FFFF00A318243042FFFFBD -:1039A000004710232442FFFE00622825ACC500001A -:1039B000920400058E03001C308200FF000210807C -:1039C00000431021904200003042000F00441021BB -:1039D0000A000510A20200068CC4000497420104EC -:1039E0009603000A3085FFFF3042FFFF0047102397 -:1039F0002442FFD60002140000A22825ACC5000412 -:103A00009202000792040005246300280003188333 -:103A10000064182134420004A2030006A202000739 -:103A20008F8200042403FFFB344200020043102471 -:103A3000AF820004920300068E07001C8F860038B8 -:103A400000031880006710218C44000C3C02FFF634 -:103A50003442FFFF0082282400661821AE04000CC7 -:103A6000AC65000C920300068E04000C3C02FF7F44 -:103A70003442FFFF0003188000A228240082202483 -:103A800000671821AE04000CAC65000C9202000621 -:103A9000000210800047102194450012AC45001030 -:103AA000920200060002108000461021AC45001072 -:103AB0008FA200109203000500021140000318803D -:103AC00000671821005320218C6200048C830018A9 -:103AD0001460000EAE0200143C0308008C631D8CC1 -:103AE000AC8300183C0208008C421D900062102B31 -:103AF00010400019000000003C0208008C421D9498 -:103B0000006210213C010800AC221D8C8E020018BE -:103B10008F48002000003021000211C01220000B4D -:103B2000AF4200203C0200080342282100E020218F -:103B30008C82000024C6000100D1182BACA200002A -:103B4000248400041460FFFA24A50004AF48002078 -:103B50000A00055E24020010000000000000000DB5 -:103B600000000000240002D424020010A7420140FB -:103B700024020002A7400142A7400144A742014697 -:103B8000974201043C0400082442FFFEA74201487A -:103B9000240200010E00020AA742014A9603000A0D -:103BA0009202000400431021244200023042000728 -:103BB00000021023304200070E000233AE02001054 -:103BC0008F6200003C0308008C630444240400104E -:103BD000AF820008974201043042FFFF2442FFFEFB -:103BE00000403821000237C33C0208008C420440E8 -:103BF000006718210067282B00461021004510217E -:103C00003C010800AC2304443C010800AC22044001 -:103C10000A0006620000000014A000050000000079 -:103C2000000000000000000D00000000240003045C -:103C30008F4201780440FFFE000000000E00023BAE -:103C400027A400141440000500408021000000005B -:103C50000000000D000000002400030B9206000489 -:103C60008FA4001427A50018000630820E00025C05 -:103C7000AFA00018504000068E02000000000000B7 -:103C80000000000D00000000240003118E0200005F -:103C90005440000692020007000000000000000DE2 -:103CA00000000000240003169202000730420004C6 -:103CB000104000058F8200042403FFFB3442000201 -:103CC00000431024AF8200048F6200040443000903 -:103CD00092020007920200068E03001C8E04000C64 -:103CE0000002108000431021AC44000CAE00000024 -:103CF00092020007304200045440000B920300047B -:103D0000920300058E0400148E05001C0003188029 -:103D10003C0200010082202100651821AE0400143D -:103D2000AC640004920300049602000A00621021B1 -:103D300024420005000290838FA200181040000D5D -:103D4000277100088FA40014000310820242302360 -:103D500027A500180E00025CAFA200185040000614 -:103D60008E05001C000000000000000D0000000097 -:103D70002400033F8E05001C022020210E0006E7D0 -:103D800002403021920400068F6500043C027FFF50 -:103D900000042080009120218C8300043442FFFF26 -:103DA00000A2282400651821AC83000492020007B9 -:103DB00092030004920500053042000410400014F4 -:103DC0009607000830A500FF0005288000B12821D3 -:103DD0008CA40004974201049606000A306300FF99 -:103DE0003042FFFF004310210046102130E3FFFF67 -:103DF000004310232442FFD83084FFFF0002140048 -:103E000000822025ACA400040A00061692030007D5 -:103E100030A500FF0005288000B128218CA40000F7 -:103E200097420104306300FF3042FFFF004310213E -:103E3000004710233C03FFFF008320243042FFFF94 -:103E400000822025ACA40000920300072402000198 -:103E5000106200060000000024020003106200113E -:103E6000000000000A0006398E030010974201048A -:103E7000920300049605000A8E24000C00431021D2 -:103E8000004510212442FFF23C03FFFF0083202461 -:103E90003042FFFF00822025AE24000C0A000639C4 -:103EA0008E03001097420104920300049605000A55 -:103EB0008E24001000431021004510212442FFEE03 -:103EC0003C03FFFF008320243042FFFF00822025B7 -:103ED000AE2400108E0300102402000AA742014005 -:103EE000A74301429603000A920200043C040040EA -:103EF00000431021A7420144A74001469742010414 -:103F0000A7420148240200010E00020AA742014A0A -:103F10000E000233000000008F62000092030004D4 -:103F200000002021AF820008974201049606000A93 -:103F30003042FFFF00621821006028213C03080086 -:103F40008C6304443C0208008C4204400065182144 -:103F5000004410210065382B004710213C01080067 -:103F6000AC2304443C010800AC2204409204000449 -:103F7000008620212484000A3084FFFF0E0001E720 -:103F800000000000974401043084FFFF0E0001F59B -:103F9000000000003C021000AF4201780A0006D485 -:103FA0008F820020148200273062000697420104AD -:103FB000104000673C0240003062400010400005A5 -:103FC00000000000000000000000000D00000000E4 -:103FD0002400041A8F4201780440FFFE24020800E6 -:103FE000AF42017824020008A7420140A7400142E5 -:103FF0008F82000497430104304200011040000703 -:104000003070FFFF2603FFFE24020002A742014694 -:10401000A74301480A00068C2402000DA740014670 -:104020002402000DA742014A8F6200002404000808 -:10403000AF8200080E0001E7000000000A000666DB -:1040400002002021104000423C0240009362000028 -:10405000304300F0240200101062000524020070BA -:10406000106200358F8200200A0006D5244200012C -:104070008F620000974301043050FFFF3071FFFF53 -:104080008F4201780440FFFE320200070002102335 -:10409000304200072403000A2604FFFEA743014024 -:1040A000A7420142A7440144A7400146A751014845 -:1040B0008F4201083042002014400002240300090E -:1040C00024030001A743014A0E00020A3C040040F9 -:1040D0000E000233000000003C0708008CE7044497 -:1040E000021110212442FFFE3C0608008CC6044049 -:1040F0000040182100E33821000010218F650000E6 -:1041000000E3402B00C230212604000800C8302103 -:104110003084FFFFAF8500083C010800AC27044451 -:104120003C010800AC2604400E0001E7000000003E -:104130000A000666022020210E000139000000005E -:104140008F82002024420001AF8200203C02400008 -:10415000AF4201380A000336000000003084FFFF40 -:1041600030A5FFFF000018211080000700000000AC -:104170003082000110400002000420420065182136 -:104180000A0006DD0005284003E000080060102159 -:1041900010C0000624C6FFFF8CA2000024A5000466 -:1041A000AC8200000A0006E72484000403E0000853 -:1041B0000000000010A0000824A3FFFFAC86000050 -:1041C00000000000000000002402FFFF2463FFFF46 -:1041D0001462FFFA2484000403E0000800000000D9 -:0441E00000000001DA -:0C41E4000A00002A00000000000000009B -:1041F0000000000D747870352E302E306A31350095 -:10420000050000000000000A000001360000EA601E -:10421000000000000000000000000000000000009E -:10422000000000000000000000000000000000008E -:10423000000000000000000000000000000000007E -:104240000000000000000016000000000000000058 -:10425000000000000000000000000000000000005E -:10426000000000000000000000000000000000004E -:1042700000000000000000000000000000001388A3 -:1042800000000000000005DC00000000000000004D -:1042900010000003000000000000000D0000000DF1 -:1042A0003C020800244239203C03080024633BD42C -:1042B000AC4000000043202B1480FFFD244200048A -:1042C0003C1D080037BD7FFC03A0F0213C10080016 -:1042D000261000A83C1C0800279C39200E0004076B -:1042E000000000000000000D8F86003C3C039000A1 -:1042F0003C0280000086282500A32025AC44002035 -:104300003C0380008C67002004E0FFFE00000000FA -:1043100003E00008000000000A000041240400013E -:104320008F85003C3C0480003483000100A31025ED -:1043300003E00008AC82002003E000080000102128 -:104340003084FFFF30A5FFFF108000070000182118 -:104350003082000110400002000420420065182154 -:104360001480FFFB0005284003E0000800601021D6 -:1043700010C00007000000008CA2000024C6FFFF50 -:1043800024A50004AC82000014C0FFFB24840004B8 -:1043900003E000080000000010A0000824A3FFFFB5 -:1043A000AC86000000000000000000002402FFFFB7 -:1043B0002463FFFF1462FFFA2484000403E0000872 -:1043C0000000000090AA00318FAB00108CAC0040C0 -:1043D0003C0300FF8D680004AD6C00208CAD0044F0 -:1043E00000E060213462FFFFAD6D00248CA700481F -:1043F0003C09FF000109C024AD6700288CAE004CC9 -:104400000182C82403197825AD6F0004AD6E002C1D -:104410008CAD0038314A00FFAD6D001C94A900320C -:104420003128FFFFAD68001090A70030A5600002A2 -:10443000A1600004A167000090A30032306200FF79 -:104440000002198210600005240500011065000EAD -:104450000000000003E00008A16A00018CD80028D9 -:10446000354A0080AD7800188CCF0014AD6F001471 -:104470008CCE0030AD6E00088CC4002CA16A000107 -:1044800003E00008AD64000C8CCD001CAD6D00187D -:104490008CC90014AD6900148CC80024AD680008F4 -:1044A0008CC70020AD67000C8CC200148C83007098 -:1044B0000043C82B13200007000000008CC200142A -:1044C000144CFFE400000000354A008003E00008BF -:1044D000A16A00018C8200700A0000B70000000091 -:1044E0009089003027BDFFF88FA8001CA3A9000009 -:1044F0008FA300003C0DFF8035A2FFFF8CAC002C89 -:1045000000625824AFAB0000A100000400C0582195 -:10451000A7A000028D06000400A048210167C82161 -:104520008FA50000008050213C18FF7F032C20261F -:104530003C0E00FF2C8C0001370FFFFF35CDFFFF35 -:104540003C02FF0000AFC82400EDC02400C2782464 -:10455000000C1DC00323682501F87025AD0D000077 -:10456000AD0E00048D240024AFAD0000AD040008A2 -:104570008D2C00202404FFFFAD0C000C9547003269 -:1045800030E6FFFFAD0600109145004830A200FF65 -:10459000000219C2506000018D240034AD040014E3 -:1045A0008D4700388FAA001827BD0008AD0B0028E2 -:1045B000AD0A0024AD07001CAD00002CAD000018B2 -:1045C00003E00008AD00002027BDFFE0AFB20018F7 -:1045D000AFB10014AFB00010AFBF001C9098003016 -:1045E00000C088213C0D00FF330F007FA0CF0000EA -:1045F000908E003135ACFFFF3C0AFF00A0CE0001D9 -:1046000094A6001EA22000048CAB00148E29000486 -:1046100000A08021016C2824012A402400809021E0 -:1046200001052025A6260002AE2400042605002050 -:10463000262400080E000063240600029247003082 -:10464000260500282624001400071E000003160378 -:1046500024060004044000032403FFFF965900329F -:104660003323FFFF0E000063AE2300102624002436 -:104670008FBF001C8FB200188FB100148FB00010D4 -:1046800024050003000030210A00006D27BD002032 -:1046900027BDFFD8AFB1001CAFB00018AFBF0020DE -:1046A00090A900302402000100E050213123003F96 -:1046B00000A040218FB000400080882100C0482128 -:1046C000106200148FA70038240B000500A02021E1 -:1046D00000C02821106B0013020030210E0000F9E9 -:1046E000000000009225007C30A40002108000032E -:1046F00026030030AE000030260300348FBF0020B8 -:104700008FB1001C8FB000180060102103E000087A -:1047100027BD00280E000078AFB000100A0001404D -:10472000000000008FA3003C01002021012028216F -:1047300001403021AFA300100E0000BFAFB0001445 -:104740000A000140000000003C0580008CA30E1010 -:104750008F840044AC8300208CA20E1803E0000874 -:10476000AC8200243C0580008CA30E148F8400448E -:10477000AC8300208CA20E1C03E00008AC82002455 -:104780009382000C1040001B2483000F2404FFF0D0 -:104790000064382410E00019978B00109784000EF5 -:1047A0009389000D3C0A601C0A00017B01644023D0 -:1047B00001037021006428231126000231C2FFFF8B -:1047C00030A2FFFF0047302B50C0000E00E448210C -:1047D0008D4D000C31A3FFFF00036400000C2C037F -:1047E00004A1FFF30000302130637FFF0A00017352 -:1047F0002406000103E00008000000009784000E7A -:1048000000E448213123FFFF3168FFFF0068382BA7 -:1048100054E0FFF8A783000E938A000D11400005B5 -:10482000240F0001006BC023A380000D03E00008EB -:10483000A798000E006BC023A38F000D03E00008B3 -:10484000A798000E03E000080000000027BDFFE865 -:10485000AFB000103084FFFF3C10800093A8002B05 -:10486000AFBF0014A6040144960A0E1630C600FF1E -:104870008FA90030A60A0146AE050148A2060152E2 -:10488000A608015AAE0701608FA3002CA6090158A3 -:10489000012020210E000167AE0301543C021000EC -:1048A000AE0201788FBF00148FB0001003E0000843 -:1048B00027BD00188F8500002484000727BDFFF85E -:1048C0003084FFF83C06800094CB008A316AFFFFF9 -:1048D000AFAA00008FA90000012540232507FFFF94 -:1048E00030E31FFF0064102B1440FFF700056882BF -:1048F000000D288034CC400000AC102103E00008FB -:1049000027BD00088F8200002486000730C5FFF80D -:1049100000A2182130641FFF03E00008AF840000EC -:104920008F8500448F8A003C27BDFFB03C04800087 -:10493000AFB70044AFB40038AFB1002CAFBF0048F0 -:10494000AFB60040AFB5003CAFB30034AFB20030FB -:10495000AFB000288C8701048CA90024AC8A0080A9 -:104960008CA8002000E988230000B821AC880E1034 -:104970008CA600240000A021AC860E188C820E109C -:10498000AC820E148C830E18AC830E1C122000FB1C -:104990003C168000936B0008116000F100000000DD -:1049A000976E001031CDFFFF022D602B158000ECBB -:1049B0000000000097700010320FFFFFAECF0E0016 -:1049C0003C0580008CB30000327200081240FFFDED -:1049D0000000000094B50E088CA70E0432A5FFFF5E -:1049E00030B40001128000E1000000000000000D62 -:1049F00030B9A040241800401338011730B4A0008B -:104A0000128000DC000000009373000812600008B0 -:104A100000000000976900103122FFFF00E2202B08 -:104A20001080000330A6004010C000D2000000003B -:104A3000A7850040AF870038936A0008022038211C -:104A4000AFB10020154000F127B40020AF60000C8A -:104A50009785004030B14000162000022403001664 -:104A60002403000E24154007A363000AAF75001449 -:104A7000939000428F6F0014321900010019C24058 -:104A800001F84025AF680014978700408F63001439 -:104A900030EE0010006E6825AF6D0014978C00405A -:104AA000318B000811600165000000008F65001463 -:104AB0003C0B10003C0A800000AB8825AF7100144D -:104AC00095460E0A3C0981002413000E30C2FFFFF8 -:104AD00000492025AF640004A3730002937F000AFD -:104AE0003406FFFC27F20004A372000A978D0040F1 -:104AF00031AC200011800157000000003C0780000D -:104B0000978D004094EC0E0C97910040000D584298 -:104B10003185C000316A00030005130332291000FB -:104B200001429825000922030264F825001F90C065 -:104B3000A7720012979500409379000A00158182B0 -:104B40003218003C0319782125E8003CA3680009CD -:104B500094EE0E0C31C33FFFA76300109763001261 -:104B60009367000900E3702125CD000231AC0007F6 -:104B7000000C582331650007A365000B93710009F1 -:104B800097640012976A0010322200FF8F9100385C -:104B9000979F004000444821012A982102669021F5 -:104BA00033F5004012A000053246FFFF00D1402B34 -:104BB0003C12800011000016000098210226782B7C -:104BC00015E001368FA700203C1880008F100E14CE -:104BD0003C058000AF100E108F190E1CAF190E1877 -:104BE000AF060E008CB200003255000812A0FFFD87 -:104BF0000000000094BF0E0800C088210000902132 -:104C0000A79F00408CA60E0424130001AF86003835 -:104C1000976900103135FFFF8E8C00000191202331 -:104C200010800118AE8400009367000814E000D8DB -:104C3000000000000E0001B4240400108F8E004814 -:104C40003C0332000040282131C600FF00063C0032 -:104C500000E3602525CD0001AF8D0048AC4C00007D -:104C60009362000997640012937F000A304A00FFA4 -:104C7000308BFFFF014B48210009CC0033F000FFCF -:104C80000330C025ACB800048F8F004897880040DF -:104C90003103200010600103ACAF0008976F0012D1 -:104CA00031E8FFFF06400101ACA8000C97900040DE -:104CB0003205000814A0000226280006262800025B -:104CC0003C048000948B0E148C850E1C8F670004AE -:104CD000936A00023164FFFF314900FFAFA9001061 -:104CE0008F7F0014AFA80018AFBF00140E00019A08 -:104CF00000000000240400100E0001C800000000A5 -:104D00008E92000016400005000000008F7900140C -:104D10002405FFBF0325A024AF7400148F69000C85 -:104D20000135F821AF7F000C9375000816A000082C -:104D30000000000012600006000000008F6B0014ED -:104D40003C0CEFFF3584FFFE01645024AF6A001471 -:104D5000A37300088FA700200A0003160220202159 -:104D6000AED10E000A0001F83C05800014E0FF21DE -:104D700030B9A0400E0001600000A0212E9100017A -:104D80000237B02512C000178FBF00488F85003C46 -:104D900024170F0010B700CD3C0480008C990178D7 -:104DA0000720FFFE24150F0050B500EB3C048000E7 -:104DB0008C890E14240502403C141000AC89014477 -:104DC0008C9F0E1CAC9F0148A0800152A480015A08 -:104DD000AC800160A4800158AC850154AC9401788A -:104DE0008FBF00488FB700448FB600408FB5003C9E -:104DF0008FB400388FB300348FB200308FB1002CE5 -:104E00008FB0002803E0000827BD00508F910038C4 -:104E1000979300403C1280000220A821326A004093 -:104E20001540FF7D00009821976B00108F8500389A -:104E30003162FFFF104500A2000020210080A02168 -:104E4000108000E500E088211620FED2000000005E -:104E50000A0002E72E9100013C0380008C7F01785C -:104E600007E0FFFE240408008F860000AC64017890 -:104E70003C038000946C008A318BFFFF0166502355 -:104E80002549FFFF31281FFF2D0200081440FFF9BC -:104E9000000000008F8E0048346F40008F83003C7C -:104EA00000E0A021240D0F0025C70001AF870048B6 -:104EB00000CF3021023488233C08800031D500FF28 -:104EC000106D000524070001939300423272000127 -:104ED0000012824036070001001514003C09010051 -:104EE00000492025ACC400008F9F004830B900362F -:104EF00030B80008ACDF00041300009000F99825DA -:104F000095070E0A8F8E00003C03810030EDFFFFF5 -:104F100025CB000801A328253C0C1000316A1FFF97 -:104F2000269200062406000EAD050160026C98254D -:104F3000A506015AAF8A0000A512015816200008E4 -:104F40003C1080008F99003C24180F005338000259 -:104F500024170001367300400E0001593C108000F8 -:104F60008E1F0E1402402021AE1F01448E120E1C13 -:104F7000AE120148A2150152AE1301540E00016792 -:104F80003C151000AE1501780A000319000000005E -:104F900093780009976300129368000B330F00FFAA -:104FA00001E33821310200FF00E2702125D0000A20 -:104FB0003210FFFF0E0001B4020020218F8600484E -:104FC0003C1941003C07800024CD0001AF8D004812 -:104FD000936C00099764001230C600FF318A00FF0D -:104FE000308BFFFF014B482100062C00253F0002BB -:104FF00000BFC02503197825AC4F00008F68000C56 -:1050000094EE0E1401121825AC4300048CE50E1C1E -:105010008F670004936D000231C4FFFF31AC00FFC5 -:10502000AFAC00108F620014AFB100180E00019AEF -:10503000AFA200140A0002C502002021AF600004E4 -:10504000A3600002978D004031AC20001580FEABBC -:1050500000003021A7600012979000409378000A6A -:105060003C03800032191F000019798301F84021A8 -:1050700025070028A3670009946E0E0C0A00025E43 -:10508000A76E00108F6E001435CD00400E00015940 -:10509000AF6D00140A000291000000000A00031620 -:1050A000000020210641FF01ACA0000C8CB8000CD0 -:1050B0003C198000031990250A0002B2ACB2000C22 -:1050C000000090210A00028D2413000112800005C7 -:1050D0003C0D800095A60E0830D3004012600042BF -:1050E000000000008C9001780600FFFE0000000028 -:1050F00094920E103C030500240720003258FFFF55 -:1051000003037825AC8F014C8C880E143C0E1000E4 -:10511000AC8801448C820E1CAC820148A0800152F4 -:10512000A480015AAC800160A4800158AC8701546E -:10513000AC8E01780A0002EE3C0480008F900000E3 -:1051400026920002A5120158260F000831E81FFF21 -:105150000A000356AF880000AC80014C1280001991 -:10516000000000008C8A0E10AC8A01448C830E185B -:105170003C0C800024160040AC8301488FBF0048DF -:10518000A18001528FB70044A580015A8FB5003C21 -:10519000AD8001608FB40038A58001588FB3003412 -:1051A000AD9601548FB200308FB600408FB1002C05 -:1051B0008FB000283C04100027BD005003E0000819 -:1051C000AD8401788C8B0E14AC8B01448C830E1C47 -:1051D0000A0003E43C0C80000E0001602E910001E7 -:1051E0000A0002E80237B025000000000000000DB0 -:1051F000000000002400033A0A0003C03C048000C1 -:1052000027BDFFE0AFBF001C3C1F20FF3C07600034 -:105210003C0980002402001037F9FFFDACE23008A1 -:10522000AFB20018AFB10014AFB00010AD390E002E -:10523000000000000000000000000000000000006E -:10524000000000003C1800FF3712FFFDAD320E00D9 -:105250003C0B60048D7050002411FF7F3C0E000257 -:105260000211782435EC380C35CD0109ACED4C1821 -:10527000240A0009AD6C50008CE80438AD2A0008FF -:10528000AD2000148CE54C1C3106FFFF38C42F7193 -:1052900000051E023062000F2486C0B310400007D4 -:1052A000AF8200088CE54C1C3C09001F3528FC002F -:1052B00000A81824000321C2AF8400048CF1080860 -:1052C0003C0F57092412F0000232702435F0001010 -:1052D00001D0602601CF68262DAA00012D8B000188 -:1052E000014B382550E00009A380000C3C02601CF3 -:1052F0008C590008241F0001A39F000C33387C0048 -:10530000A7980010A780000EA380000DAF80004872 -:1053100014C00003AF8000003C066000ACC0442C09 -:105320000E0004B63C1080000E000E0E00000000BF -:105330003C110800263139883C12080026523A08F0 -:105340008E05000038A30001306400011480FFFCCA -:10535000000000008E0601003C0C800A240AFF8039 -:1053600024C7024030EB007F016C482100EA402452 -:10537000AE060020AF890044AE0800243C03800044 -:10538000AF86003C8C6D017805A0FFFE2419080053 -:10539000AC79017890780108A3980042938F00427D -:1053A00031EE000111C0000F240D0D0024C2F800E1 -:1053B0002C5F030113E0001C000629C224A3FFF0A8 -:1053C00000032042000431400E0001CF00D1D8215B -:1053D0003C0440003C068000ACC401380A0004577D -:1053E0000000000010CD0026240E0F0010CE002A71 -:1053F0003C028008345F008093F90000240F0050C5 -:10540000333800FF170FFFF33C0440000E00092F54 -:10541000000000003C0440003C068000ACC40138A1 -:105420000A000457000000008F83000400A3402BF3 -:105430001500000B8F8B0008006B50212547FFFFE4 -:1054400000E5482B1520000600A36023000C29402E -:105450000E0001CF00B2D8210A00047C3C044000B9 -:10546000000000000000000D00000000240003AD5B -:105470000E0001CF000000000A00047C3C04400044 -:105480003C1B0800277B3B080E0001CF00000000FA -:105490000A00047C3C0440003C1B0800277B3B289E -:1054A0000E0001CF000000000A00047C3C04400014 -:1054B000000411C003E00008244202403C0408003C -:1054C00024843B6C2405001A0A00006D0000302182 -:1054D00027BDFFE0AFBF001CAFB20018AFB1001492 -:1054E000AFB000103C108000920B01092412FF8025 -:1054F0000E0004B33164007F8F91003C00515021B5 -:1055000001524024AE080024920301090E0004B3A6 -:105510003064007F24060080240700C0240400407B -:10552000AE000810AE040814AE060818AE07081C3A -:10553000920C01090051F82133F8007F3C19800AD0 -:10554000031910213184007F0E0004B3AF820044A0 -:105550008E1101003C0C008035850001022278216B -:1055600001F24824AE0908048E0E010035980002AD -:105570003609090001C2682131AB00780165502568 -:10558000AE0A08208E0501008E080100360509804C -:10559000010218212464004000923024AE0608085D -:1055A0008E07010000E2F82127F90040333200782D -:1055B00002588825AE1108248E040100952F000C96 -:1055C0008FBF001C8FB2001831EEFFFF000E69C0C4 -:1055D000AE0D0800AE0C0828952B000C8FB10014FE -:1055E000316AFFFF000A41C0AE08002C8CA30050B6 -:1055F0008FB000108CA2003C8D2400048CA6001CEF -:105600008CA7003827BD0020AF830060AF82005018 -:10561000AF84004CAF86005803E00008AF87005C01 -:105620003C098000352309009128010B906A001184 -:105630002402002800804821314700FF00A070218B -:1056400000C068213108004010E20002340C86DD01 -:10565000240C08003C0A800035420A9A9447000056 -:10566000354B0A9C35460AA030F9FFFFAD390000E2 -:105670008D780000354B0A8024040001AD38000409 -:105680008CCF0000AD2F00089165001930A30003F6 -:105690001064008E28640002148000AD240500020E -:1056A0001065009C240F0003106F00B235450AA45A -:1056B000240A0800118A0047000000005100003C45 -:1056C0003C0B80003C04800034830900906700128A -:1056D00030E200FF004D7821000FC8802724000130 -:1056E0003C0A8000354F090091E50019354C0980CE -:1056F0008D87002830A300FF0003150000475825C0 -:105700000004C4003C19600001793025370806FF09 -:10571000AD260000AD2800048DEA002C25280028C5 -:10572000AD2A00088DEC0030AD2C000C8DE5003466 -:10573000AD2500108DE40038AD2400148DE3001C6D -:10574000AD2300188DE700203C038000AD27001C2E -:105750008DE20024AD2200208DF900283462093C3E -:10576000AD3900248C450000AD0E000434790900E9 -:10577000AD0500008C67010C25020014AD07000880 -:10578000932B00123C04080090843B90AD00001065 -:10579000317800FF030D302100064F0000047C002B -:1057A000012F702535CDFFFF03E00008AD0D000C83 -:1057B00035780900930600123C05080094A53B804B -:1057C00030C800FF010D5021000A60800A00053F2B -:1057D000018520211500005A000000003C08080047 -:1057E00095083B863C06080094C63B8001061021C4 -:1057F0003C0B80003579090093380011932A001979 -:1058000035660A80330800FF94CF002A00086082C2 -:10581000314500FF978A0054000C1E00000524004B -:105820003047FFFF006410250047C02501EA302102 -:105830003C0B4000030B402500066400AD2800002F -:10584000AD2C0004932500183C0300062528001405 -:1058500000053E0000E31025AD2200088F24002C37 -:105860003C0380003462093CAD24000C8F38001CDE -:10587000254F000131EB7FFFAD3800108C45000053 -:10588000AD0E000434790900AD0500008C67010CF1 -:10589000A78B005425020014AD070008932B0012BB -:1058A0003C04080090843B90AD000010317800FF6C -:1058B000030D302100064F0000047C00012F7025ED -:1058C00035CDFFFF03E00008AD0D000C3C020800E1 -:1058D00094423B8A3C05080094A53B8035440AA4C9 -:1058E0003C07080094E73B7C948B00000045C821EE -:1058F0000327C023000B1C002706FFF2006650257B -:10590000AD2A000CAD200010AD2C00140A000533A8 -:1059100025290018354F0AA495E500009564002854 -:105920000005140000043C003459810000EC5825A7 -:10593000AD39000CAD2B00100A00053325290014E9 -:105940003C0C0800958C3B860A00058325820001EB -:105950005460FF58240A080035580AA4970600002E -:1059600000061C00006C5025AD2A000C0A0005330F -:10597000252900103C03080094633B8A3C0708007B -:1059800094E73B803C0F080095EF3B7C94A400001B -:105990009579002800671021004F582300041C004F -:1059A000001934002578FFEE00D87825346A81008C -:1059B000AD2A000CAD2F0010AD200014AD2C001846 -:1059C0000A0005332529001C03E00008240207D043 -:1059D00027BDFFE0AFB20018AFB10014AFB00010A8 -:1059E000AFBF001C0E00004D008088218F88005042 -:1059F0008F87004C3C05800834B2008001112821BB -:105A00003C10800024020080240300C000A7202353 -:105A1000AE0208183C068008AE03081C188000047B -:105A2000AF850050ACC500048CC90004AF89004CA0 -:105A300012200009360409800E0005F9000000005C -:105A4000924C00278E0B007401825004014B3021D0 -:105A5000AE46000C360409808C8E001C8F8F0058D7 -:105A600001CF682319A000048FBF001C8C90001C7C -:105A7000AF9000588FBF001C8FB200188FB1001478 -:105A80008FB000100A00004F27BD00208F860060F5 -:105A90008F8300508F82004C3C05800834A4008026 -:105AA000AC860050AC83003C03E00008ACA20004CC -:105AB0003C0308008C63005427BDFFF8308400FFCE -:105AC0002462000130A500FF3C010800AC22005414 -:105AD00030C600FF3C0780008CE801780500FFFE1F -:105AE0003C0A7FFFA3A400038FA400003549FFFFF9 -:105AF00000891824000647C000681025AFA20000E6 -:105B000090F9010AA3A000023C1880FFA3B900018C -:105B10008FAE000030AD007F370FFFFF01CF58245C -:105B2000000D66003C090020016C50253526200040 -:105B30002405FF803C04100027BD0008ACEA014C9E -:105B4000ACE60154A4E00158A0E5015203E00008CE -:105B5000ACE40178308800FF3C03800030A400FFF3 -:105B60008C6201780440FFFE000000003C038000CE -:105B700034660A008CCA0020346709800004482B70 -:105B8000AC6A01448CC5002400091540AC6501488D -:105B9000A068015090E4004CA064016D03E000088F -:105BA000A460015827BDFFE8308400FFAFBF00109C -:105BB0000E00065C30A500FF8F8300508FBF0010E1 -:105BC0003C058000344600402404FF903C02100055 -:105BD00027BD0018ACA3014CA0A40152ACA60154EF -:105BE00003E00008ACA2017827BDFFE03C08800874 -:105BF000AFBF001CAFB20018AFB10014AFB00010BF -:105C0000351000808E0600183C078000309200FF9F -:105C100000C72025AE0400180E00004D30B100FF73 -:105C200092030005346200080E00004FA202000536 -:105C3000024020210E00067002202821024020216F -:105C40008FBF001C8FB200188FB100148FB00010EE -:105C500024050005240600010A00063327BD0020A4 -:105C60003C05800034A309809066000830C200081B -:105C70001040000F3C0A01013549080AAC890000B8 -:105C80008CA80074AC8800043C07080090E73B90A7 -:105C900030E5001050A00008AC8000083C0D8008E2 -:105CA00035AC00808D8B0058AC8B00082484000C30 -:105CB00003E00008008010210A0006B32484000CD1 -:105CC00027BDFFE83C088000AFB00010AFBF001454 -:105CD0003506098090C7000924020006350909002D -:105CE00030E300FF0080802100A06021240B00042D -:105CF000106200792407000294CF005C3C0E02047D -:105D000031EDFFFF01AE5025AE0A000090C500083E -:105D100030A40020108000080000000090C2004E57 -:105D20003C1F010337F90300305800FF03193025E9 -:105D3000240B0008AE0600049139001191260012D0 -:105D400091240011333800FF0018708230CF00FF1B -:105D500001CF5021014C6821308800FF31AAFFFF9C -:105D600039030028000A28801460002B0205402314 -:105D7000912400123C0E800035D90980308500FF47 -:105D800000AC182100031080004BF821001F840094 -:105D9000360906FFAD09000435C909009126001136 -:105DA000912F0012000BC0828F2B003431ED00FFC9 -:105DB0008DC4010C01AC282100B810210164F82326 -:105DC0000007840000021F000070C82533E9FFFFB0 -:105DD00030CF00FC032970250158202101E86821FB -:105DE00000045080ADAE000C0E00004D010A802171 -:105DF0003C078008240C000434EB00800E00004FA8 -:105E0000A16C0009020010218FBF00148FB0001098 -:105E100003E0000827BD0018912500119123001907 -:105E20003C18080097183B8630A200FF0002F88259 -:105E3000307000FF001FCE0000104C0003293025F9 -:105E400000D870253C0F400001CF68253C0E800033 -:105E5000AD0D000035C9090091260011912F0012E7 -:105E600035D90980000BC08231ED00FF8F2B003443 -:105E70008DC4010C01AC282100B810210164F82365 -:105E80000007840000021F000070C82533E9FFFFEF -:105E900030CF00FC032970250158202101E868213A -:105EA00000045080ADAE000C0E00004D010A8021B0 -:105EB0003C078008240C000434EB00800E00004FE7 -:105EC000A16C0009020010218FBF00148FB00010D8 -:105ED00003E0000827BD00180A0006C524070012C9 -:105EE00027BDFFD0AFB60028AFB50024AFB4002067 -:105EF000AFB10014AFBF002CAFB3001CAFB200189D -:105F0000AFB000103C06800090C3010B309400FF3E -:105F100030B500FF306200300000B0211040009D1D -:105F20000000882134C409809088000800083E00E1 -:105F300000072E0304A000C4240400048F8700502F -:105F40003C010800A0243B903C0C8000AD80004840 -:105F50003C038000906D010B31A5002010A00007CC -:105F60003C0B8000347209809250000800107E00C3 -:105F7000000F760305C000C93C1980089169010B28 -:105F8000356A098091480008312400400004102B34 -:105F900031030008241200031460000200E2982379 -:105FA000000090213C108000360E0A80360809005F -:105FB00095C7002C910300119102001291C50018A1 -:105FC000307800FF305F00FF025FC8210019788041 -:105FD00091CC001801F8682101B1302130B100FFE7 -:105FE00000D11821A78700543C010800A4263B8655 -:105FF0003C010800A4233B8815800002000000003B -:106000000000000D9204010B3065FFFF3C01080009 -:10601000A4233B8A308900403C010800A4203B8037 -:106020003C010800A4203B7C1120000224A4000AAB -:1060300024A4000B3091FFFF0E0001B402202021A8 -:106040009219010B3C0E080095CE3B8A3C0D0800CE -:1060500091AD3B910019C182330F000101CF28217E -:10606000000D340024A7000200C758253C0C110085 -:10607000016C5025AC4A000024440008026028212D -:10608000024030210E00050FAC4000040E00069FB8 -:106090000040202116C00068004020219212010B10 -:1060A0003256004012C000053C0200FF8C930000F5 -:1060B000345FFFFF027F8024AC9000000E0001C817 -:1060C000022020213C03080090633B9030710003C4 -:1060D000122000163C1080088F8C00503C0B80086A -:1060E00035640080258A0001AC8A003C3C058008AC -:1060F0008CA9000401402021012A4023190000023C -:10610000AF8A00508CA400040E0005F9ACA4000472 -:106110003C0E80008DCD00743C05800834A60080C4 -:10612000004D3821ACC7000C3C10800836120080AE -:106130000280202102A02821A240006B0E00065CF4 -:106140003C1480008F9600503C151000AE96014C18 -:106150008F980048344F00068FBF002C271900018C -:10616000AF9900488FB60028A29801528FB3001C47 -:10617000AE8F01548FB20018AE9501788FB1001424 -:106180008FB500248FB400208FB0001003E000080A -:1061900027BD003034C30980906F0008000F7600DF -:1061A000000E6E0305A0003334DF090093F8001BD6 -:1061B000241900103C010800A0393B903313000261 -:1061C0001260FF638F8700508F82005C1447FF616D -:1061D0003C0380000E00004D000000003C048008DD -:1061E0003485008090A8000924070016310300FFC1 -:1061F0001067000D0000000090AB00093C0608008D -:1062000090C63B9024090008316400FF34CA0001A5 -:106210003C010800A02A3B901089002F240C000AA2 -:10622000108C00282402000C0E00004F000000001B -:106230000A00075B8F8700500E0006B70240282136 -:106240000A0007AE004020213C0B8008356A008020 -:106250008D4700548CC9010C1120FF39AF870050C5 -:10626000240600143C010800A0263B900A00075AAF -:106270003C0C800090710008241200023C010800D0 -:10628000A0323B90323000201200000B2416000197 -:106290008F8700500A00075B241100083733008005 -:1062A0008E7F0038AF3F00048F380004AE78003C8A -:1062B0000A0007663C0B80008F8700500A00075BCE -:1062C00024110004A0A200090E00004F00000000ED -:1062D0000A00075B8F870050240200140A00083967 -:1062E000A0A2000927BDFFE8AFBF0014AFB00010A7 -:1062F0003C10800092020109240500010E00065C9A -:10630000304400FF3C1F800893F8000E37E3008004 -:1063100093F9000F906E002693E9000A332F00FFD7 -:1063200000186600000F6C0031CB00FF018D502576 -:10633000000B320001463825312800FF344560004B -:1063400000E820252402FF813C031000AE04014C2C -:106350008FBF0014AE050154A2020152AE030178B2 -:106360008FB0001003E0000827BD001827BDFFE82C -:10637000308400FFAFBF00100E00065C30A500FFA8 -:10638000344600403C0480002405FF92AC86015452 -:10639000A08501528F8300508FBF00103C02100077 -:1063A00027BD0018AC83014C03E00008AC820178E3 -:1063B00027BDFFD8AFB20018AFB10014AFB00010C6 -:1063C000AFBF0020AFB3001C3C07800090E2010982 -:1063D000308600FF30B000FF000618C23204000211 -:1063E0003071000114800007305200FF3C09800822 -:1063F00035330080926800053105000810A0000CBC -:1064000030CA0010024020210E00068102202821FF -:10641000240200018FBF00208FB3001C8FB2001830 -:106420008FB100148FB0001003E0000827BD0028D2 -:106430001540003034E50A008CB900248CB80008FF -:1064400013380047000040213C0E800835D30080FF -:10645000926D0068240B000231AC00FF118B0080AC -:106460003C068000927F004C90C40109509F0004BC -:106470003213007C11000067000000003213007C22 -:106480001660005A0240202116200008320C00013C -:106490003C07800034EB0A008D6500248CE8010481 -:1064A00014A8FFDC00001021320C00011180000D47 -:1064B000024020213C1080008E0E010C8F8D006068 -:1064C00011CD0008000000000E00073F0220282127 -:1064D0008E0F010C3C18800837100080AE0F005062 -:1064E000024020210E000670022028210A00088C9C -:1064F000240200013C0708008CE7006424E6000148 -:106500003C010800AC2600641600000D00000000ED -:10651000022028210E00067002402021926F0068A0 -:10652000240D000231EE00FF11CD00220240202197 -:106530000E000840000000000A00088C2402000140 -:106540000E00004124040001926C0025020C582525 -:106550000E00004FA26B00250A0008CC0220282163 -:106560008E6300188CE401048CBF00240003160223 -:10657000149FFFB53045007F9269004C264400010E -:106580003093007F12650040312300FF1464FFAF99 -:106590003C0E8008264800013111007F310200FFC7 -:1065A0001225000B24080001004090210A000899E0 -:1065B00024110001240500040E0006332406000106 -:1065C0000E000840000000000A00088C24020001B0 -:1065D0002407FF800247282400A79026324200FFAC -:1065E000004090210A000899241100010E00073F85 -:1065F000022028213206003010C0FFA33210008292 -:10660000024020210E000681022028210A00088C69 -:10661000240200018E63001802402021022028215C -:10662000006610250E000862AE6200189264004CED -:1066300024050003240600010E000633308400FF09 -:106640000E00004124040001926A0025020A482538 -:106650000E00004FA26900250A00088C24020001E8 -:106660008E7800183C1980000240202103197825FB -:10667000022028210E000670AE6F00189264004CB4 -:106680000A000914240500043246008038CA00803C -:10669000146AFF6E3C0E80080A0008ED26480001CF -:1066A00027BDFFC0AFB000183C108000AFBF00385E -:1066B000AFB70034AFB60030AFB5002CAFB4002890 -:1066C000AFB30024AFB200200E0004BBAFB1001C7A -:1066D000920401089205010B308400FF0E0008733C -:1066E00030A500FF144000E58FBF00383C0980084A -:1066F00035280080A100006B3607098090E6000075 -:10670000240200503C17080026F73B4830C300FF26 -:106710003C13080026733B58106200033C108000B5 -:106720000000B82100009821241F001036110A0033 -:10673000361409808E1601048F8D00508E38002487 -:1067400036190A808E9200203C010800A03F3B9041 -:10675000972C002C8EF50000932B0018024D70230F -:1067600002D878233C010800AC2F3B6C3C010800A8 -:10677000AC2E3B703C010800AC2D3B94A78C005420 -:1067800002A0F809317200FF304A0002154000E80B -:106790003045000110A000C300000000928A0008EC -:1067A0003150000816000002241400030000A0214C -:1067B0003C06800034C4090034C30A008C6E0024F7 -:1067C00090850011908200129099001130B800FF5E -:1067D000305100FF0291F821001FB080332F00FFDD -:1067E00002D85821024FA82126AC0010017268215E -:1067F0003C1580003C010800AC2E3B983C01080091 -:10680000A42D3B883C010800A42C3B843C010800DB -:10681000A42B3B8636B609808F8700508F8900589D -:106820008ED20020240800060127302302472823A7 -:106830003C010800AC283B8C04C000B5000090214E -:1068400004A000B300C5802B120000B500000000BA -:106850003C010800AC263B708E7100000220F80954 -:1068600000000000304A0002154000740040802102 -:10687000304B0001556000118E7100043C0D080082 -:106880008DAD3B743C0EC0003C04800001AE602521 -:10689000AEAC0E008C980000330F000811E0FFFD35 -:1068A00000000000949F0E0824120001A79F0040E2 -:1068B0008C990E04AF9900388E7100040220F809FB -:1068C000000000000202802532020002144000B4E1 -:1068D000000000003C08080095083B7C3C110800C3 -:1068E00096313B883C09080095293B7E3C03080013 -:1068F0008C633B74011168213C1F08008FFF3B989B -:106900003C07080094E73B923C11800001A920213C -:106910008E38010C006828212499000200A77021FC -:1069200003E37821AF9800603C010800AC2F3B984E -:106930003C010800A42E3B803C010800A42D3B8AAA -:106940000E0001B43324FFFF8F8C0048004020214B -:106950003C010800A02C3B918E620008258B0001B1 -:10696000AF8B00480040F809000000008F85005000 -:10697000028030210E00050F004020210E00069FEE -:10698000004020218E6A000C0140F80900402021BF -:106990003C08080095083B8A3C09080095293B7E85 -:1069A0000109382124E600020E0001C830C4FFFFAF -:1069B0003C0408008C843B6C3C0308008C633B74F3 -:1069C000008328233C010800AC253B6C14A0000682 -:1069D000000000003C0A08008D4A3B8C3546004010 -:1069E0003C010800AC263B8C124000438F8C0044D5 -:1069F0008E2B0E108F920044AE4B00208E220E186C -:106A0000AE4200243C04080094843B800E0005FB49 -:106A1000000000008F9900508E7800103C010800A3 -:106A2000AC393B940300F809000000003C0F08005B -:106A30008DEF3B6C15E0FF798F87005097940054E1 -:106A40003C13800E321501000E00062AA674002C9D -:106A500016A00046320300105460004D8EE500047D -:106A60003207004054E0001D8EF000088EE4000C58 -:106A70000080F809000000008FBF00388FB7003495 -:106A80008FB600308FB5002C8FB400288FB3002450 -:106A90008FB200208FB1001C8FB0001803E00008F7 -:106AA00027BD0040920901098F88003C00093E0083 -:106AB00000E83025AE0600808E2300208E240024BE -:106AC000AFA30010AE030E148FA20010AE020E1082 -:106AD000AE040E1C0A00096EAE040E180200F8097E -:106AE000000000008EE4000C0080F80900000000A7 -:106AF0000A000A268FBF0038240E0001240D000171 -:106B0000A5800020A58E00220A000A08AD8D002471 -:106B10003C010800AC203B700A00099E8E71000009 -:106B20003C010800AC253B700A00099E8E710000F4 -:106B300092110109000028210E000670322400FF86 -:106B40008FBF00388FB700348FB600308FB5002C60 -:106B50008FB400288FB300248FB200208FB1001CA7 -:106B60008FB0001803E0000827BD00403C1F8000E4 -:106B700093F60109000028210E00073F32C400FFF0 -:106B8000320300105060FFB7320700408EE500046A -:106B900000A0F809000000000A000A2032070040A7 -:106BA0005240FFA7979400548EB60E148F93004462 -:106BB000AE7600208EB40E1CAE7400240A000A17B4 -:106BC000979400548F8200140004218003E0000891 -:106BD000008210213C07800834E200809043006965 -:106BE00000804021106000093C0401003C070800BF -:106BF0008CE73B948F83003000E32023048000085F -:106C00009389001C14E300030100202103E0000825 -:106C1000008010213C04010003E0000800801021E6 -:106C20001120000B006738233C0D800035AC098033 -:106C3000918B007C316A000211400020240900344D -:106C400000E9702B15C0FFF10100202100E9382375 -:106C50002403FFFC00A3C82400E3C02400F9782B20 -:106C600015E0FFEA0308202130C4000300041023CC -:106C700014C00014304900030000302100A978211D -:106C800001E6702100EE682B11A0FFE03C0401003A -:106C90002D3800010006C82B0105482103193824AE -:106CA00014E0FFDA2524FFFC2402FFFC00A21824D4 -:106CB0000068202103E00008008010210A000A97E4 -:106CC000240900303C0C80003586098090CB007C84 -:106CD000316A00041540FFE9240600040A000AA6F0 -:106CE000000030213C0308008C63005C8F82001898 -:106CF00027BDFFE8AFBF001410620005AFB0001061 -:106D0000000329C024A40280AF840014AF830018BC -:106D10003C10800036030A00946500320E000A78A9 -:106D200030A43FFF8E0401003C180080370F0003A1 -:106D30000082C8212402FF80032260243329007FBF -:106D4000000CF94003E94025332E00783C0D10007B -:106D5000010D502501CF5825AE0C002836080980BA -:106D6000AE0C080CAE0B082CAE0A0830910300697B -:106D70003C06800C0126382110600006AF870034E5 -:106D80008D09003C8D06006C0126382318E0007F39 -:106D9000000000003C0C8008358B00803C0A80001D -:106DA000A1600069355009808E0200383C068000E1 -:106DB00034C50A0090AD003C31A800201100001934 -:106DC000AF820030240E00013C19800037300A00E9 -:106DD000A38E001CAF8000248E0400248F85002425 -:106DE00024180008AF800020AF8000283C01080074 -:106DF000A4383B7E3C010800A4203B920E000A7C94 -:106E000000003021920F003C8FBF00148FB00010A3 -:106E1000000F7142AF82002C27BD001803E000086C -:106E200031C2000190B90032240F0001333800FF55 -:106E300000182182108F003F241F0002109F006263 -:106E400034C20AC03C03800034640A008C990024D8 -:106E50001720001D3466090090830030241F0005B0 -:106E60003062003F105F004C240500018F86002037 -:106E7000A385001CAF860028AF8600243C19800043 -:106E800037300A008E0400248F850024241800085F -:106E90003C010800A4383B7E3C010800A4203B9242 -:106EA0000E000A7C00000000920F003C8FBF00140F -:106EB0008FB00010000F7142AF82002C27BD001868 -:106EC00003E0000831C200018C8800088C8D00248A -:106ED0008CCB00643C19800037300A00AF8B002453 -:106EE000A380001C8E0400248F8600208F85002440 -:106EF000010D602324180008AF8C00283C01080015 -:106F0000A4383B7E3C010800A4203B920E000A7C82 -:106F100000000000920F003C8FBF00148FB00010E3 -:106F2000000F7142AF82002C27BD001803E000085B -:106F300031C2000190A7003030E3003F50640028C8 -:106F400034C50AC08CAA00241540002234C80900A8 -:106F50008CAB00483C0C7FFF3585FFFF016510249A -:106F60003C188000AF820020370509008F8E00207A -:106F70008CAF006001CF682B15A0000201C020215A -:106F80008CA400600A000B18AF8400208D02006CF6 -:106F90000A000AF33C0680008C8900488F86002096 -:106FA0003C0A7FFF3550FFFF013038243C04800845 -:106FB00024050001AF870028AC80006CA385001C6D -:106FC0000A000B26AF8600248C4400140A000B181C -:106FD000AF8400208D0200680A000B603C1880001E -:106FE00034C409808C8600708CB0001400D0482B0B -:106FF00011200004000000008C8200700A000B6069 -:107000003C1880008CA200140A000B603C18800021 -:107010008F85002427BDFFE0AFBF0018AFB100147B -:1070200014A00008AFB000103C04800034870A00B0 -:1070300090E600302402000530C3003F106200BE1D -:10704000348409008F91002000A080213C0480003E -:10705000348E0A008DCD00043C0608008CC63B70BF -:1070600031A73FFF00E6602B5580000100E0302192 -:10707000938F001C11E0007600D0102B349909800A -:107080009338007C3304000210800077240300341E -:1070900000C3F82B17E000DD00C3302300D0102B15 -:1070A0003C010800A4233B7C1440006D0200182121 -:1070B0003C0408008C843B6C0064282B54A0000125 -:1070C000006020213C05800034A90A009128003C82 -:1070D0003C010800AC243B74310300201460000222 -:1070E000000048218CA90E188F88002C0128502BF5 -:1070F0001140005F000000003C0508008CA53B74B7 -:1071000000A96021010C582B1160005C00B0682BB5 -:107110000109382300E028213C010800AC273B741A -:10712000120000032403FFFC10B00093322B000375 -:1071300000A310243C010800A4203B923C0108005D -:10714000AC223B74004028218F84002412040006E6 -:107150003C0A80088D4B006C02002021AF9100207A -:1071600025700001AD50006C8F8C002800858823AD -:10717000AF91002401852023AF8400281220000253 -:1071800024070018240700103C0F800835E6008013 -:1071900090CE00683C010800A0273B902407000126 -:1071A00031CD00FF11A7004A000000001480001834 -:1071B000000028213C0C800091850109359109804F -:1071C0008E2B001830A500FF24A30001000B8602BF -:1071D0003206007F306A007F114600852407FF8059 -:1071E0003C04800834890080A123004C3C0808003E -:1071F0008D083B8C240F00023C010800A02F3BD1DE -:10720000350E00083C010800AC2E3B8C2405001014 -:107210003C028000345F0A0093F9003C33380020C0 -:107220001300000500A02021240300013C010800F8 -:10723000AC233B7434A400018FBF00188FB100143D -:107240008FB000100080102103E0000827BD00204F -:107250003C010800A4203B7C1040FF95020018214F -:107260000A000BB300C018210A000BAB2403003046 -:107270003C0508008CA53B7400B0682B11A0FFA84A -:10728000000000003C04080094843B7C00857821C9 -:1072900001E7702B11C000242CA300043C1F6000E8 -:1072A0008FF954043338003F1300001F0000000022 -:1072B0003C0208008C4200A41040FFDF240400427E -:1072C00014A000198FBF00180A000C16000000005F -:1072D0001528FFB6000000008CC300183C19800080 -:1072E000241F000200791025ACC2001837380A00AC -:1072F000A0DF00689309003C2404000400A01021D2 -:10730000312800203C010800A0243BD111000002DC -:1073100024050010240200013C010800AC223B6C53 -:107320000A000C0C3C0280001060FF7D2404004227 -:107330000A000C168FBF00188F8800288C89006007 -:107340000109282B14A00002010088218C91006003 -:107350003C0B80008D640E18240A000102202821B5 -:1073600002203021A38A001C0E000A7C022080210A -:107370000A000B9AAF82002C000B5023122000074A -:10738000314400033C0E800035CD098091A7007C7C -:1073900030EC000415800019248F00043C01080023 -:1073A000A4243B923C19080097393B920325C02145 -:1073B00000D8202B1080FF658F8400242CA60005A8 -:1073C00014C0FF9D2404004230BF000317E00002F8 -:1073D00000BF182324A3FFFC3C010800AC233B742E -:1073E0003C010800A4203B920A000BD90060282130 -:1073F00000A768240A000BFF01A718263C0108001B -:10740000A42F3B920A000C70000000003C01080011 -:10741000AC203B740A000C15240400428F83002822 -:107420003C0B8000356A0A00146000060000102141 -:10743000914600302405000530C400FF108500038C -:107440000000000003E0000800000000914900482F -:10745000312800FF000839C214E0FFFA3C0480081C -:107460003C06080094C63B7C3C0308008C633B94BC -:107470003C0508008CA53B743C18080097183B920B -:107480000066C8218C8E00040325782101F868214C -:1074900001AE60231980001D000000009158004CCF -:1074A0008F8D0034956E0E10330F00FF8DA90004F0 -:1074B00001CF30238DAA000030CFFFFF000F610005 -:1074C000012C2821000038210147202100AC182B75 -:1074D0000083C821ADA50004ADB9000091B8000A31 -:1074E00001F87021A1AE000A956C0E128F8A00344B -:1074F000A54C00089549003825280001A54800380A -:107500009147000D34EB0008A14B000D03E000088B -:107510000000000027BDFFD8AFB00018938F001CFB -:107520008FB000143C087FFF8F8700243C0C800044 -:107530003518FFFFAFBF0020AFB1001C35990A001E -:1075400002181824932A003C000F5FC03C02BFFFC2 -:107550002CF000013449FFFF006BF8253C080800BF -:107560008D083B948F9900303C18080097183B8A8F -:1075700003E9582400107F803C07EFFF3C05F0FF33 -:10758000016F18253C1180003149002034E2FFFFD3 -:1075900034ADFFFF362E098027A500102406000217 -:1075A00001194023270A000200621824008080216C -:1075B00015200002000058218D8B0E1CA7AA001276 -:1075C0000500003A2407000030EF00FF000F3F00E5 -:1075D000006740253C028008AFA80014344B0080AF -:1075E000916A00683C0F080091EF3B913C09DFFF76 -:1075F000353FFFFF000A602B3C02080094423B84A9 -:10760000A3AF0011011FC024000CCF40031918259F -:107610008FA70010AFA300143C1F080093FF3B93FB -:10762000A7A200168FA8001400ED48243C0B01000F -:107630003C0A0FFF012BC82533F80003354CFFFF30 -:10764000010D78243C027000032C382400181E0021 -:1076500000E2482501E35825AFAB0014AFA90010A4 -:1076600091DF007CA3BF00150E0000630000000046 -:10767000362D0A0091A6003C30C400201080000680 -:10768000260200083C11080096313B80262EFFFFA1 -:107690003C010800A42E3B808FBF00208FB1001C4E -:1076A0008FB0001803E0000827BD00288F8A002C47 -:1076B000016A602B5580FFC4240700010A000CFA00 -:1076C00030EF00FF9383001C3C02800027BDFFD8F1 -:1076D00034480A0000805021AFBF002034460AC061 -:1076E000010028211060000E344409809107003009 -:1076F000240B00058F89002030EC003F118B000B1C -:1077000000003821AFA900103C0B80088D69006C87 -:10771000AFAA00180E00012BAFA90014A380001C13 -:107720008FBF002003E0000827BD00288D1F004800 -:107730003C1808008F183B748F9900283C027FFF8B -:107740008D0800443443FFFFAFA900103C0B8008B4 -:107750008D69006C03E370240319782101CF68233D -:1077600001A83821AFAA00180E00012BAFA9001400 -:107770000A000D4FA380001C3C05800034A60A00BF -:1077800090C7003C3C06080094C63B923C020800AF -:107790008C423B8C30E30020000624001060001E69 -:1077A000004438253C0880083505008090A3006817 -:1077B00000003021240800010000202124030001E2 -:1077C0003C0580008CAC01780580FFFE00000000C5 -:1077D000ACA80148A4A40144A4A301463C030800AA -:1077E0008C633B943C188008370F0080ACA3014C9D -:1077F0003C19080093393B913C0D1000A0B901528F -:10780000ACA70154A4A6015891EE004CA0AE016DA6 -:1078100003E00008ACAD01788CA80E1C3C0B0800FE -:107820008D6B3B7494AA0E1694A90E140166302138 -:107830003143FFFF0A000D773124FFFF3C04800035 -:1078400034830A009065003C30A200201040001CE8 -:10785000000000000000302100002021000018215D -:107860003C0580008CA901780520FFFE0000000087 -:10787000ACA601483C0E08008DCE3B94240DFF9130 -:10788000240C00403C0B8008A4A30144356A00800E -:10789000A4A40146ACAE014CA0AD0152ACAC015465 -:1078A000A4A0015890A301099144004C90A601099D -:1078B0003C041000A0A6016D03E00008ACA4017810 -:1078C0008C860E1894880E1294870E103104FFFFD8 -:1078D0000A000D9F30E3FFFF3C04800034830A0060 -:1078E0009065003C30A200201040002627BDFFF824 -:1078F0002409000100003821240800013C06800012 -:107900008CC401780480FFFE0000000090CA0109C9 -:107910003C04080090843BD13C1880FFA3AA0003DC -:107920008FA300003085007F370FFFFF0066102512 -:10793000AFA2000090D9010AA3A0000200056E00CA -:10794000A3B900018FAE0000240A300027BD000853 -:1079500001CF6024018D5825ACCB014CACCA015439 -:10796000A4C00158ACC90148A4C701442409FF8040 -:10797000A4C801463C081000A0C9015203E0000859 -:10798000ACC801788C890E1894870E1294860E105C -:1079900030E8FFFF0A000DC630C7FFFF27BDFFE834 -:1079A000AFB000103C108000AFBF001436180A00C2 -:1079B000970F00320E000A7831E43FFF8E0E01006F -:1079C000240DFF803C04200001C25821016D602479 -:1079D000000C4940316A007F012A40250104382506 -:1079E0003C048008AE0708303486008090C50068EB -:1079F0002403000230A200FF104300048F9F0020E8 -:107A00008F990024AC9F0068AC9900648FBF00146C -:107A10008FB0001003E0000827BD00183C0A0800E2 -:107A2000254A36583C090800252936F43C08080048 -:107A300025082B003C07080024E737B83C0608005F -:107A400024C634E03C05080024A532383C04080074 -:107A500024842E2C3C030800246335943C02080047 -:107A6000244233303C010800AC2A3B503C01080062 -:107A7000AC293B4C3C010800AC283B483C010800C9 -:107A8000AC273B543C010800AC263B643C01080099 -:107A9000AC253B5C3C010800AC243B583C01080091 -:107AA000AC233B683C010800AC223B6003E00008CB -:047AB00000000000D2 -:0C7AB400800009408000090080080100EB -:107AC0008008008080080000800E00008008008090 -:107AD0008008000080000A8080000A008000098081 -:047AE0008000090019 -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex new file mode 100644 index 0000000000000000000000000000000000000000..7f39b4a7f331ee6ad2a8b3ebda706dfc2ba711ba --- /dev/null +++ b/firmware/bnx2/bnx2-mips-09-6.0.17.fw.ihex @@ -0,0 +1,6488 @@ +:10000000080001180800000000005594000000C816 +:1000100000000000000000000000000008005594EF +:10002000000000380000565C080000A00800000036 +:100030000000574400005694080059200000008436 +:100040000000ADD808005744000001C00000AE5CBD +:100050000800321008000000000090900000B01C62 +:100060000000000000000000000000000800909068 +:100070000000033C000140AC0800049008000400AC +:10008000000012FC000143E8000000000000000036 +:1000900000000000080016FC00000004000156E407 +:1000A000080000A80800000000003D28000156E8F4 +:1000B00000000000000000000000000008003D28D3 +:0800C000000000300001941063 +:0800C8000A00004600000000E0 +:1000D000000000000000000D636F6D362E302E31E1 +:1000E00037000000060011020000000000000003BD +:1000F000000000C800000032000000030000000003 +:1001000000000000000000000000000000000000EF +:1001100000000010000001360000EA600000000549 +:1001200000000000000000000000000000000008C7 +:1001300000000000000000000000000000000000BF +:1001400000000000000000000000000000000000AF +:10015000000000000000000000000000000000009F +:10016000000000020000000000000000000000008D +:10017000000000000000000000000000000000007F +:10018000000000000000000000000010000000005F +:10019000000000000000000000000000000000005F +:1001A000000000000000000000000000000000004F +:1001B000000000000000000000000000000000003F +:1001C000000000000000000000000000000000002F +:1001D000000000000000000000000000000000001F +:1001E0000000000010000003000000000000000DEF +:1001F0000000000D3C020800244256083C030800A1 +:1002000024635754AC4000000043202B1480FFFDB2 +:10021000244200043C1D080037BD9FFC03A0F021D0 +:100220003C100800261001183C1C0800279C5608AA +:100230000E000256000000000000000D27BDFFB4B4 +:10024000AFA10000AFA20004AFA30008AFA4000C50 +:10025000AFA50010AFA60014AFA70018AFA8001CF0 +:10026000AFA90020AFAA0024AFAB0028AFAC002C90 +:10027000AFAD0030AFAE0034AFAF0038AFB8003C28 +:10028000AFB90040AFBC0044AFBF00480E001544FA +:10029000000000008FBF00488FBC00448FB90040B1 +:1002A0008FB8003C8FAF00388FAE00348FAD003078 +:1002B0008FAC002C8FAB00288FAA00248FA90020C0 +:1002C0008FA8001C8FA700188FA600148FA5001000 +:1002D0008FA4000C8FA300088FA200048FA1000040 +:1002E00027BD004C3C1B60108F7A5030377B502864 +:1002F00003400008AF7A00008F82002427BDFFE092 +:10030000AFB00010AFBF0018AFB100148C42000CAA +:100310003C1080008E110100104000348FBF001887 +:100320000E000D84000000008F85002024047FFF54 +:100330000091202BACB100008E030104960201084D +:1003400000031C003042FFFF00621825ACA300042C +:100350009202010A96030114304200FF3063FFFF4E +:100360000002140000431025ACA200089603010C03 +:100370009602010E00031C003042FFFF00621825A8 +:10038000ACA3000C960301109602011200031C009E +:100390003042FFFF00621825ACA300108E02011846 +:1003A000ACA200148E02011CACA20018148000083C +:1003B0008F820024978200003C0420050044182509 +:1003C00024420001ACA3001C0A0000C6A782000062 +:1003D0003C0340189442001E00431025ACA2001CB0 +:1003E0000E000DB8240400018FBF00188FB1001457 +:1003F0008FB000100000102103E0000827BD00208E +:100400003C0780008CE202B834E50100044100089A +:10041000240300013C0208008C42006024420001D9 +:100420003C010800AC22006003E0000800601021DD +:100430003C0208008C42005C8CA4002094A30016AF +:100440008CA6000494A5000E24420001ACE40280B6 +:100450002463FFFC3C010800AC22005C3C0210005D +:10046000A4E30284A4E5028600001821ACE6028819 +:10047000ACE202B803E000080060102127BDFFE0F5 +:100480003C028000AFB0001034420100AFBF001C3E +:10049000AFB20018AFB100148C43000094450008BF +:1004A0002462FE002C42038110400003000381C23D +:1004B0000A00010226100004240201001462000553 +:1004C0003C1180003C02800890420004305000FF44 +:1004D0003C11800036320100964300143202000FB6 +:1004E00000021500004310253C0308008C63004403 +:1004F00030A40004AE220080246300013C01080007 +:10050000AC2300441080000730A200028FBF001C03 +:100510008FB200188FB100148FB000100A0000CE07 +:1005200027BD00201040002D0000182130A20080BF +:1005300010400005362200708E44001C0E000C672F +:10054000240500A0362200708C4400008F82000C2D +:10055000008210232C43012C10600004AF82001095 +:10056000240300010A000145AF84000C8E42000400 +:100570003C036020AF84000CAC6200143C02080015 +:100580008C42005850400015000018218C62000475 +:10059000240301FE304203FF144300100000182121 +:1005A0002E020004104000032E0200080A00014041 +:1005B0000000802114400003000000000A000140F8 +:1005C0002610FFF90000000D2402000202021004B0 +:1005D0003C036000AC626914000018218FBF001C4E +:1005E0008FB200188FB100148FB00010006010217E +:1005F00003E0000827BD00203C0480008C8301003C +:1006000024020100506200033C0280080000000D3B +:100610003C02800890430004000010213063000F6A +:1006200000031D0003E00008AC8300800004188074 +:100630002782FF9C00621821000410C00044102390 +:100640008C640000000210C03C030800246356E4E0 +:10065000004310213C038000AC64009003E00008DC +:10066000AF8200243C0208008C42011410400019A3 +:100670003084400030A2007F000231C03C02020002 +:100680001080001400A218253C026020AC43001426 +:100690003C0408008C8456B83C0308008C630110AD +:1006A0003C02800024050900AC4500200086202182 +:1006B000246300013C028008AC4400643C01080053 +:1006C000AC2301103C010800AC2456B803E000083C +:1006D000000000003C02602003E00008AC4500146C +:1006E00003E000080000102103E0000800001021D2 +:1006F00030A2000810400008240201003C0208005B +:100700008C42010C244200013C010800AC22010C87 +:1007100003E0000800000000148200080000000050 +:100720003C0208008C4200FC244200013C0108000D +:10073000AC2200FC0A0001A330A200203C02080009 +:100740008C420084244200013C010800AC22008459 +:1007500030A200201040000830A200103C02080027 +:100760008C420108244200013C010800AC2201082F +:1007700003E0000800000000104000080000000036 +:100780003C0208008C420104244200013C010800A4 +:10079000AC22010403E00008000000003C02080055 +:1007A0008C420100244200013C010800AC220100FF +:1007B00003E000080000000027BDFFE0AFB1001417 +:1007C0003C118000AFB20018AFBF001CAFB00010EA +:1007D0003632010096500008320200041040000733 +:1007E000320300028FBF001C8FB200188FB10014BB +:1007F0008FB000100A0000CE27BD00201060000B53 +:10080000020028218E2401000E00018A0000000051 +:100810003202008010400003240500A10E000C6786 +:100820008E44001C0A0001E3240200018E2301040F +:100830008F82000810430006020028218E24010048 +:100840000E00018A000000008E220104AF82000821 +:10085000000010218FBF001C8FB200188FB1001450 +:100860008FB0001003E0000827BD00202C82000498 +:1008700014400002000018212483FFFD240200021E +:10088000006210043C03600003E00008AC626914DD +:1008900027BDFFE0AFBF001CAFB20018AFB100141E +:1008A000AFB000103C048000948201083043700017 +:1008B000240220001062000A2862200154400052E5 +:1008C0008FBF001C24024000106200482402600018 +:1008D0001062004A8FBF001C0A0002518FB200183C +:1008E00034820100904300098C5000189451000C90 +:1008F000240200091062001C0000902128620009F7 +:10090000144000218F8200242402000A5062001249 +:10091000323100FF2402000B1062000F00000000C3 +:100920002402000C146200188F8200243C0208008C +:100930008C4256B824030900AC83002000501021DB +:100940003C038008AC6200643C010800AC2256B84D +:100950000A0002508FBF001C0E0001E900102602A1 +:100960000A0002308F8200240E0001E900102602E6 +:100970003C0380089462001A8C72000C3042FFFF26 +:10098000020280258F8200248C42000C5040001E01 +:100990008FBF001C0E000D84000000003C02800090 +:1009A00034420100944300088F82002400031C009D +:1009B0009444001E8F82002000641825AC50000073 +:1009C00024040001AC510004AC520008AC40000CFF +:1009D000AC400010AC400014AC4000180E000DB844 +:1009E000AC43001C0A0002508FBF001C0E000440E4 +:1009F000000000000A0002508FBF001C0E000C9F78 +:100A0000000000008FBF001C8FB200188FB10014CF +:100A10008FB000100000102103E0000827BD002067 +:100A200027BDFFD8AFB400203C036010AFBF002447 +:100A3000AFB3001CAFB20018AFB10014AFB00010DC +:100A40008C6450002402FF7F3C1408002694563822 +:100A5000008220243484380CAC6450003C028000B6 +:100A6000240300370E0014B0AC4300083C07080014 +:100A700024E70618028010212404001D2484FFFFAF +:100A8000AC4700000481FFFD244200043C02080042 +:100A9000244207C83C010800AC2256403C02080032 +:100AA000244202303C030800246306203C04080072 +:100AB000248403B43C05080024A506F03C06080085 +:100AC00024C62C9C3C010800AC2256803C02080045 +:100AD000244205303C010800AC2756843C01080044 +:100AE000AC2656943C010800AC23569C3C010800FF +:100AF000AC2456A03C010800AC2556A43C010800DB +:100B0000AC2256A83C010800AC23563C3C0108002E +:100B1000AC2456443C010800AC2056603C0108005F +:100B2000AC2556643C010800AC2056703C0108001E +:100B3000AC27567C3C010800AC2656903C010800CE +:100B4000AC2356980E00056E00000000AF80000C2C +:100B50003C0280008C5300008F8300043C0208009C +:100B60008C420020106200213262000700008821C0 +:100B70002792FF9C3C100800261056E43C02080017 +:100B80008C42002024050001022518040043202483 +:100B90008F820004004310245044000C26310001D1 +:100BA00010800008AF9000248E4300003C028000BB +:100BB000AC4300900E000D4BAE05000C0A0002C1C4 +:100BC00026310001AE00000C263100012E22000269 +:100BD000261000381440FFE9265200043C020800A9 +:100BE0008C420020AF820004326200071040FFD91F +:100BF0003C028000326200011040002D326200028F +:100C00003C0580008CA2010000002021ACA2002045 +:100C10008CA301042C42078110400008ACA300A85B +:100C200094A2010824032000304270001443000302 +:100C30003C02800890420005304400FF0E0001593C +:100C4000000000003C0280009042010B304300FF96 +:100C50002C62001E54400004000310800E00018628 +:100C60000A0002EC00000000005410218C42000039 +:100C70000040F80900000000104000043C02800021 +:100C80008C4301043C026020AC4300143C02080089 +:100C90008C4200343C0440003C03800024420001AC +:100CA000AC6401383C010800AC220034326200021E +:100CB00010400010326200043C1080008E0201409F +:100CC000000020210E000159AE0200200E00038317 +:100CD000000000003C024000AE0201783C02080027 +:100CE0008C420038244200013C010800AC2200384C +:100CF000326200041040FF973C0280003C108000EC +:100D00008E020180000020210E000159AE02002059 +:100D10008E03018024020F00546200073C02800809 +:100D20008E0201883C0300E03042FFFF00431025A3 +:100D30000A000328AE020080344200809042000086 +:100D400024030050304200FF14430007000000005D +:100D50000E000362000000001440000300000000C9 +:100D60000E000971000000003C0208008C42003CAB +:100D70003C0440003C03800024420001AC6401B804 +:100D80003C010800AC22003C0A0002A33C028000A7 +:100D90003C02900034420001008220253C02800089 +:100DA000AC4400203C0380008C6200200440FFFE25 +:100DB0000000000003E00008000000003C0280008A +:100DC000344300010083202503E00008AC440020E8 +:100DD00027BDFFE0AFB10014AFB000100080882144 +:100DE000AFBF00180E00033230B000FF8F83FF94B6 +:100DF000022020219062002502028025A07000259B +:100E00008C7000183C0280000E00033D020280241A +:100E10001600000B8FBF00183C0480008C8201F884 +:100E20000440FFFE348201C024030002AC510000E4 +:100E3000A04300043C021000AC8201F88FBF0018F0 +:100E40008FB100148FB0001003E0000827BD002010 +:100E500027BDFFE83C028000AFBF00103442018094 +:100E6000944300048C4400083063020010600005C5 +:100E7000000028210E00100C000000000A0003787A +:100E8000240500013C02FF000480000700821824B2 +:100E90003C02040014620004240500018F82FF94C8 +:100EA00090420008240500018FBF001000A010210F +:100EB00003E0000827BD00188F82FF982405000179 +:100EC000A040001A3C028000344201400A00034264 +:100ED0008C4400008F85FF9427BDFFE0AFBF001C4E +:100EE000AFB20018AFB10014AFB0001090A2000074 +:100EF000304400FF38830020388200300003182B74 +:100F00000002102B0062182410600003240200501D +:100F1000148200A88FBF001C90A20005304200017F +:100F2000104000A48FBF001C3C02800034420140EE +:100F3000904200082443FFFF2C6200051040009EF1 +:100F40008FB20018000310803C030800246355ACE6 +:100F5000004310218C420000004000080000000007 +:100F60003C028000345101400E0003328E24000008 +:100F70008F92FF948E2200048E50000C1602000205 +:100F800024020001AE42000C0E00033D8E2400003E +:100F90008E220004145000068FBF001C8FB2001870 +:100FA0008FB100148FB000100A000F7827BD002009 +:100FB0008E42000C0A000419000000003C0480006E +:100FC0003482014094A300108C4200043063FFFF80 +:100FD0001443001C0000000024020001A4A2001021 +:100FE0008C8202380441000F3C0380003C02003F29 +:100FF0003448F0003C0760003C06FFC08CE22BBC8C +:1010000000461824004810240002130200031D8229 +:10101000106200583C0280008C8202380440FFF7C6 +:101020003C038000346201408C44000034620200C2 +:10103000AC4400003C021000AC6202380A00043BE1 +:101040008FBF001C94A200100A00041900000000C9 +:10105000240200201482000F3C0280003C03800028 +:1010600094A20012346301408C6300043042FFFFFD +:10107000146200050000000024020001A4A2001276 +:101080000A0004028FBF001C94A200120A00041977 +:1010900000000000345101400E0003328E24000095 +:1010A0008F92FF948E230004964200123050FFFF6F +:1010B0001603000224020001A64200120E00033DA6 +:1010C0008E2400008E220004160200068FBF001C32 +:1010D0008FB200188FB100148FB000100A00037C8B +:1010E00027BD0020964200120A00041900000000EB +:1010F0003C03800094A20014346301408C6300041C +:101100003042FFFF14620008240200018FBF001C60 +:101110008FB200188FB100148FB00010A4A2001479 +:101120000A00146327BD002094A20014144000217B +:101130008FBF001C0A000435000000003C03800043 +:1011400094A20016346301408C6300043042FFFF18 +:101150001462000D240200018FBF001C8FB2001822 +:101160008FB100148FB00010A4A200160A000B1457 +:1011700027BD00209442007824420004A4A200105D +:101180000A00043B8FBF001C94A200162403000138 +:101190003042FFFF144300078FBF001C3C020800D1 +:1011A0008C420070244200013C010800AC22007017 +:1011B0008FBF001C8FB200188FB100148FB00010C9 +:1011C00003E0000827BD002027BDFFD8AFB20018FC +:1011D0008F92FF94AFB10014AFBF0020AFB3001CDB +:1011E000AFB000103C028000345101008C5001006F +:1011F0009242000092230009304400FF2402001FA5 +:10120000106200AB28620020104000192402003850 +:101210002862000A1040000D2402000B286200081A +:101220001040002E8F820024046001042862000216 +:101230001440002A8F820024240200061062002637 +:101240008FBF00200A00055F8FB3001C1062006092 +:101250002862000B144000FA8FBF00202402000E09 +:10126000106200788F8200240A00055F8FB3001C93 +:10127000106200D2286200391040000A2402008067 +:1012800024020036106200E528620037104000C3D7 +:1012900024020035106200D98FBF00200A00055FCC +:1012A0008FB3001C1062002D2862008110400006E0 +:1012B000240200C824020039106200C98FBF002038 +:1012C0000A00055F8FB3001C106200A28FBF0020D0 +:1012D0000A00055F8FB3001C8F8200248C42000C33 +:1012E000104000D78FBF00200E000D8400000000CA +:1012F0003C038000346301008C6200008F85002075 +:10130000946700089466000CACA200008C64000492 +:101310008F82002400063400ACA400049448001E10 +:101320008C62001800073C0000E83825ACA20008D9 +:101330008C62001C24040001ACA2000C9062000A24 +:1013400000C23025ACA60010ACA00014ACA0001860 +:10135000ACA7001C0A00051D8FBF00208F8200244F +:101360008C42000C104000B68FBF00200E000D8490 +:10137000000000008F820024962400089625000CAF +:101380009443001E000422029626000E8F82002045 +:10139000000426000083202500052C003C0300806B +:1013A00000A6282500832025AC400000AC400004A6 +:1013B000AC400008AC40000CAC450010AC40001440 +:1013C000AC400018AC44001C0A00051C24040001B9 +:1013D0009622000C14400018000000009242000504 +:1013E0003042001014400014000000000E000332D0 +:1013F0000200202192420005020020213442001008 +:101400000E00033DA242000592420000240300208A +:10141000304200FF10430089020020218FBF0020CE +:101420008FB3001C8FB200188FB100148FB0001062 +:101430000A00107527BD00280000000D0A00055E97 +:101440008FBF00208C42000C1040007D8FBF002019 +:101450000E000D84000000008E2200048F84002006 +:101460009623000CAC8200003C0280089445002CBE +:101470008F82002400031C0030A5FFFF9446001E4D +:101480003C02400E0065182500C23025AC830004E4 +:10149000AC800008AC80000CAC800010AC80001464 +:1014A000AC800018AC86001C0A00051C2404000156 +:1014B0000E000332020020218F93FF9802002021AA +:1014C0000E00033DA660000C020020210E00034226 +:1014D000240500018F8200248C42000C104000582B +:1014E0008FBF00200E000D84000000009622000C2B +:1014F0008F83002000021400AC700000AC62000476 +:10150000AC6000088E4400388F820024AC64000C6C +:101510008E46003C9445001E3C02401FAC66001005 +:1015200000A228258E62000424040001AC6200148D +:10153000AC600018AC65001C8FBF00208FB3001C8E +:101540008FB200188FB100148FB000100A000DB8D0 +:1015500027BD0028240200201082003A8FB3001C0F +:101560000E000F5E00000000104000358FBF00200D +:101570003C0480008C8201F80440FFFE348201C0EC +:1015800024030002AC500000A04300043C02100001 +:10159000AC8201F80A00055E8FBF00200200202106 +:1015A0008FBF00208FB3001C8FB200188FB10014C2 +:1015B0008FB000100A000EA727BD00289625000C4A +:1015C000020020218FBF00208FB3001C8FB20018B3 +:1015D0008FB100148FB000100A000ECC27BD002878 +:1015E000020020218FB3001C8FB200188FB10014AD +:1015F0008FB000100A000EF727BD00289225000DBD +:10160000020020218FB3001C8FB200188FB100148C +:101610008FB000100A000F4827BD002802002021CB +:101620008FBF00208FB3001C8FB200188FB1001441 +:101630008FB000100A000F1F27BD00288FBF0020A9 +:101640008FB3001C8FB200188FB100148FB0001040 +:1016500003E0000827BD00283C0580008CA202782A +:101660000440FFFE34A2024024030002AC44000008 +:10167000A04300043C02100003E00008ACA2027882 +:10168000A380001803E00008A38000193C03800039 +:101690008C6202780440FFFE8F82001CAC62024024 +:1016A00024020002A06202443C02100003E0000891 +:1016B000AC6202783C02600003E000088C425404F3 +:1016C0009083003024020005008040213063003FF9 +:1016D0000000482114620005000050219082004C57 +:1016E0009483004E304900FF306AFFFFAD00000CCC +:1016F000AD000010AD000024950200148D05001C03 +:101700008D0400183042FFFF004910230002110031 +:10171000000237C3004038210086202300A2102B8E +:101720000082202300A72823AD05001CAD0400186B +:10173000A5090014A5090020A50A001603E0000869 +:10174000A50A002203E000080000000027BDFFD822 +:10175000AFB200183C128008AFB40020AFB3001C39 +:10176000AFB10014AFBF0024AFB00010365101007C +:101770003C0260008C4254049222000C3C1408008D +:10178000929400F7304300FF2402000110620032FF +:101790000080982124020002146200353650008037 +:1017A0000E00143D000000009202004C2403FF8054 +:1017B0003C0480003042007F000211C024420240FD +:1017C0000262102100431824AC8300949245000863 +:1017D0009204004C3042007F3C03800614850007D1 +:1017E000004380212402FFFFA22200112402FFFFF8 +:1017F000A62200120A0005D22402FFFF9602002052 +:10180000A222001196020022A62200128E020024BB +:101810003C048008AE2200143485008090A2004C65 +:1018200034830100A06200108CA2003CAC6200185E +:101830008C820068AC6200F48C820064AC6200F0C0 +:101840008C82006CAC6200F824020001A0A2006847 +:101850000A0005EE3C0480080E001456000000004B +:1018600036420080A04000680A0005EE3C04800873 +:10187000A2000068A20000690A0006293C02800854 +:10188000348300808C62003834850100AC62006CC7 +:1018900024020001A062006990A200D59083000894 +:1018A000305100FF3072007F12320019001111C058 +:1018B00024420240026210212403FF8000431824C6 +:1018C0003C048000AC8300943042007F3C038006DF +:1018D000004380218E02000C1040000D02002021E8 +:1018E0000E00057E0000000026220001305100FF9E +:1018F0009203003C023410260002102B0002102339 +:101900003063007F022288240A0005F8A203003C0D +:101910003C088008350401008C8200E03507008017 +:10192000ACE2003C8C8200E0AD02000090E5004C8F +:10193000908600D590E3004C908400D52402FF806F +:1019400000A228243063007F308400FF00A62825F1 +:101950000064182A1060000230A500FF38A500803E +:10196000A0E5004CA10500093C0280089043000E50 +:10197000344400803C058000A043000A8C8300189A +:101980003C027FFF3442FFFF00621824AC83001842 +:101990008CA201F80440FFFE00000000ACB301C0BF +:1019A0008FBF00248FB400208FB3001C8FB20018AB +:1019B0008FB100148FB0001024020002A0A201C455 +:1019C00027BD00283C02100003E00008ACA201F88B +:1019D00090A2000024420001A0A200003C030800E5 +:1019E0008C6300F4304200FF144300020080302179 +:1019F000A0A0000090A200008F84001C000211C073 +:101A00002442024024830040008220212402FF80DF +:101A1000008220243063007F3C02800A006218218B +:101A20003C028000AC44002403E00008ACC300008A +:101A300094820006908300058C85000C8C86001033 +:101A40008C8700188C88001C8C8400203C010800C6 +:101A5000A42256C63C010800A02356C53C0108003C +:101A6000AC2556CC3C010800AC2656D03C01080001 +:101A7000AC2756D83C010800AC2856DC3C010800D5 +:101A8000AC2456E003E00008000000003C0280089F +:101A9000344201008C4400343C038000346504006F +:101AA000AC6400388C420038AF850028AC62003C42 +:101AB0003C020005AC6200300000000000000000A5 +:101AC00003E00008000000003C020006308400FF34 +:101AD000008220253C028000AC4400300000000061 +:101AE00000000000000000003C0380008C62000049 +:101AF000304200101040FFFD3462040003E0000893 +:101B0000AF82002894C200003C080800950800CA73 +:101B100030E7FFFF0080482101021021A4C200002D +:101B200094C200003042FFFF00E2102B544000013D +:101B3000A4C7000094A200003C0308008C6300CC02 +:101B400024420001A4A2000094A200003042FFFF42 +:101B5000144300073C0280080107102BA4A00000DA +:101B60005440000101003821A4C700003C02800855 +:101B7000344601008CC3002894A200003C0480007D +:101B80003042FFFE000210C000621021AC82003C17 +:101B90008C82003C006218231860000400000000E2 +:101BA0008CC200240A0006BA244200018CC2002420 +:101BB000AC8200383C020050344200103C038000EC +:101BC000AC620030000000000000000000000000D7 +:101BD0008C620000304200201040FFFD0000000039 +:101BE00094A200003C04800030420001000210C0BA +:101BF000004410218C430400AD2300008C420404F7 +:101C0000AD2200043C02002003E00008AC8200305A +:101C100027BDFFE0AFB20018AFB10014AFB00010A5 +:101C2000AFBF001C94C2000000C080213C1208001D +:101C3000965200C624420001A6020000960300004E +:101C400094E2000000E03021144300058FB1003021 +:101C50000E00068F024038210A0006F10000000045 +:101C60008C8300048C82000424420040046100073D +:101C7000AC8200048C8200040440000400000000D8 +:101C80008C82000024420001AC8200009602000019 +:101C90003042FFFF50520001A600000096220000D3 +:101CA00024420001A62200003C02800834420100C8 +:101CB000962300009442003C144300048FBF001C94 +:101CC00024020001A62200008FBF001C8FB2001862 +:101CD0008FB100148FB0001003E0000827BD002072 +:101CE00027BDFFE03C028008AFBF0018344201006E +:101CF0008C4800343C03800034690400AC68003830 +:101D00008C42003830E700FFAF890028AC62003C0D +:101D10003C020005AC620030000000000000000042 +:101D200000000000000000000000000000000000B3 +:101D30008C82000C8C82000C97830016AD22000070 +:101D40008C82001000604021AD2200048C820018BB +:101D5000AD2200088C82001CAD22000C8CA2001465 +:101D6000AD2200108C820020AD220014908200056C +:101D7000304200FF00021200AD2200188CA20018B1 +:101D8000AD22001C8CA2000CAD2200208CA2001001 +:101D9000AD2200248CA2001CAD2200288CA20020C1 +:101DA000AD22002C3402FFFFAD260030AD20003400 +:101DB000506200013408FFFFAD28003850E00011E8 +:101DC0003C0280083C048008348401009482005066 +:101DD0003042FFFFAD22003C9483004494850044D0 +:101DE000240200013063FFFF000318C200641821C1 +:101DF0009064006430A5000700A210040A00075C8C +:101E00000044102534420100AD20003C94430044BE +:101E1000944400443063FFFF000318C2006218219D +:101E200030840007906500642402000100821004E1 +:101E30000002102700451024A0620064000000008A +:101E400000000000000000003C0200063442004098 +:101E50003C038000AC620030000000000000000085 +:101E6000000000008C620000304200101040FFFDB6 +:101E70003C06800834C201503463040034C7014A70 +:101E800034C4013434C5014034C60144AFA200104B +:101E90000E0006D2AF8300288FBF001803E00008B1 +:101EA00027BD00208F8300143C0608008CC600E884 +:101EB0008F82001C30633FFF000319800046102111 +:101EC000004310212403FF80004318243C068000B7 +:101ED000ACC300283042007F3C03800C004330211B +:101EE00090C2000D30A500FF0000382134420010E0 +:101EF000A0C2000D8F8900143C028008344201000A +:101F00009443004400091382304800032402000176 +:101F1000A4C3000E1102000B2902000210400005AC +:101F2000240200021100000C240300010A0007A48F +:101F30000000182111020006000000000A0007A49A +:101F4000000018218CC2002C0A0007A424430001C1 +:101F50008CC20014244300018CC200180043102BD3 +:101F60005040000A240700012402002714A20003A5 +:101F70003C0380080A0007B1240700013463010014 +:101F80009462004C24420001A462004C00091382B8 +:101F9000304300032C620002104000090080282119 +:101FA000146000040000000094C200340A0007C15D +:101FB0003046FFFF8CC600380A0007C10080282188 +:101FC000000030213C040800248456C00A000706A3 +:101FD0000000000027BDFF90AFB60068AFB50064F9 +:101FE000AFB40060AFB3005CAFB20058AFB1005403 +:101FF000AFBF006CAFB000508C9000000080B021EB +:102000003C0208008C4200E8960400328F83001CDA +:102010002414FF8030843FFF0062182100042180D7 +:1020200000641821007410243C13800000A090214B +:1020300090A50000AE620028920400323C02800CA1 +:102040003063007F00628821308400C02402004099 +:10205000148200320000A8218E3500388E2200182C +:102060001440000224020001AE2200189202003C3B +:10207000304200201440000E8F83001C000511C068 +:102080002442024000621821306400783C02008043 +:102090000082202500741824AE630800AE64081086 +:1020A0008E2200188E03000800431021AE22001873 +:1020B0008E22002C8E230018244200010062182B6F +:1020C0001060004300000000924200002442000122 +:1020D000A24200003C0308008C6300F4304200FF81 +:1020E00050430001A2400000924200008F84001C77 +:1020F000000211C024420240248300403063007F6C +:10210000008220213C02800A0094202400621821D1 +:10211000AE6400240A0008D2AEC30000920300326D +:102120002402FFC000431024304200FF1440000589 +:1021300024020001AE220018962200340A00084250 +:102140003055FFFF8E22001424420001AE220018F9 +:102150009202003000021600000216030441001C27 +:10216000000000009602003227A400100080282101 +:10217000A7A20016960200320000302124070001B9 +:102180003042FFFFAF8200140E000706AFA0001C14 +:10219000960200328F83001C3C0408008C8400E807 +:1021A00030423FFF000211800064182100621821B4 +:1021B00000741024AE62002C3063007F3C02800E5D +:1021C000006218219062000D3042007FA062000D75 +:1021D0009222000D304200105040007892420000E0 +:1021E0003C028008344401009482004C8EC30000FD +:1021F0003C130800967300C62442FFFFA482004CE3 +:10220000946200329623000E3054FFFF3070FFFFBF +:102210003C0308008C6300D000701807A7A30038A7 +:102220009482003E3063FFFF3042FFFF14620007DC +:10223000000000008C8200303C038000244200300B +:10224000AC62003C0A00086A8C82002C9482004038 +:102250003042FFFF5462000927A400408C820038FE +:102260003C03800024420030AC62003C8C8200348D +:10227000AC6200380A0008793C03800027A50038CA +:1022800027A60048026038210E00068FA7A000484C +:102290008FA300403C02800024630030AC43003830 +:1022A0008FA30044AC43003C3C0380003C0200058B +:1022B000AC6200303C028008344401009482004249 +:1022C000346304003042FFFF0202102B1440000769 +:1022D000AF8300289482004E9483004202021021B2 +:1022E000004310230A00088F3043FFFF9483004E01 +:1022F00094820042026318210050102300621823C8 +:102300003063FFFF3C028008344401009482003CAB +:102310003042FFFF14430003000000000A00089F42 +:10232000240300019482003C3042FFFF0062102B26 +:10233000144000058F8200289482003C0062102324 +:102340003043FFFF8F820028AC550000AC400004F2 +:10235000AC540008AC43000C3C02000634420010B0 +:102360003C038000AC620030000000000000000070 +:10237000000000008C620000304200101040FFFDA1 +:102380003C04800834840100001018C20064182145 +:102390009065006432020007240600010046100424 +:1023A00000451025A0620064948300429622000E2E +:1023B00050430001A386001892420000244200010D +:1023C000A24200003C0308008C6300F4304200FF8E +:1023D00050430001A2400000924200008F84001C84 +:1023E000000211C0244202402483004000822021C8 +:1023F0002402FF80008220243063007F3C02800A98 +:10240000006218213C028000AC440024AEC30000EE +:102410008FBF006C8FB600688FB500648FB400600A +:102420008FB3005C8FB200588FB100548FB0005052 +:1024300003E0000827BD007027BDFFD8AFB3001C24 +:10244000AFB20018AFB10014AFB00010AFBF0020A2 +:102450000080982100E0802130B1FFFF0E000D8444 +:1024600030D200FF0000000000000000000000006B +:102470008F8200208F830024AC510000AC520004F6 +:10248000AC530008AC40000CAC400010AC40001451 +:10249000AC4000189463001E02038025AC50001C61 +:1024A0000000000000000000000000002404000103 +:1024B0008FBF00208FB3001C8FB200188FB10014A3 +:1024C0008FB000100A000DB827BD002830A5FFFF0F +:1024D0000A0008DC30C600FF3C02800834430100DB +:1024E0009462000E3C080800950800C63046FFFFC5 +:1024F00014C000043402FFFF946500EA0A000929B1 +:102500008F84001C10C20027000000009462004E5F +:102510009464003C3045FFFF00A6102300A6182B52 +:102520003087FFFF106000043044FFFF00C5102318 +:1025300000E210233044FFFF0088102B1040000EF3 +:1025400000E810233C028008344401002403000109 +:1025500034420080A44300162402FFFFA482000E30 +:10256000948500EA8F84001C0000302130A5FFFF15 +:102570000A0009013C0760200044102A10400009AD +:102580003C0280083443008094620016304200010F +:10259000104000043C0280009442007E244200145B +:1025A000A462001603E000080000000027BDFFE061 +:1025B0003C028008AFBF001CAFB0001834420100DD +:1025C000944300429442004C104000193068FFFFD1 +:1025D0009383001824020001146200298FBF001C9D +:1025E0003C06800834D00100000810C200501021C1 +:1025F000904200643103000734C70148304200FFB5 +:10260000006210073042000134C9014E34C4012C6D +:1026100034C5013E1040001634C601420E0006D2F9 +:10262000AFA90010960200420A0009463048FFFF99 +:102630003C028008344401009483004494820042A8 +:102640001043000F8FBF001C94820044A4820042FC +:1026500094820050A482004E8C820038AC820030FC +:1026600094820040A482003E9482004AA4820048E2 +:102670008FBF001C8FB000180A00090427BD00207E +:102680008FB0001803E0000827BD002027BDFFA081 +:10269000AFB1004C3C118000AFBF0058AFB3005445 +:1026A000AFB20050AFB000483626018890C2000398 +:1026B0003044007FA3A400108E32018090C200003D +:1026C0003043007F240200031062003BAF92001CE5 +:1026D00028620004104000062402000424020002C4 +:1026E000106200098FBF00580A000B0F8FB300540F +:1026F0001062004D240200051062014E8FBF005889 +:102700000A000B0F8FB30054000411C002421021C5 +:102710002404FF8024420240004410242643004049 +:10272000AE2200243063007F3C02800A0062182140 +:102730009062003CAFA3003C00441025A062003C26 +:102740008FA3003C9062003C304200401040016C7E +:102750008FBF00583C108008A3800018361001007D +:102760008E0200E08C63003427A4003C27A50010F3 +:10277000004310210E0007C3AE0200E093A2001038 +:102780003C038000A20200D58C6202780440FFFE68 +:102790008F82001CAC62024024020002A06202444C +:1027A0003C021000AC6202780E0009390000000003 +:1027B0000A000B0E8FBF00583C05800890C3000133 +:1027C00090A2000B1443014E8FBF005834A4008028 +:1027D0008C8200189082004C90A200083C0260009D +:1027E0008C4254048C8300183C027FFF3442FFFF6C +:1027F000006218243C0208008C4200B4AC8300182C +:102800003C038000244200013C010800AC2200B4DB +:102810008C6201F80440FFFE8F82001CAC6201C094 +:102820000A000AD6240200023C10800890C300016E +:102830009202000B144301328FBF005827A40018E6 +:1028400036050110240600033C0260008C4254044B +:102850000E000E470000000027A40028360501F0F6 +:102860000E000E47240600038FA200283603010045 +:10287000AE0200648FA2002CAE0200688FA200306E +:10288000AE02006C93A40018906300D52402FF8070 +:102890000082102400431025304900FF3084007F5F +:1028A0003122007F0082102A544000013929008023 +:1028B000000411C0244202402403FF800242102180 +:1028C00000431024AE220094264200403042007F94 +:1028D0003C038006004340218FA3001C2402FFFF1D +:1028E000AFA800403C130800927300F71062003359 +:1028F00093A2001995030014304400FF3063FFFFDA +:102900000064182B106000100000000095040014F3 +:102910008D07001C8D0600183084FFFF0044202323 +:102920000004210000E438210000102100E4202BE5 +:1029300000C2302100C43021AD07001CAD060018D4 +:102940000A000A2F93A20019950400148D07001C99 +:102950008D0600183084FFFF008220230004210030 +:10296000000010210080182100C2302300E4202B39 +:1029700000C4302300E33823AD07001CAD06001867 +:1029800093A200198FA30040A462001497A2001A1A +:10299000A46200168FA2001CAC6200108FA2001C63 +:1029A000AC62000C93A20019A462002097A2001A46 +:1029B000A46200228FA2001CAC6200243C048008A8 +:1029C000348300808C6200388FA20020012088218F +:1029D000AC62003C8FA20020AC82000093A20018E1 +:1029E000A062004C93A20018A0820009A0600068B9 +:1029F00093A20018105100512407FF803229007F54 +:102A0000000911C024420240024210213046007FDA +:102A10003C03800000471024AC6200943C02800616 +:102A200000C2302190C2003CAFA60040000020212F +:102A300000471025A0C2003C8FA80040950200026C +:102A4000950300148D07001C3042FFFF3063FFFF29 +:102A50008D060018004310230002110000E2382107 +:102A600000E2102B00C4302100C23021AD07001C51 +:102A7000AD06001895020002A5020014A50000167C +:102A80008D020008AD0200108D020008AD02000C9E +:102A900095020002A5020020A50000228D02000878 +:102AA000AD0200249102003C304200401040001A68 +:102AB000262200013C108008A3A90038A38000183A +:102AC000361001008E0200E08D03003427A4004080 +:102AD00027A50038004310210E0007C3AE0200E016 +:102AE00093A200383C038000A20200D58C620278D9 +:102AF0000440FFFE8F82001CAC62024024020002F0 +:102B0000A06202443C021000AC6202780E00093957 +:102B100000000000262200013043007F14730004EF +:102B2000004020212403FF8002231024004320269C +:102B300093A200180A000A4B309100FF93A40018DA +:102B40008FA3001C2402FFFF1062000A308900FFDF +:102B500024820001248300013042007F14530005C9 +:102B6000306900FF2403FF800083102400431026F7 +:102B7000304900FF3C028008904200080120882173 +:102B8000305000FF123000193222007F000211C0C5 +:102B900002421021244202402403FF8000431824F3 +:102BA0003C048000AC8300943042007F3C038006EC +:102BB000004310218C43000C004020211060000BCA +:102BC000AFA200400E00057E000000002623000199 +:102BD0002405FF803062007F145300020225202468 +:102BE000008518260A000AAF307100FF3C048008F7 +:102BF000348400808C8300183C027FFF3442FFFF46 +:102C000000621824AC8300183C0380008C6201F839 +:102C10000440FFFE00000000AC7201C0240200026C +:102C2000A06201C43C021000AC6201F80A000B0E65 +:102C30008FBF00583C04800890C300019082000BB5 +:102C40001443002F8FBF0058349000809202000878 +:102C500030420040104000200000000092020008B6 +:102C60000002160000021603044100050240202164 +:102C70000E000ECC240500930A000B0E8FBF0058E7 +:102C80009202000924030018304200FF1443000D93 +:102C900002402021240500390E000E64000030217E +:102CA0000E0003328F84001C8F82FF9424030012D5 +:102CB000A04300090E00033D8F84001C0A000B0E88 +:102CC0008FBF0058240500360E000E64000030212E +:102CD0000A000B0E8FBF00580E0003320240202165 +:102CE000920200058F84001C344200200E00033D38 +:102CF000A20200050E0010758F84001C8FBF0058C3 +:102D00008FB300548FB200508FB1004C8FB0004889 +:102D100003E0000827BD00603C0280083445010044 +:102D20003C0280008C42014094A3000E0000302140 +:102D300000402021AF82001C3063FFFF3402FFFF00 +:102D4000106200063C0760202402FFFFA4A2000ED0 +:102D500094A500EA0A00090130A5FFFF03E000087E +:102D60000000000027BDFFC83C0280003C06800830 +:102D7000AFB5002CAFB1001CAFBF0030AFB400281E +:102D8000AFB30024AFB20020AFB00018345101003F +:102D900034C501008C4301008E2200148CA400E491 +:102DA0000000A821AF83001C0044102318400052EB +:102DB000A38000188E22001400005021ACA200E471 +:102DC00090C3000890A200D53073007FA3A200102A +:102DD0008CB200E08CB400E4304200FF1053003BA2 +:102DE00093A200108F83001C2407FF80000211C0F3 +:102DF0000062102124420240246300400047102456 +:102E00003063007F3C0980003C08800A006818217C +:102E1000AD2200248C62003427A4001427A50010E2 +:102E2000024280210290102304400028AFA3001426 +:102E30009062003C00E21024304200FF1440001970 +:102E4000020090219062003C34420040A062003CAD +:102E50008F86001C93A3001024C200403042007FE4 +:102E6000004828213C0208008C4200F42463000141 +:102E7000306400FF14820002A3A30010A3A000107E +:102E800093A20010AFA50014000211C0244202401A +:102E900000C2102100471024AD2200240A000B4577 +:102EA00093A200100E0007C3000000003C0280083F +:102EB00034420100AC5000E093A30010240A00014A +:102EC000A04300D50A000B4593A200102402000184 +:102ED000154200093C0380008C6202780440FFFE2A +:102EE0008F82001CAC62024024020002A0620244F5 +:102EF0003C021000AC6202789222000B2403000214 +:102F0000304200FF144300720000000096220008C7 +:102F1000304300FF24020082146200402402008437 +:102F20003C028000344901008D22000C95230006EC +:102F3000000216023063FFFF3045003F24020027E5 +:102F400010A2000FAF83001428A200281040000830 +:102F5000240200312402002110A2000924020025CD +:102F600010A20007938200190A000BBD00000000A8 +:102F700010A20007938200190A000BBD0000000098 +:102F80000E000777012020210A000C3D0000000000 +:102F90003C0380008C6202780440FFFE8F82001C9C +:102FA000AC62024024020002A06202443C02100013 +:102FB000AC6202780A000C3D000000009523000678 +:102FC000912400058D25000C8D2600108D270018FA +:102FD0008D28001C8D290020244200013C0108009E +:102FE000A42356C63C010800A02456C53C01080095 +:102FF000AC2556CC3C010800AC2656D03C0108005C +:10300000AC2756D83C010800AC2856DC3C0108002F +:10301000AC2956E00A000C3DA38200191462000A94 +:10302000240200813C02800834420100944500EAF9 +:10303000922600058F84001C30A5FFFF30C600FFDC +:103040000A000BFE3C0760211462005C00000000D7 +:103050009222000A304300FF306200201040000737 +:10306000306200403C02800834420100944500EA8E +:103070008F84001C0A000BFC24060040104000074F +:10308000000316003C02800834420100944500EA27 +:103090008F84001C0A000BFC24060041000216036A +:1030A000044100463C02800834420100944500EA95 +:1030B0008F84001C2406004230A5FFFF3C076019E6 +:1030C0000E000901000000000A000C3D0000000095 +:1030D0009222000B24040016304200FF1044000628 +:1030E0003C0680009222000B24030017304200FFB0 +:1030F000144300320000000034C5010090A2000B10 +:10310000304200FF1444000B000080218CA20020FC +:103110008CA400202403FF800043102400021140EF +:103120003084007F004410253C032000004310251C +:10313000ACC2083094A2000800021400000214037C +:10314000044200012410000194A2000830420080D3 +:103150005040001A0200A82194A20008304220002A +:10316000504000160200A8218CA300183C021C2D20 +:10317000344219ED106200110200A8213C0208003F +:103180008C4200D4104000053C0280082403000457 +:1031900034420100A04300FC3C028008344201009C +:1031A000944500EA8F84001C2406000630A5FFFF2A +:1031B0000E0009013C0760210200A8210E00093918 +:1031C000000000009222000A304200081040000473 +:1031D00002A010210E0013790000000002A01021AF +:1031E0008FBF00308FB5002C8FB400288FB3002420 +:1031F0008FB200208FB1001C8FB0001803E00008D0 +:1032000027BD00382402FF80008220243C02900069 +:1032100034420007008220253C028000AC4400209C +:103220003C0380008C6200200440FFFE0000000090 +:1032300003E00008000000003C0380002402FF803F +:10324000008220243462000700822025AC64002024 +:103250008C6200200440FFFE0000000003E0000834 +:103260000000000027BDFFD8AFB3001CAFB10014B1 +:10327000AFB00010AFBF0020AFB200183C1180000B +:103280003C0280088E32002034530100AE2400201E +:10329000966300EA000514003C074000004738250B +:1032A00000A08021000030210E0009013065FFFFE1 +:1032B000240200A1160200022402FFFFA2620009FC +:1032C000AE3200208FBF00208FB3001C8FB20018D9 +:1032D0008FB100148FB0001003E0000827BD002854 +:1032E0003C0280082403000527BDFFE834420100AA +:1032F000A04300FCAFBF00103C0280008C420100E4 +:10330000240500A1004020210E000C67AF82001CA4 +:103310003C0380008C6202780440FFFE8F82001C18 +:103320008FBF001027BD0018AC62024024020002CB +:10333000A06202443C021000AC62027803E0000884 +:103340000000000027BDFFE83C068000AFBF001072 +:1033500034C7010094E20008304400FF3883008243 +:10336000388200842C6300012C4200010062182581 +:103370001060002D24020083938200195040003B0E +:103380008FBF00103C020800904256CC8CC4010054 +:103390003C06080094C656C63045003F38A30032AC +:1033A00038A2003F2C6300012C4200010062182566 +:1033B000AF84001CAF860014A380001914600007BE +:1033C00000E020212402002014A2001200000000CE +:1033D0003402FFFF14C2000F00000000240200208E +:1033E00014A2000500E028218CE300142402FFFF52 +:1033F0005062000B8FBF00103C040800248456C0AC +:10340000000030210E000706240700010A000CD638 +:103410008FBF00100E000777000000008FBF001064 +:103420000A00093927BD001814820004240200850F +:103430008CC501040A000CE1000020211482000662 +:103440002482FF808CC50104240440008FBF00103B +:103450000A00016727BD0018304200FF2C4200021D +:1034600010400004240200228FBF00100A000B2726 +:1034700027BD0018148200048F8200248FBF001023 +:103480000A000C8627BD00188C42000C1040001E5C +:1034900000E0282190E300092402001814620003D0 +:1034A000240200160A000CFC240300081462000722 +:1034B00024020017240300123C02800834420080DA +:1034C000A04300090A000D0994A7000854620007F0 +:1034D00094A700088F82FF942404FFFE9043000508 +:1034E00000641824A043000594A7000890A6001BC0 +:1034F0008CA4000094A500068FBF001000073C00BC +:103500000A0008DC27BD00188FBF001003E0000888 +:1035100027BD00188F8500243C04800094A2002A57 +:103520008CA30034000230C02402FFF000C210243B +:1035300000621821AC83003C8CA200303C03800068 +:10354000AC8200383C02005034420010AC620030C3 +:103550000000000000000000000000008C6200007D +:10356000304200201040FFFD30C20008104000062D +:103570003C0280008C620408ACA200208C62040C27 +:103580000A000D34ACA200248C430400ACA300203C +:103590008C420404ACA200243C0300203C028000C6 +:1035A000AC4300303C0480008C8200300043102487 +:1035B0001440FFFD8F8600243C020040AC820030A6 +:1035C00094C3002A94C2002894C4002C94C5002EF1 +:1035D00024630001004410213064FFFFA4C20028CE +:1035E00014850002A4C3002AA4C0002A03E0000836 +:1035F000000000008F84002427BDFFE83C05800404 +:1036000024840010AFBF00100E000E472406000AED +:103610008F840024948200129483002E3042000F85 +:10362000244200030043180424027FFF0043102BB0 +:1036300010400002AC8300000000000D0E000D13CE +:10364000000000008F8300248FBF001027BD0018EA +:10365000946200149463001A3042000F00021500B7 +:10366000006218253C02800003E00008AC4300A083 +:103670008F8300243C028004944400069462001A64 +:103680008C650000A4640016004410233042FFFF44 +:103690000045102B03E00008384200018F8400240D +:1036A0003C0780049486001A8C85000094E2000692 +:1036B000A482001694E3000600C310233042FFFFEB +:1036C0000045102B384200011440FFF8A483001677 +:1036D00003E00008000000008F8400243C02800406 +:1036E000944200069483001A8C850000A482001680 +:1036F000006210233042FFFF0045102B38420001CA +:103700005040000D8F850024006030213C0780046C +:1037100094E20006A482001694E3000600C310237E +:103720003042FFFF0045102B384200011440FFF8E3 +:10373000A48300168F8500243C03800034620400BB +:103740008CA40020AF820020AC6400388CA200243E +:10375000AC62003C3C020005AC62003003E00008B3 +:10376000ACA000048F8400243C0300068C8200047B +:1037700000021140004310253C038000AC62003081 +:103780000000000000000000000000008C6200004B +:10379000304200101040FFFD34620400AC80000491 +:1037A00003E00008AF8200208F86002427BDFFE0E1 +:1037B000AFB10014AFB00010AFBF00188CC300044D +:1037C0008CC500248F820020309000FF94C4001A22 +:1037D00024630001244200202484000124A7002047 +:1037E000ACC30004AF820020A4C4001AACC70024FC +:1037F00004A100060000882104E2000594C2001A1A +:103800008CC2002024420001ACC2002094C2001AE5 +:1038100094C300282E040001004310262C4200010E +:10382000004410245040000594C2001A24020001F4 +:10383000ACC2000894C2001A94C300280010202BC8 +:10384000004310262C4200010044102514400007BC +:10385000000000008CC20008144000042402001084 +:103860008CC300041462000F8F8500240E000DA786 +:10387000241100018F820024944300289442001AEE +:1038800014430003000000000E000D1300000000B0 +:10389000160000048F8500240E000D840000000037 +:1038A0008F85002494A2001E94A4001C24420001D1 +:1038B0003043FFFF14640002A4A2001EA4A0001E57 +:1038C0001200000A3C02800494A2001494A3001A7F +:1038D0003042000F00021500006218253C028000F3 +:1038E000AC4300A00A000E1EACA0000894420006E3 +:1038F00094A3001A8CA40000A4A200160062102356 +:103900003042FFFF0044102B384200011040000DF0 +:1039100002201021006030213C07800494E2000660 +:10392000A4A2001694E3000600C310233042FFFF58 +:103930000044102B384200011440FFF8A4A30016E5 +:10394000022010218FBF00188FB100148FB000101B +:1039500003E0000827BD002003E00008000000008D +:103960008F82002C3C03000600021140004310250A +:103970003C038000AC62003000000000000000004A +:10398000000000008C620000304200101040FFFD7B +:1039900034620400AF82002803E00008AF80002CEE +:1039A00003E000080000102103E000080000000010 +:1039B0003084FFFF30A5FFFF0000182110800007B2 +:1039C000000000003082000110400002000420428C +:1039D000006518210A000E3D0005284003E000089C +:1039E0000060102110C0000624C6FFFF8CA200005A +:1039F00024A50004AC8200000A000E4724840004C1 +:103A000003E000080000000010A0000824A3FFFF4E +:103A1000AC86000000000000000000002402FFFF50 +:103A20002463FFFF1462FFFA2484000403E000080B +:103A3000000000003C0280083442008024030001A2 +:103A4000AC43000CA4430010A4430012A443001490 +:103A500003E00008A44300168F82002427BDFFD88E +:103A6000AFB3001CAFB20018AFB10014AFB000107C +:103A7000AFBF00208C47000C248200802409FF8007 +:103A80003C08800E3043007F008080213C0A80008B +:103A9000004920240068182130B100FF30D200FF17 +:103AA00010E000290000982126020100AD44002CFE +:103AB000004928243042007F004820219062000005 +:103AC00024030050304200FF1443000400000000B3 +:103AD000AD45002C948200EA3053FFFF0E000D84A8 +:103AE000000000008F8200248F83002000112C0032 +:103AF0009442001E001224003484000100A22825F4 +:103B00003C02400000A22825AC7000008FBF0020BE +:103B1000AC6000048FB20018AC7300088FB10014C1 +:103B2000AC60000C8FB3001CAC6400108FB00010B0 +:103B3000AC60001424040001AC60001827BD00280C +:103B40000A000DB8AC65001C8FBF00208FB3001CAD +:103B50008FB200188FB100148FB0001003E000087E +:103B600027BD00283C06800034C201009043000FAE +:103B7000240200101062000E2865001110A000073A +:103B800024020012240200082405003A10620006F4 +:103B90000000302103E0000800000000240500358B +:103BA0001462FFFC000030210A000E6400000000D7 +:103BB0008CC200748F83FF9424420FA003E000089E +:103BC000AC62000C27BDFFE8AFBF00100E0003423F +:103BD000240500013C0480088FBF0010240200016E +:103BE00034830080A462001227BD00182402000163 +:103BF00003E00008A080001A27BDFFE0AFB2001864 +:103C0000AFB10014AFB00010AFBF001C30B2FFFF67 +:103C10000E000332008088213C028008345000806E +:103C20009202000924030004304200FF1443000CF8 +:103C30003C028008124000082402000A0E000E5BBD +:103C400000000000920200052403FFFE0043102440 +:103C5000A202000524020012A20200093C02800810 +:103C600034420080022020210E00033DA0400027A6 +:103C700016400003022020210E000EBF00000000AD +:103C800002202021324600FF8FBF001C8FB2001897 +:103C90008FB100148FB00010240500380A000E64A4 +:103CA00027BD002027BDFFE0AFBF001CAFB200184A +:103CB000AFB10014AFB000100E00033200808021BD +:103CC0000E000E5B000000003C02800834450080BE +:103CD00090A2000924120018305100FF1232000394 +:103CE0000200202124020012A0A2000990A20005D7 +:103CF0002403FFFE004310240E00033DA0A2000594 +:103D00000200202124050020163200070000302187 +:103D10008FBF001C8FB200188FB100148FB000103D +:103D20000A00034227BD00208FBF001C8FB200187D +:103D30008FB100148FB00010240500390A000E6402 +:103D400027BD002027BDFFE83C028000AFB0001077 +:103D5000AFBF0014344201009442000C2405003629 +:103D60000080802114400012304600FF0E00033214 +:103D7000000000003C02800834420080240300124E +:103D8000A043000990430005346300100E000E5B51 +:103D9000A04300050E00033D020020210200202167 +:103DA0000E000342240500200A000F3C0000000022 +:103DB0000E000E64000000000E00033202002021FD +:103DC0003C0280089043001B2405FF9F0200202135 +:103DD000006518248FBF00148FB00010A043001B93 +:103DE0000A00033D27BD001827BDFFE0AFBF001844 +:103DF000AFB10014AFB0001030B100FF0E000332BD +:103E0000008080213C02800824030012344200809C +:103E10000E000E5BA04300090E00033D02002021AE +:103E200002002021022030218FBF00188FB1001422 +:103E30008FB00010240500350A000E6427BD002055 +:103E40003C0480089083000E9082000A1443000B0B +:103E5000000028218F82FF942403005024050001D4 +:103E600090420000304200FF1443000400000000B4 +:103E70009082000E24420001A082000E03E00008A0 +:103E800000A010213C0380008C6201F80440FFFE7A +:103E900024020002AC6401C0A06201C43C02100014 +:103EA00003E00008AC6201F827BDFFE0AFB20018E4 +:103EB0003C128008AFB10014AFBF001CAFB00010BF +:103EC00036510080922200092403000A304200FF8C +:103ED0001443003E000000008E4300048E22003890 +:103EE000506200808FBF001C92220000240300500B +:103EF000304200FF144300253C0280008C42014008 +:103F00008E4300043642010002202821AC43001CED +:103F10009622005C8E2300383042FFFF00021040E2 +:103F200000621821AE23001C8E4300048E2400384A +:103F30009622005C006418233042FFFF0003184300 +:103F4000000210400043102A10400006000000004C +:103F50008E4200048E230038004310230A000FAA6B +:103F6000000220439622005C3042FFFF0002204006 +:103F70003C0280083443010034420080ACA4002C91 +:103F8000A040002424020001A062000C0E000F5E7D +:103F900000000000104000538FBF001C3C02800056 +:103FA0008C4401403C0380008C6201F80440FFFE19 +:103FB00024020002AC6401C0A06201C43C021000F3 +:103FC000AC6201F80A0010078FBF001C92220009A2 +:103FD00024030010304200FF144300043C02800020 +:103FE0008C4401400A000FEE0000282192220009B3 +:103FF00024030016304200FF14430006240200147C +:10400000A22200093C0280008C4401400A001001F9 +:104010008FBF001C8E2200388E23003C00431023EB +:10402000044100308FBF001C92220027244200016F +:10403000A2220027922200272C42000414400016DE +:104040003C1080009222000924030004304200FF4B +:10405000144300093C0280008C4401408FBF001CC7 +:104060008FB200188FB100148FB000102405009398 +:104070000A000ECC27BD00208C440140240500938B +:104080008FBF001C8FB200188FB100148FB00010CA +:104090000A000F4827BD00208E0401400E000332A5 +:1040A000000000008E4200042442FFFFAE420004E4 +:1040B0008E22003C2442FFFFAE22003C0E00033D56 +:1040C0008E0401408E0401408FBF001C8FB2001887 +:1040D0008FB100148FB00010240500040A000342C1 +:1040E00027BD00208FB200188FB100148FB00010D0 +:1040F00003E0000827BD00203C0680008CC2018838 +:104100003C038008346500809063000E00021402B6 +:10411000304400FF306300FF1464000E3C0280084E +:1041200090A20026304200FF104400098F82FF94C5 +:10413000A0A400262403005090420000304200FF5B +:1041400014430006000000000A0005A18CC4018091 +:104150003C02800834420080A044002603E00008AE +:104160000000000027BDFFE030E700FFAFB20018FD +:10417000AFBF001CAFB10014AFB0001000809021A1 +:1041800014E0000630C600FF000000000000000D33 +:10419000000000000A001060240001163C038008A3 +:1041A0009062000E304200FF14460023346200800B +:1041B00090420026304200FF1446001F000000001D +:1041C0009062000F304200FF1446001B0000000008 +:1041D0009062000A304200FF144600038F90FF9463 +:1041E0000000000D8F90FF948F82FF983C1180009B +:1041F000AE05003CAC450000A066000A0E0003328C +:104200008E240100A20000240E00033D8E24010034 +:104210003C0380008C6201F80440FFFE240200028F +:10422000AC7201C0A06201C43C021000AC6201F893 +:104230000A0010618FBF001C000000000000000D8C +:10424000000000002400013F8FBF001C8FB2001847 +:104250008FB100148FB0001003E0000827BD0020CC +:104260008F83FF943C0280008C44010034420100A3 +:104270008C65003C9046001B0A00102724070001B3 +:104280003C0280089043000E9042000A0043102632 +:10429000304200FF03E000080002102B27BDFFE0C2 +:1042A0003C028008AFB10014AFB00010AFBF0018DF +:1042B0003450008092020005240300303042003068 +:1042C00014430085008088218F8200248C42000CDA +:1042D000104000828FBF00180E000D840000000007 +:1042E0008F860020ACD100009202000892030009E2 +:1042F000304200FF00021200306300FF004310252F +:10430000ACC200049202004D000216000002160327 +:1043100004410005000000003C0308008C630048D5 +:104320000A00109F3C1080089202000830420040B2 +:10433000144000030000182192020027304300FFC0 +:104340003C108008361100809222004D00031E00B0 +:10435000304200FF0002140000621825ACC30008C0 +:104360008E2400308F820024ACC4000C8E250034D3 +:104370009443001E3C02C00BACC50010006218251F +:104380008E22003800002021ACC200148E22003C96 +:10439000ACC200180E000DB8ACC3001C8E020004A5 +:1043A0008F8400203C058000AC8200008E2200201B +:1043B000AC8200048E22001CAC8200088E220058C1 +:1043C0008CA3007400431021AC82000C8E22002CC0 +:1043D000AC8200108E2200408E23004400021400A4 +:1043E00000431025AC8200149222004D240300806B +:1043F000304200FF1443000400000000AC800018AD +:104400000A0010E38F8200248E23000C2402000196 +:104410001062000E2402FFFF92220008304200408A +:104420001440000A2402FFFF8E23000C8CA20074AB +:10443000006218233C0208000062102414400002AD +:10444000000028210060282100051043AC820018DC +:104450008F820024000020219443001E3C02C00CE7 +:10446000006218258F8200200E000DB8AC43001C9E +:104470003C038008346201008C4200008F850020DC +:10448000346300808FBF0018ACA20000ACA0000411 +:104490008C6400488F8200248FB10014ACA4000803 +:1044A000ACA0000CACA00010906300059446001E68 +:1044B0003C02400D00031E0000C23025ACA30014D6 +:1044C0008FB00010ACA0001824040001ACA6001CA2 +:1044D0000A000DB827BD00208FBF00188FB100144F +:1044E0008FB0001003E0000827BD00203C028000D0 +:1044F0009443007C3C02800834460100308400FF75 +:104500003065FFFF2402000524A34650A0C4000C20 +:104510005482000C3065FFFF90C2000D2C42000752 +:104520001040000724A30A0090C3000D24020014C9 +:104530000062100400A210210A00111F3045FFFF85 +:104540003065FFFF3C0280083442008003E0000831 +:10455000A44500143C03800834680080AD05003891 +:10456000346701008CE2001C308400FF00A210239D +:104570001840000330C600FF24A2FFFCACE2001C80 +:1045800030820001504000083C0380088D02003C4E +:1045900000A2102304410012240400058C620004D0 +:1045A00010A2000F3C0380088C62000414A2001EBD +:1045B000000000003C0208008C4200D8304200207D +:1045C000104000093C0280083462008090630008BB +:1045D0009042004C144300043C0280082404000470 +:1045E0000A00110900000000344300803442010039 +:1045F000A040000C24020001A462001410C0000AB4 +:104600003C0280008C4401003C0380008C6201F875 +:104610000440FFFE24020002AC6401C0A06201C499 +:104620003C021000AC6201F803E00008000000004A +:1046300027BDFFE800A61823AFBF00101860008058 +:10464000308800FF3C02800834470080A0E000244E +:1046500034440100A0E000278C82001C00A210233B +:1046600004400056000000008CE2003C94E3005C33 +:104670008CE4002C004530233063FFFF00C3182179 +:104680000083202B1080000400E018218CE2002C15 +:104690000A00117800A2102194E2005C3042FFFF72 +:1046A00000C2102100A21021AC62001C3C02800854 +:1046B000344400809482005C8C83001C3042FFFFF5 +:1046C0000002104000A210210043102B10400004F3 +:1046D000000000008C82001C0A00118B3C06800840 +:1046E0009482005C3042FFFF0002104000A21021C3 +:1046F0003C06800834C3010034C70080AC82001C33 +:10470000A060000CACE500388C62001C00A21023F5 +:104710001840000224A2FFFCAC62001C3102000120 +:10472000104000083C0380088CE2003C00A21023EB +:1047300004410012240400058CC2000410A20010E1 +:104740008FBF00108C62000414A2004F8FBF0010B6 +:104750003C0208008C4200D8304200201040000A81 +:104760003C02800834620080906300089042004C54 +:10477000144300053C028008240400048FBF00108D +:104780000A00110927BD001834430080344201009B +:10479000A040000C24020001A46200143C0280002E +:1047A0008C4401003C0380008C6201F80440FFFE51 +:1047B000240200020A0011D8000000008CE2001C54 +:1047C000004610230043102B54400001ACE5001CB0 +:1047D00094E2005C3042FFFF0062102B144000079F +:1047E0002402000294E2005C8CE3001C3042FFFFD4 +:1047F00000621821ACE3001C24020002ACE5003882 +:104800000E000F5EA082000C1040001F8FBF001032 +:104810003C0280008C4401003C0380008C6201F863 +:104820000440FFFE24020002AC6401C0A06201C487 +:104830003C021000AC6201F80A0011F08FBF0010BA +:1048400031020010104000108FBF00103C028008A1 +:10485000344500808CA3001C94A2005C00661823E1 +:104860003042FFFF006218213C023FFF3444FFFF4B +:104870000083102B544000010080182100C3102138 +:10488000ACA2001C8FBF001003E0000827BD001879 +:1048900027BDFFE800C0402100A63023AFBF0010B5 +:1048A00018C00026308A00FF3C028008344900808E +:1048B0008D24001C8D23002C008820230064182BDD +:1048C0001060000F344701008CE2002000461021E8 +:1048D000ACE200208CE200200044102B1440000BBE +:1048E0003C023FFF8CE2002000441023ACE2002099 +:1048F0009522005C3042FFFF0A0012100082202146 +:10490000ACE00020008620213C023FFF3443FFFF43 +:104910000064102B54400001006020213C028008FC +:104920003442008000851821AC43001CA0400024C4 +:10493000A04000270A0012623C03800831420010A8 +:10494000104000433C0380083C06800834C40080CB +:104950008C82003C004810235840003E34660080A2 +:104960009082002424420001A0820024908200242E +:104970003C0308008C630024304200FF0043102BEE +:10498000144000688FBF001034C201008C42001C2C +:1049900000A2102318400063000000008CC3000434 +:1049A0009482005C006818233042FFFF0003184324 +:1049B000000210400043102A1040000500000000D3 +:1049C0008CC20004004810230A0012450002104364 +:1049D0009482005C3042FFFF000210403C068008D9 +:1049E000AC82002C34C5008094A2005C8CA4002C06 +:1049F00094A3005C3042FFFF00021040008220219F +:104A00003063FFFF0083202101041021ACA2001CB1 +:104A10008CC2000434C60100ACC2001C2402000297 +:104A20000E000F5EA0C2000C1040003E8FBF0010B1 +:104A30003C0280008C4401003C0380008C6201F841 +:104A40000440FFFE240200020A001292000000004F +:104A500034660080ACC50038346401008C82001CD0 +:104A600000A210231840000224A2FFFCAC82001C0C +:104A7000314200015040000A3C0380088CC2003CD7 +:104A800000A2102304430014240400058C620004D7 +:104A900014A200033C0380080A00128424040005C9 +:104AA0008C62000414A2001F8FBF00103C0208009B +:104AB0008C4200D8304200201040000A3C0280089E +:104AC00034620080906300089042004C144300055B +:104AD0003C028008240400048FBF00100A00110962 +:104AE00027BD00183443008034420100A040000C70 +:104AF00024020001A46200143C0280008C440100E6 +:104B00003C0380008C6201F80440FFFE2402000296 +:104B1000AC6401C0A06201C43C021000AC6201F8A8 +:104B20008FBF001003E0000827BD001827BDFFE875 +:104B30003C0A8008AFBF0010354900808D22003C40 +:104B400000C04021308400FF004610231840009D23 +:104B500030E700FF354701002402000100A63023A2 +:104B6000A0E0000CA0E0000DA522001418C0002455 +:104B7000308200108D23001C8D22002C0068182329 +:104B80000043102B1040000F000000008CE20020BA +:104B900000461021ACE200208CE200200043102BE4 +:104BA0001440000B3C023FFF8CE200200043102326 +:104BB000ACE200209522005C3042FFFF0A0012C1E7 +:104BC00000621821ACE00020006618213C023FFF83 +:104BD0003446FFFF00C3102B5440000100C01821D1 +:104BE0003C0280083442008000651821AC43001C60 +:104BF000A0400024A04000270A00130F3C038008B7 +:104C0000104000403C0380088D22003C00481023E7 +:104C10005840003D34670080912200242442000166 +:104C2000A1220024912200243C0308008C6300246C +:104C3000304200FF0043102B1440009A8FBF001039 +:104C40008CE2001C00A21023184000960000000017 +:104C50008D4300049522005C006818233042FFFF5A +:104C600000031843000210400043102A10400005C2 +:104C7000012020218D420004004810230A0012F276 +:104C8000000210439522005C3042FFFF00021040FA +:104C90003C068008AC82002C34C5008094A2005CE5 +:104CA0008CA4002C94A3005C3042FFFF0002104053 +:104CB000008220213063FFFF0083182101031021AF +:104CC000ACA2001C8CC2000434C60100ACC2001CA3 +:104CD000240200020E000F5EA0C2000C1040007102 +:104CE0008FBF00103C0280008C4401003C03800018 +:104CF0008C6201F80440FFFE240200020A0013390E +:104D00000000000034670080ACE500383466010024 +:104D10008CC2001C00A210231840000224A2FFFC39 +:104D2000ACC2001C30820001504000083C038008E7 +:104D30008CE2003C00A2102304430051240400052F +:104D40008C62000410A2003E3C0380088C620004C8 +:104D500054A200548FBF00103C0208008C4200D8BF +:104D600030420020104000063C028008346200807F +:104D7000906300089042004C104300403C028008C1 +:104D80003443008034420100A040000C24020001A2 +:104D9000A46200143C0280008C4401003C038000AB +:104DA0008C6201F80440FFFE24020002AC6401C0E2 +:104DB000A06201C43C021000AC6201F80A00137743 +:104DC0008FBF001024020005A120002714E2000A72 +:104DD0003C038008354301009062000D2C42000620 +:104DE000504000053C0380089062000D2442000101 +:104DF000A062000D3C03800834670080ACE50038F9 +:104E0000346601008CC2001C00A21023184000026E +:104E100024A2FFFCACC2001C308200015040000AFA +:104E20003C0380088CE2003C00A2102304410014E3 +:104E3000240400058C62000414A200033C038008D3 +:104E40000A00136E240400058C62000414A20015ED +:104E50008FBF00103C0208008C4200D83042002076 +:104E60001040000A3C028008346200809063000811 +:104E70009042004C144300053C02800824040004C6 +:104E80008FBF00100A00110927BD001834430080AD +:104E900034420100A040000C24020001A46200146E +:104EA0008FBF001003E0000827BD00183C0B8008EE +:104EB00027BDFFE83C028000AFBF00103442010074 +:104EC000356A00809044000A356901008C45001461 +:104ED0008D4800389123000C308400FF0105102319 +:104EE0001C4000B3306700FF2CE20006504000B1C8 +:104EF0008FBF00102402000100E2300430C2000322 +:104F00005440000800A8302330C2000C144000A117 +:104F100030C20030144000A38FBF00100A00143BC1 +:104F20000000000018C00024308200108D43001CD7 +:104F30008D42002C006818230043102B1040000FF6 +:104F4000000000008D22002000461021AD2200202C +:104F50008D2200200043102B1440000B3C023FFF29 +:104F60008D22002000431023AD2200209542005CDA +:104F70003042FFFF0A0013AF00621821AD2000206D +:104F8000006618213C023FFF3446FFFF00C3102B90 +:104F90005440000100C018213C02800834420080C7 +:104FA00000651821AC43001CA0400024A04000274D +:104FB0000A0013FD3C038008104000403C038008B9 +:104FC0008D42003C004810231840003D34670080AB +:104FD0009142002424420001A14200249142002475 +:104FE0003C0308008C630024304200FF0043102B78 +:104FF000144000708FBF00108D22001C00A21023EF +:105000001840006C000000008D6300049542005CB5 +:10501000006818233042FFFF0003184300021040CD +:105020000043102A10400005014020218D62000439 +:10503000004810230A0013E0000210439542005C70 +:105040003042FFFF000210403C068008AC82002C7A +:1050500034C5008094A2005C8CA4002C94A3005C56 +:105060003042FFFF00021040008220213063FFFF2A +:105070000083182101031021ACA2001C8CC2000483 +:1050800034C60100ACC2001C240200020E000F5EF8 +:10509000A0C2000C104000478FBF00103C028000EF +:1050A0008C4401003C0380008C6201F80440FFFE48 +:1050B000240200020A00142D000000003467008062 +:1050C000ACE50038346601008CC2001C00A210233D +:1050D0001840000224A2FFFCACC2001C3082000178 +:1050E0005040000A3C0380088CE2003C00A21023E0 +:1050F00004430014240400058C62000414A200037D +:105100003C0380080A00141F240400058C6200047C +:1051100014A200288FBF00103C0208008C4200D867 +:10512000304200201040000A3C02800834620080B7 +:10513000906300089042004C144300053C02800834 +:10514000240400048FBF00100A00110927BD0018B5 +:105150003443008034420100A040000C24020001CE +:10516000A46200143C0280008C4401003C038000D7 +:105170008C6201F80440FFFE24020002AC6401C00E +:10518000A06201C43C021000AC6201F80A00143BAA +:105190008FBF00108FBF0010010030210A00115A8C +:1051A00027BD0018010030210A00129927BD001800 +:1051B0008FBF001003E0000827BD00183C038008E3 +:1051C0003464010024020003A082000C8C620004FD +:1051D00003E00008AC82001C3C05800834A300807A +:1051E0009062002734A501002406004324420001F8 +:1051F000A0620027906300273C0208008C42004810 +:10520000306300FF146200043C07602194A500EAAB +:105210000A00090130A5FFFF03E0000800000000BC +:1052200027BDFFE8AFBF00103C0280000E00144411 +:105230008C4401803C02800834430100A060000CD3 +:105240008C4200048FBF001027BD001803E0000847 +:10525000AC62001C27BDFFE03C028008AFBF001815 +:10526000AFB10014AFB000103445008034460100E7 +:105270003C0880008D09014090C3000C8CA4003CC8 +:105280008CA200381482003B306700FF9502007C3E +:1052900090A30027146000093045FFFF2402000599 +:1052A00054E200083C04800890C2000D2442000132 +:1052B000A0C2000D0A00147F3C048008A0C0000DAD +:1052C0003C048008348201009042000C2403000555 +:1052D000304200FF1443000A24A205DC348300801E +:1052E000906200272C4200075040000524A20A00CB +:1052F00090630027240200140062100400A2102111 +:105300003C108008361000803045FFFF012020212E +:105310000E001444A60500149602005C8E030038AB +:105320003C1180003042FFFF000210400062182153 +:10533000AE03001C0E0003328E24014092020025B1 +:1053400034420040A20200250E00033D8E2401409D +:105350008E2401403C0380008C6201F80440FFFE73 +:1053600024020002AC6401C0A06201C43C0210002F +:10537000AC6201F88FBF00188FB100148FB000101D +:1053800003E0000827BD00203C0360103C02080039 +:1053900024420174AC62502C8C6250003C048000AA +:1053A00034420080AC6250003C0208002442547C2D +:1053B0003C010800AC2256003C020800244254384C +:1053C0003C010800AC2256043C020002AC840008F8 +:1053D000AC82000C03E000082402000100A0302190 +:1053E0003C1C0800279C56083C0200023C050400B7 +:1053F00000852826008220260004102B2CA5000101 +:105400002C840001000210803C0308002463560035 +:105410000085202500431821108000030000102182 +:10542000AC6600002402000103E000080000000058 +:105430003C1C0800279C56083C0200023C05040066 +:1054400000852826008220260004102B2CA50001B0 +:105450002C840001000210803C03080024635600E5 +:105460000085202500431821108000050000102130 +:105470003C02080024425438AC62000024020001BF +:1054800003E00008000000003C0200023C030400AE +:1054900000821026008318262C4200012C63000194 +:1054A000004310251040000B000028213C1C080080 +:1054B000279C56083C0380008C62000824050001EC +:1054C00000431025AC6200088C62000C00441025DB +:1054D000AC62000C03E0000800A010213C1C080096 +:1054E000279C56083C0580008CA3000C0004202754 +:1054F000240200010064182403E00008ACA3000C9F +:105500003C020002148200063C0560008CA208D018 +:105510002403FFFE0043102403E00008ACA208D0DF +:105520003C02040014820005000000008CA208D098 +:105530002403FFFD00431024ACA208D003E00008C0 +:10554000000000003C02601A344200108C430080CE +:1055500027BDFFF88C440084AFA3000093A3000094 +:10556000240200041462001AAFA4000493A20001F4 +:105570001040000797A300023062FFFC3C0380004C +:10558000004310218C4200000A001536AFA200042F +:105590003062FFFC3C03800000431021AC4400005B +:1055A000A3A000003C0560008CA208D02403FFFEED +:1055B0003C04601A00431024ACA208D08FA300045E +:1055C0008FA2000034840010AC830084AC82008081 +:1055D00003E0000827BD000827BDFFE8AFBF0010AB +:1055E0003C1C0800279C56083C0280008C43000CA1 +:1055F0008C420004004318243C0200021060001496 +:10560000006228243C0204003C04000210A00005B3 +:10561000006210243C0208008C4256000A00155B10 +:1056200000000000104000073C0404003C02080099 +:105630008C4256040040F809000000000A00156082 +:10564000000000000000000D3C1C0800279C5608CC +:0C5650008FBF001003E0000827BD001809 +:04565C008008024080 +:1056600080080100800800808008000000000C8095 +:105670000000320008000E9808000EF408000F88A1 +:1056800008001028080010748008010080080080BD +:04569000800800008E +:0C5694000A0000280000000000000000D8 +:1056A0000000000D6370362E302E313700000000F0 +:1056B00006001104000000000000000000000000CF +:1056C000000000000000000038003C000000000066 +:1056D00000000000000000000000000000000020AA +:1056E00000000000000000000000000000000000BA +:1056F00000000000000000000000000000000000AA +:10570000000000000000000021003800000000013F +:105710000000002B000000000000000400030D400A +:105720000000000000000000000000000000000079 +:105730000000000000000000100000030000000056 +:105740000000000D0000000D3C020800244259AC8E +:105750003C03080024635BF4AC4000000043202BB2 +:105760001480FFFD244200043C1D080037BD9FFC4F +:1057700003A0F0213C100800261000A03C1C0800EB +:10578000279C59AC0E0002F6000000000000000D3E +:1057900027BDFFB4AFA10000AFA20004AFA3000873 +:1057A000AFA4000CAFA50010AFA60014AFA700185F +:1057B000AFA8001CAFA90020AFAA0024AFAB0028FF +:1057C000AFAC002CAFAD0030AFAE0034AFAF00389F +:1057D000AFB8003CAFB90040AFBC0044AFBF004819 +:1057E0000E000820000000008FBF00488FBC00445E +:1057F0008FB900408FB8003C8FAF00388FAE0034B7 +:105800008FAD00308FAC002C8FAB00288FAA002406 +:105810008FA900208FA8001C8FA700188FA6001446 +:105820008FA500108FA4000C8FA300088FA2000486 +:105830008FA1000027BD004C3C1B60188F7A5030B0 +:10584000377B502803400008AF7A000000A01821E1 +:1058500000801021008028213C0460003C0760008B +:105860002406000810600006348420788C42000072 +:10587000ACE220088C63000003E00008ACE3200CDD +:105880000A000F8100000000240300403C02600079 +:1058900003E00008AC4320003C0760008F86000452 +:1058A0008CE520740086102100A2182B14600007DC +:1058B000000028218F8AFDA024050001A1440013C7 +:1058C0008F89000401244021AF88000403E0000810 +:1058D00000A010218F84FDA08F8500049086001306 +:1058E00030C300FF00A31023AF82000403E00008D0 +:1058F000A08000138F84FDA027BDFFE8AFB000108B +:10590000AFBF001490890011908700112402002875 +:10591000312800FF3906002830E300FF2485002CE1 +:105920002CD00001106200162484001C0E00006EB2 +:10593000000000008F8FFDA03C05600024020204DF +:1059400095EE003E95ED003C000E5C0031ACFFFF93 +:10595000016C5025ACAA2010520000012402000462 +:10596000ACA22000000000000000000000000000C9 +:105970008FBF00148FB0001003E0000827BD00188F +:105980000A0000A6000028218F85FDA027BDFFD8B2 +:10599000AFBF0020AFB3001CAFB20018AFB100140E +:1059A000AFB000100080982190A4001124B0001C1A +:1059B00024B1002C308300FF386200280E000090D4 +:1059C0002C5200010E00009800000000020020216F +:1059D0001240000202202821000028210E00006E43 +:1059E000000000008F8DFDA03C0880003C05600099 +:1059F00095AC003E95AB003C02683025000C4C0095 +:105A0000316AFFFF012A3825ACA7201024020202C8 +:105A1000ACA6201452400001240200028FBF0020D7 +:105A20008FB3001C8FB200188FB100148FB000101C +:105A300027BD002803E00008ACA2200027BDFFE03E +:105A4000AFB20018AFB10014AFB00010AFBF001C70 +:105A50003C1160008E2320748F82000430D0FFFF41 +:105A600030F2FFFF1062000C2406008F0E00006E63 +:105A7000000000003C06801F0010440034C5FF00F9 +:105A80000112382524040002AE2720100000302126 +:105A9000AE252014AE2420008FBF001C8FB200184A +:105AA0008FB100148FB0001000C0102103E0000877 +:105AB00027BD002027BDFFE0AFB0001030D0FFFFB2 +:105AC000AFBF0018AFB100140E00006E30F1FFFF41 +:105AD00000102400009180253C036000AC70201071 +:105AE0008FBF00188FB100148FB000102402000483 +:105AF000AC62200027BD002003E000080000102158 +:105B000027BDFFE03C046018AFBF0018AFB1001420 +:105B1000AFB000108C8850002403FF7F34028071E6 +:105B20000103382434E5380C241F00313C1980006F +:105B3000AC8550003C11800AAC8253BCAF3F0008DA +:105B40000E00054CAF9100400E00050A3C116000AC +:105B50000E00007D000000008E3008083C0F570941 +:105B60002418FFF00218602435EEE00035EDF00057 +:105B7000018E5026018D58262D4600012D69000109 +:105B8000AF86004C0E000D09AF8900503C06601630 +:105B90008CC700003C0860148D0500A03C03FFFF8B +:105BA00000E320243C02535300052FC2108200550D +:105BB00034D07C00960201F2A780006C10400003F4 +:105BC000A780007C384B1E1EA78B006C960201F844 +:105BD000104000048F8D0050384C1E1EA78C007C96 +:105BE0008F8D005011A000058F83004C240E0020E3 +:105BF000A78E007CA78E006C8F83004C1060000580 +:105C00009785007C240F0020A78F007CA78F006C55 +:105C10009785007C2CB8008153000001240500808A +:105C20009784006C2C91040152200001240404008C +:105C30001060000B3C0260008FBF00188FB1001491 +:105C40008FB0001027BD0020A784006CA785007CC2 +:105C5000A380007EA780007403E00008A780009264 +:105C60008C4704382419103C30FFFFFF13F9000360 +:105C700030A8FFFF1100004624030050A380007EDF +:105C80009386007E50C00024A785007CA780007CFE +:105C90009798007CA780006CA7800074A780009272 +:105CA0003C010800AC3800800E00078700000000AF +:105CB0003C0F60008DED0808240EFFF03C0B600ED9 +:105CC000260C0388356A00100000482100002821B6 +:105CD00001AE20243C105709AF8C0010AF8A004859 +:105CE000AF89001810900023AF8500148FBF0018F3 +:105CF0008FB100148FB0001027BD002003E0000812 +:105D0000AF80005400055080014648218D260004D4 +:105D10000A00014800D180219798007CA784006C7C +:105D2000A7800074A78000923C010800AC38008076 +:105D30000E000787000000003C0F60008DED080892 +:105D4000240EFFF03C0B600E260C0388356A001011 +:105D5000000048210000282101AE20243C105709F2 +:105D6000AF8C0010AF8A0048AF8900181490FFDF95 +:105D7000AF85001424110001AF9100548FBF0018AB +:105D80008FB100148FB0001003E0000827BD002081 +:105D90000A00017BA383007E3083FFFF8F880040D1 +:105DA0008F87003C000321403C0580003C020050EE +:105DB000008248253C0660003C0A010034AC040027 +:105DC0008CCD08E001AA58241160000500000000F5 +:105DD0008CCF08E024E7000101EA7025ACCE08E092 +:105DE0008D19001001805821ACB900388D180014AD +:105DF000ACB8003CACA9003000000000000000007E +:105E00000000000000000000000000000000000092 +:105E100000000000000000003C0380008C640000D3 +:105E2000308200201040FFFD3C0F60008DED08E047 +:105E30003C0E010001AE18241460FFE100000000D8 +:105E4000AF87003C03E00008AF8B00588F8500400F +:105E5000240BFFF03C06800094A7001A8CA90024B4 +:105E600030ECFFFF000C38C000EB5024012A402129 +:105E7000ACC8003C8CA400248CC3003C00831023DD +:105E800018400033000000008CAD002025A2000166 +:105E90003C0F0050ACC2003835EE00103C068000CC +:105EA000ACCE003000000000000000000000000048 +:105EB00000000000000000000000000000000000E2 +:105EC000000000003C0480008C9900003338002062 +:105ED0001300FFFD30E20008104000173C0980006D +:105EE0008C880408ACA800108C83040CACA30014AC +:105EF0003C1900203C188000AF19003094AE001807 +:105F000094AF001C01CF3021A4A6001894AD001A54 +:105F100025A70001A4A7001A94AB001A94AC001E98 +:105F2000118B00030000000003E0000800000000E7 +:105F300003E00008A4A0001A8D2A0400ACAA0010F7 +:105F40008D240404ACA400140A0002183C1900209B +:105F50008CA200200A0002003C0F00500A0001EE53 +:105F60000000000027BDFFE8AFBF00100E000232A6 +:105F7000000000008F8900408FBF00103C038000AC +:105F8000A520000A9528000A9527000427BD0018BF +:105F90003105FFFF30E6000F0006150000A22025A6 +:105FA00003E00008AC6400803C0508008CA50020DC +:105FB0008F83000C27BDFFE8AFB00010AFBF001407 +:105FC00010A300100000802124040001020430040A +:105FD00000A6202400C3102450440006261000010F +:105FE000001018802787FDA41480000A006718217C +:105FF000261000012E0900025520FFF38F83000CAC +:10600000AF85000C8FBF00148FB0001003E00008B4 +:1060100027BD00188C6800003C058000ACA8002457 +:106020000E000234261000013C0508008CA500205B +:106030000A0002592E0900022405000100851804F7 +:106040003C0408008C84002027BDFFC8AFBF00348B +:1060500000831024AFBE0030AFB7002CAFB60028CD +:10606000AFB50024AFB40020AFB3001CAFB200182E +:10607000AFB1001410400051AFB000108F84004049 +:10608000948700069488000A00E8302330D5FFFF8B +:1060900012A0004B8FBF0034948B0018948C000A20 +:1060A000016C50233142FFFF02A2482B1520000251 +:1060B00002A02021004020212C8F000515E00002C5 +:1060C00000809821241300040E0001C102602021E9 +:1060D0008F87004002609021AF80004494F4000A52 +:1060E000026080211260004E3291FFFF3C1670006A +:1060F0003C1440003C1E20003C1760008F99005863 +:106100008F380000031618241074004F0283F82BF8 +:1061100017E0003600000000107E00478F86004424 +:1061200014C0003A2403000102031023022320219B +:106130003050FFFF1600FFF13091FFFF8F870040C6 +:106140003C1100203C108000AE11003094EB000A9E +:106150003C178000024B5021A4EA000A94E9000A8F +:1061600094E800043123FFFF3106000F00062D00E4 +:106170000065F025AEFE008094F3000A94F6001846 +:1061800012D30036001221408CFF00148CF4001052 +:1061900003E468210000C02101A4782B029870213B +:1061A00001CF6021ACED0014ACEC001002B238233A +:1061B00030F5FFFF16A0FFB88F8400408FBF00347A +:1061C0008FBE00308FB7002C8FB600288FB500240B +:1061D0008FB400208FB3001C8FB200188FB1001451 +:1061E0008FB0001003E0000827BD00381477FFCC03 +:1061F0008F8600440E000EE202002021004018218C +:106200008F86004410C0FFC9020310230270702360 +:106210008F87004001C368210A0002E431B2FFFF0A +:106220008F86004414C0FFC93C1100203C10800040 +:106230000A0002AEAE1100300E00046602002021FA +:106240000A0002DB00401821020020210E0009395B +:10625000022028210A0002DB004018210E0001EE76 +:10626000000000000A0002C702B2382327BDFFC8A1 +:10627000AFB7002CAFB60028AFB50024AFB40020F4 +:10628000AFB3001CAFB20018AFB10014AFB0001034 +:10629000AFBF00300E00011B241300013C047FFF40 +:1062A0003C0380083C0220003C010800AC20007048 +:1062B0003496FFFF34770080345200033C1512C03F +:1062C000241400013C1080002411FF800E000245C0 +:1062D000000000008F8700488F8B00188F89001402 +:1062E0008CEA00EC8CE800E8014B302B01092823F4 +:1062F00000A6102314400006014B18231440000E82 +:106300003C05800002A3602B1180000B0000000000 +:106310003C0560008CEE00EC8CED00E88CA4180CC1 +:10632000AF8E001804800053AF8D00148F8F0010C3 +:10633000ADF400003C0580008CBF00003BF900017B +:10634000333800011700FFE13C0380008C6201003C +:1063500024060C0010460009000000008C680100B3 +:106360002D043080548000103C0480008C690100B2 +:106370002D2331811060000C3C0480008CAA0100A8 +:1063800011460004000020218CA6010024C5FF81D5 +:1063900030A400FF8E0B01000E000269AE0B00243A +:1063A0000A00034F3C0480008C8D01002DAC3300AB +:1063B00011800022000000003C0708008CE70098D4 +:1063C00024EE00013C010800AC2E00983C04800043 +:1063D0008C8201001440000300000000566000148D +:1063E0003C0440008C9F01008C9801000000982123 +:1063F00003F1C82400193940330F007F00EF7025E6 +:1064000001D26825AC8D08308C8C01008C85010090 +:10641000258B0100017130240006514030A3007F1C +:106420000143482501324025AC8808303C04400037 +:10643000AE0401380A00030E000000008C99010030 +:10644000240F0020AC99002092F80000330300FFD5 +:10645000106F000C241F0050547FFFDD3C048000AF +:106460008C8401000E00154E000000000A00034F4E +:106470003C04800000963824ACA7180C0A000327BF +:106480008F8F00108C8501000E0008F72404008017 +:106490000A00034F3C04800000A4102B24030001D9 +:1064A00010400009000030210005284000A4102BF6 +:1064B00004A00003000318405440FFFC00052840DE +:1064C0005060000A0004182B0085382B54E00004AB +:1064D0000003184200C33025008520230003184222 +:1064E0001460FFF9000528420004182B03E000089F +:1064F00000C310213084FFFF30C600FF3C0780003E +:106500008CE201B80440FFFE00064C000124302557 +:106510003C08200000C820253C031000ACE00180AE +:10652000ACE50184ACE4018803E00008ACE301B809 +:106530003C0660008CC5201C2402FFF03083020062 +:10654000308601001060000E00A2282434A500014E +:106550003087300010E0000530830C0034A50004C3 +:106560003C04600003E00008AC85201C1060FFFDC7 +:106570003C04600034A5000803E00008AC85201C42 +:1065800054C0FFF334A500020A0003B03087300086 +:1065900027BDFFE8AFB00010AFBF00143C0760009C +:1065A000240600021080001100A080218F83005873 +:1065B0000E0003A78C6400188F8200580000202171 +:1065C000240600018C45000C0E000398000000001A +:1065D0001600000224020003000010218FBF0014E7 +:1065E0008FB0001003E0000827BD00188CE8201CC5 +:1065F0002409FFF001092824ACE5201C8F870058EE +:106600000A0003CD8CE5000C3C02600E00804021A6 +:1066100034460100240900180000000000000000BA +:10662000000000003C0A00503C0380003547020097 +:10663000AC68003834640400AC65003CAC670030E2 +:106640008C6C0000318B00201160FFFD2407FFFFE0 +:106650002403007F8C8D00002463FFFF248400044A +:10666000ACCD00001467FFFB24C60004000000004E +:10667000000000000000000024A402000085282B78 +:106680003C0300203C0E80002529FFFF010540212E +:10669000ADC300301520FFE00080282103E0000892 +:1066A000000000008F82005827BDFFD8AFB3001C48 +:1066B000AFBF0020AFB20018AFB10014AFB00010F0 +:1066C00094460002008098218C5200182CC300814F +:1066D0008C4800048C4700088C51000C8C49001039 +:1066E000106000078C4A00142CC4000414800013AE +:1066F00030EB000730C5000310A0001000000000C0 +:106700002410008B02002021022028210E00039873 +:10671000240600031660000224020003000010217A +:106720008FBF00208FB3001C8FB200188FB10014F0 +:106730008FB0001003E0000827BD00281560FFF1AE +:106740002410008B3C0C80003C030020241F00011F +:10675000AD830030AF9F0044000000000000000047 +:10676000000000002419FFF024D8000F031978243A +:106770003C1000D0AD88003801F0702524CD000316 +:106780003C08600EAD87003C35850400AD8E0030BE +:10679000000D38823504003C3C0380008C6B000007 +:1067A000316200201040FFFD0000000010E00008F2 +:1067B00024E3FFFF2407FFFF8CA800002463FFFFF2 +:1067C00024A50004AC8800001467FFFB24840004A7 +:1067D0003C05600EACA60038000000000000000080 +:1067E000000000008F8600543C0400203C0780001D +:1067F000ACE4003054C000060120202102402021DA +:106800000E0003A7000080210A00041D02002021C1 +:106810000E0003DD01402821024020210E0003A7C5 +:10682000000080210A00041D0200202127BDFFE096 +:10683000AFB200183092FFFFAFB10014AFBF001C21 +:10684000AFB000101640000D000088210A0004932C +:106850000220102124050003508500278CE5000C40 +:106860000000000D262800013111FFFF24E2002066 +:106870000232802B12000019AF8200588F82004430 +:10688000144000168F8700583C0670003C0320001F +:106890008CE5000000A62024148300108F84006083 +:1068A000000544023C09800000A980241480FFE90F +:1068B000310600FF2CCA000B5140FFEB26280001D7 +:1068C000000668803C0E080025CE575801AE6021B6 +:1068D0008D8B0000016000080000000002201021E4 +:1068E0008FBF001C8FB200188FB100148FB0001042 +:1068F00003E0000827BD00200E0003982404008454 +:106900001600FFD88F8700580A000474AF8000601B +:10691000020028210E0003BF240400018F870058C5 +:106920000A000474AF820060020028210E0003BF39 +:10693000000020210A0004A38F8700580E000404E1 +:10694000020020218F8700580A000474AF82006083 +:1069500030AFFFFF000F19C03C0480008C9001B8DD +:106960000600FFFE3C1920043C181000AC83018097 +:10697000AC800184AC990188AC9801B80A00047518 +:106980002628000190E2000390E30002000020218D +:106990000002FE0000033A0000FF2825240600083C +:1069A0000E000398000000001600FFDC2402000324 +:1069B0008F870058000010210A000474AF82006025 +:1069C00090E8000200002021240600090A0004C308 +:1069D00000082E0090E4000C240900FF308500FF21 +:1069E00010A900150000302190F9000290F8000372 +:1069F000308F00FF94EB000400196E000018740043 +:106A0000000F62000186202501AE5025014B28258C +:106A10003084FF8B0A0004C32406000A90E30002BE +:106A200090FF0004000020210003360000DF28252D +:106A30000A0004C32406000B0A0004D52406008BB8 +:106A4000000449C23127003F000443423C02800059 +:106A500000082040240316802CE60020AC43002CC4 +:106A600024EAFFE02482000114C0000330A900FFE3 +:106A700000801021314700FF000260803C0D800043 +:106A8000240A0001018D20213C0B000E00EA28049D +:106A9000008B302111200005000538278CCE000026 +:106AA00001C5382503E00008ACC700008CD8000001 +:106AB0000307782403E00008ACCF000027BDFFE007 +:106AC000AFB10014AFB00010AFBF00183C076000BA +:106AD0008CE408083402F0003C1160003083F000C0 +:106AE000240501C03C04800E000030211062000625 +:106AF000241000018CEA08083149F0003928E00030 +:106B00000008382B000780403C0D0200AE2D081411 +:106B1000240C16803C0B80008E2744000E000F8B47 +:106B2000AD6C002C120000043C02169124050001FB +:106B3000120500103C023D2C345800E0AE384408E9 +:106B40003C1108008E31007C8FBF00183C066000AD +:106B500000118540360F16808FB100148FB00010E1 +:106B60003C0E020027BD0020ACCF442003E000080B +:106B7000ACCE08103C0218DA345800E0AE384408B5 +:106B80003C1108008E31007C8FBF00183C0660006D +:106B900000118540360F16808FB100148FB00010A1 +:106BA0003C0E020027BD0020ACCF442003E00008CB +:106BB000ACCE08100A0004EB240500010A0004EB27 +:106BC0000000282124020400A7820024A780001CC2 +:106BD000000020213C06080024C65A582405FFFF67 +:106BE00024890001000440803124FFFF01061821A0 +:106BF0002C87002014E0FFFAAC6500002404040098 +:106C0000A7840026A780001E000020213C06080063 +:106C100024C65AD82405FFFF248D0001000460809B +:106C200031A4FFFF018658212C8A00201540FFFA6D +:106C3000AD650000A7800028A7800020A780002263 +:106C4000000020213C06080024C65B582405FFFFF5 +:106C5000249900010004C0803324FFFF030678213B +:106C60002C8E000415C0FFFAADE500003C05600065 +:106C70008CA73D002403E08F00E31024344601403C +:106C800003E00008ACA63D002487007F000731C266 +:106C900024C5FFFF000518C2246400013082FFFFF5 +:106CA000000238C0A78400303C010800AC27003047 +:106CB000AF80002C0000282100002021000030219E +:106CC0002489000100A728213124FFFF2CA81701E7 +:106CD000110000032C8300801460FFF924C600011A +:106CE00000C02821AF86002C10C0001DA786002AF6 +:106CF00024CAFFFF000A11423C08080025085B581F +:106D00001040000A00002021004030212407FFFF2E +:106D1000248E00010004688031C4FFFF01A86021B7 +:106D20000086582B1560FFFAAD87000030A2001FC7 +:106D30005040000800043080240300010043C804D0 +:106D400000041080004878212738FFFF03E0000886 +:106D5000ADF8000000C820212405FFFFAC8500002D +:106D600003E000080000000030A5FFFF30C6FFFF71 +:106D700030A8001F0080602130E700FF0005294295 +:106D80000000502110C0001D24090001240B000147 +:106D900025180001010B2004330800FF0126782686 +:106DA000390E00202DED00012DC2000101A2182591 +:106DB0001060000D014450250005C880032C4021BF +:106DC0000100182110E0000F000A20278D040000A8 +:106DD000008A1825AD03000024AD00010000402109 +:106DE0000000502131A5FFFF252E000131C9FFFF12 +:106DF00000C9102B1040FFE72518000103E0000830 +:106E0000000000008D0A0000014440240A0005D162 +:106E1000AC68000027BDFFE830A5FFFF30C6FFFFCC +:106E2000AFB00010AFBF001430E7FFFF00005021EB +:106E30003410FFFF0000602124AF001F00C0482174 +:106E4000241800012419002005E0001601E010219B +:106E50000002F943019F682A0009702B01AE40240B +:106E600011000017000C18800064102110E00005CC +:106E70008C4B000000F840040008382301675824B8 +:106E800000003821154000410000402155600016E7 +:106E90003169FFFF258B0001316CFFFF05E1FFEC3D +:106EA00001E0102124A2003E0002F943019F682A5C +:106EB0000009702B01AE40241500FFEB000C188078 +:106EC000154600053402FFFF020028210E0005B51B +:106ED00000003821020010218FBF00148FB0001075 +:106EE00003E0000827BD00181520000301601821E9 +:106EF000000B1C0224080010306A00FF154000053A +:106F0000306E000F250D000800031A0231A800FFA3 +:106F1000306E000F15C00005307F000325100004FF +:106F200000031902320800FF307F000317E000055C +:106F3000386900012502000200031882304800FF72 +:106F4000386900013123000110600004310300FFA3 +:106F5000250A0001314800FF310300FF000C6940A1 +:106F600001A34021240A000110CAFFD53110FFFF00 +:106F7000246E000131C800FF1119FFC638C9000195 +:106F80002D1F002053E0001C258B0001240D000163 +:106F90000A000648240E002051460017258B0001E8 +:106FA00025090001312800FF2D0900205120001281 +:106FB000258B000125430001010D5004014B1024D5 +:106FC000250900011440FFF4306AFFFF3127FFFF5D +:106FD00010EE000C2582FFFF304CFFFF0000502117 +:106FE0003410FFFF312800FF2D0900205520FFF24B +:106FF00025430001258B0001014648260A000602B0 +:10700000316CFFFF00003821000050210A000654B7 +:107010003410FFFF27BDFFD8AFB0001030F0FFFFE6 +:10702000AFB10014001039423211FFE000071080A8 +:10703000AFB3001C00B1282330D3FFFFAFB200185C +:1070400030A5FFFF00809021026030210044202104 +:10705000AFBF00200E0005E03207001F022288218A +:107060003403FFFF0240202102002821026030216A +:1070700000003821104300093231FFFF02201021A7 +:107080008FBF00208FB3001C8FB200188FB1001487 +:107090008FB0001003E0000827BD00280E0005E0B7 +:1070A0000000000000408821022010218FBF002036 +:1070B0008FB3001C8FB200188FB100148FB0001076 +:1070C00003E0000827BD0028000424003C03600002 +:1070D000AC603D0810A00002348210063482101605 +:1070E00003E00008AC623D0427BDFFE0AFB0001034 +:1070F000309000FF2E020006AFBF001810400008BD +:10710000AFB10014001030803C03080024635784A2 +:1071100000C328218CA400000080000800000000AB +:10712000000020218FBF00188FB100148FB0001015 +:107130000080102103E0000827BD00209791002A5D +:1071400016200051000020213C020800904200332C +:107150000A0006BB00000000978D002615A0003134 +:10716000000020210A0006BB2402000897870024A3 +:1071700014E0001A00001821006020212402000100 +:107180001080FFE98FBF0018000429C2004530219C +:1071900000A6582B1160FFE43C0880003C0720004B +:1071A000000569C001A76025AD0C00203C038008E4 +:1071B0002402001F2442FFFFAC6000000441FFFDD9 +:1071C0002463000424A5000100A6702B15C0FFF560 +:1071D000000569C00A0006A58FBF00189787001C2C +:1071E0003C04080024845A58240504000E0006605C +:1071F00024060001978B002424440001308AFFFFFD +:107200002569FFFF2D48040000402821150000409B +:10721000A789002424AC3800000C19C00A0006B964 +:10722000A780001C9787001E3C04080024845AD8BD +:10723000240504000E00066024060001979900262C +:10724000244400013098FFFF272FFFFF2F0E04007A +:107250000040882115C0002CA78F0026A780001EA3 +:107260003A020003262401003084FFFF0E00068D41 +:107270002C4500010011F8C027F00100001021C0CA +:107280000A0006BB240200089785002E978700227B +:107290003C04080024845B580E00066024060001AC +:1072A0009787002A8F89002C2445000130A8FFFF12 +:1072B00024E3FFFF0109302B0040802114C0001897 +:1072C000A783002AA7800022978500300E000F7543 +:1072D00002002021244A05003144FFFF0E00068DE4 +:1072E000240500013C05080094A500320E000F752E +:1072F00002002021244521003C0208009042003376 +:107300000A0006BB000521C00A0006F3A784001E80 +:1073100024AC3800000C19C00A0006B9A784001C70 +:107320000A00070DA7850022308400FF27BDFFE873 +:107330002C820006AFBF0014AFB000101040001543 +:1073400000A03821000440803C0308002463579CBF +:10735000010328218CA40000008000080000000028 +:1073600024CC007F000751C2000C59C23170FFFFCE +:107370002547C40030E5FFFF2784001C02003021B0 +:107380000E0005B52407000197860028020620217B +:10739000A78400288FBF00148FB0001003E00008FE +:1073A00027BD00183C0508008CA50030000779C2F5 +:1073B0000E00038125E4DF003045FFFF3C04080098 +:1073C00024845B58240600010E0005B52407000143 +:1073D000978E002A8FBF00148FB0001025CD0001BA +:1073E00027BD001803E00008A78D002A0007C9C2C6 +:1073F0002738FF00001878C231F0FFFF3C04080076 +:1074000024845AD802002821240600010E0005B564 +:1074100024070001978D0026260E0100000E84002F +:1074200025AC00013C0B6000A78C0026AD603D0838 +:1074300036040006000030213C0760008CE23D0469 +:10744000305F000617E0FFFD24C9000100061B00A5 +:10745000312600FF006440252CC50004ACE83D0443 +:1074600014A0FFF68FBF00148FB0001003E00008D7 +:1074700027BD0018000751C22549C8002406000195 +:10748000240700013C04080024845A580E0005B566 +:107490003125FFFF978700248FBF00148FB00010A5 +:1074A00024E6000127BD001803E00008A786002499 +:1074B0003C0660183C090800252900FCACC9502C8A +:1074C0008CC850003C0580003C020002350700805B +:1074D000ACC750003C04080024841FE03C030800B3 +:1074E00024631F98ACA50008ACA2000C3C01080066 +:1074F000AC2459A43C010800AC2359A803E00008BF +:107500002402000100A030213C1C0800279C59AC3B +:107510003C0C04003C0B0002008B3826008C4026FB +:107520002CE200010007502B2D050001000A4880C5 +:107530003C030800246359A4004520250123182199 +:107540001080000300001021AC660000240200013E +:1075500003E00008000000003C1C0800279C59AC18 +:107560003C0B04003C0A0002008A3026008B3826BF +:107570002CC200010006482B2CE5000100094080C8 +:107580003C030800246359A4004520250103182169 +:1075900010800005000010213C0C0800258C1F986D +:1075A000AC6C00002402000103E0000800000000B1 +:1075B0003C0900023C080400008830260089382677 +:1075C0002CC30001008028212CE400010083102539 +:1075D0001040000B000030213C1C0800279C59ACD7 +:1075E0003C0A80008D4E00082406000101CA68256F +:1075F000AD4D00088D4C000C01855825AD4B000C9D +:1076000003E0000800C010213C1C0800279C59AC76 +:107610003C0580008CA6000C0004202724020001F9 +:1076200000C4182403E00008ACA3000C3C020002D4 +:107630001082000B3C0560003C070400108700032B +:107640000000000003E00008000000008CA908D042 +:10765000240AFFFD012A402403E00008ACA808D05A +:107660008CA408D02406FFFE0086182403E000083E +:10767000ACA308D03C05601A34A600108CC300806F +:1076800027BDFFF88CC50084AFA3000093A40000C1 +:107690002402001010820003AFA5000403E00008DC +:1076A00027BD000893A7000114E0001497AC000266 +:1076B00097B800023C0F8000330EFFFC01CF682119 +:1076C000ADA50000A3A000003C0660008CC708D058 +:1076D0002408FFFE3C04601A00E82824ACC508D04A +:1076E0008FA300048FA200003499001027BD00086A +:1076F000AF22008003E00008AF2300843C0B800031 +:10770000318AFFFC014B48218D2800000A00080C3B +:10771000AFA8000427BDFFE8AFBF00103C1C080065 +:10772000279C59AC3C0580008CA4000C8CA2000462 +:107730003C0300020044282410A0000A00A31824DF +:107740003C0604003C0400021460000900A610245A +:107750001440000F3C0404000000000D3C1C080015 +:10776000279C59AC8FBF001003E0000827BD00180C +:107770003C0208008C4259A40040F80900000000B7 +:107780003C1C0800279C59AC0A0008358FBF00102C +:107790003C0208008C4259A80040F8090000000093 +:1077A0000A00083B000000003C0880008D0201B880 +:1077B0000440FFFE35090180AD2400003C031000A9 +:1077C00024040040AD250004A1240008A1260009DE +:1077D000A527000A03E00008AD0301B83084FFFFCD +:1077E0000080382130A5FFFF000020210A00084555 +:1077F000240600803087FFFF8CA400002406003898 +:107800000A000845000028218F8300788F860070C9 +:107810001066000B008040213C07080024E75B68ED +:10782000000328C000A710218C440000246300013D +:10783000108800053063000F5466FFFA000328C06B +:1078400003E00008000010213C07080024E75B6CFF +:1078500000A7302103E000088CC200003C03900028 +:1078600034620001008220253C038000AC640020CB +:107870008C65002004A0FFFE0000000003E000086B +:10788000000000003C0280003443000100832025FA +:1078900003E00008AC44002027BDFFE0AFB10014B6 +:1078A0003091FFFFAFB00010AFBF001812200013DF +:1078B00000A080218CA20000240400022406020003 +:1078C0001040000F004028210E0007250000000096 +:1078D00000001021AE000000022038218FBF0018E8 +:1078E0008FB100148FB0001000402021000028212B +:1078F000000030210A00084527BD00208CA20000AE +:10790000022038218FBF00188FB100148FB00010F3 +:107910000040202100002821000030210A000845F5 +:1079200027BD002000A010213087FFFF8CA5000498 +:107930008C4400000A000845240600068F83FD9C45 +:1079400027BDFFE8AFBF0014AFB00010906700087C +:10795000008010210080282130E600400000202116 +:1079600010C000088C5000000E0000BD0200202155 +:10797000020020218FBF00148FB000100A000548BC +:1079800027BD00180E0008A4000000000E0000BD76 +:1079900002002021020020218FBF00148FB00010B0 +:1079A0000A00054827BD001827BDFFE0AFB0001052 +:1079B0008F90FD9CAFBF001CAFB20018AFB1001498 +:1079C00092060001008088210E00087230D2000467 +:1079D00092040005001129C2A6050000348300406E +:1079E000A20300050E00087C022020210E00054A9B +:1079F0000220202124020001AE02000C02202821D6 +:107A0000A602001024040002A602001224060200AE +:107A1000A60200140E000725A60200161640000F4D +:107A20008FBF001C978C00743C0B08008D6B007896 +:107A30002588FFFF3109FFFF256A0001012A382B45 +:107A400010E00006A78800743C0F6006240E0016A4 +:107A500035ED0010ADAE00508FBF001C8FB2001886 +:107A60008FB100148FB0001003E0000827BD002084 +:107A700027BDFFE0AFB10014AFBF0018AFB00010DA +:107A80001080000400A088212402008010820007DA +:107A9000000000000000000D8FBF00188FB100141F +:107AA0008FB0001003E0000827BD00200E00087210 +:107AB00000A020218F86FD9C0220202190C500057A +:107AC0000E00087C30B000FF2403003E1603FFF1D7 +:107AD0003C0680008CC401780480FFFE34C801405D +:107AE000240900073C071000AD11000002202021EE +:107AF000A10900048FBF00188FB100148FB00010CF +:107B0000ACC701780A0008C527BD002027BDFFE0EB +:107B1000AFB00010AFBF0018AFB100143C10800030 +:107B20008E110020000000000E00054AAE04002067 +:107B3000AE1100208FBF00188FB100148FB000105D +:107B400003E0000827BD00203084FFFF00803821BB +:107B50002406003500A020210A0008450000282145 +:107B60003084FFFF008038212406003600A0202149 +:107B70000A0008450000282127BDFFD0AFB500242A +:107B80003095FFFFAFB60028AFB40020AFBF002C88 +:107B9000AFB3001CAFB20018AFB10014AFB000100B +:107BA00030B6FFFF12A000270000A0218F920058DE +:107BB0008E4300003C0680002402004000033E0289 +:107BC00000032C0230E4007F006698241482001D1C +:107BD00030A500FF8F8300682C68000A1100001098 +:107BE0008F8D0044000358803C0C0800258C57B84A +:107BF000016C50218D4900000120000800000000A8 +:107C000002D4302130C5FFFF0E0008522404008446 +:107C1000166000028F920058AF8000688F8D00447C +:107C20002659002026980001032090213314FFFFDD +:107C300015A00004AF9900580295202B1480FFDC9A +:107C400000000000028010218FBF002C8FB600289A +:107C50008FB500248FB400208FB3001C8FB20018A2 +:107C60008FB100148FB0001003E0000827BD003072 +:107C70002407003414A70149000000009247000EB9 +:107C80008F9FFDA08F90FD9C24181600A3E700197C +:107C90009242000D3C0880003C07800CA3E20018D3 +:107CA000964A00123C0D60003C117FFFA60A005C62 +:107CB000964400103623FFFF240200053099FFFF91 +:107CC000AE1900548E46001CAD1800288CEF000041 +:107CD0008DAE444801E6482601C93021AE06003881 +:107CE0008E05003824CB00013C0E7F00AE05003C21 +:107CF0008E0C003CAFEC0004AE0B00208E13002075 +:107D0000AE13001CA3E0001BAE03002CA3E2001284 +:107D10008E4A001424130050AE0A00348E0400343E +:107D2000AFE400148E590018AE1900489258000CA8 +:107D3000A218004E920D000835AF0020A20F0008D7 +:107D40008E090018012E282434AC4000AE0C001817 +:107D5000920B0000317200FF1253027F2403FF8058 +:107D60003C04080024845BE80E0008AA0000000020 +:107D70003C1108008E315BE80E00087202202021C1 +:107D80002405000424080001A2050025022020216A +:107D90000E00087CA20800053C0580008CB001782C +:107DA0000600FFFE8F92005834AE0140240F0002FF +:107DB0003C091000ADD10000A1CF0004ACA90178AE +:107DC0000A000962AF8000682CAD003751A0FF9413 +:107DD0008F8D0044000580803C110800263157E05B +:107DE000021178218DEE000001C0000800000000A3 +:107DF0002411000414B1008C3C0780003C080800EA +:107E00008D085BE88F86FD9CACE800208E4500085D +:107E10008F99FDA0240D0050ACC500308E4C000899 +:107E2000ACCC00508E4B000CACCB00348E43001019 +:107E3000ACC300388E4A0010ACCA00548E42001405 +:107E4000ACC2003C8E5F0018AF3F00048E50001C97 +:107E5000ACD0002090C40000309800FF130D024AFF +:107E6000000000008CC400348CD00030009030231F +:107E700004C000F12404008C126000EE2402000310 +:107E80000A000962AF8200682419000514B900666F +:107E90003C0580003C0808008D085BE88F86FD9C4F +:107EA000ACA800208E4C00048F8AFDA0240720007F +:107EB000ACCC001C924B000824120008A14B001906 +:107EC0008F82005890430009A14300188F85005805 +:107ED00090BF000A33E400FF1092001028890009C7 +:107EE000152000BA240E0002240D0020108D000B76 +:107EF000340780002898002117000008240740005C +:107F000024100040109000053C0700012419008057 +:107F1000109900023C070002240740008CC20018A0 +:107F20003C03FF00004350240147F825ACDF001854 +:107F300090B2000BA0D200278F8300589464000CED +:107F4000108001FE000000009467000C3C1F8000C0 +:107F50002405FFBFA4C7005C9063000E2407000443 +:107F6000A0C300088F820058904A000FA0CA0009E1 +:107F70008F8900588D3200108FE400740244C823AA +:107F8000ACD900588D300014ACD0002C95380018B6 +:107F9000330DFFFFACCD00409531001A322FFFFFAB +:107FA000ACCF00448D2E001CACCE00489128000EB2 +:107FB000A0C8000890CC000801855824126001B6C2 +:107FC000A0CB00088F9200580A000962AF870068B2 +:107FD0002406000614A600143C0E80003C0F080086 +:107FE0008DEF5BE88F85FD98ADCF00208E4900189E +:107FF0008F86FD9C8F8BFDA0ACA900008CC800383B +:1080000024040005ACA800048CCC003C1260008164 +:10801000AD6C00000A000962AF84006824110007FB +:1080200010B1004B240400063C05080024A55BE8C1 +:108030000E000881240400818F9200580013102B39 +:108040000A000962AF820068241F002314BFFFF6F4 +:108050003C0C80003C0508008CA55BE88F8BFDA0E4 +:10806000AD8500208F91FD9C8E4600042564002084 +:1080700026450014AE260028240600030E000F81BA +:10808000257000308F87005802002021240600034D +:108090000E000F8124E500083C04080024845BE8FE +:1080A0000E0008AA0000000092230000240A0050DD +:1080B000306200FF544AFFE18F9200580E000F6CAF +:1080C000000000000A000A6A8F920058240800335A +:1080D00014A800323C0380003C1108008E315BE89C +:1080E0008F8FFDA0AC7100208E420008240D002867 +:1080F0008F89FD9CADE200308E4A000C24060009F9 +:10810000ADEA00348E5F0010ADFF00388E440014DD +:10811000ADE400208E590018ADF900248E58001CE3 +:10812000ADF80028A1ED00118E4E00041260003160 +:10813000AD2E00288F9200580A000962AF860068B1 +:10814000240D002214ADFFB8000000002404000735 +:108150003C1008008E105BE83C188000AF10002037 +:108160005660FEAEAF8400683C04080024845BE8DF +:108170000E0008AA241300508F84FD9C90920000EA +:10818000325900FF1333014B000000008F9200585A +:10819000000020210A000962AF8400683C05080045 +:1081A00024A55BE80E000858240400810A000A6A2E +:1081B0008F92005802D498213265FFFF0E000852BA +:1081C000240400840A0009628F920058108EFF5325 +:1081D000240704002887000310E00179241100041B +:1081E000240F0001548FFF4D240740000A000A228B +:1081F000240701003C05080024A55BE80E0008A444 +:10820000240400828F920058000030210A00096285 +:10821000AF8600683C04080024845BE88CC2003808 +:108220000E0008AA8CC3003C8F9200580A000AC0B6 +:1082300000002021240400823C05080024A55BE8FE +:108240000E0008A4000000008F92005800001021CA +:108250000A000962AF8200688E5000048F91FD9C75 +:108260003C078000ACF00020922C00050200282181 +:10827000318B0002156001562404008A8F92FDA004 +:108280002404008D9245001B30A6002014C001502C +:1082900002002821922E00092408001231C900FF93 +:1082A0001128014B240400810E00087202002021D5 +:1082B0009258001B240F000402002021370D0042B9 +:1082C000A24D001B0E00087CA22F00253C0580005B +:1082D0008CA401780480FFFE34B90140241F000201 +:1082E000AF300000A33F00048F9200583C101000F4 +:1082F000ACB001780A000A6B0013102B8E500004FA +:108300008F91FD9C3C038000AC700020922A0005F8 +:108310000200282131420002144000172404008A80 +:10832000922C00092412000402002821318B00FF46 +:1083300011720011240400810E0008720200202135 +:108340008F89FDA0240800122405FFFE912F001B39 +:108350000200202135EE0020A12E001BA2280009DA +:108360009226000500C538240E00087CA2270005CF +:1083700002002821000020210E0009330000000027 +:108380000A000A6A8F9200588E4C00043C07800055 +:108390003C10080026105BE8ACEC00203C01080013 +:1083A000AC2C5BE8924B0003317100041220013BBE +:1083B0008F84FD9C24020006A0820009924F001BBE +:1083C000240EFFC031E9003F012E4025A08800089F +:1083D0009245000330A6000114C0013200000000E5 +:1083E0008E420008AE0200083C0208008C425BF09E +:1083F000104001318F90FDA0000219C28F8DFD9CAD +:10840000A603000C8E4A000C24180001240400145A +:10841000AE0A002C8E420010AE02001C965F0016C1 +:10842000A61F003C96590014A619003EADB8000CDA +:10843000A5B80010A5B80012A5B80014A5B800167C +:1084400012600144A2040011925100033232000272 +:108450002E5300018F920058266200080A0009621C +:10846000AF8200688E4400043C1980003C068008FE +:10847000AF2400208E45000890D80000240D005045 +:10848000331100FF122D009C2407008824060009E8 +:108490000E000845000000000A000A6A8F9200588A +:1084A0008E5000043C0980003C118008AD30002053 +:1084B0009228000024050050310400FF10850110AF +:1084C0002407008802002021000028210E00084512 +:1084D0002406000E922D00002418FF80020028219F +:1084E00001B8802524040004240600300E0007256E +:1084F000A23000000A000A6A8F9200588E500004D1 +:108500008F91FDA03C028000AC500020923F001BE8 +:1085100033F900101320006C240700810200202191 +:10852000000028212406001F0E000845000000005E +:108530000A000A6A8F9200588E44001C0E00085DE3 +:1085400000000000104000E3004048218F880058E0 +:1085500024070089012020218D05001C240600012C +:108560000E000845000000000A000A6A8F920058B9 +:10857000964900023C10080026105BE831280004F0 +:10858000110000973C0460008E4E001C3C0F8000E0 +:10859000ADEE00203C010800AC2E5BE896470002DF +:1085A00030E40001148000E6000000008E42000468 +:1085B000AE0200083C1008008E105BF0120000ECC8 +:1085C0003C0F80008F92FD9C241000018E4E0018FD +:1085D0008F8DFDA08F9FFD9801CF4825AE490018D3 +:1085E000A2400005AE50000C3C0808008D085BF06E +:1085F0008F840058A6500010000839C2A6500012FF +:10860000A6500014A6500016A5A7000C8C8C0008DC +:108610008F8B00588F8A0058ADAC002C8D63000CF6 +:1086200024070002ADA3001C91460010A1A6001172 +:108630008F82005890450011A3E500088F990058DB +:1086400093380012A258004E8F910058922F0013B9 +:10865000A1AF00128F920058964E0014A5AE003CB8 +:1086600096490016A5A9003E8E480018ADA8001432 +:108670005660FD6AAF8700683C05080024A55BE8EA +:108680000E000881000020218F9200580000382140 +:108690000A000962AF8700683C05080024A55BE872 +:1086A0000E0008A4240400828F9200580A000A4D8C +:1086B000000038210E000F6C000000008F9200585F +:1086C0000A000AC0000020210E00087202002021CA +:1086D0009223001B02002021346A00100E00087C47 +:1086E000A22A001B000038210200202100002821BE +:1086F0000A000BA52406001F9242000C305F000107 +:1087000013E0000300000000964A000EA4CA002CEB +:10871000924B000C316300025060000600003821CB +:108720008E470014964C0012ACC7001CA4CC001A53 +:10873000000038210A000B7F240600093C050800D0 +:1087400024A55BE80E0008A42404008B8F92005837 +:108750000A000A4D0013382B3C0C08008D8C5BE896 +:1087600024DFFFFE25930100326B007F016790211B +:1087700002638824AD110028AE4600E0AE4000E45C +:108780000A0009B3AE5F001CACC000543C0D0800E9 +:108790008DAD5BE83C18800C37090100ACED00287A +:1087A0008E510014AD3100E08E4F0014AD2F00E467 +:1087B0008E4E001025C7FFFE0A0009F4AD27001CED +:1087C0005491FDD6240740000A000A222407100015 +:1087D0000E00092D000000000A000A6A8F9200585E +:1087E0008C83442C3C12DEAD3651BEEF3C010800B8 +:1087F000AC205BE810710062000000003C196C6264 +:1088000037387970147800082404000297850074C2 +:108810009782006C2404009200A2F82B13E0001948 +:1088200002002821240400020E00069524050200FF +:108830003C068000ACC200203C010800AC225BE892 +:108840001040000D8F8C0058240A002824040003D7 +:10885000918B0010316300FF546A00012404000171 +:108860000E0000810000000010400004240400837A +:108870000A000BC28F920058240400833C050800B4 +:1088800024A55BE80E000881000000008F920058CC +:108890000013382B0A000962AF8700680A000B49F1 +:1088A000240200128E4400080E00085D0000000043 +:1088B0000A000B55AE0200083C05080024A55BE841 +:1088C0000E000858240400878F9200580A000B728B +:1088D0000013102B240400040E000695240500301C +:1088E0001440002A004048218F8800582407008344 +:1088F000012020218D05001C0A000BB32406000175 +:108900008F8300788F8600701066FEEE000038219D +:108910003C07080024E75B6C000320C00087282187 +:108920008CAE000011D0005D246F000131E3000F18 +:108930005466FFFA000320C00A000B8C00003821A7 +:108940008E4400040E00085D000000000A000BC801 +:10895000AE0200083C05080024A55BE80E0008A450 +:10896000240400828F9200580A000B72000010212C +:108970003C05080024A55BE80A000C7C2404008761 +:108980008C83442C0A000C5B3C196C628F88005865 +:108990003C0780083C0C8000240B0050240A000196 +:1089A000AD820020A0EB0000A0EA000191030004CA +:1089B000A0E3001891040005A0E400199106000648 +:1089C0003C04080024845B6CA0E6001A91020007B6 +:1089D0003C06080024C65B68A0E2001B9105000865 +:1089E000A0E5001C911F0009A0FF001D9119000ABD +:1089F000A0F9001E9118000BA0F8001F9112000CA6 +:108A0000A0F200209111000DA0F100219110000EA4 +:108A1000A0F00022910F000FA0EF0023910E001094 +:108A2000A0EE0024910D0011A0ED0025950C00147E +:108A3000A4EC0028950B00168F8A00708F920078A6 +:108A4000A4EB002A95030018000A10C02545000178 +:108A5000A4E3002C8D1F001C0044C0210046C82147 +:108A600030A5000FAF3F0000AF09000010B20006B4 +:108A7000AF850070000038218D05001C01202021E9 +:108A80000A000BB32406000124AD000131A7000F3A +:108A9000AF8700780A000CF9000038213C06080076 +:108AA00024C65B680086902100003821ACA000003D +:108AB0000A000B8CAE4000003C0482013C036000C5 +:108AC00034820E02AC603D68AF80009803E000087D +:108AD000AC623D6C27BDFFE8AFB000103090FFFFE7 +:108AE000001018422C620041AFBF00141440000275 +:108AF00024040080240300403C010800AC300060E6 +:108B00003C010800AC2300640E000F7500602821B2 +:108B1000244802BF2409FF8001092824001039805D +:108B2000001030408FBF00148FB0001000A720212C +:108B300000861821AF8300803C010800AC25005856 +:108B40003C010800AC24005C03E0000827BD0018CD +:108B5000308300FF30C6FFFF30E400FF3C08800098 +:108B60008D0201B80440FFFE000354000144382583 +:108B70003C09600000E920253C031000AD050180A0 +:108B8000AD060184AD04018803E00008AD0301B81F +:108B90008F8500583C0A6012354800108CAC0004E8 +:108BA0003C0D600E35A60010318B00062D690001CA +:108BB000AD0900C48CA70004ACC731808CA20008AA +:108BC00094A40002ACC231848CA3001C0460000396 +:108BD000A784009003E00008000000008CAF00189C +:108BE000ACCF31D08CAE001C03E00008ACCE31D449 +:108BF0008F8500588F87FF288F86FF308CAE00044A +:108C00003C0F601235E80010ACEE00788CAD000827 +:108C1000ACED007C8CAC0010ACCC004C8CAB000CF0 +:108C2000ACCB004894CA00543C0208008C4200447B +:108C300025490001A4C9005494C400543083FFFFA7 +:108C400010620017000000003C0208008C42004047 +:108C5000A4C200528CA30018ACE300308CA2001414 +:108C6000ACE2002C8CB90018ACF900388CB80014B8 +:108C700024050001ACF800348D0600BC50C5001975 +:108C80008D0200B48D0200B8A4E2004894E40048CC +:108C9000A4E4004A94E800EA03E000083102FFFF80 +:108CA0003C0208008C420024A4C00054A4C200521C +:108CB0008CA30018ACE300308CA20014ACE2002CB2 +:108CC0008CB90018ACF900388CB8001424050001E8 +:108CD000ACF800348D0600BC54C5FFEB8D0200B823 +:108CE0008D0200B4A4E2004894E40048A4E4004AE1 +:108CF00094E800EA03E000083102FFFF8F86005885 +:108D00003C0480008CC900088CC80008000929C0F8 +:108D1000000839C0AC87002090C30007306200040F +:108D20001040003EAF85009490CB0007316A0008E8 +:108D30001140003D8F87FF2C8CCD000C8CCE001491 +:108D400001AE602B11800036000000008CC2000CC8 +:108D5000ACE200708CCB00188F85FF288F88FF3025 +:108D6000ACEB00748CCA00102402FFF8ACAA00D847 +:108D70008CC9000CAD0900608CC4001CACA400D0F0 +:108D800090E3007C0062C824A0F9007C90D8000722 +:108D9000330F000811E000040000000090ED007C9B +:108DA00035AC0001A0EC007C90CF000731EE000153 +:108DB00011C000060000000090E3007C241800347D +:108DC00034790002A0F9007CACB800DC90C2000746 +:108DD0003046000210C000040000000090E8007C53 +:108DE00035040004A0E4007C90ED007D3C0B600E97 +:108DF000356A001031AC003FA0EC007D8D4931D4C4 +:108E00003127000110E00002240E0001A0AE00098D +:108E100094AF00EA03E0000831E2FFFF8F87FF2CE8 +:108E20000A000DAF8CC200140A000DB0ACE0007057 +:108E30008F8C005827BDFFD8AFB3001CAFB200180D +:108E4000AFB00010AFBF0020AFB10014918F00157C +:108E50003C13600E3673001031EB000FA38B009CA7 +:108E60008D8F00048D8B0008959F0012959900103E +:108E70009584001A9598001E958E001C33EDFFFF17 +:108E8000332AFFFF3089FFFF3308FFFF31C7FFFFA1 +:108E90003C010800AC2D00243C010800AC29004432 +:108EA0003C010800AC2A0040AE683178AE67317CE6 +:108EB00091850015959100163C12601236520010F3 +:108EC00030A200FF3230FFFFAE623188AE5000B4F6 +:108ED00091830014959F0018240600010066C804C1 +:108EE00033F8FFFFAE5900B8AE5800BC918E0014A5 +:108EF000AF8F00843C08600631CD00FFAE4D00C04E +:108F0000918A00159584000E3C07600A314900FFE4 +:108F1000AF8B00883084FFFFAE4900C835110010C8 +:108F20000E000D1034F004103C0208008C4200606A +:108F30003C0308008C6300643C0608008CC60058A3 +:108F40003C0508008CA5005C8F8400808FBF00204A +:108F5000AE23004CAE65319CAE030054AE4500DC40 +:108F6000AE6231A0AE6331A4AE663198AE22004845 +:108F70008FB3001CAE0200508FB10014AE4200E06F +:108F8000AE4300E4AE4600D88FB000108FB2001898 +:108F90000A00057D27BD0028978500929783007CF5 +:108FA00027BDFFE8AFB0001000A3102BAFBF001427 +:108FB000240400058F900058104000552409000239 +:108FC0000E0006958F850080AF8200942404000374 +:108FD0001040004F240900023C0680000E00008172 +:108FE000ACC2002024070001240820001040004DDE +:108FF00024040005978E00928F8AFF2C24090050CC +:1090000025C50001A7850092A14900003C0D08007C +:109010008DAD0064240380008F84FF28000D66005E +:10902000AD4C0018A5400006954B000A8F85FF3017 +:109030002402FF8001633024A546000A915F000AE4 +:109040000000482103E2C825A159000AA0A0000899 +:10905000A140004CA08000D5961800029783009094 +:109060003C020004A49800EA960F00022418FFBFF7 +:1090700025EE2401A48E00BE8E0D0004ACAD00448C +:109080008E0C0008ACAC0040A4A00050A4A000547A +:109090008E0B000C240C0030AC8B00288E060010C8 +:1090A000AC860024A480003EA487004EA487005014 +:1090B000A483003CAD420074AC8800D8ACA800602A +:1090C000A08700FC909F00D433F9007FA09900D4C2 +:1090D000909000D402187824A08F00D4914E007C88 +:1090E00035CD0001A14D007C938B009CAD480070F4 +:1090F000AC8C00DCA08B00D68F8800888F87008422 +:10910000AC8800C4AC8700C8A5400078A540007AB0 +:109110008FBF00148FB000100120102103E0000861 +:1091200027BD00188F8500940E0007258F860080CC +:109130000A000E9F2409000227BDFFE0AFB0001017 +:109140008F900058AFB10014AFBF00188E09000413 +:109150000E00054A000921C08E0800048F84FF28F4 +:109160008F82FF30000839C03C068000ACC7002069 +:10917000948500EA904300131460001C30B1FFFF97 +:109180008F8CFF2C918B0008316A00401540000B3A +:10919000000000008E0D0004022030218FBF001857 +:1091A0008FB100148FB00010240400220000382179 +:1091B000000D29C00A000D2F27BD00200E000098C9 +:1091C000000000008E0D0004022030218FBF001827 +:1091D0008FB100148FB00010240400220000382149 +:1091E000000D29C00A000D2F27BD00200E000090A1 +:1091F000000000008E0D0004022030218FBF0018F7 +:109200008FB100148FB00010240400220000382118 +:10921000000D29C00A000D2F27BD002027BDFFE04B +:10922000AFB200183092FFFFAFB00010AFBF001C0C +:10923000AFB100141240001E000080218F8600583C +:109240008CC500002403000600053F02000514023F +:1092500030E4000714830016304500FF2CA80006F8 +:1092600011000040000558803C0C0800258C58BCBB +:10927000016C50218D490000012000080000000011 +:109280008F8E0098240D000111CD005024020002A1 +:10929000AF820098260900013130FFFF24C800206A +:1092A0000212202B010030211480FFE5AF88005806 +:1092B000020010218FBF001C8FB200188FB1001464 +:1092C0008FB0001003E0000827BD00209387007EC8 +:1092D00054E00034000030210E000DE700000000D3 +:1092E0008F8600580A000EFF240200018F87009825 +:1092F0002405000210E50031240400130000282199 +:1093000000003021240700010E000D2F0000000096 +:109310000A000F008F8600588F83009824020002F5 +:109320001462FFF6240400120E000D9A00000000E3 +:109330008F85009400403021240400120E000D2F70 +:10934000000038210A000F008F8600588F83009894 +:109350002411000310710029241F0002107FFFCE8A +:1093600026090001240400100000282100003021FB +:109370000A000F1D240700018F91009824060002A7 +:109380001626FFF9240400100E000E410000000014 +:10939000144000238F9800588F8600580A000EFF53 +:1093A00024020003240400140E000D2F00002821C5 +:1093B0008F8600580A000EFF240200020E000EA93C +:1093C000000000000A000F008F8600580E000D3FBD +:1093D00000000000241900022404001400002821C9 +:1093E0000000302100003821AF9900980E000D2FA9 +:1093F000000000000A000F008F8600580E000D5775 +:10940000000000008F8500942419000200403021E4 +:1094100024040010000038210A000F56AF9900986C +:109420000040382124040010970F0002000028217A +:109430000E000D2F31E6FFFF8F8600580A000F0047 +:10944000AF9100988F84FF2C3C077FFF34E6FFFF2D +:109450008C8500182402000100A61824AC83001893 +:1094600003E00008A08200053084FFFF30A5FFFF65 +:109470001080000700001821308200011040000217 +:1094800000042042006518211480FFFB00052840DD +:1094900003E000080060102110C000070000000079 +:1094A0008CA2000024C6FFFF24A50004AC820000AB +:1094B00014C0FFFB2484000403E000080000000047 +:1094C00010A0000824A3FFFFAC86000000000000ED +:1094D000000000002402FFFF2463FFFF1462FFFA74 +:1094E0002484000403E0000800000000000411C010 +:1094F00003E000082442024027BDFFE8AFB000109F +:1095000000808021AFBF00140E000F9600A0202124 +:1095100000504821240AFF808FBF00148FB0001034 +:10952000012A30243127007F3C08800A3C042100B6 +:1095300000E8102100C428253C03800027BD001846 +:10954000AC650024AF820038AC400000AC6500245C +:1095500003E00008AC4000403C0D08008DAD005811 +:1095600000056180240AFF8001A45821016C482174 +:10957000012A30243127007F3C08800C3C04210064 +:1095800000E8102100C428253C038000AC650028B9 +:10959000AF82003403E00008AC40002430A5FFFF98 +:1095A0003C0680008CC201B80440FFFE3C086015F8 +:1095B00000A838253C031000ACC40180ACC0018475 +:1095C000ACC7018803E00008ACC301B83C0D08003B +:1095D0008DAD005800056180240AFF8001A4582148 +:1095E000016C4021010A4824000931403107007F05 +:1095F00000C728253C04200000A418253C02800058 +:10960000AC43083003E00008AF80003427BDFFE81A +:10961000AFB0001000808021AFBF00140E000F9685 +:1096200000A0202100504821240BFF80012B502452 +:10963000000A39403128007F3C0620008FBF00140B +:109640008FB0001000E8282534C2000100A21825C0 +:109650003C04800027BD0018AC83083003E00008FC +:10966000AF8000383C0580088CA700603C0680086D +:109670000087102B144000112C8340008CA8006040 +:109680002D0340001060000F240340008CC90060CF +:109690000089282B14A00002008018218CC30060D0 +:1096A00000035A42000B30803C0A0800254A59202A +:1096B00000CA202103E000088C8200001460FFF340 +:1096C0002403400000035A42000B30803C0A08008B +:1096D000254A592000CA202103E000088C8200009E +:1096E0003C05800890A60008938400AB24C20001CA +:1096F000304200FF3043007F1064000C0002382726 +:10970000A0A200083C0480008C85017804A0FFFE24 +:109710008F8A00A0240900023C081000AC8A014096 +:10972000A089014403E00008AC8801780A00101BFE +:1097300030E2008027BDFFD8AFB200188F9200A49E +:10974000AFBF0020AFB3001CAFB00010AFB100142A +:109750008F9300348E5900283C1000803C0EFFEFA0 +:10976000AE7900008E580024A260000A35CDFFFFBC +:10977000AE7800049251002C3C0BFF9F356AFFFF2E +:10978000A271000C8E6F000C3C080040A271000B0F +:1097900001F06025018D4824012A382400E8302595 +:1097A000AE66000C8E450004AE6000183C0400FF5D +:1097B000AE6500148E43002C3482FFFFA6600008C3 +:1097C0000062F824AE7F00108E5900088F9000A030 +:1097D000964E0012AE7900208E51000C31D83FFF1A +:1097E00000187980AE7100248E4D001401F06021C4 +:1097F00031CB0001AE6D00288E4A0018000C41C22A +:10980000000B4B80AE6A002C8E46001C01093821EB +:10981000A667001CAE660030964500028E4400200C +:10982000A665001EAE64003492430033306200042B +:1098300054400006924700003C0280083443010077 +:109840008C7F00D0AE7F0030924700008F860038BA +:10985000A0C700309245003330A4000250800007BA +:10986000925100018F880038240BFF80910A00304C +:10987000014B4825A1090030925100018F9000381A +:10988000240CFFBF2404FFDFA21100318F8D0038AC +:109890003C1880083711008091AF003C31EE007F0A +:1098A000A1AE003C8F890038912B003C016C502404 +:1098B000A12A003C8F9F00388E68001493E6003C7C +:1098C0002D0700010007114000C4282400A218251C +:1098D000A3E3003C8F87003896590012A4F90032A8 +:1098E0008E450004922E007C30B0000300107823D7 +:1098F00031ED000300AD102131CC000215800002D3 +:1099000024460034244600303C0280083443008062 +:10991000907F007C00BFC824333800041700000289 +:1099200024C2000400C010218F98003824190002BE +:10993000ACE20034A3190000924F003F8F8E003834 +:109940003C0C8008358B0080A1CF00018F9100383E +:10995000924D003F8E440004A62D0002956A005CE3 +:109960000E000FF43150FFFF00024B800209382532 +:109970003C08420000E82825AE2500048E4400384B +:109980008F850038ACA400188E460034ACA6001CAD +:10999000ACA0000CACA00010A4A00014A4A0001661 +:1099A000A4A00020A4A00022ACA000248E62001479 +:1099B00050400001240200018FBF00208FB3001C23 +:1099C0008FB200188FB100148FB00010ACA2000845 +:1099D0000A00101327BD002827BDFFC83C058008DA +:1099E00034A40080AFBF0034AFBE0030AFB7002C4E +:1099F000AFB60028AFB50024AFB40020AFB3001C51 +:109A0000AFB20018AFB10014AFB00010948300786B +:109A10009482007A104300512405FFFF0080F0215A +:109A20000A0011230080B821108B004D8FBF003435 +:109A30008F8600A03C1808008F18005C2411FF805E +:109A40003C1680000306782101F18024AED0002C62 +:109A500096EE007A31EC007F3C0D800E31CB7FFF1B +:109A6000018D5021000B4840012AA82196A4000036 +:109A70003C0808008D0800582405FF8030953FFF02 +:109A800001061821001539800067C8210325F82434 +:109A90003C02010003E290253338007F3C11800C2A +:109AA000AED20028031190219250000D320F000415 +:109AB00011E0003702E0982196E3007A96E8007AF8 +:109AC00096E5007A2404800031077FFF24E300013B +:109AD00030627FFF00A4F82403E2C825A6F9007ACB +:109AE00096E6007A3C1408008E94006030D67FFF22 +:109AF00012D400C1000000008E5800188F8400A00E +:109B000002A028212713FFFF0E000FCEAE53002C1A +:109B100097D5007897D4007A12950010000028217C +:109B20003C098008352401003C0A8008914800085F +:109B3000908700D53114007F30E400FF0284302B81 +:109B400014C0FFB9268B0001938E00AB268C000158 +:109B5000008E682115ACFFB78F8600A08FBF003440 +:109B60008FBE00308FB7002C8FB600288FB5002431 +:109B70008FB400208FB3001C8FB200188FB1001477 +:109B80008FB0001000A0102103E0000827BD0038AE +:109B900000C020210E000F99028028218E4B00105A +:109BA0008E4C00308F84003824090002016C502351 +:109BB000AE4A0010A089000096E3005C8E4400309D +:109BC0008F9100380E000FF43070FFFF00024380C9 +:109BD000020838253C02420000E22825AE25000498 +:109BE0008E5F00048F8A00388E590000240B000815 +:109BF000AD5F001CAD590018AD40000CAD40001029 +:109C00009246000A240400052408C00030D000FF5A +:109C1000A550001496580008A55800169251000A45 +:109C20003C188008322F00FFA54F0020964E0008F8 +:109C300037110100A54E0022AD400024924D000BCB +:109C400031AC00FFA54C0002A14B00018E49003051 +:109C50008F830038240BFFBFAC690008A06400307C +:109C60008F9000382403FFDF9607003200E8282495 +:109C700000B51025A6020032921F003233F9003FD2 +:109C800037260040A20600328F8C0038AD800034A9 +:109C90008E2F00D0AD8F0038918E003C3C0F7FFF9F +:109CA00031CD007FA18D003C8F84003835EEFFFF61 +:109CB000908A003C014B4824A089003C8F850038E5 +:109CC00090A8003C01033824A0A7003C8E42003439 +:109CD0008F9100383C038008AE2200408E59002C42 +:109CE0008E5F0030033F3023AE26004492300048A0 +:109CF0003218007FA23800488F8800388E4D00301F +:109D00008D0C004801AE582401965024014B482583 +:109D1000AD0900489244000AA104004C964700088F +:109D20008F850038A4A7004E8E5000308E4400303E +:109D30000E0003818C65006092F9007C0002F940FE +:109D4000004028210002110003E2302133360002D6 +:109D500012C00003020680210005B0800216802197 +:109D6000926D007C31B30004126000020005708027 +:109D7000020E80218E4B00308F8800382405800031 +:109D8000316A0003000A4823312400030204182129 +:109D9000AD03003496E4007A96F0007A96F1007AEA +:109DA00032027FFF2447000130FF7FFF0225C824D5 +:109DB000033F3025A6E6007A96F8007A3C120800A8 +:109DC0008E520060330F7FFF11F200180000000078 +:109DD0008F8400A00E000FCE02A028218F8400A047 +:109DE0000E000FDE028028210E001013000000007C +:109DF0000A00111F0000000096F1007A022480245E +:109E0000A6F0007A92EF007A92EB007A31EE00FF32 +:109E1000000E69C2000D6027000C51C03169007F3F +:109E2000012A20250A001119A2E4007A96E6007A98 +:109E300000C5C024A6F8007A92EF007A92F3007A67 +:109E400031F200FF001271C2000E6827000DB1C090 +:109E5000326C007F01962825A2E5007A0A0011D015 +:109E60008F8400A03C0380003084FFFF30A5FFFFFB +:109E7000AC640018AC65001C03E000088C620014A0 +:109E800027BDFFA03C068008AFBF005CAFBE0058F6 +:109E9000AFB70054AFB60050AFB5004CAFB40048F8 +:109EA000AFB30044AFB20040AFB1003CAFB0003838 +:109EB00034C80100910500D590C700083084FFFF29 +:109EC00030A500FF30E2007F0045182AAFA4001043 +:109ED000A7A00018A7A0002610600055AFA000148E +:109EE00090CA00083149007F00A9302324D3FFFF26 +:109EF0000013802B8FB400100014902B02128824C2 +:109F0000522000888FB300143C03800894790052DB +:109F1000947E00508FB60010033EC0230018BC0092 +:109F2000001714030016FC0002C2A82A16A00002A3 +:109F3000001F2C030040282100133C0000072403CD +:109F400000A4102A5440000100A020212885000907 +:109F500014A000020080A021241400083C0C8008FA +:109F60008D860048001459808D88004C3C03800089 +:109F70003169FFFF3C0A0010012A202534710400DA +:109F8000AC660038AF9100A4AC68003CAC64003013 +:109F900000000000000000000000000000000000C1 +:109FA00000000000000000000000000000000000B1 +:109FB0008C6E000031CD002011A0FFFD0014782A26 +:109FC00001F01024104000390000A8213C16800840 +:109FD00092D700083C1280008E44010032F6007FC8 +:109FE0000E000F9902C028218E3900108E44010006 +:109FF0000000902133373FFF0E000FB102E028210F +:10A00000923800003302003F2C500008520000102C +:10A0100000008821000210803C030800246358E4FB +:10A020000043F8218FFE000003C00008000000007C +:10A0300090CF0008938C00AB31EE007F00AE682318 +:10A04000018D58210A0012172573FFFF0000882197 +:10A050003C1E80008FC401000E000FCE02E02821BC +:10A060008FC401000E000FDE02C028211220000F55 +:10A070000013802B8F8B00A426A400010004AC00E9 +:10A08000027298230015AC032578004002B4B02A70 +:10A090000013802B241700010300882102D0102414 +:10A0A000AF9800A41440FFC9AFB700143C07800864 +:10A0B00094E200508FAE00103C05800002A288217F +:10A0C0003C060020A4F10050ACA6003094F40050EF +:10A0D00094EF005201D51823306CFFFF11F4001EDD +:10A0E000AFAC00108CEF004C001561808CF500487F +:10A0F00001EC28210000202100AC582B02A4C02133 +:10A10000030BB021ACE5004CACF600488FB4001056 +:10A110000014902B021288241620FF7C3C03800838 +:10A120008FB300148FBF005C8FBE00583A620001ED +:10A130008FB700548FB600508FB5004C8FB40048D5 +:10A140008FB300448FB200408FB1003C8FB0003815 +:10A1500003E0000827BD006094FE00548CF2004428 +:10A1600033C9FFFE0009C8C00259F821ACBF003C4A +:10A170008CE800448CAD003C010D50231940003B9D +:10A18000000000008CF7004026E20001ACA200387D +:10A190003C05005034A700103C038000AC67003041 +:10A1A00000000000000000000000000000000000AF +:10A1B000000000000000000000000000000000009F +:10A1C0008C7800003316002012C0FFFD3C1180087F +:10A1D000962200543C1580003C068008304E000159 +:10A1E000000E18C0007578218DEC04003C070800B3 +:10A1F0008CE700443C040020ACCC00488DF40404FF +:10A20000240B0001ACD4004C10EB0260AEA4003073 +:10A21000963900523C0508008CA5004000B99021F9 +:10A22000A6320052963F005427ED0001A62D00549F +:10A230009626005430C4FFFF5487FF2F8FB40010C0 +:10A2400030A5FFFF0E0011F4A62000543C070800C3 +:10A250008CE70024963E00520047B82303D74823DA +:10A26000A62900520A0012198FB400108CE2004097 +:10A270000A0012BE00000000922400012407000121 +:10A280003085007F14A7001C97AD00268E2B00148C +:10A29000240CC000316A3FFF01AC48243C06080092 +:10A2A0008CC60060012A402531043FFF0086882BC0 +:10A2B00012200011A7A800263C0508008CA5005814 +:10A2C0008F9100A0000439802402FF8000B1182182 +:10A2D0000067F82103E2F02433F8007F3C1280008D +:10A2E0003C19800EAE5E002C0319702191D0000D38 +:10A2F000360F0004A1CF000D0E001028241200011B +:10A30000241100013C1E80008FC401000E000FCEFE +:10A3100002E028218FC401000E000FDE02C02821B8 +:10A320001620FF558F8B00A40A0012860013802B85 +:10A330008F8600A490C80001310400201080019194 +:10A34000241000013C048008348B0080916A007C5A +:10A350008F9E0034AFA0002C314900011120000F66 +:10A36000AFB000288CCD00148C8E006001AE602B45 +:10A370001580000201A038218C8700603C188008FD +:10A38000370300808C70007000F0782B15E000021D +:10A3900000E020218C640070AFA4002C3C028008F7 +:10A3A000344500808CD200148CBF0070025FC82B33 +:10A3B00017200002024020218CA400708FA7002CDF +:10A3C0000087182310600003AFA3003024050002AB +:10A3D000AFA500288FA400280264882B162000BA9D +:10A3E000000018218CD000388FCE000C3C0F00806C +:10A3F000AFD000008CCD00343C0CFF9F01CF58251E +:10A40000AFCD000490CA003F3586FFFF01662024CF +:10A410003C0900203C08FFEFA3CA000B0089382547 +:10A420003511FFFF00F118243C0500088F8700A4B8 +:10A430000065C825AFD9000C8CE20014AFC000182D +:10A440008FA60030AFC200148CF800188FB0002C1B +:10A450003C1FFFFBAFD8001C8CEF000837F2FFFF5A +:10A4600003326824AFCF00248CEC000C020670216C +:10A47000AFCD000CA7C00038A7C0003AAFCE002C6B +:10A48000AFCC0020AFC000288CEA00148FAB002CAA +:10A49000014B48230126402311000011AFC80010D2 +:10A4A00090EB003D8FC900048FC80000000B5100E5 +:10A4B000012A28210000102100AA882B010218215E +:10A4C0000071F821AFC50004AFDF000090F2003D3D +:10A4D000A3D2000A8F9900A497380006A7D80008D5 +:10A4E0008F910038240800023C038008A228000055 +:10A4F0003465008094BF005C8FA4002C33F0FFFF14 +:10A500000E000FF48F9200380002CB808F8500A4DC +:10A51000021978253C18420001F87025AE4E00045F +:10A520008F8400388CAD0038AC8D00188CAC0034B2 +:10A53000AC8C001CAC80000CAC800010A48000141B +:10A54000A4800016A4800020A4800022AC800024F7 +:10A5500090A6003F8FA7002CA486000250E0019235 +:10A56000240700018FA200305040000290A2003D5D +:10A5700090A2003E244A0001A08A00018F84003886 +:10A580008FA9002CAC8900083C128008364D008051 +:10A5900091AC007C3186000214C000022407003414 +:10A5A000240700308F8500A43C198008373F0080C5 +:10A5B00090B0000093F9007C240E0004A0900030BD +:10A5C0008F8F00A48FB8002C8F8D003891F200017E +:10A5D0003304000301C46023A1B200318F8E003820 +:10A5E0008F8600A42402C00095CA003294C90012CC +:10A5F0008FAB002C0142402431233FFF010388250B +:10A60000A5D1003291D000323185000300EBF82152 +:10A610003218003F370F0040A1CF00328FA4002C2A +:10A6200003E5382133280004108000028F850038AC +:10A6300000E838213C0A8008ACA700343549010005 +:10A640008D2800D08FA3002C2419FFBFACA80038A0 +:10A6500090B1003C2C640001240FFFDF3227007F03 +:10A66000A0A7003C8F98003800049140931F003C45 +:10A6700003F98024A310003C8F8C0038918E003C9D +:10A6800001CF682401B23025A186003C8F8900A447 +:10A690008F8800388D2B0020AD0B00408D220024C8 +:10A6A000AD0200448D2A0028AD0A00488D23002CFD +:10A6B0000E001013AD03004C8FB1002824070002D8 +:10A6C000122700118FA300280003282B00058023E8 +:10A6D0000270982400608021006090210A00126FAF +:10A6E0000010882B962900128F8400A00000902172 +:10A6F0003125FFFFA7A900180E000FC22411000189 +:10A700000A00131D3C1E80003C0B80003C12800898 +:10A710008D640100924900088F92FF340E000F995A +:10A720003125007F8F9900388FA700288FA4003033 +:10A73000A3270000965F005C33F0FFFF0E000FF4CC +:10A740008F91003800026B80020D80253C0842008A +:10A750008F8D00A402085025AE2A00048DA5003874 +:10A760008F8A003800007821000F1100AD450018D5 +:10A770008DB800343C047FFF3488FFFFAD58001CC7 +:10A7800091A6003E8D4C001C8D4900180006190052 +:10A79000000677020183C821004E58250323882B29 +:10A7A000012B382100F1F821AD59001CAD5F0018D4 +:10A7B000AD40000CAD40001091B0003E8FA40030C1 +:10A7C00024090005A550001495A500042419C00013 +:10A7D00000884024A545001691B8003EA5580020E9 +:10A7E00095AF0004A54F0022AD40002491AE003F7C +:10A7F000A54E000291A6003E91AC003D01861023BB +:10A80000244B0001A14B00018F9100388FA3003031 +:10A810003C028008344B0100AE230008A22900301E +:10A820008F8C00388F8700A4959F003294F000121F +:10A830002407FFBF033FC02432053FFF03057825EF +:10A84000A58F0032918E00322418FFDF31CD003FFA +:10A8500035A60040A18600328F910038240DFFFFFD +:10A86000240CFF80AE2000348D6A00D0AE2A003860 +:10A870009223003C3069007FA229003C8F90003871 +:10A880003C0380009219003C0327F824A21F003CDF +:10A890008F8E003891C5003C00B87824A1CF003CD1 +:10A8A0008F8A00383C0E8008AD4D00408FA6002CEA +:10A8B000AD46004491420048004C5825A14B004849 +:10A8C0008F9000388F9900A48E09004801238824B6 +:10A8D00002283825AE070048933F003EA21F004CD7 +:10A8E0008F9800A48F8F003897050004A5E5004ECF +:10A8F0000E0003818DC500609246007C8FAC003055 +:10A9000000026940000291000040282130CB000283 +:10A9100001B21021156000AA018230213C0E80088E +:10A9200035C20080904C007C31830004106000032D +:10A930008FB900300005788000CF3021241F00043B +:10A940008F910038332D000303ED8023320800037C +:10A9500000C85021AE2A00343C188000A7C500383A +:10A960003C0680088F04010090DE00080E000FDE18 +:10A9700033C5007F0E001013000000000A00140D04 +:10A980008FA300288F9800348CC90038241F00033F +:10A99000A7000008AF0900008CC50034A300000A1E +:10A9A0008F9900A4AF0500043C080080932D003F60 +:10A9B000A31F000C8F0A000C3C02FF9FA30D000B8D +:10A9C0000148F0253451FFFF3C12FFEF8F9900A49E +:10A9D00003D170243646FFFF01C61824AF03000CD4 +:10A9E0008F2C0014972900128F8400A0AF0C001048 +:10A9F0008F2F0014AF000018AF000020AF0F00141D +:10AA0000AF0000248F270018312F3FFF000F59801F +:10AA1000AF0700288F2500080164F821312D0001BF +:10AA2000AF0500308F31000C8F920038001F51C2EB +:10AA3000000D438001481021241E00023C068008BE +:10AA4000A702001CA7000034AF11002CA25E00007A +:10AA500034D20080964E005C8F9900383C0342004F +:10AA600031CCFFFF01833825AF2700048F8B00A472 +:10AA7000240500012402C0008D640038240700343E +:10AA8000AF2400188D690034AF29001CAF20000CE2 +:10AA9000AF200010A7200014A7200016A720002038 +:10AAA000A7200022AF200024A7300002A325000128 +:10AAB0008F8800388F9F00A4AD10000893ED000030 +:10AAC000A10D00308F8A00A48F98003891510001A9 +:10AAD000A31100318F8B0038957E003203C27024A1 +:10AAE00001CF6025A56C0032916300323064003FD5 +:10AAF000A16400329249007C3125000214A00002BA +:10AB00008F840038240700303C198008AC8700345B +:10AB1000373201008E5F00D0240AFFBF020090216F +:10AB2000AC9F0038908D003C31A8007FA088003C8D +:10AB30008F9E003893C2003C004A8824A3D1003C79 +:10AB40008F8300380010882B9066003C34CE0020A4 +:10AB5000A06E003C8F8400A48F9800388C8C00205D +:10AB6000AF0C00408C8F0024AF0F00448C8700286E +:10AB7000AF0700488C8B002CAF0B004C0E0010135D +:10AB80003C1E80000A0012700000000094C80052B1 +:10AB90003C0A08008D4A002401488821A4D10052B3 +:10ABA0000A0012198FB40010A08700018F840038AA +:10ABB000240B0001AC8B00080A0013BE3C12800875 +:10ABC000000520800A0014A200C4302127BDFFE048 +:10ABD0003C0D8008AFB20018AFB00010AFBF001C32 +:10ABE000AFB1001435B200808E4C001835A80100BA +:10ABF000964B000695A70050910900FC000C5602E8 +:10AC0000016728233143007F312600FF240200031F +:10AC1000AF8300A8AF8400A010C2001B30B0FFFFBC +:10AC2000910600FC2412000530C200FF10520033D0 +:10AC300000000000160000098FBF001C8FB2001832 +:10AC40008FB100148FB00010240D0C003C0C80005C +:10AC500027BD002003E00008AD8D00240E0011FB8D +:10AC6000020020218FBF001C8FB200188FB100148A +:10AC70008FB00010240D0C003C0C800027BD00207C +:10AC800003E00008AD8D0024965800789651007AB4 +:10AC9000924E007D0238782631E8FFFF31C400C0B3 +:10ACA000148000092D11000116000037000000007B +:10ACB0005620FFE28FBF001C0E0010D100000000E4 +:10ACC0000A00156A8FBF001C1620FFDA0000000082 +:10ACD0000E0010D1000000001440FFD88FBF001CF0 +:10ACE0001600002200000000925F007D33E2003F6A +:10ACF000A242007D0A00156A8FBF001C950900EA78 +:10AD00008F86008000802821240400050E0007257E +:10AD10003130FFFF978300923C0480002465FFFFE1 +:10AD2000A78500928C8A01B80540FFFE0000000054 +:10AD3000AC8001808FBF001CAC9001848FB20018E2 +:10AD40008FB100148FB000103C0760133C0B100053 +:10AD5000240D0C003C0C800027BD0020AC8701882E +:10AD6000AC8B01B803E00008AD8D00240E0011FB90 +:10AD7000020020215040FFB18FBF001C925F007D78 +:10AD80000A00159733E2003F0E0011FB020020215C +:10AD90001440FFAA8FBF001C122000070000000013 +:10ADA0009259007D3330003F36020040A242007DC0 +:10ADB0000A00156A8FBF001C0E0010D100000000B1 +:10ADC0005040FF9E8FBF001C9259007D3330003FE2 +:08ADD0000A0015C6360200401E +:08ADD800000000000000001B58 +:10ADE0000000000F0000000A00000008000000063C +:10ADF0000000000500000005000000040000000441 +:10AE00000000000300000003000000030000000336 +:10AE10000000000300000002000000020000000229 +:10AE2000000000020000000200000002000000021A +:10AE3000000000020000000200000002000000020A +:10AE400000000002000000020000000200000002FA +:0CAE5000000000010000000100000001F3 +:04AE5C008008010069 +:10AE6000800800808008000000000C000000308096 +:10AE7000080011D00800127C08001294080012A8E3 +:10AE8000080012BC080011D0080011D0080012F010 +:10AE90000800132C080013400800138808001A8CBF +:10AEA00008001A8C08001AC408001AC408001AD82E +:10AEB00008001AA808001D0008001CCC08001D5836 +:10AEC00008001D5808001DE008001D108008024001 +:10AED000080027340800256C0800275C080027F4C8 +:10AEE0000800293C0800298808002AAC080029B479 +:10AEF00008002A38080025DC08002EDC08002EA4F3 +:10AF000008002588080025880800258808002B20CF +:10AF100008002B20080025880800258808002DD06F +:10AF2000080025880800258808002588080025884D +:10AF300008002E0C080025880800258808002588B0 +:10AF4000080025880800258808002588080025882D +:10AF5000080025880800258808002588080025881D +:10AF6000080025880800258808002588080029A8E9 +:10AF7000080025880800258808002E680800258814 +:10AF800008002588080025880800258808002588ED +:10AF900008002588080025880800258808002588DD +:10AFA00008002588080025880800258808002588CD +:10AFB00008002588080025880800258808002588BD +:10AFC00008002CF4080025880800258808002C6853 +:10AFD00008002BC408003CE408003CB808003C848E +:10AFE00008003C5808003C3808003BEC8008010091 +:10AFF00080080080800800008008008008004C6401 +:10B0000008004C9C08004BE408004C6408004C64A9 +:0CB01000080049B808004C6408005050CB +:04B01C000A000C8496 +:10B0200000000000000000000000000D7278703683 +:10B030002E302E3137000000060011030000000002 +:10B0400000000001000000000000000000000000FF +:10B0500000000000000000000000000000000000F0 +:10B0600000000000000000000000000000000000E0 +:10B0700000000000000000000000000000000000D0 +:10B0800000000000000000000000000000000000C0 +:10B0900000000000000000000000000000000000B0 +:10B0A00000000000000000000000000000000000A0 +:10B0B0000000000000000000000000000000000090 +:10B0C0000000000000000000000000000000000080 +:10B0D0000000000000000000000000000000000070 +:10B0E0000000000000000000000000000000000060 +:10B0F0000000000000000000000000000000000050 +:10B10000000000000000000000000000000000003F +:10B11000000000000000000000000000000000002F +:10B12000000000000000000000000000000000001F +:10B13000000000000000000000000000000000000F +:10B1400000000000000000000000000000000000FF +:10B1500000000000000000000000000000000000EF +:10B1600000000000000000000000000000000000DF +:10B1700000000000000000000000000000000000CF +:10B1800000000000000000000000000000000000BF +:10B1900000000000000000000000000000000000AF +:10B1A000000000000000000000000000000000009F +:10B1B000000000000000000000000000000000008F +:10B1C000000000000000000000000000000000007F +:10B1D000000000000000000000000000000000006F +:10B1E000000000000000000000000000000000005F +:10B1F000000000000000000000000000000000004F +:10B20000000000000000000000000000000000003E +:10B21000000000000000000000000000000000002E +:10B22000000000000000000000000000000000001E +:10B23000000000000000000000000000000000000E +:10B2400000000000000000000000000000000000FE +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B2800000000000000000000000000000000000BE +:10B2900000000000000000000000000000000000AE +:10B2A000000000000000000000000000000000009E +:10B2B000000000000000000000000000000000008E +:10B2C000000000000000000000000000000000007E +:10B2D000000000000000000000000000000000006E +:10B2E000000000000000000000000000000000005E +:10B2F000000000000000000000000000000000004E +:10B30000000000000000000000000000000000003D +:10B31000000000000000000000000000000000002D +:10B32000000000000000000000000000000000001D +:10B33000000000000000000000000000000000000D +:10B3400000000000000000000000000000000000FD +:10B3500000000000000000000000000000000000ED +:10B3600000000000000000000000000000000000DD +:10B3700000000000000000000000000000000000CD +:10B3800000000000000000000000000000000000BD +:10B3900000000000000000000000000000000000AD +:10B3A000000000000000000000000000000000009D +:10B3B000000000000000000000000000000000008D +:10B3C000000000000000000000000000000000007D +:10B3D000000000000000000000000000000000006D +:10B3E000000000000000000000000000000000005D +:10B3F000000000000000000000000000000000004D +:10B40000000000000000000000000000000000003C +:10B41000000000000000000000000000000000002C +:10B42000000000000000000000000000000000001C +:10B43000000000000000000000000000000000000C +:10B4400000000000000000000000000000000000FC +:10B4500000000000000000000000000000000000EC +:10B4600000000000000000000000000000000000DC +:10B4700000000000000000000000000000000000CC +:10B4800000000000000000000000000000000000BC +:10B4900000000000000000000000000000000000AC +:10B4A000000000000000000000000000000000009C +:10B4B000000000000000000000000000000000008C +:10B4C000000000000000000000000000000000007C +:10B4D000000000000000000000000000000000006C +:10B4E000000000000000000000000000000000005C +:10B4F000000000000000000000000000000000004C +:10B50000000000000000000000000000000000003B +:10B51000000000000000000000000000000000002B +:10B52000000000000000000000000000000000001B +:10B53000000000000000000000000000000000000B +:10B5400000000000000000000000000000000000FB +:10B5500000000000000000000000000000000000EB +:10B5600000000000000000000000000000000000DB +:10B5700000000000000000000000000000000000CB +:10B5800000000000000000000000000000000000BB +:10B5900000000000000000000000000000000000AB +:10B5A000000000000000000000000000000000009B +:10B5B000000000000000000000000000000000008B +:10B5C000000000000000000000000000000000007B +:10B5D000000000000000000000000000000000006B +:10B5E000000000000000000000000000000000005B +:10B5F000000000000000000000000000000000004B +:10B60000000000000000000000000000000000003A +:10B61000000000000000000000000000000000002A +:10B62000000000000000000000000000000000001A +:10B63000000000000000000000000000000000000A +:10B6400000000000000000000000000000000000FA +:10B6500000000000000000000000000000000000EA +:10B6600000000000000000000000000000000000DA +:10B6700000000000000000000000000000000000CA +:10B6800000000000000000000000000000000000BA +:10B6900000000000000000000000000000000000AA +:10B6A000000000000000000000000000000000009A +:10B6B000000000000000000000000000000000008A +:10B6C000000000000000000000000000000000007A +:10B6D000000000000000000000000000000000006A +:10B6E000000000000000000000000000000000005A +:10B6F000000000000000000000000000000000004A +:10B700000000000000000000000000000000000039 +:10B710000000000000000000000000000000000029 +:10B720000000000000000000000000000000000019 +:10B730000000000000000000000000000000000009 +:10B7400000000000000000000000000000000000F9 +:10B7500000000000000000000000000000000000E9 +:10B7600000000000000000000000000000000000D9 +:10B7700000000000000000000000000000000000C9 +:10B7800000000000000000000000000000000000B9 +:10B7900000000000000000000000000000000000A9 +:10B7A0000000000000000000000000000000000099 +:10B7B0000000000000000000000000000000000089 +:10B7C0000000000000000000000000000000000079 +:10B7D0000000000000000000000000000000000069 +:10B7E0000000000000000000000000000000000059 +:10B7F0000000000000000000000000000000000049 +:10B800000000000000000000000000000000000038 +:10B810000000000000000000000000000000000028 +:10B820000000000000000000000000000000000018 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B8500000000000000000000000000000000000E8 +:10B8600000000000000000000000000000000000D8 +:10B8700000000000000000000000000000000000C8 +:10B8800000000000000000000000000000000000B8 +:10B8900000000000000000000000000000000000A8 +:10B8A0000000000000000000000000000000000098 +:10B8B0000000000000000000000000000000000088 +:10B8C0000000000000000000000000000000000078 +:10B8D0000000000000000000000000000000000068 +:10B8E0000000000000000000000000000000000058 +:10B8F0000000000000000000000000000000000048 +:10B900000000000000000000000000000000000037 +:10B910000000000000000000000000000000000027 +:10B920000000000000000000000000000000000017 +:10B930000000000000000000000000000000000007 +:10B9400000000000000000000000000000000000F7 +:10B9500000000000000000000000000000000000E7 +:10B9600000000000000000000000000000000000D7 +:10B9700000000000000000000000000000000000C7 +:10B9800000000000000000000000000000000000B7 +:10B9900000000000000000000000000000000000A7 +:10B9A0000000000000000000000000000000000097 +:10B9B0000000000000000000000000000000000087 +:10B9C0000000000000000000000000000000000077 +:10B9D0000000000000000000000000000000000067 +:10B9E0000000000000000000000000000000000057 +:10B9F0000000000000000000000000000000000047 +:10BA00000000000000000000000000000000000036 +:10BA10000000000000000000000000000000000026 +:10BA20000000000000000000000000000000000016 +:10BA30000000000000000000000000000000000006 +:10BA400000000000000000000000000000000000F6 +:10BA500000000000000000000000000000000000E6 +:10BA600000000000000000000000000000000000D6 +:10BA700000000000000000000000000000000000C6 +:10BA800000000000000000000000000000000000B6 +:10BA900000000000000000000000000000000000A6 +:10BAA0000000000000000000000000000000000096 +:10BAB0000000000000000000000000000000000086 +:10BAC0000000000000000000000000000000000076 +:10BAD0000000000000000000000000000000000066 +:10BAE0000000000000000000000000000000000056 +:10BAF0000000000000000000000000000000000046 +:10BB00000000000000000000000000000000000035 +:10BB10000000000000000000000000000000000025 +:10BB20000000000000000000000000000000000015 +:10BB30000000000000000000000000000000000005 +:10BB400000000000000000000000000000000000F5 +:10BB500000000000000000000000000000000000E5 +:10BB600000000000000000000000000000000000D5 +:10BB700000000000000000000000000000000000C5 +:10BB800000000000000000000000000000000000B5 +:10BB900000000000000000000000000000000000A5 +:10BBA0000000000000000000000000000000000095 +:10BBB0000000000000000000000000000000000085 +:10BBC0000000000000000000000000000000000075 +:10BBD0000000000000000000000000000000000065 +:10BBE0000000000000000000000000000000000055 +:10BBF0000000000000000000000000000000000045 +:10BC00000000000000000000000000000000000034 +:10BC10000000000000000000000000000000000024 +:10BC20000000000000000000000000000000000014 +:10BC30000000000000000000000000000000000004 +:10BC400000000000000000000000000000000000F4 +:10BC500000000000000000000000000000000000E4 +:10BC600000000000000000000000000000000000D4 +:10BC700000000000000000000000000000000000C4 +:10BC800000000000000000000000000000000000B4 +:10BC900000000000000000000000000000000000A4 +:10BCA0000000000000000000000000000000000094 +:10BCB0000000000000000000000000000000000084 +:10BCC0000000000000000000000000000000000074 +:10BCD0000000000000000000000000000000000064 +:10BCE0000000000000000000000000000000000054 +:10BCF0000000000000000000000000000000000044 +:10BD00000000000000000000000000000000000033 +:10BD10000000000000000000000000000000000023 +:10BD20000000000000000000000000000000000013 +:10BD30000000000000000000000000000000000003 +:10BD400000000000000000000000000000000000F3 +:10BD500000000000000000000000000000000000E3 +:10BD600000000000000000000000000000000000D3 +:10BD700000000000000000000000000000000000C3 +:10BD800000000000000000000000000000000000B3 +:10BD900000000000000000000000000000000000A3 +:10BDA0000000000000000000000000000000000093 +:10BDB0000000000000000000000000000000000083 +:10BDC0000000000000000000000000000000000073 +:10BDD0000000000000000000000000000000000063 +:10BDE0000000000000000000000000000000000053 +:10BDF0000000000000000000000000000000000043 +:10BE00000000000000000000000000000000000032 +:10BE10000000000000000000000000000000000022 +:10BE20000000000000000000000000000000000012 +:10BE30000000000000000000000000000000000002 +:10BE400000000000000000000000000000000000F2 +:10BE500000000000000000000000000000000000E2 +:10BE600000000000000000000000000000000000D2 +:10BE700000000000000000000000000000000000C2 +:10BE800000000000000000000000000000000000B2 +:10BE900000000000000000000000000000000000A2 +:10BEA0000000000000000000000000000000000092 +:10BEB0000000000000000000000000000000000082 +:10BEC0000000000000000000000000000000000072 +:10BED0000000000000000000000000000000000062 +:10BEE0000000000000000000000000000000000052 +:10BEF0000000000000000000000000000000000042 +:10BF00000000000000000000000000000000000031 +:10BF10000000000000000000000000000000000021 +:10BF20000000000000000000000000000000000011 +:10BF30000000000000000000000000000000000001 +:10BF400000000000000000000000000000000000F1 +:10BF500000000000000000000000000000000000E1 +:10BF600000000000000000000000000000000000D1 +:10BF700000000000000000000000000000000000C1 +:10BF800000000000000000000000000000000000B1 +:10BF900000000000000000000000000000000000A1 +:10BFA0000000000000000000000000000000000091 +:10BFB0000000000000000000000000000000000081 +:10BFC0000000000000000000000000000000000071 +:10BFD0000000000000000000000000000000000061 +:10BFE0000000000000000000000000000000000051 +:10BFF0000000000000000000000000000000000041 +:10C000000000000000000000000000000000000030 +:10C010000000000000000000000000000000000020 +:10C020000000000000000000000000000000000010 +:10C030000000000000000000000000000000000000 +:10C0400000000000000000000000000000000000F0 +:10C0500000000000000000000000000000000000E0 +:10C0600000000000000000000000000000000000D0 +:10C0700000000000000000000000000000000000C0 +:10C0800000000000000000000000000000000000B0 +:10C0900000000000000000000000000000000000A0 +:10C0A0000000000000000000000000000000000090 +:10C0B0000000000000000000000000000000000080 +:10C0C0000000000000000000000000000000000070 +:10C0D0000000000000000000000000000000000060 +:10C0E0000000000000000000000000000000000050 +:10C0F0000000000000000000000000000000000040 +:10C10000000000000000000000000000000000002F +:10C11000000000000000000000000000000000001F +:10C12000000000000000000000000000000000000F +:10C1300000000000000000000000000000000000FF +:10C1400000000000000000000000000000000000EF +:10C1500000000000000000000000000000000000DF +:10C1600000000000000000000000000000000000CF +:10C1700000000000000000000000000000000000BF +:10C1800000000000000000000000000000000000AF +:10C19000000000000000000000000000000000009F +:10C1A000000000000000000000000000000000008F +:10C1B000000000000000000000000000000000007F +:10C1C000000000000000000000000000000000006F +:10C1D000000000000000000000000000000000005F +:10C1E000000000000000000000000000000000004F +:10C1F000000000000000000000000000000000003F +:10C20000000000000000000000000000000000002E +:10C21000000000000000000000000000000000001E +:10C22000000000000000000000000000000000000E +:10C2300000000000000000000000000000000000FE +:10C2400000000000000000000000000000000000EE +:10C2500000000000000000000000000000000000DE +:10C2600000000000000000000000000000000000CE +:10C2700000000000000000000000000000000000BE +:10C2800000000000000000000000000000000000AE +:10C29000000000000000000000000000000000009E +:10C2A000000000000000000000000000000000008E +:10C2B000000000000000000000000000000000007E +:10C2C000000000000000000000000000000000006E +:10C2D000000000000000000000000000000000005E +:10C2E000000000000000000000000000000000004E +:10C2F000000000000000000000000000000000003E +:10C30000000000000000000000000000000000002D +:10C31000000000000000000000000000000000001D +:10C32000000000000000000000000000000000000D +:10C3300000000000000000000000000000000000FD +:10C3400000000000000000000000000000000000ED +:10C3500000000000000000000000000000000000DD +:10C3600000000000000000000000000000000000CD +:10C3700000000000000000000000000000000000BD +:10C3800000000000000000000000000000000000AD +:10C39000000000000000000000000000000000009D +:10C3A000000000000000000000000000000000008D +:10C3B000000000000000000000000000000000007D +:10C3C000000000000000000000000000000000006D +:10C3D000000000000000000000000000000000005D +:10C3E000000000000000000000000000000000004D +:10C3F000000000000000000000000000000000003D +:10C40000000000000000000000000000000000002C +:10C41000000000000000000000000000000000001C +:10C42000000000000000000000000000000000000C +:10C4300000000000000000000000000000000000FC +:10C4400000000000000000000000000000000000EC +:10C4500000000000000000000000000000000000DC +:10C4600000000000000000000000000000000000CC +:10C4700000000000000000000000000000000000BC +:10C4800000000000000000000000000000000000AC +:10C49000000000000000000000000000000000009C +:10C4A000000000000000000000000000000000008C +:10C4B000000000000000000000000000000000007C +:10C4C000000000000000000000000000000000006C +:10C4D000000000000000000000000000000000005C +:10C4E000000000000000000000000000000000004C +:10C4F000000000000000000000000000000000003C +:10C50000000000000000000000000000000000002B +:10C51000000000000000000000000000000000001B +:10C52000000000000000000000000000000000000B +:10C5300000000000000000000000000000000000FB +:10C5400000000000000000000000000000000000EB +:10C5500000000000000000000000000000000000DB +:10C5600000000000000000000000000000000000CB +:10C5700000000000000000000000000000000000BB +:10C5800000000000000000000000000000000000AB +:10C59000000000000000000000000000000000009B +:10C5A000000000000000000000000000000000008B +:10C5B000000000000000000000000000000000007B +:10C5C000000000000000000000000000000000006B +:10C5D000000000000000000000000000000000005B +:10C5E000000000000000000000000000000000004B +:10C5F000000000000000000000000000000000003B +:10C60000000000000000000000000000000000002A +:10C61000000000000000000000000000000000001A +:10C62000000000000000000000000000000000000A +:10C6300000000000000000000000000000000000FA +:10C6400000000000000000000000000000000000EA +:10C6500000000000000000000000000000000000DA +:10C6600000000000000000000000000000000000CA +:10C6700000000000000000000000000000000000BA +:10C6800000000000000000000000000000000000AA +:10C69000000000000000000000000000000000009A +:10C6A000000000000000000000000000000000008A +:10C6B000000000000000000000000000000000007A +:10C6C000000000000000000000000000000000006A +:10C6D000000000000000000000000000000000005A +:10C6E000000000000000000000000000000000004A +:10C6F000000000000000000000000000000000003A +:10C700000000000000000000000000000000000029 +:10C710000000000000000000000000000000000019 +:10C720000000000000000000000000000000000009 +:10C7300000000000000000000000000000000000F9 +:10C7400000000000000000000000000000000000E9 +:10C7500000000000000000000000000000000000D9 +:10C7600000000000000000000000000000000000C9 +:10C7700000000000000000000000000000000000B9 +:10C7800000000000000000000000000000000000A9 +:10C790000000000000000000000000000000000099 +:10C7A0000000000000000000000000000000000089 +:10C7B0000000000000000000000000000000000079 +:10C7C0000000000000000000000000000000000069 +:10C7D0000000000000000000000000000000000059 +:10C7E0000000000000000000000000000000000049 +:10C7F0000000000000000000000000000000000039 +:10C800000000000000000000000000000000000028 +:10C810000000000000000000000000000000000018 +:10C820000000000000000000000000000000000008 +:10C8300000000000000000000000000000000000F8 +:10C8400000000000000000000000000000000000E8 +:10C8500000000000000000000000000000000000D8 +:10C8600000000000000000000000000000000000C8 +:10C8700000000000000000000000000000000000B8 +:10C8800000000000000000000000000000000000A8 +:10C890000000000000000000000000000000000098 +:10C8A0000000000000000000000000000000000088 +:10C8B0000000000000000000000000000000000078 +:10C8C0000000000000000000000000000000000068 +:10C8D0000000000000000000000000000000000058 +:10C8E0000000000000000000000000000000000048 +:10C8F0000000000000000000000000000000000038 +:10C900000000000000000000000000000000000027 +:10C910000000000000000000000000000000000017 +:10C920000000000000000000000000000000000007 +:10C9300000000000000000000000000000000000F7 +:10C9400000000000000000000000000000000000E7 +:10C9500000000000000000000000000000000000D7 +:10C9600000000000000000000000000000000000C7 +:10C9700000000000000000000000000000000000B7 +:10C9800000000000000000000000000000000000A7 +:10C990000000000000000000000000000000000097 +:10C9A0000000000000000000000000000000000087 +:10C9B0000000000000000000000000000000000077 +:10C9C0000000000000000000000000000000000067 +:10C9D0000000000000000000000000000000000057 +:10C9E0000000000000000000000000000000000047 +:10C9F0000000000000000000000000000000000037 +:10CA00000000000000000000000000000000000026 +:10CA10000000000000000000000000000000000016 +:10CA20000000000000000000000000000000000006 +:10CA300000000000000000000000000000000000F6 +:10CA400000000000000000000000000000000000E6 +:10CA500000000000000000000000000000000000D6 +:10CA600000000000000000000000000000000000C6 +:10CA700000000000000000000000000000000000B6 +:10CA800000000000000000000000000000000000A6 +:10CA90000000000000000000000000000000000096 +:10CAA0000000000000000000000000000000000086 +:10CAB0000000000000000000000000000000000076 +:10CAC0000000000000000000000000000000000066 +:10CAD0000000000000000000000000000000000056 +:10CAE0000000000000000000000000000000000046 +:10CAF0000000000000000000000000000000000036 +:10CB00000000000000000000000000000000000025 +:10CB10000000000000000000000000000000000015 +:10CB20000000000000000000000000000000000005 +:10CB300000000000000000000000000000000000F5 +:10CB400000000000000000000000000000000000E5 +:10CB500000000000000000000000000000000000D5 +:10CB600000000000000000000000000000000000C5 +:10CB700000000000000000000000000000000000B5 +:10CB800000000000000000000000000000000000A5 +:10CB90000000000000000000000000000000000095 +:10CBA0000000000000000000000000000000000085 +:10CBB0000000000000000000000000000000000075 +:10CBC0000000000000000000000000000000000065 +:10CBD0000000000000000000000000000000000055 +:10CBE0000000000000000000000000000000000045 +:10CBF0000000000000000000000000000000000035 +:10CC00000000000000000000000000000000000024 +:10CC10000000000000000000000000000000000014 +:10CC20000000000000000000000000000000000004 +:10CC300000000000000000000000000000000000F4 +:10CC400000000000000000000000000000000000E4 +:10CC500000000000000000000000000000000000D4 +:10CC600000000000000000000000000000000000C4 +:10CC700000000000000000000000000000000000B4 +:10CC800000000000000000000000000000000000A4 +:10CC90000000000000000000000000000000000094 +:10CCA0000000000000000000000000000000000084 +:10CCB0000000000000000000000000000000000074 +:10CCC0000000000000000000000000000000000064 +:10CCD0000000000000000000000000000000000054 +:10CCE0000000000000000000000000000000000044 +:10CCF0000000000000000000000000000000000034 +:10CD00000000000000000000000000000000000023 +:10CD10000000000000000000000000000000000013 +:10CD20000000000000000000000000000000000003 +:10CD300000000000000000000000000000000000F3 +:10CD400000000000000000000000000000000000E3 +:10CD500000000000000000000000000000000000D3 +:10CD600000000000000000000000000000000000C3 +:10CD700000000000000000000000000000000000B3 +:10CD800000000000000000000000000000000000A3 +:10CD90000000000000000000000000000000000093 +:10CDA0000000000000000000000000000000000083 +:10CDB0000000000000000000000000000000000073 +:10CDC0000000000000000000000000000000000063 +:10CDD0000000000000000000000000000000000053 +:10CDE0000000000000000000000000000000000043 +:10CDF0000000000000000000000000000000000033 +:10CE00000000000000000000000000000000000022 +:10CE10000000000000000000000000000000000012 +:10CE20000000000000000000000000000000000002 +:10CE300000000000000000000000000000000000F2 +:10CE400000000000000000000000000000000000E2 +:10CE500000000000000000000000000000000000D2 +:10CE600000000000000000000000000000000000C2 +:10CE700000000000000000000000000000000000B2 +:10CE800000000000000000000000000000000000A2 +:10CE90000000000000000000000000000000000092 +:10CEA0000000000000000000000000000000000082 +:10CEB0000000000000000000000000000000000072 +:10CEC0000000000000000000000000000000000062 +:10CED0000000000000000000000000000000000052 +:10CEE0000000000000000000000000000000000042 +:10CEF0000000000000000000000000000000000032 +:10CF00000000000000000000000000000000000021 +:10CF10000000000000000000000000000000000011 +:10CF20000000000000000000000000000000000001 +:10CF300000000000000000000000000000000000F1 +:10CF400000000000000000000000000000000000E1 +:10CF500000000000000000000000000000000000D1 +:10CF600000000000000000000000000000000000C1 +:10CF700000000000000000000000000000000000B1 +:10CF800000000000000000000000000000000000A1 +:10CF90000000000000000000000000000000000091 +:10CFA0000000000000000000000000000000000081 +:10CFB0000000000000000000000000000000000071 +:10CFC0000000000000000000000000000000000061 +:10CFD0000000000000000000000000000000000051 +:10CFE0000000000000000000000000000000000041 +:10CFF0000000000000000000000000000000000031 +:10D000000000000000000000000000000000000020 +:10D010000000000000000000000000000000000010 +:10D020000000000000000000000000000000000000 +:10D0300000000000000000000000000000000000F0 +:10D0400000000000000000000000000000000000E0 +:10D0500000000000000000000000000000000000D0 +:10D0600000000000000000000000000000000000C0 +:10D0700000000000000000000000000000000000B0 +:10D0800000000000000000000000000000000000A0 +:10D090000000000000000000000000000000000090 +:10D0A0000000000000000000000000000000000080 +:10D0B0000000000000000000000000000000000070 +:10D0C0000000000000000000000000000000000060 +:10D0D0000000000000000000000000000000000050 +:10D0E0000000000000000000000000000000000040 +:10D0F0000000000000000000000000000000000030 +:10D10000000000000000000000000000000000001F +:10D11000000000000000000000000000000000000F +:10D1200000000000000000000000000000000000FF +:10D1300000000000000000000000000000000000EF +:10D1400000000000000000000000000000000000DF +:10D1500000000000000000000000000000000000CF +:10D1600000000000000000000000000000000000BF +:10D1700000000000000000000000000000000000AF +:10D18000000000000000000000000000000000009F +:10D19000000000000000000000000000000000008F +:10D1A000000000000000000000000000000000007F +:10D1B000000000000000000000000000000000006F +:10D1C000000000000000000000000000000000005F +:10D1D000000000000000000000000000000000004F +:10D1E000000000000000000000000000000000003F +:10D1F000000000000000000000000000000000002F +:10D20000000000000000000000000000000000001E +:10D21000000000000000000000000000000000000E +:10D2200000000000000000000000000000000000FE +:10D2300000000000000000000000000000000000EE +:10D2400000000000000000000000000000000000DE +:10D2500000000000000000000000000000000000CE +:10D2600000000000000000000000000000000000BE +:10D2700000000000000000000000000000000000AE +:10D28000000000000000000000000000000000009E +:10D29000000000000000000000000000000000008E +:10D2A000000000000000000000000000000000007E +:10D2B000000000000000000000000000000000006E +:10D2C000000000000000000000000000000000005E +:10D2D000000000000000000000000000000000004E +:10D2E000000000000000000000000000000000003E +:10D2F000000000000000000000000000000000002E +:10D30000000000000000000000000000000000001D +:10D31000000000000000000000000000000000000D +:10D3200000000000000000000000000000000000FD +:10D3300000000000000000000000000000000000ED +:10D3400000000000000000000000000000000000DD +:10D3500000000000000000000000000000000000CD +:10D3600000000000000000000000000000000000BD +:10D3700000000000000000000000000000000000AD +:10D38000000000000000000000000000000000009D +:10D39000000000000000000000000000000000008D +:10D3A000000000000000000000000000000000007D +:10D3B000000000000000000000000000000000006D +:10D3C000000000000000000000000000000000005D +:10D3D000000000000000000000000000000000004D +:10D3E000000000000000000000000000000000003D +:10D3F000000000000000000000000000000000002D +:10D40000000000000000000000000000000000001C +:10D41000000000000000000000000000000000000C +:10D4200000000000000000000000000000000000FC +:10D4300000000000000000000000000000000000EC +:10D4400000000000000000000000000000000000DC +:10D4500000000000000000000000000000000000CC +:10D4600000000000000000000000000000000000BC +:10D4700000000000000000000000000000000000AC +:10D48000000000000000000000000000000000009C +:10D49000000000000000000000000000000000008C +:10D4A000000000000000000000000000000000007C +:10D4B000000000000000000000000000000000006C +:10D4C000000000000000000000000000000000005C +:10D4D000000000000000000000000000000000004C +:10D4E000000000000000000000000000000000003C +:10D4F000000000000000000000000000000000002C +:10D50000000000000000000000000000000000001B +:10D51000000000000000000000000000000000000B +:10D5200000000000000000000000000000000000FB +:10D5300000000000000000000000000000000000EB +:10D5400000000000000000000000000000000000DB +:10D5500000000000000000000000000000000000CB +:10D5600000000000000000000000000000000000BB +:10D5700000000000000000000000000000000000AB +:10D58000000000000000000000000000000000009B +:10D59000000000000000000000000000000000008B +:10D5A000000000000000000000000000000000007B +:10D5B000000000000000000000000000000000006B +:10D5C000000000000000000000000000000000005B +:10D5D000000000000000000000000000000000004B +:10D5E000000000000000000000000000000000003B +:10D5F000000000000000000000000000000000002B +:10D60000000000000000000000000000000000001A +:10D61000000000000000000000000000000000000A +:10D6200000000000000000000000000000000000FA +:10D6300000000000000000000000000000000000EA +:10D6400000000000000000000000000000000000DA +:10D6500000000000000000000000000000000000CA +:10D6600000000000000000000000000000000000BA +:10D6700000000000000000000000000000000000AA +:10D68000000000000000000000000000000000009A +:10D69000000000000000000000000000000000008A +:10D6A000000000000000000000000000000000007A +:10D6B000000000000000000000000000000000006A +:10D6C000000000000000000000000000000000005A +:10D6D000000000000000000000000000000000004A +:10D6E000000000000000000000000000000000003A +:10D6F000000000000000000000000000000000002A +:10D700000000000000000000000000000000000019 +:10D710000000000000000000000000000000000009 +:10D7200000000000000000000000000000000000F9 +:10D7300000000000000000000000000000000000E9 +:10D7400000000000000000000000000000000000D9 +:10D7500000000000000000000000000000000000C9 +:10D7600000000000000000000000000000000000B9 +:10D7700000000000000000000000000000000000A9 +:10D780000000000000000000000000000000000099 +:10D790000000000000000000000000000000000089 +:10D7A0000000000000000000000000000000000079 +:10D7B0000000000000000000000000000000000069 +:10D7C0000000000000000000000000000000000059 +:10D7D0000000000000000000000000000000000049 +:10D7E0000000000000000000000000000000000039 +:10D7F0000000000000000000000000000000000029 +:10D800000000000000000000000000000000000018 +:10D810000000000000000000000000000000000008 +:10D8200000000000000000000000000000000000F8 +:10D8300000000000000000000000000000000000E8 +:10D8400000000000000000000000000000000000D8 +:10D8500000000000000000000000000000000000C8 +:10D8600000000000000000000000000000000000B8 +:10D8700000000000000000000000000000000000A8 +:10D880000000000000000000000000000000000098 +:10D890000000000000000000000000000000000088 +:10D8A0000000000000000000000000000000000078 +:10D8B0000000000000000000000000000000000068 +:10D8C0000000000000000000000000000000000058 +:10D8D0000000000000000000000000000000000048 +:10D8E0000000000000000000000000000000000038 +:10D8F0000000000000000000000000000000000028 +:10D900000000000000000000000000000000000017 +:10D910000000000000000000000000000000000007 +:10D9200000000000000000000000000000000000F7 +:10D9300000000000000000000000000000000000E7 +:10D9400000000000000000000000000000000000D7 +:10D9500000000000000000000000000000000000C7 +:10D9600000000000000000000000000000000000B7 +:10D9700000000000000000000000000000000000A7 +:10D980000000000000000000000000000000000097 +:10D990000000000000000000000000000000000087 +:10D9A0000000000000000000000000000000000077 +:10D9B0000000000000000000000000000000000067 +:10D9C0000000000000000000000000000000000057 +:10D9D0000000000000000000000000000000000047 +:10D9E0000000000000000000000000000000000037 +:10D9F0000000000000000000000000000000000027 +:10DA00000000000000000000000000000000000016 +:10DA10000000000000000000000000000000000006 +:10DA200000000000000000000000000000000000F6 +:10DA300000000000000000000000000000000000E6 +:10DA400000000000000000000000000000000000D6 +:10DA500000000000000000000000000000000000C6 +:10DA600000000000000000000000000000000000B6 +:10DA700000000000000000000000000000000000A6 +:10DA80000000000000000000000000000000000096 +:10DA90000000000000000000000000000000000086 +:10DAA0000000000000000000000000000000000076 +:10DAB0000000000000000000000000000000000066 +:10DAC0000000000000000000000000000000000056 +:10DAD0000000000000000000000000000000000046 +:10DAE0000000000000000000000000000000000036 +:10DAF0000000000000000000000000000000000026 +:10DB00000000000000000000000000000000000015 +:10DB10000000000000000000000000000000000005 +:10DB200000000000000000000000000000000000F5 +:10DB300000000000000000000000000000000000E5 +:10DB400000000000000000000000000000000000D5 +:10DB500000000000000000000000000000000000C5 +:10DB600000000000000000000000000000000000B5 +:10DB700000000000000000000000000000000000A5 +:10DB80000000000000000000000000000000000095 +:10DB90000000000000000000000000000000000085 +:10DBA0000000000000000000000000000000000075 +:10DBB0000000000000000000000000000000000065 +:10DBC0000000000000000000000000000000000055 +:10DBD0000000000000000000000000000000000045 +:10DBE0000000000000000000000000000000000035 +:10DBF0000000000000000000000000000000000025 +:10DC00000000000000000000000000000000000014 +:10DC10000000000000000000000000000000000004 +:10DC200000000000000000000000000000000000F4 +:10DC300000000000000000000000000000000000E4 +:10DC400000000000000000000000000000000000D4 +:10DC500000000000000000000000000000000000C4 +:10DC600000000000000000000000000000000000B4 +:10DC700000000000000000000000000000000000A4 +:10DC80000000000000000000000000000000000094 +:10DC90000000000000000000000000000000000084 +:10DCA0000000000000000000000000000000000074 +:10DCB0000000000000000000000000000000000064 +:10DCC0000000000000000000000000000000000054 +:10DCD0000000000000000000000000000000000044 +:10DCE0000000000000000000000000000000000034 +:10DCF0000000000000000000000000000000000024 +:10DD00000000000000000000000000000000000013 +:10DD10000000000000000000000000000000000003 +:10DD200000000000000000000000000000000000F3 +:10DD300000000000000000000000000000000000E3 +:10DD400000000000000000000000000000000000D3 +:10DD500000000000000000000000000000000000C3 +:10DD600000000000000000000000000000000000B3 +:10DD700000000000000000000000000000000000A3 +:10DD80000000000000000000000000000000000093 +:10DD90000000000000000000000000000000000083 +:10DDA0000000000000000000000000000000000073 +:10DDB0000000000000000000000000000000000063 +:10DDC0000000000000000000000000000000000053 +:10DDD0000000000000000000000000000000000043 +:10DDE0000000000000000000000000000000000033 +:10DDF0000000000000000000000000000000000023 +:10DE00000000000000000000000000000000000012 +:10DE10000000000000000000000000000000000002 +:10DE200000000000000000000000000000000000F2 +:10DE300000000000000000000000000000000000E2 +:10DE400000000000000000000000000000000000D2 +:10DE500000000000000000000000000000000000C2 +:10DE600000000000000000000000000000000000B2 +:10DE700000000000000000000000000000000000A2 +:10DE80000000000000000000000000000000000092 +:10DE90000000000000000000000000000000000082 +:10DEA0000000000000000000000000000000000072 +:10DEB0000000000000000000000000000000000062 +:10DEC0000000000000000000000000000000000052 +:10DED0000000000000000000000000000000000042 +:10DEE0000000000000000000000000000000000032 +:10DEF0000000000000000000000000000000000022 +:10DF00000000000000000000000000000000000011 +:10DF10000000000000000000000000000000000001 +:10DF200000000000000000000000000000000000F1 +:10DF300000000000000000000000000000000000E1 +:10DF400000000000000000000000000000000000D1 +:10DF500000000000000000000000000000000000C1 +:10DF600000000000000000000000000000000000B1 +:10DF700000000000000000000000000000000000A1 +:10DF80000000000000000000000000000000000091 +:10DF90000000000000000000000000000000000081 +:10DFA0000000000000000000000000000000000071 +:10DFB0000000000000000000000000000000000061 +:10DFC0000000000000000000000000000000000051 +:10DFD0000000000000000000000000000000000041 +:10DFE0000000000000000000000000000000000031 +:10DFF0000000000000000000000000000000000021 +:10E000000000000000000000000000000000000010 +:10E010000000000000000000000000000000000000 +:10E0200000000000000000000000000000000000F0 +:10E0300000000000000000000000000000000000E0 +:10E0400000000000000000000000000000000000D0 +:10E0500000000000000000000000000000000000C0 +:10E0600000000000000000000000000000000000B0 +:10E0700000000000000000000000000000000000A0 +:10E080000000000000000000000000000000000090 +:10E090000000000000000000000000000000000080 +:10E0A0000000000000000000000000000000000070 +:10E0B0000000000000000000000000000000000060 +:10E0C0000000000000000000000000000000000050 +:10E0D0000000000000000000000000000000000040 +:10E0E0000000000000000000000000000000000030 +:10E0F0000000000000000000000000000000000020 +:10E10000000000000000000000000000000000000F +:10E1100000000000000000000000000000000000FF +:10E1200000000000000000000000000000000000EF +:10E1300000000000000000000000000000000000DF +:10E1400000000000000000000000000000000000CF +:10E1500000000000000000000000000000000000BF +:10E1600000000000000000000000000000000000AF +:10E17000000000000000000000000000000000009F +:10E18000000000000000000000000000000000008F +:10E19000000000000000000000000000000000007F +:10E1A000000000000000000000000000000000006F +:10E1B000000000000000000000000000000000005F +:10E1C000000000000000000000000000000000004F +:10E1D000000000000000000000000000000000003F +:10E1E000000000000000000000000000000000002F +:10E1F000000000000000000000000000000000809F +:10E20000000000000000000000000000000000000E +:10E2100000000000000000000000000000000000FE +:10E220000000000A000000000000000000000000E4 +:10E2300010000003000000000000000D0000000DB1 +:10E240003C020801244294003C03080124639634F4 +:10E25000AC4000000043202B1480FFFD244200044A +:10E260003C1D080037BD9FFC03A0F0213C100800B6 +:10E27000261032103C1C0801279C94000E001274DA +:10E28000000000000000000D3C02800030A5FFFFF0 +:10E2900030C600FF344301803C0880008D0901B87E +:10E2A0000520FFFE00000000AC6400002404000212 +:10E2B000A4650008A066000AA064000BAC67001803 +:10E2C0003C03100003E00008AD0301B83C0560000A +:10E2D0008CA24FF80440FFFE00000000ACA44FC029 +:10E2E0003C0310003C040200ACA44FC403E000084F +:10E2F000ACA34FF89486000C00A050212488001491 +:10E3000000062B0200051080004448210109182B4B +:10E310001060001100000000910300002C6400094F +:10E320005080000991190001000360803C0D080134 +:10E3300025AD9090018D58218D67000000E0000808 +:10E340000000000091190001011940210109302B42 +:10E3500054C0FFF29103000003E000080000102108 +:10E360000A000CCC25080001910F0001240E000AC0 +:10E3700015EE00400128C8232F38000A1700003D81 +:10E38000250D00028D580000250F0006370E0100F4 +:10E39000AD4E0000910C000291AB000191A400026F +:10E3A00091A60003000C2E00000B3C0000A71025D6 +:10E3B00000041A000043C8250326C025AD580004F8 +:10E3C000910E000691ED000191E7000291E5000336 +:10E3D000000E5E00000D6400016C30250007220075 +:10E3E00000C41025004518252508000A0A000CCC99 +:10E3F000AD430008910F000125040002240800022B +:10E4000055E80001012020210A000CCC00804021A9 +:10E41000910C0001240B0003158B00160000000076 +:10E420008D580000910E000225080003370D0008EA +:10E43000A14E00100A000CCCAD4D00009119000156 +:10E44000240F0004172F000B0000000091070002AA +:10E45000910400038D43000000072A0000A410254A +:10E460003466000425080004AD42000C0A000CCC00 +:10E47000AD46000003E000082402000127BDFFE8CC +:10E48000AFBF0014AFB000100E0015E50080802172 +:10E490003C0480083485008090A600052403FFFE1C +:10E4A0000200202100C310248FBF00148FB0001081 +:10E4B000A0A200050A0015EF27BD001827BDFFE840 +:10E4C000AFB00010AFBF00140E000FD40080802149 +:10E4D0003C06800834C5008090A40000240200504F +:10E4E000308300FF106200073C09800002002021F9 +:10E4F0008FBF00148FB00010AD2001800A0010A65D +:10E5000027BD0018240801003C07800002002021DC +:10E510008FBF00148FB00010ACE801800A0010A675 +:10E5200027BD001827BDFF783C058008AFBE0080DE +:10E53000AFB7007CAFB3006CAFB10064AFBF008475 +:10E54000AFB60078AFB50074AFB40070AFB200687A +:10E55000AFB0006034A600803C0580008CB201287A +:10E5600090C400098CA701043C020001309100FF17 +:10E5700000E218240000B8210000F021106000071C +:10E58000000098213C0908008D2931F02413000176 +:10E59000252800013C010800AC2831F0ACA0008423 +:10E5A00090CC0005000C5827316A0001154000721C +:10E5B000AFA0005090CD00002406002031A400FF41 +:10E5C00010860018240E0050108E009300000000EA +:10E5D0003C1008008E1000DC260F00013C010800F2 +:10E5E000AC2F00DC0E00165E000000000040182179 +:10E5F0008FBF00848FBE00808FB7007C8FB60078FD +:10E600008FB500748FB400708FB3006C8FB2006848 +:10E610008FB100648FB000600060102103E000083B +:10E6200027BD00880000000D3C1F8000AFA0003017 +:10E6300097E501168FE201043C04002030B9FFFF8A +:10E64000004438240007182B00033140AFA60030E7 +:10E650008FF5010437F80C003C1600400338802188 +:10E6600002B6A02434C40040128000479215000D69 +:10E6700032A800201500000234860080008030217E +:10E6800014C0009FAFA600303C0D800835A6008066 +:10E6900090CC0008318B0040516000063C06800899 +:10E6A000240E0004122E00A8240F0012122F003294 +:10E6B0003C06800834C401003C0280009447011AE3 +:10E6C0009619000E909F00088E18000830E3FFFF97 +:10E6D00003F9B00432B40004AFB6005CAFA3005835 +:10E6E0008E1600041280002EAFB8005434C3008090 +:10E6F000906800083105004014A0002500000000CB +:10E700008C70005002D090230640000500000000ED +:10E710008C71003402D1A82306A201678EE20008A2 +:10E72000126000063C1280003C1508008EB531F4E2 +:10E7300026B600013C010800AC3631F4AE4000447E +:10E74000240300018FBF00848FBE00808FB7007C40 +:10E750008FB600788FB500748FB400708FB3006CE3 +:10E760008FB200688FB100648FB00060006010212C +:10E7700003E0000827BD00880E000D2800002021BE +:10E780000A000D75004018210A000D9500C02021D7 +:10E790000E0016AE02C020211440FFE10000000070 +:10E7A0003C0B8008356400808C8A003402CA482300 +:10E7B0000520001D000000003C1E08008FDE310017 +:10E7C00027D700013C010800AC3731001260000679 +:10E7D000024020213C1408008E9431F42690000160 +:10E7E0003C010800AC3031F40E0015E53C1E8008F9 +:10E7F00037CD008091B700250240202136EE00047D +:10E800000E0015EFA1AE00250E000CAC0240202139 +:10E810000A000DCA240300013C17080126F794F8EA +:10E820000A000D843C1F80008C86003002C66023E5 +:10E830001980000C2419000C908F004F3C14080024 +:10E840008E94310032B500FC35ED0001268E0001BA +:10E850003C010800AC2E3100A08D004FAFA0005845 +:10E860002419000CAFB900308C9800300316A02397 +:10E870001A80010B8FA300580074F82A17E0FFD309 +:10E88000000000001074002A8FA5005802D4B021A7 +:10E8900000B410233044FFFFAFA4005832A8000298 +:10E8A0001100002E32AB00103C15800836B00080FD +:10E8B0009216000832D30040526000FB8EE200083E +:10E8C0000E0015E502402021240A0018A20A0009C2 +:10E8D000921100052409FFFE024020210229902404 +:10E8E0000E0015EFA21200052404003900002821B3 +:10E8F0000E001689240600180A000DCA2403000120 +:10E9000092FE000C3C0A800835490080001EBB00C6 +:10E910008D27003836F10081024020213225F08118 +:10E920000E000C9B30C600FF0A000DC10000000065 +:10E930003AA7000130E300011460FFA402D4B02123 +:10E940000A000E1D00000000024020210E0016CB20 +:10E95000020028210A000D75004018211160FF7087 +:10E960003C0F80083C0D800835EE00808DC40038D7 +:10E970008FA300548DA60004006660231D80FF68ED +:10E98000000000000064C02307020001AFA400548F +:10E990003C1F08008FFF31E433F9000113200015FC +:10E9A0008FAC00583C07800094E3011A10600012FD +:10E9B0003C0680080E0020F8024020213C0308019C +:10E9C0009063952930640002148001450000000026 +:10E9D000306C0004118000078FAC0058306600FBDB +:10E9E0003C010801A026952932B500FCAFA00058D3 +:10E9F0008FAC00583C06800834D30080AFB40018B8 +:10EA0000AFB60010AFAC00143C088000950B01209D +:10EA10008E6F0030966A005C8FA3005C8FBF003061 +:10EA20003169FFFF3144FFFF8FAE005401341021E4 +:10EA3000350540000064382B0045C82103E7C02598 +:10EA4000AFB90020AFAF0028AFB80030AFAF00249F +:10EA5000AFA0002CAFAE0034926D000831B40008B6 +:10EA6000168000BB020020218EE200040040F8095D +:10EA700027A400108FAF003031F300025660000170 +:10EA800032B500FE3C048008349F008093F90008F2 +:10EA900033380040530000138FA400248C850004F9 +:10EAA0008FA7005410A700D52404001432B0000131 +:10EAB0001200000C8FA400242414000C1234011A3C +:10EAC0002A2D000D11A001022413000E240E000AAD +:10EAD000522E0001241E00088FAF002425E40001FF +:10EAE000AFA400248FAA00143C0B80083565008079 +:10EAF000008A48218CB10030ACA9003090A4004EAF +:10EB00008CA700303408FFFC0088180400E3F821CB +:10EB1000ACBF00348FA600308FB900548FB8005CB2 +:10EB200030C200081040000B033898218CAC002044 +:10EB3000119300D330C600FF92EE000C8FA7003473 +:10EB400002402021000E6B0035B400800E000C9BAB +:10EB50003285F0803C028008345000808E0F0030F7 +:10EB600001F1302318C00097264800803C070800B8 +:10EB70008CE731E42404FF80010418243118007F5D +:10EB80003C1F80003C19800430F10001AFE300908D +:10EB900012200006031928213C03080190639529DF +:10EBA00030690008152000C6306A00F73C10800864 +:10EBB00036040080908C004F318B000115600042BC +:10EBC000000000003C0608008CC6319830CE0010D2 +:10EBD00051C0004230F9000190AF006B55E0003F9A +:10EBE00030F9000124180001A0B8006B3C1180002E +:10EBF0009622007A24470064A48700123C0D800806 +:10EC000035A5008090B40008329000401600000442 +:10EC10003C03800832AE000115C0008B00000000EC +:10EC2000346400808C86002010D3000A3463010015 +:10EC30008C67000002C7782319E000978FBF00544B +:10EC4000AC93002024130001AC760000AFB3005059 +:10EC5000AC7F000417C0004E000000008FA90050D8 +:10EC60001520000B000000003C030801906395296B +:10EC7000306A00011140002E8FAB0058306400FE56 +:10EC80003C010801A02495290A000D7500001821F7 +:10EC90000E000CAC024020210A000F1300000000FF +:10ECA0000A000E200000A0210040F80924040017EB +:10ECB0000A000DCA240300010040F80924040016CC +:10ECC0000A000DCA240300019094004F240DFFFE9A +:10ECD000028D2824A085004F30F900011320000682 +:10ECE0003C0480083C03080190639529307F0010A4 +:10ECF00017E00051306800EF34900080240A0001D2 +:10ED0000024020210E0015E5A60A001292030025FC +:10ED100024090001AFA90050346200010240202103 +:10ED20000E0015EFA20200250A000EF93C0D800826 +:10ED30001160FE83000018218FA5003030AC000464 +:10ED40001180FE2C8FBF00840A000DCB240300012C +:10ED500027A500380E000CB6AFA000385440FF4382 +:10ED60008EE200048FB40038329001005200FF3F61 +:10ED70008EE200048FA3003C8E6E0058006E682364 +:10ED800005A3FF39AE6300580A000E948EE200041A +:10ED90000E0015E5024020213C0380083468008005 +:10EDA000024020210E0015EFA11E000903C03021F2 +:10EDB000240400370E001689000028210A000F11D4 +:10EDC0008FA900508FAB00185960FF8D3C0D800853 +:10EDD0000E0015E502402021920C002524050001BB +:10EDE000AFA5005035820004024020210E0015EF2F +:10EDF000A20200250A000EF93C0D800812240059D9 +:10EE00002A2300151060004D240900162408000C68 +:10EE10005628FF2732B000013C0A8008914C001BA5 +:10EE20002406FFBD241E000E01865824A14B001BA2 +:10EE30000A000EA532B000013C010801A028952966 +:10EE40000A000EF93C0D80088CB500308EFE0008DB +:10EE50002404001826B6000103C0F809ACB600303F +:10EE60003C030801906395293077000116E0FF818B +:10EE7000306A00018FB200300A000D753243000481 +:10EE80003C1080009605011A50A0FF2B34C60010DC +:10EE90000A000EC892EE000C8C6200001456FF6D42 +:10EEA000000000008C7800048FB9005403388823D8 +:10EEB0000621FF638FBF00540A000F0E0000000000 +:10EEC0003C010801A02A95290A000F3030F9000101 +:10EED0001633FF028FAF00240A000EB0241E00106C +:10EEE0000E0015E5024020213C0B800835680080AB +:10EEF00091090025240A0001AFAA0050353300040F +:10EF0000024020210E0015EFA11300253C05080149 +:10EF100090A5952930A200FD3C010801A022952969 +:10EF20000A000E6D004018212411000E53D1FEEA94 +:10EF3000241E00100A000EAF241E00165629FEDC07 +:10EF400032B000013C0A8008914C001B2406FFBD32 +:10EF5000241E001001865824A14B001B0A000EA598 +:10EF600032B000010A000EA4241E00123C038000EF +:10EF70008C6201B80440FFFE24040800AC6401B8B0 +:10EF800003E00008000000000080502130A5FFFFD2 +:10EF900030C6FFFF3C0480008C8201B80440FFFEB5 +:10EFA00034880180AD0A00003C078008AC8A00204C +:10EFB00094E300483067FFFF10E000423C0D800002 +:10EFC00024AB001200EB482B5120003F2404000327 +:10EFD00034820100945900208F8900002404001A13 +:10EFE0003338FFFF270BFFFE00EB782B39EE0001D3 +:10EFF00000096B8201AE6024A104000B518000491E +:10F000008F8B00048F830004A50B0014346800016B +:10F01000AF88000430CE004015C000333C048000AF +:10F020003C02800034420180A445000E3C07800071 +:10F0300034EC0180A585001A8F85000C310B80000F +:10F04000A5890010AD850028A58600081160000F75 +:10F050008F85001434EA0100954E001631CDFFFC77 +:10F0600025A40004008718218C67400030E6FFFFCC +:10F0700014C000073C0480003C18FFFF370F7FFFDF +:10F08000010F4024AF8800048F8500143C048000E9 +:10F090002402BFFF348301800102C824A479002622 +:10F0A00010A00004AC69002C00054402A465001007 +:10F0B000A46800263C091000AC8901B803E00008F0 +:10F0C000000000002404000335AC018030CE004075 +:10F0D0008F8900008F880004A184000B51C0FFD1EC +:10F0E0003C0280003C048000AC8A00203C0F800879 +:10F0F00095EA00403143FFFF5060000834820180F0 +:10F1000000A3C02B5700000100A0182134990180F2 +:10F11000A723000E0A0010053C0780000A00100318 +:10F1200030C6FFBF2407FFFE016740240A000FFE20 +:10F13000AF88000427BDFFE88FA2002830A5FFFF9D +:10F1400030C6FFFFAFBF0010AF87000CAF820014C6 +:10F15000AF8000040E000FDBAF8000008FBF0010F7 +:10F1600027BD001803E00008AF8000143C068000B3 +:10F1700034C4007034C701008C8A000090E500128E +:10F180008F84000027BDFFF030A300FF000318822A +:10F190003082400010400037246500030005C8801D +:10F1A0000326C0218F0E4000246F0004000F6880EA +:10F1B000AFAE000001A660218D8B4000AFAB000414 +:10F1C00094E900163128FFFC010638218CE6400046 +:10F1D000AFA600088FA900080000302100002821F8 +:10F1E0003C07080024E701000A00107E24080008FC +:10F1F0009059000024A500012CAC000C0079C0211E +:10F200000018788001E770218DCD00001180000684 +:10F2100000CD302603A5102114A8FFF500051A0023 +:10F220005520FFF4905900003C04800034870070A2 +:10F230003C0508008CA531048CE300002CA20020C2 +:10F2400010400009006A3823000548803C0B080084 +:10F25000256B3108012B402124AA0001AD070000D5 +:10F260003C010800AC2A310400C0102103E0000872 +:10F2700027BD0010308220001040000B0005588090 +:10F28000016648218D24400024680004000838806D +:10F29000AFA4000000E618218C654000AFA0000874 +:10F2A0000A00106EAFA500040000000D0A00106FE8 +:10F2B0008FA9000827BDFFD83C058000AFB100141E +:10F2C000AFB00010AFBF0024AFB40020AFB3001C3C +:10F2D000AFB200188F87000034A401009483000EA1 +:10F2E00030E2400000008021104000103071FFFF2C +:10F2F0003C08002000E8302410C0000D30EB8000F6 +:10F300008F890004240ABFFF00EA38243523100047 +:10F31000AF87000030F320001660000B3C1800049B +:10F320002419FFBF0A0010CF0079102430EB8000B1 +:10F330001560004D3C0D002030F320001260FFF8F6 +:10F340008F8300043C18000400F8A0241280FFF50D +:10F350002419FFBF3462004030FF010013E00010A9 +:10F36000AF8200048F820028104000063C0E80000F +:10F370003C04002000E41824146000CE3C06000485 +:10F380003C0E800035CD010095AC001E95AB001CF5 +:10F390003189FFFF000B5400012A4025AF88000C83 +:10F3A0003C138000367401009692000C8E6340007E +:10F3B000340FFFFF106F00843244FFFF30780100EC +:10F3C000570000012410001030F9100053200008ED +:10F3D0003612000130FF002017E000733C031000DC +:10F3E00000E310241440006A3C0A0C0036120001AD +:10F3F00030EC01001580000B3C0600018F880004F2 +:10F40000310D400015A0000800E628243C131F0120 +:10F4100000F378243C0E100011EE00AE3094020090 +:10F420003C06000100E6282410A000193C19100039 +:10F430003C0408008C84002430940002168000D91B +:10F44000240300018FBF00248FB400208FB3001C61 +:10F450008FB200188FB100148FB00010006010211F +:10F4600003E0000827BD002800ED60241180FFB3F1 +:10F4700030F320008F8E00043C12FFFF364F7FFFD9 +:10F4800000EF382435C380000A0010BEAF870000AB +:10F4900000F9C0241700004E00002021AF800010AA +:10F4A0003C0380003465010094AE000E8F91001083 +:10F4B00031CAFFFF108000C62553000430EF010061 +:10F4C00015E000703C180F003A2800022E7003EF80 +:10F4D0002D1900013A1F0001033F282414A0002227 +:10F4E000240400013C0308008C6300D02E25000C8E +:10F4F000001121C0386C00012D8B00010165102422 +:10F50000144000143270FFFF262DFFFC2DA40004D0 +:10F510001480010300002021386A00022D460001FA +:10F5200000C51824546000FF02002821262FFFF890 +:10F530002DEE000415C00007000000000007A242E5 +:10F540000011C02B0298482415200109020028212F +:10F55000001121C002002821364600020E000FDBF8 +:10F560000000000000002021008018218FBF00242F +:10F570008FB400208FB3001C8FB200188FB100141D +:10F580008FB000100060102103E0000827BD0028A4 +:10F590003C090BFF00EA40243526FFFF00C8282B5A +:10F5A00050A0FF93361200013C0B08008D6B002C1D +:10F5B00036120005257000013C010800AC30002C1B +:10F5C0000A0010F630EC01000A0010EB24100020B5 +:10F5D00000071602305F000F001F80C03C030801C7 +:10F5E00024639478020320211080FFADAF9F0010A8 +:10F5F000908800005100FFAB3C0380003C0D800070 +:10F6000035A90100952C000E240B00030240302187 +:10F61000318AFFFF25450004110B00D9000050215D +:10F620009088000124140002311100FF123400BF41 +:10F6300030F80040310300FF24080001106800C8C2 +:10F6400030E200408C8A00048F8B00245560000655 +:10F6500034C60002254DFE002DAC0381558000010B +:10F660003646004034C600020140202130A5FFFF8D +:10F670000E000FDB30C6FFFF000040210A00110A18 +:10F680000100182100F8A0243C0902001289FF8F14 +:10F690003A28000290B100133270FFFF02002821C7 +:10F6A000322700FF24F30004001321C00A00115088 +:10F6B0003646000200E6282414A0FF323C0E8000EB +:10F6C0000E0010543C1380008F8700000A0010E2E7 +:10F6D000AF82000C1680FF533C0600012624000474 +:10F6E0003085FFFF364600023C0380008C7101B874 +:10F6F0000620FFFE8F890008346A0180AD400000BB +:10F70000112000B23C0D800024B800120138902B6B +:10F71000124000AF240C0003347001009603002057 +:10F720002402001A30F94000307FFFFFA142000B95 +:10F73000132000AB27E3FFFE0123582B156000A91F +:10F740002409FFFE35080001A5430014AF8800041A +:10F750003C0E80002413BFFF0113782435C80180BC +:10F76000A505000EA505001AA5060008A50F002690 +:10F77000A50700103C071000ADC701B80000182114 +:10F780008FBF00248FB400208FB3001C8FB20018ED +:10F790008FB100148FB000100060102103E000084A +:10F7A00027BD00283C1208008E5200D802202821D4 +:10F7B00024040080265100013C010800AC3100D82F +:10F7C0000E000FDB240600030A0011D900001821E7 +:10F7D0008C65400030B1010012200046325900040F +:10F7E0003C1F08008FFF002424140004172000028F +:10F7F00033F0000D2414000200076AC239A400018E +:10F800002E6C03EF30820001398B0001004B402544 +:10F81000110000033251FFFB2412FFFB021280246F +:10F8200030E3010050600015321F00013C0A0F0058 +:10F8300000EA30243C07020010C7000F3C1980008A +:10F840003725010090A900132418FFFE0218802418 +:10F85000312F00FF25EE0004000E21C0120000022F +:10F86000023430253226FFFF0E000FDB3265FFFF2A +:10F870001200FF3D00002021321F000113E0000DA7 +:10F88000320B000424080001120800020234302563 +:10F890003226FFFF000020210E000FDB3265FFFF44 +:10F8A0002402FFFE020280241200FF2F000020210C +:10F8B000320B00045160000D240400010234302595 +:10F8C00024140004561400013226FFFF2411FFFB0C +:10F8D0003265FFFF240401000E000FDB02119824A3 +:10F8E0001260FF2100002021240400010A001154AD +:10F8F000008018213C0C08008D8C00243190000100 +:10F900005200FF19000020213265FFFF3646000239 +:10F910000E000FDB000020210A00115300002021FF +:10F92000020028210A00115036460002130000068A +:10F930000000000095300010949F000232190FFF64 +:10F9400013F9FF3D310300FF3C04080190849479D2 +:10F950001080FF3D240800010A00110A010018214F +:10F960005040FF398C8A00040A00124B000000004E +:10F970000E000FDB3246FFFB0A00114E001121C0C2 +:10F9800090830001240E0001106EFF3C240800014A +:10F99000240F0002106F000430F30040240800011F +:10F9A0000A00110A010018215260FFFD240800011D +:10F9B000952500109487000230A9FFFF50E9FEA1B1 +:10F9C000010018210A00126124080001240C000320 +:10F9D00035AA0180A14C000B0A0011CE3C0E80001C +:10F9E0002409FFFE0A0011CC0109402427BDFFC0F5 +:10F9F000AFB00018AFBF003C3C10600CAFBE003889 +:10FA0000AFB70034AFB60030AFB5002CAFB40028AC +:10FA1000AFB30024AFB20020AFB1001C8E0E500077 +:10FA2000240FFF7F3C06800001CF682435AC380CE2 +:10FA3000240B0003AE0C5000ACCB00083C010800C6 +:10FA4000AC2000200E0017B0000000003C0A00109F +:10FA5000354980513C066016AE09537C8CC70000C6 +:10FA60003C0860148D0500A03C03FFFF00E3202448 +:10FA70003C02535300051FC21082029B34C57C0018 +:10FA80008CBF007C8CA200783C1E600037C4202014 +:10FA90003C05080124A590C0AF820018AF9F001C50 +:10FAA0000E0016742406000A3C19000127399478C8 +:10FAB0003C010800AC3931DC0E00206BAF80001433 +:10FAC0008FD708082418FFF03C15570902F8B02416 +:10FAD00012D5028B24040001AF8000283C14800062 +:10FAE0003697010002E0F0218E90000032050003FD +:10FAF00010A0FFFD3207000114E0005D3206000295 +:10FB000010C0FFF93C07800034E501408CB90000CB +:10FB100024100040ACF9002090B8000833030070B6 +:10FB20001070010B286900411120000824080060B2 +:10FB3000241F0020107F000E3C0B40003C0680007C +:10FB4000ACCB01780A0012B3000000001468FFFB80 +:10FB50003C0B40000E001F88000000003C0B4000E2 +:10FB60003C068000ACCB01780A0012B30000000014 +:10FB700090AB0009241100048CA70000316800FF3D +:10FB80001111015D2512FFFA2E53000612600016B6 +:10FB90003C0680008CAA00048F86002494A3000AEF +:10FBA000000A3E02310500FF10C000053064FFFF6F +:10FBB0002CEC00081580000224E700042407000351 +:10FBC000240E000910AE01A128AF000A11E0018443 +:10FBD0002410000A2404000810A4001A000749C0D9 +:10FBE000012038213C0680008CD001B80600FFFEC1 +:10FBF00034C40180AC87000034C5014090B60008D1 +:10FC0000241900023C0B400032C200FF00028A00AF +:10FC10000228F825A49F0008A099000B94A7000AC9 +:10FC20003C081000A48700108CB80004AC98002495 +:10FC3000ACC801B83C068000ACCB01780A0012B316 +:10FC400000000000000AC202330300FF2405000187 +:10FC50005465FFE4012038218F990020AF830024F0 +:10FC600027270001AF8700200A0012F20120382167 +:10FC70008FD100283C0B8008AE9100208FC6000475 +:10FC80008FCA000095690048AF860000AF8A000463 +:10FC90003128FFFF0E000FD4AF8800083C03080096 +:10FCA0008C6300C0106000258F8700003C0E0800A8 +:10FCB0008DCE00C425CD00013C010800AC2D00C450 +:10FCC0003C1F800037E901008D3900243C0760208B +:10FCD000ACF90014000000003C0680003C08400025 +:10FCE000ACC80138000000005220FF853206000237 +:10FCF000262D0140262E00802404FF8001A4282404 +:10FD000001C47824000F194031CC007F00059940D0 +:10FD100031B2007F3C15200036A20002006C502555 +:10FD20000272B02502C2882501425825ACCB0830AA +:10FD3000ACD108300A0012B9320600023C120010A1 +:10FD400000F2782415E000708F8300043C1808004E +:10FD50008F18002097D6000E30F5400027130001C1 +:10FD60003C010800AC3300200000902112A000816B +:10FD700032D3FFFF3C1F002000FFC8241320007E69 +:10FD800030E580008F8200042404BFFF00E43824A3 +:10FD900034431000AF87000030EB20001160007387 +:10FDA000240EFFBF3C0D000400ED60241180000212 +:10FDB000006E10243462004030EF010011E00010AA +:10FDC000AF8200048F95002812A000073C18002085 +:10FDD00000F8B02412C000043C1F000400FFC82437 +:10FDE0001320016D0000000096E3001E96E8001C41 +:10FDF0003065FFFF0008140000A22025AF84000C2E +:10FE000096EA000C8E8440003409FFFF10890085BB +:10FE10003145FFFF3086010054C00001241200105C +:10FE200030EB1000116000133656000130EC00205A +:10FE30001580000A3C0E100000EE682411A0000D91 +:10FE40003C190C003C180BFF00F9B0243715FFFFDC +:10FE500002B6782B11E00007365600013C1F08005F +:10FE60008FFF002C3656000527F200013C010800E8 +:10FE7000AC32002C30E401001480000B3C06000181 +:10FE80008F880004310240005440000800E6282416 +:10FE90003C0A1F0100EA48243C0310001123010919 +:10FEA00030A602003C06000100E6282410A0003E17 +:10FEB0003C1810003C0D08008DAD002431AC000250 +:10FEC0001580000624030001006010211040FF830C +:10FED0003C0680000A00132A3C1F80003C0F0800EB +:10FEE0008DEF00D8026028212404008025EE000157 +:10FEF0003C010800AC2E00D80E000FDB24060003E6 +:10FF00000A0013AB000018212405BFFF0065682418 +:10FF100011A00007240F87FF006F702415C0000890 +:10FF20003C18006000F8202410800005000000004C +:10FF30000E000D42000000000A0013AC000000009B +:10FF40000E00159C000000000A0013AC0000000029 +:10FF50000E0015F4000000003C0B40003C06800041 +:10FF6000ACCB01780A0012B3000000000A0013674E +:10FF7000006E102430E5800010A0FF878F830004FE +:10FF80003C08002000E818245060FF838F830004A1 +:10FF90008F8900043C06FFFF34CA7FFF00EA382443 +:10FFA0000A00135E3523800000F8A82416A0001F65 +:10FFB00000004021AF8000103C0380003464010049 +:10FFC0009486000E8F93001030C5FFFF1100014E84 +:10FFD00024B5000430EA0100114000553A7F0002C8 +:10FFE0003C0E0F0000EE68243C0C020011AC0051E6 +:10FFF0002EB203EF908F001332B2FFFF31E400FF07 +:020000040001F9 +:1000000024870004000721C00240282136C60002D0 +:100010000E000FDB00000000000020210A0013ABDF +:10002000008018210A0013812412002000072602F4 +:100030003099000F0019F8C03C120801265294783C +:1000400003F240211100FFDCAF990010910900007C +:100050001120FFDA3C0380003C138000366A010067 +:10006000954B000E2403000302C030213162FFFFD4 +:1000700024450004112300EC000020219109000117 +:10008000240D0002312E00FF11CD00FA313200FFA5 +:10009000240900011249001030FF00408D040004C3 +:1000A0008F8300241460000634D30002248BFE00EA +:1000B0002D6203815440000136C6004034D3000253 +:1000C00030A5FFFF0E000FDB3266FFFF0000482166 +:1000D0000A0013AB0120182153E0FFF18D04000446 +:1000E0003C080801910894791100FFED24090001F2 +:1000F0000A0013AB012018213C0480008C8A01B84F +:100100000540FFFE349601802415001CAEC7000098 +:10011000A2D5000B3C021000AC8201B83C0B4000A1 +:100120003C068000ACCB01780A0012B3000000004E +:100130002EB203EF2FF900013A4900010329C02430 +:100140001700FFB6240400013C0308008C6300D0B4 +:100150002E65000C001321C0386B00012D620001D8 +:10016000004540241500FFA832B2FFFF266AFFFCBD +:100170002D46000414C0001300002021386D000239 +:100180002DAC0001018518241460000F02402821C5 +:10019000266EFFF82DC5000414A0FF9B0000000090 +:1001A00000077A420013382B01E7A82456A0000864 +:1001B00002402821001321C0024028210A0013FD1B +:1001C00036C60002024028210A0013FD36C600028E +:1001D0000E000FDB32C6FFFB0A001467001321C0BC +:1001E00010B0007200045A022406000B14A6FE7C14 +:1001F000000749C0314600FF00065600000A5E03B2 +:10020000056200B030C6007F000670C03C0F0801D8 +:1002100025EF947801CFA821A2A00001A2A00000A0 +:100220003C1360008E631820240D000100CD4804AB +:1002300000096027000749C0006C90240120382184 +:10024000AE7218200A0012F2A6A0000214C0004BE1 +:100250008F8C0020000749C03C0B8000AD69002056 +:100260003C118008963F004013E000022405000185 +:10027000240500413C0480008C8A01B80540FFFE43 +:100280003496018024120003AEC90000A2D2000BF4 +:10029000A6C0000EA6C0001AA6C00010AEC000285E +:1002A000A6C5000896D3002636750001A6D50026FF +:1002B000AEC0002C3C021000AC8201B80A0012F261 +:1002C0000120382114C0FEF83C060001266B000412 +:1002D0003165FFFF36C600023C0380008C7301B815 +:1002E0000660FFFE8F8900083C0D800035AC018060 +:1002F000AD800000512000DD3C09800024AF0012D9 +:10030000012F702B51C000D93C09800096F20020CB +:100310003C1980002418001A3256FFFF372A01804A +:1003200030F54000A158000B12A000D526C3FFFEF7 +:100330000123F82B17E000D32404FFFE3508000149 +:10034000A5430014AF8800042413BFFF3C0B8000BA +:100350000113502435680180A505000EA505001A7B +:10036000A5060008A50A0026A50700103C071000F6 +:10037000AE8701B80A0013AB00001821000749C07E +:100380002583FFFF1460FE16AF8300200120382173 +:100390000A0012F2AF8000240E001054000000008A +:1003A0008F8700000A001379AF82000C240300FF3E +:1003B0001163FE0B000749C010C00038000B760027 +:1003C000000B20C03C0908012529947800891821D8 +:1003D00024020001A06200003C16080126D6947891 +:1003E0003C0208012442947C00962821000749C061 +:1003F00000828821000AFC02AE290000A0BF000193 +:100400003C0460008C9818202419000101793804FC +:100410000307302501203821A4AA0002AC86182049 +:100420000A0012F33C06800091030001241600012B +:100430001076FF272409000124050002106500043E +:1004400030E60040240900010A0013AB0120182106 +:1004500050C0FFFD24090001954C0010950A0002D0 +:100460003187FFFF5147FE98012018210A00150B24 +:100470002409000130EF004011E0FF1900000000E6 +:10048000955900109518000233350FFF1715FF140A +:10049000313200FF0A00141E24090001000E6E0311 +:1004A00005A2000F316B007F10E30008000B20C095 +:1004B0003C10080126109478009018210A0014EED0 +:1004C000240200020A00147BAF8000203C0F0801C8 +:1004D00025EF9478008F18210A0014EE24020003FF +:1004E0000A001523AF8B00200003A080028698210C +:1004F0008E7200043C1160000A00129902512821FA +:100500000A0012B0AF8400288C64400030930100D0 +:100510001260004B240900043C1908008F390024A4 +:1005200032D80004AFA90010170000033332000DC9 +:10053000241F0002AFBF001000071AC2386A000172 +:100540002EA603EF3142000138CB0001004B4025BD +:100550001100000332D3FFFB2416FFFB0256902448 +:1005600030EC010011800016324800013C0E0F00F3 +:1005700000EE28243C0D020010AD00113C1F80004D +:1005800037E90100913800138FAF00102419FFFEE6 +:10059000330400FF2487000402599024000721C07F +:1005A00012400002026F30253266FFFF0E000FDBA3 +:1005B00032A5FFFF1240FE990000202132480001C1 +:1005C0001100000E324A00048FAB0010240200011B +:1005D00012420002026B30253266FFFF000020212C +:1005E0000E000FDB32A5FFFF2406FFFE024690241B +:1005F0001240FE8A00002021324A00045140000EC1 +:10060000240400018FB600102403000412430002EA +:10061000027630253266FFFF2413FFFB32A5FFFF71 +:10062000240401000E000FDB0253A82412A0FE7B5D +:1006300000002021240400010A0013AB00801821CF +:100640003C0C08008D8C0024319200015240FE7356 +:100650000000202132A5FFFF36C600020E000FDB8E +:10066000000020210A0014000000202124020003C1 +:1006700035230180A062000B0A0014CC2413BFFFB5 +:100680002404FFFE0A0014CA010440243C03800035 +:10069000346401008C85000030A2003E1440000844 +:1006A00000000000AC6000488C87000030E607C006 +:1006B00010C0000500000000AC60004CAC600050B1 +:1006C00003E0000824020001AC600054AC6000406C +:1006D0008C880000310438001080FFF90000000011 +:1006E0002402000103E00008AC6000443C038000E9 +:1006F0008C6201B80440FFFE34670180ACE4000066 +:1007000024080001ACE00004A4E500082405000270 +:10071000A0E8000A34640140A0E5000B9483000ABD +:1007200014C00008A4E30010ACE000243C078000E3 +:1007300034E901803C041000AD20002803E00008EB +:10074000ACE401B88C8600043C041000ACE6002444 +:100750003C07800034E90180AD20002803E0000858 +:10076000ACE401B83C0680008CC201B80440FFFE36 +:1007700034C7018024090002ACE40000ACE40004AA +:10078000A4E50008A0E9000A34C50140A0E9000B77 +:1007900094A8000A3C041000A4E80010ACE0002477 +:1007A0008CA30004ACE3002803E00008ACC401B84B +:1007B0003C03900034620001008220253C0380004D +:1007C000AC6400208C65002004A0FFFE0000000047 +:1007D00003E00008000000003C02800034430001F8 +:1007E0000083202503E00008AC44002027BDFFE083 +:1007F0003C098000AFBF0018AFB10014AFB00010CB +:10080000352801408D10000091040009910700086F +:1008100091050008308400FF30E600FF00061A0052 +:100820002C820081008330251040002A30A50080F2 +:10083000000460803C0D080125AD90E8018D582131 +:100840008D6A000001400008000000003C038000A9 +:10085000346201409445000A14A0001E8F91FCB838 +:100860009227000530E6000414C0001A00000000C2 +:100870000E0015E502002021922A00050200202129 +:10088000354900040E0015EFA22900059228000545 +:100890003104000414800002000000000000000D7C +:1008A000922D0000240B002031AC00FF158B0009B5 +:1008B0003C0580008CAE01B805C0FFFE34B101805C +:1008C000AE3000003C0F100024100005A230000BD9 +:1008D000ACAF01B80000000D8FBF00188FB100143D +:1008E0008FB0001003E0000827BD00200200202187 +:1008F00000C028218FBF00188FB100148FB00010E6 +:10090000240600010A0015B427BD00200000000DD8 +:100910000200202100C028218FBF00188FB10014D1 +:100920008FB00010000030210A0015B427BD002050 +:1009300014A0FFE800000000020020218FBF001873 +:100940008FB100148FB0001000C028210A0015D20A +:1009500027BD00203C0780008CEE01B805C0FFFEDB +:1009600034F00180241F0002A21F000B34F8014064 +:10097000A60600089719000A3C0F1000A6190010DF +:100980008F110004A6110012ACEF01B80A00163056 +:100990008FBF001827BDFFE8AFBF00100E000FD4B7 +:1009A000000000003C0280008FBF001000002021EA +:1009B000AC4001800A0010A627BD00183084FFFF5C +:1009C00030A5FFFF108000070000182130820001D1 +:1009D0001040000200042042006518211480FFFB33 +:1009E0000005284003E000080060102110C0000747 +:1009F000000000008CA2000024C6FFFF24A5000414 +:100A0000AC82000014C0FFFB2484000403E0000853 +:100A10000000000010A0000824A3FFFFAC86000027 +:100A200000000000000000002402FFFF2463FFFF1D +:100A30001462FFFA2484000403E0000800000000B0 +:100A40003C03800027BDFFF834620180AFA20000A4 +:100A5000308C00FF30AD00FF30CE00FF3C0B80003B +:100A60008D6401B80480FFFE000000008FA9000023 +:100A70008D6801288FAA00008FA700008FA40000B6 +:100A80002405000124020002A085000A8FA30000B3 +:100A9000359940003C051000A062000B8FB80000A3 +:100AA0008FAC00008FA600008FAF000027BD0008AC +:100AB000AD280000AD400004AD800024ACC000288B +:100AC000A4F90008A70D0010A5EE001203E000082D +:100AD000AD6501B83C06800827BDFFE834C500803D +:100AE000AFBF001090A700092402001230E300FFFE +:100AF0001062000B008030218CA800500088202359 +:100B0000048000088FBF00108CAA00342404003930 +:100B10000000282100CA48230520000524060012F1 +:100B20008FBF00102402000103E0000827BD001859 +:100B30000E001689000000008FBF00102402000183 +:100B400003E0000827BD001827BDFFC8AFB2003082 +:100B5000AFB00028AFBF0034AFB1002C00A080219F +:100B600090A5000D30A6001010C00010008090214C +:100B70003C0280088C4400048E0300081064000CC2 +:100B800030A7000530A6000510C000932404000122 +:100B90008FBF00348FB200308FB1002C8FB000288F +:100BA0000080102103E0000827BD003830A70005B1 +:100BB00010E0000F30AB001210C00006240400014A +:100BC0003C0980088E0800088D2500045105009C12 +:100BD000240400388FBF00348FB200308FB1002C56 +:100BE0008FB000280080102103E0000827BD0038E6 +:100BF000240A0012156AFFE62404000102002021E5 +:100C000027A500100E000CB6AFA000101440007C09 +:100C10003C198008372400809098000833110008A0 +:100C20001220000A8FA7001030FF010013E000A47B +:100C30008FA300148C860058006610230440000423 +:100C40003C0A8008AC8300588FA700103C0A80083B +:100C50003548008091090008312400081480000202 +:100C600024080003000040213C1F800893F100117C +:100C700093F9001237E600808CCC0054333800FF23 +:100C800003087821322D00FF000F708001AE28216B +:100C900000AC582B1160006F0000000094CA005C8B +:100CA0008CC900543144FFFF012510230082182B0A +:100CB00014600068000000008CCB0054016518230C +:100CC00030EC00041180006C000830808FA8001CFC +:100CD0000068102B1040006230ED00040066102305 +:100CE0002C46008010C000020040882124110080A2 +:100CF0000E0015E5024020213C0D800835A600803D +:100D000024070001ACC7000C90C80008001148403F +:100D100035A70100310C007FA0CC00088E0500042F +:100D200024AB0001ACCB0030A4D1005C8CCA003CE9 +:100D30009602000E01422021ACC400208CC3003C6E +:100D40000069F821ACDF001C8E190004ACF900002A +:100D50008E180008ACF800048FB10010322F000884 +:100D600055E0004793A60020A0C0004E90D8004E4A +:100D70002411FFDFA0F8000890CF000801F17024D3 +:100D8000A0CE00088E0500083C0B80083569008065 +:100D9000AD2500388D6A00148D22003024190050D2 +:100DA00001422021AD24003491230000307F00FF58 +:100DB00013F90036264F01000E0015EF02402021E6 +:100DC00024040038000028210E0016892406000A99 +:100DD0000A0016EE240400010E000D280000202158 +:100DE0008FBF00348FB200308FB1002C8FB000283D +:100DF000004020210080102103E0000827BD0038BA +:100E00008E0E00083C0F800835F00080AE0E0054B6 +:100E100002402021AE0000300E0015E50000000069 +:100E2000920D00250240202135AC00200E0015EF68 +:100E3000A20C00250E000CAC024020212404003836 +:100E40002405008D0E001689240600120A0016EEF5 +:100E50002404000194C5005C0A00172930A3FFFF99 +:100E60002407021811A0FF9E00E610238FAE001C7D +:100E70000A00173101C610230A00172E2C6202182F +:100E8000A0E600080A00175B8E0500082406FF8014 +:100E900001E6C0243C118000AE3800288E0D000809 +:100EA00031E7007F3C0E800C00EE6021AD8D00E04C +:100EB0008E080008AF8C00340A001767AD8800E484 +:100EC000AC800058908500082403FFF700A3382465 +:100ED000A08700080A00170C8FA700103C05080027 +:100EE00024A55F043C04080024846E503C020800E2 +:100EF00024425F0C240300063C010801AC2594F851 +:100F00003C010801AC2494FC3C010801AC22950092 +:100F10003C010801A023950403E000080000000044 +:100F200003E00008240200013C028000308800FF3A +:100F3000344701803C0680008CC301B80460FFFE8A +:100F4000000000008CC501282418FF803C0D800A99 +:100F500024AF010001F8702431EC007FACCE0024F6 +:100F6000018D2021ACE50000948B00EA350960007A +:100F700024080002316AFFFFACEA000424020001E9 +:100F8000A4E90008A0E8000BACE000243C07100036 +:100F9000ACC701B8AF84003403E00008AF85006837 +:100FA000938800448F89005C8F82003430C600FF34 +:100FB0000109382330E900FF0122182130A500FF84 +:100FC0002468008810C000020124382100803821E4 +:100FD00030E400031480000330AA00031140000D28 +:100FE000312B000310A000090000102190ED00003B +:100FF000244E000131C200FF0045602BA10D00000E +:1010000024E700011580FFF92508000103E000082E +:10101000000000001560FFF30000000010A0FFFBBF +:10102000000010218CF8000024590004332200FF36 +:101030000045782BAD18000024E7000415E0FFF907 +:101040002508000403E00008000000009385004428 +:10105000938800548F87005C000432003103007FC6 +:1010600000E5102B30C47F001040000F00642825DD +:101070008F8400343C0980008C8A00ECAD2A00A4E7 +:101080003C03800000A35825AC6B00A08C6C00A032 +:101090000580FFFE000000008C6D00ACAC8D00EC04 +:1010A00003E000088C6200A80A0018198F8400343D +:1010B000938800553C02800000805021310300FEDF +:1010C000A383005530ABFFFF30CC00FF30E7FFFFBC +:1010D000344801803C0980008D2401B80480FFFE63 +:1010E0008F8D006824180016AD0D00008D2201249C +:1010F0008F8D0034AD0200048D590020A507000833 +:10110000240201C4A119000AA118000B952F012087 +:101110008D4E00088D470004978300588D59002498 +:1011200001CF302100C7282100A320232418FFFF6E +:10113000A504000CA50B000EA5020010A50C0012C2 +:10114000AD190018AD18002495AF00E83C0B100055 +:101150002407FFF731EEFFFFAD0E00288DAC0084B1 +:10116000AD0C002CAD2B01B88D46002000C7282403 +:1011700003E00008AD4500208F880034008058212E +:1011800030E7FFFF910900D63C02800030A5FFFF49 +:10119000312400FF00041A000067502530C600FF0C +:1011A000344701803C0980008D2C01B80580FFFE8A +:1011B0008F820068240F0017ACE200008D390124F3 +:1011C000ACF900048D780020A4EA0008241901C4B9 +:1011D000A0F8000AA0EF000B952301208D6E0008F7 +:1011E0008D6D00049784005801C35021014D60218A +:1011F00001841023A4E2000CA4E5000EA4F9001061 +:10120000A4E60012ACE000148D780024240DFFFF4A +:10121000ACF800188D0F007CACEF001C8D0E007830 +:101220003C0F1000ACEE0020ACED0024950A00BE8F +:10123000240DFFF73146FFFFACE60028950C008037 +:101240009504008231837FFF0003CA003082FFFFD4 +:101250000322C021ACF8002CAD2F01B8950E0082FE +:101260008D6A002000AE3021014D2824A5060082A1 +:1012700003E00008AD6500203C0280003445018099 +:101280003C0480008C8301B80460FFFE8F8A00401C +:10129000240600199549001C3128FFFF000839C0B9 +:1012A000ACA70000A0A6000B3C05100003E000085E +:1012B000AC8501B88F8700480080402130C400FF12 +:1012C0003C0680008CC201B80440FFFE8F89006894 +:1012D0009383006434996000ACA90000A0A30005CA +:1012E0008CE20010240F00022403FFF7A4A20006E2 +:1012F000A4B900088D180020A0B8000AA0AF000B08 +:101300008CEE0000ACAE00108CED0004ACAD00140F +:101310008CEC001CACAC00248CEB0020ACAB0028A7 +:101320008CEA002C3C071000ACAA002C8D0900248C +:10133000ACA90018ACC701B88D05002000A320247B +:1013400003E00008AD0400208F86003427BDFFE0D5 +:10135000AFB10014AFBF0018AFB0001090C300D4FD +:1013600030A500FF30620020104000080080882176 +:101370008CCB00D02409FFDF256A0001ACCA00D065 +:1013800090C800D401093824A0C700D414A000409C +:101390003C0C80008F840034908700D42418FFBF59 +:1013A0002406FFEF30E3007FA08300D4979F00580E +:1013B0008F82005C8F8D003403E2C823A799005808 +:1013C000A5A000BC91AF00D401F87024A1AE00D458 +:1013D0008F8C0034A18000D78F8A0034A540008212 +:1013E000AD4000EC914500D400A65824A14B00D498 +:1013F0008F9000308F84005C97860058020428216B +:1014000010C0000FAF850030A38000543C0780005F +:101410008E2C000894ED01208E2B0004018D5021AC +:10142000014B8021020620233086FFFF30C8000FC9 +:10143000390900013131000116200009A388005448 +:10144000938600448FBF00188FB100148FB0001036 +:1014500027BD0020AF85006003E00008AF86005C78 +:1014600000C870238FBF0018938600448FB100140A +:101470008FB0001034EF0C00010F282127BD002091 +:10148000ACEE0084AF85006003E00008AF86005C2E +:1014900035900180020028210E0018A62406008243 +:1014A0008F840034908600D430C5004050A0FFBA2D +:1014B000A38000648F8500483C0680008CCD01B875 +:1014C00005A0FFFE8F8900682408608224070002BF +:1014D000AE090000A6080008A207000B8CA30008B4 +:1014E0003C0E1000AE0300108CA2000CAE020014E3 +:1014F0008CBF0014AE1F00188CB90018AE19002460 +:101500008CB80024AE1800288CAF0028AE0F002C39 +:10151000ACCE01B80A0018DFA38000648F8A0034C3 +:1015200027BDFFE0AFB10014AFB000108F88005CA2 +:10153000AFBF001893890038954200BC30D100FF3E +:101540000109182B0080802130AC00FF3047FFFFDD +:101550000000582114600003310600FF01203021F3 +:1015600001095823978300580068202B1480002716 +:101570000000000010680056241900011199006352 +:1015800034E708803165FFFF0E0018570200202164 +:101590008F8300683C07800034E601803C058000B2 +:1015A0008CAB01B80560FFFE240A00188F8400345C +:1015B000ACC30000A0CA000B948900BE3C08100018 +:1015C000A4C90010ACC00030ACA801B8948200805F +:1015D00024430001A4830080949F00803C060800FF +:1015E0008CC6318833EC7FFF1186005E000000005E +:1015F00002002021022028218FBF00188FB1001483 +:101600008FB000100A0018CB27BD0020914400D4F1 +:101610002403FF8000838825A15100D497840058BB +:101620003088FFFF51000023938C00388F850034F1 +:101630002402EFFF008B782394AE00BC0168502B8E +:1016400031E900FF01C26824A4AD00BC514000395B +:10165000010058213C1F800037E601008CD80004AF +:101660003C190001031940245500000134E74000F3 +:101670008E0A00202403FFFB2411000101432024D3 +:10168000AE0400201191002D34E7800002002021DB +:10169000012030210E0018573165FFFF9787005851 +:1016A0008F89005CA780005801278023AF90005CE1 +:1016B000938C00388F8B00348FBF00188FB10014CB +:1016C0008FB0001027BD002003E00008A16C00D7F8 +:1016D0003C0D800035AA01008D4800043C09000142 +:1016E0000109282454A0000134E740008E0F002097 +:1016F0002418FFFB34E7800001F87024241900014E +:10170000AE0E00201599FF9F34E7088002002021CB +:101710000E0018253165FFFF02002021022028213C +:101720008FBF00188FB100148FB000100A0018CBC3 +:1017300027BD00200A00198E000048210200202148 +:10174000012030210E0018253165FFFF97870058D2 +:101750008F89005CA7800058012780230A0019A503 +:10176000AF90005C948C0080241F8000019F302487 +:10177000A4860080908B0080908F0080316700FFEE +:101780000007C9C20019C027001871C031ED007FE1 +:1017900001AE2825A08500800A00197602002021CC +:1017A000938500642403000127BDFFE800A33004F3 +:1017B0002CA20020AFB00010AFBF001400C0182151 +:1017C000104000132410FFFE3C0708008CE7319006 +:1017D00000E610243C088000350501801440000517 +:1017E000240600848F890034240A00042410FFFF9B +:1017F000A12A00FC0E0018A6000000000200102123 +:101800008FBF00148FB0001003E0000827BD001840 +:101810003C0608008CC631940A0019EE00C310245F +:101820008F87004027BDFFE0AFB20018AFB10014B2 +:10183000AFB00010AFBF001C30D000FF90E6000D2D +:1018400000A088210080902130C5007FA0E5000D18 +:101850008F8500348E2300188CA200D01062002ED9 +:10186000240A000E0E0019E1A38A00642409FFFF78 +:10187000104900222404FFFF520000200000202114 +:101880008E2600003C0C001000CC58241560003956 +:101890003C0E000800CE682455A0003F02402021E5 +:1018A0003C18000200D880241200001F3C0A0004EB +:1018B0008F8700408CE200148CE300108CE500144C +:1018C0000043F82303E5C82B132000050240202124 +:1018D0008E24002C8CF10010109100310240202148 +:1018E00024020012A38200640E0019E12412FFFFFB +:1018F000105200022404FFFF000020218FBF001CB3 +:101900008FB200188FB100148FB00010008010212A +:1019100003E0000827BD002090A800D43504002073 +:101920000A001A17A0A400D400CA48241520000BEE +:101930008F8B00408F8D00408DAC00101580000B08 +:10194000024020218E2E002C51C0FFEC00002021EF +:10195000024020210A001A32240200178D6600106E +:1019600050C0FFE600002021024020210A001A3268 +:101970002402001102402021240200150E0019E16A +:10198000A3820064240FFFFF104FFFDC2404FFFF3D +:101990000A001A218E2600000A001A582402001498 +:1019A0003C08000400C8382450E0FFD40000202187 +:1019B000024020210A001A32240200138F850034CD +:1019C00027BDFFD8AFB3001CAFB20018AFB10014F1 +:1019D000AFB00010AFBF002090A700D48F90004898 +:1019E0002412FFFF34E2004092060000A0A200D4BF +:1019F0008E030010008098211072000630D1003F45 +:101A00002408000D0E0019E1A3880064105200257F +:101A10002404FFFF8F8A00348E0900188D4400D003 +:101A20001124000702602021240C000E0E0019E191 +:101A3000A38C0064240BFFFF104B001A2404FFFF4B +:101A400024040020122400048F8D003491AF00D4B0 +:101A500035EE0020A1AE00D48F85005010A00019F3 +:101A6000000000001224004A8F9800348F92FCB8C6 +:101A7000971000809651000A523000488F93003C26 +:101A80003C1F08008FFF318C03E5C82B1720001E78 +:101A900002602021000028210E00194024060001C8 +:101AA000000020218FBF00208FB3001C8FB20018D0 +:101AB0008FB100148FB000100080102103E00008E7 +:101AC00027BD00285224002A8E0500148F8400347C +:101AD000948A008025490001A489008094880080B0 +:101AE0003C0208008C42318831077FFF10E2000E73 +:101AF00000000000026020210E0018CB2405000128 +:101B00000A001AA2000020212402002D0E0019E173 +:101B1000A38200642403FFFF1443FFE12404FFFFBA +:101B20000A001AA38FBF002094990080241F800010 +:101B300024050001033FC024A498008090920080F7 +:101B4000908E0080325100FF001181C20010782772 +:101B5000000F69C031CC007F018D5825A08B00801B +:101B60000E0018CB026020210A001AA200002021DA +:101B70002406FFFF54A6FFD68F8400340260202184 +:101B80000E0018CB240500010A001AA20000202133 +:101B9000026020210A001ABC2402000A2404FFFD6E +:101BA0000A001AA2AF93005C8F88003427BDFFE8BB +:101BB000AFB00010AFBF0014910A00D48F87004867 +:101BC00000808021354900408CE60010A10900D436 +:101BD0003C0208008C4231B030C53FFF00A2182BF8 +:101BE000106000078F85004C240DFF8090AE000D23 +:101BF00001AE6024318B00FF156000080006C3822F +:101C0000020020212403000D8FBF00148FB00010AC +:101C100027BD00180A0019E1A383006433060003FE +:101C2000240F000254CFFFF70200202194A2001CD1 +:101C30008F85003424190023A4A200E88CE800005A +:101C400000081E02307F003F13F900353C0A008374 +:101C50008CE800188CA600D01106000800000000D7 +:101C60002405000E0E0019E1A38500642407FFFF80 +:101C7000104700182404FFFF8F85003490A900D47A +:101C800035240020A0A400D48F8C0040918E000D3C +:101C900031CD007FA18D000D8F8300501060001C9E +:101CA000020020218F84004C8C9800100303782BB5 +:101CB00011E0000D2419001802002021A3990064EE +:101CC0000E0019E12410FFFF105000022404FFFF52 +:101CD000000020218FBF00148FB000100080102161 +:101CE00003E0000827BD00188C8600108F9F00407D +:101CF0000200202100C31023AFE2001024050001E0 +:101D00000E001940240600010A001B2E00002021AD +:101D10000E0018CB240500010A001B2E0000202114 +:101D2000010A5824156AFFD98F8C0040A0A600FC38 +:101D30000A001B1BA386005630A500FF24060001E5 +:101D400024A9000100C9102B1040000C0000402104 +:101D5000240A000100A61823308B000124C60001CC +:101D6000006A3804000420421160000200C9182BE8 +:101D7000010740251460FFF800A6182303E00008BF +:101D80000100102127BDFFD8AFB000188F90004888 +:101D9000AFB1001CAFBF00202403FFFF2411002FB0 +:101DA000AFA30010920600002405000826100001D1 +:101DB000006620260E001B47308400FF00021E0034 +:101DC0003C021EDC34466F410A001B6F00001021EC +:101DD00010A00009008018212445000130A2FFFF57 +:101DE0002C4500080461FFFA0003204000862026ED +:101DF00014A0FFF9008018210E001B4724050020C5 +:101E00008FA300102629FFFF313100FF000342029B +:101E1000240700FF1627FFE20102182600035027BF +:101E2000AFAA0014AFAA00100000302127A80010AC +:101E300027A7001400E6782391ED000324CE0001CB +:101E400000C8602131C600FF2CCB00041560FFF9EB +:101E5000A18D00008FA200108FBF00208FB1001C49 +:101E60008FB0001803E0000827BD002827BDFFD071 +:101E7000AFB3001CAFB00010AFBF0028AFB5002457 +:101E8000AFB40020AFB20018AFB100143C0C80001A +:101E90008D880128240FFF803C06800A2510010050 +:101EA000250B0080020F68243205007F016F70242B +:101EB000AD8E009000A62821AD8D002490A600FCD8 +:101EC0003169007F3C0A8004012A1821A38600564C +:101ED0009067007C00809821AF83002C30E20002E4 +:101EE000AF880068AF85003400A0182114400002BC +:101EF0002404003424040030A38400448C7200DCE9 +:101F000030D100FF24040004AF92005C12240004CE +:101F1000A38000648E7400041680001E3C088000BC +:101F20009386005530C7000150E0000F8F86005C9B +:101F30008CA400848CA800842413FF800093602468 +:101F4000000C49403110007F013078253C192000F9 +:101F500001F9682530DF00FE3C038000AC6D0830DD +:101F6000A39F00558F86005C8FBF00288FB500248B +:101F70008FB400208FB3001C8FB200188FB10014F3 +:101F80008FB000102402000127BD003003E00008DC +:101F9000ACA600DC8E7F0008950201208E67001041 +:101FA00003E2C8213326FFFF30D8000F33150001AC +:101FB000AF87003016A00058A398005435090C00D4 +:101FC0000309382100D81823AD030084AF870060CF +:101FD0008E6A00043148FFFF1100007EA78A005876 +:101FE00090AC00D42407FF8000EC302430CB00FFFD +:101FF0001560004B97860058938E0056240D000202 +:1020000030D5FFFF11CD02A20000A0218F85005C1A +:1020100002A5802B160000BC938800443C11800070 +:1020200096240120310400FF148500888F8400600D +:102030008F980030331200035640008530A500FF12 +:102040008F900060310C00FF24060034118600954B +:10205000AF90004892040004148001198F8E003460 +:10206000A38000388E0D00048DC800D83C0600FF08 +:1020700034CCFFFF01AC30240106182B1460012181 +:10208000AF8600508F87005C97980058AF87003C60 +:102090000307402310C000C7A78800588F91002C69 +:1020A00030C3000300035823922A007C31710003DF +:1020B00002261021000A208230920001001248807E +:1020C00000492821311FFFFF03E5C82B1320012001 +:1020D0008F8800348F8500308F8800601105025A88 +:1020E0003C0E3F018E0600003C0C250000CE68240B +:1020F00011AC01638F84004830E500FF0E0017E14A +:10210000000030218F8800348F87005C8F8500307D +:102110000A001D4E8F8600500A001BEDAF8700603D +:1021200090AC00D400EC2024309000FF1200001688 +:102130009386005590B5008890B400D724A80088F5 +:1021400032A2003F2446FFE02CD10020A3940038A7 +:102150001220000CAF880048240E000100CE20049D +:10216000308A00191540012B3C06800034D800024B +:10217000009858241560022E309200201640023438 +:10218000000000009386005530CE000111C0000F02 +:10219000978800588CA900848CAF00842410FF809D +:1021A0000130C8240019194031ED007F006D382539 +:1021B0003C1F200000FF902530CB00FE3C18800023 +:1021C000AF120830A38B0055978800581500FF8484 +:1021D000000000008E630020306C00041180FF516D +:1021E000938600552404FFFB006430243C038000E8 +:1021F000AE660020346601808C7301B80660FFFE75 +:102200008F8E0068346A01003C150001ACCE0000DE +:102210008C62012424076085ACC200048D54000444 +:1022200002958824522000012407608324120002B2 +:102230003C1810003C0B8000A4C70008A0D2000B83 +:10224000AD7801B80A001BC29386005530A500FF87 +:102250000E0017E1240600018F8800683C0580000D +:1022600034A909002502018893880044304A0007F8 +:10227000304B00783C0340802407FF800163C82571 +:10228000014980210047F824310C00FF2406003466 +:10229000ACBF0800AF900048ACB908105586FF6E7F +:1022A000920400048F8400348E110030908E00D48C +:1022B00031CD001015A000108F83005C2C6F00053D +:1022C00015E000E400000000909800D42465FFFCB5 +:1022D000331200101640000830A400FF8F9F0060EA +:1022E0008F99003013F900043887000130E20001B3 +:1022F000144001C8000000000E001B5A000000003E +:102300000A001D8F000000008F84006030C500FFB0 +:102310000E0017E124060001938E0044240A0034C5 +:1023200011CA00A08F8500348F86005C9783005807 +:102330003062FFFF00C28823AF91005CA780005885 +:102340001280FF90028018212414FFFD5474FFA214 +:102350008E6300208E6900042403FFBF240BFFEF6F +:102360000135C823AE79000490AF00D431ED007F71 +:10237000A0AD00D48E6600208F980034A78000584E +:1023800034DF0002AE7F0020A70000BC931200D40F +:1023900002434024A30800D48F950034AEA000EC83 +:1023A00092AE00D401CB5024A2AA00D40A001C6E25 +:1023B0008F8500348F910030AF80005C0227582158 +:1023C000AF8B0030000020212403FFFF108301B4F5 +:1023D0008F8500348E0C00103C0D08008DAD31B09F +:1023E0009208000031843FFF008D802B12000023F3 +:1023F000310D003F3C1908008F3931A88F9F0068CC +:10240000000479802408FF80033F2021008FC82129 +:10241000938500550328F8243C0600803C0F80007B +:1024200034D80001001F91403331007F8F86003483 +:102430000251502535EE0940332B00783330000728 +:102440003C0310003C02800C01789025020E4821CC +:102450000143C0250222382134AE0001ADFF08043B +:10246000AF89004CADF20814AF870040ADFF0028E3 +:10247000ACD90084ADF80830A38E00559383005684 +:10248000240700035067002825A3FFE0240C000167 +:10249000146CFFAB8F8500342411002311B100842C +:1024A000000000002402000B026020210E0019E150 +:1024B000A38200640040A0210A001CC98F8500345B +:1024C00002602021240B000C0E0019E1A38B006494 +:1024D000240AFFFF104AFFBC2404FFFF8F8E003444 +:1024E000A38000388E0D00048DC800D83C0600FF84 +:1024F00034CCFFFF01AC30240106182B1060FEE144 +:10250000AF86005002602021241200190E0019E14C +:10251000A3920064240FFFFF104FFFAB2404FFFFC2 +:102520000A001C1A8F8600502C7400201280FFDED7 +:102530002402000B000328803C110801263192EC94 +:1025400000B148218D2D000001A00008000000000E +:102550008F85003000A7102193850038AF820030AE +:1025600002251821A3830038951F00BC02262821CC +:1025700037F91000A51900BC5240FF92AF85005CEE +:10258000246A0004A38A0038950900BC24A400042E +:10259000AF84005C35322000A51200BC0A001CEBA1 +:1025A000000020218F86005C2CCB00051560FF60A9 +:1025B000978300583072FFFF00D240232D1800058A +:1025C00013000003306400FF24DFFFFC33E400FF4E +:1025D0008F8500608F86003010A60004388F0001C0 +:1025E00031ED000115A00138000000008F84003497 +:1025F000908C00D435870010A08700D48F850034DC +:102600008F86005C97830058ACA000EC0A001CC6C3 +:102610003062FFFF8CAA00848CB500843C0410005B +:10262000014710240002894032B4007F0234302573 +:1026300000C460253C0880002405000102602021C0 +:10264000240600010E001940AD0C08300A001C5A87 +:102650008F8500348C8200EC1222FE7E02602021E5 +:1026600024090005A38900640E0019E12411FFFF6D +:102670001451FE782404FFFF0A001CEC2403FFFF22 +:102680008F8F00488F8800348DF80000AD180088C7 +:102690008DE70010AD0700988F87005C0A001D4E83 +:1026A0008F8600502407FFFF1187000500000000FF +:1026B0000E001AE3026020210A001D270040A0211D +:1026C0000E001A68026020210A001D270040A02188 +:1026D0008F9000483C0908008D2931B08E11001000 +:1026E00032323FFF0249682B11A0000C240AFF8000 +:1026F0008F85004C90AE000D014E1024304C00FF31 +:1027000011800007026020210011C38233030003FF +:10271000240B0001106B0105000000000260202165 +:102720002418000D0E0019E1A39800640040202138 +:102730008F8500340A001CC90080A0218F900048BA +:102740003C0A08008D4A31B08F85004C8E04001081 +:102750000000A0218CB1001430823FFF004A602BA2 +:102760008CB200205180FFEE0260202190B8000D55 +:10277000240BFF800178702431C300FF5060FFE814 +:1027800002602021000443823106000314C0FFE4EC +:102790000260202194BF001C8F9900348E0600280F +:1027A000A73F00E88CAF0010022F202314C401398A +:1027B000026020218F83005000C36821022D382B36 +:1027C00014E00135240200188F8A00408F82002C0B +:1027D000024390218D4B001001637023AD4E001019 +:1027E000AD5200208C4C00740192282B14A001568D +:1027F000026020218F84004C8E0800248C860024E7 +:1028000011060007026020212419001C0E0019E1A6 +:10281000A3990064240FFFFF104FFFC52404FFFF9E +:102820008F8400408C87002424FF0001AC9F00248B +:10283000125101338F8D002C8DB100741232013092 +:102840003C0B00808E0E000001CB5024154000751B +:10285000000000008E0300142411FFFF1071000619 +:10286000026020212418001B0E0019E1A3980064C7 +:102870001051FFAF2404FFFF8E0300003C0800014D +:102880000068302410C000133C0400800064A024C1 +:102890001680000902002821026020212419001A54 +:1028A0000E0019E1A3990064240FFFFF104FFFA051 +:1028B0002404FFFF02002821026020210E001A01DB +:1028C000240600012410FFFF1050FF992404FFFF8D +:1028D000241400018F9F00400260202102803021DB +:1028E00097F100342405000126270001A7E70034F2 +:1028F0000E00194000000000000020218F850034E8 +:102900000A001CC90080A0218F9000483C140800D8 +:102910008E9431B08E07001030E83FFF0114302B49 +:1029200010C000618F86004C241FFF8090C5000DF1 +:1029300003E52024309200FF5240005C0260202119 +:102940008F8D005011A0000700078B828F85003407 +:102950008F89FCB894AF00809539000A132F00F6D8 +:102960008F87003C322C00031580006300000000BC +:1029700092020002104000D7000000008E0A0024DE +:10298000154000D8026020219204000324060002B2 +:10299000308800FF15060005308500FF8F94005039 +:1029A000528000F202602021308500FF38AD001017 +:1029B0002DA400012CBF000103E4302502002821D2 +:1029C0000E001A01026020212410FFFF105000BEEB +:1029D0008F8500348F830050106000C424050001EF +:1029E0003C1908008F39318C0323782B15E000B196 +:1029F0002409002D02602021000028210E0019402A +:102A0000240600018F850034000018210A001CC92B +:102A10000060A0210E00180C000000000A001D8FAD +:102A200000000000AC8000200A001E0F8E0300147E +:102A300000002821026020210E0019402406000118 +:102A40000A001C5A8F8500340A001D4E8F880034FE +:102A50008CB000848CB900843C0310000207482429 +:102A600000096940332F007F01AFF82503E32825D3 +:102A7000ACC5083091070001240500010260202147 +:102A80000E00194030E600010A001C5A8F85003400 +:102A9000938F00442403FFFD0A001CCBAF8F005C22 +:102AA0000A001CCB2403FFFF026020212410000D2C +:102AB0000E0019E1A3900064004018218F850034B6 +:102AC0000A001CC90060A0210E00180C00000000C4 +:102AD000978300588F86005C3070FFFF00D048233A +:102AE0002D3900051320FE128F850034ACA200ECB6 +:102AF0000A001CC63062FFFF90C3000D307800084A +:102B00005700FFA29204000302602021240200105B +:102B10000E0019E1A38200642403FFFF5443FF9BCE +:102B2000920400030A001EA98F85003490A8000DAE +:102B30003106000810C000958F9400501680009E4A +:102B4000026020218E0F000C8CA4002055E40005AB +:102B5000026020218E1F00088CB9002413F9003A6E +:102B600002602021240200200E0019E1A3820064EB +:102B70002405FFFF1045FEEE2404FFFF8F8F004069 +:102B8000240CFFF72403FF8091E9000D3C14800E14 +:102B90003C0B8000012CC824A1F9000D8F8F002C64 +:102BA0003C0708008CE731AC8F8D006895E5007814 +:102BB0008F99004000ED902130BF7FFF001F204023 +:102BC0000244302130C8007F00C3C02401147021AA +:102BD000AD78002CA5D100008F2A002825420001E5 +:102BE000AF2200288F29002C8E0C002C012C68218C +:102BF000AF2D002C8E07002CAF2700308E0500145F +:102C0000AF250034973F003A27E40001A724003A9B +:102C100095F200783C1008008E1031B02643000178 +:102C200030717FFF1230005C006030218F83002CF8 +:102C300002602021240500010E0018CBA466007854 +:102C40000A001E38000020218E0700142412FFFF06 +:102C500010F200638F8C00348E0900188D8D00D027 +:102C6000152D005D026020218E0A00248CA2002810 +:102C700011420053240200210E0019E1A3820064D6 +:102C80001452FFBE2404FFFF8F8500340A001CC9C4 +:102C90000080A0212402001F0E0019E1A38200641D +:102CA0002409FFFF1049FEA22404FFFF0A001DEBC8 +:102CB0008F830050026020210E0019E1A389006477 +:102CC0001450FF518F8500342403FFFF0A001CC9F4 +:102CD0000060A0218CCE00248E0B0024116EFF2AF0 +:102CE000026020210A001EBD2402000F0E0018CB36 +:102CF000026020218F8500340A001E7C000018210C +:102D00008E0900003C050080012590241640FF45F7 +:102D10002402001A026020210E0019E1A38200643F +:102D2000240CFFFF144CFECB2404FFFF8F850034DE +:102D30000A001CC90080A0212403FFFD0060A0211F +:102D40000A001CC9AF87005C2418001D0E0019E1A1 +:102D5000A39800642403FFFF1443FEA62404FFFF8E +:102D60008F8500340A001CC90080A0212412002C89 +:102D70000E0019E1A39200642403FFFF1043FF50EB +:102D80008F8500340A001E63920400030260202134 +:102D90000A001ED324020024240B8000006B702440 +:102DA00031CAFFFF000A13C2305100FF0011802713 +:102DB0000A001F04001033C00A001ED3240200279B +:102DC0008E0600288CAE002C10CE00080260202158 +:102DD0000A001F172402001F0A001F172402000EFA +:102DE000026020210A001F17240200258E04002CF7 +:102DF0001080000D8F83002C8C7800740304582BF6 +:102E00005560000C026020218CA800140086A021CF +:102E10000114302B10C0FF5A8F8F00400260202118 +:102E20000A001F1724020022026020210A001F1737 +:102E3000240200230A001F172402002627BDFFD802 +:102E4000AFB3001CAFB10014AFBF0020AFB2001889 +:102E5000AFB000103C0280008C5201408C4B014806 +:102E60003C048000000B8C02322300FF317300FF12 +:102E70008C8501B804A0FFFE34900180AE120000E2 +:102E80008C8701442464FFF0240600022C83001385 +:102E9000AE070004A6110008A206000BAE13002422 +:102EA0001060004F8FBF0020000448803C0A0801DA +:102EB000254A936C012A40218D04000000800008FF +:102EC000000000003C0308008C6331A831693FFF1B +:102ED0000009998000728021021370212405FF806F +:102EE000264D0100264C00803C02800031B1007F5D +:102EF0003198007F31CA007F3C1F800A3C19800452 +:102F00003C0F800C01C5202401A530240185382404 +:102F1000014F1821AC460024023F402103194821EB +:102F2000AC470090AC440028AF830040AF88003429 +:102F3000AF89002C0E001897016080213C038000AF +:102F40008C6B01B80560FFFE8F8700408F860034D0 +:102F50003465018090E8000DACB20000A4B000061A +:102F6000000826000004160300029027001227C262 +:102F70001080008124C20088241F6082A4BF000842 +:102F8000A0A0000524020002A0A2000B8F8B002C41 +:102F9000000424003C08270000889025ACB20010F3 +:102FA000ACA00014ACA00024ACA00028ACA0002C65 +:102FB0008D6900382413FF80ACA9001890E3000D40 +:102FC00002638024320500FF10A000058FBF00209F +:102FD00090ED000D31AC007FA0EC000D8FBF002004 +:102FE0008FB3001C8FB200188FB100148FB0001087 +:102FF0003C0A10003C0E800027BD002803E00008BA +:10300000ADCA01B8265F01002405FF8033F8007FB8 +:103010003C06800003E578243C19800A031920212E +:10302000ACCF0024908E00D400AE682431AC00FFF9 +:1030300011800024AF840034248E008895CD0012C6 +:103040003C0C08008D8C31A831AB3FFF0192482128 +:10305000000B5180012A402101052024ACC4002826 +:103060003107007F3C06800C00E620219083000D94 +:1030700000A31024304500FF10A0FFD8AF8400400B +:103080009098000D330F001015E0FFD58FBF002082 +:103090000E001897000000003C0380008C7901B8F6 +:1030A0000720FFFE00000000AE1200008C7F0144EC +:1030B000AE1F0004A611000824110002A211000B8B +:1030C000AE1300243C13080192739528327000015E +:1030D0005200FFC38FBF00200E0020D402402021E9 +:1030E0000A001FF18FBF00203C1260008E452C08A3 +:1030F0003C03F0033462FFFF00A2F824AE5F2C080B +:103100008E582C083C1901C003199825AE532C0881 +:103110000A001FF18FBF0020264D010031AF007F54 +:103120003C10800A240EFF8001F0282101AE6024AB +:103130003C0B8000AD6C00241660FFA8AF85003406 +:1031400024110003A0B100FC0A001FF18FBF002072 +:1031500026480100310A007F3C0B800A2409FF80C9 +:10316000014B3021010920243C078000ACE40024FD +:103170000A001FF0AF860034944E0012320C3FFF5D +:1031800031CD3FFF15ACFF7D241F608290D900D464 +:103190002418FF800319782431EA00FF1140FF77DB +:1031A0000000000024070004A0C700FC8F87004037 +:1031B000241160842406000DA4B10008A0A6000517 +:1031C0000A001FDB240200023C0400012484951441 +:1031D00024030014240200FE3C010800AC2431EC5E +:1031E0003C010800AC2331E83C010801A4229530E1 +:1031F0003C0408012484953000001821006430212B +:10320000A0C30004246300012C6500FF54A0FFFC50 +:10321000006430213C07080024E7010003E00008B7 +:10322000AF87007400A058210080482100001021C1 +:1032300014A00012000050210A0020D0000000005D +:103240003C010801A42095303C05080194A5953067 +:103250008F8200743C0C0801258C953000E2182107 +:1032600000AC2021014B302BA0890004000010216C +:10327000A460000810C00039010048218F86007446 +:103280000009384000E940210008388000E6282184 +:1032900090A8000B90B9000A000820400088102177 +:1032A000000218800066C021A319000A8F850074EF +:1032B00000E5782191EE000A91E6000B000E6840CF +:1032C00001AE6021000C208000851021A046000B7B +:1032D0003C0308019063952A106000222462FFFFDE +:1032E0008F8300343C010801A022952A906C00FFD6 +:1032F0001180000400000000906E00FF25CDFFFF4C +:10330000A06D00FF3C190801973995302723000173 +:103310003078FFFF2F0F00FF11E0FFC9254A0001A1 +:103320003C010801A42395303C05080194A5953083 +:103330008F8200743C0C0801258C953000E2182126 +:1033400000AC2021014B302BA0890004000010218B +:10335000A460000814C0FFC90100482103E0000870 +:103360000000000003E000082402000227BDFFE087 +:10337000248501002407FF80AFB00010AFBF001804 +:10338000AFB1001400A718243C10800030A4007FC7 +:103390003C06800A008628218E110024AE030024FA +:1033A00090A200FF14400008AF850034A0A00009DF +:1033B0008FBF0018AE1100248FB100148FB0001021 +:1033C00003E0000827BD002090A900FD90A800FFA1 +:1033D000312400FF0E002082310500FF8F8500346C +:1033E0008FBF0018A0A00009AE1100248FB10014F7 +:1033F0008FB0001003E0000827BD002027BDFFD0DC +:10340000AFB20020AFB1001CAFB00018AFBF002CAE +:10341000AFB40028AFB300243C09800095330116F7 +:1034200035320C00952F011A3271FFFF02328021D4 +:103430008E08000431EEFFFF248B0100010E68218D +:10344000240CFF8025A5FFFF016C50243166007F0E +:103450003C07800AAD2A002400C73021AF850070E8 +:10346000AF88006C3C010801A020952990C3000999 +:103470000200D02100809821306300FF28620005FF +:1034800010400048AF860034286400021480008E8B +:1034900024140001240D00053C010801A02D950D08 +:1034A00090CC00FD3C010801A020950E3C010801D4 +:1034B000A020950F90CB000A240AFF80318500FFE1 +:1034C000014B4824312700FF10E0000C0000582178 +:1034D0003C128008365100808E2F00308CD0005C6A +:1034E00001F0702305C0018E8F87006C90D4000A14 +:1034F0003284007FA0C4000A8F8600343C1180080B +:10350000363000808E0F00308F87006C00EF702304 +:1035100019C000EE0000000090D40009241200023F +:10352000328400FF10920247000000008CC2005855 +:1035300000E2F82327F9FFFF1B2001300000000004 +:1035400090C500092408000430A300FF106800574C +:10355000240A00013C010801A02A950D90C900FF32 +:10356000252700013C010801A027950C3C03080118 +:103570009063950D240600051066006A2C780005FE +:10358000130000C4000090210003F8803C040801EF +:10359000248493B803E4C8218F25000000A000080C +:1035A00000000000241800FF1078005C00000000FC +:1035B00090CC000A90CA00093C080801910895299E +:1035C0003187008000EA48253C010801A0299514B4 +:1035D00090C500FD3C1408019294952A3111000118 +:1035E0003C010801A025951590DF00FE3C01080173 +:1035F000A03F951690D200FF3C010801A03295171C +:103600008CD900543C010801AC3995188CD0005875 +:103610003C010801AC30951C8CC3005C3C010801E6 +:10362000AC3495243C010801AC23952016200008F9 +:103630008FBF002C8FB400288FB300248FB20020DE +:103640008FB1001C8FB0001803E0000827BD0030C8 +:103650003C1180009624010E0E000FD43094FFFF21 +:103660003C0B08018D6B952C0260382102802821CB +:10367000AE2B01803C1308018E73950C0160202154 +:10368000240600830E001046AFB300108FBF002C3D +:103690008FB400288FB300248FB200208FB1001C9C +:1036A0008FB0001803E0000827BD00303C18080068 +:1036B0008F1831FC270F00013C010800AC2F31FCB2 +:1036C0000A002165000000001474FFB9000000002A +:1036D000A0C000FF3C0508008CA531E43C030800B5 +:1036E0008C6331E03C0208008C4232048F99003434 +:1036F00034A80001241F00023C010801AC23952CD2 +:103700003C010801A02895283C010801A022952B26 +:10371000A33F00090A00211E8F8600340E0020D42A +:10372000000000000A0021658F8600343C1F08015C +:1037300093FF950C2419000113F902298F87006C5F +:103740003C100801921095103C06080190C6950E99 +:1037500010C000050200A0213C04080190849511CE +:10376000109001E48F870074001088408F9F0074D0 +:10377000023048210009C880033F702195D8000815 +:10378000270F0001A5CF00083C0408019084951183 +:103790003C05080190A5950E0E0020820000000057 +:1037A0008F870074023020210004308000C7202160 +:1037B0008C8500048F82007000A240230502000661 +:1037C000AC8200048C8A00008F83006C01431023BC +:1037D0005C400001AC8300008F86003490CB00FF7A +:1037E0002D6C00025580002D241400010230F821B8 +:1037F000001F40800107282190B9000B8CAE000407 +:103800000019C04003197821000F188000671021AB +:103810008C4D000001AE88232630FFFF5E00001FA4 +:10382000241400018C4400048CAA0000008A482360 +:1038300019200019240E00043C010801A02E950D4A +:1038400090AD000B8CAB0004000D8840022D802150 +:1038500000101080004710218C4400040164602394 +:10386000058202009443000890DF00FE90B9000B2F +:1038700033E500FF54B900040107A021A0D400FEE5 +:103880008F8700740107A0219284000B0E00208214 +:10389000240500018F860034241400011254009680 +:1038A0002E500001160000423C08FFFF24190002C0 +:1038B0001659FF3F00000000A0C000FF8F860034B3 +:1038C000A0D200090A0021658F86003490C7000944 +:1038D0002404000230E300FF1064016F2409000497 +:1038E000106901528F8800708CCE0054010E68233D +:1038F00025B1000106200175241800043C010801CF +:10390000A038950D3C010801A020950C90D400FD35 +:1039100090D200FF2E4F000215E0FF14328400FF0A +:10392000000438408F89007490DF00FF00E410210C +:10393000000220800089C8212FE500029324000B9B +:1039400014A0FF0A2407000200041840006480212C +:1039500000105880016928218CAC0004010C502310 +:103960000540FF02000000003C0308019063950E33 +:1039700014600005246F00013C010801A02495118A +:103980003C010801A027950F3C010801A02F950ECE +:1039900090CE00FF24E7000131CD00FF01A7882B66 +:1039A0001220FFE990A4000B0A002154000000003F +:1039B0003C0508018CA5950C3C12000400A8F824D5 +:1039C00013F20006240200053C0908019129950D17 +:1039D0001520000224020003240200053C01080116 +:1039E000A022952990C700FF14E0012024020002C4 +:1039F000A0C200090A0021658F86003490CC00FF28 +:103A00001180FEDA240A00018F8C00708F89007407 +:103A1000240F0003018068211160001E240E0002A3 +:103A2000000540400105A02100142080008990215C +:103A30008E510004019180230600FECC000000009E +:103A40003C0208019042950E1440000524580001E4 +:103A50003C010801A02A950F3C010801A025951101 +:103A60003C010801A038950E90DF00FF01051021F0 +:103A70000002C88033E500FF254A00010329202108 +:103A800000AA402B1500FEB99085000B1560FFE5DC +:103A9000000540400005404001051821000310804A +:103AA0003C010801A02A950C3C010801A0259510B5 +:103AB000004918218C64000400E4F82327F9FFFF73 +:103AC0001F20FFE9000000008C63000000E3582382 +:103AD0000560013A01A3882310E301170184C02384 +:103AE0001B00FEA2000000003C010801A02E950D65 +:103AF0000A002293240B0001240E0004A0CE00092A +:103B00003C0D08008DAD31F88F86003425A20001F0 +:103B10003C010800AC2231F80A00216500000000D9 +:103B20008CD9005C00F9C0231F00FE7B0000000060 +:103B30008CDF005C10FFFF658F8400708CC3005C1D +:103B400000834023250200011C40FF6000000000AC +:103B50008CC9005C2487000100E9282B10A0FE948A +:103B60003C0D80008DAB01043C0C0001016C502425 +:103B70001140FE8F240200103C010801A02295296B +:103B80000A002165000000008F9100708F860034CC +:103B900026220001ACC2005C0A002220241400018D +:103BA0008F8700342404FF800000882190E9000AF8 +:103BB0002414000101243025A0E6000A3C05080178 +:103BC00090A5950E3C040801908495110E0020826A +:103BD000000000008F8600348F85007490C800FDBF +:103BE000310700FF000740400107F821001FC08097 +:103BF0000305C8219323000BA0C300FD8F8500742B +:103C00008F86003403056021918F000B000F7040F8 +:103C100001CF6821000D8080020510218C4B00002F +:103C2000ACCB00548D8400048F830070006450235B +:103C3000194000022482000124620001010748218A +:103C4000ACC2005C0009308000C5402100E02021AA +:103C5000240500010E0020829110000B8F86003495 +:103C600090C500FF10A0FF0C001070408F850074FD +:103C700001D06821000D1080004558218D6400009E +:103C80008F8C0070018450232547000104E0FF025F +:103C9000263100013C0308019063950E2E2F00028F +:103CA000247800013C010801A038950E3C01080170 +:103CB000A034950F11E0FEF8020038210A0022F32B +:103CC000000740408F8400348F8300708C8500583B +:103CD00000A340230502FE9AAC8300580A0021C9C4 +:103CE000000000003C07080190E7952A240200FF2D +:103CF00010E200BE8F8600343C11080196319532E7 +:103D00003C03080124639530262500013230FFFF73 +:103D100030ABFFFF020360212D6A00FF1540008DCC +:103D2000918700043C010801A42095328F8800345B +:103D30000007484001272821911800FF0005308026 +:103D40002405000127140001A11400FF3C12080102 +:103D50009252952A8F8800748F8E006C264F000136 +:103D600000C820213C010801A02F952AAC8E00003C +:103D70008F8D0070A4850008AC8D00043C03080101 +:103D80009063950C14600077000090213C010801BD +:103D9000A025950CA087000B8F8C007400CC5021BF +:103DA000A147000A8F820034A04700FD8F840034B1 +:103DB000A08700FE8F8600348F9F006CACDF00541C +:103DC0008F990070ACD900588F8D00740127C021E5 +:103DD00000185880016DA021928F000A000F7040DA +:103DE00001CF182100038880022D8021A207000B3B +:103DF0008F86007401666021918A000B000A1040D2 +:103E0000004A20210004288000A64021A107000AC2 +:103E10003C07800834E900808D2200308F86003412 +:103E2000ACC2005C0A0022202414000190CA00FFEA +:103E30001540FEAD8F880070A0C400090A002165FE +:103E40008F860034A0C000FD8F9800342406000146 +:103E5000A30000FE3C010801A026950D3C010801CD +:103E6000A020950C0A0021540000000090CB00FF18 +:103E70003C0408019084952B316C00FF0184502B89 +:103E80001540000F2402000324020004A0C2000910 +:103E90000A0021658F86003490C3000A2410FF8039 +:103EA00002035824316C00FF1180FDC100000000A6 +:103EB0003C010801A020950D0A00215400000000DB +:103EC000A0C200090A0021658F86003490D4000A40 +:103ED0002412FF8002544824312800FF1500FFF40B +:103EE000240200083C010801A02295290A0021654E +:103EF00000000000001088408F8B006C02301821F9 +:103F00000003688001A72021AC8B00008F8A00701D +:103F1000240C0001A48C0008AC8A00043C050801B4 +:103F200090A5950E2402000110A2FE1E24A5FFFFFD +:103F30000A0021DF9084000B0184A0231A80FD8BEE +:103F4000000000003C010801A02E950D0A002293FC +:103F5000240B00013C010801A42595320A002345E9 +:103F60008F880034240B0001106B00228F980034DE +:103F70008F85003490BF00FF33F900FF1079002BCC +:103F8000000000003C1F080193FF9510001FC8406F +:103F9000033FC0210018A0800288782191EE000A1A +:103FA000A08E000A8F8D00743C0308019063951069 +:103FB00000CD88210A00236BA223000B26300001CC +:103FC0000600003101A490230640002B24020003C8 +:103FD0003C010801A02F950D0A002293240B00013B +:103FE0008F8900340A0021C9AD2700540A00221F1E +:103FF00024120001931400FDA094000B8F8800345C +:104000008F8F0074910E00FE00CF6821A1AE000AD0 +:104010008F910034A22700FD8F83006C8F900034B5 +:10402000AE0300540A00236C8F8D007490B000FE24 +:10403000A090000A8F8B00348F8C0074916A00FD71 +:1040400000CC1021A04A000B8F840034A08700FE12 +:104050008F8600708F850034ACA600580A00236C50 +:104060008F8D007494B80008ACA400040303782179 +:104070000A002213A4AF00083C010801A022950DFC +:104080000A0021540000000090CF0009240D000414 +:1040900031EE00FF11CDFD85240200013C01080135 +:0C40A000A022950D0A0021540000000031 +:0440AC000800334491 +:1040B0000800334408003420080033F4080033D8E3 +:1040C0000800332808003328080033280800334C40 +:1040D0008008010080080080800800005F86543757 +:1040E000E4AC62CC50103A4536621985BF14C0E882 +:1040F0001BC27A1E84F4B556094EA6FE7DDA01E78E +:10410000C04D7481080058D008005914080058B8F0 +:10411000080058B8080058B8080058B8080058D027 +:10412000080058B8080058B80800591C080058B8CA +:1041300008005830080058B8080058B80800591C42 +:10414000080058B8080058B8080058B8080058B80F +:10415000080058B8080058B8080058B8080058B8FF +:10416000080058B8080058B8080058F0080058B8B7 +:10417000080058F0080058B8080058B8080058B8A7 +:10418000080058F4080058F0080058B8080058B85B +:10419000080058B8080058B8080058B8080058B8BF +:1041A000080058B8080058B8080058B8080058B8AF +:1041B000080058B8080058B8080058B8080058B89F +:1041C000080058B8080058B8080058B8080058B88F +:1041D000080058B8080058B8080058F4080058F407 +:1041E000080058B8080058F4080058B8080058B833 +:1041F000080058B8080058B8080058B8080058B85F +:10420000080058B8080058B8080058B8080058B84E +:10421000080058B8080058B8080058B8080058B83E +:10422000080058B8080058B8080058B8080058B82E +:10423000080058B8080058B8080058B8080058B81E +:10424000080058B8080058B8080058B8080058B80E +:10425000080058B8080058B8080058B8080058B8FE +:10426000080058B8080058B8080058B8080058B8EE +:10427000080058B8080058B8080058B8080058B8DE +:10428000080058B8080058B8080058B8080058B8CE +:10429000080058B8080058B8080058B8080058B8BE +:1042A000080058B8080058B8080058B8080058B8AE +:1042B000080058B8080058B8080058B8080058B89E +:1042C000080058B8080058B8080058B8080058B88E +:1042D000080058B8080058B8080058B8080058B87E +:1042E000080058B8080058B8080058B8080058B86E +:1042F000080058B8080058B8080058B8080058B85E +:10430000080058B80800593808007688080078EC8A +:1043100008007694080074880800769408007720D6 +:10432000080076940800748808007488080074886F +:10433000080074880800748808007488080074886D +:10434000080074880800748808007488080076B42F +:10435000080076A40800748808007488080074882F +:10436000080074880800748808007488080074883D +:10437000080074880800748808007488080074882D +:1043800008007488080076A40800813408007FC003 +:10439000080080FC08007FC0080080CC08007EA8D0 +:1043A00008007FC008007FC008007FC008007FC0F1 +:1043B00008007FC008007FC008007FC008007FC0E1 +:1043C00008007FC008007FC008007FC008007FC0D1 +:1043D00008007FE808008B6C08008CC808008CA8D7 +:0843E0000800871008008B841F +:0843E8000A000124000000009E +:1043F000000000000000000D747061362E302E3178 +:10440000370000000600110100000000000000005D +:10441000000000000000000000000000000000009C +:10442000000000000000000000000000000000008C +:10443000000000000000000000000000000000007C +:10444000000000000000000000000000000000006C +:10445000000000000000000000000000000000005C +:10446000000000000000000000000000000000004C +:104470000000000000000000000000001000000329 +:10448000000000000000000D0000000D3C020800CC +:10449000244217203C03080024632A10AC4000008B +:1044A0000043202B1480FFFD244200043C1D080023 +:1044B00037BD2FFC03A0F0213C100800261004900B +:1044C0003C1C0800279C17200E0002620000000020 +:1044D0000000000D2402FF8027BDFFE000821024B1 +:1044E000AFB00010AF420020AFBF0018AFB1001452 +:1044F000936500043084007F034418213C020008C7 +:104500000062182130A50020036080213C080111C1 +:10451000277B000814A000022466005C2466005873 +:104520009202000497430104920400043047000FF4 +:104530003063FFFF308400400067282310800009AB +:10454000000048219202000530420004104000059E +:104550000000000010A000030000000024A5FFFCE4 +:1045600024090004920200053042000410400012A9 +:104570000000000010A000100000000096020002E1 +:1045800000A72021010440252442FFFEA742101667 +:10459000920300042402FF8000431024304200FFF5 +:1045A000104000033C0204000A000174010240258F +:1045B0008CC20000AF4210188F4201780440FFFE09 +:1045C0002402000AA74201409602000224040009C6 +:1045D000304200070002102330420007A742014288 +:1045E000960200022442FFFEA7420144A740014672 +:1045F00097420104A74201488F420108304200203F +:1046000050400001240400019202000430420010D6 +:10461000144000023483001000801821A743014A8F +:10462000000000000000000000000000000000008A +:10463000AF48100000000000000000000000000073 +:10464000000000008F4210000441FFFE3102FFFF16 +:1046500010400007000000009202000430420040B9 +:1046600014400003000000008F421018ACC200008C +:10467000960200063042FFFF24420002000210436F +:104680000002104003628821962200001120000DD4 +:104690003044FFFF00A710218F8300388F45101C86 +:1046A000000210820002108000431021AC4500007F +:1046B00030A6FFFF0E00058D00052C0200402021D2 +:1046C000A6220000920300042402FF80004310246D +:1046D000304200FF1040001F000000009202000561 +:1046E000304200021040001B000000009742100CF6 +:1046F0002442FFFEA7421016000000003C02040006 +:1047000034420030AF421000000000000000000002 +:1047100000000000000000008F4210000441FFFE76 +:10472000000000009742100C8F45101C3042FFFF24 +:10473000244200300002108200021080005B102131 +:10474000AC45000030A6FFFF0E00058D00052C02D1 +:10475000A622000096040002248400080E0001E94D +:104760003084FFFF974401040E0001F73084FFFFFF +:104770008FBF00188FB100148FB000103C021000E2 +:1047800027BD002003E00008AF4201783084FFFF1E +:10479000308200078F850024104000022483000728 +:1047A0003064FFF800A4102130421FFF034218219B +:1047B000247B4000AF850028AF82002403E000087E +:1047C000AF4200843084FFFF3082000F8F85002CC1 +:1047D0008F860034104000022483000F3064FFF005 +:1047E00000A410210046182BAF850030004620237E +:1047F00014600002AF82002CAF84002C8F82002C4A +:10480000340480000342182100641821AF8300386B +:1048100003E00008AF4200808F82001410400008BF +:104820008F8200048F82FFDC144000058F82000419 +:104830003C02FFBF3442FFFF008220248F8200042D +:1048400030430006240200021062000F3C02010106 +:104850002C62000350400005240200041060000F89 +:104860003C0200010A000230000000001062000556 +:10487000240200061462000C3C0201110A00022905 +:10488000008210253C02001100821025AF4210006A +:10489000240200010A000230AF82000C00821025C1 +:1048A000AF421000AF80000C0000000000000000CC +:1048B0000000000003E00008000000008F82000CF0 +:1048C00010400004000000008F4210000441FFFE71 +:1048D0000000000003E00008000000008F820010CC +:1048E0002443F800000231C224C2FFF02C6303010C +:1048F00010600003000210420A000257AC82000060 +:104900008F85001800C5102B1440000B00001821E3 +:1049100000C51023244700018F82001C00A2102133 +:104920002442FFFF0046102B544000042402FFFFE6 +:104930000A000257AC8700002402FFFF0A00026051 +:10494000AC8200008C820000000219400062182135 +:104950000003188000621821000318803C02080040 +:104960002442175C0062182103E000080060102157 +:1049700027BDFFD8AFBF0020AFB1001CAFB00018FB +:104980003C0460088C8250002403FF7F3C066000DA +:10499000004310243442380CAC8250008CC24C1CB2 +:1049A0003C1A8000000216023042000F104000073F +:1049B000AF82001C8CC34C1C3C02001F3442FC0024 +:1049C00000621824000319C2AF8300188F42000848 +:1049D000275B400034420001AF420008AF80002452 +:1049E0003C02601CAF400080AF4000848C45000852 +:1049F0008CC3080834028000034220212402FFF007 +:104A0000006218243C0200803C010800AC22042013 +:104A10003C025709AF84003814620004AF850034AB +:104A2000240200010A000292AF820014AF80001439 +:104A30008F42000038420001304200011440FFFC68 +:104A40008F820014104000160000000097420104FD +:104A5000104000058F830000146000072462FFFFF0 +:104A60000A0002A72C62000A2C62001050400004C9 +:104A70008F83000024620001AF8200008F8300005A +:104A80002C62000A144000032C6200070A0002AEE8 +:104A9000AF80FFDC1040000224020001AF82FFDC87 +:104AA0008F4301088F44010030622000AF8300046F +:104AB00010400008AF8400103C0208008C42042C17 +:104AC000244200013C010800AC22042C0A00058AA3 +:104AD0003C0240003065020014A0000324020F00D5 +:104AE0001482026024020D0097420104104002C8A3 +:104AF0003C02400030624000144000AD8F8200381C +:104B00008C4400088F4201780440FFFE2402080014 +:104B1000AF42017824020008A7420140A7400142A9 +:104B2000974201048F8400043051FFFF308200015E +:104B300010400007022080212623FFFE24020002ED +:104B40003070FFFFA74201460A0002DBA74301487D +:104B5000A74001463C0208008C42043C1440000D72 +:104B60008F830010308200201440000224030009CB +:104B700024030001006020218F830010240209001B +:104B80005062000134840004A744014A0A0002F67E +:104B90000000000024020F00146200053082002093 +:104BA000144000062403000D0A0002F5240300054A +:104BB000144000022403000924030001A743014A12 +:104BC0003C0208008C4204203C0400480E00020C09 +:104BD000004420250E000235000000008F82000CEA +:104BE0001040003E000000008F4210003C030020F7 +:104BF00000431024104000398F820004304200022C +:104C0000104000360000000097421014144000339A +:104C100000000000974210088F8800383042FFFFE4 +:104C200024420006000218820003388000E8302188 +:104C3000304300018CC400001060000430420003C7 +:104C40000000000D0A00033700E810215440001056 +:104C50003084FFFF3C05FFFF0085202400851826D7 +:104C60000003182B0004102B0043102410400005F3 +:104C700000000000000000000000000D0000000027 +:104C8000240002228CC200000A00033600452025C1 +:104C90003883FFFF0003182B0004102B004310245F +:104CA0001040000500000000000000000000000DA2 +:104CB000000000002400022B8CC200003444FFFFDF +:104CC00000E81021AC4400003C0208008C42043093 +:104CD000244200013C010800AC2204308F62000035 +:104CE0008F840038AF8200088C8300003402FFFFFD +:104CF0001462000F000010213C0508008CA504542C +:104D00003C0408008C84045000B0282100B0302BF3 +:104D100000822021008620213C010800AC2504549B +:104D20003C010800AC2404500A000580240400085B +:104D30008C820000304201001040000F0000102162 +:104D40003C0508008CA5044C3C0408008C840448F5 +:104D500000B0282100B0302B0082202100862021C5 +:104D60003C010800AC25044C3C010800AC2404487C +:104D70000A000580240400083C0508008CA50444B2 +:104D80003C0408008C84044000B0282100B0302B83 +:104D900000822021008620213C010800AC2504442B +:104DA0003C010800AC2404400A00058024040008EB +:104DB0008F6200088F62000000021602304300F08C +:104DC000240200301062000524020040106200E05E +:104DD0008F8200200A0005882442000114A00005EB +:104DE00000000000000000000000000D00000000B6 +:104DF000240002568F4201780440FFFE00000000AC +:104E00000E00023D27A40010144000050040802140 +:104E1000000000000000000D000000002400025D02 +:104E20008E0200001040000500000000000000009D +:104E30000000000D00000000240002608F62000CE2 +:104E400004430003240200010A00042EAE00000007 +:104E5000AE0200008F8200388C480008A2000007D4 +:104E60008F65000C8F64000430A3FFFF0004240250 +:104E700000852023308200FF0043102124420005DA +:104E8000000230832CC20081A605000A14400005F0 +:104E9000A2040004000000000000000D000000005B +:104EA000240002788F8500380E0005AB260400141C +:104EB0008F6200048F430108A60200083C02100024 +:104EC00000621824106000080000000097420104EE +:104ED000920300072442FFEC346300023045FFFFD9 +:104EE0000A0003C3A2030007974201042442FFF013 +:104EF0003045FFFF960600082CC200135440000501 +:104F0000920300079202000734420001A202000748 +:104F1000920300072402000110620005240200032E +:104F20001062000B8F8200380A0003E030C6FFFFDA +:104F30008F8200383C04FFFF8C43000C006418246F +:104F400000651825AC43000C0A0003E030C6FFFFE3 +:104F50003C04FFFF8C4300100064182400651825F2 +:104F6000AC43001030C6FFFF24C2000200021083D1 +:104F7000A20200058F830038304200FF000210803B +:104F8000004328218CA800008CA200002403000408 +:104F900000021702144300120000000097420104AF +:104FA0003C03FFFF010318243042FFFF004610239B +:104FB0002442FFFE00624025ACA8000092030005D9 +:104FC000306200FF00021080005010219042001457 +:104FD0003042000F004310210A000415A20200060F +:104FE0008CA40004974201049603000A3088FFFF56 +:104FF0003042FFFF004610232442FFD60002140077 +:1050000001024025ACA800049202000792040005AA +:10501000246300280003188300641821344200042C +:10502000A2030006A20200078F8200042403FFFBF4 +:105030003442000200431024AF82000492030006B1 +:105040008F87003800031880007010218C440020E6 +:105050003C02FFF63442FFFF008240240067182123 +:10506000AE04000CAC68000C920500063C03FF7F08 +:105070008E02000C0005288000B020213463FFFF61 +:10508000010330249488002600A72821004310241F +:10509000AE02000CAC860020AC880024ACA8001046 +:1050A00024020010A742014024020002A74001424E +:1050B000A7400144A7420146974201043C0400086E +:1050C0002442FFFEA7420148240200010E00020C08 +:1050D000A742014A9603000A9202000400431021ED +:1050E0002442000230420007000210233042000731 +:1050F0000E000235AE0200108F6200003C03080073 +:105100008C63044424040010AF8200089742010419 +:105110003042FFFF2442FFFE00403821000237C327 +:105120003C0208008C420440006718210067282BCD +:1051300000461021004510213C010800AC23044426 +:105140003C010800AC2204400A00051500000000E4 +:1051500014A0000500000000000000000000000D89 +:10516000000000002400030A8F4201780440FFFE83 +:10517000000000000E00023D27A4001414400005AA +:1051800000408021000000000000000D0000000031 +:10519000240003118E020000544000069202000712 +:1051A000000000000000000D000000002400031CAF +:1051B0009202000730420004104000058F82000474 +:1051C0002403FFFB3442000200431024AF8200049A +:1051D0008F62000404430008920200079202000656 +:1051E0008E03000CAE000000000210800050102161 +:1051F000AC430020920200073042000454400009F2 +:105200009602000A920200053C0300010002108091 +:10521000005010218C46001800C33021AC46001805 +:105220009602000A9206000427710008022020213D +:1052300000C2302124C60005260500140E0005AB6F +:1052400000063082920400068F6500043C027FFF56 +:1052500000042080009120218C8300043442FFFF51 +:1052600000A2282400651821AC83000492020007E4 +:105270009204000592030004304200041040001420 +:1052800096070008308400FF000420800091202150 +:105290008C860004974201049605000A306300FFE3 +:1052A0003042FFFF004310210045102130E3FFFF93 +:1052B000004310232442FFD830C6FFFF0002140031 +:1052C00000C23025AC8600040A0004C9920300071E +:1052D000308500FF0005288000B128218CA4000043 +:1052E00097420104306300FF3042FFFF004310216A +:1052F000004710233C03FFFF008320243042FFFFC0 +:1053000000822025ACA400009203000724020001C3 +:105310001062000600000000240200031062001169 +:10532000000000000A0004EC8E0300109742010404 +:10533000920300049605000A8E24000C00431021FD +:10534000004510212442FFF23C03FFFF008320248C +:105350003042FFFF00822025AE24000C0A0004EC3E +:105360008E03001097420104920300049605000A80 +:105370008E24001000431021004510212442FFEE2E +:105380003C03FFFF008320243042FFFF00822025E2 +:10539000AE2400108E0300102402000AA742014030 +:1053A000A74301429603000A920200043C04004015 +:1053B00000431021A7420144A7400146974201043F +:1053C000A7420148240200010E00020CA742014A34 +:1053D0000E000235000000008F62000092030004FE +:1053E00000002021AF820008974201049606000ABF +:1053F0003042FFFF00621821006028213C030800B2 +:105400008C6304443C0208008C420440006518216F +:10541000004410210065382B004710213C01080092 +:10542000AC2304443C010800AC2204409204000474 +:10543000008620212484000A3084FFFF0E0001E949 +:1054400000000000974401043084FFFF0E0001F7C4 +:10545000000000003C021000AF4201780A000587FE +:105460008F820020148200273062000697420104D8 +:10547000104000673C0240003062400010400005D0 +:1054800000000000000000000000000D000000000F +:10549000240004208F4201780440FFFE240208000B +:1054A000AF42017824020008A7420140A740014210 +:1054B0008F8200049743010430420001104000072E +:1054C0003070FFFF2603FFFE24020002A7420146C0 +:1054D000A74301480A00053F2402000DA7400146EA +:1054E0002402000DA742014A8F6200002404000834 +:1054F000AF8200080E0001E9000000000A00051953 +:1055000002002021104000423C0240009362000053 +:10551000304300F0240200101062000524020070E5 +:10552000106200358F8200200A00058824420001A5 +:105530008F620000974301043050FFFF3071FFFF7E +:105540008F4201780440FFFE320200070002102360 +:10555000304200072403000A2604FFFEA74301404F +:10556000A7420142A7440144A7400146A751014870 +:105570008F42010830420020144000022403000939 +:1055800024030001A743014A0E00020C3C04004022 +:105590000E000235000000003C0708008CE70444C0 +:1055A000021110212442FFFE3C0608008CC6044074 +:1055B0000040182100E33821000010218F65000011 +:1055C00000E3402B00C230212604000800C830212F +:1055D0003084FFFFAF8500083C010800AC2704447D +:1055E0003C010800AC2604400E0001E90000000068 +:1055F0000A000519022020210E00013B00000000D6 +:105600008F82002024420001AF8200203C02400033 +:10561000AF4201380A000292000000003084FFFF10 +:1056200030C6FFFF00052C0000A628253882FFFFAA +:10563000004510210045282B0045102100021C02C6 +:105640003042FFFF0043102100021C023042FFFFE6 +:10565000004310213842FFFF03E000083042FFFF03 +:105660003084FFFF30A5FFFF0000182110800007E5 +:1056700000000000308200011040000200042042BF +:10568000006518210A0005A10005284003E0000874 +:105690000060102110C0000624C6FFFF8CA200008D +:1056A00024A50004AC8200000A0005AB2484000499 +:1056B00003E000080000000010A0000824A3FFFF82 +:1056C000AC86000000000000000000002402FFFF84 +:1056D0002463FFFF1462FFFA2484000403E000083F +:0456E00000000000C6 +:0456E40000000001C1 +:0856E8000A00002A0000000086 +:1056F000000000000000000D747870362E302E314E +:105700003700000006001100000000000000013614 +:105710000000EA600000000000000000000000003F +:105720000000000000000000000000000000000079 +:105730000000000000000000000000000000000069 +:105740000000000000000000000000160000000043 +:105750000000000000000000000000000000000049 +:105760000000000000000000000000000000000039 +:105770000000000000000000000000000000000029 +:105780000000138800000000000005DC000000009D +:105790000000000010000003000000000000000DE9 +:1057A0000000000D3C02080024423D883C03080034 +:1057B0002463403CAC4000000043202B1480FFFDDC +:1057C000244200043C1D080037BD7FFC03A0F021EB +:1057D0003C100800261000A83C1C0800279C3D88AF +:1057E0000E00044E000000000000000D27BDFFB4B5 +:1057F000AFA10000AFA20004AFA30008AFA4000C4B +:10580000AFA50010AFA60014AFA70018AFA8001CEA +:10581000AFA90020AFAA0024AFAB0028AFAC002C8A +:10582000AFAD0030AFAE0034AFAF0038AFB8003C22 +:10583000AFB90040AFBC0044AFBF00480E000591B7 +:10584000000000008FBF00488FBC00448FB90040AB +:105850008FB8003C8FAF00388FAE00348FAD003072 +:105860008FAC002C8FAB00288FAA00248FA90020BA +:105870008FA8001C8FA700188FA600148FA50010FA +:105880008FA4000C8FA300088FA200048FA100003A +:1058900027BD004C3C1B60048F7A5030377B50286A +:1058A00003400008AF7A00008F86003C3C03900064 +:1058B0003C0280000086282500A32025AC4400205F +:1058C0003C0380008C67002004E0FFFE0000000025 +:1058D00003E00008000000000A000070240400013A +:1058E0008F85003C3C0480003483000100A3102518 +:1058F00003E00008AC82002003E000080000102153 +:105900003084FFFF30A5FFFF108000070000182142 +:10591000308200011040000200042042006518217E +:105920001480FFFB0005284003E000080060102100 +:1059300010C00007000000008CA2000024C6FFFF7A +:1059400024A50004AC82000014C0FFFB24840004E2 +:1059500003E000080000000010A0000824A3FFFFDF +:10596000AC86000000000000000000002402FFFFE1 +:105970002463FFFF1462FFFA2484000403E000089C +:105980000000000090AA00318FAB00108CAC0040EA +:105990003C0300FF8D680004AD6C00208CAD00441A +:1059A00000E060213462FFFFAD6D00248CA7004849 +:1059B0003C09FF000109C024AD6700288CAE004CF3 +:1059C0000182C82403197825AD6F0004AD6E002C48 +:1059D0008CAD0038314A00FFAD6D001C94A9003237 +:1059E0003128FFFFAD68001090A70030A5600002CD +:1059F000A1600004A167000090A30032306200FFA4 +:105A00000002198210600005240500011065000ED7 +:105A10000000000003E00008A16A00018CD8002803 +:105A2000354A0080AD7800188CCF0014AD6F00149B +:105A30008CCE0030AD6E00088CC4002CA16A000131 +:105A400003E00008AD64000C8CCD001CAD6D0018A7 +:105A50008CC90014AD6900148CC80024AD6800081E +:105A60008CC70020AD67000C8CC200148C830070C2 +:105A70000043C82B13200007000000008CC2001454 +:105A8000144CFFE400000000354A008003E00008E9 +:105A9000A16A00018C8200700A0000E6000000008C +:105AA0009089003027BDFFF88FA8001CA3A9000033 +:105AB0008FA300003C0DFF8035A2FFFF8CAC002CB3 +:105AC00000625824AFAB0000A100000400C05821C0 +:105AD000A7A000028D06000400A048210167C8218C +:105AE0008FA50000008050213C18FF7F032C20264A +:105AF0003C0E00FF2C8C0001370FFFFF35CDFFFF60 +:105B00003C02FF0000AFC82400EDC02400C278248E +:105B1000000C1DC00323682501F87025AD0D0000A1 +:105B2000AD0E00048D240024AFAD0000AD040008CC +:105B30008D2C00202404FFFFAD0C000C9547003293 +:105B400030E6FFFFAD0600109145004830A200FF8F +:105B5000000219C2506000018D240034AD0400140D +:105B60008D4700388FAA001827BD0008AD0B00280C +:105B7000AD0A0024AD07001CAD00002CAD000018DC +:105B800003E00008AD00002027BDFFE0AFB2001821 +:105B9000AFB10014AFB00010AFBF001C9098003040 +:105BA00000C088213C0D00FF330F007FA0CF000014 +:105BB000908E003135ACFFFF3C0AFF00A0CE000103 +:105BC00094A6001EA22000048CAB00148E290004B1 +:105BD00000A08021016C2824012A4024008090210B +:105BE00001052025A6260002AE240004260500207B +:105BF000262400080E00009224060002924700307E +:105C0000260500282624001400071E0000031603A2 +:105C100024060004044000032403FFFF96590032C9 +:105C20003323FFFF0E000092AE2300102624002431 +:105C30008FBF001C8FB200188FB100148FB00010FE +:105C400024050003000030210A00009C27BD00202D +:105C500027BDFFD8AFB1001CAFB00018AFBF002008 +:105C600090A900302402000100E050213123003FC0 +:105C700000A040218FB000400080882100C0482152 +:105C8000106200148FA70038240B000500A020210B +:105C900000C02821106B0013020030210E000128E3 +:105CA000000000009225007C30A400021080000358 +:105CB00026030030AE000030260300348FBF0020E2 +:105CC0008FB1001C8FB000180060102103E00008A5 +:105CD00027BD00280E0000A7AFB000100A00016F1A +:105CE000000000008FA3003C01002021012028219A +:105CF00001403021AFA300100E0000EEAFB0001441 +:105D00000A00016F000000003C06800034C20E0053 +:105D10008C4400108F850044ACA400208C430018F4 +:105D200003E00008ACA300243C06800034C20E004F +:105D30008C4400148F850044ACA400208C43001CCC +:105D400003E00008ACA300249382000C1040001B69 +:105D50002483000F2404FFF00064382410E00019AD +:105D6000978B00109784000E9389000D3C0A601CED +:105D70000A0001AC01644023010370210064282360 +:105D80001126000231C2FFFF30A2FFFF0047302B77 +:105D900050C0000E00E448218D4D000C31A3FFFFE0 +:105DA00000036400000C2C0304A1FFF30000302169 +:105DB00030637FFF0A0001A42406000103E000080D +:105DC000000000009784000E00E448213123FFFF0B +:105DD0003168FFFF0068382B54E0FFF8A783000EFE +:105DE000938A000D11400005240F0001006BC023B1 +:105DF000A380000D03E00008A798000E006BC023ED +:105E0000A38F000D03E00008A798000E03E0000830 +:105E10000000000027BDFFE8AFB000103C1080007C +:105E200036030140308BFFFF93AA002BAFBF001455 +:105E3000A46B000436040E009488001630C600FFE0 +:105E40008FA90030A4680006AC650008A0660012A7 +:105E5000A46A001AAC6700208FA5002CA469001862 +:105E6000012020210E000198AC6500143C021000B6 +:105E7000AE0201788FBF00148FB0001003E000085D +:105E800027BD00188F8500002484000727BDFFF878 +:105E90003084FFF83C06800094CB008A316AFFFF13 +:105EA000AFAA00008FA90000012540232507FFFFAE +:105EB00030E31FFF0064102B1440FFF700056882D9 +:105EC000000D288034CC400000AC102103E0000815 +:105ED00027BD00088F8200002486000730C5FFF828 +:105EE00000A2182130641FFF03E00008AF84000007 +:105EF0008F87003C8F84004427BDFFB0AFB70044BC +:105F0000AFB40038AFB1002CAFBF0048AFB600400F +:105F1000AFB5003CAFB30034AFB20030AFB0002833 +:105F20003C0B80008C860024AD6700808C8A0020AA +:105F300035670E0035690100ACEA00108C8800243A +:105F40008D2500040000B821ACE800188CE3001097 +:105F500000A688230000A021ACE300148CE2001806 +:105F6000ACE2001C122000FE00E0B021936C00089F +:105F7000118000F400000000976F001031EEFFFF69 +:105F8000022E682B15A000EF000000009772001091 +:105F90003250FFFFAED000003C0380008C74000044 +:105FA000329300081260FFFD0000000096D8000840 +:105FB0008EC700043305FFFF30B5000112A000E4D6 +:105FC000000000000000000D30BFA0402419004078 +:105FD00013F9011B30B4A000128000DF00000000A4 +:105FE000937300081260000800000000976D001015 +:105FF00031ACFFFF00EC202B1080000330AE0040DE +:1060000011C000D500000000A7850040AF87003810 +:106010009363000802202821AFB10020146000F52E +:1060200027B40020AF60000C978F004031F1400092 +:1060300016200002240300162403000E2405400746 +:10604000A363000AAF650014938A00428F700014A6 +:10605000315500010015124002024825AF690014B5 +:10606000979F00408F78001433F9001003194025E2 +:10607000AF680014979200403247000810E0016EAC +:10608000000000008F6700143C1210003C118000DB +:1060900000F27825AF6F001436230E00946E000ACC +:1060A0003C0D81002406000E31CCFFFF018D202520 +:1060B000AF640004A36600029373000A3406FFFC79 +:1060C000266B0004A36B000A979800403308200059 +:1060D0001100015F000000003C05800034A90E00A3 +:1060E000979900409538000C97870040001940426E +:1060F0003312C0003103000300127B0330F11000A3 +:10610000006F68250011720301AE6025000C20C0ED +:10611000A764001297930040936A000A0013598203 +:106120003175003C02AA10212450003CA3700009E4 +:10613000953F000C33F93FFFA779001097700012CC +:10614000936900090130F82127E5000230B9000702 +:106150000019C02333080007A368000B93710009DE +:1061600097720012976F0010322700FF8F9100384E +:10617000978D004000F21821006F702101C6602148 +:1061800031A6004010C000053185FFFF00B1102B83 +:106190003C12800010400017000098210225A82B17 +:1061A00056A0013E8FA500203C048000348A0E00DA +:1061B0008D5300143C068000AD5300108D4B001C25 +:1061C000AD4B0018AD4500008CCD000031AC00088F +:1061D0001180FFFD34CE0E0095C3000800A0882179 +:1061E00000009021A78300408DC600042413000105 +:1061F000AF860038976F001031F5FFFF8E9F0000CB +:1062000003F1282310A0011FAE850000936200084F +:10621000144000DD000000000E0001E7240400101F +:106220008F900048004028213C023200320600FFD7 +:10623000000654000142F82526090001AF890048F4 +:10624000ACBF00009379000997780012936F000AA1 +:10625000332800FF3303FFFF0103382100076C00E0 +:1062600031EE00FF01AE6025ACAC00048F84004825 +:10627000978B0040316A20001140010AACA400084D +:1062800097640012308BFFFF06400108ACAB000C96 +:10629000978E004031C5000814A000022628000691 +:1062A000262800023C1F800037E70E0094F90014F6 +:1062B0008CE5001C8F670004937800023324FFFFF5 +:1062C000330300FFAFA300108F6F0014AFA80018B6 +:1062D0000E0001CBAFAF0014240400100E0001FB30 +:1062E000000000008E920000164000050000000033 +:1062F0008F7800142403FFBF0303A024AF7400149D +:106300008F67000C00F5C821AF79000C9375000869 +:1063100016A0000800000000126000060000000047 +:106320008F6800143C0AEFFF3549FFFE0109F8248D +:10633000AF7F0014A37300088FA500200A00034F4D +:1063400002202021AED100000A00022D3C03800073 +:1063500014E0FF1E30BFA0400E0001900000A021FD +:106360002E9100010237B02512C000188FBF0048DF +:106370008F87003C24170F0010F700D43C068000E4 +:106380008CD901780720FFFE241F0F0010FF00F6B4 +:1063900034CA0E008D56001434C701402408024050 +:1063A000ACF600048D49001C3C141000ACE9000858 +:1063B000A0E00012A4E0001AACE00020A4E0001865 +:1063C000ACE80014ACD401788FBF00488FB700440C +:1063D0008FB600408FB5003C8FB400388FB30034C7 +:1063E0008FB200308FB1002C8FB0002803E000087E +:1063F00027BD00508F910038978800403C128000E4 +:106400000220A8213107004014E0FF7C0000982101 +:10641000977900108F9200383338FFFF131200A8CD +:10642000000020210080A021108000F300A088211E +:106430001620FECE000000000A00031F2E9100016E +:106440003C0380008C6201780440FFFE24080800B1 +:106450008F860000AC6801783C038000946D008A50 +:1064600031ACFFFF01865823256AFFFF31441FFF2F +:106470002C8900081520FFF9000000008F8F0048CC +:10648000347040008F83003C00E0A021240E0F00F8 +:1064900025E70001AF87004800D03021023488236F +:1064A0003C08800031F500FF106E00052407000154 +:1064B00093980042331300010013924036470001C5 +:1064C000001524003C0A0100008A4825ACC90000E0 +:1064D0008F82004830BF003630B90008ACC20004DB +:1064E0001320009900FF982535120E009650000ADF +:1064F0008F8700003C0F81003203FFFF24ED00086E +:1065000035060140006F60253C0E100031AB1FFFC7 +:10651000269200062405000EACCC0020026E9825C1 +:10652000A4C5001AAF8B0000A4D2001816200008E2 +:106530003C1080008F89003C24020F005122000291 +:1065400024170001367300400E0001883C108000C3 +:1065500036060E008CCB0014360A01400240202182 +:10656000AD4B00048CC5001CAD450008A1550012C0 +:10657000AD5300140E0001983C151000AE150178C3 +:106580000A00035200000000936F0009976E00128A +:10659000936D000B31E500FF00AE202131AC00FF10 +:1065A000008C80212602000A3050FFFF0E0001E718 +:1065B000020020218F8600483C0341003C058000FA +:1065C00024CB0001AF8B0048936A00099769001241 +:1065D00030C600FF315F00FF3128FFFF03E838219C +:1065E00024F900020006C4000319782501E3702590 +:1065F000AC4E00008F6D000C34A40E00948B001480 +:1066000001B26025AC4C00048C85001C8F6700042F +:10661000936A00023164FFFF314900FFAFA9001007 +:106620008F680014AFB100180E0001CBAFA80014A2 +:106630000A0002FD02002021AF600004A3600002F6 +:1066400097980040330820001500FEA30000302179 +:10665000A760001297840040936B000A3C108000F2 +:1066600030931F0000135183014BA82126A200285C +:10667000A362000936090E00953F000C0A0002953E +:10668000A77F00108F700014360900400E000188AB +:10669000AF6900140A0002C9000000000A00034F9D +:1066A000000020210641FEFAACA0000C8CAC000CCE +:1066B0003C0D8000018D90250A0002EAACB2000C6E +:1066C000000090210A0002C5241300011280000777 +:1066D0003C028000344B0E009566000830D3004029 +:1066E00012600049000000003C0680008CD0017858 +:1066F0000600FFFE34C50E0094B500103C030500F3 +:1067000034CC014032B8FFFF03039025AD92000C5A +:106710008CAF0014240D20003C041000AD8F000449 +:106720008CAE001CAD8E0008A1800012A580001A5E +:10673000AD800020A5800018AD8D0014ACC4017898 +:106740000A0003263C0680008F9F00003518014098 +:106750002692000227F9000833281FFFA71200180D +:106760000A000391AF8800003C02800034450140DC +:10677000ACA0000C1280001B34530E0034510E00EC +:106780008E370010ACB700048E2400183C0B80003C +:10679000ACA400083570014024040040A20000129F +:1067A0008FBF0048A600001A8FB70044AE0000203B +:1067B0008FB60040A60000188FB5003CAE04001450 +:1067C0008FB400388FB300348FB200308FB1002CFB +:1067D0008FB000283C02100027BD005003E00008E5 +:1067E000AD6201788E660014ACA600048E64001CB5 +:1067F0000A00042A3C0B80000E0001902E9100013B +:106800000A0003200237B025000000000000000D40 +:1068100000000000240003690A0004013C06800017 +:1068200027BDFFD8AFBF00203C0980003C1F20FFE0 +:10683000AFB200183C07600035320E002402001091 +:1068400037F9FFFDACE23008AFB3001CAFB1001464 +:10685000AFB00010AE5900000000000000000000C2 +:106860000000000000000000000000003C1800FFD5 +:106870003713FFFDAE5300003C0B60048D705000D9 +:106880002411FF7F3C0E00020211782435EC380CF5 +:1068900035CD0109ACED4C18240A0009AD6C50004F +:1068A0008CE80438AD2A0008AD2000148CE54C1C9F +:1068B0003106FFFF38C42F7100051E023062000F41 +:1068C0002486C0B310400007AF8200088CE54C1C42 +:1068D0003C09001F3528FC0000A81824000321C231 +:1068E000AF8400048CF108083C0F57092412F00013 +:1068F0000232702435F0001001D0602601CF6826E6 +:106900002DAA00012D8B0001014B382550E0000914 +:10691000A380000C3C1F601C8FF8000824190001A4 +:10692000A399000C33137C00A7930010A780000EDE +:10693000A380000DAF80004814C00003AF800000AA +:106940003C066000ACC0442C0E0005B93C10800031 +:106950000E000F24361101003C12080026523DF0B3 +:106960003C13080026733E708E030000386400015B +:10697000308200011440FFFC3C0B800A8E26000090 +:106980002407FF8024C90240312A007F014B4021A7 +:1069900001272824AE060020AF880044AE0500245D +:1069A0003C048000AF86003C8C8C01780580FFFEA3 +:1069B00024180800922F0008AC980178A38F004299 +:1069C000938E004231CD000111A0000F24050D006F +:1069D00024DFF8002FF903011320001C000629C250 +:1069E00024A4FFF000041042000231400E00020215 +:1069F00000D2D8213C0240003C068000ACC20138E5 +:106A00000A0004A00000000010C50023240D0F00A0 +:106A100010CD00273C1F800837F900809338000014 +:106A2000240E0050330F00FF15EEFFF33C02400030 +:106A30000E000A40000000003C0240003C068000BE +:106A4000ACC201380A0004A0000000008F830004DB +:106A500000A3402B1500000B8F8B0008006B50210A +:106A60002547FFFF00E5482B1520000600A3602303 +:106A7000000C19400E0002020073D8210A0004C461 +:106A80003C0240000000000D0E0002020000000069 +:106A90000A0004C43C0240003C1B0800277B3F70F6 +:106AA0000E000202000000000A0004C43C02400084 +:106AB0003C1B0800277B3F900E00020200000000F4 +:106AC0000A0004C43C0240003C0660043C09080083 +:106AD00025290104ACC9502C8CC850003C0580000D +:106AE0003C02000235070080ACC750003C0408009F +:106AF000248415A43C0308002463155CACA500089D +:106B0000ACA2000C3C010800AC243D803C01080014 +:106B1000AC233D8403E000082402000100A03021E2 +:106B20003C1C0800279C3D883C0C04003C0B0002E8 +:106B3000008B3826008C40262CE200010007502BE9 +:106B40002D050001000A48803C03080024633D80B5 +:106B5000004520250123182110800003000010218A +:106B6000AC6600002402000103E000080000000001 +:106B70003C1C0800279C3D883C0B04003C0A00029A +:106B8000008A3026008B38262CC200010006482BD4 +:106B90002CE50001000940803C03080024633D808F +:106BA0000045202501031821108000050000102158 +:106BB0003C0C0800258C155CAC6C00002402000124 +:106BC00003E00008000000003C0900023C0804004B +:106BD00000883026008938262CC300010080282137 +:106BE0002CE40001008310251040000B0000302130 +:106BF0003C1C0800279C3D883C0A80008D4E000804 +:106C00002406000101CA6825AD4D00088D4C000C1A +:106C100001855825AD4B000C03E0000800C0102191 +:106C20003C1C0800279C3D883C0580008CA6000C7D +:106C3000000420272402000100C4182403E00008F7 +:106C4000ACA3000C3C0200021082000B3C0560006B +:106C50003C070400108700030000000003E0000868 +:106C6000000000008CA908D0240AFFFD012A40245E +:106C700003E00008ACA808D08CA408D02406FFFECE +:106C80000086182403E00008ACA308D03C05601A75 +:106C900034A600108CC3008027BDFFF88CC500848B +:106CA000AFA3000093A4000024020001108200039F +:106CB000AFA5000403E0000827BD000893A700016A +:106CC00014E0001497AC000297B800023C0F80005B +:106CD000330EFFFC01CF6821ADA50000A3A000008A +:106CE0003C0660008CC708D02408FFFE3C04601AF4 +:106CF00000E82824ACC508D08FA300048FA20000B0 +:106D00003499001027BD0008AF22008003E000087E +:106D1000AF2300843C0B8000318AFFFC014B4821EB +:106D20008D2800000A00057DAFA8000427BDFFE8FC +:106D3000AFBF00103C1C0800279C3D883C0580002C +:106D40008CA4000C8CA200043C0300020044282404 +:106D500010A0000A00A318243C0604003C04000212 +:106D60001460000900A610241440000F3C04040025 +:106D70000000000D3C1C0800279C3D888FBF0010C0 +:106D800003E0000827BD00183C0208008C423D804B +:106D90000040F809000000003C1C0800279C3D88CA +:106DA0000A0005A68FBF00103C0208008C423D84FB +:106DB0000040F809000000000A0005AC00000000D7 +:106DC000000411C003E00008244202403C04080013 +:106DD00024843FD42405001A0A00009C00003021BE +:106DE00027BDFFE0AFB000103C108000AFBF00181F +:106DF000AFB1001436110100922200090E0005B651 +:106E00003044007F8E3F00008F89003C3C0F0080A3 +:106E100003E26021258800400049F821240DFF800D +:106E2000310E00783198007835F9000135F1000213 +:106E30000319382501D14825010D302403ED5824CC +:106E4000018D2824240A004024040080240300C06B +:106E5000AE0B0024AE000810AE0A0814AE040818E9 +:106E6000AE03081CAE050804AE070820AE060808ED +:106E7000AE090824360909009539000C3605098049 +:106E800033ED007F3338FFFF001889C0AE110800D2 +:106E9000AE0F0828952C000C8FBF00188FB100147E +:106EA000318BFFFF000B51C0AE0A002C8CA40050A8 +:106EB0008FB000108CA3003C8D2700048CA8001C10 +:106EC0008CA600383C0E800A01AE102127BD0020A0 +:106ED000AF820044AF840050AF830054AF87004CB2 +:106EE000AF88005C03E00008AF8600603C09080042 +:106EF00091293FF924A800023C05110000093C003B +:106F000000E8302500C5182524820008AC83000065 +:106F100003E00008AC8000043C0980003523090030 +:106F20009128010B906A001124020028008048215A +:106F3000314700FF00A0702100C0682131080040E7 +:106F400010E20002340C86DD240C08003C0A8000AC +:106F500035420A9A94470000354B0A9C35460AA0F0 +:106F600030F9FFFFAD3900008D780000354B0A8005 +:106F700024040001AD3800048CCF0000AD2F0008C0 +:106F80009165001930A300031064009A2864000280 +:106F9000148000B924050002106500A8240F000326 +:106FA000106F00BE35450AA4240A0800118A004D5E +:106FB00000000000510000423C0B80003C048000B7 +:106FC000348309009067001230E200FF004D782101 +:106FD000000FC880272400013C0A8000354F0900BB +:106FE00091E50019354C09808D87002830A300FFFA +:106FF00000031500004758250004C4003C19600038 +:1070000001793025370806FFAD260000AD280004C1 +:107010008DEA002C25280028AD2A00088DEC0030D0 +:10702000AD2C000C8DE50034AD2500108DE400384A +:10703000AD2400148DE3001CAD2300188DE7002063 +:10704000AD27001C8DE20024AD2200208DF9002820 +:10705000AD3900243C0980003526093C8CCF000066 +:10706000352A0100AD0E0004AD0F00008D4E000C5E +:107070003523090035250980AD0E0008906C0012FB +:107080008D47000C8CB900343C18080093183FF869 +:10709000318200FF004D582103277823000B370071 +:1070A0000018240000C4702531E9FFFC01C96825DF +:1070B00025020014AD0D000C03E00008AD00001027 +:1070C00035780900930600123C05080094A53FE8B6 +:1070D00030C800FF010D5021000A60800A00063C04 +:1070E0000185202115000060000000003C08080018 +:1070F00095083FEE3C06080094C63FE801061021C3 +:107100003C0B80003579090093380011932A00194F +:1071100035660A80330800FF94CF002A0008608299 +:10712000314500FF978A0058000C1E00000524001E +:107130003047FFFF006410250047C02501EA3021D9 +:107140003C0B4000030B402500066400AD28000006 +:10715000AD2C0004932500183C03000625280014DC +:1071600000053E0000E31025AD2200088F24002C0E +:10717000254F000131EB7FFFAD24000C8F38001C40 +:10718000A78B0058AD3800103C0980003526093C1B +:107190008CCF0000352A0100AD0E0004AD0F0000B9 +:1071A0008D4E000C3523090035250980AD0E0008F1 +:1071B000906C00128D47000C8CB900343C1808000C +:1071C00093183FF8318200FF004D582103277823A0 +:1071D000000B37000018240000C4702531E9FFFCC3 +:1071E00001C9682525020014AD0D000C03E000085C +:1071F000AD0000103C02080094423FF23C0508003C +:1072000094A53FE835440AA43C07080094E73FE40E +:10721000948B00000045C8210327C023000B1C00ED +:107220002706FFF200665025AD2A000CAD200010A5 +:10723000AD2C00140A00063025290018354F0AA489 +:1072400095E50000956400280005140000043C004A +:107250003459810000EC5825AD39000CAD2B0010DD +:107260000A000630252900143C0C0800958C3FEEDE +:107270000A000686258200015460FF4C240A08009B +:1072800035580AA49706000000061C00006C502523 +:10729000AD2A000C0A000630252900103C03080026 +:1072A00094633FF23C07080094E73FE83C0F080076 +:1072B00095EF3FE494A40000957900280067102121 +:1072C000004F582300041C00001934002578FFEEFD +:1072D00000D87825346A8100AD2A000CAD2F00104B +:1072E000AD200014AD2C00180A0006302529001C22 +:1072F00003E00008240207D027BDFFE0AFB200186A +:10730000AFB10014AFB00010AFBF001C0E00007C86 +:10731000008088218F8800548F87004C3C058008AE +:1073200034B20080011128213C108000240200802A +:10733000240300C000A72023AE0208183C068008E2 +:10734000AE03081C18800004AF850054ACC50004CF +:107350008CC90004AF89004C122000093604098052 +:107360000E00070200000000924C00278E0B0074F4 +:1073700001825004014B3021AE46000C36040980D6 +:107380008C8E001C8F8F005C01CF682319A0000435 +:107390008FBF001C8C90001CAF90005C8FBF001C46 +:1073A0008FB200188FB100148FB000100A00007E59 +:1073B00027BD00208F8600508F8300548F82004CA1 +:1073C0003C05800834A40080AC860050AC83003CAF +:1073D00003E00008ACA200043C0308008C630054E6 +:1073E00027BDFFF8308400FF2462000130A500FFB4 +:1073F0003C010800AC22005430C600FF3C0780006E +:107400008CE801780500FFFE3C0C7FFFA3A400037D +:107410008FAA0000358BFFFF014B4824000627C0D0 +:1074200001244025AFA8000034E201009043000A87 +:10743000A3A000023C1980FFA3A300018FAF0000AE +:1074400030AE007F3738FFFF01F86024000E6E0079 +:107450003C0A002034E50140018D582535492000C3 +:107460002406FF803C04100027BD0008ACAB000CD4 +:10747000ACA90014A4A00018A0A6001203E0000804 +:10748000ACE40178308800FF30A700FF3C038000A7 +:107490008C6201780440FFFE3C0C8000358A0A00B3 +:1074A0008D4B00203584014035850980AC8B00046C +:1074B0008D4900240007302B00061540AC890008D8 +:1074C000A088001090A3004CA083002D03E00008CA +:1074D000A480001827BDFFE8308400FFAFBF001074 +:1074E0000E00076730A500FF8F8300548FBF001088 +:1074F0003C06800034C50140344700402404FF901E +:107500003C02100027BD0018ACA3000CA0A4001280 +:10751000ACA7001403E00008ACC2017827BDFFE06F +:107520003C088008AFBF001CAFB20018AFB1001418 +:10753000AFB00010351000808E0600183C078000A8 +:10754000309200FF00C72025AE0400180E00007C1A +:1075500030B100FF92030005346200080E00007E87 +:10756000A2020005024020210E00077B02202821F4 +:10757000024020218FBF001C8FB200188FB1001471 +:107580008FB0001024050005240600010A00073C06 +:1075900027BD00203C05800034A3098090660008C8 +:1075A00030C200081040000F3C0A01013549080AAA +:1075B000AC8900008CA80074AC8800043C0708006B +:1075C00090E73FF830E5001050A00008AC800008BC +:1075D0003C0D800835AC00808D8B0058AC8B0008CA +:1075E0002484000C03E00008008010210A0007BF7B +:1075F0002484000C27BDFFE83C098000AFB00010D8 +:10760000AFBF00143526098090C800092402000687 +:1076100000A05821310300FF352709000080802198 +:10762000240500041062007B2408000294CF005C53 +:107630003C0E020431EDFFFF01AE6025AE0C0000F0 +:1076400090CA0008314400201080000800000000AB +:1076500090C2004E3C1F010337F90300305800FF71 +:107660000319302524050008AE06000490F9001126 +:1076700090E6001290E40011333800FF0018708289 +:1076800030CF00FF01CF5021014B6821308900FF2E +:1076900031AAFFFF39230028000A60801460002C03 +:1076A000020C482390E400123C198000372F01009F +:1076B000308C00FF018B1821000310800045F82159 +:1076C000001F8400360706FFAD270004373F09007E +:1076D00093EC001193EE0012372609800005C0825A +:1076E0008DE4000C8CC5003431CD00FF01AB1021BE +:1076F0000058182100A4F8230008840000033F006C +:1077000000F0302533F9FFFF318F00FC00D97025E0 +:107710000158202101E9682100045080ADAE000C21 +:107720000E00007C012A80213C088008240B000404 +:10773000350500800E00007EA0AB0009020010217C +:107740008FBF00148FB0001003E0000827BD0018A1 +:1077500090EC001190E300193C18080097183FEED8 +:10776000318200FF0002F882307000FF001FCE005F +:1077700000103C000327302500D870253C0F400046 +:1077800001CF68253C198000AD2D0000373F09006E +:1077900093EC001193EE0012372F01003726098079 +:1077A0000005C0828DE4000C8CC5003431CD00FF93 +:1077B00001AB10210058182100A4F8230008840010 +:1077C00000033F0000F0302533F9FFFF318F00FC4C +:1077D00000D970250158202101E96821000450805A +:1077E000ADAE000C0E00007C012A80213C08800810 +:1077F000240B0004350500800E00007EA0AB0009BC +:10780000020010218FBF00148FB0001003E00008A9 +:1078100027BD00180A0007D12408001227BDFFD099 +:107820003C038000AFB60028AFB50024AFB4002001 +:10783000AFB10014AFBF002CAFB3001CAFB2001843 +:10784000AFB000103467010090E6000B309400FFE9 +:1078500030B500FF30C200300000B0211040009968 +:1078600000008821346409809088000800082E00F8 +:1078700000051E03046000C0240400048F86005429 +:107880003C010800A0243FF83C0C8000AD8000487B +:107890003C048000348E010091CD000B31A5002006 +:1078A00010A000073C078000349309809272000802 +:1078B0000012860000107E0305E000C43C1F800813 +:1078C00034EC0100918A000B34EB098091690008C7 +:1078D000314400400004402B3123000800C89823A5 +:1078E0001460000224120003000090213C1080006C +:1078F00036180A8036040900970E002C9083001178 +:107900009089001293050018307F00FF312800FF96 +:10791000024810210002C880930D0018033F78210F +:1079200001F1302130B100FF00D11821A78E00589D +:107930003C010800A4263FEE3C010800A4233FF0D0 +:1079400015A00002000000000000000D920B010BCA +:107950003065FFFF3C010800A4233FF2316A00407C +:107960003C010800A4203FE83C010800A4203FE4BB +:107970001140000224A4000A24A4000B3091FFFF50 +:107980000E0001E7022020219206010B3C0C0800AA +:10799000958C3FF2004020210006698231A700014A +:1079A0000E000601018728210040202102602821C5 +:1079B0000E00060C024030210E0007AB00402021D3 +:1079C00016C00069004020219212010B325600407F +:1079D00012C000053C0500FF8C93000034AEFFFF91 +:1079E000026E8024AC9000000E0001FB02202021DA +:1079F0003C0F080091EF3FF831F100031220001610 +:107A00003C1380088F8200543C0980083528008090 +:107A1000245F0001AD1F003C3C0580088CB90004C8 +:107A200003E02021033FC0231B000002AF9F00544E +:107A30008CA400040E000702ACA400043C078000E4 +:107A40008CEB00743C04800834830080004B502190 +:107A5000AC6A000C3C138008367000800280202144 +:107A600002A02821A200006B0E0007673C148000D2 +:107A70008F920054368C0140AD92000C8F860048E6 +:107A80003C151000344D000624D60001AF96004886 +:107A90008FBF002CA18600128FB60028AD8D001478 +:107AA0008FB3001CAE9501788FB200188FB50024FB +:107AB0008FB400208FB100148FB0001003E00008D5 +:107AC00027BD003034640980908F0008000F7600D5 +:107AD000000E6E0305A00033347F090093F8001BED +:107AE000241900103C010800A0393FF833130002AC +:107AF0001260FF678F8600548F8200601446FF6516 +:107B00003C0480000E00007C000000003C04800863 +:107B10003485008090A8000924060016310300FF78 +:107B20001066000D0000000090AB00093C07080043 +:107B300090E73FF824090008316400FF34EA0001AF +:107B40003C010800A02A3FF81089002F240C000AED +:107B5000108C00282402000C0E00007E00000000A3 +:107B60000A00086A8F8600540E0007C302402821CD +:107B70000A0008B8004020213C0B8008356A0080CC +:107B80008D4600548CE9000C1120FF3DAF86005457 +:107B9000240700143C010800A0273FF80A000869E8 +:107BA0003C0C800090910008241200023C01080067 +:107BB000A0323FF8323000201200000B24160001E2 +:107BC0008F8600540A00086A2411000837F80080E4 +:107BD0008F020038AFE200048FF90004AF19003CB7 +:107BE0000A0008763C0780008F8600540A00086A65 +:107BF00024110004A0A200090E00007E0000000075 +:107C00000A00086A8F860054240200140A000944FE +:107C1000A0A2000927BDFFE8AFB000103C10800013 +:107C2000AFBF001436020100904400090E00076740 +:107C3000240500013C0480089099000E34830080E4 +:107C4000909F000F906F00269089000A33F800FF84 +:107C500000196E000018740031EC00FF01AE5025D1 +:107C6000000C5A00014B3825312800FF3603014033 +:107C70003445600000E830252402FF813C041000F8 +:107C8000AC66000C8FBF0014AC650014A06200123B +:107C9000AE0401788FB0001003E0000827BD001883 +:107CA00027BDFFE8308400FFAFBF00100E0007675C +:107CB00030A500FF3C05800034A40140344700405B +:107CC0002406FF92AC870014A08600128F83005414 +:107CD0008FBF00103C02100027BD0018AC83000CC1 +:107CE00003E00008ACA2017827BDFFD8AFB00010B8 +:107CF000308400FF30B000FF3C058000AFB10014BD +:107D0000AFBF0020AFB3001CAFB20018000410C218 +:107D100034A6010032030002305100011460000754 +:107D200090D200093C098008353300809268000534 +:107D30003107000810E0000C308A001002402021BA +:107D40000E00078D02202821240200018FBF002091 +:107D50008FB3001C8FB200188FB100148FB00010C9 +:107D600003E0000827BD00281540003434A50A00B0 +:107D70008CB800248CAF0008130F004B0000382192 +:107D80003C0D800835B30080926C00682406000228 +:107D9000318B00FF116600843C06800034C2010074 +:107DA0009263004C90590009307F00FF53F90004A2 +:107DB0003213007C10E00069000000003213007CE8 +:107DC0005660005C0240202116200009320D00019F +:107DD0003C0C800035840100358B0A008D65002441 +:107DE0008C86000414A6FFD900001021320D00017A +:107DF00011A0000E024020213C1880003710010025 +:107E00008E0F000C8F8E005011EE00080000000055 +:107E10000E00084D022028218E19000C3C1F8008FE +:107E200037F00080AE190050024020210E00077B81 +:107E3000022028210A000999240200013C050800BB +:107E40008CA5006424A400013C010800AC2400645B +:107E50001600000D00000000022028210E00077B04 +:107E600002402021926E0068240C000231CD00FFF8 +:107E700011AC0022024020210E00094B000000003E +:107E80000A000999240200010E0000702404000178 +:107E9000926B0025020B30250E00007EA2660025A5 +:107EA0000A0009DD022028218E6200188CDF000400 +:107EB0008CB9002400021E0217F9FFB13065007F63 +:107EC0009268004C264400013093007F1265004008 +:107ED000310300FF1464FFAB3C0D8008264700010E +:107EE00030F1007F30E200FF1225000B2407000173 +:107EF000004090210A0009A6241100012405000475 +:107F00000E00073C240600010E00094B0000000093 +:107F10000A000999240200012405FF80024520245B +:107F200000859026324200FF004090210A0009A6F9 +:107F3000241100010E00084D0220282132070030D4 +:107F400010E0FFA132100082024020210E00078DB8 +:107F5000022028210A000999240200018E690018D4 +:107F60000240202102202821012640250E00096E12 +:107F7000AE6800189264004C24050003240600013A +:107F80000E00073C308400FF0E0000702404000146 +:107F900092710025021150250E00007EA26A002574 +:107FA0000A000999240200018E6F00183C18800015 +:107FB0000240202101F87025022028210E00077BB5 +:107FC000AE6E00189264004C0A000A2524050004D5 +:107FD000324A0080394900801469FF6A3C0D8008EC +:107FE0000A0009FE2647000127BDFFC0AFB00018F8 +:107FF0003C108000AFBF0038AFB70034AFB60030E0 +:10800000AFB5002CAFB40028AFB30024AFB200204E +:108010000E0005BEAFB1001C360201009045000BFA +:108020000E00098090440008144000E78FBF00381C +:108030003C08800835070080A0E0006B3606098008 +:1080400090C50000240300503C17080026F73FB0FD +:1080500030A400FF3C13080026733FC010830003C8 +:108060003C1080000000B82100009821241F00105F +:108070003611010036120A00361509808E58002488 +:108080008E3400048EAF00208F8C00543C01080019 +:10809000A03F3FF836190A80972B002C8EF600007F +:1080A000932A00180298702301EC68233C01080011 +:1080B000AC2E3FD43C010800AC2D3FD83C01080059 +:1080C000AC2C3FFCA78B005802C0F809315400FFCC +:1080D00030490002152000E930420001504000C440 +:1080E0009227000992A90008312800081500000213 +:1080F000241500030000A8213C0A80003543090034 +:1081000035440A008C8D002490720011907000128A +:10811000907F0011325900FF321100FF02B110218F +:108120000002C08033EF00FF0319B021028F7021DD +:1081300002D4602125CB00103C010800A4363FEE9C +:108140003C010800AC2D40003C010800A42C3FF08D +:108150003C010800A42B3FEC355601003554098042 +:1081600035510E008F8700548F89005C8E8500206A +:1081700024080006012730233C010800AC283FF406 +:1081800000A7282304C000B50000902104A000B37C +:1081900000C5502B114000B5000000003C01080054 +:1081A000AC263FD88E6200000040F80900000000B5 +:1081B0003046000214C0007400408021304B0001A2 +:1081C000556000118E6200043C0D08008DAD3FDC4F +:1081D0003C0EC0003C04800001AE6025AE2C0000C7 +:1081E0008C980000330F000811E0FFFD0000000034 +:1081F000963F000824120001A79F00408E3900041A +:10820000AF9900388E6200040040F80900000000B9 +:108210000202802532030002146000B30000000057 +:108220003C09080095293FE43C06080094C63FF04D +:108230003C0A0800954A3FE63C0708008CE73FDC13 +:10824000012670213C0308008C6340003C080800B4 +:1082500095083FFA01CA20218ED9000C00E9282197 +:10826000249F000200A878210067C02133E4FFFFAB +:10827000AF9900503C010800AC3840003C010800B8 +:10828000A42F3FE83C010800A42E3FF20E0001E7B6 +:10829000000000008F8D0048004020213C010800B4 +:1082A000A02D3FF98E62000825AC0001AF8C00487C +:1082B0000040F809000000008F85005402A0302122 +:1082C0000E00060C004020210E0007AB00402021CC +:1082D0008E6B000C0160F809004020213C0A080068 +:1082E000954A3FF23C06080094C63FE60146482105 +:1082F000252800020E0001FB3104FFFF3C050800A9 +:108300008CA53FD43C0708008CE73FDC00A7202366 +:108310003C010800AC243FD414800006000000009B +:108320003C0208008C423FF4344B00403C01080002 +:10833000AC2B3FF4124000438F8E00448E2D001072 +:108340008F920044AE4D00208E2C0018AE4C0024BD +:108350003C04080094843FE80E000704000000007D +:108360008F9F00548E6700103C010800AC3F3FFC1B +:1083700000E0F809000000003C1908008F393FD4E4 +:108380001720FF798F870054979300583C11800E77 +:10839000321601000E000733A633002C16C000452C +:1083A000320300105460004C8EE500043208004097 +:1083B0005500001D8EF000088EE4000C0080F809C6 +:1083C000000000008FBF00388FB700348FB6003038 +:1083D0008FB5002C8FB400288FB300248FB20020FB +:1083E0008FB1001C8FB0001803E0000827BD0040CB +:1083F0008F86003C36110E0000072E0000A62025B7 +:10840000AE0400808E4300208E500024AFA30010E5 +:10841000AE2300148FB20010AE320010AE30001C3C +:108420000A000A7FAE3000180200F80900000000C0 +:108430008EE4000C0080F809000000000A000B38F0 +:108440008FBF003824180001240F0001A5C00020B0 +:10845000A5D800220A000B1AADCF00243C01080069 +:10846000AC203FD80A000AB08E6200003C01080030 +:10847000AC253FD80A000AB08E62000092240009A1 +:108480000E00077B000028218FBF00388FB7003413 +:108490008FB600308FB5002C8FB400288FB3002426 +:1084A0008FB200208FB1001C8FB0001803E00008CD +:1084B00027BD00403C14800092950109000028214E +:1084C0000E00084D32A400FF320300105060FFB8C8 +:1084D000320800408EE5000400A0F809000000000A +:1084E0000A000B32320800405240FFA89793005810 +:1084F0008E3400148F930044AE7400208E35001C1F +:10850000AE7500240A000B29979300588F8200143F +:108510000004218003E00008008210213C0780084D +:1085200034E200809043006900804021106000091F +:108530003C0401003C0708008CE73FFC8F830030BF +:1085400000E32023048000089389001C14E3000347 +:108550000100202103E00008008010213C040100FC +:1085600003E00008008010211120000B0067382371 +:108570003C0D800035AC0980918B007C316A000293 +:10858000114000202409003400E9702B15C0FFF1D0 +:108590000100202100E938232403FFFC00A3C824A4 +:1085A00000E3C02400F9782B15E0FFEA030820213E +:1085B00030C400030004102314C000143049000329 +:1085C0000000302100A9782101E6702100EE682B1F +:1085D00011A0FFE03C0401002D3800010006C82B6B +:1085E000010548210319382414E0FFDA2524FFFC93 +:1085F0002402FFFC00A218240068202103E00008E8 +:10860000008010210A000BA8240900303C0C8000D7 +:108610003586098090CB007C316A00041540FFE963 +:10862000240600040A000BB7000030213C030800B8 +:108630008C63005C8F82001827BDFFE0AFBF00187D +:10864000AFB1001410620005AFB00010000329C0E4 +:1086500024A40280AF840014AF8300183C10800073 +:1086600036020A0094450032361101000E000B89D3 +:1086700030A43FFF8E240000241FFF803C110080A7 +:108680000082C021031F60243309007F000CC94011 +:1086900003294025330E0078362F00033C0D1000CF +:1086A000010D502501CF5825AE0C00283608098051 +:1086B000AE0C080CAE0B082CAE0A08309103006912 +:1086C0003C06800C0126382110600006AF8700347C +:1086D0008D09003C8D03006C0123382318E00082D3 +:1086E000000000003C0B8008356A00803C108000D0 +:1086F000A1400069360609808CC200383C06800023 +:1087000034C50A0090A8003C310C00201180001AEA +:10871000AF820030240D00013C0E800035D10A00EC +:10872000A38D001CAF8000248E2400248F8500249C +:10873000240D0008AF800020AF8000283C01080015 +:10874000A42D3FE63C010800A4203FFA0E000B8D4B +:10875000000030219228003C8FBF00188FB1001418 +:108760008FB0001000086142AF82002C27BD0020AE +:1087700003E000083182000190B80032240E0001AD +:10878000330F00FF000F2182108E004124190002D8 +:108790001099006434C40AC03C03800034640A00A9 +:1087A0008C8F002415E0001E34660900909F003075 +:1087B0002418000533F9003F1338004E240300014C +:1087C0008F860020A383001CAF860028AF8600247C +:1087D0003C0E800035D10A008E2400248F850024B1 +:1087E000240D00083C010800A42D3FE63C010800D0 +:1087F000A4203FFA0E000B8D000000009228003CE0 +:108800008FBF00188FB100148FB0001000086142B4 +:10881000AF82002C27BD002003E000083182000158 +:108820008C8A00088C8B00248CD000643C0E800065 +:1088300035D10A00014B2823AF900024A380001CEF +:10884000AF8500288E2400248F8600208F85002489 +:10885000240D00083C010800A42D3FE63C0108005F +:10886000A4203FFA0E000B8D000000009228003C6F +:108870008FBF00188FB100148FB000100008614244 +:10888000AF82002C27BD002003E0000831820001E8 +:1088900090A200303051003F5224002834C50AC055 +:1088A0008CB000241600002234CB09008CA60048AE +:1088B0003C0A7FFF3545FFFF00C510243C0E8000B9 +:1088C000AF82002035C509008F8800208CAD006084 +:1088D000010D602B15800002010020218CA4006096 +:1088E0000A000C2CAF8400208D02006C0A000C06DC +:1088F0003C0680008C8200488F8600203C097FFF68 +:108900003527FFFF004788243C048008240300012A +:10891000AF910028AC80006CA383001C0A000C3AC5 +:10892000AF8600248C9F00140A000C2CAF9F0020FF +:108930008D6200680A000C763C0E800034C4098009 +:108940008C8900708CA300140123382B10E00004E4 +:10895000000000008C8200700A000C763C0E800043 +:108960008CA200140A000C763C0E80008F85002437 +:1089700027BDFFE0AFBF0018AFB1001414A000087E +:10898000AFB000103C04800034870A0090E600304D +:108990002402000530C3003F106200B9348409008E +:1089A0008F91002000A080213C048000348E0A00BA +:1089B0008DCD00043C0608008CC63FD831A73FFF90 +:1089C00000E6602B5580000100E03021938F001CF1 +:1089D00011E0007800D0282B349F098093F9007CA7 +:1089E00033380002130000792403003400C3102B35 +:1089F000144000D90000000000C3302300D0282B11 +:108A00003C010800A4233FE414A0006E02001821DA +:108A10003C0408008C843FD40064402B55000001C6 +:108A2000006020213C05800034A90A00912A003C06 +:108A30003C010800AC243FDC3143002014600003FB +:108A40000000482134AB0E008D6900188F88002C7F +:108A50000128202B1080005F000000003C0508006A +:108A60008CA53FDC00A96821010D602B1180005C02 +:108A700000B0702B0109382300E028213C010800D8 +:108A8000AC273FDC12000003240AFFFC10B0008D6D +:108A90003224000300AA18243C010800A4203FFA55 +:108AA0003C010800AC233FDC006028218F840024B7 +:108AB000120400063C0B80088D6C006C0200202123 +:108AC000AF91002025900001AD70006C8F8D0028C3 +:108AD00000858823AF91002401A52023AF840028BE +:108AE0001220000224070018240700103C188008F8 +:108AF0003706008090CF00683C010800A0273FF8AF +:108B00002407000131EE00FF11C7004700000000FC +:108B100014800018000028213C06800034D1098010 +:108B200034CD010091A600098E2C001824C4000148 +:108B3000000C86023205007F308B007F1165007FBC +:108B40002407FF803C19800837290080A124004CAD +:108B50003C0808008D083FF4241800023C0108007E +:108B6000A0384039350F00083C010800AC2F3FF415 +:108B7000240500103C02800034440A009083003C2D +:108B8000307F002013E0000500A02021240A00010E +:108B90003C010800AC2A3FDC34A400018FBF001860 +:108BA0008FB100148FB000100080102103E0000886 +:108BB00027BD00203C010800A4203FE410A0FF9442 +:108BC000020018210A000CCA00C018210A000CC1BA +:108BD000240300303C0508008CA53FDC00B0702B5E +:108BE00011C0FFA8000000003C19080097393FE4BD +:108BF0000325C0210307782B11E000072CAA0004ED +:108C00003C0360008C625404305F003F17E0FFE3D8 +:108C1000240400422CAA00041140FF9A24040042BC +:108C20000A000D2E8FBF00181528FFB900000000A4 +:108C30008CCA00183C1F800024020002015F182526 +:108C4000ACC3001837F90A00A0C200689329003CA1 +:108C50002404000400A01021312800203C01080059 +:108C6000A024403911000002240500102402000154 +:108C70003C010800AC223FD40A000D243C028000D5 +:108C80008F8800288C8900600109282B14A000021D +:108C9000010088218C9100603C048000348B0E0020 +:108CA0008D640018240A00010220282102203021AE +:108CB000A38A001C0E000B8D022080210A000CB03C +:108CC000AF82002C000458231220000731640003F7 +:108CD0003C0E800035C7098090ED007C31AC00046B +:108CE00015800019248F00043C010800A4243FFAD9 +:108CF0003C1F080097FF3FFA03E5C82100D9C02BAD +:108D00001300FF6B8F8400242CA6000514C0FFA362 +:108D10002404004230A200031440000200A21823E1 +:108D200024A3FFFC3C010800AC233FDC3C0108000D +:108D3000A4203FFA0A000CF10060282100C770242B +:108D40000A000D1701C720263C010800A42F3FFA96 +:108D50000A000D82000000003C010800AC203FDC4E +:108D60000A000D2D240400428F8300283C0580005A +:108D700034AA0A0014600006000010219147003058 +:108D80002406000530E400FF108600030000000008 +:108D900003E0000800000000914B0048316900FF2B +:108DA000000941C21500FFFA3C0680083C04080097 +:108DB00094843FE43C0308008C633FFC3C190800AA +:108DC0008F393FDC3C0F080095EF3FFA0064C0216B +:108DD0008CCD00040319702101CF602134AB0E004B +:108DE000018D282318A0001D00000000914F004CA9 +:108DF0008F8C0034956D001031EE00FF8D890004DA +:108E000001AE30238D8A000030CEFFFF000E290016 +:108E10000125C82100003821014720210325182BF6 +:108E20000083C021AD990004AD980000918F000A25 +:108E300001CF6821A18D000A956500128F8A003448 +:108E4000A5450008954B003825690001A549003863 +:108E50009148000D35070008A147000D03E0000808 +:108E60000000000027BDFFD8AFB000189388001C99 +:108E70008FB000143C0A80003C197FFF8F870024CC +:108E80003738FFFFAFBF0020AFB1001C355F0A00CD +:108E90000218182493EB003C00087FC03C02BFFF7F +:108EA000006F60252CF000013449FFFF3C1F0800D3 +:108EB0008FFF3FFC8F9900303C18080097183FF255 +:108EC00001897824001047803C07EFFF3C05F0FF44 +:108ED00001E818253C1180003169002034E2FFFFD1 +:108EE00034ADFFFF362E098027A5001024060002AE +:108EF00003F96023270B0002354A0E000062182494 +:108F00000080802115200002000040218D48001CB7 +:108F1000A7AB0012058000392407000030E800FFED +:108F200000083F00006758253C028008AFAB0014E2 +:108F3000344F008091EA00683C08080091083FF92E +:108F40003C09DFFF352CFFFF000AF82B3C0208002C +:108F500094423FECA3A80011016CC024001FCF4035 +:108F6000031918258FA70010AFA300143C0C0800AC +:108F7000918C3FFBA7A200168FAB001400ED482494 +:108F80003C0F01003C0A0FFF012FC8253198000358 +:108F9000355FFFFF016D40243C027000033F382421 +:108FA00000181E0000E2482501037825AFAF001429 +:108FB000AFA9001091CC007C0E000092A3AC00156C +:108FC000362D0A0091A6003C30C400201080000617 +:108FD000260200083C11080096313FE8262EFFFFCC +:108FE0003C010800A42E3FE88FBF00208FB1001C79 +:108FF0008FB0001803E0000827BD00288F8B002CDD +:10900000010B502B5540FFC5240700010A000E0E2E +:1090100030E800FF9383001C3C02800027BDFFD88E +:1090200034480A0000805021AFBF002034460AC0F7 +:10903000010028211060000E34440980910700309F +:10904000240B00058F89002030EC003F118B000BB2 +:1090500000003821AFA900103C0B80088D69006C1E +:10906000AFAA00180E00015AAFA90014A380001C7B +:109070008FBF002003E0000827BD00288D1F004897 +:109080003C1808008F183FDC8F9900283C027FFFB6 +:109090008D0800443443FFFFAFA900103C0B80084B +:1090A0008D69006C03E370240319782101CF6823D4 +:1090B00001A83821AFAA00180E00015AAFA9001468 +:1090C0000A000E62A380001C3C05800034A60A0042 +:1090D00090C7003C3C06080094C63FFA3C020800DA +:1090E0008C423FF430E30020000624001060001E94 +:1090F000004438253C0880083505008090A30068AE +:109100000000482124080001000028212404000157 +:109110003C0680008CCD017805A0FFFE34CF0140D5 +:10912000ADE800083C0208008C423FFCA5E50004C5 +:10913000A5E40006ADE2000C3C04080090843FF971 +:109140003C03800834790080A1E40012ADE70014EC +:10915000A5E900189338004C3C0E1000A1F8002D32 +:1091600003E00008ACCE017834A90E008D28001C65 +:109170003C0C08008D8C3FDC952B0016952A0014C2 +:10918000018648213164FFFF0A000E8A3145FFFF46 +:109190003C04800034830A009065003C30A200202B +:1091A0001040001934870E000000402100003821D3 +:1091B000000020213C0680008CC901780520FFFEBC +:1091C00034CA014034CF010091EB0009AD480008DA +:1091D0003C0E08008DCE3FFC240DFF91240C004076 +:1091E0003C081000A5440004A5470006AD4E000C45 +:1091F000A14D0012AD4C0014A5400018A14B002D4C +:1092000003E00008ACC801788CE8001894E600126E +:1092100094E4001030C7FFFF0A000EB33084FFFF54 +:109220003C04800034830A009065003C30A200209A +:109230001040002727BDFFF8240900010000382155 +:10924000240800013C0680008CCA01780540FFFE1E +:109250003C0280FF34C40100908D00093C0C0800E2 +:10926000918C4039A3AD00038FAB00003185007FA6 +:109270003459FFFF01665025AFAA00009083000A11 +:10928000A3A0000200057E00A3A300018FB8000088 +:1092900034CB0140240C30000319702401CF682521 +:1092A000AD6D000C27BD0008AD6C0014A560001862 +:1092B000AD690008A56700042409FF80A5680006C1 +:1092C0003C081000A169001203E00008ACC8017856 +:1092D00034870E008CE9001894E6001294E4001024 +:1092E00030C8FFFF0A000ED73087FFFF27BDFFE021 +:1092F000AFB100143C118000AFB00010AFBF001838 +:1093000036380A00970F0032363001000E000B8904 +:1093100031E43FFF8E0E0000240DFF803C0420004E +:1093200001C25821016D6024000C4940316A007F60 +:10933000012A4025010438253C048008AE27083066 +:109340003486008090C500682403000230A200FF2C +:10935000104300048F9F00208F990024AC9F006869 +:10936000AC9900648FBF00188FB100148FB000104B +:1093700003E0000827BD00203C0A0800254A3AA85F +:109380003C09080025293B383C08080025082F44E3 +:109390003C07080024E73C043C06080024C6392C9E +:1093A0003C05080024A536803C040800248432844F +:1093B0003C030800246339E03C0208002442377C67 +:1093C0003C010800AC2A3FB83C010800AC293FB47E +:1093D0003C010800AC283FB03C010800AC273FBC72 +:1093E0003C010800AC263FCC3C010800AC253FC442 +:1093F0003C010800AC243FC03C010800AC233FD036 +:109400003C010800AC223FC803E000080000000057 +:109410008000094080000900800801008008008069 +:1094200080080000800E0000800800808008000096 +:1094300080000A8080000A00800009808000090006 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex deleted file mode 100644 index 52c496331de21ccbb0f9eddd692023205a4b31bc..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-rv2p-06-5.0.0.j3.fw.ihex +++ /dev/null @@ -1,424 +0,0 @@ -:100000000000000000000C900000005800000009F3 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000CE000000CE80000000500000000DB -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F01030300000000080500FFFF5F -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000000050000000000000C2F8000019F -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E0000200000008AC00000108 -:1000C00000000010203F004D00000010213F000301 -:1000D0000000001020BF001C000000188000FFFD81 -:1000E00000000008B1000001000000082C8000B0F2 -:1000F000000000082D000008000000082D8000010D -:10010000000000188000006C0000000B2FDF0002D0 -:100110000000000C1F800002000000002C070000FF -:100120000000001091DE0000000000080500555599 -:10013000000000188000FFF00000000B2FDF00021D -:100140000000000C1F800000000000002C070000D1 -:100150000000001091DE0000000000080500555569 -:10016000000000188000FFEA0000000C1F80000261 -:100170000000000805005555000000188000FFE74A -:100180000000000C298000020000000C1F8000020B -:10019000000000002ADF0000000000082A0000051F -:1001A0000000000805005555000000188000FFE120 -:1001B000000000080224002C0000001800040000C9 -:1001C000000000188000001C000000188000001EC5 -:1001D000000000188000006500000018800000B0DA -:1001E00000000018800000AF000000188000000030 -:1001F00000000018800000000000001880000000CF -:1002000000000018800000000000001880000000BE -:1002100000000018800000000000001880000000AE -:10022000000000188000000000000018800000F6A8 -:10023000000000188000000000000018800000008E -:100240000000001880000015000000188000001B4E -:10025000000000188000000000000018800000C6A8 -:10026000000000188000002F00000018800000F639 -:10027000000000188000012100000018800000EC40 -:100280000000001880000145000000188000004EAA -:1002900000000018800000000000001880000083AB -:1002A0000000000C1F80000100000000050000009D -:1002B000000000188000FFC00000001091D4000072 -:1002C0000000000C298000010000000C1F800001CC -:1002D000000000082A0000020000000005000000E5 -:1002E000000000188000FFBA0000001091D4000048 -:1002F0000000000C298000010000000C1F8000019C -:100300000000000029420000000000082A0000024E -:100310000000000005000000000000188000FFB38E -:10032000000000188000FFB200000010B1BCB00A4D -:100330000000000B2FDF00020000000003D80000C7 -:10034000000000002C3C00000000001091D40000D0 -:100350000000000806005555000000188000001736 -:1003600000000018800000BF000000102C6201BADD -:100370000000001880000006000000082C8000B17A -:10038000000000082D0000090000001091D40000BA -:10039000000000082D8001070000001880000024E4 -:1003A0000000000C298000000000000C1F800000ED -:1003B0000000001091DE0000000000002ADF0000B5 -:1003C000000000082A00000600000008050055553E -:1003D000000000188000FF9C0000001091D4000075 -:1003E0000000000C298000010000000C1F800001AB -:1003F000000000082A00000B0000000005000000BB -:10040000000000188000FF960000001800020000A5 -:10041000000000000682000000000010B18A000801 -:1004200000000010B18C14070000000B050AFFFF4C -:1004300000000010B18A000300000000860A1800C6 -:1004400000000010918C0000000000082A0000014C -:100450000000001091D4000000000018000D000002 -:1004600000000000050200000000001091DE000006 -:1004700000000018000A00000000000006820000D2 -:100480000000001091DE000000000010BEE1000539 -:10049000000000188000FF7D0000000105611400CD -:1004A00000000010918A000200000008B0E1000185 -:1004B00000000018000D000000000000068200008F -:1004C0000000001091DE000000000010BEE20005F8 -:1004D000000000188000FF75000000010562140094 -:1004E00000000010918A000200000008B1620001C3 -:1004F00000000018000D000000000010B1A0B013B3 -:100500000000000B2FDF0002000000002C20000084 -:10051000000000082C800000000000082D000000F2 -:100520000000001091D4000000000008060055559E -:10053000000000188000FFDC000000082D80011C76 -:1005400000000010001F0000000000188000FFE6FF -:100550000000000F476000080000000F060E0001B9 -:10056000000000000F580000000000000A640000B6 -:10057000000000000AE50000000000090B66FFFF14 -:10058000000000000D610000000000188000001352 -:100590000000000F476000080000000B2FDF000282 -:1005A000000000082C800000000000082D00000062 -:1005B0000000001091D40000000000082D80011CF4 -:1005C0000000000F060E000100000010001F0000D8 -:1005D000000000000F580000000000188000FFD449 -:1005E000000000000A640000000000000AE50000AE -:1005F000000000090B66FFFF000000000D61000015 -:1006000000000000026200000000000B2FDF00026B -:10061000000000003104000000000000309A0000DB -:10062000000000000C961800000000090C99FFFF64 -:1006300000000004CC99340000000010B196320292 -:10064000000000080F8000000000000C298000015D -:100650000000000C295200010000000C295200008B -:10066000000000080200000E000000080280001ACE -:1006700000000010B1C40A020000000802000003DC -:1006800000000008220000010000000C1F80000193 -:10069000000000002ADF0000000000002A0008001F -:1006A0000000000805005555000000188000FF41BB -:1006B0000000000B2FDF00020000001091D40000AA -:1006C000000000082A000001000000002C200000AB -:1006D0000000001091D40000000000082C800000F1 -:1006E000000000082D000000000000082D80011C03 -:1006F000000000188000FFAE000000082C800006FB -:10070000000000082D0000060000000030800000FE -:100710000000000031000000000000082D800006ED -:100720000000000C298000010000000C1F80000167 -:100730000000001091DE0000000000002ADF000031 -:10074000000000082A000010000000000500000062 -:10075000000000188000FF2C0000001091A0B009DC -:10076000000000082C8000B1000000082D000009E6 -:100770000000001091D40000000000082D80010747 -:10078000000000188000FFA7000000188000001083 -:1007900000000008AC000001000000188000000B01 -:1007A000000000000380B0000000000B2FDF0002FB -:1007B000000000002C0040000000001091D4000058 -:1007C0000000000806005555000000188000FF8951 -:1007D00000000018800000310000001880000006B2 -:1007E0000000000B2FDF0002000000002C000E00B4 -:1007F000000000082A000007000000080500555509 -:10080000000000188000FF160000000006820000B3 -:100810000000000C298000010000000C1F80000176 -:10082000000000100CE70007000000090562FFFF50 -:1008300000000010BA6C1405000000002ADF000060 -:100840000000000021000000000000082A00000550 -:100850000000001091D40000000000082C8000B0BF -:10086000000000082D0000080000000C3162001894 -:10087000000000082D800001000000188000FF7DAE -:1008800000000018000D000000000010B1A0B00E24 -:100890000000000B2FDF00020000000003D8000062 -:1008A000000000002C2000000000001091D4000087 -:1008B0000000001880000015000000102C620002EB -:1008C000000000188000000C0000000B2FDF000269 -:1008D000000000002C0700000000000C1F80000139 -:1008E0000000001091DE0000000000080500FFFF7E -:1008F000000000188000FEF8000000082C8000B105 -:10090000000000082D0000090000001091D4000034 -:10091000000000082D800107000000188000FF740F -:100920000000000C298000010000000C1F80000165 -:100930000000001091DE0000000000002ADF00002F -:10094000000000082A00000A000000000500000066 -:10095000000000188000FEEC00000000068200008D -:10096000000000082C8000B0000000082D000008E6 -:10097000000000082D800150000000000000000071 -:100980000000001091DE0000000000082C80000034 -:10099000000000082D000000000000082D80010567 -:1009A00000000010BEE20005000000188000FEDA22 -:1009B000000000010562140000000010918A00028E -:1009C00000000008B16200010000001091DE00008C -:1009D00000000018000D00000000001091D400007D -:1009E000000000080600AAAA000000188000FF45C9 -:1009F0000000000C298000010000000C1F80000195 -:100A0000000000082A000009000000080500AAAA4A -:100A1000000000188000FED40000001091D40000F7 -:100A20000000000806005555000000188000FF3D3A -:100A30000000001091A03C0200000010B1E6620727 -:100A40000000000B2FDF0002000000002C3100002E -:100A5000000000092CB1007F000000082CD9000024 -:100A6000000000082D000000000000082D80010D8E -:100A700000000010B1A8000600000010205F000078 -:100A8000000000002C200000000000002CA7000047 -:100A9000000000082D000010000000082D80010853 -:100AA000000000188000FF3800000010B1A6001000 -:100AB00000000010001F00000000000F0F300007B2 -:100AC000000000000A600000000000000AE10000D1 -:100AD0000000000F4B620008000000090B1600FF29 -:100AE000000000000D620000000000090D1A00FF68 -:100AF00000000010073000030000000C0D1A000871 -:100B00000000000C0B1600080000000F4CE300185A -:100B1000000000000C992C0000000004CC99340067 -:100B2000000000080F8000000000000C2980000178 -:100B30000000000033310000000000082200001611 -:100B4000000000002ADF0000000000082A00000C5E -:100B500000000010009F0000000000000F200000B7 -:100B60000000000C1F800001000000080500555522 -:100B7000000000188000FEA80000001091D40000C2 -:100B8000000000080600AAAA000000188000FF115B -:100B90000000000F4722000800000009070E000FA8 -:100BA00000000008070E0008000000080280000195 -:100BB0000000000702851C0000000008828500017B -:100BC0000000000002854C000000000742851C0068 -:100BD00000000003C3AA52000000000003B10E0091 -:100BE000000000074B071C000000000F0F3000073B -:100BF0000000000F0A960003000000000A955C0048 -:100C0000000000004A005A00000000000C960A0094 -:100C1000000000090C99FFFF000000080D00FFFF15 -:100C200000000010B1963202000000080F8000059D -:100C300000000010B1A8000800000010205F0000B4 -:100C40000000000B2FDF0002000000002C2000003D -:100C5000000000002CA70000000000082D0000107C -:100C6000000000082D800108000000188000FEFF31 -:100C70000000000C2980000100000010001F00008F -:100C80000000000C1F800001000000002ADF0000AF -:100C9000000000082A00000D000000080500AAAAB4 -:100CA000000000188000FE820000001091D40000B7 -:100CB0000000000806005555000000188000FEEBFB -:100CC0000000000C298000010000000C1F800001C2 -:100CD000000000082A000007000000080500555524 -:080CE000000000188000FE7AFC -:080CE80000000010B1800004BF -:100CF0000000001F0103030000000008050000FFC2 -:100D00000000001800020000000000002A0000009F -:100D100000000010B1D400000000001091DE0000BF -:100D2000000000102053000000000010001F000011 -:100D3000000000002F80AA000000000C29800001A4 -:100D4000000000080254000D000000002C400000CC -:100D500000000018000400000000001880000010CF -:100D60000000001880000011000000188000003909 -:100D700000000018800000DF00000018800000DE86 -:100D800000000018800000DD00000018800000DD79 -:100D9000000000188000000000000018800000F52E -:100DA00000000018800000D9000000188000000B2F -:100DB00000000018800000F90000001880000147C2 -:100DC000000000188000005900000018800000C4D6 -:100DD00000000018800000C5000000002A0000008C -:100DE000000000188000FFE6000000002A0000005C -:100DF0000000000C29800000000000188000FFE3C4 -:100E0000000000002A000000000000188000FFE140 -:100E100000000018000200000000000005020000B1 -:100E2000000000109196342100000010205F0000A7 -:100E3000000000002C1E0000000000082C800006AE -:100E4000000000082D000006000000082D800102AF -:100E500000000000000000000000001091DE000013 -:100E6000000000000D61000000000018000A0000F2 -:100E700000000000050200000000001091963416EA -:100E800000000010205F00000000000009D80000F2 -:100E9000000000002C1E0000000000082C8000B2A2 -:100EA000000000082D00000A000000082D8001024B -:100EB00000000000000000000000001091DE0000B3 -:100EC000000000000D620000000000002C13000074 -:100ED00000000018000A00000000000005020000E9 -:100EE000000000109196340900000010205F0000FF -:100EF000000000002C1E0000000000082C800006EE -:100F0000000000082D00006A000000082D8001028A -:100F100000000000000000000000001091DE000052 -:100F2000000000000D7A000000000018000A000018 -:100F3000000000002A000000000000000D61000019 -:100F4000000000000362000000000010234200A324 -:100F50000000000002638C00000000002646000034 -:100F6000000000080204001200000010B906081E6C -:100F7000000000000F580000000000000A6400009C -:100F8000000000000AE50000000000090B66FFFFFA -:100F9000000000000C000000000000000B800000BA -:100FA000000000080CC60012000000188000FFCEF0 -:100FB000000000080F800003000000000000000097 -:100FC00000000010009F0000000000082711001220 -:100FD000000000006690000000000008A31B001243 -:100FE00000000010B198000300000010001F000076 -:100FF000000000080F800004000000082200000329 -:10100000000000082C80000C000000082D00000CDF -:1010100000000010009F0000000000002596000066 -:101020000000000C298000000000000032140000C5 -:1010300000000000329500000000000573662C00DF -:101040000000000031E32E00000000082D80001099 -:10105000000000188000FF9800000000230000003E -:101060000000000925E6FFFF000000082200000B39 -:101070000000000C695200000000000C29800000F4 -:10108000000000188000FF92000000002A0000000D -:10109000000000082C800040000000082D00002007 -:1010A000000000082D80011C00000000000000006E -:1010B0000000001091DE00000000000F42EA001066 -:1010C00000000010004F000400000010B74692001E -:1010D000000000080249001200000010B5840A0058 -:1010E000000000000D61000000000010BA663457D7 -:1010F000000000088305001200000010004F0002ED -:1011000000000000034900000000000183068C007D -:101110000000000083C60C0000000010B187001121 -:10112000000000000B6E000000000010BEE900058A -:10113000000000188000FF7900000001056914001C -:1011400000000010918A000200000008B4E90001CC -:1011500000000010B1E92C4A0000000086692C0054 -:1011600000000000020000000000000902EAFFFF8A -:1011700000000010000C00020000000002040A0041 -:101180000000000F460C00010000000F0285000166 -:1011900000000010918C01FC00000010B7040E410B -:1011A000000000000F400000000000000D61000082 -:1011B000000000000A640000000000000AE50000D2 -:1011C000000000090B66FFFF000000000C0000009B -:1011D000000000000B800000000000080C860012D8 -:1011E000000000080F8000030000000C29520000DE -:1011F00000000010009F00000000000827110012EE -:10120000000000006690000000000000264600007C -:10121000000000002306000000000010B198000547 -:1012200000000010001F0000000000080F800004F4 -:10123000000000000000000000000010001F00007F -:101240000000000032140000000000003295000091 -:101250000000000031E32E000000000573662C0042 -:10126000000000002596000000000010B187001665 -:101270000000000C298000000000000F0F6B000729 -:10128000000000000D690000000000000A6C000072 -:10129000000000000AED0000000000000B6E0000DE -:1012A000000000000B800000000000000C87000020 -:1012B000000000080F800003000000102053000011 -:1012C0000000000C6952000100000010001F000027 -:1012D0000000000022C58C0000000000231B00005D -:1012E0000000000027110000000000002690000010 -:1012F00000000010B8170E030000000C2980000049 -:10130000000000188000FFF600000010B1980002F5 -:10131000000000080F800004000000082200001AEE -:10132000000000082C80000C000000082D00000CBC -:10133000000000082D80001000000010001F0000B9 -:10134000000000000D6E000000000003E7CF340035 -:101350000000000C298000000000001091DE000059 -:1013600000000010B18700070000000036140000E4 -:101370000000000036950000000000003716000055 -:10138000000000082C800050000000082D000030F4 -:10139000000000082D80000C000000188000FF2FC6 -:1013A00000000000264600000000000023000000AE -:1013B0000000000925E6FFFF000000000B6E0000A2 -:1013C00000000003E7CF2C00000000082200001BF3 -:1013D0000000000C695200000000000C2980000091 -:1013E000000000188000FF26000000002A00000016 -:1013F000000000188000FF24000000002A00000008 -:101400000000000C298000000000001091DE0000A8 -:10141000000000082C80001A000000082D00001AAF -:101420000000000573660000000000082D80000227 -:1014300000000000318000000000001091DE00007C -:10144000000000082C80000C000000082D00000C9B -:10145000000000082D800004000000188000FF1725 -:101460000000001800020000000000188000FF15B6 -:10147000000000002A00000000000010001F000013 -:10148000000000000F008000000000080F8000072F -:10149000000000188000001A00000000280A000068 -:1014A0000000000005020000000000082200000902 -:1014B00000000000290000000000000F6568001017 -:1014C00000000003F66C940000000010B972A00444 -:1014D0000000000C73E700190000000C214200041A -:1014E000000000003CF800000000000C2980000013 -:1014F0000000001020530000000000082200000837 -:101500000000000C6142000400000018000A000006 -:1015100000000000050200000000000C6142000015 -:1015200000000010014200030000000C33E7001D22 -:101530000000000C6142000200000018000A0000D8 -:10154000000000002A00000000000010001F000042 -:101550000000000F0F470007000000080F80000880 -:101560000000000C2980000000000010009F000017 -:10157000000000188000FEF400000000335100005D -:10158000000000002A00000000000010B1C6002387 -:101590000000000F0F500007000000000A6000006C -:1015A000000000000AE100000000000F4B6200088C -:1015B000000000090B1600FF0000000F4C62001035 -:1015C000000000000D620000000000090D1A00FF7D -:1015D00000000010075000030000000C0D1A000866 -:1015E0000000000C0B160008000000000CC60000F4 -:1015F000000000000B8000000000000006980000C2 -:10160000000000080F8000030000001006C2000464 -:101610000000000C29000002000000102642000219 -:101620000000000C29520003000000082200000105 -:1016300000000010009F000000000000231B0000BD -:101640000000000027111A00000000006690000052 -:101650000000000C2952000000000010B197320970 -:101660000000000C29800000000000000698000027 -:1016700000000010205300000000000C295200035D -:101680000000000022C58C0000000010001F0000B8 -:10169000000000080F800003000000188000FFF326 -:1016A00000000010B1C8001300000010B1C6000314 -:1016B0000000000C298000000000001020530000F2 -:1016C0000000000C295200000000000C2952000309 -:1016D0000000001006C200020000000C29520002A7 -:1016E0000000000022C58C000000000027650000FB -:1016F0000000000026E400000000000822000016A0 -:1017000000000010B1C600030000000023480000E4 -:1017100000000010B1800005000000002348000018 -:101720000000000C298000000000000F0F5000078F -:1017300000000018800000120000000822000016BF -:101740000000000C298000000000000030140000A0 -:10175000000000003095000000000010075000035A -:10176000000000090B1600FF000000090D1A00FF21 -:101770000000000F31160008000000003162340044 -:1017800000000003F162300000000010205F000044 -:10179000000000002C510000000000092CD1007F47 -:1017A000000000082CD90000000000082D000000F7 -:1017B000000000082D80000C000000000000000068 -:1017C0000000001091DE00000000001005C20004BF -:1017D000000000080F800007000000003300000038 -:1017E00000000010009F0000000000188000FEA50F -:1017F000000000002A0000000000000F0F5000074A -:1018000000000010B1C6002D0000000F4742000884 -:1018100000000009070E000F00000008070E000876 -:1018200000000010001F0000000000080900000177 -:101830000000000709121C0000000003CBCA920040 -:10184000000000000B97A2000000000742171C00D8 -:10185000000000000B0400000000000F0A840003D9 -:10186000000000000A959C00000000004A009A0059 -:101870000000000882120001000000010C1708009F -:10188000000000000C978C0000000000021800000F -:10189000000000080D00FFFF000000080F80000698 -:1018A0000000000C290000000000001006C2000427 -:1018B0000000000C29520002000000102642000225 -:1018C0000000000C29520003000000082200000163 -:1018D00000000010009F000000000010B197320CC3 -:1018E00000000000231B000000000000271108007A -:1018F00000000000669000000000000C298000003D -:10190000000000000218000000000010205300003A -:101910000000000C295200030000000022C5360020 -:1019200000000010001F0000000000080F800006EB -:10193000000000188000FFF400000000231B0000DE -:101940000000000027110800000000006690000061 -:1019500000000010B1C8000B0000000C298000003E -:1019600000000010205300000000000C295200006D -:101970000000000C295200030000001006C2000203 -:101980000000000C295200020000000022C58C005B -:1019900000000000276500000000000026E40000B1 -:1019A000000000002348000000000008220000178B -:1019B0000000000C2980000000000010001F000043 -:0819C000000000188000FE6A1F -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex b/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex new file mode 100644 index 0000000000000000000000000000000000000000..dcc443e210f5262552287cf7079f7f12710e5774 --- /dev/null +++ b/firmware/bnx2/bnx2-rv2p-06-6.0.15.fw.ihex @@ -0,0 +1,366 @@ +:1000000000000000000008F800000058000000098F +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000CF000000950000000050000000066 +:1000400000000000000000000000000000000000B0 +:080050000000000000000000A8 +:0800580000000010B180000659 +:100060000000001F0106000F000000080500FFFF50 +:10007000000000180002000000000008050000FF5A +:10008000000000180002000000000008AC000001A1 +:1000900000000008078000000000000C2F80000115 +:1000A000000000002B000000000000002B8000007A +:1000B0000000001091E1000200000008AC00000107 +:1000C00000000010203F003B00000010213F000313 +:1000D0000000001020BF0015000000188000FFFD88 +:1000E0000000000C1F800002000000188000FFF9D3 +:1000F00000000008B1000001000000082C8000B0E2 +:10010000000000082D000008000000082D800001FC +:10011000000000188000003C0000000B2FDF0002F0 +:100120000000000C1F800002000000002C070000EF +:100130000000001091DE0000000000188000FFEFBA +:100140000000000B2FDF00020000000C1F800000E9 +:10015000000000002C0700000000001091DE0000ED +:10016000000000188000FFEA0000000C1F80000261 +:10017000000000188000FFE80000000802240025AD +:1001800000000018000400000000001880000000BB +:10019000000000188000001B0000001880000042D2 +:1001A000000000188000000000000018800000001F +:1001B000000000188000000000000018800000000F +:1001C00000000018800000000000001880000000FF +:1001D00000000018800000000000001880000000EF +:1001E00000000018800000000000001880000000DF +:1001F000000000188000008E000000188000000041 +:1002000000000018800000000000001880000000BE +:1002100000000018800000000000001880000000AE +:10022000000000188000000000000018800000009E +:10023000000000188000008D00000018800000B74A +:10024000000000188000008400000018800000DA20 +:10025000000000188000002B000000188000000043 +:10026000000000188000006B0000001091D4000016 +:100270000000000C298000010000000C1F8000011C +:10028000000000082A0000020000000807800000AB +:10029000000000188000FFC4000000080380010077 +:1002A00000000010B73C0E000000001880000000A5 +:1002B000000000180002000000000000068200009C +:1002C00000000010B18F000400000010B18F140373 +:1002D000000000082A0000010000001091D4000076 +:1002E000000000000780140000000018000D00004E +:1002F00000000000050200000000001091DE000078 +:1003000000000018000A0000000000000682000043 +:100310000000001091DE0000000000090561FFFFF1 +:1003200000000010918A00020000000830E1FFFF89 +:10033000000000188000FFA9000000010561140002 +:1003400000000010918A000200000008B0E10001E6 +:1003500000000018000D00000000000006820000F0 +:100360000000001091DE0000000000090562FFFFA0 +:1003700000000010918A0002000000083162FFFFB7 +:10038000000000188000FF9F0000000105621400BB +:1003900000000010918A000200000008B162000114 +:1003A00000000018000D000000000010B1A0B01304 +:1003B0000000000B2FDF0002000000002C200000D6 +:1003C000000000082C800000000000082D00000044 +:1003D0000000001091D40000000000080500005546 +:1003E000000000188000FFDB000000082D80011CC9 +:1003F00000000010001F0000000000188000FFE255 +:100400000000000F476000080000000F060E00010A +:10041000000000000F580000000000000A64000007 +:10042000000000000AE50000000000090B66FFFF65 +:10043000000000000D6100000000001880000015A1 +:100440000000000F476000080000000B2FDF0002D3 +:10045000000000082C800000000000082D000000B3 +:100460000000001091D40000000000082D80011C45 +:100470000000000F060E000100000010001F000029 +:10048000000000000F580000000000188000FFD09E +:10049000000000000A640000000000000AE50000FF +:1004A000000000090B66FFFF000000000D61000066 +:1004B00000000000026200000000000002E00000F6 +:1004C0000000000B2FDF00020000000030050000DC +:1004D000000000003104000000000000309A00001D +:1004E000000000100060000A00000008051600016E +:1004F00000000010BA9A140300000000030000007E +:100500000000001880000006000000188000FF6C4A +:1005100000000010B60614040000000803060001E5 +:10052000000000082A000001000000188000FF7190 +:10053000000000000C961800000000090C99FFFF55 +:1005400000000004CC99340000000010BA992C027D +:10055000000000080F8000000000000C298000014E +:100560000000000C295200010000000C295200007C +:100570000000000822800002000000080200000EB7 +:10058000000000080280001A00000010B1C40A0236 +:1005900000000008020000030000000C1F800001A2 +:1005A000000000002ADF0000000000002A00080010 +:1005B000000000188000FF600000000B2FDF000229 +:1005C0000000001091D40000000000082A00000183 +:1005D000000000002C2000000000001091D400005A +:1005E000000000082C800000000000082D00000022 +:1005F000000000082D80011C000000188000FF9FF3 +:10060000000000082C800006000000082D000006F5 +:1006100000000000308000000000000031000000F9 +:10062000000000082D8000060000000C2980000159 +:100630000000000C1F8000010000001091DE00008F +:10064000000000002ADF0000000000082A0000105F +:100650000000000807800000000000188000FF4B29 +:100660000000001091D4000000000008050000AA5E +:10067000000000188000FF890000000C29800001A4 +:100680000000000C1F800001000000082A00000983 +:10069000000000188000FF440000001091D400000A +:1006A0000000000805000055000000188000FF82CF +:1006B0000000001091A0B00200000010B1E6620737 +:1006C0000000000B2FDF0002000000002C310000B2 +:1006D000000000092CB1007F000000082CD90000A8 +:1006E000000000082D000000000000082D80010D12 +:1006F00000000010B1A8000600000010205F0000FC +:10070000000000002C200000000000002CA70000CA +:10071000000000082D000010000000082D800108D6 +:10072000000000188000FF7A00000010B1A6001041 +:1007300000000010001F00000000000F0F30000735 +:10074000000000000A600000000000000AE1000054 +:100750000000000F4B620008000000090B1600FFAC +:10076000000000000D620000000000090D1A00FFEB +:1007700000000010073000030000000C0D1A0008F4 +:100780000000000C0B1600080000000F4CE30018DE +:10079000000000000C992C0000000004CC993400EB +:1007A000000000080F8000000000000C29800001FC +:1007B0000000000033310000000000082200001695 +:1007C000000000002ADF0000000000082A00000CE2 +:1007D00000000010009F0000000000002C2000001E +:1007E0000000000C1F800001000000188000FF19AD +:1007F0000000001091D4000000000008050000AACD +:10080000000000188000FF570000000F472200087A +:1008100000000009070E000F00000008070E000886 +:1008200000000008028000010000000702851C0093 +:1008300000000008828500010000000002854C00D5 +:100840000000000742851C0000000003C3AA5200FC +:100850000000000003B10E00000000074B071C0061 +:100860000000000F0F3000070000000F0A96000381 +:10087000000000000A955C00000000004A005A00D9 +:10088000000000000C960A00000000090C99FFFF10 +:10089000000000080D00FFFF00000010BA992C02B4 +:1008A000000000080F80000500000010B1A800083B +:1008B00000000010205F00000000000B2FDF00028E +:1008C000000000002C200000000000002CA7000009 +:1008D000000000082D000010000000082D80010815 +:1008E000000000188000FF420000000C2980000179 +:1008F00000000010001F00000000000C1F8000011D +:10090000000000002ADF0000000000082A00000D9F +:10091000000000188000FEF40000001091D40000D8 +:100920000000000805000055000000188000FF329C +:100930000000000C298000010000000C1F80000155 +:10094000000000082A000007000000188000FEEDEB +:1009500000000010B18000040000001F0106000F1D +:1009600000000008050000FF000000180002000061 +:10097000000000002A00000000000010B1D40000B8 +:100980000000001091DE0000000000102053000065 +:1009900000000010001F0000000000002F80AA00CF +:1009A0000000000C29800001000000080254000E25 +:1009B000000000002C400000000000000F4000007C +:1009C0000000001800040000000000188000001162 +:1009D000000000188000001200000018800000389D +:1009E00000000018800000DF00000018800000DE1A +:1009F00000000018800000DD00000018800000DD0D +:100A0000000000188000000000000018800000F6C0 +:100A100000000018800000D90000001880000000CD +:100A200000000018800000FA000000188000014853 +:100A3000000000188000005A00000018800000C468 +:100A400000000018800000C500000018800000D2DF +:100A5000000000002A000000000000188000FFE4F1 +:100A6000000000002A0000000000000C29800000A7 +:100A7000000000188000FFE10000001800020000E4 +:100A8000000000000502000000000010B99A2C21AF +:100A900000000010205F0000000000002C1E00007D +:100AA000000000082C800006000000082D00000651 +:100AB000000000082D80010200000000000000007E +:100AC0000000001091DE0000000000000D61000039 +:100AD00000000018000A00000000000005020000ED +:100AE00000000010B99A2C1600000010205F0000D2 +:100AF0000000000009D80000000000002C1E0000CB +:100B0000000000082C8000B2000000082D00000A40 +:100B1000000000082D80010200000000000000001D +:100B20000000001091DE0000000000000D620000D7 +:100B3000000000002C13000000000018000A000054 +:100B4000000000000502000000000010B99A2C0906 +:100B500000000010205F0000000000002C1E0000BC +:100B6000000000082C800006000000082D00006A2C +:100B7000000000082D8001020000000000000000BD +:100B80000000001091DE0000000000000D7A00005F +:100B900000000018000A0000000000002A00000009 +:100BA0000000000822000001000000000D610000AC +:100BB0000000001021C2002400000010B1C6000295 +:100BC00000000010234200A2000000090B66FFFF96 +:100BD00000000010BA9A2C20000000000A640000F7 +:100BE000000000000AE50000000000000C0000000A +:100BF000000000000B800000000000080CC600127E +:100C0000000000188000FFD0000000080F800003E3 +:100C1000000000000000000000000010009F000025 +:100C2000000000082711001200000000669000007C +:100C300000000010B198000300000010001F000029 +:100C4000000000080F8000040000000822000003DC +:100C5000000000082C80000C000000082D00000C93 +:100C600000000010009F00000000001091C6000569 +:100C700000000010001F000000000010BA9A2C03B2 +:100C8000000000080F800004000000188000FFFD35 +:100C900000000000259600000000000C29800000E4 +:100CA0000000000032140000000000003295000037 +:100CB0000000000573662C000000000031E32E00E8 +:100CC000000000082D800010000000188000FF9632 +:100CD00000000000230000000000000925E6FFFFDF +:100CE000000000082200000B0000000C6952000008 +:100CF0000000000C29800000000000188000FF9018 +:100D0000000000002A000000000000082C800040C5 +:100D1000000000082D000020000000082D80011CAC +:100D200000000008220000010000001091DE000019 +:100D30000000000F42EA001000000010004F000405 +:100D400000000010B746920000000008024900129F +:100D500000000010B5840A00000000000D610000D2 +:100D600000000010BA663457000000088305001226 +:100D700000000010004F00020000000003490000C6 +:100D80000000000183068C000000000083C60C00F8 +:100D900000000010B1870013000000000B6E00007F +:100DA000000000090569FFFF00000010918A0002A1 +:100DB0000000000834E9FFFF000000188000FF7504 +:100DC000000000010569140000000010918A000273 +:100DD00000000008B4E9000100000010BAE92C4846 +:100DE0000000000086692C000000000002000000E6 +:100DF0000000000902EAFFFF00000010000C0002E2 +:100E00000000000002040A000000000F460C000170 +:100E10000000000F0285000100000010918C01FC11 +:100E200000000010B7040E3F000000000D6100003C +:100E3000000000000A640000000000000AE5000055 +:100E4000000000090B66FFFF000000000C0000001E +:100E5000000000000B800000000000080C8600125B +:100E6000000000080F8000030000000C2952000061 +:100E700000000010009F0000000000082711001271 +:100E80000000000066900000000000002306000043 +:100E900000000010B198000500000010001F0000C5 +:100EA000000000080F8000040000000000000000A7 +:100EB00000000010001F00000000000032140000BD +:100EC00000000000329500000000000031E32E0019 +:100ED0000000000573662C0000000000259600004D +:100EE00000000010B18700160000000C29800000EF +:100EF0000000000F0F6B0007000000000D690000EC +:100F0000000000000A6C0000000000000AED000074 +:100F1000000000000B6E0000000000000B800000CD +:100F2000000000000C870000000000080F80000394 +:100F300000000010205300000000000C6952000166 +:100F400000000010001F00000000000022C58C00FF +:100F500000000000231B000000000000271100001B +:100F6000000000002690000000000010B8170E03DB +:100F70000000000C29800000000000188000FFF62F +:100F800000000010B1980002000000080F8000046B +:100F9000000000082200001A000000082C80000C4D +:100FA000000000082D00000C000000082D8000103B +:100FB00000000010001F0000000000000D6E000087 +:100FC00000000003E7CF34000000000C298000007F +:100FD0000000001091DE000000000010B187000743 +:100FE00000000000361400000000000036950000EC +:100FF0000000000037160000000000082C800050A0 +:10100000000000082D000030000000082D80000CBA +:10101000000000188000FF2D0000000023000000E9 +:101020000000000925E6FFFF000000000B6E000035 +:1010300000000003E7CF2C00000000082200001B86 +:101040000000000C695200000000000C2980000024 +:10105000000000188000FF25000000002A000000AA +:10106000000000188000FF23000000002A0000009C +:101070000000000C298000000000001091DE00003C +:10108000000000082C80001A000000082D00001A43 +:101090000000000573660000000000082D800002BB +:1010A00000000000318000000000001091DE000010 +:1010B000000000082C80000C000000082D00000C2F +:1010C000000000082D800004000000188000FF16BA +:1010D0000000001880000000000000188000FF14CD +:1010E000000000002A00000000000010001F0000A7 +:1010F000000000000F008000000000080F800007C3 +:10110000000000188000001B00000000280A0000FA +:101110000000000005020000000000082200000995 +:1011200000000000290000000000000F65680010AA +:1011300000000000248A000000000003F66C940008 +:1011400000000010B972A0040000000C73E7001941 +:101150000000000C21420004000000003CF80000E8 +:101160000000000C29800000000000102053000047 +:1011700000000008220000080000000C614200048A +:1011800000000018000A0000000000000502000036 +:101190000000000C6142000000000010014200034A +:1011A0000000000C33E7001D0000000C614200024B +:1011B00000000018000A0000000000002A000000E3 +:1011C00000000010001F00000000000F0F47000784 +:1011D000000000080F8000080000000C29800000BB +:1011E00000000010009F0000000000188000FEF2C8 +:1011F0000000000033510000000000002A00000041 +:1012000000000010B1C600230000000F0F500007BF +:10121000000000000A600000000000000AE1000079 +:101220000000000F4B620008000000090B1600FFD1 +:101230000000000F4C620010000000000D62000072 +:10124000000000090D1A00FF000000100750000305 +:101250000000000C0D1A00080000000C0B1600081E +:10126000000000000CC60000000000000B80000021 +:101270000000000006980000000000080F80000336 +:101280000000001006C200040000000C290000024B +:1012900000000010264200020000000C295200034A +:1012A000000000082200000100000010009F000064 +:1012B00000000000231B00000000000027111A009E +:1012C00000000000669000000000000C29520000A1 +:1012D00000000010B19732090000000C29800000C6 +:1012E00000000000069800000000001020530000DD +:1012F0000000000C295200030000000022C58C00F1 +:1013000000000010001F0000000000080F80000314 +:10131000000000188000FFF300000010B1C80013A7 +:1013200000000010B1C600030000000C298000007E +:1013300000000010205300000000000C29520000A3 +:101340000000000C295200030000001006C2000239 +:101350000000000C295200020000000022C58C0091 +:1013600000000000276500000000000026E40000E7 +:10137000000000082200001600000010B1C60003A3 +:10138000000000002348000000000010B1800005AC +:1013900000000000234800000000000C298000002D +:1013A0000000000F0F50000700000018800000121E +:1013B00000000008220000160000000C2980000038 +:1013C0000000000030140000000000003095000014 +:1013D0000000001007500003000000090B1600FF7A +:1013E000000000090D1A00FF0000000F3116000870 +:1013F000000000003162340000000003F1623000A0 +:1014000000000010205F0000000000002C510000D0 +:10141000000000092CD1007F000000082CD900003A +:10142000000000082D000000000000082D80000CC6 +:1014300000000000000000000000001091DE00002D +:101440000000001005C20004000000080F80000723 +:10145000000000003300000000000010009F0000AA +:10146000000000188000FEA3000000002A00000019 +:101470000000000F0F50000700000010B1C6002D43 +:101480000000000F4742000800000009070E000F8F +:1014900000000008070E000800000010001F0000F8 +:1014A00000000008090000010000000709121C00EC +:1014B00000000003CBCA9200000000000B97A200BE +:1014C0000000000742171C00000000000B04000091 +:1014D0000000000F0A840003000000000A959C0031 +:1014E000000000004A009A0000000008821200017B +:1014F000000000010C170800000000000C978C0091 +:101500000000000002180000000000080D00FFFFAE +:10151000000000080F8000060000000C29000000F9 +:101520000000001006C200040000000C2952000256 +:1015300000000010264200020000000C29520003A7 +:10154000000000082200000100000010009F0000C1 +:1015500000000010B197320C00000000231B0000B7 +:101560000000000027110800000000006690000045 +:101570000000000C2980000000000000021800009C +:1015800000000010205300000000000C295200034E +:101590000000000022C5360000000010001F0000FF +:1015A000000000080F800006000000188000FFF413 +:1015B00000000000231B00000000000027110800AD +:1015C000000000006690000000000010B1C8000B91 +:1015D0000000000C298000000000001020530000D3 +:1015E0000000000C295200000000000C29520003EA +:1015F0000000001006C200020000000C2952000288 +:101600000000000022C58C000000000027650000DB +:101610000000000026E40000000000002348000055 +:1016200000000008220000170000000C29800000C4 +:1016300000000010001F0000000000188000FE687D +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex deleted file mode 100644 index fe59d16b594e882ee8b45891c26e95ccdf6acb20..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-rv2p-09-5.0.0.j10.fw.ihex +++ /dev/null @@ -1,462 +0,0 @@ -:100000000000000000000E08000000580000000979 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000DD800000E60000000050000000068 -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F05030300000000080500FFFF5B -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000000050000000000000C2F8000019F -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E0000200000008AC00000108 -:1000C00000000010203F006B00000010213F0003E3 -:1000D0000000001020BF003A000000188000FFFD63 -:1000E00000000010B1B8B0150000000B2FDF0002B7 -:1000F0000000000003D80000000000002C380000C1 -:10010000000000082C800000000000082D00000006 -:100110000000001091D400000000000806005555B2 -:10012000000000188000007C000000082D80011CE9 -:1001300000000008020000010000001091DE000035 -:100140000000000F42E0001C0000001091840A161D -:1001500000000018800000830000000C29800002CD -:100160000000000C1F800002000000002ADF0000D9 -:10017000000000082A00000F000000000500000039 -:10018000000000188000FFE60000000802000001E7 -:100190000000000F42E0001C0000001091840A18CB -:1001A000000000082C800006000000082D0000065A -:1001B0000000001091D40000000000082D8001060E -:1001C0000000001880000072000000188000FFF19D -:1001D00000000008B1000001000000082C80010CA4 -:1001E000000000082D000008000000082D8000011C -:1001F000000000188000006C0000000B2FDF0002E0 -:100200000000000C1F800002000000002C0700000E -:100210000000001091DE00000000000805005555A8 -:10022000000000188000FFD20000000B2FDF00024A -:100230000000000C1F800000000000002C070000E0 -:100240000000001091DE0000000000080500555578 -:10025000000000188000FFCC0000000C1F8000028E -:100260000000000805005555000000188000FFC977 -:100270000000000C298000020000000C1F8000021A -:10028000000000002ADF0000000000082A0000052E -:100290000000000805005555000000188000FFC34D -:1002A000000000080224004A0000001800040000BA -:1002B000000000188000001C000000188000001ED4 -:1002C000000000188000006500000018800000BCDD -:1002D00000000018800000BB000000188000000033 -:1002E00000000018800000000000001880000000DE -:1002F00000000018800000000000001880000000CE -:1003000000000018800000000000001880000000BD -:1003100000000018800000000000001880000107A5 -:10032000000000188000000000000018800000009D -:100330000000001880000015000000188000001B5D -:10034000000000188000000000000018800000D2AB -:10035000000000188000002F000000188000010736 -:10036000000000188000013200000018800000FD2D -:100370000000001880000156000000188000004EA8 -:100380000000001880000000000000188000008FAE -:100390000000000C1F8000010000000005000000AC -:1003A000000000188000FFA20000001091D400009F -:1003B0000000000C298000010000000C1F800001DB -:1003C000000000082A0000020000000005000000F4 -:1003D000000000188000FF9C0000001091D4000075 -:1003E0000000000C298000010000000C1F800001AB -:1003F0000000000029420000000000082A0000025E -:100400000000000005000000000000188000FF95BB -:10041000000000188000FF9400000010B1BCB00A7A -:100420000000000B2FDF00020000000003D80000D6 -:10043000000000002C3C00000000001091D40000DF -:100440000000000806005555000000188000001745 -:1004500000000018800000CB000000102C6201BAE0 -:100460000000001880000006000000082C80010D2C -:10047000000000082D0000090000001091D40000C9 -:10048000000000082D8001070000001880000024F3 -:100490000000000C298000000000000C1F800000FC -:1004A0000000001091DE0000000000002ADF0000C4 -:1004B000000000082A00000600000008050055554D -:1004C000000000188000FF7E0000001091D40000A2 -:1004D0000000000C298000010000000C1F800001BA -:1004E000000000082A00000B0000000005000000CA -:1004F000000000188000FF780000001800020000D3 -:10050000000000000682000000000010B18A000810 -:1005100000000010B18C14070000000B050AFFFF5B -:1005200000000010B18A000300000000860A1800D5 -:1005300000000010918C0000000000082A0000015B -:100540000000001091D4000000000018000D000011 -:1005500000000000050200000000001091DE000015 -:1005600000000018000A00000000000006820000E1 -:100570000000001091DE000000000010BEE1000548 -:10058000000000188000FF5F0000000105611400FA -:1005900000000010918A000200000008B0E1000194 -:1005A00000000018000D000000000000068200009E -:1005B0000000001091DE000000000010BEE2000507 -:1005C000000000188000FF570000000105621400C1 -:1005D00000000010918A000200000008B1620001D2 -:1005E00000000018000D000000000010B1A0B013C2 -:1005F0000000000B2FDF0002000000002C20000094 -:10060000000000082C800000000000082D00000001 -:100610000000001091D400000000000806005555AD -:10062000000000188000FFDC000000082D80011C85 -:1006300000000010001F0000000000188000FFE60E -:100640000000000F476000080000000F060E0001C8 -:10065000000000000F580000000000000A640000C5 -:10066000000000000AE50000000000090B66FFFF23 -:10067000000000000D610000000000188000001361 -:100680000000000F476000080000000B2FDF000291 -:10069000000000082C800000000000082D00000071 -:1006A0000000001091D40000000000082D80011C03 -:1006B0000000000F060E000100000010001F0000E7 -:1006C000000000000F580000000000188000FFD458 -:1006D000000000000A640000000000000AE50000BD -:1006E000000000090B66FFFF000000000D61000024 -:1006F00000000000026200000000000B2FDF00027B -:10070000000000003104000000000000309A0000EA -:10071000000000090560000F00000010B18A000B06 -:100720000000000005634C0000000008050A0012EC -:1007300000000010B9621403000000000300000074 -:100740000000001880000006000000188000FF2450 -:1007500000000010B60614040000000803060001A3 -:10076000000000082A000001000000188000FF2996 -:10077000000000000C961800000000090C99FFFF13 -:1007800000000004CC99340000000010B196320241 -:10079000000000080F8000000000000C298000010C -:1007A0000000000C295200010000000C295200003A -:1007B000000000080200000E000000080280001A7D -:1007C00000000010B1C40A0200000008020000038B -:1007D00000000008220000010000000C1F80000142 -:1007E000000000002ADF0000000000002A000800CE -:1007F0000000000805005555000000188000FF1794 -:100800000000000B2FDF00020000001091D4000058 -:10081000000000082A000001000000002C20000059 -:100820000000001091D40000000000082C8000009F -:10083000000000082D000000000000082D80011CB1 -:10084000000000188000FFA2000000082C800006B5 -:10085000000000082D0000060000000030800000AD -:100860000000000031000000000000082D8000069C -:100870000000000C298000010000000C1F80000116 -:100880000000001091DE0000000000002ADF0000E0 -:10089000000000082A000010000000000500000011 -:1008A000000000188000FF020000001091A0B009B5 -:1008B000000000082C80010D000000082D00000938 -:1008C0000000001091D40000000000082D800107F6 -:1008D000000000188000FF9B00000018800000103E -:1008E00000000008AC000001000000188000000BB0 -:1008F000000000000380B0000000000B2FDF0002AA -:10090000000000002C0040000000001091D4000006 -:100910000000000806005555000000188000FF7D0B -:100920000000001880000031000000188000000660 -:100930000000000B2FDF0002000000002C000E0062 -:10094000000000082A0000070000000805005555B7 -:10095000000000188000FEEC00000000068200008D -:100960000000000C298000010000000C1F80000125 -:10097000000000100CE70007000000090562FFFFFF -:1009800000000010BA6C1405000000002ADF00000F -:100990000000000021000000000000082A000005FF -:1009A0000000001091D40000000000082C80010C11 -:1009B000000000082D0000080000000C3162001843 -:1009C000000000082D800001000000188000FF7169 -:1009D00000000018000D000000000010B1A0B00ED3 -:1009E0000000000B2FDF00020000000003D8000011 -:1009F000000000002C2000000000001091D4000036 -:100A00000000001880000015000000102C62000299 -:100A1000000000188000000C0000000B2FDF000217 -:100A2000000000002C0700000000000C1F800001E7 -:100A30000000001091DE0000000000080500FFFF2C -:100A4000000000188000FECE000000082C80010D80 -:100A5000000000082D0000090000001091D40000E3 -:100A6000000000082D800107000000188000FF68CA -:100A70000000000C298000010000000C1F80000114 -:100A80000000001091DE0000000000002ADF0000DE -:100A9000000000082A00000A000000000500000015 -:100AA000000000188000FEC2000000000682000066 -:100AB000000000082C80010C000000082D00000838 -:100AC000000000082D80013400000000000000003C -:100AD00000000010205F0000000000082C80014092 -:100AE000000000082D00003C000000082D800124BB -:100AF00000000000000000000000001091DE000077 -:100B0000000000082C800080000000082D0000007C -:100B1000000000082D80010500000010BEE2000565 -:100B2000000000188000FEAB000000010562140008 -:100B300000000010918A000200000008B16200016C -:100B40000000001091DE000000000018000D000001 -:100B50000000001091D40000000000080600AAAABE -:100B6000000000188000FF340000000C2980000104 -:100B70000000000C1F800001000000082A0000098E -:100B8000000000080500AAAA000000188000FEA5C9 -:100B90000000001091D40000000000080600555528 -:100BA000000000188000FF2C0000001091A03C0203 -:100BB00000000010B1E662070000000B2FDF00020A -:100BC000000000002C310000000000092CB1007F63 -:100BD000000000082CD90000000000082D000000D3 -:100BE000000000082D80010D00000010B1A80006D3 -:100BF00000000010205F0000000000002C2000001A -:100C0000000000002CA70000000000082D000010CC -:100C1000000000082D800108000000188000FF2758 -:100C200000000010B1A6001000000010001F00001E -:100C30000000000F0F300007000000000A600000F5 -:100C4000000000000AE100000000000F4B620008F5 -:100C5000000000090B1600FF000000000D620000FC -:100C6000000000090D1A00FF00000010073000030B -:100C70000000000C0D1A00080000000C0B16000804 -:100C80000000000F4CE30018000000000C992C003D -:100C900000000004CC993400000000080F80000020 -:100CA0000000000C2980000100000000333100002A -:100CB0000000000822000016000000002ADF0000EB -:100CC000000000082A00000C00000010009F000037 -:100CD000000000000F2000000000000C1F80000139 -:100CE0000000000805005555000000188000FE793E -:100CF0000000001091D40000000000080600AAAA1D -:100D0000000000188000FF000000000F47220008CC -:100D100000000009070E000F00000008070E000881 -:100D200000000008028000010000000702851C008E -:100D300000000008828500010000000002854C00D0 -:100D40000000000742851C0000000003C3AA5200F7 -:100D50000000000003B10E00000000074B071C005C -:100D60000000000F0F3000070000000F0A9600037C -:100D7000000000000A955C00000000004A005A00D4 -:100D8000000000000C960A00000000090C99FFFF0B -:100D9000000000080D00FFFF00000010B1963202B5 -:100DA000000000080F80000500000010B1A8000836 -:100DB00000000010205F00000000000B2FDF000289 -:100DC000000000002C200000000000002CA7000004 -:100DD000000000082D000010000000082D80010810 -:100DE000000000188000FEEE0000000C29800001C9 -:100DF00000000010001F00000000000C1F80000118 -:100E0000000000002ADF0000000000082A00000D9A -:100E1000000000080500AAAA000000188000FE5388 -:100E20000000001091D40000000000080600555595 -:100E3000000000188000FEDA0000000C298000018C -:100E40000000000C1F800001000000082A000007BD -:100E50000000000805005555000000188000FE4BFA -:100E600000000010B18000040000001F0503030013 -:100E700000000008050000FF00000018000200004C -:100E8000000000002A00000000000010B1D40000A3 -:100E90000000001091DE0000000000102053000050 -:100EA00000000010001F0000000000002F80AA00BA -:100EB0000000000C29800001000000080254000E10 -:100EC000000000002C400000000000092952003FF3 -:100ED000000000180004000000000018800000104E -:100EE0000000001880000011000000188000003988 -:100EF00000000018800000FD00000018800000FCC9 -:100F000000000018800000FB00000018800000FBBB -:100F1000000000188000000000000018800001138D -:100F200000000018800000F7000000188000000B8F -:100F30000000001880000117000000188000016503 -:100F4000000000188000006300000018800000CE40 -:100F500000000018800000DE000000002A000000F1 -:100F6000000000188000FFE5000000002A000000DB -:100F70000000000C29800000000000188000FFE243 -:100F8000000000002A000000000000188000FFE0C0 -:100F90000000001800020000000000000502000030 -:100FA000000000109196342100000010205F000026 -:100FB000000000002C1E0000000000082C8000062D -:100FC000000000082D000006000000082D8001022E -:100FD00000000000000000000000001091DE000092 -:100FE000000000000D61000000000018000A000071 -:100FF0000000000005020000000000109196341669 -:1010000000000010205F00000000000009D8000070 -:10101000000000002C1E0000000000082C80010EC3 -:10102000000000082D00000A000000082D800102C9 -:1010300000000000000000000000001091DE000031 -:10104000000000000D620000000000002C130000F2 -:1010500000000018000A0000000000000502000067 -:10106000000000109196340900000010205F00007D -:10107000000000002C1E0000000000082C8000066C -:10108000000000082D00006A000000082D80010209 -:1010900000000000000000000000001091DE0000D1 -:1010A000000000000D7A000000000018000A000097 -:1010B000000000002A000000000000000D61000098 -:1010C000000000000362000000000010234200C185 -:1010D0000000000002638C000000000026460000B3 -:1010E000000000080204001200000010B9060827E2 -:1010F000000000000F580000000000000A6400001B -:10110000000000000AE50000000000090B66FFFF78 -:10111000000000000C000000000000000B80000038 -:10112000000000080CC60012000000188000FFCE6E -:10113000000000080F800003000000000000000015 -:1011400000000010009F000000000008271100129E -:10115000000000006690000000000008A31B0012C1 -:1011600000000010B198000300000010001F0000F4 -:10117000000000080F8000040000000822000003A7 -:10118000000000082C80000C000000082D00000C5E -:1011900000000010009F00000000000025960000E5 -:1011A0000000000C2980000000000000066600001E -:1011B0000000000086611800000000090260000FB6 -:1011C0000000000F0204000200000010B60C080529 -:1011D0000000000C1FBF0000000000102866000384 -:1011E00000000008078F00010000000C33660010AB -:1011F00000000000321400000000000032950000E2 -:101200000000000573662C000000000031E32E0092 -:10121000000000082D800010000000188000FF8EE4 -:1012200000000000230000000000000925E6FFFF89 -:10123000000000082200000B0000000C69520000B2 -:101240000000000C298000000000001028660075D6 -:10125000000000188000FF87000000002A00000046 -:10126000000000082C800040000000082D00002035 -:10127000000000082D80011C00000000000000009C -:101280000000001091DE00000000000F42EA001094 -:1012900000000010004F000400000010B74692004C -:1012A000000000080249001200000010B5840A0086 -:1012B000000000000D61000000000010BA66345705 -:1012C000000000088305001200000010004F00021B -:1012D00000000000034900000000000183068C00AC -:1012E0000000000083C60C0000000010B187001150 -:1012F000000000000B6E000000000010BEE90005B9 -:10130000000000188000FF6E000000010569140055 -:1013100000000010918A000200000008B4E90001FA -:1013200000000010B1E92C4A0000000086692C0082 -:1013300000000000020000000000000902EAFFFFB8 -:1013400000000010000C00020000000002040A006F -:101350000000000F460C00010000000F0285000194 -:1013600000000010918C01FC00000010B7040E4139 -:10137000000000000F400000000000000D610000B0 -:10138000000000000A640000000000000AE5000000 -:10139000000000090B66FFFF000000000C000000C9 -:1013A000000000000B800000000000080C86001206 -:1013B000000000080F8000030000000C295200000C -:1013C00000000010009F000000000008271100121C -:1013D00000000000669000000000000026460000AB -:1013E000000000002306000000000010B198000576 -:1013F00000000010001F0000000000080F80000423 -:10140000000000000000000000000010001F0000AD -:1014100000000000321400000000000032950000BF -:101420000000000031E32E000000000573662C0070 -:10143000000000002596000000000010B187001693 -:101440000000000C298000000000000F0F6B000757 -:10145000000000000D690000000000000A6C0000A0 -:10146000000000000AED0000000000000B6E00000C -:10147000000000000B800000000000000C8700004E -:10148000000000080F80000300000010205300003F -:101490000000000C6952000100000010001F000055 -:1014A0000000000022C58C0000000000231B00008B -:1014B000000000002711000000000000269000003E -:1014C00000000010B8170E030000000C2980000077 -:1014D000000000188000FFF600000010B198000224 -:1014E000000000080F800004000000082200001A1D -:1014F000000000082C80000C000000082D00000CEB -:10150000000000082D80001000000010001F0000E7 -:10151000000000000D6E000000000003E7CF340063 -:101520000000000C298000000000001091DE000087 -:1015300000000010B1870007000000003614000012 -:101540000000000036950000000000003716000083 -:10155000000000082C800050000000082D00003022 -:10156000000000082D80000C000000188000FF24FF -:1015700000000000264600000000000023000000DC -:101580000000000925E6FFFF000000000B6E0000D0 -:1015900000000003E7CF2C00000000082200001B21 -:1015A0000000000C695200000000000C29800000BF -:1015B000000000188000FF1B000000002A0000004F -:1015C000000000100866000500000000066600002C -:1015D000000000008661180000000009026000F0B1 -:1015E00000000010B60C0802000000188000FF1474 -:1015F000000000000682000000000010B18F000013 -:1016000000000008878F00010000000C73660010C6 -:10161000000000082C800018000000082D000018B1 -:10162000000000082D8000020000000C5FBF0000D9 -:101630000000001091DE000000000018000D000006 -:10164000000000002A00000000000010286601F5DC -:10165000000000082C800003000000082D0000039B -:10166000000000093060FFF0000000082D8000013C -:101670000000000C298000000000001091DE000036 -:10168000000000082C80001A000000082D00001A3D -:101690000000000573660000000000082D800002B5 -:1016A00000000000318000000000001091DE00000A -:1016B000000000082C80000C000000082D00000C29 -:1016C000000000082D800004000000188000FEF8D3 -:1016D0000000001800020000000000188000FEF664 -:1016E000000000002A00000000000010001F0000A1 -:1016F000000000000F008000000000080F800007BD -:10170000000000188000001A00000000280A0000F5 -:10171000000000000502000000000008220000098F -:1017200000000000290000000000000F65680010A4 -:1017300000000003F66C940000000010B972A004D1 -:101740000000000C73E700190000000C21420004A7 -:10175000000000003CF800000000000C29800000A0 -:1017600000000010205300000000000822000008C4 -:101770000000000C6142000400000018000A000094 -:1017800000000000050200000000000C61420000A3 -:1017900000000010014200030000000C33E7001DB0 -:1017A0000000000C6142000200000018000A000066 -:1017B000000000002A00000000000010001F0000D0 -:1017C0000000000F0F470007000000080F8000080E -:1017D0000000000C2980000000000010009F0000A5 -:1017E000000000188000FED500000000335100000A -:1017F000000000002A00000000000010B1C6002315 -:101800000000000F0F500007000000000A600000F9 -:10181000000000000AE100000000000F4B62000819 -:10182000000000090B1600FF0000000F4C620010C2 -:10183000000000000D620000000000090D1A00FF0A -:1018400000000010075000030000000C0D1A0008F3 -:101850000000000C0B160008000000000CC6000081 -:10186000000000000B80000000000000069800004F -:10187000000000080F8000030000001006C20004F2 -:101880000000000C290000020000001026420002A7 -:101890000000000C29520003000000082200000193 -:1018A00000000010009F000000000000231B00004B -:1018B0000000000027111A000000000066900000E0 -:1018C0000000000C2952000000000010B1973209FE -:1018D0000000000C298000000000000006980000B5 -:1018E00000000010205300000000000C29520003EB -:1018F0000000000022C58C0000000010001F000046 -:10190000000000080F800003000000188000FFF3B3 -:1019100000000010B1C8001300000010B1C60003A1 -:101920000000000C2980000000000010205300007F -:101930000000000C295200000000000C2952000396 -:101940000000001006C200020000000C2952000234 -:101950000000000022C58C00000000002765000088 -:101960000000000026E4000000000008220000162D -:1019700000000010B1C60003000000002348000072 -:1019800000000010B18000050000000023480000A6 -:101990000000000C298000000000000F0F5000071D -:1019A000000000188000001200000008220000164D -:1019B0000000000C2980000000000000301400002E -:1019C00000000000309500000000001007500003E8 -:1019D000000000090B1600FF000000090D1A00FFAF -:1019E0000000000F311600080000000031623400D2 -:1019F00000000003F162300000000010205F0000D2 -:101A0000000000002C510000000000092CD1007FD4 -:101A1000000000082CD90000000000082D00000084 -:101A2000000000082D80000C0000000000000000F5 -:101A30000000001091DE00000000001005C200044C -:101A4000000000080F8000070000000033000000C5 -:101A500000000010009F0000000000188000FE86BB -:101A6000000000002A0000000000000F0F500007D7 -:101A700000000010B1C6002D0000000F4742000812 -:101A800000000009070E000F00000008070E000804 -:101A900000000010001F0000000000080900000105 -:101AA0000000000709121C0000000003CBCA9200CE -:101AB000000000000B97A2000000000742171C0066 -:101AC000000000000B0400000000000F0A84000367 -:101AD000000000000A959C00000000004A009A00E7 -:101AE0000000000882120001000000010C1708002D -:101AF000000000000C978C0000000000021800009D -:101B0000000000080D00FFFF000000080F80000625 -:101B10000000000C290000000000001006C20004B4 -:101B20000000000C295200020000001026420002B2 -:101B30000000000C295200030000000822000001F0 -:101B400000000010009F000000000010B197320C50 -:101B500000000000231B0000000000002711080007 -:101B600000000000669000000000000C29800000CA -:101B700000000000021800000000001020530000C8 -:101B80000000000C295200030000000022C53600AE -:101B900000000010001F0000000000080F80000679 -:101BA000000000188000FFF400000000231B00006C -:101BB00000000000271108000000000066900000EF -:101BC00000000010B1C8000B0000000C29800000CC -:101BD00000000010205300000000000C29520000FB -:101BE0000000000C295200030000001006C2000291 -:101BF0000000000C295200020000000022C58C00E9 -:101C000000000000276500000000000026E400003E -:101C10000000000023480000000000082200001718 -:101C20000000000C2980000000000010001F0000D0 -:081C3000000000188000FE4BCB -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex b/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex new file mode 100644 index 0000000000000000000000000000000000000000..435203d6430567293e662f8a1a31976d204530de --- /dev/null +++ b/firmware/bnx2/bnx2-rv2p-09-6.0.17.fw.ihex @@ -0,0 +1,392 @@ +:1000000000000000000008F800000058000000098F +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000000E88000009500000000500000000CC +:1000400000000000000000000000000000000000B0 +:080050000000000000000000A8 +:0800580000000010B180000659 +:100060000000001F05060011000000080500FFFF4A +:10007000000000180002000000000008050000FF5A +:10008000000000180002000000000008AC000001A1 +:1000900000000008078000000000000C2F80000115 +:1000A000000000002B000000000000002B8000007A +:1000B0000000001091E1000200000008AC00000107 +:1000C00000000010203F003B00000010213F000313 +:1000D0000000001020BF0015000000188000FFFD88 +:1000E0000000000C1F800002000000188000FFF9D3 +:1000F00000000008B1000001000000082C80010C85 +:10010000000000082D000008000000082D800001FC +:10011000000000188000003C0000000B2FDF0002F0 +:100120000000000C1F800002000000002C070000EF +:100130000000001091DE0000000000188000FFEFBA +:100140000000000B2FDF00020000000C1F800000E9 +:10015000000000002C0700000000001091DE0000ED +:10016000000000188000FFEA0000000C1F80000261 +:10017000000000188000FFE80000000802240025AD +:1001800000000018000400000000001880000000BB +:10019000000000188000001B0000001880000042D2 +:1001A000000000188000000000000018800000001F +:1001B000000000188000000000000018800000000F +:1001C00000000018800000000000001880000000FF +:1001D00000000018800000000000001880000000EF +:1001E00000000018800000000000001880000000DF +:1001F000000000188000008E000000188000000041 +:1002000000000018800000000000001880000000BE +:1002100000000018800000000000001880000000AE +:10022000000000188000000000000018800000009E +:10023000000000188000008D00000018800000B74A +:10024000000000188000008400000018800000DA20 +:10025000000000188000002B000000188000000043 +:10026000000000188000006B0000001091D4000016 +:100270000000000C298000010000000C1F8000011C +:10028000000000082A0000020000000807800000AB +:10029000000000188000FFC4000000080380010077 +:1002A00000000010B73C0E000000001880000000A5 +:1002B000000000180002000000000000068200009C +:1002C00000000010B18F000400000010B18F140373 +:1002D000000000082A0000010000001091D4000076 +:1002E000000000000780140000000018000D00004E +:1002F00000000000050200000000001091DE000078 +:1003000000000018000A0000000000000682000043 +:100310000000001091DE0000000000090561FFFFF1 +:1003200000000010918A00020000000830E1FFFF89 +:10033000000000188000FFA9000000010561140002 +:1003400000000010918A000200000008B0E10001E6 +:1003500000000018000D00000000000006820000F0 +:100360000000001091DE0000000000090562FFFFA0 +:1003700000000010918A0002000000083162FFFFB7 +:10038000000000188000FF9F0000000105621400BB +:1003900000000010918A000200000008B162000114 +:1003A00000000018000D000000000010B1A0B01304 +:1003B0000000000B2FDF0002000000002C200000D6 +:1003C000000000082C800000000000082D00000044 +:1003D0000000001091D40000000000080500005546 +:1003E000000000188000FFDB000000082D80011CC9 +:1003F00000000010001F0000000000188000FFE255 +:100400000000000F476000080000000F060E00010A +:10041000000000000F580000000000000A64000007 +:10042000000000000AE50000000000090B66FFFF65 +:10043000000000000D6100000000001880000015A1 +:100440000000000F476000080000000B2FDF0002D3 +:10045000000000082C800000000000082D000000B3 +:100460000000001091D40000000000082D80011C45 +:100470000000000F060E000100000010001F000029 +:10048000000000000F580000000000188000FFD09E +:10049000000000000A640000000000000AE50000FF +:1004A000000000090B66FFFF000000000D61000066 +:1004B00000000000026200000000000002E00000F6 +:1004C0000000000B2FDF00020000000030050000DC +:1004D000000000003104000000000000309A00001D +:1004E000000000100060000A00000008051600016E +:1004F00000000010BA9A140300000000030000007E +:100500000000001880000006000000188000FF6C4A +:1005100000000010B60614040000000803060001E5 +:10052000000000082A000001000000188000FF7190 +:10053000000000000C961800000000090C99FFFF55 +:1005400000000004CC99340000000010BA992C027D +:10055000000000080F8000000000000C298000014E +:100560000000000C295200010000000C295200007C +:100570000000000822800002000000080200000EB7 +:10058000000000080280001A00000010B1C40A0236 +:1005900000000008020000030000000C1F800001A2 +:1005A000000000002ADF0000000000002A00080010 +:1005B000000000188000FF600000000B2FDF000229 +:1005C0000000001091D40000000000082A00000183 +:1005D000000000002C2000000000001091D400005A +:1005E000000000082C800000000000082D00000022 +:1005F000000000082D80011C000000188000FF9FF3 +:10060000000000082C800006000000082D000006F5 +:1006100000000000308000000000000031000000F9 +:10062000000000082D8000060000000C2980000159 +:100630000000000C1F8000010000001091DE00008F +:10064000000000002ADF0000000000082A0000105F +:100650000000000807800000000000188000FF4B29 +:100660000000001091D4000000000008050000AA5E +:10067000000000188000FF890000000C29800001A4 +:100680000000000C1F800001000000082A00000983 +:10069000000000188000FF440000001091D400000A +:1006A0000000000805000055000000188000FF82CF +:1006B0000000001091A0B00200000010B1E6620737 +:1006C0000000000B2FDF0002000000002C310000B2 +:1006D000000000092CB1007F000000082CD90000A8 +:1006E000000000082D000000000000082D80010D12 +:1006F00000000010B1A8000600000010205F0000FC +:10070000000000002C200000000000002CA70000CA +:10071000000000082D000010000000082D800108D6 +:10072000000000188000FF7A00000010B1A6001041 +:1007300000000010001F00000000000F0F30000735 +:10074000000000000A600000000000000AE1000054 +:100750000000000F4B620008000000090B1600FFAC +:10076000000000000D620000000000090D1A00FFEB +:1007700000000010073000030000000C0D1A0008F4 +:100780000000000C0B1600080000000F4CE30018DE +:10079000000000000C992C0000000004CC993400EB +:1007A000000000080F8000000000000C29800001FC +:1007B0000000000033310000000000082200001695 +:1007C000000000002ADF0000000000082A00000CE2 +:1007D00000000010009F0000000000002C2000001E +:1007E0000000000C1F800001000000188000FF19AD +:1007F0000000001091D4000000000008050000AACD +:10080000000000188000FF570000000F472200087A +:1008100000000009070E000F00000008070E000886 +:1008200000000008028000010000000702851C0093 +:1008300000000008828500010000000002854C00D5 +:100840000000000742851C0000000003C3AA5200FC +:100850000000000003B10E00000000074B071C0061 +:100860000000000F0F3000070000000F0A96000381 +:10087000000000000A955C00000000004A005A00D9 +:10088000000000000C960A00000000090C99FFFF10 +:10089000000000080D00FFFF00000010BA992C02B4 +:1008A000000000080F80000500000010B1A800083B +:1008B00000000010205F00000000000B2FDF00028E +:1008C000000000002C200000000000002CA7000009 +:1008D000000000082D000010000000082D80010815 +:1008E000000000188000FF420000000C2980000179 +:1008F00000000010001F00000000000C1F8000011D +:10090000000000002ADF0000000000082A00000D9F +:10091000000000188000FEF40000001091D40000D8 +:100920000000000805000055000000188000FF329C +:100930000000000C298000010000000C1F80000155 +:10094000000000082A000007000000188000FEEDEB +:1009500000000010B18000040000001F0506001117 +:1009600000000008050000FF000000180002000061 +:10097000000000002A00000000000010B1D40000B8 +:100980000000001091DE0000000000102053000065 +:1009900000000010001F0000000000002F80AA00CF +:1009A0000000000C29800001000000080254000F24 +:1009B000000000002C400000000000000F4000007C +:1009C000000000092952003F000000180004000048 +:1009D00000000018800000110000001880000012C4 +:1009E000000000188000003800000018800001118D +:1009F0000000001880000110000000188000010FA6 +:100A0000000000188000010F0000001880000000A6 +:100A10000000001880000128000000188000010B71 +:100A20000000001880000000000000188000012C69 +:100A3000000000188000017A000000188000005AB1 +:100A400000000018800000C400000018800000C5ED +:100A50000000001880000104000000002A000000CF +:100A6000000000188000FFE3000000002A000000E2 +:100A70000000000C29800000000000188000FFE04A +:100A80000000001800020000000000000502000045 +:100A900000000010B99A2C2100000010205F000017 +:100AA000000000002C1E0000000000082C80000642 +:100AB000000000082D000006000000082D80010243 +:100AC00000000000000000000000001091DE0000A7 +:100AD000000000000D61000000000018000A000086 +:100AE000000000000502000000000010B99A2C165A +:100AF00000000010205F00000000000009D8000086 +:100B0000000000002C1E0000000000082C80010ED8 +:100B1000000000082D00000A000000082D800102DE +:100B200000000000000000000000001091DE000046 +:100B3000000000000D620000000000002C13000007 +:100B400000000018000A000000000000050200007C +:100B500000000010B99A2C0900000010205F00006E +:100B6000000000002C1E0000000000082C80000681 +:100B7000000000082D00006A000000082D8001021E +:100B800000000000000000000000001091DE0000E6 +:100B9000000000000D7A000000000018000A0000AC +:100BA000000000002A0000000000000822000001F0 +:100BB000000000000D6100000000001021C20024B0 +:100BC00000000010B1C6000200000010234200A285 +:100BD000000000090B66FFFF00000010BA9A2C20ED +:100BE000000000000A640000000000000AE50000A8 +:100BF000000000000C000000000000000B8000005E +:100C0000000000080CC60012000000188000FFD091 +:100C1000000000080F80000300000000000000003A +:100C200000000010009F00000000000827110012C3 +:100C3000000000006690000000000010B198000362 +:100C400000000010001F0000000000080F800004DA +:100C50000000000822000003000000082C80000CA7 +:100C6000000000082D00000C00000010009F000094 +:100C70000000001091C6000500000010001F0000D9 +:100C800000000010BA9A2C03000000080F80000436 +:100C9000000000188000FFFD000000002596000005 +:100CA0000000000C29800000000000003214000049 +:100CB00000000000329500000000000573662C0063 +:100CC0000000000031E32E00000000082D8000101D +:100CD000000000188000FF950000000023000000C5 +:100CE0000000000925E6FFFF000000082200000BBD +:100CF0000000000C695200000000000C2980000078 +:100D0000000000188000FF8F000000002A00000093 +:100D1000000000082C800040000000082D0000208A +:100D2000000000082D80011C0000000822000001C6 +:100D30000000001091DE00000000000F42EA0010E9 +:100D400000000010004F000400000010B7469200A1 +:100D5000000000080249001200000010B5840A00DB +:100D6000000000000D61000000000010BA6634575A +:100D7000000000088305001200000010004F000270 +:100D800000000000034900000000000183068C0001 +:100D90000000000083C60C0000000010B1870013A3 +:100DA000000000000B6E0000000000090569FFFF55 +:100DB00000000010918A00020000000834E9FFFFE3 +:100DC000000000188000FF74000000010569140095 +:100DD00000000010918A000200000008B4E9000140 +:100DE00000000010BAE92C480000000086692C00C1 +:100DF00000000000020000000000000902EAFFFFFE +:100E000000000010000C00020000000002040A00B4 +:100E10000000000F460C00010000000F02850001D9 +:100E200000000010918C01FC00000010B7040E3F80 +:100E3000000000000D610000000000000A640000D6 +:100E4000000000000AE50000000000090B66FFFF3B +:100E5000000000000C000000000000000B800000FB +:100E6000000000080C860012000000080F8000033C +:100E70000000000C2952000000000010009F00003C +:100E8000000000082711001200000000669000001A +:100E9000000000002306000000000010B1980005CB +:100EA00000000010001F0000000000080F80000478 +:100EB000000000000000000000000010001F000003 +:100EC0000000000032140000000000003295000015 +:100ED0000000000031E32E000000000573662C00C6 +:100EE000000000002596000000000010B1870016E9 +:100EF0000000000C298000000000000F0F6B0007AD +:100F0000000000000D690000000000000A6C0000F5 +:100F1000000000000AED0000000000000B6E000061 +:100F2000000000000B800000000000000C870000A3 +:100F3000000000080F800003000000102053000094 +:100F40000000000C6952000100000010001F0000AA +:100F50000000000022C58C0000000000231B0000E0 +:100F60000000000027110000000000002690000093 +:100F700000000010B8170E030000000C29800000CC +:100F8000000000188000FFF600000010B198000279 +:100F9000000000080F800004000000082200001A72 +:100FA000000000082C80000C000000082D00000C40 +:100FB000000000082D80001000000010001F00003D +:100FC000000000000D6E000000000003E7CF3400B9 +:100FD0000000000C298000000000001091DE0000DD +:100FE00000000010B1870007000000003614000068 +:100FF00000000000369500000000000037160000D9 +:10100000000000082C800050000000082D00003077 +:10101000000000082D80000C000000188000FF2C4C +:1010200000000000230000000000000925E6FFFF8B +:10103000000000000B6E000000000003E7CF2C0052 +:10104000000000082200001B0000000C6952000094 +:101050000000000C29800000000000188000FF2420 +:10106000000000002A000000000000188000FF229D +:10107000000000002A0000000000000C2980000091 +:101080000000001091DE0000000000082C80001A13 +:10109000000000082D00001A000000057366000023 +:1010A000000000082D8000020000000031800000D8 +:1010B0000000001091DE0000000000082C80000CF1 +:1010C000000000082D00000C000000082D80000426 +:1010D000000000188000FF150000000806660001EF +:1010E00000000010BA9A197F000000000A64000096 +:1010F000000000000AE50000000000090B66FFFF89 +:10110000000000000C000000000000000B80000048 +:10111000000000080CC60012000000188000FF2E1E +:10112000000000080F800003000000000000000025 +:1011300000000010009F00000000000827110012AE +:10114000000000006690000000000010919B32003B +:10115000000000100293000000000010B19800038E +:1011600000000010001F0000000000080F800004B5 +:101170000000000C2980000000000010001F00008B +:1011800000000010BA9A2C000000000031E32E008D +:10119000000000000B800000000000008CCC8C00E0 +:1011A00000000010B5CC8C02000000080C8000018B +:1011B000000000188000FF1B000000080F800003E3 +:1011C00000000010205300000000000C69520001D4 +:1011D0000000000022C58C0000000010009F0000ED +:1011E0000000000027110000000000002690000011 +:1011F00000000000231B000000000010B198000355 +:1012000000000010001F0000000000080F80000414 +:101210000000000822000003000000082C80000CE1 +:10122000000000082D00000C00000010009F0000CE +:1012300000000000259600000000000C298000003E +:101240000000000032140000000000003295000091 +:101250000000000573662C000000000031E32E0042 +:10126000000000082D800010000000188000FEE241 +:10127000000000188000FEE1000000002A000000CD +:1012800000000010001F0000000000000F008000A0 +:10129000000000080F800007000000188000001BFD +:1012A00000000000280A0000000000000502000005 +:1012B00000000008220000090000000029000000D2 +:1012C0000000000F6568001000000000248A000084 +:1012D00000000003F66C940000000010B972A00436 +:1012E0000000000C73E700190000000C214200040C +:1012F000000000003CF800000000000C2980000005 +:101300000000001020530000000000082200000828 +:101310000000000C6142000400000018000A0000F8 +:1013200000000000050200000000000C6142000007 +:1013300000000010014200030000000C33E7001D14 +:101340000000000C6142000200000018000A0000CA +:10135000000000002A00000000000010001F000034 +:101360000000000F0F470007000000080F80000872 +:101370000000000C2980000000000010009F000009 +:10138000000000188000FEBF000000003351000084 +:10139000000000002A00000000000010B1C6002379 +:1013A0000000000F0F500007000000000A6000005E +:1013B000000000000AE100000000000F4B6200087E +:1013C000000000090B1600FF0000000F4C62001027 +:1013D000000000000D620000000000090D1A00FF6F +:1013E00000000010075000030000000C0D1A000858 +:1013F0000000000C0B160008000000000CC60000E6 +:10140000000000000B8000000000000006980000B3 +:10141000000000080F8000030000001006C2000456 +:101420000000000C2900000200000010264200020B +:101430000000000C295200030000000822000001F7 +:1014400000000010009F000000000000231B0000AF +:101450000000000027111A00000000006690000044 +:101460000000000C2952000000000010B197320962 +:101470000000000C29800000000000000698000019 +:1014800000000010205300000000000C295200034F +:101490000000000022C58C0000000010001F0000AA +:1014A000000000080F800003000000188000FFF318 +:1014B00000000010B1C8001300000010B1C6000306 +:1014C0000000000C298000000000001020530000E4 +:1014D0000000000C295200000000000C29520003FB +:1014E0000000001006C200020000000C2952000299 +:1014F0000000000022C58C000000000027650000ED +:101500000000000026E40000000000082200001691 +:1015100000000010B1C600030000000023480000D6 +:1015200000000010B180000500000000234800000A +:101530000000000C298000000000000F0F50000781 +:1015400000000018800000120000000822000016B1 +:101550000000000C29800000000000003014000092 +:10156000000000003095000000000010075000034C +:10157000000000090B1600FF000000090D1A00FF13 +:101580000000000F31160008000000003162340036 +:1015900000000003F162300000000010205F000036 +:1015A000000000002C510000000000092CD1007F39 +:1015B000000000082CD90000000000082D000000E9 +:1015C000000000082D80000C00000000000000005A +:1015D0000000001091DE00000000001005C20004B1 +:1015E000000000080F80000700000000330000002A +:1015F00000000010009F0000000000188000FE7036 +:10160000000000002A0000000000000F0F5000073B +:1016100000000010B1C6002D0000000F4742000876 +:1016200000000009070E000F00000008070E000868 +:1016300000000010001F0000000000080900000169 +:101640000000000709121C0000000003CBCA920032 +:10165000000000000B97A2000000000742171C00CA +:10166000000000000B0400000000000F0A840003CB +:10167000000000000A959C00000000004A009A004B +:101680000000000882120001000000010C17080091 +:10169000000000000C978C00000000000218000001 +:1016A000000000080D00FFFF000000080F8000068A +:1016B0000000000C290000000000001006C2000419 +:1016C0000000000C29520002000000102642000217 +:1016D0000000000C29520003000000082200000155 +:1016E00000000010009F000000000010B197320CB5 +:1016F00000000000231B000000000000271108006C +:1017000000000000669000000000000C298000002E +:10171000000000000218000000000010205300002C +:101720000000000C295200030000000022C5360012 +:1017300000000010001F0000000000080F800006DD +:10174000000000188000FFF400000000231B0000D0 +:101750000000000027110800000000006690000053 +:1017600000000010B1C8000B0000000C2980000030 +:1017700000000010205300000000000C295200005F +:101780000000000C295200030000001006C20002F5 +:101790000000000C295200020000000022C58C004D +:1017A00000000000276500000000000026E40000A3 +:1017B000000000002348000000000008220000177D +:1017C0000000000C2980000000000010001F000035 +:0817D000000000188000FE3546 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex b/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex deleted file mode 100644 index f325e6904edb372ccce17c88c3efe8984d6a9dd5..0000000000000000000000000000000000000000 --- a/firmware/bnx2/bnx2-rv2p-09ax-5.0.0.j10.fw.ihex +++ /dev/null @@ -1,499 +0,0 @@ -:100000000000000000000E80000000580000000901 -:1000100000000000000000000000000000000000E0 -:1000200000000000000000000000000000000000D0 -:1000300000000FA800000ED800000005000000001E -:1000400000000000000000000000000000000000B0 -:080050000000000000000000A8 -:0800580000000010B180000659 -:100060000000001F03030300000000080500FFFF5D -:10007000000000180002000000000008050000FF5A -:10008000000000180002000000000008AC000001A1 -:1000900000000000050000000000000C2F8000019F -:1000A000000000002B000000000000002B8000007A -:1000B0000000001091E0000200000008AC00000108 -:1000C00000000010203F006B00000010213F0003E3 -:1000D0000000001020BF003A000000188000FFFD63 -:1000E00000000010B1B8B0150000000B2FDF0002B7 -:1000F0000000000003D80000000000002C380000C1 -:10010000000000082C800000000000082D00000006 -:100110000000001091D400000000000806005555B2 -:10012000000000188000008F000000082D80011CD6 -:1001300000000008020000010000001091DE000035 -:100140000000000F42E0001C0000001091840A161D -:1001500000000018800000960000000C29800002BA -:100160000000000C1F800002000000002ADF0000D9 -:10017000000000082A00000F000000000500000039 -:10018000000000188000FFE60000000802000001E7 -:100190000000000F42E0001C0000001091840A18CB -:1001A000000000082C800006000000082D0000065A -:1001B0000000001091D40000000000082D8001060E -:1001C0000000001880000085000000188000FFF18A -:1001D00000000008B1000001000000082C80010CA4 -:1001E000000000082D000008000000082D8000011C -:1001F000000000188000007F0000000B2FDF0002CD -:100200000000000C1F800002000000002C0700000E -:100210000000001091DE00000000000805005555A8 -:10022000000000188000FFD20000000B2FDF00024A -:100230000000000C1F800000000000002C070000E0 -:100240000000001091DE0000000000080500555578 -:10025000000000188000FFCC0000000C1F8000028E -:100260000000000805005555000000188000FFC977 -:100270000000000C298000020000000C1F8000021A -:10028000000000002ADF0000000000082A0000052E -:100290000000000805005555000000188000FFC34D -:1002A000000000080224004A0000001800040000BA -:1002B000000000188000001C000000188000001ED4 -:1002C000000000188000007800000018800000CBBB -:1002D00000000018800000CA000000188000000024 -:1002E00000000018800000000000001880000000DE -:1002F00000000018800000000000001880000000CE -:1003000000000018800000000000001880000000BD -:100310000000001880000000000000188000011696 -:10032000000000188000000000000018800000009D -:100330000000001880000015000000188000001B5D -:10034000000000188000000000000018800000E19C -:10035000000000188000002F000000188000011627 -:100360000000001880000141000000188000010C0E -:100370000000001880000165000000188000006186 -:100380000000001880000000000000188000009E9F -:100390000000000C1F8000010000000005000000AC -:1003A000000000188000FFA20000001091D400009F -:1003B0000000000C298000010000000C1F800001DB -:1003C000000000082A0000020000000005000000F4 -:1003D000000000188000FF9C0000001091D4000075 -:1003E0000000000C298000010000000C1F800001AB -:1003F0000000000029420000000000082A0000025E -:100400000000000005000000000000188000FF95BB -:10041000000000188000FF9400000010B1BCB00A7A -:100420000000000B2FDF00020000000003D80000D6 -:10043000000000002C3C00000000001091D40000DF -:100440000000000806005555000000188000002A32 -:1004500000000018800000DA000000102C6201BAD1 -:100460000000001880000006000000082C80010D2C -:10047000000000082D0000090000001091D40000C9 -:10048000000000082D8001070000001880000037E0 -:100490000000000C298000000000000C1F800000FC -:1004A0000000001091DE0000000000002ADF0000C4 -:1004B000000000082A00000600000008050055554D -:1004C000000000188000FF7E0000001091D40000A2 -:1004D0000000000C298000010000000C1F800001BA -:1004E000000000082A00000B0000000005000000CA -:1004F000000000188000FF780000000002020000E9 -:1005000000000000029A000000000000060C2C0011 -:1005100000000004C60C340000000010001F0000A2 -:1005200000000010B196180C0000000806960004A8 -:1005300000000009068DFFFC00000004CD051A0034 -:1005400000000004CC9A18000000001020D7000022 -:100550000000000C2B56000000000000000000000E -:1005600000000000000000000000001020D7000084 -:10057000000000080F80000100000010B18001F4AD -:1005800000000010001F00000000000C6B5600006F -:1005900000000018000400000000000006820000B7 -:1005A00000000010B18A000800000010B18C140790 -:1005B0000000000B050AFFFF00000010B18A0003D5 -:1005C00000000000860A180000000010918C000056 -:1005D000000000082A0000010000001091D4000073 -:1005E00000000018000D00000000000005020000DF -:1005F0000000001091DE000000000018000A00005A -:1006000000000000068200000000001091DE0000E3 -:1006100000000010BEE10005000000188000FF4C43 -:10062000000000010561140000000010918A000222 -:1006300000000008B0E1000100000018000D0000FB -:1006400000000000068200000000001091DE0000A3 -:1006500000000010BEE20005000000188000FF440A -:10066000000000010562140000000010918A0002E1 -:1006700000000008B162000100000018000D000039 -:1006800000000010B1A0B0130000000B2FDF00022B -:10069000000000002C200000000000082C8000005A -:1006A000000000082D0000000000001091D40000A0 -:1006B0000000000806005555000000188000FFDC0F -:1006C000000000082D80011C00000010001F000029 -:1006D000000000188000FFE60000000F47600008DF -:1006E0000000000F060E0001000000000F5800007F -:1006F000000000000A640000000000000AE500009D -:10070000000000090B66FFFF000000000D61000003 -:1007100000000018800000130000000F4760000870 -:100720000000000B2FDF0002000000082C800000FA -:10073000000000082D0000000000001091D400000F -:10074000000000082D80011C0000000F060E0001B3 -:1007500000000010001F0000000000000F58000003 -:10076000000000188000FFD4000000000A640000B0 -:10077000000000000AE50000000000090B66FFFF12 -:10078000000000000D610000000000000262000097 -:100790000000000B2FDF0002000000003104000009 -:1007A00000000000309A0000000000090560000F02 -:1007B00000000010B18A000B0000000005634C002F -:1007C00000000008050A001200000010B9621403BE -:1007D0000000000003000000000000188000000678 -:1007E000000000188000FF1100000010B60614047D -:1007F0000000000803060001000000082A000001B4 -:10080000000000188000FF16000000188000FF9E06 -:100810000000000C298000010000000C295200019A -:100820000000000C29520000000000080200000E29 -:10083000000000080280001A00000010B1C40A0283 -:100840000000000802000003000000082200000170 -:100850000000000C1F800001000000002ADF0000E3 -:10086000000000002A00080000000008050055559F -:10087000000000188000FF080000000B2FDF0002BE -:100880000000001091D40000000000082A000001C0 -:10089000000000002C2000000000001091D4000097 -:1008A000000000082C800000000000082D0000005F -:1008B000000000082D80011C000000188000FFA629 -:1008C000000000082C800006000000082D00000633 -:1008D0000000000030800000000000003100000037 -:1008E000000000082D8000060000000C2980000197 -:1008F0000000000C1F8000010000001091DE0000CD -:10090000000000002ADF0000000000082A0000109C -:100910000000000005000000000000188000FEF349 -:100920000000001091A0B009000000082C80010D0B -:10093000000000082D0000090000001091D4000004 -:10094000000000082D800107000000188000FF9FB4 -:10095000000000188000001000000008AC0000013A -:10096000000000188000000B000000000380B000B1 -:100970000000000B2FDF0002000000002C004000F0 -:100980000000001091D4000000000008060055553A -:10099000000000188000FF81000000188000003176 -:1009A00000000018800000060000000B2FDF00028E -:1009B000000000002C000E00000000082A000007C4 -:1009C0000000000805005555000000188000FEDDFD -:1009D00000000000068200000000000C29800001D9 -:1009E0000000000C1F800001000000100CE7000751 -:1009F000000000090562FFFF00000010BA6C14053A -:100A0000000000002ADF00000000000021000000BC -:100A1000000000082A0000050000001091D400002A -:100A2000000000082C80010C000000082D000008C8 -:100A30000000000C31620018000000082D80000149 -:100A4000000000188000FF7500000018000D000075 -:100A500000000010B1A0B00E0000000B2FDF00025C -:100A60000000000003D80000000000002C2000005F -:100A70000000001091D40000000000188000001554 -:100A8000000000102C620002000000188000000C22 -:100A90000000000B2FDF0002000000002C07000008 -:100AA0000000000C1F8000010000001091DE00001B -:100AB000000000080500FFFF000000188000FEBFD6 -:100AC000000000082C80010D000000082D00000926 -:100AD0000000001091D40000000000082D800107E4 -:100AE000000000188000FF6C0000000C298000014D -:100AF0000000000C1F8000010000001091DE0000CB -:100B0000000000002ADF0000000000082A00000AA0 -:100B10000000000005000000000000188000FEB387 -:100B20000000000006820000000000082C80010C7C -:100B3000000000082D000008000000082D8001348E -:100B4000000000000000000000000010205F000016 -:100B5000000000082C800140000000082D00003C2F -:100B6000000000082D80011C0000000000000000B3 -:100B70000000001091DE0000000000082C800080C2 -:100B8000000000082D000000000000082D80010575 -:100B900000000010BEE20005000000188000FE9C6E -:100BA000000000010562140000000010918A00029C -:100BB00000000008B16200010000001091DE00009A -:100BC00000000018000D00000000001091D400008B -:100BD000000000080600AAAA000000188000FF38E4 -:100BE0000000000C298000010000000C1F800001A3 -:100BF000000000082A000009000000080500AAAA59 -:100C0000000000188000FE960000001091D4000043 -:100C10000000000806005555000000188000FF3055 -:100C20000000001091A03C0200000010B1E6620735 -:100C30000000000B2FDF0002000000002C3100003C -:100C4000000000092CB1007F000000082CD9000032 -:100C5000000000082D000000000000082D80010D9C -:100C600000000010B1A8000600000010205F000086 -:100C7000000000002C200000000000002CA7000055 -:100C8000000000082D000010000000082D80010861 -:100C9000000000188000FF2B00000010B1A600101B -:100CA00000000010001F00000000000F0F300007C0 -:100CB000000000000A600000000000000AE10000DF -:100CC0000000000F4B620008000000090B1600FF37 -:100CD000000000000D620000000000090D1A00FF76 -:100CE00000000010073000030000000C0D1A00087F -:100CF0000000000C0B1600080000000F4CE3001869 -:100D0000000000000C992C0000000004CC99340075 -:100D1000000000080F8000000000000C2980000186 -:100D2000000000003331000000000008220000161F -:100D3000000000002ADF0000000000082A00000C6C -:100D400000000010009F0000000000000F200000C5 -:100D50000000000C1F800001000000080500555530 -:100D6000000000188000FE6A0000001091D400000E -:100D7000000000080600AAAA000000188000FF0476 -:100D80000000000F4722000800000009070E000FB6 -:100D900000000008070E00080000000802800001A3 -:100DA0000000000702851C00000000088285000189 -:100DB0000000000002854C000000000742851C0076 -:100DC00000000003C3AA52000000000003B10E009F -:100DD000000000074B071C000000000F0F30000749 -:100DE0000000000F0A960003000000000A955C0056 -:100DF000000000004A005A00000000000C960A00A3 -:100E0000000000090C99FFFF000000080D00FFFF23 -:100E100000000010B1963202000000080F800005AB -:100E200000000010B1A8000800000010205F0000C2 -:100E30000000000B2FDF0002000000002C2000004B -:100E4000000000002CA70000000000082D0000108A -:100E5000000000082D800108000000188000FEF24C -:100E60000000000C2980000100000010001F00009D -:100E70000000000C1F800001000000002ADF0000BD -:100E8000000000082A00000D000000080500AAAAC2 -:100E9000000000188000FE440000001091D4000003 -:100EA0000000000806005555000000188000FEDE16 -:100EB0000000000C298000010000000C1F800001D0 -:100EC000000000082A000007000000080500555532 -:080ED000000000188000FE3C48 -:080ED80000000010B1800004CD -:100EE0000000001F0303030000000008050000FFCE -:100EF0000000001800020000000000002A000000AE -:100F000000000010B1D400000000001091DE0000CD -:100F1000000000102053000000000010001F00001F -:100F20000000000C6BD70001000000002F80AA0019 -:100F30000000000C29800001000000080254000F8E -:100F4000000000002C400000000000092952003F72 -:100F500000000018000400000000001880000010CD -:100F60000000001880000011000000188000004AF6 -:100F700000000018800001280000001880000127F0 -:100F800000000018800001260000001880000126E3 -:100F90000000001880000000000000188000013FE1 -:100FA0000000001880000122000000188000000BE3 -:100FB0000000001880000145000000188000019A20 -:100FC000000000188000007B00000018800000F97D -:100FD0000000001880000109000000002A00000045 -:100FE000000000188000FFE4000000002A0000005C -:100FF0000000000C29800000000000188000FFE1C4 -:10100000000000002A000000000000188000FFDF40 -:101010000000000003820000000000188000FFDADA -:10102000000000010C161400000000008C181400D1 -:101030000000001091980003000000080C960002C8 -:1010400000000010B1800003000000080C960001B1 -:10105000000000000C000000000000000D1900005E -:1010600000000010205600000000000C2BD70001EB -:10107000000000080F8000010000000000000000D8 -:1010800000000010001F00000000000C6BD70001E2 -:1010900000000010011301F100000018000700001B -:1010A00000000000050200000000001091963421AD -:1010B00000000010205F0000000000002C1E000057 -:1010C000000000082C800006000000082D0000062B -:1010D000000000082D800102000000000000000058 -:1010E0000000001091DE0000000000000D61000013 -:1010F00000000018000A00000000000005020000C7 -:10110000000000109196341600000010205F0000CF -:101110000000000009D80000000000002C1E0000A4 -:10112000000000082C80010E000000082D00000ABD -:10113000000000082D8001020000000000000000F7 -:101140000000001091DE0000000000000D620000B1 -:10115000000000002C13000000000018000A00002E -:101160000000000005020000000000109196340904 -:1011700000000010205F0000000000002C1E000096 -:10118000000000082C800006000000082D00006A06 -:10119000000000082D800102000000000000000097 -:1011A0000000001091DE0000000000000D7A000039 -:1011B00000000018000A0000000000002A000000E3 -:1011C000000000000D61000000000000036200004C -:1011D00000000010234200DB0000000002638C00CE -:1011E0000000000026460000000000080204001273 -:1011F00000000010B906082E000000000F58000083 -:10120000000000000A640000000000000AE5000081 -:10121000000000090B66FFFF000000000C0000004A -:10122000000000000B800000000000080CC6001247 -:10123000000000188000FFCE0000001020560000C3 -:101240000000000C2BD70001000000080F800003F5 -:10125000000000000000000000000010001F00005F -:101260000000000C6BD700010000000827110012DD -:10127000000000006690000000000008A31B0012A0 -:1012800000000010B198000600000010001F0000D0 -:101290000000000C6BD70001000000102056000079 -:1012A0000000000C2BD70001000000080F80000494 -:1012B0000000000822000003000000082C80000C41 -:1012C000000000082D00000C00000010001F0000AE -:1012D0000000000C6BD70001000000002596000004 -:1012E0000000000C298000000000000006660000DD -:1012F0000000000086611800000000090260000F75 -:101300000000000F0204000200000010B60C0805E7 -:101310000000000C1FBF0000000000102866000342 -:1013200000000008078F00010000000C3366001069 -:1013300000000000321400000000000032950000A0 -:101340000000000573662C000000000031E32E0051 -:10135000000000082D800010000000188000FF75BC -:1013600000000000230000000000000925E6FFFF48 -:10137000000000082200000B0000000C6952000071 -:101380000000000C29800000000000102866008882 -:10139000000000188000FF6E000000002A0000001E -:1013A000000000082C800040000000082D000020F4 -:1013B000000000082D80011C00000000000000005B -:1013C0000000001091DE00000000000F42EA001053 -:1013D00000000010004F000400000010B74692000B -:1013E000000000080249001200000010B5840A0045 -:1013F000000000000D61000000000010BA66346AB1 -:10140000000000088305001200000010004F0002D9 -:1014100000000000034900000000000183068C006A -:101420000000000083C60C0000000010B18700110E -:10143000000000000B6E000000000010BEE9000577 -:10144000000000188000FF5500000001056914002D -:1014500000000010918A000200000008B4E90001B9 -:1014600000000010B1E92C5D0000000086692C002E -:1014700000000000020000000000000902EAFFFF77 -:1014800000000010000C00020000000002040A002E -:101490000000000F460C00010000000F0285000153 -:1014A00000000010918C01FC00000010B7040E54E5 -:1014B000000000000F400000000000000D6100006F -:1014C000000000000A640000000000000AE50000BF -:1014D000000000090B66FFFF000000000C00000088 -:1014E000000000000B800000000000080C860012C5 -:1014F00000000010205600000000000C2BD7000157 -:10150000000000080F8000030000000C29520000BA -:1015100000000010001F00000000000C6BD700014D -:101520000000000827110012000000006690000073 -:101530000000000026460000000000002306000016 -:1015400000000010B198000900000010001F00000A -:101550000000000C6BD700010000001020560000B6 -:101560000000000C2BD70001000000080F800004D1 -:10157000000000000000000000000010001F00003C -:101580000000000C6BD700010000000032140000C6 -:1015900000000000329500000000000031E32E0042 -:1015A0000000000573662C00000000002596000076 -:1015B00000000010B18700210000000C298000000D -:1015C0000000000F0F6B0007000000000D69000015 -:1015D000000000000A6C0000000000000AED00009E -:1015E000000000000B6E0000000000000B800000F7 -:1015F000000000000C870000000000188000FF1EA3 -:10160000000000010C161400000000008C181400EB -:10161000000000080C9600010000001091980002E4 -:10162000000000080C990001000000000D190000E6 -:10163000000000000C000000000000102056000018 -:101640000000000C2BD70001000000080F800001F3 -:1016500000000010205300000000000C695200013F -:1016600000000010001F00000000000C6BD70001FC -:101670000000000022C58C000000000023120000C2 -:10168000000000002711000000000000269000006C -:1016900000000010B8170E030000000C29800000A5 -:1016A000000000188000FFEB0000000082970E0091 -:1016B00000000000A3120A00000000082200001A27 -:1016C000000000082C80000C000000082D00000C19 -:1016D000000000082D80001000000010001F000016 -:1016E0000000000C6BD70001000000000D6E000030 -:1016F00000000003E7CF34000000000C2980000048 -:101700000000001091DE000000000010B18700070B -:1017100000000000361400000000000036950000B4 -:101720000000000037160000000000082C80005068 -:10173000000000082D000030000000082D80000C83 -:10174000000000188000FEF800000000264600009F -:1017500000000000230000000000000925E6FFFF54 -:10176000000000000B6E000000000003E7CF2C001B -:10177000000000082200001B0000000C695200005D -:101780000000000C29800000000000188000FEEF1F -:10179000000000002A00000000000010086600059C -:1017A00000000000066600000000000086611800CE -:1017B00000000009026000F000000010B60C0802F2 -:1017C000000000188000FEE8000000000682000013 -:1017D00000000010B18F000000000008878F00019A -:1017E0000000000C73660010000000082C80001838 -:1017F000000000082D000018000000082D800002E5 -:101800000000000C5FBF00000000001091DE00002F -:1018100000000018000D0000000000002A00000079 -:1018200000000010286601F5000000082C8000036D -:10183000000000082D000003000000093060FFF0E8 -:10184000000000082D8000010000000C298000002D -:101850000000001091DE0000000000082C80001A3B -:10186000000000082D00001A00000005736600004B -:10187000000000082D800002000000003180000000 -:101880000000001091DE0000000000082C80000C19 -:10189000000000082D00000C000000082D8000044E -:1018A000000000188000FECC0000001800020000BC -:1018B000000000188000FECA000000002A0000009E -:1018C00000000010001F00000000000C6BD700019A -:1018D000000000000F008000000000080F800007DB -:1018E000000000188000001B00000000280A000013 -:1018F00000000000050200000000000822000009AE -:1019000000000000290000000000000F65680010C2 -:1019100000000003F66C940000000010B972A004EF -:101920000000000C73E700190000000C21420004C5 -:10193000000000003CF800000000000C29800000BE -:1019400000000010205300000000000822000008E2 -:101950000000000C6142000400000018000A0000B2 -:1019600000000000050200000000000C61420000C1 -:1019700000000010014200030000000C33E7001DCE -:101980000000000C6142000200000018000A000084 -:10199000000000002A00000000000010001F0000EE -:1019A0000000000C6BD700010000000F0F4700077C -:1019B000000000080F8000080000000C29800000D3 -:1019C00000000010001F00000000000C6BD7000199 -:1019D000000000188000FEA6000000003351000047 -:1019E000000000002A00000000000010B1C600291D -:1019F0000000000F0F500007000000000A60000008 -:101A0000000000000AE100000000000F4B62000827 -:101A1000000000090B1600FF0000000F4C620010D0 -:101A2000000000000D620000000000090D1A00FF18 -:101A300000000010075000030000000C0D1A000801 -:101A40000000000C0B160008000000000CC600008F -:101A5000000000000B80000000000000069800005D -:101A600000000010205600000000000C2BD70001E1 -:101A7000000000080F8000030000001006C20004F0 -:101A80000000000C290000020000001026420002A5 -:101A90000000000C29520003000000082200000191 -:101AA00000000010001F00000000000C6BD70001B8 -:101AB00000000000231B00000000000027111A0096 -:101AC00000000000669000000000000C2952000099 -:101AD00000000010B197320C0000000C29800000BB -:101AE00000000000069800000000001020530000D5 -:101AF0000000000C295200030000000022C58C00E9 -:101B000000000010001F00000000000C6BD7000157 -:101B100000000010205600000000000C2BD7000130 -:101B2000000000080F800003000000188000FFEF95 -:101B300000000010B1C8001300000010B1C600037F -:101B40000000000C2980000000000010205300005D -:101B50000000000C295200000000000C2952000374 -:101B60000000001006C200020000000C2952000212 -:101B70000000000022C58C00000000002765000066 -:101B80000000000026E4000000000008220000160B -:101B900000000010B1C60003000000002348000050 -:101BA00000000010B1800005000000002348000084 -:101BB0000000000C298000000000000F0F500007FB -:101BC000000000188000001200000008220000162B -:101BD0000000000C2980000000000000301400000C -:101BE00000000000309500000000001007500003C6 -:101BF000000000090B1600FF000000090D1A00FF8D -:101C00000000000F311600080000000031623400AF -:101C100000000003F162300000000010205F0000AF -:101C2000000000002C510000000000092CD1007FB2 -:101C3000000000082CD90000000000082D00000062 -:101C4000000000082D80000C0000000000000000D3 -:101C50000000001091DE00000000001005C2000529 -:101C6000000000080F8000070000000033000000A3 -:101C700000000010001F00000000000C6BD70001E6 -:101C8000000000188000FE50000000002A00000044 -:101C90000000000F0F50000700000010B1C6003018 -:101CA0000000000F4742000800000009070E000F67 -:101CB00000000008070E000800000010001F0000D0 -:101CC0000000000C6BD700010000000809000001B3 -:101CD0000000000709121C0000000003CBCA92009C -:101CE000000000000B97A2000000000742171C0034 -:101CF000000000000B0400000000000F0A84000335 -:101D0000000000000A959C00000000004A009A00B4 -:101D10000000000882120001000000010C170800FA -:101D2000000000000C978C0000000000021800006A -:101D3000000000080D00FFFF000000080F800006F3 -:101D40000000000C290000000000001006C2000482 -:101D50000000000C29520002000000102642000280 -:101D60000000000C295200030000000822000001BE -:101D700000000010001F00000000000C6BD70001E5 -:101D800000000010B197320D00000000231B00007E -:101D9000000000002711080000000000669000000D -:101DA0000000000C29800000000000000218000064 -:101DB00000000010205300000000000C2952000316 -:101DC0000000000022C5360000000010001F0000C7 -:101DD0000000000C6BD70001000000080F80000617 -:101DE000000000188000FFF200000000231B00002C -:101DF00000000000271108000000000066900000AD -:101E000000000010B1C8000B0000000C2980000089 -:101E100000000010205300000000000C29520000B8 -:101E20000000000C295200030000001006C200024E -:101E30000000000C295200020000000022C58C00A6 -:101E400000000000276500000000000026E40000FC -:101E500000000000234800000000000822000017D6 -:101E60000000000C2980000000000010001F00008E -:101E70000000000C6BD70001000000188000FE116C -:00000001FF -/* - * This file contains firmware data derived from proprietary unpublished - * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware data - * in hexadecimal or equivalent format, provided this copyright notice is - * accompanying it. - */ diff --git a/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex b/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex new file mode 100644 index 0000000000000000000000000000000000000000..d2f275788f166b79e13d6e888c1142cb49fb7b9a --- /dev/null +++ b/firmware/bnx2/bnx2-rv2p-09ax-6.0.17.fw.ihex @@ -0,0 +1,425 @@ +:100000000000000000000970000000580000000916 +:1000100000000000000000000000000000000000E0 +:1000200000000000000000000000000000000000D0 +:1000300000001010000009C80000000500000000CA +:1000400000000000000000000000000000000000B0 +:080050000000000000000000A8 +:0800580000000010B180000659 +:100060000000001F03060011000000080500FFFF4C +:10007000000000180002000000000008050000FF5A +:10008000000000180002000000000008AC000001A1 +:1000900000000008078000000000000C2F80000115 +:1000A000000000002B000000000000002B8000007A +:1000B0000000001091E1000200000008AC00000107 +:1000C00000000010203F003B00000010213F000313 +:1000D0000000001020BF0015000000188000FFFD88 +:1000E0000000000C1F800002000000188000FFF9D3 +:1000F00000000008B1000001000000082C80010C85 +:10010000000000082D000008000000082D800001FC +:10011000000000188000004F0000000B2FDF0002DD +:100120000000000C1F800002000000002C070000EF +:100130000000001091DE0000000000188000FFEFBA +:100140000000000B2FDF00020000000C1F800000E9 +:10015000000000002C0700000000001091DE0000ED +:10016000000000188000FFEA0000000C1F80000261 +:10017000000000188000FFE80000000802240025AD +:1001800000000018000400000000001880000000BB +:10019000000000188000001B0000001880000055BF +:1001A000000000188000000000000018800000001F +:1001B000000000188000000000000018800000000F +:1001C00000000018800000000000001880000000FF +:1001D00000000018800000000000001880000000EF +:1001E00000000018800000000000001880000000DF +:1001F000000000188000009D000000188000000032 +:1002000000000018800000000000001880000000BE +:1002100000000018800000000000001880000000AE +:10022000000000188000000000000018800000009E +:10023000000000188000009C00000018800000C62C +:10024000000000188000009300000018800000E902 +:10025000000000188000003E000000188000000030 +:10026000000000188000007A0000001091D4000007 +:100270000000000C298000010000000C1F8000011C +:10028000000000082A0000020000000807800000AB +:10029000000000188000FFC4000000080380010077 +:1002A00000000010B73C0E000000001880000000A5 +:1002B000000000000202000000000000029A00009E +:1002C00000000000060C2C0000000004C60C3400E6 +:1002D00000000010001F000000000010BA8C2C0C61 +:1002E000000000080696000400000009068DFFFCCF +:1002F00000000004CD051A0000000004CC9A18008C +:100300000000001020D700000000000C2B56000059 +:1003100000000000000000000000000000000000DD +:100320000000001020D70000000000080F8000012E +:1003300000000010B18001F400000010001F000058 +:100340000000000C6B5600000000001800040000C4 +:10035000000000000682000000000010B18F0004C1 +:1003600000000010B18F1403000000082A000001F3 +:100370000000001091D4000000000000078014006D +:1003800000000018000D0000000000000502000041 +:100390000000001091DE000000000018000A0000BC +:1003A00000000000068200000000001091DE000046 +:1003B000000000090561FFFF00000010918A0002A3 +:1003C0000000000830E1FFFF000000188000FF96E9 +:1003D000000000010561140000000010918A000275 +:1003E00000000008B0E1000100000018000D00004E +:1003F00000000000068200000000001091DE0000F6 +:10040000000000090562FFFF00000010918A000251 +:10041000000000083162FFFF000000188000FF8C20 +:10042000000000010562140000000010918A000223 +:1004300000000008B162000100000018000D00007B +:1004400000000010B1A0B0130000000B2FDF00026D +:10045000000000002C200000000000082C8000009C +:10046000000000082D0000000000001091D40000E2 +:100470000000000805000055000000188000FFDBA8 +:10048000000000082D80011C00000010001F00006B +:10049000000000188000FFE20000000F4760000825 +:1004A0000000000F060E0001000000000F580000C1 +:1004B000000000000A640000000000000AE50000DF +:1004C000000000090B66FFFF000000000D61000046 +:1004D00000000018800000150000000F47600008B1 +:1004E0000000000B2FDF0002000000082C8000003D +:1004F000000000082D0000000000001091D4000052 +:10050000000000082D80011C0000000F060E0001F5 +:1005100000000010001F0000000000000F58000045 +:10052000000000188000FFD0000000000A640000F6 +:10053000000000000AE50000000000090B66FFFF54 +:10054000000000000D6100000000000002620000D9 +:100550000000000002E000000000000B2FDF00029E +:100560000000000030050000000000003104000021 +:1005700000000000309A0000000000100060000A37 +:10058000000000080516000100000010BA9A1403CC +:1005900000000000030000000000001880000006BA +:1005A000000000188000FF5900000010B606140477 +:1005B0000000000803060001000000082A000001F6 +:1005C000000000188000FF5E000000188000FF9D02 +:1005D0000000000C298000010000000C29520001DD +:1005E0000000000C295200000000000822800002D8 +:1005F000000000080200000E000000080280001A3F +:1006000000000010B1C40A0200000008020000034C +:100610000000000C1F800001000000002ADF000025 +:10062000000000002A000800000000188000FF51B0 +:100630000000000B2FDF00020000001091D400002A +:10064000000000082A000001000000002C2000002B +:100650000000001091D40000000000082C80000071 +:10066000000000082D000000000000082D80011C83 +:10067000000000188000FFA3000000082C80000686 +:10068000000000082D00000600000000308000007F +:100690000000000031000000000000082D8000066E +:1006A0000000000C298000010000000C1F800001E8 +:1006B0000000001091DE0000000000002ADF0000B2 +:1006C000000000082A000010000000080780000059 +:1006D000000000188000FF3C0000001091D40000D2 +:1006E00000000008050000AA000000188000FF8D2F +:1006F0000000000C298000010000000C1F80000198 +:10070000000000082A000009000000188000FF35E2 +:100710000000001091D40000000000080500005502 +:10072000000000188000FF860000001091A0B002B9 +:1007300000000010B1E662070000000B2FDF00028E +:10074000000000002C310000000000092CB1007FE7 +:10075000000000082CD90000000000082D00000057 +:10076000000000082D80010D00000010B1A8000657 +:1007700000000010205F0000000000002C2000009E +:10078000000000002CA70000000000082D00001051 +:10079000000000082D800108000000188000FF7E86 +:1007A00000000010B1A6001000000010001F0000A3 +:1007B0000000000F0F300007000000000A6000007A +:1007C000000000000AE100000000000F4B6200087A +:1007D000000000090B1600FF000000000D62000081 +:1007E000000000090D1A00FF000000100730000390 +:1007F0000000000C0D1A00080000000C0B16000889 +:100800000000000F4CE30018000000000C992C00C1 +:1008100000000004CC993400000000080F800000A4 +:100820000000000C298000010000000033310000AE +:100830000000000822000016000000002ADF00006F +:10084000000000082A00000C00000010009F0000BB +:10085000000000002C2000000000000C1F800001A0 +:10086000000000188000FF0A0000001091D4000072 +:1008700000000008050000AA000000188000FF5BCF +:100880000000000F4722000800000009070E000FBB +:1008900000000008070E00080000000802800001A8 +:1008A0000000000702851C0000000008828500018E +:1008B0000000000002854C000000000742851C007B +:1008C00000000003C3AA52000000000003B10E00A4 +:1008D000000000074B071C000000000F0F3000074E +:1008E0000000000F0A960003000000000A955C005B +:1008F000000000004A005A00000000000C960A00A8 +:10090000000000090C99FFFF000000080D00FFFF28 +:1009100000000010BA992C02000000080F800005AA +:1009200000000010B1A8000800000010205F0000C7 +:100930000000000B2FDF0002000000002C20000050 +:10094000000000002CA70000000000082D0000108F +:10095000000000082D800108000000188000FF46FC +:100960000000000C2980000100000010001F0000A2 +:100970000000000C1F800001000000002ADF0000C2 +:10098000000000082A00000D000000188000FEE5AD +:100990000000001091D40000000000080500005580 +:1009A000000000188000FF360000000C29800001C4 +:1009B0000000000C1F800001000000082A00000752 +:0809C000000000188000FEDEBB +:0809C80000000010B1800004E2 +:1009D0000000001F0306001100000008050000FFD2 +:1009E0000000001800020000000000002A000000C3 +:1009F00000000010B1D400000000001091DE0000E3 +:100A0000000000102053000000000010001F000034 +:100A10000000000C6BD70001000000002F80AA002E +:100A20000000000C298000010000000802540010A2 +:100A3000000000002C400000000000000F400000FB +:100A4000000000092952003F0000001800040000C7 +:100A50000000001880000011000000188000001243 +:100A600000000018800000470000001880000137D7 +:100A700000000018800001360000001880000135D9 +:100A80000000001880000135000000188000000000 +:100A9000000000188000014F0000001880000131A4 +:100AA00000000018800000000000001880000155C0 +:100AB00000000018800001A6000000188000006DF2 +:100AC00000000018800000E400000018800000E52D +:100AD000000000188000012A000000002A00000029 +:100AE000000000188000FFE2000000002A00000063 +:100AF0000000000C29800000000000188000FFDFCB +:100B00000000000003820000000000188000FFDAEF +:100B1000000000010C161400000000008C181400E6 +:100B20000000001091980003000000080C960002DD +:100B300000000010B1800003000000080C960001C6 +:100B4000000000000C000000000000000D19000073 +:100B5000000000080F8000010000000000000000FD +:100B600000000010001F00000000000C6BD7000107 +:100B700000000010011301F300000018000700003E +:100B8000000000000502000000000010B99A2C21AE +:100B900000000010205F0000000000002C1E00007C +:100BA000000000082C800006000000082D00000650 +:100BB000000000082D80010200000000000000007D +:100BC0000000001091DE0000000000000D61000038 +:100BD00000000018000A00000000000005020000EC +:100BE00000000010B99A2C1600000010205F0000D1 +:100BF0000000000009D80000000000002C1E0000CA +:100C0000000000082C80010E000000082D00000AE2 +:100C1000000000082D80010200000000000000001C +:100C20000000001091DE0000000000000D620000D6 +:100C3000000000002C13000000000018000A000053 +:100C4000000000000502000000000010B99A2C0905 +:100C500000000010205F0000000000002C1E0000BB +:100C6000000000082C800006000000082D00006A2B +:100C7000000000082D8001020000000000000000BC +:100C80000000001091DE0000000000000D7A00005E +:100C900000000018000A0000000000002A00000008 +:100CA0000000000822000001000000000D610000AB +:100CB0000000001021C2002800000010B1C6000290 +:100CC00000000010234200B3000000090B66FFFF84 +:100CD00000000010BA9A2C24000000000A640000F2 +:100CE000000000000AE50000000000000C00000009 +:100CF000000000000B800000000000080CC600127D +:100D0000000000188000FFD0000000080F800003E2 +:100D1000000000000000000000000010001F0000A4 +:100D20000000000C6BD70001000000082711001222 +:100D3000000000006690000000000010B198000460 +:100D400000000010001F00000000000C6BD7000125 +:100D5000000000080F8000040000000822000003CB +:100D6000000000082C80000C000000082D00000C82 +:100D700000000010001F00000000000C6BD70001F5 +:100D80000000001091C6000600000010001F0000C7 +:100D90000000000C6BD7000100000010BA9A2C0371 +:100DA000000000080F800004000000188000FFFC15 +:100DB00000000000259600000000000C29800000C3 +:100DC0000000000032140000000000003295000016 +:100DD0000000000573662C000000000031E32E00C7 +:100DE000000000082D800010000000188000FF8126 +:100DF00000000000230000000000000925E6FFFFBE +:100E0000000000082200000B0000000C69520000E6 +:100E10000000000C29800000000000188000FF7B0B +:100E2000000000002A000000000000082C800040A4 +:100E3000000000082D000020000000082D80011C8B +:100E400000000008220000010000001091DE0000F8 +:100E50000000000F42EA001000000010004F0004E4 +:100E600000000010B746920000000008024900127E +:100E700000000010B5840A00000000000D610000B1 +:100E800000000010BA6634640000000883050012F8 +:100E900000000010004F00020000000003490000A5 +:100EA0000000000183068C000000000083C60C00D7 +:100EB00000000010B1870013000000000B6E00005E +:100EC000000000090569FFFF00000010918A000280 +:100ED0000000000834E9FFFF000000188000FF60F8 +:100EE000000000010569140000000010918A000252 +:100EF00000000008B4E9000100000010BAE92C5518 +:100F00000000000086692C000000000002000000C4 +:100F10000000000902EAFFFF00000010000C0002C0 +:100F20000000000002040A000000000F460C00014F +:100F30000000000F0285000100000010918C01FCF0 +:100F400000000010B7040E4C000000000D6100000E +:100F5000000000000A640000000000000AE5000034 +:100F6000000000090B66FFFF000000000C000000FD +:100F7000000000000B800000000000080C8600123A +:100F8000000000080F8000030000000C2952000040 +:100F900000000010001F00000000000C6BD70001D3 +:100FA00000000008271100120000000066900000F9 +:100FB000000000002306000000000010B1980007A8 +:100FC00000000010001F00000000000C6BD70001A3 +:100FD000000000080F800004000000000000000076 +:100FE00000000010001F00000000000C6BD7000183 +:100FF00000000000321400000000000032950000E4 +:101000000000000031E32E000000000573662C0094 +:10101000000000002596000000000010B187001FAE +:101020000000000C298000000000000F0F6B00077B +:10103000000000000D690000000000000A6C0000C4 +:10104000000000000AED0000000000000B6E000030 +:10105000000000000B800000000000000C87000072 +:10106000000000188000FF2F000000010C16140083 +:10107000000000008C181400000000080C9600010D +:101080000000001091980002000000080C99000177 +:10109000000000000D190000000000000C0000001E +:1010A000000000080F800001000000102053000025 +:1010B0000000000C6952000100000010001F000039 +:1010C0000000000C6BD700010000000022C58C005E +:1010D00000000000231200000000000027110000A3 +:1010E000000000002690000000000010B8170E035A +:1010F0000000000C29800000000000188000FFEDB7 +:101100000000000082970E0000000000A3120A00F9 +:10111000000000082200001A000000082C80000CCB +:10112000000000082D00000C000000082D800010B9 +:1011300000000010001F00000000000C6BD7000131 +:10114000000000000D6E000000000003E7CF340037 +:101150000000000C298000000000001091DE00005B +:1011600000000010B18700070000000036140000E6 +:101170000000000036950000000000003716000057 +:10118000000000082C800050000000082D000030F6 +:10119000000000082D80000C000000188000FF0BEC +:1011A00000000000230000000000000925E6FFFF0A +:1011B000000000000B6E000000000003E7CF2C00D1 +:1011C000000000082200001B0000000C6952000013 +:1011D0000000000C29800000000000188000FF03C0 +:1011E000000000002A000000000000188000FF013D +:1011F000000000002A0000000000000C2980000010 +:101200000000001091DE0000000000082C80001A91 +:10121000000000082D00001A0000000573660000A1 +:10122000000000082D800002000000003180000056 +:101230000000001091DE0000000000082C80000C6F +:10124000000000082D00000C000000082D800004A4 +:10125000000000188000FEF400000008066600018F +:1012600000000010BA9A1972000000000A64000021 +:10127000000000000AE50000000000090B66FFFF07 +:10128000000000000C000000000000000B800000C7 +:10129000000000080CC60012000000188000FF1DAE +:1012A000000000080F8000030000000000000000A4 +:1012B00000000010001F00000000000C6BD70001B0 +:1012C00000000008271100120000000066900000D6 +:1012D00000000010919B32000000001002930000FB +:1012E00000000010B198000300000010001F000073 +:1012F0000000000C6BD70001000000080F80000404 +:101300000000000C2980000000000010001F0000F9 +:101310000000000C6BD7000100000010BA9A2C00EE +:101320000000000031E32E00000000000B800000F0 +:10133000000000008CCC8C0000000010B5CC8C02AA +:10134000000000080C800001000000188000FF076A +:10135000000000080F800003000000102053000070 +:101360000000000C695200010000000022C58C0042 +:1013700000000010001F00000000000C6BD70001EF +:10138000000000002711000000000000269000006F +:1013900000000000231B000000000010B1980003B3 +:1013A00000000010001F00000000000C6BD70001BF +:1013B000000000080F800004000000082200000365 +:1013C000000000082C80000C000000082D00000C1C +:1013D00000000010001F00000000000C6BD700018F +:1013E00000000000259600000000000C298000008D +:1013F00000000000321400000000000032950000E0 +:101400000000000573662C000000000031E32E0090 +:10141000000000082D800010000000188000FEBBB6 +:10142000000000188000FEBA000000002A00000042 +:1014300000000010001F00000000000C6BD700012E +:10144000000000000F008000000000080F8000076F +:10145000000000188000001C00000000280A0000A6 +:101460000000000005020000000000082200000942 +:1014700000000000290000000000000F6568001057 +:1014800000000000248A000000000003F66C9400B5 +:1014900000000010B972A0040000000C73E70019EE +:1014A0000000000C21420004000000003CF8000095 +:1014B0000000000C298000000000001020530000F4 +:1014C00000000008220000080000000C6142000437 +:1014D00000000018000A00000000000005020000E3 +:1014E0000000000C614200000000001001420003F7 +:1014F0000000000C33E7001D0000000C61420002F8 +:1015000000000018000A0000000000002A0000008F +:1015100000000010001F00000000000C6BD700014D +:101520000000000F0F470007000000080F800008B0 +:101530000000000C2980000000000010001F0000C7 +:101540000000000C6BD70001000000188000FE9521 +:101550000000000033510000000000002A000000DD +:1015600000000010B1C600250000000F0F5000075A +:10157000000000000A600000000000000AE1000016 +:101580000000000F4B620008000000090B1600FF6E +:101590000000000F4C620010000000000D6200000F +:1015A000000000090D1A00FF0000001007500003A2 +:1015B0000000000C0D1A00080000000C0B160008BB +:1015C000000000000CC60000000000000B800000BE +:1015D0000000000006980000000000080F800003D3 +:1015E0000000001006C200040000000C29000002E8 +:1015F00000000010264200020000000C29520003E7 +:10160000000000082200000100000010001F000080 +:101610000000000C6BD7000100000000231B00003D +:101620000000000027111A00000000006690000072 +:101630000000000C2952000000000010B197320A8F +:101640000000000C29800000000000000698000047 +:1016500000000010205300000000000C295200037D +:101660000000000022C58C0000000010001F0000D8 +:101670000000000C6BD70001000000080F80000381 +:10168000000000188000FFF100000010B1C8001336 +:1016900000000010B1C600030000000C298000000B +:1016A00000000010205300000000000C2952000030 +:1016B0000000000C295200030000001006C20002C6 +:1016C0000000000C295200020000000022C58C001E +:1016D00000000000276500000000000026E4000074 +:1016E000000000082200001600000010B1C6000330 +:1016F000000000002348000000000010B180000539 +:1017000000000000234800000000000C29800000B9 +:101710000000000F0F5000070000001880000012AA +:1017200000000008220000160000000C29800000C4 +:1017300000000000301400000000000030950000A0 +:101740000000001007500003000000090B1600FF06 +:10175000000000090D1A00FF0000000F31160008FC +:10176000000000003162340000000003F16230002C +:1017700000000010205F0000000000002C5100005D +:10178000000000092CD1007F000000082CD90000C7 +:10179000000000082D000000000000082D80000C53 +:1017A00000000000000000000000001091DE0000BA +:1017B0000000001005C20005000000080F800007AF +:1017C000000000003300000000000010001F0000B7 +:1017D0000000000C6BD70001000000188000FE43E1 +:1017E000000000002A0000000000000F0F5000075A +:1017F00000000010B1C600300000000F4742000892 +:1018000000000009070E000F00000008070E000886 +:1018100000000010001F00000000000C6BD700014A +:1018200000000008090000010000000709121C0068 +:1018300000000003CBCA9200000000000B97A2003A +:101840000000000742171C00000000000B0400000D +:101850000000000F0A840003000000000A959C00AD +:10186000000000004A009A000000000882120001F7 +:10187000000000010C170800000000000C978C000D +:101880000000000002180000000000080D00FFFF2B +:10189000000000080F8000060000000C2900000076 +:1018A0000000001006C200040000000C29520002D3 +:1018B00000000010264200020000000C2952000324 +:1018C000000000082200000100000010001F0000BE +:1018D0000000000C6BD7000100000010B197320D22 +:1018E00000000000231B000000000000271108007A +:1018F00000000000669000000000000C298000003D +:10190000000000000218000000000010205300003A +:101910000000000C295200030000000022C5360020 +:1019200000000010001F00000000000C6BD7000139 +:10193000000000080F800006000000188000FFF281 +:1019400000000000231B0000000000002711080019 +:10195000000000006690000000000010B1C8000BFD +:101960000000000C2980000000000010205300003F +:101970000000000C295200000000000C2952000356 +:101980000000001006C200020000000C29520002F4 +:101990000000000022C58C00000000002765000048 +:1019A0000000000026E400000000000023480000C2 +:1019B00000000008220000170000000C2980000031 +:1019C00000000010001F00000000000C6BD7000199 +:0819D000000000188000FE0475 +:00000001FF +/* + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004 - 2009 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ diff --git a/firmware/bnx2x-e1-5.2.13.0.fw.ihex b/firmware/bnx2x-e1-5.2.13.0.fw.ihex deleted file mode 100644 index 651f4346d89efff9410e33386ce7a34a396d85e4..0000000000000000000000000000000000000000 --- a/firmware/bnx2x-e1-5.2.13.0.fw.ihex +++ /dev/null @@ -1,10191 +0,0 @@ -:10000000000028B0000000600000068800002918E9 -:100010000000161400002FA800000098000045C042 -:10002000000073C400004660000000CC0000BA2845 -:1000300000009A700000BAF80000009400015570AA -:10004000000057BC00015608000000B80001ADC810 -:100050000000CE200001AE880000000400027CB049 -:10006000020400480000000F020400540000004594 -:1000700002040058000000840204005C0000000636 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000060400CC0000000418 -:10010000020400DC00100000020400E012140000F1 -:10011000020400E422140000020400E8321400008B -:10012000060400EC000000040104012400000000AB -:1001300001040128000000000104012C000000005F -:10014000010401300000000002040004000000FF70 -:1001500002040008000000FF0204000C000000FF81 -:1001600002040010000000FF02040014000000FF61 -:1001700002040018000000FF0204001C000000FF41 -:1001800002040020000000FF020400240000003EE2 -:1001900002040028000000000204002C0000003FC0 -:1001A000020400300000003F020400340000003F61 -:1001B00002040038000000000204003C0000003F80 -:1001C000020400400000003F020400440000003F21 -:1001D00002042008000004110204200C00000400A6 -:1001E000020420100000040402042014000004197A -:1001F0000204201C0000FFFF020420200000FFFF7B -:10020000020420240000FFFF020420280000FFFF5A -:1002100006042038000000020204204000000034E0 -:100220000204204400000035060420480000007C41 -:100230000204223807FFFFFF0204223C0000003FB7 -:100240000204224007FFFFFF020422440000000FC7 -:1002500001042248000000000104224C00000000BC -:10026000010422500000000001042254000000009C -:1002700001042258000000000104225C000000007C -:10028000010422600000000001042264000000005C -:1002900001042268000000000104226C000000003C -:1002A000010422700000000001042274000000001C -:1002B00001042278000000000104227C00000000FC -:1002C000020424BC000000010C042000000003E82C -:1002D0000A042000000000010B0420000000000AB6 -:1002E0000205004400000020020500480000003222 -:1002F000020500900215002002050094021500205E -:1003000002050098000000300205009C0810000063 -:10031000020500A000000033020500A40000003028 -:10032000020500A800000031020500AC0000000238 -:10033000020500B000000005020500B40000000640 -:10034000020500B800000002020500BC0000000227 -:10035000020500C000000000020500C40000000506 -:10036000020500C800000002020500CC00000002E7 -:10037000020500D000000002020500D400000001C8 -:1003800002050114000000010205011C000000012B -:100390000205012000000002020502040000000125 -:1003A0000205020C0000004002050210000000409F -:1003B0000205021C000000200205022000000013BC -:1003C0000205022400000020060502400000000A89 -:1003D0000405028000200000020500500000000714 -:1003E0000205005400000007020500580000000844 -:1003F0000205005C00000008060500600000000423 -:10040000020500D800000006020500E00000000D13 -:10041000020500E40000002D020500E800000007CE -:10042000020500EC00000027020500F000000007B4 -:10043000020500F400000027020500F80000000794 -:10044000020500FC00000027020500040000000176 -:1004500002050008000000010205000C0000000178 -:100460000205001000000001020500140000000158 -:1004700002050018000000010205001C0000000138 -:100480000205002000000001020500240000000118 -:1004900002050028000000010205002C00000001F8 -:1004A00002050030000000010205003400000001D8 -:1004B00002050038000000010205003C00000001B8 -:1004C00002050040000000010406100002000020A8 -:1004D000020600DC00000001010600D80000000058 -:1004E0000406020000030220020600DC00000000F7 -:1004F00002060068000000B802060078000001143F -:10050000010600B800000000010600C8000000005D -:100510000206006C000000B80206007C0000011416 -:10052000010600BC00000000010600CC0000000035 -:100530000718040000950000081807600014022343 -:10054000071C000034D40000071C800034CF0D3697 -:10055000071D00000A191A6A081D14605D7402253F -:100560000118000000000000011800040000000055 -:1005700001180008000000000118000C0000000035 -:100580000118001000000000011800140000000015 -:1005900002180020000000010218002400000002E0 -:1005A00002180028000000030218002C00000000C0 -:1005B000021800300000000402180034000000019E -:1005C00002180038000000000218003C0000000182 -:1005D000021800400000000402180044000000005F -:1005E00002180048000000010218004C000000033F -:1005F0000218005000000000021800540000000122 -:1006000002180058000000040218005C00000000FE -:1006100002180060000000010218006400000003DE -:1006200002180068000000000218006C00000001C1 -:10063000021800700000000402180074000000009E -:1006400002180078000000040218007C000000037B -:100650000618008000000002021800A400003FFFFE -:10066000021800A8000003FF021802240000000086 -:1006700002180234000000000218024C00000000C2 -:10068000021802E4000000FF061810000000040039 -:10069000021B8BC000000001021B80000000003420 -:1006A000021B804000000018021B80800000000C2C -:1006B000021B80C0000000200C1B83000007A1204B -:1006C0000A1B8300000001380B1B83000000138805 -:1006D000021B83C0000001F4061A2000000000B2D3 -:1006E000061A23C800000181041A29CC0001022740 -:1006F000061A1020000000C8061A100000000002B0 -:10070000061A1E3800000002061A1E300000000201 -:10071000061A080000000002061A0808000000027D -:10072000061A081000000004041A1FB00005022871 -:10073000041A4CB00008022D061A22C8000000203E -:10074000061A400000000124021A4920000000009F -:10075000061A14000000000A061A145000000006D1 -:10076000061A150000000002041A150800050235DB -:10077000061A151C00000009061A15800000001456 -:10078000061A09C000000048061A0800000000020E -:10079000061A08200000000E041A1FB00002023AD8 -:1007A000061A2C2800000002061A23480000002028 -:1007B000061A449000000124021A49240000000097 -:1007C000061A14280000000A061A14680000000621 -:1007D000061A154000000002041A15480005023CE4 -:1007E000061A155C00000009061A15D00000001456 -:1007F000061A0AE000000048061A08080000000275 -:10080000061A08580000000E041A1FB80002024120 -:10081000061A2C30000000020200A2800000000135 -:100820000200A294071D29110200A29800000000F6 -:100830000200A29C009C04240200A2A00000000070 -:100840000200A2A4000002090200A4FCFF000000B4 -:10085000020100B400000001020100B80000000124 -:10086000020100DC000000010201010000000001A3 -:1008700002010104000000010201007C00300000C0 -:1008800002010084000000280201008C000000002A -:1008900002010130000000040201025C00000001BE -:1008A000020103280000000002010554000000308E -:1008B000020100C400000001020100CC00000001A0 -:1008C000020100F800000001020100F00000000138 -:1008D00002010080003000000201008800000028B2 -:1008E0000201009000000000020101340000000439 -:1008F000020102DC000000010201032C00000000E4 -:100900000201056400000030020100C8000000017F -:10091000020100D000000001020100FC0000000103 -:10092000020100F400000001020C10000000002091 -:10093000020C200800000A11020C200C00000A0022 -:10094000020C201000000A04020C201C0000FFFF13 -:10095000020C20200000FFFF020C20240000FFFFFB -:10096000020C20280000FFFF060C203800000002C7 -:10097000020C204000000034020C2044000000352E -:10098000020C204800000020020C204C0000002136 -:10099000020C205000000022020C20540000002312 -:1009A000020C205800000024020C205C00000025EE -:1009B000020C206000000026020C206400000027CA -:1009C000020C206800000028020C206C00000029A6 -:1009D000020C20700000002A020C20740000002B82 -:1009E000060C207800000056020C21D00000000107 -:1009F000020C21D400000001020C21D800000001EB -:100A0000020C21DC00000001020C21E000000001CA -:100A1000020C21E400000001020C21E800000001AA -:100A2000020C21EC00000001020C21F0000000018A -:100A3000020C21F400000001060C21F80000001057 -:100A4000020C223807FFFFFF020C223C0000003F8F -:100A5000020C224007FFFFFF020C22440000000F9F -:100A6000010C224800000000010C224C0000000094 -:100A7000010C225000000000010C22540000000074 -:100A8000010C225800000000010C225C0000000054 -:100A9000010C226000000000010C22640000000034 -:100AA000010C226800000000010C226C0000000014 -:100AB000010C227000000000010C227400000000F4 -:100AC000010C227800000000010C227C00000000D4 -:100AD000020C24BC000000010C0C2000000003E804 -:100AE0000A0C2000000000010B0C20000000000A8E -:100AF000020C400800000365020C400C0000035487 -:100B0000020C401000000358020C40140000037552 -:100B1000020C401C0000FFFF020C40200000FFFF01 -:100B2000020C40240000FFFF020C40280000FFFFE1 -:100B3000020C403800000046020C403C000000055A -:100B4000060C40400000005E020C41B800000001AD -:100B5000060C41BC0000001F020C423807FFFFFFDB -:100B6000020C423C0000003F020C424007FFFFFF26 -:100B7000020C42440000000F010C4248000000003B -:100B8000010C424C00000000010C4250000000002B -:100B9000010C425400000000010C4258000000000B -:100BA000010C425C00000000010C426000000000EB -:100BB000010C426400000000010C426800000000CB -:100BC000010C426C00000000010C427000000000AB -:100BD000010C427400000000010C4278000000008B -:100BE000010C427C00000000010C4280000000006B -:100BF000020C44C0000000010C0C4000000003E89F -:100C00000A0C4000000000010B0C40000000000A2C -:100C1000020D004400000032020D008C021500207D -:100C2000020D009002150020020D00940810000033 -:100C3000020D009800000033020D009C000000022D -:100C4000020D00A000000000020D00A4000000053D -:100C5000020D00A800000005060D00AC0000000217 -:100C6000020D00B400000002020D00B800000003F5 -:100C7000020D00BC00000002020D00C000000001D7 -:100C8000020D00C800000002020D00CC00000002AE -:100C9000020D010800000001020D015C00000001CE -:100CA000020D016400000001020D01680000000255 -:100CB000020D020400000001020D020C00000020E1 -:100CC000020D021000000040020D0214000000405E -:100CD000020D022000000003020D02240000001893 -:100CE000060D028000000012040D030000240243E0 -:100CF000020D004C00000001020D00500000000237 -:100D0000020D005400000008020D00580000000809 -:100D1000060D005C00000004020D00C40000000489 -:100D2000020D011400000009020D01180000002945 -:100D3000020D011C0000000A020D01200000002A23 -:100D4000020D012400000007020D01280000002709 -:100D5000020D012C00000007020D013000000027E9 -:100D6000020D01340000000C020D01380000002CBF -:100D7000020D013C0000000C020D01400000002C9F -:100D8000020D01440000000C020D01480000002C7F -:100D9000020D000400000001020D00080000000127 -:100DA000020D000C00000001020D00100000000107 -:100DB000020D001400000001020D001800000001E7 -:100DC000020D001C00000001020D002000000001C7 -:100DD000020D002400000001020D002800000001A7 -:100DE000020D002C00000001020D00300000000187 -:100DF000020D003400000001020D00380000000167 -:100E0000020D003C00000001020E004C0000003208 -:100E1000020E009402150020020E00980215002018 -:100E2000020E009C00000030020E00A0081000001E -:100E3000020E00A400000033020E00A800000030E3 -:100E4000020E00AC00000031020E00B000000002F3 -:100E5000020E00B400000004020E00B80000000002 -:100E6000020E00BC00000002020E00C000000002E2 -:100E7000020E00C400000000020E00C800000002C4 -:100E8000020E00CC00000007020E00D0000000029D -:100E9000020E00D400000002020E00D80000000183 -:100EA000020E00E400000001020E014400000001F7 -:100EB000020E014C00000001020E01500000000271 -:100EC000020E020400000001020E020C00000040AD -:100ED000020E021000000040020E021C000000047E -:100EE000020E022000000020020E02240000000E6C -:100EF000020E02280000001B060E03000000001274 -:100F0000040E0280001B0267020E00540000000C59 -:100F1000020E005800000009020E005C0000000FE5 -:100F2000020E006000000010060E006400000004C5 -:100F3000020E00DC00000003020E01100000000F92 -:100F4000020E01140000002F020E01180000000E16 -:100F5000020E011C0000002E020E00040000000121 -:100F6000020E000800000001020E000C000000014B -:100F7000020E001000000001020E0014000000012B -:100F8000020E001800000001020E001C000000010B -:100F9000020E002000000001020E002400000001EB -:100FA000020E002800000001020E002C00000001CB -:100FB000020E003000000001020E003400000001AB -:100FC000020E003800000001020E003C000000018B -:100FD000020E004000000001020E0044000000016B -:100FE0000730040000C900000830076800130282BF -:100FF00007340000334B00000734800037090CD35E -:101000000735000030161A96083572F051A2028496 -:10101000013000000000000001300004000000006A -:1010200001300008000000000130000C000000004A -:10103000013000100000000001300014000000002A -:1010400002300020000000010230002400000002F5 -:1010500002300028000000030230002C00000000D5 -:1010600002300030000000040230003400000001B3 -:1010700002300038000000000230003C0000000197 -:101080000230004000000004023000440000000074 -:1010900002300048000000010230004C0000000354 -:1010A0000230005000000000023000540000000137 -:1010B00002300058000000040230005C0000000014 -:1010C00002300060000000010230006400000003F4 -:1010D00002300068000000000230006C00000001D7 -:1010E00002300070000000040230007400000000B4 -:1010F00002300078000000040230007C0000000391 -:101100000630008000000002023000A400003FFF13 -:10111000023000A8000003FF02300224000000009B -:1011200002300234000000000230024C00000000D7 -:10113000023002E40000FFFF06302000000008003B -:1011400002338BC000000001023380000000001A4F -:10115000023380400000004E023380800000001007 -:10116000023380C0000000200C3383000007A12060 -:101170000A338300000001380B338300000013881A -:10118000023383C0000001F40C3383801DCD650061 -:101190000A3383800004C4B40B338380004C4B407B -:1011A00006321AA0000000C206321020000000C85B -:1011B0000632100000000002063214000000004059 -:1011C00006325098000000040632508000000005EE -:1011D00004325094000102860632500000000020C4 -:1011E00004322830000202870233080001000000A8 -:1011F00004330C00001002890233080000000000D4 -:1012000004330C400010029906321500000000B4AF -:1012100002321DC80000000006324000000000D865 -:10122000063217D0000000B402321DCC00000000CE -:1012300006324360000000D807200400009200003E -:1012400008200780001002A9072400002CD100000C -:10125000072480002AE50B350824DC6062DA02AB43 -:101260000120000000000000012000040000000038 -:1012700001200008000000000120000C0000000018 -:1012800001200010000000000120001400000000F8 -:1012900002200020000000010220002400000002C3 -:1012A00002200028000000030220002C00000000A3 -:1012B0000220003000000004022000340000000181 -:1012C00002200038000000000220003C0000000165 -:1012D0000220004000000004022000440000000042 -:1012E00002200048000000010220004C0000000322 -:1012F0000220005000000000022000540000000105 -:1013000002200058000000040220005C00000000E1 -:1013100002200060000000010220006400000003C1 -:1013200002200068000000000220006C00000001A4 -:101330000220007000000004022000740000000081 -:1013400002200078000000040220007C000000035E -:101350000620008000000002022000A400003FFFE1 -:10136000022000A8000003FF022002240000000069 -:1013700002200234000000000220024C00000000A5 -:10138000022002E40000FFFF062020000000080009 -:1013900002238BC000000001022380000000001027 -:1013A00002238040000000120223808000000030F1 -:1013B000022380C00000000E022383C0000001F45D -:1013C000062250000000004206221020000000C843 -:1013D000062210000000000206222000000000C0CB -:1013E000062225C00000024004222EC8000802ADDB -:1013F00002230800013FFFFF04230C00001002B588 -:10140000022308000000000004230C40001002C565 -:1014100006223040000000A00622354000000010E7 -:10142000062236C000000030062240000000020004 -:10143000062235C00000002006223840000000309F -:1014400006223000000000080222511800000000AF -:10145000062223000000000E0622241000000030A7 -:10146000062232C0000000A00622358000000010D5 -:1014700006223780000000300622480000000200EB -:10148000062236400000002006223900000000300D -:1014900006223020000000080222511C000000003B -:1014A000062223380000000E062224D0000000305F -:1014B00002161000000000280217000800000002B9 -:1014C0000217002C000000030217003C000000047B -:1014D0000217004400000008021700480000000244 -:1014E0000217004C0000009002170050000000900E -:1014F00002170054008000900217005808140000E2 -:10150000021700600000008A0217006400000080DB -:1015100002170068000000810217006C00000080C4 -:10152000021700700000000602170078000007D0C4 -:101530000217007C0000076C02170038007C1004C2 -:10154000021700040000000F0616402400000002ED -:10155000021640700000001C021642080000000144 -:101560000216421000000001021642200000000195 -:10157000021642280000000102164230000000015D -:10158000021642380000000102164260000000010D -:101590000C16401C0003D0900A16401C0000009C52 -:1015A0000B16401C000009C4021640300000000861 -:1015B000021640340000000C0216403800000010F3 -:1015C0000216404400000020021640000000000106 -:1015D000021640D800000001021640080000000179 -:1015E0000216400C0000000102164010000000012D -:1015F00002164240000000000216424800000000AF -:101600000616427000000002021642500000000060 -:101610000216425800000000061642800000000238 -:1016200002166008000006140216600C0000060096 -:1016300002166010000006040216601C0000FFFF86 -:10164000021660200000FFFF021660240000FFFF6A -:10165000021660280000FFFF02166038000000201C -:101660000216603C000000200216604000000034BA -:101670000216604400000035021660480000002396 -:101680000216604C00000024021660500000002585 -:101690000216605400000026021660580000002761 -:1016A0000216605C00000029021660600000002A3B -:1016B000021660640000002B021660680000002C17 -:1016C0000216606C0000002D0616607000000052CB -:1016D000021661B800000001061661BC0000001F80 -:1016E0000216623807FFFFFF0216623C0000003F4F -:1016F0000216624007FFFFFF021662440000000F5F -:1017000001166248000000000116624C0000000053 -:101710000116625000000000011662540000000033 -:1017200001166258000000000116625C0000000013 -:1017300001166260000000000116626400000000F3 -:1017400001166268000000000116626C00000000D3 -:1017500001166270000000000116627400000000B3 -:1017600001166278000000000116627C0000000093 -:10177000021664BC000000010C166000000003E8C3 -:101780000A166000000000010B1660000000000A4D -:10179000021680400000000602168044000000058A -:1017A000021680480000000A0216804C0000000566 -:1017B0000216805400000002021680CC00000004D3 -:1017C000021680D000000004021680D4000000043D -:1017D000021680D800000004021680DC000000041D -:1017E000021680E000000004021680E400000004FD -:1017F000021680E8000000040216880400000004BD -:10180000021680300000007C021680340000003D8B -:10181000021680380000003F0216803C0000009C49 -:10182000021680F000000007061680F40000000594 -:101830000216880C01010101021681080000000057 -:101840000216810C00000004021681100000000442 -:1018500002168114000000020216881008012004FC -:1018600002168118000000050216811C0000000508 -:1018700002168120000000050216812400000005E8 -:101880000216882C2008100102168128000000088A -:101890000216812C000000060216813000000007AD -:1018A0000216813400000000021688300101012078 -:1018B0000616813800000004021688340101010177 -:1018C0000616814800000004021688380101010153 -:1018D00006168158000000040216883C010101012F -:1018E00006168168000000030216817400000001E2 -:1018F00002168840010101010216817800000001F2 -:101900000216817C000000010216818000000001A7 -:1019100002168184000000010216884401010101C1 -:1019200002168188000000010216818C000000046C -:10193000021681900000000402168194000000024B -:10194000021688480801200402168198000000054C -:101950000216819C00000005021681A0000000050F -:10196000021681A400000005021688142008100148 -:10197000021681A800000008021681AC00000006D3 -:10198000021681B000000007021681B400000001B9 -:101990000216881801010120021681B8000000011A -:1019A000021681BC00000001021681C00000000187 -:1019B000021681C4000000010216881C0101010109 -:1019C000021681C800000001021681CC000000014F -:1019D000021681D000000001021681D4000000012F -:1019E0000216882001010101021681D800000001C1 -:1019F000021681DC00000001021681E000000001F7 -:101A0000021681E400000001021688240101010190 -:101A1000021681E800000001021681EC00000001BE -:101A2000021681F000000001021688280101010160 -:101A300002168240FFFF003F0616824400000002AB -:101A40000216824CFFFF003F021682500000010088 -:101A5000021682540000010006168258000000029F -:101A600002168260000000C002168264000000C0FE -:101A70000216826800001E000216826C00001E0022 -:101A800002168270000040000216827400004000BE -:101A900002168278000080000216827C000080001E -:101AA00002168280000020000216828400002000BE -:101AB0000616828800000007021682A400000001BA -:101AC000061682A80000000A021681F400000C0825 -:101AD000021681F800000040021681FC000001009F -:101AE0000216820000000020021682040000001787 -:101AF00002168208000000800216820C000002001C -:101B0000021682100000000002168218FFFF01FF7B -:101B100002168214FFFF01FF0216823C0000001330 -:101B2000021680900000013F021680600000014014 -:101B30000216806400000140061680680000000262 -:101B400002168070000000C00616807400000007B6 -:101B50000216809C00000048021680A00000004889 -:101B6000061680A400000002021680AC00000048A7 -:101B7000061680B0000000070216823800008000C0 -:101B800002168234000025E40216809400007FFFD4 -:101B900002168220000000070216821C00000007C7 -:101BA000021682280000000002168224FFFFFFFFB9 -:101BB00002168230000000000216822CFFFFFFFF99 -:101BC000021680EC000000FF02140000000000017B -:101BD0000214000C0000000102140040000000018B -:101BE0000214004400007FFF0214000C00000000FB -:101BF00002140000000000000214006C000000004D -:101C00000214000400000001021400300000000172 -:101C100002140004000000000214005C0000000038 -:101C2000021400080000000102140034000000014A -:101C30000214000800000000021400600000000010 -:101C40000202005800000032020200A0031500202A -:101C5000020200A403150020020200A801000030C7 -:101C6000020200AC08100000020200B000000033C5 -:101C7000020200B400000030020200B8000000318F -:101C8000020200BC00000003020200C000000006C7 -:101C9000020200C400000003020200C800000003AA -:101CA000020200CC00000002020200D0000000008E -:101CB000020200D400000002020200DC000000006A -:101CC000020200E000000006020200E4000000043E -:101CD000020200E800000002020200EC0000000224 -:101CE000020200F000000001020200FC00000006F9 -:101CF0000202012000000000020201340000000284 -:101D0000020201B0000000010202020C000000010A -:101D10000202021400000001020202180000000288 -:101D200002020404000000010202040C0000004052 -:101D300002020410000000400202041C0000000423 -:101D4000020204200000002002020424000000021D -:101D5000020204280000001F060205000000001215 -:101D600004020480001F02D5020200600000000F80 -:101D70000202006400000007020200680000000B7D -:101D80000202006C0000000E060200700000000459 -:101D9000020200F40000000402020004000000013E -:101DA00002020008000000010202000C0000000115 -:101DB00002020010000000010202001400000001F5 -:101DC00002020018000000010202001C00000001D5 -:101DD00002020020000000010202002400000001B5 -:101DE00002020028000000010202002C0000000195 -:101DF0000202003000000001020200340000000175 -:101E000002020038000000010202003C0000000154 -:101E10000202004000000001020200440000000134 -:101E200002020048000000010202004C0000000114 -:101E3000020200500000000102020108000000C878 -:101E40000202011800000002020201C400000000AA -:101E5000020201CC00000000020201D400000002D6 -:101E6000020201DC00000002020201E4000000FFA7 -:101E7000020201EC000000FF0202010C000000C899 -:101E80000202011C00000002020201C80000000062 -:101E9000020201D000000000020201D8000000028E -:101EA000020201E000000002020201E8000000FF5F -:101EB000020201F0000000FF0728040000B5000046 -:101EC00008280768001302F4072C000035D500002D -:101ED000072C80003A3E0D76072D00003B471C067C -:101EE000072D800022BC2AD8082DC770471202F6A1 -:101EF000012800000000000001280004000000008C -:101F000001280008000000000128000C000000006B -:101F1000012800100000000001280014000000004B -:101F20000228002000000001022800240000000216 -:101F300002280028000000030228002C00000000F6 -:101F400002280030000000040228003400000001D4 -:101F500002280038000000000228003C00000001B8 -:101F60000228004000000004022800440000000095 -:101F700002280048000000010228004C0000000375 -:101F80000228005000000000022800540000000158 -:101F900002280058000000040228005C0000000035 -:101FA0000228006000000001022800640000000315 -:101FB00002280068000000000228006C00000001F8 -:101FC00002280070000000040228007400000000D5 -:101FD00002280078000000040228007C00000003B2 -:101FE0000628008000000002022800A400003FFF35 -:101FF000022800A8000003FF0228022400000000BD -:1020000002280234000000000228024C00000000F8 -:10201000022802E40000FFFF06282000000008005C -:10202000022B8BC000000001022B8000000000008A -:10203000022B804000000018022B80800000000C62 -:10204000022B80C0000000660C2B83000007A1203B -:102050000A2B8300000001380B2B8300000013883B -:10206000022B83C0000001F40C2B8340000001F41C -:102070000A2B8340000000000B2B8340000000056A -:102080000A2B83800004C4B40C2B83801DCD650013 -:102090000B2B8380004C4B40062A3C400000000480 -:1020A000042A3C50000202F8062A300000000048D2 -:1020B000062A1020000000C8062A100000000002B6 -:1020C000062A31280000008E022A33680000000032 -:1020D000042A3370000202FA042A3A70000402FC57 -:1020E000042A3D0000020300042A15000002030236 -:1020F000062A150800000100022A197000000000DD -:10210000022A197800000000042A19600002030462 -:10211000062A4AC000000002062A4B000000000404 -:10212000042A1F4800020306022B080000000000DA -:10213000042B0C0000100308022B08000100000013 -:10214000042B0C4000080318022B080002000000BA -:10215000042B0C6000080320062A3A8000000014BB -:10216000062A3B2000000024062A14000000000A72 -:10217000062A145000000006062A3378000000D812 -:10218000022A3A3800000000042A3C5800020328C2 -:10219000042A3C680010032A062A5020000000028E -:1021A000062A503000000002062A500000000002FB -:1021B000062A501000000002022A504000000000D1 -:1021C000062A50480000000E022A50B80000000104 -:1021D000042A4AC80002033A062A4B1000000042B3 -:1021E000062A4D2000000004062A3AD00000001400 -:1021F000062A3BB000000024062A14280000000A2A -:10220000062A146800000006062A36D8000000D806 -:10221000022A3A3C00000000042A3C600002033C11 -:10222000042A3CA80010033E062A502800000002A1 -:10223000062A503800000002062A5008000000025A -:10224000062A501800000002022A50440000000034 -:10225000062A50800000000E022A50BC0000000137 -:10226000042A4AD00002034E062A4C1800000042FD -:10227000062A4D3000000004021010080000000182 -:102280000210101000000264021010000003D000C1 -:10229000021010040000003D091018000200035055 -:1022A00009101100002005500610118000000002E6 -:1022B0000910118800060570061011A00000001812 -:1022C000021010100000000006102400000000E0C2 -:1022D0000210201C0000000002102020000000015D -:1022E000021020C0000000010210200400000001C4 -:1022F000021020080000000109103C0000050576CE -:1023000009103C200005057B0910380000050580F8 -:1023100002104028000000100210404400003FFF5F -:102320000210405800280000021040840084924AA5 -:1023300002104058000000000610806800000004F1 -:1023400002108000000010800610802800000002AB -:102350000210803800000010021080400000FFFFD3 -:10236000021080440000FFFF0210805000000000B7 -:102370000210810000000000061081200000000211 -:1023800002108008000002B502108010000000005A -:10239000061082000000004A021081080001FFFFC1 -:1023A00006108140000000020210800000001A8028 -:1023B0000610900000000024061091200000004A42 -:1023C000061093700000004A061095C00000004AF5 -:1023D000021080040000108006108030000000020F -:1023E0000210803C00000010021080480000FFFF37 -:1023F0000210804C0000FFFF02108054000000001B -:102400000210810400000000061081280000000274 -:102410000210800C000002B50210801400000000C1 -:10242000061084000000004A0210810C0001FFFF2A -:1024300006108148000000020210800400001A808B -:102440000610909000000024061092480000004AF8 -:10245000061094980000004A061096E80000004A12 -:102460000212049000E383400212051400003C10A5 -:10247000021205200000000202120494FFFFFFFF79 -:1024800002120498FFFFFFFF0212049CFFFFFFFFF0 -:10249000021204A0FFFFFFFF021204A4FFFFFFFFD0 -:1024A000021204A8FFFFFFFF021204ACFFFFFFFFB0 -:1024B000021204B0FFFFFFFF021204B8FFFFFFFF8C -:1024C000021204BCFFFFFFFF021204C0FFFFFFFF68 -:1024D000021204C4FFFFFFFF021204C8FFFFFFFF48 -:1024E000021204CCFFFFFFFF021204D0FFFFFFFF28 -:1024F000021204DCFFFFFFFF021204E0FFFFFFFFF8 -:10250000021204E4FFFFFFFF021204E8FFFFFFFFD7 -:10251000021204ECFFFFFFFF021204F0FFFFFFFFB7 -:10252000021204F4FFFFFFFF021204F8FFFFFFFF97 -:10253000021204FCFFFFFFFF02120500FFFFFFFF76 -:1025400002120504FFFFFFFF02120508FFFFFFFF55 -:102550000212050CFFFFFFFF02120510FFFFFFFF35 -:10256000021204D4FFFF3330021204D8FFFF3340BD -:10257000021204B4F00030000212039000000008C0 -:102580000212039C00000008061203A000000002D3 -:10259000021203BC00000004021203C40000000485 -:1025A000021203D000000000021203DC0000000051 -:1025B0000212036C00000001021203680000003FD9 -:1025C000021201BC00000040021201C00000180805 -:1025D000021201C400000803021201C8000008032F -:1025E000021201CC00000040021201D000000003E2 -:1025F000021201D400000803021201D800000803EF -:10260000021201DC00000803021201E000010003D5 -:10261000021201E400000803021201E800000803AE -:10262000021201EC00000003021201F0000000039E -:10263000021201F400000003021201F8000000037E -:10264000021201FC0000000302120200000000035D -:10265000021202040000000302120208000000033C -:102660000212020C0000000302120210000000031C -:1026700002120214000000030212021800000003FC -:102680000212021C000000030212022000000003DC -:102690000212022400000003021202280000240398 -:1026A0000212022C0000002F02120230000000096A -:1026B00002120234000000190212023800000184E4 -:1026C0000212023C000001830212024000000306D5 -:1026D0000212024400000019021202480000000623 -:1026E0000212024C00000306021202500000030610 -:1026F00002120254000003060212025800000C8667 -:102700000212025C000003060212026000000306CF -:1027100002120264000000060212026800000006B5 -:102720000212026C00000006021202700000000695 -:102730000212027400000006021202780000000675 -:102740000212027C00000006021202800000000655 -:102750000212028400000006021202880000000635 -:102760000212028C00000006021202900000000615 -:1027700002120294000000060212029800000006F5 -:102780000212029C00000006021202A000000306D2 -:10279000021202A400000013021202A800000006A8 -:1027A000021202B000001004021202B40000100471 -:1027B0000212032400106440021203280010644037 -:1027C000021201B0000000010600A0000000001687 -:1027D0000200A06CBF5C00000200A070FFF51FEFBC -:1027E0000200A0740000FFFF0200A078500003E088 -:1027F0000200A07C000000000200A0800000A000F9 -:102800000600A084000000050200A0980FE0000070 -:102810000600A09C000000140200A0EC555400002B -:102820000200A0F0555555550200A0F40000555582 -:102830000200A0F8000000000200A0FC55540000B7 -:102840000200A100555555550200A1040000555540 -:102850000200A108000000000200A22C00000000FD -:102860000600A230000000030200A0600000000784 -:102870000200A10CBF5C00000200A110FFF51FEFD9 -:102880000200A1140000FFFF0200A118500003E0A5 -:102890000200A11C000000000200A1200000A00016 -:1028A0000600A124000000050200A1380FE000008E -:1028B0000600A13C000000140200A18C5554000049 -:1028C0000200A190555555550200A19400005555A0 -:1028D0000200A198000000000200A19C55540000D5 -:1028E0000200A1A0555555550200A1A40000555560 -:1028F0000200A1A8000000000200A23C00000000AD -:102900000600A240000000030200A06400000007CF -:1029100000000000000000000000002E0000000089 -:1029200000000000000000000000000000000000A7 -:102930000000000000000000000000000000000097 -:102940000000000000000000000000000000000087 -:102950000000000000000000000000000000000077 -:102960000000000000000000000000000000000067 -:10297000002E0050000000000000000000000000D9 -:102980000000000000000000000000000000000047 -:102990000000000000000000000000000050008D5A -:1029A0000000000000000000000000000000000027 -:1029B0000000000000000000000000000000000017 -:1029C0000000000000000000008D009200920096C0 -:1029D0000096009A000000000000000000000000C7 -:1029E00000000000000000000000000000000000E7 -:1029F00000000000009A00DB00DB00E900E900F7BE -:102A000000000000000000000000000000000000C6 -:102A100000000000000000000000000000000000B6 -:102A200000000000000000000000000000000000A6 -:102A30000000000000000000000000000000000096 -:102A40000000000000000000000000000000000086 -:102A50000000000000000000000000000000000076 -:102A60000000000000000000000000000000000066 -:102A70000000000000000000000000000000000056 -:102A80000000000000000000000000000000000046 -:102A90000000000000000000000000000000000036 -:102AA0000000000000000000000000000000000026 -:102AB0000000000000000000000000000000000016 -:102AC0000000000000000000000000000000000006 -:102AD00000F700FE00000000000000000000000001 -:102AE00000000000000000000000000000000000E6 -:102AF00000000000000000000000000000000000D6 -:102B000000000000000000000000000000000000C5 -:102B100000000000000000000000000000000000B5 -:102B2000000000000000000000FE01030103010E90 -:102B3000010E01190000000000000000000000006C -:102B40000000000000000000000000000000000085 -:102B50000000000000000000000000000000000075 -:102B60000000000000000000000000000000000065 -:102B70000000000000000000000000000000000055 -:102B80000119011A00000000000000000000000010 -:102B90000000000000000000000000000000000035 -:102BA000000000000000000000000000011A0152B7 -:102BB0000000000000000000000000000000000015 -:102BC0000000000000000000000000000000000005 -:102BD000000000000000000001520176000000002B -:102BE00000000000000000000000000000000000E5 -:102BF00000000000000000000000000000000000D5 -:102C000000000000017601B5000000000000000097 -:102C100000000000000000000000000000000000B4 -:102C200000000000000000000000000000000000A4 -:102C300001B501F0000000000000000000000000ED -:102C40000000000000000000000000000000000084 -:102C500000000000000000000000000001F002354C -:102C6000023502380238023B00000000000000007C -:102C70000000000000000000000000000000000054 -:102C80000000000000000000023B02760276028095 -:102C90000280028A00000000000000000000000026 -:102CA0000000000000000000000000000000000024 -:102CB00000000000028A028B0000000000000000FB -:102CC0000000000000000000000000000000000004 -:102CD00000000000000000000000000000000000F4 -:102CE000028B029D000000000000000000000000B8 -:102CF00000000000000000000000000000000000D4 -:102D0000000000000000000000000000029D02B270 -:102D100002B202B502B502B80000000000000000D7 -:102D200000000000000000000000000000000000A3 -:102D3000000000000000000002B802E600000000F1 -:102D40000000000000000000000000000000000083 -:102D50000000000000000000000000000000000073 -:102D60000000000002E6036D00000000000000000B -:102D70000000000000000000000000000000000053 -:102D80000000000000000000000000000000000043 -:102D9000036D0374037403780378037C0000000060 -:102DA0000000000000000000000000000000000023 -:102DB000000000000000000000000000037C03BBD6 -:102DC00003BB03C303C303CB0000000000000000EB -:102DD00000000000000000000000000000000000F3 -:102DE000000000000000000003CB041F041F04319A -:102DF0000431044300000000000000000000000057 -:102E000000000000000000000000000000000000C2 -:102E1000000000000443044D00000000000000001A -:102E200000000000000000000000000000000000A2 -:102E30000000000000000000000000000000000092 -:102E4000044D0453000000000000000000000000DA -:102E50000000000000000000000000000000000072 -:102E600000000000000000000000000004530456B1 -:102E70000000000000000000000000000000000052 -:102E80000000000000000000000000000000000042 -:102E900000000000000000000456045B0000000079 -:102EA0000000000000000000000000000000000022 -:102EB0000000000000000000000000000000000012 -:102EC00000000000045B045C045C046E046E04807B -:102ED00000000000000000000000000000000000F2 -:102EE00000000000000000000000000000000000E2 -:102EF000048004ED0000000000000000000000005D -:102F000000000000000000000000000000000000C1 -:102F100000000000000000000000000004ED04EECE -:102F200004EE050205020516000000000000000086 -:102F30000000000000000000000000000000000091 -:102F40000000000000000000000000000000000081 -:102F50000000000000000000000000000000000071 -:102F60000000000000000000000000000000000061 -:102F70000000000000000000000000000000000051 -:102F80000000000000000000000000000000000041 -:102F90000000000000000000000000000000000031 -:102FA000000000000000000000010000000204C05A -:102FB0000003098000040E4000051300000617C03E -:102FC00000071C800008214000092600000A2AC0D2 -:102FD000000B2F80000C3440000D3900000E3DC066 -:102FE000000F42800010474000114C00001250C0FA -:102FF0000013558000145A4000155F00001663C08E -:103000000017688000186D4000197200001A76C021 -:10301000001B7B80001C8040001D8500001E89C0B5 -:10302000001F8E8000209340000020000000400020 -:1030300000006000000080000000A0000000C00050 -:103040000000E0000001000000012000000140003D -:1030500000016000000180000001A0000001C0002C -:103060000001E00000020000000220000002400019 -:1030700000026000000280000002A0000002C00008 -:103080000002E000000300000003200000034000F5 -:1030900000036000000380000003A0000003C000E4 -:1030A0000003E000000400000004200000044000D1 -:1030B00000046000000480000004A0000004C000C0 -:1030C0000004E000000500000005200000054000AD -:1030D00000056000000580000005A0000005C0009C -:1030E0000005E00000060000000620000006400089 -:1030F00000066000000680000006A0000006C00078 -:103100000006E00000070000000720000007400064 -:1031100000076000000780000007A0000007C00053 -:103120000007E00000080000000820000008400040 -:1031300000086000000880000008A0000008C0002F -:103140000008E0000009000000092000000940001C -:1031500000096000000980000009A0000009C0000B -:103160000009E000000A0000000A2000000A4000F8 -:10317000000A6000000A8000000AA000000AC000E7 -:10318000000AE000000B0000000B2000000B4000D4 -:10319000000B6000000B8000000BA000000BC000C3 -:1031A000000BE000000C0000000C2000000C4000B0 -:1031B000000C6000000C8000000CA000000CC0009F -:1031C000000CE000000D0000000D2000000D40008C -:1031D000000D6000000D8000000DA000000DC0007B -:1031E000000DE000000E0000000E2000000E400068 -:1031F000000E6000000E8000000EA000000EC00057 -:10320000000EE000000F0000000F2000000F400043 -:10321000000F6000000F8000000FA000000FC00032 -:10322000000FE0000010000000102000001040001F -:1032300000106000001080000010A0000010C0000E -:103240000010E000001100000011200000114000FB -:1032500000116000001180000011A0000011C000EA -:103260000011E000001200000012200000124000D7 -:1032700000126000001280000012A0000012C000C6 -:103280000012E000001300000013200000134000B3 -:1032900000136000001380000013A0000013C000A2 -:1032A0000013E0000014000000142000001440008F -:1032B00000146000001480000014A0000014C0007E -:1032C0000014E0000015000000152000001540006B -:1032D00000156000001580000015A0000015C0005A -:1032E0000015E00000160000001620000016400047 -:1032F00000166000001680000016A0000016C00036 -:103300000016E00000170000001720000017400022 -:1033100000176000001780000017A0000017C00011 -:103320000017E000001800000018200000184000FE -:1033300000186000001880000018A0000018C000ED -:103340000018E000001900000019200000194000DA -:1033500000196000001980000019A0000019C000C9 -:103360000019E000001A0000001A2000001A4000B6 -:10337000001A6000001A8000001AA000001AC000A5 -:10338000001AE000001B0000001B2000001B400092 -:10339000001B6000001B8000001BA000001BC00081 -:1033A000001BE000001C0000001C2000001C40006E -:1033B000001C6000001C8000001CA000001CC0005D -:1033C000001CE000001D0000001D2000001D40004A -:1033D000001D6000001D8000001DA000001DC00039 -:1033E000001DE000001E0000001E2000001E400026 -:1033F000001E6000001E8000001EA000001EC00015 -:10340000001EE000001F0000001F2000001F400001 -:10341000001F6000001F8000001FA000001FC000F0 -:10342000001FE000002000000020200000204000DD -:1034300000206000002080000020A0000020C000CC -:103440000020E000002100000021200000214000B9 -:1034500000216000002180000021A0000021C000A8 -:103460000021E00000220000002220000022400095 -:1034700000226000002280000022A0000022C00084 -:103480000022E00000230000002320000023400071 -:1034900000236000002380000023A0000023C00060 -:1034A0000023E0000024000000242000002440004D -:1034B00000246000002480000024A0000024C0003C -:1034C0000024E00000250000002520000025400029 -:1034D00000256000002580000025A0000025C00018 -:1034E0000025E00000260000002620000026400005 -:1034F00000266000002680000026A0000026C000F4 -:103500000026E000002700000027200000274000E0 -:1035100000276000002780000027A0000027C000CF -:103520000027E000002800000028200000284000BC -:1035300000286000002880000028A0000028C000AB -:103540000028E00000290000002920000029400098 -:1035500000296000002980000029A0000029C00087 -:103560000029E000002A0000002A2000002A400074 -:10357000002A6000002A8000002AA000002AC00063 -:10358000002AE000002B0000002B2000002B400050 -:10359000002B6000002B8000002BA000002BC0003F -:1035A000002BE000002C0000002C2000002C40002C -:1035B000002C6000002C8000002CA000002CC0001B -:1035C000002CE000002D0000002D2000002D400008 -:1035D000002D6000002D8000002DA000002DC000F7 -:1035E000002DE000002E0000002E2000002E4000E4 -:1035F000002E6000002E8000002EA000002EC000D3 -:10360000002EE000002F0000002F2000002F4000BF -:10361000002F6000002F8000002FA000002FC000AE -:10362000002FE0000030000000302000003040009B -:1036300000306000003080000030A0000030C0008A -:103640000030E00000310000003120000031400077 -:1036500000316000003180000031A0000031C00066 -:103660000031E00000320000003220000032400053 -:1036700000326000003280000032A0000032C00042 -:103680000032E0000033000000332000003340002F -:1036900000336000003380000033A0000033C0001E -:1036A0000033E0000034000000342000003440000B -:1036B00000346000003480000034A0000034C000FA -:1036C0000034E000003500000035200000354000E7 -:1036D00000356000003580000035A0000035C000D6 -:1036E0000035E000003600000036200000364000C3 -:1036F00000366000003680000036A0000036C000B2 -:103700000036E0000037000000372000003740009E -:1037100000376000003780000037A0000037C0008D -:103720000037E0000038000000382000003840007A -:1037300000386000003880000038A0000038C00069 -:103740000038E00000390000003920000039400056 -:1037500000396000003980000039A0000039C00045 -:103760000039E000003A0000003A2000003A400032 -:10377000003A6000003A8000003AA000003AC00021 -:10378000003AE000003B0000003B2000003B40000E -:10379000003B6000003B8000003BA000003BC000FD -:1037A000003BE000003C0000003C2000003C4000EA -:1037B000003C6000003C8000003CA000003CC000D9 -:1037C000003CE000003D0000003D2000003D4000C6 -:1037D000003D6000003D8000003DA000003DC000B5 -:1037E000003DE000003E0000003E2000003E4000A2 -:1037F000003E6000003E8000003EA000003EC00091 -:10380000003EE000003F0000003F2000003F40007D -:10381000003F6000003F8000003FA000003FC0006C -:10382000003FE000003FE00100000000000001FF59 -:103830000000020000007FF800007FF80000026F27 -:1038400000001500000000010000000300BEBC20C5 -:103850000000000300BEBC2000000001FFFFFFFFCE -:10386000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF68 -:10387000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF58 -:1038800000000000FFFFFFFF00000000FFFFFFFF40 -:103890000000000300BEBC20FFFFFFFF000000008F -:1038A000FFFFFFFF00000000FFFFFFFF000000031D -:1038B00000BEBC2000002000000040C0000061806D -:1038C000000082400000A3000000C3C00000E480AC -:1038D0000001054000012600000146C0000167808C -:1038E000000188400001A9000001C9C00001EA8070 -:1038F00000020B4000022C0000024CC000026D8050 -:1039000000028E400002AF000002CFC00002F08033 -:103910000003114000033200000352C00003738013 -:10392000000394400003B5000003D5C00003F680F7 -:103930000004174000043800000458C000047980D7 -:1039400000049A400000800000010380000187000D -:1039500000020A8000028E0000031180000395001F -:103960000004188000049C0000051F800005A300CF -:10397000000626800006AA0000072D800007B1007F -:10398000000834800008B80000093B800009BF002F -:10399000000A4280000AC600000B4980000BCD00DF -:1039A000000C5080000CD400000D5780000DDB008F -:1039B00000007FF800007FF800000174000015008F -:1039C0000000190000000000FFFFFFFF40000000A2 -:1039D00040000000400000004000000040000000E7 -:1039E00040000000400000004000000040000000D7 -:1039F00040000000400000004000000040000000C7 -:103A000040000000400000004000000040000000B6 -:103A100040000000400000004000000040000000A6 -:103A20004000000040000000400000004000000096 -:103A30004000000040000000400000004000000086 -:103A400040000000400000004000000000007FF83F -:103A500000007FF80000050900003500FFFFFFFFB0 -:103A6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF66 -:103A7000FFFFFFFFFFFFFFFFFFFFFFFF4000000012 -:103A80004000000040000000400000004000000036 -:103A90004000000040000000400000004000000026 -:103AA0004000000040000000400000004000000016 -:103AB0004000000040000000400000004000000006 -:103AC00040000000400000004000000040000000F6 -:103AD00040000000400000004000000040000000E6 -:103AE00040000000400000004000000040000000D6 -:103AF00040000000400000004000000000001000F6 -:103B000000002080000031000000418000005200D1 -:103B100000006280000073000000838000009400B9 -:103B20000000A4800000B5000000C5800000D600A1 -:103B30000000E6800000F700000107800001180087 -:103B400000012880000139000001498000015A006D -:103B500000016A8000017B0000018B8000019C0055 -:103B60000001AC800001BD000001CD800001DE003D -:103B70000001EE800001FF0000007FF800007FF8E8 -:103B8000000004480000150010000000000028ADEF -:103B90000000000000010001000D0205CCCCCCC1EA -:103BA000FFFFFFFFFFFFFFFF7058103C0000000009 -:103BB0000000000000000001CCCC0201CCCCCCCC39 -:103BC00000000000FFFFFFFF400000004000000079 -:103BD00040000000400000004000000040000000E5 -:103BE00040000000400000004000000040000000D5 -:103BF00040000000400000004000000040000000C5 -:103C000040000000400000004000000040000000B4 -:103C100040000000400000004000000040000000A4 -:103C20004000000040000000400000004000000094 -:103C30004000000040000000400000004000000084 -:103C40004000000040000000000E01B7011600D641 -:103C50000000FFFF000000000000FFFF0000000068 -:103C60000000FFFF000000000000FFFF0000000058 -:103C70000000FFFF000000000000FFFF0000000048 -:103C80000000FFFF000000000000FFFF0000000038 -:103C90000010000000000000007201BB012300F3CF -:103CA0000000FFFF000000000000FFFF0000000018 -:103CB0000000FFFF000000000000FFFF0000000008 -:103CC0000000FFFF000000000000FFFF00000000F8 -:103CD0000000FFFF000000000000FFFF00000000E8 -:103CE0000010000000000000FFFFFFF3318FFFFF16 -:103CF0000C30C30CC30C30C3CF3CF300F3CF3CF308 -:103D00000000CF3CCDCDCDCDFFFFFFF130EFFFFF69 -:103D10000C30C30CC30C30C3CF3CF300F3CF3CF3E7 -:103D20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD3 -:103D30000C30C30CC30C30C3CF3CF300F3CF3CF3C7 -:103D40000002CF3CCDCDCDCDFFFFF4061CBFFFFF61 -:103D50000C30C305C30C30C3CF300014F3CF3CF399 -:103D60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA4 -:103D70000C30C30CC30C30C3CF3CF300F3CF3CF387 -:103D80000008CF3CCDCDCDCDFFFFFFFA302FFFFF98 -:103D90000C30C30CC30C30C3CF3CF300F3CF3CF367 -:103DA0000010CF3CCDCDCDCDFFFFFFF731EFFFFFB2 -:103DB0000C30C30CC30C30C3CF3CF300F3CF3CF347 -:103DC0000020CF3CCDCDCDCDFFFFFFF5302FFFFF45 -:103DD0000C30C30CC30C30C3CF3CF300F3CF3CF327 -:103DE0000040CF3CCDCDCDCDFFFFFFF3318FFFFFA6 -:103DF0000C30C30CC30C30C3CF3CF300F3CF3CF307 -:103E00000000CF3CCDCDCDCDFFFFFFF1310FFFFF47 -:103E10000C30C30CC30C30C3CF3CF300F3CF3CF3E6 -:103E20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD2 -:103E30000C30C30CC30C30C3CF3CF300F3CF3CF3C6 -:103E40000002CF3CCDCDCDCDFFFFF4061CBFFFFF60 -:103E50000C30C305C30C30C3CF300014F3CF3CF398 -:103E60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA3 -:103E70000C30C30CC30C30C3CF3CF300F3CF3CF386 -:103E80000008CF3CCDCDCDCDFFFFFFFA302FFFFF97 -:103E90000C30C30CC30C30C3CF3CF300F3CF3CF366 -:103EA0000010CF3CCDCDCDCDFFFFFFF730EFFFFFB2 -:103EB0000C30C30CC30C30C3CF3CF300F3CF3CF346 -:103EC0000020CF3CCDCDCDCDFFFFFFF5304FFFFF24 -:103ED0000C30C30CC30C30C3CF3CF300F3CF3CF326 -:103EE0000040CF3CCDCDCDCDFFFFFFF331EFFFFF45 -:103EF0000C30C30CC30C30C3CF3CF300F3CF3CF306 -:103F00000000CF3CCDCDCDCDFFFFFFF1310FFFFF46 -:103F10000C30C30CC30C30C3CF3CF300F3CF3CF3E5 -:103F20000001CF3CCDCDCDCDFFFFFFF6305FFFFFD1 -:103F30000C30C30CC30C30C3CF3CF300F3CF3CF3C5 -:103F40000002CF3CCDCDCDCDFFFFF4061CBFFFFF5F -:103F50000C30C305C30C30C3CF300014F3CF3CF397 -:103F60000004CF3CCDCDCDCDFFFFFFF2304FFFFFA2 -:103F70000C30C30CC30C30C3CF3CF300F3CF3CF385 -:103F80000008CF3CCDCDCDCDFFFFFFFA302FFFFF96 -:103F90000C30C30CC30C30C3CF3CF300F3CF3CF365 -:103FA0000010CF3CCDCDCDCDFFFFFF97056FFFFFBC -:103FB0000C30C30CC30C30C3CF3CC000F3CF3CF378 -:103FC0000020CF3CCDCDCDCDFFFFFFF5310FFFFF62 -:103FD0000C30C30CC30C30C3CF3CF300F3CF3CF325 -:103FE0000040CF3CCDCDCDCDFFFFFFF3320FFFFF23 -:103FF0000C30C30CC30C30C3CF3CF300F3CF3CF305 -:104000000000CF3CCDCDCDCDFFFFFFF1310FFFFF45 -:104010000C30C30CC30C30C3CF3CF300F3CF3CF3E4 -:104020000001CF3CCDCDCDCDFFFFFFF6305FFFFFD0 -:104030000C30C30CC30C30C3CF3CF300F3CF3CF3C4 -:104040000002CF3CCDCDCDCDFFFFF4061CBFFFFF5E -:104050000C30C305C30C30C3CF300014F3CF3CF396 -:104060000004CF3CCDCDCDCDFFFFFFF2304FFFFFA1 -:104070000C30C30CC30C30C3CF3CF300F3CF3CF384 -:104080000008CF3CCDCDCDCDFFFFFF8A042FFFFF31 -:104090000C30C30CC30C30C3CF3CC000F3CF3CF397 -:1040A0000010CF3CCDCDCDCDFFFFFF9705CFFFFF5B -:1040B0000C30C30CC30C30C3CF3CC000F3CF3CF377 -:1040C0000020CF3CCDCDCDCDFFFFFFF5310FFFFF61 -:1040D0000C30C30CC30C30C3CF3CF300F3CF3CF324 -:1040E0000040CF3CCDCDCDCDFFFFFFF3300FFFFF24 -:1040F0000C30C30CC30C30C3CF3CF300F3CF3CF304 -:104100000000CF3CCDCDCDCDFFFFFFF1300FFFFF45 -:104110000C30C30CC30C30C3CF3CF300F3CF3CF3E3 -:104120000001CF3CCDCDCDCDFFFFFFF6305FFFFFCF -:104130000C30C30CC30C30C3CF3CF300F3CF3CF3C3 -:104140000002CF3CCDCDCDCDFFFFF4061CBFFFFF5D -:104150000C30C305C30C30C3CF300014F3CF3CF395 -:104160000004CF3CCDCDCDCDFFFFFFF2304FFFFFA0 -:104170000C30C30CC30C30C3CF3CF300F3CF3CF383 -:104180000008CF3CCDCDCDCDFFFFFFFA302FFFFF94 -:104190000C30C30CC30C30C3CF3CF300F3CF3CF363 -:1041A0000010CF3CCDCDCDCDFFFFFF97040FFFFF1B -:1041B0000C30C30CC30C30C3CF3CC000F3CF3CF376 -:1041C0000020CF3CCDCDCDCDFFFFFFF5300FFFFF61 -:1041D0000C30C30CC30C30C3CF3CF300F3CF3CF323 -:1041E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF57 -:1041F0000C30C30CC30C30C3CF3CF3CCF3CF3CF337 -:104200000000CF3CCDCDCDCDFFFFFFFF30CFFFFF76 -:104210000C30C30CC30C30C3CF3CF3CCF3CF3CF316 -:104220000001CF3CCDCDCDCDFFFFFFFF30CFFFFF55 -:104230000C30C30CC30C30C3CF3CF3CCF3CF3CF3F6 -:104240000002CF3CCDCDCDCDFFFFFFFF30CFFFFF34 -:104250000C30C30CC30C30C3CF3CF3CCF3CF3CF3D6 -:104260000004CF3CCDCDCDCDFFFFFFFF30CFFFFF12 -:104270000C30C30CC30C30C3CF3CF3CCF3CF3CF3B6 -:104280000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEE -:104290000C30C30CC30C30C3CF3CF3CCF3CF3CF396 -:1042A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC6 -:1042B0000C30C30CC30C30C3CF3CF3CCF3CF3CF376 -:1042C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF96 -:1042D0000C30C30CC30C30C3CF3CF3CCF3CF3CF356 -:1042E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF56 -:1042F0000C30C30CC30C30C3CF3CF3CCF3CF3CF336 -:104300000000CF3CCDCDCDCDFFFFFFFF30CFFFFF75 -:104310000C30C30CC30C30C3CF3CF3CCF3CF3CF315 -:104320000001CF3CCDCDCDCDFFFFFFFF30CFFFFF54 -:104330000C30C30CC30C30C3CF3CF3CCF3CF3CF3F5 -:104340000002CF3CCDCDCDCDFFFFFFFF30CFFFFF33 -:104350000C30C30CC30C30C3CF3CF3CCF3CF3CF3D5 -:104360000004CF3CCDCDCDCDFFFFFFFF30CFFFFF11 -:104370000C30C30CC30C30C3CF3CF3CCF3CF3CF3B5 -:104380000008CF3CCDCDCDCDFFFFFFFF30CFFFFFED -:104390000C30C30CC30C30C3CF3CF3CCF3CF3CF395 -:1043A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC5 -:1043B0000C30C30CC30C30C3CF3CF3CCF3CF3CF375 -:1043C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF95 -:1043D0000C30C30CC30C30C3CF3CF3CCF3CF3CF355 -:1043E0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF55 -:1043F0000C30C30CC30C30C3CF3CF3CCF3CF3CF335 -:104400000000CF3CCDCDCDCDFFFFFFFF30CFFFFF74 -:104410000C30C30CC30C30C3CF3CF3CCF3CF3CF314 -:104420000001CF3CCDCDCDCDFFFFFFFF30CFFFFF53 -:104430000C30C30CC30C30C3CF3CF3CCF3CF3CF3F4 -:104440000002CF3CCDCDCDCDFFFFFFFF30CFFFFF32 -:104450000C30C30CC30C30C3CF3CF3CCF3CF3CF3D4 -:104460000004CF3CCDCDCDCDFFFFFFFF30CFFFFF10 -:104470000C30C30CC30C30C3CF3CF3CCF3CF3CF3B4 -:104480000008CF3CCDCDCDCDFFFFFFFF30CFFFFFEC -:104490000C30C30CC30C30C3CF3CF3CCF3CF3CF394 -:1044A0000010CF3CCDCDCDCDFFFFFFFF30CFFFFFC4 -:1044B0000C30C30CC30C30C3CF3CF3CCF3CF3CF374 -:1044C0000020CF3CCDCDCDCDFFFFFFFF30CFFFFF94 -:1044D0000C30C30CC30C30C3CF3CF3CCF3CF3CF354 -:1044E0000040CF3CCDCDCDCD000C0000000700C07A -:1044F00000028130000B81580002021000010230DE -:10450000000F024000010330000C0000000800C052 -:1045100000028140000B816800020220000102407D -:1045200000070250000202C0000F0000000800F067 -:1045300000028170000B819800020250000102709D -:10454000000B828000080338001000000008010002 -:1045500000028180000B81A80002026000018280BD -:10456000000E82980008038000028000000B802863 -:10457000000200E0000101000000811000000118AD -:10458000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC6B -:1045900000002000CCCCCCCCCCCCCCCCCCCCCCCC6B -:1045A000CCCCCCCC00002000CCCCCCCCCCCCCCCC5B -:1045B000CCCCCCCCCCCCCCCC00002000000000007B -:1045C0001F8B080000000000000BFB51CFC0F00360 -:1045D0008A7BD81818F67020F843015F646260B8CF -:1045E0000CC45781588099812198918121849178B8 -:1045F000FD71A208F61321A019C240330419184E08 -:104600000B23C40F02D5988830307C878A5503D994 -:104610000CA2D471FF40E375529862AB2510ECF503 -:1046200058E491F10634792E4954FE4602FA071AED -:10463000DF5744E50B2940E86CA8F803347961A8FA -:10464000FC79A8BF1E2A6237F702541E005BBBD25A -:1046500053600300000000000000000000000000A4 -:104660001F8B080000000000000BED7D0B7854D577 -:10467000B5F03E73CE9C9949662627214F1E6112E4 -:1046800020028638BC0228B74E480850691D6C5578 -:10469000B468070810F296A297D6F6CB04428C8035 -:1046A00036F8FB408B3ABC2A2A6AC048510187A7DA -:1046B000E8F5F606AB9656EB8D68519147E456A5A2 -:1046C000FF6DAFFF5A6BEF9D39673201ECD77BFF6F -:1046D000FBDFEF8F9FDF619FBDCFDE6BAFD75E6BE0 -:1046E000EDB5F7D86D1EA65FCDD8D7F807CF7A1BEA -:1046F000632C23F67CC4CE7E18743356B0CEB7C27A -:104700009D0EEF77E56D4FF63196B37BAD3205DE4A -:10471000E7AC6F53E615C6BE0FB8A0723CBCDFB560 -:10472000562981F7396FB42973F1E9B0B14E68CFDA -:10473000345F0AC3270B3096C9D890894CFC05DC3E -:1047400039C58C0DC47F4217E78C64C6C63196B755 -:10475000D216092BF03E5439937919DB0470E5A485 -:10476000C177EA5FF6D9B16D8376BCCBC998537334 -:104770006A5FE733963B9BD9183C072FE3EFF1EFD5 -:104780006BF83F2F6C2D0F61A6721E963DE92760D6 -:1047900048E6619EAFD544F076EBC151B179CAE7E6 -:1047A000FA465FA65BEBFD5E3E97DCF6897E177CE2 -:1047B000FD18B61BCA5824AE7D6D58D7D815F00425 -:1047C00004B417F6FE7E262B29463ADCCAA6D0B3DF -:1047D0005EF3DD8878A93F62676180BBBEE1443942 -:1047E00096D92E850DCBEBFDFD2866277A943045B2 -:1047F0003B81F3F5322FCE4FADF13D540E786E482C -:104800000E9461BF0F2787E829DF67CF9B9E1D02AB -:10481000784A17158619D0FDDC3AC5EF80CF3F5690 -:1048200022BA1DE851FDFD86A269D0EE6D3D740DE2 -:104830007EB7488DB6D861FCDA390D054001D6A99E -:1048400073FE19BCABE4530DE83698B1704A1AD226 -:1048500085B1E3263AE0DFF1E1A2ACF68DC78B3DEE -:104860002BB01F0D7B89D07CE5FBBCF0912143E38D -:10487000C663C5040F433819EB5212D175F08B256E -:1048800047B4A2BEC7FBCF9F4798CB21E00EE95BA0 -:10489000EBD123CB01BFA52FD8A357033D6A3728FF -:1048A0001107946D7B5D01A4CF99CD5006BA443DAC -:1048B0003AB53F6D38A95CEFE8BCF72A2877BFA06E -:1048C000B28DD8EDF0241BCADD09013B1B0765C082 -:1048D000C742172FD66ED8772BF657B9CBC15C4895 -:1048E000CF17177DF72A282F027EC326B55B9AF4CF -:1048F000FE505E1C51DAB17C760A23FE08A7E991CE -:104900002D30DE596F67E6F5202F271B9DCC07A0C1 -:10491000ACF074667E1FF8A82AB2BD1CBFABDAA645 -:10492000F811EDA52F6C399C83F37A12F80AF8A8D8 -:104930007A6B32F349FCC1FF27602A5743FD129876 -:1049400027CAFF22D656CE541C7FADEEF3C4F075B5 -:10495000B2D1A0717AE4E9491807BEAB7B56F1E306 -:1049600014EB6C2C847275E645D7EC4D6E9C5F930E -:104970005EE0C179DDA563BB4591B93B5165554505 -:1049800036E8E5505FB57E83BEB010F1067AAF1011 -:10499000E1EA67856B9D1A40FC2E49756E54013F14 -:1049A000CC1DC8BE2E01FF9C6C043556102B57A1A0 -:1049B0007C933E89E8B34CEDCB9554E2D7EAAD2A1F -:1049C000F359F889D33F7C94D33FBCC713D99217CE -:1049D000A3DF1283EB4949BF25A9829E5A77712232 -:1049E00078EE457A003C6D882F78AE11F07927B3C8 -:1049F000120DE8E20D30436117E7CF363B9BCB60E9 -:104A0000EC37D982803609CA3ABB8DF91933B4DA4A -:104A1000401994FFC2826FE07C18F3FB8280E71696 -:104A200085CDC6791F4260613E2D393AE1AF6D6A8E -:104A3000F126551130A76379E12F57E5D1F76FD1F2 -:104A4000F71A7C3FAAEFEF8DF28996EF8DF24AF9C3 -:104A5000FD7BD88E392FFC7D5BF995D6F1CBABE48D -:104A6000F71FD1F8EE0BC36F4C9B6C1D7F5A0D7D69 -:104A70005FEFE0F4EA4E75463642B9D9E50F684873 -:104A8000378D45F1BD9656B011DBA9921F5867408E -:104A900085EFDDDB52C7AC6266BE98F2271CCF0300 -:104AA000D262E68B948949167E4C0DA459CAD093E4 -:104AB00071E2F2981E0A789D048FDE5F277D51D245 -:104AC000DF49F0DEB1D745E53BAEE4F0DED1DF4DA6 -:104AD000728630B01C28EBA12B0CD37A04702A2CE0 -:104AE0009BB12F94904B196F7EEFB3E1FB2495356A -:104AF000E07C921C8CF4D15D79C59BC226FCB40E7F -:104B000002FA42395DD1391E055EEF1AB4307BAE30 -:104B1000699C9641FAEC8D85FCFD7C378E17CC5450 -:104B2000500FEADD0586BBF7388EFC8996719CB97B -:104B300095344E5EDC388EDCCAB8719CB3378AF788 -:104B4000629C21171AE7AEFC2BADF3C9ADA2718AA6 -:104B5000E2E7935B15374E129F0FBC17E3F8117F06 -:104B60007DCE67C864EB7C06D7D03857E138E34D7B -:104B7000F3195C13378E9BC6C1F7380E18523E9658 -:104B8000057477742F24FABFE2227B4177849EC09C -:104B90007ED9BB2E46FAC407E366A15E81C519E43F -:104BA0005753D2689C2F9380FE6E339DB93EA22747 -:104BB000E89F05024416018840FFD4091EADD8368F -:104BC0002BB7099FBB4AB3E7A25D72BFC73F0C4436 -:104BD000E7CCAE527D7E02FB66419BFD4497857F0C -:104BE00085DE9BC28637C0F81DA86C4CE513A0BFBC -:104BF00018E8ADE3A0BFF0F9B1B04F3F02FDC674B5 -:104C000033BC4D348F131AC7E389F57C1DF972ED5F -:104C1000513B187B38CC5B8500F70D621A0BDAC06C -:104C2000F833C959BDA047F78B8EC846A2476080AC -:104C30000DF89CADEB07B812EDC0CEFC83B047E198 -:104C40006F800D6CD99B5BB71FC266EF2873072D71 -:104C500081F9CEEE586B1F00E533F6AE5BFD6E5367 -:104C60003FB3EDC771DE4EF80FFBB92964B7D8A783 -:104C70003FA8B4966F89B3576B947C410F31AE2F28 -:104C800062477ADD90C9E1B9059F63B0DA207ADD29 -:104C90006AF06F253CF577DA5994D6A3AE0C5688A6 -:104CA000F8C820BB2824D79538F86EB53B0341A03F -:104CB000E7AD3F56098FF1F076ED4D0ED8C05EEAB4 -:104CC0005AF76F76B4BF2F06FF0F9759EB59988F9D -:104CD00027F12AF9E0C6D925FD3E32B5BB2934A318 -:104CE000DF47267EF941E52C4BF996869B2CED7F1C -:104CF000B86CAEA57E6E78B1A57E7EEB6D96F28225 -:104D0000B61F5BDA2F5AD764A95F1CB9DB525FBDAF -:104D100075ADA55CDBFEB0A57DFDAE0D967ADBDE44 -:104D200011D7A23CAE785B65689F7DE13E712FDABA -:104D3000575F189A1FDBD421AF811C7ED2984DFC9F -:104D40007DB2D147CF33BBC63AD11EAF4F02798671 -:104D5000B57EAFF28770EB64D423D01E74F87EE585 -:104D6000C370189CA7D7141FF1BDBA4E6751605588 -:104D700085A5F5F075B71AABD7BAA07E6CDFF5EA5A -:104D80003A2D61BDD6A525ECF7ACD25D80F65DF875 -:104D9000770E8676605FF603FC0DC0F5A2AFFA537E -:104DA0003656D96ED23B27141BF1C10DCA9413A8F5 -:104DB0009F6B742EEF353B72A6A03F58A3470B1A8A -:104DC000DC1718AF1D80C9C27EF2695E8B230362B7 -:104DD000F24BF41B6291FBA52CF447D4CFA7F6A9A4 -:104DE000A46759F440EEF746E1F88113F89EEDCA46 -:104DF000A0F5F19DC640BF8FC09F3BD6389D9EBF9A -:104E00006F0CF6FB0874CD7B8DB3A9FC7E63889E86 -:104E10005D8D95F43CDED840F51F352EA3F289C692 -:104E2000303D3F696CA5E7C9C636AA3FD5B88ECAE2 -:104E3000671A23F4ECF103843DCAD285FD27EC7593 -:104E40005839A87C4ECC41857F73BFD59F8D727D2C -:104E5000CEFD6501DAB9E78E816192C03F94CF78CB -:104E60007EEB9B7E015AEF174680FE637BD7BB9299 -:104E7000387D5C36369D81FEB97B98CE34183FE98B -:104E800095CBC95E86F71A237D19F1CFF224E81F6E -:104E9000E79C75713AF5F0C723FF5E8CF1871B84A0 -:104EA0003E4C3AA03670BA6DF223DD4CF8E376D969 -:104EB0000B429FC7E1916CB99CDEF83C9D21F1D972 -:104EC000998B7180FB95E0081BF0C1B90E07CDEB03 -:104ED000DCEEE408C36F313832E94278E370546F96 -:104EE000751966FD50DB9E6A58F5458E61D617E749 -:104EF0008E6CF2A2DC2FC9B6191F8D45FE0808FE84 -:104F0000E07C27FBAF6DCF33DC967EACE5736DCADA -:104F100074F48340B9A77C3F817F209F4BB275E337 -:104F20002390EF935B87A4E0B8E0C71938CEA94679 -:104F3000C3E0E3661B66BEAC599644ED257C7DF567 -:104F4000FBF7860F2D830F9D8C50FFF5906FEE675A -:104F500033ED4F14CF61BBED5FE2BAE380FFBFA634 -:104F600078804665D96F7DBB1A765C81EFB759C6EC -:104F700083EF7CD287C6F5AA6FBA6BEC84292E50DA -:104F80008763907FE4243A87A0C714E8EFACE66E0D -:104F900055609CE9361FD5D70B7EAC7576E9217834 -:104FA00075BA83D3A3AF714E361EF169A03F2A9D17 -:104FB000E091C13895ED23CA503F9EEE58911902F9 -:104FC000BEAD56CFDD114CF07DAB4DE1F044ECDDD4 -:104FD0005DA6F9C8380A63D0AF33063F72FA0953A9 -:104FE000395E5FCBE77DD82FF047DDB6A3E55701EB -:104FF000FC75BB3ED7118EE9B6D07DB68CD8FC15BA -:105000009C3FF453B5F5031DE7F7893D5C70E70558 -:10501000F4546F38DDD914B793F0855927DA31F39A -:105020007AE28ABE1BDF05D1FCF49FEC6C15C0C18F -:10503000FE02ADA0DE2E6A2B58D08BF89AD7514DC8 -:10504000F1C54F6DD26E6A2B46FE38CD6CD3717EA2 -:10505000A7D99BDEB126FC75D8B8DDCF5AB91D1390 -:1050600086FF101EB0672D76CDA275D6F242765D12 -:1050700026EA8D85F7DB590450B418ED22C91F309C -:10508000EFCD366EEF2E620D2D68CF690EEE1FCC80 -:1050900033983600E0AAFDD5A3C568F7BF6CB311FD -:1050A0007D649C61711A87BB2A3DA207A0FEC38E56 -:1050B000B1375C85DCE788B4E0BACC52987F0BEB63 -:1050C0008DCFF9AD56F82E067F3CBC8C2DB7C02194 -:1050D000FB9570A85B95402401DFBD26F94EE89151 -:1050E00034D56AE767C595DFB389F8A5CA54A4F338 -:1050F00069C319B6A550BD3F8AF1911D0EFF0AA0E4 -:10510000EFEDB66017EA67B00B8A98A9DDEDB6102F -:10511000BD3FA5BCB110ED53A6458BD0BF8735452B -:10512000437ED0053FA849DE228CC77A18AC9F2069 -:10513000970E840FFA69F154CE6445187F053985BE -:10514000FEEEF1961F51A0EC727730ECCF916D8D91 -:105150002FBB7CD6723DFE03E9309C511C2779B8E9 -:10516000B51E162C86FCE6F15BDFFFEF1E3C458981 -:105170006FBDC4D2F074BAA32A8CCF266AA7CC76AE -:10518000739D93C34F7E39B45F2AECF93AE60B5313 -:105190009C389BF3C1D219368267A9C7E70F43BD7C -:1051A000A20518CA1FC6AACDEB58FD7910B97EA674 -:1051B000B2D6AD235FD69FD75804F47D912DE4512C -:1051C000C723FE0264E73A01595F03C89A7BBAC558 -:1051D000EE6503D3C4FA3AD030CBEB40A4F3F81811 -:1051E0009DA55EB00BBD08FA224BCD403DD85D4E6B -:1051F0007E09EB223D21DBE9B17603118EBEDAB9DF -:1052000062EDF212F557FBAB67768601FF55CF3D95 -:10521000E005E2B34FB5B64C3FBCAFD9B2D28B7C00 -:10522000FC8916F6E2BC3F8DA8D313F1F30DAA2238 -:10523000FCB1805B417F58D0E9E453ABBF8B78FF72 -:10524000728BDDC026F55B1D510710B1AE6331E7EF -:10525000A7AD8E0F78F9AECF919EF5BBACF256F5A7 -:10526000C4039918EF040C71BF9145C97EAEDBFCF5 -:10527000C772B447EA5937E989F8EF70FCF369B4AB -:105280007ECDD5537AD7CBFD977AC1F7F51DAB3FCD -:1052900057BD58B6CA77A5F047A6A99E748A2B4D6C -:1052A0006013906E120F2CC2EDE1154F3E54F401C5 -:1052B000C0716AF33F79154BDC88EB8773EDF31F00 -:1052C0007FC9D7B75E3F23FCF9D87711FACEB78BE9 -:1052D000DBEF6C377FD6D8A35EF4976A36D8FD2013 -:1052E00099ACE6994DBF7C04F9FA770E8A33543FA6 -:1052F00073E89D2BA15CBDDD9E3E934FC3AD64C69C -:10530000E8510FFF2F1B13C37FD5F38774DF28FEEF -:10531000FEA769313A546FDFA7B351BDF156DABE2B -:105320004FEF7227A047FB07E5686FAF78F22B1DA0 -:10533000E5EAD3BD0ACBCAEBFD7DE5864364CF2108 -:105340009E887E823E3DF4EA45A7E8775F1A47EDE6 -:105350000C5CBFFAA2D3485CFB32888F9F7D09E3C7 -:10536000F7BF77F871FE95CFFEC88BF3F8586BE066 -:10537000FCFCE8CACC008C5B690F671AF4E4EF2BE5 -:105380001FBB9DF86CD1D1DB33291EC00239365AC0 -:1053900043C33938BF05EBAFA7F92D6421E2B7CA83 -:1053A00047D56004E3591A9BBE3D813CBC21E4E132 -:1053B000E38D0E5C7BD8C7A860D13F7C53A57D02EE -:1053C000C66EA378C3ED721F822DA1F2174E4EA7B1 -:1053D0004DAA4DC6379C163EDD7C5727D2E7E4A088 -:1053E0004016C627010F61812F05F58E7A746A1663 -:1053F000A70FF369C5E23BD08BA5F81EDB77DA0374 -:10540000AE22CB77621DE3E32F15E303DC49688FFF -:105410007D9C09F64D82F97DA54ABD0CF68689BFB3 -:105420004C72CDE57CF3DD5CAEA59C47664DC7FABA -:105430003FBDC5E507BFC3751DE08A6651FDBEEFE0 -:105440002BA4071C2C9A489E37DB853C5BEBE5FEC2 -:1054500024C0ADE1FA14E313E83F8DF04F76DAC2D1 -:10546000FBE13B935EAEC7F1A89D1E7B6F5AD71739 -:1054700009F97F5515FBA342FED97A2EF77DDBBDD6 -:1054800061EE1FD823BF7C04E515E413D7999A6712 -:10549000EC419CF767DB0EBC7333F0F567ED524EC1 -:1054A000AD7A335E4E2B778C6789E4F433B79F2552 -:1054B0009453789F504EDD5DC4C7FFD97A53E2ED17 -:1054C0004C9CDE947AB02FFCC5EBC135AA2FA11EEF -:1054D00084BFB758716FBE93FC26F9ACEAE9DAC114 -:1054E000143792FC28F9AD871F25BFC5CFD38AB7E3 -:1054F000F8FA1785BE9174B62F67610FC64BF7A8EF -:10550000E45F9F05985A80BE67B7E54530EEBCD290 -:10551000C5E317678D6E6F1A3C57A6F2727786DE69 -:1055200082FA41BEEF76F1F8F6D960B737D5E45785 -:105530007CB05BF5FAA0BE2BC2A627F23740F3126F -:105540001C5DACAF7A1E0F9EAABA7397A1DFDEA6D0 -:10555000D27E7645D38D5EDC073EBB7BC8CF513F04 -:105560002D780D0C4C80F72CDA812938BD80867996 -:1055700009F305BD3F61E10727C3FCE6EFE6FE4204 -:10558000C59A38FBDEBD54477D03F6FD716B5C9B0D -:10559000F34D95E8A772BDB5BE8AAD21BA55C5F1E8 -:1055A0005148F8811334C147A3D968E187F1F885E0 -:1055B000D05753D5C29FA39D71F6088F2B9EDBADAC -:1055C00012FECF6D532218F7A1F8EE24A47FB7CEB8 -:1055D0004CFEF229E437BD6F393EF5C21F8AEF84D5 -:1055E00026353BDF2DFA053C4FEDFC5DC1CB58FE67 -:1055F000D56F73DF65BDDB97EEFD33ED1F9FDDEBF0 -:105600002038CEEE7D35F74E2CBFE4F0239C679713 -:105610003B68FF2CBCD7131986F58380DEB86EEE8D -:10562000F9AAA88BD69D66A2D33C8DEF779CDBFDB3 -:10563000EFEF2B987FB0DBE1C379D4EFE57921F56B -:105640002FB928EE7276CF57C521F7DF6F3E753A36 -:105650000B11FF79D8EC1DC8AFA97C1FA0FEE5494E -:105660009B9A703FBC639F8EFB2BA5AFFCB508F5E2 -:10567000CBD91DDC4E3863EF7A0CF7416BB5A1CB6B -:10568000ED28F768B3F507BBD3BE604AB830115EAA -:10569000381ECE021E705E80974AD48B7DE1A359DE -:1056A000E3FEE67F3F7C7C7E2B8E5FB37B02C94DA1 -:1056B0000C2F4A80BFF7449C0ACD9FBFDFFB5511DA -:1056C000DA3D9FB537D13A7EB1796FFA1F376F2532 -:1056D0007A29F3DEFFDF9CFFA76B7C5D8A9783DE70 -:1056E0007CFEAB3BA8FCACC74FF05EA2FC1FFF9F4B -:1056F00046F71D4077EFC5E9AED8FFBBCEFB62741D -:105700007F4DD0DD63605EC1D93D7FA578B99CFF38 -:10571000C5E6EDFB7F74DED2FE5965F3B7E543FBCA -:10572000352CDAE90338570EBFAE0DC34CE0260422 -:1057300013D923413BF78F5485C761D8201E1762C8 -:10574000C29FA014301FC65116925DA7B95BC8CE88 -:10575000649ABF3300F85835729E9F7235D89863AB -:10576000212C0F9CECA7F8669C5FA58DFCF611B46C -:10577000EF9B9B003E18A7D9A319602931FB705BF2 -:10578000D45144CF0FF079978867D90DDDE257B82F -:10579000E3FC0297CF5AEF10FD3BD97E03F3889CC0 -:1057A0007E8D45B01D6B0B9BF3071CCCF41DD417ED -:1057B0006200D6643F7E53FC35F5E06F4C6700F124 -:1057C00037C246712D4AEA237CF823AB781E85D375 -:1057D0008ACF964EC4A3C6C0FFE3F322BF91097FD0 -:1057E00051135D68C36D0197B59DF08B2E4A1F4E16 -:1057F0008FDC1A419F25167A48BC5F802E167A48A6 -:10580000FC7E53BAC4D3231EFFDFB7F3B89BA49327 -:1058100025BF2383FB2151F0435EDDB689E21DA73E -:105820009FFAE0BBC8A7D52FABCC09DF9FD9E661B3 -:1058300051945F2DA2A33F55D5A1268CF34ABBBC42 -:10584000FA390FF179D50E4764267C5FB5F3C32290 -:10585000B29B96771F1E807181A7144EBF7057119F -:10586000EEDB5569DC3F88EF6FBD9DC7054EBD98E7 -:105870003C1BE30FCA569EAF58D57EA3DD61DA7795 -:10588000FE5F769EF70AED489EC34F2AB4DEF4868B -:105890008FFB05A79E54387CBBEC11CC7BACDABAED -:1058A000410FA15FB9F5738A63973EF78CB78BFC04 -:1058B00045D5EA3F6F55899EF024BAC5FBB1751DE9 -:1058C000B5E427D4B50B3F31CE8FAA7E6ECFCE3054 -:1058D000A0A6FAF927BC187F39D9B9C54BFEE956FD -:1058E000EE7F6A6E2DB17F7A31BFB4FDEE847EE922 -:1058F00049FC07F813FBEC71FEFCD67E97B67FF9E6 -:10590000CC178F619CF4D48ECF1E43B86BFEE3DFBF -:105910001E43FB9EED75195B60BEF54FBD4DF12634 -:10592000F9DDBB424ECF0C62E11C6877E6770ECA08 -:105930001F39B3E7E35CF4E7CE6CFF7326FAF54B4F -:10594000F74CCDC2792F7DA1348B259077F944BED9 -:105950008C5C429C309E0E073A0E901F72FA988320 -:10596000FCBE9EF8427B2D8FD7F8445C615BE23829 -:10597000ACF487EB3A3E2CE7F131E1175F2C8EF067 -:1059800016D0F18A4BA0D73611278AA3D769FC0716 -:10599000D0E5AB387A7DC1428FE7E03E6447BF3E39 -:1059A000E308D14BC0938CEF1EB6076C3ACAC18E88 -:1059B000E41E3ACD443A3DF3452EC6C33FB177933A -:1059C000DDD3BDC761A07F5FB5E7B72417675E3839 -:1059D0004AF15326E2AC6758CF1F8F8B29627E9B1A -:1059E0003D3CFE20F08DF1099F97DE8B3804E75790 -:1059F000199FE82B2E314117794F22EE5CBBF95DE0 -:105A00009DC5C579948948A70F2CF17139EFF8FE2F -:105A10000CC4C304737C2D71DC47FACD313AF1B864 -:105A20009A8C9F9DD920E26EF07EE018F407791CD5 -:105A3000A33EA2FC96259043195F1BA3C7C961E44E -:105A4000D2E26A1783F76FC5C7309DAF0B122FA73D -:105A5000FE92580F7F47E7723DDD169AA99BF6B379 -:105A60007F28F65924BE24BCA7441EDEA9A7548A69 -:105A700007B5B41F207D1A2FCF757D9C83B855E7DD -:105A8000F1D6BA5DFB8A50EF9CDAFF22F15DDDB6FC -:105A90000FF430F47378EBF33AB727399FA39E8E57 -:105AA00098F4F4A967F715F1B81FCFBB8DEFBF5A73 -:105AB000F45FBFDBDA7FFDB6CF2DFD5787DB75BE08 -:105AC0005E5E789C935AE0469CEFC94E3B437D77DF -:105AD000B25D9D1E496407EA76CB3E68CB519DD6E8 -:105AE000AB716F26517EEED2A3D3DF4DC17D3A104C -:105AF00033B47F3B9A385F75FC2C3000E9D271F4E7 -:105B00006615D78D9D8847931D5CFC5643A907E415 -:105B1000B5F8BDE03864AB783D30E198CD02378C04 -:105B20009385FAB819FAC17C7ACC1FC2FD51D55BB6 -:105B30003E1DE1510D9BE14AB87EF2FEECEE2043A2 -:105B4000BBDC6E58F395B3AF1371B4A8356F3D5BF2 -:105B500067C3711F9CD992FCB81FB0644460F421E4 -:105B6000CCAB5F904D71E29CEFF1EF4E1BEEB0EDD0 -:105B70008AD8BE6DF279E81FF3606C91B573E0BB13 -:105B800064AD5DC17D007832A4CBEDB6D0463D0357 -:105B9000DBE9CC07AAF1315DD128FF429C7B91FD66 -:105BA000C9767DED07CB7348AA807F88D80F1EC4C5 -:105BB000BA14DC0F5EEFE1E79106BBD3E9BCD12656 -:105BC00061AFF970DF15DB3558D7ED8B9E476AB5AD -:105BD00096D34B4B6E1BEC073F58BFA354037D90ED -:105BE0007E63C9F60106EE4BDF5F8A79F7E94F94D1 -:105BF0008CCE81F26C475119D5FF4BC9E85C28FF68 -:105C0000A8755219D5572B9417B847EF2E0DBB63C3 -:105C1000F29901C62DE65B80DCEE47B93D1D3CD50F -:105C200082B5B5D77FA9F3F3302C88F31F3491CF19 -:105C30007FA0FBBDED38DFC1B6AE26E4BFC7F77C61 -:105C4000958AED7CCCA0791AACD9C07D797835F1F4 -:105C5000EB0BE4FFC4E7C1487E7F2E39F41B84E3DD -:105C6000EE79C31F2A479D5AE3273E8ADF276646FF -:105C70003AD1A542D005E1749AF2902BF12402E9C1 -:105C80009B3203C751C235EAD7977F73784E487E5F -:105C900011E7C04CE7A43E45381F4E0ED133FE9CA1 -:105CA000D47E3DF819F253CEC2F3B908BF3CFF547D -:105CB000BAC84D718173BB59C491407EE4736323AC -:105CC000CBD086F65DFFB623F4671C37FF15DF8E59 -:105CD00023D0DF1515BA1F53D7AE58362E431BCB32 -:105CE000F884D09E1074CB465AA27CDDC1F8B91C52 -:105CF000871240BFF1EC8F0CD2BF032B66925F710D -:105D00003639AF1DF327CEDEC9F300608557500E3C -:105D100006ED4E89A2FF037CFC651C1F7F695D6751 -:105D2000ACE39EFDDAB7AB8BFA33447F60E864A244 -:105D3000DCF0BFB32AB7B3CF36FA080E300BF7E169 -:105D40007A7AA9E3653BACE7F400EFFD1D26BCE7DA -:105D50003AFAA45F9E83D38F9EF1F45BE86CC8454A -:105D600039AE0AB697A36BFAF1C23B8A91A9DFD686 -:105D7000439761FB9AD99D8779CE504301EEB3F5E5 -:105D8000A62F3F8F95B97B6E931DE315481F5F6F5C -:105D90003A5EB1CC9FA1F5B3D0752CC27FC5EECFD2 -:105DA0006D08BFA4E74322CF3FFEFB6F3914316E6D -:105DB0004D931DE324BB74B267E3DB4DC74355E34A -:105DC00063E52267318D9B65E3F18EDEEDF9FA170D -:105DD000EBD749E7B2FAE2C72283F707F8FFB61913 -:105DE000FFDFED1BFFB3B01DE09F9EDF00FF3762BA -:105DF000FBBEF02FEDE86AA117AA711F05F8E88F26 -:105E000081EB3287C2F8E5AA9BE460F11695E40FB6 -:105E1000DACFCCC98CE991C5931AF6E17C173FAA79 -:105E200010BF568873A69F89BCFEF87CA885B3C3B3 -:105E3000B4BFD32B2F2A12E7D7C5E5BBD7C7F87657 -:105E400030CF53E3E7B6542117A58B0A53D01EDA9F -:105E50006BF7FD0BD9D9AFA96C6302FC6F402633F9 -:105E6000D1755083CD9227CB2A522DFD962D2AA491 -:105E70007DEF251EDF05FDAAC1CBACEB765ED87A9F -:105E8000CE6848ABF59CD1B0B6FE96F697ADCBB7D1 -:105E9000D48F888CB4D45FBE758CA53CAAFD4A4BC8 -:105EA000FB2B764DB1944747BF6D693FF6C8759699 -:105EB000F2F8CE9B2DED271C9B67A99FD45565A9B1 -:105EC000BFEA932596F23F74FFC46AA7D818E94742 -:105ED00096A490BE3CD8383117F3B1D938A50CF14F -:105EE000592AF2090FDEA6DB0C2F3E0B6C06E8AD3B -:105EF000FD0B66D2BA7FF0B6CC808F9EC501F46BE5 -:105F0000983A795CA27CCDA9C6A45C735E54A9D3EF -:105F10006ED16F530D6B79A743ECFB0DE67CF372EA -:105F20009C7CD91B2647C13264FD170FCDC2F140BE -:105F3000CEF60A3DB7F792F45C6643319641CE0E39 -:105F400026923326D6D912C14FF00CE8981F59E695 -:105F5000A1F538802F7DF43EAC81BC4C71FA071E50 -:105F6000C279D9FCE9C88465B38307797F625D662D -:105F7000C36DDF645D96729E6D13F96B693C7FEDB6 -:105F8000E1050529CC84DF3F386CC28E6EE34FE318 -:105F900088AB276F35DFFCFE9324CD942FA72C9A76 -:105FA00049F922D97DE8453D3B7FC666D0C77A8E48 -:105FB0008F9EF27DCB6C5BC23CB06EA147A5BD3518 -:105FC00022666F75233D4E67BFF920E629D5CDE9DE -:105FD000267B2BDBD676DB619CD7EBAA885FFAF8B1 -:105FE000F92A61272F9871DF6D87715FFA9F87917A -:105FF0007E92E3AC6F9C3E43339D231FD887DF74B2 -:10600000B993C3F358E3F0191594B76DF0F3A2A256 -:10601000FFDC706D39DACD8345BEE983B6C4F92E55 -:106020006ED14F16921CE135DC2427A717BEE7D5A9 -:10603000601E8FC0EAE5C47DDB2B3A8BB91D16F0DC -:10604000E339D4DCE82D0F62FBDC6C8DF25DE3C735 -:10605000CF9A136ACDC3F8679ACDEFA672B782EDD7 -:106060001D3F65AC1FB46FFE0F95E069DE3F89F2FE -:106070003F1CEE0686FBA9725E07D21E21FCA81DFE -:10608000C9B40E32B12F2EE3AD5F645774A2BDF1D7 -:10609000C5FD761AEF0B98A301FD7FD1A1D2BEEB0F -:1060A000E1B4A4A80DCA6AAB87D6EF5CB43DA1FDEC -:1060B000C20E4FC49717C38BB66E329D87710CE426 -:1060C000F36F4E7347DC7934EF749CB78453CE7B07 -:1060D000501F7E6689803BE7B29E731A0CF95835D3 -:1060E00034EA77412A3F8719699C28E8659D4F4B20 -:1060F000F675D7DE84E787DE5219A686F8BADA6825 -:10610000FE0B61FE115F6FFC9EF6E57D695309CEC3 -:106110001284535D574EF3A076F05DEDE30A7B24C5 -:106120000FF930349DE8DADF46E7027BD9074E2EBF -:106130005F339C3C2F57CF2E98B1B91F3E87925C9E -:106140007CC7D9E7BA1F74727D44CF6F70BF00ADB2 -:10615000FF521FA9019BB073B95EEAB19FF4D00F43 -:106160009C19B1B29AF2D322ECB76FFB6CFB3E1DC7 -:10617000ED333723FB59EACDBEEC33B4CB90DFA42B -:106180005DB6386E9E30BF1A31BF9A44F3EBA56FEF -:106190006F6E9076CD12E705ECCA0C3DB13E7A5297 -:1061A000D0A1DED019C59B688D02BDB3D846E78D5E -:1061B00099167199CF97AF774ABB6EF73E1DF10CD8 -:1061C000F3463C6783FF5C4E7AC79E302FFC62FE2D -:1061D00048FEEAC21D47B03FB07311FA736DBE941A -:1061E000B40BD817F665AFBBCC78BDCF29F2B96335 -:1061F000787C40E0F18184784C073CDA2CF6E1CEE3 -:10620000021FE1F117CE0BD887A7BFF77E31AE474B -:106210006704BEEA7AFC5CAE9FFBC32285F1AA5AF2 -:10622000CC5F76F232EE07E15E0CC6E18A6CC127E4 -:10623000B0FFFA5DD673873F73F2381973F373B307 -:10624000B2BF4CA1EFC1AFFED61F7DA4F7FF11E78F -:1062500013F3AFBB8AD1BF5AF1C26529689795ED98 -:10626000BCC9C0E7B9F4A1B49E9DDEE908209CA793 -:10627000D378BEDEE99D130E63FCE1B3C623F96655 -:106280007D7FFAD9A3C576E8E7F48EA3C51AE507A2 -:10629000472C7661EDD7BF29C6735832AFBA875FF6 -:1062A0009C7C9DB8DFC5E31A19997A0BE68B9F4F4A -:1062B0004A257C3D9069BB3751BC06D527EDDB7B79 -:1062C00074DAA75C32C2B7C28DF19A3C83F2705780 -:1062D00028819C05B8CF32CBE9C77D80F47C363C61 -:1062E0002F055118626EC0A7E3601B1D374DEA34BD -:1062F000F6A17924E3385A29D7B7DDD7EB9437963E -:10630000ACF91E9A03E5ECD91AAD7732AEE348E654 -:10631000E792655CA7079ED7ECB40E2DC90BB59527 -:10632000C0774B26A5D177DE59EF10BF9CF5D9C2B7 -:10633000769C8FD64DF19D9F370ECF180A78347218 -:106340006C33C8A6F90B60CB94FFEFD5583805EC39 -:106350009BD5C0FF4381FF3B1A9DD4BE05EC432370 -:106360008DEE4988DDF361929B1D8D06B5FB65635B -:10637000367D775FA38F9E3D7604E3DF5139817EC2 -:10638000FDCF7ADED3C8EF1391E57F1B07761AD0D5 -:106390003B7D025015F0922ECE9FCBFA471A5F1B21 -:1063A0005236542003F0D9BFC6D8B0EA02F0A63B5B -:1063B00022A978C4F872170B974DC43CBFEE7BCB73 -:1063C00053F17CC45D656523008FB8BF7D2590CAFD -:1063D000755F339E4FCDA9F13561DC2F6797D28E63 -:1063E000EB57CEAEB525B88F00EDE8DCA0EC37C397 -:1063F000C5F55CF2818795FC51B8B9C0F7E5D99E27 -:10640000E448A2F3A5E35C5CCFF95D7C7F70B5D86E -:1064100057EF9EE526BD987CC045FC92B3FB72DA2F -:10642000DF73F7B1AF1CDF4FF2813F531CD8ADB41F -:10643000EDC37D4AB680DB9F929FFAFA0EDBEB97A5 -:10644000D0FEAC5FA3B83098BD34BFD3B30612BE44 -:10645000B1BD598F9FD513DB650181A795F6C47136 -:106460007A8DF171C67576D37E26DEDB84F8CE791F -:10647000AB4D417FFDB4C2F331FA033E764039673C -:10648000721BDDEBF49C3354EE82EFFE641C2B5840 -:1064900009E0B80A7F9F8BDF497CA845BA13F5490C -:1064A000CEEE0FF8391F5B978EF96F8BEE7E9EE272 -:1064B0008FAA1ECCE3E5952B313E99E10D6E403E4F -:1064C00061E1E7CB0E029F3C20CE2DE31BD47BABDA -:1064D0005DA21C6E6F0E009FACB6F3F2A2BB9F23B1 -:1064E000BE596D0F2EC673CF586E86FE57A7B6677E -:1064F000DBA0EC6E7AA6F9C8202CCBF6CF34872728 -:10650000831DEA92FA39988378EF291B501E652A79 -:106510006BBCCC9CFC29E7577BE0CF870700BFD43E -:10652000EDE6F7DCF4E06DD75A05D7A35F361EF130 -:10653000356B424EA4FE8075FEB26C467E8A1E51BB -:1065400022F90ADEF7D19A69CE57F941B222E21652 -:10655000F0BD39FE1877AE8D8ECAE0FADCCCF3427E -:10656000E2E9FA7652495B52069E470DAD52510F51 -:106570003E633728AFBE4B23BD7D4AE6D537D8C929 -:106580001EAC11E75CEDCB43AB46A05CDCA2F9315D -:10659000BE509DD75682F650F58B79FE2616CBD38A -:1065A000AD4E6DCF1CE38EE5E9CAF20A1197CA4AD7 -:1065B0006D484D2DC4FD98B5B9B85F52C7DA6EFD70 -:1065C00009C2FB86CA90DF3FDD372905EF1DAA858A -:1065D00032C6C16A3B8EEA2168776512BFEFA6AE6C -:1065E00003F8C6CDEFA1091430B641339250CFFF66 -:1065F00032D030124DE24DAE5F97B9FE81B127F235 -:106600000306D2F995BB8F353BB1AC1B23D8682C60 -:10661000FF6B33F259F5681BE559B2F0BF1E0C0C45 -:1066200015FBBD506E750D9A6A8E7BE7887386F5F3 -:10663000EBDD741E0CD6E58DC8DF75EB6C61DC3FBD -:10664000B3393BE91CD02B2E26E8633D3F75BFC212 -:10665000F56178018FA72E9D91F66D3A3FB532DF37 -:10666000085F20AE5B793E89CE49C9F295493EEA82 -:10667000BF520BD33E52E5792F9DAFFAFB8DE7B4A5 -:106680009CD7EA3D9E9BE091E3D5C4C623BA1E1871 -:10669000F3FA8343816E4BB7DB6D0E13DF2DDD2ED6 -:1066A000F6E75D812CEC2743E77866E80F02AFD16F -:1066B0001D37BC1CD6B241FF4BF90E9F6B2E9B8C35 -:1066C000748BD533ABFC07D01FBF274996FFBDB9EC -:1066D0006C6082F64971EDF365FFEA4AEC3F1E9E5D -:1066E0008CA458D909EDB5BF3A7ACA08DF5A5B5C69 -:1066F0007F69B2EC5E89E34BBE6ABD3BFD5018F882 -:10670000EA9ED4B612D4FFDD0B980FEFD1427EF58E -:106710009BF46DAB8BCB75E5F97C0BBD63782FB02B -:10672000D0E5E3C66CCBBEE7A2394B697FB6D52571 -:10673000E8C5C2FC9CCDFA012C628A07FD7F38FEB9 -:106740005638AEEC038E6FFD17C3E1B38C1783632D -:10675000A805BEBF158E8D37147C3B0F9A3CA084D4 -:106760009DF9B82EFC8CE7C5A9A965BE26DC97F972 -:10677000994671FD618CE7BBE46BEC883606E5A7B2 -:106780002D807110B69CDB2BF0BED53E86D621F253 -:106790001786EC76CCC5BC8DFCCAC0627CB2818504 -:1067A000B4EF23F749998813CA7D9E61062BC17BFC -:1067B000FF8E27CDA5752A3F38A71AE3EAAA675CA2 -:1067C00012AE870FD822611C2F7C1F1F2FC31669A2 -:1067D00077A2BDE41D6AE07A97E1E5FA8FAD2AA4BD -:1067E000F56FA32D7FE46D00C74AA524E935C47376 -:1067F0006A3EC5C7F13DDEB3B351AC5B6AAADFC0E8 -:10680000756AA358B75608FD2EDF27A705E7A21D16 -:10681000F1F355D3A63A27A11E0AB4F683F5E6DEB6 -:1068200055D356664FC2F5C697EF84F5E5DEA469E9 -:106830002B9D30998D4DBEFE466AAC3CECAFB05AF4 -:10684000939E98B632007AA7D9BDA40AED1CA83F42 -:10685000847EE2136952EFF0FA7CA9A7502F811EC3 -:10686000539B7ACA61D44BF93D7A671AE99DCD8F63 -:10687000A9545E0AE3A11D03F308E3FD60DDC33400 -:10688000F28F5C004B12945D23F269FF0CE6CD920F -:10689000D0FF1FC1EBE57E873ECC46FB1DD81EF125 -:1068A000E8CAE1EDF559FCBCB4EE7193DF26F74F71 -:1068B00054B17F9724F254146316F9C1CE35639610 -:1068C000A01FE51C6ADD9FD6E3F259D4F8FC1677C9 -:1068D00094ECAEB62411BFEEC7B2E9DE04F11E2C73 -:1068E000E531F8CCBCA9B984EED3F33003F3A9B3F6 -:1068F000435166B697E4D301EBA8CF24370E370B8C -:1069000024CAA75898CCED61F7798DFB890AD8374E -:10691000B88E7A841D2EEC23BBBCE7286EDD95F67D -:10692000925DDCA7B774C6942C3C97A4BA034EB40E -:1069300073F61963689F4665FE6B4B4CF64E737495 -:1069400006C5273523C0D0CE795DD839AAE1676660 -:106950003BA7A5111C7058AB361517D0FD358FB865 -:10696000A2CE2148DF076C7ED41B07C65485158C48 -:106970004F2E6324A79B8A33A7E03EC3062D98724F -:106980000BCACB5B309E8FD38DEF73AF50309EFE22 -:1069900085339882FAE09E5466F1A3AE4DE6FEC8B8 -:1069A0009624AE7FA49FD002F044010EEDFC48BABD -:1069B000CF67B4B04BF53965142FC334208C7F3AC0 -:1069C0005803E587CAFBEA1CD9364BFEA376BE887E -:1069D000E2895B92F83872DCBBC47D83B2EC640D53 -:1069E0003C6E0C3C9EC87FAB15703AC01EF2917D88 -:1069F00012B7FFDFDB3E227B45D2A7C74E51F8B965 -:106A0000D0BEECA3FAF3368B9E8D9D67D7492F9F9E -:106A100011F705C83C10B7D0672DD9A1B6ABF2620B -:106A2000F70368221F648DB81780656BDDE673F885 -:106A3000C9188F81FA669117921C77AEDFE55E4A1E -:106A4000FE826BB8663907E66421FACEE1B3BED7A1 -:106A5000B2E3EF0B08F7E48151DEA2C61E56E872DE -:106A6000006EEF0E107958A793DFA77823D8BB07E5 -:106A70009CB42FC1CF89CA78D837B58F5F47BB8AFE -:106A8000FCC2E9A3B1DF45B81E613C9B0573F8A6C3 -:106A9000633BA3BCA1247F17E3778E91BDA54A3D3C -:106AA000177EBE19FDA80CB37D67B2D72E5FFD7CA3 -:106AB000737321F91D545E74771BE9C1952E595EDD -:106AC0004D6558AFA2E8F7B09D0E1FF2137C1F4032 -:106AD000B961371490BDACE6834B0B7097E1FD872D -:106AE000B83FB0D3B111ED59F06BE7B94C71B2D3E7 -:106AF0009E63B9AC30617F614B7FB9DFAC3F18BF9B -:106B000003F38C647D99775D54E5DFF9F03B36B093 -:106B1000F3FD30F4FFC00B0EBA9744DEB31CCFAFC9 -:106B20005392B9FF8E7AC39CCFA9CFA90820734A8C -:106B3000F974642759F2BFA5BC6AE787937CCAEF52 -:106B40005E4FE2FBC79A16A0B89A76BE90E47F8BA0 -:106B5000A06B4BA3719171D2FA18670CF5D3F7387B -:106B6000C5424F30B13FA619E67B64FA92D7F8FDD3 -:106B7000C078FD269F52BFED15FDCF4DB6C697AB31 -:106B8000D6B51F4616FA892D54913C1EF3BEDEF38E -:106B9000E2525C638B16A1BCDDDEFB7D1D4EEE4731 -:106BA000224E50B0F5B6FDC8AE0DC9A1F54950AEA4 -:106BB0004A16FB00D9B0AEA9B86EF1BCA587B11ECC -:106BC000F31B42BE87A6A29E9A554EF1EBE7928335 -:106BD000BFC1EFEEBEAE98620512EED58D3CDF4E22 -:106BE000EA4B37E20BDA3BB4061EF77407A2685F84 -:106BF000DC97FCF6540DF950E372B06CF5FE951875 -:106C000017716A7EE22BA7DBE6C3F5DD09FE1DAE38 -:106C10007B4D6E1BC59356E03DC0F0BE599969A0EF -:106C2000BC2EF1E467B10BE847ED7CA6D0BFD67B64 -:106C300075FEFEE3A4D3F7BDEEEF3930298AFD6976 -:106C40007E46F93388840F4D7A55AEEBF1DFC5F7F8 -:106C50002FF129F1EBD04284571DED8604703D9948 -:106C60006CDDB7CD92FA33F59D8228BCAD55BABC28 -:106C7000689F805E7C12F9A46E54F7AF151FE9D3AC -:106C80004C6ECF84E57D0596FB91645C5E7573BBAD -:106C900046C2BFE4B5079CE67DA77878E3D74B777B -:106CA000A1353FC3393029EEBEE0263E8E1624BE04 -:106CB000B14F0E38514E9A8C3106DA2BCD9AEFB780 -:106CC00001CA2BB193DD0C76B8657CF9BC47DC0FAB -:106CD0007C54D851F1F51E719F72FCFBCF85FD707D -:106CE000CFBE9B480FF7453F3C508DF4F5E433038E -:106CF000CFE7D805BCDE8BF4DB171FDDBB8FC77574 -:106D0000B589CE08BA58F1E3A9F66000CF93A9A3DC -:106D100019D9BBEA203E3ED0D2C0B8B0775C1A1B6E -:106D20006E5A67EF1E7A1DBFDF39C3A0F37DAAC775 -:106D3000164C64674A3C1D4C96F75470BEC9967C4D -:106D400033ECF7740FBA896FBA13F1CDC164AEAFEB -:106D5000100E333DEF1E9A9F95883E31BDC8F9EA6B -:106D6000627CD121EE4BAC45DC807F5323CEDB9F90 -:106D700012F704CD4B16F70519DC2E96F75F7468F1 -:106D80008164B4ABE6F5EC5307E85C4A8D2B903296 -:106D900009F9F228B77B3F2EE1F7967D6C0FA4200E -:106DA0009E3F3EAA2A4DB4CFCFF302659ED5C7764B -:106DB000DFEA91503FFF176AA089AAADF6DC2916D9 -:106DC00018FBCF68DFEE5269FF28EFBEB9EA2868EA -:106DD0005F01861EF2D1BC527718D7DF8EDF37BC39 -:106DE0008F7A68FE630EDF7218E7E0BAB15F62F96E -:106DF000C41A8FCF4171B27C05EF155FBA36CFA0B0 -:106E0000FDA3654CD81943CB4B8732F614FE53C60D -:106E10009D9D74CFB8A80FB694C1FC466674D8DCAB -:106E20000053C41D6CC1734E2B9B82D9E8FF5DBB20 -:106E3000A6A005E38F999981CEAB411FAF5833BC13 -:106E40001CFDC18E47447FE1112DE8EFBD6C0BE5C1 -:106E50002950FFD49A29E594973B44F67F03D5CF78 -:106E60007BFCB22F8F1988D3CA728C9915CF91F001 -:106E7000D49697826E5F30599697E8584E4F669633 -:106E800038983DE64F529CADA3C77FBCA31CE3607E -:106E9000F3A734946AD07F9EE7A72D85201A13DAD2 -:106EA0004A8C005E99EBB9AF3C39036FCD0B54E3CC -:106EB0007A32D2737F39CE27BD9FB5FF7455C45344 -:106EC000D9BA16ECAF07BEF0D6168CAFCAF66FDE95 -:106ED000F34E4B78608CEFBF1BBB5FE93BEE0CBA07 -:106EE000B7EE3086D8729775EB3C9F57E4DF0CEC19 -:106EF0002AE27945A23CBC8BE75DCB72362F772C1A -:106F00004FBCCEFFDCCBE5AD232971FDCFDC5C5F50 -:106F100000DCA4E7538EB1C0B6047254E17653BBD3 -:106F20004360E739D362F274AD83B18998DFE4E45A -:106F300070CA7EE2BFBF538CC3C2D7A6211FCF1435 -:106F40007C3EC4AFF03CA55DC911FC3D06F0B2B477 -:106F5000EFC17CB68A78C45617FBE12C183A338906 -:106F600085F0DE9C8C7E502EA4EF03DBDDB1FEDECF -:106F7000E022CCA60E096EC6FEA666E58C5E9117D1 -:106F8000EB07E06E768EB1C0AD4D4CC3FA707F8CCE -:106F900093F4E0B390CF03F884F005C33C8DBF1F9A -:106FA000D0D139321FF5EF484CBA31E9F9E2CEEBD6 -:106FB000E83CCD52AFD81FF1F1EF334A79DE4BF701 -:106FC0008BC9FCFE4C676781793FEB21B7C833B8AA -:106FD0006BE643740EBAD3CEE8FCC2F6920BE61D04 -:106FE000D6605CCE6437D66851F2C76A302E371649 -:106FF000FB7B83CE1F623F3E117FC6B85AC68AC450 -:10700000F497EB60CD798385FBF5D697B1FED35924 -:1070100078ECC5E715EBCFEA37F6EE4F17717C81B8 -:10702000774DE05D4F0CE75EC9A7806F9B89BF1667 -:10703000087E93FB8167768ED868DE7F95E7864071 -:107040003F3F8DBF8F10EE4C227FA5580B5C83ED28 -:107050008B3BD3687F40F287E40B49D78EB4068A16 -:10706000B7743FACD039AE78B80E49B8D6F17BFBD7 -:10707000B2E68454F33DE3521EA0FF0ED1FFB8895F -:10708000243F8F727900B9B905E517EF61C179F82E -:10709000BB8ACCBF4720E12F425E1C4F74E4F87FCF -:1070A000C125F25738DE7AE3BFFF45E8994BF42C4F -:1070B000EEDC4FF3ACE9436EABBC5E9EC7762CEAC8 -:1070C000F541BB3182FF3BDA3FA47BC53A76A94C40 -:1070D000F1F179A3DE2AEED1C7E35F9D02FA38AB66 -:1070E000A70CFAD28774E8D19F51A733D6FE07DEEA -:1070F000F1D39A515F8A7B7BD355586DC6C4E0F8B3 -:10710000939BDB57134389E3580D5E8F458F3DBC3E -:107110006C0AFB10E67FA59BE75F4DEC0AD3EFEA14 -:1071200048B98ED753FD3C9C8E86E7FF929E725DD8 -:10713000444FB9A49EE2EF0FA1CD3B06D7D7AE22B4 -:1071400005ECE60A5B2013FDAF8F8EFE84CEA72CE4 -:1071500012F939A3303F07D7CD63415A573EC54A8C -:107160009EA733D09381F9DAD63C1DB6999F6B8DDB -:10717000E7AB181F8585FD26E010EBC1B58EAE6725 -:10718000793CC32ACFB20C70D6D98698EADD7CDD73 -:107190009274007A37D33DC7428E8FEFCCDA80FAF3 -:1071A000F64D0FCFB3491F12188DF3977209EBAA52 -:1071B000E013DB0FAF7373BD715D02FE9DECE17AEE -:1071C00076C13ACE371DFFBBF41AC47BC79B69A9B1 -:1071D000CB4D7AA24CC8B1EC57EA21F99DAC9F2265 -:1071E000FA9BE6E17251E6E67C877024CA272833D1 -:1071F000ADAFC43FAD9C7F60BE61337FBF29FA8DC8 -:10720000E153ACAB02CFB53AE017F0B7D51EEE8F25 -:10721000F949C59D36EAAF629787F2322BDA391EFB -:107220002BDAF6D9AA4DF889EF6FA987CBD1067171 -:107230000FED211BF01BE2DDCDE13BB33387F4E71B -:10724000220FB71B2EBE6E5C9A9ED920F23180BEF3 -:1072500094BF58FBD2800D563DCDFB4BEF175A81A2 -:10726000E7F0D21F627ECC29033C451580FB4B8F93 -:10727000D03B7A40C7F3B6DD0F33DA8F1F362730A5 -:10728000DA07E5FAA07B8C02FD15B4713D5C7C3F0A -:10729000D83128774EB92EBCB6CD3CDE9D1E8FE589 -:1072A0001C61C53A8EBF6160FF3C8D4FE8E759B263 -:1072B000E3393CC71F6CBF0AE34EF2FB5641FF8B1C -:1072C000C1578CF08D8BC187FD53FE8A3BB81CFBE8 -:1072D000ADFBCD8E01E67E1FE8E977DE1417EAF9F3 -:1072E000B5B0EE9074860EE0B98B8ADDA906DE9308 -:1072F00000F26C437F478E5BA1C9DFCBE92AC67BD6 -:10730000C20B7AC69174FDDD33E6F96FF2B8FFAEB9 -:10731000F4EDD043349FEEED00AF2F86978EF6B993 -:10732000CB5DB84E1C637E5C2724BCC3E674793108 -:107330005FA45EAC1F305F1BFA2FE9BFF0B1158868 -:10734000B7CE29744F423C5F4B3A0D675C7EA49FD9 -:10735000361C03FC50DEED2912FA87919F7BFCA5B9 -:107360003D4FF37B2D385DEAE7703A7679425F7ADC -:1073700032627208FA9CEE2FAEB8BF471FB5F3F722 -:107380009DB973009FBFF64839B7D2253DD8EEA20C -:107390004B66055F9F7E71546415A7338DDFD1EE78 -:1073A00089280A9EA36D68427F5BEA0984C79CAF67 -:1073B00024E1E9A123033A8E8ABD1F3687F7570FD0 -:1073C000F28E7C54A33628390AE9018AAF66A11EE1 -:1073D0008072563B6FC776F3FB1B249E6A6E844E09 -:1073E000C1EFFC574F21CD43E22B6B4ED45653884F -:1073F000F9CAFB077F64A2F311B15F8078B98EFCF4 -:107400000DAEAF6BD4E040F45B599683CEA1C23A87 -:1074100044FAE5908B692EE8EF5578E2BA3455BD11 -:107420008DCE094D1DA2901C830690F11EFA3DAE33 -:107430006BAF4EE6795B7FF9D1509C674632E743EC -:10744000E8C729FA71D23A28D6837FC905BB4E898D -:10745000E9E5438A42FD1CFA87CB37AE50627C894E -:10746000FDA1FD7448993590D6CB8E0C911CD46546 -:10747000C927EBBD9E75E562BDD95F44FF2EE66F5F -:107480002A774D039E9A30BD3D8A574E3785D56980 -:10749000FF08E34E057FD385FAD3CBF9FA505E5847 -:1074A000F5225CC314BA5FF97052A890DFD3CBC742 -:1074B000C914719B4C91AF8CF6023E235EAEFF4720 -:1074C000A6F0E78FC533D39B38CEB356D4D78B7B8A -:1074D000AD579524CE671BE8552CF1966BC5BE05BC -:1074E000DEFFEBE57EA7C8B3E5FB1C60DF137E4B38 -:1074F000EF9A43FB765F745E9FC2EF6FE0FAE04362 -:1075000025F0EB1B157C06E9FEBCF0DB2AE5BF7F0E -:107510006404BC98DF549B94380FBB44CCAF56CC6A -:10752000FFE3467EDFC27CDC4F03FD31D6CBE7B103 -:10753000A86D6C39D27BD11A85F6D3E4BEBDA46F99 -:10754000E57AD5124F9F8FFB69FDFE163FCADF8794 -:107550001F35CEE247C971E3FDA9E38DD996B8FF87 -:10756000BCB621E29E0BDE7E3EF313DCF35B0758D4 -:10757000F6FF586BC6A5DD030AFE5338217C3AE9B5 -:107580005BF9FE78A39385CD707C3294F21E067A67 -:107590004337217D637024B3B0190E3699FFEE9501 -:1075A0008BC75DC10EE7FE0B3C37B8C94EA77B6A9F -:1075B0007BE260A03F8C14D4472573BDE3637E83D8 -:1075C00094AF9AC989FD8771C2CF1DE7E6FE71CAE3 -:1075D00031E94F27F9502F4A7B3CFEBB861EBEB5D2 -:1075E000DA93178B3F00FF86CDFE517CBF2DA2DFC3 -:1075F0006FCE2FF97DF04BC17F89DF5D3C3944F1BF -:107600003DD6A6502ECA8432AB1FF48897AFE78FC1 -:107610007893E97B695757CCB1B67B0CDB8DC76794 -:10762000F225C573CCF6BB3204F51FEF4FFEEE4ECC -:10763000DEC93729FFF377E827427F6FA404B6201D -:107640007FAC11F9F21BFE7A207B3EDA43FF6CA778 -:10765000FDFA924797AEC07C6677BB62D0F9A35D16 -:107660005679F8CEB2F6C115808F7641A71A3F9FA2 -:10767000478D3FAA0F75637E351F7F60FB3E453304 -:10768000F1DBC04ADEEE25AFDD129FD98B65E867DE -:10769000B7D7907ECBBE19E9D83EA0A11DD01F7FE1 -:1076A000EF06E0E9DFC0C88EEE3F4EA1FEBF336EAD -:1076B0008382BFBF25E7D96A9B5568C077AD99C95A -:1076C0007E5C6F328DD0419C67CD7BD1282E8F138D -:1076D000DEEBD4D0BF1A6E040EA1DCC979F954A335 -:1076E0003FDAEDC9EF71F8DA7AE24A7CBD616CB538 -:1076F000B04337727B4C654718B7C7695DCF5C3EB6 -:107700009CD63D399FCC34B16E64B210E61F43FB6A -:1077100056B2539C7CDDCF5CCE7F2F4FD233E667D1 -:107720008E18837EE69035516D1E7CF7D27A5BC24F -:10773000FB353E14788779BC6F9EC7C5F4956C679E -:10774000EF23CE28F93D797A62FF9DB17BA9BEE493 -:10775000D1F49B492E9B75BA0F51E27FB811FC1CE6 -:10776000E1E9DFBE4141DC1C177905C7573DADA0FB -:107770001DF9A3C5CC5013F0538FBC2EDB31B8C21A -:10778000A437A17FA2C786B83C71196F71A570FF9D -:10779000E71623C852C653DE2EF9CF8B37F3DFDD51 -:1077A000E8131F97882FA592DBE535B3F9EF8E9686 -:1077B0003CAA11BDAB9BF9EF0ED66CDB4EE7ECD8C3 -:1077C0004F991FE5BDA67DBB5201E3566FDBAE2C82 -:1077D00030E16F404D84F2AB2FF3C87D8728D9CDBF -:1077E000F17C8DF102B4530EBBB8BC9F2A71877136 -:1077F0001FE2943D5483ED4EE524FB719F52E2FB62 -:10780000D5EDD3E8BE03CF0E47149FADB68DD94E4C -:1078100068D73A52F7231F0D3742C3102F695AB069 -:1078200003BF4F4DF7F8711FC3E7606368BDBE44E7 -:107830003C4C88E387093FE57272638A57C805A309 -:10784000BCA7AB533CD27E22FD74D8CEE7B1837186 -:107850007823DEC0B814E4C323FC7713FAD74415A9 -:10786000CC17891F37C64F812B11FE4B87B35D475D -:10787000BD5E2DF44CC9A39B950F4D70CF40A30A5C -:10788000F973DB0605E364504F7A06DA33CC4BEA32 -:10789000BF8DFBA5D550BFC0A457E43C12E897208C -:1078A000C2E77EAFF320D72F51BE2F20E08DA7E790 -:1078B0009C141F8D5F0EE601BDD7C3C3D12F3E9C24 -:1078C0009F44FD49798F97CF3982CFFBAFDFACD88A -:1078D000DCB47F4276A4844FB67B23654A08E199E5 -:1078E00030BD93F050BB5EA3F94CD583436F33C9D1 -:1078F000435D0AB7E3F6DFF83EDDFF73FFAF8E129C -:107900003FD6823F4DFE44DB51FD7A5C57C24FAA01 -:10791000B8DF750D3749D883E25EAC6B3AB8FEAD7F -:10792000EDD8AEE13D92924FF34EEEA7FBB46ADB89 -:107930001D0CFD28E0BFA548EF783EBD547A821E9D -:10794000E27E525817F1BC501EFA39523F47843D2F -:10795000CADCFCFDBD024F31FE09B5A458F4AB8B67 -:10796000E422EFE498FD989759EB57E8BCA48427EC -:10797000BD34B17D2EF5A2D4D718370C9AF4FA5A3B -:10798000A4EB782A47B93FCAF2715D9670C6D3E975 -:10799000E514AEBF13F0D3232909D62BB97EE73DFA -:1079A000B643C37B91249F5C83F435F1C99329FCD2 -:1079B0007EDD275334EAFFC112BEBFF8A09DAF534E -:1079C0000F3639295FF2D59B78FE96E7663D8ACF60 -:1079D00043B67935587FA83F87A3D5B69CCED781CB -:1079E000FC3D95427CE2655C0F72BD77FFF35C6FF6 -:1079F000D584DDE4CFD684BE5F4179ADE92E3FDD8D -:107A0000F7193AA85FEF89E1359E8F7C3BF6D1EFFD -:107A10001D5FD3CEE50DF426F1510C7F1CCF524EE5 -:107A2000A43C44E4FE0DF001B77BB8BF5428CE3B24 -:107A3000563AFD745EB252C4550BC5B9C7E2630134 -:107A40005A0FE6093A14D982AFE2BC2AD6C4C5550A -:107A50002FD1EEAF5EF6FA08FC5DB0AAEC23F494E9 -:107A6000F2087EA9456EDF11FEDF1E41EF3F08F9E7 -:107A7000AF1ED74EF256FD5103C9A97B3AD757EE38 -:107A8000F7AC7A96B17BC47CD7D0775393DBCB71BC -:107A90005F78EAE30ADDABD9179C8BF01C18FA6F0C -:107AA000EB0F78E7A23C8BDF8792E765CE08393988 -:107AB000B55515BF97D9A05FC8AEBE587F2CFA96B2 -:107AC00042F795089FEFD4B6D2497F44BF736B0A43 -:107AD000FD7EC967DBBEF7E33FA6E3EF835CEDC73E -:107AE000F53F7D4590F8A53BC3E5DFC8E3ACD33156 -:107AF0000ED5D47EC08BE76B3E7DFA8A31A88FF11C -:107B0000DE2D9CFFC9E7D5658897E54F3CF72DAC86 -:107B1000AF8E28FDD02E3DB5F5F1FFC0DF81AADC88 -:107B20005C4FBFF3BCE2E957C8BEFF3F75A9C786EB -:107B300000800000000000001F8B08000000000013 -:107B4000000BD57D0B7854459A689D3EFD24DDA140 -:107B50003BE93CC9A393404025A1131208F2EA2453 -:107B600084872076408620AFE61D20241198591C7A -:107B7000DD9B8620221767E2EA28F8DA0E838A3333 -:107B8000CE18306A90A0CD43C4195D5B040767919D -:107B90006DD4419090F446671677B8C3ADFFAFAA95 -:107BA000749F930EA83BCE776FFCFC8A3A754E3DCE -:107BB000FE77FDFF5FD51A5FF3DF52ED8454EFE9E6 -:107BC0006F3510422EFEF2E1716428218D2D8DFA61 -:107BD000A099902F7FD98CF5C3CFBFF4C67FD3F780 -:107BE0006ADCB14E78EFCB970FE9E1798D47EB6A0C -:107BF000A125F11CD5CFB2D0D2FB824C1209994AF3 -:107C0000D8DF637B0FE91D79B4DE221142BF27550F -:107C10007ADFA02CFA5DCB5EED1233BCE123A49891 -:107C20008EFBFCC2511EA8B7251092127EBE554F86 -:107C3000BCC6385AF623C444CB4BA566AFD49F903C -:107C4000D565E6AD505EFA8DA9CA47BFABD50773BF -:107C50006D309FA1C405F578AB86900418E76E5D82 -:107C6000AD19BFC77E3ED21102651EF192F34308E3 -:107C7000A16FEDBE361CC6FB2DBE4FDF2B3115129A -:107C8000327BDE3909E61333B45EB71AE7F96BD6F7 -:107C90004E571DD93E623D1D8F8E7B0DFEC687CB94 -:107CA0003CAB19DFA700C132B5B532CD01EBB71B34 -:107CB0009CB07EB1BED46A4FA3853EBF6DBDC729BF -:107CC0003B0879FDC289890368FDF921D270195EEC -:107CD00097A5856EDA7FADD78CE3ACD950463EA32D -:107CE000F31D6F95F0FB442BB1DF4AD753A12576E6 -:107CF0003394849CD41542FFCF62BBC3405CA488FC -:107D0000966FCE7E7623FDE4319D27A518FAD91A09 -:107D1000D03BA0DCCDE64FBFB79A0BB13FEBADF047 -:107D2000BD91AC85EFBA364EB36F93B0DF802E2E87 -:107D30003C6F424219B3F2587F4500A7C9DE2A784A -:107D40009F38F4B8BE2FE115C4A3377F7E1E940F71 -:107D5000B1F96A8807E825514F4B84AB27AB92D223 -:107D6000CD7C6B6995B5385C26F663ED6AB83E0547 -:107D7000ED149E67AC2E2CC99E784246F57E4F943A -:107D800002FE876777EA8374DC470F9C43BAAD0530 -:107D9000BA85F13D9FEB611D826E9708BADD7F0EBB -:107DA000E976499B84F454DB56A0077ABDD4E022DF -:107DB0009F69699DD3DF63527039D0B577BFC9FA27 -:107DC0002C8553A7A0CFEDE7CECB141ED96D290E7D -:107DD000099EEF6774FA9646E30538BDB5EB96E663 -:107DE0004629729E1B113E5235413EA9AD273E03E6 -:107DF0006D2F7D7AFD8929B4BEA69A380D943E6A0E -:107E0000557494F5CCA75B805E6C35A4C8E480758E -:107E10009E9D3880F65F5B438A814F5327B8F643B7 -:107E20009DB4496410D4ABDD4B61FCDBEC2B9D327F -:107E3000EDDF36C1DD0AE3DD661FEB94697F8FA5B8 -:107E4000B76C31D2766F05B13EEB00FC36956969AF -:107E5000FDB10A87954292C26D7732B493217AE7D9 -:107E6000B340C79EA535D05F6DF25C27D0492FFE89 -:107E7000DFBF7108CCB7D6D1CF69A2EF4F6D939019 -:107E8000AE88D74C60FEB514BE509FEA1BED83F957 -:107E90005CE6F01370ECD40516C0FC3A5F31102F8D -:107EA0006D9F3A81D1AB6D420BCA8FB7F74F3A2E17 -:107EB000E587E9D2F2AAC10FF538AD5572825C228E -:107EC000330D91786DD291856EFA9D6D32EB2767F7 -:107ED0003BC3EF739C9F9E03B981A59EF36F13A3D1 -:107EE00077AB37DF4DE9E132C73FFC3968BFABF113 -:107EF0001F143F4BFDC84F352FB2FEEC0657C1BAD9 -:107F000008FAB59713E4E33D26B2B0923EDF63630F -:107F1000A59A5EDFE5F3C87A662DE27D09C53BE0F0 -:107F200035753B7D0E70A3740170A378443AB8CDCB -:107F3000BE02F1B664BB7417E2D13B82403D219E84 -:107F4000AD53DD7F80CBC53D26779144FB0B255893 -:107F50009CBB24988F4B63827A81CDB98BC0F7EE9E -:107F6000DD305E4292C9D91821AF08711769E8382F -:107F700017122D0CDFBEF7B533F2801F1DD86F82AC -:107F80004CFC04E50FC976E785BFABC861FD55F031 -:107F9000FEA63579F349368307C285C3C3B7B15FFF -:107FA00055A43CFD08E041FBF5DD44AA406EBCA5AC -:107FB000276623F46FA5E3D0FE12778DFEE5369C8D -:107FC0005F23BEF7A6D58A6545BCBBA81E44708E4C -:107FD0007B3DC045AC530D8FF91C1E87672F28D001 -:107FE000001DDF697602DF3D7A405A8C74ED355210 -:107FF000A604BA677C48283E802F88478BF8A8AD36 -:1080000077FBA2D37D25F259ADDDE4344948F72E44 -:10801000D47F5EB38FD13DD37F319399BE0239595E -:1080200099D75B1E083903FA0DE859F045EDB860A1 -:108030002EE0F7DBCA954E1DE3F34E0A07E023C19D -:108040003796D719BF6CDBE82885F66D94EF23F1DE -:108050007D4CEF45FE3D96DDCF09FDC23CDD96B07F -:108060007C4FB4BAFBD9609E1AFF166D56581ED7C6 -:10807000BEFE60AE270AFD09796CD4323967F4C5BB -:10808000F858BF6C3C2305B7A5104B2FE8A3980DFB -:108090000C3EEA7ED26D664E8F46EBE7548F4FA7BB -:1080A00048EA9F43C8648D27DD46FB5F630C1EA32F -:1080B0009825191B427A984722E82EE09F5D313EB1 -:1080C000905B8989C4B32F4ABFFD6D8CDE045E9A34 -:1080D000E2181F25C6B2F747D918BD0CB5313E2DA1 -:1080E000E3EF8BF90BFA77683CE788DCB71E13DF08 -:1080F000D17961BB980FFD7E2B61FA17E79BB829F8 -:1081000077D7B6087C84F9E8A642C053CE76BF760E -:10811000B1393C8ED0A76AFCC3FC817F603D95439A -:10812000FB7EAFE910E347353D4EE17C62B0112C98 -:108130009B74FE3F235FDD6D21BB607E3B882B9EE1 -:10814000CEABEE8DC18C1F5CA15CE8FF609C6737F5 -:10815000E063E4044EE7F4F90CFA7CB596780D146C -:1081600027ABF7E87C4123E3996BF4FF62C0139DD2 -:108170004797C5E895299DBF1FE7A982EFBD65C454 -:10818000E907BDF4532A3F80FF88BF18E44B1D095F -:10819000C6029C6BE5402EA1F8BF1AE3990FF4F8D4 -:1081A000A9269001CF090922BD9E31C5E613DA5FE9 -:1081B000ABDE9FFE4F30EF7764B28BF6D34D5C534E -:1081C000611DDD014D9C97AEE393B60F7F73807EFA -:1081D00035FFC0E5F9F70294B6C52C789296F38C7A -:1081E0001AA37678181E672CD1E5EB8F395D2434FD -:1081F00032BB2BB4D1E003F8A8DF1B1FC7F05F77B9 -:10820000259578E3239F33395AA70DE9C184ACBB88 -:108210009241BC74DC4F34A4BA258A9DF9A18DE942 -:10822000AB564AFAD1DA4F733ADBA323B93B603E2F -:10823000CD540E02FCB40E9417D58F6439B7D16AB1 -:108240006B76E818D811A15F4828FFCFE898DCA129 -:108250007F771A4784F5279827601F565BBD7E0DF0 -:10826000951BD5EB2D7E391F9F6BC700EEBC562D9D -:10827000C8C1C55C2F2EA97FFB1B2996B66B8971DF -:108280000CFDEE0BF3D258500BCB7FBC2E118CEFB4 -:10829000A4794DC89F844CB0823D2EB9A6C9D7623F -:1082A000AE67CF69D16E477AA1F82D8F733F09F879 -:1082B0009ED79FC17BDEBA189F3742FEDDC1E1A386 -:1082C000A6B33D40A374BE6725A657D4E3BC1057A0 -:1082D0003609FAFDABC5FD1CF6BFEE32CAB379070D -:1082E0004C19A0B7565FD1205EBA0A02B91BB28002 -:1082F0009E43197FA0F05BDD6EB07A1DD0AE57E0D3 -:10830000F5D3062AD072C3F5C517064E246680AB96 -:10831000730BE079C9D618E21D129E1F18D240B720 -:10832000B55708F6B3B8FDEDD320A76BB541A48BC4 -:10833000C54633C2BDF68A16E741B6EA3A82E27B09 -:108340003ABFF858573BCCDBFBC018DBF95BE8C3FE -:1083500024FA1CD7E5390CFCF4784C2C71313EF032 -:108360000DA6F3EF363AFAC75138D4E929DE876112 -:10837000376E6384DD44D22C4ABCB6BFF30DCC67A4 -:10838000A9D1A307782CABAAD703BFCDEBEF2FB6AB -:108390000E8DC4E718F9DA2DDF1E9FCF73F9F2892D -:1083A0009ED27B14FE3ACDE5EF782E273E49657CC0 -:1083B000F14906A9DE07E5CDB4A4DF7D92CDEB85BA -:1083C000ACAEEEE72AE78B4FF2991EF2AE657A412A -:1083D000FD5E271FAF3CCE751EE0269E0F8F63CF3C -:1083E0005F88735D043853397799D3A1DF46FB9BCF -:1083F000F7A601E9906C0EE5021E7BD695CBE79BB4 -:10840000187D5EB670BF5F437FF43D17DAE36F9867 -:108410007CB0BF20D3A8DC0539BB369D809CA5E38A -:108420005EC5F772E9B8F89E01D741B652F94B190B -:10843000ADABD88178D9564AE913F8FFA0C10AFC40 -:108440002FE849D0919A7E4C7142AF31FD7A07E80E -:108450005719F5AB298EE9573DF02FED51CFECBC04 -:1084600081886FA433F9DBE3FBA09170F8BAE3E3F2 -:10847000509FFBF3DC79BDE12CE4DF27FD9474E130 -:10848000E3781CC0DFEB81731C7BCF9EC3F499B0F3 -:10849000FB6FE1EBDACDE5B428857E1A3959696FB7 -:1084A000ECE6F263B72D164B8A97C1B07EA1D77A5E -:1084B000E1FB29866FFADE5058CF3C4368413CD53A -:1084C0004B3FA2F68EBE10BF7B1EBEEBE57F98C071 -:1084D000F469DD5A0B017D3F228ED9B1A4289401A5 -:1084E000FD9121B4CC03FEA3F246BA31FE60AF9FEA -:1084F0004279E4F65807DB57CA7440E09921C40179 -:10850000FD517897C62584E1AD1EEF0C3451FB6E0A -:108510006A9CA43D0F382A200580AF051F7C659911 -:108520004FBBBC6C357A35543FFC58E3B903FAE9CC -:10853000B8E71DB4E7CFE8FDB94DE628ED7AFF3383 -:108540008F4BE1F6852FC85E3D9533AD818E5FCCB4 -:10855000A674B938203B61C8C5F7FDF9BD91602705 -:1085600007744ED8AF523B61BB96CEFB8C86E1932D -:10857000D42BF7FBAB38DEA9BDA42523C2F249E812 -:10858000FB95C43F08EC8225C4A587F2D3BB574CAA -:1085900023145ECBCCEB516E5D5C3B05EDE0E5C496 -:1085A0008BED4BB6EA3E8DD413CB9A94F5153B94E4 -:1085B000F5953E65FDD24F18BDF5A67B665F259407 -:1085C00047B71B1EE17479491FBDBD318ED169F9D2 -:1085D00003D31E47FE0FE88881D2C9FA83A5492438 -:1085E000CAFBA2ACBB924D7C117A286C57E412DF17 -:1085F00070E8EF2AFAF9A01FD8BFAE37B992609F92 -:1086000071A92CFA3CFE778FDDD2AF8F7E63B1DF8C -:108610004BD9D75F67DD1523BED7FB7B33F64BED18 -:10862000A7A8DFEFE670B81417BDDDD7D37F32EA15 -:10863000C5F0778C0FC2E3A4A15EADBB6255E8E93B -:1086400070BB9DE955BEFFA778F5A2BDCBED39AA59 -:1086500010ADE763C2724CD78FCD47F0CD671231B2 -:10866000A6A0BFEC612E479DF960F77E067615F057 -:10867000ED24C71B413AD525F78ECAD56687F94A3E -:10868000BD1E4A8F5F0623EC82B6388B1DF5B99369 -:1086900038615CC10F0BEEA9E8EFA178FB8FFBCA34 -:1086A000933C4323E9CE8BE3D7EA853D6756E871D7 -:1086B000A2D2F34BDADE417B6DA9D19D0BC2E94F0B -:1086C00007EF413E594EDC89C01F5D07076778FE02 -:1086D00007FA5DCC67A677918ED9E714A8946F67E7 -:1086E000F0F9CC6C67F6A2C6E8D2E1382EE2B026EB -:1086F000E2169CCD970A592DAD8FED993F3813099D -:1087000019C3E72FC1F714BE637949167B9261DE66 -:108710000618978E6722BE64281B47391D508E9716 -:10872000DC5A360F1FE27922A94F83F735C6A0CC59 -:10873000D649679008DFF7C00BEB165EDF7C67F762 -:108740008265F0DC6C41F9A3E7F3F846C84D2331AC -:10875000C2BA0D66FF4558978597DE32667F7BB3B8 -:1087600089B391BED68FB41018D76CBEEC85C55AAC -:10877000895582BAC9DAED877DC865ABD9AB198650 -:10878000F2F4FFA03C95DE5D0E78A1F29BF9A5FA0C -:108790006AD7FA71FF23E4631C9F5F23978F2984B4 -:1087A000C1C14EDC875C94AEFFC5B27C1A89053529 -:1087B000EEC1F177C64E3E0EF305C0A39E9FACFD01 -:1087C0003452CF24B8B50AF99754A5ACA77894755C -:1087D00023396305FA95FCEEE46BF1B8AF1B027E1A -:1087E0001A1D973777F663F312F49316AF51D82119 -:1087F0006EBECFAF8DD313F40F261A8D6418DA2511 -:1088000069F1CC2E394B314DF7832194E705E35DB7 -:10881000837E41E1BCE503D9B989E2698BC5B151D9 -:108820000BF6DE1CC9F92C92678B1FFC3ECD0B6C3E -:10883000CE6DD06E72FDFCFF40FB0732017BAB0EAC -:10884000FCEDF1F0A2B514BE6BCEB0E27BF6F210F7 -:10885000FA49430F12B4A77AD1E9553A7F0AEF5F7C -:10886000429DC2B76EA975F58BF4FD14778C538ABF -:1088700068DF0DED749E12A70B783E7E04EC6BD979 -:108880005F4E7B41C0057E0B978CFAB0AEBDE08891 -:1088900099CE23C753E004B21DD8CEE32A76838F46 -:1088A000C51528D7D279CC32B279D4B597DE514CE0 -:1088B000DB07068613882FC41C77CCAD81260DDD1F -:1088C0004FC3776531E8CF3AC9FD4A84CB83912AFB -:1088D0007E1B1DA67F6C2F10756A36B84630770553 -:1088E000D6ED8C0F9C44FC31FEBC9584FFE0FBF27E -:1088F000707F288F26849BC3FC469756687436D6B3 -:10890000D0F7DEAA9C84745807FB2E8A8F915AFFF9 -:1089100021E0EFD1BC2CE02559DC84F0DCB6D17F1E -:108920005897052E14B70CF511D6071BA1BFB192AD -:108930001FCB8CAA871B81AC5E03E30CED4E4F0569 -:10894000F0E3960A6205FBABB1C4E9B4D2A6D955EF -:10895000CCEF3AABCAE8033FFE2C2D61F12EAD27D8 -:10896000EB4794AF7E348FF97BA13E2FC29F22E26A -:108970001B27E93E666F147BE0B578A6C7C4F77580 -:108980009BF58A38D2CBF1CCBFB5337EE24FE2D92A -:10899000FCB280FFEE8BE77265081902722582EF48 -:1089A000BDF05E47E9EFFB920BCA762E1766B91E43 -:1089B000D1A11DCFE58390C36EE043FA5D4072E91B -:1089C000007E1F9731F89F285D89F26136F1E073D0 -:1089D0004A203A77A41F6972843D44C799E556DA64 -:1089E00047B3AB947541AF62DC391E65FB0C61DFA8 -:1089F0004E56DAB7F3FEE9AA0DF56FD2736BAE658A -:108A000062DC04F7FF75144F2C6EA2657194CD7A69 -:108A10001FD849756D77BF95007C741FE17CB457F2 -:108A20005A3A14FDB0D2B2083B62408D4F02B93FB2 -:108A300098AE2980780D61BCE8A4CE7708E228279B -:108A400057D215D3791ED1B378E45113F1823F5A2E -:108A5000D0A76506F3A75232C6B8489A35C609F4BE -:108A6000B4555388FED7ADB11667A4BF73DB464A31 -:108A700077117E578781145A39DD44DBFFBEC9E583 -:108A8000E16312F37F7BE71871BF9790E356C41B35 -:108A90001264721AFC883F897788F7D1CF01F1BA46 -:108AA000E1B4F449CC9EE9F95E269BD1EFA8923F50 -:108AB00009F14EF4F727F4CF43BF7D557BC16E9487 -:108AC000376693739014EEBFCAD3AC5D06FE83F68F -:108AD00066ED527398EE4E00BD02DE62480CD06B1C -:108AE0008F1F6F9F01FD783FD6B83F02BAACD1FB14 -:108AF000F389929EF1795F7A6C05A7175D997BCE19 -:108B0000323A9FAEF7F4CCAF751F417E7D79BF0D31 -:108B1000FD90DA1904F5C9E65282F4D0D52CA1FDF6 -:108B2000F685AD1AF7019BA526D4139D7113117F0D -:108B3000ABCC47715F5BFD94EED348BB6BD56E65E4 -:108B40007D3509E0BEBAE6C55EF48CF24BC8C7DAE3 -:108B500056E57764A0523E1670B95FE876CEAC80D9 -:108B6000A9573973D8BE9AF80D741DC5EFEAB9FF3D -:108B7000771ED39BE43909ECAD2ECB0599F13993DF -:108B8000C7C5BC3FB51E2AE6F6D4382AB760FF2910 -:108B9000EC23FA3ED68F6ADAE5644D785E45FC3BFD -:108BA000619709B92DF0525A424809A5FB643B97D9 -:108BB00043D9241BF04AFB477EA0E37AF571D8BF66 -:108BC00017F66DA3F97814EF5ED0B35E8DD10774FC -:108BD000B445AA47396D245C5E4B1E94CBAF79BD7A -:108BE00032C07514A99F398DBE37C61888017850D8 -:108BF0007A48B32784E9A491F833F64A0A7AC1F691 -:108C00000EDBEFA3D28BD02FFE8F997D3195AE185E -:108C1000FAA980400E2D8F4A6C5F38C9FCA816BE99 -:108C2000FFBD660AD2C364E2D3C2FC2AAC4A3C4F01 -:108C30004A56D6A7387AD1810CE3BA383CA70E51F0 -:108C4000B6BB845C234AB99645AE229EC983C77ED3 -:108C50000C7E81980D6408D81DD442447E53CB838A -:108C60007176B3C23E8A88838CB317F78E83747192 -:108C7000BFEEAD24B8FC45A937BD74BEB5414E8EDC -:108C8000A02B41C7AFF3BC09E94D1E6F2D62FEC09A -:108C9000B09E67F43282D76E057AA3EF2F147492D8 -:108CA0004932814EC6B699FC32856B01EFE756A07A -:108CB0009BC2B03EF76BCC0E7D36D08773AB2CF7E2 -:108CC000B6DB13E31C4827C3352EA49362E28C075E -:108CD000FC94185B1AB530FFFD230778CC0ABA580C -:108CE00062473942E902F9AA975E54B6ABE846E01A -:108CF000EF38B7972711EF40188F8AB1A3602FFB89 -:108D0000B318DD541017D2C9DBD953783CDAA3C5A8 -:108D10007E88521F961B9574A0A62B3AA226725CE1 -:108D2000359DF54537994037421FC6DF986EEEEF07 -:108D30009B6EEEBF1EDDA8E945C893BD266B39D8F2 -:108D4000A575D512CAE1E1EF0D6C84FAE0355998AA -:108D5000D7B2D7E644BBB5AE9EB517055C32E4BDCD -:108D6000E4ACE7ED59EE72A8D76D60F187E2932C81 -:108D70002F66E07DACBD6053FD110BE8772FFBFE45 -:108D8000F58B5BE458DAEEDBC2BF2F6D2A877ADD04 -:108D900056F6FD17103FA2F81D71DAD708CF6FDA2B -:108DA0009EE564DB4F66CF8EE774BA57DA7704BF6F -:108DB0006B62DFAD3866EC47D00E6676EB38BECE20 -:108DC000F14FB175DA3FBB6DB283D2EFB29017EDC0 -:108DD000A6F39A9A11286FFAD867964A4D695052AD -:108DE000BA4139E33252BACE66F1C55D7488437632 -:108DF00066078AB81CE40944E6051CB233FFA37871 -:108E00002F318EB038F21316F4078BB8A1FF712200 -:108E1000019FC11AB9FE8F1A479C94538FF1C34921 -:108E200099227E18D42EA6E3165CFB6A62347FCAB0 -:108E3000713EEE059EF7209E57FBB23440177B81B2 -:108E400048520148AB7F0776D35EF0BF32A5E125DB -:108E500025805756FFC8BE62DBD6340A5F4DBDD6AB -:108E60000B4A2683EEBF68D7D303C4DF3FB6F7FCB7 -:108E70002769891FF413D1B2F92F6FA47A500ACB56 -:108E8000A55942EC8C19847C7A27C7D367766E6F1C -:108E90000C27C341DECCE278FB91B15EC7F4659349 -:108EA0004EC5FF5F20FFEFECD36E56B6ABE4433503 -:108EB0001F7739B797579210DA05E7251F9617766F -:108EC000327B79B5F924DA155D4F303BB18604D198 -:108ED000EE50FB0F57EF51D6D7B428EB756DCA7A19 -:108EE000579E17C7E9DAB96604F8EFAA77BC877E00 -:108EF000E16A21277C4A39410D2426271EBF19FD2E -:108F0000361A2395134500AE7E9847329CB8E2414D -:108F10001E8092BD46EB0FC22729B4AE711B1350C1 -:108F20005E4C8EFF5C8C2F639CF63D97238C979E46 -:108F30007DA14A4E14087FCCC038F45709B951C0FE -:108F4000ED123259BD6F7C14F96F38AFE52428F764 -:108F50003DC2CEA0DFA39D11D0987D1A4DA45DE146 -:108F6000437E2C34523D812CE434B2FD4A1351E14E -:108F70007730ACEB3AFB2665BB0AFF62DF3282E357 -:108F80007F0EF10C007CDC49DC6F817E38F171B51D -:108F900062BFF4F11F270A7F0AEE9BBEFB7EC9FF6A -:108FA000BDF64B3D783751FB9196E533A60CFA059B -:108FB000C4BD5B4D98CF5927313C27CE399911E973 -:108FC0003F3CD14012B4117CDF38C56084F860A307 -:108FD0008EED27664CFD64C4E208B9F192B1746A63 -:108FE0004231E021F0937F87FDC53B32C17C99F689 -:108FF00004C47B77137D4EE9ADFBA95B9C5EFAF858 -:10900000928EC51BBF90EA97438A9398C7F20DBF13 -:109010003369A91E5B21FBDE08427C55F2BD5A4331 -:10902000DB4EE93D73A0FFD51ABF9EF9ED0218276C -:1090300015FDF7ED87F4A2BED31F667A3124F573D0 -:10904000323FAE373732DE5495C8F657EFC7B9977F -:1090500001DE85DE13F18433774FEA0FAAE16BE27C -:10906000EA0F714E490BB1A7DEE341BEC0E608BF6F -:10907000F21953F4B8C0DA04265FF7016FD1FFED9F -:1090800036D73A18F702DFFF5DE0F1AE0BB12CFEE8 -:10909000F5BF7ADE67E5A309CCDF7D81C7C72EC4A3 -:1090A00029F78DE2BDC778F97983D1B839029F8E4F -:1090B000C70DF53ECC93E27921EB09DB27EDB735FF -:1090C0006F8B8887362794EE837925E4B8F42900DE -:1090D000BFFD4C0F433C1AE2C64556CF76C04BADA0 -:1090E00083B820EE4A1C41FD4C883FC2BE13ED07F9 -:1090F000462F5D26568A79352754EE83EFBAEE0E59 -:10910000223E7BEA954C3E3627B871DCAE59A29DD3 -:10911000D71F0A72FC33FF81F067F7150F53C7BFE3 -:10912000A8E26076B689C93175DC7BBE90633CEEFF -:109130003D8FCBA1F9EDCC3FBEC048B60CA0ED0BE6 -:10914000DB93D87E31D69BAB887B7B63BE531E837B -:10915000A0CFAEF4404FBCF6898878ED1A1EEF5BC5 -:1091600023D6D7AA5CDF9B097DC66BDF4C8812AF84 -:1091700055E705BC0AFA7D60189E6BAD6CFD157253 -:109180004DB91EE4C45282F9E16BDF59D268A4F5EF -:10919000B50F82E70FFE98BDBA86C3ABAFF925B80D -:1091A00035C4A1F013F7238E887D718A274E51476D -:1091B0000B3822BF724075AAE2FBF4FA6CC5FB992A -:1091C0001B6E56B467790B15F59CADB72ADE1FD41C -:1091D00054A6A80FDE719BE2FD0292D31FE3B1C734 -:1091E00065F095909B7C3314EDB7ECB94BF1FD170E -:1091F000A4FEB131F4BD5613D303C4EB0A0CA57021 -:1092000059CAE79FD7B258F17DA3D432C24FDF5F6E -:109210001A60FEF6616DAB14FD5D8A9DC8F6113CC7 -:10922000FE584FFF6372DC21A33DD4269127A4DEB4 -:10923000F1C8EAF687B70C20BDED0AFA877A7E15E9 -:10924000D5F36047A9ED0C39D16247FD904A52AF82 -:1092500045F055980ECC6887753F25A33FAD800C2F -:109260007E7C0CC247477C8EDEF8EA26CCCFD3FD4D -:10927000A2C509FEB215EF2C41FA33242BE9C0E454 -:1092800050D241CC10251D589C4ABCF72F51E25DAD -:109290000D679B4B4907028E02CEF193957421E036 -:1092A0005B42FF03F81692D031CC9FF6494E3F89BE -:1092B00012EF6D6BC675DCC86ECB53C173F8515796 -:1092C000A319E1C4F2A9849D64E0FE69B5DF5CD80E -:1092D0001F6313B9DDC3FB117EEE2D9217ED9C9E2B -:1092E0007856893FC39F05F64E3D61FE127769624D -:1092F0004254BF1A3EEFCBAF26E028EC99D560CFA1 -:10930000D07196110FCAA5CFB93DB3C2FC28C605CE -:109310002FFD91C1B79AF8505E7FD77839D889244C -:10932000C2DFA886A3D42EF92DC0075C6EA7927663 -:1093300021B73D983741C9CE3842115F50DAA1C4F8 -:109340002545CA2761978AF1043C85DC12E3194858 -:10935000BD9C0C7CA092636488DA4E55FA3D849FD4 -:1093600004078B88638CEC894FB07D62D8EFC5FC15 -:109370001C7266562301FBDB2AFC1A81B9F05CF8EB -:1093800035D4FBFB1BC545677AA5E09359BDE3A126 -:1093900022BE4A97F9D9BFD38FC7488E74186FC6BB -:1093A000EB831388269A5FCE79FA00ED47D684E2E4 -:1093B00023FD65C27FFDB614C479FF88B8EE27117E -:1093C000F6422D699938370BFC9F546FC542C9FC92 -:1093D0003EA44D6D97B278A286AE04E87B358988AD -:1093E000176685DBB12EF7AE8B3C971BE97747926A -:1093F000559C5BC965ED4CBE89FD5B5FFB2511CFBC -:109400007F4B4F615218CE6B793191EF33F3493E68 -:10941000F44FF9AA2511F7E7940FA548BEEBC983CD -:10942000C1F65E7CA75ABF88E7CB9622F4BB2C8995 -:109430005CEFB78087B023BEA26B83725BA203CBC5 -:1094400035FDCE7CE482E6A24046A4BD5BA76779E9 -:10945000C1A445693F9F4CD47078B9E46F03A7BE9F -:10946000F1C0F3C2381EBEAD3D24F2C204FCFE289A -:10947000E46018DE671572AC67DFD603EFB3D1E4A2 -:109480009C80C7E5E2C0738027D9723211E0FC5797 -:109490008BFB33C04FFAE9E0794903FAAEE3B92711 -:1094A000417FB5C9B83FAA1DCBF2836AF763B09C70 -:1094B00074B61B301E58DD7604EDB28E062A4007C6 -:1094C000F60D9F9E75AAE0DCD73E45ACE3BF557410 -:1094D00026F244E8FAFEA6A0A7DEEBFF5B347A137F -:1094E000F94915F2D0FEC188FD483BDFF798B46E0C -:1094F0006D12FDAEE8C3B458804B85DC7E2C15E0C0 -:10950000B05EC2F347E30DC40B7EFE147E0EAD24A5 -:1095100058EFB4527824A799F13CD1E01FCB6E8864 -:10952000637EB27E5DDC125A7ED94087A6FB8DC178 -:1095300092C68D7446F69DFD6911C4D7E661DEF1D1 -:109540007C038BFB67FD24C69F43E5C39B7A6204C3 -:109550003ED365D7E3798B904DC67D865D2613801B -:10956000AE049CED316C1DE279E9D3BB25C86312D2 -:10957000CFC7378686AFA5E539C07771789DE3CB35 -:1095800043C3EBCD61388BFC40A20D65CC88E08BEA -:1095900037393C6A13F45B400F761AF9FE8FEF03FC -:1095A00089558BF2633D8FB39F194477A2D88FDF23 -:1095B00002F958B52657FF91E0E7823C025A7C6DCC -:1095C00075F5B7E1FA1D682FAFE7765527CFDB5E5B -:1095D0003FA52C09F6517DE53D952631FBBE86C79A -:1095E000BFC5F31AAD1FF3956A20DF3822DFE9BB50 -:1095F000E61B8BFCF13EE160D3122D8543AD44DCCC -:10960000D77BEFC0DFE4A8FBDCEA24CD75F3DF16DF -:10961000F2F589FCB65AC86FA38FD6EF2F4D2251B1 -:10962000FAEBD133576E55E49189FCE8DA2BE3303D -:109630008FACFC810E3CF707FD38CCE1FCB6BEE0F8 -:10964000FC66229B472DE4850D8F7CCEE446B87FD7 -:109650003BE2E1570040F073B4C9E88FFDD571CD0E -:10966000E45D51E6FB501283CFCD095AE48F5BFCD9 -:10967000C4D51C657CF19E38170270AECCEB3DBFA3 -:10968000D6B2E002983FE4AD461BAF2189EDAFC5ED -:10969000BC5BE382CB399DE3B98C9EBA5589C77F09 -:1096A000E572BFF5B660069E2F9A123D3F5EE07BE5 -:1096B00084B65E0278042D9E03686FCEA6956190F5 -:1096C000D7EFD7B0FC29C6677DE13D0C6F8D229F97 -:1096D000B037BCF58867D19FD88F5CDC2163BCFFB5 -:1096E000E209CE97C46596287F2DE2FAEA226171DD -:1096F000838B4D12EE43167B08D940E5CBA2DDAB40 -:10970000316EB3FCD9E15B404DC1F3FBA81C599409 -:109710004CC8385A2EDEAC8CDB2EDDDE2B4E4322BD -:10972000F522353B715FBDFC51E577D564FB7F8247 -:10973000DD53ADB26B06733FD7BE249ECF37828C0C -:1097400000F9BEF6D9AFF490B2DB17BD7F49F97AC4 -:10975000A016E4A015CBA349AEFD49141E1F26791F -:10976000DA416E777DC0E0D05DD3CDE4FE5376D490 -:10977000370610CEF49F86B92CFEFA001517107725 -:109780003318985D23EC39595E27C7D2F6517F5ABA -:109790001F07F8B3FF7AD264B0F7137E1DE3027897 -:1097A0006D2B7515C0FE7F5BA519F3188C0616F797 -:1097B000F5FD6AD46108030C6C79B80CF69FD6F6F7 -:1097C000437EF08F6CD5FC279E2BD93A8EE5B98964 -:1097D00071EADA2BF7C27C32EE647A635B96ABC037 -:1097E0001AD12FE1F6592D8759D7C1C13F1F4DF12D -:1097F000F8E471348FE9FAB2D10F773361F814F9D4 -:10980000543076A41DDA41F50F24E589FACD2D9266 -:109810005F47D7B3A6752FC62F6A36F913E7829E26 -:1098200079418BF11F313FFB9B296510E711FA65E8 -:10983000AE6445FD2FECEC3944FCB1385115A783DB -:1098400039DCBE9E1BC3E0BB983833E0BBBB8C2425 -:1098500016FCD373CB5B8A51FFACD6D940AF8B7863 -:1098600047DFF640743F51ED7316763E560AE542E7 -:10987000275FD27D0761FEA2A8E78D4CC99CCF72FD -:10988000B9BD3790B820BE56FBC6E066F00718FA9F -:10989000B1382C953BC69242B4778DB08F5979C0C0 -:1098A000E467FE6A1F3F07EB2A807C90BA1969853E -:1098B0009897709ACA0F0B9C2F0C66209F52B92262 -:1098C00051DD969D1C334D4BE9BB3695DA53B4EE12 -:1098D000DE91CCEAD9C1E51A5ADF905CC8EA3707B5 -:1098E000CF437D53F258562F0C2E9769FDE9E4A91A -:1098F000AC0E1B3B4A58BF4A9E31CD0BF6848DEB14 -:109900006B6710CF05D7BE3E5813E9A77C2C99C9C9 -:10991000A52FB9BFF5CB2CB27006C07B4810CF9DE8 -:1099200089F77E9A2CEC5B96DF2BD629BE23C9D112 -:10993000FB2FE0DFADE4E779C7C790AD2616A7F2AD -:10994000C652F81F6D1F8C71B6C4E438E68FB3D2CF -:109950007E8AC2FD08388AFEC4B8AB40AF82BCD54F -:10996000317FA9681F97CCE4381D67338E3394C1CB -:10997000BF76465A01E08DE24BCBF1A565FBCE6682 -:109980001C17FAB5E5A37C1F0EFEEEA357E9FB59A1 -:10999000E179ABE9632AA78F958D2CBE18B2E5203B -:1099A0001D8D8F61F61E2952AEE3690E87C7926D39 -:1099B0000C8E3DF84892709C460EC7340AF7BCEFF7 -:1099C000BEEEF93FD0BA23F0E592A1BDEDA65D91C0 -:1099D000EB11F9DAA29F2F37AABE2B617953B5712B -:1099E00039F8DD032662C4E76457CF7759F9CCCE46 -:1099F00004FB53DCD740BCE3D04950C3A546CFFDA0 -:109A00000B2D3C7F70A08B9D3F9E31AD88AFCFCAA0 -:109A1000D7673546DCBBD0C38F274319775A7AD333 -:109A20006F0FDC7BFA1B5AC8FB53F075B4FE803F06 -:109A3000FAC2C7CFFFDEF810F354C1B307CEAAF9BC -:109A40000978023FE3774395F428E6B92959E40BF6 -:109A5000ABF83AEB7B8E57CABE5B730FCF03762809 -:109A6000E9794D6B9606E2E7E2BBC9E0634F08FB7C -:109A7000DBF625F37D6B1A49EB23FFEDD5E4E87E99 -:109A80003A7CAEDEBF75D958DEB3DA6FD095E00C04 -:109A9000C0793EEF65763E7DB4CADE80F8CB3E737A -:109AA000F8BBB03E51D6E514C607BDFD40213C4F82 -:109AB0005B64287BD9E1A47B9DE4EA695A6A571468 -:109AC000F52F5B9745EBA79257A1BC2E1A50F65580 -:109AD0001695DF7F485ECDEAB7947D950DF51DABF9 -:109AE000D9FBE35D2F837C27DED5D326A484ED87C5 -:109AF000D3C90E849B5CAE21404706F96E27E84926 -:109B000001CFBECA2283A63E9A7D7AAE870E587CCC -:109B1000A284EBE712B13F0F6A15FBF3AE5876DE75 -:109B2000B80BF4295D6F47B2E77C32D829311D0BA1 -:109B3000B268579B62CEEAC11E925C5477819FC384 -:109B40006125F3209FAE639B1BEC23B2CA69D4222C -:109B50003CB9DF89AEED1AEDE7C01B2FDC3B800D71 -:109B6000E386798CE2FC5FF7C6377F81F868DD9782 -:109B70006627B8F546B5EF5C07F6D5A8F6DF7FC3D4 -:109B8000F42D3BA721E63D0AFC87F479499B01E7C8 -:109B90003FAAFDA665F0FEE80FDB73803EC69EF18E -:109BA000378238E83AF8DA00C5F90CF285F47DCE50 -:109BB00067F4C0E34FD478EA8FF030A624003CAEBF -:109BC000629E5467C2892D41B4D394E760A85D8E2C -:109BD000F1D56ED2CF097102718E5BEDAF3C5D495C -:109BE000D7479F8F0DD11944D8CBE3AFD0FD7D84EB -:109BF0009D5D4A6C8A7AB93145F17E85354BD13EFF -:109C000029F92645FB144781A23E75C828C5FBB734 -:109C10003B4B15F53B4AA628DEAF74552AEA05FEF4 -:109C200016C5FBC38FB729DB4F3A100FC3CFB8CB94 -:109C3000C18E77063C8D508EEC682AEFEF20BDFC7C -:109C4000B445415F233C1F7DB5BED84FA29C5F59F0 -:109C5000E541FF7EAFF32BA5EC7C7BA7869DDF1053 -:109C60007ED9AB319EB180A7B7250A760AEC71C6C2 -:109C7000503CE0AB62E143982FD51D22E8CF6AD576 -:109C8000077F361AF4FC7C19EDDE569E67D35A9591 -:109C9000E7035FDE6929F82AC4E9BDF3D9F980B189 -:109CA000D4C2C575434C53023C7914EB2E252B5579 -:109CB00078BA5B51AFB0DEA3787F52F24645FB1411 -:109CC000C7832A3C3DACA8DFEEDCA9C253B30A4FE0 -:109CD0002F28DAC77E1E6C04361ADFE1952D74FE3C -:109CE000B79E6E2A07BC8C3EE39D0FFC52E4F7340E -:109CF00082382C3E5A7F044A3FDD4F819FEA7043F1 -:109D00003296471B1CE8673AD63004CBE30D4E7CF5 -:109D1000FEBB86122CDF6D7061F96F0D93B10C34B0 -:109D2000B8B16C6968C1F7F735B4614921980EFA8A -:109D3000C21EDF73AF423AECE73B35C15A88A0AE92 -:109D4000DB7900E56467BF6027D43791D7A74D80E2 -:109D5000F35CB09902FB0A4A8ACFFB525D7F49A1AE -:109D6000F54D29AC2EF2125A34AE02B0AF1FD8799D -:109D700064BB369D90FB37BA93AD365637D23A2244 -:109D80001BFAF01ED9EE4A23E437A0326EC5FA342E -:109D9000A8779958FBA69D47A679513FB0F8F19D49 -:109DA000E1F8F10330AE3A7EFC9B0B0E0BF8534EFC -:109DB0005C1D6C81759DE0FE231729D02DA265A93D -:109DC000B640077AF1B4CA8E10659DA6B409FA6D43 -:109DD000D13867615EF06D3A0279E83324B61FED41 -:109DE000B10353991CEFBADD80FB9D931AD732CC97 -:109DF000779242CF00BCF6A49C44BDD265096500B1 -:109E00001C9E4BF990D51342CF48CE88BA8EADF345 -:109E10005F534EE03E22CA3A77A7448993BF90C26F -:109E2000E3067E573A9EEBE5F59395AE35A0274EB7 -:109E300096BA06C17C4EB80DC83F5EB7C507F99605 -:109E400044EB2A9E15E157C949D5E17777EA199F76 -:109E500091BBE4A8E7CD4B53999D857883FDDC9CAD -:109E600018B4C34F6AA29F179F93CAF4F5A57ED179 -:109E7000FD2B77F1F6B29916ECAF6BBD09E3B75D38 -:109E8000EEC1680775D5532851FEE8BA507FF91521 -:109E90006C3788D016C629E77239F59BF6757F3E78 -:109EA00045DF3FBB3EC68932DC7A33EAA7BBF8CB3D -:109EB000F3E38D68B7CC9F915E067A692E8F772D7C -:109EC000B0681331ECA5B5E9E18AA0A5E6822DA022 -:109ED000FE97DB2BF5365AAF4EBB7B0B94AB063EA1 -:109EE000AC87239A3543F76E01F3710D65AD62DCE3 -:109EF0002F05DF6BA0F35AB84176B0FD933877B8E1 -:109F0000FA3BE557083A3CC9F364287C715F38375F -:109F100095ED7BC4777339BD5D4CE1765B1EC9BBA3 -:109F2000A68CE35C063AE998FF5E6E1F7E77653B80 -:109F3000B7DB3ED2B371D5F7508871E771BC9FD4BF -:109F400013970476DC5D16A48FFCAAAF3615D3F503 -:109F5000E7B75B35188717723CC0EE032BFEDC8336 -:109F6000726E6447F0B95304E9BC0DF8E4467A6AAE -:109F7000A67723EA87515F53FD0372F1AAE7EC2924 -:109F80006CB5473D8FE96FA8E6F2B11EE5DAD186E0 -:109F90000D583FD6E0C5F278C3562E1F9BB0FDDDAD -:109FA000861D5C3EFAB87CDC83CFDB1BAAB07CA3A9 -:109FB000C183E55F2DEEB8D40420360FE667BEB549 -:109FC000D340E0DEB4EE7603D229E580679EB44349 -:109FD000FE8BC10AE7EED479306A79DB83FFD65E67 -:109FE000F76164A41647E4BD807D96D937FD9C20B7 -:109FF0000E0BC893114F24DD0EF2F984C36101BB2F -:10A0000075646A32ABBB1C161DAD973C41EB54BE68 -:10A010009CF0382C065A1F959AC2DABD0E8B89D651 -:10A020006F7D2285B5FB0806A9C73F91713BC89F8C -:10A0300052221D057E2837664D8094D90A6BE9515E -:10A04000E08349C98B26001FFC36C5817438C5B131 -:10A05000F128D4A70E69D6C2511B97B960337C573B -:10A0600066AFD4C27713D2EEDE0CDF4D1CF8B036EB -:10A07000F2BBC943F76E86FA3467B316ECC1DFA6AC -:10A08000B0F3FDA21F5117ED42BE8A3CAD61ED6EEB -:10A0900094E3F96D6E94E3022E657756DE0F7EBA77 -:10A0A000BA36C92AC13CEE947A82EF900B577B9561 -:10A0B000720B95B3D39FB8C9B291F2571DD46FC537 -:10A0C000FA431BA3CBDD99A951F4CB1F389F82DE45 -:10A0D000847CE83FE8D97D1E2FF3F5D5B52FB22C4F -:10A0E000427DE5B1807EDD9FC2F4E541AE1F2FF3D6 -:10A0F000B29B3FAFD3B8E6C3384B53FBE4EB6A687F -:10A10000A77CAB3A27D0473BE7EB55A95C3FF07BF8 -:10A1100013D610769EE846F95A2B23F76F5990977D -:10A12000D3720CF245D5F90F3570CE28A7771E30C3 -:10A13000958B2CEFB14D993FDAB3FFE8C7E41E1CB5 -:10A140005F844D4763DFEB7E2035E1BAEB56B6F313 -:10A1500075AF242CBF59BD0EE24940DE12F9CEBDC9 -:10A16000D7138CBE9E5EEBE0F7EEA9F2ACA91DF40E -:10A1700038CCA762A18580FF26524E9CBA8E9C5097 -:10A18000CB9DBF973CBB8EBC79319ABC11E79DD566 -:10A19000A5B0E7E09C14E4DBC17D2FE0A7FFA74456 -:10A1A000CF6BD04F5759E82F1AD89FD9834867767D -:10A1B0009BE775782EE959DC5DE4B15ED0787F0BC2 -:10A1C00076D1B12796A01CEA04E540F9F10D5A07B3 -:10A1D000B9536475FB017E6408A39FBEF233DFE6CA -:10A1E0007AB177C9F849E42976357F93817EAC1B33 -:10A1F000D07B5F70A890C704E13C4077490C9A3C43 -:10A200001D12F14B85906F9D88764447BA5E0BE531 -:10A21000DF7B9FD8919E8BFDABF78B1D29254636A2 -:10A22000EEC4C950B6E93D3B16C13E699401F749F9 -:10A23000EFF3FCBEE99F5EB583BE9A2EFB13F3A538 -:10A24000DEFBCC8E77E69539F27BEF37E9FA26C054 -:10A25000FA6EB4EF741B03710046F5FEB366C35F7C -:10A2600008E4458FDE7095C07D6437DE8F1219C417 -:10A2700044E169E711288B3F77611ACE880BF547D7 -:10A28000A01CF535DB9EDF289FE8D62B2D47D8F1A3 -:10A29000F0A1CAFB164A7ECFF6ABBCEC754FDB2AA9 -:10A2A000AF324FADD45F8C7914723016CACB5210D6 -:10A2B000FD5EB286DDC320EE5FA0FBD8C401C5B051 -:10A2C000EF65F952E321CF884EAEE2A71F2FB817F2 -:10A2D000F9DE84F64FCF3EF6150DE609B46A5DFD52 -:10A2E000C7C23E76C320E7465AFF8F40C22F0ED02A -:10A2F000B2CEFA1712797F5BCD866E45BD6363F8E7 -:10A300009E20C883AEF99B8C7AA78690AD80AF1A49 -:10A310007258BF36420F9296FFEC81FB302AE72A33 -:10A320000170B8AFD24C77D1F72AF97E83781B59E8 -:10A330009DEFB308F9EC7617EDB73281BF4F664F4A -:10A34000C77ABA68AF62F541A2BFD7D8FB29A2CEBF -:10A35000FBBB49D47FCEEA59E2FB16F67D9E18FF7F -:10A36000BDDBB1DDC2DE1F3F60FD74900342BE570E -:10A370000CE0F925FC7E1F2AEFA70C48B86E5E8919 -:10A38000B29DEB03719F4FC54FA7C4BC07FCDC22F5 -:10A3900061EE5BCD7D3AF46F5F8A6BC98F3C9F2C79 -:10A3A000F250DCE51617D87B6B5E1DBC4BE6F93826 -:10A3B000606F6CE3F1E50AD98CF188EEED4CCEF7D5 -:10A3C00065AF2DDFF0BA029FBDDAF93DCA18A8A328 -:10A3D000E35D7E2809F3DBC9C000C6C3570C90C4F7 -:10A3E000F92A3CDF2AF2BDEC39C405FB53FB6B268E -:10A3F000764FE5E70194BFCB5F63FEDE353B8FA070 -:10A400009E5B2C3B908E0F6779D600DD765AD87D07 -:10A4100084CB37BC81FCBA2193DB09D6D050053CF4 -:10A420007BC3FF9E1BC0FF9E7F24FCD57E66713ED2 -:10A430007AD577CC4BEBB4B038A893E3E9538D636E -:10A440000487D723B09ECBCB02B9361992860389F5 -:10A450002CEFE8DD62D80775D75BF09EA379EB3E61 -:10A46000C98F3C97224AB5FD7F0EF8A8380CAFE69D -:10A47000DEF07D16F0731DF82ADB7F60F826698315 -:10A480007A27C44D4FB37BC746043ED547E6BBBCD5 -:10A490003580E9DDFEFC1E6A75DED65B032C0C4FB1 -:10A4A0003C1EB366C6BB63201E23F8617C0C6901A9 -:10A4B000FF3AA56B27A76B27D0B5A0DF705C867E1F -:10A4C0001785BFC2F44B147969EF0E50DE0B46E1DD -:10A4D00016B801DD06FE9174DB4AED5F8C63BE6247 -:10A4E00042FF891ACE5F71B80A786BD3AE0F676DE1 -:10A4F000DA0F03676D9A43E17F10F0EE4B3FA9F14D -:10A5000023E61D854F8BBF0F9F36A67339A50D62BD -:10A510009EA81AEF3169BDF0DE3FEDFA7857B6FF1D -:10A52000C07857C34D5DD6F0F8A6FA795E9A88FFD9 -:10A53000FE3070FCFFCD7F3EBFFE90A27DE18677AE -:10A5400014ED8BBC1F28EA638281722073E10F1F18 -:10A55000772184F6E5F7F5ABF7E54F9FFEF20A0D9C -:10A56000C4DB4A02CC9FFF65BA67531A85F3FB1A16 -:10A570005FA385C275E49916766F57752EE60FAD09 -:10A58000E373FC6ACC7F9DBD97D2CD57C480FE4E4D -:10A59000FFA19BB48EBCDE74507A45435C11796890 -:10A5A000A5469BD685FE1AE28A46370F70BAC1FCD3 -:10A5B0001FCAEF5546A2B3533EAFAA9230DFA98A15 -:10A5C000B07C685AFA3DB47DBA96F8E1DEE34AB34E -:10A5D000D66FC0389FF23CB381DF8B4CECF18A73AD -:10A5E000CDB24BC6BCB459252C3E7897B905CF9354 -:10A5F000CE39BEE9F2BDB49D6CF616B37C6B71FE2C -:10A60000EC8F9AEF12F77B208DF17997C4E3C89213 -:10A610000EEFC7527F37378DF1D97479A30CF92E1D -:10A62000A10F08DADD82EFE8FA8E1B0AD9F90AF8E1 -:10A630005D8A4AA2F30FC6F3CE0F97C3FB35271DE1 -:10A640000897BA928DF980C7BA09D239437E785FEC -:10A6500053B7E16BECA7427EB111DEEF3ECD5CE17A -:10A66000233BE83EC511E9AF0C2E00BEBCD1FE472E -:10A67000CCFB4C831FE9E96CC3712CDF1FF7FB6235 -:10A68000B033820D81A87EC9EFEB1F107E01E12758 -:10A69000107240DCCBB7378DCB05A33400EF53D31A -:10A6A000B252C8CBD7D27AD92B076E205F0FFC23CA -:10A6B000E5EBB7A5F39A64A617D5F4ADA66B41CF29 -:10A6C000709F37FC1EC15DD4DE03BD3A9778F36AF4 -:10A6D000A89CAD5AD1A41B2D7D7FBA5E65FE3C833C -:10A6E000443967F2DDE5B983E54796CBB83F10F909 -:10A6F00009020F9DBDF1D69D767D3B53D9FE0FB764 -:10A70000E33F5FF0FDF41A51D80396F45EEBB6A573 -:10A710005F7FDDCAF61F78DD11E75F16C89AF07912 -:10A720000FC81F063BAECBC7CE33566735E13DF2AF -:10A73000A424140B76E3CA8332D221D1BAB42911EE -:10A74000F74D7510FF47408F2BC6ACC07370BDEE40 -:10A750008932B7E2B938F57D51225FB896F7A3BECA -:10A7600037AA96E709D7AAF27646A4F3FCE042524C -:10A77000C8F22B9476A9BAEC6C200ABF64E7D50620 -:10A78000F4038C4B6FF999372D8C8709E9BDECB830 -:10A79000C937C0DBE47F24DED4F42A5B76E379A8F2 -:10A7A000EF4AAF57335DF3D313C272781EE47015CE -:10A7B000C13DEE061FDCF72FEEC7EE92D87D345D6B -:10A7C000E708FA8D6E74BFF2A8931E3CCF39F25D94 -:10A7D00097CCF20858BE81B05384DD32BA2324B33B -:10A7E000FBEDF939289E17F46DE5973360453B473B -:10A7F000F8DFFE5E7E6BA1E70E1A995C13FEC1A224 -:10A80000A01BEDB84E9DBF18EEB3F7EE3745B5036C -:10A810007E96AEB9EE3DAE7FB5787E06F43293CB30 -:10A8200077719F6B85CCEE7BEE0EC8E8BF5BFFCFE8 -:10A830001FFEF649C78DF7F575D6EEA8FB2251D657 -:10A8400069D87989C27207E6EDC17E09FC77C29F9B -:10A85000A77EFFF5CC321FCCAF421E83F76B76EF9D -:10A8600060F3E90B2F751B42387E9FED7CFCBA83A9 -:10A87000C5D6C8FB30CEA5F7ECCFACE78D61BC7E6A -:10A880005BFC8F0D5529EC9BFFD7F70DD3656A3A1A -:10A8900052FD9827F9987D4A989D3A8F04B05C4004 -:10A8A00042587A08CBA75F4C9C582E256E2CA76582 -:10A8B0007A4EA5637E4B2811F3215FFDEB50A09BE0 -:10A8C000CBE3463741EEDC0F65A775153870FCAE5B -:10A8D00057FE9A01792D37E2FFF858D70598A73A25 -:10A8E000AEF16FA532C64F88712DCAFB4A7E4B026E -:10A8F00099C0E262DB12B390DFC2F22FA959C83FC0 -:10A9000088B7E69DD3B0FC909512DEE7DA16D42026 -:10A910006BE52DCBF2C1FD3C6DADAC3D6F8DCD2710 -:10A92000D17ADE28136BBFDBE683730FF34910F98E -:10A9300071219C7A90E11C0C936FE2FE736AB167FF -:10A94000839DB5ACDDC8F2F7497020C8F1FC3EF636 -:10A95000371332189F0FCB66727B5899D20FD18F65 -:10A96000B7AFCC2C5B960171D90C574C065DDFB0AC -:10A97000B8C0B6478AD02F8FBFB3F2C5A87B307E50 -:10A9800028BE6BCA2CB3C27B2F492CDFDC7B90FF27 -:10A990006E01092546DE273A2DB33C11DE4BCF2050 -:10A9A000DC6E8E0E57F83D3A7794FD9CC8671C0606 -:10A9B0007B2AF48FB37BA95E92583DFF19EB1D9B58 -:10A9C00087A20FDF0B766D53A66730AC63989E109D -:10A9D00033CCFF69836F17DA9FF519E08F5CF18C38 -:10A9E000410376C1C754ADC2B9927F6F3062F90995 -:10A9F000DDE742F91F749F0BE539BACF85F233BA10 -:10AA0000CF8572D91527251A42DEC970B9603D225B -:10AA1000DEA69EEF28016F31FE413D8EBF32D3830B -:10AA2000F0EDC1F77EE28378C84BB6506ADC75E87A -:10AA3000AD6F39E3E5FBBDE8F959C332D8BE36BF87 -:10AA4000558B7A3CBF2D18BB3CE2BDE9197A6CCF1F -:10AA50007BE5733C27DA69ED81AF4BA24B9EAE617B -:10AA6000F5E9CFE4227C5766BA96C1BA297FCF8038 -:10AA700075E4B77DF82F709E87F68F79045D52E8F4 -:10AA800031B4F355EB50C341ACEB255B601B7CFF4D -:10AA9000D22BD9B0122A6F08E31BA02329DA7A3708 -:10AAA000E27CEF30848AE09CCA1DD7E4A879C32BEE -:10AAB000334B11CE12D05B42049C38BEBE2F5FF7E1 -:10AAC000C4B3399D1271BF06C84E07E8A1ABB1608F -:10AAD000D755F2787D5BEBC0F7617DDEE33219E498 -:10AAE00040FA55F0DD0E8E1F51E61DD4BB014F2FED -:10AAF0001D3C3F10EE5FA5781908F7B16ECD18A484 -:10AB0000F02FE68DFAE68947ECF83EFCB21A95CFB5 -:10AB1000CD15904F32D778E82D58D27CEBB90AC8C2 -:10AB20002759982C1D837291236B22E491887CF71E -:10AB300025434A8F012B4D7356A23D560AC225422A -:10AB40001F941B63F865D042FFC42BEA9392072839 -:10AB5000DE9FE2C851B44F1D728BA25D8C3BCD3994 -:10AB60005CF1DEB0B85036ECBFE83AD8FDD7CFCABA -:10AB7000987797F7CAC9DB6EA1F5E9CFCDC2FBFE86 -:10AB80005EE2EDD3F795E3EF0B765178EAA92175F4 -:10AB9000A1E4C1C71E81CE54F67DCDC15F1E7339BD -:10ABA000AE63DFDFC0AE17F27575BBB118E4EBB76B -:10ABB000B5F3D578792583DF1FC2EDFEBEE8A58702 -:10ABC0001F2407A3177EDF969A5E20B394D11F2B14 -:10ABD000A79F60E7C0BEAB1CFB13C8B18873983D4C -:10ABE000A5CADF364CEF7C7F1DF8DFDF93099EABF3 -:10ABF000E3E7F396C3BFE5309D93A5CDF7C37D5240 -:10AC0000F4B917EC4F3807EAA2FD5FCEE07653CDDA -:10AC1000A1FB538AC2ED64FD39C5FBE43E698BA2FA -:10AC2000BE394B59DF5EBA25F2FBBEE4E1F21D8B63 -:10AC3000F41E3CBF2945FD3D57319F8AC326CCCF2A -:10AC4000BB1DF24EE8A3DAA20FB4106FBDBD0FFD1D -:10AC500029E4CE1C99D4476BBF92C1E28ED30E9BE0 -:10AC6000309FE5BBF6FB318525E60BBEC6F4E7C792 -:10AC7000FD03DA48BCCB99ACFFCBC50FFFF35F20D7 -:10AC8000EEB99F60FEE6651B93FBF9AD5F6834B4D7 -:10AC90001CD68FD14BBE35A8017DD2551DE385FC56 -:10ACA000FCBA9516CCEB1C961DFAC85840484CE6E9 -:10ACB000B69F1B29BDFD110E3346E8D32ED8E3D035 -:10ACC000BAFD5F1FBC6333FDF7D4C326BFE67BAC80 -:10ACD000C74E6D28D47F658CBF1700DD70BD02BEE6 -:10ACE000F3BAFB498F9E017900EB87FA6D990FBD8E -:10ACF000FF289D77DD3B8CBF21534EBD6F9F1BB15D -:10AD00006F274F31BE34D2FFC09E5B75B4490FFB35 -:10AD1000B91BF3770BE6CD7C5BBECECFBC211F9F6A -:10AD2000984AF152B79FDD33D1DD3E08CFB5F6A585 -:10AD3000BFEB766890FF44BDB35D9E0CF4AA3E273E -:10AD40002EE049ACB98A7B9CD68EFDAF19A027D7DF -:10AD50001ED4B2648FBEC6D9AA218E88715E7AC312 -:10AD600050CD7EA792CDBF4BE8E7837F8E2B1DCAC7 -:10AD7000CA8D51F41CD5CB3A3BE8E54AF67B0BA7CC -:10AD80000E269501FC4F49C4EFC073572CCF78268F -:10AD9000EB0E9E9BF1FE90E421DAC87B0EC53E725D -:10ADA000D6C15983C08EFCA875F1298A19B22833FF -:10ADB00007E96536F1A2DD7BCAE64E077FC3741E44 -:10ADC000EF3F650B75803C3E35364682F83DED7FA2 -:10ADD0003389B8AFEF94CE9DCEEE831079C5377F1F -:10ADE000AF7BDB2AE4FB4AA742BC7A1EB1C23EF22B -:10ADF0000E99D9B5E44DC69742DED549813898E71A -:10AE0000B4CC19EB3221FEBBE167B8AFEC819B9665 -:10AE1000FFDED3B7B46B7BF6AF7B24764F8993D933 -:10AE2000FBB5632EFD62369C73A3FB6C89CE677104 -:10AE3000DB21BC8747BDAFEED9DFFC0FFDA3BDF71B -:10AE400047EE87607DC2EFADDE27F5D8E5C2BE7B59 -:10AE500096E5B91F19FB78E76A5A5FFF6C0CC2F1DF -:10AE6000E233062FC8EF8BBB0CB8DFB918173AB323 -:10AE70000EEAFBF29C5E1C2D17CF7709FA5EA171DA -:10AE8000FC01F40EF99D0EEFDDF8E26903FEBEC78A -:10AE9000CA5FDEB40BF64F5FA43B7EFD22F8F77E5F -:10AEA0009D80F7019064F6FDED9C1F81BF1C141F6F -:10AEB000F2F316B41B56BE9C82F24BE0EFC2D326CF -:10AEC0003C077FF1F8CCFEE007EBD0EC65BF3329FF -:10AED0009BBD208757EF32A1DD47F49E9760FDE5CB -:10AEE000CFDF3E7B388CFF610281F574B5BF8CFEED -:10AEF000C7307EA3EBF5EEF61C26077AF42CCB9B2D -:10AF00005D18BEA7F915E87F0D11F720B2BCD94234 -:10AF10005962BF3BF950F473E0C73299BD5823FC26 -:10AF200025F1C4980C7CE821ECDEC78706E33DBB25 -:10AF30006733F9F96512E2E71D05BD9DA93D80FE65 -:10AF40001203CBD7EBE35ECB1399367C7FB9F16B61 -:10AF500085DFA476C315657D28FB1DE6C246C7F0D4 -:10AF6000BB69B98EC3F9BF92DCA7607DAB5A1E7E68 -:10AF7000F55D84CB533FF9238C7BDC8C7E1AF22E5B -:10AF8000839F7AFFB2DC18E271876685DD7B7EE7FE -:10AF90001F307FE4FC2BB7E0EF942D9603E7E17EB2 -:10AFA000AC4E4BE0ECBDB4DC77FC04E2453DDF5E2B -:10AFB000717889C9951A58C770C85F715FCA44BE55 -:10AFC00065FCFEE9B63C849FF0D3765D8CBEBF1273 -:10AFD000F314FD8BF989FEC57BDF707C5DD607F22B -:10AFE000412FFB200E11B1AECBB1817CF8295C5F03 -:10AFF0003ACBE7BE1C47EB117473A378CDFF055C19 -:10B00000F134E600800000001F8B08000000000003 -:10B01000000BAD580F6C13E7157F77679F1D623BE0 -:10B020008684FC217F383B10D2262447FE786902B3 -:10B03000E39A908822B69AC0B48CC138DA42293497 -:10B040008D97C086E8242EF5C43F819A69DD46A716 -:10B05000D2192618D2404D3340AC02E68256C8863B -:10B060005A77651ADD2274CB5A16AD2149195B85D2 -:10B07000D42D7BEFBB3B9C73025BABD98A5FBEFBDD -:10B08000BEEF7DEFFDDEDFEFDA00E26A15C0B3B997 -:10B090006F80A31AE8137667037C05CC4F56A6038E -:10B0A0004200ABE87F099FD7FDF62EE703580DBDA0 -:10B0B0004E2806B8CE776F130580E1DEEF3B550FC3 -:10B0C0002D5AE2BF590AC0697FE4C7CB00C6E9B375 -:10B0D0007832057000ADA3CFB840BF1AC04CFC6DEC -:10B0E00084D208F2B9E5F7687C25C02C8973DC743A -:10B0F000E3742114D23A9C97E33548FB5C7214E563 -:10B10000D9C6878B24DCF7AC18AF0021B96F1BAF11 -:10B11000B2E7C3DCD58D10A4E3E215612FC0E8745B -:10B1200011B80CA433E58492857CFE01F251E4331E -:10B13000EA84B63E3CB7A6898FF4313D1C833ACAF7 -:10B14000C703C7E4AB29C3E7E5008BE8B9DB943B51 -:10B1500080CF2BEDEB93FAD8C767249EE95793C9AC -:10B16000477ACB27E3F1B8391F85B840B8E2679535 -:10B170001B716F307107500440BB3C678E9F737B1F -:10B18000E24205CAED736B02EAD3700EED82E3066C -:10B1900047FC4DA29C02B07D06AE3DEB1CBE2707CE -:10B1A000E1905BE6203EF5A67939E4B506D7EDE2FD -:10B1B0002240E7BAA187D17D5C82C9F1451863546A -:10B1C00001BF8328C2CFE8120833DA021146974242 -:10B1D0000FA3CBA097D1E59060141E8E4721402786 -:10B1E0007DC77F331DC9634FF3E3486BBE0A915E91 -:10B1F000CF641CBE4938D43E08078D237FFCAC3891 -:10B20000B4809ACBF8A5E25150CAFC3B150F17F950 -:10B2100023DA2D0D62B94417812E105D4C8E8B7C84 -:10B220001E05C941E32650D8B8F97FC4A14E571D69 -:10B230006AF91478344DED173B4CBF1827DD6726AB -:10B24000ED745292D8D8B217A09CE1F993ED683D05 -:10B25000AF496FFCBBE407F841AC31ECC8C3717572 -:10B260006357318E8F49ADC6B8A1F117411C1F8FAE -:10B27000AD0C3B1E21BF6EAC76CA00DDDDABC24B10 -:10B28000705E4DF35500C615B495F0E43F5BFD06C6 -:10B29000FE6AF736D98F71A4167A64D2CFED42CC0C -:10B2A000103FA158803AA4454BE3179DB86E89A87A -:10B2B000F6503CB6BBE33E0971DFDADD9C03A8EF34 -:10B2C0006ED158EFC27DEEAAA45EF85C4BC3715FED -:10B2D0005F591717BCFFF9C8F790544B72CCD58053 -:10B2E000E438CDC986251B73DA304F0C279CB04F4C -:10B2F0004A9EF3A31CF508C901EE1220BBE7BB0D63 -:10B300003EC37D65656497930412CD6705AA09B7AE -:10B310000F73C22769FDA8D7F0AF936487DAFBD318 -:10B32000DF4BCACF697DEAF3D10F5100DC7F415278 -:10B330005F27793BD23F2DA1BC34B2E0BD5D7A20BE -:10B34000E9A71C9EBF06F58E2A1013591E59E8BFA7 -:10B35000897914D006E368CFD10DC80771A809AB6D -:10B3600051273EFEC29AB1102629E27B8ECEED1007 -:10B37000F5A205B8EFA5953744C3CF0A0C3F33F3C8 -:10B38000D0F90BFDCFE71BC3304C88AB8E0B77FF9A -:10B39000F927C4AFE3B647A6E5C9787AB90B7CB400 -:10B3A000C863CB1B569CD59F75C5051F8D1FDA4002 -:10B3B000EB16BD37504C7A2D1ED0A35EE273FE0F04 -:10B3C000F9861C665D503EE13E4F5D6816283903E4 -:10B3D000749E16622EC4AB938B5CF2D2F824276B5A -:10B3E00028FF5FDDE81F19B45EF1E4A15E9B4CBD50 -:10B3F000DAFB8FEEF222DDF4CA93CBA182C2C1C97F -:10B40000F2B7845F8AFF2DC79DC97CCE7ED110A87C -:10B410006707589FB8487ED0DE6B5FD701FB3FA619 -:10B42000BCD33131CFA35CC392378BD9CBAC57405F -:10B430002504F93D6DEE253D3C24F77931E6E29097 -:10B440001EEA92FD3436E3074EBCC0FCD25A0FAF61 -:10B450006432DB5BF1F4CC1E943D338957E53197C0 -:10B4600042B8571ECB5148BF4A11D68519DE31E686 -:10B470007795E81B1CFAD36BD3C7823C9EF3DAF9AD -:10B4800052193328BCB15381BFCC49CAD769C653BE -:10B49000B370A249443FB8FD14F83124A1B3FFA70B -:10B4A00051378E3BF702AD80DBF4837C6E0FF131B8 -:10B4B000E253DF5F9D4BF63E65C6A72B97076902F7 -:10B4C0004E69D234904A93630B5F97699FF4D21907 -:10B4D000B679AF3CCBB63FA32E68DFAF2989F21017 -:10B4E000E56363FF74E561DBFADDBE962BE4978BC1 -:10B4F000121B97132E994BAB6CF32170B3FEA1B6C0 -:10B50000C023C7703FDC31EA791D7E593D808840F9 -:10B51000FA35E8003F467BD40F3B6C764FD3D11F02 -:10B52000715DDAB50976C73F97641FCF0F987E50DB -:10B53000000513FD2089B3E71E8ECC0FFA7111E1CF -:10B54000EC1563D8724CC22904733268BEF68A00C7 -:10B5500031867B971CC7E733C376BC73DAEC78E798 -:10B56000A9767CF337D9F12D8CD8F19DBDDD8E679E -:10B5700040B3E357BCA7DEB67E6E4FA36D3CEFE051 -:10B5800032DBFA8762ADB671D9F1D5B6F5F37B9FA0 -:10B59000B0CD579EDD6C9BB7FC2AD5EE0BE29DB675 -:10B5A00075A976AFBEB2C3C6D7B2B386DFFFA79D7B -:10B5B00037A7D8F95B281BC5DDDBBEA1FD14865F6C -:10B5C0004E37F252B3B030A190BD173A65B2E93BA5 -:10B5D00052669397E2DDAC4361B30E417817B37BBB -:10B5E000D8F41339215FA23C5A753DDCE4C3718D58 -:10B5F0001EB944E93834D4D39421313791FCB89E34 -:10B60000337179BC8E03872D5E709C9DC46DA5D669 -:10B610002D64E0E2864F6351962EC9A9F0FC567363 -:10B620009EAB33F2FA0A250D1C13F058643E072A2C -:10B63000DAC86FA131052BCDFB00F6E520525FCEB5 -:10B64000BB63D1C054FDA47C50607D92CAFAA6CBE6 -:10B650009CEA24BACA9D28A2FA75285B7D298079C4 -:10B660007E849725D667717A94941A25C558D17926 -:10B6700027AC9453FF8EFFCEC2BCCB5F0D6B1E2652 -:10B68000BE5F47F955539EC301F55000F11FE4FC1E -:10B69000BBAA71EFDBF51F1551FD71098804E6C1E6 -:10B6A0004C9FF2133A47DBBD703AB35B0EEA8779E1 -:10B6B00054E725D63F683B38761FF888983D3221FD -:10B6C0004EF73859DD01F37EB4D6C4CBBA1FAD3185 -:10B6D000CF1F44169B304FAF3D7B99E1B2257718C1 -:10B6E0001C99CCDF589FF46481A76A1FE9A454CB4E -:10B6F000ADF3E9B9755FCA173E4B5D6C16CA33F4FA -:10B7000029FA458B6EC91D62F7B97BFB4F1875E4AA -:10B71000FEFC355667937A1BFC07F7A6B3FA32B8DE -:10B72000B7B0916892FF08E3BF36F2AECD4FD66D49 -:10B730007FDFE67FEBB53FDBE6F5AC31673EEAAF96 -:10B740009FC96BF93AE277EBB42B44F746B4DB358B -:10B75000B28BC55F3F306F099DF7DFF5FC1BC377E8 -:10B760006067021C73927ADED8799D8DF59D3AA3AD -:10B77000A97A5AF74C8B8A17A1D481F619E3A6C986 -:10B78000470293CFD91C34FAF08147B31BA9CE0EE0 -:10B79000148A0E839618E3BC3AB7316E594A74D4B2 -:10B7A000E9D943F7CC010E140EFD610DA7BCBA1EFA -:10B7B000F97E3B5BFD98FCB363F3588503E3A1A3DB -:10B7C00052FF0647A97FBA7A87F4E7B0BDCB9BC189 -:10B7D000E42CA1BE6388D72A38CC0515C19C15D4AA -:10B7E000970F4DD346A812971C99618C45233E4272 -:10B7F000C17FB178A8F1ABFF263E1F70429CFC567A -:10B80000FB25173BCAFC4D175BBD2C9EDAE8DE45D5 -:10B81000F75DBA6F8CA619D419E4987E620AA55E0A -:10B820009D682868E4B566617F0947FDC1411750EE -:10B830003CE0390AF515DA7957EC288EB35176EAEF -:10B84000537E2D1AFD7CD5AF5C71CA1B1BDD77982A -:10B850009DF28201C62FAB183317F2C97AD1158B2E -:10B86000927C7AA26805CAD7E3C4FE85E2FA1ACEB2 -:10B8700023DF5B07E61DD937C11E7941E37E084F00 -:10B880000118F3398769BEBD7FF006E5918B01B5DC -:10B890003088FC0779294479A4DDF7A648F9A73256 -:10B8A00028B17D282FD317F3C1773986B3DBFF0189 -:10B8B000FAEB3A4C3619747FE3D5B9C15ABAA7E806 -:10B8C00022F1438F60FDDFFDF4BFB521F1C372A407 -:10B8D000235EB988CEB1CE45392A898FA5B72547D1 -:10B8E00092CF83FD7AA37BCC16BF375FDE5D4271BA -:10B8F0005225700C9FD4F52D262E034EA3FF4B9D91 -:10B900005F4FF6AC9DC23EF3007291BAA661AD43A3 -:10B91000BA927042FC6E7D0DF5617D8BB280ECDBDE -:10B92000DEEA91296F59FC918FFAFA03CEF92427A8 -:10B93000FC25B2C3E6C8F7CE5C9592F3E87FCCAEA7 -:10B94000DA01C35FDA2FBC7FE3793CE5999FCDAF85 -:10B95000A63C6DED4FC579C42BB1F73B4F087186FE -:10B9600023E2BB9AF8F75DF95D36E162E1FC79719B -:10B970001D2D4C88C47FF4F0DD2209F7B79FBB7CF6 -:10B980009DFCB6DD7CBF00A7ECEF0D102F8DEE9374 -:10B99000F7EA08E5D6D96C9A9BD8B7B9ACFD050E85 -:10B9A000FB7E6CD0793CEF94796F394BF9628AFB5E -:10B9B000EDA904CF4AF4A95CEC0BA9FE60BDA77AFF -:10B9C00063D5FBADEFF22C0EB60680CD935C6457C9 -:10B9D0004E7F8BD51FEBFD4594C3BA8AB8758AEAB2 -:10B9E0000BE497A076B17A24CC46BBE2BEBEDF2C36 -:10B9F00033EF69467DAB35EB592DF121F9CB335847 -:10BA00009DAB31CF0DB9B17F0A52A9D0CCF734E646 -:10BA1000FB8CBD6FD9EE77FF01E91E35E2601400A3 -:10BA200000000000000000001F8B08000000000064 -:10BA3000000BFB51CFC0F0038AD5151818D6293159 -:10BA400030DC5266607055616038278F90A31556C0 -:10BA5000E5A04CFF0B4606865740FC0688DF319276 -:10BA6000AE5F4B18C15EC9CBC0A00DE4D7006955CD -:10BA70000106062E205B0788F701F9F780F81510FC -:10BA8000BB08313070F331309802B11810EB02E589 -:10BA90007D81F4373EECE6EB09E3B7FFB9002A5F9E -:10BAA000521095CF20805F7F97207E796921D2C385 -:10BAB000C44E9DFCF868A240EF40E09B0CA87C0BB4 -:10BAC0005906062F3906861E7908FF1A92FC3CA0FB -:10BAD00098A52C345CC5816907C8BFCC80DD5C1992 -:10BAE000A0BC36507E15D41C00DF43986568030067 -:10BAF00000000000000000001F8B08000000000094 -:10BB0000000BE57D097C54D5D5F87DF3DE9B2DB384 -:10BB1000852C842D4C58141070085B1094C9860134 -:10BB2000020C8B881675588410208980FD51B51F32 -:10BB3000139688967E0DA2965AB0030D82FDB00D25 -:10BB4000183560A0C366B1451B5C10BB7C1D16D9BF -:10BB50000C2404A5A3C5FADD73EE7D99F75E664853 -:10BB6000B4FEBF7F7FFF7F102FF7DDFDDCB3DD73F9 -:10BB7000CEBD910D76424613F235FCD07499400843 -:10BB80004989A6F4E79F5FA71232C94CFF2512929C -:10BB90002FDA081942C8441B099A689D89A3E8C78F -:10BBA0006442DEAD128222B4A1F502C3082926EC5C -:10BBB0006792446A85DB0969CE7AB562909B10C1B1 -:10BBC000EB25CB3369EA769199908E3AF085E020A7 -:10BBD000C4996520A40F6BF335FD9BE8B5625F4AFD -:10BBE0003EA9A083269FE2EBACA9DF71460F4D79F9 -:10BBF000277F3F4D7997A24C4DBE5BD91D9AFADD48 -:10BC000097E768F21981719AFA3DD74ED1E47B57D4 -:10BC1000DEAFA97FEBC6D99AF2BEC1624DF96D3B8A -:10BC20009668F203AA1FD3D4BFBD76A5A67C50E8C0 -:10BC3000694DF9E0A3CF68F243EB5FD0D41F7E7269 -:10BC4000ABA67C44F8579AF29117766BF27736EDF3 -:10BC5000D5D41F1D39A8C967933F68EAE79ADFD793 -:10BC6000E4F35D7FD6D4BF3BED8CA67CACFB534D9B -:10BC7000B98207E3FB5CD37C9FE0F987A69D447CF7 -:10BC800014D884184919A6665289A99554636A2361 -:10BC9000F5989E49F7DF8FF8F962A08250BC5B15DA -:10BCA00068FAEF249ABE9BD5D3E9EF0FBD7909A1BD -:10BCB000783B91754D269A6D2191E299C94C0216F7 -:10BCC0008A0A8E08C5B7248A771182A92B42F16DA2 -:10BCD00030C5BB8819D30E910EF83D29E2C2343924 -:10BCE000D219BFA744D2304D8DF4C0B463C48D695E -:10BCF0005AA41FA69D227D30ED1CC9C4765D221E6C -:10BD00004CBB46EEC0EFDD225998A64772F07BF798 -:10BD100088175377641CA61991024C7B44A660BD1A -:10BD20009E111FA6BD22F7E3F7DE911998DE129946 -:10BD30008DE9AD113FA67D22C598F68D1461DA2FED -:10BD4000B204DBDD1629C3B47FE431FC3E20B21C13 -:10BD5000D381919598DE1E0960EA893C8DF50645F0 -:10BD6000D6629A197906BF0F8E54623A24F2027E87 -:10BD70001F1AD988E9B0C8564C8747829866457E15 -:10BD800085E988C80E4CEF88ECC6762323D5988EBB -:10BD90008AECC5EF77466A31BD0BF02D09F02E8491 -:10BDA000A937F27BFC9E1D398A694EE43DFC9E1B3F -:10BDB000A9C7342FF227FC9E1F3989E998C8694C1E -:10BDC000EF8E84312D885CC2746CE402A6E322CD30 -:10BDD000D86E7CA409D3C2C897F87D422482A9C238 -:10BDE000EF4896DC1056F0AF07FC7FA6EBDC6D94B5 -:10BDF0002F11BFE16B9A121BC58311D1FAFA94720D -:10BE00003BE49332C5AB048ADF899417023F9C5808 -:10BE10002604EFCEA0F8911C3E0C7939CBE436D144 -:10BE2000FC03A44906FC25A4DEEE1B40C88111E7F3 -:10BE3000BB8629BEBE9B12EA46911B7E90DFCA30AC -:10BE4000A79EC06F1BA430FD3E31F9608ADF06ED6E -:10BE5000296D64027AD3F101BF293A025F7E402244 -:10BE600001079DEA71E86104D60B99687E6621F1AD -:10BE700066D2FA15234C3382749C8A4C5F918FA64C -:10BE80003FCEF0CD80F4F7403C74FE87787A9C1862 -:10BE900030FD32DD85E9CC477A337ACAA340ECD451 -:10BEA000361C1E4865ED88AD291DD6D7DE7612A159 -:10BEB000ED8646EBBF4C7C1FC2F7400EE953668B04 -:10BEC000D6A3DF4F42BD18DFFF1CEB7BAD813202F2 -:10BED0000AFF400763701BC827E2764E867999DD1A -:10BEE000CE29F6F8F37A7285ABBFD44B3DCF20CE86 -:10BEF000EF4981CCA866FC256DCA00EC1FE561C046 -:10BF00006AC1FE450E7FA5DD67004FDAEE3D8BAFBF -:10BF100091C9537757848BCDD52EB8D076D7112EB3 -:10BF2000126D676F7FBBF869258333F1BA711EFC10 -:10BF30007BA9890404BA8EA66DF6E0D60CC06137E1 -:10BF4000F2CF221767A0C9141854AE1725C21208E1 -:10BF500039BC3F2164A0F573B6D9B7821ED09813BF -:10BF600078DE0770DE2A936DB4CACAFD3F3AF173DA -:10BF70009ACFD9221313CD2F48786E18A170BB55D4 -:10BF800010D8F801EF815EB47F3F517EBC02F43FD0 -:10BF90009FB0FE1B054647816D4E84EB85BCAA8A87 -:10BFA00091340DEF5B5C48281F3F4FC1DA89E2F7FF -:10BFB000022B9120A51CDC88F009C867C38A7C414C -:10BFC0007A96A279B1757E3EE415FAA7EB5E1094DD -:10BFD000A379FA77E10E6D5E052FDCF7268B1CDC6A -:10BFE0008A78D585C1478197B70B831F87579E45B0 -:10BFF0000E1892115E41E0034EC18D7028B2C82127 -:10C0000091F65344E1082458B4EFA95480D3C21DDB -:10C0100016D759D5B88BAB1335F9D2DA4EAEB32A51 -:10C0200039DA7CF4970EA0D3256906D759CADF1AEE -:10C03000567893CED22DBBB2A20053053F16576758 -:10C04000B86C9A7EB4F9E64AA180E1B7DB396D405D -:10C050007C3C5B9266749DA5A47A690793B797565A -:10C06000985D304EC30A978B8D9B86A902AF45CB56 -:10C07000AD585F995FBC7EBFEBF9115243CE9881FA -:10C080009FD3B29EF1EBC7A527E93323D2499D7C0C -:10C090001DF0C64CFF7E6D403CC2BCD26F69B51826 -:10C0A00030DD0EDF776AC6A3EDDCE754F2253EDD16 -:10C0B0004AE49C0A2F97420748A766DC673FEDD108 -:10C0C00049FB6B946C6B418F9AC0F1A714EA517EC7 -:10C0D000B0D81C36FAE9A7CB356C3FE28D7369C541 -:10C0E0008E2EC0D78ACC9546605645D57DF3809E6E -:10C0F0002ED7AC4A05F9B2506CFEBE2F46FB1F2B63 -:10C10000741B949BB4F232C8E749FBD5D019B1B582 -:10C11000AC9BE61B0C74285BEB7E7F2A30B953B2D4 -:10C12000F3F8989174FE25B5578D308F0982FFA7DB -:10C13000424A74FD02AC9FF653BCE39411D677419A -:10C140000EDCF278C64DE0D96A9EB6B47309AAF93E -:10C1500005A82249E9757616A757E2BEF7CF943EA7 -:10C160002FFE41264FD379901BB4162D4FE7A573B0 -:10C1700089CF01F09A5DB310F9CF45E03F208749A0 -:10C18000E530C08FCBC45000EBBB4CDE730C56C106 -:10C19000EFA060E4F0A1AA2CE507261C0AE1D6096D -:10C1A000F895A9A8A25E1C08DFA500E74BC2D7C876 -:10C1B0004F8202F2B322F63D40CCE5B88EB58C1F1B -:10C1C00005E81FC83F5CA9E54FF3376AF3F3C8944D -:10C1D0005489F29779CFCAB447CADFD4FC8FC2EF33 -:10C1E0006581C9DDF9A4ACC245E7BFD948F789CE5E -:10C1F0007FB68B485DE8FA16BFB179D82C9A7F5B81 -:10C200006072ECD20A3AFD5B683F1DD8FA8B970743 -:10C210008DDEFEADD777A666F0F49104FB63F2B134 -:10C220005891BFC42D0D436E4995DCF8EBEF5223B6 -:10C230007A2D0EA847BFABF8F39CB5DAF5B5B57EFD -:10C24000FD7A097906F1AD78C7640278A6AC47D9C2 -:10C250002F653DF20EC11B8C4107618EAF0A5F6BEB -:10C26000E2F053F48ECF75F92F75F9AF757905BFEC -:10C27000654EDF14EF3F1786023D378D6178123629 -:10C28000B2F30CAB678CD6FBF266F54C9C5E68BDD6 -:10C29000AF6F56CF12ED4F32A4B4AEB7F88D575EE4 -:10C2A0000F50FC2EFECD730E42F1F1A25499EAA17B -:10C2B000DF176D5BE300385D90020EC09B8B41B1D0 -:10C2C0002016BC46180445DFB00974DF4B14FC1F70 -:10C2D000553E11E4FBF56DB2EB69BA2FA53B4C213D -:10C2E00013DDEF929A05856420E64FB1FC93570168 -:10C2F0003F4A6BE5D3EA7D2DDEFE5CAADB8EFBD0E8 -:10C30000C5003A30097521342DA9FA640CE8D1A58D -:10C31000A409F159DF0EC687A31DE5D7B38CCED68D -:10C32000E5CAB9B1947D22A5353FBA0AE7C65222C3 -:10C330009D56E35111E032D5F3FA19ECC9705E2035 -:10C34000C3C970E02B0A1C483005F9F2AA977F3A5E -:10C35000F0149D4743D51F1C820A3E544342B83413 -:10C3600057CFF95BD24DE4C2158A9FE41675BB2006 -:10C37000B673D7D20974A4D93A962E92438E9114EB -:10C380009E8BB6C81E8A9964D12BBF7CE9054A777B -:10C39000E46393A73785F7C2578E9CB883E617EE00 -:10C3A00092930BD9326C426A743F4AE95FB0CB2852 -:10C3B000F02F7EF588D13D807D7FA243741F16EE5D -:10C3C0003A6024035AC32DB7FA80316C8BB11FD564 -:10C3D000A7C6803EB3EAE5BF1B61BF2FEE1748C773 -:10C3E0008CD6ED8BB61C41FD05E084FBC7F7A76535 -:10C3F000BF5AED5368E2DE2158CF05FC3ADE3ED944 -:10C4000041560F453CFEF55E3A7ED19F4C1E587F4B -:10C41000D1AF973A601DE7A53286CF9BD7A47AE9C2 -:10C42000B8457220D58529FB5EF4E2A38867F38FB7 -:10C430003F8A7A19C58F4E069419814EB0BE873750 -:10C44000DD83EB9B47FC886F459B455F10F880447C -:10C450000A76C5A087DF707A38BF95724ABABEF3F4 -:10C46000C01F41CF7D4FE4FCF111D4231FE56BA524 -:10C470009A0CE63F37B37DAA301814BB9C5983A7AA -:10C48000554F221FBDD4CDDBD1D51FE1A0F04DE427 -:10C49000A7E2F1FC8E6C7F18FFC57614EF72E13BCA -:10C4A000D4AF97BD96819A769C5FB2F197F1F1E98E -:10C4B000BCADA07F9C4F657242BFBE3F1914FE48C1 -:10C4C000E5AB0ABF5474CDE8BCEA2946D70A9D07FC -:10C4D000271740F9671F30FA8176207FE8BC421D9C -:10C4E000B1FCC03401F980898462D17395CCE959DB -:10C4F0005B4E3934EA6F74DE92E054E309EDBF031A -:10C50000C21FF59279CFD2762A7DBA14C6C37AC6F5 -:10C51000E8F78C28DDCEE7F4FF2BA0FF8428FD93FD -:10C520004D29ED3A9F2D92832FBD00F44AE933E067 -:10C53000067A957DB0EE4F771E3A713FC5EB4FAB53 -:10C54000153AD5F24D3D9D16ED7E94007EEAE9F454 -:10C55000D3AE6524269DD2EF31E9B46BF87F856FA9 -:10C560002A703BAE831BE583BFD8EB8E0F3F3D1F88 -:10C570002C35B863F241FAF30119D61AEF147C5343 -:10C58000F0ACF8BF1677077ED3828F0ABEB5E0A362 -:10C59000826FFA756AE1A62FDF04FC46A51FC82B3F -:10C5A00049C04EF7B9699F88E7C4467793A3031D36 -:10C5B000778D853C047A76A38BE71359BE29C5583D -:10C5C000017C41F9DE642133003F1B7D4D8E449593 -:10C5D000FE7CAA4E74B8697938480A62E9D594E3BA -:10C5E000E2F86112AFBC1CE1972FDAD2970F81738A -:10C5F00095E801DD6D6EF9BD0E305934D6F59C34E9 -:10C60000837E7FF86D116D1A8D56C74098173DB720 -:10C610004B9D287CE7F07DBE4002CF8FA2EB9A5362 -:10C62000C7F4E2B9EBB4F098675B66043E43F5CF1C -:10C63000281EA8F045F113146DD296179375B85FB4 -:10C64000C53AFCF1F3F34E2791E3CF2032889F37B0 -:10C650000CD0DF12CEA7F2C5FE936650B8371E1578 -:10C660008989E69BEB445201EBDC290409D0712057 -:10C6700005F1B084F207A23A1736009E19E3D36F92 -:10C68000C36B7F1DF638ADB2E8F53F0FFC394D1B8B -:10C690005EFFF8963721FFC647E97F26ADEBE7EE50 -:10C6A000FFE241E0EF8DFB4D04ED24FB7F97FE3868 -:10C6B000E4F79A3C68E75869F2A27EBCDF1EEC0DF5 -:10C6C000E5DD987D69D5BEBF0F0CA3BC598DFB94E9 -:10C6D00027B2734473DD3FFE5B488694AE0AE4E8FC -:10C6E000FE04D4AF4BF75A8270E86CDCF7F7617E3A -:10C6F000DB77B79E1223F123FED9C98CDD80AF8989 -:10C70000CC9E56FAE6885F96D3F117D71C30CEA19F -:10C71000E5B9BFFD6A20F095C6DD4C3FB822875FC2 -:10C72000241E422689CF95CB74BFAE80AED699F237 -:10C7300025F14476C0160B2E0C0E8D140EB02E0A69 -:10C740009722E087F1E031EFDF161E571F84F117C3 -:10C75000D50D2762861A2E82977DB707CD02AE9F30 -:10C760007DDFFFF781C0773FAD2E47F9DDD6BAD721 -:10C77000C0BA53FE5F5AB7106ACFBAABFE6DD7CDC1 -:10C78000F0BF9FC8E4919E0E5AE3F91BDFC7FCAFD0 -:10C79000ED1E9C6F3BE9FFF0BFEDFABFE5BEEF1663 -:10C7A000D01FD7D6BE9FF9B75D775BFBFE36DF772C -:10C7B000BB0BECBD8DFBBE4A27AAF5B7B56E83F463 -:10C7C000EFCADF6EBE6E45EFA93794B986D0F97D0A -:10C7D0004C2AEFC9A0E91FBDD792E1384A69C017BA -:10C7E000EBDC9029B1738309EC4C50F11E41B11779 -:10C7F000D56BFCB85D8B50CF98E8FD31EA07442A31 -:10C80000ABCFA6F5EB73E6789EC61A9927FD909FED -:10C810007627CF6BCF531373C61F05BDEEDD723A7B -:10C820003F885BE826B9A8A644267945D403698ADF -:10C83000FADF87E963B0DEA42CED79E23EDD79E032 -:10C84000DE19DAF27B78FFD3C9332960779B3E97F4 -:10C85000D9DDEE25656B5CAA7DBA47D78F4322DC14 -:10C860004EF2EDE037B7057E4B101E245BF46C23CF -:10C87000ED801F61F0AE9F3628087618227918FCEB -:10C88000A62FF6A01D949F3365DE5EB6ADAD07BA48 -:10C890009589F67CA99C13DB8233E1E74FECAF4727 -:10C8A00014EEB257C4F3A7AA5F848BB21FDF741FC4 -:10C8B00094FDFBB6FB310CF62386FF6C81D97C0F0F -:10C8C000F82FCC7D043CB74F5A27621C8CB9BF802F -:10C8D00070F465C9E8DFF9C4E01B068A73E1E0E1A2 -:10C8E000258FB16E3D009F051C8EF34819EA9DE42B -:10C8F000C6D75F8F02BF114286967B099940CF2130 -:10C90000F34609212B5DF77C89049C9960D714C8F4 -:10C9100069B55D33A8CDC3CF5DA9D17EDAAA1F8FDB -:10C920003F7CD7E9DF283F3ADD8B9E572095707812 -:10C93000497D4E7CA88EC1B1749110EC817814921F -:10C940007D2ABFCEC71CAFFFF6C460E473D93F1980 -:10C95000E0C4F3ABB71FEAFBA55CDF6F0EB89D60C8 -:10C96000AF69AEEBE9047B4CF3D15C879A2F2AE9DF -:10C97000717E8E7C7F8519D3C63CA15284F31669E3 -:10C980009A887238CF4280EFE8DBED9114BB4B19E7 -:10C99000F333D21F7118EC23FB994F9B3A3BA8F657 -:10C9A0006DDD848BD2C0D6FB003FA7557E927F15EC -:10C9B000BE706E05B81EB784C7F862ACF70F1C7E58 -:10C9C0008507BF30829D604A5D860C709992276A08 -:10C9D000E26E0E49FC3C35980C8679151E1CEB184E -:10C9E00001FB7254F458287C4BEBAE1AFD31FC6D00 -:10C9F0007A7842FF60173E237BE6013CCFFCD842A9 -:10CA000002941EDEE1FE1F5AE405FE45BBF2827D64 -:10CA1000EC0389F915FACACC2E3EB5305B4EA1E382 -:10CA2000F6AF710D0211D399D7EF2BBBB1BC0B6FD1 -:10CA3000A7D4EBBC88D53B657495C45AFF04235B2F -:10CA4000FF7CE2F97E96F0EFB76FD93FB187724075 -:10CA5000BEE709C8475AE33541FA682E1082207FA5 -:10CA6000E11C8BF94201E5FF3B06561E98C2E4A586 -:10CA700082F77A380B3283B3327E86CCF0D92833F2 -:10CA8000F8287056E0AB9FAF529FF2ABD16AFBCA59 -:10CA9000A4DA41BF06FDA4A44E7081E9AF440A1B8D -:10CAA000810E4B6BD7CBE02FB8CFCDFA25926FA07C -:10CAB000DA5FDB5796703E873247A2FE786D1DD352 -:10CAC0008FBD73AF3A400F7AC7E0F9E348A0C7774C -:10CAD000458C278807C73FAFD8312D4F52F79B8130 -:10CAE000F39CBA285B0673D0F7161D903BAAF0A9F9 -:10CAF000AFDC01CB95EF9D17B933E13B1D0FE7117B -:10CB0000F84F13D946BBE85F5D9F9340CBBF579664 -:10CB1000C8F0B0A8FA8011F319585F194F19474FA0 -:10CB20004FD30A1334F939B9E1AE009742536899EB -:10CB300027069E1E96153FC93794135E8AB703FFDA -:10CB40007F901357C77863C06D83DC4A3E748C2591 -:10CB50001F9694BB3B02FC97ECEBD9118863C9DBB1 -:10CB6000F9A9B1E4C3872B983FF023CACF206D9C6D -:10CB700046E5C3ED2AF930CD82F8A16FF743B99DA0 -:10CB8000F241D9AFFF653EF321C88718745D296B68 -:10CB9000E5C3F4BA59281FA64F13895B658F7B52F2 -:10CBA000E67EAEB8F2213BF53ECCCB9E841878F3FE -:10CBB000213F97005C218571404EFC96F37DBDBC02 -:10CBC00088C7CFA71805EEAF6E839FFF5F82B3C201 -:10CBD000CF97D0F30BE881ADF19020BF5E721FE5D7 -:10CBE000E702E023E3E74B1EE076491D7FF5017F76 -:10CBF0001DA2E6AFAC7D899FC983D2DA8C9FCEA4FB -:10CC0000E5F757CA1E33AD7F7F94DF0E53F3DBDFAA -:10CC1000727E4BE19CEE8AB1BF33662610B7965FF9 -:10CC2000F5023E7566D0EFFABF0A78FF8E887EC4A3 -:10CC30004FB81C3F36E87743C07E9E6C94107F3E11 -:10CC4000E1FCEBCA8AE0B43C4AC7B973993EBC78B0 -:10CC5000A7887028A9617A5E492F6BD04DF36332A3 -:10CC6000BF407FE0C27DCC1F48015598ADDAC78533 -:10CC7000EF842BBA40F91601FD99F33C0BD18E4F8E -:10CC800036323BB199FE61711D5EB4232FE6F05A36 -:10CC900050B705EDCD0B825A3BF4E25EE32EC2396C -:10CCA00040E1BF0B77E8CA3D4FA1BF6231D89B5529 -:10CCB000E70F91EB0F0F8BA1FEAF426CE71FD9B9C5 -:10CCC0004ABFFF4ABD96F517FD8BEB3F4ED73FE4B9 -:10CCD000BB5F7F7BD72D1B39BD679221401F9F18FB -:10CCE000BC48EF81DFD3F5D371E6AEEFDD511D67B0 -:10CCF00094C4E9F21D83BFA213D42B11B0DEFC4D06 -:10CD0000BB8EA4D2FCCC6A3208CCF4F3376AE5625D -:10CD10008B1CAE71A39C9D59B64B98DD1FE04DCA8C -:10CD200000CFE6649AFCE04F3D6E6942FEA5E0DD6F -:10CD30009D4686CF23F9B8673A37E5E139A25670A8 -:10CD4000215D842CEC5C41E16FA1F94323FE3E861A -:10CD5000C31BED31A5B56C7F4AE97E005D8DA9E36B -:10CD6000F91D4C0FFB1E9537E80FAB3B2043BB2250 -:10CD70005A3F09F94D3F8D9F0BFC73D9A9AA7DDB62 -:10CD8000778AE1ED36C14362EC5B1FFA27E6BE7D90 -:10CD900047F8AAC0E34E23D7E7F9FE1DB7D4170E14 -:10CDA000463F94E0D90A95EB12D18F72B6B227EEC6 -:10CDB000E3788EBF7ABC06FDDEADB2274D8689438F -:10CDC000BC658105E3DC70DC1E4CFF51F313FDB93B -:10CDD000B994D4A31E3341F0FF5552C5B54DE7F1C8 -:10CDE000278A9F5655EFA7F24DEA91349701F8E450 -:10CDF0005225DE12E28753316E097F0E751BF6D184 -:10CE00004CBADE6B6B450FF87FEE35B84F8C02FAEB -:10CE10007D5A268097D78EC95EA6772620DF9DF59E -:10CE2000CE19194C21B3284C60BF67FD90F1D73360 -:10CE3000D019FDF6272AB7BCE0AB27D543217E7871 -:10CE40009AE740BE9BEECB3D438EAF013FDCD45C06 -:10CE5000D7891300DFA74402F03DBD3617CF274B1B -:10CE60001F1110AF4F523842FB7BA6659C3841C75B -:10CE70007D606D0AFAD5667A8FE4039ECD9964B71A -:10CE8000817F6D7C1F91F855707C80D4A39D626674 -:10CE9000D923F7C07C8BA81C003B6B51DDF1FC8EC5 -:10CEA00090DF2478DCB4FFD280DFD8916E61FDC6BC -:10CEB000AB46B0B7CCA3F5607B4A37B17AA55582B3 -:10CEC000C702F858B71EF9CEBC2A81B8A03ED5F7E4 -:10CED000CCACDFA099F65BBF89B6A7F9F9D01EFAF2 -:10CEE000AD4A9C0E7EB4D263226B9F55FE16F0A510 -:10CEF00079B41D2D26F5558F607F0B3609248DF6EC -:10CF0000579495F19F59D0DF31D903E51F1DF8994A -:10CF100011E6FD201DAF13ED7F8E18CE87FAE47168 -:10CF2000C1B50DED4D2C4EB691D301F9A013A32F31 -:10CF300081E7B91EA8C8C3F78D3D109FE62D2FAF1E -:10CF400080758503291970042AADBD6A04BDEE2CD5 -:10CF500085B39FEA6D67781CDBA1C0196358C5A72C -:10CF60009A8C3DB1FDDCDA6CA4EF87890FFDDDFE04 -:10CF70007226874FADB10405D03F6417CAC9436B11 -:10CF80006E7D1ED67FE51519FDA357BA85D11E7B90 -:10CF90007E934C02748EAB3689C837CEEF64762010 -:10CFA00071B38CF9F98F1A317F68D3D431C00FCFA8 -:10CFB00053F8031EE66ECE37427E3EE5EBA618FC24 -:10CFC000639EBB98F10B1D7F98BF514BFFADF8C519 -:10CFD000B2318CBFEBF8C1E2AE1568E7D3F38952EA -:10CFE0006253F84326E4EB439D107F4B8EC904F453 -:10CFF000B912C9F5E046C09B9916F01453BA081D42 -:10D0000001BE762D28B803B4FC7B0FED190AF03B66 -:10D0100007F006BA589784FED479C1590857259E5F -:10D0200070FE462D3E2BF14BF7F945E255CB81A220 -:10D0300004E255D5FBE887142FE9780FD50A418B18 -:10D0400000F9536F3D3A04F32EC0C392E55C9EAEE7 -:10D05000B323DE7EF483AB6B002F1F7C42C0F993B9 -:10D0600080BF02E44AC946C10D76CCF94FB0F6F351 -:10D07000697BC0978F7EC6F087E2B11BF0BC64D39A -:10D08000FAB7B07E95E086FE3FDA320BE56F51408D -:10D0900024585E750AF5632A07300EE850404C05A7 -:10D0A0003C2F596D72C13E2AF8A2E0DF2999F9EDB3 -:10D0B00089D933702A6DB7C5E8C675EBF14E9C91DE -:10D0C00081F855BA5346FC280D307C3AF58A8878A9 -:10D0D0007868CDBD883F57B60971F02FD7D809F0D1 -:10D0E0002FC8CA5BF0EF6581E31FC3EBF3CB183E9B -:10D0F000E64239E0DF6B5C3F25C4A6D63B14FC5307 -:10D10000F0A92DBC6B2597E2E01BD58DA7C3BC967B -:10D11000AEB1E0BC732BF64C5F8E7423A37F3EB799 -:10D12000E207A940A7F3241687A1C071B1C4E27435 -:10D130005ACDE3D97263A7F6CC47378F0351B9981C -:10D14000097211E24A42749CDFEDFC25C6AF5DFE18 -:10D15000D5298C4B5CF826DD775AFFCA4E3B09A1D6 -:10D160003E1D44FE525C23625C289142C3A6AAEE97 -:10D170008F28F1160B7F6347F816EF36050B69FB16 -:10D18000E2D7CF0C447FF8CAA6B7807E02BF1298C0 -:10D190005D3E101E3815E22A2516F7A197BB234CD9 -:10D1A000CC5ED3B0276106E83FC28E03E84F2AAEBB -:10D1B000BE5736A9EC931E938CE3D27AEC9E0BDD1E -:10D1C00077F023C2FC260F50CFAF9CF5F732A39B1C -:10D1D000E25A19F5A2E21D5BD0AE57BAE32AC6BDEA -:10D1E000E6FEE61507C0A1B456D4C643ED104326AB -:10D1F0008CD7124F99187FD2C42595D4B07B1925AE -:10D20000D53CEE471717B3F037FB5E0F50D02C7CA0 -:10D2100075BB03E8E852FD3607C093F687F14493E7 -:10D22000B2E2C41BB5156754FD54CC38A34BF00FC4 -:10D230008A200F9AB4F1996407E35374D787F9628F -:10D24000D833157D65E12B9FBF0871AF0DBB3F7DC6 -:10D2500011E6BDE89FD75E84B80DB2DFE202FDA102 -:10D26000F4571F62FCA0D26EB9899F7F5EDE8E717B -:10D2700097573E36A1FE7765DFF974D00FAEECFA12 -:10D280002215E22997EDCB47FBC3B2D7723B921828 -:10D29000E75B2505BC0CB623EE53BF0F876AC4902D -:10D2A0008DCEF3F24913D2774BBC58F562167FE767 -:10D2B000E671623B63C7D52AF14D25355327DD0959 -:10D2C000FCAD86C9F19678A7B6E2C33EA0FB797B98 -:10D2D0003BF66D278FFFD3EDDB65F807DD9FE74C4D -:10D2E000DAF8B0CF6B1EFEC50B505613FB3E9942C9 -:10D2F000C76DC14B89DB9D63F2064D4037BBFF0B09 -:10D30000E3F060BF0ADD20E73F4F07BBE505B90941 -:10D31000ED814DFB4C2E88DB2ADEF711D2C795D765 -:10D320008E635C2CE1F1B35748CB0F8B77E43689E1 -:10D33000D22A3B8B2BE37087B833B703BFF3F832A5 -:10D3400086B74ADC59BC78B30F4D3DF8BD0B1617B4 -:10D35000B7D85D6F04F8ABE3D0842CD8A7539AF804 -:10D360003D65DDFAFE5C0087E1EAB8C978F17C5CD6 -:10D370001F6FD927C687AF6CE171942DF19184742A -:10D38000CD84781F26EF4A83C24724063D2A719335 -:10D39000F57A7A0CB62F5EB2EDF97E3B781C32310D -:10D3A000FB930297861BB1F9F1A79CBEE9B9E49201 -:10D3B00049752FE5217E2E51E2C894F9565433B9B0 -:10D3C000DBB083E9857A7A2EE1F676FD385FF0717D -:10D3D0004A6A0F0C04BED370700FC73786CF253B47 -:10D3E0004F19039C3F07D5FC19FA8BC14F4433EB0F -:10D3F0008F9E6363F657BAF36ACCFE2E49DE7B61DB -:10D40000FE97EA999E71A95A2C08C6E8FF32973F09 -:10D410002DEBB61BF15C253AACC87F96D9B34E3ADA -:10D4200093213562FCC2AA721EEFF0434F1AC079F5 -:10D43000957D1C81F9AC01F8A8CE99B2CB4F40CFB5 -:10D4400091D37C43E0FCA4CC572937261B4850BD20 -:10D45000FF5200EF474EECF17709E44BFD0AEDBDBA -:10D460008E7AC9752489F6579F2778409F6D8D67FE -:10D47000DAFE277B458D3D0C6CCFB0AE668F01F791 -:10D48000D36E08B9681562B7D4A7E141CE4DDC521E -:10D490002A8674A35FFBE9153BBAC13D2B07F1084F -:10D4A000506EF7B4DC6FC1FE9C4417671D201FC08F -:10D4B0007D481B67264EE23A0076096B1FD207FCB7 -:10D4C000D62E62F5C0FB0A1BF8BDC775763FCADBD6 -:10D4D000B874E361F75E143B91334BD2DC8B49F4B3 -:10D4E0006AF349BA7B900ABFC62B7414FE63F8BB7B -:10D4F0000F89F96CFD60AFEAAD9A6F620AF184A002 -:10D500007C820DE3996D36363F65BE743EC80F28A8 -:10D5100098D87CFA8703A087D379E9E898E0BD27FB -:10D520003ABFD3BAF969F4B8FBCC5C3E4844023E3A -:10D530006233D7130EE7666D9C698040BC81B305EA -:10D54000AEB49CF693214C3241DC820B4EC13D714E -:10D550003C5DBBAE2EF57DB15AF8C708F4171D36F9 -:10D56000829FDF2CC0F19974045C032048F54600CB -:10D57000C64F6D4A3E84FAA2AFE6389E3F17571F4A -:10D58000C77203E4699A94E0CEEB328890A7D6E69E -:10D59000E5A5F5857AB3D20C1ECC1F96808E26FBAE -:10D5A000D30C8360FA79AB0F8F22643B29EB07160B -:10D5B00025F36AEFE1A3DD00AF083AED48C07B1820 -:10D5C0007073BB92A70C10DE57D86E6DC97BCD94DB -:10D5D0002F6EEFD1920F40BE0A807F078CE73DBCD3 -:10D5E0001AE27CCCBED5663AEEE4CD06A4BBD111DE -:10D5F0001B9E3F48B803F26742CAACBE18F7A55B52 -:10D60000EC3CBC5E5B7C7C3B8F479EECF77BE0AAEE -:10D61000F7702E8F892B3C18EE63379A673F6F5651 -:10D62000D3E1E666B1079DDFF3B0F7B4BDB3C03513 -:10D63000AE0F9D9F739381C5CF9AFD3F87FABD9F23 -:10D64000F01BA0CA68125E2A001FFE4B32CE47199B -:10D65000A7621F3B5755AC31045722FEBA05906FA5 -:10D66000D1FD0BEBF6AF89ED5FED29DCBF92BA532C -:10D670006CFF6AB71C30727B3C9C5BB613CF2E30BC -:10D680003DED5A3B234FA2FB92646AAA807D95C967 -:10D69000F4BCC2BE08D7DFC4842B9F5F5B70DD7E05 -:10D6A00061EB8F06825EDF60F0F426517829F54E3B -:10D6B00098599CD864ABBF0EC6297D365C01E7DF64 -:10D6C000BD17DE433F70EF86E6D0403ADFDEA3B8F9 -:10D6D00039858FBBBD612BFA33B7031EBBC175EF14 -:10D6E0005F0972323E3C187EB7C0A3E614C2C70081 -:10D6F00079FA7D37BF4791532B78414E2499A81C66 -:10D70000A5E91FCDEC1C73C62CF294D9199D0D3DD3 -:10D7100024D08B73A619F03CE5E46974FD3CFECF80 -:10D720002C69E48BB29F0A1E11529900E79C02A754 -:10D73000FF2F5ABC7926A1072D1F7DF6F452B0EBBE -:10D7400029EDB6AD209EB9AAFBD0147FF668DAE5C4 -:10D750003F6A057BA8521FF032D63981B6BB04ED73 -:10D76000601C58C79EB3CD22C0BBBDFBAAFF5EBFE5 -:10D77000828ED72B3EFDF8B2D9BD22FDF77F9A15D8 -:10D78000BF23D347BCD17B7FFF047C586C0E3BA6E4 -:10D79000D1FD2DC9BE660438AC4CB8323296DF33A9 -:10D7A000DE3CEA6FDC6A03397D30628A798FA0AF94 -:10D7B00085E917EFAE98E1013FFC532DF704983C43 -:10D7C000CBE37C37AF577121635AAAB83130587018 -:10D7D000B9990F5FE8FC0AB27649203FF3894A5EA7 -:10D7E000323BC504D0479ECA1109C6A9B9648D7CD5 -:10D7F0001B0FF67207BC0B52761886BF3B4D7B0F92 -:10D8000074D2A85312BC5730368B8A6301DEA7D17D -:10D81000968FD7DD139DEC9DE5C9E3E5D7F0FF4179 -:10D820005CE7A4ACFB3C796A392155F6817D3EFE6C -:10D830009518536F7CB4053E3E84EB1B160A9FDBA4 -:10D84000619DB3563399747378E8E1A8874BDE5F26 -:10D85000E6317BA10E1E77DFA83C9C14030EADD7EA -:10D860005DD907E4A6023F3D1CEAA12EEA4DA620A1 -:10D87000E881F55218E1584FE118E07EAB7CF53EA7 -:10D880002BF3E1FAC378FE5D0F4F3D1CA97E81FAB0 -:10D89000C3D80176B4831D0378611C40E50726FADE -:10D8A000FDED5E32791A785F6834C619DE45105690 -:10D8B000E40DA12C0FFD322EE65FA1F29CE1C35FC7 -:10D8C00098FDAA30C2E63FC6CDE265283C4EEBE0AB -:10D8D000715A87079A738B7E9E6FC03F46C4C00FF4 -:10D8E0008E078B2CFC7C934EDC70FF7FD8C7439C4B -:10D8F0008C2FC4968FA323BE967E98DEC1DEE710E0 -:10D9000088BFE5BB8BF613F2CA18FF996B76217DB1 -:10D91000E4126F12BC07014186304F655E8305DF5C -:10D920000F2D29F07ED3D824F5FB10CAF8CABEE427 -:10D9300072F8E592C0013887E612E933F5BA95FE30 -:10D940002A2C5CCFEA4EBAA39F1C8CA143A3FD29CD -:10D95000EB4B4A22217C3F4430E33D27FA5FC0D89D -:10D96000213A9E123F9A689F526941BF4E196171D8 -:10D970001221DCCF1C5E9EC3DF6922E6B8EFF29075 -:10D98000AF13A2F37BD12248F86E029FDFE5A3E636 -:10D9900000C46B3C26F8B7021C1A846303015E5472 -:10D9A0001FBB05EFE9EBCAAF9D3C5C02E5B4DE3C72 -:10D9B000ACC7D7B5506476327AFEC7F7505AF371C8 -:10D9C000664FA3E426C1FC15FCCFB132FA1E4FDC32 -:10D9D0005DF1BD34E297203D6C61F7D0EE3EF90C6D -:10D9E000EEDF1FAC771F057A2B204109DFF9716943 -:10D9F000F1B04D3CEDA33FFFF2775DA4A67480EB40 -:10DA000041CBADBD408E29FAC27B16DF6F61BD07E9 -:10DA10002D8C3F9FF60E7D17E4C2ECECC12786D01B -:10DA2000D460F6E1BB0B0F035E517866015ED1B6A0 -:10DA300007A1EB4E88574761DFE6ACD5E19599D950 -:10DA4000D36653B605EBC8592B7FA99E570BBCB8BC -:10DA50005C6C4B3F2487A9429F0AEF2D30FC3C6849 -:10DA60003105406FCB798AC547CC21FE172B057C49 -:10DA70000740A3AFCFB530BBF7DC9F5990CE69E329 -:10DA80004D65E0E7B2F0F71CFAB077775AC6AB54B1 -:10DA9000B5877D37A7221ECEE5FEC3B3023BB7CCC8 -:10DAA000B5E4B37BBF1BE566353EEAC78FDBAFAE9F -:10DAB000DD4181D9490ECA6E8C0753DA5DB1303928 -:10DAC000DE6CEEBDC97093FBE0F3CC1DFA4B49D17F -:10DAD000FC398B65462CBD40E9AFE55CDE729E30BB -:10DAE000AE39DC357A9E3094CB47B4E709F9C8BF2C -:10DAF000729EB03F2D1F594DDBBF6DF3A55A617C5F -:10DB0000C9D717E0FE1CD70FA926D3576D974EB57E -:10DB100032FD3075790E393338FA3E9B20D199E0C9 -:10DB2000FB1AFE729037D20C82FC9FF2998762C575 -:10DB30000525DA733A5B8746E9EF2983BBAA92C5CC -:10DB40002BA0BFD7B77C36EA7353971761DA78FA00 -:10DB5000C62D4087391C9EB75A995E5A9AC0E84331 -:10DB600010FCB7427FF55ED10EFED485B522F7D703 -:10DB7000B177ADA64E1053E0FB19B38CE7C08376A6 -:10DB8000B6AF67087B9F26E7B8C95743D31B247BF2 -:10DB90009C55A5EFDD2079982769A9E8BF56EE2BA3 -:10DBA0009E21196CBE6B997FA0796D06C6311F94BA -:10DBB000B5F6A85156A60F8FB2B2FD9DCDDFB103C9 -:10DBC0007C82F724664B6EB40FCE8E18D93B6A74F4 -:10DBD0001E886F166D3FF956163F91CFE13F1BE44B -:10DBE000E460A8A7EF4762FD73BCD5C3FD4D4BEEC3 -:10DBF0005880D30DE21D6745BEEE96003E39430EB8 -:10DC00009F04FED6363F0F08C0CF4B6F08A1EE60D1 -:10DC10002FAB91F17CD6C0F5FBCB35875267D3741F -:10DC2000F1AEF71D700EFC9E95E95397A57A7C77AF -:10DC300062D16B22DE9BA6689AFA3D6C3F6718BBE7 -:10DC4000F7C1EE2D2872EE8EAF7A76F5613D76FF44 -:10DC500040D1AF72CD8120CCEF60B98876292A07F8 -:10DC600035EF90E4D7B07B097ABDEB11ABCCE3354F -:10DC7000D93E2E73B171E2D16D4EC44A822ABACD1B -:10DC800091DC12CC3F27E220410AF7CB17B66E9801 -:10DC900048F13C9026E3398F1E7F0EA3DEA7F8C122 -:10DCA00003344FC739CCD773A466EA34785FE52DC7 -:10DCB00052B67A00AD9317F6273322A6A7B4615166 -:10DCC000BD2BDFA5D5F7F4FA6041DDFAD5F0164B90 -:10DCD000037C80F1CD268C236EA5279AEF8EA91F99 -:10DCE00012B21EF1F08ED77E391EDE9FB8E3A2C1BC -:10DCF00005F39B6C7533FB62CD357C1FA18484A634 -:10DD00004379498DE80AD1564748CD6D201715391A -:10DD1000AEC02574E390D903FCDE22BA56C23ACDD8 -:10DD2000F7D820CE626463FF64906707CD32DA21B2 -:10DD3000732CBD6D7354F87C3099BD1B7024B9A74A -:10DD4000F6BB79C36D20D7F6F0B8B5C3E7EEB7855B -:10DD5000B1DED464D4CB1439AED357157BD7D8DE1B -:10DD6000628BBD4BADE71271D3B3165A3EFE561906 -:10DD7000EFBDE58599DFB4951CBFE15FCDCF239A58 -:10DD8000EF055C3F6825D7A370D6E8A16F58B95E50 -:10DD9000E9260340AF0CDDD8B010EFCBD625B8563E -:10DDA000A23D81E92D8D678B374C80EFC744661FFC -:10DDB000B921221D1DDCBFB07B5845BF5422E0BEF7 -:10DDC0005D1F74F5CA9B745FAE7F62F504E0B354C7 -:10DDD0007D5B6CBF5890C329D499D9D9039DD93B99 -:10DDE00018ECDC7957F4DCF90EF001784706C443EF -:10DDF000DAA65346381F5FA6AA38E2175D34E0D78B -:10DE00005DDEB0A8BE7F738AF3DFC956EFFBC01F8B -:10DE10000324A70B55424891D59B0D71E04D938982 -:10DE20006B2B5DCFBE0B39824CF3A3B66578049A99 -:10DE3000DF0D8A25F0CDD7C420C493EC867B6BB46C -:10DE4000DF05F595C60C3A6EA04644BBFE026E1F78 -:10DE5000BF2007D21355F85199C0F8C905D9FF0B57 -:10DE6000E8E7C2C726B4775FF8C41A53AECE48605D -:10DE70007CF74D2ECF3213DC980F35EC7DAB339D04 -:10DE80005728E21A04702FDE7155847793EEE4FA76 -:10DE900057E1B3F5ABC12E33715393047CC71774AC -:10DEA000E583489DB2C323831C9AB6D327839A3D4A -:10DEB000BDA60CE39066D4561E81FCFDA16ACCF78A -:10DEC0004FF047002E77AD6D3A04E8D2AB9248F898 -:10DED0008ECF674CAF4AE5F3E811F11C7422366728 -:10DEE0001B00BF5BC67FA25E02D57DE26A363EEDB7 -:10DEF000CF9040D77D5759532EC8B5F4E5ACBF74C9 -:10DF000072A0DCE98EF63BFA46BDA0B617BCF898C5 -:10DF1000AD88F15B06F7F4C73B6FC173197159F116 -:10DF20005D454E4F398FDBD00F70FD07CC0F707DF4 -:10DF300010D3A7AFFFC0160CC4D0A7A378163231F8 -:10DF4000FC52F08D9859DE6B067CFBFEF36556A003 -:10DF50009B649FDBA88E3FCCD950D8EF6DE8DF6281 -:10DF600042BB5CCB78EBD97810880B78ADC8B1D9BF -:10DF70003AFF4B940F30BAA05D04615C2525C24A7C -:10DF80001751E749280DE6939EC0F85C95D13D13E3 -:10DF9000C6ABB29A5C30DE6C736F23F0AD16FB2615 -:10DFA0008F4F1BC9F5CB7D170E26C1BE5F1F549E38 -:10DFB0000E7A73C8F073E4536DE1DD4FACDEE10916 -:10DFC00038CF00EAF94AFD3DE7ACFD414EBE69603D -:10DFD000714FC433AB3BAC5769378DA7BBB99F4E6C -:10DFE000A193E47AE2DDD21F41E5DDAD82C7A4044E -:10DFF000468F4ABA5B7607189DB1B8CEDDF690B968 -:10E0000027D0F39E9E984FF6119B07E2586A7B7BC0 -:10E01000C05F43F9C0A404955DEA4ECE1F92EB9B0E -:10E02000902EDB7B1E18C6E11B92AA397D11E453AA -:10E03000405F8C7F87BAF0F778D0FF077C83EF4F83 -:10E0400027210DE3C1719F95752773BEB08CD33D19 -:10E05000C001CA4B795E295FCCE1952FF677AAE320 -:10E06000C75AC9F5E56904F4C7FCE59D312DE5F310 -:10E070005D605E8FF6D205C9EBD14E9AECADC474EB -:10E08000415E257E4FDB340BF163C1C6D8EF8C1D9A -:10E09000E57AD9E50B06F69E94C1DA19F04F297F8F -:10E0A000C72A737EE97F1CF0E162CD86E707BAA339 -:10E0B00076DFEB96CA89F703FE6F135DE5B03F5537 -:10E0C000F9823B065EA9E107F02AADFA1CFDA62500 -:10E0D00024CCFCA6DC2FAAF84F83558C9F5EE4FA73 -:10E0E000599155AB57562618383FAD1F7F3B1D3F02 -:10E0F000D4DC2B13FC4121292C4A6CFFD06E047C0C -:10E10000D885F8FE74FA638047821DF51EE0ABBB2C -:10E1100054F8B170E7968ACEF49F77DD60F77742C6 -:10E1200012B1A9F9B782270A3FD6AF6F2BC75F0597 -:10E130000F4746E5D4D6046E1FED49FB2D59DF8C01 -:10E14000F6D137147A067C037A5EABE0DB20037BE2 -:10E15000374D4BC7C3BF23FEBEE79917D2D1FE9000 -:10E1600045E916DE5903BA8E8117BF6DE103FEBD86 -:10E170000931E4C145C1FF8BA49ED1F67BCE8DEB66 -:10E18000375BD5CFCF389E5F97FDDD5D31E01585DC -:10E190002BE90CF850447706E04036092E75DC7BFD -:10E1A000F22666E7AFE7F055BED7EBE03D3AFABEA0 -:10E1B0005C3D8377931144765A90E905C430AE33C1 -:10E1C000C8F90556EF38B4B7AC37107C4F55C84185 -:10E1D0007C4FAE7AEEDC574320B5F440BF09711B8B -:10E1E000008F163CE5C6F3E0CA972C8897E71258D3 -:10E1F0009CC4CA2A99E1A75C89F875F193E2EEE024 -:10E20000770950B9DE3B86DCF9AD4E9EBFCAE5A862 -:10E2100082773DD631BCAB92BCD644155E6E27DE0C -:10E220004CE6EF6772251E3E46F1C83548C1A3593A -:10E23000F47B8FB56111F68BEEE335A0DF9EEB9A90 -:10E24000909FC5DB47C5BFA6ECA7C2E787DBB4F745 -:10E25000FA641B5B4F729C7880A89CD3F26578FFB0 -:10E26000CF36544B0F70E552594F23874B3CBA9829 -:10E270006363EF3E57FC75C38340CF15EBAD9E95AE -:10E2800024EAA751FCA7CA3C3ADA048D3F47EF675E -:10E290006934FB536D2ABC023FA01BF93DF3AB2848 -:10E2A000BF8760C93616E7B4078A808F9CB506D54C -:10E2B000F7776F958857CAA470B565E0BA6F0516F1 -:10E2C00042F3C9CB8DA4173D775D1F71E0B083D6B3 -:10E2D0009FD0142EBC9D2E718F313C6D12D87D893C -:10E2E000B718F40CB4D103FE37B07E89AB5A33CFE4 -:10E2F000811CDECAFE54FC754E5A2C3F8002C77842 -:10E30000FB3287C3C3C9CBF5F46FE1E59FB69B7EB3 -:10E31000034EA0DFBB48A01CE22FE8011DE3D65A44 -:10E32000E8971ED8A1FF029B967E957C0CFA2DB033 -:10E33000A9E9371266F4CBE9D459257B63E92DD3DB -:10E340006DEC9CECACCACF0679E4F461D839D00D01 -:10E35000D2FB024AEF40C701A0DB8E004F86673D2B -:10E36000BC9518EFD8A38AE9E3D713D97A17DCE96B -:10E370003D00EF252FA0E7018156ADE4F41E1FEE0E -:10E3800021A7C0E49B13F8CC5DA3C2B92087DD6050 -:10E39000EFE888BFFA023765F428120CD17D77DFE9 -:10E3A000208C7F7CF2C2838F01DF586FC37B4F8A42 -:10E3B0005C4A4DF017DB86C6A76B8A975EB0572D77 -:10E3C000F9C2C6CE8D71FCE2A3971B48AF24C4F3FB -:10E3D000A56A3C1FED6B1201AE4909FE34399190DC -:10E3E000D5B69C31E66E747D1954EFA5F9729A5F2B -:10E3F00007F6B70E61C2F315B64EDFDE5EB77A9D43 -:10E40000F72DB0D7BD94E05D09EB82380048EFEA04 -:10E41000D224227F6BA75FBF14EC77743DA7EFE98E -:10E42000F7D22CFA75F67DBE0A2855ECC9C3B93D62 -:10E43000B9B46E10DA995576E50DB0FE7876E5B68A -:10E44000C67570BAA7F88DE73F47569308FC51E1AF -:10E450002B5B6C1D383E8709BCD7AED017F025D09A -:10E460007795F802B03BDAD15F11447C85BC333339 -:10E47000CA6FD6551A62C63F55DB6C1A7A51F82915 -:10E48000A9FBC7EB8F29EF2C32FE5AADE6AF5595AD -:10E49000A75399FECADE2D5BCA6D001B567AFED8C3 -:10E4A0002B397AEF7984C91880F716E981CEED52BD -:10E4B000C54F0A7542C80E71795FD222C0A32F0DD5 -:10E4C000986EF80F5F4106D8594E1A90FF96F07B70 -:10E4D0004D59DD09BEC353CBEDA3D9676C5EF0FF88 -:10E4E000370A66E49F8DA7AC0190AB8D7603DACF37 -:10E4F0000FEF33215D5CEB65E5F68FA0C64EA2F809 -:10E5000073AE1D9B9304FCFF79EED77CFEBE5BD0FF -:10E510006EA9D8732589C2BC0384E9B07B9939CB35 -:10E520003BA3BD55B1EFA69A67092C8888F52F99B2 -:10E53000D9BA5225BF00F6F12D6DC43F9CB1191513 -:10E540003DF82F00DFD227C24638E72A7AB022AF43 -:10E55000BB37F438007110DD0B98396D4B83C10067 -:10E56000EBDB42D12831A3355EB5E04FEB38838B2E -:10E570001AB9B486C519B4E479BB5FF03883D167A2 -:10E580004FBF8AEFE999FD1F6BDAE5A75863BDD34A -:10E590003D7DF963D83E1EDE4F37B0F779F4DF13C7 -:10E5A000EC9C6F4B655DF07ED4DFBE9FE08E61C753 -:10E5B00099FED7D9F87B24F476B7E8F8FFE1C9A330 -:10E5C000FB26DBB9DF2F9DA4835FAD2D3FA67EDE4A -:10E5D00027647FB758F2491F67A78CD7BA3D3B978E -:10E5E000B5D43312FF2E1BEB3753D5EF283BD37F27 -:10E5F000A60B04E3DFC95704E5B4822714EEDDED72 -:10E60000B47CD83B67065BD1CFD324021FB876B267 -:10E610005757F4AFC739872AF321C4DF3B561CC7CD -:10E6200074788727C6FA46D8997C9E2E333F85702A -:10E630005F6FB40B4CB7980475DC7E6F65BF74FEDA -:10E64000D88396E178BF11ECF9B1E0A7F7D3F606CD -:10E650001FEA5006174F0C7C52FC820A9C2BB2BD5D -:10E66000D912B3A7E13DB5642FE39FC90504FD6B43 -:10E67000C3052FC263BC3D03E7B785C7C75D3BC673 -:10E68000E2598765BBF1F73C51393116E03A9A847B -:10E690005F35A8E2AD143CA97885CA638DBD31A071 -:10E6A000394F27723EEC82F72654F5DC4F000F8875 -:10E6B000CA81AEABCD9A7CFA321791547222D19BAB -:10E6C000A6C977F5B9AC708EEA5AE0D6B453F04ECD -:10E6D00089F7C39F6458B70BDF3DEAC0E7335CF0AE -:10E6E00023DE005F033BF202BE9F74BDF371BD05E4 -:10E6F000E16B6ABC51D6DBD6BA4EAF70232F3CBB60 -:10E7000082CE97F28539EB32CAD310EE2E02E78B18 -:10E71000732BCCF8FD61DE3EF1D959788F3671B597 -:10E720001BEDB889DEB2B7E09E4F62991BEF15CCA6 -:10E73000AD1404B0F7503E83ED36AF7061AAECB76C -:10E740008B960BB6E83BE3F1E4D75A7BBBE5D75A8F -:10E750007B0CF965307BDE06BFFFE23AD10D78B164 -:10E76000AAB003DAFD3654B3FB6E87EA58DCDD86C7 -:10E77000E94C8E28E35E79CD89F2E28AF2FB54BC43 -:10E780005FA64EC178802F5381CF6EB3F99FB7AB90 -:10E79000F8E586BAA116FEFEB246FED01F17DC7F52 -:10E7A00040DF9C007AD2A0B5524FA4FB1761BE6433 -:10E7B0005E78B0A527E0A9FF7D78A7F4DAC9CFD2AB -:10E7C00061FF143F9FE20754C651FC8482E0DF6E74 -:10E7D00057F1A9D67E40ADFF4A7498314E374B644D -:10E7E00071BA2A394B601F57813E48F16CD5292BED -:10E7F000C263D5578CDEE83C5F85710EDB8721FE56 -:10E8000028F294CE73E0BB243ACF524353BAFA9D18 -:10E8100052D53CEB6E3E4F5D1C2B9F97689770BEA8 -:10E820008DC4EA8179D51A3D27FD2067AF58D19E66 -:10E83000D7E8BDC302EFCD36923B2CF00E6DB5CDBF -:10E840007F14F643ECD6E4003DFB50DDE0BE30DF44 -:10E8500078FED8265BCE31A84FD7F7474847BBC2D2 -:10E86000D77EED8EAEEF267EDCF7A1FE3758FF5F38 -:10E87000BEC9FA4BE1F767300339EA5302E7BB7AC6 -:10E88000BC12EA0E7C01F143947E306E33904E82CE -:10E89000AB289C2A0630FC227309FFFD395A3CD86C -:10E8A00066F335C07C14BABB097C9A609D1B6DBEB3 -:10E8B0006648611E700F84F299CFB8BC7AD568881B -:10E8C000EA5149498C5F3525128CAFD1FBC913ED54 -:10E8D00053FE01ED52FBF80557FF6F84E792E3A664 -:10E8E000F00B615C84720F7531F87321BEAB466E1C -:10E8F000D0FE9E1D2D1CAA6D3E8703FC3839EC3DD1 -:10E9000039C02B78FFED26F0E8E04078F85320B5C9 -:10E91000CB145F002859B3D200CE8D666F2AF895CC -:10E920007697333834BEC3E0B0E7AC01F1F839D2A2 -:10E930000FE92ED3D0FC20F44FF9477758D7A8A67B -:10E940006A01CEBF1D8BDC06E0B35D9A3CA2E1E616 -:10E9500078DBD381FCDE7F8B83EDC352D887C1C7C0 -:10E96000987DE62678DBCF91F28DE03ED891D27E7D -:10E97000FE42F16AB8438557ED8D9B12F8FD497D43 -:10E980007FF43C84FE83037B4CC88F4A76B3FBA2A2 -:10E9900025FBCFE3B9BB64AF0991326FAF85DD7B57 -:10E9A000A861E557B263C70178E1978F817CA87EA3 -:10E9B000C4A395BB0166AFF436BB7A8951BF6AD256 -:10E9C00004768F60158F4752FCAB0E8E6749DD7C55 -:10E9D0005E902B49F904EF13386C2CAEB0F57D0135 -:10E9E00046B729BC9DCBE51600DEFAFB0329F09E55 -:10E9F00034F38F23BE8806AB07E47E5281AE9EAD12 -:10EA000000FDAF29BAFB06F31DDCFF6A2469C0478D -:10EA1000AA2DB1EF097DE650F43A2B9EEB243EAFD0 -:10EA2000C376237BE7C56EC6752F49244985989721 -:10EA3000509EEBFB69C12BAF41730F25A9C0AA798A -:10EA40006721C5D74193EF38A3B3A67E277F0F4D2B -:10EA50007997A27E9AF26E65999A7CF7E57768EAD3 -:10EA600067508453E77BAE1DA7A9DFBB728A267F60 -:10EA7000EBC6FB35F5FB06676BCA6FDB51AC291F94 -:10EA800050BD4493BFBDF6314D7D318E9EBD87C3D1 -:10EA90005954F46CFB103FDE3BB29B0593EA3CF704 -:10EAA0002CAF97ED284803FFF76AFB9834386F1EA8 -:10EAB0004E1CE60CC7E85749BFED396CB743D0D8B8 -:10EAC0005773B8FDECCA41CA45E0F7591CA27880DB -:10EAD000BFBFC9BFDBC1F5A9596EA8CFDFB5903C58 -:10EAE000B88EE90E33DAC5F4FD3FEB706BEC758A36 -:10EAF0005E2F1A3CAE42213EBC3E6B27BCF67E47E1 -:10EB0000F03AA18B1752CE6FFA76571DCC7E4AF998 -:10EB1000ED07C00F5BCE69A449F4E139EDB32B01D9 -:10EB200002FC94A0DE124F0F50C61704DF5FA11F36 -:10EB30003D3FF52D9FC7CE99062FDED78A777EBB46 -:10EB4000CAD71F3DBFE5CFC0FD48346AE0F4B71611 -:10EB50003AF76ACE6FAB1387E1F96DB5EC4D6BCF29 -:10EB6000F9ED6FC0938602DCD9BEB6ECA7D1E3669F -:10EB7000F73CB5FA4B6B7D9BCA3FBACE0DA0C709D7 -:10EB8000A0972531FD7B377B0F4019B71DFAB6E4FE -:10EB90006C87BE6D229EB59288FB657532FD7AA9A1 -:10EBA00045FC56FA7592F31BC8BFF7640FC6FFBF4A -:10EBB000374124F02ECBB582E1788F3A1E3E7EC0DD -:10EBC000ED2FEF39197CDBB25FBCB7A2E8A6F72FB7 -:10EBD000DE1BCBE22CA7E8DEDF1DE164783095A7D1 -:10EBE00014406887B8FCBA1DE3E52F8FFB107F6FD8 -:10EBF000D2E59AC14302F87BC23CCB20DE2660B34B -:10EC0000A37D6FCAD8A143CAED2A3CE2BF8F2CF77F -:10EC10008D771C60BF99B2AB674AC0161F7FA6F202 -:10EC2000F511297C0BC653BF79117F5FCD943DBD93 -:10EC300053987D511B9FA6B7FB4C595E82F8A6E402 -:10EC4000174708C6A3B5E42576DF787144C2F8B546 -:10EC50006ECE96F8F6F49BBD9BD65E78EABF2BF09D -:10EC60007C6FEC45766FDE125BDF58E1143476245E -:10EC7000FDBD9578F731E6F1FEAF158CC0FBF7537B -:10EC80008CEEDEEDB1532970AABF713E01F8C27E51 -:10EC9000B80F13A3FF879C8C9FEDF77E920466E963 -:10ECA0006C73532EE07F36B783C788D75F0A7434FE -:10ECB0003A52F09DC4EB3FE1D4C6EB1738195FD14F -:10ECC000C7EBB775DF68B231B67C9BC1E14EE1F7A7 -:10ECD00021D0EBD2CD32C6FBCDA7730880FD6D8B62 -:10ECE0008CF6B7F76F9808F841CE6F927F09F169FB -:10ECF000459B7B6E7E96E68BC69AD06F337F0B7BEF -:10ED000087848CB504C12F5BB4E5D1547857FC538C -:10ED10004AB78BA8D2347FF373180FF3FED9A7310B -:10ED2000FEFA22D033FD5EF4D593D301FE7B8C95A1 -:10ED3000B70DA2E9A29D82E6FE447195459357E284 -:10ED4000FE94FD2342F45E859BCA91979CDAFB53A7 -:10ED500083A3FEAE979CE8EF0A639C7CC904767F90 -:10ED6000EAD039767E3FD28BC50586C6DE5B388811 -:10ED7000AE636C0A7BBF451F4748C03906EFABF056 -:10ED800038DFB11F4B2DF75C58B9D796AFBA3FF0BB -:10ED9000D68A32DC97B13F637693B1192CEE3D6E83 -:10EDA0007C615AAB7B007D406EB68A2B8CDEEF39DE -:10EDB0001D0B6F0EE9E8FAD039164738EF187B3F84 -:10EDC000AB2DBEF9019FF7FB67FB3DF06B0A8FF798 -:10EDD0000B18177FFFC6DD6BF07D1A9F40209EF356 -:10EDE000FC8DD8F7C8529C8ADEE46FB96F03FB3301 -:10EDF000B560414B1EC8F21EDF239AFB38EDE737A2 -:10EE000037E7274F3AD93D4A3D7FD7E3FDFF29FE3B -:10EE10003E65EC9174B89F4FD397F09EFE2EC61FAF -:10EE2000F574AEE7E733747C30CAC70D9A78E319FE -:10EE3000C00786AAF9B911F9FCFF00D1E7EDCB00B4 -:10EE4000800000001F8B080000000000000BDD7D2B -:10EE5000797C54D5F5F87DF3DE2C496692C96412AD -:10EE6000B2336189A088C3BE457D098B51080EB8B5 -:10EE7000A1824E02216C21816A456BBF1948C08076 -:10EE800060635D8A8A76A041D1A20D8835D6A01331 -:10EE9000A5086A357EC5AFD62A0D82088812412D95 -:10EEA0006DA5FCCE39F7DECCBCC984A5B5FFFCE26C -:10EEB000A7BDDC77F7B39F73970914319DB9190B80 -:10EEC0000CD782B50A631BED7EB33395B1A1F66012 -:10EED0004A2163ACCEB921C13F80B1941476ABCF47 -:10EEE000CED869FCBB3C9C76D88BE2B0FEAFE2FC8E -:10EEF00076E730A8F75666114B646CC8DB4D8A1F65 -:10EF0000EA1F53D8B4A618ED4EC5991883FA5BCD05 -:10EF1000BC7C2BD61B102ECF74169E8A837EB7D94D -:10EF200020857A8CD99C07FAC1BC988925A98C9533 -:10EF300028FE4C1CB7D2D67E5F29942EDCFDBD0581 -:10EF40008AD843167FBA3614D69369F16ECCEB3A61 -:10EF50006E1F271F376D4911DB3F8431AB8D05E2F2 -:10EF60000633A6682C601E8CE3F8979AA0BD368DF8 -:10EF7000B155008F3D3037ACCFFAA59B581A633F8F -:10EF8000B131FA0B14319C0C0B7C161FAC85714E01 -:10EF900031FD425CFFBF987E11CEEB13A60FC0BCC3 -:10EFA0001CB74EAC533331FF9618F028772A7C1CDF -:10EFB000E6CBF739205FC4FC91F090A9CFA951BDF1 -:10EFC000C2876FCC6D87F2CFF7DD94CB20DDF1D017 -:10EFD00088A4F618F565FA8B9A6AEF38687A6F8D0F -:10EFE0009FD224C6749CCF9A9A39DE717D187342E1 -:10EFF0001EE7556EF1E52747F433C499CC18AC27CA -:10F0000071D4D6B65E40270756AB4EC503293315DB -:10F0100063FBFDC1A4E26D03783BB7A11D9FA70A66 -:10F02000E4C57AC3BAEDDA3FDA05EC4E335C2FA3C0 -:10F030007EBB5B67B9C09385796DD8DEF2D9553652 -:10F04000D60BFA537427E6253D8C8211901EEEC133 -:10F050004FA3605CC57FAB93DAE929B2FC741E8EC6 -:10F060005F4C79393ECB763196D13DBC98A2CFC268 -:10F070007E0E31BD1CD3664BE02227ACB7399ECD46 -:10F080008945CFF3117FB09EFE4E412FCCEE3C78E8 -:10F0900091180FE6F76482BE10FB3966F355637A68 -:10F0A000595647AD8A7413E714F5DB19E21DCA6F90 -:10F0B000C77296DECEAE06785F06935D05D9970FD0 -:10F0C0007DC63C00A7C48E03CC03E32722FE62C0AA -:10F0D0002D2199C3ED0F8C15C7E63B4E670131CF4B -:10F0E00046E017933BCC2F4F41BB2D0390EFFC82A2 -:10F0F000EFF4AB503E34FED2A5AC82F25EBAC784C8 -:10F10000F4E16E637A10E121E02EFBFFC469A17E79 -:10F11000910F9533F0E143E7C9878DBF9C648AC3A3 -:10F1200079DEC5BC7D3D58EE596683FC138B9DDEB0 -:10F130005590EFBD1A080DEAE72C89DFA042FDA02B -:10F14000E0A79E0FB26571503B6F5D8786F261D27A -:10F15000DD6D9A0DEAE7D5B56B289F5EBAEBD15C01 -:10F16000A4ABC39F5FA53AB0FF6F64FF0020E0F738 -:10F17000314E8E4336B2B427E2A709E79D1AC15734 -:10F18000F1FEDF22BF5F56DD31D60AD57297300D12 -:10F19000E5E561C5FFEB94DED86FFCB4E000442FD9 -:10F1A000A7B7970E1EE95F06F9ED92DF95A24C9680 -:10F1B000CE5841A399E059D0F8D02D08EF82C62B44 -:10F1C0003405AA3CA185140DD759AD6B01C8BFEB1E -:10F1D00034D3F8873F9FD753C1F9FED9CAFAC68006 -:10F1E000EF9BA2FF2681E7972DB1E97667A7DCE1C7 -:10F1F000FC34862952BEEE443A04F99AD81BE0B199 -:10F20000F0CEE3245F9F727A68FC27B4A69D993400 -:10F210002FE60DC0A7799BDE23792FC791F5E66F06 -:10F220005EBF02EB65DFE61CA47AB05D7B1CD2CF2B -:10F23000F7711C5FDFDF191F5CAA10FD0FF25D1C68 -:10F24000830F59C86A4A270CD878AADB4C2301AF30 -:10F250001D1D8528F7A0CB65C89757257B681DB273 -:10F26000DDFA0E673CF2CBD9F4C14181CF73A5C35F -:10F270003792B9DC0A74D59B47115EE7A1373B840E -:10F28000DE3CF16FE94DA12FA5FE94E54A32C7E7B8 -:10F290003DCE6EF5A6923CACABDE74B3E0BD03612F -:10F2A0003DECA8C9BB91751D3720E4DBD178DD9A10 -:10F2B0000C6981C27C386EE2D1CF98122187160B7F -:10F2C000BEDE2AE9C0C56E9D12631D95A23FD3F430 -:10F2D0000E4B3BF6D3A210FD775DAF85EA815CEC67 -:10F2E00081F3BEAC27C84DA5ABDC8C818F5CAC9F95 -:10F2F000F5B6FE3A12C9E8E4C60440FF99F0D10B16 -:10F30000EBFF2A4EEF8DEB93F01F7C5ABDD537A053 -:10F310002BFC2F1470BECCA1F7C7767F137CD61DB3 -:10F320005E4625737BE6AA648E97AD0E512FCE58AC -:10F330006F6632874B45B2912F23F0372A3986DD2D -:10F3400023E5F0D1785F0196FFE1D0D604A42389AC -:10F3500027297FA2F115E6B3A5341EC0793CB68FEC -:10F36000D63FB27DB41E0AB70FD0BCD7231D21BF34 -:10F37000211D79B89E583F203C3F49E77EB1CE1F02 -:10F38000E2F52908BFE8793A8F9A9433CD33B9C3AF -:10F39000AD20FF27EB4E4A5F3E6452705ECE0E4DAD -:10F3A000C17939857E8CD683202E045C793F6F0825 -:10F3B000B9B1E2AB99E988E71585FEF46AA83FD9AF -:10F3C000A1CF4238DCE3D4CB717EA50E7D36E64F6B -:10F3D000C571FE1F95ACCFC1EFC9C28E8A9E67B5BD -:10F3E000C01FC0B30AEB258E6301D487979FB40773 -:10F3F00041C4020860DEA01F12756711EAB1C4752E -:10F40000CC8B749A92D0D16A857CC743CCBB01F275 -:10F41000F9018FC98AFAED367D19A62BBE52C9EEC5 -:10F420005C51C882CBA81F6E87B2BA5E41D2DFC0E2 -:10F430006F91F4BA4CC079593297736087D42473B2 -:10F440007E5A9A1C6187483EEACEAE88E0C3FAF342 -:10F45000E4C35FE078E7C1870F083E7CF05CF8F01A -:10F46000B1301F3E8AF5CFC687CF083E7CE32C7CA7 -:10F47000B85BC0ED5D513F061F3E138B0FDD821E52 -:10F4800024BD231FA2BE0F2577CACFDFC5A2F77305 -:10F49000E0CBE6E473B00B3BFB3B47FAEFCEFE1B41 -:10F4A000E33AB3FDB7C7EEA4F5487E067E793399FB -:10F4B000F48EFE16C205F8E56DCE2FB1F9AB53DF21 -:10F4C000747039C1584302D28F9CE7E702AF00AF96 -:10F4D0000FB01FC967D24F91F0EBA40761F71E155B -:10F4E0006962C7670CE502C06D6F24BD3E25F82533 -:10F4F000309211BF8047558476E54B47C18E44ABAF -:10F50000CFC5E75BB0B6ED756475A635244C757450 -:10F510000FA72217B773BA83138C7F2C963C6D41CB -:10F52000BCD9BBDAF3D1F8FA44ACC7E952CE88AF04 -:10F53000B3CD43C20FE77109CDC3635A15A1E7CD1F -:10F540002E45F2B7E682F4F2711D2AA3798512C026 -:10F5500085EA94A72C1BDA0FEDDADE1E6E6F77C1F9 -:10F560003C2FD7A1FD80707B189FE45DEFDB409EB0 -:10F57000919DAC9B503FADC8E3F4104DF78D683FB3 -:10F580000C88C0574326E1EB3E9B3F13FB6FD43CF6 -:10F5900026B4EB1AEB9D4A80F0581D8FF463B7EB4D -:10F5A00044B731E490C7757E72A88F8BCBA1BEAEF5 -:10F5B000739043035C9D72E822ACEF3C8B1C1A23D2 -:10F5C000EA17B8B87CE94E0E5D26EA1509F8C69030 -:10F5D00043635C31ECB96D369DFA8DC1A79763FD2D -:10F5E0004CA7AEBBB85E2B7445E835683716F3F709 -:10F5F00089F6AB1B4CFDC87E66F1DE587E86CF6572 -:10F6000037D829970AFF81B5FCF3F7770D67AC0A65 -:10F610008BF83C7DAED4B03FD1D8F0591AE21FFE32 -:10F620000C7195079679DFED83787B476568873E97 -:10F63000F03FED168477737CE240764978DCAA7F50 -:10F640000041A6005EFE61A254E27161CBD2210CA2 -:10F65000FC88C2FD3FE4A25D796CDF3F283ED261A9 -:10F660002FF3E3F83BB6F338C989B767A6A07D2E20 -:10F67000C75F8CF882798D5707348560BDC777598D -:10F68000BCA86F55E6F95501CCA76A979905494E74 -:10F69000311BD637F3E932F3AE156D6A22E6B58039 -:10F6A000886F28A7C99FF12421DD9A77A90CF990CA -:10F6B000B9797980D9969E067F3369A4897922E247 -:10F6C00021C97A3CF344C427528A5D867CAA2FD391 -:10F6D00050BFC7B45E86F20CFF8586F2AC39830D4D -:10F6E000F99CEAD186FA3DC1DF89CCE705AE32D478 -:10F6F000EF5D3FD590EFDB7093A1FE056BCB0CE582 -:10F70000FD83F30CE515BB9FB7A05F7DD1A6C58631 -:10F71000EF1737DD6568070069EB0374328B71F80A -:10F720005FD2BCCC507F56FBBC4948B78342AB8C00 -:10F73000ED1ACC07383C030CE1F905F35B90CE34AD -:10F74000D6B1330BE0BE30A87843506D6E735E6F58 -:10F75000E4872FDF2CDEA50C8479ADE5ED643F73E3 -:10F7600083C6FC7C7533F14F349EAB58AF24CF5029 -:10F77000A40395059530DEE76F32B66718EF827601 -:10F78000F3C57AA2E9E20B56FD7001D247406FEB58 -:10F7900093165EB799350D0FE17741274E412772D9 -:10F7A000FD72FE72DD4EF80FCB41E15B90CE663705 -:10F7B0002BEC51A5EBFAE6B4DCBF222BC63A190BB1 -:10F7C0005AD0DF8E9EFF0E97C37D3001FE91CB7223 -:10F7D000316EC5BAF0879DE4F1F1756AD00A74AD57 -:10F7E00006FA45F18771FDD1703C5F7EF10838580B -:10F7F000D38DFC12E7898FA6B7E121D615AE09FD9E -:10F800008C7C24E128E1EAF066C6A42B0FFCC7E15A -:10F81000ABB31F13BE1D08DF8BC2F03D66F39F40E4 -:10F82000397CE2A36F55A23B7FFB10D463DDE9A5D1 -:10F830006447D1DF44FD5CAC5F9500723109FAF991 -:10F84000EC877CE4B74EB9BCA4CC3B0EE4A2A2F892 -:10F85000594A6AF87B9BAE3A8602BEE637AB5ED465 -:10F86000C3C7347BBD72092DD3E34C43252DF1C6AC -:10F87000F128F1A6B4BCFE7705E0056DFC168CBF3F -:10F88000167B6D384FC6A6539C5301F7E67402E908 -:10F89000D9C414D2BF3AA3F8DF71E6AD85FE6A1D64 -:10F8A000BFBFE82CF110570AD90FFEB478B43F3A25 -:10F8B000DA4F3C87DD6B6D4E1C678ADF4FEB198199 -:10F8C0001304BB9A39014E11F12268978DE34E79EA -:10F8D000FC9709680FBF74E0B84AFAE51337D9C33B -:10F8E0004F315F7F940F5DEDEB00E93D69AF837FA2 -:10F8F000D43B85DBDB7D5322FDA34EBBFACCFD80E0 -:10F90000DDD10FED99EE52E53595F4698712EFDD03 -:10F9100010439F8E4C31EAF94BC3F1B8912911FA8B -:10F9200073E1ED2776E23C00DE63709E0E07D8356A -:10F93000CA39D93597633FBF4A4824BAEED8AD06D5 -:10F940002F8006C76D9E2417DA9142CF2A1AE8103D -:10F9500057843F6B730DD0866079FF2416C34F9197 -:10F960006911D64B09E75F8B33FAA32B06F3794D68 -:10F9700011EB5C29ECA7F2146EE754611C2E251CD8 -:10F9800087AB9AC6E3CC0F45C52FCB531C547FA53C -:10F99000BDA81CD7BF224F21BB6985A218F6915282 -:10F9A000530ACB71BDB78AFECBA16F1CF7A95E7C51 -:10F9B0005EEE28FF3D0FEB0FC394F70B9CD41FE9BD -:10F9C000CFA2AA31E1392F45C4B1E399B4BF896F01 -:10F9D000260ABE9920E4E5957D415E1273E993C63F -:10F9E00043F93851CED4757BAC503EF10233433AE3 -:10F9F0001B877209E5BCD3FC597BBFB09C9FD0AF7D -:10FA00007A078A872BD2E17B843C2966BE2CA483AB -:10FA10002B3DC6EF13F74C388CFC3A9169D40F7D1F -:10FA2000CFE3704D7085E97D594AA7BCF79C06BEAF -:10FA30000EC5FB1F28C1F8C39F54EF066AD53624B4 -:10FA4000D22FFB85C0DB6AE1A7E03E12FA1F2E91A0 -:10FA500046C3E717293CEEB0DBEEFB05C2F3214BB2 -:10FA6000DB4F70BE214B7B6D128EF301A37132E729 -:10FA7000E8AD981FE6F3308C13AFC863762FD2E75A -:10FA80002013C541DC7EE7380BE4DDEB14B4849928 -:10FA9000596301C7E0B05C684EC913F3AA6D4D828B -:10FAA000FA49EBBE61BDC87F708E73A21C9AC56215 -:10FAB000C6359F167431E5F15E1AFA614936450F75 -:10FAC000C658C7D302CF201736E13A2EB7ED1BA296 -:10FAD000907EE07E07BAB2F47F074CC18D4AD7F61C -:10FAE00076FBD8E7900E251D5FAAB2EA2D764E5F11 -:10FAF0005322E458B3A4A7738C470F9BC362C64D2F -:10FB0000DF17782AB7F95EC1F90EDBE3A1FD8E0A93 -:10FB100029EF679998067478A320C31BD7B5FE9D7B -:10FB2000EC8B1F4E9F56A5DDCEA87F86FB0F150BD5 -:10FB30001C41DC8FA868C90B50BC698E42FB245560 -:10FB40002DEFF9305F3174A893E46482A21CEC4776 -:10FB5000263FE37251630725FDA90248D0FF34A177 -:10FB600067409FAC4E807555AC5BDF9A01457F01C5 -:10FB7000C301F1FF9089FB7FD1EB4A8BE7F059314C -:10FB800005FCE04128764FACDC918D78AEBE50F19B -:10FB900082B1B2F4F8EE5D978AB85826961FDFADB1 -:10FBA0004B3F3293A61162309FA7E23BF3BA2D9DE3 -:10FBB000E481CC0730DF88CC361AECB5078EEFAE87 -:10FBC0001B40F44B7A8969200F2E0EF3FB47AAFFE6 -:10FBD000A39FC1BAAF0365BC6430A61A9B4E784A96 -:10FBE000A7755E2BD619F807530EDAC270B9AE6549 -:10FBF00037C1FB23338C07CC632EE2A031DF954461 -:10FC0000FBC9603FD03AAFB7358C47BD7ECCD2310F -:10FC1000D08BF184ED1FE60460FC4F7F7EC2C18073 -:10FC2000EEFEAA7538F0FBA1BBDF77E880DF4FEF6F -:10FC3000568B917E6F117A52C22DCECDE9E166B717 -:10FC40008FB9511ED69C1AEE8F8C0B2D4925FD368F -:10FC50003708338CB097E66F4A400BAE335FD994C8 -:10FC600062C84BBD576965D5B1E2A097BA39BEE607 -:10FC70006E5E6FC9F2E0F87E178E7F08F40BD2CD6E -:10FC8000A16D8E20FAEF723E659B0759D09EFA6BEC -:10FC90008B9585D03FD3DACCCCCEE5A602F4EA171B -:10FCA00074193DCF9DAF24507FE50F71395B0A6316 -:10FCB0002D01B8FA5BE6923C8D5E47F9A79E093D9F -:10FCC00000DEE52BC172F1F0FA7703DEFC4BEEF9B2 -:10FCD00006EDD3E87596068CF27566BD312FE57E8C -:10FCE00085C037889B7AB4F3CB1B8CF52A5AEEA5D6 -:10FCF000FE2B502ECBEFB0FE216E61170E67235006 -:10FD00000ED7DA7B25F9CFA0678FD680419ECFD85A -:10FD1000911A1BA5876A18A5CCED217C2C6879EF78 -:10FD2000A748370B9BB758B09FBAE078279033B3FA -:10FD3000B600C7A33D8DFBE3D07406EE8FC33C6BCA -:10FD4000712219B87FEE1BEF067C999D51FBE5628D -:10FD50007DD305FC99DD45F4351DD73310BF6BDF2E -:10FD600046AEE7F8AE21361C77B25CD70858977AD2 -:10FD7000EEEB92EB91EB93E595203763C90549DFF4 -:10FD8000CCCDF5CDACC6292B320114B5DBBFA038E4 -:10FD900000137E8826F0A3D957911FA231F033F8C3 -:10FDA0003AB91F12607B58049D45D35105C2019991 -:10FDB000D8C9DBD9847FD2493F2D6B081E12CFD022 -:10FDC000613ADFB70CA5E3BE25D0D181283A32E4F1 -:10FDD000CB1B8CF9AFCDEDB9C8DF402F0722E1FB7B -:10FDE00075D4791999CE70F7E2EBF7E8139C505E61 -:10FDF000CE7C2B9CB4FE06E2C3435AC3CE9F21DFC8 -:10FE00003572BAFFABC0FBC76E5F2DE29D69FA4049 -:10FE1000946F45CB325437D42B5DAD38919F66D665 -:10FE20000D9A807C3898E9D4DF8C6EECCB8D02FE85 -:10FE300065D5666601E3A0CCC348AE956D53833C9F -:10FE40004EA7DB4B00BE73041E2A576EB164403AC6 -:10FE5000A7BA82DB3D41CE2F0057B27BE6AD6EA53F -:10FE60003802F85131F94DEAA9CA266379155B4D7C -:10FE700078A88AB27F82921EBDCC8BF4E8FFA9C31A -:10FE8000A6249D7DBDAC6B9C88E248C777F5257B99 -:10FE9000F8B8C7D303EBF901E76D68E76BFE11F81B -:10FEA0001DE044FAB263694210EDFD7D27C18F4524 -:10FEB0001BD4E91F6101B8B47F9C437A5CD2A75C74 -:10FEC0004F956D35D1671533FAC9A5E09061FCB740 -:10FED00074634A10CF0340FF039BD18EDA68263B40 -:10FEE00029C016A733A033DF7233C9C3B2E664F268 -:10FEF000D3CBEAF8BE51D9E6E4A0CAE30F7B30EEDB -:10FF000022F1B0AF6EAC2583F094E745FDCB9ACDDE -:10FF100006FA96F889F673E7D5B7EE4CF7741F0723 -:10FF200089C0CF816EF07320123F7BA2F0C3EE4EEA -:10FF3000E17266D11FFBE23ED9F1EA38AF1AC36F16 -:10FF4000927A886503010E0FC7138B33393E98E60A -:10FF50004D437C9E583D8CF0158DA7E27FCD247CCF -:10FF6000B08F1D0CE3CC337AB35BA7C2F75B15CE21 -:10FF70001F336AAF2C467DFD959033EF827CD22DE6 -:10FF80008CBD07F24907F9F43EC82DCC7F50934E43 -:10FF9000F90F6B3C94FEB9A61FA50784DD27F9066F -:10FFA00008C08276E309C12F27A4FC62B7A5A3E9A4 -:10FFB00050FCAFF7879930741BB8EBAAF160CF5CA7 -:10FFC000AD1BF5DDB46B8DFAACDDEC9C908E76EE5E -:10FFD0004A85F653CA7C630CF599E6B14C417FBD66 -:10FFE000DF90F077B25F3D96A9C0EF374E4A31D42B -:10FFF000BFBE3ECB904F48F5D0FCA614F7367CBF71 -:020000021000EC -:1000000069FA45867CE94900C210A46617E1E13629 -:100010001B13F104178FF38AF334DF568FE871074F -:10002000CCF7DBB7CD541E8D0F89D7596B4DCC0F54 -:10003000539BB916D606FD1E68003C41BB2F3F728C -:1000400030A4E3159B87BC3312F2FB369B295EBBC1 -:10005000AF2EE53EB48FF66D4E4DC438B07F852A85 -:10006000EC08A78545C8ABB1754BE99C4D69D0EA52 -:10007000257B6147E00999F728C8F78CF3CB1E353B -:10008000887139C01F8F673C63A57D884360B7398D -:10009000412F1C52581DA6A85892A0FCBBB6D420D4 -:1000A000F273F1BF543D1DE9E99938B1CFA4507FF7 -:1000B00047DEEBBB6115D197A729447C6B25FF6711 -:1000C000663B5F1F53066721FE0F25333D192651FE -:1000D000B9F8C3BD1AE0696E7EDBC010B49B9E17F1 -:1000E0004ABD01DA1D6D34D3B91BECD709F9CADF5B -:1000F0005AD77339A2F7407F220CCFE0405CF70C4F -:1001000093EFF254C0DF91D9C18124CFEE4E25BECA -:100110008A86FB018B9FE01B403E50C2F231CC67C8 -:100120007CFF10845A06CA9999666F1AEAA703AB36 -:10013000CD647782FE48C4F119DB4A747C40F34CED -:10014000C0751FA8CF6328AFE4B865AB55F2B39074 -:10015000FEA8FEFDAA1F6C0426F554A05EF1B31E96 -:100160005DE9E6278B46F4C0F544DBB732FD1A782B -:10017000D51F612FCCDBAEFAD03F6243DBB56B2FCE -:100180008E5C471DDFB748E7FDDF26E4FA825E6F2D -:10019000ECB59B50AEF74E42BFE7F01E95E8EC7011 -:1001A000AF86E1E9BDF178CC6BC3EF80FC97258188 -:1001B000831AE49FB0FA17205CE79B563FA140BB2F -:1001C000632DFBEF1B03ED8E3C6BF6E2B0F39E99C3 -:1001D000DB93F619847DDD556EE9D23E4853D2D1CA -:1001E0008E7092DEF6D4C120B4FE20CDF366D6B474 -:1001F0001CF1E65CC0BFEF1FE65885719A99C01EDE -:100200009176F77E33B70BFE2795FBB552BFB7A4A7 -:1002100072F932D3C4E99ABDA2909F8AF64E9F0824 -:100220007D2CE5F29A546E4774EA65D644F26A363C -:100230009EDB81F52DD8640D06F3A88D13F97C2E75 -:10024000470FDB8D7202C69D6779F661E4A10AD67D -:1002500046FAF3883938BB2D0FDBAFAF73517BB350 -:1002600097E2C5429FD88081501E5508BEAB6C50A6 -:100270008221E21BAE17CB45FF0CF54C84FCEAAAA9 -:10028000578CFAA45CE8D17216156F6E30EA375FAE -:100290000277E2E7C1B8A82FC3F302FB186036DB90 -:1002A0001FDC3999E6AD788331E651C13A422ACE56 -:1002B0007B33DF77889E57F43ACE759EB3BD53C625 -:1002C000250F8D18376ADE12DE14B08EC08384FBD2 -:1002D000EC0087E7EC1685F0F5B9B0CBE4BE8BC433 -:1002E0007B05F34DC6F384150F82BCCC0BD341A71D -:1002F000DEDF12A4FD952F5943A21DE87EC1DA2D41 -:10030000D78FC276EBDE23FF62BA2BD4D794CC58BA -:100310004AE0F355C53931F655A2EC831F0B3E3840 -:100320007B6DB86807F0286F54F5B881867AD45E83 -:10033000DA077302010BC661E788F8E6D9E659854A -:10034000F5069FCB7C63DB33FFE9BCBF4F15F1B9EA -:100350002EF650DF987E54A71D7416FDFB89399444 -:1003600083FAB7234723FDF3ADE6FDB0D08DFAB88D -:100370002FF905DDC9D7D9420F97A35E86F4E0DADD -:10038000E713D16FFFFCC1E7693FD7F26C7922DA3E -:10039000C507D7CEBC2F002C7570F34CD2C3158F78 -:1003A0004A3DECB744EAF7B16B4B7FFD73A4CF4DE8 -:1003B00071B41F317B875FD8DDE0B7A01C5CAB3028 -:1003C000D20B0F72B95781FA6A00E9AB0BB0DE4F5E -:1003D00067FB2F403A8FF84E7AECA733FD23A83DF8 -:1003E0007386D0EF02C919427D25F5A9D4B39AC905 -:1003F000DF270DE1A5BEFDC19DB0FEAFB6AAE4DECC -:1004000055AAEB739DB8CFD18DDCFEF7E16DEA8480 -:1004100077DE39C0BB0CE14DF60F87F767F51CCED0 -:10042000FB5773B8AFD8DC3B11FDDBCFEA7B93DD24 -:10043000F3D9E6BE04EF59AB00DE64F77A8C764F51 -:100440003DC01BED7C84378C5BB6C323E0EDE5F04B -:10045000AE177A67354F6775816BE01694273FFDBD -:100460008DD58BFAFC505C2815FD91435B5486E7D3 -:100470002C3AED2261BF48387FC71A9E403BAA8BB9 -:100480003D73BF95617C76EE0B8E2083FC11A5B089 -:100490000722E068C31B89385E78FC4E3B665ADA57 -:1004A000B0083BE61CF1B390F9E81EC2C296373E95 -:1004B000423B5ED1B95FBFD0660F21DF82BF73348C -:1004C000529E2B1E94691827F1DA6C4807D9CCE3A9 -:1004D00023BB46EE77F919EE777DDFF79B5B1613AA -:1004E0003F77E447C6C9ABE243668C2F756C510871 -:1004F000DF95B715261632DC4FABA679DC9EC6F524 -:10050000B1A2EB1437B402DDC4C3784BD23C24CF84 -:10051000158F93C711D7C1B88EF07CA3BF4F46D2B9 -:10052000437D6E8F1D77DE98C6ED804AD5447EC729 -:10053000020BF73FE47996E5621ECBD3B81F726FCA -:100540001A3FCF770CCF8340BFC72EB58AF3D9E3CC -:10055000289ED9193F9170736A5F77CA2BE42BAD3F -:10056000231BE1B477F47B66946B7BB12D19D380A8 -:1005700080E168C7F0F6EF98EDF56857DE3CF20DC4 -:100580008A83EE8DF379D0DEDA9B6AF3221D05B6FD -:100590005B89FEEE89E7F16FE64ED2909F6E12F214 -:1005A00076468155C720EFCD05F7F830857102B842 -:1005B00009B1A2F0F5E54847B7A6EFBFDD064B5AF3 -:1005C0006AE2F6CA5217A373409780B98E71583CFD -:1005D00022733AE54C74638C5B2FC0F8EC68C60953 -:1005E0006A24C1D39007B852FEE587AF9BF8603606 -:1005F00063FFCB3C17239E17204C900E4A93C8FFF5 -:10060000BF1AE3C42E4C35A2AFA91A0B98785A8FA3 -:10061000213519379E2CD679DD48164A82F5857624 -:1006200033435CFD8690297401C0ED6A2DD48AF0B5 -:1006300033D93C66F4037CC5CA60F48F172C3BB7F2 -:10064000F9BEF3B07FE283059037F1C38B1D772AA3 -:10065000C10D00A79B81B9912E6FD1D80E7530C7FF -:100660001BD25D95CB13A07A8B14B13FC4E3F91272 -:100670002F83A0FB48F8DE2CE607FDD427627B4BD6 -:10068000ECB8D1C769D2FFE576E67CC1A7F3259D1A -:100690006D36F2E73F249FA03D0B70BB59A4DDD11E -:1006A000F9DF44FF7F1374FEF9798E576965215A8B -:1006B000F7762BE1518E7BB548BF4BE3F6B29C87B2 -:1006C000A45F26E24F2690184847071A6AC95E9A27 -:1006D0001315FF6591712A3556BE53EE984E636A25 -:1006E000E99885F3512E8B237EB9D9D2D4B7DADEBF -:1006F000B51ED8D184A24ABB8DECBF85AC9DC7B3D3 -:1007000084DD2FEDC5B968E761BCB291DBB59AB065 -:10071000C74BC13F43A22BAD8FB077E17F939BB70F -:100720008CC7783E18267EDAB7B0DBE8DCC6E40575 -:10073000463BC92CEC2273945DC4A2CF85083B29AB -:10074000FA5C882AF817EA727F459C0BD184FDDB9E -:100750004947696681CF80611F7E3A6B33F3FB6244 -:10076000227E27F4F378D5DE0FE5CD7425DE8BF6F7 -:10077000FEB14247C09484F125338D371DF800E562 -:10078000C82771FC7CC58CA49F4E463B787AA24555 -:10079000C3F45367AFA41B18CA1B55EC1B0527E213 -:1007A0003E532DCA4D9EBF57CFA62898C86F7C0BCD -:1007B000F767AEFD01E64BF92727EAE0BF1DFBA373 -:1007C000280F401EE975B9E4DBDFF2FC43B2FC7789 -:1007D0003CBF52966FA3F18EAD91FD8BFCFD51E5B0 -:1007E0004BA3CA1FE1F9F13DB64D0C207CC4BED32A -:1007F000F4D10AED3BCD41BE02F84D5F16227A9A44 -:100800006E7A8DA7452C84FB8E67ABB7A8876F0ED9 -:10081000EA67D571C081F6C99D19FA1CB4AFAE4D17 -:10082000F5FB7AA05F3845095870FF714F305FE8DB -:10083000AF98E7E7E7083E5D98EEA3F6D2DE857E47 -:100840006EFC77FA39D5A34B3F653D52CFBF9FDD94 -:10085000E97C7D11FDCCFF77FA1998619C8FB4FF7C -:10086000DEC8D457E0FAD801B7E15CE4FCFFF1261A -:10087000A1FDC8F05C24807EFEB2A6DC21D0FFFC86 -:10088000E75ECA9D1D115F5878D2C474B013AB4E99 -:10089000324ABF6CFDB3C503F359B8ADD53201EA96 -:1008A00055413A36625E0BE4B960D6AE4D8DB05F0D -:1008B000EEED6112FC743FBFC7F5DC61DA3F9E6F5D -:1008C0006A3AF828F2E3681E678C5EDF4F7AF0FD23 -:1008D000BEBD783E20867F727F0F6E8F6CCFD61B99 -:1008E000709D8B5146423AB636F6F98A8F457FD3D2 -:1008F000E3B93C9F39DC61F35C82FBD9FE5ABCAFA3 -:10090000377B5DDE608C57DF915AF4688F33C67F8A -:100910003B78FCB785C77FA7BBDA6E0365C53EF899 -:10092000D5FBF7DAC05F9DF82BD6B91F8C71D56265 -:10093000ABE4BB2313C715503C8FF2CD3D0EDC1B3F -:1009400080F6BBE2F9F99119232E8E4779D09E9754 -:100950006072829C08B84B3FC079CC1871E904FCE6 -:100960005E6875E497F2FD03A28B80DBD784EBC64B -:10097000FA18BFF15B783CCFFFA64AF13CFFC004F8 -:100980007FACF307CF09387CD083DB67BB00CD6831 -:1009900057C979C8F1C120BBAD0DFA3BB02C63102B -:1009A000DE8BFCD85DB887E022C6FFD8ED6F8D1CCA -:1009B0001F963B10BF9FEB3C5E1174B147E0CD57D3 -:1009C000A0323D42DE4F1D9760C85F3B2985E9910B -:1009D00071E56BB30CF969D37B1BEADF34EB22437F -:1009E0007989B56D68F579D8F9550E473C9E6FF851 -:1009F000B4E5BBFFBB19EDD746D5ABC07AE66EDFD9 -:100A0000F87F63A0D6713C364CF6A887E27B47F0AE -:100A1000BC21F29EA66B91FB525FB1363AA719B189 -:100A2000EF61D85F9AEFDC41E7447FAC7DA9133DCD -:100A3000C4BEC7603C628E7AE8835C3C5FB2D0CEB5 -:100A4000D7F3D54BFB2C74BF03F507D0F715D8505F -:100A5000453E0F50BC7D6CF33EBA47F7500F2E97C2 -:100A600017662FD2C002655590A2DC9F00F22909BB -:100A7000E8A3AD955DBC0DCF57E739E83C4CE5C91F -:100A8000A98CA5201D05062C827AF3EB8B29BFF0DB -:100A9000643CF5FBAEDA3681CED1BFA8D0BE484962 -:100AA000D68C65682760FD9FC07825BFBBA218E182 -:100AB000B3701B3F3753A2FEEF50EC67414331B593 -:100AC0002F51D92E05ECA18963B97E2D415B06F229 -:100AD000EA70C72AD4ABAA2594FF18CA138B83E403 -:100AE00049D2C99B68FCAA93366A9F95CEED3473B0 -:100AF0003B9FD7F8933EFA2EF19E97DECB70EFD353 -:100B00009CDAA895D9B13EA3FA579DBC9052B9CEB4 -:100B100037FBFDC68D72CC9CFAED043C27FCA65B2E -:100B200071927915256F4F548F486231E4914CAD25 -:100B300042CEDE7C929F43EF95A98F4887794EBEC7 -:100B4000BB5DC37D2A66B739115E93470EF2CC8E2A -:100B5000E023F5B51BD1336056778719F5F9CD90B1 -:100B600046CAE35BBB91C797A69B0CF776A47E6150 -:100B7000C11BC9FEBE45DE53167C72A1A82FDBB790 -:100B800091ED04787CC14A76D4984CBF2F1DCADB06 -:100B90000AD9B4AD241FDB72717FE8C79A3FE0D950 -:100BA000A6903FD34EF730268FF498D03EBC2EDD72 -:100BB00064B0D3CEB68E2251FF5D952D417DF2EE0D -:100BC000E597B7E9D05FEBCF860C41B92FC79D9D64 -:100BD000CEEF9D3367C70FE8B756BD92E041BE2EFA -:100BE000C1BDD6A161BB1DBE338C7356BD62DD8015 -:100BF000E799AA12C16F87F1C7BE1A17423A6E7DF4 -:100C0000354E43FDF075B67F36E273ECAB178CC3FF -:100C100073747A8B556364DFE81508B7EEE67B36AC -:100C2000F9144D67922FFDF59C5F4A059D9609FECC -:100C3000F30B3E3A51DD83F8F0C4DD30695847D9F3 -:100C4000DDCAC5DBD01EF038E81C96E4CB12F4F305 -:100C5000E07BC945C9E4EF46F01DF1E182934EEA1D -:100C6000AFF2A447F0B98BF292DFCA04BF48FAF69C -:100C7000093BE26799FE87111E25B5C0EF787F73A7 -:100C800059C650E4A330BD589C4857402FE9B323C0 -:100C9000E8A1B615E8C541F44272C8076924BD5CF5 -:100CA0002DEF1531E7843498F7E4BA3CC3BDA2C7F1 -:100CB000CE93EEEB05BD94D9437DD15E3557C77910 -:100CC000F19EE47137DF875ABC92C36FB1D93716F2 -:100CD000ED87C58F285EC00CD915288F867F546D8F -:100CE000898CABDE787220F3C0FAAF39D987D23B5A -:100CF00052FD4F231C4A4F5E2FE035F0DFDAEF1C28 -:100D0000A6F3389A3968F5AEC7FDC438BF8AF83DF6 -:100D100094C39C0F44C4D130EE87F13FB90F2AE34E -:100D20006A56DC378ED093DF690DB9E8E77489AF76 -:100D3000151AF70B17B4FEEF7013941FC9D329CE01 -:100D400036C3E47F1DE979DED4E07366C8CF5FF374 -:100D50007C22C6F5253C9BB4505FD4934D00478C54 -:100D6000F735AD568B83DC9E49E0FB7C9CAE251DA0 -:100D700047D3F7BC93BD889E4E545B49EF9C007AE5 -:100D800065117A275ADF483AAED498F05B93E8DCD5 -:100D90008894FF617DB3FEBED148774735A2FFB08E -:100DA000BE99EA2BE4F44FE7CEA3E9FFC59A743A63 -:100DB0004F24F548B4BE8996EB525F7D92E1FF1E49 -:100DC000E154F4DB7F3EFF317CBA4AE37AEB2ACD73 -:100DD00041F4F3DF92FBFF3C4FFA3F2CEA83FD4ADC -:100DE0007621CAF5C8FEC66416256640794A06D73C -:100DF000ABFF6D799F92717EF29E65F0F99F4DDE9B -:100E0000E76770791F2DDFF1A222CAF763DBFBD3FE -:100E10003EFC5E06FA00F55E4B8267A390FFA41FBE -:100E2000E293826792FFDBB367E667C496FF1764BD -:100E3000FC07F2FF7CF944D26F77FC32F15E6E9FC3 -:100E400031B4CF9448FB8CC365D7855C0F44D86917 -:100E50003C9E027CD55789E49B0DF78D46BE39E652 -:100E6000F6E25940C927926F24BFDC2CF8E356A163 -:100E700017247FBC9AE1BF11E125F963C1D668FD53 -:100E80007066FABAD95DCD503FDC0A69247D593BC2 -:100E9000F583912F6EE9A4AB73E38B4919E766479D -:100EA0002CCAE0F7DCFF8B74B508E927065D2DFE40 -:100EB0004FE8AAABFDFAE150BCAF766228D0515E94 -:100EC000988E26BEC5B8DDD09BDBFF9D7462C9A19C -:100ED000B8CEC4D3FC1CAFA45389DF68B9F85CA6B4 -:100EE000EF61C4B7F41BFE5BF2EFB1F3C4F3CA7356 -:100EF000C4F36681E71FD15E7C31165E99D36588A5 -:100F000047007F5F43765C48A32341DDE1D5BC9673 -:100F1000F397CC2F0F6952EFA6A0DE057A69FE4F3A -:100F2000E8A5642C13F18D4393304E39F11722CF8D -:100F30008E4E423EBC7EA42C3FBC5AEF837286C9C3 -:100F4000FD038A8FBCAB8A7CE0C8DBE3605E131FC5 -:100F500060E1FD05281F5F90D4194F41D743D6FFAC -:100F6000F0912FDE5E4DFCCCCFF9307FBBC6F7D5BC -:100F7000447E28E41D11F99151F975BC7EA2D6CEAC -:100F8000F8B9CC20D7032A6E3572FAF145D82580FE -:100F9000C909787E62F236C589F1909B0A8ED1FE2E -:100FA0007378FDC727E905B82FA888FCF76FE37AA7 -:100FB0006FDAC6F3A71EF9C7EA8026FA4BA37819A1 -:100FC000FD599B145DC5F320239560AFBCAE703E08 -:100FD00015A5F7F04F33B66778CEEA7CDA239EA9E1 -:100FE0007D2F6A1FB29EC7F83714C4BE27E2C8140B -:100FF000F5445C81FA07585ED314FB1E4CAAA8DFA7 -:1010000086FB4504AFA43508BF368B8467E21AA47B -:10101000A7F18CE77B3E9A581218C0A7AF47ADFFE7 -:101020004CF35732BBAEDF636C1F3A13FCAC5DDA96 -:101030000BFA9963A4A724CDB7E304CC23C9AD3838 -:10104000D13E5EE88B5B8D7E40983E324A703D6DAE -:101050009D71FD68FACF2C41FA5FC864FDEC35E460 -:10106000E7983AEB737E90F405EDFBF1F7F7A8FDF6 -:10107000A847B3D6207C003F544E79ED0CFCD01429 -:10108000952F88E21F41FFC4BF28E7013E7D63C85A -:101090009969023E5F8973E46D45DC5E6C13F7E28B -:1010A0009664F238AD3F93DB637324DE23EECDB05C -:1010B000083C3371AF2662DD04A71BDD72DD052518 -:1010C00093605D6D2E5EBE3873E49A4076381FDD06 -:1010D000DF6D990525B83F11EE7FF49F506FDC2836 -:1010E000E0B62473CC9F025C1E2AC89795442080EA -:1010F000F76D4A80CE61215DC458B7DE95AE0251CE -:10110000ED75F319DA4FE8DA5E8F6ACFCCEEF3694A -:101110002FF036290AAFC551781D17959F2EF34140 -:1011200083FC9372B1ACF9FEE5696E8C4F2A74A70B -:10113000374CCF57113DCF774AFA9DF827A4D730C7 -:101140003D4F22384F6D92F2B0640DCAC329280F6B -:101150004787F3D7A0BCA0FCE4123D29525F5CBDD9 -:1011600046073CDF502FEBFBA8FE4D75B2BF29545C -:101170002EF1C802534B70FC1B870A7D11B8E64F55 -:10118000583EAF85B7FFEDA3D7FE29D0E70CFCD0C2 -:101190001005977551F94054FD07CFA25FEAA2DA16 -:1011A000DF1D55BE3A2ABF362A5F6F6C5F3A4B216E -:1011B0003E2C057A40449C8D2F5FCEECF47F3AF5AF -:1011C000A96227BBCDC057136B79FE8F8F9696D43B -:1011D0000F88C867CE2C89E40BB9BF0AB23680FAF3 -:1011E000CADC8DBC7CBE3BBAEC17AD6F79F95FF100 -:1011F0009F19B4CF63B00B5E578DF95655CE7BD196 -:101200009F6E1B10B91F5A5D8271966EF75DD8C232 -:101210009271917649A092E844AE53D69F70EAB499 -:101220008AE3FD25B3B2A411F7758AC47EA48BA707 -:10123000A0D754D49B55222E3301CF0363BDF85061 -:10124000DFC59176086BCAC775B6FE8CDF9308D4EC -:10125000027E30CEC6BC168CABB426252D7912EAA0 -:10126000BFFE337509EAD1BD4B52E81CD66559DC87 -:101270008E7C3DA9675A39E45B136EB5E0FDF3D669 -:101280007BC653FA9AAAAFE8005EFBFBA37797D818 -:10129000FB637912C1E7BBCC25254B81CE4FE225FC -:1012A0002568EF7739D3F01E075B6566FC3D24EFB8 -:1012B0001344376BAC83D08F2E5D7A11ED5F953D73 -:1012C000346502DDD3586EA67D0DF8A3FB3AFE55BA -:1012D000E3E99CD7AC3A9106AEA0F4D57FFDA636E3 -:1012E00011CF2D3CAED0FD904BBF6D7A0BDF5DAAC8 -:1012F000A8EFED45D4BC02763D9EBFFA6CED0574B7 -:101300002F647F5C359D7385FA0CEB57FCE07967A1 -:10131000F250ACAF3AF148C941F88EF6F0C195EA07 -:101320000605E795E888C7733C074F79DE41BB1691 -:10133000CA9DCBE0FBC1E573D3D0CE3AA878121595 -:10134000BCC7F0D8AA92F40C7C3FC12AF0B9CA51AC -:101350000A7C5D6AEAA417D21FB393793E356B55B8 -:10136000C94698FFC1472EA0736EBFCCD2D3B2003E -:101370004EB766EB3DB286E13CB99E7AF55F7CDF05 -:10138000F0E5A36569484F79599C8E5F39599656A7 -:101390001661EFCCFE4A23BCBF6AF1DC86F37C35D4 -:1013A0003E47A1F3E8AC2905E3DEB3849F09F4BB13 -:1013B000E4F91876CF0F992AF57BC0BA84ED8779C6 -:1013C000B7DE7BDD5807C0A5F54585F0308BF96B9E -:1013D00031CF9A63EF8BFE90563410E71FA6FF754E -:1013E0002467C9DF80FCC8AC47D604D00610E73BB1 -:1013F00019BE3E85FCBA392E1807F09CE5D6276049 -:101400007D96DE943FD511C1A7A2FEA7017E7EF98D -:1014100053A88FFEDEA781BF3822F72F64FD8A44D0 -:1014200047008D8F2F1C0E0DF1B657AB3988E71E84 -:10143000673F6E263D31FBF1D4BB3B701D405F7DA5 -:1014400059D775D46599895FBADF2F7DDAC8B7ECB3 -:10145000E933F2EDD4C7369534DABBE7DB0AE1D7DE -:101460004C78DC4CE7F82B863934DCB72C7AFC8FCF -:101470001BE9DEF1A2B8C1787FA3E2712BE1B7DDF1 -:10148000E10838715F35D1A125632AE8616916E763 -:10149000B3B12AD36C8329A57B1B723FF0F092076E -:1014A0001EC663A64758F0FA1100BFE3882880CB18 -:1014B00071796F2D6A7FB072F7F396427686FDC11F -:1014C000B3EC0BE20D78E4DB73DD1FBC232B7A7FDA -:1014D000D09C8FFB8F15627F70EC3A1ED7A958C243 -:1014E000DF65199BC2E3C4076A02F81832AE37E021 -:1014F000C47BD60F727D54C194A00DFE79C5BA4548 -:10150000F45EED1121874AF15DB501C85FDE5CF440 -:10151000EB673F1E4770AD7862EEFF3D02EDDA9754 -:1015200096B823FDE835821EA07F86F798653F5F59 -:101530002CFD792ECABFB1BF067F18EF4326B3E753 -:101540006ECC433C65E4E23EA6AC57B1EC67F9BC17 -:101550001EF8D3E03797AE54797CEA052BE9479023 -:1015600009E92CE23EFAACBADD16CB80F0FDB8CF2B -:10157000208F4F2C44DC93B320BCE4BD2DFC4B1FCB -:101580002EEC730FC91B7A6F7ABA49A1FB5D20E973 -:10159000E85ED4CB593C1EDA94C5EDDED25C2FDD7B -:1015A0000FAABCCFEA5DC6CF2BB1CE7BF1781ECCA3 -:1015B000D4369BF62D7F6FA5384A555D9C1E97C883 -:1015C000CF536C1D40E7C6350BEEB778B85C795940 -:1015D000D05F9567CA15482F50FE9186E7D51C5CF1 -:1015E0007E56268BF700A1BD09C63986FFEACDFBE2 -:1015F000CD181831BE22BE433F9EC470BFBB4CAC59 -:101600001EE33458BFFF408463CAF5D3707ECFAA6F -:10161000C4C7B0F8FB46A23DF8AC3A04FDE0D29551 -:10162000AF4F588BF92D83F046072B7DEE7DD22FDF -:10163000F305FEDBC5B9B932C8E33B057B041FF9EE -:10164000551E1FDA23E025E9409657AEE4E7A72AA6 -:10165000975BC9DEA95CFA21F55BE9684B43395D0C -:10166000F98299EE797F28E65DB634A7E023A0AB36 -:10167000327312BD2BBE205062C1FC820685F2E19E -:1016800076A9B948A75FD6BD9888F4B33F2ED41782 -:10169000F556C7A2382F9E5794F1B92FEBFA6EC0BA -:1016A00038CE2C679B03EF6BCDBAADB70BE5FC5E74 -:1016B00067C882E57B9BF24C98D79DCE02CCEBDAD3 -:1016C0002594FF529C57A13FA41785E379C1E6D723 -:1016D0002DBD60BC1FC47ABF7AF6FD7CD46B95B972 -:1016E0006DF9A87F800EF2B310CECF28A4B7176E85 -:1016F000E6E7F8251D2C443A00BE9B27E860E1B6DA -:1017000017EF407E5888F81FDC958E804E77D0F713 -:10171000ADEB2730DE7E07D289D47790AF33BB3074 -:101720005E27F2300EE64F213C8751F9385E1E18D5 -:10173000C0CF03B6D3F9C62A719FB3533E7583E772 -:10174000CC6CB17FB6D44AF236339BAFBB7DE50B90 -:101750008988C7AF9E7D7D27C6892BB78256F7C47F -:10176000E00B01972A844322AD83EC902A5C7762D8 -:10177000180E9DF42FF8B18AF175CA755769020EDB -:10178000B25CB4CFCAE6EB5CC004DCB65DC0F94F16 -:10179000F01BF233BDBB24D6E77719DF97D7C5FA24 -:1017A000FA8B7401D005DE5F63787D53CA0928FA8D -:1017B0006ACB7A8A13497CC9794FCDF6483DA22776 -:1017C000BBC2786C37C57E5F7B54369727FB96F794 -:1017D000C86D06B87D09FE189D37007AD522C693DC -:1017E0007423C71BFBDB2957E17AA1FF10F62FC733 -:1017F000DD1B48D0B09FBD8CF307D227CA4FC997D5 -:10180000636B675C3508CF4307BE72F4467B5BE0D1 -:101810006F6A367F0750473B01DAEBCD0AC5A9F75F -:1018200009FF7FDFF21713CB22E0E413F3967486EF -:101830007F18BF92F3DDE5E271DFE8794B3924E7E9 -:101840003DF69E1BAEC2EF72FE925E257D4A384A7F -:101850003A95F703A3E995684DEA4FD520EF493F44 -:101860005E91FD8DC56FEFFA3D3ADF6937D5A5EF83 -:1018700088BCF7B65F9C77EF48653CDECF806A2373 -:10188000F48ED4F3117A65B516A157AADC3ABDB728 -:101890003367E8A27CD4632F64F37329475893A578 -:1018A00010FA5B70A86D42A2276CAF5EFA6D48C556 -:1018B000F76E166CE3E7D724DC171CDD41F45F29D3 -:1018C000EE6F95AE7CBF6404D2F9D366DAE72C5D87 -:1018D0003E9EEE69CFDD387338D211DEFB40B97E13 -:1018E000B871D810FE5C9B33ED7ABCFFD1F8C0F51F -:1018F00037C1F759CDAA97E43BF4837C5B7AFB10A0 -:10190000A6D07ADB4B70FFB4E34ED58976FE988D76 -:10191000C3EEC6FA631C3D93713D7A630AE5752DEB -:1019200089F483B48FE5B9BE5A33A78B5F67737FA1 -:10193000F5E1CE5411E7F96AF371FFBD637D1CBD7B -:101940007335DD22EEBB6EEF417E489505AF5ED26A -:10195000FD59B2C7E658982D839F0FB765C0F7DDD4 -:10196000E6B6DB518FECBEDD3188EE1FA83F0C2FB1 -:10197000E3FE23CDA324C5F8AE949CC71382DEA357 -:10198000FB93ED7789F3D9FBC5FC0FD73D7D3DEA8D -:10199000C1C39BFABA70DD5F6C8FA3F771BE887A02 -:1019A000AFF37CEFB301FD46DD175B46F36BCAB6C0 -:1019B000F3FB5CC28E93F47ED6FB5C9FB8A3F6115A -:1019C000CE7C3EE9680DA37BE7B7812D8EEDC72560 -:1019D0009C7A1ECF05CE6EB03AF1DECF01A477DC43 -:1019E000BF7A41E5F7936D9CFE0F6C1914447F7329 -:1019F000F627FC1ED68EFBEFA17309E5605FE2D1EE -:101A0000CD4E7BF9C1FBAF473638EEF5AFC88076D7 -:101A1000C737F173145DDE77D8FDFCCEC8F71DCE55 -:101A2000D74E3E57FB58C6233EC936BE1F20E12A7B -:101A3000FDA45701FF230787E1F475CD1CB28F8FFA -:101A4000D6F8293DA6ECBB6F0CD2AD2389EE37BC8E -:101A5000DCFC808AEFD1546E1BF403FAC5A3ED4978 -:101A60004EE4D7AF6B96D0FEE8D19A6AFEEE4AE715 -:101A7000BBCA414A2FDDD64AEDBE6E1ED282F78127 -:101A80005FB12709B91FBD1FC4F1D8DD3D67B9AEED -:101A90002377727CCA791FD9343311D7D5FA584AC3 -:101AA000CB28C463429213EDBC0A714EE4E05A6E37 -:101AB000471FB2253D3909E07368DD3569F85E508E -:101AC00079EBB5D7E3F7D9DB1527DAFFDEED531253 -:101AD000D13FFB5C6B4FC4FB5F9FAF95F7C682F4B1 -:101AE0007EEFE86246FB55A3431AF3E4D1D633D127 -:101AF000C9A8A31ADDCFFD12F7B1305EF2433CC591 -:101B00004B98D89F2A7F89C7593AFD59E1CF8D114B -:101B1000EB1E91E392FB0EF47DEC48FEFD8B75CF3E -:101B20004FC6FE0E379A9D38EFAF1BF93B16F3C038 -:101B30000FC3AB008736713F675E93427EF1E14D84 -:101B4000A0A7615D958BCC3ADD6B8DA2BFB1508EA5 -:101B5000E72225FDCDD38344D7D1EF8C24B326BA19 -:101B6000FFF663D1E3C539467FAD930EBBC3BF809B -:101B700013F22DD2A1C4F3BCB5FC7D5B57D3A042B8 -:101B8000A42789F7E87B0EB51646F71902A6787ADE -:101B9000177A8ADD635660FDD7B8DBC7A1F87C24CD -:101BA00087CB4575AC49C7FB7AAC96BF63D0253E61 -:101BB0009DC3E5E89B398CD2B21C7EDE58DE5B9378 -:101BC000292C2487DE654C707DE7812AD7E46C9A46 -:101BD000ACC1FCA78C71DDDEDBCBD8CD39CF4DD6C7 -:101BE000806EA70C71BDD00BF2331EDFCCF397B81B -:101BF000869921BF54F9DDE47190BF2B479F9293E2 -:101C00001A1E47F60BDFAFC5EF8752FC37E40C43D3 -:101C100039CEDF2D3BA6740C5C9217AEFF9EC2F648 -:101C2000BEAC84F3ED6646EFE594E1FC53BB4F3761 -:101C3000E4E8FE9C6131CA19A3FB6365017E1F08BD -:101C4000FE7CB6343AA746F45426EF07D51BEF07BF -:101C5000312FBF9F26EF6DC97B59FDC3F7CDD69DB0 -:101C6000CF7DB363E27E5CF4BD3FA585DF97AB0D0E -:101C7000B0F638C243D47D9F04FE7EE3E217BEDA9D -:101C800081643557DA2BA86C8787DF3960E9FCBCA3 -:101C9000C0ED820EBFA8617DFA002B5FDDD696E80D -:101CA00081C91E9D1CCA47FEF658FDF508A72FD610 -:101CB000D5662F76E3FD58AB7712D43F14E4F74F87 -:101CC0001708BB9335A60A3E57439743BD5D79FD80 -:101CD000E99D8B5F0A7A3A9A17CAC577870279DC41 -:101CE000CF817A74FEAD78D915A958EFE8967BFAC2 -:101CF0009403DEACF8AE9F8B5286F7C5AE84BE4728 -:101D0000BAE8BD3FA6D2FE6E90FAC37A89A8D73D45 -:101D100033D379FC9DDF2F947892F0EF82179802ED -:101D2000DAA5261B33E3FCFBB3754ED4C7123FF292 -:101D30007DDBC52FF038CA62A5BD2E05F3CF2A740E -:101D40007EEE0B1BBF0FD455CF6DB420A8E7AC9B24 -:101D50006978C748BE23FB63C7835ECA11F7C20711 -:101D6000B14191EFF45688B6E3D5E91E7C677471F2 -:101D7000AA8DDE3759FC786FD2272C703BD181AC0D -:101D8000C7D6A5107DACC85309CE739B19BD4F545F -:101D9000D29C49E71D2735BB284D3C994EDF0F3FAC -:101DA000F9D6502E7F381E4A9EEA41EF8A973C753D -:101DB00041117F74AFCB3B49FC3D6DBB8DEE1B2FBA -:101DC000DECDF5D2E2EB548A5332710FCC27A6E375 -:101DD000B3D7535CC7C762BF0FEC93EF03EBE63397 -:101DE000BE0F2CE16B15F8897E2FF8BADD43D2D1F6 -:101DF0005F95EF05CBF708DBC47DAFE87783EF494C -:101E00009C40EF064FD3B91E897E37580BC479D159 -:101E1000BE3567DBF9BB16FEE87784DB355CF7F58A -:101E200005FC1DE1EBA619EFD3990BBE21396D2EF0 -:101E3000E8F28E9219E9DBEA33D6FFBBD42FFD59C5 -:101E4000FF33BED39C6DA1F7F0347CC71CF2D78B57 -:101E5000779AD18E43FBFCB8CEDFDFB3C6F375B7FC -:101E6000B1A1E9C8F7FFBFBF4F7EB677C9A3DF2195 -:101E70008F7E7F7CC8AE5F1AF2C3DA1E35D41FF1A5 -:101E8000D10643F9A8F6670CE5630E6D35E42FED36 -:101E9000F883A1FEE5275F33E40BD95B86FA636D17 -:101EA000EF1BF2E39D7F31D4BF227DBFA1FC4ACF5F -:101EB0009786F289FD4E18D7A3F927E4223F7BFFCE -:101EC00069683799797E81EF7BDFE036D1BB26C523 -:101ED000B946BA1B97C3E30AAC0FCB45F9355E9DF3 -:101EE00044EF241D6F52F8FBD2DDE8B124B0F7B403 -:101EF000887192751B3882E17C4AB1D3904FF5A569 -:101F00001BEAF798E6319467F8FB19CAB3E6780D37 -:101F1000F99CEA9186FA3D97E8867C5EA0D850BF8E -:101F200077BDCF90EFDB30CD50FF82B57E4379FF98 -:101F3000E01C43F9459BAA0DF98B9B9618EA5FD2EA -:101F40001C30940F0AD51BCA87EC6A30E487B5AD04 -:101F500035D41FF151D0503EAA7D93A17CCCA1264F -:101F600043FED28E6643FDCB4F860CF942B6DB5062 -:101F70007FACED3D437EBCF3CF86FA57A4EF33949C -:101F80005FE9396C285FF0A597EE4BB397F97ED8DF -:101F9000C47EDF18CACD6E46EF6057B2782FEE3B95 -:101FA0004ABBA6C4FB7743BF4FE6F2380AD0527B48 -:101FB0001CBE1F19F051FCC7850702514EE13D754B -:101FC000173F4F339DE2486ED26FA48A3C78BE071C -:101FD000EC8044F4AEF2F2D04E4E08DB63D9A72376 -:101FE000CED79DCD1EDB96CB681EFB73FD4FE7A6BB -:101FF000A2FFB16502BDFBCE022B701EF23DC07781 -:10200000A2DEBB96E995B6432CF25DECDD710DD9ED -:1020100083CFE0BF5F693BCAF0BDEDCE7E45BC42D9 -:1020200081F52D8EE8FF3EF017B43E8C35D400FFCD -:10203000808DF4CB1A27E51FAC49A7FCC3351E4A97 -:10204000D7D6F4A3F4D11A2F95AFAB1949F9276A63 -:1020500074CA076B8A29DD50E3A3EF8D35D328FFBF -:1020600024F8C5986E023F19D367C0DFC5F2CDE0F2 -:10207000FF62FEB99A00A54D35F5F47D6B4D03E581 -:10208000B7D5ACA5FCEF6B829436D76CA2F40F35B4 -:102090004D54DE52D34CF9576A42940FD5ECA2FC52 -:1020A0006B356D94DF51F311E577D6B453BAABE6D7 -:1020B00010A56FD67450F9DB3527297F54C45DF71E -:1020C000E51AF723645EBE5B21EDBFC968BF2371CB -:1020D0008C347F6DB0DFA3ECE8687C1C11E3E03B3F -:1020E000BD43816ECD99F91B6A23FCA7AFC478F27A -:1020F000BD8AE8772798B04FE5FBB0F23D8BD962F7 -:102100005E1582FE87217DF623FA7CFB7CFC05E9C7 -:102110000F5E9BEA3F45F499630A903F6CE7F791A5 -:10212000EF48F5B39EC370DFB07C278DE7F4D2FE95 -:10213000618935947AC3507A079EE272DD8D572506 -:10214000CE89775BFECAE16CB4A78BFFA5D27B6416 -:10215000EF981DF4BB97293D395C527A9A0CE93F00 -:1021600053FDAE9E907EEFA8BEC504F3FFFEB245C0 -:102170004FFE242FEC275F8DAE26F8375398C74CBF -:10218000E71199FEC73CB49BC0B0C2FC0D2C40695E -:10219000C0EDCFC275DD080637E6FDA3ADB9B1D6F7 -:1021A000153DAF7C31AF7C311F99F64FF3F7C5FE7B -:1021B000BE77E834AF77465D918FEB92F39A27DED6 -:1021C0009D98CC3A9EC0F97DBFFD9B834AEF30FCC1 -:1021D000A53F4EEF02A0BFB34811EFFF75797F8096 -:1021E000CAA7DFAE907D3603FC19DC2792EF0D1CE9 -:1021F000AF36937CC4F709701FED78F5E776246756 -:10220000A8C7709FA3160FF64079EDCF15A2AFE9CE -:10221000F88E08B49F9196C7EF4B339B8E7A787AED -:102220008B753DD2E974B0F7D07F02FA2844B8CF5D -:102230001BA5D27DF5774CC17C85F693CB2D0ACCBE -:10224000ABC2ED35FC8E4434FE178AFB07F23BD05F -:10225000D54484D7D72F8DE847F1F7574679104EEC -:10226000B5267EEF28F0A62A7EDF8B8B6675CCC55F -:10227000145F649AD78B71A212714FA555654B629A -:10228000BD1F5F29F0F44E3A7F5FB0366A9FA5BC50 -:1022900027F72FCB7BF2B873C96BBBE99DA585BB34 -:1022A000F87B906C68FB80C877793AD7B3E4CDFEB1 -:1022B0007D22D651D5BC8F9FAF60ED0322CF9FAF5B -:1022C00010E34BFA512D0EFF7A7BE4FC3AE97901D9 -:1022D000D17332D0736FA2E783B8AF38D9EA49BA65 -:1022E00041C15FC7635FE3FB47FE5F3BE93C913C55 -:1022F00057348BF928AD00F423FDFA02F7D37BB7EE -:10230000F358137D5F387226FD3E6D15EB18970E5E -:1023100070BBAE7EE91FF1B9C06B1AEE1F8F71D58D -:10232000A9C1D23F623AA5513988FE29F0C3CF1125 -:102330001FED4AF5723CC279D3E6C2E5B83538598B -:10234000E5F8606F717C00BDE8AAABEB3A81FE97BF -:1023500013FD27EBB40E35B1D840FFD397315D7133 -:1023600087CFC777F2C3C8F97FC52D60A675D0BEE9 -:1023700079D52B5617E2791EE3FA3A6CFF493DCD29 -:10238000F5FF7CD0FF58EF88A0E723398CEE211CA5 -:102390005118DD6F97F623CBF5A70FEE1DD6B74783 -:1023A0004CC1E189BD491FAFC3F9EE4CBF86DE0FBA -:1023B0009AEFB6D1FBB0479283B951EFA1D07B4DD4 -:1023C000327E759F99C793A2E7A58CDCC97FE7C4CD -:1023D000C202B82F81BFF33D1CF938D3427C568B23 -:1023E000A0C5385891CF13ABFF3AD1EFAE53DCCF35 -:1023F0000DE4F0774BBA8CE314E3C4F371A4DEE888 -:10240000FC5DF13466186F7BCF3CCE070E9DE6BFB6 -:10241000D4944C7226C3E66FC1F5CB788EF4FF7668 -:10242000E57DD187FCF41F6AE93D267ABF00CFF530 -:102430005CC6E5D13B660FBD4BFC4E611EC5EDA5EC -:102440009CBD7A248F7B5D2DE35C055171AEA8386D -:102450000B2B881DF762CC6BC671FBB34F247C2815 -:10246000BEF25A8166F83DB1D784DF79BCD83D947D -:102470007E2FCAC3CF5925A6F0F7463A1C2AD1D9D8 -:10248000EB01AF1D7F9F6495888FAE8E7A177CD548 -:10249000D0C54E3C176075F0F73ED714C5CF893CC8 -:1024A000BFEECEE7EFC33C995F98E18174803D5861 -:1024B000446A59D73C387F45ACE72227C0DB84F615 -:1024C000A64FC439E5EFDC8C23BD2CF17CAE7AF944 -:1024D000192DB82C1ED7EB66C4778EB536929F6A3D -:1024E000931EC2A3D4B3F2A71E47B9C1345F3F1CE9 -:1024F000A775783CB343FDEF5B2D147F7AC554F686 -:102500006B7C97B8E3CF5686E71C9A1C591A1AB70A -:102510004DA72E1C47A963CC04FE3E274BC0774431 -:102520000739D96F7E874812F7C92CE9CFF80E809A -:10253000DC6E52D82EFE0E979E80EFE13599D88939 -:10254000CB617EFF0FA64C086300800000000000F6 -:102550001F8B080000000000000BED7D0B7854D5A8 -:10256000B5F03E33674E66269370327930E40167EA -:1025700092C98B4CE290F054AA93106840D0E15578 -:1025800083243A58F446854C8AB445AF5F339000B3 -:1025900001F42FA2B548BD7640A568B50D4A6D6C13 -:1025A00023770242B197EA606D8BBDB57FF0F6F7F5 -:1025B0006AAD12C47AB1A5E5AEB5F63E9939930974 -:1025C000A2BD7FFFEFBFDF8D1FEEECB3F7D98FB554 -:1025D000D77BAD7DF28CA3F6FECB18639359C0CCAC -:1025E0004A18D34A838A96CBD854D641F57B954076 -:1025F000DBEE1C289D565F18FAD58E33F919D4D915 -:10260000C78E48A9C458E0986C313B18EBF3041D01 -:10261000F8DE05FCB90A9EBB4C16C5CBD84685B57D -:10262000F54299E1B3336665F47301FE05CE953149 -:1026300056C7D858CDC4D814C6BA5DFE985F8ABFB5 -:102640009F5C32551E1AD4DF2FC6FF17AA6FA58BC9 -:10265000BA9931AF23D22061C52F6BEA54C6E8770F -:102660008DB12A95052D30451A0B30DC0F9BEEB34A -:1026700006AAB1B1517DAB02FBF9A50BE9179997F9 -:10268000C90CFBE9F3FC6102A3F51EB267D6B031B9 -:102690008C851BB4FB1A2743F953B3AF8B7AA993EC -:1026A00071FCCC6C1635C1F3A10C73648F9BB1C364 -:1026B00061EDA95EA81F96AB088EF774C266000490 -:1026C0005B3BA1A2C4E7DB3A798DAA013CD332CCB3 -:1026D0005F3A8C702E32A9A5B08FCDF3ED4D1180ED -:1026E000E3BD0DF6362C73CA2C8C01BC97165B68C3 -:1026F0003D7BCBEABF5D0CF5564760B6A47138B0A0 -:10270000BC381CE001E3FB0D32DC6F8BCA06A5442C -:10271000B830804B06DF00BE770DDF32BB4666E186 -:10272000314EC65E9EF1F663BD304EC64E587736CA -:10273000BCDF71460EC23AD8F90B57D901DE01BD94 -:10274000FF4C89BD9978CEF0EFCD0AB13F37C15328 -:102750007D4B6F375F3ADC2D4BD6573058EFA64E86 -:1027600017C1AB47F2F9C7C27872C7A93BF0F94667 -:10277000193A02BCC25E25F238CE23072A703FFA0E -:10278000782BCB1A6ED0004E19D3FE907E0BF4FB43 -:1027900028CFA42170366A377DDF8EE777329DE13E -:1027A0007B99D9B1B647A17DE8F572B60786F9E8FD -:1027B000D6E00415CE630B9CD39B1E5C4D64AC69C4 -:1027C0003A9683634D2E02AE8B9741177FCE447BA2 -:1027D00084EA6FB98BE99C00FEA2FF20F5DFA26CB2 -:1027E000B7DA711EB755DD9380F7579959472FCC4B -:1027F000F775A40B7CEF7C97B63003EB12D5EFEFA7 -:10280000DC19F89D07D713A1327B7E840501DFEC2C -:1028100015612D0CFDAC1B5810DF4F86E7DB6E9960 -:10282000DEB71E7A8869D02FDBE39382D02F673E14 -:102830008CA7C399D1B987C7D442BF3D80309311CB -:102840003EF64838055D5E93DB704CCE1CFDFC9275 -:10285000F180093CD0CFD3FA577310F902632E13DD -:10286000E2DB5A2BC7D3C6622BA379D729BBD3602F -:10287000DE27B42C5AF787390D639877F4F91E8157 -:10288000F309033D4580AEB0DCD3A9B230E0C963A3 -:10289000802F58DFDBA951B9AFB382CA273B7DD463 -:1028A000FE54E774AA7FAFD34FF5DECE26AA3FD3FE -:1028B00019A0FA81CE66AA3FD719A4B2AFB38DCAC8 -:1028C0001F7576507B7FE73AAA5F9506E786FBA9DE -:1028D00008BB16C179F4DCA9F83580CFA038C7C38E -:1028E000FEE26C1F9CB7ADC2043407E5F11D0CF786 -:1028F000637399FC1138874DAE1DEC8B505AA66658 -:10290000F448C057363EEDE8918031DBE4FB19F224 -:102910008347A4701BF331F693483020CF60CCE39B -:10292000FA528313EA3F8BDCB2DD0A785BA62D6C8A -:102930005E9F50D7326A6FDBAFC6EB13BCBB653B03 -:10294000B4BFAADDBA3D47E2EB60F98CFD26727B8D -:10295000603DE051B4988511EE436E2582F8B812BF -:10296000CF4BC6F5ABB4FEAB5997CB04EB9FA02978 -:10297000B54837D03FCA722EBDFFA0A6D1F3E4F709 -:102980002ED6CF34F992FA31F345C6C376E922E365 -:1029900058A5C5D618AC7D9B45F08F5C07F18F1EFE -:1029A0000BBB310070EFB1F1F2CA6289F8ACB3B879 -:1029B00061B71BE6DDEDE672ABC716561B70FE6A0B -:1029C000930FF9055BE7FE7931CCF7959FCA6CABA5 -:1029D00016C7CFFF1078503A2183CBCF7FB4464A39 -:1029E000619ECF4F78BADB09F5D2477D3E33F4DFE5 -:1029F000C67C76C493F03D26F638D4BF3BB9C4B943 -:102A000010BA574DF98113F9ED5237E70311C69A01 -:102A100010DFD66FBC65C220941F9DE07C4A71F325 -:102A200079765B621D749E531C6C0F0981EDE9C8B9 -:102A300077D6BBE090A631661AC74BC5A25E8FFD64 -:102A40001410D461588FF29769D6008CD7752EADCB -:102A500009F90863B174E4638A2DA866C1F3ED61D6 -:102A600013F1852ECD119160DC6D8EDA631AF24F71 -:102A7000D5E42B45387A4D04C76EC7172266E4CFDC -:102A8000D2FA36942F11F519AB1B9E47BC2615E9D7 -:102A90003CE25FD484F57050F6956A8241607BD049 -:102AA00019D98AE3B2A17FB90CDB5B980FE1B03191 -:102AB000EF4F87D2A1DEB554F599796F4D06B93342 -:102AC0000E7F8329BB2C831BD2711DCB787FF8CD61 -:102AD000B710E5701A3FBFAF0FCC558B49EECB61F5 -:102AE000A14748178010658BCFEA83F61A476D938C -:102AF0001F4A39A3D6AAC13EBBD55AEB0ADA3F73A7 -:102B0000803284228FF853976A22398CED5F447AA1 -:102B1000EF662F7AF28894A8BDDBB16300E121DF74 -:102B2000CC985BC3F5C17C3ADF0378584B661ED363 -:102B3000601F3DB738691FB2E4A33ABB59A675E7D9 -:102B40006BF628AB013EAF2C38C6807FE45B6F9FED -:102B50008FF5716DF2EF0613F8F4D8A0B19EDB6C1F -:102B6000AC6733A85BE3F32E7273FC4D865B323C9B -:102B7000C6A9DD2770FDE382323D4C5EFF43EA03C8 -:102B800059F50CD7E9A075E6396EAA070801CA0500 -:102B9000D623FEFDADEBAC511759DD307F4D8E894C -:102BA000D496CBD8D0061C779BC0F71E373FCF38C2 -:102BB0005D9975BADC8A7439619D898513E48E3B11 -:102BC0006C67E184F94A7A9C867AE9F67C43FFF2E5 -:102BD0009DC586F6CAC844437BD5BE5A43BDBAF7E5 -:102BE0007243FFCBFA1A0CF549D17986FE75C716E8 -:102BF00019EA5362D71BFA4F3B7993A17DC6E06D6A -:102C000086F62BDE5E63A87F6EE82E437F5DDF4E87 -:102C1000968FDD822F7C5A3D3BCD05989D305FB26B -:102C20001E9FAC875BFFDAA56D407CCE54089F6584 -:102C300094E7505F73A7124943FCBFD2A7217FB925 -:102C40004BE0A3B7DC7F1F9E5B7DA695E482ECE0A2 -:102C5000FD64C71CD253C6EF04BE54875A231B6EB3 -:102C60004F47FEDC190E783CF175DBD4ED0CE9B76B -:102C70003EB3890D3AE2EFCBAA9F0533703E8DE655 -:102C8000B3AA61EA67D3E0FD847D1D34999803F906 -:102C9000F88042FA7A6F46818CF4D7FB97898D547D -:102CA000665C3107F17D92CA1EFD3EF4EF95D83186 -:102CB000067A52AF899D059D8D3D936447E9F6D311 -:102CC0007813B363B95B1ABC83A19DD271A2612C46 -:102CD000233BEB59DCF7BDA043E0BEEEADE17AD675 -:102CE000C6BC791AEA653DEEDE63C5B89E5C902BE2 -:102CF000480872C0877A85BEDF37C479CAC53D836C -:102D000028FFD6645935D49764EBF6C0EF005E8F88 -:102D100058069FE8827AB7A4AE42BB237CA7C3F7CC -:102D20003843FD91C34DCB30D56D80717BD7FBE52A -:102D30002C68EFDDC27CDD481F39F51BB2E07969F4 -:102D4000E10A9313E9C1B37E0396AFA01E0BF0AB6B -:102D5000F4EE3665437BD5E4FA6686B25785F9B260 -:102D600047C72773E64E86FB611EF92DC42BD4BAE4 -:102D70002FC0D2EB9D70DE30AF0DCF5BA292E06032 -:102D80003BE788D8B0EEE170B1F9A5483AD4733C7E -:102D90007EC9EFC5F776D2F9DAA2463D16ECCF37F9 -:102DA000DC53509F359EAB6C7D80D6B7CDC4E9A275 -:102DB000274B3B8EF2B9C7ED717669F175EA7CE578 -:102DC0006D618FEACF75BE723DDA1453E2FA0DE001 -:102DD000F94E5309EA67DB19F227DBDDDB19E2B5AF -:102DE0004D0D6B0CF5F0AF8509CF75FDF60E413337 -:102DF0008DC5CD5694D767736A499FB5ADDB4BE758 -:102E0000950C37DBA089F92F02D7CCB25D24DF8186 -:102E1000016B68871FCA73B4ED4EA1F76FD0389D60 -:102E20006D01328E79098FACC8AF2DC2CE004C3007 -:102E3000A17C3BAB326E27F6BAA97E4716AFEBE317 -:102E4000DC915B3BF662FAB70DECC260C23EB6C0E5 -:102E50003C08978DE71736215C994CC4C1B6FDC577 -:102E6000BB7B2BC252D8351B04BCBFAE71F88E574A -:102E700018D905BE9CF94D24FF5C4FD2F905CE153B -:102E800093109E56EC24F883116DEEA0F55B74F957 -:102E900064BA7019AD595360FD05F8A4184B2EDFC4 -:102EA000A0CBC00509F97F823CE305C9F702FE3BD0 -:102EB000C803637BF94E63BD3292F47E98BD86F2FF -:102EC0007F25E3F0AADA676CFF16CA71E01B2B8539 -:102ED0001C67DB2D24EFACB0A20B5CFEC6E521F035 -:102EE000876B7A63F5E9304ED1748B414E1624F628 -:102EF00003F8D5DE6A0AA0DDA0FB5F74B807DA4CE0 -:102F00001685E84123380D3F17FE9664FE3D3E8D41 -:102F10009FCB212523B2C1CDFD12C1326E6707813F -:102F200024EF957DBF6A417BEC98D907983D7C9E44 -:102F3000C9E7BF6F583F0ECC2F267B77B00EED6FE1 -:102F40009C2F98309FEE37292C0F2E2A86FE1F3497 -:102F5000E54CC6734A2B6416A463DD2FA2DBF9BBD4 -:102F6000115760BC6DBE573B0EC33A369F4C239F32 -:102F7000C66CF3F1639D505F532413DF53A7ADFA82 -:102F800036DAD30DFF0AEDF0CE664D1B4BFAFC315D -:102F90000BD9F50D02DF1B849DA6FB4F6E2BE6FAC5 -:102FA000F42DA28437ECDC4E8FDA51EFADDA073C1A -:102FB000DB882FE9BCDD4F7A71756F72BB9F21BD35 -:102FC0004F14F80075473DD427897A2F93B25538AE -:102FD000E7CB9A070FA1C9E17DE9881DF5B0FD3661 -:102FE0008E1F4F0ABD2F8F49BE28AC3F6F9FC3175E -:102FF000817E1966B63F06FBF0BD28BF399800CF29 -:103000009A7E63DDCB12EA6E5C87B17E8FD621217A -:103010005CEE690154842D6F28CEC879AB8A21CC2F -:10302000CB10FF669B1D93D0EE5A53EF6008D7B4C8 -:1030300053E5DF8C219F396166283FD474EDBE468D -:10304000785FFD976CDF7A2D7EFE4F76228B67ECE2 -:10305000C10B3ED6ED89FBA99E82F34479F33DB0C6 -:10306000C7B1BD17CE15EBCF803D8EE501B0C7F1DE -:10307000F973608F63BD0FEC712C7F04F6383EEF5F -:10308000077B1CEB7BCBEA1F4CF66F25FAF9E2FEBF -:10309000AD4149F76FA5015C1BD04E9C92E0E70A59 -:1030A000723FD7278FE3D7C721FFE1887186FD885C -:1030B0005615FD27C5F0C61878FEDE9DBFDE8B7263 -:1030C000658114DC87F8BD7ACA9B0AD7B38714ECF4 -:1030D000FFB00DF01FF854E128FEC32B679DBA2303 -:1030E00017ECF41F15B72E443BFFCADB4FD58D8775 -:1030F0003A2B39C6EBDF39F56C01F0EA5B4AB6F0E2 -:10310000FAFDA7CE1642FB18F6ECC2C619E47724E6 -:1031100039F6B0C49A13F5C09F08FA0CADDB41FC38 -:1031200014E400433874E505488E9ECE19CA5C014C -:10313000FD43B94379375D84CF87D63D48F2AA2B4A -:10314000F3F7A4A7740DCB151FC9157D5E5DAE7C8A -:1031500020704F972B6B6CBC3ADC2F5842CFEF1787 -:10316000FE1F1629A57AB68DD7FF5783F60ADA47D0 -:10317000001FB2870F674EFCFA4CB43F9B645F1A86 -:10318000D4EF77D4DA502E9D15F40BE386D1DE0F01 -:10319000CFB6461EC743CDD1881E9DFAF8391E54BE -:1031A000CE9853ACE3C5CBED51F40774355AF7A074 -:1031B000DEB9C3514CE3754D57C2E887D1EB1B2EE6 -:1031C000BFDC8A7A4756A6D38D759D3FE9FE5BF832 -:1031D00031E3B80D62BB0D5647D49C89E861F943D1 -:1031E000A23EED6031C21F9F090C17A0B7AF9570CA -:1031F000BCAA63BE667CAE481D6144C68771EDB84B -:103200008F0CE1CF44093535611FFE02BE2F7D1FB3 -:10321000194A58EC83F4A91D0E5314F5C21DB02FA2 -:103220001CEFDF8B35824FF2BE18BA6861DC59D3D0 -:10323000C5BAD59907701DB34DFE6E7CEFC8C72D7A -:1032400039887E7358878CCF4BC0F245FF2DA07410 -:10325000F7858BE827C9FEDB2BFF4DA2FDB0DB1500 -:103260003A17A58CEF7B97127133328423E31665EE -:103270008C8EBF2525FC7CE3F8EB67484F5D4E3F05 -:10328000C75F7528733DE26FD650DE06DA5734E526 -:103290007924E371F2F9D4206D73396046F87ED257 -:1032A00079EAE7A8E341B2FCFA5A89AA9FAF8BF604 -:1032B000E9AFE074A0EB5B0CECA18C91F0DB04E3D4 -:1032C0006965F1BAE20A901E6DC9F155A09FB7EB8E -:1032D000AFE6B6547EDE1B049CD667DA49BFEECA61 -:1032E000E4FAF540E63C835DD408769204F861CEBA -:1032F00066BD4847E631D7939FCC3C1635285C57CE -:1033000092DE3A663ED75B55D05B53CCAB9732EA40 -:10331000AD29F4D961BDD5398FEBAD990AE9AD0F6F -:103320006728CDBB53F09BA9255C2F1CC07DA4B0A2 -:103330000BC11E247FA56E0F2A6A90EC3A7D9F5325 -:10334000055DE9FDD3D40E86FE33B3E2D3502F35AD -:10335000DBB99E9906DBAC4890DFFAFC934A785CB7 -:1033600025AB9CEBFB262BD74FAE7C45EA4805F7F7 -:103370005089EE5F498D777F03DE105FA875287E48 -:10338000D40F6A1DAE06D40F467B0F4CD2F0DBCEB5 -:10339000385FF1FD75AA99E48FEC73219EF55A060A -:1033A0009F7D05EDBD230E9237BD1985349EAE5F1E -:1033B000835D1BAE8041F6FF1928D134D29E053BB8 -:1033C0006B4B09C6BFD6E44DE6E3829E573D52AF34 -:1033D0004CF61B0CD37BE65E377F2F320EDF93D685 -:1033E0004C1F8B78954CEF7A59E4FA69D14A5857BB -:1033F000D1B86354EACFFF8999C90F97DC3F327C7B -:103400000E5C2E57C26463CC248F23B8EEF7D6BE71 -:103410009AE783A5B4CB67482E7FD0317DCC668DEB -:10342000F3DB7D2867BE2413BF2DBC7520CB9970BC -:10343000CEBB3AFB8A640FC61762458D1EF2F7F9C0 -:1034400053ADF7B83E7F7402F1678BC0032D27366A -:10345000B71CE0AE394C3E542540F81AF840BD9CEC -:10346000D5A8C2FC459DCCE780BA9BA9E4F72ABA4F -:1034700060267C2B3ABC8CF07842CE9014F626CC99 -:1034800083AC38217EF2614723D167D1D8617B8F2D -:10349000E20C1FE64417227D7FF8005F51D1A3C6DE -:1034A0007690B1E497BE65AD3D8226E384BB5513AB -:1034B000D68BBE2DB14237AEE3B07B33FA757E9822 -:1034C0004E7E1DF34E0FF965BE2D050F105C23DAFD -:1034D000574C2562B3D06FF557ED7BB6921C8BCD60 -:1034E0002539F665137B3C85DFE9E725DC8FF19A0A -:1034F000C0F722D7CB452BEBB03C4EE77DA9F4C4F7 -:1035000004DFDE3C663BC5C5C20DAC02EDC31E0B3D -:10351000E0550A7AF57B387F19E6C7027E36B45645 -:10352000602CB324F4BC7D4F3EF9641ECA6D46F690 -:103530006472BC36BDA2971AD37D7E86FE0949F51A -:10354000733EAB865D618C03FDC59C12AFC77804EA -:103550009F766F7261FF468FCF857430E09EEABA26 -:1035600009E0E770282C2D810FEB78F262C654D267 -:1035700043F471D664145FD42E57801F6B1791D318 -:103580000AFAC7519F3934C3AAC17A37396A63A886 -:103590006F6D72E4D4929FDD017C23C1EFE4701C57 -:1035A000253C74F8B83FCE81FC17FD4E62FF03EE58 -:1035B000A3B47FBDDFBB820F397C511EA7046B060D -:1035C000FBD9E44018ED0C5B0E23BBD266E5F49406 -:1035D0000EC7614DE023FABCBF2BE1F6DAA6C2DAD2 -:1035E000583DAD4F46CF01DBE4AA75913C4438A36A -:1035F0003E3A6E581F25FF4AB180B33E4ED700DFDA -:1036000067609DCBDF988D7668C0E5C1711D375925 -:10361000C3281732265F743CAF4732F887E2E3AD28 -:103620009B25C62BC6F1CC19B52A8E67413E910267 -:10363000FF6688757D56FF19405425BB8D71FD0AC4 -:1036400030DE954A8FD04BABF0838D7C8FF349B73A -:10365000B05F804FCEF6A0DD52F8E6D17AEAC5ED34 -:1036600016E75CB94286F3FA004ED02CC5EDF8643B -:103670007DA6DE3C44724D9747BA7CDA85FA8C12FF -:10368000A7A77CCEB958415B80E4B6941320BC0157 -:10369000FD4643BA31637C3805DCB608F84B99D354 -:1036A00035A497C6F38305F8DEC18CB70B5882BFEB -:1036B0004DE7872F7EBCD786ED1FB6355C546FD1A2 -:1036C000E3C7A3C58D33EFFAFD9712F596D1E2C893 -:1036D0009F143F3E94A9909FEE11C9C897BA043F2A -:1036E000FA9AC00B6771F02B88478F48011FE98D4C -:1036F000C29FE22D0FDE89E733BE47616138CF8379 -:103700001F4F75217E5C2A7C753F7BBED0A7F21DC2 -:103710007B25A4D3FCB688847EF282B65EC97F91F5 -:103720007E8B3C9C9EF5FE1631FE55F29019E5D538 -:1037300055828E0BCEC9AC22410F5CE0E1FA944574 -:10374000E8EF99879EB0E178874C819E32940F997B -:1037500026EDF1047AB7DC5A6B6D48840FC67F52B0 -:103760009CDF773DC37A17D947BABCB5E8722247C8 -:1037700036C889503AC75B5DDF095DCEED21490A45 -:103780003E86F03E7DF9EFAF4196755AEA55304ED0 -:10379000FE49F18F61BDC61459A1DB31482F3E5956 -:1037A000FDF120BC3FE93BF5440F535890CA698CAA -:1037B000EB7DA0473DE321FD0E969C70BE0C5D0F96 -:1037C000799FBC8F473C5CDEDD2BC7C8CF7AEF7991 -:1037D00089F878327CFEE8D1FD5AC371BE8BFA4974 -:1037E00035F493BA316E65F463D61D33D6A7C48C15 -:1037F000F5692793FDA2FE5F24FA451F06BA427EB3 -:10380000A0FB410BC3917A15D65BC47A296E58D0C0 -:10381000E634C0F54AB3C8A7607E29D13F5B202FAC -:103820007807DFFFFDF0B98749CFBA45B4FF43E31E -:10383000CAAF74A3ED3CEC67D5085EFF3077D16C5E -:103840003CD7647F6B514742FC918DF4B3DEF2B0FC -:10385000C5D01EF04F223B60F112A37F96D691CBCC -:10386000F75B503B72FE4F9E17FE3947CEAF8FBBC2 -:103870000BF80DF251761ECE752AC28DA1C78115A7 -:10388000C95109E3D7F91DCC8FFA70C15AE64F151B -:1038900007282CE578900C6716BE8AE0374B3CCBA6 -:1038A0007798C94ECF5F6B223D301FF801F2816BD4 -:1038B0005601B940BD6095467AE4B56D26867280A2 -:1038C0009DEF34BC0FCB257FA77EEEBB703CD4238D -:1038D00057B38809F7D33191E889D6556CF08BBF7F -:1038E000C9E16525785D3BDD62F06B16A11F3301F0 -:1038F0002E3A1E14243D7FC1A31AE802E45961291F -:10390000E13F9773A528E76049EFCD38B917F3D9A0 -:10391000AEDCC068BF4359F608CF93188E27982FA6 -:1039200094037FB2CEAA40BFCA36D56EC27C8683CE -:103930005983DF62598CD594B270E34CC6FED93EF0 -:10394000542541FDF2D24777F4C0A11CB40D7D1778 -:103950009DBD0EC7938B9A3E17AF67661EA43A9B18 -:10396000CE3419E063C719609F7675DE3E33CC6FA5 -:10397000F73AC8096967C3744AFBE9BE5CBB07F341 -:1039800041BA4B4DA427B1C476D8C7774A553DBF3D -:103990008CF2DD58138FEF278E2FE75C64FC7930B3 -:1039A000FEE44F31BE95AF3F0F1F817CC9C3F5A325 -:1039B0009F1AC7C7F3456751E2FC623C998577635C -:1039C000FC05E673487C3E15F34DF29831BF6078F4 -:1039D0003E15E6ABFE3BECA779E479582E761ED770 -:1039E0007FBAF3E836F969BDE11A07D93F0C9A4D61 -:1039F00053D1CEE0F3D964F6A25CCBE1DA3D350ECB -:103A000057D0F7685CE8BEFE8280B305E1AC2A04BB -:103A1000E7D1E07648E5F94E5B547B64BDFBFFC11E -:103A200079B9F87925CE877AE325CF773DCC97739E -:103A3000E9F3217C917E86E10B67B221EFD2E10BA5 -:103A4000AB0A5F0A7C0FC1B8A604B8C6F38A1E523F -:103A500051FFB75902561FF0DF03A53C5FD19BB35E -:103A6000C84A7906B98BAC98BFB7D1EB68C278DD8C -:103A700046CF12AB25414E6FF4B6503BF4A77C28DD -:103A80006FD48EEE0956CD6264FF6F99D9E85A81E2 -:103A9000F8D3C1F3ABF47C235D1E3211BFA47DC10A -:103AA0008B633E7760E810F4DFD23199F2C9C664C7 -:103AB000FD89F2A8B6B5F97CD8FE2D8C33813EF194 -:103AC000A0883321A2921FADE6F247312E5B5BBA8C -:103AD00046C2748EC25546F9949F94A7537B26D64E -:103AE00080F9586C05CFB772B5C849F2D048B7DB3A -:103AF00010AE3C2F2A2271F81AC6FB3D32E95CD485 -:103B0000EFF730B4EF9E85B1CC46FA32617E523287 -:103B10003DCA8A5FAD47BD7C8D89D65180217F101B -:103B200071B5D5F35D2BE079E1CDB24F82E763BD8E -:103B300077539E1268F5A46F78BDC71BB03E629F95 -:103B40002B8DFB48DE57F2BA4170911EA29F57EDB4 -:103B5000195F3ADA51B5A58B288F8C7E747A372796 -:103B6000ED271BED5F93DF0672CCEE49D81733F4D7 -:103B70001376DA7F6DFD242213D25172FCEB6B01B8 -:103B80005A671AF359157AAF85EC453DAE968FB456 -:103B900083E73E9EF1B844F2FB53F9FBCCC5E36CDE -:103BA0006976303D81FEA4DBECE4BF4C4B833A9C4C -:103BB0008FA430EB3878BE4BF8FDD64B4CC67A7CE0 -:103BC000BE28E5A9774981ED3E3796DC5EB26405F3 -:103BD000280F11C3B48976E721CCEF80F635B7BA48 -:103BE000C7A2DF6E0C10440CED661197D2FD24992C -:103BF0002583CB517E1797952CB6A27C46C7D2E57C -:103C00008C5DB6B7E8FEF0CC385DA69DCB675A82D6 -:103C1000FD922677509E47DAB9F1067F4A54D85D67 -:103C20007ADD9F2337E27C73D02EC0BC26A676E3D4 -:103C30007BF500142DD13F7ACE6518273E7EA16119 -:103C4000DE28D8CF897180D1C74F675A45E2F8C5C1 -:103C5000A38C5F9634BE9A72FCF8B8D9867137CAC5 -:103C60009C5F8473EC9154FEBC95650D5797E58E6F -:103C70009E87F6C532E177B302CBC7B893C09BCD20 -:103C8000AE0ECA4B33DB797CD422E2258733DA8847 -:103C90005FB142635E5A0353656CDF9839E798045D -:103CA000ED0D0EA39E7ED5F937CDC877AE928D7AF5 -:103CB000BA9F75107E5EC98CCF2D85463E40BA36C0 -:103CC000FAFD3326C7287F2DD7417906A3F90F7E49 -:103CD000D3C928AFCA921EE840197777D9B4EC8DC2 -:103CE000D3A13E86E3D7D6B2F98BD11FF41B81C78F -:103CF0001B81EE118E2D6BC6EE36278CDBA2444B5A -:103D0000518EB498781E3FFDC0FCBFC9CD277F6A95 -:103D1000F2BC94099CE08F6AED90029E847DFC4683 -:103D2000D0C5F07C7714EC463D7678BEB4E8149AA2 -:103D30006F381F48CC97F7D9E67B43D0B33E5FEB93 -:103D4000578CFB6B5562B4BF561313F9FF7CBE371B -:103D5000707FEECF309FC8EB1A9EEFABC6FDB5A6C5 -:103D6000C5687FADC3F6A4982FEFB3CD97A6745066 -:103D70003CE63E899FEBA1BD4BEE477FFCD9F96B3A -:103D800034C437DD3EA3FB3366BA3F4372EFDA42F9 -:103D900085F4067DDC7D9DD3995FE17E1B2C2B662F -:103DA0004A740FA072BAE4C778D8C340F7FE32F461 -:103DB0004BA9D41EE97451B9A753A3F231B007FD42 -:103DC000E49FF251FD6C19B787EF1BA72E5B89FAB0 -:103DD00042BD9DE741CFBC0234D1B8BD0506D82114 -:103DE0001BE61B7E814DDA8A68BE93C323A7312F61 -:103DF00082E7649FF462AC13EA6933CC1AE677A7D2 -:103E0000B9592095DFE57D913FB359CF9BFF9CC405 -:103E1000E3EDA08FD4C3FE6F14A066E6F912EA5555 -:103E2000D77E358BF491962583192AACE30669D2A7 -:103E30002F3C008FFF2DF4911BC7733A4EB62773AA -:103E400050B24CC6BC3E732402BF2ECE584CF6E88E -:103E5000E2A58C39E1FD6BF13D902BAF087DE6E5E5 -:103E6000C13486F65AB891C7996FB8DB6847DE67E8 -:103E70008BAAA8C7DD372987E179B4AC35B66F16B0 -:103E8000F182C54976E5B5497934A065F27C10DC4C -:103E9000F30CC6DE2DCBC8A13C589147F384F00B40 -:103EA000B1C21C4AB676CEF58CC1F8639A92FA7EFE -:103EB0008E3E5E8EE03B2CC74F70D0F3CA99F9A9B5 -:103EC00049F4BE984F7F6F97F4D4B88BF935416FA2 -:103ED0007B6BB082CB67D4AF59B931DFE7ECFCE242 -:103EE000AF37B254783B24A35F415FFFFF2D7CFDC9 -:103EF00011EE17CA57667D3899DF432B6489F7CFD7 -:103F0000F47CAAC5C37599A15EB954AFBA86BC78D2 -:103F1000DEAF7D2EDDB795F04FE80FD1D74D17D22C -:103F20003FFD78C3EB70F98BB83F4EDC1314E38D83 -:103F300006E7E47C07DD6F433F53E3FED8AEDD3C8C -:103F40002F323FA7E11DBC3F85CFDF34E095F19EC6 -:103F500054D7C01312DA17DFC27B5F727C3EF4D3F2 -:103F600086497F35DEDF1A218F19BF97A3AFA74B94 -:103F70006115648F9A803FC07C0B1C83B2A4A1DFC3 -:103F80007D88EEF3DD59CECF057387F97D18AEE756 -:103F9000990B4C3C7F6382C6F53ECFD0F8C4B8D0B5 -:103FA0000DE55CAE2F487F75AD06F26F49F9938B36 -:103FB000313F69C19857D7BAA17E5DF97717CB8099 -:103FC000470B0A5EFDD00D3ADBB2F2A778BDEAD509 -:103FD0000F8BA1BEBCFC695EBF8211505ACBBFB72C -:103FE00018F9EA0DE5AAF0F3C50A71BE0512A78F0C -:103FF000CF5A9AD34C29E3F7FF50AEFB139905E74C -:1040000009F4FFE424F2A380EE7FF527C51BB12954 -:104010000FEF13899F9C4CD267E6E1EF00CFABE531 -:10402000E800BE6FB24609AEE59837534128F0C0AC -:10403000858BE44724E39104E8BA0EF5654D652DC0 -:10404000A01F77AD63415B49029E33BFC0739EC71B -:10405000A3AF479F7FC4BAE0486567E2BA1EA67166 -:10406000F4759D9E9416C67B677AFC545FD7696988 -:10407000E811744644AB0697E2B99ECE181A2F4158 -:104080005DAB5097503D77E811C99750B7F073BCBE -:10409000B7FC27A4F7AC95FCF79623BF541C74BF5C -:1040A000AD47E879DB728361C6F57BCA770C17F1FF -:1040B0007B038D93257F627CFF9B02BFF22A7839B8 -:1040C0003B6D7BC709C0C7D00189AD87FEA1F367EF -:1040D00015B4C717F49F52D0EE6E3F704A41BBBA79 -:1040E0001DEB304EFBC30AF1AB64781754980D7189 -:1040F00074DD9E385254B63107D6D3BE52F2618A6F -:10410000EC9AE7B366637DCD0ADC2563D7CFDC3F4D -:104110001BC9BB3530B011CB1BD9E0118C172C0B50 -:104120001AF5FCE56D46BDBCB5C3A84FDFB81D4E02 -:1041300007E4D78DEB0A0CEF31D490613DCBC47905 -:104140002E73DD1333D7603DE1BE8E44644DFE9D7A -:10415000E57C07501AFD160BFA25A2E3F6662BF94B -:104160005F8F14F13CFBD02A33E50585101DB0DECE -:1041700021097F969FF8A32EBF67F79D395A80EFDC -:10418000AFB2101C58D81F43FF43B3C0A71B9B9B63 -:10419000DE413C6BD66EE3727CC25E0BF957825CEB -:1041A0001FD784FFBBA5EFBE4627EA9F6B25F26FA2 -:1041B0002C6F33EAEBADF80BEA6FEBA448D48D70AB -:1041C00032B6DFB8CE587FBD5CC8DB2A568574F2A4 -:1041D000DB7249A67BC5A2FE87A25FBE1C8589EE65 -:1041E0009202A710EF5629D11A946B774941AAEB96 -:1041F000EDF0BC9DCB1D2EEF4D4051C4772DDCAFB3 -:10420000105E2D113E2E1F21FF13F403F3C87A4ECA -:1042100005F7B777D9026BC95E7A4152511F69948D -:10422000FDB2D31BB76793F13157E0F7CB6CD08B5E -:10423000EB2A43A003FCCB168F89A03FACEC9F5721 -:10424000507E63599DE433113D9BD8BA5A2C65E2E8 -:104250000FA86FDAA02C33F73613BFBE4C5179FE8E -:10426000A08B25F201FF134C4278E1D271DEAB0B3B -:104270008F7D8CE778CDCE7BCE20BFF394F86BEFAB -:1042800083F56DB3F1F9B73D2F91FEDAEE3D4A7C2F -:10429000712CA009CEDBEE12FCB10FF8A3BEFF62B9 -:1042A000BCD70FFC0A2F8ECCF7D2BCE3F4F8809E6B -:1042B0005F1B6D305D00BE3356CC5B50A311BCF26A -:1042C0006EEB9570DF452CBC1EFD44328E991B2F82 -:1042D000753FFED278BCFA9B789EAB5D830AE9DF1E -:1042E000225E9DA2DFEE94FDFCCCE047986D3E9FE0 -:1042F0008971E5352F945C34AFC26C3519E8D5A2CD -:10430000DA0D747D758591CE17F88CF47DEDF4127D -:1043100043FB427F95A17D71539DA1BE347085A161 -:10432000FF75CDB38CF6BE6B9EA1BF4D5B64A8A795 -:10433000575C6FE89FE1BBC9C86F727A297F40B1B3 -:104340008607831ADEAF676CBA33CEAFAB32AD9857 -:1043500064CCEC753607963D93D2A2786E3DF93C5D -:104360009E9AF6D2975D5184FA98A7ACF5507E5785 -:104370008A3460BCC82AECBC897733033FFFA72A84 -:104380008EE77AB9A42278632594DE7D5A01CF970F -:104390008E4DC4F3B1A20311F1F8392BE91D972515 -:1043A000E9BF4535F5CB2AF0BDBBFD73C92FD5C795 -:1043B00054BC57BB47E1F94CE1E778FEACB76FD08E -:1043C000E44FA0B7FF53C1E5FD37020D949FD4DE43 -:1043D0000FD20CF17BE79B0AFAEDDAFB0732516E44 -:1043E000D404DE5450BF8E3F17F2441EB263FCF279 -:1043F000FBBDA9F3D0BE51A1D0F84705BF6DFD327A -:10440000E7B78070F3D13ED2F967EB7EBEBFD6A589 -:104410000AD1B7CE47817F1AE261C97C79F9CCC84D -:1044200046A45DE0A306FBE5C62573DE417B0824B8 -:1044300035E931C0478DED859B88BE6F4CB26FBAB0 -:104440002A86F9A9F702D0CBC98029E5BEF654C95E -:10445000B4AF93C15904EF6F00DCD06EFCC60838CE -:1044600071F87D127C9E16FE44FD9C92FB7DA78A0E -:104470009FD3D3A3F0CB77059FDD23C56A919985A0 -:104480000276C2D3E556EB52CC33385AF4D1268C9F -:1044900027B4FE40425B96FDEBC04B799877A0ECC9 -:1044A0003F9287F910A1DE23790CE0B4CAA2AD4790 -:1044B000BD18F0C0B71ECEA5BD2F4AEB5FDD5B3740 -:1044C00080CF57F7493E6485A10367E6D03ED9E027 -:1044D00026D4E3F78CB2AEFD153CAFADBF42E37915 -:1044E000F7419813E5EC8134B2635BF7031FC275A3 -:1044F0003D2FD13D8C3D5BACCDA9F493A7AAF877B5 -:104500001B5EDCA2308CA3AC82F7711F478B8E2A16 -:1045100056C49BFD12D984A1DE134BD11F1F5A6BC9 -:104520006118B7D5D7F75E51ECB7B8FFD7575A180F -:10453000DE2FEC5AC9E3B1AFAF35D338E69B2D542B -:104540005F762BCF133EBCF2DF3615C0B8AFAF920B -:1045500028BF7ED6CD7F3C8AF565B7723D28197F8E -:1045600087F135093F97058D7837024FDB3E1B9E5B -:104570009EAC10F66B15AB41390BE73E7B2CE2CFBE -:104580009D8CEE37369F3F6C190BEB2DDEA4FA3075 -:10459000B45B6D8E6CCC43BE7098B74F5AB55BE27E -:1045A000FC45A37BEF053D0A43BBF15D715EEFE285 -:1045B00079E5E2D68624CC6B6372AC18D7E716791E -:1045C0005CCF5858F37EF423C99CBF54FFD0B53B51 -:1045D000D18FB44BE0A3CEF7AAC0DEDF4F7EE8DE7A -:1045E0007CBC8FFEB485FBC7C68BF14A4B86E62C9C -:1045F0008432BD92CFFF47B10EBDFE9CC07FF687CF -:104600004709BE0BAC1CEEF3D6455B701FB7C8C1A3 -:104610003F23FF9B3FFE97AB50AEF514FFD44BDF1B -:1046200065611349AE85C4791C9EF1EF0FDF81F9F6 -:104630007695763AC785871E8AE1B9B67B64CA3318 -:10464000B4954E1E1BBC881F21744E33DCEF6BEFFC -:104650003F33C79F82AEF757F1FD578B7B7CAC9FF2 -:10466000FB0F801FCBD36BE3FDF4FDEB7E0F5BE90B -:1046700063744E777C894DE2F7FBEFA37196AF3AF6 -:1046800021E1BD94EB2C7E8B03E0FCCB316C29DA6D -:10469000C13FED64744FED38DE570356F272A74AFE -:1046A000F598B8B7F66AA746E5754A603CCA95A57D -:1046B0002F769422BC0E173D18C0EF359C3E2EF489 -:1046C00059A6F2FB8E02F7CEF69B9915DACF1E9013 -:1046D00022E43411EBBFE15C3E0B023FF9B5B81F99 -:1046E000B77ADDCF89CFF9DACECC413B63D2AA537A -:1046F0009BB01E5AF7C739A837FC16E404E257A846 -:104700004F622E18A7E59C93DE5FDD7742417BFE6A -:1047100069D3D01C847FF8A044F7AA421D67887F24 -:104720003E2CFC2B37546671BED13FC944E7E99F4C -:10473000C8ED1371FE0313FF9489FCCBBA4E7BE5E1 -:104740000A3CC763663AC7AD0D43996A8A73390953 -:10475000E3A24FFBD7221F2FB9BD5909935FB6596A -:10476000E06D72FBF59526DD0EB7883C2526C17AF3 -:104770005A047EB532FE9DA0963E296A07BA6DEDB9 -:104780009F45FE8DD68E8B7F0766347CBBD4B29D51 -:1047900071FF865E47FB2B315F0BED2FE37DF5301C -:1047A000E1555A91676CF022FA5D68309FE227ED7F -:1047B0003D8CE225ABCF4DA4F2FDE737D3BD27AB4F -:1047C0007DE841940BACCC447AFDEAB051BF992D01 -:1047D000E876B6D06FD654827D52C186ED13B043D1 -:1047E000BE5CC9ED90CC43CC609F243F27FBC42A1C -:1047F000FC86305CF09914EB9E57D57057652ED22D -:10480000D576C26F06F88D7895BCCF8D959C3E7598 -:104810007A5E76E81D05F5DD505F6A7A5E5A55BF0F -:1048200011D7B36594FCBBAB05BDAFDEC9085EA173 -:104830009D4E82D37B6C67A001F0F23D5807DE5F8E -:104840003F1D08A467C1FBA78381748CCFE9F4DF07 -:10485000BED34EEF6DF12CCAC6EF6DECAAE4F1F3B6 -:10486000F7FB665911CE37ECE474A7CFF7DBE8B25B -:104870006CA49F29962105FD9385FDA73251AF9B1E -:10488000F2FCE26CA4BFD1D6B975A258E7BAFCA578 -:1048900074EF077ECC40F7B70B3916DA105510FECF -:1048A000B7AF6384BF03CFFD6B3BD2EFFBFDE92ABB -:1048B000CAC9F75E480F23BF3F7D302D6282A156E3 -:1048C00089EF24BD6719BC86F4C7E7CD94AF103AD1 -:1048D000F8EE83488FA1E7D2E81ECDEDFD9BCFA077 -:1048E0009C5BD53FF71D19CBA7FEBEF4B07ADDF86F -:1048F000A589F9C5EF76EECB47FEF9BECCF9C4ED3C -:104900007DCF923E7BFBF9B335983FF8DE0B7F9E5F -:104910008AFC2CF4CF67A7221F0BFDF8EC546C0F18 -:10492000FD30BD23957EF2E32AEE3FD1E5A3FB35B2 -:10493000D9E067B959E087BB7B7B137ECF60CA891A -:10494000251407D0DBA794F27BCC537ED1987D73DE -:10495000C27BDD3199F225269F684C5F998097D7FD -:104960005759747FCDA5F947441E82EE1FD9129383 -:10497000F9BDBA36337DBF6E798CC7DF93FD268CC7 -:1049800005AEAEC6F3BE35D787DFF1C1FBEB181716 -:10499000397D676984EEAF87AD473C097AD0B2981C -:1049A000299A867E90FEB428EA43CB62F2A9B40429 -:1049B000BFC86FD56736A21ABF2C68F46324FB41C9 -:1049C000E027434E889FB4AE8D5A7439B500E6FF98 -:1049D000E546A662DC66847FA4F9F3E48749F69392 -:1049E00068B107ACF89EE6E1DFDDD1F54C3CAF03E2 -:1049F00029E87DC344CEB7743AEA8E99E81CBA63BD -:104A00000D560F94FF28DA0F80D80C635E50FFE23A -:104A1000C7D14EEF3E7F5D3AC2ABFBB5450CBF2B15 -:104A2000715A6DB096E27BE73F6F5DEA8DE3C70890 -:104A3000FE3191F3C7617D6014393753CCFBF79297 -:104A400077D3279A84BFE1FF6F790776F55513B9BD -:104A50005DBD9CFB3DB85D9D2C2774FEAB8F1B128A -:104A6000F01EC97FDF21FD05EC5FE2BFA1891AF5C9 -:104A70002BEC5F984D76F16B4BB235C7C8F14B64A8 -:104A80009FC9E91D39BEAEAF85C2FE2356B463FC93 -:104A90003CFF34B444A2EF4B850212E9D9A1164B76 -:104AA00004DBF5F5C496F0B8E0529F44DF0BD1F576 -:104AB0003F5D3F1C6E9F0CEDEEB8BEA8EB85B100CC -:104AC000F78B2EF15BA8FD3A25780BC2E9B7511B95 -:104AD0003D9F32838F0B7CE008FA3FAFFB8244DFBF -:104AE000F3D2F5451D3F93F5C90FFA4B2EFA9DBA47 -:104AF00087055EEAF4353E892E7439B5AB92C3A7BB -:104B00001DE57436CAE98F9541C7E87A37C8E9BB15 -:104B100070FDBB2A19BD3FF917722095DD9D21C696 -:104B2000DF8AE7066561ECC57A5C6F118B515ED454 -:104B300068F2F3B62A4E0FA3B5EFAABC343AFE8151 -:104B400098FFEF45C7FB27FEF7D05B87F53F25F5BC -:104B50003EE755D5FF6822C0D56EEEA0FB51EC5F55 -:104B60002CE4B74EEE1712F218E499018F8F142936 -:104B700026B47B426DDCEEEFC9D25E21FBE4257EDC -:104B8000EFFE7691AF74DB3995CA1EFC8018B67FB4 -:104B9000D94D7E9BDBF69DB0F8E1FDE56BA549E8BC -:104BA0000F5ADE66DC4F4FAE7F6EA21FBC675C2FD4 -:104BB000C515C28F9768387E2B6E16FD213DF91101 -:104BC0008C3DB6A31FE7327C9E70DF02E6592D9E16 -:104BD0005F21FC3B2C490FF8F1C0EBE4EFC1B810AA -:104BE000D2AFD22F515E48E818F777B4F773BEF012 -:104BF000769B44FCE46D919F115A6723FFB6AE4744 -:104C0000BC23FADD7AA744FADE08BDC26F8CBBACC8 -:104C10007EEC17C41793F508E7013E0EC65BD02F54 -:104C200073A468AA84F5D56017E2F74B439A766DB2 -:104C3000015F1F8B107FF11BFC281F1CFB37B22369 -:104C4000973F2FB16CD23B92E22F3DF392E22F4778 -:104C50008F14E03842CF50E13FF41F26EB19ED7D71 -:104C6000272C68177C529C45A91AF6B7905F708272 -:104C7000CCFDAC13FA2515FD4913049CA66DB113A8 -:104C80009CE6BCB1321BE95C3F9FF717F2F37AFF59 -:104C9000F50FEBF1BDA96FC82AF2DB1FBFBEF6E727 -:104CA00005BCAE59357C6F6D3ADA21EFBFB1261DD8 -:104CB000E1F86328F13B4A3F3C29A7F41FAE15FCFD -:104CC00008E45B4115E6DBDE2DFCC632C8B78CB8C4 -:104CD000FF25F9BD1DC21EEBC1EF1B21FE3DCFE339 -:104CE000DB3DE382F3A8FE5031CF239639BE3EDB95 -:104CF0009FA5A2BE57059BC538ECF7ECAC1BE32B78 -:104D00003DB9C19F127D3C6422FC85F7F97727F6F7 -:104D10006B24EF106418FFA8015963A5BCC61C8A58 -:104D200083E8DF85190776A8F88EC2128CBB5689F6 -:104D300038488D9DC938FE364B706B25C65D0664BC -:104D4000DF7A7C47F665E3F79292E3317A7C588FFD -:104D5000CBE871E2D1E23212CE53C3F12CF13B2702 -:104D60007AFC857D81E76F764DEFA0FBAF63B12FB5 -:104D7000F1CF11F194D5686F26C753EEAAD4FB1B6F -:104D8000E3695B2B9E217CFBB471B41F4C1C6D7ED0 -:104D90008D9E27CF3F39EB833CB25FFEF21F9924F3 -:104DA000CFFACF92DC393D9426EE710E723F75BF7B -:104DB00085ECF5D36007E526C8B35F55F2710FF5B2 -:104DC000CF227C3C106B4CC7FE7FADE4F0D9F2DA09 -:104DD00092C5A84F876332CFC766DCAE391093A760 -:104DE00070FD60049C364D4C0127AB3D751ED054C0 -:104DF00081D753ABF8BE67BDCEED95D05A1E3F505C -:104E000005BD859A14E227478BF224DD8F3C365589 -:104E10007CE1F921E2B3ADB7F2F8EE25C717FA0647 -:104E20002CAC3885DFB6690EF19B4BF5D732B482D6 -:104E3000A7C6F9F3769D9F5473FFADAB8AE7F33BAA -:104E40003B26D5E377F1F47DA78023F35E5A9C2FB0 -:104E5000B3FAD2FA2DACB8B47E9B2B529C5F8A7EFB -:104E6000DFB8C47E3FB8C479D353D1578A7E7FBCA4 -:104E7000C4795FAAFC9FF8E7703D39BE991C0F4DBD -:104E80008E73A6BD747318DB364BF70C4511BA99B7 -:104E9000CF35E3F7D3E5ACC7ACC8D7E6CFE0F180B8 -:104EA0002D8DD6C86E291E17D5E1F55135D7BB54C7 -:104EB000EF99307E3F71BC3FD6980D747C7A062303 -:104EC000BBE1B44D7C0F4956C72DA4F353E97B38A1 -:104ED0003DB6D4F1A527C578A3F191A29AFAF3556E -:104EE00053E8FE50CAEF54DC2FF440B58F91BF86D3 -:104EF000C9DAB84534AF360EE5CC9817F9F3CC28AB -:104F0000A3FC3E68772F22FD5973E3FA7688B897A1 -:104F1000735E991BFD744E90B71817B90FE323E425 -:104F2000D757A99F3E5F9797CFB7C3C2248C63859D -:104F30002B795E056BE935C4358E5BA2BF5B2151D1 -:104F40005C632CD2FBCF4C51EF1E373F1784AFF779 -:104F5000804AF19697677CA782EEC58B38C71D2AD9 -:104F6000EF7218ED0C58C71D2FD411FE2E3F34E3FD -:104F7000572DA80F7A6482F3083D5CD85727857DAA -:104F8000A8DB5783682726D81B555ED3687CA92ADF -:104F9000155FDA2171FB37FC336EFFD629BE92C450 -:104FA0007CAA69021E2BA2DC0FABDBB535FE88297B -:104FB0000FE05077A7399A06B2B76E53B582FCBAA4 -:104FC0006E53919DFC4A2BF79B7478A73AF77AB100 -:104FD000CE2DC786282EF16CF23D732F8FBB0E09A4 -:104FE000FCE9C2B385FA1DA572178ADF3133557308 -:104FF0002ABF782BE8FDB8BE153D7CBD7A1CA435D0 -:10500000AACDC2794E1D19DA84656D9B7B16F90D08 -:10501000579DD984723374FEECD1ABC80FA068A938 -:10502000EE0B586BCCB48E6751114178CD95296F3A -:10503000B76EAE4CE7ED6CB5911DEEB430337E9F8C -:10504000D5B990CBB1DAA69C5958674BB2480ED768 -:105050001ED3B26EF6C6ED7CE7DCB5B908A74F8A61 -:105060000FE9FE82EB14FF4D788E9F363EB4FAF8BE -:105070006B946776C3A0313EA4C77B468B0FE9F1E2 -:10508000D950D387867872481E9A837E95BA174E78 -:10509000517C38D427A92E773C6E143A704621F8FB -:1050A0008A7811F457F0BD3A38F6714EFCDE008F65 -:1050B0001F3D87F9B80A7E4F4FA5BCDB1F613E6ECE -:1050C000197E4F8FE7E31EC47C5C05EF7FF07CDC2C -:1050D0004322BF37D47F86E24D3D5E63BC428F479B -:1050E000DC2505B679730DF10AAA27C72BCC766E9D -:1050F00087868E59E8BBE8A1E356E2B3F5FD2B267F -:10510000A03EA67FAFBC1DE30509FEA5F7FD3E1B33 -:10511000DEEF793FE0B3619CA06EE01D4523BE1336 -:105120002DC014A67639A6A0BD8F70A03CBFFE7A14 -:105130001BC2F513FDFA7DFFE3D7FF347EFD8C38EB -:105140005D12FFA80D98E85E79ED31BFEDE604FE33 -:10515000B025C0FDC35B3CC5447F0F048AB356260F -:10516000FAF19BB8FDE69CEBB1253E5F54C3EF0F0F -:1051700038A5D4F70B5EF7EAFED711FCF6756F4A37 -:105180007D27753C604B13E723BABF7F647CC0F773 -:105190009227C1CFFFFECFACF47717069E4F23793D -:1051A000FED10B697B50EFAE6D5A392103EAB5276A -:1051B000D3989BCB23435C617993C96FCB4C154744 -:1051C000F017D0F74293E3054D26E2EFC3F18226B4 -:1051D000F914D5857E7EC3997FCFC04F643F2B45A0 -:1051E0007AD0BE7876B5E41B6023E3073070019B6C -:1051F0000EBB68E27682AFD94A76C127C5155A0E32 -:105200009CD8887E82496C7B0F7E7F7292C7A48275 -:10521000284A1157E0F99DB5428F48F60F207EA02D -:10522000DC4FF60B665673399459CDFD983B51AF60 -:10523000CF8D8FA3BF977CEE5F147269343FE3621A -:10524000D1DEDD54BB05CF2D3CDFC490FF77373571 -:10525000583D09E3B9AB79DECC0E8C53E424C62962 -:10526000783C22393EA1F3A7BA818FE7E0B93FD05D -:10527000CFFD472117F767D61DACA77B26F17572C6 -:10528000FC7CC0357CCF308BF17D312BF773915F87 -:10529000A176FE8787F0EF12B04016FD9D83D07196 -:1052A0004F9703F9C87C798AA4917F7BD8DF8DFE64 -:1052B000A8C5AFB4CDC37CE0BAA5934EE0B92C6DC0 -:1052C000B150DED1E2579AE9FBE3BABCAA5BBA7BE4 -:1052D00003FEDD9AA51592CFA6617B5303B65FFD51 -:1052E00054143D7B6C01AE0EE825761C7A17937F33 -:1052F000BBBE1AD65BB750F8BD5BB85C5DDABFD0F9 -:10530000C23F6E659473878B3E22BBF96C7F1DF99B -:10531000B3B331DEEA8DCB99BA1740FE64C4E5CF52 -:10532000DF2A77BE58CDEDC0CB40FEE07A9C0B79EA -:105330005C30F9FCDDE2FC479327A3F14F941FFC9E -:10534000EFF2840B24575CEE6A684F4F8BCB5FB54E -:105350000FEA6347C7BF87847E95358AFEF580C014 -:10536000F751F335FAFE3E7EEFEDD5FF3DE257BA39 -:105370007DA3FBBF757BE8F702CE7AF9AEC08BBF89 -:10538000395F198562CA7C6567EA7CE51B7A25FA74 -:105390000E8BC8573EA2B0FAFD3998A727EE2544D8 -:1053A00002A4DF1CD9F5EB4D4FE4E0BD044945B143 -:1053B000B3BAF704C9E7D5A0CF901ED4FF2EF74BA0 -:1053C000F5F2FCD2D57DC6FB0F7AE9ACE1F1F646E9 -:1053D000D80FF991451EDF9C039CAE437E25A2B9F0 -:1053E000D12FF41539D12F14D262B97A7E6084CBD3 -:1053F000A594797CED6C88F2FDDADB241FCA83CF9B -:10540000EC27F2F3FCBE4BF513FDBCDA987F7AAEC5 -:105410008ADFFB690E4A12EAA356536015E5F71EB0 -:1054200094D45479A2EF087973B5F0D3EE55381EB1 -:10543000ECBD5CA2BC5ABC1783E7BBF720CF9FDF53 -:105440005BCBF3E775BFAC9E175F19F7CBD27D1826 -:105450003D9F5ECF8FD7EF872EDC698FA27EB1CDC7 -:10546000D2EB423A1CFE4E0FEA22D06E17DF194FE4 -:105470005EE72FAAEB775553BF51F59B3F56A7D058 -:105480006FFCC24EFB73F5A87AF95FAB8D7A39D504 -:1054900093F5F2FF2ABFEC37C43E53F9D552EB67C0 -:1054A00023FABD7889FD7E980A1E5DB6D4DF0B6DA8 -:1054B000AD11FC37E9EF92B011F77BB87CEB91B4FA -:1054C0005F5D41712E0BC5B974FED293C1C7F78AD7 -:1054D000F1F4F2F3359CCF8CF65DC945A2DF5AC9D1 -:1054E0005F553305BF1F6FF49355F71AFD6497F5A9 -:1054F000390DF549D17C43FFBA63C586F629B189D8 -:1055000086F669276B0DF51983971BFA5FF1768391 -:10551000A1FEB921A39FECAA738B92EE1D71FCAE84 -:10552000078C487C6F96F58B867E056DC67D15755C -:1055300018F735619D715FFAB8EEB0717F253DC6F1 -:10554000FD39D17FEFFDECFEFB9857E3DFC1E92F7A -:10555000A1EFFEED68F2D077AEF5FB7FFF09FEEF1D -:10556000D922F072000000000000000000000000DE -:105570001F8B080000000000000B53E16760F8512A -:105580000FC15BF918182EF021F8F4C01CCC0C0CDC -:105590009C40ACC8C8C02001C4FC40CC06C49E0CD2 -:1055A0000C0CFF81F81B10BF05E22740EC0CC40770 -:1055B00058B09BE3C6CAC0E001C4DC40B378988908 -:1055C000B7DF8917C17ECCC3C0700E889FF1D0377A -:1055D0000C061B5E27403FBB7E43ED3A2932F0FEAE -:1055E00006612131609A1447F0A78AA3CA0B8B2168 -:1055F000D8C9D294D9950FD40F00F19321F080032C -:1056000000000000000000001F8B080000000000E8 -:10561000000BED7D0B7C94C5B5F87CBBDFBE92DD45 -:10562000CD26E44900370960501E4B80C84BDDF0A1 -:105630003252C40411828A2CAF10027914A9A5FF3A -:10564000DABB0B2804AADE5851A37F6A17041B2D6E -:10565000DA80D11B6DE02EA208D56A684551AB0DEA -:10566000888808498C8F6AB57ACF3933DF66E7CBF3 -:105670002E89B6FE6FFFBF7BC3AF1DE79B993367D3 -:10568000CE3973E6CC9999B3268383192E60EC1B2F -:10569000FCBB9C319B893136A62B6D573A86AB39C2 -:1056A0005DE5B7F9BDCC6B66ACCE6FA5748B3F9D45 -:1056B0007907C3779FA1306867EC5EBF8BF2BFF0BC -:1056C00017525AEB2FA27A77FA4B287FBBDF47E9B4 -:1056D000667F197DAFF157537E837F0DA59BD4451F -:1056E000692C05FA66458559C98C553D9393B719C0 -:1056F000725B668D4F504743FE15233366017C9FD6 -:105700004AFD31D5BD69E0E8AE7A1A9E9BD449FDC9 -:10571000104EED128E17B3325B8C7A5938CE3B9710 -:105720000878F6D69A9CE4A8F50623BCDB4B00DE8D -:1057300050287085AC39D1E15D8CF03697A8BC5EFD -:1057400072B0263B3A3C0FD6ABB941C04B0F586301 -:10575000D41B83F536DC20F0EBE7ABC98ADEEF78AB -:10576000ACC75CEADF5AAD8CFEBEC9C6FFB7BB4E04 -:105770005D2CF246CC263136AEAB9D3E652CC0701A -:105780009C2AF315121FDC995F7F93CFD84D081325 -:10579000DA0726B19011FA0F24B1E0FA2CA9FE4CD9 -:1057A000AADFDAF7EB6F52A5FA014394FA26D6A0E6 -:1057B00060F9CF518E80EFF7F97329DD28E4E7BE59 -:1057C000A106C6B05DBA393808DADDE3F790BCDC73 -:1057D000ED1F4BE5770939FC7721674121670FA25F -:1057E0009C41BA15E5CC8CFDF95A4B014EFBDE7895 -:1057F000B6D94DF2B598F05419C1DFB077C8F6CDDF -:1058000000FFBE1B569DDE06F46F6B1EE63142BDE7 -:105810007B866AF2C5BC2CB9ABDE3DB34F38170DA1 -:10582000257A97219CBB3D827F2A0C2CA2DEDD339A -:10583000C2F52AB0DE5D9E30BC5064BF774D09D7FB -:105840005B457C56584983BD3B5F763085E623082F -:105850000AD1D784F48579F9EC80EB9456689F924D -:105860009C97C6A0DDFD381FCD38EFDC4417AD3D59 -:10587000D2D907DF332CAC1AE10365F71B015FD3E4 -:105880006C7722D2E5F66B8B98328CB1BEA23C3598 -:1058900050A464015CFB9C2205BF9B6643397C7766 -:1058A00089F2E435BCFC762C7774952762397C4FFD -:1058B000AA8672C8DBE7F2F23BFCC089C15DF5360F -:1058C000019F7DC4EF74FE1DD88AF4318DE6A98650 -:1058D000F713282440BF83988EE9C27FD3A07B337F -:1058E00016DABBF0B50DAEA7BC86DFA6C17194D7A2 -:1058F000F0B15DD82F6321A47D97F465DE5C311F84 -:1059000058773A277AB3A5F24CD593A0029D325F1F -:1059100032B200B02013C413E1E9DB153103E1D941 -:10592000E3FC4BEEDDFC330D95E9A0A547053D34C6 -:105930003A6CEC2FD3C13240A6C3C601321D2C17DE -:105940009C9F0E3B989BE81C8B1E5ABF9B87C8FDF3 -:10595000C65D24F7BBF922B9DFB88BFF39FDD664E9 -:10596000C9FD5AB3E57E6BB2E57EAD39FF58BF4C39 -:10597000F5C064407DA5FD5D28E9B7AB99EF2CB675 -:10598000473D87F349D373A6641FF3D9BBF809EBEE -:105990001463F99170064B7A15E07C8AF5008EF756 -:1059A000FC705C3A3883F470BE16F8B0483DDD0DEB -:1059B0000E1BA81F8749E1ED428688FE99EA6345E0 -:1059C0008EC8761E5DFF39FAFE9D8A1887E1BCFD00 -:1059D000BB7574CDD6E39326F06186F3D183B97499 -:1059E00070B2F470DC029F90725E386EFD382E1437 -:1059F000FD071469FD027A0CEB6AD70EF8D13A95CF -:105A00006709EE04FD10DAF7E5295C07CE355EEB99 -:105A1000B640FDFD232DA1CBA1FC5CB0206881F236 -:105A2000C94F1E75A21D53F1A451C572C33E1BADD3 -:105A30002F6D3B142AAFB2B4DC3901CA3B9E34B29D -:105A4000EDD45DA601C7774AE81416E2F9521BCFE0 -:105A5000566CDB7F23B62F6BB2301BC0AB787AD984 -:105A6000CC09905F76C8C4B04AC5CEB5E6BE905F9B -:105A70001E541A300FF8D23A15C8B3057742FD7597 -:105A8000FBBE6C43FCCF359A06213E67609D70C318 -:105A90003AF192A3257536D0A73CB87B1AB62FDF12 -:105AA000A57840C301FE3B0F6620FE8F281E0BB079 -:105AB00070457D3C7347CC97538D461AEFAA6D4ACB -:105AC0009001BC65AC761AD2B302898378782C41F8 -:105AD0009BD235DFCEF8EBA83F2D5FF108F407ED40 -:105AE0002B1F573C38E44A03F3E13C6E7BDA56F255 -:105AF000901DC7BBD63CD881E3DC68C67ACB820B4D -:105B00009FB2B911CF6DE66988EFD66DE6D2A14894 -:105B100047B6A06828E2F77F65FCEA8C5E1CEFAA16 -:105B20009196ED46C083D943036739BAEBD933B0B8 -:105B30005EB923D6CF72067A9FD6EFA0B97858D730 -:105B4000F72F0D89A43F56D41B99DBDAD58F261F7A -:105B50008123423EF63A88DE1A3F57B9F814D0F84E -:105B6000B92A51F057EDC89F35AC3B3E77225FC84C -:105B70009E7651FA0B583731DD02EB3CD2EF5EB026 -:105B80009FDC64977BE8FB03602761BA15EC244C2B -:105B90001F043BC92DEC24ACB71DEC244C77809D31 -:105BA00084DF1F067B1CD37AB0C7F1FBA3608F6331 -:105BB000BACB1FA0EF8FFB6B286DF0D752BA07F955 -:105BC0000669A33F48F59EF2D753DAE46FA0EFCF02 -:105BD000F89B28BD5DD0D1399115E03AEAF432172F -:105BE000923D6986B7C004F9A4229E4FBD21506042 -:105BF000867CAA0FF24097BE2B430516C8F7ADE688 -:105C0000E5036E6193AC901F10E0E5D9B77B27D90F -:105C1000209F5DCBCB076F0D4C8A83FCE0202FBF0C -:105C2000685768523CE42F6AE0E5C39BD9643BE4C3 -:105C30008787783EEF25EF6407E4F35A783EFFCF7D -:105C400081C94EC8E7B7F2F6E3CF068DEE28EBEF39 -:105C50001E937B31AA9C03CADB5E3503F266F74DC7 -:105C6000A8128F2AA728DF68F252F9FB4ABB578592 -:105C700075BED1ECA5F22F94CF29FF94C947E5F169 -:105C800006A580F2661F95F737C451BEC914A0F26D -:105C900011863E3C6F0E507981A15F01C27FC61410 -:105CA000A4F26B0C8378DE1CA4F25FA8C30BA640A1 -:105CB000FDC70DBEBDA8EFD62BBE32B40F99DA904A -:105CC0008EFA4AB32B77E2E0D0CECC30D33CD8F377 -:105CD00087FC87681EE05F32E64B1F46BB14E01C62 -:105CE0002438268063EC194EDECB632538792F9754 -:105CF00069705E2138B6DEC1D9F3F278199F97CB6F -:105D00003538C7088EA377E3CA7B65A28CCF2B2BCF -:105D10003538C7094E62EFF0693C2AD3A7F168987D -:105D20003E67707D589FD23B7C46BF26D367F46B9D -:105D300061FA7C4CF864F40E4EE36B327D1A5F0B13 -:105D4000D3E72B82D3BF77E31AFDBA4C9FD1AF873D -:105D5000E96332209CACDEC179EA6D993E4FBD1DEE -:105D6000A68FD380F419D4BB71E5BF23D327FF9D41 -:105D7000307DD2089F21BD83F3D43B327D9E7A27AC -:105D80004C1F37E133AC77E3CAFF8B4C9FFCBF84D9 -:105D9000E93384E08CEC1D3E4DEFC9F4697A2F4C59 -:105DA0009F3C8233A677F88C3D25D367ECA9307DE4 -:105DB00026109C71BD83D3744AA64FD3A9307DA60B -:105DC000109D2FEDDDB8C6BE2FD367ECFB61FA5CEA -:105DD00045700A7CF5840F03388ED8709E3927D31E -:105DE000E7997361FACC213853014E4ECF70C6B794 -:105DF000C9F419DF16A6CF02827365EFE03CD32603 -:105E0000D3E799B6307DCA88CE57F56E5CE3DB6583 -:105E1000FA8C6FE7F4A9B278263BD0BE4B649EEDB6 -:105E2000D0E492930D079C9037D99907C1BEA48402 -:105E300076207C582BC92E543D9A9DE2616887CE0E -:105E400070BA3DE8F7316AF6086BA1FD827D57A272 -:105E5000E40FFAD230E916C4D701565BA45D923044 -:105E6000364EB28712BD4952BE4F615FA97E4A517C -:105E7000B6549E567291549EE1CB93F29965E3A578 -:105E8000FAFDAB2749F90BD64C97EA67056649F945 -:105E90009C9AEBA4FA836A1749E517D6954BE5431C -:105EA00082ABA4FCC5F5FF47AA3FAC619D543EA25E -:105EB00069B3543E32F40B293FEAD00352FD312D31 -:105EC000DBA5F24B8E3D2A958F6BDD23E5279C7E6B -:105ED000466707CAFBFFF5058CDB831966B20743EB -:105EE0000E33E5CDFB6C64FFEFC73CF0D3DC7706E7 -:105EF000E5CDCF2E7627E37E1A01C07A5FD0B7ECCE -:105F000042F4F7DC3CDE77A10BBEDF6CF68D70450A -:105F1000F1477854DF3E03F98B5A14968EA9DB8043 -:105F2000699C51ECD72D5CBE3666E53F148890D352 -:105F30009AFE30FF207FD86026FB5593EF8DFD4BF6 -:105F4000D31746F4B3A1BFB964FB50FE7DB11DFB6E -:105F50002B7A11E75995B96330E2A5EFC7923D5608 -:105F6000EAC73AA08CFA790DFB89F07B590694E9CF -:105F7000FAB1966C17DF453FC7705CB1FAD9983D0E -:105F80005E1ECF8072EAE75D5D3F1B0794EBFA89E6 -:105F9000E3E381EFA29FF7CE3B9E9C89F2782E58D7 -:105FA00049FD74E8E866B960A5AE1F3BF583DF17CD -:105FB000933F17760169C0674B4729C9C17FDA58FB -:105FC00000E4C29C59FE6BCCB3B76C6C10F6E38650 -:105FD0007EA11ECBE5FEA3A70D49349ECFE280FF34 -:105FE00011766AD77E3640FBE2A5024516048C6026 -:105FF0007F5B296473C9AEE20137B9216D3A30F095 -:106000006EEC678BC33308F26D4D93CD8BA3C8D371 -:10601000D25AD3A9D648BF88B6BF99C472ABA1FFE4 -:106020005D369794D7D2958A8B097F04E54FC0BE21 -:1060300085C17EE0CFB02F6040AA774D7C9FF60EE1 -:10604000EC6F30DF0AFB1B2C676C2DB53B21FCB4D9 -:10605000276E578248EFCF7EF24313E9F1007B357C -:106060003D15FD6EFC6FC19A78F4F187F15B18E87D -:1060700023E5415D661AD2695F48FBDF8EA72DC11B -:10608000ED48D79A4CA0A9A897CDD8EBB0C9CD4878 -:10609000A26CA6612C63B3AB8BA7A6D12C52FAAF2E -:1060A000023C67358E34410BD6666ABDD163EF8200 -:1060B000CBBCA613481F2BFC4338D714423EA2FF8B -:1060C0006B8BE4FC5CA676E581DF838DD9826FA2C1 -:1060D0005FB7D7847C2D4AE5F8CCC5340F8BB9BFA8 -:1060E000A3C4C5DB6AF8542D36B110ED4F03290C5B -:1060F000FDD18164AA779DB6CFD4E15762B27A8B85 -:1061000080AE250B8D44573DBE6FEE8BF71A86434C -:106110005A73B7095D9B3DE13FCF2797B332DE9FAE -:1061200046574D5E4E09FE9E40FE43FA3EF21FF07A -:106130003E29F8DF25C79CFF5516DF4CE47FC7FDDD -:106140004646FC127C9F23F8BEB456E6FB1CF49333 -:1061500043FD39ABB382EBB17E5D1F89BF307099CF -:106160000EB5774D05B5DA0DFFB7851C5C57B3FB4F -:106170007964EFF565BAF1093EDC28F8305F478FA6 -:1061800039826FF305DF96B1C06D19E43F0A9AD0EA -:106190002F36AF4C61A82FAA7EAAF1AD55E29B4FD6 -:1061A000E39B0EDF1B05DF6EFC09E79B1EEF56C16C -:1061B000B7D6BA8F4D2CBB3BDE7A3C17ACD18D2BBA -:1061C000A0E75BAD38777099D1DE29F616F439195E -:1061D00051FF9AC22BFB9C8CD00BD716154BF9B9EB -:1061E00025F3A4FAF37C0BA5F2EBCB964BE5F3ABCE -:1061F0007F28E517ACF989547F6160AD54BEB8665D -:106200009354BEB4F62E29BFACEE7EA9FEF2E03662 -:10621000A97C45FD23527945C36E295FD5F4B4545A -:10622000DFB06FC8D5285F2F1D3532F4977DEA792E -:106230009FFC759F7A4C1EAC538932370EE5D94DC1 -:10624000F27CCA9F4BE969BF87E4FD8C7F2CA56D6A -:106250004D07ECE87FAC8A03BD9F0876B8F1CDB559 -:1062600035FD70BD81F6E3196B36B6AE0D40FE000C -:106270001E46C1BC99516766A1510CA4BB6F589EC4 -:106280003B8C11E5AD3D94D7A92CD4A77BF98CD6D6 -:10629000E8DFDB958EC119E8277CC3C27646F8EBB0 -:1062A000BA9F57B04CB42B62959F35B0B2C8F3ACCF -:1062B00093467E4EE2344E3A698474A599CFFF9599 -:1062C0007B32263127E64383ABA3F85DC2FD350060 -:1062D0003269C8E71C69DE2FABBBB86B9E33EC2775 -:1062E0009BE476797094F47D45FD04A95DAEE27B74 -:1062F000D708F5CEEE37D27ACD4207065C330CF1E3 -:10630000F39EC4EFAC2985ECAE16BFB7CFC9818C24 -:10631000FDD15F48E9ABFE224A5FF397507ACCEF9C -:10632000A3F44D7F19A57FF65753FA8E7F0DA5ADC7 -:10633000FE00A527FC35949EF4D7527ACA5F47E940 -:10634000697F90D233FE7A4ACFFA1B286DF337511A -:10635000AAE9CF9EE4EFB4585FCFA0FC459133F398 -:10636000AD6C5DCDC42E398B532DEB50CE34FACEAF -:10637000A8B308794895E42111D76192B31ECAEBFE -:106380004C420E63B58F5E8EF2D6F77B9037C6D641 -:10639000911CCC1472F75DE58DA1373E05E52953BC -:1063A000274FB21C6A72A4E9815CA568B83AA64B73 -:1063B000AE661AB99DA4C9D5CFD14E8C626FDDA04F -:1063C0002A62FDE3F611F36518D07E5B25FCFECC56 -:1063D0009D4EF94ED1F77A00D782F5D4602EAE23C8 -:1063E0009DB97F1B8CFEF1CE6316867EF858E3D3F1 -:1063F000CB4B6CBA7B69FF501A84456D54F7725BC6 -:106400001CA7ABCDC00A591E9ECFE61FF3013FE388 -:10641000FEF3E23CDCD7C27795915D15F41447F1A9 -:10642000B73394F1B49EE9ABD53FF5C097F9786ED8 -:106430003E53CCF3B803467EAE1D7AC8734DC4F903 -:106440000CECB7D3D1EFDC31C8EC22FB21D457A63A -:1064500063B0AF44C703833E1B8CE71B9B400E71A8 -:106460007E750E1C9CC0CE231F3DE9F99EE8B9281D -:10647000D8B797F434333C37027A6EC7FB2FBDA5EB -:10648000674F7AB227FD786233A7B353D8A7B1E834 -:10649000DC3E09E65D1439BE475565396603F97976 -:1064A00087467FDC9746D0FF52BB9BEA3FB7EFADF4 -:1064B00001ADD04F67E385098C9FE7905DD7F1A4CC -:1064C000B0DBDD99321F5BFB125C0DCE734FBE3E1D -:1064D00000F7C9B76106E6D993F145BF5253BAE058 -:1064E000F5F61C3ED6B8767FCBF9D99EAACDCF96CD -:1064F00001284F9F093D10737C3DC9298E0FE05C38 -:10650000A5F0F16D3016FD0EF54C787CA3537A356D -:10651000BEAA04335346007E0EB3992530B643F528 -:106520001D54691FE7690DA09F625FBC673DB0A461 -:10653000CA79E6E5901BDBC9FE8C15F536976C3FF2 -:1065400025BA64FB29C315693F751E7AC8E903FCA7 -:1065500056A51B5C2747E13AE715EB1C5F5735FC56 -:106560002A1AB25C76098E9CEFAC550A1B489EDC59 -:1065700009B3A39C9769E9AA74B3EB24AC5767EA03 -:106580007312B0DF337EAB8BAFAF2E17EF37DD1555 -:10659000B9BEAE5C1347F535FC62C1FD67E3C75871 -:1065A000237BD78AEB2294E5C4AE1F939FEA27662C -:1065B0003A976E367D86F6BB2D57B3DF55CA6B70A2 -:1065C000AB1A8C01CB08FCBE4BEA0FDAB9B53366C7 -:1065D0006C175B6E54764AE327F0DF8A07EFB46FDF -:1065E000B5129F7D003101E0B5ABF61A94AB132ACA -:1065F0009FCF55424E2BACAD669F9BC8DD82F2BC4F -:10660000682CD326CCDCB7404F7FF0A289EE69B16D -:10661000AF007A7ED7558125ACC8894ECF458D2BEA -:1066200066E0BAFD8141DB0FD7E6E3B8CF31432105 -:10663000EAA573EC8FCE5111F3758889FB63580D71 -:10664000DFE704E01F8E6F69ADBCEF595627E74BBB -:10665000D9AC54D4B7A55B4C2C08B82FC77D933662 -:106660006ED0BF1926EED758C6AA37E03EFD5E139E -:10667000F7F72C72313513F0AAF88F5FE6A3DFC766 -:1066800063E27687769EBC3C89E35D3E3B68F642DA -:10669000FD771B47CD018D0BED831BC8FE29669E40 -:1066A0009DAC3BDD17D7C8F8F584BF1E5FCD0EEA61 -:1066B00076AE2DF048AE57BCC1287AEE329322F662 -:1066C0007F7C7ECC36C9FE9C7926D9EFA3C981494F -:1066D000C8C109D577B5690CE73BF251513BCCBE37 -:1066E000887AE6AE7AB3CF57CF82F58C546F9E2965 -:1066F00005EB754CA3FD3103791ADA55CFD605EFBA -:10670000460E4FAE57F11F8F3D15007929FFED3D25 -:106710004E06EBE6076A6DAA07BEAFDC799BD30B8A -:10672000E96935E0447E7E10341646A3C796303DB5 -:10673000BC7605FD69423E594D80FC149FED34B98D -:10674000C8CF5F6F0959404E2B1B97CF60C3297F7D -:106750009CE7377E64C47C93CCAFF25FDF93EAE6BC -:10676000F76CB83F8985C8CEADDCF1DE345C2FAA6A -:106770005807C999BE1DF6FF7912CDEB85E684EE68 -:10678000E58027F913AAC42CAB6AFCF9474627E633 -:1067900065F92813F62AD209F7F9B7991CC9A7E2B7 -:1067A000217B09BB04E7B9460F16E476EBFA47EE06 -:1067B0001B7E1CF039BBE345A73234523F7039EBE6 -:1067C0006C58FC2BAB21B61E6903398CB48F00309A -:1067D000B57337097BBB99A72B4D2127DE6759B9C4 -:1067E000CDE40109642B1F3332BC07C0DEB004D1F5 -:1067F0002FBAE2B1E75F1B0F745FB1DB943C830FEC -:10680000C7AEA476F1A50AFEB726AF8B0FE54F3CC5 -:106810006F760FE3DF6F49EAE2C78ADDFBCD6C5884 -:1068200077FA4D6ED86F6EB547E14BC3F169B8CEBC -:10683000AE7FE4AF66F4277EB04F616959DDDB9728 -:106840006D7B9ED63BA413F151F029CCB76EFC0AA8 -:10685000CD7C6634D573A11E8CC5AF6542EF823CFA -:106860003FFE0CDEFF79D3E2C1F1973D7E9313C763 -:10687000F1BE5ACDE5FA97B7A5E2FC2E3305525D7D -:1068800094F2EF650FFE88E46DD9911FA592BDC00B -:10689000BC1906D2C5810C1CDFD2ADD7D2F84A99FB -:1068A0008FE4AEEC97C622BC8FF8A9CA0A77479945 -:1068B00017716685F0797F3B183230BEF7717F899A -:1068C000FAEC8F46BA17C5D80FE9DED88FC45861E5 -:1068D000E5A3FCA756CEA7E3424FE24496E475C772 -:1068E000C616E4CF99FEDE343CE7003A0404BD94BA -:1068F0006F00AEF1C8D434CE1FE656F3453BD0EF5F -:1069000093F13BD66F31796DC3A576421FF2FE57E6 -:106910008BFE01EF385CAFDE4F8D6EEF8D11E383A0 -:10692000BF1616215F11F39BCFF71D9BF8FCD6E62F -:106930007BB0B810CB3F7995CF1F6C87EB03E01588 -:106940004AA3F2FDB315D207B0AF8E36AF7798C425 -:10695000BC96CBC152A4F51EF0569584483901F877 -:1069600049447FDA07976E817611F65715F647F599 -:10697000CC5DDF23D68765420F98CC30FF2FEE9A8F -:10698000FF6C2B9FF73DD9932B4DC1871FC0F9FAA0 -:1069900086C51370E37C3515E1B83FDC75E0B5EBD7 -:1069A00040AE3F6CD0E6A9AC3FF5F3B46CCF1816FF -:1069B0006D9E7E6887FD55B4790ADFA3CE537B2B8D -:1069C000C9F1F7AD3F35BA0D35CB7A13F5E033EEAB -:1069D000D8F4D3EBC1DF9BDC4447BD1E84BF5759BD -:1069E0007E77B9D3E44D93B3F2DF545C80FA262C62 -:1069F0008F9ABC85E5519337FD3865BAE9CBFF2AFC -:106A0000F4CDF5D6C26BD02EB67630DAAF14CC36D4 -:106A100006719F6CFD84D17C9F74433CE5E71A5B53 -:106A20009F409BEFAD8AB9C3701DBF9E054CFCDC37 -:106A3000BCD64476EA57DF7C3311C6739DA0EBF5D4 -:106A400040E6AB800F25AA128A033CE7A92C909060 -:106A500084FE62859D88C0E3FA32398F7F97A576E0 -:106A6000C1E9A9FEB7B5ABBF6B7AC4CFCFAEFE8488 -:106A700029ED2FC0708E90A3E2667E4E51355A09E3 -:106A800066D3FC6B558B22F6098F99B99D7164CA48 -:106A90003563907E05738725907CD70EA17D609528 -:106AA000D05B9D017702EAF3CEE61CDAF7751E5A39 -:106AB000ECF045D15F07849C3D2FCE59DAED4AAD0D -:106AC00011E4BD9D7590DD12B0DBA2FADDEACC06C3 -:106AD00061EF08BEC19F11FA2F1172380F9A26E498 -:106AE00045F06DF6551FA8CEEE7CC0BF1311FB8696 -:106AF0007F94BE28D748DF03B6D6694551FC338F53 -:106B00000A7D7DD9B35F98719D9BD25CA0221DA7A1 -:106B1000D88D92BF63BB365F87B2A188D765CF2E71 -:106B2000BF630CC871D521A3C706E3AB6AFEC8ECEE -:106B30008BB27FD3D313E1A3FDD86AE6F6F15153AC -:106B4000D152A4EBD16BF979EE9FCC9E8A6878CEB6 -:106B5000B6723CE7B1A24F472BFF7AF42D98EB08B1 -:106B60004D027A74DAF9FDE4EEF2C7E77DA74B092E -:106B7000AE55500E8D3C9FCCEFFF4E63BE3B262A98 -:106B800034DF2F8FD45F054DC58FE17D96CA66C572 -:106B90006580F24AB5D58C725CD5B45B45BBFC0709 -:106BA0006EFECE82A9D5C36647F8B75ACDDC9F7476 -:106BB000E06FD7CD47FA7E3CDBC2102FEFD08F9C21 -:106BC000B8DE7FDC3C8AE641AC71FDC1EFB9660AF4 -:106BD000FAE3CD5C9FE9E5615A72BC94BF7632EB73 -:106BE00087E7BC97595A6FF244E1DF3A0B9FA7BD84 -:106BF000D66FD6FF61FA6D22E8372ED7A648FD364C -:106C0000DDC2E53E42BFA545D36FABD6BAD3502E09 -:106C100056EDCD4943BEAE3ABC34259A7E7B41EC5D -:106C20006B0F8B7BD2EDFD40BF8D88D06FFD40BFD9 -:106C300045F1838FB66876670FFACDFADF33FF5ED2 -:106C400040FD1665BC5708B9D3F45B61F35AD26FA7 -:106C500085FD8CD27DA4CB2CC28E8BA9DF16DE7372 -:106C60002DE54D9EF828F2837445FD7658E839EC01 -:106C700007F5DCCF2CDF4ECFCDB3727C7BD473FF16 -:106C80004D74D6F4DCAAFE0AD92FDDE590EBB95598 -:106C9000595CCFADDACBF5DCAA415CCFE9F5DBA4DA -:106CA0006EFA8DB7AFCC85F6B44FCCBAEF06BCCF39 -:106CB0005762F258A1FE0CB7F6BEA07A4CA4BEFBF8 -:106CC000992586BEF380BEB3F7ACEF5E417DA792F7 -:106CD0001E1B88F3482F1FD307C64BF7D58E7E7136 -:106CE000EA37BFC5F9F20723DD077ADDC0F743FBBA -:106CF000BE38350AE7DDCB880FCC979D42FEDAFC23 -:106D000063499F4E1ECAE77BC5A1385A272A1B1527 -:106D10003EDE5B94A01BD781BF7D4EFBE4F97BF97F -:106D20003E79AE85D383FDD8C8DF4500091646C835 -:106D300043C9E7E5E4E72B519915EDD70587A67F11 -:106D40008076EB82CF6BC8DE5D80DFF17EC5EED64C -:106D50000D99D0EFFCE50AED3798B80FA1DD97B893 -:106D6000BE793FDD5FD1DF83D0F4F9FC6AF9FB0225 -:106D70009D5D7F408C13EC59A20B7BC518D53F77E6 -:106D8000404F0F0F1F7FC56A6E1F87E901F4712BFB -:106D9000DDE9011C9DB130B56BFCF39F8471257753 -:106DA0008D4BA3877E7CDAFE6481981BB1C6ABD184 -:106DB000AFDB78357AEAC6FDBC45D84517B36138F4 -:106DC000CF5E37F8EE188372F17B183FE03367DE51 -:106DD000A0B4483DFCA2D0E757F98E4F497523BDBA -:106DE000F8FBBBEBCA763F9F0AE3B8DA9B9587575F -:106DF00011AEFD9BD9877E8403B60ED26B9A5C5D83 -:106E000068E572FE7701E7685FD7145A3F9A141756 -:106E1000CD97904E6F897B6155404F9C8F554D6249 -:106E2000BD0179C3F9364D5B7F90FEF09F573573F6 -:106E3000FA57552B44FF99ACE320D2B73259F1846D -:106E400000D4B4A6DDB7E13DAA176CF01DE76D993B -:106E5000E2D9CEC961CF488D2A976A34B964D54347 -:106E6000C8AFA0AD830BB05E12BE17793D05ED1320 -:106E7000BDBD7199A5E528E271D98F4D6C1BEB6EF4 -:106E80007F68FCCE857FDF44BBCFD383FC0E12F638 -:106E9000E50B486F3BD2B5C38C725F15E2EB8656AB -:106EA0005EA5BAA7107D347A37C1BA309AD31BDFFA -:106EB0007DE9E979B5964779C6FACD8A09DB5F099C -:106EC0007CE80345930D5F1CD4E417DF89E9E98270 -:106ED000FBFF8C88F98E7A29F2DCB1B2E908D16522 -:106EE000FA6A30AB22E88EFAEA7CF4E9361F9AF6A9 -:106EF00047BD07F56DE7C38556793EECB375BC38E1 -:106F000002FD5B7B15D207AC3951DADF5F61E5FB2F -:106F1000A603361FC96DC76113DDF7D6EB8DB182AD -:106F2000FEB89F887C0737190782E7BB2E1B7B576B -:106F3000C3239BCB4FA4BE7EC1E6233EC5823F4DFB -:106F4000C08F652F85F1C5FEF03CC52DF7A75F2FDB -:106F5000343F4F4FE3BA46ACF7DF755CE1F349D6F7 -:106F60006266DC9FBFDB1C71CE3447F8F9353F58B1 -:106F700044BD999631B1EBA1BF2504E37E61D743AF -:106F8000E4D73DF7E8F19928B72B7E676456E073A4 -:106F9000DB2E070BF17B14665C57CB1B8D51CF4565 -:106FA000185B4FF8ADF8AD83F44AF91E4B7006B488 -:106FB0002F7FEADDE1E89F6A5BC7F54BE051211FB7 -:106FC00081D6E1785E5EAEF2F3623DBC1F0B79398B -:106FD000FB747C09EA47A59EBFEB2C6F986BB2440B -:106FE000ECCB2BF1C08DD7A37BC8814714F28377FC -:106FF000C76F2DAFF708D77BE54DA620BE0F2DAF8D -:10700000DF46FBD9AAFA8FCC68C74DFEED63644713 -:10701000543519653F61BD3164213FA6F138A67A28 -:107020007F5D656305CDC7CA06E10FD3F98B56FCBA -:1070300076EF530120CD8A277EED443D73A665A7E8 -:1070400093FC70F5DCCFA6DAD5E87EB89EFC6F0D18 -:107050009BA2FADFCEE07FC0FCDB6A95FD6FACBE81 -:107060004FAFCEC1573CF6E983782E7476CF870FA9 -:1070700022DE2BBFFEF8C19FA27DB2CFE6C2F5AEE5 -:10708000EAD1A3E457D7DA3D25E655DB23BF7EF8E6 -:1070900001987F6D6F58E8FE55DBDEF707B8619CFD -:1070A0006DBBBF4845FFE5EABD5369DFB2FAC9C908 -:1070B00069E7BB47827219ECC579889E0F071A8D64 -:1070C0000CDF419E3B66213B23EC476DA8E07E69C7 -:1070D000B7F09FEE8A7EEEA4F9FD2A1BAFB9FA52F3 -:1070E0005CF71A4D1E377D177EC09EFCA6AF023F8F -:1070F00047F4826FBB845F5CC7B773F81FC09F3FC4 -:1071000059657FF3A78D4B7FF5009635F689E937F2 -:107110000DF5825EDAB9D636ABF71D2BCE873DBFB3 -:1071200021FF34F20B6C6ED6F6D8A703D0DF70DAED -:10713000D47123DDBFD86BA17B42E57B5FA7F9D17A -:10714000F6E4113A2F62E25CA98D85FFF83980D808 -:10715000CB54ED70707FABA03BFA63DD4EFA2EFC92 -:10716000AE5C6E357F6C2C3F6C1F9BB8072ECED962 -:107170002A76BC65663ABFB63216F9745C3A17D403 -:10718000C6AD87E7423A5C12799E10CBCF2DF468EA -:10719000984FFC1CA16D9B385F089F1B30D62F0FAA -:1071A000EFBFF3F3EEAAA0F23A8B321FB5F304A7B8 -:1071B0004D371F83BD3B47E819DFEF460FC5C6F7C4 -:1071C000AD1A5DCE7E155D1F0FB129E2FD812FD76F -:1071D00016B1EE2C10EB4925D08BBF27E3F89E1596 -:1071E000FBBBB38F1A83B80FDED07080F4AA7E5E2B -:1071F00057B2E8F143C6DBB83EA96CDA3F1CF5CFC5 -:10720000D9679F26B9ABDC75DC1C003807EB9F30D3 -:10721000B70EED9273D4D7C1087D7DF6F1FDC3F9A9 -:107220003907DF47EAE15F21E05735CBF0AB767DE8 -:1072300024C15F116830BBEC3DF77346F5CEC5F154 -:107240009E6931515C94330DC6C268F14A86622052 -:10725000A9942E3A6D70F0F771C62433D991AB1D05 -:10726000638F2524636A76E33E7AFD5A7E1F72FDA2 -:10727000CF3CE9C897F58973E81CA856474757B231 -:10728000AB00F7D7AE2945A351ACF47A20D16B906F -:10729000F05EED284CC3F7DCB70A7B84A91E7ABFE9 -:1072A00067744E2BC471185D06972DEA3ACAE199AE -:1072B000EC45142FC2E492DFD37DEFF11FDCFDE437 -:1072C000F80F817EFF68FC07467130FEDFC77F083C -:1072D000603FFF02F11F42E4B7D1E23F247FCFF1CC -:1072E0001FD63239FE83E06738FE83E0E7FFC67FB2 -:1072F000F8FF2BFE8331EEEF53303E8316FF21253E -:10730000CE3C3532FEC38571095323E33F8C8B4B52 -:107310009F1A19FFE10771595323E33FCC8FBB68D4 -:107320006A64FC87AAB8515323E33FAC8D9B48792C -:107330002DFEC3DD7153A7CAF11F664E9D02F9B63B -:1073400038DFDF71BD8A15FFE13D9C2C637A8EFF2B -:107350000070CC716362C77FD0C38915FF01E02440 -:10736000109C18F11FBAE11323FE03C049273831DE -:10737000E23F74C32746FC078093457062C47FD008 -:10738000C38915FF01E05C1497123BFE831E4EACCF -:10739000F80F006714E11323FE43377C62C47F00BB -:1073A0003813094E8CF80FDDF08911FF01E04CA570 -:1073B00071C588FFA087132BFE03C09949F8C488C4 -:1073C000FFA087132BFE03C0994BF8C488FFD00D94 -:1073D0009F18F11F008E8FF08911FFA11B3E31E233 -:1073E0003F009CE5042746FC073D9C58F11F00CE5A -:1073F0002A821323FE831E4EACF80F00E7A7042752 -:1074000046FC876EF8C488FF00706E253831E23F75 -:1074100074C32746FC07807307C18911FF410F27FA -:1074200056FC0780732FC18911FF410F2756FC07B7 -:1074300080F32B821323FE43377C62C47F0038F530 -:10744000248731E23F74C3E7BBC67FB085062A3983 -:1074500014FF81E24486E33F247FEBF80FCD88EFF1 -:10746000FFC67FF89F19FFE166BBEFEB38F2837E22 -:10747000B7F80FB6F86F17FFE1667B517C3CEE2F33 -:10748000BF65FC87D4F86F17FF01FA498F1F13BB44 -:107490009F58F11F7274FDF414FF01FA1974DEF1A4 -:1074A000C488FFE0D1D1EDFB8AFFF045DCF9E33F72 -:1074B000FCCBC559806D0A9EFF149328B27F99B802 -:1074C0000BD7C6FF93E32E90B1F0AF1477417BBF8B -:1074D000DF60C2F5EA4DC1F7D7845CBC25E22F1C02 -:1074E0008B197F217815F94597CBF117A60B3ECE66 -:1074F000F3C9F2309DF1F386E953B278BCCC325D2A -:10750000FC855CF9FC7A86EFC81400C7AEF2C8E3CC -:107510003822E46166C947CF217BAE1E1B3DFEC207 -:107520002CC18F621D5DA60BBE158BF47A7C920276 -:10753000F23CA3EC888A749DE96E55C9AFFD038DBA -:107540007F6E897FB3055C3DBEB304FF665DC9F9FC -:10755000A7C7FB55E49F13D2B251C43F3DDE7A3C2E -:10756000F5FC6791FC8E889B51C0E4B80B93AD721B -:10757000DC85A92E39EEC215E972DC852BDD72DCC3 -:10758000851FE4CA7117AEF2C87117AE1E2BC75D16 -:1075900028F6AED5C57DD8A48BFB70972EEEC3FD23 -:1075A000BAB80FDB74711F1ED1C57DD8AD8BFBF04F -:1075B000B42EEEC37E29BFB8E6B0547F69ED112921 -:1075C000BFACEE0DA9FEF2E071A97C45FD07527932 -:1075D00045C34752BEAAE90BA97E6FE33EBC2ADE33 -:1075E00003BF26DE031F13EF81DF8C11F7E1AF3FEE -:1075F000FFE2B6C8F7F85FFEFC9BDBF03DBE41BC86 -:10760000838D15F7215C1E23EE4357FB6F1FF72177 -:1076100025F99FFF0E3FC7CECF3727C44FCAB1A76A -:107620007CF777F8D716C9EF99E796C8EF9973EC0E -:107630005C9FCFF3C9EF9AAF2F93DF3597D97CD9F1 -:1076400088873EEEC384786F8E1DF5A5789F1FC294 -:10765000F7A9B0363E8BEF53217D0EE33E407A1002 -:10766000E33E407A08E33E40FA7B8CFB00E94B188E -:10767000F701D29731EE838A712302226E448D88FE -:107680001B512BE246D489B811411137A25EC48D3B -:10769000681071239A44DC8810C139E13F44E949FC -:1076A0007F0BA5A7FCC7283DED6FA5F48CFF34A583 -:1076B00067FD1D94B6F93FA7B4B7712334B9FC3305 -:1076C000DA0D66EC9FCBB126A733EC033744CA69C9 -:1076D00091FDA20D28A7B1E245CC459AA6C48E170C -:1076E000112E8F112FA2AB7DEC781169A3BFBF784B -:1076F00011FF16CFE5F51F8D1731BF5A8E67B060A9 -:10770000CDF9E34594D98A56A35C6AF2F86FF1FC8F -:10771000BCAAA77811DBEC8A58AF812E6877015D8F -:1077200068BDEEE1BDFD738E8773713FD1997BD14A -:1077300079E31CE8E52236BD795C83EBBEE73811BE -:107740003DD155ABFF66398F5FF06FF1E78F5FD0AA -:107750002D4E444FF105067D467AB2B771227A5A12 -:10776000177AA2E7ACEF394E444F7AB5277DFAC7B6 -:10777000E99CCE13E2CF1F8F231C17CEDA72901A2A -:10778000BBBC34B555F10EBC60B68BFC27EDBBC459 -:10779000BD312F73BB52F93B75B437DBF7240C674F -:1077A000F47EDDC5BCC09F78F15DD9B57F3F9EA753 -:1077B000DFEA64DEC4248A07EF36E6E03E6CA415F7 -:1077C000FD29158D1FBDFC3B806B6B36D27DB276DB -:1077D000C0A185EC3E6F22F22D9EDD4EFB743CE392 -:1077E000FAA64FE47B66DDEF37609588F39BA946E8 -:1077F0003BED9B3AB7F27B9E4676F17D1347D37DF6 -:107800006A167413FFC84E5D21F0ECC414EBFBAC98 -:10781000643F2E3BFC447E88F1F3CA48BF419F423F -:10782000D94F5367730EC777952CE06D41FB7B8969 -:1078300080975224FB6F3E5C547808CFE997F84A52 -:10784000E91E425A89ECCF61E2DD386EC7C2F7E526 -:10785000009FD226853DA0747F475ED67CD706DC8C -:10786000E72C0FEAED6F968B7256CEE23CB8EF5DD7 -:10787000512F973B1CE23E879DD97B45B7D60BEF36 -:107880009B987C5EBA7942587F9783EEC32E3BBCAF -:10789000D88CCCB2A4CB74B3B965BAC5E7CAF4D15D -:1078A000D3CFE191E9A3A75FC258D9FFA5D14FBBC0 -:1078B0006FA832715F34C8EF91767B87DFB48DF0AB -:1078C000D4D34F4FAF510E714FA28B5E45D6545259 -:1078D000F98467861A22F9D6CF874C7B48C1FFEE20 -:1078E0009F1C5C4BAD3C0E15F5563A07CD9425BC5C -:1078F0005D3CCE078C2BCB3C341F70478FFEDD7870 -:10790000F66721F7EFB26F20BDA9F8B9E38BA07439 -:107910002BCADB08FEFB0BE4AFD27E3781795CB863 -:107920008F6AF05BDD4B543C1764EE2503F13CD0CD -:1079300045E99DE2DD6FFB5046FBFE86D027A97826 -:107940008E76675EC74CF43F542D6545B87EFDC802 -:10795000C9DF5D6C12E90827F7CF6C2E3230EF6873 -:10796000FC1D1E635041BFABCB7BF872B4479B4DEF -:107970006E7A47ECEA78F97A2A1F45EFA3330CB503 -:1079800023111FA84FEF6BDB9BDF752E8ED0C36DCD -:107990004D770FC1FBC5F71BA2BFEB2D7568EFDB61 -:1079A000F8FD8E115D71064A1D63281EC19DD9D058 -:1079B0004F657127F15193CB0982FECF954E27FC7D -:1079C0009E6C56DCE8AF9B66BCE107C300BF714705 -:1079D00055AEBFC4BDEED1A2FED3CC938EF88EBB04 -:1079E0009429387FC6BDC13C0124717529DDA7FBF0 -:1079F0009D73DA21E4D7946690279C0F67ED1EBC37 -:107A00002A3FA645BE2F9738C57700EF175E728CC8 -:107A1000913EBBE498AABF1F63C4FDFEB856F9FBB4 -:107A200004DDFE739D26774E968A72B7E52B23E11F -:107A3000D5DEC13CEB006EFB92BE746EDBFE09230B -:107A40003BB1FD2B6361B4FB25773BB8DFEB7E33A5 -:107A500023FD7D7FA99DDE393C5B5A7E01DA179FAD -:107A6000FDC47741343F65849D96C0DF9F7B13D86A -:107A70005894C35B154EEFDA8CA228EB9626779AC2 -:107A80001C6AF297511AE78B765F33D9C9EDA34987 -:107A9000A5B98A19E5679FC290AE6DEB00AFF3AC54 -:107AA000DB01B62E13F1A96AFA98EE61599B95A8ED -:107AB000BFCBF384C3C9EF03AE0BACC5FB1737C311 -:107AC00024423D9561AECD8A063FC0B6905DFA80F6 -:107AD000C3CDDF0D58451C21B53603EF23B4354D1A -:107AE000BE7203E0F900CC07E4EFFD260FE11DA80C -:107AF000608CEE930A7F5DBF996CDBE608FB77AF85 -:107B0000A3E030CAED6107B71BFBF83C0AE2EDF9D0 -:107B1000FB5F9D08BFFD730BF1AFAFB037B57627A4 -:107B20001D9C3E254EEF016CCFCA9249F9787C4EE0 -:107B3000F7923EE837077A47B1AFB4753DC9C7E859 -:107B40007C22C96E089272F27ADD2EE9BE7780E659 -:107B50008D360F584861F85E5FD36F4AB31272805A -:107B6000DC8FB6DA4378FF2CA90CC69D8CF13CACB7 -:107B70001C5E8B7A56F66B813CE6A371CFE8BD3F65 -:107B80003A5211BEA6F7347D796B22D747B7DEA5EE -:107B9000523CD0AD6AAB0DFDA9595EF7240C4D9354 -:107BA000A4BAE95E4AFF323E0FE3737E9918B6032A -:107BB00060928FFCDAB820DA7BA60C94A714A49705 -:107BC000EF4307A4C30F753C8BE682C7C6FAF0FBF0 -:107BD00053424F08BB669A58EFC6BD67E0EF284393 -:107BE00097B3C8F7457A3D0172FF27FCFD9EFBDF86 -:107BF00053294E68583F944EA3F58919871E403982 -:107C00009BF022E3C751423FB8E01FD2E792977C36 -:107C1000EB118DEFAA17F4FC66216B388F3FCD3640 -:107C2000EA10CCB7C875D629D67BA1476E2A1EB8F4 -:107C30001EE797264717DCE231FA22E8A86F1FF605 -:107C4000532AD6F077770EEA91978C783FACBD0037 -:107C5000F80D747912E70BD03BF193E095C8F72D3E -:107C6000CD57D850BE6F0D4D72CD803689D6226269 -:107C70005E22F3923F270FA8837122D69350C07ED5 -:107C80005D2DCA72A6E03DAE42C9DFA3FD2E1E0CDB -:107C900094F812E603C871E43D564D3EF5F2A8C9CA -:107CA000EF7ADC60E1F91D7ACC21352A0DC4200B76 -:107CB000DBEA423DABD997EBC3F65C22ED33560BC2 -:107CC000BB68BD7D9A95D4C0FE645ACF57E3FA04D1 -:107CD000E35F9DC2681E68E3D0CB63D5E706168CD0 -:107CE000D81F54A91D748FAFEA73330BF6C171FB13 -:107CF00026E1B835BA8C1474D1D321DB29F69B82E6 -:107D00001EB1F1CC77E1FDD944AB976D243C27D16E -:107D10003DE786509E15D7DBDB7478F602BF39D17C -:107D2000F053ED31F013F1DB2630DFEF5A415EF313 -:107D30006FAACBE0EB057B353D827FFA7933B6A99C -:107D4000FA803962BE687E5DFD3C19D1CCAE41BA85 -:107D50008F0BA90CCF5F7B9A2F9F88F156C5737A42 -:107D6000B5CFE9188CF2B943F5553BC9BE6835600B -:107D7000DCDFF6A719CD67CFFE934E8A6FD4D2BB56 -:107D8000FBE99A1DA5D94FFA7A9AFDA4E95DED7E2B -:107D9000F876A7CF8FFD2B4D209F30FEF52EBE2FFE -:107DA000DAEBF0ADC3EFF130063C4A62B9A12CFE2C -:107DB000FE5596FF58F21EAF93E706A013FD4E1630 -:107DC000E8FF414A773CB4FEA73813F9790BCC663B -:107DD000D443FDF219EFAC92D1FDC97EC3990FD700 -:107DE000A77E79FCDE5F50ACDBDB84BED5D2BD8ED6 -:107DF000A2FB117F93CA0296BCEF8E37A28AF7B11D -:107E0000B73BBDF7A1FC590BBD348E4C17F3A0FD59 -:107E100099A93628F86E3269A55BE1F7B059D73BCE -:107E200026809739C35D80729289FB68ACDF1C3D68 -:107E30008ED6134E9364677A58384ED513D82FD800 -:107E40009907CD80779F195ADC2BEDDCC6A3209DC6 -:107E5000DA1C7308E9B64F156E8F27727AE9F703BB -:107E60004878C44F15F9DBCC4CB525B1AEDFE13411 -:107E700058C98E8F679E06D44B2F3BB3C5B9A8A7B0 -:107E800006F3FFAE7658138776C9F19D13677954D0 -:107E9000A8E2BCB47338EE99409E0F23BE6D133B2D -:107EA00007DF4AC4E818C0E5C66B94E2E268F46FE5 -:107EB0003249F4B7E13E3B520F3ACCB48F6C53E2F7 -:107EC0003C38CFDA962B1C4FC52AE206A9F2FE5F9A -:107ED000E8234DBF763AB308FF7816A07D00B37A49 -:107EE000AC748F5DE08F7115C9AFB3373EB81DCF4D -:107EF000A3747114F57116272FB6D3BD8B2D7B6D2E -:107F0000B42FED2CE2E7F39DCD16D2BFB1E6691A8E -:107F10002A83F3C40B04BA7520DDD24CD589A8F7A7 -:107F2000D2E6F3F9AFA7473B0E14F73B7F3005A32A -:107F3000BD57D7D2F4F4BEC56897A567A453AA7DF0 -:107F4000AFB3AB51EF611B1314294EDF10E851ECB6 -:107F5000738C09F0FD9CEF8FAF7959D7BDF6BA3815 -:107F60004EBF4EDFF8848751AE40E0E8F704B473AB -:107F70004DB19FD7E22769FD6CF15B8B31E467DD82 -:107F8000A2E9365C075298F7CA793829B798D84ED3 -:107F90006A972BDD77BDD73FB218DF276726F07BC6 -:107FA000B49F6C994AEF9953D93ADB60A043699129 -:107FB000C183FE80738BDE741A407E1665B6E4A31F -:107FC0009C26987C990963C87545FB8D6525E660FC -:107FD00008E8955C070A81E818B892E8B8D010D58F -:107FE0003F9C9DC0F79D6F89F5243D7D40F19251E6 -:107FF00091F97E44574D8E60FE642C19DD150F13E8 -:10800000F87951429479D06E624DF85E42D347C9F7 -:1080100042CC347DA8C97132CE0FB4E38A403F49C7 -:10802000E77D5035B5EBF70C95E617BE403BD679AA -:10803000E924D237306F6B48CE73B9FEB4A13E8BC2 -:10804000F05BB5EF7DBD3FBE637AFB671F3BF05D24 -:10805000CB5FD40E07EAAFD3B7FCC98171C0DEBED7 -:1080600085EF936FD4D9FF5709F90826144D41BA0B -:108070002EF0FF3D3FD25E636BB8FF7979507EBF33 -:108080008AF7BF23FD80150DFAFB00011EA74CFCEB -:108090003EA79E0FEB041F96EFDA66CE7463FFBE19 -:1080A00039D8FF69B1BF39DDE8A0F7141A3E8B76E5 -:1080B0008D34A3CDFF97668B78A7D762E27AD93B40 -:1080C00003DFE7F804DDF4781EDC174FF096DEC31B -:1080D000DFAF2E84BED6805EF435F3384AFA712CB9 -:1080E0007DDB3D0DFDE84B3729B48FC3FAB7C03AAD -:1080F000E15BB391DEF1E8C7B93020FB73F4F11A0C -:10810000B5FDC032C1FF25F86BBC3951E23836F3FA -:10811000F774CB74F645E7A19C781CFF9A0461675D -:10812000E7B34B306EE79E43D909D1E26168E95964 -:1081300071DE8FF7FA313DED67944E4970F3785D4B -:10814000CD476E46B9AA6CDA4DF111F705DFEB3376 -:108150001EAA14347F6144A12A10F6D87C618FEDE9 -:10816000615C6EC08EDE8CF27FF9E73A3B5A8CF38D -:10817000064DEE0F2591DCDC80E31A8EDFD54FA291 -:108180008DEBEE04F9FD576FC7A58D471B9F565E1B -:1081900021DE9FEBDB69723E45C8DD921DC51BFAEF -:1081A0000229D6EF7D7F8088234771B63439D2CB40 -:1081B000C932C1B7B03C34DF41E3D2F806F29E2E9B -:1081C000DE25A5A33FA327B9D0F3BFCDD43A00E75E -:1081D000AB9EFF6D31CE7DB627F0738D256EEF34EB -:1081E000F4AF8079B8C115613F9C566B0FFE14E760 -:1081F000D10E2EC791EB22194B2F9A689D5DE57029 -:10820000A725DA05DFC6E1FB454B00EB69FD9CF2D3 -:10821000D7CC1A48E78DB5B3060EA4771B946AE550 -:10822000A5F77FEC44FBB43D97917FA1CD21E37B83 -:1082300004179B319872FAAF545BBE7E0B75D08EDB -:10824000168ADF7AEA2BE19FF8CA52186D9C6713F1 -:10825000B81DA8DD3FB951CCA31B9BF97BBB455B87 -:108260008BCDE4075823DFD77849714DCB84A6BE68 -:10827000869166E4B39E1F4B3D57D03BF06E7C6108 -:10828000B7135F97EADFB5897B4C0B847CCC74B95C -:10829000859DE6A377C44BEA8C64DF2F7357D3FE2A -:1082A00066851AFD3DD61897E1BCE3D18F6361A3C3 -:1082B000427A4F8FFFB21D6B37F465387E3EBEEEBB -:1082C000E308F5233D23C6C95A2FE7EF32C5BAFDAF -:1082D0005F995EED8C008000000000001F8B08009D -:1082E00000000000000BB57C0D7854D5B5E83E7356 -:1082F000CEFC24334926FF21413C21111212E29089 -:1083000084000171F24BC4080301826075405184FE -:1083100090207A5BEFABB79990682DFA7AA358CB8F -:108320006DEDFD062BAD0A4880A08126E9041403FB -:10833000040D820A96D68014B1053280B5587D8F1F -:10834000B7D6DAFB64664E92426F5F87D69D7DCECC -:108350003EFBACBDFED7DA6B9F65ECD94B720E636A -:108360000FB7CB8CE53356FBACEC65A98C2D63CAFB -:10837000E9BE0C46BF6BA9F85F67E59204C6EEC57F -:108380003F5568DB57553278AE5CAE9985CFF56FB7 -:1083900090995982EB1EEF53C971D036498E461819 -:1083A000C71E379EEEB33066817FD746D33C8C25FF -:1083B000E0FCFCD723B1A75260FEB38AFFBD08786A -:1083C000EE2CC0E181799678F873F47EF8FF32C71D -:1083D0008C2F2478DFFDEDF229730E5E5D6D32C0C7 -:1083E000F8A52F496C1D8CBFFF69DD78B12EFD3AD1 -:1083F0001EDAF0A3B9E91981710F7B9F0BE9C3DA8B -:108400005456C0D87D023EF6EA7F05EE73F84DAEB5 -:1084100008C632ED117167B3A05BC0265D4B63AC3B -:10842000CE1A99C3A2A03533C2233B64F46E02B8BE -:10843000D644C08201CE355BA3BD1EC4E3EA68C644 -:1084400046C0B8F68D26B70DE6C4DFED8C9DAB6F48 -:108450009E9B9E0EEBAF7F7A6EBAC2D82CBB9DB1AD -:1084600089408FB6E7685CB7E29A6487FE2A4BDFE3 -:108470008FEF5683F03899D363995C696286C07C2C -:10848000FA7659B3F1CBBEA0751621FC56F86312EB -:10849000C02FFF3DF8D5C4685B006EFDBC7FAADF2E -:1084A0001002F74A85395B6C81F568E326DA0DB472 -:1084B0001EFDF37A7A30E6A5717ABAAC443A04D15B -:1084C00017E15400AF3D1D56EF5A89F888E0F67465 -:1084D0008411DC1793D6CD3D93C7D8617C00E0AE04 -:1084E0001DF132F55F515C6E7B3C5EF48F728DC77F -:1084F0006762199B323CDE6046C6607C2ECE0FE37D -:10850000768539F3988CD75DB1C807D31BFAAA2CAE -:1085100040AA3AFBA40A05DE33FDB9BEAA30E83F03 -:10852000629FCCFB9BFA8E5A1C8C35B02915A5F0A6 -:10853000FC63700FE7BB5E9B6F762D66C05735807E -:10854000534B0CB4C7C6BC8DF256D35B5921454280 -:10855000CB984FCA057E7046FAAC39D4678530AEE9 -:1085600033CAFD1FB8BE55579B2EC938EE98C2E5D9 -:10857000A53B8EF0A000EC61F05C53B853B503BE90 -:108580009A622C8EC654BAEE098BC1BE535583AE87 -:108590006BF4C0E7108E2603734643DB75604C54C2 -:1085A0005FF6F078EBAA57AB14A0FFBEFA0C6AF5A1 -:1085B000F78B4CF674073C5F6460EE16DBE0FBAFB4 -:1085C00022BF109DD414A4736DB789E41C7F12F0F0 -:1085D000FD2AA1876A81405100CFAA63CC171E896A -:1085E000E3CABF50B06D95D8E910BE6281BE3C3C75 -:1085F000DC37DAD6E27C4A309F703C152BA9554A0D -:10860000D07B4B6D99217D39D19081EB6172B8633C -:1086100013E0574E31ACDE01EB976F8616F0A1D810 -:108620001DF212689B4BA6CB4BA16D34B2852DD8A1 -:108630001AD8F2603C750879D2DA4B76D76F90EE93 -:1086400017DEEF2DB0929E1A6927F916EB6D941C78 -:108650003ED4439E2EE6D804D79A6417E37CDCC24E -:10866000908F7F2FE671980D3B55E0D7F7EC0F12F6 -:10867000FF3AA20C8FA642FFA3E615150AF0AF231E -:10868000C570251578F478F34ADECF325C190DFDFC -:108690004F9A6B787F2A4C99CCD8C9E655159E6CB9 -:1086A0009C97EB31B6C59985EF510C12C9A9B2D789 -:1086B000E46D843F9B22393F3519812F6370BC4A9A -:1086C000E39F6A28DE6C05FE578A9DEA6A1BC73560 -:1086D000F2C3FFB4D5F0285B0DAB118FD822BECF0B -:1086E00088756B7460ADCEAC39A8175A9C5973234A -:1086F00010AFEECF11AF793DBDD3510FB77EF0492A -:10870000813B9BD30BE7C9EB612C12D673E1AD9B88 -:1087100036CA52803E97EC45E7515F4BA0A61F87B3 -:108720007549AA9DDD0372D7E864AA09D695C85E8B -:10873000B2A3FD30207D4005B532AE5F3AA35C5F49 -:10874000E2736CA48FEC4CB5DDF515BE5FD3CFACF6 -:108750003766483DACD757A69CC765067C1093D2B8 -:10876000767C29EAF3DF9A1DB7A8088F933D0E7037 -:108770006C333085C5107B642870DFCAC21DEB5096 -:10878000DE1D2CC903F2856823E0E01707F6D02828 -:1087900064485B073C5FCAA09D8470DD4AEB929100 -:1087A0009F2630978C7AAB8079ADD8F677BC9584CC -:1087B000F87A3E8CDDE782D6F22A737A83F4467E1D -:1087C000B444F89F1563A436DCD83217F934FC1290 -:1087D000B3A31FD0FF0B9382F38360DC89D71DFB0B -:1087E0000D0CE1FCB5D16B8F82BE3F53515F6681AA -:1087F000F9FA059DB5799F37A999D1D0AF8A91082B -:108800002FBF2EE2F6D8FF85C9FB722AE2C7B2DA83 -:108810001B2457E3A3F9B8BAB8E2B1D1F07C4B47B7 -:1088200038C3F74FEA0C3720FE376FC90D433ED8E7 -:1088300086B881F5C798ED8FE07C315700DE54BAD9 -:10884000EE24BC2AEA8428C06BE14C9BBA0EF0FEF1 -:10885000EBB09699C8F7FEAD06F632BC629BC93103 -:1088600007FBDB2EAB76D4B3BF4E6D09A7F56C3595 -:10887000D07AB685FBC7AD01B8D7652815089F62C9 -:10888000650AEA5FC550AC3E02D7A74573FDA8E96B -:10889000E39A6895FACF4BF0FE5C1C57447253265E -:1088A000DB48DEFAFDCC6B86F7C4CFEB95911EE179 -:1088B00073809590DF159FCC703E17121A5A9BD18A -:1088C000AB929E75DA9600DDA70B3D3BFD644D250E -:1088D0008BC48EE3D854986F9FCDC8705DB7B13EFE -:1088E000D902FDDBAE32870FF9E7AA427E981DFE62 -:1088F00005FB7B65629E5F494C898271455FAA0AD0 -:10890000F257110BF5DBCA36947F81F6ADC4A2BBDA -:108910008EFE5C24B64AE03ACCB3285AF861A3D85C -:10892000A86BA4CF60D6046147555C7FF67FE1BA9F -:10893000FA2B4C0E5CFF769BF3E3A9A8077B8D6CAA -:10894000131B5E8E7E550F1A7D0C08C7D570E68D01 -:10895000253EB421FDC76D68F684C17AC7A5F3F939 -:1089600091DF506F8CFD455C2CEAED8868AE4FB40A -:1089700056E32FE4237B14E723FBAD01F9FB5E7480 -:108980002A8DD3E409F90BE7D963F42E760D61172C -:10899000812FBF877CB9DDC62A90CF9F1961598886 -:1089A000F2A4BD67B7E07B7DFB54C39A2E23AEFBD8 -:1089B0002FA0FF01EED2E4ABA660FBDD15C7E12DD1 -:1089C00093BF25BFFA62BB44FE7C423BD7D7C17C34 -:1089D000316268BE7801F17A3DBED0C7011A5FEC02 -:1089E000B81E5F74FF637CF18B68E1DF0ECB17DF8D -:1089F00046E2FA1FEB2849647FC78F69137C30DC9D -:108A0000FD2956AED7F4D7DB053E779B9AEFCC41D4 -:108A1000B9BFCBE040B906AAA7CC05FBB23B9C3F4F -:108A2000C794D569D8DFAE703DB2BDDD4C7A64BB6A -:108A3000CDED267B9D6461E82730C5DDF77DD47FD1 -:108A4000C916755D10DF3E2EF4408BD137E573F407 -:108A50007F0F70FA4EBE2B5736C1B8110F70B9CECA -:108A60003F67DA28C33CD53145BE6818DF17CDED26 -:108A700062DD1918057C597BC644FAEDADCE23E5BD -:108A80004E1BF9374EE4AF497B8E941767E378CEDF -:108A900047DDA2D5FA53704D3164768E25017E5D97 -:108AA000C24E4C615C0FB9903F72027DE634523C7D -:108AB000A6F1413563596827E6F639CA908DAA2A8E -:108AC00042E95BED9B4971DFFCE3CEB20858D77CED -:108AD00097EEBEA07FB58EFEE007FF01E564D5E608 -:108AE000DE4E1BF2ADCAED698B697516F77B56A792 -:108AF000A1FFAFC911FD004F2DBFCF78795D901D4B -:108B00005763F83A9F752874DFD367F2DE0297FE49 -:108B100037E3CFB5087BF3AD90E3DCC7DE588CFCC0 -:108B20009BB7DCB90FF1BF284EA6EBFFC97C96348A -:108B3000A48F4321FFABC5A8967C2E05C631C595F1 -:108B40006183FB7BE2C3F3F0FDD531EE6B4827A6D2 -:108B5000F8BBF1B94985B9792857B6094DB1687F95 -:108B600034B801AE8A4DB6001C1A5CE785FEA98EAA -:108B700059720DF180CFA15E693B75D682CF6B74BF -:108B80006FE9B8C4E91D447FA47780FED27DD8D7B1 -:108B9000F06011ADD6FFE7E9EF1B89F41896FE18D7 -:108BA000F747FE8FE83F2A6608FA833F958ED73550 -:108BB0007FAAC5047E7576A0AFD1BDDA5E44E31C02 -:108BC000265819FA4F9D1057A21CBAA3D1B9613B80 -:108BD000EDFC5DFDBF3F3B0A5C4036292686CB930A -:108BE000C93F06FD8D093E89FCBE0920F0F7909F24 -:108BF0003592F49D43E0879D95A4B319DC05BF969B -:108C000082FE9F2F16E56082B9D287FCBEC33A3D33 -:108C100005FDB75CEBB434E4A737331E3B8426E78D -:108C2000CDE4E53B5F51037E8EA6D7F68969B5F7A3 -:108C300097C770FADF0E6A16FD3D740D83E1D0F41C -:108C4000379205E1907CD5866B56D2C7ED7D80AF1B -:108C5000DB110EC06B97C45A517F17199C7125E820 -:108C60008FC5FB14EED77D3D4A05BEA96C7FF73852 -:108C7000C25B69B1F930DFC21CC6F37D41F912BD98 -:108C80009FABF9259ADFAFF92D5A7C89FE0DDECF17 -:108C9000C7EB00BFDD0C00A2FDF159BC0DF0FEE7F3 -:108CA0002FAB994E21AF0AACA352AC6336EB25B87B -:108CB000D8B7D7AE4D03FACC12F8A8EC86B8300777 -:108CC000EF337617E0E12E85C78B7739203E0CE233 -:108CD000A3D99343FBF89B9E1098E77AE3F5FA7FBC -:108CE000AAC817FCB371A6D676831D3A0D0C70B0D6 -:108CF0009EC73485A3658F82F1803BD380FC5827C3 -:108D0000EC1A84C943DB2321AF8586BE1C07E0B77C -:108D10006BCF3764FFF6EEF9E623F4E7A67CA130CB -:108D2000333C5FF8457E14EA07E60A9DB7EE8FAD47 -:108D300056C6AF13FFD48AB5EFAFC78C18C267A170 -:108D4000F637E79F5F8FF37D7946E1BC2DDE5F6EDE -:108D500072A7DB6DD8F2787FBFC4FD1DEDFE7E23C8 -:108D6000C00DD737C568717FAF42F919F89983E80C -:108D70007C17C6FBB901BADE75AEE20B2567307D04 -:108D8000F0F7FF23DED7E2FCB744FCC0F69D30A924 -:108D900000D78CD64714F4A36724C9CC19F4DE3B62 -:108DA000542B7306C5FB6FC4E8FC907DAFAD9F05E7 -:108DB00076A4AE477684A1BCB66F3F9483FD5ED99E -:108DC000611D828FF4F89DD1FE8882FC9F10CBE557 -:108DD000E67AEF2F1C077C722BD29D911F77B14052 -:108DE0002239D2D377EF9E9FC7F6650F8FEFE1E868 -:108DF000AFA7C36FCE1747215EAE470F3DDF76C2E8 -:108E00003A3DB03E1FACD303FED6DE7A3BF5DFAE73 -:108E10004FA2BEC6AF751DBF8C457F4DE3D3B25880 -:108E2000CE375376AF8F65B600BD347C5D1474AB1E -:108E3000668EF9B3E0CF5D922382F48487F5261520 -:108E400004EC55F5B172F233347B552D671B51FF9D -:108E50006AF60AD3C2A8CFF4F6697E7A9111D5AA30 -:108E6000DE2EC1028DC8BFD50B43AF57F4342B1192 -:108E7000D433109D2449E043F8D51A3C1F3217C162 -:108E8000ABA7A7069F1E2ECD9FAE1674837596E1E5 -:108E9000D2E7AA45B48E417655ACF746EDA93936EE -:108EA00034CEBA72AEF4FD9C21F87538BED5DFD74A -:108EB000F44039BE20975A0FFA1109B10944AFF2B4 -:108EC000AB26E6047BC14686B1CF82F3EFAF649256 -:108ED000BD7B54D8DFE1F8A6F6AA81B96303FC6331 -:108EE0006C7BCE8AFCB35B69B662DEF136DB9CC676 -:108EF00028C053E91F8BE7A15F57D76760989A2A6C -:108F00006BBFB40FE3F6BAE3CC81FAB0B8BDAB04E3 -:108F1000F9ED6DA557A638FA4BC69E0BF20FDBDABA -:108F20001BADE83FB5C5C914A7EF8FE6FCA8DD6F00 -:108F300089E5FCD776E6F22CE710F73F13F74B4FA5 -:108F4000E51AD148F6C74750BEA1FC6903ADBF542E -:108F5000B25755A2FF718791FC7A885BFEF07DCCF9 -:108F600037B599B763AABEACED878FD881102DFFB6 -:108F7000E7B30633E60FE6488E97615CB9EAEFC2C5 -:108F80007EF9BC54DA8799F47F65F25FFD774B94E4 -:108F9000F7280776C17EF93DA95ECC3FEC9178DFDA -:108FA000D3C1F3FECCEE899D05EFF9A03276C23A2B -:108FB000E229AD7F4BEE3A261838289E7A6C17DFEF -:108FC0003F7AAC4CA2FDA3327B0AF304F155F9D3EE -:108FD00040CF3CE0C7F6C462E4DFAA0A997983F87F -:108FE0007ABECBCABC41E3F7877178FC92D98BF982 -:108FF000124D5E670AFEAE5E181B327E0EE37EE205 -:1090000042D66C44F9AE13F0D415013CF0FC4C117F -:10901000A7DEED4E09796F256641606856DC68B2BF -:109020008FB3BFEC23B33A473E796C31BC87657090 -:10903000F9D0E4AC4CAE69223E48921C181FCF9781 -:10904000C0AB9451DF85CAD1ECC9A1FD394EBD7EBC -:10905000089577BD1ED7E47C7E876CC4387A7E91F4 -:10906000E46043E803BD3FADD703930C8E7730AE89 -:109070009E7BD549FC35480F9CACF887F4C05B203B -:109080005B93415E7FA4E9839BD84DA80FCAE42D72 -:10909000EB913FFAC1AE9987E00FCD2E68F176399A -:1090A000C827F2033BCFF725CAAE829CC606E2ED85 -:1090B00001FD007E8363087FE657B16921FB490308 -:1090C000FA22C86F3016FCF37E4319F88BA65C8435 -:1090D0006F24F3E4919EA2FC1EB43ECAB3255DA2A8 -:1090E0003C4A1DC4F114CFB35F125CA8D7A498000A -:1090F000DFEBFD092D4F3B42E409F4FC3090B79BB8 -:1091000067F4229F69FC506EE772513E4FA6FCB98E -:109110009E3FB4F75D8F2F7C12F085F477F842C83C -:10912000D38DF2C5218D1FD259FA8DF083C6071A4F -:109130005FE8EDC5415DDE65387B71F23AF6E29D90 -:109140000C23E965BD9DD0ECC28138AE7FC7C7F264 -:109150007D8A9999F36DE8578C407D80FE9EB037EB -:109160000379A30D9C0FDEE95BAA486837500FA472 -:1091700006E15DE44D35BEAB7D9A51FEB052E89FED -:109180008B1D3C9F56572A7B2DF06749FB73EB796B -:10919000DF48F9B622A54BB1C0BCB31D9203F3352D -:1091A0004E917F9B75D5E455293F3FF47E7A95E03B -:1091B0001B8C7370FC6CA7E4851074901EAABACA4D -:1091C000EDBE5E1F5589FDF22ADD7EB9294ED0F530 -:1091D0006676F3BFD2EEC7C72570B919868EDAF36B -:1091E0001A1D35FA4DC0B1283FFBBE36A911DC3F30 -:1091F00046FACDB8AAD03CA3E242FD962FCFE7FEB7 -:1092000027C574627C5DFB25937BFCF0F05FCF2F5C -:10921000BD59F3C3855FAEBD7726C8780A3A863A52 -:10922000FBA1BDE7BAF6423CAFA7D3E4B8D0784281 -:10923000A387A64707E15BE8D9E1E8753D3DABE9C7 -:10924000B37FB59ED5E6D7EC80F65EBDFE1D2E3E03 -:10925000D3F4E9531B0D9417B94DC4C1B7893CEB46 -:109260008342CE970B7DDBFF178B01FDAC6D9DDC40 -:109270001F7198ED87D06F08E4F3385D9F8C601EF6 -:10928000DC2F674AAF85F62F8B81A4B87F99CCF786 -:109290002FB7283E17E96987C21A405EFE2AF216E8 -:1092A0004FEEF52C463DFDE4E93106DA47577CBD2B -:1092B00018174FCA55683F28DAAC52BEF76287D9F3 -:1092C0008ECFF5EFFE5E9711E7F90B7360A8F67687 -:1092D0008779603F06F54299DC23635EBEDF0FBEEF -:1092E000388C9FB6D05782F1CE6DACB711E3EA420D -:1092F000A4E310F47B55675FF479FB920EEE27959B -:1093000044F0BA9FE980467CEFF43613F985D7CB59 -:10931000DB177DC9C85F1A94AF6FE37A0606119F09 -:10932000DC68DEBE107D3DE0E39FE8F40E1B267F87 -:10933000BFCDC4F773FC478C0CFD5E762E6EC8BCA7 -:10934000CBF5F2F8BB3BC39D6A24EEBB71FF7C7783 -:1093500067B253CD197E7C4E9FBF18F395DBB6CC18 -:1093600055284E14F9CF41FB223AFCED9058931545 -:10937000F369ED8E528C3F86DBE728F63B69DE1BF6 -:10938000C51B63CD9CCEA27EE9762163DBCE863BF6 -:1093900091BFB79D4D76223CBB057F6AFCBEFBCCDE -:1093A000E570DACF343955DC07F6475B1C2F13BF65 -:1093B000723E6F1931C68BFBADDB853C6C0BF71F22 -:1093C000CC8A0BDECFE0FB179DF59EAA33E9B4DF14 -:1093D0002D61BE51DB27F680BC505D4E0C237E32E2 -:1093E000B21686EF6D74B29F633B7D9A1A85F8BE04 -:1093F0001CA7ED47AA519467F8F64A816BFC60BC44 -:10940000EFA877513D496BFDC22A05607CB3DE4D64 -:109410006D5BFD726AF7D4AFA6FB6B0F453E8E768F -:10942000BFCEB9A04A09D21B9FC5F3FC526ED6E944 -:1094300012E473F60D6318EF4C7FA24F463D71FBAB -:1094400055584748DD887219F14CF9CBB4403F5567 -:109450005A12867C79FB55E8078D97E2A3391D9A4D -:1094600094A65B0A485A881FC2E29D17E3E0FA0FF0 -:10947000ED2E7F5C3CF241F5BE0B8CFA97F1FA0EB3 -:10948000E96EF9028CCBF31551DE380FF3C6B9340F -:10949000ED62C4DFC42E13ED7B6BF9DB5C31AFF3FF -:1094A000ABD03C729EC8DBBEC9FA289F9C6F81C0BE -:1094B000CA807071FA39A5F94912E6FBE24D0EAC8B -:1094C000579898E6CAC37C6B573CA3FC695757C2B0 -:1094D0004815F0E054785ED7A9E575D9DFCFEB7673 -:1094E0007F1AE9217D057E0AEAA7EEA3910E1FED02 -:1094F000FF59C8FFDB810F627D4338AF1760F3E689 -:10950000511EFD760B5F07D89FF878CAFBF9F61D50 -:1095100086E77E7B99F17DC4DE93B43F5D62C84CE3 -:10952000EC0338F74963A3B07DF1D3C86C6A8F466A -:109530009E47FC741AAC2ABEF7C37A56857567CE6F -:10954000F76DB49F31FD7D9B82EDE1FA3EAA477B2A -:10955000BFFE1CB547EAFDD41EADBF4AED3B701DF2 -:10956000F9E7103C8F6DEEE2087A6EC7A20813C2CD -:10957000DB19C9B668EFC17A335FB8AF1593F9EF5D -:10958000C57FBECE7213D83BB37BBC3481B113F11F -:109590009FCF54A07F68C6A87FFF0BDCFFDD4F2E56 -:1095A000ACB3005CF38EDA5A7BA0FFE94F2EAEB36A -:1095B000A19E3D140ECA0EF546FF41907496873663 -:1095C0003D9971053B19FAB1A2EFE99F590A245F51 -:1095D00050D297C580B5A6FCC43FD302785C6075B5 -:1095E000FF1BF64D9E976696DE847DE6C17A2EBF00 -:1095F00064A4F89E8D94E2B07E6599DD7D2C3EC812 -:109600007E3BA53FD2FE51815362D1714457DACFE0 -:1096100062F653B1C1F2B6CC5E760CE971473CDF1D -:10962000BF9A384D7206D749E8C74D3CA396229D94 -:109630000ACE9537613BBB229AFAAE85939A509E2B -:109640004B6DC33D5F42CF2F8837127F162B524898 -:109650007D887E5C1E3013FAC7FE03E1941798786C -:10966000CCDD8875A36549A9B9B2D0798CFAD11B34 -:10967000711F6D62E587A5B1283F36C981E6A180DB -:10968000F535C5C661FD231644E1BA9E2BC1FA9D8E -:1096900089AAE440B41539BB5AF1F9224784A308DA -:1096A000FDF1636A299A9CA3CA84C3F9306E46BA55 -:1096B000ECB0C044477D774CBD00FDA28C28CAE3C6 -:1096C0001629ABAF1CA67E84A341C5756CFC792D11 -:1096D000CD63267BBE6356C97F20FF14BBA228E75B -:1096E000576A3B3537B82E0CD64D7017D9656F9831 -:1096F00084FCFD83523BF4778C9218CACF515FE60D -:109700009FE97E77B81A0680EE30D94B71BE1D26D0 -:10971000C9BE96FAAE121CEF196354314F541EF7AE -:1097200045C8FC334AA5296710FEECA80978AD624C -:10973000E4A590FB3D8BAC64272ADFCF267FA8678A -:10974000510AD98BCAF7A71563DB63E07E7AE5FB84 -:10975000951574DFC0E3DFCAC5DF718A3EC5BB95CE -:109760008B5751BF4B4AFC777CDF95ECA85CCCA3B0 -:10977000CD4CFF7AAE12ECFFADCE24F9CF1579BCFB -:109780002243E6FA6900FFA307F83E4465B6145287 -:1097900037372BFF54483DA86BDA1721FDB9A59741 -:1097A00042EA43E7557E1DD25F304FAA0A1E5F7A18 -:1097B000209FEC6BBEA85FD2F24B458285DEA9CF1D -:1097C000A82A05B93C00ED03A01F8A7A45DE55E1C1 -:1097D000717506FC433D586AD3E577994AFBD91564 -:1097E000DD7CDFBA3CCE783AD83E54C84F707F411A -:1097F000B7FEDC0346B293B9D132E5AB34F82A4662 -:10980000863EAFF95F1502CE1D0677530CE5C79C67 -:10981000BDE87F68F06BEFD7E0AE90EF29A5EDBF14 -:10982000EBC0AF87170025FF4D0FC78178118780E8 -:10983000BF41FE5937AF4B835FDC50765BF3CF2BD4 -:10984000414F4507EB299B1487F576C3E9296DDE67 -:10985000E1FC306DDE6576173DEFDCFAD9D1423997 -:10986000A89F7A2A3626B8FFDA67EB43EEC79FAA8D -:109870008A0EEE6FFAAC0AEF4F57D4461BF0E34165 -:1098800026393CC89F3DAA82FBCF25C79C4DD89660 -:109890009D746399299B71C6D384EDD4F3DE1E3386 -:1098A000ACEB8E0C59C5B85DF33FF4F09A13781CFD -:1098B00072F0AA6AC5FDD31D1ED58AFEFB8E275401 -:1098C0002BFA1F3B9CAC02E331679A6135FAF3CE69 -:1098D0002C5E677855E8E16FE2F9F35A7B5A717FA5 -:1098E000837A11EBC2D127A8FDDA4F75E007D1AF1B -:1098F000CA1EEC571D54BC367CDFC127BCB6E07DC8 -:10990000C21BF5ABFE8C363A1EF96C4E887C96581D -:10991000EEAE0A96EF32FB9290FB9FC6A904FF8C35 -:10992000A48743C6DDA13E12D2077F3103FD9146D5 -:1099300013A33A598F81D7C9EAF1F8A8C0A3C36627 -:1099400047378619E354AA6BD38F739470FCE9AF41 -:10995000A727F0B86823C80CB6F72470F8F475B1DF -:10996000FA3EC47C0B713E983909F9DC61355C0123 -:109970005797391392EEA47AD93CC3A369D0AF4E5E -:10998000C8E2FDA9869D581F7B774236EFDF6AC883 -:1099900033821FF02B36FE4EAC07AF0D13759D0FB3 -:1099A00024D27E9816DF2886532F2EC638738F91C7 -:1099B00061FEFE1913D8BDDCC0BEB9D5CCE352ABF5 -:1099C00089D76D3F957AF429D41B6A987B7A02F97E -:1099D00051C52AE2EFBCDD42759D8FED2E4B44FA56 -:1099E000DF93C0F35C593BA726A17EF917BC7F56D5 -:1099F000C2C4E1DF8F75BE38CFF91D59E47F67DD42 -:109A00000CE89502F887F098AE87419840E72598D2 -:109A10003309F36C8DD1269AE79E04CE7F37DA0E98 -:109A2000AAFB8D32ACDE0EEDFD82FE0FE07B095FFE -:109A3000FE51737063CEEE1F35773CEF237D6539A1 -:109A4000D78F7EACFF3B11B4AFC246FA69FFE5E3A6 -:109A50007BB21CE89F7E12CEF1B7D03BBAB14FC5A6 -:109A6000FA0DEF4D582F9191E8AE453C2C327B6FAB -:109A700021FEB1AD8EC0F96FB41E78F07B21800459 -:109A8000FA544FE1F4D1DE0B38B5A03DF8589C03F1 -:109A9000D1E080F7FF00F9408367000E5D5DB89666 -:109AA00067AEFBA381F20C7512E83DE8EF3CC91CE0 -:109AB0001E98E7A2E6AF8BBC266E45E17BA61C5E36 -:109AC0005A628336BF6D258F737B95903CD7A4E394 -:109AD0008A7EBF83ECD654ED795D9E71AA886BA710 -:109AE000EAE2DA1713849D4966C9C1798035226E8E -:109AF000B8DC333A0AFD4CD45132E0D5A4CA6C72BA -:109B00004C40CE5B21EE674171BFC667E38FD9EF52 -:109B100047B8C71F63F7915DD7E61DC82F70BC5CBF -:109B20003ECEF132A12FE3A7D3A06FEC3632AF1AAD -:109B3000584F2107955DC6FFE078BBC98B75CB05F3 -:109B4000077E99E7834BE624035383F010A6863300 -:109B500035482F5A336242FAB2866F61CFF3C4FCA4 -:109B6000118EE49079F6C49477A37DCFB32D27FBB3 -:109B70001E357974C83CAC4709B1F3B028DABF9CF4 -:109B80000840FD0CF05A704C09B1E793E23CB86212 -:109B900036F9A4A2B3FFCD32CA41E199D0EB0786D2 -:109BA000A3CB70F863393F45FFEE1FC55FB4331494 -:109BB0007FB115A1F88B7785E22F7161289E46B899 -:109BC00043F192B27C5CC8FD9B56E786F46F7EBC85 -:109BD00030647C2A18A4E07EDAD33343C6DFD23C5B -:109BE00037A43F76C3A290F199DEA521F7B35E5D5D -:109BF0007143F41EDFB226649C9EDEB7B6FDAF90C3 -:109C000079357A7BE0DFBF82DEE6C4507AA70AFDB1 -:109C10001AEDE4F565FD46DBD312E8234C13A15E93 -:109C20008B6E7FF76BCC43788A55AA9FF3CC64B4D4 -:109C30000FFD82EC92500FA5C0148634AA5FA7FADC -:109C4000BB1F1B0C21FBE28989DCBE2726F27CCDE1 -:109C5000CF4DFCDC520AF88F64870C2C102F031EAA -:109C600022315EA678FAC7CF60BCDC14DD97A14232 -:109C70007C6CC6FE4D017DB9C8AC36F6013E26C8E7 -:109C80005C1F829E4C4B84F93F919E30723FC263B1 -:109C9000443F22C5C23C91B9643F287F1CCDE224D9 -:109CA000ACC78F0AE869F51A106BDF8A2C3A07F502 -:109CB0001E4282FEAF2586ECE8DD9A7E5A9E49FA66 -:109CC000E9B22DD40FBBFC401A5D3F71AF99F6FB92 -:109CD0004F883A446DFDE784DEFA53BD85DAF3F52B -:109CE000F6103DB67CE3FA08F41F4F64707F51BB59 -:109CF0005E82789B88AD2CEC9AC58EF9AC7BC0381F -:109D00004701BE5775F7452E62E43716E3BA6B3745 -:109D10005EB9F74DE8D719FC09DC3E7878BDCCC7B1 -:109D20008CFCCFEA6F5888FF343791C7E973C5FCC4 -:109D30000BA0B1039E1600FEA3B17D775A39F2271E -:109D40005CA7F369B3BB19D59FCC71A7D23EE35191 -:109D5000E6F8701780F89D4495E09CC75CB45FFFFF -:109D6000D1BDAB2270DCC07CDA3CC028E86F7C1C23 -:109D7000ED312660DC7F1BAF6F80F759F0BAEB9EA8 -:109D80009427D10E69EFFB88B92F7C88FBDDCC418D -:109D9000F36AF3331613A29F762C5FF9692CBC6F1C -:109DA000CD0103E513D6749829EEEA5FF1D7AD2F04 -:109DB000C2FDFB52FA6E42BBFCC98A6FC6203FDC73 -:109DC000BD01F410ACB130CAFD7062509C72E281EA -:109DD0002B11781FECEBA617D1386E36537DEF2789 -:109DE0002B368F09F6471F4D2CAAC5E7D8E41B3B3D -:109DF0006F58F27A6622D563097E7A58F0D39AD7E3 -:109E0000C6921FB52662809F787F13AFEFD0D6F140 -:109E1000A1E0C715AF7F5D107CCE7407F0913A8644 -:109E2000EF6BA920533B7B2EE7E0FD57147713C25D -:109E3000D779F57424F677BEF737829FCDBB31789A -:109E400051063D0581FD65EDDCE5C2F6D83CA43B3D -:109E5000C85933CEBFE837AF5DF81DE2A763F3A65C -:109E6000EFE3981B3C7FC9847D71083C807DA1F89D -:109E7000A09F85F3731D428F2AB8839E86E7991CA5 -:109E80002AF1B3931DC27D97C62E03C3BA9548DC51 -:109E9000B409CAB345CA06CD08392D49A09F855ECD -:109EA0007925F1E49D4DE4E787FA3DF96FAF08F1BC -:109EB000775CF08FFC9D97DC8D9807BAAEDFE333BB -:109EC0002C3145DDB8FF0381B0532A105B38F06BAD -:109ED0004B14FB22420F77A21C61FD3FCE85F97A1D -:109EE0005F383F670CA602F5F80F604DF8B02945C2 -:109EF000B4D2C50C0BE8C5BD897F78E669D09396CE -:109F000074BE5EEC37E2DFDD9CDF06FCABB7C791C9 -:109F10009E62DFC2DB100F225FA1A7533EC8078BF2 -:109F20000D9233F1BC6FFFDF22314FBB35467D1FF1 -:109F3000E9E03F20D33E4D98D2678A1E222E7B1344 -:109F4000F59E89FB4D546FDEC6F38116D5C9300EE0 -:109F500008B3DB27049FB36B17FA6ED5FE4F469903 -:109F6000800E170C3D91D9307FCDAE1D91E8C6DF34 -:109F70006B747F8A7CB7F2C40705763ACFB671144A -:109F80009D03F08DA6BA83F10AF328B983E1A8DB1B -:109F9000904BC6B8760325E3D9F8F6BC87501FD599 -:109FA000F9F83A716E2CFCCB6C63D4BFD8D6188309 -:109FB000F3D5FDB62319E567733C8F135FBF3A8E67 -:109FC0003FAF3005C77F99182DF8D96BC03863B300 -:109FD000884F2E5E35D038EDFDE3DB8A643BF043DD -:109FE000B6AF792FC543ED6615E91AF60AE378682E -:109FF0000F2339AFEB9CC1309FDF1FCD1C12DCDF7C -:10A000001AEEFF039D33EB30AB981F0DB337B31837 -:10A01000987FABD80FCD048EC2F34ADA75ED7D611F -:10A02000ED3FC55802F981F2B4614A33BBCD168CBD -:10A03000E708C2733CF2533CBEC767C0FC88FF16FA -:10A04000C65E26B80270327AAF066726F9735B4D9A -:10A05000FEB3787E05E0B223FD33198793B58F55A3 -:10A0600031BE0FB33B691D6176D5E19106C35597AB -:10A07000C3BC68BF7FBC960DC82BCA6F5D78A06F4C -:10A080000119D83A9A09F9B63F5B3A2DB80F8A649C -:10A0900072E0F9711B629E6D1A49718347C63816CA -:10A0A000DA88185CA7CACF3B636A2897E301F7C533 -:10A0B000AD167E7F603CF0B70DFB363ECE1165B726 -:10A0C000CE94484E28AF572BE4FD31C977F67690F1 -:10A0D000D3BFF8F6E6A8004BCDBB7B884F571ADA02 -:10A0E0005F1C0FF7375ADCF94980CFB74E1AE81CCE -:10A0F000E99F5E0BF35662FCB87B63827308F9D06C -:10A10000CFFFC3E36B9F4F41FAEF9654CC9BF61BF6 -:10A11000FDA310DEDAF6CF4D548FD0768AEA938E07 -:10A1200024B99DF89EC96D0DB46F3C8535D3BE71C1 -:10A1300096387FDD92C4F5C7E563635E6E08C2FFA3 -:10A140008349DC0F637EF7CD2837ED423E3BD12FAC -:10A15000817697F08F7675DD9DA606E5FD1AD8DE2F -:10A1600014C4F75AF636B5DAF57E2F3FCF98F5913D -:10A17000E53E6710FFB993B89FE716EFF327B917CD -:10A1800024A1DC769D3645AA785EA56514DA911681 -:10A19000F09FEC43E065406E757254A7F84D38BEF1 -:10A1A000EE1C3F770A746EC2FAFFCD1FB58D5B02BD -:10A1B000D77701AEB1DED373C24C758FBB8CAE14B2 -:10A1C0001CDFF0E15739A8B72A1069F0BFAF3A5643 -:10A1D000DE8C7803BE2F0E47F9DACE488F69F299EC -:10A1E0008DF209CF6723DFE7633F93F4F056532FD7 -:10A1F0003FF7B98B9FFB04BE273900BEB7A39F90E2 -:10A200006D0739A0E7C7927C6FED35D0F9540FE8A0 -:10A21000F15BA85F5C85FDADBDA576926FCCC3E711 -:10A22000A29CFAF6D23C2D108320E924E60AF61F00 -:10A23000DB1323898F35FD783091EBFF960C350ABF -:10A24000EBFFADB21C2217417690F7859DECDD50F7 -:10A25000FCEC0BD3D0DE09BB20FC27769CEBF94746 -:10A2600085AD5AF34EE1EC2DB0CE3587E5817A6E9F -:10A27000F4577D824FF60AFF15ED849AC7EB67F01D -:10A28000FAC40DBCCEB5C0B9BA04CB38265734EFEA -:10A29000C3B6D0D55282678EA72DECDDC7CF1EF393 -:10A2A000F3E3AD7BEFC8C27DEAFE136686FB24AD07 -:10A2B0007FF3FFE175C0C3773B01FF43D825580EFC -:10A2C000F11F58EA149634F87EBFA4E98FF9952857 -:10A2D0006F175BE5401FEC612D3038F67F9D54F51C -:10A2E000AC07004B1BE17C1D59A230D94D6DFF918D -:10A2F000BF25A02DD8758CFB4DAD266716F24FEB10 -:10A30000E8D0F3FA5AFB62123FE79C6F6643E625FA -:10A310000F09BB37C6C39E413EAA6D95ED5EA0FBFB -:10A320008556D96902FFE6ACD39D806765CE31CFF3 -:10A3300082A968E745DCA87D4F6519FA2760A71E4A -:10A340007C61501EDF807CF450BBC47E066B5EFED9 -:10A35000D2D0FB0A35629E87DB36EE4F013AAE78EB -:10A3600025745C8DA813ABD1F92F8792447C98C6D5 -:10A37000D2D02F01FE21BD605458B719F8F5C16441 -:10A380007707C61B9BC5770C407F921C7608BEDC06 -:10A390002AEA04FC5B25DAD7CB7CD52B1BE0F942FB -:10A3A000C52BA39D62D0E23EC164A7BB1CF10BEBA1 -:10A3B0003E86FB35CB851E5CAEF9655EBE9F01E631 -:10A3C00096FCB229CCDB1889EB7E5572F854FC8ED2 -:10A3D000C8A03A5C5A779D5877CD8623FB318C5BB9 -:10A3E000D5123AAE4EACBB4EB76E6D5FFBCF49BADD -:10A3F00073C837B86FF16723F7133E10F368F7CDD2 -:10A4000023B83EAC05F0906E355ED9EBE57E9D0D30 -:10A41000BFC373BF80F77E41EF3AE633A5C0B8559E -:10A420002FF075B26743EB3F1F6C7DC484F1959E9E -:10A430002F966F31923F0A8833A1BFA8E78B156230 -:10A44000DD2B74EBAE754B3AB8B89F3C18AE960551 -:10A4500048D7555B8C0CEB11F5702D6B59528E7CE7 -:10A4600036985F395D5688F90270AEA6737C370A5C -:10A47000E7A811822FC7B17144978AD81BA28BDE3F -:10A480008FDDBE7F9C15E5FB72F7688ADF35BAEB7E -:10A490009F2F177EF08C0D8CDA0B6D25D6F118A747 -:10A4A000F4181C924AF156E478C0475E87CC2AA182 -:10A4B000DFDF9EB6DE0378CF3D9C5F85F17CDE61F9 -:10A4C000039D77DBD99D4FFBC07907D263D3281F4B -:10A4D000EDA0EFCDC03C643FFB7B72D7E3B980FEBB -:10A4E0009ED27C9C57827168E773851D68E8C9B568 -:10A4F000069FEF2E18C1E3F5A7923EFB31FAE13338 -:10A50000B61BE97CC30CA3FF3DAC9FDAD9ADD0BE2E -:10A5100075CDE1A56BC390AEAF49B46FBDBF774DAC -:10A52000DC62E4AB76A31DF7A1FBDBFF6D2FDEF74A -:10A530006C91E87B12751D65595BA19FBB31CF11F2 -:10A540007CDE2B375A25F8D8082BC5C3336E3292E0 -:10A550005D3C9F6CFD25FA372B9C1B498ECFEFD9B4 -:10A5600069A2FAB9AD1243D3BF3F69DF1B888FF3ED -:10A570006F1E31A1935DD27AC4D4F777ECFD052F1D -:10A5800004FE1407379B304E59B551EBF799904EA6 -:10A590002EE1FFD4BE728AFA2BDA24D2332B5E92DC -:10A5A000E93CFBBE8EB74CC8C7B55B2496981A74BD -:10A5B0007F8314F21D84A58CF3C152A1675632EF3C -:10A5C00053C9306E6533AF23604F87D6E5AEDC32BA -:10A5D00087BEDBB4AC79687DF3B0E0EB87301EBC9E -:10A5E00015BF83143AEE61EDBB5C3A7E7E5CE3E717 -:10A5F0004C9689FCFC55911A950DD7BF3AB2E2E60C -:10A60000A1CEB1F7083BACD9C1CB3E03D911FDB8FF -:10A610008B6D5708DEBA9ECB26B483E5ED9708EF25 -:10A6200095ED5D54C7711773D7209EEE6AB7DA5166 -:10A630008E2BFBB85E9AD96EF67A25BCDFD284F4F5 -:10A64000ECEFE4758B9E3D12F92F9ABE7A48E0EF4D -:10A650002181BF874041A7E4A21FCBE3DE873336C9 -:10A66000EE8F81FBB5E27ACD817D91E8EFCD6497E5 -:10A67000EE457AC07B18BE87BD148AE73B1987E395 -:10A68000CE2DBCDE596FAFFA4764CDA6FC23C49D26 -:10A69000084FCD96503CD7EAE2ED7523B87DDEA495 -:10A6A000C373A59F59B3110E5576786974AF82EFC5 -:10A6B000EDCE9128BFDAADA6450DB5FFA8B5EF09DF -:10A6C000BF59EBCF16E7AB5BECCDB6E038D894CCF6 -:10A6D000EDFF8A29B207E934103FA4EFCB510D8179 -:10A6E000F801E286DF8C88E771041674BC3B526681 -:10A6F000717181F8E18749EB2B73A15FB785CBF9C5 -:10A70000C5C9301F7EDF4B61E45FD66D31D339C0E0 -:10A710003AA03BC509EDFC1C83AB5D2A437A83FF5D -:10A72000FDEE888978AE8619E360DD73DA389FCF55 -:10A7300029BD447C72209DAFF7B2A2260EE58F6B37 -:10A740007E389EC35283CF3F805CE2F8DA765E0F9C -:10A75000D4BAF7EB51A9A8D73AFE3A6A09B45746DA -:10A76000F0F56B7E9E1FFCBCD1DCCF3986FEE78303 -:10A770009ADCD8F93EDA83C2CE30A989F8BBD6D8A4 -:10A78000F2760CFA4D5BF9BE3DDB6DC46F9CB18671 -:10A790000F5E6F8A81755F7C5DA27A347CFE09E072 -:10A7A000B38B4B5B4EA31FFDD5560BF98F0F828FDA -:10A7B000383D77B03C6A72AB7D77AA81AD257F7258 -:10A7C0002D6BA27695E0E38B6D8D26CA9B79839ED7 -:10A7D0001F3DD8EF58A5E33B537228BF357C104E80 -:10A7E000FE5FFF01D98EFB2780A7FF4E0EC687F0C4 -:10A7F0002F5AF786113DFB8FD8C85EFC49F0D979F6 -:10A8000091376E982CD3FA0D53789BD5F9D668A45E -:10A810001FE21BEBDE3777BE358E9FA7F612DE57A1 -:10A82000BE8A49F120385BAC94DBD3FA0D1F2CA211 -:10A83000EFF0D4ED19806B8C292E00D770FC2F49D6 -:10A840003C1E3448A1F160DD6ED9155CEF05EBB913 -:10A850000FF54F929003A6F813D02F1999AC92FDE3 -:10A860006A68E7F43474F016DEBF80E73B8CF4FED0 -:10A8700041F78B3D3578FFAB542BDF4FBEEAA9C4BF -:10A88000FE7747CB544FF9DD0F568C0DD69B0CE16C -:10A89000047AD619FD0914371E31107C75472E270E -:10A8A000A4DB501F6D2CB567A3DEE1FA6EFF68EBE9 -:10A8B00072E4630FBE373130CF6BC2DE325C6F1291 -:10A8C0007A152FF079C57AD7B2B9223EE67C942D5D -:10A8D000FC3D882B26264F1C1C57DCA83F09F6E0C0 -:10A8E000E86209EB89140FC6B53B8F737DD0D0F1B8 -:10A8F000D0A7C8E7759F98A9BEEABB9D0F8DA53A62 -:10A900005BB7FB56F42BBEEA7CF856CAF3496B09D9 -:10A910002E0FC29784FECB8709580FBAAAE3C3044F -:10A92000B2AFBB26AEF744A09F927B275E07BF81E4 -:10A93000F80FFC17E2BF9D3DF99ABF62C579571D1C -:10A94000505C889F5507F20F55A21F71B8381FD56C -:10A95000B874389FFC953CF4576C01FF455B4F651C -:10A9600032AF77E9EF0AA33C81C44673FE61E92167 -:10A97000FC53D3FA0ED9F59A3639A46E507BCE9D8E -:10A98000ACF07D7E8D7F5A2427F1C776DED6B4EDFC -:10A99000A4F5AD34B610BD1BB618F9FDADBCD5EAB3 -:10A9A000AA3D2CC683F8388497800E334D5EFA6E2C -:10A9B000C5C154EEBFEBE9F15932CF631C3CE1BE97 -:10A9C00019F9E560917BAC7D08FBE061C53C3E95E3 -:10A9D00004BE5BF97925FDB853C93C8E8F8C0D3DC3 -:10A9E0003F3A605F9239FFCC340DFD3DBD9F69F267 -:10A9F000C4D83306E08BA39546FB3AE1B78F08FA3B -:10AA00005E42D55D46F20F8E32FB3B5867384BD322 -:10AA1000AF93B95DD5F2DDAE0D2ADFD7197CAE91CB -:10AA2000F4E47C6D3EFD7969E1D7CCD7F935EB359F -:10AA3000FD37868D41FDD722CEB9ADC90CF306E7AF -:10AA4000A3F4ED7EB18F81E775B06DC8FC98F23646 -:10AA500007BB4EBC41756627C2D8689E97A3FCF51C -:10AA6000AA61F2D70D03F2382F84BF347A5C10DF6D -:10AA700055D1D3E30D81776D9F2D5CECB39D56DCF2 -:10AA80006F24535DD67913FF8E9A9FE2AB864CEE0E -:10AA90001F5D2893685F1CE01C650ED2EB1746F023 -:10AAA000B8EABB0B24CA9B76E1788C9F5A24AAABE8 -:10AAB0005EE5EB35211F8D695DF224C9AB871D630F -:10AAC00041DFA9986DE17671806EDABA07EC568C99 -:10AAD00087EBE1386A713CDAC159C2EEE9CF218DCA -:10AAE00065BDE51857563B2507EEDBEBE93D77E101 -:10AAF0008477E2FF013A9F4B761F21FDD67B7901D7 -:10AB0000E63F0F667E3E0AED65ED307CFB3BC1B74C -:10AB1000DAF7591C63D546FC3EC98F12DD9F207EB3 -:10AB2000FB0DDF468E63F87CDF7FAF91902E8CE8C3 -:10AB3000319C9C9C12F39D4A16DF258CE3FB24CBB1 -:10AB4000B18FF26AF48EA4FC42F68DED4B35EC7EAB -:10AB50003707F5D6C5AE0339A6203A9E5F03F28EBD -:10AB6000F6A3635F826A0BE63303F1972469FCA6C0 -:10AB700008BB18CA77E791EFB2B1FD30321DF5EE90 -:10AB8000F6A391B7E07CBB783BC09FED328D837814 -:10AB900067CCFC8860F89E24F82EB4F07918EB1B83 -:10ABA00053353EF87EE3707C6B4CE1F584217CAB41 -:10ABB000ADB705BF8783FE7DA799BE8783F9E6E819 -:10ABC00020B9484DE1F230497CFF660AF3D0F70026 -:10ABD0002789EFE04C51984F89C17D2E9FCCF765B6 -:10ABE000F9798602C1BF93145F17D6394C11FB3235 -:10ABF00085AC97C64D677E6A9DCC4EE7148A9983D3 -:10AC0000DAC916DF9D9876C96E69A1FA3F5F821294 -:10AC10007DD622CE430C41B7C0FA15FAEE0DF1A550 -:10AC20008CE76186FE6E4A650A9773FA3807D2F799 -:10AC300002A3FC147EDF0C5F325561155877749BBC -:10AC4000C22CE100EFF6B70D24BF9D7DAA17EB40A3 -:10AC50001DB1E2B92F18D5BB4E7272F944D382757B -:10AC600012DA7AF5782884F9303F364981C892F0B3 -:10AC7000E8A3F7DDCEF8398D22A6D207566EC78F2E -:10AC800027935EF7539C54027112EA7583C543F80B -:10AC900028C3E4CA44BEBF1109F314364BEC38EEA6 -:10ACA00057A4F1F56AF3170223E0B9BD32B15E4C47 -:10ACB000811E8FE1FB1E9154385C6AE7DF094AA0D0 -:10ACC000EF04DD285EFB13F8772123EFF75FFC7EAE -:10ACD0007E60FFC781DF0D8A0C7C8FD281E74C300C -:10ACE0007FE753CE07FBCD77A72CAD4E9918A897D9 -:10ACF000636EA6A25FA1AF9743F49D0B3ADFACD57C -:10AD00007BBCEA9DABE2B9B98571163A4F9B6B19D2 -:10AD10009587762B23D15D9D42751F5B6EA14914EB -:10AD2000EF44574480CFADCC3919F11CA8D7E3DFED -:10AD30004F1A38CF94C0E8FC9FD5CCEB199F01B9CE -:10AD4000C0EF178154A958D7C29E28A1FAC7A7A25D -:10AD50002D0E3C87604678AD01781B2DA2EE47573B -:10AD600077D96833D0F7381B59389DE79E15E6FE32 -:10AD70001EAEFFB188623A2F9DB56D5A12F983B0AD -:10AD8000DE69DA7A0D83EB10B1FE0F9FD3D7FF692E -:10AD9000EBC2E3EBF85EBBC097B64EBB76DEC7A94D -:10ADA000849CF7D1D6FF4C385FA71177E2D3E859DE -:10ADB00015F5837E7D1A3FFC3FDDFB356D605C0041 -:10ADC00000000000000000001F8B080000000000D1 -:10ADD000000B7B2ACBC0F0A31E818565181826F1D5 -:10ADE000A18AD112CFE066607804C42C3C0C0C859B -:10ADF000407B23807424101F01E2A340ACC2CBC06F -:10AE0000100BC471403C07C89F0BC4A5409C05753E -:10AE1000632B0B03433B107702713710EB30333059 -:10AE2000E832136F7FBE0803C31309045F51126831 -:10AE3000A734FDFC3FD8F00A7DFADA276DC0C0B018 -:10AE4000D502C15703B2B759A0AAD96E81DF8C1DB4 -:10AE500068F23BD1F8BBF0E83FAB87CAB7D540E515 -:10AE60004B693130782285899D067EB7A0E30AA020 -:10AE7000DE4A200600FB72DB43680300000000008E -:10AE800000000000000000001F8B08000000000010 -:10AE9000000BE57D0B7854D5B5F03E731EF3C8CC9E -:10AEA0006412420818C2092FA30D382121058AED2A -:10AEB000400091A206B50A1575C22309794DC0C795 -:10AEC0008FB56D0682111034582C51A39D2028781F -:10AED000830E3448908003581A7A5183D7FA687BDE -:10AEE000BD4129200412F185DEB6FE7BADBD4FE6E3 -:10AEF0009C9319E0DEDBFFBFFDEF1FBFF6B0CFD99B -:10AF00008FB5D76BAFB5F6DA7B648B8B484308F906 -:10AF100016FE7E40C8748910D23FFA74BE4E549219 -:10AF200048485D0E2DA710923E9C848840C8E46A74 -:10AF30005ACE23E4D13B49C89A49C8FE2316FCBE29 -:10AF4000CACFCAB45DD8720DFD3E82BD7F328BB6CA -:10AF5000A3EF9FBC2062BBE04C12DA4CCB4984F6D5 -:10AF6000368CD021FCF89CECADB78FA2F51BEFB46A -:10AF700010AB4AC8137418329E1017F1D9096DBA74 -:10AF80006A38EBEFF19996E745013E46D2E6D3F2F7 -:10AF9000EA29C5F9AB69698DCCE06A9853FC7C90CD -:10AFA000F6EFB10CC379D07A4F3A69BDC7DE2F21D5 -:10AFB000AB69BB0D732D427136ADD7A4CC0E65477E -:10AFC000E7AF3DE71289B70B5A2DE3E0E9E3CF88FD -:10AFD00002CF5F4CB4E0386BAB193E683DC592467A -:10AFE000484BC7019B9FF6B7B6A2E5E834FAFD913E -:10AFF000E1162FC52079A4E380FD4A3A7E30CFE2E6 -:10B000001D416BA74B11C1E38C8E379E50C0C7D238 -:10B010007ADE1D36D5D9B73EED7712CC7B0DC5BB98 -:10B0200098196D3706E0A4EDD6529285E9B8BF9421 -:10B03000BD8761DC5FDE902C0449B4DEF50024D4CA -:10B040009B6B21115A8F483D3642C7593DF16DDB4C -:10B05000085A7F75A1052641D67AB5EF5E3B81FE81 -:10B06000A68E3C3C1CE87A3DFD0EF3C87E7C36CCB7 -:10B07000FBB1290A01FCFF52A0F5288A1B8A941F04 -:10B08000027CAE6AE281F7F4E98B85D756C18670FF -:10B0900090351B08C9270002FEADF685560E05FE49 -:10B0A000CA235E28A77B697B67DFF69D8215E9D2FC -:10B0B00020070702FEE2D16F38C7E7EAAC2576A089 -:10B0C0000721F56985A308590F78824125BF3ACB3E -:10B0D00015ADBF5260F85927139F40E79790A7849A -:10B0E00096513C5BB23D7360BE4EBF42AEA3E55588 -:10B0F0004270A0087419A590CD2AF2857D042DAF69 -:10B10000BD2AD90BFC572784D324F87E03FD4EBB00 -:10B110003C5038660EF067A357417EA6FC7318F0CA -:10B12000BDD69F4C56ABF8BD03DB3B877BAC880993 -:10B130000A0FC54B3FCA4B80D79C9BEAAE1F06F453 -:10B14000196BF10085560B93D4F9203F49360F8CCB -:10B150002F8FBD19E927F74F16888EDE3F077A53E8 -:10B160003C3DAA16FE1C9E4FE77D943482D65F9329 -:10B17000F34A03D0E999FB6D48BF67C6762C06B940 -:10B180007AF242EEFB7E944BC5BB99F6F36CCE8906 -:10B190004C42077C7CFA474980BFC1C3EBEF216E6C -:10B1A000FA9CD953434653F8487DE1824CE413E1BD -:10B1B000168AD7C14B15A2DA182DBF25F09DF8C20B -:10B1C000D9ACECA4F319CCE9DCD2F1B6AD08FA9B0A -:10B1D0004B2223DDF8DE969A1CD53383F348249561 -:10B1E000F6FFE4C24328E7CF5C9DEA65729E86FCC9 -:10B1F00092C1FB4987FA54BFA4D94830813E07B7B2 -:10B20000F7DC0C700DCE3A3117E0DCFFC62101E807 -:10B21000F6ECE85415F45192BF837452BA0FCE7E07 -:10B22000F741A8E77286D20AB3B1FE5FB19D09FE6D -:10B2300066D5B709F0B64DA83E0CF409E658BC8CAB -:10B24000DE4C0FAEB93735047A64B0E34FB3C4A116 -:10B25000C80784A452F83C04E5A44E88D88641BBB4 -:10B260000758BB212424009E076705178B6EA8EFA3 -:10B27000170A5D7DC76D018D08F241391DF875BB58 -:10B2800042CA0A63C8C16B5C9EEB04321BF9994841 -:10B290007F03BE1992C4F8462B3F0BF0D071B7BFA5 -:10B2A0009EFCC36C0ACFAF960ECD11293C8F42BBDA -:10B2B0001872B396CB81A39D04058AD7FDBFFB9D71 -:10B2C0001DF0B6DD424AA1FEA4ACB0AD93D315E8A3 -:10B2D000B190B0FE1BB337DA505F0859C8770BC77F -:10B2E000293EFB6890BFE5829FB64FF330BDECF27C -:10B2F0002A21D0CBAEB4A060A1F0A8D9C4B33193B9 -:10B300007517A4F89B07FF00469758FD356B9342CD -:10B31000ABE9F779D954D0006F1457163AEE02C250 -:10B32000E639CF5BB718E84748A105F0B9DAC3E8BA -:10B33000D308E3D0A934A6B37ED6DE4742CB818FB3 -:10B340003CACFD706842E9363CEF95FF25D07ED3DA -:10B35000793B907B68979016B259683BB5DA4210FA -:10B360003E29725800BA8F4A55019EC634EFBFCCB1 -:10B3700004F8674BDE8DF4F3708083F6D3586DF1DB -:10B38000A1BEC8539A404FAFF6313DAFE12B938F2A -:10B390009BEE8D0874EE2493EA49C4932F62F74024 -:10B3A000399BC19399C7E6D50BFF2825B49C364E2F -:10B3B000B74508D4D3F050CCFB2BE6F370A68556E6 -:10B3C0004A00771E839BAECB084F7AB6D2047290A8 -:10B3D0009EC6FA53297E34BC035C0E0DAE3C5A1F48 -:10B3E000F4B0576902567070F88AB3193CFB8FBCF1 -:10B3F000DD2EB0FE50AE1C1C5E079F3F017853B996 -:10B400005EA7FD35CB1141A4F5436389BA918DA6A2 -:10B410004AF9D1EF8F57533CD082938F43D65B517B -:10B420001EE8ABE0B7940FE6D7D37256543E46AC55 -:10B43000B41AE4C5C9E74DEA991C51B68940BB4C22 -:10B44000C2CA1628D379146719E58C7875650A87FE -:10B450000BF89DEA9F65E315C63F57313B86105DAB -:10B460003DE0F3B1EA736BF0BB82EB7AC64F150394 -:10B470007C83AB53278BA04FDA9FBAD9027C752F00 -:10B48000B18889C8CF42AFFEA2E3ED5812B1C32400 -:10B490001DED85C980B78CEAE4C90AE0B1DD8F658E -:10B4A000477BB50F9FB0348D216410D18D9309FA7D -:10B4B000D553DE4CF14AAA9530E8EBB17A38E9F77A -:10B4C0008CD7EB6701BD1E5E7C6820C86FAAA9FD02 -:10B4D00068CB5094D3C1AFD35A38FE899F41FD55F4 -:10B4E0005C9F3800E231F87C1D9E839D54CF523D15 -:10B4F0009D4111AC8C89EA8BD557BD9BE37772FED9 -:10B5000049C667049E66BDA2AB7F15AF1F142E5AB5 -:10B51000EF04D6D3E0317F3F2758504FB9C0CEA4B7 -:10B52000F87D8C78E6E0BAECB5E0BA98C0DF87BD6C -:10B530000726233DC3C42B6482BEFD9B55CF073F26 -:10B540008197A06FA530CA8992E140FB90CA710231 -:10B55000AC7B8D527529BC0FA73B08E88503530FC0 -:10B560000980CFF456FF109043CDCE9DEC0DA7C1BE -:10B57000FB470EFBAF44F98C63376A76A2793E57DE -:10B580005CBB1CF5C1107F4F3BACF7CE0AC97B1DDD -:10B59000F0979FC2E5443DA992EF52F8BDC165A066 -:10B5A00067553F2D0FA0CF0AFE2C65DF57D594E6D7 -:10B5B0001E97A2FDAE1A4EED51AA17D777ACB7DD94 -:10B5C000007646B54505BE5DEB7DDBE673427972DC -:10B5D0003FC0734BA166F74504182FFD1D1FDA7994 -:10B5E000633D8A0794D6286B64A047B75E344E7DCE -:10B5F000770CC0416EA5441C189F8E74BEC867F1BD -:10B60000D61380C5A25B47F667EDC0F5E50D721550 -:10B61000D2455B57B475047BA4FA653E97A347D423 -:10B62000B04D407D456597D2673ED7234EAE37A9D2 -:10B630001E667A8EAF276B17A7E27AA2E94FB0ADEC -:10B640004149CCE7FA766DCEF3493750989CA06714 -:10B65000412FA591C9B0FE8E003D03FA490A0A3078 -:10B660005EE3580F598DEB98519F8EA8667AF09142 -:10B670003482FC44D7A12658EF1AD3C369D04F6354 -:10B68000F501C1AF5B3FB5F5CE55DD41400FCECBE7 -:10B6900063EBDCBC6C36DE1F00416319BCA057CDE8 -:10B6A000EBDE2F26EE406599C0ED2D33FE050BB382 -:10B6B000031F9BF936E271ED82C7F149EA37607FDB -:10B6C00069364683555907F0FD1ABF653AD8DDEB58 -:10B6D000A58E95C329FCEBA7CF5382F4FB1A2FF359 -:10B6E000BB564F9CF73CAC6B568BC2E0AA2E457BF9 -:10B6F0003581C3B501FA463F5141BFE8BE3B37AE85 -:10B700001C4AFB49A37E8CA042A590CD4ABF3B8139 -:10B71000A6A0BFFD1106BF974C2631E0FF57C1C15F -:10B72000FC507F47FB08A4A7C503F026787B6CE09C -:10B7300027AAD40F53558057B58F42782D9E656A3E -:10B74000B4FDEFB9BF70172CFC60DFCF79773AC832 -:10B75000D7BA3B995F6686FFBE49A1760B8E43D070 -:10B76000AD73C5C1EB5CD060A07FBC2184CB95C517 -:10B77000E03A2E307A3DD631F97AF4930AE97BDA51 -:10B78000D1E31D43ED20DF667BEF99840F73D0DE9C -:10B7900031AD33972A0F36E9FB51D6F00CE4B76D83 -:10B7A00016D45384303D27108BFAED305844185C82 -:10B7B000C87A547FAF90237316D0FA2B763A09E0FB -:10B7C0004BE38774DEE7EA6ACA0731E6DD2E88F1CB -:10B7D000E8CEEC0C4EF70E18AFFFA5E94FA5D90E39 -:10B7E000765B385437A80CFC8F6AE6EF8623075047 -:10B7F000FFA44FB90DFD942D4DA97316005F65F997 -:10B80000BC800E0D1EB04F62F989332CB68BFAEF57 -:10B81000F1F47043C50AF47B1B3A62CF7FA285F92D -:10B82000DB61AA27BDD9F1C7CFB7303B3AC9C2F90E -:10B830006EEAA134FD7AA6ADABDA3A3B582241510B -:10B84000B71EDECAF1675E3789546F1BC9F81CFD4D -:10B85000C786052C0EB161A205E32B1A9FD37A6926 -:10B8600080573A0FB4E7281F86C09E7B8CD4A3DC98 -:10B870000469FBCDA42FDC7712CB65CD6F029F5FEF -:10B88000EF78DCBFBE8BEBAB7539F7DBA12B3A5EF3 -:10B890001AF047C0CDF464A58BD9B1053BE5C80FBC -:10B8A000281C954D02DA59967D7684F3DC265AA63B -:10B8B0005D475C0AD63FEBB1613960ED78F47BB44B -:10B8C000DCB35324684766392CC0AF2738BF923C9D -:10B8D0005A067BD8CE8A954DFBEF82FE4A5BADC4FB -:10B8E0004EFBAFDC5D72E3F768B9A45D2650A5722C -:10B8F000F33265102D2F0A096128774FA60B15E04A -:10B9000025590981DFDEEDEE48FD119DF7E91A1B8F -:10B91000512928B5AE8ED45B293ECA42DBA741BB74 -:10B92000B2660134229DC7E64303615E5B052FF8D2 -:10B93000F7E55B120CF6E0093A951FD0EF4BE83CB7 -:10B94000412E4B48FD3458E72A37AF53545DFCE194 -:10B95000748D07C7D1CA955BE938B45DD54B8217A2 -:10B96000A65865217ED043E776DB673FE784F92D53 -:10B970005346BA605E0F2B50AF2454F48A5D05F82D -:10B980009A9469F47B59639302F1AD8095DC0D7E46 -:10B990006EF9967E46B81A4494D72549B68DA0CF45 -:10B9A00089D39776F3A8BE743E5D4375ECC868B939 -:10B9B0000CF421F2614899A5AB3F444C427E2DDF47 -:10B9C000221AED6CBEFE078F32FA07F7BA30EEA7E7 -:10B9D000D16F09F79735FA2D49E2F4947AF263C1F1 -:10B9E000F328D083C2530FF8A2CF351C3EF7443260 -:10B9F00009E22E6E1FF10831F8DAFCAC974911B05C -:10BA0000EE3F2D9F35491A88EEC362883C7956CCAB -:10BA1000993485967F6F29DC6C41FDE155418E3468 -:10BA20003FFB590B93CBBA810AE2AF7E6AFE732CBF -:10BA30003E4170DDAB9F5AFC3CD805B4FD360BCAC5 -:10BA4000216D3F2A7E7BCFB47186F69E69A55AFB95 -:10BA50009DD8DE76F1F6F5D32618C79F56A6B5DF3A -:10BA60008BF03B2F0EBFE7BA89C6F1AFABC0F60132 -:10BA70002BA3574F920DED9A1576AF4F6276540473 -:10BA8000DE4BC92337423D51E307D2E103FBDBD94B -:10BA90009C346635D1F3C5E437000E1795163D5F2B -:10BAA000248E7318F831C9976C28D39E3C27BEC3E7 -:10BAB000CB3088DB86F0288314D4179306D910DEA8 -:10BAC000FBF7D9B17CFF0406EFFD839C2867B8B66D -:10BAD000503ADEAFF8AFD1DBADB0324128E94DD1FD -:10BAE000FF11E037FA5EB5C07B8748AA513F5B097A -:10BAF000EAA38733F39F0BEAF0B37230A52F2D9F93 -:10BB000005FBA77F14AF0F0F2E4E2BD28D53375846 -:10BB100099BD319BBD9FEF84F10ABB010F01A56761 -:10BB200024D895E671AC43C719C6B16594E238DFF5 -:10BB300098C6B166949AC6B1CDDEC8DFF371FE0235 -:10BB4000F38A37CEC3432718E7935186E35845D38A -:10BB50007C32CA4CE338D87CE87B3E8E5DBCD87C16 -:10BB6000864D34CE6748058E93222A86B89575484F -:10BB700085691C278E03EF611C92CEFC1BC5DA532E -:10BB80008CF47FCD4EC09E56ACFE17A05FF2473BB3 -:10BB9000417DA2D27107805E49C6FD827FB524E354 -:10BBA0007CBE7450FA3BF5740E6A7601DA3B0B39B1 -:10BBB00088245487FE7915E7D105CDB33296C1B3F9 -:10BBC000B520AD08FCECF52E2FC44FCFB51628F3E9 -:10BBD00063D8050BEBE5139D06FEE57A6F32C9AA23 -:10BBE000063F8BDB015AF904D55F84EAAD8FA8FECE -:10BBF00082E74999EA69FAFE38D56F44D1C3BB0C94 -:10BC0000DB9D90181E4F34B275E4CB7547658CF3FD -:10BC100005C93B59741EB7F1692CAC4F60BE028751 -:10BC200023C0E9D1B3DB1ADA88F4F05D01760F693D -:10BC3000E84771C5EB0D057C517149C6E215601FDF -:10BC4000FD78E5F6DF40B57785A2C14BE87C67B7A4 -:10BC5000AC93AFA0E57372E75D5EA7AE9FD9F247E4 -:10BC6000306F1BFD0FFA99E3A765DDF877941ACBC7 -:10BC70007712295AA6749B2A0EE5F4E0E3AA21194B -:10BC8000E8755B2A83E74E788E81CF1EA4D75D1EB0 -:10BC9000D6568327F0A04C22B81E75F667C66D7F76 -:10BCA000ACE7D7D615137C77C9365F21A5E75D0FC2 -:10BCB00088884733BC9DFB127C16EA5775367C2674 -:10BCC000837F7929F8EF5E6AFC4E826C3C0DAF1AD7 -:10BCD0001FDC3E7B52BFE3BA7A73FCD7F73BAEE37F -:10BCE000973B4A6719CA7756CF31D4BF7B6991E138 -:10BCF0007B517091E1FBFC958B0DE585F50F18EA02 -:10BD000097342C337C5F145A65F85EBE659DA15C48 -:10BD1000197ED2503FD0DA64F86ED977D54D208F96 -:10BD2000B5BF1709D8675F384F3C0AF6D5174E09DB -:10BD3000FDAA2AE0352A87A76AD290BF4FD7A8F874 -:10BD40003CD79A8BFB6301079567BAD66FA83DBCB9 -:10BD50006CE544D023B43ED5E14FD7BEB52C487D29 -:10BD6000F78D10A4A67C2F362824D20FFC98E45E11 -:10BD7000BEEE1175DF3B2FF1BD812E58B97DBF8B13 -:10BD80009DB1DF770B3D23C1BE0B7E60C5FD9B7867 -:10BD9000F603FDBB82C4F01FB46717C437747AE79B -:10BDA0003591D9D5D788935F13E9B34261F25EB17B -:10BDB00063E064881754289191D531ECECDEF1C230 -:10BDC000149801D00F939745A12BA2F28BF41B6618 -:10BDD00090FB1B2CFE7DA09FBBF68B6C7F207230EE -:10BDE00003F669AE117DAFC17BD2DA1FD7C7776B7F -:10BDF0007CFD8E0F27E4FD9AE9F8FC434D613F88F6 -:10BE00001FFDA96636963FACF1E3B3B3A6149F1F9E -:10BE1000D554E3F7E3354BB17CA22688CF53352BBD -:10BE2000F179BAA61EBF77D53460F95C4D089F9AA8 -:10BE30001C68F62849E1F61FB7D7E9CA81E5F37C0B -:10BE40000E22FD7707CAB5370DE4FABCF3CB91603B -:10BE5000E79E7FDF8A41F4787832F35B7CFAF970F1 -:10BE6000BD2F0E51FAE7F6FD6E7730FAD82D643A01 -:10BE7000F867AB462804E2EA8ED7BE83F6327D2F00 -:10BE800011D49721AF7E1FB1B77F98F3804BD34970 -:10BE9000AB7FE2A97FCF9F970DF461F4751C14ABC3 -:10BEA00019DD9EF302DD74F86376D94EAECF4D787E -:10BEB00094B8DC99F179B6BF86CF8E0C88B7548AD6 -:10BEC000851689BE3BDF62C5799D6F4B60FBD89EAE -:10BED00094CB8AE7956FB17BF4FAA1329CE431EA06 -:10BEE0008B811EBDBE38DFFE9C1BE47E499AC57364 -:10BEF0003C17F8C3C7F983F19DD67F6538D3E33487 -:10BF0000F4632C9FAF17A6B37D4535F1D618FE819B -:10BF1000F65C92A6788E53BD707ACBB0441897FA2F -:10BF2000711E18A7ABC6E361E3A679F47C59B1D4BE -:10BF300081F535F8E2F5FBF7860F76FC3EB6B15891 -:10BF400013C469E2D58F4B0FE97305FC03D2267F3A -:10BF500009EB8E234B5B77242C6BFD06C262D07AF3 -:10BF60000DBC6F368C47DBA99A0F0DEDE2D35D2235 -:10BF700027347A523D791DCF0FA1CC8C74F6D31E95 -:10BF800013697FDD927325C479332515F55D0006AD -:10BF9000A2FC5469EB54FC2AA2BB03E39EE334B930 -:10BFA000576FFF2365B94FFE59C67806F90BED9D13 -:10BFB0007E97F9D705A4D00D4EC6BC96F299A0275E -:10BFC0003FB168F6407D3ECCFB2CB1E07EFE59F2DD -:10BFD000B63B576797954A3C3EB992ADCF41FA1FA1 -:10BFE000CC8FDA6986F5BAA4C1582E2637A7823CD1 -:10BFF00014AF9761C7962C82F55EB76F325BF2E0A3 -:10C00000BC4B48751DD829AB65B68F3ACF43A42BDE -:10C01000285C95BB9EC9077B3620317DAFF9CF8B5D -:10C020009219DC652921C547BF7FDC927BDBF708CD -:10C03000B40FD5815E0BBA8837563C66FE4A237C26 -:10C040009782DF0C2F21CB0D7068FD6A70885B84AE -:10C0500098791A3F93041ED761F2B15632DAAF8F46 -:10C06000733C68E50DA672A3A9BEC62732E7934CC0 -:10C07000C9FF38E89F4A5BCF34B4D308E58FEC683A -:10C080003D255A6FC3C5EA59A19E88F51AA5B1F19D -:10C09000EBD9A3FD35C5EAAF72D7B65782949FCAD4 -:10C0A0005E7EC20D41DF4FA4FA54887F556C7EC876 -:10C0B0000D783A2505DD40EF4F4262CCB8E07BBDFC -:10C0C000F8F23905F02390B529DE5F7CE446D0D73D -:10C0D0005F6E96312F26B0C51AB1523EAE6A593402 -:10C0E00013E2F7B47C8C951FFE14F60D03AD467A6F -:10C0F00096BDF0442AC489282699BD4D22687754FC -:10C100006DFAF334D0E301D2837C686E07E35F48B5 -:10C1100046B92F5212FB7ED7F215025CCE022D8F4C -:10C120007C0A79090113FF94F6AE279D0AC411DA3F -:10C1300025570AFAE5DF25DF053DA0E18384983D18 -:10C1400051BB75C3E863149EAE4DFFEC160C7E37F1 -:10C15000E3C3F3E1F9BF7A558DAF67CE717F28DA7B -:10C160002E84EDD45666FF9036F6AC90236EB03731 -:10C170002B9A642FE55052B1EDB9E79F023FED03D2 -:10C180002BFA69E5DB7EF3EE045A2EDF2EA7CC6492 -:10C19000D3710AA951BA04E8FF968E89D2A1ECD7CF -:10C1A000BF51D451ECFD4F93A3F428DFBE5F21A310 -:10C1B000FAE2AF20BC5FE974C6A04BF8D834B057A0 -:10C1C0006AB77EA580DFF5C93E810CC8ECDBBEB442 -:10C1D000E937B81E029E908E9C4EBD74EB43AFC8EB -:10C1E0008DAFE6613D0FE8C978F47A91EBE5CA5D61 -:10C1F0002E9204F1CF3F584333818E2FDDE38679B1 -:10C200009C94AA195F3FF3502AECFF95CAC1540FC2 -:10C210003ED9FBD267EF437E2B11AA53D93EA66FBE -:10C22000208F970F84F92D6CFC11CEAF98F891EF09 -:10C230004A9F110B213EFC8544A66F8F211737C8FA -:10C240006CFFE9E4462B24F9919360E7837DFDB60A -:10C250008871564216E33ED87D5A1C972CC1F217BE -:10C260007C5F6AB86CD1FC439B815F373DDC01F495 -:10C27000393DD83700E0A47808727C09B0DF2F1E62 -:10C280009D3A80D187E51B603BAAFF0BE03DD4EFD0 -:10C2900090719F50D78EEB4B36FEBD7C7C0AB70366 -:10C2A000D6B393A96CBFD23CBFA57C7EF4AF83E824 -:10C2B000F84B27DF4CDE37AD62F2ADC97B68D67430 -:10C2C000F8FEF93B4C7EA01DAC1F14AEC800FCBEAE -:10C2D000FF5601F581954462C9F52699CBB5F17BEE -:10C2E00080CA29C40528DC12E43344F984F69F8C03 -:10C2F000F847BFA4783D6DA7B3CF02301ED653A236 -:10C30000EF75EB4709D703D365A3FC93C6FE97658A -:10C310002F56C82408A665C50756F4BB2BB6C98599 -:10C3200030EF33CD07DFFD31E5EB33614D4E8DFA54 -:10C33000D32CA7A53B360BC09F66393D534A57EB1C -:10C3400058724ADFC794D3D2CEFF2BFA53C35BC0D7 -:10C350008437AA07872459E2E3CFAC075DB21A53AA -:10C360000FD2BF77487E5FBED3F84DE3336AA10D8D -:10C3700001FDDDCB8F1ABFF5F2A3C66FE6791AF186 -:10C3800066FE3E010C350A57E16E19FD928A36B6FB -:10C390007F43DB1DBA220FF1E3C3E58BD41FBA2222 -:10C3A000455F0E99CA61537D9FA95C68AAEF3795D6 -:10C3B000AB0DF52B5A0F2A2CC92862A8675DFA1419 -:10C3C000F938867DAFAD3381964F9520F0437A8F53 -:10C3D000027A4E5E4E4D33889FED15D1DFEA567BD3 -:10C3E000DCC9F4FD4376E6C7767B783989957BFA1C -:10C3F0002B75A0E7B4F73D7616E7EC2EEC7127E934 -:10C40000FCFB636DA21BF6833B432C1FB52F3CB591 -:10C4100028379D24DE7716179C2A3A339682FF56DA -:10C420002F7AC1355CB0EC7637ECBB75B70DBB69C4 -:10C43000367DBFF0B008E633E976B847035C24E800 -:10C440009306E6F3FC09FA778A047F3911F226DABB -:10C45000987DBD608DC91E76DEAB607ED97A5D5C4D -:10C460004BC7FF65BC9FD246E3F732B206F9AFCCAB -:10C47000240F7EEE0F1CD5E42187E4B0FD6DC2FCD5 -:10C4800058AE77A78AD937CDA678EF6E17316FF6F9 -:10C490007C9B48EA609ECD02EE7392607F94AB2A4B -:10C4A000D283FA4EC34B17C88D125F1F75EDFCD7B0 -:10C4B000FC07813F5EF9E3E8A7E9B3EB950F46EE91 -:10C4C00081F2AEF732FE48FAD62FD8F735EE237652 -:10C4D000EFB3629CAB7BDF6F331E84F2AB568C7381 -:10C4E000752FB7E23E4A709F2B3402BE0F66FE40A6 -:10C4F000EDDEAF46B33CC91548A7BFC8CC1F39DF36 -:10C50000F6EF1F42FEC8F9363A2BB00BF625A0DC39 -:10C51000045EB5A3FFDDBDF7AB7CBFF3EF379F2A09 -:10C5200085F891FF5C64F60EE0D724160F0EEC1927 -:10C53000FF1CE43757B6EC5720CE5EF0DA5F478336 -:10C540009EECDEC1EC9D7372E7B3B01F66553E5D95 -:10C550002E533C9F03E11944C873CA988260762C1D -:10C56000BC303C74533CC0BC285E4A41BFC7C34783 -:10C5700086F28F8A8F4FEF627AECBB98671FC58B6C -:10C58000E063EF5D219B80F367EFF77D351AF4CC14 -:10C5900099F032B4472E35EF6B15B6CFF23F67DE18 -:10C5A00042E472E63DF71F96DE8CFF3F82F5B57FD1 -:10C5B0005F39E8CBE7BBEEC7F24B2E2FC27B99F277 -:10C5C000FFD3FF6974DF41E9EEBE34DD9FFE879D36 -:10C5D000F7A5E87E98D3DDE581FDE5EEBD7FC5B822 -:10C5E000A936FF4BCDFBD5FF47E7ADD9EB332CD5B3 -:10C5F0004766D1FA4748647D2185F3F5F4A9EFCC6D -:10C60000A25F7F1BC71E39ADB0F8C76F09CB130CF3 -:10C61000A6092CCF83FB450584ADEB05592568673A -:10C6200014643D82F60191AA8FE4507CCCC858E88E -:10C6300065F96063F01CCA7503AFF5623CD0E41F76 -:10C64000165C7D7D3BF829079751F8E83807078B82 -:10C650001E6A299129E972C43A1A9FC7E079C83D38 -:10C660001DEB4D711AFDA399E0DFE8FCBDEB55E32E -:10C67000F769BCFFE9E4400AE4934CF7CA2404F5E7 -:10C6800048FD0AFD3EF234533F87C0AFD5C5CBFE0F -:10C69000A3F84BB7323FF2B764C9911CC05FBA8CA4 -:10C6A000F1C04BE28FB0FCAFEB06E6E079142279E3 -:10C6B000117F330655727C32BF59E2ED25675D0765 -:10C6C000C8AD44A8DFCBEC32F49735BFF7527826DB -:10C6D000DC9F96F8D01ADEA57419F35675FD225E1C -:10C6E000347AFC47E9A0D1EF3F4B8F73267AA47FC1 -:10C6F000EE91403E0BB8FD3FE5F30E11CBE95E092C -:10C70000F7A3B8FD3FC9992481FD7FAD745404B9E6 -:10C710002CB1B5CE8038BDCD2B205F5FD96541FFF0 -:10C72000C6962720DEB31A242C1FB578C682A17DB9 -:10C73000E3F7769D7980407CD8A7A0E14D0A597C2B -:10C74000FE2FDF7E3B513BAF81DF09B981FA5F0BE2 -:10C750001A49C441E7B75022C1C46488EF0AE423F0 -:10C76000437CD75886BFEFA746FBB954FD787AE4DF -:10C77000EFFDDC45F5D647942976C313F755282BF2 -:10C78000E8FCE3EFB6317C058E90D050D40B3EB17F -:10C7900050B76FF68895E98F5D7FDA910B71B149DB -:10C7A000DDD9894C9F0E47BF20C0FD82F3444D84E4 -:10C7B000FC83F36DC312715FB05D74F963C465B639 -:10C7C00072FFF99F209F823EBB37917A3887D14D07 -:10C7D0007A301E1BDC648BB9BF7BBF558B3771BAB7 -:10C7E000D13F513B6FA462BE4830514FB7AE999FC5 -:10C7F00048A3FBD201FE3ED2ED97FC57F10BFE3A67 -:10C80000E077ABBD735AACF3602B39FE6E3CF0356C -:10C81000C631AF6E6BB200FF5EBDC962D86F0C5AF5 -:10C82000B9DF35868C01B86E3C6077E5015DDA458D -:10C830002FE40F06DA3E55FC31F6ADCCF884FE212C -:10C840002EBECFCAE2FC7BE4F07CC0EB9EB336CCBC -:10C85000CFD9ADD497C782F34A3BD3730B49F89E27 -:10C86000D199FF78F89DD4ED8C4C063F7313E1719C -:10C870000C33FF11E4E3F35B089E0F05BF14F4C211 -:10C88000F966760E98A2642DF8D354DE7FA08FCB84 -:10C890005CD9BAFD9FC00EA86A133C903A5B25751F -:10C8A0002A106F0DB42689B0EEE6A85A5EA567D4AB -:10C8B000AD3AB9D86765F9C60727ECB903C6FDAC30 -:10C8C0004B21608FF85EEF71C3BAFD595B6E62ACAD -:10C8D000BC79EDF9EB1A32638A04FD10C4BB991FD1 -:10C8E000B29B1D86F2F744FF2090AF1BAD9DF77AF7 -:10C8F00063D0CF6F637C76D9FA2DF4FF997E7B47A6 -:10C90000D36F7EB150274759B63EFA6D402CFDB625 -:10C9100044500700DE97EC1D3600E8BAE4B0DC3F77 -:10C92000967EDB56C3F6F35EE6F9B0DD2D54BF5DAF -:10C93000A3D36F2D36CC8B33B74BB659F8BA7809E1 -:10C94000FD16FAEF91BF6DA0DF62CC77848DE90D03 -:10C950004DBF8D6E3B86FA6D748BC590379A6EBB5A -:10C96000947E13FADF0AF670BBEC4D88C13FDBB84A -:10C97000FDFD32CFC3837140CFDD6163FB9B97AB7D -:10C98000E7B2ED8CDE97D473FF4D78D6F4DC929D40 -:10C99000DA3947331F323DB76437D57302F023D3FA -:10C9A000734BF6B27B1CCCFA2DAB8F7E2358BF2A7B -:10C9B000C2DA075A3337CCA5FD8DF1C95E1BAD3FF6 -:10C9C00026AAEFC6EAF5DD1D3676EF421F7DD77E3B -:10C9D00079FA6E27D777548F0D05FD6AE60F6F9BA6 -:10C9E00031EF78CFF893CDBF06797943C47DC3A3E7 -:10C9F000FC5CDA9BE34FE6017F35DB98FEADE5FC9E -:10CA000077AE2688FD17BCCEE657E964F9C8552DE8 -:10CA1000CC3EAC6A16422AFDE7B4095F2B00FFA2A8 -:10CA2000BD021940CBB3ACAC3E7941DBF722337386 -:10CA300074FCB0605C39C6ED1748C40671F972E742 -:10CA4000B44F201E5F3E8EC5F1CBF9FB45873BEB13 -:10CA5000209EBDE84901F73D09CF07D0F21B4BDA14 -:10CA60009661BCD69C17A0E9F34521E3FB72533EC7 -:10CA700063139FE72CB113F142DE1263E62534996C -:10CA8000F1D1CEF1B149C475B3171F143F6A665F87 -:10CA90007C508ACECC498DCE7FD11B745E79D17902 -:10CAA00069F830CF4F8B3B97F376F1E6ABE1AFCF30 -:10CAB0007C357C9AE6FD1CE80D5008392417F2629B -:10CAC000281FA0DE08FE4EC4F3FB8593460CD0EB76 -:10CAD000E1AD5C9FE7D64F2A1848005FA41AF8A67C -:10CAE000B861F1A18174DE63DF57C7C0F2F8BD09F8 -:10CAF000563FEC8F6EB5F7A05ED3F8EA1BCE57EF2A -:10CB0000723CEE19548DE75403AD8207EC8A40C4A1 -:10CB10008EF80B50FCC1F995003FBF18A0FC05F240 -:10CB200074F0C92F19BEF60A2AC4C7A769EB0FE033 -:10CB30009FD6CF6D63F80F8404C47F1EE9C1FD91B9 -:10CB4000AA06C11BA1F5AB5A1763DE83A66FE99F46 -:10CB5000534F0F1D3F4AB1F8112BE9D6BF725EEF5C -:10CB6000466BFDBBC09F37BE2093261D7F66D1FF5D -:10CB7000BE8D41270D9F97E2CB0B1C4FDB008F4EE4 -:10CB8000C0570FB39F225FE3391AED7B400A1AF0BA -:10CB900058F0D4858BE269AC8627E053D0536D45BD -:10CBA00022948B5B05D22FB3EF3C617F522FB78B62 -:10CBB000F61E63FD3F23E0BD2566BED5E6DD876F2B -:10CBC000E3F02B9C4B03BFE872F9F61B13DFBE6941 -:10CBD000EF39920B7CBB5760F183B624C3FEE22091 -:10CBE0003B5BFFB7DA297FC3BED661D9BB51ED2BC2 -:10CBF000DF097CFD02BB5F7F2EE92A9808E43D6EC9 -:10CC0000B1611E19C23194D9957ABDBACD4EFADF01 -:10CC10009A17BFFF81BCFF78768D561E05E341BE93 -:10CC2000572B1D2F2B3A9E59AF6B7EFEA5E635F292 -:10CC3000BF38AFDE3C4CD281FB4E9992FF31AB2E18 -:10CC40000FEE369E67442140FB4A572FDB76917AE0 -:10CC500024CD83E79FEEF1687CC6F2DD0B791EFBE5 -:10CC60005471E27BB07E7EE663FB7C7916F2FB8931 -:10CC7000A09F27CB788EEFB32332C66B3F9BC2F2C7 -:10CC8000386F7AE3A004F1999B4039517CDC34562B -:10CC9000407F058E61C1BED92E6ADFF846E27C7204 -:10CCA000E11C57CEA6FA02387F3C664BA8169EDEE2 -:10CCB000829E9437018F93440278ECF0F52B80FB31 -:10CCC00093EEF933C1FB43E83A8BEDC7B493FE50C2 -:10CCD0006F82AF3FBA03E35BD617407C74D641A79F -:10CCE00013EE67C96AB4509F218ABF0924540B719F -:10CCF0009BF1C77DB700BCA5D45E80B873695B5358 -:10CD0000AD1BCA8D8257A5FD0782FE696E3A8F6DF5 -:10CD10000D9F4EFB0EC823AD07DD041A59BDC0267A -:10CD2000B87808DEAFC33C9BE24D021EFCDA161257 -:10CD3000888DF51BB2D17EB735D2F679B04ED0F6DC -:10CD4000D0EFA64FDFB905E4FD88C8DA37B37DEA36 -:10CD500062DA4E05BEDDB418FB5BD4289034DA5F8E -:10CD600069335B074A8FC85EF8DEB2FF495CC7666D -:10CD7000D2F1066682DE8F4C8132C9153C18EFACC9 -:10CD8000188974EBE6724E268E60FA43E065EE3742 -:10CD90006876D3BB7696EF5BEC5DA6F4A3FDBC3959 -:10CDA000AE7F26A405045A3FC5FDE7E314CF7EDA23 -:10CDB000E5519EB77170DCC74AA76E1DFACCCEEE66 -:10CDC000B75AD03A09F319169242CC67B8713CB3FE -:10CDD000D7DEBAD61E822B0EDE927BD2E1FDC16B6E -:10CDE000AD68FF9EDB26231F9D1BDC89F1E9938D37 -:10CDF000329E1BAE6D64F7739D6C66EBB8F80CDB6E -:10CE0000D72F7129583ED878CB3458DF4E6E62E761 -:10CE10001D0B9E99AA40B9A449F0B2FB8B987ED411 -:10CE2000FCB7620FCB47D0F45F259F779FBC45933B -:10CE3000BEABD4D61B93BEAB847D65373C8DEF0370 -:10CE4000C4C9F420D8FD40F7C8D7C8BF554764020D -:10CE500076BFF071D734CCC7DA2B603C7F7C9BE087 -:10CE6000837DFDD2F7AD21B457434577FF04F4F835 -:10CE7000075622A890D74EF14EF5C3386BCF9F7E50 -:10CE800041DF7F72D4069930944F8A10CF5AFE67E3 -:10CE9000DE6696C79277747D2A9CB72453FAA1BEAA -:10CEA0002D6910895FA7373E117CB7FC98E965BCF6 -:10CEB0009F42A35F9E525F0CEBD83007D34BEA66CC -:10CEC000197244C8611E27A1F6349EBF5DB47B5D14 -:10CED000AA42EBD5F1FC8F457BD7A58AF47D2DAC1A -:10CEE0005FB4FE2285F5BF689FE069D2F5AFB5D784 -:10CEF000FAD3FA51761BFB19B697972FB31F0D0E75 -:10CF00006DFC78F6F8B87FB9B01EEE8B19F79688ED -:10CF100049C7E33E9E394CBFDFA13DB5F86BFE3BF0 -:10CF200016E2D3E16DDC9F1CC4A7E38B96B154BE1F -:10CF300029DD6E681542004ACBD8634A651E963DCE -:10CF400020CF553C4E5B3585ED5BB5E41C5D01F2B1 -:10CF50003D334F403E2041BFD22F05ED2015F6173F -:10CF60004AF258FB12DA1EE4AEE5492687541FA8A0 -:10CF7000A02FAA1AD74DC3FA9B0415FA6F692AC2CB -:10CF8000F5BE749C48F0FBA663687F94B61E4B0107 -:10CF900079A5F2B91ED6DFAA8956BCCF4B933B4D7B -:10CFA0008EDF92F97D4D36CF28C8EB7F10808A2125 -:10CFB000BFE211C2FCD46619E52C308EC9E55BDBFB -:10CFC0004494E783D7DE8E72786EB310478E0B14CD -:10CFD00038977C32C4BEF7CAF15681CB31D30F27C4 -:10CFE0009D4CAE0BE03BC8F14E81FB83CC1E34CB95 -:10CFF000B126979792DFF22D26798E23B71D52E73F -:10D00000AD30EE3DD7DA11EE82EFEF7EF71ED43F62 -:10D0100032E67D147CFF8154D077C512CB57D2F015 -:10D020005829B17CB63E70AC5FA60CBC2C788C70D5 -:10D030003C6D7745F587087CCEEEE10A6E9291CF84 -:10D04000CD72F85F959FBF973C1FE6FCA3C123EE0E -:10D0500065ED217F2C42F1F4DBE6E7304FF5EC8BF8 -:10D06000C76E043C97EFA17C4BE77BAED9C5EF7B45 -:10D0700009E13A53D622621E389122F9B7B8F47208 -:10D08000C9F290CA5F76217F94ED60F9A465AF7C08 -:10D090003C1AF34496F7607E55F0456E6F063B47A9 -:10D0A000035F97492C1FCA2CE7B73A98FDD9B53BC7 -:10D0B0006136CC43D8C2CEE997856F97810FB57A98 -:10D0C0003F74C85A3DDCBF0C52BE85FD75804F7F52 -:10D0D000EE5CCB83EADACAE4BEAC55467FA96C4B62 -:10D0E00013C6B1035B3EC53CF78297B761FC20D005 -:10D0F0002A1AF31EB788B87F459FB84F65CE3FAC5C -:10D100006AA9C4FDB6AA30CFEF33E5BF95BFBCF71F -:10D110009520454DF9AF5F70831E38DDB1D90DF80C -:10D12000A4FD61DEE0F73F970C7951F1F37B7DC6FA -:10D130007CC2F0AA98F984A7E11F94C11F70707E89 -:10D14000D5F230B7F4E379DA91FCC218F1FBDE7363 -:10D150003BDBBE7816F2DCBB769C7916E0AEF8DBE2 -:10D1600067CF423E13D967C77529F0E2EF314F58B8 -:10D170006BF70B07F7F3B7BE80F9D5E73EB0A29F78 -:10D18000736EEFC90CC85F3BB7FDEB5488C7DDBBBE -:10D19000772AC62BEFDD593080C4D0EFDA13F8328E -:10D1A0007419F9DD663A1C6C3988795767DFB7A2C4 -:10D1B0003EEBCD0B0D57B23C5B95E78336C7CEA354 -:10D1C000D7F218AB5A6EB9E95AD0CF2DCC9EEBCD21 -:10D1D0006BBC541EE83B949ED75C06DD9A799EAFEB -:10D1E000896E67E11F943E6113DDBE6859F8ABA7F5 -:10D1F000E05B4BBFB879A091CBC09796A7FF738730 -:10D200006F8F03CEFDED4808A6317A85660A60EF80 -:10D210007D9101E71A4EC93D98EFD1B3D7EA817CE1 -:10D22000C6B2BDEFA17C9CDB7914E3AA84E7C99F59 -:10D2300023BD7F2CAF59E0F3DBE462F9A31CEF9030 -:10D240005FAABAF13DCF23657CABE597C6CB2BED4A -:10D25000710C6571687E6EA092FA49FCDEACDE7CD2 -:10D2600053611CD0E998214F579BB7B93F0FD79B0B -:10D27000D1FCE8D879BB5ABE60944E6C1DD1F29FA8 -:10D28000CF35F1BC69FA3E7D0CE4C1B1F53A10121C -:10D29000DE2331E451CB8F3EE330E545872E2F2F3F -:10D2A000FA52F0FE67F1F1A183C5AB35BC74FD25E0 -:10D2B000B63E561298DD49FD533901F705987F7A3D -:10D2C00037F74F357C69F0D68599DDD0B585F907FC -:10D2D0006679AE8A735F520A1FA7AA75FF68D03BB2 -:10D2E0005D0776737E63FC5CD57C8CE5DD52FD1CAE -:10D2F000D2EB677EBF84B9BF0CDE5FA02D767F8145 -:10D30000E64F63F6775AF2DD0EF09FEE6076D2E9D3 -:10D31000B0383DD6FD36B604D9903F50E762F76588 -:10D32000886E07DA47F7BAC6BD9F98024F05F37AB1 -:10D330006A97F13CA09F79F15ED15AD70C02F03C7C -:10D3400004F8D1C519648F9F809D26A715E6896AC8 -:10D3500014DE5E7AA45848484F7F29920EFAFCC327 -:10D360009C9332F4F76FA6F8C8BF49A46E0085EB12 -:10D37000DF828277991ADFAED6CAFE9F8A86784608 -:10D3800095B5E743B0CFC96B76DC0F17F7D9831893 -:10D390001F7B96DDAB7170E757CFE3BD3CBFB21288 -:10D3A0006E170AA00F4A789CE2E4CEAF9EFD77B0DC -:10D3B00023A1311DBFE4595A1FECE7E604B4F7BBC3 -:10D3C00077248E863840C96B0FDE08FAA204741FDA -:10D3D000D8992F0F08D5D2FE4EF467E513DB06E38C -:10D3E000B980F21D2ECC273CB8735715E8FB732F7C -:10D3F0002710D0F767E5CEBF4139B0279134A9682F -:10D40000F7A9FA7575119154BD3D570E65437E0B12 -:10D41000C1FC168CBF517E2E6F4DC4F31FBA7A5CCF -:10D420009E8383F83D518340EEA8DDA81AF39ED970 -:10D43000F705094C7F05AC3DF7B3FB1058FD80D2D2 -:10D4400053CCCAF58398DC7660FDC51ABFF2EF7D38 -:10D45000FB65F503092C1E10ED87B5AFB2B2FB35A5 -:10D46000CCF4FD6982C0CFE3FEF5CA58F74FC48003 -:10D470009FDDCB259020DCBF4AB6DB314FAB428924 -:10D480008C847CF55714B6FF51E18E8C847CF53D7D -:10D490005CFF55386899BE1FC4E180FA5026B6CEAD -:10D4A00097F05EA75D76BC0FAFF235970FFD8457FE -:10D4B000BE3AF1741EE4AB25609E74E56BFF0BE988 -:10D4C0005F698DDC05FCDFB3DD8AF793766D3F9CE9 -:10D4D000017643971CC948BEC8BE4E65D86AD8A716 -:10D4E000D6E671BA66E90438C7AB9D332C8BA32FFF -:10D4F000DE4860791D4D09BE5F313D67BC5FE67453 -:10D50000CD6CC3BD8965B6D87AAC19F4822E8E274E -:10D5100046CF153643BF674967DD204A924AA107C7 -:10D52000F7C7CBB664A683BF7BC07E25EE5B1D909C -:10D5300055F407E1A9D7C7A76ABCB9129EA7CFCAFD -:10D5400095281CDD4D9F160F22901F689F1D4B3F95 -:10D55000ED4D48407E2AB359639EDFFC1DE7B76D51 -:10D56000206F63D978DEECE8B807E49002704C7461 -:10D57000AA389F32EA07B07BA2E6E4EACF6D2F9289 -:10D58000EAB11E952FC4C722B25EC973F6D52B8BA4 -:10D5900096E6E54AB9A8B0BEE9E537314A27124C0C -:10D5A000413B49E23424EB071AF2FD25B9D006F8D5 -:10D5B0005248A1471281D4F528A70E12C6A7939A04 -:10D5C000216C1DAA26101F3FC5F767AD92FA18DE21 -:10D5D00037D32EA23EBF14DEDE4B7023DC56A99A51 -:10D5E00078D1DE98E9017B4C08FAC9B7941F6A6BC1 -:10D5F000A6E7B273E1C407796E6EC2E0737B0E7D5D -:10D600000DF601E533768FD5F749A8968E07C78CBE -:10D6100031FE3799DD676F1EEF2F9C0E24B8DF7047 -:10D62000DF39FCF568F7E781BF9EF8B771B01FE3FB -:10D63000F49008D84B094E1249180DF7E449A7F5A4 -:10D64000F2EB26AC3C94B233E835CF44E377335F5A -:10D6500013AFF479AF5E14B1FDE7A6F69F5FACBDE2 -:10D66000868F806DA3F7786E142F0E3E87E064EFEF -:10D67000854EC0C768B7B716E8A8F47CF820E06309 -:10D68000B493F983290D44EFAFE53A99BE5AC1EF3F -:10D690009FA67F854E5D7FC463C3F8E82A8EF7DEC0 -:10D6A000FA5ADCA44F7DBB0478ED53DF1EAFBE23D6 -:10D6B000767D573C781262C39314A7FF60ECFA554D -:10D6C000AFBDF7664485974C6F40709E9F5BCE75EB -:10D6D000827F95F8616A11E30AB61F60A29B03F886 -:10D6E0008FF28363B8EE3DFC5FB68E7E4363D09FBE -:10D6F0004490EF8A383CB4EC1C48E1FB310777CA10 -:10D7000026B65F39F75E1627FAB18DE5971EE3F767 -:10D7100001CD6D607EF5DCA56C1F9194B2733E1E49 -:10D72000FA1F8C77277442E97D67BD108A64C2BDF9 -:10D730003526FBB5F77E9C450AD42F32C55D347E75 -:10D74000D2CE23CDE7F67526E7CF85A4C705726F45 -:10D750003EF7FE3AD76B9ADE0FAE2359706E5FB478 -:10D7600038BCB03F2AF273A6C4CDEEF323BEC1ECA1 -:10D770007E392D8F2B4B4D84F58D84F97BBECFB236 -:10D78000E47A7580FE9C9674C181F783D4CADE3436 -:10D79000D083F2056AD751574DB93094A8BA736453 -:10D7A000D49E43E1963DECBE44C953484AC00EE4C2 -:10D7B000F703909419BD76D75B140F4BD6A9786EFA -:10D7C00075A193D999BF7015DEE31C0BF6E5382FD0 -:10D7D000BBE7D648C7E04E36BF5A985F665FB86B66 -:10D7E00015AF17EDCE19D462C0388E177FDF41B464 -:10D7F000AAEFA9208FFF2CB3DF2BE8830746BFF3E6 -:10D8000029C9782FFB02F7EA0F814FD7F0FB0857A1 -:10D81000D664E173754D1ADA9D75355E7C6A78B110 -:10D8200079EBF1DE37DB70D69FCDE3677605B56522 -:10D83000209F42F25447A06C4BAF2660EFDA7BF199 -:10D84000538FF8517ACB7E2C5B3DEC7723E486999D -:10D850008867DA9E94D0EF4B5CFEA7404EECEAD589 -:10D86000867BE4AC69634CF70D9AF0A6F1C7368667 -:10D87000BFB502E30F33FED6CA1D2AEC2BAFBDBEE7 -:10D88000F7DE19C41F35EF19FE7EC7F6D9E2E2CFE5 -:10D89000938CF6EB82FCBABB204FFA11BEBFF87036 -:10D8A000CD38C4D72A7E8FE443353E7C8A803F3A08 -:10D8B0003F6B7690C0FDE8ECB721E8D359E883FBD5 -:10D8C000678177017FA293E1D39A568DFB6B362750 -:10D8D000C397E80C225E6427C397E864FCA6F0B205 -:10D8E00004F8CBC5F6F89EE2EF00F0972D7D82019B -:10D8F0005F4ACAE4CBC3DF93147F148E142E5F6695 -:10D900003CA428EC7E4A4DAEE2D9714FD0F9C3BA9F -:10D91000BDA186E0B37F1C7F71A88BAD9B2996EAE1 -:10D92000FD32E02399F0F52448D2F3094B3D84BF42 -:10D93000B42051A12C303848FD60C3BD92A24732BB -:10D94000DDCBA66E003E587F58B640BEBCB874868C -:10D95000E13CA838DB97A4223EFD784FF323352A1B -:10D96000D26F1DD011EE01E5FED7439C9E0FF37BD5 -:10D97000285771F958CBE5E5312E27B5FCDEE435A3 -:10D98000D3599E554A8E85DF571621FA3CA6246F3F -:10D990009828142EB4A9557CE23D8BE47D6B680475 -:10D9A0006D97904D7CC02749EF3F1062F735160EFA -:10D9B000043B2849BB7F71A29A34070FC24624E674 -:10D9C000775055887E4C8725D63D55B5DE03368881 -:10D9D00087C68327C1EBCB7C888E97D0E042FBBD06 -:10D9E0009FBF70CE425A76362460FC2F81FF3E8B5B -:10D9F00093C25DA2A377BC7BA837BAAE4F74517AAD -:10DA00007A0046FA7CBC6118FE2ECB137221FE8E82 -:10DA1000CB137C3DD5EE39D7DA7DC3F5A33BEF6A56 -:10DA200083DFBA5EF6613BCF44A3FCAFE7FA3679F9 -:10DA30008A91CF357D7BBC57DFFA87023CA917A6B8 -:10DA4000A01E4BB939B6DEAD9515BCB7BC761493A4 -:10DA5000F36091C2CEB5F4D50318A73EEF1FB911FC -:10DA6000F4A8C657CB09D33B41E2F0E23AC4EFB782 -:10DA7000D1ECE095700F20D7AFF01487B3DF1F48CB -:10DA80009DCBEEF35DC3EFB17A94F215C17B4FBD30 -:10DA9000F89CE162FB13CB6D63F03EB55AA705F528 -:10DAA00084F48135042687B47FBC07E20592ECED4F -:10DAB000F041BCCF2585E1DEDC5A671EDEFB2E245B -:10DAC000E57980FE5FBA160CB9583E1D9D28DE9799 -:10DAD000E94929241F65E36E009E5F913D37138855 -:10DAE0001B6E48A9B603DEC6BB585CBFA1281FF158 -:10DAF00048F17B93AB7FB49F01B367F4DE8305DD10 -:10DB00006E88730EE60E17B397487A900CD7C979D2 -:10DB100083F63B276A9064E9E47DF9886904F68717 -:10DB2000FACA791C3DB699E9B115426C3DA6D9995E -:10DB30009A1E934DFA417BD60D996E38A7A5A4780D -:10DB40008177E119B478C1BE7BA5EE8E24C443353C -:10DB5000E081A4CDE8F55F7F3014ECC7FC98FC664B -:10DB6000D65F0B7AD7735F2AD0E994AC0E9803FC8A -:10DB70007438F67A3EE9F1AB1E033E58F03B51D0C3 -:10DB8000EFA7945C5889EB69F18571F82C6D988E3C -:10DB90007C4F200AAEF3C34E36DEE706B84E36F0B1 -:10DBA0003C80463904F919271BEEC3FB4A20CF5BA2 -:10DBB000D4EDEF933C15ED4BED9EB193A17BDCFAD8 -:10DBC000FDDDE25FD87D60B7C6E3AFE2C6D87E3D3B -:10DBD0009E35828D3CE2CD027B98DA373D11B07FD5 -:10DBE000365ABD41122D071FB7C7CC4F5CE29AFAD7 -:10DBF00004E07D89CBF70CC83971B27B41E3F3397E -:10DC00001BF7046C02C37ED3533C4F53F2BBF5F7B2 -:10DC1000BBF5DEC7C9E324C416E7BB43FB7D8338ED -:10DC2000DFDD2C9F8378627FD7FC8484A89FD00A95 -:10DC3000F3A86C3853F701E289FB091CEE533283D9 -:10DC4000FBD4F356F63B3726BE38C5F34716090C0E -:10DC5000AF1A7F9FEAB577FC780F8D99FF848D57B7 -:10DC60006D184FFBFDAC5DC6385C05E51FE01B6120 -:10DC7000E378CC5F171E1FFF18E4257D7E44C4EFB8 -:10DC800065176CF8BDEB67DE0D7321CEF3868CF75C -:10DC9000757FDE3E3591C5798C71E8856EB6CE9F75 -:10DCA000E6725F7C6135F2672F7FD42F5440AE8AD5 -:10DCB0002F3C8AF64CF11601EF8924C19E43932430 -:10DCC000CE8713A0FDD969CB01DF13EB717FA3646D -:10DCD000B3D5BB5AE84BE7D32ED570AF7A49E71AD4 -:10DCE000EC97507B2A45B7DF7D8AE701975C60F7A8 -:10DCF00003124F90A401DF73BD13E55FE3BDAF5D79 -:10DD0000F6D871F66FB83D537C6182C16F88CEEF53 -:10DD1000FB4C3EF97A5ED2398EC1D53B9F0DE36351 -:10DD2000CD273A8F89D8BE2B29F6F8991CCF276AC0 -:10DD30004AE1E406295558BDE2FAFB14D027C58D07 -:10DD400049C9826E5E250DE5863C8C92C622659E91 -:10DD5000AEDF281D1CBF9D343C4A87CC47E5EB96BF -:10DD60003B61BD2F74B961BC8D8BF27FA2427F4CA9 -:10DD7000FF7C22D76754A37EB9C71DEB5C43A65B2B -:10DD800035C4954A1A387DA89D9CA7A38F46177362 -:10DD9000FB134D25F93F8178F293EC5690F87AC742 -:10DDA00044B7CCD8789BD08BB72CCC07BA34DEBE26 -:10DDB00063C8FBE983374E5F0D2FDA7B6A1FE502EC -:10DDC000BE2640C0A93FF4C3E87F297C45C7E5F4DF -:10DDD0009F147B1EFEDE792C25416A3F2CB8E43C63 -:10DDE0001E2441DB45E6A1D19F5C6DA0BFFFD11190 -:10DDF000D7811C6AF45E70E049E4DF05541E615F60 -:10DE0000FE64FD7D86F5210A5F1CBA0F0F92ECFCC3 -:10DE1000FF7374FF440E6640DE57701D5B474E6D06 -:10DE20007C24438FE725AE490B812E6453FFCB5AE8 -:10DE30003F8293BDED2AAE4B32C6C376BBFC0137A1 -:10DE40007D5FCAFDEA1549D346C65AF7A95F381166 -:10DE5000E2CFB535D32742BC4DE67623FCB216D8C7 -:10DE60009B70057AACFBB5EA395D1FAAA9C6F835E7 -:10DE7000B10589477FDE9730BBE81BC2E22D5A3BD4 -:10DE800045F67B20FEA908A410ED39C9BF32330F37 -:10DE9000E2182939411DFE1E7533BB6E4DDA010FA4 -:10DEA000E4935A69FF108FB1A54BE78DFB94AC9CAE -:10DEB000238C97613E724A98603C339BBED7E15BEE -:10DEC00049A1705EC4DF946C6EDC2F9208B3D3B4AA -:10DED000F9D337B89E3DCCD7A5E510C74D013BCC53 -:10DEE00082FED07A1EA7FC654D21C78384EB98354E -:10DEF00089D5571219DC76885B8BB0AE46B0EC82C0 -:10DF00001B7644BC9A0C7F7F3489A8F83B7DFD4882 -:10DF1000A40EEF3199D4793FBCF725F8B7001F7CE8 -:10DF200039B0E34301E2D085FE2B61FD6D108339EA -:10DF30002AADFF2BB12707EAC1EF7BBD9FCC9E43E3 -:10DF4000206FD9AFDB9762F772AAFAB89EB93C642A -:10DF5000A964DAAFF9CB95FAEF4D09BE5D0047CA67 -:10DF6000C702EEC3D4DAD9BD3EB5AEDB1261FD3EC9 -:10DF7000CAE985F407FE696776CC79494D4CC6F845 -:10DF80006656EEEB86F1BD86B2C4FDB74D941F25F3 -:10DF9000DDBDACC3259F05F865443D7DAFA75F8C13 -:10DFA000B85AB213AFBF8DB90FA3C147C725803F81 -:10DFB000F1C234B6BE9AF8608FC0E00FBAB8BF4560 -:10DFC0008222D0738E765FB0B48295B5DF8B002A43 -:10DFD00052383ED0F617C80A56E6FB9481796C1F7A -:10DFE000D20CCF9CB6873B20AE3FA76DE07CD89F7C -:10DFF0009AE31CF96778EE917B0E24801D789F8050 -:10E00000E73F7EFCFBD7E504FADCF9CE463C6F7CAB -:10E0100096CBDD5DA407EF61F7130FDF270FE1FB60 -:10E0200079F00373580ECBE0A7CF8D847E74032D57 -:10E03000DDF97AE80630DBEE6AEFF90DA8017FD84A -:10E04000330DF700B476ADDE43ACCCDA45F160E3D6 -:10E05000F6A80DE7159DB70DF1F0416FDE7810E9D8 -:10E06000D18B277EAF928697DE7927DE3603E2BC1E -:10E07000F1F4D91C67D69FD9E60783CB8CA7CFE1F3 -:10E0800013B5233F77FBEC8954BF7DECF639E0599B -:10E0900061EBC99086A2BCB8A15C25FA87A4523C6A -:10E0A0009C1DECBFB23FE0A3A3DF65E9D10FED4CAF -:10E0B0000F90BC0C9C8F76EFFBC1074EBAC0EEAC44 -:10E0C000DBF95E063C2BC5CEB5B7637C53447FE8D5 -:10E0D0007CCB95173D1FF621C49DE8FA372251E30A -:10E0E0004336BFBBF9F99ABB5B12F07CCDDD4B45E3 -:10E0F000C3BDCD772F65797744EA187DABC15E5FEC -:10E1000011B71F880398FB99BF7432F9B81FECB39D -:10E110007A26615CE059C65FF3A7F844C8479EB011 -:10E1200052C078CBF8E36A6B272DCF0F25E1EF1DA6 -:10E13000CD7F60492EDC4350D5C1E27B03C4C53995 -:10E140003F83F8C901B68E437931C8B7D3A73A7572 -:10E15000F1FE2EB93A07EEDD0BDEE9F401FF14DD26 -:10E16000EAFB007F2F91C721B47575574311E6B1C3 -:10E1700016CD55C701DD8BC276FCFDC1221B911C5B -:10E18000548F1549C406CF010A91ECF074101B3C62 -:10E19000F397B37BB28B1B66A17DE01E57A8C0FD31 -:10E1A000B7456D2F7C01ED4BA4C87E76AE85E1A707 -:10E1B000A8EDF0D7C03F0B7D859877F89D2D8AC1DB -:10E1C000FF1B153696AF6935967322C6726EBBB1CA -:10E1D000BC15EE38D3D91107F65A719D283FC3CE2E -:10E1E000E9BD2AC0DA04F1602BCA5341795B3EECE9 -:10E1F000479F79C96581EF7BFECAFCDE9EAD76BC88 -:10E20000EF6DFF1F1CC40179852FDB37C2F7338EFA -:10E21000703EC4E1687DF63B5B85E191E0BFBD7275 -:10E22000B5E6A78746C3BC5EF91BCB93E9D96AC59F -:10E23000DF4F39B3FB8597605FECCCD62BD0CE7A1D -:10E2400055085AA0DFE02A467F339F966F31FAC502 -:10E25000F727327DD32D307C5FD9609CF755216341 -:10E26000F9E789CC9F9A4774EF3361FF5EAD4B832A -:10E2700075F5B9D8F70D3FC4E5E2C517158D6F45A3 -:10E280007E3F1B5175E797F644F7EFEEBD02F22A89 -:10E29000001743A3EFCB4DE36AFD1726B27DF814B8 -:10E2A000BE3FD3F38688F8396DFADDC25EBBAEA6F9 -:10E2B0007AE014DD3A54DCB03FB508FCA3C6FDA9F2 -:10E2C000F374EB4BC5D683A977605E9284BFCB54C1 -:10E2D00031E7F94727A4C07B310CF0C277887B7502 -:10E2E000857FE3867AD4DE1D23EAF05ED270DFC03C -:10E2F000293A39FD8FF2A5264F15DC3ED935AE639C -:10E300001AE4899737B0DF6F2A0FFFE816F8FD454A -:10E31000D2C8CE99E64BA450A4F253B1FD473F8436 -:10E32000DFE30A3C33D60BF0D02E6E85F7E5CD9FA8 -:10E33000E27982D5A6DF11D09EFB387D69FD888504 -:10E34000D65F7D9BB314F413EDF775281FC8DA88E8 -:10E35000F79BB84FB1382D7DFF3EFC24CAA9C9C137 -:10E3600037EFA04DCF90F0BB3764C2BC8D7C46F92F -:10E370005600BBAB67B380BF6B4B2DADFC9BC1A4FC -:10E38000F62DC3BC5BFAFDEE58E79D17858CFD9812 -:10E39000E9FF07CEBFF42F4BCF47E67AFD6606F1C3 -:10E3A0005C62C552AAEF74767EC5F17ABCCFD13CCF -:10E3B0000E06E174F906B05EAA28DF76EDFE21C1F3 -:10E3C00096CFF36687B132DE5B08FC4A19A5FC6A7A -:10E3D0003245057CDF4CA6C3F35521F2A828323D17 -:10E3E0008171A06D09A827BA3C9DCF3F0DFCD53C9B -:10E3F0000AE34F83F879CF2E3582F73C76F3F86441 -:10E40000978795CBDAEC980773E6AC827A7459F863 -:10E41000A01BE8D1F592DD02BF4B7A667BBFC990A5 -:10E4200027D91566F7FF9E0EF7C3DF7F8DB76E996C -:10E43000F581B64E1E837FC27A9AE8FB06D65BB2A0 -:10E4400082E5910EE8579D13EBF724B476294A75BF -:10E450000EF829FF1B63EBB5D4008000000000001C -:10E460001F8B080000000000000BDD7D0B7854D5E9 -:10E47000B5F03E73CEBC92996466324926218F096D -:10E48000841020E024860814EB24040C187542D173 -:10E49000A2B638804080BC44DB46A55F26244242B9 -:10E4A00051428D08087140B1F48A6DB0A8C106EFE1 -:10E4B00080F86AB537DADE5EB5FDB92370295A1ED9 -:10E4C00023F452DBDBD67FADB5F799993349AABD6A -:10E4D000F7B6FFF7FDE9478FFBECC7597BADB5D722 -:10E4E0005A7BADB5F744BE6EF1EC2D60F0172850A5 -:10E4F0009C8C5DF2BB3C9BA0BC4482573318333AE2 -:10E500007C465B3A63D672C6BCF0CFF186BC5786B8 -:10E51000FA53B2E79BB6718CDDC57C0686CF72BF1D -:10E52000818D853E9DD0388BB1650A0B290E782EE2 -:10E53000F4BE2F4DA53263D07FD92E29D801FDEF2F -:10E54000DA6C64CCC4E8EF33F8B7A217CAC5B1F2ED -:10E550002A16343019FE63575C3B187F95123A2A0D -:10E56000A530B6DAC442C930EEEAA7B4FDD6B01081 -:10E57000C1D370E03363FCF8303FC600B4FF64EAF7 -:10E58000BCBC6EDB34C69C0628C3BC236FEB8388FF -:10E5900087FF907D34AF35CC4FE3DCDE5AC54EA506 -:10E5A00031D67C5F6BD65DF0BCD87A7FD65D5743A1 -:10E5B0003DC201DFB730DE9FC1BCF601CED654B3F9 -:10E5C000502EC0B71CE69B5406E541293405CB26E6 -:10E5D000164829E3EF53CBF87CBD71F0D5B31EFA92 -:10E5E0005EFD2EED7BF68B34C267031BA27AF654D8 -:10E5F0005C3DE0A341E0A1E100BC8FC3C3CC03526A -:10E60000C07A1596821D19005FD359C63641A9E913 -:10E61000D06746CDF8AC8731C04366126366A0D799 -:10E62000A3125BD45F42FD26D64D8136F8771D9646 -:10E63000DBA9DD0981BF476F5991E587765BEC5017 -:10E64000CE16089E0EDFD0E1C7A91C32C17792AE6C -:10E650008E96A9BE623D2FD7D98A6BB6E730B64DEC -:10E66000EFCFB2011297C9BED77480BF271DFE5BE2 -:10E6700090DF96E9BC790ACE97798B7C00076BE531 -:10E680007878ACAC65624B490CAE187C9CBEDBA4C0 -:10E69000FE900EF82C7058F2EC7323DF46F47E4B9C -:10E6A000AC5DB34DA279A41E0BBF3606E9FEBCC417 -:10E6B000F642BB1DD287AF8D817E3BE6B9590794E8 -:10E6C0005D4027B90CDFB34E09F0527EA8EEEE573D -:10E6D00091CEE5499EF1F0683C5429375A68FE779F -:10E6E000FA009ECCE4963D3AA8CFBCB3B80CF91B17 -:10E6F000E67DE702787FAFCD4DDFCBB270BABBD6F7 -:10E70000070AD696E0F77D77BF0ADF8B4C49F2E027 -:10E71000F733015756073DBBCCD88EB54BD8EED159 -:10E72000143E7EBA4EBEB30ECB65BCEC582779F7CB -:10E7300012F36DA579671A590DC289EF8325B46468 -:10E74000BC07A93EC8E93BBBA514C7CB1CC79F4E5D -:10E75000432807C7794BA5F760968E6520BCF0DF8C -:10E7600000CFBD072B331DD0FFAD732645970A4F51 -:10E77000176343D84E0959183E0B8B797B93685F1A -:10E780003A3B131783334FDBEEA2DE9B7A35E0254D -:10E79000F08ECC901EBFB37853EDD0EE4B063E8F7B -:10E7A000443AF6217D603ECD9F02E46971745B744A -:10E7B000C580E3357FAAB0E0D5B1F7E7DA4C2C5835 -:10E7C000142B37D41F9B8BED1AD9D006E4ABC6FEB1 -:10E7D00064168CE3F72F258DFC5D95BF9B3FD5B16B -:10E7E000401AB16F8ECF8AF8896C588EF01F91D87D -:10E7F0003E86F5061688FB7EF3A70E6D390A67067E -:10E800008D136BC7B4ED067E4FEDD8F4700A7EE72A -:10E81000822D9CE210F3C37ED9326B41BA5C0CEAC4 -:10E82000027A58C717DCBCFE226335FD96587B750B -:10E83000BC0B8B0C2C44788FD0B8889700C8B69D41 -:10E84000839F18DC506E183C4A7851F9211E3F8195 -:10E8500038B991D13114D2C19AFE856D55578919B5 -:10E8600048714C5DBF6BBABCB3A05ED669D67372FB -:10E8700079747D93587954270B79D0D0553D2BBEB0 -:10E88000CCDBC7FA37D654C3FA2F2FE1FD4FD89A05 -:10E89000DE58AFC4E411CC230FF1122D9B12CA161F -:10E8A000284F892BDB12EA9D09F5AE84720E6F7F2B -:10E8B000CE1ACA933D8C7D645B5BA3807C3997152F -:10E8C0005A2C417973C7BD35D520E71ACB87BC32A6 -:10E8D000CACF41C923B118FE9A3CCC1B04FC593C59 -:10E8E00061C3B212C4C3D06BB8FE1B06249B047C68 -:10E8F0006EE93F18A232F673C7F5EB97A85F43FFA6 -:10E9000087D46FD4F18B75B48E37159FA4768000B1 -:10E91000DB69A0D35799C45201A5058AFF8FA8BF10 -:10E920001AFB7FC3F52E8B18F8FCB81CBC90E57D54 -:10E9300085E4E011C986EB2ECA7738AE25C6EF6AAA -:10E94000FB5F4D19FC571C26F9DE4FDA1568FF7F77 -:10E950001A7F338D01A97E854D66A05C0D4E447DE6 -:10E96000BC93F927A21EFA7AE3F8A33A6877421F0C -:10E97000DECD005FC5F64D350AB43B610DE74A2098 -:10E9800043266DEDE5E5F4F06EC46760EBA384DF2C -:10E9900013B9E15C1D94A7DA43BC3C3EBC1BCBB76A -:10E9A0006E7D8697A7847365E83F3670A0A61ACA65 -:10E9B000FB6C23AFD77C3B97E32A7C97C779B3EDF9 -:10E9C000E9C8765C4FECD603C6401E2E5EFDF1B35F -:10E9D000FB000F8BEF4F2639B5EFDC57E6FB68FEE7 -:10E9E000019F5201F290B33ED763248F15B203B258 -:10E9F00050773962F4B0E60DB949CE4F6A3988FADA -:10EA00003E737109C9F94F53BDEDF669B1E7271996 -:10EA1000F00438DAED362E97659D97DA3F6025BB16 -:10EA2000678B99CF07D60DD1D722E8512EE6536ECA -:10EA3000D7D133CF3687C6FB40F2EE30C9F8640138 -:10EA400033D2735512D91977EC01B90072B957C096 -:10EA5000DDBB75623000E3DF21311FCA8D5EBB373D -:10EA60000BE5C30B7F91EFC4F9F69642199E3F1652 -:10EA7000F2BEB7CE9B658FD38BBD7B78BD2A777AEC -:10EA80000B787F55DF6476F0EF646E99B817E791E5 -:10EA9000AC302F96972F2ADADB4E7A7B01CD9B790B -:10EAA000BD5912CCF7F4AAB13AB42355FAA4157A99 -:10EAB0006FC2F9DC8EE35B627452BFDF8EF346BD3A -:10EAC0002F83DE87F93EE0F0D3FCC10E984A76A092 -:10EAD000B003DA71BED362F8654A781ABEFFFF0848 -:10EAE0004FF760FDFF144F23C88B00B66B6C0579A0 -:10EAF000A18B9317027FDBA4903E93CB0B0FEA39D7 -:10EB00007CBF00E4E3ED36FF468447FDFEE2071AD2 -:10EB1000C9EE53E14AFED68B355F65C3D759A25D76 -:10EB200076E203D366067AEC84A19FE4E289F9CC0D -:10EB3000D38EF243C7EA118FAA5D5971FF9AB718B5 -:10EB4000D8B397ED32D1B95BF266E1BCBA81AE269B -:10EB5000D4C37586E0BE82985EECB50777AC40BA48 -:10EB6000DE52E209B8493FD27A0BB42653BB5E7B32 -:10EB70009829583FC36D034890CE448FC86D86E0F6 -:10EB80005E09E9CDF9A577D5A4604022BA07A8FFB0 -:10EB90006D9C7F7AEB18D9F7BDB7B9886FCC2C681C -:10EBA000467846E3838C0E467CC414EFD43A6B0C53 -:10EBB0000F3F13EB3AB93CFCFCBFA11DB9D94C7611 -:10EBC00024EA4CDC77B19E4C8217E8F902F187BA4F -:10EBD0005F7A242BB889F6679E0AA4C746AB7709EB -:10EBE000C1FFED6437C2BFCBCCBA4C65B8FD609DA8 -:10EBF00024EF043CACE73186F6D99DC23EFBF7FA20 -:10EC00004B56B4035EB573FB0A19C504F26F29E3D2 -:10EC1000F54BD7257F88FB99A5EBE49011F62BAC3B -:10EC20006B8E371CB7CF208E82F1FC425EB2ED11A5 -:10EC30002BF28D1FFBA5E0F87FB4BA2D5886FE534A -:10EC400091ECD0BF38D6FF3DB16E17CB1C7ED69667 -:10EC5000EC46FC26CAF5F754F87A1EF3C67F4FFD42 -:10EC60004EE2B8B08F7B1FF105780FA5A23DFF6D76 -:10EC700099E89A08AFD31079C80CF58BDB64FB7A5E -:10EC8000C0A7BFD54AF355E1BD3333722DEDAF12A6 -:10EC9000C63F93DC54A1E0FCC5FE83ADD3EEBF18A4 -:10ECA00033C4CAC017CB5984F631C3DE8B7D6BE207 -:10ECB000BE8FB1BF18E3DBA9EB85B9A504F8055FEA -:10ECC000B92505E9E69738DDA2F44E805BC5A7ECCF -:10ECD00018199F4E433817E595BFD5487848ECAFD3 -:10ECE000EABDC7CCB03E80AFB64B12F1E3F6FB9263 -:10ECF000498F3113A763F3EA2437F2E74E43E469FF -:10ED00005A372F1919D2F5A239F202C9A342EE37A8 -:10ED1000B8F833790FB6BB90CEF9FAC2613DAD2792 -:10ED20000E0CD83B3F93F752BDC4C7BDD09EECC676 -:10ED3000F5D88C9884EF3707FEAB8D01FE4EE9F8CD -:10ED40003EB87940BBDFBD00FFEACB6272E122E34F -:10ED5000DF090C703900335D45DFB923896D82719D -:10ED60009B749217EDA3A6D593821D9C5F4CB85E51 -:10ED70001A04484D3AD8F795C5D67793EE6411EE4C -:10ED80009B1A4C9B87E414AA3F8EFB2D86FB25E83B -:10ED9000B71A3B150CE7E7A6CDBFFD33C2DD7448BB -:10EDA0004BF786187F489F49D83F8E5F0A627C40A8 -:10EDB000F635CA876A161C2F713F0C96936B8682B4 -:10EDC000E8876916FE89F463E1B9C81FD6F27EB6FA -:10EDD000149ECD67B97D317370CF2BB8CFB5D70CEA -:10EDE000E5E2349B5BD75E7DFAEA187D5538670C07 -:10EDF0006E9571FFA6DA2571FBC7890BA6C43FD7B4 -:10EE0000533FDC8FE2F7C2F80AD785C2F5D936A1A5 -:10EE1000CF40EF91DC5DDE3381F41EEA25945FEA9A -:10EE20007E16E519CA8F271D558B1C30CF92B4AAC8 -:10EE3000AF38A6F1EF901D8F9BA019C3F199A85789 -:10EE4000D476B8AF6DB18CDE2EEAE7D991CAE583EE -:10EE5000225179C54FF57B36117C0AF1CBDADD05FD -:10EE6000246F557F4C83F043AD10FE9B15C27FB3DA -:10EE700072BB91B9E3FD55416DB941ACF74616E659 -:10EE80007EACFD501FEFB7A966212BD6A3FF069FCE -:10EE9000FDDAFECD2C385B41FA0E7C668C7FCF7A92 -:10EEA000F97CEF1474DF61E67E9B99EBF6C8DC1900 -:10EEB000C5E79B5AE62D7810F5C49B7AF22FFC87A4 -:10EEC000A0938A17A3A3EAEB88EF24DC8F61BB072A -:10EED0008D8497D3A08F0F0ABFC602DC67B6F9B343 -:10EEE0000A0B113DB6BC05D6E1F8DDF492B91EF966 -:10EEF00065B343A7E1A72A879ECAE4EF41BCB727C1 -:10EF0000935D0D689E8A7C543156D5936C2AFA998C -:10EF10003ED483BD05E5A65B2D7E1C2F8C76019427 -:10EF20007708F9B5C361A0F1D472741F27F805BE44 -:10EF300043E3A1DFC517C707C168FBADC25EE4723A -:10EF400061DBAA24924731BED531E2DB129F01FD7D -:10EF5000452F0939F2122094F651FD662E47142EE2 -:10EF60009F5E3A3B89E4DE1B1FAF26B972695112DE -:10EF7000334AD4DE2B61FDF3C6E07A28DF25FCA8F6 -:10EF80002F49DC0E0C1CB1D2380D06FF0EF42B34C9 -:10EF90003C37DE0314632F1882DF7F1AEB5F369352 -:10EFA000DFAA2185C3D9F0D21892933FD6079FF9E3 -:10EFB00001F9218C649F3524B953A9FE27690CEB14 -:10EFC000BB92FD8348CF6C23B71B1B0CA1223BE0F7 -:10EFD000F16490DBBF2751D0E0F88356B26B00CCD0 -:10EFE0002CFCFEA9EE4CCF26770C2FA71E9A4CFCCA -:10EFF000BF4DCFE91638CCFD9A27F5BEB959503E22 -:10F00000F97CA907768EECA2CF1032008CCD5BB8CC -:10F01000BDB64CE7EE6B45D9F472B247B3DF7C78EE -:10F02000652DD637AF5E7713CAC1D1D633CAF37810 -:10F030007FED0516C9A3FD66FDD8FE107CF7C2E082 -:10F04000440FA947E60262039FD878DBD37AC03722 -:10F05000F2D7113DF1EF171D1FE78BFB3FD42FF8BF -:10F060009D6690BF513F32C9DFB8B23C5299D3B3CD -:10F07000F9A54C619F69EBEF48F55F40B9D6F4DD27 -:10F08000DF9F6825FC4648FEB11EEE1F3FADF72E00 -:10F09000463EB557870C4BE3F6B78634BE8E9619BD -:10F0A000855E672143FCBA53EB2BAAB47CAE3EF5D8 -:10F0B000697C1F691DE2727C78BD4EAC9BAF185114 -:10F0C0006F71D70DECA7CF727F8621CD4DF533CF71 -:10F0D000860CCBA09CBF2E6458219EB82E00DF2149 -:10F0E00013CCFBF40E2B5FCF80061C67C57446F66D -:10F0F000C80A19ECD0327CEF1E08035DCE3C6FE7E6 -:10F10000FCF527C00AE07B0913ED8C60B782DC7A3E -:10F11000B1530AA15DBF64BB71AFB900D7B157B697 -:10F12000223D774B24B796745616ED80F2EA43538E -:10F1300088FE29D3395FAE0EDA49FFCD147270997B -:10F140003168203BFA19EEA783F1C91E6E804E5933 -:10F1500065C3F180F25BC30F416D9C6166BF90A7F0 -:10F16000FBE3E20B63E3E47A7F427FB0E3B4FC119C -:10F1700050F50E9773CC9D89724E95C34687AF3478 -:10F180008DE4526126D217E8C9E5E44189F0DAC876 -:10F190005AB8DE10F23EFA5DA12FCEC801AE978CB0 -:10F1A0005BE93937AD80E8B61AF50DF9CDF9FE6E99 -:10F1B000343E989BA6137271643EB85EF041C35909 -:10F1C00016BA16BED7B08E851AA7F2A7752AE941DE -:10F1D000AE0F4D229E61E2F18ECFD38B897A70986B -:10F1E000DE4BD0779906A1DF049DE3FDD9A8EF6738 -:10F1F000AE0BCAE8D7CCB379AFCD4C8FD92FCDEFBA -:10F20000994CEEABB0EC63632DE89FA97CC685FEFC -:10F210005DD88FE3BA4A06BCEC81F7BB55FBD6C577 -:10F22000E7EB3270FED52B3E566A41BA0CD17E35E3 -:10F2300092CE6CC88F2A3E775BA15F19F6E3EB2D67 -:10F24000DADFC43A93E2FA57BD6426B97AE5B035FD -:10F250006824BBC39F6F87F1327E65243BF4C24BA9 -:10F2600056D29F1784FE73AAFB7EB681E8D38A74B8 -:10F270004D476EAA1A83FE5326CD1F832250B5C375 -:10F280001AEDA3F9B3457DC1D0AD9CAF8CB45FBC82 -:10F29000620F7F13CB000F43FBBA05E98CFEF643E8 -:10F2A000B34B1F80F7CD3E8B8763DF5F8AFC6A9488 -:10F2B000EFBD15FD2A73E57591FB601E8DB9169B98 -:10F2C00011BA54E7FFFA97B741F9A3437A66443A73 -:10F2D000EF9BBD888D1D5DFEAE0AEA4F86E3D6CB5F -:10F2E0009AFDDA7263BFB6DCCC9493E13879FC58AE -:10F2F0009AD5796632C90ECF67C0DF4663CBD93D58 -:10F3000000AFF1C746D2470D69FE5D69E837D545C4 -:10F310005E433C1BF3CF4D453F4555FE9F28AE73E2 -:10F32000E5DBCC83705F315792FEBEB2C3EC0EC4F6 -:10F33000C9AF66C1FFBD79B554DFBBD3E896787D10 -:10F34000EDB40AB407E9DBF867D201FE9BB7CFFB47 -:10F3500088F64D68B543B917ED4BECF79C146C4734 -:10F36000FB713BD77BE7C17E34A1FE14EBA9591E8C -:10F370009C6B82FFEC75D44C44F9A2FC59F121FD41 -:10F3800037E25071F6EEE1E8FAE47E9C1BD08F3351 -:10F390008EFC3887516E349AC2864A18E7BA3FFF0E -:10F3A0008EE4F2CAD6A564D7C7EC5C23C99195F761 -:10F3B000F9E9FD2B3BAEA7799D8179237ECEECE662 -:10F3C000FBB995399620C2779D9DDBBF2BA19F2469 -:10F3D0000DC74B221E7EB3EB7A17D2FB378C7F2FE3 -:10F3E000D0CFED84DFD8865248FEB85B52D0CE6BCA -:10F3F000DE7EFD4728B756EE963DA8C7D9112BF9FA -:10F400003D56EE9E3371B905C7B99C568978EB9B82 -:10F410006393E9BDEC0B72FFC9D075F05EE9BBC622 -:10F420008DEBE4F86E2387CF6E7A1AE1BFEECF3210 -:10F43000F1BDA2637EB4577B0DDE89B8DEDCBBF67E -:10F44000CD45BCFEA62E5B47ED9F95980DF1606FF4 -:10F45000CDC0F72B25C587EBAB7EFBAADA787BA462 -:10F46000334D267C57E6AFCB085B88DF6F453DD731 -:10F47000B85B4F76DDF1051FFCF236678CDF57CAAB -:10F480003DB7CE8CB3379A77DD28F8013436E06982 -:10F49000A5C093317F5D117EF7F3F87FE5FA9622E0 -:10F4A0001E8FF9EBEB20BABE77F1F5F007D0F7B479 -:10F4B0005FCF7168ECFBD1F641AABFD9E461DE7D74 -:10F4C000168A1B7A719F9BE754A83ECFC9ED6CE565 -:10F4D0000F6BF7BF0DF0F7A7F98D4E789FCFBCA546 -:10F4E000485777C45605E6244E89EC1FB6CBC8EDC5 -:10F4F0004985FBDDB6A5B3A737C5C1998DE3A5D373 -:10F50000FAB43961DC0BEFFFE935C45F53DEB9A90A -:10F510003C9EF63B8A4F590679DCD2E2F131E48B0E -:10F52000E6C13A7657494C1E367BB8BC4E9CD77222 -:10F5300027DF67343B23344E753A5F67AABF77678E -:10F540006B12F9F5763A8366BEBF0D3094E73795B6 -:10F55000CB3CDE22EC129FF09399BCAF308CC730CD -:10F560008FEC190FE521EFA9CE3428BF5D3EC723EC -:10F5700043D9E27DB26B2CCEDBA317F5E3C85FF86D -:10F58000D6AC4AB24F6EF2CAF45D569F42FBF521EB -:10F59000EFCF9D77C1776F66DEB4D3F08D1A50D66A -:10F5A00048C721FC36DA018ABFDC19E75FBDD133D9 -:10F5B0002FED74BCBEF472FD8FFBF17E113718097C -:10F5C0000F2569953311BFD77D99D3E1E367F9FE24 -:10F5D000E36333F763ABED3EB6723D53EB94841DAA -:10F5E000D89F87723E5AFE5AB1260EEC34F4E7E1FA -:10F5F0003AFBADA41D6775978EE2B3ABBA18C5632D -:10F600003FFEFE8B79286F3FDAF762DED238F812C0 -:10F61000FBA9CF5B9D5ABF94EA87748AB8F4528FD6 -:10F6200091FBFB46F143AAEDD976BE1FBB08D21D64 -:10F63000F94EED77B13EC98B76E545662279B67411 -:10F6400050F835BDDE4227EE1FD4FE09E36F41FEC0 -:10F6500001B8A40189F6E7C9251192AFAB4CBED71A -:10F66000C6B8312FC54BF499877494905FBD069C42 -:10F67000B722F67946C5D788F45CDEA3A56396D396 -:10F6800026E2944EA2BBA1C9A2A07EC8E810F2FA5D -:10F690001B3ADABF18B25D16944BD715257562DC9C -:10F6A000DD99943215FDE6B9D9C5D43E50C5F93A75 -:10F6B00090C1C86F95C55A2492B736EEE7CE99CE61 -:10F6C0006C98E7F1A293DB832EE6D92E933DD82FD9 -:10F6D00091BF5FCC5F95EBC82F28E73E964CC42FB7 -:10F6E000D2A044F69DACEB5F8CE38EC63FBD09FC17 -:10F6F000D3FB0FE69F3EF57BC3F8C74F71BAA52E2B -:10F70000D3C8FC23FCAA5FB8FD6871C26F98543F50 -:10F71000B384F3AD15E3D59A2C21792AC98773F107 -:10F72000FED45D6067E27E448D2B8EE958E2E6767A -:10F73000FA5018F7E5C9D79848CF7D47375480F677 -:10F740007C629C11286B47798F3286FC8AAD55BE4E -:10F75000D36971FAFE08DF3734DDE7A5F7B307B9DF -:10F760007E6F2E3490DDD93C200590CE4D3E43D0A7 -:10F770005440719525A4B71F32BB799CC4DD4E71EE -:10F78000926FBB791C25EA470DF73D80FC566F212F -:10F79000BF4362BCE585BFC8FCFBE3197DBFB794DE -:10F7A000C7777AE7B9C9AF911847635DDAF5ABC699 -:10F7B000512E5A0131F0BDA59BCD44876C99E39938 -:10F7C000A59AB87E192E07C85F9B315D1046C43BD1 -:10F7D000A2EB1A240396B345BD1A9FB196F80AD03E -:10F7E000C2BD3DEDB93793D2FF967C86D6EFFCD5EE -:10F7F0007C8680B116F3194C683D8B7A041BF4ADFE -:10F800005AF69ADD18BF89D52B60379A0624F1BDC8 -:10F81000E76F9853087890D4EFAFDFE4B550BC5849 -:10F82000F3BD78F89484F1F530BEC52DDA070ECC1F -:10F830009BA3505C52D47FD68DF91B5BF4DAF108A0 -:10F84000A5A23F16D4EF1DCF9CFB9DCD3931BD0F36 -:10F850007680297D5A4CFF6FFCA0B6E72AF856B295 -:10F86000EDB201F5AAAAC79B9D3CBF2171BD3AD25A -:10F87000F97A05FBD5914E7283DBB5B5223E09F6C8 -:10F88000EC5C5C5ACDEB7C0CE393602F64A4631EAC -:10F89000C3FBE7CE1C45FA2DF898ECF9E64F15EEC0 -:10F8A0007701BB03ED7393E07336A0277DABF2C104 -:10F8B0006A217F7AEDA0EF915F8F48D302C4172DA4 -:10F8C00079B7000DEE4FF7BA697CB1EF4A847746FD -:10F8D0003AF793341757ED28C2F19F9218EAFB4D7F -:10F8E000C52733D02E691EFC3063795CBF55038F6A -:10F8F000121E56EDD78F38FF19E9DCBE6C3AFC3C7E -:10F90000F9073F0E4AB496EB9560F74C28D7D7EB32 -:10F91000D04263E5C125B791BF7F91818D87F9E51D -:10F920000B7DD4BCFF2B8199B83F837F12BCDAE9F1 -:10F930005B417A6FE7229305E30ECDC54BEF263C82 -:10F94000D892BC88874DC55559F89DA6BAB9368A54 -:10F9500013807D85F54DF7DD4E7E1315AE4D03FA10 -:10F960001AB4BB2AC0CEFA11C09DEB985FE381F5B3 -:10F9700037463E587A8F05E3C223CBDF7FC9E0F4D8 -:10F98000EC947C819BCBC94FC8E2FD7EF903DC9EE1 -:10F99000AB4B3768FCC275E9DCCE9C15189A8DBC60 -:10F9A000F7B2124E46BBB799793FC1FD25F359DC3A -:10F9B000FB884E5C8E38DBDCE43F3239C3DFB90AAA -:10F9C000EB6729B47F604AF811FCEE856EA76713D8 -:10F9D00013FC8BE5FB4A822847FF39DDBF18F9ACE1 -:10F9E00042D88F170E5F5F8A7E36D53EEADE630E01 -:10F9F000621CB0DBEAFE6E0DCAC13F283CEE6D8A88 -:10FA00000CCD467AFCD141E3769B83DD48FFC0569E -:10FA10003DD51FB6FA5721DF9CADAB29A2BC1B4BCD -:10FA2000A008E3BC7A670F433B01B60BE44F3039C3 -:10FA30007D0CE3A1B3034B1409E57C82DD315BE46B -:10FA40008F92F084F755428C8D072E3863A225D013 -:10FA5000F9595ACC0E79E34F0B157CA9DA273A13E2 -:10FA60008F67552F4A6232F2FD86C86B3AF45F3BCE -:10FA700087C87E6DEC97E83B8DC5CF513ED81A9173 -:10FA80007714CDFF51C2940FB53E3D59E8F14ECEEB -:10FA9000EF6C88F6CBEC00A7276361CA938AED234D -:10FAA000DAA99D3A9E41F8DD1B85DF053418D53F64 -:10FAB00094AEDA07EBC553CDEBE2DFDD260D7965B9 -:10FAC000C46BA9A4F117ABCFA7D2B97D987A2C3219 -:10FAD00017D76FE4B09AA7C9F330774C9BE441D3B2 -:10FAE00069589EE6C02773916FC0D0A6F5DA34F04E -:10FAF000C5F234BF2FF60DFFEB799A1EC9BB179ED6 -:10FB00003F4AB773BF959AA7E9E1F853E36C89F9C7 -:10FB10009917B2420ACFB70AF7ED43FE1C30521EC6 -:10FB200057EDC0EBEFA17EAC35B17E8C4326DA19E0 -:10FB30006DB6AF0C22DF5F3C7FA6EF418679BA2F0E -:10FB400078285F23C17E48DC27ECC52659A3DB7BE0 -:10FB5000EF46E9C9EDBD68F97FDDDEE3F67C601FA5 -:10FB6000CF0F50E579B3D89F5DACBF94827AE6445D -:10FB7000149E843C86A7441EC3E0C8790C8AC8073B -:10FB8000027B3D407C7290C775DE783A99E4C725C8 -:10FB90009BB217EDA5F3D6C83711598AB0933A8FA7 -:10FBA00018DD282F40DE91FC0E1CD4F3380DC66DF5 -:10FBB000308EF3F24411C711F1A29792C96E6948D1 -:10FBC00071A7627F354EF363A16F1A92787CA62BE2 -:10FBD000D97F397D84B8CD1E617FED81A16C38DE7F -:10FBE0007B4611C7060181FB9D877279DC41C46D9C -:10FBF0002E8AB8CDA9625DC8C0FD10E4A77277292E -:10FC00002C0BEADDEF99836EEECF32E940EF2F53F4 -:10FC1000E3362F733FD532119F39B5602EE5072D9E -:10FC2000C7FC7719FD18DCCF1CCDC767361DCE6722 -:10FC30000D888B9D28620280F56BE0B5A493D09E61 -:10FC4000707742998C656F4F0D7C7769A78EF6238C -:10FC5000CBBAB4FEF22B9BEEAE41FDBDB193C71FF4 -:10FC6000035D12E9EF65CCEB427B43E587828C3480 -:10FC7000A273A053E7C5EFCCC8E0FE04407D90E638 -:10FC8000279E9D7AE1671770B4335D089F3A893FDC -:10FC900037DA949A11F5B218AF53DF62AA443B36B3 -:10FCA00057477EDE2B06EF22F2933A8A886E9DD666 -:10FCB00096AE1A5E4F6BE58A39E2A3FA6B156EE8D1 -:10FCC00031B703E564668688DF24CC77798FB69CEC -:10FCD000187F5815D4969731FF842C3C87B05FFB72 -:10FCE0003E3383CBA92B9B0A849FDF437EFE4EBD10 -:10FCF000FBDD029453DD0AC9C9F61C8E2F5D2E7FF1 -:10FD00008EB5572F22FBC00E7605C1CBE11F7BAD10 -:10FD100053427DD969E77CF93F853B11DECA8C22CD -:10FD20006E27A07187EBA85B0A727C71B8BFA8BF71 -:10FD3000626986F01708F9132DFFEFEF37393F7628 -:10FD4000CB62BDD948FE2C15F1C65392E7E910BE2F -:10FD5000B7805D00702FEB96CBD03E99FD150BCD93 -:10FD6000A3E96573D008F58DEBC279B88E9AAAC263 -:10FD7000452D23E015A15554B905ED963A617F80D4 -:10FD8000EBB64B1B871A1E57F47E2B231DF721A7BA -:10FD90000EBE8EF43E6826BD04FF75D488FE8EC369 -:10FDA00005642F4D4DF5B765A03E4F0AF57DAF00B8 -:10FDB000ED136E1F350E1AF7A0FDB7B4537B6E8698 -:10FDC0006DD6C6B9589783FC19AC57FB1ECFA768F0 -:10FDD000FA0D8B7B713DBFCDE09F8876DD755FE6C8 -:10FDE000F1F5F3AB740CE9BB4CF6AC403972DEAC08 -:10FDF000B5BBCF5B39BDFAA274F614219DFB46A5B5 -:10FE0000B3A708E9BC4CC7FCF1E334229DAFC6ECB4 -:10FE1000734EE7F3CF5F5384743E77F09A22A4F3D6 -:10FE2000367D8F17D7CD930EFF5EC4CFE9393EB232 -:10FE30009BD4BCC92FCA8F8732B4FA305AFE3BF923 -:10FE40003F46D383A1281C5A3DE834B873501E2E78 -:10FE50003519FFAA3EC4BF11FD692623F9235EFEB2 -:10FE6000D3E58751BF050665B23FD4F15E56FCE38A -:10FE7000D05FF0F27B2E4F401A7DFC066157B94CE3 -:10FE80002C807E0FD5DE57EDC64479FC0B319FD315 -:10FE900019DE1AB4B355FF6CBD18D314BCCCEDD326 -:10FEA000A724F2BF9ADCFD3C7FFEC8121BFA67CF85 -:10FEB00006B93FB6E9F952F2D7AE0ABE12C2FC2724 -:10FEC0003628D970DFB0EAA90F53309E0DFBD0530E -:10FED0001971F19539621F7A36782A05E3DEF0FD53 -:10FEE0006AFC7EB2336240FE6D82FD1934614D4A78 -:10FEF00084CE0D353919E9FBF201ED7E4D8D4FEEC3 -:10FF0000F41948DEED1C9482B83FCB30F80B7250E8 -:10FF10003FB11CDB99E4D87AF924C36BCB9C161F44 -:10FF200017F65ECE88CB570AEF48253E0CEB999723 -:10FF3000EC801D56219778BCE63F77D9833C7F89BA -:10FF4000B7FFCF600195557DBD429CC35B21CEE1DB -:10FF5000A1FC0E25C8EFF87234DEAC9E3703791E83 -:10FF60001A29FE1D97B714DFBF8945447EDE674618 -:10FF7000CDB8D17C9D965237C0BDE66B163A67D896 -:10FF80000C7CDD5A16E3C3063115950F9B845FB7D1 -:10FF9000B9FE24ED039AF17C05DA551ECE870DB02B -:10FFA0003FC2FCCDC475CBFAB5F98CA3ADE329995A -:10FFB0005ABD122DFF83FC98D333B5EB579DBFEA92 -:10FFC000078FCE7350E2EB2B615E89FBCA44FFB50D -:10FFD000BA2FFCA272EDE64CAD5C8B96FFC172EDC0 -:10FFE0008ECCD1E49A363EF037CBB5C4384121F7F8 -:10FFF0007F639C00E3B6FFD338C147EE9E0C1DCF54 -:020000022000DC -:10000000C3D7C44FBBA4969B4CE330AEC8E3CB8DA3 -:100010005623C56113E3AACDEEB9228E38F4CB196D -:10002000A8370FE919EAF37ACB4A8A5736CB070C7F -:1000300078A470583C51394A76FBDF1A575F9F19F4 -:100040008DAB17605CFD15CBE5347F1C3DAB4AC022 -:10005000C02F193DDF68B3A053B2C88B30290166A9 -:100060008FEB3F5ABFDE4C6E27BF22F2635C069EC9 -:10007000C7BEC50AFB3098BF4BC7F377EE4FF76D8D -:1000800043F9687273FC3E71F8AB0CCF1D3DA1EFD4 -:1000900027391268B478501EAA7E17757C45F80F70 -:1000A000BE28DFFF2081EF7FF077E6FB447C0CA8C1 -:1000B00072E76F8D876D07DC68D607A3B8D75B182A -:1000C000CF2918CEC7A38D331A3FFF34D3F75A2652 -:1000D000C947EF54CACBFD82F226B93C720AFD3BF8 -:1000E000EC90D18DFB0D933897C13667893C4A4F10 -:1000F000451DE513F3730DEAF98FD1ECC20FA3721E -:100100009ADB851F8E2AA7FF7B76E1030EDF299CF1 -:10011000E7E94A6F11EACD8D56801FF77BDF378EF6 -:1001200078CE423D0F00FCC4CF9B3CCBE3E0897C02 -:10013000F58704FDF287BFB37E194D9EEA5D2A1C48 -:100140007F67795AFFC714F47B8E3E4E80E0A8A8E3 -:100150001AF28AB815C3B8913A8FE6219E7F96218C -:10016000F2AAD4F7116117DEE9F266BAA0FFB9F777 -:100170004D26960A2610F218DA633E0BC5039AFA4A -:10018000799E48D33A46715FF51C65D3401D43BB49 -:10019000AF3FCD5F8079601B3FB004E454F4932FF0 -:1001A0006068EF5D789F971BD2FCE3294F6C5D5828 -:1001B0001377A8F8ECF206F46700BCE41F708AFC21 -:1001C0004C15BE3A179767EAF32681EFE8BC9C1CF2 -:1001D0004ED62F07D14E4C760F911FA9E91037DE6E -:1001E0002A642FF9EBD91A079D9F683A54594AE7B8 -:1001F000CDFBCDA568E756FCAAD686FE8973D73A13 -:1002000029CF204F0EAF423BEB9FD3FDB3105E6B67 -:1002100079701EDAA9F960A7A2DD7BEEE0BC527FFF -:100220009CBF7B1BFABB61DC6D56AD3F9B99789EF2 -:1002300078FD5E9E077CD8EA9F8BF8DD66E6F006C7 -:10024000B68ABC67E1E74E5CFFEABA8F9E73BCC317 -:10025000447169552E6CD3333FEA3D559E94883CDA -:1002600039C007CFD31BACE3F91EA26C716AF3153A -:100270004F67CC2941784AD0D13B0DEF518848E8EF -:10028000775F2EE2F0D78B7C0A357FCAA8F8BE8E46 -:10029000EDD9BA9A58FC7D2CF617F177912793FC8B -:1002A00029B79FC7DA0CC43756585FE41F01BE4117 -:1002B000FACC8A0CCDC6F34485BDA15988CF973FAF -:1002C000D5113E94BAB7287E928A648371C66D0EAA -:1002D000774F403F8AED17D7225DDC3DB62A445D5B -:1002E0007F9AAF91E0505A8A715F59F5AF7A9E07B5 -:1002F000782499FC03BD790D940778E103E388E73E -:1003000046D46780ADA7BCBFB1033F273FBEF59081 -:1003100034623E6797CBC2CF0D078628BF8CCD7263 -:10032000123E9423BFA2B8AFD2AD9007A353EFD52E -:10033000E139A8403B23FFE5F85E9B0EE9922FF2DE -:100340004B2EBEFC5F53FDB44F51FDF6419E0FA4F2 -:100350000F6FC07D97D21EFE32AC60D678C8AE6BF0 -:100360002AC1F1224D3CAF3D99219FE40F8C5BFFE8 -:100370002528E777D99884F2E7A535F9E42F857920 -:100380008E1F619E77BB78FE8E722459877A4BD977 -:10039000CA28FF50B1675411DC8F4219C65923F89F -:1003A000468D4702B82ED44777BAFCBB11CFD17324 -:1003B00032AD49FC9C8C3877696DFDE0593C7FD2A9 -:1003C00067E0E70C8FBD3C7901F9EDBA1509E970DA -:1003D000C5BE24DF06EFF78B756B558698CD128F5F -:1003E000FF63946F39F608CF4B53F49C4F946EE73C -:1003F0001EF40B7E9AEAA7BCD26B3B4332C5B36CAA -:10040000A71FA971C7ED6BB6733DD2B49FEFA713B9 -:10041000F7319FA73F8EBAB47649B4FC0FB24BDEDA -:100420004AD01B7FF3FE8469F77589F649E23E6E78 -:1004300098DD9D30DE68768A9AD75115FB0EF1C3A0 -:100440002B56D50E0A68F25EAA2CE2DC9B493BFED5 -:1004500053224F47CD83C9E870B7635E79E4DB8CE4 -:10046000FC6C6A3E4EA08AEF1B023A139D8773B163 -:100470001ECAC319C3429244F67F98CE7566623E87 -:100480000EF47BDF3596E0DECD3C5D32C943B784A8 -:10049000709B318F83F236833B56E0776EB1D07715 -:1004A000CC98C7713586E2BD3B507ECEAEE77188F1 -:1004B0006CD0B7C8B7D9859C0FCD8B783E879AAFE3 -:1004C000A1E657A878A812F8CD9EB0A200F707DDE4 -:1004D00092FFFBEA79DAF873D2D1F3D1ABC6D279C5 -:1004E00093E8F9B94226EABFD839E9447CAAF91D54 -:1004F0005536BF2D2B7DF87959953FE2E84670EDD2 -:100500003CC2EDF5AA7A03C17F71D57CF2235E5C13 -:10051000A563B86EAA068D9CDF12BEB7337A0F466C -:10052000D04CF75D08BA7F9EBD0AF42C463FEDB172 -:10053000B69AAB4F036E8FB7F9E879D12CF5CB574C -:10054000D179C6C528992E67EDACC57B0A2E5A23F2 -:100550007978CFC1E5EC076FA4727AE404965376FC -:100560001EBA11EF3DB8383ED287F71E14EEACE448 -:10057000F5C883D98C5D9555716380E6CDFD4EB38A -:1005800063E7B3CB113F8D2CBC6188FC3B3C7F1FE4 -:10059000F3FD900E2E8B81EC1997C8B364D522EF32 -:1005A00012233050EEC82AA578B585B90F0D617DAC -:1005B0000E3F2704F5C4BF1DE3B95FD824E8CA7213 -:1005C000543F523880F2A9A3C04EFDA372F490317B -:1005D000C8FD59FCFBEF3C3F85E24B6AFE2863B641 -:1005E000DC855328DF445356EF37608A2D17ED859D -:1005F0000EBDB04B45392DD55F97156717BD33E755 -:100600005B25B80ECEBFF04021CAA5EB0D60B78FB9 -:1006100020877E9DCDE5D045BDA54B023BEDE7296A -:10062000FEDB719CF79217CFB5C3BC16A5551AEC2B -:10063000086FE0FB32CAC574416FFB420E9FBDDA02 -:10064000272D87713BCCB07EA17FBA5FF1529EBD52 -:100650007FA1740BC0DD2171790B9D52695F52EC53 -:100660004EC5FCE506715E5216EB7E46FF5619ED4F -:10067000E977DB06662A8531F87E2EE2CB3F2F60D4 -:1006800077D68DB0DF6DCDE2727B81EC9E827CB43B -:10069000411A78AB360BDFBBE9FD9C94D672CC3B9C -:1006A000BE3EB9A51CF5CFB0F7A9F0BE24AE6CE4F0 -:1006B000ED1A4C913C3C9FEC4DF6AFCBC2B8D092BA -:1006C0000F296EF9CDEC774E60DEC13BFA9ED92939 -:1006D000A85F0AC4B97EE1377C6D82EA3734F1F253 -:1006E00064EE378CE6734DE1F964B50BF939C55A00 -:1006F00091AF30D7C6CFF5CC2D2FF074008837B12D -:100700008882726FEE7BBE14DCB7B385FE72DF9415 -:10071000D1ED19E6D2BBE3D7EB3C775C19FEDD5097 -:10072000AC2DDFE8D1966F9EFEE709F1E53DC9DE0D -:100730001D38EF1F4B3CFF313083D9689E4E298016 -:1007400076C7E417B3C5F94E9EA7F74F625FF4E290 -:100750007446F519FB4D7B31FF5DF533CBA27EB2BC -:100760008B99F21DFCBE00D4571149E4FB39299640 -:10077000C25EB8DBC6F1076D0D30CE0B4BDCB43E6C -:10078000322C3AF6655C43E526B2432AC69892902D -:100790006F8E09BE53CFEBAA7C58A1301FE62FC045 -:1007A000A717E2F31DBDED28FA97031F31C6E955DF -:1007B000A950FEA1F81663ED547E4CF0F7310153B9 -:1007C000E0DB0AADE757AD06A2A7FC13790FEA09F3 -:1007D0008CCDA0DFF8D2E649049FBA7E6055173A67 -:1007E00033C8A52DC655740844B1B02754FE460B36 -:1007F00008DB8DC1FF2C203E27791399C6EF4FF8F7 -:100800007901972791AD0E711E8CC7CB724DD171B6 -:10081000BD386E56F43BFCBC51862843554807F35F -:10082000FE4D560197CB83AFFF81F4B2C5E3C7EF0E -:1008300018524C744E465D37B6CEDFBE553B03E7CB -:1008400059F40D9AE77CAB0DE7590C6CBDC8414FCC -:100850006F1A8DC7D78F9CE471E33AF94ACDE199BD -:100860004A1CDF40FF46DE3F59DBDF05FD1D71FD01 -:1008700053A07FC9F0FE4F594D21DD541CA7C21D66 -:1008800026791EA2C9CC17F3923378BFF9221FB480 -:100890003005DAA3BE29D6E66BB0E91E13BFAF431D -:1008A0009B9F71BDB42E0BD7D53C53E36018C67B1C -:1008B0005DD0ED7A9DFF77783FDDEB8B8B8EE37A11 -:1008C000AB310515DC0FDDC0421B9098172BFD4F97 -:1008D000D8C7913CF80BAE8B26D93FC101E5F3FA9E -:1008E0009EC2BB0B68BD7C96356D38BC2A5FA8F0F4 -:1008F000227F209F45F92301EE289D6EEAA744B68A -:10090000DD60F7E053B583186BE1F9C6EEDCD8BCC7 -:100910008089E69A5A0AD10E79BD3D4072E37AFB8E -:100920002394D7F4E7317E6736C0B5E8AA4FE85E76 -:1009300013E65A3201ED7B80373D3BFDFF1DBCAA1B -:10094000BD372CDFF6238326DF76B475A57EB799F5 -:10095000F1FB69660FEEA1FCD9E685160F9E836850 -:10096000C6FCCF728A2F911D87E784E99E13C924A4 -:10097000ECAE2F9A97CBD7616FA39BECB7A81C174F -:1009800079E5BDA51CEEDEBBDDEA3D27DCBE5BC222 -:10099000F83D29EA3D27CB6D54AFE69FF7EEE17EA7 -:1009A000BCDEE727D07929B0DFC85E60A93A0E5FC8 -:1009B00081F67E15FC933262F9D2DBF4DCDEDCA931 -:1009C000F354209E77621CE8AFC47FBF9AADF59BBD -:1009D000A8E544BFDE930EFFEDC817CB4BBC7912E0 -:1009E000F0CF3203F7DB017FEDC2B31535ACE5295B -:1009F000BC3F701E6BF9856E1CF1979FF86BF22758 -:100A0000FC5EC1187F2DE1FC1520A1A4F25794AF24 -:100A10008A13F3ABFCABB17DAFBDFF574D68A70E9A -:100A20001A892E6A9E5CE23A8E83E7B49EC3E394F1 -:100A3000658267ED48F07C113E8FE7AF4CC6F979CF -:100A4000347ECF5458C05A16E3F73DC9FE76843F32 -:100A5000CAF71BF87E6418DCB285F8E3D6DB649E27 -:100A60003F9ECCF515C62BB2E0FB75E2FBB7767363 -:100A70003EBAD56A20BEAB1B6CA47C2256CDE30ED9 -:100A80001EF81FDF077A09BF8B44BF85CE523DB2E7 -:100A9000ECC25A6D7C6291458D7FF8F4B81E6F5D93 -:100AA000A83F19AFEF17B1CD9F60DEDB228C63A8A2 -:100AB000FDE0BB8F6747E31813308E715CECD32FDA -:100AC000027F23FFBF9ABE72D7DDC0B7131E2F2946 -:100AD000437FCE9C8C554F6D85F2F7764EA2F2ABDC -:100AE0001977DCFB0ED6F71551B91A2F71C1FD46E7 -:100AF00023EF5F5C71DBFC02F8EE71B31817D715BA -:100B0000EEFB92FCBD75D0CE35756C19E623560B05 -:100B1000F970F16E9E0F7FC355569EE2B9D24D7E9D -:100B2000A3EA2451FF753EEE5BA5FF568679A9D551 -:100B300063238BE93EC6B21F4FC2F271E993C5230E -:100B4000C54D26174BA189809F6A076F5F5BF6FD35 -:100B50006CDCC75757F1F2644F65F738ACD75D5A74 -:100B60003CD2B9D09F8AF5143DF724D6E98BDE0F2D -:100B7000E99C93CF2479708ABEE91FF27B892C927D -:100B80000DFD8F3E6F81827ED2D95E9EB758656A19 -:100B9000CFC2FDEF4D7E4339E69FDA4CA5C7D1CEDB -:100BA000489D5E390DE93BDBC4F4A89780CFFF85F3 -:100BB000F8FC9A4FF25290B92C5A3E57F9A84EE5DC -:100BC000EF6A2D1FC3FAFCD7ECF4CF97AFA3F13136 -:100BD0007CFFDFB1FFA22F69F54A74BC84F596381B -:100BE000FE687200FFE2E55C0C8E7E5A573998155C -:100BF000360ED75D8FBAEE220887413744E73EF2C2 -:100C000025CF243AF0388AFE57E1CB05D9C6CA86EB -:100C1000C3857F8A6A9771086CB60CFC2EAF877EFD -:100C20005EE688C105DF676350EF6FE0F0EC965A2F -:100C3000B8DC1076B1BA3F6E52E73BA09D6F45120B -:100C40003FEFEC42FF05F673964EFA6B70370BBD23 -:100C5000B9D0E47BC80873B8C5BE8CF8E1AB2CF002 -:100C60003CDA27C654BF634C3AEEBB0247C205E4E8 -:100C7000CFA5BC01A077DA9838FB44852B111F4D16 -:100C8000A3C8C344B813F110A3CF10D957EAF9A9E8 -:100C9000E8BC12E6D361E5EB3532CDA8DE5F528CBD -:100CA000EBE26D699227DE9E7E3B416F27C2A5DA9B -:100CB00011AA5E55E1417F11FF7EA41DCF90DD3862 -:100CC000662CD99D2ADF640AB80C3A69C438EA8DCB -:100CD0006374AA7F4E43C7C4734E2ABED4BCA044DB -:100CE0003CA9793DC3E23509F1C8D1DA49603F8FAB -:100CF000710CC79F1AEF7144FD5C029FA512C93F9A -:100D000087F073CDF6F0F309B5ADFC9C7C6D0D4C0E -:100D10000070FFB6F01FA8787EC8EEBF8DF347784D -:100D20001AEED3BF3BEF698A73A8F7C825E267F9CB -:100D300028F8198DCF47833F2DD5B712BF7B5E1A98 -:100D4000AAC0CA2DE9E2FE41E62FC07560B715546E -:100D5000A21F02E4EA679FE1660EAB80AEE50E7F5C -:100D600033F2F957996F0ED2D751E3D773FF3A2375 -:100D7000FFED5AB1DF9A23F4EDA55D32C507AABD98 -:100D8000131F9B8576E21B7A16A4F5EE25FDB94666 -:100D9000C07F099FD8DEC2F5EECA377F54012B868B -:100DA0004DD8AE8BDDAF00FF26069334F72B4CDE1B -:100DB000EFD094A7F4676BDA5F353056535F1A9A19 -:100DC000A4A9BFFA8D324D79DAD04C4DFB6BDEAB66 -:100DD000D2946784E76BDA7FE9EC024DF9DAC8ED6B -:100DE0009AF6A7C4BE9805BC43C51978BF389FEFD3 -:100DF000759F2ED5F4FB6DCADC37900FEFDACCF37C -:100E0000972B01339A7B267AB85DD102FFE374F504 -:100E10002988AF15606F63DEF2CAED5ABBA37E70FE -:100E2000EB0694A5897915AB594B155E49979857F0 -:100E3000516D5BA243BEFBA731C2EEB8865D23EEC7 -:100E400085F9AB742D62E3FF5B7435BAB47435BBBE -:100E5000B5744D2ED6D2D5EAD1D23575BA96AE76C6 -:100E6000AF96AE69355ABAA6FBB474CD5CA4A56B37 -:100E7000965F4BD731F55ABAE6B668E99ADFAAA56C -:100E80005F4160B5965E09F456E5E5B8AEB59A7671 -:100E900051BAFBEA291F667CCFFD9A7155BA07E06B -:100EA0007F9CEE2D94AFFEB7D29DB120F95F13E980 -:100EB0007E3681DEA0AF3E42B90076C6397C2E9ADE -:100EC00020EC79DFC876862A7FE2F57AFCBE75349D -:100ED000B9344C8F897DECA87A2C611FFB3E66F1FA -:100EE000907DB499FC3CB709FEBC8CAF66A01FF5A1 -:100EF00007A49FDF0740A6035CEF23DCF09DF79378 -:100F000026939FE10E16D2D3BDBF98890883DE8950 -:100F100089C932DEE7E3A6E732A1BF970B3F8437EA -:100F2000D99F92C3FD0FF919F8DD9C217EFFF25B7A -:100F3000695FE89E8293E887079D721AFDF0F0BC16 -:100F400060E6FC7046950F5EE676C6E16DE96C8959 -:100F5000F4323A7C703FBBF4AB12C51996FE9E3F4B -:100F6000C7E770BB37F1D9D1AAE28DEF876EC871A0 -:100F700093FECD61FDC27E637ECB381A87FBCD9F89 -:100F8000E4F78F3E2B3165BA838E49111D334D1C1A -:100F9000AE67F5CC84F87B86F9DD8897EF28209A38 -:100FA000789EFE24E487A5BF7F672CFAB164D975CB -:100FB00013DE2F3D1DBF0770CCF95A8B847EDD4CAC -:100FC000578B847EA361EF0FDD2FE1F9C26899F1A1 -:100FD00076F8877850FD73C53A1EA78EDCCDF717DB -:100FE0004F7D9D91DFA9A3355019C0F8940C0607D9 -:100FF000E6B1E8F979E41B72B8DF2D8B0DD1BDA6FF -:10100000EC3561178AFBE04B44DEFB0511E759B173 -:10101000C7C4304FA2E4E05107C67556002D875073 -:101020009F297EBA5FA364C7AB0E7ECFB8DE8EE782 -:10103000D8543D3A3ABD1576262E7F1CE8D8329218 -:101040001E5F93CBE3B31D6D35B3302EA3C2F360A7 -:101050009B7716F287AC7818C693F0DE9DF8FC33C8 -:101060008313EAE3D6AF62A9D194F5161F5D66B18A -:10107000A1AD85F84C2FEE07DA98B3D616FFBB0169 -:10108000AB7374E21EF200433B9B8B7A7C2A675061 -:101090003EFC91F17DA8D105E3C4CBB57BF358BCF0 -:1010A0005FB9ABCD47F06E90FC7E1CC458C842E6D9 -:1010B00014CC5BC0B397F07EC7F56F601E8DC1BACC -:1010C000D613728F8E37A34BB9122F971EC801B952 -:1010D000941C934BDF6D3B4B78EA685B44DF037CE9 -:1010E000318C9F05B2B87DDAD1B684DEEBC0CE423A -:1010F0007E7A65C784A36EA83F01FFF09E1CA39370 -:10110000C3C5CAF3483F2D167C803EAB5CE09F13FD -:10111000AD7AE2B37B722D415C84F7BC3DFE28DEE4 -:10112000F369005E92FF06B8A3DF11783208B904B4 -:10113000FCE4C3F566C856C8FFEBB02D203AFD7736 -:10114000C753F16B3033BA87C6906B21BFCD17857B -:10115000F37B39097ABE3C8FE4E83D022FAFECE027 -:10116000794727EE6564BFDE731FF7BFDDD3C8285C -:10117000FF9BB5C25F458C6F54799D8E3781C0CB84 -:101180009E361034458C3DDC66C293572C19FD64A5 -:10119000E36274ECF12A7674C76FAD76D6E1F3E1C1 -:1011A000E9A77B50AC6C99F5BB217CA28F1BBF6F6C -:1011B0006B6141B43329160BDFB7D74319BE9F22A9 -:1011C000EA53FCBC9C2AEA5317F172AEF739A91A0C -:1011D000014B8883E45A1CF30A51EEDDC5F8B95B74 -:1011E00071EE7EB790BB632C8EBA6AACFF1AA37CFB -:1011F0007CB5FE71519F6539D9350EE5F2426DFF20 -:101200001D020F9996933DB3295EA2AD57E31BE9EA -:10121000964B6F50FF126DFDA3A2BFD57269683661 -:10122000D6176ABFFF90A84FB67079C87CFCFE54F1 -:10123000B5FE3BA2DE8CF5F87D8FB6BE5B7CBF436E -:101240000A127DE88E585C3FE9DC5FDAD7C6AEC58E -:10125000F5D3D316A175F470DBA7442709992C3D6B -:10126000B6AE6CAD6CC4F3E092906729EEB0D73B9C -:1012700082BC53EB1D367EDE5D7619888F8C16217D -:101280002FC43A8CCA0BA9C5C3998BFBB13F8F9F62 -:1012900061815D41FB220FFE909F73EED5317F9CF3 -:1012A000DCCA6E4862FEB8F6AEBB1C9A72C6D7B2F4 -:1012B00035ED9D0BC76AEA2DE59334F5CC9B4BEBDE -:1012C00065ADE0ABA492324DBD7A0E9FF5E46AECB9 -:1012D000677DE14C4DBB4BC56EFAFD9033F3D4DF17 -:1012E00019F198502EACB58ECD44BDF34CDB74345F -:1012F000B2D9B3B09EF0E8D4013BCF2F3E807159F4 -:10130000B4D7DBBCF47E1FD483E5C29E84F5E686A9 -:10131000F67BDA6C547EA2CD45CFDD6D6E7A3EDE73 -:10132000564CF53BDA3C547E0CC6C7E7A3300EBEE4 -:101330007FA4AD86CA5BDB7C54DED2B688CA0FB50B -:10134000F9E9F99DB67A7ADFDDD642E58D6DADF427 -:101350007CB02D40CF8EB62EAABF46D0FB8038C7BA -:1013600078A0929F4B4EA4E3AC5C49732F983596BE -:101370003F302B17F307FAC39AFBDD71DE349E99D9 -:10138000CF3F71BC3A1C0FBE3B890DB527F3754C9E -:1013900071C7F1039EF5C9C0EF635A381D0A0622D2 -:1013A000549F55CF695127E065CE00CBA9E0C750C7 -:1013B000B1DD0569A82A99C76129BF8CB9609E155E -:1013C000E27E1C62BBA00EE152A673BDA9D2353AE3 -:1013D0006F3B8713E73F12BC5F13F397CBFBF9FD1D -:1013E00017353D2164FB246F0BDD7F615AE40BE16F -:1013F000EF57387D7E3A8F3FE9D3B9B0B90139F361 -:10140000E997991B9E390DDA7D4FF65D659AFD854A -:10141000FCE9C3CC7D358C5BA2DD9F2415AED5F4F1 -:1014200033E5DCAFA93738D76BEA97AE29D8E0426D -:101430007C8E61149F316E6E6718525CDEBB95E046 -:10144000DA24F07E4172D379DEC041353ECFEDF330 -:10145000EF09BDC24C9B693D4CB0F362516A4087B5 -:101460007AE1DC8F52491E3DFD842E88FED7892CFF -:10147000A8C3F53F19CC3DAC9F8237E8CA74A58A52 -:101480008CE552E696B17C358BD0FE04ECF3F5B9D1 -:10149000DC3E7FC28CF1C15CFFF778DE5288F466D7 -:1014A00091A06791BA1FD9AE24FA65BB72890FB5B6 -:1014B000E7993A859DDE6EAFC8C4B8E88551F2CA97 -:1014C000ACAE9933F177B4AC59D3E9A9BE7FC8ADBE -:1014D0001BF19CEEE3025F2ADF4F0426177CFF38E6 -:1014E000CEE37CF9BB19B8DD6B2A8C10FF5F90BC92 -:1014F000AE2588D73765CE878359342F45E05539D7 -:1015000058E95A02F853DE1EE709B0D8779E6EF309 -:10151000CE549458B948E445EE6FAB9B591DF7FE85 -:1015200075014F311BAA41FD545CA2F30469649715 -:10153000467E990B7BBC78CE5C29631E146F1359D1 -:10154000CF7AD4D5CA5F64CA73518ECD606ED81776 -:10155000582C21867941AF47E7C934BFAFF43B5BD4 -:10156000752ADD17981D957BA813F1F79486907F57 -:101570007ED7ABE7F33AA6AD2FB6F0FC9D15C58636 -:10158000A05BC2B07A0FDD8BA7F4490C4D7FE52F2D -:10159000B3090FEC8564E2BFE4ED53E94AED9B1417 -:1015A000FF0F91BEE743EE1774E3042F42BBC6C999 -:1015B00086BD688F4D40BCE0840A8B09AFCBC57CEB -:1015C000F7B72D213CFD5ACCA33337011EE6F1E2DB -:1015D000BD912B7A55FF87769E0F9557DD8CF7ECE2 -:1015E000750CC9C256D2E273937E682AFE36DDF9C5 -:1015F00030C025139CBF46FACBDB2BE8F795408122 -:10160000D0FC1A9F80FD7E01C9A31AD2DBD374944B -:101610009F9AC857A7841C6BC9E5797F56D79767EF -:10162000E2EFBCC5CAB3883F9FD1B162CA2FD1F1E6 -:10163000FDA59ABF0186831BF775A579BAE83D1A07 -:10164000F3515FDB7594F727EF49A2F389B25DA1EF -:101650003CE34E4BB56D358E635328AE32579E3505 -:101660008476B3D1AEBB1AEDEEE37BEF1FC2FC1262 -:10167000395761E82FEAB429DCEEC8D1513E9662B1 -:10168000AF36611CA6C872BA12F17974CF37C9BFE0 -:10169000217F43E488087F925E90AC93B5D0F881B7 -:1016A0001C45DCE7E1AD2DCD10210437EE7F6A3E0D -:1016B000423FCA71DB2533DA2B6ECB0AF2A715E65F -:1016C00015D07CF4186F83F213EB2ED9516EBDB98F -:1016D0006783A300EDE7A0423648F19F3BB2E9DC07 -:1016E000F91E039D8B57F19A1F503471BBDC566D68 -:1016F000D99810BFD3279C4BCACA2B107A6E110BF6 -:10170000C5CD47EFE2FB35E6B4D07EA7304F629FF0 -:10171000E962E531A2BC5F1FC8F6007E8EED5991EB -:101720008FF3BA72D84F79BEA3D9FB1FE7BAD5DFC2 -:101730004332EBE87ED59019F37E9F6A63E968DF58 -:1017400099820AE55DEF13F2ACD0C2F9DF90CFF9D0 -:101750003CF159D8C3D79D722029988C74B3F59762 -:1017600005804F26BF328FB941FF15DABCE43F2C0C -:101770006C35A463FEC0DC1F5A884F2E5992C84FA7 -:10178000A8B42679F07DC7DE8A62771CDCC1365B9F -:101790003AE6E5EC6D33A5A39C0A8E225FC7D975A6 -:1017A00094AFECD6F17CBAF9791CAEF979FCBE970E -:1017B00079A2FCA4125880703E09F4C43CE9A39BB2 -:1017C000B93DBCB6DD4470AC7D731CD955A3E1EDC9 -:1017D000E936573ADE0FBF77B32E1BFD4795DD85FF -:1017E0009BF09E84B5567E4FAC9C3AE9314C4567E0 -:1017F0003FD533B4DF3B52667A96C5C97739755603 -:1018000031F2952C07B2D12F7267DEFC9B315F124B -:10181000E8B713CB2BFB4A79D91AC8C6FCCAE6BE77 -:1018200069BC9C1ED889F995DFEA9BC1CBB9816C54 -:10183000FC1DA9B6BE6B79797C60279637F655F208 -:1018400032FA9E40766EE99B7333CAD90E83A71E87 -:1018500005F20F00FE1280BF5F3CB70ABCA8F5CFAF -:10186000E17BC0F321F14CAC7F41F41B18A5FE25B0 -:10187000513F38CAF82F8B7EA151FA1F13FD8E8F6E -:10188000D2FF35D1EF8D51EA7F22EADF1A65FC9F46 -:10189000897E43A3F47F57F4FBC528FD7F29FABD59 -:1018A000374AFD07A2FED709E39F10EDC3E2FD58BA -:1018B000EBE60F42C07763418EA05C2AB66E76E0FD -:1018C0003ADFDB554EFCDF51C1E33B2ABF8FC5DF5A -:1018D0006F827A5D3EBF4F4A97CFE33CCF88F1815C -:1018E0000FB720DFAD7D5BA63C9B0E9DE76C10E53E -:1018F000E8261DD9036BDFE4FBF3B5DD4A30FEFCBF -:10190000C53309F06F10F0750A789FCCE3F139A365 -:10191000CB955E1BEF47B269CB9896857217E4377B -:10192000E5ED167757751597638C4C471688D26886 -:101930000AE17D0D8A55E8055B794F31C26751E8B0 -:101940009CBA625742FBB1BFAB9CEC3B15BE4E8BC1 -:1019500042F775C956AE07E6FE70960DEDAC4EE641 -:101960001FF2627F9742F6FBD1AE321BCA3D83F570 -:101970002E1BAEDF76379F5775537112CA6BF92154 -:101980001DC9EFE336BEDEFB5C3AF25B805EA1F37D -:101990002C20AF3DA82326B0503B9D8F78F885259D -:1019A000DCAFC7ACA515745E448D434B4A9CFD7FEC -:1019B00059E0275FE81105F50B3C9F2C17E71C0247 -:1019C000DCFF0464738D893BAF79394FE6E740D47F -:1019D00038A25C4BF716E5AD5334FEF79C7BB5653A -:1019E0004382DE5012F4CAB82E9093717AA7206019 -:1019F000D3944FE609BF8E8779D07E9DFBC3CD245B -:101A00000F2FA17E9346977B51F92BE4F193E21EB1 -:101A10009E2703FC1CF1D1CD653F417AAFEDD6D1B5 -:101A2000BDD35F548E3E93C7B87FDA0F7A07ED19A6 -:101A30008565E37EE9F3F0305EEF73D0BD0A9F83E6 -:101A40008FF18F963B50DE8EF72BA47786E98DCFF2 -:101A5000C1D7B392E73D3FD2D19EC4ED6A1B9F77B9 -:101A6000678693DF4724CE1FCAC25E7B50F8C195BC -:101A7000D4B96EFC89904E7B0B9537489ECC1BA049 -:101A8000FD46C96FC3F21B8E24AE777293880FF7A1 -:101A9000A32D43F71C16F8D03FD21F34A8F71486A5 -:101AA000F0FF0E627E8E7A0FA28BEC33710F63EF24 -:101AB000CDD5D85EB14D469373DA138F6DD1830DBA -:101AC0007AD0C0A2EDF13CD533C775E29EC4DD5B90 -:101AD000D05E3D98C434F7401E443F3A8D17DC82F7 -:101AE000F73EC2F76E90610F767DFEF7B658B26290 -:101AF000F054B90F6C69A73C59BE2FB1337E4FF734 -:101B000079773805970BEC4FAECAC77DF99ED3198C -:101B10009ADF5D13ED5345FBA6C148D30137B59F4E -:101B2000960FEBA07120925242EB2B5211DF3E45F3 -:101B3000ECF7E3DA7F89C61FA57DB10ACF81776F05 -:101B40002DE1ED2B71FC0BEE7006E5BC24C0933645 -:101B50007CFCEBFF1A3C9344FBF3A177A9FD05162F -:101B6000CE985240FD6EC27E17DF7AB742CC3B035F -:101B7000ED64908A37E37B34B7F8EFB1B490FDDCC5 -:101B80006FEAB1A1BD66D6F7F850EE16E2BD4ED3AE -:101B900063CF05F985DCAE4A78DF6F6269B5C88F1F -:101BA000AD3ADABFF49B86CA4AD09E7ED102320F8C -:101BB000F5C23A0FCAC181F05A4F09B4EBCB99452F -:101BC000FB8A8386967E3ADFBBC442E74FFB6C3DBF -:101BD000365C3F667B8F0DE308F27DDC7E52965AC1 -:101BE000FC4F213F85D6162F8F5BBF556E3DC1DF61 -:101BF000FDAA6533EE03BAF59E9E0968675B15CAB8 -:101C00003F57960ECEA7F3823FD03192EF30AF2AE6 -:101C1000287736EAE8BEFA87DD4BEF413C30C5E76E -:101C2000AB827E79E98A84E72F1E547C268C5F186C -:101C300085DDD6E7E1BFF7AA7E7787B02F77E4F39B -:101C40007BABBA971C287E0DFAF5B5AEEDC7EF99C0 -:101C5000279A18E699F5E59CE9C6F3A28FBB60C701 -:101C60000B78B034E8E8F75A1EAF8536A9E8CF30D4 -:101C700068FC15CF4AFDD43ED0A8A37D82A5C4A0A0 -:101C8000F16FA435E8BCE8773CE0F66F427EBBFA22 -:101C90006DE506FC9E6BBC6243FDF490EB17261DC0 -:101CA000C09952AE1DD7364B3B8EA35A5BEFACD5D5 -:101CB000D6672CD4D6BBBE6648F0D768CB29C847B8 -:101CC0008847900116D04349BC8A2559AED0EF858C -:101CD00075FB77F54C8036C6E440E96B006FD2A403 -:101CE00024DAEF6F7C3509171FC81F467267E314AB -:101CF0004679AFC772BFE9427D9A889FBE1C03CD6B -:101D0000D75208F82CC0FDFA59FA5D2F0B8B6B5790 -:101D100080F8F13E93CFF7EFCC5581FE394672F053 -:101D200059D57F7C0B3F4FD5D7CAFDD20F2DE27915 -:101D30008134830A5CDFBC7D0AFECED854F4DB77A5 -:101D4000DD8DF98E8978CDC4FC3239C61F1BD4F3E2 -:101D50002B787AB2828B655C7797DCFCFECD970599 -:101D6000DF1C14F72D44DB23FE3218DFCAC2786F64 -:101D7000E6ABFE077E1E609B1A8F1165BCC610CBBA -:101D8000078F3B6EC0F5B46DA1A30CD7D346619706 -:101D9000A5E618BC1301DE47DE3004A4ABA0ACB04E -:101DA000E37AD0E7071DFCBB86379302789EEA11E1 -:101DB00057399DCFFA389FFBF39EABF4FCBC96D607 -:101DC000A342E7DF1E717ACC65DCDEC0BBAE19A58D -:101DD00016816971B4B68CF6A98F783D665CAF8FB9 -:101DE000E478CC989F6CCE526CB88E1D2E85EED1C7 -:101DF0007AC4E4B7A1DDE2000588BF1F67C8ED998A -:101E000047E7920087BA0A1E1260228F0FF3E8D2CA -:101E100004BEFA5C77D9F0FCBAB3F0D0B7D0AF9E6D -:101E200086E3A5F07E8827BBC0D3A57C37CF4B16B1 -:101E3000E3A7DDF51CB5C7BFCE8AB8F13C9CBF0C4B -:101E4000F358907E074D7C5F1D273A3EF392DF7E6C -:101E5000C34F38DEDA73F9FD4186358CF661CF5514 -:101E6000FAF71F45FC6425D13E3BDB955D85FC916F -:101E7000FDC6CE05780E61C34FB8FE342CE7F1A63F -:101E80006C8599BE8CF34EF7DB108F89EB30EB78C5 -:101E90004F1D32DBFF054658D4C60080000000000D -:101EA0001F8B080000000000000BD57D0B7CD4C503 -:101EB000B5FFFCF6954DB249360F424248D8CD8B5E -:101EC000401E6CC24344D4E5114445BA913722FE0A -:101ED000420204482080F6A6D69AC50445C51A2AAF -:101EE0002A5AD48D02C58ABA5440ACE85D1E5AAA5B -:101EF00056D3AAB7542B4D842AC82B86F65EDA7ABD -:101F0000ED7FBE676692FD2D89D2DEDBCFE7FEE373 -:101F1000A71DE637AF33E79C3973E69C33B33B9399 -:101F2000D82D3E076349136DCC6567F4F777FEBF84 -:101F3000740B5B674E622C650AFF5E10F63D2D65E3 -:101F40007C7E0963A9D38DF5D35858DECDEB1DEE09 -:101F5000BC8DC53336A0DA58EF89D8A3A5CC845CF4 -:101F6000D877F3B7E79BB5F67B078F60CC9F6EF110 -:101F70006C75319619311E635F4721AF3193EBEFDA -:101F8000398C8D772532D60FDFEB5DBE62C676DAEF -:101F90009C131C298C75AE649EA779FBF12FAF9F13 -:101FA000FB36CFFF67A6C319C56B651C6E692BE2B4 -:101FB000DFD95E7D30EA6FB6E84FC5F2F2CD47FA61 -:101FC00033BFC658542CAB0F723CD94C4C47FA77F0 -:101FD000FC5D8D71AC34CE78179FD448C67817015C -:101FE00053DA3F9F06070E2C747AD09FBBCDCEFBF1 -:101FF0000D5A9C85169E1FF9D4A30F5A33310F0E2C -:10200000E3189AB6978D66ECB9437CDC013CE77F18 -:10201000E2C189165E1ED35DEE47F94E9349E4FD99 -:102020008107278E656CE0A1E01A8793B18AA7B675 -:102030003F68E7788BFE9528F7F1BCDF02BCD40E31 -:102040006AE7F33B90B594E6DFF4BB2816C5EB15C1 -:102050009B3D9B90671F47B3AD3CBF7DF7D8D92E02 -:102060005EAF296E944B2F626C9A4BA3F95720ED0B -:1020700077F1BCCC368FEE715CFCFD7A8937C63CBB -:10208000475A397D8B9FB1B1FB786101E006BD5A9B -:10209000A3034F83BE2D8F72A663ACDA29685EBDA1 -:1020A000E7BEACFD3C7D25AEA2CAC5DB57C74D4C93 -:1020B000053C191718D39339DD1AED4CE7B8CA4817 -:1020C000F999C6387C03530E8D630EF04DDB1A2749 -:1020D000D2FA18A687F165C6050BD387A33F2FF563 -:1020E000873F7B2AB850FC3527E96C0D87C7CF7135 -:1020F000BD15DCE98CE9D04AC0F813BDED6A7D64FA -:10210000834FD9EC6011B84EE0C1C6716A2DE3A9C6 -:10211000C3128AEAA5FE6DB29ED9EE089987F1D462 -:10212000F9E611EAD76139DD6EEFA9670F58081F8C -:10213000AC9605F234C2933F0AF98424CA33AFD770 -:1021400095920AFE6784DC0C0B3B14C5C725EEE5AF -:10215000EB279D85287D82A3C791834A99899FC5D6 -:10216000327C62E0E3A7199B1CCED72A350D3211D1 -:102170007CB90DA67EC7397E0A0F46131C96752CB6 -:1021800010CD07CB053D38DD72D7B380C58D7AB64B -:102190007EC793D1CE25F9C06962345E7028D6D54A -:1021A000A6371DEB5902D197E4CEA61856037CA999 -:1021B000F1185B43FC10907CB1B9D1497454E5032C -:1021C0006B0F44D031C94047552FE3C200A2674F7F -:1021D000BF01EA2FA36117F143C6852CC927AE6F53 -:1021E000E93FBB8FFED3A87DDFFD0FA4F19F087DE3 -:1021F000903895A3E2C79DBB127D3C8DB6B6F83CE6 -:10220000BDE039E356A39C1CB6D72877155EA2AD76 -:10221000DE940A8EFFE8DB4C9E56DEDF65478CF5C8 -:1022200026BB3F4CC47AECA91F4A9986FA75A2FED8 -:1022300015278CF57DE37647D417F05D7DC1582FC7 -:10224000923E91F072B8FACD08836B823DCAD07E7F -:1022500076E54570F59B1506D73569C6FAFA9ADE1C -:10226000E1BABE20EA1BE152F5BE33FAD2EA45CE0E -:1022700063DAE4A83EF02EEACF9A7D69FDDE54F3DE -:10228000CDF56E69881CC72FF72BBEB6F83A4EC63F -:102290003FF812486E3079A3F93EEA649D0CEBA832 -:1022A0004BAEAB24E6A4F5CC17BE8675F53EFE9981 -:1022B000CED810B7EF2BC8AF0976EFBC8779D58998 -:1022C00072BF6253788F97A3735FF18DC517F31FA9 -:1022D0006377115CAF6ABACE689FB57BB6F2F55DE5 -:1022E00098C1ECE95C0F606981EC1BE3188B752BDE -:1022F00079CD450D8773A8C4DDF30382AB12699DC8 -:10230000079200CF3F3A6E7FB737C9DDAFA77E6433 -:10231000BD9EFA024F365B7025E0ECAC7378B03F9F -:102320007C8022DEEE9999512133C7D739AB639D6A -:10233000C6E5CC91D8F96FF6E378783F5E77A1FFD8 -:10234000D9B3AEBD1B79ED40B26B1587EF5C65FB71 -:1023500028E0D51BABE7BA391CB5767D502A9FE241 -:10236000994C7D7002F0EB4B26BCF27F14FB7A8512 -:102370005FC0335113F84F4ED08B31CE4453DB93B3 -:102380003E7CB3B48D423BE6EC47F09DB17179D70A -:10239000CBFA5778182FFBD96FF57CD5C9E7B77FF3 -:1023A0004382A789C35B9D3C6BFE0A5EB4D0E44BBD -:1023B0000D990D705F81F16A1D9583D201B755C2E9 -:1023C0006DEF27F1EECDFD26B89B301EF6B51F68E8 -:1023D00081AD6E414BE45FF62706EEE3F928D3F9B1 -:1023E0000F203F3A8B4D1EBE47B0CD5CBFB0F37D92 -:1023F000E53D89EF27B8FA634FA2EFEBF03D2D469C -:10240000B44F7BC41468E2ED7DE35F213A3DB3DC59 -:10241000E131F3B12A99CB06BEAD625E1BE0FFE36A -:10242000B8BFBDD6CEE737C7AD4FC73C6E4936659E -:102430007D4070E885159CDFD85881FF6FE307C6A3 -:10244000D69BD828C66E94FAC14289C769CC6BC5A1 -:102450003833986EC5B8BF396BF3422FFD0D7450F9 -:102460000EEF2CE6A7EF735880D29B5888EADFCC9A -:10247000DA29FFEBD892CC060E5FC5A383F3B01E1A -:10248000C3F0BE54F2CB2D29825F3EEF0FBC6FEC40 -:102490007749FC5BA109FC0D71EBABDDB45E5D29F6 -:1024A0001EC0E49C30D01717B67E26F613FC677169 -:1024B000E67DD3FA69EB8A2F61C3481E38D2391EF4 -:1024C000AE91A4BCC6BB6C0AE60B0982F5FA1DB935 -:1024D0005ECBCD0E96C2E9D2E63207A2382C93C766 -:1024E000AD4CC37C7FB186FD6A38A7DF2FC69959F2 -:1024F00013D5F452BBA9B2BFA903279D847EF20E67 -:102500000BA58CE0EDCA2FE88712387EA69A7734A7 -:10251000738D9B4D1E68FDB43D4CAE5D9BB2D3C226 -:10252000B8FE725DAEF1FB94229E0F93BB5399A54A -:10253000A79CD37F3FF003B9C35ACCE0DF47DD71DE -:1025400029D057D85036549C0F3835C2E6D365FF92 -:10255000DA768EB77BCBAD3F093E5A9578763EE969 -:102560001D16319FE5EF9A49AFFCB49181F3D87104 -:10257000AE1F7AF319FB8CEB17C89F684CA3F40BC2 -:10258000AE0F203DDD5840E5671B3D94FFD2EDFBCB -:1025900009E8B460DD9716EC4BF7442B7C0B3856FA -:1025A0004BBEBB2773D4A37FE578BDE71DBE303893 -:1025B0003C35C19649007B75E6A777417F5EFDAC4F -:1025C000E641BD65FBBC36078767E121FD6E90796A -:1025D000F13BED532126EAA0BF72BDE15EAB6F3740 -:1025E000C61BF9E1F1549D57F0EEEB783399D7FF14 -:1025F000BC7134C175B2D14B709D6A9C4C694CB6AC -:10260000EF55D4F7B22F6DA87FC38E0E4B06AF5F88 -:10261000EED5BC588F57795920C0E1D96415F27DA9 -:102620001397EF589FE38A6F7CE25606F9ABBF81A0 -:10263000F63392AACA93F9F7A9A32B2DA837EB2B4F -:102640002ED3DC3D7CF8EDEB50E0A34ED2E5CCEB95 -:102650001AE1E9CC9EC2EF5CC1FB7BFDB0999939D0 -:102660005C5D174C0457D79198009456556FD56E02 -:1026700033E993AB326D01E06FD5EEC2FED0A74EC9 -:1026800071BAB1FC9EF14E3DFF6F2E3D4C8E9E4ABD -:102690000AFEE74790539F0839C5F5CDCF1E871C2A -:1026A0001B38C003BA9FB572BD1C8866F5B1D8C788 -:1026B00096DBE4FAE27206F95331E21C3CEA858CBF -:1026C000F1582F18CF65EB9143F92F3C9AFD7D57B8 -:1026D000CF78DB830B3F7A9CE7CF044C7E2BDF6700 -:1026E000CEB0E0D99F438E6E7178703EB847E3F06C -:1026F000601FDD3A80F2059A25A681F83940EBB5D6 -:102700004073591AB8FCA9FDD96303C04FAF721CBE -:102710008CE6E5AF6E8825F9F4AAD573B401FD3DCA -:1027200021FAFBC90FBFF7E95EA40FD4957D0F48CE -:10273000CE4E227C57FF68C950B4E7FB344BE7FD0F -:102740003DF7B2168AE6EBB378E3FEBBD2397CC321 -:1027500036779806F0B4748BD684B430F3BAC36677 -:102760005E6ECF76111CC377B8CD19585603021F81 -:102770005D4DFBB7715F2FDAF8E5781C2FD5FE3E73 -:10278000540B7ED18AF370D691329DF0D742FDEC86 -:10279000DE37EDFD9B18E6C13507C05D69F3D07EDD -:1027A00012F0B782CE67F402CF7D58D33EFF63A00C -:1027B000EF193DD583FD658FC91F3F06F58F5A6818 -:1027C0009E2F6FF975BC95E713765959342FAF2BAF -:1027D000ED9C84FA75992E3A87673E79CD64E0675F -:1027E000F9AEDDADD44FADDDA3619DED3EFF6606D4 -:1027F000CE43D7324F1EF86E97C8DF3FD1EB01BFF3 -:10280000D5B4FE59E4DB7C94F799FD6E0BEA5709C9 -:102810003DE751B98FB1F6129277C4CAAE1E7ADD88 -:10282000CF8B51BEC9ED4FAF77F4EC7F7CDF2ACC64 -:10283000E6E5E936D9DE392DCBF70FEC5B36B90F7B -:10284000A9FE1EB5317F34EF27937FD7B0AFDAC42E -:102850007EBB95CB17F08BDA6FF9B857648BF65EB9 -:10286000C8C90CBEB996F2F9643C1A15A03DFD1218 -:10287000C7577AD28A1821CF94FE313BB9E9B57691 -:102880008ED73FC5EBD7607E0BE57ECD2C9E34CC3A -:10289000EF58BC7732C6AFB57766610E7C3F9C823D -:1028A000FC7233D79F72C2F427FBA5ED875109DE76 -:1028B0001BD1FE52EB8F8DE95DFE8EED1A4DF2F7C6 -:1028C00035297F57FFD9C44A797EF5C351244F6813 -:1028D0004FEB052FAFF1F5AE73F9F2EFB01BF0F44B -:1028E000CA3FB59BE9FC71C854FB26DF4F69E86C11 -:1028F000FC5F6753C208CA7B41E6ABFE64EAF57C25 -:10290000A8524EA77ACCCBFB95D1DE70F5574E1B63 -:10291000F5EF48BAA4F99AFB98AF395ECC771FE679 -:10292000CB69B7FACB329297FB2E719E9951DE3567 -:10293000A06FE43C38DCF7E07B24DCDDFCDD79696A -:1029400070DFA631BF09EBEC4B5B00EB6C1F07138C -:10295000EB76DF92A200D6F31E9BC8FBE36DA47F4B -:10296000EE8B637EC88F7D15A901BF1B729009FD98 -:10297000B41F13E5D1B2FD9C546A3F208AF33FCFC8 -:10298000B39B6264FFF56F17A37C4D868743C0F548 -:10299000DBC0BA6CD26FCD64373C22E5F5C6C4D03B -:1029A0004D66FE7DE397F90CE31C61A18C15A857D9 -:1029B0001343726863A2373D89E371CFD766DA1794 -:1029C0003696F2BC83E434D977365678D313797EC1 -:1029D000AEA4CBC6D6C0D647D05F4581C7CFC719F6 -:1029E0006066F554CF2DFAF9C82ADAFD4ED285AFCC -:1029F000635AE7EF672F0801CFFAD4580BEC221C7B -:102A0000E3E91A87FFF1EA3C46F252DABD664B1A57 -:102A1000CCEDE103AF7D14F45AF13767E1D668C815 -:102A2000E31935D164973A5273579C8B8F374337EC -:102A300087A2A0FF4D2F37D89DDECFF6D2B8FC601D -:102A400021CF09A12AE0F1F54E3B835CEE8B9E7508 -:102A5000C171C9C7C3F8A1C626E4C709A90FBD1231 -:102A6000A7BF0B7E5FB1F7DAE4E361FA5EF5C2F26D -:102A70007CB2FB565FDAF9AE09741A46EBD56F02E9 -:102A80007F04A389FE936FB413BDBB1CA6A76197F7 -:102A9000BC45CAAB261C84F9F7A6DD5181BBF8B74B -:102AA0001551A19990579CFECF6E035D5F8B26FA5E -:102AB000D7DA043FD5FEBC90F86B8FCDEB5E8BFE72 -:102AC0005F8F22BAD7C6BB12A8FCAD6426F98FF47B -:102AD00086DA98507E22C7E7BA58FD24F0C6F98EF0 -:102AE000ECC1B536F1FDA8E4ABA3BC0FC0E1AF8FDC -:102AF000237E6432AF7F3F99CE535C1F25FED51FE6 -:102B00002CA4BC6EF3A62FC4FA58154BF01D95F6F5 -:102B1000B4A3B589C4DFF31E5CF60EE3F43CEADB34 -:102B2000766F3EAF77749FD5837DE9F70DE6908D84 -:102B3000D3F5EC1DC7466DE2F9F6BB3ECED2C3EC31 -:102B400068F3EEAA9B8276F396DE3115FB655FF89B -:102B50009E571BC5656E0F9D5272BCE61C8E7F4F43 -:102B60008E6ECBE1F35C51D4BE0872EFACADED4993 -:102B70009C0F3E4AD0A3F1FDDC2B9F6F237968E9BF -:102B8000CC877EBEDCC2F9007C29F7CF15922F5F7F -:102B9000CCD113509FE38FF4F1D8A23621F7EEB8D1 -:102BA0003439FFC5BEAD7B343ECEB2987DCB2935DE -:102BB000074AD0CF292D14AFE5007F5C8FE3FD9D40 -:102BC0007686E241075D9E9B966D37CE0B7FB0AB5C -:102BD0002CC33F78BB654133D955F8FE6E03FCCB5F -:102BE00060E935F813845CE1FD3C4DEBD0F1FBF975 -:102BF000DFE7F85FFAEC9032E893CB12F7FEF00AC9 -:102C0000AAC7DB293E375F9C57F3B9181E31BFD3E3 -:102C100092CF4F33290767DBBACFE1D083CE3EDFB7 -:102C2000DFC037679F1D42F92FB44E2D86C37556FE -:102C3000CA23E6098EAAC001C21B1C057DF611F944 -:102C40007D59727014E48F9247CC1E2CA17375418C -:102C5000B004E74925CF982F984FDF03C17CB4DF3C -:102C60006312760AFAC3BC9FCB68253CD8C57A5C50 -:102C7000FA5C21E1458D1349BFC8F94ECD11FE0123 -:102C80000EEF2D3E5E7FF0269BA17C48C0989F29C9 -:102C9000EB0F8AA0CB0073E7FE28C8FB6718ADD7FF -:102CA000C8716FCE11F6F49FFEB49B0E66795E6418 -:102CB0002E457F97D0B7ADC0F7EFBAF17D6B069781 -:102CC000A7CB30C7EC9EF9EF29D53320F7CF9A84F4 -:102CD0009D7A4F22CF1741CF11F8547985C7483ECE -:102CE000BAEB778B32E04F5997D3EDE7E80F7E6B65 -:102CF00082BCE4F2A2C92AF0F14563CDF0E3169C50 -:102D000047EBD3AB2D3DF359B4A9D48EF5B278730C -:102D1000A97D41D879A769FBF0C32E4E97D3DB2D4F -:102D2000643668B2047E083DBA69BB39E867546E00 -:102D3000F7F2FAA71D07DE45BD459B13CBA0F7AA06 -:102D4000F68B37DD965E1D86EFC2ED46FC17078DCC -:102D500079D8A3C3F33F822E38F21F6F571A32E699 -:102D6000871F36E63FFFE0D69960E397470B7E3F2B -:102D700011880BC04F55F3F1A4C3D8D74EEC793965 -:102D80001EF459F649F59B38B72CDE64E4334E3710 -:102D90000D7ABD7F9B46FCB12410B9EEE47ABF6882 -:102DA0003DAE5176CD82703E89A4E729169CE9E5B7 -:102DB000FC54DBB06A38FC21355338E372782E0FAF -:102DC0006EB0C16F10395E5FEB9E39BC2ED8AB2A56 -:102DD000478BB2310DE3D931187DD7FF7A12D65B1C -:102DE000E5FD1AEDFF952F0D3E04F9DDB173CE75AB -:102DF00094CE9C4C7850F6B3C5FBB4501CCF3B47E7 -:102E0000BBF6B6F3760B031AED0F0B9AA37AE41018 -:102E1000FF5FF5FA083836869573F817EFDDFF1770 -:102E20008DF75FB3D9D86E09C717E4FED22D7F8F17 -:102E30000AFFAECE7D63F6B59A31EF850A7EFF5567 -:102E40000CF3122E482E3AA4BE721C192EEFA39238 -:102E50007C6DD85FC66C14EDB8C0AAC47CEB1C3680 -:102E600017E65B6767A1580EC7E1389BD7C9BF9FBC -:102E7000DF1447F6A945515C2F2CA3944597A19DDB -:102E800087F6E9CFDE3393BE5287B1D1CF531A9D77 -:102E90007FEA606C44FE19915FC242340FF08B37B9 -:102EA0007C7E01639EB5887353AD25B41FF858CA64 -:102EB000DAC5B987D3D11BE68FABE5F33C92047D2D -:102EC000C8D87E050B52FD157BFF1E15FE3DCC4E6E -:102ED0004AE73975AE34DB9817FAB1F9CE18DAEF54 -:102EE000B9208E017FAED5BC8FD9CD48C5BCFC1BA7 -:102EF00084FE33B755EC175C3FCD077E366E18E283 -:102F0000819E3297EBD9D1D02396C450BD8D898C48 -:102F1000EC2B1BE7E40B3DFBEB974218A7F3618D0D -:102F2000EC231B4B45BF1B1F1842E590871A8D13DE -:102F3000457ACBC60A559E497AD247002D1D7AAEF6 -:102F4000FCDECF45DF0798BDF9D0D7D943D174DE79 -:102F5000577AED33497A7C6EBF9EF92A3D98D55C4D -:102F60009AFEB755EE779D1B84FFF7B8E67BD31426 -:102F7000A6970ECA15FBC3A8F1DE6DB21EF901AA11 -:102F80004D15F75DCDE1A97EC4E46A72F7E09D7945 -:102F9000BDF998FFF10DD165E0B351E385BDE76858 -:102FA000A990DBB1239837C0D3825CB17F14E49A37 -:102FB0000C695A0CE73FDECFF172611F8E1BE123D3 -:102FC0003B1BD7D9487E47CE638484AFDAE67BEBE0 -:102FD000CA5EE0E9E6838942CF38BE527B5AC0C55B -:102FE000E9CAF3A37E144DF6B9E3725F51F8E77CAA -:102FF0003392F66929AF36483ED900FA633F5B2227 -:10300000CE413D7C62E483B99AC02B7B40E8A71B8C -:1030100013455EF1013FEFB0BF824FCA19E1BDAF6A -:10302000738F9AE7C65651CEE93D05F48E3CF728DA -:103030007A334B6024CE8D7DD17BC1E8C4519A890F -:10304000FCD67EF8ADB1D7115EEEB504EEE2700CA1 -:10305000B408FC675A047F71A9EC8F29A3FA5E1BA0 -:10306000CF573EB4987979FDCA0C46F6205E9F256D -:10307000A03EEF06712CD82BD0AE3241F45BD99F25 -:10308000D13981FEB8BCCA459A4DFD7A4D49A27D21 -:103090007C19B5F79B447BAF85A78372843EDFB96B -:1030A000362AF034E4F33D99F9E08329E38D7CF08E -:1030B000EFB962BF57E9D03C97342A79D2B0BE1736 -:1030C000340FA1FDA229DA57B71B747B5EE8FF9588 -:1030D00077DF7CC348C0F742B207E07D317527F93E -:1030E0001B1634CFB9ED439C1BB647D3F76BF2F4F4 -:1030F000DB7347420F74CDDFCD3F2C9871D096C65D -:10310000DBEBC18A333FE7E954FFCE77A10F4C9D3B -:103110006EA6FA5399B08FB26631CE0DFE2F2D698F -:10312000BCBF1BC66A1433D011EDCC5AC9E1AF94B1 -:10313000F4BB5BF26F53349BFD3307E0CACCCFE6A0 -:10314000DF6F8086D98BFFEA90AA3F4EDB0CBD660D -:10315000D004B1BE547DF4837EDF92EB6983C48BCF -:10316000CA73BC52FDEA75511D39F148ADA1C13C8D -:10317000EDCC1FFF30F86A4A369BB40978FF9E19E0 -:10318000B10A1CDECE4A5AF771F92EF0A9CE588842 -:10319000E223024388AF3BC67576DCC3F31DAD83E3 -:1031A0003D64F391E7E885385FB9502EE498922F9B -:1031B000479DED71C4AFF25C5D2559E38F0D131E81 -:1031C000B98CD7AF72D83AB01F2C7C785A3CE24CFD -:1031D000AA369A453CC77AE3B99A9F7F5F045D227D -:1031E000CFC991E761F00CF8A87ABD467C38A8C930 -:1031F000634B2739A63931BF6A472817F2BDDA1366 -:10320000ED41F9E9466FF2F15CF8232653CABEE2BC -:10321000781F057B2CA3208E0379FA3EE0A9B2A586 -:1032200092CE8BB1453AC9A7BFE5BA08CF53604FDC -:1032300084BCB1B4A7631DD6A9EF49CE7C07F17356 -:1032400034031E3AACCE7CC0D5B136DA847D73CA65 -:103250005D82AFF93AB35B78FB7B2D2C06EBFD3E2C -:10326000D97EDE1A8BAF95E707DA99252E097C55B2 -:103270004A7C5D3658DF003C9CF8011B8DFDBF6A1F -:10328000FD068247F105B3B44D4C867EB7D55D7619 -:103290001FEBE1A3B2C1E3DF47BB6E7E98AE111F07 -:1032A000F0747F0EF1C38D47503E657C2877551131 -:1032B000FC58B5CC0B3F421AF3C01ED0C53A499F0B -:1032C000E8E2FA04E49992274A6E703EF022AE4793 -:1032D000D157C98F6D8D1C248ED7ED8D764A7FDA3C -:1032E000E864162E037634A651FE854617A5C1C69E -:1032F00002FAFEB3460FE577358EA6FC9E462FE513 -:10330000F7364EA6F4E78D3EFACEF1427248C91563 -:10331000258F143F29B914C947F3397AAF2AA3F688 -:1033200024F794BCC33C4C653DF248D1375BF3F9BC -:10333000D3DC9063ED73202FCACDA79F7F197692BF -:103340001A8727CA05BC08B9D7E5B0939CCFB2B19C -:10335000BD38AF37ADF476DC13B6AFDE54A3314BD6 -:10336000189FDE5C1FCD2C617C7C4B43A2213FAFBC -:10337000E1FD37FAF3FEB544DD91C7E1387AE7673E -:103380004FFC967F7FEACE2FF2406F0EC7D64731B3 -:10339000EE1D31DD702421DF6C25FD61508C380776 -:1033A000E10F7459C0C4FA7CEACEBFD2FAEE688845 -:1033B000729979BD050D5184AF8F40278ED7DF4BB1 -:1033C0003A55AE3DF6FCCB58E777D848CE2D6896F7 -:1033D000EB721DC76798BEF6693A23BD4CF33206FF -:1033E0003FCCA73FB085F89ECF3ED5EC010DBA0F7C -:1033F0003F24CDE3DFF575BFA0F82BADE130E9C385 -:103400003AE2B26027F05B0DF1585A838CD36A1F01 -:103410006888A38A1DE1B5413E80A741B70505072D -:1034200018D6356BD19CD802AAE5F7EA751AE91BC4 -:10343000DDFA429E99E8589F6BA1F45DAC71DA2FDA -:103440005A687F52FCCAE585378075D1526A5B1491 -:10345000268717C8EF5505264AD5F7FA5C1BF5F302 -:103460002E8403EFF7BE826CDB4292732E1BE48046 -:10347000AABFA0A0ECEEEC11E8675C0A0B5B8FDE44 -:103480003C0BB5AF47A017CE477661FFAFED631F8A -:10349000507AC909FCF372829FCE5B4B5F78EE05D0 -:1034A000F8C7967E1C45745A3A4CDA238A02A3A6C2 -:1034B000913EE375687C9ECB25FD273EF7497C3B1A -:1034C0002F5FB14BD82F79DA8174F91D3564D75A43 -:1034D000EEE1EB230972D5E8473EF4C2C7F1ED7483 -:1034E000AEF06720BE906F0B192C0DFEA2639360A7 -:1034F000175FC13AEF465C5764BB15DA57F1C2BE9D -:103500002FFCE4CA7F59FEDA9F53098EDDE7532171 -:10351000D756BCB63655EF65DE2B22FCD7CA6FAE48 -:10352000EC602BD8FA2FE1778BACB72A4FFAB52F86 -:103530006397919DC2C2288E61955DE0A12B909703 -:10354000C07A19AF7BDC4D5CB0F3736897C595E02A -:10355000E1709EEB238EEFE53CB13F9F917ED473EB -:103560003BCCA4179EDB1147FCBF7CC7436F5EC1F9 -:10357000F3CBB7681896D5B136C2D3F25D66660F45 -:103580003FDFC06E93DC379CCB9E8BAB073F2D0992 -:103590006ADEAD45F0CBBB12FA85EB8B929F964568 -:1035A0000547111D24FCF749FD48D55BB2EF211BEF -:1035B000E8C5EB9D25BDE5C558E8DAFCAFF35DC075 -:1035C000796AF370F2EB2E09EE5C4EFBFE8E582703 -:1035D000A6F885D5688F0AE489F514C813FAC629B8 -:1035E00069FF3DF58299E40FE0C43AFC4213765E30 -:1035F000D56E9B6CB74DE2ED863CB11E55FD25C1E5 -:103600008EF85C5EFFF3BDEF531A94F35AE2682B19 -:10361000C17EF9F9AED8C9014A7F3CE9553EDE9931 -:10362000E0B8142D6C5DBD9627E286CF6C364F0650 -:10363000BE5840C51905693EA776646874AE05BEDC -:10364000397E4EED7A29DE44EBD62FDA493A9AECF0 -:10365000C29EEAB6B8A4FDC2EE849E31976B75098E -:103660005CDED5ED12F10091DF557D5A6FE9E0F790 -:103670004E9BE07FE9BF97FE25C489903F3ECE1662 -:10368000C0FE3A7F986BD64D90676F5B053D06BADA -:103690001EC5B96AFE7BC964AF586575F547FE4F14 -:1036A000EF58C97E3E7FB85CE769ED23619FEC70FF -:1036B0008B7DBD761D5F217CCA0338FDFD7C7EB508 -:1036C0000113C5531ECBCB26B81EAF31796DE4E78D -:1036D00008E5C34E79D4C6FC66E8C93F8B26FDAE2B -:1036E000365BD8DD1F07BFF3B43629949F0C7B9758 -:1036F000A463ED8DBC3C8C9EB54F87F2A1B79CB600 -:10370000093B1ECA9D48CB44BD26C937E807FD7654 -:10371000B89D6749BFDC1DC7A0E79B5E8E13F6848A -:103720009F4493DF41F57B5EF25593F473F9B70A3A -:10373000F80017F4E625B6967CE8956ADC25F12DAD -:1037400034DE6939DE929816E13F907161A84FE34B -:103750005B9917E7F1CE67A3483FFD22BD6D0FC609 -:10376000FFE2D921E407EF700716EDA572AEB7713D -:103770003A2CFD695408F09E7C368EFC9C27AD42A5 -:103780000F3A19974A7AD0E1B847E6A3BFAE2D5158 -:103790001AEC292735664B43F9D67EE4AF5ADAD8BE -:1037A000407E82A57CB9C31FCDD3C9F02B9FDC3AE4 -:1037B00084EC2C277F6926FF22FFBE0EDF75D632F0 -:1037C000FF76ACBBEDB16467FBE2A77F1B12EE7F17 -:1037D00050E9D22D467B92A2BF2A4FC917EB2B2569 -:1037E0005FE0312D5FEC3375B1C147B2699E62BDB8 -:1037F000723AD0798BAF8F54D8A78F065F49D51C0A -:10380000C07328FFC7C0FB7671AEF9628795FC22B2 -:103810004B5F8EF392FDE69ECB4CD82F969A85FE99 -:10382000BB94B39B48857D68697C3ED98738BEE9E7 -:10383000FCD8B9D52CC711E39EDC9629ECEF219971 -:10384000DF531C009F4F4962B7DC48FACDE612E017 -:10385000F5FC965813F8828FE385DF7EE9EDDF17DC -:10386000F84C5844FA38431CF428F8CB85BCACBB60 -:10387000E78A04C4C3B0F7CC0CA2EFBCC5D31FF2D7 -:1038800030125F8BF3A5BCDCF3840DFEB35ABE5E31 -:10389000101FB44CFA4D97FD54237D6ED9DD573C73 -:1038A0004A72F05D2BCBE3709C0E3E141F4E8F0AC4 -:1038B000D94F4F7B0FD55FC6EB8BF66FC7133CDB41 -:1038C000AC1EC01349C74B6EFF53F325B5EFE68F0F -:1038D00020DFD74B2E9EF779D6F6DD8F2147764431 -:1038E0007BFCF435487EE753D6E022CCFBD4F3D101 -:1038F000245F4E258AF5FE3997877E1BE0B8FE418E -:10390000B26FFC661A83E85E1C30F6ABC69D992F39 -:10391000E46F5DB22701FE8C3A4E07F4C7E9F21D51 -:103920006AFF9E95DA47CE63A46CD7BD3E9F8F2574 -:103930007E393540D0E3D40B83695FE948147CCEEF -:10394000E1CDC239E554A2487153067CB0549E4380 -:103950004F8D0BD2B9FB94B693D20EAB68B7B4417E -:10396000FA6D39DFA5816FC093F05BD9D7B7418F6E -:10397000807D7A5419A5A1A8A48BEDCCE04FEC432F -:103980002FE40B7B16D41AC875F26F907E12B441E7 -:103990001EEB528FABDD71B1BF8CFCA03B34F2FB50 -:1039A0003C20D729A04E51F671CE8FCBFC9A17F14F -:1039B00046CB9A572E01BF2FABDF7013F85DCD6356 -:1039C00099854DC6F9AA4333133C1DD17CDD000F08 -:1039D000E1E365F7E07793821720A7929E49CAF545 -:1039E000E67CB15F21DFC2FBAB6DD6D6D3386E75F6 -:1039F0009E14F35378E268B1C14EC6CFF9A2BC8FD2 -:103A0000F92B3823E7AFE009E60BFB4487DBF5E051 -:103A100058D0FB5766B29F9EFF6A7842D237E8655E -:103A200038B175DB8B39FCAFF1BD1AFDF821DFB081 -:103A30009E618FE670E66F36FA3F0AB618F3437759 -:103A400018F345BB8CF9927DC6BCE79031BF558E0B -:103A5000ABF084732EE2DA70CE458A73AE2B5F9C96 -:103A60007391C7391729CEB9F88E732EF238E72231 -:103A70008F732EF238E722C53917DFCF4AF95D2B55 -:103A8000ED8EA003C557BD12ADFCE0B45ECECD49AE -:103A900025F9A9FC99E7961451BEDB9E5361277B5B -:103AA0008E8AD3B929413F924F7EC3B6BBD34137EB -:103AB0004B3BD97157FC5CD8716BCBA21DB02FB4B6 -:103AC000AFFDFC6EA84F2509FA27F914D7D4B94DDC -:103AD000C42B85486EB4AF71BD77B5A01FD93954DA -:103AE000DC4D25F6BBA4BEE918E94761EB8D7E935A -:103AF000483F4AA4FF24920F94DFE4296B673AE41D -:103B0000FDB167EDEB01FF31691F63B39DA47F2910 -:103B1000BDBA5BFF7A407B1AFBF6D7F949D4BEEBFE -:103B200030D7B77BD96F555A75A18CF4C6EEFC7AA5 -:103B3000CD44712369F1B40FAD963065699D1DF7D1 -:103B400040DEC599681F3FEF30D1B9E0FC0766D26F -:103B50002306433F0F9BCF90408C81BF0AB7274578 -:103B6000F8FF0618EA0FDB9B1DE1FF1B6AF44B4DC3 -:103B70005FB31FE7EB69EB871BEA55FBAE88C0A379 -:103B8000845BEAA54D776CCA82FC591DD745F0AF1E -:103B9000DE1D4D71B5D51C5E2FFC72C87014D4D8D3 -:103BA000BD5381BF9AA03511FB7C95DC7F58837192 -:103BB0003FAEB130BF33A987EF6A9CCC9BC8DB9F77 -:103BC000296DD966E2743B63DAFCC85817FC4AAD2C -:103BD000594ECE57B76AC1D4CB797F7FB3E84583BE -:103BE00039BF6559433F9C0779B93387ADE1F58EFD -:103BF000AD7F299EF46EC9675956670CE8DDDA621D -:103C0000A67301EC52E6A41E7E686D498EC975F458 -:103C1000CCB387FE5FD1FC385D3CB8A7D8E538301F -:103C20007035F4B8A0986FCD38CD4F7AB29CCF2ABA -:103C3000B9AFB05CD1CFAD327F5C9E17D4FC4E0FD4 -:103C4000D95FE2821FB3716F961972DCB4631BEE09 -:103C50000FDC19A35F337824E225F37E3B968FBBFC -:103C6000F44311AFFBC78D13E22F87FEF9BCD533A8 -:103C700085E7EF6979C68673F1524BC0867367CDCD -:103C8000B3AD362F4FAFD9DE4ADF176DAFA4F3F6D1 -:103C900062564FE7C8132AFE56E2A366BCB6D9C9DE -:103CA000E17E61B0901B3531226EA3DC3CF60DC481 -:103CB000A59FDFAE9562BED37D3B6D95B03FCB7ABD -:103CC00091EBA3EB9D69E5FD604F0A0ABF675FEBCF -:103CD0006146A880D6C3B40B2E4AA75F184AE7D81E -:103CE0000F99AF98E44451C479F61D1187DCB54FA4 -:103CF000AC831A5B28651AD6C9EB565A27755C7EC9 -:103D00008D2EC33999B1313CF58D351BF875C5C47D -:103D100058033FCF6649063FF24C5CDA0CCB4F9F0D -:103D20009263A83F6B7A6104FF97F594931C196323 -:103D30008833A9BBC3EFD2289E65BCF13B4FEF206F -:103D40003EBBCED0BE8EDDD8530FE7E02DBF263C64 -:103D500033D666C379ABC624E26A66EB1DF27B3BC1 -:103D60007DE71331ACC341399EDF8A7DD14A767934 -:103D700065979E8D7FE7F4B62F7242CB71111F0AB3 -:103D8000FB8221BE900340E74F26E85027ED3D75AA -:103D900005C2DE53E76FB321FE96E3DF92C151B255 -:103DA000BC45237B1EAF6FCF4812F93BF07D97F1E6 -:103DB000BE01FABB80F2C3E64AAC97C8F2E57CDEEE -:103DC000D03396C34E033B93EA5FF6ABF873F1260C -:103DD000A3DD6839EC396174FC72B08BF874E9F6D4 -:103DE0009D6F0EE07899E64B2CC5FAA90D56582B1D -:103DF0008B2EE63325DFCFD798C8CFDDF5CE41E255 -:103E0000B3AE1A0BF1F3B7E163B957D83323F96FA7 -:103E1000119F0FFCB28B76699E8026EA012F03C0AA -:103E2000971178C9E8055F0A4FDD788B285F8C7F92 -:103E30008C40DC801608B97BC38BC4A3EA3F024FD9 -:103E40006CB4110F8B74D77B90378B0E9B59E0129B -:103E5000E6BD18F3C3F87C7E18FFC60BC24EA2FC69 -:103E600006332F5828DFCD273E113F3D7D8A715DF7 -:103E700076F38D4FAC93191752A9DDFF36FF7C1BEB -:103E8000DF28B823E393D5FD9EFF1A2CED8423D9B8 -:103E9000485AFF971837ACF67B85E741778EA678AE -:103EA000A22E4736E90FDDFB8DD358BE2A2E9BE2AA -:103EB0008875699F53725797F5D43895BCDC351CCB -:103EC0007C3C301576D7BB9B73B2DAC3F4127DAD60 -:103ED00095ECA6596B9229AD8C76A662BFA85C635F -:103EE000F6611FFCF4DEFEA9A361875F6B4D99C2EA -:103EF000BBFEF47B23B25831F2E5941EDB10353B58 -:103F0000DC9EAD525781D80FEAEE3C42FBD719D365 -:103F10003BF1B3B1CED6EE8E4748CDB2B5EF8F723E -:103F200072D5A3D5A20F2A401CA1D6BACD09BC399F -:103F30005B4B608F1E06DAF5EBD11396AE2DEF0FBB -:103F4000FB57EDD7079FC4FEAEAFB1A642CF3CF9F9 -:103F500001DFFF34DABF483F3881F8E314F8AD627F -:103F6000E97EDB098D79E1BF5962DE5FE234ECA7BF -:103F7000FB66028E5762F46105E4A70D6C4BC3F833 -:103F80001E3FC54BEA6BF2127AB397A874C526A1FF -:103F9000BF6D53F65A69D785DE8E3CF4763885A01E -:103FA000B7230FBD1D29F4767CAF90F6FA414D9DE5 -:103FB000A53877FAC7B3827ADA5F1D05D0CB576B85 -:103FC000311EC89BD59AA73FEC606C4BBAD85723DB -:103FD000E8ABD22B3BB96E15C6EF575FB0B3F0F824 -:103FE000B1712CD1909F604F37D42F77BA0DE5D7A0 -:103FF000A40D31945FEB2A35E4AF2FB8DC50FF06F7 -:10400000CF3843FE3BA3AF35D4AFF05618F2D326DA -:10401000CF31D49FE1AB3494CF9ABDC4503E475FBB -:1040200069C8DF54F33D43FD9BEBD718CABDCC698B -:10403000C1FEB60FE7298EF7D7719EE2E9EA5FE588 -:1040400039C2E93A7682A9BE377BFC7725FF6E1A22 -:10405000E25D09FECC94F74032E57D8EE60217F171 -:104060006706EEEDD379B62D1D7C13592FB27C6C0B -:10407000EC81F32E4EC33F6C9F39DDC2E5C3D8CB34 -:104080000E0CCFE1F9A421F74FB770B932F68A03CD -:104090002F65F3FC80216F88F26107CEA3FCFE211F -:1040A0000F8AFC3446AA45F690F1D3FD7C1E63AF1F -:1040B000CE5EEF11F6905EE32D550A3C206E11782E -:1040C000401AE2FC89F400E74FA487387F56E732B4 -:1040D000F626E74FA487F9B912DFDFE2E74AA4EF3B -:1040E000F07325D277F9B912691B3F5722FD4DE3D2 -:1040F0006C4A3F68D4A9DD7F34D6507AA4B19EBE05 -:104100007FD4D840E9EF1BFDF43D50A0EC0721B26D -:10411000B3287FD272F8F16087DB6B3D1DEE6755E7 -:10412000FE40E5FF6BAA67EDB158A7ED96C4CFEC52 -:104130003D7EBDBEE5AC857D16A66FB5C67A9F2BCC -:10414000203BC94027C96BF97DBC362DB38CA77FB6 -:1041500071E93B41EF1965556B13DCB807526F05E8 -:10416000BF7C68EAFD5E707381B03FAC1AE2DD434C -:104170007C22FDD8CA8FDC1D9F12E6E73685C5C5B7 -:10418000D05F587C8BF237AB789AABEC223E4FF97C -:104190009355DC8CEAAFFC02237977E53A0BE927EB -:1041A00071161642FF2A3EE64A7BB014F10257D63A -:1041B0003A280EAD3FFF6E2BA37A5E334FB7FC99C2 -:1041C000D72FE9F15FF797F0F37282BFFC824E764A -:1041D000D72BA5FF1EEDEDA2DC8FF6889D829EC138 -:1041E00053B2AB3D8138A7B21E7F3AEAC78AFA21A3 -:1041F000F497FB9F7CBCF89EF59399142C453C5595 -:10420000E67207C5536D1E17A2FB5B2BDCFAA7A055 -:10421000932FCAF9492CAD9F9C4CD8092AA4DEFBE8 -:104220000D74F81CED147E149E155D147EC3E28E91 -:1042300008AF7DD129923E917451F428BFD0836795 -:10424000E0E9623AF4D009F6D8FF2B74186109D27C -:10425000FDBFA85ABB07707D1B5D6EE96493709F1C -:104260007870B6DE0C3C575E70BD897C151B370933 -:104270005B932AF77C4BF92C94F7EBBBFCB63ECA58 -:10428000DF8E56F1085E4729A7CB04293F56970BCE -:10429000FC4E769B09BF138A16933ECA1C42AF732D -:1042A000F1FF204F267DE56B467F93528CFAA1F2F9 -:1042B000075F27FB9B1CE107BE4EEA8DD745E885CB -:1042C000A38648BDCFCDDCE2DC27EEB94F94FB746A -:1042D00086A4730E3FCC8F051D996E81D03A847BE6 -:1042E000EE25B807EEA7FCB52C40E9F52C44FBD62B -:1042F0000D5CC021FF1DC6289EF160ECD4792B789F -:104300007F13864FC8C5F7B07B7DD70CE947F7FA16 -:10431000FEE00CBBD77760A28BF48603F61CD26359 -:10432000B00EAC6176B45F72B98F5086837C5F400B -:10433000FA06DF17723993FF82EF0BC85F57B0861A -:10434000A1DD249731DE44B5BFDE399E5986F72DB5 -:1043500077AF2F796520EC2B6F270E9E08BBF3DB20 -:1043600089974DC47CDF4EEC6F1269948DD2E29731 -:10437000737BD3B3141FF68C378959922FC6AFC203 -:1043800067241E157EFF097CAEEC0D9FCDC001ECAD -:104390007AF6F7E3D3B2E1FF12EBBFEEE5E2FE807F -:1043A000FF2440435CB25DE025D2BEF379231B08B5 -:1043B000FCB22D09F4FD36C94357368CA1FA5735A6 -:1043C0008CA6F95D11A3DF35848F73BA2C94CF3599 -:1043D00007F6F9E626BA7F7BE605B307FA77ADD98B -:1043E000B5DE83B5FEB6B82FC7BE3A98057F1BDB96 -:1043F000D27BDC6EAD5DE1CD4FF8F4667B9BC5FEF4 -:1044000027EE11ABFD776094887755F759FBDA8F6B -:1044100047C508B932304AC8414527DE8EF219BC7B -:104420009F515C6E643C1843FAF78824EF63C0A781 -:104430003A4723BE09FBD455A1C204E427E33CC993 -:10444000F36FC9FB696F0DAD4FC9E6F83E68D39FA6 -:10445000413B66FECA8C75DD94A7D13DF7AEC339EA -:1044600029C0F756B5EE4A5849F87B034A3FEE1E7D -:104470002FC54C7EF155F08FA6E0DC64277BD1552B -:104480002C9FFCA613E5F8E5BFACA27710D4BD8F36 -:10449000A83493F1FD1C578CE13D98D88224433E0B -:1044A000CE33C0503F6174B6A13CD13BD4509E3C4A -:1044B000B9CC90EFE71B63A8DF7FF678E3BB6EFA19 -:1044C0007586FA1935371AF24A7E65884F2CB37E05 -:1044D000AEA1FDA0860586FA6EFF52E3FB367E6F25 -:1044E0005B412AE49EF8CB59B7CA50FEE37871AF1E -:1044F00061B26311BD5791D772BB717C49A78C041F -:104500004127E612F2D5CFFF03DF94A719E5ED04AA -:10451000A7F1BCCDF5410DFB7B46BDC5F0FDD3FF3A -:10452000219D23F1D2C5B7A610EA431FE2F9ABF4EF -:10453000A10FC2AE3131C5EA0930614F0F9F17ECB0 -:10454000E9E178803D3D3C0F7BBAF15D2823DD61D8 -:104550004F0F2F1F7ED848F7916D46BA5F76C4483B -:1045600077C58F91F4B9BCDDC80F91F4B9E244046A -:104570007F487ACCE6FFFD5DDC93267A4D7268ECCD -:1045800071F73F4F9FD4A19C3E853DF4F9EF0C3D60 -:104590007D683FDC4F3F9F6503BD3AC57B7D2BA502 -:1045A000FC54F184FCBC2BEED3DD6E26FFFE515390 -:1045B0000BBD9774C0A9BBD1FE96A27A0DFE8334C1 -:1045C000E6DBB988C337FFDFA3C89F307F90B8D739 -:1045D000C98ADA29CE5EC9B9F919228E65C850791F -:1045E000BEF0887896A2A1422F8CF33829EEB5B29E -:1045F00048DC23E0C782ACF9C5E09F77A2F16E6189 -:10460000D74661BF6FB78AFBA57ECE47F08B414F7F -:10461000841E9729F5A8A6DFD9ED807FF02666D8FD -:10462000178704EC86B8CBC2ED4E43BE389866A817 -:104630003F6CAFCB505E1A2A30940F3FEC31E44709 -:10464000B68D36D4BFEC88D790BFBC7DB2A1FE1525 -:10465000277C867C06EB7C0CF81DA489F368F5505A -:1046600011C7C3D710F993E6DF9328EE0FCA73AAD8 -:10467000D283553CAE2EF92E529F1E64D329BEB76D -:10468000299D79E81E805D9E4F9851CFD6653CAD3F -:10469000D24799DF184FABE268BBF571A97F2B7D3C -:1046A000382C8ED61B1E473B5FDEF38DDCF7EA25E8 -:1046B000DD23E11F6413F36DFA9E8DEE2D28B822E1 -:1046C000E1F99B8CEFDC6AEFFDFEC89D4385BFFDE1 -:1046D0009739BEEF825F9F84F8C8E96D3C4FBB9F5E -:1046E000F357D30F6C9EBB5CDF3EDEFC61623EF392 -:1046F0004CA65B2A8A286E69F6CFC2C6FFA11C773A -:104700007591D6EBFCE62788B822966073817FFB13 -:104710001E4FE033CDC69AE99E8B8C3BBF797DF06E -:104720000198C8E7D95AACE2FDB28015FC30653C6F -:10473000D79F4A61B7FAFA2107D7339E6CB0901D14 -:10474000E2E1A137CCF0E7F6DC2318C4CF17E00F85 -:10475000E82A3897D88B44DCEC9EA162FD979BBF7A -:10476000EA8EFF267B3A63527E8B734B2FFC467C8E -:10477000A8E6F1AF8E038FC4933A1732B9EFE44A3B -:10478000B814FEBACFF1127F2A1EDFB5D2EA7BDA67 -:104790004171FD9311CFA4E837B048F0E589A182BB -:1047A000DEA80779D457BD72735102ECB55DCC9584 -:1047B000E0FC067BE4BF0A2F0AFF7DDDEFE94B3EFC -:1047C0005C2417FAB8EFD3177FD2DF3F70EF274C86 -:1047D0003E88F812498F40AE89FCB9F7C419D771E9 -:1047E000FF4281DF7D6ABFF0F3F3A4514E30D897CA -:1047F0009BD69AA59C10FB2AF40D7C5FB8D64AFA8A -:10480000066B10F1C835521633E64B1D3302FE58C5 -:104810002BBD67759597913EB2C0610BB4F2FA95C6 -:10482000FEC87DD54BEDC95FE3C2BB259EBB617F52 -:10483000AF5A67ACB7D821DEF55A18712E5D2CCF70 -:10484000A58B23CEA5D185725FF6300FE94DD2FF3F -:10485000ACE0ECE6AB400EC505E39C6A16F6128AA6 -:1048600057EAB6E3C3BF10F68E26C7674C01F6EDD4 -:10487000664BAF7164DDF8ECC34F7E1A7E7217D6BB -:104880007F17DDFFE9DA152DFC68CA7F21EB9FF663 -:104890009FA772D4476F674ADB4AE047EAF677443E -:1048A000F84DBA1CA6F8D1E86F87787F41C5012C76 -:1048B000FD6BA0C419E6E7D4DB4D86B88BC8545F06 -:1048C000B39BE2025A2D7A59219FC7298BC78EF7D5 -:1048D00022EF751C48C57DED29D25E13096FB71E06 -:1048E0003A56137E42BFD043BB266BA48772B9C829 -:1048F000B08E943FBB828552902AFF81BE6E34E118 -:1049000059F90F2A43A309CE194D8BAD78B2AFFDEB -:10491000B13BCA635C3D7E85F64C118FD2977F61B7 -:10492000DA050FF537FDC218EAA7A2D02DEE7135D2 -:104930003FB0127C34743BB3629EED11F1D82ADD96 -:104940005F28ECDF470B95DC96712E6B34A1676B0B -:104950004CC5BD90DC56F9F32D325F2EF2ABD78AF1 -:104960007CBB7CC7689BB437609E48311F9C8B77AB -:10497000487B04E68114F3C077C829E421A7908717 -:104980009C421E720A29E414BE2F60BEAC52B3F0E2 -:10499000834C0C5B37F0834C0CD383E00709CFC307 -:1049A0000F125E1F7E90F072F841C2CBE10709CF73 -:1049B000C30F125E1F7E90F03C1B7D6D4F1E72CDAB -:1049C0005B61C84FE3FAF8C4B0750B3F4878FFF05D -:1049D0008318FAD3571ADADFC41A0CEDE10709AFCE -:1049E0007F4B8366F093DC22EFA5576D4A22FE9839 -:1049F000E3F6FDB090D3F70FB15FDF66C539CDBCEC -:104A00006F099D9FEA623C82CE2D9305DD4D4CD00F -:104A1000B9730ED1F90E9BC8978BB8D8DEFC0D1375 -:104A20007385BF0129FC0D48E16F400A7F03DEC397 -:104A300086BF0129FC0DF80E7F0352F81B90C2DFE0 -:104A40008014FE06A4F0372085BF01EDE06F400A18 -:104A50007F03BEC3DF8014FE067C3F0ABF476E0F94 -:104A60005CD0DB730DE73BCE8786F39DD39087DE6A -:104A70001E5E1F7A7B7839F4F6F072E8EDE179E892 -:104A8000EDE1F5A1B787E7DB86BA685D427F0F6F7E -:104A900007FD3D3C5FDCE27F0336A61B369F3D846D -:104AA000B43D4E7B52E3A2E0BDE78ECD80DFA83D52 -:104AB0005ACB4AE44BDEAA9D9C3191EB67BA8C2F0E -:104AC0002B619DF4BEB32EDFADD1438CE2618BFF31 -:104AD0009226E482BA37843F4EF7D25D8CCE011520 -:104AE000723F55ED3DCC6926B925EBF7E47BAF1756 -:104AF00039BEAA47F2320C0E7E402C451C44E91DFB -:104B00008E32C4716F3369220EF22E11871AC95783 -:104B1000E6222197B699761E88415C4BA546EFC5E3 -:104B2000E75BD861BCE35DDC525F067DE15461A2C6 -:104B30009C57FD18C4C528B8951D90CB09BA5735A8 -:104B4000B693D9AA8BF09E18B32D847CB7093D018A -:104B5000ED707E2CF46BDEA7C3F8FBCF85627FD3AC -:104B6000FD2BC754F3EF853BEAC7E0BED69418D1BE -:104B7000EE274FC5131EA7366B4FE35EDCD81DCC66 -:104B80008BFB975F4B795AB8C369ABA6719D74CF05 -:104B90004BF55BB9398BEEA555B2F6896964CBD775 -:104BA000E81D7385373EBF43981F17F187ADA48F6B -:104BB0008AFB2231F2BE88BA27E2B6F8424347F6B2 -:104BC000DC17B972446239E2B5D83EF1EEDE0D234E -:104BD0002AD7F6E3FDEB01F1EEDE957FAA7F83F2A3 -:104BE0005BC4BB7BC406A3681CDAD706FB357AEF2F -:104BF00061AABFD594E2C2FDD135D654D4DFC13C01 -:104C0000507F0633710F52C157C4DA4C78779C6FCE -:104C1000310793C3F8884B80E9A07BA9C74AEF41CD -:104C200054589C56C88DC87DFCE278BA083D2122B4 -:104C30001EA2E98E2359E66CD87B4C9E10E4D6EE7A -:104C400058D21794BE5329E3A0CE37BF41EF59572E -:104C5000EE14FA81CEE500E49F8A8FA8CB0964990F -:104C6000A02F0C682D49328BFDBF08F791FC2FCD8A -:104C70001CEDC23DC637285EBF72EDC804715F47A8 -:104C8000F81FAA259EAA65FC0B2B72A642EF54EFD3 -:104C900098969BC726D07DB716A1CF29FB4BE5AFD1 -:104CA00086BF093A573E21DF03595749F78022E36F -:104CB00050947EA8DE3B59D26CA5F89625117AE077 -:104CC00032A9072E8BD003AF2B8AD003D5FB74B249 -:104CD0004EE5AF0ECE203DA55EBCC7376F8DD05BD5 -:104CE000D84EF18EFDBC35134C78B762DE6EAF47FF -:104CF000EB853FDE93FACB140C9A8C389F0194CE4F -:104D0000BC9046E9AC0B052407701703F46F7F8550 -:104D1000913EFDBED4576620CE0FF7E3FC51329E84 -:104D20008F91BE54CA9CE5901B43BDDA4198AFA752 -:104D300058F5B588239CD2CAE83ECC0DD06B78C11B -:104D40006CE839C3C1E7EE72BA173059A3FB1537C7 -:104D50008C5829F99AF339039FFB25DFFA28DFBD28 -:104D60001F48FED6FD1D167A97D5AFD9F02E9B2E83 -:104D7000CFB38A7F23F97CBEFCBD09E61076A66E10 -:104D80003B1480A5C755AE9A097D713E6C7703240C -:104D900021398AE28A447973D155339B71B8F91F5E -:104DA000DA27E6A9DF61E07A16E4E9CDB796DA16EC -:104DB00084C9958A92F1CF14F7EBA1FB82EE7B6355 -:104DC00045FDA1FFAFBA37AFFF37DD5FACE278C674 -:104DD000FA989FD07E1B5EC6DD52C4BC1347E33DEC -:104DE00066354F1642BCDA5C99FF75D1E2FF585721 -:104DF00044F8A17C60C794997E5A2F425EDD047905 -:104E000065869CD29F2CC2FD0E7BFB24D023B6A8C6 -:104E100053DE8797FB51843DE2D745820E91768918 -:104E2000AA2221C799C5957513DD5375915D4FC1B0 -:104E3000FFA9D5786F50A5BF54FB48E3BF26DEFE1F -:104E4000CB54FDE7901F8F98C4FDED01E61626EDCB -:104E500043E27732E4FA61F23D831EFA73A901FA64 -:104E6000DFAB39C3E9AFAFD3C4BDE93EEC38ACA08A -:104E7000F3B1ADB0E3358ADFE7782A5FF0D153B7FD -:104E8000DB48FF9E676B7B03EF34293C7EDCF0231D -:104E9000ABF89D97501EDE9F9A5B1F4DEFBD569459 -:104EA000F8DA4097D8220FD1E319C494F2FAED4E04 -:104EB000DFFB984FDDFAFD4FE2FEF88A7D6EBAD730 -:104EC00058B9B7F46EBC6B5151A21F4179A5C369A3 -:104ED000C3FEBDBC3991F6B3F9FDE5FD42D6497E6E -:104EE0002A85FFCE2261C7DA5622FA3F27CF21104A -:104EF0009415867A32AE38629D28FB60A49D21F21B -:104F00003D81BED68FB227C07E600BB32F2AFB84B3 -:104F1000B5E0D339D83FE7D98CF7E154EA2E96E7CC -:104F20005C790E5CD8BD7F154DEA0F7D798346BF55 -:104F30005B53ED70CDBA9CE7AB0F5B1129C8A6247B -:104F4000B9C43B12F78A772416F0F50A79334FC6B5 -:104F50000D556F1A4DEBAD3AC0D3E4BED7E54D1BEE -:104F60000E66BE02FE0979E99E78B5D36B4B0A5BEB -:104F7000F7552D9AE19EB9CA27160B7BDC3C3C61A4 -:104F80005E0679E1B6E12D97795CAD401C9ABBD8FD -:104F900065F0BBF27A14C730259BBD29DEF1E170C4 -:104FA000BBC5786561FD2F6831DE97E7F5C5BB1499 -:104FB000C571D45FA593CF1BF60FA793E0E47820CB -:104FC0003C753EC0FB73D138448FAA50C08AF3F6BB -:104FD0003CC44FF0FC5C67C08A7116348B772BF4AD -:104FE000F5621C7D5DA2AD18FA92C569CB04FEE4A2 -:104FF000BBF61C3E9283D51C2FB8FFA3EE0146E200 -:10500000A752C25BDD9268D4C35A3658418F397DAE -:10501000DC9FBF41D27D41F338BAFF5C6DF1527C19 -:10502000BD2EF1FBC795D1F7C13F3067E3A35637DB -:10503000CF5F592CF8F70689D729D9A13C7A9F660A -:1050400065B40770CE71B6D0FCBAF1FB30C7878665 -:1050500077507C845FCE177EC491556F34D2B307EE -:105060001E81DFEA8D95B4DE1659749B331C8E4D7C -:10507000FBF370AF670E5FDF7877873975BA6FF330 -:10508000D9C3B3B2689E1C4EE035CEE39A84F7666E -:10509000389F101F2B7E51F783D5780B8BC53DC1F0 -:1050A00085C5BDDBD77BD6A597F49B264E5FD8BDC3 -:1050B000FB5A97365C34E2E3DAAAC53B6091EB54C5 -:1050C000AD4FB52ED53A55EBF749AB2F94A6F5C8A1 -:1050D00019BEDFD6FFAC173C3D23E19D2BE9CAF199 -:1050E0007A28FC5ED1FA62218FE6651BD73BFA4332 -:1050F000BFB7ABF2F1A13CDC0354F5D5B8F3E4EF54 -:105100007481EFC16FB74BBAA3FE2AAA6FBC1F51BF -:10511000D52D2F76AC4D85BCD8A991BEBBEA818335 -:1051200099FF063DF679A1C79EAADDBA3C1D76031C -:105130004B202BFC7DA6EA90900F0BB9FE0379B1B2 -:1051400048EED3D7E4E9F7168F0CABF7D0F3F9BAF2 -:10515000902F21C897DF3FFFEA87635C3DFBA78262 -:105160007FC1BA5F5B2B1DE1F8127C7E5F4117DDCA -:10517000FBAA72D85C88B3AD6AAE2479CBD2F87939 -:10518000420B8B938AE083CA668DDECDAA6A18151E -:1051900030FF2FCAE5AAF515F4368FA2937A7F4324 -:1051A000EDA70AFE1D12FEB9928F5F94EB6F6E8D14 -:1051B000DBB688D6BDDB5605FE97E573AA8DDFBB4F -:1051C000E9D4ED672EBA3B4DDE63A173C97AABB06B -:1051D000EFED88237DF5D4AA97DF9DC9EB7DF148DB -:1051E0006B16F41305C76269C75B28ED718BA4DEEB -:1051F000CAE9F47A71989C5DFC94A053D50BBFFA70 -:1052000004EF43CDCB96F2EC0171BF7C417027D106 -:105210006DCEBA0D5637AFF76EB1DB20A7ABEA4BB8 -:105220009DB04FCF5DD76A851C78B758E02D92DFCF -:10523000E7C9B8548557EC3B5A98FF42D587FCDB49 -:10524000C9C7B97565743CE232D438FF25F9B8AAEC -:105250003E3109E355D557FE10E71E25EF23D7DD74 -:10526000B168B11E16F0FEB02E8F8DF3D03DDB7904 -:10527000F2F7A522EB9F9574FBB155BC2398111B47 -:105280007C96E20A56C478201F7273DB031817FC61 -:105290000CB86D26F1EE606E6DFB978083ABC51484 -:1052A0009F8214EF1D414D4EE5F9A74DE23E10627D -:1052B0004B90A694087E80690AE52CA59DDE3F0BE5 -:1052C0008BCF34F0AB8D6D5987F7576C298C7EEFFF -:1052D00045F1A7EA47F1A7E2DFBEE6E728B9B4F94E -:1052E0001D734B3B4481270BF728E63F3898DEE7D8 -:1052F000FFB679DAE43B78DDF38D12BF5B70D17CC9 -:1053000073C5B9A5EFF96E2C4FED65BE91F354EB63 -:1053100044C55E77FB155A845FE198C6F72FDEEE31 -:10532000D8CA688AFB52F35276EF4B8D97F79424D4 -:10533000493B427B1CF4C879F2F7205848E4F1BDA0 -:1053400022ECBBDAF7D5BB614A3E1FAF97FB226B5D -:105350007F00EB9935E4D03B19475B8EC5E1FD8EAC -:1053600063E3047CAADDAD5671EF95C5D95C783F47 -:10537000919FAFE8771F1636F7A773E4CD0D392458 -:10538000176EF6270ABB83D4EF174939187B6BE5F4 -:10539000DD97A1FE26B753E3E32C74783EDB44EDA2 -:1053A0000B3DD007633756D8B249EF15E700E50744 -:1053B000BA55633EBACF043989F565DA9F8B7D67AC -:1053C000F126710E986262EBE02F1CD4E49B940EE0 -:1053D00039F1987837926D36BEAB7420CF777D095E -:1053E000F016F11ED9ADD6A0B73FE438D7376067C5 -:1053F0005AE8F091DEFE969493473776D0FBE40AA4 -:10540000AF17DD53B1897BA99D7126B2BF5DEA7DDF -:10541000956AE94F527CA3FC518FE3FF2E079E4C07 -:10542000B4AF959BE7D1BB3E776F9C4069F586F2A0 -:1054300047FCC5B80FEB4B1D43705BC93E565D374B -:1054400041DC1F7D3A2A11E79B2CAB3F2B5C2FAD33 -:105450006EBD87EEA99C688DA67B2A139D1513133C -:1054600053E8BD5DBAF7A5EA7D5FAECBA575130C19 -:10547000F74C16F23E1107FBE7602CC595AAFB23FB -:1054800077C6E8DF2DE927EE915CEE12F747D2A947 -:10549000BEAB577BB84A3F6B14F711C2EEC54C9DAB -:1054A000C3DBD7D6BD148F7E963DFCFE288E19D85F -:1054B0009FEE02DDBAEFC56C12F7629A705E821E33 -:1054C00099E49B3907F8FFA599F0DFD77835F851B3 -:1054D00092B073C4CD8104D25BF510B3C19FAC3BD5 -:1054E00019E9C527CCAC017A80D25FD4F747245E96 -:1054F0004E24B464813F966C7B340BFBCBC938914E -:105500009FB76DD65B9057FA9628A19F5B18E9C3A9 -:10551000557EA15FB39A24F52E66F47CF8634B6246 -:10552000C53B3CF2FE8C824BBDB77AD222DE8BC1EA -:10553000BD18F0FBC796D042D0F763AEBFE21CFBAC -:105540007D29C73E6E31D3EF8EF8F942811EF2718C -:10555000CB4B71B89FABF4B572F3EFBD788F66D5C6 -:105560006E714F15EF9AD39B95D20EB25CDA41560D -:10557000BD629D84DF1DE1FA177DA9B5846CBDD1A4 -:105580006FA9D4AFBAF3BB76D2B9AD7687D01F6A14 -:10559000831DA43F287D44DD8B5BB6A383F409D52E -:1055A0006EF92E8197BA5DE27B25E2D6E5EF856A3A -:1055B000B9384F6B94FFA468C1AC3596F07C25E5F3 -:1055C0003F2952F6914ED207EF2BF80D9DC3EB9A6F -:1055D00065BF3C6F0D1BEF0D30693FF13DC781F694 -:1055E00062DF57E575BB12A97DA82E661DF679EF1F -:1055F00072870569539D83F6FDCDF5A602CB0800A1 -:1056000017E3811EB74FC66FF55BF61FD1B01FA41D -:10561000B3CE8378F7F580533F027E55BF67A9EE7E -:10562000BD9C7BEDF3E1E8FFAA41EDE7F1C6837590 -:105630004DDD2CF827DA4BE43C8ADA8783AFFB1D7B -:1056400010F2F9092B5B47EF075B7C0C76FB90F4BB -:105650002BFAFF6212BF2FA1859E09D7AF52860990 -:105660003DDC1725FC8B5EB77E12707C47B3169726 -:10567000E24CED32E7A17FF53B2A4A4F1D2FE5733F -:10568000A63C5FD906A439C0C79AD74BF710EF2ABA -:105690003A50857DF9FE4E3BFDBEAA8AC31BDF1939 -:1056A000437A6BE680C9B49FA97B29078A4C7EBCEC -:1056B0007B7E3FB38BB8007B845E6B8AA678646D7B -:1056C000DF2FFE02799E61FEF2207EA724E3DF3405 -:1056D0007AFF727ED7674FE03766E6B14029BD8317 -:1056E00097A89B86410E774DEED039C9EE7706ED2F -:1056F0001EB14FB070F8F77DEF2FF149A61EB8CE5E -:10570000757E46EF0A9EEBB493BD76FC3EF9DE5EF5 -:10571000043CE7D25C1417CDEB85F0BECA3987890B -:10572000DE191BBFEF20BD9B375EBDAB6737BEAB3D -:10573000C7DA3213614F261B2A570A529B04DDAE8B -:105740004A309E13F38689F356DE30213F14FEBAA9 -:10575000EC67DFD6B59E75B842F9EFD5EF4DD5446D -:10576000D1EF4D75EDCBF9C6F713DE87FEC0F5829C -:10577000F5D9DEE261FD7AF6CF19122F6A1F36CB1A -:10578000FE6748FCCC7098043E227E6F43F187A2EE -:10579000BF8257D157D18DDDDEF606EE05717A1541 -:1057A0003FC8884E97119DFEF2CE5A5CF31F60F6FB -:1057B00076E8EEFF8B740A450F869EF0B0F8FDADDB -:1057C000C8B84656C0689DCF37C7901D5097EF8226 -:1057D000F3F5FD06D6B75AD78326B717637F3CCAC1 -:1057E0008FDE80ABDD14A4EFDF1D26E20907B2B621 -:1057F00074197F33127A59937CFFB8FB770C973872 -:10580000E8BD917301F5FE71E0B1457CDC8D338A12 -:10581000C8AE7F8EC9F55ED3FD4EB678FFB8FB9D4E -:105820006CB39FEC247362C8CED3FD4E769E78EFA6 -:10583000FA558DE5E31D5A7F859DE2E323DFC9E636 -:10584000FBCCB3F0673C5E13437E28F53EF278A7AD -:105850005E0F3A46BE8FFC88E69BB310FD153BA851 -:10586000BFF639312F6C13680EC18E73B4218EDEF2 -:1058700085567CA9ECD783FC1D8F014FEA5EE71F9C -:10588000247F29BCAB7B6D0AFF8ACFFC5646F73FCD -:105890004107BC2BABDE67D7EE907243DD277CDD82 -:1058A000E342FA40A2BE0E7037ADE47283ECE2ED43 -:1058B000B761BE4F7C2FCE0BB88E9A8CBFDFABD2B8 -:1058C0008786990CBF133A5FEE57F355DC7F83311F -:1058D000EE3FF21DCDE404DFC3C378FB33DAFBA354 -:1058E000F0F19DFF36F71A47F2A45CFF2362F5271B -:1058F000505FDD7F50FAE13BA59F67D2EF8D7C754D -:10590000907E5771AED31740BDE85CE10FF8437A43 -:105910003BDDD7F8C39CBF66923DF90EF1FEE7A5CB -:10592000C279F17D5AC10FAB178A78C30C564FFC70 -:105930009BD6734F331A70FCFF769FB6E7BEEBE43D -:10594000E1C729EEC247BF5711498FB151075E72B7 -:10595000F193CA6F877D318BEE93261C58EDE6F9E3 -:10596000A32F9E15F98C03E7DD9C36ED2F9E13F9CE -:10597000C203E7711FF5D3173B45FE0A46FEACE3B1 -:105980002F7E390BF74FFBBBF53F825E332FD4BF21 -:1059900081EDF5C335372E74D37DCA8ACC02719F51 -:1059A000F26394CF485DB03641EBB94F69F2F8FE2F -:1059B00008BE3DF7A5E06F3787157CF2CFA6EA3E1B -:1059C000A992B77DC945B5EEFE55F761D53A66DBBC -:1059D0003CEBAC6042FF3F7D4F9579F8BCFE1F9BCE -:1059E0004A017000800000001F8B080000000000CA -:1059F000000BB57C0B7854D5B5F03E73E6994C920C -:105A000049C80B02E104420C18D299BCC05BEA1DE4 -:105A10002089015A1B6CB52018068D90D76442A8C6 -:105A20002DB5D80C0611A8DE0B5754B068274000DE -:105A300035E8A0012718EA00922252BF98FB37F2FE -:105A4000FD5FE10B3E90979310B557EF55B96BADE5 -:105A5000BD4FE64122DAFE7FF8DAEDDAEFBDD77B03 -:105A6000AD7D86B1B196F3D18CFEAEC98C1D3FFCE5 -:105A70009EA249646C4681D16A90A034772BC602FD -:105A80000EBB01DE7595F935B1BC9F36B45FA2D768 -:105A900066C17E7566EA973908FD72B1DF9F476B74 -:105AA000B1BE416F356430F6B48EB94D098CC5680E -:105AB0008EC8B84ECC2063CDD07FAC8131631E63DD -:105AC000297AC6B01DFA312394BB06F97AE3121A7B -:105AD000563098675C85D9DA9C81BBF53056C8583A -:105AE000DA28FF68DC5FDA4A3DD5C7687A94063366 -:105AF000638126FFDC0F33192B8E8ACD653F8052E0 -:105B0000CFB2711F4C13656D85F54AE4AFBAD20070 -:105B10006EEC906CB0342B36946F671319ABD702D0 -:105B20009088FF33795A711D6D77F51EE8D7939CE5 -:105B300066DD08E0D8D4832C331FC6BBCA72D804F4 -:105B4000C68E5A1C39D62468679B241C1F9DC3C768 -:105B5000FFAC2C7A870CE3FB0FDF54E880BA3B0CD8 -:105B6000CA0166652CDF3B7A81F61680E39442C950 -:105B700002B075EC02ED688053940312B41BDDA3F0 -:105B80001714DF82E7335A3ECC66EC174C62718003 -:105B9000970CAD63BA15CEEB2CFB44CF34D83EA0A6 -:105BA0002F9F0AF76A854960FDA4A3704FB0CF818B -:105BB00039319E1D703E96A314627BBA6E20D602C8 -:105BC000F7D1FF95B6CC63A671B13F87FA6BF8F7B2 -:105BD000AF8C3DD72953BD0AABE5375689EED79533 -:105BE000697E0CEFAF3ED568A4B2F36A29C379B4DD -:105BF000E59977C03C763D5B529E73FDF801AB861C -:105C0000F695B10E103A86C8CBCE14F8BF28A6C2BE -:105C10006E369DB1965F41C5BFF0763809D34FD23D -:105C200008F896ADC5DAB0FE76EC1F6C6776230BEC -:105C30008E775AA76E5D9B29D6433C2F639E497091 -:105C40008434D62031B8BF54E627FCBC644BA07323 -:105C5000D11FE0E9D94453CB46A45719E8328F4A03 -:105C60006681322D1AD683F6B4374C1EA4AB5D265E -:105C70004EB7991A5EEED2F0FEFA28E6463A1D07B4 -:105C80003083F26D9BE377B6249AC74FF3C8FB6D60 -:105C9000488FA39997D64F616EDA8FDA6F2CEB3667 -:105CA00021CCB40359844F5933EC7D26D9666E4616 -:105CB0003A0B34D9D947DA607D203A765528FEEA86 -:105CC00071BC3974DC2C1AA78E77AED2B08F46E146 -:105CD000E1FD443FCE4C8DDD9383E3D89B521ED62D -:105CE00077EBCB6382E37A9B8CEC23B8D7FFD3C4EA -:105CF000A83CDD64A1F5FF6F532A957F6B52A8FE87 -:105D00006C5336957D4D56AA7FBF693A95772D8A9B -:105D10002940FA77F966B28F8C42CEC0FF9C5E9D17 -:105D2000A32F04EE9D393C1DBD26E8A83763F8F685 -:105D30006E6C077CF6DECAF1D97F3FF3ECC820BA5F -:105D40005C6B49B81EFF30C284E7EB8F610BBC70FF -:105D50004F6F1748347FFF680EEFB7EA683EBB8687 -:105D60006DC5F16F17E8F9FC133455D86E4FE0F3A9 -:105D7000F666010CFB59307DE6CBC897F664A8CFD8 -:105D80000BC2BD5378BB7D0CAF57F7ABB6FFCE66E9 -:105D9000E17428F0DEAF83F57388DE697EB5FFD746 -:105DA000459C0F23FB7B3235659E61EE23C1C6FB0C -:105DB000135FC07DB8910F3242F8A25E21BE50E958 -:105DC00050A5BF976CFC9E330D82CE4127D0FDA11C -:105DD0006E40F99A027C20D1BDD8199C679724F8AF -:105DE00025921FA04439AEF283CA072ABDA7019F9E -:105DF0004909C173FC28825ED5F2B495E3A53B390D -:105E0000E601C26BA7CE02A210FA03221310BEB3A2 -:105E1000C00EE34A1E35370C27BFE2FED97B50E5A2 -:105E2000C108F770DDF9F5BCFCBEE727F986721BE7 -:105E3000E9761879F5B53581F6A3D26D92CDFE5F7E -:105E4000483FFD92492BC54169E2741379FEB70BB7 -:105E5000F83954FA79C9C6B8BEC4734EBC5EDEA91F -:105E6000E7193AE77246722F338AD747E2573D5710 -:105E700088DC8BB11506EF93316E0F8C057B606368 -:105E800046907E03495F2E43FDB5CDAAD0FEFEA00D -:105E90009109FFAA3E19AA97E425F373C2F40CB343 -:105EA000001E070E1B88BFFD1A56F50A8C6B255580 -:105EB000113CF76D362E0F06174CD2AC827D05FED5 -:105EC0006E76A3DE0A8C19382BC1F8C0563040C854 -:105ED0007EB0FF584A66EC7ED029A897AE809C63BE -:105EE000598CC9DB3E3F2BC1BE976D9319DA350142 -:105EF00010DB328C733D19E331F2718CC1B83A3149 -:105F0000AE79EBA777217D9D07FA44FBE62353FD8D -:105F1000040676CFEC6D3ABAC765317A0FD61FDB2F -:105F2000FAC48945009F6F9714B4374A6533B5D7D3 -:105F30003C2F7B709D3A73E94509EC9C407BCB5329 -:105F40005150EFDCAB63261857DA2E59FD30FF7243 -:105F50006F0CDE0C5BB645F77E5F76506EDE26F486 -:105F600058D52EC90314C3AAB687B7D7EC0A87EB56 -:105F7000983608C3FCB36C318964FF4D6636B4FFB4 -:105F8000D89604545643723B92AE506D237EEC8DEE -:105F90005C1E33F659F21D4097F2E1CFD3DF377321 -:105FA00078BE80CF01FCC9E7FCFED57BAB1732FF82 -:105FB00093D1ACC00BE7AC3F6CB2B8E160F51D32D9 -:105FC0009D23E08DA37B7645F5DD4E7C7A48B6A017 -:105FD0001DB6C127BBB1DDD969DAA98173D61F907F -:105FE00018DA9F4E9FC1C3EFE9EA326C5FEE335976 -:105FF000146C3F6460328C0F00DE4C88C7717D8466 -:106000007FC42BDAA7F0F763A928887F19F19518C8 -:10601000C457F356BE9FF37B397E4AE5D55AC25723 -:106020008BC45242F0FC67CD8B43F8C27EB3B7FD00 -:10603000B50BF1BC0CF6675010EF32E1F93CE0070C -:10604000E7D51FFE28BDCF1CC4B70CF8FEAD3A1E25 -:10605000FA2FBF01BEAB987B1DDA73DF17CF69C87B -:10606000FF4964F79EFF03DABD31608F23E908FB27 -:1060700038A9B6F778222C589170D9B902EA27A529 -:10608000BEC232C14E90E21D8F225F9F9DF39747A3 -:10609000101D3D735FB4215D34EBFA5A9F860A7779 -:1060A0007CB41579B03F63FEF6D7609DE2842FD3B0 -:1060B000F723BFFCC96041727A42F023FE1901FF49 -:1060C0004EC6EF1BF0780ECFEFEC34F80D708FACAE -:1060D000BDC43E640F4C407DECD5A39C2AD10F5427 -:1060E000AC407B1CE6C375242023E4EBDACE3F9F53 -:1060F00096609CA424B2C5081BCD7E19E769D35DC8 -:10610000193A37CC2359FE42FDDA6C13E8FC1353DD -:106110007EA4A0FC695EC81C5113BF4DCE3392F320 -:10612000CF0A7F6544FB6F0479AFDA7DCC3D361E24 -:10613000F90BEF82F30F973BCBA733F127F842C05F -:10614000556BDCB146E8BCFC666B2A9EFF63A4B3CA -:1061500058A4BF53DA51B0AFBA5689F0568FF483C2 -:10616000FE15EA37A8EFF70A39F27C77F1A8442C3C -:10617000252B702AABEE94AD7E68AFF6717ABA8E9D -:106180006E84FCA869E3F2E33A3A6A0338C44EAB82 -:1061900047BA5261C0F7C9A0FC987A0DF6FBF234F9 -:1061A00026F4955BD05B4E5C1FD0CB2053E22C399C -:1061B000217A4BE2F6962A576EDA0AA23E64DDC9CE -:1061C0001E23D386AC7BF35E4B183CD59B1AD6FFBF -:1061D000073E25ACDDE6CF0E6BCF3F610D830BBBD9 -:1061E000A787F59F76DA1E06DFD25716D6FF8717E8 -:1061F000CAC3E0C11C38CF3076C7901E4A95C2FA98 -:10620000CF514C61F3CFCB8E0F8307CDE27E841D3F -:10621000A8DAA75FD8B81D1459AAF7FB136BF83A90 -:10622000AA5FFCD3E9E1EBCDB787AFF75DF1B21B15 -:10623000EC7E2DD8F57B413F62F902D8FF5AB0EBD6 -:10624000DBC0FE47F825B0FFB1F482FD8FF5AF80CB -:10625000FD8F703BD8FF081F047F05615F531995C0 -:10626000879ACAA9FE46F7D725D63D21D63D29D61D -:10627000FD47EF492D9D6593345F009FCE4CB8A834 -:1062800047396C6FEC2BC538C0C05B32DB810CE248 -:10629000F09C684A447D348AA1DDC2CA07DEC63854 -:1062A00045FD8189968D0AEAA1FF7C07DB03EDB2EB -:1062B00082F2FCA8EF83589CE7CA17C087F938EE32 -:1062C0008358F48FEBBE64046F847605E039FB419C -:1062D00030903D03720DFB67AAB047CFA02C6FDB57 -:1062E000AF477CD4EEDD4FED6F7975E1ED7B5BC29E -:1062F000DA2DD81FCA5AAD87FCFB4B3E753E3FF5E1 -:10630000AFCB94EC68175FDAFB9FC9CBB05FDBBB08 -:10631000C9F77DCB7D7F72F0C51C94EB4ED0C37E58 -:1063200073701E67874EC07CDF7599FB4B1350114D -:10633000B4496C121457D826B60AE45DADAFB50E59 -:10634000E5506DF6221DCB207924E20D206DD15E43 -:1063500042E71EEEEF8AF7D3D8FB60DE37BCC76F8B -:10636000B723FE3A8FC5E2BAFDED72983F73771EF0 -:10637000B75BEFCED313DEAEB41F8B55A07D83F792 -:1063800018BF6FAD9FCE7D54C0FD50D23DFB643A27 -:1063900077F5171ABA7F75BEFBF3649A678E6F5252 -:1063A0000C9EABC7CBD773E529B4CE9CCCA595B8D2 -:1063B000FF93A90B0B65B2F34030A35C9D32AF1580 -:1063C000E303B55ED93E9CBFB546CCDBA5E374F8CC -:1063D00056E6AB5D63803E4E968DB291CC17FD7E46 -:1063E00093C7EDF152BD2313F5428F5989413A7E8F -:1063F000B86C620CE2F52896585FB653EF80B2A6EF -:106400009DAFD763E98E457AEB69CF97D16E51E79F -:106410005B89EB1686D0F510DEDC84A72A4F8B193A -:10642000E709E28FD7BBF2B81D7ED2F3EE5D68A715 -:10643000F464475B112F5D7A46FE6D2DE015F54142 -:106440004F675A0BDE83BA9E4BE0A33F5B43780D48 -:10645000F874A2DFA25616D64FC7F1B52B7C3F16B3 -:10646000CFB97F5B847AE959B0ABA1BA4ED7908C93 -:10647000E7FF787BF8FEAAC43DD7E9FCC9C921F43F -:106480005AD731C42F66A2EF0E953F14C2A78AC710 -:106490009E6C6EB7F5A41A3CE82FD6ED6F25BABEF8 -:1064A0003EBED39D81767EDAAF8D1437BC913FAB73 -:1064B000DA01217E0F433F4E5736B1503321A8EF0A -:1064C000AFD9EC2FE615A23F544EFE5E0F1B588647 -:1064D000CADF8976701CCADDBF3D85EB0EB683BD71 -:1064E00007EB3A8DBEB91F829D35680546817D0F49 -:1064F0006ED779847F6246FB7499B04F3F561C4536 -:1065000032E857E71A0D9DAF2E278ADBB5424E7E43 -:10651000B23FE3A748AF7527648B11ED50F05B08DD -:106520006EE37641BD37E3DF67A0BDDDA6233B40C8 -:10653000B53B9CC2EE382FECD9F36B06F464AF1E6A -:1065400096D813B08F2ADFE6AE346877E6CC257B89 -:10655000D529B751FC71F9D670BBA0DA130ED7EE6E -:106560000D879D117683EAB7F5E40DD90F93D1FF1E -:10657000289167A4201F7C2CF0A9FA232BA75A533B -:1065800090DF376895B96A3C00EFC975F8D56ADCC9 -:10659000AFA72ECA4A7EC1AA43749FFD9F71BFA3B5 -:1065A0003F9571FB88F17BEDF771FA76E924EE6790 -:1065B00000B9D27C46C9B3069AFADD83B124971894 -:1065C0002B437E685CC8FD483BC65CA1DC9727E294 -:1065D0004511FAF2566D9F1C1F221F3ECB9B40FBBC -:1065E0002FD63307EAA9953156D25BE38DDCDE2E38 -:1065F00059EDB5211D8C07FFD81012CF1E6F1E90CC -:10660000B0DFAE8778FC5CF5EFE76B2DBAF810BD14 -:106610000792276C7E90247CFC8DE6B7C0FCE6E0F8 -:10662000FC70DF7178DF9F1658491FA7CF67AC9BBE -:10663000F8B181F8513DCF15A0B362A0338C9920F9 -:10664000DEEAB61FA138B09375933F521ACBF751CB -:106650008AFB41388A97967C2E37CAF3F9BD350BF1 -:1066600058955B6FE5DBE3F3A1DC9BEF48CAA77AA3 -:106670000BD1E54A412B60A7A4F40D23771BFFC281 -:10668000FDAA4F810F90CFEF699094CC303B88D317 -:10669000B78B57B1CBCCDB3B03EFC16DEFCE4E4692 -:1066A0003F8AF3D59255262533844E5D48E7702FF7 -:1066B0005596EA1FA3DDED5895AC60BCDF85743FAD -:1066C00001AF91D37522FC43FFE23A3AF786C3F05B -:1066D000B71DE9AB9E19ACA8475CBEC876AB16E304 -:1066E0003AF9F9C0073707F9205DD0658B43F2A06E -:1066F000DC6FF94ACBE3588B258A5BDD0995489717 -:10670000F487FDAA667A70FE3B01447F886D4924B8 -:10671000BEA14690233F17E7BD53EB3F827C7C5CD4 -:10672000E7CDC078CA7127CFEB2C646070807C59AC -:10673000CCBAA9EC8DAE3FE0A7C9DDE3D06F7ECF28 -:1067400061A0384ECBDA1D31284F73D95ACBF96C82 -:1067500054EE6CEFB5FC91ED0A2024765EC50BC5B6 -:10676000853611FE55BCEECDB7CF47FC8F34BEF653 -:10677000AF076E4797A2F681567D0A279BEEECA2E3 -:1067800020FE5CCC9B8DFB55F135843FD8F358B887 -:1067900087056CA008FD1A156F46F8371CDED4FB80 -:1067A0004CD70DFC0CAF0CF412C997487CAAF75BD0 -:1067B000CF1A743CCED5F0CE42E87FF75A8D82F6E0 -:1067C000E175F8BD011EFC26DEE48F91C8DF1C09CF -:1067D0002F2A3E54FC9C8EE7E34EDF23539CEEFFB2 -:1067E000355EDECA773CFA6DFC18C97F23F1DB9277 -:1067F00055117C19C17F2ABE1CAB6289CF543CD68F -:10680000298CFCD6BACE18AB8705F167867F883F06 -:10681000CC53503CA65D62CF48DF850FFB28AF11FB -:10682000891FA00D3BCAF59D11FCA7E26D24F9A3B9 -:10683000CAAF33CC7FDC22517E80F3E7AF0C1ECC95 -:106840002FAAF901350F704CC8BFC8F20CD81D989B -:1068500077D998DD9384F65AAF5E9D87E71FCFAC5A -:10686000E91EB702C69F99C9CB5EB4D342607B14C0 -:106870008FC39D196D70E3BD9D9126CF423D7E462D -:10688000FAF5ED1C4ED12B082F4C996501B857A78E -:10689000C6ED1E1672D843E59985D38AA99FC4DE3A -:1068A000C4FB5024564EEB48524219ECE7CC0393FC -:1068B000F29A59F0FCAFE4737BD62BE4F9501CFB41 -:1068C0003712C5B197800AB060BC7DD6D36513A0DE -:1068D000FEEC83136D94FF6B0C5F1FF56806C50714 -:1068E00037D37CB77E31A05B9A13DCD790FE2BBEEA -:1068F000CAEB2B27913F512570684F98CCFD58CF9C -:10690000C438D447AA7E1A3CF1AA39347E7911F4EE -:1069100017D387C0931F4F0FD56F4776FF3E0BE706 -:10692000A9D2BB73AD507FA1E50FE9680754ED7E96 -:10693000348BECD2DD1BB2D0BFA8DAF1FB2C3BC10B -:10694000D10EF26FB4FCDC97F7DDB27363881DFCE7 -:106950006021F70B161B8F94A07D3AF7E64F1EC1FE -:1069600078F8A407258A8BDDC3BA1F41BD5991CDA4 -:10697000F9886D31925C87F928EFD83AF927BB5036 -:106980009E9FCCFE405709FD4C055ABA8F0AE67906 -:106990002C05E361EB258A8705FB8FA33CE6D2B586 -:1069A000923E3511F561BC4D56705C3CEDE3DEF571 -:1069B000B62EACAF58CDEBE71A3CED3D38CFD37ACD -:1069C0006BAB8213954F280FC90B9B0AB8DFB5E458 -:1069D0003189EC71759D494F25B7849ED35420F4BD -:1069E000F98C6EE2FF9F0ABCFC78F5BB6FA62A9873 -:1069F0004F72C41540FB3B4F9ECF44F9559C7031FC -:106A000007E97C92DEF14C359E7B8781E28705B9F0 -:106A100069720AF4CFFBE5CC27B05CB27AE933D5D2 -:106A20001807DD6A243F4ADD5FA3A468D0DF3CD6A7 -:106A3000F28B7BF1DE2E3C69243BBAB1E5A614361D -:106A40000C9FAAE51EC0BF92C5D8F34D462A5F6CC5 -:106A5000B230058EB8AF2995E0979B142AD9024E23 -:106A60005F8DC25F1D69BE7CF0F715905705EB6125 -:106A70003EB0376D26FB143CE7A429CE1D1BC4B9DC -:106A800026C1789B3B6336DE43C186155D688A2646 -:106A900017F0FCE2DB3DEBD3C98E5E7DEEB96A6890 -:106AA0005F5A509E5F00F76DDC7E95FCFC631D8F86 -:106AB00056505C7F87819F4F9CFBC2935929CF60C2 -:106AC000DCF52D1DF9DFAEEDE79EDB00E57D8FAD3A -:106AD000D087D2FB773DAF4DECE7467C35D23D7C8D -:106AE0007FBEFA7D3AF1CF0EE0AB9C7F9CAF5CABF2 -:106AF000D7D0FD3D5A507E37DEFB059D3B1DF9E9A1 -:106B0000C2E41F119DBB0F4B74FFAA1C57C72F1067 -:106B1000E7ADD5781F237B50C8F1CFC1F3C3FB3D50 -:106B2000D2F17116DAC39FFB167EEBB90F36610600 -:106B30001DE35A462A23DB8BF48E8956385F9186F3 -:106B4000DBC191ED0F17A871719E6FC73F8C0BD7FA -:106B500009FDE9848DC525A0FE93FC51B998E7B8DD -:106B6000EDA216FD2FF0EBDE0FB72FD9FB217A7CBB -:106B7000A4FDDEA8ACC779B441B93BEDB486F943B6 -:106B8000F4F62D7D51CC1FB2EE90DF01757ACCB3B7 -:106B9000748C26B98078C3BC4CA063F20E842FEAB3 -:106BA000391E0307C1BFE27115261705CF79B1E37E -:106BB000722ECAD9C8F3D61FBA4CF451E77BF4AA97 -:106BC00044E79F73519B7BE3F31FD97D3917F1771E -:106BD00051D757847E5440DF978B78A87F9DCBF3A5 -:106BE000EF7B0F6A7DF57A3D8FEF4916F2074BE494 -:106BF0002BE4C7074E703FBEBE6327C9D3C14E1EEC -:106C00004F7169BA4B5330FED070AE0BE5D9602A94 -:106C1000F7AF607E3BDEDB8C89420F6A07D2E783E9 -:106C20005C3B2AF2B5AA5F7701F9578FF378EBE85E -:106C30003D526E3443BBE212F233D457ACCA58878C -:106C4000747EC193849120F676EEFFD453FCED8DD3 -:106C5000688B4C762BD486E06FE81C1E993F9C61B4 -:106C6000AA9F1ECDEC21FD5C7AE5A7E41F9FE47985 -:106C700032D714CE4FEC10E727E7DA23FAD490F995 -:106C80005E52E587B01FE7BEF13FC497A76CF6538D -:106C900028CFA25116E27CA9711E4912FD8A827981 -:106CA0004073A7F0C7CB646A77F964361AC7A4C6E5 -:106CB00050BEBE8C6DD2A2BD3B977967F077327D16 -:106CC000FFF643689FF7869C8FEFB1C07EA6FC71EC -:106CD000699423B311ED238D24EED55B303F549F8F -:106CE00015727B6B862C911E1B181D4D76CA9C0558 -:106CF000CEC5B85FB55F9996EB339887EC2CE61953 -:106D0000C8C57C26F30FE4629E53ED77D71BD10DE7 -:106D1000A41799B7E0AE9075C61472BDF929E69F25 -:106D2000419EB844FEB344FEEA29F4A31A0FF33C93 -:106D300061AF26E33D7CAFE5867B46BC5E06BCDAF0 -:106D400051FF3898DD8EFC3335C983FCE3DA2731F7 -:106D50007CB756DF61D881719D7A5D5F32D2F306D0 -:106D6000DF5FF548CFAE03EFEA95A9389EC781C033 -:106D70005ED7E0FDBA84FE72FA6E7A0FE36ECE1330 -:106D80005C8B3AB5EF925F5FDBBE9FFCF73AE6277C -:106D9000FFBDAE2D9C5E0653799C3D923FC6142AE2 -:106DA000617C31672BE78BBB64D680728E89B8E932 -:106DB0009CD414B24782E3849D285F7E04ED97FE45 -:106DC00009925582A9FAA3DC6BD12E7267717BA65A -:106DD000FF4F2F162C23B9E229F819BE8B11F6EEBE -:106DE0009CF59BB572C87EE674F238617F14AB3AAD -:106DF00048F8768C453CA4E7958F2DE4EF6472E962 -:106E00009D8F86C73523CFF1AC88E39CC4384F4EA5 -:106E100070DFF3D2D2B81C631EA29F2E0D5F5F7D80 -:106E2000F7A28E5F21E869C81F92787C6A24B98234 -:106E300079944A9147A91479944A9147A91479946D -:106E40004A9147A91479944A9147A91479944A918F -:106E500047A9147914AC3F895BA5F7703B9F417A31 -:106E6000E8421E1B13847B1322E031E1FD7B13A457 -:106E700070788C44FD8B0B773EE3CEC138A645C8B5 -:106E8000252506EDAF0B261E5FEA8871CC2D84FA0E -:106E9000CA39CDBBF97B443BBD67294E58B818F9B8 -:106EA0006B30D1C0500EB90B1DF3111F274ECCCE45 -:106EB000DC4CF2D164C53C77EFDD37C7515CEE2D79 -:106EC00099C9B0E4CCECFCB50500CF344B44B720F5 -:106ED000277E50AEFA9330CFEC4E9ECF2891EB2A0E -:106EE00071FEC6D1A67C8A6BE53B161586C40F4A97 -:106EF000C72CCF443BA84BA7BC87F154F75F740C59 -:106F0000FD2835FEA6F6EBCD9B598DFB9A933D717E -:106F10006D1ECA1B602E946F763D6BC37DD935D133 -:106F20005233C92B458BFC5F2DF03D4BE1F6B05F32 -:106F3000AF6813D06F8F9A99E85678BEAA52E4AB27 -:106F40002A45BE0AF1730AE36650BE03F55876433C -:106F50003D9691EFB9761794AF24BA6503E9A1EF96 -:106F6000C1E6225F7139938EF4FC8288C367178A69 -:106F70007769F9E50FF2715E9AA756C4DF2EEBC26E -:106F8000F378EAB8E07846E51D3FE0F299C5E9F903 -:106F90007BD7B1CC8DEF69EF786D34C593021E8D30 -:106FA0005B170730F038CA2FF61AF76F592AE797A0 -:106FB0003B5E4DA17ECD220EEA4CE8CE4A40BD2B71 -:106FC000F84A850F7EC3DFF938F30086F275899F92 -:106FD000CF794777563CC001C9A4C1F8B873076F91 -:106FE000EF117CE79C20E613E761466F3AE2A3FFCE -:106FF000F06BE9F702BCD1EC5FC6E5BD3F8BE43432 -:10700000F367E17BA1CB92F72CBEB7FDF5C17F59A9 -:1070100084EF6B2FEBBCCF21FCDB8333382CED3FAF -:107020006B096D4FF2A6E37BDC5F1FFCE1227C9FC6 -:107030007B3969FF73F1D61058F7CA596CD73F3CBA -:10704000635131F49F67F09C6842BA7999D397698C -:10705000DF81F3783FB51DDC5E9FB5EFC0955750DB -:107060001F1F88A17CBDAF3083EEBBB963CF6348DF -:107070006F81FD3AE2838D6D7F7DEEB7D4CF4061A5 -:107080009479066F01865CDC457FBB1BF7352FDAF0 -:10709000FB19C29B8B6EA37DCE1BC5F9F9A9A2B9C2 -:1070A0008B903F0307F6FD0AF96F5E1C18B2B89F7C -:1070B000174D849F9A572717631C2010D35D81F3C7 -:1070C000D7BF60B0229DD6BC9A320BE302C70B79C2 -:1070D0007CBA7ACAA674D4AF9A43CFEFFE2DC629E4 -:1070E0005F30517EC695C0EDBB1AB9A56805E16F4A -:1070F000E76E7C371278DE4479D26A9803D7ABDE2C -:107100003D89E2EAAF7FFD4105E2A144DEBE1BEB13 -:107110003FDB65D2E03DF4E8ED713F423EECD191BA -:107120009F592DE0EADE517C3FD17DA584BFC44D3F -:10713000E9A85F6B46FDE676DCF73C79D373E8E7B8 -:10714000B03D06CA155C7C1EEE0DC65D6CD5D12B1C -:10715000D5C0F3315AA497CBD2A68A6770FE56DE0B -:10716000EFB26913DDA7BBF52686EB413F86F2EA55 -:10717000B2B439ACFE62EB9E5CF4432FBD308FFCA1 -:107180005195CE557EA9D96508D387240992C57B30 -:107190000952B36E66063D5B2DC04B07B7059E6175 -:1071A000C1F197DA747E3DDC51B581ADC5F7C12AD6 -:1071B0003FD4A4DD5686E7ABD1B464A1BD529DDFB8 -:1071C00057817C71D1C48CA9F88E4EE8AB9AF63504 -:1071D000F3D1EE1D693FB1E25DDFE7820F3FF79922 -:1071E0003CA1F9C1C8F26F4D4C3915F26EF89E06FC -:1071F00003D9EEEA7C6FEBBD75E89FD52770F97176 -:1072000016FAB7811C331771B9B76455787FA9880E -:10721000BF4BACD7F765A1DE53E7FFA650956B7D5A -:107220005928AF22C7CD9385BC7951227953D32EEB -:107230009D93E19E6A8C6E0FBEDFA94167929F53BA -:107240007B4DE2E3528BC4BDC3D8A78B3268DD9A75 -:107250003693DD04E36AA3FA62D11EAA8BE98B455B -:107260003B277048663B04BA1293057E2608948536 -:10727000C41DABBD3ABB2977183CA3DD84EF73F086 -:10728000BF61FDB622CE2755BE685A8F59FA8A9043 -:107290004EABB6878FC3735942F82FE0DB991CEAD7 -:1072A0008FDBC4BEFBA573C427FD5FBF9F8E78AF85 -:1072B000D1B0B59847BC24F1EF1E00A6EF1E2E8971 -:1072C0007C64CDDFCD51482F973EAF23BE0D487D66 -:1072D00024D7CE1C5C407229A0EB23B9D65354416D -:1072E000F22110DF578172EACCC17ADE3EBAAF429A -:1072F00081F64E84B17D1C237D7FB9E801921FF396 -:1073000064FEBE81EDD459781C687D6F13F9153A7F -:1073100025D4EFBE52A4E66DF4C173CB41BE093053 -:10732000655F3BF2619599E239603FB5BD8276DEDB -:10733000C2642BC6C5AB701CA7037D68FE2F31E16C -:10734000CB65889F45718E3B8B308F9DD347FE0365 -:107350005035D9E9F57F32901FD9AF1BD88D722AED -:1073600037CEB1B008F651A7EF5E87A1A72BBABE02 -:107370002ECCFBCD95B93C627B385D057276F2EF81 -:107380002444FEB0BA88CB5FD05BAC05E942E2F89A -:107390003DE67BF514CA9540F74492C7917C73D1C2 -:1073A000F7442CCA87D3A0C7DD217EFEE9A57B2840 -:1073B0004FBF00DF654079EFDA707A18FCEA67E4C6 -:1073C000EFB1C742EA910EB784C3917484F4E80F19 -:1073D000933B6EA29B3D82AF6A6775D7E33D0CC1BC -:1073E00077002C87C04723E088FEAC9CDB097BF04C -:1073F000BF61DEBA71FE5EF2CFF7F177B1CDA0BF0B -:10740000083E104D7963CD3ED04F895C3FA15EA808 -:107410008DEDA6B854E08081F2230F777C4CEF19F4 -:10742000810E29FE52DBF15A32FAED3EF4139248F6 -:107430000F26D33B95031DC9E86FA8F5751A6F9603 -:10744000788F4F76BA5AEF94FD59B8FF5AA93B1777 -:10745000DB7D8516D11F60196146E7A89338BFB35D -:107460000E99E47924DEF60A7A05B9904BEF2C0EDA -:10747000F1B8802A07AA853C398AF5399CEF2D6A34 -:107480005E49C2F772D1C3CA879B8A547BB881E236 -:1074900036BB8A147EAF623CCDCBE34AD45EFFFAA2 -:1074A000E5DC0939384E11E342E4D0C4A05C41FE6A -:1074B0004F25FE7F58970CE7AA794EB236A39C5A07 -:1074C000BCA614BAB3E5DA15A5142F13EF3F23F7C2 -:1074D000154947F6228EDF1A4D7C4962C87C97C059 -:1074E0005D4FCD233943EFE8EF4F7CBC14E313BF6E -:1074F00058BC99E87948DF84F2399E673B97E3C826 -:1075000036D734D7D3F1F286967529C3EC23729F10 -:10751000D58E96D264E5FA7A75BF974CEAFE66E995 -:107520009242EF61C19AD22428971BFFD17BE0E7FA -:10753000BDD461F0A35EAD5EBC625DDC3074739D52 -:107540003ED81EA2BF26207E3D94D71869FF9165C4 -:107550009DE4EFC5381103BE6A25FE027E09D10BFA -:107560006542BF0EC51BAA968E47BF9339968E47BC -:107570003D037C55611DC6AFC42F4B34F476C34D1B -:1075800065E47E3E2BE271D2B222CE2FA76CF66F5D -:1075900050BE8EF4BD85619AF4ADDF5BA46906DF51 -:1075A000417E4B4B8E51300F54323B9AF73B6CB2BD -:1075B00060DCA6FFF09714D7ED7FC4BC80E70BCC4E -:1075C0006C34B477A54EDD11AA473CD3385F46171B -:1075D00070BBC595ADFBF6B8504ECC505C88EC86C0 -:1075E0009C68CA93047C9F92DEEAEF2CB4603E2331 -:1075F000D00DDE21F093EBEBFF4A46FD1AE8FC8844 -:10760000DE8305BEFA98DE896D10EFF48EFAC43B76 -:10761000AB6E2586BE8B2BFBA014FB6D1465303E34 -:10762000C0E35A6AA9FAFF21FEEF946985C3FABF45 -:10763000090E73685C4049192E8E121A17C8D4F2CD -:10764000B800961817C8CCE4710184312E8025C685 -:1076500005B01EE30208635C00618C0B208C710195 -:107660002C312E80F59F89EF1FFA4130F178A599D2 -:10767000E4FA4A7CDF0EF7B7F230CF3BAD6C9529C8 -:107680007F8BDF3FA07EBBEEDD4CBB7837E3DD4C6C -:10769000793CD701D98A2872E9068E631CC7B55F89 -:1076A000B2AE41B9D2B480D6DFD059F8DE62AC6F49 -:1076B000D559350AD111C7638B44EFF46B3A5B2976 -:1076C000EE549C72584FF56D12C338E95D06EEE733 -:1076D0003A65A8CDA33C28D9C14E4337F91FB57BE5 -:1076E00025A532F49DC6F4AB2407D47CF232DEC467 -:1076F0009C5E935239CC3B90A177E7E2DDF432CC2B -:1077000033E37B71F92B7AD7EF04877414D2E156F7 -:10771000FEFED902FF88DF23DE35D574EE5F87EFEA -:10772000A122F3CD43DFD345E49DEBA789BCB28D05 -:107730007F5F51F664E5BE03B0DEE02603D91BEEA1 -:1077400042C703D39230EF6FA7F8C8F1C326F28B7C -:107750003EDC7C53587C84E53B1E9C46F9F9B11411 -:10776000AF68D449A48F67974D4CC17B9C7D42473D -:107770007AA737AF7C35F66B9CAA503CAAC4C01ED2 -:10778000A079C47B29151F25CD924703F05266A529 -:1077900077F64BE09A305ED9AF33AFC7774D4B18D1 -:1077A0007FE7A0D24DE36689E8060304789F15E2DF -:1077B0003E9774FEF94B7CC7709F81DBAD691A9EC2 -:1077C000BF4EDBC8DF33DCCF1C7AD4B3CB91BA64B5 -:1077D000D28F7FEA837A47F4D8746E972B2938FFCB -:1077E000D2933A7A6F5B92F2932C07E9E9627AC7F7 -:1077F00020F917C9D76E1E997F22DF311CD771B9C6 -:1078000002F748FE5017D225C5651C549E6CAAA2EB -:10781000F277E27B88EBDFFF0F9C453F312D25C6D9 -:107820008A726EC4EFDDA2BEFD7BAF17C4FBB53418 -:107830004D4FBE82F7F177B315EF437D2778CA56D7 -:10784000BE1FF1648F656E0B7D0F061210EEB5142E -:107850000F22615CDB6BC7EF8E060E4B167A977CAE -:107860009D7CDCFC08BE1371654A1649C1F8F7A679 -:107870009264D877E9840CDAB7CBC7E3A37443C921 -:10788000183FE7F84ACF731C9B5618AC9F27F82681 -:1078900000FD399DFCD083F4F61DE2A6BBB0BF9B72 -:1078A00099E87B6AFA83FDCCBB791CC54F55BA19A0 -:1078B0006C4BD98174F39E90FB8B17BFAB43FDDFFC -:1078C0009BEFE8C17D54545E7D2499CE377CFC4A01 -:1078D0007DA71E19BF0A959FFF3FDEA79F6A6AA07A -:1078E000F29DA655547637B9A93D44FE5F1A41FE74 -:1078F00047C63FAF227F47C63F99518923FD09FC08 -:10790000CDE3CD11F1CEB251F7AE87FB9BBD456FF4 -:10791000C52A35FE89EF87579A491EFCF7B461E303 -:107920009EEABD99294E3AC84C7978FFB3B2276ACE -:1079300035D0AE9DCEF1A7C61D913FF07CC81F5833 -:10794000227F68B541FE78560F2C5CC0F5BC9BF4D5 -:10795000BC89F0BA6E0DC80F80EF639630F97125BF -:10796000427E80C371377D57D56960182754DF5137 -:10797000CE82E28BBC61E48997CB937151DEE7E95B -:107980007BFFFA287A9F7B5CBC873BBE81BF87ABBD -:1079900064E5B4EE30722516F171DFA881B37F8003 -:1079A000FEF7FDDE4CF6CABAD1CB8AFE19B9724D8C -:1079B0007CD7F234FEAE80F6DB7E57E03109F3A1CE -:1079C0008DF7301BE259FD5D811491CFFE1EBF2B58 -:1079D000306D7AE177FF5D815BA78F5F1CFABB0298 -:1079E000B7FA3238ACFEAE001BBF7884DF15983D85 -:1079F0003DE9FADF15B86D3AF71747FA5D01B02790 -:107A0000CB705C92CD3E07CB34B1CFC8EF694F8AC3 -:107A1000FC5D97C6B118CBD258B796EA359E02FAEC -:107A20000E5EE3FD25F981F98E9FE3794B9FB04D02 -:107A3000C90638CDE02539D99B67BF13EBAFD9EC28 -:107A400077E13A917173C42DFAF7B09FBBB13DF263 -:107A5000DD958ACF15D3B9DC6814E58CE6E1BF2744 -:107A60006F9CCEF3F237DA37ECB706D71BDAFFA6F6 -:107A7000A505B81FD86F2DD6C37EEBB064E684B0E1 -:107A8000EF53AFA73337D155E3744E5F20CFE67D78 -:107A9000C8ED412AB3B49E78B41FC73CE489C7FD42 -:107AA0008E691930E177107F740F9850BFFF71F520 -:107AB0008009EBFF68E7EF9523E77F793AF703B298 -:107AC000660CD0F8F168E3937D3E108FF65356D5DF -:107AD00087EB28DFB27732E997F142BF8C7F68826B -:107AE000AF0FE86DFCB638CA67B3E2446AAF3172D3 -:107AF0003EAD79A8F2E00185BEDB9AF76188BD331F -:107B0000D903FB0EB3BFB483FCDD25C0784F7B7572 -:107B10000423CDA27DE564FCDDE5182137D04E5B62 -:107B20000C72C159F5E69794F7C7F1381FE66891D2 -:107B3000FE7CBA41F17D9A05FDD0E50BD674915FCC -:107B4000B875A85EF899FBD7A1DF0CF65B587D4DA0 -:107B5000E5912ED437B57BC3EB9D0D57C97F05FB4F -:107B60002DACFE9E5F9ED3F3DF2F08AF07FCEE45E2 -:107B7000BA54F17B5CE79D8C7EDE71679495BFDF24 -:107B8000F7D2EF95EC10DF3FEFFC8F599C6E04BEEF -:107B900061BC3774FCC8F4D14CFDDDB35836F2C378 -:107BA0008D4A552E0DFDFE899EB929BE373786E4D4 -:107BB0008E4BF855F59516D2F369F546925F25720E -:107BC0009415E1A1DF3F2993859CF212FFF7DC1E9B -:107BD0004F713C3A00C2095329EF93DCCCE1812478 -:107BE00003C987124D79DD1E28DFD4847FC7FE2CA0 -:107BF000CA0719F9977F87E9D27BF977E25AA5106E -:107C0000FDDC66C9BE0DBF7B6C96441CB1DA4CF935 -:107C1000827E8C2FC279B6C47BB62D8375B6DC9973 -:107C200043F6713FE3F2D4BD80E7ADB6C4972F5E53 -:107C300081ED0BA750FBC16F263E5E80F653759415 -:107C400015EDA72D366E5F6F999F4DEDAF4BCA1A9C -:107C50003CB7FB2146EB6C99CFCFBDE5F171E2FB60 -:107C60000B8F09F9794B8B7D34E6A366591C1710ED -:107C70005F63443E6E4B06D443F99454BEF07E9C41 -:107C8000672ADFEFEF6C0AC98FE30BA73CBE5B21CD -:107C900035E2C7BC906B6E0CF9C1FF0BB81F749432 -:107CA000704700000000000000000000000000001D -:087CB00005020D0000000000B8 -:00000001FF diff --git a/firmware/bnx2x-e1h-5.2.13.0.fw.ihex b/firmware/bnx2x-e1h-5.2.13.0.fw.ihex deleted file mode 100644 index ea3e254335b1845bb646be5db265343978c0f7e4..0000000000000000000000000000000000000000 --- a/firmware/bnx2x-e1h-5.2.13.0.fw.ihex +++ /dev/null @@ -1,12849 +0,0 @@ -:1000000000003BE8000000600000068800003C5053 -:1000100000001968000042E0000000AC00005C50E5 -:1000200000008DF800005D00000000E80000EB001B -:100030000000E3140000EBF0000000940001CF0882 -:10004000000058E80001CFA0000000C40002289082 -:100050000000F9640002295800000004000322C0D7 -:10006000020400480000000F020400540000004594 -:1000700002040058000000840204005C0000000636 -:100080000204007000000004020400780000000078 -:100090000204007C121700000204008022170000F6 -:1000A00002040084321700000604008800000005E6 -:1000B0000204009C12150000020400A0221500009A -:1000C000020400A432150000060400A80000000489 -:1000D000020400B802100000020400BC001000007E -:1000E000020400C010100000020400C42010000030 -:1000F000020400C830100000020400CC40100000D0 -:10010000060400D000000003020400DC0010000020 -:10011000020400E012140000020400E422140000B3 -:10012000020400E832140000020400EC4214000053 -:10013000060400F000000003010401240000000098 -:1001400001040128000000000104012C000000004F -:100150000104013000000000020401D00000890603 -:1001600002040004000000FF02040008000000FF79 -:100170000204000C000000FF02040010000000FF59 -:1001800002040014000000FF02040018000000FF39 -:100190000204001C000000FF02040020000000FF19 -:1001A000020400240000003E0204002800000000B9 -:1001B0000204002C0000003F020400300000003F59 -:1001C000020400340000003F020400380000003F39 -:1001D0000204003C0000003F020400400000003F19 -:1001E000020400440000003F020404CC00000001AF -:1001F00002042008000002110204200C000002008A -:10020000020420100000020402042014000002195D -:100210000204201C0000FFFF020420200000FFFF5A -:10022000020420240000FFFF020420280000FFFF3A -:1002300002042038000000200204203C00000000DE -:100240000204204000000034020420440000003575 -:10025000060420480000001C020420B80000000131 -:10026000060420BC0000005F0204223807FFFFFFE5 -:100270000204223C0000003F0204224007FFFFFF6F -:10028000020422440000000F010422480000000084 -:100290000104224C00000000010422500000000074 -:1002A0000104225400000000010422580000000054 -:1002B0000104225C00000000010422600000000034 -:1002C0000104226400000000010422680000000014 -:1002D0000104226C000000000104227000000000F4 -:1002E00001042274000000000104227800000000D4 -:1002F0000104227C000000000C042000000003E840 -:100300000A042000000000010B0420000000000A85 -:1003100002050044000000200205004800000032F1 -:10032000020500900215002002050094021500202D -:1003300002050098000000300205009C0810000033 -:10034000020500A000000033020500A400000030F8 -:10035000020500A800000031020500AC0000000208 -:10036000020500B000000005020500B40000000610 -:10037000020500B800000002020500BC00000002F7 -:10038000020500C000000000020500C400000005D6 -:10039000020500C800000002020500CC00000002B7 -:1003A000020500D000000002020500D40000000198 -:1003B00002050114000000010205011C00000001FB -:1003C00002050120000000020205020400000001F5 -:1003D0000205020C0000004002050210000000406F -:1003E0000205021C0000002002050220000000138C -:1003F0000205022400000020060502400000000A59 -:1004000004050280002000000205005000000007E3 -:100410000205005400000007020500580000000813 -:100420000205005C000000080205006000000001F9 -:100430000605006400000003020500D80000000665 -:100440000205000400000001020500080000000190 -:100450000205000C00000001020500100000000170 -:100460000205001400000001020500180000000150 -:100470000205001C00000001020500200000000130 -:100480000205002400000001020500280000000110 -:100490000205002C000000010205003000000001F0 -:1004A00002050034000000010205003800000001D0 -:1004B0000205003C000000010205004000000001B0 -:1004C000020500E00000000D020500E80000000742 -:1004D000020500F000000007020500F80000000718 -:1004E000020500E40000002D020500EC00000027DA -:1004F000020500F400000027020500FC00000027B0 -:10050000020500E00000001D020500E800000017E1 -:10051000020500F000000017020500F800000017B7 -:10052000020500E40000003D020500EC0000003779 -:10053000020500F400000037020500FC000000374F -:10054000020500E00000004D020500E80000004741 -:10055000020500F000000047020500F80000004717 -:10056000020500E40000006D020500EC00000067D9 -:10057000020500F400000067020500FC00000067AF -:10058000020500E00000005D020500E800000057E1 -:10059000020500F000000057020500F800000057B7 -:1005A000020500E40000007D020500EC0000007779 -:1005B000020500F400000077020500FC000000774F -:1005C0000406100002000020020600DC000000010A -:1005D000010600D80000000004060200000302200B -:1005E000020600DC00000000010600B80000000068 -:1005F000010600C800000000010600BC0000000069 -:10060000010600CC000000000718040000A900004B -:10061000081807C800070223071C00002C2C000044 -:10062000071C800038930B0C071D0000293119317D -:10063000081D686052F40225011800000000000047 -:10064000011800040000000001180008000000006C -:100650000118000C0000000001180010000000004C -:100660000118001400000000021800200000000122 -:1006700002180024000000020218002800000003F5 -:100680000218002C000000000218003000000004D6 -:1006900002180034000000010218003800000000B9 -:1006A0000218003C00000001021800400000000495 -:1006B0000218004400000000021800480000000179 -:1006C0000218004C00000003021800500000000057 -:1006D0000218005400000001021800580000000435 -:1006E0000218005C00000000021800600000000119 -:1006F00002180064000000030218006800000000F7 -:100700000218006C000000010218007000000004D4 -:1007100002180074000000000218007800000004B5 -:100720000218007C00000003061800800000000290 -:10073000021800A400003FFF021800A8000003FFF9 -:100740000218022400000000021802340000000019 -:100750000218024C00000000021802E4000000FF32 -:100760000618100000000400021B8BC000000001EE -:10077000021B800000000034021B804000000018B3 -:10078000021B80800000000C021B80C000000020C3 -:100790000C1B83000007A1200A1B83000000013806 -:1007A0000B1B830000001388021B83C0000001F4B0 -:1007B000021B1480000000010A1B148000000000CE -:1007C000061A1000000003B3041A1ECC0001022711 -:1007D000061AA020000000C8061AA00000000002AF -:1007E000021A1ED000000000061A1ED800000006E3 -:1007F000061A36E800000004061A36E0000000027F -:10080000061A500000000002061A500800000004FA -:10081000061A501800000004061A502800000004B0 -:10082000061A503800000004061A50480000000460 -:10083000061A505800000004061A50680000000410 -:10084000061A507800000002041A404000020228F4 -:10085000061A400000000002061A400800000002CC -:10086000041A62C00020022A061AD1000000000209 -:10087000061A200000000124061AB000000000281B -:10088000061AB1400000000C061A330000000014E4 -:10089000061A33A000000068061A81080000000252 -:1008A000061AD1C800000002061AD1D800000020A4 -:1008B000061A249000000124061AB0A000000028A7 -:1008C000061AB1700000000C061A33500000001424 -:1008D000061A354000000068061A81100000000268 -:1008E000061AD1D000000002061AD25800000020DB -:1008F000021A292000000000061A30000000000241 -:10090000041A30080005024A061A301C00000009CB -:10091000061A320000000008061A5000000000020B -:10092000061A508000000012061A40000000000263 -:10093000061AD0C000000002021A2924000000009C -:10094000061A304000000002041A30480005024F29 -:10095000061A305C00000009061A32200000000868 -:10096000061A501000000002061A50C800000012BB -:10097000061A400800000002061AD0C80000000253 -:10098000021A292800000000061A30800000000228 -:10099000041A308800050254061A309C0000000931 -:1009A000061A324000000008061A5020000000021B -:1009B000061A511000000012041A401000020259D9 -:1009C000061AD0D000000002021A292C00000000F4 -:1009D000061A30C000000002041A30C80005025B8D -:1009E000061A30DC00000009061A32600000000818 -:1009F000061A503000000002061A5158000000127A -:100A0000041A401800020260061AD0D80000000242 -:100A1000021A293000000000061A3100000000020E -:100A2000041A310800050262061A311C0000000990 -:100A3000061A328000000008061A5040000000022A -:100A4000061A51A000000012041A4020000202679A -:100A5000061AD0E000000002021A2934000000004B -:100A6000061A314000000002041A314800050269EC -:100A7000061A315C00000009061A32A000000008C6 -:100A8000061A505000000002061A51E80000001239 -:100A9000041A40280002026E061AD0E80000000284 -:100AA000021A293800000000061A318000000002F6 -:100AB000041A318800050270061A319C00000009F2 -:100AC000061A32C000000008061A5060000000023A -:100AD000061A523000000012041A4030000202755B -:100AE000061AD0F000000002021A293C00000000A3 -:100AF000061A31C000000002041A31C8000502774E -:100B0000061A31DC00000009061A32E00000000875 -:100B1000061A507000000002061A527800000012F7 -:100B2000041A40380002027C061AD0F800000002C5 -:100B30000200A294071D29110200A29800000000E3 -:100B40000200A29C009C04240200A2A0000000005D -:100B50000200A2A4000002090200A270000000002E -:100B60000200A274000000000200A2700000000059 -:100B70000200A274000000000200A2700000000049 -:100B80000200A274000000000200A2700000000039 -:100B90000200A27400000000020100B40000000185 -:100BA000020100B800000001020100DC00000001A9 -:100BB0000201010000000001020101040000000127 -:100BC0000201007C003000000201008400000028C7 -:100BD0000201008C0000000002010130000000044E -:100BE0000201025C00000001020103280000000075 -:100BF0000201607000000007020160800000000137 -:100C00000201055400000030020100C40000000190 -:100C1000020100CC00000001020100F80000000108 -:100C2000020100F00000000102010080003000001D -:100C3000020100880000002802010090000000006E -:100C40000201013400000004020102DC0000000186 -:100C50000201032C00000000020160740000000784 -:100C60000201608400000001020105640000003000 -:100C7000020100C800000001020100D000000001D4 -:100C8000020100FC00000001020100F4000000016C -:100C9000020C100000000020020C200800000211CD -:100CA000020C200C00000200020C201000000204C4 -:100CB000020C201C0000FFFF020C20200000FFFFA0 -:100CC000020C20240000FFFF020C20280000FFFF80 -:100CD000060C203800000002020C20400000003406 -:100CE000020C204400000035020C204800000020C7 -:100CF000020C204C00000021020C205000000022B9 -:100D0000020C205400000023020C20580000002494 -:100D1000020C205C00000025020C20600000002670 -:100D2000020C206400000027020C2068000000284C -:100D3000020C206C00000029020C20700000002A28 -:100D4000020C20740000002B060C207800000056D6 -:100D5000020C21D000000001020C21D4000000018F -:100D6000020C21D800000001020C21DC000000016F -:100D7000020C21E000000001020C21E4000000014F -:100D8000020C21E800000001020C21EC000000012F -:100D9000020C21F000000001020C21F4000000010F -:100DA000060C21F800000010020C223807FFFFFF9C -:100DB000020C223C0000003F020C224007FFFFFF14 -:100DC000020C22440000000F010C22480000000029 -:100DD000010C224C00000000010C22500000000019 -:100DE000010C225400000000010C225800000000F9 -:100DF000010C225C00000000010C226000000000D9 -:100E0000010C226400000000010C226800000000B8 -:100E1000010C226C00000000010C22700000000098 -:100E2000010C227400000000010C22780000000078 -:100E3000010C227C000000000C0C2000000003E8E4 -:100E40000A0C2000000000010B0C20000000000A2A -:100E5000020C400800000411020C400C00000400C9 -:100E6000020C401000000404020C40140000042195 -:100E7000020C401C0000FFFF020C40200000FFFF9E -:100E8000020C40240000FFFF020C40280000FFFF7E -:100E9000020C403800000046020C403C00000005F7 -:100EA000060C404000000002020C40480000000A0E -:100EB000020C404C000000F0060C40500000001FE7 -:100EC000020C40CC00000001060C40D00000003AAB -:100ED000020C41B800000001060C41BC00000003F8 -:100EE000020C41C800000001020C41CC00000001CE -:100EF000060C41D00000001A020C423807FFFFFF29 -:100F0000020C423C0000003F020C424007FFFFFF82 -:100F1000020C42440000000F010C42480000000097 -:100F2000010C424C00000000010C42500000000087 -:100F3000010C425400000000010C42580000000067 -:100F4000010C425C00000000010C42600000000047 -:100F5000010C426400000000010C42680000000027 -:100F6000010C426C00000000010C42700000000007 -:100F7000010C427400000000010C427800000000E7 -:100F8000010C427C00000000010C428000000000C7 -:100F90000C0C4000000003E80A0C400000000001B7 -:100FA0000B0C40000000000A020D0044000000325B -:100FB000020D008C02150020020D00900215002089 -:100FC000020D009408100000020D0098000000338C -:100FD000020D009C00000002020D00A000000000B5 -:100FE000020D00A400000005020D00A8000000058D -:100FF000060D00AC00000002020D00B4000000026B -:10100000020D00B800000003020D00BC0000000249 -:10101000020D00C000000001020D00C80000000227 -:10102000020D00CC00000002020D010800000001CA -:10103000020D015C00000001020D016400000001CE -:10104000020D016800000002020D02040000000110 -:10105000020D020C00000020020D021000000040F2 -:10106000020D021400000040020D022000000003E7 -:10107000020D022400000018060D0280000000127C -:10108000040D03000024027E020D004C000000014C -:10109000020D005000000002020D00540000000884 -:1010A000020D005800000008060D005C000000045E -:1010B000020D00C400000004020D00040000000145 -:1010C000020D000800000001020D000C00000001EC -:1010D000020D001000000001020D001400000001CC -:1010E000020D001800000001020D001C00000001AC -:1010F000020D002000000001020D0024000000018C -:10110000020D002800000001020D002C000000016B -:10111000020D003000000001020D0034000000014B -:10112000020D003800000001020D003C000000012B -:10113000020D011400000009020D011C0000000A4C -:10114000020D012400000007020D012C0000000721 -:10115000020D01340000000C020D013C0000000BE8 -:10116000020D014400000007020D011800000029D3 -:10117000020D01200000002A020D012800000027B6 -:10118000020D013000000027020D01380000002C84 -:10119000020D01400000002B020D01480000002755 -:1011A000020D011400000019020D011C0000001ABC -:1011B000020D012400000017020D012C0000001791 -:1011C000020D01340000001C020D013C0000001B58 -:1011D000020D014400000017020D01180000003943 -:1011E000020D01200000003A020D01280000003726 -:1011F000020D013000000037020D01380000003CF4 -:10120000020D01400000003B020D014800000037C4 -:10121000020D011400000049020D011C0000004AEB -:10122000020D012400000047020D012C00000047C0 -:10123000020D01340000004C020D013C0000004B87 -:10124000020D014400000047020D01180000006972 -:10125000020D01200000006A020D01280000006755 -:10126000020D013000000067020D01380000006C23 -:10127000020D01400000006B020D014800000067F4 -:10128000020D011400000059020D011C0000005A5B -:10129000020D012400000057020D012C0000005730 -:1012A000020D01340000005C020D013C0000005BF7 -:1012B000020D014400000057020D011800000079E2 -:1012C000020D01200000007A020D012800000077C5 -:1012D000020D013000000077020D01380000007C93 -:1012E000020D01400000007B020D01480000007764 -:1012F000020E004C00000032020E00940215002085 -:10130000020E009802150020020E009C0000003022 -:10131000020E00A008100000020E00A4000000331E -:10132000020E00A800000030020E00AC00000031E8 -:10133000020E00B000000002020E00B40000000423 -:10134000020E00B800000000020E00BC0000000207 -:10135000020E00C000000002020E00C400000000E7 -:10136000020E00C800000002020E00CC00000007C0 -:10137000020E00D000000002020E00D400000002A5 -:10138000020E00D800000001020E00E4000000017F -:10139000020E014400000001020E014C0000000199 -:1013A000020E015000000002020E020400000001C3 -:1013B000020E020C00000040020E0210000000406D -:1013C000020E021C00000004020E02200000002099 -:1013D000020E02240000000E020E02280000001B74 -:1013E000060E030000000012040E0280001B02A281 -:1013F000020E00540000000C020E0058000000090C -:10140000020E005C0000000F020E006000000010E1 -:10141000020E00640000000B060E006800000003CE -:10142000020E00DC00000003020E000400000001B8 -:10143000020E000800000001020E000C0000000176 -:10144000020E001000000001020E00140000000156 -:10145000020E001800000001020E001C0000000136 -:10146000020E002000000001020E00240000000116 -:10147000020E002800000001020E002C00000001F6 -:10148000020E003000000001020E003400000001D6 -:10149000020E003800000001020E003C00000001B6 -:1014A000020E004000000001020E00440000000196 -:1014B000020E01100000000F020E01180000000EC5 -:1014C000020E012000000000020E012800000000B2 -:1014D000020E01140000002F020E011C0000002E5D -:1014E000020E012400000000020E012C000000008A -:1014F000020E01100000001F020E01180000001E65 -:10150000020E012000000000020E01280000000071 -:10151000020E01140000003F020E011C0000003EFC -:10152000020E012400000000020E012C0000000049 -:10153000020E01100000004F020E01180000004EC4 -:10154000020E012000000000020E01280000000031 -:10155000020E01140000006F020E011C0000006E5C -:10156000020E012400000000020E012C0000000009 -:10157000020E01100000005F020E01180000005E64 -:10158000020E012000000000020E012800000000F1 -:10159000020E01140000007F020E011C0000007EFC -:1015A000020E012400000000020E012C00000000C9 -:1015B0000730040000E50000083007D8000502BD30 -:1015C000073400002EF7000007348000311A0BBEEC -:1015D00007350000356F18050735800038C42561D0 -:1015E0000736000014C5339308363400398002BF33 -:1015F0000130000000000000013000040000000085 -:1016000001300008000000000130000C0000000064 -:101610000130001000000000013000140000000044 -:10162000023000200000000102300024000000020F -:1016300002300028000000030230002C00000000EF -:1016400002300030000000040230003400000001CD -:1016500002300038000000000230003C00000001B1 -:10166000023000400000000402300044000000008E -:1016700002300048000000010230004C000000036E -:101680000230005000000000023000540000000151 -:1016900002300058000000040230005C000000002E -:1016A000023000600000000102300064000000030E -:1016B00002300068000000000230006C00000001F1 -:1016C00002300070000000040230007400000000CE -:1016D00002300078000000040230007C00000003AB -:1016E0000630008000000002023000A400003FFF2E -:1016F000023000A8000003FF0230022400000000B6 -:1017000002300234000000000230024C00000000F1 -:10171000023002E40000FFFF063020000000080055 -:1017200002338BC000000001023380000000001A69 -:10173000023380400000004E023380800000001021 -:10174000023380C0000000200C3383000007A1207A -:101750000A338300000001380B3383000000138834 -:10176000023383C0000001F40C3383801DCD65007B -:101770000A3383800004C4B40B338380004C4B4095 -:101780000A331480000000000233148000000001BE -:10179000063220000000010206328020000000C84E -:1017A000063280000000000206323DA8000000045E -:1017B00006323D800000000904323DA4000102C150 -:1017C00006323D00000000200632500000000400F8 -:1017D0000632400000000004063240D00000000243 -:1017E00006326B680000000204326B70000202C215 -:1017F00006326B1000000002043274C0000202C402 -:101800000632DA40000000020632E0000000080064 -:10181000023308000100000004330C00001002C66F -:10182000023308000000000004330C40001002D610 -:1018300006322450000000B406322AD00000000214 -:1018400006321000000001A002323DB80000000086 -:101850000632500000000020063251000000002037 -:101860000632520000000020063253000000002023 -:10187000063254000000002006325500000000200F -:1018800006325600000000200632570000000020FB -:1018900006325800000000200632590000000020E7 -:1018A00006325A000000002006325B0000000020D3 -:1018B00006325C000000002006325D0000000020BF -:1018C00006325E000000002006325F0000000020AB -:1018D00006326B780000005206326E080000000CE1 -:1018E0000632DA880000000206322720000000B429 -:1018F00006322AD80000000206321680000001A03D -:1019000002323DBC00000000063250800000002082 -:101910000632518000000020063252800000002074 -:101920000632538000000020063254800000002060 -:10193000063255800000002006325680000000204C -:101940000632578000000020063258800000002038 -:10195000063259800000002006325A800000002024 -:1019600006325B800000002006325C800000002010 -:1019700006325D800000002006325E8000000020FC -:1019800006325F800000002006326CC0000000526A -:1019900006326E380000000C0632DA9000000002B9 -:1019A00002322A300000000006324010000000021F -:1019B0000632D0000000000602322A340000000087 -:1019C00006324020000000020632D0180000000657 -:1019D00002322A38000000000632403000000002C7 -:1019E0000632D0300000000602322A3C000000001F -:1019F00006324040000000020632D04800000006D7 -:101A000002322A400000000006324050000000026E -:101A10000632D0600000000602322A4400000000B6 -:101A200006324060000000020632D0780000000656 -:101A300002322A4800000000063240700000000216 -:101A40000632D0900000000602322A4C000000004E -:101A500006324080000000020632D0A800000006D6 -:101A6000072004000093000008200780001002E611 -:101A7000072400002ADE0000072480002E050AB893 -:101A80000824E4A061D202E8012000000000000068 -:101A900001200004000000000120000800000000F8 -:101AA0000120000C000000000120001000000000D8 -:101AB00001200014000000000220002000000001AE -:101AC0000220002400000002022000280000000381 -:101AD0000220002C00000000022000300000000462 -:101AE0000220003400000001022000380000000045 -:101AF0000220003C00000001022000400000000421 -:101B00000220004400000000022000480000000104 -:101B10000220004C000000030220005000000000E2 -:101B200002200054000000010220005800000004C0 -:101B30000220005C000000000220006000000001A4 -:101B40000220006400000003022000680000000082 -:101B50000220006C00000001022000700000000460 -:101B60000220007400000000022000780000000441 -:101B70000220007C0000000306200080000000021C -:101B8000022000A400003FFF022000A8000003FF85 -:101B900002200224000000000220023400000000A5 -:101BA0000220024C00000000022002E40000FFFFBF -:101BB000062020000000080002238BC00000000166 -:101BC0000223800000000010022380400000001269 -:101BD0000223808000000030022380C00000000E3D -:101BE000022383C0000001F40223148000000001DE -:101BF0000A231480000000000622100000000042AA -:101C000006227020000000C80622700000000002BA -:101C1000022211E80000000006223000000000C08F -:101C2000062240700000008006225280000000045E -:101C30000622670000000100062290000000040058 -:101C400004226B08002002EA02230800013FFFFF84 -:101C500004230C000010030A022308000000000007 -:101C600004230C400010031A06228100000000A08B -:101C7000062286000000004006228C000000003C86 -:101C80000622B0000000020006228800000000804A -:101C900006228DE00000003C0622404000000006C5 -:101CA00006228380000000A006228700000000407A -:101CB00006228CF00000003C0622B8000000020062 -:101CC00006228A000000008006228ED00000003C20 -:101CD000062240580000000606228000000000088E -:101CE000022211480000000006223300000000021A -:101CF000062260400000003006228020000000081C -:101D00000222114C000000000622330800000002ED -:101D1000062261000000003006228040000000081A -:101D200002221150000000000622331000000002C1 -:101D3000062261C00000003006228060000000081A -:101D40000222115400000000062233180000000295 -:101D50000622628000000030062280800000000819 -:101D60000222115800000000062233200000000269 -:101D70000622634000000030062280A00000000818 -:101D80000222115C0000000006223328000000023D -:101D90000622640000000030062280C00000000817 -:101DA0000222116000000000062233300000000211 -:101DB000062264C000000030062280E00000000817 -:101DC00002221164000000000622333800000002E5 -:101DD0000622658000000030021610000000002876 -:101DE00002170008000000020217002C0000000388 -:101DF0000217003C00000004021700440000000825 -:101E000002170048000000020217004C000000907A -:101E1000021700500000009002170054008000904C -:101E20000217005808140000021700600000008A22 -:101E300002170064000000800217006800000081A3 -:101E40000217006C000000800217007000000006FE -:101E500002170078000007D00217007C0000076C12 -:101E600002170038007C1004021700040000000F65 -:101E70000616402400000002021640700000001CFC -:101E80000216420800000001021642100000000184 -:101E90000216422000000001021642280000000144 -:101EA0000216423000000001021642380000000114 -:101EB00002164260000000020C16401C0003D09085 -:101EC0000A16401C0000009C0B16401C000009C4B0 -:101ED0000216403000000008021640340000000CDA -:101EE0000216403800000010021640440000002096 -:101EF0000216400000000001021640D80000000158 -:101F000002164008000000010216400C000000010B -:101F100002164010000000010216424000000000BE -:101F2000021642480000000006164270000000023F -:101F30000216425000000000021642580000000045 -:101F40000616428000000002021660080000042409 -:101F50000216600C00000410021660100000041449 -:101F60000216601C0000FFFF021660200000FFFF49 -:101F7000021660240000FFFF021660280000FFFF29 -:101F800002166038000000200216603C00000020AD -:101F90000216604000000034021660440000003564 -:101FA00002166048000000230216604C0000002466 -:101FB0000216605000000025021660540000002642 -:101FC00002166058000000270216605C000000291D -:101FD000021660600000002A021660640000002BF8 -:101FE000021660680000002C0216606C0000002DD4 -:101FF0000616607000000052021661B80000000171 -:10200000061661BC0000001F0216623807FFFFFFC2 -:102010000216623C0000003F0216624007FFFFFF0D -:10202000021662440000000F011662480000000022 -:102030000116624C00000000011662500000000012 -:1020400001166254000000000116625800000000F2 -:102050000116625C000000000116626000000000D2 -:1020600001166264000000000116626800000000B2 -:102070000116626C00000000011662700000000092 -:102080000116627400000000011662780000000072 -:102090000116627C000000000C166000000003E8DE -:1020A0000A166000000000010B1660000000000A24 -:1020B0000216804000000006021680440000000561 -:1020C000021680480000000A0216804C000000053D -:1020D0000216805400000002021680CC00000004AA -:1020E000021680D000000004021680D40000000414 -:1020F000021680D800000004021680DC00000004F4 -:10210000021680E000000004021680E400000004D3 -:10211000021680E800000004021688040000000493 -:10212000021680300000007C021680340000003D62 -:10213000021680380000003F0216803C0000009C20 -:10214000021680F000000007061680F4000000056B -:102150000216880C0101010102168108000000002E -:102160000216810C00000004021681100000000419 -:1021700002168114000000020216881008012004D3 -:1021800002168118000000050216811C00000005DF -:1021900002168120000000050216812400000005BF -:1021A0000216882C20081001021681280000000861 -:1021B0000216812C00000006021681300000000784 -:1021C000021681340000000002168830010101204F -:1021D000061681380000000402168834010101014E -:1021E00002168148000000000216814C0000000425 -:1021F0000216815000000004021681540000000203 -:1022000002168838080120040216815800000005D3 -:102210000216815C000000050216816000000005C6 -:1022200002168164000000050216883C2008100197 -:1022300002168168000000080216816C000000068A -:102240000216817000000007021681740000000170 -:102250000216884001010120021681780000000169 -:102260000216817C0000000102168180000000013E -:102270000216818400000001021688440101010158 -:1022800002168188000000010216818C0000000403 -:1022900002168190000000040216819400000002E2 -:1022A00002168848080120040216819800000005E3 -:1022B0000216819C00000005021681A000000005A6 -:1022C000021681A4000000050216881420081001DF -:1022D000021681A800000008021681AC000000066A -:1022E000021681B000000007021681B40000000150 -:1022F0000216881801010120021681B800000001B1 -:10230000021681BC00000001021681C0000000011D -:10231000021681C4000000010216881C010101019F -:10232000021681C800000001021681CC00000004E2 -:10233000021681D000000004021681D400000002C1 -:102340000216882008012004021681D8000000052A -:10235000021681DC00000005021681E00000000585 -:10236000021681E4000000050216882420081001EE -:10237000021681E800000008021681EC0000000649 -:10238000021681F0000000070216E40C00000000B5 -:1023900002168828010101200616E410000000043E -:1023A0000216E000010101010216E4200000000015 -:1023B0000216E424000000040216E42800000004D1 -:1023C0000216E42C000000020216E00408012004BA -:1023D0000216E430000000050216E4340000000597 -:1023E0000216E438000000050216E43C0000000577 -:1023F0000216E008200810010216E4400000000860 -:102400000216E444000000060216E448000000073B -:102410000216E44C000000000216E00C010101204D -:102420000616E450000000040216E010010101014C -:102430000216E460000000000216E46400000004DC -:102440000216E468000000040216E46C00000002BA -:102450000216E014080120040216E47000000005D2 -:102460000216E474000000050216E478000000057E -:102470000216E47C000000050216E0182008100196 -:102480000216E480000000080216E4840000000642 -:102490000216E488000000070216E48C0000000128 -:1024A0000216E01C010101200216E4900000000168 -:1024B0000216E494000000010216E49800000001F6 -:1024C0000216E49C000000010216E0200101010157 -:1024D0000216E4A0000000010216E4A400000004BB -:1024E0000216E4A8000000040216E4AC000000029A -:1024F0000216E024080120040216E4B000000005E2 -:102500000216E4B4000000050216E4B8000000055D -:102510000216E4BC000000050216E02820081001A5 -:102520000216E4C0000000080216E4C40000000621 -:102530000216E4C8000000070216E4CC0000000107 -:102540000216E02C010101200216E4D00000000177 -:102550000216E4D4000000010216E4D800000001D5 -:102560000216E4DC000000010216E0300101010166 -:102570000216E4E0000000010216E4E4000000049A -:102580000216E4E8000000040216E4EC0000000279 -:102590000216E034080120040216E4F000000005F1 -:1025A0000216E4F4000000050216E4F8000000053D -:1025B0000216E4FC000000050216E03820081001B5 -:1025C0000216E500000000080216E50400000006FF -:1025D0000216E508000000070216E03C0101012098 -:1025E00002168240003F003F0216824400000000B5 -:1025F0000216E524003F003F0216E5280000000017 -:1026000002168248000000000216824C003F003F84 -:102610000216E52C000000000216E530003F003FE6 -:1026200002168250010001000216825401000100CE -:102630000216E534010001000216E5380100010030 -:1026400006168258000000020216E53C0000000059 -:102650000216E540000000000216826000C000C0C3 -:102660000216826400C000C00216E54400C000C02B -:102670000216E54800C000C0021682681E001E0057 -:102680000216826C1E001E000216E54C1E001E0083 -:102690000216E5501E001E00021682704000400027 -:1026A00002168274400040000216E55440004000CB -:1026B0000216E55840004000021682788000800033 -:1026C0000216827C800080000216E55C800080009B -:1026D0000216E56080008000021682802000200043 -:1026E00002168284200020000216E56420002000EB -:1026F0000216E5682000200006168288000000020D -:102700000216E56C000000000216E57000000000F3 -:102710000216829000000000021682940000000061 -:102720000216E574000000000216E57800000000C3 -:1027300002168298000000000216829C0000000031 -:102740000216E57C000000000216E5800000000093 -:10275000021682A000000000021682A40000000100 -:10276000061682A80000000A021681F400000C0878 -:10277000021681F800000040021681FC00000100F2 -:1027800002168200000000200216820400000017DA -:1027900002168208000000800216820C000002006F -:1027A00002168210000000000216821801FF01FFCD -:1027B0000216821401FF01FF0216E51001FF01FF5E -:1027C0000216E50C01FF01FF0216823C0000001317 -:1027D000021680900000013F021680600000014058 -:1027E00002168064000001400616806800000002A6 -:1027F00002168070000000C00616807400000007FA -:102800000216809C00000048021680A000000048CC -:10281000061680A400000002021680AC00000048EA -:10282000061680B000000007021682380000800003 -:1028300002168234000025E40216809400007FFF17 -:1028400002168220000F000F0216821C000F000FDC -:102850000216E518000F000F0216E514000F000F16 -:10286000021682280000000002168224FFFFFFFFEC -:102870000216E520000000000216E51CFFFFFFFF26 -:102880000216E6BC000000000216E6C000000002CE -:102890000216E6C4000000010216E6C800000003AC -:1028A0000216E6CC000000040216E6D00000000686 -:1028B0000216E6D4000000050216E6D80000000764 -:1028C000021680EC000000FF02140000000000016E -:1028D0000214000C0000000102140040000000017E -:1028E0000214004400007FFF0214000C00000000EE -:1028F00002140000000000000214006C0000000040 -:102900000214000400000001021400300000000165 -:1029100002140004000000000214005C000000002B -:10292000021400080000000102140034000000013D -:102930000214000800000000021400600000000003 -:102940000202005800000032020200A0031500201D -:10295000020200A403150020020200A801000030BA -:10296000020200AC08100000020200B000000033B8 -:10297000020200B400000030020200B80000003182 -:10298000020200BC00000003020200C000000006BA -:10299000020200C400000003020200C8000000039D -:1029A000020200CC00000002020200D00000000081 -:1029B000020200D400000002020200DC000000005D -:1029C000020200E000000006020200E40000000431 -:1029D000020200E800000002020200EC0000000217 -:1029E000020200F000000001020200FC00000006EC -:1029F0000202012000000000020201340000000277 -:102A0000020201B0000000010202020C00000001FD -:102A1000020202140000000102020218000000027B -:102A200002020404000000010202040C0000004045 -:102A300002020410000000400202041C0000000416 -:102A40000202042000000020020204240000000210 -:102A50000202042800000020060205000000001207 -:102A600004020480001F032A020200600000000F1D -:102A70000202006400000007020200680000000B70 -:102A80000202006C0000000E020200700000000E46 -:102A90000602007400000003020200F400000004BB -:102AA0000202000400000001020200080000000110 -:102AB0000202000C000000010202001000000001F0 -:102AC00002020014000000010202001800000001D0 -:102AD0000202001C000000010202002000000001B0 -:102AE0000202002400000001020200280000000190 -:102AF0000202002C00000001020200300000000170 -:102B0000020200340000000102020038000000014F -:102B10000202003C0000000102020040000000012F -:102B2000020200440000000102020048000000010F -:102B30000202004C000000010202005000000001EF -:102B400002020108000000C8020201180000000291 -:102B5000020201C400000000020201CC00000000DB -:102B6000020201D400000002020201DC00000002A7 -:102B7000020201E4000000FF020201EC000000FF7D -:102B800002020100000000000202010C000000C867 -:102B90000202011C00000002020201C80000000045 -:102BA000020201D000000000020201D80000000271 -:102BB000020201E000000002020201E8000000FF42 -:102BC000020201F0000000FF020201040000000008 -:102BD00002020108000000C8020201180000000201 -:102BE000020201C400000000020201CC000000004B -:102BF000020201D400000002020201DC0000000217 -:102C0000020201E4000000FF020201EC000000FFEC -:102C100002020100000000000202010C000000C8D6 -:102C20000202011C00000002020201C800000000B4 -:102C3000020201D000000000020201D800000002E0 -:102C4000020201E000000002020201E8000000FFB1 -:102C5000020201F0000000FF020201040000000077 -:102C600002020108000000C8020201180000000270 -:102C7000020201C400000000020201CC00000000BA -:102C8000020201D400000002020201DC0000000286 -:102C9000020201E4000000FF020201EC000000FF5C -:102CA00002020100000000000202010C000000C846 -:102CB0000202011C00000002020201C80000000024 -:102CC000020201D000000000020201D80000000250 -:102CD000020201E000000002020201E8000000FF21 -:102CE000020201F0000000FF0202010400000000E7 -:102CF00002020108000000C80202011800000002E0 -:102D0000020201C400000000020201CC0000000029 -:102D1000020201D400000002020201DC00000002F5 -:102D2000020201E4000000FF020201EC000000FFCB -:102D300002020100000000000202010C000000C8B5 -:102D40000202011C00000002020201C80000000093 -:102D5000020201D000000000020201D800000002BF -:102D6000020201E000000002020201E8000000FF90 -:102D7000020201F0000000FF020201040000000056 -:102D80000728040000C00000082807A8000B03491A -:102D9000072C000032FC0000072C800035780CC0A6 -:102DA000072D00003AC11A1F072D800039E228D0F4 -:102DB000072E00001C3E3749082E3710391E034BE2 -:102DC00001280000000000000128000400000000AD -:102DD00001280008000000000128000C000000008D -:102DE000012800100000000001280014000000006D -:102DF0000228002000000001022800240000000238 -:102E000002280028000000030228002C0000000017 -:102E100002280030000000040228003400000001F5 -:102E200002280038000000000228003C00000001D9 -:102E300002280040000000040228004400000000B6 -:102E400002280048000000010228004C0000000396 -:102E50000228005000000000022800540000000179 -:102E600002280058000000040228005C0000000056 -:102E70000228006000000001022800640000000336 -:102E800002280068000000000228006C0000000119 -:102E900002280070000000040228007400000000F6 -:102EA00002280078000000040228007C00000003D3 -:102EB0000628008000000002022800A400003FFF56 -:102EC000022800A8000003FF0228022400000000DE -:102ED00002280234000000000228024C000000001A -:102EE000022802E40000FFFF06282000000008007E -:102EF000022B8BC000000001022B800000000000AC -:102F0000022B804000000018022B80800000000C83 -:102F1000022B80C0000000660C2B83000007A1205C -:102F20000A2B8300000001380B2B8300000013885C -:102F3000022B83C0000001F40C2B8340000001F43D -:102F40000A2B8340000000000B2B8340000000058B -:102F50000A2B83800004C4B40C2B83801DCD650034 -:102F60000A2B1480000000000B2B8380004C4B4088 -:102F7000022B148000000001062A29C8000000046A -:102F8000042A29D80002034D062A208000000048A8 -:102F9000062A9020000000C8062A900000000002C7 -:102FA000062A21A800000086062A20000000002032 -:102FB000022A23C800000000042A23D00002034F85 -:102FC000042A249800040351022A2C500000000017 -:102FD000022A2C1000000000042A2C0800020355CD -:102FE000042A300000020357062A300800000100BE -:102FF000062A404000000010042A40000010035937 -:10300000062A6AC000000002062A6B0000000004C5 -:10301000042A840800020369022B08000000000053 -:10302000042B0C000010036B022B080001000000B1 -:10303000042B0C400008037B022B08000200000058 -:10304000042B0C6000080383062AC000000000D88F -:10305000062A24A800000014062A254800000022A1 -:10306000042A25D00002038B062A266800000022CD -:10307000042A26F00002038D062A27880000002279 -:10308000042A28100002038F062A28A80000002224 -:10309000042A293000020391062AA000000000281B -:1030A000062AA1400000000C042A29E00002039334 -:1030B000062A502000000002062A503000000002BC -:1030C000062A500000000002062A501000000002EC -:1030D000022A520800000001042A6AC8000203956F -:1030E000062A6B1000000042062A6D200000000432 -:1030F000062ABCD000000002062AC360000000D8E7 -:10310000062A24F800000014062A25D80000002210 -:10311000042A266000020397062A26F800000022EF -:10312000042A278000020399062A2818000000229A -:10313000042A28A00002039B062A29380000002246 -:10314000042A29C00002039D062AA0A0000000282E -:10315000062AA1700000000C042A29E80002039F3F -:10316000062A502800000002062A503800000002FB -:10317000062A500800000002062A5018000000022B -:10318000022A520C00000001042A6AD0000203A1A6 -:10319000062A6C1800000042062A6D300000000468 -:1031A000062ABCD800000002022AC6C000000000A7 -:1031B000042A29F0001003A3062A50480000000E3C -:1031C000062AB00000000006022AC6C40000000063 -:1031D000042A2A30001003B3062A50800000000E93 -:1031E000062AB01800000006022AC6C80000000027 -:1031F000042A2A70001003C3062A50B80000000EEB -:10320000062AB03000000006022AC6CC00000000EA -:10321000042A2AB0001003D3062A50F00000000E42 -:10322000062AB04800000006022AC6D000000000AE -:10323000042A2AF0001003E3062A51280000000E99 -:10324000062AB06000000006022AC6D40000000072 -:10325000042A2B30001003F3062A51600000000EF0 -:10326000062AB07800000006022AC6D80000000036 -:10327000042A2B7000100403062A51980000000E47 -:10328000062AB09000000006022AC6DC00000000FA -:10329000042A2BB000100413062A51D00000000E9F -:1032A000062AB0A800000006021010080000000165 -:1032B0000210105000000001021010000003D000A6 -:1032C000021010040000003D091018000200042341 -:1032D0000910110000280623061011A00000001894 -:1032E00006102400000000E00210201C0000000076 -:1032F0000210202000000001021020C00000000287 -:10330000021020040000000102102008000000014B -:1033100009103C000005064B091038000005065056 -:10332000091038200005065506104C000000010069 -:1033300002104028000000100210404400003FFF2F -:103340000210405800280000021040840084924A75 -:1033500002104058000000000210800000001080A1 -:10336000021080AC00000000021080380000001045 -:103370000210810000000000061081200000000201 -:1033800002108008000002B502108010000000004A -:10339000061082000000004A021081080001FFFFB1 -:1033A00006108140000000020210800000001A8018 -:1033B0000610900000000024061091200000004A32 -:1033C000061093700000004A061095C00000004AE5 -:1033D0000210800400001080021080B00000000184 -:1033E0000210803C00000010021081040000000068 -:1033F00006108128000000020210800C000002B5B7 -:103400000210801400000000061084000000004A32 -:103410000210810C0001FFFF06108148000000022D -:103420000210800400001A80061090900000002412 -:10343000061092480000004A061094980000004AC6 -:10344000061096E80000004A02108000000010807C -:10345000021080AC00000002021080380000001052 -:103460000210810000000000061081200000000210 -:1034700002108008000002B5021080100000000059 -:10348000061082000000004A021081080001FFFFC0 -:1034900006108140000000020210800000001A8027 -:1034A0000610900000000024061091200000004A41 -:1034B000061093700000004A061095C00000004AF4 -:1034C0000210800400001080021080B00000000391 -:1034D0000210803C00000010021081040000000077 -:1034E00006108128000000020210800C000002B5C6 -:1034F0000210801400000000061084000000004A42 -:103500000210810C0001FFFF06108148000000023C -:103510000210800400001A80061090900000002421 -:10352000061092480000004A061094980000004AD5 -:10353000061096E80000004A02108000000010808B -:10354000021080AC0000000402108038000000105F -:10355000021081000000000006108120000000021F -:1035600002108008000002B5021080100000000068 -:10357000061082000000004A021081080001FFFFCF -:1035800006108140000000020210800000001A8036 -:103590000610900000000024061091200000004A50 -:1035A000061093700000004A061095C00000004A03 -:1035B0000210800400001080021080B0000000059E -:1035C0000210803C00000010021081040000000086 -:1035D00006108128000000020210800C000002B5D5 -:1035E0000210801400000000061084000000004A51 -:1035F0000210810C0001FFFF06108148000000024C -:103600000210800400001A80061090900000002430 -:10361000061092480000004A061094980000004AE4 -:10362000061096E80000004A02108000000010809A -:10363000021080AC0000000602108038000000106C -:10364000021081000000000006108120000000022E -:1036500002108008000002B5021080100000000077 -:10366000061082000000004A021081080001FFFFDE -:1036700006108140000000020210800000001A8045 -:103680000610900000000024061091200000004A5F -:10369000061093700000004A061095C00000004A12 -:1036A0000210800400001080021080B000000007AB -:1036B0000210803C00000010021081040000000095 -:1036C00006108128000000020210800C000002B5E4 -:1036D0000210801400000000061084000000004A60 -:1036E0000210810C0001FFFF06108148000000025B -:1036F0000210800400001A80061090900000002440 -:10370000061092480000004A061094980000004AF3 -:10371000061096E80000004A021205B00000000101 -:103720000212049000E383400212051400003C10D2 -:103730000212066C00000001021206700000000078 -:1037400002120494FFFFFFFF02120498FFFFFFFF25 -:103750000212049CFFFFFFFF021204A0FFFFFFFF05 -:10376000021204A4FFFFFFFF021204A8FFFFFFFFE5 -:10377000021204ACFFFFFFFF021204B0FFFFFFFFC5 -:10378000021204BCFFFFFFFF021204C0FFFFFFFF95 -:10379000021204C4FFFFFFFF021204C8FFFFFFFF75 -:1037A000021204CCFFFFFFFF021204D0FFFFFFFF55 -:1037B000021204D8FFFFFFFF021204DCFFFFFFFF2D -:1037C000021204E0FFFFFFFF021204E4FFFFFFFF0D -:1037D000021204E8FFFFFFFF021204ECFFFFFFFFED -:1037E000021204F0FFFFFFFF021204F4FFFFFFFFCD -:1037F000021204F8FFFFFFFF021204FCFFFFFFFFAD -:1038000002120500FFFFFFFF02120504FFFFFFFF8A -:1038100002120508FFFFFFFF0212050CFFFFFFFF6A -:1038200002120510FFFFFFFF021204D4FF802000E8 -:10383000021204B4F0005000021204B8F0001000AC -:1038400002120390000000080212039C000000080E -:10385000021203A000000008021203A400000002EC -:10386000021203BC00000004021203C000000005A5 -:10387000021203C400000004021203D00000000082 -:103880000212036C00000001021203680000003FF6 -:10389000021201BC00000040021201C00000180822 -:1038A000021201C400000803021201C8000008034C -:1038B000021201CC00000040021201D000000003FF -:1038C000021201D400000803021201D8000008030C -:1038D000021201DC00000803021201E000010003F3 -:1038E000021201E400000803021201E800000803CC -:1038F000021201EC00000003021201F000000003BC -:10390000021201F400000003021201F8000000039B -:10391000021201FC0000000302120200000000037A -:103920000212020400000003021202080000000359 -:103930000212020C00000003021202100000000339 -:103940000212021400000003021202180000000319 -:103950000212021C000000030212022000000003F9 -:1039600002120224000000030212022800002403B5 -:103970000212022C0000002F021202300000000987 -:103980000212023400000019021202380000018401 -:103990000212023C000001830212024000000306F2 -:1039A0000212024400000019021202480000000640 -:1039B0000212024C0000030602120250000003062D -:1039C00002120254000003060212025800000C8684 -:1039D0000212025C000003060212026000000306ED -:1039E00002120264000000060212026800000006D3 -:1039F0000212026C000000060212027000000006B3 -:103A00000212027400000006021202780000000692 -:103A10000212027C00000006021202800000000672 -:103A20000212028400000006021202880000000652 -:103A30000212028C00000006021202900000000632 -:103A40000212029400000006021202980000000612 -:103A50000212029C00000006021202A000000306EF -:103A6000021202A400000013021202A800000006C5 -:103A7000021202B000001004021202B4000010048E -:103A80000212032400106440021203280010644054 -:103A9000021205B400000001021201B00000000192 -:103AA0000600A000000000160200A0EC5554000023 -:103AB0000200A0F0555555550200A0F400005555E0 -:103AC0000200A0F8F00000000200A0FC5554000025 -:103AD0000200A100555555550200A104000055559E -:103AE0000200A108F00000000200A18C5554000063 -:103AF0000200A190555555550200A194000055555E -:103B00000200A198F00000000200A19C000000004B -:103B10000200A1A0000100000200A1A400005014B6 -:103B20000200A1A8000000000200A45C00000C003C -:103B30000200A61C000000030200A06CFF5C000055 -:103B40000200A070FFF55FFF0200A0740000FFFFFD -:103B50000200A078F00003E00200A07C000000005A -:103B60000200A0800000A0000600A0840000000564 -:103B70000200A0980FE000000600A09C00000007D3 -:103B80000200A0B8000004000600A0BC0000000372 -:103B90000200A0C8000010000600A0CC0000000336 -:103BA0000200A0D8000040000600A0DC00000003D6 -:103BB0000200A0E8000100000600A22C00000004A2 -:103BC0000200A10CFF5C00000200A110FFF55FFFE6 -:103BD0000200A1140000FFFF0200A118F00003E0A2 -:103BE0000200A11C000000000200A1200000A000B3 -:103BF0000600A124000000050200A1380FE000002B -:103C00000600A13C000000070200A15800000800C7 -:103C10000600A15C000000030200A1680000200073 -:103C20000600A16C000000030200A17800008000E3 -:103C30000600A17C000000030200A1880002000031 -:103C40000600A23C0000000400000000000000008C -:103C50000000003100000000000000000000000033 -:103C60000000000000000000000000000000000054 -:103C700000000000000000000000000000310032E1 -:103C80000000000000000000000000000000000034 -:103C90000000000000000000000000000000000024 -:103CA000000000000000000000320056000000008C -:103CB0000000000000000000000000000000000004 -:103CC00000000000000000000000000000000000F4 -:103CD000000000000056008C000000000000000002 -:103CE000008C009000900094009400980098009C34 -:103CF000009C00A000A000A400A400A800A800ACA4 -:103D000000AC00B100B100B300B300B5000000008A -:103D100000000000000000000000000000000000A3 -:103D200000000000000000000000000000B50102DB -:103D30000102010A010A01120112011B011B0124E7 -:103D40000124012D012D01360136013F013F0148BB -:103D5000014801510151015A00000000000000001B -:103D60000000000000000000000000000000000053 -:103D70000000000000000000000000000000000043 -:103D80000000000000000000000000000000000033 -:103D90000000000000000000000000000000000023 -:103DA0000000000000000000000000000000000013 -:103DB0000000000000000000000000000000000003 -:103DC00000000000000000000000000000000000F3 -:103DD00000000000000000000000000000000000E3 -:103DE00000000000000000000000000000000000D3 -:103DF00000000000000000000000000000000000C3 -:103E00000000000000000000015A015F00000000F7 -:103E100000000000015F0160016001610161016259 -:103E2000016201630163016401640165016501666A -:103E300001660167000000000000000000000000B3 -:103E40000000000000000000000000000000000072 -:103E50000000000000000000000000000000000062 -:103E60000167016C016C0179017901860000000095 -:103E70000000000000000000000000000000000042 -:103E80000000000000000000000000000000000032 -:103E90000000000000000000000000000000000022 -:103EA0000000000000000000000000000000000012 -:103EB00000000000000000000186018700000000F3 -:103EC00000000000000000000000000000000000F2 -:103ED00000000000000000000000000000000000E2 -:103EE00000000000018701BE00000000000000008B -:103EF00000000000000000000000000000000000C2 -:103F000000000000000000000000000000000000B1 -:103F100001BE01E9000000000000000000000000F8 -:103F20000000000000000000000000000000000091 -:103F300000000000000000000000000001E9021A7B -:103F40000000000000000000021A022102210228E5 -:103F50000228022F022F02360236023D023D0244A1 -:103F60000244024B024B02520252028A000000003D -:103F700000000000028A028E028E029202920296D5 -:103F80000296029A029A029E029E02A202A202A631 -:103F900002A602AA02AA02FA02FA031103110328D6 -:103FA0000328032B032B032E032E03310331033489 -:103FB000033403370337033A033A033D033D034019 -:103FC00003400381038103880388038F038F0393D6 -:103FD000039303970397039B039B039F039F03A3F1 -:103FE00003A303A703A703AB03AB03AF03AF03B064 -:103FF00000000000000000000000000000000000C1 -:1040000000000000000000000000000000000000B0 -:10401000000000000000000003B003C20000000028 -:104020000000000000000000000000000000000090 -:104030000000000000000000000000000000000080 -:104040000000000003C203D703D703DA03DA03DD5D -:104050000000000000000000000000000000000060 -:104060000000000000000000000000000000000050 -:1040700003DD040A00000000000000000000000052 -:104080000000000000000000000000000000000030 -:10409000000000000000000000000000040A050D00 -:1040A0000000000000000000000000000000000010 -:1040B0000000000000000000000000000000000000 -:1040C0000000000000000000050D0514051405188F -:1040D0000518051C000000000000000000000000A2 -:1040E00000000000000000000000000000000000D0 -:1040F00000000000051C055C00000000000000003E -:10410000055C05650565056E056E05770577058017 -:1041100005800589058905920592059B059B05A4E7 -:1041200005A405FD05FD0613061306290629062D1F -:10413000062D063106310635063506390639063DA7 -:10414000063D064106410645064506490649065014 -:10415000000000000000000000000000000000005F -:10416000000000000000000000000000000000004F -:10417000000000000000000006500656000000008D -:10418000000000000000000000000000000000002F -:10419000000000000000000000000000000000001F -:1041A0000000000006560659000000000000000054 -:1041B00000000000000000000000000000000000FF -:1041C00000000000000000000000000000000000EF -:1041D0000659065F0000000000000000000000001B -:1041E00000000000000000000000000000000000CF -:1041F00000000000000000000000000000000000BF -:104200000000000000000000065F066E066E067DDE -:10421000067D068C068C069B069B06AA06AA06B996 -:1042200006B906C806C806D706D70748000000002A -:10423000000000000000000000000000000000007E -:10424000000000000000000000000000000000006E -:10425000000000000748075B075B076C076C077DE1 -:10426000000000000000000000000000000000004E -:10427000000000000000000000000000000000003E -:10428000000000000000000000000000000000002E -:10429000000000000000000000000000000000001E -:1042A000000000000000000000000000000000000E -:1042B00000000000000000000000000000000000FE -:1042C00000000000000000000000000000000000EE -:1042D00000000000000000000000000000000000DE -:1042E00000010000000204C00003098000040E4029 -:1042F00000051300000617C000071C8000082140BD -:1043000000092600000A2AC0000B2F80000C344050 -:10431000000D3900000E3DC0000F428000104740E4 -:1043200000114C00001250C00013558000145A4078 -:1043300000155F00001663C00017688000186D400C -:1043400000197200001A76C0001B7B80001C8040A0 -:10435000001D8500001E89C0001F8E800020934034 -:10436000000020000000400000006000000080000D -:104370000000A0000000C0000000E00000010000FC -:1043800000012000000140000001600000018000E9 -:104390000001A0000001C0000001E00000020000D8 -:1043A00000022000000240000002600000028000C5 -:1043B0000002A0000002C0000002E00000030000B4 -:1043C00000032000000340000003600000038000A1 -:1043D0000003A0000003C0000003E0000004000090 -:1043E000000420000004400000046000000480007D -:1043F0000004A0000004C0000004E000000500006C -:104400000005200000054000000560000005800058 -:104410000005A0000005C0000005E0000006000047 -:104420000006200000064000000660000006800034 -:104430000006A0000006C0000006E0000007000023 -:104440000007200000074000000760000007800010 -:104450000007A0000007C0000007E00000080000FF -:1044600000082000000840000008600000088000EC -:104470000008A0000008C0000008E00000090000DB -:1044800000092000000940000009600000098000C8 -:104490000009A0000009C0000009E000000A0000B7 -:1044A000000A2000000A4000000A6000000A8000A4 -:1044B000000AA000000AC000000AE000000B000093 -:1044C000000B2000000B4000000B6000000B800080 -:1044D000000BA000000BC000000BE000000C00006F -:1044E000000C2000000C4000000C6000000C80005C -:1044F000000CA000000CC000000CE000000D00004B -:10450000000D2000000D4000000D6000000D800037 -:10451000000DA000000DC000000DE000000E000026 -:10452000000E2000000E4000000E6000000E800013 -:10453000000EA000000EC000000EE000000F000002 -:10454000000F2000000F4000000F6000000F8000EF -:10455000000FA000000FC000000FE00000100000DE -:1045600000102000001040000010600000108000CB -:104570000010A0000010C0000010E00000110000BA -:1045800000112000001140000011600000118000A7 -:104590000011A0000011C0000011E0000012000096 -:1045A0000012200000124000001260000012800083 -:1045B0000012A0000012C0000012E0000013000072 -:1045C000001320000013400000136000001380005F -:1045D0000013A0000013C0000013E000001400004E -:1045E000001420000014400000146000001480003B -:1045F0000014A0000014C0000014E000001500002A -:104600000015200000154000001560000015800016 -:104610000015A0000015C0000015E0000016000005 -:1046200000162000001640000016600000168000F2 -:104630000016A0000016C0000016E00000170000E1 -:1046400000172000001740000017600000178000CE -:104650000017A0000017C0000017E00000180000BD -:1046600000182000001840000018600000188000AA -:104670000018A0000018C0000018E0000019000099 -:104680000019200000194000001960000019800086 -:104690000019A0000019C0000019E000001A000075 -:1046A000001A2000001A4000001A6000001A800062 -:1046B000001AA000001AC000001AE000001B000051 -:1046C000001B2000001B4000001B6000001B80003E -:1046D000001BA000001BC000001BE000001C00002D -:1046E000001C2000001C4000001C6000001C80001A -:1046F000001CA000001CC000001CE000001D000009 -:10470000001D2000001D4000001D6000001D8000F5 -:10471000001DA000001DC000001DE000001E0000E4 -:10472000001E2000001E4000001E6000001E8000D1 -:10473000001EA000001EC000001EE000001F0000C0 -:10474000001F2000001F4000001F6000001F8000AD -:10475000001FA000001FC000001FE000002000009C -:104760000020200000204000002060000020800089 -:104770000020A0000020C0000020E0000021000078 -:104780000021200000214000002160000021800065 -:104790000021A0000021C0000021E0000022000054 -:1047A0000022200000224000002260000022800041 -:1047B0000022A0000022C0000022E0000023000030 -:1047C000002320000023400000236000002380001D -:1047D0000023A0000023C0000023E000002400000C -:1047E00000242000002440000024600000248000F9 -:1047F0000024A0000024C0000024E00000250000E8 -:1048000000252000002540000025600000258000D4 -:104810000025A0000025C0000025E00000260000C3 -:1048200000262000002640000026600000268000B0 -:104830000026A0000026C0000026E000002700009F -:10484000002720000027400000276000002780008C -:104850000027A0000027C0000027E000002800007B -:104860000028200000284000002860000028800068 -:104870000028A0000028C0000028E0000029000057 -:104880000029200000294000002960000029800044 -:104890000029A0000029C0000029E000002A000033 -:1048A000002A2000002A4000002A6000002A800020 -:1048B000002AA000002AC000002AE000002B00000F -:1048C000002B2000002B4000002B6000002B8000FC -:1048D000002BA000002BC000002BE000002C0000EB -:1048E000002C2000002C4000002C6000002C8000D8 -:1048F000002CA000002CC000002CE000002D0000C7 -:10490000002D2000002D4000002D6000002D8000B3 -:10491000002DA000002DC000002DE000002E0000A2 -:10492000002E2000002E4000002E6000002E80008F -:10493000002EA000002EC000002EE000002F00007E -:10494000002F2000002F4000002F6000002F80006B -:10495000002FA000002FC000002FE000003000005A -:104960000030200000304000003060000030800047 -:104970000030A0000030C0000030E0000031000036 -:104980000031200000314000003160000031800023 -:104990000031A0000031C0000031E0000032000012 -:1049A00000322000003240000032600000328000FF -:1049B0000032A0000032C0000032E00000330000EE -:1049C00000332000003340000033600000338000DB -:1049D0000033A0000033C0000033E00000340000CA -:1049E00000342000003440000034600000348000B7 -:1049F0000034A0000034C0000034E00000350000A6 -:104A00000035200000354000003560000035800092 -:104A10000035A0000035C0000035E0000036000081 -:104A2000003620000036400000366000003680006E -:104A30000036A0000036C0000036E000003700005D -:104A4000003720000037400000376000003780004A -:104A50000037A0000037C0000037E0000038000039 -:104A60000038200000384000003860000038800026 -:104A70000038A0000038C0000038E0000039000015 -:104A80000039200000394000003960000039800002 -:104A90000039A0000039C0000039E000003A0000F1 -:104AA000003A2000003A4000003A6000003A8000DE -:104AB000003AA000003AC000003AE000003B0000CD -:104AC000003B2000003B4000003B6000003B8000BA -:104AD000003BA000003BC000003BE000003C0000A9 -:104AE000003C2000003C4000003C6000003C800096 -:104AF000003CA000003CC000003CE000003D000085 -:104B0000003D2000003D4000003D6000003D800071 -:104B1000003DA000003DC000003DE000003E000060 -:104B2000003E2000003E4000003E6000003E80004D -:104B3000003EA000003EC000003EE000003F00003C -:104B4000003F2000003F4000003F6000003F800029 -:104B5000003FA000003FC000003FE000003FE00138 -:104B600000000000000001FF0000020000007FF8CC -:104B700000007FF800000CDF0000150000000001BD -:104B80000000000100000001FFFFFFFFFFFFFFFF2B -:104B9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25 -:104BA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF15 -:104BB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF05 -:104BC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5 -:104BD000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5 -:104BE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD5 -:104BF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC5 -:104C0000FFFFFFFFFFFFFFFFFFFFFFFF00000000B0 -:104C1000FFFFFFFF00000000FFFFFFFFFFFFFFFFA0 -:104C200000000000FFFFFFFF00000000FFFFFFFF8C -:104C3000FFFFFFFF00000000FFFFFFFF000000007C -:104C4000FFFFFFFF0000000300BEBC20FFFFFFFFCF -:104C500000000000FFFFFFFF00000000FFFFFFFF5C -:104C60000000000300BEBC20FFFFFFFF00000000AB -:104C7000FFFFFFFF00000000FFFFFFFF0000000339 -:104C800000BEBC20FFFFFFFF00000000FFFFFFFF92 -:104C900000000000FFFFFFFF0000000300BEBC207B -:104CA000FFFFFFFF00000000FFFFFFFF000000000C -:104CB000FFFFFFFF0000000300BEBC20FFFFFFFF5F -:104CC00000000000FFFFFFFF00000000FFFFFFFFEC -:104CD0000000000300BEBC2000002000000040C017 -:104CE00000006180000082400000A3000000C3C0FB -:104CF0000000E4800001054000012600000146C0DC -:104D000000016780000188400001A9000001C9C0BE -:104D10000001EA8000020B4000022C0000024CC09F -:104D200000026D8000028E400002AF000002CFC082 -:104D30000002F0800003114000033200000352C063 -:104D400000037380000394400003B5000003D5C046 -:104D50000003F6800004174000043800000458C027 -:104D60000004798000049A40000080000001038064 -:104D70000001870000020A8000028E0000031180FB -:104D8000000395000004188000049C0000051F80AB -:104D90000005A300000626800006AA0000072D805B -:104DA0000007B100000834800008B80000093B800B -:104DB0000009BF00000A4280000AC600000B4980BB -:104DC000000BCD00000C5080000CD400000D57806B -:104DD000000DDB0000007FF800007FF80000192ABA -:104DE0000000350000001900001000000000000065 -:104DF00000000000FFFFFFFF400000004000000037 -:104E000040000000400000004000000040000000A2 -:104E10004000000040000000400000004000000092 -:104E20004000000040000000400000004000000082 -:104E30004000000040000000400000004000000072 -:104E40004000000040000000400000004000000062 -:104E50004000000040000000400000004000000052 -:104E60004000000040000000400000004000000042 -:104E7000400000004000000000007FF800007FF8C4 -:104E8000000005C700001500FFFFFFFFFFFFFFFF49 -:104E9000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF22 -:104EA000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12 -:104EB000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF02 -:104EC000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2 -:104ED000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE2 -:104EE000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD2 -:104EF000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2 -:104F0000FFFFFFFFFFFFFFFF400000004000000029 -:104F10004000000040000000400000004000000091 -:104F20004000000040000000400000004000000081 -:104F30004000000040000000400000004000000071 -:104F40004000000040000000400000004000000061 -:104F50004000000040000000400000004000000051 -:104F60004000000040000000400000004000000041 -:104F70004000000040000000400000004000000031 -:104F800040000000400000000000100000002080F1 -:104F900000003100000041800000520000006280EB -:104FA0000000730000008380000094000000A480D3 -:104FB0000000B5000000C5800000D6000000E680BB -:104FC0000000F700000107800001180000012880A0 -:104FD000000139000001498000015A0000016A8087 -:104FE00000017B0000018B8000019C000001AC806F -:104FF0000001BD000001CD800001DE000001EE8057 -:105000000001FF0000007FF800007FF80000112E73 -:105010000000350010000000000028AD0000000076 -:1050200000010001000D0205CCCCCCC5FFFFFFFF45 -:10503000FFFFFFFF7058103C000000000000000060 -:1050400000000001CCCC0201CCCCCCCCCCCC0201F9 -:10505000CCCCCCCCCCCC0201CCCCCCCCCCCC0201BA -:10506000CCCCCCCCCCCC0201CCCCCCCCCCCC0201AA -:10507000CCCCCCCCCCCC0201CCCCCCCCCCCC02019A -:10508000CCCCCCCC00000000FFFFFFFF40000000B4 -:105090004000000040000000400000004000000010 -:1050A0004000000040000000400000004000000000 -:1050B00040000000400000004000000040000000F0 -:1050C00040000000400000004000000040000000E0 -:1050D00040000000400000004000000040000000D0 -:1050E00040000000400000004000000040000000C0 -:1050F00040000000400000004000000040000000B0 -:10510000400000004000000040000000002625A0F4 -:1051100000000000002625A000000000002625A0B9 -:1051200000000000002625A000000000000E023252 -:10513000011600D60010000000000000002625A087 -:1051400000000000002625A000000000002625A089 -:1051500000000000002625A00000000000720236BA -:10516000012300F300100000000000000000FFFF1A -:10517000000000000000FFFF000000000000FFFF33 -:10518000000000000000FFFF000000000000FFFF23 -:10519000000000000000FFFF000000000000FFFF13 -:1051A000000000000000FFFF000000000000FFFF03 -:1051B000000000000000FFFF000000000000FFFFF3 -:1051C000000000000000FFFF000000000000FFFFE3 -:1051D000000000000000FFFF000000000000FFFFD3 -:1051E000000000000000FFFF000000000000FFFFC3 -:1051F000000000000000FFFF000000000000FFFFB3 -:10520000000000000000FFFF000000000000FFFFA2 -:10521000000000000000FFFF000000000000FFFF92 -:10522000000000000000FFFF000000000000FFFF82 -:10523000000000000000FFFF000000000000FFFF72 -:10524000000000000000FFFF000000000000FFFF62 -:10525000000000000000FFFF000000000000FFFF52 -:10526000000000000000FFFF000000000000FFFF42 -:10527000000000000000FFFF000000000000FFFF32 -:10528000000000000000FFFF000000000000FFFF22 -:10529000000000000000FFFF000000000000FFFF12 -:1052A000000000000000FFFF000000000000FFFF02 -:1052B000000000000000FFFF000000000000FFFFF2 -:1052C000000000000000FFFF000000000000FFFFE2 -:1052D000000000000000FFFF000000000000FFFFD2 -:1052E000000000000000FFFF000000000000FFFFC2 -:1052F000000000000000FFFF000000000000FFFFB2 -:10530000000000000000FFFF000000000000FFFFA1 -:10531000000000000000FFFF000000000000FFFF91 -:10532000000000000000FFFF000000000000FFFF81 -:10533000000000000000FFFF000000000000FFFF71 -:10534000000000000000FFFF000000000000FFFF61 -:10535000000000000000FFFF000000000000FFFF51 -:10536000000000000000FFFF00000000FFFFFFF34F -:10537000318FFFFF0C30C30CC30C30C3CF3CF300A4 -:10538000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FF -:1053900030EFFFFF0C30C30CC30C30C3CF3CF30025 -:1053A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D9 -:1053B000305FFFFF0C30C30CC30C30C3CF3CF30095 -:1053C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B3 -:1053D0001CBFFFFF0C30C305C30C30C3CF3000141B -:1053E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF29A -:1053F000304FFFFF0C30C30CC30C30C3CF3CF30065 -:10540000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6D -:10541000302FFFFF0C30C30CC30C30C3CF3CF30064 -:10542000F3CF3CF30010CF3CCDCDCDCDFFFFFFF748 -:1054300031EFFFFF0C30C30CC30C30C3CF3CF30083 -:10544000F3CF3CF30020CF3CCDCDCDCDFFFFFFF51A -:10545000302FFFFF0C30C30CC30C30C3CF3CF30024 -:10546000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DC -:10547000318FFFFF0C30C30CC30C30C3CF3CF300A3 -:10548000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FE -:10549000310FFFFF0C30C30CC30C30C3CF3CF30003 -:1054A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D8 -:1054B000305FFFFF0C30C30CC30C30C3CF3CF30094 -:1054C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B2 -:1054D0001CBFFFFF0C30C305C30C30C3CF3000141A -:1054E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF299 -:1054F000304FFFFF0C30C30CC30C30C3CF3CF30064 -:10550000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6C -:10551000302FFFFF0C30C30CC30C30C3CF3CF30063 -:10552000F3CF3CF30010CF3CCDCDCDCDFFFFFFF747 -:1055300030EFFFFF0C30C30CC30C30C3CF3CF30083 -:10554000F3CF3CF30020CF3CCDCDCDCDFFFFFFF519 -:10555000304FFFFF0C30C30CC30C30C3CF3CF30003 -:10556000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DB -:1055700031EFFFFF0C30C30CC30C30C3CF3CF30042 -:10558000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FD -:10559000310FFFFF0C30C30CC30C30C3CF3CF30002 -:1055A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D7 -:1055B000305FFFFF0C30C30CC30C30C3CF3CF30093 -:1055C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B1 -:1055D0001CBFFFFF0C30C305C30C30C3CF30001419 -:1055E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF298 -:1055F000304FFFFF0C30C30CC30C30C3CF3CF30063 -:10560000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA6B -:10561000302FFFFF0C30C30CC30C30C3CF3CF30062 -:10562000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A6 -:10563000056FFFFF0C30C30CC30C30C3CF3CC00060 -:10564000F3CF3CF30020CF3CCDCDCDCDFFFFFFF518 -:10565000310FFFFF0C30C30CC30C30C3CF3CF30041 -:10566000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3DA -:10567000320FFFFF0C30C30CC30C30C3CF3CF30020 -:10568000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FC -:10569000310FFFFF0C30C30CC30C30C3CF3CF30001 -:1056A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D6 -:1056B000305FFFFF0C30C30CC30C30C3CF3CF30092 -:1056C000F3CF3CF30002CF3CCDCDCDCDFFFFF406B0 -:1056D0001CBFFFFF0C30C305C30C30C3CF30001418 -:1056E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF297 -:1056F000304FFFFF0C30C30CC30C30C3CF3CF30062 -:10570000F3CF3CF30008CF3CCDCDCDCDFFFFFF8ADA -:10571000042FFFFF0C30C30CC30C30C3CF3CC000C0 -:10572000F3CF3CF30010CF3CCDCDCDCDFFFFFF97A5 -:1057300005CFFFFF0C30C30CC30C30C3CF3CC000FF -:10574000F3CF3CF30020CF3CCDCDCDCDFFFFFFF517 -:10575000310FFFFF0C30C30CC30C30C3CF3CF30040 -:10576000F3CF3CF30040CF3CCDCDCDCDFFFFFFF3D9 -:10577000316FFFFF0C30C30CC30C30C3CF3CF300C0 -:10578000F3CF3CF30000CF3CCDCDCDCDFFFFFFF1FB -:10579000302FFFFF0C30C30CC30C30C3CF3CF300E1 -:1057A000F3CF3CF30001CF3CCDCDCDCDFFFFFFF6D5 -:1057B000305FFFFF0C30C30CC30C30C3CF3CF30091 -:1057C000F3CF3CF30002CF3CCDCDCDCDFFFFFFF6B4 -:1057D00030BFFFFF0C30C30CC30C30C3CF3CF314FD -:1057E000F3CF3CF30004CF3CCDCDCDCDFFFFFFF296 -:1057F000304FFFFF0C30C30CC30C30C3CF3CF30061 -:10580000F3CF3CF30008CF3CCDCDCDCDFFFFFFFA69 -:10581000302FFFFF0C30C30CC30C30C3CF3CF30060 -:10582000F3CF3CF30010CF3CCDCDCDCDFFFFFFF744 -:1058300031CFFFFF0C30C30CC30C30C3CF3CF3009F -:10584000F3CF3CF30020CF3CCDCDCDCDFFFFFFF01B -:10585000307FFFFF0C30C30CC30C30C3CF3CF300D0 -:10586000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCC -:1058700030CFFFFF0C30C30CC30C30C3CF3CF3CC94 -:10588000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEC -:1058900030CFFFFF0C30C30CC30C30C3CF3CF3CC74 -:1058A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCB -:1058B00030CFFFFF0C30C30CC30C30C3CF3CF3CC54 -:1058C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFAA -:1058D00030CFFFFF0C30C30CC30C30C3CF3CF3CC34 -:1058E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF88 -:1058F00030CFFFFF0C30C30CC30C30C3CF3CF3CC14 -:10590000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF63 -:1059100030CFFFFF0C30C30CC30C30C3CF3CF3CCF3 -:10592000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3B -:1059300030CFFFFF0C30C30CC30C30C3CF3CF3CCD3 -:10594000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0B -:1059500030CFFFFF0C30C30CC30C30C3CF3CF3CCB3 -:10596000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCB -:1059700030CFFFFF0C30C30CC30C30C3CF3CF3CC93 -:10598000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEB -:1059900030CFFFFF0C30C30CC30C30C3CF3CF3CC73 -:1059A000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFCA -:1059B00030CFFFFF0C30C30CC30C30C3CF3CF3CC53 -:1059C000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA9 -:1059D00030CFFFFF0C30C30CC30C30C3CF3CF3CC33 -:1059E000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF87 -:1059F00030CFFFFF0C30C30CC30C30C3CF3CF3CC13 -:105A0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF62 -:105A100030CFFFFF0C30C30CC30C30C3CF3CF3CCF2 -:105A2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF3A -:105A300030CFFFFF0C30C30CC30C30C3CF3CF3CCD2 -:105A4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF0A -:105A500030CFFFFF0C30C30CC30C30C3CF3CF3CCB2 -:105A6000F3CF3CF30040CF3CCDCDCDCDFFFFFFFFCA -:105A700030CFFFFF0C30C30CC30C30C3CF3CF3CC92 -:105A8000F3CF3CF30000CF3CCDCDCDCDFFFFFFFFEA -:105A900030CFFFFF0C30C30CC30C30C3CF3CF3CC72 -:105AA000F3CF3CF30001CF3CCDCDCDCDFFFFFFFFC9 -:105AB00030CFFFFF0C30C30CC30C30C3CF3CF3CC52 -:105AC000F3CF3CF30002CF3CCDCDCDCDFFFFFFFFA8 -:105AD00030CFFFFF0C30C30CC30C30C3CF3CF3CC32 -:105AE000F3CF3CF30004CF3CCDCDCDCDFFFFFFFF86 -:105AF00030CFFFFF0C30C30CC30C30C3CF3CF3CC12 -:105B0000F3CF3CF30008CF3CCDCDCDCDFFFFFFFF61 -:105B100030CFFFFF0C30C30CC30C30C3CF3CF3CCF1 -:105B2000F3CF3CF30010CF3CCDCDCDCDFFFFFFFF39 -:105B300030CFFFFF0C30C30CC30C30C3CF3CF3CCD1 -:105B4000F3CF3CF30020CF3CCDCDCDCDFFFFFFFF09 -:105B500030CFFFFF0C30C30CC30C30C3CF3CF3CCB1 -:105B6000F3CF3CF30040CF3CCDCDCDCD000C0000B9 -:105B7000000700C000028130000B815800020210B3 -:105B800000010230000F024000010330000C000051 -:105B9000000800C000028140000B81680002022062 -:105BA0000001024000070250000202C0000F000086 -:105BB000000800F000028170000B81980002025082 -:105BC00000010270000B8280000803380010000002 -:105BD0000008010000028180000B81A80002026021 -:105BE00000018280000E829800080380000B0000F4 -:105BF000000100B0000280C0000580E80002014002 -:105C000000010160000E017000038250CCCCCCCCAE -:105C1000CCCCCCCCCCCCCCCCCCCCCCCC00002000D4 -:105C2000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCB4 -:105C300000002000CCCCCCCCCCCCCCCCCCCCCCCCB4 -:105C4000CCCCCCCC04002000000000000000000000 -:105C50001F8B080000000000000BFB51CFC0F003B9 -:105C60008A59051918AC84117C7A607E4ECAF43BBF -:105C7000F232303803B12B103700F1616E06862303 -:105C8000DCC4EB3F298F607BCB32309403F1766923 -:105C90000606133984B8AE0203C33C203F012AF63E -:105CA000144867CB53E6EEC182155431C564951193 -:105CB0006C452CF2C858094DBE461995AF4C40FFB3 -:105CC00040E3781D547E8F16847EAD0DA113D0E481 -:105CD0007BA1F28E507F25EA6037D789487FA7B233 -:105CE000A0B9078DDFCA88CA37E340E52741D5034D -:105CF000000749300AC8030000000000000000004F -:105D00001F8B080000000000000BED7D0D7854D5BE -:105D1000B5E83E73CE9C9949CE4C26BF4C20C04975 -:105D2000082168A4C70069B0584F2060A8D40E1499 -:105D300069AC8A032244082452EBC3ABFD328100D4 -:105D4000010204B13414A44300A5B7B43752B4D44B -:105D5000523AE0A7C5D6F7BDE0B356AFB66FB4145C -:105D60007F8A12F3AED6BE6BEBDB6BEDBD93734E49 -:105D7000664810BDED7DEFC6CFEFB0CFD93F6BAF1A -:105D8000BFBDD6DA6BEF71BBFC246F34211FC3DFBC -:105D90007584FC2F8D1092DBFF747B4934FD738476 -:105DA00064E698D1441921C372CC389944DF075571 -:105DB000DD23F5B713CF9399334350AF25D70C119B -:105DC000DA474BE67C1281BE227584E411A2780981 -:105DD000FE89FAEEE05C2F29C3577FFB587C9709B8 -:105DE00059172CCA8076CEFE09891132D95A7611FC -:105DF00022FAA4EDBC006F068557A72F289C699353 -:105E00005CB1EB0B29DC7A0CE14E2FA070D3F2C908 -:105E100091CF78C7D0F2A66B5D86075BDF4D480552 -:105E200021ABA02FDA76D35571FE5D31A03C433E05 -:105E3000DCAC427B9D181E5AF65FD51857B19DA960 -:105E4000E5D37641C2DA054B97CC261308C930D585 -:105E50007EB8583D9C7F3AAFE7D1E9F7D2FEEFE933 -:105E6000A4ED3D3900A50409FB69FF958EEFA5332C -:105E7000DF807ED389A55F3A8FEDF08F7C42BE40F4 -:105E8000FC39E7A0F3CF93CF031E487516215306C4 -:105E9000E2AF1F6F51A42F217536B8041D3418636B -:105EA0000C21D7B7265E72E550784C17013CCD9493 -:105EB00035DF185ADE765A463C6CABEDF106359C60 -:105EC000DFEC7CDA6E34EF677425C5039DCF9E2628 -:105ED0005AF60CC46FC1A46E13F8C33FA95B22B479 -:105EE000BF0283906C3A9F60232D17D176247E6683 -:105EF0000CE52FF2009B6F94FEF771513F1E331992 -:105F00000A88E6C07326E091E2A9E01EC7FB4A8634 -:105F1000BF4C62C16B217213E2E90EC0DF95C8F37A -:105F200063117FD12CC4EB50F127E011F80B723EC6 -:105F3000BEBE2651AB00DF4CA5F8037C513CA6D376 -:105F4000F9F6BEE489C985D08DD91D027C8BF95440 -:105F500032FED9C2E1DA08F81B879F5CAE1021BE81 -:105F6000B22E93C94B5C82727A199D01EDCF6732D4 -:105F7000FCCD903509C6DB5CCAF8940E20B92A071F -:105F8000C245FFB0FD660A8F668167B3B7CB2BD1E0 -:105F9000F2760A6F14F04F8E04811FC5BC3DBACB58 -:105FA00086572594E6E07306A7806FBBC9E4D80244 -:105FB00007BE27DD5DAD1285F383192EB2491ABCE9 -:105FC000DF6D7DFDD8FB77F63B287C89A0AF98CEAE -:105FD000EF8367656313C5CF66BDABD545E1D85682 -:105FE000CDE63B90CE97395E4F8FB77892653C8374 -:105FF000C9CBA73E0EC9B4CFAB32E80B965DFE38D5 -:1060000024B87034D03F153D3E35F8750ABF054FB2 -:10601000BEE2A004FDFBAE7AD04B50EE8F78010EAD -:10602000E73803E0758CEB1C47298D9A0A96ECFA49 -:10603000C8138C1162D12F58478727D3CBE9865DCF -:106040009FF84AEDFAD9A9CF15D03701686FD7D795 -:106050003D42CF083D3D69887AC6AC43788B48DF26 -:106060001FCAF3182ECFD30F253ABC147FC57B84EB -:106070009E7EE057A5941F0E829EA6E5831D04D741 -:10608000C38347498CC935D3D713786713B8DEF972 -:10609000419FBEB1E3E7CA76731AE89D3262BA7CCB -:1060A000B49F31878911A7EF0F93F8DCF1A0C78E59 -:1060B000B1F97BE97F563D7D05C7E395871B5D40C0 -:1060C000CF317BEC78BC82E3B7ECA8E33DC7DF15AA -:1060D0000EFC6D837F507CE54B1C8F634909E27198 -:1060E000EA10D73B8E47A7BEEEC3E31EAAAF29DE58 -:1060F000B2830C8F2D6D2E02FAA137E642FD585A5D -:10610000D8E842FDC9F5F6783EBFF17CBD3BC0F151 -:1061100027E02C9E6D5401DEC612E324E8E5CC7620 -:106120008A37027ABAA00ACA3B1E22489FB10FE9F9 -:106130002EAEDF109E4CBEFEEEA82E7F16E4A2F718 -:1061400021C590E9380789B1C62BF5E3379B8F9FAE -:10615000CDF1F86543B6F1A1938ED91CAF4EFC94F6 -:106160001EB0E37FAC834E63DAEDE56C075D6E90A5 -:106170001CF6C710E9E15148D49305E518DA755EBD -:106180008AFB5C5A967FFC940978D63AD8BBCC3609 -:1061900057AC908EE36F6165A54D8955513CDC0687 -:1061A00086172D8F6B2531B047E56A9324281EC7CB -:1061B00005E344A678CBAE268837E2B02F05FD8AEA -:1061C00039131473FECFF872B90FE8B52348F10EF6 -:1061D000EBE26C85B7377CE1ABFAF1EED40F5FAB45 -:1061E000B5E3FDA670BA0D5FB3F46C5B79E2E9E14B -:1061F00017A593D01F828F04DE06D0A1D55EF65777 -:10620000DBCB4EFD13951CFA678874524F91529068 -:106210008B71AE34A3B37060BDED928BDB43DED8DF -:10622000593ADE4222910CDAFF0A921805F83EA68E -:10623000E9F87DA52B9107E50BA467E7C831FDFDC3 -:106240008F52C83189DAED1245EF6A0AD2702F8970 -:10625000A7A33D4CC2DE3C4401E245A2FFDF8AFC1D -:10626000A2B8005F2382EC3D896628500E11F1A789 -:10627000239D3CFC9FF9AB9FF98B44E92BF1A70CC4 -:1062800074A4E3BB4904F9C14BDAB19C46BAF0A946 -:10629000916E7C06A8C68667900425786611039FD8 -:1062A000E48AD8637194C30782C8F7BE3F908FD346 -:1062B000FBE7B38ED36D3809FF48CA053AC4895746 -:1062C000EEE7433FE7436AAFA15ED64A19FF6A9300 -:1062D000E8BA5A86F28F7E17F988E2B702C665F5EA -:1062E00005BEB772BB7A4B9317F5CDE6A6203ED517 -:1062F000A98D61002FB33AD17107A55786AE1AD781 -:10630000D3F90FABEE89839CF85B99DF966630FC7E -:106310009EDCF8C44B8BE8FBB6428DF9412DCC9E38 -:10632000CDE0586C9B9C88ADA5F06D2DF41A56FFFE -:1063300040E8A7ADD7260EEDA7DF3B75DA23FDEBCE -:10634000AC3E9258037253A08226229B27FC930EE8 -:106350007A2DADB8A7C9AA77B40F65A6BC0AA25119 -:10636000E02B3ABF282CEF4EBE6A2BBF02F562DB52 -:10637000A967894E2B14D5C44DC0977F2A3565E98E -:106380003CFC35BA2BAA8154465E053C67B4062511 -:1063900093E22FAB5A9F0632AA119DE96BA53B04ED -:1063A000F23BA0FF91F1D01DB4BFE8B5AA7110D99E -:1063B0004A77CDF7A796872D1BEFFDBA99C4AE0A91 -:1063C000BA24A4FBA96BF3F2C1FFF591607EFA2415 -:1063D000902F951C8475EBDA25A32349DAF5CB5968 -:1063E0005CD835499FA9DAA5CBA4B1CBD26F898BF4 -:1063F000C9A1CBE5C5676619E3A3A252EE17B71290 -:106400003396040E93C3AF2971C2FC39DDF559E20E -:10641000EB6DAE2FB648A4B62BC9F74E0ECF0C7954 -:106420008F09EB6FC646B64EFA28A85D14BE2285CA -:106430003E2DED66F1FA87F8F312F450DE4320307A -:106440003943D3833EC7B8E259FE09C6DD46C79536 -:106450005D415CF704DE9DF4144F97CB87F53EB8A1 -:10646000F6C5101881A9E0D4414687D167017F861F -:1064700050D713BD943D9DE35D6A7F5F74B1793859 -:10648000FB2507985D95C1D7AF93534A9AD1EF9DED -:106490002DFC50BBDE007F18F451E701BAF01782E3 -:1064A000DE60E5CD318276566F1965E42288277467 -:1064B000A3BE2D20119463FA09CBAD5CFFAD07FD9F -:1064C000479FEF93F02DAEC9A04762A7145A69F613 -:1064D000A4BBA7258B1FDD09F231F9D2D6A92FD293 -:1064E000E7426F7829F4AF19674C505B99F3249415 -:1064F00027A75C51F60CCDB5C80D91055F30796AC0 -:10650000E1FC0E723387966B8A93C3D9B9B1223FEF -:1065100082FDE9C3D1EE50F4E1D67E3BBFCCE46A04 -:1065200087437E3AB8FCAF017EBCB479E6D5D0672C -:10653000D08899A02EE7471B9F06BACD93221B5CFB -:10654000B4DEBC7BC26E903FED40375D23F1FD268B -:10655000C0478DDE0E94239AD91D85E7E6B245A883 -:106560009F7B436CEAA9F82ACD74D9FD27A73F3851 -:1065700044791C6F44A701BC7AED7B277375A05347 -:10658000E461806B64F86415A05DD3CF9859167AE6 -:106590006597327DB882F371E66C4A37D0778A19F5 -:1065A0009AE387688EB91FE63BD4F153F13DD89D3D -:1065B00080AF6CCEE72D06E3732107195C0E5AE01D -:1065C0003BE06B12E3FB96607930D93AB187AFF3C9 -:1065D000DFE37C5F4092EBA193AE4BB7C3C6D367BA -:1065E000095DC1009EF749E469987F1697B3CCEA2C -:1065F000980BE011F234DB38539D9D03768A5E0ED2 -:1066000076B118F71DCE6F0BBDE6AFA17D4D71B30E -:106610009245E735AE8C18A05E6715674A563EFF77 -:106620006D5FFDF0F3505F2BEB46BF7CB076DD7CF9 -:106630007EF3A4F0CBC87F0FB42B5EA47BF815ECDF -:10664000E7816EE2B5E89B228E6779E3A92AA04331 -:106650006F2309025FCED71B9F9680BF43E1752E43 -:10666000CB3C66E9763B9EF2F99BD0EFC8463B7F78 -:10667000D69076855CC2BA314A8AF400BCB31FE872 -:10668000467833AB993F4CE1EE45BDF2E9C3FDF1ED -:10669000C5E07E13843517E47D1FEA330A9F225339 -:1066A00038C6CD8E2B5988F7330AC047F1ACCA16CD -:1066B000391FAA7CEF00E0260F2EE72DF08F29600E -:1066C00027477264E03B61F7264E12E66FD9E396E6 -:1066D000C25E0E84A8BD4CE525B32641C03FCE3E28 -:1066E0002D1BD7D32AC36A8804FE9FB063B3B85C5E -:1066F0000AB8B6723B794B5308E5285BEB390D714C -:10670000FEADF92E630D01F9AD40FB6D4755220436 -:106710007E60B0B262E31DB47D5B938EF5373619AF -:10672000D87E4353253EDB6B5E47FB776B88D9BF32 -:106730009B9B4AB9D3C1E0CE1276728D885FDAE1B5 -:10674000A2ED6DFB1FA23E0959E25A4596F63AD3D7 -:106750003783B54F9F648F8BF5B53787D6DE67D803 -:10676000DB57998956F087833CEE2FF45E80D7097A -:1067700056BAD06F1678F694DAE9DE5E937C3F471E -:106780003C9DE3113DCD367F12AD43F85671F85272 -:10679000F5B38EC75F44D9CDED4567BD15325F1F98 -:1067A000F9BE54908FB5C3A4F8B0C461B239DF6D9F -:1067B0009DCDFC321264F13AE197B909B1F9656EE9 -:1067C000BE1F8565D4F751A68F1DF08BF62A6F9FEB -:1067D0000A0ED5D9DF59DA4F85A51F079CA9E073AA -:1067E000EE939137EDFDA4D65F8E76E7874687015D -:1067F000EDC06A28B596B31CE5E18EFA458EEF57D9 -:1068000038BE973BCAD738EA4F7394BFE4A83FD746 -:1068100051FEBAA3FE22C7F7658EEFAB1CE57FB22F -:10682000D72FBBEB93E1F7FF333C09B91A88979850 -:106830006D9FD7295745243E2A0E7E43E6734BE0D1 -:106840005342969473CC1761712D129F60F55FFFD0 -:10685000A845FE00EB58E747665A98CAD581F6E787 -:1068600003A08FC4FBF3D2AB81F13A21F56A7C25FA -:106870008B03B5A3DCA411E5F544295049C2F8996E -:10688000575B8C28F716D3F7567DD5CEE4AD18FCB0 -:1068900022DA2EBA5D45BB2F3A92C4C6D2766A81FF -:1068A000BDBE9BF74F7258FFF89EF65BAE307F215E -:1068B000146EAF02D91D5EDB75129E4EFC84A64796 -:1068C000AF7E06E20B3B981F7E6006F5032C7AEE46 -:1068D0006685E9B7DB944BF64B5F9C28F7F77FE0C2 -:1068E0005B9AD14CAB1C0020C0EFFF963706F18CB1 -:1068F00051109F639B07189F1B49F81F8FC381BBD3 -:1069000008EBCB48ED34C6DBF4BAE029D0757395BB -:10691000121CEF7B52CF7818CF957EFE6AB62EFE02 -:10692000ED63B47B38FE429B2B12518A3FB24D354A -:10693000C61258520D94238F425A3CE5C01E0CDFFC -:106940006B61D565EF157F16C4D9C2585641EFC2A9 -:106950003A067C24C3FE761CCB7E92C07206B76FCB -:10696000C781B3087E00D125A6270D09F6994237C5 -:10697000503F3CC9BA1196AAC62993FBE39492CE24 -:10698000E29152DB337F91205E594A74B64FC5E3E2 -:10699000821B65E96388B70687B6CF13BAC54E5721 -:1069A000A2B49339163EBEA58F9E0C5F63426CFE67 -:1069B000A16D6A23F8310766D9F940D497954BF653 -:1069C00007774E18F3D9F141A63206E119C807B787 -:1069D00006213E2D4529DED2878EB7A06C7E5DC193 -:1069E00079122CFF40326F053A89B242CC05D6F2BB -:1069F0006FE5F0422847A791D246ADBF1FFA7E71DE -:106A00008AF74B93BD1F27ECD5B36CFD2EE1323EC8 -:106A10006C4FD005766461C7AA34AB7D55C2D7E907 -:106A2000473B8EF860BEBBEB93EB3FF1DCC2FDBD94 -:106A300054F502527718E841262BE460127BFC499A -:106A4000E06F8B1E0D38ECC2EA966815B4CFAA75BC -:106A500011880BD3F51DEDBA426E1FEE9C1A9554AA -:106A60002A873B7611B48FB35A16F9ACF3C9E7F312 -:106A7000D9393B2F0DEC957D8B177D09FD156AF7F4 -:106A8000CB181F8F6C82FEF36BD83EBF13BECD7C3C -:106A90007EED8B199E9CDFD355124926874F2ADC49 -:106AA000CF55A212C9EBDF37D97CF2BE5F8DA7E3C9 -:106AB0009554BA0C9FDE0FE7B83E7B2981F84ABF98 -:106AC00046096E027BAA43B5D999FBF63CB86B31F7 -:106AD000F837F43DA88347AE6D1C1EA6703DFAE55D -:106AE00025CFDE057CBFCE45401F0938B432BB9DA3 -:106AF0007BB24F3EEDE3D27E991F47970F39C9FE17 -:106B0000C9E5E2A3838F9B8A4F9CEBA9930F2E6567 -:106B10007DB851BEFCF9FD18E490C293C7F3B58669 -:106B2000D5EACC6FE37294ED158A848D93C7F92C66 -:106B30006BF6833EE0B35DB5E5283FBDB31749A0D2 -:106B40004F441E54AAF152C193EE6EF7411C74D704 -:106B5000E207A56478CB8FB0F890F3BDE966FAB48C -:106B60004D6997A07DAA7AA3DC9C1FB85CE5F379F8 -:106B700085A6C6C380AF3C43216B28BE76CC5E544D -:106B800055027C47E510E22AD53504ED877C93ED6C -:106B90000B0529BE9EA4EBDECEC5C488D37A3B4D3F -:106BA000D5B61F23E4D0C98F3B175F5CBF10AB7F06 -:106BB0004EF95F716B6C7FB09814831DB523857D92 -:106BC00076A9F80D2D76B1F86875F920FABCF9525E -:106BD000D7A9F9D7023F0E35DFCDA12FC853BB6629 -:106BE00095805F6B507D4192E1C7AE1F06C387134E -:106BF000FF13009FE99F1D3E9DDFB3DD3CBE3D447A -:106C00007CB4D516FD0FDC034F51DF391FD14EE4A4 -:106C1000A77D91F4C820FF2670E818F0260C7C565A -:106C200093303EBB95C857DCB4FE4CD28865117FCB -:106C3000AA53828C1E3CFF45EC732BD319DF8F9B2C -:106C400048629DB07E4C9DCB377F15F39C178C36E8 -:106C50000A47127F8A903538EF118EF558C427867F -:106C6000D5B7CF2EA7FD8E98EDC2F8C588CA23B63A -:106C7000752CC0E547F4B7BB7268EBF3238EF5F9CA -:106C8000112581F95D8F54AE6986E546C97A339442 -:106C9000ACFDB80E3B5EB77ED4E50B278167F7E20B -:106CA0006398C7B5BBF2E2F1934706E19B7172723C -:106CB0007BF68B1EB6AFB43BD37B334B2E5A6DCBDA -:106CC0004320B256681D77F74724337C517D629785 -:106CD00097AD6E9E6FE0277EE0FF54F810CFCF1A7D -:106CE0000F8F4E6B5C164ED2BEC4C3EC89759924CF -:106CF0002A533E79F4652506790E84EBE18A9BF5EB -:106D000018D80BEB404950FDFB6815C1EF1599FCF5 -:106D1000FBC33AE6558DE8205195AE67235E5ABC19 -:106D20002393D66B5B4C3DC7C2FEF76DC6A956D800 -:106D3000177EE20517C6732B7C71AF41E755C9D7A3 -:106D4000C1DD8B4F61DE71748F628C45FD2E11A900 -:106D500002BD785B1CF3845B61EBBDF1A04FA7ED36 -:106D600077E909ECE79B534E7975D82F2FE8F6C2E7 -:106D70003CB754B2F5F2C8E2A2AF96205AED79269C -:106D800033E5A9DD261D6FCB62B65F9199E8F67AEF -:106D9000E87C02B50AB99EC217D0D87CDBD6911820 -:106DA000AC53E53C9F442273D01FCE77E409E5390C -:106DB000F24D82C6CCB760DF3F08FBFB3009B97EDD -:106DC000C755A06F1B5C3C0DD54439F5F3F9F90D9F -:106DD00013EBCF948FFB60DF77578B12C4F5CFD1C5 -:106DE000AF731E411239694AD80F8EB3EB21B64EEC -:106DF00006276B06D558B429873B48E1CEA643B693 -:106E0000D8E11678758EE37794DF14FC3C828C050C -:106E10003D24E2CC027E27DFE654C48E3E4FE7BB22 -:106E2000FB050DD7EBDD95CFDFD200EB7CA907F397 -:106E300023BEF4C1A1FA7FA1CF5FBF77AC189E3704 -:106E4000E41F98D4007880FC8889A42F8E97073D92 -:106E5000A3FDCAF59A18AF6C5F8B3B075F45FDB485 -:106E6000BCE5D4CB75108FCEAF2768FFE62B8C3FE7 -:106E7000FD2DAE5833853FE79A76E48711B571044E -:106E80005AABED92A29678A7C8FBF6D747308FE2AF -:106E9000FADA76CCF7F6F3B8AF7F523BDA4933E44F -:106EA00057BD68AF71FA89FC77217F4EFA942CEEBA -:106EB000AE817E46B42806803DA2BED105709554B1 -:106EC000D2358BD2ADA4A34B62FE1FCBA76729CFCF -:106ED000F419AEC3BC2CB287E5178A3CF040BD9DC7 -:106EE0007EC1BEFCF9880BFCEFC20EC7F770CD1B4C -:106EF0008C0FEDF42C52393D4B781E21C7C3088E00 -:106F0000872DF57C7F4EF3C62E66D7BEC0F7E75EB1 -:106F100084F98F1BF8FDA614FAF746D0BFE0B7BA84 -:106F2000BA5B011FE41A17FA714E38B6D633BD7733 -:106F30004075D9ECF8CB1DFF36AEFF6557E2EF3256 -:106F40007E7DDFFCFF3EE3DFFF771E7FD3DF19FF8F -:106F5000BBFECEF33FF41F3CFFF9A592CD4FEB549F -:106F6000BDD8DF4F3C223E66D7DFB22BB9BFFDBA9A -:106F7000EAB2E5138BFCC4E9B5E6428897F80D76D2 -:106F8000DEC3D9DF0CF9B956D083BB785E36D5A302 -:106F900026E4A9664C1179324CFFD570FD57C3F534 -:106FA000DF91147AB5BC92E9776A5FC4F442583233 -:106FB000DAD19F099C56303FFB08A1CB0CE835DDA8 -:106FC00093343F3B8FC3EDD4A7795C9F963FE7781E -:106FD000CFF5A8739D2FEC8B9F128C9FFE7795E7C2 -:106FE000033BF4AAC0C3AE4A662FE7CC4D6E0FB682 -:106FF00039E8A84D6AC4FC03273D5E57997F2DE808 -:10700000B1D06BBEA2E6A6A67782D3FB3A4EEFDFE5 -:10701000A83C1F8AE789A4A277A5878DF379FFD9B9 -:107020005033CC265C857490399D64D2D68DF15F47 -:10703000F24D62F52FB77E44ED1058FF35CD584321 -:10704000CB9FCF212E9174FF91D89FA37FEE6E1618 -:107050004795735487BFE5B483BD513837B3DB74AC -:10706000C5A285604F74EE5E09EBD30B6998A7BC8F -:107070003BB3E339F4E7DA272A0087B01B098FCF47 -:107080008249C1F2509CFB4E76BB7FF7475D71B0E1 -:10709000BF828512C6FD5AF50773929EC773D8FB4F -:1070A0009AC76FF377C9F543B3DBD7727A537F3151 -:1070B000D76391EFB5FE9913591E547510F67724D6 -:1070C00073A60BE2E9A9FA8148EF39CB7E539D62A2 -:1070D0008E84FE24F01F4BFBFD47420A587C5ECC99 -:1070E0007FA8E707EAEF62FBDE1CAF39D7747D2A81 -:1070F0007EA4F0FB453D919FE7ACE7F4C7AF779BDB -:1071000053607E43857F2F301CC4B3CBE49A64F177 -:107110008304D7AF5AF8B1676FA25527CD93587C37 -:107120009F9A6DD6FDB4B61CA52659BCEB975C4E54 -:107130007EA3EA5CAFC7499684F92404E625E4D12E -:1071400039FED57CDCAB2F73FC17B85C5FCDE59ABC -:107150001003F763528D5BC5F586787ED271137C80 -:10716000DE552A8F6B0C32EE1C3ECF399739DFF398 -:107170007CDC39439CEF423EDEC2CB1CF7433EEE43 -:10718000C2218E7B37C7EFDD978967C52BF17E86DD -:1071900086E7663E5EF3658E1BE4E3360F71DCED39 -:1071A0001CBFDB2F13CF057CDCED0E3CA792DFCE9E -:1071B000CB1CAFD4CBE4E700975FA75E13E36BF97A -:1071C000AE30B4DF1DB2F77383878D2F9E24FE315E -:1071D000FAAF23F8BEEE9495F72E32938C2BEA3B50 -:1071E000D7E354E3DCC2E335E229C609F0FDD02938 -:1071F000D7D07192E047D4BF5A657A3055FFCB386B -:107200003CCB2E711EA27E15F43F3975FFF7713805 -:10721000EE73C03F58FFA2FE9C41E06FE570B45E84 -:1072200022FCA2FEC241FAFF0E87E33B9708BFA8EB -:107230007FF720F87984C3F1C825C22FEA370FD22F -:10724000FFE31C8EC72F117E517FFB20F8798AC384 -:10725000F1D425C22FEA1FE89377BBFC69E23E0612 -:107260008394429EF1289266E0FD0646E224F801EE -:10727000DA6A76BF01E9729E87B29CA3A2227EF2EF -:10728000BE9228D4DF7B178BFBEDBD9AA01FB137D0 -:1072900097E729F3B896C6EDC1BD57B338C8DE10DD -:1072A000FD6EF1CF44BC68AFC1F29C7B0B581EB39E -:1072B00056D68E26260E97C74D441DF269D8B92A98 -:1072C00061EF89F3556B799C6AAF49304EB5B78C45 -:1072D0009577579398ABD072EEAA348EF9A760D801 -:1072E000423CB6FFDC984956975BF23156C731DF16 -:1072F00040E179231421C49697E138AF25F60F6F4A -:1073000032CC19A0E60A27B1FDBCC2B0DD7FA88748 -:10731000435CB4FEEFB99E0C4E4A7E9EE6B05761C8 -:10732000F4E3F99AF3F8FC05DECA393DB7CE79AF3C -:107330007B3A9DE7B353DD983FFAEC698EC7A9729B -:107340008CED9F1377B27338A9E26C5A47E3293862 -:107350009F7BD373C40032FAF798EB748CAB7D84B7 -:10736000FC8771353AEE4D7BDA15E0BF591DFA7492 -:107370008807CE7B4E5FAB41DE7507314C40EF474F -:10738000DFC07EB25A881163A46A0EA29DEB88CF3B -:10739000F17393223E07E16AAB7F398BCFBBBC25EB -:1073A000B80EB6EECAAB3D36FB7516F733BF627A40 -:1073B000ECE725F9F9C7590E3FB3C36B8FD7691DA9 -:1073C000E11910FF96E79D31E1FCF3B8B0141C46BB -:1073D0003FDF16DEAE407C72D69E46CC5F4FB5BF17 -:1073E00095F1F05CBFD57E17FBD9BFD973717B5D7A -:1073F000C41944DCE134E4157BC04F0F71BA30BED0 -:1074000012FC91354FB2F1498797E9910E2F8BE32A -:10741000FF179F7CBA7CF23BAF3DFED001DFA83C5A -:107420009618C9F7E9EBBCEA7FC9EB674087802F64 -:10743000391D487D862D8F58E45539F1B681E34DCD -:1074400094BD29CEBD14F8F83AEBF4EB5F8D54C12E -:10745000BC449C8690FB1DFB9B538D8BC5256471A2 -:107460005F8CEB5519E653EAE3FA47210AF6EF98E9 -:1074700007CA7D1E9E53643038FA5BC7CFAB89794B -:10748000B98BC326DCB742C7C0FD3EC8573F520682 -:10749000EB63D0366FD3C7D69B4DA58CDF36952ACC -:1074A000B174965F65BFB7A8B8D39BCCAE104F62DE -:1074B000BDB7A26820BC6A71246A8547E5F038FB35 -:1074C000999B129E3A5BFCEB52E1F18C27A41BF8CE -:1074D000568911A697BF61EBCF551AC3F3FDA9FAE0 -:1074E00051743E2F075D528DEF2DB0E741A93969E8 -:1074F000367E57B42C479E9483BFFAE242431BCF9B -:10750000796EB1859F4771B6F729EDC44882779FA0 -:10751000EECCC788211D9CE76ADC4107DC8EFEDBD0 -:10752000E05D923C1C71DFD006BEAE6D5462686FA8 -:1075300045299890EFB98EF3A5128CE1BD5EDFF678 -:107540004949E74F8CE4EBAD529C1C7E6F811DEFE7 -:107550006A4E969D0E4AF2731C1B85DC070F98F647 -:107560007BAC9C727EDCB8D87ADE77AF96F43BF9C0 -:10757000633AA5833EC73D0943A4AFF261369E6BD3 -:10758000EF2B53BD0AF15A2A2398CFEBAC7F46E08C -:10759000EFD54E845FE8E9F43D22AFF693CD4392F8 -:1075A00008DF27B7B74F29875CCFC99CAF9F1E6400 -:1075B000FEA9E89B56ECCC2B1C1A7D7D20F7B0EE83 -:1075C0002926BF0CCB2EF7A9C6234136DF4B95FBEE -:1075D0004F0A67764D84803E53431112A1EB7C7EA7 -:1075E000A81DF7C935A9270AFE1895291DE8BC3B37 -:1075F0005B67F76658EA4DA3EDDC85AEA81BF24049 -:10760000F87D30D110E982FA108FE92CEBAFA74951 -:10761000240CFCAEE52A61782FFACB986AEF8F9A9A -:1076200009B2F51C96C817405787CEDF3D85FAA7EB -:10763000B4BD4AEDD07DC9F4491AB343D39FF29942 -:10764000982710D662C092F9936298CF995F470C41 -:10765000F0E74A3ABA498476FA6D8063327CA7F340 -:10766000D620FFA31DF7ED733CECDC7A7E7DBBB426 -:10767000D0324E691AE3EF6973BDB84E7CA38A9D80 -:10768000DBEB0E2D6AAF82F12AF97D7A390A194EA9 -:10769000F1E17FC9C3FCCF490902F809F2BC863782 -:1076A0009B48F9E2B184BCDDE4C5E7F9A6203E833E -:1076B0001FFDCF10E4B9AC9B5CA143BEF507FEBA39 -:1076C000D1B06EBCDB14C2EF5BBE65E8904F249F67 -:1076D0007A19EF8FE8E7F7A84C2A210F366102FDEF -:1076E0002CF3EFF459F6F9FBE645E7BB908EB3595E -:1076F00072DD0EE3417911F2A957562DF91F2AF7D1 -:107700001BDDEB48F8B132B8C72426DD5D6679EFA2 -:10771000A3761BACAF938348F77E7CC69A39BEAF85 -:10772000067F37FF398ED7B99517DD37696B8A77B2 -:10773000578FED2F6B29CEBBCD714FBB2E0DE2467F -:1077400070D8938E377D6EE930C0D743EEE4F72FC3 -:10775000C8C1894631D48DE6BB500EF93D2BABC66E -:10776000EBC3322DFDCFE17C299FFA29E237BD8C96 -:10777000E587D0BFD9F996FCFF82481DDE8F441AF9 -:10778000D93918B10F39FAD644336C498C5E6D3F44 -:107790001F33939FF32C5CE7C2FCD7C229A843494F -:1077A0006133BBBF6ABF6C94037F3F4C5EC88403E8 -:1077B000EB0514BE9154540BA3F67EF62F99FD0CE5 -:1077C000C401C4B9D1B52DACBF51BA715A87F849BB -:1077D000990BEDE5D1C4F042FFA3351781734563E2 -:1077E00088A59F4238476BEFD7096FA1DFE5827804 -:1077F0008780671439EA3573B07F12A3ED0BA89B1D -:107800003722097CCE71C6887A579597C7499271FD -:10781000494F33EC0B0D187F907E9BD2B81DEE279D -:1078200001D0E77B2436FFE8B3B27110E87AF72184 -:107830008CD714ACEAC075BD238DD977EBA93DA0D8 -:10784000B9C14EA1CFB1A9F9500E52C465E0FA9169 -:1078500094FF1E4DABDA9606F1B0B469DB800FD30E -:1078600014FD6B783FE76937817DCC34B31DE50F9C -:107870002E64023B6373595106C85B5AA39AD45FC6 -:107880006B4973237C7BD22405F242296FE1BC94BF -:107890007AFD3B3369B13BD7FC1E8CF397DC083E85 -:1078A000C5FBD0A25A1DF873FAD2328C7FF5764808 -:1078B00018FF7A438AA990AABD7C5EE304B82F67BB -:1078C0004E66E41168B7548EAF77537856DCDA58B9 -:1078D00002F8990DF97EB9305C94F98305AF1B0A63 -:1078E0009C072B50E26ECADFDEE0A997D8335A0519 -:1078F000FCEE859330949E8162F32DF09BFCFC1C82 -:10790000924C7AA2901718984AC8EB16BA814F6722 -:107910002DC39EAEB59C0AFF833D17D3B6AF8F85AE -:1079200055DE3025B40B62883F35684C0038E5D011 -:10793000E9BC62CB3AE7E1F3F34C5FC4EF4932B9FB -:107940007F6310AB7FEBE1F3021DFEBAA5BD3B6484 -:107950002FCBC14F771EC2EE967EF1D77340C7B5CD -:107960008FBB31EE39FD7177FC3A5A5EB14FC2756B -:10797000C67582E9F5770F4828F771BF8A7AE09DCE -:10798000A017CB0D9EEEAD5FA0E59EC765D28968BE -:10799000A9C57BA5CE89F5F4182B2FE10ED28A7DDF -:1079A0002717407F75C73C04D689153F5D7AE317DA -:1079B000687929E563A8B2E260B33A9C96EF8A49F8 -:1079C0005D50BE308D209F45B3D418E4B55C08747B -:1079D000E7DDA4E13A46F471B0BFDD9D378FF2E3F5 -:1079E000B2D86333A1DDB2C3124452E93C0E3E93D8 -:1079F0004FE15AF17D09D7C7E587D2D95D2B1C7FAE -:107A0000E7E854AEA3DF57D179823E5C4ADA6702D9 -:107A1000BD561CDCAE5AD7B9B79B4A31F5439457D3 -:107A20007C9F8E43DBADFC9164C0145742BE03AC17 -:107A3000973FF5D5EED7607ECD6A891FE6B54185C3 -:107A40007A4B630B9FF0E900DF3E7526FDBE6CCFDD -:107A50003E754919E08DDC0EEBEAF2435712DD4228 -:107A6000D7731D32FA0BAB32BD9D78BFA966BF0F2D -:107A7000A51F2E62836B19D71BD4EF53ADE7DD9E94 -:107A800048CF443E5D7E48B68D23E81F3D43D879FC -:107A9000B49FFBF13C9AA09F58AF04FD56890BFFA1 -:107AA000949E8A64F06C057AC0B91BEADFC0F3C10A -:107AB000A6103E1F6AD2914E3B018FE3585E0ABC6E -:107AC000A7725B05F756054CB8180CCEA5985590D3 -:107AD00087991566E5BC5B23927E113B5D3C77BAC6 -:107AE000230BC1C8999AFEDD190AF5C776AA91BB86 -:107AF00021641D543A6754D335AF3E3D5C916ED935 -:107B0000F75B2FB1F37D9F4BD771FEEBF355C4F7B5 -:107B1000CEDB2AF6F3F813AE933B6F5BF208C4C7D3 -:107B200069FB2FA6837FC1F7FF52B5CF5B50696B0E -:107B30009FB7A04EB49F89EDBD176FBF73C135F6D7 -:107B4000F1172C13ED6F44F8B58BC39F77FB54FBF3 -:107B5000F8B7D763FB060FA36F4FA617F3AD5B7C97 -:107B6000461CF4315EA83609F2C94B3AA19E5877FB -:107B7000A8E637217F5B3B9C59BE8958F968DA0239 -:107B80008003F2B2AC7C9451996693AB4C33CB56E4 -:107B9000CEAE196EAB9F1B2EB27D1F567B85832FF9 -:107BA000353CBF8865000A0C730AA73A5C457D54D2 -:107BB000359CD9C1F79EF061F9DE6BD8FCEE1DAEA5 -:107BC000A11C03CCE097DFAB463E67BDBF95C03D2F -:107BD0004854A7DEA945EE8379F4BFD75DF03E8D0A -:107BE000E73BA57908EABB0D8515FBA3167CB68E8D -:107BF000A4FC40CB2DE92AC33BA7C386914B425638 -:107C00007B7DFD48B516FC0D787F8706E385D7C3DD -:107C1000780D6A4F09D81DCE713C4595B671BCA34D -:107C2000EA709CEDE92C9E2AC6F18CAA738CE3AD18 -:107C3000EDE4EFF9383B80CF528DB3A1E81AFB7C1D -:107C4000462DC371F63AC6D9306A99639C34361F03 -:107C5000FA9E8F13BBD8389E3153EDF3195D8FE335 -:107C6000FCC0399FD1F58E71341C07DEC338D4F0C7 -:107C7000D5E1BE2CD5D3B304E9FF0B1FDA39AA270F -:107C8000F228DA39AFF8D0CEA1B54CA8474A997F8F -:107C90007B4F7A16D2E783344A7FCD4AE728CF3B21 -:107CA00088A25F7C270791C4284454BFADE43CB848 -:107CB000F8F09C51CDF03C363DB410FCD187FC1857 -:107CC000C77BF7D874F58E24FAE8CE76F7B98485A9 -:107CD0009FFBF42A8FC786D2D93EA4289FE3F19F49 -:107CE000D7214E449F6FB809FA436779BCA81FDEBD -:107CF000666C778EEFEB9DDBC3D6A90FB69F71A3A1 -:107D00001D11252F9451B8E7F369DCD96EBF2FB34D -:107D100081D3A3E7A71E760E889823F03EBC8E6C15 -:107D20005BBCF07727BEFC0CCBBB2323E0DEDFAFD0 -:107D3000B73EF634547B515A3872159D6FEDD1ED34 -:107D4000EE11B4FCAE3BB1C0D02CFDD4BAF1DCBD19 -:107D5000F0436E8EB86DF6F32D75F6F26D0E7BFA6C -:107D6000D5F422B13FCBC6D5636EA0D77CD863A52E -:107D700024BC0D9E987C17447A2D08B2B6029E86CC -:107D8000FBDD248EEB5D2217E39CD15C8CD344C4D5 -:107D9000BAE5806F81DB6B86293D17DC27231E9DAA -:107DA000F0264EA49B2EEAE7243AFEB71BCEF10C38 -:107DB00006FFEDABEDDF49D46DBB8740F0C1D76A5C -:107DC000ABF69FB5F0C7CD9159FBCFDAF034C7566B -:107DD000BEADF1665BFDDB572FB47D5F18BDCBF602 -:107DE000FD8ED6BB6DE53BDBEFB3D55FDAD16CFB27 -:107DF0007E576CA3EDFBF243DB6DE5155DBB6CF5C7 -:107E00001B8EEDB37D779D18FF15F4037F23E37977 -:107E1000E7F7B5735BC17E7B3FA8E07ECE9B7CFF1E -:107E2000EE6D7EDFCF4AE0BD29203F13BDE0373441 -:107E3000A45179A6B6C4042D777DEB54D02304AFAA -:107E4000D428D746AC8F5267770A3F9F2877A8245B -:107E50009E0DDB2BFD71D81EB9FFBB92A0DF27A6BC -:107E6000FE2E772849BF2B092569BF17A49E12B0A3 -:107E70001FA32F7B929E03EF974B32825CE43EC997 -:107E8000F32E5267F5DFE66B2C3EF44CFAB4F95A48 -:107E90002EDC8FC1E4BDFE48FE34F01BEAD57849E4 -:107EA000B27D9BBEF1BA24BC3770BEC6E4E5AED845 -:107EB000085B3C6DF9A13136B97F292D729346EBF1 -:107EC0009D3F29A39E25F1A7467DF52A18DF9C0F2B -:107ED000EFC9B15C5C1F5F6C32F79FA57EC04B4D54 -:107EE00035F8FCD7A6F0FEB3D4257CB5A916CBBFD8 -:107EF0006F8AE033D15487CFD79B1AF1FBD9A6D52F -:107F0000583ED714C5E79B4DADF87CBBA91DBF9F5C -:107F10006FEAC0F2BB4D317C0A3910F62E09737B33 -:107F2000526C981056EEE57390F3441CD3C0FBA33B -:107F30007AB50F4AC08EEE7DC98379B7A9F0E4E423 -:107F4000BBD4F43371BD5F12B3C799C5D397C6E8EC -:107F5000E373911AC891D83856C5385ADA2FAE440F -:107F60007B9CBE57D865B231634E927B3BF142E4B5 -:107F70006183D349D43FF7DD7FAF585406F42942DB -:107F80003CA53D253732BAED37BE7AD5E0F8439BA4 -:107F90002F7F201EA55FFC6E14C4A7DEC915F8EC68 -:107FA0001E05C12D450BEF023EEC3DEAC179F51EE1 -:107FB0004F67F92810541B42FEEBF243BE98553F21 -:107FC000ACE8CA8CD9F5457ECCAA2F7A4FEF0F804A -:107FD000DCAF0AC9B1B313813F4CCE1F8CEF44FF15 -:107FE0002BBA0A639AAD1F7BB9B75DAAC17B1F8903 -:107FF0009E312F89FF219EAB422A8EF3F6A1319844 -:108000007F40FDC4D85916EF8CB17143312B5FD638 -:10801000AF4E8F9DCDEE872F55BF9F367C841C259C -:108020007FF0A63E8F3BD89328FFA6E2FD6EC7DD0A -:108030001FC0BAE3A1FF7F8CF9420A9645BF0D5DD0 -:1080400072D403E779C961DB78B49D2E7C7458AF94 -:1080500052D3DD9E0FFE7BE0255CB7D9F9F2089C78 -:108060002FA7FD5D50B456E973FDE7CB1B385FAE1B -:10807000F026D4087DF5CED13117CD0779BBE97450 -:1080800050190B7904ED7871445DD7F86AD08FEF01 -:108090001C5D9B07F1B4E572EFBDC9CECD7EA8B1E2 -:1080A000381B89B97B1296F988F80C21B45F6F3FB1 -:1080B000FCC0E9E72C65A7BE164F979FC5DD571E8C -:1080C0003E33F30B14FE95C7DE53018E635AC4E5AD -:1080D000B7CC5FE2E7EB971D7A4D85F9BDE98E9647 -:1080E000DC7F113D35104E2D64DB0F8D926E90E3D9 -:1080F00045EC3718809FBEF60A15CDB77EED26F009 -:10810000BB0E62BF429C7B584CC201C0D7A2A3CB1E -:10811000313EFCD61337707BAEBD02F8E31DE2AAF8 -:1081200081F9BD439E0F4CB4E0AFD8CFFC18D2CA42 -:10813000EC18712E90DAB336BB666987BDBC84CC6F -:10814000CD03BDB1E42137895114DD452CF72FD182 -:1081500079E7F899BDBB9434AE077B4EF130FF60F0 -:1081600051902823A83E5DF193872BC0EEBFD2CF5C -:10817000F61D451CE3AE2C66EF2DCB89A9B09FF010 -:1081800087A313E77F01B8CF135B0FEB32C948BE5B -:10819000FF7747AB1DBEC1E077C22BCEBD0F88A7CE -:1081A0007038E44352D2FCB4297ECE775C8FACF1B8 -:1081B000DBEDFC0D8EF26C3F8FB3CA44063ABF1361 -:1081C000F4465D19F81DCFD9468F788CB53ADCA7F7 -:1081D000150E037F51BB6002B1D4FBA316C1F7E7B4 -:1081E000A5E796E03973253E01F3F1BC04F314557D -:1081F000CE0F725A6002F91CC4491BD1A95FEB0B68 -:10820000744279BD9F9D836A0039A5FD6D09CC3C00 -:108210000D717D2F698F9B85B0FF6D8F7FFB747B08 -:10822000391DE409F409BC007A1804E345E9A5F610 -:108230007A7EC35E5ED687A7B86C3DF711F06A718F -:10824000F89D2152A99CB7DACD2BBD0C7EB8111C2C -:10825000EADFC3EDF995448F62DE6288F1C13DB378 -:1082600058DEC43D7EDD88D2EF9262E2F9880DD0FF -:10827000D4B28E357C28919845AF37283D2AF065D9 -:10828000C3870ABEDFAB45BE057855898976AE97B0 -:10829000220DF6AF15ADC666F792027E2FA0237FA2 -:1082A000A1CD1FB4F97B422FB8B95EA4FA62833F17 -:1082B00017F460CF4CB6AF9E50D9FE0EABA7F6D7E1 -:1082C0006B033852D5F3F5D7DB9EACDE8A9FFCF00A -:1082D000892895F765FFF2ED006CA6BDA5B4E741CE -:1082E000FE43FDC17501E0E337956800E6FD562CBD -:1082F00079DEFB2FB9BE837C27382FBF92D3E9EDFF -:108300007FDE7C23E0FD83836E3C6FDF70C813F754 -:108310005022AE3C7A17E3A7439ED7587903FE6EEE -:1083200054C331BBBC2D7BF4DB793A6EEE4547F08C -:10833000FBD8D17E5E79E08F33C11E69203DA8272E -:108340009CED60FC0FB370FD5A08E7FE9DDF45BE53 -:108350005503E7FB86A39B31AFAAE1E82CCCA36AC7 -:1083600070C8791DF7438EF9EDBFB321F04162CC9F -:108370002E5EFBFDEF4C788DC273FEC0AF03922DD5 -:108380007EC4F4446FD71DDF7B524FADDFDFE57E47 -:108390007D7FBB18B6D38F313B9E1C67CF7A773C6D -:1083A000007E53FD3EB7413508A9FFE1FE47BE0BF5 -:1083B000FCFDB207E30DCB7FF8F48BD7D0F2F2C708 -:1083C000DC39B3D93434C80316748133EE90AF2B43 -:1083D000E8B0ECC74FABFA55ECFD0359FDF458FE7D -:1083E000D849955C35107FD3BB4EAAECFCB9832EDF -:1083F0005DAFCD04BB7BEDF7FFAC827CBD75422247 -:10840000C30A07B6AFDBF734DA758027A423A75376 -:108410001FDD06D02B7EE39393B05E10D6B1C1E88A -:10842000F55DE0995CE4EB1F3D09FB05FFEA3100D7 -:108430000F753FFA4600E6F386D2C8F8FBE175797E -:10844000B08F5EE78EE605F1C9DED7EDFD26F2DDE1 -:10845000D233DFCC637950663EFB5DA3683EC60134 -:10846000F7DC84F35C4222C87F750FCB9887FEBE91 -:10847000426A1E4B221FD705981E7BA3D38397DF2A -:10848000BD010A17FCC5E7E5183B6FCBF212BF2907 -:10849000F63DE0DE465A7EDFCBE8951B70897BAD6A -:1084A000BC36BE3DB0A11BE8F4F6487318C42B29B6 -:1084B0001EA21C6F12E821F9CC8C618C4E44572A05 -:1084C000783BAA27A7C37BA8DFED367D136CEDF8B8 -:1084D000BAC6C6BF878F4FE14E03FBEC8D3C6AEFF7 -:1084E0002499DFF280907F6A7F58F8CC22E74CEE27 -:1084F0000F6C64722EE43E36A706BEFFDB0B4C8E7B -:10850000A01DACF314AEF830FC7E729E847AC14399 -:10851000E2C9E4FB809BCBB7FD3BF5CAD1BE157C1D -:1085200042E15760DDEAE717B6CF4BE980F6DB9210 -:1085300087687BAB7D0EE3623DB5FFBD65BD5FCA5D -:10854000F5C13501C7EFEEECC91DD27D79F5EED846 -:1085500023DF05F9A5F20AEB4FFD0FDD9827F2A7FF -:10856000C34FBDF875CAE77FEA12726BD7A74EB941 -:10857000AD3B32992493DB3F6906492AB7F47D521B -:10858000B9D512C8CFFF51FA54E06F51C09EE7240D -:10859000F4632A3C3AF5E3DFFC3AE2D3A91FE9DFB2 -:1085A0000BA462201F0AFE137CB7EC072BF0774167 -:1085B000FAF853F05F1F7F0AFE73CED78E3FE7F7BE -:1085C0002BC15011F162FA74AF21513FC4537F2E79 -:1085D000633CF50285693DA5F385C385788E789D5A -:1085E0008FF9E717823D81AC32BC0707CB3DB9EA72 -:1085F0007AD017E27D8F8FC5BF2F847B02D63C9047 -:10860000D78ECB01D8EF4AC4484D327F846A648448 -:108610002341527D67F1E20B60FFC17869A362409C -:10862000B719B2366A35F8F9EDECBCFCE2E6AF05F5 -:10863000601FFEC2F131DB407FDDF9AC4CF8EF2862 -:108640002A906F7207A7FF9B24BA732A9DE71DC764 -:10865000995FB1B82D39BF2CE3F59768F7A8A097BB -:10866000A85FF0BA351EBE8CFF9E64DD1EC7FBE31B -:1086700037205F2D73F05584FB8D3F147C7535B921 -:108680009AFB6D2E6B3EDB0CB96C1BD825174EB3D5 -:108690003864EF7119E9D17B5862F94F100F9E02CF -:1086A000FCD0A35AF3D8CE03FF25B9DFA0EFFBE33C -:1086B000BFABB89F56A97FE29509BBE9F3FC132F26 -:1086C00097FC0CCA3FF9EDA857C8C0FAD34FFC0578 -:1086D000F7B32F9CF0201C174EFC72D4FD507ED2B5 -:1086E00083F7D55C58E361F99F27FCB1B1F07D2495 -:1086F000CB175AFBF33F4F48E0BAD482747B29C0B2 -:10870000FCB1DEE3FFFE7BC81FEE3DEED1611E0D26 -:1087100027D2717FABE1491FC6692EFCFCCF15D66D -:108720007CA6CB9DCF4A7E1FE2053FA9853CE50B89 -:10873000996CDFA0E16753F6C339A215474FAAB081 -:108740001F33FD177F9D007AE7C211664FBCEB4EC9 -:10875000EC857DD63F046EDFE086F82EACD7C309EA -:1087600069CA885D0FF7E10CC40BC3C3058A07987B -:1087700017C54B1DE8CB54F8F83FFFB0F8786F01F0 -:108780008C5F7FFCF32837FD78914CF6DE1F83A3C6 -:108790004D74FEECFD893F4F00FBE84F5DCDB8CE38 -:1087A0000F36EFFC8CFFD7E62DC58732EFCA7FD896 -:1087B0007933FE3F11D059DE9F430E06F2F94FEE9A -:1087C000C5F28FFC06C23B44F9AFFD879DFF27A48D -:1087D000FB114AF7C0E074FF6F196C5FF81F6FDE82 -:1087E00083D1FD594E777F10F2102EFCFCAF185F3D -:1087F00017F31F6CDE3BFF93CE5BD8439B5C467B3D -:108800005121E461C7BB750AE7BAD2B9ED1096925F -:1088100079DEB513AE6732987F214B2C6E4346B29A -:10882000F811E1FE46DFEF416AEC7C95A2AD67F7F7 -:10883000912906DEAFB7E98A4506E67690F29722DF -:10884000502E988ABF73EBF4BB942BBE741AECFEC7 -:1088500096660A1F1DA7C5AF04A9E544DCA5AEB8FE -:1088600067023E5F83E7061EFF7207559BDFA13953 -:10887000FC059F6EFFEEE1FD7BC9A920E42F790D79 -:1088800005F3537DA43D6ACD37F0104B3BFABD1381 -:108890007E10D0624F5E2AFEFE9CC1FC4F592AEF2B -:1088A00086BC5832DEC5EE3727EC5CF1A60223B653 -:1088B00089E55D78EDF85CDF0D785408F50FD9BCDB -:1088C000D0AF24DC9F5478174AA9CBF4D9EB717F41 -:1088D0006950FA307A8CAAE7F45965A387C0FB4542 -:1088E000E862A387C0EFA5D2C5490F27FE7F95C1D7 -:1088F000E274824EB67C905CE697C4A981FCCBC33F -:10890000FB312EF2CE3FBF7623F0E9F29FC9C44B74 -:10891000DBBF7BD84FE220BF4A4C053F6BD95119D2 -:10892000E3C2FF174BEE49A70080000000000000E3 -:108930001F8B080000000000000BED7D7B7C54D5F0 -:10894000B5F03E33672633999964F29ACCE4C52496 -:10895000811834E0248480823A218020F43AA008EF -:108960007AA38E10209827485BDAEA8F09411A1EF5 -:10897000B641E5A1453A2028ADD8061AB9A0A8838A -:108980003CC4566FA3E5DEA2450D8A82C823A51715 -:108990003FDACF5BBEB5D6DE3B73CE6402DAAFBF43 -:1089A000FBFDF3E59F937D1E7BAFBDDE6BEDB5F761 -:1089B0005CBE0C7FB73076595C196B652C83B1BAFD -:1089C0005F3B184B67ECC19D09E1C9F970DDF5E922 -:1089D000503684B1734B7A0E65C3FDD02F15DF5628 -:1089E0007C3DD43DF40EB8FFA0CAEE0F9444FB9139 -:1089F000D754A781B1E18C9DD9639B11B633A66C86 -:108A0000DB771FF5DB31DD94A044DFB33A4D342E24 -:108A1000BCE7C7E7A15F28E1414ADFFE186BE1FD33 -:108A2000FD42E1F0ED3685AD08DFB64DE620C0D160 -:108A3000B4EDCF663FC051F5EB1793BA61BCA6DD2C -:108A400046162966F47799E173632461285D8FE304 -:108A50009531BF5DA960AC11FFF5C2B5B361324B72 -:108A6000826BC7CA3F1B93F07BD327DD96E8F7756F -:108A7000BF7E7557085053F79BE793BC703DDDB53B -:108A8000358995507F0F98931953EDAAEE7DECF739 -:108A9000526ADF7E605CC65C709FDF624D1DCBF961 -:108AA000789DDF39C9103E06FD48B8617EA7F11FE9 -:108AB0000F63239D8EF4CFAF83FF47B011978D7066 -:108AC000DD96C6D80D7DF114C55788D3F3C58B1B31 -:108AD00043809F333BBFDC88F0D7FFFD2F1B7F0413 -:108AE000F863AF599D5B61DE4DBFFC8F24A4AFFCE2 -:108AF0006EAA53A1EFCEE5B29007DE3BF77E423877 -:108B000004B7CEBD7A32CF0BF33DB7E3AF2E2FBC07 -:108B1000BFF0D5719938FF852F5565327BFF709C6A -:108B20005BCC5838410B5798E8E8DD0D9D664273E1 -:108B3000AFB8C6D0637FE7FE3C84F3ECD1045F029C -:108B4000E209EE2D2A43FA009D86F2F6C380DFC6C5 -:108B5000ED3FFEB371683C3C87B20D6EA4EBA7E31A -:108B6000114EC622D9CC8DF8ED59E6B4F77DBF97EA -:108B70005E47809ED77F03BA6D5FCEC7ED00BA25F2 -:108B8000F5A5DB59FC07E8D38474B345E976910574 -:108B90007FEE298476671AD1351EBE22DF005FB5CD -:108BA0000AEFFF26A7FF874E949F9DB65E7A4D463B -:108BB0007ABD78318F01BD4F997AEE63E58CF5BCB3 -:108BC0009AE0DC0CF71F7CF58F2427E75E7AD78CC0 -:108BD00074843FBB02F33AC77AFFBA709E8D8A98BD -:108BE000E716472421298AF7C6F09409DE24BA7FC4 -:108BF0009CEE8739FF22FEB2913EE17D772A71E833 -:108C0000D1E12CA079B07006CDBB61CB9FCCC83729 -:108C1000924E481F6524D2EBF878BC2FE924E71D5B -:108C2000DB9F13F1304243B72D5C0EFBD2B5C7CCAE -:108C30000AE3D10BE0C5EF105E689FDB94A02AC960 -:108C4000FC7E0ECCE39C89CDE84038C2CA1FE3D13C -:108C500097B125349F1762E552CCEF6A727935B827 -:108C6000FF51BC3CE37452FF123F67BE8EAF9F0FB3 -:108C7000A19C03FCBBEDC183C83F8C59C227A09FB8 -:108C8000FB99C2920BA37893F09E5119E9DD33BF93 -:108C900034864330FF651DFB49CFC6CA37CCCBDFD6 -:108CA0001167BC3F8AF11A77EF1B8A7AE8CC1B7BED -:108CB00088FF1AB71F3787A09F43DB7E63EE2E899C -:108CC000F23BEAEFB0467F9FF9D5BEA1A46FB1FF9A -:108CD00038FAE684E8BF69AFBEFFA6ED7FD6F55F40 -:108CE00017EA303BED571FE7B4EA9F8EF33DDD6591 -:108CF00062A8FF4E77182784E38CFB96B05F124F73 -:108D0000CBDE35931D2B7F2F319C00785AF8EE84F3 -:108D10003F25A7E3D5EC05D4B2CE16CE579D8FF8EC -:108D2000B3912E9DEFDE63447BB20BF1784DB4DF3F -:108D30008A23CD550E90DB8A63817264AB587D30F7 -:108D4000E2A84107378C9389FA7929F4E3857E9864 -:108D5000EA7307A05F63D2F809088FD169705AE3FC -:108D6000DA55DE9FC91E604180CB0476DBABE1277C -:108D7000F7D4A4A12C19A7E731A05E5800EC85FA1E -:108D8000D96D66C52AC0C70C89BEADD0EF82C1FEC1 -:108D9000D283D05E30DBED0BC173CF1DFCBBB34E75 -:108DA0007BC8703DB6F3C22847B64B46E605D5777B -:108DB00046797B0E039560137C95DD61233B6353FD -:108DC000BDEBAAA16DAB557D8051F6993D989B9264 -:108DD00081DF99E93B4F8AA27E8EF34E6249286F6C -:108DE000B27FF99EEC97A991A1387F66612A03BBF7 -:108DF00092C338DC46319F42D6A5207FB74E49DA70 -:108E00008CED0D8E5AB2FF79AC679F1FE8F66CD2DD -:108E1000F8C3A8C7E05F03BE97DBACB7EF0316E962 -:108E2000DBF92135467EBD8600F05F619BFE7E7AD0 -:108E300055E5FC013EC6EE4BE99CA082FE4E9F5ECE -:108E4000B9231B703A69C57BBCFD7C65A907DAFFB5 -:108E5000B1BA61A20A7A24FDF795A579D0BE90FA3D -:108E60008389F4BC0E907423A8FED54327864AA2BA -:108E7000729B0160261B499E6F463C9C0D9C598647 -:108E80004F1BA67D658647F817403CE48EE478C802 -:108E9000B11FDBC1E0FD0186EE16E4CB9FBFFABF38 -:108EA00052F03D2F73D27C9D6CA9F3730B4E9E8DB7 -:108EB000BC3CEC4AFA4C659F4B3E3446E520D91544 -:108EC000BC3D05F86AD9CCE275E351D7D6FB88BF23 -:108ED000606427D943F9BE339DE85323E883705A71 -:108EE00080CF66F357582D6B177A68AC13C7514281 -:108EF000F5C6CBD77D7B78664ABE713007DE57EB6F -:108F0000BD045757867F36E2EBAF1941BACAFBEE74 -:108F10009933BC41C0EFCD2981B9380FCF9C4B7933 -:108F200008FFE41446FD55CDB5FBD1AE5ED80BEA83 -:108F30002F8E5CC9EBE6C5CCA70EEAFFF9D4D4E0CE -:108F400077B1FF82D7BD3B0F437FD7D7987D5618A7 -:108F5000E2FA45E53E358DF109A1DF21E8E6465A02 -:108F6000A2DC7D8F8551EECE27287E3FB4CF3FE433 -:108F700024BD9C5333F930DAB3F3B6FC8E08DEFF20 -:108F80009197E4113C0005E521776F72C49A44FC87 -:108F9000FC550C3F7FA5E75FFDB8E72F7B77775344 -:108FA0007F4ED11F3844F03C57D0E9BC91FBE5E738 -:108FB000177B090E701FF7A1BDFDA6E33D9922FCAA -:108FC00024419F47ACFE35480FC0FF3A2DFE7FD6A7 -:108FD0003F1D37E27B4047BAC6D2718EA5390FF5E7 -:108FE000C283818EF1A0B1D9C939DFAB40E69E9230 -:108FF00012DC82EFD7CFE83A6422689A8B506EFB7E -:10900000D259217DEEDAFB408B09DA4D48276F5F9C -:109010007A5EBFA894E8A6A16F07F67FFDDE3F1B2E -:10902000107E49D7750AB703B1DFBF92A28871EBF2 -:109030005B4C80CF0BBBCDE4FFC6BE7730C54BEF9A -:10904000C9F6504B854F0539CD34B060BC7E0FF664 -:10905000E9D7E24B88037F6F7F4EDE1FE0FF4D2D87 -:10906000FE7FD73FFEFF5DE0FFDFBF25FE8F209D27 -:10907000FBC3BFF4BBEB847EA863ABC8DFFCCC3F73 -:10908000D53510C61F6FB4933CCCDB6A243984F706 -:10909000277B5C517D32EF86E67D38DF79CF28C4AF -:1090A000B73541AEE7BF9C33F910EAF7D9ED7AFF47 -:1090B00069CE8C9019E19CBB5E7F7F5E38261E6472 -:1090C0001ABD0E7C7126CABF03B8DE7193BD340A87 -:1090D000F9A89A5B928CFED26B26EFEFC91F7FCB6B -:1090E000C836C7C17F5E6A3ED963D9CE6D06246992 -:1090F000EC3CABB11A505FCA7EC7CE2DC944BF66E7 -:1091000081C37BC5386CC022BD5DCF0F2532AFA6B1 -:10911000DFC2B6545D7B507B96EEFD6BD617E89EA2 -:109120000F0E5FAB7B7EDDB6325D7B48C78DBAF735 -:10913000AFDF3D46D72E8DDCA67B7FD8E1A9BAF6FE -:10914000F0AE7B74EF8F383A53F7FC86EE0775CF9D -:10915000479D5AA06BDFD4F343BD1F6360A427591A -:10916000A2427AF3C0E253152790E1CA95B188CFA5 -:10917000AA91FCDD03F3CD0667125E8B0C4EE08FE7 -:1091800037664F263FE0C07C97DF4BD70A3FC63F8C -:10919000CC38BA3C18C7CF1DE7FCA2E28466DC2AB3 -:1091A0008B49A7E7C639F5ED61A9227E18C0F9669B -:1091B00064AA5EBE8CCD9323666866CD1B9889E356 -:1091C000819C8D4AE57246D7ABCA59527305B641A8 -:1091D000CE2A53E3C81913F6B652F0135CFDE632FB -:1091E000642C07D9653FDEF4D2FD900AF1CA188BD2 -:1091F0002FE720CECBE04B47261C3B237080F72780 -:10920000EC332B367C1BFB2CE5DC6DF086C8AEA561 -:1092100032CA2F3D35BB289969F07B4FAA41E883BC -:10922000761E473AB70D53251E0BB4F7270C578B04 -:10923000A3F795B9933351EEDCFDE845B3BB70F06D -:1092400016D0C7664F3E5DE5FD65330C13C271E86D -:10925000DB90CAE30CE9770D8EFA5D0D88DFB3EE83 -:10926000F7D60E027C3556F790DFE536B4CF3F8453 -:10927000F3FAAD91E7CDC0B342BD305BF8D1B3276F -:109280003E3EFF10E8A7D9EF0C22FD24C7D9B03825 -:109290003258EB37E4F413576D13F06C5CEC1F5C41 -:1092A0003388E022FD20FDF4BC50C3788C7706B0F3 -:1092B000668A1BD71A586DBC7E968B7E3291E40865 -:1092C000AFD34E727276CEB12415E691E8082E47E0 -:1092D0007E9B797D5705F7C7FCBEA9C03F79917B7E -:1092E000D7E2FB796E958595BEE3675607DBF261A1 -:1092F0007E4B530D3E3BB57B147C3FE161C6D2E013 -:10930000FDA57F37123C4BDFB88161BC96606F666C -:10931000E8D7CA79ED4F7D9AF063ECB4911D64E80B -:109320009202FEBE2B687FD15DD3857EC7C5274DD7 -:1093300034DE4598A313FABFD8690CA3F37E283511 -:10934000316280B6B1CD41F63B0F7D50787F4EA79C -:1093500023ECCD8FE2455D3F9A45C0DE25E4F0F970 -:109360002F4DB587EDF934EFD5386F09A79C776E8F -:109370003F71682495DB59E62FD6D1D903315917AF -:109380008EAD82F30FFD189F34519C383BC54E7053 -:1093900086178706D798FACE6F997BEAED77033C5C -:1093A000AD478CCC08FD78BBDB091F73001F616FD4 -:1093B0005F7C9FF5E67F653012DC11E447E3FAF14C -:1093C000342F867E3D7CD7F073853D9D8F7C199C24 -:1093D0004074CE32B0ADF97DE7F1662ACFDF1E4E84 -:1093E00075D2D5EC2EE272E21E38780BF4F736EA2D -:1093F000290B8BE707FC3E95FBD3748DD54F600797 -:109400004308C785F50AD1F3A412369B006575772A -:1094100036933F20F593D16F24FF43EA290917E8DB -:10942000B10F5235F6D198FCF050ECB77F7F6DC785 -:109430003E33FA6B4E46FE9AD4A3FDF96BE8A721A2 -:10944000FF493FED54CC3C617E5F8AF97D196F7E08 -:109450007DF4EF3DCDD2CFF973EA15FCCC0C737CD3 -:10946000FD744D1AA74393D3CC283F85F132FA0FF0 -:10947000F30CE1CD988752C3D6291AFC64A5493F65 -:109480008FFB1BFDE9BDABC525052B4B48FF5EE8F7 -:10949000F226A7C235FD53A5395E3FC6452F0C43C2 -:1094A0003ACDB356DAD2004E679A1E5F4F2DEF6366 -:1094B000BFD2D238FEE8DA077F76C09F41E727EEB9 -:1094C0002AF212FE3C6957F013CFDEF15105DAA5FE -:1094D00073024F8DBD712FD7D35960AC30AFD5C05B -:1094E000FCCF9E28E6EDCB0AAD7A50BE6EA33D3090 -:1094F00008FB6FDA3DF159ADFDFE3A95E7D3983D93 -:1095000095F2ADB23F97D0FB1067DFFC9997F4FF5F -:109510005748DF68BCDD5D81F156EB4BD724A37F54 -:109520003676D7DD4EBC5E481F48783DBB2BC18FD9 -:10953000709E4D057D6CC7F688439887F872F1E1FF -:10954000542D5DCEFEEADD0A13F47376E7BB152ACF -:10955000E63344BEA6D71E5DFE434500BE0F8D61B7 -:10956000C5CD760D9F58B8BD78D2CAF31D192EF31C -:1095700032763DC4231929F4FD1A97E12778DF6874 -:10958000F943DE0994B398FCCE93266FAB1DF80C1B -:1095900062391FAE132C18ECF7CCC6FCCE1437E59D -:1095A000655A15AE4743B3791C9A5EC08AF3A13F52 -:1095B00093C168C4EF7A3CCCB7195E4938D01E41DC -:1095C000B597D8D5E147F0CB1353099FA3CE3815F3 -:1095D0008C27643E48ADE2FDF54C3387376BF24093 -:1095E000EE192AD9459BDAC1504F3F90914AF0CBF2 -:1095F0007C50D5D419814A84EB5103C533A078152A -:10960000D487D9621EF99E9DCBA56FA3BA902D1960 -:10961000267FD84AE0FF8180E724AFC18FF9D7A425 -:109620009CC85113F877D94B19FB44E347DACC4275 -:10963000DEDE3192BC39BEBEC53203FC235B22CFD5 -:10964000AB260596CDC7BC38DEFFD732A40BFF9EF4 -:10965000E863C434150B2503C88E91FA7E25FD3AC4 -:10966000175B7C0381A1772E76D2F5B9C56E82EBAC -:10967000F1C55EBAFE747131DDEF4F4EAF767D6C91 -:10968000318CABE1A7F4118015986FBA91913C3FF2 -:1096900036BC2279661C7F405E9F5E7CD835769012 -:1096A0004020D023ABDEB969453ED119850866F765 -:1096B000CE72FF68C61E35F9E73360ADD5695F8F9E -:1096C000C5BCD54AC54079AAC7D3DE5C1ECAC1ABAA -:1096D00097E86EDBFF3EC37CA7A7BC5D4179F7D45A -:1096E000B7131F947775B1A0B8EF87B6E708BFFF2F -:1096F000A895E379156313105EBBC202783D67E558 -:10970000FEE0E756AE1FBF10D72169C18D28C7FF05 -:10971000E53C5AF42880672DF9200FD73B6CFBFFFE -:109720004AF960E350B305E5C3B3F738AD83180DCC -:10973000DD660626F9F5273EA6FC9AD11CC8E7EDA2 -:109740009756603B2329B0095D3616FA78E2013757 -:10975000C80DF2C38D848D10CAF14AAB68878E1193 -:109760001E569A78FBF527FE44F35E690ACC43BC8B -:10977000607B29F4B732A5C36D80B6BDE5FDE587F2 -:109780006FC2B67CFFFDE521F8FEE534A96F021E2D -:10979000D41FBD6D27B48768DA2A6F330BBFCAF9AF -:1097A00035ECFFEBA16CE0D7C6BD4A0782E6D9BB1A -:1097B0005AC1797A76AF267CD31FC8074E83F2A4AC -:1097C000969019BF7F6EF161E752A0B39ADAE64234 -:1097D000BC5FE30EFAFDF1F21319D2FF85F7B579FC -:1097E000B6B0A9A75BE38F7B18971BB614F4431C94 -:1097F000FF626846E517E9D0CF934A708511F5CC32 -:109800008B2627EA11D6C5F5D019D1170B67917FA2 -:10981000536FE54DD392E08AC1A827EE557D183FDE -:10982000D7E5B757A27DAFDB93EF6B61517EA94BB4 -:10983000E9709521FFA4E8DBAD22EF9299D29C92CA -:109840005282EB11ABF370BDA091B5DFF74384F703 -:109850006D23433FFD8B7D37248F827603B4D16F18 -:1098600068E87CD78CFCF9443AD79F8D9DC03FD0E7 -:10987000CF2A902F3F38329B546722EAA7E7FCCDCE -:10988000D7A28BF7F5137F9B6805FA3E5FE077223E -:10989000BDDDE9A61516701A9F373B07B3526CDB86 -:1098A00089BFEA4A0D5C8E98FDB77E55AC7F42FBBE -:1098B000F813136FD3E6773DB82E03786EDA600F96 -:1098C0001992C9DEFC6FB4B78DEB0D21D45F064B46 -:1098D0009719E9EBC6B55DA28F93F0B650EAF3187D -:1098E0007DBD7062EA6DD85EF86881337485FC6571 -:1098F000ED251B0B6BFCA327D2B91CD7AA215A4715 -:10990000A9BD9444CFFF79E3595978D895C6B3D30C -:1099100073395E7D743CA2EBFEB2DFAE1D08745B52 -:10992000B8C36448D0F0DDC21D62BDDAEACFC47EA0 -:1099300032CC4CE01DFC7DC0AF9ADFDB0EA920E7E6 -:109940008FF5CAF98015634723DDA2CFD9489D1E44 -:10995000F063BCF958A2D403D7C47F3F31E6FD02BF -:10996000D9F6AD189BD3179E8CC468DB02EFABFF12 -:109970009DD0DB46F8561B62FA4B95E38FA4FE247C -:109980005F1D4FABFC6D68203C4F69AFC4FA8D9EE4 -:10999000D9CC8B7619F9D5A7D1FBC7D3B85CD75EE4 -:1099A0002AD4D13B8AF722DDFD938BDDBA75BFB98E -:1099B000D50B697DF238EA79EC878528AEAADD906F -:1099C000CDC21A7FEAFFC3F18FC231AA1F386EFEE3 -:1099D0001F86235F279F513806EAEEFFA3706CBEF7 -:1099E000ABE8B67C78658D12B214A05D78C440797E -:1099F0001363CA586F0BAE3F3CA2929F872E09D6C5 -:109A00007F14A8ECB05A86F2D3EEC7389F2DE1F947 -:109A100023B8DF662A233B447E70E1DE8407D04F03 -:109A20002BA8F5CFC32BCB29A1F50DB92EC8441E09 -:109A30004CAE670C72B24A159CB751190F909D2A13 -:109A40000854D7A13367749427A27D5C630887709C -:109A5000BCD0E37CBC0C43B8C382BA3769A013ED19 -:109A60005D4612D77F6C4509D9BFCD86826BE7036F -:109A70001C8F2A95896F219E530A28FF8BF717C0E8 -:109A8000FDCDC26E19537C4EB4539B85DD6A15FA29 -:109A90005DDEB7A5061E407FE254FAC2DB2C37A07C -:109AA0001EF2B7A581BD3999BE7085DB83F6C65B12 -:109AB0006001FB72F2C987C8DE6C6EF1663953A291 -:109AC000ED41FF0DD69AF4C4432BD05F596A5FF085 -:109AD00020FA3BF0FCB716D0B3CFA70ABD239E17E0 -:109AE000F4EA29D04BA0C78C2DBDED10EAA5825E0B -:109AF000BDF310E99D2D1B8DD47E07C643FF07E6FD -:109B00001132E27C07A9E4D75B019644685B071732 -:109B1000D03A11CC9B25A27F3D983F97F97CF3204A -:109B200003E5F3F17DC4A3D5C3DF374F613E5CD7B6 -:109B3000323BEC1487C8F501A358A74A14751A8A5A -:109B4000730AC5779655650B301EB30CD4AFC39A14 -:109B500063EA398CB1F51DF608F95F5FA48BBC7E12 -:109B60001A735F2E8CDE07BD5D8657D7DD4B2B1138 -:109B7000DE050EE634625E2518A175CE58BB66017F -:109B80003BEAD5C887C5CEFCF1EA090E65703FD621 -:109B90007E49A5F8E64905FC1BB4A30ECE67D23F6B -:109BA000323925DFEAEDAEF4974C297C2E0B278E57 -:109BB000C9C4F8DD68F75BD0CFD9E72CA3BC80918E -:109BC000F96EAFD4F83B4B231329FFA63AFDE48787 -:109BD000178A38D1E8F431AD9FB36C310496D73091 -:109BE000F66C45D1189487A7AD114B21D2778D81A2 -:109BF000E2BDFD650F8614CCBF2D6224A7CF56B8F9 -:109C0000C6601E7D931A48BE17E5E5088CE7E5742B -:109C1000E3EBB9AD0AE68B2F5A02C9A80F1E43BE6B -:109C2000D7E0E5D7021F7F4FE7FAE75113978B651F -:109C3000004F04E0502F5D47F9ADD5193CEF61AE00 -:109C40001E4BF91F33E003F37B09AC39E4A4F9F2AE -:109C50007C5D82DBA0AB0B542F0DA5EFFF9E6ED079 -:109C6000C5D56D304FAF467F595988F27588E3AD41 -:109C700071FC977732783C62017FC84BFE49CC3A41 -:109C8000775FFF88FC15499F5E3F4501FFE40AF1BD -:109C90005813C4CB5A7DDFA4F690FE6D827818EF7E -:109CA0009F735AC83F94750F76A1CF96B983EDA3E1 -:109CB00090CF139386621E40651D84945558F7809B -:109CC000FAD0ADF6F4F23FC87CAB356933BEB75479 -:109CD000D441D87C7AF94964ED113FCA67B1466E28 -:109CE00018E23B44FD2678F5F7190B328C33547794 -:109CF0006C9D44A8B71E8AEAF954F614AE5F4BBFB8 -:109D0000375BD4239DB57D447934F07B2BD3681D1C -:109D1000A087E21699EFF9B67E7221F68179844523 -:109D20007FA938817236657C3EDEB7A99C4FC0158D -:109D30005713CA30BC1A3F2F05E67FB7B07FE9C67C -:109D400076AA1B795DC4B3FFE59CE1A1380AF0490E -:109D5000F53689BE6E8A17859F66ECD58F1F2FF763 -:109D6000EBFDCE90D6CF5BB9E6E3E54B79BC42ED97 -:109D7000D79F8890FE7CD42ADBAF501BEC5C04E3B9 -:109D800025B62BC18B7C08DFFB51DED85D45E4672F -:109D90001B0B5816E2636C9285F4A67157C266F4E9 -:109DA00083212E7E394DB35E7CD671340FFDE138B0 -:109DB000FD8574FDE57DBBFE60FC4EACC791CFC751 -:109DC00026AD8F18F9775EFC8EE5747D1482FED780 -:109DD000BC94C056000A9F36E9E55D5E370B7946B4 -:109DE0007DA3AD873457D7F891A9A55C27B813593F -:109DF00044C34F52CED54B835944232785197C5DEC -:109E00005555FD9447522F95D0F3BFA34CD338CE70 -:109E1000AB8C93DACF38C3487FF43F4E85D02F4CBC -:109E2000AC5FA9545723F5427F721EBB4E16AB1789 -:109E3000E555EAC5CC0CDEFFBE0C7DFEF5C1F51D77 -:109E40008790854EDB830732A83EEA58129AF07A53 -:109E5000436428F2F1677DEF37E2E4DE4EE379FFF9 -:109E6000A26DF3DF4076EDCA085E443FE8B71962A1 -:109E70007DD20DF6D088F60EEC4509E5732FA6636A -:109E80003E37E85D378EA13CDD45F9DC6457A00420 -:109E9000FB5F36B582720E12EE958B799D9AD4B324 -:109EA000763548F8B2A8217E7506C186337621C37F -:109EB000344955109F5C8E8EAEB940726055FDC41A -:109EC0005756A7C18B7E8115E242D4BB2D4E035F4E -:109ED000BF715B28FFBF4C810811F4C68294822BAE -:109EE000AE8F9B2FB9C8DE02246EADDEFEE78F93E6 -:109EF0002EEC837E1CD5C9FD06B69FDB6144C2A74C -:109F00001A7D2CFD81D8EF62FB97F894F8B5205E9E -:109F10004BC81EC6F537AC2EFD7A66A6D4B71947D6 -:109F20008B2270B741E94E42BF06F4A8D5857A7AF4 -:109F3000484F92C14BFAD7C5FDA090E06B66D7F2AF -:109F4000B5CC53CB7949F817BC35DBA25D7F898549 -:109F500037D6CEDA4BF4750B56AFBE6E41EE0B30F2 -:109F6000AA01E21BD368BF05E5A4C559E6443F67D3 -:109F7000A9EAFDA39FEA2D4CE46F83FFAE1B5F5E51 -:109F80001F03F947384A5D065D5D8DBC3A701D259B -:109F9000CE77535C5C4F3DB6EF6ED2C3AA8FAF3322 -:109FA000C5D28FB176E21747117352FE54C09B742D -:109FB000957EFBE3A39FECB3929FAC8EB484B1AECD -:109FC00033763CA329E05750EF9632F2938DB97C5B -:109FD0007CE3204675E049E5A9AC5883C765EEA946 -:109FE000F47C41869321BD8D0E43201EBF483C0D5D -:109FF0007419747CE3967CE3F9A008E540C33781CB -:10A00000787C33D0C5F515C2A1A5EF327741663C07 -:10A01000FA44F522E7ABABF1C54C1BF7733ACD5CC4 -:10A020006F36208E205EAACF302FC3FCF7190B7F2E -:10A03000CEFCC5DC2FB3709E9B69CB0BA33FD4A98C -:10A04000FA6DE897CDEC5DB7F5D37E8F7AAB3FF92B -:10A0500006B48FEF72BFF964A5BD4D817E4E9AFCA8 -:10A06000C988EF93EF1A95165A07E7F573B20EE910 -:10A07000A4C9BBF25A783EEB67467F0B3DD6FB8303 -:10A0800067987FD83BE81FEF36D27A4BFEE30F1874 -:10A0900087C0FB35E028223FCDACB287D00E777E5B -:10A0A000D0FC11EAA3591B13BC4BB08E65FDB0AFB9 -:10A0B000B0FDF92A873781F26C058A07F35FABF3AD -:10A0C0009DB46EB2888978EECE4955A0437F89430E -:10A0D000CBFC35CCF973269F87568E85795E9BD154 -:10A0E00069B0034CCABAD04A0BD0EFD196801BE3BB -:10A0F000C70ED7F495183FBA5CFEAE5B205E3CE11C -:10A10000BA7B12B63B9F96FDDDB3D20F7AF91543A9 -:10A11000305F81E7B6CC872651FD6AA1EC7F193DFF -:10A120009FF9F36BBE3A0AFD97AE5B3F09736E155C -:10A13000D5E2FBD03304DFECD1B2BDD9563510BE29 -:10A14000B7315D1ECD148D47294FD7D9EB5F3D3711 -:10A1500009E3CF59639AAB54E87FC9BAED2B4B4062 -:10A160004446B4573AFDD0FEF1BA3726D980DF3ADB -:10A1700099BF0EE3DD95EB0E4CB2DC04FDA7E9FBC5 -:10A180004F378A7C6CE8F04ACCE3F5C2C7DE5FE962 -:10A190001F187D7F983B61552827CAFFFF22F81FB3 -:10A1A000F8FD572E5C07B4741FC2145DDEA21E3387 -:10A1B000AF7B15F52939DD4379DD8D681777F33AE3 -:10A1C00065D976F376E792F8F6FECF6E2E779D8905 -:10A1D000F19F7F24F439C0EDC7FA95E4A3CCBF3DCD -:10A1E0008E3C1D74D949FE0E82BF67498DCAD5EDDC -:10A1F00020DB23B1FEC7C2E194FDC47E7F4CE8277B -:10A2000016BA3D15F978B2E0F3429FC2EB7876DBDF -:10A21000C283D0DF6311F50E98CF3691CFD8666533 -:10A22000F74F81A15D892CB803FDCF346897D0F733 -:10A23000FE1DF6687F6F735166E30A035BB0BF7162 -:10A24000999ED2D6FC683F00F7524B990E6E75640A -:10A250002A3E0F65CD2FD1E0B384CF03F884F005FB -:10A26000C3BC700BC84B67D7B5052B600A2B5D5E6E -:10A270005DDC57D13595F6A5FCA79BFB3FCCCBBF4A -:10A28000CFA8E275213D7B6C94A76096AE22A49383 -:10A29000FCEE92C047D58F27AFC3F7EABB4C8CEAE0 -:10A2A000FF77545ED11FA8C7BC9EC67FAC5723144E -:10A2B000CFD5635E6F18F6F7B619ED18F6E315F90A -:10A2C0006BCCCB65B4C6A7BFB487F5975258685816 -:10A2D0005FBD19ED3F9D9E5F6D5ED1FEF47167DF3E -:10A2E000FECC621D40E05D157837C7877340A6E05D -:10A2F00053C0B741C35FB305BF81F6243FE0DCAE76 -:10A30000C19B57E46BC7E5FB6E403FBF700BEACBC8 -:10A31000AE448A5B2A54FF247CBFA22B95D6172417 -:10A320007F48BE9074ED4C6DA67C4DCF530AD9C1C9 -:10A3300058B88A245CEB158223B33A687C40039FAB -:10A340009407E8BF53F45F3E92E4E7192E0F2037DD -:10A35000F7A2FCE27A25CEC3D73D74EA90BEF0FFA7 -:10A3600014EDDF70A223C7FF4B5651CFC1F1D617B2 -:10A37000FFD957A1671E3DAFE87A83E659DF8FDC2E -:10A38000BEED4E2238338F4692BCF0DE1382FF3B87 -:10A390003B3E4D1A8572B1DBC8142F9F37EAAD0AD8 -:10A3A000A98FD99CB7C780FECBEC6D83BEF4221D6C -:10A3B0007AF567C46289BEFFAA7BCEE4A5F02C3D86 -:10A3C00081CB6BBA11AC4D59148E6999DCCF1A1937 -:10A3D0008CEF97BEE776D07389EFA71655B14F6122 -:10A3E0007E3F73F1F5CF91DD2105E922E53A564F25 -:10A3F0002DCCE4F2383FF3FF919EB25E454F59A554 -:10A400009EE2F70F427084EFB95CDD4315F09F6B5D -:10A410000C7E17C66127DEFD21EDE3982BEA5686F8 -:10A4200060DD0ADACDA301B22B5FE0435EBFF20824 -:10A43000C680B3DBF5F52B6C0BDF271ACB57513EEB -:10A440000A09FF5DC021ECC1ED09DDBFE245C67A16 -:10A4500079966D80B3D150A8796EE7764BD201E83A -:10A46000BD94A546E5F8935D999B50DF0E73F3BC50 -:10A47000627AA1BF14E72FE512ECAAE013C3FD53E3 -:10A48000ED5C6F4C8DC3BFCF08F99CBD9EF34DE7CB -:10A49000DFAA2621DE3BDF4B4D59A2D1135B851D80 -:10A4A00094FD4A3D24BF93CF9F15FCB12D3389DA2B -:10A4B0005B5D0E91E731C4DD37B755635F897FDAA5 -:10A4C00038FFC07C435AFE1EE65674F6B5D7AE0A76 -:10A4D0003C379801BF80BF6DA65016D6ED54741955 -:10A4E000A8BF9ADD0EAA07ACE9E078AC69DF67A8DF -:10A4F000D3E027B6BFFFC8E4FEC02603AF233A6807 -:10A50000007E43BCDB397CE77679487F1E16EF5D21 -:10A51000DD6E7C333DB3C9CCEB4881BE54CFD7F060 -:10A5200072F626BD9E6E11F80FB6E23EB6F475CCFB -:10A5300087B55680A78802704F770BBD63F69B7175 -:10A54000DF6ACF538CD6F30755FB4BBDD06E0AD8CC -:10A55000CB14E8AFA89DEBE18A27C18F41B9B3487E -:10A56000BBF0D676ED78C7321D221EE1FC5CB39EAF -:10A57000E36F10F83F2FE015FAF915F9F11C9E4F23 -:10A58000D6768CC2FC93FCFE0B41FFABC15781F029 -:10A590009547E1C3FE919F983DB004FB6DFCC3CE8F -:10A5A0006C6DBF5F65727D9B6E9C39C68A7A7E3505 -:10A5B000D81D92CEE07EDC9750B337C5B982913C6E -:10A5C0001B30EE91E3D6883C24C85DC514985A51DF -:10A5D000EF3892AEEFBFA89DBFEAE6FEDC3F8BBE30 -:10A5E0009DE620CDA76707C0EB8DE2A5B3E38125EB -:10A5F00056B41347990FED84847750757712D69D22 -:10A600003409FB01F33560FC92FE332F6B45BC75BA -:10A610008D3163FC14CBD7924EC58CCB8F8CD38AF3 -:10A62000718100DAB9EEA142FF308A773F79F9D51E -:10A630001756507CC5E9D254CDE958E90E4E7767DC -:10A6400044E510F47905EAAB9A277BF55107BFDFA3 -:10A6500095570DF8BCDE2DE55C4F97F4408715D774 -:10A6600035245F9FDD3324BC82D399C6EFEC708420 -:10A670001505F7A136B760DC2DF504C2A3ADC39470 -:10A68000F0F4D291011D8744EF0FAAE6FD3581BC9D -:10A69000231FD51B9B158F427A80F2AC99A807A087 -:10A6A0009DD9C1DF637BF9B908124FF5D3A1538857 -:10A6B0003BFDEE129A87C4576675C4500FB72658F3 -:10A6C000AAFC2734FEDA61B1DE8078994AF106D718 -:10A6D000D7F5C6400EC6AD2C3381F671821D22FD22 -:10A6E00072D0CA542BF4F7265CD12E8D33CEA77DC1 -:10A6F00034E30A159263D00032EF13417FFAF65B20 -:10A700006C24FFECEB8706E23C336C9C0FA11F8BA3 -:10A71000E8C7427650D883DFE7815FA744F5F2416E -:10A7200045A17E0EDE74DD66AA2D147C89FDA1FF95 -:10A730007450999243F6B23343141771F8FBB7671C -:10A74000DD79F85C1B2F627C178D374B57DD0A3C97 -:10A7500035624247C4E044E9289FFC7D807F1CC4E9 -:10A760009B5698FF0382AF0FE6878C4908D7209845 -:10A7700037DC3A94182C69B647C77189FC8D4BD4E5 -:10A78000EFA2BF80578387EBFF9F78B8BDF8505C7E -:10A790005D49F1F33D17C5F38FED5C4FAFA88CBF5A -:10A7A0006FFB11615764DC79BB58EF80B8F3113748 -:10A7B0008F3B45FD295F1F01FF9EF05BF5E36A5A61 -:10A7C000F7BBD8352D999F87C0F5C12C51FF79FF74 -:10A7D00023D37E8A7C7602EBCC010F9F0A7E39E17F -:10A7E000F427619D544362FC3AE267053C0D020F79 -:10A7F0002717F3F30B66E1BA1CF0DF1A37F7F3E61D -:10A80000B60F1B8F749FBB4AA17539B9FE2FE95C47 -:10A81000BBC1A8CBAFCFC275B9B47F249E2AED27A8 -:10A820009E2AD7C55372DCD8B8EA93C56EDD3AC00C -:10A83000CCF642717E047F7F16F311DCB3DAB27579 -:10A84000EB88AC2DE31BEDFBC7382A14173EB3EEA3 -:10A85000FE278B2D2CA485E3D440AA9F78C41D7CB1 -:10A86000C5AD83C3C642BA7CE86827ED27B2F23C87 -:10A870002CF8E33C8E81EB263BF9EB13D09FEDCD1A -:10A8800087811E7126A35EAADCEF1E1E8D1FA49C6D -:10A89000D58F8E1F47AC117ED01A178F93938FCA16 -:10A8A000B83AD18BFA51FAE5B1DFBDD7CBBF7ABF49 -:10A8B000F26A7908E0E390364E8AEDF794FB1F8D3B -:10A8C000BF0BFBE197A2FF91F8BB627490F27CACE6 -:10A8D0005DA19A961163F5F1D0D768D787E3D5A625 -:10A8E0008B876AAAF5EF310FB7FFCC63D3F9F1FD7F -:10A8F000E153EBC72B85A807797F8D822FF24FBFDD -:10A9000047F5A4A33DDC2FF265F9133C705D25EA01 -:10A91000C95759F97EFE4DFFBDDF3D0BFDA3774CB6 -:10A92000B4FECF7673BEA97C66612B9E0F60EF509C -:10A930009CDAFDABDF59A4F86B40AED3847EACF754 -:10A94000F1F9D4FB22E68176AC2FE670E474EC5387 -:10A95000540DDFE5D4F2F7723D265D5E3C5FB4072F -:10A96000789C328ED937311DDFF7ABE81764752834 -:10A97000643FB39A19F9D559E50AF5FF9DF24DCA1E -:10A98000AC92E87CDB0C534A9CF05D9BCBE643FB2E -:10A99000F3C3ACE0351E84EF582482E672C4B12EB6 -:10A9A00015E3AD5559FE62C4839CA7D7E8CC423F5E -:10A9B000DE768CC3D7DE9B67E2F687B195C22FDDCA -:10A9C000CCFD33233BCCB87F4E76DEB5A498ECA00B -:10A9D0009C8F2B55D811170BEEB4D3FB6DE4B758F1 -:10A9E000B81FE05A5244FEBCA46B34EE1C5C867166 -:10A9F00067E1AA883A13BE7B798321EE7915E305D6 -:10AA0000DE611E95DA795C4D6FC9F74CFDE41D25BA -:10AA1000DFDB26C48FE7C112D2F3CA67D2EF21F978 -:10AA20005C6A6698AF96F85F9515B813E1C9EAD8E5 -:10AA3000A4206E3E11750A9F24F27CFC272B5E50E9 -:10AA4000D0BF7C681E731A59FF70D72F32FA6BB4CF -:10AA5000F2BCD44C7491F14A141E9E8769F070FBCD -:10AA6000B42F2B5083E337EE5E4D71F5BC2DC7CD6F -:10AA7000575C87F88678536AB9BF5E3FC342F54C8E -:10AA800095CFA844F7BAA5665A37ACDFBE83F6A7C0 -:10AA9000B187990FE5BFBE63875203E3D66DDFA18F -:10AAA000CCD6E031BB3E4CF5DBD738E47A4484FCAD -:10AAB000E958FEC63C02FA2F87AC5CFECF54DA435D -:10AAC000B83E71C614ACC7F7CE786C3E5CC79478BC -:10AAD0007F73C7AD745E8063674204AF6D86CD6ED1 -:10AAE0000BBCD776ADD987FCB42A2BB81CF192AA3F -:10AAF000063AF1FB9474870FD737BC09AC8CECF79E -:10AB000037C4C38818BE18F130979757847E813FA9 -:10AB1000AAA77AD6C3FD725C5E427D75C8C4E7B150 -:10AB20009371780D1EFF7A944B763895C6CDAA8F17 -:10AB300028587F113B6E94AFFC1B3D19DF06CE0EEB -:10AB400033EAF93AA16F2A9FD9A27CAA81FB458FEB -:10AB500091E0CBDABE49C1FC193C277D03EF33AC51 -:10AB600077CADACEE3D53A783E5BA35FE43CE2E80D -:10AB7000994E84CF7EACEB00D73311BE5E20E08DC2 -:10AB8000A567C4E3A5F1C783BB40F7CDA1628C974D -:10AB90000F1524527F52EE63E534E2E17E65D686DE -:10ABA0002D8AC14EEB2AE45F4AF8E47BBEAC310744 -:10ABB0003C84872EC243C30695E633CE1C18385F0B -:10ABC000230FEF89FEDE98FE119DABF3E4BFBD4B72 -:10ABD000FCD8007136C519EDEF9AA7A19D09FDC2F9 -:10ABE00088EB6093B88BC2D68A73A72675723DDC5A -:10ABF000D0B9439D658FF269FEE937E8BCAA868E1D -:10AC00000486F115F0DF518427964FBF293D411F7F -:10AC1000F1F829641679BE603EC63F524F1B84FC92 -:10AC2000333BBF7F41B4A3FC133CEDD1E9592BC9A1 -:10AC300045FEE9B237B0DEB3C1A7D0791D129EF44C -:10AC4000AAF87EBBD48F526F633E31A0D1EF1705B7 -:10AC50005DA11DE1712A2B403B2DE18CA5D3802CF9 -:10AC6000AEC7E3F0D3DF11DE58BB25ED79FEC69DFC -:10AC70002AEEBF917C3209E9ABE113479699E07067 -:10AC800064A9D4FFDA4ABEEEB8D6C4EDD5DA160B05 -:10AC9000D561BE7937AF0B73DC638EE0F5A06166DA -:10ACA0003D3E3F98C5E168332CA1FD68207F49599E -:10ACB00019C827498CEB41AEF79EFC0DD75BF521F7 -:10ACC0003BC5B9F5C13B6B68DD3FDDEAC37A591678 -:10ACD0003C609EE688E235968FBC3BF799711E93E7 -:10ACE0003AB8BC81DE243E8AE22FAC9313290F864A -:10ACF0005E3F2198CFFD201E479588FD81B5161F28 -:10AD0000ED2FAC15F9D612B14FB0E2A89FECC14CB3 -:10AD100041878DF6C0755998A75915936FFD8671B7 -:10AD200040DDA2DF51DCF5A0FB2DBA4A79847855CD -:10AD300027B73766713F3B5F5C2BB3389FD495775D -:10AD400090BCD59D682639B54FE0FACA7E2CC62F37 -:10AD5000648F09BE5B45E38EB3758CC7F5E2713F26 -:10AD6000579CADAC7F38E7E23E2B8CE736EC4F7A50 -:10AD700000E5F96B882634FB70A666713939B30D8E -:10AD8000104EF6A8D97C253FFB6AFDB1C81185CECF -:10AD9000F910B83CB3BDEA86CF707D675BB20FF7A0 -:10ADA000D37FB9FD8E1F7C06709FD9728B0FED7F0C -:10ADB0007A6B80F8A527C3EADBCCF3AF13303FD51D -:10ADC000D2B13F09F7ED7CF1C2F565A88FE7657157 -:10ADD0003D75FA37C645889725CFFFFA667C5E1722 -:10ADE00056D2D02F3DB3EDE77FCF827E6AB734E1F4 -:10ADF0000962ACF585D7C9DF378437F1FBDB92C92F -:10AE00007FFDE2D9D53723BE5B3B5AE9F9E96737C5 -:10AE100051FB8DE77FFDDADFE0BDFA4012ED673EC2 -:10AE2000FD9B7D4497FAA04A75E7BD7C1CAB077774 -:10AE3000ECE37A10ED37F2FD0CAE9F241F4BFEFDC4 -:10AE4000E2F9FB6FD0DA0379BF4DE469DA12B97D1C -:10AE5000F852C869DD187B1B5EBF7CD14AE76E36AD -:10AE60009ABB8B307EAF2FE17CF17D818FFA8EF91A -:10AE7000A6463B7D4FFDFC27303D5E87007F627D0F -:10AE800017BCB5E532D529FD8AEB99443612F33863 -:10AE9000D3AB8FF37D9B25CDA63A82F305FE1C66CE -:10AEA000AD7D5EB1307EDCB83ACBAECBD366754EAD -:10AEB000C9F192DC27F80669FCDAACDA60AB03EE84 -:10AEC000DFB630E8C37DEF2F9F7A6F3CEE4F78BE40 -:10AED000581946F4372ADC7E85EC344E03AE0F4118 -:10AEE0005CF1AC9013084BD36F84F98C53593A6ED4 -:10AEF000DD1DC7D81113E985ADF41CFC17F2CBBCDE -:10AF0000AF4FDF8AFECC5A53D0331CFB6913766FE8 -:10AF10000B871FBE77DACBA83FE78DDC0F5F80DFA2 -:10AF20009D6F999C8E7E3BF4DB65D2C459C09179AC -:10AF300068F7B0BF72C4D384D00CB23F5E33CD4F3C -:10AF40009EE709F31F7AEF90A87CC6E691503F6117 -:10AF5000DE775F56E55ED433F2EAEA270FC3B2F933 -:10AF6000737FB69FAEDFF47CD037A69FE3F6FB95E8 -:10AF7000E3C4B78DC8B7387EF084CE7ECF927CBB59 -:10AF8000E738F1EDACDDDC7E37EE2E3523BF7EB940 -:10AF9000D8CF3E0507B651F0DF5AA57B0EEDFFDA9C -:10AFA00063A57D7DE7247FAE3AFE39D69B16ECF68D -:10AFB000509EE0DC1ECEA7070D068AEF0F6EBE6E18 -:10AFC00053ABD2D76E821F4D72D2D8CC841FBDF046 -:10AFD0003DF4BB1A6A799D79630C1FE56FFC641917 -:10AFE000F24B0A78BD583F037ECA78DA1759CF86EC -:10AFF000A39C668DF5EFC9A6F53F1E7767D5823E07 -:10B0000081F66DE9F37C789455CA58F07791FFD2B8 -:10B010006FF2613E6C6D6EC732F48B43E3189D9BFB -:10B02000BAD6D43E06E3DBB5E3BC4EC024E06D0BDC -:10B03000F9CDACD82CEC570DF9DB8DEE7FF551BE78 -:10B040003A56FEF7B490DFD6E84DF4E139B6937680 -:10B050002B0BB89F6267087F23E017DB93C2A3C264 -:10B0600008CF59813F89C773A62E3A4FF7DC4B09A9 -:10B07000743EE1A4B19C5F53C67690FE7873CFAD69 -:10B08000649F255F3A7625909D4E559D0AE62F18C0 -:10B09000BB23414BD77651879B22EC48E12A4EDFF8 -:10B0A000C46CEE6724661BC4D52CF85C9EB712A254 -:10B0B0007CC259417FFCF36ACE6B6AA889903CD56B -:10B0C0006FE7FDA527F84B1FD2F0AFF497E47A2B7A -:10B0D000AEBF4E89C3DF3E0147FEC60544F759B5F2 -:10B0E000E23C8755DC8F60C0178837A023F1C16D23 -:10B0F000E973896EB35629F7101D431594D7947ED2 -:10B10000576CFFE5D95C2F6EB306CAB18EAF27C36B -:10B11000E1C3FA806D297E03AD0F94A6507E2323F0 -:10B120008DFB8119C20F8CCA7DA0DC00E39C7239B3 -:10B1300038BDC3BF57316FEDCFF6C6F5EBFAC6EF9A -:10B14000BCBFC9EDA1A118CFC8F563898F704BE2D0 -:10B150000CAD3EBD51E0233C98CD40BD0171829DB8 -:10B16000F2EB4E1807F3049B473DCBF304FC5CE77E -:10B17000C26C9EA71B97162847BF2CA330B090DB4C -:10B180004F3ECF587CEC13F6FD8DE9F795627CDAE3 -:10B1900078A7DD8772F7E42BCA4CE2EB90050FFB32 -:10B1A00001BEE772080E13D5ADB1A04AF4686C0E6B -:10B1B00084E3F3FD1492B346F0F3D0BF9F847C9EEA -:10B1C0004E7C1FE67CCFED9FCC23A09ED4AEAB4837 -:10B1D0007D20F50CDA37E46729178D377717217D45 -:10B1E000BFA95E3967E2727E0EF0807224E5C6F177 -:10B1F000329797152DDE4A7CBE02E45E4BEFD8B83D -:10B200000BE1C4F855EAF71F66051AB3318E3044D6 -:10B2100096D1DE52A18F1B5F5E5E146F7F90D4C704 -:10B2200016711EA6256C0B6BD741B0B6C25146D71E -:10B2300010DA23DBA2F87996966C695FFBD4A5B58A -:10B24000640FEF5B97E642DB85F2B3D946FBD4642B -:10B25000DE29B6DF87B2155D7E47C625B89E81EF31 -:10B260003F23E4A75DF0E573D932CF1BD6F1BFD7FA -:10B27000103C8E7505FDD931F9DD3F2B0F26C791A6 -:10B28000F63496FE723D06E733A5A4FFF7DAF731F0 -:10B29000B1CEA7E7C717859CD46533BAB69B2217F2 -:10B2A00049AEE63B18D5F3AC67FE345CE77BED1A9C -:10B2B0002E0FFE9E22EC7F606ED09A9311CDF7E2A6 -:10B2C0007D8C3FEB54164A009AD46D3385B5FB64F0 -:10B2D0007E86B58600C779872564043EAFC80DEE2B -:10B2E00045FE0A8DE1FBE1423FB4D2FA1438D2C3E5 -:10B2F00051BF34B1EE24C473A3B1AB08F393D5AE00 -:10B30000E03EA4FF2786AE3C5ED7C1D7CF8E897CB6 -:10B31000EE3191CFED344772BF9F1E3D9FEE02E3A9 -:10B32000755517BA0CA918F77DB8FB0F2FBE025F31 -:10B33000DFFBCAD97B7F84D85A61BBEF6770ADB69B -:10B340001803AA26EF76CC115FCF7E20F8A8B7EEBF -:10B35000A925216E3E7F6B0E7FAF2966BD7A6B0EED -:10B36000D7A7D17D4F7CBDFAC37ECEB5BA2147D4D5 -:10B370004B8A7AACD8E737E7707EDB666245EB1123 -:10B380009E4D0E5AE7672A3F8FACF6897C1FAECFE1 -:10B390007716F0F3EF7BD62864078E99B8FE81BF4D -:10B3A0003B2D15513B8A6E0AFA89B5CE50C400FA7E -:10B3B000A376A12382E760C27D7534CA5AC8497555 -:10B3C000C133857D9CD5FCE65F319F51AB32CB68A4 -:10B3D000F8EEA4BD2609CDC39CEF3E8447CCB0CC8B -:10B3E000EA76513F2ACE57F34F365EB65DC9AFD3EA -:10B3F000EF1BF9454E80E5C0FCAB9339BEAB1FE2B5 -:10B40000E7ECCAF77F23E43696DFB621AF02BC1F14 -:10B4100029DCBEC48EE3CC1DF302F253B53B60A31E -:10B42000FE1F3A4B7AADFA152B9D7F5487EB5CA03B -:10B43000F2CE9776152DCA47BEEEC9FB23E6C9F6B4 -:10B4400026505D721DAE7769D6A7FB5BEFEA7F9D44 -:10B45000CB6B46FE6DBCA410FD67EE7DF328EAEBD6 -:10B4600046B59BF862A6C54E786FBCA4D273D6666B -:10B470003AA3DDDFB6D0EDCF47B8433F1E9D42EB88 -:10B480006599709FF0574CE7632C10F5E0CEDC60B7 -:10B4900031BEB7CE96743FC67D172CFC3CA4263334 -:10B4A000AFFB6662DFB0A43FCB71E8E9BBF7ADBF8D -:10B4B000225C3596209D2B397B06C4C946A447647F -:10B4C000B8B3444BD7D1DFEA5C5B7B0ED7371F9A0A -:10B4D00079DD4F5FBEE67A69AB7C2F8BCBC787796E -:10B4E000AC76275EAF852B7CF761816897F1766C2F -:10B4F0003F33857C7C3894DBA5D0025BDCF33CEEEB -:10B5000014E3FD22C73F19F125EF3F25E4CF99EB66 -:10B51000BF1DEF83DEBB03F51EF0632405FAAB7E8F -:10B520009DFFBE005BDA4375A7BDF32A12F0BAE2B5 -:10B53000C3F5FD68BFF7607FF09E9FFCF3D7ACB406 -:10B540006F8D4D063D8C7A77412E43BD0BE3CEC403 -:10B55000F1A1DF480ABD9740F3606DA08F41E0CEB6 -:10B560000FF7125D5654029F968BF3F2BD51BE92B7 -:10B57000FC14CB474D424FC5598F6F42B862D7E399 -:10B580000112A237F1DBB7D8FF352A8DEB7F90E7A8 -:10B590001FE4905D8D0CD1D6F3493C4B3DF861A280 -:10B5A0009E2F4C02CE16F15E2F9EC5F953E985DC25 -:10B5B000BEC93860B5A0BB557C27AFD25EC5E6F3E7 -:10B5C000ADA25F6B4E92A4CB6308A7B4737DE8BDB8 -:10B5D00081D31BDE7B9CF44742CF7D6960A7EE02DE -:10B5E000FF07CF9F84EFECF85D9F7CC4586E5F9B94 -:10B5F000163818DAFF0D39A24EBBBC87AFB715C39A -:10B600007508CA1FE81DE5EAF4C3D8DF037AEED750 -:10B6100058EF01E329583F944A6AC08BFD01BE9F51 -:10B62000D7E23B76BC63F808FCBD1D39625F5C293C -:10B630002B457ADDF7EE5F1CF77AF17C72BE1FF7BF -:10B64000337BF025ECE7CC0FDE22FFFE983952D495 -:10B650006E8FF3DC1CD9B84E893EBFFF17C610FEB3 -:10B660001E4567D79935D3812F6776197D38E4CC8D -:10B67000872FBE3302FDE62E13AD1B81DFB00ACF4C -:10B68000E73C26EA0059B33EFE7F57D047EE0B96C3 -:10B69000FA49DAFF79CCC7F552223F0FFD93F973CF -:10B6A000695F700D0B1CC2F3D0BF583091FCE2B93A -:10B6B0002C48E771CF6AD39F871B7B8E6EECF9B95C -:10B6C0009880477CC59EA3FBE5F7AE9C2F97F52B92 -:10B6D000B1CFFF26F8F1CB7EEACB4F0BFE95F500FC -:10B6E0004DB21EE0D52BD70334C5D40344FD0C590D -:10B6F0000FF035AF0778555F0FF0E598F8705C10E4 -:10B700007034E1393A71FB4DA2FB5F165C799E4DB6 -:10B71000782E4EDC7DDF76BADF5F3D822D57E0A9C3 -:10B720009F7A8C845CD9BF47678F6DB9DE183F2B39 -:10B73000879E37C5D435449FF37A06991700BA52CD -:10B74000FD9CF4EF62F7C3CB7CBC949F4F1566F170 -:10B75000501E6DB5881B7C43D11FFE14FD2C94DF59 -:10B760005BBDAF7503A8B37E7443915A1095AFD8F3 -:10B77000F9005F9ED6EE3B1F902BCE6FF0311FED90 -:10B780004B147271DF0FC625633EFFE387AB74FB7A -:10B79000CD7AF7A39BA57F67D7D9731663EF67EDC3 -:10B7A0007E8BFCB71A4B80F6BD7DF6EA0FC8CECF74 -:10B7B000610117CAC9F957AFC90BFE5FD87909CF24 -:10B7C0001DA1074CDC6F4F27FF64AA80E78EBDDC0C -:10B7D0007F3458FC261AC7CFBC4E1785E61C5E5036 -:10B7E000B678EEDD4DBDF097D07919A305FC0A7E41 -:10B7F0000FF8BD495CD9CCA01BE196FBF881EBDCCE -:10B80000786DBDC1E7C5EB2D4A40659AFD9DE359B2 -:10B81000730EBE6FB0741BC5F962742E7C42145F48 -:10B82000D47688F6D23B2FDC371BEFDBF9F9C26602 -:10B8300001473057EC5BB6300BCE3BC11EF982D6C8 -:10B84000FBC4353486FBE3A1025E479C88E717C042 -:10B85000B876FBD9104ED6C99CB42FDFEABC10C114 -:10B86000B844F3BB1035B9C335BF0BC1223C5FD51B -:10B87000DFF398DF8D4815F0B50A3DE9C1F3050BFC -:10B88000E91C05D2938F3BE6D079E219F685B40E18 -:10B89000FD54D2045AA77421E2B13E7E82E61C0414 -:10B8A000789E11D09F7F903943DFF604F56D0B3BF6 -:10B8B00046F55C4A24E0BE9C163DE7D124F4CD9DBC -:10B8C000891CAE3B1379FCD69AABDF971990BFE782 -:10B8D00092CACF4938E7B258B0AE02FC93D65CEEBC -:10B8E0009F7C0494863891FFDE4BE92DFE416BCAA4 -:10B8F000F1774C8CBE2540A7650E6F8B8A7EDFDD0D -:10B90000E277BFD40EAA57D8745F8A0FEB6B9659B3 -:10B910009D9598070DE5F2FC4F93D8A70114A9DB7C -:10B920000EDF6D9A9A4DEFA557F550FEB467392397 -:10B93000BFAA0F9F7E0DFC0FF87E16DB787E438D2D -:10B94000AF0BF7ED7AFC46AA3396CFB7E07380537E -:10B95000117C81F76FA988FE2E53E1DED2FD78FEBF -:10B96000240B2A3E9E8EF412BF4F13FE7CD3DECAF8 -:10B97000DB87035C855DC3888D07EE15EB2FE90936 -:10B98000627D989FBF1BFBFE407C1FDAB6C3DE7F43 -:10B99000ADC7470688BBF1BB31369AF711917F627C -:10B9A000423F8C8891BF515179A0E7A5A2DD24EADE -:10B9B00001F1CC087F054F6FD07BE95C3E7C4CFEEB -:10B9C00071B9BD9145FFB09FAA68BFA4A7C6461F25 -:10B9D00047E510A65866F1B5D6C37B07A7F075F406 -:10B9E000116A641FCAFB28712D155736B39DF0BB31 -:10B9F000A225F286291F532D0123B62B9CCB5BB1C8 -:10BA00009F9B94085DF366AC6E4535EDCD2B14FC21 -:10BA1000161C87F2B96C1CDFDFDC3AD2E773C2A3D5 -:10BA2000E933787E76DA0C0BD54D4F53F9794C4CCF -:10BA30000DE6DF0572765735CF0B63BB5A937791CE -:10BA4000EB204720BED911C73FF0E671BB25BF6F81 -:10BA500012753EF2790E1EF40C001AF2C67F9C4B52 -:10BA6000F684AFF77E962BFCB462561CF3FB315F75 -:10BA7000901EA8FC5D7F7A42FF5CE88969FE274C36 -:10BA8000E4DF0B7D21F57240D42F75897354DE1FDE -:10BA9000C3F1FE5EE53CD21777B266D2E777B1908C -:10BAA00009F1DBABFF2768FC2318675A40EF2F4DE5 -:10BAB0009F11EB57717E95E3DE1DD43F9F2AFDDE7B -:10BAC000097ABFB7FAFB5FA7905DCC7CAEE1F2804C -:10BAD000689D52534C9D52A3A8536ADA3DFF60867D -:10BAE000A64EA9692FAF536ADC7DB53AA51E5A57F9 -:10BAF0003A620AEFC3F59623F3402400CEFDA2AECE -:10BB0000E500D6B59445F9D23195E75D817D69FDB3 -:10BB100024C769F3213FB519CA284FDB96E4F069C1 -:10BB2000F3A22B5A80EF34F959599774A49FB8B8EF -:10BB3000388FC7A96B159E270FDD6DA13830A33054 -:10BB4000A05B97C830B2A3986FFC58F8416B451EB4 -:10BB500004D7F586C135AC70FFA6F77BDCEF84F91E -:10BB6000C9187D9491E6A375818CE42194DF9FB17F -:10BB7000B7740BE91BBBD587F5FCB2FF19C14D2A81 -:10BB8000D60B35EDDDA4D6D8A37C372A4FF0AB8D8C -:10BB9000D9905F7BF37D3B1328DFF7993D704B1EF7 -:10BBA000CCA7DE1C19CAF4FC4CF7FBB36B7305BFC2 -:10BBB00098C604EE9E0DF09C7FC7CCF35E0F3392C7 -:10BBC000D7DFEC49A17CA53A95917D595AC9F8EF88 -:10BBD000BB6C52C89F3B99C2CF0D5A3A85911D3C10 -:10BBE000973A9EE8378F850FE1B940B51B4CBAF301 -:10BBF0007F1EDCA26FD7B30EB237F5DBFBF033E963 -:10BC00002DA91F1B98D7887AA8B153FF3D1BA8D731 -:10BC10008FA5C21E0C9B36B6D504DF0D3370BDC593 -:10BC20001EF6654FA5B8BB9ADB51F61C9D3775DE35 -:10BC300071CAC8E59CEBE3E151ADA9B34BC3857F65 -:10BC400075B3CA7F1741FA4BC3C5EF241C30EC35DE -:10BC5000D26FF20878CAC577D24F93FA5AD2A5723A -:10BC600024FEC603443779C2DF2960054857E89FA0 -:10BC7000E441C140891F714CBFB7304A8C0774E75B -:10BC8000E7CD192C61E4A3654A33E9690B13FA5A2D -:10BC900009925EFEB750C8887C70036BBE037FBFFD -:10BCA00073B4A5CB467EA93DF868DEF0289FB4B2F8 -:10BCB00048DE0E45C72FF4FC4CCAEFE2F28BB42BE2 -:10BCC00091F7B9BF3189811F08E3FA3FE07ED001C7 -:10BCD00085C78BE00F1EC078F1778689C40F13618A -:10BCE0001AF8DE38A79ECEB7BAF5ED89DE3E7C6045 -:10BCF000D4FEFE04489C8AF04C2AD6BFE797FA8D02 -:10BD0000E9F55B3EFB9AD7C12F3FF45DCC1BD816FB -:10BD1000B162F463C073F4C5FB7DD16DC25EC459DA -:10BD200037D99697D177DDE4BCC8FFDEC8BAE76C97 -:10BD300057FAF2CDB9838B8C6E0D7F497E7E59D434 -:10BD40005928AF8BF5D9729E2F8CDA79CE3715A290 -:10BD50007523F21DBCFF96E417F13B2137EDB64683 -:10BD6000F077704A453F3722FF9445ED7AC460F77B -:10BD70009A0B904F7C6D46635F7FDE95EA257E19B6 -:10BD800066F013BF0C67BE34A4D3484B47AB8AF0B0 -:10BD9000EF19911DB4EBF8E31DE20F05F883F2599A -:10BDA0007DECA3FE790CFF483A1E167EF4ADCC4B19 -:10BDB00071C404E14747F239FF54D9EF54F1FB371E -:10BDC0000B78BE612C2E28D23E53BD5DACB2E8F993 -:10BDD0002096BF60448376DC587EEB8F6F0620DFB1 -:10BDE00048BB987675BE39DF3FDF9CBF12DFC4F2D7 -:10BDF0008BD42B3BACCE2A3BE6B76A15D2C7C3DE49 -:10BE000019D88AED6B1AF2A90E66478A6F3F3D6F0B -:10BE1000E6CFCBBBFC46AC93295C289EE707AAB0D3 -:10BE2000DDB488AF530C3FC2EB68063ECC9F972E23 -:10BE300069DE8FFBFA9A42FCFB97BF5846FB9BC218 -:10BE4000CBC4F795ED55D86E6AE3DF9FC4F5A6EB3A -:10BE5000B1FE2DDC8AF707AFCAF7F1B094FBB5B796 -:10BE6000083EDDA1ECDC4FDFB5F3EFE61EB224D2D5 -:10BE7000EF060ABFF56631CF5B36F079A67F7A1BF5 -:10BE8000FD8EE8EC9E10F94F9F1BEAE9776AFA8B6A -:10BE90003F2B95F61CBCDE8AFA040FDFB2005F1759 -:10BEA000F0F5C8CD30C47503B83F28D7F1B0AE4027 -:10BEB0005B4770DD001E17C9F75CA97C1F1A7BDA8F -:10BEC00041F962B9CE1859C71494339CA3F003E228 -:10BED000AE3BDE5AD84CEB8DB70E90EB8DDD2A9E33 -:10BEE000A35E7AF92FE3E3E559CA06F03CD0295165 -:10BEF0002721EFD786F3E977C1762093D03EFAF079 -:10BF0000EFA92DCE056762DFDA8E7CDEF60FD8F062 -:10BF1000D3B61CC0AFA159C573D4589E42FBF6FEE0 -:10BF2000A58B459293FAC27FABCA2266BEEF8EE024 -:10BF30009FD36ADECCF74F72BD344DAA9DD18348A2 -:10BF40004EEF1474FACE00E1770C63C350DF4C134C -:10BF500074BBCB027E2BE9B576538CFC4F1980FE67 -:10BF6000C653FDFACFFAE731FAA1568C3B47F8CD1C -:10BF7000F3F0F7478D78BE3BF79F4F3DC5FDE607D1 -:10BF80005907E523CF3FCDFDC506981EF24B9FDF35 -:10BF9000E7DAA66F3774C4FE2E6C88FAEFF3BBABFA -:10BFA000253CAF7BFEA9860ACCEFD5AE7F87F2C7D2 -:10BFB000B5525F84F5FA021C0CAE2FD65D4B791D8D -:10BFC0008385FF2EE630D017586F320CEB48A1FF67 -:10BFD000A162DFFE72FC84EFD77F6800E98D09540F -:10BFE000674AFD19697DF71DBF374A1F693762F53A -:10BFF00045A9CCD70C4CA57C96D41FA5C24F611384 -:10C0000062E3C727490E8789D64F06E8E320E97720 -:10C01000C0F7E4777419EC618341EB6784492ECB58 -:10C020002C602F48947C1626F6FFC7D0F971A273B6 -:10C03000FF7194FE790C1FC838A642F0C1DDCC4FC9 -:10C04000F1D12EC107EFBDCF7FBF6D9A7D21F1E108 -:10C05000FB1F70BF53C651DF3E7E8AFC43F1532F56 -:10C06000DDADE04FDAF07728260E5A83EBE49D56DB -:10C07000FE7BD50AA7B3EBEE2379DAFCE27BF8BBB3 -:10C080002B9ADF73689D9860C175C456138F2FA6D5 -:10C090004EFAB062A6467F0C49ABDC85F85AA6740E -:10C0A0007DEF4F186FBC25CE4FDD9B4174BFD0C5CF -:10C0B000EF5FD8709D2F04B7BF3489F3A894E63999 -:10C0C000581A25E198237EA765AE31FC5A37AEC7D2 -:10C0D0002AE15DF50AFDAECA01ECBFCE1031F3BC1A -:10C0E0005E17E5E965FFFDE72943A4CFCC6F70FB40 -:10C0F000D8A324FA789E37A4FBBD9E035E1E6F551D -:10C10000E406BA060C8FDABFD8BA8363F36FA57D55 -:10C11000A9FFC5FCC9B82EAAA8FCF79963C7C53A00 -:10C1200083A59A3CF5316BFCF5838F849ECF435CED -:10C13000C1F88BB2FD1FE33C4F89B8F094581F3B08 -:10C1400095C4D7CB4E0BFD9CE715EB79E27A4AAC50 -:10C15000A79D4AD5C793F23D83977F7762B125B0FB -:10C16000544357EFBA8466CC4B64148ABA92858CD8 -:10C17000C74F7B5274E72438BC9579DE0C7C4F9C0A -:10C1800033B087DB655CC7C675E6F559C14B88B728 -:10C19000462FF3E33A2DF3769BEFC0F54AB13FF714 -:10C1A000BCE09BF3567E957039BC53F2BC88EFF926 -:10C1B000DD44D7DEF6946ED297FF072EE42C97006D -:10C1C000800000001F8B080000000000000BD57DE0 -:10C1D000097C54D5F9E8B973670B9909939040101D -:10C1E00088938D246461B261D86492808A22262C5F -:10C1F00015651B50C2964DA0FDA5D5BE0C06117944 -:10C20000DA426B5BFCBBBC01C16AB52562B0B126EA -:10C2100076544AA1D53A22286A6A4754D69044A057 -:10C22000567FF2FBFBBEEF3BE764E6DE4CD89EFA9E -:10C23000DE4BFC7972EEB9F72CDFF9F6F37D07BB24 -:10C24000B322C999C058F7ECA099A98CD965FD21F2 -:10C250005E871F031BCCD862FCCB09A5D5E657F33C -:10C26000E0EF0DA6CE6026B5B36F52185354E665C5 -:10C270007150C964CE0A3B3E9DE0389A0D4514B416 -:10C28000433F7566DB066534BD5E6185FEE68BFE69 -:10C29000D870BB11FB9FC7BB62F3DBF67FA5C43030 -:10C2A000B6C0CAD60F83F6856D43CC3003B62CC614 -:10C2B0003BD291836F4C761C8571156FB4FA4D3467 -:10C2C000F48D3F93FA968C19D951393F5A8797319B -:10C2D0005CD78800AD6B63694FD27F1531D6D36EC2 -:10C2E000716C83716ADAFE7A588175D5C8F5B568C4 -:10C2F000D797ED54182BC69AD5F7A995B15B98C27C -:10C3000006423FAD364F36C2ABC61AA479428FE61D -:10C310008A5C18EDFE09B1B4FE21F03DCCE7C546BC -:10C3200037FBC41482E72A075FFF14B5BADC1CCFC1 -:10C33000D8993B99C3028F56EDBFA3C90AF5550F93 -:10C3400030071FDD6D6063A07F01AFFEE69750618F -:10C35000604EABA8E3B07306306766A83ED413A75F -:10C36000A943BF0CE7B152F43B6CD9559AEF47D4BF -:10C37000A768DEBFBA6194A63DD95BA0A9A76E18D5 -:10C38000A7793F7D5399A69EB1E546CDFBF92C7563 -:10C39000208375D6ED53990F409BE59BA169CF7E15 -:10C3A000FA76CDF7C758FDAF27C07B2D5131790CF8 -:10C3B000F0A8292A661B96CCEB0EE4007CEE14EB69 -:10C3C000C86D5EACE9E754CC75FB705FEF0C544D63 -:10C3D000638057A35B5768FA5DA956F37DDB643A27 -:10C3E0001284EFEAE117E159C07AF60E03FCA8F5D2 -:10C3F000292E3F342FDDC2DBE577CB5BB7D277CB7D -:10C400007DDAE72B9FD6D6BD652CB3DE06EB74DA5A -:10C41000E38F02BEB2ABD855DF84D155080FE025BB -:10C4200018EFCC63AACF928CF0C9F8CD04828F8923 -:10C43000F99C7DF7EB0C632E3FBEFF9CDDE585FA92 -:10C44000D2FD77D07C2C895A3C88726AF1203A530D -:10C450008B07769776DF079668F75D0FDF58F7A8AA -:10C460000BC277D00D5ABC90702D81DF6F13AE8F49 -:10C47000E8E059B8C7DD642338B159D631083F3EEA -:10C480005F0BAB50592AFC1D0F7C069EBB7817EC46 -:10C49000B4C3E63500FE3CE3548CC427443FF94660 -:10C4A000FFABB89EF58A97E17751CC9788FCA2A99B -:10C4B000C49FE4877D29B0D6E3CEB1CF6C15BF47CA -:10C4C000BAAF36FBF3B05DF6F799CD43CF3B953766 -:10C4D000AA18AC9719FD79C40FAD8CC697701C33A0 -:10C4E00080E3F14A5661C6715E14F8FCE9FBCB08A3 -:10C4F0008E55AC7EAF1BC63BF50187EF72E6A5F704 -:10C50000966CD2C2A10FFC747003B471E2B875626C -:10C51000DD2B18F31952FBC2536953FCF63C04435C -:10C520009BE4DB9E6F0A39DA213CC7B1DE1FE2DFF4 -:10C5300012BEF08212CE9F703CC7E0D078129E925D -:10C540006FC9712CAC5E4D443AD0F13196A9DD270C -:10C55000864C620CFD473F7F021E6A8D13830DC619 -:10C560007E70F28C5D23C6618B3D8908272BDB44EE -:10C57000FBB751716D50611CF5EAE42606F02C748E -:10C58000B855DCAF6216988BCF4BACCD4D46E8EA80 -:10C590006A76DE41F834E4A99A6F0685D6A1C8759B -:10C5A00079156684FA44519FE955828F26E37AFE15 -:10C5B000FA158E3B519433B184FD83657EF2217C64 -:10C5C0003C41718EC0F166FC292301F166BD52CF5A -:10C5D00074F33BFC32F4A31A7A06E17B5398C7C884 -:10C5E000E5AE8FE4CD5F9520CDFB07CC7D1F965245 -:10C5F000BED5B2E6EBE642BDB605E4560C96517EDA -:10C60000154AD6AA8327331EC1BA015682F8BD1235 -:10C61000EB72DF9343ED5457FBD6D7C21A86C65D43 -:10C620005CBE3F98EC10F2B167246FE7FC6D998017 -:10C63000D73229B77CDAF975E01F4319FB8B1960F3 -:10C6400052807464F51A063296980C7489F3CC63A0 -:10C6500079D83FD0D5F064E87F701CD0A1124E7716 -:10C66000FC7DD9DE87EE74EB67F5B0B96301DEF6C9 -:10C6700022B30758EE1DE1EBBD0478483D6221BEB0 -:10C680000BE37DE174525933A0E35D373617059211 -:10C6900050FECB7DAA33334F33EA2DCD0934AE7C27 -:10C6A000EE4E360878013E5E029CFADF8734D28770 -:10C6B000E43E5CAA3E347E109FBF84DF75C9820FC2 -:10C6C00086E07DA3069E0CE099AB81F78D91E02D6D -:10C6D000E171BA38F014EE936A3F3818E13C2FB19B -:10C6E000E2966400C188C3C1A38A01E55DE7538F68 -:10C6F000A2FC6A555D48C3B513397FAB7D492592CD -:10C70000EF6AB3F814F87E59EBEBA4977536020381 -:10C7100035F50F9FDE75EAE0DC170E7CFFE43AAAE0 -:10C720007478B6E0EDB3F6F94E5ADF8AE4840BAEC6 -:10C730005FDB2ED67FEA476C61450EAE2F67603017 -:10C7400027346E26EE37BCFFD3988A7A845BD13BC0 -:10C75000C363102E53D4B6BD57211CD6282E0B8C84 -:10C760003BC9C2BC51B0BF431BCAD927B04725C182 -:10C770007A9703E09138DCE652011E193F542B7C76 -:10C78000D0EF3FD7AC8EBB03CA938D30743A3C5781 -:10C790000C1584676CD7473F81FE32ECF35C1BA11C -:10C7A00036DF02F38171927F14ED4F05FEF067339F -:10C7B000B3229D9952EA0F4C857E7B625517EABFE2 -:10C7C000F12A9B8C7825E11C1FCDD7219F973EBE77 -:10C7D0005D09DA42CF2735F514AE82F2E66427AD63 -:10C7E0004BAE7352794F21EA3B12CEF1A9FC7D6624 -:10C7F000EC499A114617D9021E1DA8CF013C6B13B4 -:10C80000CCEB51FE7559799DB93349EF5D63E57401 -:10C81000D11195E443B9D8016B0D507F7E3BB385B0 -:10C82000F1C328F7C06B60DDEC6D95ED80E29CC331 -:10C830003D3096E0E1E0FD083DAB8BB11B104E6B47 -:10C84000A6960D898332A189C3478F273B93159AFA -:10C850005FF597407085A1E7D546BFD961C3E7660C -:10C86000CDF3230037AF25545F7C3CED3A46FCC541 -:10C87000B51EDFBF634334F386E9552D621EFDC14B -:10C88000A536D6C88C008F5A85555CE8BD97FF5BEE -:10C8900025F8EAE7FFAEE02F09E591D7F76632B752 -:10C8A00067CAEF9FF61BD43B6B03266681476B5E1E -:10C8B0002A1DC222F4D70BE72FC733DFA0B0BA314D -:10C8C00048F0A8FDF25A7A5E7E7FA719F11EFB712F -:10C8D000C2F33551EE21AE0BC0395BC0B9F6CB586F -:10C8E000E61D14FE9CE355A8FF786AFF1D0210F0B8 -:10C8F000D6DBAAFA76C0A7BFDB67B8615B84F97E96 -:10C900002DD63F2AC148F492ED67EEAD11C697EFE0 -:10C910000D8E033E6DE370AECCED3BBF96B2E002F0 -:10C920009CFF3593993BD278A7C57B72DE2D71C1F0 -:10C930002A81F7232BED617587761FA3C5F82D3764 -:10C940000693B0FFAEA96C4E7384FEE57E8F31D6A0 -:10C950002B088FD2444F06F291EA5BA10278326431 -:10C960009EDFE0C909D15D7FFB1E8237D85D851748 -:10C9700082B799DA657F270E08BA646E9B02F4B419 -:10C9800048C8AB45DB574E03DED96BBF9CD802F6D7 -:10C990000B0C7182D5BF6EC7FA2685EC93C51EC6F7 -:10C9A0001A80EF54ED285C8F626B512263D7C6F179 -:10C9B000E7F760B9CE1492B3F47F370B978B72FC14 -:10C9C0003B1FD4EAADCBD8839FA3DE73E200E70F11 -:10C9D000A09E92FD5DF5B0B6BF65DB6F3A86F35C55 -:10C9E000A6D37F3250C103FD233545D81363D81831 -:10C9F0009403AB769C35C738FBA7839340EF69E976 -:10CA0000C82F1D548E49718F4A81FDE87E9BCF73DC -:10CA10004A8A272F05FD0D6FF3799DA93EC3E5C412 -:10CA200063F1249F2CC8CCE14FCB5CABAF09E6711E -:10CA30003FB09328808FC5C2F520A9FFA9EA6A35C7 -:10CA400006DAC77EB6260EF737FED9EB6FC0FE12A8 -:10CA50009E8D76E37A3696BAF3D15FB0B1D2E66AAC -:10CA6000822EADF03DCA0FDFEFC6BE76156A07CD48 -:10CA70009BCB8621DAB5BDEA477FCA06C3E77B8731 -:10CA8000C1FB1BAE65AE26161AA7AEADF2799C4F60 -:10CA9000D22C2E673626BBF31D61FD32A1CFD50AFD -:10CAA000D875B767FC7C3CECEFA3FB489D86F5A5E9 -:10CAB0000C44BE318AF17D66E7014E80273876B896 -:10CAC000DEDA09F28A6584EAA39A15BF09D653D340 -:10CAD000F2BC01E561F5BDFEC173512E3D63746D7D -:10CAE0000B9B5FFC9F8796396342F268AEE2207D24 -:10CAF00041EAE5B731F99343783347E0CD6D421F02 -:10CB00009F1BCDE1BB98B992F0BBDBAD2CC60024D6 -:10CB100035B7BCB998E4D54A532CEA3FB89648FBE0 -:10CB20002DCBFEFC4AB54FD9BD0AEC7B97D2331210 -:10CB30003B3989BE1EEE5FF26D4BEEDBCFDD298205 -:10CB40000E470AFD308DB9EDB0EEDA5732B66E847D -:10CB500026CB00D8C702E24BD69202D28FAD68F73F -:10CB60002C7F39CAAFC484E0C21CEE7C03FA09668C -:10CB70000C2FD8883AE961E02F40605DA66012D1A1 -:10CB800031F01D0564DFC329932B8D80E7B55781F4 -:10CB9000FE05F5D7B655F27A4AB0CA00F593292BAF -:10CBA0002B8D8097B5A38247B17E2EE547BC5E10E2 -:10CBB000AC52A13E30751D7F1F0D4140ACE1A9FF75 -:10CBC000B3D20BFD9F8C15F2DD155C80F853FBA7EB -:10CBD0000CC3C6B0F55A5339DF3A19C5DF3B99CCBF -:10CBE00016CE4078670647E23C7BF12245EAC39BBC -:10CBF000A894EB94DFB1C4C8FD3F99C2FB5F5E2EE1 -:10CC0000F49268B601E106DBE48D01F8EF69CBD858 -:10CC100086EF6F488913F0827E8A42FD4838CAFE4B -:10CC2000E4B82B50EE223F36013F0EE3A3CD295C42 -:10CC30006EC238EB689C1C0EFFDA19C3F371DF601B -:10CC4000BF8C62BF8CDC4EDDCAE707FDC6E611FF74 -:10CC50002F34C2FB7BCEC3FBC9A179EBF1A35DE00E -:10CC6000C7F2266084A4A7A5121E4D8AE6FA212BDE -:10CC7000D2AE63602A879F353596AFB3773F86285B -:10CC8000344E9380E370807BEEE5AFFB2D319F6FD8 -:10CC90007BDD61FBE556B1BD356B5BF87A18DBAC2B -:10CCA000E9E7E45ADD77254080388FB854FAEEFE84 -:10CCB0002866A5E76C5BEF77C9795C2F457DB546A3 -:10CCC000E8D5CC7B2D3915AA05D7A8D910303BB1B2 -:10CCD000BD5971FB103FD3607D08DF19D38AC4FAB8 -:10CCE0001C627D0EBE3E9F064FD9C19EA459F6BE62 -:10CCF000F8DB0BF7DEFE720A447F1ABA8ED41FD21D -:10CD0000477FFBA1A47ECBFB21E7A983672F9C75FE -:10CD1000F393F0447AA6EF72B4F828E779AE3FBAFD -:10CD20004EBEC2F14AF977353F867D44FDC4A9C5A0 -:10CD3000E79A9664C3E29CD077ADB897C521FF5CB3 -:10CD40005AAAB07387B3E1C8BFBD65DC8FEADD6561 -:10CD5000713539C9AF97995A1CD1AF47CFF5F65EF7 -:10CD600077AC9929A41769FD0CDD09AE801BF5D4B9 -:10CD7000D3CCB503FA1DAFD33BBA613F77D942DFBD -:10CD800085E489B6FE43C13FFBFA8D7A92707E45F9 -:10CD900096B2179C2EC6CA52B712BF2E1A58B63A70 -:10CDA00019EAD7A73E49FCBA6858D95974CD4C4DF9 -:10CDB000DDCEEBD9656753B0FEE476FEFE24F70BBB -:10CDC000C8DF99777BE5E4A121FDE1C654278DAB4F -:10CDD000961B18E29145BDCB857252C2B3BFB2C853 -:10CDE00062A88FA4BFCEECA5677E9E5122E4738912 -:10CDF000B4E783468D3DDF1D63F5AA00D76E94A787 -:10CE0000B0DE05A99E3908FFBAE8CE05A80ADF1BE7 -:10CE1000FD9119F521C50DFA06FA459C0E360FE66F -:10CE2000A9746EAC203D7085CB6A24780A3F15AC9E -:10CE3000ED1BE8E7E5579EB97B181FA602E73156C0 -:10CE4000D07FDD2B5F7DF121CAD1933617AA816394 -:10CE5000DB1E598DFAD5D8B6BF7FC5E5AD8DCEA9FD -:10CE6000E4BCC7A2BF119E97B45A68FE63DBB296BA -:10CE7000E0FBE3DF694B45FC98D8E16F4276D0DDFB -:10CE8000FEC7619EF0732B764CF926FBF2F58B5EA4 -:10CE9000787C6666A85F023C7EC2E171BE0AFD8AAC -:10CEA0005D0907D607494F1BCEFD98E27BD0CB33F7 -:10CEB00091CECFB0012E3C57E8B6F37EF4FECDC341 -:10CEC00095B03E783EB1076610A6374FFAD20A0CED -:10CED00024542F65B19A7AB975A8E6FD298E644D60 -:10CEE000FBF589599AF6A9CE7C4DFDA6CCB19AF7EF -:10CEF0006F76956AEAB7944CD5BC5FE9AED4D4F3AB -:10CF0000FDCD9AF70BF7B56ADB0F3A691F0A3B2A8A -:10CF1000CA519F77053C4D585ED3B9A97CA093F5C3 -:10CF2000F1EB16057D4DF87CFCF9FA623FEBEBDF87 -:10CF3000652B3C741E60C17D51C3CE074A03448FEC -:10CF40005D069733DC8F3B6FB067672AF97101ECA0 -:10CF500000EC6BAD3D8370BFA62C7C488DC17DE994 -:10CF600061E4FF6A31077F361EE5FC7C95F4DE162E -:10CF70002323FDB1654EAE0F7D7F8795E08B1F2289 -:10CF80009F9A1F4DFC642268B8B46E3C0355709F95 -:10CF90003C9A7597B2E5BA7DBA4B539FE2F8B1E679 -:10CFA000FDEB13D76ADAA73A1FD0EDD3664DFD66C5 -:10CFB000D723BA7DDAAADBA76734ED133F0D3621FC -:10CFC000194DEAF4AA7698FFB8C39BCA715FC67779 -:10CFD00078E723BD14F93D4DC442F6D4BF8EA51F9A -:10CFE000EC2AF46BBDD69848E59E4627F9A5F6369F -:10CFF0006652B9AFD145CFFFD65842E51B8D6E2A98 -:10D00000FFD178039581C60A2A9B1B9BE9FD5D8DA4 -:10D01000AD54020447A0BC881F24E40FD4D1DEEF36 -:10D0200032046BF1C4F5B327CF115FEC1A10ECC2D8 -:10D03000FABDEC2CF1C5401A233AB4A633E2635D85 -:10D0400069EE6569509E4BE5F56E936D03CA816686 -:10D05000833B1FF5EBAF9E3CBFD93882B1FBD65660 -:10D06000243A6279DD0A75DA6C34CCBCE737BB87C9 -:10D0700033F67B1419E3A85E89F5EE28DE7EEEC94F -:10D08000F3955E9A1F3F6F9E153A6FFE2A35C2795F -:10D09000F3EF8F3BEDE86F39703EC38EEB3A20FC27 -:10D0A0004B6E966F5A0465A931DF8472F1B04E8FD2 -:10D0B00090E5BF6CA5065C4FB3C1351BF514EF8D31 -:10D0C00026B603F8C50C85DBA3BD7A601A9747DD49 -:10D0D000375BC8DE3968702F413C073EFD04C2EB68 -:10D0E000AA34FB0C845FB7BD2709E1909866E3F58D -:10D0F000849E27145758DDC4D7199B163DA39F75EE -:10D100000E4E8BB0CE61690E1A9FF9DD2350FECA18 -:10D11000FAC14A770DCA8983A5EE749CCF810A0BA8 -:10D12000D18FB7C2EE4B4726677417CF0EF3BBFC07 -:10D130002ACD44FB36CBCCE98CDDAEFA7644B0D3B5 -:10D140005E48E3FA3EED1BDA73B745931E7ED0C00E -:10D1500096ED8A00C7BFA77139776A4064FFCB1B81 -:10D16000027E6533EDD45FF79A283AEFEDAEC82022 -:10D170003DA8BB1EA004F4D17DBCFEF46E6AB7C806 -:10D18000A3303AD79C2BF8D4EFDB56FFFB10BCFF43 -:10D19000D19A6817F170C728924FB78B97E70FB2F3 -:10D1A00092DE327FC68832944B73C5F9D802BB71C8 -:10D1B000301D931963CD0EE8E74E5BFE7A14FF55E0 -:10D1C000F195E658A82F1B7ED77A2C57A46D36C749 -:10D1D00041599DF3FC7A541F6B80B48AC95E0ABE24 -:10D1E000D908F35AD8A03AB9FD24E49A7BE565C57D -:10D1F00063483C4438229E027CC92E7C53C05B7E2F -:10D20000F7A680E7DC34A1B7E5B2DC6FB4E73E0BEC -:10D21000114F3AE7BF39B21F3FBDB65DE86DEF9AD7 -:10D22000F9B82B9F36F9C2FD4972DC7F88791C342E -:10D2300033B7827ADCED76C28FBC3967EF2D86F585 -:10D24000E7B5390C746E2FF9788091FFBEF8530F53 -:10D25000F1B96B3A834F1D6284E7AD4827179353AA -:10D2600033BD6B493E8C3D07F207F9E279CF478722 -:10D27000880F2E137CB09EF8D79EC606AAEF6DF4D9 -:10D2800052B9AF7183E0839BA8FD8DC62D820FFA42 -:10D29000041F7C9A9EB735CEA1F295468FE083FCA1 -:10D2A0005C7586C0A779899E7548FFF2FC7296D599 -:10D2B000634278FDE5110B53F17CA2CD42780A144C -:10D2C000F0C4A3F1182F63716C74F68D9BD1F3DB5E -:10D2D000DEFDD79DF3AE49746FC27DE98D9341FDAC -:10D2E000ECEAFEF1E70073DA919F3CBDBD82F8C71E -:10D2F00001A7D38E7AEB3369953350AF3DE076DAF0 -:10D300004D50FFDDF64ADEEE71DA2D507F366D06A8 -:10D31000AF7B9DF628A83FB75DD47D8C0EB59FDF0F -:10D320007EEB0CF4639432650FD243B9357932B099 -:10D330006B908FA57B900EAE4F5C3419E9C099E6D7 -:10D34000247C98EA5CBB07EB37656E350E72A2371A -:10D35000347F1D7E57165F69C4EF260FBF6B1D7E9D -:10D36000775DDA6663F87737E43CBF0EEBD35C5B3E -:10D370008DA80F3AD3F879A9EC47D665BBE4AF681E -:10D3800027209E8E6EAB203E9ED75A417C5CC2A564 -:10D390006C56E57DE8A7AB6B551C0ACE6396D27B35 -:10D3A00058AF800E517B1EA805F8AC7FFBE2B8B5E4 -:10D3B000188782F57154FFC5DAC87CF72F88077A81 -:10D3C000BEFB9EA053949B95D0CF7B403FBBA09EBD -:10D3D0002ED657D7B6C8BE88EC198F1DE56B761AC6 -:10D3E000978BA385DC5C28EA778AFABF6CEEB7706E -:10D3F0009C77FBA7EB0FB01DE8B68ACFA30F5D6B40 -:10D40000DB055D770838B2A29E24ACD7B04DE42787 -:10D41000BC587CD7F270FB2D19E3249A29FE421FD9 -:10D420002751CD02BCBF665D9C050B9AE93CB63521 -:10D43000EC39F123617F0CE07C6F0E326BC0BF7F53 -:10D44000A78973C7BEEBFE4AF0ABFED6AD6D17EBF6 -:10D450005ECE7C14D7A65F07F324106DADB41DA477 -:10D46000FDECBB9E60E4F5F45907B7DF651C8BF457 -:10D47000CB831E14955E8C7CD0CED07F13CE270E2E -:10D480005D804FE8F9D1B7C5E72EC06F92709E7AE4 -:10D490007E23E3B3F4A5D4E7A0EEC5F83CEF2B510F -:10D4A000E4A7FFC4E9C9C27EBACB7ABE30A07D161C -:10D4B0001F243C6B002B0F9F2B667E4E0F5F8CC48E -:10D4C0007D3B6EF0FE01F5A2921D8F119FEA42E1B5 -:10D4D00000F4E8823AF29D2D575514E0772C93E33F -:10D4E0004FB7C2E5A2A47BD007A91C9BCEE551DFB4 -:10D4F0009269E21ABBB77E95447EAC8BE07B7F706D -:10D5000098A24E087A91DF974493CAD3A930BF02FC -:10D51000FA5F67E960D2233A47988D587EDB7662DE -:10D52000E78891D4BFDE5EEC1C5A62E5E35E7703C8 -:10D5300096AD66CF964568278DB5909DF496880781 -:10D540009C1ECDE3A7DEC27362786FFA91F3F128D7 -:10D55000BFF4F666E7FE7965CEBCBE7627AC7332C3 -:10D56000AEB3FA63C37DF8EC72EDD0EA862F987102 -:10D5700010C8ED86F3CC587829762953915D141C98 -:10D5800076BD8E65F1A781B83C27DA9F527F10F6F1 -:10D59000E945E2904A7AB8BE30E93CCB3416A19F07 -:10D5A00069009DDF28257FE776AB28E5B9C8043EF2 -:10D5B00005B6C060F39953347148894628E7A9C17C -:10D5C0003158EF62013A27D1DBB37F157E28B06B6B -:10D5D00037A6935F8AC727C18E0C42FC9DF293F752 -:10D5E00017DC4D7C208AF4A15EBB76B781E20C5A31 -:10D5F0008CEE8113D1AE6D4877AD85FABF0209BFBD -:10D600007A19CA3AC717043749BFD50D67099EBDB5 -:10D61000E703C2EFBBC904F207CAEAFF56490E5539 -:10D6200033B681F68DBD665E15261759F3E7BDF05A -:10D630001F0D7CAF12014876D684996EF8AE52D891 -:10D640001FCCDBCEEBC2EE626CC44C37F453992096 -:10D65000DE679B79FB08D9FE0B5E4F97FD7D3E830D -:10D66000EA43655DF49725EBFB793D598E7792F798 -:10D670009F2BEB165EB7F3F75F48FFC34CE40B92AA -:10D68000DFBF942EE4443ECB177139EDE9C5178C0A -:10D690004BD1B60BF9B0F019D56B1E8DFB3335FAB3 -:10D6A0004DA4EF668562E7AAEF3191BFFB545C732E -:10D6B000DEEA307B45C6B15494DBDDA8FFD5BC98CB -:10D6C000B14D15F13CA87F7CE1E47AF914D546E729 -:10D6D00013671EE47CBF3FFDADAAE165CD7EF66910 -:10D6E00057156E8FE3C11D8C77FAA1215BC9BE4827 -:10D6F0000BD0F9F98782DF0D06DE5A12178A178BD5 -:10D700004F656EB457E3FF08FC19F7F8D300F1E357 -:10D71000AA3F72FF6FCD23AF93DC5BAC3AC99F5B2E -:10D7200096E3F918E1D3650F905FB1AAE1159AD796 -:10D73000992C61573A7A72C2E179A22FFC4F5F04AB -:10D74000FEA7BF4FF8EBFDCE2B6C7B68BD2B2E33B5 -:10D75000AEADCBCECF455D629F8E189C6304BC2CD2 -:10D7600023012EA7970446C6AA18741C18CCE3966A -:10D77000DE2846BBE84CBD9DE1BECF5BFDCF3C4FF4 -:10D7800004BFAFDE1EB80DC72C0EC12B61641FF89D -:10D790000EC5F12E005F6DFB770CDF21C6A0D98589 -:10D7A000E7A88719F5332670C41C1E1F337624C7DB -:10D7B000CB81ADFCDC481FF73576A49DEF93389FF5 -:10D7C000A999F1C6043C9F91F430299A35A3BF1D55 -:10D7D000F0DA25F0DA85782DF137744E03DF45A0B5 -:10D7E000AF10FE6AE1EAEE0BD7C9232F8CB7DAF649 -:10D7F000EF18AE2DA00FD3B9E6EE28F2A7E8E1BCF2 -:10D8000074243FDF92F06EB8089C1BBE2338378C1F -:10D81000746AFC1112DEFDC927FDFEC87947A0D34A -:10D82000E22BA1D3AF33847D630C529CA97EDF1B16 -:10D83000FBEE7BD345E8A9E9FBA4273DDCF465B505 -:10D8400038EFD43FDF3A92FBCDBE2B38FEFFE64FD8 -:10D850009F5FFFAAA67D61C37E4DFB22EFDB9AFA94 -:10D860008460A01CD15CFAC7AF3DDEF33AD6AFD4DA -:10D87000CFDE9F7F7DFA0B4B0D78FE5612E0FEFD4A -:10D88000C5999E2F90AFBC65F035D901AED77434E1 -:10D89000AB741EE6CBA773C0D5628E6727FCE7A3E7 -:10D8A000BB016FCE320BF93FFDAF66199DB97DF11B -:10D8B000A0F44B95B9C3F4C4526BAC11F5A75260F8 -:10D8C0007991F0E66B8137140F04F43EC7CA4CF12E -:10D8D00040E773E62814FF3487F1786A28FD1E6854 -:10D8E0009F6E647E0BD42B6D46BF85CEFD78BEC384 -:10D8F0006C3E4D663182C686F65DFC20B28367E1E0 -:10D900004398AFEA56299E6D76093F2FBCDDD66C51 -:10D9100042797ADBBE7B4FDF0DED6C9DB798C76B0C -:10D92000CBFCB50F0C97730EF8F5484EE7DD8A383F -:10D9300057564C2E8C73D57FF7D6484E67D3D5B546 -:10D940002AC6BFF4BCCD48EF967407EBDB6729E02D -:10D95000F919E3709DCCE4CF8841FD797339BE5F3E -:10D960007DD04970A92B599B87FB583759F9D8921C -:10D9700017B26FEA1ACE919E3E457DAE09DF3F7326 -:10D9800098BBC6AFE9F4AA68AF84FC97C105489775 -:10D9900017B383E4BC3B1AFD844F1F35EEA3F2ADF1 -:10D9A0006BFF5E8C7A46B03110D17F79A5FE02E91B -:10D9B00027907E03C907FE754FF910C4CB74C917B1 -:10D9C000ACCA30E40BCCC84BC92FB333FAF0D7D173 -:10D9D000191796ABDAF6EF98BF5E2A9E572772B9F1 -:10D9E000A8C76F3D5E4B7C86CF8A1518F776D0F7B7 -:10D9F00050AECE65DEDC6AE0B373966E328D57AE04 -:10DA00001CAF57D83E4D6211F2542E9F9F3B79BCFC -:10DA100064B94AF6818C5790FBB03843F81943FB40 -:10DA200056957161B9A86DFFDEF5F84F175C995CEA -:10DA3000639AFC86B57DF1F5BE8BE0EB7DDF27BEFA -:10DA400086E5CF2C500DA17C118C27463DAEDBC75F -:10DA5000F32197256F8AA1E0CC929E18D41B97B72B -:10DA6000AB8487CCE8360E057C5D2AF0B593F9DFF0 -:10DA7000457C5C3A6129E5D12D7B2C725C71AD78D7 -:10DA80007F85ADC58CEB5CB15DFB5EAD882BAE7E5A -:10DA90004EEB17AD9D70FD31ECB75617CFF36C868A -:10DAA000881F2E60053CEE42AB9FEACBAE46A6F146 -:10DAB00057769D6F247FC00BBF3DF94BEF8430FB41 -:10DAC000BF2FDEB65F046FDBFF6FE2AD6ADF4E791A -:10DAD00055978BB73F1AE53E80F396FC781EF226E9 -:10DAE0001877DECB169F17CF478B9DDCBFA9F89A1E -:10DAF000F0BCADFB2B46FEA3C5C2CFD95F5EBA8C8E -:10DB000037187BD0D7C4E30DDC2AE6898ED957516C -:10DB10008EC715856FD4933ED2EFB995CCAF12F175 -:10DB20004397CAD7A45F6FCCF17AD2B35C0107E9FF -:10DB300043E3BE6C7E1DE5E3B7E5EF96F270FC2093 -:10DB4000EEBF280A56909ED765F217BF877AC24B60 -:10DB50005111F5047326D78B667A179978BE619FA9 -:10DB6000F34073269E070AFE6FB0BA4D08A7296AD4 -:10DB7000E7AF6E45FC09A8E4DF5BF3D377FEF0A8BE -:10DB8000F3E2767F9DE32CE90DFDE9FF75069E7FAC -:10DB90005150EEA4383FB4A7D0BF27FD7DFAF78BD4 -:10DBA0004695256692FF6942C08DF3D9C2E7D3DF5F -:10DBB000FED4357CAEF12FF6377E5D7BB1637118F4 -:10DBC0001DDC96A948BBC371D41ADADF4BC5838923 -:10DBD0003D7334FACFFFEB76C57415544B909FB963 -:10DBE0008A8FEBAF8CEBB1F35880CA05AC874A0F34 -:10DBF000E3F1F78B998BCA3B451EF3DE2CCFCD9911 -:10DC0000781E61EA194CF1932F7E9D837873FADABE -:10DC1000F19B30D6EEBBD2E3BAF39D347EF7EEAF84 -:10DC200093300EE6627C614DA2DB9319E1FCF91F93 -:10DC3000A52A9DB7B0C38F929CA814B730B0C9FC79 -:10DC40001CED0B6732E143882F0ED92AF9229ECFB3 -:10DC5000E67E6CE0F124CB155F3ABCDA1A34106929 -:10DC6000E52E49F6A9586FE1EDB935B13E05EAB99F -:10DC700063A378FB5DB13EF4A3CF6741A2C78540A3 -:10DC8000A2582E629CEFDDC1DC3CDF81F5A4A01E12 -:10DC9000B6A4CDCAE3FD59300DF97B5E3FF64F5B6C -:10DCA00026E7D3A353383F1F5DA6F553DC2BF8C0FE -:10DCB000275965FF447A3A96E96EC272745C60E354 -:10DCC0002F8BC86FCFD07E3836F6C774DE28BF1BC7 -:10DCD00030AA6C03C26FA7C2E3D3BDED168A8F8052 -:10DCE0002F065784C5F5EFCD2AFF19F6F72BE1F77C -:10DCF000EB0FAEF09D266F36444F5E9ADF68B4B9E5 -:10DD0000C8FF0E0F4A685CAA3FF5F4B459EB72C81D -:10DD1000C7EF45BD77C028CFFFC2798D363366C3C4 -:10DD2000F93F6EF16D23FDB43E09FD954B9FB01890 -:10DD3000506F781FC42DE6A17CD868A5F29F6007BC -:10DD400063F92FB083B1FC18EC602C3F013B18CB7A -:10DD5000255FE683B060AC2CCBDD9A591C3A9FD38B -:10DD6000CFF77901CFDEF1DBCD34FE27591E826F6C -:10DD7000EF7EBFC47C78A8B333B6E7AAB80BE05BEC -:10DD8000FF7C86C3459E17EADB7F2BF63DAFC54877 -:10DD9000F23DAF35185315F6DEDE4C33B5E7EEFE37 -:10DDA00094F250BB1CBDF0752BB0E4E9065EDFFBBE -:10DDB000F46282EF2759EE7F225C81BEFF86655EAA -:10DDC000EB3BBFC0FC1FE89FE20EBA959E5F931D20 -:10DDD000A05B871E0E725D3B63031BF1FB9DBB5373 -:10DDE0007025C06F18A71BC42325D27AD7D27C6FA9 -:10DDF000B1F414615ECB2DDFA811E38C3FC92A2555 -:10DE000038FF18F12D210C4E62BFAE94AE7BCFBF10 -:10DE1000059E32797F07F24E27CAA1F331A8EF554C -:10DE20008AF3FDD696B4B7707DDE7D2A4B7712FE5D -:10DE30006AE8CE91C5F14496B9EDE60ADCA79DEDFE -:10DE400047D3EEB4D1BEA42DC171B3D235FEC7DC29 -:10DE5000B15FFDD72FE3E97D070E751BDB3A05E3C4 -:10DE60004FE65A5FFD0B2E69BEE3E329187FB230FF -:10DE700051D98BE52267F275187722E3E3EFC82CBE -:10DE8000DD8BA434CD55497A5A2932973079506EBA -:10DE90008DC643C1DEFA14C7204DFDFAC4619AF75E -:10DEA000A73A5335ED3765666BDAE5B8D35C859AEA -:10DEB000F746C7F5A4A07D06EB207A603B548AD3D1 -:10DEC000CBDD7DF0C66CA84F7F6AB60BD5929DA2C4 -:10DED0007DFAAE721FEE4737C0D30C0AD4F1920719 -:10DEE0007EFD4BEC4CA7FF57B73FB9D7EDBC0CFDFF -:10DEF000BF1FBD5FF2D9956DD662E4B3976A07E89C -:10DF0000F7272F4B6B17F48737BD74A13839DEEC38 -:10DF100057D98E08788311A91C0F7939FD00CF1FBE -:10DF2000BB5C7EF619F2B34121FAE82D757EB9D1BA -:10DF300066D75BABD14FFFA6CA281F4FE4F555E16A -:10DF4000DF6A08DFD99D5BEF1B1A4FCFBDA8E762E0 -:10DF50007EA91BFAAFCA12FEEFEA57EF1B5A146AEA -:10DF6000676B3ED6BCCFEE51D66BEAEB92B5F507A8 -:10DF70004BD7877FDF1F5FACDAB2C8ECA1FC4FC57F -:10DF8000ED8BC01FE47CA6BC1645717D3763BC0ACF -:10DF90003CAA2D7ADB88E7B437F7234725FFB94D34 -:10DFA00065F591DAEF12FD4E7B2D8AE2602EB7DF28 -:10DFB000F701961467F8472E47DF1F183086EFFBEE -:10DFC0003D595C0F3D5DBCF9A75FE0F9E84B8CE281 -:10DFD0003E4FC772FE9FD772CC608072F4008E2FC6 -:10DFE000798EA001E54AF7B2682FC6F5D72DB75351 -:10DFF0003CE8E8949E77ADB0F5EB9ED9FBB015F602 -:10E00000ED034C820C93ABDD681441FDA1ACBDB3B4 -:10E01000D6C1DF37BD16E5375CC17A1EC2730994DD -:10E0200083659CCE1720DE08F9823EF6BAFB58AF16 -:10E03000BC41BE80EBC7FA9E67F61F7C18F5F0FD69 -:10E040009CCE31C24E6FDFCF0DB3EFD9639C2EADA6 -:10E05000F0CBE39474F4BD6793D976413A6FA6B8D8 -:10E060009B4BA5EFA7919EB32F48CF076E82FDA9CA -:10E070007B89DF6B71A62D9DF262FB93E7755B5484 -:10E08000A24359EF6A536F40BCD5E7A14BB832B7F2 -:10E090008BE853DE1BB56AE27F66A0DC5CD56EE4DC -:10E0A0004122FD8DB34165CEB07176BE625946798D -:10E0B0006E62FEDD525EB7FF3BAE3487976B23C8BE -:10E0C0003D90D3A67894D3950AD99587DA87942181 -:10E0D0009C0E29CCEFA4BC2D1EA73C937787CF6D57 -:10E0E000745F496226C5274BFB52DA95B3DB67A7FD -:10E0F000A35EF96ECBE243B073ECC3AC541AEF5697 -:10E10000E6253DF8506CC508F44B4C17F1018762C9 -:10E110007B3A912F1F9A18ADE0793FF4BF0EFB9721 -:10E12000EB3A64AA18C1EF9F9071C9A3AEE89EB8FC -:10E1300029EA3DA537E1F9F63CE640BBF21695EB3E -:10E14000B9ECCF9C3E25DFAB53027138CFBD5933BC -:10E150004E67C177431A7E26FCAA026E461E877858 -:10E16000A97A6EAF3DFBB4C2EF457171FDBF76C2B7 -:10E17000A95FDD8A797260772B309FC5ADAFD2BDC4 -:10E180003F7A3BBBD7DEF93FF4A7F6B5972A2CA31D -:10E19000C2FCE47ABBA9574F97FADE0E1E27FFFA9E -:10E1A000C4DF74AD84FA9A1DD104C7134F58BCC89C -:10E1B000C74F6CB390FD7322AEA76335D677E5BA2F -:10E1C000BC349A4B732FDA5283F33D943FEC6F26A5 -:10E1D000BAD7E3D8E3163FC67B2C7F326B1BDA53EA -:10E1E000C746389F7D0EFD81CF26D03D03CCC3BFEF -:10E1F000BF59D023D29713540FF5B776D22396BFC9 -:10E200003094F898DCBFE38F47511EFD897D3307BA -:10E21000A2BFACD3F03CE5F130D5E6457EBC725BE5 -:10E2200014E9810D0E4FD628585FF96F6FBEB510F7 -:10E23000C77F2781E17ABADB5E207F65687F23CBC9 -:10E24000F7336DA99C0FF4CA5B1E77BB10E36E53C6 -:10E2500029EE7634C2B786C97B1779DC6D81AAB8FE -:10E2600029EFE0A1C879E4EE515C7FAC96FE9341C2 -:10E27000CC9A8874E861B4DEEE8732B6A1BD33670C -:10E28000545CEFFD4C3C5F52E25B47EDCBE43FB1A9 -:10E29000F078BFA8C8E7D8D346F1BCE22AEB398DA5 -:10E2A000FFA6B6E12B8D5FA5368791DC2D6872162F -:10E2B000DE05E56A01E7E52915B7E0FA56346F7E19 -:10E2C000F10D82CB633FFA00C7DD6723BF0D7B836F -:10E2D000C34F6FCF54593F17F4B45573CFCCD147C8 -:10E2E000DEA37893A3BBB3F370DF16AB81A3781FD3 -:10E2F00057973DF0D1DD50EEDA7780F6453FDF3EAF -:10E30000E7F60AE72BD5B88E4118EF52B16414D165 -:10E310002DA7F7231B73097ED29FDB7D22B2BD257B -:10E32000E729FB97F393FDCBF7568BFD3A6D0EE48F -:10E33000A17C4ECC746AD6753A2690176BC3E7DC85 -:10E340009F773A0EEA6178F35D9DEFDC2EFC3C8707 -:10E350000D6B7F6806FCEB6CFEA5C913CE472FF34F -:10E360005C47CE57C695CA3CDA874789F388116C5B -:10E37000443FF9B75B90CEAAFBE6DFD2F3FEF26F23 -:10E380007BF36DFFCDF36D657E6D51B9A13E3CCF42 -:10E3900056F2C3A26C789E83E7FE5AF95E345AFBAC -:10E3A0007E7FFCB1209BDBD7458322E7BBEE1FC5F8 -:10E3B000DB9B989FDF3F28E4E278017779EF97D4E1 -:10E3C000536A05DF96799EE3DB78DCE67891B70344 -:10E3D0005C80F25CFBDCEF96984D7255DECFA74077 -:10E3E0005FF3E222E50B07681ED7B21E2ADDCC617F -:10E3F000C412C04FE5645641E575AC9ECA1BD826D1 -:10E400002A6F64CD544E63012AD928BF88F7BC8790 -:10E41000E7994E5D6A40F95A746B64BDF8D445E1E2 -:10E42000E0A5FB032F170ED7317ECF5F1F780CCFEF -:10E4300024FCD6C3439FAF399105E9E2924988B8DD -:10E44000A968073B29BEB59CB9A93EE512E1501267 -:10E45000F418797EAF0E1EE591F1E29CA0FF9FA219 -:10E46000EC2C0EED5356B693DFDF20F60B0CB144C7 -:10E47000E4FFFA7D94CF8BA2CBCE3A8145389E6DD6 -:10E480009C4D79DC8565AB53A19E92BD6936E579DB -:10E490008F2F7B01F3BCD39EDDCCEBA3CB0A4D2E9B -:10E4A000D022D7FE6236E6337A44DCB447C44B331D -:10E4B0004FBEE69E2CCFDA1FD2BD639E113617AE3B -:10E4C00053E685ABA9FC7C35E906FF6B2678AFDD0A -:10E4D000E189CE46B965F5C738514F583B85EE8F77 -:10E4E000BADFCCDF97F7D9C8F5C97B6E76EDCA5E87 -:10E4F000ADA45C7C1ED0FF50ECDFB3369DF2E33C54 -:10E50000BB15910F5736640EF08DCE8089617E81E8 -:10E510001CCF94E249C2F71926C5035D0C1372B8EB -:10E5200073577636EE5356B638DF8F4F2E4438DEAB -:10E530009A529185EFCBBCE82CDC9784FECBCA6C59 -:10E540007706BEAF7F2EF3B2C7657B72B1BD2EFAE0 -:10E550003CE59B75E5BFB33E98DC374FBDC9CD7C2C -:10E5600066E22BDAFCF4EE2566BACFA9A8C2D38402 -:10E5700021CAD7CCEB1983FA31F45B929D80F7095D -:10E580000693F2E1BB8767F2FC777DBE77FB2BFB3E -:10E5900035F9ED92CE7AF3DBCFF0FCF6107D3DB28B -:10E5A0009A85E5B74BBA9174370EF3DB63B09EB52D -:10E5B00004DF9BF84E07E5B74FEA088AFCF6F7B48C -:10E5C000F9EDEEFF5C517EFB3171EFDB312BBF2F9C -:10E5D00049DE27B56A373FFF5DA5F0FBA456FD9ED7 -:10E5E000DF2725EDC265627D35FB77ACC773BE655D -:10E5F0008FDD41F75131710FAA137EC3ED42792FA0 -:10E60000A93E0FA60EED41D29BFDA477E9F361EA86 -:10E610001E2B277BB04EA747AFC816F6A090674CBD -:10E62000E87F4BC5B7B80E1BD96766D23B573DBED6 -:10E63000DAE5C0BAA02BF6D87374EE26DF678F0D2B -:10E64000225C9074B67C8342FAAB84DFE8A72C6E20 -:10E65000BAC7F8A921A4B782BE2DF2987DDCCF0FEE -:10E66000B882F1F03B637B52504FDED99EE9020E37 -:10E67000CBFED4EFFDD3CFE9EE9F7E5273FFF419AA -:10E68000FC1FEA69C70D3EEC670CCBFCF904A81728 -:10E690001F37BA7CCED07DCC17BB7758C2DF22F6AD -:10E6A000EB72EF21D6DFF72CF31FF4F711DF2FEE1B -:10E6B000239ED8CF7DC416B54D25FDE19C51732F07 -:10E6C000F135629D254EE6C37B7EC7751A35FB5F2B -:10E6D00012DCC4501F8A3A68D4F8112C4E6DFD39F3 -:10E6E000890FE27E91BEF0B6F5C2D342F04CFB0D2D -:10E6F000C15377CFB38453EF3DCFC36D84F7E3F6B7 -:10E70000BFA0223FB8DCFBBEBFEFFBBD2F769FB79B -:10E71000FE9E6EFDBDDCFDDDF32DF73DDFBF4AF350 -:10E72000BE7EDF0BF7FD447B0FB5D86F2FFC7E9BC1 -:10E73000FB7D325BF877C57EF7E00568C0CFFE1140 -:10E7400073FC4124CBE9D1E23E3869D74F30919D2B -:10E75000F5967350B91DE95FC8A90A21A75845333A -:10E76000AF0B7C7105781C41C1617E7F455190C71C -:10E77000138C391E393FE896124573BEDBF7DE6213 -:10E780009E673CFE3C8FD3D39FFBCBBCA14A7794C2 -:10E79000F6FE867EF288A41F07F47866463DDEC04A -:10E7A000EFB38B70CFF11635353C8FC843FE9D59C2 -:10E7B000D64012E27354B2273E2721946F3409F3F6 -:10E7C0008A14B20785501AF8038CF3ECC624DBAB2D -:10E7D000307FD4F603CC9381E93B8263B8B98B3F99 -:10E7E000C9399E1139C0078F288EF585F0ED3FC6D7 -:10E7F0009D4A42F964C173ED023AF7BD3A27FCDC49 -:10E8000057DCCF1F343849BFF0FE4421FBE11476BA -:10E8100036368C5E3798445EA3EEDF2F10F694FCFC -:10E82000F70B8E4017CB806FCF6FE579D42B133B5E -:10E83000851DC6EF71BD63B88DEE7F62EE4217B7DE -:10E84000C3A57D354CBD1CB979B1F8A29589273493 -:10E85000762E7B6ED0259D2786D6CDFB3FF24034A9 -:10E86000C99B230F8C203F5FA8FF2EB2FBE7D76B1D -:10E87000E38C1736BCAFC1BF45DE8F35EDC1F81E46 -:10E88000D330587FF0C5A1D7CD05F89DDE6D198333 -:10E890007406FB362B27CC0E0E3E943199EB0117F4 -:10E8A0005BE7299A4787881395EBFCA8F130D5835D -:10E8B0008D415D3C8F576397CAD2FC1AA37B727A55 -:10E8C0009401AE487E9693395C6FEF1079901D22CB -:10E8D0000FB243E42D76883CC50E91A728F3473B41 -:10E8E00014E6C6788A798AFB8945C9943F7A17AEBF -:10E8F000B36E454F1EE6DBD58D0E2E5054CA1F5DFC -:10E9000083CF23E48FE661DEFB1F726EFD01EAF91F -:10E91000C70778E95E92A79E9BC1EB664E1F2FE664 -:10E920004CFC01CF27F5FC0FECE75345F5D3FD1761 -:10E930002F29749ECADC41F38C0BE497DE97C3CF7A -:10E9400017D6EB4AF2452760FF4CE47B3D3892F244 -:10E950007EB65828EF07C6A1FC2B79FEAFCFCF2A91 -:10E96000F8B3C58F7C43FA611EC94996F702937FBD -:10E9700025FEE7169EB7150C24619E17C6FBE0BD69 -:10E9800019EC2073F33C307E7F9FDC87477244DCB8 -:10E99000195EA45F14CA13ABD97FE423E42365395D -:10E9A0009EC771FD327FA926E6558A9BD899E3A4BC -:10E9B000EF60BEB45EE007EB1482731F3FDC0EFC19 -:10E9C0005E9FFFDEDFFA4F2F09FC3A2739943F158F -:10E9D0009637B53327CC5F26E711EAE7C2782DFDDD -:10E9E00049217FD7FD23914E0AD00F1EC1CEDE2BC9 -:10E9F000E0D2618AECBFFB384789983F5790C11835 -:10EA0000FA0BE57D93EF209CD0EF749B8BFB4119B3 -:10EA1000BFB7AE6686CD857C4BF68FF7E53E7F812E -:10EA20007196A754BC89EB5F51CFFD7DB2BD5BE110 -:10EA3000FBEA7D88E34BCD2BEF7F74378CB2FCB7BC -:10EA4000B985C8A7E5F77A3877D979FEDE62D54F60 -:10EA50007004F87E80FBA4F7F35D295C2F377F1AE2 -:10EA6000E045F730F6F583032285E96F16F9FD706E -:10EA7000EDFD6616FC771860BC1661F7B408BBA7FD -:10EA8000D524FE9D1C9D1DDC12E071442D89668AF3 -:10EA90001362E2DF7590727FCDDB3CAE684D32A32E -:10EAA000769C1FEEAF12DC4B72A8F79E2A05E42B72 -:10EAB000C0EF94C3A3E6A21FDAB39AE4927A35ECCE -:10EAC0002FFA4DFF76A3B0E7B89C2B1672AD18FB5A -:10EAD000C175E40C24795724C61D63AD277D7A2CBB -:10EAE000F30AFF8EF0833CB097ECC0FF0D9F4D61A1 -:10EAF00077606800000000000000000000000000D7 -:10EB00001F8B080000000000000BFB51CFC0F0037A -:10EB10008AF92C181856593130DCB0666070B4612F -:10EB200060D86C8E90BB218E6053133F97A74CFF2B -:10EB30003C4906860540BC0888974892AEFFB71648 -:10EB4000825DACCAC0F007C87701D25FD519186ED4 -:10EB500003D97F81B803C85F03C43B805804C8BF92 -:10EB600009A499D518189E00E97F40BE34907D44D1 -:10EB70000DBBF9FFB5F0DBBF5D0395FF128D7F4143 -:10EB80001DBFFE284DFCF2AF09C863C35EF6E4C7A3 -:10EB9000471F057A0702AF474BD7E2A60C0C7A66EF -:10EBA0000C0C85D0B4BF0649BE192826610A617FC6 -:10EBB000D103E617207F258E7CF11528CF0F94EF27 -:10EBC00037C76FBF38335A7AE1C154F39609C1AEE3 -:10EBD000174295DB248CA9FEA708030300E92850FF -:10EBE00078D80300000000000000000000000000D2 -:10EBF0001F8B080000000000000BE57D0F7454D54A -:10EC0000B5F7B973EFDC9924772693106042024E72 -:10EC100012D458038C18302613B821098424E0003C -:10EC20007E34565A07E421B640A3B5ADEDF395E125 -:10EC30008F315AACD0F2FAD4767DDF40D5D5F6B913 -:10EC4000DE0A8A4A43422790502488112DD66AFB57 -:10EC5000A276D9F81AED80C1C6EFA38FEFEC7DCE76 -:10EC6000C9CC3D994942F5AD7E7F64B537F7DE7377 -:10EC7000CFD9679FBDF7F9ED7DF63963B7B988E75E -:10EC80000A422EC17F0B09F95C2E21645EFC2A9E8C -:10EC90002F729270C61C42B29C077A67E710B2D8F6 -:10ECA00050FD4B7C844C75AEED26A5840488C3E7EB -:10ECB0005008E9525EE89D4DEF8FBBEC7E0781FF67 -:10ECC000EE22643E21773BE99FB4FCF173F40AEF36 -:10ECD0003FB145082D5FAB361205BE772A7E870F00 -:10ECE000CA9BC6B22984D410F6DF8273A446A1CF92 -:10ECF0006BBC773492D984547B68AD4EF6EE12FE2D -:10ED0000BF49082D5F4158FDA6D3FABE82EC3AA751 -:10ED1000BAE12EA60667D1FA2EEAD6F7DE257F24C1 -:10ED20006E2897F0BC80F603FEA03CB88AB872DE6D -:10ED3000CBA07FDF406EB8A4D2AB3689901BE37CBA -:10ED400091AF848409994C483BFF5E23C1D9704F31 -:10ED5000C833D87EB6E0635D3FF1D27EE79411FF01 -:10ED600012CA87A9756617A17CADA8D1191F6BE7D8 -:10ED7000E7F61B84FCE083B63C52423F8F6C423E78 -:10ED8000E6703E767DF0FC9B5B806F7504F976D86B -:10ED9000EECF0D968CA62750979D46683D7B824707 -:10EDA00033B01E42FEF3D2145E4F11211DC1C2CCFE -:10EDB0005092EFC4F591AD1E421CF1FBDD26A96B0C -:10EDC0003346977B1E06731E54BF06E9ACE0BCFCBD -:10EDD00081429ADAB0DD261CA7C39CFE6EF368461A -:10EDE0007F09BC8F66D8683FC2E76CE4495A45C7C3 -:10EDF000E0A274A077BB698BC2F38E413D02FC2078 -:10EE0000DEB6BC15B346D37FF8DCBAB9D8AFD0268E -:10EE10004BBBDF1FA4FD35A07FCF642CA6F59C1F44 -:10EE2000B479543AAE7BF8F3C3A1B60C0F7C37909B -:10EE30008DE3F9C856FAF7D5A9F9F1C8822F1786DC -:10EE40000C28E7B4F263F0FC89223A6E1D7B353F53 -:10EE5000F46B3C7E7E9FB723EEB3FDD16A0FAD37D6 -:10EE600010F32BA017D983844C2A00BDE838E6861E -:10EE7000F16D24A84781E0A2B42B593FFCAA0FDE14 -:10EE80009F52413E029E28F663841EA0EF6AA0D3E3 -:10EE90008BD747797B3F8471C4FE6D4FBB8AD27B91 -:10EEA000BE4CC37AF69BDBAB34ACEF62540579DC25 -:10EEB000C4E429C717DA6607FEAF27FEB00FEA25BC -:10EEC000D8EFFFCEFBFF635E9F68A76330BB4A03AA -:10EED000FA9A881FD4A456BDAF0BBE0F6C64F4CF52 -:10EEE000B8B75901FE5D715F3F5E239CCEDDF03DFA -:10EEF0002D90DF1C53806FD3EF89E275EFB6B7BA60 -:10EF000080BECC9D240D6CC19E1A5B167CB767F148 -:10EF1000B43478EF0E52C5A7F620E0F7DCD54DFBF0 -:10EF2000B3B746433AF70E52FED372EEB0C70F7A2C -:10EF3000ED0EFBF8D5EF87F2BFE4FC38CCDBEDE457 -:10EF400074B8C3262FD75C02E5DCE1305E23BC9F9A -:10EF5000C4B719E5EE6E2E77BFB4873E077CCF1994 -:10EF6000245E42F5F9F087F5B9D0AEA85F2EFFD444 -:10EF7000E3FFF37A783F7990BC6D9F0DD7E85A682C -:10EF8000EF6AE8871BEEFBD62A68A722A847E6456A -:10EF90001B21C5713B95331C5C7A13DAC75AD42305 -:10EFA00061072A06759B9299A86735A8077BB91E49 -:10EFB000D40C46514EA89E1DB3513E853FA07A46C3 -:10EFC000E5EB70D086E3FD444C473B4C8AA3792B9C -:10EFD0005CA3F5A8E3DC86B9C06FA14FA3EDC7FF22 -:10EFE0001BFAB597F62394C4AE89F684BEC9EFC761 -:10EFF000D5374F18F5AD83EA5B18F819B4A5CD04E1 -:10F00000FD6BB5A19E786BDABA98BE6C427DCB5988 -:10F01000CFE899BA26827A309EDEEDF579AA34A837 -:10F02000BF89E969C7E03BDB1C301E6B08B71317CB -:10F03000BBE03E702FD36B59CF643DCC0CF4A17E66 -:10F0400016EC8C11B8FA7634A25CD356D250FF522B -:10F05000E86107E861E9FF3F7A5823E671CA982C16 -:10F06000CAFFFA186178C8B30FF150AD8FE3A182DF -:10F07000D76FFD2A7DFFA23D03C7F5C5C9F421DE88 -:10F08000AB110238E3CA7F5973372D5F9F23F0CF4E -:10F0900046D4EF3AAEDFC7E011D59FAA7E85CCCF2C -:10F0A0008672EFEEAEA6E54F0E103FBC3AE9531163 -:10F0B0004F750F12AC4FE8671DEF6F37BC07791B18 -:10F0C0002611D04F81236AB97E9FCC61EFBB2F12EE -:10F0D000B403A2FC49A244547A7F9CCBDFF9E2DB63 -:10F0E000FF87BB90903F6F8BCD8ED2E7FF6E8B7DFD -:10F0F000DD468BFE7E99EF69B81FE0E5FE83CBE924 -:10F1000020C70D27AE0DDDA450FC5349621BEE86CF -:10F11000EFBC458FCC2550DF47330865ED57AFFE78 -:10F12000CB7BA4102869D383AEB85E89FA443D2F07 -:10F1300078434D0A1D8F81C8BB6E18BF0F0E7E34F9 -:10F140001BAEC49884386B3C3C1610E315EBDB0116 -:10F15000B883D450B9981F978BA9B1BE63886387D1 -:10F1600018FE22759B711C2A3D8C4F5D17CEE6C19F -:10F170007747385D9DE7FAF2D01ED659EBE9B4F730 -:10F18000AF09B2FAF1FB80878DA3A0A75DD8074530 -:10F19000E025365E01FE7DB9D637690EE57FF909B7 -:10F1A000D5BF8D7E573EDC5F4392D89D889285FD0A -:10F1B000AA18B0CA67E785E32AF085D2AB02BD95ED -:10F1C000B13E95D96D2657012E5795B133167B2E3A -:10F1D000DAEF8C9D699803F66380D9A7547CEDE63D -:10F1E000FD38CAC7FB88D04F12C900FA7B28FD0F33 -:10F1F0008DF17DAD47B5D02DF4ADDA9961C1E70B46 -:10F2000087B325BC6FA5778116457E2D007E91D4EE -:10F21000FCFAB6928DF52F1CFEDBF825DB11516F41 -:10F2200027F0B164345D04845BD0ADFE9FCFD74E30 -:10F230006E67A8BFD20DFA4AFA0FA8A08FB5AA81AF -:10F24000F6A5E26625E248B02FA29F0BB95E4DBD40 -:10F2500048D06E980304CB1D8E31FB9F8ACEA35BF2 -:10F260004DEC5FD645DF4E98571719C17CD09BAE49 -:10F27000C97F647AA69C43FD322FBED7FB55CAFFD7 -:10F28000535CEF0E6FADC3EBCB5B9B912F014371D2 -:10F290005D0F54CD64FA562DEC1A9F4F4E70FB71E2 -:10F2A0009CCF33AF6E0DE1F357B66EE47C65FD592C -:10F2B000C4FB1335AA0D18CF6E6711CEFB0B355367 -:10F2C0004BE65755C4AC7274CC47F18E0178EBA86D -:10F2D000713DCCC7D43F46BCC2EB19F92E5F6953D0 -:10F2E000E6C4EFCF0A5CC4CBFDCAFF2CF3EB6ECEB5 -:10F2F000C0F9A02216AA05BED63629C4097C9D3EB7 -:10F30000AB318B3EFF7C93759C457D3D39EF4E02C2 -:10F31000BE5704825A905E6BA3B7683E57EA71E805 -:10F32000D1828DD7E1F832FDA988F5D798948E2542 -:10F330009E8246F44787351BD8C3463ACFF5A35E75 -:10F340007890CF62FE3895A3D64500EF0DEECF0042 -:10F35000FABB3DEA64B86E87C981CA51ED458A4F50 -:10F36000E78CD1FEB046794E2BD2A2CC5FA3F5C07C -:10F37000B5C750F9F3208E470FAD179E77FDF5877F -:10F380008D737300F7ABC89F00F9DAA9EB60FEF24A -:10F39000DB91DF426F851C741B6C7EEC8959E7475B -:10F3A000C4B7F455CFE0F76F5E09F323B1235E12C3 -:10F3B000F8577C7FC4B87DEF0AD03BA2FA0919FD4B -:10F3C0007DF066D5A247E57EAB9ED5974EB2DCF7C1 -:10F3D0000CAEFBF15DD05E2C9DB517DE64A1F78805 -:10F3E000C1E6DF9E08C30762BE16EF0344D66FB9BD -:10F3F0003F8B4EF9C1CE50F9043B53FD49A951430F -:10F40000EBABC9513DA097C73CDBCE82BE7C10F868 -:10F41000F53760DEAD2BB1D2DF3138977DEF5591F6 -:10F42000BEF69CEBF1FEB0D72EFA6F2C037AE02FDC -:10F43000FAFE08E97F7536AD7755C44AD78A6086EB -:10F44000E57E73DD24896E6B5CA8FAE2068CEF2CF6 -:10F450002AEDDA914DEFCBC11415419CC961F92E0B -:10F46000E0B4DE97437C877EB78048CF2F2EC6B8A6 -:10F470004E39C475C473E0A764C7E93DD221E6796B -:10F48000593EC57C9D4A7EDB6D6423C443C8D0CA07 -:10F4900071E242DB93CEF744DBABC0F897739CD0AC -:10F4A0006E6FCB80E795E798FD2443D949F18D3CF9 -:10F4B000EF13F2359423C14FE209939CF9C8C7A416 -:10F4C000FD127C69A5C37209F00EC749F87112FDDF -:10F4D00096BF9F02FA4DFBB3B8E9408687CA5775BD -:10F4E000CC86F2D561EC41FD6CF7AB5C1FFB2F25A0 -:10F4F000CA674353D529880FD2F204F4B7C3B80BB7 -:10F50000F537781DD35FAADFA88F01AA8F897858B5 -:10F51000C8BF2CEF03247CF67A68977CF4DA2AC003 -:10F52000C10759BBB2DE53BD433D3E4FD4547A8E22 -:10F530007AD943F532593B97AFE73613DA3F7FD09C -:10F54000C570F7283D7FB56612B4E754587B9FB16C -:10F550009E1FE1FA23CBF7687D5F6480FD3F6FC893 -:10F56000FACEECDD62D7BBAFCE66C52D7AFF59E986 -:10F570007BA0789F0A5049E8F178FAFEB7EA794A09 -:10F58000FD9DA07ECBCFB7D814A62F29F433AEF7BC -:10F59000612CB7C3458A213ED6AEA4FBB717809E27 -:10F5A000B3788D5C3E5DE5F51267F80FB43F6BA94B -:10F5B00053964959BD99F4CF808156737DA8775BE6 -:10F5C0006CFD53E0FECF2436E55A15FC067208E2C6 -:10F5D000408A49C8BD9424C5E7216BA8A3D5A2865B -:10F5E0002ED968796520FA890203790FF101AEBB43 -:10F5F0005A09D954FADC41F963D0F2443B83788F3D -:10F6000022201CA7E55C09963B8D28C6CFCBEC8356 -:10F61000FD426ED05F5BE379EF5A5A2F892A97AE8D -:10F620008DF7F3297B24CF6F403F233FDA02F1A609 -:10F63000C774FF93BED1FDFCC426FC9FCBEBE7272C -:10F640005456909F36C6CFB02DDD0FF12CB97E53A6 -:10F65000BDECFACFA6D36B05F071CE683E2A839439 -:10F660007FC007ED3F2F81BF57E16572A5FE593777 -:10F6700021BE425467E4CA2474ACE774B4A8E66CB3 -:10F68000E0B75ADD86FC390CE36F00FF72C8371211 -:10F69000E4AB52D5B17F6A0369C67985446D6037A2 -:10F6A000C61B0FBB463415C6B1EF12DADB164E9FF0 -:10F6B000833E37E6A61E2FB5C11F8BD271227F660F -:10F6C000E37478A9552EBFC6E9FF32D0358F992152 -:10F6D000A8BFDCCBEC90FA27BD3992448E7708FEA8 -:10F6E000737EC9E50FDFC2FA2FCA7F87CBFD372FA4 -:10F6F0005FFE574F2D4A3D6E42DE95C1E3A9C6AF6E -:10F7000039D9FC364BB5713AC2CA44F4A15265727C -:10F71000A956D37183FED55AF9F86DCE8F55BCDE4C -:10F720002F2A6633C8C3D54AF06E15DAA9E943FD1E -:10F730002B847AE8F36B89790F3CA7EFBF01E5488A -:10F740009DF53D7DFE2D7CDED487EB4AE279976204 -:10F75000FE23FFEE9FB05ED3FA9ECAE156784EE5D7 -:10F7600085A873E1B90FE9A172429C602FF6DDFE16 -:10F7700005E02BFDFE7EAC9F9CB17C6F070391CD15 -:10F78000AECA5C767D1CE48EFB993B9A4CE4AB4E92 -:10F790009AB91FCCE6AD057CDE728202C33CECD187 -:10F7A000715ED4D2CC48945EB33D5113E278934855 -:10F7B0005F18FCA8D5D27CDBB4C63ABF7C61BD75AE -:10F7C0007E59B329CF72FFA57B8A2CF7A1FBAEB57A -:10F7D000D4B76EE7F596FBF5BB2A2CF71BF6565B04 -:10F7E000BEDFF8E306CBFB2F3FB1CA72BFE9E95B8E -:10F7F00093AE4B8AF9EE41DBDB9BC01FDB01AF12FE -:10F80000E60B2DBEEE686338CCFA1D153F9F361F00 -:10F81000CA110C29C872AA49EB96AF8FE8CFDD96C2 -:10F82000F9F668B820C74B596A166806C6DBC26687 -:10F83000DFCC29F1F9BCDA47E76337F8E1C9D757DC -:10F84000355EAE8AF457C3B8999AB59CC6D7590DA0 -:10F850007F0CE329F23AABE663F3B44CEF19D5958C -:10F86000037689D6EDC3F555237B42EBABE3F68FE8 -:10F870005AC209F58FB75705FD2C4ADDAF05A531F2 -:10F8800015C89B68BFE2745A718F58DF5EC68A92B2 -:10F89000F282273280DE653E86874829C3374EFADA -:10F8A0008FCDB38CFF0DBC7CF01E8F1DE2C8C11A3A -:10F8B0002B9D0D1C3F513DD4C04E94174BEF81CE74 -:10F8C000D950CE8A93BAB93CAA1A5FE79E4FE6E3B5 -:10F8D0003870BD5D21F4B696C5278827F9FA77FD03 -:10F8E000302D84819888256FE06471513A7CB7ACE3 -:10F8F00095F81C149F3C386F9B6711D5FF46D3EEDB -:10F90000AFA3A5ABFD2C1E5E6FAAB8CE7B4531BB65 -:10F910006FAC51224B287DF5A13E8CE735AE8F6C44 -:10F9200083EBB48D510DE990F8FAB82F926553E34B -:10F93000FCCDE3FCCA137CE57C14767CDA26EB383C -:10F9400036965AF9B59CF353E6F372CEC7E5121F0B -:10F9500045FCAC44E3F22CF17119C7A1CE794563A3 -:10F96000FA758FF33897901F4D9AD784FD1899DF59 -:10F97000B8FCB6801D079CE7E13885CF7B55331571 -:10F98000F4836ABD0AF2B776E63E4B7C73C9885CA5 -:10F99000323A6BF97897E7BF8A71CDCE1C3EEE9470 -:10F9A000AFB5F3E372D83093E563ECE4FDEEE038F5 -:10F9B000BA9DC72D5BBC67D4C4B857C78CBE7C3F0B -:10F9C000BD7FE942DF9AAF517A1AF3157F1DB41B50 -:10F9D000E271565EEFE1EBB6E5037D27CEF561DC23 -:10F9E000E7A59CA231E38802BFCBF250EE0FD6C050 -:10F9F0007CB224FA0B15FA5F1EA36C53002747351F -:10FA0000C05F8DDEBB358C73E5DFA541BCB1367FB1 -:10FA10005F35B41B20A1DD5510F7CAB1FBA33E88AA -:10FA2000FB8477BA419F4B985E6EA4FF12F552D0CB -:10FA30005D31D8AC019D4B7C92FFC2E5A8D62B3D31 -:10FA40009FB904E52820C9D13D420FAF245726CAEB -:10FA50008F8817E8E70AB91E26971F310EFFCEC719 -:10FA6000E1773C7EFC268F7FBEB1D587D75F6D2DB9 -:10FA7000C6E73D5BFD78FFFAD632BCFF358FCBBEC3 -:10FA80000A71568C930679BCB509EF7B79FC54C892 -:10FA9000E7037CBDA356EDC0F860833FE4F424ACDB -:10FAA0002B3470BA51A4015F9414255DBF75CC3816 -:10FAB00084FC3B3322FF04EDC0CAC682FD0F51BE59 -:10FAC00038BE434280171D477FA15D45E5BAA1AE10 -:10FAD000C0BE01DA0BB769D7D3FA1AA2BFD08AE049 -:10FAE00079E375F6DB93B42FDA49D5BE6CB756D5FA -:10FAF000A9921F2AD68F4261E8E7D458280AF40554 -:10FB0000BCBACF9104F777E56EF0825CB59C0B79B7 -:10FB100041AE5A72D93A032059901B9DCBA9281F98 -:10FB2000F05AD7D7754E77077D0EF476C4C65EF7C8 -:10FB3000167A20CA55686DAAC748DD3F397EB4538E -:10FB400049EE8F5ED46CF89D1BFA4FED37B5851AE0 -:10FB5000E8198828D03F958A0DE8976110B42F19CD -:10FB6000FE10B7B7D6F939AB2C18AC827239C4BFC6 -:10FB700004CC96D1EF05B951CB16BF0FF327294915 -:10FB8000B0C7E0CFC8FE7CE2BD8A262AECCA86ABAD -:10FB90005C8EF1D7E022D47A1DA3EF7B03D6F8AFB9 -:10FBA000C1F95BEE3BF11BB097DFF3DB58B91CB634 -:10FBB0004E7ABE6C1DE2AD728EF71D6437964F27EC -:10FBC0006D78DDC1F97DBEEC0C81F95BD5281ECEC8 -:10FBD000017A9C9130FDDE2DD96DCDB0F25BA13C58 -:10FBE0005903B87940B3F8114A19B3DF4EF0C3C1D5 -:10FBF0003FE1B824EEBF85C82560FE0471D24EBB3C -:10FC0000D5CF12D7DF6ACC0FB1D9A5FCB6FFEBF97F -:10FC100077FC33E59FF0FF46F0DBB13B09ACA788EA -:10FC2000FC3E51FE57521C49CF7FBBC64CC2F72A3F -:10FC30003BE3FB7576096F05E476D2C2C04F9DFAAF -:10FC40004969CAE87A52B54706E68E138FDAC6FCD0 -:10FC500044CDC3FAC7F373A8BBAD58FC0EA7E905A2 -:10FC6000BF6FD4F75E9B454F47D3CDF8F359D3BB55 -:10FC7000903A9A705D2EEC7019C3892B7C1427D2B0 -:10FC80003F57184C4E4F572991ED28A7A6C58FAA6C -:10FC90002B5BF23EDA25EA67E8F339FEA6F4B742B9 -:10FCA000BDB49E5772C57723F6C47669CEE87A82D2 -:10FCB000350CF790F0CF9726C60582545C8AE74250 -:10FCC000BDEC7B5AB4EB52323AB8DD0A96DDB5DCB6 -:10FCD00070C3BDA93C0A38AE24011F005F673AAC6F -:10FCE0007C96EC5FCD28BB67B5B78BA9FC1EA2ED57 -:10FCF000D4A9CD8D35B4FC923DEB0EBE88E408FF4F -:10FD0000C297B4DE53F0C78D80F6AC7885F8599E63 -:10FD10004575D887EB822B7214122900FAAD742C2A -:10FD2000CE97FCAB1CB91FBB711C8F6A741EA1E37C -:10FD300075948EE36EF47B93FB49C27F5B583084ED -:10FD40007E92F0E308F7E33CF45F221EABE4E5AB00 -:10FD5000EEF169B07E5025C58F2B47F28109FA4933 -:10FD60000B8995DE4AEECF554AFE9CD0F79F0ABD1F -:10FD700015FE2AB78737093FA93239BE10D70E2999 -:10FD8000BF8DE247B3ED32F4800055B4BD4632C2B8 -:10FD9000278B7C75155CD516A57CBDC99FC6F2AFB7 -:10FDA000299D9AB0E7C82786B797F3F237F974947C -:10FDB000FF804741FBDE384E3C2250C6D6555E36AA -:10FDC0001496371826AFE17A11A7A786FEEFDEB9A1 -:10FDD000D09E552EF27D7DD59939306F28FE0819B9 -:10FDE0002DAFB57C5CE1FBFBB2C14FA1BE7636AC5A -:10FDF00067C8F1883E0899527F9CFA4A05A3FDF92D -:10FE0000057C7CABFC04C47E943FBF808FEF8251A5 -:10FE1000FEBA1567BF1C7B07F3ACCE9728B82ED26D -:10FE200055F031FA09629D26CEBFE3E84F05CA3E80 -:10FE300062790323FE08AB6FB9A8AFEC18E617DEB2 -:10FE4000EF3986791CA74FB0F5EBD35ACC007F640D -:10FE5000A9C05794A35191FF5E007912ACBE28CF80 -:10FE60006778D9F96A06D84D9117D21948BE3EB7BE -:10FE70005065F16371CDD7198E2BD6D9FC23EEC511 -:10FE8000F88EC8937AAA94F97BDFB68CBB5C3F945A -:10FE90006FC2B85FB42438467E41A3C4678F6EC575 -:10FEA0001BE3E15AD14F990F723F47E98BCEE260D5 -:10FEB000ABEDE6747D72BC1D31DFC9E5573893E7C1 -:10FEC000CD549559E38E72DECC6A7BA804EAAFD696 -:10FED000949D993EB46BA84F472F1A8863CEC78E66 -:10FEE000EE8461ED196271CF4AA2F23C1AB311D6C9 -:10FEF000D3C43E871A1EA790E918AFFDCAA17EF4AD -:10FF0000B3AB866335207F3705BAD0AE2EA37675A6 -:10FF10005212BBBA581DDC3909F4D7AFA07D78F96D -:10FF2000ADBE9A494C9F313FD5AC2CD226811C786E -:10FF300092C7A116703949A577F4430D70C344F5F3 -:10FF40006EA53E82836EB85434FE38A59287F3B115 -:10FF5000F35F4B161F15D7EA14E3BB8548FCEDB0E1 -:10FF6000C695E57A449C87A81DF9A0CFC2FF95CB22 -:10FF70007D5B67F1FE9E597790FE04BF4ED803BDAE -:10FF8000ACCD80F8446FD9D8F3859CAF5645ACEB27 -:10FF9000CED54EEBBA73AB66FEA36EC1496B99BF6B -:10FFA0005AB616FDD5E5250EF457BB66DD81FEA9D0 -:10FFB000F0AB5B6E3C807117914725FC5399EEDEE8 -:10FFC000DC670C28371EDDC28FEF74B03C20F0DBFD -:10FFD0007DE8B7BF8DF94572F9430EC6AF2735F3FB -:10FFE0000740FF4EBBE95D0BEB87B31CFE27938CEC -:10FFF000C31B0EA6DFBD29D6514FC382C664EC07D2 -:020000021000EC -:10000000F2419E6F841F2BF60D4DF532BD6DE07EE3 -:100010006C45C95AD4C72C2FF55B816F7EE6B79229 -:1000200041AB9FBADCE8CB83F197E73B7588FBB522 -:1000300013F45B1F48637214F210A797BE4FD328C6 -:1000400034A5F3E82E75D173C08F07B208FA03A761 -:10005000B3F4C8FE24F18617B9BDAB553759E4ADEA -:1000600092E312BDA6DF8078C0E9A1B1F3F21E923F -:10007000707A6131A972B8E11AAB027ED07BD3816C -:10008000D718E64B7F77D686C264F5ED6FD592CE52 -:100090004B6FF1715BC9E7BBAC3A169FDC52A263B0 -:1000A000BC776ADDDBC7514E1BB99C2E7360BF7BEA -:1000B0006769382EBD3716B4C17A65EF2C27E6275D -:1000C00074CD7AE1ADBBC1AE96297CBFD9468BFC1D -:1000D00056525C9D0EF57B55C42B5BA8FF920EDF3C -:1000E0007BED0CBFF03C90CD7C4C4F1F64F8E64399 -:1000F000816F381F5709F96F14F1502B8EA2E6C497 -:10010000B24E43F8FAC312562DB5534C1F3E6C64E1 -:10011000F1CC2DA2FF870EEC043D6CE072D475612A -:100120008317F5F5D0018CA7B5CC5A8BF1A3AEDCC3 -:10013000B33ADC6FF6BEA7C3BD8C33C4386F297BDE -:100140001671482F1FE7CD1077A7F2BFC4CBF0552B -:1001500074CAB5769F11CF6396F1DDCA681AF67F2F -:10016000D5451BFA9D2BF9F747A6FC4987EFB64406 -:10017000A91E53FBDEA0F5CF00DC9221E1C50F9F45 -:100180003B900FFADD33FB8F58EE8AB2B75B80EEFF -:10019000696507308E9F77E8407736AD7F7931F11A -:1001A0009BBED1EDD7F2F9694B0EDB07B1C51F0934 -:1001B000C33EB00F8608CE4F0B9F3B56ADF892ADB5 -:1001C000B79804708858AFD1BC7CBD83AF3B908B8F -:1001D0009794C4F16AD0424EB0BF2D65AFBA81DEAC -:1001E000C283EA5A90EB9AE7AEFF22C81FB9D1E169 -:1001F000B992F6E703CFAFDD5719ECFD1DACBE0594 -:1002000021CA8F869203F91B668DB62B237A53F28F -:1002100097AD214AC7E9A52FE4035E7B95DA5B1F02 -:10022000B4C7ED95EC272D94E6D3C090B4CE24F559 -:10023000D7A5ADB8D1310FC6F347DE820479A2FA53 -:10024000BF0EE8DFFCA8D303FA9275E8155D05BB85 -:100250004671FB920479DECCE5A5C16076AF6516E8 -:10026000896C5740CEDE6BAC007D7B5165FB500E38 -:10027000BDCDF23EA579A197CF1742AE7B73DF715A -:1002800083DC7D7890EB47D8A624C6918CB2D8CD7C -:10029000301E823F1D929D0990E4F3C22907C3A935 -:1002A000951A7B6F50BB0DEBD4F27B13FC28C04139 -:1002B000DC9F12EFD73B18DE15D7CBC82BF8E177C0 -:1002C000A8BE77ED3AEABD1DED9381787DF3A103D9 -:1002D000C5B00633E5E0811A9EF78DFE98CAFB395A -:1002E00095F8D03E2D379CB87E20CBB7BD6C5F14FF -:1002F00060B3989FC111D7A6C4ED869A187F48E2D3 -:100300007F91B0F9DACC843C2C3AAF13B01FD55EA4 -:10031000167795E524ABECC04E361F50294C58C7D4 -:1003200095E5B6C10879617D9AEACDFB6C3D93CE27 -:10033000531097501BFD389E5C3E6DF41FCC7B190B -:100340007EAB7CDA8B750B4E91E978C4C1D7C5388A -:10035000EE17F37296B71FE95B6EB4E543FB53BD2E -:10036000FDE86751BB9E0F572167C24E8FC8DFACB7 -:100370001BEAC14E815CC392F7E9B2EBD3C1DE3513 -:1003800078193E21521CBDD73BB69FD12DC9E369D8 -:100390000FF3AB1ACA48BA2713F49DC59B7A1FCE38 -:1003A000DE9791108FDB630FFDAB6372FCDE5DF2B5 -:1003B000F97A8F1BEC0BCBC72AA766CB5E148F6331 -:1003C0008A78A958BF13F1D15171CC922ECCD7B2F3 -:1003D0008B3C0ABE9E372A8F6782F9678EED6D9A35 -:1003E0009FAF93200E6BE4F1B7A1B9E3C441B70905 -:1003F0005C76DC31797C5CF628F72BDF00E341AFDB -:10040000B7383C783520BF8492DA9B961CAF1DE04C -:10041000F8E572F4F3840ADFB176DE7458FD4AF130 -:100420003C8E83991E4C2D3BD09D88832B5B296F7E -:10043000E838E9AD6406C94C2D77CB47ECDEB3163E -:10044000F91AC1C5E3E061215F83AAF967C7BCD48B -:10045000E51A381DA9DEB7CC723441FE142D47A62B -:1004600066B2EBD5F4DA3DFB40BE8D3E3F09B82BBA -:10047000818EDEC70E613F5ED6D9FE97DE0B1B0A6A -:10048000611EEFD24CE29C3771F991F5C939CFF476 -:100490006DA3FAD799EFC4FD7E9D5E86375E81928B -:1004A00009F2B45E0F799C93718A304936377242F3 -:1004B000CEC168D64C6CFFD66D19FDF70413ECFA6B -:1004C0002E78958BE70660BF1ED4FB31BFE6365A07 -:1004D000BB83B673CC50A7ACA3F7454E66F78F85A8 -:1004E000ED16BE886B9193C9DD7A3D58047492B6BF -:1004F00066D4B3B58A1A04FD27FE89C5E576B4270C -:10050000CF132D8DD73F07EB3F48EB07DCE0E771BA -:1005100077E2999234CECEFB1D25A40EF4E57B59EB -:10052000563F739693E9D99C78FD1589F5CF7132C2 -:10053000F9A7CF17E0F3A7D9F35CFEBCAA88E5A919 -:10054000093E8A7A6BE3F5D5E27787D877939D7C6D -:10055000BD80D32DF0BD9CCF74431A1B8F2AA17789 -:100560009A8278BB9CE26FC4F7DABE6318BF73F25D -:10057000FD91690E7CDF916B477CDFF10941FCD96D -:10058000E962F1C8AE0B676FFD2ABDD78689251FCA -:10059000DCC165481B7A0AE36FE5F97C3F1BD7573E -:1005A000B16FEB486CBF655D55ECF3E974F23C0C40 -:1005B0005EDF025E1F9170BBE897C039ED7C9F4EF5 -:1005C000B9E8DF407407DA958128F6ABD2C3D68349 -:1005D000BBB2BE81FEF503179ABD8971C1AEE9C7F2 -:1005E000D9BEFD7C4A77499C2E8DE3B1F261DBA632 -:1005F00003C00F4DC18CEDAAE88B1905B4FF8B4EDB -:10060000A8FE34E8BFE4672CC9E779D41CE7A6C28A -:10061000F5BF54623F80FA6D19178B80FE2353FE9D -:1006200055053C5A1E7D43059C5EA9B1BCDD851273 -:10063000FE6887F33A809EBFDA2236DAAF9EF3EF88 -:10064000A9307F5C311CC17E4F1BEEC3BC89BC014D -:1006500016DF5D30534985EB7764421E868FED735C -:100660002DF7EFAEC9867A87F8BEE5D8F94940D7AD -:10067000685C6FC529015F15F67B04E7E7B3B8D264 -:10068000E5E2E94AEED708BF408C3FE503EEE36AB6 -:100690001FBEDB09F36315E76B61BE8DF907D30B52 -:1006A000D7A07FF089EE817CDF073C5F77A27F4097 -:1006B000DF837F5009FE4126C4E5FAF236B846F7DB -:1006C00047C853E1D0C75B43B4FC11FBEB79806BA7 -:1006D0008F5E782A0FECB2C80B17B85E9477695515 -:1006E000CF83BD16790802E73B04CE8F3513D8CFF0 -:1006F0005F396CB3E07C0797AB4A83E955FB5F0930 -:10070000AE7375BDFF5E6F01FDBEF34516879E1A81 -:10071000EB5713717E39E777E7277D78FE8890FFE6 -:10072000CEF7D939221DF97C7F0AC7F98B092BBF77 -:100730001870BEFBF271FEEC3466774C8EE317F353 -:100740007C54F1BE9FDB7119DFCBEF2F17DF138EC7 -:10075000DFE3B8D82AB75DBB0A713DA5DCE364FBD3 -:10076000CD0662CFDE45AF5362A127F600BF2FA6AC -:10077000FBE13307F7BFC6CDE794F0FE5412D79BD9 -:10078000287D9495DF8F7A5249F504F6938FD2072E -:1007900019FFE7C78E41F90584E955F57088AD8FDB -:1007A0008D83F72B8DFE3CC4FBC38BDF677EC3D8E4 -:1007B00078DF94F297EA663AC6F64FD3AC786C814C -:1007C00088770C37B378E47033C623170C717B79C4 -:1007D00081D94B319E0F70B913F65CE867E785B39A -:1007E0006A28C16E8EC8F730DB872BBEEFCC6778E6 -:1007F000FF275A1FEA73E7D0DCF4C438958CF73B27 -:1008000001EF97401C89E2FD39A0BF04ED5E27E0AF -:10081000FD04BDA578FF9AB404FCE61E5A5DEF8185 -:10082000F5E009E613083F7631F8B1D909F152A78E -:10083000D58F4D25DF67F9FC1DE7671F9B7F86FB82 -:100840008E25F253E3B8D60178724E7CFF7A672A80 -:10085000BE7E62DDC72CF2B53B8727E637515C5B75 -:100860009F363975B94A4E47AAF70F5CD011D702A7 -:100870001E9F3A875DAFA6D7EE8FFBF212712D3126 -:10088000181EEB7CEC37B83FB8338BE2D992443E6C -:100890006F1B077FB0FB055E3B5F87B1E20922CD8E -:1008A000FFED2E260747291EC1F848DAAF908F1DAD -:1008B0009F9CC5F6657C22F0888C4388843F04BDEC -:1008C000EDF98CEF476267BEEB877D7327C43E531B -:1008D0002B2E91F9353E1EE9437B2ECB7987CBC475 -:1008E000BCAB383ED1116F3C60677843E0138A3B64 -:1008F0008EAD05DC3140481A89D32F708AC01D6245 -:100900007E6C1FE6E72D79F8BC20E19411FBFF29EE -:10091000718AA847C629723D9D3CAFA39DE2966DA2 -:1009200088638EE33C3B51FC22E395F17049E54C32 -:10093000864BDAFDEC3C268167645C52E7EBC23CF7 -:1009400040815F268A5304CE91F18A4C5727E09765 -:1009500092387E91F18A2C4785F9642DC4F7058E73 -:1009600049A59F50EE0E771CDFA42A47ED33E29E87 -:1009700094F50CC52E17F7FC1AEC4A6ADCC3C6B90D -:10098000F222C13CA05478E4017F3F3B8F489A3764 -:100990008EE49F7913F7690EE83E157111B5934601 -:1009A0006A3C24F46EA4BF60074AE2F3524ABE0CCC -:1009B00070FDC81F7BFD65A27849CC17B3D3D87CE6 -:1009C000906A1D323D9DE1AA070B997F2CBF8FE7EE -:1009D00095587113C99985F2FD55BE2F39158E2290 -:1009E00024E66671A930B683F9E480C34037E7F3A3 -:1009F000BC024A6A70269909718D20BC8775AC7952 -:100A00004A244C495B01CFE9B856D5B075A033B341 -:100A1000D83913A7AB1C38AEA73E6479875D2E1674 -:100A2000573D7D5D9A7F3F25E143A897CEB767D2BA -:100A3000FA4A615CA78B7E66B37E2ECB886EC27548 -:100A4000F0EBAFB5850B46DB8707D3391DD906AE72 -:100A5000A735F0F814AC07E6CD1DBD1FA035BD00CD -:100A6000FB0DF9EF79B4DC4E5BDF770BE9A3341BA8 -:100A70005B3F95F9FADB7445E4EB841D097C689CC7 -:100A8000E934D3A83CA67D8EE50374D638709D2941 -:100A90000D96CC69BD0F1517BA92C987E897FCFC73 -:100AA00061DEEF33D363787EC6CB3C8F77B3A68409 -:100AB00081DF6880617E9A346DDF43B4E8D274765A -:100AC0006ECCCBCFBD8271A197B2381F4C05F31508 -:100AD0004EFB983E853D4604F655D2EFEDABC7D0B0 -:100AE000E7BEAA25C51C8F1105D6C9E08FC2D1FC6F -:100AF0005E55A762BF577976DD05F3C699BA5733BD -:100B0000E0DCC7E54336027AB7CA537E073CEF7292 -:100B10003139063E03FE5F55F3F9AFC0F3C646EB2D -:100B2000781C4C2F44FE56686C3C60FCF2E68E6EDE -:100B3000977848489F92C0FFC00BDF5412D62144DB -:100B40007E8A3345BE5EAA7E2B8976578DC719A74C -:100B500096EDDB0DFB5B82A5ECFCCB061F09C37A8F -:100B60006E839F440BB87C61DE4CF74CB6AF87EBCD -:100B70005756D9BED642884B0E696C9D599A5F2A4A -:100B8000E858E567439C9C8DCFE9792AE2910AC831 -:100B90006BC4F32B197E6F30D722FE6F7CB87B5766 -:100BA00021BC57F36BAB7C6C1DD492477588C5DDB7 -:100BB000564872EE92E2FA157E290F90E7EF75160D -:100BC0003FE101F979309BCBCF5C05F5E815C5F71E -:100BD0007061C23C7363BAF0CB88CF9E201F23F2B2 -:100BE000C0C757E67B2A7ECA7C92E542E6F7699742 -:100BF000C4AF14FC4FC5EF8AB2AABF2B7F3FB03BF6 -:100C0000EC20B75DF63FE6B37815B5C109F644E6CA -:100C1000DB0786CF0576E2CC108B87BD34DDF74548 -:100C20003C8F8AEA319E9FC9F5213E0E541FDC8914 -:100C3000FAFCFA0CD0672A6776A8A7D154CC34D036 -:100C4000BF830FDC85FD063D75C7F548E6FF28FD2F -:100C5000A3FFD304BD45A3F548CE0FFB5BF5EF4ED4 -:100C6000B0E7946F73D37D7815F6B49178BE98B8D9 -:100C70000F55AC937715B40461FF78C3808DC07CA9 -:100C8000D33EF48CB60EF6A5D62938AD19A40FE9DB -:100C9000355A59FEC3558FDF4B203FFDE1E9C40FA4 -:100CA000F6CA6865F910F43DE64308BC2ECE4DA4A3 -:100CB000EF4DE687B376EB79BB2EBF359F67E5E056 -:100CC000225C4FE82EE6F148EE37883C5622ED6371 -:100CD000698127B9F1FD1EAD1722E83FB4A7D8D727 -:100CE00022AEB21F205F7B8EFEEC2BE00754CED4E9 -:100CF0003D00292A87A24EA8EFBB2547EB105FD500 -:100D0000291E5867EBF9B86D07A172B4B2E49DA42F -:100D1000B8E4F0073FF4433F0EDB77FBB3C13E6C12 -:100D200067F356DAD525D3D78D817B427555750586 -:100D3000B353E78DDC9AC1E7F7AE3BF73F08EBD939 -:100D4000833AC643EB393E6ED07637ADA3E3D9BDC7 -:100D500054F16FA3CFBBAFD9D37C14E2C8EFEBC083 -:100D600071D27BE1A97CF0234E3EE66C82FA7B3E99 -:100D70007EEAC7983732A8CF87FE8ED07FA5C1DE26 -:100D80007FF8FC09B0332B8B5796423B691AD90D7B -:100D9000F274C550DB9B70AE41C3803E0FECCFCAEE -:100DA000BA7DCE7F003ED53DEBBC925EA70DF96AC1 -:100DB000613C33D243733228BD792505F7E7403BC8 -:100DC0007EE23791AF7D04F8BA528A3F5672B96914 -:100DD0005F5AE04A8C639C192A74617E421DCF4F92 -:100DE00058AA06C10F3EE3B9D28571C73A9697203B -:100DF000F36B25C7E92BEB0AA627C3E385757F4173 -:100E00001CDE7E8DA32919BF6FE2FC4EFBD386FD4D -:100E1000D0DFB41F393D00AFD352E45B6667F07C8E -:100E200052EFC4E22002CF50BE3AED0971108AF7AA -:100E30006FCE4888AF5C6EFBF519CC0E0CAAA12FC3 -:100E400001FF2B781C64BCF843F938EB6E548E908C -:100E50004F2B797C62A5884FD4174CB7C42788E9FB -:100E6000053B7B06D6DDC0CFD6566C013A7A3F6093 -:100E7000EB6EA9E477E5CCA76E3D9A60EF7AED269C -:100E8000EE97ECBE86F949FF55F23B226775CFB667 -:100E900096D2E70F95AC9C0CF62F418E5B613C2EF1 -:100EA000578E65FEB52F2D7211232ECF428E47CB64 -:100EB000A582FEA890EF54E301E5C01F5D398E3F87 -:100EC0007A66E9D549E53F5ECFB931F5A086CBD545 -:100ED0004D5CAE2A89E9C173A9F2DE44BFF557DC47 -:100EE0001E8FC889AB0FE341E1279DB83EDE7941F3 -:100EF000C7F3CD3B9FD8F8139837BA871679DEC36E -:100F000079BCCAB38AD2750DF80F25383EDD5A4236 -:100F1000BCFB8D0CB11E6ECDDFFD37CF1FB2ABD841 -:100F20003C6B54517ECFE1F3C4E70A9E4887F97CBD -:100F30000ECFA39FDDA1279D973984202539AFD8F7 -:100F400000FA971CB4963346F691B7D960DDEF737B -:100F50004F4BEFF9FE6739DFB13723F9BE6731DF59 -:100F60003A2F8C1D47FC39F7AB9FE6F9BCFFC6CF83 -:100F7000ED6BE3E7DC3E03FB56E9F520EC5BA5CF28 -:100F80009F877DABF4FE10DFB74AF227762EBB3881 -:100F90008749E77C68CD8D58D607C53EEDF652955A -:100FA0009D53E1D5F11C548A9B6C987FC2F1A22D10 -:100FB00023E0D4E9B8EAFF4130FFE4EBEFF7A13CCE -:100FC000ECE2F3AC8C633A243911573DCE470DE285 -:100FD000589DD3434DC1123E602037F3A6EE7B28C7 -:100FE000014FFF2F2E172DDC6F0B5F209127957877 -:100FF000F9972E90A71E421C45C22AE00EF88B8A54 -:1010000070FD00411C575FFA00FA5F80030197E111 -:10101000F96085101F7D1EF15CFDD0FC3BF8FAC124 -:10102000281C37C23715F9C4F079E92B1827A91FF6 -:10103000482E6FF1BCA5A6EE9909FB0C1A87C43A9D -:1010400005A5644A7C5FB92EC9955C4F56A982E319 -:10105000B2AC98EDFB12EB1C623C7734F7617E4733 -:101060006FA9C307F1051927CA385F2F65FBC2B402 -:101070001BD9FED4FA0B2CCF1005664AFCFC349D1C -:10108000E7EDB67B427E38AFA4C12FE1DE189BF7B7 -:101090002A8BAD785EC6FBFA802EE1FD309B0FB740 -:1010A000B3F13CFD21413FEAC9BD2C3E70D8EB6352 -:1010B000F24722E8F72CF4DAAE7BC807EB526CBF9C -:1010C00065F9103B6FB37CC087FBA7170E92E855FC -:1010D000B3213E4A5AF13C20897F0B095B7758E8DF -:1010E000F5754F86F8A34676C23930539C6B4DD0C8 -:1010F00003DDDB8CFB6BAA9D0A9E934DF8FA98E00A -:10110000AF9E7E6A07A8C0429ECF277E1762AAF3D1 -:1011100000CA813E4E5C56AC7FE95CEEC47A56153F -:10112000AFBF6A90E5B1C97290E53CF7269CA3BCBD -:1011300068C8C0753179DCE5715D64C4DE7D04E2A8 -:10114000F617D2FDDB619C9D6C9CC538EA6A870A64 -:10115000FB3588C6C64BAC7355CABF0F21ED8393D0 -:10116000E912E71F7CC590F685711CBF8853D79A9A -:1011700076C0B2BE22AF031CE6F9083FD1D839A22F -:101180008707C75EAF3ACCD7AB886782E70EF2F32A -:10119000022ACA483AE09C8A41C2E4EB615B2471AE -:1011A0007D4BDE27EE1E5C5D8FE7AB793C789E427F -:1011B00005A1D7523CE715F31B4D72C0B21E6772F2 -:1011C0007BAFF3B898AEB07E093EC9F4DD3664F566 -:1011D00087BE18B6EE6FB8F55EEB7E8C5B9AF32C8B -:1011E000EF976C2CB2BCAFF55D6BB9FFBCD77ACE74 -:1011F000CF7F0B59CFF959D5542D9D63673DE7E754 -:10120000A63AEB393F0DE6AD92FE9AD67507A58F4B -:10121000AF5FBC5534569C37617FE198E7FEA01F55 -:1012200098645F8BBC3FF1AC21E28D563DE80E57D0 -:10123000B17371067C7BABE8FD51E2D7D0C1E5E725 -:10124000FF887D7BB55EB69E337ABF1DA34BD84128 -:1012500079DF8F38B7AF62B00FE5A0523E9FCF9BCA -:10126000FC7CBE570C8E17C4391729CEB318357FB6 -:101270004FB47F7C1D6FDCFEF176CB49DF3138E760 -:101280002355FF26DAAF91BC2D383790F2A30F1EFD -:10129000E5B2F706D5B79D59C5789E85DDB92866B4 -:1012A0004C8EC73B8979FDC4F66DF3383E31578DBE -:1012B000539EE9BDDDE9637261327CB45331237022 -:1012C000CE5DFC3C0B827640E7F3A97CAE45DA4E5E -:1012D0006296501685179128E28D42676407AC83A9 -:1012E000E6B27DA32DD7D870FE693967EE86FC93F0 -:1012F000D66B34DCB758AB1A585ECF67F35300D6C1 -:10130000A0203FE2A4D964398FC3BBDD037AA2FFDA -:1013100098BD4FD59F8E5CB63E2C3F2F72313CD48A -:10132000A505F35C281FA697AD4744F0DC32916F0A -:101330009B2ACF9602470FDA6D22F0011BBFFB619B -:101340003D2589FEFA5D4CCF02254AC40E79A337AC -:1013500093887D0CBFB2C36B4B1ACFC875F1B8E848 -:10136000C54B781E9D2ECEC7CB63E7E37549E74E8C -:10137000E6F27E1E7039991C143CC5F6A34AE79428 -:10138000D7FB3690443C5BCEE7193DF60EC6994E2E -:101390000F8C8DC3C5FAD32EBE4FB9FA822D988C0F -:1013A000FEDFBB3496176CD893F66F3DA7B7638604 -:1013B000FFB5209583967FB6E1F9D2016FCB34DC7F -:1013C000C7EDFA07C2E25D8CFE7AAEA7016F640733 -:1013D000A1E31788BEF128FC3E875EE6C0F5E7D39F -:1013E000D7507C426568578CE2C58278FF5C7CBE32 -:1013F00009EC3D5A5754CACECD8778CF9201964713 -:10140000BEBC6C1F3F77A51FF725CABF0F525E17E2 -:1014100032615E5EDE18DD81F8C7EFABC2DF0B2103 -:10142000FE6D6CBD50DE3F6920EEEA186272DFF19E -:10143000537F17FEFE8657E046B3B1764AFC7CAF79 -:10144000CA734777C2128C7CBE977C8E90F0CB74A7 -:1014500009570A7FAC81448E69CAE838732A7FEC49 -:101460009F5C1C8F5C43FD313AFEB73958FE6CE03F -:101470003EA50C9CC6B4FB945CB05F2D7C9C5EAB1F -:101480000C615E404B8AFD747FE472FF5A6514F76D -:1014900029751484BCFE31CAE7BA542CAF5F64E7E7 -:1014A00078E84E96D73272E5795C42AE0BDD0E7667 -:1014B000AEA19BF9DB0B2F3D9D37D6FC591E0811C1 -:1014C000E80FB52F49F365F689F6A3EC3C0ABDF5A4 -:1014D0009D9A64FA2CF470BD1EFC890BF61D2ACD72 -:1014E0009134B403133F7F728EFAE9EDCD9F0CF374 -:1014F0001968FFA4FD5F7CA01F3B42D6DF7512D7A1 -:101500009346C889FCF71ECD007FF377E9A1C3603D -:10151000F720DE0DFB053B62CF38D19E4A7C97EB6E -:10152000B9CDCDC653F7B1F7E437A66F65429CE459 -:1015300006371B17BBD3EC81FA67DACDE340DF83B4 -:101540008B92AF43BAB44527A1DC7546F01494EBF7 -:1015500088EDC7F8F12769E64BF0BC54334FC375EB -:101560008FDD7C99D9E91ACF7BC5F17D0CA9C6190D -:10157000162EDE2B4EE4D7A7E3B3DD19EC87F6E990 -:101580003C18322E739CDDF45A07730BFDBEBF323C -:10159000F97A7B0B9727AA67989F25F6B904BCC4F4 -:1015A0004C367F89F274FCCF035D0FEAE120ECD763 -:1015B0003A3DCD46F627D839712E414B8CF985E757 -:1015C000EF51F633BF90E0FD4FEF2CD80FEBBB3758 -:1015D000CFE07ACCF759DC7E8F75DFB368F7CA4C61 -:1015E0006542FAF9CD4C260777673AF0BA2D93D1C8 -:1015F0003B61FDCC61F5083DD535765DEE61ED9F33 -:10160000E1F57FCCEFA91EE6B8991EF6BB2E6F7CE4 -:101610007EB8AAE8D3CB87D007DD6FCD33FD16D7D0 -:101620000761AF289DD7B8518E9A43E99747E79451 -:10163000F2CF408EC57E033543B1C4C303DC7EDEEA -:10164000E416B8C8AC7433FD5D00D731F477919BD4 -:10165000E96F8DDBAABFB56EA6BF8BDD4C7F97B857 -:101660003F85FE9E05FD81FC3C1EC727A7AC768703 -:10167000E2E255D07EBDA6F07DDBE40F4A82FF5149 -:101680003F1022269B2C9F48C40D14BF9AB85FE3DD -:10169000356B7D3D7CDEA276EC4B506F0FD7DF1DA6 -:1016A000BF65FC033E3E93442F051F55C75A2FE4E8 -:1016B000C5A79AE7026EB6BFBDCAC1F6539013B470 -:1016C000FD5996FE6C067E8DF4274C3DBBE4FD096A -:1016D00027ED4F9FB5BE84FEDC0BF58AFE2CBC7453 -:1016E0006A4C7D0C087DF4445598B7035AF279A1F1 -:1016F000DDCDE6CDDF67983BA17E59BEC475179757 -:10170000AF54FB5EBAB445BB80DFE51AB383C4882F -:10171000F6AB09FD2B2F5E2BFA1DB225C6D906921A -:10172000DBC947DD237AF728CADF5EB64F87CAF5E3 -:1017300063D0CE6D933CAB715FD747CC6E9EFDEB13 -:101740007D76F89D94A69C3DF7C3F5A49BE5BDACC2 -:101750003D57E88661E8AF64FB1D5B72D9F9682DDF -:101760008AF59CB4937C7ECCCD147EF5C4CF11C792 -:10177000B392FF4EF31BE54F07B74BFD69459767E3 -:1017800097E67D06EDDF3C83203E6ED9A7E33E035E -:10179000A137B7C1D8B2730D4CC8A3F812BDB7D1E9 -:1017A000FB7E70BA291DA17C42BC73B15C58C77323 -:1017B0000FCCD7983D327F0DE34BEDD0596E875E4D -:1017C000877B6A877EF369ECD0336EA637AD54868B -:1017D000FA400EB508DF8FC3FD11DED7F2E2639643 -:1017E000B89DF0A73A06F61B61C81B2C66FB4F5349 -:1017F000B52BF205C7FB3D82AA7F5EE70427600791 -:10180000C575104715BF5FD701ED1BD09EAD11F810 -:101810007A92A8B80E2FD7D7329DCFFB2E2ECFB9F4 -:101820001BD0BF927FBFAEDA1BD93597D613387164 -:101830003B3B2FE1E2ED64F52CC0272102E76AEA89 -:10184000F40AFBDA05DDAECCAB2CF1409D28DAE2E0 -:1018500092B81DA98E91E8C252C437B87F0BEAF145 -:10186000F17A42B360BECFC273564F1627CF4FD81E -:10187000A58672322727F041FADD0B3AFE93E13D4F -:101880001DFF2999F370FCA766B279C80BF7BFE179 -:10189000E3B84B0DE6C1F3500E5B82A6E5F379F990 -:1018A000E9999F819CEC20EC776F417E13D7ABF7D1 -:1018B00070FBF0B3C9A11268AFE6A72BBAA7D14F4E -:1018C00036B5ADC5738A175E11FBE865CA1F92A7CE -:1018D000E37A60CBC3D679E4071CFFFC3C53ACF73A -:1018E0005D1E8EA0F6EFC64CA48FD9BFB097FDBE8B -:1018F000E7DADCC2EF31F8481DCC29F1736A6B3CA2 -:101900002B6AE0F70ABFFC74C15C38D74AE7F67966 -:10191000B1B74B5F07E30ABFFF94C49E378ED8412F -:101920006ABD2DF354F2FCD42F65B2F993EAF1B2FB -:101930004CA6BFCB81CE7D93CD9B32E7FDFDECA3C2 -:10194000B043218DD91BEA3785C16F5A3DDCDC03DA -:10195000D35413D9530BEB1B542E3700BD5F701EAD -:10196000E8613F9D129E06ED5279BC83CBE3462E83 -:101970005F777279FCF2A7E9D76A687C5E6AFC2916 -:1019800070B8C0DFD4CE7F2B93E1649FFBB399374F -:1019900076F0FA42EECB9C376EF90CDAA778E3FBCF -:1019A000C0C7924C3226BE7D94CBD5639923F8F6FE -:1019B00031F86EA1D37C3C33116F949CF803E4C9D9 -:1019C000C5F14697CAF1869618CF0E50FCC5F3EACA -:1019D000D6DBE6C7F5448F25C7216599237ECACF9C -:1019E000D0AEEC6238A46C846EFF4004F4701AD759 -:1019F000F737983D5EABF7AF07FB7C3E8B7D1FCB87 -:101A000062E3F81CAFEF6DC59534BEF942E608EE0F -:101A10007901DBBB8FB5A7665CC77EB743D815BB22 -:101A200082ED88F87059B6B59D79D9360B4E95DBA5 -:101A3000E98EF7AB1BE5F81EB1EFD7EC81760371A9 -:101A4000BE4613F90AF6C5363F819F1CD7A5C27161 -:101A500009FC7B05FBD3CADA19E15F28B99DC5DF14 -:101A60003564B8F475A02F957CBCC5E5E37771F9B2 -:101A7000F81D978FDFC37737CF60E370DB24EB7EF1 -:101A8000F277F977F7723E89F192E9FF7A362B37D0 -:101A9000C20FDF892712716DA0386B7513C42D5BDF -:101AA00055BFCD375ADEE87F336D09F6581F88E001 -:101AB0003C510FF296C4EEFE25CEAFBFE0B8D43055 -:101AC0007E75A5F0E3EECC66FDBE257F5FCD646834 -:101AD0003F7CC9F27B2D5FD8D8A526FA09FF1BBE33 -:101AE0005F0B5400800000001F8B08000000000006 -:101AF000000BE57D0B6014D5D5F09D9DD9D94DB275 -:101B00009B4CDE1B48C224040D1A708110A304995B -:101B1000BC780688BC4445591E86F04A22624BAB0D -:101B2000FE2C2684A76DB43EB045BB2054AC682380 -:101B3000A64A31D00D08E2B3A1ADA2B58F2008A806 -:101B400008216A5DAB7EFCF79C7B273BB3D905D4AB -:101B5000B65FFBFFF1EB77B977EEDCC7799F73CF08 -:101B60009DBDFEC3E373350721E7E06F44B0AC4A87 -:101B7000B010924C48FD0CF741359F10AFCBE2DE20 -:101B80004A7AF65B1E2F63BF51D93E298EF67BE35E -:101B90002C5136D37E374C11345F1E21233B89E60E -:101BA000A3E37F192F103294104591B0FF1509ACB3 -:101BB0003E4AEE985B1966FEBEFCF9689568CD74E6 -:101BC0009CD10AD17684E977295FE7A8E8F0E38C15 -:101BD0008271E8F331848D13FA7C1C7F3EAA24FCC9 -:101BE000FB97C1F8741DD35DCF94271058CF26AB57 -:101BF00087F6CBB16AB90A6D5F53D2B128DC7B4E50 -:101C0000A9240F9E4751D059071372337DD742073D -:101C100098494B9996EB45CF6085CEEBA1E070D10A -:101C2000E7B45BAFCA01840C726843A0FD8B282D1A -:101C30001FCA7C491B0AE3DC6BD50AA04E889F9023 -:101C400002422610F637C1EEF08BB1F41F85D65351 -:101C50001D76D6762E1BFEFF0CE5F8E58408C42F12 -:101C60009CBB1CEA3E11C6BF5A3DF8B640FB5FADB7 -:101C7000BF77520A792F5D391EC3EB22AE0BE1B359 -:101C8000CBFA90EAB0F4DCA75EEE7278EC0087BF86 -:101C9000447BC6C33AEB5D9B1D2A85F72B9E66BB32 -:101CA0009BB61F8E2308C7BFC66813613FF5BB48AC -:101CB00075336D176384BA6603FCA6280C9F531511 -:101CC00086FF36499B0AFD47D8B56930EE944C8AA9 -:101CD000273AEECCC48EA546B8CFE474309DE3EB32 -:101CE0006699F50B5DE754DEAF4812BC31B026C7EC -:101CF000C163620A8507E9FECBB1D0FA58F8974A6A -:101D0000FB9D54A64D4FA2385B2DBA2DB42EE70A89 -:101D100048CFA1E32EE2EB9D2B572E82F512B54E54 -:101D2000AD7452FA90C3D3C731DEBF3C025D66F199 -:101D30007596C1F330EFA771FE284B6A13097DBF7A -:101D400088F35B68BF490922E36337191D6E9C7AEB -:101D500085D13F5D773DD297C2D69D63AD5C09FBCF -:101D600098A11C2A8FA7CDC5F7244D2349000F0B3E -:101D7000B165219CEC84C249E270A2CB24505F6221 -:101D80006775297A1189A365A6CBB76E20C0AFC14C -:101D9000EA5669FDBD93EF8984D2D9D6FBBB0442D4 -:101DA000E5C5AE4E4212B3601C1946843FCB39A143 -:101DB000E778F4992AE9F351D05C739268364ABF08 -:101DC000D714764E22B1A6F7C9393A9EA3B3DD2BBC -:101DD00000FEECC41B730592F11F735270541C2F4C -:101DE00095CE0BFB913F253ED88FE6F2549081842F -:101DF000C47776FCAC16DB1DEE51B82FE2007E0BEB -:101E0000EE7309F29FBE2ED9D1F1D88F69FFD6CFDC -:101E1000A2DD77C3BE3B477EC0D643BC4EE06BB16C -:101E2000C2EDC983F76CB83E0BFD0FF86C7880AE3D -:101E30003797AF1726C937AC9FF4DCCF7AB1F27968 -:101E4000C0C74C3BD16207A37CD809F5BE56DA81E6 -:101E5000C2B151117C5EDAAFF1FEB9ABB3405EAFF7 -:101E600097DCFD08D039D929503A1F46E75D46E591 -:101E70008E5C481C0AADCB2EB6FFC67B9236C508D9 -:101E8000F05C2233E8F3619DFE2F040A8758575512 -:101E90008542F721F3F7050A38785F501532633031 -:101EA000D06DBB48503EB8101E3AFF689712E1381B -:101EB0005D373C02FA2A9388D74EFB0B2E36EE355F -:101EC000A453247D010F5411D0B284B8B16C143DD9 -:101ED0006F02FDD9658A57BA7EBBC5EE5B2100FE55 -:101EE0002A5F1B8D702F538EE706E5592439049025 -:101EF0003BAEC355FCEE72AF7C6978BEFA30C83792 -:101F00001F32B94CF986CE33259BC99DFDCE8E1963 -:101F100046BE5FAA30B9B494F33D91189FCD95B5F4 -:101F2000B380C7487CBE8CBF9706CA07F89884E781 -:101F3000E39FC7B3F54CB9DBD7D88BC26F4282E0C1 -:101F4000063D5CBE7D96D45B0DF693B9BE3B97AC67 -:101F5000917894C3EE93BE24D03E32EAF7C677C898 -:101F600074187F16979F27F8B8EFC7B375C4703DF4 -:101F70007E44704E0F0717677CB71C74C2F8C4C349 -:101F8000E022C60CEAF4D379486F3E8F55C079DA67 -:101F9000B2997C8C4F30CF13CBE53895FBC9F12833 -:101FA000F77DE9D0EF152B5B5FE8BCE9C179D37110 -:101FB000DE456CDEB120E781FFD5832F829C2FE2C6 -:101FC000743AB6D343C0EE011EB61404E5BDACFAB4 -:101FD000C53ADA5E1441CEF70FCED31FE7A9637876 -:101FE000DC9EA25D06EBA476C1E550B6652B282FDA -:101FF000DFE865219B295FCE4ACBFE11884D7D9C91 -:102000004D7C9F6D598DAED9145F722771DB90CED8 -:10201000AB51EE1571F952BFCB43E0B9B7179599A3 -:1020200086F7E5CED976E2C0ADFCCF39BD3FF051A1 -:1020300067769C270C5EF472DD72268A88BA18DFF8 -:102040005BC2DF0BEDE778606F0C8CBF16FA5F4A5E -:10205000F996EB1BBA615CDF58CE3BF59D9B633A6A -:1020600068BF5DB9734CEBC1E7948F1A731F8B0186 -:102070007BA93583EA0190532F8B28271B9D0C8F5A -:102080008D6955C4638073A9CB2F1E8771BE9A4397 -:10209000A651FC15B93CE4126770DD45B9555E21C7 -:1020A00009DB9F8BA2E3CC89BF04E946CEF3909174 -:1020B0000E804B33A9A2FB9715BFE8A6656927F1EF -:1020C0008FC887FE54CE0B6C3CD5691C8734C3384F -:1020D000B29BD203BCD7E9C7F5EC3A797E383AF225 -:1020E0002C26F9ADF325B5EB6A802ECA946BCBE2B2 -:1020F000E9F80BB6670D16E9F8235D6DF2EC3C9438 -:10210000DBB5401F9B92B53AA49FFF257B6E3AF149 -:102110005901EFA332991E985023F83653F83486AC -:10212000D8098D9C4E2F0DDA37AB61FDA450B71343 -:10213000B435F1E7B783EF893FBF1DFC93F8F07624 -:10214000F0FDF1CC0E7E209ED9C10F4249EDE08713 -:10215000E2BF831D3C5C21BA1DEA43F8C7B37AFD98 -:102160009F983D1ABAFEF9F1CC0E5B4DF7DA0E746A -:1021700029F92446E78C4FAFE67C3AF624E597BC74 -:102180009EF4DF4AE9DF4BE9AF8BDA4D6256647AA1 -:10219000F25F245F163FC0F8BEDEB517F9EEB79CBC -:1021A0003F5BF9FCADB96205E0F315222AA2D073BA -:1021B000BCC60C8F0BE47A28FF695F99E9B9D4E5B6 -:1021C0005B3F18F8E6E01C372C2B941F655A560D20 -:1021D00008AEFBF79C0FBBE51311A49117C1873024 -:1021E0008E6700D819F112F05F3D61F37A0F8AA86B -:1021F0002722F111A59B77E30DF31503B00DEBA793 -:1022000074F367C02FE5B3BF7C177AF93EA70FEAD6 -:10221000871C87F192787D5604FFE2E3F86EBBE0FD -:10222000639C7706D343CE7895BD479264D02F9AAE -:10223000989109F2858E7B16C6DD1377FE710341F6 -:10224000BD1340BA5DC6C67D1E8CECE49EE38E4A8B -:10225000A0F6479871EC5C8EDF10C15F50B85D430B -:10226000F2BAED136B02FAED6C7D4F246BB684E489 -:1022700020DF1471BBE525C1AC9753B93E57B83F79 -:102280002726B0FE646EF7B80A8CA3C353B7036663 -:1022900071F9A08F93C4F92F2E4161EBAA66EF1359 -:1022A0005E1FC9FD270A97DEB82E3B7B7E21BFE863 -:1022B0002E85C52D2671BBAA1336C8F41BC27574B2 -:1022C00024BF2B68F7F507B81037EB9FC6E143DB57 -:1022D000F3B0BD82ADE352450D1B3F88841F1DFE48 -:1022E00052025F4F2E1B9F78BBE17625EC53A797D8 -:1022F0004870DB13C7E056A0C3AD818F13220FD601 -:1023000049CD7625CC3E47727AD5EB31B966F910C6 -:10231000299E9215D413E3111FF96CDD91E22BFD78 -:10232000F87E2FE378A0EF4D41F839D87AEF52BA12 -:10233000DBAFC3F67436DECC60FB0D388F8BF58FC8 -:10234000E4F7CFE4EB9A9AD08DA759385E127B2F31 -:10235000349EA09737F2F54D0FAEAF1ADFCB61EF89 -:102360004941BC2FC4F6D1ACFDFAF44D65C92AE051 -:102370008D8E037AC2C5F4C10DD56DA2D1DEB93EF2 -:1023800042FC4DE2F35605D7FB7DDCA7C6F67F2263 -:10239000AEBBFD87386F119B3792FC3811C7C6BBA7 -:1023A0009DEFE31AF08BE918F101922B2581D714E8 -:1023B000ED1E45BBA406343FE88F924F6515E474CB -:1023C000B9E8F00A541E4BAA1DFDE4288968E0D73D -:1023D000B67DF63D57471ED6FDA0D7574515DBC144 -:1023E000EF5C9D25B9411F16DF2B31FFFA9405E5FF -:1023F000FD4871118EB357D1EDDC5B4D7EB4AAA8B8 -:102400001551B00EBB4854E6FF578CA7CF477079E3 -:10241000BDD79E6881F18665B078C108B50AFD75A3 -:10242000F215F3A335FA1F93DF1AEA6599BF27A5C2 -:10243000D711014BB3BF2D93F567C581A817D08E77 -:102440001AD669F6BF6575E409185F2686F7E8BCF9 -:10245000DB129C49684FE5907EE728FFD872056241 -:10246000BB02FC6CCF76C0CF18B54A29A1FBB1A541 -:102470007BEC208773ACFEDE104F684897DD5E6012 -:10248000C3FBCBEC59E06F3551FF1CE1A0255C3B51 -:102490002088275B9146800E294E90BFBA4B072BB0 -:1024A000854486C7B7136C580EE275FD7928DEB3F4 -:1024B00013A319FF13BBF7582EC80981C4513A5C06 -:1024C0004C3A32811EC534C6E735968E14A89F213A -:1024D0009D2949B4AC6F924687F37FD6F1B8D41AE0 -:1024E0004B787BE95EEB9857010E12C40DAEC0B875 -:1024F00080C7D637183FD0ED553D8E10C96E6D148C -:102500002BDF04BA1614FF17D0BFA7FDEB65FB4EF7 -:1025100067725A2FF5758C4F64FC6E4BB463BF3DE8 -:10252000779692D92AE2E908C7D3C12B012A5973B9 -:1025300015C0D3CB590FE6405CCA9E757F12F0E7F9 -:1025400068C2ECD372FA8E8B962B1D9E9309067B84 -:10255000634CCE2CB49B8A32EBD09E5A15C12FBD52 -:1025600085AF43E27432C8E1390BFBDA7AFF123BE4 -:10257000BC2F2995D150EE094CC292DABD9FC0F311 -:1025800055E9AC7E213CBCC4F939D2FA47815E8062 -:10259000784D7AF73E84C4647CEE950707F761585E -:1025A0009F3531CCFA3EE5FA485F9794C3E932D7BC -:1025B0004C77457CBFA989BABF78D174F7D6C5D00E -:1025C0005DE87EC7642D1DDD9F04D7AFEF57DF3F69 -:1025D000DD6F1FD86FB9C4F6BF55F168300485B3FD -:1025E0000AFBECB12F7B78BDEF48B47CD3FD3C985F -:1025F000D0F7E2F7F30DC69D96F80DE0B47FB8E68C -:102600000279D2904CE993E2A94160A5DEFF0B6EFE -:10261000A7FDFC9BE32BA5DF37D85FB14B7811F406 -:10262000E108CF9152D86E59D120503BC08F930111 -:102630000F2579F74AB369BDF1CE39283FF70FAFBF -:10264000C375AF729AD7AB9742228FE3676AC87F90 -:102650000D9CFFCA09F323F57E4F72F918CA1FA11A -:10266000E385F2F54A873617D62524323D1BF4FF61 -:10267000DA45A3FF57C2F5D770FB6DA6F8C770EE19 -:10268000FFADFA34DBE1A51BEDA27AED9FE2FF7D01 -:10269000419F809F945E6237FA7F0DF6526C5F9582 -:1026A000A18DBE2209F4B1E8BE9B20FCD01FF40A24 -:1026B000A2B2358C3FB82A43F68FA0CF6D0AF90538 -:1026C000ACAF94EA4B88BFD8148D5C32A0A75FB83A -:1026D000D75E4A206ED2A590E7C01FBBD07E1E48B1 -:1026E000BCC464474AE017F2F1D12F54EA4807C648 -:1026F0007B4A09D835D0AEA25DA5118F13F408F539 -:102700000B0DF2A9CB7E1BF27BE87C546E3D027C64 -:10271000DEA0303E0EF507BB389FEB7236941ECA22 -:102720005D8C6EA2E8D2AD4C6EFC2271684FBAF897 -:10273000E6F2696E19B800D79115FBC1559B1AE8EE -:1027400094C0E59993C8F8A9D2F14C033CD7C70FC0 -:10275000C50FDDB906F174B06758FC86DA6BD48E0C -:10276000B2527B6DAD109C7F0DA78348F888A4AF53 -:10277000F775CBB5D038D16DE6F317C54B920A5833 -:102780005C9F8481BFC8EDA4D5945FE0FC668DD5C5 -:10279000ED02BFA2BE5FD1DB1EA0BF7E32B377A425 -:1027A00026D7B561FC90B511E2DAEF2526203CA3CF -:1027B000732C26FB8C7A0626FB31D2BE095F9795D7 -:1027C000EF4B0078E61AE119B2EF3205F70D663DDE -:1027D0008C1B6B71133FE58BD84CE24681156BC1A6 -:1027E00038ACCEE70AE7735D1E3814F6DEB0A4BE3F -:1027F000EC7C4F74748A145FEB92A83D4DC7A9D747 -:10280000F6A25ED5DF8FE3FB770C67F14687D3AF87 -:102810002861E4DD8F2F80DF264D8A2FA3EBFBB1EB -:10282000C2EC6F69B8A5D287F12816AF5538ECC451 -:10283000E27C3BD8ED05E0780F85F5EC508C712BF0 -:1028400091AF27C649D7731E39B98AF3B75EB7A9C6 -:102850001D65B07E294B53E20DEB1F94A4EB9576DA -:10286000E4EF48E3DDC3E5BC2DDD4DAAE8BC768787 -:10287000DB0FE75A36ADAA00FC05BBEA26730CED68 -:1028800076AD6088CD80F7A67EF2F4707CB92089A1 -:10289000C97FA7A455C27B4E4522704EE6E4F6726E -:1028A000A47123ADE342F38D8A349F1ADEAE884DC6 -:1028B00062FC270DDF5109729A0C9048BF307A42B2 -:1028C000E0FD62E50E15F88AD2A327DC7867126571 -:1028D0000EEF7F117FE8767771CBC16CBADE7A8715 -:1028E000E416407E159E6C570D7281EAF509490683 -:1028F0007B59747850BE892A3B771F6D63FEF6FEC4 -:10290000E1E673B2299C5E5EE56524B97079928533 -:10291000DB4DFF9A7D7E53FC0D4A2226B834015CC4 -:1029200008F0D77D0DF561E42585CF926F039F6593 -:102930009CBE1EB9007C32FECDF0B9105F07F9CC09 -:102940004B8E86916FF54E396D8E89FFA91D12A1B0 -:102950005F95A13D121FEAF4310AF002FCD0A49960 -:10296000E2027292B79DF995B79BF59CB8C8CDE588 -:1029700033F9AA808539E12FDE41FC31B1C1F1E59F -:1029800032733CE1C9241E17882251009F2EF72480 -:1029900001F214A22C3306410834853409A02752D1 -:1029A000609C81D44FE6F23C540F266BCC4FEE4D29 -:1029B000EA04A657D2717D497C1DA17A308DFA3583 -:1029C000108F0154833FDD5B82182F3CD5F01C5CD7 -:1029D000F05AD05F76119F00E3A7930E2CFB402A9C -:1029E000021D3F8BB40B39147FF796570D02F9FD8A -:1029F00062C83E2E648FEAA56E7F2CFB37C1FB9D1B -:102A0000FF5E78AF2835C0BBEB3BC27B0A973BA18A -:102A1000F1BC31DDF1BCA617310EF715B33FDABEBC -:102A20009631BED790C5E279E562C506B0E7C7A882 -:102A30003201FD26E576AC833C27DDEE049704E207 -:102A40005C7ADCCFDE6F4EE560782E9D4438E1D9AC -:102A5000908AF2CC998CF286D91123F8FAC7A8553E -:102A6000F62CD5E83F3599CECF644E07635C25E858 -:102A70003F357C757EBBE362FDA43DD2030EB06B97 -:102A800074FFA83E670EDA3DA1EFF9A5A63F435CAF -:102A9000D29F6353575078BCCCE5D5CBFD1E928CAA -:102AA000E7BFA17E906E578DE0EB2FCD997510FC9E -:102AB000AE31CA6C06130E0799CFD3E0EAC273F0A9 -:102AC000DF7E65417FAB8BFB5B63B89F05FE4E9558 -:102AD000B3E73E87279BCFD574FF694CB7FFD4245B -:102AE00019FDA73111FCA7D1B6CE57AF80BC9057C6 -:102AF00045CC0B8904DF50BF2954FF8C4E667A67A2 -:102B000076323F270A81A71EEF0B3D976ED4F94F0F -:102B1000F20A46FE0F9D5FDE3B06CF05896288C73D -:102B20006607E38982E625CB0607E38761E2863301 -:102B3000920D71435D8FE9746CA37DED78CE1C3EE0 -:102B40009ED89A75A02FF30B5F4C04FC972B2C6E2C -:102B5000A4AF8FFA85F3930D7E615127D3DBB6FFC7 -:102B600053D7B182C297241037F30FEA547B3EBA91 -:102B700013896B591C1DF3B4C638048C874BFE288F -:102B8000AC979D72FBA268DDB6F76109FC84524ADE -:102B90003F5142907EC670FFA221E7E83AA0AFAE57 -:102BA0005392FB7C7E7799430CA1D3E8601DE55BD3 -:102BB00082A9BE5AF2AC647CDB2B086F11F2C1B261 -:102BC0004DF9675B25AD11F63DCAAEAD4AFECFC4E7 -:102BD000FBCF605D8272E05BE13D380FD30760B3ED -:102BE0009134C37C0EDA7815CCA322FD77C7A59764 -:102BF000123C8FD90638033FF763E28338CB0BD6FC -:102C00009744D0478D7C9CAB49932AF765EB857E32 -:102C10004F6C756D5A0BF238390BC77BC1E1590FF8 -:102C200036E4C12DD22088DBD4ABCFDA217F76EF1A -:102C3000D6C6F40E03FF1D7CC2D3279C7FA897F451 -:102C40002FCE5288FB8A65A5265A5CD82E42BD87B6 -:102C50007DB6A54581799ED86A0F6B4775713EBFD9 -:102C60007A0BB36B47E75ADC1402A48878A50438C2 -:102C70008F7113B79F36C40CD8D15E02BA284B446B -:102C80003F9FD6F7C5D27ACC500DFD83FE0376E088 -:102C9000FBFD3F2E71B33C4AAF6330ADAFCB2D1976 -:102CA000BA16FA477BDE04FC513DD324A13E6D8E5B -:102CB000813C8098019392A98D4B620452192E0E8B -:102CC000F84132B3F39EB0EA7095300F72EF5619A7 -:102CD000F9EB609A88FC46E1B608EA7F4F8B2194B5 -:102CE000124999E62D03389693E67AF0A7CAD46B79 -:102CF0005F8C25DF027EF93B14E0FF756087875902 -:102D00005F1B5F1F0A114A3F07B634DC40C2E45123 -:102D1000EB74F88B18ED1380C31A7EAE4B5C939066 -:102D20007E22E3FB6EA41F67B3BF3E9AC2F1EAEDB9 -:102D30004DBD8CE3EF4F564DF1371DDF90FF4CAE8C -:102D400080FC5B0FE6D3D69FB420FC5EC9137C02E7 -:102D500085CF815C91DA6C745539765F3F5A5FCFCD -:102D6000E9B862FBA1865E00A494245CEF2BB98FC6 -:102D7000D9597EEBC5C7AF87503E5800E7C9141F2D -:102D8000A394689F4AF1B51086C887FC1CBBCF4F3F -:102D9000E76B73B697C6D1295E4816DC9B815E72DD -:102DA0008902F2035D100B439442EB2032909E9215 -:102DB00008E673AD2BC8DB0CF2766DBADA0CF98637 -:102DC000BB07D831DF2C349F78B750F7623CE499C9 -:102DD000C40B28AF0FE4FE1ECFE90EA4DB08D02BF6 -:102DE00026FCD2E70D098C4F63F2CDF6677E4A16BA -:102DF000F7B389D756105C574C8E5D8BA284F45282 -:102E00003C7BFF608EE0037A3BA872F940F7BB156C -:102E10001201A91D346D4064BCBEDC6F94AADBC5F1 -:102E200082BE4F4BCF7DBC20F85667C33EFAD37DA0 -:102E3000D0BA3357C0F99DCADA5B099685F3E01C16 -:102E40003374FD35298C2E654A76B920DF9A578F69 -:102E500031E6C7C885B74E70C4621E13DA95A9B9AA -:102E600002D35F27D9796E8FFC6C857864137EA8B6 -:102E7000D591121C2FE6D3E7BE0FF9BFE30A057FF9 -:102E800014AC87E737D3FF6B03FD22E7CC62F9D799 -:102E9000B99B703F630BAD6E38CB19EBF03595D015 -:102EA000FACB1F4818CF1E97330AF3AB43E75FAB4B -:102EB00010FF680ADF97F3248477D4258FE1386FF9 -:102EC000E45950DE8C837C6CC85F36E655A33E34F3 -:102ED000E7738F13FFAC1543B39BF12B91BCBD403F -:102EE000BE4F7099E1E73C693E2FAEC8B799EAE35F -:102EF000F2E49078A597C58733185DBCD45FF06D78 -:102F0000CE0AD2D9D893093EA033F8130B4C7034B3 -:102F1000ED33A653D6007E07FB3FFE1338278951B9 -:102F200057DD8AE7E01CFE3A9DC470BC3BD39FFF8F -:102F30003EE8291DFEA17470F1F8BFB6B218F09FEB -:102F4000AF9FDF87E03F04DF1883D4F7D1B727DED8 -:102F500071FEAC9EF8D6E9A0C7BEEF69599D4DF150 -:102F6000FA8A933E003C6F927D770B413C5D10AF37 -:102F700039C548376B952607C8FDA84B8E3AC0DF88 -:102F8000D0E98288ADF946BFE39F85EF92F50273E1 -:102F900026DD820FE27ABF83475705E77936A53BE6 -:102FA0009FE8D914D013952C8FA35E1BCCEE5DE562 -:102FB000337DDA433EA4B07B1D6DD697D2CF97A761 -:102FC0005AE1F010381FAB877C3BBA3F79FD2CB833 -:102FD000D140E429B3505E92F5028BCB17FD01E599 -:102FE000FB5C976FA510663EB464709D2A937B4589 -:102FF00089D89F4CD7F3922A5FC5F54F61F58B5D59 -:10300000D7EBFFA4751DA0B4420CFEE7446E37EB6E -:1030100076F70407CB3B9C5024223EDED822F830C2 -:103020003F92F6F3523A59C0C97622B703BB0A9FC2 -:103030006D1CA4823DA899EC4EA1A80DEDBEB8422E -:10304000B33F18AF459BF09F383AC1544FAEEC6583 -:10305000EA9F3A3DDB1C57F05C667ADEBB7AB0A98A -:103060009E5177B5A97F9F6525A67A9677ACA97FF3 -:10307000DFD5934CF57E4D3798FA5FBA61B6E979A2 -:103080007FDF02D3F3CBB72D31D50734FFD0D4FF88 -:103090008A9D779B9E0FF2AF353D1F72F03E537DA8 -:1030A00068FB4F4DFDAF7C7BB3E9F9551DBF343D47 -:1030B0001F767287A93EBC7397A9FF88C05E53BD77 -:1030C00098BC6AEA5F6AFF83A95EAEBC6BEA3FCA3E -:1030D00075D4F47C8CFA91E9B94E07E3723F31B5AF -:1030E0008F777F19724FA712E59B0CF180BEF0A875 -:1030F00009CB68D2CCCE75483B962F1578DCA94019 -:103100009F8F7A1B2121A9DEDBF957389A7EA3B065 -:103110006F1CB39F3462949F7A7E2AF55BBC5194F6 -:10312000146203946E8750BA0B08582A012A591367 -:1031300021DE138565422011DB1303F15826057A41 -:10314000637B72200DCB94405F2C53035958BA0215 -:1031500097639916E88F65AFC0107CAF77601096C3 -:10316000E98161D89E11B80ACBCC4029B6F7091481 -:1031700063A906C6619915188365766032F6EB1B64 -:10318000B816CB9CC08DD8DE2F703D969704E660B4 -:103190007969601696B9818558F60FCCC7F2B2C02E -:1031A0006DF8DEE5815BB1CC0BDC81ED03023FC045 -:1031B0007260A01ECB2B022BB07407D661BF418179 -:1031C00035580E0EFC04DB8704EEC5323FF0336C3D -:1031D0001F1A7818CB82C063585E19D8846561E0E5 -:1031E000492CAF0A3C81E5D58167F1BD618167B0AB -:1031F0002C0ABC80EDC303BFC1F29AC03E6C1F1104 -:1032000068C3520BBC8AEDC58197B12C09FC01DB68 -:103210004B0387B02C0BBC8BEDE58177B01C1938C4 -:103220008AE5A8C0112C47073EC2724CE0032CC7A8 -:10323000063EC1F7C605CE625911F812DBC707BEBC -:10324000C0B25BDE45CC57F658D09FE57E6A647FFE -:10325000C18B72D2CAEFC5416E35E6FFD709BE51A8 -:10326000943452933A305E682DB461BCF026D26932 -:1032700065E7D0ED4ED04B6D579D488738DA1BC9B6 -:10328000FE0C63BE8395C701CAC553188F9A90B4CC -:103290003719F4E94DB419F28C88760EF32027F033 -:1032A0003CC89B24EA60D1A51E8211AEC27E7E1B63 -:1032B000ADCFA820DA60DABFF12A1BDE2F6A1C4CE2 -:1032C000FD205ADE93C5F2657DA94C5F3ECCCBC78D -:1032D00053D9F9CB5F0B589EEB8C5BFB317E2A4BAD -:1032E000BC80DFC4E0307420CF8F757466627EECE2 -:1032F00045BEF7A714FE1EEFBF3CB5F2C954BA0E87 -:103300006F09C9AD7304FBD1F6A723B43F03F220C4 -:10331000B47DAF85E1C3FB96C8FD84CAB849E7F127 -:1033200013DE58DE7ED98BFD82F5DF45F043095967 -:10333000C1CE0FF77E50711DD587130B4537951CF5 -:10334000E4CFCB770E3FD68FCD0B71506F8988F1CC -:103350008B194587F627D2FA8CA5F19877DFBDAE99 -:10336000122B3E9FE07AEBB217E9D66FAAFBCDF0A5 -:1033700063A6789307EDAEDB388D12CDFA8F0EFD84 -:1033800039D22B8BFBDE0693AB20FFAC386EBB66CD -:10339000F59D2F3F866836A299E89EC16B1DAC1F34 -:1033A0007C7F62B7C0BCB1BC0F852BEA7D6FACECF3 -:1033B000AB17C07957E380EE62F23AC9F9E2CB006D -:1033C0004F092E4E920E07D83191E029B8581C347F -:1033D000AE487379297E1ABE16316EBC2FBE4001ED -:1033E000FAFF91232715F843E2FD1ADADEC1F856F9 -:1033F0005C7E27F13A58FC5EB5C139BA1DCB95CB3E -:10340000DD58362C2FC4726DFA7D76889788C9985E -:10341000094CA232E6623C489FDF1A3FDB5EEC2695 -:10342000E4CB87BE1E07212411E20CD444F89AD6BF -:1034300057509FE2642AA3CF375CC71CC00F2753A5 -:103440005596876F61E7C631F97E0DE28D316EA525 -:10345000445283EDF89784ED9BC11F798374AC9F30 -:103460000C70D4D87D8C7A7EDFB4BEB81F87ABFEDB -:103470005E08DE43F02CCA6E3CB716A369FFBCC8D9 -:103480007875B9585E02D09744E9EB6FB06EB037EB -:10349000B5180B8CA7E3B74BEAC47CAA7A217CDE73 -:1034A00065B68BC987064553CE778E4214E91F4611 -:1034B00079EAC8DB1942CF0E94AF58877C2E2EAF25 -:1034C00076A46AB92E3A7EF3355C0EA427A01CA020 -:1034D000EDF75D4DD7BBD3C2FC146F828CFC4281EB -:1034E0001087792F76356ED279F220562D5734C950 -:1034F0000AE7036A1CC06B15CFD7831BCA4639F095 -:10350000AFEA1794173E961719D27FA785F3557423 -:1035100014EE4BE4F0D0DF9BEE62F2F8C1ACCAF1DE -:103520002E8C8FA8E92057697D22C08BEE3F1DF8B5 -:103530008AD6AFC5BAD25D9F8CFD5DAC3F26D25C0A -:10354000841CA6EFDD80EF49DDE3CCC0BAA37BDEAF -:103550009B719EA4EEBA079FA7B3FE173B8F5E76C2 -:10356000EFFFF74C4E7E2A697109143E95CBE65465 -:103570009651BD3D79D97C2CDF5BDEAE815C3D4E42 -:10358000E54903856B6571DF24F073268FEFEB50FF -:103590000DF43A8FC735F7AEB68E067D57B246ACFE -:1035A000DC82FCB4C214B7FBBECBCAE34D6C1D5524 -:1035B00094C7EFA424376FC3A1CB1A0CF6E86CE2D2 -:1035C0009681DEE7ACB606E99A18F853616D3B2D9B -:1035D0009E1F5D0FFB582BF2F30ACEAFF184FBF375 -:1035E0006A4AE579F40E596D239E30F2B8277C08BB -:1035F000F907E5834F1D391897A5969A3DDCB83A2F -:103600009C22CD372F42FC5787930E6FBDFDE8FA01 -:10361000210AB3AB7D2638CEB96728C62BE7F178EF -:103620003D89B773FE64FDAAE83C3BE03D49538108 -:10363000DEA11E4EBEE8F356D17FDD39381C7C3941 -:103640001CD65A991E0F81EFF10DFD62410F85E2E4 -:10365000EF62E15C6B23789FA273AB93C59192A656 -:10366000E3F8D57C7E923403D753CDE77B714F8C42 -:10367000DF42FB976C756E063FF84C89F7C14A90A4 -:103680004F9BAD98CF76F79E756FFD0CEE7D6CB2BB -:10369000E299C9FC98070AE0FCF42F5C8E5205D031 -:1036A00006DF4FF010FD4F1360FC79848D7F463F9D -:1036B000FFD81A87F03C59B6A571182D3B762FAE6E -:1036C00080B8CB893DE30F80DF3C3F9A4878979DD7 -:1036D0002832F29FD77ACC6C1F48C1BAD8B33E0FBC -:1036E000EA86F8D17C9FF59891CE176E33D78DF08E -:1036F000B218E1A59699E1A5969BE025FCD6E917BD -:103700000DF02A8BEA97047A7DBF4BC5F1AAA35628 -:10371000A6007CAA77AFC172E1B628EF31C3BC8B9B -:103720009BE34DF5DA9D695EA35EE93AF8582CD02B -:10373000E11297E83D46F5DCA9E55A3DD831A79757 -:103740008FC652C7FFE2E62CAFC3348EB9DED52454 -:103750008C66F2598D9B721E7E5DE292719E0FB750 -:10376000317FF3C3E5762FCC736AB9E265F3BABC57 -:10377000CC8E62F05AB42CC67B6C48707D91C6FD2D -:1037800067AF8F901672D44EF0CECEB9F3E8ED88C5 -:103790007249FA5446FDD16AFD3BD08D9DFEEF1C67 -:1037A000C65125ACEBE3D6368B5EC8272664BB69D1 -:1037B0003EFA9E7ADCC06F91F582F93B13FD21162B -:1037C00086F2999D8378E01C848E774672AC8638A9 -:1037D000827E0E520B13D1BE8BED1DB287367DDC7F -:1037E000D2F7BCF7CC299EB2402F57DB9B6450B672 -:1037F000D5CDFDCB809F3E6EA94F01F9B150ECFABB -:103800005EB8FB5EA5699C6F7DD64EB3BFE8D3D78B -:10381000992599F88C38BAF74DEBA722E40B8F4F16 -:1038200063F66CCDF6432387D1F5D7EC3C2B63DEF2 -:103830005A9A677C9A61FF023F075AB0ED888CF66E -:10384000A7D57BC91DE7B3EF7BACD3E132E51D7A89 -:10385000493BF0E7EC42A233EC75EF5279F3C1AB90 -:103860005602E787E42BDA8B3ECFE44FE792CA5843 -:1038700080D7EC9685287F3E786EDC01967FD45405 -:1038800000F4F131B160DEDCC7E4F7B1430CF05B6A -:103890009626EB7144BB31BF852E300DF3D3AB1BA5 -:1038A000DBE1DE988D485E2E9704F6BD1A9F80F20C -:1038B000AC9AB57B897D05EE633593475EFA1FD4DC -:1038C0006F6932CBA7791BCCF52A322905F2BBAB45 -:1038D000EEB7420611996F947F147E33D3581EFBC6 -:1038E0003C52D708F6DC2332C5135DFF6C8548BD1A -:1038F000A91E5AFCFC2305B3687D791A3BDFF990B9 -:10390000FB19F3C13CA5CF172CF3C95A5ECFFD1D9F -:103910006D19326D18C1F198DE5AA0DBAD448538BF -:103920007E6FF85776E4FDF76E11F1DCA937B41B12 -:10393000E4F39CD5E6FD5D68FFA1FB25E43EDCC712 -:10394000826DD7A2DFA6EF47C797BE1FEBB6F0F791 -:103950007C1FE4F4DA7DBECAE1A7FBDD4FA631FB94 -:103960005DAF3787D47F1D52D7E9DBCAF99BD2FD03 -:103970009369C9C0CF9D23199D74C8C6F35039D827 -:10398000AFF97CFD6C9C5F68BF5F9FAF5F5470BCFC -:103990005DE1FA2D7EFEA9E7C01F5DF0AB0762E195 -:1039A00030E803A92905F284166D5D190B703A29D8 -:1039B0007963816E3EF089A3C3C1ABB31B5E9A43AA -:1039C000A078AFD1E9BF68C504D0EF7FDF6A55C0EA -:1039D0002FACDD66F3C3F7976A5AE6E3790DAD1FA6 -:1039E00061F55578AFB276A7F53D235E173CFE40F2 -:1039F0000AE677106F6F769EEEEF0D9F0EAAD9F252 -:103A0000FE48F0936B4927D273E87B307F2001E5B5 -:103A1000F52C39AEE7733D6E5ACB9A486DCBBAB3ED -:103A20001037AD6D197302F8BE9648EF19E9A91A5F -:103A3000689AFA2B47D278DEDD95E44A902F3A3C1B -:103A4000882F19E573FD130F0D3C42D7736ACBAB7A -:103A5000B182D15FE5E7ED5DCD73FE96781EFD7016 -:103A60009AD2A9313F5E97BBEA4EBA80545A6D652F -:103A7000E522AB3F761885EBA24D56BC1FBAE8A9EC -:103A8000C77EF153C8237AC786E71F0B9FDAFFD69C -:103A9000D5B4BEF0196B5205DB8603CE8375BCD45A -:103AA000D2FFC1F9848E8705CFEE9721FF0BDAC1D3 -:103AB0003FD0F1B1F09936990CE809BFD2E636B99A -:103AC000C311062FCD4746E23DA3273E9701EF1FC6 -:103AD000EC11486A56CFF7AB37ED473B06E08478E8 -:103AE000E478EAC65B0F7CF927ECCAC77E0AC8ED0A -:103AF0000BE16B1FE8D564A4EBA777D17554FFC920 -:103B0000E60638543F7D5B2CECE78454C7E8FB9114 -:103B1000952990E7566DF5A62858B2F6EA476F4703 -:103B2000BA9B77E8F61476CF414BE3F91D69B0CF25 -:103B30005B364EC57D56110FD25FF5236225E4C179 -:103B40007C2691D1CF84E18FEA5E4CAF9ED84C9118 -:103B50004BF77902E46552D0DFD1EF35DFDE1D0788 -:103B600061E7909FF173C86B7A594CFAA59B6EB7C9 -:103B7000AC42B9FA6186960AE793140EBA1C45F96D -:103B80002A1E2A4F657862F218DFA3F4570AEDD097 -:103B9000BFDD8AE7C286F7B8FC64F32FE5F3D3757F -:103BA00047833D722285E98DD0FDDDCFF747E0C226 -:103BB0008681CE0C7CCEF87ECB1AC6E73ADFFBAE10 -:103BC0001D0DCF3FFD23E323780FF4115D973F15C3 -:103BD0009FB74D11502ED8883F1C7F6FB172FE36B3 -:103BE0003FA71209ED399D4EE8FA25F81E59905E5F -:103BF000E83C098807B457AAEEA7EF1BECEC5A98EB -:103C000017FBC9C1F6AC201FCFE3F2604E2FB33CC7 -:103C1000201B932F2A2EB0C8EAFBC54F817F29BFF6 -:103C20007A55E05F2BDEBBF968FBBEB76EA074FE71 -:103C300051B3CEB766791ACAB7D53B6EC7F86028BC -:103C4000DF7E945E47C2F26D3ABF3717CAB7E91DEF -:103C5000FF5679AAC36F5D08FCA87CFCF92E3532AB -:103C60001C43E5E3A5BDD4B0F291FEFD9114F4A48C -:103C7000439DFE74BA5BF0E4E23E2087BAE953A7A5 -:103C8000BF6EFAD4E92F74BF66F8853E9F02C94E15 -:103C900006FBC17A37F13A29BE3B778BF8BDA433D6 -:103CA0006A672CC47F5646919960879F51783D9EE4 -:103CB000D53B93E54690137A7B67148B579EA9EC0E -:103CC0008C8D37D8D7475AC55888EF76F8C2DFE7CA -:103CD000C08C443A7F4784FB1E7A3CE24C74EC4033 -:103CE0009C2F3AD307F82A171D99CBF2C10F13F175 -:103CF0003B3E73575C170BF921675AFB4E9C4EDB1A -:103D00006F79997FC6CFAB496914CE7338DE4F12F5 -:103D1000EF8345747F735A99FD3C777D783AD1CF14 -:103D2000CDAB1C4B659047D46E0DD20781E7EC3BC1 -:103D30000BD51B43DA5BC7213D2D08A1270FF78F59 -:103D4000DE047A82B8EB203288FB2716633E48B93E -:103D5000983711BECB79E6A08879EB5DAD226984F6 -:103D60007D6E177C04F8DB9B8C745943E58731FE2C -:103D70007B0AE8EE3CF7E84EFDFA2F0577D02E8B54 -:103D80009E7B77E0CF6879EAB9772E7901EACF1F79 -:103D9000CE7C9784F1B3F67C7133C8FF337B6C041F -:103DA000E32A7B5ECABC03EABB6C987774E66E9B21 -:103DB00086F6F41E27E6D19DC960F1D4FADD9F0F87 -:103DC000C47C74D2C0E8AB37BBB7D5D5FAE55FF198 -:103DD0007E6D2BDD15E8DB3D31688FD7EE8AF281F1 -:103DE000937A66F7E705C6F38BEFBA9F1A99C5EF8A -:103DF000CF38C974887B9D896771EBDA17AE7A0C6E -:103E0000F2E117B7B4C9706FA7F4B75F0F04797305 -:103E10006607B3234E5B3B1E256E42627ADF768FC8 -:103E200095C2F934D87694571EEFDD321ECE377A1C -:103E3000C285C1E10C8503EC8BC2A51AE464247829 -:103E400064FFC7C2E3ECCD30FFA2D62BF1FC210802 -:103E5000174163ED4E9F5DC0FDB3F63D9F0F0479A2 -:103E6000FC51F30AD4EF17DA77F1FF73FB16FC1756 -:103E7000B36FCF7FECBE19FD1F07FD94DC930F7A63 -:103E8000D2F9F3DFC3FAD34E37AEF722F9DFDB9B6B -:103E9000C51DFEF3F6FF2DF1BE43C0FC950BE1FD01 -:103EA000E7FFB5787F99E3DDA9409EC499DD5F67A0 -:103EB00012C3FE2FB4EF3DFFA5FBD6EDA0764B9DC0 -:103EC000924FD7F70E699A9A45CBDF699F2481DB21 -:103ED0006A8B704E73BA37F32B6C02CBFB265305FB -:103EE0003DBED46ECA7B4AAF467B6382760FFB3EF3 -:103EF0009354D70E79A7ED2573DC6BB1C7E0B73DBE -:103F0000509F329CD7CDFED684927107C1CE7B6381 -:103F1000055D1FE4F965480ADCE598A8896817D2B1 -:103F200012EDC137334762BF8985667FE3FA103FE0 -:103F3000E1BAE9E6E753F9F8D3C87DC910A79B3683 -:103F400097C5E9AE23752B8DDF519B1A32CE2B100E -:103F50004033D891DF147E6ABA0EBF25080F52ACE9 -:103F60009FDB5D007E84C1BB7DCA20965F2CB919A2 -:103F7000FCA62D7663DC94FBA156FEBED5B1BA1D1E -:103F8000F8D64ACCFEA7EE475E08CE84FBA7385E83 -:103F90007610EE564D44FFD4302EC245C7C737C504 -:103FA000838EBF6F8B8F2EC087E15C572FE7DB6757 -:103FB0002D8473083BE4BBD37D4D5CCFEE8FD8F3EB -:103FC00004846365A115EF4DBE6FA92C00C3B962CF -:103FD000C895353F64C3BA013EF3391CAB481DDABE -:103FE0009DE4AB73E78A0AF0F40FEDD6F91A21E3EA -:103FF000A95F525524F8A3E9BEE749C41B3718E26C -:10400000A00279CF1807F599EBF0774D4A709C0B19 -:10401000F58F241FFED9E5DFA83C7A8F22FB089498 -:1040200098374324A3FF38B395C1B17691E0CB46CE -:104030003AF25B8DE7BF0FA4B378E3DFEE1C827228 -:10404000AEF8C703E2985F9B8FF93CB5DCDEEFF278 -:10405000AA7110CFE96AED1B07F19AAE83A5B1E111 -:10406000F2780E71BFF20FCBED589E29139AC43827 -:10407000BC773201F570591401B913FADEEDE97A13 -:104080005CA68E9D4B1296875FC5F7318FBE1A973F -:1040900060C0DBFAF11F48037BE201FEDE339CAB1C -:1040A0007C57F8821F0B703D14D53132DCF709576D -:1040B00071F855ECFD4286F8C1A4D62CFCBEE4A4F0 -:1040C00032D194A7BA3C9DFB5343C8105857C5DE64 -:1040D00031B157015E0E8AEE280ADFDAD6B3B22775 -:1040E000CCF95C283C617C88231FB5BAAB009E47A5 -:1040F000EF89C2FBFFAFF3F3A23CFE5D48F87410FA -:10410000C4CF9AD2593EC8FBE92C8E3EB9A2D89AA8 -:104110004CE7CD6B5106415E592FDEFFFD74159FB4 -:10412000F7E6EFE9FD7A2D62FD8EC84A4DB8FDC76E -:10413000640AFC3CC4FDBD42E13F0F6FC53F76FA07 -:10414000E15E5C5799C0EFCD84D23541FEE81A2D6F -:10415000F840FF821F8BF50A01F5FFEB7ADEDD24C4 -:10416000A62F75BA0F85F36E0E677DFEBFF0FA5E5F -:10417000AE377438EBF00D5DAFDE9FCAAB11C67879 -:10418000CBC49D839E06FBA4A655502C74A81AA9E7 -:1041900043063EACDD79AF15CE17AEE7BFCF42A4E4 -:1041A000CA81C6F3DDF7D3D9EFBCEC1B3C0CEDC7DD -:1041B0004FD633FB589B7B3616ECA0D72DEEDF0D88 -:1041C000037E7C43347DD73CB47C77B9B2A0CC6A03 -:1041D0001C370BD7397951B115C243372E6AB3A6B4 -:1041E0001AE8E97DC8C31A1A6CEFB548C5FC453A10 -:1041F0001FAEC3FB231B817C8CBCE6F69218FAFC35 -:10420000C6BA784687D5CD6D32D6D97786F5F9F41A -:104210007942F9694A458CA93EA7B4231DE0526151 -:10422000F32F7587A1536F867EAEF20DF58446E9B4 -:1042300076E0FF0F7AE2ECC870DF419D98D1433FF2 -:10424000A486D30F4B56A8A900FF25BBFBA602737B -:104250002C79B93C259C7E7873393B3F3CCCF32EBE -:10426000CF4CA1FAE10A837E981285F411FADE554B -:104270001917A91F747CFD9BE5CC9BA01FC2F0758C -:104280004586593F4C6B9D85FA61DA1491A8867872 -:104290005C69068FDF46D40FC529D763DDEA8E0936 -:1042A00043376F72BF04E00A25CC037AE28E0C26F6 -:1042B000F743F5452479AE5CAC3CFF5F82B32ECF6B -:1042C0009750FF85FD0E4E281D1294D74BAE17F068 -:1042D000F74B96EC66F27CC94D3C2E19225F2B41C0 -:1042E000BEE61BE52B7BBFC6C3F441EDCEAC8766B3 -:1042F000D0E7373459DD76DAFF86A0BC2D30CADB33 -:104300003B32241DCE994A18FC4E9F114354B3BC36 -:10431000CA01397574D04B79CF02DDBFCEEE99BD9D -:10432000CFF5F86B835ECA8778FAEFF9B89B391D31 -:104330009D5E4E1694513894CE65F6F0E2ED22C2A1 -:10434000A1A685D97935DB04BCCF3B72F017786E16 -:10435000B870373B3784EFF9161BF0B8F0F58EC60E -:10436000DEF07C9380E79E55EE85ECDEDF061627B7 -:10437000B6D3FF205F624D74EC6682793A1AC69B11 -:104380001773B855D83A0FC0FB158F0BEE4D28D7D1 -:10439000CCF1E9C539633F00BF60E1B69076F71A0A -:1043A0003CCF580C7167831FD2C6F7778BE8CF7B61 -:1043B00016F2027F2786FDBDB3B65038547F4738CA -:1043C0001CA270C8FFF670A86DBD17F36FBEEBFEA0 -:1043D000F76570FB7030C9077E79DFA221FF7B5F34 -:1043E00011F15EF1DC7BFBA51AF3940E6530BBE2A4 -:1043F000758BA7310DFAD5B0FBC7F3363EB31FAEB0 -:1044000086CF682683206C3F6F83594F76EBE51685 -:1044100015F5EE8CBA6704F89EFF2D22C1DF019BD3 -:1044200033D8E681F3D743519D28CF743AFC12E884 -:1044300090C2FD0B3EEFD15E9D65E857EC1414E48D -:1044400013F89E06D4291EA2603F577D3E92C31DDD -:10445000E333B53B199E6A295E80CF46527B17F441 -:10446000C88D54EFE079596B9B15FA57D37E892894 -:1044700077DCE8EFEAFA09CEEF8A530C78DB7D842B -:10448000D1EF56C14DC2E02D97FE773EBC45C29795 -:104490006E3F5C2CDE74787CA9CB6F8EBF4351EDF0 -:1044A0001543F09C8AFD0E10698DC77395634D7D91 -:1044B000118F519982E9BB32DD7805FD68882F5D47 -:1044C0000B0BC70FD747619E1CCE9BCDEC21A37C65 -:1044D00009F5A36B493BDA35629AE7E174435ED88C -:1044E000349EBFD27DAE1BEC37392339723FE22AAE -:1044F000C1F31F3DBF167E390AF3C1787D5F46C107 -:10450000E11974BF9FAC16F17EF27516F5AD22E08D -:10451000E3B5560274F9C96B568DD9A13128876766 -:10452000BD7ED40AA19159905F40FBCDBA8BC9DB07 -:10453000A330186DFB13D5631A7CB784340F85BC88 -:10454000FD29EEB672C8DB9E9A7F68259CD34D2E5E -:1045500055DE7A0BE0BB462400DFF75697A2BF7208 -:10456000DBAD02D2F5DBCBF1B7B0C8D429596FBDB2 -:1045700045E7BD6975329EB3CDD0F69703BDCD99A1 -:10458000E874C039DDB85C91780C70BC89B463DC28 -:104590006246DDAD5361BDD5542F40DCB5BAF55050 -:1045A000792AD4370AF83B6AB55E8F0C57A0DA3700 -:1045B0009C9521FE5245FB017A6A37B27EB55B04B9 -:1045C000BCDF5345E503ECAF6A8B40E022493BB5C5 -:1045D000FFEC6C5C9F9D8EDBBE91BE4FEBF3E07DEC -:1045E00018774B3CFEDE5DED6BEC7E5055E18A03A7 -:1045F000209FAAE87BF43169DF722B8E377FA340BE -:104600002035B8BA30EB478530DE6B56FC2EC8E15A -:10461000B6876558F7CD74BE343AFE1CB1A31CF3BF -:10462000ACEF1014CC83FEEA07C80767381F90D799 -:1046300096313E13789DDB85BA7EBC37339BE5BB54 -:104640002F5BD108FBEAF02667814B54BBF3AC0C1F -:1046500076DEB1E5F0E1198A379E07B7CF7B54EEDD -:1046600030C8A9A733FBB2EFE4EF2C463EBF855418 -:10467000E2B9B86705D3CB475646F904B047AC0A50 -:10468000EACD7D2B2F7D10F67FFA292B9E979ECEAB -:10469000E8C0F8EC898D56FC6E48FD4611E5C889E6 -:1046A000ED2C2E243E3275641AC08FCA01A0BB7D4A -:1046B0001B4B659087277C02BE5FFAC8ED292CEE64 -:1046C0006B961F55EA0294178F4431F9306F43F807 -:1046D000F3D588F262E94826DF43E4C1E2F4468C70 -:1046E000FB85CA895AE2D0E5C360A8B7FBD3907EA8 -:1046F0006B5EB312B0EF6A24E5E60D403733A2E0FB -:104700002499F2857F3FC8B74F7C82EAA5CF6F9C82 -:10471000F99BA100BFE3006FE08BF58978BE5AE5F5 -:104720009B8570D5F311E76D30D3B39EF774BD4709 -:104730000CDEF3A1FFBBB13A8668867E87EFA274D8 -:1047400049E79BB953C0EF211DBEEBC881DBF3B134 -:10475000AE001DD62CE37A75BD13E9F6F00FCEAE90 -:1047600004BABCF94E01D74FBC9E46D02B351B0472 -:1047700015E29AF3EE64EFCFA3EF03BD1C7E98D150 -:104780000FA56315E8BC66E3BD07B0FF164185F1D0 -:104790000F6F9A857AB8DA2B127CBEE508DACB5413 -:1047A0001F60DED03EAF9802745ED3605300AF3A14 -:1047B000BDE8F477847F7F9AD8DD0327C3EF536485 -:1047C000AAECBE7C08DD89D3B390BE6AB75B915E6C -:1047D0006ABD8C9E8E3C25221DEE5B79DD48A09F34 -:1047E000D35B8508F447E92B3F485FE223567C7F83 -:1047F000DE132CBEB06F23A3EB132DCC3E2D7DA476 -:104800001FFA35F35EB712167F200EA3FD71213A11 -:104810000CA5BB1E7A89D36124BAF3589BA741FE2D -:10482000C1ACA7E9FAD520BC4A1B7F807180D2C6F3 -:10483000EB71BF3AFFC0BD16C8DB98DBB482E5332D -:104840004A2CBFE71BAF2B641DCB339D41FA175990 -:10485000FE899FAEE3A5ED8FA11DF0F12F8F607E45 -:10486000E3C21728FE69FFD3DB9DC48F76B60FE540 -:10487000CC821611F34B89E42F986CB8BFA5E7657D -:104880002CFC9513E1BE6087CD5741DF5FF0DCD192 -:1048900081784E7E37B353BDBF64DF9921DE8E81B0 -:1048A00093213F5362F921A1FA3790C9E230A77EE4 -:1048B0001383DF6312B6B5E139D382E6EBAC36433E -:1048C000DCF24CA615E7A5FDD83D338A7F385F841E -:1048D000F5197F4F42CF0B39F504E39F053BAD68D7 -:1048E0001F2DD8B609E37DB5DBCE62FE6CE9AF9E25 -:1048F0008A0538D4EE14CDF953DB44BF0DF3BCC4A4 -:104900002336F65D0E531E534D0BBBDF51D3CCF354 -:104910008442F26716FE6AF7735E0A9A85CF3E1EDE -:104920000BFCF461FBD65880271D0FF38F2616462B -:10493000C84FBA505E52F31A9E97341E7FA7233495 -:104940002FE943F807D5E3997D42F2BAB631B9456C -:10495000B15F10EE1E926EBF2C7CEAB347218FF63A -:10496000D48E8F1E85F52FFA9F4F1E85BC0EB22761 -:104970004A017BA2F6976F62FEA1FE5E611F664F41 -:104980009D7EE271CCDF3CFD8E0DEDC2D3BB4F644A -:1049900082BD70FA992F52202F73E9EE728C4F2C42 -:1049A000FD7529DE0F8DE46F027DFA2E227F34140F -:1049B0001FFB5A44BF83AEF3E3B76DC8FFDD7966D2 -:1049C000CD8B59FE9ECAF3CBB687CFD3D5F3A16A60 -:1049D0005A264F1C0EF2AE85E9F5EEFCA80BE595C4 -:1049E000FD91E2F58A8BC0DF769E3FD83C3E6C5E3F -:1049F000D9C7F00F8AA76921F8FBACE5969FFF1491 -:104A00009EB584BFA7ADF3F585E0A6E701F7EDA35A -:104A1000CDEA037CB4E349CCE303BC55A8A0FF3F37 -:104A2000CB84F8E6496B27C60D3B77DB14C8F75AF1 -:104A3000B0FB30F2CBE95F1FC23C5BC2F3714F9316 -:104A4000EE3F9637C96317B55B9C2C1F8DC31FF2D1 -:104A5000D5D4586CE779698C8EF57CB548796A0FA6 -:104A6000F5C966F1439E9FBC586D971547105F804E -:104A70001FA110F075C494FFA7EF3B743C05E070D4 -:104A8000A531FF32523E20B7D37BE08BC9E5D39BE3 -:104A9000783E66779E2521E983213F88E9C35A9FA6 -:104AA00070381C7EF5FCCBFBFA70BF53E74FDFC5B7 -:104AB000E55D5E78DDDF0E2E0D7DD8FD001D3EA785 -:104AC000BE0A2FA79FE2FC4EFD96ED7D0CFECD4C5D -:104AD000EEB7E87967FA7A1B9B995E3EB58DD98D62 -:104AE000A1FC5D13E1F7B45EE8C3E20D353BDB06E4 -:104AF000821C3AB5F7379CEE7CFC1ECE11D9CBE573 -:104B0000B6CF28B723FC7ED97E3E1EF577C38E57DD -:104B1000BBFD6CD8F13E94B4EB60FD1FB6333BE4B3 -:104B2000C36631ECEF20FCAA8FD5E407363A65F472 -:104B3000BBC4D86894474B9D856FC377DD963A65B3 -:104B4000CC77A85FC1F323EE72E3EF78D43BC7E2E2 -:104B5000F74B57027C0C7EA855F1E0EF4E585D955F -:104B6000F9E05F85DEEB94932CC467C4BFE4C5FB1A -:104B7000BD13B23F9740EFB42F37DF1B699794FD09 -:104B80008974BCF632C10DF66E4F3A338F7FAD2675 -:104B90009AE26710AB867D75B9D9F7D09C16BF42F3 -:104BA000BB106754BB0B1D3D95FD5E35FC4C179C3F -:104BB00083AF5D6ECF817B5CB1C48DDF1976BABBEC -:104BC000EFCFE0787124246F9BFF5EB5830B95389F -:104BD000A2B441DC223A97FDFE8342A2DDF0FDA2A1 -:104BE0009FC46A78AF69BDD3837A3822DFB8D9BD54 -:104BF0001A3D9E1457C8EE51FE5FBBEBC4160080F1 -:104C0000000000001F8B080000000000000BB57DB5 -:104C10000B7854C5F5F8DCBD77379B6437D9900421 -:104C2000C2FB6EDE0921591E09A82837E16110D0A8 -:104C30000511505137E1FD4AE2A396AA9505621A83 -:104C4000296D8380528BBAD050FD5AB480B4828DC6 -:104C50007603D162AB36A0566DD52E101194C70ADB -:104C6000948FFAC3F29F7366267BEFCDE681ED3F0A -:104C7000FDEA30F7CE9DC779CF3967660921E40A8E -:104C8000FD7F92A6B485EC04FFA09E4C747537FCA2 -:104C90005723A4373CA77F2A211365072123E977EF -:104CA000132C811809DF4FC9A2EF1DEC1392944A0F -:104CB0003C41783FD5E1F1D3F60E876F0A49206475 -:104CC0004382F6A6444BE2518E8672A12B955C4935 -:104CD0002724B120E4B7D0C789A3E973DD3CE89F5E -:104CE000E475E2FC8E9AE677543FBFFEAA33E5787E -:104CF0003CAD2844B922D3F1ECAD84D0D2E951CEF9 -:104D0000C13891FEFC4429A1E3F0792612FA9EF6FF -:104D1000E396362A57E83A5CC425910C1CCFF4DDA3 -:104D20000017F60F75DAEF5EF8C73584F45BA6B6A8 -:104D3000D8E83ABD76C90560E843E7DA0A40505A38 -:104D40006D008CA71CA21EB49102DA6ECF215B8885 -:104D500096CB771EC2F716A8D332395E1DDF7F18B7 -:104D600021930359DEB43C68579166F160BD554903 -:104D700025A46E9A2FCD320CA69FD5D0328090E715 -:104D8000494DBE44DFDB6BDDAD07AF27005A3A1952 -:104D900078EF6ED50AE03DAF131224741DCFC7B56E -:104DA000D7357B1AADA7B7D7FD506F04E05F0BE393 -:104DB000B95B6BE9F7BB54EF44958E3BED190B9152 -:104DC0005208197BC91190800E42BD08E90B9FD58E -:104DD000C4015EAEC0DFD84809F025A99176E6F798 -:104DE000E676749EE53BE9FAA7F92ABCE347103260 -:104DF0004A627025AED088E94E9847E56CB538F226 -:104E0000DDB467CEC9E9747EB3294D11FA3CB1DC3B -:104E100075532E9D5FE2160A2D15DAFBEE82796737 -:104E20003DE2B300798C25A1FB258A4FF2490ACED9 -:104E3000478C53F79A8CF45BF79825B01AE957958D -:104E4000BC43F5F80B99F01766F8DB7B04F157D5F6 -:104E50007484E16FEFD666C07F5593E48A51613D5B -:104E60009E5D9488C8FD816BBCCA408AD798701D2E -:104E7000E0D54A4679A7C4225CEF85F574802B9F64 -:104E80005F77707DFEC4B61F17D2A6FE53164F166D -:104E900089C04BB4DBACDA102E7DD27D8F021CAA08 -:104EA0003786EA62E9BC5E3D7138C147E79B75EA27 -:104EB0005CB090CE376B0CB271FBB8CF9FDAD66C7A -:104EC000A3FF7C1EE898BEC826BED52E4757F060CB -:104ED000F4DD0E8F3D47103E16A8D3E7BB6D64117D -:104EE000E0B56CAFA40580BE63C83D5E5AAE572DD9 -:104EF000B88EEDAACC4B89E1F154BAA2D2EFCB66C1 -:104F000058B4002D137919597F2DB6DBAE2A580AF3 -:104F100078087C0A3A22A4217E1AC5635A8EEF597A -:104F200023DD3C119F4EDF8F6D3B7A3FB144BEDBEA -:104F3000BE9278E75923ED28FD3C6CF86EC2F7E28B -:104F40007C0591F64097402766FCD0EF7630BC3E5A -:104F5000110FEBD8D7764E0678F714AFE6E7AD2BF6 -:104F60007DDEF1D6CEF9C75B2A7B01AEE6E7418054 -:104F70002FC2C7EE6FCB05A92D91440A6AB9AF2F96 -:104F800008F35B6E0F25CCA0F8AD2A3D6F0338AC5B -:104F90008E3F739D2F4A3F9DCDA3F5728EC34BD795 -:104FA000B7FF520CC2DBDCFE2B8ECF7757CEF68ECE -:104FB000A704FA785C42210A5B3F793F93EA87F1C4 -:104FC0005CEE8ECF5C3285092DC5CFE5B8742586A1 -:104FD000A0425068BB09F084CEAF7CF42E85A44378 -:104FE0009DB613F2D88DFD6E2345800F6B1B3CB729 -:104FF000D3FF811E999C79D349D02FAD4A684D22A9 -:10500000057D6B9A84FAE7C6CB0D2DA0BB6E4CB321 -:105010001AF4DC24D5589F0C7A4F37CE348DE29D9C -:10502000BF3F8FFF0DE0FA6E56296869FF3767C6EC -:1050300005FC74C9B78CBEDD3B5EA72F0E7D2BDF50 -:10504000E32DE8089FD16E011F2FC2F595580A9FE6 -:10505000225867452DD3495DC3C30C47335CC67FD7 -:10506000B2600A29EC08979EAEBF1DAE84FC04D640 -:10507000375993C95A7704AE66F8D0BFA9D0EE501D -:10508000296D27815D704AB1D0FAA46B2422EC828D -:10509000097ABCF3F999E16A869FB03726F3EFDE0F -:1050A0000678517A9A2C6F71003D4CFA61EBF864E6 -:1050B0002AC7260D64F825410A5CAAD76F20083359 -:1050C00080EB36A43B9715ED0CAAD7197D7C32F105 -:1050D000A444C79F7289BEA3F39CA84A01CA2200B8 -:1050E00097A326B81C35D1C551FDBACDF37D05FE79 -:1050F000714D147A511A7281EF8BDCDC3E1944D465 -:105100002B541F957C3C3291C987E87A72EC256F4D -:105110007B3F0C1E0D483712F1B53F77D17E829A46 -:10512000358582818CB3BB904FC6116D4D9B1D4060 -:1051300021E33CC5BC4EA6793537FDBE944C5AD30D -:10514000A687F327429F33788FE3F01B47FCCD728D -:105150000294CA05FDBA457F93C47A0693C1600FD5 -:1051600035AB2AD3FBBC3FB1BEE4641294E804C360 -:10517000923DB04D82F913BFAD57643C2BC7EFC7CA -:1051800099D36F75A3DCAA21002F305B009F65FCCB -:105190007D99DD1184F910BBF5543B5EC086217307 -:1051A0005CC787205CC895F8C8FC2ADC92723C3743 -:1051B00032BFD307ED7E99D2B5A7AF6FBE9BCEF3BA -:1051C00094F47621C08BDA65D920CFCDEFCF7FD490 -:1051D0005205EF69BB05D88EAF6BA92C21DD845F2A -:1051E0008B096C734793E7AB98FCB5534BB42442DF -:1051F000F765718CCF2713AF02F6E5FE58C6672D11 -:10520000B18B911F26929ADAA1B4BFBFC4DD78108A -:10521000F86C12F163BB092E231D7647A73791F076 -:10522000DD60F74ECEB59AEC683FE2677F6C4E26A4 -:10523000E8B3FDB14C2E0BFBE149B7778D1BDF0FB7 -:105240000A805C3EAA15BF0B7AA2B274C4DF46D2B4 -:10525000D262F7DA009FF381BE285C47037DD16FED -:10526000F743D77D91BED601FEE6D69BE8CB9E8C58 -:10527000FD7BA91883799569D66FF476753BDCB808 -:105280009EECCE5E242D0AC9A5709DC7E9747F6C83 -:105290008C1FECB8B2C7291F53F8CD25BE671B245D -:1052A0009887D560BFCF8BB5A2BD37EFE7B1C8EF08 -:1052B000F4E32D3574C805F4F95ADA0FC95507E837 -:1052C000F53A69D07D0FF8B7AB488FF35CEC591B0A -:1052D000EDA36F2FE8974A370A4FB2D97A4E4F970E -:1052E000E6F13BEDD7F4DD7E89CC06BDBADFAA0E30 -:1052F000F0E8F4C76E37B39BCED9B3B658D23B872C -:10530000D3027BB2A68C88D48FC7C6CE8E66278880 -:10531000FE045C23FB8B130D2D6322FB0BCBAA2F0A -:105320004CFB8B2FFEABFDC5A1AD5FB4D6D2F934DB -:10533000647AFF0EF446146F1EC07D13B71729A5BB -:10534000E44DD3E1E1EF6E66CFF45E318E1CA3A491 -:10535000146327FED8E194DF15E2B70E87F6BE5539 -:10536000168A57653641FD43E50DDA99E6F57E9CD0 -:1053700059F6198C27F8B02C8ED239E5BBC72D6AA7 -:105380006303D8D37F96A96D49475F3117EDBC5BA6 -:10539000572CC6F2ECD1CBD9C0FF651CAEA7417F1C -:1053A000835D1DCFF8A73A9EF1CB2B69BED340FF9A -:1053B000AD9AEC1C49FB5BBA57F6C4E0F2C38360BC -:1053C0007DB74E9553E1F931BB15F789FB9D0CCFA5 -:1053D000C78854BE13ECDE4331DE3DB45C9056EA20 -:1053E0004AD7D9830BD2C6639D9453C38ED2DF7D37 -:1053F0007646F7C7889BCDBB5EF26CA78FCED5BB38 -:1054000013810EF75B89C1EEB0A4337BD992CEE055 -:1054100058798932E108465F3574FC4A45B5819D6B -:105420005F79C986CF611E487FB1C67EE2793FF1C0 -:10543000EDFD48E80CD81F6BEE4761CF391D9BF19D -:10544000F0A87B5C22AC67419AE64A4779AF2A0014 -:105450009FB2912D1F81DCEB5ECEFB2590F3D5979B -:10546000A5E060BAFE537BACB87F3BC5EDFFD37BB4 -:105470000EF4AEA4E5F25DEF25C03ED19DCEF075F1 -:105480005A694D80F92DFB1DB59B0B906C7BDF8914 -:10549000DFCF2D59CB86B1EBF5DFB5DF660CF062BF -:1054A0003B3AC19288FD35CEEE0FC0FCF6AF926755 -:1054B00003DEA87E14F69704F270C21E598B2DEC01 -:1054C00068978D4AB7727E63787CC0C5C6E98C8FB9 -:1054D000CB2EC593808E8FCB145581F9975D4AC032 -:1054E000E7A74F6CDB7033A57B7F9A15F781747B40 -:1054F000D48276A1C4FAA56CDD9249C769E1EB7943 -:1055000063CFAD33AEA3FF7C13F40C6D333EE44B9D -:10551000614C4D777125113B6B82CB680F9AED453D -:10552000A1B7CA9BD6D7F62700F7C0ADD7011D9EFD -:105530005008D061077BDA7E632776E37A84C7ABB5 -:105540007B7E89FBA53EE92AE3AB3DE727021D5799 -:1055500091E04CE8B76A8FEC0AD2D66F903D434099 -:105560007F08FDDEBEDFB97CC0EE01F91F2BBB5604 -:10557000C33AEDB739540AA7EBCE16A4A09EB35B8D -:10558000CB41FE95C56639E6EAE8797F8A5C0E7400 -:10559000F0464A86F1B97DC310D073FB2C4C1EB582 -:1055A0001CBFC311C276B7A6A0BD26F4BBC93E1569 -:1055B000FEB0495972209ADD4BE42D1B63E9FBC90B -:1055C000395622839D1E5A827ABF837EBFECC37DEB -:1055D0008059CF0BB8534823BF74B04F237036D8CF -:1055E000A98FA6533B6D08D2C050B03B8397372C90 -:1055F00085799E6D8A77AD46BF03B36BCEB62DD944 -:1056000030159EBF2DA31FE5EC6519F969FFEB4B23 -:105610000787747C4C3505E2E9E2B0AFCFFC81E24C -:10562000E7E2E7711E3F3C56760E89B62F16FB2542 -:105630003A723F4B1ACEBF9F6534B21BEE4F6F8854 -:10564000EC4F37A6E3FE343C11D446DA962336A05D -:105650008BD3D45487F9FA29F2B753B8DEA0856406 -:10566000976E3E2FA44BDCDFA13D0D72C54FCAFAE9 -:1056700053E3842C8AD34AAF03BB731A716DA3EB37 -:1056800079ED449964A5F531DBDD1E89D67783E198 -:105690000974FB3B39B09DC2613795C7BB69BF8BAD -:1056A0005B1B6C6E3AAE7F0F9DD4285AA7880438D6 -:1056B0009CB0FA0725E9E8645606932B27ACBEE7B1 -:1056C000A09F131FC710D8079EF83C2EAABE1D9C92 -:1056D000C1F4ED1FB89EFB37A7F7E0A957DFEC47F1 -:1056E000E715BCE41A06705FF2C2D772051DE77AAF -:1056F0006E974DD9D85A0BFE9B9BB78415903FDE11 -:10570000806B02A8DAE92F78ACA09766ECF05AC15A -:105710000C9FB9A7C60AEF67EF6D7803EA770477A5 -:1057200062FD7CBAEF8F00971BEAC307805C321BD7 -:1057300088027C412E307BEB533E8FF44B9EFD89DB -:1057400048D5A516A0F3F6F11F6955C0F4B9B9966E -:105750008D4FFB7B0BF074434D781CE8B7412B5801 -:105760007F8348F3AA4435D2EFD8CBAD92DEAFF0B9 -:10577000EC438E454CEE32B80F7AB8DFD6B5C82769 -:10578000AE38D0F782AFCA1E766880EF8B3F880BA9 -:10579000C4B881CE98BD7DF1078E803F8ABD1DA122 -:1057A000B3600CA32F416FC4CEEA9A1DE8EDC12768 -:1057B0006BE2407EA478559B4F87C7B20D53F2DF52 -:1057C00082FE6363D07FD73EDE7A361EFD3E1FE841 -:1057D0005AE8B34AA007835F4AC803C617B48B00D0 -:1057E0008C2B4A22AD76117D9D04D3603E9F03DC55 -:1057F000E9778D36750E8CD71817E382F12AED59AB -:1058000036905FED7E5070265239721DB73B5F3B7C -:10581000B13F19F07E71D8AA41B03F085A7E81F29B -:10582000AA3BBABB2D5DFB0FD3B7FE41B0BF12ED53 -:10583000F71D8F2B007DF9079077801F4FC56058AB -:10584000AFF8AE7F06D3F7945F70FD824F525A894E -:10585000B6B50041A5EDD6C1A337E70B51EEB6AA08 -:105860007EC667D44E01BE7306ED19C0CFFB32B0C1 -:105870009EE2250E0F7D5FBD37CB23AB28077A67ED -:10588000A446E4C3F55C3EA4B486912F7BBA4FF8DE -:1058900096C337A8ECE4FC45504E017F31391EEC2D -:1058A000CFE490BF3FE005E406C74F5F89960B3910 -:1058B0009EC5BA53B85CB84EAC0BEC375A2FC960D2 -:1058C000F247BC1FC9E136412E480C45F1FFB4D365 -:1058D000DD8ABE04ECC9092BFA635992C1E6BBD834 -:1058E000BE1EFDAA8B53D6A33F35456BC072F1F89F -:1058F000067C9EB6A502E963F166C9E01F15E5CFF7 -:10590000B87D76FA8405F51BB1C4F503FA13EF37B9 -:10591000723BA44FBAAF0CE07C72CF86270BD588C0 -:105920007FF8626CC3CD7700FD6F975DAB003F8D54 -:105930001324350A5DE9E107F0AA6EFCD744985FAD -:105940001509D5817C569B24949FEA5E5AF6A1C422 -:10595000DFC8E4E9496EA72D8A33DA97B338DC4E05 -:10596000585B2717D1F183E73287835F27A88464C8 -:1059700085E18F007F801C7621BDAF1DF410D09192 -:10598000E444FB07E4EA2E1D7D2CDDB1B5AE1FFD1E -:10599000E70D975DC364EC8738F4F25BD08990C75C -:1059A000E6F52DE6781574785D444F2DCEE07E54F3 -:1059B0004059D5FA73E8477D94E3AF11E80DF8B983 -:1059C0005ED0DB300BCA5B131F8FFA1FC9F77D4F08 -:1059D0003C3D08FD13A329DF52BE3E097C1D852EE8 -:1059E000EADAE5806F5546147D7052F23D979C11BE -:1059F000F97EDFF19BF22B75FDF8383C2E5A7D8342 -:105A00005D51E015812BE907F4B0886206E040B6ED -:105A1000482EB00BC5FB942D2C1EF014E723F15C2F -:105A2000D405BCC702BC3310DE4FC17CA95D600346 -:105A3000959D16607601B1DCD40FF4FCE238ED26BA -:105A4000F4C7ACB710F02F11A90CE93DA571D3F143 -:105A50006F4742199B8EF1156A77031D2D7E5CC539 -:105A60007DE2EA5FC5225DBE98918EEB5ADD6865E6 -:105A7000F4696D40FA3AF9F992C1109FF153BD9E55 -:105A80001545EFD499F4F943194C8F0ABA4B5FC707 -:105A9000E8AE51D1E2927474F93CD18683DC167A77 -:105AA000A5337A8CD0916B98A0A30AFA3CBD3E2412 -:105AB00003BE281E5F053ACC58174679D6191E45F5 -:105AC0001C4EE053C8F9FFF0F98BF1DFE6723E851A -:105AD000DB3B1DF1BACAC00FD747F8E12F0C3F11CD -:105AE0007EB0AA91F5FC9EC3A533BEC8CF7461BF3A -:105AF000759F6EB81BF8B96E7D9C673589C4734479 -:105B00009C55CCE3334E879DC56376A9BE4F334C7D -:105B1000F14215E53D8BBF4CE076FA7DDB63D0BEEC -:105B2000D807AF408EB4C505C0BE14DFE528445386 -:105B30008613F255861BE79F032284D65356D84816 -:105B4000261DF7E235CD2D09B4FDD470684A115DEC -:105B5000E23E5B68C62DE01726DA12B033D0970F0D -:105B6000F47F8AF54B5C3B0DF3FC1787B7C04FDD24 -:105B7000A773D3A2C50B041C3BC34B7E268F9FF19A -:105B8000F766FE6F15FAAAC7FCEB4F04FEBD81F85D -:105B90005741FC845C262ED0D3EDFC7B99B0F85C99 -:105BA000A6917F453D0AFF2666EAF9F75288F12F54 -:105BB000E7D3C446AB16CD6E19986965EB6A9C5065 -:105BC0000AFA28D14BD06F429789FCBE98F23BF07D -:105BD000B11FF8B60FC093C9DF74ADE16E789FDED8 -:105BE000C8ECF18B496CBD8BAFD79A65E07FBA1FCB -:105BF0009068D306CEEF9DC33D982831FD9608727C -:105C0000E68631A171A08755881BF481F531FC8EA1 -:105C10001D4302418A77F53261F2E3F3A7EF7E0874 -:105C2000E4C67A87274B8DE8A54FD37DC332533B1B -:105C3000E76B4A971AF8B1EEFBB783ED1F3B899FDC -:105C40008F5D2123FD513ABF365307FFB1DEB00C03 -:105C5000704D8EF7A55993E83EB0316BBA7D205D4B -:105C60009F9BDABDB45E4EEBEBC02FD72B4478FD83 -:105C70000947DFFF224F2033F330F8F1966768932E -:105C8000328B31AE3D19E67343FFB08CF2AD87F134 -:105C9000FF6AF0EBD1F51CBD2DFF5715F469E5ED5A -:105CA000DE3A782BFCCCA3B89FB9BA6918FA9F7575 -:105CB000FEE63B60BCCEFCCDDD8D9BC0F99ED237AD -:105CC000EEFF12468765908F42AE2CCAECC5E939CB -:105CD00044A60F8DF017C825B077451E02F8239D06 -:105CE00018CF0820FD413D717844DEAC6BB094477D -:105CF000A3EFEF673AA2CA53D2F47FBF7FA884AE66 -:105D0000175E31F9FAFD4C9D7C6D6C38DA9BD9AF8A -:105D100054FB537BE27EEE03D8B0DAF3D74CA0BB42 -:105D20007765F4C35C1363F34BE02FD088EAEACDC8 -:105D3000FB03B66B9282CE425AFF46221AF837BF57 -:105D400091B1DCF0A8B7DC0DFE968F2C287FABC09C -:105D50007EA3F0193D9804ECF49F7BB9DFB4F4986E -:105D600043833C81B3921DE5E7D923717ED0AB67B5 -:105D70009D16F4ABB7BC16837C713E338EFB41029B -:105D8000067F8988F79C7F7B6E32C8FF2779FCF3FA -:105D9000C958E68F7DF2F66CF4630A7FAFA250D843 -:105DA000F782B41E0AD75E6037F7473FACF0FFF6C4 -:105DB000B657482CE9888DA3D8D9FA7A2B3E09FC2E -:105DC000E75BBBC997F84DA64DD8C38D00E7EA47FE -:105DD0004236D8EF0A7B58E8EDC1A7D29B216F620B -:105DE000703973AF6D3D65B1C03AB752724A727780 -:105DF000A42F41475B3BE625ECCAD4EBA7C7585E0E -:105E0000427B9D7FF71CCF4B18DB76F465B0F328FF -:105E1000BF6F357C372135CE17456ECD5CF1307EB6 -:105E2000DF19FDCFB4105F343DF21ED72344A9E93A -:105E30000F7A8AFCF3C178358A3F67E6A795A900F7 -:105E400017B31F2E32FEA338FE3B99EDF1CE411061 -:105E50007FEB2EDE699EF7DFACBE81D1F494C0B338 -:105E600079BC8EDFB3FD597B3B1BF1ED72B07E87B1 -:105E7000EBFA55B2981D345362F17CF22D417D2D21 -:105E8000E884C2FD0BA08B92778E8D88C338505862 -:105E9000067970FEA3CC01188FEF643F2AE6432DEC -:105EA000E7AC68791F743C6F343C48594C8FCEB4D2 -:105EB000B23886747B16FA0766C6C648313AFBE4E8 -:105EC00074BBBED50C71DBFDB1A346A2DFD3AA0E15 -:105ED00088063F733CF774264178025C3C51E849E0 -:105EE000C49D059CEB4AB55285F9D5C83650811A38 -:105EF00093A329E504E36FA3240DE1910C467331CC -:105F0000D03FCBA73BFFB68C72A1A4540D4008959F -:105F1000EA8BA4AC62CCCF7AD9A2CBCF127452F761 -:105F200022D5CB06BFA3DFB0AF4EE2F2985A8FDA8C -:105F30002E5D3BF5119001117D30A0D66EA80F7A31 -:105F4000C045149DBE48D2D20CF5015E571CECA78B -:105F50000694AB86EF04DD89FC40FC4B8175BB02E7 -:105F6000901FD18BCF6794E443BA01F9067EE561B7 -:105F70001C9F74BD4559B41C5B1E3AAFA71BB1DE14 -:105F8000EED67574259D0F15606D2BE97CA95C9884 -:105F9000BBCEBD2A0DE1EE22B0CF38BED28ECFE708 -:105FA000F3EF933656D4F5A54324D5AAE8CF4DD2C6 -:105FB0006ADEEC0BF99835B44EFFE6354812F87DF1 -:105FC000A89CC1EF9E59E9C252E0DB45DF4BF4BD0E -:105FD000BF8CE4427CA7333DE6CD7218ECBE2EF4B4 -:105FE0009837ABB8A31EB3D83D6F417EC0F2265997 -:105FF00005BA5833A517FAFF36EC943CE08F3BD036 -:10600000C4F2F436CC64FA448C7BE67789A837CEA8 -:10601000488CCF494B12F2417512C74D6D12C66BB9 -:10602000CFF2FDF6B24C9F2F4B672F6D682A8EC5BD -:10603000B8AD492FD13F9744BFC3D89D04F6D3B024 -:106040007A2503E5C022F89E2C088D88CD00BAF58C -:10605000BD37460239706110E0D31C0F1471431133 -:106060004F7C25CD77AF7EFC8E7142637C4B4EB06A -:10607000E7029F8D96E33CB251FF12C0EB1AB013BA -:1060800029DDAD391287F059F32DE33F3ACF1F02D6 -:106090009C5B9C25484F42CFD27916BE4B3ACEB37B -:1060A000DA12463FA26E9E7559C55DCDD39407CBDB -:1060B000E7D50E7F1ED7929D0ACEFF2C89F3C03CF8 -:1060C000F7DA3C1FF9400F9F8943BF9FC04F15E788 -:1060D000B1B3141F129DE7D9BD23622D0EB08F7C82 -:1060E0004F02BCE481E104B0CF0F348DC883F57456 -:1060F00016DFDD9B59F67416F299EF19E43357E871 -:10610000FC4B6A64FD5DC485B742FBAB80CFAFBB7F -:10611000C6A3113ED58AA35E628E75B4C3242EA792 -:10612000CD74273535FF1BF29228BF615EA87F1022 -:1061300009ACA170AB1BCAE88FCC232AEA65139D7A -:106140002CCBF4BE0AF8127CDA057C5E8779DF93EB -:10615000E90D4209F3E83F1CE5D2FE2CA6DF5EB64E -:1061600059F07B96DF9244305FC71C77FF38B3F25B -:106170002DFC5ED85FB93EC95570557C70B86BF880 -:1061800005912E9673382D877830E4B3EDB19E32A9 -:10619000E44D98E0F0FD4CEF270C0E94CE46323AD9 -:1061A0005B43BA844708DADF93E93B06A5D34AE9A3 -:1061B000058032BA220DE0BC4BD5303F61F72A068C -:1061C0008FB3EF3078EC6BB3205D6F22F9C897C3C3 -:1061D0002DE7EE86FEA97C390DEB1A13DE29C1BE30 -:1061E000B9CF22D50272B97FD8235BBAA6DBAFB391 -:1061F00070FFE4BBC0F1703FE061C4DBCCAFD305FE -:10620000DD5EE274DB53B84BD95DF27507BAB26656 -:10621000A746E8AAA7F958942E48FF5E1DFBA3FBEA -:10622000288C3B34EF8B417955B55B42795EF5FAAA -:1062300017B85FAF7A35068972FCABB1F8FEDC1E89 -:10624000F6FE4C69F43C8284EC5EA8A796EFBCD7BE -:106250006BD4D37ED4473FD3CEB932E5485C367990 -:106260002A3BA7B086E73D89F86C02A7B3E4815EBC -:106270000DF450F20482F984090E96A7D8F13C027D -:10628000E3DB54FE9DCBA54A0067F3F904398EE5A4 -:106290001FA692755F039C92CB8DEF531DE518AF3F -:1062A0004D359D6310F02ECEE6F6B38DA4811CD93A -:1062B00069CAC710E5FE6C6E07D626E17E50E1F391 -:1062C0006A71DA906EEF73DA71DDF72591E429587F -:1062D0005750FF9BFB1165926621AAFE9C45791CD5 -:1062E0005175F651AAB797A1DE67763F43FBBEBE54 -:1062F00074C3FBFE8BF20DEF07D60C37D407AFB893 -:10630000D6D0DE4D01A0AF67D4DF64689FD530DD05 -:1063100050CFD97C87A17D5EA0D2F07EC80B4B0CFC -:10632000EF87EEBCCF502FDAFB90A1BDDC895DFE7C -:10633000A36CB63F92855DEE1CE903BA929D762967 -:1063400046B7FFABE4F8284D284F83B879AD7362A8 -:106350001AEC4F5B92A83EEEC2EFF65DF76D7E81C0 -:106360007F6E7F9571BFDB99FD548A50FAAB3A403E -:10637000E9A008ED2F7F36F72354A8D03E6C437D6B -:10638000A278701D3313ECE84F33F75F99AD1AFC18 -:106390007C621F205B3CAE2952E7F01274D91DBC11 -:1063A000EA395CFF5B78FDCD946F24F67BE6EFFE67 -:1063B000986DE1F6B86F5BB67E5F47C2B217F775AE -:1063C00017CEF809C85182764D75BC0BFD12663B9D -:1063D000408CFF4A9AF7372057CDF2D4BB62016B4D -:1063E00067A11B0CB9F3FDDE1FB3CDFBBD09B311D3 -:1063F0001F4936039C5E6CC7B366D8EFD52695E07F -:106400007EAFD6AAA5F564BFF762364178D7035EA2 -:1064100075FB3AD9E6515D28E78DF64B47FB9CEAC0 -:106420003FBACE0D60D749609725337B7DB784EBAB -:1064300016E37E07FBFCFDEC1ED8E731C453AFC862 -:1064400088BFBF67337BFCFE58F93BD9E3C7AE4634 -:106450001F1EB67A30CFFDF05499ACA2703C5F3E5F -:10646000AA0F89228F45F93EF7DF6CCB2188B7EE62 -:10647000FC1F87572EEAF2BCC7E1492C8F733AD034 -:10648000916EDCD81C46171939DC7F13C3FC18A7A2 -:106490007FEFC47309A76FFA208138212F6EC4489B -:1064A0003FE43913CF0390B7E37738D14F387D52AB -:1064B000F1C8554E1D5D8D66701EF7CA3B09E0FFA1 -:1064C00099BE2B23D5EFE89C9E32F8FA8812CAC6F3 -:1064D000BCED3F9CECADD272FABEAC54E6A734E6FC -:1064E000BB99FD46D3575419F878F925890492755C -:1064F00075A515F30A975F52F0F9E96CA35FA953EC -:1065000078F5109EE6E7029E87279D1C04FEF43373 -:10651000B1D1ED8F5B38BCDBE9C7744EA6B3F31F76 -:1065200025BCFFF3E5D7F4013937DDA666F5C4CF06 -:1065300025E0D47AF98B789013AFC3F99B28FD1727 -:10654000E5B0B8D2EBDAE7703C8294DAC3E380EED0 -:106550004BB93F3DCAB9807139E087B954FE3F3924 -:10656000173025C7782E202D478D7A2EA0BBF34DEE -:10657000D36CD1F55D6E047E1F00BFDEFF8CD505A8 -:10658000F35A08B613F8EFB65AD17FF7DEE51802D2 -:10659000F1942FB6587F09796E8B9EC9786623AD2A -:1065A0002F9A1483F19F855BAD2C3E37293600AEC0 -:1065B000AA455BBFD77B2E1DEF2BCAB7CBB2E8FB3A -:1065C0006736615ECD7B6D6B31BFFB24F0337DBEE2 -:1065D000E8DB1FCD04F8EFB3350C190676FF0EC9C2 -:1065E000704E634963ACA12EF20805FE881439BFD2 -:1065F000A1527DF2608EF1BCD68848DCECC11CE66D -:106600002FC13CFCAAA9ECBCD681E36CBFFF462697 -:10661000CB330C4E9A3565185DC7A4542BFA4BCC7E -:1066200079898420D2C9029E373CE96305CFE54EC3 -:106630001AEA443BF0CD95358807FA9D6382EEBC9B -:10664000C2A49F33BFCB2437CBABEF345FD194A729 -:1066500028CE0F75C84F8C9C1F3A1A8D6E36E4F009 -:106660003C45CED7078EB37CC4056FCB6C5DDDC8CF -:10667000CDF7F93ADE6BCBBFEB250A8FF7CA991439 -:106680007FEFF28D8F81DFEB0BAF44203FF48BCB9C -:10669000D1CFAD7DDEAE5F7DEDE77A003FB7962FBF -:1066A0006EAF035BDEE6BDD770EEA7E7F2A66B79AF -:1066B000322B87C521CCF2DD4CF7FFBFE4FBF44958 -:1066C0006F0CF23BB1FC1594A77631F968E673B311 -:1066D0003C17F332CF77F925D990BF9CCBE54044E6 -:1066E0009EDBF03D35F7713DFE1225B046423BE0A2 -:1066F000831CDA6EA423905C4A87A8756D8BEFCA61 -:106700007F43F7CF1F43FB3BDCBE4FA04CFE4BBF8C -:1067100032D0F723DEDE89F987673BC9436F769B6A -:10672000F2DA2463BCE0CB9CD266C8E77F50A5A513 -:10673000CEBE1E499990E73D7CC9F9F3A710B7ACCE -:106740007AEB22F2E7269B2F0DFC03FE7E36CFF676 -:106750002879231772AEEE3CC316EE9F27B9B9868F -:10676000781FF889306FE1681CFA89D6A669DFC006 -:106770007C9E4BD3FE0FCA2169DAE51C1D5E6AF9C7 -:106780003A154B74BBB83857D0BF17F5F8FC322A0E -:106790007FA3D0A19ACBCE01943E79FB20F0C77D98 -:1067A0007EE48E41201F5B368DEA32DFED67C09FAD -:1067B000547EFE18E47E56249EFA13CE37C2DF3D87 -:1067C000DFE6CDD6E769C9B949385EC235BB5BD3D0 -:1067D000299DB4AD93517EB739587EDB318752DEA7 -:1067E00058C0BE4B317CA7B0FD07D03DE563C5A1C5 -:1067F0007CA39747C5B90CAE9DADB33897ED136C2C -:10680000C46387EF6D476FB2831E9525CDC5FCFF2E -:106810008C1EAEA123003DFC88CBB19369BEA2DCE7 -:1068200062F88EE9DB6BB8BE551C26FD3AA0EBF88A -:1068300078639A3632978E3F314D2B86FEF6DAFC1E -:1068400043806FF6C645CF57BB2E97D923FFCEE1C5 -:10685000F4421C68BFE27832C6E96FC865717A0DF0 -:10686000CA1BFA87D7401E7AB3DBC5DB87F0DC1D75 -:106870007D3F01DE93B410B905F2E7E864E17CC422 -:106880001F4E1C2520BF12C26D04F269124C79B054 -:10689000A2FC0787DBAB3CEED991EFD83CBD1CFED8 -:1068A0008D945FE0BCA8E01788AF43BEC483AA8F75 -:1068B000F31DCBF7687CA297047196744DB5007DEB -:1068C00040FE29C827737ED08E5C76FE1DF850EA04 -:1068D000820FE7F379F6940F1B9F98628985793EC2 -:1068E0004430AF8372C26A3BAD3F7B9FCB03E7C7A7 -:1068F00032D611DC070D5C11B70DF649351C1F832C -:106900003792D5B1B4B59BE7F7897C6A776D48C1FA -:1069100073060FB1FCBD939FDF243BA1FFAF45FF82 -:10692000C67C4191DFE7CFB518ECC2DBD27D0F23E7 -:106930003E4DF9D89DE7817D9907790E3F11FCCE38 -:10694000F370C6F03C9C318D9BD01F37A6F14645B5 -:10695000A24D9E558212ECF79EADD114D037CFE5F3 -:10696000B2BC9CEEF2E39EE6FDFB01CFA99DE75988 -:106970003ED92E773AE4593E999BAACB2BFB01CB0B -:10698000B3FC7E2ED323CFF23C9A676B98BF6EC9BF -:106990000B8750DE8B71443B918F37E001968FF768 -:1069A000AC128A05FAB9184BDAF3CC57A1533E342E -:1069B0002CFAF90591576ECC271F1C0E97623E10DA -:1069C00021784F42BF3CD5A007B7865D71C02FDD4F -:1069D000E983DFE75E9D3E782A8FF14D14BDD9949F -:1069E0007B757A33087443F5E60128AF5A6F727DE0 -:1069F00029F4A7787F88E373562ED39F51F4E621BC -:106A00008E5783DE4C2101CCD320A72C1E7DBEA83F -:106A100028BDBCDF97D3B50F61BE63B83F25E1D475 -:106A20005122E9E45019E76B71FFC4F3BDC83DD3AF -:106A3000A2ACE37ACE9F963961BCAF22A1498A9A73 -:106A400087D6ECB689F8ED1730EF1B0653B92975D8 -:106A5000949B51F07106E6D9FF6DED0010C9B54960 -:106A60008DF1603E75818F73B968C768E7A114F036 -:106A70001F7EC5B88F14F0FF86C3C396A5FD1BC645 -:106A8000F913E7B3CEF0129BC7F0D12F8FD9332281 -:106A90007F7DB7C91E1D91C7E0322ACFC8973AFC47 -:106AA000C5E645B17B841C7E39DDEB80F7AF9ED80F -:106AB0001D0F7424F024E48F195F113E5B85E352AF -:106AC00038A7E6A576D43FE27BB31E8A7CEFC7F9F0 -:106AD0006E053A1AC9F27DF07C013FA720E627E84F -:106AE000DCC3D779205D73E715779CA7EB9445EA63 -:106AF0006A9E49E11409F83F497361F98713160941 -:106B0000E6E50A2B982FEFE2FAD1AC07A9B8E074BA -:106B1000C3FA798ACB8DBAD32C0FB1AED49706FEC7 -:106B2000FFDE59DAC83CE423AD18CABC2CAD04E63C -:106B3000D9EC66788ECDD346435DE40B98E7A9E5A2 -:106B4000B5E71D8C857609E3891FF421DC370371D5 -:106B500096049EC790A0B9CA408F256C21982790B3 -:106B60001C1F6E8E81F8DF26E2817353D97ED50219 -:106B7000FBAF8C07B4D550D69DE6F7E694123C7770 -:106B8000D99E47579B8E7974C06F7A7A9DCEE73134 -:106B90003D8FF125B5436EC963F39A06A5B0430452 -:106BA0001F756657E8F87076DED5F1E13DD0FE2A14 -:106BB000F8706E1EE3C379793DE0C3A579ED7CB82A -:106BC00004DA77C7870F71FE7BAA1B3EFC39A7CF7B -:106BD000E7F23A95A30FE54595A38C1E04BD031F6C -:106BE00082BE6FE0FD51F9B9321ABDF7802FEBF389 -:106BF0007A6017B6F7D743FAEFCCFE8BCFEFDAFE09 -:106C0000DB0279E3BAFD1EE597A7617E945F7E0102 -:106C100025E5972D8C5F54965F6EE2AF767D136607 -:106C20007202F2F3F4795ABFCB6BD737DB01CEE6B1 -:106C3000BC9C31267FFE3B9CBE9B7899103E4A400F -:106C40002E50B8BDA4A7D7E739BFF847B3BC53AAA5 -:106C5000D9CAC0AEDC778ADA91003E2E0FC66C6EC0 -:106C60003D007623511AE2E11EACCEE0D42B5F1535 -:106C7000F99551E144C7FF633479DA04787374B449 -:106C8000E7CDF8DA91C7E83CC4E1F15DE721E00720 -:106C9000F328C279A896B53A3DFF41445EBD0F780E -:106CA0001B3B3E2C139C57301EE227429E9201F460 -:106CB000FB911DBFFF24F2FD27B0DEB11AFDBE20FF -:106CC000F27D12B8F233408E51798676B286E71C97 -:106CD000EBDC8C1ECC74DF6863E724DAF1D5D00FCF -:106CE000F1E5557D5F42FF8D0A3B4FD258EF92D8B8 -:106CF000394196EFFB5E8686FC1A450E85AF520E33 -:106D00005DC843FB4CFB1794DDC9A1CB9CBFA91CFC -:106D1000FA3F681FCAE95A0EC5E7337839F2997C01 -:106D2000E94C0E25F076BDF225839F522787E2F3CA -:106D3000A3C8A107550687287C9A985F0CFE15CD3D -:106D400095CFF834295FA7D7E877C9D09F17BE4FF2 -:106D5000C5BC33CCB7F093384FB47D869AEFE86961 -:106D60001EB59A9FDA31FF8C749347BDE1D1900D27 -:106D7000E02DF29CC4B8E6FC6981C7AAA65523C8D9 -:106D800050C8D3BA3C08ECCAB347BE41FFC8DECCFA -:106D90004A0FACB3E5B55186BC2C31FE7DDC9F3685 -:106DA000412ED809FED973076DE8F79489FAD418F3 -:106DB0003A9FEA8356124039C5EE2910F130EBC1F3 -:106DC000BA56F0C75B89EEDE28DCCFA88940B7D67B -:106DD00083ECFE2692C2DEFB897D15DEB738DA1819 -:106DE000E74FD28C71FEE4F25EA6B8BF31CEDF670A -:106DF000B631CEDFD7678CF3F75F34DC14F737C6D4 -:106E0000F907AF2833C5FD8D71FE8CFAE9A6B8BF2E -:106E100031CE9FB3D918E7CF0B18E3FC0BDF7AD93B -:106E200006FBEA212FDC678AFF1BE3FD1420AD99E6 -:106E3000BAFB648AF6AE36B49F1762F7940D0BAEB8 -:106E4000357ED7C0EE39F0D3FF013CBF203E1BD0CA -:106E50009942C26FF687FC9680E409D2668BF7EE02 -:106E60002A817238F78B2FDC6CBC1F6171C058FF10 -:106E7000EACFE507210FAC1A9888F653FD82140873 -:106E8000B83BC7FBD2178CDF0B3FEF52BE9E73DCC3 -:106E90002838B745C6F3CC663A59F8D6ADFC5E3112 -:106EA000AD15EE8F107010F4E2E2F422E625E0B1A9 -:106EB000545E867C2EE020EED7AA32ADBFC37AF7AF -:106EC0006EC5EFCCEB36AF6353BE31CE473AF08997 -:106ED00083E509D175419C5CF6E79AF8C40887CE32 -:106EE000E0D753BE51391C62D28C7C13ABC699E9F2 -:106EF0000EF16D86677CAE919FCCF0747AFA45A551 -:106F00002F713F2AAE07E2217B25F2B4D411AE8B5C -:106F10009AD6D7F58F424F840430CFC30CDFE67C7E -:106F200063BC6597EA6B01F978FEA30B32E2D517D3 -:106F30001A01FAAC8BFCB383BC7D4FE3ED87F2758D -:106F4000FE1173BCFD2CE449EACEAB48ED78D34C7E -:106F5000799207FE0D7124FA8DCF067ED8728F9D2F -:106F6000DD1766CE5FF3FD331FF5B046D00F788E88 -:106F700078D6D0FED6387F3FA41BBFC8B1FC62963E -:106F80005F00FA6B6C3874FE25E85E6975C138D114 -:106F9000EE29359D3F3C0DDF77760FE4F3C49B4728 -:106FA000A2C4ADC5FE55D8ED749F74219FD9331787 -:106FB000A1BFF67D52BB7DDD753F228FACB352DAA7 -:106FC0002FA35E0D4B719E68F798C50E31EEFF75CD -:106FD000E73D6387E8F468D5F7CEBF09F3A0F07604 -:106FE0000CA1F3743AA97D23F5C8BE71413F4FC58A -:106FF00027205D87DF9203396EB8DF4A4DEC55D00C -:10700000F19E2691575803F73025C3F3BCC4AEF266 -:107010002FCA4CF76099EF33AA1BCEE695CED7392D -:1070200085DB5125BC2ECEA5097F5CF56CE66FDEB5 -:1070300064F263960C71627B6F665909ACBFCE2D0A -:10704000A1FD5427498678D2F1FC527CEFE1FD97EF -:1070500000EF15E3F93A9C578A691F7F8EB73F9777 -:10706000CFFA857BB180FE6CB21C159ED70D61F303 -:10707000FF3BB7A3BEC3FD34EFC78CEC783F8DF95F -:10708000FEC489B9352D201ECC71DFDF75773FCD69 -:10709000FB13A3C67F01BEF1BD22743F6388F19E3E -:1070A000C4609C6FC354F047BC237BB6E157AD234B -:1070B000F4FBB48A21CC2E5DC7F72D1057C2FD0812 -:1070C0002FCD70AAE0706AC8F45600FD6DB2B5DE2F -:1070D0000FF41BB4B1FB42C31F101CA7DF22AD1974 -:1070E000EAC55E15CF57D4B98903EE190A0FB3A0CC -:1070F0005F24C5E71A0FF7FEA66C917A0138855C0C -:10710000B02AC4EFA4F4B276881BF1B08EAC6986C5 -:107110007B5112B77C4DD2713FE11AEF0279348F67 -:1071200044F5733ECCE963DA33E90AECCB12EDD1D6 -:10713000EF79787888C863F33E04F431D67E6484AE -:10714000847A82ED43606B8BFF69B318CE358BF286 -:10715000BD8C717EF84ED0F3F532A9D9E56074A6E6 -:10716000BF7F6DED90ABF34F172F2251FDA8DBF9D8 -:10717000BA72546F03C0BDF87D15E31F0B85DC9F09 -:10718000672170CFE9ED9C1C6FDFC2F2E1C9E52BEE -:10719000576461C713EC9F403C62E1326700E21321 -:1071A0000B9BDC78FF1F592461DCA4BAE99017EA35 -:1071B0000B478E74A1BC8C9724B807124C08261F6D -:1071C00015725CD09FCC8144FB9FCDF50DD52BEB88 -:1071D000E2E9BA166ED9DA0CE72CFE410D08C0FFC1 -:1071E000267E6EDEBC2E713F5DE4FEBC4F36E9EFBD -:1071F000E7B6ACFAC707C6FBF3FEF1C17F737FDECB -:10720000BEDFFCE303B89FDB7C7F9EE0FB8F64DF87 -:10721000470FD37FDF4695F28AE1502A640EE229B8 -:107220000DD73983AFD3FF0D918EDB2370B9ADE954 -:107230002D84F747563A1E651E6B19038DF5A14440 -:107240008C2F8B7CA499F68609A0D7CFDAC28570E3 -:107250005EECEC6B1F0E84BC834F7F78DE097908EF -:10726000FF54C24E787EE291F79C1AC5EFA78FB00B -:107270007BB6EEE6FA52C0ED1F9C1E0A0BBC87815E -:107280001EEE59F96D89FEBE20B22215F5DCE280B2 -:107290008C292C428E2C7D211E2CB9F6FAF29DC928 -:1072A00086BAD07FCB63484D34BFA8AB80F1CDE226 -:1072B0001D5B6DFD5518DFD706E39F80C4694A3713 -:1072C00027F638D14E16F3A9DC31CC0676D53F9B94 -:1072D000624810F66B4AAB959D37D5A648945E7D03 -:1072E0009C2ECDF37CF3F578EC6FFE26266F2BE811 -:1072F000582B285C7D4DECBE4FF33AE67FAA4EEC4E -:1073000043E13DFF716AC1A8ACFD23146FBE153F78 -:10731000C2FC71F33A2BFCE6FB3D3594F70B397E4A -:10732000E7D61BDF2F6CFA31F6338FA8EB204F72B4 -:107330007E83F9FDA42F8048179AF2D16D055C1E5B -:10734000979051208FF7DB3312A39D3B15E5A9954C -:107350002E64A22F57DAB13CB192607978888A7096 -:107360005FD674E841A09FAABDBBF01EA696C0845C -:10737000144AD6E4C6A6DBF1FEDA1B79DCFCAE8E3D -:10738000F78BA6151443FE91E9BC375FF71C8E07F7 -:1073900071FE7B0EACB7109E2B17F4EB397730C320 -:1073A00001E3BAC5BA46D175C93D5F97588F589F5A -:1073B00078BF9CCACFA8F1704EE787B9BC9ED7387A -:1073C000ADAE1F05C59AD7BE40FF00E1FB92F6FBAC -:1073D00091ED3F6E85798F27A67D899FBC4F74F410 -:1073E000B69068783FAC99AE049EA9DEC6EFED7CFE -:1073F000DFD24E4F4D3F41B8087CC30D82FA7BA9C6 -:10740000285D19F609948E0CF5F90DC6FA196B680A -:1074100010F0FB42D3EF459C31E5D388D25390CE98 -:10742000E0A06A13E1DCD07CE2AD6379C7ECDCE17B -:1074300009A5E1CD87810F1B191FFC93E37F6781AD -:107440007716E09F285A21DE17B9BAAF0C171F57DD -:10745000AC935CC05F736B87E1FD43C38986FDDD40 -:10746000D589DDF910E7FFCA1A2BB15163A1928EBD -:107470000172AE728F2CEEFB724CED0DF7D7303EE1 -:107480005AFEF82E5B5F5A2EAA59C8ECA100E31BE6 -:1074900071AFB6A03FA19F96AC6B46BF03DD6F19DD -:1074A000F8AB1ACE8114021F9B9ED7DC8878A836D1 -:1074B000D945DF2BE0FB330FF1007DFA1E74DAE1D2 -:1074C0001C5977EB261DFD49E86F3A77300BEDE547 -:1074D00073AADA07DAF912D83DFE92E21B05CF292A -:1074E000BC508F8657C5E3BDC6472EC944C5FB5562 -:1074F0007CA3E0BC7FE8EF0309BBAF8DD1AB586F35 -:10750000B57D1DEEA3AB4DF45A41376CE027AED8E4 -:107510009E8C796AB4FFC2BD605F6DB7A2FDE4279F -:10752000F7A5C1BD1ADEC7D8BDBC957B93701F5FA0 -:1075300059CBE24B953B92F09C30DD47BF0FFE19D3 -:10754000818F23B5E36C7D115F6EBC2F8CECB5FA97 -:10755000F93DE748E7024F1DF7C1263CD537BF99F3 -:10756000A676DC17EBF0D4D6099E0CF758FE5AC865 -:10757000118E27F208973FF7BE910571B57335B1AB -:107580001E39CAFEAAFD3EE379D7623E9DF03F96C2 -:10759000F713BFAFE0E90D783DBFAE18F166C657EF -:1075A000F97FE6225EC8DF9D04FCD27765907BA65A -:1075B000D3E7F7488C5FEE5A33A91CF4F9810266D1 -:1075C0001FFF95CA2D2D879043546E69546EBD4799 -:1075D000E519D43F589986F50F57AA587EBC321743 -:1075E000CB366E170A3EA2846003BBF2AD0266EF93 -:1075F000BC5520FCC10FA4816951FE9FF78A2DE084 -:10760000EAF5CF9F3981DA3BB768467D387B8651F2 -:10761000DF85ACAE89707ED9FF38BB17AED27B9DBB -:10762000A13D5154DB34D8D7E78E883C477E536D5B -:1076300070FEFEF629C986F633EBFB1BEA470A54B7 -:10764000764F507986E1F91D738618EA15FCDE5BEA -:10765000A28E46BE7980E7C912329AE185E7DF5CE7 -:10766000A819D5E7FB74BE17DEB6E27B333E045E95 -:10767000E76D96898FF6377733955F748A6D0D14B1 -:107680004FF4BBAF3E72C2591952B763C4BBA36972 -:10769000FDC80E96AF7BA436F9A7603F1DD9919A1D -:1076A000007E635F9DCCED0C17DEF726FA1D57BBFD -:1076B0000AF3722A023178EEA2A2C5FFACA8C34F2A -:1076C0002EA089077CF3BE1C084A883FE6F7F875B0 -:1076D0000CC62D4E50BBCE45F5C40989D4420907CE -:1076E000C512E9FB7FB5A60680AFCBFF236B6940CF -:1076F0004FBF8EE5712909FBFBF250D6B6B5485F46 -:10770000EACE20F26F0CEE8FE686D8FA8834BC3FC2 -:10771000E0FF4412D192E82496DFF7E1670AC5D36F -:10772000E2ECD642B817678E3B983A8B7E77AAD1A7 -:10773000CAEEE9A7FDBA687DF96F62F8FD8F5A1F9E -:10774000D86F44E019288475A7F6F3A60EA5FCF1BE -:10775000E5824021CAB5475291AFCC706FB3F910A2 -:10776000BE7EE003292227237CC6E28D54B8F505AE -:107770007933D7EAE90DFAAA6D9D95DD8FA76809DF -:10778000ECFEC9DD48C76D8A3A11D6DD56EFC6FB5F -:1077900083C4B895EB648DDD5F49E912DAAF977D5C -:1077A00070DF8FD05BFE7AC907F70299E9E6FE7BAE -:1077B00047619EBFD9FE15E519CAAB3E9D1DB1E4D8 -:1077C00035197FD7838C0C29330CF783B1DF3F2128 -:1077D000BED186FCDB65E97FFACC6141BB2611F6A0 -:1077E0004527DF9791CE4EA63794A465403ACDFE4B -:1077F00092EFD3FA5753FDC7E11CF13D837D65003D -:10780000D7A59675CF4A1638777DECA770CFEE973F -:107810002F5A3D30EC925F2F1E8C71096E7F77944A -:107820005B9AB0177AC33D5115AA0BF5B85A2B11C4 -:10783000B6FE00CEF34EB2F331C09B6B197B7EAC2B -:10784000D8B916FC03734DE7D88EF17B3A660C6508 -:10785000F244E8FB0D4399DD34D7C2E89ABC2EB15F -:107860007BB4F8EF5F087D20E4B590FBF38632FB34 -:1078700042C86B6A39A0DC5A00B747D1752E7B210C -:1078800086F9D355E202382E6668225B873279B1D9 -:10789000C4F6E293C04B0B492BEAD32FAD8105AD63 -:1078A0006EF87E6B6D2FFCDEEA41FF32D72F70CD74 -:1078B0003FC8A5859CFF963748781F14E17A723E31 -:1078C000EF9FBC608DE88DF428FAC5A457E673BD20 -:1078D0003A9F98ECC006A3BEF3C6B3CDFE123A2E73 -:1078E000E8CFC8BCA8FD4C61B7C01778F3669CB759 -:1078F000E4094499C742120EC2BD58CB77307FBD10 -:10790000795EE675F4749E0B3CD3C6278DD48D6BDF -:107910009AB780373AB8757810705FE067F05CD03E -:10792000C4E21F9F737B4DC46BCCF85F48BC3743E8 -:107930003EE2C28D547EBA23F420E860F1AE00C668 -:1079400067BE220D090ECA07CB36EF9A798D0AFB66 -:10795000FC43B80F99D32B9865492224D97FE8C9F5 -:10796000F281DDC727FE577022FC7E71FC8EC26556 -:107970007E23BB3F5CD78EE7DDFB91AE17F9FD366A -:10798000F0DF2EE2FED0EEE659ADB073FEDDCF970C -:10799000C1F17F3DEF778776661F6545DD6FB5DB0B -:1079A00045DDE8E34FACC181A08FC30315D4471771 -:1079B00014CF87A529A09FB370DFD099BC5DC0F517 -:1079C000F27CD0D3B43CBEF965BCE7E9F38D2F63FC -:1079D0003CD8F6E2FC04B0978F6F9EFB53380771DA -:1079E0007CC75CD4CB0B9F167AD967D3EBFB719B1A -:1079F0002B9EFB21D0E90BB118C758D0E2E3F63833 -:107A0000DDD7805CA4E3A19ED8C8E4E042D05F0546 -:107A1000A8BF72A0DD830B7C3940EFBAE7A8D71E60 -:107A20009CEB1B85DF135790DDB3EA0A82FE12FA46 -:107A300055E8DD57FBFA2E0F053E92DFFEE0077496 -:107A4000FDA777CBE8D3592E6F1D04BF0FD3991C28 -:107A5000FFEEF0B6B4C3DBDD03785702BCD11E6283 -:107A6000F03E5ACFE07C6C1D837BDD8E8C04D80702 -:107A70001FADCF403BE8E88E2C84F7BCB514DE6820 -:107A800007AB463BA89EC21BEC7F80371DB7B245B3 -:107A9000E5F0F63078D7733DB48E95F33AC0D57FD4 -:107AA00037C895077F19E3C1FBBA6383A9B04F3983 -:107AB000B14B2690A7D16E27717B46C0F95FA4E138 -:107AC00059B0AB3AD837EB6308F87317FFCE89E7A4 -:107AD000A4BE944AFB00024E35FC2901C68B8CDF04 -:107AE0006ED7780A8B75764D0FF15345BC788EA111 -:107AF000AAE94F1F815D0FD72CC1BEBF4ADC8FB1F1 -:107B0000D7783F86A4824CC3F3B2763BD0C100F352 -:107B1000FD213EFCBD9C8B595FDF7D1FF273385BFE -:107B2000EF57AF8E0B5AC11F15DE2521BE973F5070 -:107B30009A504A200E5783F3985AC8F4B3A469E8C0 -:107B4000678CA1741347C7F3C265C2F05C7531BF7F -:107B5000E3163AAE33325FF3F39B4110817E7744F4 -:107B6000F753FF908FB35CB6E03E64998DED4744C8 -:107B70003ECC5D85CC6EB8AB90ED4BE616B27C93F7 -:107B8000B3903C45FB3D7B7D0CCFEF1E8FFE4F71CC -:107B90003F8222E0E652CE187E674209E3EFC07CC6 -:107BA00076ED21BC7FF733F8168D6B8A8012B06BAF -:107BB000D8F7EF5AD9BD2E778EFE13FA4D3F8BF5CD -:107BC000AA607F7D966AF7001DF9E11E3C4A7F3F5F -:107BD0008A63FE729292A8007FDDC1E5ED5D63626B -:107BE00034D04B778EF991174A3A8E1F821675A5BD -:107BF000071E033ABA27EDD8F7EC7449AB2CCC6ECC -:107C000059D58B601E511135DFC16F4B5FEDB992B5 -:107C1000DC15DD18FDDCCBC09F7B2D6104351AE13E -:107C200069A853B8627DC34BA5B3360E20E430512A -:107C300087029E97014C800E2A12D12F700BF89567 -:107C40007B41A9207D4D5788DFC2CA7A07DEFBC180 -:107C5000FCCC37F375DE369A0413E9FA826F118390 -:107C60001F7E56D012CCA170BB45093603FC2C7682 -:107C7000D50AFB026FB9341CF6CBCB56F76CBEBFEE -:107C80007A69CAAC8D6368DDC2F21CC23F90F09E77 -:107C9000963B2973035DDEAD90167938C31BD05D2A -:107CA000752F761F79F85E89C79398FF5FE0651896 -:107CB000ED5E0FDF3BF9FC683FF509F0BD2DBA5FC3 -:107CC0006937A753616F2EE57CBA54D0D90E237F54 -:107CD0001E167C02F62D85DB9DBCEC8CCEFFCAFB0C -:107CE000FF6B21F35FBD7695E32D8F2141FDEF56AC -:107CF00089716FE1E53B85CC6E16F310F44BB85FEC -:107D0000CA422506D0515BC31AB4971699FCC444E5 -:107D1000EFBF92A3D5DBE58EE50A94B6F03C988FD1 -:107D200074432CF2CB9DB69D59EC9E1963BBE50DB7 -:107D30008CFE973BEC68078AFBC5C53E40D88D8B0F -:107D4000C1DE037BBF91D9B70AB7CB2BE87E0D8884 -:107D5000CE4A42B5FD61DF5CAFB37F519E717FCFEC -:107D60009E613E18E74E871DE39F372F33DA4B564F -:107D70006E475A3BFEFE9D31AF84DB4BE6BC129949 -:107D8000F3316DCBF6313CAF44E1F6B0A0A30F0B5D -:107D9000ADDCAFE237C4F1E790562BBF778EF9F731 -:107DA000B89E9E203BF03E863912BB67EB6CA9D390 -:107DB0006FA172E9137ECFCDB91A76CE79CE0FD8E6 -:107DC00039DEBB121FBC19ECE239093605CA4FF87F -:107DD000EF7D7DEA4A4F9C4540FEC83CEEF4935946 -:107DE00010BF59037294D59FD2C6A0178DD79FF8A4 -:107DF00010DECFB84CE78DF50DB3343ADED937F845 -:107E00007B3FAD437CE831C1C79B597D9378BF85EB -:107E1000D51F17EFB7B2FA4F44FFBCBEDEF47E9514 -:107E2000E9FDCF597D70D1D6597EB0E379DC6ACEB9 -:107E3000B512C6AD34E0330ACF39AB83485F732C3B -:107E4000FB5959468210B7ECAEDDE422AF06FA5A70 -:107E500076B639C15E99314CC37AFE505F7E11C54A -:107E6000CF926992DF06F1CBF703D95C9F45CFC76C -:107E7000E7FA699287F527EC5FDACF88A2E2ABEFE9 -:107E8000E7A3A20EFD8CF92EFD34769CCF84EFB2D1 -:107E9000AED861C67E843DB86DB8E6837991F1D7DE -:107EA00019FC9C4B1FF524823D49DE65BFBBB574B0 -:107EB000F5CE412368FF4B5FDA376881CEFF5075FE -:107EC00049261A95C3D597242CBF6AFED806F74BCE -:107ED00054ED69B64D2C80DF0B6AB68DD3CD6B990E -:107EE000C833262165BACE9E995F64E17CC57E7752 -:107EF00068E94B2731FEBCD4B2F3F8D3C097D73230 -:107F00003FA4797D53F9779F417E4194FDCAD222E7 -:107F100026879F1EA92D01B84D0198D1F6E3D644BE -:107F2000CFD3D8C3FB9B13C7E4FBDC12A75D2D8224 -:107F300078B86F0D9CFF5BB0C53D1CFCDA5387968B -:107F40003D50D4A57F38CCFCC34DCC3F3CA757EB6C -:107F500003547991DFFE36F814DCFB3CF929D21E7C -:107F60004F06BF2B1E8747BEFB70D6F831E8EFC324 -:107F7000FA1345879E82F3DF07F9EF31DC356A6833 -:107F80001CC885903BDEE2A2FC3CA3A0E2B780BF08 -:107F9000BB465D3F119E97C638B32B589C01E962E2 -:107FA0004681772DBC87F6E0DFF1D998BFCFF76720 -:107FB00019FD7DBEC2785FB4FC857A0E87DF16B1ED -:107FC000F31B072D749EC323F310E35303ED815677 -:107FD000DA5FDBEABEC3E09CE5CE82D297909EF8E2 -:107FE000F83B0B7CBFD08F0F1409CF7B3A8FCD4568 -:107FF0004C9FBEC4F1E61D43E94D27F7A78F8F378D -:10800000D4674C49269ADEEF3CA3BFA13E7B4E8647 -:10801000A1FD1DF38618DE4F8D691D597315767FFE -:10802000B5D31907F9119F36FDEB6F77823DDB2839 -:10803000E3EF172D7E6DFBDFE0F7BCCED10527A364 -:108040007DAAA2FFEFCB83EC775889A229FA38D614 -:1080500069D2FA24C47D75F191A8F163111F59EA20 -:108060006AC13CCDFF368EF56E118F630D87D475D6 -:10807000D0471F0C823C952A075BD7E97D47F0F774 -:108080004C20CFE34A09C47F091A89D59756E1EFFE -:10809000C88DE3BF275D5DC4E473D5807B15B8B799 -:1080A000A09A9620FF2752399548E9A4B5990CDD8E -:1080B0000379DB6E27E6D52CBF742BFAF50FC6F9D2 -:1080C0000BEEA5ED96D64FC27AD5A578ECF7AF7238 -:1080D000EB44CCCF7F45C2F8C9D4FE77AD86F943D7 -:1080E000FBFBE978537F7B6339C0A96A0FCBBF994B -:1080F0002A1F1E09FD2C6B9884DF4F95C94189DA30 -:10810000498997EEC47EA7828D43EB7289732DE86F -:108110005DD916CCFE05C8159B13E54AF5A558FC9C -:108120006EF238A69F2F16B17D8B35C4E635E1D2AD -:10813000347C2FF07FB928DD709ED49ADAA8C07DF8 -:10814000ADD69084ED6FBA34044BB1CE3FE7FE124A -:108150007F9FCC9A7A6122E4DFFE394572A1D9650E -:1081600092BBE76B4625EAF7D3FF0F762BD097003B -:10817000800000001F8B080000000000000BCD7D78 -:108180000B7854D5B5F03E73CEBC9299C9E4C9843E -:108190002470024908106032791042209310109127 -:1081A000C000550906199047401E21BEE295FB67A5 -:1081B0004212088216B5BF45453A205AB4B6372256 -:1081C00056DA224E006DACFE366A1F786B6D502F6A -:1081D00082458DE0B5F416E5AEB5F6D999394382FE -:1081E000D0DEFEFF1F3EBE9D75F63EFBB1D6DAEB3C -:1081F000B5D73EB978117ECA19BBA895E6F332F31C -:10820000263276D37989790B18FB3ADF9BE04E66EC -:108210006CD6861EC592C418B3599C4F66025C92F8 -:10822000AF2ECF0BBF271FA961EA18783FA9D7E867 -:10823000B5C1FB504EB185EB1731E6ED0098B11E8C -:1082400065AE3DFCDCE53630968CCF9B192B827EEB -:10825000FBDAFD8CB114C66E7632FED3088D52194E -:10826000336AEDC5FBDD12D4C1BC022F98834FC227 -:10827000EF291EFF6837F4D35DC1E6EFC77E94EEA9 -:108280002173ECFF73F3AF9699454AA0757871DCC2 -:108290005925AAE15EE8CFDDB78E0095DFB68E0CDA -:1082A000ADFDAF65D6D801F3F8757979B717FAEB5C -:1082B000BCA7A04056C3E356B84D8417E6ECBDC03A -:1082C0000A195B773856BD17D6590D3442B8F725D1 -:1082D00073704F263D67521296E63D12D4AF73F489 -:1082E000E6F860FC292F5B436C2CF4FBB25561303F -:1082F000CE1B85FE0AA4E794974754490E98E421C3 -:10830000B3C2A0DD75E3BC9588B781E67B318A4FA7 -:108310004429D6CBAA261A583163B759F86BD3E64D -:108320004881B838C6FCEDD73206735D7C7E1E638B -:10833000C04F4BCEC712ECDFCE9F9FAB1F340DF169 -:10834000786E034C1AD6B1648334E600AC8BA97600 -:108350007736E0A13A6DE146E640BC1B68BDD5A387 -:10836000E3832DD0F4BA29F680218EE8D185F45824 -:108370007D3E9EFA5B733E93C6597B3E91E075E766 -:10838000AD542E393F9A9E0BFEF6217F437983C769 -:10839000BF1EF151DD72CD741CC7BF31B5D06F8BDC -:1083A000E4179313F90AF8C5B53C821F5A3A815F66 -:1083B000ECC42F8A17F0EA8332925F6623FDF31034 -:1083C00013CE692930EF59AD99867B59B8FE4EA47A -:1083D0007FD195F3FD2D1ABF2CB185B20DD09FB181 -:1083E000DEEADE08F33A9BA44E43BC346CE1F86B42 -:1083F00030FAA6D861DE0D8F486EA00CBBA5D86EF2 -:108400006180A7E2E3F5267F04BFD79C1FCB54C051 -:10841000C7BCF35954568FF1B722FD179FBF41A334 -:10842000D3582A995A62C0F9DC8E74557142259C42 -:10843000CEDAFCBEAC1F3FE82E18FFCB378C545F62 -:10844000E40DDC8CF33106CDEEDD309F5356BF8C4E -:10845000F43D95C19C0FC1144F1959C009F4BA6578 -:1084600087CC02D0FF5228FD509E8A67DE780FE24B -:1084700013D699CBFBBE08FFFF53D93E840D07BA34 -:1084800036FCFE7D6518632B73BAC786A0DFDA8AD7 -:1084900050F28DD0EF99BD467700C65DDDF976B11B -:1084A00001EA3FC9F40E6232A06AB07F17D275D5D7 -:1084B000DCE04F8C00DF7ADFF38E096A189F1D4ADB -:1084C000285B81F73B008F019857C736797A90F087 -:1084D000CF62E78C09F3B5E0E368FE5E757E38E1B4 -:1084E000E75CBD79CC01E45FE0577CBE46E3F35B1B -:1084F00091EF890F39BF0B3E5EA37079B5C6161791 -:108500000CC03A8C3DBC5DF5BF01FF01CAD71ED837 -:108510007D7F29F2DD1985F87FB5B64FAAE5B9BE92 -:108520000ACEFFEE1678FE62930B9015E6FFA9E7E0 -:10853000E750BBB8F337517F82EFA3E579C4BE6142 -:108540000CDE7B31DFFF16E2A9F2477F7BFEDFE125 -:10855000D10C2594F358129676E29F7F96DCFFDDCE -:1085600055F2FF31ADFD74335BE4CBE3723DB2BF36 -:10857000144FE5695CC7676E89CBDF7FB2BCFFEC47 -:108580002AE5FD1FAE50DE4BF95CDE47CB7706FDDA -:10859000A17CFFFCA5914194FFEF33D007A8F70E13 -:1085A000C5AA4F6AF29FF4434C5CF072F2FFD1C24D -:1085B0005BA4FCFEE5BF21FF1F90FF7FEF3E11FC97 -:1085C00018BD5FAEDBDA4D7A81BD283194BF62FF02 -:1085D00074C570BC748DE27A20BC6F24DA570CF637 -:1085E00055B614B96FF6DC5F8AFBE6F324770B1BF4 -:1085F00078DFDCA4ED93459A5E10FBE3D17C7F61CC -:108600007EC4FE58BD3F5A3F5C9EBF6E4AAA67A813 -:108610001F164119C95FE63EFDA0DF1713F2AF6ECA -:108620005F8CD0DA7F1B5FCDFCE7F3D5CC01F8AAD5 -:108630003A3FF9EFE7AB687E3A57FFFB4215E67326 -:10864000AE10F82833CC3FD7BDCEB8DD30DCEE7E9F -:108650009245F0892923D882ED2EB27AC463B43CC6 -:10866000147CBB05EC009CA7A07B574C206F7DDEE3 -:108670003F4FFEDD997F7576EFD2FC2B931F9B91C8 -:10868000CED8EFFF9CBDF8607F74655E6E1784E9FD -:10869000629E47765C08149C34305D8D3BF8FE1278 -:1086A000705B48117A3711F52EF0CB43FF08BF54A9 -:1086B0004F815F0723FCBBF9DE74E8EFBB1A1C781F -:1086C000773ED2E7861251FFFB1DDE2C9433F06B10 -:1086D000298DE06516C2AF061F3F5E85FCFB505F2B -:1086E0007D00EBA796C569EF332FBA1EA2FDFEFCF5 -:1086F000DF1EDF46FB793BDFBFFE1EC53726022E9D -:1087000004D81E019744C13B797B87D2C39C848FD8 -:1087100020DFAFD0BFE4E1FCE38BB04B8092D3E22B -:10872000D1AE3C2039EF05FA2F28FBDC84F40AAFE8 -:10873000BF87D6BFF690A4C11F1DF70269161CE0C3 -:10874000F0F1FC533B028AD61FE079B58666738749 -:10875000E495818EAB4BA4E0B0CC4BF17CBC4F3E9A -:108760008979802AD6BFCF4C8557F73EEE6F7A7F46 -:1087700018BD1F325FC5F83796316FD07669BB538D -:10878000A2DD058045FF80CB79B0BE60DEA5ED7B24 -:10879000B5F6DD068386AFAF7720FEBA4D029F1790 -:1087A0007678CB80FE8CC3FF957F617E208F4FDF74 -:1087B0001BB5FECBCDFFBD7CBDDD803FAAFEFDD04D -:1087C000E5F0F7C125F8D3F8A74ECF4F718AEFD85F -:1087D0003998475C92E444FB78ADCFBA0DFD803008 -:1087E0007F986B703DDD56D6C7CF7AFEB7D454C1A3 -:1087F000FAD632511FF308F93986BEF67C3FF4F100 -:1088000017F3E6023FA10980EF2779AC8F046C448F -:108810001FAA2738EB32FBA1230A2E8BDA3F1AFF5F -:10882000D3FE45390FF8C9EE47CE1478387E3E9511 -:10883000D87C9493DD95DC5EEC1EC6CB791E89EA6C -:10884000277A381DA66865774C041ED2C374869FAC -:1088500010FA2311EB263CD52469EB0E8CAC990958 -:10886000EBEE4EE0F5D5FBB31F099485E1E8FE661B -:10887000EF1F59837CD3D77F60C4BB88D71A0D6F95 -:10888000F3F6E7BE1BE0F250C27DB9861804A87566 -:10889000400AC8B0EE35C817FDAC3BCD73C9BE0A5F -:1088A00044BDEF355EE6FDCC4BDFF746BDCF8C49CE -:1088B00057F3BE46B79951749D1E45D7AA28B8569E -:1088C000C0419DFC137271C9C107DA52601EB7EE38 -:1088D0009350CD44F07309F1F3AD4EC1BF13DE45A3 -:1088E000791FE6E75282E776087E9DF808CAFF39CD -:1088F000280F4BC3F03C94170497D578C745EA8BF3 -:1089000049547F63BB683F99E005ADA2BFF2475071 -:10891000BE0A3A02FA6A70BC9A42A12F2ADEC5F654 -:10892000AB0EF1F737792ADFBDEC7ED81E85979D17 -:10893000517020AAFDF7BE45BFB446BDBF21AA7E37 -:108940005B14BC230A6ED7BFBF78A944FB7031F01B -:108950000312E2DBF6E5C39E3E3BB54F9F4A36B2BB -:10896000DB74FBEABA160E073DB36BDA6D11F07ECD -:108970005F8D266F695F1819FF01591B407D651CCB -:10898000405EDE3F105FE646EB5B5EFF27FC351581 -:10899000ED60A6B30B8ECA7AB853D6E61DB8F9DDE2 -:1089A000DBF3F0A18017D6A07F70DDF7F5EB02BFF7 -:1089B00055ABBFA9A6AA2CC22E6137119F88758A14 -:1089C000F6D3BEBE28E3783FDDBFA0662FD4D756CE -:1089D00086B2EBB14CE025E83519F5E63A2D2E3399 -:1089E000ED25D9877AAD362694DD106987B08E1CC7 -:1089F0005C67E73D32D127D002F4C1381B739B304E -:108A0000AED21917D7F814B43F7A8FDC887AF4FD08 -:108A1000C6C4149C7F6A01B7238FC60D4D590670DA -:108A200067EC22930AED3A374FA5F288ECDDD40BC0 -:108A30007BED379E5535B691581F47F8E9DEBFAC40 -:108A4000A619F6C13B1E95DEF72738530EA2FD7C12 -:108A5000AF913DA9E27CDCBB886FEE33E7A31FBD7D -:108A6000B879740ADA934BFEF79C69A9D06E499BDA -:108A7000D12D513B3616E7EDBF77AA09EB97B66AC1 -:108A800065E01A2A5FFEE6891607B4EF7D5C72EF97 -:108A900081F693BEEC787D2CC02BDA87BB913487AE -:108AA000CF1B9813C6F960C788A00CFCF8A1B5FECF -:108AB000D559BC3DC3F62B2EA86FCE2AC4F6B2738F -:108AC00023B43F09CFD11E3EB945DE23E1BC1CF6DD -:108AD00018099674F26BF54DB46BA1DEB9119E9F27 -:108AE0006C5B998276D649497548B0FE5E4F638DBE -:108AF0000BF865C50EB346BFC6D4C5B0AF171BFA99 -:108B0000F885F4C7F2780EF7EEBFABE64998FFC9D7 -:108B100047463810CF6B0BBC5F78501F157ACF7A61 -:108B200092719E5C4FBDFC8DBC08EDF15F9C59922B -:108B30008271BB0B1A1F1F3EBF24654984BDB3FC65 -:108B40005385E8FEB249BD1DE7F9724C8684F12CCD -:108B5000A07B22C6BD976A7E26F06FE3F3FDD83D69 -:108B6000BFF7C844A78FCC8DEC43D8549D5BAF9F13 -:108B70006207BC74BE28111D96327F0BC2ECA0E4C4 -:108B800046FA45BFFF9BB195D682A248FEDF4272EE -:108B900096FC0D80139FDF44FA906D800713A03C74 -:108BA0006A253FDDF8AC3568057C2E4DF24EC3F6E4 -:108BB000CCD59133D71EB14FB5F67F0CD8A9FD1F88 -:108BC000A13DFA7B7F0CFCC1CE6C97DAFD2B1CF625 -:108BD000001A1F1FDBED0AD2ED7DA5E9E4DDF0DE12 -:108BE000F2C78DA427963F9EBCA117D701FC95CD57 -:108BF0002E5D87BFC048F81D70DFB2EFD754E9FC87 -:108C000089872FBB6FC7143C5CB3376FE07DBB42D5 -:108C1000F36BA63D6EF4E1BE5B51645718E89BCA46 -:108C2000C75F7912F7C78AF5568F1926BEE27133EE -:108C3000D1B7C76E0F38A1DEEFB02BF1504E2CE04C -:108C4000FCB0B040A5728ACC148B87CA568CAF9EFC -:108C500085F924027CBAF1A187C7C3389FB0E00D23 -:108C6000E3017F6791508097B307648A3F32C5ABB9 -:108C700054833CAD635C8EAC79ED795305FC5A5757 -:108C8000BF6226FA812B83C60F7A341FEFA2B64C3F -:108C900094BFEBF823D0C3FAFA756CDB17F2586275 -:108CA0007B13EEDF351D51F5F5D77C8C719C754C2F -:108CB000F9A047C479611EF30AEC49274703E06134 -:108CC0001EC0103B5B6FCC61B0C41536D887B0DED8 -:108CD000293B797C6745A31C3443FB29893C5EFC16 -:108CE0005113D07F04AD3BE00478C5F7B85E5AC19C -:108CF000A4A0057EBD66E77A05F7CF2B1E8EA7C51B -:108D000012F3E17EF8D0EA1E82FEFDF2C7AD84DFE9 -:108D100015BB56FEEE1178AFA7B93A29D29F5EA9CE -:108D2000F105F4CF2C09E17E3E6EFED7212807A77E -:108D3000FC00FC6258EF8A78F6939A4CA457EA102C -:108D4000D5166EB762E33D39BC1DF8D5B0EEC55BF4 -:108D5000641EA77AC14C7A1264838BE4B886CFA5CF -:108D6000ADAF994C7928D7B775CBD0FE0380651B82 -:108D7000E12BA0E1D184F85A84EFA6F2775CC59A82 -:108D80009DAE92DCF1E3FA6A0DD2A2B9A4077A4D46 -:108D90002807BE5FC0EDDE6D5AB97888FB668A434E -:108DA000DF6F76A35CC31F59CC03FCB03586EEE5BC -:108DB0001807663F35533C655DABD56B75909FE2F8 -:108DC000DD8FF3539862C2731795CB97EF6B7CB826 -:108DD0004E9D730DF20DD41F57A07E8D9DCBD135C6 -:108DE000F180776ED77A0D30CEE7F8DB70DE6FEA70 -:108DF000D888F125ED39F4A33AC2FD7619583BC65F -:108E000065B0FDC8B188C7C41BE6E3FC7E2CD37EE9 -:108E100086C5DF5F8276E18FE502F487176F393A06 -:108E20006D07C2CFE53BB1CBC53F7987F4CCAD1A16 -:108E3000FD7BD03F40BD03F073507668FBC92FF334 -:108E40003851878627C107A27ECD16238FDFB799B9 -:108E5000C9EE59D3FC7BEA778DBD3B05E5F59A1742 -:108E60008CC528D79FD7E6BDA439A3EC38F0D5121E -:108E7000639C538247AB03D52684576F97080EBF78 -:108E8000973C04F9F4CFAD2F3A907F3EB486B251AF -:108E90007FF5AEB7BAF7E002B438DD9F5BB3F76099 -:108EA0003C67A9B3DB2E41FDD2DB8727A0BC7FDF67 -:108EB000193261FDFB1D990684BD4E6719C25E65BE -:108EC0001CC17F0651D6A1F9ABC86F6B254EE7D503 -:108ED000CF1E350D83F18E17F0B8F9A73F7E270717 -:108EE000F5DB9A21DD39A887800F72D210CFCF48E9 -:108EF000A4BFD73E2B7BAD63C37CB016F900F6DD73 -:108F00002A8D0FD61E78F12EDC0F6B91FE9E4BF949 -:108F100008F8F4183DDFBF7B1AE3EF1F433E117AD8 -:108F20000FE05623C6DF4C1A0CE320FCAE864FA898 -:108F3000AFE2F581BC7A1E5733A19DBAEEA031D0C5 -:108F400013716E34109DBF2AD0CED19ACD2477BF35 -:108F5000D2D6DDB3E50507D2F1D31F1F7D15E3C5DA -:108F60006BF6837657FBD9171A5ED6211E1CB40EFA -:108F7000B247D6E1BA1D613CF4F1BFB61FD731BE8E -:108F80004EB1EE758A860751AFBDFF176D9DAB9947 -:108F900086B70323F8FED3F61BEE6794AB627DFE23 -:108FA00004FEBEE0D3F442BE3E6321E7D7D5C0172E -:108FB000EE3CE21FAF49C809A8FAF4B9DD142F123C -:108FC000F412F31E5BA80A79E78D4F08D3B1C7C02E -:108FD000EA3AFA89B3241772FC9D681B34E420E056 -:108FE000EDCFE097A1FD85FCAA448C27F8468C378D -:108FF000E5477366E07AA1FF10F62FC67D3F10AB00 -:10900000603FEF33BE3F903F517E8A7D39A565E1D9 -:109010008C7C07B6FBD43E3C0FD7CBC71F5BE8A4C4 -:10902000F7BD682FC0FBDE8312C5AB4F687180139C -:109030006D2F3A9644E0294F7B4FF019FE601C4B90 -:10904000CCB72B81C77FA3E72DE49098F794CD3759 -:10905000CEC0E762FE825F057F0A3C0A3E651B9236 -:10906000C9AE89E657E235A157659DBC27FD784D0D -:10907000FA1726BFEDD2E7D1709FFDD4EA3A9615D4 -:10908000A1D73FC4380FCA93A7E520C913065C1BBC -:10909000A17784BE6F5E7F8D13CF198DCF4A6E345A -:1090A0007D22F4CC362542CFD415AECF417DF6607B -:1090B000E1302EF793BCA7919EAB4F754F73A8611B -:1090C000FB75D29721390EE36107323D917A75F530 -:1090D0009963B40FD6B0EE4DE87F2DDEF24EF578F1 -:1090E000E4F7A78D74EEB9B86DAA09FD81954FDE3E -:1090F000528CFCF441FB7092EFA7F71615107F31EC -:1091000067CA0DB00F96EE7DE88605F07CE941D97F -:109110004D721EFAC1FDBBF88E0226D1BA7BAAF1B0 -:109120003CB5F76ED98976FFC4278B3660FB89F68C -:10913000A1F1B80EEFDE4482BD4A1CE909612FBFE0 -:10914000AFC9CB1623E78F0DDABEBAADAFE4FC335F -:10915000A5A52507CFE37B77839CC6736993DA11B6 -:10916000C2F15E1A447EC93A70A35C40FF5312B745 -:10917000CFEA4CCC92EAA1E7965478FE9AB1FB0E66 -:10918000D427AFDD61CF6FC609C8178A97707F9269 -:10919000E60176348D2FF026E6714F21D74FD1FDB1 -:1091A00089F7BBD0FF40B9AACDFF74EBD337A03EFF -:1091B0003CBD2F3B01D7FDF14BD676B4AB3E3672AA -:1091C000F9D867EF048D1F45DA6B60DFE960B0E71F -:1091D0007430F0F1477AFB7023CDEBBE429BCE9EFC -:1091E000137C5FBB3E3B2E320F21DA8E6759D1E7ED -:1091F0003DE3E3583F724794679A0051C0A873D08B -:10920000B68771AB62BF7EBE1BEDFEED66A719D6B9 -:10921000F911F23D9E67BD2007F1FC066D74DC0775 -:109220001F3D971F44FF73F97BFE69D8FFB10736D6 -:10923000539EC232B033074911F6F3F71EB801D975 -:10924000FFACDBBF2915DE3BBB8FE75540B52DCA10 -:109250006E7E3555FDC7EDE62BB597459CE2E7855B -:109260009ADDEC666EC4B3C0AFF09F5E063E28F197 -:1092700084F1F559531DD9CB679AFC547E2E9DB8C5 -:109280007F22F2AF3DCEBD075EFBC5C187E434A4AB -:10929000F381FC0BE82F97DAE29CB86F3F6B6AA46E -:1092A00043CB334DF5540A3A8B38DDA4039DF4DEED -:1092B00067070B0E4D84F70EDBE2B81EB8E49C88FE -:1092C000D3333A8FE4B6F5E307E173B1AE4FEEE680 -:1092D0007415F3FE64DF2D0E5C57E7638987262043 -:1092E0003D63E39C68F7ADD0F2474EEEE076F5299A -:1092F0004BDC533331EF64E7BC1406F27659E77761 -:109300006EC0E7CB5F929CE80FB85F9AE3C078EB42 -:109310007F283D0E2796F05E08E7A304659447A5D5 -:10932000D3199D63958614A666D2D130F1CB8433D0 -:109330004A10F34EFE8CE75B1847B910437114A630 -:109340009D5B2DFB198FBFF4F9B99A9F37515B775D -:109350004A5102E76FEDF99412FEFCE39DCFCFC2B4 -:10936000FE4EEF353A71DE9FED3552FFABC03F3315 -:10937000C07C4FEDE37ECFAA0E89FCE5D3FB406FA6 -:10938000C3BAD6AC377A4D7197F2E114A8EFB18524 -:10939000F970953748FCCD347EB4C0BF8BC32EE541 -:1093A000C778D6B109F1F18FF2A5AD48EFC7F5F155 -:1093B000E3407CA0E10BF731F2A3A0F72AA00B9EBB -:1093C000CF2674E457205F09FA0B3911A864B9A8B5 -:1093D0005F5B4C2C17F37802861837EEEF3936D5E1 -:1093E00028011EE625F554A138BDBB88CB49798AF2 -:1093F000C16B40FDD2622639102D47B28BB8BDF447 -:109400002CF234FCAF2872723B8AD5933F224AD0AB -:109410003B19A8C7E7C426FCA70A4D3C2F7C7F81D7 -:1094200002F39F3331E18EE16EE09B171E5FA000D7 -:10943000FFCE2948786118C065453B393C2EA1C84C -:10944000087073F3AE055500D71479DD45C9E17195 -:1094500044BFF0BC009FFF7CB4BF18CB75261BC96E -:10946000E9CFA5DEB18D99E1F66F49ECFD5F48616A -:10947000B8C7C886A09D57D137FFFECB8D45DE7299 -:109480003EAEFEF912C6DA28FF2EF0CBE312F7C784 -:109490007C9614CA6323BE5A62B185C8AF6F379EEB -:1094A000E9A337F2913B4E41BACED2F868B612EA40 -:1094B000C4F747B256E7490B99523B2F260E2CBFF3 -:1094C00061E3B193A23FE097CF8DB05EE06B09D826 -:1094D000B311B68C0448AE05F9251DFAE55FB1DF7E -:1094E0009600EBB1121D6A9DC86712F31B2E42B99C -:1094F00026D63116E3276B62870491EF1B5EF8F4E2 -:1095000018B2D74A61BFF84B88DF6F77F2F5307F2A -:1095100029F1E31D1A3F7EDCC4EAB360EBCDEEEE29 -:1095200076A830E933B34239B8DFFF34C45F5784DB -:10953000FEFECE96F406E09F4FF79BDD33A1FDA91A -:10954000E0F314BF5BADD9A56C6FB2B6EFE550394F -:10955000B4EBCA1CB907F54B4311D7D76732434365 -:10956000EE41B991C9FD2068477972D3375E938C7B -:10957000EDCE3CB7396B19D0CFACB0803D814AE617 -:1095800080755F0B7D97006C0458A673E020D10BAB -:10959000DB3950DFABB7B8789C9EF950AE087A093A -:1095A0003A5C421F9802DAAD060B33E2FC47B29DEB -:1095B000CE93B1613A7D6C013C621CCD027884FD92 -:1095C0003D15830F85884F1E7769907A5A1311FED7 -:1095D000B144797797EAC1274D88F2BA9DB790FCDC -:1095E000117247857FFDC99DAB8E1FED9CD2AFDC0C -:1095F000790CE50EAC83E5B3FC8BDC4024FAAED0ED -:10960000DE9D2AD7AA0ACE3BD9E2C6B85AC3E3C325 -:1096100049DFB00BBF217F58B4633B13895F3665C8 -:10962000CA84F79507259E1F79308DA95035F360C0 -:1096300022958EF3A9F4FCF453AF1772B9C4E95222 -:10964000FDC3419594AFFAC311548A7934687C37CD -:1096500055CEEB08A11D61837900DCF01AD75B0DB4 -:10966000D7CB14DF6428A2539098FCC7676BA73848 -:10967000908FF5D9F9D245B2DFD538A48BAF4B66C0 -:10968000C83FE07504389E2DCD8867B3CBC0D47E2B -:10969000EC0FB34627AB1AC3D408FF43098CFC6E0A -:1096A00019C665BF637407A1BEC5EAD883FB8905E7 -:1096B000BCDDE847CCD7DEEBB672FE88CD4DD0BD21 -:1096C000BFD931AD0BF96DBE97EB1DBB7BB06E7C86 -:1096D000B3BCDA884CC6FCDC5E14FC407C09E3CEEB -:1096E000F649A45FAF9F0FF511FD1ACBBE20396E6E -:1096F0002CD3DB99669FBEDD1F84DE19C94646D296 -:109700003F8C779B17EDF4B35E3BF13168F7EF9731 -:10971000017C439791E17ACD317C5D671153181F2D -:10972000F5CA418C9B6C463CC0F3B8123D3EE3BD8C -:109730007AFC254ED7E323D9A75FFFA0F9C374F5C0 -:10974000A9FE51BAFAB43A8F0ECEA82FD5B51FDABA -:1097500058A98333033374ED87B7CFD5C1D9DB174D -:10976000E8DA8FD8B144573F32B84A573F7A5F831F -:109770000E1ED3F12FBAF6E30E6ED4D5E787EED5E1 -:10978000D517743DA8838BBA1FD5B51F7F7C8FAECC -:109790007E42CF33BAFA89A7F6EBE049BD3FD7B591 -:1097A0002F3F7F440757B0D775EDA758DED1C1537F -:1097B0009D7FD0B5BFC6F5A1AEFE5AF5CFBAFAEB84 -:1097C00072CFE9F93586CBBF6AF7DF74EF7D9EE68D -:1097D0001F558C3A533EA320DFB62C945822C6D591 -:1097E000BBE659500EE4156B7248E3C3E1453C2ECD -:1097F000C1B2D810946753E5990CE376673BB87F04 -:109800003D90BE8B0375A5448C1BEFB58003198674 -:1098100013A73B7570B2CFA56B3F68BEAAAB4FF5DF -:10982000E7EAEAD3EADC3A38A3BE44D77E68A35716 -:10983000076706A6EBDA0F6FF7E9E0ECEDF375EDDD -:1098400047ECF0EBEA4706EB74F5A3F7D5EBE03114 -:109850001D8DBAF6E30E0674F5F9A1765D7D41D74C -:10986000761D5CD4BD43D77EFCF1A0AE7E42CF3ED8 -:109870005DFDC4531D3A7852EF415DFBF2F3211DAB -:109880005CC15ED3B59F62794B074F75BEAB6B7FF2 -:109890008DEB84AEFE5AF5B4AE7EF59FDD213A071E -:1098A000F8053F57BB2EF70B5DBD3109EC5A8C43D1 -:1098B000B218379E5F0AFBA7DAFD575DBFF7160F98 -:1098C00023FB0278A9C72AA37DE4A3F85102261638 -:1098D000025FC6811043BE4257A196E25049A4EFF1 -:1098E0004835A99827047602000986CC4CB4A763B2 -:1098F000C3765BFAC5822BB7DB76409F388F5F1645 -:10990000FBEF2B4E467FE5B96968B7AF64814D38F0 -:109910000FD07B713DB03FDEB4EAE319A2BCD602A2 -:10992000F88918EF35EBF674CF65FCFE6B2D67A850 -:109930007D5FBF5A9C4382F53544F47F3FF8150A9A -:10994000D875DB9B60FF80C3F8609393E0EF35B977 -:10995000087EB849A57247532E958F36B9A97E6700 -:109960005309C1BB9ABC04079BA653B9A7C947CFEB -:10997000F736CD27F829F0A3B1DC077E3596CF80E6 -:109980007F8CF5CF82BF8CF04F9A02547634B5D3DA -:10999000F3FD4DDB093ED0B483E09F3605A93CD8EA -:1099A000B48FCA9F377550FDA1A683041F6E0A119C -:1099B0001C6AEA22F8485337C1C79A8E13FC6A53CF -:1099C0000F955D4DA7A8FC55532FD5BFD1749EE0D0 -:1099D000335ADCF6956249776F4AC08C55113F08BF -:1099E000FB7016DAF9C81C25C6CF74767E94BD1DAF -:1099F0004D8F4FB4718C95602E62FC7070CE9E9628 -:109A0000083FEB2D6DBCCD312C6005F9D66CE07EA6 -:109A10006D7302A33C6EA6D9AF2B34BE6449DC6ED5 -:109A20005DAECD6B85C6FF45C89FB9C49F6F5C8D89 -:109A30005F21FCC65163FC27883F330C01F29F6D08 -:109A4000C11CB49FABC7F83F42B97EB67ED9AB34D8 -:109A50009ED34DE78FD5E650F28D181F794DA6782D -:109A6000DE40E3ADD3F2CD07AC3F7C3A1DEDEDE92E -:109A7000DFC87EC4D39B46FB7C8C17FCA598FBA754 -:109A80007F2936E8CA77C6F8BFC2797E65AFBFD9ED -:109A900000F3FF6AF2FAA76ECB0CFBD3B3D1250516 -:109AA0003F680E538D94D7C8BCAF644257D78381AB -:109AB00085F08D2C40E577F2FC17715D35608823C9 -:109AC000EC2F350FE96F5DD1F38A19CFE71533DE3F -:109AD000A02BA5B17EEBF8229C9797E6F5E6846B68 -:109AE00072705D625E956355ED3E44EF2E9CDF57CC -:109AF0002F7D71521A1EC6BFF0DB375568F928EB6F -:109B0000251E9713F69A96CF22FC8EDA3BA420DA14 -:109B1000EB0BC1DFC173A6F734FBF33D2BD7CF6747 -:109B2000EB8D24276BA518379EC79DADFF0F1BB289 -:109B300035B467785ED282894250DFF2AF12F159B4 -:109B40002DF463807E8AC666D27A6A99C58BFAB88C -:109B5000F6907937F26B2D987FE867019FE48C4788 -:109B60003E9920074C6007BF6908E648742EBDCCBB -:109B700024C1FC5624017F0C1B980FD66AF719C428 -:109B800073E02F37F6F7D9CFC6E7521CFFF0041564 -:109B9000F1D562E0F79802BF92DD3C3F868B687991 -:109BA000E2188A4F32C5EDC6F852B576EFA5536676 -:109BB0008DCFF5233FE78EE7FBEB4D97717A90FA57 -:109BC000D59FD7CC18CFFDD0195ABBEA23AF65E09B -:109BD000BDADB55D46F24358614F9ECFDECF7A1AD8 -:109BE000B7DE9915C1D7EB0E9EE0F91AAC272F32DC -:109BF0009FFD56AD5FC147B2C9EEDF6D8B9C1F1F45 -:109C00001FF87A0EE2E1AB78E0EBE1C4D727D1CEC2 -:109C10009E6556E36E84B207501482D2FF0327E597 -:109C200027893CA5A5CC47E50A6003E4635FE00112 -:109C300013E27F15EBA0E76B4B6E1982F03AD65B0F -:109C4000E5423FA2BDF91517CC72DEF607A6625CAD -:109C5000766E70F12B58CED92B9D44BF15F6C512E8 -:109C6000E4E31EA9BE6D308CB7E0D98AB634783EE5 -:109C70004BE6F460AF737A00BF78E5844BD709FBFD -:109C80006015ED83782FAD43764CD7ED83DA8DCC1C -:109C90002B2585F3EDFBF645C9AD7F4A433F48E9E7 -:109CA000A5F3F77587CD0948E7558CEBEDB01D2876 -:109CB000F435B7036E053B00DB7DA2F1F327198C69 -:109CC000EE357C228163E709DB916C88DFE5191EA4 -:109CD000D6BB9F1882C58EE1A4979B71BEAFBAE632 -:109CE000A9182FBB35C9E296B13E3E38849FA3F632 -:109CF000C9777631361CEFBADFC8E34FD1F3924A09 -:109D00005EFD2BDA0D66130BE0B906EC6B568CFB8F -:109D100079B089F6590BA216E366953EB5BFFE5B96 -:109D2000B57EBBBEE6FE6F00D683F77C2E19C7A9B1 -:109D30008D13C3C711FA03C723F991C274E3ED1958 -:109D4000CFF7F59B762FCDBFD9104FF2E60F43FD2D -:109D5000BB91EF44DC47F8855D991F6791FF7EA1B9 -:109D6000251DED73E05F9EC73899CBA5378D6A003E -:109D7000E1372B3229EE2FE4EDEC121E279B2DE26A -:109D800062655171B1A8780C2BEB3F4EC698DB8809 -:109D9000E38E64EF09FC501CE6489942740F00DD25 -:109DA00031CE7C44F34F2B62B95F9E509248EB4C0E -:109DB000B8368BF8CD91C842740E659789DF8EB2A4 -:109DC0007C5B42849CB8578BAF6E033B8845C4D5FF -:109DD000EF2D6CB060BEC1661BBFFF785F654C5D48 -:109DE000647E7CE2649EFFF2C3C915AC04F0976701 -:109DF0000B5692BAF62A2AAE47D2D637DA09F83786 -:109E000060D73E2D4EEAB6F0B85415E96B41F72BFA -:109E1000D5D7CF28C18D31B8FE2446FBD0BEC34A6A -:109E2000F254EEF08630557BD9E4B9EF223F33C5CA -:109E3000978BE37416C7301BB4FFAAD344FEFD61B1 -:109E4000C3921F9870FFBD6B6678DED9614F535087 -:109E50005F747C3DAA8A4AFBC4698CC739630D20B4 -:109E600028F29DEC897F43A269F7D54CAEA3933EBF -:109E700002147748AC8B51DCCD1B6B009FACC3C088 -:109E8000CE95C3FCF6DB3C0F8D2316F4C9B8DEA1DA -:109E900093FC9F227F15B37A82EF33F9EA76C3F8F9 -:109EA000F72558886F3CA906BA3FC8FE6AA3BC1FB5 -:109EB0005F97624415F76299FFDCF808BBCCE73284 -:109EC0001831FFA7CD04F23B0FE32831FCCC8A7197 -:109ED0007BDF773E87E6F78D264F5B5DDE6EBC88C5 -:109EE00032205E9D4A6F5FDC84F8329DE27D02CFB6 -:109EF00091F47416EBE8E93746D2B304E8392692B8 -:109F00009E5EE96AE8F90E26A1155DCAC7814AF589 -:109F100081AA42AEFF30952E9A8F2BCC936C980776 -:109F2000D3E9900D48D7CE98B43C8CDB093E167C23 -:109F3000DD0F3FAF3F8A72255D71E279B2B93A8693 -:109F4000CE67047F0BBE9E5EDAC7DF8F95023E1799 -:109F5000DA7C5351F644F337C6CF22F9B876407E07 -:109F600067CEC87D3E0BEC8DB804B4934EEDED8802 -:109F7000E0E3DAFA2F142E772E96C71487E37DB329 -:109F8000CA24F64124BDE1FF07B9DAFAC84E52C827 -:109F90003F1378BD52FC1BBFD39C8B76DF26BCFFE2 -:109FA00008F86A97DCDE411807AB3F711B3E6FD3A0 -:109FB000EE2507F24CDC1ED3F695E86FD9E4CA69AA -:109FC000B8FFEDE3CFC42E87765FA51854444E9BAF -:109FD000BAE4DF689F1E8F65F89E23B1BBEE09DAF5 -:109FE0007723189E277EB5D23F14CFF7B7009D3E4A -:109FF000A0A4EDE020039D7DF50CC27D07C875F19E -:10A00000D2EFE2CF99561F24F80F138669E78C5ED2 -:10A01000AD7D0FB5DF62DA6E89C171322DCE3D1193 -:10A02000FC5FAEC5E35B4BC4FD9F1615F3DF5A4BD7 -:10A03000B83DFB50D3BE491F65E37C3A267D04F34F -:10A04000499C19647EE0EB98DC808AA923966FA670 -:10A050004878CF818D621D18A7C7E7CD63C2FDAFD9 -:10A06000D4FAB5A09D03F4B36C0CA89172D662909B -:10A07000FCFDE5C9FC718242FBD5B29151BDE5C83A -:10A0800023F4FD80C42CB784F9D5968DDB199EDFAF -:10A090005843FC795296575A1AD16FD24C9877048C -:10A0A0005F007F05E2402E59F6006316221D6228EC -:10A0B0005E193DEEACE4CA2EC531309F44F31BD38C -:10A0C000F84DF08D5827DD8089F80E40D5300BE92A -:10A0D000C9B646D36EB4CF7795C4135EBE4CAA8C76 -:10A0E00063FDD8A7A2DC057C1030A33F6DA1720FE1 -:10A0F000F8E38111E84FBB087E0AFC712CF7813F21 -:10A100008EE533E08F63FDB3E08F23FC13F0C711BE -:10A11000EE007F1CE1FDE08F237C00FC71847F0A50 -:10A12000FE389607C11FC7F2E7E08F63FD21F0C735 -:10A13000112E37037FE07A7203AEB940D7F6BB4DDC -:10A140005ECC33FC6D0997A747BDC312DD407F6B22 -:10A15000AE8162E5D6371E64B81EABCB40F7CC3675 -:10A16000B91E64B7A09F5B6C277BABEDC7DC8EB1DB -:10A170002A0F31943BBBA4401D73C3782537D5E229 -:10A18000B960966B7D6502C0474A16EFB4C0FEC841 -:10A1900051E7CC6F8E8055BB67D573CE303C346FA2 -:10A1A000B7029E0CFBE5C15B76E215239C07E61720 -:10A1B000BF55B2BC16F3EA43C318D923BD9926CACA -:10A1C000E3598AF4CAC6F9F373C0EB588B0BCF3945 -:10A1D00087AAE02D49D49EE24C57DAFEB7252A3DE6 -:10A1E0008F7EEF72ED0C8557D48EC997E90FEBA5E2 -:10A1F000CBF46391E659BA61EE5B8D9A9C4AB691B5 -:10A200009C6AC7B80FE0BDDDCACBFC52BECF8DA59E -:10A21000950F4F80F2E1099CAEEDD680B312C71FB7 -:10A2200063A03C07D698F9CE3018EFCE5F290CF327 -:10A2300045057F9ED1F8207BA89DEBEB7B2C74CE4F -:10A240007FCDD01FB726009CFD84DB8DF9105B9974 -:10A250003B06F924B0CD4079913F2A1C9E30079AE5 -:10A260008F2E7A2101E5FA8C097C1E412D8FA8B929 -:10A270006DF9508C537DF51697877FD3C6D96DEC59 -:10A28000AE277A16D918CFCBDA4EF648B30B880D25 -:10A290003AD390CA4B93D1B900DB99C030C0BC6DA2 -:10A2A000D3D7E32DE80FB69C374FE779B5DD649F30 -:10A2B00098AC7E673C3CDF1E30905C68516D940723 -:10A2C000B7D5E6E9C27BD301A781F265B7E61908E5 -:10A2D0008FADB61B82E8072852731DEAB1A073BF89 -:10A2E00025139E07F30C94FF18F4CE9D8E70C0CFFB -:10A2F000BF47413F58EF4FA0FBE25B59EFEBE3B0A4 -:10A30000BE96DB696D29FF752416E3E2D73BDDFCC1 -:10A310001886A9983746296406F4C77B36C6E23CFE -:10A320006A98E6EF06C8BF759839FDBEDB79AD7354 -:10A3300018D91911E75D668CE1B92D6EA81F6BF372 -:10A340004C47FF53B17B2C9817D8EAF45816D3FA30 -:10A35000793E1BE56B40BF2D4E03F9C1587F0BEED4 -:10A36000F75646F97083B5FA56DB839D880F651959 -:10A3700063992ACE4F09449E275A869775A9B08EB5 -:10A38000F6E509B40E457213CC962934EFC16A0C78 -:10A39000DD937EC854DD85F6E460CBAD74EE955A4E -:10A3A000A7E8CEA506F9F570F27C3D9CC894F0B9FB -:10A3B00016F2D9041197D3E32D1A1FA9CED6B77080 -:10A3C000FEA97EBAC47BC9FC1F717E2FBE82E13C10 -:10A3D0006D34CF14DB920AB49B9299AF19F9EF1F39 -:10A3E0009DE758E75C4B268C3F36C940E6D138D60E -:10A3F000BB11FBDDAAF17B7B26A767785FC9625F93 -:10A40000364D48C6F305033874E1FE3303E0D8E95E -:10A41000CE17127470F6F6C1BAF623760CD3D58F28 -:10A420000C8ED2D58FDEE7D1C1633A4A75EDC71DD8 -:10A43000ACD4C1F9A119BAF6055D73757051F70274 -:10A440005DFBF1C797E8EA27F4ACD2D54F3CD5A025 -:10A450008327F5FE8BAEBDB0EFA3F5E3DD13B87D2A -:10A4600071B576BDD93558F7DD9C68BF21DAEEB7F6 -:10A470007CD3A26E447E7698889F15D4E7780E7DB3 -:10A4800037F79F2C93DD2AE5396BFC5854EEDD84B9 -:10A49000F2B4C26121BDA0D8783BC5368DEC9521C0 -:10A4A0003B4CF43D1FC5C9FAEA63513E37052665AA -:10A4B0006587E76D756E67B87F2B1CD319E6298910 -:10A4C000F715A797F9318F1B3FD28376923340ED72 -:10A4D000AC2ABC1FB18EC30603B3A11C073F0FFDFE -:10A4E0008381FC3AE1CF09FF6D20BF4DF86B430C2F -:10A4F0002C06CBDD52CF6DE8DFE7D5BF553988910B -:10A500005FB70FF9F53EBC078EFEDC586E67B5A548 -:10A51000CC5031DED39ED9D1350CE7936CA0382ACC -:10A52000D8CDEEB911F6E2DB9AFE5186B5F7A0FE62 -:10A530006B88B7A8682F2996DD933E027CED32F632 -:10A540003C8DF18B56C9B9BA03E5E2DD36CA0F7905 -:10A5500048C39B6A37146C847E3B9ABD0ADEF7EFD2 -:10A56000D8C2DCADB83F922A36C6C3F3ECF4C506B8 -:10A570000C138DC86ADE88E5B109FC3C6864DE6EA8 -:10A580004322D48F2EAC988F7131D9B99BFCD981DD -:10A59000F84976EC60B81E96A59C44BE42EBFE22BC -:10A5A0004CBD2201E80DE35A91DE12958407EB7948 -:10A5B0005BD08A7016C78BD52B0563256EB7627E7C -:10A5C0005D45C20EA2AFB067D1CEF5737FF76DE4E3 -:10A5D000A3A4997ABA2A96BD848FAD06BE2FDAE37A -:10A5E000D537503FB7676625B4A8E1790AB9F24775 -:10A5F000CD0E17CF855C998D3938C961FB06F87C83 -:10A6000007C6E7ACCA76BAE769DDB09D215F5BF1AA -:10A61000563CD9FB01D547FAC3A7CB4FAB1A36DF5F -:10A6200082FAFA5C9287EC596BE34F697ED178B37A -:10A63000F6F03CB581F0EAC87994F43B086015FD6A -:10A64000FE2329B6BAC8B8A828EFD2FC13A3C8279E -:10A65000024F02F5D93991AFE48DE5F38BE7F0D1E4 -:10A660009C0534BFDB923D832E676F5BC1DFF447EF -:10A67000D07D8BE2B3201EDA2ECC994EEB56683398 -:10A68000B0AD5FE7EDA678B3E62FDDA5E1B7B58401 -:10A69000E3738889DF337027CDA4EFA40DC6F84893 -:10A6A00041385E32AA94E737BA034CE6F1BEBEFCED -:10A6B00076C3C571346715EF1FE09920F2631AE382 -:10A6C000FA0C9A74623ECBF076459F0FAFE9F334F3 -:10A6D000FE3BC87F7DFD881D7A786430EAFD00FB73 -:10A6E0000DEA7BB477299EB14F5FFF18EA6D901396 -:10A6F0004B35BDCDB6F3FC120BCCE822D7B761FDCC -:10A7000007F260564777452CF49351A2CF3B498B13 -:10A710006C07F8F3AC34D0BD1211DF1178F7D519FE -:10A720008C26E27F55770E27E239D1F25ABAE7CC70 -:10A730007ADC5715B1B12ACA598C77F8CDDC7FF78E -:10A74000833F739FE2FE7D2DFA5F5D32E561097AFA -:10A7500046D37F6F9F3DEC2B2F253FBAA700FD7A94 -:10A760001CCF1F319E88CB6497FBA7623B119F399A -:10A770003B5D794552C3F116113F7818F719B4DBE8 -:10A78000EA7EBBFE28CCE3E87133C54AA6CA6F74E3 -:10A7900035619E55864272CE397EF50FD04FAFFCA3 -:10A7A00003D4635C52550791FDDE65A47841A5C6CC -:10A7B000EF959A5F26E2320BB579D7940A7B281081 -:10A7C000C3FDFF500CDAB9A3F7818CD6F34B2CAF45 -:10A7D000E771BA311DD1F55ECA7F1AA5F103E6AD66 -:10A7E00055A460BA18873B9894E8043A8F9BDF73AE -:10A7F000045D8CBCD75E8941BBEB392BE78F673496 -:10A800003B2F85496ECCEF4FD9677307A19D5D66DD -:10A81000CF75C33ADCC7145D9EDAD8437A388F45CA -:10A82000C099380F3DBC4DADC7A36BB6AD165811DE -:10A83000967C47A9964792C37290FFA6CAB67CF44D -:10A84000B31A2A6C0CF16A3E31E2FBDD2857DE9226 -:10A8500019EA0B67ACFA4015BCEF7C3DD1DDAC8644 -:10A86000E9FF0CF8DBA8471EBEE866ADC670FCEB3E -:10A8700059A067169D4F3BA9BE03E88AF07EF0BF42 -:10A88000B3E87C3A979EFF14FC6F840F82FF8DE53E -:10A89000CFC1FFC6E787C0FF46F887932B1EC4B819 -:10A8A000D97BD00EF92226FF806538C6CB6D32DD0C -:10A8B000DF89E6C7CDF51FDA6E049936CA953C33B9 -:10A8C00019F9E17699EE45432733D1BF8D8CBF4509 -:10A8D000C623C3F1B71E49C4DFCC409F519A7FD92C -:10A8E0001787F3F338DCB7F7E315FD509CF3927E3E -:10A8F000FAE29D96C047B928B2241607CF3FBDFBA8 -:10A90000DF9F427D24A7FAF7E23E5953F48189DBA9 -:10A91000E7FC5E56BAB68F765A793E6ABA96471405 -:10A920001DE79C3CE5C46DC980B2177F7ED3428C85 -:10A93000134CBEF544C11080BF29FD25877F78E206 -:10A94000F934C0D3D289ED1C7EE8C4B97437E671FE -:10A95000EC5F88F9C38E44AE07776AF79B047E8F5D -:10A9600069FB665DE313A4EFC11E61888F96141F17 -:10A97000E9E1CF937A1D8BD1AE4BEE4D597219BDE3 -:10A98000B1AEF1297A7FA7E43E15C4794FB0F0BC8F -:10A99000554D2F9DD57857E8A5062B07C57C187314 -:10A9A000D1F387B47811F3A6D17B89560E1F759425 -:10A9B00092FEBABF52FDB5CACF3FC98F3EEA18F525 -:10A9C0005DCCCB6B99AED0B9E443368F15F5DBE7A0 -:10A9D000DABAA0FF00C60902532D745EC492E6D312 -:10A9E000BE4E10E324D5523E4382369F63A53121EB -:10A9F0008C23B45459F6A01C7DD0368CFA6B2931C7 -:10AA000005307E23E08DA5301FC067BC2321136174 -:10AA100021E7447C99E1E91CF45BA92DBB52E44990 -:10AA2000588C6722ED701BEB26FE711B5419EDC884 -:10AA30000D13395F1530F77C7C6E92EA03C88CB831 -:10AA40000E43E43AD42AFD3AD4A9BA75480D9610BB -:10AA5000DA8F2D53611DD0FE98BD98E61B4D37B19E -:10AA60009E0F4B55C257F43A99762E25EE1F543A55 -:10AA7000CB0EE0BCA61ABCAD38AF57FE5A9B841F64 -:10AA8000E89BC6EA157C3E3C9C0FD47A35F91693B8 -:10AA90003F94F839DAAD265A9F71329FCFA3A66052 -:10AAA000265D0C5182A9787E3C101F674E8CE663B0 -:10AAB0002FC3FDD592E0E57CECEC7534231FC7F77E -:10AAC000A66CA47585FAA54F343F47D32B6F22138C -:10AAD000DF079111FFDF465F41D7E8F334C12F1B39 -:10AAE000263A05BD5DB4CED010DD7923F4A0F6770B -:10AAF000CEBE09FA5323CEE54C2E1FD9E3C62477E8 -:10AB00002EC6A55BBE91FBBD7F59ABE1A9D9114310 -:10AB1000767A8B83DBE99D8E193AFFAA0AFC2D3CDD -:10AB20008F96135907EE2B396E01C5DBE441689906 -:10AB3000115BE8EDDFB899DCFE757A2E7BFF4AE900 -:10AB40009175DF73BBC4FE4D98C1ED5F8789ECDF63 -:10AB50009D76D3FCDDFDC89DC289DC4FEAC475F447 -:10AB6000E35F825F49714FE1579A9C7EF20FC53ACD -:10AB70000BB57D26DA9B9DF50CE370B2C9ADA2BD85 -:10AB80002B6BF764312F3A37C22E10E38F9BC8ED41 -:10AB90008EC1E53C5F53E4C74FFEB554DF1FDED7DF -:10ABA0004C147649FF7CF70FF00DC9098FCDE445B1 -:10ABB000BBC36373511EF940EFE151F8A984B09C07 -:10ABC000717F532C933E52DC742FA0C3D8F3FCAF9B -:10ABD000D16F7CC5467AA7C39E4EFD09BBBD2296A8 -:10ABE000517E33F8C9815CE8ECB9BFC18E3484FD75 -:10ABF00063F0D7364F8C38D73CD27092CE8BA2ED13 -:10AC0000D5E8F843DF7E773C95C9E7134CC5FD2BAB -:10AC100035940C42BE8ADEEFA2CC70158C5A0AF332 -:10AC2000CA48CDA7523C7F9CC9D3FBFB6EDBAE3E2E -:10AC30003A703D3D12068B93493FEFC2797F7AFB14 -:10AC4000DB296E15EFEB7E417AFA6C7D49DC66E418 -:10AC5000F7DC0492AFE9DAFD33319FF4959DF109F9 -:10AC600036CC03EC1D89F973C126DFA82A23C50D54 -:10AC7000BDFDCDF757DAFE63A1A12CF2BB446A52A9 -:10AC8000F7B52300EFAACDE056697F3949FF0939AE -:10AC900050A1C4573981CF339A98DBA6E2A79B9D78 -:10ACA000143FCBB82813BF651CE5DF971E9AD42B41 -:10ACB000E1778FFAC6D1F2A4C439CC97F555B43FE9 -:10ACC000330631D68D7210F43DCAF92F934273705A -:10ACD0007F7FF93D3EA38C27F4F5A07329BEBDFC10 -:10ACE000F698A00A5D0FDD00F3C3F9FC4062E99914 -:10ACF000388FA3999B313EF4622CC587E41D59140B -:10AD0000DFB93ED5BF7F22CCE3D3A07AA761B8B626 -:10AD10005868B7E6AE18FA2EC14EA9FB5ACACBB88E -:10AD2000C340DF6D8DC6D75B13B95FF9F644BECF64 -:10AD3000325CC59CDEAEC2514B13AF7C3F7D83DFDE -:10AD4000D601FA6E8D0BD2799EC82BDB66EC9FAFD5 -:10AD5000CACAB87CE993C71AFE2CE80521BF489AF5 -:10AD6000DDB7EF99679E4961FC8AE2307E6E197902 -:10AD7000BE1C9315A4CA18B797E48FE4F47239EB9C -:10AD8000AC770580BF377F2DF73BBEBD4C93D31901 -:10AD900077BAB07D95EAA6B233A3F8F862C09FCD2A -:10ADA0006662E608392CF8245ACF37D8875DD6DF9B -:10ADB00037813C562F138F306979649B8E4CB0E0FD -:10ADC000774B37D93CDD687F6DB22579285E6F03FC -:10ADD000B91111BFB2D95E253EB4B9795CCF86F204 -:10ADE00017E357B8FE3C9CFFABB47ED1EEB4268788 -:10ADF0006CEE109DAB5ADDDBA99D45F1D1FD3B4BBF -:10AE000012A37C088B937FEF3426CBC02CFDC8E3C4 -:10AE10000F501E433F9BF23CDD95343F05AF65B1BB -:10AE20004D2E8F8BF421E219DE3F6A2F8E8BC4CF1B -:10AE3000500DCF2D9D7C7DBEC654675501FAB5BE21 -:10AE400094B222EC678905BFAF27DB0B2FDB4F6E77 -:10AE500019972BE17E1E49A94AA47E86623FB2DD86 -:10AE6000E3C47E8CDA775BA3F15CA4BDFFF7C6DD9B -:10AE70000083940F447821C2847474892E6D183F26 -:10AE80004BECEF3D2E173335FF05E4624519CC6BD3 -:10AE90004DDE07AFF23DC6FD96846B79BED1592DCC -:10AEA000DF3C3A4F23DA8E11FA47E823E847C67EA3 -:10AEB0001E453B6644781F0DE6128BA5D5F9F87E3A -:10AEC00049F211BF805DA3E27E91B57CC1E8F56CCB -:10AED000D6F027394A54D41755177AD2F0BDC3F6A5 -:10AEE0005369DC8ED59F471FFBEB5356ACFFB2AEC8 -:10AEF000F2B2F68A387F1EE8DCD9F12F9FAC8FB40E -:10AF000057063A87FEB6F3E7230E13C5F97649FADA -:10AF1000FBF5CD9A1CDA5026E232FEDB901EBB24F4 -:10AF20009F9B5F98E6F199A272FF9DF87C48BB89D0 -:10AF30000580AE87FF5AECF247F473A57816F1FA54 -:10AF4000C19A3D35D8F69484FB74705D50C2787B0D -:10AF50005A5D87E4BD4CBBD9655C8F8BF646ADFF6F -:10AF600072A557467D55EEE47A31EDBCC27223E4FA -:10AF7000CE8C32BE7F8D9AFDEE38F2B415FB3B626B -:10AF8000F0B5E7A07E7018D42723F6BB71A5C75291 -:10AF900019B1BE163C47EA878ECF94F5D95DA4BFA0 -:10AFA00085BE350A3D91A4E8F4C4BA58CEC7C2DEC6 -:10AFB0005957CAFDA175B1DC2F7FD1E57F02F7F3A8 -:10AFC000E7A59FCC1AAEE23DDB0E139EBB7FDB797B -:10AFD0004A9F7D63082E16FE0CF2BF5B71FEA2072E -:10AFE000DECFFF6105D97B45F8E512198F70B9FDF9 -:10AFF00007F6D473385E014E3D82DE2CEABB860331 -:10B00000AD67277E4BAD08E37FDD14C7BDEF82D46B -:10B01000EF7D8A2FCB84BDD0776E78D938AC8A711A -:10B02000D84C3C07D3C7490BBAF47051B71E1E7FEA -:10B030003C3AEEEAFD6D64DC7527EC33941322CEC6 -:10B040009A1E0856E03DF30CD641E7906975093A1F -:10B05000BC4E96B5FC0CFCBC7244FC374DA93E8D31 -:10B06000EF9FEE5B5780E9EE07542DBD133FC519E6 -:10B070008EE3AA84AF15D7CE9D8A748D8EE766D4F1 -:10B080002BBAFB84D171DCE53BF5F70D7DDE7CF25C -:10B0900007E67D471FFF1579EDB8DE34CFA5E37FC6 -:10B0A000FBB8F03FE1D2F145BF8F82FC21F9AA7DC8 -:10B0B000C73803ABB01F2524E179F8E07A46DF33C7 -:10B0C0004EBB9D79FB3B57489BC4F1158D671628F5 -:10B0D00027FC4DD19E0DB6F1BCD7C1B71BC81E1CB5 -:10B0E0000C7281FEDEC16AC612014E5BAD923D3923 -:10B0F000BBCEC0503FB00B4DBAF761BA144F1574B8 -:10B100007FD4C6F37A33D6B0A001D7533F8AF61363 -:10B11000CD6B982EEEAEFB2EC1EC12FD7DDF8CA820 -:10B120007BBE820FD2A29E1F2A73EAF605E8B9B44D -:10B1300049C4275CFF65A3FE83297D3AE1F8539853 -:10B1400087377923E3DFC3898FD1BE87D3775E2129 -:10B150005F047E3D6299928BF6CA56678C01F32399 -:10B160000EC7F73CC6E2191B338905F0FB9D2FC7BC -:10B17000F48E96009EF0D29E5DED4094C3D6DE1F05 -:10B180006130D9B6EDE99BA747C08EFB5F22989549 -:10B190003015BF2F84B9ABB8EF629C33F6E1F77C72 -:10B1A00063F26C149C8C61FAEFF8B496AADB30BFA2 -:10B1B000A435DBA0DDB38EA887753C35C929F2E242 -:10B1C000284F8F4DE7F90291FD639EF780FDCF80F8 -:10B1D000FE0BAFA27F0B9F7F0A3E023D9382F3C717 -:10B1E0003838F68FF4C5A051E4F85A7F0A0BECC644 -:10B1F000F31D18CF26F1F19C98BF92C2F4F90A7D95 -:10B20000E33961BC31FF17D633FF527A182F478FCD -:10B210000557478F568397E61B186B233F08BF8758 -:10B2200085DFBDB36AE359B5EF7F215E5B8BC378E1 -:10B23000053B90FA85E6CD17353C633E628AD344E0 -:10B24000781E086F479C3C7F6A8B3326D89CF9FF99 -:10B25000805E2E4EAFC8F1D09EBCE2F116C0784998 -:10B26000573E1EE217F74F1F7E81261B53AE1CBFB1 -:10B2700030ABC095E0F708F46B88C06B384FE9112C -:10B2800027FA0556A3CF82799BCF4FE2F98F7949F0 -:10B29000732D94B7903C97F290DBF26C9457DF9645 -:10B2A000F51D8B31424FB7E5D5523DB4A7FCAABC82 -:10B2B000500C8629D818D64D71802D65552EF40B6B -:10B2C00003F53C5F4BE42F097DC8B4F3515A17BC1A -:10B2D0001837E940EF1168BFA5BE90F2D3E2E2FF54 -:10B2E0008BF2B2B6D6B9DD58FF189E63813DF1B03E -:10B2F000768E858C4AF1B4B1A54FE0B9AF27BB413A -:10B30000C2E3A6F4D57AFD34382AEFC7F345772592 -:10B31000E677B1C53C7FCB55AB44E943FDBEDD8A42 -:10B3200078E579564189E357D7DFE949C9A4E7B6FB -:10B3300064ED6115D0EFF3D097ACDF5F06CC778A70 -:10B34000DE8F8AC94BDF29630D069A471AA6108043 -:10B350008AF38C99E95A0CCFD39729F4FDDA417915 -:10B360001B28EF09AC7CB237F2F2DEA844F89275E4 -:10B370002ED5AF237A5DD1F316DF5716F4F27CE1B8 -:10B380008E45FFCA933D97F2D2E847EC77396A3D84 -:10B39000600F5B930CF45DB998AC8875315D3BCD63 -:10B3A0007FFB9F857F3F8971FB39FA5CEC7FF1FB66 -:10B3B0004766E6B698E83D715F879FB70DC6BD83C7 -:10B3C000741FC2787E78F4FBC5FC7DE6E2E76FE689 -:10B3D0001866C1FB3AD2AA188A639ACD00E37D1E93 -:10B3E000ED7B658F6AF1B6668929A99EC8F1429402 -:10B3F0005F2F5BAECB42BFE188659E93EEC9697E4D -:10B400009431DE47F98D2C3741E78F1ED1EEBB35E5 -:10B41000ACCC1C84F1BB38A8EB46BF5A715B90DE04 -:10B42000226EE218DE7313EAF16193872FB2002EC9 -:10B430000EA3135CCAD8B8C3193FC0EF148BFD69C3 -:10B440003ECFBFF7D1072BF5943F623E3F44F73C18 -:10B45000A4F96102F626295538DE34F40F92F1DEA4 -:10B46000B8B315DFAB00E4E8BE2FA07D3FE4D2FE09 -:10B47000D375CF43E05F479E0B0CDC7FACEE3B0502 -:10B4800066F077FAEF3F27AA7F67BFFD87FB4DD4B1 -:10B49000F5DBA670B911488A09F617DF5B36B9F2F9 -:10B4A000BAC94503E7B72D9DACC5E12C20FAF11CC4 -:10B4B0004AE39FCDAE7ACA779363F8B9A911C4085D -:10B4C000F2D3517B1DC92D96AECF7713DF2769C309 -:10B4D000EF8E407DA54D6FAF57B0DEA3E324F4534C -:10B4E000F5F6FA645439783EC5A2EDF87A3A273574 -:10B4F000A6EBE5C2456DBF18EC85DD941F976CA3E4 -:10B50000BC8681E20BEF3531CADB32C6FAEA51E77D -:10B51000FDEBE1F143DB4A008EE37CB6F5F0CC4570 -:10B5200018377A4FE3E736900374CFB561D06E39A0 -:10B53000A2DF5A53281BF54AAD81DF17A01F18FF61 -:10B54000BDE4C114678D1E577C7F46C00BEBA54937 -:10B550005911EB7B4FDB1F7DE3DD96B61BEDDABEA9 -:10B56000F1CCA1221AAF2FFF481B2FE5EF1BEF8F65 -:10B57000DAFE16E32DBC53BFBE85A66E5ADF42ED40 -:10B58000FBA762BC3FE2FA32FF8EF1B4BCB1BEF160 -:10B59000EED2AF6FA1B99BD6B7B0CFBFD4C64BF92F -:10B5A000FBC613F90E66737D1DF2D340790F22DFBF -:10B5B00021C795A8CB77C09B2715598C3D2071BE1C -:10B5C000787D72CD0F30CE7F6E66839BEC14CDDF1D -:10B5D000A37B4432DD23223D3A3B9DDB21A2FF7D4C -:10B5E0004D25CC3B82C783B0CC2D93E89EC2C812B8 -:10B5F000C98BE76C3B417EE077F476C13EC7FA60C9 -:10B60000938BCA3D4D2A957BC1BFF452FCCB4DF0C4 -:10B6100085C9DC5F7C20D559B314ED8F8A189EA7AD -:10B620005D36112CDBB0FF06FBE58815F3216F605A -:10B63000F9F8772D7376707C2655A5D0F7F663F26E -:10B640008F753701BCB9445631FF7CB3DA7F3CE7D4 -:10B650002F5ABECF662DBF3280F72E49A9803F59A1 -:10B660004C7F3F8BFFC833E95ECEECBBE2C9BEA97D -:10B67000FD4E8FDD09F3B859CAFF6D16E0E34F9A0E -:10B680007DB368C80C9207D1FE69126AAA42CC3B0E -:10B69000948341F8759E7D1EF9B7F3AE672C01DEE9 -:10B6A0009F8DEF819EFAB5661FBDD96366E8FF05E1 -:10B6B000AAF8F9F5CD1BF47EE903D69013EDC20785 -:10B6C000F29318D2A3F6767DFD6613DF6FF3A2FC2A -:10B6D000D4D951793FE23B8A9BF1D7098C7D395906 -:10B6E000FB8E9196F7B35F8B33B1F4044A0617F7DC -:10B6F0003DCD66D6EFB9A4E82F11041DBD97E42512 -:10B700003C88BC77263F9B8FEF8BF1C47B8F4ACF61 -:10B71000A65E2E6E0A76E0C99E5CAEEFD15EB7964D -:10B72000EBE7796EE6B0EF56B1FEF8B657C1388553 -:10B7300098FF3F8B5F8FE27A414EFF7ACA9785FC74 -:10B740003E5E3A8BBC8727F2BFE6F5C10A7D9FF8C3 -:10B750007A01BA7AF390DEBF9914EBBE97F84FB333 -:10B760004742EF1A2EC65E7D7F7DF370793374F702 -:10B7700060B5FE06C2F340DFADA09FE2709CB7A5A6 -:10B78000D9EDA27B77C9FC9C6D7052E569BCE78559 -:10B79000F51FE8F84B7F9FABA5F36909FD96C7F04D -:10B7A0001E9C31224E54D721B5D9B0DF208F2B8576 -:10B7B0009EA6F86F7A5D486ACD0BDF1B8A968BE9EF -:10B7C000ABF5F7D2A2BFC7586DEB512415E3FDBD11 -:10B7D00074DFB1AD5C3B9F411C63BB646E4FCA69B3 -:10B7E000069E2F3254E5F66556EF90C8F38E55E568 -:10B7F000DC6EA88E7DFB761544AFBFBC6311E645B9 -:10B8000055C7BD7D7B26C0B7943FB708BFB3589DD1 -:10B81000F6F69799206F9795EFE7F0E8B7BF1C060B -:10B82000F08AF2E7398CF91E80A495E50716A1BCD1 -:10B830005D552EBEBFD84DF7BFE554CE477F776923 -:10B8400036F4BB2F6F2B17714B46F7BD7D877E7982 -:10B850001CE5944FC479BDFAF34DA67D7FF13AC142 -:10B860005E490EB29766E0EF80CFEBB4EFF6182C8E -:10B8700021C2EB88F07751BE7735DFED09DFB7E7FE -:10B88000DF9D6A69647EFDF715BD1AFFF3BC2131A7 -:10B890001F31FE25F3C2EF0B2644CE6B27F523E6BE -:10B8A000F579BE39208D0B9FD78A797D2EF5EEC2B2 -:10B8B000A047CF94DEC548D7CFEDBD43F0EFAB94A2 -:10B8C0008786FA094EEEDD25B9236023A7E323E539 -:10B8D000FF87ECA951A9DE47CA317FCFC4BF83D00F -:10B8E000AED9915B93FD01F4EB81DF286F3390C1FA -:10B8F000EF3B5415EAFF0EDC131A7F1579F9F9F4C2 -:10B9000054F3F6FAB70AF1BBEC126B86F6EB2E9CF9 -:10B9100033A1DF5F7DE88409FDFBB5074E98D07F3A -:10B920005F8B30F4B376A7A9DFBF4357EA95C5FE16 -:10B93000D5F92BAF64E4B425C17CD62EE5DF016BCD -:10B94000F859FC54841B16E32AF1EFF93D37155FD3 -:10B950005BE8EB6CC37211EB7905CF256AFC7A3F8B -:10B96000E2A63ABDDDBFB05E6FAF2FDA0ED401BDE7 -:10B97000B6A8312DEA7B80FC3B83351A3D6B5CDB3E -:10B98000BAF13B06352CEA3B83011E47BA89AF006A -:10B990004A7D7CA41AFF9E15AE63B54C71DE57320A -:10B9A0003629784F6E5DBD44F97B530F7E61A27AD4 -:10B9B0006887E74A2983F9F7F484FC14FAFDA6970F -:10B9C000761B315E10FDBDC145F3A7D377C5E7AB4C -:10B9D000ABB87E1FFABBA909F03CFA3B82B507B9A8 -:10B9E0007EAF6D9482F8DDDE9BEAF4FEC042D6DDC8 -:10B9F00086FECCC27AFDF3458D7AF823A1D746B3F3 -:10BA0000D1B83F4E974B0AED170D3E93F1BB37432C -:10BA100030BE3BD5C7BCC027AB4DA1B1A8E7DCA960 -:10BA20007E82453D3C5F8BF27FA07DF8FF4BF9DFC6 -:10BA30005818855400800000000000001F8B08008B -:10BA400000000000000BED5A7D70545596BFB7FB07 -:10BA500075A7BBF341E73B31045EBE58244D68D265 -:10BA60000441778AD7DD494FF8723A40866008343E -:10BA7000B350152549478953B1CADD341063072DEA -:10BA80004B59B4C0F28F06C5D51ADD0D92C1CED286 -:10BA9000301D302C3A387676D08171B582CB3A524F -:10BAA0008E9088A3B8CB167BCEBDEFD1FD3A2F8AFE -:10BAB000B353FEE16E527073DFFD3EF77CFCCE396E -:10BAC0009710E1A3B1D984E8082537F484EC344811 -:10BAD00056E7024202EDD47E5024A419DB4D84FDCA -:10BAE000DC28C1FF797F56D74FAE3B244A480DCCA6 -:10BAF00063F676119CE718B51E844FB5822464D98D -:10BB0000E03B254D0369D0177F96C4CB05928E90FC -:10BB10005C427E43C66CA48C90592930610E94AB74 -:10BB2000A78502B0EEAC5F6D0A50986F9683DA7508 -:10BB3000B0AFE5B0E3EE6A2C05B21ECABB0542CC3D -:10BB400050CED20F34E1BA649ED17A90EDB7809096 -:10BB500085842CC33F619CF432A11FC37970EBB87C -:10BB6000EEF2E9A7BFA619307EEFE3137A28CBCB1C -:10BB7000A4EAA7607F8F99F9FA8F0DD1D07698A7A4 -:10BB8000C376EA1CF6CB97085BB7A3202D8AFD4944 -:10BB9000D8F0C79BE72F8576D14AD6674165858D5A -:10BBA000AD5B28D30E56261F433F1A75E96E5442EB -:10BBB0003F79DD1F794476EEBCFB06289EBB9804D6 -:10BBC000B65358AF0CD6413A2A2521A6C04518DFF6 -:10BBD00008F7340DFAE90B7DCF2F8171ED0563462F -:10BBE000528AEDE346EF5CCD7EAF2EA9D1E8270166 -:10BBF00001617F0F58395DEAF4D73380F2E4816345 -:10BC000065F9C436F97E94526FD21151E107F86795 -:10BC1000B05A88383B5E5F3E3B5B555F692F52F5FB -:10BC2000FFC9A232557B8354A96A5F5DEF50D51BD3 -:10BC3000BD77A9FAAF6D72ABEA2905CB54FDCDE211 -:10BC40002A553D75F63DAAFEE9F69FA9DA49CE4090 -:10BC500081379D10A32930E6033A04815717C1FDAF -:10BC6000A518D382741A219519D0194A8BC39C86C2 -:10BC700065707E4A14EF2D785B4615D653DE7CB096 -:10BC8000208A549FF68AC909E52F68C8950D73006C -:10BC9000997C0340C7390F13299440CF636E1DBBB5 -:10BCA0004FA5DC26F9FECE09A5ED25B1086E047E70 -:10BCB0006273F07E4C16F813F9F88829847C3C0FE7 -:10BCC000E6248BE3F32CF138BB251CF7B0B414F950 -:10BCD000948489B502FA1D30C2CD423D70C4C8C6F5 -:10BCE000D9C2633A2941DE042797CFA7BDAEA53854 -:10BCF0007F47845A09F2F7DE8F8CA20DEBC319122D -:10BD00009455DE8F8C242DF1FB05237EEF10C62D7C -:10BD10005628FF69405F1FD2E09341C9C8F8F95423 -:10BD2000B191C94FCB83FA500A65FCBFC209FCD65A -:10BD300024CB61CBA1F1A81ED66F013D13804F4DDE -:10BD4000E27D2B08CA93CFC0F48D097E519E9E2EB2 -:10BD5000CC3840E671F92179846C94A5E99E45516F -:10BD600003D2ABB9D510D74FF06FE31ACF255A05E0 -:10BD7000F376267D9FDEC7E47B63A2BE427A49E963 -:10BD8000391F833C924A62BB01F272CEABD33CD7DF -:10BD900009B7C0CE75CEE766F47E1AE8A6A748C7F5 -:10BDA000643A71FA7D1B7D5EC5BB4EB8A7E47EFF89 -:10BDB000E2A6BCDF14FAD2E2E4ED0768AC1A95996A -:10BDC000DF6B617CDA6CDAB4F5A203E9FF651F452D -:10BDD000FAFF92921498FFFDE137F344E4F3432312 -:10BDE0007963309F7F60248F009FB519C4ED420EA8 -:10BDF000E303FB76B8978E7094EDBF7DC0318CDF86 -:10BE0000DBC3D48EAAD03F38E161E724637DD6340A -:10BE10005C577B5F31598FBF2F898CCFFC3E5833E5 -:10BE200007C7A7844214EF1DF410EE6B889227A178 -:10BE30007EA0DFD414D298E70CD21BC6BFD16F24EA -:10BE400002F0491B8CC7739C2A3E653421DF1C829B -:10BE500073513CC768632ACEDF6520228DEFEFB3B4 -:10BE6000E2D88778FEF39B0D2400DF776ED6337A15 -:10BE70009FEFD2B379F45BFEA3AF08EAEB80FF52E9 -:10BE800060AB27375F3D5504F39E6F853A9CD7BD65 -:10BE9000C5C0E46FDDFD94F54FE65F855F9F95F9C2 -:10BEA000739D4FCD6FC9FC3A894F5BBF1B9F7E15B9 -:10BEB000E7D32AB4B370EF75F9C83F0F11FB419473 -:10BEC0009FEB270DF9B0DFD23EAB7D07D4E7EA4305 -:10BED0008FE4A15E38C9DBE7B7EDA75CBF88F7E068 -:10BEE000B98A8246B28B221FF1FBB23845568A646A -:10BEF0009CA6A2BC0AB152D443B0B484F7FC9A8188 -:10BF0000341DB2E177AE5FE6BE5EB07F5702DF0E52 -:10BF1000499C1F15BD576924BE4369D87FE0B6060A -:10BF200098E755188FDF67C8F355948D7B1AA09C4E -:10BF3000E3E47A3047DE87527F4FE67FD22A50A46F -:10BF4000E34A13A7FBB2EEE87A3C47E974DF6DA839 -:10BF50003757CC78AF0DED5AB0F42D9B0FF747EC67 -:10BF60003AECEF97E97E72F11F9EDB06E735DF6E54 -:10BF700061F7DA70625F0CEFB9A35C2078EFE68AB4 -:10BF800005F93E0DFE534AFFB512E2CB8ED73B2298 -:10BF9000131E4943AE47DD5CAFCE35F2F393081074 -:10BFA000A990E963615175BC9F727E4276B0FEE64E -:10BFB0008A17D83D6DBB9FCC67708A3CC5CEDDDC4F -:10BFC000364A37C13C6B0D92210DE8FCDEB4A6ADBC -:10BFD000172B0879AB0754241CE44C8F89F8FE0A10 -:10BFE000F0528F95D5633D05ACFEAF3D222B7367B4 -:10BFF000787F84F4697CA3B302E975B2F819AF0BBA -:10C00000D6B972C6C0E840888BD1699BCC7B5723D8 -:10C010007A6282F6AB833444687CFF1BAE15111F35 -:10C02000E893DFE37A30B0BDFBB74CCFD95B273C58 -:10C03000621AF2D5853EACFBBBFFE441DCF021D8AF -:10C0400009E42F7F9892029867FDB56C36BE3D3C9F -:10C050006A14910F74E31EA47FE03825C897FECEC2 -:10C0600009A63F9F837349B0EFBF756672BD1199F2 -:10C07000AFE3F7B980E314F9FE87E7FC6706EA2F20 -:10C0800053B7F8CE5D788FA7F5EC1E77B9C633AC01 -:10C090001AF7720EE625297CFF5826B737190315C3 -:10C0A0007618D724F36D72FB43323F02850D881357 -:10C0B000F08702DDD6CBFCD50247990678617D98E2 -:10C0C000462D20B72D11F72501CB4E4A3E52E903EC -:10C0D000423E4AC0C953F1DBAD961D385F45BCBE38 -:10C0E000CE079326E09CE6D65434A209EB07185FEE -:10C0F000A51497E7FBBE01DFF9C700AFC17D75004E -:10C10000101281EFDBAF55B2F2F2D0A322CA89C977 -:10C1100032FE0CDA05324BC7707D7B408D6F36CB1B -:10C1200072BBD9CDE5F929271510F782DEAAC473B1 -:10C13000DB0B7D7B902FFF58FC5EC609F8DC668C1C -:10C140005611EDEF1D88874D284FB06E25DCCF6B63 -:10C150001AFBBED7EDDAE7CC45B97A92F13701FE8A -:10C1600046BE4A3EE70B32EE51E479DD894B46C4C8 -:10C17000BBFEB0B63C77B99D2FE07EFA09A9D7B2D5 -:10C1800073F7C9F2DEBE97327AF9F766333A7D4625 -:10C19000F67A5DC0979FC13E0E005F5EF17A533321 -:10C1A00061FC159F37352B2D2EFF1D7B53D9B8FE13 -:10C1B000F255D99BA03E847C0FE7B81C769B90CEAD -:10C1C0001BF672B953D6FB30BA2E1BE5A7C6306EEC -:10C1D000B443FBF4C8850CC4753543ABB351FEA61C -:10C1E000DAE7CB2E7E1FEDDDDBB65ECCE6FCA007EA -:10C1F00079DA2ADB31FF8EA811E9BFB59B30FE1D2D -:10C200003EF27E07CAEFE548AA15EDDE67C7520386 -:10C21000A8EFAF1C4F09E960AA36E477D0679F19F1 -:10C22000C6EE66F871486F45FFCC7FFCD367501EA1 -:10C23000FD47401A61DEAD914727D0BEB545965EF9 -:10C2400012B07CE5FB9587F6EE9FB3F32AF54F7BA2 -:10C250004C22EACFCB02D7135BC387199EDD7AFD50 -:10C260006A95D786E7FCAF85A8CFFCBFBABA10F5B0 -:10C2700098FFE8D585D8EE7F3DB5530B9FBCEFD630 -:10C2800033BA2AF6B1E4AC2025F6EB95F9A3A4F76E -:10C29000C9FA52A05FCDE81ABB5E8CB7D754E8BC90 -:10C2A000D8BFE6DDDAEC2D89E362423D7E5F305A8D -:10C2B0009BBA39812F1F721B643D04520DFA679D92 -:10C2C0004CC375058FC7F455581702328EA0371826 -:10C2D000DE26A2B010FD7782CE3DE98F090CCF0497 -:10C2E0005AF5A10A686F8EE9247315F3EF038938B4 -:10C2F0008310EFF2B978DFF7E6DA7789CCDE931EA8 -:10C30000AC3F5411427B4F02A691F2041CB42EA6FE -:10C310008BA600DF344552A28887D6C5840BAC2E8D -:10C32000E3A30FADAF3D826E27E0A38B893807F002 -:10C33000D045355E22E9B85F052FBD87B80AF06C9D -:10C340004B57D480F60A7092AAFFC6A61F5F423FE1 -:10C350006C63B7FA7B494CD0AD84739680BA433294 -:10C36000F4C7F698503E149C89F735A821EFFB5D81 -:10C37000FCBE1439EA8DE9D83DF4C65CA672289F4C -:10C3800095E568D0AA230198BF37B2FA20FAE9BD33 -:10C39000D7D7A622BD7ACFAE223B50DEAD2E5305B5 -:10C3A0008EBBFE6353A32DCE1F93F4878BEBC73850 -:10C3B0001ED0B673CDF2BEBE2F7BB7D6F5C3B07715 -:10C3C000E0576F70E532BFBA99C73DB85F9D6C27E3 -:10C3D00014FDABCCFB847CCF93F5EF25865FC0FFCB -:10C3E00065FAF70997C8FA4D8F346433BFF8EC9AB1 -:10C3F0006C316DF2FC65825D97659B3CBF82D7FC1A -:10C400000169C4847E8CA467F2E95F434314EB5E48 -:10C41000CA70B67FBD2184EDCA7E626B28EBD768F7 -:10C42000A721338DE33F051FDE6C5F00ED2571BC56 -:10C43000A8E0C29897323F688D6460EDB9337C8F75 -:10C44000B86AF07C66F6BD66319F17F4C008FA47FB -:10C450006B7F4A09D303325E54F833194F7E1E298D -:10C460009BF64D71A3E764BE54E46B46925C28765C -:10C470006A48B6D31D68A71D68A7BF36A21C4C85A5 -:10C48000BBC14EEF73B171848D5FF0AEE0D5F2BBEE -:10C490006DB21CBDACDC5BEC0D27EEB798C4B6A347 -:10C4A000BF3895FDEC9771CC54ED43323EFC3639E4 -:10C4B0003E2B9FEFFB92E3D80F448E6FE23FA3F633 -:10C4C00039EF753BCF23FF5AF49D3127CADDAF0DFD -:10C4D0002C6E9DDCEF09D91E833D53DDCF48B15151 -:10C4E000877E8FBF95C7018299E23BCC3F79534F3E -:10C4F000709EADD70A194EBBEF5A262B838584DB7D -:10C50000D1074B58DCE6BE97460D128C6FEEA2F3B6 -:10C51000311ED4DCAA3E4F30575A9A18070F160E18 -:10C520009C42B90A1C2C1371FE163C2CC6435A338C -:10C53000433B317E81719C79F8DD12A703ACD32E89 -:10C540007FBF4B8EEF90241C7074F83C8BF7F8077C -:10C550002941F93546407FA03E39CDE31D1D11AE7E -:10C56000173EE936337DF289C0CFE1EFA6A1ED3465 -:10C570008E232E459ECA43399B842724C01379718C -:10C580003CD1FEC2BB4C1F26E387AC41BE8EBF4DE3 -:10C590001FC278CC48F1428AF576F007F311278A5A -:10C5A000E24F8AF8BE4888E91549152739701BB74C -:10C5B000FB9F9FFE77E647360F5192CD7087142B75 -:10C5C000CF8BE38E8DC165CCFE2B3863E3CC532338 -:10C5D00045389F8C33ACF08BF1C3649CD1111E3570 -:10C5E000A05F30094F24E1880AB73A2E3853E07132 -:10C5F000D699116AC578D24C999E77F45B182EF6BD -:10C600007CB0391BE55CB99FCB0DFCBE2E9FFFC2F1 -:10C6100089E3167E205851DF1E3DDFF5DB225E17D1 -:10C620004D228EEB4A453FE4F2070FA4223D8F4294 -:10C6300049405E5F3F2768C60FFF3E1E37BED38D61 -:10C64000F6ED61396E2C807D4B8FC75F92C7BD269A -:10C650008F0B829BC1E28E4384F16FB0D0B78CD533 -:10C66000F79592832CEEC3F9F57024D38A78AF1234 -:10C670000EDB0D7AE21F2DA417F32BC15CDF5B4CA0 -:10C680003EF6E918FFC2789697091C1299BD4392AD -:10C6900061FEA3CA087BA9267C3190B739F2BD158B -:10C6A000821F8AF917D8CD9A1B40A74A390F5265C5 -:10C6B0002102CEFF98C1B7EB76CCBB0C0BF6ED3860 -:10C6C00046B06737A44FCEC70077B37D2979198A62 -:10C6D00079976FC8CB505CA78AF31BCBC31089DE58 -:10C6E000488DE75FC84FBD2C29B473512741BF73F4 -:10C6F000B187F0EF93F3298F3B35F229FBD0FE3061 -:10C700007DABCEA7ED9AFD1AE3B7EF9A473BEB520C -:10C71000E64B5E5FE47E67D2FA0B323FCF63FECB1F -:10C720007F7F95C1EC59E42AB33B57C653488CC56B -:10C73000EDC6789C3A6260FEFA15F0837213ECD96C -:10C74000974E4E87131137E3C7C1586D2AF62F96BF -:10C75000ED65FFD935AB57229FC4047B05DB25F778 -:10C760006B0663420DC70793E874D0A5919F3259B9 -:10C77000B83E4FE6CF46993F1BDD9CEEEEF3DC5F03 -:10C78000F177F1FC815596377F27657AE554711E64 -:10C7900055E2C8F95AF985A171A6675BEEA5F68046 -:10C7A00038757E61B7EC6724EBA18EF0217E6FC9EE -:10C7B00071DB7A0FD33BB71AB725E80D2F8CEBE965 -:10C7C0000145AFCCE571DC3BDC5676DEACCEF9CE74 -:10C7D0007C123FBF063DC55AAD3CDEE47EF3EA6EF7 -:10C7E0002D2FD829DD5ABF17A55B5B77F016FB9D6F -:10C7F000BDC57E73B4E44CA35F8EF3D6CEF18966DB -:10C80000BFFFA379D0E43C67725E3439DF99F2E66A -:10C810009600B63D4A1F1F8F2275338E3451105932 -:10C8200021F30513CAC98AC53C2FD05F6B0AEDA757 -:10C83000F1FCA842AF020FC75F56DB44201BE83C67 -:10C84000438AD566833C5F594C98FF70C5CCF3038F -:10C8500044B01636B0FBB316AE02BD1F346BE79979 -:10C860007E5D27E3E929F4C9128F733ACA8B1571EB -:10C87000B9C63D1E96E394D63061711B228885AB04 -:10C88000D8BA6221DA9B696FF0EF195122ED67FB8C -:10C89000124B56311C2D96E0FE76CBF9AFAC65B34A -:10C8A0004A305E97057617F3234F619E84F901564F -:10C8B000D64F59EFF95ABEDE6E03A198CF0ADCCEEF -:10C8C000DF57907FB3AAF21B670CD18B9B28CB6FED -:10C8D000DC81FB7F5B17B51D28E1F782F4B50D5AAB -:10C8E00059DEE5378BFF61B68FADC3F31DDBACBC02 -:10C8F000CB49F437601FDB8E3918FF369F58FCBBDD -:10C90000F5880BCB0546E749785CF6B3CEC97EA225 -:10C91000E2678DA1BF98E0772CAFD54DA59796D74C -:10C920006AC8D56ECAFDE0C0DBDC0F7618ED659DE8 -:10C9300009F7B4B696F3C3A6288FC72AFE6D9514DF -:10C94000D2E5011D1C0FE9A32960AF1D7D738DA8E1 -:10C95000B71D7DC516165FDA7C48A7D05BEBDE37C6 -:10C96000D5723BD27F7A9CE5270E27E5299FAF350C -:10C97000B2F62C991F9FAF251C4F55083BD10C4F89 -:10C98000FB6BAB5E2B3EDE02F81FF7B729C8F7AB97 -:10C99000E4435AA2A21BD7B93032DE8765756B8992 -:10C9A0009BC50FDB26FAD07EFAAF5F3DB584C50389 -:10C9B0008C22E2ABE479E778F46CFDC30848905E22 -:10C9C0004B8510F6732C15D87D67B598993F9E65F9 -:10C9D00020FA34AC37707B565D9FE3C63A5993C951 -:10C9E000EC71F56931738B2DEEEF672DEDCA453A89 -:10C9F0007D5B9E48891BE4CE907620BF7DD73C515D -:10CA0000FB99B3463CF78631759E48C9FB4C952788 -:10CA100052F2B4FEFA2F547965BF30EEC1F88AE3C2 -:10CA2000D8059627F687A9B5A0249E3FF20F4E1889 -:10CA3000197DE5BC11F437E2B8C11E9E3F3A02EB06 -:10CA4000631986F34AB08F7F86F3621981F3E2F7A8 -:10CA5000E33DB35919EDB1B3F244CF22563A806D9C -:10CA60000AB330EF34C1F24E2FD5AAF3164A5EC294 -:10CA70005EE8FD05D229216FC1EAC9790BBD85FBAE -:10CA8000A3FED306FB01F8EE3F63627AD619D934D0 -:10CA90001371D997A3BE99569607C8667EA5C20F93 -:10CAA0009725BB3913FD01AFDD8CF902C7F025A333 -:10CAB000C8F44EB4089F3275083123FAFD4807893F -:10CAC000E139A719E9FAADF1FDF0FFC7F7BF4B7CDB -:10CAD0007F5E5C2E99FEA8F6EAA4FD589E96CC5B7C -:10CAE00012F443BF97C789FBCB4B99FCEDF19666D7 -:10CAF0006E4E8CE7D7733F2E6B69B939F17B97C7C0 -:10CB0000C0711F255E2D3DF6F5D4FAF66B2D7D4BD9 -:10CB1000A6C80BF4D7733DA2C4FD27E709EC6F96B6 -:10CB200027C4FB2FBF0D7C0A7EEBF0500AB3E75FF2 -:10CB30001E4B3980F8BBBA7EF3CC74A8579F4B21AB -:10CB400025DC1EA9F20BCDF53AC99CA1954F908A20 -:10CB500074C0B793F206F53AA6DF6FE60DEA850BCF -:10CB6000AC2EE3F40D137F482FA148FF5010FD8C2D -:10CB7000C3EDD43E4C26E71160E222B2084E517F4D -:10CB800096E595ED9DD42E8ADF9E5FC893E30C1D3C -:10CB9000E14C3DF279CB1B84E0BBADC979867A8646 -:10CBA000F7ABC993C15A7C8F55AEB3A23D4B8E17DC -:10CBB000209FA0FD4F8E13CEABE3F7384FC62B61FD -:10CBC00019DF57CBB84419977CFFBD75EA7C4472D6 -:10CBD0007B97DCDE5B5FDD8FF71758A12368077A50 -:10CBE000EB5DA6F284F95C75FC1DCD6ECC5BE42494 -:10CBF000E62D787E22395FA1E829C7F0D71EBCFF59 -:10CC00003D111E4FF217F0F8A6E3B8F334CA7D7C4D -:10CC10009FDCDEEE813B8E311C65CF24FC5CC4C4FE -:10CC2000E35E2CCE50BDE28B13A9483F2FD82BD406 -:10CC30004B67CA77A6A13E5921D45091C5BB6FC698 -:10CC4000BF313EB5FA9DD66504ED7FE3FC51A47B70 -:10CC5000E37A037B87A4D8ABD5EF347978FBFE1D4C -:10CC6000166C9F4DED6611BFD7BBF0FBF257A218B3 -:10CC7000E9232B91DA2037B13317059497DC19BEDD -:10CC80009FA17FE46890E3E0EBB97D6D8C34184898 -:10CC9000DA647B77B2F84BE6475F8D38587C3B1BF4 -:10CCA000F3AFB6B8BD701C033B94FE97B343BD759C -:10CCB0005646CF796087703F590D3C4F987CFF2EC8 -:10CCC000F9FEA7B22B53E951B423BA455C6E684113 -:10CCD000DCFE8AE85FDF11B7C3D630D4F3BF21EEA4 -:10CCE0002DE3ACCC2970D82F657E9FF2FD46F8FB72 -:10CCF00089831FAAFB81C4C1653F4789872B7E5169 -:10CD00009A8C639532DDC3E9FEBF7EBF8CC651F3BA -:10CD1000FD7296F6FBE50D03147186F27E79C44828 -:10CD20009C8772F0DD1E25DB51BE430D0CE78C3C69 -:10CD3000FBFBBE97E17BC720B5A2F9691F1865769A -:10CD4000BA1D700DC343914F799C6A80BF376D0F38 -:10CD500053492B0EBA40B6CFB512617AA35D7ED788 -:10CD6000E719E4721D8F13FD5C488C13F9C558AEAA -:10CD7000F25E30C4ED93E6BBBE0E32CEDE0376B477 -:10CD8000527B14BE27C78D92E3454FCAEF00A78C94 -:10CD90001B49DFEDBDDF9FEAD2733E061650E2CF9E -:10CDA00005B53C4ED4E4A314E737E9BC6DECDDEFE8 -:10CDB000716AD57A3F9AEAE17667B91CBF7DD1C81E -:10CDC000F9E1C53B297B4FBF9CF038ED8BC7F9BB20 -:10CDD000FA17ABF9BB7A255EABBC97BF3D1EAFDD42 -:10CDE00083F15AE59DBDF26E9E9010BB8786BD967D -:10CDF00028E28DC70C0305288FCA7BA3A375DCDE50 -:10CE0000595248A7967C7E55E73C5AC7FAE9A6884E -:10CE100077FAF23D1A71209FECB7157BA6C4E9A200 -:10CE2000275785D3593D19A7FFA5E2B547EAC8544E -:10CE3000FBBF5F1BAF4DEA77F116FB9DABD3A0C7DD -:10CE40004E397E924CDF1E8FA287A75B193FDDDC37 -:10CE50003FE1F95C39EE3522DBB920157F7717CB3E -:10CE60007F1958FE4BD133C1743EFFDDB29E51CACB -:10CE70007BE53268D08ED374C9ED730AA595788F9F -:10CE8000952FA9E3667307D471B379E12C557D7EA4 -:10CE9000F436557FC7E952557B4D6C8EAAFD8E73D3 -:10CEA000D5AAFAE2B13B55FDEFFAC4A5AAFF685C2A -:10CEB0001D375B724D1D3753F8DB091C9138CE6D61 -:10CEC000FA1B55BFA256F5B98A3BD5E79AD9AD3EB4 -:10CED00097326F49407DBEB2A0FA7C5918D7B7FD92 -:10CEE000F971FDF15A518EEB979971DCEEFA7233BC -:10CEF000E2183DE631E1FBFF001DADB367003400F1 -:10CF000000000000000000001F8B0800000000006F -:10CF1000000BE3146060F8510FC1D3F9191836F310 -:10CF200023F8F4C0C79819188E83302303C33E201A -:10CF3000DE0AC46B80F83D0303C352203D078827F7 -:10CF400003711710BF048AD5B1623787858D81813F -:10CF50000D884F02CD3AC54CBCFD8A7C08F6215E97 -:10CF60000686B5407C9497BE6130D8F00C41FAD962 -:10CF7000F50C6AD76ED181F73708B38A3330304A5F -:10CF800020F8FD12A8F26CE20876960C6576950101 -:10CF9000F50300295128158003000000000000005F -:10CFA0001F8B080000000000000BED7D0978544540 -:10CFB000B670DDEE7B7B49BA3B9D90952574802051 -:10CFC0002A4BCB1201113B2189010306440928D2C7 -:10CFD0006C2184249D01661E3EFDFF6E0842C4D173 -:10CFE000898A1AFC195F83E004079DE0A0139DC0A5 -:10CFF000348B8833E804C70597795F401E204212BE -:10D00000A338E8F3C9AB73AA6EBAEB763769B7FFFA -:10D01000F97FFF840F8ABA55F7D4A9B3D5A9537500 -:10D020004F149D9524DD40C825F8A1E5AB0A2124C5 -:10D03000255876489DC3E581C1F6B55E177119097B -:10D0400079C06BC272BD379DB8AEA0CF47EB8AFCEA -:10D050001642EEF7DAF1F9E3DE122C1FF59662F9CB -:10D0600088D78DFD1EF29663F92B6F0D96F77A8B9C -:10D07000B0BDCEBB0AEB372A0BD2605C425CA6ACDB -:10D0800064423C2F0F1CB981D6D6678E4F9047D390 -:10D09000FA5FF5449F45DF1B2D17F987D206B9A427 -:10D0A000286B74B09F8AE78D4A5E5F80F3F8581D45 -:10D0B000EB67AA792D3B72BF2C3286E2395646FCCB -:10D0C00089A564727672C47E8301DE2343D93C89CC -:10D0D000DDF9DAA0C8F0AE06780F0DE5F825DB27FC -:10D0E0000F8A0CCF09FD7EE5E4F0D23B0F0F8CDCFC -:10D0F0006F0CF4AB7372787D7DA60191C71D0FFD97 -:10D1000062E013C589105F8BD19F9DF5FDF9455CE9 -:10D11000F42FC5A763AF79EB0609F9370DE8B4D64C -:10D12000BEFCCC163A4E7BCB30A7DE41C8672E67DB -:10D1300082DD1213DF6E8179C4C0B752182706BE94 -:10D14000CD8D916F0BA05F0C7C5B02FD62E05B6597 -:10D150008C7CFBD94F846FF7021EDF836F1B62D478 -:10D16000B75FC5C8B78D31F26D538CFAF6648C7C0D -:10D170007B2A946FEA73B5DC4124B48B372A253BB4 -:10D18000A09F27B3CD3620EB27C1BF3DDF53EFF67D -:10D19000C7C8BF5763E4DF11A04F0CFC3B1A23FF45 -:10D1A000DE89917F1FC4A8776DB8CE58E4AFDA86C8 -:10D1B00010FCB93400FEB5D84F5DCDEB7AC03B8989 -:10D1C000908C7039504BCA51940799B8DBD9BA5535 -:10D1D000F0CDA51C425698E87FE9FBBE3C12D0D3A7 -:10D1E000F17D36E2AF9584FE9F039E84E47F732930 -:10D1F00055E8EFD345EC4F74D0FE30C815E5FF6617 -:10D20000EF102CEBB91C6D2ED2A13CF8920D285FCB -:10D210004F789DD8DEE01D8BE5635C2E3772397A3E -:10D2200000E4EE0A90C3522E574CEE082971945335 -:10D23000BA76EC89271B1C28576609F09499BCDD47 -:10D24000BBE7CAAD1B28FCCD35BA2BB785C8D913AF -:10D2500045AA7C51C94C0EF67BA2FC846DC150A43A -:10D26000B70DE03414EBD47EBED07E0DEEEE7EBD65 -:10D27000A0DF63C55CBE6412081DF7B1D2EE7EE983 -:10D2800012A5CBBD12296DB284F3658AC4F4942A29 -:10D290000AF243E6F4DD9F7796B4D1F76DF6916913 -:10D2A00084964F827EA2FE39B054DFAFA7747653C6 -:10D2B0007A641A494D13E04B5A2585E22B8F752469 -:10D2C000821C3D34CE45242B21FDA19D8EDF677449 -:10D2D0001BC9A265E2F836220D837EB49DD6537831 -:10D2E0007BC650DA4EE13C04EDD6607B2A6F4F736B -:10D2F000F0F7AF63ED0F7B098EAFF6BB8FF2D94D20 -:10D30000F15B47F1C5E7C5C4057494293BFD21F3E2 -:10D310009F2DE971DE95BC54F1BF2FFB54C6FCA1D3 -:10D32000417CCD832F66CC0FC1EFBEC173B0AEE29E -:10D3300063BEA212EBFD57F5A69E18D707124EE763 -:10D34000D49903847687EC443FCD71444F7C945F3D -:10D350000E2A9E91F8F30515E71F54FF5C8C1EDA28 -:10D36000F6BB3574589721D2C1D05BA4C3BADE2274 -:10D370001D0C7D2E4F87299203E147A3873AEE8645 -:10D380002BC571E3AE12C7DD7095386EDCD53FCC8E -:10D39000B8EBFB89E31A33C571D7678AE31AFB7FC1 -:10D3A000BF7189ECA40F99B9200EF8679E60DF2E3B -:10D3B00010F7C3A0DF60E7F4C9413B27DB4B88DBF4 -:10D3C00012E42791E9CB39A170EE14EC2A85F37FA2 -:10D3D000381CD7E5E1D83570E66AE16CE37048A8FF -:10D3E0009D0E8343EED0CEE3B7FCBD802E647CBAA5 -:10D3F000BE92126BE87B4ECDF8B76BC7DF0D760C93 -:10D40000E6A1BBECF80E0D5DE768F1D9C3E110DDD4 -:10D41000E5E841EC1A38B3B5700E713801E9B27025 -:10D420004AB5F3785DE5AB24AC5F941EC382EF751B -:10D43000E4759E423FE845C5B19DB64B7FB2066E8E -:10D44000A0FD8F6C91FC465A0FEC8DC7F5E3FCB63E -:10D45000E958DF778D11D789F3CEC97E23B527939D -:10D460005E78DB06F6A5EA05BD0C75DDDE8F6D6D19 -:10D47000142F8FB1F5C1EBE8F3CE17F4642B4A6398 -:10D48000A10EE87E8ACB2659C5EA656656ADDAB2AA -:10D49000EF4E805BDE6C24660AA7EAA525D3AEA317 -:10D4A000F5258715025DAAB6AF36F4A6F5A57EA9C7 -:10D4B00009EA1D79A41CF469CDDEFF6C87F5E8FC50 -:10D4C0006E251BC63F4BD70907B5C747ACADA9337F -:10D4D000291E15FE5D85F05EC54EC9492D1CC57718 -:10D4E000FBA10CC07787E434527A2F6B8C270ED5C2 -:10D4F000DED1BFA776EB71FECBE9FC0985B784D4FA -:10D5000017023DAB803830BED3E8374B417D3BEB53 -:10D510003D8CE3A9F5AA1D743CFA7EF5739213A61F -:10D520005AAD236EC0B3FD2573E9531698E76AC35D -:10D53000602BCC6FBD01FA2DF1CF7FD1EC003CB751 -:10D54000180A01DFCD5B0C6543817E645EC950C063 -:10D55000EF2F227E0D7A17CC77F935C6AD7AE0A78A -:10D560002530688635DCCE9EA5EB952364FDAC2086 -:10D57000CCEE13D96F983E2CF8FC257D22CAC1B29F -:10D58000463D7184DA0D2E1FBEA384F9317BACFEBB -:10D59000ED59413E2EB77379E57C5C9EC8F92A7738 -:10D5A000E6CC18168ECF83C01723F38FA07C98AEDD -:10D5B0009B0EF47F1C48BFC7A8FFE440FFC889CF7B -:10D5C0009FA07E12949BA99F04E593D44F82D24FD3 -:10D5D000FD24E8B795FA49506EA37E123C7F9AFA73 -:10D5E000E7503652FF1C9E3F43FD7228777A7DF844 -:10D5F000FC396F1D964DDE7A2C9FF73660B9DBEB58 -:10D60000C77E2F7A1BB16CF636E1F397BDCD58B6C5 -:10D61000780358EE053ED332E06DC572BFF7189619 -:10D6200007BD6DF8DE21EF192C7FC9E96E9B4072B2 -:10D63000652A2F3617B1039B928A5DB9E0AF249516 -:10D64000B07AEA1DBE5C03ADA7BA699DD2B1776519 -:10D6500020D748EBBD6B587BE63D24CF44EB993E89 -:10D66000D63EE097AE3C33AD0FA867ED8337FBF2B3 -:10D67000E2687DB09FB55FB53390174FEB5735B17A -:10D68000F6E12D649285D68707587DE411D7242BC7 -:10D69000AD8F6C65F59C0F7D936CB49ED3C6DE1F79 -:10D6A0007F2E302981D6C777B2F6895F937C3BAD58 -:10D6B0004F2412D6F32CB9F989B49E6767F5C2BE20 -:10D6C000F3654784F57DAFD2B6104CDACF7539B922 -:10D6D00032F513F61ADA5680C95DAFBB21571E47E3 -:10D6E000E9A79045D0BE4957C4EA06B212DA7FAB2B -:10D6F0009B8EF5FD8A03DBF7E8E6B0BAC181ED7FCA -:10D70000D52DC4FA41C585EDC77595AC6E7061FB2A -:10D7100067BA9FE378871437B62BFAFFCDEA06374E -:10D72000B63F2CAFCFCDA7FD2BF56E8F8ECA75AD52 -:10D73000E42E2703415E9BD2C11EAEE37EEB2C9DFF -:10D7400003E57E5D8601F56CEF7FE53C857A063F5B -:10D75000C9502F7B1AFC5E0A6715C251281C7DCF69 -:10D7600070267E33568033F19B7215CE6A84638EA9 -:10D770000DCEDE6FC68BF87C53A1C2D9A0A3F6BE36 -:10D78000D61ADBBC265E9A20E273A95285F308E222 -:10D7900093181B3E01E55A014E4059A2C2D98C7024 -:10D7A0005262C3C7651827C0711996AA70B6239C28 -:10D7B0008CD8E0040CD789F81896A9709E43FAF427 -:10D7C0008B6D5E2EE3F5223EC62A15CE1F109FAC50 -:10D7D000D8E0ECB78AF4D96FEDA64F00E164C73604 -:10D7E000AF3C9B489F3C5B377D5E433857C606671E -:10D7F000BF4DA4CF7E5B377DDE4438C3629B575E4E -:10D8000082489FBC846EFA7C8070AE890D9F83290C -:10D81000227D0EA674D3E724C219131B3EF9A92258 -:10D820007DF253BBE9731EE18C8B0DCEC154913E4A -:10D830000753BBE9F305C2B93EB679E5A789F4C938 -:10D840004FEBA6CF258493EB6E447C0885638D0E49 -:10D85000E7503F913E87FA75D3C7A407380514CE29 -:10D86000C09EE114668AF429CCECA64FA21EF46295 -:10D87000726C700E658AF43994D94D9FDE88CFD4CE -:10D88000D8E655D85FA44F617F461F8FB173921DB4 -:10D89000FCC644E2DC4A5F9994FCB383B0EE2816E0 -:10D8A000E204B047A4C036804FD756F44B65A7EAD0 -:10D8B000073909F8B9C5368713E2017AD5DF21ADFA -:10D8C000B81FB1EC4C14E24D2FE9F38603BE56EAC3 -:10D8D0001586FA3D0963E3047F2BD19524D47B158B -:10D8E000F516FAA7940C10DAD34AAF12DA33DC2318 -:10D8F000857A9FF2F142FF7E357942BDFFAA294227 -:10D90000FF2CDF0CA13EB06E8ED03FBB7E81D07E5F -:10D91000454385D07EA57FB950BFBAF15F85FEC370 -:10D920009AD608ED239A3708EDD7041E16EAA30EFF -:10D930003F21F41FD3BA5568BFF6D83342FBB8B6BF -:10D94000E785FA75675E16FA5FDFB95FA8DF70F1E9 -:10D95000CF42FF5CF237A13EC9F481D0BFC0FE9137 -:10D96000D07E63FA271A3F568C5FD4E612E6CF6664 -:10D9700018D09F0D580D5837EC35B3FD0DD49321B9 -:10D980000E518C75C3FE858E6488070000EA4FE453 -:10D99000F62EBF02E255BF18EFBE02E2B8BF30B8A4 -:10D9A00047D823F841EDB2FB1E3DC6135B25920E0E -:10D9B000A54307659C9EC7138C4C7ED767E53CE565 -:10D9C0000BD183BA7ED4BFA0F5F57A8AC798A0FEA2 -:10D9D000ACEF57963E3F649C75FD0CA55B87B2E7A4 -:10D9E0000B2D305EC97D309EC7D03918F0D28E63C2 -:10D9F0001C305618C794598EE36C84715282E31818 -:10DA000033CB35E3984AB7F2E77C9CC7406FA28DD1 -:10DA1000B37EC078713E991538CE16CD38EB332BD6 -:10DA200034E3C4B1F9D0E77C9CA72E378E71E004B3 -:10DA3000713EFD2B719CE7B4F3E95FA919C782E33E -:10DA4000C0731887F4A5BB9834CA67636719CAC145 -:10DA50009FCC182733F4A9F80DD4C90766920DE3BB -:10DA600038E8B8B41F199244859A907FD127217F56 -:10DA7000BE88A3FC0F89A705F7E33EDCD72FE62875 -:10DA8000123FC588EE93AAB96C2EDA393D738583AF -:10DA900096CD07063D02E36CB43AB369BDBD7992F9 -:10DAA000616104795A5CAF9C6A0B91F3EEFD591EDB -:10DAB000195243C75F1167477CD4BA5A26E9C4E7B5 -:10DAC00027E8BE8BD0FDC987749F42E87EE5238599 -:10DAD000ED33FF9DEECFA0DE46F767D04EC86A7CDF -:10DAE000EF048F339FF8A5E4077A7F71D7CF145CDA -:10DAF000277CE4ADF4548826B09F79ABE2291382E9 -:10DB0000F8CDF7F512EAD41CF7D1A5E3BE16E3076A -:10DB10009D2F19FD5B81AE757D284D79BF0184BCB9 -:10DB2000BB77EA21C986D53EBAB184CCAC995E9068 -:10DB3000865A24F55B4EF19CB1FB1A85BE41DA95FD -:10DB4000B63B9D96205CE2524E007D4CF40FC0B96E -:10DB5000A588D643C6BFB544ACCF2272B04EF97D7E -:10DB6000523F80B0F83F1FD7E15280AF25748E1925 -:10DB700094D5B3A01C09CD2C5E536A67EFAAF87840 -:10DB8000162A2480FB6B5F0AC4B1892F19FBCD5183 -:10DB9000F7C91AFC4A1593AB84D2B574BE1EE9AA24 -:10DBA000C5F7FDBDF12EDD705AD63DA24068B627FF -:10DBB000FC67BBC57652CEC653E9AACACB29CEDFD5 -:10DBC00013C07F5A9E06FE53BC4F72FE07E598F1C4 -:10DBD000DF63744F03FE776ED213E417E7FB6D9C8F -:10DBE000EF8BEB45BEDF06E771B4FF6D2BB358BC7E -:10DBF000A9A197C05F3A71910EF50F1550B31A861F -:10DC0000FFDFB91CCCA9DBF50AB0F7F672CDFC3802 -:10DC10001FEEE47C98ABA1C76D9C6F7339DF961043 -:10DC2000DFBD1918BFF02B10D79B5D2E11B0179ECA -:10DC3000BB55BEB5097C73AB7CD3E07B27E7DB9D8E -:10DC40007731BE69F16EE37C6B6BF84C2103C2F156 -:10DC5000D6E2396F95665E3E2DDFEAB95CDA0DE0FB -:10DC60004F4D77E5AE3819D2FF96A2C92B4E86D814 -:10DC7000855B4BA60BF559A5B385FEB3DDF385F6A1 -:10DC8000DBCB970AED736B7E26D4E7ADBA4BE83F4A -:10DC9000DFB75A685F58779FD0BEB8FE21A1BEA4F7 -:10DCA0006193D07FA97F8BD0BEAC7187D05ED5B495 -:10DCB0004BA87B9A5F12FAEBF65E7933C8D791B71F -:10DCC000F504E27D179CA731CE78C1A938A1CF49D0 -:10DCD000AF03E5F89477089667BC4E94F3B3DEB1D2 -:10DCE0005856834C8E033B7BC002F1534F1CB5FB4F -:10DCF00089741D97C7ADA99B00EB0D6D1F4FC8BF61 -:10DD0000CA37ACF1F5A55A00716F4AFFE206030964 -:10DD10008C2254BA7B77CB73A73EA4BDAD87F606A1 -:10DD200099047A85B717B7457EDE21750ECE80B887 -:10DD3000EC7B46B23D24DE187EDE42FA805F11ADF8 -:10DD4000FD9C8E94879EF76C95D939CF117DDE5658 -:10DD500099E2556960FA5FF97C461EB1413D30B8E1 -:10DD6000C67299F19A283269C0E78182DE2F69B8BC -:10DD70003AA8E704C661F674A97F94F07C59E3756C -:10DD8000C27B6F48EE2D80C7B97D7A5CAF49E04019 -:10DD9000E62DC3003FD75619D6D1E614F4BB5ABDC1 -:10DDA000AE15271542DEF41661F996B704CB77BCA1 -:10DDB000A5581EF3BAB17CDF5B8EE587DE1A2CFF17 -:10DDC000DDBB0ACB36AF0FCB13DE3A2C4F7AEBB16B -:10DDD0003CE56DC0F28CD78FE5596F2396E7BC4DBB -:10DDE00058B67B9BB154ED674FF27786AFAF674172 -:10DDF0000E8DE1727670EDBC35757D837276582E8E -:10DE0000433953E95BDC60E4F2902AC8C35F611DCB -:10DE10004E0179E9A1BD41E17218EDFDC8ED206F19 -:10DE2000BD7F047923640DCA8105E4EE7BC81B81A4 -:10DE300053841490A73E1A7912E550952355CFDFED -:10DE4000904ACE817CA9726591993FA4CAD5FDE024 -:10DE50002746F0B77A2B125FFF987F4402B93A2029 -:10DE6000D9727E5E417C2EAC77F1B16B29B856E851 -:10DE700027FB87C03AD235E4ABC110DFEF3A4685C5 -:10DE8000202BFAFCB4F2129DEE2EDC3F94F929F31C -:10DE90007B85B79BE3185DCD3A524446C2F972CEFA -:10DEA0003137E567DC9FAE1E09FB66FA5C26490048 -:10DEB000C7EF9C1EE1BC800C2248E79EE8ABF63F12 -:10DEC000F5C47FE6C0B9BF05F49CCE3DEE80BE86AA -:10DED000E9EF53CE5B42CE973C46673AC4C13BB3B1 -:10DEE0000D76E63F4C12E94826E1F9814AC703D98D -:10DEF0005F0C86F399FBA81C827E750D1A9C402E40 -:10DF0000231F3DD9FB9EE8B900E61B133D0D04CE4F -:10DF1000B9283DB7C27DC758E9D9939DECC93E9E4B -:10DF2000D8C0E87C84FBA7D1E8AC9E8769F1B845EE -:10DF300091391FB81C933B34F42F15E8DFD7EAC0A2 -:10DF4000FE07F77E9009E7785DBBAF48204343DFCB -:10DF50002F60E73DDDEFE70B7A20FDE9EF99B03F59 -:10DF60003EF8C2BB58AE254C0F375A4AE62A6382A8 -:10DF7000F062BD47106D5E1E4512E7D5837E76A424 -:10DF8000AAFAD99A09F2B49BDB81B0F9F5209FEA8D -:10DF9000FC0EC0FC289CA920D3741EF972C95DC276 -:10DFA000FC46A7E0BC7B9A9F27C140A411143FAB5D -:10DFB000C14012A83C2AEEB50AEEEB9C6D3E885398 -:10DFC000EC8D77D65296786C67DF0838E03D319E4D -:10DFD000B1ACD15C23FA4F8935A2FF945113EA3FCB -:10DFE000751D7ECAE6A6F82D4FD7D79CEC05EB9C95 -:10DFF0008BAF736C5D55F1AB6ACAAAB10870C47A75 -:10E0000057BD54C4EEE13812664638EF53CBE5E90C -:10E01000061CE76CE3C00418F7ACD754C3D6577B93 -:10E020000D1B37BD26747DAD5C155F73725410BF38 -:10E0300068707F68FCA844908F4CB02ED2B681D116 -:10E04000FB47E5A7FCB901CFD55B942FC07F370F05 -:10E0500051FD7719EB2A5C4F93DE671C01CF770ADD -:10E06000E3D1F71CEAD938BC175D6E64724AE5A7A4 -:10E070001ECEBB08DF1F9890CF6E0A3181C2EB9095 -:10E080002D7520577E85E9B387CB6995A9CDE076BC -:10E0900020B95B41AE178C55E5DC31EB036AA73F35 -:10E0A000FE8B82F7CCC8D7147A4EF0AAC3225262F4 -:10E0B00083A0EA82DDCB8A61DDFEF8C59BF83EBD18 -:10E0C0003E07E67D9EE88AC02E9D276FDA4685E8EA -:10E0D000EB6985C5B1481DDBE7F8E81F98DFE27AF8 -:10E0E00071DFB3A441AC979119A9606FCB362AC4F4 -:10E0F0004F715F0AFB2675DED4FEBEABD811B92581 -:10E10000A4661DECD31F5358BC67819DC87DA8BD74 -:10E11000AEFAC3AF7320EED3AE307F573D0F5F9A98 -:10E12000C4F6831533FD0617EDFFD1EE51B7518BC1 -:10E130004BDFF7AF43FF673A716E27E1745F5827F3 -:10E14000E2D713FE5A7C553F28EC5C9EE391DC2815 -:10E1500045BC2FF535B773AA7E2419EC42DC274D58 -:10E160005357E540E172E057DC56430AE33BF05178 -:10E17000923B0DEE907E8660BF24C398E8FD8CD064 -:10E180004F8FFDD258BFCE42DC1F132A4F4383FD71 -:10E19000CC41787DD9B862BFAA3F3CFBA28FCA4B65 -:10E1A000C5EF1EB511BA6E7E2CD7A73AE9F3CAEDBA -:10E1B000F7DA5CB43C23FB6CC0CF8FFDFA88F77DA7 -:10E1C0006F31A8F470592488A771F924753E8C53D7 -:10E1D0007CB15DB1E33942A33160A4F259BD7B69E2 -:10E1E00031198EF5E3ACBEFE533DD49B457E55FC04 -:10E1F000E6D15407BB27C4E24924807E6EF5B6FF02 -:10E200002884F5C2433A51CEB4EFC1F8179350AF0A -:10E21000E71B12C2DBF162702ABCCF7E3CBBEFFF72 -:10E22000546F8372F269D0238F464ECAB9DF0AF465 -:10E2300082FD7EBEC19A8CF6FE5A722DE8BB4A174B -:10E24000E267FE6BED8EC7871FA7789DDBF6179BF5 -:10E250003434D44E3079EB6A5AF86F265D747BD231 -:10E260004EE531D44FA280F13D4733F7BB5B58599F -:10E27000A9046C701FA7728BE2A492482A9FD51341 -:10E28000B89F40DE33FA213EBAECD957DE194FE988 -:10E29000BF6C97925CCCA663915283FCF1D0BFAB6C -:10E2A0004606F951F1FB570C8E61ECF93D4941BE30 -:10E2B0002CDBB5CF408685D37152D33E439B2502DC -:10E2C0007F9A8E17C27A5BBBE31F06882B7EBC57F2 -:10E2D000226959E1EF976F7905D73DA013F293F3C7 -:10E2E000AB9B7F617C0B4C7B7934F6B3833DEC892F -:10E2F0006FD9B09F4B41F97EEE65B8C7F4BED10926 -:10E3000074287F6E850DE6735AAE6172FEEB7B5307 -:10E3100041DFCB155FAA1D4BF6BCFCC99FA3FC2DAA -:10E3200039FAF354F41F882B4387B6D99701F35C6D -:10E33000BCF9569C671971A31C96FF5A5F02F74CF3 -:10E340002FC8A46857043DF98B81ED5F4E6FA5CCB3 -:10E35000A5F33C0DF8817D7B53EFDF8E71F39FE1D8 -:10E360003DB89FF339D39510EB174C8C5F5B0C3A9B -:10E37000351E6A12E477DBFA56E0D3D97EAE343824 -:10E38000F7A074F071BA4997285CFDD18234C62792 -:10E39000E29073F87BD4DE4F82E7D0BF5571998746 -:10E3A0000BEF71FBC8C65FC9C7A778C7C1FA753A3A -:10E3B00035B2FFF70F3E3FFAD34A42E42C44DF99CF -:10E3C000FE6FBB8FE9BBAAFFFEE945D0FEF95B4CAF -:10E3D0008FE03D582F285E81346CDF375342FB407D -:10E3E000F7D991F47C9BC2F55C6CA73B1C5CFF5594 -:10E3F00039A1F8CB5242A8BCD07192900FB83F2EF1 -:10E40000DB48DF0FF1CB3C302EF633049F87AC1B8B -:10E410004BB85D38A4B10764734A4C7E74A5E27FA3 -:10E42000FA09D0DFF78C4E9F03F4572981F97FB2A8 -:10E43000F3C03B73A89C7FD2A4EAAD6857B57A5B62 -:10E44000FEFC1812496F3FB1D07D5724BDA5CF23E4 -:10E45000EAADA50DE5F9FF965D55E9D7AEA11FD848 -:10E46000C7971DD1E9A8B58F1B0C8E88F691FEBC0D -:10E470004572C2E550953F55EE2A7E5BD51FEC50A4 -:10E48000B77CAAF2D72D9FAAFC69E72BD24FDBFEFF -:10E4900007D06F8AD7EDA64DD3C07F3675128CC3D7 -:10E4A000E7CED4E33D4DD3E784DDD3B8231EEBB3F1 -:10E4B000F46DBF079FF083AA59C3609DBF9DF814F8 -:10E4C000766E5FAFA01FFBF5A54B13E87CE670FAF4 -:10E4D000DE4EC93D95F2A35496027114CFD932F1A4 -:10E4E0002524413C59222742F0B8BD5CACC3CFC4BF -:10E4F000D4209C9EFA7F5BBFFBBB9647295F4F648D -:10E5000013F2372871FF411DEB10799ADEC2CE312C -:10E510003CA325FF00D4C336B924641FE13132FB8C -:10E520007334FF963140BFDC59C312989C0FC6FD6F -:10E53000A287DBB12E9F2301EC7B57CB40DC177603 -:10E540001D5E687547B06707B89CBDC2CF613A2CA5 -:10E5500052BD9ECA7D07E944BFC66731478CCBCD0B -:10E5600031AA769AF38DFEE8E9F8A55C0E67D357D9 -:10E57000134686F06DE6D48F655B381FE0E744C82C -:10E58000BEE2FBD217E41AE87BC0DC565812217EAB -:10E5900053C9E93771FF970658F7F25B7265A063BC -:10E5A000BE452FC4431619B9BE0E254301AF89FBE2 -:10E5B000973E3086CAB1E7B0DE69A6F3F3B47C6A51 -:10E5C0007047D8DF69E909F0C1BFDC6A64FEF2DB9D -:10E5D0004AC962A0EBDBB7B2F3DEBF199C5591F0DC -:10E5E0004C37337F733629B9305AFAE9D1377796E9 -:10E5F000359047E9D16561F7B5C3E58FE97D975D52 -:10E60000F2AF96400EF5AC9ECCEE371712F703131F -:10E6100024D4F71B42ED576EF3F467E13E4D758B42 -:10E6200064D7D1F66AB9CD0072EC69DE2583DF7E4E -:10E630009383B8707F2DD70C9B1912FFA2CB1ED2EB -:10E64000EBC05773E6027D3F9B692480976BE8A778 -:10E650003658FF3F6B19857A106D5EAF7BC9B47C6D -:10E6600005E0307BA69587C2E478A17EEB24D21723 -:10E67000CE81271ADB563823F02FDFC4E42C66FB4B -:10E6800066FAFFCCBE4DA0F68DC9B5126ADF2CA686 -:10E6900030FB9616C9BE2D5FED4803B958BE672002 -:10E6A0007EBFB5FCB5C52991ECDBAB7CDFFB1ABFA7 -:10E6B00007DED197DAB71121F6AD2FB56F11E2E47D -:10E6C0005FC46ADF4CFF33FAF72AD8B708F3359BEB -:10E6D00044FB56D4B21AED5B515FBD705F8998A8B8 -:10E6E0007D8BBF9C7D9BFFE8AD58579CF111E407E3 -:10E6F000E80AF6ED356EE7601CB0733798587C3346 -:10E70000563BD72F563BF73F4467D5CE2DEF27A179 -:10E71000FF122E87CCCE2DCF62766EF91E66E7965D -:10E7200067333BA7B56F7961F68DBD5F3D84BE8FC2 -:10E73000FBC7ACC7EF80FB84A58AD344FB173BD44F -:10E74000EF276AC684DABB1B4C32D239CCDE393FA4 -:10E75000C5EF607AB2777F057B978D766C10E89174 -:10E76000563EA60C8A17EEB3BDFDE5A9DFFE0EF4FA -:10E77000E5753DDE177A57C7F6477BBF3C350AF48F -:10E78000EE2113B3BF4B4C8C9FED5E1FDAD3494390 -:10E7900099BE57DDC3E857BD5B62F35DA9F73B60E7 -:10E7A0001DF8EA22EE9FE7EE61FBE759C6D69478A2 -:10E7B000B897F42F0A61DF7D90E2F921F2507AB127 -:10E7C00002E380CFC7D9B6C2FEB2542626F063E773 -:10E7D0001D9EF231F8AFF32ED6A1DF3B0F9EC33959 -:10E7E00009BF27A1DEA398D3BCEB953E24FC7EC4D1 -:10E7F0004423E3C3C415927F4B16DC4710DBE76963 -:10E80000FCFA757C9ED49F45BA90BFEA23C6EFD62A -:10E8100069E9E164F3AF5AA917E9512345A407E573 -:10E8200068F1FCD4E0FCE7BED0B6AE0FB42F957013 -:10E830003FA5D2433B4F953EEA7E651ED7114FCB95 -:10E840002E05F8A59DBF4ABFB079ABF4D4CCBF4E1E -:10E85000B51F579361A06FEFEADC0F8C01F9F83315 -:10E86000A503C5EBB6D9D969A1F6F8416E97A6BA4A -:10E870008FE7A73A806EECBBC439E5BB5E49A5F3D0 -:10E88000B9D9953512BE1FBEF52B831BE20B07CC01 -:10E890009D68DF54F9FA84CB7B80C379BBB73D1FF9 -:10E8A000D79166C98E7A13D0D82F7E7FCC730FD3C1 -:10E8B000AB03D23FD6F5198D7485658014AAEB1091 -:10E8C000F081FE776A0BE38307F840FF3B8D741EEF -:10E8D000023A57274BCE00F46FDE752FC8CDAB66DA -:10E8E000FA1CF4B75C72B2EFCB882523F5B2F2299B -:10E8F00047924F0C4EE404D7C579D02F29DCEF980E -:10E90000686C7D1BF09848F5610B09F74354BE0F06 -:10E91000A17F2E45BAF7D3831C7FCCE5F355A0B772 -:10E9200005E8DA69007FC61360EB87DAEE911DF91E -:10E93000481F95DECD747D18CDE8AD8B40CF9BD5BB -:10E940003AA7A7A74552E0FDC974FFDA4B82D3ADC1 -:10E950002F0FA9720CDFC369E901F1808C10BD078C -:10E96000FB147A3E59DD7C14E932652575AF42E827 -:10E970000E76EB72F489A617D5CD3F8C5E7CA2D1C2 -:10E980008BBDE6CEBF8C80F8D71E09ED0369491414 -:10E99000F6FBF166E6671C30BB517E3B5F53F0FE31 -:10E9A000B9D68E7CCDE51EF617A1DFFD4D8289809C -:10E9B0009DB39BC9472A1E03981C85DAEF57CD6E7D -:10E9C000E45734F8717C1D8EE63FA9F51B613CB815 -:10E9D0008FE810C70BF32F78FCA7A779A5F171BFBB -:10E9E000EBBCBACF3349AB81B0F8FF0A63C8B9D4E6 -:10E9F0006DFC5CA03B4E16EC67375DA61FC45F0242 -:10EA000074DEAFEE7C0AE3BFE79F393E0DE477D9B1 -:10EA10001FF5C444F9DCBED34A02ECDE8501D6D929 -:10EA20008ADDFA88E72884D4B2EF1C7F6745FB5261 -:10EA3000F1BCD15F4CDFAF78F1A3E110B76A5FC3DF -:10EA4000EC8CEF192E1FBEB6E170BE5E21B3736170 -:10EA50002DBCEBB8BC9C7B29BE14ECA4D4C8BE5F13 -:10EA6000AD689AA51843F6E923CD0A8E4BFBE1BDAC -:10EA700065DF0E09E3E5E1F8AD66F07630FB57D1CE -:10EA8000ACF8E13BD88AC62DB8BFF5347E6A00BF2A -:10EA90006ED2EF9E65DFD736EBC5F861A33E60C44A -:10EAA00038A7FEB87138D35B49884755A15E563701 -:10EAB000F13899267EB4EC777B5EF451D22CFBFDC5 -:10EAC0006F6C606FCEB66EB7617CAE91C5DF648B44 -:10EAD0001C393ED7535CAEE93E1E979B7A9A0C0FC9 -:10EAE0008FCB9D85FF503D9C6FE6FAAAC6351B7BF8 -:10EAF000C5747EBEECD90B4FC279D2B9E73F79120B -:10EB0000F0AFFCE6B327EF867389BD663BAC7F9E12 -:10EB100067DEC6F8BBFADEDD5CCEDB77FCE6E92714 -:10EB2000A81EB6BF67C47B5BED7B4E67C2F78CED5A -:10EB3000BBBE4C85F8E6CA3D05B89F59F9C2A4B4DE -:10EB4000CBDD3F01F9F4C7707EA2E5C781DD7A0213 -:10EB5000DF739E3F6644FFA33BCEDA54C5E2D70E77 -:10EB60001E5FDD19F9BC4A8D0756EFBEE5E6EB6185 -:10EB70001DDCAD381DF89CC7077B8AABBE45F93A52 -:10EB80002206FEEDE4F1F3A6A911E3AAE7E13F9422 -:10EB90004F9BCC625CF5C2EEC5FFF604B4EDEE15FA -:10EBA00035AE1A88816EEA795899D9B5CD0CFAF14B -:10EBB000FC6F318E0D7CA33E39697FF64226C4235B -:10EBC000CE289D77E23DE53D46BC6754B1E75DD474 -:10EBD00097F6178EE23913E1E751EDA4FB879D1BF1 -:10EBE000F0BD8E679B95C56339FD215EEBB0E17387 -:10EBF0001E976572ACC66BA3C569DF37B3FB50EADD -:10EC0000F95CD5B60F0C4413FF96C602BF8E0BE716 -:10EC10008AEABCB5F0EC40876B43CF1FA2C5C3B9ED -:10EC20005D0DE3173B7768DFC2CF23BACF1908E940 -:10EC30003B12CEC7D9B9B9C72FBD1B89BFEAF9C3EB -:10EC4000DB5AFDF4C776EED033DEDF8D2EAF9AD9D6 -:10EC5000FE56A5CFB9AF23DBE94EAEEF749DE93088 -:10EC6000E3B9315B67E6F175A69AD28D7DF7C6F000 -:10EC70003DC7F781E79ED1FB61BFBCAEE900DA5B1F -:10EC8000AD9E571316FFD28E27C531FFA0BA79DF8C -:10EC900070B047E7F6BF84F257BDF3B8C147E11C37 -:10ECA0006AFCBDA16D6850DEC18EFB43ECF8B9E78C -:10ECB000F60D67E72291F3B4D8387C4F8B08DFB3A9 -:10ECC000F35301FE325F93C16EE9799CB3B26B16C8 -:10ECD000CCF76CAB42E03EFBD9267D913FC2B89F9A -:10ECE000C13A362648A77556F61D9F3EC9807EE676 -:10ECF0004AEBD863F0FDF84AABC101FBEDDAD5EC85 -:10ED00005E65EDFF72A6035F6A136FC373A37A0D8E -:10ED10001DEDC9F65CD887DBF34B46835869ED419E -:10ED2000A24B27E0BDD25A94E6B0405E2FE6A71072 -:10ED3000D989DF19EA6D8545300FBD5D6737475CBE -:10ED40005F193CC5C2F2662876F1BBBFEF9007831E -:10ED5000403E8E6F9D07A3539307A3FCC6FFD7F2D7 -:10ED600060F8609C9F401E8C00C677D43C18C93F59 -:10ED7000721E0C882F8D0EC983D1A9C983C1F9F8E1 -:10ED8000CF3C18FFCC8301A59A07E39D0D65059044 -:10ED9000A742CD83716683A700F252A87930BEDA0C -:10EDA000B08AD5791E0CCBFDAB0B42F36064DEBF9D -:10EDB00001DBD53C18CEFB1F2908CD839177FFE6F8 -:10EDC00082D03C1833EFDF5E109A07A3ECFEE70A0F -:10EDD000843C186BFF500079305E8F77B7C6A5442E -:10EDE000CF83D11CE788290F0685F31EC2899207BD -:10EDF000430B275A1E0C0AE744DC98E87930C2F02E -:10EE000089920783C2F904E144C98311864F943C77 -:10EE10001814CEE738AF287930B470A2E5C1A070DD -:10EE2000FE0BE144C983A185132D0F068563884F2E -:10EE3000899E07230C9F287930289C048413250F72 -:10EE400046183E51F2605038E908274A1E0C2D9CA6 -:10EE5000687930289C2C8413250F86164EB43C18F4 -:10EE600014CE55F163A2E7C108C3274A1E0C0A67F6 -:10EE700014E213250F46183E51F260503813104E1D -:10EE8000943C185A38D1F26050380538AF287930A0 -:10EE9000B470A2E5C1A070A6213E51F26084E113D6 -:10EEA000250F0685330BF1899207230C9F287930B3 -:10EEB000281C37E213250F86164EB43C1814CE5288 -:10EEC0008413250F86164EB43C1814CE7284132575 -:10EED0000F46183E51F260503877239C287930C293 -:10EEE000F0F9AE7930CC8141D240CC8381F938BB86 -:10EEF000F360247FEB3C18BF027CFF9907E39F7906 -:10EF0000307E8C3C18B75ADD7F8FC77DE377CB838B -:10EF100071265E9337A2873C18B75A4BCE823C7F4E -:10EF2000DB3C1817E2BF5D1E0C3ACE3F2E374EB4C5 -:10EF30003C183ACBB7CB8341C7912D632E339F2822 -:10EF40007930122C62FE901F2B0FC6B1F8249C4F13 -:10EF5000B43C183FB97C13749B05FBB4E9288AE4E0 -:10EF600027937F62B485C70D7FA8FC1330E99C9F6F -:10EF700052FE09358F419302EBE1FB9CEFEF70B934 -:10EF8000F880E7A13816350F857F2AC677978A79EA -:10EF900028A6703ECE768BF23085B0739429F9594D -:10EFA000FE5AD8AF976BF2500C11CFE98BDD47F3C7 -:10EFB000293832D529CEE328978769A59F1E04F604 -:10EFC000DC3C36721E8A199C1FD3357499C2F936FF -:10EFD0009D97B7C3A739549E8BCB8FCA40D7698EF4 -:10EFE0003619E3F437A9FC7308FC9BC9E16AF19D6B -:10EFF000C1F9376332E39F16EFB7807F14EFB7CACA -:10F000004721FFB4786BF1D4F29F84F23B247F4810 -:10F010002E11F34F4C3289F9270AEC62FE891BD37B -:10F02000C5FC13931D62FE899B8688F927A63AC505 -:10F03000FC13378F15F34F4C77ADD6E4BFB84F9321 -:10F04000FFE2214DFE8B4D9AFC175B34F92F766859 -:10F05000F25FECD2E4BF784993FF629F505F58F7AC -:10F060009AD07F71FD51A1BEA4E13DA1FF52FF7175 -:10F07000A17D59E3C7427B55D3A742DDD3FCA5D080 -:10F08000BFA7FC036FF1EFA1DFE1DF431FE3DF4325 -:10F09000BFDF43FE8B772C4BD785E6BF78DFE25985 -:10F0A0000779098E5B1C3CAF40E4FC16DDED51F2A4 -:10F0B0005F04DFFFF6F92F52927FF87C043A2BFBB6 -:10F0C0001EB0B7254F674DF9EEF9086E2D11BFEB55 -:10F0D0009E552A7ED7ADB3B2EFB567BBC5EFBB6F08 -:10F0E0002F17BFEF1E11E796000F6DFE8BDE1697F0 -:10F0F000CE0AF692E72908C077BAD9106F2BC2F270 -:10F1000020E4BFC886785B29968721FF052DFF0C78 -:10F11000F92F687904F25FD0F20DC87F910DF933B1 -:10F120007C3C7F461DCF9F51CFF36734F0FC197EA6 -:10F130009E3FA391E7CF68E2F9339A79FE8C00C233 -:10F1400039E13D8CE5496F2B96A7BCC7B03CE36D18 -:10F15000C3F2ACF70C96E7BC9D58B67B2F62196BD7 -:10F16000FE0C552E3F04BFE10A189FC9B32AA757CA -:10F170003FF0C8BAD0FC19231ED884721A2D6F46EE -:10F180000E7CD397123D6F46777B94BC19C1F7A3D1 -:10F19000E7CD481BFDE3E5CD986BF961F266CCAD98 -:10F1A00011F33ACC5B75F9BC1923E24A6E41F9E3DD -:10F1B000F238D7125BDE0C9F55E2DFE553BA80DFF1 -:10F1C00045E982EB750F79070E5A9F1E02FB89AE47 -:10F1D00021575D36DF83562EA2D39BE57798F32324 -:10F1E000E7CBE889AE6AFFF72B581E87B9966F996F -:10F1F0002FA3877C0B07B3BF403B196BBE8C9ED6F9 -:10F20000879EE839E347CE97D1935DEDC99EBE391D -:10F2100085D1B9770F7456BF97AE34B51EC297ED3E -:10F220002E546D997F0F9F3BD38EF1998E9DFC5E7E -:10F230009C8B38ECA9EC7B7DF0373B9E4F184EF051 -:10F240003B7E3B7151FEC4F3E7D2CE7DFBE05EC056 -:10F250005A1B71252681B3471CFA81B00FBBC60427 -:10F26000F19AAADD9FBEF1470AD7DCA2C7FB721D47 -:10F27000148756F4FB5C89C0B778F24BDCA7C3193E -:10F28000DDA55EA1DF756B7E0F0774490D9E3F15EE -:10F29000E82DB86FEADACCEEB3EAC9D58F4F188DF6 -:10F2A000F7C689DF81FC433F7519C7B38B10670030 -:10F2B000FAEFB4E2FDD525AF2D34C0A070DE1A1AE6 -:10F2C00037E85524C6811ACCB6E1706F2F5DBDBFFB -:10F2D000E773B5821FBE88C34D2911E3449F2C28D4 -:10F2E0003A0CFEF3227719DEAB482B15E346847FF8 -:10F2F000470FDB32F03365C2EF75FAD97DCFB0EF3F -:10F30000EA9BB7209E4BFD9AFB4B8D625DA5DB39D6 -:10F310002BBF9762219698E8D676C5E31392BF3D3E -:10F32000DD8CE922DDCC0E916EF14344BA68E966CA -:10F33000758A74D1D22D61AC185F53E9A6DEA7FCA3 -:10F34000A1E89664E3F73C82F42A31A5A2C9473CC0 -:10F3500033E400CAB7561FFA5802F01B7E48BF6458 -:10F36000FF6A7CCB6995C16EA533D0445AC4DE8B4D -:10F37000077D80FCBDC489FAA0FE3E8A78F2219701 -:10F38000FB8FC8255AAE987EF0F802DABA19E46D00 -:10F3900004FB3D1A18AF4A22B89F5388D30EFBA82E -:10F3A00026AFC9B94881734DE25C940DE799762C7C -:10F3B0001FE4DF3B770C25B8EF6F0A7C9E0AF70647 -:10F3C0001E1CD9390DE20F9EC5A404D6AF59096C95 -:10F3D0007D5DC64B5B028BCF6C28D111D768F87D61 -:10F3E0004A7ABF44C76BB7BB5EBB01FCD116763F00 -:10F3F00080D83BDFB81DDB47E1F7E119BAFA6B00B3 -:10F400001FDA1FBF2BEE68F9C8B630C40EB7373FFE -:10F410007225DC6BDDA48BFC3D73818DFFFE1D7EB0 -:10F420003F654430DF42816D0CE6657870001DA7B2 -:10F430007A7A17F25195CBEB38FD0F964D41FC5E71 -:10F4400068911C10AF2BD4DF71D3308ADFB8B76559 -:10F450007EAF97DD5F1FCDFBD79AA9FEA2FDAAFF65 -:10F460001BFC9E95974ECA980F71744D19DE13FCC4 -:10F47000A3ADF030F02BC7D5340AE429BF2511CF56 -:10F48000713D1F12277E9AD52ADE07CCE1F7B673AD -:10F49000DA881F84E2DA6362FBB836B17E9D66FFCC -:10F4A00039DFC6F5D4465241EE367EAD9760FDE8B1 -:10F4B000E824CE3514DF8E45BD71FC8ECF09FA8964 -:10F4C0001D5FEB8B22DD8F596E63FCDB642068BF10 -:10F4D000379559F0DEF9FEB28AFEE05F7C7197BB8A -:10F4E0007FA43865889F96C0BEBB772590B12087E2 -:10F4F0006B2546EFFA8C9208EB962A77AA1CAAF2A3 -:10F50000975116E78E740FF5339B847296573644E5 -:10F510003280FCEC9530FCD5BE86E2759975DB47F0 -:10F52000D6F4017C3CCD9FE17D32538BE48A744F4D -:10F53000E7619B8DDD6F5CE35B0DF7467E419508CF -:10F54000EC5486A13E2B127C1FD9887EE95D3607DC -:10F550007BCFC4F320C9F519709FA2BD79D2E475A1 -:10F5600014CF27A83EC07AB5497122DEBE2A42F0E8 -:10F570009E2C8FD7F59D46B66C08F17F37DB721B4A -:10F580006D145EA38D7D6FD9CBED94006FE77FFD89 -:10F59000C306F03B2E1A917FBDB9BFA9BE7780D3B9 -:10F5A000675C826B2BBC4FE0979F51E3E374DB9C5D -:10F5B0008B46415C9ED23BC40E06F9E663F951DCF2 -:10F5C00004CF3F922C3A9443E27239ECC27D761F0D -:10F5D000EA8DAA07242011C853A0DA37A9450A5892 -:10F5E000A9DC8F365902708F2EA99CCE3B19F29A56 -:10F5F0009818BC56F99C18D7A2F29803CE3DC1AB1F -:10F60000F3104805F8AADD53EDE5DA44668FD63EDF -:10F6100024635ED4CD729B19E2A9592E471EA4889B -:10F620004C921D78AFA65F3971520C49FCC05F2720 -:10F6300076FB0154C9AFF9463F2FD2775B176DCCEB -:10F64000DF1E97E0FE33D06BF8E1CEFDE02E38CD23 -:10F65000A417BBFFC5ED04F76B0AF97A37EE3F74C8 -:10F66000EC7BD1C00D24F43B2AAD9DD86466EBFC45 -:10F67000B8EBD9BA37EEBC05D7BD6E3B515688EB17 -:10F68000D4C8965107E09EC5C80F997E126E1FEC34 -:10F69000F40FD029E7B04F0FF4F9B67641CB6F12D3 -:10F6A0003075D787EAE01C86EA5BC8FB673576646D -:10F6B000C5F441B5185EE672D4FF1EA7DE1D4247B1 -:10F6C000EDFBDD714AC9D4FDDC3110ECC8113DDC25 -:10F6D0000BE9C8A5F3A3F3DFC8F525F173FF649820 -:10F6E000D7C6961BCD20DF6B0379F662FA4EA2A92E -:10F6F000049997485C18CF19493D32C88F518B4205 -:10F7000041FD41A58424A4C03DB42221DE432C49FF -:10F710003CFF4B00F9D22DA7548E43EFE5AAF2A986 -:10F720009547557E6BE1A005CE0721624E4BBDD4B7 -:10F7300084878146B2D90EEBBBEA5FD6727FAED624 -:10F740009CE9C7EF977C19E81FADE4FE51ADA5D049 -:10F7500084E6605F32AEEB2B217E42E9B03285D980 -:10F7600079753E5AB9F45CD4137FC83EC12377E261 -:10F770007D44CF45033E5FA7B807C0FC55FA5CC384 -:10F78000E9A3A58794C0F79D9C2E3DE39B63877BEF -:10F79000C1892617598FF8E6E13DEEA6C04813ACA3 -:10F7A000BFF76AF08D01CF6B13C684E3295BA2E03B -:10F7B00099CCF0BC8EB8FFD846E53767455D6D3C07 -:10F7C000EA15792B3D275CAFB47AA4EA8D1AE7BD20 -:10F7D000B6B2FE005EBBED416F3CF18C2E4EA5042F -:10F7E000EF5739F7C4A31DD1EAD3E77CFE9E7846D4 -:10F7F000BF058A7B06CCCFA3EBCC043919EE20BD24 -:10F800008A2992C39BF5A8E7A435B67BF8AA7FA501 -:10F81000FA55DA7EAA5FA5DA63F51EFCDA04F77CF6 -:10F820009003A999CA2DC5A7D6CEF64B9B6DEE4580 -:10F8300080573CC53D0EF68D430259ECFB5F512FBE -:10F84000A2E941BC46CE9B0232AE0B3EBA2E644BBF -:10F85000E178A8E30F4A48647CA45A0EEB7DDF1CD4 -:10F86000C206AB269837A7EF70E28675ABEF4876F5 -:10F870009F714D02B3BFB5096CDD52CBCDB692BBC3 -:10F8800051BF65E2338EFCEE7803AA70DF7C6D8297 -:10F89000EB2EA087A9C885F3E863274EF04BFBC881 -:10F8A0004D127C379A54E990D83D7312FC7E8BC27E -:10F8B000EB53ECC8057DED03FB6BE8DF1239CFD8C5 -:10F8C000A309EAFD5EE67F3A49771EAF471398FF2A -:10F8D0007908529FF42A56F382A9E7394E09E8D4F1 -:10F8E0006EBD0D916EBF20313F3D91D14BBB4F009E -:10F8F000C287FEFEBD7B0D44362791E0EF59D599B6 -:10F90000D0BF8F27CE26B057BB1206F0734C671DB1 -:10F91000D47F25779A128706E55D95E30727CC709B -:10F92000422A52DBF55DC3614F45E57A27D0BF7DA2 -:10F9300042D760CC41493A3399FCB8F442BE209595 -:10F940000FCD8AC00733ECC343EDA4D53004FCD1FE -:10F950007629CE09F72CDA974A0C5FC9C4F329C976 -:10F96000C23CD3E3997FDDC1EDD53B09592827AAD5 -:10F970003DA6F3AB83523B0F8F11EF7490CE3DF158 -:10F98000FEAD706EA5C93FA9CD4F3969A105EF7FC6 -:10F990006CDC63C6FD6B57093BC7EF6A31A27D8EF5 -:10F9A000A6B7696DE688711CB5A4F47B0BE897A631 -:10F9B000D424823D4C9B7BD2067CD7D2A543F25DFA -:10F9C0007308F645AF2B11BFBB55CBF4F49B121750 -:10F9D000D1FEE91993B1549F3758E488F7CD4F739E -:10F9E000BD52E5F14A3A22DF0F9D06793CEF7EF3E6 -:10F9F0001D1709DEDF6F8863746C886374EC728F87 -:10FA00004F781AE4CD9781FAB0583D07E5FB7F3572 -:10FA1000CF943ADE46AF2951A62AD0B0608A19D6D3 -:10FA20008914E29A3C1B9475A342E03BA2C7BC3BFD -:10FA300012F3318E6D12EFF9DAD9BDE1CF3716E04E -:10FA400077DEA9648D7930A5475989CE09F183F312 -:10FA50000BDEB7E9A83C2DE8D39A03F2FBBAE22605 -:10FA6000F63118EAC2FDC99252833F40F996DC4054 -:10FA70000D05A5CB7F03D85B39A8008000000000EE -:10FA80001F8B080000000000000BB57D0B7854D5DB -:10FA9000B5F03E73CE3C92992433794E1EC009E1F5 -:10FAA0009D108724BC1F4E9E448830BC0485EA808C -:10FAB00028CF2488D6DFB6DECBC444F4A2B745E90C -:10FAC000AFF4D6DB7FB0A2A8200182069AA413402F -:10FAD000E4113408A8A8AD5129620BC908EAC5D6BB -:10FAE0007BFDD75A7B9FCCCC4922D8DE4E3EBFED62 -:10FAF0003E8FBDD75EEFB5F6DA872EC977134B641C -:10FB0000CCB7D8C0B64A8C7D87BF1B43ADD96E60D9 -:10FB10002C89B196383BB54EE70CC7D284F07E8570 -:10FB200063693E63D5D6D85C16876D7F3F8B85F1C0 -:10FB30008A58EAD202685BACAE5A95B12546AFDD71 -:10FB40000ECF774EBA3CA48EE12FD8DF3392B12E80 -:10FB5000236B94E2B01F606C0C4350F8CFED56ED70 -:10FB6000D097F0FFE1FD448B2D20C3B8CCA35CEC13 -:10FB7000B0F047BE1B281E4D66CC285E939ADEF877 -:10FB800046CA652C7672116370DFCA5C8FB22CB8DE -:10FB9000318CA99E18C6A2D833F6F3D98C19F07D02 -:10FBA000584757F3BBFD7C00C71FFEE54A0C83FB9B -:10FBB0001F29C118570E63171E3C15E3B6C1F50780 -:10FBC000E5723FF46F4740C687F0926F870BA31929 -:10FBD0007BC4EE1981EBBA63DD7F8FF1DA42F7D98E -:10FBE00003703195B1157E19E7E6F0C27FABB659C7 -:10FBF00019B384FA95F509117DC018E1B5D2CCD6B8 -:10FC0000D4DB7AD26305D203E65DB17D8B295DC575 -:10FC1000F9BD93ECD0BFA0C0AB80EF0B0D317E5F80 -:10FC200066089E25DB4799D2E1D6474D661680755A -:10FC300030A5DDC86C84B50A09F0E61578D3C37920 -:10FC4000B8C54AE3DDF57F65BF1996BA18E67A2094 -:10FC50001E9E6F5A51C1727BAEE3AE3FA86529402C -:10FC6000BCBBFE4D623E953FFF601E3CFFC0235F64 -:10FC700020DDF4EB5CEC337ED211B16E376300CF44 -:10FC80003241EF3B1F8DBCBFACE9311A6729F39AB3 -:10FC9000909E776DD4DFBFE933E4BB654C095D0707 -:10FCA0003C5C3E9265453CDC618F493C0F20038FF4 -:10FCB0008DFD0EDEDF7D64609C37A7277EB5F6E202 -:10FCC0003AE06F33637F5E67A1F6C23A46ED08BB48 -:10FCD0004AF459DD74F27EE4AFAAC65D261CA7C5BE -:10FCE000FFA78409F04861D3373232572173DF7B95 -:10FCF0000EF0F92326B3EF007FBB19E79FF546CF3F -:10FD00003D48AF1BAF96D37DFDFA1769FC7F249E5B -:10FD1000F86711AE3B17AF2B5FF6B6AE9FE2BA8025 -:10FD20009FD95858977CFDEBD2D6A3AD4FBB5F2926 -:10FD300003DFF5F2BEC6EF23843E58FADCACF5696A -:10FD4000808ADAE6CFFA77103FB1D328BF1A3F2D69 -:10FD50001374D2F38D46C76EFE68FA775A9F463FFA -:10FD6000E07FA7C1896DC06918D7934FF47CA1E7E4 -:10FD7000834E63477F945F3D1F744A6C416FEBFA7B -:10FD800037FB405AD752D55D6687FB7731CF7A3B38 -:10FD9000AD67235DBFA06C3CFC3394ABE7385F7765 -:10FDA000EB3933973776DCE847BDB936464D71D825 -:10FDB00004FD80CE9DBBCC3E7C4E9BE7FC3AB77BDE -:10FDC0009011F15E4EED9FD779DC830687EEDFFD63 -:10FDD000AB2BB12ABCDF358C95A3DC77C644C2BB04 -:10FDE000CF2E133CFB900EC87F4AFBFF7C803AE984 -:10FDF000B9F631A847CF7FFB5FB11E78BEEB5B73CE -:10FE0000796FEB3C2DE807EAE5B413F8EC7621674F -:10FE1000B73755125D963C33CB84FCCC1EE0F8B46A -:10FE2000C01FEAD7B6A8D867711D8B1B24D2237ACE -:10FE30007ADCE59AFA39EADB3BFD85F47E0FFAB00D -:10FE4000C789BE77213D8685E831D6A1727854F8FE -:10FE500003BEB943F0CD79658DC9007AE4FC3380E7 -:10FE60006F007995C2DCBDE9C1FE0ECE877DAD473E -:10FE7000BF8EBEE05FF65CCDFA3486EB1F654AEBC1 -:10FE800045EF68EBBF8BB96249EF88F5B28E1B492D -:10FE90005EAB2D7C5E6D9D2B9AEE9C817C51B519DD -:10FEA000E895D973DDA87717F7026F997CD168813F -:10FEB000F7BA1E905CA86FFBA283A627EE12F85A31 -:10FEC000B96DF10C349A8B613E3913F5D1176FC6B9 -:10FED00024A25C415FFA1E7A35C91F9B711D8CE319 -:10FEE0007B09E07B8374FDF45BB6B9D03D28ECB9A7 -:10FEF00015FE9BDC83C2F5998EAE6CDBACD0F3644F -:10FF0000B7DD26B4C7F10EA1BF845EEE5BBE60E133 -:10FF100000E7DA1D0EB26F6C8D83F46375D3165350 -:10FF2000B8DDD5E44B93B7B10E3BF15955E313F46B -:10FF30001CE85FD501FD4A4BC7CF6F55C3F0394E62 -:10FF4000D051AE30A1FEEE4B7F82BEF9B2236C9D44 -:10FF5000231CC2AE08FD7B2DFDA0C1AD1F57D307EA -:10FF60001ADC1ADF6BEBD1F37D5FF0E9E9C2989FF1 -:10FF7000FB0B3AFAAC427A84F5115E05F0DBD66CE5 -:10FF8000F53F04F0B6491C7E5F7314C1DFE92C769F -:10FF90009F033FAF2A7521B527F0C554F4EB3CD33E -:10FFA000109F9A3FC70A1222FC247DABF93779C211 -:10FFB0009FDA1BE5CE0713093F4F02F2C3949A8ED6 -:10FFC000391620D9AD8EEDE50A8C3FE5898E395181 -:10FFD000D05FE8D8C1FB5B3B4E595C8CD5B057CAAB -:10FFE0004BA07F3BA013C7BB565B60F62C44F95D6A -:10FFF0000D7E9205ECD1EAD3430EA1DCAD6EAF28A5 -:020000022000DC -:1000000097C0EEAC068323813DAA74C706ACB9D471 -:100010006713E0B9E7EDDE65C42F57EBC86EAD3E60 -:10002000AD70B9399248EB5700F62878AF2E1AFC1C -:1000300055C0575DBCC5559B49D77D51F1D877ABAD -:100040006AD8758D1EF81EC25167606E07B4AD4741 -:1000500087C4757C8FDD6E5DC72A14E08383EB2C2B -:10006000D4EAEF179AEC83D0EE151A98B7377DF9DA -:10007000A483FB8DC0E4E948E7AA23269277FCA17C -:100080001F5829F4511510280EE0A93CCD02D1B11A -:10009000F85CD9E70AB60D12FB24C25F61A1BEDC91 -:1000A00037DCD7DB56E17883C3F984E3A948912A8A -:1000B00094B0794B6C51117D39C5300CD7C3E468CD -:1000C000D756C0AF9C6E58B31BD62F0F8016F0A129 -:1000D000D85DF2626837164F9197405B6BE476B556 -:1000E000D6C09687E3E905811FADFDC0E1D98A74CA -:1000F000BFF456FB182BE9AB0C3BC9B9586FADE404 -:100100000A50DCD4CA5C5BE15A9DEC619C8FEB1910 -:10011000F2F11B621C97D9B047057E6D747C40FCE0 -:10012000EB8A33DC9B09FDC0131FF17EBAE14A263E -:10013000F0F781273ACA15900757B6E1CA40E81F81 -:100140007AE2637E7F220C0906EAF0139F94FB6C2F -:10015000382ED7676CBB3B1BE7510C12C9A972C084 -:10016000E4AF85FFAD8BE5FC54073C82FCF786B01D -:10017000B3EB6B8A5EB602FF2B456E750D8CE3C741 -:100180008069F4DFDF6A7894AD068A53B0457CBF9E -:1001900029D6ADD18135B8B367A15EA87767CF8E78 -:1001A00041BC7A4F225EF3DBDAA7A03E6E78FBFDFE -:1001B00031E8AF22BD709CFC3688DD603D975EEB78 -:1001C000B7450E8B473F7014BEE3003996DCDC9FC9 -:1001D00094543B5B047257EB66AA09D695A28BEB4D -:1001E0001A18D72FCFDB3D7FC4F7584680EC4DA1BE -:1001F000C3FB31CEAF8F57597B7CAF7A59AFB74C29 -:10020000B90FC8E8E7C4A737BEB704F5FBEFCDAE1A -:10021000C12AC2E5660F003C3B0D4C61F1C426C308 -:1002200094028C3FA35D1B50EE5DCCE90339C330D3 -:100230008D80845FE298B0B855AC07DE2F61D08E18 -:1002400045F86EA0F5C9C857A3984746FD3586F90D -:10025000ADD87635BFE644BC3D19C5EE40BFCFB240 -:100260008DB9FD61FA63403CF7F726251809EE6861 -:1002700063FD6CE4D7E82F981DFDAAAEFF34293842 -:100280003E08C874BCEE3A6C6008E70B46BF3D0EF2 -:10029000FAC1E18AFA2C0B8DD725E8AD8DFBA44974 -:1002A0001DEE407D93C0FB2F1472FB1CFCDCE47F31 -:1002B0003613F16359E30F932F673CF75BBD494554 -:1002C000F1F1D0D63747339C7F6C4BB401E9F0F2A3 -:1002D000F6BC28E4879D881B587FBCD97E0F8E17FB -:1002E0007F05E0CDA4EB6EC2ABA28E8A03BC4E9814 -:1002F00066533700DE5F88AA9F86FC1FDC6160CFF3 -:10030000C2143B4DAE59D8DF7959B5A3BE7D21B398 -:100310003E9AD6B3C340EBD9191D1CB116E0DE30AE -:100320004C2947F8142B53500F2B8622F51EB83E4C -:10033000349EDB574D2F2F88E7F2F3A404F3E7E157 -:100340007385243FA5B28DE4AE2BC8FC669827695F -:100350006EBB8CF4889E05AC847CAF046406FD49BA -:100360001E46498D4936A35F257DEBB62D06BA4F53 -:1003700011FA76CA87AB2B78DCE33A3D11C63B68AD -:1003800033325CD764D621A33F38F92A7305907FB6 -:10039000AEF278C60E7FE83F3DAFF3074BC578EE6F -:1003A000A0BD042F17B2483FAE7473D9E712CDA396 -:1003B0002A68A78B2DBAFBE8E7C5621B193795C5DC -:1003C0000BFFA63FEBFF1DE937E05E98EF3E3B9F3A -:1003D000AF54CEF915AEAFABDCE4423CECB2B9DFC2 -:1003E0009D887AB1DDC8B6B2BEE5E979883FFDE007 -:1003F000730CBB6A65FE7CE2471BAE67C4E68DBE2C -:100400002858F788417C7CE43BD42343FF333101F7 -:10041000F5F855A15FB456E333E4277B1CE727FBCF -:100420000D2139BC333E939ED3E40AF90CC7D96F32 -:10043000F42FF4F46227813FEF44FEDC6563144738 -:100440003D966A598072A5CDF3BCE0637DBBBE6664 -:100450006DAB11D7FD15D80380BB24EDAA29DC9E16 -:10046000EF49E27C552A7F4BFE766793C4D0CF4F8D -:100470006EE2FA3B9C3F527BE78F5F225EAFC51F67 -:100480005ABCB0FB87F2C791BF8F3F365C933FBE2B -:100490008D453CDCD75C9CC2BEC7BF6914FCD0D77D -:1004A000FDF156AEE7F4D75F1178DD67DA383D1716 -:1004B000F5C0CD0617CA39503F7D36AC635F347F37 -:1004C0008F296BB2B0BF4BE17A65579399F4CA2E6E -:1004D0009BD74B76DC6961E83F30C5DBF133D487CD -:1004E0006916754318FF2E8DE7FC566F0C8CFF0CB8 -:1004F000FDE2A39CCEE36ECE934DF05CEA522EE774 -:1005000005174C5B300E2B4D28DC817C7402751670 -:10051000B4D5E7E029407CD53913E9BBD75A4E96CC -:10052000617E11FC1E37F2D9D8FD27CB8A72F07993 -:10053000AE4FF78A56EB8FC735C5B3EE78D723ECAD -:10054000C678C6F59207F92437D4676E23C56B1AAF -:100550003FD447033F805CCC67AA3116869C73CE9C -:10056000F330984336A73C92CEF303D3283E9C7BCE -:10057000BAFD55D0CC6C9E47775FF0C17C1D1F80C3 -:100580009D3D1E8FFED2F180C980F399D664737FA2 -:10059000684D16F293264FF4033CD5FF61D8B31B88 -:1005A000C2EC7B6C0297A3C75D0ADDF77598FC83EC -:1005B000E1D2BF33FE5EBDB03F9FA33C63FC70DF62 -:1005C0002B0BD18EE62F771F44FC4F4F92E9FA2F69 -:1005D00058C09285F47129E497D51BD5E2CFA4D0F9 -:1005E000734CF10CB3C1FDFD49D1F9387F6982F735 -:1005F00022D28929C123F8DED80979F9285FB651BA -:100600007509688F34B801AEF2ADB6101C1A5C677C -:10061000055F94262CBE88EBC7F750BF347E7CDE86 -:1006200082EF6B74AF6FFE82D33B8CFE48EF10FD00 -:10063000A53BB0AFE1E12BA157B4FE3F4A7F2D7F30 -:10064000704DFA637E20F6EFA2BF352129447FF07A -:10065000B3E2B1AFF7B3EA4DE077E7F4BC5EE82868 -:10066000A4E75D265821FA552D1077A23C7A1DB4D7 -:100670002FB0C7CEE7EAFAC3F9FEE022B2C109F112 -:1006800084F76A537008FA21A30212F985A340F097 -:100690001791FF95417ACF25F0C4CE4BD2F961DC9A -:1006A00045FF2E1DFDC34002FA51A3CC1501E4F70E -:1006B000DDD629E9E8D7E5592765215FBD3AECBECB -:1006C000E368825E4D5BBEE73935E4FF68FAEDA072 -:1006D00018569BBF2081EBA11B41DDA21F882E6312 -:1006E000381C9A3E47F2201C5260BEE13B2BE9E5E4 -:1006F000A60EA0C78D0807E0A155620DA8CF0B0D6F -:10070000EEC462F4D392020AF7F7BEE98FF9C18A08 -:10071000A637DE43782B703F04E35097F162773EB3 -:1007200062604F3F58F357B4B840F367B4F813FD15 -:100730001EBC3F405CB79B0140B447018BBF06E63F -:100740007FF2B23ADC2DE4568175548875CC64EDA5 -:100750000417FBF6BBEF26017D66087C541C81B8AC -:100760003117EF337633E0E16685C79337BB207EE0 -:100770000CE3A399E322FBF89B921C1AE75ACFEBF8 -:10078000EDC044DDFECC3FDA1E017BF409B8CEC7D4 -:10079000D6F1B874C240D9A7A0E11C9769407EACDD -:1007A00016F60DC2E85EEDD24BC22F9E60E8C8750A -:1007B000017E5BF7FF8DECE081FD7F7B07FDBCF1E7 -:1007C0009F2BCC0CEF4FF8BC200EF5041BA7125F3B -:1007D00069E356FFA9C1CAF875E2FF2AB1F6C30062 -:1007E0008F7B28C267A1F677179FDC84E37D794E63 -:1007F000E1BC2DE62F337907611EBBCCC4F3018722 -:1008000025EEFF68F70F1B016EB8BE2941CB0BB474 -:1008100093DDC79F398CCE37633E202F44D79B2F63 -:10082000947FAEE4F6A40FFEFE37F2015A1E60ABD1 -:10083000C01F3B78D6A4025C531BEE51D0BF9EEA8A -:1008400094993B6CDE9B542B7387E5039E49D0F94A -:1008500023075FDC3403EC49759BEC8A42796DDA3F -:10086000753C17FBEDB2CBDA0B1FE9F13BB5E91E86 -:1008700005F9DF98A8927C5F6BFE0923804F6E40DC -:10088000BA33F2EB3AC74824477AFA1ED8FFEB8412 -:100890008E9CBEF1DD17FDF574F8DDC522DAEFB9E7 -:1008A000163DF47CDB02EBF4C1FA02B04E1FF85D9A -:1008B00007D6D9A97F689D93FA1ABF5637FF36012C -:1008C000FD368D4F4B1338DF8CDFB72981D942F4C9 -:1008D000D2F0F5A1B0577BA3347FC3356F065C3AE5 -:1008E00005768718D4C7DA9D6342F66BFEE932F2CB -:1008F0003734FB355F5E544A6A53D82F4C23A35ECE -:10090000D3DBA9B9EA6223EBCD3E2D88EC97B76D16 -:100910005462A867203A4992C087F0B33538CE3088 -:100920000FC1A9A7A706971E1E6D7D9A7F3D5FD0B8 -:100930006FCEA04C23C2DFC3AE8A75E2409887B861 -:100940005EBBFAB58E9FAF5C28792BB717BEED8BD7 -:100950007FF5F7357D508613E451EB43BFC298987D -:100960004C742BBB6A626EB01B2C238A7D1A6657AF -:1009700058C550E29F7B851DEE8B7FAAAECACC9BEB -:100980001FE22363E31356E4A37DCA462BE6272721 -:10099000DB66D5C6019E4AFE543417FDBCEA0E0341 -:1009A000C3145669D3170731AEAF7E8FB9502F16D7 -:1009B00035B51623DF1D52DA658AB3BF64EC893082 -:1009C0007FB1B1A9D68AFE5463A24C71FC6107E7DE -:1009D0004BEDFE9644AE3F1ACF5D9EE1EEE5FE196B -:1009E00071BFE4E33CE2A3B24741AE310E4D8AA1B0 -:1009F000BC4489649F53817EC84D46F2F3218EF931 -:100A000023EE035E6A34EFC2D47E69E323F7D88114 -:100A100010F5FFFD698D19F30BB324D7B3F05C9982 -:100A20001A6CC57ED9DC4CAA7B18FB3F32F9B3C1E6 -:100A30005B25CA8B9401BB60BF6C51A61FF313FBEF -:100A400025DEF735F37D0266F725CC8079DEAE48EA -:100A500018B581784AEB0FCEDBC0042387C557F762 -:100A6000ED9549CFDC572AF971BFA9D49ECE7C61A0 -:100A70007C55F6A889D635BB29A508F9784EB9CC9E -:100A8000FC61FC1D107EE13C0FC4E161EF1D8EE2B4 -:100A900070051703DC52486EA7093E9FC5B89F3802 -:100AA0007F4142C47BF0C62D688F6E6D8238157A07 -:100AB000D344FC7AAB373D625E0FE37ECD09162C42 -:100AC0008983F1FB250D24FE9B11B48F0EA8A87716 -:100AD000CE24A25E63C3B89C6872572AAFAE237E51 -:100AE00070F27DB2791248938CFA2F529E668E8BEB -:100AF000ECCF72F7A83788907FBD5ED7E47E5EB3F7 -:100B00004CFB72F30A2517EB453FE8FDECB1D17DB4 -:100B1000E8856FD587E37AD30B1F96FF5D7AE135C1 -:100B2000082BC681FCFE3451E8877EAC1FEA875251 -:100B300079FB26E4972EB077E65EF845B3175A3C6A -:100B40005E06F24AF27E91EF67945E4D65BEFC5000 -:100B50003CDEAD2FC09F70F5E2E73C9D984572D416 -:100B6000AD5F34FD11E64F18C7FCE3FE4429F89150 -:100B7000A63C842F83E02B633C1F588685439897BF -:100B8000737E41F9966A88F329DE67BF25B850CF96 -:100B900049F12139D0FB195A5ED72AF2087ABEE80A -:100BA000CEF3CD35521D8CC61765762E1F65736545 -:100BB000CABBEBF9449B4FCF1F015D5EE69AFC2157 -:100BC000E4EC87F24773A2D8571DC4065D0F5F6837 -:100BD000FCA0F187DE8E1CD3E567FAB2236FA21D5D -:100BE00019DDB71D797D9891F4B5DE7E68F6E27760 -:100BF000495C2F6724F27D8E69C3E7D9D0EFB02618 -:100C0000F13A0DCD0E75E79736737E78BD63892274 -:100C1000A13D41BD9019867F916FD5F8AFEA51890A -:100C2000F28D15422F7536F3FC5B7589ECB7C0FF6A -:100C300016373DB189F78D949F2B545A150B8C3B79 -:100C4000D325B930AFE316F9BA196E89E7EB5C9199 -:100C5000FBF42D3AFACE117C349305EBD01FD7EB81 -:100C6000A53957B95FA0D74F73C4BEFB1CDDBEFBCF -:100C7000554DDE07B001FF4C7FC09CF4FDFE80F6B1 -:100C8000BE46478D7E2AEEC5A11C1DFCC6A4C670BB -:100C9000FF19E937F5AA42E3D893045F0A7FE6CB50 -:100CA0008B79BFA0984F3C5FDDF485C93BB26FF8EC -:100CB000AFE5B7C6A29F3E3AE4B76BF34E53184B6D -:100CC00047C74C674F6689EB3FD47E0CD7AD43A333 -:100CD00083A6477BE059E8D9BEE8742D3DABE9B364 -:100CE0007FB69ED5C6D7EC8036AF5EFFF615B769E6 -:100CF000FA74FD1603E54B268BF878B2C8C3CE4FC5 -:100D0000E2F1C1AD493CEEECFACA62407BB9B38571 -:100D1000FB272EB3FD38FA05A17C1FA7E7C331CC12 -:100D200087FBEC4C69B7D0BE67119012F73DD3F842 -:100D3000BEE77625E0213DED52580DC8C9397C0F3C -:100D4000E679F8806F21EAE9873F1962A0FD7725EF -:100D5000D08EFEC9D83C85F68F1C6695F2C19DCD1C -:100D6000663BBED7B5EFFFB41A719CAF980B43B882 -:100D700043CDE6EEFD1BD407A5729B8CF9FBAE209C -:100D8000C8083C3F6941A018E3A0C9ACBD16E57B8B -:100D900002D2B117FAFD2A498BB37BCFEF17377315 -:100DA0003FAE3846263F6E8AAFBD18F7ADA62892F3 -:100DB000AB169FD5E5F75FD1C51FA1FCBEAAF0FA1F -:100DC000435DFEBE91EB99EBCDEB4F40DD067CBC65 -:100DD0005EE373A16F581FF9FD9D26BEEF133C69BA -:100DE00064E807B30B89BDE663AE95E7DFD712ED84 -:100DF0005663719F8EFBEBFB5AD2DC6A6EDFCFE746 -:100E000076048BD03CEEDC3E5BA1FA35911FEDB150 -:100E10007FD2C7FE88BBD17E08D5695FFB21C55F45 -:100E2000AA94F6B95EBC69750B4CD43FDDC8B49F7B -:100E30009BE474E7F96837F2F9CEF3696E84EB79D5 -:100E4000C1A71ADFEF3B77399AF6414D6E15F78F40 -:100E5000830E8BEB59E25BCEEFF5A943FCB84FFB59 -:100E60001B21173BA383C7B213C3F73DF83E47CB03 -:100E7000BA47679F33D27EB984F9486D7FD907722C -:100E800043753DF18CE20F23AB67386FAD9BFD1AC4 -:100E9000DB2993D438C4FBE5446D1F538DA33CC4B8 -:100EA000B757A8CE508FFFDDEB9807EB511AD659F4 -:100EB0003C0AC8FFABEBECD46F5CE7A476FF3A9535 -:100EC000DA878EC73E8076BFDA6DF22861FAE39D3D -:100ED00064EE77E5657F524CC5DF7F6354873EE55E -:100EE000C10E19F5C58D57611D117527CA65C43727 -:100EF000E537B342FD4C69710CF66FBC0AFDB0E7F3 -:100F0000AF2439B83DAA53EA462793B4105FFC2DAD -:100F1000C9DD9104D7EF71783EC176B734FFE02583 -:100F200046FD73BC7FAB7C099ECB0F14525E391F0C -:100F3000F3CA7934EC42C4DFE85613ED976BF9DD60 -:100F40003C4DFEBE8ECC33E78BBCEEABAC83F2CD1A -:100F5000051608B40C0817A79F5B9AE794301F98F2 -:100F6000647261BDC3E82C4F3EE6635B9318C547CE -:100F7000ADADC9196A0E720FCFFBBAB5BC2FFBFE1F -:100F8000BCEF918F627DA4B7AE9A687FFAC8A9586A -:100F90005780F60B2DE4FF69F5C82DD1BCCE8065D6 -:100FA0002CA03CD38DA29ED162F69A93495F050E88 -:100FB0009E80F77E7F99F17DC7F60F695FBBD830C1 -:100FC0003C05EB7E0F4A43E3B07DEAA3D81C6A4F91 -:100FD000C55E44FCB418AC2ACE7B669D5A82756D02 -:100FE00027D6B112AC637B6B9D85DA93EBECD49E74 -:100FF0005AE7A4F675B88EFC731C9E477E71BF65D8 -:10100000A37D92296FD9146CF316C650BBFBB6189A -:1010100013C2DB12CBB66BF360BD5A203AD080C945 -:10102000FED6A7BC8F59FA81DD337B474AA3186BE4 -:101030007BCA3B5D990CE34EEDFF93AFE0FE9BC98D -:10104000CB1EB3005C734FD91ADAA0FF76F2F2C759 -:101050006CA86F8F4783D2C3F5AE38EE1E0474437D -:10106000A590C605978D837E82D65F31BD641263DD -:10107000B71477643360ADECE495D32D80C75BACD7 -:10108000DE1F63DFE44B9A5ED20FFBCC87F5604135 -:10109000C948713FCB9012B1FE65A6C3FB4672589A -:1010A000FD9E5BFA13ED338D714BCC41871F8CB4E1 -:1010B000EFC5EC1F2784CBDB4C47E91B488F89C960 -:1010C000BC0E78F424C91D5E5FA17F6EF439B504AF -:1010D000E934E642591DB633CB1DD4F72C185B8793 -:1010E000F25C62EBEBFD627ABF3C99D78D1429521A -:1010F000445D89FEB97C6026F48F8347A3294F3075 -:10110000FAB4B716EB4F4B9D9979B2A6FAA8EFD86F -:1011100082FB6DA32BCE9424A0FCD824179A89318E -:10112000ACA32E01EE17DAB1A00AD7F54431D6FFF1 -:101130008C562517A2ADD0DDDA80EF17BA625C8538 -:10114000E88F9F564BD0F49C52469D2880E7A60E10 -:10115000925D1618E854E0A68997A05F382C8EF2AD -:10116000BC85CA9A2B27A81FE3AA51711D5B7E5D1F -:1011700045E398C9AEEF9E51FC2FC83F459E38CA43 -:1011800009023E4AC2EBCA60DD0477A15DF6474919 -:10119000C8DFFF5A6287FEEEFE1296CBC37CC3FF08 -:1011A00042F78F44AB5100E86E93BD04C7DB6D92EC -:1011B000EC0F51DF538CCFFB861855CC1F9525467D -:1011C000458C3FB5441A7F0EE1CF891B85D7CA33C2 -:1011D0001C11F7DB6EB3929DA8782B87FCA2B6DBBF -:1011E000D2C95E54BC35A908DB3603F7D32BDEAA7F -:1011F00028A7FB061E07572CFC915BF429EEAD587F -:101200005849FD5629E52738DF959CB83CCCAF4DB1 -:101210001B945AA244F8810349FEF3447EAFD030B8 -:101220007CD32480FFDEA37C9FA2222733E2F9191E -:1012300005524978FDA8675254447F7689A324BC9F -:101240000E756E456A44FF96B99911FD92A3056427 -:10125000BF410F5494801E380AED5260C1025107FD -:10126000A5E59F0A054B15B68BBCACC2E3EB61F05C -:10127000877AB0C41669A77747733B5FCED6D0068E -:1012800049F911BEBF5D9668FC24DC4E94CB15363F -:101290005E97158987BCA346B2977931921FE3FA0E -:1012A00092A34BEBD0F4966744BEAFF961E5023EE2 -:1012B0006D5EE673B7A33FA2C1ADCDAFC15F2E2F68 -:1012C0002AA17CF735D6A18797C17A503FE8E1681B -:1012D0004A16FE1AF81FE4AF897324F04BECCD7E5A -:1012E0006BFE7A05E82B47B8BEB2498958B7D79745 -:1012F000BED2C6EDCB2FD3C69DE9F0D0FBEE1D9F2D -:101300009E9A2087F5333F4E880FEFBFF8E9A688F5 -:10131000FB491FCF7184F7B77E3A07EF4F51D45A7C -:101320001BF0E53126B97CC8076DAA1203F4283EEC -:10133000EDAEC3B6F4432F96ABB2A9E77C75D84E99 -:10134000BCE86F33C3BA6E1A26AB18BF6B7E881E1B -:10135000DEBF26F3BCC3B1ABAA15F75977FB542BFC -:10136000FAF3BB1F54ADE887EC76F37319EE2C0348 -:101370009D8F7167F37AC5BF24F3BA834EF1BED651 -:10138000FA8DDE4E841BEBCCD137A8FA264875E5E2 -:10139000C7D0BFCAE9E95F1D53FC369CEFD8837EF6 -:1013A0005BF87EE2F5FA577F041E43380A99E40998 -:1013B000D723C596284FB8DC96DA1D11FD93C20FCE -:1013C00099EA4C8D78EF263533E239F01B87A15F1F -:1013D000526B62546FEB33F07A5B3D1E57A4F0F80A -:1013E000CE65B3A33B83FB66726FE7915CC5865EF7 -:1013F000CFB7A5A4707FF03F5218C1352B85C3A786 -:10140000AFAFD5F76BF17C0FE293B99CC8E72EAB79 -:10141000E10AB8BCACE0E927A6535D6DBEE1DE2C65 -:10142000E8573CBD753AAFAB35ECC13ADB194F3FDD -:10143000CFEFDF60C837823FB0CDF7C274AC2BAFBF -:101440008AE2F5095551A23EB46E7444DCA3183EFD -:101450007E6A21C69FFB8D0CF3FC8F99C00EE6853A -:10146000F6D9AD661EAF5A4DBC0E7C7DE6A9F5A837 -:101470003F3E8BF2E6A5509EB148453C5EB45BA86A -:101480003EF4BE7DA529C807B35278DE2B7BCF443E -:10149000279D2FFBE7C151FC7D7060FD308E73717D -:1014A0007736F9E5D903189D27D1E801E1335D8F3F -:1014B00082F081CE6330B713F36FB50E138D332BEB -:1014C00085F3E3F5B63DEA89E30C6B7641BB2085F5 -:1014D000C7CDB7E2BC046FB0FF2CDCD0B307FBCFA5 -:1014E0001EC9FB486F59CE0BA27F1BFC510CEDC3EC -:1014F000BC1FCDF1C63282B46FF3EEA26CD706BA30 -:10150000CEF1B8C03FB0B643C5FA0F7F3FACB718B5 -:10151000E8F42E457CDC66F60F26BEB2AD89C179B3 -:10152000AEB7DEB8EFF921E0047B327F3CA79736F7 -:101530003FE0D882747C579C3BD1E001387E8C70B0 -:10154000687075C3A3AB3FEF147E7B278E971BCAD1 -:101550005357FFC940798A6A09F424F4F77CC85CC0 -:101560003E95E8437950DCD2C2F9C69F58526C834D -:10157000B6A071158F8FDB9588BC9866CF268AE759 -:10158000C7BEA744D8A38922FE1DAFCB4F4E6C9C8B -:101590004EE7F826EAE2E25FA488BC651A4B0BCF5F -:1015A00023AC15F1C6E5B68171E89F2A10E7CA8021 -:1015B0006F932AB371F121BDD0B08E459C53D4F8FE -:1015C00070E469FB9D38DFC8D3EC0EF207B471BB41 -:1015D000F3131C2F97DFE37819D531ECE949D037A5 -:1015E0001E3132BF1A5AE7040E2A833087E2A4CB99 -:1015F000176C645FC61C9D43F5DE66A781A961EB8D -:101600008F52A3991AA62FADC3E223FAB2A04F5D61 -:1016100054A41F902FE68971A5458CB73FBEEC08F6 -:10162000FA05F9B6E5E417C48D1B18311E6B532279 -:10163000FC833CE67163DCE802FAE27ED998D34A87 -:10164000841F302EB091CEA18EFB30F2FA847391BC -:10165000FD037DD1A52FFCB1DCA7D12FFCA1F87330 -:10166000B823F197501E89BF244F24FE521644E23E -:1016700027D51B898FF4E52322EEF75B9317D11F43 -:10168000F0C08488E733C18085F7B31E9D16F1FC56 -:10169000E08DB323FA4337DF16F1FC70FF9288FB2D -:1016A000D9DB56FE207A8FAC5F1BF1BC9EDE37344F -:1016B000FE34627C8DDE3EF8FBDFA437730AFF50F8 -:1016C000D03B51D859879BD7AD75196D8FE2797C86 -:1016D0003C3682FACE81E7E963D1FEAB5497E79BB3 -:1016E000C6685FFB97B24742BD940EA8356451BDF2 -:1016F0003CD5F5FDDC6088D867B73BB93F647772AD -:101700003DFE6B133F2F950EFE26D929030BC5D93D -:1017100016AC77648299AC8F639C5DE7E818A63AB3 -:10172000306F07FDC921BDAAE9D1DBCC6A6D07E89E -:10173000975132D793A03FFB39619EF7A5078DDC07 -:10174000FFF019D1FF48B7305F6C1ED919CA433B6F -:1017500058A284E700E2427A5CFD0E887570653617 -:101760009DC37A134140BF5975D17ED3AD9A9E5A1D -:101770003E9CF4D4655BA4FF767969165D3F7BBB24 -:1017800099EA07CE8A3A470D0FFAF3D6DA396CEDAB -:10179000FEF22D9B62D0EF3C2BCEFF6AD7270BFCCD -:1017A0004D76CAC2FE59D6603E6C1118F138C07B26 -:1017B000E5918ED8DB18F99B9370DD555BAEDCFEAE -:1017C0002AF4AB0DC1646E377CF4DEFC77F9B9EE18 -:1017D000F97F8BFCAE408593C7F91562FC5BA0B125 -:1017E000039E6E013A38B07D635219F2275CA7F36D -:1017F00071338F3023CAF32C6F26D54D9C62AE33E4 -:101800007B01C4F94E95E09CCB3C46CC5BBD737B21 -:10181000650C3ED73D9E360E300CFA25EF3A7CC65D -:1018200064CC1B4CE67513309F05AF7B16A53F8C2F -:1018300076499BEF1DE6BD7406E83B9BB9685C6D7D -:101840007C86E9F9303DB57BF9AA8F1260BEB547B9 -:101850000D948F58DB6CA678AD6BE57FED780AEEC2 -:10186000DF91DED10FEDF6FB2BFF3604F9E1D6CD8B -:10187000325381DEAADD7BA7336C5FE5ECD22B31DE -:10188000781FECEED6A7D058BE6CA63AE2F757BE4A -:101890003C24DC8FAD74162EC7F7D8B8EB3BEF585D -:1018A000FCD2F014AAF712FCB442F0D3DA178792F4 -:1018B000BFB536A69B9F787F2BAF1BD1D67146F064 -:1018C000E3CA97BE89F8CEC46EE023D5CCF7C5D461 -:1018D000A160EFDB2EE7D2771F8CDE7F75C2BC2DB7 -:1018E000573F89C5FE9E37FF4AF0B3B9D7072FCAC5 -:1018F000A26F4C687F5A3BEFB9A029211FE90E72F5 -:10190000B601C7BFED772F5EFA00F1D3FCF2D69F88 -:10191000E133D779FE7397967714F6C625F001F672 -:1019200086E28B2E16CDCF9308FF46C11DF92CFA07 -:101930009E874A7CED66C7711FA7B6D5407526B154 -:10194000B8091496AF8B950D9A51725B9CA0AF8528 -:101950009EF97FCEDB2AEAA83E20D21F2A38B43275 -:10196000C20FF2C05FAF7ED033DE5ACC2FE9FDA1AB -:10197000F101C36253DCF7F84587A6F5EA17414049 -:10198000ED96C688AD21F835E8F4F37E2157F53899 -:1019900016E6FF03D1FCFC33980EF47B7F9ACAF560 -:1019A000B72D83F1F36952E7300BE8CB16E7A2C7F6 -:1019B0001F856B96417CDDD8AFA53335F9C47FDD3B -:1019C0007ED7A111A4B7D8B7301BE243E43DF4742D -:1019D0002BC0F3ECF9617227DE0F1CFE6B2CE67D49 -:1019E00077C4AB6F213D824765DAFF89523A4C8E4E -:1019F0005EE2BB57510F029FCAA9DC1E581A797EBE -:101A0000D1A2BA19C60F5176FBA8F0737F8D4E1E76 -:101A10004F561E7EBFBF09E871C9D0169B03E3AFC6 -:101A2000DEBB3B16DDFF0C93F703E4C35567DF1EF7 -:101A300063A7FCCD96FE180FD607F87730462ACC60 -:101A4000A7E4F584A37A332C2601CFE927503BB2D3 -:101A5000297F19F2597580AF13C7C642BEE18D12B6 -:101A6000F53B1B6BE371BCEADF37A7A13CBD9CC40F -:101A7000E3CD97AE66F3F715A6E0F341A74310D385 -:101A80006FC0F8E46511D7745E95E9396DFE918DEC -:101A900085B21DF82127B0F100C5514D6615E91A30 -:101AA000F51CE378688A22B9AF6E99CAD0EE77390F -:101AB000984B82FB3BA2837FA4F36ECD6615F3ADFA -:101AC00051F68D2C1EC6DF21F659870347E179298F -:101AD000EDBA365F54D3D31873203F50DE374AD95E -:101AE000C826DBC2F11C437876A4723EDA111D30A1 -:101AF000609E253898B16709AE109C8CE6D5E01C35 -:101B0000EEC7F3843B4CC1F3786E06E0B223FD8749 -:101B1000330E276B1AAA629E20CAEEA67544D955C9 -:101B2000974FEA0957752EF3A35DFFF943AC5B6E3F -:101B3000518EABA3437D0BC8C08E814CC8F9CF1F1B -:101B40002FC908EF836219177A7FC8AF363E5E3718 -:101B500089E2099F8CF12FB431F1B84E95D6A76078 -:101B60008A298FE301F7DBAD167EBFFB79E06F1B9F -:101B7000F66DFC39579CDD3A4D2239E1F5B8421F2C -:101B8000DC2705CEDF08A4FD2A702057055856BF74 -:101B9000B19FF87495A1E9A99170FFEE28AF2B15BC -:101BA000E67BED43039D6BFDF38B51FE0AC0C7B08E -:101BB0007D5B92DDBDC8877EFC47DE7BE8C974A4EF -:101BC000FF3E49C53C6C973148DF37A96AFACC44DF -:101BD000F50D8D1F53DDD39BA9DE4938CFB8C61A4A -:101BE000DA8F1ECF36D27E74B6380F5EEFE4FAE39A -:101BF000F2E921CFD684E17F492A972F16F40E40CF -:101C0000B96912F2D9827E0AB47B85BFB4B7F5D622 -:101C10002C352C7F58C30EA423BE1F6287A8D5AED7 -:101C200077F9F9B9CAEC772C77B8C3F86F9190F7C8 -:101C300045A9224F96EA9D8DF0AE6AFDC414ABE231 -:101C40003999FAFE6857EAC19FB2F782976EB9D503 -:101C5000C951B51234E1F3D517F8F957A0731D9E99 -:101C60003778F99DC6118BE1FA5EC035D695FACE6C -:101C70009AA9BE72AFD1938ECFD79CF93A17F55679 -:101C8000090201F07CDDBC6A00E20DF8BE281AE50D -:101C90006B17233DA6C9670ECA27BC9F837C5F8054 -:101CA000FDE1A4877798DAF9F9D3BDFCFC29F03D72 -:101CB000C901F0BD1DFD861C3BC801BD3F94E47BFE -:101CC00047BB81CEC9FA408F0FA67ED11CECEF68CE -:101CD0002FB1937C635E3F0FE5347080C6A987D82F -:101CE000044927314FB83FD9E88C25BA69FAF1B0D9 -:101CF00093093BA1C6E17903AB2C47C845983DE465 -:101D00007D612F4FFC2AF0F82FD176B8855D10FE4B -:101D100014F3E6939EBF57D8AAB5AF4F98B91DD616 -:101D2000B9F684DC5D3F8EFE6B40F0C901E1CFA2C5 -:101D30009D5013783D0E5E1FBD99D7D58E71AF298A -:101D4000C6B3CFE3CA371EC47682A7BE18CF3E4FB4 -:101D50005AD07E909F81E6E7D91B0EDC948DFBDE86 -:101D60005D67CD0CF75D1AFE1AFCE34B8087FB5BC9 -:101D700000FFBDD825580EF11F58EC74E6EC79BF72 -:101D80004BD2F4C7A90AE4C7CE0639D40740AA80CB -:101D9000C1B1FFDBD4938FFBA09F95E67E3E15FD7E -:101DA000ED742FB55D27FF9A8CB660EF69EE47356D -:101DB00098DCD9C83F0D0323BF1FA0B54FA61A89D1 -:101DC0000E057D7CBFEB482ACF6F0EF1B1C7908F17 -:101DD000AA1A64BB1FE87EA941769BC01F3AEFF6A2 -:101DE00026E3D99C0BCC77CB44B4F3228ED4BEF738 -:101DF0007217FA2960A7EEFE65EFFB0FAB99F65B51 -:101E00006340BE5AD624B1FF001C2C7F26F2F9D5C0 -:101E1000DAF76A1AB71CC6EF88AD7C4E771FFD153E -:101E2000FA0E46A41F732455F827592C0BFD13E016 -:101E300023D20F46851D3103DFAE48F7EE437BFC0E -:101E4000B2F8BE02E85192C77D4E615744FD417021 -:101E500007AF2B1EBECD2F1BE0FD098A5F467BC559 -:101E6000A0C57D87716E6F197D87C9E73E8DFB3EEA -:101E7000CB853E5CAEF9697EBE3F026637C24FAB92 -:101E800016AB1FCFFCB5B1B8FE6D12C5CBABB645D6 -:101E9000EEA7548BF5AFDE7CF2309ABCCA7ADD7DBA -:101EA000B1FE6ADDFAB57DF3CF5323EBBFAE773FCA -:101EB000E42F46EE37BC2DC6D1EE9BD2B87EAC8265 -:101EC0006520DD56FB65BF9FFB7936FC5ED09D62C9 -:101ED0005D770AFAD33AE1B9CA6D923F803CFE7849 -:101EE000649DE95DF58BCB90AE7A3E5929D6BD7CD9 -:101EF000BB91FC55FCFE0FCA9D9E3F568AF5AFD4A0 -:101F0000ADBFCA2BE9E0E37E744FF8EA6F413A5760 -:101F10006E37B2DEE0D3E8B552E3EB3EE0D5E0D475 -:101F2000E0FEA1F0F64F13F9AD116C04D1A93CE12C -:101F3000BAE8A4F773771D1E41DF5BBB7C6420C544 -:101F4000FB1A1FE8DF2F137EF2D4CDDC6FBCD45810 -:101F50006C1D89F14C9BC125A9149FC58E04BCE45E -:101F600037CBAC02FA5D4D599BF0FB8379270AE62B -:101F700060FC9F7FC240E7EFF61C29A07DE7FCA331 -:101F80008312B228CFEDA2EFE3C038645FBBDAF270 -:101F900036E1F984AEB692021C5782E7D00FC8131F -:101FA00076A2A62DCF1A7EFE7C4C1A8FEFD73B3F30 -:101FB000FD39FAE9537719E99CC55463F04DACDB60 -:101FC000DA7344A17DF2D527963C1485F47D51A2A5 -:101FD0007DF2C3ED6B1317229F3519EDB8EFDDD5F8 -:101FE000F4E30378DFB75DA2EF5E54379766EF80C6 -:101FF0007EDE967C57F8F9B33C874AF0B1542BC586 -:10200000CF53FB19C96E5E4CB3FE16FD9F95EE2DA6 -:1020100024DF17F7EF3151DDDE0E89A1293BEC3CBF -:10202000F80AE2E3E2AB274DE88417379C34757C6D -:102030008F3F70C92FB300C5CD1B4D18C7546ED14B -:10204000FA1D26A49347F84755CF7D4CFD95E8CF60 -:10205000C37C2B9F91A97EF760F36B26E4E7AAED82 -:10206000124BC90CBBBF598AF85EC312C6F960890E -:10207000D03FAB987F7D1A3CB76A23AF5B608F4639 -:10208000D6016BFCBD42F0F7AAEDB3E8FB533DBEB1 -:102090005B8871E30DF81CE7EF659B23EFAF107CC5 -:1020A000BD42C7D73F4913FA67381B8E7CFD75A127 -:1020B0001A9703D7BF3EB972406FE7ECDB84BDD6F9 -:1020C000ECE5E58081EC8DFEB9CEC62B046775DBAF -:1020D0006513FAA7654D5F10FE2B9A5AA97EE46638 -:1020E000E65D8DF8BAB9C96A47B9AEE8E07A685AD0 -:1020F00093D9EF97F07E3DD53977B5F0BA49DF7EB9 -:1021000089FC1C4D8F69DF775C26F0B80C14787A57 -:102110001EFABB3C6EAE1271F28A615B0EE33E7B2F -:1021200095B8BFFAE8C158F40FA7B12F6E47FAC0AF -:102130007C0CE763CF44E27DBAD08BD3B773BDA8E4 -:10214000B76B5DA9D933298F09712AC2B57A7B246F -:10215000BEAB74F1F963693C3FF6820EDF15416650 -:10216000CD413854D9E5A7A7DB159CF7482ED85B9D -:10217000B4936AD6F77E87F14DE1676BFD99E21C57 -:1021800078BD7DA32D3C6E8E4AE7FEC2CAF1B20F28 -:10219000E9D51D6F0C3A98AB1A42F106C419CD6906 -:1021A000493CEEC082923732649698188A371E7185 -:1021B0006EAAC8837EF5762EF79DE3603C3C7FAD2A -:1021C00030F247ABB79BE99C6235D09FE28A267E0E -:1021D0009EC2D3249522DDC15F3F9A86FBB19852FF -:1021E0008575CF6AE47C3FABE40BE297A383F87A72 -:1021F0002F2B6A4A6FFEBBE6B7E3F93035CC7FAFD1 -:102200000239C5E7AB9A783D52C3816FFA67A29E47 -:102210006BFEAFFE8BA1FD5AD845CD2F0C825F38E7 -:1022200090FB45F4BDC9BB857C2DB3F37DBABB855E -:10223000FD61521DF17995B1FE503CFA593B78BDD4 -:1022400000DB871F8503FDF8F64B75F1B0EECE97E6 -:1022500024AA87C3F7F17B949D4BEA3F41BFFBEB78 -:102260001D16F237EF06BF654A5E4FB9D4E45BFB3B -:102270006E560D7B88FCCF87581DB595829F3B1B02 -:102280006BE9FBA09ABF42EF0FECE98F540ABEAF97 -:10229000D4F15F547A24DFD5BC1D4D7E63D751D96C -:1022A0008EFB3180AFDFA485E345F8210D07A288BE -:1022B000AE5D276D6447FE2CF8EDA2C83FD78C9326 -:1022C000090F86F1BCCD6E796D20D211F18EF5F734 -:1022D0002FB7BC36829FFBF613FE576D9323BE0FBC -:1022E0005B591FF9FDD79AB76FA3EF0855EFEF863B -:1022F0006B88293104575F7220493C8E34489171B4 -:1023000064F53ED9135E7706EBB903F551BA900731 -:10231000A6049331FF35009D0680AFA689D3D5D0A2 -:10232000CC5B98FF169E2731D2FC3DEE17F956E3A1 -:10233000FDAF33AD7CFFFAAAAF02FBF70F94A9AE55 -:10234000F3FEB7570E0DD7A30CE104BA561B83C991 -:10235000146F9E34107CD5272F270FB2A15EDA525E -:1023600082DF0F9D2EF4DFE181D6E5C8CF3E9C379A -:102370002534CECB69BC7E8FE17A9DE86DFC928FCF -:102380002BD6FB109B2DE26ACE4F39697CBD108F96 -:102390008C4BEF251EB95EBF13ECC3A98512D63353 -:1023A000293E8C87F7BCC7F5424DF3B28F90DFAB67 -:1023B000DF37539DD7FD2DCB8652BDAFD77B03FAB8 -:1023C0001B5FB7ACB881F283D24304970FE173A2CD -:1023D0005F732619EB522B9BCF2493DDDD3B7A9361 -:1023E0002F06FD97BCE9781DFC09E23FF06B88FFE2 -:1023F000F6B415687E8C15C7AD3CAA78103F95479A -:102400000B8E57A07F71A2A800D5B974A280FC984A -:102410007CF4636C21BFA65B4FA6733FA6AB358AE5 -:10242000F20B121BC8F9870D8AE09FD50DAF93BD43 -:102430005FDD2847D42F6AEFDD99AED038CB34FE6C -:10244000A997DCC41FBB78BBBA710FAD6F95B19E65 -:10245000E85DB3DDC8EFEFE0ADF67D581F8BF721E7 -:102460003E8EE325A0C334933F03F3D3C732B99F15 -:10247000AFA7C7E7E93CFF71ECAC7700F2CBB14204 -:10248000EF507B2F76C2C78A785C2B097C37F073BC -:1024900053FAE73E4B97C4774222CFB76AEDA9744F -:1024A000AE3FA7997AFF2EE06FD2B57309EC3143A6 -:1024B0000146C546FB06E1D7A7867DD761CECD464E -:1024C000F2174E31FBEB58EF3843D3B3E3B87DD569 -:1024D000E7CBE789F73C9B55BE5FA43B3F334F3BBF -:1024E000DFA43BEF364FF83BF374FECED3E9C28F47 -:1024F0001FC286A01EAC17E7EFD60E8FF287E7B398 -:10250000F4ED61B12F82E787B0AD19FE2EE57D8E27 -:10251000B59E7D85EADDCE46B1813CAF47F9EFCA75 -:102520003EF2DF35DD72393782CF34BA5C12DF8399 -:10253000D1D365B7A6AFC4BE5DB4D8B7F31BBDBBDE -:10254000519E2B2D174DBCEE3068427D56339CFBBF -:102550004D974A25DA6F0738FB9BC3F4FBA5541E41 -:102560007FDD7F8B4479D7567C1EE3AC7A89EABC49 -:102570002B03ED26E4A7210D8B1F26B9F5B1D32C33 -:10258000ECBB1A332DDC4E76D34F5B77B71D8BF740 -:10259000717D9C482D3E8F767186B083FA735143CE -:1025A000597B593AC033DF2DB9B01EA02F3ACF5E08 -:1025B00030EA7544C3F5D2BB33DDFB4E3ACA79FB32 -:1025C000E55B308F7A6CF867FDD18E56F5C1C71F79 -:1025D0000B3CEBBF2BE31AAAD6E2F7556A9DDE0E41 -:1025E000D29F866F6347301CA7E3376B25A4132364 -:1025F000FEEF4B7E3E13E37E96CEBF770FB8A77DEE -:102600009755E9BC4EEB98D19F41798A9CEBDBF75B -:10261000AAD9F7462EEAB3CED6A3B9A630BA5E5CE5 -:102620000B7A00ED4AF3C164D516CE7706E237493E -:10263000D2F84F11F632920F2F221FE6607B2676DA -:1026400010EAE35DA76207E3787B79DBCDAF4DFC51 -:102650007BF6101F0D9917130EDFC304DFA57A3E1A -:102660000E631D43E68C0CBF5FDB171F5B33888F47 -:102670003B22F8585B6F3D7ECF07E38016337DCF5A -:1026800007F3D78E3039199AC1F5CF58F1FD9EF175 -:10269000CC47DF391C2BBEE3335E6101251EF7CD2D -:1026A0000232DFF7E5E72DC6087E1EAB045AB18E75 -:1026B00062BCD8E799C0DAE9B9292C48AD9BD9E9C1 -:1026C0001C451173513BCE12988EEE544E7D3DD574 -:1026D00025069215C7798B38AFD10BDD42EB57E851 -:1026E000BB3DC49F329ED7E9FDBB2FB333B8DCD3CB -:1026F000C74590BE9718E5B9F07B6D38C9448595FC -:10270000637DD3648559A201DE5D870C24CF2D1D26 -:10271000AA1FEB535D09E2BDCF19D5E18E75737920 -:10272000459383F518DA7AF5789800E3619E6DACED -:10273000029128E13140F3DDC8F8399242A652FDFA -:10274000736946A6D0F7418AA38A218E427D6FB075 -:10275000F8081FD33354BA8FFB25B130CE848D12C5 -:102760007B0FF73FB2F87AB5F1270023E0F9C2E911 -:1027700019DC9E614AF5BD78BE8F124B05CD2576DA -:10278000FE9DA364FACED1F5E2B52B997FEF32F628 -:10279000CE60E7CF0A42FB492EFCEE516CE83B9B32 -:1027A0002EEDDF830844FE7B1077642CF911F2A331 -:1027B00056AFC7BCFCDF7DD0D7EB85D5E7B10B6149 -:1027C000E7B0B5BA926DFED92A9EF35B9068A1730B -:1027D000BF7996FEF968C7063ABD34FEFBD2F6C152 -:1027E0003498E21FED8909F1BB95B9C721BE437545 -:1027F00083FC3B50DDE7AE92199D57B49A797DE595 -:1028000063201FF81D26902E15EB68D883C5548FC2 -:10281000B9DE6171E1790933C26D0DC15D6B11DF04 -:1028200005B5F07D717D3D68ADCD40DF1DAD65D155 -:10283000740E3D29DABB2E03E0BA2FA688CE776747 -:10284000EF9CE444BF317CFD93B4F51B7AD647C2BC -:102850007A1FC9E8A51E515BA7F6EF76D805FEB42E -:1028600075DBB5734A6E25E29C92868FC7A2F9BAD2 -:102870008DB8F39F45EFAAA837F4EBFDFFDC29BC28 -:1028800016A064000000000000000000000000002E -:102890001F8B080000000000000BB3D36660F851E6 -:1028A0008FC0C19A0C0C5DD2A862B4C41D120C0C6E -:1028B0009780F80B106702EDF5926460F006E26D08 -:1028C00040BC1D88C5A518180280381088FB80FC04 -:1028D0007E204E07E224A81BB30519187281381F09 -:1028E000880B815848808141588078FB8B151918D6 -:1028F0005EAB22F85A6A0C0CC91AF4F3FF60C3816C -:10290000B6F4B5EF16D0BEE56E08BE0490BDC20D9C -:1029100055CD4A37FC66AC42935F8DC65F83477FD7 -:10292000810D2A7FAB292A7FAF3903C3072435DB0A -:102930004CF1BB051D2B00FDA788274C9730A2F258 -:102940002732A1F2F9A17C00BE1E313CA803000091 -:1029500000000000000000001F8B080000000000C5 -:10296000000BED7D0D7854D599F0B93F736726992A -:1029700099DC24433260126E7ED0A001879860B04B -:10298000586E20E147A30E082CB440262888166D07 -:10299000C49FC6DD500609BF0921E14F70D11D104B -:1029A0005DEA63FBC5565B75BB7682D646AB356880 -:1029B000D787767765A015BFBA761BD96D976EBBA2 -:1029C000F57BDFF79CCBCCBD9900FEECB7BBDFF30A -:1029D000C5C7E770EE3D3FEF79CFFB7FDE73C725BC -:1029E000FB59701A631FE31F9413731963B5A9B2DF -:1029F000C5C362D9398CE576488CD530B6B25D89CD -:102A0000CF827F1676B4BC82F5E56D6EC35DCA5881 -:102A1000FF036E7F0DD44F6F57C26EE8DAA8F8A897 -:102A2000BEACCB15761BF07CEB472FE7E3FB8D525A -:102A300098419DB1BB199BCCD81A0FFC13EACB2A45 -:102A4000921DF8FEDD2D523886AF99E99B04EF6F99 -:102A500065FC7DF3038AC664A8EFBBAD894D64ECC9 -:102A6000961E98C5430DD9C7BC3D63058C45F82318 -:102A7000D6B205DE57A6DE4758D7470AF46B8E3923 -:102A80009EEF9BF53E0BE07B2DF51CD6730CFF31C2 -:102A900085B14B993F783A1BFE1D66E18F15281BC7 -:102AA000F2191B9DC297B3640CA01FC5D85CC65C0D -:102AB000AC1CC6A9BDCCC5CA607D161EDB381E97EE -:102AC000354984C7653E46F577E74AF1074BA91FAC -:102AD0009B5E0D253C2FC88332C8CC4228231E960E -:102AE000C806F8E7B65DF61EAE7F034E359ADA27C4 -:102AF00002F07E018BBA18C0F7672C46E56216A774 -:102B0000F2CB2C41702C6543252AD4EF52129B182E -:102B1000CC130E45A7E3FEFEAEFED8BB12BCBFBF72 -:102B20005AAA9D0225F3E5D1BA2FB43E6B7E954596 -:102B3000AEC37118935D113F63E3AD751E66B18A34 -:102B400020637A8F8FD3CB61D6CFA03EBE41D04BCE -:102B5000E3FB7208D6DDF33C0B633D049B3905EAC9 -:102B6000A1AEACF806A8F73C1EAB47BC1C6B01CC71 -:102B700043FF638D6E295A05A54B7745A00CA98CA0 -:102B80002980A7FA86F59202EDE646F938E34D4D25 -:102B9000665742FD704C52C573ECAFEB314987FA72 -:102BA00078A83F28E17BDDC5609C86865C57B20A29 -:102BB000F1DD334687B2E2B0969001BFF5A64ECF65 -:102BC000195B4474355ED0DA5C93F79B7B38CFCFCA -:102BD000E83DFBD3C7D67BC0EF25457CDF8E1D2E9D -:102BE000CB417859D4DEBF4865314F5E0ACF3BD721 -:102BF000C10B770ABFBB0E976D45BC1DEB53C3825B -:102C0000946DE3C3B8BD0DF0FE4C951C560CE4B3B7 -:102C1000220E7F85EED77DA97176AE83F697A5E06B -:102C20006854A6F6133E4C46FC38B706DA57A5DAC8 -:102C30003F81ED018E3D080FF55B73D48BF3441893 -:102C4000CD33123DBCB04EA77E83621DD7FCEF3062 -:102C5000EDD3DC861689CF2BE06BB0C36795167C6D -:102C6000238D7F4CC0658D6FCDF7C4BA10958D4A0A -:102C7000D523F7E2BA8E687C5DF38DC77723FE8E8D -:102C800078C231A83F79DDDF8CB91786B862FAF3D4 -:102C9000973FC370BEE50FDF8EEB7A2E8BD6F5D44F -:102CA00087675EBB910D9FF72D81879F9E9B3F4459 -:102CB000756BFEB9A63446023AAB34A5840BE8E541 -:102CC00058FD571EBED7C07ABF89F2A4D23C664ACF -:102CD000504E846168BF99FAA78F419E554277E4B0 -:102CE000C7490D520BB67BE2C687BE741F3CFAA9DA -:102CF0008BC37DC55F72B82FBB7EED9308EF653740 -:102D0000AEFDF93350BF028520F0DDA537ED5FF34E -:102D100077F0CF6F2CFCCBE57B18C9855836C09176 -:102D20006B4A0CF777D9F7DD36B972EC793FC99564 -:102D300042B33486FCB7AC4F22F9DCDFE866417C55 -:102D4000FF3377DC8DFCF5806452FB67DD71940FF7 -:102D5000C75C8CA13C5E76DC1B477E61AB9691BC68 -:102D60008E58F2DACC5F7A2F8CF76E8325CF399D9F -:102D7000D27B58DFBBE62FB65F0DFDCF98AE308A11 -:102D80004D4B5E38F1FCAEC06FA4BE9CE860999AD2 -:102D9000748533D043739B6293DBF50D2789AE9620 -:102DA00041C9D2F874AEE0B3650DBF10FCA9935CC5 -:102DB00072C2F3466D617126BA3B25E0490A7A7BFF -:102DC00017F7FB32840F7A21DD742971254D4EC32C -:102DD0009F2B3281EA3164E95BB6D8E1B4E4764BEB -:102DE0002CDBA6AF40FEFE0BCACDE6B67CDBF3B90A -:102DF00039AC76EAA793C37F20399C94081ED0BFD4 -:102E0000B4FF91B81447B968EDCF1D627F22158CCD -:102E1000D6F3AB03523C06FBFBAB23627DFBA4B8AD -:102E20002211BD9AA73D382ECC599EDAFFDBC5FE94 -:102E3000A7F68FE3C7C2574ACFE56E4A02082DBEF8 -:102E40004809CA6B8B7F2CFCF6EFF95109EE5F61E4 -:102E50005B69771DC2794021FEFDB0FE6431EEDB77 -:102E6000BB2EC02BF48F1C7E2CC07C29F85B841CED -:102E7000FCA003E8059E4B0867651A9C026E17D6F6 -:102E8000A1DDED0D521FF2E92FC5BC56BF1F6D9994 -:102E90003113F173478FC4103FB71FE95DF6E7B0F8 -:102EA000FED5F1EC304EF1ABC6E2C02500CF8A1E54 -:102EB000FB7E9EDA727300E9E6C3BEFC021CE7F6F5 -:102EC000A9090DE15C9D78553380CE6699BD5A32D3 -:102ED000035D7DD8B72180ED3F547B6EBC06E7D9FA -:102EE000A784D7C3F8AB8F94CE34399D12FDAE16AC -:102EF000F83DA9F6CC1C03F0B57CA39CE4C17B7D16 -:102F0000CAEC7806F9F97549213A58DDE696719DC3 -:102F100023D1CB871D2E96C079D404E173A4761FEC -:102F2000F4B5D0FBFE070A6F40FBEDF67617C98BB0 -:102F3000DBDBDC444FAB1BA4389352FCB642C0BB76 -:102F40007AB742EF4F9A12C90F6BBF6E17F476F241 -:102F5000F055AFA0BE3F03F207E5EE8C8D3FD42EB7 -:102F6000013CACD8C2E5D1C9DDB94BEF413922F4FF -:102F7000E51D62DCDBE28A8D3F56B667DBF623DABD -:102F8000956FAB9F3E927F631DD2759742FAF39681 -:102F90008D8F6921924F767B13396C5241CABE3CAA -:102FA000C186165C23A5E8C9A29F5BDBC0DE0C0CC2 -:102FB000B7375B8E48648F5EB49DD90676E6C4E170 -:102FC00076A6254722689F95A7E4882537EE52A26A -:102FD000638300C7AF5DD1CBF2CB496E3C20D522D5 -:102FE0009DE8BF45BB92C5945A946F172B2F68B1CB -:102FF000161FC1DF7B1D405719E87506D215CC336B -:10300000B3A73F233DCF900C1A2F4537B704886FE5 -:10301000715080A3D96376219C97C0C4DE6A2A9937 -:1030200092C74B15EA9B1166A087536BA5F8A15276 -:10303000DECE87F214E0BA069E37775D1EDF26A14A -:103040005D087FA83FDBB8DD0DED4C7F1E3D3725C9 -:10305000288BDA4B5FC6FDB904048056CDDBE33C18 -:103060006067114AA07DC25D4D5D6301288BA19F01 -:10307000CCFBD37B6C1720391EA7F5E2F8384E85C0 -:10308000125F8372C6A2E36542EE805CAD5481BEDE -:103090009A595618F566735BF979ED971BC276F964 -:1030A00071539D5D0FCC35EDF2FFE6D997D8DA2F3D -:1030B0008894DBDEFFD9A22B6CEF1747AFB2D5BFE8 -:1030C000BCEA0BB6F64B5B67D8FDA49FE6D27AD676 -:1030D00008BE1C09EED785BCFC89C33EB5CAA6EB69 -:1030E00013356FC33EB175EEF0E3509C98C316F5EF -:1030F000A5C9159F2C113E7F036CC2FD833F7D4CFB -:10310000780CF1799BFEC2DD9A89EE34D10FCD2582 -:10311000B4979CED4F2C8679D2FAFD9B24111D9E0D -:10312000EBC73C3DBF04905B80937300F577B264BE -:1031300009EE9B3BD7A0F777C9C902ACFF860DED1E -:10314000CDC7FDF5258B917F9A55F69C9483FDC2E2 -:103150001E37CC07D6106B03FA6869FBD171B4E354 -:103160002423C89660DDE34B207FB30ED787490B3D -:10317000EFC087BDA1E88712C021B5F7FF5EC2F797 -:10318000DF6706EA61962CCA45FF11A74AE7C3A686 -:1031900019AC15F175A2D18E37AF58C7CF2599DA82 -:1031A0003DC7CCDF221F9D9474BE3E01EF36C93C63 -:1031B0008BF35970BF9BAB6BECD3C1ADC8B508F7AF -:1031C0008F08EE0DAD2C99AD8C0CF715CC74CBA3FC -:1031D00086C373969959999ECF0276CDF4FC7237C7 -:1031E000AB447BF58494155E5F8AE5D03F7E0DF895 -:1031F0002AF60D5FF87163385D4C957369FE666160 -:10320000EF16B64B896CB44F9987EC57D6F390E91B -:1032100041B926445C4B9B7412D7CF3A1ACDA427F0 -:10322000B55E66482CBDDDB97D6F73537B4BDE58B0 -:1032300072CBC2A725572CF965E1D539FE48720635 -:10324000C753F310FEE824399D4E74C0C70484C7E9 -:10325000ACC6FDB3F60DDCC898A77AE47DB3E414E0 -:10326000B463E8FF8FB45F8027B2EB5C6146787A85 -:103270003738B4F42958F7401BD7D7EF1631B20FBF -:10328000CFB45D359083F8F1782A103F857C2A56BB -:10329000181C5A87F2D5A726FA11AE42A1BFBC8CE2 -:1032A000EBAF4266ECB81AFDFBF6934BB09DB53F11 -:1032B000B9627F9A617FD01F69F60D15A39DE44620 -:1032C000BD06EDDC2077512E17B6BFFF1FA8170BE8 -:1032D0001D7A112161E9706455EDB8DA481FFFA32A -:1032E0008D685F5AE35287F4FD0F6A2711BF85EDA1 -:1032F0009BEF5602B6F1A58F110F426EA3D9756EE2 -:103300009E52B457E5843B90A20B275C56BF91E8D0 -:1033100084A5CF536EAB933DE1ACBBC39A4D3EBF8A -:10332000FBC7F29C56DF79E8CD399E93BE9D7C2089 -:10333000F0F029E87413A7532E172CBEFDCFA2D3AB -:10334000A8B5AFB1DC3B8EA07EEDD2C2B30CB413F6 -:10335000867EC8ED04B77108E92C266555C2FB6866 -:10336000874A76A36557F4AFFDEB2D65F0FC44ADBD -:103370004C7EC489F59CEEF73CC0ED514B6F478500 -:10338000DE46BB00F10A76C3809B971E1CC7BFFEBA -:10339000E65209E0F61843FD6E6CDF6690BD9A5365 -:1033A00017D71BA18C571CF28C3352722919CBCF23 -:1033B0005B0EFBF5AD5C635984ECEBE8E8B9FED439 -:1033C000FB1FCB5C3F4D2B6179B361BCE45639FCEC -:1033D00020F44FBAEC7ACC2AD7285C5F26BDAC0427 -:1033E000FDE091DA0D29965ED535DA97F903C771BC -:1033F0009F46DA07D8019DE298E7E890E31DE6A131 -:10340000F1937EBB1E3A29F49005FF27D0AB0B8BBE -:10341000813EF64A99E1FE488C177D0E0080FD8EB4 -:10342000AACCCCD4CEB9EE7F10FD12B24AF3EDA8EF -:10343000D8391BF73B1653C2E9FB61957FA170FD9C -:103440009933B721B711DAB1F599DBE589768FDDCC -:1034500097B508FD2B409D8AF19A504C9F371BE38E -:103460009153F326A18FFD63D43F30EFEEC819BD11 -:10347000C5F789F051105246C6C79BB2CCF7D1C1EF -:10348000B77BC05D43F999943C147F6989B933F2E5 -:10349000B125A79CF2C8A9E724D3646DD5C3E58AFA -:1034A00035EE27D567201FB2945129BBFD9C3EBB4A -:1034B000587A1C410E94C82CDA97C13FBD5AE17866 -:1034C000EA8FF138856ACAA4B7662A4D4C023C6D72 -:1034D0000832920779B8D7C8B70D2C0E2860F92C9E -:1034E0003CE0437912945982FC56A71F6836A11F0D -:1034F00018E4A0317D54597F213C0FCE5F49E70C81 -:103500002CC2E5AD0EFF713E32495FB8055EA3B136 -:103510004914E7CC6BB2CB7137FA81201FF506C78F -:10352000F3F933E9BCC1CDD29EC33AAE52FCC1D34C -:1035300060DAB36A5683FC59BDFFAA5D8B61FC9AC1 -:10354000476E7E1BCBC907EFC9FF1294758FEFBA88 -:1035500019CB92D7A26333C553AD123885C9750014 -:103560009F8F19EE9C91DB19EB9508DAD5B08F1D72 -:10357000480FC9587916D2F72A85F37FFF022D80AC -:10358000F119750B97ABEA7C401ED13FF7D39B53E3 -:10359000FE34F915AAF093947685E20849BD8CE2D1 -:1035A0002D87B6C81A96206763388F357FAF88534A -:1035B000778A78AB13BEDE92A162948327D67F44CC -:1035C000F6A1A2678567C37C5D7E5642708878410C -:1035D000B3D8BFE4DA7A4F7ABC48117E4EC7D139EE -:1035E0000306D2C18012F61AC4371A8E1BDD329D33 -:1035F00061FC65961E66684F740ABF47F1990CF727 -:10360000355B6733D1AF85575A08FB57B17002FB62 -:10361000B7F7236E61BDE6EDC8073FB896DB2127FB -:103620004AED721B48A80BF694CD2A5AAF226D368C -:1036300005275D8534FF7BA540C8554EAF6FD44E3E -:10364000796C1BD0C1736EF31E65D427E023875CB1 -:10365000FF01B009EEDBA3925D9E5BE541271FB53C -:10366000496417AA265FE74CE5C346D4931BC16E95 -:103670002C3486F3CBC6D719D98D1B81FF62A5994F -:10368000F8A75A421971B1FC93D79E2B611CE3B382 -:10369000F2CF5F2AE29C4EF00FD05902ED984725F9 -:1036A000A3730AACEF3BFB1A7F3C055E3F7B604592 -:1036B000F635507E2FBEF1FA6B60FEDB1FDF938D77 -:1036C000FBFCE8ABC04FE7F1E32D7E6A461BF63CFE -:1036D000713663AD9D9F8CF515C44F6F295C7FF5E6 -:1036E0002FF8DD1B57FF7F7E3A1F3FBDAD007D4E9B -:1036F000FBD3D9E2E879E45B7311D3D0DE823626BE -:10370000D27934682F7D6A16E17B9D8BCB31BFCB9C -:10371000CBED8E107FEF1CEF6FD44F1E3F5850FE45 -:10372000D9F9749DCFFCE8F3E077903B246F4E8C81 -:10373000B3F37DA78BD3DDAF5C9F787DEF7CE17326 -:10374000581FD8F564DF5DA73203FD80892F7848C4 -:1037500058BC3A6EE311648969F03C94C7DFBBF34F -:10376000485EC6D18E19522AA9BFC9B81DDF54B30D -:10377000F9083F9718AC5804FEF21CF817DA23D763 -:10378000F9B85F01E3B0108CBFDA1B2D5647D17832 -:10379000E45FBEFAFCBE20CA97D73D66093E674982 -:1037A0003517CF072CBB63647E57D9E9343FEB69EB -:1037B0008D111CA72ED5285E89622C00F5ADA5972A -:1037C000529C928563C725AC8FD219CA71251859AE -:1037D0004C76489BDB9805F5AD6040C58244B72424 -:1037E0003795F6DE5000E500D825F85E8DCDF568FA -:1037F000E8BF8C923108CDDC6D1F91DF7DA298CBA4 -:10380000DB8E298CCE69061EF8B7A532DA3BED6E49 -:103810003AB700BB91F8352AE44632383DD4827E6F -:1038200046911696A0BE29F68BE35FE3F2C4F44CF2 -:103830004E8F8FF078474B88FBBB4EBB6FF3D72F73 -:103840007BD3C0F17EF85AD7E550BEFEE4CF5FBF10 -:103850001CDEBDF1ADD76A30EEEDAED36C714737EB -:1038600033DE447B0B7CA68486F2397672096E6661 -:10387000CAAF9362889F688D3F8EEB45DE46FC247D -:10388000A728FC7C11FE42005F40C0D71D3C554577 -:10389000F3C4DEFF8F4CF29EFE260B3D02ED36E7B1 -:1038A000DD1F4739929A6F12C9A728C827F423A3AE -:1038B000BE9E256B683E7FF841ECF347D8D5C9A979 -:1038C000F3C2435BE6B5209EE72EF0E84867EED8EA -:1038D000E6BB91CE9DEB3CE37BF0520CCDD9E607E5 -:1038E0003E715768A697EC5F7698F64334B1E0D600 -:1038F000418160DC01FA2F5BC132F437A03FAE1387 -:10390000E419DADB563F206313D77BC637FD528AB2 -:10391000F78B7885D5EFA69844E7043795031B9479 -:103920000FC7D3069FFC93AFE1B94B4CD1154E079F -:10393000A18A34BCE19F3D6EC6E9E2B27D76BD0B43 -:10394000F32F2CC5F73185E8C5C92FE3E3F6F61B45 -:103950007CE73FD71FBE9F1CCF1305BF59FD2DF835 -:10396000085E29537CDD7E2E73539DBD3E77183E45 -:10397000CE0FD774D57E6ED3E0B38F3733687F3FD9 -:10398000BBC85EDF80F19B4FB26E07DF3D3DC6FCDA -:103990008EFA19FC7A4BEEBEEF89FC2D8DA38619A9 -:1039A0008ED3BF60EFFC794007853AB73B0AE72F1B -:1039B0006CC8AD4139C5449E4966FBA350E87BA560 -:1039C000FD252507FD5193B74F2E796B460E9E17A7 -:1039D000D7313A4F8FAAF7C4728C943DD2AF966715 -:1039E000219E3F7F7BE46E6F7ADE4DCA1E79E055E3 -:1039F000A326833DA2DE239930CEAC25608F54A54B -:103A0000DB23AD12CAA0EC25608F90DD117D0FF194 -:103A100035925DF263CBBEF767B6ABFFA0723D0B8C -:103A20007AE69F3E8B9E19E735FF45FD1CEC8169C8 -:103A300025C6CA48063AFC40E5F10E4B7F36061310 -:103A40000A9E9D83DE545DF0FCDABAE44B288E3B7F -:103A5000F49D415C37ACC7E5AAFDF4EB39A372785D -:103A600026AA3C0F66A47EDF1AC15FF16A5E61B7C9 -:103A7000D8F7BB7FC13BBA8CFE0BF831E8BF247D81 -:103A800065DB302E7826A652BC4E9DBF72F75CA433 -:103A900027B0B3393D9FDFBEBE7648B6F1F1B4B36F -:103AA0005936BEAF67F673BA191EFB395DA36E3F78 -:103AB000A79B15B29FD3CD31ECE774D757DACFE986 -:103AC0009CF6FDCCD1AEFF9EF67DA891113F5DC066 -:103AD000BE077EBA09E969247EBA2EDFB83F92613B -:103AE000BFAB356EA7AEF6461620DD4D33B85D1779 -:103AF0008DADA77CC0BC28C89B528A1B52DCCB8AE8 -:103B00006B59712F2B2FD08A6739E35756DCCB8A3C -:103B10006349311EB76AF6445720BCCDED27659442 -:103B200023FA73300F3282758E372C3EC7E5414B36 -:103B30007BE6B89C33FE3662BB4FC9579F837E58E5 -:103B40008FEBB5F403F0F9839F85CF416E6DC3F120 -:103B5000FE05F97D14C9936EDABF0AC035DAE9B003 -:103B60000F1AC6E9179CDE8FF138F5B89BF8F6629C -:103B7000FD5F4C749061D3A2E083633C2B1A2B252C -:103B8000FD62F18DC5274EFF78187FFC57F3CF45B6 -:103B9000FAC7C03FDF739D471F017F3C8FF89E56D9 -:103BA000C9F1EBE4078BFE8124125235EE773481A4 -:103BB000ED2D7A672F864D8473A2F06B4E8CD6C89C -:103BC000BF38F1FCBFF373D8E73DE171628DF87E39 -:103BD0006277417C5B698ACF2C7E6AF7447FEC4A2E -:103BE000CB03B1F21D0F7BCCD7F17948ED4BA0BFD1 -:103BF000129ACDC21B0CE2B363FC39E7535F9851B4 -:103C0000FCF433FB657B5D713C1F6A91869632F252 -:103C10005B99867CAB0A79F26256F424E2B3797A36 -:103C2000A484D3D3D0381FC0F58B0E85FCB5CFCA82 -:103C30004FCD23E1FF1C3EA243AEDAE1F901E97268 -:103C40000BE55B28A4C5374819E495C0579C85C788 -:103C5000E0FA603FFF1DF19857C5245A8EE0E366F5 -:103C60008FF907D767B33F14AD36C5C780378F8646 -:103C700072B11AF0563E1C6F275D7CFD4EFA0BA9FF -:103C80004919E93F0472748394764E2AF062AD6755 -:103C900024F96CD169DA7943484B5FEFFFA372D9FD -:103CA0009297977BA293711FDC6644C83F93F6D727 -:103CB000296786DB41329D339E01BB07BB5DAC7C2F -:103CC0009D76D68B87256CEA5985CA6BCFD2E109E0 -:103CD000FBE2D96C2ACDB3F954D69FCDA572FAD99F -:103CE0004BA89C717634950D67011830711ACF96E8 -:103CF0005239F3EC1554CE3A3B9ECAD967AFA2763F -:103D000073CE4EA2F2BAB35FA0F2FAB353A874DA3C -:103D10003FC67A95E4B725BF2CF9EE94DF96FCFBFD -:103D2000BF26BF630D1765FF80FEFBAA761EF93D17 -:103D300092BC00BEBE4F4B971329FD7CBFF619F80D -:103D4000FAB8E053E0DFF7300EE3012F8EE2546162 -:103D50001EA70A189A81791AFBB0096CA9BF3472A0 -:103D600012E306CD0B3C7A0CE01E28D5483E6D0BC5 -:103D70006A74EEB659D2477379904C20FDED0C6908 -:103D800034DEB63F2A5ECC5F7869544100E7E9F63D -:103D9000CB3AB6FF566E72DF2D788E3F85850FC108 -:103DA000782BF6ECF1A4FBE1FBD13800F802B1A7C7 -:103DB0001903BEDE38EA774B713EDF5446F118280E -:103DC000CD4CF962DF748BF36975288478DAEA9355 -:103DD000491F74EB1E91879A1C68413FB74E66DB02 -:103DE00060DE0DA3DFD98260ABE3CA7694417D67C4 -:103DF0005D991737E9E9573E08913D01EF10142806 -:103E000013A23473607F3ABD61E37CE76D8A31B4FD -:103E10000E8915FBBBAB476EB7C93F1042FAE89855 -:103E200034B9F21698BF7752C1689C7F7BCD511B85 -:103E30003E14DD1E4F5130E0887E785D92E26A1BB1 -:103E400064634719AC2F20F2AD01CCCA485ADE8119 -:103E5000058712867570B8120A5F0F2B80E7B97557 -:103E6000895892AFD7C4B8ABCF970CA1BFA8D49D47 -:103E7000A6785BA73FB988EA0E38ACF17FAB5979D9 -:103E8000019C6F7C826F9A277D7B11E5915769B405 -:103E90006FDDAEA105588FAD75B1C733C46F36085D -:103EA0007EDE5679FEB88CEAB3C3D1EDB5FB8B1636 -:103EB0003CEF8BD20947B36B6854A6FDFBB4F35FAC -:103EC00068DD9FF77C9D23E40F5CEEB6EF4340C8AE -:103ED000F3E629DF0EE1B9B8054FA704FB50F3F96B -:103EE000EF43F3142EAF3FEFF5FE4F1BF7F71A8F9A -:103EF000AB009FCE2EC738E398C9218CD7FAAC7897 -:103F000074384EF949018C47532F83F490AAF3314A -:103F1000149525900FE5EC0F13B84F4AB566282489 -:103F20006733EFBB12DE44796D4EFEB4E0A6BFC925 -:103F3000C274A0F343AF159F36D4C9FCBE04C67F3C -:103F400015669DCFF2F8B4D55FAD90291E4D81EC7A -:103F5000B47154D0C3788EA3609C3A6FF8FCDF4DE7 -:103F6000D1A37DFE221E1F5754EE07BE27717CC4CD -:103F70005E5528DFB3EB792EDFD87146F2BBABD6A6 -:103F8000A073951DF03FFA0FB15A5F1CE95671E41A -:103F9000E39DA99C1E42396AC5C5693E7E3E4071BB -:103FA0006ECC53A4B8B9C12AF07DB700CD1A47B57D -:103FB000E2F2956B26613BBFC13CCFC1FAFC752C88 -:103FC0007109C01B74B76EBDBC34433CBC72CD37A5 -:103FD0009E8479773F35FD574F427D971C7EB50E05 -:103FE000DAE57FB98EF0EA8C876FAB944D1DE583DF -:103FF000CF7708F7156C68A28B5B7BA4183ECFF6D1 -:10400000F90EF2FD6E0D298817D0938817AF332F64 -:10401000321DDF6508C7CE8179F06FEFD679CB709E -:104020005E841BF32B57F4D66BA867824BECE71723 -:10403000FE267BDD5B658773ABD8BF0BD1BF330F2B -:10404000B1C79CB708E9F64C5063286F36AEBDFA8D -:104050004692FBDB1536AE3403FD3AD6D5A9B948F6 -:10406000FF771BF57B2B506F346894D7D31DF7C6B1 -:1040700031C57B7B5DEADCC466BF1B1A3FC7AA91D2 -:1040800013EE4C76BC381F0B8867CC710ED63D5BA7 -:1040900026BBA6BB87CF638DD75DF79607E5C448DF -:1040A000E33E3DC63CE2467B2A9A7751F72EEEDB93 -:1040B000E8E2743D458B4BA5688FEA0B17417DF311 -:1040C0003899EC2126FCBFEE6BF979E2C39A61BB0B -:1040D0005FB169CA4AB21B6E72EB82BFC02E9C9060 -:1040E000BA6F71C06BBEE086E7EA733012D803EF97 -:1040F000E5866F44BA680C7E4476D4AD45B28EF442 -:10410000B5624F23AD6BB32EB304DABD6A2B19A988 -:104110004DACD5C4F3004CD444BA9B036F64BA17BA -:10412000913CD40970CE195738691BD4DC45AD9445 -:10413000C7D26848E4875D07984179D0521C51A5E1 -:104140002AEC37FF1DB4FBE6044B65F4F7AF535977 -:104150008396669F835D7CCC9DB6AE13E3F604E543 -:104160002A9C1FE6C1F91779E83E811BEDE32B532A -:10417000F6F14444649A9DFC6B342A319E5194F8C4 -:104180003DE5797F3F29E3BCEC0556BD4DFAE47E61 -:1041900035F897BFC4FD8C33A31F530D3F6B5CE212 -:1041A000EB9AD827716FE5B027F21B1CDF8A074C0A -:1041B000D4F8FDE6CD2D2C1C4B8BAB6C7EFECF8F47 -:1041C000A3BD6AC55FCEE5DD09382DB837492C8B14 -:1041D000F4BC27FA0777BA5FCC926573277C7E70B0 -:1041E00067C897F3D5023F8D15FC93575BE145B93E -:1041F0003916F37D701FDAB93C31E1BFF47C1F45FD -:10420000305F30DCDA2F1BC3E59222EE4D015D4BAF -:1042100068C73AF38114CCFB99385C6E1C10F47FAC -:104220008947E4FF4C6693B91F6E3FBFF22FE57AD2 -:104230009FB5E665BC87FA7DA1F75F147E6542DC19 -:104240006B3C2AEE2DBEBCCE203FEF957595540EEB -:10425000AC0BD3F3D7D6D55199BA5FC5E7CD177656 -:10426000988A41353CE7F7B1B801F0FA47AD192813 -:10427000453EAFE3F7BBBB9B4E6D2927BB919F5BD0 -:104280006C2EAA4E14A2FF02B0E643DDE5EBF3F07C -:104290007B5EE6606501577388F7FFEAF30A275DE6 -:1042A000E8D6FE3BF6DBC75A19CABB8069DFEFECE4 -:1042B000B0D3BFE1FBEF2ABAB87DEFC57FC03E7E29 -:1042C000C9DAF7ABD9D5FCFB0C17278F918F2A855C -:1042D0001C1803FC7400FC79B7C2F3D5F3799EABCC -:1042E00019E2FC66AABC1E1B2FDABB3809B1813C5F -:1042F0009ED75ECCCF13A81FE695E37B0C4BBEC0C8 -:10430000E35B2C47E4BF8F15E3AC16E34EACA67B12 -:10431000BBFCFC9FF5E958FA5892EAB9C007580669 -:1043200059AB84C81CC306C9DF2E9686A86E487A8E -:1043300016D6CBA47019F7C3E3A43FCB15F3DB1556 -:1043400084FC88CCE345C9C5644F825E46B91857E2 -:10435000238B50BE6C68D3C28089737972787F0ECC -:10436000CB0D7D350378FE118BC9247F94E75896D9 -:104370007E25D97BA4BF36ACCF3B984DF91A49CAEC -:1043800073DFEF29B5E9A989BE85D7E9B05F1B4581 -:104390003E9D0BFAB30CF9A7563E1D8C5B92E9BD0E -:1043A000556EF46B8B32F9FD0F7B2411CF488EA62E -:1043B00038A0D8D7F85439E37DC67D1E6ED73C5A55 -:1043C0009AD99E66EC411A6FBF47778C9B6CA1FB14 -:1043D000333A8F6F64B94CCAAFD9D8C6EFE95BF8EE -:1043E0001B0D762DDAC31BFBE6CF46FE8E55AA9435 -:1043F0006F0EEBF721FE5C222F79E3F8E0C16C1E13 -:1044000097284539DD8FF8AB4DC35F706513E2AF78 -:10441000E3559EDF0BFADCC732E41B5AF873F9D878 -:104420001733BDB7CA8E51DAA24CF7868F7A2C3B70 -:104430003D59CAE984E32FEB5A3592A97D42E0BB8E -:10444000A48C45CF87BF7E8F6E1BD73AF755468821 -:104450007749BE04C5B9266ADCCED8B098E375C3E7 -:10446000F3D71C8FA69D43FC12879C928A075B7131 -:10447000634B6FB67BA2FFE81995D297ECFB8CE4F7 -:104480002E7BC17310F72DC339C4294F6D867388F5 -:104490009E8BFBBECB58C1B787B61C9D87F3FC55DE -:1044A0001D23FB2AF00C9F37576771B914BF536067 -:1044B0004A1867B926A2D7A3FDE66A6726E6CF8C1D -:1044C00015719BC2F63E05E922087B5928E1BDA67D -:1044D000640CBF67327637233F512D9CB96ABD21EA -:1044E00044695A7E94C286FA697DED9AF1782981F1 -:1044F000F553D40F63C4FB40FBCC5FA1DC1C1389D4 -:10450000521E2EF48BF9D1BE10782CF072BE5DDEF7 -:10451000109624681F0C26293EE994EB63003F9710 -:10452000A4D96F015167ABB89C96E13FD4F3F91160 -:10453000BBDC1EE7B8171D70E4BDE47A45BEBB25A1 -:10454000B78BF8A64E5007E54C7E794ABF3AE04358 -:1045500019569DEA1FB0EA9F113E2004A2670B1E68 -:10456000BC4A8972778F4BFFCA53A89FEB359E4791 -:1045700026EECB650BBCFBD061867603535E3171B2 -:104580005F7784F97769CE4C9D477E68769D759FED -:104590008EDF5786328671BA6C31BF75AF2E9B198C -:1045A0006F96033D649B49BA57A75BDF55305902AC -:1045B000F370749F4C7974BA2F42F2A9678147C790 -:1045C000EF7C68E29E9E4BDC1FCF364FD3FDBAECEA -:1045D00061EBE3F7EB2CB8B3B3AADE2C376CF3AC8A -:1045E000C7F836AC7D74C6FB7575DC4FCA36791CCE -:1045F000226D7CBA5FB7636A99ED7E1DCD837E9C88 -:10460000A03FEB9E9D13AE73FD6A32DB6913C27649 -:104610003BE242F7EB5C217BFB1D17C8CFFAC4F7E6 -:10462000EB041E86B573D8832ECB0E1D2533DCBF5D -:10463000330D327D4724F7A3646486447109D2F7B1 -:10464000969D97C787FA6F67E7E55979FD0E3BCFCF -:10465000B2DF7267DBF1EDB4FBDC5511EA73B176C2 -:10466000DE2EFC07D0CB435E879DD794993E9CF20B -:10467000229F0DEEBE12C6395AFB2305F3D576E50F -:10468000F2EF1FB161FEC15B33685F7CFC7B47BB0F -:10469000A6F4ABF8FD9BDF2D656427597104B78044 -:1046A000795791BC9EC2EE5D0F117E82020F4DF8CC -:1046B00001B21AC2557C1CF199E9C5BC85FC26469D -:1046C0008D0A2BC2B4EFF85902992E6DC554D4E36C -:1046D000F58895343CCDF0D8BF13D0A8E73BF6D190 -:1046E000BECFE7CEC11FE4DF539863D8F7DDF29366 -:1046F000D09CC5F9AEAFB4D3C1092932A84097A761 -:10470000B34A85FD33A8A3BEEC5EEB22BBF1A12525 -:10471000655BAF447F3528EBFC3872681CDA47CD07 -:10472000474D2FDA79DB23D3BDE3E0FD431D4A1863 -:10473000CDC3A796AC7915EBB1DD2EB2839EEA9B73 -:1047400057B0228DEF36EF5EB07031BEEF70917EC4 -:104750005FB1E7BE81D220F677D5A67F6FAA65E369 -:104760007D3AFA6D6FD47A33DA31576771BB64A33F -:1047700096A4F8D3C6791A43976B6349FDE8156888 -:104780003F5CA365BC4F7E57969BDFE773B54A2815 -:10479000DF0BA399EF0558EDC6D6FC96CE3182B358 -:1047A00065867E9CEBFA7932D61F827DD5A5143DB5 -:1047B000E5097ADA5874EFD60A5CDF40E67B875663 -:1047C000B9366B1CA7D3889DCF5D854DA371DD2EB7 -:1047D0007764A01E89AB50D6312EE272B7466E4682 -:1047E0007BF46A175238DBDCF1C38645B82F614988 -:1047F00097609EA01A59457416CC62A80F1A964469 -:104800005A112F85A0FF30B45758F44B3AA728AC63 -:10481000D39817EA9E253D0917BCF75444AF42BC14 -:10482000BFB4967FE7A530E8A37B4185117E0E5784 -:10483000D8EE6668326C0417D845FE814471222791 -:104840001F59EB6A5ECAE5F8EEB5BF1D95E97B33EB -:104850001559658457AF615FB707F52E8C33D51CAA -:104860005C42F8AE71B338F1AF9BE87B57AD8BE09B -:10487000DA35E5E45710AEDFFD3E8BF6FB5A664AAB -:104880000857FE103F67B5E6C96F1A54783C9CF391 -:10489000A193EF2C7E70C2B773F63C3A8FDBCC0647 -:1048A000E723BE636765A2A3CD456BBCE971D15612 -:1048B000417FB00F245F623AA3FD56FE95ADC77CE1 -:1048C000D88D5F8C54227FBCEDE5F756EF5BAAD103 -:1048D0003A1E9AAB51BCF1217F2BD1FDA98DAEF0D0 -:1048E000210447D517E27EEE2EAE0863BCEDEFF053 -:1048F000F039CD3FD83DEA4B9588CF2FFE218B8FE5 -:104900003345B5C6F919D17BAD97E09CA1B4FF6CD6 -:1049100005DAA14BE4C9943BBD6A09C92F9790E31E -:104920002F2FC9AB473F2570C372C6E5218F5304B3 -:10493000D656F3FB0C0EB99FA85377CFA05DE2F1DA -:104940009F7A21EFC6DE30BD1ED7592FF482A966AB -:10495000FE2E63AE685F381441936C58FC2757E80D -:104960008FB1BB1DCF855EC81D16071FACB819E4FB -:10497000CF97B2841D3942DC67D79279C40F678024 -:104980001F282E5D7292E83F067202EDE637A4649E -:104990006845DA7998F59DB99F887850C42CA53C74 -:1049A000E1B7443CE8A7E2BB73EF8878D071110F00 -:1049B000FAB98807FD03C683F0FB61DECB69DFC669 -:1049C000D57DD48F719C9D350B3C068C33551F7C57 -:1049D0000981FCA239E813F9F7046FD0D24373CFF1 -:1049E0001FA74A205C6E8C4B71385F16DFA37B4596 -:1049F000C03520E07A4DC065E941941B48676CAC36 -:104A0000AA67928741B555C2F35E9417FD4192178C -:104A10003C4F3CB84632260C971330DEE8743BDD41 -:104A2000A2BF53A37C44C7CEF11FCDE2F70E5F5A5D -:104A30003B6B3F0BA6C9A3C8C2554877F9B03F28C6 -:104A40008FA24D5C8E47F1DE459A5CB5E269B023DA -:104A500061D23B37703C8D245F2E24570A1D72654E -:104A600037CA15A8EF46B9124C972BADFDB8EE200A -:104A7000CA1596D243C1C827932B3FF396D9E22497 -:104A8000967CB91AD898ECC430E853FFA7D7A76F23 -:104A90000B397121BD6AE57F044C467A7D0FE685AE -:104AA000A03F339ED13D1CC51CA47CA2DC7617C35D -:104AB0007C90ADD86534FA330B291F64C77C8F8E88 -:104AC00074F1B09408213EF7493D5EBE2F7A3FDA7B -:104AD0000BDB26F038C98E3FDEE3453BFBA5DB0B45 -:104AE00002788ED39B6BE581E88B6F85FAA94646E9 -:104AF00074B262CF0A5BDEC3CFB3F2081FB9319044 -:104B00003F808F876FE7FA4737781E089419F34084 -:104B1000DC3E110F526321A48F6D52D4437198462D -:104B200099F4546F98E7AFF4825F8EE783BD0D3B35 -:104B3000E7A07EDE70ABCC285FBCB2E71E94331DCD -:104B400013161AC897AED1656FA239BEC1277BD3A1 -:104B5000F348F13841ABE6E786A2347300E4CD5E5A -:104B6000D338DFFD5155F87DD8DF7D9E3CF8CEDC93 -:104B7000D0688C13F4362E0CE1BCBDA322A13CCA34 -:104B80004F1943F6C0C6519B1663FCA963B9C6D240 -:104B9000EDA461F305EDF6B51567541B78FE488763 -:104BA000CCFDCB5C713E0D7C5589784B5F27C2A94B -:104BB0009A3C7F04D7ABF0F5D2F74D731BC03FACE6 -:104BC000E2EB47FF55F7E9A3517EA80D3C7F64B3A4 -:104BD0005F5F8C7EA3130E6BFC6BB3259B7FA45B86 -:104BE000790BF56BF8396211CF5BE8759D3F6FA1CA -:104BF00043C843CB6F1C091F2EC73975AFD71E079B -:104C0000B4E0B952944E3846CA17F8B4F35F68DD81 -:104C10009FF77C23E511ACC9966CF72B72AD7C969F -:104C2000C635219413163C9B2F903FF269E16A6EC2 -:104C3000E4ED3FEFF5FE4F1BB73E9BEB47E0D301A2 -:104C4000BC47D931716608E5502A1E3334508EF6C0 -:104C50009CB8CF68E58FB874FE4F55E5DFB993B3C4 -:104C60008BE83BCBEA749E3F427F19F240363136E7 -:104C70001BFD1D55C46F9C7C7A21F89D792337FB61 -:104C800084DF1875CC27F2449823EF440DF1FC1211 -:104C90002B9FA44B82F50553F92023CEEBC0DB7884 -:104CA00021F7DF73F41FB6EE30BF5F69E59F0CCBD1 -:104CB00023992AEFC72D18964722F2517A728D3820 -:104CC000CF13E77925A836319E372C8F64EAF4108C -:104CD0007E53725A89E87703A3EFEFF67879BD77B0 -:104CE0000E8BE3F7CE7AB18EFC54CB28AF65587E9D -:104CF000C9D43584278D4596F1F31D7EDE6FE1C161 -:104D0000995F72417ABB401E49D0677D8F2242F382 -:104D1000F4F8C33FA923F8643A8F2FF8D2F170FA60 -:104D2000F897F8B89CEC1179783DB9F67CBCFBC4D7 -:104D3000BE548876CEFDD58B385D77D5EB1477776A -:104D400037F078E5B0EF40D4D8FD01673CEF8490B0 -:104D5000D7175ABF33AEB76D84FB660B7C3C8FEB25 -:104D6000A12587282FF6CC2AD0B380AF87319FA505 -:104D7000E6E2F3595ECFE2F92CBD46FDC24B518FFE -:104D8000453586F2B417F359E0FD868611F2594491 -:104D90003CD18A8F8E94CF927BEE3CDE9ECFD27B2D -:104DA0002BCF67E9EDE1F358E3F53654939D35D207 -:104DB000B84F8F31651FEE7FC5C59D9F4E2B89FC77 -:104DC00019E6AFF4946AFA8306D20BA7E7AE468DD4 -:104DD000E8BBCBC5FDD8D868EE3733351E5A086D11 -:104DE000B6F8138B289E2CF2327AC5FDF9BFCF326C -:104DF0006CF67167E3774368D7031DBEAC733EA1C1 -:104E000071F2D5D2F5600332B7DE62A24F3990CD90 -:104E1000E308AED0B181BA343ADD22F41DE2470690 -:104E2000FCE44AE7F015950B28BA4F7F6B047DBE72 -:104E300091CDE7B7E890A993C2FCFC8F55A01CB1B7 -:104E4000FCD761ED3CBCDD30F9E390233D98DF8673 -:104E5000154B9EDC60C9133B5D5AF28339E4CC39B3 -:104E6000793287DBE9E7E409C80FFCD499530EF5E2 -:104E70007AB9BEB0E071A3600639F29E2B6C8BD379 -:104E800038E5CE85F8E8F3963B2F65E70BFB83CB3F -:104E90009D20D206F24DB6758EC8EF3D9C99FA2042 -:104EA000C9438FCAD7ED8930FA9D00ACA33CF7E027 -:104EB000394A46B95E2D51BC419C8BE48BEF0F3EC5 -:104EC000EC0A537EDAC3C0CFE8E74D309CF6D9F93F -:104ED000CF159CE7490FAFFD1AF7CF00DFE8775DEC -:104EE000AC1CB2E4C487D97CDDE7E8CBE4705AF4AB -:104EF0009546CFF47D018B7EAD712D3A66C8A00535 -:104F0000E7A15741D7188EA638754C8A631CC4CACE -:104F100023B3C67BC3C7ED9191EE5759EDBE63F93C -:104F20005DE7E2C17A40A77CB21EBA6FCEBA38FD07 -:104F3000CD61BBD53555944FA032CA278894A03F88 -:104F400073D867F78BAD7CB06925E110CA890DC2B3 -:104F50004EB7F2C8ACBCB4C3BE5CEB9CD9969FB64E -:104F60006184FBD96F9EC3CFC57FFF04BFDBB6DA78 -:104F70006B3E8E7211F0658AEF39511E9A35EE77CD -:104F8000059E5EF7984FFA3EC3FDC917B3EC7957FB -:104F90009D3EC31117E0789DA8C7EAE93E5E94DF05 -:104FA000AB729EAB8F74FFD5796FEFDCFD5771FE4E -:104FB000DEEC89BE4CF0BFC8F3DFF470F46027FB71 -:104FC000FCD673C06BFE04C7EF14FC3D2DC8EFED9B -:104FD000BCEF89BE8DCFAF63DCAFB6EC9CC3D80EFF -:104FE000FAFB5F06A90DF4B2A996D36B5125A3EF86 -:104FF0008F4F6FE5F51D4BF9774DFB5FE7F73EB639 -:1050000045F9F74CA15F9F0C78D9319EEBC3FD5554 -:10501000BCDF7EBCDF847C5AC1EDAE3C8CDE2B282D -:10502000AEA3544EAFE9F14E80F70796CA1417DDD0 -:1050300023F822C04C8A736CABE4F3ECAA909F1067 -:10504000DFA359740BD43B67AF9C8CF74BB68B78BE -:10505000CABEC52B9FC0BCBE0F02E582EE1274EF24 -:10506000B5E7F86D141F7968499EB412D6B8EF60A1 -:10507000E6FC962ABF2AFAC5DC229E24CA8486E56D -:105080005653E4ADB632F13DF69886F1A76706793E -:10509000DE6AF7EA678ECD447D5C29539E59D7E0DE -:1050A00051EF65B8EE3A9ED753A426A474FFC5EB22 -:1050B00077713BADE6A8C7A81ADEFE99C1A3447775 -:1050C000DB01EF4A9AFF270B38BBD19F807E7B5DC7 -:1050D0003D0333A1DDDE717952CC48B51BEDE7FC11 -:1050E000D7BD4416DFA167F41D874EF39407E5662C -:1050F000279E7F40FBEE1A2B2FB587EE65ED9D3383 -:10510000790EE6896FBB81074BBBC287C84FEE990A -:10511000CDEDB2BD12B4837DD9D7A25D4FF7985AB9 -:10512000799C08CA8C71A25E4C0446BC8A733B4AC7 -:105130007D81793B1BFA06709EA23AFE7D8BA29A76 -:10514000CCFD5F08B8A9FF3E578CE29F23EDDFBF7F -:10515000FA383E3BABF8790163718A4BED167E1746 -:1051600053A346FA77425B021C3F3B5DCCC478995F -:10517000AF4E23BD2E870DB243FD603F623C6E9B58 -:10518000145B8CF921B1491A7B9C30627AC761FCAF -:105190006E425E18E96F939408E1779563E3787C3B -:1051A000FB686427DDBB3A00763485835982F4546A -:1051B00077348FEE431D8D540F527F5F85EEB634EA -:1051C0000AE6CDD38722199B74D9A6AD68D7744E51 -:1051D0009175CCDBEC94EAA3385E2CD7437164D78D -:1051E0009479B47FAE517952BA3EBAD1CFF5C2D0DC -:1051F00084C88D7E585768CAA95C8C5B6EAF7D658C -:105200001FEEDF23F77B888E1EA91DBC1BE7D97F0D -:10521000F6AAE351E24B7E5EF768EDE952B47B7685 -:10522000359DCA45FC15637C0EF46171058FA3A101 -:105230000624FB4CED6137031E8BDB3466A4E96367 -:105240002FE3E779F8E79B4C728FFE9E193CE569E6 -:10525000C1F196B0C4A5017AEEC1789625678AEBB4 -:1052600058A200E4E1FE15EFC4304FEE91890574B9 -:105270008FB248BC27C909E39588F1FADF78653D0C -:10528000B67BB4BAC04079513C30340F954471D5E7 -:10529000698AB385ACFB1F5163FFAD449F327DA784 -:1052A000B238FCCE5FE03A02BE3ED273D09EE266D8 -:1052B000CE7504269AF7F9018FDF945A5F1D174CBB -:1052C000F963F487FC782FBF975D9CF50F7395B455 -:1052D0007CDB121117D8240DCE26BBF4016E878F0C -:1052E00065719273C555B1BB79BE6D94F26D9DF336 -:1052F0006EF79FD3AF12DDA3CE6F12F74AF8EFD847 -:105300009488DFB171D27D28945FD57155AABE2FE4 -:105310007A8AE8FF69CDB82BD3F71EF609B9B049F0 -:10532000F863D6F86373F9F856FD519DD3E3D32F94 -:10533000E75D5F05EBF9ABB6B24918FFDC31821FC0 -:10534000B732C0E92F7B002C1CD003FDAFBDE6C5F2 -:105350007C96A765B60AE5547D55C293AC12788455 -:10536000F1C91783F10F84BFED41B9F4D54025C1D0 -:10537000B5622A8F1B74563D48E740219DEB1DE422 -:105380004F94EFBE504CC2B8F7F21AA61F12F19616 -:1053900018E09FEECECB2C95D7BF3D97FC1CE015B7 -:1053A0007EAF067393268BDF9F28C773A24D778B42 -:1053B000FC5919F1DD29E601BEA5790E148971EEBB -:1053C000E3F63FFA17D8BF5CCC535EF7DDAFA11E02 -:1053D0002FD2395DA4E0EBF3107CAD3223F8D4C4B6 -:1053E000ABE8876E9F546020DD1C0885DF6E82FA73 -:1053F000F2452AC5E3CB6B381C075A65FA3D207F7E -:105400009D7690EE8F99A02FD2F06588798B6A12E5 -:10541000129E6B19AD7C5DD0CE8B72D108033C50CF -:1054200037C4BACEC13F4923F88B3C83985B740ED6 -:105430000F2B713CA0DF9575BC9F3FD4B705E5D815 -:10544000F23A0E37E87782A728AC1D447D5F14E25C -:10545000E32D07FC1C925270655B70D5C9947F5593 -:1054600054A31D443F385BC0B732CCE1E97FFDD483 -:1054700080C4C73370BC6C016FB6583F25EC16086A -:10548000FD00E33DE54AD4E3BD9C5353987188CFBA -:1054900046F12CEBFDAE56C003E0C72FE661BBDD45 -:1054A000C44FB0C4D8C732FFFD10232D6E51B15B7D -:1054B000B3D5FD62FF58177F4E7E1CA9445E9785C9 -:1054C0005FB7B2CADE8FD5A4D5CBF07E19A7F7F5AA -:1054D000D7F2F38E0313B87D847EC739FE463A9F18 -:1054E000623CD615C4F71AE9BB9276FBB8C5AD0588 -:1054F000D3513E140F3C3C4F86F514DDCB64258719 -:10550000E8593A27FF60BE6FAF49D0FDD9EC81481A -:105510001ECABB92D6BCE9F8FDB7EC8128D5B3070B -:105520005A4D9E7F062E4C1EE6EBA5CD538A729AED -:10553000E7D3B156AD0FE55A6D3A9CF0BEE4E59E57 -:10554000B9D87FF3DDAF8C46FE2D70F4F7E470FF21 -:10555000A1F8656815C0F94FAFC5F6567C271B2129 -:10556000CEA3F2652C8B7D208FA12C11F97796BCF0 -:10557000E89CF0CEA4A84FD00FE5E3B144BA9DEF6C -:105580002CA1FD78D13E269DB7DD696A3752BC69F2 -:1055900020C0E34D0161AFF630633FE9F71A9EEF9B -:1055A000E1C3E7A03FFA6A8E4EA7FDEC6361A4E772 -:1055B000E2B63FB9D3E5F5CD8152710F3A4174AFF0 -:1055C0009564D1F91EF0317DDFF480DA4AE7AC7DD5 -:1055D00045FC5CF3E89C5724C467D1733C4FDBB2B5 -:1055E00097A7D72442F8BCEBD5E865C49F23D89F82 -:1055F00096BDE95CCF25F50F923C181B655E3C5FBC -:10560000F3AF56298FB5240A7055A15C00922E0481 -:10561000F86B62EB916E8C28AF1BAB45B90ACAAB35 -:10562000C1BE5D3750FE4B576ADCAD1560D7A2FD99 -:1056300034B8DB7303DA2BAD608D18682F9EF2E06F -:10564000F754BA5BA7E7239E9F8958F66542C2F1DB -:105650008B7E6A92BD58AB6B3AC66126B813A3D352 -:10566000CFE90ECC79A79ABE2736FFE2F2C946D21F -:1056700027088B9CA647FAAB8E927E79C23F9EF498 -:1056800090A5572C3D4223827CB945F0519791F06B -:105690004824AF807701CE5B508E001DFB8BB83C59 -:1056A0000739CCE59CA54FEEE67ADF929F15629C08 -:1056B0005B50DE42BFEEDA27726F40B922E4AC3FA6 -:1056C00064CCC4F3B90A215F991A9370BE0353F8EE -:1056D000F72A030E795AD1CAC7E90A31A227D04363 -:1056E00007916E0E1425E89EF881D6A352FA3D5319 -:1056F0004BDF055A930CF77F5C1D9783E3845CFDB9 -:105700008EDFE0F4E9E172F59CDE13F276AB79947A -:1057100089EFC266CCC3FA7BA1CF7B2A0E915FB022 -:10572000EDD653844F2B1E1A12F1D0EEAAB7E8FD26 -:10573000F628BF07B0CB9C3E87E08F2CD728FFB45C -:10574000E6E89C32F4379A966B68D79D0C1458E7BC -:105750005FDE85684FB6AE22FBD727F6F1A1301386 -:105760007EA7467ED67D4BBF3D80FD43E0174906B0 -:1057700036EAF3B891CEF17B0A88EFE82075F6D5CA -:1057800018F41D08E73ABE17E0DFA5F5479303E3D9 -:10579000685F65BAD2E3AB61E4772E07BF0E87DDA1 -:1057A000AD86BD13E0FDEE26595FCF52FDFF578059 -:1057B000E7A34DF4F37B0A3B179FDE8271BE9D4B3E -:1057C000C577CE1CF0DFD7D8E751681E8C09501E74 -:1057D00073C6EFED57F9B3F8F7176AFA06D09E0FC4 -:1057E0005471B85E0C181CEF831C8F3D1199F8683A -:1057F000D760B517F59DD36E7C24FBDD493CAFC562 -:10580000AE6F2E542F76C8FD09EEBEEB48DE7D53F9 -:105810002679C518977712930DFC5D8D9600A7A782 -:105820002A21AF3B5C89FD9857D0F1AC8FAD375240 -:10583000745124C6EC6C9533FE7EDAA180C2F77FEA -:10584000F8BE73FB41ECFB93020F17DA7F0CB3A099 -:105850003DDD17DF34E60E94E3ADDC7FEE4BBC4557 -:10586000794745B31792DF73E4E0A5E40F14559927 -:10587000B6DFD7CC1EC16FADC8F19C371E30923C4D -:10588000DEB7BA83FCEC7D8399EFC514E4F0BCB4B9 -:105890003E9097F87D9391E6D77338FFFD5340D043 -:1058A000DD9C77E87B19697AF665A16749DF16AB5D -:1058B0002CA6A4E5394C10F873EA4FA6C63D97D63E -:1058C000109D13FEF689F38B874C99F06ED1399EAB -:1058D0001F205E611DA6A0433ADFE861710FF24D03 -:1058E000AC89E77938E19EE0972F6A7DC11CEE878D -:1058F0009C9B4FF8EB13FD1CEE9DB5F7D33D4798ED -:105900002F84F421FDE03F4ED37DA8675DF47BB684 -:10591000339E752530A675E741FE7B8BF28B5E8248 -:10592000F39F0FF3EFAB27FCDC1EFBB5CE7FAFE898 -:10593000ABEEC1EE2F407DE85985913D1907C505B5 -:10594000F47A5AD02B7B8ED7577A79F5CE83FDCB5C -:1059500070BC55CFF13CCC3B9FBFEDC62F40FDB690 -:105960000117DD19B8F3F1F5DA18A8DF1E97FAB0C0 -:10597000FE9BE98C7EEF3396A7519CEB3781C18269 -:105980000580EF0FD679987119C649070BE6031EFB -:10599000EE883F3D13FBDDF1941446B69DF1ECE338 -:1059A000AF8C06B8EEFC8644F95F5F39926DB30B9D -:1059B0004FC352A6C1FB3507F9EF46DEC67A662211 -:1059C0003EEE7CBC977EFFD0C2E707EB2A9991F6AA -:1059D000BB61777EE369FA3DC3BBBE25D1EF2BDE09 -:1059E00025F37B44FFFCBC77D1633E5CDF7AED524C -:1059F0003FAE6BB386ED6E8BB77C17539AEE881F64 -:105A0000D466C2FB3B0E1CD456A25FE666CDA87FCF -:105A1000BE72E40A9BDC39BD4F21FF604DAE87EEBC -:105A2000D7339F199A3761F83E7FB08ED9E0BAC359 -:105A30008A13A8716D6E5A7B97CEFDDFAF1C516C37 -:105A4000F3587640EC18D70BB1BFF553FCDCDABF46 -:105A500035C2EFB6F66F8D15885787266782A71B6C -:105A6000F703E0E959A753B9735D88CADDEB0CDA97 -:105A7000A7BD884728BB04DC81A9AC1EBFCF1F305F -:105A800079DA715E93598F77CBF222BC5EB0244AEB -:105A90007EC848768C55EE75455BD087ECDCD13FEF -:105AA0004B05BB67AF16BD1B235F7AC7ABB31AA00C -:105AB000FE3739918D39246FC206F29DE59F7F3DF7 -:105AC00087CBDD4DA335C2F7DEA5931F532CFF0B0B -:105AD000E37E4B573E81F604F4DF9E437C1BA6EF2A -:105AE000748DD4BF60599DAD7FC1B25556FF3DD472 -:105AF000DF73FEFE7B975D639F7FD91D56FF4708CE -:105B00007EDFF9E12F689E6A9FBF7935F5FFAA9B7A -:105B1000EFEF50AE87F2E93BBCE1848BFC6746DFD8 -:105B2000E750F32E3D44DF4F3A17671A3451CFFA4E -:105B30009ECAAD463996A2A3E9DFC475F881BBD2EF -:105B4000E928A72ECBC657B9669EAD9E3F7B8CAD8C -:105B5000FDA84899ED7DE1A2CB1D74E9D3290F96EC -:105B6000717D6A629C13E0D4C6F0EF35D58FF1D019 -:105B7000FAEE7FD14BF5FBAFE1EBBB7F8C8FF89852 -:105B80007417ECFBFD5AF4CA74FB18D62561C8EBF8 -:105B9000193D3A90539BFEDC90F17996C27FC72E57 -:105BA000CBCDF5E5E6D2C98FC5D2F0B9A518E8018D -:105BB000EA6FE768B638CFE6E295A196B479361574 -:105BC0006B8B0E55F1E7B7A01DAF47FE0EE7FBAAA2 -:105BD000367429DAAFCE79DC6575B6793C25AB68C9 -:105BE0009EA4631E77C92AC73C9E4587C47331CFE4 -:105BF00029A49391E6D95C768D7D3D2577D03CBF75 -:105C0000C6796AD3D6537287639E2CBE1E782EE661 -:105C1000F9CD79D7533ED5BE9EB1AB699E7F77CC87 -:105C2000E31EBBDA318F8FE6C1E7380F2BE27E949B -:105C3000E61E5A49FBFF032FC33890E68EFE355D02 -:105C400052F97B2FC585A19589EDFE0FF9438DD2C1 -:105C500000800000000000001F8B08000000000012 -:105C6000000BE57D09785445B670DDBEF7F69274F9 -:105C7000773AFB420837801034C40E840CE0320DB2 -:105C8000411E3A80C1155CA0C3923DE988380F4798 -:105C90009D34041111B551D4A0C034080EF840034E -:105CA000132040C006D4C119D438CF7199059B4543 -:105CB0008210930651F1CDE25FE754DDF4BD9D0EF5 -:105CC00030CBFFBF79EF8FDF4C51B7F6B3D539A793 -:105CD0004E55939C0442461172308EA62308F92635 -:105CE000C67DB5C34AC8F7F0F74342FFBC8424F32E -:105CF0003485903984FFF9170BA490905A33CBCE9A -:105D0000DE3C256B01A42D45692505F41F2B6CCEC7 -:105D10002B14423A5B8A8CB372C3FDA9E91C9F7CA9 -:105D20003298C3DA7E4FC2E378C7929C3A3A7E59E2 -:105D30009C03E7A3E64FD6D3BC899063F504D376E2 -:105D400099CC28A6DF4FD4D3090CD6CE7701B63B29 -:105D500029D17F26D17495E0F70A745DCB3F90C9B5 -:105D6000001CE6C31CBA8E3BF832E6F862093187A4 -:105D7000E7E1311117B40BED32F9D709F0D5D5C7EA -:105D8000904693C64442D4F9F627E48FFB26BD2DF6 -:105D9000D831DBC7309290BB966C7D0BAA7D2494E2 -:105DA000F49D4BD73BB579B9DC87E63BE5E074A7BA -:105DB00055D3CF54F918ACDB4CFF837EA6B9695E8E -:105DC00033FEDDE5FAFCBD440AE7B309B9CAD19F49 -:105DD000E3838FABF865C0D71D744DE91485F74296 -:105DE0003A0C8A1D88AFE90ED6569D8FE72199049B -:105DF000603E523099E4424932D673433DA5E7FCF8 -:105E0000A6CB665731C5E7F407458463E47C83FB82 -:105E1000625D863C9A367E2593FE979EFF8CF9FA4A -:105E200072E265E3A97055E9E0CEA9639E3DA1A1A8 -:105E30008F69EE1B9F3DA183D3145DFEDEBA69BA64 -:105E4000FA33E697E8CA4BBC15BAF2594BEED3E5E4 -:105E5000E7F81ED4D52F6B5CA02BAFF03FAE2BAF75 -:105E6000DAB85C97AF695AA9ABEF6959AB2B37EC3D -:105E70001B7233A1706CF8AD484C148E5F5B4F3EC3 -:105E8000754D12A49213E07EAA3E0DE9FA74BD820C -:105E9000692DD0DE28E09FE16637C5932726544A56 -:105EA000E20979C477ED9225D7D2BC91968FA6D41A -:105EB000EE1BBBC49B49C8128782742F361A4980D7 -:105EC00092AA4012BAE93A246ACA8397286F944882 -:105ED0006078CF723118FD7B97101A9441D7E1FD9D -:105EE000D44436083DF93CCC97A40F49EBBDBCC364 -:105EF00040CA9B34726783C380F349768CDDE0A08F -:105F0000F4506D64FC5EBD2D7D2CB1433E30A8CEB7 -:105F10007A91F19AE86452A11FC62F15FE3E61FEE8 -:105F200045FC0DD0F1FDE038F77A071DAF63BF38AF -:105F300015E6410207B36E1D0AE3BB36C077D242B5 -:105F40003B49A7FC5DEF7AF6C415847C523F01D330 -:105F5000DFD5173F7B4226E40FF553317FA4DE8D5A -:105F600069B0BE1CD363F575587EA27E3EE64FD65F -:105F70007B313D55BF04D3D3F53E2CEFA86FC47CD5 -:105F800067BD1F53950FA83C9A510C7C5A5C6C005E -:105F90003E9D6B21FC8FE5CFF13588F4DF6DC8D7CE -:105FA000CE34E0EB73D66F0665507A3BF70925A631 -:105FB000ECDEE1144977BDE3CF6500FC95FA29F1E9 -:105FC00024F62CB7C430FC580C6402A1F2E7F12B84 -:105FD0008C44A2E3C7BC71D53A311BBF4B403A7425 -:105FE000E3704EB145E97F20417C5D0A4F6AFD9325 -:105FF0002FFEA970662EE0A73FD249CC41B18EE1B9 -:10600000ED6527E0ED52F093387F45C25178E38F7C -:1060100059415AFFCB64159E6D5984A6B73A8A4FF1 -:10602000011D9C6B36E1BACEB5C6FA09F4E14842CF -:10603000BAE81D6E6C1E551B2D3EAD7CA8698AF713 -:10604000E9E545BA4F2B2FCE1D7AD90E7C3F374D4F -:10605000F49D180EF4E1E2F4C1E84EEDBFA629DB91 -:1060600067D5F5A3CF9FF309139A50CE2B71B70DC7 -:10607000ED7D9E73D38C38CEE98D03E260DCD3F5E1 -:10608000661F8CD351EFF0B171D37C5ABAAC9E1F0E -:10609000EB3B91189E5F6FFDFEB3E7474833396EC7 -:1060A0002608FAEF07F45EBF577C48E78DC5401F0E -:1060B000ADF237B0EFC4E4A8FB8E8479B55F4F939F -:1060C000E8355D0DDF37EBC6A3ED94932A9EFA5FAA -:1060D0000CEF1239A9AE93CAC9A15476039D52623E -:1060E000463CBB698F71B4BF2EC9BA44A0E398E2A5 -:1060F000152CF7C040949E6ACC41A35B4170B781D8 -:106100009E3573A4CAF7CA9DBFA724F7C5AF65B271 -:1061100014CAFF4C7BA7E5322F9D4D8AED848E3744 -:10612000B3B96A22C8C92F76FC88EB29BE4258F75A -:1061300097C43001F8E44BF21BFB708D5E3639DEFC -:10614000C8E6B784EDCF5EFA1FAC8FEA69BAFDBA34 -:10615000AC519F2F25B7A4003F94AE90899FCEBD30 -:1061600002F67B75DD94EFAF8F677A5C19A95B0C43 -:106170007ACA52994C057CCF7410A90F9513353B00 -:10618000571796D0FCEDF106A4ABD354BF53A81C0F -:10619000AA48607A4C6592DFE8A2E5C79B87DF7169 -:1061A0000D81F6FEC520D7BC36E2DC407AC27DD632 -:1061B00012FDFC2E35FFC8F912B210E7ABCE43ED4D -:1061C000579D87B85170F9A3E8B3B3E285B09E4CF0 -:1061D000D3FBE3F5FAEB7CC86BF4DB4722F20B232D -:1061E000F22A9DC89C4E4CF1EEF9F1C94017A1F17D -:1061F000A8A7114A1FB9E17AC670BD472E56CF0431 -:10620000F544ACB7F062F52CE1FE1E8B56AF66E7A5 -:10621000961D5E4A4F95AF3F6727549E7F21F952E6 -:106220009CF47BF58647ED00A75392D70EF8FEC28B -:106230002F4E8806AF7DDDF0725905B02390B4294A -:10624000DC5F7D6232E849DF6C901D22ADE2D968E7 -:106250000A9828FDD636574C2479983FCAF28F9D6C -:106260001521DFA2C767E5CF9F4B516C8807A66F4A -:106270009300EA1DB5EB3F1F0F72DC434248879144 -:10628000ED60FC0B09C8F725C6B89EE5749EA827EB -:106290007B389F799A9F382BDA21BDB11DF8CC133A -:1062A0004147E5DDFB4BD0584CE7F37ABC2DE9E4E0 -:1062B0005534FB03F20390072A5C889FE9150D9B78 -:1062C0005EC83B4AE7D5B1FED77621572B47183D2C -:1062D0009E6B9AF5B3DD4AEFF2A693DB45E1767E3D -:1062E0006CA7B4303D88B4B2B45A0ED841EFAC5E5E -:1062F0002B3B29A592EA2D2FBFF222D86B9F9AD073 -:106300005EABDAF2D647A369BE6AAB9C34912DC767 -:106310002AA484F1E3A1FF9B3F2C8C8FCA5FBC654C -:106320005486B2EF0F2784F152B575BF910CED0979 -:10633000C7A2A6FDC6A0350A7E9A8E8E07BDA561AE -:10634000D3B746B0BFBED82790D4EC9EEDCBD7BE16 -:1063500085FB22C009F1C9F1D58DBF1E780B4CDE3B -:106360005D80F51C202F2F85371F97D3353B6D247B -:106370009ECEA3FC7726FF44C0E76BF7DB613DEDC3 -:10638000521DA3F3D58FA6B8E8F8E5B237C5812929 -:10639000FB5EBEE601A4BF32A12EC581FCE44A37F4 -:1063A000A0ECF6A6C33AE7ACBA1DD7594ADC488739 -:1063B000E5ABC5623F4DBF96C884AD51F8A43081AE -:1063C000F149FB3A8A5CBACE76D0FB41DFFE8DE81C -:1063D000DF80F6E97D04E4FF037CCD74A7C4FCD71D -:1063E00066862F6B8241B517CD3AFA5DFF581BE0E8 -:1063F000E9745F572ACC93C2C1CBE1267C4FFB15D1 -:106400003FB82195E1892852216F47F78322F80E82 -:10641000F5DB6497254FD78ECB4F36FE3C3E3E9D35 -:10642000770CEC6FED2954BF8FB2BE99B03EDC17EC -:10643000E93EA7A1330DBF33FE5FFF38E37795FF39 -:10644000FD532640F9F90F191F413BD84FE8BC0214 -:10645000A958BEFF3601E5838904A2F1F97A99F3C0 -:10646000B9BEDC43F915FC042A9DD0F94B429C9639 -:106470005EE838098807B4574A57D0F65AFD06C671 -:10648000C57AC6F077CDBE52C6E5427E029507B109 -:1064900061794056255F961E592D132FA89CD59FD4 -:1064A0009AD01EAFDE2217C3FACF6C3EF8D15D94AE -:1064B000CECF34A97CAB97AB917C5BBE6D8300746F -:1064C0001AC9B767CAE92E1E8D6FE9F7A87C5B1E53 -:1064D000FC7F2A5755F84D4BD0CB532A1FFB810A1E -:1064E000D11B1C23E5E3D7A06F25F7948FF4EF436E -:1064F00052D8930E55FA53E98E6A70FD40AE77D3A9 -:10650000A74A7FDDF4A9D25FE47AF5F08B2CEF0F78 -:106510003612A593E25D54A3A3F8AC6E15FC26E4F5 -:1065200073EFDB7D0A104E2EDCDE88EFED3E49DA9C -:10653000BC3F22DF1451DF15912F8EA8EF8EC8D7F4 -:10654000E9EA57B71C3412C47F4057CF34FF257295 -:106550003C8A3DA8EE3F9EE6B3462FD04566C8086C -:10656000724F5E485537F0AFED15D1BFD6A584EC1C -:1065700009F4FBA31666A77539783E9EE543C9C6A4 -:10658000C520F7D4EF210B41FBBCAB38648FD7D8C3 -:10659000FF475B45BB42CB837E3241EB4708CFA729 -:1065A00001F11D24BD9533BF61578C3D0FC78BC9C9 -:1065B000F203FDDD205AB3E683BDE7139D947CC84A -:1065C000EC0577DA09A5B3AED601374FA5DFE7BCF6 -:1065D0002382BA4DD1E392D229DDCCE2747C8A7851 -:1065E0009FBF96AE6F562BD3C3672F8B4EF795BCCC -:1065F0007EA9759E11E42BD5A38F69FDA295641920 -:10660000D25DF9AA88EFAD3F42FEA88CE00F37B704 -:106610001FF6AAFC914FF251BE10C2EC5F2E976F8D -:1066200010736F9E4AF1D07548242605EC59912CC1 -:1066300086756E16FCE02F20DE64E4B35A124279B0 -:10664000A8C2A903F86870EF72AA63FB1F0B1F02B0 -:106650007AD9F1FBBC9768DAB1E3D3417B20BFF371 -:10666000E3ACDF939EF58BF67D371DF6B3AE7D264A -:10667000F48B75EDFB65D64390DF6D42BF58D74272 -:10668000930BF8C0BBCFE6BF02CAFB32FBA161EFA0 -:10669000B77941DC5F1721DE4E2530FBE55CEB9FCF -:1066A0008E084990D25581FEB02F16F9C8B3DB820F -:1066B000F67AD7DE6F0BDDD67FDE7A6A8DC48DF475 -:1066C000682353B701FDC633FFB167CFA89717D032 -:1066D000F16B9AF71B67D1F2A237FE9207F2B36B08 -:1066E0001BD38B3AE5E01AE224E4AB84B2C765F031 -:1066F000F301336510F274E2C61BBDB9D1E0C2E00C -:10670000D045E100EBA2702907B9DF1B3C62128D76 -:1067100048EFFF7AF0383B9DC9B51F10F00B85E1BB -:1067200022B8D8779BDF2CE0FAD9F77DDFE681DC51 -:1067300039D3B400F5954BAD7B48E2BF2A1DFCBDB3 -:10674000EB160297B3EE09FFB2F866F4FF5E8282A1 -:10675000F38CE4839E74BEF3C7987FCDE6C4F95EE4 -:1067600026FF97FF6FC3FB368A77FBA5F1FED8FFA4 -:1067700058BCBFC3F16E7398409EEDFD0BFA59D51E -:10678000F55F6ADDAFFC0F5DB7AAC7DF64A83B3CCD -:1067900085D63F4C022B8AE93CDFCCBCE1C329B44F -:1067A000F497BDE8271F25323BF097A07C80FD972A -:1067B00026F837A05DC1ECA622C2F6F5A29C32D421 -:1067C000378A729E40BD81487587F3293C6ECA9A0C -:1067D000E35C8AD5877DE2A6F97F4BBFCE89FEC3F5 -:1067E00008FBB1E8CA1B0F81FD7270019D1F1DE7F8 -:1067F000605FD1413527322E530E98F2303D0AE9C1 -:10680000DBF609586F9C556F3F4D04BB47630FDEA5 -:10681000A8E8CBC7F3FE2790034912ED7F825326E9 -:106820007EA8477C8BB4E7CEE323FAD946754CADFE -:106830007FED6F859F3989D999BF24730FE703FCDA -:106840003265F41F5E127E006F8457BE7F29E856C2 -:106850009213E17753460D8727B3AB25DE5EB22E48 -:106860006E03BE9508B58B995E86F6B46A175F0A0B -:10687000CE84DBDB121F5A85BB9449ED6D7DBF08CA -:1068800017151F7F2B1E54FCFDBDF8F81DE0634457 -:10689000181F99E71D12F06711B707C69D6F1331D6 -:1068A0009FE994F0FC85DB0363ACF112D803D74970 -:1068B0001F88C09765E65D95708E60760A48D7831D -:1068C0003B0C68EF980B04847B4EA384F90F0C8E6D -:1068D00011A0684FBE66E7990709F8935D46A67850 -:1068E00017337FFE9FBFFFFEDA42F0ABB0BF32FA34 -:1068F000BF49D41E9BBD8A0462E8FAE648C40B2156 -:106900000E737C0239A6F307EBF3F0777D4AB89F4C -:106910004BD5EF4D8EFCB3D39D546E1DBB82905D65 -:10692000903267BFA4B59B7FD0CAE0E5394CFCFD2F -:10693000512EB8C462CD39DBBF2731F9B1F30FDB7B -:106940008683FF6C4C576E1C93A70506A04B0FB7B0 -:106950000BCE11250EE215CEB50E88C373C443A22B -:10696000CD1DC56FB389DBD3FF518F4E65D2B59E68 -:10697000F844B09B4808FDB7DEF5E6A8E7C13393BD -:106980000C9C6E38DEE89F5808E7166CFC39B46939 -:106990009C166F1D13BF90F27AE201FE8E69CE57EE -:1069A000FE51F882FD0EF0DD64098E2F8E223FE647 -:1069B00071F84D3EF01DFA3BAF6C5D6B00FABD7295 -:1069C000BD41773E599DC4EDAE616418CC6BF201B8 -:1069D0008BAD00F07248745AE8FA3CAD678DEE2832 -:1069E000E75C91F084FEC18FFE6A123B17D8233713 -:1069F000CD02B8EEF9D24CBC14BFBB8CBEAA68F372 -:106A00004C4A61726E0E69BA3F2FFB5F0FBE63BACC -:106A1000AC81B16067AE27DCAF11497F04E9F8DCD7 -:106A200046E287FD14EC52900BE73613DCCF294881 -:106A30009E04BB9AF2FB0FB57E9AC12D5BFF03F457 -:106A400080DA56C161A0E5B552D008FE584F4BBC64 -:106A500008FB6EBE425C783E2C3986DEA6E18B5781 -:106A6000932484EFC1D17BEE8671BFEA3012D04708 -:106A70005C6F86ECB06F7FD53A1CF9A0B775FDA2AC -:106A80009E548E93A11F260F23E92177738C2E7FAE -:106A90008DE8CE00FE9A6C0ACE7346C1DFC4644610 -:106AA00067972DDFFCFF9FC9B70F55F9E6168B35A9 -:106AB0007C9494CCE85E23DF52A3C9B7B982920AD2 -:106AC000709FBB77402AE075EE3B727234F9B6A531 -:106AD0009E9DFFBD4EF911D2AE662ADFAED6C8B775 -:106AE000662ADFB27BB6FBEBE5CA37FF7F0FFF6D8F -:106AF00001F91665BDF11C7EAA7CCB6B3D8AF22D97 -:106B0000AFD940148DDFC99C7C29F92624DF06FA11 -:106B1000F021D9191B857EB670FDFB751EB707E302 -:106B2000809CFBB764765E7AB9722E3D85F1C925EB -:106B3000E5DC7F139C553937773B9573D9D1E890C5 -:106B4000C9B9B9BBA89C13801E999C9BBB9730FF09 -:106B50005B847CCBE921DF08D6AF0DB0F69E96ECC6 -:106B600017EEA1FD0D73C94E33AD3F2C2CEF4668D7 -:106B7000E5DDBF254B08E71EF2EED0E5C9BBED5CB5 -:106B8000DE5139D61FE46B247D385B6374F93DA375 -:106B9000DA37FF02F8E55D11CF173F30B073A0F789 -:106BA00046B517007DADE4F3F170FAEBACF762FF88 -:106BB000456FB2F5D56C66FEEFDA66A61FD6AE1746 -:106BC000FD0AFDE7F8D1DF1961FE157B05924AF356 -:106BD000534CBEE7AD20837F2E13762E4626E66B00 -:106BE000E861F6C82AF4E33758ECEB08E5E3D9127C -:106BF0003183BFBECA3AFE0BF0D3578D64FEFD2A27 -:106C0000FE9DF0B801350EB2B4E5BEB7FB909EF123 -:106C100003934D0C8F935F16FC6BB3217E495F5E2F -:106C20001511FFF8145FE71431887021EF8B51E3E1 -:106C3000189E8A84C7210E0FBA7E1D3CFC425478F0 -:106C4000508C4ECC4F09AFBFE2DDE062F0E757ACAD -:106C500014F0DC578547E43A55F8A8FEE92ADEDE51 -:106C6000D37A1F9EFB47AE5F855F8F75ABF08C5864 -:106C7000BF2F999F7BE593E1104F43E901E587F72B -:106C800057140E749CE23157A46AE5F1F31C0EC34D -:106C90007D638AD209C08DD401FD9436DEF7763A41 -:106CA0005DFF884F9461B04D5E33DAE48673D44D56 -:106CB0009610CA3795BEDA557AE7FDECC9A81B8B4A -:106CC000F67A8BE000FDC213B0201C3D94CE2CB4AC -:106CD000CAC195DF8CE770749890AFF8BE43E16E3F -:106CE000A0F5C7ABFB10853BF0CDF0D6B3789E5B2B -:106CF0004042785E52DB283803741DB52D0C5EAA25 -:106D0000BCA57F562D3EA2D0A3148D1E0938890B39 -:106D1000C3FB6015AF37D9E4FB08CE6126537A5F19 -:106D20004BC278CCA1FF011E23F1A4C2F352F4F9A7 -:106D300039D73FB6001CAD00AF10D3A302745FB0CB -:106D400085CB3D925707C7A2172F30FADA2B287050 -:106D50009ED00D27A0575A3EA295D12BC04D01B809 -:106D6000B79688902FA5F04DCCEEB94E38BFD4F22F -:106D70006FC5DEA3ACFFD5829344A15F75DDBDD1A5 -:106D8000EF3F4AB7ED1174FB9E25747838D0ED5E65 -:106D900081F9115AE375E78EA61476EEBEC942E971 -:106DA0001BCEBBDE919DEB949E7C7E81C313F47F52 -:106DB00045E3971A020B80B3C08D668C3FC379F40C -:106DC00067FAA556BE6EB190E4DB0A7AEFDFC8ED34 -:106DD00081DEF41B353F14C603B9D742C7CB098FF8 -:106DE0001729DF557BFF52EB4A4CF9C7D6D51DBF9B -:106DF00049DAF0FCC914EF7E2809FD3F2C3EE90E6C -:106E00001E9F4467807A96A65E5AF288DEEB913424 -:106E100033EEC3F7F3B8F81B442BF1D2757CE5923F -:106E2000914EE92EFDDB6B412E8FA5FB084DBE3A3E -:106E30003CE2E37BB05CC4F3A89BDF4DAC8173BA4A -:106E40009B4118D1EF37E70BB8FF7E009D8D023DC7 -:106E5000D64C5C264EC2B47CE40FE2D16F94BFDE08 -:106E600057A4507E1AB6D1DF00A9B32894F41EC0EF -:106E70006F8C48007E6DAEC422D8BFEEFF9CE48BC1 -:106E80000AEEB3D8CFB0432419EA8D7625A3393062 -:106E9000AA794511F847A71CB45A81CE73561988B0 -:106EA0005B43BFA389BF01FC36A34EB86E05FE2B22 -:106EB000A7FA02F89DCB5BD736D821BF4A702AB417 -:106EC0007F8FD73DDE4EE7B5A5F1ECF8AB800F69BB -:106ED0003DE8C6B38AD5F3AC179C102A5BDABA1C1E -:106EE000E3714AD70BC401F5FD0231B37EFD66DACA -:106EF000EF9655B43DCD97417BE877FDD90F6F05EF -:106F00003E3F2CB2F69BD9B975296DA700BDAEBF27 -:106F10000FFBAB58259034DA5FF96626FFCB0FCB19 -:106F20004E286FDEBF12F7B18974BCF46C90F78104 -:106F3000719027C30507FA3B33EF42BEEEE27C4D6A -:106F40003AA632B921F03CB71B54BDE9400A8B0F79 -:106F50002E752E3026D27EDE1B999C0D61029E96E8 -:106F6000B3781E7D82C2D94DE1FC018FE73838F23B -:106F7000B831A8D97F3E4B19807438BB650CC6392F -:106F8000CC21C518E7307914D3D7DEBFCEE217E89D -:106F9000BCDE974399F0FDE07526D47F3BB7C878F7 -:106FA0005EDCD93788FEE9F6553281788D86552228 -:106FB000CAC5F6CD6C1F1757DF3E3E1DE0B74170C6 -:106FC00082DC3CB8AAC808FB5ABB5FC0F645AB1FC1 -:106FD0004861760C9387AADD56EAA8D0ED1F91F29E -:106FE0004D957F351C0E9172AE46DD6722E45C0D37 -:106FF0009C37DB21D57FF7102B937FA0F703DE03AF -:10700000DF21FDD61E9609E8FDC2F18EF118B70505 -:10701000FB262D1FD52AB8E09CBFFC13931FF55506 -:107020007FC98C9F80FCFED4440405E2E029DCA9E2 -:107030005C18690AFDE159FAFD8B0FCC102143E978 -:10704000A404E1ACC68B166C60F12D051FAC482979 -:1070500005388C4B44395BD62812B7465E7C21B884 -:107060006EBD8BC963C7068D3C2A30FA4A61FF7238 -:10707000A43239A86C902166846CE7F289EAD32E99 -:10708000D01B2A762D4F31D27A8B793C48C5DEE56C -:107090002954349006D8B768FD0A23EBBF629FE0FD -:1070A00058ABE95F6DAFF6A7F663DCA5EF67C05E8E -:1070B0009EBFCC7ED479A8E3F7A68F8FFCCF0B2B95 -:1070C00004DADFC8F7450C521E797CE200ED7987BF -:1070D0009AAAFED7C20F0DC4A581DBC83FC4109782 -:1070E000862E9A4750FEA6789BD4C2F4A1E611479B -:1070F0008D35059877003FD7723F6DED38766ED5A8 -:107100009CFFC122E0EF890502D201F1BA8D8949C5 -:10711000A8072970BE5056C0DA97D1F6C077CD2B9C -:10712000191F5279A080BCA85DB57C3CD65F2F2882 -:10713000D07FF3DA12DCE7CB478A04CBD71F45BDFB -:10714000A3BCE56812F02BE5CF15B0EFD65E6B72ED -:10715000007FA87CA7F2F1FB328B0F2166C750B8E5 -:10716000075096A244E55FF1306176EA6619F9CEE0 -:107170003392F1E5FB5B44E4E783D7DD391EF8B0D9 -:107180007383D00B1F533E2D08F3A9B89AC5EB9417 -:107190006D62F6CAC1554C3EB437333DB168B53C5B -:1071A00009F265EFCA84F9BD983E78B9FCDC434F1B -:1071B000D9189D9F7BE3DFC972D347F7D3F9DDFC74 -:1071C0001A9DBF128657D1F50FDAD14F7FFD345C7F -:1071D000AF2A874A2516CF34DBB780C5FB4A2CEE91 -:1071E000ED6F9E57C43C1E4BB185E58808F41ECF59 -:1071F000E2A4D7CB48EF91FCF88FF2D13F8BAFB729 -:10720000733A52E723EE65ED21AE2C40E1F8CBCD89 -:107210002F635CEB97AF1E9D0C78AEDA43E997AE17 -:10722000B773B38D04406E497EDC6F2A9B458C1F7B -:107230002752A0F0569B963F597C52D5EB36A49B23 -:10724000CA6D2CEEB472C7F13C8C175918C2B82B1A -:10725000EFAB5CDFF406F380BE2B25162715C9EFD4 -:10726000635299FED9B12B762AAC43D8B81FCF5BB5 -:107270002B9BEE9481FEBAE547AAACD6C3734C2F84 -:10728000A55F386787F94D19AA9DDF02C453C72649 -:10729000C6FF952DB2DF02F3DBB816FDD99E8D67D0 -:1072A000313EBEE8F52DE847F0B488FAB8C88D2223 -:1072B0009E63D114CFAB22E3136B9B6BF0DCADB6B6 -:1072C00089C7FF45C4C555BDBE77879782A6EA1713 -:1072D0003FB7833C38DDB6C10EF0A4FD615CE1F53B -:1072E000E7255D7C54EFF1C02E7DBC61D3E33CDE2D -:1072F00070523BC9EB196F781AFE01FB4D6A44BC12 -:10730000E6C6441EDF1D282C8EE2CFEFBEF7B3E5A4 -:10731000EB351027DFB1EDCC1A987FF55FBF5A032C -:10732000F14D649F05F729CFABBFC5B862B5DD82CB -:1073300054466F9D9B7E8E71D99D9F9AD0DEE9DC6D -:10734000DB9E05F16D9D5BBF4B01FFDCBCBD37A033 -:10735000FF72DEF6A2541245DEAB29D0A7FF32E25F -:10736000C223F171B0F920C6617DF98909E55B7727 -:10737000FC68530D8BCB5578DCE8E6E871F86A9C25 -:10738000636DF3AD375F07F2BA99E977DD718F97D7 -:107390008A17FD90E2F5EACBC0DF661E17DC3429C0 -:1073A0006ABCE897F00F8AA79FA5EAE345BF6E9EE7 -:1073B000F3B317A1AC39B1D778D1C065C04D8DF307 -:1073C000AF4E75BD9A0A7CB42DD69BC6F0E69F28B9 -:1073D000801EF87516DC8F382587300E24B4D7E46C -:1073E00080B8C7CABD1F23BF746EFF00FDAD84C740 -:1073F000D97792EE3F160F2DF075AEB7B138530E18 -:107400007F884355ECF89DC79B323A56E3507B8BFF -:107410003F0DA6F2FBC3FCDE410DB59B589C7A38AC -:107420002E551809F83AAA8BEB55D71DD99F83CB57 -:10743000D1705C75F4385F358EB027BED8BEA2C659 -:107440004D77AEE5F1D6F47BE630889363FBB9C7A0 -:107450002F7C1C0DBF6A5CF5EF23F0ABAEAF37BEDF -:1074600050F9F352F3FE7BE1F26E2AF367ABF0E9D9 -:10747000F8737439FD0DE7776AB77E9DAAB16F671F -:1074800070BB55859B3ADFC54D4CAFE8D8C8EC873B -:1074900048FEA6EB71458BB397D298FE5BDBB23FFB -:1074A0000FE450C7815D9CEE185DD76E3ECAE27452 -:1074B000A9DCF66BE536617EE4C8FEECBC3F4F6BA1 -:1074C000F4FE3C9BCF46EDEFB4E4BA13E67FBA8DF1 -:1074D000E951A79BC409FE28FD5FE0FB52F7BA6D96 -:1074E000468C9712ED31A84FCDB38DFC242E095256 -:1074F00023C6FD342CE071428F38D300CE0DB69BED -:1075000008CCE751808FC6FF203BDC04F43839AD4E -:10751000B84054C2F355CB8D4906E2D7E25F0A6406 -:10752000827C3F92DF2E437F9F45F84D3E93C8E219 -:10753000543AAFCFBC827381D2BBDEADE6DD0F8B98 -:107540003A3F47AD297404F477F28605FDD6E23E52 -:107550008B17FD666B2CB8CE83DBBF7D05E0D5F9BC -:10756000331361E7089430A85C28E3FE8BF6EDDF67 -:10757000AEF913E899D0988E5FB686D607FD7A7378 -:107580002CDA035DDBE2F2509F7CE3A1C92037CA0D -:10759000600F033DEFF5547F03EDEF6432CB9FDCCA -:1075A000D217EF13546DB361BCE1C1ED3B6B41FEEB -:1075B00077BE1E0BC7D1E44B39F857C87BF6C49190 -:1075C000B50AEA818A76BFAD2092A2D5F3AA20AF90 -:1075D0008B7F2168A7A33F8ED273554B1CDE1FD132 -:1075E000D4E3FCECCD60F7650219C077549FD48DCD -:1075F000A396DF96D69FDFEF0DFD98BDAFC0EA7B67 -:107600008CA15296F76530BE6DC3FA252ABDF2F201 -:107610009EFDB2FA33D2FAEBEAA9ED6B4DA42E1A15 -:107620001F54A709FC7EEF5F06477BCF22CAFCF1FF -:10763000FB0302F11A400FD86AC138AE6A636010CA -:10764000C4B7EF30B2F3916A7B6010C4B7EFE1F2D8 -:10765000AF3A86E6E9F70C3E0FA80F79620EBE0638 -:10766000F8AED969214BC17E7FC3E6023CD7ECF866 -:10767000F6E44B0510CF168B7EAB9A37FE1DF15FFB -:10768000630A4C07FA0F6D359175B47EC7D677B291 -:10769000408FE8900359091739F7A96932E9CEB14B -:1076A000D5759CAEF70F84FBEBEABDC5CA5EE4C599 -:1076B000DE34A68F2E4F733D9D867C6D75A0BC86F3 -:1076C000FE44E8A76580F65E73A5125D8EAD4A9311 -:1076D00075F768C5F03DC555D0EF9724B83883A23B -:1076E000A44608E1F979E5C6B343C11EFEECA757ED -:1076F000E1B9D667C6D05090DB9F6585866AE5F113 -:10770000A97AB322C9E897C0B46BEDD9D20C02F1C3 -:107710008396A9D1E4D396B4589C47E5C3B151EF01 -:1077200083EEE6F4B61A6830998D0B7E0875DCCFCF -:107730008C7E23CC23375DC1F2CA4CBF11BE576D7E -:10774000DC3540F7EE84E4C37A94BF101E156485DF -:10775000B1C0DA53AE54CCB72A12DE8F96FEAB9B83 -:10776000DEC4309ED0C909716A1C877467423FA885 -:107770007A1F40928BCD002F2329764822A0DA87EA -:107780007C1A439A30B5527584ED437504E28A4EF3 -:10779000F1F35B93A43C0DF2C3744844797E29B89D -:1077A000FD32CD8EF3364975C4897AC74407E8D5D2 -:1077B00082D74DBEA7F4D050BF71C00976FEEF82CC -:1077C00038383B61F3B33BDEFE0EF4034A6768676B -:1077D0007BAF27FE063A9E6464793296F8A39DC774 -:1077E00077703C10EF7E943F5612FE0BD17C2C4AF2 -:1077F000283A6EDC5F47829D6B759000E84DB1566C -:107800001288A5A935573AADE55F3B61F9FE949C16 -:1078100041AE39AED59747D235714AE7BBE5A2886C -:10782000EDCF47B43F7FB1F62A3C3CE601D9ECFEF0 -:107830003B834B0C5F8377ACF34210E09167773664 -:10784000001E8DA1230F013CF2ACCC4E4C6A245A91 -:107850003B6E403A93578B04B65FD2BF62ABA63FF4 -:10786000E230A3FFF4710EF7EEFAAA5FA5477D8B15 -:107870000470ED51DFD25BFD98E8F56DBDCD273684 -:10788000FA7CE27BE9DF1BBD7EED1B1FBF1750E0DA -:1078900023931B1231A8F7A007A483BD157724A555 -:1078A0008451053B2788C05B0CD01FA58798819A1F -:1078B000EFF07FB91AFCF58F827F1240BA2BE1F30B -:1078C000A1796B3A9DDF5D7CBAE3D6B373CC7BE6DE -:1078D000313FD25D0FB3FB42477FCAEEEDDFD3C825 -:1078E000ECED7BE6B3733352CEEE0139E87F30DE48 -:1078F000BDD009C5F7BD3EC11FC886777022F4D739 -:10790000EEF7761E90A07E49843F46A527F5DED28D -:107910002CAE5F6773FA9C434236E0FBC87BF4CD24 -:10792000692C2E8D9A632E58DFDD7C7DEA3EE05D6A -:107930004E72E05D00D110E384F31191DF5B257698 -:1079400023BBB77A5B824EFE9CCB51E260BF236FB4 -:10795000F2EFFC3DA2B9372AA9DA7B5ED285587CCA -:107960007FA44176A6815C942FFC8828942F8C17E5 -:10797000061045730F8DEA77C8ECB283A01F4772DB -:10798000149332D00BE3399D25DDD4AD87BD4FE193 -:107990003277B982F760EF4C67FBCBD28CE239408B -:1079A00017A27DA4D36DED8957EF76B6BE06585F5A -:1079B00076CF7937189D4ED4436FA21A04FA7B9C78 -:1079C00066988F68523E56803F7F2D13B0FF7BC272 -:1079D00081E1F35C52821FE25F66DB971E01BA5DB4 -:1079E00056EFC073B425F539982EAD4F433D7471F1 -:1079F000BD1353152E66A7CF2552389B07B2FECC78 -:107A00000E37D333E83E04F11792A32E0079736644 -:107A10001D01FDD7D20D1F1FC2C7D89D7763DE049D -:107A2000799ACA8D1311BEB43D29033F6A867B192A -:107A3000C0C7A25C49140D5D98D286E9F23DE0A66C -:107A4000D2C71606BF2705461F91F07B526E53E042 -:107A5000FCF9C91BBBDFB541F851759FC1EF57EC6D -:107A60007CAE57F83912509F9D5DB8783AC4553FA7 -:107A7000C1CF211FAB1F89F07A1CE2BA06837DE0DB -:107A8000C25404F8513A32E57A8948DB9B143667D0 -:107A900093B5D8652860B40BF013AD0C9EA6B43A2C -:107AA0003C8F335B19BC44AB17E1225B19BC442B00 -:107AB000A33723CF4B00BFE1D81EBF53F835A78FA4 -:107AC000003C8CD6C1CB9834F6F2E0B792C28FCE90 -:107AD0002389F357241C92E09E426E98AF7AD3EB31 -:107AE0009EA3EB877DFC050A1F48937BB11F933350 -:107AF000981C4D32D4ED97011E0984EF2F5E9259E8 -:107B00004858A822FCA57989027981CD83ACD7E3B6 -:107B100055744811EFBE292F001DAC784736C03987 -:107B2000A938FF47BAFBA4E25457BC82F0740BB0EB -:107B30003F3F51AF20FE96031E07C3FEC8ECB1477E -:107B4000393E1F033E41FC32FE7892F3CBD39C4F6B -:107B50001A9CECFEC4B2092C2E2B29DFC0DF430B8C -:107B6000106DDC53BCB38918E9BC50C756300DA06A -:107B70009EF189C97F056D179B4B5C4027F19F3CA7 -:107B8000E8C7B592E274D08BE2B9FE4BAE55E2A7DE -:107B9000E145DA80C4EC102A0AD1AE6933447B0790 -:107BA000ABC179C00C7ED3DEE6B37FCA0EA4CBD2C4 -:107BB000AB313C9824BA8BA7CDA1796B632CFA0723 -:107BC000639DEEC24781CF1B6D48A7563AFF320D29 -:107BD000DE637BC1EB8B19371A32281D8AA0B451A2 -:107BE000FC3ED338C002707E4E2E4E07F9FA1CDFE1 -:107BF00067290E14ED3954079793F6822B75F6EC2E -:107C00000AD985ED1CD7EAE5C00A2E7713C6E9E943 -:107C10005D95BB1F75CB5D7732CC27E5C238E4C7D5 -:107C2000A45BA2CBDF06D9E88577051A86327EF7FA -:107C30009618D97D989EF200FDDAE7DC83D6813C68 -:107C400055E96B2161F2C74B629CB81FF177745400 -:107C5000FD7809BC37C8E52CA4E24023D24DCA3DCB -:107C6000068CCF5BC6DFCB7A8AD217A43E4A5F90E0 -:107C70005E97C1CE33169A87E1BB6D0D5603CA0BD2 -:107C8000E95393DF0AFAEAFE510EF02348B2B3CD6E -:107C900005FE409BD4B48E40BD0233BC2721C417DF -:107CA00038800EBEB1CDEE77B1383C8A4E01E8C8BF -:107CB00091544C8EE5E2E901DE7B911DB710F02B6B -:107CC000BE90546701B8E56630BBABB1A410E14883 -:107CD000E13B362339DC4FEAD49BBADFDB826E5FAF -:107CE000E8E5FECCE40CAE47677AC9400DBF370A21 -:107CF0005C0F53BC2447C3F70BAF184FE05CA927B8 -:107D0000BFF722CF363079B648882ECF54FD539531 -:107D10006772849C50D3C5FD26E8EE7719939C408A -:107D2000BB907A0D144592F7EA27EF8E4738CC02C4 -:107D30003890B49BBAEDDA1FF607BDB2302ABD45C4 -:107D4000CAB1D9DDFBBA2B05F0744A5652A7013DE2 -:107D5000BDD3DBBEEE2A453AF4F551605FDAFFCCC5 -:107D60008FD0AF73E2199B0272A8ECC2E3B83F94C4 -:107D70005E18856979E38DB89F0BCF4E2A047A6827 -:107D80005F7543DEA7E0E7F1D970DF6E6F2C1A84D0 -:107D9000E791BE5805E23BDA1B697941B81CE2C5A0 -:107DA000454DBC0001EFBBE6FE372950502F55DF93 -:107DB0003DA3769D7D34F885568B782FACF4599B86 -:107DC0000BF4CFDEE8AF7455747F00DE614AC70163 -:107DD00073408FDE6F1F1D0AD07E67AF63E7080D0B -:107DE00046D7C900E84DCF58F01CB22121FABB207C -:107DF00073326E580672604E86EB39C49395BD534C -:107E0000DA3B3FB0F14FC221339C63BDC8DF4791DD -:107E1000DCF629BA7336768E7592FB5988B997F2DB -:107E2000185EAEF4526E67F122C411BD5CB53362C8 -:107E3000C3764613ACA3A6F1CCE24F115EDCCEE0D4 -:107E4000F33E25B3799F7AC5E45F1885FE4FF1F8BC -:107E5000940A81C157E58353DDFA911BDFC389A4DE -:107E60005361DD901746D17EBF3A24E3BE514DE900 -:107E70000BE96ADD288C8F179E19F534C40D9F3FDE -:107E80002C6279E5050B96773CE27C01E29E42EF9D -:107E9000CA04E4D3F94337C4313F91DE8F7D6F1FAD -:107EA00026178E71F9507AE109A4DF6E3AF1CD31CF -:107EB00002FF955E788AD1F74601DFAD24DEEA77CE -:107EC000C70CE4F4391ADA574C5A08F0BED687E7E3 -:107ED00024651B4C4ED00722F17C2C43D1F93DCABE -:107EE00082CBB05F42F5AF24CD79FA291E675C766C -:107EF00081BD57481C5E9206FCC0E553988EF5EF95 -:107F0000D07658A2FBE9CF71FDA7F4C2353A3B23E6 -:107F1000BCBEEBF17B29DFFFCB82A3301F5ECF0B12 -:107F2000A3A2AD27BC8E6BB17E477CF4F1D3399C04 -:107F30004FD6971317956FE54656AFD4F78011E4E7 -:107F40004EE9AAF80441B3AEB2C62A5D9C47D9AA4D -:107F500012E34C4DBF613C2C7E778C14C643FA4B28 -:107F60000B262DB4825E502CF7017E5A5751F81320 -:107F700005FA63F2E90BD99705F2BABDF17E7BB43D -:107F80007B13E97D22F0D3C8F143F5EA020D7E545C -:107F9000BC44B63FB9B6ACF027E08F5EC95E21E9BC -:107FA0005DFE44E02D3B3ADC8675C32D07E38D2E44 -:107FB0000DB7AB7471453DE0C6F1ABC245FD4EF562 -:107FC000A8ABFA8C80F108BBBFD3C8F07F297885B5 -:107FD000C7E5F81F137D1D53BBD7319F7829A3CE6A -:107FE000BEE43A1E225EF345D6A1E29FBCA2C3FFC7 -:107FF000D497D6221FAAF89E7D6025D2EF6CCA8F37 -:1080000070DEDFEE7BC01E2DBE686A6F781FE8252C -:10801000B985FFF7F0FE85ECCD82B832EF720BDA4E -:1080200023A7D63D91A585F39C8C31F7025EC8FA53 -:10803000E4CBDA3FBC639D87C0BEF43E23A33F6D13 -:108040006B86BB0CDA97733B7C51FCF841D1F4830F -:1080500047EB0F0D013F5D437D1BA632D72F09E88B -:1080600097D9A82FB9A2BDEFB5A40F932B8FD6B780 -:1080700031BFA7D94B1CDAFBC484E94FFF4598BF39 -:10808000466D6794DD0EF09F1A05528C7A9FE45E70 -:10809000925D007E8FA47CAF067E8BFBB0FB48CB4D -:1080A000D20E38E03EB189F60FFE1C73A6744E7FE7 -:1080B000CEC9F2F9C2A722C437CB494D04FDA1B9FC -:1080C000F4BB06DEC6A4369D7F3A120E92D98EE727 -:1080D0004D1261FA9CBA7EFA05F7A5C7F8BEB482C4 -:1080E000FB359FAF6F42BFFFC2583BEE7F8BFB1942 -:1080F000983D6596F0BD1A533CAB6F8C63F3B68028 -:10810000DF5B847D3580791BBCE823E2D36802E421 -:10811000E38922403E910416E33B2963823F86EFC8 -:10812000CE34B71FF0F84D7ADB1101FCD8C5EEC193 -:10813000B0FF368ADE7C85D6FF9918CA877A59B493 -:10814000E8930496F6837868B7E65C8BBD13AA685B -:10815000FD8291F97EF3A588F39E3F0FD6962F4FAF -:1081600073BD0EF368B0B07786928E0B789ED360A5 -:1081700061EF0D35D8EE88837DFC577D98DE8E74D7 -:1081800000747488E933E724252E81F94995377501 -:108190007E7EB3F2A6661C89DB7BEB295D4A9A736F -:1081A000958192CB007473858F7ED7CE338A3F2E14 -:1081B000C18ACFF2463DCF51E70771FB0047F1C2BC -:1081C00078B4D722E9614FB79FD92B023EA7A9EF18 -:1081D000174B8B583E9EA87F687F7DDAAD8F2E624D -:1081E000797ECEE999C9CE311B4AE2303E4E9DC719 -:1081F000B4D6C7DA404F9DD69A3E0BCEB7A65907E4 -:108200007D0EE91E39742016F4C00704BC5772D7DE -:108210006FDF946369BAFDC375789FF9732E4FA71A -:108220009310BE0BEF260E7ECEEEC7EF338993E799 -:108230009B64B0EBEF09F86F9F4473F7BEE99F04AE -:108240006ADBF443A1B7400CB89B1CE3F10C416D11 -:10825000D7E27C9BE559BBEEF54B665C4F78BD667B -:108260005CBFBA3E3A53847F377CF87B4D2A3CC4CE -:108270009974DD945EA6C5DD7113B9885E3ECD9A12 -:10828000F3393B3461F38984CF7928A2FA63471F1D -:1082900017C9A4F8FB7D1F970069B5399425F547E8 -:1082A0003E91215F2BBAFB41E8F3977DDD8393017B -:1082B0000E6D8997253F8F5818FF1F017A8638AFBA -:1082C0000B49B82EF51DFA830FB6DB40EF5CBCFD01 -:1082D000637C67B9460C3E7927FA4345B49BCE359B -:1082E0000FBEE8FDB323E0A7A2FB5FDF4CF59E25A0 -:1082F0005BE70C89F1C98CE6588CC79F315FD4BD10 -:10830000233D633E8BE723525BDE6D3A7D7D51AFAB -:10831000FD80BF20B29F59F38BC8F1E1704EEB187E -:1083200083FE83358CBE668D738910EF3C7A89801D -:10833000E7ADA34E282D419A9FE58F77027BCE7A39 -:10834000F03F07C03B07B56DCC1F982ADE97FF08AA -:10835000F8590EB07D1CF2F7019D585D8A55735E89 -:10836000D021D7E5C37B7FDE7BAD2EE0FF92DB5CC7 -:108370009FE27BBEDC5FA1EEAB3B1B4B304EB6E415 -:108380001E6524E0BFA4C9E2C2D44CA4182AC74A7F -:1083900024628634D548240BA431C40C69E142F62A -:1083A0006E7769E314D40FEC238B8DF01E6F49EBCD -:1083B000CFBF86F6655260BF9017864F49EB3BDF13 -:1083C000015EE7B88A319EF1AA8D469D1D38B449F9 -:1083D0009FBFBA459FCF0FE8F3C30FE9F31B3209E4 -:1083E000D2D14CF3ADB900AF037B4D742F82F83F6F -:1083F00013C6BB1C13187EBC9B2C280F8BAA5A0BD0 -:10840000C10E3EF39ACD0076F49EBFFC02CFC3436B -:108410005B6209C459EDFF5D0C898178C5D72DEBEE -:10842000A0BC8AE20EFC9755AF5BD6821DBEE34A24 -:10843000D58EF7E7C17A76FC95C5D7843699FC705E -:108440003E7E66D7CF5F83F3B4339BFAA07E754C34 -:10845000F01A6260FC2F98FF33C8DF8B0BF2F7E253 -:10846000AA36EAEDE2B9994CCE04175E13174D6FA8 -:1084700052D39CB4C4DC71746E5D8F9B66801F68A0 -:1084800070A31E2E6ABD217EFDF78778FFA3893178 -:108490004CA7D91027E06FB0C3FEFB72F477921798 -:1084A00072FE79F5D5EE76227F278E289A7B53616E -:1084B000F94DE6F581F80D807FFFF0F72AA2998F3C -:1084C000463F99C0FBFFCACCE29993F8FBFDA7EBAE -:1084D0000FE1BEDFADF7D5BB5CE334F9D2C6FD29B1 -:1084E00025603FADDA9F325303AFEA4D0753EEC626 -:1084F000B827093CB8A47ADA2B4F81BFA27A93D867 -:1085000004F38472805B47D35B76A847F5E161E0B2 -:108510000709EBA337B8C669F8F86FA55B95DFAA22 -:10852000B9FEB27364DB788853AF6A149C50ADAA6D -:10853000E9F65B2701BC57B17BAE85122916297F6E -:10854000556FBDFD4743216E66F50827CC877671D0 -:108550001B7CAFDA7C16EF332C8DF8DD0335DD9D07 -:10856000C9F4425A3F60A0F597DE612D07F945FB3B -:108570007D13F20772D6E1FB2AF653ECFC817EFFF5 -:10858000C440F5965363BDEFDD4D9B9E214D1F4DBD -:1085900002BF52A39E1E297D0BA097853608CE757B -:1085A000F87561E12DA072BB1660BC2F2D9F11EDF7 -:1085B000BE75855FDF4F24DE3FE2F3A57F395AFAAF -:1085C00089AC9738D18BF1E4D5F3A93CD4F809AA4A -:1085D0004FF8F07DC9C8718896AE993E41149087D6 -:1085E0005B2CEAFB4782B990C7E90E60797C571192 -:1085F000E894124AD595649C02F0BE854C80743490 -:10860000C815784F7F64531ED4DF2D045F7909FBB2 -:10861000B3A11CEF7004F09DC90C7ECFB44361F987 -:108620002EEEE754CB2B5B2D186773E64B23CAD98C -:10863000054D07318EBEE3358BC140E5C199AD894B -:1086400063211EB3A389BD537CBA2971ACF122FB0F -:1086500076A4DC50F7D3A3F04FBAEFFE29D3F54D43 -:1086600026EC538B58BC6A6A625D7EB4DFBF50DB78 -:108670002519EBF2C18E09DD6B75AE433879B32550 -:10868000F483A739214EA84460FD1AFB158B7D6940 -:108690007D1BAD0BFEE8844322FE5EC371D1F963FE -:1086A000C7007C4F1EF5A0D9056E7C9F922C62718D -:1086B00095B324129028BDCD82FD280FF32897672B -:1086C000AD1230AE6CF632FD7AE09D5CED3E5A4163 -:1086D000FCEC7D0BAD1FB13FC4BBD0FD06DEB53455 -:1086E000B3F88BCAF5FA76552480F3A9DEFCBD29D0 -:1086F0001ABCBE26EABA5C99B02EE11633CEEBFE68 -:10870000E7E2D8798F91B8603F0D3D6743F95E4548 -:10871000DCD8DF5D7C5FF73C58E29A0D7278FE2C66 -:10872000D7EC44B86FCBF63F34F990BF05DC77AA9D -:10873000C691405FF6EE06817DB5AA55080C85BC52 -:108740009978EDC3D877787F00D6ADBD5F534E7C66 -:10875000385EF92AFD77F221C36B35BFC748D66B67 -:10876000CAFB837EC6E051BDD9A4F3EB8CDE2C7826 -:108770006D78DFD5DF9042E7577B8ACA0A0271AA7B -:10878000DF9B74FD433CCF08DCF78985E2EDB96ED1 -:10879000B9EE1F122DCEFF0887E373B797A603BF6C -:1087A0003E0D7A6B0607F448945BDC7F4002663A24 -:1087B0004ECCF0EE3C96172E64F9C9AB5F99DC788D -:1087C0002DB5F364379E0BCD128BDF86FB602FF740 -:1087D00073DFD2978E33CBE0CA92906F5D83D01F48 -:1087E0003A9FC1E185617543EAA2E8812A9E9F17FD -:1087F0009A02702EEBDDC5F42F5B4148D6EEAFD563 -:108800007D993C8A3B10C47B13A1ED02DEB35C2949 -:108810001CC5FB882B6F5408D8F769144F208F575D -:108820000A649140E152D03CE5BEB700CF05314E1D -:10883000F8B98B9AE631628D15D7CFF4B4D8BAB5B2 -:10884000709E933A236718D0395DF78C5BE8F7FB8D -:10885000FA2A385EBA95E13D6DA1371B7E072AEEF4 -:1088600040F17D6F011F0E8DC17BB2A91456B60475 -:108870004C9780FE9546160850EF393BEB3FD920C8 -:10888000CE9802F9612C9FF0B0E05A87C4B71CFB68 -:108890004F359109304FF80E7AA419FC0A58EE674B -:1088A000F82DAACB87FE5207B034C918C8847E0EB3 -:1088B00077E3DB8D76C53CBE8FCDDB3A2615ECBC6D -:1088C000C31DD4E0A672EB709AAA0F05ACF8FB505A -:1088D0000373587D6E17CECB67F70D92B2F4F5BADD -:1088E0006457DC7090A31F303DFEBCD585FEE96B5C -:1088F0008CD1FD592FF5657A8BE78240FC9A7DC0BB -:1089000033F51BD42B3D1724DDF78E7AB32ECEB969 -:10891000BAFC00DEBBAF216D18875DD314AB8BDBD7 -:10892000BD2626FAB82A7D7B2E88C41B755CA3FE63 -:10893000FB8544E24D8C562F45FF9DAE43976FF962 -:10894000B67B1DF09D8C0CDAC11E9CC8F5DA2EBFDB -:10895000C12B5F1DC64BA723A8DB773A1596EFE224 -:10896000E7716AB9DA7FE75423BF57C4DE5506F8CA -:10897000780713F262EB59F44757B7EE1FCF7EDF4B -:108980008BD185164E5E8DFC4869680B18286FFFE9 -:10899000A6EFA9A7728750123BA0F2F1E9A75C9459 -:1089A0006F5344838EAF630BBAF91CC5CB7306912A -:1089B000CB85334F8DBB569B67F5C3ED3B268FA30D -:1089C000BA7D412E6BFF87BE5FBEB77060582ED157 -:1089D000756415DB34797344DE4AF34335794744D3 -:1089E000795244795A443E93D5EFB005B2442721D9 -:1089F000ED7DCF4E9646C13976603ABC28B0ACE1E9 -:108A0000ABC9E368BEA6A00DE3676A5B05271EEB52 -:108A1000ABF1F14EA667599D41FC3DBBD882B6B77C -:108A2000410E54B7080E81D2BBB5692BC6D554434D -:108A30003B45D3AE89D99DD54D47B15DAFFDE71814 -:108A4000909F97E61CC37AEAF9D19DA4FBF73A2ED2 -:108A500080BCAC696A67FB70C4F95167BAEB20CA85 -:108A6000C388FBAF1EE8D71AA67BB5FEEF87B6FE1C -:108A700016BA899D77768144EBFFB1A67D04E84B59 -:108A8000F0C625C8FDE705FF10D89F5F24EE21B092 -:108A90001FDD5B73C57E03AD77440EAE86A71A0655 -:108AA00065596E96A89C3E620BF615A82CC9599381 -:108AB0007833C0F34872105F68F8E99A2456DE37BD -:108AC000D817CE5D73B37EC8F257045743FEB63550 -:108AD00057B2FCD0605F91B6EFEFBDEA6680FF064B -:108AE0004774BEED9BC5E4B93ABFB27C575A16E84D -:108AF0009BD56CBF80EB97662A17A7579EDEB28185 -:108B0000C261FA4F62515E6DE8B8F5A6625CBFB70C -:108B100018E2DCD813EF7C3F43B92CA11E900E7BEA -:108B20005842181FB6AC3605E5FD95755B61DF4F01 -:108B30009D9E8BF2FE7CA6AB3E6B4438FD76004BCF -:108B4000EBB3D87D8F54D180F106A90FD9500F7A9D -:108B50009A9F2751BE41FC5A393E866531F9372C20 -:108B60008BD949197D6FA887F5DCC5F5D3158FFB27 -:108B7000375928FC7F07449284FE6DD477EF5E4B13 -:108B8000E5461CC453B8D2411EDC0DFEDFDC705E2E -:108B9000D5DF57E4D3BC356CA7AD98E24AD7C60100 -:108BA000AD58CBCA5579B3229BB557F79DD406066D -:108BB0009FD4A787AC8375C44A04EF5FCC993A6809 -:108BC000DD02DCBF6FC1F912972B1DECEF1315FD11 -:108BD0000DA057AAF8792CDF3511D723B278751577 -:108BE0004FEAF8F57CDDB344BAFFD3753ED4CF8DA0 -:108BF00070A4FA401E0B2E60FA403D386293C3F019 -:108C0000255270047CFF5F04A7FB60DDFF289CA257 -:108C1000C88B9FC2B835F3A9BC3068E40587DFF381 -:108C200042404E2DD0BC5F42BF831D78675FF7A3E3 -:108C3000599A739CE90FD5A0FEA7CE2BF6DF774E8D -:108C4000B893F4E4B348FDECC8EFCCCBD00F686C1C -:108C500042B978E426E25C00F2839FCBAAFA65E190 -:108C60004FAA0E831D752E4BC4761615AF42F1D652 -:108C7000520AA7C7E9B60AF7D1BD53587C8FBA6F1D -:108C8000AEE0EFEEAE78F02A8CF3EB2241FC5D36DD -:108C9000EF4882F2AFBB7CDA202CA7F8F65A80DFCF -:108CA0002B62F0770756E413BC67B362DA9558BEBF -:108CB00047F52B4D33E3382BA6307A5A51C1E230B9 -:108CC000611F01B8F5460F290DCCBF4124579E36D0 -:108CD0001EE05D8EBFD882E0F68F41AF5C6641BD7D -:108CE00012F64E3C1FF1A5E27814AFDBB390BED96B -:108CF0003C663D9BEE5F8AE33AD13E7FCCE62A415B -:108D000079F548AC02F35F65214BCCC3C01C218BC5 -:108D100050EEF1F910DF0B18E73183EB6B9F959F55 -:108D2000B3813EF02697374030602FCF24AC7CE6ED -:108D3000C3B147C1BE99F9B088F70BC9921B5CFA61 -:108D4000F30E3AD714F08FF3BFC6900DE0E08676AD -:108D500076E8FFBF6CF09E89FB6176BF9778697BF0 -:108D60004D3CF4C7C0BFE06717D9FC497DAC12ED9C -:108D70005DD08FB97CA7F37769C753C789EC97DAC1 -:108D8000779F00BC28DC03700F2CF488C87FAF5598 -:108D90003FDF2463E8490B2D9F5E2FC62FA4F0749C -:108DA000CFB7E17AD5F9CE480D5DC77E1756DFFF04 -:108DB000C9D8DA42F087ABF60879586F8F815FA285 -:108DC0003B2F629C34DA353DBE737B36D20E24E4F1 -:108DD000AF266DBDEE7B1A8A10317F4E578A200177 -:108DE000DEDC3C7EA11BDF11F356E169E8171D9E16 -:108DF00049C6605F905BEEF9268443647B75FF7B18 -:108E0000C142BC6027360A02D263E383B1B89F1126 -:108E100033C3A3A7324601FA7CD118C23826EF6EBD -:108E2000F6FB9F5D96D00E944B03993FA1EB3D71ED -:108E30002DD4EB4C6674DDB94BE6FC44D83B12EF05 -:108E400089EBB05C60FD762E88C5F828B8FF698490 -:108E50007B99DE3FD5837F45B5E38FEF60EF29C077 -:108E6000EFF668ED60B8375B3E2C2C1FF07D18E004 -:108E7000E79658EE277257E07877C71088C3A83571 -:108E80000818D75B5B7925DE2321FC1DE76A3EB518 -:108E90005A03B5078785F9BCD6706C10D853D5E650 -:108EA00065F8BE332D7F13EC30F899DDEEDFF1C8A5 -:108EB000EE49D7B5CBCEFC05EFB537EBF15F1DA67C -:108EC00013BC1F57A9A59BEC303DA0BE0D72621CC0 -:108ED000C17BF9369E8F9DD0E6073F8D87FB2D9293 -:108EE0000FB0776B6D054D04FCA69E534CDF18DD6B -:108EF000BAF620D8BFF113DAC0E2A2F599DF2DF25D -:108F0000FED0A8D6E522D875AA9EA2B12B87DC3266 -:108F1000549BB2FBB660A7C27841F804FC21B1FDB6 -:108F2000ED79BEBFD17D10E5F11CDF60DC07619FEC -:108F30000239A6DAB920D7408EBCDC6FECD47E743F -:108F40009D79CAD85BFBB1739821A8D77B2FEFBC62 -:108F500049AD07F6EEC5FD610C6EA195714C4EC092 -:108F60000F80829FF8D7F25A7CD71B042F9DEFDC2D -:108F7000D5D92877553F4D35F7539572BF4E29F710 -:108F8000EB805F551BF70A7E4B6DBE9AF37D0DFC9F -:108F90009E14BE17600AC7BD823F671C09D8A01C7B -:108FA000FC3A7676BF4EDBDE43FC4512D2F9F7265B -:108FB000DDBB582BD87A6770BCAFB4307FCEE88762 -:108FC000D78ACC49C5D61B37CC95FD6841F87DAE14 -:108FD000CF399E54B818FB8DBD17E01E23B2F7CDD4 -:108FE000438FB2DFBB3E41F7E7ADDCDF718B15EF9E -:108FF00017BB06425C82E4C8BA25CAEFB62EDD6D07 -:10900000C177FA97F563E7C1EAF7B1FDD8FD5DF4E2 -:109010000301DC17C4A29E4DC19C077454D85FDDC8 -:109020002F491EF89F8EF2F8CEDA3BAC6EE82FC8BF -:10903000FDE22BFBB17D6B653FF6DEBF9AEFB6EB31 -:1090400038BDA8E758E08FD1FAAFFDDDF599FF44B0 -:10905000DD5F9FAF8841B914A65B03DE9F8CCD2DE9 -:1090600036821F6937972325DC5EDF0D07B4204F5A -:109070009AB8DF59724C87DF05DA7D2A17E325930A -:109080008C4CBEECBE2B8640FCDEA1D3AF3EF11E65 -:109090002D3F77CA88EFE1CDE6FED6DD0271C178BB -:1090A000DEED26F423561B99BE58BD6F28D3538C92 -:1090B000EE9510D7EDDD26A35FABDAEEDFF40A966E -:1090C000A73B2966E13E28D37377C5B2F631FEFF90 -:1090D000780DECCE7DA94E2FAD3F3FCDBD0FF09A60 -:1090E0006152E2887AAE2A84EF8B1EF333BDF81802 -:1090F000081E18A7D5C67F47CE953E87F673FCF1AC -:10910000545C0F95B7A83F1D7FCA84E766CF778F61 -:10911000CBFC9FC7E4627C2FE6D8F67C27B52C49B0 -:1091200057B13100FE6DCFD34C9F9B6550D6007C6C -:10913000C8BE58A7CE1E7DAA8CBD1F51F9F0E48B86 -:109140009D63837CD7FA773B49280BEDD1F2FE4D26 -:10915000104FDAD93AC4C98EABD2F090A4969F2FA3 -:109160009F90197C437B65A4E7CBED1FE8A2FB77BA -:10917000EE4482BFDFA63D4F8B3C87E8996778F4C9 -:10918000EC4EE57A9BBEFCD64C7708E45BED33DF12 -:109190001E99AFC078219487C4C7FCE92764D774AF -:1091A000A0DBF871015D9C9659617C35CBC4F77BDF -:1091B00012306AF9502D2F1C4BA29EDB9814A60783 -:1091C000D8F8B97364F9FF014BC990C00080000062 -:1091D000000000001F8B080000000000000BC57D90 -:1091E0000B7854D5B5F03E73CEBC92996426992481 -:1091F00093F7C93BE4014308112DEA24040C98D2EB -:1092000009A062B538BC41C943B0BDB1C5662011E3 -:1092100002A2861A1128E0848762D5367801A34617 -:10922000EF8048B1D5FBC7475BB4F7F78B4A2952AB -:109230008188964BEFB5F55F6BED7D92394322D86F -:10924000DBDB3F7CB0D967BFD65E6BEDB5D65E7B0E -:10925000ED1DB36A602C81C1CF4C334B64EC1AC650 -:109260007F324F316FD0C6984555A9FC9A5321D310 -:109270007CC867AE0C991689D40FE909230B59CA2B -:1092800021DD620FEECCC2965E86FD2C9A00FF8532 -:10929000A68B64D66629C3EF6A4FBF8BB193079C38 -:1092A0009EF5F09D7DF995CC2A189BCB443D336B00 -:1092B000B7C431F67C9B14B240BDB99BCD3BADD059 -:1092C0005FC56AAF6C87FCC076C9B313EACD6DABDE -:1092D000CCDF02F93BF7977A64681A83E3603EE8D3 -:1092E0000CCA50FF9AE649ECE3718CCD37074D0A62 -:1092F0007C674F4B6C0FA3FEDBB0FF65D02819E0F5 -:10930000F90A7FAE1F4A176F36C364F9DCBFC27F0C -:109310008261F96CE8B7BB4B66305FB617BE170EBB -:109320007D5FA6840E49318CD57747B4677F330FB4 -:10933000D643405980F0E832B13B7C369A74525D96 -:1093400029637FC0FF263366CAF48D53C76326376F -:1093500069861DE65DC5E735B04F22BCD6B326133E -:10936000C37E3AE319BB3A6C5C0B0B45437A520E51 -:1093700050F922F3464A6BD42C1AEF4ED66F62395D -:10938000D8EF80C907E3D9FB80AE2597CEBF06F999 -:1093900060FCC87C3055F0C1B2532C742D8CB76C76 -:1093A000250BD58FE6A91DD2450A0BC4005E170117 -:1093B0000E62451A55C6F1AA160EE16569509F471F -:1093C0007CAA6178463C869737F67C650ECF279954 -:1093D00018B3C60DD119084570274D6A1ADB047001 -:1093E0005EB3322833985F4ABA77522EC01B5DCEE7 -:1093F000E7DB78DC6251C760DEC7B2A1DE17699592 -:10940000CFE54179A3C2BCDD501E0D78E982EFDBC8 -:10941000AD2C80FD3F9EA752BF6E13E75FA3E263B2 -:10942000636D4897BE9001E992C01CC88F1A3EB781 -:10943000DBA15D19B693A8DD607B0B6B8B0A6B5FBC -:10944000F5A29531582F175EB007CD509529FE4CE7 -:1094500027F497F87B335B0FF9B32FDA97607F67B8 -:109460008D6C7637D477C9ACA99BF8650DE1FF8781 -:1094700048D7F1C84D55A90C795F9A96CADC58BEF9 -:109480009ABED73B81BF86A1EF607956DFCD9CAFF6 -:10949000CCEA4E18EF82B3FF079807785800F2CB5A -:1094A000550E77E3FE49637F04DF1B7D360FC7BE91 -:1094B0007F2CF2AB59BEE7660BF0D71479E5C0BD3F -:1094C000308FFA749BC30C4DAA33FFE3B7B742FE4B -:1094D00093FD4666463AEF99349B655F0A87962E60 -:1094E0000D1A3FEA0F5B2F77EDD5E7EBBBF5F94699 -:1094F000A67CD4AFF101A0608B6A779D8C26D9E160 -:10950000F90AF8DB6C6E3AD505F09A5F327B56C1EA -:10951000E706D5BF03D7538361E028E2D99CF9E978 -:10952000683FE0A52AF3CBA3A988FFFB9807E1BE1B -:1095300060AD9C4BF4D862550361F2AB51F07F678C -:10954000462D95776E35AB122FAF1D0F726B092D1F -:1095500061AA623100FE1B374FFD441A4DE516A487 -:109560004727F029B57B4E0AAE82764B362FAE6583 -:10957000507E86054D1680E70F623D35CABD532CDF -:10958000F0DFCEB89A51285F94BF2A3EA4FF5AEC70 -:10959000EAEA217CBD34B83E2D1D27002F373289E1 -:1095A000C5E2BC9DFE97709EF5967E5325F473FD33 -:1095B0005FBF20B9BCB8F9D59C13E350DE78E71241 -:1095C000BD617E284716DF7B88BE4B332C04DFC984 -:1095D000745BD00CDF5FDD62E679A789F227B74BB9 -:1095E000945FDC2D052D5958FF627C25CAEFED46AE -:1095F00087995D8AA748BCFC71DBEF621880FC4745 -:10960000102DB8BE98A329C667C7B2A69819A58819 -:10961000AF1B3E41F9B578BBEC09A19C7ED9EEC9E0 -:1096200063989F3C6AA10DDB7F1E5F89F8DB31D90F -:1096300021D377D987728829DEBEEBE1BBB2E32A5A -:1096400015D7CB91ED1CEEC54ECB1348E7EBFF2AA7 -:1096500013FF2B06E6DF67433A7847E1BA53B7EDCD -:109660009982F8FD635D8A81EA3F2B3107E2C3D915 -:109670009C88DF174B8A0FD7D992CD4B6B59CC10F2 -:10968000DED7A832E1BD32736562BF8DF8FE66D4C5 -:1096900077F5DB81CF71FC19EFFFF656D710DF4B62 -:1096A00033364FBF06FB7FD248FCA5F5D3B8EDDBC0 -:1096B000823F180B019E160B3C993357E6E3F8974F -:1096C0005B0F8B5737E53B6C975F1783EB7D1BACCC -:1096D0008F62C6FEAA4AEC2BA0034B8B233D33D2EC -:1096E0007AD4F493ADD0C0F5BE8779F7409A64661A -:1096F0005E09E457769642E5D95926C287F297E586 -:109700007BDF04F89F53FDD15990CF64DEB1A86789 -:10971000D40147552CF4664306294738CCC13D2473 -:10972000E7200F78DA94C09E581F066786E80FD6A8 -:10973000AB0BFB39FBDE9747118F0D199F8E46BD92 -:10974000DD78F10B930AF4B4F54A24676D1E1F43CC -:10975000FE68ECAD630B4A86E463A387CBEF4BE472 -:109760004C9691CB33D700F533359BCBB74E275F63 -:109770009F5B9BA38228F7B6BA8256043ABA3CC0D4 -:1097800050BE4F2F973D08B666A7F82C9C5E16EF8B -:10979000AB4C467EF5C81E14F17DDE8FDBE221FF67 -:1097A00066F9648F0C799B77577B36CEDB6314E5C3 -:1097B00039019CF71B132BC95E99EE95695CB624A1 -:1097C0002688AAA2CFFB8E6B018CFB1DE67DE404EC -:1097D000D0B1069437D2B10FC7067A9D71F8272011 -:1097E0005EB4F97CDB33F59113E1768697DB03F009 -:1097F00089EBB1F2E1F1305AADBC0EFBB9FE3A4E45 -:1098000087D3CF9A83AB61FCD356D03361FAE2B4ED -:109810009DEB1D5F9624ECC2EE0C94FB837965945E -:1098200001D7FD3D0E8E0F97A93B03D7DB9F247D0B -:109830003F77B6CB2C08726669BBC48200E2E9A709 -:109840009ECF40F9FBC99EE733E685C117D94E4B41 -:10985000BFAB8DD7F198D702E3CD63DA78A1341C82 -:109860006F9EC7FC21CA0FD63ED9DB1F663F90848E -:109870000CABCF367B497E9F83D5887CA7B53BB7A1 -:1098800024CA8B76E63966094A30D4BC5E3964C690 -:10989000FEBCDE5C17D0BB416B1FD17FA7E01FA9C8 -:1098A000470AD9A17E74C900C9DBA516DFD15428A7 -:1098B0005A8A7484FA53918E12F2ABD784F35624E9 -:1098C0002ECFCF387C7767C1BC1676E8E9989EE545 -:1098D000E0F375B8B83DD86053505F24B6326E07D8 -:1098E0007EDF10447DED8A8A19CDC08E31A5B86D1A -:1098F00028A7AECF8F6A33C4E2F78C20D64F4F290A -:10990000A476812ACEDF8144166C95B0CB2689ECF3 -:1099100040473F53E07BDA04E6580FD9DE2C6E2730 -:10992000BA9967B34C7662B78476A286074DBE2398 -:10993000DFA0DC3B2D59886FA45E89EC3ED9D03D79 -:1099400007FB1D898FB644F0D1967F321FED1A9127 -:109950008FFC2AF191DB323C1F81DCFC46F559C0BB -:10996000A700BE9204BE1E16F265E0FB16A21BFC09 -:109970004838DF5AD15FADC5169247939CF87450B2 -:109980007E433FDBC0FEC47D4A32DACF90A6B6CE1E -:1099900055B9FDDED72F417FD1575948EF3D60E8DB -:1099A000CB423B3FA9A8691FF247D29C92B256B264 -:1099B0004FD29C28F751D6E0FC1B9A27F9B81D001E -:1099C000FD221FD599683FD1706FA58FDB0135B49B -:1099D0003E1A375855D467937AB356217F34AE0474 -:1099E000FB08E56F4FD79645906F9865F3A09D6291 -:1099F000B5CC2CC176AC5DBFCED649DD641707A6C9 -:109A0000320FCAED734143C03806E56CFF8E1FA1CB -:109A10001E5F5AE209A8B8DE045FE632D20B9D4E03 -:109A20006F721CE0F5E0DF64DA17758E853CA42FB9 -:109A3000097A76D679939D909FB7C14A78EFECE288 -:109A4000E5E7EC8020E83F45E6FDB1580BD73397BA -:109A5000CA030BE23D7102D37E36633E45CB773CB1 -:109A600046768CB6DE3BB3383CF6125F165ABEB76C -:109A7000ABE3FAA260BD27CA066D531440BB3B1A84 -:109A8000C7E4792F0EF7A8010049C1EC7F6FAC9EA7 -:109A9000189EE7F587DA3F30A33A8DF4EB60398200 -:109AA0000D7A57CB7BAD00C75AFB50B902F6A4A57F -:109AB0004712ED27CC980CAAF89C24C60F281BBD92 -:109AC000808F87AD4C375E387C4A44FF46E8DFA67E -:109AD0008AFA8152DFE45C80B74C6BBFAAC30BF0FB -:109AE0003D6CD4F7472815ED31A38DF7EBDCD73764 -:109AF0006E481BD2FF600FD8B3C70FD9016BDFAF21 -:109B0000ED180363453B3E37A17ED5F479A34B2284 -:109B10003B2372BD2665F3F50A766D5236C90D6E8C -:109B2000EFD6A2BD2B939D3B059756E34A1F43FBFF -:109B300012EC86D46CB21B3E3D7908BE77CE384D10 -:109B4000767EE34585EC8F46B03FD06EB7F4727BEE -:109B500096F51849EF6A74BF53C89F4E27E87DE415 -:109B6000D397A5F1C8A78C3565DC043468C9F6E63F -:109B7000211CDA7E2C12DEEBB2B95DDE5858B52519 -:109B80001FFBDF2D31D4FBEB0B3F4A44FBA4B1F7A5 -:109B9000C3C48561ED96F63C4A7858BAD738ECFCD8 -:109BA000AFCB9669FE0D2F1CF0E27A3F1D94682D15 -:109BB0002F5182EBD0AE5CB2C480961A2B0FCEBD73 -:109BC00015D73D9B6D627930BF5CD44BB89FD83BB5 -:109BD00033700DEEDBE0AF049FB6FA16D1FADE3A31 -:109BE000DB62635908E7BCBB090F8E282FE2617D59 -:109BF0006155328ED35037C581FE9346B0B3B0BCA9 -:109C0000E1DEEF923F45836B7D8FB106EDAF0AB089 -:109C1000B7FE15E04E8F9B56E381F5982AEF1BBBEC -:109C200002F29B4690BFBFC9E1F46C937C81EFE0E8 -:109C3000BA7F41627BD4A1F2CC1E6ED7DD9CCDED04 -:109C400040EDFBCDD9DCDE9C18E89B84BCF78AD2C2 -:109C50001F8DF66F23F37E86FB4EE6B3A97B884EFD -:109C60005CEEB85A54F22B595CFD0F8CC1F2890A94 -:109C7000ED2798D2FF088E7B769DCBB39E09FEC55B -:109C8000FCBD2541DA3F64FBE7237D2B841D79F67B -:109C9000851BC6CE2B19B293D6755983AB010FEB3A -:109CA000ECEA4F6A50BEFD4521F9C62C037D939026 -:109CB0001EFF1547FDAEB306D721FD031B8D54BE15 -:109CC0002FC5DF807C79AAAE261FF7C1CC16C8AF9E -:109CD000037E32BA3A18DA0BB07D203F83C5E563C4 -:109CE0002AE42705E62A12CAF908FB6312FA796802 -:109CF000DF0083C3F72A21B6F2800B4E5A6809B4FD -:109D00007D153F648F1CFB7296821F353BC560F149 -:109D10002FC5A6D5B3A3988C7CBF66E0A801E61337 -:109D2000EDEA233BB6BE5BA271EA0B9F33A1DFE4F1 -:109D3000AE6EBE2E1BC53E00F09781F6C0DAEC6811 -:109D4000A1C7DB38BFB33EDA47B367383D19837A22 -:109D5000F6F0FDC42AAAA7F5675ACDFD5EF5C21F2D -:109D6000037290CA7F922D897DED6A9176F0548CB2 -:109D7000BB49EAF3CA88D7B192279C6FB4F4292172 -:109D80002F620F0F4CC1F53B00FC857E992D52DDF3 -:109D9000DDAFC1FCB68C2FF2A009E5067692CBF0C0 -:109DA0003BB022E0BDBCE7B329C8376070D37A6D01 -:109DB000E8A994EB6DA4B769FF9814DDD485E54953 -:109DC0007714925E8D1AC7EE9801DF7F2EF09A6CA1 -:109DD000E37E2EF7EA40D6F2121CDF77F76B387E6F -:109DE0006914F929938036F6384ADBD12FE466AB43 -:109DF00024ACF7680CEF3FC120DF5157427297F255 -:109E0000711EC9BB13D29E6C27F76799590DC28981 -:109E1000DF693F069C81FB59F473613F49393C3D42 -:109E20009B1C5250406C65FD3BF6207FF6981D88C8 -:109E3000A7DA9E5F1E477D596B61DD32DA2B117602 -:109E4000C6CAF49987903FCF9D39B9E37EF8F6E80A -:109E50004D073D7EA28BDE7E88DC2FECC42AC92311 -:109E6000DB7BBFCBD6DB7B83F97FB8BDC7EDFAC008 -:109E70009E68754F983C6F14FBB4734BCEC7A09E81 -:109E8000F97890BF404F570CD92BF376477F88EB7A -:109E90006AD0EE8FB01B8E3D111D40FA9FEFB69237 -:109EA0009F4E41BB07E039631FF80122C765F27975 -:109EB00025DC3FEC337A56437F8D779EFEB901D681 -:109EC0009DD205764F2CDAFB6A2CC9D9D765B60727 -:109ED000ED32C5EB40BF8706BFE29CE2F696A05C80 -:109EE000E4F35F660AE5931D64624B281F13CA47BB -:109EF000BBE725A1779645411EBE37BBFD7F41BA22 -:109F0000A598B9BCC276F8BD4BD85B5D801207E25C -:109F1000E538ECBBB384FEC6FDCF83E9C1F5E4C7E9 -:109F2000B1103D3F7EC5BC13FD3C1F171A4226EE03 -:109F300097203F96DAAEB064A8AF1EB70655EEEF95 -:109F4000B21840FFCF7FF8AE37705F31FF15EEC714 -:109F50009A7FE7CAE9B8FFF878C61413CA9B85CC84 -:109F60004F7EE7C58CFBA197B220F757338701C717 -:109F7000BB0BC4C656143501C0FE55F059324868B3 -:109F800057A86D9027A3D9DB5103E3CE6B33D0BE26 -:109F9000647EBBDE9F7E61FDDD35A8C7D7B619B8EC -:109FA000FDD82E911E9FCFBC6EB43B34BC16E4C4CA -:109FB00073FF689BC18BE35C9F6322FE03120569FC -:109FC0007E226D330A3FBC80631533843035483CB4 -:109FD0005DEB506A86D3CF5A7F6DC6260BFAC30657 -:109FE000D20DE407BE60F2CE263F6A5C3E433F627C -:109FF0009BBDA9BD8697D39AB9601DF051F9B50AEA -:10A0000037F8981A87F2323D87DB0F91F35DD8A1BC -:10A01000CF479E4F2C0DEAF3F399BF203907FD4639 -:10A02000FAEFE9395C5E5D589F25CE013C740ED095 -:10A030006654DFCE4279B54E2179B92A8DE3CB90B3 -:10A04000CED36C67F56CE25F27D817042F873FFBF0 -:10A050005A97847AB3CDC9F9F27F0A7724BC37E4E2 -:10A06000E413BC6D68E4C1786DEBA420C71787FBCF -:10A070004AFD174B72F4726830FF8FDF77727E5C97 -:10A08000278BF5E6203934CFC1E7F4B1E479228497 -:10A09000DF6D601F00DCF3D7C96568A74C9A69A320 -:10A0A0007934BC62257F6BFDCAFE0CB267ABFAF354 -:10A0B0009B86C12B42AB68F20BEACD73C13E01D740 -:10A0C0006DBBFE9C0A342D0B3F779A99E6BD2F2776 -:10A0D00001F7231FEFFB25D27B9F95F413FCEF9034 -:10A0E00019E5D70B596437E5A7F9EFCF41BD1E1528 -:10A0F000DAF16416DA29DC4EAAEF3577A11D38AF04 -:10A100002DECDC0BFFD9A03F0763ED71E4DF609D10 -:10A11000FAEF4BB645B4BBE45C8CEBFB4D26FF2855 -:10A12000B4EFAEBFCE9B8C72F5CC520343FACE9700 -:10A130003D8B508E9CB1EAEDEF33764EAFDD8374EC -:10A14000F6E4239D778F48674F3ED279BE81F9C3ED -:10A15000FBA9473A037D97093A9F3970553ED2F9DA -:10A16000D37D57E5239D37193BBCB86E7665FAF76A -:10A17000221E4F4CF691FD04F22AFF9BF0E38B1157 -:10A18000FCF8E2FF1E3F52BB91F4E1D19CE1F5A146 -:10A19000CBA4A6A13C9C67317FAD5EC49F61FD6BE3 -:10A1A0001633F9255EF9F2F3879E403BA457263B10 -:10A1B00044EBEF15C59F837E85578EBB3D0169E457 -:10A1C000FEEF16FB18B78505D0FFA1D9FD9AFD1843 -:10A1D000298FDF17783C9DE3FD36ED1785BF768923 -:10A1E000E8D312FC9CDBA9BB25F2C75AD46E2FDA48 -:10A1F000BD0D2FCF75A0BFF65490FB671B0E8C25AD -:10A20000FFEDD2E0ABA154B40B7B2507EE1F96EE19 -:10A21000FE3006CFBB613FFA494ED87E74B2D88F6C -:10A220009E0A7E1C83E7E230FE54D4CBD1AE0113EC -:10A23000F26F03ECD3A00A6B50068E627F0D2EE600 -:10A2400009A0A8E8D1EFDBB4F3CBAD3E13C9BBAD99 -:10A25000BD5210F76989267F561AEA2796E6A07341 -:10A260002EB15EFE33C79B983B3EFCDCD8FB971CAF -:10A270007EAE4CEDFBB7C4121FF61B9997EC802DF8 -:10A280007621971492537FDEE6A47D0FFD40FD3FBB -:10A2900007B328AFE9EB450A0B2980F745B3BCEFBC -:10A2A00021DD507E8722E477787EF03C9AF571FDBF -:10A2B00002F23C34DCF9B838A7C6F3DDF0F60D6CD9 -:10A2C00080DAE139AFAE5F6D1FC09AC6AA00F75DB4 -:10A2D000B7DB3C68BF34025F37970DF1E1323115CF -:10A2E0008D0F1B849FB771C947B41F68EC911CE8A0 -:10A2F000DF5DE6E17CB80CF649E6D197AE5BD60DA2 -:10A300007C1806F748EB785CAE7E1D0FE6FF49FE31 -:10A31000CCEB72F5EB579BBFE6171F9C67AFC4D71A -:10A3200057C4BC22F79791FE6C6D7F78A572EDA69D -:10A33000087CDCF4BF8C8F91E4DADCDC91E49AFEDB -:10A34000BCE01BCBB5C873835CEE07C773033CD777 -:10A35000FD9F9E1B7CA276241A480F7A75E7A96898 -:10A36000A7E338EDDB65B20FA6C8FC1CBADE6E268B -:10A370003F6DE4796BA33A459C2FF6FDF66AD49FB6 -:10A38000FB8D0CF5FA12DB623ACF6C949F3139D415 -:10A3900061CE19954364BF7FD3F3F775B983E7EFB7 -:10A3A0005978FEFEAAEDF3787F185DAB4AC0D02F36 -:10A3B000A1389661E5F623824FA245FC8445093019 -:10A3C0006758FB91DAFD3497DBCBAF8A381AB7892F -:10A3D000B5637CC6C3F6682FEE4BDC061EE7D3924E -:10A3E000EDDB8E72D2A2723C3FFEC22DCC00F37F19 -:10A3F000DCD84DF224506FF3A05CD4FC305AFF56E9 -:10A40000B15FBD52FE3F30C8779CFF07F3FF247950 -:10A41000F06FDA78DFF49C6C33E046B74E189D8716 -:10A42000BD81E73B5997F2F348FD8CC4D76FE7FA3B -:10A43000DECC25B9E01D4DE7FE572877A2CB073EBD -:10A44000467F0FDB6F5671DF817E0FD2971B92B96B -:10A450001E533C158867B0F72A304EEA03FCEFD54F -:10A4600023DB87A706E513B70F4F8D289FFE3EFB22 -:10A47000F04799BED3C867272ABDF9A83FD7DA01AC -:10A480007EDCF73DC5E36BB659397F6E93385FB21A -:10A49000E678CD7F42F30A3CCBCFC723F98AE5E9C2 -:10A4A000F96A30FF4F96ABB64138FE97E5EA92FF66 -:10A4B0008A413FE8C8FD04886E15557D84B78197B1 -:10A4C00025B633CC3FDDD8C7E3D4D205BCDAF70BD1 -:10A4D000C2DE5D94E7CDC078AF4FDFB358582C98FB -:10A4E00042C8636897F96C743ED0D0CDE3481A56E1 -:10A4F000323A0F6E40FF6709FA05EB18DA7FCFA9F1 -:10A50000FEC2BCF1789E610BC8B1E8379FC1D0EEA6 -:10A510003BFB1ECF37A8FE122C6F5CD9AF3B87A840 -:10A52000F8EAF335E8D70078C94FE042BF4D189DEF -:10A5300066E7F1F84B2DBD29027EF4E313FF77CBDC -:10A5400041B417A3D53E3A1768D8CF8DB80AD94B76 -:10A55000FE7B76571C433E6AD85F39F635AA6F1DDD -:10A560008BF66EC5EF6B1DE8A7F8F45A17C51F648C -:10A57000C8FD4BD1DE3A92ED9F84F8B09707A7A2B1 -:10A58000BD9A09F62ADABF9FEE9B3A16E1D6E4DFC0 -:10A5900026F47F43BF9BEC7AFF36B378B3EE47FFD8 -:10A5A000F7CE24DA3FEE4BF17F1BE7BFC9CAE10DBE -:10A5B0006CB4F2F52AFCDE91EB5F5BF749B281C621 -:10A5C00049BACD42E7D49A5CD864647E4BCE903CC5 -:10A5D0001927E2E9001F3C9EAFB78EC78188BCCD2A -:10A5E000A58F6B3C9D33791CC2332E4FA1760B2D6A -:10A5F0000312FAE1178AF3F91B449C85166775C6A6 -:10A60000E15B80F8602B6B86CEE5B3B1BD83F3BF11 -:10A61000889F89BEC8EDE86C8789F8C6DECEF8B998 -:10A6200012F00DD267E240DFA458984F6E6768229F -:10A63000E2F3958B06C28752F7069DA7C422D9A0E4 -:10A640009F9C0DFDEB0AD09FE278F75AA48BDAE1CC -:10A65000A842D43DA7FAEEC9A375DE5488FBCBAA65 -:10A66000DF1879BCE0CBD1640774662CA378C1B342 -:10A67000EF03BF665DAA0FB434C056537C6076CF3B -:10A680003BE4D7B7EF97868DFB7C38CFC6E36F02EC -:10A690007D1487C626BA081FCACBBF0FA0FDA1AC88 -:10A6A00053C893D166F41AAC48D7558CFCF0799D09 -:10A6B0000E03D22553C49D9C7BE5BF47FB69BFA217 -:10A6C000F9F1833C4EC8D8BF06F75FCAAAFEEB601B -:10A6D00005B3FAFD4E4303FA3D8D030DE437793996 -:10A6E0009AFCA3993D39ABBF05F9CC76079350FE90 -:10A6F000BC785726F27500E69937CC3C9BF38CB4B6 -:10A700005E9497A30DA8B7948D8CE214156762151B -:10A71000C1FD28E4A19FE5826FB4F34900D78DFA0B -:10A7200068519E7F37D23B5AC801D61C45FE44BBB8 -:10A73000C2FD1EF6E6F79F5D05F91DC21F7BF89569 -:10A74000E219E4BF5BA74848870BCEB9990EF8FE23 -:10A750008B3C6E8FD8953EE6B085E3FF30C56566CD -:10A76000BFCCE3D61423E713659DAB0BFD835FA439 -:10A77000F929FEF4DAB6904CE75B8E138FD4A8610A -:10A78000FB9BCD5C8F34ECE5FBEAC8FDCCE5F4C760 -:10A79000B13CBD5D3E98FF27D925EF0C8EFF77EECB -:10A7A00053987E7F17699F44EEE72EB1BF23FA1BB3 -:10A7B000C94ED1E23CAA86C6217E78D5AED94101E8 -:10A7C0005D1C4C958D8FCB2CFAFE9F12F13B5A5C91 -:10A7D0004C62ABBA0AE3CF07EE63E46FD3E276B420 -:10A7E000389D4015DF47040C20F7B2F07CA883E2C7 -:10A7F0007352594892683FD0CFB07D12C6E940FBF2 -:10A80000FEBC6C827F3BF3B4CB24175509E1B762E1 -:10A810007C473CC21DDCB208C7BBC946E35931BE08 -:10A82000239EF611B48E537C3CAE73D2121E0F9A47 -:10A8300002FA17F329B99C2FADB34D14E7A9C56DE2 -:10A8400068F11D1A5EAA04BE530A1665E17E418BAB -:10A8500003D914157CCA2A63FC8790FB4B0D24F79F -:10A86000B5F8BACE3C3588FC7E0EE3406D571EEF3E -:10A8700011895F2DEEE3FA747F72FE788AFB203D2A -:10A88000AAC56B68FC1246C78015C6DFFA32B7DF6F -:10A89000AB969808FE734BA7917FF1DC5203C3750A -:10A8A00054D56BE6FC1731DED6D92616C27E95A0AC -:10A8B00015E5A7C60797B35F81AE85E8BF3DDCB25B -:10A8C00037E704ACF9232DDD949EB34ADDF2184C32 -:10A8D00007E6A0A41AFD64C64CE56A8C6319C8900B -:10A8E0008075CAF6E6CEA27CC2C007989FF6E4AC9B -:10A8F000590AE8897379033B24A8EF2FF87026E5FD -:10A90000912753189BF0C46F660668DEDC1F35493B -:10A91000F8A3CC4EFFB5F909785FA07F4D1FF97DF4 -:10A9200078DC3FC605223DDC3613D9376E118FC95E -:10A93000AA457C269ECC40BE35792C9D67DB98BA13 -:10A94000BF0FCBD3CC5CDF33CECFAD79DC5F4C2AED -:10A950001265679AE65FEA0FA0BC6ACD7252FB41AE -:10A96000B9BADF1CE47E2E3EFE5B074AE91C4A8B27 -:10A970003365CC913EAB94E25174F987ADFC5C94A5 -:10A98000298E74B41F5A8DC24E15F9A834FF77F37F -:10A99000C3ECA4B726FF4B09AE8733077F948B72B5 -:10A9A000EA0613D8F1C3C8A5D4422E97CE196DED8F -:10A9B00012D86D6FA4FAE723BE8E47CF99E284794F -:10A9C000CD8EAF343911DEC05332CAC904416FE7AE -:10A9D0002C0E9FB3DA272D847E5BADB09EA17D82C5 -:10A9E0005FF192BDEE9F25DD0470B74AC27E676AB3 -:10A9F0002CD9ED856A2C9EFB2D6B7E87E2AE6521FE -:10AA000007642107DE6EE9CF55F240E5766F94D1F9 -:10AA1000DE7E479C3FBF93C5EEA81B66FFBB299F08 -:10AA2000DB873364B514F9C875FFC4776A812F6476 -:10AA3000932748F44BB7ABC8EF87EC15EE7EE84799 -:10AA4000CABCAF1CE3965BD3EF2BC7B81339CEE378 -:10AA5000F685E537E5733EAEC67A88B7E8A672D4C8 -:10AA600063FFB0FE62A1BF92BFBFBFC17ECC1CAE70 -:10AA70006596810C05D6A7C7EDDF8A74BB30F74316 -:10AA80003A8FFD41CA5B1F60FCC45BC68E4931280A -:10AA900087B224C1B7DC5E3B5AA0F93D79DCFBD11B -:10AAA00062EEF70439C4E32B4BF93D9BDA598CD69F -:10AAB00073AD88BB98E2E0F796A69467795A616A0D -:10AAC000D3D98082727ACA715F0CD28FCDF297FB94 -:10AAD0004A47B6C398DBA886CB95A96A581EFEDE06 -:10AAE00058A8CF7FDBA3CF7F67C25F0BC2F31BDD0C -:10AAF000DEE771DE2F493C8E33703573D03C5D52FA -:10AB000000EDA5E2E753BA847F97E20D7F26F67346 -:10AB1000CF4F60549EB8D7B213EF1F687E7259941E -:10AB200017BB9925338EF0417A764012718B2E3AFD -:10AB30000B6207EF7670FC415D13F47370AE4AEB65 -:10AB400038D16660D7E15A2FB790FDA4AD8B562B54 -:10AB5000F037E0B122D51285FCDE6AF46CC6BEE4A3 -:10AB600028B38A7AB532C6427DCB3F56482FADB264 -:10AB70009A29F4F5F0835194AF50980FE33500C44F -:10AB80005998BE65F4049B70BE500FE7DBEA64245D -:10AB9000AFE40A13E969E897E87A78A321C868FE68 -:10ABA000950AC5630A98B5750723D1F7C7C4BA9645 -:10ABB0000D2C44722CC54272EC08F48FFD1E7E5D94 -:10ABC000EE223F5BA17A3B969FB714D0FD9CC6C195 -:10ABD0007B478A01812B147694B397DF0FD3D6B3CA -:10ABE000265F22D73348C15C5722E320AAF80F4CD6 -:10ABF0002311F53E237B5E3B3F4CB768E58A17C7C0 -:10AC0000491EACCFEF67258A7C6A4116AD37A81282 -:10AC10003294A1FDF1CBBF20DF6AF261C7DA1F9346 -:10AC20007CB814FF85DFA7FC34BB83E3BF200DD7BE -:10AC3000A11C559086FAAED5E9517D61F94258467E -:10AC4000B3E3103F500FF2336B3ECC55C2FC83A9E7 -:10AC5000052A094BA8E78D07380E5BD5345CAFC3D6 -:10AC60008C5BCFC78DFEC78EEB8671A1DE613B8CFE -:10AC70000BF5765BCD2143CC70E34F5071BCCB8D8F -:10AC80000BE824A44E137806BE08A05FEAB0DD40AE -:10AC9000FC394DC4EF1E4EE0E3B1427D7C4D6E1495 -:10ACA0008C4FFE587D3CCD0DD2B636D4CB8F596338 -:10ACB00076223FFE52F0C9D1E81FE7A25DF5CB39FD -:10ACC000F94750AE4C895DD5864C328D7593BCD119 -:10ACD000E4DE85E40F2B300FF2EF9A02A0FB0FB2F7 -:10ACE000DF9A839D1F713E968BFA0FE4C3B70A1259 -:10ACF0002E855FE3470D6EE4435C07837C1801BF3C -:10AD0000C6476C7A3705206E07BB1453CD4E65AC31 -:10AD100089C789ABE943F303269E6269E2F35815BC -:10AD200020B86F703E42F168D78EF2FB10DED96317 -:10AD30003ECB50B0B27B6E01EEC300DEBAFF9FF097 -:10AD400046DAE5978B97D6E08A5CC7DAF8D28CBDF5 -:10AD5000142FDD38CB46F1D39344DC69E31203C5ED -:10AD600011C1FE8DECFE066609A21CBE46D8D15A62 -:10AD70001CFF8B12F77F060E98D53D61F6F8A57182 -:10AD8000D42AC5690756F278EB417BBB9EDBDB8397 -:10AD90007A4DDC1BE81CCB6579E7DD2AC553BC2462 -:10ADA000F1FA81B98CDBEB75A27CA143C45BC05C7A -:10ADB0001287E2D93BBB18F17FA73D9BCA5364AE13 -:10ADC0007FD8B7B8FEE9CCE2F664E7ADF9540EFBE4 -:10ADD000825188F7F932D8CFFCFC9EEF0FF2F87859 -:10ADE000917EDA4D05DC2E1BB473443ED22FBB2B73 -:10ADF000D3BF05F9656189374302BE9A6FE27E577A -:10AE0000E0BB6D7867A68635ED5672F0FE45D3BB84 -:10AE1000861CE2BBC789EF8A81EF72747C172C18FD -:10AE2000CFE52F0A538DEF06F9AD30325ECEFF1419 -:10AE30008EDBE9ECFE7D03EE2B7ACD44072DEE315F -:10AE4000729D87C173C2C8E171C932C1B36F3878CE -:10AE5000AE84FFC3F92D89713E1F691D24292C6022 -:10AE60002F1B5A071BDDFE10C23FB81ED6F07DE433 -:10AE70002570CB36E28B9B6F9539BF46737D8EE78D -:10AE80004DC9307E9D18FFE675BE6A27D6AB930884 -:10AE90000F75BDF51417C6AAF9B99107FE203CAD90 -:10AEA00042CE69E75BB345FB998E3A23FAE366D558 -:10AEB000EACF9966DBF839D6CDB38C1F85DB3DB37D -:10AEC000D986CF308E71369E4369F5818FDE2F187B -:10AED0003C872AC073A823C2CF720EF81AF9FEB5B8 -:10AEE00084C5DBEE06BE2BF8694919FAE326272E46 -:10AEF000DDBD11F24F6E2DA2FC6B89B7DDF3169606 -:10AF0000EFC8A77CB541223E3D57CFDB1756DC3A50 -:10AF10002D2B06E5BFE817D713EED7A3FC9D755080 -:10AF2000CF3D3ABB0CE34BAB85DFE0DCDD8CCA6F79 -:10AF30001C63E721BB8B55F2FB554789F2EFF17E8D -:10AF4000DF18FBBB328C33AECE1E9883FCFD46D996 -:10AF50004B45983F227D3667B873AFE24229340AE9 -:10AF6000F0521DC7EBD7963D95827E98EA2A9E2F18 -:10AF7000F654AECBC172C3F939C3DDFF8D12FB9E0F -:10AF8000C1FB6C625D3FEFFD90EEAFF92C9207A71D -:10AF9000E89BF021F91D984D72A0EBCCE7CD52D083 -:10AFA000CF3DC9CBE350AB2CAB92517E4DF79BCA42 -:10AFB000319ED861197B04E30C6227548E47BA4E48 -:10AFC000B230A22BF0794C21FAB5AFFA2C230699B6 -:10AFD000CBA6E7738D8FEA34FEAED6F331AC4F5774 -:10AFE000E1F8CBCBDB91F818C6CFC0F6B3BFA5D73D -:10AFF0003783FD45ACB7C8FE479203F8132E178779 -:10B00000E0E8A6759586D17D39B8EE3AB475370675 -:10B01000E13019FAE81E4FA6E429A20BAD133C1645 -:10B02000D24711706BF0A5836C636597C2853F8A28 -:10B03000662F72081C8E441C9797433B2F8B1B82F4 -:10B040000BC6BF1EE9C0D67078B64B4D5C6E88FD4E -:10B0500081E6CF68D0E6DBA39F6F4514BFD7EE46ED -:10B06000BF13B6738D2DFA3AB81B853E9D65F13D31 -:10B07000688639DCE49C4FFC700B683427CCFF6F8A -:10B08000A9FE3AC447AB1478B93F8BFCF114FF0119 -:10B09000F49E51186607687045E2A36104791809A7 -:10B0A00077241E86E8D3978CA9761F6E705E11F305 -:10B0B00069B5F3F53A30DECCDFB550C01485FC9BA2 -:10B0C0005211C5A16870BD2971BF6440E2F78F3489 -:10B0D0007B2212BEC87B7A1A5CE8EFE3700CACC22C -:10B0E0003B820F166A7E3E4EAF24019FC9200D7B26 -:10B0F0001EFE60A141F3B3EAE819797F4DC39B16A8 -:10B10000E715892F2D4EEB9273B78873E591EA49C5 -:10B1100060A7A7C65D8A47EDDC2E6ED04FC9FD4003 -:10B1200003F7DA490EC60DFA298F2968DF4FF21CA2 -:10B1300052D02EAFAD8109000DDE147E1F0DDF0F42 -:10B1400064F8B71492DEEE1F8FFE959F4C7D82CE81 -:10B15000AB3E30703F7D247EF68C809F91F87D243D -:10B16000F8A3D27C4FE2B867A4BE0A2CECCC16E759 -:10B1700042CC9F85EBC1E9C8AA44FF11C8D7AFBE36 -:10B18000C24D2B16015DCB33FDBFC076B730DF64F7 -:10B19000A46F5C8DDFC8CF4918F9E1978BFDE3649C -:10B1A000A177CF6FE3F11ED5DE518F4D44BBF198EF -:10B1B000910569DD7B497FDE25E03F0F2A3684F566 -:10B1C0009FB193FE5DFCFA7C8AE328D86C187A4F15 -:10B1D00003FE8E0A46E9DED328DE1BA7CB9776A7AF -:10B1E000E8EA8FE9C9D6958F0D15E9CAC71D2BD39B -:10B1F000E5C7F75DA3AB7FD5F12A5DFEEAFE69BA2C -:10B20000FADF3A354397BF76E0BBBAFA1F0FFA0F61 -:10B2100084DD10F0F615C2BC1788795F7F719EAE91 -:10B22000FD9F62A61C437E5CB081C7A55702867451 -:10B23000EF8B7470FBA209FE207D27B3018A076C97 -:10B24000084A9E10C3F836BDFDB1B4A78BF078B99B -:10B25000FBF805AEB90634B94F170AFBE32A761599 -:10B260008F67FD7ABAE6B3BCBF8BAE66B79EAE56AB -:10B27000554FD7E8423D5DED1E3D5D6327E8E9EAA5 -:10B28000F4EAE91A5FA3A76B824F4FD7A4D97ABA21 -:10B2900026FBF5744D5DA2A76B7A939EAE99CD7A8D -:10B2A000BA6505EED4958F446F4D9EE6B42FD7D581 -:10B2B0001FA4BB6F09C537E575FC50D7BF46F70023 -:10B2C000FC41BA17301187F93FA47BE1283DBD410D -:10B2D0006F8D1A359EEC8D124C671708BBDE37BC9C -:10B2E000BDA1C99F70FD1EBEAF1D492E5DA2CFC47A -:10B2F0003E77447D16B1CF7D8F81BEA5413690DF6C -:10B30000EA56C19F87A338DE3FC7A2ABA11ED499DE -:10B310000070BD8770C338EF4515933FE2BBACDBCF -:10B3200088FDDFCEFA289DC30628F53307E9EF79BB -:10B33000CC43E902E63309FFC4F45109E8B7E8AFAA -:10B3400040FD7F61EE5B1FD0B9D61BF157F40EC5EF -:10B3500047787E92C7D849210F4EE0390AE4CF5A88 -:10B3600007F5ABEA0AC3DB49E16F9C3749223DCDC3 -:10B37000E4288AEF9A778B44E744F3FE93A78B4641 -:10B38000493C1E24226D6DD6F0C7F7473B47A90400 -:10B39000471AEB16F61CF3DB72A81F7EEEB1CB4406 -:10B3A000FB58B785C3F7ACC4940971741D8EE8EAE5 -:10B3B000B670789E35320BE2F369E65791180F2884 -:10B3C00020A2F83D8C22E48F79FFF95636FAE9A2E3 -:10B3D000A25E98557D359ECB0456919FFC7B4CEF29 -:10B3E00027BFBD49223FF9F7004E48DD0E8F1BED08 -:10B3F0007C2DFFB080B71AEBC1F7247793847EA928 -:10B400007F587FFB7FC8EBFD9DFD0DF6C3385CF8D0 -:10B4100083F4D3FC9E85061E27317037DF1FEDFEB7 -:10B420001EE3FEBBE6406500CF45653094308ECA12 -:10B43000C8EFC7EF1CC5FD9EC9AC8FFC0BECA8661E -:10B44000D7FA49FE9688FB1767C5B9E2A22E0BC34F -:10B45000389D927D87E2F01C7111F0601FEA61C592 -:10B460004FEFBF946C792D8EFBFD8C4EBC57A9E934 -:10B47000FF91F9546127C3EE3100DF350D677FBCC2 -:10B480005AC4E3035A5BFA46E139A006CFFD2DC743 -:10B49000282F2B1E86E797F83E5478FCA3C905E5B4 -:10B4A00061F24EB141FB303964B4F9E89195352D24 -:10B4B0007D74BE6814EF58AD4D5BEEF087D9898777 -:10B4C0004609FBC71260B84FE02A0A53E524CAB503 -:10B4D000FF627C1F6D76433FE1F2F362020B3F1F78 -:10B4E000686F394EF0AE91FC7EECC49CCB4256A006 -:10B4F0008F59C1BBC0F07DCB0DC7308ECB645FEEE2 -:10B5000009A923E3CDEC562E84CBD3B723E4E94F2E -:10B510005A068A719CD6967E0D5F0CCF6B03C9DCF0 -:10B52000BE6E6DF984BE1BC03E447E7B754BC1214F -:10B5300015CA3F80BFF8DE8ED9C5E162175DA457FA -:10B54000E7083E405F5C3AF0CF07CD46E2B315E92D -:10B55000363A2758F166DE212FAC67134C57FE06AA -:10B56000700F8DC3F16412F214F8C987F2C194A26E -:10B57000D079419C6306D1E9EFED4FC3AFC9CAE86A -:10B580009D2453BA8DEC822B85F36FA3F83B408347 -:10B59000F6C94517C9FF15022FDABB4F1FDCC3C818 -:10B5A000DFB3E25EEE375C51CFE81E026B869F8A06 -:10B5B00021BED1F44C02BE50031F3B5A60C5411757 -:10B5C0000FB55898BF00EC108CDBCF19A2638757DA -:10B5D000716288C1C66A571DA60F4D38D181E2EF4E -:10B5E000E1895FF4618A670438BEA38905D13EA66C -:10B5F000B37F18DFB904F2307E8C288FF1F37CAC76 -:10B60000288F9DCDF3E9DEE7A46A042CE23C2BDD14 -:10B6100016373517E5F402C6EF818B7720B60B7D20 -:10B62000916A8BABABC6F2DB19DD0BD1CA7F2ACA9C -:10B63000936D1FB5E7A01E99A56FBF45E021C9F620 -:10B6400051C7243AF7D2976BE74A09B6F3C7A87DEA -:10B6500089BEFC51D1DE6E3BDF3709CB73F5E33F8A -:10B6600028CAA36D5C1E321FE3EF1588F20744B9A8 -:10B6700015CB717C0F2F97B5773944BD75020E8CB1 -:10B68000A923BFEB28EE77DDD1622921BAB45C246F -:10B69000FA3CD4C2287F6B511CC909430DC7779C63 -:10B6A0008BF383A3990DFB4EC1AD42AEC5A8FD5EE1 -:10B6B000EF30724F2B8F73F0771864B789F8C96C2D -:10B6C000137243ACC741B92135793893713FFDE519 -:10B6D000F81A16DA05B48F32E007F93AED1E03F3D3 -:10B6E00087C9CB946551CC1F56DFBD204E974FBC08 -:10B6F0003D4557DF352B5B576E2B2FD295B35971D4 -:10B70000B46E960BFE8A2A29D3956BEF43B0DDA267 -:10B710009E58BFC6DC6B74F5CE17AAB1C8E327A745 -:10B7200082FEA178068F05E5C3727B7612EA9FA799 -:10B730005B2610729E857505462B7BC6C9E3DC9F90 -:10B74000C1F34328FF598B97BEEF817215D25DB0CC -:10B75000EE54A8DFD5E2A0FCE32D6E4AB7B7A8945B -:10B76000FEB4A590CAB7B47828FF18F48FE9A3D027 -:10B770000F7E7FA4A586F21B5B7C947FB86536E5BF -:10B780001F6CF153FA40CB12FABEAEA589F26B5B87 -:10B790009A29BDBF2540696B4B3B6F57C4F5CC332D -:10B7A000E25EED3395FCBE7C241D3B8B841F52C4AE -:10B7B000ADD887E2563A8B306EA5BB9FEC702D6EEC -:10B7C00005E74DFD59F9FC23FB7BAA88DB6F45ACEF -:10B7D0006F55345FCF743E9CD7E3591D0D7C9FDAC3 -:10B7E000C4E990D53340E5C94B382D9E12FCC95CA5 -:10B7F00001965641510254EFACD45715CDCFD529FF -:10B80000CE91B9619E15E2FD2662BBA001E15226F0 -:10B8100070FDA9D17570DE4E0E27CE7F3878F70BFC -:10B8200078E5F26EFE2E4B4D4708D93ECADB44EF59 -:10B83000B25866FB420AA42E9F9FDE8928BA3805BB -:10B840003667206F2E5EC75448D396E9F76D290BF3 -:10B85000CA74FB22F9E2434C0539602BD1EFAFA249 -:10B860007297EBDA59D27EA82B37B956EBCAE7DDCF -:10B8700095B5C68DF84CE5E74BE60DAB5832C0B533 -:10B88000B07323C1F59198C75949A5FBE5817D5A4D -:10B89000BC05DF5F3C29F40BB36C207BACC0C9B3A3 -:10B8A000F9B10103EA874FFF3596E4D2138F1B826B -:10B8B000E84706F164C0F55F0C661F9697B27ECA32 -:10B8C00063A80CE6C73255C6FC383640FB2BD85F60 -:10B8D000BC5F8471ABB2FF712BE4CFA4FB9FE4711A -:10B8E0007321D29FF9829EF9DA7E6AB312E95FEE84 -:10B8F0002F22FF8DFE7E5D9BD85FB459B99F6E9558 -:10B90000B32209EDD6B323C439DADDAF1E5D00F8EA -:10B91000B6271FA274D02FA71A86BD3FFE4504FF8D -:10B920008F026617FCFF05F2FF99F2B713D10DD510 -:10B93000903B40EBE0ACE475CF45FCBE2E737E84BB -:10B940001D17CE4F11F855F655BAE7021E953773FD -:10B950003C013634CE132DC773300E41CBE78B3804 -:10B96000DDBD2DC9B9D561DFD5624EC742D657833B -:10B97000FAAAB0C4E00962C75E87CE8F61CDEDF050 -:10B98000E27B084A19F3A0981BC53A56A3EE56FE6F -:10B9900026539C9572F86AA6C27EC6660B318C4B04 -:10B9A000D3FA65C21F728F909B5F38AA63E99DCB63 -:10B9B0009441F9873A927D61F3F6211F7DD169E4C4 -:10B9C000F33AAC2F2FB471BFE1A242535095F05D12 -:10B9D000B50E7AC751D921B1B42C846312E1811D0F -:10B9E0008C263E8CDE3C9A0560BD943BFD9662F44D -:10B9F000DB85D483861CC19350AFBED8B413EDB39E -:10BA000002C48B0DF1726B6E350E9D5B48F85D289C -:10BA1000E63DBE98D3AB2D3D021EE6F1E27BA78B3F -:10BA20003A353F8E7E9E0F96577D07DF856CED93EE -:10BA3000B95A8BC0E77A63DFE8B9D0F5997E804BBD -:10BA40002638C717A30DBAB98205488FF3F9D53F39 -:10BA50002EB1AD5924976A488F8F37B0F0F3532D2C -:10BA60009D58CCE5EFB1221E876A771F257E1CCA40 -:10BA70001F39BA00F0F1B48115D2B9B181EF8FB599 -:10BA8000781D19FD0078AFA158C845D6C6A6A1DE1D -:10BA9000761A28FE54EE8AA27BB3B253A1B8F736C9 -:10BAA0005BB5E34EECC7A1D039D11479621FDAD16E -:10BAB00066A7611CDAE14776FEB00FE386E4748581 -:10BAC000A1DFABCDA1703B24CD40F1808AB3DA82F7 -:10BAD000E74AF9B6139588CF435D3FA07722E4EF9C -:10BAE0008B981DE117330A92B5B126EA3F90A688DC -:10BAF000F766BCB56313C591888AFBA19A4F70BFE6 -:10BB00007DC471DE8AFB02D5B688FC81F715F37D12 -:10BB1000A211CF0F21FFF8CAF34E945FAF77AD8922 -:10BB2000CB427B3AA8902D52F8D7D6147A0FA1CBEE -:10BB300044EF356878CD0C28BA73C8F4667DDE1CF6 -:10BB4000711E698CB827B75C8C8F2797A1B0F91844 -:10BB5000DD7CFFC65C36DAFFDC572CDEE914F97BAE -:10BB6000447EAF3190E201FC1CEE5A9489F3BAF0A6 -:10BB7000829FE2CE47B2FF2715AB62BC80D540EF73 -:10BB80000287AC1887BEBB8579D0CEB30415BA073F -:10BB9000B047C8B35C1BE7FF3B4AF87A8D4C733B58 -:10BBA000F8BA539E890A4623DD1CDD650158E7C5B6 -:10BBB000AF4E652AE8C15C87D780FEF7DC66930745 -:10BBC000EDCF29BFB0119F9CB7F1382EA5F9011513 -:10BBD000BFB7EEAC2854C3E00EB6383C289F76B60B -:10BBE000583C181B1F1C41BEE6380D143FAF1A7895 -:10BBF0003CE72EB11E7715F3F788760A39B34B0967 -:10BC0000CC403877013D316EFFD0066E1F2F5F6547 -:10BC1000213896BF9E43F6D548787BA2C5EDC9452D -:10BC200078361852D05F55B92E773DBEDFB1DCCEE5 -:10BC3000DF3796638B1EC3AB11ECD74686F67C6B61 -:10BC4000CC359EF961F25D8E9D58887C25CB8114A0 -:10BC5000F4E7F43C7DE1268CE705FA6DC57CA8F895 -:10BC6000839B307E77AF3D9082F1BDC78A3FE2E58E -:10BC70000981AD18DFDB577C9297A707520C903FE4 -:10BC80005E7C9A97E705B662BEBFF82CCFE3D91B5E -:10BC9000C8CE53C5E76F0AA0BFC5E4598202F9E7D1 -:10BCA000007F092CB16E919E1678D1CA9FC3EFB068 -:10BCB00001DB2FD2C8F283A25DCF08E52F8AF2DE26 -:10BCC00011FA7F45B40B8DD0FEB068776484F647D7 -:10BCD00045BB632394FF4A94BF3142FFFF2EDAF540 -:10BCE0008DD0FE6DD1EEDD11DAFF56B43B3E42F948 -:10BCF000FBA2FC3F22FAFF40D4EF17DFB3ED1BDEBF -:10BD000047FF7D36C811944B85F60D71B8CE77B6D6 -:10BD10009713FFB756F0732A8DDFB32546EF0EDF7A -:10BD200056C2DF3BBBAD84CB71A584F339F0E1C3D0 -:10BD3000C877CBDF94299EA8D5E039154439BADEFF -:10BD400040F6C0F2D7F97E7DF93A25187E1F486B80 -:10BD5000AFC1BF06E103C66DC314D6DB97C5FC9C1B -:10BD6000D1EC767B6AC3E499D1A1CF83BC602877FC -:10BD7000417E53DC78E1BAAAF6C2723CEB339005FF -:10BD8000A2D45B42F88E8862177AC151DE5188F0E6 -:10BD9000D9147A3F4193F3CCE6D6F935DA6C0ABD73 -:10BDA0002727DB79F9945F4C74A09DD5C6FC7D5E96 -:10BDB0006CEF56C88E3FD45EE640B967B22F70E094 -:10BDC000FAFDB894E3BDBAA1300AE5B5FCA081E460 -:10BDD000F711075FEF3BDC3CCE0AF40ADDAF0279D6 -:10BDE000ED411D51C042AB506EEE7DE8E05CEEE7E8 -:10BDF00063F6B115747F493B579794B07D406D0948 -:10BE0000C74FA6D0230AEA174877958B7B3701EEF8 -:10BE10008FCA54983B35ECFE706D89CCEF3D69E7D5 -:10BE2000A1722DBDAB95B152D19D23A4DDA3CF9BB3 -:10BE300022F48612A15772DA414EEACE4F1CBAFCA8 -:10BE4000B74A849FC7C33C68C74EF9C5069287E7C7 -:10BE500051BF4923CBBD41F92BE4F12E4400CAD197 -:10BE600000BFDF7E6843D9AF90DECBD719E83DEB4A -:10BE70002B95A30AE218F090E797482FC0845270E0 -:10BE8000DF74393CE4197D71F4DEC765F091F76821 -:10BE9000791CCADB3CBF42FD5FA2372E83AF67250A -:10BEA000CF713FD2D11925EC6A6000F4DBC545752E -:10BEB000E1F9BE49F853B438652549E1EFF58B7BCC -:10BEC000B2B2E0E3FB99578DCBC1F78A9AC8BFBFE6 -:10BED00062DF3D6EB4DBD71AFC0ECC1F8B9B368025 -:10BEE000E32C874D3FE26F2FF641EF72BE7D33FAB0 -:10BEF0004DBA8326ED5DCD10FEB30FE38FB4773BD3 -:10BF0000DD64AF897CD5CDD530DF6EC5518C266818 -:10BF100047C9E44D46B049F799D8607DBCEFF7F4C6 -:10BF20001183E8EFC64DD52097F64531DDBBA5FB63 -:10BF3000D0CF4EF9E99BF09D5218EF4619F6663BBB -:10BF40009F99B5C976F5103CBB9FFDEEA655E8B0AC -:10BF500013FB1427E3EFCD9F51FB6390B4B05F59FF -:10BF60005F82FBF5AE1389E1FB75AD7EACA8DFD037 -:10BF70003BD0F08C4AF53B4A801FEA7B06624A08B8 -:10BF8000DF0315E1F563841F20ACFEA6AFAB5FA80D -:10BF9000C1F3CCDB3797F0FADBB0FE59B53F9162C5 -:10BFA0007A22E089BFB4FF9D04FF08FD1789FA6774 -:10BFB000426F53FDB3AC3FB1348BDA3D85E39C7BDC -:10BFC000E3ED0A31EF443CC779D7E6FD197E6FC136 -:10BFD0003E707FA734A9F8BDDBD2E140FBCD6AEC0F -:10BFE000F0A11CCEC5F7C7260CA5CFA2F2187FE999 -:10BFF000F7487EEEB6B0F85AE4D76603ED6F7AFAEA -:10C000000D0F205FEE489BE8C0FDF33E535F5909DA -:10C01000DAAF076C64BF1A323FB5A2DFDC5CC0D771 -:10C02000BFD5D9E42981BC35BD84DE0F95EF5DDE37 -:10C030004DEF98DFC7DFF7527E6CF2EF46FE0A2D18 -:10C040002F5C18B6BE7797F27B96EB5EB36DC0FDA2 -:10C05000C13AA3A7A300ED70BB42719FCA8F0F4ED8 -:10C0600023FBF0E70646F21FE65905FDB6CD55E87D -:10C07000F7300C94CEEB2B217CF87C55502F2341CC -:10C0800091F07ED0FD8ACF82E71D6661D7EDF0F09A -:10C09000FB61DAB81784FD79A184BFB7B623EDC27E -:10C0A0007B8B5DF8FE8389EE75DA961942A618BC83 -:10C0B000E7B6F3D462A46774FF3ABCE71C95A238D4 -:10C0C000707E3FAD85323A97EBA6EF817A03ED1B88 -:10C0D000E29719BCE87F8CCA35E9FC1D361827DCCD -:10C0E0001F1233DAFF47A4E7B837951B11CFEEBB19 -:10C0F0000DF43EEA83EE772D068033A65CDFDE3159 -:10C1000051DF3EAE5A5FEEAAD59727CED297BB6FCE -:10C110003745F875F4F9268DAF4026D8404F45F1E4 -:10C12000221665BBD082FB9EB5AF4531A2CFCA4D6A -:10C130001D05B83EA307085F514551E417589B6C95 -:10C1400022B9BEB694FBF50FA79B6EA43CCC0BF9AD -:10C150006347DA51DA8F5C8217DBA9BF62FF3616BC -:10C16000F61DFDF2A3BD96521E57C3DC15E8C7634A -:10C17000240F9F95BC9E4388EFB7B8BF624733F743 -:10C18000633F388BC741D20C2A70BDF3FA31960D4C -:10C190007DB82F8BB1B5DF8DF19D91784D14E70DF2 -:10C1A0003BF0762FF29D9FBF1BBD46BB6785DF2B03 -:10C1B000E8D604BD8B366BB478EF4FD809B1EEF8F2 -:10C1C00092B6B0FB1A89C26FF2F0C47956D41FFB45 -:10C1D000C43B2283FDA934280F79457F54A9E6AFDB -:10C1E000E1ED3769E73C229FE0E4F97D47E26EC468 -:10C1F000F5B569565C19EEF7D70AFB2E36CDE41D6E -:10C2000005F37AE49829208D81BCC28E18C12ED8FE -:10C2100017C7C735BD1E15C07B818FB8CBE99E619E -:10C22000AD80FBB94ACF3BB8DE07601DED84FE1F31 -:10C230007179AC65E2DC3400F051A8159828876A62 -:10C24000CB68BFFB88D76345BDF9489AC78A71DAC6 -:10C25000D664C581716B716E85DE897BC4E277A07F -:10C26000FD13078AD484E749E91D53E97E1DE0DA0E -:10C2700050C18F1A98886FC4F8C27881CF1DEE051F -:10C280000E7C97C195BBFF5FD04F1F8FFDC5F07629 -:10C290008827A7C0D3AC5295E07689FEE3173C47C8 -:10C2A000F5F1A7AD22AC3F4147D35416C47D9A3671 -:10C2B000BED6CF60FFCC4BE7006B7EC5F1B62A9DA2 -:10C2C000BF8F65BA8BD17EEEB94AFF5EE4B381E4DD -:10C2D00028927729EE942AE4A394635B67E0BD8BF0 -:10C2E00035BF8AE2E32CE4FC9EA230CB7538EF0424 -:10C2F000BF03F118B95E938F74D421536A74895CBB -:10C30000BFC90A6B97E32E5DC7C96E5755FEE8613A -:10C31000D673C47A493E36F07DEC3F725D6F8FFE76 -:10C32000602CD72361DFE5CBE7DBA4FE7524879380 -:10C33000155A67E911E3E13B7B98979841C5B8E846 -:10C34000DDA54EC1C7A0974A91EF1D936CFCBC9D23 -:10C35000F8ABEAF90DDFFD35E42FE0EFF3815AA9E0 -:10C36000C73AFA482FF6F80BB0FE36C5FF38FAD3B5 -:10C37000B71D4FA2F72BCDD1FCFD5153C47B299A99 -:10C38000BED85DCAFD486AC4BB9BDF34ED4E4B2B63 -:10C390007678B0BFB77F6B49F8C7DB3F6947BA57BC -:10C3A000D9604D3F5372F326BCFF6C7D93973F0DD0 -:10C3B000F980827859467E97C31977D2FC5BDF33C8 -:10C3C000933FAB54F66CC63CFBBD95FC717B0F4CA8 -:10C3D0009C8DEBA4D55EA1A2BD7F40ACE37F156927 -:10C3E000E4BC6493C78FF640E4F7674B35FF9BE7E7 -:10C3F0007817D0B7749789DE711A8C8FE8B2F2780B -:10C400005461872E10F26CC1C1F5198718BEC35153 -:10C41000F75A29B45F60AF4E4478522F4ACC0FF2DE -:10C420006F9B389F4D753D27A19C49731DA9447989 -:10C430009FCEFA56A1DC486FD29F97A55E54A8DD27 -:10C44000BE142FF5873F18076A62624DC7F9D92AD3 -:10C4500094F329FCBCC5E488E271A1EE6ADD3D6A73 -:10C46000ED7DDBB7851C35014E8D6590DA147E6F4E -:10C470003FA2FEEF443D19FDF6E8FC771C3D4EFD62 -:10C48000DA944FC3E34D715F4A426B193FFF043C9E -:10C4900005701FCA62E3F879A9D7AB86C7DFA68209 -:10C4A000DC359761FC4980E24492C5BD082DAE079A -:10C4B00030E044BF9B16F7B193E9ED112DD5F6E7B7 -:10C4C000B9CD32ED3B8A5FB5F2FD413B0B5A25F405 -:10C4D0008731923BB91BF8F9B4E617BB0D1713EA85 -:10C4E000257C0F97C6EBA6386ACDAE02FA92DC59CE -:10C4F00017F1CE94F68EB66134E78B6D2D0EA2A3A4 -:10C50000569EE68FA4A3FE9C53AB977A3195F9E330 -:10C51000C3FB0D527FA9CDFB891F522F6650F9B680 -:10C5200016F532FD678FD07F32F1CBC8FDA751F9E8 -:10C53000F6D0BBCEE9808A9F0EEC77FA54942BA1FB -:10C54000A99E61F09C7A8F5E4E8EE9D1CB5D0D2F56 -:10C55000DB14AFAB0EF0BDED1E83A78B61FCA9BE53 -:10C560005E4DD66F9CFC5D6BAD7EC83513EB2FE343 -:10C57000F5BF754A5FDF577920B23EC177FD457D33 -:10C58000BD48FA44C20B7025DC1406D7248BFEF795 -:10C59000DACD9E7B095C09B784C175835B5FDFBF21 -:10C5A0006A78B86E2C347F2D5C5ABDEF4CB8B27AE5 -:10C5B00091F39859631E01EFBCFE2DB3AFACDFDBE6 -:10C5C000967C7DBD3B9A23C7096871DB3A7B24BE0C -:10C5D00099DBEF0E364071269ADD11C71C22FE8BC7 -:10C5E000DB0DEFE07F93197B60B46FCEE804C4BF2E -:10C5F000F7F64755BC1FC3F515ABE5EF56C2BEA411 -:10C6000034FC5DEE21B85653BF2F61BC13E9598B42 -:10C6100007EDCEE254664946E3CB1DCCC6F7C7EA28 -:10C62000476BF29AC7971709DC3D9BD2BDDC49EBFB -:10C630003C1887F07CD371EF1DEDBD67F4F8A1FACB -:10C6400023F95B343C994CDDF47B1D06EA6D1ED466 -:10C650000FEF6211B4DB75B3398476B516877A3C77 -:10C660007ACED10495DE3D588DFDCFBE65EA1ACC59 -:10C670004B87E3D5E536BC37D5AFDD2F5D83785BDF -:10C6800066F167261AE87CB500F7C3CC172F2E2376 -:10C69000FB4A878BD3D0E0A99638FEA3D2FC0FE3E8 -:10C6A00038D586BE1D3EFCA6F4F17DB62381BFBB06 -:10C6B00084EFEB0CB3FE353C54897E0E193D5F0EC2 -:10C6C000C0FC0E6D8CA57BF80BE26F99836FB22CCA -:10C6D00034F812F1003D0CEEED04B76D6E6632C217 -:10C6E0006D14705B1204DEBDB95F07F760BCCC7DD2 -:10C6F00092F67E3AE59F0F38E9BEBBD9F0F9BB331D -:10C70000510F971A3C68776E03FB02DF77FB3F02FD -:10C71000DFDBF18C258EBED3BB6F6E71EFCBBDC955 -:10C7200040EFBCF8AA5E203AED6AB07970DF3E9720 -:10C73000A9F4EEEA7C710FE60F95FFFD723FCCEF96 -:10C74000A5D1FE83388F3BE20D19EF121CFE627AF1 -:10C75000476BE295C5CF6AE7F033847DB050E07156 -:10C7600026F352DCEE4DCC6FC471DF3E6BF2A25D5E -:10C77000FAB68847BE8505E8FBAD2C48E96D2C4428 -:10C78000F5BF872FCA42FEADE8D1E9CD005FDD637A -:10C790000579B81EC3F0FE06D219F8E50E17E79723 -:10C7A0003F2621DE3B13AE887FEB248EBF0746FB7E -:10C7B0007FC3D7ABEAF2204C8E4969E847195C3F4A -:10C7C000D5099CFF1447DED7AD9FBEF3DA7D7FAF5E -:10C7D0002DB902DFFBE23F3778EFA278718CCB777F -:10C7E000011DFA547ECF11C4863D0074AAA9942974 -:10C7F0006E6FED67E27E363A31A0DE2FC7CAF43E97 -:10C8000099762E395DF4373D8DDF57ACAD9CD91646 -:10C810000B7899F2657F7908D29A34FDFDC5A9AEEF -:10C820002E7AD27C5AAEFEFB8DAC830E886B4BF415 -:10C8300071E6D323FC9F87706CE0AB8BA345BC648F -:10C84000112B0ABF6FF01DD1F67CEDE7A673307E89 -:10C85000C918FF57488FE5DFFEC31CDAD729ECCD96 -:10C860007130BF867F97C99EFCA80566528071D53E -:10C8700016E60583FF24D815983FD5E2A6F434D8F0 -:10C8800001987EDA5248E5675B3C949F35C667198C -:10C8900003FDCE6BFF4C417DB4568BC7167068719B -:10C8A000856B45FCC40AFBF2E318BFB08202DE19B7 -:10C8B0002CF68E2908FE9D3DDD473185EF32EE4393 -:10C8C000566C94C8AFB3F0887F0D9279F11BFDD3FD -:10C8D000514C8CFFCD8944DCA7D7A31D0BACBF22E4 -:10C8E000CE9B340658C0DBFBE1D178A8FFC7960980 -:10C8F00004DF272D5E82EF4F2D3594D68FF1A5539F -:10C900003DF619BDF3F4ED673E54F0F7B34DF64A2A -:10C91000E4BFBFCECB8241C0EB662397EF9B41BE05 -:10C92000E3FAAC2C9DB1FD1E86F2D75F80F3BC29E3 -:10C930006EFEE478F83E7DC25C05EBDDF225E8A0F2 -:10C94000AC213EBC1C5F9F794522FC9C79C549F80F -:10C95000D0F0542FE875E660F177F0DDB3578EC95B -:10C96000147F7AFEA281E03B7F3C8AE25323DB2FD7 -:10C970003F909384F6D89F807E78F0B1FC4031F9E7 -:10C98000E3FFF4ECBFA8E171BF7F8AEBBEF03ECAC3 -:10C99000A9FFCBE514D89B27B7A21C4B4BA1F77B73 -:10C9A00006E3D5585334EAB10693585F206730FF49 -:10C9B000A728BE0FAEF8796A15AE171C0FE3BDCCE1 -:10C9C000E2F760407F1FFC10FA3BB8D54DEFFD7CCD -:10C9D000BAEFB16C1C7F6FF7C2F7B742FF6782FCFA -:10C9E000F7609C61DD675F4479BADB467ECBB512A8 -:10C9F000C085FA744F0AE50B2525AA999C19411E9A -:10CA00008722A90ABE7FB6ECB92D29C85F784F1DD1 -:10CA1000E3EA5FDA184D72EA25A3E78366EC6F3B21 -:10CA2000EFEFC987EEFDA807D307EBCBEE4539370B -:10CA300086C7312EF8C9D2226C0FFA9A7EDFF3D363 -:10CA4000CF4B21F48394761E5A8D714C63B67D686A -:10CA5000488174EC6EA915D3E2F469C7D07F70D712 -:10CA60001895DA8F7B264BC6D8F4A294E0FBD7F357 -:10CA7000B8119D7E2FE9FCAC0AB7999A9E2F92BA05 -:10CA80004F77E1BE38E37819BFDFC5DFAF3ED03B5B -:10CA9000F39DDB18CE032C08847BAE89E22E583040 -:10CAA000D085743EE32FF4D0BB2ABEC016E4AF336A -:10CAB000FE44BA5F78D01088C1DFE314F880FFBE6F -:10CAC000A1E777BF1583F114B1FB8D0C7F2F76FDA5 -:10CAD000D88129141F92AED27E3C7DC70D35889F28 -:10CAE00086FD07BAA89F65160FFA63971CF89CEE9F -:10CAF000BDB0A93C0EF5CC7E9E7FA0DA4BEF9D2FFA -:10CB0000E9FA33CFF7F928EF930359747F623EB700 -:10CB1000771E13FA8CF58F66E1EF2169F47A008AAB -:10CB2000B17C73562019DFBDD2F420E8AF8770FDC9 -:10CB3000A1DB91DA3B66F27BF257A8BF4C421F693A -:10CB4000FD3D66E2EFF4A218C1DF8BB3CDC4F5EE74 -:10CB50001E9037C82F9ADE857177E0BA3589FB328F -:10CB6000A9A064C7C27C521F3373F97D85E347DEF9 -:10CB700067D5EC90D9F1AD746FF5D354FFCF701C2D -:10CB8000EDFE2A533CF4AEE0EF53BD4F8F49E0EF8A -:10CB900075E01C402FFE02F30D32D85139617694B6 -:10CBA000E5CAF4E2DF52BD07709C2BAD1F29872731 -:10CBB0000AF857D80D8487158F9AC91F3651DC4360 -:10CBC0009D78FE7834CA93157F2E23B9D2CAD8B087 -:10CBD000F879B985C779FF1BFA1120BDF68B7E99CC -:10CBE000F623470CCB8E827E2510C87F38D01A5B87 -:10CBF0004E792F92FBBA2F0CC3EE17B514E8F52E21 -:10CC0000C9E92FF5FE87EBBF74D0EFCD64B6B82B22 -:10CC10009AF7D0FB3EFAF96BEF6CC1FCFA51BFAF4B -:10CC2000F8CC40FCBBE2B332929BBD57385FABCB34 -:10CC30007B12E18C9C0FC0FF29D22712FE417E1F80 -:10CC4000B832F8BF2F31FA7D43A0AEC8BFDD2BDE6E -:10CC500031E85D5A42EF691CC4F748506ECEE0F7E8 -:10CC60008E7AC5FDE4DE0407BDF7F19291E703B7C4 -:10CC70008AF6E27DC8DE5B53F87B1DE6A65F97620D -:10CC8000FFAD3C3EAED718A4DF53FBFF00D94A30BE -:10CC900097008000000000001F8B080000000000CB -:10CCA000000BE57D0B78D4D5B5EFFECF2B33C9242F -:10CCB000998490072161F220040D3879F10C3040FD -:10CCC0008268D10610058C71420284BC088FF6C4BC -:10CCD000969AC100A2C51A8E886851070A14156D6C -:10CCE000A888A8C13382505A5F69B51E5B2D4D04D8 -:10CCF0009F3C1282F6620FB7BDFBB7F6DE99F90FC3 -:10CD000089DADED3EFBBE7BBF1D3EDFEEFF75A6B69 -:10CD1000AFB5F65A7BED69FFD12097D7C998D13AC4 -:10CD200037E7743E63EFF90C5E7334632D9AFF5658 -:10CD3000630163DE0B16B63B8DB12D31FEE4E53C9D -:10CD4000BF65D95554FF3DC666B6E5E0BB3B2996A5 -:10CD5000A707FF66BCBDD4CEF3B93CCFD39734361A -:10CD60009FCA67BB9362787E6178D468760DCFEFF7 -:10CD7000F0EDDE1A87EFD9D4CF10236BA47A69A225 -:10CD80009F3F9A45BB3F30FE97C4D8A366E6B5C522 -:10CD90003236DEB568B8AB9031CF8D1126168D4294 -:10CDA0007792C6E7F348D57076AFC6B3AD0F3116AC -:10CDB000CFD87C2BA33F351E2A5AC730364F7C660E -:10CDC0000B16EFB679F87CE655DBBAB4D17C1DD5ED -:10CDD00077453AF978F33C467F5814AF705389BBD6 -:10CDE000335BD4FD7B3AC675D3B8AC6A10CFF0D4B0 -:10CDF000E4AF647CDC977BACEC5E0E97BFE36F4ADC -:10CE000020E510636C30639FDAC4F8F56D531F386A -:10CE1000ADFAE3FF565BEC1BB56894A7FA181F7FC9 -:10CE2000FF104F01FA5F7EE8BA074E5B03F5AA16C2 -:10CE30009764314360DCD07142C76B01DEF878C380 -:10CE40008047DEA485171880BF369B0FF863A69E27 -:10CE50003F2CE5F996F957B9EEE5D99973AC6E8D8B -:10CE6000E3A1F740982F4CC3F77037D6D57238D26C -:10CE700067E0F9DB3501FF168DD177EF7EB36F37B1 -:10CE8000FF5667F13DB187B7AB7B79A48B8FCC0E92 -:10CE90005AF87F50FE6284288F72A7AD2F40790226 -:10CEA000E1F725B3339ACA7F6D64541EEECF8AE151 -:10CEB000F06E4AF4CC71F1790F09E3F8B7A35FF192 -:10CEC000FDA4A4BF93BC5BE0D7DB1849FD3299F702 -:10CED000FC7090EF5E5A8F3B6931F2ABAEA6F578ED -:10CEE000300F3E2FD6A0D17A4F3A7CF764F1F293FF -:10CEF000ED83691E71921E4E96FEE58DB1BCDEC9B2 -:10CF0000434617FAFCA0C9E8B744A15CE0439B6321 -:10CF1000CDDAC6DB9D7A31D215C6CBCBEEAF7D1D07 -:10CF2000DFCBEEAA9F4569CD9A1B19AFDF79D7FBFE -:10CF3000A99E9C2BF15156C75B05E1F14E97BB1E94 -:10CF4000F87DC4E569C47A97E7742E619CAECE5B28 -:10CF50003A1E6346C6DE1DEA5985EFDD2F7CB20717 -:10CF6000DF399EB24A47F16598389D807E3B471372 -:10CF70005D2F97F49B9EEBB903FD713896B30CC6F9 -:10CF800022723A2C98075B33F85BD1C9E7EDBB0FEF -:10CF90006A7C9CDAF0F6064A8DBED1E8E78CE68F13 -:10CFA000D232088E1EECBFB30E7F14F0E131F03C9C -:10CFB000C74FED5EFDBAF067E2F3AAC5FFF076B5A4 -:10CFC0006D46B70DFB87F92C987F2DB304EAA7892E -:10CFD0007D083AE0FDECA4FD6AFFA0FC871C0F353C -:10CFE0004F8CCCBB97E3A736E6D04F26523DDE4EA2 -:10CFF000ED17E39579B59E2BE723D67756EE83B3ED -:10D00000FC8B19F4B32F4CD03F13F471FE892449E3 -:10D010003F826ECF3F31C287F9C4CB7D735EF31A76 -:10D02000C2D1EE47CCB59BCF8BB9DAC6CC1E85D921 -:10D03000B78D9913C9D856C9D76A07B58D01BF52A4 -:10D04000FC8B59DB46CFE6E52CBB6DF49C5101FE11 -:10D05000C74ADBB2E8BBAF2D0BED0F1A5835E0A97C -:10D06000E653F354F20E828755ECD79AA7AE26F812 -:10D07000A8715AC047C08FC12FA2AE5CF7CB2E4D0E -:10D08000ECFFC83109E06B03E13F3B71500E58C91A -:10D09000F90596DBDDBCDF11DB2CBA7E54BD913E79 -:10D0A000FDF75FA17F4E6FC342F039C4D8F34A1831 -:10D0B0009F2FFB198713BB72BC3765BB279FECC33F -:10D0C0009F51E09331A7A21B27C149E0E90F1685C4 -:10D0D000A7D5C99C5FD70226E901781DCCF524436A -:10D0E000AE9C471EF22686E779DA20E1AFF20AEE1F -:10D0F000A1F477D71F962477F2F6FFE532D0BC4231 -:10D10000E1BA96C30FE52D66767B296FFF79F38927 -:10D110008CD3E6C07A3E6E76BBB9A8E9CB2FD99600 -:10D120006BC5BE5BBA3DD7BA2808EE2D7BF34F38EE -:10D13000395ECFEE356124D662F2FD64421CBE1B1F -:10D14000DBBC8CCAAD6E5EFFACFDC89BA8B7647B30 -:10D150004C9ED11968BF745B89BB2A08FE57EFD576 -:10D16000E363549B3E7FCD217DDE9CCB881EFED1A8 -:10D1700076B97E7D3EFF843EFFC93BAB6FC63678F5 -:10D180007E9CD8379FFA227D560ED7EAF7679C809F -:10D190001CFDF4E0F351C057ED9FAA8E2733AC433A -:10D1A0004FA71C8F9A89AFD7BB47237A59E60BDD6F -:10D1B000BF926F5CB1AFD712BEB0B382E92614BF85 -:10D1C0006758DBCD6E4E5F754D6F67408FA99EC56A -:10D1D0000919F2BB6DB385D9AF1C6F20FEC1EC6E8F -:10D1E00027E3F457314E944D689ACE4EF1FED8A6FF -:10D1F000DFCEC07EADF8B146FA46C5B3235E05DD8D -:10D2000074ED5F703DA537CF24385432B705FC70FC -:10D2100069BBE68FE479C738E7A14EDE6EB14F7384 -:10D2200061DE8BD68505F819FFB76A53C83CB60492 -:10D2300095F3F92F3DF4CA571AEFBF7ABBBEDD3222 -:10D240000E2FC88F9A5D7F0F0BFECE152182D784DB -:10D25000F61D46AC7BB19CBF927FCC3B99617D13A0 -:10D260004413761AFFE172C332CC539C5B1890834F -:10D2700013B688F69CF15560DDF5768B13EBAEB7EF -:10D28000327F049FCF89488BDBC1BF5FDC1649FA30 -:10D29000C39230E6B5E651CA6C7968E78A46BB8F1F -:10D2A000DF32929E54CF790FF5F3B8E66B413F46DB -:10D2B0004DE47F26F2CB989FD603BA7107AFD3A770 -:10D2C000CFB3D641A497D499FCAF002E35AC93E0F0 -:10D2D000CD383EDD0A8E1C6E757C9DEFC542FFD2B7 -:10D2E000B75FCEDAA8FEF2437F0F0BFECEF54C6699 -:10D2F000E5F5B787F394E6EF23381A2DCC6DE0F30C -:10D3000034DE19EEF3921E521A0E3A354B7D79CB6C -:10D310003DEE2CCC7BBDE6CE72808F6DB6B9C0C71A -:10D3200016EE1072684B0CD75FE3486FA6F60BA1A0 -:10D330004F414F5920F8DD9698363FF8FE9607D3B7 -:10D34000843EF53723C1A5E73E9B6FA7067D5AE8CB -:10D350003D5B368FA0F6E097A44FDD1729DACF1694 -:10D3600070DD32D8E1F3F2FC1F31C524E8D9EE2C90 -:10D370002BB5E37A5A5A404E297DFA67C33C7701B0 -:10D38000DF6ABD4AFF66D5DF4EDFDC2DE567CF667D -:10D390003E4FDEFF69ADF4B821481F7E2057F0FFF5 -:10D3A00031D3DC7B643D17EA551966DF3B85CFB787 -:10D3B0006AABC1D99216803B73BBB300E7D39B6DB8 -:10D3C00079A0B331D3189D274EE60A7E1E51C0DCEA -:10D3D0003E9E6E97FD6ECF35E8D2C4704E7FBC9FE7 -:10D3E000D3257E33F01B59506A813CE4329CF87996 -:10D3F000E83AF6E60AB9596529FDCDA47EE6D34799 -:10D4000007C5426F39BD42DB29E625F03CE6DF6DFA -:10D41000AE165AB7989F823BA79B4292F7926FC570 -:10D42000F4D189EF091B47ED66A54F03FF9A8E4E95 -:10D43000089E5BEE1B45785C28F1CCEEB3493A615F -:10D44000ECAF282F7152F9379DB7D43A391D5039B6 -:10D45000C7B71FF80E3D6F297C3393AFB0347260AD -:10D460007C2F1A173346E3A04E36316F18870B64B2 -:10D470001EC1E51E93EF2E3E9FA12601FF1493A02F -:10D480002FCE9DBDE17954DF6DE1F98A07963237E1 -:10D49000AF5F91CC5C9AA8CFA2519F7763E42964D7 -:10D4A00006DA55448B7E2B1298EF2EA9F7835F6521 -:10D4B000224DA77EDD8658D13E2A8FDA7B0DA2BD94 -:10D4C000DBC4D3611962BFF4AC0FA3FD5371774A7B -:10D4D00016E860D6343D1DE4E709BA51E9E3794E18 -:10D4E00029675C89D8DF8BD68D24B9D1622BAD7FBB -:10D4F0000EF87A3A82F4C18A0DB7DD5088F93D33CF -:10D50000081A0EFBFCC6FD63406F8BD62DF8DEEFCC -:10D51000711ED96BA3EFED799EF3B9D0B73567F9DA -:10D5200073FCC3A279472D89BCBDA76DF6B91779E5 -:10D530007AA377FF9BD00B6EBCC948F56F646D7FF3 -:10D54000F923F8C23A31CE0DDE0BA644DEDF0D45DD -:10D550001A437997CD91BA82CFBF42E2EFAF721FE3 -:10D56000B4D8D8FC5FDA31AF94AC74FEFD0668AA7B -:10D57000FDE881E3F2A49E3855DB0EBD67D874B197 -:10D58000BF547DF4837E27031EBC9E59C245E539F6 -:10D590005CA97ED5C6B0AE8C28A466FF089E2E2E50 -:10D5A0009866CBE3F566A5B3193837F5DC61643BC3 -:10D5B00069BE3D15B4EF23B39CD8F71EC6FCC4F773 -:10D5C0007C2389EEBBA6F674DDCDF35D3B46B85AED -:10D5D00088AF8BF3FB620723F9DE3555F035C55F65 -:10D5E0004E3A3A23895EE579BE5292C6474DD3B78B -:10D5F0008EE5F52BED962EC883C50FCE8D72F27990 -:10D60000566EE1E7792EC7D826FD799E9FB733F293 -:10D61000065F792E0F3D7F83664047559B34A2C33A -:10D62000612D2E4B12F131CD81F555D9FD99907FA9 -:10D63000552E9B0BE5679BDD0F9CE6FAE1F9E69919 -:10D6400094B2CB1CEE7C9E5701797CDF8FCDF7B86E -:10D6500000A78AD60A3A4F46E478883F2D97743758 -:10D660008B835903BF317526611F76E5CAEFB18EF2 -:10D670002C3BD1B38D010E5D664716E6D5B5DE664F -:10D6800080DC9C7597A06BBECFAC26DEFE1E130B14 -:10D69000C77EFF1BDAF37596AD3595EEE0F9A1561E -:10D6A000668A8C055DE5125DFFBCC063061C3EFD0D -:10D6B000111B07BDA072D3669A8FA20B66EA281EC3 -:10D6C000043D6F775A1ECED78A8E7E5E30EDDABC6F -:10D6D000607AB849233AE0E92B19440F7366113D8B -:10D6E0004CF367AEE4F32A31D63137EC0C89CC1514 -:10D6F000C6E7DFCB7A489FE8E5FA04E499E2278A97 -:10D700006F703A705BE303F8DDD3CCA7C279F2DE29 -:10D71000662BA54F363B9889C3775F7322E59F69D7 -:10D720007652DAD69C4DDF7FD9ECA2FC81E671946B -:10D730003FD8ECA6FCA1E69994BED85C4ADF155F01 -:10D74000E270213EA4F88AE2478A9E145F0AA5A3EC -:10D750007227F606B527BEA7F81DD661C80BF023C1 -:10D7600085DF74ADD49B98063ED6B900FCA2C47880 -:10D77000F6E9E7397C7BABEDAE3027E022F85EAF0F -:10D78000DD4A723ED5C20EE1FCDFB2C2DD75779094 -:10D790005CBDB55A63A620BABDADD1C64C41747B01 -:10D7A0007B538C2E5FD6F4F6B104DEFFDF533C5E74 -:10D7B000E0E5E49D1F3FFA9FFCFBE3777E3E1CF80B -:10D7C000E6F3D8FD10C65D13DE378F58E4D79949CC -:10D7D000CE0C0B17E7A461E1E29C843FE0671113D4 -:10D7E000FBF4F13BFF4AFBBCAB29CC6984FE017C16 -:10D7F00071F87E20F1B5A8298CE058B1FED4D3CFC2 -:10D8000063BFAFB110BF5BB44EEECF8D1CAE417A9B -:10D81000DB87498CF433CDCD581387DF873FB2F8CF -:10D82000B9EC671F6A569FC61B6AFCD054C6BF7B03 -:10D8300036FEEA3DE8DB5AD309D28F3D56BBDF887E -:10D84000F979CD6783FBD39A8E533DD63934E6E31D -:10D8500008DA8A0C708C28705BC02740DBC0DFA21E -:10D86000EC230CFB9BB56A8EE17C5D55F27BD546C3 -:10D870008DF40E05FF27F28CB4AF4EE79A08AFD3B4 -:10D88000B0670713032339A5E896F30DB70FFBA381 -:10D8900035D7B224881F2F92DF2BB30D94AAEFA7A0 -:10D8A000F9B6443FD3B0B978BFF766A75B1613BF8C -:10D8B000735AC00F54FD45D9791BD20BD0CFD43841 -:10D8C00016B42F9FCB33C97939841CB37239C6DBA8 -:10D8D000D50D200F947EF229FE773CCD9FCE5F358B -:10D8E000CF3CF5CC8BB04BBC1F4678AAB946DA3793 -:10D8F000727C63E6925EE3B66B7C9D0D12FFC54FB2 -:10D90000FD29AA93972F3F20ECA73CED42DAB0A661 -:10D910009AEC650D2EBE4FB00F0E993FEC0CA2CBCA -:10D92000579F793FAA93CE17DE644322527F32E39A -:10D9300069C381533318FA633D1B1CF62BDB2DD7CB -:10D940002ED33953ADA3E4F097F134BE76299EEA85 -:10D950001F5E1FDF9F1D6439337DD8B77FC9CEE0BE -:10D96000D6D9D596B34D178C7CBECBD7CCFC0474DE -:10D970001E5AFF93BCC838D00F1BCBC6921DC3C420 -:10D980000CC0F74AAB8043AF6F7834FB1AFBCBF285 -:10D990006DBC1157B57A4DCE68179F6F37ECE7FD18 -:10D9A000D4CFC91772FD1CDF478C9FA5BAF719E9C0 -:10D9B000BCD0BD2F92E8BF61DF03C727F27CC32E26 -:10D9C0000DC3B27AD641706A386064D6607906FBBE -:10D9D000CEA081E759FB546423E869599BE6DECD6C -:10D9E000E7D36B75460F0E9A8F2D5FD0536D58DBC2 -:10D9F0001882AB9CFFDF253F53F596B53F6001BE13 -:10DA000078BDF3A4BFFC228291DD8CF5BC89799EA0 -:10DA1000D99EEF827D6F59DBFE0692FFFB221CC36D -:10DA2000F93A3E97767ED5CFE07CB19F06E70BBDF5 -:10DA3000E38CB4E79E79C6487C08F3C43EFC1C7AAC -:10DA40006ED03C93E53C93F3857E7304FBB130507C -:10DA50007F595B575426AFFFC9A1B7291D2EC7595F -:10DA600066EF180DB9F9C98188993E4A7F3AE325D6 -:10DA70003EDEB9B6A9715AD0BECACB3753BFE7B69E -:10DA80001B67025ECC3748EAF96DB49E33FB9235D2 -:10DA90003ADF02DE5CCF3F73E0D92803ED5BAF686D -:10DAA00027F168B00A3B6D588C53EA99D656E81BAB -:10DAB0000BB97617CDF95DFD810B247F43BFABFA1F -:10DAC000B4DF9270FEEE21BB06FF33807EEB1D02B9 -:10DAD000E725C69C04EC83F26B9CB7DC0A3EF69A01 -:10DAE00059E061A8F3219CABCADF1A44768B956696 -:10DAF0006702F25FBCCE0F827CDEE5F9727F27768B -:10DB000016C2CED99526E47ADD467E50E1EB19C2E5 -:10DB1000F1EEE54BAEF31999273FE0279A9F9F4E10 -:10DB2000EB7BA4DAE0B6909FC59F05BBE7490BF3FA -:10DB300092DFE89736E10F481776FD47A4BFA82E7D -:10DB4000D69F3508F62F89C7BA39BC3C089F753B6C -:10DB5000FD59D05FCE5A849D0FE50EA479A25E8B4D -:10DB6000A41BF4837EBBD21CE749CF7C2E9241DFFD -:10DB7000373C1F29EC0A3FB7ED0C0B929BD592AEB8 -:10DB8000B8CEE4C5FABDBBC5FC302FE8CFCB2CAD79 -:10DB900059D02FD5B8CBA25A69BCB372BC65E1ADE0 -:10DBA000C23F6111F648D4A7F1CD8CFC283D4F84CB -:10DBB000919EFA7952C7418CFFF9132319E47857E3 -:10DBC0009A6FC9212AE7FA1BC747CD93617ECCF72C -:10DBD000B327227D8CD7FFCC2CF4A1CF22E3491FA1 -:10DBE0003A11B9B59CFC32BBC234D8553ED3982506 -:10DBF00011E5BB851FA3A6B989FC0F357CBBB33CDF -:10DC00004A67B258948F247BCB67BFE6FB54A3EFDF -:10DC10001BF1DDC35ACB7F807DB73782EC6E9F3F0F -:10DC2000F95F23FBF35BD4ECD2DB97141DA8F27BE6 -:10DC3000245FBA47C2F1BE7C07E1BF3EA26D6B3ADA -:10DC4000AD53EC578E073A77F1FD110F7BF7C9B64C -:10DC500017E2353BE0ECCFFA29E0BE579C6F3EDF80 -:10DC60006726BF4BCDF3916EB2E3DC3DD600795110 -:10DC700063147A708D81838FA7DA9D7BB3A067B719 -:10DC80003C61CB033C38BCE91CD9B3DB28C711E3AA -:10DC90007EB62745D8F5FD327F7014D9F567C5B239 -:10DCA000DBE7909EB37D34E07A7157840174C1C77D -:10DCB000716B1C3E353FF8A18067F412D2CBF9FEA0 -:10DCC000237E5927F965FDDD13A327623FBD6564F7 -:10DCD000D00B2E9A5C09E087A1F0FA40F295DA8326 -:10DCE0008F5AE0B7ABE3FBC6C3F74DADF48FD53E1B -:10DCF000A9915E57BB61E243C407DF34B3E17C1EE8 -:10DD000067DB1E880AC6C771C9CF02ED5D54BF9696 -:10DD1000D717ED5F8BA2F9EC31BB309F503C7EEB07 -:10DD2000F64F1ABF55FB3EFA68E3727DF495EBBEE1 -:10DD3000C83ABEFF3EF8C93E1BD9AF38DE53A177C3 -:10DD40009C31B72DC1BACF3C6D233E732646ECF70C -:10DD50004F383FF48EC03CBE733FD9377E37974172 -:10DD60001E2CF5E9FB55E3BE26F96FFD205734EC78 -:10DD700064F51C0FE88FE3E5BBD4FE2D33B50F5DD2 -:10DD8000C793685718B43F9F8E207A393344E0E335 -:10DD9000CC332348AE74C5083AE7F34DC579E54C5A -:10DDA0008C481994114E0735F23C7A666A1B9DBF68 -:10DDB000CF68FB29ED328B76354DD26FCCE92E1131 -:10DDC00074039A843FCCBAA903FA04ECD563F22811 -:10DDD000F587C55E6977067D420E651408F9C53082 -:10DDE0005EBCF47F909ED266015FF6483DAE6EDF6A -:10DDF000957E38E0B76E9F467E2483EA87CF3A4E01 -:10DE0000D9CB393DD67A35B70DF359B76219F991A7 -:10DE10001A37DF0A7A57EBA835B199380F7569467A -:10DE20009A4F978DEF1BC02178BC20BD2B32300E4E -:10DE300073C4939E49CA754C819057C8B7F2FEEAE5 -:10DE4000D6699B689C3475AE14EB5370E260B1C028 -:10DE50005EC6CFFBA27C80F5AB7986AE5FCD6778DE -:10DE600081B05374A539EF2F02BEDF30BA704EBFB8 -:10DE700078393F3AF66BF4329CDCFAECC67CFE79DA -:10DE8000A0293EFF2F257FAB855D9ACF336BBBDE8C -:10DE90001F92BD4B9FBF6A9F3E9F73409F1FDDAE89 -:10DEA000CFBB5ED5E787C871159C70EE758E10E705 -:10DEB0005EA438F73AC3C4B917799C7B91E2DC8B36 -:10DEC000EF38F7228F732FF238F7228F732F529C7F -:10DED0007BF1BDB240F0EF3A6977041EE097612F05 -:10DEE000D8949F9DF64BF78278E29FCA4FDABD2CFB -:10DEF00087F27D769DD956B2EB90ED86EB25738740 -:10DF00007A6E282884FFB4634312F066EA247BEE1D -:10DF1000F217853DB72ECF66879DA173FD271BA005 -:10DF20003E650DF5CC41FD6E73CF1EA203939FF8A5 -:10DF300046E75AE75B5304FEC8DEC1ECB1743EA964 -:10DF400080BC8B1D188FA17E15B649EF4709F5AB34 -:10DF500084FA5342E940F9511E37F72481DF9F7A52 -:10DF6000C2BA09F33F25ED646CBE95F42FA557970F -:10DF700018ED04A795F7693B21A75615C452FBDE9F -:10DF8000135CDFEE47DEAAB4F252BED0AB557E93EF -:10DF900066203F8DC74D7268959C53AAD6D37537BE -:10DFA0006824D24072FCA2DD40E7828BEF18498FD3 -:10DFB00018B1CDA05BCF485FB88EBEAEDE1B1BE2B2 -:10DFC0000F1CA2AB7FCDA1F4107FE0557A3FD54D59 -:10DFD0006B5FC1F97AEEA67C5DBDAAD289217094EF -:10DFE000F3967A69CB9A6DA9E03FAB227B69FEABD1 -:10DFF0009EB3D1BD8B2A2E5FDC7CDDD5C870FE5868 -:10E000006D75DF08F855B7996360D7AA94F2873524 -:10E01000E9E571B589791DB101BAAB7630770C6F3E -:10E020007F2EB7758F81E3ED9C61FBD62227FC4BD9 -:10E030003B521D9CAE566B6DF1E3797FA7623C3B72 -:10E040000AF87E4E35FB7F52067EB93F83ADE5F57B -:10E050004E6D7A368AF46E4967A9664738F0BDA3DB -:10E06000D548E702D8A7600F52F4B0A3755078A640 -:10E070003DB0CE00FE2FD3FA385EE8DE48AFFDC8D3 -:10E08000D055D0E3DAC47AABA76A5ED293E57A566C -:10E090004AB9C2D6897E56CBFC69795E50EB3B3BD0 -:10E0A000F295D14EF8359B0FA51AC1C70DFBF6248A -:10E0B00041BF48F0B463FF54EF18FE9F457CDC9AE3 -:10E0C000DF1B19FCC81F6D991E351EFAE7D366D7F2 -:10E0D0002C9EBFBBF567169C0B6A4C3E0BCE9DD5A4 -:10E0E0004FECB0C0FF7FEDDE1DF47DC9DE0A3A6F54 -:10E0F0002F658D748EFCD42CE4B48247F5346DBB4F -:10E1000083CF3BB350F0D7EA70711FA4C458742C6E -:10E110000EEBDDABE562BD3795EEB754F0EFEF4A9D -:10E120003E1CBA3F7A5F9F5B321876A536E1071D29 -:10E13000683FCCF38FA4FD30F7521AA5375DBA9A29 -:10E14000CE55BF67A5A3884FE4849C675F370ABBA1 -:10E1500059BBD807D5167FDC5CEC9397CDB44FEA5A -:10E160004DB07DE39CCCD8049E96161975F4BABCCC -:10E17000384247CFF359ACCEAF7C331BA2CBDF3450 -:10E180002B4357FF969BAE0EA1FFBC4039F191097E -:10E19000BAFB2BF56BBC4E8DEC68D3F4DF79BA86F5 -:10E1A000E8EC7A5DFB7A3627500FE7E05DBF253853 -:10E1B00033D661C179ABDA20EEEBCCF774C9EF9DB1 -:10E1C000F49D2F44B70F8765B8FE53C84533D9E790 -:10E1D000957D7A3EFE3FA33FB9C8112DC78D360A03 -:10E1E000FB8247AF7774D0F993093CD44B7B4F7DCA -:10E1F000B6B0F7D47B3B2C8D7682BF299983A4A13E -:10E2000055237B1EAF6F4D8E15F935F87EC01CB0BF -:10E21000B330D1DF25949F305660BF849637F075B8 -:10E2200043CF6880BD86EC4C333F213B931A47F6C1 -:10E23000AFE874E936BDFDA801769D207C2E2B74D5 -:10E2400012BDD6ECDD7F7C0887CFDCD2985CECA3D6 -:10E25000BAB6D9E68A9C2BE94DF1F98BD506F27B4B -:10E26000F7BE7E94E8ADB7DA4474FD4D7069700B6B -:10E27000BB66281D2EE1EBB2F2F1971CD05C3E4D3F -:10E28000D4037C86803E43E093DC0FDC14BCFAE0D0 -:10E290001752BE14FF5380FB049ACF9FD61F5C42D7 -:10E2A000E0A9C60981171BA787C7128FF32DF09F1E -:10E2B00025278CCCF72DD6BF14EBC43CF83A318F10 -:10E2C000399784DD44F9136EBE64A27C1FDD94721D -:10E2D00078E561DFE9F7691F1D958A7D33EF523CD0 -:10E2E000B5FB57D1D337D1919ABFE2DB817D74174B -:10E2F000C98DE58591711F7356C1FFBF90F882E407 -:10E30000AF03EBA55EC1473D7A3933ECCE7174EFB4 -:10E31000A8D79E4E7A459F1C72E8CB5746A627A0E9 -:10E32000DC23ED768A1F7B643D354E052F770E0288 -:10E330005D0F8D873D76C3BA8CD4CE207DC5B3DE0C -:10E340001C0F7B61EADA419456D81CF19023156BBF -:10E350008DA5908F1FDE93103F0EF6F9F5E6B859A4 -:10E36000BCEB0FEF284865A3902FA1F4D4E6B0F9D9 -:10E37000C1766E956E2B147A68FD9DEF915C3B67BC -:10E38000783D6A3EF6DDFAE7A270F5A676FDDB631E -:10E390001C5C25B93BC6F35021F95177EC71006E36 -:10E3A0008E1DA361A7FE396C688303FA43CDFA92F0 -:10E3B00004D8C5EAFE76F431C87DCF5A733CF4CF59 -:10E3C000CFDEE1725123B9467AC3A73646E7A54F9F -:10E3D0007747F8E0BFFF54636EF87796195F19ED41 -:10E3E000D0C9D9F69B318FBD099E9F1716627CDF7D -:10E3F0009E448CEFF2D2FD4CCFDAE1D1FDD95154DD -:10E40000BA7C9BD0EBF6283BAEB4F7429F471EFA8E -:10E410003C1B21F479E4A1CF23853E8FEFC7A41DD7 -:10E420007F584B4F2ECEA3DE692CBB91E4AE3D1B33 -:10E43000FAFA2A2DDC457AA6E64A807D8CBD1323A4 -:10E44000E46D087E553AA987EB5C41743FE59295EF -:10E4500005DF339BCA6274F9E9D6245DFD12479A41 -:10E46000AEFCDAC491BAF2EB9CB9BAFC77B2C7EB56 -:10E47000EADFE09AAACB7F77DC75BAFAB3DDB37531 -:10E48000F9B93317E8EACF2BADD095DF327F99AEDB -:10E490007C8167852E7F6BF51DBAFAB735AED595B1 -:10E4A000BB99C304B9D78E731687FBCB3867F17459 -:10E4B000D51BC3EDC1782D9A6E68ECCF4E7F5EEA16 -:10E4C0004313C7BA3F037DA418041DF2D40D15E20F -:10E4D000B2942BC9CCAF89736E4712E826B45E683C -:10E4E0007951C4918B4E8EC32507636F35713E52AF -:10E4F00034F6487E06CF3F336681C84F3CF26C3A13 -:10E50000CF1F3CB8F55613E71F45D71CB988F2D189 -:10E5100063CB457E2E2395E3C898BF2DF4F2751486 -:10E520004D49DFE41276927EEF69AA1470C0FD4671 -:10E53000C001A99FD327D2239C3E91BECAE9B3CA8A -:10E54000CCD8714E9F484FF0F326BEFF869F37917F -:10E55000BECECF9B48DFE4E74DA41DFCBC89F47719 -:10E56000CDF3297DA7D943EDDE6DAEA6F4BDE64619 -:10E57000FAFEC7E6264A3F68F6D2F7C431CAAEE0D3 -:10E5800027FB8BF23335C0BF07FBDC21F3D9603F9B -:10E59000ACF2132ABF604B23EB8CC03EED34C57C3C -:10E5A0006C0DF8FB06E6B326F671901EB639D19DC8 -:10E5B0003186C61FEA207F8FFC3E4D9B9B02D7DF32 -:10E5C000ADA33D23C7707CCFCBAB5C1FCDF9C79407 -:10E5D000CB8D66D0CBEFE53DD5D0FE2F4B3A891BD6 -:10E5E000EB1E8D7693ADE21EDE64ABB86737D9D4EF -:10E5F000D9027ED4F22573E21ECD2B9116E24F2D67 -:10E60000F7987CB0536A5F30CA4F8A63946FF9B24F -:10E6100083EEE54D76B81249DEC87C9FFF1C7F4132 -:10E62000F765943F5BDD9329FEA2733AF480497647 -:10E630008B332CC4FF0EBFF52B91EFAAF9308CA7BA -:10E64000FCE4BBBE647EC3E8803F7CB2B5230D769C -:10E650008249ABADAEE0FB3FCAEFAD7DD161843CFA -:10E6600051F77CD4386ABE9126DE5F5EE01ECF642F -:10E67000475B2EEE35B4D4DBA9BF04FEDD9247F52F -:10E68000DC466AD7960B3BF0A43ABB0BF66DE56F00 -:10E690004F90EBE6F5689DC55F78E8BEC12479DF51 -:10E6A00000FD5845B917FD4C8AF32799B0FE468BFB -:10E6B0000BF6D04735DE3E2FE0FF47FD88A0FD8BEF -:10E6C00079A2DFCCBFF0F9426F77BB09BE73D5F9F1 -:10E6D000CD29F3523E33EB34B25F1965FEB7A33D4B -:10E6E000CB81F7D230C79F22689F67A4C0CE315B31 -:10E6F000EAED5F432FABFF7BE8C52DF03D94913DE4 -:10E700002D946E145E149E07A22385F7A0FB5A84F5 -:10E71000E7BEFB57B29F50FA1A88AE143D4DB60AB9 -:10E72000BC03AFB847A3E848FBA26D07ADA3CE4A30 -:10E73000724ED151281D5C4947822E5BBE67A5FEF3 -:10E74000AEA4A300FE018F7F9E8E3A8C90BBFF2863 -:10E75000FDDCDEC36644F3A27BAFF15C86DCA8B8C7 -:10E76000E43C8E7C259B3A0324A5CA1F40F9E02B8C -:10E77000CB43E94BD57F7180FE3C5FF498A383E8DF -:10E78000729294817F18A0FE6BF25EFC6B3675DF8F -:10E79000C36DCFE574305DF2E1552582BE66A619E2 -:10E7A000C99F313D6729E9F7CC2EF46327FF87EC39 -:10E7B0006DD2BF7EBD6C37E372E93A8C33234EAF26 -:10E7C0007F5F2FF5EE9921FEF6EB73AE253DFCFA47 -:10E7D000103DFBBD31528F4E6369E27CBD89F4DF91 -:10E7E00062B91F9325BE339C4656C4E15EC23C26E7 -:10E7F000088157CF5BDCE8EF5AE6A5FC75CC47E90A -:10E8000077989FF4801BB8C040FEBB8CD1FDD1A38C -:10E810001137962DE7FD4DCF9F9E89EF75D69E54FB -:10E820008B01B7033D9F413E34183D7F869E792E74 -:10E83000C53302E7E323C54ED2C38E5833482FC4F5 -:10E840007E3207D92B7FCDE56826977347B99C4563 -:10E850007A8CCBD94C2EEF7EC5E52CF2D767AF650D -:10E860006837C3A9BFDFA3DA7FC7319D99060D2C96 -:10E87000C7BE33FA85A1B063BD1633A218787B2DCD -:10E88000666C31D6FB5A4C8241A461164A473D9FC3 -:10E89000D99FDEAAE83530DE0C1A2F14BE0A9EA1DD -:10E8A0007054F0FD27E039686CE195F0BC0CFD1E5A -:10E8B000F653EBDB5189E9F033CA78BA08C107EBAC -:10E8C0009F1F958075D459055C26354DA47472D36D -:10E8D0007866CA273F9317F0FD0C4B80C139C4CE30 -:10E8E000C64CD328FF3D495BD9099EE198C7D93C66 -:10E8F0007F16D7C8D827DB5BA2703FF3DC334617FF -:10E90000CE357546E72617ECE4AF19455CD0E5A394 -:10E91000A9F06FB25DFDDF97AEB32AF87909AE3F7B -:10E92000BBC64DFB8DC13B1B1FD06B8686897BC64A -:10E93000E45EC81B58CF19132EF8CCD030C11F1578 -:10E94000BE783B2177793F63385F4BBE3F9CCE3525 -:10E9500005C3DC45580F3F2F505C516F7604D92B0F -:10E960007E23E31227FBAFA6B8BC9938B7F3EFC6F6 -:10E97000F0A89DD8F7BF917189BF18E4B916EDAF23 -:10E980004DCB4B043CA630E157B9CE6A76F9F99CE1 -:10E99000AE1B2BF7E168365AC6F5E8CE1FCA4ED239 -:10E9A0001B6724393499653D043B41F10933D9098A -:10E9B000FAEEBB250ABF68EF898B46F09592488D29 -:10E9C0000D4A0BC4E784251A9833486FB739C399A9 -:10E9D00033687F4464C7EAF291AE21BAFAD1E3D238 -:10E9E00075E531EEAB74E58366E6E9F2834B27E823 -:10E9F000EA27CC9FA6CB2779AED7D54FAE9EA3CB27 -:10EA00002BBE972C3EB194C685BAF6C39A16E9EA96 -:10EA1000A7796B74E50A0FCCEBEEC88E075F147F05 -:10EA2000191B57EAEAFD344AC49BCCB42F9985FDE3 -:10EA30003EBCF507FA79195FD7287ED429F8AD973F -:10EA4000FF033A2A49D4F3DFE90EBD5D23B9D1A40F -:10EA5000CB6FF847F1ECB94A87E7507870BCBBFC44 -:10EA6000A8CFE5B797E74B7E5D69827E01FF45F051 -:10EA7000FCE1BF085E2FFC17C179F82F82EBC37F42 -:10EA8000115C0EFF457079FE093D9E0B3BF4781E2C -:10EA9000FB9E1ECF8AFE06C2C7F84E3D1D84E26370 -:10EAA000E2A7217421F1309FFFD31F1EE828C2E99D -:10EAB0007F7A2323FBDC37E1E58510BC4C1AE9693A -:10EAC000C77E9D3FE862AA0578EAF18CC079F233EF -:10EAD000692709BDC7E9E5EA00C521FCC048F1374F -:10EAE000270DAD1AF8B23FC5736C2CAF7F7B4E2358 -:10EAF000D14F222BDDBF84CFA7FC3FC2C88F533E2E -:10EB00004CC4EBB29C4E8A7350FCAE3C59DC237A69 -:10EB100063AC3CBFB9C47DA28EB1429F8D7439E80D -:10EB2000DE71458E88E3E0C7AED4F251A09FD76D69 -:10EB300023400F5B84DFA413F1C271817861E89BED -:10EB4000D0EF52A47ED5F207AB15EB18B18DE9E4F6 -:10EB5000E4489F5577EFF5EABD0E5D7E545BA2AEAB -:10EB6000FE35879CBAF25C7FB6AE3CFF844B972F94 -:10EB7000EC18A7AB3FF63DB72E3FBE73A6AEFEC462 -:10EB80004F4B75F964D6F330E03B4C13E77D2BE730 -:10EB90004B740FCC29E281CAEF8E1171A0D20EA066 -:10EBA000F469751FDA23E92E544F1F66117A6A4BF8 -:10EBB0001213E730AB3C6F31BDBEEE91F799959ED5 -:10EBC000CABCFAFBCCEA1E739F5E2FF576A51F0721 -:10EBD000DD637607DF632E97F1DBA1F22F6E9CB029 -:10EBE000EF85CE7F9845ACB7E50E0BC58DA879852E -:10EBF000CE67799EA0DBDDD6FEE377D2C769D47FEE -:10EC0000516EE99071BCDE6366978FEC28578CE7F4 -:10EC1000EAF4E25CF9238BEB2EE7378F577E8D58B1 -:10EC20004F99C170FBEC1CBA2F36FF9741E3E78D7B -:10EC300013F41D3F41EB777DE5D1E23E178BB638EB -:10EC400041BF038F27E0996861EB28CE48DEFBBF08 -:10EC50006D53DB7D23785199A5D54CC60BE63383E4 -:10EC60001E664DE3FA542EEC822F3E62E7FAC6632D -:10EC70004D26B2F38C1F37AC8C6B627D711CC3F8D0 -:10EC80007903F4019D05E79427C71B699C85E3C4BC -:10EC9000FA4A8C97FBEEDF93FF8231C9BF19DD87FB -:10ECA000E987DE880ED53AFE55F7F115DD86C249B3 -:10ECB0009D2F99943B99725E0A7E6A3F28F8A97845 -:10ECC00008E70A73E94E3BC555CCC43D3285BF9772 -:10ECD000C70B7EB409F02814F5C08F06AA5762CC82 -:10ECE00089863DBC9739A31D5F63EFFD17C62910C8 -:10ECF000FC078AAF1A883F5CC1170688B71A883E9E -:10ED0000E9EF1F88BB0AE20FE25E8FC4872FD34072 -:10ED10007EF4BB23F5FBF8857102BE1EB98FB97C6A -:10ED2000B5E7EAF90483FDBE65BD51F2092157A19B -:10ED30006FE0FBE2F566D237182BDD8A38A28FB67A -:10ED400098E97EEB64B773864BF8E749EF20BF176D -:10ED50009F5A85572F4FB97CDF093D780A736D8024 -:10ED60003FA372A3BE7CA97DC66790E78B43CEA567 -:10ED70004BE5797569C8B9F4A971521EBB988BF43B -:10ED800024E9E7AF9675FAE8C897112DED2EB43F48 -:10ED9000794AF7C2145C9CF0D7E407F21C7EE1D9F3 -:10EDA00090D3EB4CFDDED7EB83DF00F711CEE23ED4 -:10EDB0008213FBBD97E2AD7A0FD8849F52F983642A -:10EDC000FDB3DE8B548EFAE8ED5C6EC768E8217DFA -:10EDD000FEA3103F54AFDD10350EFDED33537FEA37 -:10EDE000BE45CD5F7DA31D41FE644FA75177BFE5B2 -:10EDF0008AF9AF7D8EEE5FDC1DE379077CFC8CC960 -:10EE00006505FEEEB11F89479CFC2C69B7099D6F13 -:10EE10009FDE59A4093FAC57C4CDF6CED4E81E00FE -:10EE2000E7830CFB46DD1B98CDFC7148953FC6B3CC -:10EE3000713CC159F9632AFCE3699EF35A969AC35F -:10EE40007995CE87D794843B037E9ACE1471EF6771 -:10EE5000207FCDDC4BB9D4DF4D9726523F17C7A595 -:10EE600009BD6BDD7D2B404757ED6566ACB333E4E0 -:10EE7000DEBB4A2B25BFF18E577C5ADE275AAB11D9 -:10EE80009DAFD498BA5F447C5AE52FB6CA7C89C836 -:10EE9000AF5A2FF29D66F1CECC1E696FC03A9162D7 -:10EEA0003D3817EF93F608AC0329D681EFE04BC845 -:10EEB000832F210FBE843CF81252F0257C5FC44A98 -:10EEC00053738DC2AF541CB46FE0572A0ED27BE04F -:10EED000570ACEC3AF145C1F7EA5E072F89582CBB3 -:10EEE000E1570ACEC3AF145C1F7EA5E03C1B775DE3 -:10EEF000200F3EE69EADCBCFE5FA7771D0BE855FA1 -:10EF000029B87FF89574FD7956E8DADFCA9A74ED6E -:10EF1000E1570AAE7F7B93A6F33BDD2EDF03A8DC2F -:10EF20003688E8E3A5D1A5AEF17CBFFE39E26FDFFC -:10EF300033E31C606C5F06BA5D591FEE12786E9D5C -:10EF400029F06E6002CF3D0B08CF6B2C225F22EEC2 -:10EF50001FF7E7BF29360BFF0D52F86F90C27F8372 -:10EF600014FE9BE2E1C27F8314FE1B7C87FF06290F -:10EF7000FC3748E1BF410AFF0D52F86F90C27F8312 -:10EF800076F0DF2085FF06DFE1BF410AFF0DBE9F5F -:10EF9000841F29E8DD0CE8E999BA731DA743DDB9A0 -:10EFA000CEA1CB434F0FAE0F3D3DB81C7A7A7039DE -:10EFB000F4F4E03CF4F4E0FAD0D383F3ABC739893E -:10EFC0005F425F0F6E077D3D383FAAD57B0CB6A32D -:10EFD0001BB69F7F156967A4F698C659C18A170E9C -:10EFE00094C1CFD669D3526338A7346B2F9615F3EB -:10EFF000BC47DEE31BCD7A0CC037F9D939DE3C7E45 -:10F0000046F78E477D9544E5CAAF4B7F1CEFB907A5 -:10F0100018E9FDC764BCA76AEF620E2352553F9002 -:10F02000EFBF5EE8F8AA1EF1CBA079F083612EEE67 -:10F0300099E4AEB1E7E1BEFC1E8326EE9BDE25EE31 -:10F04000FB86D2D56EC997F618F61F09C7FDA10A2F -:10F05000CD8538862C133B61CE039C1AF3A01FDCB0 -:10F06000373E46AEAB7102EE1FA9792B3B20E7136A -:10F0700014BF56D4C32C557C9C495F30CB62F077CB -:10F080008BD00BD00EE7C5ABBD9A7B67107D3F34AC -:10F090005EC8378F77C5842AFEFDEA7D8D13101771 -:10F0A000372B5CB4FBF9E35104C71BD7693B117FD5 -:10F0B00058B48FB911EFEA93F3BE7A9FC35245E378 -:10F0C0003A289E4EF55BB13D95E2FF2A586731E242 -:10F0D0002B5881C6E01F5570E3EB7B15EBCBE25B51 -:10F0E000C54CFAA788CB099771392A1E272CA6B4DC -:10F0F0000A724BC5E54C2A8829C1BD38D6CE5C08BA -:10F1000003BEA1A062FD60DEBFC7E776E15ED1A4C9 -:10F110002F1A8F517E5729E5890CC6D03824D7463F -:10F1200078357A5FE346EF0E439C13F1BA6BCDF16D -:10F13000A8BF8FB9A0EE70514371A76A7E39ACC3E6 -:10F1400060D38077767450101D710E7013F09EEBB3 -:10F1500032D3FB1BB34D0E33F846A81CBFF2DE6260 -:10F16000889E1072BFA465CD7BA9C674DC2F31B810 -:10F17000FCE05BCF4590BEA0F49D0A79DFECE2BADB -:10F1800063836FE1E515FB857EE0D9A611FF53F798 -:10F190004DEA337CA906E80B43768C8E350AF90FCD -:10F1A000BE78C6FBECCDD8A215EB8F515C44C5FAF6 -:10F1B000C268111725FC1055124E55F25E11CB7125 -:10F1C000C443CFFC90F31DF708BA97184D7185AD75 -:10F1D000429F53F616A50FAAF7632ADEC83F0EBC5E -:10F1E000573C2ADF65D95841F157A1F77C6AA5BE83 -:10F1F000B76C9D99EE0F2D0BD1076BE57DA1DA1051 -:10F200007DF0DCF8107D509E5FD47DDE8A378ECE97 -:10F21000237DA5D14C7EB9B2B5427F61FB990FF138 -:10F220000C656BA71BF06E48D9736E97D60F9DBC0B -:10F2300025F598599D3682EB9C4BC994DE7C298933 -:10F24000D25B2E897B94887D011D74BEC0488F7E61 -:10F250005BEA2DF370AF12F188DE30797F9291DE98 -:10F2600094CB1C25E01F57B9B5A350FB66993DEB25 -:10F27000716F73D60E46F1473740BF41FC17F41D3E -:10F28000D8DD0BD24A280E63A646F12C3714AC9079 -:10F29000F4CDE99D81DEBD927E4B29DF2717249DA9 -:10F2A0007BBC5D26C0FD06AF66C13B7C1E798E55DA -:10F2B000741C4AEFE511D2FE6417F6A53EFB132637 -:10F2C0008B476DBCD1B7E17E6B396C764398403C7F -:10F2D0008779648E281FF162F46DEB70A8F9BFB4D2 -:10F2E0004B94190C22DE89EB5BE0ABB7ADCEB52CAD -:10F2F0000AE22F5F4C9C3663626100EF8B42E2F4BE -:10F3000056DE333CE1EBE2452B399CB14FCAA33BBF -:10F31000BFC729945D3B81B98BF999750163EAF107 -:10F320001E3FEE052E94F9D52F8EFBD3463BC187A9 -:10F33000F2D327A4DEE625BE2AF8D6ADE05B46F080 -:10F340002BCFD409C4AF3A67001F11393DF21D021B -:10F35000299742EC10AB2738C57A43EC11953982D6 -:10F360009F339333F5568A0B76923D4FCDFF43B3CF -:10F370003E4EB3CF2F3241CA93E67F4D7CC3FFCAC6 -:10F38000F0DC86F56D3588B8F921C65626ED42B415 -:10F39000FF15FF60F21D8900FEB99E467E74CD11F7 -:10F3A0008C7FCF464DC4A90F60BF61D93D0FEF865A -:10F3B000FDAED9C210E7FA7896A0A3C77F60213DC1 -:10F3C000BCCCD2710CEF642938BEDFF4EF66B2CB4F -:10F3D00033FF70BCFFB5B0D1E6027FFE6262E92A5E -:10F3E000CC3B22C745F898C1B719FA3F9952FA7D2C -:10F3F000C2D7A6571E43DCFEF2F6348A23AD3894FA -:10F40000BB01EF897C31D1F3C309F0E3DA1D16C8E3 -:10F41000F186753124D7CA13645C27EB213F9582AE -:10F42000FF031384FDEABA2241C7DDF23C028639AC -:10F430005B574FDEE30ED927CA2E186A5F087DC7D7 -:10F4400061A0FDA3EC08B01B5882EC8ACA2E61CEE5 -:10F45000FE7001E46899451F7FA8D25795DD4D9E47 -:10F460000717F7C9B19C1909D09B376B0EC8B12A91 -:10F47000BBF396F13C5F75C28C1B986C56AC53BCC9 -:10F48000DF718F78BF6311DFAFE03765F23E56D58D -:10F49000B6F1B4DFAA7C3CCD1F785FDEBAF968CA4A -:10F4A0000BA01FBF9BE2F2AB1C6E4B6CD0BEAF6CCF -:10F4B000D57471FD2A7F6082B0C39571351DF0BB94 -:10F4C0006D759A056FE89471F502F7FB5E9DE0D4C7 -:10F4D000C555F37A74AF61563A3B2EDE4FE2F34ED8 -:10F4E00013E3E505F5BFA855FF3E01AF4F7AD1CB39 -:10F4F0001322097F150EBEEE34A40E9A278703C18E -:10F50000A9E73EDE9F93C6217C54FA7D669CBBCB67 -:10F51000709F82E7173A7C668CB3689D782FC4B3DE -:10F52000498CE3D918631905BDC9E4B0A4007E383D -:10F530002CC7D1FC880F5671B820DE4AC55D86C243 -:10F54000A742CEB7AA3546AF8FB56E36031F0B065E -:10F5500078AFA047D2EDA2755329DEBCCAE4A678E5 -:10F56000068F84EF472B6CF7C22FB060CB43E63495 -:10F570009CB32708FB738FDC77B3D2FDC3E95DA092 -:10F58000153617E6B9C0D14AEBEB83EF831C1E1A80 -:10F59000DE9F2925F872BAF0E27E5ED5163D3E0365 -:10F5A000F311F0ADDA5241FB6D89C9637104CF6389 -:10F5B000DB2BC3710F6501DFDF78EF88393C14DF87 -:10F5C000F4F183B7A4D23AF93CE91E94CB3903EFA6 -:10F5D000FC703A213A56F4A2E2B2D578D689222EAE -:10F5E000D33AF19BF6A59BF49A168E5FD8BB07DA47 -:10F5F00097160476F1712D55E2FDB5D07DAAF6A7D8 -:10F60000DA976A9FAAFDFB98B9D49FA805F80C97D2 -:10F61000B78DBFEC074E33E47C174ABC72B8BE1AF4 -:10F620001CC775CD4481D7B274FD7E477FE837652E -:10F63000A2D8EF65D3FCC31177A9EAAB71CB6245C1 -:10F640003BD03DE82D65A2A1AFFE4AAAAF8F47A9E6 -:10F65000ECE317FBD6C7835FECD748EF5D79DFD1CA -:10F66000947F833EFBB4D067CFD4ED6E4882DE68D2 -:10F67000F2A506BF8B55E517FC6131D77FC02F96E9 -:10F680004839DD9EE7C99918B47FAB1E783ACB2381 -:10F69000F88B1FFCE583A75FFAFD0467407EAAF99B -:10F6A0002FDAF85B73853D185E627DF766F7529C32 -:10F6B0005DA5DDE2C4FDE5CA7515C46F59223F574B -:10F6C00068017C87D241C53A8DDE17AB6C1AE333F3 -:10F6D000FE37F2E5CA4DB3E94D248527F5DE899260 -:10F6E000A76AFEDF95F35F28E978CE44B1FF16568E -:10F6F000A75996D0BE4FB35482FE65F9822AFDF712 -:10F700003E3CF5F9977336607F206E88CE279BCC00 -:10F71000C2CEB72F92F4D5332B9F7FF3665EEFF303 -:10F72000AD3B52A19FA8792C95F6BCC5D22EB7440B -:10F73000EAAD1C4F15C1785AFAB8C053E5336FFCD7 -:10F7400009EF7295A54B7E769F88E75FD4B69FF050 -:10F75000B660E366731AAFB762629AEE9E4C652399 -:10F760003FE872782EDCB8C30C3EB062A2805B2802 -:10F77000BD97C9FBBE0AAE903B5A90DF42D507FF4A -:10F78000DBCFC759BDC21605FBB41AE71149D7959F -:10F790008D31B118AFB2B1E2273877287E1FBAEFAA -:10F7A0004ED9C47E58C4FBC3BE3C35D54571CDF09F -:10F7B0006BF52757374BBCFDD42CDE6F4C8E687B26 -:10F7C0000270485E1EEE027FC8CCEC24BF31E819FF -:10F7D000F3B618C47B8F99759D17300FAE52D3FDC9 -:10F7E00014A478670A2A763CCFEF3488F8AB74A368 -:10F7F000489F97F0E1E57E94B3B84E7A77AEEFDD9F -:10F80000A4107AB5B05D1BF1DE8D258EB95A9C012E -:10F81000FA54FD28FA54F43BD0FA7E21F9C837ADEA -:10F82000EF549AB44764BB5211A7527EFF0817ECFD -:10F8300033DFB44E8B7C7FB06FBD9C58C7C5F6B329 -:10F84000DE4C716E1978BD5B4AE2FB596FE83AD520 -:10F850003E5177DAFBFC0BADC2BF704AE3F28BB7C7 -:10F860003BB5C246F7BFD4BA94FDFBDBC621BC3D15 -:10F870003156DA133A23A1479685CBFDEF17797CF1 -:10F880009F1DF45DC97DF55E9BE2CFA71BA55C645F -:10F890009DF7613FB3A60C7A9FE464EBA948BC973F -:10F8A000726AAA989F6AB7DA2CE28C59A4C589F7C4 -:10F8B0000FF9F9EA6413FC3EEB12E81C795B53067E -:10F8C000F185DBBC31C2FE20F5FB25920F46ACAEC4 -:10F8D000D88077BE176F4B73687C9CC576D7C7DB23 -:10F8E000A8FDD52EE883115B665BD249EF15E700D2 -:10F8F000E5275AADB1528A1B039FC4FE32BC920960 -:10F90000B9B3749B3807CC32B08DF0130E6B299DC0 -:10F9100091043EF1B04671E66CBBFE1DABB1F9A59A -:10F92000E7E9FC17F20EDC6A739B3B017C9CEB1B46 -:10F93000B0372DB69792DE5E2FF9E4C92D5DF41E27 -:10F94000BD82EB15F13F161107DC1369203BDCB7D4 -:10F950008D03AA927E254537CA2FF508FE331E7007 -:10F9600032925C2B3196D17B4A1BB64CA7B46A739A -:10F97000C956EF28C41F97C64FA0799BC94E56554C -:10F980003F5DC4EBEE0C8BC1F926D5EC4D0DD64B8B -:10F99000AB76DC4DF13F9FEEB051FC4FB163767119 -:10F9A0004C1CBD774CF175AA5E6A91E03B35F5D3EE -:10F9B00075F13B8B799F7867F3CBB608BA1FA6E247 -:10F9C00072EA123C494583457CCE78A788CB49A290 -:10F9D000FACE7EEDE22AFDB859C47904C51BDDB824 -:10F9E00080B7AFAB7F360AFDD43EF8F6188781ECBE -:10F9F00050C3D17F5FBCD136116F9425CF4BB3621A -:10FA00004B6F5E00F8FFDA48F01F68BCEA439ACEFD -:10FA10008F779B2F9AF4568F9F59E047F63818E955 -:10FA2000C59F1A5913F400A5BFA8EFE3255C3E8DCE -:10FA30006E4D057D2CDBF3502AE4CB6791225FB637 -:10FA4000E796DF805F79768509FDDCC4481FAEF458 -:10FA50000AFD9A55C7AAF7486DE59C8EA6174588FA -:10FA6000778FB6E9E3CDD53BB79F99C4FB3C883788 -:10FA700002BDBF6FF22F067EDFE7FA2BCEB1A9459C -:10FA8000823EDF6F35CEA07B437CA3400F79BFF56C -:10FA9000D948C4432B7DADC4F8811BEFFFAC7C4E2D -:10FAA000C405E37D7A7A2B54DA411AA41D64E50B70 -:10FAB000E619C971A47FD1973A93DFD21FFE6AA4D9 -:10FAC0007ED5973FB09FCE6D75FB84FE50D7D6454F -:10FAD000FA83D24754DC61EDBE2ED22754BB860395 -:10FAE000022EF507C4F78A6C83B2A3B8B54C9CA765 -:10FAF00035CA7B5FCC2F5F6B0ACEE795AF05B39F0E -:10FB0000A0EC233DA40FDE9BFD3B3A87D7AF93FDCE -:10FB1000F2BC3968BC6A1051A1F89E61477BA7EE20 -:10FB20007C577F2086DAFBEBC33742CEBB1BEC262B -:10FB3000A42DF57692FBDB1B0DD9B8A7EED6C25DDE -:10FB4000D0E3DAE5FDADC1B5EFDA603F48623D478D -:10FB5000F1DEAE3FC5F3C322DE6F025E773106E20F -:10FB600089BA0F7F928FFE270FEBBC883735CCDA2E -:10FB70009472F8295A8AE43A723AF341D7838F088B -:10FB8000FEFCA8996DA4779B4DA50CF67BBFF42FC6 -:10FB90007ABF32D0FBB3ED9AFF67C1FAD521499FF6 -:10FBA000A561C2CFB873B46713E6F15DCD3C2A9767 -:10FBB000EE1D1A87A3FF6EE987547AEA34C99F5372 -:10FBC000E4F9CA3224D10E3A56F7ED34B79BE23D40 -:10FBD000EFCA395209F9FCE31E2BC50B4CEB092780 -:10FBE000BD3565C84C9267EADD7615F77324C7E02A -:10FBF000C57BF43F6656712FC01AA2DF1A6C743FA2 -:10FC0000596BFFD557E0EBC9C60B47A3715FF6DF11 -:10FC1000347A7FB4BCF7E347DF62380FFB72291EEA -:10FC20003AC5B307EB39D93BB3CBC351F763479B15 -:10FC3000D525E4050B5E47FB1D5F45C51A02F3EBB6 -:10FC4000EEF998DE75ECEEB192DD765ABB7CE730CA -:10FC5000643EDD894EBA27CDEBD1FBCFDD7603BD07 -:10FC6000EF36ADFD28BD57384DBD6768D5BF67C8B5 -:10FC70003A52626057265B2A570EE25B04FE264723 -:10FC8000EBCF8BAF15097DF1B522ADDFF7EE55DC7B -:10FC90008A922B2FDBF7DC26EC52629F2E577EFEDA -:10FCA0004BE9A44FF4B6677CED3B166F43AFE0FA27 -:10FCB000C2856BDC6F171506E4EA3C0927259F55C2 -:10FCC000DCC23C09AF797683804FC8EFAE28BA0911 -:10FCD000A58B50BC2B7CB21F741C433C16C7E3A8F9 -:10FCE000FB19E1EF24E1EFABD7D7E3D985214677C4 -:10FCF0009727EDFF45FCF96D23A0473C68203D4266 -:10FD0000DD77F4C8F7DAD5BD4796CD881F941BC3BD -:10FD1000C95EE891EFB4733E700C7C40EDFF613337 -:10FD20003B47418E9EE44774CCAFD3D046DF532788 -:10FD3000A5D37E1DCA3A92E4FD9C42E86FC6C0FB83 -:10FD4000D444F72D9AEFE125B87F39CF4EF7DCBBCD -:10FD50007D21EF53CB77CCBB99E40FF3D53BE67C09 -:10FD60003FF3765B1688F2BE77CC87333A476DC98E -:10FD70006559D0BFD4EFFE0CF88EF9B258B29B3E55 -:10FD8000F2886F24E4817ABF7A4A8A2771D2E02B05 -:10FD9000DFAFDEAA952EC0EFC0784789F9762E082E -:10FDA0007F668F00B71FF69E934D91F46EB7A253F6 -:10FDB00065E71EE6ED7A18705271B57F96F4A6E0FD -:10FDC000AFE20AE342F0A0E8CE6B6614870B7C201A -:10FDD000CEA8EFF763D648FEA2E23A5F763991FEED -:10FDE00038D5933B09FB70058733D9D13BBF87F5E5 -:10FDF0003E7A47A41BF33B297FD722745F154D320F -:10FE0000287F31C50D944BF956AEE2049AF4710285 -:10FE1000A1EF9C860F2D9D0CB89DD3DE1E838FAF66 -:10FE2000FF6F63BFF74FAE9D24F84466A267C624F8 -:10FE30009273D374FAE4EBB99FA4D0EFCC5C3E3A52 -:10FE400014F2EF9694D2EBD0AF2D53F80FFE9CD462 -:10FE500049711E7F5EF0D714B23FAF11EFB37EDB66 -:10FE6000795E19D72CE861D562712F319935121D51 -:10FE70002706E2656D98C7FFB4B8E640DCF15EFA8C -:10FE80007D91979BDB324E0FEF07EF61479E75F236 -:10FE9000938DF7F0CBE514F71B7D64551ACF6F3CBB -:10FEA0007CB49CE27C938F5C4CE3B8B9F7F0AB2256 -:10FEB0007FF5918B880BDE74F898A80FFFC110C6F0 -:10FEC0007E72F878B997E3E38ED19EFB81AF9B2FCA -:10FED000351E8338FEFDDA398BD328AE75764AB6E7 -:10FEE000886B5D07BCCF8B5FB43E5A0BC4B5EE9BED -:10FEF00024DA755F10FBA0FB82A0F330F083C1FF12 -:10FF00007CAAE27B151F1E885FAA7DF8AF8A4F5638 -:10FF1000FB99ED716D348318BDFF74DCF093936829 -:10FF20005DFAB8E16E73CF63E457BAC09CE013AFDB -:10FF300044BEEB84BC682914718D5A4F8713F73186 -:10FF40008A0A44BEE54287137C1E79D8B7BA634457 -:10FF5000BCA38A8B6DB9E04FC23E2942FC22AF5F41 -:10FF6000DCD3530E3E5A84FBBC69E8FFF851391EBE -:10FF7000437FBB2E88B8C36E5B87D321C7413F7CCC -:10FF8000DC34F0C7A2D556BA77D472A17105F55307 -:10FF900066EF1B570B19D7FAF5E34ED782C6CDECA7 -:10FFA00015F19D18D7A91BD74F71C1BC3F8A3FEDF2 -:10FFB0008E7125E2DCAFF2C528E7F987E4EF54142F -:10FFC00039FD46C8011527956091EF71CB730BAFD2 -:10FFD000477199BB7AC53ACF37FB6BB09F8A25DF53 -:10FFE0002EB608B9C90CE12EDCC72E315E3E9E8CC0 -:10FFF000F3C90BE27C521C56BA1DFBB1C124F80DAB -:020000023000CC -:100000008B53BF97D6B1ECE7BCDEEFE293E9F7C5BF -:1000100086261E6499381F2F9F9903B9C1F5EE33C8 -:10002000C0F7EF58AB267E874BB49F3B3382EEA1DF -:10003000741F1E5188FD3327CCF91CE3FBB677D221 -:1000400057B44FE7443B0B71E2E93DFC5F229FE070 -:100050007C0EFE5D2BFB8AF473E5AFBD25E0AFFDA2 -:100060005F18A77EE6398BD0CF7AE89DE6FF9A2409 -:10007000DEA7E3FA3BE91F3DD7C97737739C852894 -:100080004F35F744016EDD974DE2DD5AD6137553B7 -:10009000907FF6B176F19E6D285D1F9E2CE4C0F234 -:1000A0004C3BBD77D69068B552DA7E6106FD1E8C5A -:1000B000A93413E703B7A57FBBE32F260B7995B6C9 -:1000C000C112F0BF73F9E10E672AEF65E318DBF1A7 -:1000D000FDF0BEF317448C65B83C8F79131F2F36A3 -:1000E000E9EABB51BFAF9C8967DA54FB9C97ED8F5F -:1000F000AF33C9F180E725E2FE44A8BC689812DB63 -:10010000F75E21C9DD381BDDBBCA344A7B1EAFEB6D -:1001100020BBA0F0DF26FF878DE2E876D9041D66BC -:100120001A44BACB20E37DA5BD4F9D637E3CC53309 -:1001300069CA60EAC74FFD18F7E742AF48626D34FD -:10014000BED2CF543DAE87D988C9C8DF7B2B321AC7 -:10015000FA85E73B93A7964E2E045D7BD947417203 -:10016000E27C44545330FE1A8C7ABBE73B93A75190 -:100170003BD5BEBE693AFB88E211FD443FF59906C6 -:100180003AB73618D9ABF4BB03AC83FC99AADDBBF4 -:100190009C4F7E44EF36B8297D8FF3CB8FE8BEDFCE -:1001A0007C4A3F68F6D0F793CDD594763637D2F7B0 -:1001B0000F9B9B28BDF9D6C802D0FFF2436BD947ED -:1001C00041F2B1BECDEC09BE5FF3EED4FEE9E8FB2F -:1001D0009385DFE6DDB4FECBEF57E593053EBB1715 -:1001E0000B3D93D3E53A47ECC0FA4277A4B897F0B9 -:1001F000D234717EED4E12F9C6C9E2BD50B7816DA1 -:1002000043FB97A65928FF6EBA81DE7570C78A7EB8 -:10021000DFCD32909E76FD8CA90D80933B9E7FCFE3 -:100220000BE4DFBD4A94BB8788EF6ABEAA7CD294F8 -:100230003E3B4296381F0BFF3BA777EABF0FBFC577 -:10024000627EA1F5D57DFA5078FC56EE5BDA17D0C8 -:10025000DFB10FD282F6458393F685A243457F0D29 -:1002600053C47ECD0C9374CE6517C10F320CE7E3F7 -:10027000041BF907DDF05FF0F5EC92F1EE57EC07A7 -:10028000E90F50FB41ED0345EFC97C9F097F87587B -:10029000C72463FF76FA87268B7577C447927EDC86 -:1002A000DD6E7640DE4C320ABF4377FBBC02DC0BCE -:1002B0002FB9DBDED81FFF7A53B6FFA7E1A0F8C144 -:1002C0000070B862FD1669B7FF07D74FFC0D7C7B45 -:1002D000B1B897194AAFED9395DD5DD0ED3B93DD55 -:1002E00007413FDD9ACD84734AB7ADFF7BE42F4DC4 -:1002F00013FB42D14FC31426DFA1E1EBCCB892DF50 -:10030000A9F5F4AD732923BE9729E38D43F1ABD64C -:1003100015C4F75E9F3C38004FC6B8BEC2FB195AE1 -:1003200067A773AAA2DFF383BF5A02F9357FB253DE -:10033000F8990C46F91EAC90277DDF3523C55D0585 -:10034000C91906BDA5E7B0F0C7F9F93909FE2CD8DF -:10035000A083E3AE2D53C4BA7BE7171A602738FF9A -:1003600017BB1772EBFC909E93D04BCE6F13EF9D93 -:10037000F31E6769B83782F81F277EB745F8418CAE -:100380000F7F7912FAD092878DA4BF9CC7B199B71D -:100390005BFEA0F89D3B757FB04EB66BD976F166DB -:1003A000FA7D334E9FD07F3EB235A4432F9EFEF0A0 -:1003B0008327F0FEFA92E734989BD951D8DD79FE75 -:1003C000E3BD46F13BAB32EE6486BCDF5FB35BDC82 -:1003D000EFAF43BC09F497033BB6E2F727EBF79A7C -:1003E000998D7F9F8177D2F8384BDB22F94192F7C4 -:1003F000BB451F377A2DF36E803DB97ABBFE7BCDAE -:100400002E7DBE2EE4DEA23645FE9EC148964BF7F9 -:1004100013B7087BB1E2DB57EABB5E82AF7BA5BABC -:10042000AFFB05BDEF6D3CFC65EA8776919F2DF330 -:100430005D3C7FEE4B017F05B706C9F3CF25B18246 -:1004400036BEBE86C33607EC000D2F083BC1F9B699 -:100450006882F3F2F04EF22BB0178D0EE861F71CB4 -:1004600032925DA1BEDDF633FC2E6DC3731ABD570B -:100470005B7F28CC27E0736109CA971EB2399C289C -:100480007F318CC1FE7C9EE30DF762CFA77412FE14 -:100490008157D825F8DF2CFC7E85C2BFF161E14F82 -:1004A0005EF284C4CFB65526C2AB4F63096957E2EA -:1004B00049E1F95786A7FAF08476D31FFEFD7189CA -:1004C0007786789BA3DB2AE9773114BE2D873F4AD4 -:1004D00085DEABF06CE478FEA16AEF94EFE17D0D70 -:1004E0009EAB8167FB3F8EE73F423E1692DEFBF1FB -:1004F0004FA1F7465AC88FAEEC1ACA6E31B8F6DD76 -:1005000063717CE0E189CF929E5B1E7BA67E052312 -:100510003BDAB5536047BBEE0DFCAC2FFBDDF54F6E -:10052000E5823E5ACC9DF4BB31DE18F1AE7C77DA21 -:10053000ECEDCFF3F18A63BF4ADD8F7DF37218B91A -:100540004FE6CA7D893F6BF0BB80ED36B2B7D5B7B9 -:100550008709FBDA01BDFFAC3B49FC4E5F89A5A7CB -:100560007C05F472DE1FC651E7C1DA76F9FB2FF283 -:10057000FC56ABEC0CFB42DE8772BC41F5EAA68868 -:1005800078DB8C84494EF0A19605CC139EF175FC66 -:100590009E11BF57BF9737A01E3800DF57FA1FF3D1 -:1005A000EAED1C8AFF2C95BF2FD9B73F64BE7AAD08 -:1005B00037CA6A24BAA3771BEA1E15BFAFF809E849 -:1005C0002E2A404F0D323EEDD8F77F63C2EF3475CF -:1005D000EF12F7233887DC8A7BFA67DB443C5C4DFB -:1005E00041D718BF13BFD321F8D0B27D9ACF99D687 -:1005F0000F1D31DF06F1AE7D083DEDFBFA770FEF01 -:100600000DF091517FE7F0DC51C2A4DCF2F61B3F04 -:10061000D927BF427EC7E37F5A3C776F0E5FCFD7A3 -:10062000F81BAF4DD4BFE3729D53FF3B4DDFC9D6DE -:10063000FF4E53AF5DC247EA834A4F3D3445C8F190 -:10064000D054C1F706977E1C752EFEEE38FD78B3A8 -:10065000DDFAF1BE2D5EFE5571ADDF04BFE372DC45 -:100660001372DCDFC871FF5938A974A0F1FE7F4D09 -:10067000FF0F822563C60080000000001F8B08006A -:1006800000000000000BB55B0B7C94D595BFDF7CB0 -:10069000F3CC7308210904C2242421608803245464 -:1006A0002B94C9D300D6065C2D68840152C83B80C8 -:1006B000B5D2D6FE3208222F5BA8D1A2224E82E10B -:1006C000A1613B118289863A286411AD1B698BFDBB -:1006D000FD56DCF828F23213A374E5575DF6FCCF23 -:1006E000FD3E321942B5DDDDE4A737E7BEBE73CF6C -:1006F000FB9C7BA929CE317C394588DC9873E69E2A -:1007000008215CAB7A8A12B385E87B43154D0E2134 -:1007100084DB7BBC3E5688DA8EE1625332C1257D94 -:100720006F1A00B78DB36FA2F18DED7F781BE3BD1B -:1007300007558785C65F6BFF280AFB5CFC325C8827 -:10074000E158F7519420B8FAB2C2F0261A77103C5B -:10075000AB5515FE4CDACFE83363FC62AA0E7BCDB5 -:1007600082DA929656730FB5557B5B79FC0D9F69C3 -:10077000F0F8DEC641E376CCA7B6CAE88DB2537B6B -:10078000BE5DDFCFCFF3AB53159717FD7BFF10B7DF -:100790000CF35ADE895B4AED15FCCCBCB6FDF4D0F7 -:1007A0000B996E5A57D341FB440CEC53D361D26082 -:1007B0008977756A6B510CD14BB428228D9A8B6264 -:1007C000AB584DF4AC6A6FAE16D45F95718F49107B -:1007D0005D023EB518DFA71F8388A37576FA8BE804 -:1007E00077D1F779D452DAF755DFB1DB5DD4063A29 -:1007F0005F8FC2770307697EE6003ED35D44BF1C6E -:10080000B4662146D0BA83AF4739687CA3EF7549F7 -:100810006FA39FCFFD9A0607A8653AB7AB7CEE8A17 -:100820002F55A6BFBEDFAD2E95F799D59E168973BD -:100830009DF4C9EFCD7539647FEAE232E07F226131 -:10084000418E9ACC78BB000726CE69DE44A854F9C5 -:1008500068DFCC6BE9B654DBB7CB24E6FBC0B7D47A -:10086000035DA3483E4E140F9F4C2357E7DDE33250 -:10087000F0BC22B33B7505CD3B19E188B4D37E0FA4 -:10088000158F8B045F5F438BFEE25D6637B595077E -:10089000E5F74EDABBA3206F270F4E553DCAC07E49 -:1008A000776ADF15C2C3ED00DF3CCCA7726F63042B -:1008B000F619E09FEC9FEBB2F3FC13DE77EEBA87FC -:1008C000CE773223DC09BE749945B98FE5843E8228 -:1008D000EF752636820EFAF7E6821FB42E9061601D -:1008E000BEF6B69BB479F7348B41F34CCCB78BCFC3 -:1008F0000DC6C7EEFDE097F7D0FCEA675461A1EEA4 -:100900006AD38A389CFF931D83F12BD7E85C6DF284 -:10091000C7C505C96B75C7557D8960F9EED0F5C3AC -:10092000C1FCD4F978324395782558BC8250AE6E1C -:100930006D66B92675F3D8A6702BECD4268677277A -:100940002B74FEC407ACCEB584FF738A366EA03616 -:1009500086608384CDD45AA97DC624FBA1B6583FB6 -:1009600086D8A9106C2A1E976348A17DD4D6C9E009 -:10097000EBAB335D8FBA088FCD334B66CC043EA210 -:100980006F99A06FD65C8AF08868210AD5F79EC05F -:1009900077FB0F9A04EC478DB5A3F26392D37E27C1 -:1009A000290AE1DDBFC3E4F5B0FCB9229469422C09 -:1009B000BB49EACD270EF734751CCD5F63E0F355D4 -:1009C000B7A85E1BCDEBAD271210C93F6D4DFE01E0 -:1009D000E4B5FAB86AB7D2B9F37DC9BF9A0EB8C503 -:1009E000E4B4D0FA5A1F75125CBB57F13AE4FE0228 -:1009F0007A597313CBBA3863AB4D1159D4AEE9337E -:100A000063DE99C38A788CE66D0E8B6A02DE3599B7 -:100A1000B3CF2951D4AA5BD627D27ECBB79B3EEC6D -:100A2000B1CAB557E8BFBACE6D2CB715DEC1FD55BA -:100A30007B07C335C23800D3FECDF8E36621DA5C0C -:100A400091B1676EA0BF2788095754D0697A3CF4EA -:100A5000E104F84AF2241A88D82385B86F92331E2D -:100A60007ABFD1E8980D3A043A4D76D0ABEEF081DA -:100A70000AE0EDAD0E731AE8A8B5AB5F61BA06BE29 -:100A800020BADF486D82E0F30784A46FA05DCA79C5 -:100A90009D49F15AB19E68C8FB5915EF1A1A0A7898 -:100AA000FAA3D83E09510CBD58B520C7003B073505 -:100AB0001684CAAF747D506C46251AADD4FFEF1969 -:100AC0007BD4614176E23F5D298C7F8159B87DD42A -:100AD0007F5FA4331A723FD61A9505BCC65A93BCE1 -:100AE000A0FB5863DF1A7C7FF328C5F1106D7D24CD -:100AF000EBE5C90AE0DA0827E44449586C043D36BE -:100B00008F5A6C84BC8FB5FB324A3207E0028C43AB -:100B10001F8497BF5714E136E23BCF8D54FC06DAB1 -:100B20003F6023FCA02746BB09F8054C121662CD96 -:100B300020FCC82231FCFF8E9F9DF08B18C08FF8DF -:100B40001D8DF59F67137DA84D9A2B4437DB8515C6 -:100B50006C17747A5E24792F205EA529526EAA77CD -:100B60001C29C2788DE85E8F754551F21C45380FFF -:100B7000E030D9AAB9925FB95A7B7FAEF42FBAFDA3 -:100B8000ECC8751973A9DD9E5B62465BA866C6F763 -:100B90000C61EF5729569693CF49FF608FEF5DA107 -:100BA000D8533306E45BD7AB3AD975557FAA7EBFDD -:100BB000CB2C52F0395777068D970BA9D78B56DB84 -:100BC000ECA9C17A043D237A94DB2B6E13A46FEE5B -:100BD000D571F6D4A9D4AF5E340BC89EA65FB1F42C -:100BE0007B256508FDF285E865FB60D86F9372EEA2 -:100BF0008F54BC6B09FFD4DCC17A97A4E941A35B95 -:100C0000E1F3357E6564D853AA7841F33BA9737547 -:100C10008C7638CC2BCFF5C23FDE496029FA1B62B7 -:100C2000594F7990ECD7BF68E7BCD3E83F02FB711E -:100C3000CCE44BB6D3D0B11AAB13FB2F1014E89011 -:100C40005D2B15DDDC9E0AAF6DF3F3E69E3190AFB0 -:100C500077DD1627E2B0C6754D91B0E359629DFD70 -:100C60004C06820AB1F7CAD4EBC7332438E28CCEE3 -:100C70001738628A53C06F9DAFDB735D79B939D77E -:100C80005F5FF5A7B6DBBF03FB757FB3395E8A49AB -:100C900077C6B401BEE97CAD131EC65BE7D755FE2F -:100CA00011EEA3410FF5E25CB633CFAA82E30A8DC1 -:100CB0007F56FA1D8A7F3A7D676A7C58DE21ED51A6 -:100CC000285F757AFF9036C4F7C98FEE607E080BF7 -:100CD000DBBF50BE7F135F28C22CC5507EAC458061 -:100CE0009F8906691F1397919C10DEF708F7E11E94 -:100CF0006AEF0A7FCBC472A8F1E75EF087A6BE2B2D -:100D0000BCDFCF48FEBFE34F476EC903C17A18AAC4 -:100D100077D7D3B36A87F3DF75BF479686F42B4442 -:100D20003F43F44FE7977B7514EBD9553EAA2D52FC -:100D30005F357E45D0EF90FA863FE87B35ED8AD768 -:100D40009FFC2DF44F21C4896F8F85E89DCE9FEBCA -:100D5000D91DDD4E9D16FE63763AFFA9141907785A -:100D60007E62F136034E3794C3EE9D9A28DB039AD8 -:100D70007D0B6D4F539CA3901FDB94717204FCF5A7 -:100D800029B3BE8FCDDB4CF89F5ED33D6625AD3FCA -:100D90009D2BDB53880B836057985804BB7E7AA445 -:100DA000C5033A9D5626E4C13F9C561EB85DC2F16C -:100DB0006607E005F17976824F99E47CDDAFE8F6CD -:100DC000FFF482EF14F03C451C053D1C8A28E1EF3E -:100DD000284A4C31E173FAFEB4296BC5C0F99B7205 -:100DE0000DBCCEABD96FC283E9DEF753C5DB445DE2 -:100DF0008BE05208FFE4BCDF14A750FFFB3F1B371A -:100E000019FC75AD1AFC7DF8EBE41B016FE37DBEA8 -:100E1000F7659F6971905FBAEA270B3E93FD6539CC -:100E200006E84BB9C64357CC8468F0A7DF3B2E1ABF -:100E30007E47F743FDC70F44B883F8768EFC9418BD -:100E40001F044F783429D88F1DD9BD391DFB949BC1 -:100E50003D594EEA3FDBF87412E28DF2DD8FA47348 -:100E60001CBC7B633AF299F2A6CDE92E86C3DD9CC9 -:100E70004F19E5B92FECBF79D7A6A0B8BB2A5F659B -:100E8000FC4BAD470AE16F67DFF0E9C3769A97F64E -:100E900033C50EF1BA57743F0CFFB810F131F2B7F9 -:100EA000062BDB73DACF05FE374FF8FE73D0E31362 -:100EB000191F99CA68DEE55C23D367A1F06E89A784 -:100EC00071B141B1378BE0F9631A317FF13AC59CBA -:100ED000003BB062D864D58175C3188F251B267777 -:100EE000A17FE183B27FB6C57BF024F6F98DD9D915 -:100EF000EC607B9352326900FFCBB9665EB7688BBA -:100F0000C2F1BFFE9DB427E21A83CF7959E3BFF83F -:100F1000CAA2802F3FD0F872DB83EF1C4DA07DED7D -:100F2000B1EE2BB01B6F3F7E26D54FFD0531E7326A -:100F300021E76966F75315387793C5897364672588 -:100F4000AAF1347FCA8F731F43BBE8C1C54F55C098 -:100F5000DE6EB772DEA6E3B74A711A608F5F6FFC70 -:100F6000E112D0EDECE3568EDB57358E8F1743E858 -:100F7000A9DEEE21FE3B28D1D9576FE5F6857ABB75 -:100F800070903CECAF4F60F8B7F50E6EC57C295FF2 -:100F9000ABB4FCF87AFB4DFD325C38289ECDDE60A8 -:100FA000130EB2534971AE517974CEB489354D1BCD -:100FB000B573A5D1FAC99EE47CD0217BE3CA2E8407 -:100FC000BCE63C998FBD797243128CF2F2073FD890 -:100FD0005941E373F34AC6E551BF75C7675C57785B -:100FE000BDE39185A0777993459E4F3BF7D9C7D351 -:100FF000E39FA2FD3D6F9838DFAFDBF1C1CE8DD40A -:101000002EDDB2D21C2CEFDFF6BCC91A3EDFA4578E -:10101000D7A3C33FAE579B93587F9A48AF32FF790F -:10102000BDAA7B700DD3EF81BC92D9A0FB59932749 -:1010300009FA7476C20C9673CF6185E9AFDB717DD6 -:101040007DB176DE2A836FCBF4E4013B7E496433C5 -:101050007D8F747C928EB8F752FB82BF7BEE437417 -:101060006E3F9DBB9DE8EB1F7FEDF834B37B9C93F7 -:10107000CE37CD20E3DD6BE2D63C83562FE83697A2 -:10108000444A9A2BA8CB68FE93FC98279AF0A9EEC5 -:1010900054FC6159F067B79E3322DFA3BCF1C3E073 -:1010A00038827E3E0CF2DBD7C3F79BDA5AEC9336DC -:1010B0006077BFF36783F007F9E99B7BC2843FE861 -:1010C000BB57F313EA33139F7A3B46B25D00DF8CC4 -:1010D000A8C7754C68027CCE2CF9D87B88E22659CB -:1010E000C711EAB481739EEBB890053B1B7ADEDA38 -:1010F000972FB07C54B73FF299C2E79F75CE98F511 -:10110000CDE73FB2FB4216F877CED4330DF956AF98 -:10111000B9270B7CA87D45DAF37F940E7A7FC5064C -:101120003A08E979AD62653929542F72DDA0F7B824 -:10113000AC1BD476EC627BDADF29EB377586EEA246 -:1011400078D43B567CD0057BD69F20F328DADF0588 -:10115000BA4D1FA7F941635FD25CB26B2F5E950752 -:1011600099FF9D85FE8EC73EBE6AD80191152E104F -:10117000579C873E53FFC2D5C9EB21E767BD23A625 -:10118000C03EBE99F5B75AAEF7BD1A6E5739EEA1FB -:10119000DE20FE5D3D875715AE41F58070E10A9A6D -:1011A000576776FC80E3E313AA405C573751EA9314 -:1011B0007859EA53CDBA23E684A0FD76429F186F92 -:1011C000192FCE7EF56FAC975B66BA3AA197E1B066 -:1011D00085D82F21DAAB28DA3CE27FAD864344A7DD -:1011E00096F717AB3C5ED7AE8A91589310E94DA3A2 -:1011F00073148BAD46C4D3B3856F3AEA36C2D8F3C5 -:10120000CB5B687CCEABEAD44D82F3A745259C57D7 -:10121000BA5357213E32281A5D7DD97383FD599EFA -:10122000F453D35585FD58DFC8708E5366CDAF2972 -:1012300005BEFABCAC61721EEDC37196F0F665CDC9 -:10124000857EFAFBB2E6450ECCBBEBD5F015EC176C -:10125000852FFBAEA0EF84E5CBFAE8E7E447202733 -:10126000759764BDA350FDEA09C4E7AB0E93BC209B -:101270003E3424BF6B801D273A83AF1788AF2EF80A -:101280001FB770B9A03F934678A13F75FB15614425 -:101290009DA8C3D2843A52ADA9270EF2BCB1FD4F2E -:1012A00066C8735DDB3B66C724AC9775275248B6AA -:1012B000E3759AFFAA691FFF2EEA7C35C7A517AD13 -:1012C00031BEC3F97BD5C156CED3AB859FF3F4EACB -:1012D00096C1F2D29FE0E0BA48A87E84E53B06E9D9 -:1012E000C5ACED522FEE52C50AD839A1D569672594 -:1012F000C4733C32B04EC6BB2EF5C2C3885F022910 -:101300008A53A1AD02619E75888B3CE9329E09FC2F -:10131000EE85EC656C57BCD977D0B9025ABC3B6BF3 -:10132000C336A31A84CFAC4E59970C8489F243CCB0 -:101330006FF768F041B84A22F27358AFB2605703B2 -:101340000659470D3D47BD562F3A817A52E600DED9 -:10135000731213A51D135E969F2E83FCBECB40E334 -:101360005306D62FC997EB07F2215907BB9E5DD9CB -:101370004DFC2923FEEC253EA37D9EFC7119D999D5 -:1013800016F2C780FF95FC315A5F7D06F7BF58EF14 -:1013900064F860FD4D0C1FAA7731DC5E5FCCEDCBAD -:1013A000F525DC7F02A87E17FF7BBA11F2D0051D60 -:1013B0001B35009F8A0981470D9E7F2A46190C8F95 -:1013C00052787E76FED38D1ED48B66DA35FD764458 -:1013D00022FE3A6B9375A8B33659876A1DE5BE2580 -:1013E0009FC6CB66ADDD2DF350573AE615C42CE011 -:1013F000FCB59FF257D8A395F9EE3CF0E5F8F1FC67 -:10140000D46D6C276D5C073D75F70DD15C077C834F -:10141000F271FA746EC6D475D904E746282CBF64FD -:101420002F6E2CD1F34ADA27BF53DEA314AAD56559 -:10143000D87FD548DB54D8DFCF5DEEDB80874EEF19 -:10144000A251CB53110F75991CEFA28EEBF9BD4938 -:10145000209FD2EB7DFABC0E57EEDD58372B63DCB4 -:10146000BA29B03BA464B0732EB368015E2E43B8B2 -:10147000B296ED96C3083B70B726C7790E1917FBD5 -:10148000CD0E630CEA3761B9B11E5AD7A5F1F9B890 -:10149000C6E7131A9FDF429D8CDAB7A91F6D37F597 -:1014A000A39D01FA4A7965BA3D915752C6F22BFACB -:1014B0009200EB75C1D9D02F696F9220D75B34F9B8 -:1014C0004DD0EC4D576E49955CE7E37DAAB47ADBCD -:1014D00005ED1E443FAFBE6E60BDE076DE8DC2639B -:1014E000859D7F49E69D6234C52304CF7B299EED0F -:1014F000906ABD23F363D2F37953651E200E58E43E -:10150000BC04470EF464AD566FEDF51A3C26D4A723 -:1015100063BAD363E07F35FDD2E143FFADB2BDAE28 -:10152000994230B5AF28F27C35F3BAD38761BD62FA -:1015300033707DBB498E9FD4F4AF2645DB4F3B8F84 -:10154000B0FA92C08FC0E197929610BC29C2BF4CEE -:10155000DA7D7F3ADB6BE14F9F07BBA8F8DE174EC1 -:101560008A2B0BA62E318E043D7C3B015717E42CB1 -:1015700031DE8CF1D6F7EDC1E3237C498A1D70B6CC -:101580001C1FD1BA7398330836BDF83EC6CD869C71 -:10159000250504CFB1788FD7436E7E2BE5CBB6BF40 -:1015A000ED0CE856D521E3F6BCFD6D175F845F6E48 -:1015B0008B74C2BCEFCB4F667AAFEDD8B305F2D6D1 -:1015C000DB2AEF0336B5FC69E7CF799E05D724B453 -:1015D000AF2F5BD077561EFDE362E03527DCF705C1 -:1015E000E0878ECE643CE70C977AFDC8D1BC25D04D -:1015F000D3DEB6FD3F81FECD89A68016F8BC60E340 -:101600003A44E5810905D0D3DEC8EE85D8BFF67926 -:101610008B13725A79203E0FF58143F9B21E5E3169 -:10162000716B12FCACE1E57DBB7F8EFBD5E76D7C79 -:101630002F541723E3BC4AB571DA4AE6DFAEDD4F1B -:1016400003EF7D36BE9FAD40AD8AE08ADD695CC7A1 -:101650007FE5EB8F16820F85EA8EDDE8FFE2399B8E -:10166000017438697645CF801E9E3471BE59A1C180 -:1016700015A7864B7CC27B8A987FB15B93E0672B72 -:1016800087FFF476E03D47DDBA13F98ED863E1BBFE -:101690008973FB886EB4EE5CB3690AB8DCBB2FD2E9 -:1016A0000879B9A06C5DF814F66F96F32ED8B632AF -:1016B0003D3DCDE305BE47F304ECD60565DBA0FE5A -:1016C00073CD7BB2908F9E7F7E0EE7A5BAFCEAFABF -:1016D00052F99C65905F644B40F6A852FB5BD83D85 -:1016E0002282FC6D85069E3FF464EF536260FDF933 -:1016F0001693DF4C34AAB08875D698017DA84CBCEF -:10170000B518E7AB3434A6236EA998DAB3107A7112 -:10171000CE26AC0934EF4DCD6F551E5C3317F1EF7B -:10172000F5F0B9A2D9A34B09D27F5D6AB77983EFEF -:101730002543DBF7EA85FDADB401F8DE15168EE131 -:10174000F5FDDE34FBAA91A7D5C648FBF13ECD6F6F -:10175000213BF6B5E6EF16AD1E3CBF3F3F86BF5FAF -:101760006BEE4987FFD3F70FE46B7EC3D8930E7BF4 -:1017700015BA6E0EC211D8911714B6239507950F9E -:1017800054A253A5D5E355411761D6CF69BCA2C871 -:101790007509D334BAD3DA0D05C9FCDDCA169BCB63 -:1017A00046EBAAC27AA210175547F64421DEE97D1E -:1017B00059154D1ABB62E334FEA4682C0BAA3756A8 -:1017C000F84C2E5BD6107C46FC44F396E36FFAFE91 -:1017D0003305297C9EF2F670FE9EB0F74C839C96F2 -:1017E000EF18BC0EE7B207E95F6FFBAEB8E0BC3C98 -:1017F00045C33BA07CC07A12F8FAC324F0BDD220C6 -:10180000D6E1FEF23CADC1BD26C1C22A61BEF7AC35 -:10181000FC6B4418E4E5FCA56AD6DB5EA587EDDA2F -:10182000DB0573D92EF59A7AD8AEBD7EF42EB60FAD -:10183000BDC37A16C24EBD5DB05C8E8FEC59E8A078 -:10184000F1FD3A3C46B0DF7FEF680DDB8F39AA7CB3 -:1018500057217699ECB21EB4E1543DE71726477044 -:10186000FE7DBA40ABF70CF087F32E5D6F7A85638F -:10187000FF41E8617904D775288E6A7911F1DE821B -:101880003827DE6B94639D940373F07D636CCCE525 -:1018900065E0CF1DA3DD450539B8DFECE13C82A44E -:1018A0009AFD4DEDEF2C9C4F064C7DBB61A7D247B6 -:1018B000BB6717101ED5E6EEF5D984D245534F17F6 -:1018C0004AE4B355698FC41E2957BD99BBE43D8DC9 -:1018D000765F79B7467F41494C23E44291FC7DBD58 -:1018E000FDC05BB02BBDDDE3D81E87EACDB9F6C7DE -:1018F000A2601FFE4C7EDC1394EFFF79F11EBE67E1 -:101900009D8FF720D42E5937581EFABFBA83F33E65 -:10191000B125A81F72D830180E9523C8A37F90DD7B -:10192000F130DDB76B7A5595D75D0B3A5C85E711E1 -:10193000AC06C1AF85C021F345898C13B6C3FF1334 -:101940003DAAC7F84F719EBEDF2460C7D792FF62E1 -:10195000B82DDC8B7CC5B09FFC53ACF44FF00B551D -:1019600051DD5C9FEA6DB3F07DEF431D9F24E1FCE8 -:1019700024875C87A9EA78290EF9FB3E2D5F203F7A -:1019800018C7EF63DA3AE29077E8FDD5065F3AF0E0 -:10199000A28888E375BDBF46F5A703FF2AA53B0BC8 -:1019A000E3FBF2EDDA7C8255C082CF51AD487D1762 -:1019B0001D2ADBF350BE3DA9C92BD9852C7EDFF152 -:1019C000B2AC0FE876A042B327AFA13F53EABD5DAA -:1019D000BF57A2A515D0F721EC4342811E17AFE0F7 -:1019E000FACDE3050E096BEB795F595FE2F1DA5747 -:1019F0002E64A564629D362FD80E8D1BB02BD0FFB0 -:101A000004D6FF874C7174AECA9D8A732DEC54E9DD -:101A10009A229A2E961B571671DD4C78386F0BC59B -:101A20002B548E2617483A551A8615C606ED779E12 -:101A30006C7AC214B6337ED89D1FC53E5A843AC50F -:101A40000F4BE5BB81ABFE2658CF719E1DD28E4356 -:101A50006DAE18AE95E3E52B1AD7C70F8147289EC8 -:101A600015EEC6A238C7B5FD3ABEE76D3A7E79A637 -:101A700011C17498BFA66804B5CBADFF2C1DE479E5 -:101A8000CF7758FCF0AB15A52BD7470F2137D7F8E8 -:101A9000831D41FE2B05FCF5F2FDC6F5F00F6DAB85 -:101AA00015FF29D48B04E95533EB17E94B905FB848 -:101AB000B920A4EE50BE782CE26AE15E3C167E8628 -:101AC000F46AA17388FC920CE42803BF19F1701B1F -:101AD0008ACF5F0AE4BBA49B0BA49E6F99E90AC05E -:101AE0006ECE500D1C8787EEF765818C27BAE322F6 -:101AF000EFD7DF7380D9335449B74443FFDBD0B706 -:101B0000C4B84807EE830AF3C3E5BCC3363BEA37E3 -:101B100081C397B9BE1B783862BEBC378810236971 -:101B2000BC2B615253B01FF975A13C6F78B68C5B2A -:101B3000EA324C7FBF3E941979B53EC47143663892 -:101B4000DF97F4B67FCE7E2BD09963C7BD466F3743 -:101B50006587A44F755FFF571CFC6B6FE75FF81D2F -:101B60005AEF579FF0FBB48DDAFBC0D7DAB5F75DBB -:101B7000DD8E48F4078A3F2AC2BC4D5A3B5027905D -:101B8000F562BDD5F35FBD1E1094078F2E1C3A0F72 -:101B90008E714704D7091CF143D55582EB04A9691E -:101BA000B24E801675825493AC1300469D002DEA08 -:101BB00004E8479D0030EA04805127008C3A015A1E -:101BC000D409D0FFC57CF95E2640422CEB97116CFE -:101BD000DFEF6B56BD88CFEF3B2CEFA1EE6B54F8D7 -:101BE0009DD645FA3EFCDC35EF750E6AEF757CDB61 -:101BF000F85EAFAE4D75825575A6BE63A8EBD4B541 -:101C00002ACE35B02FF5F3F9FB1B3B73DE2D457F54 -:101C1000B3C96970804F97E250AFAAEC6CE6FA53F3 -:101C200041FC6133F3B74511A897DE6591796E8D5C -:101C30004ABD53F83E94E3E01A4B37E71F557B1536 -:101C40007B59F07DEE4D9FB11D586B8B6A029E351E -:101C50003E9BBD6C88F71F7C2FEC1057EF9B97C9FC -:101C600029A226A288EF9B97E19E995AA17E65E45E -:101C7000FB634A4C87431EF1AE2A0366DD2EF53E18 -:101C8000E43D556567EBFA4471ED3D342A03E07F8E -:101C9000E8FDB3BB3032F64C380C85988CB8A9F807 -:101CA000F1B2FD6DF4BDFEAD168E3B56E6BB97431B -:101CB0008E8E995C5C273976D8C6F9D1C7DBC60F02 -:101CC000AA937CEE725717F2FDFC68AE5BAC32292A -:101CD000EC97F38BC7C5F3BB81E326F63F1DAE92AD -:101CE0005ACC5B35C9C1F5A9428BB89FF7D1DE69E3 -:101CF00051CBFA54B856F11A085E2C9C66E8CF22F4 -:101D0000221BCB8B296203DE532D12F27D832E37EB -:101D1000ABB6291C1770A1200EF79292BE8B3AFF2A -:101D2000ED32DE2F2CB5C8F835D120EFB31337C90B -:101D3000F72D3F126E33FCED72F28B68C94FFEAE89 -:101D400087FADDE1A393647CEE88C7FE8B4F98F899 -:101D5000BD6F61FCF7D3DDECAF0BF81D83E2BF472D -:101D6000BD72C3F5F527F41DC33193B42F4447CE9C -:101D70008BBA20975C9F71737BA2BE9CDB1933A545 -:101D80009DBEFA2E91786407FEE17DEF235F4C8CB7 -:101D90008F74C2DEE97A7FCDFBC430D9EAEF13C776 -:101DA000502B82DE276E713978FF44C3C9A90ED04B -:101DB000E3AF114ED0437FA7B86566C92EF0C915B1 -:101DC000253CF82EEE51B6125D8B701005756E9F96 -:101DD0004B45DDFAB062E777D1D7D8C96D0FE31D67 -:101DE0004F5DAA62571CA8876F2D8C23BC8B529223 -:101DF00019EFBA76592F650AC5A19EAEE983CBDDEE -:101E0000563862A07F8EA617BD345FCAC92D5EC842 -:101E1000DBB7A8A33E87F91E6173366BF91AF83E4B -:101E2000E786315C4FD5E5A6BF25BE0972F346A112 -:101E3000F433A5A5EF98100774E5BA8FE2FC0BCB3D -:101E40003E7B388ECF37741D8BEC28DF4B86D6B1A6 -:101E500074BBBC5BAB83C37E1AB53AAB51ABB31A50 -:101E6000B53AAB51ABB31AB53AAB51ABB31AB53ABD -:101E7000AB51ABB31AB53AAB91EB772BB87DBB7EC8 -:101E800035B7DDF51E1E0FB2FFEF5DC7FE87D641E9 -:101E90003FC2BCD03AA8B03AA2D98F927ECBFA7397 -:101EA00048DDB378F8920D44BFFC06B3135D7A1D8C -:101EB00014EF97EF8B607B70B170C8FAA74EB7082C -:101EC000AE97F60BDB14D03F2F639CD140E37FD558 -:101ED000F8A0D71FA11F381FF4032DF4C39836A014 -:101EE0001FCF984985B3A5BFF7B0BFB7315FD7AF54 -:101EF00021FB41F052611F643F2E86D80F4A3CEE11 -:101F0000061ECB3AE5BB26FDFD661E355F4E19C2A7 -:101F10009EF8A43D1913E6DB87EF8CA90DE3F7C10A -:101F2000C7B4F758C736CA777165A284BF3B845DD2 -:101F300089023F960EEF7BFF699ABF747304C72D29 -:101F4000EB472E9BF6BFB12B9F150AA6DB6FEAFD70 -:101F5000951F132E056152FE0ACC2203F735C210DD -:101F6000C67A50A86E51703FBAEA5E31197C2EB025 -:101F700094EC009EF1DAFDB688D5EAADC6EE8A3D56 -:101F8000049F8C4B74E25E6B74C22181F74F8575A0 -:101F9000C599B08BFE31EE09453978BFBC55C1FA01 -:101FA000F04C79FE3B8AC39B205781C3E373C0EF9B -:101FB0007916471BEA00CEA284A5C8F3E7453B7219 -:101FC000500770768D9270BCA34D7122944D585A73 -:101FD000C0EFCFAC5B3FB6E2DD9A22A2E95C96612E -:101FE000EE1C7CA7A6F85399378B3EF6633717C9CA -:101FF000FC6BC46BC28F7BABBE59917C7F26321DBC -:102000003918A7B8F2BB45241F7FFC9EEB16AC4FD6 -:10201000D4F08CC72DA20AAE76DBD09ED0EEF3BAF8 -:102020000CEE52B445511E23F71BBCD968DF34F8BF -:102030007E8C7E92E722EC57F4D8E4891904275A63 -:102040007C6C273B5CAE5BB1FFAB335DC5180FAD5D -:102050009F83B7C8F3099FDB302FF41D96CECFA521 -:102060004552EECB8AA4FD98BE56DEC786F2BDACC3 -:10207000C8A0D9B7BF8F37E15B8AEFE9F88BAD8B8A -:10208000B3810FE17B2FF0247C17625C44C470BDE8 -:10209000E3FA72E6E1EF951549F9227B56F5B1B402 -:1020A00067DCA61BBDC3103F8EFA857718F01DD5DF -:1020B000D867C3BFC378D6D367837F7FF6C13E1B83 -:1020C000FA9F75C977D2A1FB3716C9F713E9D3FB7D -:1020D00078FD58FA5637C7E97DC31047A5977FBCEE -:1020E0005EDEBB64B07F19ABF997B1BF4869EF21E1 -:1020F000791BFB6434DF6F8B82581EAFB44A3DAD51 -:10210000FC45D9A1366AC76F277C83E2AF095EC25E -:102110007B505C64EC97EF2D09069DF69A1886CCEF -:1021200022BEAA11F2BDE528CD6E206E2B25BB5034 -:10213000537EF432BF03C07AEC8F3B5BC85FBB4970 -:10214000C2E4AE918F2E9FBFA68BF3C3ED57FBB5B4 -:102150007CB3753DF2678ADF06F557961DE982BFAD -:10216000A9DA3BB8BF66C5679CC752FC36A8FFDE3C -:102170001F7FC0EF6CEADA07F7137F9F029F75FE9F -:102180001E33F92620DF3B5613E694FF7EC0B712BC -:10219000FADE541DC1EF6777FD3A8FE546E737ADAC -:1021A0006FFA76F2B196E77BF24406F4E19BDA5ED1 -:1021B000D8A7B441F6C9C375BED9916C77EAB4FC0F -:1021C000AAB6CCCE7E3EB1D6CAF6AB500D7302AEE7 -:1021D000354A3B238A55CD4EF958FF4FDE3E8CEBF6 -:1021E000797C00C03193F8DD71DC5A09F78DB0B00D -:1021F0007D28349454EFA1F6A86105DB8104BCB8B6 -:1022000024BE3F03FBA0427F655DB5CEEC53E4FDE9 -:10221000BE2307F9AE7EDFD4B0D1DB7A10F9B2E28B -:102220007D7219EA8A7746F0FD4100F5463A4FC3C0 -:102230003069471B16A4B31F088892D2958843E6DD -:102240008771FDB16198E351DC2736544CE438FACC -:10225000D07F4BBFDB37D7EA441CD530D9B106EF6E -:10226000551A7EE1E0F15714B99FE751499F86B9AD -:10227000F2FC0D15319CF7E87C6868748DC4FDD4C0 -:10228000CC31EEFF00DF4769F7730DC9D44FED1372 -:102290004AC9821F619F4912DF19331DAC77C716E7 -:1022A0004C7C74B783DD891FF74475B32307E5C5FC -:1022B000FF033C759D8B10370000000000000000FC -:0822C00005020D000000000002 -:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex new file mode 100644 index 0000000000000000000000000000000000000000..33b584c7c1abb860362b9be0f4d60f6968c6ec0e --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1-6.0.34.0.fw.ihex @@ -0,0 +1,9476 @@ +:1000000000003BB0000000680000070C00003C202E +:1000100000001AF8000043300000007C00005E3051 +:10002000000079E800005EB0000000B40000D8A035 +:100030000000800C0000D9580000008800015968B9 +:10004000000039C4000159F800000090000193C07D +:100050000000ABA80001945800000FFC000240080B +:100060000000000400025008020400480000000FD5 +:100070000204005400000045020400580000000083 +:100080000204005C0000000602040070000000048E +:1000900002040078000000000204007C1217000037 +:1000A00002040080221700000204008432170000BE +:1000B00006040088000000050204009C12150000E0 +:1000C000020400A022150000020400A43215000062 +:1000D000060400A800000004020400B8021000009A +:1000E000020400BC00100000020400C01010000058 +:1000F000020400C420100000020400C830100000F8 +:10010000060400CC00000004020400DC0010000023 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000060400EC00000004A1 +:100130000104012400000000010401280000000067 +:100140000104012C00000000010401300000000047 +:1001500002040004000000FF02040008000000FF89 +:100160000204000C000000FF02040010000000FF69 +:1001700002040014000000FF02040018000000FF49 +:100180000204001C000000FF02040020000000FF29 +:10019000020400240000003E0204002800000000C9 +:1001A0000204002C0000003F020400300000003F69 +:1001B000020400340000003F020400380000000088 +:1001C0000204003C0000003F020400400000003F29 +:1001D000020400440000003F020420080000021155 +:1001E0000204200C0000020002042010000002049F +:1001F00002042014000002190204201C0000FFFF6A +:10020000020420200000FFFF020420240000FFFF62 +:10021000020420280000FFFF0604203800000080B0 +:100220000204223807FFFFFF0204223C0000003FC7 +:100230000204224007FFFFFF020422440000000FD7 +:1002400001042248000000000104224C00000000CC +:1002500001042250000000000104225400000000AC +:1002600001042258000000000104225C000000008C +:10027000010422600000000001042264000000006C +:1002800001042268000000000104226C000000004C +:10029000010422700000000001042274000000002C +:1002A00001042278000000000104227C000000000C +:1002B000020424BC000000010C042000000003E83C +:1002C0000A042000000000010B0420000000000AC6 +:1002D0000605400000000D0002050044000000205B +:1002E00002050048000000320205009002150020BF +:1002F000020500940215002002050098000000305D +:100300000205009C08100000020500A00000003358 +:10031000020500A400000030020500A80000003122 +:10032000020500AC00000002020500B0000000055C +:10033000020500B400000006020500B8000000023B +:10034000020500BC00000002020500C00000000021 +:10035000020500C400000005020500C800000002FC +:10036000020500CC00000002020500D000000002DF +:10037000020500D400000001020501140000000184 +:100380000205011C0000000102050120000000021E +:1003900002050204000000010205020C00000040FA +:1003A00002050210000000400205021C00000020AF +:1003B00002050220000000130205022400000020B4 +:1003C000060502400000000A04050280002000002B +:1003D000020500500000000702050054000000075D +:1003E00002050058000000000205005C0000000843 +:1003F0000605006000000004020500D800000006A9 +:10040000020500E00000000D020500E40000002DE0 +:10041000020500E800000000020500EC00000020DA +:10042000020500F000000000020500F400000020BA +:10043000020500F800000000020500FC000000209A +:100440000205000400000001020500080000000190 +:100450000205000C00000001020500100000000170 +:100460000205001400000001020500180000000150 +:100470000205001C00000001020500200000000130 +:100480000205002400000001020500280000000110 +:100490000205002C000000010205003000000001F0 +:1004A00002050034000000010205003800000001D0 +:1004B0000205003C000000010205004000000001B0 +:1004C0000406100002000020020600DC000000010B +:1004D000010600D80000000004060200000302200C +:1004E000020600DC0000000002060068000000B800 +:1004F0000206007800000114010600B800000000A8 +:10050000010600C8000000000206006C000000B8F0 +:100510000206007C00000114010600BC000000007F +:10052000010600CC0000000007180400007B00005A +:100530000818076000140223071C00002A1E000090 +:10054000071C800031E60A88071D00001DDD170228 +:10055000081D4470577202250118000000000000B9 +:10056000011800040000000001180008000000004D +:100570000118000C0000000001180010000000002D +:100580000118001400000000021800200000000103 +:1005900002180024000000020218002800000003D6 +:1005A0000218002C000000000218003000000004B7 +:1005B000021800340000000102180038000000009A +:1005C0000218003C00000001021800400000000476 +:1005D000021800440000000002180048000000015A +:1005E0000218004C00000003021800500000000038 +:1005F0000218005400000001021800580000000416 +:100600000218005C000000000218006000000001F9 +:1006100002180064000000030218006800000000D7 +:100620000218006C000000010218007000000004B5 +:100630000218007400000000021800780000000496 +:100640000218007C00000003061800800000000271 +:10065000021800A400003FFF021800A8000003FFDA +:1006600002180224000000000218023400000000FA +:100670000218024C00000000021802E4000000FF13 +:100680000618100000000400021B8BC000000001CF +:10069000021B800000000034021B80400000001894 +:1006A000021B80800000000C021B80C000000020A4 +:1006B0000C1B83000007A1200A1B830000000138E7 +:1006C0000B1B8300000013880A1B834000000000FE +:1006D0000C1B8340000001F40B1B8340000000054D +:1006E000021B83800007A120021B83C0000001F4CD +:1006F000061A100000000273041A19CC0001022728 +:10070000061A2008000000C8061A20000000000297 +:10071000041A499800040228061A2E280000000234 +:10072000061A2E2000000002061A0800000000022F +:10073000061A080800000004061A08180000000243 +:10074000041A08B00002022C061A2FD0000000067E +:10075000041A2FE80002022E041A2FC000040230EF +:10076000041A300000010234061A300400000003AD +:10077000041A301000010235061A3014000000037C +:10078000041A302000010236061A3024000000034B +:10079000041A303000010237061A3034000000031A +:1007A000041A304000010238061A304400000003E9 +:1007B000041A305000010239061A305400000003B8 +:1007C000041A30600001023A061A30640000000387 +:1007D000041A30700001023B061A30740000000356 +:1007E000041A30800001023C061A30840000000325 +:1007F000041A30900001023D061A309400000003F4 +:10080000041A30A00001023E061A30A400000003C2 +:10081000041A30B00001023F061A30B40000000391 +:10082000041A30C000010240061A30C40000000360 +:10083000041A30D000010241061A30D4000000032F +:10084000041A30E000010242061A30E400000003FE +:10085000041A30F000010243061A30F400000003CD +:10086000041A310000010244061A3104000000039A +:10087000041A311000010245061A31140000000369 +:10088000041A312000010246061A31240000000338 +:10089000041A313000010247061A31340000000307 +:1008A000041A314000010248061A314400000003D6 +:1008B000041A315000010249061A315400000003A5 +:1008C000041A31600001024A061A31640000000374 +:1008D000041A31700001024B061A31740000000343 +:1008E000041A31800001024C061A31840000000312 +:1008F000041A31900001024D061A319400000003E1 +:10090000041A31A00001024E061A31A400000003AF +:10091000041A31B00001024F061A31B4000000037E +:10092000041A31C000010250061A31C4000000034D +:10093000041A31D000010251061A31D4000000031C +:10094000041A31E000010252061A31E400000003EB +:10095000041A31F000010253061A31F400000003BA +:10096000041A320000010254061A32040000000387 +:10097000041A321000010255061A32140000000356 +:10098000041A322000010256061A32240000000325 +:10099000041A323000010257061A323400000003F4 +:1009A000041A324000010258061A324400000003C3 +:1009B000041A325000010259061A32540000000392 +:1009C000041A32600001025A061A32640000000361 +:1009D000041A32700001025B061A32740000000330 +:1009E000041A32800001025C061A328400000003FF +:1009F000041A32900001025D061A329400000003CE +:100A0000041A32A00001025E061A32A4000000039C +:100A1000041A32B00001025F061A32B4000000036B +:100A2000041A32C000010260061A32C4000000033A +:100A3000041A32D000010261061A32D40000000309 +:100A4000041A32E000010262061A32E400000003D8 +:100A5000041A32F000010263061A32F400000003A7 +:100A6000041A330000010264061A33040000000374 +:100A7000041A331000010265061A33140000000343 +:100A8000041A332000010266061A33240000000312 +:100A9000041A333000010267061A333400000003E1 +:100AA000041A334000010268061A334400000003B0 +:100AB000041A335000010269061A3354000000037F +:100AC000041A33600001026A061A3364000000034E +:100AD000041A33700001026B061A3374000000031D +:100AE000041A33800001026C061A338400000003EC +:100AF000041A33900001026D061A339400000003BB +:100B0000041A33A00001026E061A33A40000000389 +:100B1000041A33B00001026F061A33B40000000358 +:100B2000041A33C000010270061A33C40000000327 +:100B3000041A33D000010271061A33D400000003F6 +:100B4000041A33E000010272061A33E400000003C5 +:100B5000041A33F000010273061A33F40000000394 +:100B6000041A340000010274061A34040000000361 +:100B7000041A341000010275061A34140000000330 +:100B8000041A342000010276061A342400000003FF +:100B9000041A343000010277061A343400000003CE +:100BA000041A344000010278061A3444000000039D +:100BB000041A345000010279061A3454000000036C +:100BC000041A34600001027A061A3464000000033B +:100BD000041A34700001027B061A3474000000030A +:100BE000041A34800001027C061A348400000003D9 +:100BF000041A34900001027D061A349400000003A8 +:100C0000041A34A00001027E061A34A40000000376 +:100C1000041A34B00001027F061A34B40000000345 +:100C2000041A34C000010280061A34C40000000314 +:100C3000041A34D000010281061A34D400000003E3 +:100C4000041A34E000010282061A34E400000003B2 +:100C5000041A34F000010283061A34F40000000381 +:100C6000041A350000010284061A3504000000034E +:100C7000041A351000010285061A3514000000031D +:100C8000041A352000010286061A352400000003EC +:100C9000041A353000010287061A353400000003BB +:100CA000041A354000010288061A3544000000038A +:100CB000041A355000010289061A35540000000359 +:100CC000041A35600001028A061A35640000000328 +:100CD000041A35700001028B061A357400000003F7 +:100CE000041A35800001028C061A358400000003C6 +:100CF000041A35900001028D061A35940000000395 +:100D0000041A35A00001028E061A35A40000000363 +:100D1000041A35B00001028F061A35B40000000332 +:100D2000041A35C000010290061A35C40000000301 +:100D3000041A35D000010291061A35D400000003D0 +:100D4000041A35E000010292061A35E4000000039F +:100D5000041A35F000010293061A35F4000000036E +:100D6000041A360000010294061A3604000000033B +:100D7000041A361000010295061A3614000000030A +:100D8000041A362000010296061A362400000003D9 +:100D9000041A363000010297061A363400000003A8 +:100DA000041A364000010298061A36440000000377 +:100DB000041A365000010299061A36540000000346 +:100DC000041A36600001029A061A36640000000315 +:100DD000041A36700001029B061A367400000003E4 +:100DE000041A36800001029C061A368400000003B3 +:100DF000041A36900001029D061A36940000000382 +:100E0000041A36A00001029E061A36A40000000350 +:100E1000041A36B00001029F061A36B4000000031F +:100E2000041A36C0000102A0061A36C400000003EE +:100E3000041A36D0000102A1061A36D400000003BD +:100E4000041A36E0000102A2061A36E4000000038C +:100E5000041A36F0000102A3061A36F4000000035B +:100E6000041A3700000102A4061A37040000000328 +:100E7000041A3710000102A5061A371400000003F7 +:100E8000041A3720000102A6061A372400000003C6 +:100E9000041A3730000102A7061A37340000000395 +:100EA000041A3740000102A8061A37440000000364 +:100EB000041A3750000102A9061A37540000000333 +:100EC000041A3760000102AA061A37640000000302 +:100ED000041A3770000102AB061A377400000003D1 +:100EE000041A3780000102AC061A378400000003A0 +:100EF000041A3790000102AD061A3794000000036F +:100F0000041A37A0000102AE061A37A4000000033D +:100F1000041A37B0000102AF061A37B4000000030C +:100F2000041A37C0000102B0061A37C400000003DB +:100F3000041A37D0000102B1061A37D400000003AA +:100F4000041A37E0000102B2061A37E40000000379 +:100F5000041A37F0000102B3061A37F40000000348 +:100F6000041A3800000102B4061A38040000000315 +:100F7000041A3810000102B5061A381400000003E4 +:100F8000041A3820000102B6061A382400000003B3 +:100F9000041A3830000102B7061A38340000000382 +:100FA000041A3840000102B8061A38440000000351 +:100FB000041A3850000102B9061A38540000000320 +:100FC000041A3860000102BA061A386400000003EF +:100FD000041A3870000102BB061A387400000003BE +:100FE000041A3880000102BC061A3884000000038D +:100FF000041A3890000102BD061A3894000000035C +:10100000041A38A0000102BE061A38A4000000032A +:10101000041A38B0000102BF061A38B400000003F9 +:10102000041A38C0000102C0061A38C400000003C8 +:10103000041A38D0000102C1061A38D40000000397 +:10104000041A38E0000102C2061A38E40000000366 +:10105000041A38F0000102C3061A38F40000000335 +:10106000041A3900000102C4061A39040000000302 +:10107000041A3910000102C5061A391400000003D1 +:10108000041A3920000102C6061A392400000003A0 +:10109000041A3930000102C7061A3934000000036F +:1010A000041A3940000102C8061A3944000000033E +:1010B000041A3950000102C9061A3954000000030D +:1010C000041A3960000102CA061A396400000003DC +:1010D000041A3970000102CB061A397400000003AB +:1010E000041A3980000102CC061A3984000000037A +:1010F000041A3990000102CD061A39940000000349 +:10110000041A39A0000102CE061A39A40000000317 +:10111000041A39B0000102CF061A39B400000003E6 +:10112000041A39C0000102D0061A39C400000003B5 +:10113000041A39D0000102D1061A39D40000000384 +:10114000041A39E0000102D2061A39E40000000353 +:10115000041A39F0000102D3061A39F40000000322 +:10116000041A3A00000102D4061A3A0400000003EF +:10117000041A3A10000102D5061A3A1400000003BE +:10118000041A3A20000102D6061A3A24000000038D +:10119000041A3A30000102D7061A3A34000000035C +:1011A000041A3A40000102D8061A3A44000000032B +:1011B000041A3A50000102D9061A3A5400000003FA +:1011C000041A3A60000102DA061A3A6400000003C9 +:1011D000041A3A70000102DB061A3A740000000398 +:1011E000041A3A80000102DC061A3A840000000367 +:1011F000041A3A90000102DD061A3A940000000336 +:10120000041A3AA0000102DE061A3AA40000000304 +:10121000041A3AB0000102DF061A3AB400000003D3 +:10122000041A3AC0000102E0061A3AC400000003A2 +:10123000041A3AD0000102E1061A3AD40000000371 +:10124000041A3AE0000102E2061A3AE40000000340 +:10125000041A3AF0000102E3061A3AF4000000030F +:10126000041A3B00000102E4061A3B0400000003DC +:10127000041A3B10000102E5061A3B1400000003AB +:10128000041A3B20000102E6061A3B24000000037A +:10129000041A3B30000102E7061A3B340000000349 +:1012A000041A3B40000102E8061A3B440000000318 +:1012B000041A3B50000102E9061A3B5400000003E7 +:1012C000041A3B60000102EA061A3B6400000003B6 +:1012D000041A3B70000102EB061A3B740000000385 +:1012E000041A3B80000102EC061A3B840000000354 +:1012F000041A3B90000102ED061A3B940000000323 +:10130000041A3BA0000102EE061A3BA400000003F1 +:10131000041A3BB0000102EF061A3BB400000003C0 +:10132000041A3BC0000102F0061A3BC4000000038F +:10133000041A3BD0000102F1061A3BD4000000035E +:10134000041A3BE0000102F2061A3BE4000000032D +:10135000041A3BF0000102F3061A3BF400000003FC +:10136000041A3C00000102F4061A3C0400000003C9 +:10137000041A3C10000102F5061A3C140000000398 +:10138000041A3C20000102F6061A3C240000000367 +:10139000041A3C30000102F7061A3C340000000336 +:1013A000041A3C40000102F8061A3C440000000305 +:1013B000041A3C50000102F9061A3C5400000003D4 +:1013C000041A3C60000102FA061A3C6400000003A3 +:1013D000041A3C70000102FB061A3C740000000372 +:1013E000041A3C80000102FC061A3C840000000341 +:1013F000041A3C90000102FD061A3C940000000310 +:10140000041A3CA0000102FE061A3CA400000003DE +:10141000041A3CB0000102FF061A3CB400000003AD +:10142000041A3CC000010300061A3CC4000000037B +:10143000041A3CD000010301061A3CD4000000034A +:10144000041A3CE000010302061A3CE40000000319 +:10145000041A3CF000010303061A3CF400000003E8 +:10146000041A3D0000010304061A3D0400000003B5 +:10147000041A3D1000010305061A3D140000000384 +:10148000041A3D2000010306061A3D240000000353 +:10149000041A3D3000010307061A3D340000000322 +:1014A000041A3D4000010308061A3D4400000003F1 +:1014B000041A3D5000010309061A3D5400000003C0 +:1014C000041A3D600001030A061A3D64000000038F +:1014D000041A3D700001030B061A3D74000000035E +:1014E000041A3D800001030C061A3D84000000032D +:1014F000041A3D900001030D061A3D9400000003FC +:10150000041A3DA00001030E061A3DA400000003CA +:10151000041A3DB00001030F061A3DB40000000399 +:10152000041A3DC000010310061A3DC40000000368 +:10153000041A3DD000010311061A3DD40000000337 +:10154000041A3DE000010312061A3DE40000000306 +:10155000041A3DF000010313061A3DF400000003D5 +:10156000041A3E0000010314061A3E0400000003A2 +:10157000041A3E1000010315061A3E140000000371 +:10158000041A3E2000010316061A3E240000000340 +:10159000041A3E3000010317061A3E34000000030F +:1015A000041A3E4000010318061A3E4400000003DE +:1015B000041A3E5000010319061A3E5400000003AD +:1015C000041A3E600001031A061A3E64000000037C +:1015D000041A3E700001031B061A3E74000000034B +:1015E000041A3E800001031C061A3E84000000031A +:1015F000041A3E900001031D061A3E9400000003E9 +:10160000041A3EA00001031E061A3EA400000003B7 +:10161000041A3EB00001031F061A3EB40000000386 +:10162000041A3EC000010320061A3EC40000000355 +:10163000041A3ED000010321061A3ED40000000324 +:10164000041A3EE000010322061A3EE400000003F3 +:10165000041A3EF000010323061A3EF400000003C2 +:10166000041A3F0000010324061A3F04000000038F +:10167000041A3F1000010325061A3F14000000035E +:10168000041A3F2000010326061A3F24000000032D +:10169000041A3F3000010327061A3F3400000003FC +:1016A000041A3F4000010328061A3F4400000003CB +:1016B000041A3F5000010329061A3F54000000039A +:1016C000041A3F600001032A061A3F640000000369 +:1016D000041A3F700001032B061A3F740000000338 +:1016E000041A3F800001032C061A3F840000000307 +:1016F000041A3F900001032D061A3F9400000003D6 +:10170000041A3FA00001032E061A3FA400000003A4 +:10171000041A3FB00001032F061A3FB40000000373 +:10172000041A3FC000010330061A3FC40000000342 +:10173000041A3FD000010331061A3FD40000000311 +:10174000041A3FE000010332061A3FE400000007DC +:10175000041A4CB000080333061A400000000124AC +:10176000021A492000000000061A2500000000109F +:10177000061A258000000012061A09C00000004861 +:10178000061A080000000002061A082000000012D5 +:10179000041A2FB00002033B041A4CF00002033D70 +:1017A000061A500000000004061A449000000124AC +:1017B000021A492400000000061A2540000000100B +:1017C000061A25C800000012061A0AE000000048A8 +:1017D000061A081000000002061A0868000000122D +:1017E000041A2FB80002033F041A4CF80002034108 +:1017F000061A5010000000040200A468000AFFDC72 +:101800000200A280000000010200A294071D29111D +:101810000200A298000000000200A29C009C042488 +:101820000200A2A0000000000200A2A40000020921 +:101830000200A4FCFF000000020100B4000000014F +:10184000020100B800000001020100DC00000001FC +:10185000020101000000000102010104000000017A +:101860000201007C0030000002010084000000281A +:101870000201008C000000000201013000000004A1 +:101880000201025C000000010201032800000000C8 +:101890000201055400000030020100C400000001F4 +:1018A000020100CC00000001020100F8000000016C +:1018B000020100F000000001020100800030000081 +:1018C00002010088000000280201009000000000D2 +:1018D0000201013400000004020102DC00000001EA +:1018E0000201032C0000000002010564000000302A +:1018F000020100C800000001020100D00000000148 +:10190000020100FC00000001020100F400000001DF +:10191000020C100000000028020C200800000A1130 +:10192000020C200C00000A00020C201000000A0427 +:10193000020C201C0000FFFF020C20200000FFFF13 +:10194000020C20240000FFFF020C20280000FFFFF3 +:10195000020C203800000020020C203C0000002176 +:10196000020C204000000022020C20440000002352 +:10197000020C204800000024020C204C000000252E +:10198000020C205000000026020C2054000000270A +:10199000020C205800000028020C205C00000029E6 +:1019A000020C20600000002A020C20640000002BC2 +:1019B000020C20680000002C020C206C0000002D9E +:1019C000020C20700000002E020C20740000002F7A +:1019D000020C207800000010060C207C0000004F54 +:1019E000020C21B800000001020C21BC0000000123 +:1019F000020C21C000000001020C21C40000000103 +:101A0000020C21C800000001020C21CC00000001E2 +:101A1000020C21D000000001020C21D400000001C2 +:101A2000020C21D800000001020C21DC00000001A2 +:101A3000020C21E000000001020C21E40000000182 +:101A4000020C21E800000001020C21EC0000000162 +:101A5000020C21F000000001020C21F40000000142 +:101A6000020C21F800000001060C21FC0000000F10 +:101A7000020C223807FFFFFF020C223C0000003F4F +:101A8000020C224007FFFFFF020C22440000000F5F +:101A9000010C224800000000010C224C0000000054 +:101AA000010C225000000000010C22540000000034 +:101AB000010C225800000000010C225C0000000014 +:101AC000010C226000000000010C226400000000F4 +:101AD000010C226800000000010C226C00000000D4 +:101AE000010C227000000000010C227400000000B4 +:101AF000010C227800000000010C227C0000000094 +:101B0000020C24BC000000010C0C2000000003E8C3 +:101B10000A0C2000000000010B0C20000000000A4D +:101B2000020C400800000562020C400C0000055148 +:101B3000020C401000000555020C40140000057214 +:101B4000020C401C0000FFFF020C40200000FFFFC1 +:101B5000020C40240000FFFF020C40280000FFFFA1 +:101B6000020C403800000046020C403C0000000C13 +:101B7000060C40400000005E020C41B8000000016D +:101B8000060C41BC0000001F020C423807FFFFFF9B +:101B9000020C423C0000003F020C424007FFFFFFE6 +:101BA000020C42440000000F010C424800000000FB +:101BB000010C424C00000000010C425000000000EB +:101BC000010C425400000000010C425800000000CB +:101BD000010C425C00000000010C426000000000AB +:101BE000010C426400000000010C4268000000008B +:101BF000010C426C00000000010C4270000000006B +:101C0000010C427400000000010C4278000000004A +:101C1000010C427C00000000010C4280000000002A +:101C2000020C44C0000000010C0C4000000003E85E +:101C30000A0C4000000000010B0C40000000000AEC +:101C4000060D400000000A00020D004400000032B2 +:101C5000020D008C02150020020D009002150020DC +:101C6000020D009408100000020D009800000033DF +:101C7000020D009C00000002020D00A00000000008 +:101C8000020D00A400000005020D00A800000005E0 +:101C9000060D00AC00000002020D00B400000002BE +:101CA000020D00B800000003020D00BC000000029D +:101CB000020D00C000000001020D00C8000000027B +:101CC000020D00CC00000002020D015C00000001CA +:101CD000020D016400000001020D01680000000215 +:101CE000020D020400000001020D020C00000020A1 +:101CF000020D021000000040020D0214000000401E +:101D0000020D022000000003020D02240000001852 +:101D1000060D028000000012040D030000180343AA +:101D2000060D03600000000C020D004C00000001D5 +:101D3000020D005000000002020D005400000000DF +:101D4000020D005800000008060D005C00000004B1 +:101D5000020D00C400000004020D0114000000097F +:101D6000020D011800000029020D011C0000000AEC +:101D7000020D01200000002A020D012400000000D5 +:101D8000020D012800000020020D012C00000000BF +:101D9000020D013000000020020D0134000000009F +:101DA000020D013800000020020D013C000000007F +:101DB000020D014000000020020D0144000000005F +:101DC000020D014800000020020D00040000000187 +:101DD000020D000800000001020D000C00000001CF +:101DE000020D001000000001020D001400000001AF +:101DF000020D001800000001020D001C000000018F +:101E0000020D002000000001020D0024000000016E +:101E1000020D002800000001020D002C000000014E +:101E2000020D003000000001020D0034000000012E +:101E3000020D003800000001020D003C000000010E +:101E4000060E200000000800020E004C00000032C8 +:101E5000020E009402150020020E009802150020C8 +:101E6000020E009C00000030020E00A008100000CE +:101E7000020E00A400000033020E00A80000003093 +:101E8000020E00AC00000031020E00B000000002A3 +:101E9000020E00B400000004020E00B800000000B2 +:101EA000020E00BC00000002020E00C00000000292 +:101EB000020E00C400000000020E00C80000000274 +:101EC000020E00CC00000007020E00D0000000024D +:101ED000020E00D400000002020E00D80000000133 +:101EE000020E014400000001020E014C000000013E +:101EF000020E015000000002020E02040000000168 +:101F0000020E020C00000040020E02100000004011 +:101F1000020E021C00000004020E0220000000203D +:101F2000020E02240000000E020E02280000001B18 +:101F3000060E030000000012040E0280001B035B6B +:101F4000060E02EC00000005020E00540000000C1A +:101F5000020E00580000000C020E005C00000000A1 +:101F6000020E006000000010060E00640000000475 +:101F7000020E00DC00000003020E01100000000F42 +:101F8000020E01140000002F020E011800000000D4 +:101F9000020E011C00000020020E000400000001DF +:101FA000020E000800000001020E000C00000001FB +:101FB000020E001000000001020E001400000001DB +:101FC000020E001800000001020E001C00000001BB +:101FD000020E002000000001020E0024000000019B +:101FE000020E002800000001020E002C000000017B +:101FF000020E003000000001020E0034000000015B +:10200000020E003800000001020E003C000000013A +:10201000020E004000000001020E0044000000011A +:102020000730040000B00000083007680013037692 +:1020300007340000332700000734800032520CCAF6 +:10204000073500001A8C195F083539A058CC037881 +:10205000013000000000000001300004000000001A +:1020600001300008000000000130000C00000000FA +:1020700001300010000000000130001400000000DA +:1020800002300020000000010230002400000002A5 +:1020900002300028000000030230002C0000000085 +:1020A0000230003000000004023000340000000163 +:1020B00002300038000000000230003C0000000147 +:1020C0000230004000000004023000440000000024 +:1020D00002300048000000010230004C0000000304 +:1020E00002300050000000000230005400000001E7 +:1020F00002300058000000040230005C00000000C4 +:1021000002300060000000010230006400000003A3 +:1021100002300068000000000230006C0000000186 +:102120000230007000000004023000740000000063 +:1021300002300078000000040230007C0000000340 +:102140000630008000000002023000A400003FFFC3 +:10215000023000A8000003FF02300224000000004B +:1021600002300234000000000230024C0000000087 +:10217000023002E40000FFFF0630200000000800EB +:1021800002338BC000000001023380000000001AFF +:10219000023380400000004E0233808000000010B7 +:1021A000023380C0000000200C3383000007A12010 +:1021B0000A338300000001380B33830000001388CA +:1021C0000A338340000000000C338340000001F418 +:1021D0000B33834000000005023383800007A120F9 +:1021E000023383C0000001F406322A88000000C2D6 +:1021F00006322008000000C806322000000000025D +:10220000063223E80000004004322E580004037A0E +:10221000063250A000000004063250B80000000250 +:102220000632508000000006043250980002037EFF +:10223000063250000000002006323000000004008A +:1022400006321C0000000004043218300002038033 +:10225000063224E8000000B402322DB00000000075 +:1022600006324000000000B40632300000000020BA +:10227000063231000000002006323200000000204B +:102280000632330000000020063234000000002037 +:102290000632350000000020063236000000002023 +:1022A000063237000000002006323800000000200F +:1022B000063239000000002006323A0000000020FB +:1022C00006323B000000002006323C0000000020E7 +:1022D00006323D000000002006323E0000000020D3 +:1022E00006323F000000002006321C1000000002F1 +:1022F000063245A000000024063227B8000000B4D2 +:1023000002322DB400000000063242D0000000B4BA +:1023100006323080000000200632318000000020AC +:102320000632328000000020063233800000002098 +:102330000632348000000020063235800000002084 +:102340000632368000000020063237800000002070 +:10235000063238800000002006323980000000205C +:1023600006323A800000002006323B800000002048 +:1023700006323C800000002006323D800000002034 +:1023800006323E800000002006323F800000002020 +:1023900006321C20000000020632463000000024F5 +:1023A0000720040000870000082007800010038237 +:1023B0000724000031A500000724800008190C6ADA +:1023C00008248EB06C9003840120000000000000FF +:1023D00001200004000000000120000800000000AF +:1023E0000120000C0000000001200010000000008F +:1023F0000120001400000000022000200000000165 +:102400000220002400000002022000280000000337 +:102410000220002C00000000022000300000000418 +:1024200002200034000000010220003800000000FB +:102430000220003C000000010220004000000004D7 +:1024400002200044000000000220004800000001BB +:102450000220004C00000003022000500000000099 +:102460000220005400000001022000580000000477 +:102470000220005C0000000002200060000000015B +:102480000220006400000003022000680000000039 +:102490000220006C00000001022000700000000417 +:1024A00002200074000000000220007800000004F8 +:1024B0000220007C000000030620008000000002D3 +:1024C000022000A400003FFF022000A8000003FF3C +:1024D000022002240000000002200234000000005C +:1024E0000220024C00000000022002E40000FFFF76 +:1024F000062020000000080002238BC0000000011D +:10250000022380000000001002238040000000121F +:102510000223808000000030022380C00000000EF3 +:102520000C2383000007A1200A2383000000013848 +:102530000B238300000013880A238340000000005F +:102540000C238340000001F40B23834000000005AE +:10255000022383800007A120022383C0000001F42E +:10256000062250000000004206222008000000C899 +:10257000062220000000000206224000000000C6E3 +:1025800004224318000503860622432C0000000B9A +:10259000042243580005038B0622436C0000000B05 +:1025A0000422439800050390062243AC0000000B70 +:1025B000042243D800050395062243EC0000000BDB +:1025C000042244180005039A0622442C0000000B44 +:1025D000042244580005039F0622446C0000000BAF +:1025E00004224498000503A4062244AC0000000B1A +:1025F000042244D8000503A9062244EC0000000B85 +:1026000004224518000503AE0622452C0000000BED +:1026100004224558000503B30622456C0000000B58 +:1026200004224598000503B8062245AC0000000BC3 +:10263000042245D8000503BD062245EC0000000B2E +:1026400004224618000503C20622462C0000000B97 +:1026500004224658000503C70622466C0000000B02 +:1026600004224698000503CC062246AC0000000B6D +:10267000042246D8000503D1062246EC0000000BD8 +:1026800004224718000503D60622472C0000000B41 +:1026900004224758000503DB0622476C0000000BAC +:1026A00004224798000503E0062247AC0000000B17 +:1026B000042247D8000503E5062247EC0000000B82 +:1026C00004224818000503EA0622482C0000000BEB +:1026D00004224858000503EF0622486C0000000B56 +:1026E00004224898000503F4062248AC0000000BC1 +:1026F000042248D8000503F9062248EC0000000B2C +:1027000004224918000503FE0622492C0000000B94 +:1027100004224958000504030622496C0000000BFE +:102720000422499800050408062249AC0000000B69 +:10273000042249D80005040D062249EC0000000BD4 +:1027400004224A180005041206224A2C0000000B3D +:1027500004224A580005041706224A6C0000000BA8 +:1027600004224A980005041C06224AAC0000000B13 +:1027700004224AD80005042106224AEC0000000584 +:1027800006224B000000001704224B5C00010426C7 +:1027900006224B600000000304224B6C000104275A +:1027A000062238000000004006223000000002002F +:1027B000042251C00004042806221000000000C0BA +:1027C000062215C00000024004221EC80008042C86 +:1027D0000622390000000008022251180000000003 +:1027E000062251D00000000606221300000000025D +:1027F00006221410000000300622392000000008D4 +:102800000222511C00000000062251E800000006D0 +:102810000622130800000002062214D00000003037 +:102820000216100000000028021700080000000235 +:102830000217002C000000030217003C00000004F7 +:1028400002170044000000000217004800000002C8 +:102850000217004C0000009002170050000000908A +:102860000217005400800090021700580810000062 +:10287000021700600000008A021700640000008058 +:1028800002170068000000810217006C0000008041 +:10289000021700700000000602170078000007D041 +:1028A0000217007C0000076C02170038007C10043F +:1028B000021700040000000F06164024000000026A +:1028C000021640700000001C0216420800000001C1 +:1028D0000216421000000001021642200000000112 +:1028E00002164228000000010216423000000001DA +:1028F000021642380000000102164260000000018A +:102900000C16401C0003D0900A16401C0000009CCE +:102910000B16401C000009C40216403000000008DD +:10292000021640340000000C02164038000000106F +:102930000216404400000020021640000000000182 +:10294000021640D8000000010216400800000001F5 +:102950000216400C000000010216401000000001A9 +:10296000021642400000000002164248000000002B +:1029700006164270000000020216425000000000DD +:1029800002164258000000000616428000000002B5 +:1029900002166008000006140216600C0000060013 +:1029A00002166010000006040216601C0000FFFF03 +:1029B000021660200000FFFF021660240000FFFFE7 +:1029C000021660280000FFFF021660380000002099 +:1029D0000216603C00000020061660400000000265 +:1029E00002166048000000230216604C000000241C +:1029F00002166050000000250216605400000026F8 +:102A000002166058000000270216605C00000029D2 +:102A1000021660600000002A021660640000002BAD +:102A2000021660680000002C0216606C0000002D89 +:102A30000616607000000012021660B80000000167 +:102A4000021660BC00000001061660C00000003ED7 +:102A5000021661B800000001061661BC0000001FEC +:102A60000216623807FFFFFF0216623C0000003FBB +:102A70000216624007FFFFFF021662440000000FCB +:102A800001166248000000000116624C00000000C0 +:102A900001166250000000000116625400000000A0 +:102AA00001166258000000000116625C0000000080 +:102AB0000116626000000000011662640000000060 +:102AC00001166268000000000116626C0000000040 +:102AD0000116627000000000011662740000000020 +:102AE00001166278000000000116627C0000000000 +:102AF000021664BC000000010C166000000003E830 +:102B00000A166000000000010B1660000000000AB9 +:102B100002168040000000060216804400000005F6 +:102B2000021680480000000A0216804C00000005D2 +:102B30000216805400000002021680CC000000043F +:102B4000021680D000000004021680D400000004A9 +:102B5000021680D800000004021680DC0000000489 +:102B6000021680E000000004021680E40000000469 +:102B7000021680E800000004021688040000000429 +:102B8000021680300000007C021680340000003DF8 +:102B9000021680380000003F0216803C0000009CB6 +:102BA000021680F000000007061680F40000000501 +:102BB0000216880C010101010216810800000000C4 +:102BC0000216810C000000040216811000000004AF +:102BD0000216811400000002021688100801200469 +:102BE00002168118000000050216811C0000000575 +:102BF0000216812000000005021681240000000555 +:102C00000216882C200810010216812800000008F6 +:102C10000216812C00000006021681300000000719 +:102C200002168134000000000216883001010120E4 +:102C300006168138000000040216883401010101E3 +:102C400006168148000000040216883801010101BF +:102C500006168158000000040216883C010101019B +:102C6000061681680000000302168174000000014E +:102C7000021688400101010102168178000000015E +:102C80000216817C00000001021681800000000114 +:102C9000021681840000000102168844010101012E +:102CA00002168188000000010216818C00000004D9 +:102CB00002168190000000040216819400000002B8 +:102CC00002168848080120040216819800000005B9 +:102CD0000216819C00000005021681A0000000057C +:102CE000021681A4000000050216881420081001B5 +:102CF000021681A800000008021681AC0000000640 +:102D0000021681B000000007021681B40000000125 +:102D10000216881801010120021681B80000000186 +:102D2000021681BC00000001021681C000000001F3 +:102D3000021681C4000000010216881C0101010175 +:102D4000021681C800000001021681CC00000001BB +:102D5000021681D000000001021681D4000000019B +:102D60000216882001010101021681D8000000012D +:102D7000021681DC00000001021681E00000000163 +:102D8000021681E4000000010216882401010101FD +:102D9000021681E800000001021681EC000000012B +:102DA000021681F0000000010216882801010101CD +:102DB00002168240FFFF003F061682440000000218 +:102DC0000216824CFFFF003F0216825000000100F5 +:102DD000021682540000010006168258000000020C +:102DE00002168260000000C002168264000000C06B +:102DF0000216826800001E000216826C00001E008F +:102E0000021682700000400002168274000040002A +:102E100002168278000080000216827C000080008A +:102E2000021682800000200002168284000020002A +:102E30000616828800000007021682A40000000126 +:102E4000061682A80000000A021681F400000C0891 +:102E5000021681F800000040021681FC000001000B +:102E600002168200000000200216820400000017F3 +:102E700002168208000000800216820C0000020088 +:102E8000021682100000000002168218FFFF01FFE8 +:102E900002168214FFFF01FF0216823C000000139D +:102EA000021680900000013F021680600000014081 +:102EB00002168064000001400616806800000002CF +:102EC00002168070000000C0061680740000000723 +:102ED0000216809C00000048021680A000000048F6 +:102EE000061680A400000002021680AC0000004814 +:102EF000061680B00000000702168238000080002D +:102F000002168234000025E40216809400007FFF40 +:102F100002168220000000070216821C0000000733 +:102F2000021682280000000002168224FFFFFFFF25 +:102F300002168230000000000216822CFFFFFFFF05 +:102F4000021680EC000000FF0214000000000001E7 +:102F50000214000C000000010214004000000001F7 +:102F60000214004400007FFF0214000C0000000067 +:102F700002140000000000000214006C00000000B9 +:102F800002140004000000010214003000000001DF +:102F900002140004000000000214005C00000000A5 +:102FA00002140008000000010214003400000001B7 +:102FB000021400080000000002140060000000007D +:102FC00006028000000020000202005800000032CB +:102FD000020200A003150020020200A40315002035 +:102FE000020200A801000030020200AC081000003C +:102FF000020200B000000033020200B40000003002 +:10300000020200B800000031020200BC0000000310 +:10301000020200C000000006020200C4000000031B +:10302000020200C800000003020200CC00000002FF +:10303000020200D000000000020200D400000002E2 +:10304000020200DC00000000020200E000000006B6 +:10305000020200E400000004020200E80000000296 +:10306000020200EC00000002020200F00000000179 +:10307000020200FC00000006020201200000000025 +:103080000202013400000002020201B0000000014F +:103090000202020C00000001020202140000000102 +:1030A00002020218000000020202040400000001F3 +:1030B0000202040C00000040020204100000004064 +:1030C0000202041C00000004020204200000002090 +:1030D0000202042400000002020204280000001F73 +:1030E00006020500000000120402048000200434DF +:1030F000020200600000000F0202006400000007EE +:1031000002020068000000000202006C0000000ED5 +:103110000602007000000004020200F40000000437 +:103120000202000400000001020200080000000189 +:103130000202000C00000001020200100000000169 +:103140000202001400000001020200180000000149 +:103150000202001C00000001020200200000000129 +:103160000202002400000001020200280000000109 +:103170000202002C000000010202003000000001E9 +:1031800002020034000000010202003800000001C9 +:103190000202003C000000010202004000000001A9 +:1031A0000202004400000001020200480000000189 +:1031B0000202004C00000001020200500000000169 +:1031C00002020108000000C802020118000000020B +:1031D000020201C400000000020201CC0000000055 +:1031E000020201D400000002020201DC0000000221 +:1031F000020201E4000000FF020201EC000000FFF7 +:103200000202010C000000C80202011C00000002C2 +:10321000020201C800000000020201D0000000000C +:10322000020201D800000002020201E000000002D8 +:10323000020201E8000000FF020201F0000000FFAE +:1032400007280400008D00000828076800130454B4 +:10325000072C000033FC0000072C800038B20D0062 +:10326000072D000039171B2D072D800005D9297364 +:10327000082D8A204EBC04560128000000000000E2 +:1032800001280004000000000128000800000000E0 +:103290000128000C000000000128001000000000C0 +:1032A0000128001400000000022800200000000196 +:1032B0000228002400000002022800280000000369 +:1032C0000228002C0000000002280030000000044A +:1032D000022800340000000102280038000000002D +:1032E0000228003C00000001022800400000000409 +:1032F00002280044000000000228004800000001ED +:103300000228004C000000030228005000000000CA +:1033100002280054000000010228005800000004A8 +:103320000228005C0000000002280060000000018C +:10333000022800640000000302280068000000006A +:103340000228006C00000001022800700000000448 +:103350000228007400000000022800780000000429 +:103360000228007C00000003062800800000000204 +:10337000022800A400003FFF022800A8000003FF6D +:10338000022802240000000002280234000000008D +:103390000228024C00000000022802E40000FFFFA7 +:1033A0000628200000000800022B8BC0000000014E +:1033B000022B800000000000022B8040000000185B +:1033C000022B80800000000C022B80C000000066F1 +:1033D0000C2B83000007A1200A2B8300000001387A +:1033E0000B2B8300000013880A2B83400000000091 +:1033F0000C2B8340000001F40B2B834000000005E0 +:10340000022B83800007A120022B83C0000001F45F +:10341000062A3D4800000004042A3D5800020458D2 +:10342000062A3D6000000006062A30000000004821 +:10343000062A2008000000C8062A2000000000021A +:10344000062A31280000008E062A33680000000397 +:10345000042A33740001045A062A3A780000000254 +:10346000042A3A800002045B042A3A700002045DD8 +:10347000042A3E280002045F042A3EB000040461CE +:10348000042A250000020465062A25080000010020 +:10349000062A297000000004042A29600004046739 +:1034A000042A2F480002046B062A3378000000D853 +:1034B000022A3A3800000000062A3A88000000324A +:1034C000042A3D880010046D062A502000000002E6 +:1034D000062A503000000002062A500000000002B8 +:1034E000062A501000000002022A50B80000000115 +:1034F000062A50480000000E042A3D780002047D90 +:10350000062A3C1800000026022A50400000000055 +:10351000062A36D8000000D8022A3A3C00000000F3 +:10352000062A3B5000000032042A3DC80010047FE8 +:10353000062A502800000002062A50380000000227 +:10354000062A500800000002062A50180000000257 +:10355000022A50BC00000001062A50800000000E24 +:10356000042A3D800002048F062A3CB00000002699 +:10357000022A504400000000021010080000000160 +:103580000210101000000264021010000003D000AE +:10359000021010040000003D091018000200049100 +:1035A00009101100001006910610114000000008DB +:1035B00009101160000806A1061011800000000229 +:1035C00009101188000606A9061011A000000018B5 +:1035D000021010100000000006102400000000E09F +:1035E0000210201C0000000002102020000000013A +:1035F000021020C0000000010210200400000001A1 +:10360000021020080000000109103C00000506AF70 +:1036100009103C20000506B409103800000506B961 +:1036200002104028000000100210404400003FFF3C +:103630000210405800280000021040840084924A82 +:1036400006104C000000010002104058000000006D +:103650000610806800000004021080000000108046 +:1036600006108028000000020210803800000010C0 +:10367000021080400000FFFF021080440000FFFFA6 +:1036800002108050000000000210810000000000C5 +:10369000061081200000000202108008000002B520 +:1036A0000210801000000000061082000000004A96 +:1036B000021081080001FFFF061081400000000297 +:1036C0000210800000001A80061090000000002404 +:1036D000061091200000004A061093700000004A76 +:1036E000061095C00000004A0210800400001080FF +:1036F00006108030000000020210803C0000001024 +:10370000021080480000FFFF0210804C0000FFFF05 +:10371000021080540000000002108104000000002C +:1037200006108128000000020210800C000002B583 +:103730000210801400000000061084000000004AFF +:103740000210810C0001FFFF0610814800000002FA +:103750000210800400001A800610909000000024DF +:10376000061092480000004A061094980000004A93 +:10377000061096E80000004A0212049000E383401D +:103780000212051400003C10021205200000000285 +:1037900002120494FFFFFFFF02120498FFFFFFFFD5 +:1037A0000212049CFFFFFFFF021204A0FFFFFFFFB5 +:1037B000021204A4FFFFFFFF021204A8FFFFFFFF95 +:1037C000021204ACFFFFFFFF021204B0FFFFFFFF75 +:1037D000021204B8FFFFFFFF021204BCFFFFFFFF4D +:1037E000021204C0FFFFFFFF021204C4FFFFFFFF2D +:1037F000021204C8FFFFFFFF021204CCFFFFFFFF0D +:10380000021204D0FFFFFFFF021204DCFFFFFFFFE4 +:10381000021204E0FFFFFFFF021204E4FFFFFFFFBC +:10382000021204E8FFFFFFFF021204ECFFFFFFFF9C +:10383000021204F0FFFFFFFF021204F4FFFFFFFF7C +:10384000021204F8FFFFFFFF021204FCFFFFFFFF5C +:1038500002120500FFFFFFFF02120504FFFFFFFF3A +:1038600002120508FFFFFFFF0212050CFFFFFFFF1A +:1038700002120510FFFFFFFF021204D4FFFF3330D6 +:10388000021204D8FFFF3340021204B4F0003000EB +:1038900002120390000000080212039C00000008BE +:1038A000061203A000000002021203BC0000000484 +:1038B000021203C400000004021203D00000000042 +:1038C000021203DC000000000212036C0000000181 +:1038D000021203680000003F021201BC0000004019 +:1038E000021201C000001808021201C400000803FF +:1038F000021201C800000803021201CC00000040BF +:10390000021201D000000003021201D400000803DB +:10391000021201D800000803021201DC00000803B3 +:10392000021201E000010003021201E4000008039A +:10393000021201E800000803021201EC000000037B +:10394000021201F000000003021201F40000000363 +:10395000021201F800000003021201FC0000000343 +:103960000212020000000003021202040000000321 +:1039700002120208000000030212020C0000000301 +:1039800002120210000000030212021400000003E1 +:1039900002120218000000030212021C00000003C1 +:1039A00002120220000000030212022400000003A1 +:1039B00002120228000024030212022C0000002F31 +:1039C0000212023000000009021202340000001945 +:1039D00002120238000001840212023C000001833E +:1039E0000212024000000306021202440000001905 +:1039F00002120248000000060212024C00000306F8 +:103A000002120250000003060212025400000306D4 +:103A10000212025800000C860212025C000003062B +:103A20000212026000000306021202640000000697 +:103A300002120268000000060212026C000000067A +:103A4000021202700000000602120274000000065A +:103A500002120278000000060212027C000000063A +:103A6000021202800000000602120284000000061A +:103A700002120288000000060212028C00000006FA +:103A800002120290000000060212029400000006DA +:103A900002120298000000060212029C00000006BA +:103AA000021202A000000306021202A4000000138A +:103AB000021202A800000006021202B00000100468 +:103AC000021202B400001004021203240010644029 +:103AD0000212032800106440021201B0000000012D +:103AE0000600A000000000160200A06CBF5C0000F1 +:103AF0000200A070FFF51FEF0200A0740000FFFF9E +:103B00000200A078F00003E00200A07C00000000AA +:103B10000200A0800000A0000600A08400000005B4 +:103B20000200A0980FE000000600A09C0000001416 +:103B30000200A0EC555400000200A0F05555555568 +:103B40000200A0F4000055550200A0F8F0000000AB +:103B50000200A0FC555400000200A1005555555527 +:103B60000200A104000055550200A108F000000069 +:103B70000600A22C000000040200A0600000030761 +:103B80000200A10CBF5C00000200A110FFF51FEFB6 +:103B90000200A1140000FFFF0200A118F00003E0E2 +:103BA0000200A11C000000000200A1200000A000F3 +:103BB0000600A124000000050200A1380FE000006B +:103BC0000600A13C000000140200A18C5554000026 +:103BD0000200A190555555550200A194000055557D +:103BE0000200A198F00000000200A19C55540000C2 +:103BF0000200A1A0555555550200A1A4000055553D +:103C00000200A1A8F00000000600A23C0000000491 +:103C10000200A06400000307000000000000000094 +:103C20000000002E00000000000000000000000066 +:103C30000000000000000000000000000000000084 +:103C40000000000000000000000000000000000074 +:103C50000000000000000000000000000000000064 +:103C60000000000000000000000000000000000054 +:103C70000000000000000000002E004D00000000C9 +:103C80000000000000000000000000000000000034 +:103C90000000000000000000000000000000000024 +:103CA00000000000004D008B00000000000000003C +:103CB0000000000000000000000000000000000004 +:103CC00000000000000000000000000000000000F4 +:103CD000008B009000900094009400980000000079 +:103CE00000000000000000000000000000000000D4 +:103CF000000000000000000000000000009802DE4C +:103D000002DE02E802E802F200000000000000000B +:103D100000000000000000000000000000000000A3 +:103D20000000000000000000000000000000000093 +:103D30000000000000000000000000000000000083 +:103D40000000000000000000000000000000000073 +:103D50000000000000000000000000000000000063 +:103D60000000000000000000000000000000000053 +:103D70000000000000000000000000000000000043 +:103D80000000000000000000000000000000000033 +:103D90000000000000000000000000000000000023 +:103DA0000000000000000000000000000000000013 +:103DB0000000000000000000000000000000000003 +:103DC00000000000000000000000000000000000F3 +:103DD000000000000000000002F202FA00000000F3 +:103DE00000000000000000000000000000000000D3 +:103DF00000000000000000000000000000000000C3 +:103E000000000000000000000000000000000000B2 +:103E100000000000000000000000000000000000A2 +:103E20000000000000000000000000000000000092 +:103E300002FA02FF02FF030A030A03150000000052 +:103E40000000000000000000000000000000000072 +:103E50000000000000000000000000000000000062 +:103E60000000000000000000000000000000000052 +:103E70000000000000000000000000000000000042 +:103E80000000000000000000031503160000000001 +:103E90000000000000000000000000000000000022 +:103EA0000000000000000000000000000000000012 +:103EB000000000000316035700000000000000008F +:103EC00000000000000000000000000000000000F2 +:103ED00000000000000000000000000000000000E2 +:103EE0000357037B000000000000000000000000FA +:103EF00000000000000000000000000000000000C2 +:103F0000000000000000000000000000037B03BB75 +:103F100000000000000000000000000000000000A1 +:103F20000000000000000000000000000000000091 +:103F3000000000000000000003BB03F700000000C9 +:103F40000000000000000000000000000000000071 +:103F50000000000000000000000000000000000061 +:103F60000000000003F7043D043D045204520467BE +:103F70000000000000000000000000000000000041 +:103F80000000000000000000000000000000000031 +:103F9000046704ED04ED04F204F204F700000000ED +:103FA0000000000000000000000000000000000011 +:103FB00000000000000000000000000004F704F80A +:103FC00000000000000000000000000000000000F1 +:103FD00000000000000000000000000000000000E1 +:103FE000000000000000000004F8050A00000000C6 +:103FF00000000000000000000000000000000000C1 +:1040000000000000000000000000000000000000B0 +:1040100000000000050A051F051F052205220525D1 +:104020000000000000000000000000000000000090 +:104030000000000000000000000000000000000080 +:1040400005250555000000000000000000000000EC +:104050000000000000000000000000000000000060 +:10406000000000000000000000000000055505DC15 +:104070000000000000000000000000000000000040 +:104080000000000000000000000000000000000030 +:10409000000000000000000005DC05E305E305E783 +:1040A00005E705EB00000000000000000000000034 +:1040B0000000000000000000000000000000000000 +:1040C0000000000005EB062B062B06330633063BEB +:1040D00000000000000000000000000000000000E0 +:1040E00000000000000000000000000000000000D0 +:1040F000063B068806880695069506A20000000085 +:1041000000000000000000000000000000000000AF +:1041100000000000000000000000000006A206AE43 +:10412000000000000000000000000000000000008F +:10413000000000000000000000000000000000007F +:10414000000000000000000006AE06B40000000001 +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:104170000000000006B406B70000000000000000C8 +:10418000000000000000000000000000000000002F +:10419000000000000000000000000000000000001F +:1041A00006B706BD0000000000000000000000008F +:1041B00000000000000000000000000000000000FF +:1041C00000000000000000000000000006BD06BE68 +:1041D00006BE06D006D006E2000000000000000087 +:1041E00000000000000000000000000000000000CF +:1041F000000000000000000006E2074F0000000081 +:1042000000000000000000000000000000000000AE +:10421000000000000000000000000000000000009E +:1042200000000000074F0750075007630763077639 +:10423000000000000000000000000000000000007E +:10424000000000000000000000000000000000006E +:10425000000000000000000000000000000000005E +:10426000000000000000000000000000000000004E +:10427000000000000000000000000000000000003E +:10428000000000000000000000000000000000002E +:10429000000000000000000000000000000000001E +:1042A000000000000000000000000000000000000E +:1042B00000000000000000000000000000000000FE +:1042C00000000000000000000000000000000000EE +:1042D00000000000000000000000000000000000DE +:1042E00000000000000000000000000000000000CE +:1042F00000000000000000000000000000000000BE +:1043000000000000000000000000000000000000AD +:10431000000000000000000000000000000000009D +:10432000000000000000000000000000000000008D +:1043300000010000000204C00003098000040E40D8 +:1043400000051300000617C000071C80000821406C +:1043500000092600000A2AC0000B2F80000C344000 +:10436000000D3900000E3DC0000F42800010474094 +:1043700000114C00001250C00013558000145A4028 +:1043800000155F00001663C00017688000186D40BC +:1043900000197200001A76C0001B7B80001C804050 +:1043A000001D8500001E89C0001F8E800000934004 +:1043B00000002000000040000000600000008000BD +:1043C0000000A0000000C0000000E00000010000AC +:1043D0000001200000014000000160000001800099 +:1043E0000001A0000001C0000001E0000002000088 +:1043F0000002200000024000000260000002800075 +:104400000002A0000002C0000002E0000003000063 +:104410000003200000034000000360000003800050 +:104420000003A0000003C0000003E000000400003F +:10443000000420000004400000046000000480002C +:104440000004A0000004C0000004E000000500001B +:104450000005200000054000000560000005800008 +:104460000005A0000005C0000005E00000060000F7 +:1044700000062000000640000006600000068000E4 +:104480000006A0000006C0000006E00000070000D3 +:1044900000072000000740000007600000078000C0 +:1044A0000007A0000007C0000007E00000080000AF +:1044B000000820000008400000086000000880009C +:1044C0000008A0000008C0000008E000000900008B +:1044D0000009200000094000000960000009800078 +:1044E0000009A0000009C0000009E000000A000067 +:1044F000000A2000000A4000000A6000000A800054 +:10450000000AA000000AC000000AE000000B000042 +:10451000000B2000000B4000000B6000000B80002F +:10452000000BA000000BC000000BE000000C00001E +:10453000000C2000000C4000000C6000000C80000B +:10454000000CA000000CC000000CE000000D0000FA +:10455000000D2000000D4000000D6000000D8000E7 +:10456000000DA000000DC000000DE000000E0000D6 +:10457000000E2000000E4000000E6000000E8000C3 +:10458000000EA000000EC000000EE000000F0000B2 +:10459000000F2000000F4000000F6000000F80009F +:1045A000000FA000000FC000000FE000001000008E +:1045B000001020000010400000106000001080007B +:1045C0000010A0000010C0000010E000001100006A +:1045D0000011200000114000001160000011800057 +:1045E0000011A0000011C0000011E0000012000046 +:1045F0000012200000124000001260000012800033 +:104600000012A0000012C0000012E0000013000021 +:10461000001320000013400000136000001380000E +:104620000013A0000013C0000013E00000140000FD +:1046300000142000001440000014600000148000EA +:104640000014A0000014C0000014E00000150000D9 +:1046500000152000001540000015600000158000C6 +:104660000015A0000015C0000015E00000160000B5 +:1046700000162000001640000016600000168000A2 +:104680000016A0000016C0000016E0000017000091 +:10469000001720000017400000176000001780007E +:1046A0000017A0000017C0000017E000001800006D +:1046B000001820000018400000186000001880005A +:1046C0000018A0000018C0000018E0000019000049 +:1046D0000019200000194000001960000019800036 +:1046E0000019A0000019C0000019E000001A000025 +:1046F000001A2000001A4000001A6000001A800012 +:10470000001AA000001AC000001AE000001B000000 +:10471000001B2000001B4000001B6000001B8000ED +:10472000001BA000001BC000001BE000001C0000DC +:10473000001C2000001C4000001C6000001C8000C9 +:10474000001CA000001CC000001CE000001D0000B8 +:10475000001D2000001D4000001D6000001D8000A5 +:10476000001DA000001DC000001DE000001E000094 +:10477000001E2000001E4000001E6000001E800081 +:10478000001EA000001EC000001EE000001F000070 +:10479000001F2000001F4000001F6000001F80005D +:1047A000001FA000001FC000001FE000002000004C +:1047B0000020200000204000002060000020800039 +:1047C0000020A0000020C0000020E0000021000028 +:1047D0000021200000214000002160000021800015 +:1047E0000021A0000021C0000021E0000022000004 +:1047F00000222000002240000022600000228000F1 +:104800000022A0000022C0000022E00000230000DF +:1048100000232000002340000023600000238000CC +:104820000023A0000023C0000023E00000240000BB +:1048300000242000002440000024600000248000A8 +:104840000024A0000024C0000024E0000025000097 +:104850000025200000254000002560000025800084 +:104860000025A0000025C0000025E0000026000073 +:104870000026200000264000002660000026800060 +:104880000026A0000026C0000026E000002700004F +:10489000002720000027400000276000002780003C +:1048A0000027A0000027C0000027E000002800002B +:1048B0000028200000284000002860000028800018 +:1048C0000028A0000028C0000028E0000029000007 +:1048D00000292000002940000029600000298000F4 +:1048E0000029A0000029C0000029E000002A0000E3 +:1048F000002A2000002A4000002A6000002A8000D0 +:10490000002AA000002AC000002AE000002B0000BE +:10491000002B2000002B4000002B6000002B8000AB +:10492000002BA000002BC000002BE000002C00009A +:10493000002C2000002C4000002C6000002C800087 +:10494000002CA000002CC000002CE000002D000076 +:10495000002D2000002D4000002D6000002D800063 +:10496000002DA000002DC000002DE000002E000052 +:10497000002E2000002E4000002E6000002E80003F +:10498000002EA000002EC000002EE000002F00002E +:10499000002F2000002F4000002F6000002F80001B +:1049A000002FA000002FC000002FE000003000000A +:1049B00000302000003040000030600000308000F7 +:1049C0000030A0000030C0000030E00000310000E6 +:1049D00000312000003140000031600000318000D3 +:1049E0000031A0000031C0000031E00000320000C2 +:1049F00000322000003240000032600000328000AF +:104A00000032A0000032C0000032E000003300009D +:104A1000003320000033400000336000003380008A +:104A20000033A0000033C0000033E0000034000079 +:104A30000034200000344000003460000034800066 +:104A40000034A0000034C0000034E0000035000055 +:104A50000035200000354000003560000035800042 +:104A60000035A0000035C0000035E0000036000031 +:104A7000003620000036400000366000003680001E +:104A80000036A0000036C0000036E000003700000D +:104A900000372000003740000037600000378000FA +:104AA0000037A0000037C0000037E00000380000E9 +:104AB00000382000003840000038600000388000D6 +:104AC0000038A0000038C0000038E00000390000C5 +:104AD00000392000003940000039600000398000B2 +:104AE0000039A0000039C0000039E000003A0000A1 +:104AF000003A2000003A4000003A6000003A80008E +:104B0000003AA000003AC000003AE000003B00007C +:104B1000003B2000003B4000003B6000003B800069 +:104B2000003BA000003BC000003BE000003C000058 +:104B3000003C2000003C4000003C6000003C800045 +:104B4000003CA000003CC000003CE000003D000034 +:104B5000003D2000003D4000003D6000003D800021 +:104B6000003DA000003DC000003DE000003E000010 +:104B7000003E2000003E4000003E6000003E8000FD +:104B8000003EA000003EC000003EE000003F0000EC +:104B9000003F2000003F4000003F6000003F8000D9 +:104BA000003FA000003FC000003FE000003FE001E8 +:104BB00000000000000001FF0000020000007FF87C +:104BC00000007FF80000016A0000150000000001ED +:104BD0000000FF00000000000000FF0000000000D7 +:104BE00000000000140AFF000000000100000000A7 +:104BF00000201001000000000100860000000100FC +:104C00000000860200008604000086060000860878 +:104C10000000860A0000860C0000860E0000861048 +:104C20000000861200008614000086160000861818 +:104C30000000861A0000861C0000861E00008620E8 +:104C400000008622000086240000862600008628B8 +:104C50000000862A0000862C0000862E0000863088 +:104C60000000863200008634000086360000863858 +:104C70000000863A0000863C0000863E0000864028 +:104C800000008642000086440000864600008648F8 +:104C90000000864A0000864C0000864E00008650C8 +:104CA0000000865200008654000086560000865898 +:104CB0000000865A0000865C0000865E0000866068 +:104CC0000000866200008664000086660000866838 +:104CD0000000866A0000866C0000866E0000867008 +:104CE00000008672000086740000867600008678D8 +:104CF0000000867A0000867C0000867E00008680A8 +:104D00000000868200008684000086860000868877 +:104D10000000868A0000868C0000868E0000869047 +:104D20000000869200008694000086960000869817 +:104D30000000869A0000869C0000869E000086A0E7 +:104D4000000086A2000086A4000086A6000086A8B7 +:104D5000000086AA000086AC000086AE000086B087 +:104D6000000086B2000086B4000086B6000086B857 +:104D7000000086BA000086BC000086BE000086C027 +:104D8000000086C2000086C4000086C6000086C8F7 +:104D9000000086CA000086CC000086CE000086D0C7 +:104DA000000086D2000086D4000086D6000086D897 +:104DB000000086DA000086DC000086DE000086E067 +:104DC000000086E2000086E4000086E6000086E837 +:104DD000000086EA000086EC000086EE000086F007 +:104DE000000086F2000086F4000086F6000086F8D7 +:104DF000000086FA000086FC000086FE00008700A6 +:104E00000000870200008704000087060000870872 +:104E10000000870A0000870C0000870E0000871042 +:104E20000000871200008714000087160000871812 +:104E30000000871A0000871C0000871E00008720E2 +:104E400000008722000087240000872600008728B2 +:104E50000000872A0000872C0000872E0000873082 +:104E60000000873200008734000087360000873852 +:104E70000000873A0000873C0000873E0000874022 +:104E800000008742000087440000874600008748F2 +:104E90000000874A0000874C0000874E00008750C2 +:104EA0000000875200008754000087560000875892 +:104EB0000000875A0000875C0000875E0000876062 +:104EC0000000876200008764000087660000876832 +:104ED0000000876A0000876C0000876E0000877002 +:104EE00000008772000087740000877600008778D2 +:104EF0000000877A0000877C0000877E00008780A2 +:104F00000000878200008784000087860000878871 +:104F10000000878A0000878C0000878E0000879041 +:104F20000000879200008794000087960000879811 +:104F30000000879A0000879C0000879E000087A0E1 +:104F4000000087A2000087A4000087A6000087A8B1 +:104F5000000087AA000087AC000087AE000087B081 +:104F6000000087B2000087B4000087B6000087B851 +:104F7000000087BA000087BC000087BE000087C021 +:104F8000000087C2000087C4000087C6000087C8F1 +:104F9000000087CA000087CC000087CE000087D0C1 +:104FA000000087D2000087D4000087D6000087D891 +:104FB000000087DA000087DC000087DE000087E061 +:104FC000000087E2000087E4000087E6000087E831 +:104FD000000087EA000087EC000087EE000087F001 +:104FE000000087F2000087F4000087F6000087F8D1 +:104FF000000087FA000087FC000087FEFFFFFFFF2C +:10500000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 +:10501000FFFFFFFFFFFFFFFFFFFFFFFF0000000399 +:1050200000BEBC20000000000000000500000003DE +:1050300000BEBC20000000000000000500002000B1 +:10504000000040C000006180000082400000A3001A +:105050000000C3C00000E4800001054000012600FC +:10506000000146C000016780000188400001A900DE +:105070000001C9C00001EA8000020B4000022C00C0 +:1050800000024CC000026D8000028E400002AF00A2 +:105090000002CFC00002F08000001140000080003C +:1050A000000103800001870000020A8000028E00D8 +:1050B00000031180000395000004188000049C0088 +:1050C00000051F800005A300000626800006AA0038 +:1050D00000072D800007B100000834800008B800E8 +:1050E00000093B800009BF00000A4280000AC60098 +:1050F000000B4980000BCD00000C5080000CD40048 +:10510000000D578000005B0000007FF800007FF872 +:1051100000000166000015000000FF000000000014 +:105120000000FF0000000000000019000000000067 +:1051300000000000FFFFFFFF00007FF800007FF885 +:105140000000035F000035000000FF000FFFFFFFBD +:105150000000FF000FFFFFFF000000FF0000FF0046 +:105160000FFFFFFF0000FF000FFFFFFF000000FF29 +:105170000000FF000FFFFFFF0000FF000FFFFFFF19 +:10518000000000FF0000FF000FFFFFFF0000FF0016 +:105190000FFFFFFF000000FF0000FF000FFFFFFFF9 +:1051A0000000FF000FFFFFFF000000FF0000FF00F6 +:1051B0000FFFFFFF0000FF000FFFFFFF000000FFD9 +:1051C0000000FF000FFFFFFF0000FF000FFFFFFFC9 +:1051D000000000FF0000FF000FFFFFFF0000FF00C6 +:1051E0000FFFFFFF000000FF0000FF000FFFFFFFA9 +:1051F0000000FF000FFFFFFF000000FF0000FF00A6 +:105200000FFFFFFF0000FF000FFFFFFF000000FF88 +:105210000000FF000FFFFFFF0000FF000FFFFFFF78 +:10522000000000FF0000FF000FFFFFFF0000FF0075 +:105230000FFFFFFF000000FF0000FF000FFFFFFF58 +:105240000000FF000FFFFFFF000000FF0000FF0055 +:105250000FFFFFFF0000FF000FFFFFFF000000FF38 +:105260000000FF000FFFFFFF0000FF000FFFFFFF28 +:10527000000000FF0000FF000FFFFFFF0000FF0025 +:105280000FFFFFFF000000FF0000FF000FFFFFFF08 +:105290000000FF000FFFFFFF000000FF0000FF0005 +:1052A0000FFFFFFF0000FF000FFFFFFF000000FFE8 +:1052B0000000FF000FFFFFFF0000FF000FFFFFFFD8 +:1052C000000000FF0000FF000FFFFFFF0000FF00D5 +:1052D0000FFFFFFF000000FF0000FF000FFFFFFFB8 +:1052E0000000FF000FFFFFFF000000FF0000FF00B5 +:1052F0000FFFFFFF0000FF000FFFFFFF000000FF98 +:105300000000FF000FFFFFFF0000FF000FFFFFFF87 +:10531000000000FF0000FF000FFFFFFF0000FF0084 +:105320000FFFFFFF000000FF0000FF000FFFFFFF67 +:105330000000FF000FFFFFFF000000FF0000FF0064 +:105340000FFFFFFF0000FF000FFFFFFF000000FF47 +:105350000000FF000FFFFFFF0000FF000FFFFFFF37 +:10536000000000FF0000FF000FFFFFFF0000FF0034 +:105370000FFFFFFF000000FF0000FF000FFFFFFF17 +:105380000000FF000FFFFFFF000000FF0000FF0014 +:105390000FFFFFFF0000FF000FFFFFFF000000FFF7 +:1053A0000000FF000FFFFFFF0000FF000FFFFFFFE7 +:1053B000000000FF0000FF000FFFFFFF0000FF00E4 +:1053C0000FFFFFFF000000FF000000FF000000FFD4 +:1053D0000000FF00000000000000FF0000000000CF +:1053E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:1053F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:1054000000001000000020800000310000004180FA +:1054100000005200000062800000730000008380E2 +:10542000000094000000A4800000B5000000C580CA +:105430000000D6000000E6800000F70000010780B1 +:105440000001180000012880000139000001498096 +:1054500000015A0000016A8000017B0000018B807E +:1054600000019C000001AC800001BD000001CD8066 +:105470000001DE000001EE8000000F0000000000CF +:1054800000007FF800007FF80000021A00003500DD +:1054900010000000000028AD00010001FFFFFFFF29 +:1054A000FFFFFFFF00220006CCCCCCC17058103C9F +:1054B000000000000000FF00000000000000FF00EE +:1054C000000000000000000000000001CCCC020140 +:1054D000CCCCCCCCCCCC0201CCCCCCCC00000000D1 +:1054E000FFFFFFFF0000FFFF000000000000FFFFC4 +:1054F000000000000000FFFF000000000000FFFFB0 +:10550000000000000000FFFF000000000000FFFF9F +:10551000000000000000FFFF000000000000FFFF8F +:1055200000000000000E0000011600D60000FFFF82 +:10553000000000000000FFFF000000000000FFFF6F +:10554000000000000000FFFF000000000000FFFF5F +:10555000000000000000FFFF000000000000FFFF4F +:10556000000000000000FFFF0000000000720000CB +:10557000012300F3FFFFFFF3318FFFFF0C30C30C5B +:10558000C30C30C3CF3CF300F3CF3CF30000CF3C5F +:10559000CDCDCDCDFFFFFFF130EFFFFF0C30C30CC1 +:1055A000C30C30C3CF3CF300F3CF3CF30001CF3C3E +:1055B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2C +:1055C000C30C30C3CF3CF300F3CF3CF30002CF3C1D +:1055D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C2 +:1055E000C30C30C3CF300014F3CF3CF30004CF3CE6 +:1055F000CDCDCDCDFFFFFFF2304FFFFF0C30C30C00 +:10560000C30C30C3CF3CF300F3CF3CF30008CF3CD6 +:10561000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF7 +:10562000C30C30C3CF3CF300F3CF3CF30010CF3CAE +:10563000CDCDCDCDFFFFFFF731EFFFFF0C30C30C19 +:10564000C30C30C3CF3CF300F3CF3CF30020CF3C7E +:10565000CDCDCDCDFFFFFFF5302FFFFF0C30C30CBC +:10566000C30C30C3CF3CF300F3CF3CF30040CF3C3E +:10567000CDCDCDCDFFFFFFF3318FFFFF0C30C30C3D +:10568000C30C30C3CF3CF300F3CF3CF30000CF3C5E +:10569000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9F +:1056A000C30C30C3CF3CF300F3CF3CF30001CF3C3D +:1056B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C2B +:1056C000C30C30C3CF3CF300F3CF3CF30002CF3C1C +:1056D000CDCDCDCDFFFFF4061CBFFFFF0C30C305C1 +:1056E000C30C30C3CF300014F3CF3CF30004CF3CE5 +:1056F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFF +:10570000C30C30C3CF3CF300F3CF3CF30008CF3CD5 +:10571000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF6 +:10572000C30C30C3CF3CF300F3CF3CF30010CF3CAD +:10573000CDCDCDCDFFFFFFF730EFFFFF0C30C30C19 +:10574000C30C30C3CF3CF300F3CF3CF30020CF3C7D +:10575000CDCDCDCDFFFFFFF5304FFFFF0C30C30C9B +:10576000C30C30C3CF3CF300F3CF3CF30040CF3C3D +:10577000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CF1 +:10578000C30C30C3CF3CF3CCF3CF3CF30000CF3C91 +:10579000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CD1 +:1057A000C30C30C3CF3CF3CCF3CF3CF30001CF3C70 +:1057B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CB1 +:1057C000C30C30C3CF3CF3CCF3CF3CF30002CF3C4F +:1057D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C91 +:1057E000C30C30C3CF3CF3CCF3CF3CF30004CF3C2D +:1057F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C71 +:10580000C30C30C3CF3CF3CCF3CF3CF30008CF3C08 +:10581000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C50 +:10582000C30C30C3CF3CF3CCF3CF3CF30010CF3CE0 +:10583000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C30 +:10584000C30C30C3CF3CF3CCF3CF3CF30020CF3CB0 +:10585000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C10 +:10586000C30C30C3CF3CF3CCF3CF3CF30040CF3C70 +:10587000CDCDCDCDFFFFFFF3320FFFFF0C30C30CBA +:10588000C30C30C3CF3CF300F3CF3CF30000CF3C5C +:10589000CDCDCDCDFFFFFFF1310FFFFF0C30C30C9D +:1058A000C30C30C3CF3CF300F3CF3CF30001CF3C3B +:1058B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C29 +:1058C000C30C30C3CF3CF300F3CF3CF30002CF3C1A +:1058D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BF +:1058E000C30C30C3CF300014F3CF3CF30004CF3CE3 +:1058F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFD +:10590000C30C30C3CF3CF300F3CF3CF30008CF3CD3 +:10591000CDCDCDCDFFFFFF8A042FFFFF0C30C30C90 +:10592000C30C30C3CF3CC000F3CF3CF30010CF3CDE +:10593000CDCDCDCDFFFFFF9705CFFFFF0C30C30CC2 +:10594000C30C30C3CF3CC000F3CF3CF30020CF3CAE +:10595000CDCDCDCDFFFFFFF5310FFFFF0C30C30CD8 +:10596000C30C30C3CF3CF300F3CF3CF30040CF3C3B +:10597000CDCDCDCDFFFFFFF3300FFFFF0C30C30CBB +:10598000C30C30C3CF3CF300F3CF3CF30000CF3C5B +:10599000CDCDCDCDFFFFFFF1300FFFFF0C30C30C9D +:1059A000C30C30C3CF3CF300F3CF3CF30001CF3C3A +:1059B000CDCDCDCDFFFFFFF6305FFFFF0C30C30C28 +:1059C000C30C30C3CF3CF300F3CF3CF30002CF3C19 +:1059D000CDCDCDCDFFFFF4061CBFFFFF0C30C305BE +:1059E000C30C30C3CF300014F3CF3CF30004CF3CE2 +:1059F000CDCDCDCDFFFFFFF2304FFFFF0C30C30CFC +:105A0000C30C30C3CF3CF300F3CF3CF30008CF3CD2 +:105A1000CDCDCDCDFFFFFFFA302FFFFF0C30C30CF3 +:105A2000C30C30C3CF3CF300F3CF3CF30010CF3CAA +:105A3000CDCDCDCDFFFFFF97040FFFFF0C30C30C82 +:105A4000C30C30C3CF3CC000F3CF3CF30020CF3CAD +:105A5000CDCDCDCDFFFFFFF5300FFFFF0C30C30CD8 +:105A6000C30C30C3CF3CF300F3CF3CF30040CF3C3A +:105A7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEE +:105A8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8E +:105A9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCE +:105AA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6D +:105AB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAE +:105AC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4C +:105AD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8E +:105AE000C30C30C3CF3CF3CCF3CF3CF30004CF3C2A +:105AF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6E +:105B0000C30C30C3CF3CF3CCF3CF3CF30008CF3C05 +:105B1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4D +:105B2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDD +:105B3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2D +:105B4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAD +:105B5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0D +:105B6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6D +:105B7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CED +:105B8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8D +:105B9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCD +:105BA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6C +:105BB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAD +:105BC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4B +:105BD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8D +:105BE000C30C30C3CF3CF3CCF3CF3CF30004CF3C29 +:105BF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6D +:105C0000C30C30C3CF3CF3CCF3CF3CF30008CF3C04 +:105C1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4C +:105C2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDC +:105C3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2C +:105C4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAC +:105C5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0C +:105C6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6C +:105C7000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CEC +:105C8000C30C30C3CF3CF3CCF3CF3CF30000CF3C8C +:105C9000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CCC +:105CA000C30C30C3CF3CF3CCF3CF3CF30001CF3C6B +:105CB000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CAC +:105CC000C30C30C3CF3CF3CCF3CF3CF30002CF3C4A +:105CD000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C8C +:105CE000C30C30C3CF3CF3CCF3CF3CF30004CF3C28 +:105CF000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C6C +:105D0000C30C30C3CF3CF3CCF3CF3CF30008CF3C03 +:105D1000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C4B +:105D2000C30C30C3CF3CF3CCF3CF3CF30010CF3CDB +:105D3000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C2B +:105D4000C30C30C3CF3CF3CCF3CF3CF30020CF3CAB +:105D5000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C0B +:105D6000C30C30C3CF3CF3CCF3CF3CF30040CF3C6B +:105D7000CDCDCDCD000C0000000700C00002813069 +:105D8000000B81580002021000010230000F024097 +:105D900000010330000C0000000800C00002814038 +:105DA000000B81680002022000010240000702503F +:105DB000000202C000100000000801000002818003 +:105DC000000B81A80002026000018280000E829810 +:105DD0000008038000028000000B8028000200E021 +:105DE000000101000000811000000118CCCCCCCCD7 +:105DF000CCCCCCCCCCCCCCCCCCCCCCCC00002000F3 +:105E0000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCD2 +:105E100000002000CCCCCCCCCCCCCCCCCCCCCCCCD2 +:105E2000CCCCCCCC00002000000000000000000022 +:105E30001F8B080000000000000BFB51CFC0F003D7 +:105E40008A5B591918EC39107C7AE0A58C94E95FCB +:105E5000C3CCC0B019882F00F12E66D2F57F9642D0 +:105E6000B0CF483030BC03E29D620C0C2B2411E211 +:105E7000D1D20C0CFF81FCD350313BA09EDD52945B +:105E8000B97B140F0E7C471D957F5C15428740C57A +:105E9000EFA2C99F80CACF5780D0F7D4B19BBB0077 +:105EA0002A0F0001FE3753600300000000000000CD +:105EB0001F8B080000000000000BED7D0B7454D513 +:105EC000B9F037E735672633939390C704123C83C4 +:105ED00001820618303C54AA93F068E8A53A3C04C5 +:105EE000E447195034822411D39AB6FC7F4EC8E49B +:105EF0000102C617A52DDA81E2BDD185BDD1466B61 +:105F0000FB6B5710A5B9B5772DA4A8B4451BD06B72 +:105F1000C10237DA72A1FFB2977F7F7BEF939C7348 +:105F20003293876257EF6AC3D2937DCE7E7CFB7B30 +:105F3000EDEF754E141803CA8D0097F0875CD7B942 +:105F40000020BBEF6ADE073556095900154145DFD1 +:105F50004A9EAD17237A7D09B97F85107E0AF0FE2F +:105F6000B839300940C671790053F17FD300A4CC11 +:105F7000969C988FDC1357A6E3D59CCFBC5648005F +:105F8000DA547CBE6D5CB2E7BDEB27E49E6E15E88B +:105F9000CFA53100B5C76F9DFF9AD926FF8D027F2F +:105FA000D68757935F66C08C4B22C027F98BD23BB4 +:105FB000F5D4F37D54D7A54963012ED42D9FFFDA84 +:105FC000D8FECFD78B50DD5EDCFFFE75A052BC80C3 +:105FD0006A28D1897DFB5E0FD0E9CE0468CEDFCC84 +:105FE000F69B4590752DB9DFF66F9A54D407E77A82 +:105FF00089F49BDA7F3F00069DD79CA7777CA2CBD4 +:1060000036DE39AE773E3E1E24F26F3A00ED42F6A0 +:106010003FCD15BB11EFBBF3171923497BFDFE5292 +:106020008815A786BF975E9F117E735C4A3AF27E01 +:106030009FEC6B6822AC071F2AAD375D47F8E8F785 +:10604000CF89E1CDC847BBC7CF8100B90F8C8F4C3A +:106050003A9DDED790938C3F52D1E97F8387F29FA0 +:10606000C95F15C2CAF44EF8ECFC7537F2579A8531 +:10607000BFDA170F38DF67E5AFB893BF383ECEB44D +:10608000B3FDC3AE118C2E9C5E4EFAA4A4CB671D4B +:10609000D79F9FB6205EDDED8B8D9190849F38BC9D +:1060A00026BD3E2FBC83F111402BA5334054C4F5CF +:1060B000FBEEB3ABB7447381409B87711F23F83E5F +:1060C00046C49AEE13089C7E682D1F1722EDEED56C +:1060D0000B500EFCC7E79FC66B6371595719E997C0 +:1060E0001ED616CE23576F11B8709F5B70B2EB703F +:1060F000BE4AA3B418E905B4FD8C7147C4403C40C6 +:10610000042007E06B7C4F00822E91B682BF8E493F +:10611000B60F053A193E5C97DCFDC7A7DABFD23748 +:106120000E2E85F0FF1B01F737D8385840C6A988D6 +:106130000E83E23BC3314F7A843D37E9E3074B9B43 +:106140003C3F8ABF507CDFF757594F8347549DA887 +:1061500014A550D012D81FB40C89B4BD7388222264 +:10616000678D16EC31047D70BA340294B7FB28C3F6 +:10617000C1427F1F7CA7C145F7135C130F3591798E +:10618000CF97F8C2943F34F2DFD4FEFB79B00E19FA +:10619000D9D22EDE0BC8E771C24763C878A3989C9A +:1061A00087084FE1F39A555FA5B95C9C2F9DFC01D0 +:1061B000BA341DC50C59855C0B858827F0F9F94365 +:1061C00072E071A8FC91B6C0421F183EBD82DC6E21 +:1061D000182A7F7CDEF54CBAF697AB7A4ED71A15A3 +:1061E0007C782E2F4A6A7FA4A6EB2394AEDE4288E9 +:1061F0002492E8E902978BCB8161D337F44AE823F4 +:10620000F692F77E1BBDC4DCE9CBF70C800F31CBD7 +:106210008E0F735E4FADA87F80CA4BD2049C4FC1D6 +:10622000F990CF828F1840CECFF3C8DB041F62EB0A +:10623000944E6C432150BB8CFC74BA48DB138C2405 +:10624000B68618FF235D4CF8DCBA60C3AF94E5B5A1 +:10625000B561B9E1B2C2EFA955281C0AB511C83C15 +:106260001A9990A042F24127F2ADC9AFC80697AE85 +:10627000C4F6B76C7CD0A24F85647430F915D1CACE +:10628000F8F55B43D32FCEF596D8E11DF2389FA4E5 +:106290007F683987528F93E043933E048915388194 +:1062A000850F9A6578C93519A0217F29C4C8DD6694 +:1062B0007C44CEB126BCE6211F4ED5E879D9E692C2 +:1062C000104EF35C856026ED37CDA5D3F904B59A61 +:1062D0009EABA22FC2CE57FE3C355C6CFD1CBD357B +:1062E000A211FCE6426B4420F4914A20DC09A84745 +:1062F00023807C0061C61722B7D3CDF171CECF1EAB +:10630000384AC713ED6A68F43CB3CBF15C913C2486 +:10631000F36C2982849BD2A955C5B6542401FA0591 +:10632000443FF9F2A6A39EE63FE28230C29F8EE789 +:106330002BF2C72CCEDF2EA2CF089E7D2576F9F654 +:106340003AE45FE2E7713F7D96C29F30AF4EFBEDCE +:10635000FB2E6EBFA5818FD29B8F075F727BD5B45A +:10636000DB4CBC660B40F109BF90134F85F8DE484B +:106370007BE3BB1909DCB751165DDD48F0609C7406 +:10638000851B909E52A4279D3CFFF09F45EA2F65F8 +:106390002FADBD02D7DB5E678C2DB4D883DB25CD56 +:1063A0008B78DE139FAAC62C7AE66688BDE8B2F821 +:1063B0005FA160D3D8C26B28FF9DEC2EC2A3C2455B +:1063C000F9CFE38B075F47B9E4F77BF1636D8BFD92 +:1063D000DB59B9C0CE4BB8A93442D66D41DD3592F8 +:1063E0003E365C04CE963CD6FE797D4E299E9F2D8E +:1063F0007ED6FEA4FEFD483DE58B981A25F76A81FE +:10640000E3A58BE085D25FCF5D3831355D9CFBDF46 +:10641000211DF6E0FE9FF01D993F1ECFCF99421837 +:10642000D1FE44CD116DB5051F2DEEB2B7111FA3DE +:1064300020E102A45F3C8BCA4F107A7F22D8CEE3C2 +:10644000F2940F8769BFD1D19E52196F2DD75EC5C7 +:106450006B53F0F90C2A4F3047FB90CABFE8BA746F +:10646000F5D0E53DD57E032E8826B3E7378A9954CB +:10647000AE022564DF36BD9EAF517EE4F37E0D692A +:1064800044F6B72783C04484678FDCBA3C9A84BF44 +:106490007FEE1268BF787C5E742DE533761E8CE645 +:1064A000E741E3E2DBC3C80F50A8E7227D242D4675 +:1064B000F5AD84E707E11F398BE915498DB48C27C9 +:1064C000FC1A3A2A8241C6855A33CA54D40F1A504C +:1064D000FB05D1B96422DB2F9EAF6EC2712897995C +:1064E000E47AC9B26F087AFBE4750CAEA3D0752EBE +:1064F00003BDB3846983D37924B497E261968ADEBD +:10650000979BCEA9C63BE91B7031F9DAD87021629E +:1065100010FC351D7709222AC5D6424A2F95EBA6D5 +:106520000B724C45BB71CBD704D84BF130B09D12E8 +:1065300077D82992168DB8C8F89115DA5464A15409 +:10654000E3765608E58924F3960B4CEF6FA978A4FF +:1065500095AABBD7ECFE9EBC3242ED52E2F79523E2 +:106560003DCC719E42C647B08FEC87F49739FF5DF2 +:10657000C85E940E49E4C0BC7E0FE11FDFD71EC584 +:10658000F9CBD9AF5AE4F6D5636C7ED3DEB9903738 +:10659000F0FC267E2E960B7018E1937A3C40E53D88 +:1065A0009BDA61A3391349B5846FC8BA3274D7E353 +:1065B00079B753808AF662BE69D2CFCDE9F3FDFC8C +:1065C0004F3CD8EF3651A0F08C8AF46C41BD3F6A45 +:1065D0009300E88F548A3ABD9FBBB2FA804CEEB765 +:1065E0003442D8A7E33A6CDE96031E7A5E2A5990AD +:1065F000F090FE8742399B915EEE3844DCA49FFB0D +:106600005E2272D82E84844E9ECBB53103E19582F2 +:1066100051746FE060E82EB59BFA2D60E39BA64DA8 +:106620001B55ECD7AC6FEC0AA1DF522851BF45D106 +:10663000AA23945D3F25F830FD0A2217A138740A79 +:106640002554CF277CB483CAE8A67139DA350B3AD2 +:1066500089DCB6647CBD13E133A601954BB403D04D +:10666000340089D813647CFC4E2DBC15F922CB7004 +:1066700059F97437C4B659F943D2DA297FB4FC45C5 +:106680005C9E4C2FDE2B307C5673BD77414ECC4741 +:10669000BC6EA92772E0EADFFF7A8EFFEF1A8B6EDD +:1066A0001E4FF5133B7FCCE75D2EDD16AF1C7951F5 +:1066B000A1FB71DA2FF3B8FDD2944FEC178A07587B +:1066C00080F64A1A277D5318E8737706240C428F08 +:1066D000341E178062667FA8E41FEAB9DCE576BB4A +:1066E000C5EDB04F52D92DDF7445DBA95E232A09D1 +:1066F000E1DFE56A9D3F0EF19DC7FC46E7BEBBB8F2 +:10670000DF3857DC166A22703D992584DD7A1F3FF9 +:106710001470B978128C1397C83C7BF2059D58C051 +:10672000B0A746A0F6C9799DD9E7F08187F6BF8268 +:10673000C3D2B86911F58B7AF532979B6D75AA4D66 +:10674000BF38AF3EA53596EC5CF273FAA4CD8AD083 +:1067500038872F9CA0E70EEE33993DFE6071993A81 +:10676000909E938A94D5147FF965A725BCCE74FAC0 +:1067700045C9E7755EC16A4F8AA9FB0DF5BA85E088 +:10678000E9A46C9D3FAAE239E121E728CA85274C9C +:106790008EA4005EB51C84DF130EFBE8B5BBB49C71 +:1067A000DD8F6EC5AB3AABE7F06CEAA74994EE7BA0 +:1067B0005462075AF031490C517CF6E2B750B0ED03 +:1067C0005F95AACB914FD57C01904FD5D8D7BB2EE2 +:1067D000E17C84FE6343C9F848E2FEA99D6FF69010 +:1067E000F30606A0C3E7E58B5F08A69F6CA717FD1D +:1067F000B1C63D389D7BE9DF2F7EF1B7416F75163D +:10680000A137E299D09BF9D7DA569433292E50FF5D +:10681000C7EC77411863A39F74916852E237EF2A5F +:1068200085A4FAF082A0D0FE443F94882CEEEAC200 +:1068300078E65C71533930B906F4B754E22F50BA98 +:1068400093F550CE9B3FAD5311EF6A4CA1F679976B +:10685000ABAEB45E1A8E9E6470C16E66978C32CFFA +:10686000D90D433B672F9043829DB3D5F43C92BA38 +:10687000ABD55202EF15F7B2F3116DB04CD21E4DED +:10688000CEB7CE501FFF85F83A7271EBE17149CE59 +:10689000A3EFC53F39E046FD950FEC5CAB6D8FA0D3 +:1068A0005EF1E777E2B6F1BC5921127CE5151AA535 +:1068B000B8A591BBE6D17D7C57022A47177061824B +:1068C0008F9D9B9FA8376611B98B443B0511FD62D4 +:1068D000A07A91D8B9DCAEB3AFFBFD4D4204F1EB29 +:1068E000C910F6A008FAEFED34DC16BD4CD6BD0792 +:1068F000D735CFBFBCC276C0F59D76414A7BE02F2D +:1069000022F7B3A6D7A3DF950F0CCE873727EAD19E +:106910004E2C7547EEA7F477F807BDF1251EC75E2C +:1069200033D314227DD96FC93AF774C9B0159B9F30 +:1069300092DE96F8CE3D780E117DB3869F63774246 +:1069400034800FCF8240E36667E148E01A0B9D1F59 +:106950001215B64E8B7CB2DB12B75DDBCADAA6FE2F +:10696000B97B97BD7D172CCA9108DEEE7A4C460F95 +:106970000DEE71F8A375A246F9FB6EA86E423C3489 +:10698000CA4C0ED668208D202ED2861F3F311DEDB9 +:10699000FF9D22F36F3E22FCA55BF4CD3A5F42419E +:1069A0007CBDDF71CDD2EB01C7279A46A2BF9D0106 +:1069B00049CFCD3B5AECF00D06BF135E80CD14DEFF +:1069C0005470486DAE48327B7A9F69B7727AD5AA07 +:1069D0008149180CB9E06157A30CA87D61BCE74957 +:1069E0003490750E70FB9158429359FEA27A065E60 +:1069F000071B7748D4B93E1FDEB83752ACB741ED1C +:106A00005690FFAB24A3DC25F4C5A154B93A328AD1 +:106A10006C497EA9B493D8EAD67E2D43EC572E0C50 +:106A2000D0CF09EF694D3584C9FDE1BE1962C75069 +:106A30002E2E08B14AEAFF73B8DD886711AF12A5A0 +:106A4000278D8B84705D5F0BFAD11E5F07B5473CC5 +:106A5000BA64A37795A9078A80C673D28AECCF9DC2 +:106A6000F1923F8866FCBE93CA170D75922D0554AE +:106A70005FA788F6E14CE94C6F7FB25E25EE6B3282 +:106A8000ED44F54B0DD72F95A03F34AB84CA178D3D +:106A9000C3D5CC1F63201C35D97A18FD7009C211EB +:106AA0003A8783AFAA2EBA2061F1ABABA41E05E5ED +:106AB000A88AE86FEBFD8D4116274EA5B765507586 +:106AC0005F11DAB102C593A891B665DF9FB4BACA67 +:106AD000B91F94BE64007F776390C581D76C199B02 +:106AE000CEE229767D758E9F0F3FDFFF0305FD9770 +:106AF000B3CF9CB809F7B9FEFF8AA09275CFEDF726 +:106B000043273D37120A9E1BEB3AC4A471768006D8 +:106B10009617FF573FA5D7BAE7DD890564FCBA177A +:106B2000DF9F0404BE739B7B0E8D42FBF919178B0C +:106B3000771BDD931693FBEB2458154D325FA1C4F0 +:106B4000ECD4333F495B8EF2EB6A3B703B9DB77DE3 +:106B500099ECB69CDFA32499AE4BFA45F0B9F1B499 +:106B60002B3136895F62E619CE3CED62F0BD2453CD +:106B70003F6F5DDB1E2546E0A86AFB98EA8BD9FFD4 +:106B8000FA6C00F150F59268B3E3AADAC44EF72428 +:106B90007A3D81578C9FBAA6239F707EE9D840E347 +:106BA000A695ED0F7E2C0670BC5D6F11BC843B1169 +:106BB000AFEF88E105D8FED1BF047482AA8F0E3FE3 +:106BC0001540BC9279572BE9189FB7F337CE7F3128 +:106BD000B3FF7C003D348F5BD5BE85ADE7D08B1F06 +:106BE000E12F79FDE3ABFF24D9F3E3D036B4FCED1C +:106BF000FA67CF3F6990F5CE3CFF87270D02F7BDBE +:106C0000FFFDC727BF8572F9338F867ABDEA99B732 +:106C10000260E1C3B512D3AFE70A88CB44FA9DFB0B +:106C2000B53B8106C1B9577E3F5A27FB3DF7DC9F34 +:106C30007374D2BFE695B9B9B8FF9A1766E70E64C8 +:106C4000DF229F26DC56B812747EFD251733165EB0 +:106C5000E657075D0E761C1C8D709E3DE60E635A4E +:106C6000AE8ADCAB9D8A74DA40CF596C6F22F8ADE6 +:106C7000DCDFFC31EA87FE7836460934A845D4606B +:106C800010E9FCFE3C4A2FE8A1E7A3B37FD55142AF +:106C9000C7C9A9E9761E3E5550CF55EDDFC2D67360 +:106CA000D0ED2CFE726D7FBA6D76D0ED3CDCFBFD35 +:106CB0003CCC97778CB0E5077AEDD4DEB878343DDC +:106CC0003A807E30E57F30BCD2FC09812B2A451EFC +:106CD00091508E9E4FEBA5EB02A4EBB3E74703E187 +:106CE0008B5372CFED781EF4BCE2D6303EB0EE95F9 +:106CF00077A85C9D7BE14D45A7E718F85CC4AE3CE6 +:106D000007BD3F87D1CEAC643E3E54EDF377BA0366 +:106D10007DF4A94C2C2CD703F4FE097A3FC1F8BDB1 +:106D2000327160892B09BD7E298D61FA3F914DF149 +:106D3000B261DF6F15F0D9E9E89A89743C310FEF41 +:106D4000A7A2A3B97F0DF73FC342CF7D4C4E9DFD57 +:106D50002B893CE279D74BD784EB1D482297E7F685 +:106D6000B8253CEFCEA15D95341FCAEC99E1E64D04 +:106D70000E39E5DACC9B703CA4E60F26DF83ED6F7D +:106D8000B8F8EB90741B1F99783CF369727D7F9281 +:106D9000EB8B4A30CA475ED9DF0E91206A8C0AF528 +:106DA000C17B061D52C27F679E1169FCA7A9FD2009 +:106DB000D5DB4E3D518971CB24EBFDD15CEFA503B2 +:106DC00093509F9D79F527943F2BF79F50D0BE3F5E +:106DD000D4F623A5BBB84F1EF03C4858CE83333FB2 +:106DE0003C3089E981E471515A6047E0AC7AD93E80 +:106DF0007FD5FE8F6DF3AF37DAA97D30D83A1F49C2 +:106E00009165B8DF8F0ECBD49FFCA85D4C1A27FE8E +:106E10000F3C0F2D766DD39BF37E8BF9AD92235EE5 +:106E20001DCFCD8ECD91DCED68AF1D9181E60FA415 +:106E3000C81FDCA4DDF1A657C7BC73C791A5A26E1D +:106E4000F1437FECC0E78CA3C66C3F996F4637F1E6 +:106E50007FF5FE7A63E671E25759F8A0E6CDF25C61 +:106E6000D4F7E887EAE371BD7010FD5C3130AF9C68 +:106E7000E5A505CD93F4BC66F3C9BE288D4FC99A2C +:106E800000BA65DE5190A8C73C3AF87CCEBC4354AA +:106E9000B5E697961F3E802E66D6E297F3709E0069 +:106EA000C4B50FA9FD09E14B03D85FCE3C8389CF60 +:106EB0005EF94B917748D36E0F1E80FEF3F5CFAF8E +:106EC000C454CCAF34F9D6B4842CF995A660BFFC79 +:106ED0004A4426786871258F478C91CBE6E073E2AF +:106EE0001DC7923D5F2E333EBF11BAEF5F8D7046D6 +:106EF000599E6696035F5FE2F8FAD964B271A242C6 +:106F00004B41976482DFD94B227199DC9FBBB2E77A +:106F1000EA5769779EA731C60B97D2868EBFE1E606 +:106F2000E34ADD8B56CBD983E7E352E585FBE030BE +:106F3000B83F9E69CB4F1C7CF7011AAF97A1BA25C9 +:106F4000648913E5747A208271FE2C9DDA87399D5D +:106F5000F77C672DC699B3F2C31EE83F8F74F17AB0 +:106F60001ACF30F3F4527E84C6E5254D2F15E93A49 +:106F7000CB2298CF6FD681DA1FCDC181E33553E4A0 +:106F80009881F4942EDE40E715545E5730C47D7E20 +:106F90007B7180E23940F08CF24EFD1FDCDF71170F +:106FA000CF87771B22E6C34F64D0FC404082228CFF +:106FB000075C7079C39B43D02F1F9E8A7FB74B8697 +:106FC0004AE3247ABF7CF82ED9124F53311F4E8BDF +:106FD000F9ECF970D557137C5D47FFC662EF86FA6E +:106FE000FAF5C99D231F8E73615CC6689E8D764538 +:106FF0007306F0FC38CB8737F37CF8B38DD366A3E8 +:107000009E6DF698CF67B0FE66DBF8F5AB111FAD4D +:1070100003A1EDD372CF66EC9F350AAA69FD9914DE +:10702000855B2C7AF0B82CB13A5539F2BC6CAD279F +:10703000E2FC60E67B0EBEFB7BCA57781D8374279B +:107040007C8571A99CCED360D5ABE6D5E49F667DE7 +:10705000E0F8AE7C710ACD9398ED40562C1249C2EF +:107060004757BAD9B963F271200809D4AF8199B1F1 +:10707000EFAC45BE0EFAC26914CE07689DC90E0D6D +:10708000749AA770EC6387BE91F2EDF92CC2E516F5 +:1070900079E90FFF0D1C7EE61F9FD7781C306840F2 +:1070A0002C097CF2C512BA8F2972E4B7563C665D92 +:1070B00091BCCEF60E85EDA731BA92E5D12BEC79D5 +:1070C0004F4C335BE3A6D35CB153A837CCFCB9A0DB +:1070D00046797EC330E3EAC1DE78B68EF580F71AD2 +:1070E000A8DFE495ED860BAF592C1F22AAB18FAD16 +:1070F0007C2C69DD4C0E1DF9BDB9E2198A971D8300 +:10710000D06F5B1DCBA76EADD3A8BDBDA52E48DB50 +:10711000CD753ABD36D545E8FDFEFCF4F3E01DC85B +:10712000473E2FCD270DC6270FD585E97CF1BA99AB +:107130006C5E97C9EFEE06E4774530E5C74FDB3E5E +:10714000D1948F2CDADEEE62CFAF514653F931F98C +:1071500079B0FD8989E994AEC39D3FE57E67F986E4 +:10716000B4DFF44EB6EE50D7713BD6D9314BA57A89 +:107170007947FE20EBB4B27506879FE16BDB81D3C4 +:10718000B45EC04DE4DF43F6E1D62249E5C1949FE9 +:10719000FEF3B8A9DE6ECE62F94FB9D0174165DEB5 +:1071A000ACF37C21916BB47FE4A29C32BC2F87AFFF +:1071B000A2F5DC72B18FE6E3E4C29C3BB0BDEDC04A +:1071C00016AD8CEA01819E5FB5D00D58974BC486F1 +:1071D000C663E5C2A2B5D85F43B9247064BA99FF0B +:1071E00024175E77378E3F30E590DE9085E716E313 +:1071F0003FE8966CFCEF94FB94FA2B68AF5F04E9D0 +:107200004E40BF74DB94BB8AA87CAA967AC62475CC +:107210007DA63E217A638D62A9E354608E8179D385 +:107220009DB7DE154EE62F91F3749D92DD7F1E73A0 +:107230007C851CDDA0B0BA74B0D7A527CF4737072F +:10724000CD7C74B58AE7A814ECADA75B9047F0C27B +:1072500052A9D05B4FE733EBE9C22CDFD54AFE25BC +:10726000CB4B3BEBC42F573DDD16A5B79EAE00EBD5 +:10727000E97E2A43B813F3EA6F89E1BD7A7FBE73D2 +:10728000CEE77C2FC23C0752C965A762CF87E6C50F +:10729000ECF950B8D3635BEF359497E2C1F5CBA816 +:1072A0000AFB3C05D5F6FAD72B6A336DED9031D247 +:1072B000D6FFCA9631B6E7635BAFB23D1FBF6BAA7C +:1072C000AD3D21719DADFFD56D65B6F6C4F6AFD865 +:1072D000FA4F7E6991AD3DA57385ADFF355D6B6C51 +:1072E000CFA71D5E677B3EE3D8465BFBDAEE6FDA25 +:1072F000FAD712F34641B9CDE2F5C259B98235CF7A +:10730000DA924DCE25E2B7EFC8260C43E3D9ACFEA6 +:107310004A618F7BF380CE7192AE44349AB71F37A7 +:1073200007AF20D5D0F354D273CA747A7FFA3CBC2D +:107330004289BD0E56D1591D31FA65F67CBFBD1E7E +:107340005811B7D1B206F7F12F77B926F5A7AB924E +:107350006F9783A1D613CBBA63DC30E5E28C291793 +:1073600005442E683CED5311FD1E98E3A7F685C534 +:107370003FA27834FDA31B5488A3C968CA45E9CA53 +:107380009E51B48EAFD72F720BC3A95F33E52F6028 +:10739000D1FB91AC3E3DD33C7368FA554C5C63B372 +:1073A0000F9DD786C0BA54FA31E01E403F4E91A3DC +:1073B000196EF42FA5880196F80B54CB36B8870ABE +:1073C000E7673D07561386B3EA15134E85E86DCC83 +:1073D0002B352DBE893AF55003363ECD591EA5FEFC +:1073E00009B10BAF76DBC633FBF06FCD4EFE8D6C73 +:1073F000DFA7692F9B780F84C2B49E04F204407FFC +:10740000AE69562C88F1B416EC62F10F1F705F491B +:10741000E7690C2A02D6B93776B1387B835ACDE2B8 +:107420000E72358DBF34640B5AB23AAE3BDD2CBFC1 +:107430002BD63E3876DF007C252AC9E30E0D7C7CF6 +:10744000C3816F74B17352D1D19F06E234BE6FC94C +:10745000BF8970381A72E13A3BE83A010E57A040F2 +:1074600080FAD0E070DECCFD1DA976CB80704A0892 +:107470006712BA9870C611CE92D470FAB3CB687EF8 +:1074800052AADD46D731F1BACACDE8E584DBC4B7EC +:107490000C91F2D9D83EF1E5284D8712B223BFEF07 +:1074A00098C9FC66A2D86DFC6AFA2D845FEB915FE7 +:1074B000258DF92FE6FB055F716B0CAF9C8EA067E5 +:1074C000D2B8432016A775E7FE18F3B7FBF40DE317 +:1074D0001BBF1C01EC2FF9049ABF5378BCC2ECF718 +:1074E0009E9BC5891A667547711FCDD74AB019F59D +:1074F0000FD63763FC2E9FED378EFB22F0FCCC9D20 +:10750000C1F891AFEB8525E9B41052DC1F1C480F80 +:107510007B117F23FAEBE327DDFCBDE03CC863FA77 +:10752000B87819E6A353CDE3B44BCCFAE7E1D7B56D +:1075300057D33846B36F6317C681CC381C044B92BF +:10754000C6CDFBF0CAF2897DF45DA67712FA49D365 +:10755000A6523E69CEE7F4AD76D4E99A75DD9CAECD +:10756000669C1B822CBE63D2D9D38BCFDD03E2D3C2 +:10757000C3E5C689CFAEFFA1F8FC11DA28E4EAF72B +:10758000B3F7C2E1E03780E68DF2EDF2688E33F9B1 +:10759000DDB9FF536E7EBEFF0FDDBFC90FA9FB1B18 +:1075A00049FD1433FFE9E7FCA6E2DB4D44F1BC3EA4 +:1075B000F364CB955978FE32BFDA3F334EDFAB959B +:1075C000C1D0502FF8CDFAD912FB7BA0DE62BB9D53 +:1075D000A53AFC1185D72DF57BCF95DB63CEF797C8 +:1075E0007AF1EBA0D7683545FE6A88EFFDECE4F947 +:1075F000B4BC9AD67AF46FF3EE6475F6BB65588521 +:107600007577232B0CC19B85F995D0736964FF793D +:107610002F3F5C3F0A4972A71E42B3E17BAA6E8BE3 +:10762000EFE7DDDB5AEA65CFA7E03CBB54A677F372 +:10763000CA5B693D59C30BE3D3D16F79EDDD651AA0 +:107640009EF79F6415D2B8EED917DD11CCEF9DCD12 +:10765000840A5AB7F5E28C436897FFA1AE2B53B268 +:10766000F0C9D91FBE395D26443AFBFC9BD3254A9D +:10767000AC84EDDCDF70E957D3116EA30C8AAA311C +:10768000BFA629F47D932A95E5B3CC7A9C9D394A0F +:10769000135E7FE261FA382757D881ED5A0C70A14A +:1076A0009DC0E3EDD79FD197613D644697ECC27AC8 +:1076B000B9875D86E123D70B271EA6EF5D2B9DD5ED +:1076C000183621F7C30711E5C658E6675C08415133 +:1076D00088E87DEFE1EAF1D43E76D42399FC2FCD02 +:1076E000061A97E8B9554DEC0D617C58FFF64AB281 +:1076F0005EC34A89D6CB6C970EAB5A123DF68667AD +:107700008C0DEF7E1E2F3EF8EEDDADA564FCC62984 +:10771000AC8EDA77624A3A2491DFED7533E9FA816B +:10772000BC93E5A508D6A7E4EEF43EBFC727819138 +:107730004E8E4839241832C18B6F26C0490BDF3575 +:107740000910D1C8F317EB80CED351A7D26B5B9D44 +:1077500036B69018FADFAD0BD2EB63753ABD3E52E8 +:1077600057449F3F5417B6C93DAE77B288B743A977 +:10777000E5F6725FF17DD8931638764E24524FE8C5 +:10778000B593E78B1E2C9E9ABE66807CC3EEBAAE84 +:107790001173C6726411FAE5D7687BB60E00FFEE6E +:1077A0007AD7AA459837B94F8AEEA5FA3196B7C865 +:1077B000A21F1BE5581E1056BC5FC99C33278FCAF9 +:1077C00023959792C331C03A9BBC60AB0BE3D6794B +:1077D00047D97DF3FD074A2F22683FCE9AE39251A5 +:1077E0006F16433B82A514C7A08CF49F91BDA414CF +:1077F000EFC344FBFDE90A936F9CB78C5CA7AAD149 +:107800003615EDA6CC5DC6B3643F7FEA70EB988772 +:1078100079E8D53F2B187F8FFF5A51D18EC97BF95C +:1078200004AD4B88BBBA156292C11B2D6BE748446F +:10783000CFC4793E802A16C22771D4B1349EF9FB99 +:10784000F89C627CFF2476DADA7FA737761FB65180 +:10785000F1AA41C2471EB3FF9A78249FB4797DEB09 +:107860001B2DABE3066D93FE53583B4EC6BF9811DC +:107870001B25107CF9EA57C5BBBE846DB3FFAA383F +:10788000D6C31E52593D26F8622194B7DEB646DAB9 +:107890007E4B5B626D50D9D5DCEF86837F3E847A68 +:1078A000AEF265573B8246F41EC3FF4B0FD3EF2465 +:1078B000B4D575697199D3DFA40311C90941A07EBC +:1078C0008A927025C610FD31817F1722AF24A2D77E +:1078D000A37E4DC861D49B577899DD382141E6B12C +:1078E000C8D58414DF1FA17959A4E33656D7DB8F9E +:1078F000BF3CCC9EAF05632BFA0DB05FD668BE903F +:10790000C71DCF98E71CF73FEFF5B0A6BCD9F05ED6 +:1079100085FA67B544E35AEB43ADA50A5967FD4FB5 +:10792000426172B242A387D51DACCF68CF994AF8A5 +:10793000A431C3DE7E98D7B906338C8CCC62AC0BF5 +:10794000787834E6ED2BA1F5F66F22BCBF64F9C15F +:10795000D307AE4DBF9EB437FC92C5753774BCA932 +:10796000C4483FC1C3EB093AA67C05F757B94D009F +:1079700021C4E433329EE039D27A9544F864A27788 +:10798000C45C4F01C0D363229A40F860FED68246A1 +:1079900015DB8A3601E566FED6C246E4ABF513CDAB +:1079A000EF2414BE1E29E4F54C23719D07E21877DD +:1079B000DEB7A2FC2B78CCE6084C6E0923D2FC9EE5 +:1079C0009811A779A7FF6C14685C1B53EE9BA66205 +:1079D0003D1D7449E4BA5361F4339AD8FB0CE47E3C +:1079E0008B3C15E9C2DE1B228E24D5FB635F76D368 +:1079F00038726175E41E6A1768C592F5BD2CE0798E +:107A0000E32BF03732CF780D4AF1BD80A73D2CFE35 +:107A100057B87CE97A1C27FA977851CE73C4844111 +:107A2000E7FF1E8B3BEF1412EDF81EA31128A4F400 +:107A3000DD19607C613C524CF9629F5076D57D84A3 +:107A40000E8DAED55BFF0DE99A51084857BCBF912A +:107A5000DCDFC7E929668435A4DF3E4ECF784230AB +:107A6000B07EC5BCFFA26BCD3D286FB76ED93F4736 +:107A70002578CD71475A47103A2CDFB23F1EBC968D +:107A8000D2618C4AF0BEDCB33F8E74D8571F19A95F +:107A900059DAE3FF42AC115A07BE9FCAB394F1C84A +:107AA0003A9477F2FC3595F0E9D399A6BE60CF0BF6 +:107AB000C7F4EA8F0890B346ACEFD3272A391F0AE0 +:107AC0002DFDE710F9FEE727599DF997C87A28EFB1 +:107AD000641F343FDB33414AA0BFEB25B0A0DDE299 +:107AE0009D3886D6CF917D03DA253D13257ACE9A2F +:107AF0007169F70481BEE78DFD911FBC05AC3F1194 +:107B00009428EA4D295F02D4EB92B83B3241C7700A +:107B100030CBBBBAB485F43D514F9125CF0A7D756A +:107B2000BAB41DA29F97B1B5C7BABBF3046257663A +:107B30001D5FE81A4DE65BEAE1FE4616B1B7C9FDE6 +:107B4000151E662F3D1035BE8C210DD0BBF3A87ECF +:107B500082E854BCE6DE56989B2C1FD277AE3BEDF4 +:107B6000EA6E6A3FECF009E5C9EA4F0BBD3CDEE086 +:107B70003B42BFE7510B44FE512ECCF764B9FE30B7 +:107B8000DF1F70D6FB9AFA44CE607BAC995F968B70 +:107B90007A40E2F5439216D6B0FEB1D45F42EDBE14 +:107BA000C7B99E120F5C7B33BE47A1A03E00D45FD5 +:107BB0003103F3FF3D79D08EFC2A052360CDD39AA3 +:107BC000FAA0A94EA5D7A7A68E2B4339796A6A4E8B +:107BD000994664E0E0A49F7661DEE8FC6E26BFE78C +:107BE0000FAF35687CC960F122642B1A67EC7C9476 +:107BF000BE27FB0329FA10AD7BC5FA0502D2B60CED +:107C00007B7DD5082FABA3ADE2F036CAEC79731DAE +:107C10008B072B17AFA671A9F3FCB93B76277DAF75 +:107C2000C24DCE327CCF5105C360DF196078C0F7FA +:107C3000986C798B8B93E8F82A0FC3BF59CFE1ACCE +:107C4000DB30E119CBE1E9FFDE849D1EA6FF65D2A2 +:107C5000C11C5FE38AE46A03F04DD545111296F822 +:107C6000475FFDB542EF9FC3BAF574ACB389B55E0B +:107C70001F42394850FFC8E3AB01E0DF35A27C1A50 +:107C8000947AAC75E2698EBAF57EF2A2DBDBCEBAED +:107C90008515C81CD3981EA7F5A6127CC745E87D9C +:107CA00036EDBDE968D75611F5A062804832345CE4 +:107CB000FF1CB7F7A597EF8B8CD2FBF663C60BCCF6 +:107CC00076E54B0B691CA16A9F8FD6E357A2FE9BFA +:107CD0008C75FD4697DB56CF1FE9C4FA39F9253676 +:107CE000DFE31C9E3F691579B8EF37B8FF9323C4D3 +:107CF00044F652CA618A87B827720C34A6CF24C2D0 +:107D00001371B3DEC2581B478761A702367B69A790 +:107D100097B5FF73CBDA789C9DB3DC9EF984DA3F8C +:107D20008D1EB37D96EABB9D4A6B27EA3BE345B7C0 +:107D30008EE717194FDF93365614D173201E8291A8 +:107D40008887D73214AAE7E22FB8F7A29E9BAAC66B +:107D50000EA916BFE16CC6DBA3D1FF4A329F619B1F +:107D6000AF6078F391F53B10AFE6F3D73276768AC1 +:107D70006C9C4EBFAB917F78F46AD2CE79D14DDF47 +:107D8000EB31FD4D275F2A5E265F4D8EF7F314948D +:107D9000371FEADB6A2A67EEA03DAF65CA9D7271A4 +:107DA000822DBEFF383F67152986A14AF2BC983E56 +:107DB000AFE2746DE27506A9D7C94CB1CE35549EB9 +:107DC00053AF339DCB3B703996B4DEEFB10CF01E50 +:107DD0009F33EFE1D453BDF2CAF5D0169C1FE3BA2E +:107DE000101BE325D77589F6795E3A3A3609EDE03E +:107DF0005F737FBCA8EDE157F1786E7147EEF24CEE +:107E0000A3EF657D17AFC39587F95EE0F1947E7AA5 +:107E100088D95777327BB566FE546ADFD56C1FA3CD +:107E20001903F8491517D36C7A48F0E8FC3B77063C +:107E3000D547151703F4F9E55BCF637BBFA4FF7A41 +:107E40003EFADC5CEF5E879E3D38E9173B0BC9BA12 +:107E500035CFC982DBB24ECD73BC3EDF43F4AE5D9D +:107E6000DE2328EF52087ABF4782FA619BC2DBC645 +:107E70008CC639F968D75AF4C34CB4BFFAC6E3F7D5 +:107E8000E5B679CDF19146B487FAF54F73F41F63E7 +:107E9000CE5F4EFB3BE131F50FB6D1DE92FEE2360E +:107EA000E1A3FAEB61C1315FA6B9FE423A9F69775F +:107EB0009F6BB9F57543423E6D2D45FFA9672DE8CF +:107EC000F8DD871F48616FD8C2B7E75466F7575C83 +:107ED000BCD246EF3EBC8FB3DDFF7D5DD0564F7BFD +:107EE00077AC86D6519F5339BD88654EC7ED1E6568 +:107EF000ABA3FD071C9F158EEB53C071C35F198E9A +:107F0000904D3EFBE028B4DDFFAC704454A68FE7F3 +:107F1000F1EB5C8DBDD73A5777851BC8ADB9E4BE90 +:107F200087F0FA97C95525D7B912183EFA3DD20401 +:107F3000EB4FDAE8DFDFFC97FB3FB89126AA82B669 +:107F40003A0191D7613BF50EBE77CDEAD854DBF705 +:107F500042CCAB5764F594CEFBDD3C6EF0EDAB2B21 +:107F600001ED6962AB277DAFACD1C7FA811A146C01 +:107F7000716EDE36EB702F175C7FE4E7F4B7AFBEAF +:107F80000930AE2B215C49FAB573B89AD408CDC339 +:107F9000C5B581BF07F359E191D34C3CDD40F124D5 +:107FA000A6C0D32A1FB72FB418F5939A825F0C3C52 +:107FB000B9BDF00C8C9F6FA43178E0E215948F442A +:107FC0004EA7265FF2EFDB98F98F26F58B857F723F +:107FD000DAD0E8BB87F7FBA2E95B3A44FA8E30F9C6 +:107FE0004DFB62E1593C4478AE35F92D18A1F4FA05 +:107FF000A2E0593B44787E6ED24BFF62F1F3C01091 +:10800000E139CBFB29692C3EDB54C4DEF7F08AD181 +:1080100087B0DE6130B9F016DAFD6C35DF6BAFB3D7 +:10802000FAC05EC7956A9FBFE1FB4C254F2BE44425 +:1080300036D2EF581D8B07BCCDFD93DF5434F86961 +:108040007CDEB14E5370AF7FA0B8CDFFAAB0BF3772 +:108050003B981C17A4B1FCCFAD31FBB865CBD31C4A +:10806000756106FB4E30C75FAAF9FE5EF0361993C4 +:108070009843C01BC1577A6800BFE172E32B95DCBF +:108080000D175F716D78F81A4CDED722BEA60D1D54 +:108090005FA6BCFEBDE24B1926BEFEDEF9ABF41FA7 +:1080A000F81A16BE160F571EB95DFBF78AAFA1CAA4 +:1080B000A3D36F23FE5D78A0F7FF2F37FE9CEB7FE5 +:1080C0005E3C9AF3AD48E1E7A5C2E7607098D76ED1 +:1080D000EF10F1EAF43FFFDA7875ACFFB9F1CAE7C7 +:1080E0001B365E0781C3BCFE11F13A0CBBAE4D617D +:1080F000DFF574CE93ED67DF5B1BEFAA3E321FF313 +:10810000C75F15697EFAC8EE391BACF540D97E66AB +:10811000FF1F299FBD81D65747D368EDD95121FC58 +:10812000EF2598575EC4C639E73FC2F1F55FBE0C34 +:108130001ECFD6B391AE47A38B07944728B7EC8BDD +:10814000E68D2CF415FBE3FB08E8DB4B300FB12088 +:10815000391C269D53AD3B5CFA1E8DFE6058FA67B4 +:10816000B0FDFE876FA8767A82E2310B7AFFDECD12 +:108170005588CF3681D5C31DC75B79F8DD35A09D05 +:10818000962DCFDD83748AF9595EB043D13760FEF6 +:10819000C4BD78C1837E42B7A3B764B8DC167C5DEA +:1081A000E3677ED5F495C9FDAE08E783BEF12E18CE +:1081B0009F84BF27F37EB7AC64DF07032952B0C8A2 +:1081C000F21EE90ABE8EF9DC397EBE3F40C71F4D64 +:1081D000F15EFEF57CFE654B061E0FD5ECFB3B8485 +:1081E000EF0AACEFB1F6F219978FE3BED81C3F81CE +:1081F000E76D57EC89AF211F4DF0B1F7802408617E +:10820000FD95394F96049D0AC1FB07B25E8079CD7A +:1082100024F37C75A07952E1D5DC8FB90E8A227ED9 +:108220004767AECAE28825118059183F7487EF630B +:10823000F943C60799BC0E7146755AA21EFD5E89A8 +:10824000ECD3026FC7FF9BFD4FF8BCE388A0D1F7CA +:10825000CF1D78184C3F6CE47C9325C6367B306F7D +:10826000B2CA95F43B73EBFDECEF0C15F87BEBA574 +:10827000E83AE31E8BC9F87D8AA512CB7F114E2CFC +:10828000B0FEDD9102CE07CE715922AB37827798CE +:108290003CB7ED5D57904C7E7EC5E5B4C05F64ABE6 +:1082A000735C12BD4F46F95CB260A1ACFBF0B9CE75 +:1082B000F88DC3D1A6C40AA6F8FAF094520F71FC47 +:1082C000741C8B35E0773956D5BA689D40F126C6C7 +:1082D00077AB361D103690EB1E2E7F0B910696F96C +:1082E0009EE0746DDBEB1D8DF0B799F91B9C98C077 +:1082F00071FB2EA0F990C7FD1F34613EA4DB053C45 +:10830000FF1B2DC7FC6F37AF6F7B8E3CAF4778E705 +:108310006453F91EB7E9E31AD4CF1D0AD0BF7BF12D +:10832000BB2DEE04BE4F60F24BAF9ED874A10EEB96 +:10833000871F553A2722DF6437547F2D59FE743F3B +:10834000A7C39F7CD1F46476A07935F5B9D96F9134 +:10835000A4CBC9FA2F2E779C6B1CEE11EECEB390F6 +:10836000248FD9CB878981EDB4B7B81EFF9523CF71 +:10837000BBE458F23863975FE0F396ADA7E796E168 +:10838000D669CD3487C7C45796C1F0B4748968D311 +:10839000B7AB16A439EC1E86D79BDDFA93B88F478E +:1083A000F7FE62227D2FCA713E78C59882CFEF8694 +:1083B0004E19F5C42951A7D7B7EBECDFFD7E1B6240 +:1083C000DBA7E1F9592B2695ABF739FFBCBDFC8E35 +:1083D0005B28FC715143F84FAC1C71D34CD42FCBAC +:1083E000E5F05832EE44FC7EFF5ACBFE7BED1A07D7 +:1083F0005CBFA9B863C0736BD9723BDDDA14661732 +:10840000185F6172780FE1D15994BFBAB7CF20EBF2 +:108410001F49644ED9CABA03FE7DA7C5FCF7534273 +:108420006CC70CA26F4E0B2C4F627C9DE98D258F83 +:10843000451B31757ABAF69A57BA49BF8B7C7FEFE4 +:10844000D50E7C3E3AF969DC63767B6FFA31507069 +:108450007CAC26F979B0554BE37FC72B3C1AF5CBA2 +:108460006D9B92F7FB213233A1EFE9FF162B92C5EA +:108470002727680CDE55D1E4E327687EF61CCFA5DC +:108480002478FE2090C6F59C361AF5F4AA14F076EE +:1084900007D8F9F57EE303B7A11E3825D8F5F39187 +:1084A0000093D7F600E3EFD37B57C8D948A72697A8 +:1084B00086FC7032233C01F96D75FC047DDFE55FBD +:1084C000020CEE43DEA81E9886F2B2686E36A14B0F +:1084D000C74A08BBF4D4FABF2860EA7F16AF25E785 +:1084E000DF0778FE91A11F50FB438A8CBE75229D49 +:1084F0009AD6819F168C75B4CE70AF97D595427879 +:108500009AD58E9FCEE13EBD6F78F4BE25EAB0834A +:10851000FAD97FAD9574DD7D691AD6A51C29173B64 +:108520006F24407EB82F8D7EBFD62917A9D61FAEE7 +:108530001D787ADFF0ECC0C1F6BD32101A921D78BA +:10854000BEFCD11D2528474AEBA464FAD7D4D347F3 +:1085500079FCDDC93FE6B582F3C5A9C4C070DDBDB5 +:10856000CB0ECF6DD576784C79399568F0AE463C18 +:1085700041E744AB5D0A73A60D72CEB2FC542A38B3 +:108580003705EC7A02390FE9700FD737EFD53E1A6D +:10859000B0D2C1B9FFD302F70F9E6475B963A3AB24 +:1085A000CBB2F53EFEDCC2E7BFDC7C699E33CE7900 +:1085B000FED6F9D03CE706E3C3AC14799C027C718B +:1085C000998C5F2D690AE6EB0B023A6B83360F5FDD +:1085D000D58299E6DF57D147E3FB5FA7F77AE97BBE +:1085E000C0C6567702BFDB7E6AEFF513ACFBE9E24B +:1085F000F459B524837E9EE294109E9F4BEBCE44AB +:10860000FA9DB5B78F65CEC3F6A38705D4D0705B4E +:10861000CD6A11F7F77A80BDB7B36AD39BD41E1C1D +:108620002E9FAFAAB69FFF13701FD9163B4BEA29A6 +:1086300041FE49858717100FE8074517CE45FD7C99 +:10864000C72617D5B72FF279EE9022546F439C9D21 +:108650008FA0127C9023E4046E02F1F138FFAE94F7 +:108660001455ACEFC9ADDDF6C05CAC7B75CACB97D9 +:10867000D3199EA6A433BD7DC81B7B2F90DDA79F79 +:108680004FBAAA0FE4922EEB039AF91D5F2AA7E6D0 +:108690007ED673B8889DF62CFDBE30DF1FF438F807 +:1086A0004D68ADFC29E2BF4CA57681D74DF43ED68E +:1086B00045FFC04BEBA84CB932ED1DE7F8A552CCF5 +:1086C00066377ECAF59ED976DA21FF382F92F71FDA +:1086D000931E1A929C5EAEF36252FAE5392F04CED5 +:1086E00067CE73A357AE9BD8FB20278E7D32379978 +:1086F0005CDFF819E170CAF3A9BD5EF65DE31BFC0F +:1087000054EFF4F953B909F4979D7281FE147EC7B2 +:10871000E3D1BD6F4CC4BADE13DB1FB82D193DAFDA +:10872000D6781D7677AE2D9EB72600B4FE1BC87A8C +:108730004F59E637C7F5CACB20F1CBA52BAEA5FE26 +:10874000E4DB2BAE1FBDBAB8BF5FD1AFBF2BF6F8CD +:108750002DB86E3DF7A777B82BF626F303395EFBED +:10876000C789EDF6FD2D9B4A1BD1A5DE9C76C397EC +:108770006249D6EFF56B36258FC7FD9F74875F631F +:1087800010BF86E0A37BA5189859D2E7D7741B5F6A +:108790008C5FF33BE8F9F71954FE93C3F7643AB3DF +:1087A000534F29B11DD712F84E13FFC740F911C816 +:1087B00038E497EF26F7D71EE1E37EB76998FAEA27 +:1087C00098DD9F49257FBD707D4EF96B537A0A5025 +:1087D0000FFC6ECFA7EF3E80FBD9E3A5F876CE73F2 +:1087E000A32672FFC24BF9D63C9F3B14A6FF7FF72E +:1087F000D591F4EF553BE503A0F5A6EBC8F3E37B79 +:108800008529F81DC4B6BD6915C9FC9C159A8BFB5A +:1088100017F6780F70FBEE16CE6FDADE67AAADF1B1 +:10882000E877B8BE32E300AFA4B37376C982850A95 +:10883000C67BD6F6C69B803A2BDA55F97BF03B52C5 +:108840006FF1F7B98C35FEA4EFC7FD82F3E56071D7 +:1088500088E52BED7182250B063E6F3E4C24AFCB95 +:1088600032F939D57AC33D5FDA12C3CB8B0DB64FDF +:108870008F36347FE416A8FE12C63B964258C6EBEC +:1088800012A89EF85382CA0F772DA6F0BC65FEDDB4 +:10889000E14FEF9F68B563FE8BE3FBFC92FBBF8A61 +:1088A000EAF21DA57A62B2F3C919F7792B053ECF1A +:1088B00070BBE71DA433F2EB5231299DDDDC8F7FC5 +:1088C000672593A3FF0F425212950080000000001D +:1088D0001F8B080000000000000BDD7D0D7C54D5CF +:1088E00095F87DF3E62BC924992433934FC2840075 +:1088F0002206984008A80813422428950904080A6B +:108900003A7C88817CAAD8B25BB74C0860A46E1B05 +:10891000566A5DAB74A0C152C536D1D422A638A028 +:1089200028FEABFF06EBBAB845775017F9924456CC +:1089300017BBEB963DE7DC7B336F5E6620B6757741 +:108940007F1B7FEDE3BE773FCFF739F7DC3B972EF8 +:10895000C1DF0CC62EE99E8BAA5516B232FABB04B3 +:10896000FFAB9E9B145576D9ED8C3919FBC7A5AD8D +:1089700089FE22C64E19E065096381C7D4E06E0501 +:10898000CA41FE5EF6E7B22B54FF547041AADF36AF +:10899000783CF9BCEB5118774C649C65CDD1E386EB +:1089A00059602D73C038C144FBEE0286FF0C592676 +:1089B00046DA77DA0D340E3B9569602EC6EE936D7C +:1089C000E38CF7BB0DD0C15583EB571BBD26BB66AF +:1089D0009E2B52DD8C4D8E94ABE746CF3335C54E82 +:1089E000DF19B3E7FB92193BBD2BD14BF0989E1CCE +:1089F0001C05F3ACB0B2800DE6F9F093D7BCCF46BE +:108A0000305625E051EDFBD484F0386DE8DF9C8CC6 +:108A1000EB7ACB60DF0D43951EF39AB4F05B9BA21B +:108A200050FFA73B2E0FBFB5297C9E0B2AA3E7B7AB +:108A3000F058625459BFDE7FFE9B072662BFFFFCE1 +:108A400037174DDAFE177D91CB421991F21D358A09 +:108A500037583478DC8E54F390E0DEA183E31D5F59 +:108A6000E453FF0E953577C65897C76EA5FA0B7D70 +:108A7000652627C073E5FD8A47812E8AED6E1A6F41 +:108A8000A591793B613ECCE8CEAF02B83B5B9BEF52 +:108A9000F3C5E8678D9DC3EF339B2FD57E19F8BDD5 +:108AA00023E841D65B64F49B62D55F5C130DDF3035 +:108AB0006395B1E67FFF57A44739BEBEFE50E7512C +:108AC00097C2F932C312FA84A9F0E21CF453FA15E2 +:108AD000C6D5D5D78FFBD702EEF1C63FFD47B536D9 +:108AE000161CF60AF8FB7D403F31BF27D3F7B75875 +:108AF0007BE37EE2EF24CF6E0443C7CAEF01DAD9ED +:108B0000EA39F7BD0AAFD91F920B68FCA5BEA315C1 +:108B10000856F6E5C3E311EF9F573EFCBD1298DA05 +:108B200069B3BF35191A9CDEA87802EEC1E3BC8593 +:108B3000EBB430F6F6062BADF70FD096F0330BFE04 +:108B40002F9BB131AAB70E850AFBB6C5BD5BC3B773 +:108B50008EF51737B0F18CED31FB36E21446DFFFAE +:108B6000E93A86328F0569DE1F983C6B08DE8C116E +:108B7000DF1FDF65DBB915EAFD3199E3032839DF33 +:108B8000374E23278C762A0F153FBF8B839FAF2A42 +:108B9000A7E43AE38D0390A7F9CE9F696B5352196E +:108BA000EB36BBEFC4F5F4CF49B0EF0214CE377B00 +:108BB0006F46F8BC75D4606829A06E8D48A70BF885 +:108BC00010ACE09682EF8E2D41F963F226C054AAD4 +:108BD000A00DBB16E868A62D80FD95FC6EEED3882F +:108BE0009F876B2C6E15FB9BEE7E4F85F2FC9B2CBA +:108BF000EE8DD05F69EF88830EE87FE15CC5CEA083 +:108C0000FDAC39A39C61585FD27AE82707A7F79D8E +:108C1000CAF2918C3D85835DC7F8840116F3155126 +:108C20000E3CD5360BE4C15867B7C106A05EB8ED5F +:108C3000A9362BF4BBB9C597654F83C9A6B5B459FE +:108C400087813E72797B6778189B9AD65A69BD01F5 +:108C5000D6F998EC6F539B378FB1170DFE0205BE06 +:108C6000DF91F644A511E6EF2894E377D2F7453774 +:108C7000ADD9BD0EFADFBCED50A511E7BD548EFF96 +:108C80005A65B911C69D26CB6F58B1EC4812ED71EB +:108C9000BE5319338D88CCDF9805E3A7CBFABD9579 +:108CA000B3A0ED3B65CDE54618FFDD6DEFB41525AE +:108CB0003036656E99DD0BE5F7D3CE5726017EBAC7 +:108CC00019D029943F48EBA7F93B5483E8FFD336EA +:108CD000EF349C4F602C7E57029FB5551633D660FB +:108CE0000DBF8AE4DAB43E6075C13F262B9C4EACC2 +:108CF000A6666F2EC0CEB4AF2C944BD369E7F4991F +:108D0000171A877A6CA03C06CAE334E52C5EEEDEC7 +:108D1000C8EE88256F83E95CEE7527C6FE3E318D6F +:108D2000CB03801BE993D463CCBB37865EC94EB3BB +:108D3000513F871359C09A1EE1B779C0C353812FA1 +:108D40009995CF53F633487FA4713DCB02F3D2916E +:108D50006FE66217B0F4428F1240BA66CD49C15136 +:108D6000483B2C645C80FA4335D07C9DAA72471541 +:108D7000F4E74A64FE2E783A331895A1BDB7CB16B6 +:108D8000E9EF0D41F71585BE0EECAF2233BBB8B548 +:108D900020D20FCC7B937562D4BC8D53D3F1FBFCF6 +:108DA000E2BB8B34F02CE2EB003AA07630CCD3332C +:108DB000800FBA7BC78ED80AF3FB5027774B7BE72F +:108DC0009B18D4DB9C2EE4899BB7779673F9D37FED +:108DD00077527017F2A7D5538C7892EDE60AB897C0 +:108DE0003F30F78758AFBED7C42C506F5D57592618 +:108DF000BB8C5EACFFE27A169CA4291B4366943BB5 +:108E0000F55F4CA7F7E50FBC61463EC57EDCB0AE12 +:108E10007509DE4C0FC2AD3536FE196BA179D47FD2 +:108E200091C60293B4EF399C22FD3BE8FB95D61521 +:108E3000E94F65C18CCBF567A6EF0370370AB89B85 +:108E400063CFF35E49A7006F8386BE160A7A03E9F3 +:108E5000E7457978FC96A25D28EF23E36EA476DDE2 +:108E600046C023DA81BD896EB48B4B8D5C7E96F64D +:108E7000A6DB034A843E245D48BC76A73797D17AA7 +:108E8000AB14FBAE82C1F3FA6B392FA14F3397FAC3 +:108E9000D5E59AF9497E80FEBB45FF2553897F9E23 +:108EA000E0FC007CB30CF917ED165C8727346E7E6E +:108EB000F2E0F97F0CE485F5018F1CFEDFB005516F +:108EC0000F48B80D867FEE15F0994FDF4B7B0F9959 +:108ED000719DF571F8F6DBE929346EE6B1508A1B15 +:108EE000EA9DB57379D5DD3929E17AE48BB9068637 +:108EF000220CD78DF66AE980BCBDE1F599A01F323E +:108F00006519E5AD1BF130207F43566BA47EC3DFAE +:108F1000DD306713D4775800FF4564875A99C69FA0 +:108F2000F8591A976353FD2CA6DDD2929E4CDF258B +:108F3000BCFF7E7D39FB10D6F7AF76CE9753C301C9 +:108F400005F122F95A2FA78E083C1EFE1F9353CA23 +:108F500015E454959053FCFD6130F3B19ECB151A86 +:108F6000A7804E5CF1FAA451E8CFDC93A5BA3F028A +:108F7000BE5AA078863D03FD565BDD9B93DD113A1A +:108F8000A96656B70DE10E46D325D4FB7313A88C02 +:108F90007F68975C6857381D32776AF5B8F8724871 +:108FA000CEE39E2C338DB7E2C151A97EEDFC849EA9 +:108FB0009867093DC30A07F3B92CC3FC1B0CAAE64A +:108FC000BB8DEBB3AC64EF87698087B7145643F36E +:108FD000D1D94BFF21FC36BDBDB449D8914E342FB9 +:108FE000898F0DE49C66B659828C3709A09F9AD967 +:108FF000C904BF860CF51A3AB8989647F358BA18C0 +:109000003E4E00A6B4BE3CE1230D1F1DC1F9905E8B +:10901000084D463E05B119358FA5AA2F4F41BB35E6 +:10902000D3E24139037822381C4E60C60418F73564 +:109030007822DE2AD4BB0F9A1C48078AA795A0BFC6 +:1090400053D8A72C84FA66DE8C24B25BD997F78EAE +:10905000AC0278389338DD423F56D18F95E844C84A +:10906000BDDFE65FBD0BF593949F120FEC4B95FAB5 +:1090700093DF0F2B557976281F765E55DCAA44DBEB +:109080003F680F45ECA7C40767033F4EA9EC0C19D6 +:10909000EC285592E77C0BED70B09F12603D19E90A +:1090A0005C0E1C2E08A829D8DF285807BC7A35D1B9 +:1090B0005FD46C8BE0036C1C3FE2CF6586A78DF319 +:1090C000073EBBD23932AECFE0CFCDE2E94AE1F57F +:1090D000F5F4F6830CCE9F6B150EEFAD655C4EE894 +:1090E000EB8D17FD36580395AE115AFBCAC7900E8B +:1090F0008D8CDB5913D2059D947378953FB0341550 +:10910000F5E6E7BD0B535951448E6E56FC760FD4ED +:10911000DF6CF27D9FE21DFFA032F447CC697E7BBD +:109120003AD4CB488AED2F57A7F3F966A03F0DF547 +:10913000BE27FC1DD317D7909F7D23DA65F03D2510 +:10914000AB9AE439C2D00DFDA6B2FE805D83BFD4D8 +:10915000A98628BFC1F4C5786AFFD5ED86E23876C6 +:10916000434994DD20C7D5DB0FEF6DC8A2F9CBF6DC +:10917000CBB2DEAE609AFAB7B3F066ECEFF675B933 +:109180005171A27876C75A8127B4130231E7658EF0 +:109190007AFF1EF88901EDF8A7F8F891719380D154 +:1091A00022E34E48F7D6A5133F4DB39FBC061E6081 +:1091B000BB5F5249DF90DC07BDE4DD69237D548944 +:1091C000F25AFA47C8F7F654E4EBB27BD3276BF4B4 +:1091D000A368A797439F087FFA13A167528F497B23 +:1091E00031D1AD28117D33585F093DA3938B57B220 +:1091F000AF815E035AFDAFEFF787E97FAA5D59188B +:10920000873E46FFB7D895A5D3FCEA38949B950ACC +:109210001B058F29B3A2F5FCD3E9DCFF783A3D2981 +:10922000CA5F99BF34BADE2FB0DE647C260DC95FF9 +:10923000D1EA21454579C7FB6B14F45070E62DB394 +:109240001BE4EF19B483A0DED10CEFF348579B1257 +:1092500053C6A37ED8F99FE56376C2BCFBDF3479A1 +:10926000766177FB387D942D59D76A84F7A64EC571 +:109270006E6191F9D9D6774D5805EB3D28F054EF42 +:10928000E0EBA87784CC2361DC9C7A3E7E5EE741EC +:10929000C5A8916F79B5BCDE6FD24D51FAE6B758CB +:1092A000867EDE94FE070BB65494607DAF712B88EA +:1092B000BE9C4E85E2C139CD0000A0831C0FEFDFBC +:1092C000E6092A2B8B22EB6C335415A15E687325BB +:1092D00079502F6439FCFF80EBAC3F1E0A2198A621 +:1092E0001CEF35A27D37D1E17D87F84AACD3ADDAEA +:1092F0007350AE261DE7F36BD7D13B63DF15F3DA6E +:10930000C5E5ADCA8E30C407CA0E18CFB5710CE9D9 +:109310002559DF952EF4848BF99F25BB8AB531C280 +:1093200017A375B8368E26FB5EE23362475D3D11AA +:10933000EDA8C28742C615D06EFFE386CA5876E212 +:109340006702EEB08E3EED3AE2F185D463B29E291B +:109350008E1F2DE93DA932B67D0A1A80BE972D7168 +:10936000DC8AEBAEDF6466162502FF890E9F21C3FF +:1093700089F8DAA9206C247D6D4A7F4AC985F5DD1C +:10938000BB86D955167FBEF5EB9F9BB04AE36F4174 +:10939000FF848F9D6656ABD5A7D29FC8C9E0F6F46F +:1093A0006A872F0DC76DDCB7CD8CF85DD371C2AC69 +:1093B0008D770F5AC710E1A5D4723FA5BEC61AC457 +:1093C00075962D3112FEEA369983288FEAF7768555 +:1093D0000C684FDFCF3CC8EFF59D5DAFE6005C72D7 +:1093E000EBBD935577A4BFDCFAA082F3710111F6AF +:1093F000929F1732A37ED6D335DAC36897BC9AC042 +:10940000F9FD5C992DA000FCCE99FCF558EF5C7637 +:109410009227501081F76B5DB38F28C0D2C9CF5A05 +:1094200042F86C33ECCAB242BDB6B1660FD2D14439 +:1094300087BF3403E0946EF47563FB3447B2A7052D +:10944000DABA2D6C22E9E721C2618A8E1EA6DCCF32 +:10945000F9A4362345DA7B13510EF93278DC156313 +:1094600042289F5E35F1756C627CBE5DE9DE0AC400 +:1094700013B3A7D3B839F52105ED7DFDB8117AF204 +:10948000DE9CF115E81BEC3C33CAF53A2167CA961D +:1094900074281F6AE8E0563064B05ECEDE9D0AFA9A +:1094A00081F0BDA5C241F59905E5CC5EBE1F51070F +:1094B000DFEFD4C815B98E18F26539C2D776BCF77C +:1094C000152E5F42447F72BE7A7C3664B869FC1BFD +:1094D000C12CA0F7E6C01837F4F7EA8844EA4FF247 +:1094E000BB9E3F1B049DE7D474281837702471BBC2 +:1094F00051CE4FD63B9A31F36E9CCF94CA5E8243D5 +:10950000438D91F026E75361F68D44FF6B83E8EFBE +:10951000D0E2F7CD61286FFFD551A2C78676C54B43 +:109520007E41FB51F3428CCF057EA6623CF6666E0F +:1095300092B0477E7994F4C8CDDD3C4ED0D0DD6545 +:109540005C698BD069C19943B7239D35745A5882A1 +:1095500082F8E376AB9E4E41BE10DDB38099F6B340 +:10956000403E06489E327F01FA2352FE7689B81F9C +:10957000B3F1F77F27E62DFB8DC8CD04A2F7823328 +:10958000130F59019E0D1EC503A612D8DBBC1EF495 +:109590001F22F9CBD808F4CB64FF7AF81D10F679B6 +:1095A0000C3CEF40B8EAF588D4AB053B66327C4A08 +:1095B000FC1905DC65BFCF6498A9DF67328CDCBF7E +:1095C0002BE3F1EB4D26AE3F36B55883C8D7AFA598 +:1095D000DD7844190F704A3787F079D8B0A21EBFE2 +:1095E0001FCEE1F368336C1CD3CCF5D7CF713E8727 +:1095F00016A7302E9FB83CDAFE1C9727F5011BF901 +:1096000089F5FEEA55B4FFE048F0A0BDCFFCAF9865 +:10961000172647E8418F5FF7B307CD6EF87E7327B3 +:10962000E78308DCB89E92740B728EF0DE952EF7FD +:1096300023FC050857F0DF5B30CE20FDF794A5BE74 +:1096400040B27B30BF6608FF7DB2F0DF4D53AD7F87 +:1096500051FFBD6EFD6FB2B1BC36EB757A4A7E012B +:109660003F318AAF7E2FF01D12CF0F04BDD4957409 +:10967000123FD47DD44C7C64ABE4F2C4763C5A0EE9 +:1096800032F6B7C22E7888E05091D479A38AFEF0E2 +:109690008F157B2B8B3FEFBB94E6FF7F2DE2A54B15 +:1096A000A57D29F62558F5A500D704010351EF3310 +:1096B00041EFE7F60022902F8DCDE6CBD9BF57EAD8 +:1096C0009785DE5610DF7502D6E7F6965FFB2F18FA +:1096D0004FDC93EA19054B3FBB77C15FFD0BB43FED +:1096E000D731C3837ADAD1EA23FAE9772678306E64 +:1096F000E850C1B2057A68E97C39E57ADC177B7AF3 +:10970000C244949B490EEE079E794E5D8FF0D9F8C6 +:10971000D35F4CC7EF75412503EDC6737B7EFC47D5 +:10972000D48BB51D4DE869B0D6A75F223BDC10DCB9 +:10973000C9DFEF4925FBF2F44FB64D47B8B776B60F +:10974000D2F7333FD949E5433FFDC5817F477BC30E +:1097500097E2C17A679EDBF69D7F473AAF4EF1E014 +:109760003AEAFD46BE6F2BE95B2FB7BA0E129F4A4D +:109770007AB919F52EC2A986CB1F49CF1F887DA5BE +:1097800015E5B63694671F6C4DAE8D154F9C20D6EF +:109790008B31179263350AC5D3DA806A30AED19621 +:1097A000C8A6E233A92864CE8571162FED9A4E76AD +:1097B0004FE0C46AACBF605F02DB4AF1370CDE8267 +:1097C000FD4FA4CED838108327C14F86DE3B2E81B3 +:1097D0007DFD0EC807D23B3AFB7F41DBEB7F403972 +:1097E0005A6D0D1F74BA23EFDB449C06EA93DE2901 +:1097F0005D173B1E3AC561137CCBF5664E77559ECF +:109800009BE484C5334A63970E3BD6BC15C410CB8A +:10981000A9EDBD11D771D398E593882E30CE87FA84 +:109820002760A3FE1B304E097C56E910F10F3B73F5 +:109830005C07E3571899C3864FC6DE36911CD94D95 +:10984000FD82FD417695FBA5C5BBD11E79C4E4CF51 +:109850009E8CFDB409BDD5C1E70DEDEDB85F0AFDE5 +:10986000D9AF9B48FDF49AD2A97D80B79FDDD1A2E4 +:1098700044E60B949A8F7A0BFB2BB1A19E09D4106E +:109880007EDC665AD719AC924DEB1EBF6C5C847FB0 +:10989000F5F11D9467B80FBCDA51B6DCE18C3C657C +:1098A000DC470FCFDDE2FB470EEF7207CE634F467A +:1098B000945E8967AF1C5A7C9EEBDF174F90BC69A2 +:1098C000443AC6F1FD1F45E9DF95928E5F38417439 +:1098D000BC721FD7BF8DFB8ACD48B7673778D98751 +:1098E0006080368A7DD64794F06A8AF3BC9060C760 +:1098F000F8DD79A16FEA1E3A7112F74747ECCB26E3 +:10990000BFFEFC0B0935D8CF618381E07978D7356C +:109910003B5B15ED3CB93F007630916A23D8A9DC5A +:109920000E5EB50DFDB3865AE641FE6FD4D14FE30E +:10993000BEA3442FD20E2ED8317F15B73F133C095A +:10994000E8BFCDE2F628037B14EBA7CD0AB69889D1 +:10995000BE8A4B91BE0E2D3EB005F578E32C66C74E +:10996000FE1F19E67D2197D6A330CC6779C4D43E7B +:10997000D308ED1FA970DB019200B70EB27BD91896 +:10998000B3D073ABC85E6ECCBACD437CA697072F1D +:10999000B490DDD5E84EA4F9DCBC4FB987DB2336A3 +:1099A000C6E7AF107DDE1CBC3E88FBCA9F08F849A5 +:1099B000389E37F5DE8EF038FF4B2044F87EF32CCE +:1099C0004EAF69B33A498EBCF6C26CD2E3922E9385 +:1099D0009FB7903E4F37DA150FE9B505162D5EDBC0 +:1099E0004D5C2FA5093D53F810C7EF2F043FFDC272 +:1099F00061104FB3A073116FB107C6A3DEFD44E041 +:109A00009FC408CA77214F1A5685889FEAF7F2FE4D +:109A10001C166FF1BD1AFA759473BD28E3FEB80FDA +:109A20005015435EBC2DE651B063C536B4976F0246 +:109A3000BCA34AC91923E428D005C22DA7D6477470 +:109A40007093E32E8F5A40FB07E427F6B79859AC82 +:109A500038CF31B12E6786AF04E3CDCECC64B2737C +:109A60009C6A992101DB152B9E5D6EDADF243BAFEA +:109A7000DF99EDD915C5EFBE1203D43BE54AE67870 +:109A80000EFED6387F1CF2A15BFAE95176DF607FCB +:109A90009BDB8D73DB03E3D10F91FB17120EC19695 +:109AA000C41AADFC7C5FC02178358FE7837D6FA33E +:109AB000F8B51DC641BF7ED7F53FE17E7D2BD57B36 +:109AC000CDC1E31915B03EB4DB9C85BE755C9F2605 +:109AD0007B62C163B543DAE5B717A35FD9586DF36D +:109AE00020BF6D7F515941F48CC141F4B7FDAB08E3 +:109AF0000F0CF080FCC0FCDC2F6D6CF60563D37B93 +:109B000015F15F23F29F42F44EF176A0F720A7777C +:109B1000AEFFA4DF8FF2B12AC67EA8942F8DE6F0A7 +:109B200068A463C90F8DD3C3A3116E439527E74D76 +:109B3000C0FFC83F0007E41FC92FC9FB399F6C6DE8 +:109B40007197E1F7AD15CCDEAAD1477A7F09E78995 +:109B50007EA794EB590E5FBA13E30086D016CCA310 +:109B60009072B871FF83A363E5B949396C3572F916 +:109B7000660D26055B35F4857B7BC913E949793B86 +:109B800049EB63C745463979BC6EA879112ED4E5F7 +:109B9000286F762505515EC93891BEDF4CA7121596 +:109BA0008F917E0BEE2F60FD3227B7434A9C9C2E8F +:109BB0006F72CA786C30CAEF711BFC27309F289EE9 +:109BC000FE92EDFE52712B398ED4A37AFCCBFD119F +:109BD0005C4F5551FC7AED07B97CD2D3E37C617FB1 +:109BE000A5E25AE17F3F17FB5983F1CBFB6135C6F4 +:109BF000A8FCB73643576DACF8D7C10D222F6ABB0E +:109C00007148F9753F17F5BF27F2BFD85263543E2C +:109C100095CDE36EC1F8E9841E77B14AE3F2385678 +:109C2000F274F629EAE194A9ED63304FC9E98BDEBD +:109C30001FC9AC498CDA7FC8F6A74795736B73A22E +:109C4000EA0F6B1E11F57DF8FAB151DF0B0213A379 +:109C5000CA856DD745D51FD53E33AA7CD5A33745D8 +:109C6000D5BF3A383FAABCB5A5B306F172CD9E5B0D +:109C7000A3DA4D30860DC5F07E5CE78AE83C311DE5 +:109C80003C67FE518D49873F7016103E27EC8B864E +:109C900047EAD46878605A1CF697CA447F897FF0F7 +:109CA0005C2E8F3595193F0BCBF60583E98159ED75 +:109CB00025DAFC8308FD04A3F2DF661A55DD3C02B9 +:109CC0007F12FDC59BA7DC5F8BBB8E3870DB27E462 +:109CD00084848B492C2B757ACD65E162BA125C586D +:109CE000D83314B8E8F7F706E2CDBAFE3626355277 +:109CF0003EF0DB58D0D8C761C147B2BC2890CAF546 +:109D0000906FC115EC681E07F65BF8FEA4FEFB45DC +:109D100021D79C300782CF10F9FA7D8187E3C8D71D +:109D2000E870EAF97AFDA78733517E5732F29BED4E +:109D3000CD2D9FA2DEBAC31862C530EFED623D8F14 +:109D400008B9F0E8063BF5F398D87F7C7C839BDE6E +:109D5000EFD830869EC10D1E7ABF6BC3547A7680D1 +:109D60003D87CF273754D273CF061FD57B6A430D6B +:109D70003DF76EF0F3790DC2172B253BC7971133D2 +:109D80005EBA3CA00E094F4CCD8BA92FE3F6A32E53 +:109D9000BD6C1EF9FAE34BE6BCA2E11B8B2BD9414B +:109DA000FB9953D814DCCFBC52FB8B1B6AE6BC3248 +:109DB0006AE87C24E9897D9931DA17237EE417F972 +:109DC000936F3B2F6E0DD8E2C32B4267B1E1546D08 +:109DD0003D9F83CEFA78B41934ED8FE9F8B8DA9F55 +:109DE0001AD36E287771FAACB1F0FDF7253AFEEE82 +:109DF00010DF3B5CDC2E7C378E9CB9CE6510FC1FDF +:109E000030D17EE020BEFBDE0DB1E0DBED7247F12C +:109E1000F112BF0EAFBA7EDE35B50FF3C4E0B32B3F +:109E2000F523D7A76FB7C9C5E5D6AEFFA3FCF9EEFA +:109E30009DC9E43F20DC9C9AF5BF7B67524DACB8CE +:109E4000CC5E17DF1705EB9C15A493A91F30A3ADBB +:109E50003886B9F93EEF483BC687641E407C7A35A8 +:109E6000521C8960A80E862BE0C36D2E84FE8D03E4 +:109E7000E3848C388EC710D16F9853C334E73CD439 +:109E8000C1F400ED0366CADF09E750DEE357A427FB +:109E9000A63E3EEA72FB7483DA7F4539B3FD6B96CA +:109EA0003392CFD9970F8F8AA5276B50CE5C07646A +:109EB000E82AFE6EA0E8CAFD7E55F8D5A861DAB79B +:109EC0001E32FCF6398614975A6F4D198FC6D5C5C8 +:109ED00004FE0CCC64FC3CD6FB0941B4F343629E07 +:109EE000E0F84FE07E75F3147CF664F90EB9A0FD3E +:109EF0000A33F713F35CDE975D502F51EC039B336D +:109F0000CD5BF0C9EC7C1DE3311F14BADA6270E757 +:109F1000E33A3E523C57A39F6237043DF84C61A19F +:109F2000713CEF2EE847FF2CE39A4437FAB789A338 +:109F300019EBA578B82701E366E6A4F05B23D19F6F +:109F40007DD148F1A1F198CF06E5F17F9F1B0C90E0 +:109F50003FE726F99021E0B615ED70683F8FF9DFF5 +:109F6000C5F99EB65B030698D7C3951313301F2A15 +:109F7000B4470D98F1BC42EFB9BFBB19D63DA1570C +:109F8000A538F30436E9F59128577A4DB4DF5B67BD +:109F9000640F21DFC483E7D96FC6CEEF2ACAE4720B +:109FA0004FE66DE9BF2789EF67E3E411FF87D00B28 +:109FB000323FC624F3639CDECBE6C79874F93126A2 +:109FC000A38FE13EB069203F6629A3FC18E8479BB8 +:109FD0001F737666EC79A8997C1EA62F92E2F49BFB +:109FE00042EFCF8EB8FC3A4D5F2444E55947DADBA7 +:109FF000E87DBCFC9C3C09A738F9495903F3CB66C2 +:10A00000810C6D3B4EBF9171F2E8BB4997E713F9A4 +:10A01000CEF37B36A5713A399865772C87AE97B326 +:10A02000B009E9F40E9BC384F1231FF374D1B91D69 +:10A03000A3A93F2CF96E04D6337E8076B601242D79 +:10A04000DAD977AC377D10D6C8A92A6F7499617DAB +:10A050008DDC5D9FC568BE8963C7505EDF05E64E37 +:10A06000B55F466E2EB5AA56A366BDC7E3D80D7E72 +:10A07000019FE3D9B1E13727D31095A734B87D4AC2 +:10A08000D479B47BED979797085F7F86B67F3D1EA6 +:10A090001CF4FD4A7076B672FEEE2F5378FEFE5F1A +:10A0A0001CDE69229F8D9F0B30E9F2D0D767B9394A +:10A0B0005D0DCC9BE7A1BF6CF7ADC8A476EED1DAFD +:10A0C0007300DD466FD244781E1772470F973D022A +:10A0D000CEFA75778B7CFA4495357769E0AF5FEF00 +:10A0E000E3028FB2FE2613DFBF823F9F15F0B28CD2 +:10A0F0007139DB9A3942E485A719511E2EE55DB00E +:10A1000065F657693F49C27910FC04DCF570F431FB +:10A11000F7ED98B77D25782E3F9A6846B97FBBB595 +:10A12000FF30FAA6E15EC33B23E179C236F2640751 +:10A13000C37DB731CF1F62180FF1F0FC09368BECED +:10A140001C2590AB5EBA66E876CE9614FF18E48BB9 +:10A150008F44BEB5D4435B72CE8CC6BCF9D4F4B286 +:10A160009A2C27C5DBBD19483FBFB670FA79147A1F +:10A170008272D381AB77A27E69C9F22FCA9A1CC9B9 +:10A18000DF63DEFED1987FF055E1037F26A49F2B8D +:10A19000C1675B26E37C98129B3E8EC4A10F3D5F96 +:10A1A000D0B9B292AF8F2F243CE57E859CDFA22CE4 +:10A1B0004E7FF229E1A6CF1B5A946510F5B8DC68F2 +:10A1C000C9F2119CFB867D7A3201E67E5C97E73509 +:10A1D00020BF86B87E09EFAF4BFE1E4F8C3DBFFE01 +:10A1E0004CBEAEFFA9F92D91F31B1F7B7EA6ACA13F +:10A1F000CDCFC7FADF4FFB1AF417E07909E2996D6A +:10A20000EA27B9783C3DF63C470E799E7ED3D7A12C +:10A2100067257DB3C0F25ADAA7CF4A8CB94FBF0881 +:10A22000FC26F47BF4FBF5725F1EE407ADB7DADAC7 +:10A230007F7B06E27D9658B78B85D2701FF38085B1 +:10A24000E2FEFAF55F23D60FF02A4639C5E6F6534B +:10A25000FCE2F8E8D872A1388BF3C540FD363E4EDB +:10A26000BC7305D70AFEBCD2B90256E2A7B85F9903 +:10A27000D51652010FF7087C9873D77AD02E2CCBC5 +:10A280007AE318AE13E07F6E009E9A3CBE331B8EBD +:10A29000D8479AE2CBED3AF5D9D2E618EB99E7F434 +:10A2A000CFC5750CD4DBF3BA7DA4065FE358D8C0E4 +:10A2B000CF45F71BA2FCE14CF695FC61AF95F34B43 +:10A2C0006ABA8FF401EA07D43B5BF65F5B8CC84443 +:10A2D000FB02F378FA9313498EB6E65C37C6AD817C +:10A2E000676396B45BD538F6E29F97F71FB19794F2 +:10A2F00028BB35D2BF91DE4BFC94D9FE5F4C7CCCA1 +:10A30000737AEF453A1C9DEE5D874F3DFC020F4C82 +:10A310004B23FF18E13723D2DF00FEE3E0F9C74EFD +:10A32000EF77B0BFDBC4F91945E6EF0DC4298CF611 +:10A3300093D608BC878A97EFE13FC03FDD91E5DD0A +:10A340008A78315B043F321B9D0B97F60AD3D935CF +:10A350006C2ACF275D96F5C61F30CEB32585B3ECAA +:10A3600096EF24505EDD1D8ADD8CEB06FBE3BD1FFE +:10A37000417D3F0BBDF76DDAC7927646927A296927 +:10A38000E8F3947EF295F2A80FA11D06F39969B047 +:10A39000D1BEE621209B6C901B33CDFC59361BA807 +:10A3A0000AFA9BA9E6F584615E9FB373E93740EB37 +:10A3B00044114F5C77747202D2E54CA3E98C566E5F +:10A3C000E9E31C5D59D1718ECFD9DCEFD3DEEF18F4 +:10A3D000EEEF3F3C7766A636CE3210E710EB581012 +:10A3E00058CEE5A94ECE497966B0F2FB439897B9AD +:10A3F000ED2E8A1771B883736D84F20DB28CCE097D +:10A4000094A7092429D81ED67D8378B215FE2C94F2 +:10A410003398BE83E381D79785CFD66B3D6E7CCED4 +:10A42000507C463E8F20CF3764CD7958DF600DAB2E +:10A43000FC5C1ECCC085EDE578BC9C2CCA9BAA2F89 +:10A44000DC7EA77B70FC82D992C9DE358B799DB604 +:10A45000DB0206786FB1854E535EAA78EAE31C17DB +:10A460000D8100E6657F4B0DD27C935828D48B710B +:10A47000092B80C040F1831348A7E0D534E23C1398 +:10A48000EC1742DF6698DFE855B09CA1D3474EDB5E +:10A490003ACA7776FA8C3A3DE457906F326BF4EF14 +:10A4A000A3F593951DA773404AC8977529E3CA7110 +:10A4B0001A7D7CC63493A3B87F0DB77BDF49E4EDEA +:10A4C000245D28D95CFF34A69B19E5B9B8AC56B415 +:10A4D000DBCF279FC2A396A837DA506F584D5E8214 +:10A4E00087D41F0DDD7733C44FE3BE2A86F4FA4FBD +:10A4F0000ADFF70C2C53283F41DED75053C4DE84CB +:10A50000966C59F6086AB7F0887F593D94ABDF60C6 +:10A51000E34250AF7886AF02EF65691DC73C1BA1CF +:10A52000DC9AE07FE697B89EA32AF5D324CEC33207 +:10A5300066AFDB0BFDEFBC7598672B2EA9BC7F0BBC +:10A54000E6FFF43FC8EC982F32884EBF84F501FE39 +:10A550007F82659877D32AFF13F741FDEC37988700 +:10A56000EA88EFE88B20DE14410FF87E06BC6F12FC +:10A570007453D8A3F07D7B8785F226D8B14CE2973F +:10A5800085563E4E534FD9BCC930AFC2DE4944C692 +:10A5900023A13EE635616601CFAB63E427EBEB8F89 +:10A5A000C4FA6E8A52F17C9A1C33DD7BC4849C9B76 +:10A5B000A2E3B7EB23F44FDF8B45B949E8A3283E6C +:10A5C000C17EC02FF796F26D7C6AE7E0FCE061F295 +:10A5D0008FF3ED752CF287FD9647C621F93B4B7C36 +:10A5E0003BBC640EE5734F31860E225F5F2F9EC524 +:10A5F000E2897C6D05382E36361F76C27AD2D63384 +:10A600004F0B8EB2D4DD8AFD95309F8A702EB53FF8 +:10A61000D88AF3BB76E9D10CA4AFEDD985447FD3BA +:10A62000AC9EC2042091D6A91E8F1D5ED52C550864 +:10A630002E0B6BAC41CC5B5B38704F8FBF6011F061 +:10A64000CD62BF22CECFFB0B966AE2B0329F6F91F4 +:10A6500005FCE718727A7B36B78764FB2671DE4407 +:10A660007E6FCFB6D1F76F66DFB82C9BF22A789E4B +:10A6700033F0BD3F7B72448EC0B89487B280794D71 +:10A68000B8AE05826F25DF2FF4DE4B76EB425FB468 +:10A69000FDF94F0AC777608942F6E0E29ACBDBA763 +:10A6A0004DD9729F37CF7E3229F25ED29594DBF37B +:10A6B000518FA3BCAD04BDADB18F977EEBCB346A97 +:10A6C00097F964C3A5E191F32D4DBAF32D8DE27C8A +:10A6D0004BD3BE16930BE95D9C6F69EA39B1459B7C +:10A6E000D727E134F87C4B3FE5332E32070FE2B930 +:10A6F0009F456B618D50FF65711EE2153C0F313136 +:10A700004247C9B7268478BE9C97F2F6F2EC491E00 +:10A71000CC3369334CA43CA1B694648F362F676B5D +:10A720004B7305D693F941F23CCBA238FBC08F673F +:10A73000733BF91185E76905965809DE4E951DD3DF +:10A740009ECF7716FA283F6E59B69BF0FE88882375 +:10A75000603EE9247806C11CE3F8E2EDF5F201FA67 +:10A76000DB84FD95177A282FA63C95E79739337C33 +:10A77000C5F71445FAADEEE1F978D5BE4F5FE5793E +:10A78000B55525084FBD3C97F4A597EB407F9D48F4 +:10A790008F170D5CEF44E4BB6FC99DD05FDF9B66F4 +:10A7A000CA9B63F77B1513B47BEE75BB07CFD16DE6 +:10A7B0002AF35555D077239DF373D5B09005BE97F6 +:10A7C000BC61DE85F97AB5ACDD8CFDD5EAF4D65AEC +:10A7D000DB2B66E4CFB51DA6083D32CC33F414A2C2 +:10A7E000A0ABDF3B28EE41F247CA253D1DB391D116 +:10A7F000F2A758CA5B900B5C5F2DE57A8E3DA9608D +:10A80000FCA72FF9942AFC67927793A590D2C9F9F7 +:10A81000C93DAF91BD321DE403FA670A96C7537D67 +:10A820002A83FC1C8379A3D7B344A2AF41768298D4 +:10A8300057C9C0BCB93D24E562D9546E6A4ABCC050 +:10A840003844CF729F6E32DEBF03CFEBC5B8DF3224 +:10A85000788B420AE289050D856847F8C9DED1DBAD +:10A860003FA5D6E6242BAC6F2A6B27B938E5F02B31 +:10A87000242701CF9FA09CF9359378F65851CE54E8 +:10A8800060C29F8ACF683CCDB66D37229C6667E96F +:10A89000F11130225CE7B807E189CE0778E3E0C91F +:10A8A0002BE5088B962305EC4B7E1EF9C157EF4331 +:10A8B000BFF74A76C821A7DF9C43F233DA1E899797 +:10A8C0004F979A63137EEAD0F2E9FA4CDC4FB88EC8 +:10A8D0008557EF5506D3C5F9C3EBD52C0DFD48BA06 +:10A8E000DC2FF2EB959744BE6E4932E9B9885EE4FD +:10A8F000F82F15A5EB90AE34F8BF615F4248057A9A +:10A900002B16EDAF437A9818D18B2183CD6D8671CC +:10A91000B7289E363506DE5DE96ED27F930C5E95D4 +:10A92000EC29E6C9403C03DE8B105E53AD9DAD467D +:10A9300098E749B3E747E8AF943137E1BD4CA75FEB +:10A94000CA6DD546E4CF72AB1EBF5EC27B857DD09B +:10A950007BC39F82F7E18877A93F86607F02DE2B69 +:10A960007262EC13C6C3FB2D7F22DEF5F8967CDF06 +:10A9700095602FB7615CB796E7114F7A73642B9699 +:10A980005D0D0574BEA52BCDF3327D6FE6DF4B7AEE +:10A99000BD2ADE9B58B80EBE43B9ABC0578EE5A6A4 +:10A9A000F50AC9CBC96FFB5BB13CF27EFEBD786393 +:10A9B000F3CB78FF585380B7DF7F7A0BDD2311DCB0 +:10A9C00022DA97B59763B9A98DB7FF38D91A40FF36 +:10A9D000BAF458B015DF5FFD109F87B4EB66083AF4 +:10A9E000EB529E7D99DAB5F37677BD6A4DE4C96E78 +:10A9F000DC4E9B2ED639E371BE4EC7873755BA81E0 +:10AA00000EEFEC0F98900E4E1AEA4B495EC6F1B766 +:10AA1000CA94F63C7CCE06B9C008DF409F23789EDE +:10AA2000E92E18626B0EB78B647E26E6895769F0B3 +:10AA3000B53587FB09B29E2B9DF17CE2C792C96EAA +:10AA400095F9A3A11F3205E300B846D2AF71F249D0 +:10AA500067173693BE9C3D5CE691868D2B60DCE2E9 +:10AA60004BFF7A632CFF7A9B18F794C87B97EF6BA8 +:10AA7000830506F43FBA9078E87EB5796FA25DD27F +:10AA800085FBC19AFB41BA0A78F9C78FDDFCB76D27 +:10AA9000E0ACDE6568360650E8E72B74DFC92DBDF3 +:10AAA0002C949A3278FEB38D2CC4F31DF8FC57B762 +:10AAB0009A776DD5D8E90BA5D898368AF448B5C0F1 +:10AAC0009394170B05BE80BFF7207F2FB236935D9E +:10AAD000B844C8F7352C48718A353AFEAEB37DF6D6 +:10AAE000BEC180F1B0683E6E80E970BDD0BFE35D4D +:10AAF000807FEDA3C976D4F30D9DD1F56A1F7DF358 +:10AB000018B7AFA2F9BC56F279309ACFF1A649E254 +:10AB1000F31F8EA5FD17799E2FC1DAFF7E8045D6E3 +:10AB20003BA0DF75FC9780E7FBC6A0DF62E079857C +:10AB3000A22CC7BDD0CEF57000F4B0F07348D45E3F +:10AB4000383E2788F4502CF857F271B1D0E783F4DF +:10AB500075A5DE8FD94EFC31499424DCA57E867E16 +:10AB6000483FCBF382A097DFF4927F0FFE27CE738E +:10AB70006C34BF6C55403E1744FC15C0DB3F23DEF0 +:10AB8000401E5B799CA29DA13C8B6BF7DBD6C5B4C4 +:10AB9000FBC18FA07D80C1F67E28CA8ED7E32B9E95 +:10ABA0005D3F80AF04B09792D08F67242FF7E17399 +:10ABB00008F91C20A7FF3D967E361FE2F5FA77269E +:10ABC00050BC40C6C725BFF5E572BBFA57595E9623 +:10ABD0008BFB57A2FFE377CFA67DEACF9897F6A924 +:10ABE00031CF2837469E04EE536FD2C4498FA7C594 +:10ABF0008E5B27E772BFE71BB97C5D794E6F4A2EEB +:10AC00003C4F99795CFC54A278A6F07D85EC81FAE2 +:10AC10005C4E4C10E55322FFFA547A743C5DD62BFF +:10AC200016F53EDA60B56ED2C815F70F2DCDA8AF78 +:10AC30009C85225F7D1DA7D7BE17D2766AEF699BE0 +:10AC4000965BF60D9C97B3D06BCEC638CB0B5C2FC2 +:10AC5000341AC366CC2BB9C1E1BF0AE1D4E866DE81 +:10AC600067B11F77D8BC00E0DC27F6E7FB4CDCDFE0 +:10AC7000E84BE04F39AF69B955DFC0767D7787493A +:10AC80003E0C94ABC2C4FFD3727D346EDF42F95DDB +:10AC900094FF969799F00FCB045F509C37465C77F2 +:10ACA000701C37FADE992673EC7D6596971C159F0C +:10ACB0005DD6C3E386B75BD9965CF87E474F26F92D +:10ACC0000FB52981D1768AE3FD7971D7BE61BDB414 +:10ACD000AEAD65FDF98F95D03E2EC57D1A7A5E2307 +:10ACE00039D720F9A43B9A4F96E40E6DFF431F1706 +:10ACF0001F02FFACC88DC13FCFA37E3245E07F8FDE +:10AD0000C877AA50EBCB312E746115A373AFF7BC93 +:10AD1000AE123DDDF38C42F74048FBAC41C037DE5C +:10AD20007AF0DC805B233FF0DC805BE39FE1B901DC +:10AD30006D19CF0D68EBE3B901ED773C37A0FD8EBF +:10AD4000E706B4E562B6B215E36C4D6DCC1E74F344 +:10AD50007304DAF6788E405BC67304DAF6788E40B8 +:10AD60005BBEC0381C2F3CAE529C1ECF1368DBDF8D +:10AD7000F5FAA42CA49BEE049E3FC602DEDE2280E0 +:10AD8000CB2A01173C67A0EDEF6CCA8D4718D0DDC8 +:10AD9000AADED573F13961DFDAA8FEEAD47AA243DC +:10ADA000D6CEE56E33FC47F2532D52711E9FEF5302 +:10ADB000584601DE1BAED39F3DDBB6A0E859138C8D +:10ADC0007E5FC734F1DA82C171F98EDC64C7499EB7 +:10ADD0006B9CA38DD344E8C0E609E1FADF563DB190 +:10ADE000E8A0985D954AF199232AC61ED8C7ACF908 +:10ADF00091698A267EAF8387252B9A1E12DCD1F4B7 +:10AE00009034269A1E923DD1F4903A359A1ED2BCC7 +:10AE1000632F0BDF8CCA68FAD0C3772AFC87F09DBA +:10AE2000883742625C09D68971DEBF147C7B75F07D +:10AE3000FD9C4D2BB7B9E973B5B534629F941C697D +:10AE4000A64D5A7DDC53C251DA09327E3999713FE1 +:10AE5000DD8AE72C0BD10EE0FE1BEA7F94AB27CDF9 +:10AE6000DC6F430A42397927F3933CBA53A7FFEFCB +:10AE7000B26D37A3FE1FB45EB0B8F0BE40FD7AD10C +:10AE80008E629A78925EFF2B3D4A28793C2EB74716 +:10AE9000CA65FF253276BCCA50E4C5719BF7739C26 +:10AEA0003F3A7ED6D2A8786F4C7B4ECE43C2458EB9 +:10AEB0006F61CD6A16D2F318BDFD15ED2F4BFF9AC9 +:10AEC0003AD5C4A3A57F2CFD133D9CD5E10564773D +:10AED0004DB24BBFB8F7367C2FFD61BD1F7AA57D03 +:10AEE000A9050125FCA382883D7983782E10F122E3 +:10AEF00058D687BF87C6D314F7301C6FFEFEAB9CB5 +:10AF0000482F5B9466A69BDFB117A11FD5D09FC1C8 +:10AF1000E32FFEA8FDAAD79430CD7B11F36EC66750 +:10AF2000A388A73576BF46FBA88DDD3C5EC0F645FD +:10AF3000E3456FEFAF659DE60265B0BD5FCF7AA9CF +:10AF40003FBD7D3F884EAEA0C777E4C97B3B78BE4E +:10AF5000001372A956C02B9E5F6044005F1BB9B7F7 +:10AF600013F8A12C6F72247FD6950E7E8C8A7918E7 +:10AF70006E73AC3C298697AA804DBAD2564D726248 +:10AF800065DBA0B88499F8A9FDF2EB9376C05FE584 +:10AF90003182FB883C37DF874A9C7BC48B9F4B7A8E +:10AFA000F3B5E73E9ACCFCBC216B8E3E97BF3ACFFF +:10AFB00020CF4DA94359FF60B8FE69F9F832FF0070 +:10AFC000E0B7460B3FB98F20D7F3C9E4DE27317EC7 +:10AFD000A826CFB2A25F9B9AEE6FCA73E2BD0CE1C6 +:10AFE000930ACA339B9BF243CEEF3BFD0EFAEF72FE +:10AFF0007D8C851FC17B6D6BF7A9E40FD6EE7B9925 +:10B00000ECA2F8FE5EFBC0FD09627FE37E1C473FB9 +:10B010002F99CF5CA116A5863576FABC3C1E0F1879 +:10B0200035DCB711DB95FC2E2F05E76B1AD149F7FC +:10B0300061F5DFC7ED6087CA6621FC40EF71BD6F27 +:10B0400033D2BE832329A0A6A01DB79CF1FBE73C09 +:10B05000CD1E2415755811C5695DF7A93EB4BFDF33 +:10B060005BB7320DCF29BB9257A515C2738685DF1A +:10B0700047E3520C3E7EDE74451ADEFFB1CCC2F7C8 +:10B08000E50BBE99142A047E7BC9CCEF197524F90F +:10B09000E9DE82FE3495E67366032C6D14EE7B7C4C +:10B0A0003609EF1BC8F9D23611E7932DEEB3A8CFBE +:10B0B000E3E7B7CF3E737112FAABEA251B9D6B979E +:10B0C000F4E7288CEDAFCC17F06874F27CF7F3C28C +:10B0D0007E3C2EF65B65FEFB3AB10F787CF4C0BD7A +:10B0E000604ECC0B694CF0A62EC678C451156FCCBF +:10B0F000609FD9BDA9696437F33CF675C27E382FCD +:10B10000F23DD7CD999989FE45BC3CE997F2B8DD6F +:10B11000FB75DD5329F34EE3C221CDC88C13E8BE85 +:10B1200025DFE5EABDF84735263C4F8AEFF1F2E529 +:10B13000DFCBE37E9BCC876FC47C7878B5EE85B29D +:10B140004C76993CE946BC875C935F837E1AAEAF30 +:10B1500011EF21A7FB49CFD1FD1CD80FDE1776A533 +:10B16000FB22E70B3837621E7986F6BD9BBF1FE8CE +:10B17000DF41DF9F12707BEA88A172578C79260E1F +:10B18000E3EB1EEB34FA705FF29A10BFEF335E3DD3 +:10B19000797E3BDEBCBA67866FC779637E66ACF1A9 +:10B1A000BE147094F3ED4E0FAFF6F1FDBCD155C94E +:10B1B0009AB2BD3F7FBE46BE4E11F8E9BE299C4FF4 +:10B1C000F700CCE1FE6B3C3C971A9B1584C31769D2 +:10B1D000FE5B50FEC97B8AF11E639EE711B82CBE50 +:10B1E000237056A3CE1D0C86B399BECBFEA4DC39CA +:10B1F000FDA84A72E7F45B821F99D7A694A2BEE22B +:10B200007C759AF1B8EEE976FEBB1F2BFC607B8261 +:10B21000FC58DE5137177FB763F5EE495B50FCE30E +:10B22000FBFB41FE2CCF626C3A3C576C8ADE1FFB65 +:10B230009C3D447A6ED5437A7DE633A39C5DBD3D4B +:10B24000BA7E2D7BE853B40F6A7576AF4BE85DBDCF +:10B25000FDEB1926F27E4A59E95739DFF428F34EFF +:10B260001946FA9FEFB74D16FBE9FAFA4FB8399C29 +:10B27000EFD9FDAF66FC29A078FD9E01793112FA65 +:10B280003DB7C14ECF6F0CF3CEC4FE970DF3570CF4 +:10B29000C338C4510EE70BF51756535CBA86DB0171 +:10B2A00016BC5C05FE69B9CD4A7EF40378BF18C0B0 +:10B2B000D962E1F685B4AB54F55E3505BE5FFB2F70 +:10B2C000ABD2707D8EA76757A2FFE17C3AC98BF89D +:10B2D000D85AE62D46F9BDB5CA46FBC43B0DFCFE67 +:10B2E00041AB85EFCF059FBAF610868347766E9BFC +:10B2F000897E86BDE76008E3126D06BEFFDA369DE3 +:10B3000089FBABF9784D3D555D38AFFC6A90F7D0BD +:10B31000DFD6026FB15DD33F13F652A3C045DFAF56 +:10B32000AFFA3EDE77F5A32364AEC23A4750FC6B1A +:10B330002CE37423F34BE8373134F1A273A07F98E8 +:10B34000E6DCF3D84E25644AA17BF5288E5DBF313B +:10B35000E4BA0DF5E7CFF87EAD9C9FE3A5EC991814 +:10B36000EF97FAF436CC6FC338B0B07B9730F9C79B +:10B37000F70B6A045D2F11F6EE6D491CCE2B9887F2 +:10B38000CE5DDD6A6529185FBEADBC7332DD7B5DC5 +:10B39000674A437B45C6BDE3E13D5E7CA6F1C964D7 +:10B3A0007E4F8ED23F1A3B398331909248BEBDBE4C +:10B3B0009F8787097E1E2DECB491CC8BFB2C8D07CB +:10B3C000AEA27C7C4B22DF5703F96645BC1E467D4E +:10B3D0000EEB5EF3624288EF1B07C57D382C40FB05 +:10B3E000310732695FC151E8A57DF7F3A6703EC908 +:10B3F00003905F0AE8CEBDC37A6FC1DF6169CC01FB +:10B400003B0ACAEF3EF1DE2D46A0C7C611E1D57852 +:10B410004FB8B2E3DF78796CF82496937628F3A8D6 +:10B420003C31BC5A85F2E81DA9F3A83D3A5040587A +:10B430009376B8E6E139E233227EC93C61BA1FA8AF +:10B4400071FF55066D7C70783EB737CF24F07A6770 +:10B450000AD81DF311DE63C2A3B5BF97A0E61B98FF +:10B46000F65E65B94ED98E65C5EEFF45A107D68853 +:10B470007B7D6624B1B604BE5F1140FBEA959EABAE +:10B48000082EC161E9025E61BAAF51F6A33FD72F22 +:10B49000C75D8B7A1BE5BA29FA1CD191615C5FC04C +:10B4A000389B689C226F31DEC7D3383FAF18F10656 +:10B4B000F8320A7C19B91FB893CF0FFA4D1B4F7A97 +:10B4C0006412E689BDF225D42F88CC5B4F1F6F0B29 +:10B4D000FA58D3CAF799FAD30A898E662471FB8F7A +:10B4E0009500FC408E8D16F01D9E9FC6E13780872B +:10B4F0004C85FA6F15F0CBE3F5BFEA7A4F7E4DEB42 +:10B50000D5E0C98B79C7AFECBB9AF024D7C3D8B6C6 +:10B51000A87ECEB4E8DA4DE579298DE985D4EE012F +:10B5200071BFBEBCAF18DB1540BB19E5FD93901F82 +:10B53000E47D6D2C309D9CF57A212D06EE5FEBE4C9 +:10B54000F9296CA497DF43347F6E89589F5DACCF97 +:10B55000AEBD8F6E800FDFEECFAFD6DC472DDF0F95 +:10B56000C07DA0BFA289A2BF287E8ED51FF2453C18 +:10B570007C64E573BAF88BE143CE5307CF0138EB17 +:10B58000E627E1897C4CED8AA2F949CE3369008F28 +:10B590003A7E2EF813C713F9FD0D7F25F221DDD178 +:10B5A000F4DCD05D60C0FD53D9AEADB3C587725E2B +:10B5B000C6BB2DDD5501D47F4D3D6594B7D9F0ABA9 +:10B5C000679E0F40FBB5BFF8410A26D39E36B6BB37 +:10B5D000D0CEADDFBD39C58BFB25C6400ACACFD35F +:10B5E00041B532D639C0C67C45FAD16447350A7DAB +:10B5F00073E6A9EFDE82F0F8B7DD263BEAD1A63D7F +:10B60000969085E2206BC88E82F2095E7EE053F44C +:10B610004B9BF645DB496B7FFA03979BE829906BC0 +:10B62000C0332E2C94CBE0D9D861F2841C3C9E0808 +:10B63000C3B026D6BF05E7A76F8FF3F802F0DED4BC +:10B64000A92EC7F3BCFAEF2049C80E6BEAFE2ED92B +:10B650005D4DDA3803E0A1368EDD75477E74BEB5E8 +:10B66000840B0B3AC9AE69FDD90FC79FB0E13D9A73 +:10B67000BF49518AB4FA7223C1E942E7CA1FEF7782 +:10B68000C7D7ABE7D12EB068DB71BCBAF729B427B6 +:10B69000C17AF8B3DE144A413FBF7EA7C9039A9727 +:10B6A000D53FF39327713F84BD6BA17B0FEA9E3991 +:10B6B000FCCE7550AEEB3239E6F2E9DB1457043FAD +:10B6C0004D6E6E9F487CAC7DEE30DD2F88EFD1AEA5 +:10B6D0009578A9EB3A6866E306C3AFBCF3A0F8BD62 +:10B6E000051D7E3A4FDC48F778FEECA219E9FAF422 +:10B6F000018565160C6E5FBBF3700AD21FC209FD8F +:10B700004B89A701BC0DC257E896FD25548FE21A5C +:10B71000F1F0E6CD677C9FE757CFFC1C7FFFAFF6CB +:10B720009F2C1E5C7FEDCFEF4DC1757C6C6CE6F4F9 +:10B73000FDC4669717C6AD35055C767AF2F7B53B62 +:10B74000EE23BABBEBE87D2EFE3B1ADE6CC3545AE7 +:10B750006736AEEFCEC717D2FA56333FD15DED1341 +:10B760003C3EF1B9F81D063D3E4F0AFEF87897853C +:10B770002E2DFA1813D1318FF02D55E4F9DECDB40A +:10B78000F75780C54DE5CF457CE0C5017B805999D1 +:10B79000262EDBD4F1402FE2E7CC306F26EEAB0152 +:10B7A0001C02025E0ADEABAB1EADC8E4F8616EA3FC +:10B7B0008C2B83FD5D8EEFB17EAFC99B303EAA9D81 +:10B7C000D8AFE7E3CBF804CC3B11F7FD3E76C53E9E +:10B7D000B7E5182EF99FF5322D7DC5E3F78E078961 +:10B7E000AE3E7B9BF34D63B0AA92BEF79A4278A41B +:10B7F000B83178B05A21796089BA6F69802E3A4C95 +:10B80000829FA3BFC33C8D8A16BE07785EEDEAED2A +:10B8100096A87B102274638EBC2F88F0A7F4A3EE49 +:10B8200012FCAF5FAF5E1E9CD0C903F6B87348F739 +:10B83000C9D49B824F3E86FC0BFC8A7E66FD332674 +:10B84000F2F3CFEE7DF99D5B81CECF764ABE8D9629 +:10B85000AB7ABEAD7D76328BC5B7676D1E16936F22 +:10B86000E17D4CBEB545F669DCECEB93AB77C59159 +:10B87000AB89C3C57ECEC03996A254CC753FF35474 +:10B88000DD708A0BE8E02AFD59BDBCECC877C7948F +:10B89000970CAF9ED2C051C24FD2E3DAA71B689C6F +:10B8A00001BA957429E976802E07E55746C151FF04 +:10B8B000BD57C8A38173431BC14F413BF6D72AFD37 +:10B8C000FE491FCC650BC0BD6F6F01ED836E167610 +:10B8D0007E9FBD3F05E37A9B855FD18FF1C4D4C8BD +:10B8E000FBFE049137E0EB4F49D3D845277AD414B7 +:10B8F000B4E3C2C1D8BF232BEFA70CC7F99D597978 +:10B900007EA942B5E5AFC7386D3BDF9F5CD5B23845 +:10B9100005E3197D3D85F43B4277BE0EFE2ECCB784 +:10B920004FC635035E637669E45ED3532C40FB95C6 +:10B930002B7BEA68BF501F07596DAB4EC5FD407D9C +:10B940001CE42ECC83C23CE4C7A3DFAFC5F808E2F9 +:10B9500049474F7EA4A7ECC1F4543D5CF065312B00 +:10B960008EDA7F1572AD422DFA3EDA277DE0B7639D +:10B970003C88A945BF457DFA39FAF1C8000127D1B5 +:10B98000699DFF94CCB322BA9674A7F7DFF5CF7305 +:10B99000BF7CAF14CF03D53FFFFBF13F82E7B9E790 +:10B9A000DF1DFD22967FF58FF9BF6783EB971FF8A8 +:10B9B00003F92B7D072C349FBE03AFE57F1BCBFB28 +:10B9C0002D1E9C6FDF460BFF1DE803C974DF74DF7B +:10B9D000301E676BFDF5C5F161D2539B7812F27092 +:10B9E0007E4FEC859EFF781FEF55BDD0637163DC01 +:10B9F000A1E94012F9E14DFB13E87EF8BE5F5F2C30 +:10BA0000D5C68BFEDCF5348AF3167DC9AC06F35B34 +:10BA1000FAD2B8BFD6F4E2B53F692940BBF420DDC5 +:10BA2000575CFED27F8E47F9D3F72CB72BC03FDF90 +:10BA3000819B88DF1DFEDCF74DD978DE88915F7D24 +:10BA400095FB33F2AB07C385C3A10FE080EB02B8CF +:10BA5000D03DDDF1E0B1EB7F2D3C3E257FA1BE67FF +:10BA60000AF151042E0AFFDD919EE4A055A1F5F3E1 +:10BA7000F7072E8E473BE96C670BE9FD2BADFBE02A +:10BA8000FFB9752BA1A1AC3BFCBF76DD9CFE570F27 +:10BA9000E7FA49CF0783E9FC57DFA4F2CF933D349F +:10BAA000DF21F23F6EBFA27CFFEF5EFF7F01F65207 +:10BAB0009D150080000000001F8B080000000000A2 +:10BAC000000BD53C0B7454D5B5FBCEBDF3493249C0 +:10BAD000261F2008C19B2F51F2194802E1A7938429 +:10BAE0005050C409488B157000955F4822D89A566B +:10BAF000DFCBC4440CD4D547D5565BD135A0509E7E +:10BB0000CF3E530C96564207540AADD5D142054D4F +:10BB1000E948AD480D6404157CA5E5EDBDCFBD99A0 +:10BB2000B9378988ABAEF55EB2C8F1DCF3DB67FFED +:10BB3000F73EE7586F035F8713A03711E6EF28C47D +:10BB400032053C900ED0F0E2C4A75AB20056777E80 +:10BB5000B408CA00EA764F0019EBD5BFFE477198CA +:10BB6000FAEF903CE27B62C021E1F73D9F89EF7BD9 +:10BB7000CE1503961FEE90827212D6EFB32F0FD020 +:10BB8000BC9930BF03CBD6AE73C5612C01DA00CAB5 +:10BB900001AE546D5C9ED9FDF763523A95761570EF +:10BBA0009D863D0940F337FC2A2E00387F6FD7B9B8 +:10BBB000F13E9CF722FD5C0BD0D38C538C8ED6CDFE +:10BBC00065CFCE3F8DBF07BBD4BDF04EF1E358F635 +:10BBD000BC7034FF45AAFFE2AD51EF60597FC97DCB +:10BBE000EFB52DC5F63BAE5419BEE8BEF7DAA08816 +:10BBF000F67B7011F5EFDD93E8B267117CFF180555 +:10BC000031FBBFD4BEAFF97FBA6F003FC01000ABAD +:10BC1000EC7564237C0F4230A462793FC08C0E67C0 +:10BC20007F785651E3101A0721180A2083F891D320 +:10BC300057CE82242A377C2417D3F83933B2100E1A +:10BC4000BF6A716F55A98785F1D03ED21DD880702B +:10BC500081E25DBE19EBD62BEBDC1B78863B01C67F +:10BC6000037CCBA1CD3774D60C09E76B6D41B8705E +:10BC70009ED62116572BCEA3A896A0BD98CB77A908 +:10BC80007C60E87507685DC56983A036F622FE739F +:10BC900002D60BB43AAE179F1B53C77F71B0CFA526 +:10BCA000E0FA716E0502B8253BC48CC7FE33551708 +:10BCB000EF331E027E97F3F2F1F4F825F064C68F9D +:10BCC0008EB77E780270D07885FE8BF69FBE2144B9 +:10BCD00072A880E20F8BFD481725C2A73BC381F3F2 +:10BCE0005993EF706F90F8BBAA8CD7C659E8CF1A5A +:10BCF000037E117F9EB8E2289E63E6E3FD9BF17C04 +:10BD0000B9F8D5E912077398CE71239DEE00C27F72 +:10BD1000BF2AF07E3FE25D92A2F8D5F166A6433DD0 +:10BD2000F14E7914FFD1728AEBFD314C48B888C8C6 +:10BD3000F557414123CE53234F09FB71FE331509BB +:10BD40006E3BC98B0441691C969543AB00F7D193B8 +:10BD50006953A89C1AC13DC5C07BED79072831FB0A +:10BD6000AB841443BD27339FC7573B861BC6F50CD6 +:10BD7000AF70D0F71A5796A1FFEB7149C55042E357 +:10BD8000A6CFA0F6AF655C651837FB78CFA6C5587F +:10BD9000DE2885CB88397A0E2EA8227CCD54C71A8E +:10BDA000FAED42B542F21CA991035B101FB5527027 +:10BDB0006831E2EDFA828946F8249846FBACB3205C +:10BDC0006B61BF1BDC9586F61B2B661AE6ADF5D4BE +:10BDD0001AEA754D9F82920630B9E90228A50063E0 +:10BDE000831D86F1A5077619FA27BD0A722296638C +:10BDF0000FA9AD5496768752897D6D690EBF2519BE +:10BE00005938ECADC6EDC0F80F1A5FA2B2C981F87F +:10BE1000C0EFE7E24489F4623EF71F8B0BB422BC0B +:10BE2000E72C011FE1E16E39504065FC883B8A2117 +:10BE30001BE064C6837232C10FBE632AF2C1C48F95 +:10BE400003AD54BFF64287EC233DBC5DF6DB4A8868 +:10BE5000EEB3127E4F7AB74302A27B9DD3E20990E4 +:10BE6000DD4AED285E1BC35F1F7E1B6EF516F6973D +:10BE7000D74D7995119ABF2DC3B3712FE9CDAA3F44 +:10BE80002D92B3FBF703971209EB78C9A671DEEC8C +:10BE900091384E4E9CE620BD1E5F2DF3BEE06BD662 +:10BEA000C0569C679DC51DA7093FDB57D774EB663D +:10BEB00092EBF62CA11FE27F07AA84F0C7A7F9E452 +:10BEC000221AF71F126C85E87A4B2B80F791926546 +:10BED000117CAFB8862C2CA2F1895C1F5F21F00881 +:10BEE000B32C813C9C72EFD413FE44C443FC8D966A +:10BEF0004CB4409054E1F95D2ED6C787DECC94490E +:10BF000096A0C042FA640DAA37D227C31ECC7A7419 +:10BF10001F8D3F60853C2C962EF09CCDC5FAF767AF +:10BF20005940C2F6CE8AAA84A218FC259D97402DBE +:10BF30008DD6DBB3548623490903C971D27985DBD9 +:10BF4000A129DF42FA465F276981FAD6DA9875405F +:10BF5000F1AC22B8375CDDAD92BE4A3A22F6091048 +:10BF6000CEF0E2D6FE86765125422AE18C8589FD07 +:10BF7000E9F0B7EDE5292AD231ADD29DE2A6F2670C +:10BF800088E4498C673FA9BFEFD39F2BA8F6686868 +:10BF90001AB66F271D28DA83807CBCC1A6B5930A28 +:10BFA000C17A9AA4B5FB1FF54E233ACAC6FE25D91D +:10BFB0007DFD3D8E8CE8FC53363F1A6A2BEC8FD703 +:10BFC000BD53ED6C87E3910FECD877CD5585C360F9 +:10BFD000003B11C56BC225F09A24F07A01B53DAE45 +:10BFE000739743ACF39EA48E22FE7AD882529F03AD +:10BFF000F092CB579D554EF0078BE8FB9224CFB0C3 +:10C00000A9C86F9D36CFA8EF901EE98A736FC171E2 +:10C01000B5777EF85813C9F1ECBF15A007039D8AC8 +:10C0200027611CAED3E0FA94E5BF462E4C26FFA64E +:10C030000F8FC4BFB8E6F72DD13AE983A4285E3D3F +:10C04000B9D8BE2106CF0E07E92B51FFF7AC67BC6C +:10C050006D44DFDB1C8CA7B59A0CB5A5C0460BF26E +:10C06000FF59D7B6AF133F9CDD6E05F2933AA99105 +:10C07000EC638183E508D2C319B5C8F7456F58BC96 +:10C08000E48775237F78883F1AF30DF39D9DF25660 +:10C090006A118E3B9BAEA4127E56866D8CB7850AC4 +:10C0A00004EDA81F3BD36FABAEC4F6CE232AB777FF +:10C0B00068F33C9BE7599EC576659AEB7DDC97E477 +:10C0C00099245F1C3338BDC862BEAFEB43C4730311 +:10C0D0006D3375703E68AB7404C8AF6CA8682924D2 +:10C0E0007BB026257F18E03E1AA6496C5F1B9A3E5E +:10C0F00066BCEBF32BE76550D3A275778ECA7650FA +:10C10000513CCC0FCA791BB7D7359D65BD8DE06416 +:10C1100091DCF4B408FDB6D10AB7D66259F74FF9ED +:10C12000D65AEC5F872CC5F601F6D9D6C4E83FE8AD +:10C13000F8A84FCF9720ED1E9EF5663CE9D55AC969 +:10C14000350F700F87B36DB5CA70ACC7B9E64958E3 +:10C150000F6CE9F5723DD335CF82F58EACDA5A65B6 +:10C1600022D687BB7E687103FC69CB4AD13FCB7571 +:10C1700098EA07B31E10ED89820F7E98755BADBFFC +:10C1800090F8CBC97839D39EC0F231189E9735BD4F +:10C1900068C04BBF7659BAD54B7C355FE8C153EBCD +:10C1A000476C66FF2737944F6B6E273D8B781B8A51 +:10C1B000B4A9C07FAFA0DC3B100FE939E0B160FF4C +:10C1C000F45FA0FDA1FEEF854611FE96FD222E280C +:10C1D000213D563FF1928DECCF1259CD27B9FAF59A +:10C1E00068DF7F935C9D4E0C717D59D31E86EB1FDB +:10C1F000B92EE19FB822855EE4CFE5B0D146EDCB04 +:10C2000041394E7602B528FB312B9D2FDBC80F5BE1 +:10C21000F9B4F57838C68EAE82F03192D3BA67ADF4 +:10C22000C7C331F616687C0C7F1DB70838140D1F84 +:10C230004BE4D0229B806B2FC1B53A15FD7999CC88 +:10C240004368A88FFDA0BA028E4332E281F86EDD0A +:10C25000156F17FB06B07B1DCD68E751E47634EF10 +:10C26000E2B21DE724BD334C09DBDC384FBDA69795 +:10C27000C7878EDB2066FC31CD7E25EF92B85DD777 +:10C2800017D176619FA0D033D68270AC9EF3EA14AA +:10C29000A28B4ECF6B13A0232E95E9E2D6E8E226BF +:10C2A000BAE8F8477C962A38EEE50B382E6B20BEAC +:10C2B000D0F12FE0ED8C17FA22B2338EFD2433FC3F +:10C2C000E7343ED0F791902DEA83C19F909D28E8F6 +:10C2D000FA2F863F215BC8B1791FBA1CF7C57D2DA7 +:10C2E00003FB293ADC97CF6721DB17E1335DCFD41D +:10C2F00083AF80E6D7F58A8E671D4E1D5F9D14FFC4 +:10C300000C00A7D2F44BC37E945015050D50909DA0 +:10C310002DF458C74C203A284DBBB9DFE5EE47D77E +:10C32000B783ED4BD7B3E6FDE9FA56DFA7AE77F555 +:10C33000FD4E4545C2FA10C3768AABAE3DEF33F8E9 +:10C34000BD95B0C2E017573BEE34D46B5CDF31F4DF +:10C35000FF5A468BA17DA6BADED07E7DC10F0CF5BB +:10C360001BDC3F36F9ED9B4D7EFB7F1ADAA7844339 +:10C37000EC67BFD63C031474ACAEF920C2FE76B0B5 +:10C38000D9C5F57DCD195CBEDCACB27CEF6F2EE07B +:10C39000F240B39BBFFFB6B982CB579B3D5C869AF8 +:10C3A000BD5C9AF5C2ECE7BFA1507C5211DA584D42 +:10C3B000AA7C5B8EEFEE6CE487D72D81D644C4D384 +:10C3C000846EE18FC372B33D3E77EC1EB2EB2E9BC1 +:10C3D0009BEC61DBDE89923A803F9784F6CE13C3F3 +:10C3E0002F49B3C2E021BF07CDF340FC756FB6857E +:10C3F000E9476A1F50EEE63BC09A8EF2367FBEE4F4 +:10C400006E15E6C00FA95C067DD83E5B013FD9FFE3 +:10C410005AA712B42731685E07C2394F8009766A7D +:10C4200027FB9D9EA690DF7A137D4478658F0CD7FD +:10C43000E0F77915BFFB8CE2E46F3A3BACC42737D9 +:10C440001FB8EFD43DD80E6DFE72928F3EBFC1FF74 +:10C45000B6E572FC867BB3855CF54AEE9087FC9D61 +:10C4600014C51DEBFFEBA5375BF8FFB35BFD721244 +:10C47000E233F206B01FA7CB23EEAF9DE0D7E5A2D3 +:10C48000D6A504472791BDFF4135F5AF3BA4325EE9 +:10C4900074B9D0E5408FFB7439A8919F6DA5FE67F4 +:10C4A0008E00C7CF137A7C1F3C4FFB34F99D15914A +:10C4B0008DD514875D2A4E9C74BEE325EAB7A7D9B3 +:10C4C000C77CB4BB793E97C1E6E51A7F3672FDE5BD +:10C4D000E626AEEF6FF67379A0B95DE3CF8DDCFE93 +:10C4E0006AF3635C7FAD39A0F1E976FEEECE11F61A +:10C4F000F7E350F530E2BFA7B245DE061C951C47B6 +:10C500008022CA2FCA2775192F0A7FCAC41F66BE88 +:10C51000D0F901506F4888AF6FA29D25FB700BF8D2 +:10C520008B1663397FD946EB64E9CBF3C54A671BA9 +:10C53000FB1F667DB80282ACEFFAEB77E1FF5F4A42 +:10C54000BFCB189F92BDD2F5DF6A08F37C76F94E17 +:10C5500037E54FBE3ABBE2D2EC0A2CA6FE7D7176DF +:10C560007CF722D972E9383B7BA418AFC7D9E83FE2 +:10C5700002D9E5DE80CC7EF5F2AC8D491C675744CC +:10C5800092C80F58D125333D30CE548623DD9669AD +:10C5900074EB81E01F892ECBA62CE33CDCF24DC668 +:10C5A000FDAC74DE941C5407F4D306DC673D3CF804 +:10C5B00011E5E3EA357CF17784A7A9FBE6992FC75B +:10C5C000F4FB243B319DF355136002E103E177074F +:10C5D00049CE0EC92C6783F1C5698C4F88CFCF3502 +:10C5E000CF9FF932F2FDE90BCD1C7FFD33FB811F9C +:10C5F000F8477E75F45A97E74DC8E1BC5BD846F220 +:10C60000A3D36F1DE948847B5D95234081766FB984 +:10C610004BA1F57B258F4C7987DE77C1DD82F8ABA6 +:10C62000DCFD9B23241F950E279F1BE0267A62E9E1 +:10C6300039F190AFD589FD26BCEA91C97D2F7F39AC +:10C64000DC4ADD747BA3DB9FC93D11D9C779815CCE +:10C650009623C0D8E262CE17972373BCD94AF1263D +:10C660002AA4B3CEE90CEFD920B8E97B348F25F2A8 +:10C670004B932F78E424846F9D161F4E7CCFCB7094 +:10C68000781C2AEB17BB164FDA332CF82D8A479704 +:10C69000CDB79DF29DF0AB38CEEB9AE19B9023F4A1 +:10C6A0007872AA7702E3D7A9E653DC5023F76C7BB4 +:10C6B0009CF8A133C14D791BB3BED5F5DB607E7B01 +:10C6C00083EBEC807EA45E3658C439C1B86AB59459 +:10C6D000E23FF22F292ED4E34473FF9ABCAAEB0861 +:10C6E000BE1A794AC84370B92C9FCBA70D4D1F7D48 +:10C6F0006E9CA6AFDFD055EE5A12930769CF91B466 +:10C70000FCAEE27ADF11A5DB17A5EFD4C87C83FD70 +:10C71000F9BFEEAFCD46374742192A9202C28F00C9 +:10C72000E14F2C8010978B20C2A50F3989CA25E0D4 +:10C73000E6F236F07219CEF535E790BF608D0C2524 +:10C74000393EF5C2DF0B892F4E5D33D995A546EDF5 +:10C75000AB6E6F2FD7AEC6D379D200FCF090C6B7C0 +:10C76000BADE1E943E26BDDD3B16F5834C79A1C88A +:10C77000A21729DFBBC7EEDA1AA31FC06FF4170791 +:10C78000D317358A88DBB75BDCAF531ED1FF5A1A4B +:10C790000C245F7A399BFC49E4C7E40561251BF949 +:10C7A0002D3FD5F334F1B3FF812929AC87498F5C44 +:10C7B000897478579CB7C00A299087FBDAD529EA93 +:10C7C00045B7A70424B6E741A6C742085B691FB76F +:10C7D00002B0FE5C0C2A974BC1C374C199138A51F5 +:10C7E0009FDCDEA98CDB807095A446B249CE8A26F8 +:10C7F0001E4D9570FD62F2639D9C6369277F4387A0 +:10C80000F3448EF0632FE67876115D4B52431B1E86 +:10C8100026FF6EA705C8BF3B31F13B77408C7D1CDE +:10C820009157D545FB784E12E77CFE2EBBC88F4151 +:10C8300064A837C6AF0EE756BF44F3FD568BE7A199 +:10C840007B3D9FFFD4BA044E61DA10C6018E1B45B2 +:10C85000FAA7BF9CF9795C09E97B91EFF34305AF37 +:10C86000CBF577724ED4B689FDF8C9AF1A91E73B84 +:10C87000447095D850A511FC4FD8035BD8FF691CB4 +:10C88000457988654FDA2D648F8FA23EA5F3CE7768 +:10C890009A1D5CFE09E3142AFF8C710A95EF629CD5 +:10C8A00042E55F304EA1F2F6F3635129231D723D3C +:10C8B0007F617D39C83E06D7177ECDBF86F9039DBF +:10C8C000D3756B7C5DDCF9DE7D09C407BB64771E24 +:10C8D0008250B453E17CC2E9DD130272562C5E7DB6 +:10C8E0001182A378D71F1E9A5C46E3149784FD4FEC +:10C8F000EF3A3B94E31F137C7DF8E8B2097C68F0C3 +:10C900003E9712DA40E39FDB994D10A23E00C187AB +:10C9100044CF01F261002DCC27CFE708FFF6467B1C +:10C92000A42CF65C12C8F453DE51B31735F285A47B +:10C9300070A1967F9D487C9DFB3AADE73F20431E4A +:10C94000F3A731BF50902BF0A097455D362FE545FA +:10C950009EEBFAE39CEB110FB327CD2C9763E42DEC +:10C96000237788E837F1B39F3C9CCEFD5DB4D4CDEE +:10C97000B0B9C685FD6E71EC7D8550B0D0F56E4DB9 +:10C980000AD66FCD90F653B958CD9A9EAA12B80127 +:10C99000DECFD282CAFDC462B3DCB536B2AF952415 +:10C9A0005431FAB3DA914027A07DF51A579AA1FEC7 +:10C9B000B58C1186FE33D51C43FBF505630CEDFAEF +:10C9C000BAB3DCA5867E24AFE4FFE23E98EEB05514 +:10C9D000E6F394A29D1FBFBD8AF77F7319EDBF17C1 +:10C9E000F1674307E1838AF53F7A98D4C6CE7D4943 +:10C9F0007CBE6AF233EBBA9EDAEF5107F7333F8120 +:10CA0000DD03FA67F583F8675FD4CF44FDF110E9E1 +:10CA10008F92176EE2F3F2E7267E76854AFE722E3B +:10CA2000FA9F884AB3FFD9ABF99F66FEE9E3534901 +:10CA3000157C7350667DABFBA166FE01B84FB3E376 +:10CA4000A2BC5C399FFDA6B03B7F25794F8BE56B7F +:10CA5000AD34E5154A6C680728DFF77B19B6D08737 +:10CA60000B08878EFF9C28DFC36D9B5F195EC6DFB6 +:10CA7000FD89B864BD966768CED5FC8EBABDAF0C93 +:10CA80004F8FB6C35DEF1AFAC3BDD27E43BD2DCB27 +:10CA9000587FB0727FECF8C1F4D0B24D77DA7C9455 +:10CAA0005F7E44E41BCDED3A3C35FBE23CA42F9580 +:10CAB000DD768E6BEA5D1ECE832883E44174BD7003 +:10CAC000B30C8D03E9B70DDABCB3F6C581FC25E6DE +:10CAD0003D8ABC42F0F87F21ECCCD1640F7863D65C +:10CAE000F961AEC8039F4AD9F86F9F62BF53BF0474 +:10CAF00037A1FE548AD0B7C59D272C16B213F182F8 +:10CB00005F8A5D614B2ADD53599EE0A773E086156D +:10CB1000897E3AFF29C98EFCD181A47F2277EE431A +:10CB20000EE4BBB72D1683DDE9255D87F56D4FCF8C +:10CB30009943E76DD7EF8B0B5ABEC47EB6511E9357 +:10CB4000EC549590F745C437FAF916CA47C3FD600F +:10CB500038EFA2FD53FD58EED7DF7C84CE6B0E0A72 +:10CB6000F9C766A739AEBC2526AE844D427E1DF8B6 +:10CB70004BFECBCA9737DA28DEF9AAE47E6FAE33D4 +:10CB80001A5F8EEE2FCFBABC371C16F27E66F727DF +:10CB90006F925E3F83F62E56DE757CE972DEF0986A +:10CBA000CCF2A87F3FBD5B9E111800BFCF6A7C000E +:10CBB000AE7CC3F9D79AA9E7E6905D5BD3A5F0B93F +:10CBC000DE60F6BAA1DD78DEF5DC1EFB72711E2C8C +:10CBD000F6D1ABDBD3AE4F522B0B45D9C2E7AE1B20 +:10CBE00035BD23FC18B4A3D674B2A3B512E7D10E99 +:10CBF000770DE37B15872508AAE3788A9B1C48B745 +:10CC0000B9623AFAEE247F0C320A145A678E46CF84 +:10CC1000B95A7E675ED7BC3CA2D71F3B971CF66013 +:10CC2000D327B939BCCF6F809FFDC1C329DE4CBA71 +:10CC30005F30BB55F0F7E194480FE5830E4F4D9000 +:10CC4000E85C09E76F8BF5F70E5BBD998DBC2FFD96 +:10CC50009CF16AF962C265C4B39A3E447AFA25111E +:10CC60009731FF2BC31F64BE5A0181FD1E5CB7DEE6 +:10CC70001D64BF741588F8DCEC97D74FF9D0467661 +:10CC8000C11C4756EEDA7B84CE2FFAE5134CFC7AB2 +:10CC9000A9FC81397E1DCCAFCF4FF566E4C5E4EF2A +:10CCA000CCFE799F1FAAFB515B13F87CE7A5A98FE7 +:10CCB0009E5E85F5BBB626B8285E3EF9A4DD4F7AA8 +:10CCC000F9E4167B40C2F693A9916E8A134EEE28C2 +:10CCD00072E30CB0CCA2FED7B364D79FB1325FE051 +:10CCE000CA86FB096BA6DECDF7F6D66C4D94E8FE3E +:10CCF0000C6488763D76937F9AC87EC18AE787F375 +:10CD000079A56E5F483EE87CF98327E23CE4E49F26 +:10CD10003C303799F2763D969FF3B93CC8F71EA395 +:10CD200073F755DB12C7F1FD8B4260BA2DDF721528 +:10CD30009F536E547C9368FFD53FBD6118DD075B40 +:10CD4000F1872140FBE9DDFD3C9FE345FDF481FDDA +:10CD5000BB33BB7392A1308A273D9FD7FE748B975C +:10CD6000E85E2EA9E2BC051A3D23882F76D502CDB8 +:10CD70003B4E16F73D23EB13D82F35F35D6D9EF038 +:10CD800003EBF4BC411A3832487E7CC078E85D3F42 +:10CD9000660B9D6BADC84BD5EC74247F4ECC7DC229 +:10CDA0001AB9BB9EE2BD339BEC9CCFE8891BF83CD3 +:10CDB0006B615E0AC3B7CC613CFFAE6FFACC582FF3 +:10CDC000040FE99D71AD6AE99D58AED5F0DF92E997 +:10CDD000F5E5E17A2B3B7EF0C2AB8C974DDF7E9B75 +:10CDE000D63DE01479945705FECCFEFF3287C85734 +:10CDF000006C6678F5EF279E788BCF494FEC1C933B +:10CE00002FCE7F43EF3F9EC5E7BEC7EEC172C781FD +:10CE100037992E6678FB9DDF4912EFB78EF6914663 +:10CE2000E7B4DE6FE7F1FD1D11B72DD950C4F8D37B +:10CE3000CFD17A4F0E1C9FE870EAF3EBF0E9F3EBE9 +:10CE4000FD5A357A5DA7C507A76CA1D37C1EFEC22B +:10CE50001889F2747DDF5343C52931FCF255E5C5CD +:10CE6000BFA9E5358E585ABE65A3FB6D1D0F5B7DCE +:10CE7000B17AEF32F3E17D7EA00754D750614AD8F2 +:10CE80006EE1E694A1746EA7D54918B03E45034FF4 +:10CE90002278E8BE9F56C24A5F06E7BB693E99AE5C +:10CEA0000F06B8DE5AE956A9BC56F22AE2BE5680F1 +:10CEB000F9723A348EA47D581C613EDFD2EFABCCC0 +:10CEC0004B59774316AED73604D6911FD3661572E9 +:10CED000E15F9CC0F19B8E27DDCE80ABD0605FDA36 +:10CEE0005CA02A38CF7C05DAADA9A2DF9588E7C31C +:10CEF0000796BC427EC25B4AE3105AF7A8F3912220 +:10CF0000C942FE5D209162C4B7DF7CA6FCF7D8F76A +:10CF10001DF04C7522FFDCF41B07EB7D733EE276BF +:10CF2000F0717D1984AD1FE3B83F4FFC9FADFB202E +:10CF3000BAAF3F4FFA7427C507B7A4DC574EE3F5E5 +:10CF4000FB93E67B7A275D4EBECF67BEAF7723F8B3 +:10CF500042C4CFE72CBE7A91FF689C40F6B737C534 +:10CF60000612F6EF1DA2E1E314303E7AADDAF88F37 +:10CF700054AE97558FE3BC229C53591F4F36D99B13 +:10CF8000B2311611875D14FDA7461483BD292BD13C +:10CF9000F2367F57D92FBDF6BCF2B9F6A82E5FE462 +:10CFA00059CAD22C8D03F98756ADBD1582B2D88FE0 +:10CFB000F01326F7F1954726FAD56BF57AB267C8D4 +:10CFC0004FBD490E3F5D509CBC5BF0D76425B897C0 +:10CFD0004AD4AED0447EC52EB4773A1C74D697316D +:10CFE00086F96092CE9F38D702ECB74E6AE4B8C596 +:10CFF00041FE0C961BA410C3710D44B8F46876BCB6 +:10D000000ADC5C4E032F97C89F5CCE404B42E5750F +:10D01000D0C1E52C0809BB7F75B095ED19DCEBE2BA +:10D02000F86FE6320BF91B65DF18385E187D493C56 +:10D03000A0C08DBF7C3C4C0794BB9C01F031B280FA +:10D04000F587191F66F99C0A6199E59314430EE56B +:10D05000095496D36AF070BDE60BE2A122EC533876 +:10D060004F63C647F5C07CE1D6F0F1E77C10E71FBF +:10D070001A9D96E6AB5CD7E985729541FC6FA6A335 +:10D08000FEBD2CA1EA2C5D29BF7E5BE65CBA1F5574 +:10D09000565AB59654F282FCA2B9743FAA6C72D566 +:10D0A000F37474B9685BB1A89754955ADD68DF5A78 +:10D0B0004AE64EC3FE3EED3E31CC17FEF55D9ADFEB +:10D0C000E26BF996DB8572E2CB74BA697F0E74EE7F +:10D0D000E95E8A9C23CEF946CD08EEB362BFA38AEF +:10D0E0006F7A3E9DF73982492AE2FDAE961ABE7FDD +:10D0F000F6804DF4B7DB457E55DF177EF7C7617DBF +:10D10000C78E316BA5ECC1D7C779E7E60F2138F29E +:10D11000FC24AFBE9D925B50B26AD87C94CF9E90A7 +:10D1200015281FAAAF939EE99B4F7080239FF3643D +:10D1300023347FA667C798314497A5F9DA7DAAF40E +:10D14000AC52C25B43A67729CDDF9B28F86B29D16F +:10D1500061C8E0E5F7F23D8B697EF3F7DEBF2200A0 +:10D1600038FEAE7CDF329AAF21E102DBF7D363FFFA +:10D17000B02E9C15E5530989B400F7DDEA81808D56 +:10D18000ED8076CF5C3B77EABD1DE7413C94797D2D +:10D19000ADA4D2262C888C27FD89F3AEA1751B6C1B +:10D1A000E1516371DC23738FD9049F8D147CA6E950 +:10D1B000A1AE3D07EF1921AA5E8891AB863D9F7D08 +:10D1C000FA0EE2AFE18CD34DDDA3F2F4E3B51C4FD0 +:10D1D00082D3A03774399BB4CBCE7EF5E4DD57DD26 +:10D1E0004EFDA6FEA13B87F6756D7798CFB37ABB4F +:10D1F000DE1A21E0D0E38D73D297B1BB74DECA7121 +:10D20000DC4E71DEBA466A7C2991EA3F93DC7E846B +:10D21000FF846637F4B878B9B6AFD507B7AEA3BC0C +:10D22000C8F24D4B67F17D9C80881B54FC25F9FFAB +:10D23000045EE573EE55DBCDF144C446F45FDD6179 +:10D24000BAD743F130DD5F88D5EF03C4C34FE56B38 +:10D25000F9AE4CC8E47DC80B927D03E83B73BCFB80 +:10D2600018789EC9677FD62BD3FAE5CAC0F9842700 +:10D27000A2EF3B581E96696B139E9C1CEFDAC4BD4F +:10D28000DF27D6BA5D54D7E47333F24A05F9D16D7E +:10D290003F66FED7C7E9F2BAA25DDCAF864D69CC26 +:10D2A0007325DBEC1EA26BC9B6611C5F601CC47EDB +:10D2B000DFE66DF676AAB7DE1FEF974B289F1CB905 +:10D2C00082F22AAD71E27D129947BAEF59922DF29E +:10D2D0001CC774BDAED975FDDE6C5FFC9398CFF7AB +:10D2E00093FBDAC38A21DE68D5FCE732828FFCC06B +:10D2F00046AB889FE204FC7BDFF87A02F9B13B156C +:10D300006F02E5A5CF1CCA4E8601F0A697E5685EC0 +:10D31000E073CE0BCBDF9A95F379F42A7B4CBB6795 +:10D32000AEF1E7AF9A3DF0176B941EFABE6AE46760 +:10D33000AB6D94E7B80D5C94F75873F0A9567A2753 +:10D34000B3663D7046E10CFDA178E1030B9F674F8A +:10D350003A589A41FCD8A9E93B3ADF5563F86A3C50 +:10D360002585B07FF94808D0BBA138351ED498B8C0 +:10D3700038A120D5504F745F61189F5C916D68078C +:10D38000BF2754383EEABFA678AE36F47F20693A0C +:10D39000BFA3991ABA83F34A6933C619DAEDC8D71D +:10D3A000745F013E16FE4F05FEB25D854699E09C16 +:10D3B0001C06F809F2DDA41EA37F5411DEC87160BB +:10D3C000DC21C510D7DB2F91674A1AADC9D54818A3 +:10D3D00029F48319DFC67B0D6B0ECAECC7ADC944B7 +:10D3E000C7336B707CEBF2A7E37D88D788F761F3D6 +:10D3F0008D781EEE33E279C472239E331B8D78BE86 +:10D40000B2C988D72CBF118F39ED930CFDF3365676 +:10D4100019EAA31FBBCED0FFAAC01C437DCCF66F78 +:10D420001AFA17752C31B497EC5AF9B9741F1B5CB2 +:10D43000636837D3BDF4C0774D7CA8309ECBB577F9 +:10D44000553AFDFDF84BF49F0CDEE4A044E9407F23 +:10D450002BC9E3BF8AFEB3476BF75874FA7F41BD0F +:10D460005AA8F94FE6F759B31384BE79EDC0994332 +:10D470001EACBFAE965A33C86FD2FC03AF7E1E619E +:10D480008AFBF438E5C60AC974DE1E67386FBFD45C +:10D49000FDB4F250D0501F7B48BC6B1A77C4FD120C +:10D4A00095E5EF79E4D8774C133F66B3DC2FEED4E3 +:10D4B000EFB9E97113643CC971E8021D7E1282F173 +:10D4C000FDF38B7A7C6A8E5BF578B5FF3B29E1979B +:10D4D000DC2D0F16C78AF8558F5BBF0E1E7E0F56C8 +:10D4E0003ED2B76E34DD9FB244D2A85D8F6709B1DA +:10D4F000746EDC4B8865E7E2E05C4F21BF23E5BC3E +:10D50000F7CA9657E6D27D7D04DF151E2FD23FF471 +:10D51000F3E468DFC6D1A8778F4BAE75A538F6B5B2 +:10D52000491F8EA2F91E1E2DF20C76193184F66762 +:10D53000D8020FD0F7FC54CF23A387F4BF676D2E1A +:10D54000CDF77F3A9B835C2A2E37DFBF31E707C3D5 +:10D550001695FD4EFF7725BE6FF321013731EAAFF7 +:10D560009C69B7B2BF025A3CBE50C3BF9EB758A019 +:10D57000EDE7384EB11CEDEFC25DBF61BAACCAE851 +:10D58000D1F21D8DEC5F2F1DE91CC7F7C93CA56EBC +:10D5900091E7D2F318232EEB9DC8A5F6BF2AE3A48A +:10D5A000218F04CFA67DA1F3EDE8BEC5FCC7D78BC4 +:10D5B0007CE4F1F5999CFF8ECE7F9AF3490B1BDF3B +:10D5C00030C8C5AD4D470D72B0D8FFAEA13D9C1E11 +:10D5D000B152FE30FCC2F0E9B720FE4EEDB4F33B91 +:10D5E00066E4833746C7E4CFC2EBC74CE3F79097B6 +:10D5F000DCE7870C47777388E9ABEFF358F311AE9C +:10D60000879BC35C9AF7A9E729F4D2B60F0AE89E74 +:10D610007D448A77535ED89CBFB8DBA2BECFF72289 +:10D620000BB2B57382C6122FD34FE42BBAB577A1D4 +:10D63000DDDABBD06EED9D67B7F6AEB35B7BBFD9CD +:10D640006B75B6535EA35B12F77716489E2717E3F8 +:10D650007AC9237D1F915C35AC8C142BB84E43499D +:10D66000789184741E39C4F731E145C2706138BFC6 +:10D670000BF2F33DAF0F2CFE627A47E32EC8B88958 +:10D68000E2BC0FE2FDA7C91329D89E26EA362187FE +:10D690001505FF60B97B0F27A3FDF97F2989BC928F +:10D6A000336CA3775053D37D503044DCDFE2F72F47 +:10D6B000F89DF852CF73F65A851FD8ABF983F6025E +:10D6C000710EE83095D944F3725A0F343FFFC17C94 +:10D6D0007E37B2C90EE4BFE2FAFC4E46BF67627EF7 +:10D6E0004733EED7767EEFA0E743471464F17CF42E +:10D6F000BE86E432FD7B09ACB7201C1A45EF71FAF7 +:10D70000E03D24DE439EA23C724CFE794481F6CE7D +:10D71000F13630BCE7597DF0F8318AB37E3DDA77D7 +:10D720006501CEBFC4A28E27BAAE4EDACBF9AEB138 +:10D73000052AAF8BF08AFDCAD046745AED08737E75 +:10D74000EC52F9F0C1F67FEAF6D08F0A39FFAB163A +:10D75000F37B3A6D5D84636C414CDE5A87233ACF8C +:10D76000E7F3BF9ED7D5EB279E78205FCBCBDFEAD0 +:10D770001DC09ECED0F0D26D1D388FBEB440C423E4 +:10D78000FDE8331A4D11DD538C471B81E53CC21374 +:10D79000E5816FC6FD707EC23396E8BB7A8E93DF5B +:10D7A0008DEBF3E33CBE9F7FCE3A2D99DE1B89FFC4 +:10D7B00056368ABCBBDEDE2B09BAFAD78B3CE8EAC8 +:10D7C0003D478FD1FFBF60C54F8B4A39BED7C69B3F +:10D7D000F18CF8E5F74D4B64716E85F85D40F39B75 +:10D7E000F3ED5F16AFBD99E27CB577F367A3E8DD93 +:10D7F000E86ABA7F46EFBCB4FC15741AF352882F5E +:10D800003FE52BFA9F47019F6BD9353B62D7C78F06 +:10D81000540CE3BB9DDEB5C41F2F687A03FB072CB5 +:10D82000B87EA71E279BF2289D2191EFECCCB0B1CA +:10D830009F4CFE0ED927DDDFB9EB0D91EFBC2B4BD2 +:10D84000F8D1041FD1573AB29FFD843EFB2FB95542 +:10D85000C29FDDEABB9FD607DF5AB65FF295485FED +:10D860003ABFF8ED755A3E40D8C372CDFE95D33C11 +:10D87000E4E01426B35D2CD3D645FF91F36E13C1BB +:10D88000D72A80D1F266EBF7731EE17F01BC43AE6D +:10D89000E0704400000000000000000000000000F4 +:10D8A0001F8B080000000000000BFB51CFC0F003ED +:10D8B0000917B0A1F2AFA1F1933951F93F5951F9CC +:10D8C00017D0F884B02E1303C30A46D2F420E39D88 +:10D8D00040FD0780F838109F6322DF1C103E28CCE3 +:10D8E000C0F0458C816116906E01D26781F82B10D3 +:10D8F000DF06F245441818948178BE28034314903B +:10D900005E0AC40522107D8780748D287976AAF37B +:10D9100050E6E6514C195E298DCA2F55616058A614 +:10D92000CAC0F05A0DC25F8824CFA0CEC050A60254 +:10D9300061EBC931307400D5CC94C66EAE3E50BE9A +:10D9400013282FA00EE10300D191FB3B68030000D8 +:10D9500000000000000000001F8B08000000000015 +:10D96000000BCD7D0B7855D595F03A8FFB7EE424E6 +:10D97000B9819B90C049081834E0490C0F11F12679 +:10D98000441A6CC41B8C1A6768BD606B231588C869 +:10D99000687C4C7381248497066D2D83FEF462AD00 +:10D9A0004329ADD16287A98FB9202D689D1A2D56C4 +:10D9B000ED4FFF46C6B1D42A7F44F1552CB3D7DAD8 +:10D9C000FB24E79CDC04D0CE7C838FC33E673FD62C +:10D9D0005E7BBDF7DAFBBAA104E0128053F8873D05 +:10D9E0006F9000206FF0095EA3092200CD9A5B5F63 +:10D9F0005F0CF04DC538A857B1F7A365E3073ABEF1 +:10DA00009F580B610005EBE70318F83FD66E4D7089 +:10DA1000F5A84490BD531666E1D3ECDF7C36AB002D +:10DA20005A257EDF3831D377F30929577F9F17E8CE +:10DA3000CF29066AEBE1D727EF37CBECBF020845C9 +:10DA4000DE0AB0BF4C87E9A71480E3C10559691805 +:10DA5000BEBFB7DBBACF5327007CD4F6DAE4FD13A0 +:10DA6000867EFFA6022D3DE543DF4F0736E854C40E +:10DA700047D21D9F3C38EF81790619922E64ED0143 +:10DA8000D29E1CF6DCB1F93CB56C104EE73C00921E +:10DA90001CBF9FB39D2752932E60A50A29318BE0AE +:10DAA00052D93FD300A82A5B97253B1A80E072C069 +:10DAB000DB11F9DBC03BEC7A897AC783AB3B91B4CD +:10DAC000D6B838BDB4E7C9C66A184A2FE67A98783E +:10DAD0003CD3F5B81D7C348E4947CDF2C211D7FD39 +:10DAE0007474743DD2D179FFFD7494FCDF4B471DF3 +:10DAF000D4CFFF323A02E8E6F8823E15C71F7CCF4A +:10DB00009F91853D12D2192BF622DC457C28286A8C +:10DB1000EDBC599EC2C41418CF9DC3E45651DFA278 +:10DB20007A847BF4E1797FC26767634DDDA56C7E03 +:10DB3000F94D3D2F7D893D23F1949460EB751FC80D +:10DB40002854587F3725ABD9FCDAB1B399008F241C +:10DB500017C592385F88018C02F8073127005957A2 +:10DB60005939447FCD340F37A4393EA4539EA1EDDB +:10DB7000879B7F08DB99758AF1FF2B00E777BA76E0 +:10DB8000B0928F9764FF20BEC70C8E4FFDE4375BC9 +:10DB9000CA80F8B17FEFC5BF107E6FFE1F19AF00BE +:10DBA0002A7D281F42F5B296C2FAD093ADB272E434 +:10DBB0002615D24C461454754B2EFDF4EBD2095069 +:10DBC000D7C3D7476A080DC2F79F2011FD8CBDE36C +:10DBD000CDED6B19C99D581834883E3480DC9CA16A +:10DBE000F3F94E1B12B2A5DC582325683CE3B95269 +:10DBF000D63ED9C8F5DE7DF50BB2ADF2CA23490297 +:10DC00006F4EFA005D9D866CC5E943AD9763BE29F2 +:10DC10005F9C3ED4CF491F792B2DEDE0ECD72B62D2 +:10DC2000DA0567481F5F743C735D87F2D52AB1AE91 +:10DC3000A53E607C7B6FDD828C76C6F0EB5A49FC9A +:10DC40001EA987582A43BBFC81F54C0E7DB2F551C5 +:10DC50000696F716DB7A29A3A7356D1F011F4AC464 +:10DC60003E5FB35F5FABA2BF99CB8AAA26637F6E8C +:10DC7000EC8FD1D9BAE8BD4960FC7002699BE143E1 +:10DC8000E9AE4863194AC1F881804066655F349601 +:10DC90005A4F7490A27531E1F3E8B20DFF6AC46F78 +:10DCA0002B435352B2C2EF6B75131C6E1C8FD1BB4A +:10DCB000A2B10E192AD420A47D61ACC1E14732384B +:10DCC000351ECB77DAE8A04BAF844CEB60D22BA2A9 +:10DCD00095D3EB9D67265F9CE335DAE13DE3764122 +:10DCE000557FCBA287866FA7C25BE6FA30247E0DF4 +:10DCF0003B983AB84E6B5DB0473A9FE9EBC2AB2117 +:10DD0000C1DEAEC54F17129D923DB3B6B05243BAB5 +:10DD1000821D928A709A7A14A23954AF42D2A91FF6 +:10DD2000D9DB02584F09C6E8697E1F1E2E417FC904 +:10DD3000D8DE52D6EFE5627D2F177A0DAA5C6FF61A +:10DD40009970939E5507CB6C1EEFDECEFEC7E8247C +:10DD50005921A57E200DFD5E8F7A91C9A57A7C6F31 +:10DD6000912B5B06F8204AEB552FBE3DFBC4AB134D +:10DD70002F60F4D16B2880626BF5139E582DEBFF5A +:10DD8000A58BA5944712F03238E70B385F88E5166B +:10DD9000219DF6D67A888EE77FE9A30892F1B13DFE +:10DDA000BF5133D1CBFC59AE4138D87FCBADF363F3 +:10DDB000FFFDF3C0BA14D238265C4B2B1582A37733 +:10DDC0009694C271F6FFFE8F775FC4E07CA14A3261 +:10DDD0003C3AC11B02365E6FECFDC8887E8739BEB7 +:10DDE0000E1AE2D339BEB91EE1314078853F30BC0E +:10DDF000B2F19235FD7D6B10CF4724630D1B2F6B65 +:10DE000076EB381CA7589609DE75B3BCB2C2E8079A +:10DE10005E1B25233E8382CFB3DCDDDEF10CCECE4C +:10DE200009323CC45EAD2B1D599EB53BE499AAC591 +:10DE300063126BAF27B54A6504BE48C5E4BA4CF21D +:10DE4000EE7989EBC98EE402AD14A7B7DF6E07A2A5 +:10DE50005E8A5BF42AB3179F97D8FC5D114EC7D931 +:10DE6000B5716E27F68E22F91510EB9135654116C6 +:10DE700064B083879D071B2893DD9C2D73F8E030E9 +:10DE8000EF5F35FBCF19B9FFB5A2FF8F9B25E845A2 +:10DE9000F8D4B817D71F621544CF7E419FB03287A0 +:10DEA000CAA6DCF594C5BB8AD93A7AA232E83ACE42 +:10DEB0002F49EBBC81AD712103C55FCBBEB3AA1B5B +:10DEC0003E53C82EC9964F24930C8E0D7B6F049D34 +:10DED000D9A9FE680AA83CF9062FE26703530A7C19 +:10DEE000FC1EC0F1038C6C51BE06987CD551BEEA75 +:10DEF0003D699995D53A3062EC534833243F2399D4 +:10DF00007DD192552A7BDFBE10887E01AD080B7E45 +:10DF1000DBA32FC71406576713905DD319A9A1F986 +:10DF2000B597D7788BD1DEA957E93D9C64F830EDE1 +:10DF300010260FFD6510C3F136E4432A88BC549BBC +:10DF400047F4E8D6F8FCF52DA590BE807DCF9EB6AF +:10DF500017C74FFE231813F89024D754932ED44498 +:10DF60005242FFAE5533D667A0BB2D90C892A7DAB8 +:10DF7000E894F4AE136F596EB80CF1DB59C1E8BFE9 +:10DF800078683F85C83F8CDE52C6822B4A328C535C +:10DF90002CEB441F6659FFD84DF00F577FB01EB3CE +:10DFA0003373B1EB98847881DA08CD2F0706FEC46D +:10DFB000B09C2BE63B0A5AA85E7446F75EE4B38237 +:10DFC000584F35E2E23BA1AB5FA2758307358C4722 +:10DFD00030684B4FE50ECA895890CB89E3864CF2E6 +:10DFE0003124A7B518EB20E4EB8D92B2D681FC88E2 +:10DFF0002C6CC2005EDFD63D19FDCB3018127E0FAF +:10E00000196AD22A7FB280956DF61F1C2A9D46A4FC +:10E01000C5F902B4BDC8325A59CB39D8DF7D0C20BE +:10E020001FF393378612A42F3EF285A7E0601FC925 +:10E03000F1AC346F5F8676F76D8ADF588FF46070CD +:10E04000FDE065FFA0FCCB9AA1DAE47176CC5ECE50 +:10E0500075E88DB94A90E69B7D39087D10AB9F30FD +:10E060006A103E065903D2CDE65A1570BC6090C3C3 +:10E0700065C299AB9C4CCB40701C4138187A088E15 +:10E08000701990BFC7E039E280E788039E23567875 +:10E090005ABD7CBE4EBF7FB12CFC7EE6F7A21E3C73 +:10E0A00001EFC4EA90606245A457C21AAF1BF4F6B0 +:10E0B0009251A58146EBEFF4FBD9FA1CB7E9871919 +:10E0C000A2AC33BBBE84E0B37F8742A2132A2B30BD +:10E0D000E0BF2E9E61E247BFE6FF32BEBBF1A00B60 +:10E0E00090AF18FF2AF8DD25BEDE28FCD8C5A8FFB2 +:10E0F00099DEFE1AC4C308DFBB2093BDFC2EBC1CF6 +:10E10000BEC02217EF93DD428FB305B5F22F185131 +:10E11000F4ABD56067AF1226349874269DA2753390 +:10E1200080FCEE20A7B7247857917DD1C5F5A3E9EF +:10E13000F77DBDDBAEAFBFB1C55EBE01168C42FA46 +:10E14000BAE1DB2E48B17E6FB4DA1F6C7DEE9035FC +:10E1500082EF1BD0D2A905C9CE6AC2792CD6404520 +:10E160003F6DE9BFFC9F698BD87CB60A3DFA3693B8 +:10E17000EBBA456F2C89A4DCB1F2A1F35B2319F350 +:10E180002F92869FDF5A57EF7CB40F929B5CE4D7A7 +:10E1900081D35FDBAD90BF666947F05EDF659FDFCF +:10E1A000E9E6EF9C2FF35868BE4B762C22BD39DC94 +:10E1B0007CDC3BA4582A837E7BCCD48742BE98F477 +:10E1C0006DF275B206B8BDF7FF7CA9356CBC57502F +:10E1D0003ED2FAB79CCFE3282DD3F179BA76BFFBB4 +:10E1E0009CEDFEF039DBBD29E4B8B3DD526F9F1B17 +:10E1F000D773B99AAC93E4413BDAEB6A898D61A895 +:10E2000070EDA94EA32966A9D77586F50E4A256734 +:10E2100054AF4E1EA1BF63C2CE38B0EBFBEE3EE45E +:10E22000BF9D6FCC47FDFECD2715F0B2791DDB15E4 +:10E230008234D2A79A72A3BDB284D1558ACAE96941 +:10E24000575AEC2A46B1D4FF371F0D917DB0E471C7 +:10E250004FAA9EB55FF2B3FF98020C0FC756F7FFA7 +:10E26000720CD2EB4E89FB7FC9BE2957B2F74B54D3 +:10E27000B82E9E814E6485F3CB3BFF1A6842BB4F9C +:10E28000DAB1F7ABD46FCF352E94CB66BD4F6417A0 +:10E290008DCBEAC5F07BF287526A82C4E16B983C71 +:10E2A000D4EF7EE78712876F8F2BE543F8766C7784 +:10E2B0002758BDE53BDE23BA9DF3E88FC38887E589 +:10E2C0007B149BBFBB7C8792F64CA1E71BF844CD27 +:10E2D00028317E5B26F875D9EEA5A40796F56C78F3 +:10E2E0000FF975F91E974DAE33BC1869C4EBAB8AB4 +:10E2F000518FE59FFE735867A87A3BBA33AC9553AC +:10E30000BF8BDC8CAEAE98616F87FD7F9C33B43FD2 +:10E31000807E8A6B2EEF59C7C703AE6F4C3E7D1BC4 +:10E32000FF923F546F4C52ECFB0E27E08569148737 +:10E33000DC919BD18F33F585C9AFDFFCF1896D4945 +:10E3400036EE3B8FFF795B92C17FD35FDFDF7627AD +:10E350009B173CE3D3500E2DDFF94A182C78AF55AC +:10E36000B81F76EC87FFFCC856C62FC75EF7905DD6 +:10E3700077ECE93F8ED5D9BC8F3DF6C928B43B5721 +:10E380003E7DE968A4AF954FCC190D23F80F48AF37 +:10E39000298F755D53B4AEFA1E098330004F89A7EB +:10E3A000637D9EDDADA43174FBEE6B9E9487E167C7 +:10E3B000397BD75A89EBB594F41096EF62785EB644 +:10E3C0006BED7BCA944CF84E8E91A3F8646C13C528 +:10E3D000F5BEF28A8BABF0E93274A40FE827F9EFAF +:10E3E0006CB7FC105BD7F3875FC71370D28DF85FF3 +:10E3F000BE6B1D1FD7B18EEFE25F2ECCA0FF87ACA6 +:10E40000E34DDFDB8A1F77E7D2BA0FB78E4B9FB899 +:10E410006A44FFCC9407A7C36FB3C4E13A5F89ADE8 +:10E420005090AF1EFFD1235B237C7DEB19428EFD04 +:10E43000F8C4580C2E1F75F57F15E564FFD31EED4B +:10E4400021D666C9D3AF129F1D7BE225B74E72124B +:10E450008212D37BC760E04F2FEAC165122F2C7F59 +:10E460003894F68407D76959AAA14E0FD3FB37E831 +:10E470007D8AD3FFB2D4DE4629C3BAED544AB85CD4 +:10E480004EE5115E96EABD6E2D685F4F6906AEE3FC +:10E490001B7391EE865B4773FE1ACE7FBA653D1FF4 +:10E4A000E67C3B1C7F1EDBEE51A5ACC1F53D26ECA6 +:10E4B00083E529E955C8C0B700AB39BCC3EC3F9A26 +:10E4C0004F273D3CECA007B3BD39EFD3F1F5E9E7A9 +:10E4D0007376F8FAB6A2DBE8C6C4DB3B2733CBFB86 +:10E4E000B49013CB205957307EA8BE52219E1C53A6 +:10E4F0003C086F678F4272FC9D1D0AD9E94EB9B086 +:10E500006C187FFCD70AB73F96EDD93B05E5D73BA2 +:10E51000FBFE55D021A7F365BBDE702785FC4F5964 +:10E52000E53FF697613D5E13702F7F2A737FCB77AF +:10E53000BD97B1BFB7D5D83508FFDBBD2E48B22E89 +:10E54000DEEE5132C637F6292E5B1CB73334EDB5FB +:10E550002C8C6F86FD3ACE7BCDEAD8AB49B4435EB6 +:10E560007601D981AA71D4C3BEAF09F969DF7B4DA9 +:10E57000F806D02D7ABADD8127351A273F588DC489 +:10E58000AB78EC3565F3475D9A6C831BD46421C688 +:10E59000537E5DFC4715FB7D11EDBF7306EBBFA8F5 +:10E5A00042472EEBEFC59864AC820CF12947FFF18E +:10E5B000590AE8563A8B95C9D6F86A78DFED149770 +:10E5C00068859634C689A0107A7E60E9F7C1360D59 +:10E5D000D26C7CA82B93ADF1554F4B4BCCC3E028AC +:10E5E0005CA995A06936DCF8452DB23DAE2DC65F1D +:10E5F00021E209B063E7CE9DACDF3AFC56827E0C87 +:10E600008F5731778AEC9839420EFE9BB083F749D9 +:10E61000F1FDE867C5F4CD2ACA39A974B38AF6C4F6 +:10E62000BC93DDEA620B3DCE2B5D5588F472F0336E +:10E63000A529135D35AA9CAE5615AF2DC4F6077DEE +:10E64000B7157227344AF32C10F3DC5FF48D601F8A +:10E65000EB776FF137364E6470D54515C0784B5D5A +:10E6600064D1C60A36FF82438AE163E582E6A49A52 +:10E67000983C749C6D28EF19FE1E423C32F81F6EC8 +:10E680008B52F991369D9E3BDACAE8B9B3CDA0EF23 +:10E69000BBDA6650B9A7AD8E9E8FB7C5E97DF80E7F +:10E6A0007F02E977775B13BDFF595B829E352AE7CE +:10E6B000B779021F9679D33E58637B7835C6514CA3 +:10E6C000FC39F15DCB282E87F60D241DF13D5AE56E +:10E6D00072C589D7D6D620D9A5DB24B0E1739ACAF2 +:10E6E000EDC8B880E3696FE23215F7F9EB4ACBC9A0 +:10E6F000EE81B881727A9B14BFA782F1CB81A2E927 +:10E7000051ABDC0D051371D5422F63BB787C66BA23 +:10E71000CAE5531DACDA9FC5E08B9D041DE9CC9C76 +:10E72000E7BE6ABD10E5E2BE550C9E72FC2E439911 +:10E7300085CECCFE660AF82098594E0FD22DE7FF01 +:10E74000E8CCB2CD1827668EA7314127ABDBD66E59 +:10E75000B36AC6BD75A263934E18FF1C288A503752 +:10E76000DC5F6C2EE6DF7D9CCE5BFBDEA3F856748F +:10E7700014D8E28D1DCD32F9395B0FF3B8F489E678 +:10E7800092CD1359FD6A8637F4DB73E69566252C26 +:10E7900074BD51D0D3566F3C4B1B417F758A7A664E +:10E7A000F9902FF12D5C97EF8EFB493ED2F356572F +:10E7B000EA5A948FAD873DFA6A36A593817812BFE5 +:10E7C000C70BD97B06D289BA951E9A5A90EF3FB4EF +:10E7D000DEA56F3EC7C2E721C3CED7DB5A478E4BBB +:10E7E0009B706F43B84788CB9A709BEB71A2AEB118 +:10E7F000FF1B30140FCE7E73E6358E38FE83C8774C +:10E800001EC2C3362BBD15B668B4CF60B637E7EB72 +:10E810006CEF9CEF60BEC299EDCFF4B82017D7F330 +:10E82000B1BF8CFDE98B804B1E57508E5DA7267AB9 +:10E8300010EFD3A085CAA0F6E723BFFCD6CFF970AE +:10E840006BE723F9C4476AAA18F5C2998ED701F17C +:10E850007835EA2D4336ACF2DC7CFE4235E30469C0 +:10E860008A1FD116331B520EDC15CD84E781FE0BB7 +:10E87000D577ACFB491B01B89F9EF6D23E070644F4 +:10E8800034562E3E0895EB597F3B853CA956B95F1F +:10E8900078C1417DBBC2E3474A43C88247114F3527 +:10E8A000E3581D701768ACA95BADD88BD54D3EBC45 +:10E8B000C29DF82DE2CB1DD569FFDD1549105F81A2 +:10E8C000887FCF1271FA4B95C301945FADD01B388E +:10E8D0001FF9F99002E41727C6135F5E34CC3EE1BE +:10E8E0002E619FEF10F2FA1141370FA3BC66CFEAF9 +:10E8F0009EDE34B2F4AC875373F0F99090DF292197 +:10E90000BFC355FEB4C4ECCEBBA71D4DB43038BA5E +:10E910008F1E5770294D793153C067CA87993E0EB3 +:10E9200047B8BFF366B4BFB7A1FC473DE73A30FE36 +:10E930001E86AF8E84DBF0907C89D7B5E03C0A65FB +:10E940009AC7CF0B6B641F2B3F658081FD3DD816A6 +:10E9500023389EF2F6BFFF22C6F767B98D247B1FCE +:10E960003E79FF2DD86F58FDD13FE0135213F8FCCC +:10E97000855C32F9ED59D70109F5F9D38540E38576 +:10E980004FEEB90DEDE7F0C9E76FC77697A4A03653 +:10E99000C0EA072B767FF97CD67FD6E532A0091A2C +:10E9A000ECEE4F74B3FAA5AD2DD538B57F93D201F7 +:10E9B000FC9E9CA7921C1C0BB15518E7C8DB9890D5 +:10E9C000F07BE8418EB78BB6F4FEAA1A109FDA3EB0 +:10E9D0001C6FBCAB98CB5FF9B939B8F7E2297AD391 +:10E9E00087EBFAECD11580F2CAF3814CFBF14F7F33 +:10E9F000B002BE61CDAF38AA668C838D7779F8BE40 +:10EA0000D5070BBAA7E89CBC907F66FEA9D64B7CC5 +:10EA1000FE02D8F661CDFD2AB37D859418EFCAA316 +:10EA20007D09BE7F25DA5FA4A02DC78A7F96F97E77 +:10EA3000693C15B0C641827F92E399ECCC2A974A93 +:10EA4000F0B41BB5477FCDC653A75F4DFA17BAED9B +:10EA50007038DB3138AA381C1C3E138E2246EF3E3C +:10EA600036FE53C77F978FF07D5C67EA95DE00FA2C +:10EA7000F97B4FC8C46F9BFA81F4CABEAA7D5EC4FD +:10EA8000E3C6AA1A3FB773383DE6087A7CB88ED73A +:10EA90003F51C5F7F5E1E429DAF77289EF3979FBDF +:10EAA000BCB457918C05ABA7A17E32FF58F2081871 +:10EAB0006E8A93F63C02B935C7562E8202477E4ACB +:10EAC000C9A05C453FBB2EF2FC38064A48EC3B57D8 +:10EAD0009BFBD8CA6103E7FF80A9FFDABCF4DCDE48 +:10EAE000F25000E31CBF30E9A4B9670ECE6FD64DDB +:10EAF0003DCF86D97C2E3ECAF7CD9C792928F75088 +:10EB0000CE6ED4D2B9563D0AAA87E031F7372E3EF1 +:10EB10006ACF5399E5C84319928F75967EE572972F +:10EB20003DBFF0046C9C4474D15B625B9FED173277 +:10EB300037E6FCA1FEE540BFC27F8228976F3942CD +:10EB4000AEDC7D87D28CF651F8B2CA6CEB7E68BB26 +:10EB50008BEF9BEDFFBD0730FEBEB6D64B711B732E +:10EB6000DFDC5CF70D986485F90DED3F0B205E9FAF +:10EB70008C94F8F0F9ECCC9D245FCDFD7F8F98D379 +:10EB8000EA993BBFDC8C72294F269DD251B86F0C9D +:10EB9000EE27DE5BEBA5FDFD70A0AFE759560E7EBC +:10EBA000E436703FFBE9EA7493D55FFDB18BEBA5CA +:10EBB000FB5DC2CEDA68DF6F66FC70BF8B7DF70449 +:10EBC000E3B45F297B459E84C3AF31F111DE972FFB +:10EBD000174FE6CF92C983F6F883827EB60AFF66A6 +:10EBE000A3B0CB9DFD14376BFBDC68E7DFA4552A8F +:10EBF00019F8735CABDD2E286AB1D3FF98663BFD34 +:10EC0000878C02871D9126BD65EADFB5BEE078B42A +:10EC1000BF2A997EE4F680265BF7D79DFA77A71A7C +:10EC2000FB99EB2CEC907020DE82F876DAB5FB04D1 +:10EC3000DEFFA2C4D288DF801ADF47FDAA719237B7 +:10EC40004E3B61089CC0E09C3C229CBF3A1B384F65 +:10EC5000B71FF0911CDFF22203797616883C8B10E7 +:10EC6000D91F1D21EE9F74B8B85FD02FE8E80D972B +:10EC700042F33B26CAB303D092397F8CC7878EA359 +:10EC80002182F54667CED7450B85BE8FC9FCFDB8FE +:10EC90008BEFABCD1E37F2381F88717EADC6FEBF3D +:10ECA000CBB26FF3A42BF69EB5FCA18BEF830DAC1A +:10ECB00087C8C735EDA53D6AEC235786BCB49C795F +:10ECC0002AEDDF9E00BFA130FC3C930FBB81C991B0 +:10ECD000672481CFDFFB488F99F81EB0A7517EA033 +:10ECE0003E381C4861FCC45C0773DFC59C87693FE4 +:10ECF00094B9B93C6174E37313DC71BE3F08699247 +:10ED00000F05826EB6FA16DE53CB9E77CF7CFB35AD +:10ED1000CC4F78F7099F8E706DAA3A12B6CA4D682B +:10ED2000B6D38FF9DEF5F118DA97BF554A8C765BCA +:10ED3000E328917E37B67F46D2C97F4BBEA290DDD5 +:10ED4000FB8C949A44FBE82AD0FEC533374653EB3C +:10ED50002DFB1B4EBB3EC7D7F7C0729C7733B39FCA +:10ED600060E8BA9976B959C63C106BFBF96CD9B911 +:10ED70005DCDA6CBF8BA42CCDB50630A100926E879 +:10ED8000391D747A32FBDF7033BC5D00FDF9C84772 +:10ED9000AB03632FE2F6C67F1BDE66E378FFDBF092 +:10EDA0003648B74E3DCDF719F2041E42D042FBED76 +:10EDB000BF685ABC6E021BCF5D18247B35AFA9FD1E +:10EDC00066398CD97DBD1AFA977962FF1B1AB97E14 +:10EDD00036F7A373EAEDFADCA9BF3DC2EEF00CA34F +:10EDE000D79D727338BDBEC46DD7EB03F1E261E409 +:10EDF0009F335E7C7AF9A7DF535B8C7919B1576B2F +:10EE0000D9BAEC9BA5527C333C1EAE8B5BE8E1B0DB +:10EE10005BA1FE0EBB791C643DE3D7D4399CCFE1E6 +:10EE20001CD4074C01E1FE41919CC2FC9AB5C95427 +:10EE30001DE69BAD552768D675AC2E62762DC3EBCB +:10EE4000A61A7FB3D5DE7ED3EFE271D840F541E458 +:10EE5000C7F260AA86DCBB1873FC46F13C4B5CB77A +:10EE6000F334E8C37D570F70BDCD38C2CBF54AAD42 +:10EE7000F616E56326E0546024BD60CFBFDCA9A68A +:10EE800056FB111F111E6F096D91281947E989A5BD +:10EE9000D17F981C58B095E4901A2FC371F64E6339 +:10EEA000662FABFFE15E37D9393DA1312ADA95CF24 +:10EEB000C88BBFE766F3ED7FDD03B87FD2F3D9B926 +:10EEC000748EA12774D15CA4831E099827CBE6CF4A +:10EED000F88727FB4000E3F4E13931C03865FF2FA4 +:10EEE000C078888DEF8AFE344E79BA100BC833583B +:10EEF0003B1F7461BE8AF1A9FFFD4B18DD3D1EACBE +:10EF0000BCEF7C18F4FB4D7FFF627FE231E4C78EDB +:10EF100051BF6B463EEB62702A6487C5A2087765D5 +:10EF20009E4CFC0779C1D404F6BEFA60A416F3CF58 +:10EF3000AAD50A94340C0EBEDE877C892771BEB533 +:10EF40005A436D36AB5F7548277B656EF4E6FD5816 +:10EF50009E7698973BDC40F620F22F58F8AFFAE304 +:10EF6000B134BF5F0A39DE1E8DF5C6A411D64353F6 +:10EF70001DE737EC792B563AD0A6D9E820E1B2D27A +:10EF8000C10C460793AD741093CE860EBE8D5838D3 +:10EF9000237EE17C729BC2F96628DDB77873CA874D +:10EFA000F28739EEFAAA9C08FA19261F68D3EFD225 +:10EFB000B0EC59E4267FCFE40B931F4E7AF9BE02E2 +:10EFC000E38B3A1F7B3606F54B33F105FA7356FA9D +:10EFD000BF72183E990FFDFB31C77EBE0AC92C26B1 +:10EFE000427E7DE1D1D2B116BA77E269FE2C098E5C +:10EFF00058E4D1A953BC6CC1A33690F7AC9C39BE80 +:10F000005F56F58E8885EF3A99FD8C4661976C4086 +:10F010005E31F2DD62BF07FDD5FAC7A214CFF7C497 +:10F020009B294F6DFA3B811B181D7E384AD671F221 +:10F030001DFAE247897F5F0B00DA6D9BA62D1987C9 +:10F04000FEC9873726C6A13FB68EE1FF081937A94A +:10F05000D132E53EF58DE6FB637A943F1351FE1EF7 +:10F06000C4F79428C744BD3EAAC7D6D9260F377B1C +:10F07000397D6FF6723B709DBBDB8BFCD55FECA5D9 +:10F08000FD53B3DE250AB7DB6678787D38B946C70D +:10F0900078D50C0F6F775F5B2AFEE6048473073D1B +:10F0A00073EB5380F17F7F5952C7F8BB7735243219 +:10F0B000D97DF779791CC0BBEF9F68DF28B7D4A052 +:10F0C0003856A49EF56759AFF90C35594C7E30700F +:10F0D0006348C71DBA9FECB0F9919A3FA95386AE19 +:10F0E0002FFE39625927EF5F95440FC50BF87EC696 +:10F0F0004AE1CFD59678892F3A5ADDDB712A0B3C4D +:10F10000D9DC0E8DD48C982F8B7E53D283712E2F09 +:10F110003D713F23790EDFCF487AF87E46D2C3F7A0 +:10F1200033F089FB19F81DF733B0FC93B6189571CD +:10F130005F03CBB8AF8165DCCFC032EE67E0734FC1 +:10F140005B333D7FDED642DF9F6A6BA5F2251E6EE4 +:10F1500067435932BA80E1B9EB76770CF7A9D789C2 +:10F16000F5793656926BB075F445B8DFE97BE15E10 +:10F17000C0F9F8A23C6ED419BD17AE67CFAEA9A1F5 +:10F180002EDC2FF63E1AA4A74FBD0FF420EE4F241D +:10F190009B3153B6C5F3C41C95E9F7D2E8CD353998 +:10F1A000AC7CABE7C93518BF9AA8AF32166B836544 +:10F1B0003D54B9E4314B795CF976D5CFEADFB9F645 +:10F1C000E935C8A708071A6F1D9EF49C556CC9D372 +:10F1D0002540E735FA8BDD29A4B3AFE17A21FD782C +:10F1E000B85DFF655813453F799CEEAE44FE60F56F +:10F1F000D39C2ECFACFE3ADC94CA1BDA6EA47A7292 +:10F20000D519D5036584FEF0BB34423F1DB046C31B +:10F21000B3631B9097312EE80B909FD6E5E27CD923 +:10F22000E5E3CFA35E73FFA8669E978D3B4FF06921 +:10F23000972F5E87F9CAFD93658A17F4B858179817 +:10F2400084DB5AFC9B1236EEADCFAB8071E694871F +:10F25000DB3713C685B8BEBCD34BFAF24BE37EDC7A +:10F260009EC3CA13BE6F18A8FF3680E1473A496EA5 +:10F2700094693FF74755E3731A58F5F3A63E918317 +:10F280007184CF047FA7F07C112BAFEAB8611CC654 +:10F29000953E7C89CBA547C538DB5DBD2DB49E531B +:10F2A0008364370074935DB02AAAD23EBC9CCF9F82 +:10F2B0006E97F67758CFCD146F92C1E3FE6CBA9774 +:10F2C000FCEF8F3DE25C5A2FD90B6E5F42CB66EFAD +:10F2D000BB9332F1FB1ACD9FC2D4FB0DC14A3A2732 +:10F2E0009B2C5729CF7A43398FD3054257A7D04E4D +:10F2F000B867AF8FCB87A097F2AD52E5BB0FD6446E +:10F30000F0296BC8EFA9D8823AC2BB266B94B7C567 +:10F31000FE46DF9B239497BD01C4BA34F37866C7D9 +:10F32000A84F7F85F1DB355FD70C715688F21EC977 +:10F33000B491F1DC6EFFBE00C2F315F39C51DFEA1D +:10F3400000ABDFBE5833701DA66835751827ECD0AA +:10F350006ABCC85781C9B5DE45248706F292E93CEC +:10F360005B7B39B757F13BF225B4C37E3CBF3246D5 +:10F37000C8B24076A584764E473D858D306FD796CE +:10F3800067D99E7319E5B12BF37308CE0E8879B156 +:10F390007EB29EC79DC704BD69B4E3C698F1434CD5 +:10F3A00031B6F811B937D9F394F39B55DB398ED1C7 +:10F3B000097B394FF805798E7CE64F3DE63E8A1D84 +:10F3C0004FCEF9E6461ECA467873F160B23E743EEF +:10F3D000F7452A1B709E63343FC11DD55657A3FCC9 +:10F3E0001A0D2DAB90EECE1A5E079C53CADB7B71D3 +:10F3F000DDA7E82A9D5B381FFA5763BF1B049D7782 +:10F4000015DBF564CAC3FD06C68F95C88F18E74A99 +:10F410005AC6C7386FD232DEF8AE1C5B79427781AC +:10F42000ADFE395B4A6CDF27A5CEB57D3F6F47A5A2 +:10F43000AD3CB967A6ADFEF97B6A6CE58AF465B6AA +:10F44000FA171C5C602B4FEDFD3B5BFDE9AF2DB661 +:10F450007DBFB06F89EDFB454757D8CA17F7DF610D +:10F46000AB6FDACD4EBD58EEFD7CF6B207CF75D945 +:10F47000E282767BDC694F7BFFBA465F8D722DECB2 +:10F4800026FA56518FB3F28ADBB93FE39D6DE82827 +:10F49000574A841C0D056317E2BA5587BDA40FD4E3 +:10F4A00020AFA706E792DD31760B934717A015082A +:10F4B00003DF032897DB92F152D720DC3EAD9BCED1 +:10F4C000285487EB00E3BD667B558B412284E3E93A +:10F4D000DC9E61DE22D6F3E9ACBD651ECFC8321DCD +:10F4E000E9EE677ED74316BF6B383FCBE9579DA93E +:10F4F0001F3556063F3EB74BF1167C96B7BC54837A +:10F50000E974CCBFFA0AE261933BDEBC1DF7434AC3 +:10F51000FCB42F66FA575DC53DC417FDC52AE9172F +:10F5200050F5F20596F8569797CBFB80F701F2EF6E +:10F53000D492190775C4FB2A95E20E1B241E1F499D +:10F54000B27540BDB66DE6D1F7FE91BDF79678C7AE +:10F5500078993C329E75C770BFF33E81D712ADA239 +:10F5600086595CCCBE68D887CF893AB333D8B3AC60 +:10F570006CF33E7CDEE1E5F974E71A8FD5A02CF13F +:10F58000CEE6F69F32C59D5A8DEBA7713886A33320 +:10F5900035670BDFAF2A55DF427A436BFB943C485B +:10F5A000073EA403899E443FBE4890F4860F0F7720 +:10F5B0006159955201F63D521A9330CFA23ABC855B +:10F5C000F6557C69BBBDCAFCCD2EC46BA4DEBEDE85 +:10F5D00001EF3682AF5DE2F1D7AE6CFD851A067F92 +:10F5E000575E490EC64E303ED16091379B85FDD6A1 +:10F5F000E4934DFD4FF24646DE983A68EF30FADF6D +:10F60000228F47F8BA01E596EFAE6E407AF7696C43 +:10F6100035D1DEFE5692E8DFB4776F11BC555BD270 +:10F6200044FB5EEF472AC9BEF5B5FE2423FE7C7D70 +:10F630000AC42E181EAFE1895B49DF43895B47BBD3 +:10F64000A25577C7B667900786D007EB30CF03E1A6 +:10F6500011791E5D021FE6BEDBFB66FE93D807BE76 +:10F66000251B6CFB7FB7E4558E1EC91EF731BF2FDB +:10F670006181771D1B07F1D271B2A12E4EFB80C0B4 +:10F68000CFA57D56BE9DCEFF0AFFC510F6CB0C0F51 +:10F69000C7EF5837909F3007E31717A0B7F9E53A3F +:10F6A000E44B33DE71C49B43F83792A0B490BDE2C3 +:10F6B00032F5967CEA7C8259779B714A3279B95E41 +:10F6C00063FFEEC57314E3BBECE7932674DBCBE773 +:10F6D0006CB19727A5EC6566351F42BBA001387E4B +:10F6E000CEDB61FFDE60C6F96AF9B90A2F1BF91497 +:10F6F000D7BFB673AC20F4BF194F2DEA4957A37892 +:10F700002D5C69D7AB0542CF1738F4676548213FB8 +:10F71000BFFA60643FDA8F66FCE510267F59E2A9E4 +:10F72000661CC529CFFD873703FB42FE72C2C3E3C7 +:10F730000B09E6DFB4168AB845117FBA14FDC585FA +:10F7400064A7B59C83F2E9696FE2032F192DF67364 +:10F750000FC7EBD45F483A1F276119E7B6B2E497A9 +:10F76000F8F453944762C6314C3FFD642036CFCB4A +:10F77000D67D83F172CBB318477ADD03D8CFA5CA03 +:10F780000B07DB587945914A798FDAF49BBEE7C7BE +:10F7900038207E67E5EA627D34D1FF732EF2D7D739 +:10F7A0000A7A36CFE398718F6C1FB79F433ED32EF2 +:10F7B0004AFA455EAB1FEDDCF37630D96CD3733C6F +:10F7C0009E66C6CD26F7D8BFF78094ABB1F53BBF98 +:10F7D000292573BB2A16ACB6C4D5CF15EB356561A8 +:10F7E000FADE85ACBC0B5295783F4485A00B63BF15 +:10F7F000FDFCD72890E89CC0A8438A9162F5A73CFD +:10F8000065FF5EEE381F76AEF3BC9823CE1B52E048 +:10F81000BD456CBC8D7A8B84F273E34266C3B3F250 +:10F82000B93E912F3C112622FD5DAA048D34E2F7EA +:10F830001585F486E78D735E5D84FAFC259E97A29C +:10F840008DD737D7B2B2F62B85F49316808A8AE02B +:10F85000605CF8FE5306B4BB06E34C3BD9BA964E47 +:10F8600040FFDA0BA8577EC2D617CB3DCC1FC7F29C +:10F87000E3CC1FC7E76EE68FE3FB9F317F1CCB7B9A +:10F88000983F8ECF9F337F1CDF3FC5FC712C2F0F1D +:10F89000545FE28C5359E3768371AA3EC98C53A11D +:10F8A0002839EED6699D07E255091EAF3A7D3F31F2 +:10F8B000B31F8A070EE947C405DFBDFD778FE079E6 +:10F8C000E9A5535777E1B957AFCB8C8BF13C08339F +:10F8D0008FD9E4BFA5BB6FA6FD6077FEA1165C8F34 +:10F8E000DD5541BA53C8ED4A68281F9DFE97E97758 +:10F8F00039ED5FF3E9D4477EB4032E403BA99BE288 +:10F900003EEB5D5046E76025BF817CE18C439A7CED +:10F91000FCA2AF24E3F9A5817C58119FF140CA8B6A +:10F92000F132B724E629F2354984B12E36203F5B07 +:10F93000F28B83E5698A73048331B2BF24669791A1 +:10F940009DA625A21887EA1C26FFF541C1A7ABF2A8 +:10F95000DD746F44673EDFFFAF2D34A2D87E4DFECD +:10F96000B4A8351FD6CCD7DD1F9AE6EDB3F4B72285 +:10F970005432A29E52985ED547D0AB8A87E7ABAF90 +:10F98000D977A117F390D70717F7A27DB53E1AA133 +:10F99000F3EA7BF3A791FD31503F3A83F29595202E +:10F9A000B75B95A897EC5615E75F3E58DFACD72AB2 +:10F9B000E433633F8ACF05823D54CFA3C629FEE1DD +:10F9C0008900ED5779BC3C5F20C8FC6BAF2D6ECA37 +:10F9D000C7BDD9C7E5DB7A3D11C776EBA3AA8EE296 +:10F9E000687D5925E1798DC0F39A3C53EF1B646F14 +:10F9F000F4083968F6B346F8EB6B9ADD6477C55BBB +:10FA0000B363B5B9947FF903E4BFF5C187BC98CF60 +:10FA1000EECEAF1AB1DF27C5FA0DDFEF1B35B517F4 +:10FA200050BF3D3E36BE3BB458C37E5DC3E4D91FD4 +:10FA300014707E5EFB92614EA3FD2E30F56D2A6A36 +:10FA4000DD27763EFD68275E30B4DD52BD6F2EE6C1 +:10FA5000F9AA90ACF32B43CF292CDBC3EF9DDAA49A +:10FA6000F692BDB3E9A494F1BC43965F12CEFE803A +:10FA70001F6EB357C6087E1A23BEEB68AF14A35F90 +:10FA800069B72F2E38682F4FEDB597A7BFE6B4574B +:10FA900062AFA0BDD228E45D2F93CF3C69A25F4541 +:10FAA00039104FA6AA11EE06E85985FB942E11676E +:10FAB0006E14FAEA0AA1CF5C7E1E971DD3ECB7F94B +:10FAC00089E6FD1985A2FFA2DAFD37B7A3708D9BE9 +:10FAD000F68F4EFE65D1BCC7AB494C3AECA0869878 +:10FAE000FDFCE9150E3BC7690F55ABDB29BFB2C062 +:10FAF000117F30F729719E780ED739FED98E6BF6BB +:10FB0000B795E92DB457CC7B09E8DE2ED6BE484D1B +:10FB10004B06C353410B50BEDF989510DB9E818E80 +:10FB2000A789751F82B7E42584B739E25D4190DF6C +:10FB30007B5250ABA4F462CCDFEF21FDBDE0263652 +:10FB40001FB2974FD13EB4593F27BB672FEE136EBC +:10FB5000AD97B8FF9804B243CC75DE1AE4E7651A96 +:10FB60002E965232B66F29A1F109AE92C1F5657891 +:10FB70003AC2F1C4F3CBAEACB39FEB6970D81B268D +:10FB80003D5CE178FFBA4F23FA30F9E0DD0B5F9B73 +:10FB90003896C1B1544AD6059433D79316FE709D5A +:10FBA000423EC4BF8FA2A9107FECF3FE54A3FC8099 +:10FBB000ECBE078091E4657E48D6CE02F8377FFF21 +:10FBC00079122B37F8CB3BBA2EC6E389FD3F42A30F +:10FBD000CCE3A9B8B4AE68B0ECF75F4CE588188701 +:10FBE000B91649BEDE967B0A18BCDF15F9011B6207 +:10FBF000B059C11C4B59DB6C140FB6CBC176D2087F +:10FC0000EDE2B059CDD02E68B663E8EA34EFF528BE +:10FC1000C127FF2E0B78ACE3AB88374D0FD2B99DCF +:10FC2000B9AA86790F5F148E51A79B770236BBC69F +:10FC30000F6DC7C05E65C22F67863F85DFADE3BB32 +:10FC40004680FF6F8D8FD3F5E716DFCF1A3E567DC6 +:10FC5000F5A8E1E78B70B9E87E0C3D285BFAB9673F +:10FC6000EF2714BF56AF053A97A3BA629AC1E8BC12 +:10FC70005CFB36F9E16A76AD8676C03A56463B6063 +:10FC80005D4F37C5A9CB4BEFED42A22F4FFB01E5EE +:10FC9000C164D0B277B17E276B2A66E2807AF17EAA +:10FCA00019E3DE7039D0B990ACBD7E7E8F45F1CCC2 +:10FCB000EFA37F949DEDA53850207BDAF7B9B1CB47 +:10FCC000E3C126FC81EA43351827571BC040565430 +:10FCD000A5145423934D02DA87F0C776DF86E72B0D +:10FCE00099E223FD44773BA05E1571F1D19C64A09D +:10FCF000CBAD35A09F907C5EA5F8FB68BCF2861169 +:10FD0000657979CE6684A73CC13A90107E1ED79A59 +:10FD10009C908D34EBBFF23DDE0EFE9D9F0760BED2 +:10FD200044D313C141BC9A7265B488974717DAE38C +:10FD3000C9D0CFE6CCDA57FEFB821F603C61D410FD +:10FD4000F9CDFD6BF3DE9CACF720FE04ED6BDAF52C +:10FD5000865FDC4FE177DC7B302E683F8737C46FEE +:10FD6000F8569CF480070CAF9BEC8B85643798FEAB +:10FD7000C856AC88F1FF22E079D9CEF6D3787B88DB +:10FD800072FFC4E367665E25FBBEC41FA37C1F0F22 +:10FD90002B333C4A6EF0E6B3F705328F8BAC9240C2 +:10FDA000C5F2E07869DAA75F2B195D8634E8FFAE0B +:10FDB000D10CCA1F809539367BD9CC435D7163F174 +:10FDC000E81CF6CC1A3CFFA3213DAEC82B25FB391D +:10FDD0009CDBF7F7285F8FAF5F7FA917E529E62F38 +:10FDE000CC04F8ABBFA323C9E4ADE7E331A05BECDF +:10FDF000328FDA427130CFC7636DEFD36DF6F38285 +:10FE0000B1A05C8BE3E461F23EC683416BC776D55B +:10FE1000603F17E8F938DF66A70FF65F687B9F66DB +:10FE2000F68CF53E8AE1FB0F805E66ED7FFC30FDCF +:10FE30004F74F4AF65EC7FB0DF5C5BBF1D2A8F8F22 +:10FE400026237E5A77A73D3039505310C81B217E98 +:10FE50001FE0F1C7B5D1168ADFD700637846279730 +:10FE60009C3CA2F0F36B40761B14DAE3F735827EFC +:10FE700065461148BF97A8F67BC06683F35E30BB2A +:10FE80003DD48B8C827E65A8AA97E2F89F0475F416 +:10FE9000BF86B3977BDB80E2C7B3037DB7E03EF557 +:10FEA000A51B1E7075CC10F9AF05CC8ED8D0732968 +:10FEB0009EF3EB15E7F33A2232E1255E339ACEDB6F +:10FEC00098FDC4DD3001E5615CE6F909F4878DDF5A +:10FED0009B57F0D0FA0CF8739EE76C8849F1520BEF +:10FEE000DDF4CA0CAFD6F1E68CD9AE58E611F7C0F6 +:10FEF000541A4FD8B903E38DFA7CE3BD24E24EE6F1 +:10FF0000780D73EDF36B706B34BF06C1BFE6782FCD +:10FF1000E1FC32E0F7B4E3C99C6E06C6FB927D7E3D +:10FF20000D1E8DE6D720EEF51D186FD4E71B6FADC3 +:10FF3000AB258176DB6689F3FFDD817FED40BFED88 +:10FF4000FDFA1551D207C22EBE021BB07A57A87C0B +:10FF5000BCF985DED42ACB785B991C88893CF7985C +:10FF600007F337342AA7DAA2F47C88D9D931CADF5B +:10FF700028A3EF8FB41954DED136839E663F6533D4 +:10FF8000F83D3393664919EDED5F06B8DFB8395F88 +:10FF9000BBF66BA897AAFDFCFCE38C8B2066B17FB7 +:10FFA0009941BCCF87FB2F574305EAB6895B38DC04 +:10FFB00091DA51295C3F7FC5FEDE3656F6B85C3AD1 +:10FFC000EA53C60BF14C7EEADE00F7C33D6E2EEF1E +:10FFD0006126BFB770BED02BA0D44B2EC4C715D995 +:10FFE000B4DFBFA03116D218DE1A25E99552A1A7B9 +:10FFF000F0FCCA5562A99C767E043506EB37125395 +:020000021000EC +:1000000052781FD15585079B502FC74357927F10B9 +:10001000670D73583F57093D59FD860730DF012EA4 +:1000200075131C8D8D767B7EB32FADA17DB2B92269 +:1000300002B83E0BEAEDDF3D6ECE8771C73D05F39A +:100040004F736F01DD9D95218FD4199F7C32608F96 +:10005000439E80F27B6AF1636164C47B0B5604C0EB +:10006000BCD73263FCC884E74D94635391DEF650ED +:100070003CCC84AF404D4928AFC734EFB1E53531B2 +:10008000C492316CC6E141D955817E88733E5BA52F +:100090005DF923DD535200EA5B7D65E21E4F69E89E +:1000A000BC7F1710F9B703F39EF5622964E21F1EA7 +:1000B000779D7F503156E9837831F1F03FCD479DF0 +:1000C000018ECF17E77C50C5FDB742DB7D99E63D39 +:1000D000C0570E9455502DF47CC51237D93310EB10 +:1000E0002F47BA3B747180DFDB66DA2FE9D765B43E +:1000F0005FBE78FFB1225BDEA6E877B8F572E61145 +:100100005ACE7D0EE6B9637E89C4F7B10A30CF2D91 +:10011000CCDF1FB1DB99B63CB7357B7F28619CEF04 +:1001200001CCC7B3EC5B8F61FE3CCACDC29BEC79BE +:10013000754EB8CCBCAA8173B3B31AB55D3ADD93E2 +:10014000D88D17CF746D49C6C1921F699E1334FDB7 +:1001500069E7F94025C8EFCB8B8AF316CE78F06DAE +:1001600072522B96301F35E5AD66CFF29C848147E5 +:10017000D36F539275F85E193DB319F1B0B0F54ED7 +:1001800003E3775A6EE6B8F442A1BF2F0A72BA3978 +:10019000EC4A17611C3B91537351302F43FDD66FCE +:1001A000517FB387B97FBE51F4F380D0E7CEEF978C +:1001B00007795CE59AA532DD67E183504A2AC67D5E +:1001C000E3EE19742E6FD95623D3B9B783E144BD3A +:1001D000151E5F293F6F0DD07321E26BDD5F1EECB2 +:1001E0007994A132E72F4192A3390AEFD7D2BE31D9 +:1001F00053FB673EF92D9D537E06CFA9CCC4FEB6B6 +:10020000CEC5F8F7A6813224252C678B72F2B6B9D9 +:10021000E8EF0D962BE6566319699011D9ABC1DA58 +:100220004EA4974D120862BC94D777F1FABBC5F77C +:10023000D997BDF37D3C970BD3DCE4076E12F688AB +:1002400009DFEB419E37F3FA69F079ABF81E447C85 +:1002500046CE0A9FB766C2C7EB39B1DB8253B19F66 +:100260001EBA17D2F717EF4ACC23FEA73630BEC608 +:10027000E6F080B1FB87F700B5FF5670EAD0F6F3E1 +:1002800072626DD86F70E9119A5FA83488EE0DAC78 +:100290009B0ED44F0638D666EAC75CD774169763B0 +:1002A00027D076CEC375E5F69FE2E98DE2FEBF5614 +:1002B00075FF2D1A93239DC5DD4D99E8FB3B21BEAB +:1002C0004F9D3D4CBC7A97A0C757B5F877118E76F5 +:1002D000ED5EBA4FD52D71BB61DD8C3E902CED7E6D +:1002E00015E2F519DCDFC3FAEE0BF93DA72186779D +:1002F0004C300B5571F8D7E98700F3BA43D14394DA +:10030000171AAAEA237EA7A30A059CAED05FF30AB8 +:10031000FB6C57F0DAB94817398A49777FEE443ACF +:100320005406CB4497DB7378FB97427FEE4C3291B7 +:10033000BB8DD92F78EF46B280E78D38E7F72F21B4 +:100340004E1FF787638F23BC43F0E9E9FBFE3DAC0A +:10035000FDA609FCBCCD6CB9B7E97AA4CBCB82640D +:100360007FB1F74DD673C86F0A7CBD19E4F6D3A6EA +:100370004FBCF4DDB91EC3D1EB0BA2FDE7A0D7172C +:1003800032D109A3D77F477AB3D0EB0790995E0F9C +:100390000D43AFAF607B275E9C6505625B707F5647 +:1003A000FD74EE0EEC4FFDF2AC2D8FB2A7F2E95DBD +:1003B000495A4D43B29D2F35C7A99012FF11B4C8B9 +:1003C00077F33EEE1B83BCFF21FD4E9FB605E5D8BB +:1003D00019F47B2C387568BF4F0539BCB32F0B2639 +:1003E000329D1FDF1252E9FB43213EFE707C7330C9 +:1003F000C4FDD9E1F8E65141578C6FFE7A267CF3B3 +:100400008741BE7187F2CE846FBE4D4F5F29E71BD7 +:100410003A863C7328DF40F2D54E94AF9DC59C2FA1 +:10042000466F7AB313E31C037C943C41DF95C132E1 +:10043000C963938FFE73D309E22367FBF030F75251 +:100440008D15F33E188E17E13C62E769EDFC9C4D7B +:100450001FE9EDEDD0BFD74379B63CAFD59F4CC671 +:10046000B8D9D00B78BE7FA2C0C336F4C1D0CF9923 +:1004700026E24C6A2F2C080DE5E75055BACA7A9F40 +:10048000C0D362FC0F43F1C9A1A9385EDF24B4BF19 +:10049000865BA74A31DE3DD9B1CA5006FE3F9D1E9C +:1004A000BA26C4CFBB5E23FAC9F98BB705ED4F2737 +:1004B000BFCF5EF6F33F3D32423F8DA27D7DE873B4 +:1004C000F37F7D2833FF5F1EB2F37F15DEB799817E +:1004D000FF1B33B567FC7F55E86FCBEF8B4219F8F4 +:1004E00072E619E2FB6181EF87BF20BE570B3AB974 +:1004F000E3F3E3FB8E61F07DE719E27B7528837DF2 +:10050000C1F0BD2644F6CAE3047F480F521CBB6B02 +:100510003AEC964A32C2B1C1DA8F57E7FD30BC7F60 +:100520002031BA9FFD699791E99E19D6EE5E2BFCAA +:1005300066BBCA9066266FDF8CFEF9035F0E52BC65 +:100540009FE9C7FBFFC674F050263A982D7339F423 +:1005500041F0B14E8CB37D81FE7F92A9FF6621D719 +:100560004F6717EC1574C1E6FD4468EA50F9B75DB2 +:10057000FC2ECAFDE1C45321C257DF3C9457DBEE89 +:10058000C891301E55184B4BE8273C2EF4D87921E2 +:100590009D9F6710EDB6A96909F359B6B568129E1B +:1005A00037B2F4F74B1C6FB8FE9C7030F89EC3F165 +:1005B0003F0CC59EC767A598DFD9DA490DD9B19719 +:1005C00043A47FE287486E9F6397DBE63CE478377D +:1005D000E5BDF86664FEDD96C783AAD063F1DF5BF4 +:1005E000E5FF2B0374C5FB3B5BFDC3E07B2BC4F530 +:1005F000CAD14CF039F1723A38F34203701EC77E0B +:100600009D7ACAD99FE9B79AEBE4469D648DEB0CBD +:10061000E8BDC45F897F3B643A87345FC893F93390 +:10062000B285DDAEF9B1FF07449CFC819BEEADC6FF +:10063000FDEEED77691588828266AEF7F49BC652AF +:10064000FCD317966C714CF339D0DEDD3309EF190A +:1006500067E386C2ACDE25B3208D7E6316DA0D1407 +:100660008FD0E877BB723CDD518C9FAE93BA9B165E +:10067000A35E9D17E4E74AA28DA7B9AF6DB58D6E55 +:10068000215A759AFAABA8BE16E8A6FB2FCEB8BEC3 +:10069000A7BB29537EC994B06CE275527824BC463E +:1006A0002314D732F13B741CBE7ED5F11609F11D1F +:1006B000AA92343C7A15627482F6925CDA4BF94C59 +:1006C0009757717A01E6978C7C7F46A769AFCD0A70 +:1006D000E77D71B8CC7AC38F27EA39CE2BE0BE17FD +:1006E000C567835C8E5145563E7E303763DCDF7CC8 +:1006F000AE6DD30A5597B5FF14E179ED40FEB41104 +:10070000457BAB15383D42D44B7618DDCB6E59CFC7 +:1007100084589FEF66C5FF3E4CF019740F2168DACC +:1007200019CD87B55B4CED54D62E74E6ED867F9AD5 +:10073000BF5767E871CBBD6726BF8E4E2401EF9986 +:10074000F1978326B1F58F84CC7D424E07DF0E9A58 +:10075000E5246D92C74BBB795EBE6ED209972B5ACA +:10076000A0272657006CBEBBEE4BD149ACBFD2448C +:1007700014AFD067E5032AF9E1BC0CC9BA03FB0B3F +:10078000917FB4732583E9A9F6DA03072F067E5417 +:100790008A7E4FADF600C93BB38C175294B1B27F3D +:1007A000A01CF34659B964A09CC4F236A12737DFD8 +:1007B0005D7BA03D48726CA3953FAA051DFEADE987 +:1007C0006FBBDEAEE13983645425BB6A9D831EF6A0 +:1007D00084F97D2C93B5C4365CD7F977F5AB787482 +:1007E000C55B1C09213F8C8B7E90C4FBF2C6CD12E9 +:1007F00069AAA5FC9E86EDD195C497DB715D80A7A3 +:1008000025607C72707D5299D7A72C45EBE3D7F910 +:100810007719CBE46FF3F85BA08CF3B3E6E1F1BD9D +:10082000C704BDA6C33C7E9416F2352BDA4EFE9467 +:10083000B74EA6F871569D6CD31BF48B77D44EB58A +:10084000DDFBFF7A4EE2A9B0452FB01AF132360F28 +:10085000FFA4480EEEBF5497A92BD1DFFE9EB0FF38 +:10086000D83A3D40EB5411F127486EC79FB5CA8F67 +:100870008175137839DDBAFDB62D61D4BA865FB7BC +:10088000ABAF5532DE93F6DB30F75F8F35FDE7FD1A +:10089000389DA5DE7EBABFBBAB7415C561CDB8ABC4 +:1008A0006777757A8C3E980FB83A109E854FE7B8F7 +:1008B000BF3DF95D8DCE897CE2C9B89F7452E0F9E5 +:1008C000505B13B5630B4CBFB7721D4E85E7B1D9B2 +:1008D000CEF199E711BE0A9C181AE38B2E4739B462 +:1008E000B849A17B1BAE037B3EC557CDBCAF563389 +:1008F0003F8EE77D25207B2EB2E1A2A4E3F722C044 +:10090000988BE7E887FC8E84D8DFFABA236FE29AE7 +:10091000A64546ADA8F73EFD3F45F369D4B9FC6D49 +:1009200034F8FD3D57C5AF356A2DFBD1AF7EA664C7 +:10093000CC9B9C9765E2236ED44E188A8FC571C9F3 +:10094000ADE9A7C7CB99E261915A31374F1F8A07AA +:10095000E7FC19C636219EBFCEF08C76E770F860B2 +:10096000F5683D5EBD56A1DF8F99ABD4BB701FE427 +:10097000FA0689F698187EC3222FAEFE520BBC4EA3 +:100980003C3AF175FDD340E706AEFF4E88E26D2F8D +:100990009BF8495F42FB17E6FE89659E4778FE9605 +:1009A00046F35C30A3E217786F42A25DA2FB1AD92E +:1009B0007C6DFB808B219E85E716D8BC8F0CB3EE37 +:1009C000B6FD40277C4EF87D42AF38F7C5404D97C5 +:1009D000A31E9C9D25F605A78021F6C7B2281DB74A +:1009E00034B3BC75DE3767D2D975AD0D03E362FF52 +:1009F000122406CA1A9ED77A4ED97415FBFB8A2890 +:100A0000FF1DC3F8B5B91DF86D3E98BF2F14A3FDA7 +:100A1000A6EB04FE1A98C787BF7D7609134EB8AFC0 +:100A2000373FE6D38396791EEF96EAC439AAACC65F +:100A3000C9D82EB957993214DE1551FE7B858C0E1C +:100A40003FB0D2A16F02BF47D68917135F8B06F163 +:100A500032E56CF0F22A2ACE3CDAAF213BB75FF2E6 +:100A6000D27978731F87FD35E966A2F3D6AC62614F +:100A70000FF0799BF77701B4907DBF509CC73AEC9B +:100A800082A6C7827C5FA7D222B76ECBA9BE35CB28 +:100A9000E2579BFB3AE67D51263D7FD51B4C2B9CB4 +:100AA0000E6DF7410DE63125288F49C9BA49477CBB +:100AB00074E1A70BC9EE5985FD2B01BE5FE57BEE06 +:100AC000A75D57E983EBB7FE6B4F744F6565FFD7A2 +:100AD0007F93A44EF51CC25B48AC5BB55837133E00 +:100AE0007F397F6F593F1E3F2B13F133B18EC3E91E +:100AF00009731DCD75433B0AE9D757A67E9AE9775E +:100B0000F7607F553FF26922AA520E5D427AB383A5 +:100B1000EED9027D1BEEBF5FD7EAB2FDDE5202CFF7 +:100B2000E963FD753EE19718D47E713E6F0F65DC79 +:100B30006E1CA0FB246B6FC903026F7814AE5B1FA1 +:100B40006B8B7962ACBF51A8EFA1CB324EC9D0718B +:100B500087EDCFD14E19D837310CC322AF1FCBE26E +:100B60007AF278B4AA47CE107F319F8BBDB985AA9F +:100B7000253FEC48BEB729E3EF0689FE06EE8D1B44 +:100B8000B013DF39B07FD6A09DB8C1F5C703078B7E +:100B90002C7622FCF100F9ED03E5B3B3135FCFFA35 +:100BA00023D9891FFDDE43FAEA789D9FD621B775C8 +:100BB0000EFC079EB755F1B7FCC8BEA77B6FBCAD56 +:100BC00063683E92CA3087BF07A61B12E2FB4896B5 +:100BD000CEF7637548871870B9AA2121BEEE15FEBD +:100BE00028A3B349D6DFFF3D22E66B8EE3F1421224 +:100BF000CF199BFD323A584579A5F5407AC4DC8778 +:100C000035F9D9ECE7589664CBAB3E03FE3D9635FB +:100C10007528FFBE20B7FCE11FD17E7D5EA17CD090 +:100C2000AF446FA7F757B75E4FCF6B5B6FA4E7C7B3 +:100C3000423FDF2A253E463EED6DFACD576E63F406 +:100C4000BA7CB787CE952DBDF54F77237F7A5BD9D8 +:100C5000BA63BBAF5FFF9DA9ECBB7B824CF66B57C1 +:100C600011CFE770AF9278BC5F77D7ED66CFE670B3 +:100C7000F544CD02D77F01C39B58310080000000AE +:100C80001F8B080000000000000BE57D0B7814D5D9 +:100C9000F5F89D9DD94792DDCDEEE6B5900713C2DC +:100CA000230AC44D202128D60D011A2B81A0A8515A +:100CB000826C0884008104B4B2552C1B021830D613 +:100CC00068B562B57C8B85D6B6DA06A52D6D23DDB9 +:100CD000085AA81463B50A562020B5286A228FB294 +:100CE000B6B6FEEF39F74E7666B21B82EDEFFBF734 +:100CF000F7FDE2D71EEEDC3BF771DEF7DC7367EB46 +:100D0000EC5347390A09216EBB811411B2CA42FF64 +:100D10002D1372F1E8FDEE05C984C45BAD1EFA84A3 +:100D2000989AB21F32D0323920921D148809647EFD +:100D3000C5580ACD0CBA1D122185000D081D00539F +:100D400008B184054292A09DC7D368A56529401CBF +:100D500000C3123E370942453B7DFF0BF8BB2E0214 +:100D600095FE2C619190F1309EFE7D133EDF249B19 +:100D7000CAE07D3189CD43793F9BBF9FCDE76309B1 +:100D800027B07924E9FBB1B3E722696CB7F69FC7B6 +:100D90007D89A5231D741D7576EF288084741B2B17 +:100DA0006C84DC61FDFD61218F428B35245248FC4F +:100DB000C68FBA7309FE7D311CFEBFCAF1FE184210 +:100DC00004D22D7C41879EF9B9101A46F11757229B +:100DD00006D765532838CA274CA0CD4A8C1EC06759 +:100DE000D78864DB70D5F8C50E01F1F7BAE4B0C15D +:100DF0003C2BA68915C1B1D87DCA1CE8675A4DD1D4 +:100E000066369C85A412329FFD9BBC2E6F6F194ED7 +:100E1000EB0301A36724A5E37C4B2008F39B4FA4BD +:100E200040B7059B085F080865A988BF47E73B7F77 +:100E3000AAE88DB36BDA912FE83CC97AB26F04ED62 +:100E4000FF0E810F10A065FADE315E3C3EF5DCCD71 +:100E5000B08C6EE2300DA7EDEFE8AE9E41F2B0CA65 +:100E60000AFCB488B79BEF379EEAEB97FEAF3AA037 +:100E70002D2F28CE7F859281E225583601F8EC0A85 +:100E800003F2594D8BB6DDA277AFFF80D8A15FE9A1 +:100E9000541FBE619EE461C66FD39A1D32C5D3381C +:100EA000878C749F39F5BDA9849667117233F43B22 +:100EB0006BAAE808D1D6AD7E03F1D2891FF28A4130 +:100EC00081AEED506EF781EB006FC5467907AC350A +:100ED000973C785332D48F77009E2BE0D9106C4F1B +:100EE00008B4735B8223E9B32EEF7BD61A15DF1D9E +:100EF0002A7EEF0A1FA5D75603A98BC64F8434E17B +:100F0000BCF6DD138FFD1C7F54089AE9FCA7899F6E +:100F1000FF61229D4FCD7D468F59C6651980AE3346 +:100F20003C4C1E09F15AA7517CDE4158F93D525103 +:100F300014A2E3D7E41F2D31D37E6A360828A70A0E +:100F4000FE29BE4FAAF1E66BAC480CC98877CD7379 +:100F5000DA9909F899E2F9640C3C9F54E3D9FFEE61 +:100F60009171FB54ED363B6CC9C0E7A480147C4101 +:100F70005173814C4E1C4FFAAF5B8117D71E1EB7C1 +:100F80006F24218F12EFC3A87748B754318ED2490E +:100F900022DE687A60BA9DC9C134F123A4CFD96238 +:100FA00051067C1DF27F68A51C460E7D2E96019E83 +:100FB0008997369A1479EF870E13E279AB89780115 +:100FC000CF5B875A824DB4ABCE7BAE4CEB46FAC8B2 +:100FD0008F4F063AFEDE4876C8B1E76BF38B6404A8 +:100FE00065CC72BF8050A1DF307F1C91C647DA0DFF +:100FF00023D1E7BF1BE498B64F59430C321DD719D4 +:1010000020DE6014BE50DA2DB7F44E9708B60F39C3 +:10101000E9FC56C886A040D79B2FC88CBF8D8DDEBB +:1010200074DA54EA981D4827300F11E721D3F949A3 +:10103000747ED9FE042C0FF72721CCF13B118EF0E2 +:10104000A763FD487F0EC251FE6C7C3EDA3F06CBA3 +:10105000B9FEF108AFF0E723BCD27F0DC231FE52DA +:101060006C37D65F82709CFF067C9EE7BF09E15516 +:10107000FED9083DFEB9589FEFAF4158E0AFC6E733 +:10108000E3FDCBB03CC17F27960BFD2B1116F9EF8A +:101090004538D1DF8CB0D8DF84ED26F91FC0F2D5FA +:1010A000FE6F23BCC6FF30C2C9FE27B11E1410E07C +:1010B000219ECBE303F242079514E07019F83896AD +:1010C000DC5DE4F668BEC37B1CF84E696732109F96 +:1010D000BABDD2EE1CB71B4EA06B94FE3EE1F4FAF3 +:1010E000C473F23BA349846E2DEEA60A2246E8653E +:1010F000DE55124AA7FF5CB17B3601BD40729335C5 +:101100007CDA5F3FB0F51DE3FA6BABD4E515817F68 +:101110001B8927401F954F785D807EB6C952593094 +:101120000ABF8D761AF1BD710EDFBFC05E25649FC8 +:10113000DA07FA6456C0F18729C02F63937F3F8591 +:10114000F6376CBD0146A0AAC4D13985EA1D792ABB +:1011500041BDB88D1094A76DF15A7B3ACCC9F041CE +:1011600048FBFEE1284F230A98FDE9BE1EE4CB743C +:10117000CF70B2391BE42D2448B4BFC02A42762870 +:101180003603DA6F5CF003A88FF467C2750E6B212B +:101190002F59E844B2DBE4297114E66CF1BE144720 +:1011A0005F1919F44D89A7E5D1CF045E0278457B1C +:1011B000704A02856376875EA2E6948C0B754FB108 +:1011C000D2F255FBC95E406B7E975C6AA3E5F1875E +:1011D000BD7B291B90C26E5FA95D86F9049BED74EF +:1011E0003E5B8F114F132D177FD426261215FD4D10 +:1011F000C4B7534517DB84AEA949F49F197739F278 +:1012000045785FEA8E738EED4F9F6DB06E5827B5AF +:10121000233BE8BA32BC21C1A1E2931B9C4C6F5125 +:101220003A5CE5043BB4A65782756E5BEFB221FDD4 +:10123000E21D253064EF34E2785A063E96104FA640 +:101240000DC351DE15BEA3F8BD62B64D8D3741D139 +:101250006B75ED6363E3F70627D37FFF2DF87DC73A +:10126000C1E421167E2DC02B932E2DC755CE3E39BD +:10127000AE74A6C46ED7C4F1AFC7F33603D94F6DB1 +:10128000151D97F229932B12A04DD770FEBE145E48 +:10129000EFFE2FE3DB9B9C03E395C8C9A82729BF7A +:1012A0005E417262EB1BE82F9AFD7A80E351A5E75D +:1012B0004CE02FB638A89ECB89ADE76E755E427FB5 +:1012C000713D63E27A5C196F0BE7EFFDF68AEF8000 +:1012D000DC58371802206725C4867241DCC99C4F50 +:1012E0001CF1C02733444709E81B329AA01F9D30E8 +:1012F0003618807DCAB0805C20423350CA80C7A1B6 +:10130000B9C1CDB4EB6CEA674894FEB4AB10408B26 +:10131000EC302CA0EB4E54E4CD51ED56CB9B62EF5C +:1013200023F2A8F0856BDBE66CC6AFB3A9FFF236FB +:10133000C753A41F01DB6DFCC6D06D9B557A709B13 +:10134000DB8D65A57D2CFEBDA0F0EFFA75C407F21C +:101350003139BADFF0BA53E47CDBEB053E0F7C8514 +:1013600038C09F71AE3F89FAC949F59380FA898DDB +:101370009FE18FFF418096BB9CA95C9F3BE26FB1D0 +:10138000FDFFE3E71D4EC2F4D46447A748EB875145 +:101390003B24839C4EA6739F00F83221DD65C2E892 +:1013A000284F2641F07B29DE4206D0BF065B10ECB9 +:1013B0008CC9D4E60579262627AE7FBFDD77DC39D8 +:1013C000805C3812E47C206AAF335C66A5FCB731E0 +:1013D000DB110FE58F69B9D54DC77575135E6EB119 +:1013E000A2FCD0BFA148C510DD1B807D54CA5E0B96 +:1013F000B41FDE570E40792BF82457D3FE1FFEDBB7 +:10140000FEF51431B39DDE4F9C8CAF7B017A47D340 +:101410000D6A4E849F2FE50F28F219912747BE22AF +:101420004FD563511FFEDD5918E92F967FB38BEB23 +:10143000CF04D7C0FE8DC2F797EDDFF0F97EC6F579 +:10144000522CF98F3BF0C696EDB4BCCA2DCAA7A8A2 +:101450007F671BFA569744CB16EA6FBE47CB064B05 +:101460009704EDCAA9845A29BEBDD4C983FD8765F6 +:10147000022BC31FEC3FCEB609654C5FCB8973C608 +:101480000D84C720AE6795DB84E3C58D1C9108727F +:1014900065E77C4524210876DC5EEC9016607FDDF4 +:1014A000E446DA5FAECBA0916BD05BCF8F05BDE495 +:1014B0009260BF6EB69080CD15E91FCA890511FDF7 +:1014C00044F83EEE4EBE676A5BE7491C01727A88BB +:1014D000C551DABEC9E4B23C8304D7819EF012D96B +:1014E00041DBC711E58F0A2E2D1B7969C6DF05E2A6 +:1014F000A5F33FF87711A13082846C74BF57EE11C9 +:1015000042B00F34192C41B0A525432DC40465BB4E +:10151000216806F93829E03A4D050941507E538784 +:10152000162776D3759C3BB8D7EA8B42FF5B7DD5F7 +:101530009EA9E363E3B1AFDDBC971D80C727E5F546 +:101540000EF023036E09E30E9BA0A94AAFDFEA3237 +:1015500029FED06C17F8430B7BD79B80DED9C9E8F6 +:101560000F91112EE4DB21EE5D9B4AC064D533FF61 +:1015700074280936A9FD2A85BF8EB87C73A19F27E0 +:10158000B91DA162D9350AE2555724BBC02F2D6978 +:1015900018DA01FEEE136B8967A111F5C14C68EFF3 +:1015A0004D6ACF07FE7DD2B3EB470F013ECD745F8E +:1015B0000C7A7CFC51AB4CE95555B83705D6F3078E +:1015C000DDFCFBFC0FFF37112FFA7DF03217DD0732 +:1015D0008342CC2379B00F3EE7B9293184BC9514FE +:1015E00055BEABFCF7623FCA7EF85D6328D3115548 +:1015F0000EB5F856C6AF12D8BE961805A6FFB81D90 +:10160000A5FAE53E58277D0DEDA6D72C3C0DF6E654 +:101610009C67BC07EC762C7DA3CC87E27164852D9A +:101620004ABD402AA2E989C75DCC5E5719E97E818F +:10163000D60B2B0B1B615E5536AB007CA7B46BE65B +:10164000ED147E56E25562E2E785407F880F465BE7 +:10165000FF7C229D57C7A39A41D65218BE3C51FC2D +:101660009558F83A6C6C2B87791D5E249226DACF58 +:1016700039DFC43412E57D05BE037C43E9B21CF6B4 +:10168000FC852A7A8E888EBFC36BEB3C538D117A12 +:10169000F6ABAF8EAB04FB5D0978548DBB9FE3E5E1 +:1016A000848BD97B62F6C90E5A6F5AF098838C03EB +:1016B0003D75BE306083B858EFCF9B80DEF7D930E0 +:1016C0005E51597DA1B0699C0A9FC5048DE4FCBDA3 +:1016D0004F3864FABC72E4FA948035361E4FB8D89D +:1016E000BA1E800793301EB3D77519F11832D6850C +:1016F000FC46F6C67942108FFC93E801BF01C6F59F +:10170000A1FE64F1E4BB1C6C5E713A3FAFD2BF42F4 +:10171000A35F12C2020926A9CA523BC66713C212AE +:101720003ED7CBDB0E178F3B717953F01F8B9E0A90 +:10173000FEF5CF431CEF87AB97C8103734C547F78A +:1017400083D392040D5FBDB5D6A719EFED7F8A9ABA +:10175000FDB202CF73FA9EF34D4A837855A5293026 +:10176000723072AEE0E7ADCF1F7740BF719F99A393 +:10177000CADFC7DC3E517BDA72B3ACB2A7B789EBE4 +:1017800001EF0912D76F3AB9F3825DA5F8BC0EECF0 +:101790002A9D62C225ECEA7C12E88438B27E7CC5C0 +:1017A0009EEAF94BB1AF7ABA297CE04CD2EA4B25DC +:1017B0006E184BBE14B93AC2E55F8F7F3DBCD5A40D +:1017C000F57B14F87E1F3DE24880EAC73B4BC420FE +:1017D00011903FD03E1E7E4C407F33546D46BB5C23 +:1017E000531D87F1D99A7C11EB6B1E14D17E86A80C +:1017F0007EA8A7F3F903D713FAF86C09113C5355E7 +:10180000EB9E39214E53BE6DD1B7FFB016E2CBC56A +:101810004619C63B24B37873C02BA2FF4AFBF08461 +:10182000203EFDE8B51EB0670A3F1CF28A286F8192 +:1018300037450F0CDBC5E3D1875AF28322D059F02C +:10184000F58D23E740FF3532D0E1887B8B03F45DD3 +:10185000DC3F1FAFA8C0FDA34FCE47BB499D553A03 +:10186000EF382EA7A5438B6F013B7EBCD548206E79 +:10187000747CCD3994E7EEB58D9EA92323F16525BF +:101880003EAC8F33EBE3CBFDE2CABA78B2C20F7A3B +:101890003EB939067F28FA2A167F503D5695947234 +:1018A000F97A4CD11FEFF075960EDDF26013C54347 +:1018B000C24211F1A0F0E591CFEFFF1EE8E138CA76 +:1018C0001FEB809FFFF9C397611F42960851E3C841 +:1018D000DFEBB37B942EB911BADCE65BD25706F18D +:1018E0009F5BB7B2AF0CEBD7DB95D87A6D60BD3597 +:1018F0002C89C581F476472F0FFF69BB5359FD58DA +:101900002EBC5F59BD280870D3504B1DE85FBD9EAB +:10191000D0DB09653EFA79268445121CAF9EB78C50 +:10192000ED2276C284F57E8B3D0F9CF58B710C0603 +:10193000C00904BFF4585CB019C76BBCAA02E7DF4A +:101940003811A09F78BA03B03E773CC60FDA325800 +:101950007BF1FA78E68F4F70E13A45C5213FEFC43D +:1019600072335FC35897EFD9243A8F66AF210ECEFA +:10197000154A6DD20108B9B44D31103389E049F1EF +:10198000DF094406E87AB14E807D67BEC59483FEC8 +:10199000E92EE4DB6FD27D21E5F78307C55DDBE847 +:1019A000120F7AC62746F3CF1538CFFD0DD40BB7EB +:1019B000F86B101EFDFADB5920AF770BBEDFC2BCFF +:1019C000BA2A6B1E2CA4F369D82DE2B9D2BCBB8F06 +:1019D0008C62FB34EDF9A468B7E4421CA55988F782 +:1019E000801E51F0D86933A17E693ECAF460F309C4 +:1019F0008197D93E621FAF3FF7AE0DF7190ADEE9B6 +:101A00007A0EC1F8DE6F3B713DCA3EE3DF58CF91DD +:101A100081D793E1407D017C2546E62FDA245C578F +:101A20000F89F7C0FCFD3C1E44DE8D43BF59A16FFA +:101A300003E73F85BE2B387D7B3A2E7CEB1ADABE5E +:101A4000CDEBC253063193E07A7BDE4D40FE50D69B +:101A50004BF9E06398DFDE0E6627DA8ED918BE6C8C +:101A600045B9303FC5BF7624313F59BFEE2ABE4F3E +:101A70000F27097DFE2DC4297CAE29E1A428F2A000 +:101A8000F8B514CFFF80FA1207391F24113C2BE35D +:101A900028E32AEF9993B5F255C5E30AEF1A4925D1 +:101AA000C41361DC02D5FC56BB4ACCC929FDC7FD75 +:101AB00037E8E84ABE0C3A3648D6162191F4ED8B49 +:101AC000319426F79773BD9C091D9D9FC1F9BC5E9B +:101AD000FE2F1A1A8940FB5D2DFA0EBB286CF69179 +:101AE0006E734E7F79B8941EA1F4BE32B9B0BF3E7A +:101AF000192C9D0B93FBD1B93079003ACBAE8A8972 +:101B0000500FEB4F2FC07DDE2428839E300DC7F190 +:101B1000902F7B9D24F8346D94C4E328CA7C202E3A +:101B20001147DF2B4BCE46FA0B120918693929D71A +:101B30002380DE1F041F94A9E7F71FE0839B06E6BE +:101B40008310FA25CB39BD972B7916BB06CEB31877 +:101B500004DDAA61DC8B064FAF2FFBF2E956DF9F55 +:101B60006EF503D3CDD700F2D36C22E7D10F2FAEA1 +:101B700076C378FBEDDE9389F4F99E26AE4FB22949 +:101B8000DD68FDCBC922EAAB47C895A887BF6230A4 +:101B9000E0FC7BA8FE7D3A3B1ADF0724177DFFE2BD +:101BA0008D04CFE3E8FABE998CFE4F4080E7ABE7A7 +:101BB00013033C77CB4DC470197A6813D713AA75F9 +:101BC0006E52EB81287AA815EA293FDE05FC689160 +:101BD0001DD2407A68CBE5EBA12DFF613DF4FD817C +:101BE000F9EFB2F9EA598677AD3E50F858D917C4E3 +:101BF000CA17A2F248D25DFDC725C483E7612576E6 +:101C00000BB3BB3B05B4B3CD27F27D58B659502971 +:101C10002876F8EC2E562F4E89EE0FFE3CD985FC27 +:101C2000BBBC7DA547D2E48104F0F943DEB38E113D +:101C3000542F4E17ADB8BEA472163F54D64FF5ECD4 +:101C40008C69A93C6E4AD79394C9F09044FD013841 +:101C500047B3F3FD4162B1A4F1FB15BCAD162B04F3 +:101C6000887B3B9309A4DD50BF7ECD6838BF777A6F +:101C7000B5ED5348EBA7220E42501E5CD47E431CA8 +:101C80002BA94CD70EF62179D05EF53CBBFF7EE246 +:101C90007832DF4F98881BEC0A11AB06E41BD57E27 +:101CA000E2FDE441EC273E4A56CEC7B5F6AB3D8E89 +:101CB000448D0BDC93C2F71FE79DE8FF8ADC6E4D75 +:101CC000EDCEC6FC94553619E305A2E8B1CCC8EEBA +:101CD000FFBED36B20B26A7D4965F14456ED1F52B9 +:101CE0002A5C9A725AE5504DFB21BEE19AFAF4BA89 +:101CF0002B35F5998D059AF230FFD59AF6D9540017 +:101D0000D4E59C96AF69DA8F6CBB51531EBDE57666 +:101D10004DFB2B820B34F5639E59AAA91FD7BE4AEF +:101D200053BE6AF73D9AF6CD3CEEABC7CBB51CAFC0 +:101D3000CD12D33B4DD6028C47365BB5F1C8B414F7 +:101D4000A67F4A1227E7421CBCF9647E2EE07B9FE7 +:101D5000FD6A8C8BC7E20BBD1E8BA53FF5CF8BF8C0 +:101D6000789FBC6432801CACD84BE5F52A5AB6BECD +:101D7000B311D6D432969DA74A84E5F728E72BCA3B +:101D8000FB7DE72B9287C557ED56B2390A5FA4A5B4 +:101D9000C851E39F0A1FC5C2DB3D83C4DB5778BB34 +:101DA0007F176FEF0AA4523D8F2A7E9EAD7F6F751D +:101DB0008A819F07FB2A5398BF33211E3D7107CAB2 +:101DC000E3E5EA7F651E54FFD7A4A480FE7F63DEAF +:101DD0006AD0FFBBCC1ED8937D52F946EDE332B4F6 +:101DE000AF65ED0D9E5CA04BACF8F7EA947EF1EF89 +:101DF0003A16FF8ED7E06D514AF4F877B3FDEF182D +:101E0000FF6E3679720713FF5E043A2305E8C0F8C7 +:101E1000A38FBE3C7E1E6B1FE427E48000FB1EAB3D +:101E200024C339D7A5F6B5743F9B0BE7A96DB06FF6 +:101E300052ED73E8FE96EF6FE2D02E50BBD79A8238 +:101E4000FA911C90E9F38B74DFBB5986A262FFBC48 +:101E50001ABFDC4C3C169388F47C04E849BE49EE7A +:101E60008A13215E163A3839FBDFB2E7DF4BB90C33 +:101E70007B4E2E7D2E8776A79CAE7F5D14BF4B7F59 +:101E80000ED7E77F839F26E0791CE26903B58B704C +:101E90001ED799C2ECF386A36C9FBCE1C46C37CA11 +:101EA0004D4AD180E77083D537BF4DE9E797FE36BD +:101EB0006500BF5459FF2ABEEF9D268E6D8778E3DB +:101EC000D9B009F12612961FD9B0DF4882484F9643 +:101ED00067ACD0D118DED805F6D948F479C572229E +:101EE000ACDBB85F44FD4492597D80589AC0CF491D +:101EF0002CD6DA2DA7576BB792CA5C3A3BA6B55BD6 +:101F000069955ABB35C4A7B55BE975053A3BA6B5DB +:101F10005BC3FC5374764C6BB7725A6ED4D931AD37 +:101F2000DD1ABD456BB7AE086AEDD6986756E9EC89 +:101F300098D66E5DB57B9DA63E3FB459533F7EFF5C +:101F4000239A7261D77735ED171F7801F36F261E3C +:101F50007E5AD36E52F78F35ED28C2BB204F7B21BE +:101F60009284906B4E3FAFA95FC8FDB46B7B7FAD91 +:101F7000E987B4B17CEB00FD0FE8F557E2338173DC +:101F80002291DE57D2295D5704054F88365BB27B1C +:101F90006711CCE3CCB1EBF7433F8BB768F3B49751 +:101FA00004B5E506323C11F44303E58B20E5936567 +:101FB00090BFADD26BCB48A31DF32106C9678B0F31 +:101FC000DC4430EF33E0ED82FC74659D0ABF793963 +:101FD000BF29F353D6BB8CFA7D2139B24E2FFD8F2A +:101FE000ED23BB4DC0B7B5BB05F25DA1FF7AEA3A60 +:101FF0001EDE981E655DFA75E8FDCEBC546D1C7B37 +:102000009A68C5B8FED937450F8B0F6AE570D501C0 +:1020100016CF5FF59C80F1353D3E14BF34165EC48B +:1020200000DB273424936050257F32C787D9AD95D4 +:10203000BFB3F00F98CF536210F282E2E4783DBF55 +:102040001585487F3C27E46AE5548F679B67685491 +:10205000BE92E97F308F5AC2CEA5F47CA5C7FB8A19 +:10206000DD0F9B402F5E2EDEE7A56ACF0795F38339 +:1020700012BA5A53943C3805AF745F5E935A187B7A +:10208000DFDA907AD9FBD686D4FFECBEF59ED40178 +:10209000EC5C0FC4CBA85FA98F97F58F8FEDFD4C3B +:1020A000B0631C9AC5BF7C1E0BCB57D1D9C95CB796 +:1020B000C64EF6ED7B4F0AC166DAF912BB7713CC38 +:1020C00067A9DDBB196099DDFB807ABDCD142F783F +:1020D0003F87DAA99D51FCC3975315BFA802E3229D +:1020E0001B4A587B7DBB9FA5B2FB3C9D29456EF4E6 +:1020F0003B4FE433FB692B1AD0EF7C889FE73C0011 +:10210000E7852323793C0FF273152A765EA0DB0660 +:1021100063855B9DE7FB48AA13C7B34F7ABE0BF2FA +:102120009D9B1D06872083FF6CC073D1F55E6BD924 +:10213000AEB1ECBD64CD7B12DA6111F00DFEBC5581 +:10214000FABB9A6F5FA6B884FA58EB7C3995F9BB55 +:1021500046E2B580DE55CE738D27F32DA06F25C1E5 +:10216000E38896C769E4795253F879AEE860E7BB33 +:102170007D727E893CA97ABB6F9F9A6ECAB9EE1CAC +:10218000BBF765A0AB5F0A98C1BFF45BA2EF7F5FAE +:102190004D65FE470B5F1F7534918F707C7150F158 +:1021A000933753312E17C07CC5D5A2E734C4E70658 +:1021B0001BAF3A9EDACFFF399E3A70DCFC64229C5A +:1021C0004F240E95703B21797281FF5BE0DF9330E5 +:1021D000BEFA3EBCDF2FFF5476F17C5A79C07C5AA0 +:1021E000A59FD94EEFC78057DA5F4F2ACBFB5B2FF5 +:1021F000AAFAB15FA21F8AA7DC46EBA0F0F739C3A9 +:102200009FE7340B265C5E5CD39CD62FDE674E1BAB +:1022100020DE77F1E8E844384F56E256FA76167F2A +:102220005286FA7E4C8B533BFEC6025676A531BAD7 +:102230002D4E647C3F8ACF43C90354E2D69619C41D +:102240000BF71D1EE1F9D94A3FA3D26CD83ED13518 +:102250006514CC7763B680FBCA8D4E41B3BF3C9901 +:102260005A322A8DB69379FFA3D2189F6E1BCEE205 +:1022700033FA3CC833BCFD99D42908E99B57003E8A +:102280004DA218158F63D2581EC64988911546E293 +:1022900067358FB1FB5D4ADC4C890312E2792B81F3 +:1022A000EA95F75A8D04E25A8B44EB46E0C3BEFB35 +:1022B00073FC5CDD41FF037B593DB602F38FFEDD0D +:1022C000FB5B80CF04577F7B599AD6E7A7782EF324 +:1022D0001ED7D7D22EE3BCBD3B9EF16DAFCD8AF1A8 +:1022E0006C7DBB859C3EAD3C4E01FA1AEC864B24BE +:1022F0008DD1ECC7C234C637178F9ABDE8C794C5D5 +:10230000633E8772FE2149C01B98061E0068F1A734 +:1023100067C07DA2BEF30F99E07B49562BBE27C94B +:102320002464832BA1924780FCB26E53F7863498C5 +:10233000EFB58207EE0FA455393AD392E11EA18C76 +:1023400062B6319BD88BA13EDF80F5CE398E8D46AB +:10235000C8BB96099C6413231DC746C7694DCBC6ED +:10236000F5B7066EEA4CA3ED12E55E327C2CE8115F +:10237000C77437C87125CB5FD7AFEF3E2E1FD60D80 +:1023800074DF00F890A3E781DFC7F98FEA99354041 +:102390008F1299EC62F7A2581E2AA45963BEA08737 +:1023A000E54B2740BE510ED33350FF90B3741DF060 +:1023B000B9225F22C737F0BD3A1FBE95E33B4927DC +:1023C0009F0A3EE9004D900F21CD20C8D7B3AAA2A5 +:1023D000CFF7879CCECBED158FC07C674D6EC23C8E +:1023E00077F2F9175F8845E0F43239A1EF1388439B +:1023F000C42533FD1B27CBA88F8943C03C538BECEE +:10240000A983729CF56A870876CFCCCF0B171A8800 +:1024100044E5AD94F7E3AD24C2FBB92CCECAF4ABCE +:1024200044DE57E442E4C82902FBC9FEA85FD49AFF +:1024300040D7536A3D88E78871231A4BE05EC1CBD1 +:10244000F3591F8FC4C8DB3F99C8E8E0127D6E03C3 +:10245000F8F4E4E4ABFB26239DAF841B9A0F6C7861 +:10246000F7D5FD993C7E0EF9E281775FF55ABF7C86 +:102470007EF9BEC7DF7D15F2CBBF3CFF7B04D0E306 +:10248000272963C1BCF5FCAFE8B3C3A2EFF0BD14CC +:10249000FF3753A6F21700944815D29BE50FCDE104 +:1024A000780EFC9DE2D912C1F3CD1D07107F878DF8 +:1024B00074DE747CE314866AE33D893C1F2388FD47 +:1024C000DF62699B06FE4D8FA9370FC6ED79F1EDEE +:1024D000CC00D52747EF3B672394FF8E4BBD367862 +:1024E0007E7ACD1B36C0D7D13522DE7FC37BC9AA09 +:1024F0007CA0F7395F95BA2B8E025FCD5FFBCF22B0 +:10250000B59F4DFC296877970445B8E3DBA7FF9694 +:102510003D93C0998E9597B72769CA8A3D5E6E8EA6 +:102520007E4F3CDDCDE8BEE4D96D26C8872F75FB14 +:102530007A409E4EF37C83D3BB6CB8BF52E6B3E0C7 +:10254000D97C13EC278F77984908F85EEA32128C11 +:1025500053796708946F7D9C0FF5F37C654F02F605 +:10256000B7E83111E348D5742C3FC5ABAF6309DB45 +:10257000DFEAD6B1E8A83C1DF4D5A24D0209C8ACEB +:10258000FD1A4A379FFF7E3C5FD1AF536F5F2E909D +:102590003526D0237AFBB290785A2683DD6AD33E63 +:1025A0005FDCF100F6BBF812E7314E37DF9F159183 +:1025B000895FE4409C7938E60BC6B237A7D732A1D1 +:1025C000FC70AD05E1476B1D088FA631BE5DB6BB43 +:1025D000F3957414EBAE22B04371074A2DB793887C +:1025E000FF2C6DBB29F4A40C7CA9CD87ACE27856F6 +:1025F000FCE7C5FC9EC1A5FCE72A58E700F9905509 +:1026000083CC873CBB7FBC059E8F57F03191E203A2 +:10261000EDEFD8D7647269FB1B0B2FB1DE5B0EDFC9 +:1026200039888267456E8E723BB270FBEC8D43E950 +:10263000049A5FFC6B5637F2258B4328E754A27B44 +:102640006317AC5F24BAF85F80BC4954FCABE7CF9A +:10265000C5C4C3EC8E95BD67E171893EBEEC7810B0 +:10266000F1AAF011DC2830B80186DC86E2FEDF0D2D +:10267000E8F77D80366DF913637716E88DC5BA7873 +:10268000C12742F4FDD734F770B67ED93B1DF22244 +:1026900016918A8D2CAEDE86F8392DB5BD722FC805 +:1026A000F376264FCB7FF9DC2F404F2DFDD9637693 +:1026B000D0531F486DA9305EFD8E0D762FE82B2973 +:1026C0006087F73F088A51EFEB06DDFC1C9078AD80 +:1026D0009017B602590C042C3013F4E4DF76181D61 +:1026E00010476D78C61C32537CACD8C5F048CB2758 +:1026F00058F97EC457C36EAD1C2EFDE163A932EEBE +:10270000E703E91C7FE9A0AA576C3762FEE88A3725 +:10271000450F0CD3407A717DFAF7611E614AB78686 +:1027200076B1DA94D8BF9E7A3C2690B3865D8C4E03 +:102730000D3A3FB38EEB653DBFB7E9F89CE205E388 +:10274000614A3E2B0932FDDCFCA3C7F34ED0797DF4 +:10275000B4FD55BB3036C2EF04B22E291DCEB6D71C +:10276000CC873C83587CFE09978B3EBDCFED8CBC5B +:102770009B4E0C7CFF0E06EB8D21FB35141FF5DB09 +:102780008C9E007D5CFF9CE8B5829F74C48CDF77D3 +:1027900058F6DCCB6F5D4DE7B76CA73179065B86E9 +:1027A00015F4B342A706E0EF82085D96BEF0B209C9 +:1027B000F220E1F91A57843ECB76769A20AF528FF9 +:1027C000C7D2F64E13932F1D9DDA4F4C07BBDCFC8E +:1027D000A38B26E0830FF608045C48FDFB75DB5EE7 +:1027E000B683FE003C81FD50E8D547BF7E740BCD1B +:1027F000FCF5046CE780739A58F45B09732944FE76 +:10280000FEE9AFE9F875EF983DB0FEBA9FDE698743 +:1028100075FC556A647CFEBD0DA9608FEB8C8154FC +:102820000742F6BC6EEBD791FF16BFFEF554827AD5 +:10283000D33B04E497AE7308AC6FD15337E3FA6A25 +:10284000890FF9AFEE7B6205F88917245216CDCFB8 +:102850001F3284C9C95F9F36E3A6E0AF26C2BEC35C +:10286000F14791E5F19195E8877C9DAF956A622CDF +:102870005FB0303A7DCCED33E17AAC81B76AD87E77 +:102880003FEAB10F33BD6920EF140FDA78EAEBD3DA +:10289000D2B8FEC3EFA5E07B94EF4AE139B4EF3242 +:1028A0007AE3F234EFF1BC5636FE5D7C7C3AEF7889 +:1028B00088CBFD3555BB7F55E05787287130D24511 +:1028C000D4FC154BEEB76F42BE3AFF26D32B2B82BA +:1028D000B3CBB0BECB184A83FA60E71C01F502F512 +:1028E0002FA2C9F57623976B6D3D9DA724A8F1BB58 +:1028F00087DD8BAB7D94B653F92111BE31459E67C0 +:1029000047E453C9AF58ACF3CF14A8D70B4943B42D +:102910007A41799F3C9512F51E56441F0490AEF5FE +:10292000C6E00FBE0B727CC48CF70CEB9F33E2F752 +:1029300072CE3CBBF7ADDB29BF9F6957E457AB674D +:10294000F5F25BF7FCCD249AFC9E49AE2051E59749 +:102950003E8F2ABFC92C7FFF7F5ACF2E8EA167AF33 +:102960001DD2CF9F48BC86163FFCF1B261B8CFD2D2 +:10297000E155C1A75E6FBEE596A3EA4DFAF7265171 +:10298000E151C19FC2974B7FB21CC7E9E35F853F0E +:1029900015FEEDE34FFD7AB578D4D71BE0CE51613B +:1029A00084EEC675747F0DE7AE2F8A78EEDA23F7D2 +:1029B000DA5D1097E579373D0E5E76B2726F8A69FF +:1029C00023E80FE5796F1CCB43E8A9E8B53B557EBA +:1029D000FD890ED10E79F5DDC1E8F912984901F1B2 +:1029E0008C18F914CAFDD969A235CB0FFBB2367623 +:1029F000DEB3B0E9563BF8D33D1D39B32AC18F3F52 +:102A000020A24FD513CFF3AB025E6908C56B0D5BF7 +:102A100032394D02DF013FBBA663D90CD8342E6C8E +:102A2000D5E2A3D63A07CFB36A1F3546F88280BFF6 +:102A30001334819F55F794F6F952C8AB02FAE8F8BF +:102A4000C8077C14E51EC646858FF2493EDB27F396 +:102A5000F32AAED7A68963675542FEE27E764FE23F +:102A60006C874836C27A9FE5E7578114E4CF159406 +:102A70008FD571CE8F80CF46C7B6DF1FFDFC68D1E2 +:102A8000BDB449FD2FFE9CF724851FFDE2C8A8DFD9 +:102A900040F9976F67FD99F46F5FBAE7B33B308FEA +:102AA000728F99C0BEA867CFEFB2EE85F2AFCD1E90 +:102AB0009867CF3AB63F0EECB1A15DEFC964FE5FF7 +:102AC000F38B17F3BAD13EAD477AED1CC2EEA99E47 +:102AD000EDF8C73101F2E93AE8AAC0EEF27D57C33A +:102AE000AFE3707FDDF3E245CDBEF2DF5DCF0A7E5E +:102AF0005FA9C7462AE17E718F93DDEF6CF8CDA404 +:102B0000EFC37DC5E5BB3A4D35B4BEF4B7FFCC038A +:102B10007DD3F33CF327A87FBB155CEA8E275E6D5F +:102B20003552FA7D023EDF50BAEFFE6E4239DCC309 +:102B3000E88F1786871E8A075817C54B1DE8C958A6 +:102B4000F8786308BB3FF2DF878F4FEF80F1EB3BF4 +:102B5000261288A747F02278D9731BE65DD0F5B31B +:102B6000E77B2EE6817F74A9F57EFA7F6CBD8943F1 +:102B7000FFBBF9FDF12132CE4FCFF7FDF9FA977780 +:102B800063F9A7360FCE7790F27ED5D0FF5BF42E97 +:102B9000FF5F4BEF039CDE36079CA7F4BCF8CF2CFD +:102BA0007219EBAEFF5FBAEE3E3FC7E0B14CA0F347 +:102BB0007B87046F2E1162E7713E3154BB8F98C939 +:102BC000FD8899C9B5E83FCCF4B2F84A3329D80F4B +:102BD000F7D4025E11CF1D309986E2A16B4E7E10B4 +:102BE000F3B6A4C0C8EF401ED72DCB3DEC3B5FDA57 +:102BF000FDD5CCD4B232F0DF0E35D179D176876CE9 +:102C00000647335DC22CAF88FE1E85E8E7FD69CA22 +:102C10000D981732AB58BBCFB85DB76FB8B5525BE4 +:102C20007F0B793A05F2EF6EA93362BED0CDBAF6CA +:102C3000AB873A709DB792C60D2C3E7379783AC037 +:102C4000F1D41F0F03E3AD1F9EF87E127379E4FEEB +:102C50007833FBD8FED24C2BB8BFC5F3E4560D0A2F +:102C60009F84EF3BCD7C6805BF662FFB5EA7AA5F04 +:102C7000C48B82F7CBC5B742273DDE15FC2A78D33B +:102C8000D3E12938934889E03F02953C121F51E770 +:102C90005BCEECF31BAD88C7D7B6B3FB0AAF15D735 +:102CA000B4E643F95901FDB50B93C7130B5DEF2152 +:102CB00023D9CDEE7F79654751249F4528FE1D9E7F +:102CC0002B403EA17A5F0AF984EA75413EA1BA0C15 +:102CD000F984EAF6904FA8AE877C42753DE413AACA +:102CE000CB904FA86E0FF984EA32E413AADB433E7F +:102CF000A1BA0CF984EAF6904FA8AE877C42753DE4 +:102D0000E413AACB904FA86E0FF984EA7AC827542F +:102D1000D7433EA1BA0CF984EAF69047A8AE873CA7 +:102D200042753DE40DAACB902FA86E7F5DF8254D2E +:102D3000B984BCAA695F6A7943539EE6F8B3A6FDDD +:102D400057DDEF69EAAF97CF68EA15FADF907B4E5F +:102D5000F31CCE2C0245B08F617FE59E7F68FA910F +:102D60004805C6994DA411A105E2B714C69376840F +:102D7000562AE6004B47F972D2815FB706360273D6 +:102D80001D9A74310BF4FF6B936F62F1077E4E3026 +:102D90000BFE2953264EF83C03F6B5CAB9A73D2CC5 +:102DA00092D078CA876101A1239C404249940FC305 +:102DB00071085DE1247C9E1476224C0EA7E3F39407 +:102DC000F01084A9E11C8469E16C84EEF01884435E +:102DD000C257201C1A1E8FEFA587F3116684AFC15E +:102DE000E799E14908B3C2A5F87C58B804A11CBE14 +:102DF000016176F87A84C3C33761BB9CF06C84238D +:102E0000C273F1F9C8F06D0847856B108E0E572319 +:102E1000CC0D2F4378457809C22BC377E27B63C280 +:102E20002B118E0DDF8BCFC785BF81302FDC8CF04F +:102E3000AA7013424FF8016C971FDE84B020FC6D1E +:102E40007C3E3EFC30C209E127F17961F8098445F6 +:102E5000E1EF239C18DE86B038FC138493C23F4216 +:102E60007875F8057CEF9AF04E8493C3BFC1E7D71D +:102E7000867F85F02BE1BDF8FCBA7027426FF855CC +:102E80007C5E123E80704AF80D7C5E1A7E1DE1D495 +:102E9000F09FF1F9B4F01184D3C3EF21FC6AF80478 +:102EA000C2B2F01984D7873F40F8B5F0397CEF867D +:102EB000F0A7086784FF81CFCBC39F21ECDBEF4FE6 +:102EC0008E752FD167F802F6CF56D7A0BEF345C84E +:102ED00016CDB9D4E30976D493B3D6B03C928D2500 +:102EE000E7A6A25FBBD22CF3EF6BEAF4EAE756F059 +:102EF0001F3640CD10D607E401CEE3FCFB5AF1DECD +:102F000014F097361674D7433CE4C1ECEE2A84E9FA +:102F10002CBEBA9EC307D259BCF4F651CCCE56ADE6 +:102F20001C89E757247970EBF803D8E79448FBFA3B +:102F30004C5EB6F666E1BD8041F633D87697CA8F0F +:102F40005A95EE0BA6A35FA4BF9F37E8F79F413DBC +:102F5000F1E5DF6F1FE8FDE39C5EF68C8A5D384F7C +:102F6000C99B07F553D60D1193693FD5AD8203EC8C +:102F700064CDFAFCE940BF02E2C578E2BC18795D95 +:102F800047D2599EC682462381B8E20299603C77B7 +:102F9000C12E96E70B71D072CA17759C2F966FDA07 +:102FA000690217B4AE7131CB3F0AB2389385FE0780 +:102FB000FCBCB47536E61F2D7B461B7FAA87B88EF6 +:102FC00008E7C8DAE70D3CCEA48F57EAE34B7F4C05 +:102FD000E7F1250FCB3B226206AEF7025D2FE473CB +:102FE000F8EEB65940FF533CE03989B27E255EA920 +:102FF000E081F4BFCF8079A167F78FC43CB5B3B24D +:103000009C06ED7C549CBAAC90FFE09B08CF29FE57 +:10301000309FA4B72901F3914E507D2E43E293C314 +:103020003711BE9FD6FD4E26E1DF6FD49E1B585A46 +:1030300031FFBADA4807A6EDAA7724E1FD47DA5F47 +:10304000DE6E8847EE30623E5080AC7293E2FEE75F +:103050000A151B8CC81F0B763B597E58C0FB26E413 +:10306000EB2BF438B13E673AE4152D68C9CEC7B0F2 +:10307000DB6E23FA79CA79A942A7FE79D11589F0C6 +:103080007DC4A52DAF233D29BD34F5F5AD9FE2FDEF +:10309000014AAF5331E8756A207A5932B4F482B8E4 +:1030A000F2AD50B92609E5B46A5D6864A38A1FF5DC +:1030B000717A9261C5FB8E4A3E71D950460F2279D2 +:1030C0005281AEE75A0B915E7A3A95FDAB06E94123 +:1030D000DEB1E1F776E7E590F937D2E7F379DC7214 +:1030E0005EF3F5E83F676730BFFEB5B5906B49C842 +:1030F000EB6B2DC44B9DE737D63AB0FCA7B56E2CD1 +:10310000BFBD564678646D2EC2532696CFA3C81312 +:103110006500CCAB1B9DC1E4687486B2AFBACB0D21 +:1031200071E9B27FBD5108F93D2981E499D3AE45DB +:10313000BF5B93A75139479B87D16DE4795E9B04B0 +:103140000F7C476541C5359AF624777CA40CF6833D +:10315000E78D2C6871E2F7DB6E9B91A4697F4B4B86 +:10316000BAA67C5D868CF39B5D96A3797E7BD51891 +:103170004DB99AFF6E02B1C41BD4E753D4336279C0 +:10318000DE0ED6F67CE3C4B4D574FCF3078D58AFDD +:10319000A7C7295300F7E381A7CD1EB043A7E11EBF +:1031A000192D9FFE9388FAEEB491041C54759F1656 +:1031B000C87A804462F274E13093A7B27F8904F642 +:1031C000E1E4C7663CBFABD9229000DCA1EAA59838 +:1031D000A7E3DEF52333AE7BE11691F8F0BE92DC77 +:1031E0000EE7D677ED18ED8173CB7939A14CB8B7DE +:1031F000D7FBF338CFD3B4B6A69BBD7F9AEEAF9D75 +:1032000090972414E0F9C1C7E56DB506C837100FD3 +:10321000A6809C7EFCBC88F194252BFF54E400BD65 +:10322000F64AFB5BC5749C536D228E7BE619F33620 +:1032300011E5DD9B06DF758DAC3B8871867DEE8ADE +:10324000BA0CCAC71FD606F350EFAC61F1EDFEF819 +:10325000A1EB057A03BFAAF458C46EB17332AA7CFD +:1032600086807EA8317AF0DCF454AB11CFF3A8FE4F +:10327000C7F3FF536D4906A67F9E47BE5B20C92654 +:10328000F5B80B5A452FFB5D08D904F3250F8B3E8B +:103290003211CA2C5F21D022F8D8798D96BE77AE34 +:1032A0009C88F78BF5F9530AFC84CA944F750EB4C9 +:1032B000F445763E4B26744BEAFC7125BE42DCACED +:1032C0007FE53B3EF5C31FFFD6640ACF7AD92707B7 +:1032D0002F6CB7A17EFCC8F052D16A0ACF9407DEEA +:1032E00097285D1A45DFA380CF6586D6AD029E8BF9 +:1032F000BCF72D388FFFF039A307C590E76B2DFD84 +:10330000F1926103E507C10CD8F972285570C357D3 +:103310007909E66FCC25ED3C3E1064E75830098A08 +:103320001F473D3BC77AAFD0B619EEE1D6E8EEEDC8 +:10333000BEC7EF2DFC3043D0D8E7BFF0728D81C9F6 +:1033400027D9C3BEBF08792F2354F654D1A7BFC8CD +:10335000188EE3F6D955D28E7AA5967F1FB8FE193E +:1033600033BBA7231307C8E312461E7216E4998ED7 +:10337000B3D4F4DC77809D17932EB4731F1A83B5F2 +:103380005DD9F0FEB6F52E7CDFE80982FC723B6069 +:10339000A18A03F4C762C2E6B7BC4D088654710A1D +:1033A000E5F73808D80595BEE96F0FB4766011B718 +:1033B000778B882EDFA74D6B972A126CB8AEA56D60 +:1033C0003CEFB96F5E22F982E2ACD6177C6526CE5F +:1033D0005BF004A3CC6331E90DC17780973FCBEE5E +:1033E00003E9E7A55FC760E759EB993D15BE27DC08 +:1033F00037AE6EDE0ABE095C5052D141C17B6D8092 +:10340000E1B3B643407AFD85FB55CA3D3B85EE8B63 +:1034100049C54CD06B8B1FA5FBC2EC081FF4D9EB40 +:103420009D41F497CE9036BB95F27FFD969DB74CAB +:1034300082F79E7ADD04FC5DE50A8D3438E1276968 +:10344000EEF956596614FBAEB3E7FF29FC101E6770 +:10345000C2F7283E166D1731AF41D58E9FEF07108A +:103460004F7501827944756F8A9E66FAB40E7ECEDE +:10347000A7E0F2E7ABE0E77F7ADE7A3F263B7360B6 +:103480003F46AF5FFAF9313AFB09F726C05EF6A670 +:10349000B03CF0F39237D1857A59A777530AF0BB45 +:1034A000A38ADEADE5764F196711D83B5A7E7FCBF4 +:1034B0000B76883FFCE5D11752318F02ECCBD888D0 +:1034C0007DB9BB868D77F72FE3306FE9E3F2AE3C31 +:1034D000F0FBAABEF73BBBFABBA6756EDF75993051 +:1034E0005F6E0F978BDBB21C600FFDD1F32AFAEDF4 +:1034F000BF62ADD3768975DAB4EB5C00EB54DD07BF +:10350000A9E1EB3CD9C2D6F75E2B5BEFC27EEB0C98 +:10351000E039C8DDDF377B02E86784D08E9FDE2983 +:1035200012B87FD6E767E8ECFE05D2B615F0B17C9D +:10353000D5DBC724CA174B4651FC503EA87AD88C1D +:10354000767EC9CFD9F9E78742491A1EC0EF0BD959 +:10355000BF419F2FA5FE01F8179179F4D9FDC599B8 +:10356000852ABB3F48FCADE071A8151DBFC3DF8BAA +:1035700012BC2C1F7285F21D98DDBAEFC0C8A003E3 +:10358000D83D790BD02983C86C9FA88DA7FE6DE428 +:10359000A777AC42FEEF1DA5FE5E6F437CC808F91D +:1035A000BEBD3B05F48B96DF55622F2190DFCAE24A +:1035B00060EB3399FD12BC5ECC7B3153BAC6D3F1BC +:1035C000EECF94D973D9C1F2BA9F22F8DD1965BE46 +:1035D000FAE7101FB780FDB31AD0FEE9D7FF8B4C76 +:1035E000E62F2F170DE84FD79B985FDDC3BFFBF089 +:1035F00028AF7F3493F9D7DFE5F1811EF023E17C1A +:10360000FA5A33FE5E0F2153314E2E11C67F92823D +:103610003787F4499F7CA3BFDC9B0178BA83741978 +:10362000819E338B67CB706FE058AA05BFA344FF20 +:103630002AA09FB9BC9F4346764FE0188C41D735EE +:1036400097C7938FC16740E9F8C78698D08F0DBCA4 +:1036500068463FE1FE7816EF23C98912F0F9ED5C68 +:103660004FCD9B6CF6C2F9C0DCC9F75700A4FD052D +:1036700008C55795A577433E1DA7C9C0EC7C938B21 +:10368000E07D49B2BEBB10F07715758B214F9EAE21 +:103690007ED7174903F191F69E423DC415AE268CA4 +:1036A000C18A11BF9A72BD89D51FCC3C36F3D10CAB +:1036B000BABF866C26B0338023E08BEA44DCE7CEC9 +:1036C000823C7E174009F9ED4689040C0CB658F18E +:1036D0003B442CAF5F3907B9B9988412E9FA420725 +:1036E000B4F7286E0D1942A3E17C470A7502FE0C5F +:1036F00016D9E8A0E35494090580F7FA75839BEF87 +:10370000F1CC0F70BEF5F0BD2B98E73704CCE799EC +:103710004B851EF8F40E89EC130B18FD800F1B5C13 +:103720007200DBAD647CAEDCDF50E8924FBB57E348 +:10373000772E9F1FEDA7C50EEF9BA2C74DCE70F948 +:1037400050FCB4655C6E97297CF7AC565E6D5932BF +:10375000FB9E1AF883146F73398CC5F7F159ACFFCF +:10376000F82C165FFBDB658EB7DC4C42B8EE17CD4C +:10377000484765DC591C5AB258FEB2320F857F6B40 +:103780004923E6DFD4F2788C816A12CCD36DFB3EFC +:10379000E6F7EBF384A8838479674BB7EB9FABE242 +:1037A00039A2462F619C5330F52E84F9095F89F3C5 +:1037B00000BFCF35B5633C40DFCED826A09C1B5B55 +:1037C000A83F25F0F32D5A36B70AF8FB0E73337A6B +:1037D000C7E1F7CAB95F5DCBE94AB5F774B80754DA +:1037E0000BFE149E7FF1EF446D617EA4C4FDDF05E6 +:1037F000AD5A3F63EE7A959FC980E65EBD59971F2B +:103800006EE4FEC67153EF38D0F7FA7BF6C70D6C45 +:10381000FE815482F991CA3D7B89FB930A3F0DC911 +:10382000326ACEC594FB9C55A0A7D8F70E74F95404 +:1038300056FCEE4A95C0BF57C9E38A67A9BF89DF26 +:1038400095391A87764B8933F694D8028644F89CCA +:10385000252BCF4BBC7B26F89955769304F0A2A17B +:103860001BC7592D76D9B2B32371DC8D25E3B74040 +:10387000DED0ACADA3675932F19483DF471AFB1A4F +:10388000E4ADCFF99CCE1FCBE36679E9FEA8E7E56E +:10389000DE3B2C54452FCACA9B25517BDEF358EFE3 +:1038A0005628AFCE9A384BA276B0E7C1DE2CF88608 +:1038B000F0EAADD7B0FA26A5BF6B66417E70CF1394 +:1038C000AC3C87D607C0CFE5F780AAAE1650CFAE86 +:1038D000E6F647891F55195E62700AFB9D8F4BB54E +:1038E0000B6455AC063F47B49DC2DF13D82C7BB1A7 +:1038F0007C5F866F7E16ECA3660B0113DC8B7F3337 +:10390000388ADBAFA8BF7BB13A93C9E5BA61AC3F57 +:10391000055FB49FBAACC2CBEFC701FD146AFA5978 +:10392000F965E673B4FF7CEEF932F3F1CADAF928EF +:10393000FE99F29DB957B2BDDF81F92DFB26DB0F51 +:10394000935356CDFDFF738DBF1C0576FFDCB3E6A8 +:1039500024E0C3653FFD55562DF87FDC1F3AD3792F +:10396000C40479DF2BC2ECBB380D61F69D9C15BBFE +:103970003A4DD3C7421E6BA7A95435BFFAC8EF5CB6 +:103980004937AAFC9827B30C3CDEC67ED771D94FC5 +:103990003FC0EF092E33B4BF0F79BEE46A1647D398 +:1039A000AFB399BF770CCEFDA3C40BB66531BFE3AF +:1039B000628E3708EB5C9745B02CC6F86ED787BC93 +:1039C000BFAA78A6C76B8A6C1699E2BBF04D5F332D +:1039D000E49DD63E955D20D2790433A6FC386BC0B9 +:1039E000F8662F8B6F76B0F86695ABEB2E6AA4C89D +:1039F0005FB6CE7DC8722D21373C4EFAEEFB41DC1E +:103A0000B0CCACC8CFAA595327B3781994F767D56F +:103A10003F04F2B39FFF3EDBBC89E3E241CEBBB380 +:103A2000130C0E2AFF3BD3ABFF027C316FE2B5D300 +:103A3000E17989D936AA9AC5C7913F76A65784A05D +:103A40001EDA43DCC3670AA5DC4AD7E1FBBD8879EF +:103A5000D3BEBC045FB47B2A7BB8BDFA4B163B0FC8 +:103A6000DA6FA0F32C88CC43199F72FC5D5D10B710 +:103A70005A37241FFC687B46C9A9ACC2C8F8F60CAB +:103A8000DFEBEAF1E972F3E0F960E77188D3E31460 +:103A9000A75BC56411BE94D0A7D76F9C9AA029CF0D +:103AA000999144BCEAB8E99C744DB9B22A47D3FE57 +:103AB000F6856334F5E5E6AE098D97E1EF37D89EDC +:103AC000C1FCDEA31D17DE9A0B7EEC76D123D0F568 +:103AD0002C7971C75B907F7D167E82A480C5C5D886 +:103AE000F71AF9798CE49534E731075E3081DFAE5F +:103AF0008AF3EBEEE51DC438BEFE3C46C917FFB2A3 +:103B0000E731D230FDEF797EF40A5D1929DDDD89D8 +:103B1000F4693EC0F2989BA9DF02DF13FBEA2E7323 +:103B200010BEE1FEF1AF4E9864D5B94C43B8097FA1 +:103B300057B774F7093CB7D991C5F4F68A8E4F4D43 +:103B4000704FEAAB1D2B519EA753FD9548F9A6ABCC +:103B5000938CDB05F1E46C1BE6E12C6BB91EE3D41E +:103B600089E1B908EBDBAEC7FE96876FC2F20AFEA9 +:103B70007BBEFBE3BBA6831DDEFF0B27EE075F13B7 +:103B800043A39E847ECC36D40FE5E9F3D6819FB063 +:103B90003F3E30F64E3A5EF9CFBE8A79E82B760981 +:103BA00018372D17C97E01F2EFC371D85FB9F8C776 +:103BB000092BE9F31B4A995D2D071F87D68B45B664 +:103BC000CDF83DE918BF93E619C6F48AB19BCD7BC9 +:103BD0005A7836F6A7D4170D1BAEF99E9F3165BBF8 +:103BE000B4C01A598FB15B40F8B5F018840DBB66AC +:103BF0004B907FFEFBDCEF27039E687BFC3E587FEB +:103C00007D3C319144D15B0A34733D3C17F4309CC8 +:103C1000DB677B670C4B81DF23EC962CA047AD164E +:103C200007F82F338BF3E55AD5BAC4976EC37B10D0 +:103C3000E6E45E23D8EFB914AAF5F6FC1876E6C6DA +:103C400061CA3D9B26F6FBBB8A7E7FF7EBEC3BA867 +:103C50003C3EA0C8D375C30C9AEFE974094C2E0200 +:103C60003F67E702D3B37D0B61BE5D25A4F279D433 +:103C7000A35D59701FFD3F357F4A5F0BD0DF2E7566 +:103C80001388632C19A6D81D26CF979AFFAD7CBD4B +:103C9000AF89C40F7CF1DA75D77579E9BC3AEF1DAD +:103CA0003F1EEC8232DE3DC3589E2971F47E8EF9B0 +:103CB000867B126488EB97C399C784883F0FF98885 +:103CC000103F6CD8637E1A3E90DA60A7FB7B2BE432 +:103CD00005C685806F3B7F1B2781FD1833C277CFD8 +:103CE000B042783E7A2A7CC7C7DB619608FA41DE8B +:103CF0007B015FB1E67B29FDA5C8A39ECF7C2D4C3F +:103D0000FE7C5C0EAB39DF2EE072582D7912E13C5F +:103D100066FE4111EF452E58238CDB05F101D98653 +:103D2000F7F4153954E4CD087C391EF893F1657D1C +:103D3000D8C9E53B9BF7CBE4A05C64F976E5639CCE +:103D4000B87F5E114EC2768ABC2A72BA3EDBF76338 +:103D500058777933956F3A8E6FDD9009202F113E99 +:103D60003139809F289FB86B557CD0DCF999047C51 +:103D7000629C2C209F98292C55F151459F7FE298F9 +:103D80009E4AE731737D367E4F59A9FF591FBF0CFC +:103D90008EDF9FE2ED17584323C1AF3536C679E079 +:103DA0003BF2679365D463AB3609F8E384AB8C15BB +:103DB000A5E05FAC7A42C0F81EF81DA07F8A0E37DE +:103DC0009AD4E720B785F3F0BCFAA6F00884C10CBA +:103DD000DF8BC017D5E15B381EF3A29EF79D6FBC49 +:103DE0001FE36AE783660FFBCE98367E57E8F5E05F +:103DF000F99FF1A0916C9321EEE613F17C2F93389B +:103E0000BE2DB0F81DC4F394F89B724EA7C4E1CC4C +:103E1000F03D5C951DBD20B565C13EA45F3CAE8400 +:103E2000D9FD8FB61BD9BDADCE3F161968FD87D918 +:103E30005E8CCBED73FBDE86F52CBD31F853232D64 +:103E40002F7BF0053BC4CB157CB64BA191B05F6ACC +:103E5000A77884F8607BAB581664FE4EC26C557E22 +:103E6000452CBE5E1ACE41FC28F646D1DFBF5CEB86 +:103E7000C64DA9A2C72F658714FE5ECEE56039C87E +:103E80000151DB9BD915F0BB662457C07BAE117B7B +:103E9000C3E441D1D394DF516ECA733231AEAEE880 +:103EA0006DBD3DDA2BB67FFB6A3847937D7132C515 +:103EB000CF949FFCE385776855FDF33F9A0A742AF7 +:103EC00019231038C7BC949EFC7FD95BF3F900809E +:103ED000000000001F8B080000000000000BB55B15 +:103EE0000B7854D5B5DE67CE9C9949322FF28020ED +:103EF000249C993C0825E0F08884879F0702018470 +:103F0000E0046F1135CA2422CF840494CF28F4CE64 +:103F100009090894DAA0D6528B7642C1528B6D788B +:103F200058D38A303CA441AD1DAF7DD02A7450CA0D +:103F30004B9088F582B754EE5A6B9F939933495052 +:103F4000DBAFE3E7B7B3CE5E7BEFB5D7FAD7DA6B7B +:103F5000ED73100F7E2EC94318B3AE2C678A9DB146 +:103F60007BA12D81F63AFE6E634C624C69059AB1D5 +:103F7000A879A623F6DC299B18CBC0E70D8C153158 +:103F80003643E77B7F3963B73076BF9BF15F3D30C7 +:103F9000F565ECDA0013F14DB1B239FE42786E8E60 +:103FA00064C7CF57EA9920CBC09A270B34EF8C9582 +:103FB00051B32D1DF8EC36F7360FD0C5C3E4798523 +:103FC000317EF12BCA5D26329B900AF29AA32CB562 +:103FD00010E7D7E556F93A5F22779AC6FF3B91D5AD +:103FE000B7C2F8DFDD765B4401B90EAC18314294FC +:103FF00063EB15CB16DA5F591A8C1DC958C76BD6FF +:10400000D016909BC17C02F05F7A6D50683D6CEDDC +:1040100004EBB8C68056F7A6C8B8AFDA7D29C45FEE +:104020009BEC0A09D05FEBECC8F7833C25FB93C2FD +:104030006C28ACB33FC9CC60DD2B390F14CB45F8ED +:104040007CE044C10942EFB59A19F0A9D9CA68D4F5 +:104050005B4FF2EBF225B6FAFE4BCB05D5E5626C71 +:104060005A89433541BBE86A0E6323185BBC762A44 +:10407000B5AF043341C98C4DBA5A0ECA60ACE6EAFA +:104080009DF47CC9D514A2A77D3B528AFB61AF0881 +:104090006C1BC85FD6EFBE550CE46B4F6643F6C091 +:1040A000BEDABD59BE46E8AE6E9E4AFC65BF983C7E +:1040B00005F7B5640F30E3B8022194877A3A653783 +:1040C000B1DE8C3D64E3E27F5AF7A791328CFF7436 +:1040D000A4631803D64362EB536304B2673BDA73FD +:1040E000C2CFFEB1FB2FC0275D159902F258AF0A6F +:1040F000D446E4C022D407F031067CD5BBFA8E0C3E +:10410000D8BF0A9E7E25C98047A9FA1309F16485A4 +:10411000B624AE7F8E8693443DD6CA1CD75FD50F9A +:10412000EEFB8A785A8578CAF88FE26915EAA91BEE +:104130003C3522CEFE553CDDC08E3EE689E16CDA90 +:104140009B1C1F2CC7E1DBC6082F2477BB252BD473 +:10415000087CF7A25D115FD7591DEA730EDA372D7F +:1041600086D7973C819FC4DBB93D592D5C5AF855E1 +:10417000EC7C37C3B8716F7A1D53E0F91C68E3E338 +:104180008615ED57D8757F3BBEA69D9FD5F8BFCC51 +:10419000CEAF6976666EB0E348B29F8C764DB43B85 +:1041A000DA15ED5EBBCFBAE546761D9C1B68EF2E97 +:1041B0004E3077B209E58CD9C57A27E2E6D3B099BB +:1041C000A17FF564576913D7BB4EAF0E9BA784E858 +:1041D0003C6069E543082F47FF9DF85356D2FA77B4 +:1041E0005B2FC6CEC8757E33F0CF2A86AE9BB07FDC +:1041F00069B362C6F8027F8EA1191566237D6AF441 +:10420000B2C844D8EFB4A73AFB55EC9F34CEA58D85 +:10421000670A6CAB93FFB45C1BD9407237733B06E3 +:10422000A266FF90387A24D08E38BA3881DECCF975 +:10423000F11C71D33C211EEF617E6138D2FA7C9A69 +:104240001FB08ED25E60BF197B04F77AB0F73DE3F2 +:104250002E59D03E6525D123FD60BFFF273FEAB729 +:1042600027C1738C83206FB2A7A159356BE3C17F3F +:10427000AA35355A5B0545043B55170B21AFA7AB53 +:104280001E933DC6F30C7F66E3786619F9F5C6A365 +:104290001D69BC97C687AD5F63FDBBC63125D44D94 +:1042A0009CCCD4F9AE01ADCF0FBABB13F617EAC65A +:1042B000DF640FF79F88C954C3405F059EEF35DB6D +:1042C0006E05FB328E8F6F789EF6AB855C5C256148 +:1042D000BF3792D7E9D1FD38B65FD9383E7C237D10 +:1042E000A577D197868F0546BCB8CCFEC39F821CAC +:1042F000AE74C1AD82FD97F893363017DA5FC7F719 +:104300008FFC4A7FD85F12EBC4AB11DF21FF44D092 +:10431000E312A6F76F69C673C96FEAE4E778DF2B8B +:10432000748E2F00FCB8181F3FD1D3D2ACDAC91E4F +:10433000D44F74EE0DF0DE9A408F4BF00F0DDFE49A +:104340009F18B7413F79DDC48D4A4DBF1705361B15 +:10435000E35E6402CFF7225EDE3678787EB750D314 +:10436000E352AD8D24C7E9A17FCCCEF00BB302C3DD +:10437000BE494F77A76BFB56C3FEE9B0AF482A1B77 +:1043800022004E56B4EC6D6ECA8A8DFF564BD88F04 +:104390007AE89C4FDD17C1B87FB7A6A78696FD11B6 +:1043A00095C73301FDAE86000138D823A822ECB3AF +:1043B0000671D0CD3EA775F51B3561BC22DD607C52 +:1043C00079571C2A09E39994FE75C66B769A9E600C +:1043D000C72909769C984057E874C810CFF438571D +:1043E000D5B671756F9063F176018F098CD7166120 +:1043F0001863CF78DEF0DB47235E65A91FC4FC6736 +:104400003D6F456C80E5728C6784DFDF362B6097EB +:104410003BD1DF897EDBAFB8103F75AB33813FE422 +:10442000F95DB30D58EF69DA28614EB3D5F34EB399 +:1044300019EC77F7C85F1CC1F9CCC2BB91E9C20D7A +:10444000F0DA9CB08FCD09B49AC0FFF497C4F7A6F8 +:1044500084F12B13FA3724D09B12E8B5C6F195737B +:1044600005F2934AB01F2AEECBFCE6D79ECE7CA184 +:10447000F33C13EC942719703FAD91D3873D27FD92 +:104480006B0BE3E8960FF47848389618FFDD9BCE67 +:10449000543C3FA41EE2D9AE9EE25941E279C7FBEB +:1044A000FF8A7FF6C5BC9319CEE543A2913E20EA70 +:1044B000FED61179D88E0F75FA921FF3F169DF37A6 +:1044C000EE0BEA42ADFFA27F22F8FFB4EFEAFD1740 +:1044D000FD4ADC3E75FED27F5E1771BDBFB45CF055 +:1044E0006F85F92A2684F3EAB04DE52D9C33229E90 +:1044F00063B536EE4FA5AF897E3C672A92C379CB70 +:104500000AE3F6C95AF3719F075688641FB591D71D +:104510002355CC6761500A1D70B9EA5F00FE432B3A +:10452000C47A3CD74ED4A7F546F9077B79BD77C846 +:1045300035A0F783401F4899639181EFC0E393A8AA +:104540003D282A6B3A00C7573DD7FCF641D8EF22E9 +:10455000FDFCBDE58ABF01E2F4158F4CE303A9EE33 +:10456000DE6D98AFAE97D83619E5F13D4FB8F98EAC +:1045700075D87A90A3B261706FCCDFAABE575EDAAD +:1045800017F8AA564B3E81F8D850943BB07E92055E +:10459000FBE73669AD3A99DAFD5FEC7E7328F07778 +:1045A000AC137D5B8079DF55AFB30AE4FA3089C77D +:1045B000E10F2EE43A51CEEF7A03A217EC5AE974D8 +:1045C000240B7878B865E74C9877438E62F616C569 +:1045D000F8F77F21CEC17CF3D50B55BD03403BBD21 +:1045E0001CAFFBAE56F5AE8A3BEFE75D34939EF70A +:1045F0005BE48731BFDC9F9C25A8E4C7AD69E5E09B +:104600002F73B5FC1AF052BFBB9B73FF1F1E917036 +:1046100076CA5ACF3E04101FF876C63894531F57F7 +:10462000F4FB40A303F1DC5F1E1E9F47BBB227DCF7 +:1046300084FB88E12CF51D3C2F298F063ACFEBDA5D +:10464000A802AED821C8FF518E74A514FBD94A60C8 +:104650008038C6325BF3E3EF236279EA2A2D1E70BD +:10466000BEE3AA83EAD6E33B924258CF1C57DF73DE +:10467000307B3C3FF793F94E878A87F11987C38CCB +:104680007A3D610E9E7E14C6CD7B4EA2383AEFB9BC +:104690008C951D180FC09E79ACEBBAFFED9568DDC7 +:1046A0001EFD84C9E513C7C5F9893AA01CF7D39349 +:1046B0009FDCE61D50BEB5B0673F99AFE5EDA5CFD5 +:1046C000497EC4F9FC228799DD0C75F673AF6F4300 +:1046D0003CCE5F9A34DC0A82CF7FCE4AF68D3A1CFC +:1046E000AA1BFA034E87B917B4FFA5E121DA90445B +:1046F000758AD8DB42714F5C5324A37E4A4466B668 +:10470000C1B9223A7DB29FD34D6EA8DB563B8A6574 +:10471000B4EF0AAF4C7AEBEC77CDBE5D80BAE632EF +:10472000EC230DC69DAB7FEA995120DF79169A35AF +:104730000AF47E190D0DEB5CDE238654AC8BCD8A1A +:10474000B90CE2DE02C6FDBDE6E86ECB78F8734137 +:10475000DDFCE9581F2D0C491F44B5DAE73AFCFF90 +:10476000197BCB82F9EDE2EDC6E7E03116F4AB9AA6 +:1047700056E3F35AB6E1137128B6E60FA205DA73D1 +:1047800058B7FEFD3F0F391CC757ED75A49F1E0C8F +:104790007F0C67C341B3B04EA1EB2E845DBD48F2E0 +:1047A0008AAB9242A847319B9F0F9399104A42408F +:1047B000B861DFB0EE95E0B121870110E2632348D4 +:1047C0002FA78280A781A00FA78DF8C5C7C4901519 +:1047D000D62D49634A2FD4E733E58C39489FAA1B6D +:1047E000E8C9E975668C4FE7B4F85229307F2BF998 +:1047F000BD2F1BEBE379CF2591FDE63FBFF08F3F47 +:104800001889F62A4B8FF7A3C735DCC17CCC961AE2 +:104810009BE74CC3B7B2519E921F415D89F5A61824 +:1048200078E66E8A97293E8A5BEEE87746214E1A33 +:104830005286AD678893BED9DEC2D8F8F9AB56E48C +:10484000F3F150AF3A315E25D17EAAF7580927958A +:10485000EB4485CEC72C0B9D8F1F3425115DDDBF2A +:1048600098FCACD2C402B80FC8053329AE7395B317 +:104870006A3B5376DB31CE6F88884EB28FAAD9CD92 +:1048800082F6D9E24DA3F5E7A08EE1DC3AE8D5F453 +:1048900062E2F861FB84D0368A4F7532FA7F85492F +:1048A000A03897E88FBB3109C371D9BEFB715CCDCD +:1048B0001356DF2A0F9741D4E5013CD59822F37EA9 +:1048C00088F3FED24AF71AB5B08F2427D517CA2E1F +:1048D00090BFD6CCCC16BC9792793CD3E5A995CBAA +:1048E00027234EA1FF9819FA6B1C3C1ED7F4E2F760 +:1048F0003DCC610B6D8B5F0F65CEE1E36427FAD988 +:1049000068C20BFABD09FA2F31DE5FE22C96A3F0E4 +:10491000BCDDC4D6E23D09CA336868DCBA40F71D85 +:104920008A785C6AF63AD00E69B366E37A2F891406 +:1049300097C0999E28C6FCEF257104D6B195EB0E61 +:10494000956E427AE730378A50F9F377E97C5AACB2 +:10495000E12C8A793F9E5740EF84F63D2FCF2F02FE +:1049600022BFC779CFCBF37F5DAF7A7FCD3A89EC99 +:1049700051B39AE3A1A6E14F346F8D23D21BED51C1 +:10498000F3B2740BE2FA941627AA1AB2C61D037C7E +:1049900054492EB7008FAAD5320BD2D5CD02D1FA09 +:1049A0007A35EBFED0DB54C8E7C3D6AAE128366FD0 +:1049B00046369E671FED48CBAE8CB3FB474DAF38F4 +:1049C000653BFA4D38CF8DF7304B937C5BC84FB9C0 +:1049D0003D3E6ACADB82F73473DD118700FD731F29 +:1049E000CE49C573EE843B6CC1FE13AD1E13D28A53 +:1049F000DB3D0E69C57C33D11F41086FD5EA56C433 +:104A0000F11281E3A67AC7218B17D64BCAE138BBD6 +:104A1000F8D2BBF9785F50931DC9C7F3177095DFC3 +:104A20000FEDF2A24079C2921DA292343486AB25DA +:104A3000882BF0FF451AAE96EC79E511F4D3258862 +:104A4000A7E15D710975E5617ABEABA594F1F187C7 +:104A50001177FA790F749384F76A168D8675904EE4 +:104A6000CEE1B881FE89BC5F2DA47384452D980FDB +:104A7000D78A3C4F007FCAC43CA2B64D523BE325C7 +:104A8000AE8BFD85B1FE9E703338879F27550D563E +:104A90003A8F066B7A89AE7BD989B8B8F8D2A12350 +:104AA00063B0BEDA25B831DE77F1434D6FB5A82784 +:104AB00027ED93F2A25AD48B33A6A74E7FD3705121 +:104AC000CBB81E74BDD49A353DE9FDDAF8C21C8E10 +:104AD000C36AA6E975CF40EEEF9A7FEBE788BEBFC9 +:104AE000402A1FAFE3EBBE1C8EFB31DA3EAB013731 +:104AF000BE42C29762B945ABFBA1EBE2CE16BA3714 +:104B0000D2EDA9CBBD5C5B1FE2B4D22B3566E7A822 +:104B1000892DE8EE9EDAAFE94FB2F3B872B2A1DFA9 +:104B2000FDF5A0BF453B441F290F6BAEB875ADA680 +:104B3000A883F2D2C74437EEABE467E5B7E3BE75AE +:104B4000DC49DB0573DB48AC337A91FE75F94AFA30 +:104B5000F86FEFC57117467974394F0A61B297BA89 +:104B60005370F33C376AC1FB43DD4F13E5BD2F475C +:104B7000D0F201618C7033CAE393D1BF199C8324B6 +:104B80008FFDD80A5A4F3DBEC23334B6CE09D56127 +:104B900046BE138CC7011D9727B5FB8893AB5FA159 +:104BA0003C585FE7A1AEEB04EAD3BBAEA3F32FD62C +:104BB000F875BF684FE5F82F69FA13F1E971167FB0 +:104BC000780FA7EB53D75B9C5F1AF4A3FB97EE4FCC +:104BD000BA5DFF55BF622B33285F7D5CDB37F94838 +:104BE000EFD8B980F8C4F3CE6A015CDA0DE726E5A8 +:104BF0003593FB7F620974F35CD753E2F3583DE5CC +:104C0000CE46FD4FB6679A300F604D998773E3F239 +:104C1000B20FF1BE0BE36906E3EF33187865DC7978 +:104C2000AEE76BFA790DBF0D9DB884F1B5E9CA39CD +:104C3000EC5F3072693EE6119772BCB4EE79D66AC9 +:104C4000190FF3559F8D943AE558BD72EBDFC3A25F +:104C50000BEF03F7780CF542F585C3E4DF352CB292 +:104C600006EBDBCA75EF968D42BBFF14F271E09B39 +:104C7000DBECA173EFDCD6074660295BB93A8FE81D +:104C800085DB1EE4F43A9ECF55AE2E7A01EFE33F6A +:104C90004C524A11DF1D1B0537D65B63B715ADBCFF +:104CA00007FAC73A06F442B98F6FFDB06C0CD60D07 +:104CB000F522F98BB2F5A959D8AFB4893EDCEA5C8C +:104CC000E65E790FE2DBEC227F3BA19D138D12C7DC +:104CD000D91B5A9C38A8C58D831A0E4B1A1BF34D4D +:104CE000B86E0B9C4FB0FF0A8BDC1AC6BAEFB53E0C +:104CF000BE2DA82F285333014767059E7F2FB03064 +:104D00001BE2EAA814598EF21F5DEE18D6800288C5 +:104D1000D76E41BF50B43A0BEA265A57D797BEFE1A +:104D2000512D8EE8F3E8E3DA319FC2F34393F75C49 +:104D3000D34F67619E706E7B5E2A8BD3FB39DC1785 +:104D4000E87B21C4C55DDDD47F7FCCD1EF23427CDD +:104D50001DEDDEF0A8D4DC1FDFDF421E7F2A3E2FD0 +:104D60003FD39264433C421E6F7C2EF1F304F278F1 +:104D7000C373F09B53C67C5FABEFC40A57A09B384C +:104D8000A4B78979FEB91C7BFAE914D625CFD7FDE3 +:104D90002E71BC9ED777DEB3BC6F4F781F33CAC568 +:104DA0006EB0FE852018066ABF16F45D907762CA61 +:104DB0003F7747B09E6CB6BAADA0DF53E857F81EF8 +:104DC000F06591E78936E60B032E4EFD61840FFDF9 +:104DD00070DEFBDCEFE6B50A217CC57E78E3E322DA +:104DE000F23FB859607D84B83AEBE98DB3D0ED2E2F +:104DF000FB026BFA02FFE5ED824F2509157B427D30 +:104E000075A4AFDC737DF5EFD655FA3D53A2DE33C2 +:104E100073B5FACAC77C46BDF3FA7C3FC0A7787861 +:104E200057BD5F0806A88EFA38B880DAD1AD2D25B7 +:104E3000FD40FE4BC2C927C6A2FF385C744F7221E9 +:104E400058472F013F6E1B716D06E8E755BBCB8DB0 +:104E500071E3E3603D3DEFC48B86CF5BF71C10FB35 +:104E600031E2DF3B16F8F7D95DF85AA39BF76DDC0A +:104E7000BE9041F1F7A35ABDFDD0D2517DF0B9BE2D +:104E8000DFF38F723BEBF29FDFFE8013F3D3033F20 +:104E90004CDB3B1AED9BE272238CE66F12596004E7 +:104EA00063A737F13874D6E67A613AE8EDECE63B71 +:104EB0007B633DF8A0D461F1C1BCBED7CA9D787FA9 +:104EC000F63773D4E9C616F8C32887392462FC1B69 +:104ED0003385D17BC0316133933DF48A9E7032FAC1 +:104EE00082391406FA237C3F88E7F6B564FE9E5E9D +:104EF0007BEFF7E0AFF87D5AE7FD89768F3056DB20 +:104F0000EFC3B9A95C4FDAF39262FEFCCCE6DD3365 +:104F100070BE735B2537CAFBF15689E65F0475BC2A +:104F200009707816F086F16BD1EF451F42FADC76F6 +:104F30005E272F02DCE27D71CD5249B1B8BAE2B1F1 +:104F400044E7DB2B507DADE37291122A25BD6BF84F +:104F5000B4C17FD7E1C8E8C55AD7A03E1271FAAFF5 +:104F6000D6FD8B1197DDC583041CE8FAD2F110C37E +:104F700027235CEA764F6D1D36BE1F0D50295EA8B3 +:104F8000135801E6058D165660461C98927DE8E799 +:104F9000F536E750BC67BA92C4DB474CEED7B15E3A +:104FA000BE62922501DA13B91EB2C323A26F12D2D8 +:104FB000527A94EE07C4129362C2F3AED14AF12240 +:104FC00031DE3C9ECBE3703F041BB43FCE75532BC8 +:104FD000B13ACA1FF416369885F949794AEA673218 +:104FE000B03CBD75CA4C33ECAF7C6CEAF21CC82CEB +:104FF000376F9D3113DFEB968F487DD90BF4F3B9F2 +:10500000659CBE39B54802BAA1E18E991381FFD5DE +:105010005CE5C9DCA2D83AFABCF0FC7BB940BFDE43 +:1050200027B009DB5A8B7D2DC6FB4B42C712931864 +:10503000E37F4760275E1562745462D9984FFF186A +:10504000DF7915F5DC9EC9555A72BB795EC5D86A01 +:10505000D46395FA9B6398AFC1CF6F03BCDDA1E128 +:10506000ADCA660F232ED85AE942272EBC18975C8A +:1050700066F4EF199AB9EF30870FE0F841ACC97DBB +:10508000DA46A9E0E6EB693DC779704C765A9F0F86 +:10509000F6774982FD825D05056C0D2E2580922BE9 +:1050A00020BE097B7FF339CEDBA8B26812D9A1C23A +:1050B0008D71516001D375686B52000FA0A7652FE9 +:1050C0005F3C8CF05FA8E75399FCFB8CE51A1EEF60 +:1050D0008828DF6F01A1CE04597A2ED8FA223BF836 +:1050E000B119D63D670AFC06F55D6D7A2B7B998C6C +:1050F0007EDBE8C4FCE5E2CF45DF741857ADE5ED93 +:10510000EC9A18BE0D9EB77B066D591F87A3482EDB +:10511000CF172E78C2D92B307E7878DDC9AE1DCA64 +:105120005E01FC53BC538BF05C7A9A29FF931BF70A +:105130007E7186B9FBEF2FDEBC89E73B6C2B3F5FAE +:10514000AD66A63A52A9654ED0C75490A518680915 +:105150006891DEC787687DE473629E223F90C9DF55 +:10516000D7303FFAA36E47DD3E5DEC0622637E6ECC +:10517000B23109FD6510DBEC46FFD6ED3749B4537B +:10518000BC59F632BF8F5B26449BD2907E09CE4B32 +:10519000D497E6975DCFCD6D1634C582CD0F507C88 +:1051A000D2E3920CFF217EFE53F792D7F57373186A +:1051B0001B86B8FAB27C478F4B601F4B5EC6D7B0D8 +:1051C0000FAA08F63B5F5B7B9258219B512F193643 +:1051D0001FC6E565CFE5D079C79A9E64F17C6C73F4 +:1051E0001AE1738D47243B96B5F563323C5AD826B5 +:1051F0003019CEB9E96D69443BAFF625BAEC277D8D +:105200002660FEDFF9DEF22703893EF7C29B230307 +:10521000FC7EC586F3FB992E47612BE64397ED2074 +:1052200007D8C16F5F4BF7857ED659C708D705A44D +:105230000125E84F8AA472BBD81AC8AFB57D2D737B +:10524000733B2E3BCACFDD65E3F9FB3DB33AC8851E +:105250007890DA451602FA9B47C5A230B0366A71DB +:10526000D99A6962729C3D92E46426C7D56F4C5509 +:10527000225827CDD6709252906AE87F5C08482861 +:10528000D76CFB3CC28DC3779361BE4876693BE91E +:1052900023C0F35B1D4F4CBC6046393F1B27B03425 +:1052A000C0C53767437FDCBCD2B84F260AD41AF397 +:1052B00062D0CBA91BE1696A9E86A7416C10E129E7 +:1052C000413FE01F947F5E86731CD326C82EBE3FED +:1052D0000EE859ED120BC9946F92FF5C5652E8FE2E +:1052E0007EB5A6271D77FE81CCA1C0BCAE62A3DE31 +:1052F0007A2946BDA54D31EA29C36FD44B9FD95EAB +:10530000437FDFC0370CFDFD160C37D05975630C99 +:10531000FC03EA2718688F7ABB813F67ED4C039D39 +:10532000D77C8F817FE0A62A43FFA0D02243FFE0F5 +:10533000EDCB0CF490D6C70CFC37B7AD32F40F0BA5 +:10534000AF37F48F687FD24017459E35F08F3AB65D +:10535000C5D03F3AFAA2A17FECD95D06FAD68E5F9E +:105360001BF86FBB7AD0408F676F1AF84B6CEF1A3F +:10537000E849EEF70CFC93333F34F44F953F32F499 +:105380004F2BF8D44097F9FE61E07FF6A6C0268C3B +:105390003FB34D1B8EAB0CE3B3FCDD7180E7BBD29A +:1053A000CDBE30327DCDBA2D94A7E5691A6E3F632C +:1053B000F6FB4DDE2F8F83AB312FC8405C4F6778F3 +:1053C000DF7BB955205CF7743EBB20DF35C7EDA30A +:1053D000976283023C46A74D711BE80C7FA681BFF4 +:1053E000CF6CD9D0DF375060E8EFB7C067A0B3EA21 +:1053F0008A0DFC03EA1503ED51A718F873D6FA0DD0 +:10540000745EF36C03FFC04D0143FFA0D00243FF65 +:10541000E0ED75067A486BBD81FFE636D5D03F2CAE +:10542000BCD6D03FA2BDD94017453619F8471D0B51 +:1054300019FA4747B71BFAC79E6D35D0B776B4192E +:10544000F86FBB1A36D0E3D951037F89ED1D033DB8 +:10545000C9FD6703FFE4CC9386FEA9F239437FF5CB +:1054600047003FCC9F5F15E8FDD7B4824F0CFD523B +:105470003AE4E9783FCD927DA2D0354FD7F3B732E9 +:10548000DFE786751E31D5D17771574C3CAFB3E459 +:105490007B097790BFDB6C1467E1841A42572D0DAE +:1054A000989FBA54817087A94605DD17A6D37B055E +:1054B0003A1A65FC0E0DF21B20524D1E0FD60F2915 +:1054C000B13CB4FFF5115F3D0F4DCF67FCBE293FE6 +:1054D00090949F81F5D8CE52AC4F1632750DCA010B +:1054E000E7AB0BDF33BD9D64BC37D2DBA936D05FA1 +:1054F000DC7A47939AFB0FBF81DF4EB55D20FECE6D +:1055000079B57B2501F6B72C6EFE27A06E324309D4 +:10551000D91C04FF023F7D32E826FAE96026D1CF8C +:1055200004656A37050BA87D36E8A3FECDC162A2EB +:105530009F0F2A44878253A8DD12F4D3F3ADC1D95B +:1055400044BF100C50BB3DB880DA178375D4BF231D +:10555000584FF4CF832AB5ADC1B5F47C57B099E864 +:105560003DC14D44FF3218A2B62DB89DDA5F075BEE +:10557000A97F6FB08DE87DC130D1E1603BD1078359 +:1055800011A20F078F117D2418A5B63D7896DA3742 +:10559000821DD4FF56F02AD117B4FBFEF1F9FC5E50 +:1055A0004ED78B4E333691F0A0E7B533B06E4170D5 +:1055B000144B1F1BEA9684FA21D11EE7B575A40986 +:1055C000706C639E7353FE96C6B87CBF4C5BEFF164 +:1055D00064A62641FC6BC0621EA0D890CA428DF41E +:1055E0007E95E7DDF3355CB2749E6FCFD3E49AAF5E +:1055F000F94311E2B380F0F9D6D7A993F43AF95BF5 +:10560000FD03F7113EB34C2ADD13D843F998F78711 +:10561000FA0702F920DFE5BA078FD07A6E5F3E2ED7 +:1056200052660D67DC85F73F4745BA2FED69BD5AD5 +:10563000EDDF2FF4D8BFEF5C7F3C87A67C21D27DC5 +:10564000FADB926336DE8F2CD3F4B22CDF6468076A +:1056500066F997A29C67F2EA5E7808582A96E6B93E +:10566000306FBD034B6BF0FB72264BF47D2C535E09 +:10567000C74F26BF09891DD2773195DA9DFD028F6C +:10568000E17EEE860202E9C0186B7677FB4994A7AB +:105690004993A74993436F2766F91B71BE53798AD3 +:1056A000419E47B364ED7BF78EE751AEFF7DED93EE +:1056B000D3424E4CDFFABDC49AF1DAF7534B05FDE5 +:1056C0003D35CF076D4CCF07A9BF6239BF9FB90FDA +:1056D000EA327C5FF9BE160F2FD749142F2B846452 +:1056E0001FE6D397EB960FC4FD24C6CD0A18678238 +:1056F00071158C7F0F51F17E0AE10BE663F8DEAD88 +:10570000023277ACFFAAB3F47B8FA83D83CBA3E032 +:105710007BD8397BAD2D58A7024EB6104E468BAACA +:1057200005EAE4B74DA17C41247C580490777E3A89 +:10573000E0A39BBC40C7C112EDDFC7E8CF015F3BD0 +:10574000507F1FFF6A5401BD37D9375A46FD359A3D +:10575000C01E785FF386C8BF93C02B76FC8EC355FE +:10576000D842DFF9631281F61AEDA0F721074456FB +:10577000BFB39BF8F9DB7C5E5FBD9D294D09D1BCB1 +:10578000C6F77C47343B1ED1EC5B76F068D62330FD +:10579000EF927689EA1D36325AE8EFE6FBA6DAFA8E +:1057A00037FBE6C6EDA3B6ED24FF2E8A450BE3BF1B +:1057B00087FA9BB6BE8E27D1E208B4D8E3E5E3F7BB +:1057C0004580EBB7345C9FC6BC7E865576DD0543CD +:1057D000A3A09A30B4811FB9E9BB3AFDFBBAB9CC9A +:1057E0004FED7C8003E2D8AF6EA4FA77116BA5E78A +:1057F0004B8A1FC846BA96754CCCC4FA656DC3EB8C +:105800009920DD9DCD1B27E1FDF3CC50E5EBD8962B +:105810006F154E63DD0D7E711CD78F0A75ABB124F9 +:10582000BD67C7F8D578CF3B43E476606F723B0025 +:105830008E1431B5EBFEC00F4EE178F003925FF7A6 +:10584000838A551C3FFABFC7E8F48BE2C57FED871A +:10585000EF3ECC1DF45D48ED3E6B2AE26B11569E87 +:10586000627C5EA89FCF3C2F580C7901F29D97B8BF +:10587000FDCF1F4FA27FF7725E007C0CEF8A7B3D4D +:10588000CFBC62E2F76E8F88B04511EBE5A7484FB9 +:105890000B6CA1A1A827389FBF401C2EFAB075CD74 +:1058A00030BCEF9B10CAC67C557AD1EA6BF418E283 +:1058B0003CBB9E12BBC77B42E2F76A89F276C95BAA +:1058C0008A8F7C8EF984D5C2547C9F04FECFFDFE66 +:1058D0000497FF8A2990798BC8F315AAA3FBFBA92B +:1058E000FE67BD6DBEF542D7F59BB475DBFFC9EB16 +:1058F00069358BD1F7388972086EBE6EA23CD664CA +:105900002E877EEE749587DB4197277FA087DF5334 +:10591000642BB4EF06532F8A5F97C440DE403C2FC0 +:10592000B5FB31BD8E6DF79CA1B8CEAE35F6E7DF85 +:10593000F7867B3A4F2F74D6CFDED879A7DF33B105 +:1059400071DDDF0BFA6D6E09ED3693F928EE0F620B +:10595000EFEBFAA17BA6FF0732EFAAC6A039000041 +:1059600000000000000000001F8B08000000000085 +:10597000000B7BC8CEC0F0A31E82C539106C6271CB +:105980002D0B03C37B56D2F5C17005507F3110E754 +:1059900001712610A700713C104701712810BF0249 +:1059A0009AFD14881F00F16D20BE06C41781F80C03 +:1059B000101F47B277291B03C31A36D2EDFF8DE4BF +:1059C000E70940761910CF20231C46F1F0C0723C45 +:1059D0000C0C5ABC08FE5E5E5479791E047B99203B +:1059E00065766D05EA070050DE58A18003000000CF +:1059F00000000000000000001F8B080000000000F5 +:105A0000000BD57D0D7C54C5B5F8DCBD773FB3BB2D +:105A1000D97C10120870F3014608B8240141B05E29 +:105A20003E8CD1A206B4482DD505F908494822DAA2 +:105A3000CAABBC66490209883628225AD4054141BE +:105A4000898D7CD8D406FECB4731F6A98D1615ADCD +:105A5000B641FB14154844119FB57FDF3967E666F0 +:105A6000F7DE6C08D6DAF75EF8F19BCCBD7367CE33 +:105A70009C39E7CCF99A898D6532CB10C6BEC69F9A +:105A8000CB18BB59668C8D8994A3EFBCAEACA90032 +:105A90007EFF9BCDBF558DB4D3CB214CA2768CA578 +:105AA000323696B1CB1CF02BB49BF2FC893F5D944F +:105AB000CCD87E26333B3C0A2B5392AE867EF67FB3 +:105AC000C5FCF8DEF2BC3BBDC38DDF05194B61ECB4 +:105AD0007B8C7F17CE50D37DB95861167CAE39E8E8 +:105AE00077E8276B63157C7FE60B377D6F86432F46 +:105AF000D957161616DF7C9D89FD2A9F75E4887A92 +:105B00000683C19980379DC6D5E13DF4CE0704EFE9 +:105B10000105E055638CEF00F89323F0EF67D7C5DC +:105B2000B35C0EBF363602FF378587E6DF8FB1FAEA +:105B30006AF5FBD956C6EEAE66DFCF1ECAD85DD574 +:105B40000EAAAFA8F651BDB63A95EAF50A7C0278DE +:105B5000A8DFC64241F8DE5B00EDF5FEE0BF3BD7B3 +:105B600061A8DB92E17B47A4AEB8530D7547BA6AD2 +:105B7000A80338475261DE23F823181F7060C7F16D +:105B80001D4CBB00DF0F25BC3805DE6A3DC36EC867 +:105B900004BC34BC22332419ABAACD42F886BA6DBA +:105BA0006A08E01BE15E308D79615C6F8031685777 +:105BB000FB2063F7C2F3E1EEC20FF1F913D07F03CC +:105BC000F42B7B1B8EDAE1FDAA0C9B2A235E762840 +:105BD000EF229E1CF00FF196B391D723F332D687B4 +:105BE00033A8EBF380EF7F9FB0FEA80470D466DB90 +:105BF00054BB1419A77B5DFAE87FD8BA73F73F54FA +:105C00002D9E8C74AAF73B8C056A7CEEFFBDFD8E41 +:105C100000DC26E545FAD5C7E9B35F58FE62F876A1 +:105C2000D846160A4B3DC719AAFA8B82B8DE1B1557 +:105C300016CAE0CF93811F860A7EA84F9FE10AB85B +:105C40007BC2C3A2C7C98CACCB50D536C7320ACAF7 +:105C5000EC996512D0075B17F55D262750E4975F36 +:105C600054FB881EEFAECEA1726BB54F433EB9FB1D +:105C7000EFF2ACE6DC9E7CF8579453F0DD3D5646DF +:105C80007418DCCE425B25ECAFEAE81CA8AF199D86 +:105C900092B75A25A02D28C774FA5E23A944DF4184 +:105CA000A06F947F66FEB8DB5A7C15D2FBAAD11692 +:105CB000A906F19CCDE97DA835ECC882E76BD665D5 +:105CC0008E0688D91AFFAB1D38EED0A1C388BE87D7 +:105CD0006773FAFFFD98F50E9483DDF35F9AA26572 +:105CE0002731168FEBE38EAC97EF3CE9C037310AD2 +:105CF0005F31E8401FE79FCD0FDF1D7D359E93BECE +:105D0000D6F8333FB4C3FBADC0E7B2D413AEC42161 +:105D1000E1D4E2DC9EF436341BE80CD7C97F6E3A3E +:105D200033976BAB43EC3D187C7D752AD1DDBA6AA5 +:105D300095CAD54887202751D6B0F150473AC4F5C7 +:105D40004A2FA07AAFFB155B4EFB51C2D410433EE5 +:105D5000598FF479093E5FA169B045F5CFD1EB2C9D +:105D60006C01D9BF0EDF0FA0BA865BD85D925E7F53 +:105D700026A8C1F7FD7278BD507A26589B0DFD39D3 +:105D8000F9F745D2292D981EFDFD5D9A3631D21EB8 +:105D9000EAE1C9D9D1FD41FFB9D1F01CA4F67A7F5F +:105DA000F3A4635A10EAEB9CBC7D8374F45FD2FFCA +:105DB0006AA93115379A5552375EA89FD57A3DD8D2 +:105DC000A869B9917132963FAD05A3DFB3A70DEF76 +:105DD000C72E6F0C06016F0FB0E22C09D637715633 +:105DE000552AA844CC393BA459D568F838BE23F3CA +:105DF0005B4FF0BAB2F9FB5CE98F5A6DD4FA4C9262 +:105E00005E0E22FCBA7E63E5A4057A4FFA6D2F027E +:105E1000BD5BFBDBFCA467A443250DC69B1A642A6B +:105E2000C06151830CE5815555DE8FE6039DFE0070 +:105E3000CE71046771D5AC5EE00C46C3A9C3D1171F +:105E4000DC3A1CBDD3291FDF4C4F936F1CF78789A9 +:105E500040E2CE76AB1FF53C54995822FCF2D57D3A +:105E60009A025DA6DC04B85769DD66B1AC9EFDF60A +:105E70009F358085A2E6F9CF5ED72CAC8F21BCDDA3 +:105E80002C8D89AC2FD4E744E3719C6867A63F7DD5 +:105E90007E0E9C9F1A3DBF5A4D2988CC8F298DA913 +:105EA000C59EBEE7B7CE593CABD8DDB3DDEF25AE1E +:105EB000474F9E31EE5AC6C72359928CE3E545C63B +:105EC0004B9EA98F178A395EBFE2EF169F667ED47C +:105ED000E17522BC19D1F0F2F5D7E15D6D05BE8DFB +:105EE000B1FEDF35BCE7CB7F2E90BF2A7C6FC901A6 +:105EF000FECBED9DFFFED9FD25E3AF404F9F2A2C41 +:105F00007C19E0F1F6E98E50508AC8B97F35BE524F +:105F1000F015ACDFED2FDD72EC320B5680AE47464C +:105F2000C6AF905482BB37FAEE6D3E8C850CFDFCFB +:105F30004FCDA737BC7ED772E87CE56BCDEB2E6EDC +:105F4000DF65B310F27F7DDBE5F10CBEAF7F714AF8 +:105F50007F84C3DE308269F98CDD8F9F805E512F94 +:105F6000F45D767DDE79E919ABAB995607FACB1E65 +:105F70006F15E945F512A3EFD780DE16023DA6E0C6 +:105F8000952D8E396ED4ABEEA5B2DECA488F297836 +:105F9000E5906F0A4CC135347134DA79F54EFDF96C +:105FA00091A22C787E57363C07D2A8F7F0FEE07914 +:105FB00031B68F1BCA9FF706571CA84D75517877CD +:105FC000DA428158F2F17B160BE1E75ED4BBECA814 +:105FD000F7AB543A5D8D01243AD7609BBA39A3E7F9 +:105FE00077B32C5CEF5F3BF4D9306E73AB84FE76F5 +:105FF000E0F2C7892F5DD98D9A05BFF773D7C0BD71 +:1060000026FDCA9DABD753A529B067BA4CF5BBF5A1 +:106010007D37A84E427DCD2BF49D4935974EAA8DF4 +:106020007ECF2E9A84FBAEFEFEA69A31F43ED1516D +:106030007574228C9F08F2B316594751A52AA4976C +:10604000EB1363D2CBDA2B1DB342F07EEDE5C33206 +:10605000E6C7B0736015699DF57A529191AEEF1560 +:10606000FAEADD427F4D451E8F926B4EDEB45BAE89 +:10607000392FE072CD95A32E47BA4C2A627ED4B355 +:10608000D702FE0251EBE4CC01F9166577242AC64B +:10609000797D57F37980693FB4F4EBBD7F337F3D61 +:1060A000C00273B07DA2D8A75C397E2990DBF7FCD3 +:1060B000CDF3ED6DDEDF17F884712A628DF3AFC288 +:1060C0004BA21BC629F8E78FE3C271A2FD45E78901 +:1060D00077D84784DF8DC9B80F98ED2A57814F6272 +:1060E00016AAB6A3FD9D84AF00EF1ED658340CF857 +:1060F0003AA978E5AD68AF79DEBEF243360AEA1D0B +:1061000073A66159979BD73619DAC5FB7DD30B89E6 +:106110004E19E1791576467CB768F924981FE1009D +:10612000F8EE51CB4D9382B99CBD71BD7F22E682C2 +:106130009AB7A2EFEB99B1E66163618E5FE96B7B81 +:10614000CFEF7B9BBF35F29DF0F72D213F695FDFDD +:10615000B16936F21B06E11FDAA309A67EE2355BC0 +:10616000C4AFC8104F517578FF42375FDFFA2F195F +:10617000CFC7EE75A8A807655B7C68A7C7335F0229 +:10618000EA7FAEA9A00880BCF02577052D6ADFEB79 +:106190005207A605ED674077D3A3F4DB3F5BB87EDB +:1061A0009C3C636AC60AE8F74C01F70327F9B8DF9D +:1061B000C13C9FBB603F0BDBA3EAB99B897F6B812E +:1061C0009E32812F82B916F267AFCADEE98BE66B89 +:1061D000264B026F66FA60AA027894057DC8D9162C +:1061E000CD39EADBD387FC0FD247DCB4A8EFD83730 +:1061F0005F2F8FFCCDE8E3DB8EA7AF6B4FBE5A2E2F +:10620000D6759E03F59B95A933E263C9D9DED7F510 +:106210005E5A57B067B5508CFE13BBD733D8B34C1A +:1062200011EB493FB719D64BEE3F76D6A673AD5B5F +:10623000B2111F7ABFCEA5B2FA57145E8A8FFCE462 +:106240000ED1DF2AF5DE20EA2967706F077CC88D42 +:10625000A3C3B89FB26CE6DFCA9B901EE254B5D0D0 +:106260006AAE2FD3BAE8F0D9D22D86F194649701A3 +:10627000DF6C1668D951F03B97DA080E078E07E3FA +:10628000C83EE85042FF3F0B3BBDD423F587437D1A +:106290009D85F53B0D74509F9E1773BF53C4BAA2E2 +:1062A000B9CAE9F5CEF3932FE6F1AE37C27BDEDF54 +:1062B000B915F5FD283F5DEFDF29EC7D1D5F80C43A +:1062C0001F77D33B5FA79556D622C5833C489DC90F +:1062D000022AD4F115EC630D588E473ACCF3915E47 +:1062E000B04D52104E626915FFF3FD6E382AB5406D +:1062F000B7164780F024BB3546EDD5F3DB0FCF5AF8 +:10630000B99E9C2C3143FB65B28DDE2BAC98A1BDB0 +:106310007CF69D2B52A95F0D1E8D8DC061EE77B866 +:106320001C58268F41B2E3F0E007E81F601D39E4F6 +:10633000CF4E13383B3B7F06D913BDC1F7A089BFB1 +:106340001E14F6012B2EE8635E9C8FCFC298EDD809 +:106350005E515D380E3B9E437CA08AF1370733E9DE +:10636000F9E68673F3F92F110ED04F1FAD7650F971 +:1063700058B58F4AFDFD63C2EED922713B447FFEC2 +:10638000B9CCED845699EF179B1D8D4EF2431F7CBF +:10639000F0CA61C05F038EC87E27E02F6B913F314A +:1063A00010435EE865F61A23BF3179F639E15DFAEC +:1063B000F6A4E987A2F8B149F624BF1F07BF5CCC59 +:1063C0002E46FAEBEBFBB3D5DAF44343BF3D5EB6A2 +:1063D000083BF4F3DA9797939E13BE8CF87380A072 +:1063E0009B01E55C1EA8752CA422FF7EF5358BA6CB +:1063F0000FD8A92DE84F1F58C2D843D07EF33C8B4D +:1064000086726BE05A5BC842FCAEAEC67ADA11996E +:10641000ADA6BAE69E13E58F4F93DF5E0E14CC86D1 +:106420000AFD4CF7ABEBFEFF4141637C62208BF22F +:10643000CB437F6942BF4B33F9F1BFED7AFCE57F77 +:10644000683D1E53FC2E5FD4F759122B8EB50F9E5C +:1064500011FB54D6DD5BB83D52E266EF45C52BB665 +:1064600048FE44DC0C1E5DB373BF0DE35125CC3FE9 +:1064700014F09D5EE5B344C3A72871D48F9569E1FC +:106480000BA0CB15736676EC45B9359119E4580C21 +:10649000F9A128F85D32971F8FAD99C1CBAF647217 +:1064A000EAA4055908E35B53E755EDB7A22828672E +:1064B000E4EF4D2B094A08CF802AE65755A22BA2BC +:1064C000AFB4D92CA4F178CD9154A08FC182BA0673 +:1064D000235DE0FEB3D418171A5865A48BB4126379 +:1064E0001CA83FD2057CD7DF442FE67E06A87E8A13 +:1064F000C765042D3C5E34CB18D749635D1F3E81D0 +:10650000F01D72FBC3384E9D715C73FF0A0B5CA0DB +:10651000801CD9F3F3896002C3AE1C9C9C8478D99B +:10652000EC288E27B982C1AB187E971EF4AAEB1D0A +:10653000BDB48FC8D1A0C1BF662E1B86A6DC36179E +:106540005AADF204188D1FCC20F96E15F1CA8319CB +:106550003F75A05FA33E398FF213F6631DFD38EA45 +:10656000B0FED172DF8A7EA4A4487D85885799C782 +:106570002B54385DBECFB442C4C3687B3015E9D913 +:10658000AEA6E4231CF654D0BB627C374E71717BFF +:10659000CFA77C698CABB97DEF8BE029F16172E20A +:1065A00079E1235F09FC10C70F4E067302E93F91A2 +:1065B000856A717DAB1AF93E17697713D231B40B36 +:1065C00062FCBFBB5D00DA8D34B4BB45F4A719DAB9 +:1065D00015F7685722FA638671B51EE32E16ED484B +:1065E000AFEB6EE7EFD1DF12312EE983DDEDD41E84 +:1065F000FDDDA1C36768E7EBD16E990E9F615C6614 +:106600001CB7FBFD705BA896F4CB62F2C71EE8577F +:1066100048F472A85F6111C6C16F7BC1CA65C436F8 +:106620009EE7210BBADA2FDAD5B9395DD556B371A9 +:10663000E5201F1B44BE4AAD7BAE2310F55C5F3FD7 +:1066400078EE8BFD7C8983EC31F15C6970925F138D +:106650009E933D56F777596C5A3F9B8C71CD0674CB +:1066600054613D78758D960DFC9EA618EAABD2F963 +:10667000FBAFEBAEAE09A2A34F29A6F808D0E7F70F +:1066800073A3F8B07BFC7F19FCDC7F1C81FF4735CE +:106690009A120D3FAFEBF0EB75E720FE5EB6CE9E93 +:1066A0008CF35921F6F5CF946535E44FFE5F3BBF7F +:1066B00045A6F55964581FBDAECFCF6A2DFD3F36B4 +:1066C000BF3B4CF3BBC334BF3B0CF3B35B974E0EE5 +:1066D000669FFFFCCCED565B8B49DEAEE8F7782A6F +:1066E000C2B542F8A79D56AD6639C61DFA75EBDBFB +:1066F00024DF4733ED6F2837FAFA6EA3A2927C7637 +:106700007A2C3C68D3CF161A9AC1E19A0172A1453E +:10671000F171F92DE03C62AA7799EAF0CB97B86F56 +:10672000FA986E4F9AE47C1FFB5A7D06DF4F1A3CA5 +:106730009A44792E625FB3E9FBDAA099B48FAD4831 +:10674000CD23FB65FFA005248F56A60FEBCFF3F0FA +:1067500052495ED9C55EF34035CF5BBB5FE407AD00 +:1067600048CFA376F7EBF19250BA61DF3CF0830596 +:106770004519201F4F1FE1F98AABADDC7EA8AF663B +:106780001ACFC37350B90FFA0D408356D0F7B07CBF +:106790000EF43D2C5BAA53A97CB65AA572278C8BAC +:1067A000E5AFAAFD5436558FA352D7171F14FAE24E +:1067B000F7D22DB47F3E56CDC62BD0FFA66A0795E3 +:1067C0008F56FBC62B40970F57A752795A9A31CE56 +:1067D0004AFED38EDA7858AF3DAF6653BED2C4744A +:1067E00085FC1E4C09CBF10591E73A5E4F4B932F88 +:1067F000B502DE2F512DBC9D2354EB8DDD6E32F69C +:106800003F4E55081EE60ECADEE498EDAEC0766334 +:106810009339DCCC17A8F5C4EE6F1A8E9B972CE049 +:106820004B566BDDB1FB9B8EED2E4A15F0A5761D08 +:10683000888BDD6E268E3B3255C097DE3E392EF6B4 +:10684000B83FC2FEFA2736521CE932B477A03F7B2C +:10685000BABA897C16A2DDE64155CC0274DB3FA9A9 +:10686000B10ADB5D5A55CC32A1CC4C296616A07F0B +:106870007B32BC077852453F13E6F1F79BF1BD2709 +:10688000EABDF87E7C09BC877A667FE37B7D3C7B32 +:1068900023D3E54998813CB0AF61DD793D584FB1D4 +:1068A000F0FA9DD60393296E69E3ED1FC13AF463B4 +:1068B000AF337E9FE2E2F57BF4F65EFEFDD3A27D70 +:1068C000FF443E6FE78D8E10C6C51EFDF79FA6CD17 +:1068D000CD8DCC77C8CF975E38376A7E8FFE7C35FA +:1068E000BDD7E733A47A0DBDEF8D5F53675B981674 +:1068F00025B7521A73499F1C6DAF22B9337AC8CCA1 +:10690000F01C58176B31876BDF8A553535D9045722 +:1069100090F205045C0FFFC408D7A09F1AE17AF833 +:10692000A746B806DD716EB8565BB95CEB0D3E1834 +:106930005F8B1E3FB4DC38BE5A631C3F54631C5F40 +:10694000ADFDD6E387A3D7E5917F338E3FF867C6C9 +:10695000F11FF99971FCC1777EBBF1FF59FAB8D7E5 +:106960001AF80FABD0C7E568BDB32A68D03BA15D6C +:10697000BB681794A3F5D840D0A0C742BBD7443B0F +:10698000CDD0AEB847BBB7443B661857EB31EE5F8E +:1069900074F82CD1FDF97BF4F757ABB0172CD1FD6F +:1069A000A93DFAFB5087CFD0CED7A3DD29D11F3325 +:1069B0008CCB8CE3C24F0EE6F3DCC15C7EF4F72E89 +:1069C0009DDA40F1AFFE2C20A1DFCF97C4461FC255 +:1069D0007D398BE7DD27142E1D82FB784382D1DFC2 +:1069E000D5CFC6F729C52653BFBE38564579878E01 +:1069F00060DAF4A87C8B32D1AEFBBD3B98765DD4D7 +:106A0000FB14F17D83885727AD1C538B72C537105B +:106A1000DAC7A0B7541BB70BF5F72CD9DFAE01BC12 +:106A20001B7E3C63CC6A163DAE95B71B22C64D8FCC +:106A30000D5743061FB714C7CDC5E7BA7E114C23C7 +:106A4000BCF978A93F5FEFF9A9F457C04BFD548713 +:106A5000458E87F76BB89F53F7B727D8AA1C98B70E +:106A60005B3BC8C236AB94877C4E3F4E5DB5D1EFE1 +:106A7000A9F88A35B4F70694F8F264D6FB770F15B7 +:106A8000598A62C51D0AC4BCEA4A263766C3F8ECB7 +:106A900090D17F0B84CDA2F36186CB81025B2CFF6A +:106AA0006D1DF79FEA7A50C28073FB6F6B857ED1B4 +:106AB0003D0FE828D6FACD12F0B10D1C6F8A8EB7C3 +:106AC000C41964DF25D45CE9F0C5F86E95A97F2769 +:106AD0009BA161BBB8E446662179C2CF4DE87A55E7 +:106AE0009D6F33DF87D280A6300E94BC338CFC734D +:106AF000A6809FA35052434189EC513E4F542BF145 +:106B0000274E0907D1DF386083C2C220B7D65A02A8 +:106B1000B36C185FC96E24FF98E2D324C4D3596BB9 +:106B2000E84A3A5700EAE266A927BCB7D8B83FF866 +:106B30002175C61F3262AC63894D35C4B7077C61CD +:106B400063E1FCDEDB47DA71B8BAE93415E8732497 +:106B5000C90DA2D34A592BB7119FA7FBC8EFA8CBE9 +:106B6000579DFF459C7BEE38267ED41BFE04F358D0 +:106B7000D46665C83FEC2B681D15FF5924FC5F7374 +:106B8000855F751E2BF6E2CB93CC52847C7592BD4B +:106B9000EACD8F5AAF069B8DC3D56025FF961ED7D1 +:106BA0009DDF6835F8BB166E30D617B019292897C7 +:106BB00016ACB3B210E07391C91FB614E70BF02FF7 +:106BC00064552B7DDCAE207D7AAE8F2949B0752CC3 +:106BD000FEF5C363E740FD17887718FF23A017353C +:106BE0008AAF4ADD211BE647BDB73B7FE60486DF5F +:106BF00087560E40799AC0629E2FBAA5C1085F5F82 +:106C0000F09BE165ACE69C7028DBA498FEAB877531 +:106C1000FE10EBB5D4E11DC540CE9C75F2B2DB9FF2 +:106C2000F26727C9F7BD4847B4DE5517F1FDA0EA62 +:106C3000622CFBFAEE80A03FF3778B1D1D36E48FAC +:106C40004AA5AA48B244E24D766B401B08DF595B67 +:106C50002685073243BB86F36CD726659E57BB2239 +:106C6000CB39FA3B25E4E5F33B1EB3A15D76F2C9CF +:106C700063D7201F96FD56660E68776A878785C999 +:106C80002E09D9509E94EE9663C667290300F056EC +:106C9000F62B0FC989D29DF6D034F8BEF4D9F74649 +:106CA00031C0C3A99AAEC303711F7D52E271D26095 +:106CB000C728DCB74A157673718CFE3A04DD9DF85F +:106CC0004D1CE5B548DBF6DF44FD36DF60B547C94E +:106CD0008737705FE2EDB87F6DBB141A1A437EE808 +:106CE00071AD13DB250E5F8B35E444F8B66DB2054C +:106CF000008ECA6D9F101D4DF9559317F150D92282 +:106D00001BFCBE95DBE4B07D1495C7B0C478890444 +:106D10007C5DC1B87CACD8BD98FCE115CD777D22F7 +:106D20007BF17B233D035EFC61C4EB1BB27F1AD673 +:106D3000773DE15501551FB56FF5225EA1DF39B6EC +:106D4000788CEB1AFDD8D8FF17893DFB03CBDD8685 +:106D5000F455D9BC8A8F67E2978FF097B49EF113F0 +:106D6000BBDD934C7AA21E3FD996745E7A6259D3EA +:106D700099478230DE899D1F3F1204B8CBFFFFA7E1 +:106D80008FDC897ACD3EA70FF9BDF2C9D7BC2C6A3A +:106D90001FCCB073BE3BB5FD89C71F023E39F5A6B7 +:106DA0009DF2F24EEDFD6030E6D39E7AE6BF52547E +:106DB000687FFBDECBC99EBF7DCF94FEE7DA0F91E3 +:106DC0004E43F668B842D4BFDA22A1B20586BC2889 +:106DD0004DEB7270B7CC9C00E7C9A3F610E63557AF +:106DE000C2B3A579B84E8B49FE627D19E0B7624700 +:106DF000FD27F2A858780E0EB4A46209EC928AEB33 +:106E00007CDDB597166069F5AB4817AC8BE4A7F944 +:106E1000BBCA23B09E17F5BE7E67D85736CC3FA9B4 +:106E2000DCB18A8F6B5ABF93F8CBF89EEB7799DD74 +:106E300018FF3AC3CA1F7D085FEE4E8A19D7D5E303 +:106E40005F8BF7FCE09C7A932E07FAC26F89C4E14E +:106E500072DBB56BEDC84F3B9F7AFCA164BEBED31D +:106E60000021A79ACE0C66401FC7AD5D37A17CEC10 +:106E7000DA6BF7E17E5EBAF70DE2AF537B5EB1A944 +:106E8000241F995B023DE114EBFE6947BDA142E27C +:106E900095CA2D9EB0DD1B59A78AD0F422D54BCFC1 +:106EA0008FD1F310A7FB8AD0FEEBA518EBB6D29ECC +:106EB000C9E571A81FE165F1963FD9288E1DB59EE1 +:106EC000D2385CC76385F8BCB775D4E7EFC3F95F08 +:106ED0001CB59E5B38BFF6C697A736D915CC4BD0EC +:106EE000D7F794C8BFAD0C496FB018FCAAEF6FDF9D +:106EF000341EBADC440FFA7CFBE2E7BEE7F1CDF0CA +:106F0000742B26578EE989AF135FC596EF1B857CDE +:106F1000A860554503B27AEE4F0A188C033322F06D +:106F20009EC05800D0D98927653A2FBBB2F920C935 +:106F300069B35CA8E8454F6EB2733BA7A265FF2812 +:106F4000945F270EFC86E8B062C7311BDA4787B72B +:106F5000EDB275E446E81EE57F741EE689A7F78F5B +:106F600022398DFDC7589FE744FF95ADC6FE2B77AC +:106F70007C62E8BF2CD86C23BF681FE37CA4683711 +:106F8000E07C3F6AB732CCBBFFA8592E8AA5DF3C14 +:106F90006AB71AF3613C638FA25F514EB4A928EF20 +:106FA000EA966B6F04715F7CC5CACF3D2ADA51CC7B +:106FB0000BA84DB0A968AFD6796632354A6E379ABC +:106FC000F0E94BF64DC2B89A6F6A7141B4FDA4C3A3 +:106FD0009FA0590CF0DFEE29EA8FE79FD00E53F106 +:106FE0009CB1E227BFB2EC2D2CC2F9C83E8BCF1961 +:106FF000737FE6FD59DDC56437597D96EE5C13EC71 +:1070000077F4949923D075A630D5A0E7AF9DCAE355 +:10701000B8FAFCD70E621B19C8DDB552571BE6B390 +:1070200007AFE4F9814CD8E95EB4D3337AEA734C04 +:10703000D354943F247E787BA6459D0FB903C0B1FD +:10704000601E8FC54FCAFC1DB246793D361C370BFA +:10705000EDA7103D8F6361AA5B1C5CFE7858153D5F +:107060008F671D8DD9D0F9DBF6E2B32837EF2D4AB3 +:107070009438DC61CADB4810E358E2D2D3CEC5FFB6 +:107080006CAA7222DAEF63671BC92E41B7E3D749B6 +:10709000113CE879717ABF6B9D1325DC6F707E031C +:1070A000F15C8F3837EFEB9EAF46F57E7ADD340E1C +:1070B000B6F48D155B2CB162405264BC2DA091FCDE +:1070C0001C03583395E9AC9DCA44874F5208BEB79C +:1070D000C92F6561EFB2AFE34CF09D873E7ED6A22B +:1070E000BD1980B2D62A9EBFE3096D85FABA04663F +:1070F000381F9CE9E0F264ACC3A2E72707A2EDAE1B +:107100005A564E737726F3632CFA773F7004863B0A +:10711000A2E219B2BB9DE77F09FB57B7D72F97971C +:10712000F1F87B2AB7AB7B5B9F15D5C506BBDA5C54 +:1071300036F673CCD9C4087EEEA7921CFCFCB2C60E +:10714000545F34FD61AECDD8E8BC464D23FB5EBC38 +:10715000B7C2F4F0A51DF128F7A4BF62A4BF7E4812 +:107160007F1DA2932EF25354CA81229C6F6A76959A +:10717000C49F0724EECFD2649C6F8AE8DF12579E2B +:1071800076AEBC2A360BE8232AAF659DB01F158565 +:1071900029AE3C8467A35877335D1AF354757DCDCF +:1071A0002D6A76912FF7BB8257E93C8A92ECA6FCB8 +:1071B000147741DDAD789E5C61553E949F6E3DFF36 +:1071C000C4CFF30A75BBD89963CCE7B49BF257AD33 +:1071D000C2FEEE91CF2DF6DD7BF0410C7DD8BCEFE9 +:1071E00056394C7AB4F89E8D8B9D37A8EB61E74BEE +:1071F000F7663BB2DCD17E9806F769946FA9087FE9 +:10720000C3A4EB7DE407EFDC21F1736B263AEADCE3 +:10721000193F0AE521F22FDE6F11279E4B3BF6EF57 +:1072200047BDA9CECBB484449273AA0C785F298D54 +:107230007648502EDEFDC9CBBF45FF7AABCC706BD4 +:10724000EE84B9B5E3FC142D01172B8EAD31ACEFF4 +:10725000379D4FCFB822E7B7253E9DDFDCF4FDE92F +:107260001D129D9F92D98807F01C44659B9585E06F +:10727000FD69C6FB3FBD91EB030B5F805160FD379D +:1072800088F1715F8ADE3F928A5C4C8DCEE3096A99 +:10729000ED78FE7F9EC047BFE244C3FB8FE716B583 +:1072A000917F26B080F44F3C5716DD5F99BCEC020D +:1072B0001C8F093F860AFF90FEF4F99FB5046C7C91 +:1072C0009F288E0F933E03F62FDA0D2189F295CC7D +:1072D000FE8E8A1689F6A745B03FE1BD028B422695 +:1072E000FBD19447A7E3DB4C97071D421F7433770C +:1072F0002F78F587797C94F86AC90B3C2F6C4993F9 +:1073000014A27CE68E0BE219E15926BFD107AC6AC4 +:107310003DEC1C11FA35E1CD9E6AC4B35335E23918 +:107320002EC788578FDF8847339EE3C7651ADA97E1 +:10733000C9E536223281E71CF88778063948F3A878 +:10734000807984D59EF82C695DBB12FD1B7DE2D14E +:1073500084BF8F4DF83BC35AF7F3B720525388B51B +:10736000797EA41226FE31F39B8EA7745FFB247AEC +:10737000E6F790BF38557422CDE3DF0D703473E625 +:10738000C9F313BFE979C271DDFBE57BEC6B286FB4 +:107390009B7EE818C6D3CDFCB5114BE0EBE66A87BF +:1073A0006F1E8CF77435F3CDB362BCDA47658C7D04 +:1073B00094FA077AA4FDE01E8C4B26235F2BA1CD07 +:1073C000DCE68A9B86E7FC5AAD3EF45BDE93D7751C +:1073D0000DEAED95F3799EE38F5D7C5FBDD5C5FD2C +:1073E000B08A8BE737AF2EB6300DEDFB563924A1AE +:1073F000BFC8A7BD7019EA5DAD5695F6355FD7CB0E +:107400003FA2F7F93E8CEFA6591A47231CD09EFCE9 +:10741000ED9DADEF796F89D2774EB5DC7721EE3BEC +:107420000F5A58492C3D3EDBC9C73F95F36E0A926F +:10743000E3624717D9D1F51D55C5382FDD8EB0ED64 +:10744000E6FEAD8A96E9A44F1E5AC0CF63EE39C15D +:10745000CF6316CAB3BF3F12EAE35F53B8DC64DA06 +:10746000B43929D484D6711DE64B221FFCD512AA4B +:1074700021FC34FE11E354B5FFA950BE6C4115BF89 +:107480001FE4B7DEC2362CC76ACDF9C8D7535B13E9 +:1074900026E17999CAB7795EE59876A33F87C9E571 +:1074A00007D10F76E628DF962F3EAA98ED2E19F722 +:1074B000E3F11DC6E713FAA0DBC94EB11F7959CA23 +:1074C00037C98BBDDBA25DE9E4712C3ACFE5576289 +:1074D000DB4F0FBBB87E057891504E7576317F0D2E +:1074E000E0A973DE009A6FE767FCDC65E75772512D +:1074F0002CFBE82627A797076D3C6EFBE002776818 +:1075000039FA4D17940E41BBE8F37F0B0C8915A790 +:1075100088D8072CDE427B9E16CFC6215FD4F1733C +:1075200066AC312DD6F9799D1F74FED0F9226D819C +:107530002B10CB7FF9AE93DB6F9317E44836A4D7BB +:107540007D12C5784ED5005CE7C06390D50C4478B9 +:107550002A5B3E25FF82A335B61FFAE7785803E978 +:10756000B626B87C02E0EBA7C0D441E4075B6346D3 +:10757000ACFE836C1DF99BE663923B7EE7E07634BC +:10758000531AD36678904FA65CB912E07C08F80FC6 +:1075900049FE41AB9FE00E2E668CFCAB0AE7FFF480 +:1075A0006BD8A6D551F6568373D23A5CEF754E1E52 +:1075B000EF480AF82584DBFFF7B35EECBFF30B3B23 +:1075C000ADDF00E1E7D1BFFB958E1F97760FD14B62 +:1075D000493209437FC0EB9B07FBFF452D80EF2815 +:1075E0007A8CAC5B90BE4B0C80EC2BC0F38C163AC3 +:1075F000BF82F616DA13954CFF0992F2A9F31F1E0B +:1076000036C3735ABABC955AA5B007E46681C31D48 +:10761000467F4A6209CC1BE351CCC1FB6B37EAA31E +:10762000287951EEA20CA07D5AD83BBA1CD6E5773A +:107630005D029783756B15CAA7DCA87438D17F9C4F +:10764000A1A99331B52A515129CF615009469C41D6 +:107650003E663D9CD0ADF74C60EC99BFCB31FD1B35 +:107660001F74E32BF02CE26B545BD701549FFC4E4C +:107670009684EB5D28F49BF127B93CD2F3FB2B8574 +:10768000BD619647BF013A478131FE52BEEF8D3F43 +:10769000E9F623FD74CBA10585B48FE6B5E61FC4DA +:1076A000FC9CBCB7393F32217FC07A23BC8C6D0B68 +:1076B000CA880FB3DCE94BDEE8F2C4BCCEA05C772D +:1076C000D731752EBF0DF82C6AFF36CBA9374C7217 +:1076D000EA0C9BD8FF7235424F794BFD07ED51F410 +:1076E000A3CBA9083D85886ECDE348CCD15DF76575 +:1076F000A17C7951463F48E7241E9F0C221FA1BF61 +:10770000E2B3D09538FF75AD573891EE77B64D712D +:10771000205B2D49E5E7BD94FDD70799209FE8B888 +:10772000AE953954770EE2C542F8907D508F9AD7C6 +:10773000E946499C7754E3AF8F713F825E2E49E55D +:10774000E7B976B665C6733B334CEBDE4DF7C20F37 +:10775000A1F3854EEF66FAD6F9A19671BF84AE3FCC +:10776000C852B3B00B8D7E815ADDCF1174529CF894 +:1077700076A10FD6BA87DD85D7DBD48527FB302EDF +:1077800071BB2793F2996FEFC7F166C6835E567E91 +:1077900001FA6154DE79A5D2457EADCA2F6C86E729 +:1077A0003A5E7BC3878ED74B10AFD23F8ED7B36282 +:1077B0007DCDF8FD47E79DBE645CCC7373FF57E653 +:1077C0003D81057EDB4176173FB7A1D3972E2FC6AB +:1077D000DEB6218D88A3DD78AE479723E35AAA0E43 +:1077E000A28A68961317B5B2EB104FE3C30A1DB116 +:1077F000ED4B6E7C86BFA4D1F98B592E8073F4F3C8 +:10780000B3CA76C0A3512A4B9A06408D6A57488E58 +:10781000B1F6F38B4335873F4B41FFA2AE979ADB1E +:10782000E97AA9BEBFE871A0D5AEC0421C5F6A016B +:10783000BE81F9D7FAB8BDDBE00C94E2F33880D909 +:1078400085B97639E10C6E9F1AF9B2373E8C33F167 +:107850005933E085CE21C03E3754EA09873E7E96F3 +:107860002B81C309D486FA4BFA58C607ABE0F7D987 +:10787000A58F6201DC87F1F826CEB3C1C5F7935519 +:10788000420FD3CB0667F17284DFAAB0A03DEF1F91 +:10789000875BF70BAE7669D52E18C751A4D13C068D +:1078A000FA981FF5FA814AB3E4073812CB55A9DBE1 +:1078B00059A3EFDF78EE679A3A89CE9765333A1786 +:1078C0003B10F5A018EBF34B17F7572F76741CC637 +:1078D0009079E5B4AA22EF39E2D391FB06FCC24FBE +:1078E00065CCC3E8DCFBC6208C4BBEF3EF9F7A303F +:1078F000EEF417A5CB83701E5FF6470F9E377867AF +:1079000019B7336E32E9333B053E7D71C5DB117F1C +:107910003757FF7DACE1FCF8521E47591492D1E86D +:10792000ECA6EFB26D71E49BD3EB8B9B930C759D32 +:107930004E17DB799E9479FEC785FDB468C726DBB8 +:107940004015C70FFC16C73F2EF4B5E3BB3DE4CF8F +:10795000D0E199BB63B40DF1F09756BB88C3B75B18 +:1079600039FEB569183F0B88A530C379785F1CF5DF +:1079700037FF7E99F48B3930D652A0EF40EB22B21C +:10798000B3CDF398FF8E5AD81FD66FFE2A89F452D2 +:107990006CBF0CE821B0B49EE26CE679CE099AE3A4 +:1079A00099CBC84E37E779CC63EA5D133362E47B49 +:1079B000B4F238F9C23EEC9A775C425F18CB2EC61F +:1079C0007CF4332CF717B96ADF76CDF16A46495A51 +:1079D0001F553BA83C51EDA372BB4BE5F1EC96FD66 +:1079E0008789BE94F6B1C8EF3BDBDE8BBB518DC8F7 +:1079F000EDEF6DFAF4E02FA19ECFB8FF46F78FCFE1 +:107A000016F8BE4CC8EF85421FC8FFE2DCF27B3699 +:107A1000CE77544F7875B93D1BEF938DC2832EC737 +:107A2000CDF838DD9615477EC638731CF8DBE1A526 +:107A3000B7EF16CBB1F30675FED92EE879DE96E9DD +:107A40002B07C0F8B57B3F18CCEF036647503EE8E4 +:107A5000F469A63FC6AA6CC8CFDD74D67A37E14771 +:107A6000A70BE0A354117F4C45BBCF4C6F7DE513B2 +:107A70009DB2760C463960A6AF53128B79AF68621F +:107A80001CF797CF53B542B443617B59C9E3745C8B +:107A9000FE1C571A0FDF89FCB985F3C7E25F373D3B +:107AA0008B72A7F457F77B51EE7CA834A6E078E5FB +:107AB0005B577831CE7D5C097AF1FB0F4372CCBC09 +:107AC000C2057192906BC67C05D610BC06F9F6F320 +:107AD000AD561FFA192AB7D9791C7C37C71BD47940 +:107AE000FC7B77EC7C85D227EE4F51797EAA316FF3 +:107AF000618B95F24FD05F86C3F416C7ED8E0B37BE +:107B00009F3BBE5DB9FBAE9879277A7E80996E6700 +:107B10009AE815F042764C10E021B7B8885BD76E32 +:107B20007F60D43180EBC496FFF04AB9D17E731EDA +:107B30001F3FDD7CCBA318E2E98D5E4F09FA8EE88A +:107B40000DA198790CE5D6B017EDF0F24D56B2EBD9 +:107B5000CA9B64E6C07C9637EDB46F9735FDEEF5B1 +:107B60004B00BEB267ACC9D3F834285F415FA7EEC3 +:107B70003C12B12EA5BB7EC7E3BDAAC82711EB53AB +:107B8000F6CC7E1BE6C598F138A579BFADC3948FBE +:107B900040EBD47CAC90CEE56D3F6BC3FDF4C37D70 +:107BA00012EB9FD1F3FB924DBFF3A27C403C515CA2 +:107BB0005EAC57EFF942E16B9E2BA076E487EB6D4C +:107BC000FD2EC6351A43F4FDF473307EC95B76CAC8 +:107BD000572A79FA36CAEFF940A9E274FEF08A14FE +:107BE000DC5F4BACC1141F95FC79C9233F21FA5BC4 +:107BF000F8CA4F52F8791E2D8DFB6D8269E4CFD8FB +:107C0000F8039ADF021620FA2B79582E467FC919FD +:107C100085153D13834FFE2CF8E483CD760CA2B27C +:107C20000F84DF32F8AA2CEEFD35C793F8BD2B6721 +:107C3000841DBD2BCEA2E7693BA2EDAACA2DF5EDAE +:107C4000B83E1F0DD2FAFB28AEAF0405BE24D2C742 +:107C50005FB9BCBF9063745F8CAEE74CC1E7D8BE20 +:107C6000DD4AF7C6447D67B8F7E576313EC0ED9250 +:107C70002E823225B63FD3ED9674F878FE8B4E5F98 +:107C8000BDF1FD169E4FF2D9112E57302F86DEB76B +:107C90005BC3FD0DF93076C3BD22917C0FABE06B69 +:107CA000E37B8093F255BAF1BB4FA238EB82757635 +:107CB000631E5C37DD98EFBB31E6AF2C34E95B7AAD +:107CC00069960B6FC699E2681BCF2F7FA5DC1AA2BD +:107CD000BCA3F237ED643F9437598B111F1FEF3867 +:107CE000F8FA8D40E71F37EB7C6B94AF66BE2DD959 +:107CF0003986C5E2DB8FDD7E16936FE1794CBE7568 +:107D000047E2112AFBEEE4EBC25EE4ABC5DD431FA4 +:107D100088C7BCDC8F9E2C1B427E06135E75B96A39 +:107D200096971BE3D45EF2EAF87E1EC977E4F8D397 +:107D3000E9B1F4A9C5344E37DDEA74A9D36D2F79C2 +:107D40005A663C9ADFB7097964F6670427B31CBC0E +:107D50005FAFD6C672D0FF1CB4B8FC5B3362E4756B +:107D6000B0AA0B50CFA87167C4CCCFF5BB7D68C655 +:107D7000326BB22AC78A77FBA75862EAF1F96E71B3 +:107D80003F09D202EA936E8EB73A115F014B90F22F +:107D9000FEE98C36C297E0257EB2C27346E72AFD23 +:107DA000746EDB1F67F9540515ECDA35430A15F4D8 +:107DB000A7E65B6ECB82FA823579850AACB37F8207 +:107DC000655726D44BD6E4F3FA45967C2B90E6E330 +:107DD000C182C2A9D0BE429FE7BC78837F43B11C59 +:107DE0005B8F7117E5392BAB85FA5DC0D78EBC4828 +:107DF000BC37CECE824EA8C7D9A084FACA8C3FAE7B +:107E00004423F03E7BE06A37C9A3C92AE2F584CF58 +:107E100041F932B7FFE672CACF2C7373BFF1885DA8 +:107E200013E8FEDDEF60FC1FBBC7F43E7E9D95F7B7 +:107E30007362E7882988D71143F8555F3AFEF31437 +:107E4000959E3B9BF1E829F17F2A9EFFA84DB051FA +:107E50003F65DDEB757E65ADC86B90E3381DC8F1FD +:107E600096AA67A05C22D6FF36810FFC417BB973CE +:107E70006FFFCDFCDEA7AEC1B8BEB27CFACFA8378B +:107E800076FD38CE8FE757DE72717CDD10BFC63AC3 +:107E90001CEA798EC1B72151BF25EDF80996D77834 +:107EA00002FFCEF1CFC2D8DF8D37C9BC3F7795072F +:107EB000EF519334AE474B4034B3010FB51A536DB5 +:107EC00059C8A2C67C0B59CEEB0AD3B81EC3B82C36 +:107ED0001DF64158A71BC6F375029CD2BEF8C638E2 +:107EE0005E9F15CAACED50098EBB118ED1F6D02025 +:107EF000B47F6E04B588D3B5D1FED6E3F495FF699F +:107F0000213BB352526BDD50DFF53623B97CCAE515 +:107F100015F907FC7E19DD2F31FEA5B95370C90A8A +:107F20005ACA781E87F043E971F433AC55C6C9F4D8 +:107F3000F0539BE4E104B686E4645FF1B1C7DD620F +:107F40009F19C0067CC3F85893FB3CE263E96E5D61 +:107F50009F17F176B1FF9F7E3193F285140573F27E +:107F600018B3A932A588E8DFED36C95F9D8E471E9C +:107F7000F1DD8278197984DDCCEDA55EF2238E33B4 +:107F8000CA6B1EDD9143F91156737EC4510B253C1B +:107F90008D7D215F457CD689B8F1378DDBEB71FF94 +:107FA0007CFEA8471CFF396F11C541F37DB1E3F892 +:107FB00097C8B329EEC05EE4EBA7C7F1999C2B23C9 +:107FC0009C67C28C25219C478CF7C55C9C1C94291E +:107FD000ADE66DE3F34BCCE7594CEBFD57F37A9FDD +:107FE0006F1EC487FC7EB5D16C14E54158451EC494 +:107FF000B32C705F741E848EC7BEF24CCC7925E61C +:108000003C92B480114F034B861BDE0FAACA33D4B7 +:10801000872CBDC4D03E0336C2E87A56C35586F6D7 +:10802000431B6718EA176CB8D1D0FEC2D05CC3FB03 +:1080300011DB4ACFB9EE239B9718DECB96503EDE7C +:108040000BA9AFFB452D3F8B4917FABAEB795A982C +:108050006E84F81D03EBFE5006F98FA6486ACFF533 +:10806000F78783B42F7FD3F5CFF6087DE81BF2BBEB +:108070001F898DF25AB99ED8697537A05E9C00B0F1 +:10808000A1BC35EB1709ADCFFF17FEDD899EF916B0 +:10809000EA72A4A33B646D3CEEF7FD447E649D450B +:1080A0009C279DEC207DE01E8BE5E6E87B922FF57A +:1080B000707BE0520FDF5F7E09FB26EE9303E358EF +:1080C00090F64F0B8BDC6701F3F52631716FF1A64B +:1080D0009553D3319ED991A326007F637D5044EE02 +:1080E000DF68576B311E305AE6721CE4FB959E7EAA +:1080F000B8EF2CB372FD2768453C0F74B0A0378FE2 +:10810000F63D8A6B26B06469492E9A5EDDFB8BFAD8 +:108110003510C3C1D211F16807BD8C906090D6E1D3 +:10812000A2FDFF87BADC2BB990E4DE69B79E37A6C3 +:10813000D279C7D3F3B2E8F99B3701D701FFBC6905 +:1081400033DA457DF9A74A36DDE741FFFF9B39CC9D +:1081500090675026F056861762E2B993D07FA6202A +:108160005A3AE7FF6D18025D29B5AF44115DBFE1D2 +:10817000D662CADBDD3D3D88FE3FDDEFACF753D96B +:108180003A8975DF230CFDDDF006F77FDDF037A3BC +:108190003FF7671E7EEEE86762BC9950F8006F33C8 +:1081A000613D12B07C7E6221F2033C0F4B50BFB6A2 +:1081B0000D543FA0FBE9810C2BC2F347E67F6D0F06 +:1081C000C0B3C2A3D238D7B3622BC2F5FA4D8B3DF0 +:1081D000D8AEBB3FBD9F8178A613F6E984A03505D4 +:1081E000E8A7EB5289F67518CF81CF8B670F5C81BA +:1081F0005B873EDEEB2C70F23558EF19CC4FFDEA71 +:10820000FD33E632C8C19D25657F49CA44F967211F +:10821000FFC792BD76927F9DA5679BD6C3FB9B0748 +:10822000760C42FDE2ADD2BF0D43BCFC7083CC5452 +:1082300058FF475D81B59E28BCBD39EF530FBE077F +:108240003D61EB7ADCE49FB2D339AFB74A9F1A168F +:10825000AD57FFD233693DD21D1B777EF19E294F6A +:108260005E48F6B64E5F8B047D2DD97E01E9834BC7 +:108270003CDDF4C5EB5BB3E83CD15889C5B423F1D0 +:10828000DE0FCC4BDF097485E708F77DC1F3C777B4 +:10829000BD98984FE751596047F4BC76BD7CE30820 +:1082A000F2B71E4D3E2F78912783A85F310EE74B22 +:1082B000823F66B526E50BFDAE05FBBFF1B7DB4F90 +:1082C000FE09F1B3F7A9AD77629B82F3C30713FBF5 +:1082D000985FE001F631B27F3A99CB6F8F61FF3C36 +:1082E00023F4AF3B2C1AD925672DC5227F9DDB21B6 +:1082F000B2C59F8A79DCCDAD721CE2CD8B068B2E88 +:108300005F4027F4E23D8CE2FE7C07D8672384FCC3 +:10831000F9C3DD9F16D671FF8E41AF2B38546AD05A +:10832000E78AE11FCAFB8B37066AF14EEE5EF5BAAB +:10833000B085ECE17F54BF7BF71F94F7273D9CFF8E +:108340009B73B8FC6E0EBB42DC6E60F9A8EF35790A +:10835000F97E7025E68900FE6DD2A91C07FCFEC9D6 +:10836000DD6756364C84E5CEE6F8C03AFDFD95361D +:108370004EA7DDFADFA1E1FCEFCB8973C005E25C1B +:10838000B4199E02E02BBEC9BA0CFA63F8F09774D8 +:10839000CEA52951FDC304D4E7414F41BE772A1D24 +:1083A000B68418F37B16E527D0F7382FDF3F1C2D56 +:1083B0003C0EE75035BAF7CCE9F38D467B496FFFA9 +:1083C000B187EBAD8B0FBF35D806EB74D2F2A21795 +:1083D000E308E57B767AD14C1E1517F07A51AEBED4 +:1083E000F9EA581FE55B6D1A8C766D7398C72746BE +:1083F0002A2CA8C4B8B7B972433E5DFE5DB121898D +:10840000CA0BD19F008F2AC37C9EA75A6A63DEDB0A +:1084100059F9FFF60EC0757BAA1F3F2F35B2357F85 +:1084200021CA3F84C50A72EEC92F46507F43BDDC86 +:108430009E87F1157CCE58C882F71D3D25ECB553BB +:108440005FC8D44EEF7764CB24D9076B991B6E3C81 +:1084500040F661AB5DC575766EE1F7C1395B9D2471 +:10846000F72AF75DC1EDB8041EF76C7275FD599CD3 +:108470006353314FD2E96B6489D07F938DEF8F17AF +:108480000203EC74479EEBE3395B1FA0A4764736EA +:10849000BF57CFA934B24BDDD178F710FC8582BE2F +:1084A0009A5C610BE6ED74E15D950457044E46E37A +:1084B000EA705E48FA7C93ADEB7D3C7F49E7EB5474 +:1084C0008483C3C95A2F5051AF70FA78FCD6E95350 +:1084D000FD41A9275C95A340CF057EBBA78645FE3D +:1084E0003E06E6B1B9227507F044532613F761E55D +:1084F000D4A37ED15D4781342EF2FD8FBC23EAEBFD +:1085000026929D1394D1AE87D29388F3E4FC85F72D +:1085100017F4CBE378403F719C83BFEF6E0FF4EE0E +:108520004EA47B8DA99D3FDE177795C4BAEF35D554 +:10853000FD4EB74BE1F72F43FF56F8C028156029D1 +:108540007FFE39A2DB324BEBFA912A9E4B0CCCF723 +:10855000C278BF7EDB827F53917DB4DD49E79073A3 +:108560007EB389FCD5E6FEEA8FD6DC8B79D99DBF38 +:108570009154CC03EDB47651DCA8A2F5033AAF7860 +:1085800045CB313AB765890F5462BFE35A964F41E4 +:10859000FC8D678DB5E8DF03794871FAE6542E3F0C +:1085A0004E1F19B6797914BEEFF70ABBB02B300411 +:1085B000F9A655F0E73ED46FA0DC23F4AC3DFB7F79 +:1085C00098157D0E2BC80E903FAC861DA2FC42FD77 +:1085D000796748A17360235E77DCAC45D1DB2F045B +:1085E000BFFFC2CBF5A0ECF8C00A84B76CFFBB3666 +:1085F000AF8A79ACCD8351EE36831E76AE7CC64A07 +:1086000013DF74E7B71CE7F772C3BAD6C5C33A3DA8 +:10861000F57ACB70FCBB22003FA3FBAADEB493DC4F +:10862000DC93C1F96FF96B9F8F42B9F5F9DEB22186 +:1086300088AF3BBC3CEE0F743ED985FCF40C23396B +:10864000A6F3632EF223809EEBE37E945CA473E496 +:108650003F5B3BDD03DAB587DF0B01744E740F74AB +:10866000EE43FD22D707744FDF5F40FCDCD46EE1A0 +:10867000E7C0418E0FA5FA64CA57696A9FEA237E54 +:10868000B6006AF3902FC307A89F667EE76D81E965 +:108690003ED78F3149634C443EFE9787CBFFE61CA3 +:1086A000351E6D84385936F041D43EC9EB621F95B2 +:1086B000E26FAC5F878946ED625F107AD73EA1E733 +:1086C000B2A35CDEDF26F6B225BFBBE4DA1D30DFE5 +:1086D000252FC95CFE0B3A3920F4E043D5A954C7D5 +:1086E000FD4285751A0325DE773756AB9A82DBCFBC +:1086F000B8A2C683585E52DC3C058F4C4D9CD57E9B +:10870000909F61D34620FDED3E70E508CADF7DD322 +:10871000CE304571F7975D7F7E12F351F701FE630E +:10872000EC4BE89F6514BF29267AEC8D6E3AA58E36 +:108730006B26F8613ADEF22B14D8E82B9030001F3C +:10874000AF794BEB8300D00FE3B5A3488F77FA02E4 +:108750005476BEF2650ACAF43D47DEF5A2BCDF6D71 +:10876000D346209DEDCE047B20067DFE4ED04F41AA +:108770002F79155F7A797EFAB020BB0BE9A762B733 +:108780004C7FBFE0E46E59C373D8EF6B8114D47390 +:108790008EB3E0CC09B8BF0BBB763E473B9B8F7ACC +:1087A000CB28BA2FC3606732799985EE7B6F95C865 +:1087B0003F5162D243CA59E3CA81B86FB46EB2E185 +:1087C0003C4AB718BF2F47FD651496E7B657BFF46C +:1087D0000AFD258B65A1FE02F443FE89AED764FF36 +:1087E0006646F93D6D98DFF39485E307E425F1A132 +:1087F000AEC73CE1D34EA05E7DC223F613618F76F7 +:10880000354994DF7FE1369E777DC9717513E3F3B7 +:10881000A7BCB01221072F5178FCE2922359140F04 +:108820001DA731F2872C68954288C7125DAF13E708 +:108830002960DB25BD6E3C0BD5E2FD720BB7497498 +:108840000EA36C9BD17F5FBEE195C3681E2E6E3672 +:108850009D8F177831C73776E22F31E21B83E3858E +:108860003F67301B6C386FD5767EE7AD3E16E7AFBD +:108870005F15FDEBED26C473BAA910F32D0FC921C6 +:10888000F1F729DD987F7B8BA08F5B047D54B2B01C +:108890000DF3F717AFE3F3656BAC867B8B17ECBE7C +:1088A00095CE2398E9A864078FBB010229BE53B275 +:1088B000D1F8BE54E0A3D4848F8A8064828BEBDB32 +:1088C0003DE16A9E89EBBB788795FE4E8719AE33F2 +:1088D0006C36E511FDB3E133AFD375FA3A0D67C3DA +:1088E0000DEB5474EEFB0922F68D51FF7DE6F0701E +:1088F000CA7739DD9649FE039D3ECCFD140AFDF989 +:108900008A0D5CCF3CD932256E24DA452F2A7E09A8 +:10891000FAC97FE9332F9EF7C8DB2B338C0B76B671 +:10892000E6DF85E7B477B5655F87F751E4BDA4D08E +:10893000BE91FF521EDD0B92F7525E5C16E551A808 +:1089400049880FE887F6DDCE17B3FF988BF2B36D39 +:108950006A01A279F98B7971A81FEC62DC1F21BD35 +:108960005490D411B58F94C773FFC0CAD4F7EE41A9 +:10897000FDFD8A67F8DF1FBCC2DAF532E61FEC6A3C +:1089800053FCCBA15EFED2DC1ABCA7A27CBBE447A1 +:1089900035FB70FB92E41F219DB55A7D7682F72747 +:1089A00007F07D708744F78557EEBD7C4413E67968 +:1089B0006FCAF7479FCBCE4B50EFC3BC4A961647C2 +:1089C000F6F71583ACB49F9E1810F718DDC7A26D9B +:1089D0002A44397BE2B95D363A37D824B15498C875 +:1089E000E1D4834FD3FD1ECFBE42F90A5376BF4276 +:1089F000F909BDC9FB93219985C9EE6EA47B611667 +:108A00006FD2EB1D740EA258E84D155B8E51BD144C +:108A1000F57F18AF74A31C52E1D7837B7F4DF90D0E +:108A2000153B787E03BC27F9538AF1533542E7732F +:108A300019A783B942FE94317ECF5059233F47A7EF +:108A4000DF8BA4D3F9FC1D73280FAD47BE19DA974D +:108A500014876824FAEE79DF10A7EF1EF72499E84F +:108A6000FB573A7D5FC82E44FAFE7C12CF0FFBFC09 +:108A700015575C2ECCE7F31764CABB3F079DD37E26 +:108A8000FAA2D8FF4F872DB43FE9ED4EB57C4AFBE3 +:108A900048E58BA76DA8AF16B67E42EB30AD75FFEB +:108AA00054C4F3D52C508E78BBBA35CE877C3EADFE +:108AB00083CBADAB5AED21F4535FCD9AEB707D3B88 +:108AC000F73D519788F4F238A7175D9E2D14F85C96 +:108AD00028F0B950E1F73D95E6EE5F8F6ACA558CF4 +:108AE000CB9BAB9A85BCD968C46FA7B55921BA197D +:108AF00029B1C68C9EFB5D19EBA0738F9D6923E89D +:108B0000EF4906C15E453DAC7C87390ECEEDFA0AD1 +:108B1000D37E7A205EDC67F00DEFC178D7B42ED318 +:108B2000BAF87E7615D013C643DAC235B928F77481 +:108B3000FC98D7A54DCD8A3FD779E79785DEAED78C +:108B4000AF15F74C34FB1ADDD176F8153EBE9F9475 +:108B50008E9783B8AEDDF64AF6C151AA2562AF8082 +:108B60009DF2657C3F6EB78C86AE9F4F97597272AF +:108B7000C45EA94FBD6F5A5E32DE1FC1E5C5A97143 +:108B8000D01FE60B288CE454E50E7B08ED0C3C77F7 +:108B90008476C07F03EEF3D8290080000000000037 +:108BA0001F8B080000000000000B8D577F6C14D74E +:108BB000119E77BBF7C33EFBBC87CD116AE2AECFF7 +:108BC000BF3018B3312636A449D62E6928B8CE193D +:108BD0001A429BB45C4814D284B351845C242AB1F9 +:108BE000B6898A42AA466AFF88AA28DA448A94A8E3 +:108BF000343A84514C655BE7C424B6532408D0183A +:108C0000D4B427FEA069656383149C5691E8376F3E +:108C1000F7B833366ACE92E7DE7BF3E6CD7CF3CD50 +:108C2000BC778F0E5EF7A5EB886283E21182AC2CD5 +:108C30008AFBB4A5441D44DE9246C80161A40872B3 +:108C4000D3755FBC8068BCB2A2280EBD1BAABE4C07 +:108C5000C3F8167F1ECECAAEAF15A262A24E48BDA3 +:108C6000383BDFA9A67DACDF39284C1BB2FFC3FF20 +:108C700094951712CD0CCD953D0DD9A8798896F213 +:108C8000FC0F57AB3877F6929FA2E538D8322FD039 +:108C9000FD44CF91F3D9A3111D5882F1E80B6D5417 +:108CA0008F0971B8949A61D74B460AFB3A2F2A86EE +:108CB000A563FE9497A889A8E7B33F8F2E2921BA10 +:108CC000F6BE30FCBAB3FF570D18EFB60F2F81FE7A +:108CD000CDF7846141FDB97B881EC2FC9ED7BD578C +:108CE000D201E7AC5BF27FF2CA41E8258E05F4576A +:108CF00030EAA1DE52826E2F1D963241AF5E57429E +:108D0000B037D0E7635CC8CED91F257AF1DDF9F61C +:108D100012A466C788EFC0DF5A3A4673D61FD50A39 +:108D20004BAE06F1A5966A6F29EC7FFE5181F36781 +:108D3000C615CD2F246E6F7E27179F3180B19CE71B +:108D4000F34C429C33E70AEC3CE8FDFB10D66A8802 +:108D5000A60EC1B81F769A158987678323570F7FA0 +:108D600010E57C32FEF135447F1CFE6095C9FE9310 +:108D70004DB49EFD86DECA1CBF93702AC74FF865AE +:108D8000A4705ED75F1503E6D9AF6A5F49D6AF938B +:108D90006A3A64E4F063EE90D9315A8574890F65BC +:108DA000BE3C6254CADBBC39A5C4ECBAEC18F1EC89 +:108DB00032B1FF27CC0BF843EA6C24063F7FA6E9CB +:108DC00092273D834E7E3D438EC4F93B8871C19806 +:108DD000CF5FB0DE6AEDE5F59BE541B218B7AFAD08 +:108DE000361E7747157A05E3EECF5EA8A19CF3897E +:108DF000FD447EBBBCB311E66DD7398FF4AFEBDC1D +:108E00008D4825C65BE8AD4D1AC65B297998D73FDA +:108E10008E069F675E5B7CEEB2AC9D2F8B14C77F86 +:108E20008E17F62CFABD63D78DB797B6491C7A5DBD +:108E30005EED2E72E23DA8C5BBB90E67CEFD37824E +:108E4000B0E9E4852B21CE5726DF77D6DD6DBF71E3 +:108E500002E373B3453FFF2478D030AE5A4588F320 +:108E6000C4649EDDC6B80CEDF9C741CEDB653F7129 +:108E70003D740FEFA921B61B8FAF8DA10E6F0EFFB2 +:108E8000622DE340A257FA65B17FF06B7AE062444D +:108E9000C77C62E86284D71327D7FFCE82FEBA333D +:108EA0000D5B79FEC4982AF9D770A651F2EFC45F22 +:108EB0001A8B2BD87132826C3731AEC6189FC478AA +:108EC000E3A76DD04B9C696D147CCC99C662EE3FD4 +:108ED000EB04C5925817E395729C89E7379A22E311 +:108EE0009919011F302F28EAF0872AE7F1676FFFF1 +:108EF000691FC7B1774031737994D9F796A64A3B79 +:108F0000EF307F806F4F5298921FC71DB977E08472 +:108F10008CEF456F52E6BBE798D759FF9323895EE4 +:108F200093FB2C5A62311E9FF214F2B0C567AF203A +:108F3000B838514E3B938BF4C3AAB090FB262EC594 +:108F4000BFCB7C996889D768750BF52C6A95F19031 +:108F500070F1EEF76EB617B157E1DA0B15D3AED854 +:108F600022EB5AD8E1CF161FC517F3E78B4C3D1102 +:108F70001DF58017E7DBBC1AF39FC82C588E3EDB2B +:108F8000EEF6D9ED3FF29ABEB55827ED741ED6DB4A +:108F900033FDB619FD0C7D21863FEE6FB1D76345D9 +:108FA0002940DA61CEEF73DB28E6A50AD8D93C7FE9 +:108FB000FE71EE97F52C5569E76E7DF022F7C1D56D +:108FC000F8524DD5DC074929080AF0E6AB31AFA6C7 +:108FD000487FED4AEE0777C697E9331FA3FFE9E81C +:108FE0007F63E87F2C7B6A3FAF4F038F89914BEF04 +:108FF0008765FFCCA32813F01B5847DC09CD3DFB48 +:109000000E7B3DB7EBF3C7F3F896C9CF34D1E664D6 +:10901000DDC2FC5C77EFB34460CA07B25217ED3B88 +:10902000E2411CAB14877F7E6FDC2C451CDE8196F1 +:109030005429F7D35A7451C437FD88B0B9CFC3CF80 +:10904000327F4E9F9F5E2EE47AF70E615BF83A52B4 +:10905000FBB9BCB713A9B33EE65375FFD32FCBBA08 +:10906000B5E80245B2797C2CE0DC97B7F397899795 +:1090700017758E0F7C96FDB8444AD6E7FBB1DDBD6F +:109080000F1F6B9E9FBF1A3AFB8352F8F184290C85 +:109090007BB1BCEFBCEFF452FAF6795F158E1787FF +:1090A00081C7CCD91B3BD6C0DE44ED3FCBF81EEDCB +:1090B000BC0B7FEF0D3BB8760543F55484EE52A30D +:1090C000F7A581C7F1C2F80A69C7F34D6815F1FE2B +:1090D000F49B2F09CE0749FDBBD54B855B2F15614E +:1090E000CDA98B125AC7BC7A4F73C6135E7B05F7A6 +:1090F00003AAC36366C3FFEFBB3DA73EA9E7BC5C01 +:109100001B19AFF7E5E46FEA25D43DDF23431F4584 +:10911000F4825C7E795C7EA9520AB1CDBD1FE7F373 +:109120006D8AF9C6F93EFE51FB93CC93FEED2542C4 +:10913000CFB93F4F9E0F55E5D89D1E54A43EA9E9D7 +:10914000EAC70B73FD7C59FA399D74EC11A5ABB7D6 +:10915000AFC95DEF73799B96BCFDF5CA7D31AEE377 +:109160000C6F557278DB39D041F23E72E34EFAF063 +:10917000057E59C37EFB1DACCF7867CBC23975F134 +:10918000AC8B73534A483E6E204B61BB4DB0F81414 +:109190008F554AA9900F504ACE13AD20E6F1FD2E0F +:1091A0008F9BD4D488A8977A960A5E6EA4B352EFA8 +:1091B000219A95D2243478C85632A46C0EA4B67283 +:1091C000FBA84B2615E6532AA286AF828FDC4A16EF +:1091D000CB5F367E95AE66F809653C6E76C516E9BE +:1091E000D7BF75EBDCE0B71AE7799AECB731F52019 +:1091F000A5153EE40195362B88E7419502F9F0F775 +:10920000F8A847D6EF705AB7B97F19C5EEBE7F618F +:109210001FC64DA653A77CD53CD5908DF74E1C3666 +:10922000C25E11EBA974C42B714CC9F31E66C71141 +:10923000770BE92A8F7BC3E56E9F9FFD399FF3FD76 +:1092400041BF7CE7780296C4E3485897790B02CF78 +:1092500010EC6C7C4DD024CE352A9C7833F637E266 +:10926000D557D4C0FA42EA634C93980F069C7D44CC +:109270009B34C64BA4229E5BC16F8FEB4C84A4DF52 +:10928000A16766AF1D94EF36BFF6365C32063F9994 +:1092900014784F0BD3A403EC4FA020C5EF6BB06341 +:1092A0002AF75DFD4678F71FC2F047E89AC48BE2C3 +:1092B000A4F33B6319BDA1F1BDE161BD6207BE2FFF +:1092C00081DF136EBFBB9CEFF48D77ED6DBA07F9AC +:1092D000D8591230381F0D81B27504BBED85716904 +:1092E000F7B23856258DA8F67AB69BE17990CC6610 +:1092F000C659B8F93A1070ECCDE539926B92F91C69 +:10930000443B0FC0AFA3A88B00C656AB936FEBEFE7 +:1093100079761FCE9BF3C424197FA91801C9F76879 +:109320007CB209526D35F57D05FC64471CC16C1C8F +:109330007D7C0EEE637A160F449061BFE6C4D3576E +:10934000E059C9BF97FA28DFC0E388F6173A3CDB3B +:10935000FF459E4DE50BFD1BF1C74738BE398F31E8 +:109360003921EFD17D4DDCEF18A7EF6570F2647104 +:10937000DA6947FBD2BAC4658CFBEB7D7EFBDE1459 +:10938000F6FDD46F57B1FF193C90204952CDC53935 +:10939000838FC6F9631E9BC85F26FFD12C4E47F30F +:1093A0001D7CF0F3CDC141471ED72C8C3FC3A3FFDA +:1093B000010A95CE3EB00E00000000000000000043 +:1093C0001F8B080000000000000B7BC9C7C0F0A382 +:1093D0001E81BDD0F8E8B89917BF3CA9588601C1D5 +:1093E000CEE6626008E060600804E2DD40BC078809 +:1093F000A539191842803814882703F95380380793 +:109400008893816A1B981918B6B13130EC05E223B4 +:10941000407C9A8D74FB9F8A3330A4C920F85B800E +:10942000EC4D72D4F5E3281EBC38C600953F4713B7 +:1094300095BF449B81E12E929AB99AA4992F68C84E +:10944000C02004C4008B7A89656803000000000016 +:1094500000000000000000001F8B0800000000005A +:10946000000BED7D0B7854D5B9E8DA7BF6EC994921 +:1094700066263B0FC2248664E70501031D6288400F +:10948000D14E5244B4D48E685BF478740848781393 +:10949000F09556BCD9900709093058AC81224E107E +:1094A00011156AA4F8AAB40E88163DB64D5B5BD1BF +:1094B0005A1B11410139296A9D5AAD67FDFF5A3B7C +:1094C000B3F7CE4CC0F6DC73BFFBDD1BBF8FE5DA14 +:1094D000EBFDAFFFBDFEB5462645442A20E40BF860 +:1094E000FB1A21B9222164423C254452FB9C901274 +:1094F000ED8B62539E7C613B9FFC67A3CC798D9082 +:1095000061907E9F906C426EE365F42F00F9A93C58 +:10951000A3CF474F895F26D1B2783F5309CBABA287 +:1095200040BE10E0ABB95C1FA7C1E91D47D208F9E6 +:10953000C4C552AD861655D2F42D57A4A9901097E4 +:10954000102A66EBACFF4A702CA61743DA24905918 +:109550003DEE04F320AB195C76E788A42A3E7F6BCE +:109560003D3D6D6A24243A2A9EB749FE288C4FA6B9 +:1095700010FF8309DA4DA4EB40F8B88904F0903964 +:109580003CDE154213E1BB9D04A2365CAF9FC03C9C +:109590000F78AA8E84B208E99C22FB1DF079530E45 +:1095A00081797975B8CE2AC0BC0C799590AFC33F4C +:1095B000B8DE685B319D47AA5F246BE9A7A69C0AC9 +:1095C000271D93AC9FF4575F88A6A9520F512075B1 +:1095D00093404FF9E0790689C8F7F12E723E70B0DA +:1095E000EE8F1DD680ED6947D9F1F96EB0D379D1F0 +:1095F000F568134402F0595739332D94601FF47401 +:109600000DC0972EBCA5D18969D3C49969A41C7AD1 +:10961000EA9F05705E3F295B5C2BC4E1A2C3E1C0F9 +:10962000A4179D7DB45E3BDF9F4EDF4127B46BE7FF +:10963000FB6E85DB7A800F2DAF2102CEBB6558CA49 +:10964000AC4802B8D4102F96AF77D176B08E1C12EA +:1096500079B010E6D3D73587E6BD13950A80B715E4 +:109660007FA60E93B0BEDB4D220EDCDF803B8796DB +:10967000A71236BE3B8FF8A3743D2EB7DBAFD2BC2A +:10968000345124511DE6F8EF72D33E7849BD835022 +:109690007A4D9D326F061947F36AFF1118DFF9A65C +:1096A000C31F800AE532B657E87F5F14D1FDF8DBAF +:1096B00087584EDE16FC0FC2FC767078296C7C67EA +:1096C000896C1ACFFEF93541806F47F98A9455426B +:1096D0007CFDB2719FE9BA6D96BC7DECCC6F15AB89 +:1096E000C9F7D3DEE725D18B6865DB0D43EE7BC37D +:1096F0009BE32F3D54169FCF8F8827EB3800EB62FA +:109700007231D2FF39DA7FD2E8BFF4901DD7291A1F +:10971000F950B2FA6D1CCFF47C7B21C513C4B33E63 +:10972000DFD563E3DF5FE5F841B46AE46F12DFBFC2 +:10973000F64B48BF8DC2B769ACACAEA67090DC7278 +:109740005418C7C6ECAF02BAA67FF0BDBCB557F03F +:1097500042E636137F6C29BE8A328EE4F393B2CC94 +:10976000FBF365E1F73CC0EFC238FCEC249816052A +:10977000BC0DFA103E1E7D1E977C478DAA09E0782D +:1097800031A53B3A9E3D2B42128DABF341BF10F801 +:1097900035F01F9BEC47BE4526CB09F9A05D109123 +:1097A0004FC5E1EC94101F09FFDB1F42B8C30C9DAD +:1097B000D91C7E8097252FFE0DE027A9249AEAC5A3 +:1097C000EFCD5205A5039568A994FFCB129120FF18 +:1097D00029007B02964F9533804F4CF38780FEED36 +:1097E0007C3C65B6EF6A4F7C3E9FF27D8D97877C0F +:1097F000DF3695DBD97C3D9C7F28734C7831D03E99 +:109800009DB5B7AEF723C2D6FB29A547863F737C2B +:10981000410FF4434CEB6E516F08D6AA280F3E85DA +:10982000FACD5F09F4CC017AE5F2C02A5793F263CE +:109830008B3CB5FB0C79F84731E05311FC9BA7201A +:109840007D11AB1CE76960C43F270F69CB4472767A +:109850009C203039A565E1FA753A225C4FD0F79B20 +:10986000F27593FC90613E94EFB948043B4F25514B +:10987000CC7B483DE63F9E581115683F0EA9AF0DC1 +:10988000F89783F251AD70F0F81BB83C49B68E0DD5 +:109890009724E6FFF9807C80DFEE7A1242BCBD415E +:1098A00001BA12B410F902E88B84B9FCF5FB60BF71 +:1098B0005A1B1BC83BA584A41CBC8EA863611FEA6D +:1098C000038172D04B6815CA824949254B25BF6A6E +:1098D000C4C7817D24ABF87841A43B8A17970AD08E +:1098E000BFD38C3703F85142896E12E6D560C2FEB1 +:1098F000F87EF27A49F16760FFF5F5A832E2AB0530 +:109900002F5C958A00A84DB3BD309FE17C36C343E0 +:10991000ADCBC571B02FDAF49174ADC3FB66CF0047 +:10992000D1E979F38AF7415E3597571CAEA1FB94D4 +:10993000E657AE9E4653570911009E6DD0592EF43E +:10994000F7A2564DD7DB049DD1FCF5AB9E0D686E9A +:10995000861E66BD5254251D5F8A86D44B842F1CFB +:1099600083DB275BBFDD22D70859717E7AD00DAC2F +:109970009D46FF03BA4AB7F4931630F3710F31E4F2 +:109980006979F380DEB4FC7F643C85AC76AA14056B +:10999000EDAAA844E8D869444997286AB8A64A2499 +:1099A0004AF34A567F4054CFBD2FCD844C677C3C50 +:1099B0004C8C78BC99D3B9AFB6B9B095F6FB71A50C +:1099C000DB0F743E9CB2C1CC8CC1EBE9B0C8E18E18 +:1099D000F2BB11EF9B88E62C02BDBE5C44FDA54D99 +:1099E000DDAB18E5D0B33A3F19841F4495AA9035F2 +:1099F000207ED85431E0F2FEEBF861D57BCE173FE4 +:109A0000526F30EFC797DDAFC3801F13CE1F3FFEED +:109A1000D5F1F47D4DC6977CB5B7A25DB1266F68D0 +:109A20003D7EF0BEAE46FEE952492092A0DD2F05F4 +:109A3000C12C7F8C69B6515EDC62DA2FA960DA91A5 +:109A4000EE21E021A91639A8F3B1069B7A2C133A2E +:109A50005050DE38797FEDEADD1AE8ED1FE7018628 +:109A60005079125E1E1540AF2961F61D742002BDAB +:109A7000A88108DA212097E8BE38F8FCEC3EB31E36 +:109A80006F5352CC7ADC2C4D30CEDFD520E33C9C9A +:109A9000301EEDD741ED0518D79647A22E6F1C5FFB +:109AA000612866AFDF795E78A0E32B8095E1ABB9E2 +:109AB0005DABAF22A15E3768BC6BCDF34DCA97ACEE +:109AC000EDDC927ADCA06F246F2791E306BDC50719 +:109AD000B2C5B0FFAD76F2B440F5BC26DF77349C5A +:109AE00037FC9303FC89A03CB3E5D490900A7252F2 +:109AF00065EDD40C265F7709267B5BFF9E7C1E6C90 +:109B0000BCD8CD84F482DC9154D47F93D56F6AF4B1 +:109B10007D55A242C8DEF0C06489EE5FF3AAC0ACF6 +:109B200020ADBFB671D764F8AED7AB11454EBF5468 +:109B30006C56811EC3F196D07A4EFC4ABE00FB885B +:109B40007266D580472ED233592AC3AF7CFF883046 +:109B50004007B4CB25225BAF833C8DF5A023A847FB +:109B6000B938CBD386906FB10702414A776BA5888D +:109B700073054D5B5C3CAFF27C3ACF2B3C5FC8F386 +:109B8000643BE6ED32CDD375A5D8230AE65378BE03 +:109B900090E733783E9DE78B785ED88EF91699F57D +:109BA000D721F5B0FE53785EE5F90C9E5778BE8854 +:109BB000E7C95E36BE83E553ED3DACFF549E2FE40E +:109BC000F94C9E4FE7F9629E17F6623E299F2C637F +:109BD000F08FF305066F1D0F09C0D5E4E78A5AF22E +:109BE0000C5F32058687B16FEA78E347FE48DCF9FF +:109BF000486FC3B9BFA1E906E66F20DC3F62F87E7B +:109C000058057E334BF40F455F8F707EBA8BEBB1F6 +:109C10003B1B15D4BB7734FA30DDDEA8E2F748638E +:109C200019A6DB1AFDF87D6BE3444CB7340630ED22 +:109C30006A9C8EE9A6C620A61B1B6761FD0D8D21BF +:109C4000CCAF6B9C8F6947633DA6ED549F85744DE7 +:109C5000A386694B631BA64D8D614C7F7843C54B32 +:109C6000A0D27EEC1651CE279BFF85BB44131F1E4E +:109C70001D31F3C5515D19A67C6938D754BFB8AD05 +:109C8000C8545EA88D319517345498F223EA279B67 +:109C9000EA5F30BFC694CF095D69AA3F2C38D394E0 +:109CA000CF987ABD29AF4CA935E5BD950B4D797795 +:109CB000F90A53FF2925DF37E59D79AB4DF53B5C6C +:109CC000A19F8A942FC8596B4DF524F7DD6679352D +:109CD00023EBBCF816F948CB06BCD2F98795DFDB3D +:109CE000F2492080728BC99726C05BF0678D209166 +:109CF0000705F0235D7E18FC178E1226771C83E47F +:109D0000A6B93FD9BDF38846C7A9F61EF6F519E8EE +:109D10008C18ED4ECAF7FF2C32BFE2DABB989DDCFF +:109D20007957627B19393BADD7F979623FED9F4492 +:109D30009B452F60764AE75D02D6FF57FBD7CBAD38 +:109D4000FDC6C7A37B5C65B05341EE4F60FFA7190A +:109D5000F4137B5FFA1CB07B743BD6C6E9BCBACC6B +:109D6000FF763385778B42FC0E9A6F71D710D02B1C +:109D70003E5618DD931DF9686FEBF507CFCFA0575E +:109D800020FF4931D9FB927B26F29796ACA1F532A0 +:109D9000396623512AAF6C3101FD72B2149C5E48C2 +:109DA000E9577ED5E65F45505E26B4DF09B91BE171 +:109DB00060B3E837CD732D7C6FEA085CB75DE76F61 +:109DC0005935F8BD59197A5E0E9817CC87CFCB1E3E +:109DD0004BC5D41673E17C27C532313F31968EE9ED +:109DE000C5B10B30AD8AE5603A21568C6965AC107F +:109DF000D38B621762BB8AD8684CC7C72EC2EFFEEE +:109E0000D8784CBF12FB2A7E1F179B84E9D8D8D77D +:109E1000F17B79AC1AD30B63DFC0EF636257603A12 +:109E20003A760D7E2F8B5D8DE9A8D8BF613A3276E8 +:109E30001DA6A5B1399896C466635A1C5B84ED8A49 +:109E4000620B302D8CDD82DFD5D8724C0B627762CD +:109E50009A1FFB1EA623624D98E6C556617A41AC57 +:109E600003DBE5C6DA31CD89FD00BFFB621B31CDD6 +:109E70008E6DC6343DF600962BB16E4CD3628FE2E8 +:109E8000776FEC614C3DB19FE07777EC714C536399 +:109E9000CFE2F794D83398BA62CFE37767EC00A6A5 +:109EA000E7DA2739CFCCC76D5929A6FCC463663ED3 +:109EB0005EF5A6998F57BE6AE6E315AF98F9B8FF2D +:109EC00090998F8FDB6FE6E3E5FBCC7C7CCC6E3327 +:109ED0001F2FDB61E6E323B75E6FAA5FB2C9CCC771 +:109EE0008B3A179ACAD566331FCF5FF97D53FDBCF5 +:109EF0005B579BCA7317AF3595FBE69AF97736D94E +:109F000062B6BFA76E37CB91298F98FA7357EEB51B +:109F10009C034490CFA494FFD4D4CE597230A15D59 +:109F200063F57F0348244ADF779014FF5A61F07E7F +:109F300066707E90097447D32C4E77C380EE689A82 +:109F4000F18DC5787EF4C937DB7E416D4392710196 +:109F5000FD673274BBA12640BFB7E6E879A209903D +:109F60001F4198DF80BC5F8DE5852CDFD574AC5A2E +:109F70002B477D9EFB154E57835FACD5C5F20FD99D +:109F80005E59057E858CB440AE9FA63BEC89F9F8FE +:109F9000633619E1714A0C6CB3D1F5FE6775DFEDDC +:109FA000E00FFCD411DA6EA3DF173B4305E06AFE35 +:109FB000C01E7A4802BE48020FC0F73412D861436F +:109FC0007E6DF67B36828140FBF98B187C18CA3394 +:109FD000AFDA857691BEEE56CFD0F3B9CFC6E45254 +:109FE0006B3A41BB51BB4746798A7F55713FD5BD1E +:109FF000A9DE009477DE236F87F320BB3F9BC9095E +:10A0000062911F9B5A9783CBD101FB6933FA3D7B49 +:10A0100031F5927EF47F2A441120D5D73FB0EE115E +:10A020006CDD141E87603D32F84B697E75EA55136E +:10A03000613D141E2F7078BC681B961C1E044E0ACE +:10A04000AAB82A01FFEC164CFEC7778550AF8D9D4C +:10A050005FE27C54CD8F707BC4C6FCDD3AFCE8DF48 +:10A06000AD19BA3F86B53B82FB60E94FEFA7D7C673 +:10A07000C7E7F250C7E34C918412C1BFA591F99F85 +:10A08000C9AEFC2FE5AFFECC2E261CC72E05F19CD9 +:10A090007410DFCBB2D8F5592138D385F38784E724 +:10A0A000A99364EECF900ACEEB3C4AF79790DDF986 +:10A0B000E755FF217DDD70BE908DA063FB74281FE6 +:10A0C000F3A5BC7D31D7EB9EFFD353D125940F74FC +:10A0D0005230B3F348B33ED7B949C473F4E2114CDC +:10A0E0003F6CE07A80839A0DAE710639DD69D60B3C +:10A0F000DB7438EE37C3B19822F44F2BE8FFB80B6E +:10A10000D8FC14F37A9AF5F55AE6D152EE2746BBFD +:10A110005B1A1B1421EFD8C4E6611D9FF0F3035DA9 +:10A12000EF75B8B9DF4429C07EF571ADE310DB4AA5 +:10A130003C1F4AAA8F58C7F992E76F174989CF2F5A +:10A14000E9FE209C4AB87E441AE81FCD8FE4F3D77D +:10A15000FBD3CFE1F4FCF37FAAC3F3EDD6702DEA75 +:10A1600079AD3E26A7C967B477E88F24C617FD3CB2 +:10A170007C0DD88D60CF95D438B15D568169BF5CB8 +:10A18000A59B9C008F66E56E05D2B565AC5ECAE8FE +:10A190001DFCFB76FCEEEAAA3F0CFAA28BEAAD129C +:10A1A000C07BC4AD58AF595981FED9942EE6B74D46 +:10A1B000E1E5B925AB9D10A2911B0E38A11D5125DB +:10A1C0007F29B4EB0A4F2F027F571BF14B6C0A4ECD +:10A1D000D8C7ED1C0E7925520DB4CB0B6B9A0BDB57 +:10A1E0009100B4D3EB45F87AF3CBC45570AE901F11 +:10A1F0008E846BC04F574FFCA5F8FD60B4D0507FE4 +:10A200001BEF5709B3F993F9AC9E5EBE95F7E70EC5 +:10A21000D7F756433F9B58B92FAF12D837C9566B63 +:10A220004598CF3A8EB7CE424960E741ACFD161D46 +:10A23000CD2CF45E1A66FE4EBD5E179F870DBE974D +:10A24000C7E97E0DB7E7F57A3FE4DD8DB4B40FF3CF +:10A25000EF8E4AD6BE89DBFFFA7E97CACC2FAEE3DB +:10A2600047327C256D067E060BD452CCF9860C93C2 +:10A270001D47EA73CDF9F945E6FAA131E6FCAC0ACF +:10A2800073FDC06453F92703FE92880BFD22DC5F47 +:10A290003292D7D9D2C5F03CEE8FEB7319ED8B3CDF +:10A2A0005E6F5B3D8B7369729F5F5C4918FC16C8DB +:10A2B0002C981F46D1FB69ECC2EFAD81DA141877F8 +:10A2C00067D7D0FDFD84D3D5E39CAE1EE3FBB787F3 +:10A2D000EFC7A3DC1FF330F7C73CC4FD310F707F1D +:10A2E0004C37F863E8F7FBC11FE3003F4D10D32D57 +:10A2F000E08F413F0DF3C7FC90FB6336803FC60102 +:10A30000F8D780E9C6F1E1EBC0CFD6C1FD32EDDC74 +:10A310002FE3B5337FE3C6CB02B950BEE3B2C4F638 +:10A32000AED7CEF024171414CABFF389164D01BA64 +:10A33000E82404CE5B9CAF680137CD8FDEC589640D +:10A34000BF1648A5F9511196CFE3E3809CC0F8A74A +:10A35000061617E3C8D3C86CD8A73CAAED50F8AED0 +:10A36000E1F8FA9AC4C68372A41B95F88C7CFB0DA5 +:10A370002170449A00FDB2F9B8422101CA86DFDAA1 +:10A38000AFC9B45C59DC1B80ADF2B6F544C17E5652 +:10A39000B528EA1B1BABFD87E13C6BF3EF6D7EE458 +:10A3A0001D59C4841FB4EF8476757E6C1BEAB7AD6B +:10A3B000F53CBEA892D5CB4F627F8FD96196FF65E1 +:10A3C0005BCD764F6BC3CC21FDC5C36789167F92E9 +:10A3D000E55C608A191F5B036C5EC9FAF3569AE765 +:10A3E000E32E37F7D7EA1E7A3EAED855A8EF27C33B +:10A3F000F332B1D66D9F10CF17C72EC5FA56FD4E5A +:10A40000227E543EA4A97200CE79A5A94A00F45A2E +:10A4100069AACA533FFF1EE0F920CB2B03E7DBB943 +:10A42000F661087FCBF97680C0F9F3C6D184D917DD +:10A43000DA9CD5812934FF6D82F6C2EBD2B21A2D97 +:10A440008FD2CB0CA768FB0AE01B8B57D0E3BB3243 +:10A45000E5487B21E5E39B378A643BCDEF080F4D50 +:10A46000CF83E218DC01F4CF14772A1520BE93B510 +:10A47000DBD4294E4F14377031A72F728858F5E678 +:10A480008B61BD2D9D33159067D2B57EB40F88CA00 +:10A49000E6AFF3BFCC2D43EF5FBB65BEAE247E9B22 +:10A4A000EFE9F328637C53C7EFCCEF0F8D5FBA7EE3 +:10A4B00016EB114CFE9D61D706ABED142EAD9B89BA +:10A4C000DF4DFB69FDDCC6FC64FB597C998EBF4DFA +:10A4D00081A3C8AFF5F1739568B500F50F4C222A3A +:10A4E000DDD791EE9088F6E001CADF81FE24AA75DF +:10A4F000D2FACAFC6880FBC905D87FA5DEAF411E31 +:10A50000F603F806D89BBC3ECA8D7003550F29FD93 +:10A5100037815FB330CED7753C68F271FF3AD53BD7 +:10A52000B0F433BA3EDD1EA1FF8CEC62FBDC3A8C4A +:10A53000F8719965F5C486FDB0382989EB8FAD9E19 +:10A54000DBF11C509BC0F4026A350704A82769445C +:10A5500084F1E72AFEB5345BDC350EF98AA4680283 +:10A56000E0DB0C21741BEC771CAF7AD83A38DCACFA +:10A5700070BF96F3D59424FB9922337D3B53F65F4D +:10A5800009F6E4E67B287E2788779164D6CF039B83 +:10A5900066A68D56E3F4AA973F6253B19F387DCBF0 +:10A5A0002C4E2F6AB63FFE5FD7E377DBCD7174FF89 +:10A5B0005F8FFFBF5B8F5F3780AFE7D2DBD9FAC910 +:10A5C0002C73FF71FD5D53709E5DAC5CB7073A2C38 +:10A5D000FDEB7ABCAEDFEBFABCAEB793C17A3D9728 +:10A5E0007781D5010AD0516E961FD51A58AD419981 +:10A5F000C5CF61A36CCDE8AFF8C042D792DBAC7792 +:10A600009C3F3F9050DE13FF08133FCDCC1D5A6E88 +:10A61000E872F49311BADE1E427D9A949411A37EDF +:10A62000B5B3A18608743D5B7DC4CF978EE3E4F299 +:10A630007539FB029A884E0D331FDE3AFFA06B94EA +:10A64000819F3BDC3D01380F77FB7A217CC9C877BD +:10A650004BE409C08FAB90AF39D530EECF5DA05F32 +:10A660004E180C57E073BE0CE8D1C25F48B017E239 +:10A670003D8AC7138CAB77409414E5030E3FE34F3C +:10A6800049F9CC79C669E87113F9F40FF8CB2A209F +:10A6900022D0879E36C7931385E289213E80BCD79E +:10A6A000448CF17E3ADCADED9A951A2511BF7B43BF +:10A6B000085D210F8127563F14B1F067AAB08910B9 +:10A6C0007F583C633AFA9706FC5192995F3B227A95 +:10A6D0001CCBFF2CDF9E2327E6DBC9DA0FC43D7FAE +:10A6E000497F5D3B3F8FD7E97B80AE2DFD88E53DFF +:10A6F000A42FC1F8EE7233DC534ACC76C53F802ECE +:10A7000027C0F97186E9BBE4CE4DECFFE77199B53E +:10A7100013F56D53BFFB478ABF0B0EDB09E827BA61 +:10A720009CD1FDB10B203E93EE4F2DC46BD27D9C8E +:10A730004B825E28FC8088D341FFF880FCD67B9159 +:10A74000619F36CBCCFF4EDAEC47E11E901E877836 +:10A750007398E5F5F9D47599F3F3C8CC6C388798FC +:10A76000B7C94E20EE7001918EF6E9F3A7FA4B3B84 +:10A770005C4CA0FDD691FA56E0672DDCDF5EAB1095 +:10A7800009E206973C755FD56C9A8F70FDE72485CA +:10A79000BF6A882F5BE88EC8709EF0CEBE8BBEF37A +:10A7A0005502ED23ADB9103F984E307ED00AF739EF +:10A7B0006DE6F99D6BFED6F9EAF78692CD43DA2570 +:10A7C000248C73FBB1ACC72D6AE7759FE9B760FCB9 +:10A7D000A23FDE7C9FE95CED5EFB27DBBD29AB245D +:10A7E000D1FDA973B57B3BC9784B9C7D32F08B655D +:10A7F0005268BA50148FD392EDC1C0051414D2D34D +:10A80000E3A370A464A8D7769EF50EC379C779D464 +:10A810009B2E0ED1DF194EC7BFD8FD800CF4F9C1B5 +:10A82000236F5F057AF5A2676D54A6D3F2DD1E1281 +:10A83000457B2322831C5BB8CF867E372245ABAE97 +:10A8400031F05F8C90A5FD2F7ACC8371150BF73A10 +:10A85000223368FB854FBE338E50389C59DDFFE2B2 +:10A8600005603F3C22B03842AD6FDC35F4FB4289D5 +:10A87000DC144CC407399E9F7E267516E091B0EB20 +:10A88000C08DD86FCF77ED0EC339DE5F65764F810F +:10A89000D6C3F325ED6121522AB0F919EF2BE8F167 +:10A8A0009BA71F16D8FC9EB6475C30BF5DDD728843 +:10A8B000D65BB6EB2F88B75F7F6C8F17E0B0EC6983 +:10A8C0009B89BF2CDB658B3AC661FAB603EFB904EE +:10A8D000DC02E5234B91C5D074DF128CF75EDAD32E +:10A8E000F1179B17DA9BE987C2C51F05B8BE66F34F +:10A8F000CF80FC4F1EF2821D78B2F7412FC095F633 +:10A900003B5BA67875E947063A23ACFF58C6E0FEE4 +:10A9100008E99701BF96F5B4B3F12CF47912FE273C +:10A9200067B05C18E930CB858FC92B55A818EECAE3 +:10A930004C181F3F201738BD2EDAF3F1368D8E7B71 +:10A940007AEFA96D1A9DFFE27F7CB8ED4ED0037FB0 +:10A95000EE5280CF2C7BE4F75E62807BB583D1FB27 +:10A9600099871FDAB985D2CB99D71DA8B79CF9D999 +:10A97000897C95AEFBCCE37FCB867B02B7FEECB245 +:10A98000E100875B9FF8FAF0A1EC7EC0D788C3B8DE +:10A99000AF11EC5F7D5A60C1F8FB796AD99FE7F788 +:10A9A0003D9F0FF3FCE08803EF152EA3DF1A2A600A +:10A9B000BF9620DF87FC4A0AE7A5BBD7FCC5362E29 +:10A9C00011BCB50B441FA4946C7CB0DFD77CEB9218 +:10A9D0004A48ED7E15FA23FDC8B7ADED96BD4AF79E +:10A9E000F52BC9F7F163F2990CF05FB6BB9D8D6B47 +:10A9F000D9C70FE07F260DDEC79B1CE6F3958FC9F4 +:10AA0000E2FB5197DF9799305E4ADFC7254F7C7B89 +:10AA1000483D40E707E782EF7C1EF757EE082C73AE +:10AA2000005DED4DD57C6C7F233368D9993D1FE7E0 +:10AA3000138A1FEFD9FB6F043ED9FF3387B29D7E87 +:10AA40005FF8B3D790CECE3CF11B5965F79DDC0281 +:10AA5000D513CE9081BF5ED01B96F233E4653B3CAC +:10AA6000518737BE4F4B23574F57BDF8FD6DFC1E26 +:10AA700061F8BF3472E05A21C1BE3DEC28627C39D6 +:10AA8000320CE1B284F4CA4AB9793F8589B08F6F3C +:10AA90004F03BC4BB68FFAFA1558FFC586FDDCC1D3 +:10AAA000E8D65A7F29A54FF00B0EEC6B44788D2425 +:10AAB000A0D333DD0E09E27BCFD8CF713FF74BEA4D +:10AAC0007F0F38929CBF71389C8BCECFB5BE2F0BB9 +:10AAD000BF8DE0B41E36188EA73F4BCCFF9F730886 +:10AAE0007C1EA1E9B9B6C1F2CB4602DA0585F1F9BF +:10AAF000B6F6D890AF9FDE65C3FBA6563EB1942450 +:10AB00003EA7FEA53ECED307C6013F3B7DF0198E82 +:10AB1000970CEF97EE7E5BD6B83C8818E54112FFA4 +:10AB2000D46B9CDF2DDB9FB8BF65BBFF92B0BF939A +:10AB300052E0BB30FF93BD76A2D12E4EF6D8A627A9 +:10AB4000D29F0E38EC26FDA9D55375248DB6B37966 +:10AB5000535418BA6975E035B0E7B4DFDAF11C83F5 +:10AB600048FEF71C704FD393A2AEA5F06AF2CE4315 +:10AB7000FFA3DE5FB3054E922FA8815D2A65052BEA +:10AB8000998ECCE6AD97DB15D1346F2A67F3400E72 +:10AB9000BD35FE841DD6F9678B3EF86789B40EA7D4 +:10ABA000FDFD5913FCABD444F86DEE3FB4D24654CE +:10ABB000A3FC73F4BF05F321CFB908C495D87EEE8A +:10ABC000D2809F2CDBE68A38E87A9E7FE2939D0054 +:10ABD000B733F73B88C310275EC7EDAF134F7CB286 +:10ABE000EDEFB4FC0434A6E3D76DA3F5410FDF9D70 +:10ABF0008AC1FAFFB9376D1CA1FCB9EEB93BAF02AF +:10AC0000FE52073443EBD73D361CF5BAE3C358FE7A +:10AC1000F89E1111D897C53FF9D95290238B7E9C8D +:10AC20004AC03479FE89D76E84FC99E73C18D778FE +:10AC3000E6B91397021D50FD5935CAF105C67704D0 +:10AC400068BF8B20CFCA852F0CF1328B20A57C6387 +:10AC5000D1D36901F0131AEA61BB658EFEDBD151D5 +:10AC60004BB45C116D9C682ED0E1A25DE6F1F29CC4 +:10AC70004C7F5A26F7CF63F5C3B98C5E7BB1DD6894 +:10AC8000A7602AB7B6D7EB8F721659FA61ED973ADB +:10AC9000487D22FCAFE4FD2EDAF5F928737F1AFF18 +:10ACA0006E1D877DBF4D60F74AC8E32E3C475B2C85 +:10ACB000474766507A7D5226F3816E177BA323D3D4 +:10ACC000E978CF723EB93885E6E9F75C3E0FA80F08 +:10ACD00079E2ECFB31ECEF92A75C04F07DC9731EC6 +:10ACE0003C6F59F2E427C77F44BF9F7E2215E3B42F +:10ACF000973C7707EEF71247F446F06BF73FEE40CC +:10AD00003FF2E9C75FCA073DE4B43D9A9F31847DB5 +:10AD1000BEA4070EC107AF83DA0565F5743EDA46B7 +:10AD20001677D64052FCAB68BF0DE0D7003C7ED30F +:10AD3000C5E2A3F839EE0AEE0F3A3B574DC3F99737 +:10AD400033FFD60A7E4F7DC537D5E1E98679405C71 +:10AD500028B988903BE4FA51C0676DB16F1015FCBB +:10AD6000EDB1624CF57A3685AA59706E90C5CEC9A0 +:10AD7000ED597E52570EED581C11715F394067BF77 +:10AD8000A65BBC62B33A1CFAFB7727E32F1DAEC06B +:10AD90004227F21937DEF7C4755286A03DC1D6F5B9 +:10ADA00089C0D6659DEF2776CD01FC3C7EBECDCE19 +:10ADB0004D1A24F53538A72487395F1AB47E4667C3 +:10ADC00067950CA4337D1D1D8D0AF293F6461FA6D0 +:10ADD0006B1ACB888A71F87ECCDB383C1CE51AB143 +:10ADE000C1FD5795CDD5E10E06E05C02FA047FABBC +:10ADF000CD1D42FC72F8EAD1F677BA991FD2E6D699 +:10AE0000481D4DED6E0627B8770A7092795EEA9A72 +:10AE10008170A5EDF1FB025768A313FD11634C7C13 +:10AE20004ACEAA30E507C14DC78B3DFFD3F02308BA +:10AE30002FF0D3A8E83F9F88706B690C60FEFF007D +:10AE4000FC9E61F09B4C5403FDC85935A67C52F81A +:10AE50006DA6F0CB8AD395150E0D3C1E4DA7A764A9 +:10AE6000F4FBC34682CEBCBB1BBB30D5BF6724916D +:10AE7000EB392E819FF78756C1F91F51985F856482 +:10AE80006924CFE04F223E0DEF31E19B2650EE6664 +:10AE90007E447D7F6D8A74DCCCFFD4D7603D77BC67 +:10AEA0006C17815FD91A1E20EF641AE87846D0A586 +:10AEB000229CFDE8BF6DE2F2B565603FCDF4D1D1D3 +:10AEC000A862BA8ED3C9064E271B61DFC13FE717C0 +:10AED000714F3BA713949FF7D03CB3EFA3C4E8D7BF +:10AEE0004EF7F744ED74FF9127A998B2775E8E383C +:10AEF00022A5B45D6A390900BEA41FF95E84BDDFD6 +:10AF0000D283F7FBD339FCC8FEA2F4EBF0FE34B1D8 +:10AF10003339456C2C0DDBC17EB2C2B7C97FD00975 +:10AF20007677B2F964FB35473E1D2FFB4D07F2EFF4 +:10AF3000AC1B7A8ED4D275B83B53D19ECCF6337C01 +:10AF400074FB43429D61FFB293E87D9B5D57385C83 +:10AF50008087107F4BF9F6DD5DC52E3CBFB0F7F85A +:10AF6000800F76A43339A3CEA2A35D1C6F7796F32E +:10AF7000476FA599FE757EAC4CA930E1B1CE6F3319 +:10AF8000A69AF15DE7B76F0EF0DB608E0BCE3563EE +:10AF90005B911EADF8DF649735E12BF0DE06617E34 +:10AFA000A7B705F60ECB603E80F12867FB0AB7C352 +:10AFB0003B00AB79FCB346E905E50EF77FEA77B9CC +:10AFC000F690609B5A08EF81500485776328FE0055 +:10AFD0003DACA7F843305EC8CFE96422A63A7E565E +:10AFE00083F3C4A0B7D94A5E14D9FD0B11640E9146 +:10AFF000A81DE8063FD381494ED00B253B8B53E972 +:10B00000F7883D7036D6E29EE984F86821BD12F7D4 +:10B01000FDAF9EDA82A1CE5508C4F152BC51DC7E50 +:10B020007214C6817BBA40174A05017B728FBB3709 +:10B0300005EC1BBF4B349DE374B842D35C86FC58CF +:10B04000189DEFDBD770FDAC1FEB783339BD933C17 +:10B050008D9418E85B8F0B25AA46CA0C74BEBA748F +:10B060001A8173CDC1F49D848F3DF8DFC3C79A0A5E +:10B0700022B86F762BDFC8A2FCDD8DA9262A30FF0F +:10B08000BDCDFF361EF1AC0EE041DCDB07F497AF1F +:10B09000150D9EA7956FC5E5918AFE2A2A8FEE9D14 +:10B0A000087C30893C3AF0A751DF9269F93B2FD9EF +:10B0B00004A3BF6E7EAC1DE5415D6C1251E97C6B53 +:10B0C000BB7E80E9BCAE6EC4FBF7222D5ED8C7F70D +:10B0D000DA983DF75EC41EC17884CFBEF8C2067E02 +:10B0E0007DC2FA7F6F6B13D623E07D318CFBDE5679 +:10B0F000D69E54AAA84F9FE56BACDDE008405CF9F2 +:10B100007B5DB4DD10F0AC056328817E8AF7FF21FA +:10B11000D69FD48F023EA7D3FB1D32E54B0087B7E5 +:10B120001C09FDEC0B5C97AD03782F70053601BF51 +:10B1300021EE8CF37A87E21D91EABD08EF90F76A61 +:10B14000939F95F931DFE17A31712629F7F2F64ABA +:10B15000E2F2259DA75EBC8BE65ACB434162B0AFBD +:10B160006D84D9D74B9FAEE6EF7DB0F924C04FA6D2 +:10B17000CF763A900FCDE5FE201D5FE3F812F2F294 +:10B18000FBA0267C5A10DB88FB2D748CBD771285C2 +:10B19000DF87148FC02F27745C321CE868D5DAAFC4 +:10B1A0006EB881F6FFD12B36FC3E3FE6C2FAEFDFE8 +:10B1B000E5BFF706D0D77F69C733F68F0E5F86E706 +:10B1C000B1EFDBCD7E841B5318FDFED1C5EC917928 +:10B1D000B10E937E3CAF6D8E0CFEC779B1F5F87D54 +:10B1E0001E1CCAB07B1B87AA4BE0BC86E0F9E81F97 +:10B1F000DBDF9DBA1AE55905FAB1EAD63912DE232A +:10B20000F9A34B35F19DBABE4EEC9750FD282B9B10 +:10B21000F767E01F7531B87402FBA311B867308F70 +:10B22000F39181F96DB59BF8C8FBAEC47E925303D0 +:10B23000EBFB2AD2D1E0F55DCAE84B1FB78FD15D99 +:10B240007C3DF74E4AB49EF83AA660FDF7D3138FC3 +:10B250009F91C2C63FDE389F04281FAA75D07A6E20 +:10B2600018FF96D68960676F4DCF100CEBAAEB5A8A +:10B2700044028675D56D9D2DD71AFA8DEF83ED05A5 +:10B28000E33E64A4FC63EAEA7290DBC17F003DD533 +:10B29000765C322E847636E327EFD8FDF9C0574F1F +:10B2A00074DD9290BE33522CFBD3C5F787EABD956F +:10B2B00086FDD1F7C5DAFEF89FEAFE7A17F8013667 +:10B2C00033A52619BC06ED5B6162B89573FC3C4E54 +:10B2D000E56C08E1A63E7904F07A5D2AC6712687FE +:10B2E000DF85243414FC92E8AF54DF294D9900E344 +:10B2F0001284435D17C38373C12D3E2EC783EAC4F6 +:10B30000EBB97E000F1A884609F6A87C2E3CB8934C +:10B3100068CE21D6318007A34C7870FDDAFCCB8053 +:10B320001EDF033D65D4E0FD3F2A6BDEC9700EB41D +:10B33000D686E74C4753B4ECEB597E3CF0E7A3DEEE +:10B34000F055932BE3F9050F967A671BC63DD1762E +:10B350008B37919FF5FA64F853A291F2AAFF7DF81A +:10B36000F34E927B570B5CD537A6005F0E27F6E7AE +:10B37000EAA9CEBF6D69EE01BB13E4E95177D15F55 +:10B3800023B4F451576801F47387A88E9B2DC4ED44 +:10B39000CF41FA67E3F44B8E9582BF3078C9313BD9 +:10B3A000EA43D81F01BDB290DFDF42FF460ECA0359 +:10B3B000EB79E9FA94C284E7AA2D8DF5171DC30035 +:10B3C000228D28867B6012617AD4A784F9BDF4F5BA +:10B3D000C8F690E207FB522041C073BB146A833861 +:10B3E00028BB2F6BBC66806B670A8BFF731D3AD43A +:10B3F0005648DBBBDE7D45C1B8153A0EF8D79C79BF +:10B40000D259A37FDA9EC5E2124989E17B11C42794 +:10B41000D0BCC9CEA7F31DC24E7D566070D03C0E85 +:10B420007E0F4EB381DCBB4E7FF8024047F1E575DD +:10B430003D0E446A66E5E97A71332BE7FECB65B5CC +:10B44000CC3F69DDD7EBF6AFC177F5AEDB9F3307B5 +:10B45000FC58D7B947BD0BE70BCF820F1FF03D9DBE +:10B46000C9656BBBC7389DFE5BB7A8D9E9BE1CB2E6 +:10B47000F71F84B876ED36F64EE2F5BF3F644FA570 +:10B48000E91BAF1EB5435CD14D10A043D7359BA837 +:10B490003253822308D739A4C7C3F23DC3667A8CDE +:10B4A000FD515315FA5BCECE79AFFFFDAB9781F816 +:10B4B000A4FDB5407AD32B4486FE67EF535BD9B524 +:10B4C0003BDEDF7EDA9F18EF2F0E4799D9399213B2 +:10B4D000E112879313E1F6FA405CA4867E14039C84 +:10B4E00051DFD0E13C00B7B459579271C9E9E53A50 +:10B4F000F7C877C9B8F8BCAC70FE088A28BD3D9380 +:10B5000012F815D04D2425F06B48173BFBF3A5220C +:10B51000BC77F83BE0B34B6DA182EC62BC8F386A1C +:10B5200018C471F5263E5FB5D2E95B402F10CFCD30 +:10B53000E32B6FE4EB7BFE7B273C1837F9C46BF9F8 +:10B54000902EB1F5ADFB2ED0DB7FD850FF3EBB6F08 +:10B55000D49071696F717FC7C914FD3D16B6BE9B4B +:10B56000B81E77D3BED408BC7B795383CDA4FFDE4D +:10B57000D4C0E23888D43BEE5A931ED99CB41FB095 +:10B580003BADFDE8EB3B989F7B21D887F74F90556B +:10B59000F03F1C78E5ECEB75349F32C289E7B2EBE3 +:10B5A000D239FE568BB8EFF7A70752C782DF696D15 +:10B5B000865FA3EB5CFB02E911297C0E8EBE3D5237 +:10B5C00043C75B7F89883EAB0DB107306E522B6756 +:10B5D000EF14295C1FDDD07BB40BF0F1C41107FA26 +:10B5E000FBED1E765F75AD3D980FFAFBBBDD72C2B9 +:10B5F00077EFFEEE96705DDD421FC6BBCD21612761 +:10B60000F08D7DBD3387C37CBC7EA200FA9FD86AD3 +:10B6100013F93D28EEE7884ACCCFAE492C1FE0A9AC +:10B62000E232C6ABB54F9F8AF114733B7F8371C280 +:10B630005E7E9FC93A8F0B53D97C3DBD1957007C64 +:10B640003D53457CD3C8E3EFC778F182DE1A19DB9E +:10B65000878521DB17AC54AE00B8427BE0FF05E7DD +:10B66000D9BE3895C53B6DE47672B7DDDF3A95F605 +:10B67000D3BD2E5D80FDD0EB4D4965FACC89A9BACA +:10B68000FF268CFE9BFC12C505EFA3E40790B8894A +:10B69000A7328C71B8DBA11EF36F221CBA473F1989 +:10B6A00085F3E3B5201B609FED0C9FD6AE13D09FB2 +:10B6B00049E1970BF2E2DD7B1CDF807514B4090AC7 +:10B6C000D8DE344D38EF5BDD4E66B774DE8B762006 +:10B6D000B847A1DFFCADBFC3797992AC779B9BC122 +:10B6E000EBDD73E0475AAA9DDD1B6AE8E57652144C +:10B6F000DF3F0CEBEFC2052AD9BB84524035C6A10F +:10B70000C4E987D961749D0138DFAA9D2847C00F1D +:10B7100020B675E33BBF73C20E72395D5FA7D01BC5 +:10B72000007AD12688FCFDADC05B00A7F51B8763BE +:10B730003CDB1A31908FFE9DFF25E3F9D8C1C0D9BB +:10B74000CD73687EDB4419E9E26080DD6BBD7F6507 +:10B750005137D8E19E861A7CB737A2E04BB8A4A92E +:10B7600092BC0CF1A44D2B4545A0F5C341FD7E8153 +:10B7700092027831DEF6E11565707E9623822F897C +:10B780009C10D8BB202D2B6B14D8D716254B30DA44 +:10B790002DB7A432F9F2ABF4E02DA934F5DD75B77D +:10B7A0000231DD1B62991782BF506B9355F67E30D4 +:10B7B0007B4F2493EF4B66AF189DE7C5BC7B3E35AE +:10B7C00091374C617ECA1F5C1962FE453893AC42CA +:10B7D000FF22FFF3E1BE66F1DCDA312998D9B47AB1 +:10B7E0001ED6877EB2693F999562B48AF6BB3D3D0D +:10B7F000B00DE5C9654E841391FABA004E91CB7233 +:10B80000FD10D77AF7A491BF8127A5320FF7CF0497 +:10B81000391A1991F24637F0A91659053ACF5C79D1 +:10B82000FC06F89EEEFFE12D906636FFE14E900794 +:10B83000E97D7F69C4EFD365937F2FF3CDF73F8711 +:10B84000F2CCA06CF2139E4E0FFE3095EEFBB6F2DA +:10B850007018DE3DC51DCD8EAF63CFAADEE9F08E38 +:10B86000F589AB45FF765E8EEBDAA444D632B85547 +:10B87000825CD3E1B646547BE01D65ED2A27E247A2 +:10B8800009E9457E9503A7C8C5F17DC97CB37D391B +:10B89000C44958E7F308A75BF883772531FE9ECAB1 +:10B8A0003139676A0AE0F5E315BD3ED0E3D7A52735 +:10B8B0008E4F38E966ED1D49EEA71FE7E5C012BBC4 +:10B8C0002A300D8C85D44DB43448F39CF83EE1E326 +:10B8D000A2FA47C4F3BB6D2AEC0FD4B7D3FD3BF0FB +:10B8E000F249F40F1E08FF0ED317DC657A7FD16C86 +:10B8F000DA7E7DE551F6CEB7C270A4AE8DF18B3AFB +:10B900005F9F13CE2BEACA89B29DE39BA6C319FCA5 +:10B910005D5C5ED55ECBE09A554EF0BC157C62F066 +:10B920004E5936D4A3F0CB6A5BB51CF791F46AC5C7 +:10B93000B4DE7AE817F6A799DD3B21A4CF89F41B82 +:10B94000B6E17923A5F75FC179626DE7703C6F8737 +:10B95000EBE9D05F061F3783F7D74DFB01FFDF8987 +:10B96000361BD98EFCAD97405E5D497119F1B3BFAE +:10B97000BA8CF6AB562ACA5A1D0F743E4649632E3E +:10B98000951700B7B99AB61CF0EFA8537919E6914C +:10B99000BAC9A1C2FAE76E7AEA0ED05B527D7D6D1C +:10B9A000C01FEA26B2F96674D2EFA8DFA8BF82FAF8 +:10B9B000759D0E958DC7E157C9F18CC3E1663EEFC9 +:10B9C0009BB7B279A78C8884013FEB5652B8425995 +:10B9D00088E13DB834BF1091AE0EC3FA3D5A36F639 +:10B9E0003B6C96852E2CF8A7AFAB96AFAB76255B5C +:10B9F00017E1F444A715857E6B2BD93AE712D65E82 +:10BA000084EFB4FF9BF97A6AB52731BDB9CD61EAFD +:10BA10007F5BD98E5E984F61B9AC0A0867F63E66C7 +:10BA20003E5F577E331B2FBFFC4984176930CC170C +:10BA3000FDA2863CA5AB132F51C2A27AAE0081FCB9 +:10BA4000B4DFA3DF93F11CA56493795D27DA473D4A +:10BA5000D009FECF7B643CAF785CF4BF558076A8FC +:10BA6000AC32FEE3FFDD0CE0D33737E3BDA93DD5B3 +:10BA70000CFE27BE4922800FA587831900EFD2C391 +:10BA8000219ED6E33936DE13AB8AE331359DDA04E5 +:10BA9000E097B1E247E7031FA0FB0CFAE008E3BC24 +:10BAA000E9FC32DBB26B200E296B62468D8C4FFABB +:10BAB0005ACA0F6F9909EFD7661DDA720B8C934340 +:10BAC0000CEBA1E5459E62A4BBCC43B414EA351C43 +:10BAD000BF0BF6A393BF2F5F0A33CBC0F410A4991A +:10BAE00094BE3B32609E12995A11E7070FDE533520 +:10BAF0001EF80ADE29A9C0344A2A06F30D43FDD1F7 +:10BB0000BCBE2624A837DAA39AECF207EF99361ABE +:10BB1000ECF7F5A027D27D6A27CA87101FA3F94545 +:10BB200084FB7A7BD4594EF36BA8DE08FACB86B23D +:10BB30003F884077EBF7113FE04766F01F0EE33E8A +:10BB4000CE71A7E3BA25997400FD1F1C7D7C3AECE9 +:10BB500053E48088EF48D4FCC2BD2515F4A1D75921 +:10BB6000FC49F74BF528BF6FCF9713BEC34CCEA14E +:10BB7000275AEB6794CE443F5EC1A68DD3E13E4E7B +:10BB8000DD74C97F39AD9DB5A9BA1AF4183548B12D +:10BB90006B389DF7D6F1AB8008D519ECBC4A9DCE29 +:10BBA000BEAB5359DAD138FF22B0DBC3BB24173CFC +:10BBB000853CA69DBD57D7517ED619A27A6965F5F9 +:10BBC0005EE737E9F76395540AD2EFC7A69C75C1C3 +:10BBD000F9CCFD95359900CF7D6D66BD8EC0636A49 +:10BBE000D40E1AEB08073C745E9DBF27084F9B23B9 +:10BBF000DA554BF3B6A7DCA0E10CB26FDA3BBB67BA +:10BC0000019ECE2DC3F0E441EB3DCBE5C59C867E85 +:10BC1000BC5755A811768E1ABE1799F2CD9C6514A3 +:10BC20006ABDC8743C9B987D1296022F025F0E97E6 +:10BC3000876468A2F3B3CED2DA9DC0CFFE067A1D28 +:10BC4000C8B9FAF978FF11E9DF06FA507F7522BB0F +:10BC500029989A82F33DB1F59AD7C03F3DB781E963 +:10BC6000FB055B3F14703FA8DE9743FB2FA8C4275A +:10BC70002AC9DC9561E758D89F1291A82ACCA787DA +:10BC8000809D10A6F2C70807BDDF7FB6FD3AB70357 +:10BC9000DB07C1781E165F8F9BAF27DF4FD793401E +:10BCA0004E5FC5C7BDEDBE0F0F4C02F8AF64265204 +:10BCB00041F86DC169984781767EF3F816F447E143 +:10BCC000B9D3CDEE437B2AFBF0DE9195BF833A0FCB +:10BCD00074BB2DF5CC7866DF9BF9E9A03CC72BEB54 +:10BCE000F77C0BBF1AEBE8B912F7770F7BEF9C10CC +:10BCF0004AB74E7C065465EFC446F477C9EBA1DE23 +:10BD0000188F5B013CE81CFD870A80CF3AAE2FDC20 +:10BD10005C4ED05EBD39AF17F58539CD5C5F90FCC8 +:10BD2000ADC06453B7A693B506FD0143FCE188B1ED +:10BD300099EB0BBAFCE772BBCED7DB867215F40326 +:10BD4000835CADD5985C2DF031B95ED746C75139CB +:10BD5000325719F51226C7D54D5C7FE07238938FA4 +:10BD60009BD5C6E45526E8115E083FD0502EE35916 +:10BD70005E765C6F1956CEE46566E7E328D75E0110 +:10BD8000A7CB04E01B4C5E8EF8CDAB1A80C9473FB1 +:10BD900077513EFD142FF729543FCB88EB676B4456 +:10BDA0007ECE44987E88B1F5749E8FF1FAFAF71D25 +:10BDB0007C7E8F1FCAF806F0D707C345E36D06BA2D +:10BDC00045AF27CDE757B273FAFC06764EEDF1CFBB +:10BDD000DB69339C3F34BB99BDD9ACE35543D407F1 +:10BDE000FDE2FD40E4E3EC7DA976FE1E946E5F7DEE +:10BDF0002795FB3538FE2493273A1FF29080B79C95 +:10BE0000C2F7586427F26B8DDA4BB0B663E1A6DC5B +:10BE10008540EFE1AB2B61FEEB27FD15E32E0A9287 +:10BE2000D88B7F073B93C1E14BF175CFF457991D38 +:10BE3000DA2B26BC2733D123E13C7B24920AF07411 +:10BE400085D9FB84AE8972C2FA177A18DF943DEC6B +:10BE50001ED1FA493BF17E6352F92C11CD96409EDA +:10BE6000EAF2B613F6793221D5EE59AD1AF2FD4851 +:10BE7000D086FC95A0DD19E6BFFFA295C9E837EC96 +:10BE8000B4879DB01F1B2AF9BE2ACE6EB88FFEA5BF +:10BE9000F785C203F6B93D2046E07E793BB554C72D +:10BEA00032BF0EFE7ECE096ABF1BCF292EF3881C3F +:10BEB0004EAA08F189056D0CBFD64F92711E6BC753 +:10BEC0006777DB0A8DFC97C12998CAE0B476D28BDC +:10BED000885FE73BBF790D774E3E6638473CBEF939 +:10BEE000A1228073FC9D96C090F717E635FC66F2A0 +:10BEF0008E04E70303E56047B9C10E8C5C6F3C67B5 +:10BF0000F9770FB3AB431EB3FF0EF8AB1D8D8B4813 +:10BF10002EF897F65C12F1A2FF7E313BAF5DC0CFE9 +:10BF20006B4FEEB806DF53184BD1CA9E60DFDF6F50 +:10BF300034BFA7F0FE830FE532BF46C414E7B160FB +:10BF4000E73363D8BB661AFF9D0CA26655B177AF85 +:10BF5000514EBFE8D71CF8EE5C10F9900CBF5301AE +:10BF6000FE76A0E062B8D7DF83A91BE8B778F07B44 +:10BF70006E19540D43BB8B0431CD26F598FA481841 +:10BF8000D35CD283691ED8B9C52017FA31558922EE +:10BF90001203DF2F227ECC979020A612EC5B66FC6A +:10BFA0005C42DAE5C4F80B38BF00BAD7CF29F4F306 +:10BFB000FD199EDA4E0F327BF379C5524F609D0713 +:10BFC000E11F45BE3D87B3F0C33F1ED303F77B5649 +:10BFD000AC63F74B74BE8E760DEDFFD10C2607B423 +:10BFE000BB05E45FAB53AFBA14E1D8693F6D3C6F5A +:10BFF000204E6709FCFE8BDEEF1CEE5F98C3E51F49 +:10C00000B8B7D9FD3B3FDEFF99037E0643391928B7 +:10C0100067F7AAF57EC4D42923873ADF33B4C778FB +:10C02000E45A8BFE7F4EB96DC9CFB5B6FF8C4E2852 +:10C030003BEE877BF452359F9D3331B94D1149C595 +:10C04000766D8EB7D10E0B5F1630C2E510C77F5DDF +:10C050009ECCB5F8F5ADE95C89D385A51F2AF9D248 +:10C06000E15E04BE6962A06BFDDD5BFD77D2160464 +:10C0700042720E6BE6C3773DF8BCC3646B4D0E4D48 +:10C08000DF83BCC19F7FD81BFAADC7608728817A48 +:10C0900091BFFF8774388FD3E165B6CE6AE06F2712 +:10C0A00042C40FF6C30252BF1EF431F2AA0DF9DBEF +:10C0B0000574DE7205D86F44133330AFC1EFF97CDD +:10C0C000D0C8EEE51CE7EF56EFE4EF249DE2EF5415 +:10C0D0008FEDBAE32AC08393FCBD6A9DFEF571C75C +:10C0E000F6A4CE06B93FB6E7923AA8377697230A68 +:10C0F000702EDBD71E04BF10BCCF9242C7C9A3E38A +:10C100003933808F1094B7A73A5322ABE93C4F756F +:10C11000D9902F7F5C2EE23B23F0CCA58DCF2F2D25 +:10C1200003FAF9FB8DA0879CE47C447FEFF154B5C2 +:10C130008AF6F10B7BD608702FE1D46C15D77D2AD7 +:10C14000A7273F83C2C7E765F1E525BB1DD1223A8A +:10C150008F858FBC5E540BFCAF28BC30D13973BACD +:10C1600097F1BF534F108C873BE5E2BF4FE4ECF1F2 +:10C170001AFDACA95EC164179EF2F0DF39CA3B47D5 +:10C180003D1E5F4EDC3D5E46F73D5E388FBA37F5AB +:10C19000C7787FEDF813EC9CE285CD75F9E08F1A36 +:10C1A000EE55D939FE9E9F60DC38AC03EC683A3F0F +:10C1B00015E6776FEA5B27C1FF40DBE1FD0CBDDDD3 +:10C1C000F13D75AC7E17ADEF45B8136F05E0038305 +:10C1D0003BD9CDF884AE3F2E8A64E3EF2DC4CB4526 +:10C1E0002C8729BA28FCC7EEBE1ACFB5467B3398F8 +:10C1F0007C507AC6CCC4F987F3611D7B2E09E58398 +:10C200001FEFB8FE7B4E52381FE030C3131AED35D6 +:10C21000F0F7F7DF7E0AF97B9958FFE7BB002FF7AD +:10C22000B2DF1FB9E3CD8DA2917F4CF432FFFABD8E +:10C23000A94BBD701E757CE09D9C308BF7D9CFDE7D +:10C24000615DC469EF7837B59F283CDEDFFD032CC4 +:10C250003F3EF08E4D0FC693BDBFFBF90C486B7986 +:10C260003C3F895C83F445E1D2E64C20AF06EE45C5 +:10C2700045D87DB733027F7FF43E1D6EF5F24CD377 +:10C280007915A3EFBCAD8587505F8E24BE276795D7 +:10C29000F7D6F764CF750FF828A7D363FC9D92A556 +:10C2A0009ED0B7BD09E4486DC7927C80732DDCA990 +:10C2B000C33887AF5E0EF636DE3761EFC946114EE2 +:10C2C000FA7BB1643C2B4F67F9C5DE2BD7804E74E7 +:10C2D0005C7F7F56FB1A2B2F64E56DBCFC254F70ED +:10C2E0002E1B9FBD2744B9623AFC2E85CEFF92AF2C +:10C2F000DFFCBB143F029E3C01FB5B8AFD49B4BFDF +:10C30000B1FF7A7F3ABFF997FB71FEF7F6A3F361AD +:10C31000A04B08D9237EFF98FF0EF8FDB3EDC9AC02 +:10C3200002133FFF6473712B9C037DCCDF0F71748C +:10C33000AE2220976EDEB4D1F4BB26D677BD9A78B4 +:10C340003C895C4CE9CC40CFFBBD4C8FDECFF92162 +:10C35000FCB90DEFF9C05F673686DCA0FD378ABFF8 +:10C36000F35E46C2A85F8D213D9896935E4CC791BF +:10C370007E4CF198B4185C7D7E1B7FAFB70A16BF68 +:10C38000D819BA1F42753F75849E017C82777B0560 +:10C390001BE8454B27C3FC7FEE55F4DFF52496DF01 +:10C3A0004B8BFF0E880A7ACD0CDF507A0D51A4D347 +:10C3B00003F11B45F8EEEF0B5EEC37D9EFBF2DB75D +:10C3C000BC7FC2EE11EB7058427A300EE285AD2B85 +:10C3D0005E1E4DE1BF70B707E5C1C8ADCDF8FB5F8C +:10C3E0000B496F36DC2F1DC9DF93205DECF785F418 +:10C3F00077224677394CEFD42DB1FCFED022FE7B5C +:10C40000618B2CDFF5FB9B1DF021411C81F5FEE7C4 +:10C410003BDE24EF369527FE1D18EBFDCFDD3D22D8 +:10C42000C6F7AC80782121CEF746EFA87798F1AB1C +:10C43000E7D212C3FB4E4D829FD9D39E94C083C2D4 +:10C44000E071462A0CBFF60842C238B26FA6897C5A +:10C450001F9AC995B49FA6C59202F666532405CFCC +:10C46000419B1466175EE0A971829D4ED2457C47C0 +:10C470006E9A6D0AC697CB4BA48BE0DCF3D0F685A1 +:10C48000BD707FA1C927A19FF68274760E4A7244BF +:10C490007C1FA059D99B3E07F6C9CDCE1947282449 +:10C4A0000271F007BA6F1721DF44CD96E1308E108C +:10C4B000EAC57B373912E1E7AF33C653FC2BE0F80E +:10C4C00020914EBC7F3C75C93117C8F502BEEF13F1 +:10C4D000D20A99DF98EFE7B686A3E980A72F75B750 +:10C4E000FE761AEDCF1E9130AEB5ECF3A637A6D18D +:10C4F000F1FABB658C67D5E190BF5232DD9FCDBBB1 +:10C50000D59C972DF788256228A7F9517C7C78C0A7 +:10C51000296A8CABCA0A3067A1E246FCB8284D20D4 +:10C52000786EC3F3A3214FF174973D5C03EF61EE86 +:10C53000FA93807E8783DDF30A304EFF995001E045 +:10C54000B78E0FD6FDFB1BD7872806B8F8FD6017FE +:10C550001CD659F1A7B99194823FDA193994722106 +:10C56000ECE3613BBE23D5C2F56F89FF4EAF8E2F42 +:10C57000D6B4C582772D9F5F8378D74FF16EFB10BD +:10C580007827292AEA09F63CE207F2B767F5E62A96 +:10C59000B4DD854FC97E3705D9B4C7CAD3409FB92A +:10C5A000F0F9EBF09E2CC00BDF796C904BC1EE776D +:10C5B000346495C2EF1D4D7BCC8DF878D6CDCE7FFF +:10C5C000A486543F94377557F954035EB7362AA5AD +:10C5D0005229BC6FEA2C85DF456A4DF23BCC23D251 +:10C5E000C520F897646EFFCF4B63F39D97968AE959 +:10C5F000CD3C7F9FA4CD84F9DF47F107E2050EDC37 +:10C60000CAF077458E13EF3DAF78A978F8507140A6 +:10C610003B1B7DA500B7ADB7D6A2DFA37AF921D722 +:10C62000E540E71EA702F868F38EBC770AE0FBCB73 +:10C6300076BCF7D5E4A952E718FAB37927A25FC907 +:10C64000266AB96014DD9976E4722907F045DB02A9 +:10C6500092A869C373974B943FEDF268B9022DEF2E +:10C66000D8F03CCB0FD3B608B4FC071B7EC1EA8FD1 +:10C67000D072E1973F7EB4E13F5879A9B605F20F39 +:10C680006CF835CB836E41F5984737FCEE72B82FC6 +:10C69000DD64F7CF02FFCE8FE9FCCBE9FC7B78BAF3 +:10C6A000278DF973F4F2BDF09DC27B1F4FADE54FAE +:10C6B000F2764F2729FF292FDF9FA4FF9FF376D122 +:10C6C00024ED0FF2768792B47F91B73B9CA4FC6572 +:10C6D0005EFE4A92FE7FC5DBF52669FF5BDEEED586 +:10C6E00024EDFFC0DB1D4952FE062F7FD3D2FF5B36 +:10C6F000BC7E1FFF9EE7697B43A37897D7CD5EF68C +:10C700002CF3B4A1FEBEB5BE12F1BF6902D33374DF +:10C710007CCF83784D9A2F52585C5591C2ECB85F0C +:10C72000F0FEAB97976C00BC5BF14B1BCA532A47DA +:10C73000F0F774B5E52CEE65C54BEC3EC88AE51202 +:10C74000BECFAEE3E32F2CF3DFC6E7D7CCE7FB5C2D +:10C750005A113F6FF195CE30C67B2AE6BC93D213B7 +:10C7600084EC346731F952B6BCC6390AE407952F18 +:10C77000C0375BDC7214EED1B72812963767D52824 +:10C7800050AE2912CA9F96AC1AE71CF4E764A07F4A +:10C79000A280C7ED352B12DEE397D2A762F9B4C7AA +:10C7A0006628C0479B497F3ABCCFA7AD94F0BCF642 +:10C7B000407D0D7E2F48FF281DF8F38174B6AE43EF +:10C7C0009E175DF08EAB749B88F26224C08F8E5BE7 +:10C7D000B4528CA8B4CA21658508F9079A99BCA2FD +:10C7E0007F9EF186771477DD5EF532C4EF34AD932A +:10C7F000F077B6E14F32C88312FE3BA5994A8649CD +:10C800005EDDC7FDB89ACF8971782512F1197FBF17 +:10C810003253E1E769B619F88E5971D82C9F0ADBBB +:10C82000CCEFD81458E493555E8DA8A7FCD150DF07 +:10C83000E1534CF9CFD3F87B167EE2077D66C5E362 +:10C840002B2E8750769D5FEBF2E5BF005F71521291 +:10C8500000800000000000001F8B080000000000A6 +:10C86000000BDD7D0B7854D5B5F03E67CE3C3349E7 +:10C8700066263393C97B1220040838811023BE2614 +:10C88000216044B403A2E2A338E11920C9044A2B71 +:10C8900056BC4C48C440B186DB8840810E2A8AF5DC +:10C8A000D1A1458D18EC808878ABBDD1D25ED4D6AD +:10C8B0008EC855501EA3B648BDB5FC7BADBD7732C2 +:10C8C000E724516CFDEEFDBE3FFDEC619FBDCF7EC8 +:10C8D000ACBDDE6BED3DE7CFD3BF2B09695D19BD64 +:10C8E00062A89E902D2B4DC314FA6CFD72DC4C5245 +:10C8F0004E4822D5E27F482264F54ADB3065182194 +:10C90000E779FB621B7DE92264AB129E4E9CF41911 +:10C9100051484B2121FB96C904CA4BB34C11236DDE +:10C92000B2F4D5DF5D3D1CCA4B641FF1F67DAF7DCF +:10C930003EBAD2330CC67F259D60BFFAA034ECD836 +:10C9400038FA6F25E809A41232A443391A3711FCCA +:10C950003B4FFF2B6CA7E592BEB25E1FB0D9AC84F3 +:10C960001490A476743E8AA6AC771DB6074BA17FBF +:10C9700005FBD7CE23AF99AE3FA95FA3C7A62AAFC9 +:10C98000969A4BC810FAA47305F8845D7264075D2B +:10C9900067EEF2BB261CCB2024E7A0A58DC01A3A77 +:10C9A0001E24C44D880EC6A6EB5624BF97E808691E +:10C9B0002B2CF349F479E8690B83539E15E16490BD +:10C9C0007C99D7D0A7510ED8A07FFAE787FEEFCD8C +:10C9D000B36C5F5B08C5A009E090BB9376984D8B64 +:10C9E000E1DC35FEA1749F28B8C904A8EF69F7D32C +:10C9F000F5EF947ACBB5508E460CAC3D2131F8BFA3 +:10CA00005DB2C4EB895FF110F29424F1FA91B5356F +:10CA1000B9B4BD621BA5F80899DD31BA5D7F39D480 +:10CA2000CBE27B3FA9A4EB83F17819E0F2C4015E6D +:10CA30001FBEB4BD86CE6797418C4FC2D07E972C67 +:10CA4000B372B8BCBDE632DA5F35FF3E9CBFC69F0D +:10CA50008BF3B9466727A4D97665BBF592BEF9B6C4 +:10CA6000D827B5B728849CF2C6D3E87691C6EDC71F +:10CA7000DC8476B57A6630007024C44702A309F9D5 +:10CA80006FC98BF822F64FBFBB2A9C435F9D39F8D4 +:10CA9000455A297D8674F18329147E8D5D4193BEAC +:10CAA00088C259EF0FE714F67DD7B87B1A095238C0 +:10CAB00085BACBF039C0778714F99FFACE64B88075 +:10CAC000F14EC5DE6C7A925635EA82EDD621D89EBB +:10CAD000B0FD1F787DE2FB534FBE79238C77DA1BC4 +:10CAE000774F01BC8C51B80CF09D68DFD4554500E0 +:10CAF000EFFF62F1AFB48D27E4263BA333A234FBF2 +:10CB0000A07DD4D461F3D17AB3BE23E0A3EDE9567E +:10CB100046E4CABEE72ADB506CAF7DAFA59FA8896B +:10CB2000644CA5781D6E507C3B0894C329636879DA +:10CB30005DA332AE854E6955D91FC69642F9192BB1 +:10CB400031D2726BC3014F29D091CF40287B21EBAA +:10CB50002E8966011DB7351A663E42E7138D2DF505 +:10CB6000CC2BEDEBBFC54E098FCE7FCDCB94CE2E17 +:10CB7000A24F7DD42EC1F7C314027468B6D37DA62C +:10CB800065739683840BA19D751DD0E31A7DB0B6A5 +:10CB90001ADA65C964071DD73C6C466D359D87C799 +:10CBA000254B3A9C47CD91F9B4BED56600CE467E62 +:10CBB0006B9FBD13E0F484E26B063A7CC26AB585D4 +:10CBC0006905E58D7EA05B6598330265A38E3447C9 +:10CBD000E9FC72CA48206AED9BE76F397FFCADCD56 +:10CBE00080F35D678E4EABA2FD5896CAB6301D6FBE +:10CBF0004DE3869EC9749C9F363EFB460B7DBFD697 +:10CC0000AD109887D5A9C40C69148FAFA573A4F390 +:10CC10007EAA256003FE997029E4215A6F196A20C3 +:10CC2000DE243E682DA5E524FE94E154FC66FAFD61 +:10CC3000497BF0D7363AFEB8D70F9BE07BCF7859C7 +:10CC400006B2892A6C9FD3CAD5FDD82E53F7E3A824 +:10CC500051D73BA7AAEBDD33D4F59EDBD4E5ECB985 +:10CC6000EA722DE0DB786848E75C41D7C1AA8825E5 +:10CC7000FEC94A9286F0790BE06F29967D001F73FA +:10CC8000E323C7E7D3FA1CE02774FE640C89ECA009 +:10CC9000FBB93FFF87DE3885B3D1D1ECB597F68776 +:10CCA000474E9EE91AD82FEB50C546687BEB1F4FC5 +:10CCB0007C09FD5B4952BB42808F3F0EFB0B7F1E00 +:10CCC0003A9F54F88717E0DDFCE7BB41EEBDA1F3C6 +:10CCD00001BC731A151CFFBE19DE88AE903527B44F +:10CCE0007D1A6F9F665AD7A31B439F7F5CB34497FF +:10CCF000D61FAE6ED22C015D52FC407941EA08CAC3 +:10CD00008B7B65520F7843C995407F36F880F29946 +:10CD1000890E03E2CDE71C7F28A6C950EFB6B13ECD +:10CD20000D5973CD40CFF71C64F87F8F81F5D3DBAD +:10CD30009F17074511047C52679755FD6CB0F1367B +:10CD4000BCECB2B3F2AE038E6B802E37CC708C0588 +:10CD50003C31CA2408FDA5E79AFC23E8FACCAF1AB7 +:10CD6000C212ED345D2107F40EDADE426E0FD07987 +:10CD70006C3A6409EBE87BF3BC7FB711E01B7636B5 +:10CD8000EF5DAB7CBF033E90A853108E6657876D56 +:10CD90006C295B4398CECF01FFA0FCB16A58A70D68 +:10CDA000F6D35CD581F2DB5CD6D10170DA3455461E +:10CDB0007DC23157467C36E745DF184ADFEBE7C9CD +:10CDC00036E8CF4105BB8176F293DC8E4000FAA5B0 +:10CDD00030972B18AA40BFB8423A4E0687ABD3B95A +:10CDE000FB0E89F69301FD8D61ED014E760EA75283 +:10CDF000BB17F1D3C9FBCD184ADB8F61FDB455F4E5 +:10CE0000F523F671532D89C0FCC4B8A29FDEFE89BC +:10CE10005F02BEAAFF0D851BDD2729DF8493BB6758 +:10CE20001189180B013E81E6ED48D756F210D08BE0 +:10CE300033B71AF028FBD0E6E9F218F8CE82E3E81F +:10CE4000E79108E071B6424C5738407F09201CB585 +:10CE5000F49A75A0E37A4A23BDFBA2A5DF2C85B422 +:10CE6000EB1CFDE938CBE9AC2E1E33003D6BE82509 +:10CE7000EB50E2FB80F45ABADE9672BA0CE04292B2 +:10CE8000DBEBBEBEACD345DF980C9B9549E50405B2 +:10CE90007DBE663C42FE6184B24464EFF921C0F776 +:10CEA000ED8C7F102AAF28B1EE1A6B9B68053A5DB6 +:10CEB0004210BFAA9F5B77CB6F687F6787196C2092 +:10CEC00057F20E75F4807C245DC1E1B00F5B94E0F5 +:10CED000CF5268FD96239904F8F61A339909F8ADF4 +:10CEE000703CD7CA97164E375E90739E7FFE29F42A +:10CEF000C1E850F7281BA5BD96F5B14326D7FFA280 +:10CF00009E4586A19E957BA0A7C50AE377F8DB4DD9 +:10CF100014BEE6D759FB302D8715805F4301D0E161 +:10CF2000FEBCF90827E56D23013C1DADF347A04C7D +:10CF3000DE3113E0BF3B9FB9ADDE0BFCC73DC50B37 +:10CF40007CE8DF81DE29BC3A38DD6BD7AF18FC41C5 +:10CF5000D027B4EFD7027C713F03C7EBE83E8E7E4B +:10CF6000D840D6D2CA1279767B21D0C51ACA7F6939 +:10CF7000ED6C9DB7E94752DFFE3C61AE8AD8C1EE49 +:10CF800058692241235DD73989042971E639DFAC1C +:10CF900002FE934F6212C8D9FC66AAF0025E2DB35E +:10CFA000906012BEE79E53B0FD13667FC4CEF9BFFA +:10CFB00089F2013DFB2779C21120754EC6A3407F3F +:10CFC000D13F69790FF80671D6F87BED8D22C05FED +:10CFD0002AF7E9784FF1F5EB290CF563E97F56392B +:10CFE000661CD3BFFD2F397C14933506FC52B1BEAD +:10CFF0007604F98B4D3999DCCE1461F2863490C8F1 +:10D000003089C105CBDFB3613987F25FE358D4FBC8 +:10D01000C34698671AB33F88DFEF75BA815E08028E +:10D0200039D744DA4DB41D623BA5B72CD26346BD57 +:10D03000F900F1023D5088D93F4841964500AE5B6A +:10D04000A8884EA603F12CB2B17D5296EBD05E1AA1 +:10D05000F59219E7A36F261133E84330370A6F655D +:10D06000198928606F2D3760BB229B17BF339066EC +:10D07000D4679FFAF2DD6CE0D39683541FBB08F6A9 +:10D0800059463E65B1A8E98F62287E17E7F8B17569 +:10D09000A50DF7B9D73E0B1EE6FB1C6F017991BFBA +:10D0A000CCA1DA5FD12EF75C0E098E4BEE3782FDF4 +:10D0B000E50E3D209152A8CFC7FAAD2BBD5FD37FBF +:10D0C000D120FD67211E0DDE7F2ED66F8D1DB65F30 +:10D0D0004741B12571C01EF0F6E9D75A38E72E5303 +:10D0E000F3E58BBAD4650117B3DEEF9C46616EFEA3 +:10D0F000BEECDB4EFBBBF888BA5D6DE1EFD1BEED57 +:10D100006B1F735E0FEDA9FDBD9DBEBDF4B8BA7D6A +:10D11000A0EA653BD0715F7B36BF2BCFA9DB69F7F7 +:10D12000473B5F3A2FD70D49F39A6832AAEA67D690 +:10D13000F59B97EBA6A4795DE551B70FB60C3CAF14 +:10D140006B4A8C5F392FD1EE3B9517D64EBB8EEBD9 +:10D150006B8D83C09DB5BF69E685F57B6BFD57B7C9 +:10D16000BB7DB9769C30F2875AC93FCE41EB67C38D +:10D170002BD017AD16D47BB5F812E1F26902E87333 +:10D18000F43935D53FC1419F954077F46978FC0F5C +:10D19000B7007F39F4F4C84CE0EB3920E7109ECC9F +:10D1A000AFB0ABC1837E8500A7532A4FDA805FEC16 +:10D1B000DA49BF4B63F34AD69F321A985D6123095F +:10D1C000A467A12F39884D62F638D377061B47DB59 +:10D1D000FFDDDC1E98B37C22799FD2E1B3065B951C +:10D1E00002F6D93609F58139357E5D2AC58F09EDFC +:10D1F00012FA8DE6DCF9BD71C0572E39E6ED8AD3FF +:10D20000F77322761F0CDBD443FC118A5799BA2599 +:10D210006577D3E703FBA9FEC3CB4B00DFAC7E2FC2 +:10D22000D81B753023DACF497D73990DF8E677ADB9 +:10D230007EE09B7533FC6FE17AFF4EB512DA6E1E0D +:10D240005B3A79AE739AC14BF58CBADBBC95A0F70B +:10D25000D445CD7E7C9A8862A1EBA8A3FA183C3312 +:10D260000D4431C3D3424CF0AC58C5F4AFB4CA80BE +:10D27000A18E8E5FD7FDD85FE1BB054A6C1FD32717 +:10D2800023B8EEBAEE57FF06FADA3C7FC000FC6224 +:10D29000D44E03D349393E8C8EAACBC00F92CB65B6 +:10D2A000317579DC2175F92D07C38B3D526414EC7F +:10D2B000CF1E2AE0C02E0E3F654479B17FAF11F733 +:10D2C00067F1C796EDE07F9AB8D88A7CFDE39F9B13 +:10D2D000D11FB5478E3E0DE5F0D3296857EF7B7B14 +:10D2E0004F8544CB8B7E912A43FD0B5FEA10CEB075 +:10D2F0001C3D7DBFF8E911DBD7D2F78BC7452B6CFE +:10D30000F4FDB32309E9817A253206D6F7EC3F74A0 +:10D31000D87FE27163E4218A0F1F3FFFD8D377D112 +:10D32000F13F7E3CC721D17DB914E4016D37E16145 +:10D330009305EC8C091F3F3904F8C5E29D46D5BA28 +:10D34000B63A24AE3778D300DF06F3271E5DF31814 +:10D350007E5F72FC08E2DB1E7D58B6C0FAD730FC57 +:10D36000D2B67FC4C1E48D98077C5748F7E7CC0953 +:10D37000CBED7E5A1EBE510DDF111175F949079391 +:10D38000EFB349D2FB42E8AF68B507F4D4ED04F53A +:10D390009992E37FBCA510F46823D31FB4F3788679 +:10D3A000CFE3E73FA7FD30FEA063FA335D31A5C7A9 +:10D3B000C51C8F5F9098FE4AFF96E550BC5D0C82BD +:10D3C000BFA8EFFD62CD3C44FF4B1C8C6F38B95DAC +:10D3D0009D785D87FBF1D1CAFA71C786F59FCF07AB +:10D3E0002B9B47D4E8FBCAF3372E399845BF6BD83F +:10D3F000E5423B51BC6F78FC25F7ADF4FDC99D8A31 +:10D400000F54D7869B1FFDF10468F7B82E0AF385E9 +:10D410007AF0479E8CBE9C06EDE66FB18FD525ED68 +:10D42000C3828DDF1F5193C40FBF293D08FA6DE001 +:10D43000F6ED73953D937300BF374A3E68B6387A70 +:10D44000C3F5D782AEB245E71B46EB2B1412D08D45 +:10D4500045D37B063C1B763D73309BD687F68EAF5B +:10D460008075AD9503D78C06FCDFA6473F96162E38 +:10D47000A7F97ED3EF6332FD7EED8DD6FA8815FBDA +:10D480003D00E5FD250FE9E2E067394EF9137B7FAA +:10D4900044A63479BCFB9E31E04FDCA3B7B6039EB3 +:10D4A000EF4965FB107E4A877C9EC4D83A2670BF40 +:10D4B000F1E23F751A14FA3C7E7C555A15A323E419 +:10D4C0002FC0949D747DF50F8F46BA5BB0514D27E8 +:10D4D000A29D98EFC288BA5E8B1F6919C2DF404ACD +:10D4E00092F14CDB2E636AD80074D5B09CF2E32431 +:10D4F000FDA7E1588701F426ED38A00112B1AF3A3B +:10D50000C44FE2C5F59AD97AA9CA6AA2EBFD08FE12 +:10D51000C5FCDE12D8E58B245C22593C92D47829D4 +:10D520003C174F27B5F0DC23C57EACE3FC0CFDEFC8 +:10D530004FA5203F3B698B3FFA53C0BF27F37C6167 +:10D540005A95CDFD7227BDB134077D9E01BA00FC0E +:10D55000B3B1F2A26ECACF297D7F7CCA807CBD2583 +:10D56000FA521AECD7C9A7CDB24CF7E5E35D19D54D +:10D57000E0CF3919FD4D1AACEBA3684635F8E50646 +:10D58000E3375A3E25E4F97BF0CF4B287FCEF08F6E +:10D59000C900F8B66580324E32339ACB9A07A07F25 +:10D5A000F19DD3D05CE605BEF15DAB0FE8F3D20C84 +:10D5B0002FBEAF93587FF0E7A7F59F1ECA7808F6F5 +:10D5C000FFD0BEE27490F39F126F3AF0DF29AEC035 +:10D5D0001519948F78AA7BFC3AF0FF4D21BE56FABC +:10D5E000CDFB3ADF0F6C14CE7309953BF02C0F1A6C +:10D5F000D05FD2E6C279CD51484CA1783A07E4E237 +:10D60000182C239CE76C9122AD741E73D7A9D739CF +:10D61000BFD3D8B7BFF4BF8584324620A02D49EDD3 +:10D6200068FF0B41FE51F82D3291580AED77D12356 +:10D63000EAEF169318CEA7E1C9F3C681E0F8570EBA +:10D64000C7292EFF4D192AFEA547FEB59804AE80C6 +:10D65000711773393BCFB80FE711BAF3CE1173A925 +:10D66000DE7066F95D23E666801F907D47364A8846 +:10D670007F8B6B482C8FCE6B71B7141B0D7AC061FA +:10D68000B63FA27FB28DB5BB85EB29F3283C40EEB7 +:10D690004F78520AA7523B669E899A60C03FF8BAFB +:10D6A000A03E9D96EB4907AEA791C4711EDFE3FB38 +:10D6B00007112980E75F0FB37D9B50BF5D07933A49 +:10D6C000B4AF221DF0EF33E2C3FDA3FA04313BFAFD +:10D6D000E307C0DB9F049FFA2DEA327924A95C049A +:10D6E000F0A4E5243837ED3E6FF40F00DF077AE54C +:10D6F0004964C4B4D1A49FBEFA2E87FF0337CCCFB0 +:10D7000002FABF1FF4B76CDE4125F04B22FC113149 +:10D7100013EDDF328EA8FC13542FC272C74F5EB9CF +:10D720007A632E211BF441F4F3CFD1050E4248EA6F +:10D73000842BD809F83A47F6E72BC807FCC568A739 +:10D740002E67FBF1E0D8E611CD03D8A762FE1BA43B +:10D75000684C067EF03C93EFA9E5097D3089BE9EBA +:10D76000E6FC2D7D7FFC600EE0CD3312FAD3374905 +:10D77000A44DA270F6D06D0139B0497AEF20C88D62 +:10D780004D577B492BAD2FDF3D6DC9CB68E35A7CEC +:10D79000109F68DC5DA56BB4E2FA999E99D2BC5DDE +:10D7A000A6F599B7978C05FAA0EBBE7D3A7DFF2BC5 +:10D7B000BEDF5956860F9E55E1C2A5E04FDD1F58CA +:10D7C000F232D0F5680BFAAD3229AC521DF86C0775 +:10D7D000FDD1435A2468F7401AEBDF25EB6E9F0614 +:10D7E000E5B1ACEC5821F91F42245E8FFD671AA900 +:10D7F000C9E060EF410FA6DDF977617D04F72D7375 +:10D80000627319F49739843D9D86582EF4F39AD8A3 +:10D81000EFEE2C19F8ED322E3797EDAACA74D0EF3F +:10D820005F3B6952800FBEE6117A5CCC0A7A1C1904 +:10D830005AC2DA73F9B4AC6C6226E0AF335FDDEE46 +:10D840008CDE9F3E0EF8FC1B3A8CB7FCC5EA4FB746 +:10D85000D376971AD83AB4FBF8A70CA6D785CE4949 +:10D86000249264B787669E45FD38744E51BD3FB91A +:10D87000D2442249767B43FDFEC9D0AE91F4AC067A +:10D88000BC6A8CA69048129E5F6A19785C81DFA101 +:10D89000733A121E87E89B0BFEC5D7F489D5F300B7 +:10D8A0009FF64AE8070A517B389C3CAF7319249CC9 +:10D8B00031D03CDDEAF7743DAA72D7E7D88E54C662 +:10D8C000D3609CD3B6789A9DAF0FDA09B97526223A +:10D8D00087F517617C8FC92FF0CF58997E3A0DF6E6 +:10D8E0005749A44D4FEDEB57D4437F8EA4759E9EB0 +:10D8F000692031DC97048E0B700B0F276473F727B8 +:10D90000062FC8F1EE7D0837812FC9F00B27C77BA2 +:10D910005A7B6232A5F9CC4ECBDAD21114F5F673EC +:10D92000FA0E5BD7827FD1AD9355F49E52DE4BFF4A +:10D93000C86E1E80E813FA2F53D7429CB9B7CCDBD0 +:10D94000F77E1F4E9B02F5E5A5ECFBC2CEF4FF5817 +:10D950000532887430BD5F49E4075293CA264DD919 +:10D960004ACBA393CA364DBD5353EFD1947359FBA1 +:10D9700093A9B17C9D8FDAB99D195314CA7F4E6665 +:10D98000C566514B94ACD3B9A7D4D072633993AB6D +:10D990004DDD920F7D6E1C7E4D3EA6EF597D71C30D +:10D9A0009C528043CF41E00F0D5D924DA274608D7B +:10D9B000EE8A6119BEF3267D1795F0BB86E87BF8E9 +:10D9C000DDA0FD97C848E76B4B8EB276D10F517E34 +:10D9D000AF6EABC3B8B888FBEA48C09F23F5C57DDE +:10D9E000059F3C9DE57F4966786D4BB68342D06FBD +:10D9F00092BF45B47F6774F7EF413D4859F6490B34 +:10DA0000E8A17F6AFC703CE865EF7079B0418A8CD0 +:10DA100080713793E0089077DF6D1CB64FA6EDDE7E +:10DA2000D5C7B7426C6B71E7A8290A6DF76E6A3CDF +:10DA30004FA23CA6D15981F07CD715DF0AF07CC9F2 +:10DA400079312BE7C5F3645A5ED259C7DA0F8B6F71 +:10DA500085F226E7B5AC3C3A9EA7B38189731DC217 +:10DA60007F876D607A9EED647C44CCAFABC8FF5D70 +:10DA700027ACA781C991AD546F34517E396BD14722 +:10DA80004FEDA07098F5C314E4633B4E5E3F85E90B +:10DA9000D5E18052017E53F687720EF9B5827A463F +:10DAA00016C83647DF7EA4E6F778510E8C6CDE058B +:10DAB000FA42E6AC529403A519FE0330AE78CECB01 +:10DAC000A64F0ACF034E1BE3CB3A19E3C89977A5BB +:10DAD000A25E75BF99AD87D20DEEAF95EFC71D4E13 +:10DAE00026B7EE7032BBED868C49D8CFDB927F93A0 +:10DAF00089C2FD6D3D099B81CF2EB4A01E7CEB76C3 +:10DB0000CA3728DFEEE4F3EE5C9F158138F8AD12DA +:10DB100009005F11FCA3D3EECF7224D9139D65B425 +:10DB20006CEDB31F3BA7F9B32C4E78BA6588970804 +:10DB3000BED459C8BE13F228B3958D9379FF888758 +:10DB4000601D290AF3FBCC9B59FC500BCAF5E9B8C0 +:10DB50007EE2F76781FFE0D8C22219FC41627FDED6 +:10DB60002AF2AF87F5DCC2FDE9629FC47E1E7032E7 +:10DB70007B788E8EEA0574BDFB5C415C3FD513C695 +:10DB800070BF13EA0907404627C19728F1F1F0FE5C +:10DB9000FF23383DFB6DC0A97139E517F205F00B85 +:10DBA0000EBF0D524C9FC9F805DAC1F01EE4CEA697 +:10DBB0008CE07F3893F25266DDD5887AA19857CAF7 +:10DBC0001DCFD5DE44FAD399566F3B0CFBE5EAD363 +:10DBD0002F7DC27FC8C779F76D13C60BDE35449120 +:10DBE0006FBE4BED9816E02F3CDE5DF1C3C5AF81F3 +:10DBF0001D27FA9DE0D2617F6B247F16AC6F0DDD8F +:10DC00007713CC7F9A01F57821573BED914D906FBA +:10DC1000D079432EE61B9C212CAF23BC3C05DB5D59 +:10DC20002A1F25E08F4C5C62C37833C513ACEFBC70 +:10DC3000B918F33E283E84CD504FF109F2E33ACBB8 +:10DC4000E882A0BF9B47623DD8B9689FDE6CC2FEE8 +:10DC500006C013E6DF1DCEF21A3A0B391E2E2C42F7 +:10DC60003C74B7323F2251FC63A625C979B78BF1CA +:10DC70008194F2F833FF0538BFCE8C7A29C8588CCE +:10DC8000C57464627F74FFCF3B597C0BF16CEE8FDF +:10DC900053791E99AF02E07A6F2AC3CB2D661627FF +:10DCA000DA42F560E48B1C7F45FE5A90EB79F17AFD +:10DCB000390DF4855457AF9FC00F763BFAA969FD23 +:10DCC000ECB8F41ED85DB3C3BA9811ECA8F649FEBF +:10DCD00078921D027F1067BB9DF355B291A0FFEEB5 +:10DCE00076F82E0DFAB7A4415CF176F81EFCA42B51 +:10DCF00026A9E2670530E6F8BEF969F97E819857F2 +:10DD0000C783FEE47144FFDAFEA81DE975B910CEA1 +:10DD1000B174B0075A74B88FDA79C637327F737C22 +:10DD20006301E29DE86FB079FE5997F8BE44E5E0E3 +:10DD3000FC89CCBE16F6CB3C6EFF92156AFB0CFC40 +:10DD400023BD655DFFB2D6DE83B8B8BA3DD35B5262 +:10DD50004A13068C977825D5FC05BC0683C3E46F6F +:10DD6000083721F71E34537EEA00335A42BCDD786F +:10DD7000670ACA31A7213202F06A9ACB8BFD6E8600 +:10DD8000FC1494ABCCEEFDEC35E1AF50DBBB214B8A +:10DD9000621BC02B646174747A6F2AD201191A9FB6 +:10DDA00005F95D67F61809E06F93142F06BA3E2D4A +:10DDB000F9EBB05D4B8A17E8E97DB907E11D020870 +:10DDC000D27985C2FF837945A12EB5FD7B9AFE5796 +:10DDD0004FF1FDB41CAF807E043F00FA47BDA89E02 +:10DDE000C55B9A641206BBEA5279F64294FF376724 +:10DDF0009387F0FD7BC56047093E4FDB1D901C0CEF +:10DE00006D805E1A38FC9AE4A3D8AE01F283008ECE +:10DE1000605F815F0B2A93FCB14DEB3EC6FCA4A66C +:10DE2000DDEA7D6EE8C303E9BC04DF25E105D271BC +:10DE300098F301C2FC14352C5E9CCACB29B53D98E1 +:10DE4000AF14E27E0BD7FEF864E027A9E551329BC0 +:10DE50003E43C7999E31A17BFB4B600FDB6B7BF28E +:10DE600000FD43DCAF27F659CCF392EEF5E8A7109E +:10DE7000FA49929D3962BACA5FB00ABF03BB15C6A0 +:10DE80008BC3AB2CD87E26D73670B946E51FF2D7A8 +:10DE9000791DC351FE817C02BE24EC5EE053C01F9D +:10DEA0004EB8AAB7009DB6B8AB1F74B9D878A8CF42 +:10DEB00083B174C9E0FE38011FD10EECDFAFF2B7B9 +:10DEC0003DC6F1D569E07C9730FFDAD2575DC2BF1D +:10DED0008671B4A5923713F0F5035D10FD680B4809 +:10DEE00018FD3B0BC17F459F0D9CCEE773BFD07CD7 +:10DEF000EE0F02FF6C72BC0FFCA4C9E54584E12F54 +:10DF0000D969ECCB8301FF4D0D89A5D2FE1AC1BFA3 +:10DF100004CFA8FABB26926078DF75DEA88A277640 +:10DF2000B275DFCEF7DF5E13D1017FD864667E2540 +:10DF3000C13726AC60FEA7F4B1FEC27B00CF5FD52F +:10DF4000A35FE2BFF9BE09384D71556F77D1F61660 +:10DF5000B0D3A0DD3D46E497C7A81CDEC5FD21D3A4 +:10DF6000C1FE5C191C0179DC44B1E527DBA7E2B9ED +:10DF7000768FB91EF0E74D97ACC2AFD52E9677835A +:10DF80007E22E4C729A86F53B63106F0ABA248C879 +:10DF9000433206FC53EFE9993FB7E9466B10FA8B21 +:10DFA000CB8CCFFC99F3B33FBB58DEE59F7BE515E7 +:10DFB000B7EF38FE88381DF86B92FDE41FF4B65FAA +:10DFC000CFF36309AE77C3429E87DD8BC732F2A3DE +:10DFD00094D200F2DD4BE56AE4478913562FC0A5C1 +:10DFE000F6E38685B08E4F675A08C4CBE672BFED64 +:10DFF0005948B873F5F969BF2E8E55BB7604F249BE +:10E00000D1FE6F3027577F7FEF1ECEC7F61036DF69 +:10E01000709B91F9D7F9FCF71C1F19013CA67A6D8A +:10E0200018F85C629799C93BAA87027FDDB37B78B9 +:10E0300004D6F39E9EE90B61CA7FD9F7C14DE00774 +:10E04000D9F34B970FF273428B3E1A03FAE39EE328 +:10E050003FFFD56FE1FD5EA30FECBD3DDCBFDE6091 +:10E060008815A3BECCF3121BD262C5E0F77981EF0D +:10E07000578385964B4179083ADCAEBE38187C0749 +:10E08000EF8F46985E7E94303C08AF63F14A0ADF1A +:10E090002C9847624D26C6D1605DB00FEFEF1D8D05 +:10E0A000F3DEA0E7EDEF63FADB515E3EFA7C19E6A2 +:10E0B000E99D091830AF36743FD317E7C8DE6DCB42 +:10E0C0008157BE9882FEC2799D6F605C23F4E305A0 +:10E0D00053A13EB468C575E42BFCFD205792FDD4D6 +:10E0E000A749221FEDE0FAA2688C8E7BBA7B848F51 +:10E0F00085ED3C18246AE2F99BC7287C61DE89BD66 +:10E100007A84FF85F60FEB05BB14E41BFAB593E3A5 +:10E110002A280FD47196AF2B9FD6C78BEFA4E3AFFD +:10E1200070046BDC497A62E8C52CE477EFDFF7799D +:10E130003EEA131D2C2E704CEF9F057462AF8919B7 +:10E140006627E95FB7B9B9DD61E47A23E583C9746D +:10E150002FEA2BAAD574269EB7BA19BDA5F2387E30 +:10E16000FF7A91BF7ABD11E427732941BF5EECB7F6 +:10E1700080C7D7261C4FEC837CA8866819C6EF0A97 +:10E1800056C4902E29BC63A0FF1FDB94CAF8095D1A +:10E1900026F433BF92A0DE3A5FC7F212E61BA91E37 +:10E1A000CCE438B6FF605326C2A16215D3FF12CF6C +:10E1B00048C817459CB18EB0EF9F6B7B2FACA3ED89 +:10E1C000EB764A6594B592BAB62ACC5B58B4A510E2 +:10E1D000F77F02E7BF738CFEE24D806FCFA522BEB2 +:10E1E000D1F150DF6E80DCACB1C8970C200FEB771B +:10E1F0004A642D498E8B6AF020A28EAB4C8832FE89 +:10E200000D728324E969420E81BC201AFD518D17DD +:10E210006195DC6BE77015FC1F21F6157290EAD151 +:10E220006B808E2BAA19BD25764908E746D2CCE231 +:10E23000405C0EF5CE87CBB10F744C6ECE37AEC7B7 +:10E24000E73677218EBB08E225E8FF4F18802F0EB6 +:10E250008617DB06C10B810F3FE3EB68384E6297F0 +:10E26000D3F11A569058E318F64C1D837299C9677A +:10E270001393CFF0B45C809CD6CA67AD3CD6CAE19C +:10E280004C0393B7020F92FDF2A08F4C5811D1317D +:10E29000FF6BAE0DF2F1C4BEDC90E17F227B7C9F70 +:10E2A000BE153A6232792F8272801459C1AF54552B +:10E2B000914BD71FA2FC1BE82E85C2693B7DBF9501 +:10E2C000EBE54372BD081F0FCFBBD12B0152668512 +:10E2D0007DEA413B3AE12268D70AF86E4DA5DF8D11 +:10E2E00085EF183DF67E6F226D96A4EFABF798513F +:10E2F0009E9C7D3E15F344A87C28B0D3FEDCEF50F5 +:10E30000FD9C964FEF4945F97E9AF37BA7F0579015 +:10E31000D5D8DF9BB0CF2EC0BAEA1CF0FB12694AF9 +:10E320000EB048A13736DA07F3D3F3FAC29E1B19B1 +:10E330009E1951CE9EB5C77F00653A1FCCEBFD0FED +:10E34000BEEFA1DD13CBEE82787EC0EA63500D965E +:10E3500081DE60D42DBB11FC4193752B1277D275F1 +:10E3600034E659315FB8A6E08F7FB899964FECD666 +:10E370001323ECFB8EEBD363F099E2F70C249F1789 +:10E3800046F4AAF3688B77AACB8D5175394492CEA7 +:10E39000AB51102CFF63D9150792F0E43377AA1321 +:10E3A000F7DF4B7C90EF4C74B7A50707E097E2F9D5 +:10E3B000F94ADF1507F4982FF6851BE9C06B00BDFD +:10E3C0006636E0C300DFED7233BFA8D1D87C1CF203 +:10E3D000CE8D2F187D2DF4AB83EEA02ED305F64AFB +:10E3E000E220ECA7B1E0E4189083D5057FC738D8C8 +:10E3F000D9BB890FE073D65C85FACDD94D662FD88D +:10E40000659DF956E6AF78518A484C7F9F3ABE0227 +:10E41000E29EB80612DA78F5097648829864DC5FE5 +:10E420006ABD7880CFF8D19EFA609AC5B68A7E57C9 +:10E43000BF91C9DB06D293067CA03693E15D48F715 +:10E44000A4C144FF59D8E61FD142E7BB3860C1F3ED +:10E4500031CA974A00F0EB5EE83249FF2FC8647278 +:10E46000A6D1143754C1F87F9F5BEB2AEAF36F19EA +:10E47000F4CCBFA57495C572E8A70B96CF413BA716 +:10E48000378EBC89E5252DB8B30EDFBFB4C988EB44 +:10E49000FB60AF8478FEC156B6FE051BCD5EC89FFB +:10E4A000BED2CEECD905F4BB81D77FD50958D7872A +:10E4B0005BEEF0817FFE43C2C609DB981FEA431B77 +:10E4C0008B77435BE8E7C3DD43508FA9DFB8702A41 +:10E4D000E68B6DD5F9408F207B53D1BFB360EBF74E +:10E4E0007F7B09F88FA6DF520E70B8D2BECC0DFE2E +:10E4F00012DA2E10617A31CBC375543E0A7478E576 +:10E5000097137BAE047D692BA5934296E70E7AFAAA +:10E5100081AD57A15EBA609AC50EEBF26ED9311982 +:10E52000E4C787D3B2655CCF5312B1011CECCBDDDD +:10E53000F07E81A40406C2A777DDCCCF565560F5E6 +:10E54000C5E0BBDFEB104F285DDD08F2B371AB1EF9 +:10E55000F5DE03D3DFFEC3CDCE3EBA5AA0EBB871D1 +:10E560004292DE13DA72ADC01312AB007B8AC14453 +:10E570004B5FC68215C5301F2D9D2D58D55CCCE252 +:10E5800055DF8CDEC8164A6FA3A8BCCE94985FE313 +:10E59000C2E9AD3EF31BD01BC975A8ECA8FE7C2DCB +:10E5A0008C7014FE7E938FF8775831AEEB9728DF8E +:10E5B0005D9FA9603FEB33D9B920E56F4B77BE4E25 +:10E5C000E1E3CE0CFE3013F41FE22F033CF2266C85 +:10E5D000D570E6C7CAF538B285E9CDA0DFC37E6F36 +:10E5E000709147D726F91DEECB64F611A5FF56E8CA +:10E5F000E7F45B7F3F08FBD3947F720C8B77FE05BB +:10E60000E383D66E1657B6FA121837D73B03887FC6 +:10E6100082AF877C4CEE68D7753893D97321670237 +:10E62000FBF98587D1A1F0B76F5E6E413FE9666760 +:10E63000C4CCFC0A610272696AA58EC5C5B89E7514 +:10E640002DF73F9ACA5F22100F2397B1FCADD7CBAD +:10E650005F523268F9B795937C786EAEFCE1F62292 +:10E6600058F7657A5E3F240CEBFE4F7F15D62FF5E9 +:10E67000E8BC40D753CB591E22A94F437FC9EBE5D5 +:10E68000EF3BE726CD3F404C5E2BC593E9D4C8490C +:10E69000CE9BBBEE32B3D79A845F9F7648B54CDFF2 +:10E6A000F5A6CF18CDFC212887CBD5F058EA31E06C +:10E6B000B82DEEAAA701CE575EC1F6E3A3A78C1131 +:10E6C000E07F1FF173285AF8EDCDE476E86D25AAB6 +:10E6D000F8BCD310CD07F9F8B1A4FE6E51BB0EE320 +:10E6E000E30BDB2512A1E37DF4F873F9C0C74FEC0F +:10E6F000782E7F76D27CB4DF89E72B991C5FB91F17 +:10E7000050EBD71DCC9F2BDA9DD94882A6217DEDF9 +:10E71000CFD47F81FEDCD9DDDC1FECF70F75821DC5 +:10E72000C4DB6BFB4B70FC90BA24F477087FE6D116 +:10E73000430F43E4A477FFCCDD857272DEA1784EEF +:10E74000E0FB763DEC1B5D8AB99D9507DBAFC1E828 +:10E75000711DC89FF17DFB76B47D483AC0D1D0646D +:10E7600055083B0F56027AFA5662F1013D19B23D47 +:10E7700056E05FCB4D6963E09CCFE766F6745AE8DC +:10E7800093EA6B79D925F8DD1D7200F3DB3E973BE8 +:10E79000F03CE01DBA66CC9BFE8CCBBB5C5B60D7CB +:10E7A0007CB44FA298474DDAD5F075B732F991A8ED +:10E7B00033A09C1270BE74F60FD04E1D607F3602DF +:10E7C000DE6457B277A59E42AE2FC7314E60AE24AD +:10E7D00036B0E75B2F09E37CC4FE84587322754B87 +:10E7E000A827437E4A8A03E3A161FE245607E98DE8 +:10E7F0000FA470BB9668E201946D85A19D9827B027 +:10E8000031C873B9DF1EED282EC7782AEA9FD02FB2 +:10E81000BC9F5DAAA03F1DDA19C67E3DBEF5E2256C +:10E82000CF179C2ADED75B068C3F4C857337B47DAF +:10E830001E9583A0FF119F5E75EE660BD59BC11ED2 +:10E8400013F15D9D1C2DF3A01DD21307FF88A1C2FB +:10E85000E405B99AA28B96C0BE69E3BDB45D21CB35 +:10E8600033C8B5835C11E76A9A964F0C40DE7AAFE5 +:10E870009EB197D9474D7756E1FB89DDCC7F1E6A63 +:10E8800037E2B9C0509784F1AAA6802162423F8640 +:10E89000B705F62B4CF530B01B3BED2CCFA9F36A36 +:10E8A0009B2F4C92FDD7F16D77A1FFDA8A71BA7F69 +:10E8B000367E79269502E0A2A4F854BA89C911EEF1 +:10E8C000DF76737C12FB2FE859C43B534B0385A0C2 +:10E8D00071EF76DFFE1BCBF86F901742C6DEF7951F +:10E8E000792164EFB570AECD04DA3CAF876951B9D8 +:10E8F000D97B4ECEECC5B8566F3DDC6F60EA92F81E +:10E90000F78BAE9DA4601E282F57AE83BCEEFBCDC7 +:10E9100044355EF2FC144DFF7ADABFD5CBDB876F4E +:10E92000BE66D2508CEFF272D78FFC747EF7EBD5B7 +:10E93000FD210A8A737DA6BEF12A72E4FBD65DD65C +:10E9400027BFA93C5FE671F5C9F17BDF9EDA7191C3 +:10E9500017E8EB33CCAB15F238E46479225ABEB534 +:10E96000D22309FD773288D8D533EBF03E80DEF82C +:10E970006EF7343FDC8B20E2BBA11501CCAF05F96B +:10E98000EF41F97FF2837D04F4CB8F50FF0F9D534D +:10E99000983F88EA1112C543537715FA3D216D144B +:10E9A000E4A6D8FF455C2E81AE0EF81DDA72D30EB8 +:10E9B0001DAD7FC7E35F87FD723B503BDF1D1E66C9 +:10E9C000BF874AAA37013F208F4804E4F6DA924F06 +:10E9D00051CF687A7ED2F8E4FCF0855D0FB0FCE29E +:10E9E0009DFA01D7BFC3A363F931CF3F83FECC8F1C +:10E9F00022EC584ABD12593301FC2AF532685AA458 +:10EA00003C527733CAFF99741D745D3FE27227B49C +:10EA1000F3FA30E4AB87E87F00B2CD81F9A8EF6F5D +:10EA20009E69B242BC2654327B09D283CDE287F57F +:10EA30006BE7D91B1FBED382FEC6B55DFA5AD09BC9 +:10EA40002AA89EF42B3ADF3CC7945A1FE54B39BAEB +:10EA50005D65DFB3425C7D60395C9DCDF6B14D0AEA +:10EA600084BF538EF98C24394FA7A08BE963DD1E38 +:10EA700083EA5E886E0FD3132F0BF74C049C7B51F7 +:10EA800089A7805E1C22FE4FC0CE2501AB17FA81FC +:10EA90001B1540CF72AEF4A23FD7E48CFFE822D41E +:10EAA0009B14B433841D71FA79E6FF1A9E157C1508 +:10EAB000F0B24217FFC977006E3F62E77589C2F86E +:10EAC0004DFEF5D6B1E0AF323BE33FA9F5627E0DD6 +:10EAD000FA1FD22F6FC37D78D1496C009F89E13A2C +:10EAE000454A9233826F4CEC3D17E3443F693567EA +:10EAF0002FC3E86E7D6042146D3B9FD1A7171CFAAF +:10EB0000FB0C055E0A7D413605D19EA99949ED436E +:10EB1000C0CBD5898332F8E59D3DA82F3646251C0C +:10EB2000A7B1E49798FFB698E759F5E63B2971CC71 +:10EB3000FF7ADF93C2E3036D4C6F253D68FF922798 +:10EB400019FCA9DCC4BCB03EBDBD05DB89FE0C3C94 +:10EB50009ED0C8FD351450587FDA23E209AB78FF08 +:10EB6000228F8D8D4B146F45B27F61C3342A49705B +:10EB70005EDE3498EF13E6C0E7404747EB65E6CF2B +:10EB80006E4F89C021CF0D528F1FFC8EE1B281CF15 +:10EB9000B358B3181EA5EF4F4C467FFFF383E5BB78 +:10EBA000B2FCD64DE347627E7879D72793013F4880 +:10EBB0002D417AA4FCE282F25DED595E1CEF5BCF41 +:10EBC00077F549FE87E83327CBAECE77F531B88BA2 +:10EBD00038A436CFF574564C617969F16D3B407EAF +:10EBE000761931DF6D6AD72B47C00F39D544A2188B +:10EBF00097D5E8012F665C3F348BAEE3CCA90FB606 +:10EC0000DD4320DFF9591FCB9F53CBF5C1F4788C3E +:10EC10004D24D97B157C1FBE2D3D5EF0DD10B78BDA +:10EC20003E96123F2E86F5EDD5D9063AA732314BE6 +:10EC3000E0DF20F91ADD03E76B887350B5F1425528 +:10EC40009CE95AB19E6F18B70A802F7980B895C297 +:10EC5000F3B01489B100926750C5AD147BF16071B7 +:10EC6000AB18D63F331CEBEFED17B762F9016D7BA4 +:10EC700033BDA0A737B8128F3EEA85FE0CD84FDB14 +:10EC8000F32911C83B6FE3F06FB8F0B8D5C2AC01FF +:10EC9000E256DBB91EF67E891C3350B86E276CFE37 +:10ECA000E16E11BF92D11E4DDC9727E68FF567EE1E +:10ECB0001B857E9F39222EF522F387CDE1F1A7F740 +:10ECC000A71763BED660709ED3AEF6EFDFC5E17CBA +:10ECD000D65C857EF51FFCFB34F433CD077FFC90BA +:10ECE000BE730984FBE5BCEDECBCB977A714F1B2A7 +:10ECF000F88849461DCF26C3FBC5941D6E06161A1B +:10ED0000A65873317D2D51A8D17A6F1B2D53E55D27 +:10ED100059A3843DB4DDF62329E807BBD7E9C5F93B +:10ED2000DEDBC6E2C4E175526418EB17EFF10AB7F7 +:10ED3000C97EE8E7A7594C5EFF2A8BF921BC9AFBF4 +:10ED400001DAF43CDECBC76B21720C9EB2C49EF795 +:10ED5000DA94DA81F400D15F9BBED95405F0CE631A +:10ED6000F7859C35F867A29FD8518CF702B5A53678 +:10ED7000B7D7B27AA4D9B3E64400EB2F57986249CB +:10ED8000BC0E98EFFA2CA6A768E13CAF435DD6C64F +:10ED900069B4E7A0E690E0F0AC21FDCF09ADCF6209 +:10EDA00072ECECDA42BE2F3E8C7BB4E9BD6F1602EA +:10EDB000BEAF61F7FEB4E432B8C979EC5964AFC1B3 +:10EDC000FBD9889DEB6384CDBFE872A704F4D066BD +:10EDD0006778FBAFCE5B3BDF17B28A197CED8C5EA8 +:10EDE000DBD64811062F36EF0BF56FBC25F8D2B7EE +:10EDF000C417DF977C8FC60AF13BE40BE1FBF448B4 +:10EE00007747492487E53FDA906FCEE6F6EA512E40 +:10EE1000AF36D717A5413C73CEF1D5787FCFC4EB81 +:10EE2000AD38FFA617CD688F35AE88E7033E6BE19E +:10EE300008B355043F9521EF98B07B5FDAD5F139DF +:10EE40006DDC7585239000F9D2541D2F86F8CF0311 +:10EE5000F2FBBB5E617C0DE563D38AC4A3E02F0E99 +:10EE600038829F43BB9377BE3D59F2E2E7C8DFCEBD +:10EE7000EC1D8EE7FD66B7A9CF4F9175EAF81F69C3 +:10EE800077B073629DEAF7705E48F55DBF7820D376 +:10EE90004F36188223407FBCF20A96EF706AA14C6D +:10EEA000603F4F99098FB30B3EEB2B4E9603CEEC90 +:10EEB000C1E41D6D0770E6F99DA27D23EC2BDDCF2B +:10EEC00006BEAFA79EB9B818F6F5E4AE8B8B615FAE +:10EED00037E83BFC4017275C414F36C597639302E8 +:10EEE000A8DF897CD60BC5B7E183CEEB7F470E97B1 +:10EEF00067FF737218FE92FD1E2FFE9DE59D86BB77 +:10EF0000D979D13E7FDB4778EFD59973B2047C780D +:10EF1000B0FE5EF730BCF7984818FC1C15D571FCA4 +:10EF2000AEE20B99803E27F458EDFCAFE2F09B99DE +:10EF3000EDFF15E8A3C23F5BCFFB36453E63FAF217 +:10EF40002312FA5F4DDE70DA04B48FE68DD3215FB1 +:10EF5000F9159E6720DD920DEC8C858FB460FDE97C +:10EF6000AE39582F9B6231B0A71A693D94575FA6FE +:10EF7000CE4FD6EF2E8B25DBAF741EBF00BB24C552 +:10EF80009930007E36817E4CA7D8A4303F7593938C +:10EF9000A07FA4BC4B6DEF89F8EBE600BB5765730F +:10EFA000B784F72BB90DC1C25CD8574D1C765EB63D +:10EFB000BF0DF04EC4C3A7B8FC0BB259BC3C1FE058 +:10EFC000D494CDE617D78BF373EAF37D87F6DD880B +:10EFD0007AD05F49207DE0BCB1882A4E3E9F9FBF1A +:10EFE0009CCFCF5F027F8E69F87372B921296F2C95 +:10EFF0003650FC3F296F2CF9BBE4BCB1988AAF7541 +:10F00000F0F3094B313E1DA278BE7C6C1F1E3610FA +:10F01000FEB731F13E9E4FD96944BF5803CF170D5B +:10F02000D51F457B2304E75D183DB2BC6A7EEF40E7 +:10F0300003B5E3306F36AACE2BFD69F6B72B0F442C +:10F04000BBC1FCDD8F0A7EC0E951AC4BACA3A15B18 +:10F0500062F4A399A7D67ED5FAAD85FD79A17C6926 +:10F06000CFB7BCEE6FCA975EF996F8523FFFFFD05C +:10F07000449AEF5BF0FF9FF076B8C125D82E317C23 +:10F080009DACB3FA597C51C7F20FB47157EF648C41 +:10F09000270A7FABE9595D645521B6C7786AE3DE7C +:10F0A00054CC07A8F7D6A39EAD8D332E22BB26C322 +:10F0B00016FC95BC86E7AAFED5B8FEE9ECDEB87E64 +:10F0C000E1378CEBFF35FB1BC4195FB27E96114C08 +:10F0D000C293EA52AAB0970E9E77A5CB61FB9EC25F +:10F0E000F33F4C4A98D893BE1FECBB941C16677F25 +:10F0F00089E70BDD9F9A82E7E83D06768EC023B351 +:10F10000BCA677A8B69FE30239C0F6F167CFDF440B +:10F11000204FF067FA289E6B0F375A7D20BF84BFBF +:10F1200048F4DFCCFD98174A3F4539FFBB7CA33438 +:10F1300047FA6671B28D14064974A5A583C1BE1B3A +:10F140008CAF5C9E13A8CC41BEE51F83F1860BE417 +:10F150004729E5945F837CDE6DF482BD60E2E75D64 +:10F16000C8BA2C95BD3DE7FE3C945BA7CCCC7E1085 +:10F17000E772C4FA0383C2FB9FD3EFF6B902D3014F +:10F180004F8E55F931AFFFDE542657128FB3FC1E58 +:10F19000EDF914AD3C11E72BC47873C5FEFC1FF1EB +:10F1A000D325023EFF223FA5F215FD2B83C653FB5C +:10F1B0007D1F66F79154F7F8799C09CF2B887985E4 +:10F1C0007A585E5C0B9F5F2FBC38FF3F98E35F056A +:10F1D000FB70F22D9309E297E5E58C7F3605ACE8EC +:10F1E000FF6F8AB27C98A61504ED7C710ED59D192F +:10F1F0005C07F878EFDB56BC07B4A96B7B7B11E6A4 +:10F20000090451AF3BFD167B7FD01DEC80FE432BE4 +:10F21000E2AA3843C5F9CF56D796E37CD14E771A88 +:10F22000D5E77B7E99C3EC6FF1FC452F7CA95D424D +:10F23000BF3B59CFF2B0434EBFAD0AF303981F3B1B +:10F24000C5DB83FEE7A6DD282408268542FD5DB9DF +:10F2500088374DBBABCAF05C7FD45C86F7C1BC631A +:10F2600045FBEAE49DD9111DF37B3F06EB4A2D8F48 +:10F270005C0DFA65011D07FCD827775D5D86FE40B1 +:10F280000DDD097AEB3DD779AB29D22AF5D1E3061A +:10F290003D938F42AE3D08CA2CE647F0FCBEEE69B6 +:10F2A000649EB5AF6C75AAF31E67664F7A10E6F3DD +:10F2B000608EC2E3D32C1E5E68A2D667517F3C2CC1 +:10F2C000E4F1F0693C8F81844D7DF90B455F1F0FA0 +:10F2D00017F31365110F4F39C7F4DB229B01F1229D +:10F2E000B59DF10D42F102F4EBCB123D13E13CD59B +:10F2F000D0CED86500AF74003FE691C67F7411C4CC +:10F300001D3294CB20EEB06DF9D8FD2627F88F7A08 +:10F310002E87ADF176D8AAC1B47467060E039E108D +:10F32000A5B904F0BFFAF77A966FB82605E57D67B0 +:10F330007E03E61B9E7EDBA83A47A37D86C92A0F83 +:10F34000F8898ADA7F877EFFD4DDD28079A419A07C +:10F35000F48F67EDC1EF94DADE13AE043FCA7D127D +:10F36000BB4B91CE5EF280FDAFC8A077CCE962E7DF +:10F37000B1E774D8AB4DC84F251637B9CC897C524C +:10F3800059738D0CF699D242F0DE324B2EF35B0F9F +:10F39000EBB4C9B0EFBFFE5237603CEC6F1CBF212D +:10F3A0007F0DC0D5684C1C8490BD88E389BCB5C175 +:10F3B000EE0317F248ABC7F6D35FB93CEAD5E335A5 +:10F3C000783CD87702BF053EFF5A4F500FFBB5641B +:10F3D000C2735A02AFDB441EFE97CC8F5BC0F36250 +:10F3E0008EAEFD9F31EC3E3F110789B07B25F5F1D4 +:10F3F000D53908AFF8156158F76EBBDC548AFEAFFB +:10F4000026EC670DBB7FACA07DC8AACA7278DA086B +:10F4100080E0E89EC5054097618A07C306C0832344 +:10F42000392CFF48599382FBA6ACC79B968962771B +:10F43000E3BE290FB0FD793387AD47C461859FF2E4 +:10F44000604EB004F26B7BCF572DB7B0F355FCDCA8 +:10F450006EEAF2B79F82734BDBB8BF78FF8BA3F0E5 +:10F460007710CEAE5124F01B9DB5D71580BD372E39 +:10F4700097E94BA94A0FB15993F1733FE6BD16EDD9 +:10F4800065F97B0ABFCF4859E3DC0EF02CCD08624A +:10F490007EEFE56D31FC0981176DC730BE46F52260 +:10F4A0003CC7FCD1F392D08B54F250D86B5A3BEC52 +:10F4B000AADC6F572E7E9D9E343D572D072FD8BE58 +:10F4C000226A3BB3B7BDB01BB57684E6FBC1F41F1F +:10F4D000E20FABF25BE6E57A851E87F23D9BF346D1 +:10F4E00091F7D27B0E9944CC709E017209C4FD58ED +:10F4F00090FFB351B2F8404FD2E6FDF4E6E390E658 +:10F50000E12C1FA4F92276BF44F3C5F014794166BB +:10F51000C80B49CE3F4D65793D66C80BA1EF5B072F +:10F520003DB7EC6D81F13BEFB68973CBCCCF5E4B31 +:10F53000789CE1213CD79CB82117CFC94CAC65FE23 +:10F540003B47C020035E3EFB0F9D1FF86E82D22D0D +:10F55000E8578EA1FE2CD0B7CCB41EF24D7ACF2D39 +:10F56000D79101CF2D8BBC2411A7CD1EBE4102F92E +:10F57000D39B2F12EA3BCF0CE3762EF1A27FB83754 +:10F580007FE9BB04D7592DF88C49BD7F697ED62E03 +:10F590006DA601F50CB71C7C1CE3789B7BCC78BF77 +:10F5A000446E11EE5B6B6504EFB3759476A0FFB506 +:10F5B00025C3BF39D7D5873F627E64235BFF1938E7 +:10F5C000AF25F58D7B66E117F9A04F55771B191E06 +:10F5D0006AE6B1B9F7DE143A0E7DFE2297EDBF4F11 +:10F5E000A3DF8AE72F047D713E2CC61F6C9D021F8E +:10F5F000BF4E6FD7E257B89AEFCFBBE608CB3B526E +:10F60000E3D7FE95B5E38E515E726065009F67CCCF +:10F61000525407F941E6C42CE08077E6CDBF0EEEE8 +:10F62000D338939AC887FB385AF2A77E07EEDF38A3 +:10F63000E34ABC0BE5CEBC7F63E561896D703FC7D3 +:10F64000CFF3145686B1B2097965CBB9EBC2A57870 +:10F65000AFD5EA1E904FE59A3C13CD3D02900F893D +:10F66000F71E58D97E66F27C5452C3F577882CD1A8 +:10F67000726B56990FF208ACC4BBBB07EA738DECF2 +:10F68000BE01C2F29F5A8715B27C058EEF2497FB0C +:10F690009F493C0CF8DB5A68C7EF7BF9F56E238F66 +:10F6A0003BB1F1DF78869D131379B684D8F240EF31 +:10F6B000B17A89AA2CEEE1208A2D0FCEDDB70ABFE0 +:10F6C0001E2F1FB1044FE426E9456F4CBAA3147FE7 +:10F6D0008FE3D9BB86C27AAF32A8EF33EEE5A7F944 +:10F6E0008C1F9EE1F7FE7558829F423F4752664D40 +:10F6F00086AB5467665419ECA8A73DAE037EE4E2DE +:10F7000078619FC1E667AF0948F03B18E2DE3D57DC +:10F7100050417F000976EA407EBA8E05309FAFC126 +:10F7200094C857287E7D610CFE03E8E16CDD7B3FC9 +:10F73000C03860F61BEF42FEC51BFA8E8969202F88 +:10F740000AF97D0ED4F00B3B41DE15A0DDD77B4FCF +:10F75000E73009F9C3D419ECFCE9141255D0FF6263 +:10F7600063E7A1269717FA5AE9785379FEC6E4238E +:10F770008134F0034CBE29AEB0784B4249CE97108D +:10F780004FE2D17B93E9E06A6F5299C0FDBEEAF285 +:10F79000B53E75F93B955F0E4F2EA7533B206F3C4E +:10F7A000F0AD389E270E5F426C6C5D2C2FF0E7DCCD +:10F7B0006E1BE521A602C85B744A61B00B463D97FB +:10F7C0008D7194E72A0996DD3B4D0F9992D7BF5E64 +:10F7D00066715AEEE716BFE3037520579F7DCB8D08 +:10F7E000F0725B65E4A7E001077CABC8315980BFCC +:10F7F000EB389F17E7AF27A599F0FED5D625ECFE8D +:10F800007FEDFD93AD7ADB3ED8C7D613740D749CA3 +:10F8100047520D31390DF68B1083B38F1F0BFC81CE +:10F82000FEAE00BC1FCF7E678962F9D0E4FBBF5BF0 +:10F830005D6CAEAD772B3C3EC77EEFA1A4F7F71F02 +:10F8400028D9D1F6A05312A413161FCB13EB248A88 +:10F850001FDA67115166E7ACDCBC2CEEBD24A44A6C +:10F86000C1FB7224D1AE05CB0FF27652F72B7F038A +:10F87000FC189A46D7439F4BF2189F78587E632313 +:10F88000E28935E8053CF1A50C7CEEE7B63C46374D +:10F8900093D22A3D9037D09AE5F3805E25E023DEAF +:10F8A0008B7E45BD18CF973170BF4B78BF517E6EB0 +:10F8B000585BBF388FE96DBDE3EA69BFD6AF18D793 +:10F8C000A51EB7F7BBBC81BF13EF457BFC79A60A29 +:10F8D000A03306B7293C5F9594A8F35348A5CFC43D +:10F8E000F8BD3A1FE52A694516D0E7D5A6C6EE3819 +:10F8F000FDFE158E2757C9C1BF40BCE19559C5070C +:10F90000803E6BE18279DACF3524B61A90E54C550A +:10F91000F067F621C82FDAF2E83A9A74C1E10E5A7C +:10F920003EA5EF18BAA410E9EB9EBCF1FDE727F065 +:10F93000B0779E14FF60DF05FE69E72DF0805C174D +:10F94000C5C4BCAD24864F0F61F9D0547EB1BC67ED +:10F950006F5EDFBA28724E36350F05F9FE4A4B1836 +:10F96000F9CF55F69F60FED78305C1CD30AF99170B +:10F970007D82F7DD104F1DEA5B74BE3FFDBF9C2FFB +:10F98000A5AB2C782FF440A1EFF5CB033E6150E5F9 +:10F99000018BF969E958CC2344D83D4613BBB7A382 +:10F9A0007E179A61F5C1798D10E4B79663FC0BF36D +:10F9B00085F770BB2C2CB1BCDD7EFAE2E0F9C2EC1D +:10F9C0005C7FA38DDD6723EE45FA7E91B8EF86CD8F +:10F9D0009BF22F7EDF0D963BEBBC68FFF5EA8DF3C3 +:10F9E000981E7A65B1A50DEE0FEC7FEF0DF3EF9148 +:10F9F000E78C5EAE27A2FCEE4C65E39C32B3FCF4D0 +:10FA0000243E4E2477DF7D5C1BF44C1FFC635E219B +:10FA1000BB5F44F655C07E6C86B895AEBF1FF284BE +:10FA20002BF867C0EB79A5FE7CF8898D3906E6676F +:10FA3000A478B5A587409A5BF32370DFE4D5A4F9D9 +:10FA4000B03C04F1EABFA1FDCC519FB07B28FBF094 +:10FA5000EA0386576164825F47A72F6604CF40FBA5 +:10FA60004E7BF49DA67288331A11FE228F504BBF35 +:10FA700049F339A667F371C23DB7743E9F0F349FB7 +:10FA80000BC1EF643CCA240C8F07C373C8D74F1D4A +:10FA9000DB87E7E92468C81F9F84EFAB7DEDBA21BF +:10FAA00003CC5B67C57DBFF166168F09A5303D1598 +:10FAB000E232596EF03FB1F16F5CC3F0E346B3112F +:10FAC000F1655A7723C65F480D8BA7F8E8FF603EC3 +:10FAD00033897F12FC54C6F5B66978FE72C6547538 +:10FAE000BC65A6E92A8CEFDC40983FEDC6197AD5B3 +:10FAF000EF000A38CC24EB3E817C8E999ADFFFD34D +:10FB0000C2451BAF11F068ADFC6ABA1F91DF1BD76D +:10FB100019FE0DE33ABE7C963F7741719D03FA04CE +:10FB20009EBB7FD9B560CB124A17C37F5A8AF7664E +:10FB30004F722F7C643D2D3FB67924965F76DFBAF5 +:10FB4000EC0DA8DF568CE51AF99359788F79C5CD5D +:10FB500053E0BEF10366D68FC712EC84DF8FF08CC2 +:10FB6000291A0B26598D2181EDAEB9A8711CE4C16B +:10FB7000D45858F9B5B2FF1A8BE5225E1EFBC24875 +:10FB8000281F903E9935505C6854891483DF89AAF8 +:10FB900071B0F653C73E9E0D7E829A6A561EE5AB43 +:10FBA0005A3304EAE54F670D248F67E573FB89EB51 +:10FBB0005B014EEFCFF9DF6B83735E01ABE483FC37 +:10FBC000FE40E57BEC9E2B13CB2308F8CB14B80743 +:10FBD000B1DACFFC7B13AD2D59C0FFAE0B1ACAC1F1 +:10FBE0008F6BB316B6C17DFFE99555E361BF275210 +:10FBF000350CE41FA5ABD9F94057177F929F867A41 +:10FC0000889AAE04DE4E13F454A3A61BCA0FEAD999 +:10FC10003EAAE981F6DB88FD5EAA964BBDFC5D43FA +:10FC2000B75A7C1C54EE13351FEC954FABA3889745 +:10FC3000B9849DE3D90A78CAE8F7DF607E06B9C7C0 +:10FC40000BEF0B24DF484CAC18447F10F303B5874F +:10FC50008CED3F2FF85384BEC86660B3B9615C5623 +:10FC60004FBFF3C38F7A8979D1F17F8CF059CDE6FC +:10FC7000B3556AE6BF13C1F47261F73689F576A908 +:10FC8000D75B6161E7D13D84F21DF4DD978DFCAA5D +:10FC90007987B89C9D610ADC67A46BB8C13E07F701 +:10FCA000F926127E06F49BD72CC108CC472787F78C +:10FCB000C625F89D073FC693E93E6ECF4FD217C4C5 +:10FCC000BCB4F0681A84AF6AE7AD8543DFFEF4A0E8 +:10FCD0007E96C57F0FAE775D9AF5B4F2FBE01365B3 +:10FCE00046559EE86B752C0F56CCEB358994A09C3D +:10FCF000942C1847EDF53B69F9DB20E7D2847C169C +:10FD0000F3BC839F8BFA5C667CEF0E5D0CE7595069 +:10FD1000DB630638C6F38BD87DC67CFEAD95616C7F +:10FD20006790A501E3C4F17C59E457A8F65BDC4F6A +:10FD300026E25C02AE4E833717F33D35F09C6D3200 +:10FD40000E1C57D5C65F07692751F8E538FAC35925 +:10FD5000C4CBAED5FAE1AE66FEA96BB91F6E622DBB +:10FD600083BF63792ADA6D8EF2371432BAEFFE64FC +:10FD7000B11F3DCEE049C423253E1EFC04AF8F7F5A +:10FD80000CE344E29E422D7CCE0D029FC1E861B09F +:10FD9000F91FB104BE80714F493D789F59C263E39A +:10FDA000CE836021D08BDD565805FE05CA57CF9F04 +:10FDB000076313AAE8FE2D770565B853EF2612985E +:10FDC00004B9D78EDAA09EF9E709FA8797723B71DA +:10FDD0001297EF9F3EC9CEC1D7F8473C7819E89FEC +:10FDE00087F424E2853C6E069F4FB7E850AE2F782B +:10FDF000759C07F4F3F739BE0DDF28AB7E2F6E44F8 +:10FE0000C4A2BA2F63D44E87AA3C3A9AAD6A7F51F6 +:10FE10005791AABE2C3652553FEED05855797CCF1B +:10FE20000455FB8B8F54ABCA97C4A7A8DA5F7A7CC2 +:10FE3000BAAA7C79E216F57D1F617F4F891BEECB54 +:10FE400067F0B8F2DC6C55FB8FD3261F02BA9BBB60 +:10FE50008EE56D5791C5AAEF17EB1A301F9A7430D3 +:10FE60003DA699FE8F9F3757304F8CEAEF1900B7A8 +:10FE70008D6A3DA7BE7BFD6AE0B5FDEE99D0E83303 +:10FE80005AFD65B8B30EAE69269717B0F3EDE4627C +:10FE90007231FFFD10EDBEE2B9FD4F0FEBD08E5871 +:10FEA000FA2AD3EF973EC5F2E18AC9B0743CCF7508 +:10FEB00048472212DC5FD0BCE132A94F8FD1C2C5C6 +:10FEC000E851EFB3D9ABDEE79412F53EA7FAD4FBC5 +:10FED0009C5EA9DE67BB5FBDCF19B5EA7D7605D410 +:10FEE000FB9C3953BDCF5941F53EE7D4ABF739AF51 +:10FEF00059BDCF05CBD5FB5A185EA4AA177C734811 +:10FF0000FB52D5FB56295A413925991BA8C77B1BA3 +:10FF10008675FC7040FC10FB1FA6FF63F4DC8CF9B7 +:10FF2000F5F3E9FE437EFD5FC9BA83108AD2E24150 +:10FF300053D77A8CAB7D533CB8BB80EBA762FF2FC5 +:10FF4000503FA5F2B015F802D5635617807D3D9C51 +:10FF5000DB1D8181F518C1B792F58664BB7A307ECE +:10FF6000D64F4E723B7B5039A9B1B3DF82EC26D419 +:10FF7000C7D7A15FEB668ED79FC1AB4BC0AFFA343A +:10FF8000CAFFB7E8442AE9BCDE8279D371DEB28CBD +:10FF9000423FC8AD24A6C77802646EEAF0DE4BCCBF +:10FFA000C3ACA37A393CE770FD601EF7937C610C0B +:10FFB000EE2C60FE9102378C9BDBC3CE6FBD967139 +:10FFC00041F73BFC0EFE49DBFDA92010857E6A4C03 +:10FFD000DE650FD057FBB9FF894C65F99F44098C4A +:10FFE0004EBE4FB1AF1F16377D410A06D1CECE327D +:10FFF000F9C0CE1E95434C5920DF3C91228853FD19 +:020000022000DC +:10000000BA4016712A942B23398E3C951D5D6A47A0 +:1000100078451C1827F886E3FEA6C07F10F041B48F +:10002000FFBAF51A0CD125CC9FC07EBFE430DF9714 +:10003000876F34C6C02E1378742465D6419717FD98 +:10004000E187012E336FBA7A3594A5FD19DEA574C8 +:100050007E67EAE268DF53F81F81F11B4C14FE74DF +:1000600089A7F282C3D301190219DC4919183DD0BE +:100070007924319F8912C70B4BF03D1867BFDC9381 +:10008000EF0378283D78FE8E5851B921A70C03FB69 +:1000900003051CAA53F26EC3FB748D461FD817D5F7 +:1000A00012DBD76319B7CF82D8E23C39E08EE9542E +:1000B000F33E03E335D8EA0AB28AC0AFC6E70D3F84 +:1000C000028A70F7960EE827E7F3861C128CEFDEA3 +:1000D0002D89DFCBC1F273613BC6338CF26787E1B8 +:1000E000F7FD12A3658CF76DB1D0AE29BEFF27874F +:1000F000B7B8EF9CBE67F97916F6BD67838CF1A39C +:10010000FF07EF54F02D0080000000001F8B080057 +:1001100000000000000BE57D097C94D5B5F8FDE6F4 +:100120009B2DC924992C6421102609598010266121 +:10013000111471588251034E006531E24C12206453 +:100140008100DAC64ACD40D854A8A122A2A20E0846 +:10015000141568B008A8D1372C527CDA8AADB52EB8 +:100160009597002A3B3168A57DBEFA3FE7DC7B33DB +:10017000F37D244F7CCBEFD7F7FBC7D777B9DFDD13 +:10018000CF39F7DCB3DD3BEE31AF2E6043187B7E19 +:100190009ECDA92A8C7999C3CC54C6CA99CBCC32AE +:1001A00018FB7CF4BFBFD1EA602CD2E1B13A8632B1 +:1001B000764F9C21F58334067F9E012591908C8C8F +:1001C000632C99B1EFF1EFA6AB53C67C8CF5C074EC +:1001D000B5810D636C929DD1DF2C180BDB4D662E23 +:1001E000138E7307F39870DC3F5C34BB5814A4067D +:1001F000282F606C2AF3D1F7E9CC4FE95D2C40F54C +:10020000EF66AD947F3F22AF773DCCAFE489EC4CF5 +:10021000066D2E795B8761F9DF2D9E549C6F8DD51D +:10022000734F3C7CBFD0DBF36522D467EB60322395 +:100230007E78BE25383FA8F7591F779603F2E3ACC6 +:100240008E21F9E98C1D34B0CA661B948DEB41F305 +:1002500067467BE6A4815DF5B3943118FF58475497 +:100260001E1B8479972D19D67F335F3EBBD9555D10 +:100270008CEB2C546D2C1EE07FCCA1FA2D3066D176 +:10028000686F4F5C17FC45FAE2199BE852D9C3002E +:10029000EFDF2E812F50EFB7F9AABF11EA4DDC3006 +:1002A000FE0CB62F1E3D795934AC7FFC77AD43026E +:1002B0009016F5329D68CDE1637C0FFFFB866D1CC7 +:1002C0001703E9AD49BB8D0CE67F6B5F6D79712E2D +:1002D000E4ADC1FC44660C96C3B807100EB18CD5D2 +:1002E000FF257FD4E190768C35A96E58F7AD8EC886 +:1002F000F82F0640B63FEBFF3DCE5B2D8DF6D8BA0A +:1003000087EFB70DCE51874D304FC55582F861400C +:100310006F6EA0A33223733577D1EEE94C45D00F31 +:10032000603781B1DBC55C3B8A2F9B2FC17A57397F +:100330003CA5D8CFC2099FCFC4F53123FBDD608037 +:10034000DBBCDF03DCA0FC4403403E9BB1530D56F5 +:10035000E6B230F645839DF2A71B92283DDBE0A074 +:10036000F47C430E955F6C7052FED70EF72CECB701 +:100370006CD557464F2E632BC3241EF93C16093A01 +:100380005ED97BD89F9D30DECA774D94AF6C6E1AD4 +:100390001F01E9A2DE279646C0F7452F284EFC5ED6 +:1003A000DDE232DB603EB30E7B5620F9CC79B775C7 +:1003B00022808FD55E519807B690A5AF7B11D2D918 +:1003C000D03F9D4A40F87DD9309CE673A6C145F3E5 +:1003D00071B5B41D8983F6E71A8A287FD4E1BE1F60 +:1003E000E7E7625F99B1FE841D6DC614282F74295A +:1003F0002E06E38E7231BF1FF0B7C1E4F120DD6C31 +:1004000048B63A1B213F7AE0A467EE8571DFE9E345 +:1004100069C4F677C49617C6C1F789C3BD46AC3721 +:10042000F53BC6302FE9FB87F7358747ADC0CB8555 +:10043000371582D385BD036EBF01FA7BF3A8CA547A +:100440009857C71503CDABE3A3703F5382F516BE93 +:10045000A2125D2F1C68F6B334CC0F4864B9B84EB5 +:10046000E80CD69FA338583DD0DFB99D3F4D423CA4 +:10047000C8F1CFC536FFF513E8AFFD338373338D75 +:10048000DCFCC55390DFD72BC9F930E42E9AD83461 +:10049000DAA7AC2E6212D0D73C33F3F0BC6700E68B +:1004A000CF85B37BDC901FB62B650CEE231CCF9160 +:1004B0001DE46B59BB9E487FC0111C6F7BF3AC4F92 +:1004C0009E82FC05BFC1678A8694355F7C0DC6F3AA +:1004D0006DB139B7329CA7311CE7F98889CFCBB70A +:1004E00035DCB9D581FDF9890F40B919CB6B5E7E3A +:1004F000B227AEE37580C170C8BFBE3682F8DDEBAF +:1005000026E7F17A6CF70CEFEF57BFB8FFC47E4CCB +:10051000D7D416DC0F69C0114BF0AEF8E5DCFED87D +:100520007E400AA007F8E34BFB9440581E6303D7B4 +:100530001D589A0CE30DDAD866E80969FE16A51174 +:10054000D301BD8B8EAAD0FF118783E63178479AFD +:100550009A82DBB5A7FF939B3208700AE2AFBFC057 +:100560005FEEBAAFC6F4847467CFE6853150DE5FC4 +:10057000693EBB240DE9FCC3020FC1AF89FA79A51E +:1005800065F21FEF62B80E5FB215E7ED353BB7A617 +:10059000F1E59A207F614FC6A687618D7B0DBE4D28 +:1005A00088775F99D5B915F1EEF63D89F8AE85FAF1 +:1005B0003EC8D7E6FBA2AE87F2DACFFA3A81A2585C +:1005C000EF676F2E4278CCDBF3F8F89E50EFC2480D +:1005D000E604126095AF5C1E8FED586FC690255CE7 +:1005E000D8D3983003DA3D923B6628D2975B6DA64C +:1005F00071D87C3ECE13B01DAD0032D60AC0491072 +:10060000A40AF51E81CFF83DB625E6400A0BE26745 +:100610007ECB923423B41FE2B13A55DC3769BEE495 +:100620003A58EF7B5865049D7FA7717F269B45BF95 +:10063000F6C9A9EE1F71FE99C57926FB7BC2CC7C59 +:1006400061D04F6FF8AE40BA11FB85F2ADC057EAEA +:10065000217D46CC1FC6BD82FB14DABB900FA7C01C +:10066000219D0FF34C79C242E7C0B58E7FC9645B10 +:10067000A500DDCE0FE77C6C8C387FA7C535BED1D9 +:100680000AEB7D35DC634C83716689739F199D0E7F +:10069000E4EFFE709729AD079EA3EDA9B806385781 +:1006A000C3303F4FF5F449C8A073353B1AF9BEF586 +:1006B000DACED577C35DD1D8FE5AEBEBF9EDA26F58 +:1006C0000C2C1FE860D1E316E2178DC897615D8D91 +:1006D00091C3ACC837D86143CD1138676FE42D3B67 +:1006E000FB5B1459407CA591B12EE1F526EC7F0F00 +:1006F000F09B009C131EE003A3AEB4AB9CDE8F1DE9 +:100700008A1E827C96B922817E6EBA62609E907348 +:1007100050DF0FE02B0FE1389A45304FC8B9EA623D +:100720003166DCB7CC16FB5F5BB798FF4881BF91A1 +:100730001D1F45301BC203BEDBBA5FD71B625DFFC6 +:1007400082EB82745DA6DB85F0BFF16BBB11D777BE +:10075000A3B12415E51A98F778FC3EEA6B8376DEA0 +:10076000DF856BF2D73AFFFB14E633E07EFCCAEC80 +:10077000C7FDD882C723C0B1656EAE1FF7FD5E33DB +:10078000CFFBA2A01CF0D812C97CC8475A4A12FC61 +:10079000BE34E487508E7CA307E3E561A2FDF40438 +:1007A0006ADFD30220457E7057B8E8BFEE9D8158BE +:1007B000BE2485F848A3C9BF2A1DFBFFB94A7CF8AF +:1007C00023C1B7D7C504EE52A1DF755F25301CE702 +:1007D000231648998FE3548613DFBDC160B8A7C4C0 +:1007E00086F55CC9B100EFBDFF50E99C58970F79C1 +:1007F0001BF1ED69CDF07D5D892B391CFB2949305A +:10080000D07C545647DFD378BB4F4CBCDE0C81AF55 +:100810008F057E605FD3BEF74C8C3022DDAE492B56 +:10082000F3A5911CE44A5660BE4F556432E49B33F5 +:10083000AA6E49237A697A82F8D7348103D91F36A0 +:10084000B00E43B999FF4D9FB5350CF17947655806 +:100850001B9CACECA3CAA5910E687F87470D5880FE +:100860009FB22985AE4EB92E1DC775D1B8B5CDFD45 +:10087000324E85D0739905F804F4FF52986725ED40 +:10088000D3FDF954BE1F849AEF613F9DA8C8DC8553 +:10089000FB8A55C4111D3063A01CF1F066BB95E4C2 +:1008A000D4EEE8A111E13F48D029E26531C73BC849 +:1008B0006B946F9CD6DF8FED9F3371BAF1ED0E23F1 +:1008C000BC164DB2129E3BA6856FB240F93D826FB9 +:1008D000354E0B772950AFF1158BDF807C40E1F46A +:1008E000E07B2392FAAD31F37CCDCB99444F7BCDA5 +:1008F000FE17B661F99B61440F35517CDC9AD752E3 +:1009000004BDB9D296E3B86F58880E6AC21DD1549F +:10091000FEAF7144272EAB673BC203E8AE0EE588FD +:100920001A73202B06E07B5CD0D5716883F8F3D571 +:1009300045D2BC69CB43DED3D87B33E2D363E6E553 +:10094000EC672A951FB7F3F18FAFE6E3973E5AFDA8 +:100950002E03BC1D778F4F9E05F3385E174172E35F +:100960005FEAD580390AF59EF6F55950EFE2E29339 +:10097000C336C0FC5B977E9A8AF451BAB4B618DBD2 +:1009800095562D9E88E76677FBB2B406367FC83E43 +:100990007E3FCD15C0F55C48F31C423A989FDB3A88 +:1009A0001BE5E78BE663CFA2FE1115E73982DF2F47 +:1009B000BDFAE5362E57B767E17930CFC8E9439ED7 +:1009C000ABF305FDDD97EE7997CE89F0C04C3C3F47 +:1009D00022728F717EB7F8DAF8FCD996AD7B1518C4 +:1009E000A73ABC651EA5AA3F0FFB39A704A2940C29 +:1009F000829F07F7D3797B200AE1EE317079AE7AD6 +:100A0000BB765DF867847955E33FA05D75B3EA0A6C +:100A1000435C33BF19E75FCDCCC1FA69413C413F2C +:100A2000842766FBCBCC0700FE552FF42B40FDA19D +:100A30003A66FF2F6EA07AD04EEE13F5EABC5CCF7B +:100A4000D5F3E1EB3B2FE8FFBCA4FF6982FEC5F8BC +:100A5000175F4DA4F1CF95F8B310FE171551EF05B0 +:100A60000BAF07D460C479FE9AD3D37A93CF80FCBE +:100A7000C7F77346F45C1DD73C0CE122F910CCC1DA +:100A80006780FAE776A5507DC9B7989B316C57BD52 +:100A90002B793397CF843E8B1385FA552FF1FE3196 +:100AA0008FFBF0EC8B29623C2E4FEBF1A75F6F447C +:100AB000BA81E4A9F5927F47CA7DEE4C2A01F86716 +:100AC0006F306BEA5F8C34DFE3827EFBF9B5DF6564 +:100AD000FF89E95CFFEBA3C35B4FB5FD8005F7D34E +:100AE000F38CF6AB7E5EA9A2DD8B2F76E249E5782A +:100AF000033150D28783CBE12684F3C79DF8B83702 +:100B000005F86A35C2203D089FBDF99E14E4FF1721 +:100B1000318FE7420CE473510EE2F0967909673D9C +:100B20009D2DFD78764A2BB4BF45C007109A88F4F6 +:100B3000D829BF98401FC9457DB472F0A94CD45341 +:100B4000EBFAC151D0B99ED91BF2ADB89FE66CCC7F +:100B5000B79685E0A171FBE0A30E80F3F9ED46277F +:100B6000B2E546A3FF17284F376E579B7D8CCAAD61 +:100B700008DFF3B683BFC77AB337C614A0BC2CDB3B +:100B8000CFD9705FBF8A10B80FD8AEC5C3C0666D2D +:100B90007ED07E6D7E32F286A13FBE5D7E409B1F81 +:100BA0007C549B67ED802DC0836AE578DA37DC7969 +:100BB000D40178EAE3579DF8A98F6DD2E409285F44 +:100BC0006C549D9950DE67B1FBB681903FBD719624 +:100BD00013D15CA9FAE63D0038ACFC74FC513C0F23 +:100BE000CFB1E60F27001E66B7AC351B1DB86E2DC2 +:100BF000DDEE35087A7D51213A98EBD7965FBDAF8F +:100C000097083CB29C507AD2E31DC6BDD30513AA07 +:100C1000A95F34F8141C9995C540E800B311CD6B59 +:100C2000CD28B7FDF0383E2E0FDA5C0E848777387A +:100C30002FBBBE7E2C3B3918FEB1FAFDF1386FEFA9 +:100C4000230AC90DDEDF641FC673A06DF7F45B29AC +:100C5000BDB388D62FED79735A944024E4EDC31DBB +:100C6000FB5BA1DD2CBFE2C479972DB304F919FC1D +:100C7000AF62B56E1EEB42CA61FE73F61FF89B02AF +:100C8000FD576ED4B69B0B7C16F957D596EF2DA168 +:100C9000DFA5DE787DCB2615D73D4BCEDF378AE149 +:100CA000BAAEE75559BC906F4E6106CE8D5B7BB8EE +:100CB000D7A763BB75BC1DB04B2FAEB7D66676E029 +:100CC0007A6BAD2C1001F3381A6976D9E1FBE50D8A +:100CD0009164479B6D0179B28052165680ED9CD18C +:100CE000D8EE8BF7B83DAD368EE3BBF63985F4A868 +:100CF0005A347E62FE799E9FCB02B40EA41357E84D +:100D0000FAFCDA3C6BE2FA578D317000E151C55ABA +:100D1000B9FE04787449F801BC6A609D1FC5A2BC85 +:100D2000A56BCF9C1E1C77BE8DCB4FF3F77F6F0951 +:100D30002D977AA0D4533786733DF1B92C77388E2E +:100D4000B35C713D6985792E17F2B56F6D18D1EFDF +:100D50008C4DFCBC0139360BE1B26E6DB213E58CE3 +:100D600019209787E1BE991B4EF540DE25BB4C3B11 +:100D7000C8D59BD3B07E7300CF8D758FA7911C0D06 +:100D8000F22FC1A57D4D987FB38272309763D6ADA7 +:100D9000CD2639FC75794EADE1725717723195B396 +:100DA000442EC77F824B099183CFF4F07C901EB212 +:100DB000AE8AA5AE643C772A26990D68AF6295711C +:100DC000D7243F6C1572643BAC1FD7714A711F3139 +:100DD00084C8A39FE37900E30C1BE3DA26EA39B168 +:100DE0005E85A1E4E19B70BCF506078ED7096F977D +:100DF0002B0BE7716A6D5801D2D9B031DC5E743CBF +:100E00009FF3F78821CCE587F4A238672E225F0F85 +:100E10004993C281FEA09F5385DC5E1D39C44D7687 +:100E20003A38AB89CFEBD7F177D14F85D9FDAF37C2 +:100E300076311F091F368ECB0BA716289BF9BC00F5 +:100E4000BF901FF6CB30B2EF9D12E78F8433D0CD29 +:100E500050B2D30B7EB556D0CB5A13A703DF5CAE8E +:100E60003F05E985113DAC137AD60C815FB686CB80 +:100E7000B5402F1CCE6B9205BDC0DC911E0A1D5CD7 +:100E8000CEBE467D09F01E9BD1E36ABD49E29B19A7 +:100E9000FD43D1BED21DBE6BF7EDDCEB83F3B3EAAD +:100EA000D78F4731A877C6D894E084F6355B97474B +:100EB000B9203D6DF445D961FC337EB5C8DF05BC72 +:100EC0006FCF907665974D01FE330FFFE94079E7CC +:100ED0009189B8BEBF6E35D99125CCDF6E21FD69F1 +:100EE000DE9EB9246743BE8DE7577EA5627EBFD6DE +:100EF0007E5EF5ABC7131C046F5F8A2109D3400ADD +:100F00008374DE1693338076E90F54270C037273D3 +:100F1000FB0A9C9FBE3DCEE30AE07B7EB3EA3547E9 +:100F20005F5D3E5FF097F97B1EF90AED7AF375F687 +:100F3000FA4AE1B7D0DBEB6FCA888CFF020DD3D73A +:100F4000B1EB500E02B83803B86F613E994426DC0D +:100F5000DEDBF8C213796D282F6C79274AC90DDAC8 +:100F6000EBA53FA3A3B9FCB9D71CDDEFC78BC26EBD +:100F70001BC417E75B8EFD0AF20050D0795A630A52 +:100F800044DD00F0A8D964223E53B3F3F96D4F213C +:100F90009D7D6CA1F3BC7AE75B1F5E8FF2EE6E5312 +:100FA0007C315F864D4908E269BE83DBC9245EAAB5 +:100FB0007EF396D931907F5F1C1BC44FF5EE03661C +:100FC00036F06A388E6D3E606EB57581A7E6B6F173 +:100FD00064277AE15B33EE83336F2A2C31EDEAF636 +:100FE000959BDE8A42790CE184E792C45727FE7410 +:100FF000F5A1FF89AF0DA17A76D42BBAC39F03CF99 +:101000000ED4CBF745B21818BFF2138BBF18F1BA44 +:101010006B5114AEE34B631DA7F3679627A05C5793 +:1010200069F225D829E5DF2B9FBD8FE86F8E529797 +:1010300060CF25FA4E3690CCE04BC6F5CDDA780776 +:10104000AD6F36F310FD553EA3BAFD907E63644547 +:10105000BBBBD8276F6770BEF9E566402AACEF4B83 +:10106000B4DB20DFF8832AF4DC05747EDF27D6CAE0 +:10107000D842CA7F23E4B68D1952DE056922445F47 +:101080009CBF65E531C4CFD9DEAE449C27C0C127E3 +:10109000E0A57C0FFDAAEF172672FC3087719868D7 +:1010A00007E7E858FC8EF58F995C68F70E6927F41E +:1010B000393EFEBD627C987738EAAB5F2670B95D39 +:1010C000BFBE6F3BF9003BC642E9ABBB7DBFE5212C +:1010D000A2ABAF3FE07C659EBFA488CA8F9902890E +:1010E00058EE3F304521BE606181AEF6F51693D8CB +:1010F000D7DA7298A7510985EF9B5C0E9D0D725748 +:1011000020641F07E9C61CFC4EEBFEA558472BF9CF +:10111000D3A41F6E8EE007FA75EBF9C3211D7F90F3 +:10112000EDD9C6AEFD4041BEE0A3716BE03C413954 +:10113000A3E6630B9D1B353B4D6E84CFB91D873EE7 +:101140009C817A68B3DCC75A7EABDFC7952F0FED61 +:10115000721F9F5B9DDFF53E86EF5DEEE3D50AF1E2 +:10116000B7FF2EBF85938EEC06DDEDD739DDF0DBC2 +:101170000B3A787EC372A36FC042BBB70FE147073B +:1011800057094F3DFF5C9EE120F8EAF927FC7DC03E +:1011900042E028E127E993310F8DD349C7924E25CC +:1011A0001D77D2A97EBD5A38EACB77237F82F9B862 +:1011B0005F3571FB598B42F236B43B923284F6A90B +:1011C0008B8E3FD67424253E34EFD7E59B75F55DB5 +:1011D000BABC5B57DFA3CBD769EAD7EC3F64E6FA2A +:1011E000414053CF527F1BE91957CB117EEEF7D9FF +:1011F000F395D98774D1ABDD8C7CD1B494F92251AD +:10120000DE7D432579F792A33D0AE592E5615C6EA8 +:10121000BB6417F9189E6FEF615E817C517E6F0F82 +:10122000E376924BEEF6A898103DBDAD458D427B1E +:101230006CAB9F1575654721CB28C0B5957557CE0A +:10124000E5B742D5965A8FF6D026D50964C22A96BC +:101250004C8DA2B887968CDBA7C1F7596FAB143EB3 +:1012600070299CDB1598CF65C4B883728E42769A3C +:10127000F9D68F847595B7F0F8838AD55AFCCEB627 +:101280004D890E3890EF68E304E6A05E9781FA9EE0 +:10129000F67B155B4DF456A5DB171E61A7D5EF0B4A +:1012A000775F112F90CFF2853D86FC1C0B05BF2E7A +:1012B00054736F9F06F0BF74546516C877B4A86C5A +:1012C00005AE778742FE1E7408E07E9B07FB12E79F +:1012D00023E1731EF74D76F772C9F9573E1BF600EE +:1012E000D2C9DE4FF39E86F4FCDE8FB35EC7FCBE30 +:1012F0003FA77ECAAEAE3FF6CDBFCD443E7CE94DA2 +:101300000B43FABEF4E66F53D12E78E9350BE9CBE7 +:1013100097965AB8BDF9CD483FFA232FF5E6726E7D +:10132000E31BDFE6B5D2B9BB8CF0F5405F33979B8A +:101330005AFEFD38DAAB3B5A6055284FBC1941FBC9 +:1013400067FE6B61E40FBFF4C6B7C342E326FEBB82 +:10135000EB91FEEE4B916CDACB48B742AE9FFFFAB1 +:1013600088E7D19F5BBBE780B91CCAC7FECB7FE48F +:1013700021FFBCF43297932E9A5A9F455BE38A2D46 +:10138000CE5F9A92D13E079DF564ACCFD6BA49B8EC +:101390004FAE860B87C3258003AE0BE052897CBF1E +:1013A0003B783C83F0E8F1CF088FAF66727E761D04 +:1013B00043FF6F102E0AF723B444FAAD0AAD9F7FA6 +:1013C0007FF3DB3CE4373FB4DED7FF69F1FFBFB307 +:1013D000DE8FFF69F1CBE9DDDBD741F3D4D3FDD557 +:1013E00074BDEF2794DF15E9A4F95EE37EFFDBFF10 +:1013F00067F84ECCFCBF8AEFB705BE23EDE857BCBB +:10140000F4C67FA4B21FB1EE61FF47D72DE5F531D9 +:10141000AAF3683ED47F87357FE04C23E9A34BB91C +:10142000A33C5391FA1BE94763193FA7C75AAB493D +:10143000DE1CDB6B0DC9C58DAC80FC10BE5E2AF9CD +:101440006328F802E0F0DBA47C3FF9938C815E8B8B +:10145000203F26A596E2B3F47AE3D8F00945288F19 +:101460001E5A02F3827E0E451AECE82B1ED74B0D56 +:1014700058F2286DC3F448EA6D47516E1967D3EAF4 +:101480004FB7E9F4A15B1CDAF222F6723CFACF8A7C +:10149000724DCC0FF3198FF543F4C6D199765AE704 +:1014A0002DAC6999DDF6E3E1F49880D3D570F8CFDF +:1014B000E176159C849E6C14F5F57033DA1E3E8639 +:1014C000ED8C0CF45EBE5ED297A5DEFB43F0644269 +:1014D0009F368AA1257C8DBDB89F34A45F828B8402 +:1014E000FB8F85B7C4931EEE12BE126E7A3CCC46BB +:1014F00063548F20FC7B19F38DB8EF6E1472FC38A7 +:10150000630CCFF73AA6BA693FFA399D7FED34A252 +:101510007C32DA1643F19ACCD13B06E54C1431BF4C +:101520004F61AC6C78CC3005D69B62643E0BE89B77 +:10153000E843233BEA4346FFD2341C87DB6B7B1B2B +:10154000B95D1A76B72FBC80EABBCC90F73E3687E0 +:10155000B9A0BE378539155E9F45C752381A533139 +:101560002E0B526CE78DE6FD7A13997F29C727E190 +:10157000A52FA6E9D4AFCB10CBDB4715507B9F81BD +:10158000B7771921ED93C1EDEBEDCB2DA47F785703 +:10159000F6CE42FE513C466B378EC8E2766699FE27 +:1015A00024CB41A96A7026A15C5CB6AC1FE9436AF2 +:1015B000B8BBF615B4F7EF8A207AF4AEB87BC25008 +:1015C0009CDFAE38274EEFECC4DDC378FDE9F7FDB4 +:1015D00009BE7BB687D1F7A7B23C473201AE67158B +:1015E000C7CC57E043D91D87CC493084A7B9E40262 +:1015F000DAFF26FA76FF1EFD8C13A7A8547F22E39C +:10160000718F6C5904F9A327F8BE3226417F13402D +:10161000D9C0F2B6307BEA0298BF57D87BFF20F6DC +:101620008B1ACE3C2F23BF5AD13B2B1DBE4F605D82 +:10163000C701DBB3B89D461DA36C44FF509FB1DCCE +:101640001E2FEB633FD86F8280C76799DCEE24F3CF +:101650000057AA5FB1CAD296817ACF2A53201BE3E2 +:10166000A773C6B4E13A8BD3D9F80D08F7FB55B68A +:1016700099E6DBEE253B77648E03F1E00192A6F854 +:10168000C2A63407DABDDA463707D03FD0F6649AEF +:10169000B3D14158A6781CA967B58D0EF445BB7C23 +:1016A0007B3EF7331CB7B746A27E586EB3527C8E92 +:1016B0008CEB9965E7FBBC4F63EB9AEB50EF7C5CDE +:1016C000756E86FCACC7B9DFE5739BD5AFA0BEB61F +:1016D0008EEF53B65A1BC7C3EC4EB2F794378D3614 +:1016E000A37E59617399719DC9D99EEF715DEC3BE1 +:1016F00080DF308CE364B419BC4D5E8A3351A36043 +:10170000DFE13E313AA250EFD5C701CD17713F322C +:10171000FF5298C79A05702C8B76EC427A39519F0C +:101720004176CF9B91EE107E18C788FE09636B321D +:10173000CEE7D54C4E8FC5B1F62C1BD1731843386C +:10174000B4990093906F5B1E66403F5BF1524ED799 +:10175000B0CFAC4668FF909185A3DFE043D1BE7463 +:1017600089D1BD09F2BDACCC18198B74954F74FDAD +:10177000688EE7335CDFE99FB3E1480FE5ABD792B2 +:101780007F45D205331E1B1707E39CDE9A56807CEB +:1017900053D2D1A33963FA6485D2C31485E800D249 +:1017A0000319440F93FA6279F19840DF85B9A88F45 +:1017B000D630179EEF49CC897242076B27FF6387AB +:1017C000CDEC403B97E427926F005E5DD684201DF0 +:1017D0006C83F3DE68626C7B8395D2171BECCC08BC +:1017E0003C6E474312E5773538286D6EC8A1EF2F60 +:1017F000373829BFA76138E5F736B828BFBFA188B9 +:10180000D2D71ADCF45DF225800BF121C957243FB1 +:101810002AB799DBD01F29F9929E6E660278471588 +:10182000507BE27B92DFE13A0C05417E24F19BAED6 +:10183000B87D4969C8C75AA723FE0BD5F33BF7A16A +:101840005E5E6973929ECE38DFEB007A45B8A49A4B +:10185000D97EB4BB362E70B5AD4C0BC2FFAE4A85F7 +:101860001943E8EAEEBA30660C3937EEA98FD1E4B5 +:101870004BEBFFF85622F43F2EDE332D0BE671FCC6 +:10188000C12F9EF9337C7FEEC1B399886F98C7D67C +:101890002770DCC5E19DF388C5FC3213F9A3FA4833 +:1018A0003B08FC215ECA18DF6FCF3DF877DADF6DA9 +:1018B000F51607CAC39F209E00AE7F11782AABB7EA +:1018C00010FCBCCB4FEEDC87FB7CB199F85CD932C5 +:1018D000B10F57013C43FCBB279219D923409AA66C +:1018E00078F5133F370722A0FF130ADFBF0A080568 +:1018F000A518F7B7EAB71FE1FE57EA8F92FFDC633E +:10190000B505480EF099CE87F6A7D41FA17AACB5DD +:10191000570CDA11E91C43BE3FC46576C0BA91A6E4 +:10192000116F6539075932FA4D9A143B6E990AF1D5 +:10193000BD629542FE498CBB9902729F2F4B253C9C +:10194000B6641A695FF5CC6242AE6BA2F349D26B02 +:10195000C56A6887FBA229DF3C3B840F9789EFE5C6 +:1019600039064AE5F726EC17FB5B953F0DE5899EA6 +:10197000589E8B69C134846F4FDB78A31282FF8736 +:10198000B3F8F82D997CFC9EB8D9E0FF1ECE4937FC +:10199000CFCA45FCF0F34B8E539653B002E338CBDD +:1019A000568F46EECB1A4DCEA478A8F718F643EB27 +:1019B000B17379C1CAE3956BBA393FA4FDEC34FE2B +:1019C0007304AD9BECBA55BB5EDA8571FC559F5A2A +:1019D00008BF558344FC54AE7FD86432346AEDD5D9 +:1019E000E35EFA2C8AFC0F7B785C25A4DC9EBAB8F7 +:1019F00092DB5F9DB0AFBAF0FF1CDEF569549776BD +:101A0000EA3DEA35D9A9E72BDF45A1FC20D753F8F9 +:101A1000C63709340FE50AF97FE6BFB13CA1AB7BBD +:101A2000377A7B75A73D5BD8EDF4E57A7BDD912CA9 +:101A30009D5FC0C8E81E97B4D73135371AEDFBDF7C +:101A4000887B1EDDE935D2BE3D7F03741207FBD3D0 +:101A5000E888467FD5A56EE4E9A86C2E1F5C10F6D9 +:101A6000F04B3B54D2732EED88A4FD346FC763470F +:101A7000D07F386F8B42D3A865C7086E004F660DC4 +:101A80003DC730DE2CEEEA7977F833A3F11CA97E4E +:101A900029B20EE96C6EB3E2DA0AF3E9B03AA27B3E +:101AA00084CCE7ACA0D76A4BF33082B3987FAB907D +:101AB000B764BDB92D8F91FD18EA5D2439E8D711BF +:101AC0008CDFFF68FF3DCEF3DCC6C14EF4FBCD6D6D +:101AD000DE3D8FE4881D11761481CE8A3861D9CF1E +:101AE0005F055DFF358BCB2FE7843FE8DC2E95F853 +:101AF00019CE13F7D759451B8FF79D68F75D1687E9 +:101B00009B1FF7778F60FDB9CD6D517DA1FE97FBCF +:101B1000FF48A9399BAF6BAEED581E9EBF5FEE89A3 +:101B2000207FD6977B9E1EFF3A8C77A179743CEE7E +:101B300007D97F7CB689E363A35A84F0627E1EF7DF +:101B4000528BF01D1C3ACFB84DBEB4D07DC7E37E9A +:101B5000CEEDF94D94213788CF5AABC79A9C8EFBB6 +:101B6000C7EB46BEF1B9C2E169DA33DA87F798E626 +:101B7000B7E433A467DA77C9547F9521A49ED9E4EA +:101B800024A668DC5FE24A21388B7B48225E1EEF88 +:101B9000D5D1BDA2122BF927660E724CBD0BF9E40C +:101BA0003B268E975E8E27507E9BF95E1CC54D2D81 +:101BB0004C734CC5F92F7A5FA578DF9983051F48D0 +:101BC0006A1D8A718B35AB14E68275B6A571B9A111 +:101BD000C6AF320FE47B023DF8001423B3D3053FB8 +:101BE0000D64E17DC0A72A0D2E339C7FC7CDCCA705 +:101BF000A2DDE8651ECF5C93CEE3869F42BA87B430 +:101C00002636901507FD9D17F8AC9914C8C238897F +:101C10009A9793294EE2BC99FB2DF13BFA496B0A46 +:101C2000A03DD48B17F1B0D83E26847E6ACA9C0EA4 +:101C3000ACA7C63A1DF9369CAFFD22C9B1AF4432FC +:101C400094630DFB22799CD3AFC2365B42F0E4CEA5 +:101C5000E67272BCC0239BC1E321D78B78ECF55BA5 +:101C600093FDA8BFC9FAEB4D9EE908075C07CAEFD0 +:101C700073CD4D5928DFCAF9CE8D6AA2799E17F42B +:101C80003D37BC89C74B9B793C25D6C77C9B895186 +:101C90001C77FB0B168A27399B7C6C2F8E7FF68571 +:101CA0007E0CD7DF96E69FBD9FCA417E04BC55BD22 +:101CB0006809E07ACEBCC0EDCD674C5C1E3B539208 +:101CC000E440BC154DDA3093EC315B2C0AE2FD8C1C +:101CD000C2CC4958BEB587D387ED1BEA294EBA0A54 +:101CE000D804DEC781B408EFD59CD9DA8FE2C3CE21 +:101CF000BCADE28D28FCBE0ABF7B58D3CC9F213CF3 +:101D0000B673FDE9EC8BFFDE2FF41E9A4CABB66880 +:101D1000E3E0249DC8F205D95C7F5920E07C5F3662 +:101D2000B737D44634AF4FA77572B8039E48EF0358 +:101D30000E13F9F4108C83C854906F3C0574F5347D +:101D4000DA15B673FDEAEC0E13C58557ED8B7451A9 +:101D5000DCD9CAEB0C1407A17239BCCA00E0A35449 +:101D6000A17EAB26E5F81B49FE66A4C7B66F55C534 +:101D7000388CD970DDDB789C6F31CA8A543E90CAAA +:101D8000CF88FC99BD0349AE83FE5D785FA9EA6701 +:101D90000F70384EAE7C97911DC34AFCB5A6D38F09 +:101DA00033321ACFBBDA953744E33D40F69ECA5032 +:101DB0003ED1C3E9B2D199887CF57036E75FD57B17 +:101DC0009F31233FA816F743AA5F54B83F19F6196D +:101DD000DE93AC5E71C313449FBF37B14C58CFF94B +:101DE000E6C7A242F1B14BF4D359DFECA4FAD550C7 +:101DF0001FFBA95EF14E14CD679B89E24CF478BCC1 +:101E0000E6F62FAAD7D4BE933E9AB91DE5AAF5B33C +:101E1000633FF914FAFF7A4798D3475F9BE95ED98D +:101E20003953F36C5CFFB99D61C48FCEC570FEF071 +:101E300025F04F5F36CEE3B647292EEB0F93E93EF0 +:101E4000DC1CBFB65F39EE6F906F63BC549C331AD5 +:101E5000E3FA6ADFE3FC0DF0723BB57FCF44EDF5AA +:101E6000EBF8A568D7B93F7746103D9CEBC9F172F6 +:101E70006E57369D476D319CCE61BEA9787FEEDCF2 +:101E8000CEEC7CBA9786C20DD04395D06FCFC534C7 +:101E9000A7DA43CADB4C424F0B404DA41B6C0372C4 +:101EA0005F553D97ABAAADAB293E04E36A87155059 +:101EB0001AB0C45E1D1F0BF44AFA63780EDF5F0C84 +:101EC000C74B10F1DB24EF349B917F7B845C58B3CC +:101ED000431F5FCBCBCF6477DA391DF1329E17E910 +:101EE000D0A7509C49F5B2057391CEABEBD6DE85F9 +:101EF000FB4CCEBFDAC88A500F6B53549A475B181D +:101F0000BB67129E1BA1E384C86D5F07C761F6041F +:101F10009257E91CBB92EDE074832726DE135DA681 +:101F2000ACA671D2A43ECBD725E104E030635C5F60 +:101F3000DB6851DECDBAE53CF5EB96F3B1E5707E9A +:101F4000D496E6787424E2F9772ADDA7BDFCDDE0BB +:101F5000E8D82EE4B2E0B96E0EC6B7C2FC9391F693 +:101F6000D0EE92CDE5F16A8C9F8579666DD4C67509 +:101F7000E76CD1E6FBEFD0E673F768F3792DDABCB6 +:101F8000F3B036AF887151CFC6FBBBA867638A7ABE +:101F9000B6C3C2F56CCCA39E8D29EAD9F81DF56CA9 +:101FA000CCA39E8D79D4B3312FE18DFA36E651DF83 +:101FB000C6F25B73B83C5623E224110F48EFECD510 +:101FC00030CD7D9F4B6FF07B1C40077CDF4C37D3BF +:101FD000BE790A6B90DEC1ED4A3D275B1D18EFBB51 +:101FE00038D633246728DEF738B62219F1666CA597 +:101FF000B8D3F9AFF1B8D39A82301BDA375A977F4A +:10200000B902C339DDB19E1158FF92A97D1BC2B739 +:10201000B6FE10DD7B6F5DE278EF268E3FB2B3B087 +:10202000CA58929BBC78CEC5768F477DDC375BADB6 +:102030008DF3D6C77DEBE3BDF57420E5BDE74CED30 +:10204000C9C8D74FBE605D8DF33F1926EE9F4CB3D4 +:10205000EAFCFD424E5BA36CC6F37A464E2CF79F1A +:102060001D05F9BC8B7356A6E55706931CDE995FD8 +:10207000AD18E85E5C52029D438BC49C5295F6B647 +:1020800095C8E7E61AE8DCBC0C72198E77F903955F +:10209000E487EC0D06CD7AFAF9C335F435607BACF4 +:1020A000EE5E434F4DFD41FBD375F71AFA6BE3E843 +:1020B000A72C3980FAFDE4D58335F52ADC37E8E032 +:1020C00028E62DE4D70A383F5CB0BEA7166F484516 +:1020D000FC2E9ADBD1B612E5D357C2E85E5825FE36 +:1020E0003FE08B95D027DE67ACDC23EE03D76BCFC8 +:1020F000E172710E551A99CF1E1BA4C34A3B73C5DA +:1021000040FBB9FD8FE50550AF78FB8FC3ECE9A824 +:10211000578C4E447E946A72511C6CCDEECC98253F +:10212000D0EFA20CCF4339B0CF4E351DFA45299ED2 +:1021300087BBB9BE7772F56FA2284E4CD05BAAC997 +:102140001E8E78DFD4C4E3E3D03EA6C606E9625310 +:10215000535C785F5B70BD413AF88EF004F8E1762D +:102160009CCA83E4F7E86816EB1DADF8509E96EB29 +:102170005B28CE15D697F773AFC89F12FA855CE738 +:10218000F97E07F21C78FFA2617FAA8AFCDCB063AB +:102190005B32A4B916CF165C4FE5A6CC3F8F847195 +:1021A000AAFEC4D7F3F9BAB1512350FEDC69721606 +:1021B000437E65D3F366D4B3AB8C7E33C557BEB0D4 +:1021C000C98CF1C5376FDF44DF676FF7523CE51C00 +:1021D0005647FAE769F9EE808047E51865A31DE6E2 +:1021E0001DD68FF38FCA70EEBF03F9E82D7CF7E39D +:1021F000F276251FE378A6B8779BBDF0FD0DC18F61 +:10220000F5FBA4E3DDC9853D081EFCBEC69F18682A +:10221000F11957EF8BC957D2685F4CB93280F4B2CD +:102220003B02FDB8FE9BABD37FDFE5EF2E74B4F02D +:102230007D50690EC44FC67DF2A689E4DC5A386F22 +:102240008617A05ECDD8F590BA47AA1A7A9D3F2E80 +:102250004243CFD358C83E81FEEEC4A09190FC9477 +:10226000E20C4DFDA95306E8E8BF20584E7CE47A05 +:10227000CDFDBADAC53E874272E618ED77C6E304B3 +:1022800081436BDAD7B249C17A48DF5BB81C5CBBCB +:10229000276633DAFB2A0D5C7F9AE6E1DFE7EDE79C +:1022A000DFD934A6D9877D329C7FE6E7A289FC027C +:1022B000D29E3E0DFFDD05FC4112E9BC1F8EF7E208 +:1022C000D11EA1B93F2DFC81386FC443ADB01BD5E1 +:1022D000E670BB51ADEF9819DF1D00F81BE362A952 +:1022E0009E350EE3239B14B22B62BA98E225B5719A +:1022F00058D81FC631CE3BAA7A719FE8CB81EE78C1 +:102300001CFF6B3CAE74CE067D1CE46AF247CE43E4 +:102310007B5008DE6EE9E710FE38FF8A9E08BF6238 +:10232000259FEE45EE3860C638BB295362F271DF57 +:10233000E8E94BF275D8CFA47F77BC7B88E8ABA3E4 +:10234000D248F4FB437098E7E276543DDDCD66C792 +:10235000CC784F7CF61EC589FA28D64378F4447AA7 +:10236000D4C1232EF66A3848F874C26B8F3ECE8DE6 +:10237000C369CE7EC51FE8024EFA79770737B99E4A +:10238000D91ECF78E40B725D7370FED83FCC1FFB73 +:10239000977E08365CBF3F33C83E35CFCDE363F54B +:1023A000F430E90AB7BBDC79C548E99462ED7EC434 +:1023B00076B82FEEB89240E53F965EE6C13CF9FD57 +:1023C000A76BA313B90EC97783FB81DF1BF8A17735 +:1023D00081F476C73BFA09BBE3503654138F2CF8CF +:1023E000AABEBD3E1E59CA01FAF3C51B69A0B8C9F1 +:1023F0000E5B3AC91792CF7AC4F9E159FE0DD5F3B5 +:10240000403D3E9B04CD79E311F6BF8591E9F41E72 +:1024100043EA92B804C49337CC4EF1F7DE252AC5BF +:102420003D7BA19E23443E59B12C2315CF8B130F26 +:10243000653FEB03B9FDC4FDF109C3619C93CB4D2E +:10244000F15647B0DE89E585A918A77172AD659A86 +:10245000BF0B7835F4E3E743ED831FD17976C1F004 +:102460006ED434685FB3FC95280CF3AF5ECECFF129 +:10247000C40CCF83FDC87FBB699B1DE167DF9487D8 +:1024800076DF35701C607B293F542D2F4C44F9A218 +:10249000E61F879EB5E33DEB25A604943FCF7C0065 +:1024A000E7A142E719C90DA7C3A00BF2A745921DEA +:1024B000E1B4C25CE8573A6F38F0D795A817E63711 +:1024C000670520ADB578D6F443F97FF9F324B75406 +:1024D0003DBC244B55B1DFCCE8AEEC2632DD26CE38 +:1024E0006D94DF3145F91DE364507EC73CCAEF9817 +:1024F000A2FC8EDFE76FD0CA7FCF087FA1B427F799 +:10250000696CCF47FF9D6F0CCBA9A3F3D69683F2DE +:10251000FA2225DC89FC6811CA4A98FF2C8CF458F1 +:10252000B625999FB702CFF556EE37FA56DCCFBDE8 +:10253000B11D64B210FABCE98A9585DE9B1DCD629F +:1025400034F9B1D6644DFD427B9AA6FCE6A47E9A8E +:10255000F25B1CF99AFC6D392334F52738476BF28E +:10256000B70FBF4553BFC455A2C94F2E9AAEA97F1E +:1025700087DBAB299F3A6DAEA67CBA6781267F5771 +:10258000E5FD9AFA77D72DD1947F6B008D14E8A5DD +:1025900005F52E0BBE9F62A5F4A7AADD887C63D14A +:1025A000EF326D88EF91630D755DD9F73F14741CA0 +:1025B00037C0F53ED24B6FF13E4E6FF1CECD293C88 +:1025C0007786A21F12A88AF4DD63C948BFFA7AFA97 +:1025D000F29111072F3B0087A35E34DF61043E3484 +:1025E000F2BA83833320FFD3176FE4F91B0EFE2664 +:1025F0001DF20D2F2EE5F941072F63B9F9A5313CE6 +:102600003F9991E8F148FF8E29184F32F2A6F4D590 +:102610004E6E27E9F29EB94C110E785F1BE180697E +:1026200000E817D38340BF981E06FAAD00FE74047D +:10263000E817D3A3A07FE2F77F05FD13D37741FF0F +:10264000C4F4F7A077627A0CF44E4CFFD0308DD2F0 +:102650000F1A3CD4EEC3864A4A3F6AA8A3EF9F34C0 +:10266000D453FA97061F7D27473FB74333CDFD006C +:10267000F433A23F71BFE97CA81F58FA2BA57FB2A3 +:10268000B18EB54620BF6835C67C610DFA1DBBB75B +:102690000318D91721F258347345F42779A1979D6F +:1026A000F8B7F8BEB38FC7DE1FE6F5A7B4C99983A4 +:1026B000553CB7EADE42B7EC9FC4FD7A7DBFA784E4 +:1026C000BCFC657F570F6C27FDEBD2BFDD193713BC +:1026D000E27F3784C4EBD05F48DC8DF483CB389F36 +:1026E0001BADFC9EB1F473CB781ED95FE1D78CF89B +:1026F000C3A85546925F228D2C80FDCBB89D51D644 +:10270000E67C8C63185563A37BB589F0DD5C40F5EE +:102710005C2AA45BFE06F5F3827EF544317F28A790 +:10272000F9177EED213BEC28115780EDADBCDC871D +:10273000ED47A16D6108A5C49F9EC17BBB05413FCC +:102740003FD68FE0F503D85FDFBFC37851C17DD39B +:102750003BB6391FF975EF7936BA17BA717480DE56 +:10276000B322A313C065B2D49FAC222FFD79DB1333 +:10277000C98E3456ECF50C87E766C4A7DB62FF2CE4 +:1027800082F659466FB44F9608F9F93FC15B31E2C2 +:102790004DC253E245E251E223247E8AF0D01D5E11 +:1027A000F5F8D4E351E2AFF0EB205E10AE57E32D25 +:1027B0008857B4E7FEB3E06D8891BF5F66A9B1D2D8 +:1027C000BB683F84C77BDAD9F868A872CAE139854B +:1027D000E7BCF78AE308E6CBD9E8F1885A597EA12D +:1027E0009B72CFD7EDA6E8107CDF28F01D9F06F581 +:1027F0007B5C5D5FD693EF31C8FE077753FF9D305A +:102800001977E1B2E50F0BC63F2E2AE4F02F4A53A9 +:1028100009FE6373E7909CCC6C5CCE74C07FC89754 +:10282000C67FE7A6772DBF613BD073CBC6C76BE5EC +:10283000D3229DDFFA562197DEAA934BF572A5BFEE +:10284000BF902BD358DA8F7CAFF257FD89AF5EEB88 +:102850007B95FCBDD371629FA5083ACB70A86C2410 +:10286000D211F3D0397918DF3BCDC377417D94BFC6 +:1028700085F929BD8D05E87C9D008C18F3B733469A +:10288000F7C80F454C2CC5BB7163078FED8BDF4339 +:10289000DE656BC17D3A4FF5FC9B3DE45DB683E39D +:1028A0001C74BFF2A03583E42FDC87A6107BE0DB2D +:1028B000703EF585F3E3109C5F98BE05E7575F58BF +:1028C000EF6FE1FCC2FCAD394B18B61BEFD0C6ED83 +:1028D000C8F6B7D9C78262D23DFC6ECB7BB517C2B2 +:1028E000F79D98EC71683F7F27E6BA71B8DE776292 +:1028F000120D3CB598291DB8AF6F57F2A1DC07C186 +:10290000F1C6D3787AF84A78EAE128E1FB5F80E7FC +:10291000175DC1F394909F3BAC7F8C4A4A47FF5DA3 +:102920009478C7F277792AE4CFE0D492315EF50645 +:102930009AE7A8FA11CC3898FC36B908D71A2B8731 +:1029400097DE6EC5B6241A42E377BF307BBEC5F171 +:10295000BFDCA8D2BDF10B2F87913DEAB49FDBDB32 +:102960008A14CF77488F35AA6335BE3FCADEE1EFC0 +:102970009CB1EF0EA54E8AFC1174BA85DFB7AFB1DA +:102980008EEF128F529FFA0F878BF80813EF454A8C +:10299000B9A29785BF4B20DF2FEC4ECE1816CEF98B +:1029A000602F8B781741E015DA513E05FA19067C45 +:1029B0002EE5D170D22FEA7BB8E2070C0DDA113A7E +:1029C0007A45F891DF8E0A0CA077B98A8EAA144F47 +:1029D0007C50C477DD3CA0CE960E78BA29D3933ACA +:1029E00000D7A57EA7229F7917D61987F687A383DC +:1029F0006DA43FFE483D346B80E017792C4F735F28 +:102A00004DD29D6AA3F89D8E0FF87DBC856FF3B8FB +:102A1000CD853D548AFFD7C7C58D62598FA2BD7140 +:102A20006CBCC9E97704F98B7C07C89264608E108E +:102A3000393BCC11CE1C21F389C889D5E4239D3DB7 +:102A400035F5A387A76BCA635CFD35E57145059A2B +:102A50007C0FF7F59AFA89D3C668F2C99E5B35F503 +:102A6000532A2769F3B8EF00EEBDEB6668DAF5A9E3 +:102A70002FD3D44BF35569CA99CF752C2701F93858 +:102A8000FFCB58B55053FE7454118F1FB7CDA67BA2 +:102A90008A994D3FD3F427F19B12C7F1CB1CFC7CE4 +:102AA000F0C17FE4B710782E4CD29E1B63EDA30FCC +:102AB000DB29D5DA35527E200E6ACE7F950E6A99D3 +:102AC000960EE2791C4FE1DB831D28C7E8F18FFEEB +:102AD00088D075A23F22142EE88F08CDA33F22B4E0 +:102AE0003EFA2342CBD11F115A3EF8A816FF438F5E +:102AF00069F17FDD4763FE533C8D68D5D2831E4F5D +:102B0000379CD6D2C7284F38C1652CC86348EF120E +:102B10004FD3E03F3AE7993B1AED06373117DD0B0B +:102B2000F89FC2D7333A7C7DC3560FC5772E2F79D5 +:102B3000391FEFEE9C7FA28FEB79E41FEF0B3EAFC6 +:102B4000B703C87852DF188E4FDFF130E257DF1A33 +:102B50005A23F1FCF8A9DA4A76F964D6FE16BE3F8C +:102B6000638AF7FC1AF95822460F40F95373EFCCE9 +:102B7000C7736EE6BF585251AE99D987BF27C87246 +:102B80005BE99D16399F99293CFE68DF00C1A79D2E +:102B90003C0EE9B5015CBE8E74DA290EDA9BCB449B +:102BA0009C274B9D3910E9F0DDB06CA4B375DCCEE9 +:102BB000D56A72505C8B0FE811FD94286FA33CDC42 +:102BC0005BC8A38D1F5BAD9CEE98E67CEFE7B76A10 +:102BD000E270076CB76BF2039B9334F507ED7768EF +:102BE000CAF303399AF2C1479D9AFCD063C335F505 +:102BF000AFFBC8A5C98F682DD2D4BFE1B45B934F9A +:102C000061ED4F223CBF1A90CEE3FB156107707057 +:102C1000BCCCFC6902DDA7917A848CCBF6083AD64D +:102C2000EB237DCC1E8AF36E4C664EBA0F6215FA0A +:102C300020D3EA291E11572DE579E6D3C655CB7866 +:102C4000EA4E7D46E82F529F0889A776E1FC653C55 +:102C50007527DEC5FB927AFAFC87C0BB7E1D7DCC52 +:102C6000FCFE57E3FD66BAC722E7A79FD7CD221E19 +:102C700070ABB5EBF7876CB9DC6EF068BADB980B1C +:102C8000F59E85E389E079D578CE561FC0B7F1E788 +:102C900066E752C70F8F3773105F4F29BEAB9A4B51 +:102CA000EF74D2BD35396EAF5C4EDF863CA5CBF5F7 +:102CB000CD8CE6F15D2CDA4CF72EBA1F8FC335C9E7 +:102CC000CC96D13B49E21EC2DDAB9BD7606845A9DB +:102CD000B9C9C4DFD5F79BD04E543C06E4C07CE0B4 +:102CE000135B77AEB381BCF66CBD91EC3E19B9F1C4 +:102CF000778204D979AFA40FE8694827C5887FE8AF +:102D000077C3401EEF3C2E97AFAF50FDAEF33E8031 +:102D100045C3E7B9FED705DD113DCA75FC6FDD0F70 +:102D200090F4AB8793D4AF9938BFFA8A7949F87594 +:102D3000DA4F04FCE4FD0CC702937BB38DEE7914EB +:102D4000615C99C4DF4B03395DFE04E13194D743E4 +:102D50007ED45DBD4235371AEDE01DCC116DFF010B +:102D60007BF0FFD2BD09827F77F7BDBAE31357F13D +:102D7000876EEE7F75479FF4F723EE8185F0091E7D +:102D8000EF23F0E1EF6B20BFFACA48ED3EDE9ACBAD +:102D9000E17BABD84F706EDBF2B57C82A15DBF7179 +:102DA000B92AF8C4ECCEDF9FC0EFB3969B48BE664D +:102DB000CCBD1EE30C3E5F67A2B8D8512E46724CC4 +:102DC000D946C5BF49C173746412CEDFEBD39EC729 +:102DD0003731E70AF47F94AFD27E9F63E3BF53316C +:102DE0004BFF6E8AD0D7E7FC80BEBE3E579CE34EB9 +:102DF000E624B94BF8FF2B451BBDDCD5E1E77E335C +:102E0000D4B7556E77A2B83179BE3BD07F13F21E8E +:102E100008C0333C07CFF165C62EE3F93AE1D94D3E +:102E2000BCC2799B8857B0F1F88C8E3D61DCBF291C +:102E3000FD4AA2FE79DF652AC7FAD8DB857C1E77BA +:102E400021FD497A7F5587CD40FE968E3D91E49FC6 +:102E5000473F4E34D0C159C3EE84E169C1F9795A74 +:102E6000558D1F449F7A96BC42FA62628627908BEA +:102E700071D846A7D509F9876C07E9FDA86261F703 +:102E8000D2CFB753EF1AC9DF77E9F07179B6A388CB +:102E9000BFC3017C91E13E927108250CB45448BD3A +:102EA0008111349F1FEBCF997C259FFB31AFDC4014 +:102EB000ED3DAB4650BECFB2350BF01ECC1D8D7331 +:102EC0004CE8C26E7D72716138346DEDED5F1A8E23 +:102ED000781BAD7469976F13E759AB2EBE5EA625BC +:102EE000821FCD1B28F9B888435AA2D03E58A8307B +:102EF0001997447C5CE62F37897C21CF2F5ACEF37B +:102F0000ADE27DFD6DC28E82EBC614D78D7AFF0EC9 +:102F10006167C175638AEBC6EFC8B7308F7C0BF36E +:102F2000C8B7308F7C0B53E45BF8BD8CB953F355B5 +:102F3000EE871A17BAEFAE58D9B890FD827EA8D0A6 +:102F40003CFAA142EBA31F2AB41CFD50A1E5E8877F +:102F50000ACDA31F2AB43EFAA142F36CF82DC13C5E +:102F6000F2395789263F19E4FC7121FB1BFD50A162 +:102F7000FDA31F4AD39F6781A6FD5DAC5ED31EFDF6 +:102F800050A1F5EFA957347EAA7BC43BA7E51BE20D +:102F9000887E221DEED48180E77F8BF8C77DA674E2 +:102FA000C473CB5CAE97853B399E9B8A38DE0D8C13 +:102FB000E3B97D3AE179B199E70B797CB29E7ED095 +:102FC000DF33CEC4FD3D98A2BF0753F4F7608AFEFD +:102FD0009E7199DCDF8329FA7BF03BFA7B30457FD9 +:102FE0000FA6E8EFC114FD3D98A2BF0753F4F760A8 +:102FF0003BF4F7608AFE1EFC8EFE1E4CD1DF83DFA1 +:103000008FA3DFC9149C17CAF17D35FA23D0A146DE +:103010007FB46BF228C787D647393EB41CE5F8D099 +:103020007294E343F328C787D647393E343F33D7FA +:1030300041FB0BE5F9D07628CF87E60736F9DE426B +:10304000DBD9848D170F63DA1AA93CAB00CBB867C4 +:10305000E74B771A413E6B0D53526380739A94DDB0 +:10306000778E83BC47C4FFE5B17603E2DB23DE53F2 +:10307000F70418C55B0EFC5B32953F23EF87E11F19 +:10308000E03D7F0FA3DF2591FE62D9DEC9EC2AA6C1 +:10309000B27E30DF753DFDF8B21EF1CF9079E00DC4 +:1030A000608C57C95F6C2BC078CF6D0685E224B663 +:1030B0002DE571C27ABA7A6C20F78B6E33EC3E88BC +:1030C000F740DABD0ADD07CE32B2A3A60284535D13 +:1030D000019EBF0F0C8C117EBEBAEBF1BE899CB76E +:1030E000B46F029FA0FB7323DB8F8D8D867E3CBE69 +:1030F000D1F43B29C5662E37603BD42707F814D797 +:10310000E610FA5E3E90F34D8F8F8FFFABE726F20D +:1031100076E1BCDDAF9E8B22384E5CA650BCD4C895 +:103120001DCC85F7737F21E63D604740C5F1BCCBE0 +:10313000F878B25FEFC654BAB7E865ADE392C84716 +:10314000A230E4DB126EB0BEC3B83E501B8EA27D2F +:10315000FA5AEFFDDC3824A610E3E8580BA3772CCD +:10316000270C795FB35E42FB30EA97CEB56C9F4285 +:10317000EF054FF42D598A6431C1B7E0AD1E587F79 +:103180000B73A639E828A27BB1723EFD5DBB0D70C2 +:103190002CB25C76CC10A620BED9A1B810FA819DC5 +:1031A0003F05F19DEF34D1FBBD2546BB89DE8FE89D +:1031B00026FEE4B24DC69FE8E4055D9C49E3E28F3C +:1031C00052D19EBC30D240F6DF85AFF0DF03F06C09 +:1031D0005088AF4939C82BE2D42E2F7BABC754841B +:1031E000FB6E13F527E34F6A33FCA9068CABEFB9EE +:1031F000292F562539E000F2C373BEDFDC391CEB02 +:103200002DE7EF585E5E764774807AE2FE9A0A01F7 +:10321000AF0A11C7E4C507BDD5E0EF69C9FB1DAC16 +:1032200089CB7BD29EE3FDDDE023885FEF33E25D57 +:10323000E9555EBA97AD8F239ABBCC44714773753D +:103240007261B5900BAB7F402EFC78A04E2E94BFE0 +:103250009722DA30B5D78718B727EF25969AF8FE68 +:103260002FDDCDC80E5BBA64AC81DE417E85D34DC7 +:10327000E9122EDF94BEEAA2FB85525E7C4FC83174 +:1032800093AEA410DCFF28E4963B30BE12E05BDC7A +:103290001A26E2B092299D7A85C75B4EB2713ED064 +:1032A000FA067F07A2C367E1F2D461C6DF31D3D14A +:1032B0006589D16FC00B77CE914097909F80721037 +:1032C000F4370DE5A238A4F3B4428ADF2B52E8DECE +:1032D0008B9ECE8B4D756F617C68F156E6F4B150D4 +:1032E0003A07FAC5FE7C0ABD0FE0117AADA45F3D36 +:1032F000BDCF8C10F6281BB73775DA255046C54769 +:10330000BA7DA6A918FF3A137D7B3D39C160DC590F +:10331000642E2F8FDB659ABA0CEF2A7463A7507F57 +:1033200066267878E43B08DDD80DD05E807CF2EE2E +:103330007BF3CD65217CF2E4A0318307F508E2BB85 +:10334000ACF3BE5F2EBD0BBAF0A14CFA3D9CEEE48F +:10335000E172802BEE8B99D1ADF7E12FB315E431FB +:10336000D7B824FC7D41261F210F601CE10C91BFC2 +:10337000272FEFCFAB6C0417CAE7ED8A9B8A712128 +:10338000B5D6D6F14876F3733D45788F31C89FDCCA +:10339000AE1405F9537E0075C29BB3F83D2FBD3DB9 +:1033A000E29E3C5E5F6F9728CFE57C5BFE2ECA896C +:1033B00087F6EDC2F34ACEFF4437BFC330358FCB1B +:1033C000B3FF53F720F4F71F66F5F414E5C17CD77B +:1033D0001BF87DFE9E6A1313F621F20B4B7EC1C4CF +:1033E0003B1841BCBBE81DDDC687147BA87DCAB372 +:1033F0004AE1F7E8BBB1E3B09CF627B742BB990DB1 +:1034000066FA1DBFE7B238FD3C07F443BF97623E42 +:10341000F696352D08C74FEB7F69A2DFA561814C79 +:103420007C7F67465D9813F9F1C941EE9938EF88C2 +:103430005C27F1A1C183387D65C4BBBD7978FF6E7F +:10344000F58167F13D81F92D69F47B25DEFDF92BCE +:10345000F09D9393833CB3B1DC6BB3D37B1AF396AB +:10346000C5D0F9353351DC0B65EDE46793F07F305F +:103470008FEB89D73999F8BD2D71DF01186489A6C2 +:103480009E88EFD6ED0F6927D4DB19F4EF4B7467F4 +:103490005F90F604B41F9843EC8CD23E61CA393178 +:1034A0001DE58652B3F65EA24C7F2DE62FF5C0597E +:1034B0009DE756EEF844948FD72A767A6FD2E69835 +:1034C0003A02F215474D18D9C98A631D667C7FA060 +:1034D0001DF08BF1D165B05F91CF948A38AD8A0D24 +:1034E0002368BF55F821EDE21D4E99DEB5F650EF89 +:1034F00057917E022EF25B56D85DE6D8907D5FDE56 +:10350000A468DE1D90F9E7F2545A672988E308BFE2 +:10351000BBEF4D33E3DB3EA5204660FCDFAF057D0E +:10352000C876508FE2418AD3D911FE0E3CCC3B8D38 +:103530008F5710D27F5913BF372DF3509FE49F1739 +:10354000F222A93FAF1DD69D86A99DE609702038BD +:10355000B5AF81FE1C340EE1A33CE037A1BE5D8A0D +:103560007128909F61F79B709CB265FC1D13CF6A18 +:103570003E8E67558C7920CA4746BBB937C22F9C0F +:103580009F57303F92232B002E781F0BEFBBE1D9C2 +:10359000A2878F57CCB7A22986DE51087E5F6B4287 +:1035A0007C4CEFE65D844F05DECB968DA6FBEB15DC +:1035B0004617DD73F008F87EBE20EC61F40F4C5F17 +:1035C000F784290DFDF882CF7C2AE05A9C1EC8A4FE +:1035D000F78A168439719ED3ED4DB4BE4EF83E0E77 +:1035E000F050F09D1B37C117E8C287717B15EBB413 +:1035F000F80CCE87C3B7629D97F6DB6CA3C76C0F40 +:103600009DC786039978AF6A3AEC6F7C5782D93DA3 +:10361000745FF28BC7A7A6D23A619E08D748A7630A +:103620003CBE3F0474C2EFC188F5C87BDD72BCCBE1 +:1036300079FC1EFCE51FDC972E926B1A01BF68F720 +:10364000EE6E5F9A9171C3B8E60AFE3B12FA7D2ACC +:10365000F7A7DC97729FCAFDFBACC91D4852827C5C +:1036600006CED9BA97BB80D3E0411C0F33045E016C +:10367000AE8743EF79F51AC4F15A9AAEDDEFD81F41 +:10368000F66B95E5630299F82E93AC2FC72D8DE567 +:10369000ED90EE91DEAC830C9DF517527DED3D95DE +:1036A000F24E7EB1637902F28BDD0AF783AE39D434 +:1036B000FBA728BFEEE4F2EBB99AADF3F0BC644689 +:1036C0007F6AE8FBFEB340CE413E315B9CCF158163 +:1036D000AEF9C553599EE44121FBB9E2B19D591E93 +:1036E000CE6F02C86FFEB2F3F53F5DEF089EA77282 +:1036F0003D65ABDE37796DA1F0E37ACEC3391D7439 +:103700001FAFDC667660BC73F9322FF15F960472EE +:10371000A112127FA6A30BEF3285EE9195D70FF37E +:10372000ABFF837CBA7C7509BD7B20F126DF6791F6 +:10373000E7AB9CFF4831FF9B06F1F633047DCFA831 +:103740001C6D4E8E27B91BC32CD974F17D7A85F67A +:103750007B27DE3AFDD7B92B70BFE0FD22D24F5652 +:103760009BB8BD6F07B73F9E5BB8EFF77742BDB31D +:10377000EB37A532558B379453670B79758EB0FFB5 +:10378000758137F7A090389E39CF71BC95EFFADD7F +:1037900067F89E5869BAE0776BF83B0065CDBB09C6 +:1037A0008FD357AD35A5213F1A94A6E1E3E575F90E +:1037B00076B42BCF58B5C9847CC223E1A0DB0FA51A +:1037C000224E58C219CF2525C4BF21EB237FC4F751 +:1037D000EFEF5D101685F13C729C87049D97D7C56D +:1037E000C4E278E575DE5FA03E24CF03FD3A4F8644 +:1037F000F1FD5206FDE1BE3D39DA99BA303728CFE6 +:10380000EAEBFBC4BE7BDAC47FA72625A2F9058AB2 +:103810006B981FEE44FED1B76FAB1FC745FAC67950 +:103820009B0DFC776DFAD6B47E85F3E8CB785C0D02 +:10383000A6F83E16FA171220BFD9C0EF6FA5AB3C11 +:10384000DD26E003E5012C67F1ADF4FB1A2171B32D +:103850001AFA35B32DF4FB89E67846EF9B497A9541 +:10386000FD487A95F4DCDDFA9EBDC6F59D4CE3F08B +:10387000348BDF4DB9E6F559F8EFE8CA75C9F9811F +:103880000CEFA2F73D1E1848F69E934B9CA91837E3 +:10389000D9FD7AD7152674B15EFD3AE5BE91B1F037 +:1038A0009DFEAC26EE7738A9C0F906ED4E2E08A392 +:1038B000F836B9AE1F6B0F3F382856D8775A2351C8 +:1038C000CE2C0D0FDE9747F81DAFE7BFAF2BBF4BD8 +:1038D000B940BE3327F9F7A93A716EB2D635B8BFF1 +:1038E000597D06BD7F72BCE96424BEC77272349FE5 +:1038F0009F6C77AF89DF4F66916607DE138BB8F751 +:10390000FDC244F40FAD4BCB57A0DDDDF5838FE353 +:10391000FBE3772F4B24FD7E96CDB102CFC559BE78 +:1039200034F20747ACCBFF02DFD19BB56C00FD6ED4 +:10393000EFBD0A73933E29F484D9ACF38FF4843934 +:1039400082AFCD417E89F7A5EA0FD1BB79B39D61E6 +:10395000F978BECFD9C0F58462035B85FEC43E8D85 +:10396000EEF1C8C7DA9F54F8EF3E6FD4BEC3959C02 +:10397000EDFE0CF98CFEDDBB7B4DCD2E5C07037993 +:1039800004ED4EB36C6E92EB4B05BD1C5FD746BF8A +:103990009789F0A6DFCBD1D96FFA98F93DE2F648C6 +:1039A00003D9E300EFEFE1EF91E17BEB163A6FB45F +:1039B000F69B3E0F0EA7DF6B93F7842A84DF49D274 +:1039C0008FF45FCDDA3499EE0FCD427BCDE0E0FD90 +:1039D000A915EBC6D2FB4E156B0BD7E3EFDCA40A9F +:1039E000389E32B696207E4E6F4A8CC57BB915B58F +:1039F0008D59785FA862D34ABA37747A5318DD1BA1 +:103A00001A672F1987BF1F327B23BF9F27F7A3CDCC +:103A1000C9F76355ED58BAF7F3FF00B910AD8C0044 +:103A2000800000001F8B080000000000000BCD5636 +:103A30005B6C1465143EFF3F7BEFECA5ED527AA161 +:103A4000EDB6E5B2EAB69DA51403189834802412A9 +:103A50005D0805368176088114686B4593164364CA +:103A600061951088711F5AA104CC52A1BEA8D986B5 +:103A70004621AE66A541A236B18117129266FB526D +:103A80002E11BB564D69A2E039FFCC660997C44799 +:103A9000E7E5ECFFCFB97FDF39B3ED0F473EF1D457 +:103AA00000ECAA02F02C01F82B91178F3080F6431E +:103AB000972A240E10B06A56650EC03E9EDCBCCC20 +:103AC00007708FC5074B84BE6FAE47067844CFAAF8 +:103AD000A7E5E421009F15A0E3BD9BC2CF7D3EFA80 +:103AE0007A18EDDB3B2EBAC8CFBEBE1B4B3D783FEC +:103AF000B7462B541AC9EFB9418F0400A7CED5851C +:103B00006A01BC0AFEC6FBF505A1CD61CC2BF3A36F +:103B1000A40CF89E1FAFED1226DD903B6F8FBB2DDE +:103B20001000D05260F190F480A500E51D097A12D2 +:103B300028D75743EB463977BF48417BACF38E3BE0 +:103B40005611C2FB3D83272B7C28EF3AF5F3B6C113 +:103B50002D3F810BF5CF5B2D407626B02868B7331B +:103B6000C2D4384A682B0028C9C50F2A7922FF3DE4 +:103B7000A730A9C2DC3D405CDCDF35C13ACAA332C4 +:103B80009A09BE85F29629B50BB0CE5B5D7625828B +:103B900058C88A4FE4732B26ADA5FBC83B0C1630E2 +:103BA0003A5F74CEC7F82D6EE8227BE792448A7B99 +:103BB000B1CFC3F98BA97DF8702802E8F4E8873506 +:103BC00092BCB60CDFEF1F621E2BBADC7FF9EA5AFB +:103BD000D0CF00ECF9FDDCFB6005F81ECB7BEFF0ED +:103BE00090C587F1DA3FC77A317E7B62E88752F46D +:103BF000D3796947831E3706B014F3A09F18A773C3 +:103C000058EF4BC7F084656720E76787BFE0681906 +:103C100062BB29D1B8A50FF576106ECB910F752F29 +:103C20006C3D6C22E911FD0153A622E40438EEBF7D +:103C30006ED1C8CFFB863FFFF5A3D5A2DE0D85F080 +:103C4000181F9A15B3B0CBDA633F845DAAC3710C19 +:103C5000EA01D44ED94432DA21BB489EE9E27E1310 +:103C6000F655650E45C27EF7D85C75E00698B1EB57 +:103C700032E9D065370F0DEDC61467F8981D90F73F +:103C8000DD528C915C15E862D869307BB57D341FBC +:103C9000C59060201A916294F7D4B7B71B28FECA6A +:103CA000CAF41F802999D9CB5B57233FDE568CFA83 +:103CB00002E906E2F99C2BD04AFC3A6B8663F6C512 +:103CC00054770836D69217FC4DB8CFF2F805CC2FB2 +:103CD000C9529F92FF6CBD9F115FD14FC82A1F63CD +:103CE00098E79F95DA41CAE30D66AE0D72C2405A5D +:103CF00040FEA7CCFA7B889D546DC88B269D16503C +:103D0000CE210248594B69B14CBC66AA0A3D18FF46 +:103D100048E0CA4EE2C7898C0DAC18376AF4A32973 +:103D2000E39860A8575EBA8E431DEAFBBCB00DED68 +:103D3000AF0478C48A799E005B9CF4C1B6464DFB03 +:103D4000F5188FAAD13FB7AB423F796D96A12C935E +:103D50007E1F71A37E593753A2A8D3323D79F6173F +:103D600094DB201EA4BEAEF66A7DB40FC6A7D74D65 +:103D70006888EF094FC2467346CFE3F9270FCCBAE4 +:103D80000A782EAFA9CCE4175F2F21695318DA35D2 +:103D900025A594B5EEE97CA68A7D268A837A294EEC +:103DA000FA328F3346FA233729BF269B9C925C64F4 +:103DB00067FE356DCBD9C15879FEE44B20207E5487 +:103DC000065014D5715B69CC611697CB0A17B85CA5 +:103DD00036F0C9F64F248FF3B1DFA6CFC777F2E0F4 +:103DE00076E24F765EDF34EEA71F54BB69BF4C27E7 +:103DF0006BDC1078FE7CDEC0FD0A8B005EAB52BF30 +:103E0000A77EE1A3DAD07FB3D11FC41BC8AF64F88B +:103E10006D36FAD42C73BD2F9B9EE88BC1932C0F6B +:103E2000B2796771CEE207EF8E5D755709DC6A3FA4 +:103E30000281D7CFC4BBF1D9D10F70ACA0545227A7 +:103E4000B4AAFF235E29FB22E475A68F2B03C47F4F +:103E50006AFC6221558EF5811FC43E68911CCAF12F +:103E600067EC038DF6413DED839898F3199EB9CA2E +:103E700019ED832E712E86CC61139EC779DA49F92C +:103E8000A6EDC87A94EE60B5D8E36534D1353A4EE4 +:103E900034D7670F38078EA37E94A9FD36B48F9A66 +:103EA0008D79DF23C72FE0FD549C47CC18AF373FF7 +:103EB000DEBF1BEF7B9BE72911ECD314187A6D0E44 +:103EC000B11756702ECE9970517CA08AF471AEB1A4 +:103ED000CEDEF08BE23BFED543744E752F00FD7DA8 +:103EE00010169EA2F71BFCC2DF37D93DF3A153F891 +:103EF000EBDDA09638C4FB224EF6870B357BB091E4 +:103F000070D5F5F08F80D03B7D5A2D213C4E6FB49B +:103F100008BD8F5928BC8BFCD4CACA05F49B0E3B44 +:103F2000BE1CD4E14831BC1FEFD1EBCDF2F7D585F3 +:103F3000FA1EAC8C4CF403B628D204FE2EE4FD38F5 +:103F4000F1B03E870F53118B821C4E593E46CC88F0 +:103F50009757C7EB087B1A2FAF8117EB41DEBA08E2 +:103F6000B784E8FF0CD771E896209D8735495C2916 +:103F7000B6A21CF36AF3F53AC74AE87D8B35DD1823 +:103F80000B109ED09678C61CD6D3929D23EA63343C +:103F900067AD06CF5BB37C3CF8041FD3F3F227F385 +:103FA0000C3EA2FD4D472848F1EEB31B4BE972F4DD +:103FB0001F69EBB3E22C0FEA7BE437ABB68CF4E17C +:103FC000FC5C2EF688479FEBD1E0ED72FACEC0DFA5 +:103FD00023F3E8BBD35F187A85F4ECF333168DFA3C +:103FE000599231533DE3E17BE5F47FA6B5E79A981A +:103FF0009BFF9AE7BF3AB4AF4B200A0000000000D5 +:104000000000000000000000000000180000000098 +:104010000000000000000040000000000000000060 +:104020000000002800000000000000000000001058 +:104030000000000000000000000000200000000060 +:104040000000000000000010000000000000000060 +:104050000000000800000000000000000000000058 +:104060000000000000000000000000000000000050 +:104070000000000000000000000000000000000040 +:104080000000000000000000000000000000000030 +:104090000000000000000000000000000000000020 +:1040A0000000000000000000000000000000000010 +:1040B0000000000000000000000000000000000000 +:1040C00000000000000000000000000000000000F0 +:1040D00000000000000000000000000000000000E0 +:1040E00000000000000000000000000000000000D0 +:1040F00000000000000000000000000000000000C0 +:1041000000000000000000000000000000000000AF +:10411000000000000000000000000000000000009F +:10412000000000000000000000000000000000008F +:10413000000000000000000000000000000000007F +:10414000000000000000000000000000000000006F +:10415000000000000000000000000000000000005F +:10416000000000000000000000000000000000004F +:104170000000332800100000000000080000333069 +:1041800000100000000000020000332800100000B2 +:104190000000001000003A78000000000000000855 +:1041A000000000000000000000000000000000000F +:1041B00000000000000000000000000000000000FF +:1041C0000000000000003120000000000000000896 +:1041D00000003360000100040000000100003368AB +:1041E000000000000000000200003370000000002A +:1041F000000000080000337400000000000000020E +:1042000000003A70000000000000000800003A4082 +:10421000000800000000000800003D880040000089 +:104220000000004000003A500008000000000008B4 +:1042300000003A60000800000000000800003A8812 +:1042400000C800000000009800003C180098000022 +:104250000000002800003C580098000000000028E2 +:1042600000003378036000300000036000003EB0BF +:10427000000800000000000100003EB1000800003E +:1042800000000001000020080010000000000010E5 +:1042900000002000000000000000000800000000F6 +:1042A000000000000000000000000000000000000E +:1042B00000000000000000000000000000000000FE +:1042C00000000000000000000000000000000000EE +:1042D00000000000000000000000000000000000DE +:1042E00000000000000000000000000000000000CE +:1042F00000000000000000000000000000000000BE +:1043000000000000000000000000000000000000AD +:10431000000000000000000000000000000000009D +:10432000000000000000000000000000000000008D +:10433000000000000000000000000000000000007D +:10434000000000000000000000000000000000006D +:10435000000000000000000000000000000000005D +:10436000000000000000000000000000000000004D +:10437000000000000000000000000000000000003D +:10438000000000000000000000000000000000002D +:10439000000000000000000000000000000000001D +:1043A000000000000000000000000000000000000D +:1043B00000000000000000000000000000000000FD +:1043C00000000000000000000000000000000000ED +:1043D00000000000000000000000000000000000DD +:1043E00000000000000000000000000000000000CD +:1043F00000000000000000000000000000000000BD +:1044000000000000000000000000000000000000AC +:10441000000000000000000000000000000000009C +:10442000000000000000000000000000000000008C +:10443000000000000000000000000000000000007C +:10444000000000000000000000000000000012C892 +:10445000008000000000008000000001000000005B +:1044600000000000000040000490000000000490E4 +:10447000000019C8000000000000000800004948C2 +:1044800000080000000000080000492800080000A3 +:104490000000000800004938000800000000000883 +:1044A00000002008001000000000001000002000A4 +:1044B00000000000000000080000401004900040D0 +:1044C00000000040000049980008000000000001C2 +:1044D00000004999000800000000000100000000F1 +:1044E00000000000000000000000000000000000CC +:1044F00000000000000000000000000000000000BC +:1045000000000000000000000000000000000000AB +:10451000000000000000000000000000000000009B +:10452000000000000000000000000000000000008B +:10453000000000000000000000000000000000007B +:10454000000000000000000000000000000000006B +:10455000000000000000000000000000000000005B +:10456000000000000000000000000000000000004B +:10457000000000000000000000000000000000003B +:10458000000000000000000000000000000000002B +:10459000000000000000000000000000000000001B +:1045A000000000000000000000000000000000000B +:1045B00000000000000000000000000000000000FB +:1045C00000000000000000000000000000000000EB +:1045D00000000000000000000000000000000000DB +:1045E00000000000000000000000000000000000CB +:1045F00000000000000000000000000000000000BB +:104600000000000000000000000040000018000052 +:1046100000000018000043000040000000000040BF +:1046200000004300004000020000000100004301C0 +:1046300000400002000000000000300000400000C8 +:10464000000000400000000000000000000000002A +:1046500000003000000800400000000400003004AA +:10466000000800400000000400004B00002800008B +:104670000000002800004B50001000000000001057 +:1046800000003800008000000000008000003800BA +:104690000008008000000002000039000020000037 +:1046A00000000020000020080010000000000010A2 +:1046B0000000200000000000000000080000510879 +:1046C0000008000000000008000051200008000061 +:1046D0000000000800005130000800000000000841 +:1046E000000051C00008000000000001000051C19E +:1046F0000008000000000001000039400010000424 +:1047000000000004000051D000300018000000102C +:10471000000051D800300018000000020000000026 +:104720000000000000000000000000000000000089 +:104730000000000000000000000000000000000079 +:104740000000000000000000000000000000000069 +:104750000000000000000000000000000000000059 +:104760000000000000000000000000000000000049 +:104770000000000000000000000000000000000039 +:104780000000000000000000000000000000000029 +:104790000000000000000000000000000000000019 +:1047A0000000000000000000000000000000000009 +:1047B00000000000000000000000000000000000F9 +:1047C00000000000000000000000000000000000E9 +:1047D000000000000000000000000000000023E8CE +:1047E00000800000000000800000000100000000C8 +:1047F0000000000000002008001000000000001071 +:1048000000002000000000000000000800002DA0B3 +:10481000000800000000000800002DB8000800009B +:1048200000000008000024E802D00028000002D0A8 +:1048300000002E58000800000000000100002E5962 +:10484000000800000000000100002D90000800009A +:104850000000000800000000000000000000000050 +:104860000000000000000000000000000000000048 +:104870000000000000000000000000000000000038 +:104880000000000000000000000000000000000028 +:104890000000000000000000000000000000000018 +:1048A0000000000000000000000000000000000008 +:1048B00000000000000000000000000000000000F8 +:1048C00000000000000000000000000000000000E8 +:1048D00000000000000000000000000000000000D8 +:1048E00000000000000000000000000000000000C8 +:1048F00000000000000000000000000000000000B8 +:1049000000000000000000000000000000000000A7 +:104910000000000000000000000000000000000097 +:104920000000000000000000000000000000250062 +:1049300000400000000000080000250800400000C2 +:1049400000000028000009C001200010000000083D +:104950000000000000000000000000000000000057 +:1049600000000000000000000000402002D00028ED +:1049700000000008000030000000000000001000EF +:10498000000050990000000000000001000050B03D +:104990000000000000000002000045A00090000898 +:1049A00000000008000000000000000000000000FF +:1049B00000002960000800000000000100002961DB +:1049C0000008000000000001000029700008000439 +:1049D0000000000200002978000800040000000424 +:1049E00000002FB0000800000000000400002FB4F9 +:1049F000000800000000000400002FC000000000BC +:104A00000000000800002FC800000000000000089F +:104A100000003000000000000000001000005040C6 +:104A20000001000100000001000050000000000033 +:104A30000000002000000808001000000000000432 +:104A40000000080C0010000000000001000008B782 +:104A50000000000000000001000008B60000000097 +:104A600000000001000010000030001800000004E9 +:104A700000001004003000180000000400001008BE +:104A800000300018000000020000100A003000187A +:104A9000000000020000100C0030001800000001AF +:104AA0000000100D00300018000000010000100E82 +:104AB0000030001800000001000010100030001845 +:104AC0000000000400001014003000180000000472 +:104AD00000003000010000800008000400003004E5 +:104AE00001000080000800040000000A000000002F +:104AF000000000000000306801000080000000019C +:104B00000000306901000080000000010000306CEE +:104B100001000080000000020000306E01000080F3 +:104B2000000000020000307001000080000000045E +:104B300000003074010000800000000400003066B6 +:104B400001000080000000020000306401000080CD +:104B50000000000100003060010000800000000241 +:104B600000003062010000800000000200003050B0 +:104B700001000080000000040000305401000080AB +:104B80000000000400003058010000800000000414 +:104B90000000305C01000080000000040000307C58 +:104BA00001000080000000010000307D0100008055 +:104BB0000000000100001C180010000000000004AC +:104BC00000001C30001000000000000400001C3831 +:104BD00000100000000000040000000000000000C1 +:104BE00000000000000000000000000000000000C5 +:104BF00000000000000000000000000000000000B5 +:104C0000000000000000000000004C100008000040 +:104C10000000000200004C1200080000000000022A +:104C200000004C14000800000000000400004C20AC +:104C3000000800000000000800004C3000400008A0 +:104C40000000000800004C00000800000000000206 +:104C500000004C02000800000000000100004C04AD +:104C6000000800000000000200004CD00008000016 +:104C70000000000800004CE00008000000000004F4 +:104C800000004CE4000800000000000100004CF0AF +:104C9000000800000000000200004CF400080000C2 +:104CA0000000000200004D000008000000000004A9 +:104CB000000050000010000000000004000050043C +:104CC0000010000000000004000050080010000068 +:104CD00000000004000014000008000000000002B2 +:104CE000000014020008000000000001000014048D +:104CF000000800000000000200001410000800007E +:104D0000000000020000141400080000000000026F +:104D1000000014160008000000000002000019B88E +:104D20000008000000000008000014200008000037 +:104D3000000000020000142400080000000000022F +:104D4000000019C8000800000000000800002C1036 +:104D5000000800000000000100002C110008000005 +:104D60000000000100002C120008000000000001FB +:104D700000002C13000800000000000100002C00BF +:104D8000000800000000000200002C0200080000E3 +:104D90000000000100002C040008000000000002D8 +:104DA00000002C30000800000000000200002C323F +:104DB000000800000000000200002C340008000081 +:104DC0000000000200002C2000080000000000018C +:104DD00000002C21000800000000000100002C222F +:104DE000000800000000000100002C230008000063 +:104DF0000000000100002C24000800000000000159 +:104E000000002C25000800000000000100002C26F6 +:104E1000000800000000000100001400000800006D +:104E20000000000200001402000800000000000161 +:104E3000000014040008000000000002000014122A +:104E400000C00018000000020000141000C000188C +:104E5000000000020000141C00C000180000000840 +:104E60000000141400C000180000000800001427FF +:104E700000C00018000000010000142400C0001849 +:104E8000000000020000142600C00018000000010D +:104E9000000015900008000000000008000015A0A8 +:104EA0000008000000000008000015B00008000025 +:104EB00000000008000000000000000000000000EA +:104EC00000000000000000000000000000000000E2 +:104ED00000000000000000000000000000000000D2 +:104EE00000000000000000000000000000000000C2 +:104EF00000000000000000000000000000000000B2 +:104F000000000000000000000000000000000000A1 +:104F10000000000000000000000000000000000091 +:104F20000000000000000000000000000000000081 +:104F30000000000000000000000000000000000071 +:104F40000000000000000000000000000000000061 +:104F50000000000000000000000000000000000051 +:104F60000000000000000000000000000000000041 +:104F70000000000000000000000000000000000031 +:104F80000000000000000000000000000000000021 +:104F90000000000000000000000000000000000011 +:104FA0000000000000000000000000000000000001 +:104FB00000000000000000000000000000000000F1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE00000000000000000000000000000000000C1 +:104FF00000000000000000000000000000000000B1 +:105000000000000000000000060022000000000078 +:00000001FF diff --git a/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex new file mode 100644 index 0000000000000000000000000000000000000000..54f36f1d256de440273866c2e126798398bb3d0c --- /dev/null +++ b/firmware/bnx2x/bnx2x-e1h-6.0.34.0.fw.ihex @@ -0,0 +1,13178 @@ +:1000000000004F48000000680000070C00004FB8D7 +:1000100000001ED4000056C800000094000075A027 +:1000200000009EFC00007638000000CC000115386E +:100030000000DC6400011608000000940001F2706A +:10004000000040180001F308000000A4000233285B +:100050000000F378000233D000000FFC00032750AB +:100060000000000400033750020400480000000FA5 +:1000700002040054000000450204005C0000000679 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000020400CC40100000D0 +:10010000060400D000000003020400DC0010000020 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000020400EC4214000053 +:10013000060400F000000003010401240000000098 +:1001400001040128000000000104012C000000004F +:100150000104013000000000020401D00000890603 +:1001600002040004000000FF02040008000000FF79 +:100170000204000C000000FF02040010000000FF59 +:10018000020400140000007F02040018000000FFB9 +:100190000204001C000000FF02040020000000FF19 +:1001A000020400240000003E0204002800000000B9 +:1001B0000204002C0000003F020400300000003F59 +:1001C000020400340000003F020400380000003F39 +:1001D0000204003C0000003F020400400000003F19 +:1001E000020400440000003F020404CC00000001AF +:1001F00002042008000002110204200C000002008A +:10020000020420100000020402042014000002195D +:100210000204201C0000FFFF020420200000FFFF5A +:10022000020420240000FFFF020420280000FFFF3A +:1002300002042038000000200604203C0000001FBB +:10024000020420B800000001060420BC0000005F8A +:100250000204223807FFFFFF0204223C0000003F97 +:100260000204224007FFFFFF020422440000000FA7 +:1002700001042248000000000104224C000000009C +:10028000010422500000000001042254000000007C +:1002900001042258000000000104225C000000005C +:1002A000010422600000000001042264000000003C +:1002B00001042268000000000104226C000000001C +:1002C00001042270000000000104227400000000FC +:1002D00001042278000000000104227C00000000DC +:1002E0000C042000000003E80A04200000000001C4 +:1002F0000B0420000000000A0605400000000D006D +:100300000205004400000020020500480000003201 +:10031000020500900215002002050094021500203D +:1003200002050098000000300205009C0810000043 +:10033000020500A000000033020500A40000003008 +:10034000020500A800000031020500AC0000000218 +:10035000020500B000000005020500B40000000620 +:10036000020500B800000002020500BC0000000207 +:10037000020500C000000000020500C400000005E6 +:10038000020500C800000002020500CC00000002C7 +:10039000020500D000000002020500D400000001A8 +:1003A00002050114000000010205011C000000010B +:1003B0000205012000000002020502040000000105 +:1003C0000205020C0000004002050210000000407F +:1003D0000205021C0000002002050220000000139C +:1003E0000205022400000020060502400000000A69 +:1003F00004050280002000000205005000000007F4 +:10040000020500540000000702050058000000002B +:100410000205005C00000008020500600000000109 +:100420000605006400000003020500D80000000675 +:1004300002050004000000010205000800000001A0 +:100440000205000C00000001020500100000000180 +:100450000205001400000001020500180000000160 +:100460000205001C00000001020500200000000140 +:100470000205002400000001020500280000000120 +:100480000205002C00000001020500300000000100 +:1004900002050034000000010205003800000001E0 +:1004A0000205003C000000010205004000000001C0 +:1004B000020500E00000000D020500E80000000059 +:1004C000020500F000000000020500F80000000036 +:1004D000020500E40000002D020500EC00000020F1 +:1004E000020500F400000020020500FC00000020CE +:1004F000020500E00000001D020500E800000010F9 +:10050000020500F000000010020500F800000010D5 +:10051000020500E40000003D020500EC0000003090 +:10052000020500F400000030020500FC000000306D +:10053000020500E00000004D020500E80000004058 +:10054000020500F000000040020500F80000004035 +:10055000020500E40000006D020500EC00000060F0 +:10056000020500F400000060020500FC00000060CD +:10057000020500E00000005D020500E800000050F8 +:10058000020500F000000050020500F800000050D5 +:10059000020500E40000007D020500EC0000007090 +:1005A000020500F400000070020500FC000000706D +:1005B0000406100002000020020600DC000000011A +:1005C000010600D80000000004060200000302201B +:1005D000020600DC00000000010600B80000000078 +:1005E000010600C8000000000206016C00000000C7 +:1005F000010600BC00000000010600CC0000000065 +:1006000002060170000000000718040000910000BD +:10061000081807D800050223071C00002BDC000087 +:10062000071C80002DE90AF8071D00002F521673E1 +:10063000071D800015DB2248081DB0B049EA0225DD +:100640000118000000000000011800040000000074 +:1006500001180008000000000118000C0000000054 +:100660000118001000000000011800140000000034 +:1006700002180020000000010218002400000002FF +:1006800002180028000000030218002C00000000DF +:1006900002180030000000040218003400000001BD +:1006A00002180038000000000218003C00000001A1 +:1006B000021800400000000402180044000000007E +:1006C00002180048000000010218004C000000035E +:1006D0000218005000000000021800540000000141 +:1006E00002180058000000040218005C000000001E +:1006F00002180060000000010218006400000003FE +:1007000002180068000000000218006C00000001E0 +:1007100002180070000000040218007400000000BD +:1007200002180078000000040218007C000000039A +:100730000618008000000002021800A400003FFF1D +:10074000021800A8000003FF0218022400000000A5 +:1007500002180234000000000218024C00000000E1 +:10076000021802E4000000FF061810000000040058 +:10077000021B8BC000000001021B8000000000343F +:10078000021B804000000018021B80800000000C4B +:10079000021B80C0000000200C1B83000007A1206A +:1007A0000A1B8300000001380B1B83000000138824 +:1007B0000A1B8340000000000C1B8340000001F472 +:1007C0000B1B834000000005021B83800007A12053 +:1007D000021B83C0000001F4021B14800000000112 +:1007E0000A1B148000000000061A1000000003B36A +:1007F000041A1ECC00010227061A1ED000000008B1 +:10080000061A2008000000C8061A20000000000296 +:10081000041AAF4000100228061A3718000000041E +:10082000061A371000000002061A500000000002ED +:10083000061A500800000004061A501800000004B0 +:10084000061A502800000004061A50380000000460 +:10085000061A504800000004061A50580000000410 +:10086000061A506800000004061A507800000002C2 +:10087000041A52C000020238061A40500000000656 +:10088000041A40680002023A041A40400004023C84 +:10089000041A800000010240061A800400000003D0 +:1008A000041A801000010241061A8014000000039F +:1008B000041A802000010242061A8024000000036E +:1008C000041A803000010243061A8034000000033D +:1008D000041A804000010244061A8044000000030C +:1008E000041A805000010245061A805400000003DB +:1008F000041A806000010246061A806400000003AA +:10090000041A807000010247061A80740000000378 +:10091000041A808000010248061A80840000000347 +:10092000041A809000010249061A80940000000316 +:10093000041A80A00001024A061A80A400000003E5 +:10094000041A80B00001024B061A80B400000003B4 +:10095000041A80C00001024C061A80C40000000383 +:10096000041A80D00001024D061A80D40000000352 +:10097000041A80E00001024E061A80E40000000321 +:10098000041A80F00001024F061A80F400000003F0 +:10099000041A810000010250061A810400000003BD +:1009A000041A811000010251061A8114000000038C +:1009B000041A812000010252061A8124000000035B +:1009C000041A813000010253061A8134000000032A +:1009D000041A814000010254061A814400000003F9 +:1009E000041A815000010255061A815400000003C8 +:1009F000041A816000010256061A81640000000397 +:100A0000041A817000010257061A81740000000365 +:100A1000041A818000010258061A81840000000334 +:100A2000041A819000010259061A81940000000303 +:100A3000041A81A00001025A061A81A400000003D2 +:100A4000041A81B00001025B061A81B400000003A1 +:100A5000041A81C00001025C061A81C40000000370 +:100A6000041A81D00001025D061A81D4000000033F +:100A7000041A81E00001025E061A81E4000000030E +:100A8000041A81F00001025F061A81F400000003DD +:100A9000041A820000010260061A820400000003AA +:100AA000041A821000010261061A82140000000379 +:100AB000041A822000010262061A82240000000348 +:100AC000041A823000010263061A82340000000317 +:100AD000041A824000010264061A824400000003E6 +:100AE000041A825000010265061A825400000003B5 +:100AF000041A826000010266061A82640000000384 +:100B0000041A827000010267061A82740000000352 +:100B1000041A828000010268061A82840000000321 +:100B2000041A829000010269061A829400000003F0 +:100B3000041A82A00001026A061A82A400000003BF +:100B4000041A82B00001026B061A82B4000000038E +:100B5000041A82C00001026C061A82C4000000035D +:100B6000041A82D00001026D061A82D4000000032C +:100B7000041A82E00001026E061A82E400000003FB +:100B8000041A82F00001026F061A82F400000003CA +:100B9000041A830000010270061A83040000000397 +:100BA000041A831000010271061A83140000000366 +:100BB000041A832000010272061A83240000000335 +:100BC000041A833000010273061A83340000000304 +:100BD000041A834000010274061A834400000003D3 +:100BE000041A835000010275061A835400000003A2 +:100BF000041A836000010276061A83640000000371 +:100C0000041A837000010277061A8374000000033F +:100C1000041A838000010278061A8384000000030E +:100C2000041A839000010279061A839400000003DD +:100C3000041A83A00001027A061A83A400000003AC +:100C4000041A83B00001027B061A83B4000000037B +:100C5000041A83C00001027C061A83C4000000034A +:100C6000041A83D00001027D061A83D40000000319 +:100C7000041A83E00001027E061A83E400000003E8 +:100C8000041A83F00001027F061A83F400000003B7 +:100C9000041A840000010280061A84040000000384 +:100CA000041A841000010281061A84140000000353 +:100CB000041A842000010282061A84240000000322 +:100CC000041A843000010283061A843400000003F1 +:100CD000041A844000010284061A844400000003C0 +:100CE000041A845000010285061A8454000000038F +:100CF000041A846000010286061A8464000000035E +:100D0000041A847000010287061A8474000000032C +:100D1000041A848000010288061A848400000003FB +:100D2000041A849000010289061A849400000003CA +:100D3000041A84A00001028A061A84A40000000399 +:100D4000041A84B00001028B061A84B40000000368 +:100D5000041A84C00001028C061A84C40000000337 +:100D6000041A84D00001028D061A84D40000000306 +:100D7000041A84E00001028E061A84E400000003D5 +:100D8000041A84F00001028F061A84F400000003A4 +:100D9000041A850000010290061A85040000000371 +:100DA000041A851000010291061A85140000000340 +:100DB000041A852000010292061A8524000000030F +:100DC000041A853000010293061A853400000003DE +:100DD000041A854000010294061A854400000003AD +:100DE000041A855000010295061A8554000000037C +:100DF000041A856000010296061A8564000000034B +:100E0000041A857000010297061A85740000000319 +:100E1000041A858000010298061A858400000003E8 +:100E2000041A859000010299061A859400000003B7 +:100E3000041A85A00001029A061A85A40000000386 +:100E4000041A85B00001029B061A85B40000000355 +:100E5000041A85C00001029C061A85C40000000324 +:100E6000041A85D00001029D061A85D400000003F3 +:100E7000041A85E00001029E061A85E400000003C2 +:100E8000041A85F00001029F061A85F40000000391 +:100E9000041A8600000102A0061A8604000000035E +:100EA000041A8610000102A1061A8614000000032D +:100EB000041A8620000102A2061A862400000003FC +:100EC000041A8630000102A3061A863400000003CB +:100ED000041A8640000102A4061A8644000000039A +:100EE000041A8650000102A5061A86540000000369 +:100EF000041A8660000102A6061A86640000000338 +:100F0000041A8670000102A7061A86740000000306 +:100F1000041A8680000102A8061A868400000003D5 +:100F2000041A8690000102A9061A869400000003A4 +:100F3000041A86A0000102AA061A86A40000000373 +:100F4000041A86B0000102AB061A86B40000000342 +:100F5000041A86C0000102AC061A86C40000000311 +:100F6000041A86D0000102AD061A86D400000003E0 +:100F7000041A86E0000102AE061A86E400000003AF +:100F8000041A86F0000102AF061A86F4000000037E +:100F9000041A8700000102B0061A8704000000034B +:100FA000041A8710000102B1061A8714000000031A +:100FB000041A8720000102B2061A872400000003E9 +:100FC000041A8730000102B3061A873400000003B8 +:100FD000041A8740000102B4061A87440000000387 +:100FE000041A8750000102B5061A87540000000356 +:100FF000041A8760000102B6061A87640000000325 +:10100000041A8770000102B7061A877400000003F3 +:10101000041A8780000102B8061A878400000003C2 +:10102000041A8790000102B9061A87940000000391 +:10103000041A87A0000102BA061A87A40000000360 +:10104000041A87B0000102BB061A87B4000000032F +:10105000041A87C0000102BC061A87C400000003FE +:10106000041A87D0000102BD061A87D400000003CD +:10107000041A87E0000102BE061A87E4000000039C +:10108000041A87F0000102BF061A87F4000000036B +:10109000041A8800000102C0061A88040000000338 +:1010A000041A8810000102C1061A88140000000307 +:1010B000041A8820000102C2061A882400000003D6 +:1010C000041A8830000102C3061A883400000003A5 +:1010D000041A8840000102C4061A88440000000374 +:1010E000041A8850000102C5061A88540000000343 +:1010F000041A8860000102C6061A88640000000312 +:10110000041A8870000102C7061A887400000003E0 +:10111000041A8880000102C8061A888400000003AF +:10112000041A8890000102C9061A8894000000037E +:10113000041A88A0000102CA061A88A4000000034D +:10114000041A88B0000102CB061A88B4000000031C +:10115000041A88C0000102CC061A88C400000003EB +:10116000041A88D0000102CD061A88D400000003BA +:10117000041A88E0000102CE061A88E40000000389 +:10118000041A88F0000102CF061A88F40000000358 +:10119000041A8900000102D0061A89040000000325 +:1011A000041A8910000102D1061A891400000003F4 +:1011B000041A8920000102D2061A892400000003C3 +:1011C000041A8930000102D3061A89340000000392 +:1011D000041A8940000102D4061A89440000000361 +:1011E000041A8950000102D5061A89540000000330 +:1011F000041A8960000102D6061A896400000003FF +:10120000041A8970000102D7061A897400000003CD +:10121000041A8980000102D8061A8984000000039C +:10122000041A8990000102D9061A8994000000036B +:10123000041A89A0000102DA061A89A4000000033A +:10124000041A89B0000102DB061A89B40000000309 +:10125000041A89C0000102DC061A89C400000003D8 +:10126000041A89D0000102DD061A89D400000003A7 +:10127000041A89E0000102DE061A89E40000000376 +:10128000041A89F0000102DF061A89F40000000345 +:10129000041A8A00000102E0061A8A040000000312 +:1012A000041A8A10000102E1061A8A1400000003E1 +:1012B000041A8A20000102E2061A8A2400000003B0 +:1012C000041A8A30000102E3061A8A34000000037F +:1012D000041A8A40000102E4061A8A44000000034E +:1012E000041A8A50000102E5061A8A54000000031D +:1012F000041A8A60000102E6061A8A6400000003EC +:10130000041A8A70000102E7061A8A7400000003BA +:10131000041A8A80000102E8061A8A840000000389 +:10132000041A8A90000102E9061A8A940000000358 +:10133000041A8AA0000102EA061A8AA40000000327 +:10134000041A8AB0000102EB061A8AB400000003F6 +:10135000041A8AC0000102EC061A8AC400000003C5 +:10136000041A8AD0000102ED061A8AD40000000394 +:10137000041A8AE0000102EE061A8AE40000000363 +:10138000041A8AF0000102EF061A8AF40000000332 +:10139000041A8B00000102F0061A8B0400000003FF +:1013A000041A8B10000102F1061A8B1400000003CE +:1013B000041A8B20000102F2061A8B24000000039D +:1013C000041A8B30000102F3061A8B34000000036C +:1013D000041A8B40000102F4061A8B44000000033B +:1013E000041A8B50000102F5061A8B54000000030A +:1013F000041A8B60000102F6061A8B6400000003D9 +:10140000041A8B70000102F7061A8B7400000003A7 +:10141000041A8B80000102F8061A8B840000000376 +:10142000041A8B90000102F9061A8B940000000345 +:10143000041A8BA0000102FA061A8BA40000000314 +:10144000041A8BB0000102FB061A8BB400000003E3 +:10145000041A8BC0000102FC061A8BC400000003B2 +:10146000041A8BD0000102FD061A8BD40000000381 +:10147000041A8BE0000102FE061A8BE40000000350 +:10148000041A8BF0000102FF061A8BF4000000031F +:10149000041A8C0000010300061A8C0400000003EB +:1014A000041A8C1000010301061A8C1400000003BA +:1014B000041A8C2000010302061A8C240000000389 +:1014C000041A8C3000010303061A8C340000000358 +:1014D000041A8C4000010304061A8C440000000327 +:1014E000041A8C5000010305061A8C5400000003F6 +:1014F000041A8C6000010306061A8C6400000003C5 +:10150000041A8C7000010307061A8C740000000393 +:10151000041A8C8000010308061A8C840000000362 +:10152000041A8C9000010309061A8C940000000331 +:10153000041A8CA00001030A061A8CA40000000300 +:10154000041A8CB00001030B061A8CB400000003CF +:10155000041A8CC00001030C061A8CC4000000039E +:10156000041A8CD00001030D061A8CD4000000036D +:10157000041A8CE00001030E061A8CE4000000033C +:10158000041A8CF00001030F061A8CF4000000030B +:10159000041A8D0000010310061A8D0400000003D8 +:1015A000041A8D1000010311061A8D1400000003A7 +:1015B000041A8D2000010312061A8D240000000376 +:1015C000041A8D3000010313061A8D340000000345 +:1015D000041A8D4000010314061A8D440000000314 +:1015E000041A8D5000010315061A8D5400000003E3 +:1015F000041A8D6000010316061A8D6400000003B2 +:10160000041A8D7000010317061A8D740000000380 +:10161000041A8D8000010318061A8D84000000034F +:10162000041A8D9000010319061A8D94000000031E +:10163000041A8DA00001031A061A8DA400000003ED +:10164000041A8DB00001031B061A8DB400000003BC +:10165000041A8DC00001031C061A8DC4000000038B +:10166000041A8DD00001031D061A8DD4000000035A +:10167000041A8DE00001031E061A8DE40000000329 +:10168000041A8DF00001031F061A8DF400000003F8 +:10169000041A8E0000010320061A8E0400000003C5 +:1016A000041A8E1000010321061A8E140000000394 +:1016B000041A8E2000010322061A8E240000000363 +:1016C000041A8E3000010323061A8E340000000332 +:1016D000041A8E4000010324061A8E440000000301 +:1016E000041A8E5000010325061A8E5400000003D0 +:1016F000041A8E6000010326061A8E64000000039F +:10170000041A8E7000010327061A8E74000000036D +:10171000041A8E8000010328061A8E84000000033C +:10172000041A8E9000010329061A8E94000000030B +:10173000041A8EA00001032A061A8EA400000003DA +:10174000041A8EB00001032B061A8EB400000003A9 +:10175000041A8EC00001032C061A8EC40000000378 +:10176000041A8ED00001032D061A8ED40000000347 +:10177000041A8EE00001032E061A8EE40000000316 +:10178000041A8EF00001032F061A8EF400000003E5 +:10179000041A8F0000010330061A8F0400000003B2 +:1017A000041A8F1000010331061A8F140000000381 +:1017B000041A8F2000010332061A8F240000000350 +:1017C000041A8F3000010333061A8F34000000031F +:1017D000041A8F4000010334061A8F4400000003EE +:1017E000041A8F5000010335061A8F5400000003BD +:1017F000041A8F6000010336061A8F64000000038C +:10180000041A8F7000010337061A8F74000000035A +:10181000041A8F8000010338061A8F840000000329 +:10182000041A8F9000010339061A8F9400000003F8 +:10183000041A8FA00001033A061A8FA400000003C7 +:10184000041A8FB00001033B061A8FB40000000396 +:10185000041A8FC00001033C061A8FC40000000365 +:10186000041A8FD00001033D061A8FD40000000334 +:10187000041A8FE00001033E061A8FE400000007FF +:10188000041A62C00020033F061AD0000000007254 +:10189000061AD24800000010061AD6B00000002038 +:1018A000061AD47000000090061AD46800000002E6 +:1018B000061AA000000001C4061A30000000001043 +:1018C000061A308000000010061A310000000010D7 +:1018D000061A318000000010061A330000000012C2 +:1018E000061A339000000070061AD4580000000257 +:1018F000061AD34800000002061AD3580000002040 +:10190000061AA710000001C4061A3040000000109B +:10191000061A30C000000010061A31400000001006 +:10192000061A31C000000010061A334800000012E9 +:10193000061A355000000070061AD460000000023C +:10194000061AD35000000002061AD3D80000002067 +:10195000021AAE2000000000061A5000000000022B +:10196000061A508000000012041A40000002035FB3 +:10197000041A63C000020361061A7000000000042C +:10198000061A320000000008021AAE24000000000F +:10199000061A501000000002061A50C8000000127B +:1019A000041A400800020363041A63C800020365B6 +:1019B000061A701000000004061A32200000000809 +:1019C000021AAE2800000000061A50200000000293 +:1019D000061A511000000012041A4010000203679A +:1019E000041A63D000020369061A70200000000484 +:1019F000061A324000000008021AAE2C0000000057 +:101A0000061A503000000002061A51580000001259 +:101A1000041A40180002036B041A63D80002036D15 +:101A2000061A703000000004061A32600000000838 +:101A3000021AAE3000000000061A504000000002FA +:101A4000061A51A000000012041A40200002036F81 +:101A5000041A63E000020371061A704000000004DB +:101A6000061A328000000008021AAE34000000009E +:101A7000061A505000000002061A51E80000001239 +:101A8000041A402800020373041A63E80002037575 +:101A9000061A705000000004061A32A00000000868 +:101AA000021AAE3800000000061A50600000000262 +:101AB000061A523000000012041A40300002037768 +:101AC000041A63F000020379061A70600000000433 +:101AD000061A32C000000008021AAE3C00000000E6 +:101AE000061A507000000002061A52780000001218 +:101AF000041A40380002037B041A63F80002037DD5 +:101B0000061A707000000004061A32E00000000897 +:101B10000200A468000B01C80200A294071D29114D +:101B20000200A298000000000200A29C009C042475 +:101B30000200A2A0000000000200A2A4000002090E +:101B40000200A270000000000200A2740000000069 +:101B50000200A270000000000200A2740000000059 +:101B60000200A270000000000200A2740000000049 +:101B70000200A270000000000200A2740000000039 +:101B8000020160A000000001020160A400000262E6 +:101B9000020160A800000002020160AC0000001811 +:101BA0000201620400000001020100B40000000113 +:101BB000020100B800000001020100DC0000000189 +:101BC0000201010000000001020101040000000107 +:101BD0000201007C003000000201008400000028A7 +:101BE0000201008C0000000002010130000000042E +:101BF0000201025C00000001020103280000000055 +:101C0000020160580000FFFF020160700000000741 +:101C10000201608000000001020105540000003054 +:101C2000020100C400000001020100CC000000011C +:101C3000020100F800000001020100F000000001B4 +:101C4000020100800030000002010088000000282E +:101C500002010090000000000201013400000004B5 +:101C6000020102DC000000010201032C0000000060 +:101C70000201605C0000FFFF0201607400000007C9 +:101C800002016084000000010201056400000030D0 +:101C9000020100C800000001020100D000000001A4 +:101CA000020100FC00000001020100F4000000013C +:101CB000020C100000000028020C20080000021195 +:101CC000020C200C00000200020C20100000020494 +:101CD000020C201C0000FFFF020C20200000FFFF70 +:101CE000020C20240000FFFF020C20280000FFFF50 +:101CF000020C203800000020020C203C00000021D3 +:101D0000020C204000000022020C204400000023AE +:101D1000020C204800000024020C204C000000258A +:101D2000020C205000000026020C20540000002766 +:101D3000020C205800000028020C205C0000002942 +:101D4000020C20600000002A020C20640000002B1E +:101D5000020C20680000002C020C206C0000002DFA +:101D6000020C20700000002E020C20740000002FD6 +:101D7000020C207800000010060C207C00000007F8 +:101D8000020C209800000011020C209C00000012A0 +:101D9000020C20A000000013060C20A40000001D6F +:101DA000020C211800000001020C211C000000019F +:101DB000020C212000000001060C21240000001D5F +:101DC000020C219800000001060C219C0000000775 +:101DD000020C21B800000001020C21BC000000012F +:101DE000020C21C000000001020C21C4000000010F +:101DF000020C21C800000001020C21CC00000001EF +:101E0000020C21D000000001020C21D400000001CE +:101E1000020C21D800000001020C21DC00000001AE +:101E2000020C21E000000001020C21E4000000018E +:101E3000020C21E800000001020C21EC000000016E +:101E4000020C21F000000001020C21F4000000014E +:101E5000020C21F800000001060C21FC0000000724 +:101E6000020C221800000001060C221C00000007D2 +:101E7000020C223807FFFFFF020C223C0000003F4B +:101E8000020C224007FFFFFF020C22440000000F5B +:101E9000010C224800000000010C224C0000000050 +:101EA000010C225000000000010C22540000000030 +:101EB000010C225800000000010C225C0000000010 +:101EC000010C226000000000010C226400000000F0 +:101ED000010C226800000000010C226C00000000D0 +:101EE000010C227000000000010C227400000000B0 +:101EF000010C227800000000010C227C0000000090 +:101F00000C0C2000000003E80A0C20000000000177 +:101F10000B0C20000000000A020C40080000101109 +:101F2000020C400C00001000020C401000001004D5 +:101F3000020C401400001021020C401C0000FFFFA6 +:101F4000020C40200000FFFF020C40240000FFFFB5 +:101F5000020C40280000FFFF020C40380000004641 +:101F6000020C403C00000010060C40400000000243 +:101F7000020C404800000018020C404C000000F029 +:101F8000060C40500000001F020C40CC0000000175 +:101F9000060C40D00000003A020C41B800000001DD +:101FA000060C41BC00000003020C41C80000000107 +:101FB000020C41CC00000001060C41D00000001AC8 +:101FC000020C423807FFFFFF020C423C0000003FBA +:101FD000020C424007FFFFFF020C42440000000FCA +:101FE000010C424800000000010C424C00000000BF +:101FF000010C425000000000010C4254000000009F +:10200000010C425800000000010C425C000000007E +:10201000010C426000000000010C4264000000005E +:10202000010C426800000000010C426C000000003E +:10203000010C427000000000010C4274000000001E +:10204000010C427800000000010C427C00000000FE +:10205000010C4280000000000C0C4000000003E86E +:102060000A0C4000000000010B0C40000000000AB8 +:10207000060D400000000A00020D0044000000327E +:10208000020D008C02150020020D009002150020A8 +:10209000020D009408100000020D009800000033AB +:1020A000020D009C00000002020D00A000000000D4 +:1020B000020D00A400000005020D00A800000005AC +:1020C000060D00AC00000002020D00B4000000028A +:1020D000020D00B800000003020D00BC0000000269 +:1020E000020D00C000000001020D00C80000000247 +:1020F000020D00CC00000002020D015C0000000196 +:10210000020D016400000001020D016800000002E0 +:10211000020D020400000001020D020C000000206C +:10212000020D021000000040020D021400000040E9 +:10213000020D022000000003020D0224000000181E +:10214000060D028000000012040D03000018037F3A +:10215000060D03600000000C020D004C00000001A1 +:10216000020D005000000002020D005400000000AB +:10217000020D005800000008060D005C000000047D +:10218000020D00C400000004020D00040000000164 +:10219000020D000800000001020D000C000000010B +:1021A000020D001000000001020D001400000001EB +:1021B000020D001800000001020D001C00000001CB +:1021C000020D002000000001020D002400000001AB +:1021D000020D002800000001020D002C000000018B +:1021E000020D003000000001020D0034000000016B +:1021F000020D003800000001020D003C000000014B +:10220000020D011400000009020D011C0000000A6B +:10221000020D012400000000020D012C000000004E +:10222000020D013400000000020D013C0000000B13 +:10223000020D014400000000020D011800000029F9 +:10224000020D01200000002A020D012800000020DC +:10225000020D013000000020020D013800000020B6 +:10226000020D01400000002B020D0148000000207B +:10227000020D011400000019020D011C0000001ADB +:10228000020D012400000010020D012C00000010BE +:10229000020D013400000010020D013C0000001B83 +:1022A000020D014400000010020D01180000003969 +:1022B000020D01200000003A020D0128000000304C +:1022C000020D013000000030020D01380000003026 +:1022D000020D01400000003B020D014800000030EB +:1022E000020D011400000049020D011C0000004A0B +:1022F000020D012400000040020D012C00000040EE +:10230000020D013400000040020D013C0000004BB2 +:10231000020D014400000040020D01180000006998 +:10232000020D01200000006A020D0128000000607B +:10233000020D013000000060020D01380000006055 +:10234000020D01400000006B020D0148000000601A +:10235000020D011400000059020D011C0000005A7A +:10236000020D012400000050020D012C000000505D +:10237000020D013400000050020D013C0000005B22 +:10238000020D014400000050020D01180000007908 +:10239000020D01200000007A020D012800000070EB +:1023A000020D013000000070020D013800000070C5 +:1023B000020D01400000007B020D0148000000708A +:1023C000060E200000000800020E004C0000003243 +:1023D000020E009402150020020E00980215002043 +:1023E000020E009C00000030020E00A00810000049 +:1023F000020E00A400000033020E00A8000000300E +:10240000020E00AC00000031020E00B0000000021D +:10241000020E00B400000004020E00B8000000002C +:10242000020E00BC00000002020E00C0000000020C +:10243000020E00C400000000020E00C800000002EE +:10244000020E00CC00000007020E00D000000002C7 +:10245000020E00D400000002020E00D800000001AD +:10246000020E014400000001020E014C00000001B8 +:10247000020E015000000002020E020400000001E2 +:10248000020E020C00000040020E0210000000408C +:10249000020E021C00000004020E022000000020B8 +:1024A000020E02240000000E020E02280000001B93 +:1024B000060E030000000012040E0280001B0397AA +:1024C000060E02EC00000005020E00540000000C95 +:1024D000020E00580000000C020E005C000000001C +:1024E000020E006000000010020E006400000010E8 +:1024F000060E006800000003020E00DC000000036E +:10250000020E000400000001020E0008000000019D +:10251000020E000C00000001020E0010000000017D +:10252000020E001400000001020E0018000000015D +:10253000020E001C00000001020E0020000000013D +:10254000020E002400000001020E0028000000011D +:10255000020E002C00000001020E003000000001FD +:10256000020E003400000001020E003800000001DD +:10257000020E003C00000001020E004000000001BD +:10258000020E004400000001020E01100000000FC6 +:10259000020E011800000000020E012000000000E1 +:1025A000020E012800000000020E01140000002F9E +:1025B000020E011C00000020020E01240000000099 +:1025C000020E012C00000000020E01100000001F8E +:1025D000020E011800000010020E01200000000091 +:1025E000020E012800000000020E01140000003F4E +:1025F000020E011C00000030020E01240000000049 +:10260000020E012C00000000020E01100000004F1D +:10261000020E011800000040020E01200000000020 +:10262000020E012800000000020E01140000006FDD +:10263000020E011C00000060020E012400000000D8 +:10264000020E012C00000000020E01100000005FCD +:10265000020E011800000050020E012000000000D0 +:10266000020E012800000000020E01140000007F8D +:10267000020E011C00000070020E01240000000088 +:10268000020E012C000000000730040000C800000A +:10269000083007D8000503B207340000332C0000CF +:1026A0000734800030AC0CCC07350000353318F807 +:1026B000073580002A7126450736000018DA30E217 +:1026C00008364670373203B40130000000000000C5 +:1026D000013000040000000001300008000000008C +:1026E0000130000C0000000001300010000000006C +:1026F0000130001400000000023000200000000142 +:102700000230002400000002023000280000000314 +:102710000230002C000000000230003000000004F5 +:1027200002300034000000010230003800000000D8 +:102730000230003C000000010230004000000004B4 +:102740000230004400000000023000480000000198 +:102750000230004C00000003023000500000000076 +:102760000230005400000001023000580000000454 +:102770000230005C00000000023000600000000138 +:102780000230006400000003023000680000000016 +:102790000230006C000000010230007000000004F4 +:1027A00002300074000000000230007800000004D5 +:1027B0000230007C000000030630008000000002B0 +:1027C000023000A400003FFF023000A8000003FF19 +:1027D0000230022400000000023002340000000039 +:1027E0000230024C00000000023002E40000FFFF53 +:1027F000063020000000080002338BC000000001FA +:10280000023380000000001A023380400000004EB6 +:102810000233808000000010023380C000000020DE +:102820000C3383000007A1200A3383000000013825 +:102830000B338300000013880A338340000000003C +:102840000C338340000001F40B338340000000058B +:10285000023383800007A120023383C0000001F40B +:1028600002331480000000010A33148000000000CD +:10287000063280000000010206322008000000C875 +:10288000063220000000000204328EA0001003B6C1 +:1028900006323EB00000000606323ED800000002BC +:1028A00006323E800000000A04323EA8000203C641 +:1028B00006323E00000000200632500000000400F6 +:1028C0000632400000000004043274C0000203C855 +:1028D00006324110000000020632D0000000003035 +:1028E0000632DD40000000440632DA00000000D06D +:1028F0000632DEA0000000020632E0000000080000 +:1029000006328450000001180632100000000188D1 +:102910000632500000000020063251000000002066 +:102920000632520000000020063253000000002052 +:10293000063254000000002006325500000000203E +:10294000063256000000002006325700000000202A +:102950000632580000000020063259000000002016 +:1029600006325A000000002006325B000000002002 +:1029700006325C000000002006325D0000000020EE +:1029800006325E000000002006325F0000000020DA +:1029900006328DF00000000204328E00000203CAED +:1029A00006328E08000000020632DE9000000002AF +:1029B00006321C4000000038063288B000000118C2 +:1029C00006321620000001880632508000000020E8 +:1029D00006325180000000200632528000000020A4 +:1029E0000632538000000020063254800000002090 +:1029F000063255800000002006325680000000207C +:102A00000632578000000020063258800000002067 +:102A1000063259800000002006325A800000002053 +:102A200006325B800000002006325C80000000203F +:102A300006325D800000002006325E80000000202B +:102A400006325F800000002006328DF80000000290 +:102A500004328E10000203CC06328E1800000002F1 +:102A60000632DE980000000206321D200000003809 +:102A700002328D50000000000632401000000002BB +:102A800002328D5400000000063240200000000297 +:102A900002328D5800000000063240300000000273 +:102AA00002328D5C0000000006324040000000024F +:102AB00002328D600000000006324050000000022B +:102AC00002328D6400000000063240600000000207 +:102AD00002328D68000000000632407000000002E3 +:102AE00002328D6C000000000632408000000002BF +:102AF000072004000091000008200780001003CE8A +:102B0000072400002B0B00000724800015080AC3CF +:102B10000824AA10692403D001200000000000004E +:102B20000120000400000000012000080000000057 +:102B30000120000C00000000012000100000000037 +:102B4000012000140000000002200020000000010D +:102B500002200024000000020220002800000003E0 +:102B60000220002C000000000220003000000004C1 +:102B700002200034000000010220003800000000A4 +:102B80000220003C00000001022000400000000480 +:102B90000220004400000000022000480000000164 +:102BA0000220004C00000003022000500000000042 +:102BB0000220005400000001022000580000000420 +:102BC0000220005C00000000022000600000000104 +:102BD00002200064000000030220006800000000E2 +:102BE0000220006C000000010220007000000004C0 +:102BF00002200074000000000220007800000004A1 +:102C00000220007C0000000306200080000000027B +:102C1000022000A400003FFF022000A8000003FFE4 +:102C20000220022400000000022002340000000004 +:102C30000220024C00000000022002E40000FFFF1E +:102C4000062020000000080002238BC000000001C5 +:102C500002238000000000100223804000000012C8 +:102C60000223808000000030022380C00000000E9C +:102C70000C2383000007A1200A23830000000138F1 +:102C80000B238300000013880A2383400000000008 +:102C90000C238340000001F40B2383400000000557 +:102CA000022383800007A120022383C0000001F4D7 +:102CB00002231480000000010A2314800000000099 +:102CC000062210000000004206222008000000C872 +:102CD00006222000000000020622B000000000C60C +:102CE0000422B318000503D20622B32C0000000B07 +:102CF0000422B358000503D70622B36C0000000B72 +:102D00000422B398000503DC0622B3AC0000000BDC +:102D10000422B3D8000503E10622B3EC0000000B47 +:102D20000422B418000503E60622B42C0000000BB0 +:102D30000422B458000503EB0622B46C0000000B1B +:102D40000422B498000503F00622B4AC0000000B86 +:102D50000422B4D8000503F50622B4EC0000000BF1 +:102D60000422B518000503FA0622B52C0000000B5A +:102D70000422B558000503FF0622B56C0000000BC5 +:102D80000422B598000504040622B5AC0000000B2F +:102D90000422B5D8000504090622B5EC0000000B9A +:102DA0000422B6180005040E0622B62C0000000B03 +:102DB0000422B658000504130622B66C0000000B6E +:102DC0000422B698000504180622B6AC0000000BD9 +:102DD0000422B6D80005041D0622B6EC0000000B44 +:102DE0000422B718000504220622B72C0000000BAD +:102DF0000422B758000504270622B76C0000000B18 +:102E00000422B7980005042C0622B7AC0000000B82 +:102E10000422B7D8000504310622B7EC0000000BED +:102E20000422B818000504360622B82C0000000B56 +:102E30000422B8580005043B0622B86C0000000BC1 +:102E40000422B898000504400622B8AC0000000B2C +:102E50000422B8D8000504450622B8EC0000000B97 +:102E60000422B9180005044A0622B92C0000000B00 +:102E70000422B9580005044F0622B96C0000000B6B +:102E80000422B998000504540622B9AC0000000BD6 +:102E90000422B9D8000504590622B9EC0000000B41 +:102EA0000422BA180005045E0622BA2C0000000BAA +:102EB0000422BA58000504630622BA6C0000000B15 +:102EC0000422BA98000504680622BAAC0000000B80 +:102ED0000422BAD80005046D0622BAEC00000005F1 +:102EE0000622BB00000000530422BC4C0001047207 +:102EF0000622BC50000000030422BC5C00010473E5 +:102F00000622BC60000000030422BC6C00010474B3 +:102F10000622BC70000000030422BC7C0001047582 +:102F20000622BC80000000030422BC8C0001047651 +:102F30000622BC90000000030422BC9C0001047720 +:102F40000622BCA0000000030422BCAC00010478EF +:102F50000622BCB0000000030422BCBC00010479BE +:102F60000622880000000100062280000000020006 +:102F7000042212700010047A06223000000000C003 +:102F800006226700000001000622900000000400F5 +:102F900004226B080020048A022212C0FFFFFFFFF8 +:102FA000062211E800000002062212C800000009F3 +:102FB000062212EC0000000906228C000000000826 +:102FC0000222114800000000062213200000000623 +:102FD000062233000000000206226040000000309C +:102FE00006228C20000000080222114C0000000084 +:102FF00006221338000000060622330800000002F3 +:10300000062261000000003006228C40000000080B +:10301000022211500000000006221350000000069A +:103020000622331000000002062261C000000030BA +:1030300006228C60000000080222115400000000EB +:103040000622136800000006062233180000000262 +:10305000062262800000003006228C8000000008FA +:103060000222115800000000062213800000000612 +:1030700006223320000000020622634000000030D8 +:1030800006228CA0000000080222115C0000000053 +:1030900006221398000000060622332800000002D2 +:1030A000062264000000003006228CC000000008E8 +:1030B0000222116000000000062213B0000000068A +:1030C0000622333000000002062264C000000030F7 +:1030D00006228CE0000000080222116400000000BB +:1030E000062213C800000006062233380000000242 +:1030F0000622658000000030021610000000002843 +:1031000002170008000000020217002C0000000354 +:103110000217003C000000040217004800000002F3 +:103120000217004C000000900217005000000090B1 +:103130000217005400800090021700580810000089 +:10314000021700600000008A02170064000000807F +:1031500002170068000000810217006C0000008068 +:10316000021700700000000602170078000007D068 +:103170000217007C0000076C02170038007C100466 +:10318000021700040000000F061640240000000291 +:10319000021640700000001C0216420800000001E8 +:1031A0000216421000000001021642200000000139 +:1031B0000216422800000001021642300000000101 +:1031C00002164238000000010216426000000002B0 +:1031D0000C16401C0003D0900A16401C0000009CF6 +:1031E0000B16401C000009C4021640300000000805 +:1031F000021640340000000C021640380000001097 +:1032000002164044000000200216400000000001A9 +:10321000021640D80000000102164008000000011C +:103220000216400C000000010216401000000001D0 +:103230000216424000000000021642480000000052 +:103240000616427000000002021642500000000004 +:1032500002164258000000000616428000000002DC +:1032600002166008000012240216600C0000121002 +:1032700002166010000012140216601C0000FFFF0E +:10328000021660200000FFFF021660240000FFFF0E +:10329000021660280000FFFF0216603800000020C0 +:1032A0000216603C0000002006166040000000028C +:1032B00002166048000000230216604C0000002443 +:1032C000021660500000002502166054000000261F +:1032D00002166058000000270216605C00000029FA +:1032E000021660600000002A021660640000002BD5 +:1032F000021660680000002C0216606C0000002DB1 +:1033000002166070000000EC0216607400000011EC +:1033100002166078000000120616607C0000000FA4 +:10332000021660B800000001021660BC0000000137 +:10333000061660C00000000C021660F000000001DC +:10334000061660F400000031021661B800000001AA +:10335000061661BC0000000D021661F000000001BD +:10336000061661F4000000110216623807FFFFFF25 +:103370000216623C0000003F0216624007FFFFFF9A +:10338000021662440000000F0116624800000000AF +:103390000116624C0000000001166250000000009F +:1033A000011662540000000001166258000000007F +:1033B0000116625C0000000001166260000000005F +:1033C000011662640000000001166268000000003F +:1033D0000116626C0000000001166270000000001F +:1033E00001166274000000000116627800000000FF +:1033F0000116627C000000000C166000000003E86B +:103400000A166000000000010B1660000000000AB0 +:1034100002168040000000060216804400000005ED +:10342000021680480000000A0216804C00000005C9 +:103430000216805400000002021680CC0000000436 +:10344000021680D000000004021680D400000004A0 +:10345000021680D800000004021680DC0000000480 +:10346000021680E000000004021680E40000000460 +:10347000021680E800000004021688040000000420 +:10348000021680300000007C021680340000003DEF +:10349000021680380000003F0216803C0000009CAD +:1034A000021680F000000007061680F400000005F8 +:1034B0000216880C010101010216810800000000BB +:1034C0000216810C000000040216811000000004A6 +:1034D0000216811400000002021688100801200460 +:1034E00002168118000000050216811C000000056C +:1034F000021681200000000502168124000000054C +:103500000216882C200810010216812800000008ED +:103510000216812C00000006021681300000000710 +:1035200002168134000000000216883001010120DB +:1035300006168138000000040216883401010101DA +:1035400002168148000000000216814C00000004B1 +:10355000021681500000000402168154000000028F +:103560000216883808012004021681580000000560 +:103570000216815C00000005021681600000000553 +:1035800002168164000000050216883C2008100124 +:1035900002168168000000080216816C0000000617 +:1035A00002168170000000070216817400000001FD +:1035B00002168840010101200216817800000001F6 +:1035C0000216817C000000010216818000000001CB +:1035D00002168184000000010216884401010101E5 +:1035E00002168188000000010216818C0000000490 +:1035F000021681900000000402168194000000026F +:10360000021688480801200402168198000000056F +:103610000216819C00000005021681A00000000532 +:10362000021681A40000000502168814200810016B +:10363000021681A800000008021681AC00000006F6 +:10364000021681B000000007021681B400000001DC +:103650000216881801010120021681B8000000013D +:10366000021681BC00000001021681C000000001AA +:10367000021681C4000000010216881C010101012C +:10368000021681C800000001021681CC000000046F +:10369000021681D000000004021681D4000000024E +:1036A0000216882008012004021681D800000005B7 +:1036B000021681DC00000005021681E00000000512 +:1036C000021681E40000000502168824200810017B +:1036D000021681E800000008021681EC00000006D6 +:1036E000021681F0000000070216E40C0000000042 +:1036F00002168828010101200616E41000000004CB +:103700000216E000010101010216E42000000000A1 +:103710000216E424000000040216E428000000045D +:103720000216E42C000000020216E0040801200446 +:103730000216E430000000050216E4340000000523 +:103740000216E438000000050216E43C0000000503 +:103750000216E008200810010216E44000000008EC +:103760000216E444000000060216E44800000007C8 +:103770000216E44C000000000216E00C01010120DA +:103780000616E450000000040216E01001010101D9 +:103790000216E460000000000216E4640000000469 +:1037A0000216E468000000040216E46C0000000247 +:1037B0000216E014080120040216E470000000055F +:1037C0000216E474000000050216E478000000050B +:1037D0000216E47C000000050216E0182008100123 +:1037E0000216E480000000080216E48400000006CF +:1037F0000216E488000000070216E48C00000001B5 +:103800000216E01C010101200216E49000000001F4 +:103810000216E494000000010216E4980000000182 +:103820000216E49C000000010216E02001010101E3 +:103830000216E4A0000000010216E4A40000000447 +:103840000216E4A8000000040216E4AC0000000226 +:103850000216E024080120040216E4B0000000056E +:103860000216E4B4000000050216E4B800000005EA +:103870000216E4BC000000050216E0282008100132 +:103880000216E4C0000000080216E4C400000006AE +:103890000216E4C8000000070216E4CC0000000194 +:1038A0000216E02C010101200216E4D00000000104 +:1038B0000216E4D4000000010216E4D80000000162 +:1038C0000216E4DC000000010216E03001010101F3 +:1038D0000216E4E0000000010216E4E40000000427 +:1038E0000216E4E8000000040216E4EC0000000206 +:1038F0000216E034080120040216E4F0000000057E +:103900000216E4F4000000050216E4F800000005C9 +:103910000216E4FC000000050216E0382008100141 +:103920000216E500000000080216E504000000068B +:103930000216E508000000070216E03C0101012024 +:1039400002168240003F003F021682440000000041 +:103950000216E524003F003F0216E52800000000A3 +:1039600002168248000000000216824C003F003F11 +:103970000216E52C000000000216E530003F003F73 +:10398000021682500100010002168254010001005B +:103990000216E534010001000216E53801000100BD +:1039A00006168258000000020216E53C00000000E6 +:1039B0000216E540000000000216826000C000C050 +:1039C0000216826400C000C00216E54400C000C0B8 +:1039D0000216E54800C000C0021682681E001E00E4 +:1039E0000216826C1E001E000216E54C1E001E0010 +:1039F0000216E5501E001E000216827040004000B4 +:103A000002168274400040000216E5544000400057 +:103A10000216E558400040000216827880008000BF +:103A20000216827C800080000216E55C8000800027 +:103A30000216E560800080000216828020002000CF +:103A400002168284200020000216E5642000200077 +:103A50000216E56820002000061682880000000299 +:103A60000216E56C000000000216E5700000000080 +:103A700002168290000000000216829400000000EE +:103A80000216E574000000000216E5780000000050 +:103A900002168298000000000216829C00000000BE +:103AA0000216E57C000000000216E5800000000020 +:103AB000021682A000000000021682A4000000018D +:103AC000061682A80000000A021681F400000C0805 +:103AD000021681F800000040021681FC000001007F +:103AE0000216820000000020021682040000001767 +:103AF00002168208000000800216820C00000200FC +:103B000002168210000000000216821801FF01FF59 +:103B10000216821401FF01FF0216E51001FF01FFEA +:103B20000216E50C01FF01FF0216823C00000013A3 +:103B3000021680900000013F0216806000000140E4 +:103B40000216806400000140061680680000000232 +:103B500002168070000000C0061680740000000786 +:103B60000216809C00000048021680A00000004859 +:103B7000061680A400000002021680AC0000004877 +:103B8000061680B000000007021682380000800090 +:103B900002168234000025E40216809400007FFFA4 +:103BA00002168220000F000F0216821C000F000F69 +:103BB0000216E518000F000F0216E514000F000FA3 +:103BC000021682280000000002168224FFFFFFFF79 +:103BD0000216E520000000000216E51CFFFFFFFFB3 +:103BE0000216E6BC000000000216E6C0000000025B +:103BF0000216E6C4000000010216E6C80000000339 +:103C00000216E6CC000000040216E6D00000000612 +:103C10000216E6D4000000050216E6D800000007F0 +:103C2000021680EC000000FF0214000000000001FA +:103C30000214000C0000000102140040000000010A +:103C40000214004400007FFF0214000C000000007A +:103C500002140000000000000214006C00000000CC +:103C600002140004000000010214003000000001F2 +:103C700002140004000000000214005C00000000B8 +:103C800002140008000000010214003400000001CA +:103C90000214000800000000021400600000000090 +:103CA00006028000000020000202005800000032DE +:103CB000020200A003150020020200A40315002048 +:103CC000020200A801000030020200AC081000004F +:103CD000020200B000000033020200B40000003015 +:103CE000020200B800000031020200BC0000000324 +:103CF000020200C000000006020200C4000000032F +:103D0000020200C800000003020200CC0000000212 +:103D1000020200D000000000020200D400000002F5 +:103D2000020200DC00000000020200E000000006C9 +:103D3000020200E400000004020200E800000002A9 +:103D4000020200EC00000002020200F0000000018C +:103D5000020200FC00000006020201200000000038 +:103D60000202013400000002020201B00000000162 +:103D70000202020C00000001020202140000000115 +:103D80000202021800000002020204040000000106 +:103D90000202040C00000040020204100000004077 +:103DA0000202041C000000040202042000000020A3 +:103DB0000202042400000002020204280000002085 +:103DC000060205000000001204020480002004AA7C +:103DD000020200600000000F020200640000000701 +:103DE00002020068000000000202006C0000000EE9 +:103DF000020200700000000E0602007400000003C2 +:103E0000020200F4000000040202000400000001AD +:103E100002020008000000010202000C0000000184 +:103E20000202001000000001020200140000000164 +:103E300002020018000000010202001C0000000144 +:103E40000202002000000001020200240000000124 +:103E500002020028000000010202002C0000000104 +:103E600002020030000000010202003400000001E4 +:103E700002020038000000010202003C00000001C4 +:103E800002020040000000010202004400000001A4 +:103E900002020048000000010202004C0000000184 +:103EA000020200500000000102020108000000C8E8 +:103EB0000202011800000002020201C4000000001A +:103EC000020201CC00000000020201D40000000246 +:103ED000020201DC00000002020201E4000000FF17 +:103EE000020201EC000000FF0202010000000000DD +:103EF0000202010C000000C80202011C00000002C6 +:103F0000020201C800000000020201D0000000000F +:103F1000020201D800000002020201E000000002DB +:103F2000020201E8000000FF020201F0000000FFB1 +:103F3000020201040000000002020108000000C8A3 +:103F40000202011800000002020201C40000000089 +:103F5000020201CC00000000020201D400000002B5 +:103F6000020201DC00000002020201E4000000FF86 +:103F7000020201EC000000FF02020100000000004C +:103F80000202010C000000C80202011C0000000235 +:103F9000020201C800000000020201D0000000007F +:103FA000020201D800000002020201E0000000024B +:103FB000020201E8000000FF020201F0000000FF21 +:103FC000020201040000000002020108000000C813 +:103FD0000202011800000002020201C400000000F9 +:103FE000020201CC00000000020201D40000000225 +:103FF000020201DC00000002020201E4000000FFF6 +:10400000020201EC000000FF0202010000000000BB +:104010000202010C000000C80202011C00000002A4 +:10402000020201C800000000020201D000000000EE +:10403000020201D800000002020201E000000002BA +:10404000020201E8000000FF020201F0000000FF90 +:10405000020201040000000002020108000000C882 +:104060000202011800000002020201C40000000068 +:10407000020201CC00000000020201D40000000294 +:10408000020201DC00000002020201E4000000FF65 +:10409000020201EC000000FF02020100000000002B +:1040A0000202010C000000C80202011C0000000214 +:1040B000020201C800000000020201D0000000005E +:1040C000020201D800000002020201E0000000022A +:1040D000020201E8000000FF020201F0000000FF00 +:1040E00002020104000000000728040000A10000F3 +:1040F000082807B8000904CA072C000034F700009C +:10410000072C800039250D3E072D000037CD1B8878 +:10411000072D80003292297C072E00001AF33621E9 +:10412000082E4390378E04CC0128000000000000C8 +:104130000128000400000000012800080000000021 +:104140000128000C00000000012800100000000001 +:1041500001280014000000000228002000000001D7 +:1041600002280024000000020228002800000003AA +:104170000228002C0000000002280030000000048B +:10418000022800340000000102280038000000006E +:104190000228003C0000000102280040000000044A +:1041A000022800440000000002280048000000012E +:1041B0000228004C0000000302280050000000000C +:1041C00002280054000000010228005800000004EA +:1041D0000228005C000000000228006000000001CE +:1041E00002280064000000030228006800000000AC +:1041F0000228006C0000000102280070000000048A +:10420000022800740000000002280078000000046A +:104210000228007C00000003062800800000000245 +:10422000022800A400003FFF022800A8000003FFAE +:1042300002280224000000000228023400000000CE +:104240000228024C00000000022802E40000FFFFE8 +:104250000628200000000800022B8BC0000000018F +:10426000022B800000000000022B8040000000189C +:10427000022B80800000000C022B80C00000006632 +:104280000C2B83000007A1200A2B830000000138BB +:104290000B2B8300000013880A2B834000000000D2 +:1042A0000C2B8340000001F40B2B83400000000521 +:1042B000022B83800007A120022B83C0000001F4A1 +:1042C000022B1480000000010A2B14800000000063 +:1042D000062A9AF800000004042A9B08000204CE73 +:1042E000062A9B1000000006062A90800000004865 +:1042F000062A2008000000C8062A2000000000024C +:10430000062A91A800000086062A900000000020DE +:10431000062A93C800000003042A93D4000104D0A5 +:10432000062A9DA800000002042A9498000404D1E3 +:10433000042A9D58000104D5062A9D5C0000001146 +:10434000042ACB20001004D6042A3000000204E620 +:10435000062A300800000100062A40400000001034 +:10436000042A4000001004E8042A8408000204F82B +:10437000062A9DA000000002062AB000000000509E +:10438000062ABB7000000070062AB150000000022F +:10439000062ABB6000000004062AD00000000800C6 +:1043A000062AC00000000150062A94A8000000322E +:1043B000062A502000000002062A503000000002A9 +:1043C000062A500000000002062A501000000002D9 +:1043D000022A520800000001042A9B28000204FA65 +:1043E000062A963800000022042A96C0000104FC28 +:1043F000062A96C400000003062A976800000022DF +:10440000042A97F0000104FD062A97F40000000337 +:10441000062A989800000022042A9920000104FE30 +:10442000062A992400000003062A99C800000022E9 +:10443000042A9A50000104FF062A9A54000000033F +:10444000062AB14000000002062AC54000000150C3 +:10445000062A957000000032062A5028000000024B +:10446000062A503800000002062A50080000000208 +:10447000062A501800000002022A520C0000000117 +:10448000042A9B3000020500062A96D00000002274 +:10449000042A975800010502062A975C00000003D1 +:1044A000062A980000000022042A988800010503CB +:1044B000062A988C00000003062A9930000000228A +:1044C000042A99B800010504062A99BC00000003DB +:1044D000062A9A6000000022042A9AE800010505D5 +:1044E000062A9AEC00000003062AB14800000002E8 +:1044F000022ACA8000000000042A9B38001005062A +:10450000062A50480000000E022ACA84000000005B +:10451000042A9B7800100516062A50800000000E21 +:10452000022ACA8800000000042A9BB80010052651 +:10453000062A50B80000000E022ACA8C00000000B3 +:10454000042A9BF800100536062A50F00000000EE1 +:10455000022ACA9000000000042A9C380010054678 +:10456000062A51280000000E022ACA94000000000A +:10457000042A9C7800100556062A51600000000E9F +:10458000022ACA9800000000042A9CB800100566A0 +:10459000062A51980000000E022ACA9C0000000062 +:1045A000042A9CF800100576062A51D00000000E5F +:1045B000021010080000000102101050000000015D +:1045C000021010000003D000021010040000003D93 +:1045D0000910180002000586091011000010078656 +:1045E0000610114000000008091011600010079625 +:1045F000061011A00000001806102400000000E0C2 +:104600000210201C00000000021020200000000109 +:10461000021020C00000000202102004000000016F +:10462000021020080000000109103C00000507A648 +:1046300009103800000507AB09103820000507B045 +:1046400006104C000000010002104028000000107D +:104650000210404400003FFF0210405800280000B4 +:10466000021040840084924A02104058000000006A +:104670000210800000001080021080AC00000000DA +:1046800002108038000000100210810000000000BD +:10469000061081200000000202108008000002B510 +:1046A0000210801000000000061082000000004A86 +:1046B000021081080001FFFF061081400000000287 +:1046C0000210800000001A800610900000000024F4 +:1046D000061091200000004A061093700000004A66 +:1046E000061095C00000004A0210800400001080EF +:1046F000021080B0000000010210803C0000001099 +:104700000210810400000000061081280000000251 +:104710000210800C000002B502108014000000009E +:10472000061084000000004A0210810C0001FFFF07 +:1047300006108148000000020210800400001A8068 +:104740000610909000000024061092480000004AD5 +:10475000061094980000004A061096E80000004AEF +:104760000210800000001080021080AC00000002E7 +:1047700002108038000000100210810000000000CC +:10478000061081200000000202108008000002B51F +:104790000210801000000000061082000000004A95 +:1047A000021081080001FFFF061081400000000296 +:1047B0000210800000001A80061090000000002403 +:1047C000061091200000004A061093700000004A75 +:1047D000061095C00000004A0210800400001080FE +:1047E000021080B0000000030210803C00000010A6 +:1047F0000210810400000000061081280000000261 +:104800000210800C000002B50210801400000000AD +:10481000061084000000004A0210810C0001FFFF16 +:1048200006108148000000020210800400001A8077 +:104830000610909000000024061092480000004AE4 +:10484000061094980000004A061096E80000004AFE +:104850000210800000001080021080AC00000004F4 +:1048600002108038000000100210810000000000DB +:10487000061081200000000202108008000002B52E +:104880000210801000000000061082000000004AA4 +:10489000021081080001FFFF0610814000000002A5 +:1048A0000210800000001A80061090000000002412 +:1048B000061091200000004A061093700000004A84 +:1048C000061095C00000004A02108004000010800D +:1048D000021080B0000000050210803C00000010B3 +:1048E0000210810400000000061081280000000270 +:1048F0000210800C000002B50210801400000000BD +:10490000061084000000004A0210810C0001FFFF25 +:1049100006108148000000020210800400001A8086 +:104920000610909000000024061092480000004AF3 +:10493000061094980000004A061096E80000004A0D +:104940000210800000001080021080AC0000000601 +:1049500002108038000000100210810000000000EA +:10496000061081200000000202108008000002B53D +:104970000210801000000000061082000000004AB3 +:10498000021081080001FFFF0610814000000002B4 +:104990000210800000001A80061090000000002421 +:1049A000061091200000004A061093700000004A93 +:1049B000061095C00000004A02108004000010801C +:1049C000021080B0000000070210803C00000010C0 +:1049D000021081040000000006108128000000027F +:1049E0000210800C000002B50210801400000000CC +:1049F000061084000000004A0210810C0001FFFF35 +:104A000006108148000000020210800400001A8095 +:104A10000610909000000024061092480000004A02 +:104A2000061094980000004A061096E80000004A1C +:104A3000021205B0000000010212049000E383405E +:104A40000212051400003C100212066C0000000166 +:104A5000021206700000000002120494FFFFFFFF24 +:104A600002120498FFFFFFFF0212049CFFFFFFFFEA +:104A7000021204A0FFFFFFFF021204A4FFFFFFFFCA +:104A8000021204A8FFFFFFFF021204ACFFFFFFFFAA +:104A9000021204B0FFFFFFFF021204BCFFFFFFFF82 +:104AA000021204C0FFFFFFFF021204C4FFFFFFFF5A +:104AB000021204C8FFFFFFFF021204CCFFFFFFFF3A +:104AC000021204D0FFFFFFFF021204D8FFFFFFFF16 +:104AD000021204DCFFFFFFFF021204E0FFFFFFFFF2 +:104AE000021204E4FFFFFFFF021204E8FFFFFFFFD2 +:104AF000021204ECFFFFFFFF021204F0FFFFFFFFB2 +:104B0000021204F4FFFFFFFF021204F8FFFFFFFF91 +:104B1000021204FCFFFFFFFF02120500FFFFFFFF70 +:104B200002120504FFFFFFFF02120508FFFFFFFF4F +:104B30000212050CFFFFFFFF02120510FFFFFFFF2F +:104B4000021204D4FF809000021204B4F00050005E +:104B5000021204B8F00010000212039000000008D6 +:104B60000212039C00000008021203A000000008CB +:104B7000021203A400000002021203BC00000004A1 +:104B8000021203C000000005021203C4000000046A +:104B9000021203D0000000000212036C00000001AA +:104BA000021203680000003F021201BC0000004036 +:104BB000021201C000001808021201C4000008031C +:104BC000021201C800000803021201CC00000040DC +:104BD000021201D000000003021201D400000803F9 +:104BE000021201D800000803021201DC00000803D1 +:104BF000021201E000010003021201E400000803B8 +:104C0000021201E800000803021201EC0000000398 +:104C1000021201F000000003021201F40000000380 +:104C2000021201F800000003021201FC0000000360 +:104C3000021202000000000302120204000000033E +:104C400002120208000000030212020C000000031E +:104C500002120210000000030212021400000003FE +:104C600002120218000000030212021C00000003DE +:104C700002120220000000030212022400000003BE +:104C800002120228000024030212022C0000002F4E +:104C90000212023000000009021202340000001962 +:104CA00002120238000001840212023C000001835B +:104CB0000212024000000306021202440000001922 +:104CC00002120248000000060212024C0000030615 +:104CD00002120250000003060212025400000306F2 +:104CE0000212025800000C860212025C0000030649 +:104CF00002120260000003060212026400000006B5 +:104D000002120268000000060212026C0000000697 +:104D10000212027000000006021202740000000677 +:104D200002120278000000060212027C0000000657 +:104D30000212028000000006021202840000000637 +:104D400002120288000000060212028C0000000617 +:104D500002120290000000060212029400000006F7 +:104D600002120298000000060212029C00000006D7 +:104D7000021202A000000306021202A400000013A7 +:104D8000021202A800000006021202B00000100485 +:104D9000021202B400001004021203240010644046 +:104DA0000212032800106440021205B40000000142 +:104DB000021201B0000000010600A0000000000C7B +:104DC0000200A050000000000200A05400000000FB +:104DD0000200A0EC555400000200A0F055555555B6 +:104DE0000200A0F4000055550200A0F8F0000000F9 +:104DF0000200A0FC555400000200A1005555555575 +:104E00000200A104000055550200A108F0000000B6 +:104E10000200A18C555400000200A1905555555533 +:104E20000200A194000055550200A198F000000076 +:104E30000200A19C000000000200A1A000010000EF +:104E40000200A1A4000050140200A1A8000000006C +:104E50000200A45C00000C000200A61C000000037D +:104E60000200A06CFF5C00000200A070FFF55FFF75 +:104E70000200A0740000FFFF0200A078F00003E031 +:104E80000200A07C000000000200A0800000A00042 +:104E90000600A084000000050200A0980FE00000BA +:104EA0000600A09C000000070200A0B8000004005B +:104EB0000600A0BC000000030200A0C80000100013 +:104EC0000600A0CC000000030200A0D800004000B3 +:104ED0000600A0DC000000030200A0E800010000C2 +:104EE0000600A22C000000040200A10CFF5C0000E0 +:104EF0000200A110FFF55FFF0200A1140000FFFFF8 +:104F00000200A118F00003E00200A11C0000000054 +:104F10000200A1200000A0000600A124000000055E +:104F20000200A1380FE000000600A13C00000007CD +:104F30000200A158000008000600A15C0000000368 +:104F40000200A168000020000600A16C0000000320 +:104F50000200A178000080000600A17C0000000390 +:104F60000200A188000200000600A23C000000042C +:104F70000200A030000000000200A0340000000089 +:104F80000200A038000000000200A03C0000000069 +:104F90000200A040000000000200A0440000000049 +:104FA0000200A048000000000200A04C0000000029 +:104FB00000000000000000000000003000000000C1 +:104FC00000000000000000000000000000000000E1 +:104FD00000000000000000000000000000000000D1 +:104FE0000000000000300031000000000000000060 +:104FF00000000000000000000000000000000000B1 +:1050000000000000000000000000000000000000A0 +:10501000003100520000000000000000000000000D +:105020000000000000000000000000000000000080 +:105030000000000000000000000000000052008995 +:1050400000000000000000000089008D008D00912C +:1050500000910095009500990099009D009D00A188 +:1050600000A100A500A500A900A900AE00AE00B1F6 +:1050700000B100B4000000000000000000000000CB +:105080000000000000000000000000000000000020 +:105090000000000000B40309030903130313031DF8 +:1050A000031D03240324032B032B03320332033990 +:1050B00003390340034003470347034E034E0355A0 +:1050C00000000000000000000000000000000000E0 +:1050D00000000000000000000000000000000000D0 +:1050E00000000000000000000000000000000000C0 +:1050F00000000000000000000000000000000000B0 +:10510000000000000000000000000000000000009F +:10511000000000000000000000000000000000008F +:10512000000000000000000000000000000000007F +:10513000000000000000000000000000000000006F +:10514000000000000000000000000000000000005F +:10515000000000000000000000000000000000004F +:10516000000000000000000000000000000000003F +:105170000355035B0000000000000000035B035CBC +:10518000035C035D035D035E035E035F035F036017 +:1051900003600361036103620362036300000000B4 +:1051A00000000000000000000000000000000000FF +:1051B00000000000000000000000000000000000EF +:1051C00000000000000000000363036D036D037B1B +:1051D000037B0389000000000000000000000000C5 +:1051E00000000000000000000000000000000000BF +:1051F00000000000000000000000000000000000AF +:10520000000000000000000000000000000000009E +:10521000000000000000000000000000000000008E +:105220000389038A00000000000000000000000065 +:10523000000000000000000000000000000000006E +:10524000000000000000000000000000038A03D6F8 +:10525000000000000000000000000000000000004E +:10526000000000000000000000000000000000003E +:10527000000000000000000003D604010000000050 +:10528000000000000000000000000000000000001E +:10529000000000000000000000000000000000000E +:1052A00000000000040104330000000000000000C2 +:1052B0000433043A043A0441044104480448044FC6 +:1052C000044F04560456045D045D04640464046BD6 +:1052D000046B04A4000000000000000004A404A863 +:1052E00004A804AC04AC04B004B004B404B404B81E +:1052F00004B804BC04BC04C004C004C404C4051342 +:105300000513052A052A05410541054305430545C1 +:1053100005450547054705490549054B054B054D1D +:10532000054D054F054F0551055105E805E805E90F +:1053300005E905EA05EA05EF05EF05F405F405F9C9 +:1053400005F905FE05FE0603060306080608060D18 +:10535000060D0612061206130000000000000000F1 +:10536000000000000000000000000000000000003D +:10537000000000000000000000000000000000002D +:1053800006130624000000000000000000000000DA +:10539000000000000000000000000000000000000D +:1053A0000000000000000000000000000624063994 +:1053B0000639063C063C063F0000000000000000E5 +:1053C00000000000000000000000000000000000DD +:1053D0000000000000000000063F0675000000000D +:1053E00000000000000000000000000000000000BD +:1053F00000000000000000000000000000000000AD +:1054000000000000067507780000000000000000A2 +:10541000000000000000000000000000000000008C +:10542000000000000000000000000000000000007C +:105430000778077F077F078307830787000000003F +:10544000000000000000000000000000000000005C +:10545000000000000000000000000000078707C8EF +:10546000000000000000000007C807D107D107DADC +:1054700007DA07E307E307EC07EC07F507F507FE94 +:1054800007FE080708070810081008670867087C67 +:10549000087C089108910894089408970897089A3E +:1054A000089A089D089D08A008A008A308A308A6BC +:1054B00008A608A908A908B2000000000000000022 +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00008B208B800000000000000000000000042 +:1054F00000000000000000000000000000000000AC +:1055000000000000000000000000000008B808BB18 +:10551000000000000000000000000000000000008B +:10552000000000000000000000000000000000007B +:10553000000000000000000008BB08C100000000DF +:10554000000000000000000000000000000000005B +:10555000000000000000000000000000000000004B +:10556000000000000000000000000000000000003B +:1055700008C108D008D008DF08DF08EE08EE08FDF3 +:1055800008FD090C090C091B091B092A092A0939FC +:10559000093909AA00000000000000000000000016 +:1055A00000000000000000000000000000000000FB +:1055B00000000000000000000000000009AA09BF70 +:1055C00009BF09D009D009E109E109E209E209E3CB +:1055D00009E309E409E409E509E509E609E609E75B +:1055E00009E709E809E809E90000000000000000F7 +:1055F00000000000000000000000000000000000AB +:10560000000000000000000000000000000000009A +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:10563000000000000000000000000000000000006A +:10564000000000000000000000000000000000005A +:10565000000000000000000000000000000000004A +:10566000000000000000000000000000000000003A +:10567000000000000000000000000000000000002A +:10568000000000000000000000000000000000001A +:10569000000000000000000000000000000000000A +:1056A00000000000000000000000000000000000FA +:1056B00000000000000000000000000000000000EA +:1056C000000000000000000000010000000204C013 +:1056D0000003098000040E4000051300000617C0F7 +:1056E00000071C800008214000092600000A2AC08B +:1056F000000B2F80000C3440000D3900000E3DC01F +:10570000000F42800010474000114C00001250C0B2 +:105710000013558000145A4000155F00001663C046 +:105720000017688000186D4000197200001A76C0DA +:10573000001B7B80001C8040001D8500001E89C06E +:10574000001F8E80000093400000200000004000F9 +:1057500000006000000080000000A0000000C00009 +:105760000000E000000100000001200000014000F6 +:1057700000016000000180000001A0000001C000E5 +:105780000001E000000200000002200000024000D2 +:1057900000026000000280000002A0000002C000C1 +:1057A0000002E000000300000003200000034000AE +:1057B00000036000000380000003A0000003C0009D +:1057C0000003E0000004000000042000000440008A +:1057D00000046000000480000004A0000004C00079 +:1057E0000004E00000050000000520000005400066 +:1057F00000056000000580000005A0000005C00055 +:105800000005E00000060000000620000006400041 +:1058100000066000000680000006A0000006C00030 +:105820000006E0000007000000072000000740001D +:1058300000076000000780000007A0000007C0000C +:105840000007E000000800000008200000084000F9 +:1058500000086000000880000008A0000008C000E8 +:105860000008E000000900000009200000094000D5 +:1058700000096000000980000009A0000009C000C4 +:105880000009E000000A0000000A2000000A4000B1 +:10589000000A6000000A8000000AA000000AC000A0 +:1058A000000AE000000B0000000B2000000B40008D +:1058B000000B6000000B8000000BA000000BC0007C +:1058C000000BE000000C0000000C2000000C400069 +:1058D000000C6000000C8000000CA000000CC00058 +:1058E000000CE000000D0000000D2000000D400045 +:1058F000000D6000000D8000000DA000000DC00034 +:10590000000DE000000E0000000E2000000E400020 +:10591000000E6000000E8000000EA000000EC0000F +:10592000000EE000000F0000000F2000000F4000FC +:10593000000F6000000F8000000FA000000FC000EB +:10594000000FE000001000000010200000104000D8 +:1059500000106000001080000010A0000010C000C7 +:105960000010E000001100000011200000114000B4 +:1059700000116000001180000011A0000011C000A3 +:105980000011E00000120000001220000012400090 +:1059900000126000001280000012A0000012C0007F +:1059A0000012E0000013000000132000001340006C +:1059B00000136000001380000013A0000013C0005B +:1059C0000013E00000140000001420000014400048 +:1059D00000146000001480000014A0000014C00037 +:1059E0000014E00000150000001520000015400024 +:1059F00000156000001580000015A0000015C00013 +:105A00000015E000001600000016200000164000FF +:105A100000166000001680000016A0000016C000EE +:105A20000016E000001700000017200000174000DB +:105A300000176000001780000017A0000017C000CA +:105A40000017E000001800000018200000184000B7 +:105A500000186000001880000018A0000018C000A6 +:105A60000018E00000190000001920000019400093 +:105A700000196000001980000019A0000019C00082 +:105A80000019E000001A0000001A2000001A40006F +:105A9000001A6000001A8000001AA000001AC0005E +:105AA000001AE000001B0000001B2000001B40004B +:105AB000001B6000001B8000001BA000001BC0003A +:105AC000001BE000001C0000001C2000001C400027 +:105AD000001C6000001C8000001CA000001CC00016 +:105AE000001CE000001D0000001D2000001D400003 +:105AF000001D6000001D8000001DA000001DC000F2 +:105B0000001DE000001E0000001E2000001E4000DE +:105B1000001E6000001E8000001EA000001EC000CD +:105B2000001EE000001F0000001F2000001F4000BA +:105B3000001F6000001F8000001FA000001FC000A9 +:105B4000001FE00000200000002020000020400096 +:105B500000206000002080000020A0000020C00085 +:105B60000020E00000210000002120000021400072 +:105B700000216000002180000021A0000021C00061 +:105B80000021E0000022000000222000002240004E +:105B900000226000002280000022A0000022C0003D +:105BA0000022E0000023000000232000002340002A +:105BB00000236000002380000023A0000023C00019 +:105BC0000023E00000240000002420000024400006 +:105BD00000246000002480000024A0000024C000F5 +:105BE0000024E000002500000025200000254000E2 +:105BF00000256000002580000025A0000025C000D1 +:105C00000025E000002600000026200000264000BD +:105C100000266000002680000026A0000026C000AC +:105C20000026E00000270000002720000027400099 +:105C300000276000002780000027A0000027C00088 +:105C40000027E00000280000002820000028400075 +:105C500000286000002880000028A0000028C00064 +:105C60000028E00000290000002920000029400051 +:105C700000296000002980000029A0000029C00040 +:105C80000029E000002A0000002A2000002A40002D +:105C9000002A6000002A8000002AA000002AC0001C +:105CA000002AE000002B0000002B2000002B400009 +:105CB000002B6000002B8000002BA000002BC000F8 +:105CC000002BE000002C0000002C2000002C4000E5 +:105CD000002C6000002C8000002CA000002CC000D4 +:105CE000002CE000002D0000002D2000002D4000C1 +:105CF000002D6000002D8000002DA000002DC000B0 +:105D0000002DE000002E0000002E2000002E40009C +:105D1000002E6000002E8000002EA000002EC0008B +:105D2000002EE000002F0000002F2000002F400078 +:105D3000002F6000002F8000002FA000002FC00067 +:105D4000002FE00000300000003020000030400054 +:105D500000306000003080000030A0000030C00043 +:105D60000030E00000310000003120000031400030 +:105D700000316000003180000031A0000031C0001F +:105D80000031E0000032000000322000003240000C +:105D900000326000003280000032A0000032C000FB +:105DA0000032E000003300000033200000334000E8 +:105DB00000336000003380000033A0000033C000D7 +:105DC0000033E000003400000034200000344000C4 +:105DD00000346000003480000034A0000034C000B3 +:105DE0000034E000003500000035200000354000A0 +:105DF00000356000003580000035A0000035C0008F +:105E00000035E0000036000000362000003640007B +:105E100000366000003680000036A0000036C0006A +:105E20000036E00000370000003720000037400057 +:105E300000376000003780000037A0000037C00046 +:105E40000037E00000380000003820000038400033 +:105E500000386000003880000038A0000038C00022 +:105E60000038E0000039000000392000003940000F +:105E700000396000003980000039A0000039C000FE +:105E80000039E000003A0000003A2000003A4000EB +:105E9000003A6000003A8000003AA000003AC000DA +:105EA000003AE000003B0000003B2000003B4000C7 +:105EB000003B6000003B8000003BA000003BC000B6 +:105EC000003BE000003C0000003C2000003C4000A3 +:105ED000003C6000003C8000003CA000003CC00092 +:105EE000003CE000003D0000003D2000003D40007F +:105EF000003D6000003D8000003DA000003DC0006E +:105F0000003DE000003E0000003E2000003E40005A +:105F1000003E6000003E8000003EA000003EC00049 +:105F2000003EE000003F0000003F2000003F400036 +:105F3000003F6000003F8000003FA000003FC00025 +:105F4000003FE000003FE00100000000000001FF12 +:105F50000000020000007FF800007FF80000014010 +:105F600000003500000000010000FF0000000000FC +:105F70000000FF00000000000000FF000000000023 +:105F80000000FF00000000000000FF000000000013 +:105F90000000FF00000000000000FF000000000003 +:105FA0000000FF000000000000000000140AFF00D5 +:105FB00000000001000000000020100100000000AF +:105FC0000100900000000100000090020000900419 +:105FD00000009006000090080000900A0000900C5D +:105FE0000000900E0000901000009012000090142D +:105FF00000009016000090180000901A0000901CFD +:106000000000901E000090200000902200009024CC +:1060100000009026000090280000902A0000902C9C +:106020000000902E0000903000009032000090346C +:1060300000009036000090380000903A0000903C3C +:106040000000903E0000904000009042000090440C +:1060500000009046000090480000904A0000904CDC +:106060000000904E000090500000905200009054AC +:1060700000009056000090580000905A0000905C7C +:106080000000905E0000906000009062000090644C +:1060900000009066000090680000906A0000906C1C +:1060A0000000906E000090700000907200009074EC +:1060B00000009076000090780000907A0000907CBC +:1060C0000000907E0000908000009082000090848C +:1060D00000009086000090880000908A0000908C5C +:1060E0000000908E0000909000009092000090942C +:1060F00000009096000090980000909A0000909CFC +:106100000000909E000090A0000090A2000090A4CB +:10611000000090A6000090A8000090AA000090AC9B +:10612000000090AE000090B0000090B2000090B46B +:10613000000090B6000090B8000090BA000090BC3B +:10614000000090BE000090C0000090C2000090C40B +:10615000000090C6000090C8000090CA000090CCDB +:10616000000090CE000090D0000090D2000090D4AB +:10617000000090D6000090D8000090DA000090DC7B +:10618000000090DE000090E0000090E2000090E44B +:10619000000090E6000090E8000090EA000090EC1B +:1061A000000090EE000090F0000090F2000090F4EB +:1061B000000090F6000090F8000090FA000090FCBB +:1061C000000090FE00009100000091020000910488 +:1061D00000009106000091080000910A0000910C57 +:1061E0000000910E00009110000091120000911427 +:1061F00000009116000091180000911A0000911CF7 +:106200000000911E000091200000912200009124C6 +:1062100000009126000091280000912A0000912C96 +:106220000000912E00009130000091320000913466 +:1062300000009136000091380000913A0000913C36 +:106240000000913E00009140000091420000914406 +:1062500000009146000091480000914A0000914CD6 +:106260000000914E000091500000915200009154A6 +:1062700000009156000091580000915A0000915C76 +:106280000000915E00009160000091620000916446 +:1062900000009166000091680000916A0000916C16 +:1062A0000000916E000091700000917200009174E6 +:1062B00000009176000091780000917A0000917CB6 +:1062C0000000917E00009180000091820000918486 +:1062D00000009186000091880000918A0000918C56 +:1062E0000000918E00009190000091920000919426 +:1062F00000009196000091980000919A0000919CF6 +:106300000000919E000091A0000091A2000091A4C5 +:10631000000091A6000091A8000091AA000091AC95 +:10632000000091AE000091B0000091B2000091B465 +:10633000000091B6000091B8000091BA000091BC35 +:10634000000091BE000091C0000091C2000091C405 +:10635000000091C6000091C8000091CA000091CCD5 +:10636000000091CE000091D0000091D2000091D4A5 +:10637000000091D6000091D8000091DA000091DC75 +:10638000000091DE000091E0000091E2000091E445 +:10639000000091E6000091E8000091EA000091EC15 +:1063A000000091EE000091F0000091F2000091F4E5 +:1063B000000091F6000091F8000091FA000091FCB5 +:1063C000000091FEFFFFFFFFFFFFFFFFFFFFFFFF4A +:1063D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCD +:1063E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBD +:1063F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAD +:10640000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9C +:10641000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8C +:10642000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7C +:10643000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C +:10644000FFFFFFFF0000000300BEBC2000000000B3 +:10645000000000050000000300BEBC20000000009A +:10646000000000050000000300BEBC20000000008A +:10647000000000050000000300BEBC20000000007A +:10648000000000050000000300BEBC20000000006A +:10649000000000050000000300BEBC20000000005A +:1064A000000000050000000300BEBC20000000004A +:1064B000000000050000000300BEBC20000000003A +:1064C0000000000500002000000040C000006180C6 +:1064D000000082400000A3000000C3C00000E48070 +:1064E0000001054000012600000146C00001678050 +:1064F000000188400001A9000001C9C00001EA8034 +:1065000000020B4000022C0000024CC000026D8013 +:1065100000028E400002AF000002CFC00002F080F7 +:10652000000011400000800000010380000187008E +:1065300000020A8000028E00000311800003950013 +:106540000004188000049C0000051F800005A300C3 +:10655000000626800006AA0000072D800007B10073 +:10656000000834800008B80000093B800009BF0023 +:10657000000A4280000AC600000B4980000BCD00D3 +:10658000000C5080000CD400000D578000005B0010 +:1065900000007FF800007FF8000000D50000150023 +:1065A0000000FF00000000000000FF0000000000ED +:1065B0000000FF00000000000000FF0000000000DD +:1065C0000000FF00000000000000FF0000000000CD +:1065D0000000FF00000000000000FF0000000000BD +:1065E000000019000000000000000000FFFFFFFF96 +:1065F0000000000003938700000000000393870061 +:1066000000007FF800007FF80000069200001500EF +:106610000000FF000FFFFFFF0000FF000FFFFFFF64 +:10662000000000FF0000FF000FFFFFFF0000FF0061 +:106630000FFFFFFF000000FF0000FF000FFFFFFF44 +:106640000000FF000FFFFFFF000000FF0000FF0041 +:106650000FFFFFFF0000FF000FFFFFFF000000FF24 +:106660000000FF000FFFFFFF0000FF000FFFFFFF14 +:10667000000000FF0000FF000FFFFFFF0000FF0011 +:106680000FFFFFFF000000FF0000FF000FFFFFFFF4 +:106690000000FF000FFFFFFF000000FF0000FF00F1 +:1066A0000FFFFFFF0000FF000FFFFFFF000000FFD4 +:1066B0000000FF000FFFFFFF0000FF000FFFFFFFC4 +:1066C000000000FF0000FF000FFFFFFF0000FF00C1 +:1066D0000FFFFFFF000000FF0000FF000FFFFFFFA4 +:1066E0000000FF000FFFFFFF000000FF0000FF00A1 +:1066F0000FFFFFFF0000FF000FFFFFFF000000FF84 +:106700000000FF000FFFFFFF0000FF000FFFFFFF73 +:10671000000000FF0000FF000FFFFFFF0000FF0070 +:106720000FFFFFFF000000FF0000FF000FFFFFFF53 +:106730000000FF000FFFFFFF000000FF0000FF0050 +:106740000FFFFFFF0000FF000FFFFFFF000000FF33 +:106750000000FF000FFFFFFF0000FF000FFFFFFF23 +:10676000000000FF0000FF000FFFFFFF0000FF0020 +:106770000FFFFFFF000000FF0000FF000FFFFFFF03 +:106780000000FF000FFFFFFF000000FF0000FF0000 +:106790000FFFFFFF0000FF000FFFFFFF000000FFE3 +:1067A0000000FF000FFFFFFF0000FF000FFFFFFFD3 +:1067B000000000FF0000FF000FFFFFFF0000FF00D0 +:1067C0000FFFFFFF000000FF0000FF000FFFFFFFB3 +:1067D0000000FF000FFFFFFF000000FF0000FF00B0 +:1067E0000FFFFFFF0000FF000FFFFFFF000000FF93 +:1067F0000000FF000FFFFFFF0000FF000FFFFFFF83 +:10680000000000FF0000FF000FFFFFFF0000FF007F +:106810000FFFFFFF000000FF0000FF000FFFFFFF62 +:106820000000FF000FFFFFFF000000FF0000FF005F +:106830000FFFFFFF0000FF000FFFFFFF000000FF42 +:106840000000FF000FFFFFFF0000FF000FFFFFFF32 +:10685000000000FF0000FF000FFFFFFF0000FF002F +:106860000FFFFFFF000000FF0000FF000FFFFFFF12 +:106870000000FF000FFFFFFF000000FF0000FF000F +:106880000FFFFFFF0000FF000FFFFFFF000000FFF2 +:10689000000000FF000000FF000000FF000000FFFC +:1068A000000000FF000000FF000000FF000000FFEC +:1068B0000000FF00000000000000FF0000000000DA +:1068C0000000FF00000000000000FF0000000000CA +:1068D0000000FF00000000000000FF0000000000BA +:1068E0000000FF00000000000000FF0000000000AA +:1068F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA8 +:10690000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97 +:10691000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87 +:10692000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77 +:10693000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67 +:10694000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57 +:10695000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47 +:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:106970000000100000002080000031000000418075 +:10698000000052000000628000007300000083805D +:10699000000094000000A4800000B5000000C58045 +:1069A0000000D6000000E6800000F700000107802C +:1069B0000001180000012880000139000001498011 +:1069C00000015A0000016A8000017B0000018B80F9 +:1069D00000019C000001AC800001BD000001CD80E1 +:1069E0000001DE000001EE800001FF0000000F80CA +:1069F00000007FF800007FF8000003400000150051 +:106A000010000000000028AD000100010022000677 +:106A1000CCCCCCC5FFFFFFFFFFFFFFFF7058103C41 +:106A20000000FF00000000000000FF000000000068 +:106A30000000FF00000000000000FF000000000058 +:106A40000000FF00000000000000FF000000000048 +:106A50000000FF00000000000000FF000000000038 +:106A60000000000000000001CCCC0201CCCCCCCC5A +:106A7000CCCC0201CCCCCCCCCCCC0201CCCCCCCC80 +:106A8000CCCC0201CCCCCCCCCCCC0201CCCCCCCC70 +:106A9000CCCC0201CCCCCCCCCCCC0201CCCCCCCC60 +:106AA000CCCC0201CCCCCCCC00000000FFFFFFFF1F +:106AB000000E0000011600D6002625A0002625A005 +:106AC000002625A0002625A000720000012300F367 +:106AD000002625A0002625A0002625A0002625A00A +:106AE0000000FFFF000000000000FFFF00000000AA +:106AF0000000FFFF000000000000FFFF000000009A +:106B00000000FFFF000000000000FFFF0000000089 +:106B10000000FFFF000000000000FFFF0000000079 +:106B20000000FFFF000000000000FFFF0000000069 +:106B30000000FFFF000000000000FFFF0000000059 +:106B40000000FFFF000000000000FFFF0000000049 +:106B50000000FFFF000000000000FFFF0000000039 +:106B60000000FFFF000000000000FFFF0000000029 +:106B70000000FFFF000000000000FFFF0000000019 +:106B80000000FFFF000000000000FFFF0000000009 +:106B90000000FFFF000000000000FFFF00000000F9 +:106BA0000000FFFF000000000000FFFF00000000E9 +:106BB0000000FFFF000000000000FFFF00000000D9 +:106BC0000000FFFF000000000000FFFF00000000C9 +:106BD0000000FFFF000000000000FFFF00000000B9 +:106BE0000000FFFF000000000000FFFF00000000A9 +:106BF0000000FFFF000000000000FFFF0000000099 +:106C00000000FFFF000000000000FFFF0000000088 +:106C10000000FFFF000000000000FFFF0000000078 +:106C20000000FFFF000000000000FFFF0000000068 +:106C30000000FFFF000000000000FFFF0000000058 +:106C40000000FFFF000000000000FFFF0000000048 +:106C50000000FFFF000000000000FFFF0000000038 +:106C60000000FFFF000000000000FFFF0000000028 +:106C70000000FFFF000000000000FFFF0000000018 +:106C80000000FFFF000000000000FFFF0000000008 +:106C90000000FFFF000000000000FFFF00000000F8 +:106CA0000000FFFF000000000000FFFF00000000E8 +:106CB0000000FFFF000000000000FFFF00000000D8 +:106CC0000000FFFF000000000000FFFF00000000C8 +:106CD0000000FFFF000000000000FFFF00000000B8 +:106CE000FFFFFFF3318FFFFF0C30C30CC30C30C329 +:106CF000CF3CF300F3CF3CF30000CF3CCDCDCDCD66 +:106D0000FFFFFFF130EFFFFF0C30C30CC30C30C3AB +:106D1000CF3CF300F3CF3CF30001CF3CCDCDCDCD44 +:106D2000FFFFFFF6305FFFFF0C30C30CC30C30C316 +:106D3000CF3CF300F3CF3CF30002CF3CCDCDCDCD23 +:106D4000FFFFF4061CBFFFFF0C30C305C30C30C3AC +:106D5000CF300014F3CF3CF30004CF3CCDCDCDCDEC +:106D6000FFFFFFF2304FFFFF0C30C30CC30C30C3EA +:106D7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDD +:106D8000FFFFFFFA302FFFFF0C30C30CC30C30C3E2 +:106D9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB5 +:106DA000FFFFFFF731EFFFFF0C30C30CC30C30C304 +:106DB000CF3CF300F3CF3CF30020CF3CCDCDCDCD85 +:106DC000FFFFFFF5302FFFFF0C30C30CC30C30C3A7 +:106DD000CF3CF300F3CF3CF30040CF3CCDCDCDCD45 +:106DE000FFFFFFF3318FFFFF0C30C30CC30C30C328 +:106DF000CF3CF300F3CF3CF30000CF3CCDCDCDCD65 +:106E0000FFFFFFF1310FFFFF0C30C30CC30C30C389 +:106E1000CF3CF300F3CF3CF30001CF3CCDCDCDCD43 +:106E2000FFFFFFF6305FFFFF0C30C30CC30C30C315 +:106E3000CF3CF300F3CF3CF30002CF3CCDCDCDCD22 +:106E4000FFFFF4061CBFFFFF0C30C305C30C30C3AB +:106E5000CF300014F3CF3CF30004CF3CCDCDCDCDEB +:106E6000FFFFFFF2304FFFFF0C30C30CC30C30C3E9 +:106E7000CF3CF300F3CF3CF30008CF3CCDCDCDCDDC +:106E8000FFFFFFFA302FFFFF0C30C30CC30C30C3E1 +:106E9000CF3CF300F3CF3CF30010CF3CCDCDCDCDB4 +:106EA000FFFFFFF730EFFFFF0C30C30CC30C30C304 +:106EB000CF3CF300F3CF3CF30020CF3CCDCDCDCD84 +:106EC000FFFFFFF5304FFFFF0C30C30CC30C30C386 +:106ED000CF3CF300F3CF3CF30040CF3CCDCDCDCD44 +:106EE000FFFFFFFF30CFFFFF0C30C30CC30C30C3DC +:106EF000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD98 +:106F0000FFFFFFFF30CFFFFF0C30C30CC30C30C3BB +:106F1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD76 +:106F2000FFFFFFFF30CFFFFF0C30C30CC30C30C39B +:106F3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD55 +:106F4000FFFFFFFF30CFFFFF0C30C30CC30C30C37B +:106F5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD33 +:106F6000FFFFFFFF30CFFFFF0C30C30CC30C30C35B +:106F7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0F +:106F8000FFFFFFFF30CFFFFF0C30C30CC30C30C33B +:106F9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE7 +:106FA000FFFFFFFF30CFFFFF0C30C30CC30C30C31B +:106FB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB7 +:106FC000FFFFFFFF30CFFFFF0C30C30CC30C30C3FB +:106FD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD77 +:106FE000FFFFFFF3320FFFFF0C30C30CC30C30C3A5 +:106FF000CF3CF300F3CF3CF30000CF3CCDCDCDCD63 +:10700000FFFFFFF1310FFFFF0C30C30CC30C30C387 +:10701000CF3CF300F3CF3CF30001CF3CCDCDCDCD41 +:10702000FFFFFFF6305FFFFF0C30C30CC30C30C313 +:10703000CF3CF300F3CF3CF30002CF3CCDCDCDCD20 +:10704000FFFFF4061CBFFFFF0C30C305C30C30C3A9 +:10705000CF300014F3CF3CF30004CF3CCDCDCDCDE9 +:10706000FFFFFFF2304FFFFF0C30C30CC30C30C3E7 +:10707000CF3CF300F3CF3CF30008CF3CCDCDCDCDDA +:10708000FFFFFF8A042FFFFF0C30C30CC30C30C37B +:10709000CF3CC000F3CF3CF30010CF3CCDCDCDCDE5 +:1070A000FFFFFF9705CFFFFF0C30C30CC30C30C3AD +:1070B000CF3CC000F3CF3CF30020CF3CCDCDCDCDB5 +:1070C000FFFFFFF5310FFFFF0C30C30CC30C30C3C3 +:1070D000CF3CF300F3CF3CF30040CF3CCDCDCDCD42 +:1070E000FFFFFFF3320FFFFF0C30C30CC30C30C3A4 +:1070F000CF3CF300F3CF3CF30000CF3CCDCDCDCD62 +:10710000FFFFFFF1302FFFFF0C30C30CC30C30C367 +:10711000CF3CF300F3CF3CF30001CF3CCDCDCDCD40 +:10712000FFFFFFF6305FFFFF0C30C30CC30C30C312 +:10713000CF3CF300F3CF3CF30002CF3CCDCDCDCD1F +:10714000FFFFFF061CBFFFFF0C30C30CC30C30C396 +:10715000CF3CC014F3CF3CF30004CF3CCDCDCDCD1C +:10716000FFFFFFF2304FFFFF0C30C30CC30C30C3E6 +:10717000CF3CF300F3CF3CF30008CF3CCDCDCDCDD9 +:10718000FFFFFFFA302FFFFF0C30C30CC30C30C3DE +:10719000CF3CF300F3CF3CF30010CF3CCDCDCDCDB1 +:1071A000FFFFFFF731CFFFFF0C30C30CC30C30C320 +:1071B000CF3CF300F3CF3CF30020CF3CCDCDCDCD81 +:1071C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F9 +:1071D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD75 +:1071E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D9 +:1071F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD95 +:10720000FFFFFFFF30CFFFFF0C30C30CC30C30C3B8 +:10721000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD73 +:10722000FFFFFFFF30CFFFFF0C30C30CC30C30C398 +:10723000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD52 +:10724000FFFFFFFF30CFFFFF0C30C30CC30C30C378 +:10725000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD30 +:10726000FFFFFFFF30CFFFFF0C30C30CC30C30C358 +:10727000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0C +:10728000FFFFFFFF30CFFFFF0C30C30CC30C30C338 +:10729000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE4 +:1072A000FFFFFFFF30CFFFFF0C30C30CC30C30C318 +:1072B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB4 +:1072C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F8 +:1072D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD74 +:1072E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D8 +:1072F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD94 +:10730000FFFFFFFF30CFFFFF0C30C30CC30C30C3B7 +:10731000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD72 +:10732000FFFFFFFF30CFFFFF0C30C30CC30C30C397 +:10733000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD51 +:10734000FFFFFFFF30CFFFFF0C30C30CC30C30C377 +:10735000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2F +:10736000FFFFFFFF30CFFFFF0C30C30CC30C30C357 +:10737000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0B +:10738000FFFFFFFF30CFFFFF0C30C30CC30C30C337 +:10739000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE3 +:1073A000FFFFFFFF30CFFFFF0C30C30CC30C30C317 +:1073B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB3 +:1073C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F7 +:1073D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD73 +:1073E000FFFFFFFF30CFFFFF0C30C30CC30C30C3D7 +:1073F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD93 +:10740000FFFFFFFF30CFFFFF0C30C30CC30C30C3B6 +:10741000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD71 +:10742000FFFFFFFF30CFFFFF0C30C30CC30C30C396 +:10743000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD50 +:10744000FFFFFFFF30CFFFFF0C30C30CC30C30C376 +:10745000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD2E +:10746000FFFFFFFF30CFFFFF0C30C30CC30C30C356 +:10747000CF3CF3CCF3CF3CF30008CF3CCDCDCDCD0A +:10748000FFFFFFFF30CFFFFF0C30C30CC30C30C336 +:10749000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDE2 +:1074A000FFFFFFFF30CFFFFF0C30C30CC30C30C316 +:1074B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDB2 +:1074C000FFFFFFFF30CFFFFF0C30C30CC30C30C3F6 +:1074D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD72 +:1074E000000C0000000700C000028130000B815832 +:1074F0000002021000010230000F024000010330C0 +:10750000000C0000000800C000028140000B8168F0 +:10751000000202200001024000070250000202C0E7 +:10752000001000000008010000028180000B81A80B +:107530000002026000018280000E82980008038031 +:107540000010000000010100000281100009013854 +:10755000000201C8000101E8000E01F8000002D895 +:10756000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC5B +:1075700000002000CCCCCCCCCCCCCCCCCCCCCCCC5B +:10758000CCCCCCCC00002000CCCCCCCCCCCCCCCC4B +:10759000CCCCCCCCCCCCCCCC040020000000000067 +:1075A0001F8B080000000000000BFB51CFC0F00350 +:1075B0008A37B231306CE344F0E98159181818F871 +:1075C00099C8D7BF0668C01620BE0CC47B5848D7E0 +:1075D0007F5E1AC15E20C9C0700488BBC51918EA55 +:1075E000A510E296320C0C3780FCC5503109A09EE4 +:1075F00069D2E4BB79140F1E9C648ACA773586D0A1 +:10760000374D2074329ABC1B545E500F42A79862CB +:107610003757488F38FB1354D0EC57C1AF3E5D034A +:10762000951F8EA6DE0FCA0700DCEC914ED8030032 +:1076300000000000000000001F8B08000000000098 +:10764000000BED7D0B7815D5B9E89AC79E3DFB99E7 +:1076500049086127049C8400C1F2D84280A0142705 +:107660001030B6D46E5E12BD081B1F95872411D34F +:10767000635A39CD401E2401243E4AE92DD50DC55B +:10768000367A6D1B6D6A698FF66C442D9EDBD303D1 +:10769000942AADE0096A2D58A0B1A71C68BFB6DCDA +:1076A000F5AF47F6CC64761E3EFAF57CB7F193C988 +:1076B0009A59CFFFBDFEFF5F2B0A2A443957217428 +:1076C000057EAE47C8101042D3534F744F86887260 +:1076D00010FABC8AC8CF255F7832CA40A84EA5CF21 +:1076E000FBFDE17DF06CAB4728391EBE8F4EA0300C +:1076F0004201848AE56C68E18F3E5100CF9A29B13E +:1077000049E439139E594844683894F3B57703B473 +:10771000EF2B12FEE764BC0CC693E82B24A3D268BF +:1077200092B47F00A119A979A09ACF6AB1506ADEFC +:10773000CEA7A42928C9EA5E817FA41519F160FAB1 +:10774000FA752785EFBE64A93F1685B2C9BC6424CB +:107750009379B1F60899C83A3F673F97EAD1775FC6 +:107760001ADB176EE9C6E5706BA957C9B3B95E435A +:10777000492F42B899D139113F83C8D837B16FBB6F +:10778000722430F8B1F9C0383AAE8FFF4718EE8D49 +:10779000D92811001CA2B80D6E8DC1C5AAE1D21F57 +:1077A0007FA26C0CB76236E7C2BEEBF5C1BC301CE1 +:1077B0007C302F17782E87794DEF3B2F5F91735ECA +:1077C0006B90153E439D977F024247001FB2811088 +:1077D000C1CB7DB6FE44CD30BB5DFA438C2E649D9B +:1077E000AD6F90780A148BA9F1010EBADF465FDE07 +:1077F00048969DDE9C740DF020F86A67F0894994E4 +:107800001FCC141EF13350AA0BA890148F00DE2257 +:107810000CEE913B9BEF15315F8551A2651CE6870D +:1078200048F7EA85C067E193379E459331FCA25340 +:10783000D579784D5A89FED002FC0C4CD404A0D7DF +:1078400036E0B36BA1BF5BCC325C6E80CEF270D100 +:10785000BCC93009DC0C1BDC30E47419973DF06BBB +:10786000A10BFC502F1E842BDEBEEDD3C1CF832C89 +:10787000F823FCBCD1469769F11EA7ED4CFC1FE034 +:107880002BCBD18F566EE7F330B294F1F7A7E01708 +:1078900002EF7BFF26E365A27DAA5E82D75B2C6A9E +:1078A00009A88FF44C1997031532023996998D0E59 +:1078B000628C0C889746842A80FF11EA448B26A5A7 +:1078C000E6F7AF8CBF723FF7E8EA66CC4F174B8301 +:1078D00051E0AF8886D0B0ACBEEBD9CEE44B6F3967 +:1078E000FA2C8A4F84F1122D85785E66548C3E0105 +:1078F000F3297E518B5BF8E574AF7C71D207D2E53A +:10790000194C1E60F848C5A2E19BFCE1E943FA80EE +:10791000F4118C2B36BE1C2ABE2E0C913E3EEC7808 +:107920001CAF7DF96A33C36BA30AF2AC455FDCAFD1 +:10793000BEEA8BD77D08EA078A91917069F75F5696 +:107940007DE17C5AE4BB538E4A236654EEED0F6F03 +:10795000D97678F07E7D7592FECE305C9435225FCC +:1079600015A6075A230F9B08D3DD45903D181E52DC +:10797000FB354928A32244E810FF24055CF6458C1A +:10798000441BA18304C10B9F9F57176DF095B3ED66 +:107990007218559A8275FEBE3A85CC4381F1B2C108 +:1079A0002EC01D6250C84194F485A1069D3FA8A435 +:1079B0002B63A06CB7335AF4A9C80D0F32C3AB20A8 +:1079C000707A7D6070F2C539DE52FB7C07DD2E28AF +:1079D000EBEFF2362E723AD54E46EF72FC6020CEB7 +:1079E000E1761DC3D3560F3A204CC1F220FF66B09A +:1079F00014D056F8340BDB21F0CCC5E5FCA9442E9D +:107A0000A00E4186799221311E11D677502F20E8A1 +:107A1000A41F51AD2172450A1AE4C9BFA79F171DC3 +:107A2000BFB7ACC6AB003F6B228ADE86E7B85E32DA +:107A3000F4CD4017D3B07CD2E1FDB872D0731E8173 +:107A4000CEEB4B422E59879CD59243ECB234F6DDF7 +:107A50001A19F3E454F8BE7D5C7FFC84129E9E6E7E +:107A60000B3C9DF6E0DD02B6073F817F99896602F7 +:107A70001C7F1F5D9C91EC075FEFD51FD6E4B129F9 +:107A80007BD0F97DBD846ADCE440B3A052BE544D86 +:107A900005EC03BEEEF5982FBC59C0E75BE87AB35E +:107AA000B3097CD777BCAAC916FE5B8FD58C776AE1 +:107AB000DFF57078F37E7ADB270EDBDA3BDBF5F659 +:107AC000C7E505B68781CE391D0484F83601BFF7B6 +:107AD00046179B7930FED36514FF69E6DF8BAF0F45 +:107AE000387FDE6E20BAFAFDFE8666D04FEF2AEDB3 +:107AF000375D8BE9E837CF48D12DF8EB9A3DE3CBE2 +:107B0000C16E7A97D137C7D3D9FD0D396EF4910E76 +:107B10004FAF0A3E320EA7AF35E28A7EE96120FA06 +:107B2000FA9E93BE3A977C2CF475C4495F0C1EE70D +:107B30003AE9FAD1EE61142F0C5F4EFCA4C5CB07D5 +:107B40006DD7979E7E2160BEF6762E71A727365F91 +:107B50008EAF0F3BDF81E82847370C0D8F3F02DBEC +:107B60003102E88F12144DEA60D745A9DE8A52BD72 +:107B7000C5E5126F7F41A0769A8C8E93F6124A9AD1 +:107B80001AB1B7ED76C67C09BFC4FD3416A384973D +:107B9000EC8B0C95E8A9621951FD67047371FD0C1B +:107BA000C47EA4D951587706B3FFD16CA67F056C6B +:107BB0006FE1F5054BECF687DF619F48B05F08BBCE +:107BC000D85B43DC1FFB44B63F0EA020D1477C7F2F +:107BD0009C863F7BF7C50CAEC315648878DDCA610F +:107BE0004F628B00DA0D11FD8C4E0A09EA2F40C559 +:107BF00060376F14F2A2A00FF03EAF27037F7FF72C +:107C00009B12D10F75919A554DB0EC9BEBC677E363 +:107C1000711FAE47D38A3CA9F11E96DB5580776B66 +:107C2000D146CDBAAEAF09F102D1A2777C11655A27 +:107C3000D134184E7EAB1BC343C48004FEF3071F30 +:107C40008DBCAC03FCE8FB5E3859CB52DF7236D8F2 +:107C50003C79A498043BAE3584A89D8F460A65986C +:107C60000E5A3DFCFBEB65B0DF6DF5D1F29E2DB3F6 +:107C7000369B501ECEEA9B95F47B2E2DDF273E517E +:107C800006DF139978CD5380AC13953117FEBE4FA4 +:107C9000A47E95067346EC2E323D6A7F5DC5F7D90A +:107CA0004B6E8ABE0CBF14E923C07F220563C4BE9D +:107CB0009198BD266B26D5E36AF4F0780CEF51C796 +:107CC000256462388C6A3F5AE6057A0F723B2D8A2A +:107CD00096E2F675CC1FA022BA3F06BFCE1542C76A +:107CE000FA08D8B720B0CF2CFB7689D963BD78725B +:107CF000E0ED11B986E06D6B7EEDE1023CBEB9505E +:107D00008C02D96CCD2FCC5C6DC1E3B7D4B9952270 +:107D1000D8318DD9C42EE1FB64601828E792290080 +:107D2000683BCBC078CCC7920F613A1D1DEB29038D +:107D300014E895DA8B648F8BCAB577895D2509576E +:107D40003E31783B0AD62D02BD62FA7DC2B2DE61B9 +:107D5000028AB9C9DD157216C1CBB00ABCDE7EFC41 +:107D6000049FC7FA84DA677135164A3F4EBA797EA6 +:107D700008786E01BE188912044E03C1351D3C9B64 +:107D800023CF661279FD11C3355D7B273C870994AB +:107D90005F56C8A5845F06EBDF6981FD14DEAF3650 +:107DA000811F0E3F1B981FCED9DE27B7A3A80B7EDD +:107DB0007DBADD3FA458E91EFF5F2BEA541F049DE6 +:107DC0007E228A67A75E58C0F4425304EB052A0F4F +:107DD00017821E0830F8374511F9AE8450C2C4DF4F +:107DE00003A00FB09D852652F9AFE2FF80DF465415 +:107DF000DAF58132487DF08E107B99F0174621CC60 +:107E00006FB7D07EE338A09F5C6A8F476E6F89584A +:107E1000FD05B522D5775C9F3D56D43B6F023F2FC1 +:107E20009BC36358A4023D26F2176710BFDD9D0176 +:107E30009B7C8A7C6931D9FF5AE899EC73DB997F86 +:107E4000341DFE342511779387BA249279858D9E4F +:107E500024F8FC0821E7309721236B0A7F64DB8735 +:107E600085A7F61C1E83D7FBF83522B11BE5D97216 +:107E7000D283E12B97BE5229E0E7E3B03680C72CCE +:107E800044E834A82F382B813E96BBD122DC5FB06A +:107E9000C2B92FB69425E8A76725D1DF563F753FB5 +:107EA000FBB8C13E1B30BCDEB2F03F42B10AD0B3DA +:107EB0003296E36D88B84BF3605CD9D072805E6413 +:107EC000231A24CFEEB20A5A8EB5C177DFECE8D17F +:107ED00072E0434D26F23EA152BCF17EE74805B662 +:107EE000FD5BA6E6F08FCA6625D0814F5710D0A75C +:107EF0002FAE180917FCD48A329377763AE1F4D181 +:107F00008F9CFB5074714AE47E6A3BDE6DF451989D +:107F1000C22B6F17ECE3A7B2E3D559FEA8F1E99B9A +:107F20004DF189303E99BFA40DE01C344504761113 +:107F3000AF17900A6DF8095EC61B2B6CE7EC2E4359 +:107F4000956EFA292029A43EE6FB7289DAE502D86B +:107F5000DBF3A53D06D079A208E306F7DFE2C126F0 +:107F6000112EB76C16395E89BCADDDD252B619D769 +:107F700069392988D214A09BE5049F3EE6F7B9E44D +:107F8000312B0A71BBB65122DAA783FEE9DFBFD5D8 +:107F9000506FF76F815F01ECEFFC1A6D2A80395D3D +:107FA000BB5D3562859BFFEB2E89FABF76D41C6BD7 +:107FB0002766E84BF67D876785011408FB8FBBA415 +:107FC000E9A976A112EAD74071BC1E5CDFC3D733A2 +:107FD0001CD3673FF18AFFCDF4092FE7B1788EB348 +:107FE000DE4F2446873A8597CAE8F05241FFF4CF26 +:107FF000E173B9456271901E1F227A7738F1DFE98B +:108000006C5D9279A40CFA9151F766D887EC12D185 +:108010001AEA578E117D1366E33D5EFA7B1FD4BBCF +:1080200041A6F27294D1D30A781EB54944E0C77EC6 +:108030004AD249D72356D41CF4E0F7AD9B5134887B +:108040005F8D867E71BB57C62A44EEABD954EEAB2A +:10805000B59804703D15EF6B745C6E3DD88A40AFE7 +:1080600087F1C6094C5EBD1489E0E7F6D4759B30F4 +:108070006EB8344AECD0436367907DD583D928EA43 +:10808000D5537281D3D1839B161B40072D781F06D1 +:10809000E596A22D2AF8B12F16CBA48CFE8CE1C355 +:1080A000FD85F81FDDA474D35A40E72B4FEC462220 +:1080B000E15B95E053D6E8FA5B43DF34617EE65A34 +:1080C00044EC23B06F497C468EAA20CFF377CF26AD +:1080D000FC236BED02D0C346147FCA4A27523049B5 +:1080E000E6DFFA1789D9EF2F6D06FB7D247485CB67 +:1080F000AF4AE7370FC51EE171416E8FB4C99D8449 +:108100000F4DCC63A06FB87DE22BEA24F4F9DF8C2D +:10811000BE07DBBFAFD8EE4775DA2B4E3BA556D472 +:108120006C76A9735D973CC91B617E6DB998BF0BD6 +:10813000FA8E775CA2FB923D91C5FF51A0A7FAE1B0 +:10814000DFB97DC4CBF9971502EFC1D7C7F20DF6A1 +:108150005E06E5A3D19C4FBFD03F9F723EBA84918B +:108160007E04F0239B2AE123A398F011E70FA9DBFB +:108170006C1983E94CAF13C1238DC04CCFC2E5AB62 +:10818000307D2785149D8E62E3CA1313EDE35DE80D +:10819000ECB15AD120FEEF28EE067F0F9B4788995D +:1081A000E92F4E70BABA0874C5E92C7FF702B2AE57 +:1081B0005781A0A7835E7597233F62760ED2F61B88 +:1081C000563FAD0F35BAC7CF6B1FEF377EAE167D6A +:1081D000B8F87948B6FBB3066A3FD4B8B9747918D1 +:1081E000A18FDE32DB873AEBC565265F4FEEB3C168 +:1081F000A50F3CA4EDD1783F74A27E487F3FD159B2 +:10820000838083138E3364E667F998E0E88C6BBF54 +:10821000CCE4FC40F2C06F1849710CF8C510F5DBD6 +:108220000411F3DBD8E9FDF14D94DEFD21712F88B7 +:10823000A870ED11D36B990FA6F725F2F014BDE7E6 +:10824000152793801FA7FE49A7770692B72B55E302 +:1082500036D925CF84EFB3537904988B5DF208D2D9 +:10826000E2B5E6A3C923182CBC7BFD962C2FE0F6C3 +:108270005246B7D8707803C365ED610FB1EFB1FE18 +:1082800093ACF1B2B56C7F773BDB1FDE896261F89E +:10829000781E8915C02FE7D1B1F0340BDDEF9415AE +:1082A000CA2F2D9EB7C06FCAE3E077B5D3329FCFF8 +:1082B000DDBBEDE5CFA1C539E0AFFBDCA31EF020AF +:1082C000A0B50EBF593D10049EFFDDA8A619F0D63B +:1082D000E4A176E8ED1A92216EBDE1075F9FB11A25 +:1082E000EC13667FBC87E5B26EB19FD605130AE03A +:1082F000F7EDAE69375F87A07DA2390FE2D7998885 +:10830000EC479D70BEA3C53EBF81E6EF9C2F425B4C +:10831000FA9D87DC21B8C659F7CBF6386BBA7C29B1 +:108320009E27F5924CF16FCE45C47E32DF0C241AA5 +:10833000883EA1795203B57F15DA4FFFE0ED7F3615 +:10834000C0F81BD49E05C4CECA3663E0EFE1F1BE8F +:108350002A54638CC4BFCACF2F3281E77AEB45061B +:1083600059AFA8FF7AE9E67D56534D714A6AFE5F20 +:1083700013E2276597F5DF2FC5ABA07F2FE0418281 +:10838000A74CF04DFCBB18BFD572B045C8803CA6C9 +:108390002EB2CFF3E9B28D1EAAE117906BC554AE91 +:1083A000058AEDDF9D7EDFDFF5E23D49F88F84969B +:1083B00075B01F824909FC32A5F2B9DEFA78BC2AF1 +:1083C0005817EC93508CC88D5A8DD6AF42FACED93F +:1083D0002584FFC8BEBBB6750C8997D70ED7A3E01E +:1083E000879551D4207D38E8AEFAB28012167D58B8 +:1083F0002DF728C067D5D82EB2BEDF18916CFE5776 +:10840000E7D383543D584CFDB9C43FA4E1B265DDC8 +:10841000BF6F17585E8A9EB1B41FBFDCC608F5F364 +:10842000DEDE3A3683FA03EDF2F702DB1FFDE4E904 +:108430006F28E0BF3FFFD4E99B00DEEBFF45422AF7 +:10844000E4653C1D4249628F2514B0C7D67549AE1C +:10845000FE0392390371CDEF8608BED63DEB4D2C5D +:10846000C4EDD73DF7F66484E777614BCF2B23C18A +:108470006E7E4AA07E6BB37BF212FC7E9D8C56B959 +:10848000F9058A3DD44E3DF7C34025F0B7D0717051 +:1084900025E9B773B9C76BD95F5FE5F1F07AD42EE0 +:1084A0007F52488C15DCE647F33ACE3D29D0F91DC2 +:1084B000F0247C30BF8EBD4A1CCFA3BAE37D224F8F +:1084C000E67DF7DB618043F501C9A607AA3BA4A4BA +:1084D0007732799E8627C483841940278C5EBA360A +:1084E00090385055E7B6F7C14F517DC02ED7305C5C +:1084F000A24980EBEB52742194BFF7ADB08E41F5E9 +:10850000DE9127C20057DCEF6A2503F48D9DBEA1E2 +:10851000FFCB597DFB43A887C4E1AA3B5BE9785DAB +:108520009FF90DE8956A87FC7C0F7EC9ED6BCFC47F +:108530003C0EBBB0637071B8F5DFBEF89889C73DDB +:10854000F7EC6F1F33F1FCEFF9EB7F3DF600F0E73E +:108550008F7D1AC8FFEAA77E1146167A5CE7A1FC58 +:10856000786114327371BD0BBFF4264CFCEAC20B68 +:10857000BF19ADE3755F78E68F393AAE5FFBC2FC99 +:10858000110087DAEFCF1BD1DF7E1BE835E1B5CED6 +:108590002B41F0AA1F10A811F43C7B3AF073A8EB12 +:1085A000D06898E7F913DE28D83DD5F85DDD54C0D2 +:1085B000D706A28FA1BC09C3B9EAE9ADEF839CE855 +:1085C0000B6F73A4489CF0C991E08CAFEA7A7B01F1 +:1085D000C11BEA217AD459BFFA38C6E794F4F8BB34 +:1085E00088FEAC80BCAB7EBA958ED789F117EE8B36 +:1085F000BFF3F0CBACBEF86B71E0EF22BAE7F15CF1 +:108600004868EB1A668B7FF2672AEE17CB88F52352 +:108610002FB83C1808BE6B043AAF651E63B707F865 +:10862000EAD9402F7E17027EBF7D7134C2F471C635 +:10863000D3B312E466CF0B5E6D1F7EBFEE85D70904 +:108640009F5DF8FE51452779972828E4B0FC2FFA62 +:108650007304E47015DDCBA1EAFDA1A4379CC253DD +:10866000556251851E26EF4F93F7094AFF558983BE +:108670004B0517BC1DF314523B2A319CC065C3FE49 +:1086800037146A5FA6F02994023E4F2F80F7E9F075 +:10869000C9D7AFC1FA675AF0BA9FF2ADB37E15E6FB +:1086A0004FD07B7DF09B105E87E785BD5E19F4DEC1 +:1086B00005B0BF827DF19E823FB57F86BA5FF9A982 +:1086C00093BF795C98C1213D7D98CC0EE87F7D43B6 +:1086D00085DF8F3CBA8D8E381CCFFDD95DFE9F6142 +:1086E00072A30A99157916FB44F560FB04F2C65093 +:1086F000CC1C59909AEF39D84760FA3BF79444E282 +:1087000030CD9D87881C77CA8BAA34FEBF3FF2F11B +:108710000E1C9C0C72EDDC8B3F24F459F5F46905BA +:10872000FC63AF747C4FE99E98E207D00F098B7E03 +:1087300038F79D8393A93C70DFFF2A0AEDBFFA79D1 +:108740007BFFD54FBF6FEB7FBDD9A9D0FC84FEC79F +:10875000794F3696C37ADF3BE241204FDFEB945CE2 +:10876000FDADBF05FD68C9336B3EBAE00D88DF97EC +:108770001CF3EBA047BBB618237680BD76CC8340B4 +:108780007E23D9F82DC497BB8EFA75C87BE83A765C +:10879000B3A45BFC133F70C073E671735E08F737D8 +:1087A000B33B56025B28A7DC283D2942CCA277FECA +:1087B000B5472B4680DC6F047B7E3C8C178D90F890 +:1087C00077784105CD0B14359FABFEA6FD79589CFB +:1087D000DCA38948B7D223DF6F31BF4F73D0DDFFF1 +:1087E0005CA670FB108F6B9183D856AD74C35B8908 +:1087F00042F741E9BE970EF07DB6C2F200D27CEF9F +:10880000E56F861F2524C6DCE63D99F5E3F4ABA6AB +:1088100093071ED6CF144567FDD3F502BC1759F256 +:10882000DD47A2C466F07FA160D019678EA9D63853 +:1088300073E591831057CE5EF27C2EC03F8C1AB543 +:1088400077891D8FA257FAB1639D716567BE61BAC2 +:1088500038B31AAC3A91447DFBEB1B5737485CBDEB +:1088600031BF5CB5C6D51BB53E71F50D0A1EB729E3 +:108870000D1E3EABCCBD17BE63B333EEF6BD49A1B2 +:10888000FEABEB51F7F756C33CA3342E3FDB01AFF1 +:108890004F3278FD780C5E38563D6548973D18BEDE +:1088A000F3961A8D2002E7AFE8597F10F88CC7E5E0 +:1088B000CDF1E295C0E0E137D47C8795EAE20795F7 +:1088C00041E43B202DCB552FA4E66132BE89907D3B +:1088D000128FBF1C3A75B70A724B46F18A024B3CA5 +:1088E0008CE4D1E3FE72923E64E0F92A9A4EECEDFC +:1088F0009CE4DAAFDE05F1722D9FC41FA4CBD71123 +:10890000FFA1B35F291235499E57502F932CE334B2 +:1089100067D3788CACC55CF381572AF1A761BDD2CF +:10892000E539A45F51A5F10C141C5C1EEC5796842C +:10893000097C550C5F908F0464B02E960FF5D09291 +:1089400030D133BEC39EBDF0DD17A4F951F78BFEC5 +:1089500028E44F39F3A3CADEA4F196E6D30289A333 +:1089600070FA6D2EA8B90AE4783FF9512F2B16BF83 +:108970007ABAFC285FF04E921FE5FBC0F951917264 +:10898000B0C79A337919AB133C8F6696EFF42BE599 +:10899000F03CD04FCD2C3F0A99AFCE23F57919D5B5 +:1089A0001C32E03BCBA7CAD9DADC00F5B347A29A68 +:1089B0004EE2CF33D0328B9CF579699CF9CB8AF1AA +:1089C0009F8A45EE71FCFB7AE96AAB0AFA1B3F49C4 +:1089D000BCB219D315D8ED39C95664D547FCC9E9DD +:1089E000A8B9A8FF789D7CF91AE2C7E765554B182E +:1089F000864B7D43A57A82D32FC4D3402FA97AFC1E +:108A0000AB77013D6707A3014A97244ED61224EEA7 +:108A1000A93EEB6829BA9DC4BD2E6AD4DBCDE9B866 +:108A2000EFFCE7B0F9179A405F1783288A5CE45F90 +:108A30006A1D25641D2B1543F55AE0987D957BBE74 +:108A4000E9762F5D4F536C45EC2E98C91A7BDC9567 +:108A5000E75FF0FA01213E1CFAF564D3B8ABA852E7 +:108A60007E4BE10BAB0A8B7FB301AD308104E41583 +:108A70009DE4C8A2AC2548FD31BEF868AF2D3ED7B5 +:108A80004DE3B88E78E27CE91ECADF03E06F07DBB6 +:108A90009F6C83B8DB7888CF45D8B93D9DC5E90C7C +:108AA0009A2F94869E5A8AFA8F43B5D74749FB9DE1 +:108AB000F5A5340F4940CCAFFDF506A013704B501F +:108AC000BADFDF007C1092385F3C45CA0F0AB41C45 +:108AD000DFDA45F8E6D0A9D72BEFC0F4D16CF8095E +:108AE000FF0FB43E2D3183E075A8E3F45D2F1DB771 +:108AF000C50892FDEE40EBD69274DCC18EC3E3E371 +:108B0000A9F5A9649C667D8071DAE93803CF9FF2EC +:108B1000C98E836B2B20AEAC62FEF7E1F7EAEC1E48 +:108B2000E4161FCA60FC73E89497C8EB966C9AC76A +:108B3000EB290E1AD40968EFDF3331672E39C7509D +:108B40007235C98BDF71B095C81905C6C1553CD1C6 +:108B5000E06ADA2E6EC0F9D970398A825FDF539CE1 +:108B60007307BCAF43EDB1B9A0874BE9B92D4F7185 +:108B7000F15DD04F26F0259EC73495E67D788AAF0B +:108B8000BD1BEA1F9CFE5ABC01E0544AE9001DCE01 +:108B9000B5C1B1592FE4E771FAE57B4FA93D6E816C +:108BA00054BF2D6F09C94B49BC1CCB856D5E8BFF33 +:108BB0001BEBC59D50F6A01213ECBD5DB7DC1CB5D8 +:108BC000F2F39795D8C3548EF03C2CCEE7EEF970B3 +:108BD000CDD93CAF2CAE4A2570FEA8374F7A61AE96 +:108BE00035AF8BE54907799E7494C6E1DAF17F6E63 +:108BF0007971CEF3891F559EF477BC6C3F1C40A35E +:108C0000204FFA471E144DE279B7FD428A421E8C6E +:108C1000933E9CFD39F3FB7BED9134FCFC6B008EA5 +:108C200045EEE5C61D78BBD347E2737CBC97403E5A +:108C30004D1C984F47AEB1F733AAC67EEEEAAA3A6A +:108C40007BBCAAC0CCB3D51FD35268FB3EB6FD6A2D +:108C5000DBF7F1BBA7DACA1312D7DAEA7FA263AE59 +:108C6000AD3CA9F353B6FA530E2CB695AF49DE6A64 +:108C7000AB3FEDF0EDB6EFD38FACB37D9F7962A340 +:108C8000AD3CABFB8BB6FA75D83C51483E1C8D37DA +:108C9000A1ED23452B7DB66662BD9281E1988909DD +:108CA0008626EB937833CD314EE51938DB49458A7A +:108CB000A161FE95F471E51AC91FBC93F09154941B +:108CC000335727EF672C00BF132AA1E7AF7CAC3FD7 +:108CD0004F114AC2B94B39E8C0AF232EED91B6937C +:108CE00078AA72F286C342B82F5E3D11679EE2E019 +:108CF000E2DAB2EE683744BEC854595C7B14E60B26 +:108D0000E247FCB344CE3D9787887D60D9DF1038B9 +:108D1000F2FDCD1C1535024C395F94ADE81949F2CE +:108D2000D97BF7355E7128F9C67DF58A97D85D5CE9 +:108D3000CE0CA457A4C4345B1E82F389E5DF14155E +:108D4000F6E1E15B893CEADD17F4CAC7D854F8EED6 +:108D500091A3443EF6CABF8E3C9B5C18AC7DE69462 +:108D6000D36D20F4C9791F77791D863C302C971E6E +:108D70005C72138983A15A643BE79753195341EFFF +:108D800061BBAC42B5EC9FC3A5D43EFB7BB353BDE6 +:108D90006CBDBD74CAEC550ED76105353112D70BC9 +:108DA0008908F6550DB3A311F003B64015CB3E6DFF +:108DB000973A86C8D1C6A02282BFB4F1F07C121FB8 +:108DC000F0FA622AE4D135786215B0AE864C517360 +:108DD000CB77DAA252FF8C521798B6BF1FFA501405 +:108DE000BCEF7759EF3E95FA5D1AB5C58741CF655F +:108DF00085141D526E9B0FCE5A04E3CA0B650DF607 +:108E0000B5086FE2DEB6C41521DF1711F88B442FC9 +:108E10002A756132FE40F3BD47A57E066F9DAFDF28 +:108E2000F97A15773F45BAF96E85F9660F3C5F6FA1 +:108E300036CD5FF5D605C9F8FF0C1759B8C0DF83EA +:108E40008C96725CAFE9F40DED458462689EDE237A +:108E50000BA7123AC582DA46BF7C1F81E937A10E03 +:108E60004FEDDFF939D5BB559A97C0F18A74EA8F77 +:108E7000181697C9BE372B4EF7BF29F941E928CB01 +:108E80001345E45C57BE4CE292E0A6B1FA31FECA4B +:108E9000F671DE4F4609BE5A3F23A32D406F457839 +:108EA0003D70DEF6308D3BB57AA295B1606A3CDE4E +:108EB000FE4D860F192DCD20F95BD2C2889BFDD9BE +:108EC0004BE70C6E4E39FB632E6773512E95B3132F +:108ED00097C311A174FD38ED0D7EBE67E8E74EDA49 +:108EE000093C5BF31F257634F78FA148C900FE1EAD +:108EF0001A2F4DE179B99EC478946F9C4A9C7EAD3F +:108F0000450CCF358EFC5D86678E5FEEB747916C62 +:108F1000C2D71CDF12C0137025CD8EF4A7AF24C6B4 +:108F2000374E789EF91F0ACF9FC31AF0336B145E39 +:108F30003FF0CDA11B11898339F891B7E374EF5C41 +:108F4000BFEAFB9FBD7E4E0FE9EB9BAEFB0F1ED72A +:108F50000D317A5399DE7CB9F4AD1638272267D3E8 +:108F6000FD6EA8B491DCD322235303FF5A889FCB14 +:108F700061E732793E957FA27DFFC1F30B4919F37A +:108F8000BB87ED3FFADC9BC2EC2C7E4EDF397F279E +:108F9000BEE6F8DCF30751BEBBDFD5198FE3F10D58 +:108FA0009E07CBE300040E78FD9E59628CC8BF1269 +:108FB00064EC75914FCB7C542F74BDE8237912A1DA +:108FC0004A85F863F34A926550CEAB4151D013D72E +:108FD0009E3982E2B8D3B17E2AF7F34A1202F83DF5 +:108FE000F2CED1BCD85D2C5E99579B10565BC679EA +:108FF000C047E5ECA553F713F9F8E2289A877E5F9E +:1090000019B5DF8E446E6F2F83714B693E7908EF7F +:1090100017216F2C74C24BF26F514937023F2AD689 +:109020000266087F3F538FA6DE3916F2BE54F23C2B +:1090300057AF91E7A151CAC1EB71BD8D057E1DFAF5 +:109040006D2AF4D373BB2195ECF7FF3BF373C4AFE8 +:109050007AA13E42EAB77CC9207645E3C1B3C46F2A +:109060001830A645A91FD5905029CCE788017E0E5F +:109070002447F5C5F0FDD02F493D4989FFD204FBB7 +:10908000E45685ECEF010E104F68F0D17CB9ADBE0F +:109090009A48263C0BD0AA452EF0BED5C7E34CAA71 +:1090A000A4E4A4F29094D2A49401FEE412D439165C +:1090B000E46553A20CF4345AABE9304EBE9A28034F +:1090C000FF71FE1A2D0A3E74A594DE23C2F1E1F170 +:1090D000A1D83341A89714EEC5E316FAA9DECC3B1C +:1090E0009120F70C5D3A35D3D5FEBFFF6419F9BE68 +:1090F000BDBEE258B9859F8369E2950F14CD7DD43A +:1091000087FBFD196C7486A7EF973F07DBEFCF7CD9 +:10911000549F1E3A357E04D8977569F2A8250DE351 +:109120006918954FE08FD838561F9119B4F643E16E +:1091300021BDF8438AD789943E1BBE3F3E03FA7D8A +:10914000E9D4720DFC7DBFCF2E22FB86F3CF790DC3 +:10915000B05FCE67A13524DFF2B999AFC0FEF0B79A +:10916000F587B3648B5C3CFF9DA3333CB8BFF3CF62 +:109170001E9D2113E64AD8F6F11BAEFC7C06D809E9 +:10918000E65C545C839FD59A82A0DF6A95AE83E744 +:10919000C9EDCA519AE1393F9049DAE78C101F8432 +:1091A000B2A4FE7CF43BD3C8BA695C81C571F0FA05 +:1091B0001A8284AE35BC018178A1E91D0DF1AC5352 +:1091C0005E427F970A5071C114F00B4AA45DCF5ADA +:1091D00094807C0A255903EC897C3F4D20E09BC09C +:1091E00071ED20A13576CF5BABAF90D121CD23DCE3 +:1091F0007CEAFEF1001F2ED7E57988C4337A6E51E0 +:1092000013608F3E2CEB5F590176E06D3299072E8B +:10921000FB34173C2E0F14DAE092C5E2131CAFE9C1 +:10922000E8645B3D8A166178FFB85E8DC2F8CFD7DF +:109230006BA4FCA3FA08291FA8D7C9F3B9FA62F2F4 +:10924000ECAA8F92EF1DF5A5E4C9F3FAC8D65E2209 +:10925000F674AC0CF4D032EA87D374D1807C850CE0 +:1092600019A9C3B0A9A29DFC4925ECB741AE64641D +:1092700011BE17A07D36CBF31B9E3BB7B54C4FC933 +:10928000572E4F1B3C48007964CEA27E8610F4878F +:10929000DB672F45E82D8B5CBF82FF79AB98AD0F64 +:1092A000CF27C3B07F77D60FCB7801597DDB61B96B +:1092B00048CAA97EDDE137D427F8CBDFB2D0F7AEBC +:1092C000E978D5988E7609548E3DC8BEEF983E2336 +:1092D000E37628CF9A9141F27F67215DC370DCA9C4 +:1092E0008BA62723557F4FFDE19CF2B14C07819C53 +:1092F000AAD5F6B659F631F9265A15B3D0CBCE1AFF +:10930000B9621FB133E2B98B27917C63E6D7DE5790 +:109310006ECC26FD927241DBA17293E915903373F6 +:109320002E533DD4AB7FFE4CDF73BDA730FC6F9F47 +:10933000BD450A039F803C057959124773F13C8370 +:109340009FA4F1EF59EF2411E4F72951FC1EEC51D1 +:1093500085E69BE4451202949FF4C5A6FA613F920C +:10936000B53BB90FE3FB0F5D5E1DE28D5D2FFE91F6 +:10937000E46748931515F83BEFF9D3246F4912BB06 +:1093800015D8F12E6BBB7ABE0CF62C4C84DC2B80EE +:109390001535C6B394C3D667763695031CC5F85900 +:1093A0006BFD5DFEF8BD74C78C0C3582F9C1C7DA60 +:1093B0009BE39B8C7C5CF6D0F2B2B6714DE66C28D8 +:1093C000E3FA99B4DC88ED846D999D111197839B24 +:1093D0008B9A0E8F8232AF5FD464E2F631A60F50C3 +:1093E000305E00FCDE5BD670396429CBB48C54FA55 +:1093F000E4EBDD70E88FAF8CC470A87A5EE82421BE +:10940000BEE7F70AB0EEBC037BE9B9800422FBFE9D +:10941000BC849080A39B1DF587B546EE5CE378C1C4 +:10942000A2614284DE1BA4243C51D85E4E60F782C8 +:1094300070BA782640F5C084046E6F8D4B3BEE0900 +:1094400099C0EEA1212403F2723B3DE7EBA4F3F1B6 +:10945000ACBF3A64B649A0B79FF668243ECEFCEC98 +:10946000E7B8DDC4FC39F730079E678BE9BF1AE423 +:10947000DF6A99F881D7172436631B0AADFF614173 +:10948000145BACA8C947E9657D6667CE544C2F4D87 +:1094900099F67203CB9F8F649A995913217FE8A1A3 +:1094A000D190DF5385DA577E11E6FB531A0F3F7BCD +:1094B0007056C675B8BCE1A7348EB1A1EBA802F412 +:1094C000BDC3CFF28EBAAEF914ACAF6ABB48CEC5FD +:1094D000015F1AE3F1748DF6AB654C2FFF1A383932 +:1094E000DF87F1FD64A1A189D720F4C6B6779BD4AC +:1094F0004FE2B2A24D00FA7863DBF926A0AFF5B3D4 +:10950000F87D76E75F368A58FE2306DE8EB6D94DA3 +:10951000700E63FFAD159F02732B47A4FC8B09925D +:10952000C4B5A5CC46727EEF774D22B19FC145BA36 +:1095300009C3BD48468765FCDCA5607C029F35CB2E +:10954000441EE2F72D1E829776727F086AA1F751BA +:109550008C7DDEBB1AECECA21A632DB1B7B589C4C1 +:109560000F301AF5FE903C89AB1095BFE3355426B9 +:10957000E37A2501EA2F2FAABC793DB493424BFD33 +:10958000C0EF3952C224FD7F8DCAE15D62A253054E +:10959000B91C2E24F8DD15A674613E3C91D0C57E21 +:1095A00071EED560173509ABDB5E05BC66169273AC +:1095B000AEF07E23AC9FE1B3418BAA80BFFD0C9F30 +:1095C000D25ED1847C4DFE7E9B70FB5A80EB3BFECD +:1095D0008DF3550CD71CAFD1320CE3E16DFFC6A65D +:1095E000C82C828742157F7FBBEDDE2615E365FF21 +:1095F00066234FB394C7FF054B752207EE257CDD2C +:10960000187C741D2821FCFD65F07F3C99C5F99EEE +:109610007E2F2AEC952306D8A50D664AAEA8582FB2 +:109620001459EA9763B9F0CDC72482D7C3783C9028 +:1096300013781D26D07DCF0499D8057E3C173F2E88 +:10964000FB2715927C5BBC6EE407BB61924CF43C3B +:109650008FE32813446237437DA0077F6E21C99FA3 +:10966000C3F23A06E77CA4088DEB48D21E03F33020 +:109670000AB0FC7D415B44EE17F1155BF20A40FE37 +:109680003AF210244779ACB73B17CE2B659F5C2488 +:109690008CC67839ED6771996CBC8FC5EF7FEDA7EB +:1096A000E71BEF8F993740BE0CD2BB73693C2A365B +:1096B000159E236E2B1AD19FFFA5EF7E354AEC979E +:1096C00047F265D77CB0E702745FE41D5544EECBEA +:1096D000A84398FF812FF8FD2A4C7E7898BDE03C86 +:1096E00027C0E5892793AEB1B675DE88AC60EA1C69 +:1096F0009C143454900707B5A919608FEA01CAEF8A +:109700008DC9599F05BB4566F2608F8F9E8FEDC94D +:10971000449DFB10D8BF5164CD4BE0F2607BBD4A45 +:109720009E4FCC1947E2974FCCC9990BF18A43D78A +:10973000BE47F6BF17F750FEBD78E465B823095D54 +:1097400034E9F95C202BE2974F3E42EE01F9861C8A +:10975000DB49F2E5215F074F6967A63D0FF38900FA +:10976000F59BFE89C927ACB7C9777E3F877CF91383 +:10977000C40FBC95C95D355E4EF695E0C6D3812E0B +:10978000503BB96789C3C1792F877C793269FF273C +:109790003F853FCF5F72E629F1F9FC80CDA7EF7DD1 +:1097A000AE767C70BF06C7036F5F2B1823B47EE8CC +:1097B000A6FAB2841296BC90D4B90D85BCBF00E75E +:1097C0005D32E05E9578FB7505C007096227FA8275 +:1097D0008DB6FB595144EEB19E2F0938CEBB38F9F6 +:1097E00005EE05063DADE8FD9F6BF935DEE6F2BC02 +:1097F0005C92A72EA3AF825D7B3EF0E60CF0C755CE +:10980000633101AE72249BE43CE905B62F919FBF02 +:10981000979CE7E1F3E3FE385EAE3AB088F8E9AA38 +:10982000F707C9799EAA0495831B54F3B057B4E691 +:10983000DD1A49C8B7F51CA0FDE980038C8F3F688D +:109840006B7261FD81BA3133E19C498E5873D568E2 +:10985000808F4CF100FBE56783E49CAE0C7A9C8F13 +:10986000FB4BB60F5CC6EC9100324580A7E48F76C7 +:10987000237A66D190B17D24F5CABDAB9B801F765B +:1098800039ECAD5D7E5ADEBCEDEAA646AA9F895C46 +:109890005CD6F62FC41E6AF2F1F273444EEE52DA31 +:1098A000932027CDE7BC3AE83DDC9E9C63376F2DC3 +:1098B00026FA432A447900B77270B480FC7BCEBB91 +:1098C0000FFC0C4FFAE231BF65BF733E746234EC9B +:1098D0002B5DFA336DFD8D1E5A7F78FC2EC003FF81 +:1098E0005E1EDE4DFAC7ED88BF03E51F7913DBBAB4 +:1098F00028E7392F3967B8C763B7B7F97337933398 +:109900002D8E7B39D478A3019B73CE9FCEFB9339E8 +:10991000BFCA9727D8F2A474A69F65D9005725FE21 +:109920003E917CFF939FD2410BCBC7493F4E569A45 +:1099300071EC71BBBEE3CC60720231FE97B5DEFB09 +:1099400036FBC97F75C6179DF28D3FB97CCB0E5093 +:10995000FE8A09F1AE001E675DA273819FF2E76483 +:10996000E0CF3B995E2AEE78E84550EBDF528DF769 +:10997000013F2B55636C60F8D0F9E70D369E8BFCE8 +:10998000A276D91A6AE7D6B64EFB14946B77146A9E +:10999000A64BBC883FD75C0ED8E4D70EBFCEEE45B1 +:1099A00034891C5B73394CBE7F74E3F96CE7D9FAD8 +:1099B0008E1724DFF978F738E4F3A16BFF6D572990 +:1099C000A6E3DA673CA2D7324EED33EC1C900FCB06 +:1099D0006B3BBF1BC0EF7201EACD5304F9B053617A +:1099E000651335835DF4A4553E9482DD966A0FF7C6 +:1099F00011EEF4F3F6BEE6F27C97FA0147FD42DE83 +:109A00007F26E9DF391F2E7FA00C769AFC172F9F47 +:109A10001F915F0F898EFEB2F8F879A43F6EAF7F79 +:109A2000A1ADF01553063A4D948DA4FE1D1DEC809A +:109A30006FC851BFF59EAB2FF8A9DC5C73798C0D14 +:109A4000DF29B88FB3BDFF4D7DC496AF7F77BC963D +:109A50009CD3F802F327AEC1163D69B767A42D4F1A +:109A6000FF1FF3F8A0F3B82ECD3CE6FC8DE7516064 +:109A7000E3CFD43C8A6CEF3FE83C7EE0A3F2F805EC +:109A8000F69CAFD17B01E6EB02F15BCFC7757D9809 +:109A9000D66FC04F153FE7CBC80C92FB6B13B43E9B +:109AA0002E833FE0B37FB9EF9DEBC97DCF06C9C7D9 +:109AB000E1F74EF1FB1007BA9FC8F9771B9CDF0353 +:109AC00069EE5FFD6290C2E9A129372192BF1E8C29 +:109AD0009338C1C1DC0511B0D3BF32A58A3C1B73DA +:109AE0006744401E35843E67CB37C77B04D773B0CD +:109AF000EFB17ED1E51B44EB7994AD701EC5A53E58 +:109B00008F8B6D55F9FD801FCF7A777F4CEB2D0D34 +:109B100051FDB9558D93B86073E4E399FFB3413AB1 +:109B2000CE4353E6203ADF39491AF75174EB796096 +:109B3000FE3C189A11817536642E88003D3766CE3A +:109B4000B0AD474AB39E957C3DDAC7BB9E7FEFC55B +:109B5000C7075DCF02D73C5839DBFDDEF9C6101DC3 +:109B60006F6B244EE8ECE35AD7990F8DA7A1AD2B6C +:109B70008BADEB8E20DD476CD5291F05A4D87F1453 +:109B80000803F3E1407F4F0415E9E260F2F07EC57F +:109B9000E0958E7F6FF52486C3BC4ED4D3FDF36B66 +:109BA000EC3EA95FAD690811BFB6639CADF9FB42FD +:109BB000FDF939FED71AFBF9F481E48619A471A0E6 +:109BC0005BE2F676CB2B03AEF79B60F8ED2C2848D2 +:109BD000C1B30FFE3F62B8A5A3C7A1C2AD393234ED +:109BE000B80DC40777C0253783801BA7B774FDFC69 +:109BF000FF4267BB83D46E1804BC087DFDADE0F561 +:109C0000F74A5FCF0E9EBEFE012FA23707475F5C6B +:109C10008E7528F49E45673FEF84E83D9BE3859A67 +:109C20006337427CE13312F1F71EDB53BE0189D664 +:109C30007A54BF1CAB98B781E4BBC60208EECF3A9A +:109C40002E46FFBD04E20E8B693B67FFC7187C5EA2 +:109C50000E65B27DBE3E1CFC08C7634BFA5D1FAAB1 +:109C6000B0AC8BE4655AEEA392FAC2F718D277949F +:109C700080BF69A1FB3C383ED38D3B547C1E8F7D59 +:109C80006348F81C68BD5DA1C1EAA504C14336EA7A +:109C9000FD3B1857033C3B449ACF710A5ECD82FBD3 +:109CA000C910A9B4BC7204B9E76C4A98E53D29FA19 +:109CB00006F09379972CDC16C2783BBE2C53B0DEAD +:109CC0007F2686A9DD326385BB5D9811A674906AF4 +:109CD0002FA0F17ADF7A7F65F6E3B215F45E2A24CD +:109CE0001BA3165BCED54D08DBBF3BDB47C2613201 +:109CF000CE71C1FD7E583F9BC7F2A5FDB747B5C3E6 +:109D0000D8E16D6D92DBFD829C3FFE4F283E2C8C8E +:109D1000EBBF26C4BFFE79A0A309411AF7905101F9 +:109D2000C4EB793FD9324A2A18EEEF78B449E0A75C +:109D300075E927BFBF7ED2C195AF878F03AC08F707 +:109D4000B2E0FD23D92F961808CD867DA2377A2F51 +:109D50003D6C48E9208BE5CFCCAC092436839D27A8 +:109D6000E3755AE6DBF5A7799F86EF5DC7446D4B37 +:109D7000415F380C241FCAC234DE902DC5B7F8C02D +:109D80003FB64A70BDDFECDA30FDFB23E742BD7120 +:109D9000F55130CEB847E31EB8E7E06696DF845051 +:109DA0007CD422CBF8E7189D38DB654B341E8D5EE2 +:109DB000A7FCDCB16FDD2837FEF939E3D373A1626C +:109DC0005B1ECED2D8BD1EE0CFA50B1779F4207C48 +:109DD000D729BDB1797428F151D70453704A2B8724 +:109DE000187CBA4EC41BE07E8755750289234DDC72 +:109DF00044E96ED5A683E206FCDCCBF86F91806C5B +:109E00007990F730BC76ECF38F86F977703F1D744C +:109E10008CE7B17237227EAF3B1FFCF456B84BB5CE +:109E20005B40CC4F76A002F20DBA599E8889BF6F75 +:109E300006F8950F27F31DB7E9FD5A90CF5D0A226A +:109E4000E7E5FEB3D54BFE6E05A7975E39B1E95243 +:109E50003D24DD3DA2242701DD0C6FA8F9BC9B9FAA +:109E6000FC0136CF3F0463196E762E7F7279CEEBFC +:109E70002D96758F5BFD25157639C6E73DCC9B3C4D +:109E8000EF765F432F1D26FAD77BBF60729CE3BD40 +:109E900017DF27DCF7455F6172AF2331773DD15B78 +:109EA000A6570779C8E7C3E1956D5238DDBC54B2B7 +:109EB000C9DB550B038EF34814AE9FF5EA8FC13A08 +:109EC0001ED9F76F93000F4EFDE097E20A7CBF1B8F +:109ED000253D2027CE483A79BE566FBF47FA351444 +:109EE000DF311DF4679DE4CA57CF32BCBC5679C739 +:109EF0003232FF464983F99F5E31ECA652902F958E +:109F00009E28E44F9E6EBC2F749765FD5CDF39E799 +:109F1000F5AB3577F4ABB79657DAF1D6A150BBC0A5 +:109F2000FC14E5C3B558DECC26F4D5BD63261EFF70 +:109F30005822EB9A365A1DC1DF695CC27E3F23C6A8 +:109F40001F9C89E5CD5991FAC3CC7FA27263E9A326 +:109F5000B12688F39EAD9BF64237AEF713A607DE17 +:109F6000ACEB5F3F3AE969DCA3F6FB29679C400A4A +:109F7000B48FD7BAEB835B32034CBE4447837CB9C2 +:109F80006D937BBD7F86E44A0CEFB37F95D6B8E531 +:109F90006D5ED6E87C57C5DCDB5FD642F43BE82536 +:109FA00017387F2F2340E5BCAC8D0639BD2ACD7C08 +:109FB000BF9B1126FDBCDD74FF6D10EF3B23DAE57E +:109FC000F3DE0C4A17F519543E9FDD77AB6738E096 +:109FD000A959D0801EDECA8C4E007A5BDD789AF8D3 +:109FE00011FE89D5AF0CC67E171E0EFCB278FE702E +:109FF0008C97AE15282AE8E9E5FF25C63FD912BDA2 +:10A00000C700EBBF7740FFE1A6EF10FB433646DF0A +:10A0100032895ED90879856745731DC943D9E7A799 +:10A020007947283ADD7ABF8C2783C2EFECFEA1E1A5 +:10A030007B592CD0AF1D7F0CB5579171F707348831 +:10A040003F1EAB9092D7E349BEBB3FB0572AE8CB47 +:10A0500017E9C61FAA1D7876FFD0ECC081D6FD890E +:10A060008C8241D9F5172B1E79B004F848699FEC12 +:10A07000267FB99C3ECEFC564EFAE1CF998C2ECE6F +:10A0800024FA9FD7DDBBEDF3B9ADC63E1FCE2F67D7 +:10A09000120D7EC80FC7A34FB2DAA5A87CFA00E75D +:10A0A0001CA8FF37DD3C3F9D6197134079104F5B43 +:10A0B000CBE4CD9B758F84AD7870AEFFACC8F6074E +:10A0C0008FD1BCADB1B1D57387EB29FAAC6470F810 +:10A0D000A8E992EB19673F7FEF74C8F5DC4074C8BC +:10A0E000E582B3FD3988F3E3A5AF963505E232E7A3 +:10A0F000C23A2D236D011C9141A5ECDC32D247C33D +:10A10000B99BB3FBFC08FECEA6D9E64D8CC52C70DE +:10A1100066DF7513ACEBF90AC3CFAAA59970AD0D34 +:10A12000A693E88D23487E8144EEEB7AED44D60277 +:10A13000283F724404098D6EAB5D2DC1FA1ECDA07F +:10A14000FBCE559B8E127B70A874BEAAC6AEFF2FA5 +:10A15000B375F4DA59724F09D04F3A383466503833 +:10A160002C8B2D9A0FF2F98E4D0291B74D193AF5BD +:10A17000D7CA0691DBA891EA47A462786015721AE3 +:10A180001601F0F832FBFB63724CB19E4FBA6BFBC9 +:10A19000FDF3C13E74F24B0ED34F481399BC8F7F31 +:10A1A0003B637A4A3EBF25D41C1C81AB5C9BA1F16A +:10A1B000FB61099FF2F55C9B41D787EDB46F93BFBC +:10A1C000BBC4D687A20E7A13DBAB7E04F09FAB1222 +:10A1D000BBC0EFC5721FF2E6BEE1D768DE1CE52BFF +:10A1E0006EEF38DBDF2CC76D76E3FF05B9373CBD7A +:10A1F0001DF20F7DE15EFF7D06B7BF95BEF8CB4730 +:10A20000A42F8E86759B9DC5F5C6FF03C8D629333E +:10A2100000800000000000001F8B0800000000000C +:10A22000000BDD7D0D7854D5B5E83E73664E669221 +:10A23000996492CCE41F9C49000324780221444095 +:10A2400098240482609D408060030E081A2584A82B +:10A250005879AFDCE684440C14BDF1E7AAB55EEF93 +:10A2600010D0F25ABC0D965A54DA8E54507BF53603 +:10A27000F88BFDA2466B292085E8AB57DB8F5BDEB0 +:10A280005AFB2773CEC94C08DAF6F2BDF0F19DEC0B +:10A29000B3F7D93FEB7FADBDF6CE098B3A3FD34341 +:10A2A00088B655264F10423E3CF65935961FE8B504 +:10A2B000B82528AFD8B84A0E390949C692979013E5 +:10A2C000E1C529583E8F3FB3873E6F7A44269142BD +:10A2D000427FCEC3FFEB5B920CE513DD890182E385 +:10A2E000CD7285C7FA09D9AF108D9412F2C1B6CCE0 +:10A2F000F0162857DB89E69C4CC8F4141F1DCFB319 +:10A30000F98B56F724984FF77F14937C98DF3D77AD +:10A31000AE08150D1DF72F6E0B215361009FCF4224 +:10A320003208B9C3CEC65C9D4C02D83F81F19ED0A5 +:10A33000F52FBE7BBB9590C8E5503F06BE2B8B7EAC +:10A3400067EE7FE975578EC675BF7DDD8CD1AB8A10 +:10A35000A2DFC583C35229F42F4B70DC365945B8B0 +:10A36000EEB937A1B13B06DCBE8D709D3A747CFC22 +:10A37000B1C23A16F3DF976CAEB8CB0520D9923450 +:10A38000EBAA508CF1DF26A17BA6C278DA66369E56 +:10A39000799C6BF8386FD7DFB004E1FFB926BB6555 +:10A3A00080477F839C5C8EDFD5DBD4B1D07FBF76C6 +:10A3B000BB6BAD6E9EBF8D039FDF36DEE08A8507E7 +:10A3C000F15C566FA4830FC8C06BD3709CDDB1E7FE +:10A3D000B75ED09712BAF74A98DFC9AB655583F9D3 +:10A3E0009CB4C077482F8FC277BEA1DFADE2DF7D7E +:10A3F000B07978BA5C5C639CCF92638946BAB490BA +:10A40000C69E18EB59FF15E97E05D2BD3D5ADEA365 +:10A410000C8C72C3F71FEC3CF7DE9DB89E9D89142F +:10A42000DEE67E9253653ADE49E41384D7F604CE25 +:10A43000275DCDCFC1771F5C93A36E2143F9839035 +:10A44000AE6F4C87FABE6E4BC976A8DAD39DD4188E +:10A450008E31DFF1A98C0E3CB2963801DA93771871 +:10A460003E90DC906F96707A7377FFB08558A2DFCC +:10A47000BD83749040C81BAD76FADCE1B6D3F1EB36 +:10A4800016D62A3E1867AD9504107EF407FA754F6C +:10A49000C8DBB91D867ACBC2CADA6AE03F69E87CBC +:10A4A000BEC7E9724F78D1B0F0AD6F900DF0AC5BE4 +:10A4B0006884AF993E8F872D35B1D62FE839DE7885 +:10A4C000D7D9C25EC4D331BEDEB7F97A7FDBD8EE0E +:10A4D000C2F6E671F684BB87E5836F361AE9E2427D +:10A4E000EB3CE6F653B82E0F19BF5B566F5CEF12CC +:10A4F000D272150152594A541B3EEB484BF173007E +:10A50000CAE38F2CA6F3798B909A1E9CEFB9DB8B54 +:10A510006B8BA3FD1FE6F0FEBCEEF66B50ECBCA30C +:10A52000B414BB63CCE72D0E2781EFB7E2C0F379FB +:10A530002E77DF413C23BD2E9563E2F96DCE47EFC8 +:10A54000340CCF474BEB86C7F3EFDD6EDE4F7B223B +:10A55000AEF38418F75136EE89307B2FFAFBFDDF1E +:10A56000887FFB89760BA5E370A21BF58807C9439A +:10A57000A7475A53B9FE291C5E8F88E71B42AE9A43 +:10A58000DAD75903363D3E4ADC8CCF45B96EA1710E +:10A590009EEF27BBD9B8C43D3AE8D2C90DAE5F855E +:10A5A000BE7BE0C989EFA3FEF471FEAF0B7E6A4368 +:10A5B00078807CBDCB85EB7ADDE246F95A762C605B +:10A5C000D3C3EFCA1406BF93BB8787DF955C1E5DBC +:10A5D00048CE9AD7FBC13FDD3D19FBFDE09FBEB0E1 +:10A5E000E9FB5FFA652E89A447CBD7D74B81700C66 +:10A5F0003EBBDDAD8C08EEB79BE078FD97A369FF0D +:10A600001E99B4F4C45A17CA37E87749B0C2E605B0 +:10A6100078DEB0595225E882A4B27E6E10F2CEEAFE +:10A620001B5D0B70F7B6B7DC118CD14F3987F79FE4 +:10A630009CC194587C36C81F9C1E44BBA5D6902D47 +:10A64000567BB35EEDE77C6E6EB700E9D13B727A64 +:10A650001CB4834CED473A8FE9298C2FD313227F0A +:10A660004479448A8C76D805C735B5378F3B1FE1CE +:10A670003E35FEF827FF2A37C682C3B75319FD8639 +:10A6800082403F31EB5DB4FE75C2F4AB164EA2FAC8 +:10A69000F0C4EE1BEE45F3EDC6F9771C4135F972B7 +:10A6A000B29F8EDF103C5A8D6025E71E988478FF9C +:10A6B000BCE6817B4B616A279550BB0B3E38B945A0 +:10A6C000A2768B799CD7B93E7913E5E9E5D81F616D +:10A6D000743B077ACB06B0CB81752854C8B7137C7E +:10A6E0007A3BD5B3E98B563209ED87E01617BC1FCC +:10A6F000B7F9D38DA8970909D3EF3FB2A93753789B +:10A700001366E7F6753B776E8776AF25337C10A22C +:10A710008E0E16EBE484D54DCB23C5CF1B71F073A1 +:10A72000B1724AAC33DE380079FA7D6D95B353BA15 +:10A7300002ED1DF71D088F816A97BB1BD6539B1036 +:10A740005880EB3BFABAC5D2E6A7DD527B6511FE15 +:10A750000643FBAFF67F17ED99450BE58003CA7DF5 +:10A76000F81EC65B52E9D4A41450116F2CFC11E200 +:10A77000E781BA049F0C24513BDBFD4719DAD7CEA1 +:10A780004BF26D8172596F7E9B07EAEB6A2437F6B4 +:10A79000F7E2C229AE7E585FD226E827073B3B5E30 +:10A7A000533586901FE2AFD3099B30C0E20D22EAF9 +:10A7B000D3B6CD017930C1BBDFE204508F494BDB0A +:10A7C000668779DED516CC72A742BBFB4E74DAAF32 +:10A7D00022242323D03B5B2524E1FE5335F651B0E0 +:10A7E000CE47797FDA279D8199A04F2D21BF04F5AF +:10A7F00093EEB7CEB75E09F82F10FD676DC3FA254B +:10A800007357ACDD0FF5756913E65BA1FFB2063136 +:10A810009F2BE65759E1FD4CD1BED481F3F5248935 +:10A8200032CCB79C105B7E74FED62C183F4D94CB77 +:10A83000E7CF816FDFAA68A9B242FF7BD2666D2B9A +:10A84000721032ADA6C21D80F53C75FF92F94940E9 +:10A850003FFB09D029D4EFBB7FD97C9CBF47B6B062 +:10A86000FEB57A3ABFB2066D02D64BA4615B0DAC61 +:10A870007BBDBDFF0892EB864D9A3D037E49921841 +:10A880009DD86D2D815C80BBED404524974EA78BF4 +:10A89000D1675EA418F5D860B910CAC5BA72162B74 +:10A8A000EFDF42AE8F256F5BD299DCDB9F18BB5E7A +:10A8B0004A63F218E046F549CA3112D81B43AF9CEF +:10A8C0004875D276871389664F8BF2DBB5C0C3E536 +:10A8D000C097C4CEE629FA1942D75CEE10EDDA34FF +:10A8E00094A70B399D16A812F577494B52782C3A4C +:10A8F000D824625D8C2248B6D0F97A65E9FA5AE824 +:10A900002F239184F6C1D39B4E6819BE0FEC73467A +:10A91000FB7B95B116A92E08EEC6FEAA33B34BDA1F +:10A92000FDD17E60DE1DF6C986795BCBD3B07E514A +:10A93000C9AD453A7816B175001DD0EF60981FCDAE +:10A9400006BED8DF3B211FEDF7A7538D7C5DD65B9C +:10A950006923F0FD92742E4F7CEC7B6F15933F03BF +:10A96000B72685915F895D2D09EAECCEDC34068F30 +:10A97000AABB173E8CED9A7A6D2401DA6DDC5791F3 +:10A980004986D18B4D5FCE20E129BAB235A2A0DC39 +:10A9900069FA72167D5F75F7AB0AF229F6E38379DF +:10A9A0006D74043255845B7B6CFC83434EE7DDF4AD +:10A9B000652AD1A6E8DF333845FBF7D0FA0BAD2B7B +:10A9C000DA9F4CC2E9C3F5A7D0FA41B85B39DC95F0 +:10A9D000D8F3ACE4F042785B74F575486F4E2AFD0D +:10A9E000681CA5EF1B45DD28EFA3E36EA1FDEFB7C3 +:10A9F000021ED10EEC4DF4A15D5C6605F9E9C1FEC5 +:10AA0000D2DC9A14A50F411702AFFBD35A2AE87A79 +:10AA1000AF91DCDD31ECF8F9827F16327B2CB3216B +:10AA200024AFD2D1BFE007E87F3FEFBFB49CF2CFA5 +:10AA3000BF327E00BE5981FC8B760BD2A11A295EF3 +:10AA4000E41A3AFF674076607BC02383FF35CE303F +:10AA5000CE47C06D28FC732F80CFD1B4BEACF79029 +:10AA600082F4D614876F17A427D3EF328F4592D183 +:10AA7000AF7D8EDB1DFB7BA63866205F2CB41014E7 +:10AA800061B86EB457CB660AF9FDC42B95207F33AD +:10AA90004519E5AD0FF130287F23767BB4FD550FC6 +:10AAA0003C31BF03E57302E0BF88DAA176A2F32749 +:10AAB00036A53139561E2231ED96DA7466B708781C +:10AAC0007F6F5315F91DACEF502AE3CBF27E4D5A40 +:10AAD0005514E56BB39C7A98E3F141FEFCC7CB2992 +:10AAE000E90272AA96CB29F6FE3098F9D82E2323D4 +:10AAF000522C814E5CFDCA94B1E8CFDC9625FB3E1A +:10AB000006BE5A2CA9A39E827EEBEC3E1A27137434 +:10AB10005247EC3E27C21D8CA6F312DA070E5AC626 +:10AB20001FB44B3EEB92181D125F4A5D717C3924B5 +:10AB3000E6715B9642C75BBD6D6C4A483F3FAE27EE +:10AB4000AE4D883C450A86F2B928C3FCD75B645DEC +:10AB5000BD93E9B33FB8024FA741F9288F43812243 +:10AB600003A72A3AFEAFB93E31DB4B8B93399FA046 +:10AB70007949F9D8429DD3CCCE8430619F68E8A74B +:10AB800066F6303ACA6C88589A747470242D8F36E1 +:10AB90006A5806956077D5D8AB021FEBE4D8CB1284 +:10ABA000A9A7710412998A7CFA521A31CCA3410EDA +:10ABB000E64968B76626A82867004F140E871DC4AB +:10ABC000EA80715F8227E2AD5ABEF5059B07E94036 +:10ABD00052DB29F47772FB944450DF5C3B3B89DA0B +:10ABE000ADE4DCED63305EE14D62740BFDD8793F7E +:10ABF000764A275CEEFD66F4F86ED44F427E0A3C3E +:10AC0000907332ED4FD41F966AF3DC503EECBDBC1E +:10AC1000A45D32DA3F680F45EDA7DBB6CDB3A2BD28 +:10AC2000D313B1000BB5691BE7DF897638D84F0E17 +:10AC300058CF47694C0F1EF66B7232F63716D601A5 +:10AC4000AF8E24868A5A9C517C808D1342FC6528E5 +:10AC5000F07432FEC0675B3AE33397873D97F16744 +:10AC600046326B6FA6B79B787D00790F9EDB2B98E1 +:10AC70009C30B7FB6FCEBFEBED5A4D46BEDEBE0A31 +:10AC800012A4432B6176D65F39DE409F517855DDA3 +:10AC9000DD90827AF3F3DE2529A4282A476DF63762 +:10ACA000467F0C72244216FF33F2ABF2964CD05E14 +:10ACB000BECB067400ED94D4903B0D9EE949B1FDE6 +:10ACC000E6317C9DE9E85743BB7BB9DF63FB722229 +:10ACD000F5B733B87D969C5547E53AC2D207704E1A +:10ACE00021039A5B87C794728BC17FB07D39897EBF +:10ACF0007FF1F643491CFBA1D4603F8871CD76C437 +:10AD00007BAD5974FEE2FB15596F56135DFB95A49C +:10AD1000FF2EEC6FE5C65C43BC289EFD319DC3074A +:10AD2000ED052DE6BC14C3FBF7C05FD4F4E39F60D0 +:10AD3000E347C74D02868B8EFBD7B4C08C741A0FC5 +:10AD40009AE93E3E111E60C39F97A9DE61FA1A9EE2 +:10AD50003B9D542FD5A0DC167E12F2BF3B05F9BBFC +:10AD6000A22ADDABD393FC3BB33C3AC8E31A07B944 +:10AD7000BE493926ECC6449F2445F5CE50BDC5EDED +:10AD800062937CBC909D0D74ABE9ED8021FC92FE3A +:10AD900055EDCB8238F431EE1F625F96CD0CC9C5FC +:10ADA000283F6B2432161ED3E618F5FDB7D39D74E9 +:10ADB0005DDF0686D3FB2D8B1A8CED5AD399BFD25B +:10ADC0008AEDBC1786A75E1F4932CA3DD65F33CADB +:10ADD0001BC0B3FFD4EB8A0FE4F0F3DC1EDAE50905 +:10ADE0006C45BAE8484C9E847AA223717418E31229 +:10ADF0003BFFBBAA7027FAE9AFD9D46EECF600F39B +:10AE0000F32B966F6CB7C27B5B8FE44E20D1793AFF +:10AE100037498135404AF7737C3579D87A9A3C11A5 +:10AE2000650C8C9FD3C4E691D7F38264D5C9BBBCB3 +:10AE300046D6EEB1749B41FF8479F9F17411EF08A5 +:10AE4000B7559762FB8015F741727A241A1FCE69B5 +:10AE50000140003DE4A8AC7FA71A966E288AAEB7E1 +:10AE6000D3525B847AA2332349453D71CA137A12C7 +:10AE7000F9A8A92F1241704DEBEBB5A2BD67F506FD +:10AE80007E807010EBF4C9EE1C94B3497D6C7E5D3E +:10AE900026BA27E4BB3C3EDBCDE4AF4C5E268817E8 +:10AEA0009421305EC69642AAA744FB8C34AE37325A +:10AEB00048E8696A67914E42F146E83A32B68CA397 +:10AEC000F6BEC06BD4AE1A3F19EDAA821D11EB6A13 +:10AED000B45B1F8B1DAF3FCCE50FAC2342E5C481B3 +:10AEE00091C565443B5B1CBF5AD07D524D6C7B15B0 +:10AEF0003401ADAF58EEB90ED7DDD4A19004290AC4 +:10AF00007FAB37F806CE27A767A784B031D3594760 +:10AF1000DA0FA55C58E7ED3713B74CE2CFBB699366 +:10AF20001C58A3E7E70E85E265A762DCDF137EC647 +:10AF300069AE8FCABDC1DFE1F8CD07EE5310CF3740 +:10AF4000EFFE50196E5F67A470931A99FFD2546F89 +:10AF50000FE37A2B965B291ED7752861944F4D7BA2 +:10AF6000F7452C68676F262AF27F53CFBE2339003E +:10AF70009FDCA6C054D9A7F39F9BC212CE2703889B +:10AF8000B1B788CA4D05F5B699BED14E467BE58866 +:10AF900083F1FFE90AA786F1B4D3B65013B63B9DFF +:10AFA0009DA46AFE28DC5FDA37EF650958DCF5748A +:10AFB00042049F9D96EE2C3BB4EB9CA0A8484F56B4 +:10AFC0006FC8EE8175A45983FBF1FB548F4B6D83E1 +:10AFD0006F7D096432D5D72384C334135D4CDBCC39 +:10AFE000F865BA2759D88193512EE57B5CC28EA2B1 +:10AFF000F2EA888DADA383B0F9B6A507323D48B714 +:10B00000EE343A6E4E5344423FC03C6E94AE02A3BF +:10B010003CDE8B99678F82727E1D973715CB774BFD +:10B02000BFD3D1419187EDCFE6ECDD29A17F08F5B3 +:10B030006DD51EDA9E24A0BCD9CBFCE27550BF565C +:10B04000275FC43A62C89929383F675FEF8B4CCEBF +:10B050004428FD89F99AF139DBC3ECBBB96026D0ED +:10B06000F78A56E883FE8EE427D2FE04DF9BF9744C +:10B07000B687D1794EFD6EC95244E382D49E14F353 +:10B0800013ED76792AAB3C140EBD140EEBEBAD2C10 +:10B09000DEC0E753AD04C7A05F56EB61FB5D87964A +:10B0A000BDAFF443F9C19F1DA5F4B8BE4B0A507F54 +:10B0B000A1EBA8B204E376DAFF91314EBB80992868 +:10B0C000E4A19F1EA57A65C17E168F5FBF7F9FF5A5 +:10B0D0000667944EFDA70EAD443A5BDF93401C1209 +:10B0E000E28FADD74CA7206728DD134DA1FB5C2074 +:10B0F00027352A5749C88F7E8A90C36DE97C5FCE79 +:10B10000C9DEAFE1F316FD46E5A783D2BBFFD4E469 +:10B11000437680E77A5552C174023BDC47DB43FF3C +:10B12000112A878144D15F13FD9BE1D7E5617A2D18 +:10B13000069E5B3C31F489D0B3FEC72B093E05FE69 +:10B14000AC1CEE83FADDA3D07E5B3D563A9F8E0A9F +:10B1500016D7EEB0313DD2D1660F235FBF943AF7D8 +:10B160006509E4A52B4D89E0F3B0657513D61FCEB4 +:10B1700061F3E8B46C296C617A4CF350FC2513261A +:10B180009F983C7AF0274C9E34694EEA3F3685EA18 +:10B19000D6D07D098F43C57D09127A5159E28AD2F2 +:10B1A0008319BFBEA75F507C50BFA087F141146ECA +:10B1B0004C5F09BA053947F1DE26E2888037842BD7 +:10B1C000F8F56D187F107E7D72435073F986F26B2F +:10B1D0003AF7EBA772BFDE566EFF9BFAF5EB36FD32 +:10B1E00007F5836EC97A853E05BF80FF68E0ABA78F +:10B1F000B89F763F7FEEE7FCB9AEB487F2C3BA8F53 +:10B200005B281F396B983C71F619E52021F7F0F5A2 +:10B21000EF60F498D43317F725AAFF4D72B793F86F +:10B22000F3BE496AF94FCC9321FB78FEC639B0F2E0 +:10B23000CB00AE0E0E03DEEE08E7FBD37B0011C899 +:10B2400097D61665387BF842FD92C89B12E27B1DAB +:10B2500087F5E9BD5557FE1EE38C7B52683ECB2730 +:10B260007B17FFAFDFC3F7A777CF56514F7BDA834A +:10B27000947E06BC0E15E3A7203E6B24A087B69EE5 +:10B280005F25CFC0FDB21F5D3119E5E67B7C9EA72F +:10B290007E226F42F86CF9C18F6761FDBAB0948E5F +:10B2A000F6E3E93DFFF657D48B8DBB37D0BCB4F63F +:10B2B0001FFD92DAE596F04EF67E4F0AB5334FEE5B +:10B2C000BA6F16C2BDBDA79DD69FDAB593960FFD86 +:10B2D000E0C7BFF80BDA1DC16415DB9DFAC97DDF3D +:10B2E000F90BD2795DB28AEB680A59D97EAEA06FAC +:10B2F000B3DCDAF702E553412F0B50EF229CEA99B9 +:10B30000FC11F4FC11DF6F5ACDF7B13EDAEE6A8C16 +:10B31000156794BC6CBD188BA172AC5EA271B64E61 +:10B32000A01A8C77742692727C261545945C186757 +:10B3300059C3BE59D4EED13EBC11DB2F3EE020DB19 +:10B34000695C0E83BAD17DB0621083C7C16F86DE9F +:10B35000779F07BA7D1BE403D53B267F6071E72BFF +:10B360007F46395A67EF7F0145A178DFC9E337D0BF +:10B370009EEA9DB28DB1E3A40EAF93EB6DA6377339 +:10B38000F6D7E6F9A89C4850C7EAECD351C75AB69D +:10B39000637A524E63EF5C5CC7D585ABA650BAC0EA +:10B3A000F81FEA1FCD49FB5F8FF14BE0BF1C2F93C5 +:10B3B0009F196EE2990EE3575B89C7894F42DEB44D +:10B3C0005139F204ED17EC0F6A57F97EB9EC09B464 +:10B3D000471EB285B2A7623F9D5C6FED66F386EFB4 +:10B3E000DDB88F0AFDB9A74FA6FDF4DAD2E8F71A47 +:10B3F000FB7EDEEE36293A5FA0D4D1A8B7B0BF52AB +:10B4000027EA19AD9EE2C7A7D0759DC226D974DD83 +:10B4100093561447F9D71CF7417986FBC3E5DE8ABA +:10B42000295E6FF429E2416678DE89F5D0CF33DEFC +:10B43000007D923D467F3B9EBD7268D919A67F9FD5 +:10B44000FF90CA9B66A4631C3FF4B141FFDE20E875 +:10B45000F8D90F291DDF7080E9DFE603250AD2ED58 +:10B4600027AD01F23B30409B2B816E817E1F92FA0B +:10B470006FA4F92ECF3ADC18D73BC3F5CDBA1D1F08 +:10B480001E97011EF907B2A99F7FE659473DF67343 +:10B49000D862A1F03CDC3D7167BBA49F27F30BC0D1 +:10B4A0000EA6A4DA0C762AB383D7DC877EDAFA46B6 +:10B4B000A222FF379BE8A7F9C0514A2FC20EF63FE0 +:10B4C000BE680DB33F1DAA03FDB839CC1E25608FA1 +:10B4D00062FBD439E13685D2574919D2D7A165BF6D +:10B4E000D88A7ABC790E7163FF0F8D0A3C9B4BD7CB +:10B4F0002311CC7379C8D6556985EF1FAAF6B90117 +:10B500009200B7DDD4EE25850AD7736BA8BDDC9C0D +:10B51000F54D95F299591E3CDB46EDAE665F229DD6 +:10B52000CF8203D26DCC1E7112367F89D2E782F0B2 +:10B530008C30C6CFFEC8E127E078C6D6BB12E171D9 +:10B54000E6A7408850BF600EA3D7D4393D548EBCC7 +:10B55000F4EC3CAAC7055DBA9E49A0FA3CCDEA9638 +:10B5600054AAD71627E8F1DA65637A2995EB998210 +:10B570001D0CBF6D5EA697DABC16FE548CF117B792 +:10B580003609F5EE1F39FEA91841F9CEE5C9FA359D +:10B5900011CA4F4D7B597F9E8440C9ED3AFAF5544C +:10B5A00031BD28F603707FA03686BC7892CFC3FFEA +:10B5B000F8EAFBD05EBE1AF08E2A25A790CB51A0E8 +:10B5C0000B845B4E6390D2C1D59E9B54CC4FF5A6A5 +:10B5D00013EA2F0EB4292456DCE7877C5DDEF46085 +:10B5E00029C6A1BD992E6AE778E50A8B03BF2B9186 +:10B5F000D46E1FDDF7A476DE80375BED36F07BB0CE +:10B60000D402ED4E64B8189EC3BFB12E2A463EF454 +:10B61000097FDD60F70DF5BB99DDB8B04B9B847EEB +:10B6200088D8D7107008B725D6EBE5670F976FE17C +:10B63000F12C9E0AF6BD93C6B5DD300EFAF7DD3368 +:10B640007631FFBE9DB6FB9E97D947D5B03EB4DBA1 +:10B65000BC05C18D4C9FBAD458F028E77AE5D0B22A +:10B660009525E85736D73955E4B7079F9756537A4B +:10B67000C66021FADDA135140F04F080FC4042CCF5 +:10B680002F6D6E098663D37B2DE5BF66E43F89D2BB +:10B690003B8DC303BD8719BD33FD27FC7F948FFA13 +:10B6A000BC432107847C6956FAC7211D0B7E689E26 +:10B6B000D53F0EE136527972C606FC8FFC0370400E +:10B6C000FE11FCE27A8EF1C9F6365F05D66FAF2621 +:10B6D000EE769D3E32FB4B384FF43B855C3FE509EF +:10B6E0007E8CF2B7D912D98AF915420E373FB76D61 +:10B6F0005CACFC372187ED5626DFECE1A470BB8EF5 +:10B70000BE70CFCF35993E693E4FD2A6D8F1912F6A +:10B71000BC4E1EC71F59BE4406EA729437DD493439 +:10B72000AF5DC48BCCFD9EE4F426F022FC16DC77E2 +:10B73000C0F6E9198C5E940CC69F7919223E1B361F +:10B74000F83D3E4BE843CC338AA7BFC4777FABF8C4 +:10B75000951847E85133FEC5BE09AEA7B6287EBB93 +:10B76000AE17987C32D3E3182E373EC4B5C2FF7FA4 +:10B77000E7FB5C43F1CBFA21A1F186BCB84ECBBE0E +:10B78000C65871B0175A79BED463E3479477F7EF80 +:10B79000BCFDBD3C2F8CAC196FC8B372AABE368CF1 +:10B7A000A35E71D05722D371591CCB358B7C8A7A1A +:10B7B00038B9BCAB10CF4D7883C6FD92CCFA44C3E8 +:10B7C0007E447628CD50CE6DCC31B41FD5926FA873 +:10B7D000BF6CD30443BD5F9B6C2817744E37B41FF6 +:10B7E000DB5569285FFEC8D586F6E3C38B0CE5ED13 +:10B7F0006D3DF58897897BAE337C7785B5DF520246 +:10B80000EF8B7B561BF3C74CF0ACFCAB1C930E6F5D +:10B81000CAF0537C5D71C0088F9472233C305D0E7A +:10B82000E19C42787F897F5687CB6F4D21D63FF5CB +:10B830008BEFFD43E981D8DDA5FABC8428FD840D9A +:10B84000798B9556D9340FED2BD15FBC798AFDB633 +:10B85000B8EB8803B7ED837CCFE062E3CB4A995520 +:10B860003F2C5C6C17820BE957470217F37EDF60B1 +:10B87000DCD9D4DF96A4669A27FC261674F6717F6D +:10B88000ABF13CCC522D85E9A1E0E20BD8D12C0ED6 +:10B890001C4A60FB95E6FA57B85CFC03C084CE678F +:10B8A000847CFD3EC7431FCF9F1FC2D79B3E3D9C5C +:10B8B00089F2BB8650BFD9DDD2F629EAADEBAD11D6 +:10B8C0005202F37E90AFE7212E171E6975D37E1EBC +:10B8D000E5FB918FB5FAE8FBC75B0BE933DCAAD235 +:10B8E000F7DDADE5F4B91BEC397C3ED95A439F7BBB +:10B8F0005A83B4DD0F5BEBE9736F6B88CD6B08BEC9 +:10B900004819B57382E931E3A5AB347944782272E2 +:10B910005E4C7D19B71FB961D8FCF24D7DD28F5FA7 +:10B92000D4F1CDBB192E0FDDDF9C46A6E1FEE685E6 +:10B93000BEFFA295FCF8C5B123E723414FE45CFAB2 +:10B94000B8608CF85188E7553E9911FAAEE68C0F35 +:10B95000AF289DC586539DFD4C0E3AEB93D066D023 +:10B960007D2FCE9F88725D2825A6DDE0CD64F45939 +:10B970009FC0F6E3979BF8FB5BBCFE5B994CDFBD79 +:10B980001B47CE38332DC29FB7D1FDC1217C77EF45 +:10B9900055B1E0BB35D367E063F3B915733FEFDA18 +:10B9A000BA46A931F8EC42FD88F599BF5B9AC9E423 +:10B9B000D6C64CC2E4E4FF67FCF9EE5A17F51F1037 +:10B9C0006E5EDDFADF5D9B541F2B2EF39D4C1BF347 +:10B9D000B703A0B3D3A8A9AF29682B16121FDBF7B2 +:10B9E0001DE3C6F890C80B884FAF561A47A2309493 +:10B9F00087C215F0E1530AA07FEBE038112B8EA32C +:10BA00005AA2FA0D736D88EEFC873C941EE07B4DC4 +:10BA1000A1793DFD3938BF8BA527223F3676B87D09 +:10BA2000BA21DF5FA49CB931F3EF2B67049F9373B6 +:10BA30000F8C8DA527EB51CE4C075193F9289333EA +:10BA400017E8F762E1572FF7D3FDEB11C3EF8067DB +:10BA50004471A92F1CC993D0B8DA6467CF3B139304 +:10BA6000BBF1F9856374982413F200CE13DA69955B +:10BA7000849DDF7A5FF84D2DD3E8FE4A76F05F3281 +:10BA8000A17EB5C2FCC53319818732615D897C5FB7 +:10BA90003891EF0B2B99CA562C9340215DD7247017 +:10BAA00097316EB1D5E21B8DEBFA5852C7A3DFE296 +:10BAB000B684557C26934831CBCF0B87D05F4B9F04 +:10BAC00098E8437F37711C21BD343EAE3A308EA6D4 +:10BAD00024F5BF3E06FDDBE7AD345E3409F351A12A +:10BAE0003CE97BB9618DCE3348E5453A87E376B4CE +:10BAF000CBE1FBEF4BA1A770DE27DD76CD02F37A19 +:10BB0000A0738A230DDE47F6C89A9282F931A7EF17 +:10BB10005F00EBBDA257A671E72BC89457C6A09C47 +:10BB2000E9B5D1FDDF7556B203F9281E7C3FF95601 +:10BB3000EC3C30922519F2BBCCF51F703DF0499CCE +:10BB40007CE3DF70392AF2676C227FC61B18367FD0 +:10BB5000C666CA9FB1598304F7856D83F9330D8496 +:10BB6000E6CF403FFAFC994F2A63CFE31D3E0FDB3F +:10BB7000974971FA4DA6EF3FC91F7E9DB62F1D86CE +:10BB80007CECE8F74EFA3E5EFECE001FFF9338F9DC +:10BB90004BA707FBCF265ABAFE3B46CFD171F268BE +:10BBA000BDCD940714AD67F93F1DA98C4E5EC872D8 +:10BBB0007B5641D7AB483F3DCF79BDD363C3785265 +:10BBC00090A8FBE8F91EAB6DA05FF0613EB6B37EB6 +:10BBD0008476B705242FDADDD76FB27DD4AF935BBF +:10BBE000B5016399607B9D1C5E88316CE4A7098573 +:10BBF00034FFEF33E24B710F23471BEC72D0AA5B8B +:10BC0000475F1C3BA2348BC1A72F3B36FC466559CE +:10BC10000C79CB43BF4FE6E73ED839B4DBDDC3CB6D +:10BC20004F846F285DDFBF190F1E5A7F21387BDBE1 +:10BC3000197F0F54482CCFFF6F0EEF549EEFC6CEE6 +:10BC40000FD84CF9EA0BB3CDF366F9EAF7A706CBA8 +:10BC5000B2D02EB3FAC6E9CF0BECB7069226C3B327 +:10BC60008FCB1D335C3667317BCFBCEEFD3CEF3EA6 +:10BC700051262DFB74F037AFB785E351B4EFB0B167 +:10BC8000FD2C147C76907B2B0893B3CBB2F2F93960 +:10BC900097542BE2AB81754156B88FD0FD2501E753 +:10BCA00021F0E37037C331487C2B31BFFB42F05C9D +:10BCB00075345141B9BFD23E70187DD5FE5ECBDBE5 +:10BCC00063E0F9A173CCF1DD04F7E10A9F39443058 +:10BCD0003EA2B27C0A3287DA3D92962B9F9F387241 +:10BCE000BB676B72A810F9E26389C56B853EDA9A6F +:10BCF000736A1CE6D7BF9F5651943D95C6DF03E992 +:10BD0000483F3F4F60F4F308F404E50DBF184FCFF0 +:10BD1000C12FC90E4DC8F646F3FB4860601CE623F0 +:10BD20005C2C7CE0C786F47321F8ACCD62FCDD9717 +:10BD30001C9B3E1EE37C7821BEA0E7CF4AFF7E7CA1 +:10BD400021E029F62FC4FC266433392C9E026EE6CE +:10BD50003CA209D916DE8EE5112DC90E52389F1D61 +:10BD6000F5E97107CCBD4F897DAF434F1CFE30AF65 +:10BD70005FC0FBEF257FFB1263CFEFC5FFE1F91535 +:10BD8000E3FC008E7D9362CFEFDD11CE2F4806DEFF +:10BD90004FFD3BE82FC07331F21DE918A072B12F9F +:10BDA0002DF63CBF1CF13C43B6BF879E15F44DB445 +:10BDB000558D74DF3E2B31E6BEFD52F0A3D00F321D +:10BDC000EFDF8B7D7A901F74BD75F68195E988F75A +:10BDD000397CDD1924928AFB9ABF48A0FB0043E41A +:10BDE0001AE77380978DC26BE1008D67F48D8B2D00 +:10BDF000176CD90C5E83ED3BD938F1CE1FB8387F74 +:10BE00005EE8FC01290DD1386085DD1991010FB77D +:10BE1000717C28B9B7A868175664BD7A0CD709F0A9 +:10BE20003F3D084F5D5EDFA9D697DD636CF1E5F617 +:10BE30003AF9E9B29618EBF167847C280F06DBED3E +:10BE400079C53D4687AF62D26F61E7A7072C06FF31 +:10BE500038935C947FFC3307E3E7F7D382541FA049 +:10BE60007E40BDB3F5B92B4B1099685F605ECF8003 +:10BE70002B91CAD1F69CE9853E1D3C2BB3855D29EB +:10BE8000C7B117BFDEB980A8BD2419ECD668FF562C +:10BE9000FA5EE0A7C2F9EB98F8F06704E6213C3FB0 +:10BEA0004F0BD4E03ACDF0D3EE9E994AFD6584DF86 +:10BEB000EC687F83F88F83E75B33028BB0BF89E93F +:10BEC0003E16BF10F97C83710BABFBB83D0AEF91B6 +:10BED000E2E55EFC05FCD5DBB2032BB17F2581F3E7 +:10BEE0002371D2F3E3C25E2126BB8694B3FCD21544 +:10BEF00059AFFE19E33E5B9319CB6EFD8E83E6D9F5 +:10BF00005D2FB9155C37D81FEF7D1FDA8748E4BD78 +:10BF10006FD37D2D616724C9E793463E4FE1375FBC +:10BF200028BFFA10DA61309F4A8B93EE731E02B27B +:10BF3000C906B951A9B067C53CA02AE8AF52CE3BAB +:10BF4000D80FF3FA9C9C4EBB0ABE4EE4F1C58D4758 +:10BF5000A73A902E2BADB6537AB9658E7BDC956DE2 +:10BF60008C7B7C4E16FE33DD0B2E64FEFF030B2B09 +:10BF700033F57197C1B8873897A6AD62F2D424E73C +:10BF8000843CB3D8D93D2324407CEE0C1A3F627028 +:10BF900007E71AEFBDBA4A94D13981F24C8E2409D1 +:10BFA000BF87755FC59F6475280BE50CA6F3E07825 +:10BFB000E0F565E1B3FD4AD587CFD952D0CAE61185 +:10BFC00066F987A4250FDB5BECFD328E2FE214743B +:10BFD0002619D88F1897955DBCDC51F7D9CAB5BE24 +:10BFE000A1F10CE27451BB57E1F33BE9766A165DAF +:10BFF0009C23C1193949F356F9D31CEFB853D634F1 +:10C00000CCDB4E243D545E3A9D7FD410186EE296F0 +:10C01000B0FC7D29F433E4B7E34A17F1C3FBB33F27 +:10C02000FF8220FED2F16458013E8DFAC9EBDC4854 +:10C03000F3A1BD41AB492F8524E4A3CC7AF37BA3C4 +:10C04000BEB2933E7A6E488A04B3CEA75F388E1391 +:10C050002F7E63AB64A81FB899D9C36F27B2EFDFF7 +:10C060004E64DF1DE37AA6394D212CBE63B7A33D94 +:10C070007FC675028F6AA23EE9447D62B705285EDD +:10C08000855E59BFFF5682786B3E504BE1F05B896D +:10C09000ED8F6A2B249AC7B094E7DFD51791D702AA +:10C0A00038B59C7CA6CF5E0EAD688272DDABA4383D +:10C0B00002ED4A6607ABF15E97F662A26E8172BB33 +:10C0C00023F4D44F711D47D93D631BF8795AC0C47E +:10C0D000BABDD0FFCEEB46A9DB714955035B314FAA +:10C0E00068601B71635EC910FA3D07FC00F4B00B79 +:10C0F000CB30EF0D6B42FF7A07B4CF7E95A8B40D1D +:10C10000AF471F05F12771BAC0F7B3E1FD064E47EF +:10C11000050725B6BFEF61F77FD1CEF17E2E3BFB41 +:10C1200075C3C18A6BA7C2BC0A7AA750F21E03ED81 +:10C1300031FF093310587B6289D57E0CB6F7E17E5A +:10C140003EC30FC951E8BD4984CBBF69263E9C114F +:10C15000E5075A5FC2CB1BB89E32F00DF603FE7A9C +:10C16000A08C6DF7D3EF3C8C3F54227E183F4F27B5 +:10C17000D11FECB72A3A0E95CB7378DDE1E5F36970 +:10C18000DEF7346BE405E4F719FC59C29FC8EF767B +:10C1900080E3326BCB612FAC27751351DB709406B3 +:10C1A0005F3BF6574A8232C2B9CCBDAD1DE7776519 +:10C1B000C3D174A4AF753905949E66DAD502079091 +:10C1C000487BB9AABA0BF09E3189C26549BD3D8C46 +:10C1D000F96D4B06EFF909F99702FF2C0BB1BC661C +:10C1E0002C37E8E2B522EF6F6902F8D531E4F7BAEF +:10C1F0001C662789EF37F07329A2FEA61C96FF71F3 +:10C200004DCEDCD21C9A97C4F2A181FFA76159C818 +:10C21000151897E6AB2C26011BAE6B31E75FC1FF0B +:10C220004B02B7537B7649D06897FE5662F8D69694 +:10C230004BD44E5C563FBCDD3A3747EC07E7B98F2D +:10C240002745DF0BBA12F27C11EA7794C335A0CFF1 +:10C25000757673C39DE752E977994FAE3F7F59F4E6 +:10C260001CCC06D33998667E0E66C381365B06D237 +:10C270003B3F07B3E1E0875BF5F97F024E43CFC157 +:10C280000CD0BCC7A54AF8053C1FB4F4165823B41B +:10C29000FF153F37F1229E9B981CA523D7758E086A +:10C2A000CBAB0BD0FCBE3C77928AF9289D96C93463 +:10C2B0009FA833D9A5EAF377B6B7B554633B914746 +:10C2C00024CEBD2C8DB35F7C7B0EB3B71F92583E3E +:10C2D00097B6DC4EE1ED95C931FDF97E6F4190E6F0 +:10C2E000D195E6F8447B1A5FC0BCD329F00C839942 +:10C2F000C6F0C5BE37CB07E8AF03FBAB2A5069FEDB +:10C300004C550ACB43F3A6074B6E2B8AF65B77900E +:10C31000E5EDD5053F3DC2F26F6B4B119EF1E4BADE +:10C32000597F01FD75E6C488D3DF29879A91FE6C99 +:10C3300095C1E56BA1DFB3AF2934CF8E6C0E4836C3 +:10C3400068F79357DC2A9EBFEBA808D656D37A2B02 +:10C350003D1F98514F2209505FFAAAD28DF97D8D69 +:10C36000A44BC17E1A4D7AEC16E78B0AF2E92DBB7D +:10C370006D51BA249897A816A0C06BDA3B242E42C0 +:10C38000E590904F667A26638C72A844C85D900F42 +:10C390002CAFAF81E93DF2A484F1A1B3AE1332F723 +:10C3A000AFA9DC9B2A849549DE4F3DF812B567049E +:10C3B0003C6781BC403F4EC2F793D8116EBABFA50F +:10C3C0004985986F3A8324527A1B6247F0F9950E9B +:10C3D000CE9FD94D424E56943393D48C1F188FD292 +:10C3E000B9D8E79B8AF7FAC073061FFF0B4BA0284A +:10C3F000E2477C91B005E0BC556AA17AC78EF99FEF +:10C40000F0DC2E85A85CFC99A6C908D72B49CBE2A5 +:10C41000857E8AF72339543EF626211E8E2BAA1DCF +:10C42000EBAB3151903E8DF89AE77CD08AF09A9729 +:10C4300065C68B6645F8CEF70DC1173D571088834A +:10C44000AF80902BC42857FCE41C3BD7BCEDC81D23 +:10C45000E81F5FC83E793023D48FF2339E9D122FA0 +:10C460001FEF2497C723CDC73B6B637EC574D27F74 +:10C47000E35E69289D9C39BC49CED2D193A0D3E715 +:10C48000787EBEF44B9EEF5BEAA2FA2FAA2F191D0D +:10C4900094F1D274A42F1D1D5C75C01191619D256E +:10C4A000FCFBE9480F93A3FA326271FA947CC4BB97 +:10C4B000DA29CB43EDE48C341FC5FF144B80E27FB7 +:10C4C0002A51D3B9DDA9E4C2FACBED3DED561FC523 +:10C4D000FFF7D1BFA9203E8AFF0A93DEA972D65981 +:10C4E000914EAAEC663C0728FEABDD43DE5BBE0A3C +:10C4F000FE2F43FC0BBD3202FB14F0EFCB1D669FF9 +:10C50000311EFEC7E73A795CE3E2F06FC6BB9003E9 +:10C51000FB1CEE2A27C6831B593EF294D7C6B46390 +:10C520003963BD9F9E93D997AAFE8AD6B7B0FAD237 +:10C53000DE808CF732166C847A28EFF307ABB0BC40 +:10C54000619344E5E8D43743ED581EB399D5976C11 +:10C5500069F915DE6FB64163DF3F77722BBDA72205 +:10C56000BC957F5FD15585E50D9DECFB3FB8EC1A7E +:10C57000FAE565C7C2EDF87EFC0E360F61F7CDE631 +:10C58000F4B64F7AFA57F4BB2EF6DD4D47EC89CC62 +:10C590005F6276DC2CBECED98FB1757A7E77758DD1 +:10C5A0000FE0BE7640B351B961692AA372348E9F01 +:10C5B000562175E5E1731EC80942F10E749ACFF257 +:10C5C00055BB6188B5B9CC0E11799E986F5EABC32F +:10C5D000D7DA5CA66F45BB8C34C2F2921F65F7CDEB +:10C5E0008A3CD4C8C344C2F801AE91EADF3879A9C5 +:10C5F000F30A5AA83E9D7799C847EDB7AE86714BAE +:10C60000CEFFDFB9B1FCF2263EEE099E3F2FDE37AA +:10C6100086FD16F44FF621F1D0FB7F7EFE1ADA2D4F +:10C62000FB701F5977FFC83E3F2BFFEFDC67EFE938 +:10C630000427F7264B8B554325305AA2F7A97CA334 +:10C640009744529287CE7F9E954458DE049BFF8D7F +:10C65000ED4AF7769D1DBF44888F9963A95EA9E3D3 +:10C660007812726309C717F0793BF2C7527B0BB59A +:10C670001B9713A6D76F26611ADFB8D9C4E7EB9CC6 +:10C680007F7ADF82F6F31E233FAF87E9B07DF58125 +:10C69000C7DF05F8373EE272A3FE5FDF636CD7F8B1 +:10C6A000C86BC798FD65E4F746C1EF6123BF8341BE +:10C6B000C1F8FDE10974DF469C0B74D807DED7484A +:10C6C00074BD837ADFC47F0E3C2758887E8D85E554 +:10C6D00027F2B218F7B32EA69735D0CBDC0FA222E3 +:10C6E000F7B3BE05340FBE44E8512E67043F977080 +:10C6F0003D3F448FD798FD9D07299F4CE125B3FE10 +:10C70000167A5B9C3F847EA9FE067DFD5A00E6DB1F +:10C710006B718611DE51BD1DA67C34D90EF2DA4252 +:10C72000F1F73CCAE9A91C6FED5CAFC7F50F9C1B84 +:10C7300063FA07E06FD07D84A17E41C460EF9BF176 +:10C7400016CFFE1FC49B03ECA924F4F709E3E31CF6 +:10C7500032A2FC1090DBEFE40EA3B79543ECFDC0D2 +:10C760004E078D2F8838BBE0BFDFE4B1F8C277B346 +:10C7700003EF613F7D7CBC3EDE7FDFADF3E8BEF7BB +:10C780009F4880EE7B631E536E8CBC0BDCF7EED0B3 +:10C79000C54BFB5263C7C13FE17260621E5BDF198C +:10C7A0006FE034F2D50985C5D94F24F26732DBA793 +:10C7B000F82297C57B27E6B1A72B8FCB119EDF7D93 +:10C7C00022CD189F17ED52F8F3E3567BB043170FB5 +:10C7D000F73D9CD0827ACC5BC0F3E137323A3EFB26 +:10C7E0006CEA4EFDFD7039791513F3304FA420A08B +:10C7F00064637CE659A62F9AADFD0ADEEB93E20D49 +:10C80000D9F2302EE32381A7B11F5FBFB218E07DBC +:10C8100096EFF79FE5F7009D75B0A798574E5EED30 +:10C8200044FCEEECADFD546E0C966BFBA95CC8C9E4 +:10C830000BD271CF2E11F5BC7C0F2B13EE57567017 +:10C840003EA171E31871E2A17161E33D371B94D8F9 +:10C85000FBD424CF6588F7AE38C8E2902BED646B2B +:10C860002ED45F7F3093FA1B8DC9DA38A487AF1BB3 +:10C87000C73D3BAA97AE6B7BC5C0E8474BE9BE30CE +:10C880008D17AD3FF812957FEB05DFEC37F2CDB495 +:10C89000BC91EDA798E3EC23E0A78ABC61ECA0670C +:10C8A000507FD9A278B88DE75155CB4D551857FA1E +:10C8B0006C0DA1E76B6F7B45A67475DB5312BD6FE2 +:10C8C00042D871EB399CE3AD0BCF27F8747205CFDA +:10C8D00027F8747E1D9E4FD097F17C82BE3D9E4FFF +:10C8E000D0D7E3F9047D3D9E4FD0974BC80DED188E +:10C8F000A7DBD049DC611F3BAFA0FF1ECF2BE8CBED +:10C90000785E41FF3D9E57D0973F230C6E9F3D269A +:10C91000D3F83F9E5BD07F7FD32B3F298BE0B21DA6 +:10C920002C3FADDD01F0473AD402BD45009F351CD8 +:10C930003E78AE41DFEF27C9735F46FCACE9BD71BD +:10C94000213EAF38708BA15FD2C5E4710BFC433838 +:10C95000DE488229E8CF4D26034730DED11C9654AD +:10C960001CF7A6478C727BF01E93B0F1FD3AA28BA8 +:10C97000FFFA87C6FD3BF25C9EE32CB739471FEFF9 +:10C9800089D283538D201CDE94D558F450422E4F0B +:10C99000A1719E97658C61903F909687664ABAFD1B +:10C9A00001133C12B28C74E1F019E922A9D04817A6 +:10C9B0002ED5481729E546BA480D4C1816BEE9355C +:10C9C000463A59273751BE17702E877F08E7C97836 +:10C9D0003325C217D689F162337C1B0FDEB715ED04 +:10C9E000FE8B856F4F1EDF57E1F0FD9CCCAC72FAD9 +:10C9F00068759DBD2C6AC794BEDC423781CDF1536A +:10CA000001476147883828E87F6A4F47FD7AE6EF9B +:10CA1000817DF04B94C3C715E6E72125A1DC5C4B73 +:10CA200042543EAD35D90737391F54D03E18B25E57 +:10CA3000B0CCF0DE42F37AD1DE22BAB894D93E907F +:10CA40000E4A11D7245CEE4121A743E7A931149087 +:10CA50004622377EE40ABC85720B1D457B99216E08 +:10CA60001CD3EE13F3107011E3279016390BE9B9BC +:10CA7000D06C9F19FD6BE18F8B78BB886B0B7F5A55 +:10CA8000F8316638CB97F9DB91FEA7B8851FDDFB3F +:10CA90004D7C2FFC67B3DF3A781E00218BE76D7861 +:10CAA0009CFE6EEF6A3BBB8F8FF19D78BFD5B3289C +:10CAB00065B83CCCBB5A8DE75F60198161CF13210B +:10CAC000C83270DF89605085ECB8E6483FDEB1B30C +:10CAD000E31BBF1E78119EDB8B9FECDF8275E7CED8 +:10CAE000CB08D7C1783E61E78315FE9D92B7F55616 +:10CAF000D4A389AA957CA4A30B3B68AA8F0AF9B892 +:10CB0000A827B206EB7FA3DFD7FF473DBF0BF0F9A5 +:10CB100068EC30F58ADA1833AFD6042F710D86A38E +:10CB200068EE49B44F1C44B76EAA0F7565390A2FD9 +:10CB3000AA5A657A5E4AD407F0DE92AFBB2EC4FBD8 +:10CB400047367D3972F4639B7EFE619657600D1205 +:10CB5000CCBB553C50AFD72F8374080C55A65BDF78 +:10CB600008D6854C83EE27B34B18BEFF56EBEA3050 +:10CB7000E10BFB0D665CD2F3D32EF1F9452E71FC6F +:10CB800092DA4B1B7E81DA4B1B7EDA253EBFC8252D +:10CB90008E5FB2E8D29E5F60D1A58D5FED129F5F80 +:10CBA000E412C72F597C69C32FB0F8D2869F7689CB +:10CBB000CF2F7269E357A376A0B33C42F05E095FC2 +:10CBC0000751FD3E3059E135FAF3052AA1791A845F +:10CBD000FB25F9DC2FB96F474B3DBA50BB34C54735 +:10CBE000E341E0DF6741FD78C2EA77752EA271D696 +:10CBF000B651E372F09E2A67E7DC93786E6FBCC68D +:10CC0000FC71F3DF0BAB0D18FFEEDAB5E5E986F248 +:10CC1000D45EE3BD15DF6C2C30D42F0F4D34FDDD19 +:10CC2000BC29C6BF47169C61BA7FE156A23F0F9947 +:10CC30004F222AC657F2EFB154E2BE99157DE62B7A +:10CC4000E1FF6E857E17807F7AFF251F3CA1C1FE24 +:10CC5000FD0837C5D0BFD3547FB1E74F9F19CDE34F +:10CC600031A6F3A7042F978C71DEDC9C8749AC3783 +:10CC7000D3F89CC0D7DDDB2CD4E5FD7C07A1F73BC6 +:10CC800056857D167AFF39C7DB444E7A62DDE15660 +:10CC9000E339F47C8D54223E0B3A8805E36BFEDDCC +:10CCA000440D101A17A274B24B8B4D27BB88BB12D0 +:10CCB000EFE3DA1526F4EF6309BAB8DBE6CBC17D02 +:10CCC000B5899D8C1E049DF8904E92312FC87CDF53 +:10CCD00080195F647204E6BA6B477E9A3E1F95EC3A +:10CCE0006570B7C3BFE1F055B8DB882F1FD195BF82 +:10CCF00002BE4E7F4D7C299E6024C583F14CE2C369 +:10CD00003CA9C3A3C659101EFE4E95FAFF35D00CA0 +:10CD1000E1ECEF64F7A8093C89FE76B492C81C9D4B +:10CD2000FFE75723018473B55C5489F9E73B4B69EE +:10CD3000C878087E76127722C6BD77765A12E9DD6A +:10CD4000D407002FC584FCD7B6A5298550DFED2771 +:10CD50008978BF56779B85DE57D6FDAC546FBC4FA4 +:10CD6000399260C9A2EB48B094D3A7953D03FC4922 +:10CD7000ACAC3E226379F4E621F77DC8589F5A6334 +:10CD8000FA7B812420617BEB652C8F332560BCC747 +:10CD9000C6566E940700C6DEAC328CB7707AE7F7E1 +:10CDA000A386AB4918FFCED7655CEE98E928F5AEAF +:10CDB000459498DA467D8BCAB3EE3685C2DFC6E568 +:10CDC00015D9CCE842837F484FA9263A72A9463A42 +:10CDD000B2C979340F57F095988F18BF6D5446A299 +:10CDE00095CECB4AEFC1B699E584697E4E0C06021A +:10CDF000EE9C1E120E43BD4D63FC41E43EFADE364E +:10CE00008D9074FF5798E7D7944F575F16FB7CFCC3 +:10CE1000C5CA2717EFF3EEA96C9D9FABEC3EEBAABA +:10CE20000E46EFAE1D8CDEF12437CBD70A2CCCD6C4 +:10CE3000EDABEEE772CA0C37576FA00AE979AEFC8A +:10CE40006A00F323EE7993D17FDBA8B75FC6F28E39 +:10CE50007B18FCFD2AC333D08B1A81A9DF7397930B +:10CE6000E6054F29057C21FE5F35CA93A9BD4638EA +:10CE70001698E4863F0E5CCDFC1A0FAE7708B89684 +:10CE8000015C0B2E1EAE8AC6E473EA4C76BFE2E16B +:10CE9000510AFBBBBC1A83636A40A5F277AE7C2EB5 +:10CEA0009202EDEE0B80BC8179D60418BCDD33858F +:10CEB0001C37C253C81701FF7C0E7FB7EA7E05FFFF +:10CEC000BE8B53B3129F84F0FDAF00DA115D538522 +:10CED000BC192088B79400A35B01E7AEAB189CF3A4 +:10CEE000031CCE9D1C6E129110CE667A35CBE79452 +:10CEF000AF09E76E01E70C52F655E07C5F12BB3FCD +:10CF0000D93686C1D5E61C88A09CEDF45BE9BA5EF3 +:10CF1000F02BB4BEB398D53F9CB4320BF56DA77718 +:10CF20006B16D2659BFFC62C94EF8E2C2E6748C0E3 +:10CF3000995D163D77502DEFA0F78F6EF529143FC0 +:10CF40002E5F6CF995323364A7E31459894CE1F0F4 +:10CF5000981A0B0EF652C5202F731B8DF04D32C15F +:10CF6000D7F135E5C37F7E4DF9803947D8EEEEB174 +:10CF7000E27E862E3BD54FE5B7D0B879011F6BDB3B +:10CF80008EFBD97BAED774EF6BF2519E38AD2AC2BF +:10CF900033DEBC859DF338BF0FE67E7E9F4B17BF07 +:10CFA000CFE55E7E9FCB0E7E9FCB76BCCF059E9D50 +:10CFB000789FCBE5684F07E853BE278DDE3BF839F5 +:10CFC00026B0FBF1DE9C3324D6FD247ECDA8FF2EB7 +:10CFD000DB64BC9F2CBDC6A8E75203463D87FB5EC1 +:10CFE000FA7A976ABCAF2DA9D0785F9BC367BCAFB4 +:10CFF0006DCF6521D907F0FD7FB1B1C61E0080005D +:10D00000000000001F8B080000000000000BDD7D09 +:10D0100009785445B670DDBEB73B9DA4BBD3095912 +:10D0200081849B950E84D040C0A0416F16302A8326 +:10D030009D088A8A1A013140481075CC3C9D97861C +:10D0400004081830A0A8332E34EBE0B845272A2A6C +:10D05000321D04069FBEA1595474D4BF757C0AC802 +:10D06000480417FC9ECBAB73AA6EF7BD371D088A28 +:10D07000FFE77BF1934ADDDACF56E79C3A55313B27 +:10D08000CB88DF4AF0E747F8C7DB4D3C76CC9A48BF +:10D090003221D9BC6CBCF8B0355840C8B2B6EA38B9 +:10D0A0005200F594402A2D8F85429990A566777F8E +:10D0B0000FFD1EDB366B227110B2B88910FF604283 +:10D0C0005A9BAC982E4CB7B8FD89846C7853744742 +:10D0D000D12616C5A33869FDAEF42584D0EFCB9CCC +:10D0E00084A464D2EFCEF984641122D101049A970A +:10D0F000DA261C2185B4C1D4B9848C09CF67599B29 +:10D10000C9ED2F22242ADEE686F14981F45190965A +:10D1100039E97F3FD2F63FC2CF45E1348AB0725C35 +:10D12000278C236BF204C6D39737BE273CBD5353DD +:10D130003E58B6277E028B3D8F9CF7A34853715A09 +:10D140005C8D8DA6AD09848CED39DE374DE4E99D0B +:10D15000B90850429220AD25004F89F7B934BEDAA4 +:10D160004A6C6138ABDF173B197CA30412B1DF16A0 +:10D17000806B54382F11A274003E061645ACAFA642 +:10D180001403848C26A4ADC9BFEF6373F8BBAD84D0 +:10D19000B6B7F5AC5F298B38EF29B28CED6C929F56 +:10D1A00038693DBB9BB6D7C0C5A69CDDF8F4A7285F +:10D1B00091AED7C1E9863C214880572BCFC70A35AD +:10D1C00053E424C09787229BD62B56484D011B4F12 +:10D1D00051DB09904AE42357185FF0E3A4E50CA45F +:10D1E00090D272ABBE5C4E467861BF52B8BDF2A31E +:10D1F000D0FBBC7FA914F0F851EE69CA2DEE5AE0BD +:10D2000027E3F77F974D2A1CBB1329DC44BEDE08B9 +:10D2100070FC772D1C451B83638B90B93548F9CD85 +:10D22000AC38DC1423A43451EE00BE6C516CC897AA +:10D230002D891D81329A3F5964724357F6DC32E4DE +:10D24000C796FEBB0FCD04B84EDA737823424D0962 +:10D2500054A8F0A5E5765765A042C50709E32B86DB +:10D26000FFBE7CD8E6E0229AF6BB7C1A715252B11E +:10D27000A5588848F1129D5B61ADB185F163815F6E +:10D28000E8F798C4094744CAF7316E0D1EE1FF1F45 +:10D29000591EE141176F19B8E41601882235546F01 +:10D2A0002FCC47923DE1F991738F2F329002298D57 +:10D2B000A6923B15E4654F7AF732BEE7F57AE70BA5 +:10D2C000566FBC3831F5460A97D637A87C04BE7035 +:10D2D00031B960B6327CB61225F546DA55EB40C955 +:10D2E000ED857CE274941F4B52AB5B417E7E95686A +:10D2F00022A200DF1759417EC0EFDA71933C26E28B +:10D30000D7E027656A8C4EEEB7CAD528CF7A9B67DF +:10D310005A8DBEFD805A7DFBF4F909BABCDA2E3A6B +:10D32000F5B20315FDC2F96592C70A726471E26A2B +:10D33000A14643DFF1F93507E5D1E1BC397512B6F5 +:10D340008B4A2F8A382FBF4B3904F5E9FA991CB65E +:10D350002546943FF7F17DE87EBE0F9D699D0FF253 +:10D36000FA7FE4F51F6E72621AC267CE6C1D5E967C +:10D370002651794DFBDB0C5534E33F23D71C07FEC8 +:10D380000BE3D914860F306DC11C13F0ABDA4F4B91 +:10D39000D274C49BBA9EDEE6D7CAE5BF5ACF2A79BB +:10D3A00089BB00F91EE57008EEB21E5F05995C6E40 +:10D3B0006C9CAD1B7767FC84A99994EE961C14496C +:10D3C00014CA11FDFA7AD2AB7E1D4B12D9FA7BA793 +:10D3D0006FC3BAA94408CD0BF309867C7F43FD2CAB +:10D3E00043F91043F94843FE7C43FD3243FE524368 +:10D3F000FD6A43FE1A43FDE986F23986F20586FC92 +:10D40000BFE9EB17313CDFAE7E3B8D7C01BC1AEBF4 +:10D410004B9282F8950CF8353BF5F82D4D2F3D3F9A +:10D4200013F7855A1D7E55FAEC2B7E96521917007C +:10D430007E926A987E523C8768E961496216EE1FC7 +:10D44000622971B3564C4E5978B998C6C6A3FA9A58 +:10D450008E8EBAD267A1FE481E4C6072F30C742106 +:10D4600090047DB9D23F5C9E05FF9E5BBA38331DA8 +:10D47000FBF8BE7BFA79AB7277CB20CFBC4C901710 +:10D480003EAA4F0F0BC3490EE9D37430CA77EB1392 +:10D49000892F8AEE77EBBD26CC7F954A07027DA5C2 +:10D4A00062B64EFF262428403F4639B00AE4144DA8 +:10D4B000EF013945D3BB9B52315DBAC2943613FAA2 +:10D4C0009B6841FDB8DFF0255E09D2B2E27CD8BF8F +:10D4D000EF1EB64531D1BCFD9448FCA3A8BE5078E0 +:10D4E0004D312C2776FCF4D49D30DC77749C31C010 +:10D4F0009D04958C7515C4671E4EC88A1D6997BA20 +:10D5000068BF728EE48E86B202F7422911EB79C1B0 +:10D510006C90A5EE3DD9343F28C784FA85B9B8BBD5 +:10D5200009F47775DE2B2EA5844B2B6656BA4D5E1B +:10D530000A823B07D5DC0B701AD4464C0ACDCB5E71 +:10D540005900B9F666A68CF0DEF02265C86C18A802 +:10D550003B0DF6D9AF575816C13C7BC713114DC5CB +:10D560003F3D55FB413DB33F7E57402ECB129210BD +:10D570005DE57FB52B346F1359FE95CC239E459AFC +:10D58000FCE399479C906F1B9561827564263A1461 +:10D590005F04BADA0FF298AE7BC38A5983B4FBA05A +:10D5A000319527D27E53685AC053A0B5F300FE3C94 +:10D5B00095F9F754967F0DE046FB951B7979224B40 +:10D5C000CFF538C6FE0F643A55BDB43FB71F0B6C9C +:10D5D000C9A7D54FF783BC32EAA754D0F5073A5F05 +:10D5E0004BED4913ED7BED0A0BF1529E5A9B4ED049 +:10D5F0004EF42EB3F836017F4872FF2B357A976FC1 +:10D6000059F23580179F40A66AE5E4FD1CCE2BB386 +:10D6100004AE671DF38A947ED7D26D13C4ED5AE22F +:10D620008C067D24846FEF098FA2C1F78559A5ABC5 +:10D63000BC30AF996CDFCC0AC9B3BC8512ED671D55 +:10D64000F443F3EB5A4D38BFB5DB28FFD2A1BEBA85 +:10D65000EB2313E8CDC388DF04EB1B4A7C98BAC8E0 +:10D660007C1300A583EB191B39FFE651FE467B07AF +:10D67000441F2DF70CAAF91AF8228EC89897BD4EB0 +:10D68000A4A7FA6DF16591F4039265E27626A99557 +:10D69000C6703B87C199648DEE097F33998F70BF47 +:10D6A000DDE53141B96DEB3EFF005AF4DCDB7ABABF +:10D6B00005A8546BE44E0A1F27CEED5144DACFB6CD +:10D6C0008C9A58685F5FFBC5EE64E8DAEBC5F6A399 +:10D6D000B29C58EF1A7FC778E866B83B5806B4305A +:10D6E000ACB26B0790CC50651D9819C4557CCB8E9D +:10D6F0007E32CCA326318BD6CF0B044B817C6CB50C +:10D70000FBFCC9389F0B4D4017D9301F4E1F5548A1 +:10D710005F32D2898A6FA0872A9ABFA68EC1875AA4 +:10D7200083584E24A76EFEEB17533AB1F5A4137B32 +:10D7300016D38F866485EC2B623EBD7D35242B820B +:10D740007DA5C2A5BAD36D067781E709E762B081EE +:10D7500026F9BA7746D3EF8B326A4640BBA2073D23 +:10D76000CD407FB66D012FD453E1642B092802D63A +:10D77000538A00AE6BEF2A2BC37DA19DA0BDD49B25 +:10D780009E6B2E31E9FD38A41DD791DBAED7D3298E +:10D790001DE37EDE838EEF0AD1718CD62FA1EE3F82 +:10D7A000BE36538C0BEC0C6A7F605FBDC891CD7C9C +:10D7B0005F52E95AFD9E4322FB19A686E19D2A9EEF +:10D7C0001EDE5323C1DB01FC918DFC320DCA9DA4EA +:10D7D0001BCB07DDA5E797FAAD5FEC1E40E76F2B8B +:10D7E0009247027ED4F167717AA6743C13E9F8C1BE +:10D7F000EEDDB0AF0DBA8BD1F13CD03592C2F478EA +:10D80000BB4BB919C651E9CCB89E9B787F8B323C93 +:10D81000F3B0DE831DBBA2B19DA701F2B60703FEE4 +:10D82000681286EF200EDFA8DF87F0EC04F9513D87 +:10D83000D1BD0BF6678FCB391ED24972770BA81674 +:10D84000D7D68A3ABDCF885F4A5FBF877514114F1C +:10D85000B9208036DB61C6FDB317BA09EF9B5E5570 +:10D860007EDC7506B9BD2C121EFADAFF890C4F3B1F +:10D87000B44FA8F490D3D96D3DE6D5C77AAADF2C72 +:10D88000ACC7FA747AAC4AF7CB5BABD1DE52F1A0ED +:10D890007E5FDC5A5D9909746E93DC91EC9FD07EBB +:10D8A000C3E9FC514EE7ABB9FED5CEF5AF954D328D +:10D8B000CAF7B62617A6CB9BDCDC1F5A8CE9E226FA +:10D8C00005EB89CB4E94A2FD7E1741BFD6A2D8426C +:10D8D00021125D657AF5FAFEA0463DDEFB55EAEDC4 +:10D8E000EF78ADBE4CFF8F2BCED295DBDD4374E5D8 +:10D8F000B1AE91BA7CB47CBEAEFE964135AF015D4F +:10D900005912CB74F548F00B9D7EABC271BC380D3B +:10D91000F57D0A4F660F707D562D27A48668ED149D +:10D92000759D6D063D7639C011E1CBE0D80E70448F +:10D93000F81673785632BB89DB3D31AADD93BF7A86 +:10D94000EAF444D4A7515E2D4CB7E0FEBC3C93E909 +:10D95000DB3DE82755233F29CF2F5DC6F673551FC2 +:10D96000DF95FE5625E8B5EB534D2827D727EE70F7 +:10D970006DC07C8C9BEDA7DE7617C59FD9C5FDD504 +:10D980009462D3E87AED9C6F969A09FABF9727D9EB +:10D99000DCE007B3BB664DC47A867109B98568EDD2 +:10D9A0003FF271AD4EEF20D26CDD3A43F32FB2B0AF +:10D9B0007E0422403F0905161DFEAC4493CF84F936 +:10D9C0005AC278CC84F5723C19F41CA39F421DCF37 +:10D9D0003951BFDF2CCD67EDBBD23723DE8DF0751B +:10D9E00054E8E97739A78B96A4F5C887C6FAC6FE2E +:10D9F00049498CCEFE5BEE3ABD9F44B5A7D57A600F +:10DA0000473B23D437DAD1E7C25E77E278FAFD2EBE +:10DA100082BDEECED6F893547887F0A0FA17B91DE0 +:10DA2000A6FAADD5FE24C2FAC33CFAB7BD28FF1E44 +:10DA30008875A01D9963B3F84016E6D079001DB72C +:10DA4000FC21D6B788E657C54EEA8EA3F99C8DA275 +:10DA50008CE5360F9EDB74AD99D03F48C77D48A852 +:10DA6000199FADF1C36D8CFF6D2AD307A48F822E51 +:10DA7000607201ED5CEFAA510105F4F17CE2DE4435 +:10DA8000C00A66E52A3D116D5EEC99FF3C9BEDFBFB +:10DA9000A9D792F91D11F0DF9CCDF6D1B01CF7C4C7 +:10DAA000A0BCE6723C87C36B537B758C568E6BBEF5 +:10DAB000C745A2AB7325BF5B407E0F8671F62BB8BE +:10DAC0006F17112EBF9F22BF46F93D27B36621D0A5 +:10DAD0009BD978DE2705517E0F939545501E07F69A +:10DAE0001EE0E5068A9708EB7881E3EDD78A177583 +:10DAF0005FDDD4FE2CC34B818A97952492FDFB2BCE +:10DB0000C04B27C0BDC7BE4A82780EDB3D50790EA0 +:10DB1000F8F11959791ED2107EAE8ACC379FFEC219 +:10DB2000F87994DBADAB397EDAB97F7C25C74F1B22 +:10DB3000DFAF9773FCB4F2FD7A09E027EAECF966EF +:10DB400050A31E3FFD2A630CF8D0E327AE588F1F69 +:10DB5000BB5B8F9F58D710033EF4F889CB91991E79 +:10DB600099AAC7530FBE3983BDE2807E22F83706DB +:10DB7000D6044AE18CABFFD48E2E3374E2692F8534 +:10DB8000545DEFC306BB544DE372983C4C2D8F8C13 +:10DB9000F7EF38DEFF98A5FCB78E8F2F8ECCC7A687 +:10DBA0001C56FF13591172B4747559E4FA565EFF8E +:10DBB000E020252A47D33FFDB94F3C8DBD605C7FF7 +:10DBC000ACA0C4E5E03AE4AD418AFB8D0BD939E461 +:10DBD000C668B903CEF3BD0B6DEE4D32F6E4B182EB +:10DBE0007DC4FB21DE38EC37830F33C8B6E75B38E2 +:10DBF000F7CB9C31B0FFCDB43C7341EAD11A9AE621 +:10DC0000E464239CB26ADD3B00CEA2636A7F767E29 +:10DC10003CCDF9C9504A6AFE7EC28F60703B13FA50 +:10DC2000742E47E520EA817422BE4D944EA324222F +:10DC3000D91360BD0AAECB0C7AAC08EB6DC77C0C77 +:10DC4000E9C0D44602ECFC9ADBA3A37332115E4E0A +:10DC5000E2447B3581B83155F9D89A48A4A491D8CB +:10DC60007F4BD448821BFE0560AFDA06AE5B0E36F2 +:10DC70008D42A130065905E121DCB71BD74F5C442A +:10DC800066FEB6BB9C189FF01A5DDFD0BEAFAFAF8B +:10DC9000F5BE8976149238421AAD2CBD23C6B11E4A +:10DCA000D26FA2337CE0B43A3FBBE63780576F199E +:10DCB00041FDC3FB41ACAF19273BFF3C661FF4B9E4 +:10DCC0009F2BCF513F379CA37E6A813FCED4CFDDBF +:10DCD000F0EB5838C7F4D4C1B82DF16350EF54536A +:10DCE000235CFD2E653EF42B590F647CDC2FACB712 +:10DCF000D9DE13506F6B11FC04FC94DE0F05D4AF1A +:10DD00004801C3934D26AECCE1E17E6CEEF98398D9 +:10DD1000BF8BF97B16BE7FC760D0BF1F889D148C58 +:10DD2000A3ED37ECA37A1EC4D194BBDFADA5F49468 +:10DD3000D4CFE25E4FE9A71FB793A3568CD95B4BB4 +:10DD40007FFD6C30932F5B9AF6385BA840B24BEEA8 +:10DD50004B46D276367E7E4BC48941D01BED632480 +:10DD600019CE38F2457F25CC97349808F0C5437515 +:10DD7000FAF3DC2579F9D89F9A1FC0CF734991D463 +:10DD80001D8AB3A17AFCEA1C1E57E3200ED00BA516 +:10DD90001F94B848710F6AAACEAF2891EE5B71E06C +:10DDA00017A49C42D3A2363F067F94B9FD56D06398 +:10DDB000D7F888D742E1F4D874CF6CE8AFADD81368 +:10DDC0000B7AF99A83D5970DA3F30E04253780E0DB +:10DDD000A5C10938CF8022AE88A5DFB7BE6772C261 +:10DDE000FA36F0F66D1E01F9FFA169C4E7A5F0D877 +:10DDF00050B7C32A82DE1B30915CD473A9C135862B +:10DE0000BB4E64F0D732BEBF6370127EEC0C2C8820 +:10DE100007B8AC8ABD30A0D0FEAB2A99DF79823832 +:10DE20007017F41B68B3207E9278FC9140AA507F53 +:10DE30004E98A6D197E9FF761E0715B88D60DC5382 +:10DE4000DC681BC6013C1764E7460F5532BFB3833D +:10DE5000F871FC09E2B66813FDDE592939819EE2AA +:10DE60000CFAB90DFAA324D7F920EBCF3182F5676C +:10DE700037C44159D57939E9BC28FE44BB8478764A +:10DE800056EAE3A71C867636C3787B01CF20970637 +:10DE9000923CC0F349CF6F471DC052B71C297EA2E8 +:10DEA000AD89042A34F116B65EFC875FE431BAB559 +:10DEB000A4EDB4C2BC4E7ADE4A0477D71BDFEFFE76 +:10DEC000F81E487FF88FCE06BAAEFFFCF6D0C6A784 +:10DED000018E8D77EF473AE476550A4C81CE67572D +:10DEE0009505E1385A61FE0152D4B5D35C84E578DA +:10DEF000AEB5624734960F2826BE680ACF019292CB +:10DF00007613F06B40742F94A113C5963686B0A398 +:10DF10002A9A5F713D251C2A1F92A629229C1F8CDC +:10DF200017DF20768AEF358A20B3F8376117F05370 +:10DF30007A85807658FA414F34D0C3C9C9268C7F80 +:10DF4000595875E525B9B4FF474A25F43754569416 +:10DF50005E0DE5030E327A71DCC6F047E1E4AFA056 +:10DF6000FC907D90F9138A48D0EDA7E503DCC49CB2 +:10DF700008FBC7340A60985F1BC70FF70F1415051D +:10DF8000BC0054BB5B8F47A7018F46BC5A73391E38 +:10DF9000F3493EB3EB98FE58C5EBACA91885F6EBF8 +:10DFA0004332F19A87F7C4D77EAA3F2A54FF0B5019 +:10DFB000FD11D2BF53FD11D24EAA3F426A574A2FDC +:10DFC0002BA2F30D24D17E81FF268E5E04E7038F02 +:10DFD0008CBBF9CE7FD174343F67A3949F5046E148 +:10DFE0005A0D5CCCF2AB15BA671E281275F915896B +:10DFF000927A8EE7853DD59E66E2E73CE5F7427969 +:10E000005BAAC4CFF5583EBB80E8F29D134DBAFC25 +:10E01000053B34FD0F04FC4461BE20F7B9D55E4DCD +:10E02000F9B23C9AA7E57BB93E5735CFE4591F8139 +:10E030007EE7E432BD4AFA8178058AAF2F7308DAA9 +:10E04000E9A24941F94DF224795384F83442A81CDD +:10E05000D4DAD73954AE6AFC23FBF3B85FDD53CA78 +:10E06000FC6C24FCF3DD181E6745E07B5B00F48844 +:10E07000256F5FEFF693DEE5AE39553AAAA5934BCF +:10E08000543AC825B930FE97A4646F29D059FB28AB +:10E0900009E8A188F301E17A1CAA8A947E5E3871AE +:10E0A000FFEB8A0C765AABB32517E37EAEC8D5F8E2 +:10E0B0001B1627CD1A05FB991AF7434885F313BAA7 +:10E0C0002EC17BA509F4B6DEF514897CA2814757E1 +:10E0D000D58438D8076C5C8E1BEB2F6EDAFA168C61 +:10E0E000BFB4A903535BA207858C55F2A2FFC6EF0C +:10E0F000AAA985795907D2728D1CB624D2763A3BEB +:10E100006020D3BB543C3889491BA7BAA66D644C28 +:10E110001405461BDD2F403EAF095447C3386DEE52 +:10E1200091A7F55F9D894F36541C2089148ECFBF6F +:10E130003DE9F5C934DD07FC46F7C1E738DFA41730 +:10E140003FF3CEAD3A7E399C5066D3F2CBE1D54A4F +:10E150008E965F58BE777E29B917CA3B53255D3E20 +:10E160001DF84593DF10E217960FF30BEDBF84CA3D +:10E1700085372D985F9D7B78B557537E67DE613D6F +:10E18000BF8C173DEB23E801815C26EFCF35BFDC68 +:10E19000C7F7913EF3CB3FCE8E5F9ECEE57ACECFD2 +:10E1A000E7971773937E397EF1F4915F3C3DF9E573 +:10E1B000EF3F855FDA9C7E8C076C9B6CAAF445C0B0 +:10E1C0007703978FAADF7B34F753944F53AE1E0625 +:10E1D000FA2C8F5B53E369DAA6B1FD7B61D504DCD1 +:10E1E0002F37EC63FBA5BA3FF3A35DCA4FCC8F3149 +:10E1F0003AC0F6CDA46201DB4F52049F4C7F6DA361 +:10E200002A413FD8AF4B04D22EC352E757E50A61EB +:10E21000BD898E877AD3236E16374B0E327DC74A5F +:10E22000FF037ABABCD8ACDB57538CFA9721AF9E68 +:10E2300063AAE7978F405C0285C7D72ADD18F65B93 +:10E24000150E6B0E96A11EF2D540CB69CFABDAF856 +:10E250007A43FA5491A734923F6C7A1E8B93B8DDBF +:10E26000A54879A3613FBE11F75D753F37EECB9DA1 +:10E270001507F472C65BD84F2767BC85F7EAE40C34 +:10E28000CFF72A6748119687F6659E0FEDCB3C1FA6 +:10E29000DA97793E2467A0FF92F0BE3C6873E1BD37 +:10E2A0005A393307F27DD897AFCBFB65E4CC5FCE0C +:10E2B00056CE9CE5BE5C9277CEE4CC84BC5F50CE5B +:10E2C00054819C893BB39CA9023953A09333D7E670 +:10E2D000FD043963AFEBF2C2F9FD35BDD0BDC8F521 +:10E2E000A5D939CA0CE89F4CEC5BDCB691AEBAAA52 +:10E2F000362F4E067A71333BAFB7F6F6C6BFBCD5A4 +:10E30000A2898BB64B0176BFA2F179FC7E6DDD3E12 +:10E31000F4979D69BED3F308A6C67DB4AB6AB71562 +:10E32000E9D66DC233F19F3A8FB6C98C2FDFDCF48A +:10E3300002EAB70F80DF2FA9A79EABE2B5AFFA8F35 +:10E3400071DC865C19D7611CFF4C744BE9F421A089 +:10E35000D393036F1B0A769E68BF2F16E0F52BD868 +:10E360000F3B7E0A9D0672193EFBB0EE977EC97583 +:10E37000FF0CFEDC0BF33ADB755F97D7E775BFF355 +:10E380004BAEFB67D80B9FFF9475CFC9256ADC0D98 +:10E39000DE9771C22F944F567F9FF721F82F56FFBB +:10E3A00030E4195867FBB7D675E0BF20DFFD283A87 +:10E3B000B5F7A708BB3763E7EDEC1E761FC659A972 +:10E3C000B91F45C2F7A5703DE8DF0895EF8D745F72 +:10E3D000EE974E411FF9C87C9A720BF3DB19BFBF51 +:10E3E0009323B07B6C425534C4C5774DDE81F10672 +:10E3F0006D9347E2B995514F51DB753629E84F6A65 +:10E400006BF260BAB2A932007E93E70F7C20403CE9 +:10E4100058D1813ADCDF568CB97400C6F18D2B8A55 +:10E4200081FC4A839EE2E07ACA90C16FEBF48A8E47 +:10E430003FD5ADF69684FD50F784F417DA4ED6D862 +:10E4400049340FE410B29320AFB393E6A15FA11358 +:10E45000F4175AFFBCC1F356471A678589D482FE68 +:10E46000B2A2CE5419497F793727B25F81E6F1DC39 +:10E470002DDA6EF52DCA047D86D468FD6A67D25FF9 +:10E48000FE34F82CFD0A6769274D1E7C6EF4971048 +:10E49000DF72BD253E5FB91E5CB2E74A4E0CE8A3B1 +:10E4A0009C18D0534EDC3AF827C8897773587CB54E +:10E4B0004A5F1B6437FA93DB2A09FA1FDB028BFAE7 +:10E4C00015D2FC73752622D0FCED6F32BFF09A6234 +:10E4D000E2837BB46B0612CC07DC8C0E2688B6DF99 +:10E4E000801FBCB382DA4F32F8EDAEA802D8AE8AF4 +:10E4F0009D747734A597AA628980DD34412CC1715F +:10E50000020A8B0FADB291DF44815D354E228BCE76 +:10E51000C26F6D170B04CA91943FE578E0DBDEFC17 +:10E52000D146FF3311DF70E33D27831FFA6CFDCF27 +:10E530006B07FF6CFF33F2DF179BEBAA311EFC0C5D +:10E54000F478DD601933C67DCAC8C72A3DF5467F19 +:10E5500036D0934669F2FC1EEEBBFC7CD9067AD21B +:10E56000A8305D74558D898B147FA5A6B18D2FBE03 +:10E57000A5BD8F172B75607FB18DDBF0FB7D10374C +:10E5800000EB93DC284F1F2BA37238C2FCB637CDAB +:10E590003F08F2735B5323A61749DD6202ADFF52B9 +:10E5A00093F720C06D6B532BA6CF37B5637967D334 +:10E5B0008398DED3E4C37445D3164CEF6EEAC0F4FF +:10E5C000B12C364E89E4C77E2E3A45FBD7D0D1B860 +:10E5D0006E3A8E06DF171CF6EACAC7065B75E5E7DA +:10E5E0001D6AD7E547071ED4D57796F874E5B3734F +:10E5F0006A3E01BE74146DD17DB71574E8DAF5D5A5 +:10E600002E38D7F532AC4FC1313989877B1770FF6F +:10E610000AEE0D513E4E69A4E295E61FB5733F47E1 +:10E62000073B274F25A11FA44BBC7245EB77D95957 +:10E630001C64731A6BDFFC3B967F349D9D1FA97190 +:10E640009AA23544D744480E9FE73F6AE7F7947291 +:10E65000585C6446810F3C12240302D4E03CA48839 +:10E660009D93A9E7DECDDCEFF0A8996C15A83ED903 +:10E670002CB1F9372BC4B790D66B2E60F9872A8856 +:10E68000CF04F357A8144FD69C7337EEFE56280CD0 +:10E690009F9793210A9ED788FC9C3D74EE1DFD4FE9 +:10E6A00082E7FA1C5E8B623FC738DAF8C66E01F863 +:10E6B0002BA5B1BB0BE6F7E8EF2D72247BA8EBF797 +:10E6C0005FA701DFACFDDDD769C0EC6B43F133DD43 +:10E6D000D1DAF8990C0E97B58D5918BFB0B6D6A1FE +:10E6E000BB07A729C77886AF6AF9FB044442BB6819 +:10E6F00080330C579F1A3F2242DC1D5D7F76F8FE67 +:10E70000E9CF8DAF59DBB880C5D70C243CBE66126B +:10E71000DA932A1ED6423ABCE7BDDE5F3ABEE68CEB +:10E7200071358638071DFD42DE6BA46F19F112C5E5 +:10E73000E95BB88BC545A419E8468DBB50E9528DFD +:10E74000CF50E335D4F80D0B8FEBA0C3F2B8E6C879 +:10E75000F465D9415C70EF4D34C5B8D7679E398EEA +:10E7600060812B8B6F0EF387B37E59FCC057839566 +:10E770005B5C49E17E07B8945B5DA3C37935DD003E +:10E78000BF8EA55DB88315A0AFE6172BCD709F2F68 +:10E79000A188E03D9DA26201D3FC832CBFD82562F5 +:10E7A000BB7F77317F939ABF5C515E85F671867629 +:10E7B0009787DA99B1DE932EA6E73DE992D8BC7926 +:10E7C0001CF2244EDF4BC78A2C3EBA426072030E05 +:10E7D00054C7F0FD90C2EF72E29C92A3F1BB5EC100 +:10E7E000B1B5B289C5F7A9F1D07F7F53C478685B12 +:10E7F000B1A71CEE9E8D0E04FC70BE5EB491381362 +:10E8000064985F50017E5C987EFF0E888778EE12D8 +:10E8100076667BF941A62F5C517C33BE37E2F84E19 +:10E82000447FACB3C4EEF6C14013CD6CFF57E3A1F7 +:10E830008BF5FA4295415FB8FC0CEF7F24906E2F68 +:10E84000EC935B5C067F2C7F07A437F91D7E078461 +:10E85000C98722DEA7ADD8190DFEEBFC8326BCEEDE +:10E86000296E5444BC1FDBC6E23C9E0B784E7B1FD6 +:10E87000753F876380CB89BFF338C94E2E27DEE50D +:10E8800072E210C8099ABEC5E3240FF23849E37D4D +:10E8900089B6A6CA035A7DC798DA05BF07E3A04622 +:10E8A0004804EFDFF5F2DE87DD4DFBD1C5312E44A4 +:10E8B000FAD9197F7F29EAA31E13EA95F7952869EB +:10E8C00091ECBBFBA6949D36FE7065D3D4032DA7B7 +:10E8D00099A7C3A2B767D4F45B977A3FAE1DEF5BED +:10E8E000A42826027155695619EFFFADEC52CFF7F7 +:10E8F000ADBE68585F9D8DFC5313A7D23E2DE081BD +:10E90000F2154512DECF51FB8D2BA6F3D1FAF92B70 +:10E910003FC278E995E382A9A0CFDC37F693A9B985 +:10E92000102FB24F2440063DE6ED62FE76755D295C +:10E93000D27C21529C7A6FEBFA90B757E3C58DF0E9 +:10E94000EF55EF808880D3DFB7B2E427F58CDFEB9B +:10E95000C33CD16EFD76CBFCC970BFB7AFEF5FC4CF +:10E96000723A4C9B49A2819FCE448F3673379E1BCF +:10E97000DD3333F2B951763EC3F73D25FBD9FB2297 +:10E980000591E7D1935ED97C5648B47FDA6F7B4915 +:10E99000E4FEAFC81754BA7E07E4557BA509F50A13 +:10E9A0003B159F10176F1F47F520F0E328EC9DA241 +:10E9B0002F4BD8F98C515EF418BF84C257636F1B7C +:10E9C000E55071BE4D671F9F1C3839CE1F89AE7848 +:10E9D000AAC25195433DE148F09CA91DE088708A88 +:10E9E000CCD7617C2D540FD16ACE705F6F5224FA60 +:10E9F000E90D0F467A5831D313E70778BDFA2D9108 +:10EA0000C1B955A2E7C7DEE06784D7F5BF30BC8C3B +:10EA1000E517E773FF481FD7D9E77A542F726AF4D6 +:10EA200062B8142DD1FC389EBFC22B041FA2724BBA +:10EA3000D8F637D47BC6F1F40A48E9FEB84DF0FFAA +:10EA4000F31FB4718920A703D2AA5F1A0C1E32B239 +:10EA50004498AFD37F960BEE432FA35FA8BB1FD480 +:10EA60001B4F6A2486641FAEEB6F42B01936AC2B85 +:10EA700089B218D27AD26E8176F59D7F3B04E3D4B9 +:10EA80007746FB45704E6E351FD3FA8D666BEF8F60 +:10EA900064C22B1A1D964C3A9FB95BF4E7A4752407 +:10EAA00080FDCDEBD07F37DE1F11440A18789C2003 +:10EAB00014FF5A82F1BD249A954B439C5CCE75E7B6 +:10EAC00069DF33ABE5F0AAB5DAFCF0BE10F1E9E797 +:10EAD000297139B48BCA31EB48BC0FF3A77CBAEE6D +:10EAE000234EABD744F5E5E4849A7A80C78D44B6CB +:10EAF000B094E90DEABA8893E173866DB205E03B04 +:10EB0000A3D5B80EC502F3B9A9FDF4EB53F1FEFF8E +:10EB1000F209C2BD355FC6745ECCC43D0A14170548 +:10EB200032B4EF4134C0FE00FC35BF9F8E7FDF5012 +:10EB3000E99128625FD6DF13AE39E82753E1DA3B6B +:10EB40009DEAFD642F44B37953F8ED0539A0C28FD7 +:10EB5000483585D0AFBA9E7F8D0E6CF6C3B9AA9D9D +:10EB6000BD03F54142CD9B00EFF443C14F043A751C +:10EB70006293F3609D9F6F3DF29698155E1F21C1D1 +:10EB8000FB213EBA76ABE85C0EEBD9FAEA21A0F79E +:10EB9000DED6A5C6C7527A40B8D1797D14695E9F8A +:10EBA000FD96DC007AC978B140E747798EEF276B94 +:10EBB0000A3C87617E4507063A60BEE6AC8EDDFD05 +:10EBC000E93CBA6F1730AE36512415003F351EE1CF +:10EBD000844D423B3B31D62B3A68BEFB46E25E0F8A +:10EBE000D370CF7703A988E905EEE5946E926F178D +:10EBF0003D204FDEBF6D46FC0C9A26DB67C667D30F +:10EC0000F4A228E28DA6FD250B264F073AA1A6C740 +:10EC10004FA1F3BC2E8ACE93E6337F1BEBCFA6FC2D +:10EC2000F6570BB102BD26C6D6AC1A0FE3C48B381B +:10EC30009FA3544F94A81C2BBDFACB51563A5EFFAC +:10EC4000EF6C23613E698DE5E49F1494FBF3995FBB +:10EC5000F1B327BF1905F7C0C51F6D6EBC67CEE9BC +:10EC60002F319BC1C388EFAD9CAEDE8B61F64E7D2C +:10EC7000926509F8DB3FE7F60F515C682FDCC6EDC3 +:10EC800085F762981DF45E9EEA5FF22769F5DBFA6C +:10EC90006825EE2A301EA89E04F1CE5F3A95B8781A +:10ECA000A8473CC8B7B771BBF973422A81CE6F5BE6 +:10ECB000569E9240DB2735333818E7377808DB9FBC +:10ECC000EB4E5182D6F8CFEA24BF05F486BA53162C +:10ECD000DDF7F7A91EEDD5DC57BFEEF0C1F130BF6F +:10ECE000EB497031D4BFFEB658E6B8E7FCDAC9E7A5 +:10ECF000D11B5CEAE325225178D40BC473BA7A2F76 +:10ED0000FF204684EFA421AC3CA93CF2FAC60F6177 +:10ED10007A5FF9D2890F009DD507CCA8CBDFF662C8 +:10ED200069CAE9F4E7FA5317109FC6FF572F051178 +:10ED30001EF5A72EC4EFE54B8F5980EEA11F997EDB +:10ED4000BF2D5A49017F6D6F70DECAF5A0FA53F1ED +:10ED5000C4DB4FFB9DF177B8FF442CFF3387DB9F6B +:10ED6000F7982A23C5772DE0EB1E92247940EF1AFD +:10ED7000EA27CABA08E3AAF5921322EBC5EABC3A1D +:10ED8000CB82D7C3BCCFAB204AA4F1667238AAF3BA +:10ED9000ED4C08CEF2207D76E7C13B13A1BCB33B1E +:10EDA00043FB8EC4235C1E745E1ACC80FE3FBF24DE +:10EDB000F2BD1D15CF63B8BEFCB7849A4E901FD329 +:10EDC000AEA2194A1F29D3FC26763F85F15B6FF866 +:10EDD0000EC35924BE51A783B305CBD5FE8EECE7F5 +:10EDE000FC48ED708853BF91CBFF1B37CEC5B827C9 +:10EDF000554E1D795044397504F7169AFA04D45FBC +:10EE0000A7D7509D8ACA95599BCA77C37670632A43 +:10EE1000211726B0EF7741DA62D6F9FBD5F1661CEF +:10EE2000F2A09E35B34DBFCFD592B62F403F38B23A +:10EE30009FC903CADF1690C7B3EED3F753BBF1B235 +:10EE40004F617EB506BB3C99EFCF463DEFA121DC7B +:10EE5000BF3F868C391BBBBC9E92C510DC173C2281 +:10EE6000CC63B4A47F674B4DE30A199D2CD874D2B0 +:10EE7000E2907BEFF728952339B4DF63D41E87F443 +:10EE8000C521CA934368BBE3FB185C5E1B52F30CBD +:10EE90008C777C1F5BFF89BA13B3E09D183295E92C +:10EEA0000D5170F980FE1A75ADD5D74CD7BB948A39 +:10EEB000A968B81714C5F411550F13C55B45072D84 +:10EEC0001FFB5F33E3619D898F5F5C09FD253D1E5C +:10EED000AB00DC96972A2340DE2FAFB2B9E1BECA61 +:10EEE0003A4A86C5B4BD95F603FB89EFCF6377C078 +:10EEF00071644EC7AA3278F7C5B9ADCB3F80AEABCF +:10EF0000D5C4DEC968BD90B89B4978BC866D55CF25 +:10EF1000C0BC3226D3FD41807BF4CA08A7A67FC2BD +:10EF2000F5AB7A8E93E3AF0CBEE702B897B04744D7 +:10EF3000F5F1445D16DAF54308A32735FE1EC60633 +:10EF40003D5285DF31BA5F114D9CDA900EC16FA63C +:10EF5000EB9AD7F90CBEC751B7C89F7C2DECB78F81 +:10EF6000496C1FE5F34BFC6B5A99EC08EFBFD70ACD +:10EF70004ED423553DF96AA2FE14A0BF702AE78340 +:10EF8000ABB97E7C6D2C83F374E2CE8076D7588942 +:10EF9000C34461766D79C7E8F9B0EFCE35C7837E9B +:10EFA000036B8984773535EA412A1FD66FB67BC15A +:10EFB000EFFAB9D09D079D1C35333EEB7E25CAB7CD +:10EFC0003E33427F7CFFAACFE37A5D0E51E0FE40E4 +:10EFD000FDF6C1781F2C2A86E27124CA3F2BE0750A +:10EFE00017ECFF74DDB35F8EF6E3BD30F5BD32275D +:10EFF000F1DAE9380DDB53D6839E9198AD8C5840F9 +:10F00000FBFBDC1CCC407941E59B40F7D6D4A14BFF +:10F01000A64894AFEAFB53BD8BE6C73F7EEF148949 +:10F02000D2637D56709689E6E73DFE04CB0F097EDC +:10F0300002F93B1E7F81D51F199C25D2FCEAC777B8 +:10F04000B17238C3A684B5F6F137A680FD7F349E31 +:10F05000E90FC41DBC1EE8A7FEA5C1A6E59AF5DE12 +:10F060003D94C9D1A3D1ACDED14C724335C0DB1580 +:10F07000CCABD69CCB350C0DF96F589C165FA7DA3C +:10F080008EA446EE7F306F37BB9CD5BB2896B44626 +:10F09000B3FB755ED0C7766E1B8C70B10D4DE0F082 +:10F0A000A2FD1485FB51E1A8F6A78E3B07F67590EB +:10F0B000FB662AF73572A66828C31B1DA705C7295A +:10F0C0005046C03B56F5D5034700DE28BE248E2FA0 +:10F0D000C98A8FABAD63F3A3FDC617E23E330AFCCA +:10F0E000CA3BBFA3F533C3F336D287C2C799DDCC81 +:10F0F000EEF777C767231D5D14CBF4455244E14713 +:10F10000E5D9EAA16CFFB97B683C5B5F080F290277 +:10F11000F6DFCCE13790D53FDBF556FF42EBD5E08B +:10F120004901FFCACEADF98827753D84ACD2F5738D +:10F1300074A1A15D31653C98474236B65B1A4DAC6F +:10F14000F89DAC0FB5CBA4ED2E2AEF1E05FC308F39 +:10F15000EBC3C47B21C635D4716931AF356001BFC3 +:10F16000F4BC0EE6272739747D401FD5138BF8FABF +:10F170009C7C7D4EB63E9F8E3EC9C1EE8CC9F69EEC +:10F18000741B827BA8BF8291BC3F1D3F47EA0FF8EA +:10F19000A2377CB40C65FBD439C3873A4F033C4398 +:10F1A0007036CC4F8527F031B62BD0F3933ACF3B56 +:10F1B0007AE3E7CC9F385E296B37EF77148FA0FF97 +:10F1C000C87A7A9ED799699A5E106ED7DAB1D00361 +:10F1D000723E5690991FBCB3CA0BFB5FC3B652F484 +:10F1E00053CD7BE1C9E7BDB4FD9CA7D73820B8EA71 +:10F1F00088D49E0C7A70DDA6C50E781FEEB0E4753B +:10F2000080FC3CE21323FA07FFC1F1A0EA5DF57C24 +:10F21000BF39FAE7BB27013CBEDE64C67B860D5BC7 +:10F22000A2FC51E837998DFA18CD7FC8F24BBF0088 +:10F230003BB661AB5E7F9AF3A735C9E80F23DE01C9 +:10F24000263C04F30F80C3B0FA8D663C4FA93F28DB +:10F25000BAE930A481742F81F919DBC33C4E51BC4B +:10F2600037748837427C9FB19C4A12D4C71A3AEF50 +:10F27000463DADA1F3924F41AF6830C453D4F6A2DE +:10F2800087BD3194EB61FC9D74153EC49784FA4DA3 +:10F29000F3630F147E48E7756CE3EB0EA140BB6F80 +:10F2A0002E423C9DE898B1F625B9F7FDF573D00FD5 +:10F2B000A2B4ED187EE5AD023B18DAC6D23AB3DF50 +:10F2C00001FE81BA756637DD8149DD931B36FF117A +:10F2D000ECCB77A2DC106A3AF7C95D6F9D4FF373F0 +:10F2E0009F31274E64D3B7C139B78A2788D9003DEB +:10F2F00045C5CB9CBFECB2C8C3D877D07B55FCCCFE +:10F300007DA6CB02F7FC8C702CEFE8B2603CAC1110 +:10F310004F1D1F4E0015A4F9B16F2C40DF47B60BEF +:10F32000F8EEBDB17DEDBA5D0EA0438013D8A12AE1 +:10F33000BE42F8EB8137FFA4978AB01EFA43CE8411 +:10F34000BF270047A391CE9F7A09FC28EF46B90159 +:10F350000EB54FDDEA80F57C2ACD67F4FEC8E26485 +:10F36000782FAFD6EC4D7662CABED73E7A3BD2E15B +:10F37000CDFB6E4F66EF482869EC1D4D6F1AACF35C +:10F38000A687A7E03A67911AA4C3DA47987FE32BD0 +:10F3900089543E13815FA614B07DE4D3F551101C4F +:10F3A000443E8573043837D92FE2BDFB1EEF22910E +:10F3B0000598FF8AFB17F20B42EF1F5A41BF6BE023 +:10F3C000B51A362E0D009E8EA62B29E0B7A570F03B +:10F3D00072B809F0EEBBB86F7C0AC31391E13C042C +:10F3E000DB517DBC1CBE43FD8059892ED4B5E3EFB3 +:10F3F000DBB0F155FF069D770C9CA77F9ACCE2F21B +:10F400008CEB6BE1EBA33F01A2A5B3DEF87FE33207 +:10F41000A4AF2F0F32FEA9F755556279C0EC4F818A +:10F42000725FD76401E54394EEFC3C441F1BCD9C06 +:10F43000BFF5E5749E92A085EF7601DFD354E965B0 +:10F44000D67D51BAF3FA30FDE8DF8B52F955B5B3EA +:10F450006EE6F2C0B86EA37CF01418FE8EC2C349EB +:10F460007DF27FD7997D9BFF08FC4CF9D72B033F9A +:10F470009BD13FF0D913AFBE750DA5FBCF3A543EDB +:10F48000D6CB5B231FD73E3B9A44E2E3CF6C6E1290 +:10F49000918FE9F7887C6C63F7A6FF7FC9DB9B7BC4 +:10F4A00091B7FF56A097B75F9182B80B08EC337302 +:10F4B000F1BD57237C55BBD72847130AE4887294C3 +:10F4C000FE1C241A78AA7054E973CEE3F3709C10E2 +:10F4D0001DAB74AAD271884E8DEBD6C3D3587E2152 +:10F4E000CC5D1307615E44ED18D0735F117DEBE9CD +:10F4F000D48ED3B92CA1F03FFE4426C61B2DE67650 +:10F50000C07167B703E2C71673BBA31BFC9271E11E +:10F51000EFDDD14C5F3AEEE976C46BF4A60FB78904 +:10F520000ED0F3823E5219C99F442536CE23487A25 +:10F530002B67E762C7B93FF438F7778E176D198DDF +:10F54000E0076E677FF764E6C2AB1C702E707C5BD1 +:10F55000F63DC07F37BD26B2773DBD8A04711233B8 +:10F560001808C861E2BDBF84AE73C6B6B918DF60C3 +:10F57000F4A3CCB26DC4F385AFC85D981AFD2773B0 +:10F58000C0CF02F4FEB0E1FBB6CB90BEE618E8AB0C +:10F5900006E82BAD277DED56F9750419A1BD7FB6A0 +:10F5A00080CBBDF162C13DA0CF1CA7763EC61288BC +:10F5B000057B61DFFD0AEC7E600C6F12D2EDDC9AF8 +:10F5C000C316FE8E33D2BB4A87467BDF981E7BEE86 +:10F5D000FD3177D22A75CFFFA3F0219A1E7BFE9DC5 +:10F5E000BC9721FFC2DB19FF203DEB976FFF16EDA3 +:10F5F0009BE3DBA3703EC7B7FF2DE34EC8BF148566 +:10F60000E7AFC71745615C9477BBDD07F7F98EA7B5 +:10F6100033BF5DF32BDF1462FC0569617A48818595 +:10F62000A5DBFEFB03889F3EB12D4A063F45C3F68E +:10F6300058B4DB1B5E8AC6B897E3AF7C3346EB67F2 +:10F64000FAB9EBA9E7E7FCC7ED64EAB340CFF1CC28 +:10F65000BE6B7879EC0688979BD7D96581F381F2E8 +:10F66000BF7E5F0872E9F8B34CFFA0F6FCA3F0D2AE +:10F67000E1F70575F79B29BC3F071D91DAE17F187B +:10F68000F6E4956087F7840B83C3710A07581785E2 +:10F690004B2DC8D3DEE09138ECD70A8F2FD0BEA80F +:10F6A000DB761EF251182E82C2BEDB7D5601D7CF0B +:10F6B000BE6FFFA610F4A9CF3A16A25E70A6758F92 +:10F6C000FA3FB76EC1DF977557C3BA937E8DEB666D +:10F6D000F47F88EF57463EE849E72FFC16F34FD9F1 +:10F6E000DD38DF3EF2FF82FF6B787F56C073F9335F +:10F6F000E17DD5FF5ABCBFC6F16E77427CD9F15788 +:10F70000BECF209AF59F69DD1DFF4BD71DD28F44D8 +:10F710008F159EB86F23FE00DC5F5FDC8B9EF2FED0 +:10F7200030D52FC1EC10357E474C9C837A8698B833 +:10F730001CF586C584BD83EC954DFC3D3616F7DD82 +:10F740003AD0ED43BFA8E4A95D47F3E64175EEE585 +:10F75000D883DE3E13932756829FA579219D17ED0E +:10F76000A739C9E46C96E19976933FAA10D30F218B +:10F770005D9A7CE91E1857B2E9DFABB519EC8D989C +:10F780001C8B3EAE98EC70C27975B45B82B7DCA975 +:10F790002AAB7FDFF6E5612CFE2386F8306EF36C32 +:10F7A000E1642FD4DB6B463819E1A3C2AD079CB8E6 +:10F7B0003DAABEC72F252E0F001F4A84DA936C3D49 +:10F7C0006887C2DF9182F31A73DC2CF772769E226F +:10F7D00087DEF18738086E6F86DE99954D6897AAA7 +:10F7E00070D6F487EB37C2F96CE1ABE2259A54236B +:10F7F0009EA307DADC3E3AFFC53283FB620A7778C4 +:10F800005F5C85AF0A37231E8240A34961F88753A6 +:10F810007DBC8EB78CB8E09C65BC5812F482BE5C8F +:10F820001C8BFAF23181F8056ABF1D2B4D2E03BBEC +:10F83000E258BA4582745C375D9366BE179DB28606 +:10F84000FE861EE44B49BC2E7F2C3D0FDB975BD31D +:10F8500074EDF642DC36B5DB8FA5155BF13CD4992F +:10F86000A96B3729D6B11ECAF7421C378E3F01ED6E +:10F870009B8B53F375FD4CFAE8D8C337D2742BB782 +:10F88000ABBBC799D11F7FECB5696500C74BE411CD +:10F89000BAFAFB883309888AAEAF02D677996BAC87 +:10F8A0006EDCBA0F77E4811FE237EE52DDF7CB8BC7 +:10F8B0002FD1F5E3B106FD40DE554A95EE7B5DE3C1 +:10F8C000D744EA47C8058DDF11691455DFFD1DBA1D +:10F8D0007E46EDD9AAABEF0E38CB41651C79C8FD49 +:10F8E0002AA46A3CBBA59FD56BA2E9B00FCB4438D4 +:10F8F000F71CFD714D33B8A12F38465C4007E791E6 +:10F90000183C0FEC2DEEFD1B93AF06D67987E873FC +:10F91000411A33605621ACEB486A9B08C7D20F09E5 +:10F92000355714523E1BFBA5AF19F2177DD7218224 +:10F930003DD9BC45C4FB75E3C589B1FF09F2B843A5 +:10F94000C018FF3A9B09FDF09F257414DEAAA13B65 +:10F95000356EC7C8C7FD4795DE5448E9AD255569E2 +:10F96000EF02795AF6FEF56284FBAEC4A97F97AE2A +:10F97000FF284F2B9CD3AB714931E5220B6EBFD8CA +:10F980008CFE9225267734170AB8EF3A2798D701CC +:10F99000BF7FCFE546CCEB44067F504CBF1A11EE3B +:10F9A000D9917B048C6B51C79B51CCE2ED9714AA83 +:10F9B000EF9B3893AE1B06EDED2C5E007C69D06E9C +:10F9C000A209F594AE719FA2FD1B73B9291DEEE14A +:10F9D000398A95D773687E4C607F3ADA59A418E368 +:10F9E0006D16F0389994B6CC077640FB3D668C3B9B +:10F9F0009E314D399943F32B27B2FB819DC565B1EB +:10FA0000C334F0739C1288AC892BF8BE50C6793889 +:10FA1000A420DE0F739C92B09C044730FB8F8FE3D1 +:10FA20009826BF7DAB661C22297361DECB87BC277D +:10FA3000831C731C22FCEF8804F1EFE4413C123E6E +:10FA400080260553AF8B70EFEEE896D1F16087F713 +:10FA50002B75E33DC17E4F8AA17BB2201657C23F72 +:10FA6000788FB6FAED0A5ABE0564232BF7134ACFF6 +:10FA7000CB2D6A39152D2EFECE2196575F55017874 +:10FA800014F5F5876785EA2BD6D470FFCF1456BFDF +:10FA9000DD52D013AE5DE3A2707F8EA17400FAE553 +:10FAA00082FC8294D3C5E93B4EC59E01AE0E06D7BB +:10FAB000EFE82E901CF6277E2CC819405FF7C2F5A0 +:10FAC000006A37AF8EAFD90A741C23FA87C1F7E9F1 +:10FAD0000E25651CA5B74E8B92F13BF48B4463BC9D +:10FAE00057D52D9F3D0857C41C938EBAA866433A3C +:10FAF00025257624F8A59C5FA31C50E3DAC270A4E8 +:10FB0000F44BC75C690AE7412E38C27055E06DE0DE +:10FB1000E51A385B69BE8AC3F5E45333AF4238CD8A +:10FB2000B4225DDCCA79A8259EB4435CDD49E7E6D2 +:10FB30002B811E4E6E3163F06A2714C2BEE9B2B249 +:10FB4000BFE393184C85BFDB326C9F09FD79EF5101 +:10FB5000FA50803EFC2310EE6A7F274BDE4E80FB7E +:10FB6000122713A50480CF9CA005E1769D44FCF0EC +:10FB70005E6A67E2CCF2525ADE7948C6F20EDECFF8 +:10FB80009051CAFB85B88FF3FBBECAF922BC8FDA4D +:10FB90001BBE8CE7F7E00F3E3FA1773A6829B5E23C +:10FBA0007B430DC50B0B605F58109F87F1570D15F8 +:10FBB00002EEBB0D8D5F22DCD5FEA553229135717F +:10FBC000524F80F73049F36EFC290B96D7359E448F +:10FBD000F94DA793097C738C9F6FB69BC90D553463 +:10FBE000ADFB41BCA1CA86E794ADB07FD4911D9610 +:10FBF000051AF9473ABE08C9FBE11477F74EDC1F36 +:10FC00000372B54A704E8147062EEDF05F05E7F7A7 +:10FC100055D1CE2970DE9FE4FEF355707E5F95EEE0 +:10FC20009C02E7FBB94FC74EC5F234E71AF84BA068 +:10FC3000D5EE5C96CF74BE09F90B8797B1BC9DD108 +:10FC400041CCD31953BDB87FDB102E275A637DA753 +:10FC50007B77E4E6C6977570E9512E0A180785810F +:10FC60001A947EFEB56C007B073727807159E9C373 +:10FC70000535FE8B142784E37513B38902E7A98940 +:10FC80002F44B3775A3F0E6400FC6E7E21DA0F7E5C +:10FC9000C8798FBC6A81FD67BA28E7015F8D1F5D57 +:10FCA000933D3C09FC2501CCDFDCB81DE775E74836 +:10FCB000FEF7AC9CDD05E0AFAAE571CEB58678DF36 +:10FCC00039B69DE87F9BB351EF679B4B821F009F26 +:10FCD000D63D71FA38DF8F4C6C1E1287C7743170B5 +:10FCE000BD85CD6BCC70389F49E8C23863C91948CF +:10FCF000AE41F8D6B9D03E498DC17B344BFABF5BDB +:10FD000018E97D988E26BADF53967BB6692BA6D26A +:10FD10000882EB4991821637EDA79ECBE531818FA2 +:10FD20002CDA78C12B385CE3B6B2F36E631CEC15A9 +:10FD3000C3ED3CBE9D9D2BCFAB7EA304F0A2E2F3AE +:10FD4000A258D281F1AA09C4CDF1E206BCA8F00FF5 +:10FD50009F2FD3769991E842853F61F175314C5ED2 +:10FD6000743F178DFA9471FE757CBEEA3ABCC39954 +:10FD70007DD3DBFCBD30FFA4733F7FEF7059F7DE0E +:10FD8000ADBA0E958F43F6E0C2C87A8A3AEFB3A7B0 +:10FD9000B380A52F74A6CA997A52E3423F2C972BC1 +:10FDA0002A9CD579AAF0EAEC25BE556A7C51B71E8B +:10FDB00029508697E31F19CEEE374A1D9760889524 +:10FDC000D4B80DEB9DED7A5479DBDBBA54396B5C1A +:10FDD0009F2A6FD575AA72575DEF382A48501EC208 +:10FDE0005B0F02D80B353AFDB7146E2868CF7DAC97 +:10FDF000B7E8F2E39DBFD3D5BF3875A1AEFC127949 +:10FE000099AEFC32D72A5DFE37EE3F18F4F875BA8A +:10FE1000F22AE5315D794930500E7AF6DF9B2A31BE +:10FE20007EFBC2C3DDAF42DEDFE4C4FC8EA6544CD1 +:10FE30007736C9C8DFBB9B5C98EE6972E3F7FF6851 +:10FE40002AC6F48D2605D340930753A35C98F497F4 +:10FE5000AB24D0D38B03EDA8FF678DA83906F270D1 +:10FE6000AFC9D76CA7703AEF3DA68F139F713FFEC5 +:10FE7000E6833B615F77B27B4D2D5D630539823E42 +:10FE8000E7A0FB9DA2A117C7C42081F36407891CCA +:10FE900067F9C570768E8BF1799436A75AD93BB63F +:10FEA00053A70A188F3895B0FB0934F5D7D0F2491B +:10FEB00012F1C2FE5F6593F0FC89F0FBC253D834A7 +:10FEC000E13D756F14ECDF89FDF07ED264F848E700 +:10FED0002B2A22C6B14E297E1DE3FFAEB1B1BF93DE +:10FEE00075F59E45FFBA93969316EF6876FF417DB0 +:10FEF00027E45DD3D9E80D5FC09D02380F12DCEC1A +:10FF0000EFA4C44B6EADFEAFA6BB8633FD7F52336C +:10FF1000BF1FB08FA01EA7F2235D5F2BCC5FE58BC8 +:10FF20002AA7E41FEC80FD7E5539D4AF3B28235C23 +:10FF300054BE50F940B5FF543E182F3ED10CF54F3A +:10FF40001C62EF929D77ACE6F05FE838FF03F207A2 +:10FF5000233E0080000000001F8B0800000000000E +:10FF6000000BB53A09705455B6E7F5EB2DA4937420 +:10FF7000428084CD0E110C64EB74D210B6E1911066 +:10FF8000DC101BD42F20420332614D62C02F8EFE45 +:10FF9000EAC63018F8D69F8C5A7EFDA2D53082CCA6 +:10FFA00068151948303343B0418D30E348545090C0 +:10FFB000882D322CDF848E2C223354F9CF39F73D33 +:10FFC000BA5F2761B1BE49A54EEEF2EE3DFBF61ECB +:10FFD0005CF95182BE002BAD00E00028EEAC2B4D49 +:10FFE000C27F0B82F560A439FCF911FF0AF7358155 +:10FFF000312B321EF343FDBBB46FB7CF0B4613C09A +:020000021000EC +:100000002EDF0C8641DF22300E05D8EBABE2F17B10 +:10001000BE553C6EF1F919EEF3D532FCABAF8ED77D +:100020003FF4BDC4E38F7C0186ADBEAD3CFF96D3EB +:100030000ED007E0426B693F6F0E409A3A06EBC460 +:10004000344F0242A38033082117422B9852531198 +:10005000CE909C35C0F37E486118F4E2FAB2B4BF8A +:1000600080B137A3EFB122BD0F80FA93DADB08230A +:1000700001EE0741FF03C57FBB2C25D2C09B251590 +:1000800001CC4AEB05EB258087C09F3B0FE18CF24A +:100090003AD35889D627D94F223F24FF17861FB35A +:1000A0009127F433A12B4444E1A4C6371960896D2C +:1000B0008D19860020978E8790BF0690E0C70C8030 +:1000C000C5103403ADBF6E3A1E8AE2F352800CC8ED +:1000D00044FCDF32F17E6D1EE8F9A873E552198AFF +:1000E00053886F0EE6D37208F17916F95167958D32 +:1000F000EEAB33D339B1F72EB1BD67C64137F7B692 +:10010000F2F3D7BB57935305C03CDABF264DA9DBAA +:1001100083E72EEFD536473674C30FBBB1F3EA79C8 +:10012000C887DAE1F8BC1BF14F9864F5229E65B2EE +:100130000D0C28C770400E58F09C45197589742E17 +:100140002A6622E0FCE26699E50146C5988E722B8C +:1001500057E5D60EC1CF482EE5E3CAA700CA6FD136 +:10016000063D3D4B6C2798EF176157B7F456C0B367 +:10017000DFC9895DE9AD1877FB293AAF42E51BCFAE +:10018000235EABDAA46DEF45ED5BEA4C483D198F79 +:10019000FF8C8251C417A4C31944FD397750765A95 +:1001A000A067FD38EB03D6F74B3ED8F61EEAFFD921 +:1001B0002B38D11FEDD159F2927FDCCF273763A1C5 +:1001C00067B593EC09F584EC4893E35AD42140BC1D +:1001D000D79658037EE467D86D37D2FD61295093D6 +:1001E0004872B90CCED5C8EF89BB3E384C7632D1B7 +:1001F0006A0B12DF9088F668B94E6817D3E34F0494 +:100200006A1270FFD836BF4C663BFAA0B7C686E3C9 +:10021000511F2A2869F433EF796492FB765F13F358 +:10022000A1DE57CF30623FB7B29D413ACE65DEB80E +:100230009DC1235603F9B5152A4E35C9506740872D +:1002400075DE36594E403ACE07C149F305071D35D4 +:100250008457619B2227225EEE13DE1AC27B2D8A11 +:100260004141C18D6AF7CB49386F3142D0827EC49B +:10027000926600258AAFA32F046AC80F6A7EEDED4F +:1002800038C1C70957EA65F25B76B377EB46E427D6 +:10029000FC39CEB9D9D115EF1D4E03EBFFB114CF08 +:1002A0000E9687CD31CC934BFAD3BEE515D29F86FF +:1002B00078A7059F83183FADF945ED1C8D6F1A1F78 +:1002C0002BEDE751C6A807ABCEB3DF8BBDB7D2008D +:1002D000DE7AE4BBABD451588DE7B4AF86B9D370A6 +:1002E0005C674298D375FFBBAE9216C2AF4C1ED767 +:1002F000AA105E76C335F5BA72D5777C7F8FEBEAAC +:10030000FD95CD6EFB7C5B64DE5820093F0F46FBFC +:10031000496B449E372AF7F19D3374716BC20F5EAF +:100320005DDC9A889E367ABDD4FAA86E5C667F4200 +:10033000B7FFF6B4D5BAF53B1DEB74EB7767FD5606 +:1003400037BEC7F9B26EFFBDC51B75EBD394DFEBAB +:10035000D6A7CAA0486873B952C044763613EA19C2 +:10036000CE86568673A093A1173589E07C70327CC7 +:10037000043C0CE7B8BCFF22B9844D9D7DC9EE3B1F +:1003800076FE2B87F4A2E31763ED198E485CD6E264 +:10039000F4CDC6E35E66945337FA905860603969CD +:1003A000FEBE47F9C4F8FB7001FA13C473BDA17314 +:1003B000CE5F508FFCBB2DF6CD51FE0435D240F1FF +:1003C00058B3DB9EFC4B99115301B4C7AD06E781CE +:1003D0001574CE47BDA13BFBD2E0D41F90D1A88FAE +:1003E00049B343C621A86F1753144701E2EF7F6654 +:1003F0005CF2C96CD5BFDC8272F8DAC0FE0F164B16 +:1004000081A14857538318E72E4C0E489C07045986 +:100410001E0F43C84474CC05607F3B0F1C0C178033 +:10042000C272C193E3F3D0CF2C6C30BAD6235EF9FD +:10043000299D43C8CE72471F4991F0FE3C742FA4FA +:10044000FFF906A8A53C45C3734181F0074F162864 +:1004500045056E7AAE75FDF3787F67A30136E13905 +:10046000A7463FF14B888AAB2FBB4A46D3BE6D12DD +:1004700028141FFDCD96C0E60CBABFB32FF9756DD9 +:10048000DF1C57E904DA37B900F87CA87F0788CF6A +:10049000D3EC82A730A90FF3009F1B4CFEA7AB9DA6 +:1004A000F959DEF9141FFA839828E67B79FC60C1BC +:1004B000E6196B72981E3FE5632FBBBC1EC6DF8C2E +:1004C0002E8DF07FD512D8C47953D56009F12C7FD9 +:1004D000CD62A0387E04FD2CDC0670D46765F8A5DB +:1004E000CFCEF02B5F1AC3AF7D0E86DFF8B2182E89 +:1004F000FC010940391E2E50E692FC7AA2A3677FC8 +:1005000021E8084B30A3DED6757D86AAD7790D2762 +:100510009E8E273D68929D431185DC465438C4FB6E +:10052000ECAE510139239AAFDE6584475ED3A7CF85 +:100530008D2DA2E78C7609F79F6D3ADF97EC301688 +:10054000BFABFC68360B7EA8F86E4B6E5D4FCF6F6D +:100550006B1C4218A23F00A187244FA93B3A56B317 +:100560001CF30B44BCB9D7D25964B745E8034A150C +:10057000305E54ABF1A24CBE9218427CA6D1B9A316 +:1005800049AF6F3D40F7F9F7C93094F513E67AA209 +:10059000ECFC75950F1ACC6D367B0278FEB6E6CF73 +:1005A000A6DF8D7C983AE64EB71C656F2F10136856 +:1005B000DFE8CBFFF37C2AEFB7D355336163991D96 +:1005C000F73D64DDF33EB1E061FBD765C9389E9B22 +:1005D00026B5109CE7C8989CE22074034CCF82ACEF +:1005E000892DA462539CD3CC94174C24A38AF29FE8 +:1005F000A5564CB274FEBAB76E7C7BDA00DDFE3BCA +:100600001D99BAF5BBB3B275EBDABD539C85BA7DC3 +:1006100064AF9437231D2C77D82C07864AA407177C +:10062000BE58CAF4CF2C22FAC3C83F332600A78B8A +:10063000D7BDF83CB98DC6BD89649FB1F9E9B2E672 +:10064000DFB5288E9EF3D30AF02405A59EF3D29E33 +:10065000F2BA1BCD4FD18F3C477E247FE7FDF61ABF +:10066000C463DBE8CBFD1D48DFDE02CC5BC9FFC500 +:10067000E4AD61356F8DD5A3ABFA2A3984FEEC97D2 +:10068000D9EF6AF96BAC1E013C2DFC8D0A6FD6DEEA +:10069000A77E22E2CF3FC8EE7B47EBB70A0305BA3D +:1006A00078916FC67880F2E9FCBB0C9B68E20AE2A5 +:1006B000A1C92133A2FFF0C8C6F7D38B78DE4FF96A +:1006C0006905C5073CFF0AE51F84EFB23DEFA7A708 +:1006D00046D661E5D7BAFDF094D4A21BAFC9D08F3E +:1006E0009F9DD812FD7C4FFEA87CC3A3662FFAE91C +:1006F000F2172425D08D3FD2F029DB1BA790DF34E1 +:10070000EEB2705D54615740B151F68371A49BF80D +:10071000ACF98799325475E7E72C2E91674DD91BB8 +:1007200007F24F38F708EA0AE1E37F5BC49B2349ED +:100730000A78A2EE497109BC3B92EBFEE37BDCD761 +:10074000F1277012EB3B9285DFCD6B38653050FCA2 +:10075000EB25F425CF1E32A4200C2F8AF703DA53A1 +:10076000E5E204BF211FD787747E6645D1F7DF9E7F +:10077000FCB215E5F685C1A08B3F61F27938CE74E5 +:1007800025CF5C83FFDFBD372E68F809F46462CCA7 +:10079000627F5A22EC7E0EE98DB84701743995BF0D +:1007A00006ED5E85FC04D14FE3D9DB538FBC407965 +:1007B000EC7EE10770D9165B973E145597C206612F +:1007C000BF56FCA53CA60202936D54FF07D1FEE183 +:1007D000E7B3FF092E5BC4CE6FEB6AD79ADD571ED5 +:1007E00012767F6ED7C54FC8CF9FC3F8176DF71A23 +:1007F000DF347BAF7C4966BBD4E6CFEE92EF087462 +:10080000C3E7E1AABE81E2647BADB68B7BABC75F79 +:100810009A4E71AEBA19252475BD478395B5323805 +:10082000A2EED9B6DBB228608BD011D6E26BF3C54D +:1008300094893902AEA6F80B75AAFF11790DC65539 +:10084000532AC5D5699273338243CDFD4A887F8789 +:1008500024083A5C7CC4FD56C4EF3E711CCDDB28F5 +:100860003F83B42C23DD335D95EB7D6A9FE881E601 +:10087000078692BFFFAC61FE21059756B83299CE2C +:1008800007C1CFF9E1A164CFA01588E7D41AA1E789 +:1008900087923BDBA9AF74687CBC5423F1F96BA24F +:1008A000F3BF4326CFA02AA64BED2F2923E41FE355 +:1008B0006FA2EE55FD22CAD32F893A8DEDC098FE66 +:1008C0002CF70B1643A045C17B2B9C41CE5397823E +:1008D000A8EF63F3F48A71DF9A293EC4D695139B7F +:1008E000F61C96F2BAE947C4E8EDF5FA0FB1F56CDB +:1008F0004F79FEC514CF8BAEA83E606CBE7E352FFF +:10090000D5F2AACDF1814D88CFBBE3FFFBEC521CA1 +:10091000AFDC1C6FA7FAF9CC6B163FF9E7339B2CC1 +:100920000109D7CFA474B651DD70667BAE134F803A +:100930007283E3CDB728CEFFC1C47A01E014F6710B +:10094000554F1F3F46FEAE7A738204945F7BC5BA53 +:1009500056CBC96F24709EB078477AC02245E20C0E +:10096000D98703538BD3AFC62994F49FD9775F12ED +:10097000F5A1DA0D7F1CCC7D2DF9A9634FE0734BF7 +:10098000B724B8289F801C60B92DDA347C23E5C7D2 +:100990002F9ABC4D447FE91BF7F4CBA0F33FED0346 +:1009A000444F78D78EBE941F45F2F6EEF3BD73BB6D +:1009B00032932027C227AD2F58FBFA6A0FC93D5E3C +:1009C00072F0BC11AA9401A4174DD380CE75C992C0 +:1009D0004276D9B92E9EF3D458BD3BE01275CA3287 +:1009E000AD8FD01BAC69643F5E603E84D7656F5AA3 +:1009F0008F7C3AE54A51E375E7B0E9B9D1FAD956A7 +:100A000041F5DFB90D16EE6FB4C7E9F3060D1E759B +:100A100025F3FE72EB055D3FA162D565FD38071435 +:100A2000F23BAE1A47E1A30857A8FCEF18E139E6FC +:100A3000423C97D4FF76E787CC970DFFFE05DDBBE0 +:100A4000CF26FA2A1F0AFEC5D603E556D1BF00D825 +:100A5000C8F76BF3A75EFD3C8FF4F05463F6309259 +:100A6000E37CB9F5E42B48E7D984D6634F22DCBE9A +:100A7000EF13964B2CBEB17D987649627A97111D83 +:100A8000385FE6F65C2039A320B88E9BBF3E97F90D +:100A90005726E724911CC367BAAF57343CB5F335EA +:100AA000FCB4F3B57D52A190578BDAE7EB30B79EDB +:100AB00025F976ECCC96A8CF77753EA5352F394A27 +:100AC0005F7EAEFEFA2CB5CF71D8B0FA3133EA634F +:100AD0007BFDF3266FB4DFBBC9BEFAD57C5001871E +:100AE000BDAF08251CB79038238EC76B6332061C38 +:100AF0008F53D193081FB4CBF12A8425DE34EE9BAB +:100B0000D37908E320C0E39A894E07C1099287FB95 +:100B1000175ADD3019AA06121D066B88FB7D6BA8DB +:100B2000CF8879CB03C96BEFC9C0FBD6F481B594EC +:100B3000CFAC3109BBF0CF8BE77A4EE3931667C099 +:100B40009EA38B2F6BECE030E239338C506B4A1153 +:100B5000FB6E413E1FDA37FF7DEA9F7E6EACEA43B3 +:100B6000F71EB1BD902B1928CF0B2450CDF8C52707 +:100B70007F70FF1DF71E05653CE515F77F6065BFBB +:100B80001FDB9F58085E1E9743C874019FFB6AF4E1 +:100B90003F37EF85085D5F8DF9BE91EA8487929FAC +:100BA00076D3F3FE12C8A2B874292E318FE85965A6 +:100BB00015F0F15E899B089EB1DBFCD45FBD143754 +:100BC0003840F1F415C97B6F611F7E8EEB58FFB181 +:100BD000F800C5BBC7656F05F79393CD20E1FE70A4 +:100BE0001F952F1DC07C099BD4FDDF39785C54EA2A +:100BF000E27E235C72B05F1E1B13778AB20DA23EA9 +:100C0000FB51EC1FDF69D4C59DA27CB59FF32F0774 +:100C1000E7A9137E305E332E75148A7AB7A8B7A180 +:100C2000AABB7C718DBA5E034159F47944BE30F69B +:100C3000AA7E2932C9B1421D57505C43BD0A275ACA +:100C4000FD32D23B7697D0B3B1C6E01E82E8656133 +:100C500015E5174D18F7343CD0AF405A36EBC318A2 +:100C60004D4FF1ACD9B86FAD54C5758C95F21A845F +:100C7000EBA556C6E317D0C95051E3790938194E90 +:100C8000020F43D4538677401DC3BBA09EE1146876 +:100C900015F17F44B086E31A3C65E7F71877961B99 +:100CA00028EF287AB0FBFA61CB75F9808637F2E637 +:100CB000F93019D0FE32BBE1C7C02CF623B1FC8855 +:100CC000B5D3F11092D94EC9416452FFC0C1F65A52 +:100CD0000A0A8FCB6E900FC521AF91FB37B1FC286C +:100CE000ED5E2FB6A9FC5840BAD62722A713850E71 +:100CF0001E6BF242FB4AA33C34568EDA7C517CC90F +:100D00007907BAE2BF157E39D388F1ABA8B0644544 +:100D1000268EBFDCD121C6634B760CC1F15785E12D +:100D200099C674D2EF92429313AB18A973E6241CB0 +:100D30007BC93EF309A21D923FF38AFA78A59AC7B0 +:100D400078573FE6B4A3BD7807D99C44A71593FD17 +:100D500038E4A39C29DE1F0EBE23B8D784FBBE3225 +:100D6000795BC87E975B83890EE4FFCAD565FDC8B1 +:100D7000753E6316FB2D16D17FD5E8C3797F1C8E97 +:100D8000B76FCF5E210DB93E1E78FE413ADFBB7AC8 +:100D9000A89FECD7DB283985644BFACD401EB6B747 +:100DA0009A80FAA6DA7D4F8DF01EA1FDE070B2FFA9 +:100DB0001EA0E639EDDBB3B3494E270AD5F7C3A928 +:100DC0001985C4C7A3233C27687F3841E8DB098A1B +:100DD000E5EE9EA1AD48395ED8CD7CF81F88003E77 +:100DE0007FB1D07B9AD62BE3AF70DC3F5BF0E9DAC2 +:100DF0005046446F2514DA6CA4BF46818099E3C342 +:100E000038FBD53C95FCDD423C07F951E4F1D69026 +:100E10008B1B35BB7324F9553CF73C9F6B0E0D2E95 +:100E2000C0E75EB8EF9859E8DD40A177AA5F6ADEB7 +:100E3000BDFFC90162E881283BABDC7DF9FBA3C89B +:100E4000BFCA7336276D8FD8D7CB2BB8DE049BCEA5 +:100E50008F687637A6C9C2F9F6D85DC317D2BEF13E +:100E60009FB665125D13DA42FC3E2CDCFCF9008172 +:100E70008756875C927E4A3C3EA5C6895356111719 +:100E8000E8FD2ED77B8DE2FD6EB5DAE7AC6E9602FB +:100E90007EF63FA27E5EA4D2B77C7F630BF54F1631 +:100EA0006D583085F52820EA0A07FE925F5872587F +:100EB000D4CD4BB7EAEB8D4AAA9B693F04CDA40F72 +:100EC000CBEB63D6379472DD5C19EDFFBBA99B8732 +:100ED00015A9FDB1413088E992672779BBF187B147 +:100EE00075710528B9459CF77A64BADF6DECBEFFD1 +:100EF000909427E9FAB5E5EADDC4271BF3C5CCF5E4 +:100F000044F5AB2B9C761AAB76BB1175A798F2ED26 +:100F1000DA03DC5FD69ED3EC7871ADC475076CE85C +:100F2000CD3A98BFC5A210BDF95BFA711D82F512CA +:100F3000E7871BB7586A695CF3EB5E7E399FFAD08E +:100F40009DFDA90F531387F9A6E8E783E4E23E0C61 +:100F5000F745E617A97E5FCD032058A0ABE76BD419 +:100F6000F85F9D30AC1F56CE917DFBD275F5498D53 +:100F70009A6F17119E94376EED2FD6E3041D7B3EBA +:100F8000FEB778CA7B1B8D9E78EA6B9F3B3884EB5B +:100F9000989EF8EEC63004D778DFE8FE7C4AE6B5C6 +:100FA000E456F49251F04BD5DB3FFB14F8C6149194 +:100FB0008B465F99FC56A999FA228F809DFA24D519 +:100FC000FB7F5763A5BA701D7007E21C087D3E7752 +:100FD000DAC0EFCF4742D66FC6E1D87DDAE80CE041 +:100FE000F30DAA5FA4F7C88E283DB3A8FDDF3847EC +:100FF0002F7044D5D1F15929BA7182B3BFEEB9A48B +:10100000E221BA75E4F7263A1FFC4A6BCEC848DEE7 +:101010009BAC8CD03DF74CE2E47D6CF7ADBFE4BEF9 +:1010200054EF3B5C7A7CE45D32F903B820F2A562B0 +:10103000FC257B1B05FE1A92C798767D1E551CAABF +:10104000E3BA31EEA051D707B05CA72FF59C665FDD +:101050000361A0F01BB1FCD67F4751BD5FE67CAFBA +:101060007A1026AA19DDF1FB561DBF357BD4F8DEB8 +:10107000C7A3E77BBF197A7EA77BF5FC1EB048CFDC +:10108000EF41557A7EDFB24ACFD70CBF9E8F99B51C +:101090006374FB87D695E8C6B7BD74976EFFF0C042 +:1010A00074DD387BEB2CDDFEDCFAF9BAF5FCA62505 +:1010B0003724FF8260B56E5FACFC0BF7FDEA9AF255 +:1010C000F7E3AF903FB03C8A511E41C7FF9F1E7CA3 +:1010D0001AAB0737E867DF249B15DF2584FCA407DC +:1010E000C5F1AC2753E385DFF968DFB9830A8E0FBA +:1010F000380A4D699467A9F98347F5435A3D135B54 +:1011000037DE5B2CC5BCB78FD3BDB7BFDEF771EE42 +:10111000D6A06E5C7010F8FB17D761E7BB04DD2723 +:10112000146E778D3C5DF52EC1D117386C77A957B9 +:10113000B5EFEC62EB2D701E64BF3F5B7B2F434627 +:1011400031B26B7F52ABC7B43A37B6FED5EADEAEEA +:10115000759AC863BAD61BCE3423E7D15ECEAB3FB7 +:1011600090BCDCE77C65B8D7E67653118075B28118 +:10117000EAE4508D60A602F41E3A4CFF7312F2ECC2 +:101180002CEAC7879381FBE7CAEADA597E1BA36F73 +:101190000F8D14ED23FAB9D5EDEDEB46B91E97ECA2 +:1011A0006B0BF1D98FC67C3B98F29174B7F85ECC8B +:1011B0002223A7302EF59BAD00CD5F4C51FAD3FD15 +:1011C0005ABFA427BD89FDCEA8C1176468B43BF9F6 +:1011D0003BA4D8FE62C8E0E0FCD4FF2B89BFDFF956 +:1011E00096901B1DC963CED59A388F01B59E7F5846 +:1011F000E5BFD6F798ADD2731C8F588471F9E1A67C +:101200000F582E4BD3DAD57E4915E7E30B06DA5C8F +:10121000FC5D9B52E8147D32AD0F3240BE99BCEBB1 +:101220007AF42F4D3BA3EB43C15BBD6FE87D79841E +:101230006E71FEF175A29F797CDD20EE9F47CE3F57 +:10124000CBFDA887AB3ED6D9C7DC554774F630CF67 +:10125000FFB56E3D94DA69A2FE636867FAE4879091 +:101260007F1D8D9691240FD48307DD51FDB7D0BA31 +:10127000EC4974EFF5E9FC96F168F3B5B27C353AC8 +:101280008FF90EF338E40BC57C6726E8D4FA1C1AF4 +:1012900034EF852C23BD4F947A39A9AFDC53FF433B +:1012A000B3B3F3EE21AC9F970C8E93A24F54358AC3 +:1012B000F2BFB6897D4B08EFB64166A380C3C43840 +:1012C000BDD82AC693EF201836D96AA92FD226890D +:1012D000EF82664BCA6BF3F0DEC7867B57917E5771 +:1012E0002EE9CC23FBABCC0FCD91F0FCB37DBC4FF2 +:1012F000127F242C2FD253980EFE7EECB4C19F2770 +:10130000A1A9BCDD787416D58DA77BF9CF5286B222 +:10131000CDFDF92CAA1B4F9B853DBED3189CE5A79C +:10132000FA090F233AFD7F92447FCA16324FC373E6 +:1013300092FA789FA1F3E9BB307ABF47F3A49F5A92 +:10134000BF346C12796258CD17FFCB2DF2D9DFB8BC +:10135000C5FB3F0DFE9EDEC1E0DF3B04D95F3F3B96 +:101360008CFAE9E7365880F25BBC5F311445BE5F0A +:10137000E98BB4501EFBBE59D499AE772C41F25381 +:101380005A5F75933B83CF49CD14FDD2D4FF44BF40 +:101390004576186A1D3C2D210ADF83C07DEC0EEADC +:1013A0004747F5B137B9453F141E117EAF63DD00E5 +:1013B000EEB72FDF7FFC18F9AF32B7770BD13DDFE7 +:1013C000E018497E6F79E21EEE9B35B91D7C2FE255 +:1013D000CBF4A21F5A43725A6E0D719FED7A7DF5C0 +:1013E0009EE8EF58D8FA620EF7911D79A437DABD5E +:1013F0008847933BAAFFADE11139E7DA76A0F5877C +:10140000B5F1A9579F19A6F6F7E77ABA89AF07DCB5 +:1014100022BF6F3375DF8FFF5F559E5DE4731B0046 +:10142000F5FF2DBD30F6236C233ED1FBDF99480F2D +:10143000F737940292EFF2E93627F1593B1FCFF1CB +:10144000FEF11AF7748CF07C467ABFA44AF4EFB52B +:10145000F5B024E4EA5F27FAA9CB771F39F624DE3A +:10146000B2F88DDC428A07DAF3B17C46FE0EE3EF78 +:10147000E864F1FE0BF9FB0D9D1FDBB7FFA97C0DA6 +:101480000F12EF69C31B2F0F76E0F3CBE9BBB63C1D +:10149000D20FD1FF82067D5F0BF9E5A7FE46D7F795 +:1014A0005AC0EFC72C6A3CB168CF0F34EA9E7F3335 +:1014B000C1F34FC27FA7EA37707FC080F737A8FE1D +:1014C000A941ADBB63FB2F0DADA26FDA9066E63C80 +:1014D0009AF21F5AD7F29F951F8BBEE9CA0C9167EB +:1014E000139E2467E9700BE70B57FBE212C67BE4FF +:1014F0006382D99B309274D2BB82E3997C0BCA99E8 +:10150000DE87FCF52EB58F20E2A35B8D876E3A87D0 +:10151000F0CA49E23859A4DE8BF505F7EF46835748 +:10152000CD1FD4FEDBBA16EE3FFC1F5946A94AB0C8 +:1015300030000000000000001F8B080000000000C9 +:10154000000BFB51CFC0F0030947B3A3F20FA3F187 +:10155000E7B0A1F233B9D0D4B3A0F283D0F4A3E3BF +:10156000762606064626FC6AF061116606061920F4 +:101570005601621D66F2CD0161235106866209069D +:10158000062E20FD5F9C81C10BC82E01625F20BF2B +:101590001D886700B11450FC029096156360782E88 +:1015A0000AD1670D647F1323CF4E4B5ECADC3C8AA1 +:1015B00029C3E6B2A87C013506064F750686891A4E +:1015C00010BE1E92FC0AA098A01A847D481E98DEC8 +:1015D000807C5559ECE61E06CAEB02E5776AE0B757 +:1015E0007FBB0E2ADFC10C959F8B26DFE882CAD70E +:1015F0007043E5EBB84368003560D6A4D80300001B +:1016000000000000000000001F8B08000000000028 +:10161000000BCD7D0B7C54D599F8B98F99B93399CE +:1016200099DC241398BCE02604881A6012121E8AE2 +:10163000781302461BC304D1E22EDB1D686B23CF57 +:1016400001ADC6C736139290204482765D162D1DDB +:101650007C15156B4AB14BBB6A27402B55B70E164C +:101660001FDDDA6E60FDB76A955F50A9F868F99FD3 +:10167000EF3BE74EEEBD998447BBFBDBF8B839F78B +:101680009EC777BEF3BDCF774E9CA484A8E30939EB +:10169000033F5710F21AA13FB9434F427A09A98676 +:1016A000E7801C9E02CF187FCF9E81A57D02ED02B0 +:1016B0008A4932839022C27E8A5A36AE13A71232EA +:1016C00096847E31B99896079635103F2DBF75D513 +:1016D000BBF0DCB8B8B67EBE4648DE92BE2357D219 +:1016E00067201C1722E584DC474442F2A1BFD25890 +:1016F0008D97900EE8EC5242C6C4F2F45839147437 +:101700005A20E49B0A1F88889A4CCB3EFC75681EC1 +:10171000C693102749946145E18C6B787B7B7DE310 +:10172000E98376469D62F8FF7A02F33B5B3B720BDE +:101730001B2F46FF3943F15230343EF693D76C2AC3 +:1017400013C08FF5BB9EC2FBBAFF95F1F249A55BB2 +:10175000ABA2F36D10D538D4277D59322D0756C969 +:101760002421D0EF55BD82433BFBBA6C24A4BECFED +:101770008BF8159A7C43F05D47049CCFB83BDEDEC6 +:10178000D51520E4D4526F08E9432524277BF87C43 +:10179000FEB9959084CB545E5C2B4470BCD02F4A2C +:1017A00069FBD86231F428C0D3B0280BDE1BF56E7C +:1017B000E3E30CA70FA2C9148F32A70FB941D4DD00 +:1017C00053FF7AFA902F903E726F31B523E7BF5ED8 +:1017D00088F7EA73A78FBF763C635D87F3551BC21A +:1017E00031EE8E5237A1EB7F6FFDA2CC489A7A235F +:1017F000AF6B25F27BA081E8F134ED36C17AE23C93 +:10180000631679834FBA3E526A796FB6AC973476D5 +:10181000C6925DA3E0430A58E76BF4EB6C91B4B752 +:101820007368515645E84FE6FD6D5497C708D02DB3 +:10183000D036C587D45B9120943F4890841EE51034 +:1018400088B4EC54F5F8DD0294E2B82E067C4AA97F +:101850006819CF51E8B1AC07591213CCF03B5B9C2F +:1018600008870C6CC2E55D18851B831B8638330125 +:10187000CA775AD65FF692849BCAD54DA595C4BC4B +:101880000E069D0A8241A7779E9B5CB18FB7D80A4E +:10189000E739B7F3CADAEF8D3625A3B593C9EF0D53 +:1018A0003C51E4FD0A7E31AD7B9783EC17A611D243 +:1018B0005EB831066FBBE07FB3913E416891AEC226 +:1018C0004A15E889EC166480D36D9047301BEBED28 +:1018D000221AD2534CB895403DC91B463C19DF47EC +:1018E000868BD35D4CEF2FA5FD5EC3BBBD86EB336E +:1018F00052E5787BC080BB04E73154A6F3F8E0766C +:10190000FA3F4A1FB10A21FEA830FC7B03E8432AB4 +:101910008F1AE0BD499EB804AB3C6BE0DF0E3EF38E +:10192000C6A4E9941E93218980B8DAF08C4BAFA34A +:10193000FD1FB95C88BB040E2FADDFC8E17C59CF19 +:101940002902FA4CD6B9907E1BAFFC2400E47B62DE +:10195000FFAFE474FCDA38C7310407FD6FAD797E60 +:10196000F4BF313006F2651DD29101D7EA4A09E190 +:1019700048CE11E230CEA1DFFEE19ECB289C2F574E +:1019800009219786F0FA081D2FA97F14184D4E10D3 +:10199000637C8DA8804FFBF8A9F550424B802F9BAC +:1019A00055A776371D6FA5143A0C7A8C8C65FAA171 +:1019B000599D5407EB23098C3EE60979D8AEDDBB6F +:1019C000610CAEBBB434ADBC6AA68A42AD84EF5B99 +:1019D000268D0A67DC313860A2EB96B78AEF39644E +:1019E00082738AE00BFC3E83FE3293CC8475FED07A +:1019F000BB28334146EEEFBD56A54D7610F249ABFC +:101A000076CF21C7F0EF2B2512ED2B1FFEFE6A418A +:101A1000E1F88839C13E33E69D9AA73780F4BD12BC +:101A2000C42F25F595BBDD6DB259FED8E691C2EF06 +:101A300005B65302EB63F91AF05B64A100FDC8F42C +:101A40009F1943FCB8724F13E33B1BBC9D81BF0D34 +:101A5000BC67E3E30FBD1B3682BDDAEE60F4D291C2 +:101A60002B863690E1F462AC8781C7735D8F2D823F +:101A70001BF9C3A0A36671E9A8EB7E363ABA15E854 +:101A8000E892FF793ABA0FE8A8FAFF241D6DFFBF6C +:101A9000484743E52BD15E58C8FBEA1FF8EF6F8338 +:101AA0007C7E5D9750EEBD3E87C9FFD7234C2E2626 +:101AB00049A4A71AF4C15109E554526FF721BCD4C7 +:101AC0002486791C81DFE8F847B9BDF46AAB42127D +:101AD0009371FE458BE8F757AFFAA410F4D7AB74B7 +:101AE0006DC1FE266450D769FB5752656A8043D9A1 +:101AF000CDCA836DA763609F270556FE69DB693DEC +:101B000086E36DD97825C5E742F895C271DD1C21C1 +:101B1000AD1DF6A2E06478A92316BD4AD7E545813C +:101B2000D28BB298DAA188BF3041FFB094DA09268F +:101B3000FBA2051418C8E57A17EA3F7BFFAFF079DE +:101B4000DAEDB8EBE6D438405FB8169F940728FC6E +:101B50000B170B0E660FC5886A825BD4051DF44017 +:101B6000788EEB21D07F619938D434F358A8BB2C00 +:101B700076D749AEC7285E9630BF452B6A9A325455 +:101B8000FFA4A17F6DF319892E8C7918E5C5734EDA +:101B90001ECAA1709106213451033AD58ABEE233A0 +:101BA000F79F61D8373EC0DBEB4BAECD647410417C +:101BB000BD6AD0D32F8E7DC33100EFEB72502E5D06 +:101BC00017962CF6E4B5F51996795D3FE7DA51EDF5 +:101BD000701231E1C144F7FE0282744AFE8BDA29A9 +:101BE000944E63B58311B45B8E0B5A3B2D67CE6D5B +:101BF000190FFDDE2966637D616ECBE401B4B71673 +:101C000020FD67F03E339DD13F94805C9D289287F4 +:101C100034B04747F70B3A016F9387CA8E402426AA +:101C200050BC6931B5521A05DF715DAC4F47AF1337 +:101C300044B66E9DB1456A290074C82A37B2EAA23B +:101C400068FF19F5291D4F107361DC18BE4FD17163 +:101C5000379D176DE761B608C9BC78512619651E16 +:101C60001DB6F5A7E25F4F27675772F8C87ED6BF4B +:101C7000219332B369FF69EA1BCF2EDEFFE990485A +:101C80009200A71C56001E52564BCCFD10BD02CB35 +:101C90004E5E7405C34A31C5A7AB5C846990CEF231 +:101CA000877459033CC470BD37D3B52D34F1E5E6D4 +:101CB0003F4BE8E7AF144BDA406E6CEEBF89681417 +:101CC0001F9E609C6079CA8D0AE0693375B29230BC +:101CD000BEDC47008E8C42FA3B1D274325718DF6F2 +:101CE000276B7D099196E57A12D2E9279F1A123C5B +:101CF000D4FF3E102C6993E9FB8EA504E52301AFC8 +:101D0000DC443F1DC1577509E867090901C01D8101 +:101D1000E538CF8DE5CBBB8BE9FB530D32C60FC841 +:101D200017145EC3AFA77E86A78CE830DEE63C12B0 +:101D3000F7A21DAC237E9D2A5B3F6D7B29494CA7F2 +:101D4000DFB366F4C3F8B17F22A1896C48946B328B +:101D5000972744A6F407E3B7A8A1BBD3D09F42229C +:101D60003789D5A67556C3E8C7DAF196E924570333 +:101D70007E3B2A281FA4917BB78A22D2413CB468BB +:101D800061499A71EE1435944F46593BED44F8473A +:101D9000AA3F544F26891CE85A17002F241CC0F96B +:101DA0006593D48F0EE51C3EDF31248AF582B37A29 +:101DB000FB81DFF2F5BE1AC0C53FFBAE3F82EB46AA +:101DC0001E54C18EA5D0969EC9199217A073607E2D +:101DD0001F8644F43B7C6242D569073E773288CE49 +:101DE000AF46302E97094D28C077B72A1D6097F867 +:101DF000494880EFBE901C33DBF59984962DF11491 +:101E000072B474069216E30FA2F603EBA865D169CB +:101E100000CC7D7EFDE7E0376DF145D00FFBC4EDD2 +:101E20009F0A83DDE6F13F04CF4FDCE3E2E89F85C4 +:101E300098BFA5D07F40DE65CE922DFE4D966E2DCB +:101E4000E7D8FCB0059217E799750DE1FE95DE30F5 +:101E500071CC105C14A226A0976D753201FFDFEBE8 +:101E600065F018F0E54877CD0478291CC7010E8A83 +:101E70001684E314F922014BEC2F23183FA5701DA3 +:101E8000B7C175DC06D771335C2D0A9BAFDD5E8C64 +:101E9000D592B22805EE3991FB1FD46E02BBF11426 +:101EA000795FAF07C2095F8D7AD6AFB2365E2589FA +:101EB000C10A95A8480776BB91AED38716FF6B166B +:101EC0002F6B4480795038ADDF4921D20B96259293 +:101ED0008A0B2F9F65E04BFBF26F28FFDD74D84122 +:101EE00080BF281F4BF0DDC1BFDEC4E3C3CBC1BF41 +:101EF000A6F8FB1A09FB01BE0F888871A80FC8ABB2 +:101F0000FEE926397942E4F6092CB1998F4928086F +:101F1000725CF66E4C4A7E4483416FC2195CC710F6 +:101F200093F35E467731A2B4A13EEC66FEA7114F53 +:101F3000FD7AAFD51FFEC6766BF946B2680CC44B6E +:101F40006FFCB683C469BF3799FD7BBA4EAF892A4F +:101F5000C2F70D12DD0876499783D91BCB55224372 +:101F6000FC73F5BF7D67C6323A9F53200FAAC17E2E +:101F7000A7E09BF4C88A40DCA9970F9F5FBB106A5B +:101F8000BC4C18797E5D8E6423F8DFB11E07DA99A8 +:101F9000C41E07DD27611CD4D40EE1FD6AB7757E2F +:101FA000679BBF7DBE84DC8BF35DB17B19DAE723D1 +:101FB000CDC7B99BDA9B69F49D57122C711F83AF73 +:101FC0000D7AB7F37795A4B1B80E558368AFFC2EA0 +:101FD00023DE8EEB1B9D09EB7BB6F6B3A17DEE8570 +:101FE000B79FFB578E3FEF2CED572B830B60BD3710 +:101FF000057AC3C09F461C6B0D89E905F457C7B32A +:10200000EB6260BAA5EA05CFB15E21AD279D43BD65 +:10201000D2D1FB3BC1ED9217F63CEC043BF5832794 +:102020008E35821DB0F2DF25A2507A38B1C7471233 +:1020300068AFC49D60DFACA07417C77262C6B526D6 +:102040007B985234AEC3CAA77D6847ACD8EB8A37B9 +:10205000D0F62B7EF4DF5309C5C3890D833F2F00D3 +:102060007A7E426071D7D8C0D46BE9FB1532F9C7CC +:10207000701A3A5A26317E7AFFC7194BC04E147631 +:10208000F77F05FBEDFBB2C365D2C74B24078E4B30 +:10209000EBA11F117B5C884F14187C667FC088778A +:1020A000BFFFB8C0E0DBEF88BB01BEDDBB9C115AAF +:1020B0006FEDEE9348D7F39E7ECA0F7858BBDF6A68 +:1020C000A7AFDD2D255C53F1790C9EA041851980C9 +:1020D0004FC6CF6BF6AD46BDB1A66FF349E0E7B58D +:1020E000FB1D16F94FF1124A005EDF90420D50FEC3 +:1020F000E1F7FC1A45D57BC947FD8057DAEF322757 +:10210000A5AB85B3ACEDA0FFD3D9C3FBA39E21FA49 +:10211000CD6BFB36B1F1F65DF30790B76B09D35386 +:10212000063FBF07BFE40DD7339B246B7CEB1479CC +:102130007906FA81BB73D2FACF865E31F87AE5531D +:10214000A776C6E8F8EFEFFDE3CE189DC7AABF7CDF +:10215000B4F34EF0979E77AB20AFD63EF19A9F989E +:10216000F0FF88C4F6034E3CFEBDC776503E39F101 +:102170006B17DA81279EFBC3388DCEFFC40F3E1D3F +:102180000376EA2DCFCD1F0BF8B8E599796347B3F5 +:10219000D7816EE32EF3FAC6B17F6DBF009B20841A +:1021A0003CCB9FB6753AB84F4A4088E083375D71A3 +:1021B00017C5CF5AFAAEA512D66D35EA2B28DF45E2 +:1021C000F1BD664FD749696A3ABCC70AC4203C13BF +:1021D000052408EB7EEDC2CBABE0E908694027643B +:1021E00010F584BDDDDAA3747DA78DBC9ED49E70EE +:1021F00002FED7EED9C4C6EDA3EBE91FBE9E1FC0F9 +:102200002FB387AFE741C91A673A45567D77077CF8 +:10221000DCC7FCCE91D673F533D78DEADF19F2E136 +:102220006C786E16185C5B25FD5712F0E3DE271FF5 +:10223000DB1160EBDC401173E2A953E36093F71DFF +:10224000C7E057404E0E3EE752C1AE5EF1DC1BC800 +:1022500077279E39E2D4707F9A7805AA274F90D4C9 +:102260004F12F4E61A8115D63EE24BB8FC43EBB5AB +:1022700026DE54AFF9F1FD317C1F67FCB026DEBFCE +:102280005848B37E5EB984E9A7782EE265B59674A6 +:10229000AA5EEBBA0AB3603D8F2D00FA1B693D8D33 +:1022A000F9AB30FF99A6757D84F1F148FC7A62970D +:1022B0004B163287AFF3096E57AC8D0B6FA45B776B +:1022C0004236B0F8DE08716FE369A70BA76CE573BF +:1022D000A3BD31FFB3F1F9D9E7757E783BC5F5B5FC +:1022E0001D7FEF7F915E0F94C802D75BBDF5F92685 +:1022F0007DE776503D560C76673456503C04EFC669 +:102300003E09E5FBFBBB25B4F7ED7262CD087E7D8F +:10231000C818677FFF549067EF1FF831A74746EF53 +:102320006BF61C73C6B85E889BF502F497663D2E6B +:10233000E5FDAD7D367D7F6BF79C4CDBDF7BB2FE30 +:102340006580FFBDA483C46817EFF54969E324A540 +:10235000B2C362676DF4CD783393B693FC1E0DE67D +:10236000DDBE417F2306F6C8AB0E82F6A31C7AC7FA +:1023700045BFB7FB3CB8DFD2EEBF916826FDDD61FB +:10238000C3931C0CA31F2D07C2556C2F346EF1672D +:102390001DAA68819BC8B142D8E7FC65F11F64E8BB +:1023A00017E2699A292EF48A4C3A73687FAFE842A3 +:1023B000A88DA4896BD9FA0FCF918866A6337DBC0E +:1023C000688E2FFA0FDC8E718D16124D40BC891469 +:1023D00092BE474DFD3ED8AAB1B86B78BC688EFF5F +:1023E000B9A251DD45E128BC452D01FF6DA4F18B5B +:1023F000A2D67D5F63FCF53C1E41763FF1C413B469 +:102400003C1EBE616A45BCCD09F13795D937F3B89A +:102410003CFC29B79F0F08E1436087E977C56490CA +:102420007782D626839D51FF454C5E6EA2C77AED1A +:10243000641EE8D5EFFE595A928E4EF773BA6AFBC6 +:10244000A71FE541FCEE01F76D85CC990D237C8536 +:102450007C9E878ABEE185EFFDAB6FF44EA6F8291E +:10246000084A04E2350581655B2A60FE47A5905B5A +:102470001BDEBFF1DCC9E37A0FB5AA28FF1F690D87 +:1024800062F9318ED7DDAD65F87CA23584DFF7B413 +:10249000CEC2725F6B3D3EF7B686F1BDFF8E17056B +:1024A000A03BF22DD207F19A7DAD4BF0FB8F5A2362 +:1024B000F87C94CFA71EF0E2B5CC1FE331FB3BAE16 +:1024C000D800F118038F76BCD7D1A962FF9AA0017A +:1024D0009DDF2E33F962C7EF38574208D3724B9411 +:1024E000E52BECE4716363BEFF2A337B731F87E740 +:1024F000C7EEC8F765D86FAA2F2DE7F1F110C8EF26 +:102500009D42786B05E59F178A6606CD72B8C8179D +:10251000D9279BE8675C378BF7EC9099BC1A4F4E34 +:10252000F66752BCEB5F100DE8CE98EF811AAD1044 +:10253000E4E40141C0F5D6BF10499989EE8CFEBE96 +:10254000238B7C7F23BDDC1EA263260FB2AF92CB10 +:10255000C0AF3D453C2189C2DB9947F681DFD209F6 +:10256000740976F26F33304E6CF8375BF87A67BBDC +:10257000D9F7536FF9E2207F46F27B36F2FA1F72E9 +:10258000B856CBE15FC9B8AF1C1758BE4302E398F9 +:10259000056C2A944E976EA56B45EEB9F4BD3721B4 +:1025A0003EF8C1336E0DE0EAA93AEE37E391AC9202 +:1025B000DF37EFEB18EFF34F17203EFF1F891C3377 +:1025C000E339BF79D009ED3B056D5B1DCCEB3509D7 +:1025D000F9AF53885F84F13399A05FD07953300EFF +:1025E00072CF68E70B59F93BDB1D5EB20CE6DDEC00 +:1025F0000CC5D2C8A7DF666816F9E00A5ADB0741A6 +:102600006756B3B246E9B382303911927509FCB40A +:102610006A12C1E74CA2E133CF11F90CE6319D8477 +:1026200035807343C6B8CBD8FEC1FF18DE14C7FF90 +:1026300041BC19F41ABCB46C1BE41F903B44DC6F22 +:1026400069874F263A5FE810387E1594E7053CAE5F +:102650004FE5FF0B4501EC86C549D40C9483057CFE +:10266000C3A065E024C67783E3088FBBC731DF6969 +:10267000C72A11FDF507DE12E290EC726A55C99186 +:1026800049B47D0DE573589FECAB4A33CDFB0C0686 +:102690007F3CA08433D551E2FC065F18E57F19FF2B +:1026A000BC007268DBF8E7FB413FE40F08211063D0 +:1026B000F9DEE864904735BF7B3C0FBEFFC6139937 +:1026C000635E9F1DABA3E3014EAF2F3C17DE870B6C +:1026D000E33780BC3B557F8B0B97D9CBF25E5AEE2C +:1026E000D2B64DD6465E9F9D2DA3EFDF18F3DA7963 +:1026F0008EF332D6EB54FDE228E8713B9EECFD668A +:102700005FB578D4F11F04BDE2C2F92F35CFBF30D9 +:10271000AA627E8BD1DE98AFBDBD7DBE43FBC0E714 +:102720009617D4E72039B0DE3FF87CDC0F5F2140FC +:10273000126109E89FF2E71A806706894A8C1FC276 +:102740001AC87F839E778C792C0FF5821C2F4679CF +:10275000778EE3759270B806ECB2901832DB2BC618 +:10276000B33D45E7098CABBAB81C1133EE0AA6C3DA +:1027700073AAFF42CAFFA63CA62D84B078544241FA +:10278000390F814295961D8749E5DDB4BF66079BE9 +:10279000478DCCE221D30F6BBB241657959A7C262C +:1027A0003CF2FD0623BEDB49EE22AA067E45453FEC +:1027B0005437F8F4E7CEC8B71D908717D430DFD36D +:1027C0001188086C3F8EED0F15717E9D2F2D55C021 +:1027D0002E6921E17AB04BC85189B03C3CC6D72E56 +:1027E000631F8CF3B1CB4D783C38C8F89AF77390DF +:1027F000FBA53FE5F6C9B3DC3EF909D827B45CF484 +:10280000F1E00180733FD8292EB03742F87D1FB721 +:1028100053FCB77812E01FEE6DD5B1FC706B333E00 +:10282000EFB9F5709B1FFA7FEE4707FD14BEEFB4BA +:1028300010E4D71692FCC54A80372A627C63576B36 +:1028400014FBCDDF923C007B24BD2D077485BEEFC9 +:102850008AD68A6E5A6F6715C1F8C64E85E21DE4A6 +:10286000631F41F908EE12CA2F2E9F32D79522FF1F +:10287000F654EDBD0AF051788D88DB2F06BFB9BA4A +:10288000070656D2F283CD7BDD4086D9B9C9F52F34 +:10289000815E9F43E5AD06EB92EC5E40D7B7A06842 +:1028A00091328F96FD7D1BD7817EF6EFBBFF66F0E0 +:1028B0008FFDCF3EF14D2817D8EC59FFBEFDB7B1C3 +:1028C0007A2FDE0EF50A0ED379D0F653D563FD309C +:1028D0007F8ABF81CDB49EA3CA9AEFF894613F74FA +:1028E00012A4ABED3FD82FC2FC0303E11AD8AE19F6 +:1028F000F366B41FC8A7F01D86FF5DAB3A76413F73 +:10290000EF3A8A919E1E6839001175F29D6FBE8E56 +:10291000F47C70D57A02F4E05A25635CB160F52D41 +:10292000E41B2679E16A91D3C699DF75B8907E3BA6 +:10293000572D4E4EE2640A7C38EEF63A05E5C5CBDB +:10294000D67C07637F781789BCEB40FE62FBC4B27C +:10295000CAF6932FA148077B89AC15599E5FB8CF63 +:102960006D8E1F16AE16C3E9E0F8D421E3BC3AA27F +:1029700075EFBC48E72BCFBC15ED52D26B1DDF18AD +:102980008F8EFFA9C3947F22AB0C2E8D84441F1D14 +:1029900077CF5E4F3E944F470D7D95C0FDD3A72B5B +:1029A000C4C4780ADFBDBD22E6A11CAC67FAABE760 +:1029B00016B6AFD5C3CB3BFAA801563CC44F863FF1 +:1029C000B023CAF6BFC91767D0BEF0723ECAAE7850 +:1029D00055C1FD8998EEADA1EFA71183DFC4A175A4 +:1029E00007FB658B950EC48E6C4B59A3C6BA39EFA5 +:1029F00018360D5365D4A74715F0274FF5C904ECD9 +:102A000097697C7FC88ECF1D9CAF7742DE0CF81D86 +:102A1000ABF6BA350AF7CF0C3A6989EAA0178BEE04 +:102A20000AC798DF63CDA3868C10C07311DF87229D +:102A3000D25B15480FCFB23C5A631FD15168CDAB62 +:102A40002EB7E58317D9F2A8CF37EE52EDB4C7E31E +:102A5000B65C84FA42F3A31CCBE7633D329BBAF920 +:102A6000D386C75F52FDF2F802E9F5E37AE673799F +:102A700078CF1D5233F80BFE159559E638E9D54E3F +:102A8000E6C71CFAAD0BE979679DC2F73D59BEA7B1 +:102A900083AF7B9353C37A3B7B6F55009F5D81125D +:102AA00037F473F0D29FB8315F85E7AD1AF278033F +:102AB0007D7F13EDEF3BB922EAA4CEC257F360BF8E +:102AC000FEDE3A05F352FD19037D0769D97BA73372 +:102AD0000479233B6B124BC226B86E7732BDB6D455 +:102AE000C9F787B658F33A285F2C7542DE98378AC3 +:102AF000FB99A2C2F37B6D7EBF810FFF81ABC4E265 +:102B000029EC593205FC54262FE33CDF6A27D70B0A +:102B1000867DB183FBAD5BB8DF6AEFB7B4593F8008 +:102B2000F6D92AB5124254F6F59DD06D959FC53160 +:102B30002B3F8C6FB1F2435134DF52BFA0B9C4F2C6 +:102B4000DD17BAD866B72498BE236C7DBADCDE09DF +:102B500020472AA93EE6F607CAB791F47DB343DFC2 +:102B6000E004B9768E76883F231C85789BDDCEBE47 +:102B700087AFCF3FC8FA16E88FFA75F760BF725C6F +:102B800060E787AC76C93038B99C1B05CE7F719E53 +:102B9000877D76B6FD37FBBEDB6D5278FB2BF439B3 +:102BA0003793E54976FA989FDF09F1555A7E8ECF23 +:102BB000EFFB4E099FFFCECB733368FD34FC6DC431 +:102BC0005D7F0A0939506F6CFAFC4BB08CF07B4189 +:102BD000FAEF3F75B27DEEB9E3471FA79F8FB3C5EC +:102BE000A13FEB34C5F7BA9CFAF3E6F24127DB9735 +:102BF00036E8C2C8AF34ECB45B1DFA2173FDA1A75F +:102C00005D5EB2FD915CBE9E3EC2F8EF674B966F73 +:102C10009A48F9D959E845FB277749C73AD10F793E +:102C2000494915FC845C2EBFC96226378DFDF6EC40 +:102C300006AB5CB59FC372F17C7997FDFC0D97AF35 +:102C4000767A1C49BE1EB3C9D7545C7B04BAB2C79E +:102C5000B55BE057667F72FB389CB968CAC8F4F868 +:102C6000CBD6C19E431387CAAFC0B99AB474C0F61D +:102C700019FD07DE6D585C05FB795208645CB235BE +:102C800031F7ED8943F22B3C27EB67100F0DD76529 +:102C9000A1BC690CFEA9E7500E95CB7AFFDCB74DBD +:102CA000F34CAA14DA09A3F089EEF8CCCC5FDF0369 +:102CB000590F76111F6F2BC7A7DDBEEE12632EE8EA +:102CC000F76332A00BC5A3CFBB03F136E0053A1B77 +:102CD00069DED35D4CBEFB67454310BF739D919089 +:102CE0000F5CE30D3B268476CC0C5716A3676F0967 +:102CF000EEEF51FF7DB01FD6C1CBF2FE0DFDF89176 +:102D00001167E57AEFE62C56DEDCCAE2CAAE83B381 +:102D1000DFD0683BDFCB0E0271CC4D54AE437CB0AC +:102D20009BDAF9F0DD5F354020BEDE4EEB474CFE0E +:102D3000787BA85685FDC68EF24A05EC0A694A15CD +:102D400096E5E24AB5968E39A5EBFE79B9101F2FAC +:102D50001531DF761A2DB79552BA76A938BF5F962E +:102D6000BDED05FB2C1B82A9D543EBE9A88AE8122F +:102D700085C711546B214723A5B7399DD1F70F4162 +:102D80007ED1F784C86C179DFF2FF9B9AC2E67B4BC +:102D90006C3DF84372CC0571C01685ED4F003D7453 +:102DA0004C1F82BB96E3D7CDC74DF9477C3D3F967C +:102DB000076290F2DA2592E674EBD3E06272AE43DA +:102DC000D5D551E949953FB3E455CF61FCE40C50AA +:102DD0007A32F1F548F25A728517BB7287F298E899 +:102DE000C2AAC8A784D981C6B99F3F38F52558CF54 +:102DF000CBF04A0AB3914EE9FBF99EEA0B91FBDA5C +:102E0000D63ABA6E07E6541DC17856D2817124FFB6 +:102E100004F28F663BE4251706E3E893C52DEFA681 +:102E2000F4119FCCE21504E826832A62D89F2C1265 +:102E3000E30F1503BCBBEA27D0FEBAE489D4521FC6 +:102E4000EAA7A688F9033DB59E66B35FF0C70CB646 +:102E50002F739BB7E619171DA7DC1BAF45F30BB209 +:102E600036C7B0735540C797A8644010410E860915 +:102E7000D39B2185C54DEB543847259008399331B4 +:102E80009A7EB49EB77A428E6FF0003E022C0EE618 +:102E9000DB2E6092A0D4A7273C2012BC8BBA5CA882 +:102EA000C7C365304EFF0C0FF1D2FA7FEA77E23EDE +:102EB000789FAF4006BC3E2F2EFFAE93CE77F0D763 +:102EC0002ECC7BECFBF3C59897DFE7BB6C01C8ED1C +:102ED0003E811CA6CA9ED49C2EE049882403F6FF9E +:102EE000FCF37402FB30833F2368FF39822FCD7DD2 +:102EF0007B3A4E3C439C45DBB949B79BB60B7DE61C +:102F0000F9E80A4A577BBD95F74D2343F11623CEC6 +:102F1000529711D90974D139E63F9B816FBA299C28 +:102F200012FA137A10E0AECC15312E4972BDF18938 +:102F3000F47DCDE1401DE495D6C8159832EB9FC7CE +:102F4000D6FB379EC86E986F9DDA549745EB571D98 +:102F5000D550CE2E08AE3B04E5196FB172A793F1A0 +:102F60000BC4918849EED69C1E87F3FB21A7938E54 +:102F7000A09ED48551F9C6761EC19A4767A603C89C +:102F80007F37D141C461A68359940EA698E94017B2 +:102F9000CE870EDA50595F08FFE86FD40943F1BCC1 +:102FA000E17CB04EC92E1FCE2F061C775765074017 +:102FB0008E1A7CA1CEBC0BE5AA6B99330CFB2D06B7 +:102FC0009F18FCF1A9DB817C48F9A411F87DB15769 +:102FD0009B9F8E4FC00F31F3C3B523F04D23193C97 +:102FE00014A08D1A6512CBA4A2E497B3DF291D6744 +:102FF000E2033BDE1AE708E4B8459EB1B209AF6AC6 +:10300000EADCA374EEF87F55D63A03263EDC48FD91 +:10301000103096BBC51001BD52ED5DFE29D0A5DC78 +:10302000F08320F8830E57B819F36967BE9F7123A8 +:10303000A5CB3F8D1135987CA7B6FC69E4E7373303 +:1030400008D8273D3356603CF84F3745C6839ED895 +:1030500044F17F1CF5727CAC88B9990363D93EBCFE +:103060001664CF4890BD27FC7B9C97755E6F00EB84 +:10307000D175B6C8C71E37A3F71E37D3179B9CBDA3 +:103080000AF0DB60B1A29AF3A0AF90981D5BA5F0A7 +:103090007DA92FDA35881B5629ACDD7DAD7D687F93 +:1030A0006C6ADD8FCF9C8638813C2B4F594C83FD59 +:1030B00070E52FF30407F0F1C56CDF16DEB799EC6D +:1030C000AF710AF36395BF4811E04F65434CCB36AF +:1030D000C959451422E9ECE8AD6E99B5DB40F0BB67 +:1030E00072E05F719F3BA734247C1DCA1B7A49881C +:1030F000F6E34EB0F781525DF89AA9DF40439F4551 +:10310000CF35D225C8AC44EB09CFC1746A1EDC1799 +:103110006B0CD4BE2B4F1D4E47F073DC440F06FCE6 +:10312000C6FEEC2DDCFFAE2B5190FF3A5B9CBB4002 +:1031300035372ACC2EFA38503BEA3902D897A59673 +:103140001BFAB9F084FDD9D864B63F0B65D89F85CA +:1031500027ECCFC213F667E13BECCF42F9FBAD3A67 +:1031600096619F16CAB04F1B9BCCF665632EB62F97 +:103170000BCFFDADCDF8FC496B14BF3FDBDA82E528 +:103180002B5CCCBF2165B120D8CBDDB73B75C8BF68 +:10319000E9E47470502FC909D1757507589CC0FDBA +:1031A000F2BD780EDA1D1471DF7563F05EF255FA28 +:1031B000ECAEF675431E8CF2B4179F6EF93EA2E199 +:1031C000BE6CAC1922A7AB94E97532B5134A83EBF8 +:1031D0006AB36979BD32BB03F21127696DA1E5EAD3 +:1031E0005059F355AEF881A93CBE7C97ECA1F56F20 +:1031F000EBBEAC03E401C001FBC86DCADC3AB0E32E +:103200001225D45001B956EC8C033D7F0DD66B22AC +:10321000C0CFFCA92F91F620C435C66BCE4AE0433F +:103220005A3FC1E8FFDCEA774210387778BBD1EA31 +:103230008955E7548F48A3F407DF85D1FA21ED6A59 +:1032400092C2BE196406D8476EB6FFDBED60FCDFA4 +:10325000ED66CFB739DFFFD85D3BDF4DF968BE9B28 +:10326000F161B73B5C0FE75006A788A18708EE9B8A +:10327000C4DC7028A1A5F857705EE8D6176502FB7C +:103280000A0F72BE9D38DEC7F4F49D0AEAE92BC727 +:103290003FD5914DCB131F0E8540EF6E26210FD0E9 +:1032A000496C8B88F9294F564DC86EA2D52FA97E3F +:1032B000261BF4CFA70AB377E3DCDF68EBBC713CD5 +:1032C000C4FFFE7484C9BF2739BDED7224A3B89E24 +:1032D000D55EB457A8C380F6485B50C6BC22318F78 +:1032E0003D9D0EF5EFA09E932AFC1885C7F9E7993E +:1032F0000AC63F4EBBF8BD1749B4539CEE889A45A9 +:10330000DFF7C644E4F776D51307BB7AB3B712CF1D +:103310009BC6CA653C77B2B95C64E7657CD7C7C118 +:103320003ED9DAEF66F2C1AB605E69BC7CDFE1DA00 +:10333000003C4515F83DAE2FAA47BCABA28AF9A9BF +:10334000F437FCDE1CC0732A1023C7EFCD2CFEDC43 +:1033500039E6B397A641BECED7D510BF8B00F3BFD9 +:10336000D1E412619F68F04006C0F30FC63D06032A +:103370001B3268FD8EE56A08D661AA5A5B0FF90513 +:103380009D6A2DFA391953EA9465288752E734F07B +:10339000BE8C8E7219F38BE03BF025E92087E09C10 +:1033A000BCB1FF9C915529807DD5D980613E38C73D +:1033B00060C937EFC8BE1ACF27498DD9086727D112 +:1033C00015A81F6B9051FF15789504EE3F18E7ED97 +:1033D000E1E88529DE90B3CA7A7E23AF59B69C17FF +:1033E0001F1BB1967379FC20D776CEE34F8AB16F5D +:1033F00066C5937DBE398187B200DE1C38E0AB0D17 +:103400009FCF7D81CA26986781EA41B883EA861AF0 +:10341000905F6349B40DE8EEBCE1B5C139B5BC239A +:1034200009EB3E559389A641BC7D7003F4BB99D34B +:103430007977B1551F3FA848063F4E75E7429C512A +:103440002431D3F810878C99C69BD09D6D294FEC01 +:10345000CDB7D49FBCBDC4F2FDA2F8C596EF97ECE2 +:10346000AEB494A7F45D6AA93F6D7FADA55C91B839 +:10347000DA527FFAE145967275F2EF2CF567BEB924 +:10348000DCF27DF6C00ACBF7CBDE596F295F3E78C0 +:1034900087A5BE61AFDBF56299FBC2EC7417DC1F38 +:1034A0006189CB5AFD00BB1DAFFCA55DDB0072CD71 +:1034B000EF44FA96418FD3F2FADB991FA5CC0D6940 +:1034C0002057C671395AE4D3AB418ED6F815D407CC +:1034D000B297D593BD0BD0FE18B79DCAA3E9606D16 +:1034E00092D4F70C90CBADB1B9A5A678935BEDC59E +:1034F000335B35FE7A02F179A3BDACEA2402FD40CC +:103500001004E2E7D44B857A6E8DB637CDEB795156 +:10351000C4A3D183D4DF7BC8E4EF8DE4DFD9FDB948 +:1035200073F5DFC689C483E70D8470149EE5D1234B +:10353000B590264CFDBA1B807E7B9CE1E65DB4DF36 +:103540009E120FEE5F1A7E5D77711FF2C560B18C1F +:10355000FA85C85AB9391ED7C1D737437912FD4AFF +:103560008A7794B706DE370B03F176903BB77B5032 +:103570001E8EFB2FD7ABC05F4A8952A0D0F7A18324 +:103580004E1DF6B7EFE3782D512B6A21A4541A6C27 +:103590003A00CF491AB533E8B3AC6CDB0178DEEA08 +:1035A0006679C217877E500BB24499CBEC3F79AA5B +:1035B00033BE81F623A9148E347E85F194FCDBD9C9 +:1035C000FE45A9FC7BA037B0EACFD029D4642B7884 +:1035D000FF8C1BE840C027D28F3BE045BDE186430E +:1035E000AF5096857886C0EC53D89FABC9DE8EEB82 +:1035F0006ED8AD60CF46989FDB01F41568B0AE770A +:1036000086F27DC45387C0E2DEDD59DACBB574DCC7 +:10361000EEDC926C88B1425CA4C9246F7AB8DEFEFD +:103620008A47E4F96F4CDEFC05FAAC1EB27728FD40 +:103630006F1727007CBD04E496FBAE5E02F4EE56E5 +:10364000E96AA25D1FD3C2A84F99BD7B3387A9AE9B +:103650006409EEFB7F14A844FBD6DDF27C5AFCB96A +:103660000724A24F1F19AFFE493B50DF9312A70654 +:1036700076458BE6D477A59107E5DC0FD934CE38B3 +:10368000E7CACEDB76737C18F1D0549C91C7D38CFB +:1036900038A3D1CFCDB9956347B3C7DDD4BF8C98DC +:1036A000E0DD44C701BC747ED1548F7890093BA7FC +:1036B000FBE7F25D904765F849E5DC7EA9E2F81D7D +:1036C000E724E827CC83B8490E78B55FAA07BE3453 +:1036D000E22CBF03638BD60BC588C4E26A0E436F2E +:1036E0008967A621CC9A7306BBE28BE5A332BD465F +:1036F000FFED87F36413BAADE73527F65ACB93B7DE +:103700005BCB17C5AD656A351F05BB006C348C5BA0 +:10371000ECB67E6F32F603EAD8F932858E7C86E904 +:103720005FCB7D3984EBFF7CDE4F515FA206C46B1B +:10373000E12D56BD9ACFF57CBE4D7F56FA248C27DD +:10374000D41C0E1C02FBD188FBFCC6A359EE7530BD +:10375000E2377679EE796B1BA15FD02F8FB8581CBA +:1037600003E2C39F14F17849218F978CE3F19222F1 +:10377000162F7148DA2B4B05CC0B3DE9463B233A1B +:103780008DC569D839AF0FEBE59F091A1B2F621A57 +:10379000EFB6B2D8950C0DF13CA867C44D8CB8803B +:1037A000D7A7CF073EDB1C7A357A90D249EDAF5DC3 +:1037B00004FA992FBD7CB815E45B918CF9DCEACC56 +:1037C00055DFF5401C12BED3726DB13616F9E01705 +:1037D0000E8C0F7471BA36CE271A7116BF87D94571 +:1037E0001E8F60EC037978BEBE07ECDD4B76535A32 +:1037F000B4E83B16CF33E27653FAACDFFB8890A3F4 +:10380000D2759CB6242E32FB4AF7D698F21D2FE6CD +:10381000EB367569E2DEA5B4BC87C42BE11EBA0A9B +:103820004E1FA143D673B1638880E7A2C61C9542A0 +:10383000715A7FEAB3D6EFE5B673B317DBCFD1DAAF +:10384000F6857C1239B98C8EB7458B0A2047B72C88 +:10385000A5B63C2D4FF6F0FDA2496412D0E17CC91B +:103860001B4A007E5F93707FCB756CF21B90C7483C +:103870008EB07C247502CB8B545F92504FA919A453 +:10388000A2C23BB48F74FF9910817D1123AEF50461 +:103890005D57D02B7BA85F5EEA003F5BC5721FF5CA +:1038A000CBA1BC97FAE5F0DC47FD72780FF94850E0 +:1038B000DE4FFD7278FE84FAE5F0FE59EA9743F98F +:1038C000366FCD7C4F2EEC1B9521BD782AF629133F +:1038D00028BC5D8A4305FAB0CBA19A9A9B95C59402 +:1038E000A4FECEF514EE5FD4CE67F9D3F33D4FCDF1 +:1038F0006B93ADF13573FC7128BE362018F1350895 +:10390000791EE3FB0CA9385B84C5D9CEDE8F6EF43B +:103910008371CD61FDF0F8E607B7FFE763EDF4D3FF +:10392000EAEA7BBB3D25709E234ACCFBC7C6390F14 +:10393000637EABF7B5619E8C33EF6814D6755F95E7 +:1039400017EFFA713A222AC85BBB3F67F871767BA2 +:10395000DA78DAF59B8FDB1546DCB4C741307F3A65 +:1039600026507B02EC8BD6F8DCB71D23C7535FF7DC +:10397000F0734536B9903A37C0E33E2EB066E93C65 +:103980009D02C707CF6747D158C2E27AE6B8AAA717 +:10399000348E87D53D5E1DED3A81DA7B68FFA991B3 +:1039A00020C4D136C2398134F37B98F37B5B9E13FC +:1039B000ED8D8D790ADA497585A120B46FCF9B1101 +:1039C000349F1B30CE351CF2CD50064CFDADF79523 +:1039D0008CAAFF24AAAFB551F4B5E462E77ADA0FF6 +:1039E000CC56E0BC46B7777912FCE8EE6000E3EF16 +:1039F000FD793330AF27553F380BCF75485E660FE2 +:103A00004B4105ED6119E65F3E54DFA8D7EA6174CA +:103A100042D919E38B6E6F2FD673C961BC4FC215A3 +:103A20006079772E95EDC7794A45A298E485316E85 +:103A30008B87C5A3BBCB232AC459BA8332E6E97767 +:103A40006B9588E7768EE7F622C39E08A11DF36F7B +:103A50001CCF463FED3C0ED0DEEC447B2EDC92A525 +:103A6000C2D52F5E5F780FF073B7778302FB92CEDB +:103A7000BCAA51FB3DC0E5F6C8FD568CA99B8EFD46 +:103A8000FE1BF4EBF42D57A15FC708E7915EE170D0 +:103A90005EA8DD6ADFC7A3D006CDF928F6A78FDBC5 +:103AA0009FF676ABCB079CB0EE9B1EB19E5F761067 +:103AB000769E6BCDFE75C8E73D7212EDA89E2F84F1 +:103AC000B4E7C2C66418FA2CE5DF5BECA002CE4F67 +:103AD00005FC3B901AE88B8A84D56E997ED85AAE45 +:103AE0004E5ACB33DFB4DB41FA6B60072DE6722F01 +:103AF00049E53D4B861994011FE158BC06E06E2252 +:103B00007D6D9027E1E071F2C55CFF2DE4FAD19B59 +:103B1000C1E2BD05CD1E8BFF49F8FD7F85BCFFA22C +:103B2000BA43EB3A40C8860DBB4A43BFB5E8AABDCD +:103B300035282E6DF655936E3DDFBFD0663FD9ED2B +:103B4000AC1A7917E6E9E6DBE21AC67E2ECC13EE54 +:103B500039B08F7FBEE31AFD411E16C837E3FE174A +:103B6000BC6F98B62F92134288E2291FCEE7507897 +:103B70000A6E21FAAE34747C395FF761788B5D810F +:103B8000789BC7DFE57BD9BD5DF975525C2B86F369 +:103B90000E7D680F2C5A45E78376F819CC8331EAFD +:103BA0006767F5F5C3BEE78E0681F9A53182768D8C +:103BB000B1CE3BBCEC5C61D3E5425C84F6D1121C17 +:103BC0001FE12A195A5F8AA7E30C4F2CCFF0DA7A4B +:103BD000EBF9C7269BFD62D0C342DBFB010FDB176D +:103BE00037F8E083D96F4E1A47E1582DF4D6674C69 +:103BF00038777D69E20FC719E043F87D0C4B7D01F2 +:103C0000FE38A0FC50057E7F3E6BE0014249B229A0 +:103C100083C4EA28F1FDD433788940CB4B363FDDAD +:103C2000D95D04C7BA079F0423CFD5B56F7EBDA960 +:103C3000ECB93B81E5001F07B616D97A9BEE83A14C +:103C4000A8DB0979F360E7EA649B04B9B6A2BA2D50 +:103C5000543CD42E1BDA09A3B40B936D729A765E92 +:103C6000A31D45D746B8EF89CFCBC3BF8B1C1EF32E +:103C7000F832E04DD5BC78BE7181AC425EC65F0BB8 +:103C8000C798B3CD3B42B639260C6F47C16E33E0BF +:103C900017D3C31F87EFE6F11DA3C0FFB7C6C7D96F +:103CA000FA73F2EFE70D1FADBE61CCC8F305B81C87 +:103CB000780F91E6154DFD6CEDFF14E3E2F20D0473 +:103CC000CF2FCA0E5D85FDBC72F5DBE8DFCB5975E1 +:103CD0002AD8019B6819EC804D7DBD18FF2E2FBDA1 +:103CE000B71B88BE3CE121200FA610356B0FED7786 +:103CF0008A2AC3892B225F7E4884783AB98660DE9F +:103D00004866BF87DD1B547CE9C3E06F656529B851 +:103D10009F919135E36166F4B238B3017F46CDD10E +:103D20005A88BFCB4D2424005C429CD400935D4450 +:103D3000707FC3A3EFBB0DCE1B1099E927BC3B07D7 +:103D4000F42A8FB78F652443BA9D6A13E6AFBC2867 +:103D5000631C6B2C5C0D4689B2BC3C7B1BC0531EA4 +:103D6000A11D08003F8B974D8988A104EDBFF22467 +:103D70006B47FE839D2BA1BEC99267BC437835E497 +:103D8000CA581E870F2EB5C6A9C9209D336D5FF98D +:103D90001F8B1E8538C59861F29BF9ED1E0E67E6F4 +:103DA000491286FE030D56BDE1E179D71EDBBD3217 +:103DB000953E87F53E68BBFFF0AD30EA0117092953 +:103DC0004EB42F96A2DD60F8253BA022D8E34584AF +:103DD000E5E7DBDBCF60ED4990F9292E0F51944ADE +:103DE000FA7D8547C77C43172D533C0A4EA2E4D188 +:103DF000F7F9228BB7B4094486F2D07809CC337036 +:103E0000295FEA00FBE580321DEF4B33FCEA763593 +:103E1000847910A4ACD662371BF95EEB2B4AC6C27C +:103E2000F7CC31A9B8930A74B93EB714ED687FCEC8 +:103E3000C0DF839CFD6CB37F81723995A39087713D +:103E400029E523AF7B636C0E1DF77401D14CF69905 +:103E50004B8E629CCD757A9CE57DA2D57ABE5AF7D1 +:103E60008A75304E9197F1610D513BA05D0DB19E69 +:103E7000A3769DCEB3D8EB43FD175ADE27A85D632A +:103E8000BEF767E4FE33885666EE7FC208FD4FB288 +:103E9000F5AFA6ED7FA8DF1C4BBF9D328BBFC602DE +:103EA0009EB4F750567B6B4BBCD523EF0F5479591A +:103EB0005CB32B18C5FD815A42199FD2CB155F1CEC +:103EC00097D8F95E82F61B29B4EE0FD4723A162900 +:103ED00065001D5F215BEF339E4BECF71B5BEDA292 +:103EE0003720B845F125FAAA92B84FF0A957033FF9 +:103EF0006C24BB39D94A303E3D3763E066D807BFF2 +:103F000066CB7867E72CCC67467FFEEFB7542DE091 +:103F1000F781B2BCE680887809D78EC5F35B463F4F +:103F20006127990872312CB23C08FCA1E32773F396 +:103F3000310FD13EAEFDFC7B932ECC2D35CD2B0920 +:103F40007985E6F1E615EC924CF308BB48358EC74F +:103F5000EDDDD478632E6CBC233C9E658CD7B4C059 +:103F60003ABF26A78AF36BE27C6C8C7704E697064F +:103F7000BF671D8FE74DA6C6BBD23ABF26978AF30F +:103F80006BE2F7EFA6C61B7361E319719D2E6734D0 +:103F90000A7438527CC788EB5CEF7AD212D721E4DE +:103FA000C97935A5846C1398FCD8E9ADD90874F1AA +:103FB00051C3FA32D42BDCBEC67B56A93E5E2833F1 +:103FC000781B0BBDF136131EE1BC8D3E19CE49287E +:103FD0004477B173133A9EA308E2F3216AAFEB98DA +:103FE0005F5286DF1F6B0D617977EB2C7C1AFD9495 +:103FF000CD62F7815D3447486BB7BFEE65FEECB626 +:104000003CF586AF817EABF1B07CDF599711DD6462 +:104010004753C3FA009C9FEBB99E54808E9CB49D7D +:10402000C11DA81B1387F5F7541C4AB6421C5476D1 +:104030006898EFAAA5FFFB0647BC4CDFB85CAC3D17 +:10404000B98CDD8BDA983A17D480F9478D0BB330F1 +:104050001F61D162DDA752BC2D1684D74AB9BE8339 +:10406000F350D7F1A5B6FB0B01D03C74BD02BA14D6 +:10407000877BE3AE2B7C798940FB0DFBAE453F236C +:104080004C1B66D37EAEE3FAB6E6988B403C82CCFE +:1040900077A2FC5ABCD8EA176C732754B073B65594 +:1040A00004481B6DB7A8C1FADDE5627C15B6DD0BCF +:1040B000D378967B628C7C5B3B7EEC71D397BCFCA7 +:1040C0009E181E1F3D45CAF1DCB991976B6F6FC4F6 +:1040D000413700AF835C7532F9309C0F183C7FE4A8 +:1040E000727047EB9B184733E0CB97E302C8FB8223 +:1040F000E6372D79EF14B168541BFB0444DA538181 +:104100007AD8369F1DC29EBCD1EE89CA27F2EF072E +:10411000CAF8DF331086CFFBBD61F39EF34A29490D +:10412000C73F2C1EDC78580AB569437831F0F0BFE0 +:10413000CD47F773BCBF32EFE32AE607165AFE6E8F +:1041400080717EEBDA545926B2899E17AE70EACCA4 +:104150005F1D2C07BA3C7A794688FDFD0B6E07255A +:104160007E2D821DF4D7F7AF1759F29A79BF23AD90 +:10417000973D9FD2740E99A4F68D20FFA52D14446F +:104180007B609D88FB1FF951968F07DF8F5BED5693 +:104190004B3E5E7BFFE302C40D1F80FC44D339BB62 +:1041A00082E63EA113ECBBB6388B4324683D0A7708 +:1041B000617342E8281FCAFBB2CBF5C255D67CC159 +:1041C000CE398BD53D1AE4D5D4F6C285609BB6B303 +:1041D0003897513F15EFE2E7511D244AE0FC85E492 +:1041E00065F1E620BFAFE36CF9BB9F8831B5B81825 +:1041F000F276E34A0D5DB7077322753E885F062AA3 +:10420000A3BB803EE510E6792F6DB9330C714235C2 +:10421000277D1C7C29B70F16FA585CE52D47A208AC +:10422000E2E6C99CDA85BEEA34F55BBE85FDCD1DAC +:10423000E11EFA66DECF03627A79B08C7FFFF26A04 +:1042400011EF1772131F9E577597F6CE027C3CB084 +:10425000664728DD39CB196A246286C75DCAEE0736 +:1042600020A46F36CC73D3E70FF63D4DE79DFDB923 +:1042700017E56CB6C4FA35B56FF6E50E6FFFFCA70F +:10428000EC1CF2F3FCBE75424AAF04BFB1275526C1 +:1042900031B88FBD278B976302FB9E2AFFFB02F884 +:1042A0007B4A3D40A394F8FEE8FBE54688C3F60848 +:1042B0008413EB2B0B206EDFC3EF773F0CDF69FB22 +:1042C000B957BFFFF056D007339CE86FF6707BC735 +:1042D00080EF031FCBFBF9C0C7F87D247CDECDF156 +:1042E000E9057C06CE0B9F77A7C3C755017D33BC7C +:1042F0007743260805C1FDB9720BE45BFF6B2B0900 +:104300007F8DCEE181D0BEC7E14C116D7F6FBAF6D3 +:104310003FCED1EF8375F2AE3E8EF3F3957A4380B4 +:104320008A4D3309F693068E07D2F563AC6B288B62 +:10433000C93977267B6673FB5272258390BFA056DE +:10434000DD7FB34AF97E63717249BA38F1E37E6664 +:10435000F7678D10174F70FC5E991D7E12E0EE50CE +:10436000EF457FCF299030D4DF346B8008A676FFED +:10437000E567F8A670FF10E076CE66F756FB28DEFC +:104380002141CE57C5E0DFA41D2590FFEE0B1EC5D1 +:10439000BC565FD500F23B8AC27C4657E00F2ADC50 +:1043A0007E4BF8FE7B01D04DB664D0DD37BB806E0E +:1043B000A4A1F29550DE95CDDAFF3FFF37BBC05F79 +:1043C000DCE9A46D400EE63BD1BEB1CFEF250EAFC8 +:1043D000ACEA3F87F90DC3A76BE0E1ADB47DCF44F4 +:1043E000767FCB5C31B9E4AB4097577BD13EA3EFEE +:1043F0009798EF1F3BCDE9ED34F7E77B3E55F0BBD7 +:104400007D3D46A2D7810BA7D78111E8F5988D5E37 +:104410003F26E9E9F59D74F283D2EBBBD0DE8E171F +:104420007B5922FA76D857963F5BB01BFA93BF347C +:1044300067FBD3F4297DB62586AB19122CE7998743 +:10444000E47DE4135FEED03D03C6DF2DFA27208420 +:10445000DC34FDCE9CB11DE4D839F42BFAD3F49BA7 +:10446000F43178E75EED8DA4BB376E8F9FE5C7FF13 +:10447000C8CFEA8DC4376FF9597ECA487C73D09F84 +:10448000E29B6C80E36C7CF311AF4FD721DF7F4E52 +:104490007CF36D7CBA4B19DFE0FC2F1DCE3724B6C0 +:1044A000AC0BE4F1C662C61797DCB306F922C54728 +:1044B000B156FC2E0D95517E1B7CF4E93DAD58DFC5 +:1044C000DEDE3FC23D819529FE0F57C03CF44BD440 +:1044D0000E763E6900CFE1EE2283FD2ECC13667985 +:1044E000B99E584C67E64192C07D1297723CEC042D +:1044F0001F0DFCA0193C9E2527C922DF707EF655B2 +:1045000025AACCF7BE1CE1ED3D99E11A187F1719D9 +:10451000C0FB9A465AA7051CDE33D9FA027F1A3A25 +:104520003F9B1E5AE967E7E556F27EB23F57A2600D +:104530009FDAF97DEE9A9FBCFBD828FD34F3F61183 +:104540000EFF05F07FC49F867F29FF2F83F726FE8D +:10455000AF124AD2F27FB33FBDBEBAC9FFB7E5F78B +:104560006FA6E3CB463FE3F7B3E17BBF9FE9FDFDD9 +:104570001C4F178AEFFB79FB7B2E1CDFF78C80EF3B +:10458000ADE788EFFBD3B5A7F8FE173FCAFFBD081C +:10459000BF4FF362BCBC7B26D92794A485E3BBE65E +:1045A0007E148DF54379EA6381D2FDDCCFBA43E90D +:1045B000EE45A2ED1E4BD76E815F3592CFD7E1FD60 +:1045C0005F5FF2E2BE02D58F4FFC8DE9E047E9E87C +:1045D00060AEC8E490E2BFAC0BF4FD5FD1FF817424 +:1045E000FDDFC5E5FAD9EC82D786EC825FF8AB87B0 +:1045F000CBBF5DFC7CB2AC46927E8CDB0F5C05F2DF +:104600006AE71DD902C4BB0AF584007EC2CFB91E79 +:10461000BB022E0DAA1E6AB7534E08F0773A7646B3 +:104620005501CE4B99FAFBCFD1FAB3C341E1FBADB3 +:104630001FE59DFE3B782EE0F33B5F3BA93F5BFF10 +:10464000BD1FF54FF81D78EA93AD72DB988718EE21 +:104650006579B6B3D2FF5DCB9FFB64AEC7C227CDF1 +:10466000F2FFDD145DB1FECE57FF50F83EF333BDCF +:10467000F2453AF8EC78391B9C17F965434F39330A +:10468000D3E8297B7F869F6DAC135C8B618EFBE446 +:1046900064A6F47736F4E7ED14F11C552397278DC3 +:1046A000B3B2B8DDAE7AA0FF07781CFE8155F7D60D +:1046B000C0BEFAAEBBD40A40417E33D37BDAAA71C6 +:1046C000185F2DCA142CF933C633D5DED97711FC07 +:1046D000BD083A6E318C7BC51C9200BF3113EC06CD +:1046E0008C57A8F8778DB35DBD4188CF6E127A974D +:1046F0002C07BD7A95979D8B092E3ECB7D991B2C5F +:10470000744B825567A9DF86F5D58C5EBC3FE59C6E +:10471000EBBB7AD3DA59B599A2E14F5C9E593D0AB9 +:104720005E83018C7B19F81D3E0E5BBF9A705400AE +:104730007CFBAA041552EF7C944EC05E124B9398FA +:1047400037754D15A31742FD92D1EF5FD968C0159B +:104750001E75BDCF112EA3DEC8E3F17AB6F316A9FC +:10476000BF3FE665720C2BD2F2878773D2EE2B180F +:10477000CFAE5655872B923F54B54CFCBB1DA9BC00 +:10478000EF507091EF7FBEDED0BCE22C3E6AAB9F53 +:10479000BA7F24A8A0FD877FD7C344479B3299DF07 +:1047A000EACC0A7F2B13E56508EF9FA5E518AC0757 +:1047B0005168D987E50DF85D4D953BB01C64F589CE +:1047C000AA9E13DE69BBCDD84E4EF5D383656F6AC2 +:1047D000DCAD386E2055DE86E54256FF5CC71976A3 +:1047E000FF4A52C2F97F2CEB99B06F7A7DCB5731DB +:1047F000BE7443CB4DF8EC6E556B204E67DC4372B4 +:10480000FD0D5F55C19FBEE1EBF7E1BEBED1FF429A +:10481000F03B80FF35B91EEC2567B1187EC43BC460 +:104820007F43707460B95166F7FC2F9C75B2A7C3C3 +:1048300014BF53E0EFA5437E8D66BA07830CC9C34E +:10484000EF09FAD399E741CFC3E749C8214ABF1F0F +:104850007B4BE331A4E75A351DDF18F31DA97F63B5 +:10486000BE23C91B036F297A2AE57F5FD716BF7461 +:104870004FACC3FC9F850287D3C7EF8BE4F51AE9E1 +:10488000387BCB912E34A0DB46EEDFD9F58331EEB9 +:10489000F784C8EB801F8813DF55391CBFE78A37C0 +:1048A000A3FFB19118817BB93CE504F7C5023E63D3 +:1048B0005F9DC9B56F7B8D720C934BC2A5BD28E778 +:1048C000DC9A21F7989E5433FA74B1828EB3F5CCFA +:1048D00095C18B200F3412848B0869F905B8E7392C +:1048E0005B6265123BF3C2A142D007EAC54288D29F +:1048F00043C7E72F1C2E22ECE822FEFDF4CF5F40D9 +:10490000FBC228C385BD65B4EC4995752548CB2508 +:10491000A9720CCA3BB9DD7766EBE72F74A03E0B9A +:104920007F6696AB355CAE9EAF3CFDFFDA45D4E9C1 +:1049300000800000000000001F8B08000000000045 +:10494000000BE57D0B7854D5B5F03E73E6956426F3 +:1049500099BC278190131E12157012480848DB0974 +:10496000AF862B8FC1074609304978846700AD4E6A +:104970009596810082628DAD0FBC2A0E16BDB6D50C +:10498000DE68E92D7F8BFC83A0424B3156AB684536 +:10499000A350A56A4D04B98E56CBBFD6DA7B67CE3D +:1049A000399909A1DAFFEFFF5DF874B3CFD9673FFA +:1049B000D67BAFB5F69EB367E1CFB7183B6B2A192C +:1049C0000B3396CBD80E6D8367FC28A879ADBE213A +:1049D0001A635BF05541BCDD051E3B63158C3D98A9 +:1049E000197479A09CBEA6CBEA8476CE921C77D0AF +:1049F000C558B1F79370357C5F3C8E310DBF1D9C5F +:104A0000C5D818E8D77BBD62CF817218F3288CDE39 +:104A1000ADF740FB1C3763ED50326B84B1618CDD28 +:104A2000E59275980F9481D208EB80E7A91A7F6F01 +:104A3000C13A3C571D6C651BD4D34A993F02758F10 +:104A400083CD0BE0F81E0BAD63844715A542F3CD73 +:104A5000F06E601AB477D658FC112833B074E9D7D9 +:104A6000BF81DA8DF058A994F0989213BCC8837076 +:104A700061ACA60DE7C5A281525847EA853959B7FE +:104A800042ADBAD47A3D83211F5ACB02F36D8C55C7 +:104A90007A0229081757594E6A7018D5CBF07BD780 +:104AA000464B98015CAA993BA294C4E102334F0D96 +:104AB000B893E3E395B5C1C0445BCFF7B29C758D65 +:104AC0001AD0AF439613110E308F8F6AFF7C0F2ED2 +:104AD00067B9B3CBCE06023E07DF19602AAE47A303 +:104AE000F7CE5D33A3FDE0FD8ADDAB18CE777D5AAE +:104AF000FA38C4A379DC57BEB8D71380F7299F3999 +:104B0000026D09C65B22E0FCF2DA5AFA0EBAD7ACA3 +:104B1000798CCDC3A50C6484D00E27964C39EBA0BC +:104B2000E5BD3C18DECF659C18AE0CD44F6300D7B2 +:104B3000865A95A925F85D777B7616EA733BEAA736 +:104B4000B2115009D94EE07327FC3D0BFD0659E622 +:104B5000640F3CAE0FF3E7D41EFE5BC07C9373E1A1 +:104B6000BBC6CDA6E76F4CF90B4BC7F7D6131DA5F7 +:104B7000F1FEAFAEAD0F4C14ED4ED3FF23B49E2B20 +:104B800035E647BC5DE94B8B8461895705AE094C1E +:104B90002C8DF7F7EA97EA3C848B191EBFEA86470B +:104BA000203071484F78340414BB473B375CFA0A15 +:104BB000877A6BD9E45CAD271CCCEB0788DD8E705F +:104BC0005E0070BEB524393CA01DE1E3D56BA01D8D +:104BD0002C65B23AD566013834CE54984321F8A6F4 +:104BE000B341D8CE3F75926EBE66389AE1D5F8349F +:104BF000F345A1DFC6BBDD3EA070F607099F280084 +:104C0000AD12E4096FAA5FE73B387F0FFCC5755E04 +:104C10005E55F66C0ECC23B841F131BEDE77F4EB75 +:104C20006B60818CA842EB7E2709DEDFD1AFD33CDD +:104C30003FF3FC53505881FC0BBD51F28303BA760D +:104C4000CC1A1D1618CED8E31E77CEBB69501FC1F3 +:104C50007C6781AFCEB0711923F1FDE01CE26F33A8 +:104C60005D7CBA56FBC1019B9ECF399DCD0BCDEC2F +:104C70001E17FB5758B0BBEE013807AE516FBF0A85 +:104C8000FEFDCAC1EC8DF86CB557D54E6423BC60EF +:104C9000BD842F3F6392BE1896E17D2AC06F2673B4 +:104CA0006A2EE8E75B20A4CEC25AA6FB5334976E67 +:104CB0001DA75A951A94A380BC8C2B87C7D76B9ECF +:104CC000F76AAF9DC6037AFC444F8F66B8BC523B6F +:104CD0002803E5C80B71B88C381FB84C42660678BB +:104CE00078B25954013C7729CEC8C330A7BAD0CD89 +:104CF000818923112E2C6C07D179C25342F251AE17 +:104D0000DBC6E49F950CE5699D9D05715D6FD858E4 +:104D1000ED932E2CA345E53AB9F55E76F50994D3CB +:104D2000B25E17FA3EF50F84487428E979AED315C0 +:104D300055391D7ED84D3724CFEA3CEF5E4C786262 +:104D400067619D6AC6320DD7ADA6A58F60198C6DBF +:104D5000C626B04E7B66A00BE5BF9A362082F4973C +:104D60007ACD8F37733CFEA866960E8F290B7E1185 +:104D7000A6CEB52C03FCD304FEAA05FE524A9D66BE +:104D8000FC31E4D370298B3CA2081040FDD4607F35 +:104D900004F93699DE90F84C29B57EDEA1A76BD6D2 +:104DA0004AF097786407467521BF06BD56762BBD3D +:104DB0002F25F8043D123E5D36D427F342B653FA50 +:104DC0007E8205F323EBF0BB2D0E1F3E6BB068799E +:104DD000D80EE0E4413DCE4A7D3EE41F1686EF2426 +:104DE0003D215CD198D0F5DF016B2828C7FE407AC1 +:104DF000E2779B75E30CEC396E375F99FB357DA745 +:104E0000AA603F901DE1F3F974F2BB2493DB0FA776 +:104E1000BCA3DA2C0393C3AFC199EDB766C7EBEF20 +:104E200014386B2309F480EC4FEAF32C35E8B5E035 +:104E3000DAC23B0F1E18877AD873114832769BED81 +:104E4000A183078B1892086385F8BF870EFA5D640B +:104E500077883A1026CC7F476A77DDEFF4427D6091 +:104E6000773D8CF5ED301C1B0B764BE6430737C0C6 +:104E7000F79F1E7390FE3A55931A41E6C90E4D6096 +:104E8000C761DE5630733280D4A00863E90CF5A305 +:104E9000F52856801CC03B5BF32908EFCB3335A2C5 +:104EA00007ABC6A26E985CB6D5A720BC7E68674DDE +:104EB000426E5C385367BF5C9EC9ED0E398EC3C924 +:104EC000C229E5F17E19F3AD433D629DCA48AF00AA +:104ED0009F93DD26F95BF6333793EBCF6EFE3C37BD +:104EE0003FCFCD4CC0CF872D2BDFFA1EDAB3BF5595 +:104EF000D923B09439DEEFD2F359A1462AAF092D58 +:104F0000A6B2498CF767166CC27EDA6B5F9A732380 +:104F1000D06FF32E870FD5F2F21BFEF2830A0DE15C +:104F20000478C7EF1634DE5D01EFED432C64CF6EDD +:104F30002E62B5484FF6750AD9475B347BCD2E28D3 +:104F4000EFCDA8BE2733373EAF7B3326529DD568C1 +:104F500016A4F3D54E4EE79F1EBBC5DB8076A5CBCE +:104F600045FC625F57728705EAEC10CC9BA1FC60A0 +:104F70006467A80E5E6ECEB4123D6D16F415167001 +:104F800077C610C99CAE57C2F84E6B98A19DED8CA8 +:104F900059E9B95D81F925A053D99F33064C3A12DE +:104FA000C7337F6FA7E7B82EFC5ECD6606BBE7CEA2 +:104FB0004C6E37DFD93D8F343E8F6C733FE9FCB9BF +:104FC000E03FF33C3EF04CB81BE17F6F86FF9E4C08 +:104FD000B2C33B6C28CFE7BA7E7B5419D11779DC7A +:104FE000A1A03C9EFE85122D06F8A554AB91F52597 +:104FF000A8D73CD346011DB06A9B0FE1D93E38C704 +:105000003D5037FE6302FF2F5A3D6E9C676012D8F9 +:10501000D544DF2CF74AEC67526325977F6070E92F +:10502000F4EC8BDACECD0351FE866DB45F9AE70CBB +:1050300047707E3ABB4D39CBE5B266AD8CDB7FF372 +:1050400026AAFE94F49EF61D6C430E90FD2765790A +:1050500018EAF0DD9BA2FAD6C4D357E1323A98C7DA +:105060003E506F0FE26EA912ED1BFE675EC868F737 +:1050700099EDC286AAB2E7000D009748CD28A4B3E7 +:105080000B2D44677DB59701D39C5E26B578705F84 +:10509000F5A09013D3271E9F887263069856D8EF09 +:1050A0008C89AA270AADB7862CCC0F133FE2572371 +:1050B0000AACED4869C7A16F21DCAA6C1AE9AD52B0 +:1050C00076FB1539F87EA407E11C107608B4E7FAE0 +:1050D000CDEB8C0C8167EDFEE3AE461DDD1DA93ADC +:1050E0007E21EE5740EE3525A227C6D6D1BC0EDC78 +:1050F000944AFDBC75971271C0FC27A95FFC7E34F1 +:10510000DAB3DFB3F91C1A2DCB82789DEA6362E330 +:10511000EA774DD2D901C759A092ECCAB263D50E35 +:10512000B45F372AC4A712FEF342467B33B812ECB1 +:1051300032ADA77D0A9DD9919EFB6A9F9AEDABCFB8 +:1051400033C1AE023A67E5AC5C6F5725D353D2AE9C +:10515000B232BF92457AA8C38A7A773A3C4824078C +:10516000AECD5008AF93D40F093FA7AA540DE175F7 +:1051700024F4BE0BF7E347BE50F93ED89F6BB0E373 +:10518000F2B3B85F60BB1D0C32F86E7BA133B20E78 +:10519000BADA77D345F91D841FEDDE7188C7DFDAEF +:1051A000480E279BAF3BA4B2C14098D3420A951248 +:1051B0007FC5A11466D5E987629678FEA5597CFE65 +:1051C000B96B9845837133C3CC9F687F2CDBC1BE1C +:1051D00078B29551FB6826CC6FC5600BD1A7DC1F58 +:1051E000A7D8C2FE7EB07EDB9E5561DC2717C3FCCC +:1051F000701E1ACC0FF56549288DEA0343D9540E69 +:105200000A65523938D48FDE0F090DA2F282500997 +:105210003D1F1ABA98EAA5A191545E182AA3F2A2DA +:10522000D0A5545E0C7A13DB0D0B5553393C741921 +:105230003D1F11BA82CA4B4233A9F48566D3FBB233 +:10524000502395E5A17A7A3E32B494EAA342D7512D +:10525000BD22B48ACACAD0CD548E0EB55059155A43 +:1052600047EDC6846EA3FAD8D08FA8BC34742795B6 +:10527000E342F7D37B69B7A40A7EBC4D9BEF417F25 +:105280000750B886749C8CEF1665713DF042A67F7E +:10529000465645BC9DDD027ADCD5B35D6316D76307 +:1052A0009988D704FDCDCDE2F2F923DF3BF70C65F9 +:1052B00071BC6DF1F6EECF60A589F71B71F9C0D70F +:1052C000373D4BA372BBB5DDAF22FDAE64BE303CB3 +:1052D0009A36EA4505E5CB0ECD5A93C8BEBB37CB0F +:1052E00046DF3D98195C81EB4C2B397100E5C98C88 +:1052F000B0E7F7E3915E86E5FC763CF457BCC1422B +:10530000DB7D8D79F6A17F4D9BC8482E4ABF12D810 +:1053100075067D7A87800B636D0707123F0D2EE7B8 +:10532000FAA7630AF297FDA681B47FDF6E8F2A5633 +:10533000B46F5633A6B7FFB76F6A7814DFC7FBB3F5 +:10534000D33C8B37B367D0C42E69D5C6A740396824 +:105350009BFF9914F8644824383E15EA431F0B3F1D +:1053600083E5856D91F169505EBC3BFA0C6EE38676 +:10537000473BC6BBA07EC941B61FD9BFAC5D9BE011 +:1053800086FAC8A3FEFD4006ACA22338215DC3F90E +:10539000445AD2613EDBDF04430FEA551FB6AAB080 +:1053A0001D8AE31FEC38B4DF245EDCA3DA2766C372 +:1053B0003FFB5FEF2953F17B6B474AE6B09EF8D97C +:1053C00081EBC675821E7904D6D5DF1F553C3A3A6B +:1053D000F98DE067C0C34328E7A45F72C7862CF24B +:1053E0004BEE48F554E3905D9398E7610DE9D84A98 +:1053F00070B26F1C48FE384977005F833D7B87A001 +:10540000BBEDDDF66E62F8FE46C8BF7F15F8FE5BA9 +:1054100016E78764F07522AD8C39371F1F167C099B +:105420007C7C50CFC7E6761F0B3899E1BCC3C20E17 +:1054300082AE8271814E395F31F4A37D28E8FB5C36 +:10544000707DF75F8C6EF70B39910CAE4CCB213928 +:1054500009F47A21FAC792C91BBBD8CF98DFFFADF8 +:10546000A79CE37E5B0FC8B941C9E5DCF302DF49C5 +:10547000E597903376937FC799CDF9A6D213B0679D +:105480005724F0537B730C7EEAA9AAA71AE50D1BDB +:10549000CAC88E4E1B1609E33EA538AC95ABD80C96 +:1054A0008532C2B1B094FC0F2560675801FFD0551A +:1054B000144BA7E6B134A0FF5DF29BA7DEABE73744 +:1054C000A9EFE3FC28E9226BC7ADDC2FA9CD04FBD3 +:1054D000E5DBD9C2AFDFDD0FF7836CFA6EE18E5BDF +:1054E00075727087D74B75D93E19FD2E10EF776C0A +:1054F000584FF0748E4B6C375467F3B8C2767B9775 +:105500001FE93CFC4DE6417B2673C33B249F32419F +:105510003E29249FF8F8FD43A98F86A1EECFCE1334 +:105520007E004FEA2CF7FF3B7ACE459B0AE5D43844 +:10553000CF3E15E334A08734E4D37130F751082F00 +:105540003BE15D631C8FDA381641BB17E016C57D61 +:105550007BD8E2263F93DDDEEA477E66F64C5A7F33 +:10556000A5273823BB17BEF0A4696588D46076DB15 +:105570001417D0DFA6124F2AD6E7407D6B158C9BFF +:10558000D5C1447D8B6BCC3FEEF708FEE8E787364C +:10559000C078FBB2FC73919E81AE8358FA877AACD7 +:1055A000E4AFF6F6CD1E90FC19E7274F99E4A7FA71 +:1055B00061240F9760BFB2BF64F6CDE06C2EE76E3A +:1055C000166532FB46D2FD79DB3762BE8BB37BE7D3 +:1055D000FF570EFE68DB4EA6F33716DED36ED5D02E +:1055E0009FC1FD3416673BF5E716FE463FFA1B8167 +:1055F0000E9C83791DFF24F21727876384E623FD21 +:105600008CD29F982EE88A599508EAF1F42A8FB532 +:1056100081FAEB6097437FDBB2B9BE917C8D72EB70 +:10562000A9612897B2ACB85F477F923B2BDE3FD68B +:1056300033CAE3F289897DDC7562CEADEB7D19E872 +:10564000720E1FE17E94D6EF73BE9CD69F45D6A303 +:105650009CF033CD03ED5398FCE337F893A77EAE6F +:1056600000EF821EFC5CA55219CCA26ED8EF4DF360 +:105670002951DC07DA2DCE08EAD2EA4227C3F8A680 +:105680003DDD12C1F888FD1D85D6692F4F8BA0F036 +:105690009B5858958171CCD387F7BB8209F07F75F1 +:1056A000B0DEE0FF32C3B1BBDD9C673D08C7FBCF76 +:1056B00011A77D3EBB3B4EBB0FF972FAFCAE0D76D7 +:1056C0002D1EA795F1C702EFAE2DD5A8B29671FB9E +:1056D000B49045D6E9ED2A5D1CF477D8CFFDF138BA +:1056E00068FB05FA386873E11EB477EFEB8E83062A +:1056F000F712DF65B79521FDDEEFDBF5933B109EDA +:105700000E11AF1879CCA5A19FBE627F2EAEE7F730 +:10571000A6F9CB52FAF1CCFBE03F651BE30BA77D6A +:1057200057644489B6B213F2B7F42FCAFD30FA0FAA +:105730003D09F9D0086F397E9DC2F7B5CCA670F946 +:1057400027F428C897BF921C8830D29B7E87F230FE +:10575000EA9BD3BE913E8A7B269137723E00C721D9 +:1057600089E2BF305EC238AB2387EBA93A1BF79BB7 +:105770002AAB2A56E2BCEADC2EC5A1F3F79F16FA43 +:10578000CC1C175233BEA8080ABF77A2F59BE33B97 +:10579000A7515FE47278E9FDE4E782D7515B2BC53E +:1057A0000F8F2E50D93AEC27383A9F25F85E96AFE6 +:1057B00023DD0C61EC18C2B84287CF24F1A2A36BA1 +:1057C0009B28CE6C8EA775BFAF4FA945FD5D8B7032 +:1057D000D48D5B25E0375394CC11D43CF0DEDE70E1 +:1057E000B78761FC6BC827156137FAC5BA7E89F1A6 +:1057F0000BF63D37F92B6AEBCF54AC1BAE83671524 +:10580000E3F1D9FDF77934785E3B64436ED8951C9B +:105810008E3373381C6FC30763C81F333287FB375F +:10582000FBE48F61C3785C88ED4FA1F869CA1F550E +:105830001FDA0D382ED703DC9F7CBD889B98E37858 +:10584000B5A11506F9921653584417BF48B3B6913F +:105850007F362D66A5E7667ECBCD31F29B847F3205 +:105860007C4AF89B9FFB72F87A8ED62FD6D06F6851 +:105870004F4D6C07DF22DAC9BA391F2159DC7DBED2 +:10588000C0EBE9E0987CF457D5DAC343FAC2E712DB +:105890003EE7CA739893C3F5B8FB9A97441C4FDD53 +:1058A00080BD49BD9A66ED3D1EEB37C563D346F515 +:1058B00088E7FD53E2B1EB7284DFF03CE3B15304BF +:1058C000DD9E2B0FE56ABBD1EE91E52C81C7D3C1DC +:1058D000141606F9785DB54A7128A00FD28F47EFEC +:1058E00056C8DE8CD63B482F37D6A7907FB6B14C32 +:1058F000A5F78DB7ABA43FA3201F96817CF8BD9080 +:105900001366FF6C35530CF1F3E9A3520CF56B16DB +:10591000FCE8F76BD1BF5C65D370BC231AF73787FF +:10592000FD2AD9AFD0872F8AFEE9BBBEE1437D2691 +:10593000E9E1885F257E0BBFACFA70D876E18F3E37 +:10594000B2B92C82792A4C89C7E9B541D87F23C5E1 +:10595000815FF36EA33867CA97F70602B47F0C6ABB +:1059600065A43779FC3445F0E984C2AA59A8C7DF99 +:10597000DA6A63E8377A6BCD69E2E78EB52B292FB7 +:1059800042FA97A57FD8EC6736FB977BF8954DFEDA +:10599000E464F90CCF26A10F29AF92D10788ADC3DB +:1059A000FF881C93F2E375B1CE0985DB6E5F07704B +:1059B000489BAF121C245DBEF6C52D0FA21C4E01E4 +:1059C000FA58CF109EFFF12CEE43D86225A11FD9C3 +:1059D0002DE53AE64F94C6F1724D7071771DD97F6F +:1059E00076D32A43DE8759AF24976BBDCBAD3B728C +:1059F000B8BFC2AC77CCFCF075EB9DDAFABB4BF1CB +:105A0000FBDAFA05112CB7143A9B50FE9AE583593C +:105A10004FCC32C9D9B87E505964A47EDE1AB58BFA +:105A2000EB093BBDFF3485E73B849CBCBC3135FDB5 +:105A3000612C3F4DE1F90E61340AD14E7D332DD2F8 +:105A400042FBF295A3914E42CCD711C6757A53C949 +:105A50008FD0DA9FB753A7A472BBFC4035AD5795E2 +:105A600086F9866AE29B16B19607B28345B980E74C +:105A700016BF2505E30B13DCD643E87A691D6F6179 +:105A80000E1687573C2F847914F89EDE29B8FF2C18 +:105A900073DA07919D3A2417F1F17DD81F02DD1FBB +:105AA0003EACEEDA014B3DEC1B9991C84EEFD603AC +:105AB000A638F2B1EFBC3A00F9F6CF2CE8CBA5F846 +:105AC00071E3ED181F6EDEAD527C69CE0DAF5D4007 +:105AD00076B7294EA9A63B4BD19FD2A2A4FA509EDD +:105AE0004838EE73DB49CEB41C4BA3FD44CBDB8AB4 +:105AF000A8BB491E4AB81F807605A33057C94D720E +:105B000053C21FD6E5C775493C54B3E8E171255F20 +:105B1000695D97F5BEAEFE1EB20F90CED4F83A5432 +:105B2000B795D6D7C9527D38BF90F00FB137D2683C +:105B3000FF27F1DC2CE851E27985C073E79E333F03 +:105B4000B814DAB7FAB328EAA016318243E71B6E1D +:105B5000A2130907B96EA08B20CE53AE7BFF9E9196 +:105B60004783F87D7A2AC5F1A5DD2DF30ECCEBAF86 +:105B700013FBF7A5B94AB7DD8BFE8BF6ECF14B733F +:105B80002B12B417F62EC07B05C2BBDAC33E89B018 +:105B9000F83E2F597EC34DB946BEEB437EC34DB987 +:105BA000B93DC7FD0AF8DC88FDF5159FCD56D766CF +:105BB00025230E6FB96F2696D67AF2BF99FF243E41 +:105BC000943DFB3EC338BE592EDCA8AE640A8CB3AC +:105BD0006938E74BB68669941F64E29773C91BC0A6 +:105BE0007F04F1944CEEF415FF3FEB89FF9FF5869F +:105BF000FFD6ECC013084F1CAA5F39ED0BFF13DB77 +:105C0000A33CB10FA4F1886EBB3219E5B3C9FC18EF +:105C1000391F9927B317935673757938A53E05F543 +:105C2000441FE863AF7E7E5F037D1CEA9DDFA3C453 +:105C3000A7CB05FE97CBBC8C5DBDE765F4017F4724 +:105C400013E1EF46D5D7152CE93BFE8EF7C4DFF103 +:105C5000DEF1177C17F1D762679F90FD5E55EF4527 +:105C60007AA9F4F82FC77C9DBDEB84DC2901FC9553 +:105C7000A0BDA4925CFB21BB88E4F6372D169A6F79 +:105C800027C8EB87953EADF3BF73C94E095BB3A040 +:105C9000DF1BAF6014DFF36AEB14ACE76BA0A7B5B2 +:105CA000BEAF57C9EBB15E25AF777965CDCB25FA8D +:105CB000BC1EE9D3A979ACBDC92B4FDE79CB2B4FE4 +:105CC000DED72BAFFAE59D875EED03FC87E0FC9203 +:105CD000C989BEE681029FB27E593DC7879D2EC508 +:105CE000D5AAD39D5C6F3FA9083D5E16A4BADB49D7 +:105CF000C2E280D0F3A776F1F7EAF8C476E588BC73 +:105D00002C9EAFD0B62A6035E49384E9F91DFE538A +:105D10009EC12AE669BB683DD9D3B81F52AE5FE683 +:105D200069A78BF56417F175671FE379ED125EE9DA +:105D300062BF91516535EC2324DC6E54030AFAD11D +:105D4000337318A649C03E6198827EAE4CBFB1BD88 +:105D500084772EDBFAB18A295F35C6F7B9B89F1967 +:105D600081EF75CF13EC5F013FA5983F764D9EF014 +:105D70003FD89917F51153EB7AA523DDFE249847F8 +:105D80007197DEF7270BF364BCDDA8F7DA525842AF +:105D90003FC327821FC05E217FB32AF4DCC48E126A +:105DA000CA7759EDD6C8FFA0AA3EE7D4929EDF6716 +:105DB000FA81BD75F0C8AE49659ADEDF12C832D4EB +:105DC000F36B0B0DED0B82030DEFFB355D64785F1C +:105DD000B4B2DC502F0E8D35B42F01C0EAEB833600 +:105DE000FF9BA1FD90D6CB0DF5A1DBAE35B4BF3046 +:105DF000D260787FF1634B0CEF87B7AD36D42FD9E3 +:105E00007D93A17D8BF0239BE1F2AB3CBE7F6BB118 +:105E10007239B4CE554EFECD1697D1BF79A7807F8B +:105E200075C6B852F4ABB7BC53568AF03E903E9656 +:105E3000FCECC9E8C22CD792C953F3F33631DE47E4 +:105E4000CFD82D48D72BF603DF5E0275D7EB9B70BA +:105E50004D5B86F1F8AC8DF17C2119AF91DF77C7EE +:105E60006BAC3EEEAF4D77B15B13D0C59D799A51C7 +:105E7000CE0AB929E92819DC243D9E0B6EBB057CAE +:105E8000BF2ADCDE5078BEAB5E1F3C99605E1FE728 +:105E900059447C39F8873C6E0F8D4A254BDE43FC14 +:105EA00078BEFA40CE03F4C131AE0F8C79BA1FD55B +:105EB000BEB4F05E0DDB2FE4ED2DBE52C44B327F3D +:105EC000FAC7026E3A7F7A13F7A7A71AE0F696E4AC +:105ED00077935FAF25FD73F2A7B7D87DA57DF1A7B6 +:105EE000BF05DF22FC77E771FAE8C6AFF0C727DB12 +:105EF0004785183B84E72198CBAAE9F74DC9F6C737 +:105F0000529EC3FEB814E3B4ADB8FF5212EA414743 +:105F10007E05ED9F491FB4821E74909F801DD2A004 +:105F20007EE3040BBB558BAF5BDAF30EE673DA55F9 +:105F3000C2AB1BBF67DF67D7A7A85FCB3ED39BDF92 +:105F4000EBBEC4AC67CF19EF233B6D1AAC7FBD6EBF +:105F50007F2DE1638EEF49F84CF3F1F8DD46D08FE9 +:105F600018DFDB97CBF5F446D87F231C3DD901EF32 +:105F700000B4E7E1F9C3888EDC4AE21F0957739C3D +:105F8000AFAF72676C7E0F3B6E6C7E2F769C5CFFB2 +:105F90006AB17F9EA40E6B433FE6A9989DE0A632AE +:105FA0009E77D97CD0C62284479EBF2CF1688B6D2A +:105FB0006A47FD6C63E67C652D03D76F3BC8CF89CC +:105FC000B11CFE3ECC9CEBD0EEC9A832EAAF4CBF70 +:105FD000517F65D76499F499517FE5D71AF55741F8 +:105FE000D0A8BFFA35959BF499517F1587C69BF4CD +:105FF00099517F0DDA7CB9499F19F5D7D06D46FDCF +:106000007561C4A8BF2E7E6CB5499F19F5D725BB15 +:10601000D71BDE97456F35BC1F79F087867A45FB25 +:10602000BF1BDA2F3AF40BCAEB197DF46143BB3185 +:106030001D3F35B40380B763FEF77C420963979E2A +:106040007CCAF07EBEB0D7BED1F56B433FAC95E7BE +:106050007187E12FE2EB3D16B4A39162655DCFF548 +:1060600003BCAE8828BE28345BBCFBC94A9CC7076A +:106070006F4E3988FD2CDA66CCFF5E1C31D69BD979 +:10608000C00C940BCD401711A093A59817AE936F39 +:106090004BD94A712EB06F74B6E8D0158CF249C353 +:1060A000FE76CC7B97EB94F4E617F426E727D7BB74 +:1060B00014ECBFA8165FA71FFEF2FD66871DE976E8 +:1060C000E16E85FDBBD2733D4D7BEEDCD42FC1BAB2 +:1060D000CCEB30DBA13FC937FAC727A92E8A179C22 +:1060E0007A59F5717FA3910F571FE27182D54F281E +:1060F000E4AF33C343DAA7C9E0A286F9BEA139876A +:1061000045223AFED3043C1C5E23FF9DC27FE07C07 +:106110001E5023986F94A2A59AE9AD32CA7AC2396B +:10612000ADD4C8A76638BB7D8509E94A83BF388FDF +:1061300085E2FCA199AECC705FB1FB4E3BCAC3F3C4 +:1061400085FBD1FCC47109D076A3EC09F2EB245C89 +:1061500061DFFE26CACD64FBD9F7F395F33D5FF40A +:10616000BE5E0E7F0DFBD933BDE9B94EF4B7817D1C +:1061700069F6B399F5B0B267FF674A3AF9B53B1CC7 +:10618000C877419F93E7C198F46469A9414F76EFBE +:106190007BDF5168DFBB2BC36FF5C2FA0E65F86D6C +:1061A0005EB48732FC76AFCE0E6D01B8D0B91FD089 +:1061B000534F26B013C77BA57D1420BFC9C66ADE26 +:1061C000DEDCEE222F3F27B42FB7D24BF6E7DB659C +:1061D0005EB23FDD95BDDA9F778838D16D18871C98 +:1061E00012CF0FBA5DC46B80EDFC88B78DB68057B7 +:1061F0009F3FECF666D2BCD2C73CD58E79D42D1E1B +:106200008B47D1B0E4F9DC1B5CD69A9DE2BB1CC382 +:10621000777C9E2AC21BE06A75593FD7D3ED782F51 +:10622000A3F7C9D639DECBED5E1B0BDE8EF6908C64 +:106230000FDBDEA976A2BC6B617E0F97933E8F3E8B +:10624000FFC3C6783C78BC880FCBE7AAE71FCBC357 +:106250003A9211AC463C9AF3B06ECCF08FC7E7216E +:106260006BD8817667C899785F5C23F0AA8AF5823B +:10627000014A7445F350CF3FFE03F6E61538EE8D24 +:106280006A98F2245BDC95A54157DFFD5C73BD9CE9 +:106290006F75F6D15C3D9D9AF913ECD3CBF11C9947 +:1062A0003FA3D04ADB0EABAF14E1BD19FF3D86FC26 +:1062B000B40BF0FB1E79AFE21C2EECE37ACDE39534 +:1062C000FDECCBF22FF3F27CC3155E9E6FB841D587 +:1062D000F5937E8E7EA49FA30F7EAB35DEC4FED1E8 +:1062E00093A8DFFB0AC75BBC3DECCC5BBCBDD89977 +:1062F0009F1E1B9A81F16CE9EF32B793E722657D0F +:1063000073A671FC4DE5BCFE4381BF3F8A7B3A1EFC +:1063100015F3709ACE8B3AA732BAA7439E3395FDF8 +:106320003CEA7553FBB5D9E31FC5F96E2A51681FC6 +:10633000BA295331EC47EBBDD58F225E23A2FF472C +:1063400005FDEE18C8FD39E63CCC25D8BE024BDE73 +:106350002F9E6B45396657D58470FC9997FB8B2E21 +:10636000878EB07FE9776BBC5B11FB27E3BD08C06C +:10637000E7AFA481FC39BED546E75E17A8AE4D480D +:106380008FC9EE39A81F16A0FCA7AF7A7E0CE19941 +:1063900096D553AFEEF776EB55DF799E23FBADF73D +:1063A0003CE2FD1DA99C4EBBDC2EF29B9BDB9D10AD +:1063B000F8D92AFC1A28D751BF64A96C65223D730D +:1063C00042C8D57FFC5C33BFCF23DBE5A2EFCCE72F +:1063D0009A3BEC1D1BF371BEDF507C787E21BFCE53 +:1063E000B32F3F07CF316AE4E3DB54C2D2ABF07D79 +:1063F0009985DE675EE9D964C3BC6F8D61E63EB303 +:10640000C1386E18C755C0E3385BC357ECCB8776ED +:10641000195A171B388CCE7B4FF622DFD6F2FC7947 +:10642000F3FABE14FCE1DA08FB0B848796380FFD03 +:106430004B417F206FBE403AAFD6D82E7E2E8BE7E1 +:10644000C1225952BEA28FE76BA761BED3202E6F27 +:1064500048DF644DB014E4C6F94B15F0369FE7767B +:10646000159CDF79EE197589E73BB480AFEB4F19C6 +:10647000812C1C77C6B875DC1FF6C5D9B36A251AFE +:10648000C79C4FE07B86FE8A941C2E8753348DE494 +:1064900032F32894E7EAD47C4D584F718DF5A86803 +:1064A000273B785C92CDB730BC5F6582E8C75FCB95 +:1064B00094774BB95F96CB592B7B57D2BF2A805329 +:1064C000897A96FF01FB696B1AAC6782EB30C527AE +:1064D0005306AFACC6730DCFCEE37DFC30C9B90116 +:1064E00079DEBDFB5C3F7BF8B0E15CFFC6070E1BAD +:1064F000CEF5871F38FC55CEF54FBCEF81C3FFCCDE +:1065000073FD529E1D5583476F06F85F0544152A9B +:10651000C7D2CAEA08DF5E82DB9502CEE1CF01CEA8 +:10652000CE389CAFDA7388E077D406F386F16DE35A +:1065300039A86D3765445A482E4668DC59CED6498D +:10654000B8EFECB4778DC0713B9F7EB5280CF2E4B8 +:10655000D8F74EBB19D0DF5BD62E373E3FB9E625C4 +:1065600037C2EBD81A95EC353A17ADCB475A28E825 +:10657000EAD982C01CA4AB796BBFACD4DBE32C940A +:106580004BFA777144A5D42B29FF963E9626888E28 +:10659000D797B7651BEA522F2F77243EA7FE6001DD +:1065A00097438B1FDF61EFA7E1F8C1E60298C74967 +:1065B00091DF7072979BF661723E0D8F97D971DFF4 +:1065C000F9D61E078B921FB8DDC6C89FE59FAAE4C7 +:1065D000E13D46FC8F799ECFED4DA3FE16DCAD92DA +:1065E000DFA91EC60A015C837B16F37DB0691D0B13 +:1065F0008E6993515E2DD8A2B0B0C6DBAFC1FB331C +:1066000042B7501CC6BC4EB37E5994E4FE9C457BF9 +:106610006EA3EFE733FF6D68CF2E6835BF9FF21E84 +:1066200012F9A273C4737E5820F44E251B7D761098 +:10663000C58F32866BE7D63B27D772267D7FAD9319 +:10664000CA0FD77AA89C53A0111E96EEDEF75C3FC6 +:1066500062F3F64AD44BAF1C6C4CBB568BDBDD951A +:106660003BAEDB7F3F91BC313FB34EC07DB4C8CB66 +:106670005C24CE3D541CED3D2FB30EE131A2E77CEE +:10668000A59D5D67F2FB4ABBDB0C8F530727A42156 +:106690007DFC52C26534C045FDEA7049F6DD729555 +:1066A000DF9B667E2EF9688EA0EBF93B676E2A842D +:1066B000F15B9E7E6F4007D129F75F54087855B88B +:1066C00036B5E3FA2B98C96F18662F331D3D033D8D +:1066D000A9A877CC742BE989BDCCBF770ABF463710 +:1066E000BDEEB99DE02BE90A4F3A58D0866351AF11 +:1066F000A5EADCF75C2D6835D63FB2750C4079B25F +:10670000C8E46FF84849BC7F7BBE60202D76BEE6AA +:106710009F8CF9170B586013F7CFF3FB714E5A5B40 +:106720009FBB19F97C27E7B3E5BF7AE2BF507E2D06 +:10673000F9CFBBD3517EFDC5DA9A87E32D7B646325 +:10674000BA1FE598359C8EDFFF25A2263C473CB852 +:106750005091F9FA2ECC535B41A406FFCD0F4F4761 +:10676000F9F9DF8FD83CE8876D7ECC1175003C5677 +:10677000ECE27084FADBBC7E0BC1AB79B7912F974A +:10678000FCC7DD791AF903C2FD04FCFAA1085FB168 +:10679000D34679AD2B5E567D384C33EBA2F599BFCD +:1067A000C779C4006FCD6D6ABD3DA3E77BB084ECB3 +:1067B000C86FCDBB383E9B77717C359BECD02621D2 +:1067C000B7CDF49F5328E2BA82EE013EE45793F925 +:1067D000B62CC2E577CB4FEE1DF136CCEFC39DBF93 +:1067E0004B5786C5E99F615628C0ED545BE33C7B5F +:1067F0002FF7F57C24F8A45B2F083DA4ED8689E5EE +:1068000043750F2F97D9A2E997025C96EDB0F9C2B4 +:10681000F078D913AADF8576D46B0EBA7F62E913BC +:10682000CFBE3216E6B7F4495BCE54BE0C17CA6F22 +:1068300089AF66A4F3F2387E96FCE2593BE669E242 +:10684000F33559713C2D7D729F1DF33ECDF09CD0E8 +:10685000B6CFCEF9CD84AFB6B727A3DE6EF9C9A700 +:1068600076A487BFEC55587E49CFEF9B763C9B8E34 +:106870007206E184FA45E2AD1B8F3DF0179DFEEBF9 +:1068800051D4CE83719E73E1F1133C835041F4FEE9 +:10689000F35FC33C9A5E77F8100E4D3FBF2E1DD7B5 +:1068A000F39E7525A7FB0737E6A1DE6EB285F33CA4 +:1068B00054F2E74DDBBF43F4B8E8C5EFF0FB9C981A +:1068C000BF00F919D65B80EB5CF0C055B4CE852CC7 +:1068D00048F4D8F420BFDFF08C95D524DA0F3C249F +:1068E000F8E6BD871DB47978CFCEF87D217F50C5FD +:1068F0007D58ABC85EF98E58334868AA9F71727C88 +:10690000AD2E94717F2EDF9A45ABE69DB7907C7BD0 +:10691000BFC89F8FFC0F7030FA675F9C942FE422F2 +:10692000DDEB42DF01FD4DC0E7D8BEDDE64F19616A +:10693000F84EE4DFF2F1AF17E3C3BC53D1CFF75EFB +:106940009E719F2BCB2385D2AFC6DA999ECE92C97A +:10695000819D5B88BE3E7999CB9915919935F4BE9E +:10696000DD16CDC7F7917D572A2427C00E49C4E70D +:106970003B6D82CF8DEF619E56450FDFBDFCFC9EC7 +:10698000A4978577417B1D5FC7E9C71E7F5E12E72D +:106990005799BFB1C864CFC9D22C27EE33C909F9C2 +:1069A0003D7B2037E1F988B87C0813FC96D9228F0B +:1069B000FE3BF2F56B0E3A17B9EC091BDDEFF3C1A4 +:1069C000E3FB5FB916E8FF8336C9CF46F96BE6E70C +:1069D000A6A7AE6289F8F9839C004BC8CFF03C2192 +:1069E0003FE7F0F306FFB7E4EFA224F2F740614F70 +:1069F000BBE352A8BEFFD3A5C5B43F33C157C2D530 +:106A00002C4F67A3B190DB539EC29F97990E9E12A5 +:106A10008E924E97FC6C398DD34DCF925E253D778B +:106A2000D3AB79DD46789ADFDF827BA7DC38FE6D59 +:106A3000EB615F8EF1DAA755CACFEBD4BAD2B3605F +:106A4000DC8D22BFA7D323EA99BCDE956BDF84F2ED +:106A5000443EEF4AE1F90E9D81AEF44CDD7EE0ED5F +:106A60003D6A3A9E07E88824CECBA08C0DF483249F +:106A7000C9DB90E77E3B53B9BFAF3395FBF926A93D +:106A8000AE0121DCDFB5F2F8D2FC7557A7E3FEBEFC +:106A900073CFA019B5B81F38A4F29CA3B0DF5A0079 +:106AA000F06DE44B672759F89E7168BFEF593A15AE +:106AB000FB99BFD5089785AE9D76ECE70C5B43E567 +:106AC000C2BB6C713A81FF9660BE16D2F903A6E78D +:106AD0007B2E23BA5A62A2AB20D25582F32419FD31 +:106AE000045D95B132BEDF16F13121F726A9C366E8 +:106AF000D4623EE5417EDEE3D41E956DC2F53E2EA6 +:106B0000E265E15CA2D71540DF7ABFE987487743A9 +:106B100093EBF90F7F79ACF26668B2ECBFFE34E21A +:106B20007E283FFCAFD72EF80DD67FF5EA803FB127 +:106B30009EED27ECFD6C2EE575EE75D0BDA69D7B18 +:106B40009F1F7033D67FEDA0FB453BD7F37D767852 +:106B5000AF9BF47F6711B7175B9EFE744407E92F64 +:106B60007E6FF0D87EFCBCEDA93D7F7B53C17CBE1F +:106B70003DB02A948F62FFD6FCEB14DAA7773EFD76 +:106B8000A9617FFA55D7B3429CBBEA74B35A3C273C +:106B9000DD99C9CFA936FF66CC8FF1DCE5F25DFB4C +:106BA000EC8DF07EC2FFFE7204CAA1CEA7B8DD0153 +:106BB000F6F076E6033CF46BBDDD06F8FB086D44A9 +:106BC000E09937FBB54FC3F3243DE1C2E1D0097032 +:106BD000C075015C9A507E268347DDBF2C3C3E9EEB +:106BE0008BE32FDB339AEE198EC345F1F3E76ECAC0 +:106BF000F780F5F3E77B3F1D8176D4B9D67B533F11 +:106C00007EEEE77FCA7AB7FDCBAE97D3BB864E99AF +:106C10008A9E74DF93AE7F7503D57FEEF6D17CFB41 +:106C2000C8EFBBFF87D1F72BFFDFE2FB90C0B7DBDC +:106C3000837199CEA7BF1CC0CE63DD67FE65F1DC12 +:106C4000FBBABBED1E8BCF390AE6F73A8B5C55AD2C +:106C500024CF1F1DD85FFA1FF83E43DEC33D3D67BA +:106C600021D911D3FDDC1FD3C2CA0FE239BBB05FFB +:106C7000A5F80525EF001CDAAF2C8B509E98353C0B +:106C8000E41ECC1B9BB5DCC7EF2B33EEBFA6E7D5CC +:106C9000D4A03D77641DCC0BDA1D715B3C2DB08414 +:106CA000197E95EC3F28C9EEFBE3F8CB280F65462B +:106CB00095711F72AD693F7175ADF1FD2CF6702EA7 +:106CC000E6FBCD6AB2517ED255E6FD477F0FADF3AC +:106CD0006AB67223F7E79C1F9C2EEFCFF7633DE166 +:106CE000D03BDC7AC049EC37297748EB093747902D +:106CF000EF3F1DF042D85B222F6F759FE0C9C4BEE5 +:106D0000D4218696F075F8F9BDA3BA7E092E12EE4D +:106D1000E70B6F892733DC257C25DCCC781882E7EC +:106D20003D2BE2F08F97C67BB599B01BA777DB8D23 +:106D30002E82E30B3BF9798917AA1AB79661FD7188 +:106D40007E1FFC9971239913D67BC4C676535CC809 +:106D5000EFD73C95F1FC19A5EA798A4F60FEA27E37 +:106D6000BF8AF98BFA7561FEA2BE8EF98BFAF6988E +:106D7000BFA87F8FF98BFAF798BFA8AF63FEA2BEBA +:106D80003DE62FEAEB98BFA86F8FF98BFA3AE62F12 +:106D9000EADB63FEA2FE3DE62FEADF63FEA2BE8EC3 +:106DA000F98BFAF698BFA87F8FF98BFAF798BFA8EE +:106DB000AF63FEA2BE3DE62DEADF63DEA2FE3DE646 +:106DC00029EAEB989FA86FFFADD833867A35FB9DF3 +:106DD000A1FD04E74B86FA24CF9F0CEDBFED3D6E7D +:106DE000783F45FBC0F05EE2FFB2D2D386E718FBE6 +:106DF0000857E23E86FF99E6FB9BA11F2B0B509C98 +:106E0000D4CE5652E9447F2F94A9AC8D4A17B0399D +:106E100096EF0D0D3EDE1FE9757B781312D7913189 +:106E20009F0E40F9FFC2B82BB85F42C41766E03F1F +:106E30003520E2B42FFAE33E57C64FD3632A8B8E38 +:106E4000043A8C29547A62692C9A0D74184BA13239 +:106E50002B964DCFB3639954E6C4FAD1F3DC5801B5 +:106E60009579B14154E6C74AA8F4C62EA6B2207659 +:106E7000219585B191F45DBF581995FD6397D2F3C3 +:106E8000A2D8182A07C426D0F3E25835955AEC3216 +:106E90002A4B6253A81C18BB82DA0D8ACDA47270EB +:106EA0006C363D1F12BB86CA0B628D540E8DD553B6 +:106EB000591A5B4AE585B1C5545E14BB8EBEBB381A +:106EC000B68ACA61B19BE9F9F0D877A91C116BA108 +:106ED000F292D83A2A7DB1DBA85D596C0B95E5B1E9 +:106EE0001FD1F391B13BA91C15BB9F9E57C4EEA3C4 +:106EF000B232F6632A47C776505915FB199563627B +:106F00003FA1726CEC17F4DDA5B127A91C17FB0D8E +:106F10003DFF46EC7F51F9CDD87E7AFEADD83E2AB2 +:106F2000FDB1DFD1F3EAD8212AC7C75EA2E7136219 +:106F30002F523931F6277A3E29F61A959363C7A95D +:106F4000FC76EC6D2A6B621F503925F6172AFF2D4F +:106F5000769ABEBB2CF6319553637FA3E7D3629F2D +:106F600051D9BDFF1F97F477052C6771FFECCAEA72 +:106F7000D37D6577A6A5935C9CBE86CBC57BD33EAF +:106F80003A4072728C437390F0DB668877D18F48F9 +:106F9000C0BE6FDF98F7FAA3BDB3A9FAF81BD7A15B +:106FA0003E5BE560429F99E4EE172EE1EF64988F17 +:106FB0003847D0F50B55FB73D18EDA54DEB10CFD9A +:106FC00026B79774D4615950C4ED098F28F38B7894 +:106FD0005CE9EF43B9FEAD5B3584FFBE404EDFD6C2 +:106FE000374BE8EDEEF6033C5C5FB8BA06D079BDEE +:106FF0003EF6D3D776E7CAC3FA5BFFE0F0A2047986 +:1070000058F1F3837DEEA7F26BEAE75B7DE9E72DAC +:1070100081F7878A02138A101E56FF087C3F7E7D07 +:10702000818ABFAB52BF55F120BD346E289B8C784E +:107030002D677EF24BCE49924FB658E0B561A58DD3 +:10704000A17FB24163E41F6ED8C5F390D19F3A0D82 +:10705000E8A549D0CBF22D1F93DFA969E5229EF761 +:1070600014E1FE29F93B364B5B773C876EBD33EC70 +:1070700030E5C72F7DCCE8BF6A16FEA9E56DA6E70F +:107080002BBF9DD0EF69F64B3514093FB28FE73D1A +:1070900031B53FADFB0CAC1BF3498237B89DA83727 +:1070A000001E14879170907E4F090FD6F3DC05E522 +:1070B000AF9E3A3884F2E44E695A3EB60BA6F3DF2F +:1070C000B352ACC1D1F81CE048F92C5DEBD2281FBB +:1070D000EA6DD0031A265E7982A3F1FEB88ED78BB3 +:1070E00098B8BFD2188F706EA53CF17A9803E6A5C8 +:1070F000D43F924DE736A1BF11BBD1AFF9888DF2D5 +:1071000091C26CB59755F58C570436DA882E1A76ED +:1071100067F2FCB4B0FF653C5720F1F2F68641936C +:1071200031AFA961734919B9EB76DBC83E94715947 +:1071300089AF9EF9DB3C5FA099453661EA12E0EB2E +:1071400044427CB5EE23BC02DE4E24C1DB89DEF076 +:10715000765F91F027FA64BEDAB08CABF1E59A6CF9 +:10716000E2E7BAF5D1212B75F469F6FFB3F963E9CB +:10717000DE1399FF5C53287F67CC9787F83DBDB538 +:1071800082F066C657CDDF1B092FEC7537DD3B3C1F +:1071900067109B77393C9F27FC9E735AA690FDFD94 +:1071A0005411DF17BCB016733F197B71AD93F9C151 +:1071B000F87E69AD87EA7F5CEBA5FAAB6B352A5F99 +:1071C0005B5B4AE5093BCF2B92FC058440F97DBB14 +:1071D000055FED2E92F19FEBBDE8E7AEF9FB4B1595 +:1071E00016127DC7A64F2A22BBDD902F527BA531F8 +:1071F0001FA4C326F2CDB6283EBC4FA62170A9A17C +:107200003D2B1D19AFA3FE11F92B0D9B33E91EBBBE +:107210006BA6661BDACFDADCCF506F2FD2F87D6A0F +:1072200035830CCFAFADBBD850AF17BF1FC1B42A49 +:10723000E21B19FF02CDCDF1E2E16D3F59393AFF72 +:107240004618FF93C3367A6FC6C7097B98F6F3E1F9 +:10725000871D3E8CEF9DC4F36F503FF94795F28B2D +:107260004EDA58D80322FEA4C23660C9AC9CAFCE19 +:107270001CE57C55F37795E13E9EFDD441F1C1C6F6 +:107280006D0A0BE3DD0C5D007918F7FA9F3868DDB5 +:10729000F3B7A92C48E7ABB4368C935FFFC8501FF7 +:1072A000C647E70C8A16E179C3AE5FA6F8F0DC5753 +:1072B0006307FFFE24ECCF33313F4A29A778C45F30 +:1072C000A7B52EB460BE9D7A3817F9F5AF4FF1DF40 +:1072D000355BBCEA8F951E80F392E7DA5EA9827176 +:1072E0004EB4AA34EE078F3976A8C4F7FE7CBCDF13 +:1072F00036BEEE08F929A614063E43F9FEFEC2C8C2 +:1073000008923F6BB87FBC277C60BD886FA4579DF7 +:107310003C8BEB371E7F0321548072A2D1E6A3B8C9 +:10732000EC89AD368A17823EA07C8313ADD9162E28 +:10733000879E22BA6BB06A76FDB80D5B553FFF7D24 +:107340000CCD8EF36577AA41361AEB3C3F22BC592F +:1073500009F2F88F11BFD7AD1A4DE7A2CD795CB213 +:10736000FC08782AA88B2B2D799AC77FD9A80EAB59 +:107370003ECF5DFA6758B0CA709FD1B281F7FE6008 +:107380001C94A7FCFCEAC5333BDD24273FB43C53E7 +:107390007923941F4C0BBF6B05BCBCA806870CC09F +:1073A000BC21CBD6ED0AC5558EFF00E3FEEF3F6151 +:1073B000F3111B8ABCB1253F5D4CF1A9E4F602F341 +:1073C000F2F875344FF1E2EDC48CF24566B336E164 +:1073D0005F88F03C039C04C0C7B38CC7C58E57B808 +:1073E0006FC5F3C38DA6F3C6C7C5398BAA01DC6E82 +:1073F00092FAFAC6015C0E345A387FB2BDFC1E4ABE +:10740000F97B71528E4B792BE575CD009EC722E535 +:107410002C636D245F168AFB92973DE6E0E78B3480 +:10742000E641382EE668621B0770BE5E627FE21E90 +:1074300024EB45AC9DF4DEFBB6C8C2F612FC7EC759 +:10744000862CFADEE68B201F47E4EFD159498E2CBB +:10745000627C9ECB5B954854E7EF90BF4FC2504F84 +:10746000E8E44E0FBD60D2070B84FE5BC04CF946CA +:10747000AD463D154873D3BA96B48A3CECEE79A973 +:10748000EC2CC6BB8291E7A6D3BC155F24C13C1689 +:10749000B1AE28DE8BBCFC717E8EC93C2FF33AFA6C +:1074A0003ACF85BE9913F17EE5EE714DF396F06605 +:1074B00078B04A870709F785610ECF857B14C2D75C +:1074C0009F85BD25CF079AF1BF8805A6A39C5B7455 +:1074D00017EC334BE2F420E960F193113A0FF80115 +:1074E0006B4D77013F2CDBF6E4AC31F0FDA2075E7B +:1074F000B423BDD7654587583261FF199E70474D4B +:107500005102BD6FD2F35F179C98F05BD177009763 +:10751000053B55CAA3D0B513790461E287A630FFB5 +:107520003DC1A697555F0B3C6DC29F392A3FFFF9BD +:107530004AB8FDB3E76DB66B760DE8DDAE31CB9B97 +:107540001E768D499FE2790ED49F5DB93C3FFD13B5 +:10755000AB3F238BE4B4490EE796D37DAC520E2F9C +:10756000147A508EB300F51FD4DFDDF68B74F46708 +:10757000FCF9AE5FE451BE06EA9B61717D73432363 +:107580001FEF865FA550BED45FA7B58F407BB0EEDE +:10759000C1E7D3F5F7BD7E5010FC03CA5BA91F9766 +:1075A000AB3B06E0EF1A4A397BCE7D5BB275BACFB2 +:1075B000B14EB7719D0DB84EDD399546B1CE7736D7 +:1075C000F3F51DDFCAD73BBFC73AC31457B9E1C7AC +:1075D0000E5F98EC8E28E9F5934FAA0CF759DD76EB +:1075E00087C90E38C35AB7233C96AF7EF54D2BD0D2 +:1075F000C5E20B003E400775773A48EF2FFE258F16 +:10760000A7BEAF54E75340FF4034FDBBF07C09D820 +:107610000B686FC4E7D16D077C3E406F07F4117EA5 +:107620002B845F6BC59EE7E977B4143FCFC75C211D +:10763000EFB5D96DBAD7464319C0CFF93B114FFD0D +:10764000CDF77171FFEC7F0FF978EE6AA2FFAE0BF8 +:10765000F4E7D89A53A336CC43EE7A52213B69F92A +:10766000F5D5E9D50CCFB771BF5A7E31D76F8ADF18 +:107670004FF9350EC06B2A8C5758ACF1FBAF340F65 +:10768000CF377F80D13D3A72BEE6E7E86F77A23E02 +:107690007459481F9AD73FA598EBCDE5AA85ECEB26 +:1076A00065766E67778AFB2B868A790C2DE6796082 +:1076B000C38BB99FA113ED4A8C777FC341BF63C4CD +:1076C000D844F2BB5B19A73FAB849BC7FA51377F05 +:1076D00093FDDCD51FE13497B5D3EF224EAF9AA9C5 +:1076E000E1798637F39C744F14FC09603FB3453F42 +:1076F000476CFCFCC29B3806AC6BB6F04FBF89D719 +:10770000A3C2F86F16D8C9AE0D3FED20BBE1965469 +:10771000EE3F64391956E4876B859C9A33CEE14776 +:10772000B93E7BDC2D012CA1BF300378D539BB36A7 +:1077300096C138EB2C5CDFAFCB62DC2FB0A1A3028B +:10774000E1770998C998BF0FABDF7536BB373A327E +:107750009E9F58867E86B18C135815C1D7505F66A0 +:10776000E7EFE73DF41F33EEEACFD81F306B0AF5A1 +:107770000CC208E9A23E83F6BF33F07C4116965650 +:10778000A2B7CBAD2C6CE1E56617DDABE435FC2E82 +:10779000EC55552C9A01EB8B1E329EEFB83A6A8954 +:1077A0000EC5789135BA0FE167716A360F8C13A850 +:1077B00051CA11EECBD6F76DBEAB1F7A6AC65DE338 +:1077C000A08EF779E13CBFAB50BED06C607AA4D3F9 +:1077D000B95676402DE7F8433A6CCED2C2D46E1536 +:1077E000A77379AE44E2A50CBAD7C377B6981FF455 +:1077F000B3391DBFB727F6AB7CBF58C6E3B8BDB6DB +:1078000054F0ED5249778F1BF935827C83FC84F666 +:1078100021C06DB62893D1FD83822F1E2CE6FBCCB0 +:107820002DC5729FD9B7F1963B5894D6FDB483F01D +:1078300028C79D21CAFB8BB9DD29E721E977215BA8 +:1078400049F93C0B859FC6029284F2835B7FCCFD95 +:1078500042A6BC23309428BF6DC94EF3739D9F4749 +:1078600035C825F29B2AF6AEF9383FE59B293EA4A0 +:10787000F7D9F636F20F98DBD9F0F75331EEB61997 +:10788000EC2A45C4CBA0EED8AAD0EF5ECCEEDF3513 +:107890001CF53948EBC9742E54D8DB0B057E1DE26C +:1078A0007EAB85685F615C0DED2B84D7366E575AD1 +:1078B000853DDCB0D5686FCCDEA0B33B7961B81FE5 +:1078C000C061CA53B709BBE32D7BD77094FBE6FBBD +:1078D00002DEB2F07584F318BF573387BFB70AFBD7 +:1078E00052D2D513C53643DC4D9E3BAD4379C5EF2F +:1078F0006D30E569B9E8FE983A85DFDF29FD906FC4 +:1079000088F214D8A1745FCEB1348A839BFD939D15 +:10791000D5EEB045E7A79C9371C374844F5DBADD83 +:107920008AE51BDDF78A75D0F8C73C03C9FED95438 +:107930003D721BE627FDF9A153339C45144D11E719 +:10794000A73E7D01F3E9AFFC02D643F5D80C3F8E8C +:10795000F36CD75C2788EEBF157F36C30A7ABEF377 +:10796000EEAEED58776B9600D56FEF1A80772EBB91 +:1079700023765E5F27FBB307304FB9F33E5E7FFF90 +:10798000217B00F39FEAC4B9A5BAB10AC9DF54C18B +:107990005FD2CF5467798697E3F9EFA29CAB5D9EE7 +:1079A00016482DCEC5FB504FD0EF2F940CF4A716E0 +:1079B00043BBF401C133582E99A984ED78DEFFE56D +:1079C000C80542AF25FC9D9054A1A70A4A02F4BD08 +:1079D000F4A3433F7FC7FECFD5CFFF016BCEE90AAB +:1079E00000800000000000001F8B08000000000065 +:1079F000000BD57D0D5C5455DAF8B973E70B6606BC +:107A0000464003F9700604B140470545A51A011127 +:107A10003FD041CD2CAD4634454341ABCDDDDC7785 +:107A20000651336B0BABB7DCB2763273ADD75A323B +:107A3000412C3F06B5D26C6B4C6AA9D4C532BFB29B +:107A400022D35DFAAFBBFECFF39C739939D7416D5A +:107A500077DFFDFD5EFCF93B3CF79C7BEE739EEF10 +:107A6000E739E75E2E5DA23F371312D94B43482E0C +:107A700021BFB7B9227B752764FAC2F46877162153 +:107A800051296E838DC2F3CA24AFBE3F21A4C5978E +:107A9000E1B210329E1067BD99904BFCFE4BAA7963 +:107AA000EEB35F368FF59F99E74FAA79EE94E8BD64 +:107AB00043E97FE2B0C1FD77A439B360DE7BFE8B82 +:107AC000B8611E52345C43061372AF91E0CF8FD57C +:107AD0005B338C39B4DD648825763AEEF56D29B3D5 +:107AE000E93C6431BD2981906F9A3FD3DBE83C0BC0 +:107AF0003A64E28C25A4AA43C276C196667D311D04 +:107B00005745DBC210FC2A39BE84B469275A82D794 +:107B100007D828BEDDE1FA6A6CEF79FDB4D64DC70F +:107B2000DDA3A93FF16C1CBD3C4C72BC6CBB7C9DC1 +:107B300009FCBEA38494D4675DDE3FC426617F5DEB +:107B4000BA7330AC339ECE01B0AC61EB558FF7F217 +:107B5000F9A64792BB5CB47FE6608BD146E99DDB1A +:107B6000E2AEB5503C66AFB50F94E91C03520A9CD7 +:107B7000301F99354CA057494F4202B03E6D7B0FE4 +:107B800042DB1FB7E746138AD7F498C07D64002113 +:107B90000FFA32EA8CC9848C7D868EE989B7380960 +:107BA000BDB7C4C061EF8DAEA27C0AFF4346F84E5C +:107BB000DB903A2F9D671FE043E7B963487624E9DD +:107BC00047A9673769ACD1F4E6E4190F021E770CB8 +:107BD000B9B118AE8F30583266207D09CA8733D9C3 +:107BE00035C596CBC613BA0EB7DEDFFD56BA0EF713 +:107BF000FBB2C34BD7E1EE6772FBC2D06D32A7C3B5 +:107C000083362BCAD13E0DC57360100FE5F9845839 +:107C1000EF0BD0F98E2F4D18B08ACEF7BBE411BF11 +:107C200082E729CFFF5DB27B4EE8F32946FDE0FAFB +:107C3000B5E2318BE3F12BE01B9DC7954FE58CD36B +:107C4000FA12FD3FB1C824C093C7C5126766109EE3 +:107C500032395180A74E4F13C6DF3EEB06A1BFD489 +:107C600010C8A93607E55B8D8FD25246215E559626 +:107C70008D5184A27864FB854FA7513DF97EBDEC00 +:107C80009028AE7377BCFCE9703AEA1C5D702CA5B5 +:107C9000DB392705E87ACF6D917D5E3BC887535B62 +:107CA000DA83900A988A8E9FBFFF4DFD08FA6B45D4 +:107CB000F59C71C0C7B93EDD976D21785E2017F540 +:107CC0002495EAC346F17A1579F407B91F407EBDC1 +:107CD0002B9BCE53AFEAAF1E759244C138ED976D22 +:107CE000CA3AE9F3171FB63FB63764DDCFD92C7116 +:107CF000276EA0BF0C24032FC9F0BCB3EFD215929E +:107D0000C2A666E453ED7ED901225A9B2C1189AE9E +:107D100073D416832F82AAD6B7DB8EE96D945E7F6B +:107D2000F5D81EDBAB03FDAF212416EE3BA66FA3F7 +:107D3000D787DB6C48A705DB7FD013CAF751DB1769 +:107D4000A25E17533B164DE527D04CB2B7D0F9BD14 +:107D5000768BE3653AFF3D2B4713328890E88E69B6 +:107D6000D856D68DC6F9E6774C4278418709E17D31 +:107D700091816242F1D8D7D88DD4523C3E92FD1900 +:107D8000CFC13C060BDA89D2C43B96C2BAF7457A1A +:107D9000B3EEA5CF2BFDC3A812A0EB822D9213E466 +:107DA000AC5426FBA418C03702E72B953FCE5948A8 +:107DB000AF8F2DB47835D1D84F08ED97075B5611AA +:107DC0000ACB7A6A2FC2C8E77BDCBEE8DA18DE236A +:107DD0003BCA703EA5FF8FB654945B05D6755FAF66 +:107DE0002D3707D7A36B93B01DD37103B6555BCA6C +:107DF000B436FA9CF7335F8A033AD1F1667758BB01 +:107E00003C249A84B15F4A6BE0F6781AD8633AEF63 +:107E1000DE54E757A087E397B4698D604FCD46EBFA +:107E2000CB540EC6E70DB0CD0E5997BCFB3662A3FE +:107E30007264886BD739E9FCD3681B6ABFEFEAC26A +:107E4000DF9CEEB4DF35B85EC52F91CC2584503968 +:107E5000BFD3CAF056F4EA533E5EB93F2031FDF07D +:107E600036187C2FD3DF8FA4BAFF06F8064690A9F8 +:107E70009BD19E0652CA2CFF3EFC297F8DC0FF2855 +:107E80006D1B89017F6657F0677A7D35FCBFB33182 +:107E9000FFFA914C16835C7C74F3CD0127C5ABF9D6 +:107EA000C14183C03F28CFEB66D7E338626DBF087E +:107EB000F25AB5D3645B45D7574A790370FB0E83FA +:107EC0006F9D1DAF13290E5AC33A89F65745B56702 +:107ED00080FF29DC15E107B96DDE15A1053FF24EE3 +:107EE000BABB9BBD3B5CEF532451F9766E376841BA +:107EF0000E7AD89C3170BD2B7CAF66C7147D54CBF5 +:107F0000997B25D33F37D7C3195C6ECBB91ECED032 +:107F10003AA21FA078DFF5814CC08E972F91B2B79F +:107F2000E4804DB338D243F450D1371DC8E52090DA +:107F30004F2697951DDDB87EDBF9BC4C0F4AA9830F +:107F400006FA94DED0CD07FABDA02316C729FAAAF7 +:107F5000E869629A7B04ACBBB496EA377D8E7B6994 +:107F6000420EE84B504EF45690272A27F1B343E4D3 +:107F7000A0B6F9272DC8892E5F423931D0B63044DA +:107F80008E5C9D718AB5B807C563FC32BB66150966 +:107F9000F617DB19FFAF55DE0771F92A37FBD3352A +:107FA000743E5D75846329C5EB5C9C0DEDD8A2879A +:107FB000294049B048E72A843863D16F2507D85F44 +:107FC000883FC0FE0C6EADD6BB43F0BBADA31FB166 +:107FD000513A4DEAE88DED8014F7647B2EF0670A84 +:107FE000A7633F6C892D4F03F8DC67647EE67CF560 +:107FF0004377C2F3CEFB0C0E781E21798CDF1CDF99 +:108000005CA7E3BA0700BF0F74E4453AFE54845BF3 +:1080100006BD3C954CAC4F521467AEA17CA6F39EB6 +:10802000D211AF95F2731685DD007723CE6E034132 +:10803000EFE83A43FCCA056D5D0A49A3FC5DF4A76D +:10804000A35A6A0AE76604FAF9E973A78F60FEFF8C +:10805000EC7A1DFAFFCAE68F076B68FF19BBF33A8B +:10806000426DEFE89EEE05C0D779137DAFEB287C1B +:10807000CF6FDE8C1A6A0BD2B35EEB4FD7D2FBEB1D +:10808000291DBD14AFFA47E5121F8B7B4C65D957EC +:1080900097EB791D69481FC5DF28F67BAB279E2E1D +:1080A0002268C7AFE68714F99ECFF5603EE8010964 +:1080B000F53765AE1120879992239D84FA1BA60F90 +:1080C0008A9DA6F28E7A539A96ECA82541BBADF60E +:1080D000477BE4FA2787D1F52E4D75FB80DF05FF3E +:1080E000F3B7373FA75D959B5F29023E8DB84122CC +:1080F000B2742D76F2271DDAC9256504ED246D438F +:10810000EDA4AE8B38FD65FBCFB3F34FF2F134BE77 +:10811000C5B811EC78E87C47520BB6C23AB6DB25FD +:1081200036DFBF096FB57DDFDEA9AFD766DF5FE55C +:10813000785FCDBE7FC4EDBBDA9E133A1FD8F3EF54 +:1081400077F4F581BD3F4AA8FD07FFB6DD647B9952 +:10815000DB7BF40791D1BE2BD9FBBAF4991F756173 +:10816000EF0340B77FD5DE2BF2A5D607B51EA8E5F5 +:108170007EEC2334FE023E6D9508D8D760BC455096 +:108180008EF7A5323956F42624FE423F4FF5C197AB +:108190006EBF5C2F7FACFE538E0DF2CD1CCB002248 +:1081A00005E55DD11745DED57E644EAA5B4ACD0D4F +:1081B000EA49E566B51FE84A9EB6E9207FD555FE37 +:1081C000C0FC006D43FD4057F18E3EF5E7E9C179F3 +:1081D000FBB5C50B09A97A9CF77F519E12804E61B1 +:1081E000E4A967EABF204F57E023FA1945CEC61E1F +:1081F00060F241D258BC4FE505F1DEA74FF6D5DA63 +:10820000C1EE317B38F612A9067ADEC5EB098ABCCD +:1082100016A5B96F0AE533C4F710B75F6B5C382D4C +:10822000AE9A38E9F5BB681B6A370CC0BF30F17DE8 +:1082300061EACFF3F30352AF8DCF93399FFF8D7176 +:10824000E15DA961EC047132FF1FE48B6112C8CDBE +:108250008F7E2D01FDEA8AAFBA358CEE0ABCDCAF09 +:1082600055FC6B2CF8572A2FEED47F21DE2C2DAC39 +:108270003F6FA4A1DF7FAD1B5EA61D4AF3F43CC295 +:10828000EB1FF9AB9D5AB02FF4F7613823D6473E68 +:108290009239ECBDF16011C563EC939DFD5EE81F62 +:1082A000991FDD594F81544219FFEB75C30E3E8A69 +:1082B00078D7313EBADBB4AEEC103887C2961038AE +:1082C0004F05AF65E3C18F58711E1FB3F7747E6908 +:1082D00020C0CA7C5C0F487B71378817B74856A806 +:1082E00087DC9EFFBD1EF8535AD8F66E225DEFEA7A +:1082F000754565E6BEF43AD8418AEF8BEBC6ADF61C +:108300006AF9FD3DB03E863F867AC929533E55E65F +:1083100049BE54FBE5747C3155F467F0A315EF2793 +:10832000FA9C9F773FE82FDE9F8AF7FB0D3FE3F92A +:10833000B7E613A72F8C9DFC8362272F5258999F75 +:10834000D26E523DCBC3D5E3B7F2F1018D663EA1AB +:10835000F4DAB5CEBD1AEA652309938FE6757795F1 +:1083600079991C12A76ABD57C2F7E55431BF831F24 +:108370009B78BFFF4AF4FA9FCBE8C5E5A3429497E8 +:1083800068AD6BEF8F148FE838C90A71ED0257C4DE +:10839000A310BF97162AF23DAFCC9944D71741845A +:1083A000FA5F50BEEF292BA274594094F1F3578322 +:1083B0005F72693AC73379DF2E75DE9F49E5074B57 +:1083C00071F4FE2FD655AEF666213FB01F61ED1554 +:1083D000E4BD5E05E7ABF483CB37EA27D86D4A9F4F +:1083E000F43076A383D3E75B894C05BB172860F193 +:1083F0005E2095B5F1692CBE23696C9C318DF339F3 +:1084000032840E49413ED31F3FE41121EB463ADD51 +:1084100016A7ACFBD1B271745D8118922D513989C8 +:10842000495BB97A59889CC4A53D8A72129C6FD564 +:1084300041A0E36D9C4EF1698F1CE4722481DECD76 +:108440004781A072B045F2CA749DF3410EC2ACF3ED +:10845000CBCBE5C8ABBADFA9BBC2FDA72EBFDFA956 +:10846000BA9FE8E27ECEFD9C4FE3547C2C51F1B1E3 +:1084700048054F57609F60CF143B57DEB47A798F21 +:1084800038A8374AE026C05EEBA5018464BFF4DF5C +:1084900065E60490579B2E91DAFC012F3D73D0487E +:1084A000ED5919D83394DF35AB9DBDA97E83BE232A +:1084B000FCDB32677F909FEAE5F174FC90979E5D4C +:1084C0006DA4436F5FB65A0731CDF097D6AED6D2C2 +:1084D000796FCBF9C3BB309FB6E68583E3A42BC885 +:1084E0006B9D6A1D6B55B05735FEA9ABD8F765AAD1 +:1084F000FB97A8FA1F55C16B54F04AF1FE19B3243B +:10850000D49319947F40B8ABE94D595A679ED1E98D +:10851000CF2433C64982DC8FAD65F0B4973695AD74 +:108520003487C069AF9781BE2B72AC23EC675A1CAD +:10853000F182FFD07561CF46A7752147996A7FC741 +:10854000FAFF0CBF26E03E8BE097F7C822DC2C2B0D +:10855000786F3F785F165C54E0B7CBA07ED1E5BE64 +:1085600007D95606FB1E631FE7B0B7A90CE23465B6 +:108570009DCAF8E2BF5F92E1790BD39ACAD6C3BE17 +:108580004A813F1DEAF5D363584BFD8C0C7EAC8AC3 +:10859000D73B8A77C82EF033D323FDE98BB242D67E +:1085A00049EA33609DCD0FCAC81F6F2DCB47CA89DA +:1085B000430FF58AE6E8E8C51BE8F83D0FCA8BC112 +:1085C000AF1D5D1CDB03F289DD692CDFDB13DDAB46 +:1085D000C7DD146E36DDA5877A6DF34323B1DD2D3B +:1085E0003B57B453397EFCA5F7D0CF379BA2913EC1 +:1085F0008FA4ED29ABA17AF1589A0DEF77C7587B7C +:108600003441BCBA4A47A05E4D88E305949BDF180D +:1086100006ACA278CCA8B901F78FCAFFBBAC3881F1 +:108620008E2B5FAEC37D05FAD30FF076AF1AA98704 +:10863000FE59CB78EB1D85EDAE7FBC79A01F1DDF09 +:10864000FEB0EC584707EFEC488D2AA7787D15C19E +:10865000ECF097677B47019E7D7ABB9F4DA37C9D85 +:1086600011658994C079586D5113E9BCBDD39DCF74 +:10867000A5E506C7EFFA878CFB606F9F2DEF01FC25 +:108680007B99DBEF9D1DE53DCA43FCFDEC6FB548D2 +:10869000E75D7ADB7D105FEE8A4C96BCA8C7F5B12A +:1086A00050B79DC5E36B2A2F8BDF0CE3F79F4893F0 +:1086B00071DEE386C5E42B2AC4CD8F74CF073C95C9 +:1086C000FB94FD375D926D60681CBDAE57C11BB059 +:1086D0008EA09C1D3D087283713485B7BFF4F96A82 +:1086E0002FF8C23D34FE073CE29CC5E007C8925813 +:1086F000B60F1A5F9F115A8F08C6A94BB93D60E3A8 +:108700008E782D98B71ED914E1837CE688F70B4B41 +:1087100068FD5DD1933951162F38E393168B16E817 +:108720007A54EB39F14BD8377C5E877674F6F3DDFB +:1087300097B4833DA0FC847A90FAB93D7AEB709EA1 +:10874000AEF707BF11F5847C53E63477AD279FBEA3 +:1087500074A66CBDB96B3D99C3E3F6E2E7752E9044 +:10876000F339B9162DECD3153CFFCECB208F731601 +:10877000460C3450C4E73C6F40FEB6592C5E2BECDF +:10878000234659B4DD68FB0D9787B69A08CC53E4AD +:108790001E7AB47BF28A5C1BD0A750265A23F52B95 +:1087A0007294C3E662F032A81B2EB7E4D980BFB141 +:1087B000BD993E74F6474F1D23F50BEE9B9D5EFC65 +:1087C000E4D343287E67886FCA10FBBFBE8F56452F +:1087D0005CD1507FFCDFDA47D3F6B6C49DA0A97800 +:1087E000701F2D2BFA5610BFC532E22D2F8DF001D0 +:1087F0003DE514E627461109F7D18895AE3F3BB811 +:108800008F26FF6A10D2E7B887CA551F4A972823D8 +:108810008E977F25FB0CF4B985B1ACDE2A3F5D460F +:10882000605F8DD2D56BA5F0A8B86ADC5FF3829D3E +:1088300001FD9688AB1EF5DF910279F2ECE72390FB +:108840008F735E98FBE96F73806FA571A1FAD48B6B +:10885000CB1F9D8F186382F39CACF9750AE053F827 +:108860003B9A5F42DE29BB9FBE0DEDA609F7DB8870 +:10887000B5ED3743405E6A4C03A04E3EE7F9849461 +:10888000D4ACE0FD73963E98C1EEA7796B14D8ADD9 +:10889000085C4FE51603CACB8C876527FAC9643D8F +:1088A000FAC92F9745205C999487FA3643C3F6DFBF +:1088B000684C188FF69D919C549A89F34D33D8FBE0 +:1088C000470332E38F97F34D0FFC19D63B169F7F7A +:1088D00017D098FAAFDB7B73BA68981C919D12EEA3 +:1088E0003711526D033B305D23A1BD53EBE5D8DE5C +:1088F0006C9F6F468AE34EB86FFE6306C7523BC358 +:108900004156F0A179D37C4D6036EC43924603D6B4 +:1089100037AAE83A22A2D8B987CD14FF2A2DD1EA86 +:10892000A13E6563764DC1A7CA56360AE495F6B7EF +:108930006A69FF7C0BB3CBF3BBB1BA0FB1187D2FC3 +:10894000873E0F704E63F7D9A240DF86A2BC80FE3F +:108950006B68FFF784F51746E5D9DAB270FF7E251C +:10896000D44B009FBEFD429E4BE1847E208F0BB511 +:10897000A916E043EC94A9F0BCD764B44F54A91EE7 +:10898000CB8338F0357910E4B3331EDE53BC06E0F8 +:10899000370658018519AF1F423F750F97B33688C8 +:1089A000FFC16F51F80DDADEDB9BD907B7CCEA398E +:1089B000F7F69684FD50A57FFEC33AE4C7FCE54C6C +:1089C0001EE6D7FC09E79D6F09F4007ECC6FD00D41 +:1089D00006B95EC2ED45794D727E2B958F725DB4FE +:1089E00055A2972ABDA57A802BEB248495E7CD7FED +:1089F000F8931E9A2C361FB4062E47C179BBA78068 +:108A00005FFB66536CCA8C10BE7FB36C6B14EC6B4F +:108A10007F15E14FB7423D666184631DEA29E3C7D4 +:108A200037CBD2D741BD6696356081FDF059F7A5A9 +:108A3000C580BF3B6AF5EBA1FF68BD5D03B0D36A9B +:108A4000CD07D8A9ED8FF037FC9C0AFE503E2D9043 +:108A500098DC546EDAA34FA5CF7B91D3E7DBD70E1A +:108A60006540DD607E4A2003FC3095AB8C44E0CB52 +:108A7000AB12C60B0B36C9CE887E41B95A0072457F +:108A8000F57F1E97AB055BB63E007ABA00E469E05D +:108A9000E57249F3CBBD787DF38BC584DDBF17E468 +:108AA0004EF1FB145EA683FA9A9EC3F43900AFE33D +:108AB000F4A7FD45ACDF9B85FE84B4E9212EAE9280 +:108AC00059BC40F5291EE289AA269DB72DC43E2E29 +:108AD00080FEAC607F5772B3A737DF2FAB31A05F4A +:108AE000DAC3F5AFEDE18628908B6F5FDBF3EE30F4 +:108AF000C8B3364B56B0FB97E921A75B15D0290ABE +:108B0000D789F15115D0252A48A74E7DE3725145EA +:108B1000181D14BA5469399D947E7EFF5E4E874AB3 +:108B2000C2E9BAA50FD377AEDF5462D08F28EB73BA +:108B3000C788E7072EF0F57DCCDB4A2A378E2C94C8 +:108B40002FA77E30CFFF69D7B76FBC88F523859FED +:108B50000ADE96749B62A79DDD62827C6ED3908A4A +:108B600070F5EA539C7E3A33B32BC76A12EF5C4C24 +:108B7000E9376F93EC40E241EE15F25C83A6CD82BB +:108B8000F1E9AF642BACABF07FCAC6C0BA15B9D35C +:108B90006D94B44DB04F48BA21FD15FC0AAF738DEA +:108BA000E9C6E4CE0FF828781E93FCC82FEF1B927D +:108BB00095C5BB6D7AA8232A7AAAC6F702C7578E35 +:108BC000928649FD011F870DF49B503F88F8985B02 +:108BD0001FC4E7798F3C68EF177CCE51AF450BE39C +:108BE0008E12660714B93CC6EB12C7966FC578584B +:108BF000798E29FDB2E7B817C75DFE1C65BC9CCE17 +:108C0000F453D18B7D314CFE0B97FD09C7297616A5 +:108C10007EA01EA7D053A15B885E0AF451F44BD10D +:108C20002785AFFFAC5E9125DD316E7D88AF1B756A +:108C3000A447D02F807C82BF33E8D939B810BF89D0 +:108C400071CDA8A41FF4EE30D7153AA9AF07F32AC7 +:108C50006B0AD07F94391EF7CBC9B2F8BDBD43E291 +:108C6000B3AFA0EE05F6F415D987F69450AD0CF12C +:108C7000E74ADC56B370947504C8D72609CF1D297E +:108C8000FE9BFE3CDA29A774BE8A9C8519104FAC66 +:108C90004C4F65FE2CCE791AEEAF3C15288EB205EE +:108CA000F3971BCFFBE568A80F6EB10BF943E5D92D +:108CB000BDA8E7F3496005E4BB331E3E543A04F80F +:108CC000FF8A0ECF2FCCAAB3A3FF3BBD7EE6204880 +:108CD0006D672C4F4778EECB7733F86116D7CD58B8 +:108CE0009EBB01EAF35F45388B41CEDB574B56C83C +:108CF000BF86BF9CBBE476DA3FDCD2AB1BE07B6473 +:108D0000FD57A5C3208F582CA3DE38D73F3905FA6D +:108D10009D4DB20396388B5897DC0E72AE8D46BDD2 +:108D200053CE35D6EA98BCCD4C67FE725A3AB31B87 +:108D3000D3B8FC16D6D666C0B982F617A99F82FDB5 +:108D400075BDADDE0F79E08EEB1CEBE873AA68DA37 +:108D50001A4FE5E994C4E2F10A3D31827CEDD70572 +:108D6000EE07FCF7DF6F19500308C8170797B3BC6D +:108D70001DED0CCDA3F0B90ABD94E797F3E72AF3F4 +:108D800028F7ED83B80AFC08C7F7F4B257A640BC31 +:108D9000707A637A0C09A1FB695817A5F75C6A1F02 +:108DA0003787C907ABD2957AAB0FDB0A5E47DCAFDA +:108DB000AB4B82FD5C1AD71F0F8DCF4FBE186104DD +:108DC000B9A471BD785DC7FC0A8DE785EB547F04BB +:108DD000B833DF93A747BBC3D823A555C7FB4BD3F5 +:108DE000CDAA73732CDE57F44F7DBF12DF77D65DAB +:108DF0007AFFBC735D673D9431542186417046EF24 +:108E00002F32FDFD4D387F39BBCE603550FA1E073D +:108E1000FD827DC10699C58B46A66FC7770CF041D0 +:108E20005D61F661E2F05378768BECB0D1F17B575F +:108E30003F84E73BEE5E2B91EBA490BCEBA9D553AE +:108E400040DDCE39DC2B12E8F8731BD97914DA6DCA +:108E500056E55BEF26D8BACEB7FE5D7996527F52C3 +:108E6000D37F733ACFB71CC421D29FE5EDBBA818BE +:108E7000E50DBC9CFE673D6ECCABBEF354603BB4CD +:108E8000FEC5C244BA8EEFA5638F0D073DB24463A1 +:108E9000FDE4ACA71A3707BF6B1A74713CA5D3DB8E +:108EA000E6682BD88FEF3C8BF17AA7DC7039BD7167 +:108EB0004BB39C4870FCF6E174FC4E73346C7784C1 +:108EC000D987637C569FBFB977E190EBE0BAB2DEF9 +:108ED00033BF64FC56F03FB3716614C4ABCDCFC54D +:108EE0006E1F0A7C36455B4114E6F0733827D63096 +:108EF0007B74CA18BD611CA5DBA9B5937A407E7846 +:108F0000B7AE5DEFA0F33A769445417DE46B6D5BBF +:108F100094155A3ADE0F78687D32D8C1612504F77E +:108F20000787F9B5C466C7AD7B949FA167B53EC8F6 +:108F30009BBF817D43F0E31723D9FE3DDF0FBC7B50 +:108F40001BABB375D655787D61385F6F74468CB2B4 +:108F50000F84D70BF3D8F5936BDF1C0FF39D5EAF37 +:108F6000B302BEDFADD7E1FCF3687EAFA1F2786A51 +:108F7000233B2F306F3BCD93ED60472494DF795432 +:108F80007E8D207F0B754E7DF4E57259B891E5D743 +:108F9000F3EA25CCB715F99CE7F41523DDB99C1A43 +:108FA000E9BF4BD4757423F52B801E5DC9EB3F5B85 +:108FB0000FD06784AF07A8E541A19B22174139254F +:108FC000289F0AFF63EA078C48C41BBC484F6F0107 +:108FD000C98478A1564F32E13C945713E900BDFF94 +:108FE0006B44543FA8432D36B2F681C8A875D0FE15 +:108FF0003522C50778FF55637D07F2AC5F67D871EE +:109000009E07649B4EA2BF4E8A6B2B423750A871BD +:109010006AC00FD61AD08EA8ED505A06F33FDB3344 +:1090200008CAFDCD19EC9CB88E54637CA1B4341EE3 +:109030004886F8A5CC1473018E923B36F49804FB55 +:10904000BD65C363EE4FA39167DE86A4495A2AE744 +:109050006583621A52293C2C2391F5F78FC9D551AB +:10906000B8A626795211856FCD70F6CB08798E326D +:109070002FBD3E2083E23132C19D03FD557AF34A74 +:10908000F003DF4BED0B347270FC41891C7D5B0AF1 +:10909000C26D3A9202F1F6CD807FF7AEDB1519CEA4 +:1090A0001B33C25C2F276439D425CABDEFB54A688B +:1090B000CF88CB48F93981CB5FB9D1EC473BB75268 +:1090C00077B6533E52C14E456B81EFE339DB2768DB +:1090D000FDCD707F5FB2CC7AC288A1E2DA4BB15D80 +:1090E000DB7FAAA8E484321F5DDFF73ABA5ECA5775 +:1090F000C949794D554CA2449E4EED9DB4FDBD9F8E +:1091000060DE5A2F698B403E4CB7829F92885B731A +:1091100089B6F34D542EFA434BE5818E5BD4F0EDC6 +:109120005E508BB94A9CE5CEC378F13E2B5B0F7144 +:109130000F4379BD9FCBEB490FA98652D1844020C4 +:109140000A8EC29E1DEFCF00FB5022BB6703BD4EAF +:10915000AEAD4D5A44E5E7DBCD06C7383AFE94EF95 +:10916000CD28F0AB953CDE271765FFCDB47F9FBDC2 +:10917000EFBA5521F25595C1FCFE59BB3FE541B010 +:10918000337696AF928B7B521EA4E34B5247E7AEE9 +:10919000422A381766E0BE05DBAF18AF0D7F7E634D +:1091A00072128B53C87AE68F0D5AE2B5C4604BA297 +:1091B000289D46535CF2E05C2A8565DCCFF7E1F33D +:1091C000615C14C435B699F16CBF87B8C06E29FCD8 +:1091D00055F876193F29CA10D76B8C4407EBED4B35 +:1091E000D65A41FF15BE9EE4FA78D2C8F470A46C3A +:1091F000463BB5A881D5F51649CCDE2EDA21B1FA69 +:10920000E665FEB66105D8E48AB533D19E2976CCF1 +:1092100046FF817CCDB3BAA2FDB67FC2EFAE2DBCB6 +:10922000267BE653ECD9003200E4EF6AF19262C784 +:10923000287B7E9F11B29F7C557E01C9E8BAE770FA +:109240001C47CAD36D5AA04B77A303ECF9A2E7D30E +:10925000D04F92F36BB08EA28C236B63517E57D8A4 +:1092600065E46B695322B1D14B739B243C273BAE21 +:109270002916E1A88E04844B7F7F5D01ACBB731F70 +:10928000F4F77D103EBDE1408E9BD5698C80878BC5 +:10929000287864D583FF3967A678503ABBCC2BB1C8 +:1092A000EEE8229DF990744902984A0DE89D53E733 +:1092B00065FC31D6A0FEF3752DE27AB5683FF3D791 +:1092C0008B46B0FD42ADB76F34F05FB74F263E0A14 +:1092D000DFB25FCEF5D3A1B5DC9E1BE235C416C26A +:1092E000B7085B24B185F087789D01C8B7A672796D +:1092F000792882D97D53668C306EAA7936CA4F2080 +:10930000A5781FACD7E2E829CC4BDC2C3E56E46AAA +:109310000AAF9B8F27EDCBC04FDE3295F687CCA7E7 +:10932000CBFF01FD862E5F8CAB295D8E5F499ECE03 +:1093300064F0F74EFA92BE284F2AFA50FD407F7F24 +:10934000AE85BD7F42A39267F2293C659F8EF86887 +:10935000FF724E17885B21FF39E7B4A0DE28721731 +:1093600000BF47ED5C749E48B76E4E916EB12522EA +:109370007DBABB447A5C373555E84F705F2FF427D0 +:10938000560C14E0E4EA61C2F85E8B0B04D8EE1DC3 +:10939000238C4F5B395180D3EB6E17C6F759532E90 +:1093A000F4F7F5CD13FA6FD8B84880B3EB7F258C6E +:1093B000EFDFB454E81FE05F25F40FDAF78400E72D +:1093C000069E15C60F695D27F40F6D7B55E81F7E5D +:1093D0006AB300DFD8FE9630FEE68EDD023C821CCA +:1093E00010C6171A0F09F048EB17C2F851F15F09C0 +:1093F000FDA36DDF08FD63337F14E0E53CCE2975E6 +:10940000FC4DB82F4096A5831CA725B987F7C1BA94 +:10941000CF292DE85FEB1D128985FC67DF242BEA3D +:10942000FDCFCC030BFB70BBC8E5F80231DF09E7C9 +:10943000D9AF6617ED3C9E18298FC3F7AACED5B3D6 +:109440007A87DAAF2BF15C3475CBDA90E776731A52 +:1094500069421F84634BAC02DCDD152F8CBF6EAA02 +:109460004DE84F70670AFD89150E014EAECE13C64A +:10947000F75AEC1460BBB744189FB6D225C0E97503 +:109480005385F17DD6B885FEBEBE0AA1FF868DD577 +:10949000029C5DBF5818DFBFC92BF40FF0AF14FA60 +:1094A00007EDAB13E0DCC01A61FC90569FD03FB4CF +:1094B0006DA3D03FFC54BD00DFD8DE248CBFB9C300 +:1094C0002FC023C87E617CA1F1A0008FB47E268CC2 +:1094D0001F157F4CE81F6D3B2DF4577EE3F0E3BE74 +:1094E000D4DBEC7D57259E1B9BF983304E1747E359 +:1094F0007DA87F9348079CF7EF2ACE57E2C052C75A +:109500004FC273FFAA61F1F9AB7DD8FB690FC82C7C +:109510004EACF5BAF07C5E0C1C78A57A12ED955035 +:10952000FE20C59A8EF5C838F4B7E8326D70DE8D2E +:10953000C6411488D1D8ED90879882716CD2A5412C +:10954000D71EC736F52188C7C93EEED7402FE7D5CD +:10955000BF510C79CE5CE25D017850BF1B0DFB580A +:109560001F4688F528A51D6DA4740C79DEFE88BA07 +:10957000A48157D0DFD1C6B338BE735E5EAF92E828 +:10958000FA1685CCFF18CDBFB4544FEB3C54CF68CE +:10959000A2FD84C78AF0539E78849FF6D8B05DE31D +:1095A000C9C4F6598F03FBD77AF2107EC1E344D8C1 +:1095B000E729C1769DC785D7D77BA622BCC1E3C664 +:1095C00076A3A702DB573DD5D8BFC9B318E1D73D75 +:1095D0005E6CEB3D2BF1FA664F1DC25B3C6B106E6F +:1095E000F4F8B06DF26CC4F62D4F3DF66FF73421F0 +:1095F000BCD3E347D8EFD987F06E4F00E1BD9E564C +:1096000084DFF5B461BBCF730ADBF73DEDD8FF8192 +:10961000A703E1B37C3FE1EB3EE2BE9D021352841F +:10962000F2A0C4BFE321EF01E1C8D37D27E43DAA46 +:10963000FC43CD8F33FC39BA021AFE42FCD33363AC +:109640005D6D485EF0037FDE4391C41B41F5A1468A +:10965000C3EA02353104DF0F233C3E9FC3E592C4C9 +:10966000B1B87C36C76B0ED7835C90CF4C94CF0FCC +:109670007E4E9EA5E4DB51296E2993E2312F59E3FA +:10968000C5BA8399BD873F20C5AD85EBE7AAEF7EBC +:10969000179F677564C0434A0DFEEEB7423D69BF30 +:1096A0008C75D8AE9E57C5DF93E8B27FE7E924F00A +:1096B0004725FF90B15EFFA1CE3215EA2D3D32194C +:1096C0005D7A646A84F6AD145777C0E7647AF586EC +:1096D0007BA5E0FBFF132035A77A5E466C3A3C87FA +:1096E0004B9CEFC0AB37B7D0800FE05B89175B674F +:1096F000B23B25B33B9C97F421EC1E664809B71E8C +:10970000353E99992C7ECFCCD408ED9F525C7D00DC +:109710009FE3E94E011F732F1B3F57DFFE02E0F569 +:10972000971D3F9C90D282F456EA1B2B46F0735A49 +:109730000B25651F9CC58946A2C489D83FFD7E566E +:10974000EF51FCE5E1CE96D9C373D53AB49BD3A5CE +:109750004807C4DBE7AAEFEF0FFB8577D07C0FF655 +:109760004F153B3A9DC21A0A4F27ECDCC5F4C316CD +:109770009433B57DA5F711D8EF9B4E4906F9E3A5C3 +:10978000143BAEE743D70F3A9897C4B5E37BAB548D +:109790006E4A809EF386CAF8FD860F35BE0C494698 +:1097A00079D14B14FF3971545EC2C40B8A5C2CE032 +:1097B000EFE528D7A9BC4D047A7EB76D4826EED3D5 +:1097C000EC1C6A037AD66AD87B75DEF765762E03C1 +:1097D0004AF9706E243AEB457CBF00820BE0DF5003 +:1097E0000BBE5FD02C93C56F84B1A7F772B9FA3066 +:1097F0005E57E2C379C57DC54ACED74ACEEFD2DDEA +:10980000FB93E1BDC105FB749817919CB62C57984A +:109810007355558B1FF945EF1039AF6A3AC6CE63C1 +:1098200091B6ACD073588FF07915F992F516F78B85 +:10983000E650FC3AE57C11D095CAF90988FBC71BB4 +:109840006CD1B7D25BDB2869FCB475FFCE8AE7F92F +:1098500094737DB3880BDB3994DD20D72EEF6A7CBF +:10986000AF7E1EA9C7EB0BF266A6005C45DA8BE261 +:10987000E97CB7ACAC79279E6237A96EF548A8732E +:109880004FF4CD7807DAB2F5D209AF0DF5A416F88A +:10989000D026552FEF499F77FBA611CBA18E3C5EBA +:1098A000667C2007181FA83C39E598CBD747F5629E +:1098B00015E04FF502F157F462FA52E294E282EFBA +:1098C0008174EA49DE3D7F4E843D166D3B9E43A97F +:1098D000DA698881FAC93CC2FC76B00EC4FCB5A234 +:1098E0000767748CEF675E93F03D9B3312C1EF39CD +:1098F00074153728F127D53FA677474D4CFE655E96 +:10990000D74B71C70F4C0BFAE7331ADFE0A834F4DA +:10991000DF1B801EBA02F7A303E0BCDEEB92A39626 +:10992000E272A69B2F859D13E8F403E49229582741 +:109930007C4CC7EA76EA7857594757781AF4C40B33 +:10994000FB5952DEBB3F411C7239BEEEF8C1942E6A +:10995000B5C022A84B16B86CE1F058C69FBFEFEF18 +:109960002C1FF726133C17A4A6A76465CFE9AABE4F +:109970006A8864F8287E4AC1F372BC18BF0E66324A +:109980007BA1E0478835D34A9FAFD5463A405FCBAD +:10999000B4EE00C887527F53F2E27DF693E80FC819 +:1099A000C5DA2476FED8DF951F3EDB998FA706FD2A +:1099B000A452C722F9E1EB912EA315EDD744E24062 +:1099C0007FD1971C56E885752C197608B1CEEBC669 +:1099D0007518C05ED33602EA28E82F7DB82E13E052 +:1099E00085EB0A404584AC3645211D86B512B4D3BB +:1099F000C3600D74BD3B8E111F9CA76ABE30A5D0FD +:109A000042FB777CABC53CE819D3EB89F01D891D7F +:109A1000A73F4D847A4FCD854684079F2D3ECDEAE2 +:109A20006787A7C17C6F9FD7DB0C18072C443A28A7 +:109A300075CAB70971C03E68DE67667CCF38B7A5C6 +:109A4000DE8474E375B57CBEEEFCF3AC1EB213800D +:109A5000A1340F68D7137F48BCACB38A701E09814C +:109A6000EDF0480A87D4397E6EFE68EACBEB2043DE +:109A7000C890D0BA1AE98809FB3E957A1F3147622F +:109A8000789FC874C5F5C5B86CA2CCE8FD0F19E87D +:109A900075B3D99700F16DF3DC0D0910EF3E63FA51 +:109AA00007D2F1D9BFEB1380AE7523FE827EA48E60 +:109AB000DE1B80FC57EB8B2058FF9A8F75E09BB91B +:109AC0009F7DF6E297249ED2B32E8FA0FF24DC0F59 +:109AD0002BFD7517CF55003F2FE41B6D60173278B3 +:109AE0003DB4E6A6FF17DF16428F1D34AEF65306CF +:109AF000BF4DE36A3F8DFDB7D1B81A6078EF14DA35 +:109B0000061A5743EBA37135B42FD0B81AC6415C7F +:109B10000DEDB334AE86760D8DABA17D9AC6D530F2 +:109B2000EE291A5743FB048DABE17ADDC5F242C43E +:109B3000A795E0FBF54B4D511AB0AF14FF48A80BA9 +:109B40007DE41C1809F4B8E9BC46E06FFED9480171 +:109B50001E763C26C85FE0FFE19E42FFE09654A1DE +:109B6000DFEEBD5E807B2D1E28C0501F0ABD3FB1B9 +:109B7000A2408013DC6384F1D74D9D28C0DD5DB722 +:109B80000BE3634BCA85FEC7A3547CF4556A443E7D +:109B9000B2EF2B5CC837E3F9CAAEE4F409CE17057F +:109BA0007EF297F2D47075DBB97D35423ED093E3F7 +:109BB000B6B0AF0DAFEF3D32E4958C1CE087866DFB +:109BC0009B3ADB4DBD295F329ED410385788270E53 +:109BD000287E567EDF9305E74C20977B4AF511C01F +:109BE0009F5DCE8248809796EA1342E5A8CEEE1E8E +:109BF00088EF29B8D9FA94FB1F2F9878C57DF427F0 +:109C000040FEFA5CA17FCCBC54D087CBE8482A70D8 +:109C1000BF3648C789F87D27E2AE10F057EB0581C3 +:109C20004DFA0478AE51A4A733F561A0C3B34F69D0 +:109C3000F11C56E77CFC7E65BE91F245535BD6E590 +:109C4000F8EF72B2F134FE8D00BAD06709F8C5386A +:109C50006C23803EBFE5FAF6DF5CDF9EE17C853C4D +:109C600016606265F7297CABAB78627406E84D1E1E +:109C7000C36BDDE427243037B1C451630DA1EB532E +:109C80001C8F17F8BAD6C2BC14EE3ED92901FD527A +:109C900016BB24D0B75E4BDA107E96EB7752753B3D +:109CA0005E4FBECF8F6DCF8A00F68F9437E13A3A80 +:109CB000E9E010E9A8E6938FAF47993778FFE6FD12 +:109CC000206F179C0CFF28AFD909FE22CA6B75B014 +:109CD000D6C65B8703EC7E94D7C9E1EA2C801BF8DB +:109CE000BAA2BC5E847D7C5D751571FB37D882CFCE +:109CF00023B62A4DA8BFE94A9E9A38FD1B399DD448 +:109D0000F735E8BC83AC61F44A69157F3AB44D235A +:109D1000E8F99056D14E7D04BF303FF0495F881B73 +:109D2000BC2E99EF5F211D2775E64BD3519E569BA4 +:109D3000EE3C00F9F6E41699307F3BFE1DB09787A4 +:109D4000461BD09F368F1E951C2A77CA3AB672BA28 +:109D50000FF53A8FDC47C797B90C8021755FCEE4C9 +:109D6000FBE97CAE71B203F6A15A3AFD89CBC4CEB1 +:109D70003B307F3291E3BC7BDCA447E0F9875AA8F3 +:109D80005DB005F154FA1B4A268DCD063E06181F1C +:109D9000BBA2CF7B9C5FEF70BCF6707E3573F9DEA3 +:109DA000C5FDC90EEE4FDE067F6200BF93C7D7C365 +:109DB000FC4903F7277F047F42DB03DC9FEC077F2E +:109DC00042DB9CD169456837E12536F4273441C12F +:109DD000F3040B847529789524C9027F8AE34C0229 +:109DE000FF8ACCB1427F813651809D175305F8A67A +:109DF000F3D7ABFC94E857861D1FA6F25305023C2F +:109E0000B8658C70FFF89C49023C2E6B9A008FE974 +:109E10003D538009DF0FCB65BF93DCC8B532E6B98F +:109E20007CDF4989A70E95C8B86F33F413D911AAFE +:109E3000B7B9A4739F4C03FB64347CB16995F952A4 +:109E4000857E8CA35A74AE4438BF575346E590B60E +:109E5000F92D344EC3E223956B1AF7E6BA46611C1E +:109E600048E3A541C88776B6DFA4EC5B0D55ED3F0E +:109E7000B98AC4FDA9DCABEC4FDD747D1771597E46 +:109E8000EC35C56554BF30FE7AC674E71E909B6DF5 +:109E90009FD13815E2DCCF7E81F1D7073094EAEB11 +:109EA000D6AF7F81F1EDD64E7D710BFA92CBF5B630 +:109EB000B125B5A98DEA5B4E37C9C1498DFA92C764 +:109EC000D794736CD1348C775A34187F91922AECE2 +:109ED0001FCCEF6F685D6A12DF5B0A897B306E8F83 +:109EE0000CCA0BE4932446ECB786C8672A635AE889 +:109EF0007842AE57CD3750050F538D2F50C1635464 +:109F0000E327AAE0DB55E3CB85FEA6B689578CBBD9 +:109F100015BBAE8CCBD5BA644718BB3BB8458C0794 +:109F200089AB4A38FFD07C6436DACFC6C32B389F62 +:109F30002A043EED569ED342E99D75F9FD055AAFC0 +:109F4000A91F95878216ADA3C616E4A3C22702797E +:109F500071C87C854659D0E3A656E61FBB5AE74E2A +:109F60006EA7B7737FF3962A8E93FF7EFED0042AE6 +:109F7000278D6D1ACCB31A5B0A62F1FDC18BB31049 +:109F8000DFA6560DBE4FB6F1D5F1B7D46883F829D8 +:109F9000F8E47CB2D404E7832E507F047296A37356 +:109FA000C65AC3D05D2D5F5DCDABC82F25542CD0D4 +:109FB0006517F547787E98DB55852EBB8F3C8D74F1 +:109FC000DFD6CAF0BDB943F48737B68BFE70F8A967 +:109FD0001801CE39C6E242EA7F71DE1C7EEEEE6ADF +:109FE00078ABF502764844B8A738FE1AE3826D5C78 +:109FF0004E1A389FB64538A6867BFFA8E1A8BE2238 +:10A00000F4FB0A27AF67F5B993D7B3B83BE79806D7 +:10A01000F35CAAF7686F875AEBE4EA30F30C3BAEC7 +:10A0200051E52D9102FD7E6EDEFAE5F57CDF53658C +:10A030001FBBBA5FB18F05CA77541C93C29E930DA4 +:10A04000F2819FAF54D19338C2DBDFCBF9A69C4B92 +:10A0500057F1AF8BFB83F378D579F5A5EB619EB60D +:10A0600032F43BAB4D0BB85D5F8076FD839FB85DEE +:10A07000FFA93109AE1F18B03509F4E840AEF23D32 +:10A0800058CABD907C5AD1A3F75B3E3685C6FB63A8 +:10A0900038EE3B320F8DED1FC2CFAEF0DCC7E5E7E7 +:10A0A0005D1EF7ECE57ABE9BC73D7E887BFA803D5E +:10A0B000C8E4F680E5D16FF1B8A789C73D8D3CEEC5 +:10A0C00039C8F3E88F20EEC13888E5D10D99F7E261 +:10A0D000F7C52E242971CF786D383E8FB689766A00 +:10A0E00054BC4990B7915631DE2934260AE3479093 +:10A0F00034A1FFE68EEB55FA2DC63BC34F8979F4A8 +:10A10000D036318F1ED22AE6D1138BC478C7952F53 +:10A11000C63BCA3EC22EAB84E7B1C6E788F1CF2E5C +:10A12000F885F63718D9F9AC86CC4957B4C37E6E9A +:10A1300087FFC8F5FB3DCE9F7778FEB093D37F07AE +:10A14000D01FE3521667E69E77EF89B6817DA8603F +:10A15000F9426615E6D537725CB67AAA597C7A411F +:10A16000637650BEEC32B3386B57E6CCF3F0DEFFCB +:10A1700005ABC906F599033A37C2BB32251B7C6F84 +:10A18000508D5F6EABCACFF1784191CF5D2D5FA24C +:10A190007FDBD9716D7E5519F71E998475979B5A8F +:10A1A000083184A92F5CCDBF5EED39EAF1E0C7C369 +:10A1B000F91FF573C674B86542F577476BE04948F7 +:10A1C0008BC6F8E7CAF05DA8C1ADEE42E0EBDE4C0D +:10A1D000C90AFBE9745C21EC4BBC77F1E3B1707DFB +:10A1E000E779ADC680FB4E56C11F7D7091D21FE44A +:10A1F00025939D4FF2B77EF9487FA8F31A657C7FBF +:10A2000064D7C58171A1747BFC0619ED4A43964160 +:10A2100003F5E686F35AE20F89F71A3B52CDD036A2 +:10A2200064CAFC7A00EDC37337B073AB3BE87CCCF7 +:10A230005ED8100F451EFCE73525E1BEBFF31C7F3D +:10A240005EEEC53F9B20BF7CF77CB909ECD3CE56B0 +:10A25000F69CDC256D26A0DB818E7566B8BE2B735F +:10A2600010CEDF9CFD907920C84DAB86EDE7F0F86D +:10A270004679DEAEAC398F0E8075B7B2BC6CD7F9BB +:10A28000CD7BA2402FD64B0E16BF307BA68C6F38ED +:10A29000CFEB4D3E76CE2D97783FCD06FDE9F17B95 +:10A2A0003DC839F1569250FB576815ED4841ABCA8D +:10A2B0004FB92B511F143E946A6385FE039F4D9C3A +:10A2C0005C067C33B3F7DB769E5F1A3711F4C2ACC1 +:10A2D0006371B38FDD3F2E58AFC1F7B594EFB0D4A3 +:10A2E000643F70A814EE6F607CCD358BF81CE85B82 +:10A2F0009BB880CED7B0C5E410D67798E0FA76390F +:10A30000DE9C8E75ED2C03EA61E185BDE6B6903AE0 +:10A3100051679CD8B2DB3C08E87C5623D04DA1C3E2 +:10A32000A83C317FDC91B907C75F38CBE89E4BAAC8 +:10A330000FF567755873E9E060FE95DBC1EAE373DA +:10A340007D22DE43378AF9E77C557CA4AE9FE76720 +:10A35000CD1927E4573C6ECAE37193BA4E5EAA3515 +:10A3600088F509559D3C575D27FF67E3249D7B1ABF +:10A37000BE0F17987C4DF1C3501A6BC6E3F95EEF20 +:10A380009320D76FF1F872A8BEEEDE04AA220DB2B8 +:10A390007B38EE5BF03A9D72FF55E325AB97C40D19 +:10A3A0000EC98789F604E4972B618F13F9E265E7FC +:10A3B0005955F376156F28FB23F945CCFF3C63FA1A +:10A3C00010E38BC6AF597C013F6D3D60BF9EA01F5F +:10A3D0006EFE5A8FFB276F8F66FBDE4ABC328938D0 +:10A3E00071DF667CDE79ED6F6CB09F7367F67CDAA7 +:10A3F000BEFD5923E6996F77E69975429E99CFE5A0 +:10A40000725BBBC61B0BF941ABC14742F6DB95FE45 +:10A41000C6F6F247B2410E031A94C3E66FF504BEC6 +:10A42000BFD7B8DD8078379ED5633CBA6DBB89C98C +:10A4300035AF3F2BFADACAFDE2A79C9F07B85FDC75 +:10A44000CFFDE27BBC5EF30E8F5BF6F07A4D338F6F +:10A450005B7681DFA4ED9676AE774B4C1C4F569F12 +:10A4600055F0BCAB4FDB112DE56BD57783D7403D65 +:10A47000EA36B7A80FB74E15E3937159627C32A63E +:10A48000B7588F29494A13EE2F8EBB41E82F320F60 +:10A4900012ED9676B8003B2F8AF1C984BCB1A23C7C +:10A4A0003943E213CCAFC57CF796D07CD70E7C62E3 +:10A4B000F9CCB6D627D04F6C3B9E1A1DFA9DE0AD65 +:10A4C0009CCEDB8E33BFBCF5F0394B68BFD29EE229 +:10A4D000E3CE707E9CE5FC9894E0BC238BCACA85D1 +:10A4E000E3E7F470FEA32B3956EE57EE3BE5FB2A6B +:10A4F0002AD4EF7D0DCC08393FF46DE31719684F6E +:10A50000AE512F6A2DECBC5B831489EFE15FEDFD4A +:10A51000962559A95C29ABFBB3FDD1EA21D06ED0B9 +:10A52000B912E13DA806C9356D3EECF3FE561FF6A3 +:10A53000EF4AD46649CA39F426F00B32D76FB249D4 +:10A54000D2827C4570F045E2AECDEA0E45B16A1C80 +:10A55000249B5D04D6B545479AC0BF1327B1597BEC +:10A5600010B655469FF3976CF7C3404F29C0F6913C +:10A57000A95BC5EF7EC0112DF8FE16B4B05F663042 +:10A58000B2F70F22B3DC8FC3FCF05DDBE881306FE4 +:10A59000411ADB4FF5A39D9EC6E7D598B627E3B9D0 +:10A5A00055759EC4EDB5A2779D74AD14DF4B51DB9C +:10A5B00059A5BEBBCDEE9A162E1F7D258BE59F4D6E +:10A5C0005F8D97E1B939C62827FB3EA45386F7C1B2 +:10A5D000B69D18639A1146CEF6F69BF10AAC4781F8 +:10A5E0007302F532FF7B151AB1CEA5F103BF2F9888 +:10A5F000F5A8D74361C13197CFA7B6CF798755F674 +:10A60000B9739FBF4E8273679DF2040C01FE1F64F5 +:10A61000DFD5B89A3CA9F7EFBFC84AE5EF4D557FA3 +:10A6200001E74CE468339EB3D972D0B84EB65F9E52 +:10A630001F36F0BA9F1AFFE6CF6627621DE993D94D +:10A64000ACFE07861DBF9B563D05DED3EB8461FD46 +:10A65000D00F1FB4C3EF002D60FDA315B86A0AC464 +:10A66000AB5B47B0F19F6F0A3C0DDF05DB7A07EF6C +:10A67000278FB1F10AEC5D386504C03A568FB9E511 +:10A680003536FEE2F5CE2F803F9159CEC320A7AFDD +:10A6900082EED0B6E87AE751B8FE05C8186D3FEEF5 +:10A6A000EB6C837E05EED6D7F965687F6367DE2B9A +:10A6B000D6FD8728F1E0E1727E5DCD77C5AF5CB94C +:10A6C000DEFF2197D30FB89CBECFEBFDFB78DEFBFE +:10A6D0002ECF7BF782FFE803F9B083E7C3793C1FF5 +:10A6E0006679D7769EF7BEC5EBFD4D3CEF6DE479FC +:10A6F0006FCE271359BD1FBE3B2841DEDB2F6CDE1A +:10A700003B214FF42BA50ED1AF8CCD14FDCA685B55 +:10A71000A22A4F4E53E5C93708FD85C641AA3C79A8 +:10A72000B82A4F16FDCA8DED635479B2B87FFC4547 +:10A73000968DEF27DDAECA97C57DE4201FBBAA47E3 +:10A740002F0ACBC7AD2D8B0E5CCBBECDBFBB7EF130 +:10A7500021E7E3079C8FEF2BFB369F7C8CF9DD858F +:10A76000F384F3F175F9FF62FD6242DEA4B07C2C44 +:10A77000754C53C9DBCC2EF8F84FEAA3F9CA75A87B +:10A78000FF943ED6B6C4307DD42A75A8EFE470F1AC +:10A79000CCFF357DA471C163D9D7A08F6AFFAEBC51 +:10A7A000B7A8C40D9D71028FC7947C690BA5157C59 +:10A7B00077A22141CFBEBBA175F784B843A1D7EFE3 +:10A7C000B259BCD3F8C502D48BC1E0CFC3D0F55584 +:10A7D0003EEED56C2BB6F09E64E440382DED65F16D +:10A7E0004FF4382B3B5F4502F01DAA2BC44DAF66DA +:10A7F000770FC64B5A6B35013ECA068D17BEC34B49 +:10A8000064239EBF6B80380ACE59ABE2A82FB3ED0C +:10A81000CAF7782598F70B3EAFD4F22E9EF3FE4B85 +:10A82000B6730BCE5FE868877DC8C6237ADC67699C +:10A830008C60DF4351C75B1F6667F0F79719FDE037 +:10A840003D805F803F850FC6A2FFFD52F49F1048F8 +:10A8500050784324EB0F647F35C59B14F4D79FBF1A +:10A8600076FE69F8BE6C86B9E74C383F20ADF1C67C +:10A87000B07D4B3FEA973A6EEB32FE55C5697FCE0D +:10A88000747E0472720EFC72773C5FE5D40EECFAB3 +:10A89000FE0D91AE7BD877619C323C57A153A7FD4A +:10A8A000CD6671DC877CBE4EBA287205DFA98909A6 +:10A8B000791F5685BF42AF1507F704E028E3CF5D47 +:10A8C0008FB28E30F2E3BA4ADC7D0EE8A0961F32DA +:10A8D000CEC1DFD70D1FF7E9781C19CAFF61B82E6A +:10A8E0009FC27F327220BC07A3BCBFCEECA1F2EEA8 +:10A8F0004C8CB5CE6AA77A74678B8CEF1F12BE1F83 +:10A90000AEEDE467BE04F6495B2C91D890784F5DBC +:10A910008754C7A9EAF365F9677B0AF04DE75355F9 +:10A9200079E4F5AA3C73902A0F15ED51715CA130C2 +:10A93000BE2469AC2ACFBDF239002DD12ADF1BE23B +:10A94000FBF6920DBEC3A365140AEDE7DF0362F4C4 +:10A950005ED6451EA49CA3FD4BB60DC775EAC75A2B +:10A960006263FCF30A7F1F4A1FCFF8FBF860C58FB4 +:10A9700039B0EE6EF0CF657FEFC921BE4FBCCE631C +:10A98000FCBC4807EFD990CF8BD2F1FC0EB62F78E4 +:10A99000E2B15DEBB161FBAC2713C7ADF138107EBE +:10A9A000DA9387ED531E275E7FC25382709DC78561 +:10A9B000F0A39EA9D8AEF2B8F17A6FADDB0B7F1F82 +:10A9C000B1F74A82E74BD3EBE8F342E89CB692E258 +:10A9D000114247BBD72AC0BD16C70BE393AB6D42EC +:10A9E0007F6245A6D09FE07608F07553F384F1DDD1 +:10A9F0005D4E018E2D2911C67773BA04D8E2982ACC +:10AA00008C3765BA85FEDD370D8B6EBB823E3FE12C +:10AA1000711E013A3CEA711D29C2F7A44A105EE595 +:10AA2000998AEDDC7EDD50AF62B401CC8F6272ACEE +:10AA300060B121BFC5FDBF58AD43EA16327F6C0936 +:10AA40009D4FC097CE27D4277D389FC5E13A22E29B +:10AA50003D55B88F3E0BFDE4043E66A49C64817CAA +:10AA6000EC607E2C7EB7F5119DB53487EAF1479FE7 +:10AA7000B0EFE4C21626096347BFE6718DA99F11A6 +:10AA8000F3C5094F4998DF11C2EE9FDD92E608FD3C +:10AA9000BB504AFBD1AFD977874CBBB7D9403E26D4 +:10AAA000E4CF888D08D97F99E0FFA92801E71B3002 +:10AAB0003882CACD843533F433B382EB53C6CD7EAE +:10AAC0004AACFF06E5DF67E4711CAED3C0C7AC4AF1 +:10AAD0005A87D757655E79BFE60C5FD7291EAF9DB1 +:10AAE000E071F7715E7FFB92C76B6D3C5E3BCAEB1A +:10AAF0006F8779DCFD39AFBFB5F27DAB4F79BCD63E +:10AB0000C2E3B58F79DCBD2A7333FE9D980B9BD8C9 +:10AB1000DF25EA0A9F7B368AF1DA5C9F18AFCD59B0 +:10AB200023C66B77D789F1DACC9562BC36C32BC6C6 +:10AB30006B772D16E3B53BAA45FB38ADA250806F6D +:10AB4000738B75B95BA78A71B7C2A75B5CA29D9C2A +:10AB50005422C6DD5DADF76DFF68DC7702667E15B9 +:10AB6000E20F43BE0B2F9C7BCCB13A0B61FF2697C3 +:10AB7000B86A61BFE6464DE010EC33914F65FC1EAC +:10AB80006413DC3194EAEB85C1E326D842FC8E578E +:10AB9000949FE987C5F311B7DF27D2B5AC52AC77E4 +:10ABA000EA4B44BA3A93C4F36793547E87707FA804 +:10ABB00067BF9322D795FD90C65489EF2DFD5C7F2A +:10ABC000A427EA7364CC1FE17353857EF447C6FE65 +:10ABD000EC7DA5C1FC7D859A88211FC0BEDDEECF2E +:10ABE000D87B0694EC81DEF4FE9B08A3B7DE380A1E +:10ABF000BF23B743C7DE1FD89560762CA55D375DB0 +:10AC000064EF09900E2D9E2373C3FB23A930AF7808 +:10AC10008E2C37A015CE99E955FD89E013AF880F2A +:10AC20003B4FF79FC3879FE3E84FFAE3F988B6F0FD +:10AC3000EF1D74C6712AFF1CBCCEE456B147397EA5 +:10AC4000EF213B5D578E2A5E32F075694CD3F1FBE4 +:10AC500063864F09BE7F9FA7F1C6C277B6C8390D7C +:10AC60007EF7650411EDC2E47157CEC747C58B76F8 +:10AC700061B42D4D95F7DDA0CA0B45BB6020AA3805 +:10AC8000A78D9D4F34B09585F623DD26F78F51DED5 +:10AC9000DF417AD51C5B81E7EFB625F3F751B85C4D +:10ACA0000DE7EB1D9EC4CE2FE6F17A71DE0F8B64AB +:10ACB0000BBD6E385ECCCF312E71601C7B96F12BB4 +:10ACC0008FFE037EE69110FE013F0F8BFC34A8FA45 +:10ACD000E7807CE586C387C9D57F1E1F7E8E529193 +:10ACE0002F73CC55F6EDC2CBD788805386F783DE21 +:10ACF000B14AB82FFD4EA03A00DF89FC319ED5271E +:10AD00001E4A9AA865DF6D719A4752BA17F375E625 +:10AD1000F17DB1460F09405CB2C563C496906A3CB0 +:10AD20001FBD227E512CF8CBC61477229C076CECF9 +:10AD3000DE6D199C1368D0754B0AF71E41B36E087F +:10AD4000FAD7C6E6042D7C577E84D6AA85FB462416 +:10AD500095CB90278E82F74DE20026B81FB6C5E34B +:10AD60000F14E1B950379E1FA2EB2884F8B5C83AFA +:10AD700003FFDE63F32754FE6D101777C37DE3BD39 +:10AD8000DDD9F96B83959D6F2D8E63FBB0390EF67F +:10AD9000FDBE9C24B3C307D3C5B3EFF854D07F974F +:10ADA0005283FE81EABBF07D9F212404B6237F04F9 +:10ADB000F839357F54E71157B4F273736DE1F76BCF +:10ADC000FECCE309E57CFB611E4F7CCEEB3F0779AF +:10ADD0003CB182C7137E1E4F1CE2F1C45E1E4FBC05 +:10ADE000CBE3897D3C9E789FC7131FF07842910B7F +:10ADF000C34A6233C07BB4C904EBF2F1CB245F09D0 +:10AE0000ECB3BB196C98C5F64F7B25D5B90AE2A007 +:10AE10005FE718057239D53B12D6113FBDBD02C69A +:10AE20002524E96D4E3BBC9FB40ADF2B51DE0B9B02 +:10AE3000C5E5E6367731DADD595C4F88BC3617F365 +:10AE4000D33AF1FB71096E5DF0BB49F4FF0C157D3F +:10AE50006F537D57492F317BF1BE6277079141A136 +:10AE6000748FE7748F98C1E90E2F5D85D197359C5B +:10AE7000EE0A5D9A6F1A6661EBA810E2C243F963AD +:10AE80002C206F2D497C3EFEBE8C8B3F6722D70F56 +:10AE9000655E657FF6F1822B9F6FFA888FEB848168 +:10AEA0002FD121F3143CA883EF92DFEAFF6532E84B +:10AEB00049F07D1A07C6E123E5FC3F423E1DE0EF65 +:10AEC0001F28F6720AE1B4523DEF90E7CAEFED1C7D +:10AED0002A18AB83EF764FF6FF12FFDE83415B1D2E +:10AEE0001F7ABEB785E3F750D9BDF877E00229EDA8 +:10AEF000F8BE9AC165B0417CDE2BC9B11CE8179F32 +:10AF0000D456C4EBA12A7FB5B6390EE4AB1FFB368D +:10AF1000E2FF072D97429600800000001F8B08007B +:10AF200000000000000BED7D097855D5B9E8DAE79F +:10AF3000EC3364E484C98326B813A658194E263826 +:10AF40000987B003C1460D7002018284709230C43B +:10AF50008A367632BD8F363B24246110F03EEB8377 +:10AF60004AF080436B3FEF355AEBEB40FB4544E53D +:10AF7000BE673128B4D8DB62982CB7AF03566BC7D5 +:10AF80007B7DFFFFAFB5CED97B7312A085567B0BBF +:10AF90009F2ED65E6BAFF5AF7F58EB9FD63E6DA56B +:10AFA000255903A98C2D0DAFAB645319FB00FFCCC1 +:10AFB00066CCC354632097E11FC7070AFC3FCA341D +:10AFC000753A3EC7279676F64136FEBF9985D3E09F +:10AFD00079E5C7FF83A533B6983507FAE0BDFEC211 +:10AFE000C0281F8CCF6A5C67B17F2EFCFD20273EF6 +:10AFF0008F2C1733F5AC79BC9420F4F78A3AA3F977 +:10B00000E27568EFEA669A671854FE04D08D86F7F9 +:10B01000B14D83E72A4BF34D86792B3FEDD5A1CC7B +:10B02000C974D47B605D0BB33EB5928D843EF33D15 +:10B03000BE09005757A8E8270550EFD2D769B83C9A +:10B04000ECB70EFAFDB0ECBE2C6D721CAEAECDAC02 +:10B050003402F374657DCEBF360DFBBDDF1AC17EB1 +:10B060002E56D30BEB3A31E7FF65669BFA3F3DADB9 +:10B07000ECE6C02818B002FE3786B189EE484E6073 +:10B08000F2C5EB65CC600CBAB495263356C8D8E946 +:10B090007A25EA01406ABA017F53B1FD42133E8F1F +:10B0A000747BB42D0820D353E7C33AD77014B0C8CB +:10B0B000848EA23E58EF9A6E4E37F6A0EB34E2CF64 +:10B0C0000B7F11BF59CDEA6933FE224C3D6DC66F2F +:10B0D0000D33B543DD8D7300BCE581B4916FDF0C9A +:10B0E000FF2E60051F3839FD11BF35A26F52FDE2FA +:10B0F000610CD6C3FC80BCE28BD7B5FC774ED6374B +:10B100008211C3B0A2F8F337578F4B8EE07BC8375C +:10B110005EC157D388669A1BF82A199FE460C9DB81 +:10B1200061692F105FB5B8E27C96836CE63262707D +:10B13000E758C66308EF52731DDF37F4E3E301FEFF +:10B14000958CF3C7CA505325F227FB0CE72F2F3CF1 +:10B1500014E3C4F90FC6A90ABBE27526E8355AC044 +:10B16000097F96943FD6FB6F30FE633BF3E7235F86 +:10B170002DF9829339A15E0DDDB05E5DA344A380FD +:10B18000D3A5A15B889E4B6DFC9D5C6D1DFFAD0D35 +:10B190000534CEAA4A180769B1C1D44EF0ED247C1B +:10B1A0005631DF26942789D7B7B3D97806787C61E2 +:10B1B000F7BABDC82FE71EF0300FAE1BDF05BCD6B7 +:10B1C000730AB2E3691CAE9F6E56A2FB61FCB3BB6F +:10B1D0003DC4776FAF51A20CE9CF7C4FA0BC76077E +:10B1E00032689E734991BD9F87F686AE9480017840 +:10B1F000EB1EDE7C4F18E63D9711A9C3711ABA6E9B +:10B200007618D83FD9F0E6E0B80DCEC07E9862B986 +:10B210000A381D0E25FCFB0628EBBB4DF482FF8E81 +:10B220000614E2FB050E16E94DBD987F92F2149AC2 +:10B230001F11EE31C1BF20C741F09E78D043F0A668 +:10B24000E469344E7D30494F4A473A325DCD077844 +:10B2500032F5B108E75905E413F8EDCC12C540FC0E +:10B2600030800BDF77DF70FD3E94A727C43ACFDE36 +:10B270003F632CF2F3990CDE7EDA9F1CC5759DD6D8 +:10B2800078DDF0A7461F477AA891DCA5697C1D0AE6 +:10B29000F0418380AB4173E84940DF860797DD8545 +:10B2A000746EF06FBB17CBE369469A02EFFF74B779 +:10B2B0009321BE111FDE7C6C2F5987ED76BCFC3AC2 +:10B2C0009043EB41FC8D00BCBDBDAB3D2D82FBA688 +:10B2D0008F45DCA3E378A8DFF9BFEF53F07DC6F715 +:10B2E0005FAF90138599F663E0DFE59ADBA8807184 +:10B2F000D8A1F1C4B7CB7D9CFFDDC59B46E5F06EC0 +:10B30000A931FED0A8BE0DF7F70651AF47BE05BC68 +:10B310002E4779998AF8183E1DF79B9AD5D67D79E4 +:10B32000D3C88DF72F8675AE09BA9813DAD7F855BA +:10B330000B5F57B558F91CD66DA9FBF218D1A17B4C +:10B34000B8E0CF4ECE9F8C85C786A7C4F9E2CB016B +:10B3500007E107A1730D817F3B5E3F6A78388DFC62 +:10B360000AE7CD992C6D6F318C77A61EF887C3C57F +:10B370009C2679A8EFF610DFC3CEEE463C017FBADB +:10B38000ABA6C4F945E2A77E571BF163BDE0BB86BF +:10B390006DC03FE9263EB2E10BD7ACCA79C6C5F90C +:10B3A0008CDA13F0D977021C6E297FF52C5CC79CD0 +:10B3B00017CBB52C89CE2548CFBB6A8C4C1CC52039 +:10B3C000BAEE282D1946FC2EE8A1C6E9E145BAA53A +:10B3D000CBBAC18EE17E9E26EA192DCA9BE505D027 +:10B3E0005FD0C9533E10ED83A6E12DCE37CB475039 +:10B3F0001F4D85FE23043ED881194F4F1C1D3F6F02 +:10B40000D2C479A03A33C7607B3AB3EA3D236CEBF0 +:10B410006785AA3837F839FB80CB3706F7E364B184 +:10B42000BFAF9B374EC17E0F280AED3F9E0AD5C2A3 +:10B4300027AA4D8FC9C97388FDCE90FC4DE7AD5B3F +:10B44000E83349631C2417BFC984035589E3C3CD7E +:10B450008760C3FBB4DE3E68AFF37B035186F0F236 +:10B46000F3A10C88D067E2AFEACA14D66782639E64 +:10B470006F84A5FE71FF0D96FEB76AE32CEDB7E76A +:10B48000DE6C699F1F28B0D4DDCC74AE239C031CF6 +:10B49000EF6E816753BB3C97FB918E8BC53A76B8B4 +:10B4A00023FE30E06BB17F2DD1A3ADF4137ED44BDE +:10B4B0003D7E4E57B7D0279326ACF6911E51C9E575 +:10B4C00027087F910EED38C898389FB96DE7AD5DBC +:10B4D000FEECFA64631EE83D2950F918FB18E93DBB +:10B4E000A9C313EA3776FD0DCE0807F26BB2A0D7D9 +:10B4F0003C672A9D1B5DD55C9FEBCA5DC4F5A5DC4E +:10B500004F125D17887ECC7090DEBA54AC5FEA5F54 +:10B51000AFB532D60747F38E12AE672D0D5EA83653 +:10B52000EBE5B2DC82FD26C5EBC9A17DBA9E40CF1A +:10B530006C13FC95A2F3F6A55EA6E23924DB378AEC +:10B54000F376A938B717821C23DF86B1349DCFDB91 +:10B55000C538DB63FCCAFAF361DD4E013F7B4A511B +:10B56000110F49A2BA8F45B6E715219E0DEAE44CAA +:10B570000D3392EF3F0176A1DF02D1AF2C6F75CF73 +:10B5800067817F3DD56901B42D3CC1FAC7BF54889E +:10B59000FA514AC0A1C5F99DEC0EA88FCCE5FC5E1E +:10B5A00093E90D50B3A11F1B0FE3558BF66A21CF12 +:10B5B000A35833C9C145768C97F3E5E0760CDF7F5D +:10B5C000E47C1EB1AF30E78600F15D98EFFB0EF82A +:10B5D0008B7CB7A4C6CA57CB2243F3596F9ED0AF1A +:10B5E00067B019C46791F5C4171ED167C7D88361C6 +:10B5F00092F7A09391BC0BFB46EA9D47822F12FF66 +:10B600001FC91D50F5D438BF487D7C41C8A947B13A +:10B61000BD9825FBE01C39E21AC87C00FAB954D663 +:10B62000A7E2DE2BF4F2F4E0B2DB7CB0AED78A5FA7 +:10B63000F19D4A6583EAF3767E9F08FFC07D7EF325 +:10B6400084B7FD08C76617345D8FCDBFAA4178B6B1 +:10B6500063BD04FB9FAF2983F6ED49B2FEEE2E6C6D +:10B660007F2299D77FF5CC1F771921A207F14D8A48 +:10B67000C0778AD4CF279BF00678F68ECCA77DC4FE +:10B680006BC3A75D6F770A7DDB69937FFBBC67A502 +:10B69000BC0B3A0CB6EE8BE005D6FBD8D07CFF8B0A +:10B6A0003C3A0F9B2D7C7FF1387DA49FAF10EB7649 +:10B6B000A41CC88A2490DF18FED7BB7E6EB6070094 +:10B6C000CFDF5450AFD5E1EDE99C55701C25F8F261 +:10B6D000EFF17C577619C3118F4EE880E7B80B2C39 +:10B6E000408447CA6312F28113F1DE47ED709E0E6B +:10B6F00028E370905A1FF2A702FD3F40FC5CEE3E2B +:10B700005861B513DDB87E18CFDDCDCA3CE9683786 +:10B7100036EEDF5C88E7983B40FA57F78532A41392 +:10B72000B4EB1E2A2FE8747EFB1D9673E585D23F8D +:10B730009C7F1458B3B3DF19F0C07B1DD800F074A0 +:10B7400086BECD50BF7E77320BE0E2EB22BE796E33 +:10B750000DE5A1EF44C784387C275A597FB92B5E89 +:10B76000EF3F98E4D660B111E35E2FD2E5AD0DED69 +:10B77000539E433B3BE8F1A1DED6BFB1DE40649C63 +:10B780001863F4224EBBD40843FBDDBDE17FCEC37A +:10B79000FDF384CB080C87B27BE3CEBBF1BCD2B502 +:10B7A000CA8A6C807B7FB75A114D60CF7C229FEF95 +:10B7B000AF475EB873FF66F4378C710792609E01E5 +:10B7C000F45F00FDBA5C46168E7FA2AD3D0BE5A38B +:10B7D000ABBE2B7010FBB5790234FF6E6F0D8EDBA4 +:10B7E00095B5D6BFD634BEF70677333EEFBFDEED54 +:10B7F0001E47EB7927CD0FEBE8DE50300279B373AB +:10B800008C7B6C23B637AC631AE8856EBFE142FED1 +:10B81000F2AA6C17EE0337FA2F7C7F06DA439A639D +:10B82000FAC7A1FF7D8148793ED0B1A6E5D43CD8C6 +:10B830000199BB3C63139E3F9D024EB90F49FA0E1E +:10B840008C69F062BFCE4823F7B3F81DF548E78551 +:10B85000631C61DC7F3A436BBC13C5F375E917E3E6 +:10B86000A513FD2AD3104E58D714ECF77E6B04FABB +:10B870000D64B96B12E13122F0E86D5F97D302706D +:10B8800077EEF6FA103F9D4A64573DE0CBC84E0D67 +:10B890003CAE5DFCDE53E23DC91F402792C34F3CE6 +:10B8A0003B7AB7311EF5514E47C08BD7653A179F8B +:10B8B0009E56B626DFE4BFB868DE319D741E742A3A +:10B8C0005CAE9F7A76EA6E03EA8140E46E7CAFABB1 +:10B8D0001B78791AAD732CEAF383C9CF8068EF6CBB +:10B8E000F3D44413C8FFC06A279B348C97D74139DF +:10B8F00071A373AC92003F03590D39D9781E40BB38 +:10B9000003C619D8EDE5253CCF81E76F0EC29F53E2 +:10B91000F2F9793E796AB81DE9CF2647C88FF772E8 +:10B920005E7813D5D94E3FDA171F01FEDDF321E112 +:10B930005F3A0F23F937137F31DF708B5E3AD8FE01 +:10B940001916FB715BE91F9AF0FCDF5AECD13C261B +:10B95000BF9FD4939327737D243CE1B100ECDC6C52 +:10B9600071701D3F2F2BB9FFCF077F13F9FFC23630 +:10B97000FF5FB2AD2EF5CF43F9423F117A70A6B604 +:10B98000333C07ED8B579D8128D03D0B5F1889FE16 +:10B990003125DA976D82F726B78097EB6B0BC57967 +:10B9A000F4A3562F2B9FC06276DB72B18E054DEF4C +:10B9B0003C8676F402A16732243ECC5F3D999FDF3E +:10B9C000D26E5B849D814597E772BB002C2B7EDE97 +:10B9D000382B8B901F1632AB7EB788D9F4B9D55C63 +:10B9E0001F93F6DA0A9BFE60B70BAA6DED3B60CEA3 +:10B9F0007ED4FB54B04600CEF782053B0A00EEBA77 +:10BA0000E0A14D0309F69BE378DEC07ADF68D5DF5D +:10BA1000EC80736753F5D7BD03F0FE56B5D78B7234 +:10BA2000B2B5F2D36928275B6B9D248F475B2BA8A7 +:10BA3000DF6BAD612AFF2B3F23E6FFEA93F601C0DF +:10BA4000B120A0BF8FFB8AD4D3AA2BCBDEEC30D1A0 +:10BA50007751F9AD967A3854F56687DD7F897CE6B3 +:10BA600064CD89FC6E530BA47F45B7F83999F3A9CF +:10BA70004024417F59021FBD67C6576A8155BF3DAB +:10BA8000129C3B6C28BD46AE5BE24BE243B60F0610 +:10BA9000EF6FF2A51DF297C19B7385F0DAE194F088 +:10BAA0000FD63F8C9B5909C2DBB6DC48453A46F2BB +:10BAB0000B00CFD515192FA14FE20D95CBD31B7AD3 +:10BAC0005AD400785E9ACCEDFD945C16453FAE9D4D +:10BAD000CE2915F5F3705FBB14BD93430AD9A14B72 +:10BAE0007425AAC33F6F1176E996C98CECD2B6D201 +:10BAF000AF1D4E2BC478878B897DA672BEC98E4A36 +:10BB0000A9E571881D6E16E8C3F7A6A40636C2F330 +:10BB10006A944394CFB0EBB4D90F0276D069B31CCA +:10BB2000D9F79B145BBCA1AA40E8DFD301EFE3E2A5 +:10BB3000781FCC0E198C4FC07A28C2F3CA8EA77B0F +:10BB40006CF8B1C723C207AAACED9769FFECEF2EE2 +:10BB50007C6924EA1BE54A6002E0E3756C82F79297 +:10BB6000F56728ECB1B940F0A5B0EBAAA55DB70820 +:10BB7000EC7920C111D40B86515C692CFAA5E3EB5A +:10BB8000E3765C20A07FBAA06870388E89F7BAAAE5 +:10BB900012EB0BC7505F98C6CBEBA09CB8686E56F3 +:10BBA000227DE1587123D717A01DF58463BB2B7844 +:10BBB00009CFCDFA02AB28B8045EDA68BD49130A92 +:10BBC000872592BBD7A7457622BFCB7A4A6E332B07 +:10BBD00037F149539EFE4001C535B8DF41CE07E736 +:10BBE000FC21B33E669FEF997C1FC773C5083A37A7 +:10BBF000647929FAA9BE66867CB6D5A5D7609CC0B3 +:10BC0000EE377AA680C727BA73F4266C67A9F9972E +:10BC100018B74DEED7B979A34D7E4B9B5D28EDA8A3 +:10BC20007DD868B20F551FB70F93332F1CF241D345 +:10BC3000DA82C8F388AF5917A286A310E3A90AE9EC +:10BC4000519E4CE622FFC9E5DA6397D9AF7B23DF2B +:10BC50007FBA1AB8DFBD2C4FA57A72C4B99FE248EB +:10BC6000C25F1316CB48D6DF217B6C01E803C23FCD +:10BC7000437AD509E1D70AB36617DA7DA9AEA8974A +:10BC8000E2BE36FF4C4DA6A36F22EC1F35C10BD58B +:10BC90001AC539ADFE9D1A2DE7D028D1EE83724129 +:10BCA00098FB7B96A2BF07C7AF8E76E7E0BE165023 +:10BCB000033AE3F61E9EB7CB1AEF9BF29076F5FCA3 +:10BCC0003DD28F24F546E9AF82F3A57B04D265AE61 +:10BCD000A2910FC0E60FB2FB7FC2C21F63F713D958 +:10BCE000FD42BF2DC8267A483D4CFA6BDE2FB0EAE4 +:10BCF00063FF09E281FDB614C35106F2BDC5C5B2AA +:10BD000076C2F8E9FAB2DB705F7EADEC151FEA1B74 +:10BD1000FF5960F3675EE6FEF663D887CEA0BEF6F5 +:10BD2000E21817EADD55CDF5E437B4CB89BF90EFC3 +:10BD300073C985A99678717F6B8B783FC9C0F3A6CC +:10BD40006ABC3B9A046BAAD2F938972B4F1979FA3F +:10BD5000C8C25164978CC69205C02E99827689908C +:10BD60007BC1DFAC7C143B638E937AC15E4933C3E5 +:10BD700021D67185F3238DCDF35C0A6F3B4A4BBC12 +:10BD80006EF447002C4ECE57BE989F3E07FD3BEB0E +:10BD900035B35E5187F18902D43F158A53C8E7262F +:10BDA0003FB98AFC9B9C19D1C309F6D5E5850E4B9A +:10BDB0009C34E667CF65141792E3A8CCDF46728007 +:10BDC000B22AE17126F0C70B781B259FB380D78379 +:10BDD00071DE6D4EC6F30FB89CC8B8835A1CAEC84E +:10BDE000C6F8F02625601014358750BF5F2DE4C8D3 +:10BDF0002DFC70F678D16A2957CEF5A4A735EEB49C +:10BE0000C6D1EC7131BB7E2EFDFA2A4C82707F5E6A +:10BE1000D2090E78E7D078D847EBFC3BC583E4C362 +:10BE2000CA82BBFC98BFD29914D9558FF1EB1E2F53 +:10BE3000F945BAB00BCA4B1FFC457F7B4FF0D12DA3 +:10BE4000F05E77A193DEEB54783ECBA1319FA3FD4A +:10BE500043F259B7E0B39B0A35EAE7C57D09448848 +:10BE60006572BB56E6AFBC3686EBABEE10CFFF7902 +:10BE70002AF3D0EB65042DCF63C90DC5F358CA0072 +:10BE80003F5304FE7227AC263B764A88E7B14C7ECE +:10BE9000CE6AB7DE9EEBB2D473ED76ABADBEA750E3 +:10BEA000EC7BB6FC95783C6D11E961127EBB5C7D44 +:10BEB000B595C755BE06762B964FB5FAA8FCD75652 +:10BEC0003F95BDAD1AE969CFB6E672BFBBC0FB5660 +:10BED000D7053A17CF65B9290F42FA29A5BFFC3B10 +:10BEE00085DC0FC5421C9E85624DF39C996918E75D +:10BEF0003A1AE2FAE160FBCCE20A6B3C6F49D81ACD +:10BF0000CF5B56638DE77D7AAA7EA010F5AAC9BFE4 +:10BF10007BF551E479117F5A23F0B0E3211E5F9243 +:10BF2000E31FFD02A7BFAC9F1378F83EF207C68F50 +:10BF30000E8A7DF4C1AA5B681FF5E55F965E785CAA +:10BF4000C867CA469F2B00E357F52D77E3386B7619 +:10BF5000C138A9973FCEE609A3B3ACF1864FDE8185 +:10BF6000EF1F8DC51BEEB903E30D4745BCE1FC7324 +:10BF7000CD5F467BEBA642FD27880747A17E12CB0B +:10BF8000F308CF28AA0FE0B922EBF0E770C6E8214A +:10BF9000FDFAE70B13F8F59D739584F6E93B85DC14 +:10BFA0009E86F3EB97F81EF3C6FC6A17789D9F53A5 +:10BFB0006A119FBFFD47AC09C769FF366B7A3681AE +:10BFC0005EFFC742458EF73B3A0FFDF23C0CFF2166 +:10BFD000D1784E4FD558C4F73917CF83B18FA716F4 +:10BFE000B9E5788E227C2733069F5A641A6F07E0E2 +:10BFF000A01FE9A4FAD2288EC9EEA678A7E4A394DC +:10C000003ADF7CCC53000393E13E93F2BC6F7E2178 +:10C01000E6D9FD605CE07136385D7F26F8EBBC90B8 +:10C02000B3B751CE409ECEA29C41791AE50C9E0F2B +:10C03000A09C4179B23540CF7FDC1AA4F247AD3ADB +:10C0400095275A2BA8FC416B98FA1D6BADA1F2F510 +:10C05000D6083D3F5AFEF55B289EF69442795583FB +:10C06000C173D757ADF27567D42A5FEB7659E56B8C +:10C07000CD4E6BBCBCB1DB1A2FAF37ACF1F2552DF6 +:10C08000D678F9CAE69996FE2B9AE65AEACB23B7F8 +:10C090005BFA2FAB596CA9EB455C5F5C125E617972 +:10C0A0006F7145A3A55FCA22164944FF8A22CE9F1D +:10C0B000074305C30686D877DC2DB7FF04F59458EF +:10C0C0005D8D30D4EBDD2D0BE8F9D6A4705D38C161 +:10C0D000F875457CBFEB2C5F1D9EC3D0FF7B8BD3D7 +:10C0E000ACFFAC9F16595464B273DD7E6E97BD3BB6 +:10C0F000FEBD17F1985854FECE4BD7E139D5CF028B +:10C100000AF0950E6A9F1FB6EC22A3CD791DD4AB21 +:10C1100033C18E34ADBBF833FBDA47C3F399EB5F21 +:10C12000983B12CAFCBC485D11DA5115A7DAF1FD43 +:10C130003995792A8ACDD60C467AE9B9096EB27753 +:10C14000EC707FAA48B1C4B3AE749FEE6CB5C6E57F +:10C1500073FC3CFE95E3E7F12EA853BCEBE9699133 +:10C160004F217CF09CE25E5D596B73703F192C8E01 +:10C17000F490A097F42B48B8769472788E8A78C39E +:10C18000107E852F168D1A1CEE73220ED1F5254FC9 +:10C19000C2F8CB3911873827E3100F2D4E18873896 +:10C1A000374FF815A01DFD09E776D7F0725EE390D2 +:10C1B0007108B93ED88F1EA4FD27168710FABEF06D +:10C1C000A3BF3E4DFF5FB88EA63C7D17F67B7F8AEE +:10C1D000BE1BEB474DF150DF68533CB4FC154B3CA4 +:10C1E000F499FCC83E7C6F226E693064BBC1069234 +:10C1F000C6617C367C4F223EFE9722A967F7FD453B +:10C20000F15A535CD5F1C1CDECB2E30297DD2FC8F2 +:10C21000F350EC7A4E0A620486E8C6AE70CE3E5900 +:10C22000183988EBEFC8785EE3F9568EF8FE8187FF +:10C230009F7679F3250B3B15CF2B3CB78E81C4E05D +:10C240003EB33DA399FC2AFD026FF6F28D22414FC9 +:10C25000E61B89F47DB230FC3AD28F3DD7AB511E3C +:10C260009B78CE722FCF5E7DC21DFE09EEEF9D73CF +:10C270009C1ACF1B64E4BF9894EB8BA27E2BF5B085 +:10C280005FE27E49F92803E3DDB0CE76FDC554CCEC +:10C29000FF7E6B8F8A1930EC2B69CC8570877361B8 +:10C2A0007F8375CCF1476E1C6A5FC4041E4790F80B +:10C2B0004271F8A91CC14B43C1E7F6FEAFED796F9F +:10C2C00014EAE55FE9E1F1B0493DABBD0DA6F173BC +:10C2D000A6F37DA73393C35FA72B512D1BE1B9F0C4 +:10C2E000FD19186FD11CE4EF786BC36F8E2F43FFDD +:10C2F00063C8199840F577A9DEAF390A307EFD96FC +:10C30000FFD7C7B1FFA42FAC194DB68EC0C7AA0D79 +:10C31000054F203EEE0B4494E9304F7FE8DDB471C9 +:10C32000A678DA2A858513E93163A673BADDA637C4 +:10C33000DF81FBE66DBA87615E737F9987F0FE95BA +:10C34000598A86F6EE42E475680FEF51C98F0DF8F1 +:10C35000588FEDAF065218CE3B477F46C5FAFB53C8 +:10C360001476DD10E7F015E335F4EE2894C3B790AA +:10C37000FF12C0FF4BB96F0A399AA882DCE723FE8F +:10C380000FA59AFD95929FFEA9501F37BD08FD7F0E +:10C3900091A630E9B98B2EC1871B093F0BBF1AA5A7 +:10C3A0001884E7B1E6EB5982FB0DAF09F9B03F2FD6 +:10C3B0009CCECFC95F0BB998D4F3DEABB7629C7942 +:10C3C000838BF2116E2A0C4F47786276D755DE3791 +:10C3D00064BE5A7F5021FB0DD4699AA71F245005D3 +:10C3E0007A2529C9014E4FEEA7F38AFD0FFAE9C35A +:10C3F000A0DF2AD6DB87FE3EA6EA3B9DD07F73B145 +:10C400008BE8BD6CA52B0DE9128F9F052CF686BD20 +:10C410001C1071B3CE562FE56BF47738B99E0F7FA1 +:10C42000401387461EB767C6948775F8E713228FB7 +:10C43000F493C15B1FC67C9AE30E5E6F08DE7AC37D +:10C44000468C7B8F6D3EBE04E3160F2881360DCBE4 +:10C450007DBB1A30CFA345095440BDAEEFF37E74C7 +:10C460008935747848C73FB56912E989EFFA990FA1 +:10C47000F5C46563B8DC34F6B3A8233B6EE79ECC05 +:10C48000E2F113B463E74DC76D97E3E39F5BFB08ED +:10C490007E4F0B8F9B0C0FF0B86972BF1A884297C2 +:10C4A0008F6F7B87ECE0B0DFAD219E47301E578950 +:10C4B00064A606300E1AF4F3B84AB27EEFF125F006 +:10C4C000DEF07295E7B70D707BB809FEE2391261B4 +:10C4D0008136DC9F465458EDE4425B7C459E6F1EDE +:10C4E000FB7315EC5178DE36DD7ACF6330FFBD2C5F +:10C4F0009F033D02D7F7BC88E77E13F475A4D3B73A +:10C50000415FC7F200E8EBF8FC7BA0AF63D907FA04 +:10C510003A9607415FC7F210E8EB58BE0CFA3A961C +:10C5200087415FC7F7FE0FE8EB58BE0AFA3A3E7F35 +:10C530006E16DF473AB3DCD18D8067EF9F808B01A9 +:10C540002F9D2EF663E42FA3CCA3F17C7CDEAF2BD2 +:10C550006322EDF3FD4AE4138CE781688F633DEDC0 +:10C56000C21F7F85F54DD964873055FBE600F4EF97 +:10C57000F87C76600B54BBDDFCBC1F38CA7CA83746 +:10C580009C5EA24C45BDE9CC7CA55701FDA67FBEB3 +:10C5900042FAC44414BDFCF83E5AF29EB61FE76B43 +:10C5A0004F63821FF7F5E8C07FA71126E2D7B43AA0 +:10C5B000B48F677B643DB90EDBEB5B1461A7A6EF1C +:10C5C00045FEED92FD8DEB7AB07F87AD7ECC21EB01 +:10C5D0004D7BB07E3C365FFD0A1CEF788E6C6FA8F9 +:10C5E000D5E1CC184892F3CD5C89FDFB15D93FAF5E +:10C5F00007EDE43359B2FFDA15D87E2666473FB619 +:10C6000092DA47F1FE93BE3BE211B49BAFF678EDB0 +:10C6100011BE3FC33EA69BE33A2D25DCBF10F39F1E +:10C62000EA8AC57F2AFDF68E94DAEB30EEE6D9C8A9 +:10C63000F3B406B20275785E0FE64735F9F9C98F93 +:10C640003ABB24767FC0EA2FD5159E47EF6311CB06 +:10C65000FD369127EFCE34F9ED84AC5F8EFF50C6E6 +:10C660004BA4FFB0461FDA7F5833CBEA3F947912D0 +:10C6700083F90FE57D04E93F0CAFB6FA071746AE24 +:10C68000CC7F58CBFA5C686F315D2179A9F5F5BE96 +:10C69000341AEDFAB31AF90F9976381ABB7FA0D184 +:10C6A000309A633ADE23E3F5D3772B7EB41FB6DCF2 +:10C6B000AD8CC6F2E4DDCAF5284767EF567C2857F3 +:10C6C000BF98C1EFB7149D0F1CD6705FF53B021CDD +:10C6D0001DE12FE03E1C5E9DA16D41BADEAD0CC791 +:10C6E000FE2B3F93E1C6F303F44B21371F3C8C7CB8 +:10C6F000E54C512CF5C2B1924FF73C8C72317B84E2 +:10C70000E4C3C57BB05EE696EF7F710FCAC9F288BD +:10C7100022FADFBB07E5F0F81CD97F782DF65F32EF +:10C720004E8EB7770F8E3F3B45D61FA4F6EED878D6 +:10C730005FA3F97E882721D5B7EDD1C7C37C55E229 +:10C74000DC323E46E377D6CAF7EFE92983F1568813 +:10C75000738A191F2739273F33BD0F7A3AD4FF5DFB +:10C76000EC030D337EBF02E5E68E58FBEF69BDB5E5 +:10C77000A2BE7AC6937B30DFECEF7E7D7FE5F9ECDD +:10C78000F595AC7FDE758571B9B09F8BCB8BF9BE0B +:10C79000126C7A068F2756DBBCCF89F2887E001197 +:10C7A0007FAA0E237F7B9D943717F687C9EF691FF9 +:10C7B000E7FD195CCFFECC0C6B3CADD3164F0B6381 +:10C7C0003C2D7BF071EA8AF938DD7312DBB34F4FF1 +:10C7D0009BD33A63545C3F4055D00D6529940E2895 +:10C7E000FF3425B26946115EE6E1FE16E9BF5E2020 +:10C7F000F288DB4ABF1C9E83F7928A5D01E1FEEE60 +:10C8000037C777D56DDCFFBF62CE05CA0B5BD3E9B6 +:10C81000D1F6631E4B87C85373A652FC41BDC1BD00 +:10C820008FF679113F8D60BE710ECE33F4BD0DFBD6 +:10C83000FD1943ACF7DDD01617EEDB35E56A9F5BDB +:10C84000C48F79BE9835BE2CE3C56579E329AEDC8B +:10C8500098E9A5BCE22ACC0F41D910F1EE3AD1BF3C +:10C86000B1E58530E2BD7EA793A11E78A5F1E5FA7A +:10C87000B091F539787F41791AD7E76CF1E69A865D +:10C88000277517B41F055C8FC00E225E2EEF85C47E +:10C89000EE1F883874443C5F1ADBFF2BD371FFF422 +:10C8A00074811D86EF8B38B38C4757D9CE81FAD06F +:10C8B000DC74F2D70654B21FD54BDCB3CE29E1F9B4 +:10C8C00068321E7D7886351EBDD5C5FD7FDD3956A3 +:10C8D0007E2B29E1F6EC2471EE1E2C4DEE4B42FD31 +:10C8E0009A79C9CED882FE9A61DCDE40FF84DD6F82 +:10C8F000A3B6AC20FF22B62BC07F4AEECBBFC7FB4E +:10C900006A582F81FE2ADE578175A8A90EBAAF2971 +:10C91000FD3BA886CCCB273FCF49E463B5A58EC6A7 +:10C9200091F7D307F3F3FC6C86D40F7A5DD86F854B +:10C93000FFE51338DF5FECE7117696EC1FD6789EA3 +:10C94000CBF0199A8C5BBAF8FD3DE65A3485FC2190 +:10C95000EFA17CB2C9BD1AC221F7A345C5CFAEC0B5 +:10C96000FD88E9A3D819D3BD08FBBE20F78BD87C7E +:10C970007EFE7EDDB7BEBBC2183978BC2227148B81 +:10C980002FA8419C7FA48C2FE82EACC7CF595850BC +:10C99000D072CED636FD37386763FABD31B616DBB6 +:10C9A0003F6AF0035FCD0E52BE14F7B37DD4E07F33 +:10C9B000A5485F8A7C78ADE7F956517835CEB359F2 +:10C9C000D16B52793030A00C1D17BC0BFBDBE3821E +:10C9D00097F257FCC33F31B47FE24B416B1CFFC35E +:10C9E000E29FF867C029EE93204F4F923C85B83CF8 +:10C9F000FDBDEF7FB0DE57B85CF44693C75D7DFFA9 +:10CA0000C09385916388CF895A6A3D9EE3308F86B3 +:10CA1000F217F37B20DC418BDF634FD335F07BC013 +:10CA20003ACF125DCB395DFF0EE8F65F749EEB5C8A +:10CA30009FF83BE4CBEB8B915EBD7C7D7F83F93F20 +:10CA400046F33FC5F9258E1FAE2799F053DBF4B7A7 +:10CA5000C14F29C1F74D0EDF47809ED5046F80C3BB +:10CA60007B29FBFBCE193C7E02EFADA0F70A391FF4 +:10CA7000DC85FA35B7CBE762BE80B4CB33F2F45530 +:10CA8000D80FF4DC7A3E4F4CCF6D281E35A4DDBCA8 +:10CA9000B67868BB797DF147C86EDE2DF0168FCF72 +:10CAA00044E93E1C9CE41447AE137DB7B42CBEEDA4 +:10CAB0002680FB37807FAC7B703D4ED37AB254B278 +:10CAC0009FEDF7D48E883C08B92ED5593B0CF5085C +:10CAD00089CF23E99A1BEF4335E84A272603CE3551 +:10CAE000DEA175BB750FE91F37FA7D9D187F5DAC20 +:10CAF000F3F5BB9B7C74EF45DE7393F74E1AFAC6D1 +:10CB0000BCEC86F7B680FD3206C65F586EBD876204 +:10CB1000D72F545BBDE5C7D9DB0F99FA3F566CCBD5 +:10CB20001F743E5541F94386427A1713F9840D620A +:10CB30008CB6D23B92FD5C8FD3100F73773ED08FB3 +:10CB40007133B7E1A4EF30FDB655DB7E08442A69A6 +:10CB5000F3BBB4BEDFC0FAC8C8ADE4F1FA4611AF0A +:10CB600067363F8527F9E72EF44F4B3C26DDCFF3A0 +:10CB70003CDCC153E574AFB1764D7F11EF4BFE073E +:10CB80009543C6E47735AAC438553ACFAB5CEA770B +:10CB900058F284EC7E0C95A9B6BCF881974620BF6C +:10CBA000015EBF8CEC91CBFD10C94CA7EF7024B790 +:10CBB0002D1ED687DDCA5D96EFA12C0CDDCBCCF601 +:10CBC00072B28D2F3D367F839D2FEDF4F8818D1E3F +:10CBD0008FAB5C2FED3CE6247F79E783ABBBD17F45 +:10CBE0006E3CE8207FC65999070240A23F7F198B0F +:10CBF000E197F4E5CEE68C28FAE1255D96EDE4F9BF +:10CC000021D4CBE477672C9399BFCFB14CF817EEC2 +:10CC100060BD74BF61251B70A11CAC4257BA13FDE7 +:10CC2000E21A958DCCD8C4087F91EE6C98EFF1E6AE +:10CC30001101F46BF75DEFCA783B97DB1189F4D7EC +:10CC4000785C56656F9BFCFCFFF06B5DAE5FCB695B +:10CC5000D0F7FDFCEE287EDFEF527EAD97453C42DB +:10CC6000FAB5CEEEE4DFD5E817F72AFA5DDAD89DFB +:10CC7000A9D84FE3DFCBE85E761BC2FBDAE6577C30 +:10CC800003B44FB20DA387FE0EC4D4920476E1F72D +:10CC900067309E17973D9085F999275DD6BC5B5903 +:10CCA000CE0FB9C5BDECC88C12935ECC7CB13CCD27 +:10CCB000E212F257F1FBD9D2CFB4B620528ACF6735 +:10CCC0005D60640F7A2A95A882F919A9CA4B8A1661 +:10CCD0009F9FD9F3E5FF1107E3DFB712F8E94FE2B1 +:10CCE00079B3FDD9ACE6D904F4C99EC5CFCFFEBC5B +:10CCF000C4F493EDA097DC83F443BB299D33CBCFE1 +:10CD0000DD43FB133E5B9220CF58D2F7C9D9FA7DA1 +:10CD10009CEEBC9E941FF902D6DB23E19FD0F7EB7B +:10CD2000B639B536C47F9F762488F2F945A70FE35C +:10CD3000DDD73ABE377C46F665C5F77E81F81D45DE +:10CD40007C2FF4C67FAA433D708BB4CB84DEB862DF +:10CD5000B8A90E5B71C931DEFF1B25D3F71AEAE0D3 +:10CD60007AE6FA0377F4A01E29F54CA8AFC4BA7C82 +:10CD70009FB1DBC796815EDBD824E388B7EF453DE2 +:10CD8000373EDF92BDA8079F7559C7977AEA2B25D2 +:10CD9000E57B71BC706CFEF2BD08FF800D7EFADE93 +:10CDA00024D4DF28D1F7A2DE5BCF64BB4EF901713A +:10CDB0007FE27AB25B8FBB65FB27285F607B361F03 +:10CDC000FFD503EB7BF03B691F3678AEF5F857DAF9 +:10CDD0007F307DFFA48BE7071AA09F615E4890F526 +:10CDE0003AB9F0E96E27F07F89AED07EF4EB109768 +:10CDF000D770AA43CCD3D2437C512AF11AA53C8FD9 +:10CE0000C1F8EECE03DF7818D71D87FB1B2B900EE1 +:10CE100031B88DF575E81792701FC5FE30DE8A7B3C +:10CE2000EEF4239C2B627E8DB61EECD79921EB93FA +:10CE3000F6627DB0795786B6F5E0BC2B62F8798052 +:10CE4000DE5F912CDFDF65CD4F317A565AE15A6DA6 +:10CE5000C1E7F70EF4F4205C615F74D368F2073227 +:10CE6000FAFEE71D4D6D94BF1D97A3AD592447FEF3 +:10CE700058BDC72A479F26B8AF365CB09FFA67E215 +:10CE8000F995CBEDC3ABBF6ED82771DDDB145AB774 +:10CE9000E4A35A9F89DFE19C6BD464FD9EBAA6C9C6 +:10CEA00057635E6EE7867FCEE8FC93F2C48C884DB4 +:10CEB0007E2E6FBCF6D41CCA9F00FB4A4F946F7D38 +:10CEC000D70C45FA31E7103E83D26E6652EFB86553 +:10CED000E62893DEA1C5F48E0AEA6FD33B3A451EDD +:10CEE00055A7B86FA2438BDF94E7337E168FD3B676 +:10CEF0008B3CCDC28DE1B5663BFB89D91C9EC766D4 +:10CF0000733994DFAB3DD3A4501E58FBB611E9989A +:10CF10003F7B2AD3B700CFB5FE6C4700AF2E9F14DE +:10CF2000DFCBECFFBC27EB33F0FC44762AD9A927F2 +:10CF30003276A6E13D855301A738679E7B8BFC5D69 +:10CF4000717FA281E78AF417AE9ED94EFEBF3735B6 +:10CF50005E0FCC7EFE2D8AB7E5DAEF7186488F71C1 +:10CF6000DF22BED32BBEB729F5A5AA4D8F7E896CD3 +:10CF700060A1BFC8F3D37EAF13FFB8CCFA57879335 +:10CF8000EB5F7EDECFCF06DA3E30E9DDDE41BEF379 +:10CF90005A23EF11DAF429BB7ECCC4774DA57E9ECF +:10CFA0003CB281FCFAC94DD67EA73A5EAC0CC2FAFF +:10CFB000BA024ECAB3BA3DD7AA474B3DECB68E472C +:10CFC000C90E05BDD0D22EF36B6F67BD1D74FF5B1C +:10CFD0003B7CC8393A6E77B4FBAA484F69C8851ABA +:10CFE000ACE7F8FF284B2B42FD609B13BFF0CA73E0 +:10CFF000EB4DEB807E2EC748DAA7038A62CE076A24 +:10D000007B04E5229E0FC4EB713FFC7D8FE07E1018 +:10D01000F317B37B5659FC9BC632EA1FF38719619D +:10D020006A3FA30AFF97B1EA11DCCFE2FEB11FF617 +:10D0300058FC6346E523C84F32BECA8CFB29AF6F4C +:10D04000A94FC2F3A31EACB7EBFC3CF9E6773C2733 +:10D05000F17B4057DA1FE4F379944316E6FB9DBD5C +:10D06000BDE458B43D5DE875F83D0ABB9C27857862 +:10D070007E5DB99ED7314AE37E2B0FD0475FE95CD6 +:10D0800089FC1ACF5329A6EFA2350E9257322FC42E +:10D09000E5F7F0CC548B3D6ECF4F691471E8C1C6F3 +:10D0A000A92FE571F67EC557CDCF6527C373B9ECBF +:10D0B0008171A9783D55F62B2DE5FBC19FA6E8C7E8 +:10D0C00071FD763FDA59F4A3A1AC0A7FC722C13BB8 +:10D0D000EA4EEB774BCE64F0EF962CDA26BE935EE9 +:10D0E000F197F9CDCECFB4DEAB1F2CFFA1B894EFF2 +:10D0F0006379A55727FFE189645D477C9D83BEE87E +:10D1000017BC281F42E439C83C08772887E76D30F0 +:10D110009E0FD16EF0EFF15DF57B2CD22E290CA77E +:10D1200084F05CA8E1E788E4B3BE991AE7BFF30195 +:10D13000E23FC977D03F23847C5DCDFB979CE7DF3E +:10D14000B790FA45D281933D6DE3E91CBA2E643E57 +:10D15000875263F71EC784129C4347E7EA37F0E71C +:10D1600086C86788DC182A4AF87E762881FD3C79D3 +:10D170006A783C3D8FDDD7D42784FE91FF00D3260B +:10D18000CE3B691C24EF44EA85F5DFFBE94A03FA4C +:10D190007D30475F1032D9AD31FD7280EB3B31BD40 +:10D1A000D2984AFBE235D01B57854C7935D760FCC5 +:10D1B000BB88EF265BF528B4FFCDCF3F6C761CC053 +:10D1C000B791F022E2267FC6FB5B42A678CD5F01D5 +:10D1D000DE5D2193FEFF21C4E75384CF0F2F7C7DBA +:10D1E000045F25A7F7CC99313E7D31311F5C36FFB6 +:10D1F000FFDF90296E6E1AF7083DAF1C3A2E07FD2F +:10D20000DEB0F68BBDFF03F3B843BCFFEF047FAC89 +:10D210005FECFD93F45CF0E75590F3F366FA5E8300 +:10D220007DE43D5AEF783EFEE992D83A7E6B7EFE71 +:10D230000F7FD925F93C6B16E2AB99F3D365E8D99A +:10D24000E366F1FC9608F7D31A52AF99289E0FE0D7 +:10D25000BDD105C8D7A3E85EDE4D38BECEB89D1B54 +:10D26000B34B8CDD7BAD76090C34D972DEEF35DB48 +:10D270001DFAAC7D7B115EE75CDEBFE8BBE9AB70FD +:10D28000FDF63AE825336659F3328338FFA5C6C563 +:10D29000F83FBD678BFF9BDAE7CCB2E42F703D16F9 +:10D2A0008E70AF0768FCC35AE7C806A857CEE27A6B +:10D2B0002CE82109EF6F57CE8AF9132A693E918F26 +:10D2C000712CECA47B80317D8579C9AE8AE953C687 +:10D2D000D7C84F14D7A7FE85F8A954D077D5777B48 +:10D2E000EB049CCBF8FAC53A2EDD7F25F5F7F3FE6B +:10D2F00009DAEBA93D93C3C9520F9F755AE2156C29 +:10D30000BC6374FC7740CA5C4B668D047DE56007A6 +:10D310008F47D5770BFA1ADFDA6BB513B9FC2D17E7 +:10D32000FCDEFADDBE3AE4FFE5EF49789D7CFD3195 +:10D330007F5F1FADFF4DE19748FB5E9F84EFB30415 +:10D340009FC6E1BB06E3B711DD19C74F0D335CA3E0 +:10D3500087C8B3D82CE80FEF75D37B5E0E574D44CA +:10D3600071F1B8CB2917F279DD3196D0DFB473961D +:10D370005BBEBF93DE4F15F66C20F1BDDD87E2F199 +:10D380009387A8BF8FCFE780F31FEBA1C8D1B94027 +:10D390001EFCDE1CD935E17255C7EF2C84831716AD +:10D3A00031D377E5641CBCECFEF1BD680F269727EE +:10D3B00071BBD16BFD7D0ACFDCFB721FD4485AE9EB +:10D3C0003BB54B041354316B5C34419CCBE27791F9 +:10D3D000FE9125B1B85426D9B9EEADFCF7A158B5E8 +:10D3E000358E99DCC2C8CFB5C050A21A8CEFD1AD32 +:10D3F000FE96C8066D3BFABB54D515D0B58BE39AA3 +:10D40000F6DFB998ED657A7A3EE5A37C6FD6A87809 +:10D410001ECAE9EE71A92887763BFAF4607674B7E4 +:10D42000D58EEE9776B47E75ECE8A3B3AC76F4DED9 +:10D4300082F01BC4EFAA4EFBDBC1D29245685FBCF1 +:10D440002BF228061E54D3110FC6367E6FE1948846 +:10D45000F3CB78FF40314BC5DF3B1868F3103E0734 +:10D46000D6644453E0BD74635D25FECE81B4A7113C +:10D47000F3E80793DF27B6DBDDC941A0E7341233B9 +:10D48000B2B7077C3EBACFBCB0437C4742E40B48FE +:10D490007B5BDE7B6F2CE7F7A7D17367FE7D8B8507 +:10D4A000C21E977679DFBF31C59C07B08805289FDB +:10D4B000A09A85A95C2ABE9F58E3639B10A8F7A792 +:10D4C000447E47FCBF87F309DBAED2EF570D6C7B80 +:10D4D000807E1F6AB0FB0C6AA9BCCF60509CF61A14 +:10D4E000D8FB49A5A6FDE332F69B61D45FE572DC6B +:10D4F00086F77C47C5BF1FD12FFCC2DB33B83F6521 +:10D500007C29F737D94BF97D882B3D3FE0FCBCB136 +:10D51000D46AD76BA597777E4EA4F7C4F7294663E4 +:10D520003C88EF4B379572BD404B27BF0A6CD14307 +:10D53000E703044A8788EBB24BE713044B13E41369 +:10D54000FC42E8236B0B22B370FC591718F1AD3D78 +:10D55000EE2FFB1D473F5582FDB659F8DBCA8045CB +:10D560001DF917DFDBFF61AB7E1275BCE3AD15540F +:10D570009E508D34CCDF3A22EEEDC30894CF24F3D5 +:10D58000A2E4B835B56527CF9AF6AB85F31EA33C68 +:10D59000B3F6DCFD871580F394C8F7EA4FF36D47C7 +:10D5A000BFB371947F476A69F5AD27CF9AF60F3BF9 +:10D5B000BC98176580A8DF59CABF5FF76299A76F4B +:10D5C00036C8E1EA6D5C0E576F3BE5427F665D4B06 +:10D5D0003D8B4CA1BC2915E97B6C26FFCEC2C2A0B5 +:10D5E000931926B832F2F486528A7B845713BDE32E +:10D5F00079816BB05EE6D2D331AF5DFA2965DCA0EC +:10D60000B4F467A43FF767309A3FEC67518CBFCF03 +:10D61000D5B3DD03187FF1FBC8AF5A57AAF1DFABD2 +:10D62000EBD847F02487DE2178CA54C0F7F08BF19D +:10D630002DE5A253E0DBB46EC2F760F2BB709E9A98 +:10D6400086F83D82F4827E9BC43EF09A7A21D5977B +:10D6500080EEB1F78265167C7BFC1516BAB5EBE35C +:10D66000D2713D92CEF5A2ED7487F3FB48C7F73037 +:10D67000AF8DE898381FE228D26B12B497727FB44E +:10D68000A4579DC1E9556794713C056F758FA178CA +:10D6900080D28BF7251BCBEB19DA0B6E3D83BEFFD7 +:10D6A0002FE9B7A81CE8678217E4F1E15293DEF98D +:10D6B00067F8D91F2D35E9C1D73A0E00F33D43F382 +:10D6C000D9F372FF4A71888BBFDBC3F7DD3705BF23 +:10D6D000D84BB9EF0E9ADF6C54AE6AFA33E0907211 +:10D6E0008372DBA660FEA4E2423E0BA3FC4E417DAA +:10D6F000EE3F36615CB4C1CF7A712F7C08E508F04B +:10D70000E6AEC870A3FCD47767135FA0FD4FF81492 +:10D71000FBF44BA54C9E5327E97913E78BBF75FCAF +:10D7200007E0B940F0D48AFB051FB2F854564558BB +:10D730009D8DFE597D1F9D2F7D33E5F79A5816F775 +:10D74000935F593CD4A3F3FC3119174D1007D594BE +:10D750003F230E6A8FAF0E16174D1007B5E8EB8307 +:10D76000C541992D5E6A8F83DED63182E2D0B765DE +:10D770003A28FF51EAFD32FEF96AC7D7E97B47AF85 +:10D780004E565846F6C571D26DC23FC650AB33AD4A +:10D79000FF4416FFDEF596315EFA8E28FE719AF28E +:10D7A000F1E07CF07A60DE8E794ED24BABB2F7DBE3 +:10D7B000F1EA1676C965E155C6D9DD1D3CCEEEF11C +:10D7C00033FA3D4D49C7F8F7749FA7DF8B642ACF22 +:10D7D000D3ABCFF5515EAB9D0E9E8EB67BE9779CA9 +:10D7E0007CD3D75129E8EFF15F9C3FA84AF812E4B7 +:10D7F0000FFED9F4BC041DDDCE0D5E14B98BE8A973 +:10D800001D4CC5EF8ADF1670FA342D4E4749D78B71 +:10D81000E9E7A3FD45C6B96F2A0CDF857223BFD3A4 +:10D8200024E97B228BE3F7CC4D2C2ABF4F66A62739 +:10D83000E05FA77B77B96C1FE11FF330A75ECC17C1 +:10D840009E5C837EC7D39D5CE927B992F8D50E1004 +:10D850005DDA9B7D0B507F3A5AEEA2BC9504FC40EA +:10D86000BF5B7B297EB888EEDBF8EF845E29FDEE96 +:10D87000287E5CCF4EC01FD790AE15C14474C57CC6 +:10D8800086BF80AE278AF4C791AE929E3715EA5FB5 +:10D89000995D64965F83DB312CF1F76D9E16792DCF +:10D8A00030CEBFE27BBD686391FF50EFC5FAE21B4B +:10D8B0005973A2EF823D5BC6CFDD5AD6FBD268B466 +:10D8C000FBCE3291B71938ACA19FA6655CC2BCCD26 +:10D8D000E3F86121E8BFD0CFF639C4FEEA30E16950 +:10D8E00040E46FBE89F99B60E7BE3C3B9BD6B10527 +:10D8F000F338E1F92991E7598B63E33CA0CF627CCF +:10D900009EA91186F7D3FB63DF6769A373379E8FE8 +:10D91000F1EB47ACDF67E1F58599B23D356A898364 +:10D92000327F04EDB6B8FD35356A39EF5830628D77 +:10D9300083F27C1D79BE6DD4E7440C731C9455D0E2 +:10D94000F8276B65FF1DD1B2C9E638E8E2A86E8EF4 +:10D95000731AF3A3E638279CAF54977EE8C7FBEE13 +:10D960008FA05E3F796AE43CD25FDE9B870348C7A5 +:10D97000DF9D73FB7DFBD10E07FB00AFE40FAA57C1 +:10D980007FD8CBFF0F02C2B069008000000000000A +:10D990001F8B080000000000000BE53C0D7454D5FF +:10D9A00099F7CD7BF393644226017480A02F01DCAC +:10D9B0005843187E020109BCF9C94F157480A0B103 +:10D9C000207D842CA55D5A83959676EDE6416248CC +:10D9D0008240E8D2EDCFE9CF88D03DAEEE69E87164 +:10D9E0002991D20E6229964A634B8EB14B75B0597C +:10D9F000165BDBA295DAEEF194FDBEEFDE3BF3663B +:10DA0000323128B4C7EE8EC77373DFBDF7BBDFF7C3 +:10DA1000DDEFFFDDC79DC58CB105F03FF3C60C8D72 +:10DA2000B18110FC3911FB7ED380B1955364BF22C4 +:10DA3000669433B6384FF6AB4C6321639D2EB99E86 +:10DA4000590CE6BFC09CD4DF66844C6B2A63C16569 +:10DA5000AA985F4FF05F5A2DE7EF8E0501DE2A8707 +:10DA6000E85B2B628697B10F31D95F4AFDD5C97E3D +:10DA700094FAF732BEFF81F84ED382F58FCD894EEE +:10DA800034C6C3B348AF1E9DFEB787FF3945E233A6 +:10DA9000C5C4F1F73BBEC0EF7AA312C1737EFF0D80 +:10DAA000E0BB86E4E330C7F77D88DFFDC4CF2738CD +:10DAB0007EEF037CDA099F5EC027FF2FBFDF0F2BAD +:10DAC0008D3DB8DF5F808EAFD1B997733AAE60FEFF +:10DAD000A34477809F43E6F8C4A08F311C9FC3E125 +:10DAE000BDE8147264359B28F709D9C77383FE8299 +:10DAF0003372BFCD7A50B3E3BF99F46455119FFFE1 +:10DB0000EBF8A74DAB38D5879F81E72ED7FF06C727 +:10DB1000D3D67F8AD67767ECE712E3CAB1AD846FBC +:10DB20008A5E8BE6F767CC6F14F4151CEB8C5936C4 +:10DB30007E306B3BF1276997AC9D6497065CB2BF62 +:10DB400083F4665709873FE1D8CE18E20FFC3B45C6 +:10DB5000FC9ECAF9F7FF9D1FBF3584BC94717E48B7 +:10DB6000397C6C8EF13B94B3F71BBE707E6A707C7F +:10DB70004AFEFF0AFB15D27E429FDEEDFAA43E0A62 +:10DB8000BFCF9624F93B2908CF2784741AAFDA70E7 +:10DB9000307C3DFCB9BAE511D544B830878D632C93 +:10DBA0009A60B16DB0E7AD2CA632F061D180C97C2E +:10DBB000E536BD665F243C5C5E87E87F83ECDFAAC8 +:10DBC00045E25CD8600CE38B14DEDEB5784E49BCD0 +:10DBD000D9D7D2F05E78CCFB88A03B10B4E9C9B5A8 +:10DBE00086EF0F015F6CF150B22FF8B3EA135F9E1E +:10DBF0008C7C58552AE17E3386705E2C94700FD24F +:10DC0000BEAB92FB7C8FF773E5FC1FD1FC145E0367 +:10DC1000661A5ED6CF28EE92783D766C80CECBE544 +:10DC20008B3D74DD1C689B958005E7F1A10D5B556C +:10DC3000D36E1758AF1E04FF760F4BF649AE5276DF +:10DC4000A097F6BDD6786D0A0AFE083D4DE29960B0 +:10DC5000018BD9F13BCCCFE71AEF6FB30BF7A3DC05 +:10DC60005E7BBEC79DD7DBF82EF560B52FA9DF061A +:10DC7000F300DF7509E707E606EFD5EF0B72BED3B9 +:10DC80006E4FAE9E8EFE1AA2E3357E2E29FBF31355 +:10DC900033DDFE5C317E8F046DFEFCDDAEFFB760D0 +:10DCA000BA9ED9ECCFE348779BD7E1423E9B7E6694 +:10DCB000C400DE65FC2D4EB513420AD9A7A47E56DA +:10DCC000F1F52B76B396DE2CF3AF0F39685EDB539C +:10DCD0006C432FC00DBA2E36476DF3E2413E7E34C1 +:10DCE000A8500BF41D25FE6FE1F89D0AEAB45F9081 +:10DCF00069CC009D6A5831B918F16BFB398707E987 +:10DD0000125B9E9F827741C093FB1C5B96DF18F3EA +:10DD1000A6C69F15FB9C0A723AD0FF133F1FE474FE +:10DD2000A8051BFD085FCD5384FEFC9AF8DAE114C8 +:10DD30007DEB0DF26B03493BF43B92F7956E29970F +:10DD40006F91FECB78FD8DE0FFC4AC85883F638E7C +:10DD500059F675BF253B38DABA84F417EDE2BCAC4E +:10DD6000E4799D43BC475BAF869516E29387C51562 +:10DD7000F01F2EBF6F5F3790525E61BC8A7C3E31D0 +:10DD8000D3F815B6A3C1013E5DA47379203D1FB140 +:10DD90008DBF194CCB072E6E8C221CD8D90DE7F6FF +:10DDA000C26A755C13F0EDCF783E95941FD4DBCF3B +:10DDB00045B67F4E9DCB9F8369F17C38BF12F488B6 +:10DDC0004D7004A6E9C3D779438A9433714EDA23A0 +:10DDD00048474752DF787F57211FCF79DAB956E895 +:10DDE000535E08F77952F097F9C6E17EACFC645CAB +:10DDF0009D0BFE95257F8603FA6BF12FD87F207C43 +:10DE0000CE8972B0A65DB9323DE914F01F4E9EDF97 +:10DE100084D078826BB2B9C27FC06FE0235B096E99 +:10DE20006333C0CDA22F53429C7F5342493E4D21C4 +:10DE3000FC0D0ED731273A0DE1C254E69E9582BF04 +:10DE400046E01D74468F5E0F72D061293ADA557331 +:10DE5000CBDACE12E4ABE60C4C83E626E414ACEB52 +:10DE6000F0977AD1CF3D27F643782E3847F425FE38 +:10DE7000229AC73468E7D66F3A0EE0D8DBD3CD4A92 +:10DE8000C4A32ABA278C642D683C781CDB3BC04CA9 +:10DE9000639CB275D157A221D8A77FBE3380A2065A +:10DEA000D159FF54C0AB41E0A51975AFB2319045CF +:10DEB000B958203E07FDBA37B00D9E37347F64094C +:10DEC000AB803951E750C283C498EC7229C2D58621 +:10DED00012659C6797C1C62DDBE24CF511371CF724 +:10DEE000A4C657DCC8EDD3AA10F0D32677DF17F409 +:10DEF0007D5FF07337E0D05F4E00F219EA0DDBE092 +:10DF000040FE991E8E67BFB5E2B69B81E04B652C43 +:10DF100080A36EA44F4DD19798AC05DC3A898B77DE +:10DF2000E975B0AF38D7D3AD60EBFE0EC05A9C4E4A +:10DF30004D5D5D10B7C9F1E931260B60DC56663DD9 +:10DF4000C4404EC2E61E6702F0B8B1F9F50D18F7ED +:10DF5000AD31DD7A1DA078CF065F0DC6B52B4CC163 +:10DF60009725CE57906E0FFC877C71C55FFD810BA6 +:10DF7000F9BC50611300FE9D113E2EF9E266DA2BCA +:10DF800076BE6819FD2D674B763D639B7F5F287FCA +:10DF9000DCF95BE08FD96CF665A093A9DEA588CF8C +:10DFA000A576C5A796D03407033A5D823F07DA37D6 +:10DFB0003D877ABAC6AF051CC887258CF8D728F6E6 +:10DFC00078AB55DFF50CC4AAE12D7B7A4A00CE3D33 +:10DFD000675486FCEA587D0021E1CF83F034211795 +:10DFE0008EBCAFF66B304FFBACCA703FC947E0B791 +:10DFF0006F2E3C3F3700EB61EA3D55C027D8F70E46 +:10E00000C3ADEB302F77E1EBEDC8A75CD6121F0B49 +:10E01000FDBBFC0E16F7A4E802BA2DC117C7658533 +:10E02000F6D235B9AF236D9CF892FB99306368BB8B +:10E030002DA37F2ACC5B26E5B61DCE13CE6199C1F8 +:10E04000CF439E2B8B707995E7929B21AFEE2A6789 +:10E050004A3EB3C86BE639C432CEE180C6F52471BE +:10E0600046A5B822B1571B53057D6BAF83F418F258 +:10E07000B4C34A01FC11579806FCBF5BE04B3FE07C +:10E08000DB8196C2587749EA3CEE2E3BF127A58208 +:10E09000F159D7A5EC11C32416FA7789DEDD5FB2FA +:10E0A0008A507E3FC47A9DA8D7F762C60CF87C9848 +:10E0B000F95CD86F62016AE1BC5DC8AF037B9FCE9B +:10E0C000473B129FE82C3C5F46AAC2EC7632B34530 +:10E0D0004E9C9774C3E4B8B49F1ED34F76D90B2DD2 +:10E0E000D9698361BFB026E231B3F891F86CF38748 +:10E0F0006807655FF3B530C4E3EBB3A3CF72BBCB66 +:10E10000D74FAD307E84FD83B38C53D87E13E33D6F +:10E11000F00F17430F525EF2F674E334DAB54C3B5E +:10E12000760EED989E9287E519F220EDD820DA312F +:10E13000185A8EFA0A7C63F55767C7CE4939F8003A +:10E14000FB00F207E8F925D97F0DE801BEBC84E7A2 +:10E150003E8361F52DCE8A884CDD07F829023F7C8D +:10E16000AE807D57B6FCF04FCA18DE5F00F3147125 +:10E17000AE9846D6A0DFF87AC0E39982F6C21C4476 +:10E18000BA33F9028ED9497999FFC420CA8D23EF99 +:10E19000BB93CD2C7E3079AE1B9DAF25E9423D82ED +:10E1A000481EE95098E9B88CF4F8008909EF241763 +:10E1B00016C941C75285E8EB28618D68CFDB7168CD +:10E1C0003E63DB972ABDF8FCF170118F97A6F2B879 +:10E1D000707B618B3F00F3B63B613EDAF33293AD67 +:10E1E000989E82FB7858A5F937CF31F2D07141DC87 +:10E1F00047F1928C57E53C5F98C79563C33CCE28A6 +:10E20000AF881685719F7126F11DE2A8B1D4F7C6BB +:10E21000638EEB445D84FF74872D8E1898D4C2D032 +:10E22000BFBB0DEEDF33E9BC219CF4EB3710BCBD66 +:10E23000D2AF1B37227E8BC7FA1AD0CEB900EF7D42 +:10E2400025297F7D68E9E754D896DD122E21FCAAA6 +:10E250009AF7B45D07E71D0C4EF1A27B8F57B7F814 +:10E26000D1EF6D9FC0F996B9EF9630F783736E10BA +:10E27000F304BFA4DFF740F8ED847D30CD77601C58 +:10E2800050CCE3807BC3A5B44EC60330DF72C1BC63 +:10E29000E04DA0A718374FE37032F7BB57F033E5D6 +:10E2A0006F030568AF196B217F1115FEE48556E3F6 +:10E2B000A52110CA81D67A6AC1FEF747C0C00D6A8F +:10E2C000567E200B1D77D63CE041386DC54D1EF4BF +:10E2D0009F1D4698E036AE0EBE3464B3B7DB8BD9D3 +:10E2E00064C4EFAE860FBE3464D3B7FE7C8E2FFAC3 +:10E2F00019CB9D82BB12E504F03D1E74C717034382 +:10E30000DD7E16739750EBD4314F0CEB341E35D6AF +:10E310003213F3F1AA731AD5BF0A5972FE5638DACE +:10E32000703123BF1EF5B7305CE7863ECE8F2E7C62 +:10E330009DE6DF59A532CB8627D89F35145065C49A +:10E340004BBB51C0006EC77C25B60DF068F0AF27FF +:10E35000FFB375512E3D877D09BF3BA63593DF92F4 +:10E36000F15547241220FF7495F1547C76F47EC455 +:10E37000CBE54FDAD507485E5376757398DBD54FFA +:10E38000E173693FF61D7F81ECC77685CBE176E0CE +:10E39000F7B7B3C8C756A107DB0BB3CBCF9785BC84 +:10E3A000BE3D3DDA86F00DF069FE59EF3DDEEC90A2 +:10E3B000F1A6E0E3D5F207F8F12F619B5D067E7CC4 +:10E3C000313C7E381FE0D78EF64295D6E2094543B0 +:10E3D000F9CF11DD47981943381ED64293546F94F4 +:10E3E000A1BF1B0E27CE70DD2A41DFBBB5C7DF8280 +:10E3F000F086DB35E38930E5853AB7A3C22E33D604 +:10E4000023FCEE7BB3DB671C604FB1DE8D8F6CF3BA +:10E410008F8A73EEAB348F229D37E9DEB5782E5D9F +:10E420008AE1F74EC1BAA7D9887ACACA668DB2CF37 +:10E43000568233506A6E88929D5F3ECAFC6D625F61 +:10E4400041675911F911D8F74BB96AAA3F1A5D878C +:10E45000C2C64F11EF3633FA0BD4BBED650EDD5259 +:10E46000A8253DECAECA8929D0CF9965BE887C0528 +:10E4700011319C00BABBEC0D8A8BDC4B148AD3DCC7 +:10E480001EC8E0B2C8F979E16F20D6A07176D6F047 +:10E49000DBEB1D8511477ADE0B2261D8EB171147A4 +:10E4A00013D6E5A53FC3BAC9B7B3C8C545A14FAA9E +:10E4B0007B539ABFCC9CF746D845F39488A84B0869 +:10E4C000FFB7D2CDF32BF663C0CFE65FFB2A437FC5 +:10E4D000203DB098A5D8FCA2F48334627BEEC6BA86 +:10E4E00013D279261D8EA4B328C2D2F605797544BD +:10E4F000781D438D54A6C657AA8CD73DFAD3F9058B +:10E50000F8782264A7D8D008F8ECCF8ACF603A3EDA +:10E5100045117E2E7D954611C203FF3C16DBCE10C1 +:10E52000C85F16FE7E6B46E87AC45363566769C9B6 +:10E530003BC6AD37201CD9B7C5AD7A24DDBE9644A5 +:10E54000B87D2D8D907DCDBE6F85E0DBD5DA87F768 +:10E55000AAF73BF0CF2C7AD49D7832AF02F070BB93 +:10E56000AD4F92BE96CF1A45DFB87E7FF886FE4942 +:10E5700048E751219F68DB31DE30741E8F7C22C258 +:10E58000E53878538CE63D3542FC919C078CC1BA46 +:10E59000DC4871C8FCF71887742F1CC8A338E4CD79 +:10E5A0007D79E8EF9F1A0A658D438E16F74CCA16DF +:10E5B00087F48D1087AC8FF078F5F87FB928AEA876 +:10E5C000BEC0FD7CF5851E15E3898D119DF83E7F4B +:10E5D000A85F35414EAA310E01387D220EC1F914D3 +:10E5E00087BCD9A3225EF32FF4D3BA6AE8631C3246 +:10E5F0007F843804B05051EE0E5777FF0CCF2D9327 +:10E60000DE5315E666BBDC5625FAE93D895CD75D2D +:10E61000B62DCFA4734E979BF86C8E6F6A1D97F73B +:10E62000CC7923C9578DEA2DC3FA4017CB0D201F93 +:10E63000DECA1953C10A785E837171174E05BABBE1 +:10E64000CEE6C52CCCAB3D7CFCD3B963F6612BED9B +:10E650008F47E8C55B3937C4441E6414C0FA4FAB1A +:10E66000467C31F8A1AEA99FF7717A36911E6D16DE +:10E67000BC09EDD1289FBE55C48332FE7A6EA51227 +:10E680007353D2652C590AF3E709F8AE393C3FAC15 +:10E6900055BD346F4719A379B75A17A97E313FE1A9 +:10E6A000D275E8CF4BACE7F9A2FADD937918EFDF2A +:10E6B000A231159EAF6C8FB6917C9E75513DC38083 +:10E6C000FF503F2BCFF412DFF2865C69758E5CB091 +:10E6D00064715BDCE2CAE833757541363B24DBCC00 +:10E6E0003AC4C188C83F2BD88CCBC0974BECC14EE5 +:10E6F000A4CD3D2D74FC51367CBDAC2F6C9C617C4F +:10E7000007E563AA33F1EFDF017EF5BDE6A2F73A34 +:10E710007D7BF7DE5E81758B1E8DEABA329F01CA62 +:10E720008A96613E8B3CA0BAF4E92694CB23F9B2D9 +:10E730000F060DF03E82092BF9BD8F3619B6FEA9E2 +:10E74000C843AFA0DF3B325ECE7F95AF977D2BD124 +:10E7500084F7358E4CE0FD4B11F5518BCE37A1512E +:10E760001EBDE597DE6CF6F1744DBABCDE51B5897D +:10E77000CBEB28EBC0AEBF18C9B22E67A9B9633A7C +:10E78000F0E3C89083EA389067C5313ED838C37C3F +:10E7900019F9B57D90F3F5C86BF7FBF09CDC6313BA +:10E7A0000F64B3F3BF11FE285E1DA3BCAB7BA6C8EC +:10E7B00077D990867E6BF7A2A74E55C03EA7E74F4C +:10E7C0009BA50209C00B0FC6CB72BDBB86E77129A2 +:10E7D000FC9E579BD0FEBCF64A43367DAF8C98BF5B +:10E7E0008FA4CDE7EF45DB7A34E27FD189BA7D781B +:10E7F000EF275EDDD3AFC1F9F6FDC6C1304FE99B0F +:10E80000CEE3FE11F10A005E455784D7DE7959E464 +:10E810000DF072D58C1F8ED74F6A187FEF53617839 +:10E820006A2A87E3C9441D7381B0F739AF7E9EEA37 +:10E830008E7D0907154F2E0DED5351F464FDBB7B02 +:10E84000B0142320B678C9391545CA7C504DD3BBC6 +:10E850007983B969FD7B5BC6A6F5576D9894D24361 +:10E86000F87F79644A5ADFEDFF405A3FC866A7F542 +:10E870001B96DC9A06AFC6174EEBD7F96F4F9BFF7E +:10E88000417D455AFFF6B25569F39706D6A58D57D7 +:10E89000FBF63C84E5A368F94C6D2C23799C897CBC +:10E8A000CD3B63903C6E1FBCDF877211AF8E521E52 +:10E8B0003D90DF5F8CF5EBE79CD9EB0B0FD6A8D230 +:10E8C0007F17A3BF3718CFD7E4FC606922AD2EBFF6 +:10E8D000AE86FBE735354AD63A41A63F967E58FAD2 +:10E8E000E5CCFD33FD6EA6BFBDF3E67D1E5EEFE712 +:10E8F0007E7FA59083B6B29F7A13485703AF2374E7 +:10E900001703BD5EBA8F41FA757CE5DD93F1BD5A00 +:10E910006E9939D65D92F2D7E1B218FB258CE7FAF1 +:10E92000626CCA741C8FB175D3A92EAD85CBF9F377 +:10E930009BC4F3F5D8829FAEB5F12DD3FF063D33CE +:10E940007F50C052F14AC31F8D4801E0775BF3410D +:10E950006D1CB461EF31CD6E874E57FF6ADC087EC7 +:10E96000FA633519FA84EBFA8696BFA31F78B99536 +:10E97000D7DD0FB57A581CE83BDBEAA3F6E7AD7E9E +:10E980007AFE7CAB4E6D476B19B5F1D6008DFFACAE +:10E99000B58ADA675A0D6A4FB4D6537BB2354AF35B +:10E9A0007ED4DA48ED8F5B4D7ABE4BE8E9FB051F5C +:10E9B000A34CD615A2C71D0AF1B501AFEA2EB86067 +:10E9C000A8763B0F7CFD4236BEBE577F12AFEE9D50 +:10E9D000847206FE2AAB3EF5D6C8B83E79DE84972F +:10E9E0008C87317F413991753AC0EF31C4CF8DF5B5 +:10E9F000B9A2ABC7EF88A8DF1C29648DDF1670961B +:10EA0000E5A33DFF4A3444F67CFC4CB2E77EA6A564 +:10EA1000DBF39261F67C2DE91D3B897552AC2FD258 +:10EA20007B8A8C3A4841AD4EEB641D64D11F791D41 +:10EA30006434FA81EE9368B7A4DDBE52BA879DC7ED +:10EA40006CE327C83FE99F87F90F7323F98F2AA149 +:10EA5000B34C7B93E2C43C41CFEE579617A07D7137 +:10EA600023823C4F3758159E3393F701F66D281ECD +:10EA70000EF7E5EA5EF2E73B9271CEEB14C70CF7B6 +:10EA80005FE97CC058C8EEDF810FAFA6FB45CE879B +:10EA90001AF5BB896DE09F8F2418AF93CDE1EFEBA2 +:10EAA000A41F3C7281D7312E694A8CC1D185584B45 +:10EAB000CF3C680F7F8E8D8BC2395B931D810330F5 +:10EAC00035EFE93EDD03F38209736C0E8C57C57395 +:10EAD000685D68C9CC18F61BA2AF937D0A69E97E10 +:10EAE0001223D4A4DFA1225851467F626ABE8AE76E +:10EAF0005B9AEA03DCF5B34DAD16CE65F9C516A6F3 +:10EB0000978B7AAA37AB7FDFA8D8EA6C1A0B7422EE +:10EB10001DDA6776F0F77A19F226F924EB6D320FD9 +:10EB20007F8419BEDA2CF143BB78EF92F9BEE50F72 +:10EB3000D34D7F2DF05DF19DA0F72D6C03E3F723FE +:10EB40001C909F20FFC6B862074A86CBDDC1591FC3 +:10EB50009C5C4BFA6D29D7266FEF51286F177913FC +:10EB6000D3EF73D8F318993765E6470F0B3BBB0B10 +:10EB7000ED2CB40F3B19E55B1D4A6E609F92CA975E +:10EB8000C06FCE40BA16D58AF72FAC651EAF177E80 +:10EB90002E2D5F1A116F91973893E75EEC3B9F978C +:10EBA0003A77AFABC78FF71CBB667EB5B109F936B4 +:10EBB000D343EF399916D7D1EE64D2C37C161B37F5 +:10EBC0003775DE2AD3CE637DB61382197CDFBB1383 +:10EBD000BF040078F901475ADC5350951EB7DD5D3C +:10EBE0002BEDECB5A1030580DE6F4B3C5954D45599 +:10EBF00079FCE911CFDB756E2F18DA3BDBFBF5767C +:10EC0000AFE1F1D9CE7F3B9E8F7B647CD492761F9F +:10EC1000D6C17BBC0ED2EF4E5DEBC2FB1E9D5E8D5E +:10EC2000C737BAA33EDBFD95DDB58AA09BE3E513AC +:10EC300078A9C1E514078DB45FB79017D9CF2D37E8 +:10EC40000DD2473D10C53CB9CD3B4EC1FAA81CFFC3 +:10EC500068AD22E485D797BB445C955BD61B77A053 +:10EC60009C4D583F1BD9E68138E93C3CF794F7525C +:10EC70005CE59DE832B3E1FDCF025E9733504F79FA +:10EC80007FBE8361DEDF5592DD8FFE632D8F33DB28 +:10EC9000F459519C6F015FA629C3E77D5CC8C1434D +:10ECA0004E9043D8BF6BDA5D744FAC6B3223FB5D83 +:10ECB0005A37FDD1ADDE2C72A8DF47E7E7F431F912 +:10ECC000FE3DEDBE449BDED0B816F6D59E6701B47E +:10ECD0001999FAE69CB0BC712DDEB7A8CA0DE0FC0C +:10ECE0001AF5C716F2B123C0A8DEA115367BA8EE2F +:10ECF0005CACD1FD08892FC4EB8FA19D1A4DBE33AA +:10ED0000F181FD48EE463ADF4CFC28949FF50EF366 +:10ED10000BCDC66816783F4FEA55BA7C394791AF9C +:10ED2000D1E849F3AFC529FFFA6CEDA675784F6DB0 +:10ED300027E3E3A76A4394EF67F6AF959EB7693D73 +:10ED40008D782E6D535D247F99EBBB4A385EDD27AD +:10ED5000AAC5BE3E05E57F5755510EDA772F1A6AD0 +:10ED60001B5F9FA930CFD5DAE2A6C2482F8FDB6B9D +:10ED700019C9AF578FFAA6825C78CFA82053C07705 +:10ED8000C7DB7F3CA7BF773EB21E83E4964C3B9720 +:10ED90005BF636F0A54088F518F6703FBF2FB299A4 +:10EDA000E6497EEDBEF1B781F83BF06DCCC2F4FAD6 +:10EDB000D4BBAD3F2975F9E388CF392C07F97C899D +:10EDC0003DA890FF8E18A477BEA45DE5F756C6C98E +:10EDD0002E90837D123925559762F8DE03F5CB64BA +:10EDE00014DFD0CCEBC42B2FA2DB47EB260930136A +:10EDF000F1428D8AF2CFEDEE25F61ADF1F96E1BDC6 +:10EE000015C572909FBD11E51AE69530F34FE7B234 +:10EE1000DCE799EC6B3EB80EDA4975A29E26E8193C +:10EE20008D1F12EFBF94DCCAF820B38E2AEBAC1D05 +:10EE3000A2CE3A5A1D956917896F32FECDACABD27E +:10EE40008D3AD08FB76ED25837F19DC70BA93CDFF2 +:10EE5000CAE375787EFF6E9EA0EBF0D9A45FA4E7AD +:10EE6000D26E65D2F9E4287EB1FB4C7B1EC2694BA1 +:10EE700034517DFE907FDB2905E3DC844B67367DD2 +:10EE80003D9C9FEE373A84FDDB5627EAF0E73EA52E +:10EE9000627D609EDF52F1DE5E5522407EA14DC94B +:10EEA000FEDEA1BB8EFB9B617E22E3FDCC7FE6787C +:10EEB00063AE5296F41FAAA053FA57E08F62D7BBF5 +:10EEC00043F2BE9761E8BEB9A9F8B3FBE98F321DE2 +:10EED000E323BFADEE5B9A65FF617163BA5F5006D5 +:10EEE000F9FD30C9D76E9177B7F9F979CC4102B203 +:10EEF000F801887F3F5B07F254D99F6E6FF2CAD248 +:10EF0000ED4D663CECF6302BD7060FE2E1D63A52D7 +:10EF1000DEF478B6B89E91BC1E2EB454ACFF8413B8 +:10EF200006C3F3D08A4D86E7E1F2BFF37934D6F118 +:10EF300078A1A3AC298A7993AC3FEF5E741BD957B3 +:10EF4000F0A33D75B6BC49DE7778B7F52829AF5AEE +:10EF5000867E66D6A5BA17FE3DD5A1DAFC4D27B14F +:10EF6000AE7408E411F5ED70BE9987F725ADE7554D +:10EF700076401F5EBFCAA44BD6A1C6D78B7B2BE7BA +:10EF80005CF1C5788F7290BFA7D0064DBA7F02F4AE +:10EF9000D07BA279E23D5166DDC9ED6EA1F773F138 +:10EFA000EA9655F6BAB3E45BA390E797AB4DBA3750 +:10EFB000D43142FD4FCE7333C31A87EFC7AB3F4BFB +:10EFC000FCC6CFCD302F97752D7D86F9BD3A98E7D9 +:10EFD000BA68AAE375CCE72C3A87BC7F6224642C1C +:10EFE00057891D80F54F2F7A8AF2CDDF27D8587CBC +:10EFF0007F92CC37359E6FCA3C56DA8D1AF589CE92 +:10F0000052183F7C46A33838EFE9AE5358770F9E2D +:10F010005947399FA1ACCCC37DE43D2689F7D5E69D +:10F02000AB9598AFDADEB748B8DF69ADFF05CAC562 +:10F0300093AD516AFB5A0D6ABB5B1BA9ADD28C30F4 +:10F04000FAA5AA7ECA00D9822118B7E1517516D651 +:10F05000DBCE7F5785F9DFC8B7CAFE68DABCBCB221 +:10F06000C6B479902FFF1AE7697ECE4FD71285EE8E +:10F0700027DC39C81E52F42C76E1FFAE5DCAAFBF63 +:10F080003676A9A89EF29791EC1223BDAB1A14EF25 +:10F090005DA57D12FAF7789D4E7A91D4437CFF4AA4 +:10F0A000FECDA2F59DF8E77CA067CCC7B81D4BDD6F +:10F0B000F3A0EF1B83E2BBEB9B4F2EDA8FF7803A76 +:10F0C0005E94E3CBF71BB67166D534E3F726C73001 +:10F0D0005986B873C7C9F1CDF45DB6F8AE26DC58D1 +:10F0E000583CC052F71F33F9B5AB9EC7EBF27E4DCB +:10F0F00090F1FA9A1CFF64BDC8E3801CACE3C9FB25 +:10F1000013B9237C47F4F17A6E0F3E23F8D4E9E279 +:10F11000F71716677C2F1212FB8EF4BDC836313EEE +:10F12000DAF721ABC47E4D62BFC7E6446FA3738B91 +:10F13000F2EF329AC5F30567626D633068F4B3ACE1 +:10F1400070960B7BFA6C3DBF97ECF21B1A9E0BC0BE +:10F150006B20788DFCBEA61C5F702139DE48E30D64 +:10F160007C7CC10593EA4AF23BBDE5F565FBB74EF1 +:10F170004DDDD3E9C0FA8417BF57E1F79FBE26F0F3 +:10F18000CF6CE5F72A77F9C47D1F3675BF81700C07 +:10F19000FE7DE6EDF5B70CE177C7B0FF06DA5F7CE0 +:10F1A0009FB300E9ADA4E7FF40CF33FE9D81F5F5A5 +:10F1B00093F78BEF7AEE433D612D1CEFE4BF9B602C +:10F1C000CDD96FFF4E6841FDEC66317F33C1DBC0A6 +:10F1D000E7679107218F73F7634DF60AE0B512BC1C +:10F1E000D51CBF5BEA757EDE19728BDFFF139EE2D2 +:10F1F0007BA133D1751EB4E7C97F07C09A4EFB5D72 +:10F20000019F76121C53EEC7C4BD28AE1752FEA54F +:10F210003C7C4BC8DFEC7A45CAD517687DF335A333 +:10F22000FF1B042FE3FBA4D1E828AF887E93D6F917 +:10F2300093F793FF95FA57898FFC9E2C532FBE2787 +:10F24000E8877DFF83CE0BE22FC413F63D742DF6C5 +:10F2500005B87182E349C23D762DE032FDCAEE99D0 +:10F26000FC2FBAA2684270460000000000000000B7 +:10F270001F8B080000000000000B93E16660F8514E +:10F280000FC121486C62F17A76068678160686B937 +:10F29000AC0C0C3540ACC8499AFE5540FD4B81780A +:10F2A0000110CF06E269403C11887B80B81D88655B +:10F2B00080E68903B11010F3023107103303F13FE8 +:10F2C0000E06869F1C08736E03C51E93683708DB05 +:10F2D000F220D8E781FEDF02C437C80887513C3CE2 +:10F2E00070163F03439D00822F2C882A9FCD8F608C +:10F2F000F38A5266971C503F008DFE9C5880030095 +:10F3000000000000000000001F8B0800000000004B +:10F31000000BE57D0B7854D5B5F03A73CE3C333312 +:10F320003909794C20E049483055C0214004A1F505 +:10F330001010432FD78ED42AF5A2774004E49554B9 +:10F34000B1D2AB6D46264050F4060B0A0A3A50A8DB +:10F35000D08246C4962A7A07454BFFB6365A6F7D4F +:10F36000D4F6C6DAEBAB18E28362FBEBEFDD6BEDB4 +:10F37000BD33E79CCC24A0C5DAFB874F77F6D9AF25 +:10F38000B5D76BAFBDF6DA3B1EA884C273013EC68B +:10F390001F96DEE60180E24C3AEAFAAF2EDA3386B7 +:10F3A000FDFE7F3DD11D46A69E4C4F0305602C2BD4 +:10F3B0000713A004E05C1FFB95D59BFCD323BF3D46 +:10F3C000AB08E020A8E0659FD2DAE401FFCCFA396F +:10F3D000F82144B1DCF5D360796710DB25A8DD970F +:10F3E00080B74B5718E5FA70CC800BBF9B3EFA9D57 +:10F3F000F5337473136B7FEC8320B577C22153F818 +:10F40000D00569D1E6E34AEC577BBFB346E42B80D5 +:10F410000D0E02DE29007519780FFDEE7582F77169 +:10F420008DC16B6419DFC7E02FCAC07F10BE9A0F71 +:10F43000C339FC665D06FE938587E6CFF09C6C368B +:10F440001EA9AA0658DB0C8F54B901D634FB28BF7D +:10F45000BA59A7FCCAE608A5498D356170247742E0 +:10F460002AC1501F8AB2FAB27FF65FA0CA67CBFBEF +:10F47000CA755BDE53C4FAA9C9E4B5A061CB278382 +:10F48000F5BE7810C76773F7E2F83E4A1998CF4582 +:10F49000183ECEE455C16F246602A34775D063A41D +:10F4A000D83CCE0CCE9B0E61AC7719E1CD23F07A1F +:10F4B00075D98A4E84F77D560F58BD338253DFC409 +:10F4C0007AFFA7E2FB7C1E1B014AD9F7D5DF6EEA63 +:10F4D00054587F2BCB3CC60A36AF7BD9F8ADA75B1F +:10F4E000F0B85BFB03E2CDC7FE211E6B36F37C66F2 +:10F4F000DEF6FC19C0F272DE15997E4EB6DF61EBC6 +:10F50000FBEEB7DA88D523BFCA7E87417C851EFC17 +:10F51000FCF67B26C3F980DA4CBF729C7EFB65EC5F +:10F5200010636D876D86545AE93D4EB5116D4820C4 +:10F530003F6CD62055C1BF1731B9A81672D1A2CFE2 +:10F5400008205F39E101EB389519BA54177966BB89 +:10F55000189F54472E5EA4205FADB7B4AB049072E1 +:10F56000F3EFCD3A986C1EB734D750BAA3596F4712 +:10F57000B9B9E5237566FBF0DEF2F8DF425FDDEA3C +:10F5800006E2BFC42E48ED50B0BFA61766B3FCDA42 +:10F590005125B53719989FE942FDE0177CBC5631DB +:10F5A0002EA9C4FACFA8807AD0290FB7B8635F46D6 +:10F5B000795833CAA5AC403C577179A876A77D43EA +:10F5C000D9F7B5EB2B473188616DF4599287EAEA98 +:10F5D00061868AF25025E461ECED3ED4873DF35F0D +:10F5E0005ED25E3500201FE913CCD04B3F413ED0A8 +:10F5F000275AF0F519CAC3A9E3AFB63EF96B6DB44B +:10F60000F24D2F2BDF51E53154A5375C85A7A5239B +:10F61000B1E1BDF9ADBA4AF059B46F3E73A62B9B68 +:10F6200053F02A1BFCF6E608F1DDFA6683D29B054F +:10F630001F7A91A7C6B3BCE043281F43F99CEB1681 +:10F64000DC487CE92E4A01CAC9EDC89FE7E0702B6F +:10F650004D7322D3913522CF9648175B03D663F9B9 +:10F6600040CA9B508EFC29CBF7264CD6BEB8869755 +:10F6700037287B13B866DCEEE7E55F56BACDC444A5 +:10F680004BFBC4CDA6599EA9CFF2E97ACDDA1FEB88 +:10F690007FB8051E3844F5657FF39457797F7EDE89 +:10F6A000FE26E52533517EEAFBBF49698B30D30244 +:10F6B000D638FAB9A927BFCE348767C6A9BCF17E70 +:10F6C0003311B496DF6F229E64F938655D22C1EA7A +:10F6D0006F845895C2E85038B329C24C23F0CF4A02 +:10F6E000996EC30A1FC777667EB713BC812A5E3E38 +:10F6F000E2C6E7CC6455A67CB2F2AB04C2EF2F8A17 +:10F700008321EC055C1FDD9CC5981D547ECD2F1810 +:10F71000DFBB4B3D51B23BCA59A68C7D8FC4C1AAF9 +:10F720000FDC11ED35AB3C4B3E64F09E43F0C69AC6 +:10F7300066E68037618557C2D31FFC128EDCFCCA97 +:10F74000C777F255FDA5E37E3591B1BABFC31D451C +:10F75000B3014D282864BF7CF85D53615D965CCE93 +:10F76000686010FD66C2D0DEFD96CE1C08298BDCD9 +:10F77000FFADE95B85798EB7D94A7186CE2C7F853E +:10F78000158FE7887A4E3E94F3F3F49ADF15B6F9B5 +:10F7900081D6168985FA9FDF7A7F7C662CD8BBDEFE +:10F7A000D38A42E3D7CF18F715E0E381B782962CCE +:10F7B000136A33E3155D2CC74B651DAF38766AF1CC +:10F7C000E9944B09AFBF17BCDFB5C17B939BC96FF1 +:10F7D00016FA9F6A78034CBF9E941CD69C981C9E78 +:10F7E000AA7E8BF057C65FEF69903E97E175D98589 +:10F7F0003EB2FBA5FEFBACF15782458C9ECB7E79D9 +:10F80000C52BE7BA30C3F87C4466FC26C520B87324 +:10F81000F17BAEF900A46CFDFCBDE6930BAFA75ADB +:10F820002F9DA8BE5DF19B00A07CADAE8214DA18BE +:10F83000AB0F9F970FACBFD5BF985C8A70785BCF3A +:10F84000047334C0066CC2EC8DD5D2FEB8A8F68421 +:10F85000EC8F9B9AA1BD85D9350F859BC85E5AADAB +:10F8600000B567FB524831BB66CC33DB7DB311FE7C +:10F87000E86D94AE76B3F2207E3FA44F66530854F1 +:10F88000178E62E883D57EF9FDB986A1ECFBCD55D4 +:10F89000EC3B638DD521DE1FFB1EC3FA79D5FC7BC3 +:10F8A0002EB8F26A183C16BCFB3DA978367D59EF9C +:10F8B0007211FCB7A13DE6C5FD8041A93FD01647B6 +:10F8C000A60B0CF118DB2A7AB79BE5E2FB8175D514 +:10F8D0003F4AE3D67A8DB0EB1E3FEFFBD089FAA208 +:10F8E000AACD7461FB28771DDCE6B0BB82C3657EC0 +:10F8F000A03299751070E46FE9B1E32A27A11D17B2 +:10F900001676D0792BCE9D84EB6C4F398CB295CF87 +:10F910005971F624B4DB0A7D4D2F4C64E317327D18 +:10F920009A44D1D10CA509EDFF8B0AB3F2CBBA6989 +:10F93000BE992956BEEEBC61155766D9FF302AD252 +:10F940007C657E40839DAF6F1376EC2DC2AE2D4754 +:10F95000191F2BF88F098B9F57EDD16BFED3B95E22 +:10F960000BD41837225F0E688028DADFEB18FEE22E +:10F97000163AF96BECFAAD50B3CFEB54CD67239840 +:10F9800097B9C6E6EEDF295F1B217E25D62F14EB43 +:10F9900056A026AAC487F73F7FE77C73CDFB2B02D6 +:10F9A0009F6C9CABB38DF359E1A530C8C619F3B772 +:10F9B0001F2780E358D7B113C43B2CDE6EE27E1BB9 +:10F9C0006510F7737E98124DD33EEF7AF2D35D2B1C +:10F9D000FA84F8261DED1C82394BBF5A9527E36F38 +:10F9E000C3FFA9B3F2B3D145A6CB5F7EA7E090A534 +:10F9F000FE7657A8E835DCD49F0D677FAC66DA83C6 +:10FA0000F0076A128E60A14D9F1E6FEE2E38C4F46F +:10FA1000C6CDFA0CD2C7B9C6FB21D3A3692657BB02 +:10FA20009A7D94DEDBAC43DA8B7E8B08A5DF63F234 +:10FA300087DFB7B27D24A6F73447E9FB96E67194D9 +:10FA4000DED56C52BAA9B981D23B9A63546F43F3A5 +:10FA50004C4A7BF0F9211BAF4EAC6FCCCE3A7366AB +:10FA60002AE1423FEE3E885633FCAEC6EF16F8D789 +:10FA7000B9263D4E7232D34F7E8F02E1F70840CA5D +:10FA8000ACC276CFA9B00372CF2B29E67581EAE22A +:10FA9000E36B35347840CACB6EA075AB640A5BB7B4 +:10FAA000185DB582ED85885796A7EF056C3D43FF3D +:10FAB000A07F0AA4FD23A98986ED8B44FBD6A08BE9 +:10FAC000EAADABD168DD73F2C508D0A75561E59802 +:10FAD0008FFCD4BE90C6EB4FE4E3159CCF143DB32E +:10FAE000EB5B751775BA6E0C5F3FFD358C5F2C7242 +:10FAF0005130F50F486928572B691EEBC2535E64DD +:10FB0000DD317ED4CB2A583F77B02D35AE6BBBB6F6 +:10FB1000BFABCFB6D039A8727B7DC4AC773B10BFEA +:10FB2000233426D76C1C757B2085EB0EA3878AF0C7 +:10FB3000E60B0532C2C7E7ADB6406A9B9229D70BE8 +:10FB400038DE47E85113D7B99EEF7EF1DDE84EABC2 +:10FB5000D82E05D16D46A63C24DB99F67621D92E08 +:10FB6000018A86EDD6B37690290FCB7630CAD62E91 +:10FB70002CDBC1B3268DB7D1DECE5F207026E61F09 +:10FB80001E1775C52DFAC15F65BAB8DCD8E9948B2C +:10FB90007F8A40D0E1F184F231E2630ACF2B8AAF51 +:10FBA000F56317FAB3EC721D1E63A71B5459F28C50 +:10FBB0007417A1EC16931DD480F6C6B6D6ECF4DA11 +:10FBC000A0C5A655E3FC266AB6F9493A6DF0093A94 +:10FBD000B606B2D269832EE8B8006C7496F4DA20C7 +:10FBE000E9B52C3BBD36E4A0D70649AFE5F67692E1 +:10FBF0005E1B72D06B83A4D7627B3B492F273DC22B +:10FC0000E3D28A9D6E6D943F55F470EA850E97415C +:10FC1000DF5DBB4D7D12EA871B34DA57438DAEE0C2 +:10FC20007E00CA4F70FD8026C075612DFE2AED331F +:10FC3000368F5D788EC5ECAB39C95727A11D1E5490 +:10FC400064F9A14968876FF3F0FC75C9E393D00E9E +:10FC50007FC4159BAB92BD93021ADF812F6F2C05D9 +:10FC60001B1948A76B4D3F43BE397DBB2B9A3032E1 +:10FC7000F07881E305B7EF1F6759BF72CF43E017F4 +:10FC8000EB0C3D2138BF45706A299A772F382F62D7 +:10FC90007032BBC240FE66FC6BB49E1A38612E5FA8 +:10FCA0002F7AD667C7FED7D9FE8CED2E1BDFD46C1A +:10FCB0000ED8F866D8FA425BBE6AED405BBEB2A5CC +:10FCC000D296376E38C3D6DF9065B5B67CF9E2734D +:10FCD0006CF98173EB6DED7BF10B707ED9A9BE7C65 +:10FCE00023E2B9870E899A7AA283A8BF3B59536F42 +:10FCF000E3A71CE55FF9B666FA18FEB5220FAD431F +:10FD000000D7107E24BEF275487850BF140553E723 +:10FD1000B3F2806E26D02FA0EA26A01DE1D2E39494 +:10FD20007747ECF275211A4A8CFE5FD9A5816F4C9A +:10FD30009FFD9B9FA4FFFEE6E5E417B9BEAB457CA3 +:10FD40005DBD836D97D0DF9360FA71071BD7CDCC73 +:10FD50001C7F18F942F00FE367D42B459A22F6175F +:10FD6000272767D529BBFE19BAD10E7F459B431FB4 +:10FD70009D207F7F56F2DB1FFE364034817ABC3FE8 +:10FD8000FC8DD114A1FF4E4EFE872CB3E3A77CB1AE +:10FD9000C721277F5FFCB5AA20F8A2A91EF112DABD +:10FDA0000C705305DA5DCFEAD9EC0AC92F77CCBACB +:10FDB0002D60B5F7618CC776FE2EC7A1BC9A2DFFCA +:10FDC00079E313A847FB2394E03EA46DAD39E62FF9 +:10FDD000E8BDE1A2CA80753DFFBCCF3F43E76F9FFE +:10FDE00054FB480FBCE5FA6B7916F81DFBB2DEED4B +:10FDF000135C5EE27E97554FB29F1AB4B7821088AB +:10FE0000229E8FFBC323219FED0F7D3C3DD5FBB68A +:10FE10005DB3F8FE26F1725EAA1AF189FA1DCF8D44 +:10FE20005F1E9122BA5FE482DBB17CB88BCAAF0B54 +:10FE300084B7215C5F57E3D76BC508EF9014C55FAB +:10FE400068697D46C8324F6117C9F9E7B28F56B568 +:10FE50005C5B6F5BEFE0E27AF4634A7EBCAB654DBE +:10FE6000BDB03B5AB5CF957D9413CE2D1AD99B9F2B +:10FE70004FFB4885ECFDFCA3D847BFD096AEB0DB66 +:10FE8000470F733A88FA1D2D0FD79F48B9B48F02D8 +:10FE9000418FD8D73BEC971A661FE1795250D82F83 +:10FEA0003529B257FC35296EBFD4487BC6BE7E5D6E +:10FEB0008B066871C63EEAA37FF393F4DFDFBC7262 +:10FEC000ADEFFEA0B48FDAB87DC4708DF1276A0D56 +:10FED000F77BA88EF57D9CFB7FBB7D945D7EFBC38D +:10FEE000DF0668E3F6513FF89B990B7FFFE0F6D100 +:10FEF0006E0DA47EFFFFC43ECAC527FFBBEDA30C59 +:10FF00009DFF36768ED3AE9176C4A9B66FA47DC21E +:10FF1000EC981A0DF51EB3B3D08E39EE6AF7DDCE2C +:10FF2000E6739DCAB03514E356F87EE6062DB6C1D9 +:10FF30004DFE8DB48E76C666D4E763859E45B90FB7 +:10FF40008AB83D2D0A334660FDF866B7E51C420DC0 +:10FF5000A6F59E739BCF111E989D679FBFC08BC453 +:10FF6000C37E7781DCF79C1DE3F3FA31E101D2DC3B +:10FF7000DED2D23E4CFF43AC6FB41E1759F1C1F133 +:10FF8000A3468D14EA03D6FE3FDCC536BCF86C7878 +:10FF900061EB101F0F546ECFC9EF3C0D8CD115F4DF +:10FFA00087B36C07F2EF002C3298BC415BC330D6AC +:10FFB000FF80D8AA6F60FC5CE8E5696F02D3BF03DD +:10FFC0003A674FC7B46578EDE17A562F3FAA5F389C +:10FFD000D5C07515C8AFB8063BA3F3505772D270A1 +:10FFE000718EC3E4F9D995C7853C9B60B7CB5D861C +:10FFF00026FD4995B9E585FD281F7B7BB7CF251FD9 +:020000022000DC +:100000006EAB5C937C5E7D62F2399DCB7582FD4365 +:100010007D51E0E827DFB4AF1321B0E459F98782BE +:100020008F01BEF1998CA7C36D3E03E34FAA5C3AE2 +:10003000C64DE6835E80FC1798A201C659EA45DDED +:100040000974C1F6479716E14747BBFF42CB7EA232 +:10005000C0C3E5B568C6948A95ACDF6363787CFE5F +:10006000009DC7813AE77333CA97D7921FBE8DCEE2 +:100070004D938C9F2AF9FE86CE6FD654EDD5ADEB0D +:10008000D4688FF47338F9832DE175C29E66F851F8 +:10009000AB5C26DA019F963FD44FC81F79D31DE78A +:1000A0004927492F53DCBB3851FEF8B4E349BAF66F +:1000B00096AB1B894F8B66CCF5A1DDBF2A32A3CF4F +:1000C00073D4DE74BD8DE81AA8023395A5FFF33C06 +:1000D0004A26AEC0195F6BD91F39ED75B5B46EE60F +:1000E000D6BEE856E4B4CB78BFFEE5AAF147545E2D +:1000F0009A4EEB804FF4B7C6B82D81FAF318DA0C9C +:100100000C1F6ADBA834EA4FA882E80E5E85E23F46 +:10011000FC8649FB703AEFAECBC0E72977D9C6D34E +:100120008A02F6F3E79909C50ABF7FB987E0F0E1D3 +:1001300078A8A775D6A182F730B87FAFD7FED16176 +:1001400037AC2EAFCD1A67A0FDADF6AB17D9E13DA8 +:10015000E17641CD78CD6247E56EA7C16B167BAAEB +:100160000DF9DDC207ABDCB05F61EB70327231C4F8 +:100170000D96C7A23280564CC7231FD6F2757DA7B5 +:1001800042E7C324D206FEC7CF892EF318D49FCBF3 +:1001900017273CA94113A8BE7162E748C707F3F8C7 +:1001A000A422056CF5EFF778A85F0D62749E7EFCC3 +:1001B00077E747A85F937DAACBC0E1ECF7324FFC0D +:1001C0007E4F31B21D87071B903F621CF70BD0DDBD +:1001D0001CD6EEF8BA19749F28177C9B1CF2B549FF +:1001E000C465416C4C3FF3E2727C9C8DD981F5B5BE +:1001F0005880EE2DB5717B68B0187FC7B219F47DB9 +:10020000C7FABEE57C8BB08FEE42FB88EC1C9DF2FA +:100210003D708978B33B057CF27B8D97C7671D15D0 +:1002200072BFC36706E85EC013D3025F60F255F980 +:100230009C1AC523CCB2356D057D8D3F70AEDD3F78 +:1002400072B2F11D9D9E5011D9D18EF88E5CED6574 +:100250005CC7A7C5CB9D621F53E35D90A4F393F4E5 +:10026000B9249F95428F542E03B2E3062F8694C182 +:10027000EA1ACBDA47A591AF3FFC18AC7C3218A242 +:100280002E20BD600667D7D1BD094EBF36179D53DE +:100290000FBECA93C290B661C20E838DFC3E83BC72 +:1002A00077B1C3175DE1457DD74A961F5426ECF719 +:1002B000440683E57E04D32383D0AE637A6990E35A +:1002C000FBA7A54381F7EF43874D5A9B5FB7B42F38 +:1002D0005320966DFD3BDDCBF9B4ECCAF779FCD722 +:1002E0000D417855CEBF12E9D9568074B86BEEB384 +:1002F00093F0DE49A215A2781765C8727B1C449D55 +:10030000378FDFEB00338DF6F2CAD917773E8A7448 +:100310009D0836FD95456FD479E93E08D71B9BE6CD +:10032000CEE0E9872AF149D53248E13DA3296D4D58 +:1003300007DD2C5FBE1CE8DCBCBC35A1A03FABF2E6 +:100340000688E23083D181C7F255B32065D2FA0521 +:10035000CF45EA68A9A39F0AE4135C775AECF773C8 +:1003600086DC60E78BAA56FB7D9C52C117A50EBEAA +:1003700070F65369B44D4378872E73F17B3B33EDB0 +:10038000F76BAAA0FDCDEFE37C0E05A3C8EF556B7C +:10039000EDE33AFBD720FE75C4CB434B374F3B9D73 +:1003A000D5DFB2AC7E00E265872F964FF7A2F01240 +:1003B00051967D712F7E95F6468EFA19FD99B0C53E +:1003C000333BD3D5D525D7CC61B5D6841240E327AE +:1003D000BE4E7ADD2DE4F589C1F3E85ED7AAA25AB4 +:1003E0008A0B3B8879B4A7CA87955AF5BD1BE3767B +:1003F0000764F22B518F66E1F3E5822F5F077339B3 +:10040000E26194B72982E37ACA4BDE9BCDC663CB07 +:100410009F99CAD26EA137C0E7AB6B7FB5DF6F0A79 +:10042000EAAF894B6C24874527E657B8D21BBF1922 +:10043000C74FD4B36D04EE3F0B219544FA36B5098E +:100440007F7B4FBD36512F81F73B7BEAC5DBC0BABE +:10045000DF64F536887AA6AD5EAC57BD3B453DB04E +:100460008D6BF61AF71E091F58FB8BF6EA6FBBB7A8 +:1004700098C307D6FE8C5EFDED92F0D9EAE9BDEA9D +:10048000DD27FA03DBB8601FB7A77CA44794C72811 +:10049000FEFDF1E2A9C41F878AA736E07DC46B7E0A +:1004A000E6163AE2725AAF55C1570745BD96602D20 +:1004B000D90DC966685DCCF696AD787FB81AEFF1B4 +:1004C000CEA17DBEFC2EE9C7BEEBD9BF5F4DF77E46 +:1004D000E577ADD54F71E4EC3BEDC35A3E52851F35 +:1004E0006EC0143CA76C8DB884FFFBB5A459C5E45D +:1004F000BD4CB3E5D794F3F251ADAF2513789F48C7 +:100500008BD1FD146F041E196ED1233DE37F66F07D +:10051000F3738C0CFCEF3BE07FDF06BFCCFB07F3F3 +:10052000F2B1BE639313ECD795A84BD97E7998AFFF +:10053000B885D6F3CFEDFC5C2DA6669D1FCF67E690 +:10054000C7F3727E67FBD429FF58F3D31DF3D31D85 +:10055000F3D36DF31BEF2B9882FC78A2F373D6BB19 +:10056000D91D8BA0DDBAB2F84764FFAF1C0CD4EFE5 +:1005700004DF8BC91BB19CC97607F56794A2BE1F27 +:1005800005E6085F71FFED9EC62072DCA786787CC9 +:100590002A147BC439702C82FECDB7BCBA889FE385 +:1005A000707A7C3ADF37897CA523CF7EF92BAE9B0E +:1005B000189EC8F7910E3DDFDFBA5651321AD7B5F3 +:1005C000D690A958D7354FCFBA7631AD6B2B23D9FA +:1005D000D735DC36D3BE48AC357734F3F7043688EC +:1005E000FBB12BCB6BA9DE06793F253195F49B5CE3 +:1005F000371FFFDABC860AA61FDF7D8EBF1F71C0C2 +:10060000C7FD3FAB9BA19DBF87E0A3F431D66F9C94 +:100610005538C0EC3D4C1F66F61EA6FB9B2394FE8E +:10062000A8D9A0742F1B17D3FB9BA394EE691E4778 +:10063000E95DC25EDC24FCBD5F2A77D1FAF9BD66B4 +:1006400058AB55A39FD747E93DCDFA5ACD8DF665F6 +:1006500084D23F2B3316FAC85FD199CC67F47AE87D +:10066000D92ABA373EB15C237F076869357F4CE6EB +:10067000BBC4EB9F95FA461FA3D339868BD7F3A54E +:1006800092E1ECF59661BD718646F04030A1868B13 +:10069000B2D6FB16C25157C4E1063D9E0C65EFEF82 +:1006A0003BD85F6D9180AFC84806B3F797C4FECEC4 +:1006B0008A08F822DD8FE765AFD78AFD8D8808F8B4 +:1006C000CA3BEAF3B28F7B0BD62B2D6CA37B3BE7A7 +:1006D0002E06E26F6FB9B1957C15A2DEB6C14DE072 +:1006E000627C5B3AA0AD09EB7DB12906952CAD2C5F +:1006F00089818BF1BFB78895337822A29F097379DE +:10070000F9362C0F59CA45FBF10B5839CB5796DAFD +:10071000CBE578DE3690FA24CD8C50F0AE859EFB8A +:10072000D5982F71F1FC1EDFBF4C41B92F11E74E58 +:100730001D22EF6DB1B72F09F07C1ACBD938256196 +:10074000DEBE53D42F2DE4F3F65FEAA338E17BBE7F +:10075000FDCDB239C333F33DED3BCBBF30C732BF24 +:100760007BBE731395CBF99CD6BC96CA73C96B64D8 +:10077000960B4C8BDE2A691B4EF6A4B40F479D7670 +:10078000717A36A38B3BC6E1EA6EAD6C5951457068 +:1007900025E85C55C0B5E55A3B5C83BF69876BCBE8 +:1007A00037ED700DBEAE6FB80EF8B85ECB051F1BEF +:1007B000DFB48E9FBAD13EBEB1C23E7E6A857D7CDB +:1007C00023F9A9C74F5BE972F7B7ECE30FF937FBE1 +:1007D000F877FF9B7DFC21D77FBAF1FF56F6B8E989 +:1007E0008B7FE413F6AE6AB53B9B1236BB93D57391 +:1007F000F985BDAB5AEDD878C266C7B27A5E51CFE3 +:10080000B4D58BF5AA17F40B7BDC36AED96BDC02C2 +:10081000512FEDB2F617EDD55F8984CF65EDCFE8A6 +:10082000D5DF20D19F69ABA7F7AA6788FEC0362E17 +:10083000D8C70511FF759D88FF2AF070795D1EE706 +:10084000FBEC52882BB8DFD707C0A843B83E0FE5B2 +:10085000EF21154C5D7E1ADA27CAD4E5A7E3FAD753 +:100860005A00B67DDB343FDFAF8DF3AB348E9E078D +:100870004D580EBE44D98596FBAE5B45BD9EF260D9 +:10088000A2ECAB96F22F8BF6ADE2BEE0F96B3A5AD2 +:1008900050CFE88358FD2CFC375DF627CAA128DA33 +:1008A0006132B8375E3663EC4D601DD7CDE13A4D0D +:1008B0008C5B9E1DAED60A3E6E4A8CBBD52FED8D4D +:1008C0004419E151E7A9FC7E7BE89BCA1F197E60B1 +:1008D000BBCFF61E5081A7E9DE0A064772B00BF0C7 +:1008E0007EC2EAF2BEFD392DCD76BFA7A6C7E81EAF +:1008F000F9C0057AAD0AB9DBDDD9E06AC876EE3019 +:100900005FCCA765417D5B15C277C8EEBF650C0E55 +:10091000D67BC89779E2F391CF7AF96F5B7CB67D8D +:100920007E4149DFF7BEE4FDA89E79B08EB2D1EDDD +:1009300056BF38E77A8EF72FEF9B1514BA68DF7928 +:100940006C383F2F80441958EDB18281F53EEBF8A9 +:100950006B1CE3F9618689F6272E53282F9E2A48BF +:10096000E1FDBA40519B5E81EB42A483CE0141DCA4 +:100970007393FDB64466D07EFC98B8FFAA45DA268C +:10098000B9487E047CBAD055629C811B354833BD82 +:1009900076C81DBFD55F6CA59BA920FE8EBB53E416 +:1009A0000F4A5630FA2BBDE7BFC9CFEF8FDD69CCB8 +:1009B000F8554516FADEED376CF70D077EE081F449 +:1009C000E8DCF533F5385C3D7C1B61FC3A82F40AC7 +:1009D000F1ED368FB9CD9F2DCE42EA0771FE3D670E +:1009E0001C881FE392DFB2795C75D80D284FF29E08 +:1009F0008D3C17BA4AF8C7E6083FEC5C8885B1F031 +:100A00006D70D1FDB1B7E1D9F0680BFD1FF3F3F3C1 +:100A10000526E0E4FF92E7BD57B6B96DFEB0F91BBD +:100A2000EDF97930A304F5D6BCF56E48317C5EE56E +:100A3000F097DD27E63B1F9A56A11DB0D2CDFDF2FF +:100A40007374D006B0A565C98FB7D4CD66F92705F4 +:100A5000DEDF627C6358E46D6130E5C1B89B57F717 +:100A60008DBE780260FBD4AA81A86F0B20EB7B704F +:100A700057B4DAE1EB0F7E27BC002B08DE5C706810 +:100A80003B95ACFEAD5FFBEDE789B9E23B64BCC5CD +:100A900031E423AB1FE6F779A924F94779DC457FD8 +:100AA000EDFFDA4FFB25BE4E0FCA4FA3D6D4A0B838 +:100AB00032E7525E77DC1CC4E6E9DE3F293D086C74 +:100AC000F55AFBAED73D15485F32C358CDD45B0A0B +:100AD000AC1ECAE5810B13B67A55ACDED0DCF5BA94 +:100AE000845EFDE9EEEF79701FF7F60F5EB900E561 +:100AF00072D1232AF8D8B85DBB4390A67D4CCA8337 +:100B0000FBB485FBD4ACE7B81429C0F0B0E8FE1004 +:100B1000AD970BF77A53D359FB853F7A7524303C58 +:100B200074ADE87E6A10AEBB3F50F8796AA27324B8 +:100B3000AE6B0B35F8D75896FE2201CE87477E92D2 +:100B400047F78E959D072FA77EDB2F717B2DFA220D +:100B50003FE0A679B17ADC1FB74B495567D127F240 +:100B6000FCEBC82E85C3B7DF9DF2237C3BB77AE24E +:100B70000C8EC69DEF105F4DBE7F4F18F1D0B85F51 +:100B8000B59DE736EE54D3DE9194BEE2A57BA9660F +:100B900050A9437C72FDB874DF12F29F2F6DBFF92C +:100BA0001D358CEDEDFCCDF0124D235E9F57A3D388 +:100BB00031FFE0BD6183A1EAAD8E1D61C42BEB77EF +:100BC000B6271FCF7FED7E6FECFF83C2DEFD31CBFA +:100BD000DD83FCD5D8BE868FB7EF9F5F47FDD2E897 +:100BE00090A3B7F097B2DEE72E66C071EEB273C085 +:100BF00009D9978BF61CBB3BC1C63DB2F74F77278F +:100C000018FC8BFFDF7B775F8F76D0637E1DF5400E +:100C1000E30FFE330C9675F3D2005FC7BA76DDFBA7 +:100C2000FD3B997C74BDE8A5F5A3EBD1D787E03BEC +:100C3000295D0FFCA5C460F5973D7A1EF901963D2C +:100C400034B9B4AFF513F935E5B5C29522BA1AFB3C +:100C50001534CE98A12D52077D9ED8A7829FC1F949 +:100C6000F60B5EBA1FD5C8BE2DAF457A2D21BD8CBF +:100C7000F91B189E97EE5EFD8E3A321BBE13835C05 +:100C800078D90098184690DE5FFDCA17C760EAA6BB +:100C9000F39546E826BDEA6CD7F81CA3EB59B9E9F1 +:100CA000780C3EF4E0E15FE3EE357CDC7646C7701D +:100CB0006F3ABE8DBF8CEF4DC76F39E8780C16DFE9 +:100CC000732716EE1B90F53C589E9F2D79E86B7D9F +:100CD000DA5B522FF487E7050A87EBBC80B92680E0 +:100CE000F2BAF787DFBFB388D3793A434CD79E6314 +:100CF0004380F1C91BEEEECB513F763FEAD571BD83 +:100D00005FF8E8F3246F5D0F3DE331C84E87A0C262 +:100D1000EC8D2EE8F9E940FB63293FAB82C6EDA1DB +:100D2000B4379CA1D7D2D4850D4698BEBF42DF53BD +:100D30005C0E96A60E5EA464A1DFC100BFC70DA91C +:100D400062C2CB92EDBFF540D04E57651CD2F395F1 +:100D5000A9F83D173DE5FC759CFFD916BA6EE7F280 +:100D60009B4B4EBBB67A358C6770D2B94BBC9BD2CD +:100D700098529ECF4677B90E9EECB9EA01A77C8BBC +:100D800079F727DFFDCFE7E4F0F5C38061E31B8946 +:100D9000B7231F66D7FBCF0B7DB1149A1A060EED51 +:100DA000BD0E6A6CE339A82203EF118C7364FC76E4 +:100DB000E4076A2AC1BEAF6A7F82F4B7534F2CCDD5 +:100DC0006167BF21C7DB7F7024EAB3238FFF84F8FC +:100DD00071E9EE573CE8AF796AE7839ECEE119FEF0 +:100DE000C775C1FA7EC691FB0E8E24FD8DFD67A1ED +:100DF000CF31D17FE3017BFF8DBBDFB1F5BF28D1C0 +:100E0000EE21FF6A3FE3BCA59997E07CDFEA70031F +:100E1000BE97F456BBDA90CD0E7A29E0B6C553AD35 +:100E20000AD5BD80FE49B5D063A0FE6BB9D17C3E2A +:100E300081EBE5336EFE8EA566BE80E7D7C9028FD3 +:100E400081FBDE96D0C56058F4789B039F7A913E73 +:100E500009F703FA94D818EBFE4BC25F60BA6CF046 +:100E60002F0B35941A41BE8F33F07D0A2D4AFE694F +:100E7000353CB581EED5EB2EDD9F75DDE6FDB98302 +:100E800031DA77B975171816FE1A35F9E233D1053C +:100E9000A78161DB0FAC9BC2CF83E5FCD70D86CD6C +:100EA000C0F4F03AA5FB30BE439498C6E30BA57D91 +:100EB0000762DF1FC67D7F456F7B0F4CD3407D44AB +:100EC000EAC8E0E39B96FBCD99F85D305C14C71C43 +:100ED000A54D8006718A13F26194C550DC77B55335 +:100EE0001A64EA0DD373F3B85EF24237E56F6BF81C +:100EF000039D7394E6C5C6E41563BE50E1F348D381 +:100F00003E4F5EDF77E59597F5A50F608A76C4EAD8 +:100F10004FF2C266DACFA03BF3E30119BCC8383BFD +:100F2000D9EF3AFF447A1F03E73908DF6BC3C78D57 +:100F30004AF8F9019FB749F96299778C8335F53AF8 +:100F4000B1049368C615F750BCA7D7467E9381D0ED +:100F50004E693974505AE8D3158DE07B99FC5D2EAB +:100F6000F8037C9CE780EF04EC78A7FD7D9D6ABECA +:100F70001867744C8A7DCEFA027B1C523C8FEF13AB +:100F800096E5B964DC73DCBA6F4BC262C281BF887C +:100F90003F4B26DB7D372FBE20CFB29F55831D3CB4 +:100FA000AECCB15F3E4FBD81CE455647FA8EE75A73 +:100FB00029E2C27395B715FB666F05829FFBC114CA +:100FC0001F8FEF36C1D0ADFC88B13D75D67849D3BF +:100FD000F68E8E1BF950453C2728F5A35CB1340FE3 +:100FE000F98AD1E156C18721E8149D7493FF639B70 +:100FF00027BE0AE71BA96A52F8F7B8C2FD65A68AA0 +:10100000F32D11FDBBF21697C5FB9827CC647C62CB +:10101000899B592FE8A269A0056A119ECD82FE4ED8 +:10102000FEB4C7BF4ABB2E28725E1187F7E49867EB +:10103000E97D31AD2848F12FC1312DDF708DC4F924 +:1010400037E9A8578332BE25CAE315E5BEDAF9EEC3 +:101050008BD71117EB16FBF75E71E2623DBE153FB1 +:1010600064B19B9DEBF17D7939DE131A973D1E51DA +:10107000DA699F94FFE5FE73B1AFE3290242372995 +:101080009E53137E8B4917E9E46F3FBA5BE1EF1182 +:101090003AF8E9E8DEFC91A82F519EF15DF33CF1AE +:1010A0005DD97DF020DA572D61300B0A49FF192AEE +:1010B000C3FF2A65944F61E9927DEF3CFD08FAF188 +:1010C0000FA880EFB91D0DCA7350B3008996076B46 +:1010D0006D74FEA4F3EA7D8EC9E5EF6A5DCA5F9088 +:1010E000DABDBB5BA17B622A9C7907BE73D578D839 +:1010F0000D2956FE2EF07EDFDDCCED86F93F7BB06C +:101100008E49026C14F0E0FA655D67063404C0B0E5 +:10111000F04944AE0B09B303DF7F9E2BF0531C2B29 +:10112000B4D593F3FBD39C86C3E4FF89CF23FB158F +:10113000DF11B4F60FC23F62B07FC8974E3C1C77F8 +:10114000C53D40EB4A2C3F4D7610DB4FE3FE23A517 +:1011500044116EA73F65E97E85D6B3ABD87A86EF9A +:101160004B5F9572EC471DEF224BFC3BF9D61D14EB +:101170007C1B84600E3C47D3FC7C96E4EEEA9FF136 +:10118000B8B4ABF728F48E93DA797A3E10DE55F2D4 +:101190004BBD0E4DB7B31526C3DF0EFC792376BCCD +:1011A000FB0D3BDEF36AECF80D45ED7874E2397F18 +:1011B0005CA5ADFE2275B187984FE0BB86FD437CF0 +:1011C000333D49F358CAE691367AE373C18175AB72 +:1011D000D05FD22F1E1DF81BE1C0DF313870909711 +:1011E00042CC5742A24FF32ED3D224574E39947893 +:1011F0002AD73B26D1B76888FCD411D1893297B75A +:101200001BE86BE742551B253994F1C9793DEBEAA0 +:10121000ABF0314BAFB9F0D02B7320B7DCB537FB57 +:10122000A2739950DFD70CD1B9D5785EAE53BA19F5 +:10123000EB9FD5E77A4BE3B921AAD37A22CE4D8E24 +:101240000EE7EF5AB5A7DF2F41FBEFD6DAEE0BD052 +:10125000EE6FBC92C75B7E2FC4D7DF1F8BF4FC9070 +:1012600087F4DD4D311798E82F38A0A614F443E930 +:10127000E6CFCE45BBED80DBA0F54FEF7EFA5FA851 +:101280007CB48EE7CC65AEB651382EAB4FFEFEA3D4 +:10129000075E0D5F61B18FBAF67FF70BB83E6D72D6 +:1012A000C1826CFB80F9413E7E57CD1F4A902D973D +:1012B000F8BA695FBEBAD3EE67F3ECE37EB8A5FB7C +:1012C0002F247BF4D03CFE0EE74347F87DD4A9EAF7 +:1012D000AC7F1AC1F2E3FF53E37A15CCE9B34BA814 +:1012E0000AD133E9677866785C8FF19B28177F74A1 +:1012F000A5F0EF1C8CFF227FE769FC8B7812C68A71 +:101300009AF8BBF18F84A71EC674CA0185FC478D6D +:1013100047F8FA36B6C3EE273A7B0AD30BACFFBACE +:1013200003DCBF55D7C9CF07CE7EC15E6F7CA73D1A +:101330003FA11FFE5D1914FBC830949C4C7C6EDAF3 +:101340006DAE0D72BB8AEE9345B5ECFBAF57437C97 +:101350007FC4F041F33FDA0DD1156C1E47E70E9CB8 +:1013600084F7938EBECFCF1B8E7EA83664DB5F6D75 +:101370000D727ED9E4E1E7C79BE6055337B2793CAD +:101380003E6FE169B8AFFAF3B7E2A7E97DD9254C22 +:1013900045B8684D34F3611CCA470BBFE7066D655D +:1013A000D9DE51967221E544CA47D9BC403C9B5FC7 +:1013B000B45ACCAF7E5E0DC5E3763DA6D01953D7A7 +:1013C0000A06571F784CC08A41084FE3FEF7C84F02 +:1013D000E13B90DDDF7D3018E67CBB2271E30486C3 +:1013E000AF6F32E14EA03C78DA2AB2F59F80F5E487 +:1013F000BFDA19E4FCDCE5E3FB70D0DACAF0BD88A3 +:10140000AEFD93A7AD6270DEC9E40FD7EF4DEE28B5 +:10141000C19D5802F4EE1F887B85E517C0D69B2C32 +:10142000FBB59F07273D1F64F37C3EC8E39306C4CA +:10143000A30AC21DFDE87818FB3FFA8197E83750F0 +:10144000F88B64BB7783DC0E5F1D329F217E595081 +:10145000444A311A0F47E78E06386B3FC3779638F8 +:1014600033691715C6990E1C83EF58BAF87918DB43 +:10147000A7E1FEA311E44F828C54297F78D90DEFA8 +:101480008949BDAB1C50D221A63FC7F88269F4CB75 +:10149000142E70E1DB3BCC1EF5F1FE3AEC762B6AA4 +:1014A00060D4BFA80378D03EDF1F497D2CF5784B70 +:1014B00001D77F2DEB34D28F9BB54E3FFAA52B4C35 +:1014C000A35E33E8FD568AB718BC80CB7BDED02DF7 +:1014D000053D76D10480073E52B3FA47CE10FCB4E6 +:1014E0003A14FF0BE27BE4E1EEC7D1BC8AFA61005B +:1014F000D27BAAB07BC6BFCDF591BC5FD028F625C4 +:101500004E7DB4C92FEC1868FB359EDBFFE48F1AC3 +:10151000DD9FEED13FF3A6D27A0AEAF02790BF26EC +:10152000FC5C6C0F84FE61BB3DC2CBD9BF88271128 +:101530000EA7BE19074C2F29FDEB1D279D9911DE23 +:1015400093C710BED187999C59DA3BF5D4C0905807 +:1015500067859E3A06134BCF3332FC54BB3CFA846A +:10156000D7C23F524F65F829457CE81C47015F4FC1 +:101570005E1F8AFAE5172AFA518E4EE27FFFE709CD +:101580009423468782F753D3901FD61F38DF8F7C72 +:10159000BFF7F0641F8AD5D5117EDF4C3B7851022E +:1015A00004FB58CF95DDE0338235880F17E141D534 +:1015B00059DE32FEBB6D8AB86F69E45F94E55D6CFD +:1015C000995E1DE1F7C9F61EAECCE7FBD134D1BD63 +:1015D00087EF85FF42CA85E477277F4B7948B2566B +:1015E0002E8B1DA12AED62FF68F72324851D91949F +:1015F000EFCE24CAC83E5C26ECC36470D8CD13D9A4 +:10160000AF2DE97A1DCF3D96852A29BE7A5931C77B +:101610009F131F326DFC80D98B9638F846AD9BFC2A +:10162000638D1F786CDF257E73E145E2F71CC4AF44 +:10163000F2C9F17B4EC820FE70E2F9D3CEBFFCEABE +:101640007159EFF1FDA3CC7F02C41FE9247F2CBFA9 +:101650004F22F94DEA8FBA6B5A937946465FC8FB21 +:101660002052EF48FD72F6E2B627F2B2E80FA7DE8D +:1016700088BAF52BD632FC459F0CD23B1D4E3DF26D +:101680003EFE52467EB7BB434C2E1F78EA2D17FA1A +:101690004D1E7A98CD9D95470F4EE17EC18E133B2E +:1016A000EF9276ABB4579DF5A4BD2AD71D79DED451 +:1016B000118AEF09317C29FB993C313C2475BE4FDE +:1016C000FE7930DE8E70E5319803180B5893AEE04A +:1016D000FB59BBBCE692CF3C87FCB5A7355AFF123D +:1016E0006CFDAB567AC321C79F1F12EF0930AE4382 +:1016F000BBA6BC0EF8604BF97B01E523218EEB33D2 +:101700005E2BC5793E2DD6995F85F8FA2CD39F07BD +:10171000633F45F8DD1A24BCB59F1C6EE95FEC08F9 +:10172000994F229E7C0D26CD63900E51B4F7076928 +:10173000ED4A94C151B8D8507A9C3D725D67FD0D59 +:101740009A6E4C42391A84770AB03EDA4759E8F368 +:101750004A88FBC197F83A9F4213BE717A5343B847 +:101760008FF3F5CC3B0851E1E7B2C7811C7DF4F95A +:10177000C178FEF9BB6FBF17C273ADFFD2BA430881 +:10178000E71B37FC3A84F7217E7703DF7F5CEEB0FE +:10179000733E10F8BC241C3B8AF3FDD7E68FEA6C3D +:1017A000EFAF2CE7E73357A554DC94F6F0FBA29D8E +:1017B00079E4DB93F925ED036C79C9A74BBC3C6E4A +:1017C000CB39FFB3C2FC1CFDAADD5B3D830C1C3F83 +:1017D000AE84D9F86F083BEE8D7D21F27F4878E624 +:1017E000EC1EE5413CFCD701AF38F7EF7073FC9B72 +:1017F000D3F17C2E2E48E184F3A9C7F2A8BF2B3782 +:10180000A86477CC66632D67FC1D3F7015EDC39D02 +:10181000F3B8F277C6D45246BF2BD72864AF62FD27 +:101820001B183FC497AFA6733CE73C67271CF12306 +:10183000C2AE70C699CC3FC0CFDFE78271F3C48AD5 +:101840002C712707A6D1B9DBFC7EF63D5561B1EFBF +:10185000A983B3316EFE180CFFF7E146FFFB9E37FC +:101860009A8182C8DE6AF6517AA459A7F428EA4F11 +:101870003C3FDF7FF029E233ADA30EE57EEFE15779 +:10188000F32E35327AFC4B5BDF7BE22E961F0DDCAC +:10189000CF23FDEDB304DECF15FA7CBEB017467F33 +:1018A000D0B73E9F85F818D91B5EA9C767E1DF2135 +:1018B000B4E041EA75273EDE3D3C340FF9E3FCB06D +:1018C000F3BCF9D3E12557BB256AF678462947478B +:1018D000439CAFE76EBF70D540367EF2D1D7877498 +:1018E000723DF11CEA09C9A7004D1E9463273F4AC7 +:1018F0003EE9E1BB03B7109E247F30B98A8873CEDE +:1019000008EE0F9DFCD75F7C5397BB7308EA052751 +:101910009F7539EE43CBF4EB61EE7F9F6B9853716B +:10192000BFCA969B55FC3C90EBA337B4B6A7AE4715 +:1019300079DDCEE565C98FF7FC08F5D0C2FB3784A9 +:10194000510FBDA9B595E0788B77AC0CE3B9FA1BC4 +:101950005A228CEDDF4CA959E31FEF0F2BF2EF75E4 +:10196000DAE224A0357101CAF19F77B8753C076BA4 +:10197000DCE9E5E7EEFB38DE589E9FB7EFCB1E278C +:10198000B1F0DE0D25068FA7B5C74B6C7793FF022C +:10199000FD6B384CAEF3E29EF3E7F6BECFD31BF7F8 +:1019A00089389B7DD3B2C64BC8B804271FDFE3E05C +:1019B0005F861FF2FB25185CE46E17E7E4C95D77CC +:1019C0008C7C85C17764FBCFC3CA70AB3F9E9FC739 +:1019D000BFDB7EC53D3E576EFEED12FC9EB1275229 +:1019E00059E32716BBD361DC572DDEEAA67DE0E282 +:1019F0003D2AE03B78F0A297D6F3457B9EFCCD399B +:101A00000CBE450FB88BA6F369509C84A4574F1C9D +:101A10008BA0CFC2079FE4E7CB86886711745AF486 +:101A2000C0410FC6E538F139B9FDA0A7D311074170 +:101A3000F46A7F652ADD27DC75DC83EBEC9B8F295C +:101A4000F4F7399DED176C7D328CFA02F144710088 +:101A5000826EB9E396D2173C3C86EA91DFAE3F3AFC +:101A600036A32C8E257EBFEF6106C78297BC143F3C +:101A7000B5E0BE6B28CEE875AD89F3FD969525B827 +:101A8000FE2E70274A744AF9F705775F4BFC38FF42 +:101A9000996B4BC47DA432EEEF4994E13CAFDCFC82 +:101AA000359AE73C88133F2ED8A2C6D0CF724C831C +:101AB0008607B2C8CD17F2B9DCBCBECD8B8FE8C0AB +:101AC000EBC2CF997856157F3FD2795EC5DF8B394F +:101AD00026F6DF1F89F5187075B3ECC71AB7AFEE9D +:101AE000403ABD35D82CD5299E404B08BCD1BBEB24 +:101AF000EA33E7950AFD46EFDC483B68327EC7FAD9 +:101B00001D6E7AEFC6D2CEF65ECD32313E833BA05B +:101B10009CC5D292EC7ED099F9522F88F81BC967E8 +:101B2000B9F4C0761ECFF2FE735CCF605C0E957781 +:101B3000B8D3A5B6781CAFEDDE7526CEC42DE4DC97 +:101B40005ECEE0A478991EFC3EA6A4F0FD63C92FEA +:101B5000F3D67BEDF1793DFCE37CAFC71E3F33DF6D +:101B60006197C9B4D7FA9FEF38AFDB7C62F1338B52 +:101B7000DD298A7F5AFCA297F6278BF7B8638897EE +:101B80003FED7EE2379732BEFF53BB9463BBDE75F9 +:101B9000CAF182BD63219B1CFF291885AC72CCBEA3 +:101BA0006795E360E65CC38053AF77E7E7D0BB1788 +:101BB00038F0C9EC867C8C237EEB078B4E237F8527 +:101BC00003BF52DF3AF5E86B6183F0DC3BDE8FAF99 +:101BD000FB99784C8E47C99F0B7FB884C6E9E163B7 +:101BE000C9A7928F73C48D39F1E92C2F44DFD9D85E +:101BF000DE7E91443DD4E0DF674A7A80BFF3E60A97 +:101C000044917FFB3BEF7C36BF42BEFB7616DF176D +:101C1000F2F3CE6850C7BF5401EE2243CD76CE1EFC +:101C20009DECCA6AFF27F2F9B9463EFA2318DE1E78 +:101C3000CE37F8BD0735261C79ED748F81CE56114D +:101C4000CE8230C9995BC4A9B09EE93E7A34CFF503 +:101C50009EC1FAD892FFD4F91AA36F74B4EB9AA17B +:101C60002CFF50FE4BE76BE8AF9DE07AB092E57F2A +:101C70009CFF5B9E3FCB35DACD587527BC7CFE14AC +:101C8000567FA998F752E92769196BF39368AE5705 +:101C90006EC7F31CED61372459FE6626F7BEDACC19 +:101CA00039739E17127E96CFF3B094E55755FC7AA0 +:101CB000156E229F0EC4EFCA277CD51B88E723BA76 +:101CC0008FE27796FDE43C8A237D389FC7BD9FF95C +:101CD000E004FAFB8EA7108EDDF9C5B9E16871F357 +:101CE0007E8EEC3D7332E2F9CCD3D0A796A147ADFE +:101CF00066D0773F437B82DBFD11BCDF922CF05036 +:101D00003F0FE74BFA9D582AE35ED43CCE176ABEDC +:101D1000ABE901961E14FCF0B8C00BFEE0BEFBE878 +:101D2000A3A5DBF8BB56DD4390DEAAFAEEEFD1DEC9 +:101D3000ECBE2C8FFE7EC84B018EB797021C6F97AE +:101D4000E4AF759FC1BED7FA865C834CFF92B2FBAD +:101D50005A4CB7EBF15F723C401AFBBDF47295F739 +:101D60001B6C0AE17B718AC9ED708531D32C868F9B +:101D7000A4098667288AB03DFE43556BBBD3347EE9 +:101D8000C8363E94B37593C9F925E339BD186E6919 +:101D90001D7D7E1CCF4BF866A62A939D06C1F37B62 +:101DA000E48F51DED460DC4F5DCACC2AC8F25E7885 +:101DB00057809F6F7661FB9199F881C6FF76D17E3F +:101DC000B611E7C0F20F1E01F1770AF9BB3BD2EF63 +:101DD00031FE975793FF7BCCFE453CCE44F8BBE4E5 +:101DE000797EDD217E3EE7F46F4D80B5A44FC73B81 +:101DF000F4E884FDFF44FAB5BFF3B9BF48BD3A101B +:101E0000069EE4F91CE896F3B9FF01DBE0C6DF00AB +:101E1000800000001F8B080000000000000BB55A76 +:101E20007B7054559AFF6EDF7E25DDE9F48B100838 +:101E3000869B0448421E36498010706CDE4C8C1222 +:101E400060406418695021E6D56CD6416A748B0EE7 +:101E500041459DB2326A29556BCD5E18DC45496615 +:101E60001B4934BA9D4C0710120437082830AE665F +:101E7000DC1D44973C645670D42AF6FBCE39977E1D +:101E80002428F3C790A24E9F7BCF3DF73BBFEFF7CF +:101E9000BDCEB91E3D7883F900D7E9DF9D91B62A02 +:101EA0005902980EF44F0729000D66FCA5005C3915 +:101EB00091990C385EAF07909D004645865267E4C5 +:101EC000B9B66D38CE14E9BF93ACB0790ACED81F3D +:101ED000001BB5B00E0AA3E6B5F37917CA568012F7 +:101EE0009CFF12A8A60C8069FD392FCFC1BEA1C7E7 +:101EF000002ABD979EA0FBE7746A00459BD1FBBBFF +:101F0000E2305EDA91602B84DBF195A93A50CC6C1B +:101F10005EB88EFF1394445072227D4B8E33A62FF1 +:101F200027DAF64032FE0878FB52518E627E0B9221 +:101F30003CE363E679C7B6A487E42EB66FAC20B95C +:101F4000934B3363E68113FACFFAB19F837FD73384 +:101F500069A995C96194BF082ABD12CAEBF9183C5A +:101F600061947FC6193E4E7BCE130EC83EC4B1F4B9 +:101F7000E3D8EB6510D5C779B67EFC95E348943C71 +:101F8000A5F624F7C53CFC311EC65F9747C5D113A3 +:101F9000269CCEC81E540334F4E22037B65F800A74 +:101FA00088DB34284C0686AB0C2AF6DF04DF0B7383 +:101FB000B0BDB66DD8716472044F8737164FD79293 +:101FC000583CC754C6E23976752C6EE37CB138A50F +:101FD000554D8DB97FDBE6A298FEC4AD6531E33384 +:101FE00002F362FA593BCB63C64F6E5E1ED3CFDE5F +:101FF000B526667CAEBA21E67EDEBEEA5BD27F41C4 +:10200000B021665CBCFE6FEFF855CCBC65F25A1986 +:1020100032233C08E01FF1A088544CFA473D84610C +:10202000A4FE67BA03C4F8BF59FF5B49FF9628FDB9 +:10203000CB6B937DD691F6ABB59A5EFF89D63A9D70 +:10204000F48A73A070D748CF786DC860DD2961EB42 +:1020500040EEACC5EB5BCDFCFAA3029F6B09E92A0D +:10206000ADDF113AF657095B540BB3C3C02716B561 +:102070000979F3A8AC3412AF5E942B254079D25085 +:1020800075BA2CE4910EAAC8AF3CA7D3ADAB8C9225 +:10209000EF793B0E1E43AD8EB5FF6C445BC5F7A6D2 +:1020A0005920602E62CFD1DAE89F1770DD36170312 +:1020B00005FF55EC5C3001EF3BFA731407E02DECA3 +:1020C000DF06702191CB7B2191CBB9C6A434F59367 +:1020D000FF90D5C924CF5EBBEF5FECF89E0BD2E337 +:1020E000067C3318DC0103D95D9A1902367C5F93B4 +:1020F00001D65562DF016EA901DB6478C54EF68515 +:102100006228D7911487ABF392FBF1FAFB24C23813 +:10211000B2318F0E6600DCA7F9C3AA5CE60FAFE010 +:102120001AFB48A17A2519B0BDF26016BB7EFE7E6F +:10213000B442B4A7F3468E8786C325E127BFDC6689 +:1021400066EDE56DF618BF59B5FB852405E7399FA7 +:10215000034B8251F8750BFCBAED32D3E7A0FAE7D6 +:10216000148267E8A1EFA690D07EA9EF492B0E79E3 +:102170006AD73F5402EAC1D8B62C803A815F18155D +:10218000365E9BC71F9A0B84033196E6BBF723D8B4 +:102190004CF2DDFB1DB651EFEBB31BD8737DE27D36 +:1021A000ABB0B1236EAB502F0E6A8FCD5944768100 +:1021B000D7C312F697F68081EC61992FC340F29C49 +:1021C00006CFD97694E78F76FEFE9F41A581E4FA8B +:1021D000F0FEBA241A77633E6D1E14D681F1E42313 +:1021E00047C090827E6BF80EC9B34761EF33D3F5D9 +:1021F000CAB5694F5895C8FB3E04DFC059D4F77281 +:10220000F0B079B5F9D1F262FCE21B55359FBA32D4 +:10221000C91FEAC04CFEB0D3C4FCE150F5B5D69757 +:10222000F0FEBAB4FEDB8CF8DC85EAEFA6102EF7E0 +:10223000ED924141FDFF39C9F739F147C3E3FC8312 +:102240007F49A2FB6B4CEAAB2FA11DC07E93E755E3 +:10225000A0E7F6B3E7B4715FD9E75EB653FC2C454F +:10226000A066DDDC3E35FCE7BF9E3B9678A6F1EB31 +:1022700061C1AF86D7B2C7129F1A926EF08BF75F1B +:10228000CD1A4BFC9A21715EC6CFDB85FC52B27130 +:10229000DDC82B0579D5F5CD3C17F98983279CC579 +:1022A00024A71E7C3A47141F0EBEBF268FEEC339EB +:1022B000F72DC94BB6194039EF052EE749611FAB21 +:1022C00043AE62D23BDA9DCD81E3D6FCC76B037F80 +:1022D000247C3AF7BFFA188D29B9353C34FF7420B5 +:1022E00091C7231071CE2370C13897A3475187201F +:1022F000D143F9C2CDFCD601F20BC8AB6B3A747C6A +:1023000059E4AF2A81FC82053C0AB5E865DE9B8D65 +:102310007A6CEAD6C133D8B59153D3FC4F29F66510 +:102320009DF03FE035A7621C11FE29E737EA921DB8 +:10233000CC7EBCD6F533984B6472951CA9AEA0F741 +:10234000421FFA7194B512FF281ECC86CD87135018 +:10235000CE19BB303FC07133CFF1FB9A5F9F15D6CA +:10236000AD3726D3B85F7F25DB08A2D83830FB48CD +:10237000F9E734EF6C887A6E94F830C711971FDC58 +:10238000627C584C0100710FE670FF1E0C27AA8179 +:102390000C366D716501BA26B43DBAFFEF6E1E476B +:1023A0008CD2608E19FDF05DBFD9B373E71CA4C356 +:1023B000248E0BF59BF4844531E3F18DBCF1C854B8 +:1023C000E60FE17B948AF0B20B99E3E42941BBE389 +:1023D000C1D8139377868F7E6BEBC775B43A95FFA0 +:1023E000247D0D635E437E2141DF6F748CB2BE3766 +:1023F000C9BF22FF9F77E898BCE60EC9ABE2FBCDD0 +:102400008A17245C4382DD3E4D9622E3173A78BE5C +:102410005B77F442BA11F535A03B61CBC7F96BDBB2 +:10242000DFB0E1F2618BCD57457CAE39FFC10C0ABC +:102430005D00BBD32B9308A7CC64B2A7023D04F484 +:102440004523E5F0EFC2C520E5EB77B9589BDB21CA +:10245000B1F5F9C37C9D831D4DCE68BF71E3B93FD3 +:10246000748E27BDED1F03ABC91F17848A37118FE8 +:10247000491603EAE2F56FF2D87CDB1C194C2FF801 +:102480007E3D5D075075CB71D07E033E87F30E7E97 +:1024900023B371DABC051D73653BF2283FDC7C88F1 +:1024A000F2C2849049213D27EC058E4B2881F945E5 +:1024B0007FD762A0FC75C8011E09EFB7260E7F42C8 +:1024C000BC18EE34297B24C2AF199C387FAB91C76E +:1024D000CF5C348437AC91EBDAFB12422F03F92B3B +:1024E000E48757A5FBFA66B8C31A8D7B12C35D75E6 +:1024F000705EB526867556F2FBC8C93D4CAE889C09 +:10250000C0DEABC999CBEA8056E3F0C5C7DC4C2EE0 +:102510003BF12117B89C10CA565EA5E7ED5EB68E5A +:1025200004BBE2094823E5F217625E8C76F7DC769D +:10253000B861E764F7FEC448DF8C36D19AC9F90D5B +:1025400081B33B17CC89EA93C32A8D3CDFEE38B7C1 +:1025500073C704561F0564E48305DB2427AD93C7C6 +:102560003F340DEF98228E830771B298F9FD1BE37B +:1025700091EF56EA5BF9384FB2DD522E31BB01B212 +:102580009B7AE1671E91C217EF44D57E1D3E54A889 +:10259000A02CB5C7DE61BCADD1855E2A20FF98E8CE +:1025A000FB03F9F7B73ED6810DD7FFE56B096A0546 +:1025B000E291F3F6EE14AF75E47C4F9DDBFE7C1ADE +:1025C000E9FB6D4941A4312F1C4E27F9EA439F1BBB +:1025D000BDD82EEEF89391E2D32F9CBE5EB283D28B +:1025E0008EC6F984DF2C686EB25B995FF4114F835D +:1025F000A9DC7F5C3933654F6314DE43C2BE60D80B +:102600003791EC2624ECB38BF21F6CDB451ED6DE33 +:102610007D5F965210792E0087D200E7DC0E47D2FC +:1026200008E71BF3A9FA25C4A7BC0FCDEBBC517C6E +:10263000FB42D8FB17E27D01A7EF53C2A1A6FB33F3 +:10264000A30DD7E5FF9F603AC5A720E669F61FF006 +:102650008BFE38BBF1EB878D34DE7F09981F41BDBF +:10266000EE48463DEDFFB063EA7A2B931F9271DD91 +:10267000EDE74DCC6FB66770FB6B3C7BB590FCD63D +:10268000D5CE9A8984D7298741E3F9BC44B2A70300 +:10269000C0FC98668FF9648F287A3EF1BC84FAB941 +:1026A0006CBE56635F39B3BF761D90FD21CF19EF25 +:1026B00091E776CA3FF2EDC87BF67C36B3E7D63EAB +:1026C0000C78D80FA01F9FCCFAF35650BFB56F817E +:1026D0009DD9B30EA12D22BB0C1F62F304B1A6221B +:1026E000D54950199DA72E74D898BC9A7F5C21ECCF +:1026F0003498A3247B703D16598EB183A878C9FB0A +:10270000229EAE759A9E7E71025993880B222FEB02 +:10271000127930F88A99BFFF4711CB1ADE2D5BDAA8 +:1027200082EB6D382973FF2F787248E4C947B6A54C +:10273000B23EC50B05F5341D5B2FFAD319DECDF380 +:1027400029FC942E693E4C6D596570BE81E2E2EA27 +:10275000BEC3066ECE79C4BFB6433FCDD313DFCF21 +:102760009B2001456CFB76F893D711872D5D88FF80 +:1027700028710997C3F887119DF1F166BC1992FA87 +:10278000EF99EDC1FACF39EEA7FA04B41F2206E2A1 +:1027900071BB73ECD30114A8C3E92D72227E9FB8DC +:1027A0007CAC1D3AF56D0AF9F4F6339FD9C8DFB752 +:1027B00019BD79C4B3B64CAC1746E1E744A781F91B +:1027C000FB12536C9EAEB52B9DBCAE9A12806789EE +:1027D0003FF56DB25D457D0FB4C95E23E65117BD6F +:1027E000BE143D427A0902AB66537C17F5EF431CD9 +:1027F000767888F2178C331B5F34C4D4A5B5625F3A +:10280000231BFA9F4C439CFC7B2556D756C5E523DA +:10281000B594BF14527DB1DB48EBA9DE1B370FE541 +:10282000318534EE87EBDC954E91C7644116E53176 +:10283000C823564F0F9F953D7B2806EAA1C784FC0D +:10284000DDAFE338A1DF64F6A8E533896EEF22B28D +:10285000FB450E9EB7B48ABA75B8555299FDEC4344 +:102860003F8FFDB24BCA6EE0389C499D41EBE1BC05 +:102870002CD3F3F165A10C667FA55EACE771DD1B7F +:10288000B19E5769DD5A9EA71AD8FA31FCB23C6F47 +:1028900016A84D361CB7699FC4F67D6AF61962F218 +:1028A0003CBFC0A776D7A9A3544ED605E3EE0B7C58 +:1028B000FC71F8BC413F668DC4E9574EB11F900EC4 +:1028C000E9D1F91EF43847AD0B347CB43CFB7F0DE5 +:1028D0003CBFF840CCAF8DDBE5E47EB4DE0B6CFF93 +:1028E000A856955595E783D6F5C89707045F1E103F +:1028F0007CF1031F57B74F52C314AF7ECDF56EC6A0 +:102900003FC2E5A1E0FA4569CA485E550B3CAA5AA8 +:102910000C2CFF05D86C24FBAC7A256E9CC0A53A24 +:102920000E977A9F14271FCFC7FF56F96A0C7CBFFA +:10293000A606F91550FE7EF2C6EBEF0D8DE753614A +:102940006A8CFE96B86E497FF179F281A3532DF41B +:10295000FC959E4CB60FA1F1267E9E4522CF5EBC13 +:102960008BE7A3031DF32D05544F9DD07B249CA71B +:10297000F8E4FFD90A108FA24E192A708AA150F1EB +:10298000B3015CE7C19E492B148C0F4527F52CBE83 +:10299000149F2C52A9AE293A5964C94A62C6E3A2CF +:1029A0007A01E761F179E8C4A4D3F9E4677B16946E +:1029B00010EC8D278A2C94471C04BEAF219D2C71EE +:1029C000F547C59BF79C325BD793A9FFFD1CE5F942 +:1029D0008B0F183C948F2C360CBF3FDB4DEFD77B11 +:1029E0001AB15F7B72C3F604D2FB6B9287D2F1A35C +:1029F0007D0DEE9F937E4306BB89C9FBCB43743F9D +:102A0000D0227926E3787FE7C2BC56EC17ED2EF68C +:102A100010CCDAFB8A1CCA0B15942F8EB3B03A7E09 +:102A2000F16D0616772F8FB7FC8EF2A56AEFEE4593 +:102A3000E48F2FBF73D048FE60A85582545CC8D184 +:102A4000D4C3BF0FE03A2FBF79CA4849F9FCB65347 +:102A5000C6FE1FC827065419C2AC7E6F36521D54DD +:102A6000B75BEBF71B494F9522BFAADFFB27D6AF19 +:102A7000A63A01DF57FD8AAC2AF8F370E75B46C23D +:102A8000BBBE4582B11951F7F74AECBEC6FB0DC07B +:102A900079B041F8A71AB10F5943FB90781D7672AF +:102AA0007FA3F1FEC17DCB8E52F87EA839D60F3DB3 +:102AB0002C78BE89EA52567FFB8CA4D74DBBE2C668 +:102AC000099E3FFC233C4F76093F950BB9C4F3ABFD +:102AD00073793CB97A2AD1928FEBBADA2B7B007EDC +:102AE00090EF2CFE9E10F9C295B08EC5336DDC6060 +:102AF000C75F58BCF19FB862A4FC7651E82BA68F43 +:102B00008A50F702C2FB6EF0D5127E77872C76B220 +:102B1000FF8A7EEE0FCA432695F6C1EF86E00ED2FD +:102B2000F350D7BFED70126FFE95F30684BFDB2420 +:102B300070DD2470DD840EDF852EB63ABFFB252CB8 +:102B400007A01CB81F2A0F0A3FF44A2CCE1879EEB2 +:102B5000277DD5874CF00CDEBF4BF8A3BB5AB83F9E +:102B60008A8F93F5621F60685CDE52B6DF8AF52EAD +:102B7000E571B52DB1F8D78B7D81FAB8389CE9E2C3 +:102B800079C28FD5FFF17A5A10A7A78A61CE9F72BA +:102B90008A7BB8FE9EF0F67CDAB7D3F08AD7538FE3 +:102BA00092953C5A3DABB5EF8BBC5FEB2F057EFE9B +:102BB00014B4375BA3EBF8D75D3CFE54CF9203A46B +:102BC000E71BF5CEA4C3858A2E52EF609DB3D635A0 +:102BD0009DD73DD370EA63136470BB23F5CE53A930 +:102BE0002F541451BED2C2FDC86029CE974CF93C77 +:102BF00030FFE56F31A954A7F8913FACCE21DE60DC +:102C00005B199216126FB07EA872218ECB68EB18FA +:102C10007158D6C1F39E650BBE627CEB9DC4D77B19 +:102C200045AF8C1DAD9ED0EA88FA6F789EAA5DAF45 +:102C300047BBA7F1F52189D5C56D87FE9A9E81FE18 +:102C400073A8F35AFA7A6C5F76F13C4ECB53873116 +:102C50004FCD14790AE5CF1BB9CA6013A6C35B91A7 +:102C6000871B459C036907B3937A4A76896FED12F7 +:102C7000DFC7791B2FCC44FFFB4122CB63063FE427 +:102C8000E743F4FCE398470D6E081E71E2F8ABAD24 +:102C9000128B7F1B31C7FD49D1487BAF13BC6C84BD +:102CA000EDA22EDBC1DAF29C039F3D46FEA8C5AC27 +:102CB000907F1DEC6832B2FD6535EAF9CC91F95090 +:102CC0009DE06FDD8FEC6BBD1EC74B5C07CB6F8744 +:102CD0007A65BB4962F8FD767C344E22FF693B94ED +:102CE000C0F43C74CAAA529EFFA5E0DF65B1EFDED6 +:102CF000582A335C74B3789BD7F55626E995F4E0EF +:102D0000A37D94AEB7A67AD93E9FCAF858B34FA612 +:102D1000C3BE88FC410BDB0BD5FA1ABE7E812FCADD +:102D200035C5E88EC8D5AEEFB77946B11B493AC470 +:102D3000F4A69362EB5CFFDB72A51A654FB89E7533 +:102D4000E4DF42821FA01F4E21BF1C76294CBEC665 +:102D500010D7B3AE93B7F8FE557CDFC6C0DE3FE2B6 +:102D6000FEBC402DDDBF9A6101C6936F0215D4DF12 +:102D70009229333FB5E583EA6C887A3F48BC1EF759 +:102D80001B8653583D7C4AC7E4F39FBA9232C94A26 +:102D90007E70F7027B3EF937EE1F8E665AAA88DFF7 +:102DA000017AEFD8C83CE52E7E9E00B4DE54CA6698 +:102DB0005EE4F38AF56E87E50C87ED8267DD221FFE +:102DC000C5BAE93CD9637CDD74B37C37AA7E6378ED +:102DD0005D9DAB9CFE39F2A0A8571FA07AFDE0399B +:102DE000EE271A3B377D4A75B0FF8209C84F6CE960 +:102DF000DA944D71187CBEDB29BFBBDAF5F0ED6CBF +:102E0000FF52DACEE40A907CA994379D4DA17CA8AC +:102E1000AEF36C0A8BEBEDD35FA03C09F3A2BBE8E9 +:102E20003AE62B8C7F45274B18FF0E9E2871659143 +:102E3000E0E0B1D0BC75BDFA4AC2A7AEB7E4BD0AA6 +:102E4000CA5F4ECE637992961715533D4E7952EF75 +:102E5000A4983C69D8C5F3A4A1EE04B6FF2141268D +:102E6000E70F4C8AE14F6DDBBB2C9FA8ED90BDD1E5 +:102E70003CD29ED3BBF57C7FD42DF81394BC8C1F21 +:102E800007785BDB7190ADAFC61064FA6E6C31F001 +:102E9000FBADBC0568E6FB2CE00C101EEFD125D481 +:102EA00043B9519D40FBEBC733787D11AF8F67DD90 +:102EB000FC1CEBF879DF44E2CBF1B9BE6CFB287166 +:102EC0002300F378DD2D09BCDB0C2CAF8C1FF7B48D +:102ED0009BEF4FD85C1073DEA8B5BF7473FE941BD4 +:102EE000F93E55FCFDB96E614F289A0E7971BAC250 +:102EF000607F46D413E3D0DFDE23FCED8ABB0D2CCC +:102F0000EF382DCE99EED1FC6E298FDFDA7EFFB23D +:102F100057E0092CFFE16BC867E760CBBCB17E6F5F +:102F2000A5C8AF562C89BB2EF2A9953F924FCD7202 +:102F30008BBA610A4CE17583D542FBA25FF718ECAE +:102F400032935B9D545930729D9ABF392ACE877A4D +:102F5000D00F52DB98FB11DBA73ADE7DFEF70EE6C1 +:102F600047132093EF3BB2FDFABA9BECD737DEB0A4 +:102F7000D39FC5F04ED3D300E5F9F923F5B452E061 +:102F80005D67BE6C64E796B079A74E8E9C539A0C31 +:102F90003E6F1AAEC3D031374CE7978DB926962FC6 +:102FA0000D2C9454F2F72867BA29CADF0F8CE3F985 +:102FB000D7965512DB17EECEFD88C5F1BA709F91FA +:102FC0007835A56DFD13CC7E037086EA254D9F4BA9 +:102FD000CD3C7EDED0A3B65EBAA9D0FA9C01EE97B6 +:102FE000DDACA5F1142FEF11F1716969ACFEB2A14E +:102FF0006F11ED8FDCEB9558BE7433BD2F5F3DED47 +:103000005DA2DBADEABFD9EDDBEAA6FDA2BE2BAB2C +:10301000687FF778EEE7E9145FEB6FC2E726C177C8 +:10302000BF859F8BF92DFC3CCC93AD34F5233E2618 +:10303000876FBB9BFC87EE7BDB54A079FA7FDB209C +:10304000917E80E9E56676F4B498F769B79DFB6FE9 +:10305000373F1FB2529FECD9A04E203F01F9B776FF +:10306000CED7F8F6B142D2D360776FA1314A9F979D +:103070001BD01F507CE93C9CA258A3F9A6137CD31B +:10308000B35692968BB819CBBFCBC43FD2FF81C346 +:10309000F7505D38D0B6C22D295171B5FDB46D72AF +:1030A000D4BC0321998DC77A6CCACAA468399F60C1 +:1030B000720E04F97C00FD53561444DF6F123CEE8F +:1030C000673C7E2A67333B77D778AC07CEE3FA8E2E +:1030D00065C0E2945877D0883FA8CEE832A9744EF4 +:1030E00041FBED8E283B392EEC63261607C4CF59E1 +:1030F000109069DE9938E35AEAEB21AC77D2796017 +:1031000058E6E7DD1380783D43F07AA63EDC2D15C6 +:10311000B271EC5CAA0CFAD8B89FC0306BBD60D716 +:10312000533B0F3CAC2D3587EF2277921F0CB2EF4B +:1031300092C2297AC745333B2A85D1F41759BF1E5D +:103140002E6A3CC5C198F4B07DFCF8715F0B7FEF2F +:10315000A11C8EF43C006C1FEE0EE897E925B3F538 +:10316000B084BE27BB430FE64494F7C0111DB3E7FC +:10317000AE7E45257FE67189E7BEC0E7B03FD3CB81 +:10318000ED9642107DB7A2AD371E87329C8FF605B3 +:1031900067EAB1F2653886D9FBEE24C171DD73416F +:1031A000D153FF923B437CEFC6EBB4F9A24ED399C7 +:1031B000030C8F418A8F63F8798E0DE7296B96E0B7 +:1031C0001C9DCF64F1F56AF39761284DA67C5AAC3B +:1031D00097B6C2CF39F9398F8D9DCF2DB0135E527E +:1031E000384577DD72EBB80EA50093DBF6C0F0E052 +:1031F000632591F32E4FE8D839FA2E47F27AD97722 +:103200003D1EB3354CF939B2E37274DEAD1BB30128 +:10321000C6E0FA24C5CEF0021F28947F8C8D7CEF87 +:1032200002D75D91EF6908C64B2991F37DEDFB9ABA +:103230007DEA7245877A59ED367B482F45E6F46280 +:10324000AA07F7DA7D30867D67D332994DA657A756 +:10325000572645F86E016F29E1AD9DEB4B427F3754 +:103260003BB7275B259E5BD0EDD37741CFA2BD98BE +:103270009DA37D7FC4CFF3D10A15FAEE081E9FAF40 +:10328000D077014F3ACC9E67C8CFD1FA2C91F53553 +:1032900099F9F7044D66FE5D00EC98CEF6CF1E114D +:1032A000E7114D565D0ED55B4D90E8A1925E93F708 +:1032B0009124CEC747FECBC2CE47E3E5FE3ED19771 +:1032C0004FF86AF23F2A7BCE61EE1383E71C0D4F65 +:1032D0005D04CFD56A6653BFC2F02BA1E7A799D48E +:1032E000DB685F648D897FBFA4E1860A65A4B60BA5 +:1032F0007D68F8D949DFB40E2FEA5BE34B6604BF63 +:103300006713396E06FA72228B3DABB0F3FC385C62 +:1033100034DEFD3FD45368B1102A000000000000E5 +:1033200000000000000000001F8B080000000000EB +:10333000000B7BCFCFC0F0A31E81FDD1F8E8389100 +:103340000F534C94118257B3E0D78B0D5B3122D8C9 +:103350009EDC0C0CB29C0C0C7240DC01C49D40FC49 +:103360001288B5B81818B4813801C84E04624B20D1 +:1033700076E086E8A96567606805E25E209ECA4E31 +:10338000BAFDBF2518181A6411FC0B4036AF02E9CC +:10339000E68CE2A1897F1BA2F245B451F9F6BAC0CE +:1033A000F46184E08B6A9366FE36A0DEED46B8E5F4 +:1033B00079CC51F9CC96A8FC6E3354BEAA3B840656 +:1033C000009B2185B9B80300000000000000000048 +:1033D0001F8B080000000000000BC57D0B7C54D53E +:1033E00099F8B977EEDC794F260FC20021B9794000 +:1033F00002267188E1A5A013040B886CC017B4AE37 +:103400000EE111DE44B49AAEB8B99010420861B42E +:10341000A8C18D3841405468830D4A57AB03524BC5 +:103420006DB71B1505772D0D688358A0298A4CFFB1 +:103430006BEBFF7CDF393773EF6426E0BAFFFDA743 +:10344000BF7A38F79C7BEE39DFF79DEF7DCEC8243D +:1034500087A4DD44C837F0474BBF891032205A9209 +:103460007255206308F9A195E09FD62FB6ACAB2129 +:10347000246C2124B290904E27ED28555949212DD6 +:10348000EF982E92744292E07D85907AA1EA686E60 +:103490002921EA5091ECA28F3664CC4E0A38138F62 +:1034A000BB978FFB931A2B96ED351E2C5FAEF16206 +:1034B000D951A390703E21AFD4146079B0C687CFA4 +:1034C000FFB5661C96AFD7F8B17CA3662A96E19A41 +:1034D000722C0FD7CCC1F2484D00DF7BBB66319612 +:1034E000476BAAF0F93B35D558FEB646C5E7BFABEA +:1034F00069C0B2B32688E57B352D581EAB0961BF84 +:103500000F6BF66079A2A61D9FFF47CD412C3FAE01 +:1035100009637937494678DE79E725EB3CBADEFC6A +:10352000671E7C6F5A1A215B468B3E0057FE339F05 +:103530007A0385D1756FF99B694E7B1CB8DC450415 +:103540001C678B8B60FB96431F11A58890E6D15DAD +:103550005E95D6A7F1EF8CD875CC3AAF30DA2F76DE +:103560009C3F12131BC74CDB69BFE1DB587FAD7D6D +:103570001A7C6774B47D77CB7BD6F94E7D3B7BFF9D +:10358000F9D6F7AC80BFCD11898411EF2A21B4B4EC +:103590002B3D2D03289E6D272CC4924DF1AFB49383 +:1035A0002E3A4EF3F827C36229AC9B7653609DEF09 +:1035B0001381C2417511A40705C6181BFDCE582200 +:1035C000E23CF29F39C6BE73C7252CDFF8AB4C082E +:1035D0007DAFF94E21E4A0E3374FBCE8F503BDA968 +:1035E0002F9880DE905C15F84F97B79C8EBD65E2F2 +:1035F000875E95C269F3DFDE9F331FE86F14F1C168 +:10360000F7361FFA3951A0BDA807E157CBD7BD79CE +:10361000EEBC2C4F6162BAA49444C47174B94EE2FA +:103620000FC581EF3F0210287C4C9E10AEC94EFBA7 +:10363000C5C3C33F1219FB6D76957F007051EF34FF +:10364000FB76D179DFEC0B936E6774DE50FF84D686 +:103650009D5F8689C905F33EEB35D1F53BC6C9D7D9 +:10366000D9E86C9C3D3D27E07DE784457E587BF39F +:10367000A82EEF22DADF5AD089EB253EE21B46C79F +:10368000B517A8647E21C0C184788D9DCF7C80F75A +:1036900000C0D3575EC08946871FDCF1BEB542D754 +:1036A000FF798D3E04465FA4296C9DE58AB63FA351 +:1036B000B5DB18FD10ABB17D5B0C1D938C04ED6682 +:1036C0000A68C49718DA2520DCADB38BFACEBB2983 +:1036D000FC6BDC074E5FD81A88B32EBA4FACC077AC +:1036E000924A451FC0AB7922DD2F85D1755E69DF17 +:1036F0003570B86C2E9DED82F1AFC4B78ADA4512F1 +:103700002EE03C93FEFFDA83763AF3687D5438C5A9 +:1037100050BFEEE86043FFD19D3986F6B127461AC7 +:10372000DAC7779518EA377C76BDA1FFC49E498633 +:10373000FA4D91E986FE65E47643FD66EB0F0CFDDC +:10374000A778E61BDABFE75D66689FA63C60A8DF46 +:103750005AF088A1FF6DBE5A43FB3F8CDB64689F23 +:10376000E5FFB1A17EFBD47F31F4BFB3FC3943FB4D +:10377000DD735E32B4CF0DFCCC50AFB4074E027E89 +:103780007EB0F835C37BFF58F596A1FE012153E3C7 +:10379000E197088CCF500AF2745FC3FB5316E70120 +:1037A0009A033A1EC0E8B4A02D019FE4ED2FEC7CF3 +:1037B000CFBAD0C027CD8C8E07B1F63DA1F7E2BFBE +:1037C0003F94EF13D2699DEDD2B7B3795DF357CA39 +:1037D0005FA15D52BF157F75797CD85FE3AB94BE66 +:1037E00009B99EC2571DA2AAF83D3A1EE59726B612 +:1037F00064524D189F22E4017CAEC97D9241C226DD +:103800003A6EAD2BA3AD116042C796D2A05EB8034D +:10381000EAA2E2275D71E06AF2C8063CC5C29738A9 +:10382000532831F7C76755849F3A851448F07DC106 +:10383000EE5B4BD72B91C060813EBF2C06BC30F9AC +:10384000874DEAAF02D9D1FE6B27D27F42FF5342A8 +:10385000681DF657108EB545C40F72431D24877638 +:1038600065233C2DC04FB4F7E803A58BCD57FD264B +:10387000D75067F3BD62FDEB7C635D1BF79F8CF057 +:10388000A47086FA7DBCD267DD3E394AB726E8C708 +:10389000EA8A28906F900F1ADBB5EF5CB6B98B49B6 +:1038A00012C5A395950FDBDD3BA0BC6CCB0C11378B +:1038B00021C562609240E1A04E62F0514F3A42B59C +:1038C000385ED5D8F222806F7C7D8190756C7F7CCC +:1038D0003C4DD4AF2311DE3682DE961FADDB32289D +:1038E0005DC5E1CB77094CFE511A95605C0B61B464 +:1038F000E53005EE8279CAA4DC2F225E7D04E677EE +:1039000068D893732A28FE9A26C83EEC1BA40A277F +:10391000D54FA55EB84EC5BA95D7E7090A8EBF3117 +:10392000F9B03587AE77B34FE47A4110C76BC8FE64 +:10393000CA0B7CDC26058907CABCF8727AA52072FE +:103940003C3E4AAE461F8EC5CF48FA3AE32F04E10B +:10395000A7CD6FCBD0B03507E8713CD3879BC7F5B7 +:103960002F57D673B8D6727D78B3323B8938A3EB24 +:103970009612CC6B03D7A309E99903786FC84E1749 +:1039800061DF6E1018DF3994FDB615F84793E7B084 +:1039900015C60B08D96CBD31F06D487E0FF5FA5A8B +:1039A000977D4E280E3E03821BD7D900388375259C +:1039B000132EB7552FE0CDAA784A1A95BE7434D984 +:1039C000F525CECB594A140BEDEF4C63EFDB3E16D9 +:1039D000420ABEEF770EA2F37070FAB02B46F9BA26 +:1039E00076E22D2AE8910FE71032109FDE6FC09328 +:1039F000A3343003E8DFF457138E4B06B17949A4A2 +:103A0000EA0FF361FC42C6A73CF47FDFD031AC790A +:103A1000317CEBD834DCBFB2877D9F982674DE44BE +:103A2000E72BE58B034D74AD2673A71FF4B18D5DB5 +:103A30006D3E55077F594F07C0873E9E769614C34B +:103A40007775E3C3FBC3666FC9ED879E4C5D6E124D +:103A5000BE0EBE7B4FBFF4E1FAB8ED9D233AB8BC71 +:103A600021B8D2BA016863C958E4135778FF724D80 +:103A7000E89D23C370BDE2D5D0797DCC3EDF90CDEB +:103A8000F5398AEF593A3DEDB2C0F439A296211CBE +:103A9000258EC70D13490FC895CDD9B2B20EF0517E +:103AA0002A8781849052E9F7CDF00F809B52DFC9BD +:103AB0009EFFD0C047D70F99E90B2B89E727A5C5F3 +:103AC000E0F10AEBAF06F8E9FA7703FCAE89C2CF62 +:103AD0004CCA93C240DBC1A948BF6E6D1E13EF52A2 +:103AE000F4F3E885E30D6C7F9AD354124F2FADE5C4 +:103AF000F0BB53F45F047E67927D2702409F39320A +:103B0000DA27B1FD478A8C0F45E16C95004F76C2EC +:103B1000FF668410EEF4AFDC9ACEE147FFCC196F5C +:103B2000FF5500BAA366B3A3189FD74925747F79C0 +:103B300089EAA0F2C12E1109EA59C06C4763FB64FF +:103B40003905F6F12D3ED477CDFC7B9E36AF5E4F26 +:103B5000CF12195EA3ED21EF9D8676338EB7C1C5D6 +:103B6000F51BCF7306BAE87D3F39BEDC192832FD5C +:103B7000274BF470FA790EED39F3D0BB1A0E517859 +:103B8000D7E5FB7D15B0400F413868F243931754D9 +:103B90008E64890300FE010278973CE558C6CAE3AB +:103BA000847C3C460E9B0B6403DF217AFD2607FED6 +:103BB0009BE1C1FD4662E53F2FCBA75FD5BEAA8D35 +:103BC000D95726125F2EDD2E32FD91A869B87E6D81 +:103BD0005F11AE5F68F8A7F2C140AF32CC87321CEC +:103BE0001B09E1E00E6A6641DD45AAB07E695C49C9 +:103BF00058A0E358A4AE06E0CB96712251B3E3D8A7 +:103C0000555C0E255AC79689F1E5C4CDA29BD9C74C +:103C1000CE2ADC1784DC837AA1A006C837A81F0649 +:103C2000B9BCF479018F1B6BAAC927743F590FCF18 +:103C3000457BDD9CA7FAC1DE075901FA23C9286537 +:103C4000A5E453F4F4D98B47B216C7333919FEE50E +:103C500034AA17E7207D2C00FA205623FDF4D24920 +:103C6000461AC80A9887521E775C8E57DE2F211D90 +:103C7000F5D281B62E4586F162E9C35E4A2D0E115A +:103C8000AB9D309F811C7B0303F5F78BC5809FE0C4 +:103C9000D4E1140F03BBE6A13C737179525F38FB8A +:103CA00028A874493ECFAC5B14B0F3890070DD08DE +:103CB000835D0FE3CD5D5B46EBEB61B0C1B4BA6EE3 +:103CC0006699EA646462D44B4545D2F430B15FBD75 +:103CD00046F8C6D2F7FD44EBB7C4C83B42565F9DD9 +:103CE0001E750FFB9E4AFF07FB2B39469E26F98D5A +:103CF000FCDD15F39D17019608DFFBFF57BEE7219A +:103D00008F5B154A0A963CD113A2B499443CC96012 +:103D100027D92753FB8DD63D193D2A4CE94A78A96E +:103D2000E7762AA1FB534FCF6F727EE9ADA8CBAEE9 +:103D3000A7E35E2A75FA805E0752F6989AD2773D1D +:103D40009BB8DED75B2FDC8174BD9ED211E8C36ABD +:103D5000A188FEA68D792F7BF472F194C657FAD014 +:103D60000751244D2EE7C03E14FDB6E2EF4E1FE68C +:103D700018385F2D7D38EE31E2E3DBE2EBC2B7A409 +:103D80008FEFFABDFA44FE07CE9F285E51FF6E50BA +:103D9000FAB703FAE2F571C4AB9DDA2FF1F8ED172B +:103DA000BDF8548DF288DBFF51B961B4FBA5AC5B63 +:103DB0004EB4F5030F29564FE6E3DAAA4DCAA7A978 +:103DC0003080C760EF6C541E5741FFBE047A34E860 +:103DD0007BC132F4FF923CE68F850144D0FB157F16 +:103DE00008FD0C209F74724DCE30EAFDA634BB5105 +:103DF0001ECF5105FDFC6DD532CEC30ADF4B437F8C +:103E00006D08BE6BF290B0CD1DA557F814B3F71F27 +:103E1000B92A3A3069EF091ABD1ADFDB905142E244 +:103E2000E1AFCFF7EE30CE37215F8A7DCF2929DD94 +:103E30003ABD23F17B12E9D6E92F376A711D8EA7AF +:103E40007A33392850FDAFD67B170928489F28C7F9 +:103E50001AA0A4F2B4DE5BE241F9BC4788B1CF15E9 +:103E6000464F4A0AF617AD4CBFD2EA89E7C3BE1BDC +:103E70008D1329A81F27EA5F5B33EE0989321B7374 +:103E8000F55B5B256AFFD4ADF5CF29A7FD1B6B8ED3 +:103E90006E958645FB2D3169F639159F6340AFE17C +:103EA000F44B683F849B48BE01FB8972684527E755 +:103EB0006DA473AB84769FC2F14884DEFD4087DC3D +:103EC000CAD7692127B01F0C84761CE9C271E1456D +:103ED000A8AF37FBFDE5144E8D52C8BA1AF8B98D5C +:103EE000D7155E4FE6750FAF67F33AD98175B34CBE +:103EF000EBB07FCD210FD6EDBC9ECDEB29BC9ECC87 +:103F0000EB39BC2EECC0FA7A998DB7496A67E3DBCE +:103F1000795DE1F5145EF7F07A0EAF9397D9F72D3E +:103F2000ACEE30B7B3F11DBC9ECDEBA9BC9ECCEB83 +:103F3000B9BC2EBC8CF584FCB280C13FCA1F18BC32 +:103F4000357A240057831FAB2BA69DD18B49205C6B +:103F50000FAB42FDFFD0D0BBBCE06F5C7FAAD20BA1 +:103F6000F4537F9B464F01E49F24E356E463662DA0 +:103F7000EE98B67A0EECFFFA0C19ED49C2FD305AF4 +:103F8000FB86E4C0D46CF0577C6022F1EC2EAD6C63 +:103F9000E57CF769D07BA97EDEC2E3914FF278E43D +:103FA000568847D23208F1485A36F37864138F475F +:103FB00036F27864038F47FE04E291F910E79C83A0 +:103FC000E58B108FA4CFF7403C9296BB211E499FF2 +:103FD000EF8478242D77403C923E0F413C9296DB53 +:103FE000793CB23EADE428E81D97AA45D40712CD2E +:103FF0007F6895917F0E596C8C4B0C0A18E3120365 +:10400000E718E31203CA8D718964BF312E9134CE53 +:10401000189770F98C71094781312E61538C718921 +:104020006B0FCE36D48BDABF6FE87FCD9E0A43FB91 +:1040300088D052437B7ECB6A437D58F09F0CFD7342 +:104040001BD619DA9F32E5207D65AB8D867E59D56A +:104050008F1BEA95767FB709FD946957E5AF265F18 +:10406000AAE97A7E192B1F4C99C4EF4739C7E4118E +:10407000FA6081FE8632BF94F5E3EF1D057BDD9289 +:10408000C7E4944589B13B63C6939DBB4FA8F43BFD +:1040900065EEA3DE2EDD7E245EDD7B60EF488C4F77 +:1040A000363ECAECF1265EF65D473DF66BFA5B7C68 +:1040B000BBDC269962F40866D7343D2A60FFEF3AEC +:1040C000BED61E3B6EF47B141563F4F66D48F3AF59 +:1040D000923A9DBE60EE4A9E4F50CE33FBD7C4F756 +:1040E0007B5981EF541D85F77A0FF159687DBD73B7 +:1040F000929FE925A2824276CD6D68A76BFDB579C6 +:10410000D5396733FE42D947D8C0A7EC063FC1FA7C +:10411000B4FEF53739622261AA97982202FAF56453 +:10412000A97C6A36D5C7E56326DF5AC067027B9F44 +:1041300090C7193FF48A063AAE5BA0F13F1F9B1F60 +:10414000CFBBD0F85B6DDA247C5EE7E97F5E169822 +:1041500017CC87CFCB1C7160698AD870BEE323A9C6 +:10416000581F1749C6726C640896632283B01C1DE1 +:10417000C9C5B234928DE575916BF0BD92C8082C1B +:104180004745AEC3E7BEC8282CAF8DDC80CF8B235C +:10419000E3B12C8ADC8CCF0B2365585E13B9159FD5 +:1041A0008F8C4CC37244E4767C5E109985657EE406 +:1041B00007580E8FCCC57258643E9679917958E6AF +:1041C0004696E17B3991255866471EC0E74AE47E52 +:1041D0002CB3228F609919F911964323B558664480 +:1041E000D6623924B209DF1B1CD988E5A0C88FF13B +:1041F000B937F21896E9916D5826479EC3764FA4B9 +:104200000DCBA4C84BF8DC1D79014B57E467F8DCF3 +:1042100019D98FA523F21A3EB7477E8EA52DF21627 +:104220003EB7460E6179253C5D490F1EF7A9918F77 +:104230008FF9D8C8C74B8F19F978C96F8D7CDC7797 +:10424000C4C8C78B5F37F2F1C20E231F1FB9D7C88E +:10425000C70B761AF9F8F056231FCFDB6AE4E3396F +:104260004D463EAED419F978E61A231FCF78D0C850 +:10427000C7072F37F26FEF0223FF4E274F1BEDF4D6 +:10428000C93B0CEDEE092F1AC67396BE1C63D7848A +:1042900090BFD80BFFD5F09E35EF700C5F56197F9D +:1042A0008AF19F0348207EF930B1FBC0AE89C56713 +:1042B0000AE707A9B0EF6899C6F7DD00D877B44CD4 +:1042C000B97502C6A952678E9B07FEB8CBA7040535 +:1042D00074226166753EE841294308F32790FC9BF0 +:1042E000FDB45E3B48AB135580FA5082FE0588FC56 +:1042F000617B36ABFFB2EE91491007AE35F376B570 +:104300007612F8D56A6DAC7EACAE621DF82352927F +:10431000FC83215169A7393E3FFF5892113E032586 +:10432000FF6F245AFEB9ACEB21F027FECA1AF877CA +:1043300089C263B935900521B4F3E6C0F3203A721F +:10434000047F27F42B12FCEF4AC8CF8D7ED35B404D +:1043500070D2F6A152F987D09E3A730FDA171A1C61 +:104360006A5DFDCFE79D5EF944504E6AFE8AA71C48 +:104370006EB43F1B9F904310373717A4A37CA84D02 +:10438000262C1E0A71218C0BB3FAAEA14AA891E922 +:104390008B46B9B2B5FE7E884758413EE5EAFDA797 +:1043A0005DE83F4D024B2117FC033D99122D575AF2 +:1043B000C2F52057BE4AEE3C2998102E1761FD0F1A +:1043C0004D0F61FF758E99E3605D142E5FC07A29F1 +:1043D0005CBE944627860BFD2BF78EE1AA05FC6791 +:1043E000AF60F05F3A4C81BFC3383229C7F115D5B1 +:1043F00087F03B2E79F07D0D8EF4EFC19431D1F82A +:104400003F7D4F360FE83B9E36CEDF25FE7D2E1FCB +:1044100035FAAE4E20AFB47825516FFB567EEFC310 +:10442000B218F73B66A91CE3B47DF8619A511E9A55 +:10443000D258DE83498A1F7746C7318CDF3AF3AA08 +:10444000E2D99ABF85D4DD7655FD1BB4FED44084F5 +:10445000FEB91A9E5A6F437A1CC6DFCFE57ADE5B3F +:10446000BF7F556D02BACC2398CF11ABDF356E15E7 +:10447000911E739399BEA8C15BE2FAA1F65DA9C92A +:10448000A827BE2673BB78EBD5C17F0F877F2EC5CB +:10449000F3BF96F49D07D93993ADC7C3AA0545C1AB +:1044A0007720DF64580BAB4B5BE97C8A13CF87F036 +:1044B000B884B68FA416D69FEC318EDBE7BBA61965 +:1044C000BE78F1B384DFF99671BEF966639C4F7BC9 +:1044D0009FE20BF19DC7F528524DFFE8BCF2891110 +:1044E0008E5ABC4FABBFF5FBB1184FAF0D96B078ED +:1044F000B993C973F2351D7D0CB8BBE2E3418BA7BC +:10450000D671FBB2DEBB03F3D9C85E239DCA831606 +:10451000E0F3C6820A0FCB4763FD2C431FC4FCC8DF +:10452000C682D5E8CF955BFD56B06BE502D107306A +:10453000979227F3F649D86E69657AA705DA15D000 +:104540005B77AE45D1100C35807F98A4493E086357 +:104550004AAD8106E82735101C8700EBA3F3D9C1CB +:10456000F198E195D695D17F6604CBC3367C8FF860 +:1045700087E9FA85F87A33331E0F43BFCC6055675D +:1045800019F8FDAA088E9F99B103CDF2C19ED96298 +:1045900099EEBDED7CFCCD7C3FD9827E0FBE1760CD +:1045A000F98CB1FB577BAF955786A75594C1B8F6E8 +:1045B000607939BED7CADFE3FD9EE6FD86417B29DF +:1045C0005227CEA777BFF37E2D7C1EF5DCDE1F1EA3 +:1045D00064799F75DCEED7FA3DC9C7B3589F7B0657 +:1045E000FC8EF941E68FD5DA83BC5DCBBB904B8D59 +:1045F000F9A31D66B65F3F97197FD2E826111D9378 +:10460000061DDF83F8A36A37D6AB530CF61FA91A31 +:104610006CAC2FCE31F60F8C34D6E79418FBFBAF81 +:1046200037B45FEEF5BB846C98EFCDFD2EF97CBFFF +:104630003CDD5A827647D4DFD765D3DB27197CACC3 +:10464000ED551576787F770BDF27DC3F63D3EC974A +:10465000BCD5D8AEAD7B3BDF271BC0FF6101BCB42E +:1046600030BFCAA8AA7746503CEEF9C0E4DBA124CB +:10467000865B223FCE46C027EE3F9657FE24F7E3E7 +:1046800004B91FA719FC38F9E0CFF1737FCE54AC01 +:104690001FE07E9C9FF1BCF2FDDC8FF3539E57BE62 +:1046A0008FE795BFC4FD382FF0BCF21D3CAFFC2650 +:1046B000CEA71BA6F807835F6DE794F876F14D321D +:1046C0008BFF4CA7EA1641F9DE23A0FF7C1CD555D1 +:1046D000E87AB3AA7AD6CAB49E7E0F835B56A0A7A7 +:1046E0000CFCE99EC9AC3E83CB55901F204F8897A8 +:1046F000EB3B1974C752786FE1749E59DD13867CC9 +:10470000165B866714B8406DFCBBB4CD8BF9FC9C7E +:104710008E6DD55561682726BF5D1E00E3B379E530 +:104720001CE99904E14DDF89CEC380CEE2CE76113B +:10473000FA159606D7510B9B380A4322F0AB86B286 +:1047400040E388B428BEE82C0C7441E788722B53F0 +:10475000E3BF138C742147B6A37E5C5B353B09E94C +:104760004F61FD8727907303E718EDA664BFD1FF63 +:10477000555B3DBB5F7FB4EF75E3FBC51D46BBAB2F +:1047800036AFFFF70BF71ADF1FB933E6FD16B68E0B +:1047900044EFE74466A27DF07C6B7CBEF00FA68AF6 +:1047A000898007ADEE8EDC88FD63F53E09F4B95CC7 +:1047B00070BFCB7ED07F25C5E3C7BC2445E1A58F64 +:1047C0003FF7F37A39D6A97E385D1E8D7831E887B8 +:1047D00026CA902116D23082703BE3EB75FE0C5A4C +:1047E000BF93A01DE290AD37AB13807F2C34F855FA +:1047F00052E5AA330AECD7C74494253B83FDF3BBAB +:104800003E79114E3FC68F729B3C25A638F8D6CA1A +:10481000AD4DE2D47871B1259CAED737CDF6A05C12 +:1048200038123F8F44EB4FD7BF44D6E5930CB88383 +:10483000E7099C63F96C83392DA52EED9F0EAE36EA +:10484000BF63AFB6EF9C2C6F44A3FBD4E1FDD389CB +:10485000A67F464222E9847D2155D9F148C21D3EFA +:10486000CC770701AADF27B57F7BA011F8A6FA2332 +:1048700011F9C8803BAA443D1EB4790C56C265B0FC +:104880007F6B0F2D1121DF3EBFA54AC4731387082C +:10489000FF0E9570B4B42D0EF9999F8CE559DAAAE4 +:1048A00002EBE0F9F016062FB04F797F940F1BABA7 +:1048B00067FB018FBB33888FE7AF18FC75BB9DA2E8 +:1048C0000A7AE625CAAF5051F89ACE4BB3EB28F0DE +:1048D000F25B996BB676180939A1DD3F15E1A5E5C4 +:1048E000EBD9B65D5471DE031E0AE37993514C0F88 +:1048F0003093CE30C616A4802AD0F1D7073C3EC8EC +:104900004FCC6D29667E99BC20E651AC16037B80A6 +:10491000EE357898D3DA316FA536C179810D9C9F39 +:104920004B24BEFDD1C9F970AAEC9B0EF6E89E2778 +:1049300028FDC7F10BBCC3C7796EEBECA4114A7418 +:10494000FF6AEDC74169D3CD2B3722B33CC1966FC7 +:10495000A7EFDF6C263CBFCAF89E49F219ECAD21E7 +:104960006605FB6975C969E467573F4F09F9122964 +:104970009C6EC073AABB7FBAD6F6CDE5A1317A474B +:104980005E01D27354EF10899BC2B5358FD30BA74C +:10499000274D8EC805414FBED0974E5AAB4BF0BC49 +:1049A000C9A509940EE99FC5D3EE07BF816B4218D4 +:1049B000D237800ECE021D0CCA53D70A4827631087 +:1049C000DEED5CEE593DCCBF123B6F4DAF03BBCA71 +:1049D0009B0223C7D83724F81ED077EE0888190227 +:1049E000DDD0CF51BA960AFAB7EFAE365EADC58FBD +:1049F00033E91FD8371D806FE0E39FC5F8A93C5409 +:104A00004F1DA393EF9F3D80FB2316FEB1EFD57999 +:104A10002679E2F16D620A782CA313D34BAC3D4D9D +:104A2000FAE4AD3D88FCC332632ADAC9BD7675EB82 +:104A30004C5CB785DB8BE63C6E47F6B11BEFF1F5BE +:104A4000274FCC19DF2D3F74A425BEDD98E8FDDE8D +:104A5000BCD06FE977D8C8F3EC34FBA3D7EE881944 +:104A6000472C6C8F7B0EC3596884BB3DCFA877144D +:104A70009AD9FEB4788D7E63B367707CFF26CF4FE2 +:104A8000AB18A7E149B9FB3FE97E5B72D44C1AA190 +:104A9000CAED5CCDAFB404F2D4281D5740DE1AC570 +:104AA000D30252EE86C6F344C47C98F3E43DF77516 +:104AB000BA7D1FB0F073010DE6D3709E42CBC75A8A +:104AC0001864756D3E952DC6FA22323B1DFCAC8BE9 +:104AD000B69A09E45F2D21D2E92E6DFE940F945B06 +:104AE000981E5449AAEA81AFADE7FEC30A0F912090 +:104AF0007F6AC5ABCF8C81F33995166E8751F82B41 +:104B0000BA3C9BA5CE900CFED14F3AAEBBEB060251 +:104B1000EF87EA0797629E3BE651C5C27D7E8371AF +:104B20007E579A7FEC7CB5731789E621ED11E29EE2 +:104B30003FFCA14530C4E7AE742EE41908820D484D +:104B40007C2EE44AEFEFF88EEF3FFF1DDFDF6B6155 +:104B5000F49BE8FD15D69E5B30CE9F56558EFE5ACF +:104B60009ED7B19204FCE03A37BD3E4B1DA2E8FA55 +:104B700079AFB25F06ED67BA8A7E79FD8F7781EFF4 +:104B8000F35FED7D4E86FD7BFEC55333412F58F616 +:104B90009A8958214F6DAF8B9FFF0AC920EF9676F7 +:104BA00098985F410A8FB95D971F082758018ECBEF +:104BB0007EEAC278F2D2972DA119F4FDA5AF7C52FE +:104BC0004C281C2EACEB797B08E83F2F0A2CDF4ADF +:104BD000ED2ABE9D3E5F2A91FBCAE3F9D12D4C4FD1 +:104BE00039F773C71CA03361CFA17B71DCF6BBCD55 +:104BF000169D5C3864316BFDD8F9AA1784D03081DA +:104C0000CD4F9FEFADE5B99D7B4160F33B680ED979 +:104C1000607E7BDAE400EDB76ACF5F90AE6FFEE9AD +:104C20003E37C061D5419381FFACDA630A5B8AB13C +:104C30003C65417EEF770A63009E04E5F7CA8E1556 +:104C40009817BBB27DD35F4C6E78DFB8BF285C7C11 +:104C50006180EB71936F06D47FF6BC1BF2893FEF46 +:104C6000DCE506B8D271E7C994AE6EFC52B70F0905 +:104C70001B3F92D2773C427A64A0AF55ED1BD9F727 +:104C80003A6E3B03FC6D55CC3EFE1CFE31A8AFFCDA +:104C9000B818233F2E91DF8E017D83EC498D9B67F1 +:104CA000D02B3FF8BE5EB6EFD276381F7CEEE53FE4 +:104CB0006D07BD7EF9DFBFD8FE08F803DEB079804E +:104CC0001FAD7AF10337D1C1DF65657CE1C20BCF3F +:104CD000EF7E9AEE930B1F5950CFB9F08B33990AA0 +:104CE0005DFF85FD7F4D07BDFEC15F4C1908F07863 +:104CF000F0C0CD03FBB363806E43163D7E43885FF7 +:104D0000E5A0C092975FE7650C9EDEEA782B13E67C +:104D100079FE8405CF71ADA2CFAA4B006F2B503E18 +:104D2000407D0D85F7CABD1BFE622A8E0777758808 +:104D3000E885323C847801EFB7FFC3C45228CD3EEA +:104D400005C6233DC8DF63DF5B758CE2F7DAC4F884 +:104D5000BC44BE9601FEABF66E64DF6DA7F874F737 +:104D6000C5E779F8C7F8BEF82CB4C6E273F9B3E822 +:104D700063EC488D9B17A7E173C5813BFBD51B34C2 +:104D8000FE7025382F16D8BC2216FF042BECB397E3 +:104D90001DAA97E1393483B65DD8772993503AF943 +:104DA000CCDC732FF0C99E5F583C60772CFDC57139 +:104DB000DC77170EBC2B2BECFC8853A07AC505D2F0 +:104DC000FBD7097AC64A815556ED74852DEE28BE6B +:104DD0005686664D55DCF8FC143E0FB1FDB03274BA +:104DE000E80E210EFE1EB2E630FD333400E1B28241 +:104DF0005A449E42235E857180CF53B700FD25C281 +:104E0000A7B67E0FAC7FAC0EAF3BD93E8EEDBF9206 +:104E1000EE57E0C37DF01B128E4379A1CD22413EB7 +:104E2000E4057E9E2516EF51F8F3F390DF525FAC58 +:104E3000B226883370385C69BF5F697DDF167EF704 +:104E40005A151C37168EE7BE8E2F0F9A38FF584919 +:104E5000AAA60ED6C9338B99CAB36CD0F7CAD5218E +:104E60004274BEF5EDECBCDDB93DA610C88B587E92 +:104E7000B132817DFCB495F9BF571E3C540C7CEDDA +:104E8000DCE19F73BA6474BF72EF2959E5F221A483 +:104E9000970F09FC283BF9BC57BD1E7FBC557BFF13 +:104EA0001277BCCF25FFDD30FFCF3BCD44A5437C3F +:104EB000DE6E9A1A4FDF6AB69A8D79B5AE312792B7 +:104EC000E87B26B71DCF33D6AEF31F57412F79CFDE +:104ED0008CFE1522F93EB3E0F969BB02F1E55AF701 +:104EE000223CD7A28D57170327C95B8EFE0929AD37 +:104EF000BC94E9D421833D6DF688867953B99B0132 +:104F000072E9E4A8336658E71F62F4C73F48A47EFD +:104F1000201DEF0FAAE05BABC4B3178DE307D69853 +:104F200088A29787969E93301FF2A68D40BE9AE97D +:104F30000D9B0AFC64D5761BC6D5DF3A707937C065 +:104F4000EDC2B3161ECF6479B595DC5E3B73E0F21B +:104F5000F6FFA2ED67E065FAFDCAEDB43FE8ED7B30 +:104F60001D98E4FCE797938A09E5D3956F3E3213C9 +:104F7000F84B25C4C069FFCA9F0E0C41EE42F700F2 +:104F800056EFDE3734047859FEB35FAC0479B2ECE7 +:104F9000270E0224F9D681E3F742FDC29B2ECCEF07 +:104FA000BAF0E6991B611F507D5BD1CBF525FAF372 +:104FB000DB74DC655067EDC2379CD7811DB30C4AAA +:104FC0004AEFCB0E26E179075D3F7C6F95A5E7217F +:104FD000BCC885A88345B489C283611F2EDB63FCEE +:104FE000DE592BB32B56C93D8B58FFE060B65F3BB3 +:104FF000F1BDAF38DD6BEDB1EF6BFDBFE4FC333AD3 +:105000000E7B7FA58554C5A37FC1C6C65DB6E76F7D +:10501000F9C6F118BDF6FD0E7BFE4381E5E393FD75 +:10502000368C132C97C3C353E87E7D45268B61DFF6 +:105030002E77878727D3EFBDC6F9E5723BADD3E75F +:1050400083F93CA03FD489B5EB2780DF15AFDA08A0 +:10505000D0FB8A375DE8575EF1CAE5EE7FA1CFCF7E +:105060001D70A0DF6FC59B0F23BE5758C2F7829FEC +:10507000AE67BF85ECA0FDCFEDFF7526E823E7CC3A +:10508000E1CC947EFC432BDA2DFCF217E33AA85DC9 +:10509000505045E7A33EC6F270AA09BB47A09AE765 +:1050A00079908F6DEC9C328F4BADE67EA28B0B948A +:1050B000249CFF845BD973EE275A7D9B323059378D +:1050C0000FC89323D751BB44AECA073E6B8ADC4A54 +:1050D000145A9722B9586AFD4C701F4321E427B037 +:1050E000B8A039CD472A69F9700A09E0F948E7F410 +:1050F000DE7DF6EF14C5ABB7290361BC9136C65F00 +:105100002AEDFEB136E433C67B14D4036C5D97F907 +:10511000FD08B1F3BD6C562DC0CFA3F13A962758C8 +:105120002D29C7C1FF4E8E72BED467FD6C9F5DF402 +:10513000A4E03ED3D6B1A9C683FC04E265506EA8B4 +:1051400029204A3EE47BF8B06EE2F0B014AA04CE07 +:10515000F7C21E843F8BB3DC2FB2F83001FFABC91E +:105160001940FAB278ABD05760E5F7E9989C2AA9C4 +:10517000A4A5D9C9E004E7F6004E32AF4B2D331099 +:10518000AEF47D7C7E933D702FC0C59A31D2C0A70E +:10519000E4B41243BD0FDC34BAD8F7BF0D3F82F040 +:1051A00002BF8E8271CC7108B7F5357EACFF7F806F +:1051B0005F3D83DFF544D1ED1F396D92A19E107ED6 +:1051C000DB28FCD2A2FB2A160ED53C0F47DB4F8909 +:1051D000F6EF933504832F8FD7B460A93D4F492054 +:1051E000D7CFD8985CAF2681B566E0531EE68721FD +:1051F000692AC9D0F99F8857C5731FE8EB87F68CD9 +:105200005BD17FA9E1D7E491BA8DFC4F390EEB79E0 +:10521000F81DB308FCCA54FD1CF92455B78F6794D8 +:10522000DB1484B30FE303B55CBEAEEFC5A7717F9B +:105230006CAA51B0DCCCF7C916BE4F1E03BCC37DAF +:105240000E702F05FD5ED35482F2F3095A67F67E85 +:1052500098E8FDE1C9BEF6B099E21F79928225FA7D +:10526000ABC9094B685836C455891FE825F9C48F66 +:1052700042B856D28EE72592B57B5D5ECF499E8BB4 +:10528000F11F6266728A98581934831D150BDF5A14 +:10529000DF612BD8E189E65376728900DFBB3C974A +:1052A000C5CCD2EE693F01F73C389B1C6857A6FB82 +:1052B000AAB23291BF5A905E9DBE8050A9C3637A54 +:1052C00002FDEF21FBB40F801E3F843C445A3EDEBA +:1052D000926B03386F32B77B811F6EE2E7C5953959 +:1052E000140ABAFBC2DEE47CD25D6AE4031A5FF6FC +:1052F0004C2831D0B3C67753261BE95EE3BB2FD8C9 +:10530000985FA3D25E7E06E6931A69C57D19BB0F2E +:105310006ACDB22A5C8BF7CB30FFD32981C5D5FB90 +:10532000F2038CBB5FECCADE01E7A9B5FD13BB7EBF +:10533000A9611A7EA7571F34C7CF07182230B9DEDC +:1053400040E98D605E82828868A6744678DE02DB62 +:105350004FE3B0D4E8781D613C44ED10D93CB9BFAF +:10536000563B7BB3CE5AE2073CAE6F677B68A09D8D +:10537000C749D344905D44A2F6A4933E920E8DB7E4 +:10538000827E29997D47810FF6B8C47688E3AE778F +:10539000CEB6421C44482E45FAF9CA5591D55F5CF9 +:1053A00007EE5303FAF3387DE474219E8745BFB0BE +:1053B000C95342C02EDDE7ECB4633E935D34C49F15 +:1053C0002AED810CBB4E4F2D82AF73BCC3B0FB12D4 +:1053D0009CB72CE0EB21192AC9D3F189DEFB8F148D +:1053E0009514E8F8C5BA61B7E0FD4A7DF944027E3C +:1053F000B8EB7F861FD6668510AFE658FE93E6C7EA +:105400003B9D68A9C2D508263274FD0F92914E27A4 +:10541000023C887347AF1E74534EDF79C6F2BFA8B3 +:105420005C53D00F46E5DA53E3809F26946B55F723 +:10543000211D370D51808E0F353FF22CD43F69B6B8 +:1054400028C0BF1645361285CEB732321ECBC52DC9 +:105450003FC6B2A2A58D6E2242D66EAE6C9E0BFDEB +:10546000B799D0FFD31DBAEE4235AD773759507F8B +:10547000EF6E7D200BF4BFEE268702F7AB74B78E7C +:1054800036B63798709F75B79843261E0F36413C45 +:105490008270FE0E5E20DD7C49A9827AFCC5987878 +:1054A0004BC5168B5F7027867F454B7C7DB216FE01 +:1054B000C9CEA3E5037F2D3BF9A32CA00F8DCF3CD4 +:1054C0009C42F91EC0EFA485C48B0BDC649FB2C460 +:1054D0003E004AFFFD768CEF5FDD3D589F8854EF1C +:1054E000463C05DCB30C7E5FE657FD84EBE5C49AD1 +:1054F000A0DDCDDFF7C46F5FD1F4A7B71FA5B50D51 +:105500008546BFB609FCD502D8E3B3F8FD196C3E59 +:1055100071E89AE9D34D16E42B0BB83F4AA3F32860 +:105520009D05DCFC9C9E810E97441E43BE276C2A81 +:105530007A6A3C85DF1794FE803E844D1307027C17 +:10554000D736DEB0E51E3AFE97BF35E1F3C5111B35 +:10555000F63FFBA8EFA97BC05EF83733E6917C7974 +:10556000740AC691CF9A8D7E8C1B1C6CDF1FE4FBE6 +:105570007F516493413F5FD4305F063FE8A24833D8 +:105580003E5F044124CC8BBFFB976579105F229866 +:10559000CF72D07EC79475284F4BD08F56B9D91291 +:1055A00037AFFFA05D31F2ABAE261C9750FD2C2D1E +:1055B0009D8FA7E33B959154DC1FC4A312C8EF5EF7 +:1055C000C4F94FEFFC5ACD06FE73D616DF4F73D4E5 +:1055D000CEE4C2A2C80DB8EFFAAEEF467CBE48FBDF +:1055E0006E17DBA7D1F53C353EDE7AA2EB9880FD45 +:1055F000CF26C7FFFE9FF9F7BB6B16133FE55F157C +:1056000016DACF09DF7FA07E1CD8F9ADC929826EDA +:105610005D952DCB885FB7AECAD679B2FEBEC928DC +:105620001EEEFF659914C5C39F1B974F595708FA83 +:1056300042F97FC23EAAD834B1388076FE4684F360 +:1056400027665F26F0E3332D0FB8E3E50FFFD9AEF1 +:1056500018FC1C952D1C3F54EF2ED5E147C34BEC95 +:10566000FBDDBFAFFCEA51E053DB5C06BE125BF62C +:10567000C15B767CB8D91C1ADC0A4800E1A6BC7272 +:1056800002E87AB3C307749D187ED790407FF04B31 +:10569000A03F533D4B748C86EF12665FB6303AB82C +:1056A00012DCA2DFE57450167F3D63F97EEBAEA9F4 +:1056B000262ADDB0A7E52BD1C12344B5F6B38E5E13 +:1056C0003A78C24007631D9B910E3E03FD27BF2F12 +:1056D000FE4FCBAAFB7AD0771A4D18F73A6D57D305 +:1056E000BFCFEAA3803F9F7607675E5F1AAD2FD9D1 +:1056F00035CCADBFA7F14C0385431CF88D75C4ECC8 +:105700006F8D7EF2545238E6FF1DFD7C92E0DCCBBB +:105710004DF6B21B009F2418DF9FAC95BDE7AA93FE +:105720009CBD762FC8D1D3CE9CAF42B4B5C11EF874 +:105730009E83B6D7253F8472FEF46901E5F0DADF77 +:105740003F9C0F7CB88FFE5B1379FAD361E8B7FCFE +:10575000974FCDA84FE1B884EA3F200730671CED92 +:105760008021E8674914CF5D0197F98E8EC675B523 +:10577000F8EDFA9ACE1FC3F8C4AA128FFEFC00619E +:10578000FAD8FF8179E8FCF3B239E0F181BD2B90C2 +:1057900072A07BB3C4F2D7CDDEB451AA0ECECB1C1F +:1057A0004C9FB41D39D2904DDFB72DFC770FF8F91F +:1057B0002CF43B505A33A48B7A7FB996F745F27498 +:1057C000CF7320BF82D60D7E073ADF7EECE6D7048A +:1057D000EDBE4F15EF2B9EAB5D5800A0A374F39167 +:1057E00096BF22D5B1F664ADB98EB5733FEAAA0A69 +:1057F000E6277D6B5E12C24F5BD7DCD737E07D6951 +:10580000735F1F341FFC69739DF97F0478BE06899E +:105810003540F7C94C3EC7D2C566CE7F7ED026AA9A +:10582000663ADE1173CF6107EC8B1F0A68577FFF62 +:1058300083236620F9FF3876DA0CF723DC078945E5 +:10584000743DF3882233253A84EFCF27ED2E566F2F +:105850001F00F79946C7A326338C773F8B3F7FFF06 +:10586000836353408CD2F1D64379DF6F890CE3CF49 +:10587000EB50EAD9B1273EDEEB743C313A5E2FFCA7 +:10588000242BC2230A1F2BC2EBA3DE73242AEA17A0 +:105890003AF8A2BEA2C1B716E046E1373769CE7426 +:1058A000529C78BFCC750EFF23298ECE2716BE5F83 +:1058B00042D320385FE67F09F6CD3F3BFC7BA15CFD +:1058C0006EEDC99472F0BC573BECCB95A640563AAE +:1058D000A5ABF34303F903E0505067FC386FEC3E8F +:1058E0003D09FBE55A28E9BE8079F07329F7F27586 +:1058F000BEF5A3332ED897F5078E6742B9C2D4B54B +:10590000F96ED86FBF31A1FE79B123BFDFBCBA9366 +:10591000DCEF72D4A1DDA3C1D6791FD7E7EEEB701F +:1059200084D652D2B8AFDAD46B5F015DDF57CDF2C7 +:105930004F88D4597C87419FACE3E7D4FA8E03F6B5 +:1059400042EC38DA3A0F670EBE06ECCB6747CB68FD +:10595000471CFAEDC58F2A69DD3ED48A76C2E6641B +:105960004EBF65CC6E7D36D9EF2802FF57638A4F54 +:10597000A5EB6CFC256917299C0E8F782834A91497 +:10598000EE7916D177B625F25C7012BC57C8EE9945 +:10599000F170BD744BE7E916A0C733272C1877F8D0 +:1059A000C465C2F9369ACB33418FFF639B1CF7FE67 +:1059B000B28F5C12CEB74DE8C23CBDF92468057EBB +:1059C000D1D1397B20CCC7ED231E20FF33AD2691EA +:1059D000DD6FA6F95BC212F3F7AB12ABFB79E9B14D +:1059E000E9EF17DB387532E6792C687A17CFB1B951 +:1059F0004BE3DFEB6373B2F9BA3A53A6017C5D93D4 +:105A000045CCC376F97A04782FAB73928CEF078577 +:105A10007EDFCF5AE399067085F781CF675DE5FB9E +:105A20008293E5693DC6EDEC36B3AF7E321DA76DBE +:105A300073B200F8D0FA0D7632BE7266B2E64762F3 +:105A400079C299791E5B1E9D77A61F37377195061F +:105A5000F11CD30EE8C7FCAC0887B611AF84218EC9 +:105A6000DD08FE15C0B399D153E36601FDAA147E8B +:105A700083414EFCF109CBADB08EAC06C103B63B01 +:105A80002DE3CE7BB6CBCAE8BCE929B40BC14D0BE4 +:105A9000E366B6BE8FF3722558EF1A4E1F7FBC0225 +:105AA0007D9C77303F54667527BFDF2E8CF7D80575 +:105AB000014E50F797F2FBEAFC8A3E3F26BA7FD6AA +:105AC000723A247E88B3558C9343E047101BDAF07A +:105AD0009ED4F9410BF91E5D5F93C0EE1D55478BB7 +:105AE000FCFE24FF498053F36303310F6F83E8CF3B +:105AF0000439ACFEB38C71BAC3FE8BDBE03EF8ED2B +:105B0000E364DC1787FDEC5CE1B36B72DA204EE9ED +:105B1000AA9ED4329F8E17F260462CA92D25EFE461 +:105B2000439C728DE81168FF60B996B7EDC17CF2B5 +:105B300051A62FA615401C6F90883EA53302BBA727 +:105B400061FD9A491EC0EB7A4F9AA0B75F66713A21 +:105B50003891523ECB49E1E37DF4710F9C85DB1215 +:105B600049BD06FC886A83ACEC62F142BCDF21953A +:105B7000E325B5530C2F7263DDB9989ACA5B2630C2 +:105B80007FE98FA707989F1362A363D0CFC9FFBC9B +:105B900088D7345E6B1C69C7CAD6758BB03F8C93AF +:105BA0004EC7492D15C363207F2DD9BF1DFD7653E8 +:105BB000AC08272275B5009C425306633EF8E3E328 +:105BC00087BF0BF9E3A9477B66831C0D0DB5FF4723 +:105BD0001BF0A9F5B202FB3C754DF73DF03CD9F73F +:105BE000E40350A6D67DF808F0E9E4AEBFD4E0F3B4 +:105BF000A9B2C1BF98FAF1D9BF417B6AB96CF05321 +:105C00007E9552FEA093C2677B613058A1B0E7FE3B +:105C1000F4E83AF6ADED9C0AF7D89F9925B2F33235 +:105C200084F1C3AD5B3DDA39E552900B1ADC36885E +:105C30004A7B18D635D38AF491473A915F0D826832 +:105C4000766E142FA91F6FBC1FF23562E7D3E014E4 +:105C50007ACF51C3BD80786E3107CE1F4EB6035D3B +:105C6000EF2FE9F4823EBF39C1FD9D475DEC7D8B8E +:105C7000C8FCACB1ED47783BB0C496122CFD455042 +:105C80003A899A046586D50FF9CFFB45E53F91CE59 +:105C90001F3729801FE86FA6F83BF4CEE7E85F3C8A +:105CA000147C1FCBE75C05DA78E174FA7E73E9694E +:105CB0008CD3347B188D5436307E51E9EDB242DC02 +:105CC000A4B2907876707A53353883BF8CCBAB8A88 +:105CD0003B185CD30A09C67DC11704F74BA5433FA7 +:105CE0000ABFB486B5F7231E49A79A4BFB35C3B844 +:105CF000809F3A91B071BBACB87F83268C7BD2FD7C +:105D0000FE3BF06B55340DC4B83F1C0F86F152F8C2 +:105D10007753F8786D741CF01F9E6930E1B9004824 +:105D2000BF81BAB286D232D2674F59011D5729F5C9 +:105D3000781A353AD0F818DD1A0BA8BC00B82D50E7 +:105D4000D5FB81FE4E5B3DEFC03C1C5B2D0AAC7F5A +:105D5000C1D6571F06FDC5E1ED6A00FE50398ECD54 +:105D600037A5893E473D47F91DF4AF6CB228EC7B5F +:105D70001C7EA59CCE381C16F2792F6C65F3B60FED +:105D80000D05813E2BD750B8425B80D13DB844BF52 +:105D900011715F1D85F5BBD4741C77C09C987D1173 +:105DA000437FDABA2AF8BA2AD6B07511BE9FE8B492 +:105DB000C2306E45295BE702C2DE17E1391D7F2143 +:105DC0005F4F85FA0A960B1B2C86F1B717ECEC8413 +:105DD000F96417CA8A807066F71B66F27565D6B1DA +:105DE000EF6516BE82F022D5BAF9A25F5557A7FB20 +:105DF000EACCAFE9C682C3FF70D0808E7BFA47EC55 +:105E00009E81BCADC6759DD998FF1C9CF7FEE40928 +:105E100019E3DEFB45DFC92CB4476585F11FDFFBC5 +:105E200033804F2FACF3011FDF57C6E07FE63612F9 +:105E3000027A1876B43C05E03DEC68809755184F1F +:105E4000A700117AF91E9D1F35991A04E09791DC7D +:105E50009716031F18C7CEF70CD5CF9BCE2FB521B1 +:105E60007D12E443A58D4B9924E315DE31ED479F68 +:105E70009E0DF78FA61D79FA01F8CE20A25B0FD0F8 +:105E8000833B979D6739425BA15F75F7A3808F269F +:105E90007E9FFC3098590A9647A04CA5FB7B530A7D +:105EA000CC5322934BA2FC60D7136346015FC1948D +:105EB000A7122CC3A4A42FDFD0F51FC1FBAB429CBB +:105EC0007E16B762B0CF773D71CB08B0E39B414FF0 +:105ED0004C827B383D5F409E8EEA1311EECDE6B0DA +:105EE000B5300DEEA51609E82F5B0A3E1461DF35CB +:105EF00077101FD0476AF9DF2D7A3C96B9D8EFEDBD +:105F00004832D904FBFFF088EEA980A7D02111AF59 +:105F10001898F42BE7D30ED0873E6279306DBFAE70 +:105F200042F9FD50A61CF73E5D72053D31B67FCAB1 +:105F3000B0D9E8CFCBDAFA18DEE7593955F27D8FC0 +:105F4000F64EDB5A56067A8C524EA96B209D77EBA3 +:105F5000A8B5F83B103358BC4C99CA9E2B9359B93D +:105F6000A9E6E88FC16E0FEE916C7974BE2337B24B +:105F70007BC436155EB406A85E5A5AF6B2F536FAF8 +:105F8000FCD3522A05E9F34F275CB4417CE7D9D210 +:105F900049A900CF8E06A35E47E0722B6A0F155900 +:105FA000827E179D57D30704E169B2845B2A68DDBE +:105FB000F4AA13349C3E76CEC6A6B63940A70B0A87 +:105FC0006474DBC7AEB793CB8BF9D53D53E1DEFCF0 +:105FD0006C9530FF7EF02964CA0B39CBC8563B91D3 +:105FE000E9B8B632FB2428F9DF06BE1C2C0CC8F039 +:105FF0008AC6CF9A8655EC067E76DCC5EF0BA95A89 +:106000008CE7CA70FF9B401FEA298B6737153BED71 +:106010004C9F6DBDFD38F8A91754337D3FABF50B90 +:1060200001F141F5BE4174FCAC52BC5A902C58139E +:10603000B416017EF244A228309F7602764290CABE +:106040001F3D1CB471FFBBEF2F7359701DC5A03BE2 +:106050008F8EAEC7C9D793E9A3EB8923A70BE1BB0A +:1060600090EFF3CC1787C603FCD73013292B784A5F +:10607000B0EAE691A55EDD3C8AF83AEA5CECBC85C4 +:10608000ABB44BC0FB6B62F83BA8F3B06FB73B2ED1 +:106090008C62F6BD919FF6A973BA8A7D9E19C3AF33 +:1060A0008A2CEDD311BFFBD8BDD584D07D6BC5EB59 +:1060B0001B1576CF6748BB5FBA0AFA8D74393D402D +:1060C000074D233E2C01F86CE6FAC2C24282F6EA82 +:1060D000C28C4ED417E6D7717D41F2D5039375B4C7 +:1060E0002613ED7E18D01F50550213BA8EEB0B9A73 +:1060F000FCE772BBD2DBD98072B58E9DF7EBD5334E +:10610000542657B3BC4CAE5736D0EF289C98C7E8FE +:10611000F51226C795AD5C7FE07238957F37AD816B +:10612000C9AB54D023DC9006A1A25CC618567A54A1 +:106130006F1950C8E4656AD37E946B2F3A199F4C4F +:10614000DBCAE4E5D0778FA900262F7DDC42F9F485 +:1061500013BCDDEBA1FA594A543FDB20F2781361FE +:10616000FA21E6FCD3796EE6FDB5E73BF9FCF61FB4 +:1061700049B915F8EBAE600E9E2BD7F62D7A3F6924 +:106180003D93DF879059CDE2E42EDFA2DDFAF3677D +:10619000152E76CF50858BDD07EFAA0E7B615CBC98 +:1061A0005701F9B88CFEC58D545F42FF13B7AF4A53 +:1061B0009DFC3E194E3F89E489C6875CC4EF2EA43E +:1061C000F0FD34B41BF9B54AED2558DBA7C1DAC19F +:1061D0004B61BF076795C2FC9BC77F85F91F5909B3 +:1061E000ECC58F343BF35BF275D7D463CC0EED1462 +:1061F000E39EEF497733FF43BB441C004F5B90DDC8 +:106200001B671B27C7ED6F7333BBEB53BE1F9BC7C9 +:10621000EFC6F39909E5B34454531C79AAC9DB26A8 +:10622000C0F3F574DDAE5FD5E3EF0849A17213F258 +:10623000578276679074A11DA916C8E8376C32079B +:10624000AD808F2DA51CAF1E6B1B9CCBFCD678A1FF +:10625000F0003C6FF48B21211BF01CF21431BF0EB7 +:10626000DEDB7986DAEFFA7845AE5BE47052F087D0 +:10627000F6B21A187D358F97711E8DA3D2DB4CD9DB +:106280007AFE2B70FEC9E8AB71FCDB485F573BBF61 +:1062900045D52F3DF3A92E9ED8BDEDF91C8073F492 +:1062A000FE0B7FBFE7291655FF65EBCE387182DE06 +:1062B00076B0A39C600786BE6F886BBAD9BC6F743A +:1062C0001BFD77C05FCD685C8406837F69DFC49067 +:1062D0001BDE236B58DC76098FDB7EBEF3763CAF8A +:1062E0005E44C9CA1C07EF676B8CE7D5CFEE7A7E98 +:1062F00030F36B840CF1B325BB7F3ED2101FF61335 +:10630000256D0CBBB718E5F4DB3ED5628ADE3F2075 +:10631000C3EF0DE446EFD1B293762C9DB07F69E9CF +:10632000263D587A401CE5829DE4C3328D946399E2 +:106330004EAAB0F492209683493B961960E7E68214 +:106340005CE8C152211E91E8F87E0EF1613D8F9408 +:10635000632901DE52A37109698F15F337207E018D +:10636000FB3ED1B9B391EE8A656E8477D5B5E598D9 +:106370004FCEE21533DCFEE56E942F61E4DFF33996 +:106380002B3FFA9391ED70FE68F56676EE45E3EFEC +:1063900068DFD0EFBC94C2E481FAB8807C6C9D6366 +:1063A000E68D08CF26F3397DBC8158AD79F0FB1E10 +:1063B000DAB8F3B99F613E9783E0EE66E7077D7830 +:1063C0003E693EF81B74EDA4B79DDD4BA38D233AC7 +:1063D000260CEF2FDEA77B1FF3A32B62ED802BC9CA +:1063E000EF98FA82D8F7BFA6134A8FFAE35EBA5144 +:1063F000C9447AE5F29B129482EF35584EA13D16BE +:106400009CE2D7C3E539CEE734B9B22026DF23B604 +:106410005C20F1FD11330E9580C970EF1ADE29A1C1 +:10642000DBDFDA7DA4DAEF642DF107E441EC352FF0 +:10643000E0D1C3E71D24AD9306D1F233A8EBFCFBFA +:10644000BF4B0AEC77EBF68BC7CFEE59203C2EB151 +:106450009CEFC729A6A632E0736702C40776C41270 +:1064600052E5BE01FCF9C7D8FDC443E8BCE512B053 +:10647000E3882AA6605D85DF6B395FC3CE0975F3BB +:10648000FB6876F37B85FFC4EF112E6A797826D0FE +:10649000C1E7FC1E9A828E8DE5E0F7296A77CC036E +:1064A000B95FD43EB112DA8BF658D8EFF0703EA146 +:1064B000CD0B8EB9DBE97732E8F7AC29C04F08CABB +:1064C000DDF34DF610FC7ECFF97613BB47B550C413 +:1064D00073F770EDA089CF2F2905BEF75FF7823ED5 +:1064E000F239E727DDEE64862F4915D434484B2175 +:1064F0003ED06B1E73ACC473908B9CA1DD4FA74143 +:106500007EB8D5B78E7EFFD0FE5733E1F9538E9516 +:1065100058FE69DBF14CE05BE70F1C97E3D1ED0A15 +:10652000292C837F6A59872042FCA4AC7D9E0CF104 +:1065300091457B0FA15F79852780EDCB5BF6637D6D +:10654000F2DE77317E323449417C9F1F14403F6F29 +:106550005E8B250C3F59B22F27B8346EDC3E89F193 +:10656000DDC71C6FE0F84F39DE781BE1B2CD82E762 +:106570003F0E6DFB158E7BEEC0AB7CBE04F305CFEA +:10658000DBDA4FFE13C8AFFDFC3CA6B5D3ADF70771 +:10659000FF9DF375AD7E5EFB1D9D8C2BF4D37E8F2E +:1065A000C7D9E9667CA9D30D71B345ED0C0E7F32D6 +:1065B0008765D02397B50B0AFC3E5ED9DE363C0FCB +:1065C000B8ACC38AE72596013C006E145E08979626 +:1065D0004338FF0C80CB6858C7FB988F9FD741E1A9 +:1065E000521C5DF7326700F7ABB65E0A07B6EE7D68 +:1065F00057C253C088A7967765F0CB2CEF10107E5A +:10660000CBF7B2792CEA60F39ABC771EE2FFDC018B +:10661000A280BFA57BFFF1CF613DE70F58F1FE5E81 +:106620006D5E944E89BB04F60FA353D2C1F8AAA69F +:1066300077AF08A5E3EF0CF4B6EF65BF330A20B3DC +:10664000517A2DEA988571C162205EA0534FFB48B4 +:10665000F67B81C14C80EBBE89E14C98F739ED7730 +:106660004CA56026E065A43B509CA4DBE7674FBDCA +:106670008A72B140ACFAC3A3B08F5F66BFBBF1F0C2 +:10668000C78F897A784C841F4A1E0D70FB9D1BE1D1 +:10669000D67B7F4B90E54B9100EEC7457C3F9E6FCC +:1066A000A376275DFFD9969F61FBF941C6FCAA3FFF +:1066B000B5BC950270ABE0E73148E876E447142EAC +:1066C0000DD63872BEF75C5B889D57BC2010BC2F7E +:1066D000537D46835B953CDB10E763FC30A335FBC1 +:1066E00008DA19A1F8E71C63F5A4D8FB5113E503F8 +:1066F0009CE6FCEC537E4F97267767B8033F481A19 +:1067000090F8BC77C5A6159900EF0A381B89F711D8 +:10671000BDF13DC823C57343EC5ED430C0A75BBB5D +:10672000F79474B0F664565F9DF46F1BE03C58B765 +:10673000768FAA7A98B567B3F666DEBEC75DBE34BB +:1067400009E53C11D8EFF99893E1771934B991181C +:106750000EC6DF6568830B3706E0780FE278121DFE +:10676000AFE8BB8FA7F1E9EF3C8EF57F761C4D7E3D +:10677000C1FE84D447E2F38DFC9F80DF7FF77D125A +:106780005C68D85797B7E5D6431CED9297DF03D3E3 +:10679000B496803C5FB8F531C3EF7AC4DEE354CBE6 +:1067A000F372E45CBADF74FBFA7012B3730E27095C +:1067B000BDF794437C6B3821FC9E29AAE2A5F37BAC +:1067C00025A9FE91CFEF2D2F2041D44F4792762C53 +:1067D0000B492796C5A4074B0C33E782ABD487E55A +:1067E0009FCBBAC6C0E2975B03CFDA44CC3B7813A9 +:1067F000F6C9F9A181E7E1DED9758E95D7C3FC8F83 +:106800002479F83CC286DF5721FADFBF50401F9C35 +:10681000E1ED4F1F241EE95C6FDE4B0EDE5BFB9B40 +:1068200024C443A2DF41BB3FE6DE1B762E5C83C35C +:106830000AB84987F6FF65EB6ABCC76FE95E17EADD +:10684000C9C35BEBF0F7AF9692CE7438273C9CDF60 +:1068500023425AD8FD2DDAFD20235A2C86FB4B56B5 +:10686000C4FCFECE32FE7B59CB627F8F8A9FC3DD94 +:10687000040FE2E463C49EE33D9B14FF7715496176 +:10688000FCDF3F893DC7BBB75DC4FCA8D59077A5A9 +:10689000B32F46ECACB218E94BF94D9E5957177C13 +:1068A000CC1FE1B2FB77097DBF5394CCF4807D828D +:1068B00010371FEF760FB7B7491D994EC7F9BFD4F0 +:1068C000AD220900800000001F8B080000000000BE +:1068D000000BDD7D0B7894C5D5F0BCBBEF5EB349F2 +:1068E0007693CD6673DF4080201737185244AC6F23 +:1068F00042C4886817A48ADAE2060402E406A58A7C +:106900002D2D1B122120D6F83522D0842E7829581F +:10691000F5DBB4A848835D3022DEFA87D6B654ADE5 +:10692000DF827C8A88B06A4BEDC5FA9F7366267B4E +:1069300021116CFDBFEF79FEF4B12FF3CEBC3367AC +:10694000CE9CDB9C7366B6B55EB56F608CB506AD4C +:106950009ADE094FBB2EA8143396975A655E0265DE +:10696000E6D0D94778189BA69F72C853CE98B141FC +:10697000BDC404E5BE1D4BFA0D506E75ABCCA440F2 +:106980007B878E3128B31C5D700494DBEC3F73CCA5 +:106990001FCBD8481BBC877E0AEC2CE8817EF76FA2 +:1069A000BF5D87E5D666C6B2711CC5DFEFA1EF54A7 +:1069B000F630C33F6D46998BB122FC278CA3B28D74 +:1069C0001FEAD318AB6E386E89D8E07DA476061B1B +:1069D000CFD86576F87822D4BF79F57B58DEB6F249 +:1069E00098C30FE3BDB87DEDAFA7417F8620C005FA +:1069F0005D947EDAFAFA34182FBADDC87640F9339E +:106A0000FCBB82B1C255EAB1889906649FC17FF987 +:106A10002B12CB4606E552512E4638E2EAA13C0E37 +:106A2000C7CFC2D21C167661BD80D7A9310670329D +:106A3000BBCDF9CE18C62EB52BECB361B1F2C5585B +:106A40000694EC3474545901CE9D7F54BC2D507D76 +:106A500060FBC2229CDFD967FC457698C74A73DA8F +:106A600078961E8377E099EE11E3062C3A373EC301 +:106A700016E68EB51FFD50B3C90FFDB4AD66DEE35B +:106A800023183307FBAC63701D0F19BC50647729C2 +:106A90006C4E08EA551BD34230CE388742FD253F65 +:106AA000EF5AED79B9C4101BF7AE4FAF9F83EB1BC4 +:106AB0004DB56A3B9473E192DFA9764F00D7D7902A +:106AC000CFBC29309EC1D99F6B87EFC63C6DF4DAED +:106AD0000065D3FE736C7A04C61DF3DC4DCC93CAFB +:106AE000F185F0AA2B8DDEE3998C99563ABDEA2503 +:106AF000D8CE46F4F891CD183421FE57DEDD81F56D +:106B0000ADDB2BDC9EB1B171D7AEB67B5580B36BDC +:106B1000B5D9ABC204D78AF925C357E0D0F982F0C2 +:106B20009D51C7FC585F0FEB80F4536F4FA1E752A4 +:106B30003B87BF5B0DCC42F8BB817E5A905E57709D +:106B4000FA5D9E630E229D2F7F7178361B3BC8BA7B +:106B500088E723ABDDDE1280A36BC53C37834F2B68 +:106B600097F559AE82F92F4F35DB911EF569231F3A +:106B70009882F4FE9281215FB5A65678E6C7F5A704 +:106B80004F9BE4467CE875815C6667ACC57E4B8DA7 +:106B90009A83F412D8CABC8CADEFA8AA512F857283 +:106BA0006A205781FAFB3AA6F1FAACC05605EAB75B +:106BB000744CE7F505815C1D94B7775CC7CB230265 +:106BC0005BB1BCAB63162F8F03187219EBE9B8A148 +:106BD0002600E3B71ABC73BC30EE1300FF58803FA9 +:106BE000249E3F177891F53FC3F780EFDDE2995C73 +:106BF000FF94F86ECF10F57B457DEF10FD3F2BBE67 +:106C00000B0FF1FD01F15DDF10DF1F14DF1D1AA274 +:106C1000FE2551FFCA10FDFF4A7CD73FC4F7BF16BF +:106C2000DFBD36C4F7BF13DF1D19A2FE7551FF6625 +:106C300052FF6F89F611F13E3FB5FDF500D05D3E84 +:106C4000C82DFC2B4D6DCF40BAEB6A2E27FA6F9DF5 +:106C500008743E3646EFF90AF361B9D4A1527FA514 +:106C6000288FE1F9AAE8BF7259C9BD4877CB5FD533 +:106C70007B910E5B15EF113FF41F58A6F3A2DC5D6C +:106C8000FEA29ED3F93235C8E2F8FBD524F8B70945 +:106C9000F8DA04BCCFDB87517DD14AB77786949769 +:106CA000C8F7F6C4B219F84983F1DB9C5CBF942E97 +:106CB000AB328F42FD01FA05E5E65D3663D804E3A9 +:106CC000DF6557A9BECD5965C7FA805D25FD73976D +:106CD000B3CA3C1FE5AA0D845D058C67E77DB7D973 +:106CE000D59A20CA0F4735D54FFBCF197694A36D9F +:106CF0002CEAA8C4F9AD02BD02DFEF6FAEA2F745E2 +:106D00008E3F39503EBF9CC1F9BF2FF5A0A518DAC0 +:106D1000A9DFD691BE186957498F0D5BA50B7AA0E4 +:106D2000499F7DB90ECB0FB6717D057FA965307E79 +:106D3000091F9EEDBCBDE2A552D467F7A85E8F8700 +:106D4000BF53E3F44109EA2BD05F398E0C2E1F8527 +:106D5000BEEA2E671AF61B709B830F43BF252A736A +:106D60006766C4F09EE3D07339AF9FE145BD36BC82 +:106D700023513F15B7C7E92786FA32513F25EBABC0 +:106D80008266908F71DF9BDCF684B2DE914AFA094D +:106D9000648CF733187A79CFF2ABAC2C26AF93F52D +:106DA00051ABD00F52EEB67E7A49827E907239593D +:106DB0003F9C5FBEFEE6EA51448720AD3CE797B3B7 +:106DC000AF221DC03A1AFC0AE90FA6FADDBED4F3C1 +:106DD000E3CB60F0D9EDB6F3E3CD90F51AD9150603 +:106DE000BF4AFD9FA357CE8357D9CE687EB0FB38EC +:106DF000E8B53FBD7947290396590BB8A1F5CFD225 +:106E0000051F8679E7AFFC6937F69F77D0DA867879 +:106E100036BAE777B7E17C3A1E600CE8496FE6F4D2 +:106E200064CCA9B2E3F7AA4E73670C87F2AEDFDD3C +:106E3000AC003DE9339BBD0CD6EDD0132F655C83D0 +:106E4000F87BD5407C6ED2F9EC6C388143F4B6AE59 +:106E5000C0BA7D03D1B1DF8C78CADF69263DC0029C +:106E6000DBD76B40D4ADB01C6C32D67F7DBD06F84D +:106E7000D9A90C94AFC6722868E4ED4144E3FFF54C +:106E8000E81451CF341558F3714511F5FF59533DAE +:106E900005DAABF6312AE89DFAFB7ED66EB81CEB1C +:106EA00075F27B8D4D82F9E278A2ACC2FAFCB44F48 +:106EB000D407C2EDD5C0443D46393E0B60FB1E9D54 +:106EC0008E9703CFB463FF8F5789EF030FAED7F2CE +:106ED000099E6BF40EC6BEE3E86BB75D1A83F7EE4E +:106EE0008C97DA5B607E1F782269B09CAC61FB7185 +:106EF00017EAE775739A7D8837247C1FE8C414BDB0 +:106F000087E86960DD76CF0CE441ED99837F4B1B08 +:106F10000B554DFAC8C114C05FC39E66B301BE379E +:106F2000197C81BCE2D8770DBB6BC99E69EA2DA3A1 +:106F3000E720DF1D5287FD4BDF998D1730DE07E11B +:106F40005F373E06550DFAE6769B9EDA33BEFE832A +:106F5000CF4F7EFFC163BFBE01C73BED89B8A643DB +:106F6000EB7561C0CB20DFC9F68D7B66D2F3D729E4 +:106F7000DA7A07F0752DC82E92576AB317DB87CCE3 +:106F80001D762F20DA62E8F0A1DE00D40775936247 +:106F9000CF8D8E126A9FFC3E99BF4266963903E5FB +:106FA00078BD4A7A2A640EA48C87F246D887B4004A +:106FB000486BCA7E37612C969FB431DC97B4D6F704 +:106FC000B9C7225F798D0CEDDD8D97867290CFDB8E +:106FD0001A8C731E027842E1E5EE0571F6D6DD19D2 +:106FE000069AD7FAE781EF2E86A721E450F0FB112D +:106FF000A03780942D0EBF19F739969C0C1628C621 +:1070000076B68DC89FEB0DFE9A2A6C97A323FD627E +:107010001931BBA60AE07067E9143DC1517D6421B6 +:10702000EA37BB1135283B9231EF6788A79FAADE6C +:1070300066E4C39FDA6CF60054808CD450FEA9231A +:107040009C412C9BF4AC19F5785E19E8F3383BF6BB +:1070500088909F471C468277A32534B312FAB12E3D +:10706000D7D90330DEFA864DFDD3609C1F353C75C1 +:10707000B805DE6F70A90CE1B039D5B011F48FE11D +:107080005A8011E07EBCC56747F91ACD52D90EA8C7 +:10709000B7961899274E5ED9C642394E4E663A5574 +:1070A000CD02DF9FCDF0BFE880712F79F535337EBB +:1070B000EF9EA8D321DB8454BECE69E589FDD8A715 +:1070C00024F693519D58EF9C9158EF9A9D58EFFEEE +:1070D000466239F7B6C4F22C496F20736CA08FADAD +:1070E000BC8A59231FAE467D0BF8F903E2DF3A5202 +:1070F000E745FC581A1E3AB110EAF3509EE07E684C +:107100003C23BD7BA0F03B1EB40B4C19CD1EC7D851 +:1071100073F1915760BE06D7CB56A2DA19B4B7BD4A +:10712000F9DEA7D8BF8DC5B52B46FC6827113FF8FF +:10713000E7067852F11F1EC477F37F7D0FF5E261F9 +:10714000BD17F19DD7A0D2F8F7CCF604F5DC9E7000 +:10715000A33D9326DAA79937F6EB419EA7BDB97EEA +:1071600019EE7B93F1EA62CD0AF225D007DF6FD7E3 +:1071700032D21FEB74AC0EE906F708D81F994720EE +:107180002FAECD34129E1461EFA0E6C07A97B09F67 +:107190008C39B759908FEF3AC8E9FF2E23EF67A0DB +:1071A0003F0F0D8A24CF504EA666E812FAD9641715 +:1071B0006D4439CBC1CB3D7D19D7205F6E9A9D318F +:1071C00001E9C484FB2EE82F3DDFAC8D86F9595EC2 +:1071D000340614E8345D657D0658CB1E2BBBD507FD +:1071E000706C39640DE8E1BD65C17FD8D14E1B9F3D +:1071F000C1E9BE678DF7372807A2B52AE1D192D53C +:10720000619F3096CF2100F02139A05EAC1CD1499E +:10721000769EA5B283F4BBA5ACA303F1B465868EBC +:10722000EC8D8CDB7444CF9682D0E112F4132CD019 +:10723000D9B1BF0C50FC46E8E487F91D3E1FF60BA0 +:1072400038D7557052C17E6986304EA6C0ABD3B9CF +:10725000FB0E05FAC9C4FEC6F3F6882787C053455E +:107260008687E0768A7E334BA0FD78DE4F5B45ACA7 +:107270001FB98E5B6A5810E193E3CA7E06FA679ADB +:107280008272D5F032E00DD64929341370772D6122 +:10729000B43FEE59E36BDE4E7C6D233F47AE33BF08 +:1072A0000AE928F7D0D659BAF1F89D95C6312C6075 +:1072B00041A4E35C9599BF9A81F68D8FF098CCAF8D +:1072C000397D1DD7A39D2AD725997F7354D6AECF7C +:1072D00038978F739CCEAA91E307E1E7247EC939E2 +:1072E00014FD36127D325F6F4B395D867861F1EDAA +:1072F000F5E72FEBF5A1C3E8E761D9A02700F585F5 +:1073000049E331F64F139615A6F37C361CE5BE43D0 +:10731000D031E82B60D69E09F6A936E4D3658CE817 +:10732000ABEAE98D37BF0CFD9D1D61B4A35E293822 +:10733000D4D18FFA91EDF18FC275E852FD3F4E81A5 +:10734000FAAE23D90CE5F67A0BDF8FA982CE93F53E +:10735000CBDD197C3FE6413DE7FED79FD23E0C9541 +:10736000B8C6D881F7EEFE8F2B5F3467FD0FDA5970 +:10737000ECD1F51A94F3FBFA5B6C38FE7DCFB79B2A +:1073800001BF965779FB0D500EA888BF7AF2671D92 +:1073900028584878525F3731A4D3717A2D8865F622 +:1073A0008685A1FCDDF9E437EA3C287F5CD33D28E3 +:1073B00087BA04BF6F15CFE4F9AB46CD8FF644F220 +:1073C000FBCE01B9E43B510BEB38EE4123DB0095DA +:1073D000A5BA79EDB8BF8BAE07F90BB5F3F49EC62D +:1073E000BBE3F6B7EDD6CA4733E0BBEED566E6079A +:1073F0008339FF1385F981390B9CBFAE44F953C81B +:10740000C20AEAD9C266307891AE5658993F8EDEEC +:10741000F33F51A97DBB557B34238BBF37831C3091 +:10742000F07FB29F66F858AD93CB28B45F0C8F59AC +:107430008FA2DC60CE6A6D603F320CE917F43E8C9F +:10744000F7B498B70170689800FFD97461D3F873E6 +:10745000DBF70A79AE9A6D619497AAED9523245FC4 +:10746000ECEAA9F876B8EF262156CFC82F8B78A181 +:10747000F2B7EC54CE03F96B9A40767F00F7DF81C8 +:1074800034BE1F619AE671BA905F182139DFCCDAF9 +:10749000CDD08EA81DF82D87F55BC86EEE631EE477 +:1074A00007F4B0BD9342228B215EBB18AB89E70382 +:1074B000F9947E0975A59EF653639EB3103C8666CB +:1074C00016B4A03D84B001BED5152CA816C7FC8209 +:1074D000A50E0F7D6764CD64CF3EFEE95BB928A79A +:1074E000AD07C11EBB18D7594772CA6A4DE43FC6E3 +:1074F0005A084F27057D74AFB6D33A0FECDFFCAFC7 +:1075000089758EB4A0BE285C9191B0BEB25DFE2795 +:1075100079CC7F497CBF41EA2FBFA44F41BF4CFECD +:10752000278554DFBDDA739EFE870DD17F0ED1D142 +:10753000D0FDE7537D77F835C775808AAE689FC365 +:10754000E789D9D7C978CE5F9128972FDE935896CF +:1075500078B11834E74CC0B9E5DB3AEF76E8EF2BA9 +:107560004712DBD514FF96F6BFB1F661E7F5D81EDA +:10757000F6E7DBE1ED652712DBFB2A9F77201FC7CB +:10758000DA73F8AEF824B15DF2FA24C30B70657DAE +:107590003D0EAEA9665342FD9CDA73E0CABA310EC5 +:1075A000AEABDC89EDFD2D83C3754DA9E973E19286 +:1075B000EDBE36E9C2DA25CFE3FA1AD31078E7ED4B +:1075C0006F9C7361FDDE52F7F9ED6E5D993C4E8064 +:1075D000F8A551A75D9E09CF79F80AED459B95EC7A +:1075E000DE647A7954E8A76A343CA0BF8BD2B4EA4F +:1075F0004C785649BE137E86434F5C948D723D4F46 +:10760000F8D199F02BF4D4BBC9AF70B3680FFAA4CA +:107610000DE545CF4EF82E8DC3156F3F65D6F37D32 +:10762000859D45899FA5BD94C1EC0ADF8F737B675B +:10763000A87192FB5F97C1E19EBF722A7B1BF8F095 +:1076400029A3BD52C5FDD93685EC81F9D59A3E15E1 +:10765000E86372BB427EA5F977FEE687E88FB9F44E +:10766000B8674F04DECF0F3ABC386C633FD3304E5F +:1076700090AD5F56F63D78DE7F00EC1F515E86F4DC +:1076800066D33CB8DFA84588A09F5386E6323BCA44 +:10769000CD6FDA34949BB5B3B53FD07CFF0156096A +:1076A000B45BC0A7CE9EEE9C69C47847ED373C938F +:1076B000D0EEA90D59347A9A996A8579D4823D869B +:1076C000CF6C23532DF8B432333E2BD670FB2B6D89 +:1076D00092CF580BE3D7F6FEE4CFF8DD2235BC9FFE +:1076E000DB93419A776DEF8B7F457B6D81E633A20B +:1076F000BC18B3D3C86D52410FE34289659407F1BA +:10770000E5B27062F9924389E5F771E1607D260B7D +:107710003FD6817D2692DB4BDFB792FDB917141E51 +:10772000EE93038F9B487F4C5D6AA3F57AFFA475A7 +:107730003BFAF5F6BF6EA5F64B7E6AE1ED75A12723 +:10774000B01C782285F6D94B3343151900F72F3E2C +:10775000D513BE715A06ECFF89D1DB3760FD25A138 +:107760000A8C8B3D751163FD58AF06C7E33C9FFA49 +:1077700027F75B477799823BA0DFF79FF9C913DFB3 +:10778000C57177E56528B03E97A15E8076931F347A +:107790005B71BF31F9FDC786A3DC58BAD39430BF03 +:1077A0009D998A88AB79D290EE86F23B1E5BFF13DF +:1077B000FABEF4C411A2BBBD86800EE37881F59CAD +:1077C000CEF65AB89F74AFA53088EBF47426D73B39 +:1077D00097E976FCA811EDCB57B91D3254FFA5EE01 +:1077E000F9DDD583F81907EA61DC6258E733EF5910 +:1077F0006FD5008E519B13D7697430B1FC4B31AFFC +:10780000792CEE7D31C2336CAD1BE1D9CE089ED20E +:10781000136FDE5C8CF6B889DB21C9E31ECAE4F283 +:10782000E1D147A11F2E67F4DC0E078C015F2F15F5 +:10783000FCF00B85DBC1F0B7220FE87F291A10C3DB +:1078400062EF9726C121FBFFAEC0D3C7E6B41DA8E7 +:10785000CF9D464EF727571FFA21C63165BB775695 +:107860006B5A759C5F79E1E665077360FDEB7BB24F +:10787000689F29DFD7EF7ACE750BBC3FB553F5A2D1 +:10788000E95B7FD3233F988CED76E9430827D6A3A5 +:107890003FF354E8F9346CB7B0CB3101FD25F2FB6E +:1078A000459BAFD4AAE3E4E917E527C9FFF5627F5A +:1078B000FCF4A4FE697980EFA59B152F365B1AFABC +:1078C000FAF5D7A2ADD3A5F7627CA342653EFD04CD +:1078D000DABACFC6677DCF930773A1BE69DFC40A4A +:1078E0009CD7069DEF9A71C82FDB0CE4074B5E1FF7 +:1078F000E6E4EB0CDF8775F0FD861B6C75181781CD +:107900007EFBB07CA074871EFDF8692740BEF1F7AE +:10791000477420334FF4DE351EF62C40C7B676E4AC +:107920008FBDE8B8C0711ED7939E60613E8FC9C2FB +:10793000FFBCF48F9D46159E274EAC49ABE4FC4737 +:10794000EB8442DD09F3AB7B701CF1EBA2CD89FC2B +:1079500025DB4978170713EB93E9C2E394FE0A5637 +:107960001A4F5FC9ED3267048CC88FF52B419EC753 +:10797000F14DFDF10E23DA5DC9E3A005C9E4BAEAD1 +:10798000892E612C9CAF85CF174C5E33CCF724FE3B +:107990008BFBCD15DCD72F51688A6CE945ACDA0337 +:1079A000F85C3A8BD5E053CAC3539342E3B1FD5E12 +:1079B00043E4911F911C4C257970CA1E4E43BF525F +:1079C000AEF0EB9DF284D350CE9D11713BACC7F26B +:1079D000925ED007C0D7EF7F6024BDD0127A2E0D03 +:1079E000D7EBD413169D0ED6E5FD9ECC2AF4079D49 +:1079F0000ABD9C86F33A19CAAC42BFDE50722259C6 +:107A0000BE497BE028FEF352C6AE746A9A13E51DA8 +:107A100006197240DF643697350FC2F7F23BA7B103 +:107A2000B90CF334A2DFB47951CE5EEBF4D0FB5A3B +:107A300085F7877F18DFFBE850E60E5CFF43FB47C6 +:107A4000A6A39DF011F3A4A3DC9EEBF2F99CB09EDB +:107A5000EEAA7E8AEBBBA7336F2B7CF3B6DE7BBB33 +:107A60001DF0761B03BD85CF72BF91FC2D6D5904AF +:107A7000D77C958555A0D3F9A857C75399EC98F9A9 +:107A80005D4AB015E0B86D63E23C17769A62EB0B85 +:107A9000FF2D6620109181BAE2DA41FF8B517F02FF +:107AA000FE9698593805FA5DF250E2774B5998E006 +:107AB000A97FEC33D36078FCB3C0E35C97B618F1D0 +:107AC000A8CC32135CDF7A5C21FDE6147EC6E8FDAB +:107AD000E9418C872D15FA7A81693FC1D37467AD6E +:107AE000761BD0CD9995F3B5DB3279CA08EDCB364C +:107AF0002B44874BAB59B800E05BDAAB84C7A13DA0 +:107B0000F11A5F27D92FDBC6DBDD2CEC9D05801732 +:107B1000B41F263FA60452417E2E30C3560EE58880 +:107B2000981FD6A743B98E75D0BC1A5884E0588BDD +:107B3000EBC8FD7904FF9F5FE3EB37B96EBB1E8195 +:107B40003AB4BF82E27F1F332FAD23D825CC927188 +:107B50002E9D20DEB5383CD5752596D94371E5615B +:107B6000885728C7E1BB71F767266D103CDF3FA03F +:107B70004F82A3678E63E7D8BD6F8975B8FFEB0BA3 +:107B800073500EDC8BF66BAEE86012CA4D26FD1A00 +:107B90006133F46FBD8425F839C0BEA2F283CE995B +:107BA000D337E733B6C9E0A778C17CBDEF2086B6EE +:107BB000FEE9F2FF04D777BE4E2B54491E682369B5 +:107BC000BFBB92AFC703139A47370FB2CF95F06F81 +:107BD0005242611DCA8367B87D905A1E35F8E3F89A +:107BE0006CBF9073E9072207F3905E9E54C82FBFC5 +:107BF00045616D0AE0D90DCB82FA608B72F420EA00 +:107C00008F2D577B582BD497EF9EB9EC79DA2B5BED +:107C100029AFA76177A5BEC146F3E7F66A4AF376B6 +:107C20001DD467DF5A3A01F904E67DEB2C787F50CA +:107C3000F06D8E8DD3837B4DA07839FA650FF89661 +:107C40003D8FFC3DCE4AFEAF6C33FA7AE9D98E7691 +:107C5000A89BB528D8EEFE34DE7F964E7FEB4C2CE9 +:107C60004FE0E58C558AB68388F83EEA3FDBC46A6C +:107C7000107E7C8FF63474A7F5507D90E69B3DB561 +:107C8000B90CFBCB1ECE9F4E63381FFB796560BDE0 +:107C9000FD3A94BB2B84FE5CB1BD2A1BE5E42BA707 +:107CA000CC2ACAC357DCD20E0CDBD00E6425A5BC8F +:107CB000BDD0532BCAA66623FD3A0B13DB9D31685A +:107CC000E997A0BC3FACA7B8CD9F6C5ABA03DA5D68 +:107CD00066E4F3485EC7A8D0AB4D9F282C18B7FFC9 +:107CE0006F9A7396ECECA64FD484F7A7569B593045 +:107CF0006EFF5F5F77601AB66B60FD6B91AE1A42E4 +:107D0000292C1847E79759071F57D277D3277A1698 +:107D100018745C63E2FB4F32592073B076AEC4F73F +:107D2000308F84F29EBF0CCC03DFB3499134F487CB +:107D3000CE40BD06E533415DC000F2E41503D757E0 +:107D4000A7ED91047D76DA13E1FA0CFD3D366E6FF6 +:107D5000CFC47556A369B35263E3C87AFC3E236E61 +:107D6000BEA7E7185998D6274A7020FE02A318DB51 +:107D7000DAFBA111F35CEA7BF713FE24DDC4E331E7 +:107D8000101F3F6AED0FEB80F7C7DCDFB961EC68CD +:107D900058B20382CF039B36605CD8A5D725F07D0F +:107DA0004AF9801C20B1733F46B3C81FFAC086EA67 +:107DB000FCB8B2683FF07D60F374AC2F1FCBBF9F5F +:107DC00078FF9697D65032480797A36AB4D0971A8F +:107DD000573627956D501E1757B627D53B93EADDCA +:107DE00049E57CDEFE546AB850EF05E0EFEF9E8E69 +:107DF000F95CA772C27331FF6BA33E38BD1ACA0D7E +:107E0000E55CCF36F62A5EF2E109FC357AB9FD670A +:107E1000F3468C98779652DE7F10E544FD1EC5AE82 +:107E2000003FD8423D612AE3779EB8EF420A7D5772 +:107E30001F3A4ADF0DD97FA98EF87D43E931DE2E46 +:107E4000F42EE9F3756DCB28CE2EE3C87AE6D7F28F +:107E500094581C59CACBD339DA73242FF72976E406 +:107E6000CF013AC57EE3FC37B2FD1BE37A7F8BE698 +:107E700042CA8A0F5BD02EFD63C3BB13D14E7B4336 +:107E8000E8854D4A70348EBB95F947A3DEFB66C387 +:107E900088FD3A68F79621D28DB1B2D5F73F49F8FF +:107EA0007B2B355280F9742D59E1E9984FF75656DE +:107EB000A41BF1F9FBACFDBCBE205280F97377DD49 +:107EC000FF3EAF1F11E9C6F2E359BFE7F5E3220514 +:107ED0007A3B6E758E4CAF86FA87ED83F3F5ED59DC +:107EE0005C9E48F8869768CBB2D00EABE7FAA41B2D +:107EF000F63666909B73979C7CFC61C0C3DCEFA454 +:107F0000903C7BF8D4F5D3B99D1DF0A915E887E521 +:107F10007FA4EF486EABB4FFCD411D97115B8FD4AA +:107F2000C27E0FE9838B9A7BD06EC89E3B96F4C1CC +:107F3000579DDA111C573EBF9F074F687F24CBCE59 +:107F4000E5B35E4771E9ECEFA6929D75AF85CF076B +:107F5000F886D6D726D6E3EE2CAEBFEECEE2FBB740 +:107F600045CE2BA9BF9B855DDCB93EB8CB02F87F1F +:107F70005DE6BBDCC7EDEC5BB6835C0139DEE9D0C6 +:107F800072509EDC22F2D7A4FCC0F71971FB8BCE95 +:107F90003228DB62FBC8CE995A8ED5894F970EE303 +:107FA0002F521E7516F3EFA45ECA6EE5E366DF3B43 +:107FB0007A07CE2345E57EA4057346EE6821FD3E93 +:107FC0008BE6CD342D4781FE8E2F1EA643FF925C9B +:107FD0009FEA12ED61ACBF59F8E7E53AC9F53C22DA +:107FE000E63D5F0FF601CCF3772E3FCD1FEC85F118 +:107FF000C28F45F6C2115CE3AC187E991A9988EFDE +:10800000FF3FC2D34B5F069E1A5682BCD05D80BC38 +:1080100010F8DBA4840DD95C5ED0BE18DFA3DE7936 +:10802000CCE97F0BFB97E3CFFD6E03D98712AE94AB +:108030003B9EAEB9919DCB67C9F6DB09B15ED2CE4E +:10804000F44A7FA418E7ADD7CD147F78CB1822B9B6 +:10805000F916EC6B5A50BE88F879C57796BE82FB4C +:108060003AD9EF752E9ED76791EBAEF87A16166364 +:108070003E090B98711E338DB4EE52EF763A787E3E +:1080800048E79D79941F72864518F9352731928FFC +:108090004007541FBDC945FC0FED03166CBFF82205 +:1080A0006A0F741120F9709395F6219D186FC6FA26 +:1080B0009B4A8398CF82FB5FA2B7C53A1A77107AA2 +:1080C000E17EE3513C5F42D28DAB95FB6798AA8D70 +:1080D0009F19A7E72F72713F514A79E4C9DFA37D49 +:1080E000BAD142F629EA588AED7464533FB0FE993A +:1080F0002EBEBF273ABBED07A9222FCD5B81785D4D +:1081000097CAE9B2CBC2E34E5D600F935C14F42BC7 +:10811000F3E2FCC2DE8BD4E9D2D05E28760DF80DF6 +:1081200034DCC793DF1BEAE74594A3B8FF9A17D066 +:10813000874DB89F6ABF528BC4ED47F00FE376B707 +:108140000AB9CA3633F203DE8ADFA561FFD6348C62 +:1081500053DE8ADFA3DF75D59509F1B84B5C9CBF70 +:10816000257CC972FF120957C7035AFC38B2FFE4D5 +:10817000FE605F59EECA223C87D3717D5BF4B47E0A +:10818000C970463673FF75647311D19DEC6F283842 +:10819000FF4B1FFDB6027A70E154BEDF96FB9805D7 +:1081A000623FCC5625EED3D05F3250D69F5B4EDE79 +:1081B000F7619C3DB13DB75B52C6468DC4B71E25E5 +:1081C000017E89AFA1F070F317C49BD47B0F588058 +:1081D0000F32703BAD10FD6EBE3385F498D3181C82 +:1081E0008D74B5C0E5A1765B31DF85F42ADFFF7EB3 +:1081F000FC8AF45F24EE7B9BACD16D88AF262B23E9 +:108200007E3ABD2F95F8879544E662BED899BD2683 +:1082100086F4DBA84446A2DC3AAD68B5D4AE25C5E9 +:10822000837C24FD036F3FC5FD034D884980AF2942 +:10823000F077CA576ADA93B81F3E0DFFD501DD9F6C +:10824000D6452AB03F290FC08ED6C83EAAE3719CFE +:10825000461D0BE03EEB32DDBCC59CCF73D90E7AD8 +:108260007F74E4F2383B1DDAF529199C7C906FEAA3 +:10827000051E1B75C7A85D3DE61D213E71BF85FE2D +:108280002EAC8CF3CF366E7C9FF29E1A7727AE779A +:108290007D8C1E94CF14FC2E8E3E889F03421E3090 +:1082A000EEB7A8E671E854514EA9E9A73CA826E12B +:1082B000C7C83A1099867225B53CC4E6C1B3E90433 +:1082C000B73726F76E7F0EF7C78E9AFE02648326B5 +:1082D000E1EF93EB2DE1BCB4F73EF25B483B256E3A +:1082E000DF397A5682FF600D7D87FB581C2F82AFE5 +:1082F00072900CB87EDB24F41BE84192B70B3A462F +:10830000911E443D85F249EE83515EA19CF8A7ABD6 +:10831000AA07F9755376D563AE2C3E1ED9F5B8A9D8 +:10832000BA74683F9DC48F6C87FBE1CFF3C3F5221D +:10833000DD66C5FCE3045139E64D6749BF1BC5E75F +:10834000962B9E6CA4DB77F47EF2AF2D6201F2F7E0 +:108350002C46BF163CEB05BF2F147EA285C23F847E +:108360007EDBF83822FA4FE3CB4B583F971B3B4D4F +:10837000B1FC1AF4E754B3702AF4D780FE267C8649 +:1083800012BF6B6451FAAE69CF67A6843865279F28 +:10839000F7AD62FD1DD5413DCA892D16EE6792F2FB +:1083A00063F22AEE8F4A9FA015DF8574FEA281FC3E +:1083B00014FF2DD66D40CFBBAA9E42BD62D5F3F30C +:1083C00068D1BB4C24378F833EEE11FE9159B80F14 +:1083D0005DCD34CC5F67AABD307E9F2A9F1BF65AC5 +:1083E000EA907EDE75E912E8EB472E9ECF437E23AE +:1083F00092CB29A477417C8C47FAAA1826F5221B38 +:108400008FFEAAA362DFDC7883CD8FFD45745CDE2E +:10841000FCC9C5F7017F72F17C4E591ED8E709FAF5 +:1084200091F13FF4DFC4FBCFFF3ED0FE3E9177CB0E +:1084300068BE9B168BFCEE013AD6915C4A19EB2381 +:10844000F97B99AE8AE452F43D9B07F152F37EFD2D +:10845000629CC74773AC748EEF36E1CF4DC976503E +:10846000BFD27F7BBEB858CD86D1242F65FB34DCCC +:10847000A0649DEB07DE2BE4D85EC6E10D9CB0F254 +:108480007C13950550AEED0D8D0E22BCB5C2FF805C +:10849000F60DCAD7E8937C1D99CAEDA1BDBDE38254 +:1084A00048EF470DFE2D0BD09FD36320FF1A538357 +:1084B000BB1EC17E9ECDF162FECF695D74DBAFA0B5 +:1084C000DDDE138FE661BC67AFF0BBD71BC323C9EA +:1084D0006E16F98EF569E191E807FA8558AF7A2BA7 +:1084E00094E17DAAC53F2A3B2B1617C3EFF0FDB1DF +:1084F00020B7CB8F314E07818D3CEE09F8CD5980E6 +:10850000F0AECFA6B81AAE0BAEC3DBFBC6D1BC36FD +:108510001944FB67146AAFCC2A9D4B7A61832913F7 +:10852000F17FC667A47CDDA67BB9DD385FE7D9B6ED +:108530001265E5B32934BF059D8729DED1F4834553 +:10854000740EB269C9AAEBD8E7C40150AFC4FBAF3F +:108550004FB36821ED87EB8685C200C7E9DED15EA7 +:108560001EC6E3E76A1A455EE87103D310EEE83EE3 +:108570004370B0F37E43F58FF3C5FD29EA37F273FC +:10858000C7C75B481F24C65FCE573E6D888CBC139F +:10859000C65F9BE9BF293BCE5E6C7A3687E4DDDBA4 +:1085A000F7FCA590EC8A0E1E2F386ED0E6229F387D +:1085B000AAC3C6797176D8B26C6E97CE3709FB1113 +:1085C000E4603CDFCBFA8AAA443E93CFE66C6E8728 +:1085D000A48AFC8073EB65FED9F526D49FDCB584B4 +:1085E000FD72795D24E26E934F44F7639E557DA83A +:1085F0008CE27A45ABC2C49780EF30DAFFC7B7A4EC +:10860000727902D3C47E164E6264BF2ED4F37C8787 +:108610008526B087B91EA7F6EF6CC9263C54ACE19D +:108620007660F44985E4A28C3FD632FEFDD36D47D7 +:10863000037A685FBB532903D1CA6ADB2A291F6208 +:10864000495731ADFF64217FE79BB4915B90DE9E7B +:10865000E6F12B188FECEE7ACCF99A4072C988FAC1 +:10866000B06EA7C2F0DCB09C7F72BC8F0513E32D07 +:1086700093435C7EA3DE6071F69AD443A82F589290 +:108680001D9948178104BDD78D789D1893FF84B13B +:10869000CFD183604F6F43FAA9A8E2FC17ED5108D0 +:1086A000CF0DAC99C787841E1A8047E8B177F45C78 +:1086B0006F2E34DD47CF9FE321B02CD48311AE075A +:1086C00041AFA15C1C8A2E7E3E045D487AD82DE81D +:1086D000A3FE040B5F0EE3D5AF62E186F1FC993A8D +:1086E0009EF432D7CF66AE9FF169BD003D9DAC9F31 +:1086F00093F571B21ECE36727D2BE920DE4F8FF6D8 +:10870000C8E455413DF7C3E6DB31CF4FAECB22A7DE +:10871000D6979715B3B79A8E98CD9E8BB1EC63C35D +:108720006CE85FAAF415A0FF5CE5E78D53004FDB12 +:1087300071FD847D7E79015F47B7C8E731A83E5659 +:1087400066C375EAA7FD74348B517EB6C46F772A71 +:108750007C3701BFE3FC38F0BD99B559E3BEAFDA11 +:108760006B21FD72F699543A57C6547F9103FA7300 +:10877000BD01763A944FEF4D25FD7E5AC87BA7F494 +:108780005BB0B5B41EEFE23A4F44AAABCA43FF2F29 +:1087900053A6E7313A6FCDEDC606C7507E7B515FD9 +:1087A000DC7F03A73313E9D9B38EC8ED58067828C8 +:1087B0005FF8BF04FD36ED9E5AF65D8CF3FB6C5EF0 +:1087C0008E557F19DA0D26FD8A1BCC7A3C77BF2A9D +:1087D0007A27CCA3A1C04679C8D5456FFEEE2628DE +:1087E000BFB7DB40E715173F7C7D7A183F5335F75D +:1087F00060FA7971D090700E6EE9CEC4724328B1E0 +:10880000DC9474EE7DE59BDB5FEA8BAB37BB539D5D +:10881000B4FE1EE6C53C6AA6FF46BA7F1079299FC2 +:108820007F591D7CA96F04E5A1A5BB797E8D11ED53 +:108830009A79480F837C77309BDB352653F309CC3C +:108840006737FDC244E7E3DFC8F6BBDDE85FD64526 +:108850000FE27A9A8A4E8D473D5855F40F8A8B9DC8 +:10886000FD1EF3227ECE5A2AC9BE39BBC5E2C1FD28 +:108870005967A18DE8A0F35925A870FB7DC6C40AED +:108880008C83D21C58D3E6ABDFE3872F98999FA740 +:1088900087DD8B1BE58C46FBA977665AED6BE0BB49 +:1088A000BACD5CDFD6B3FE349403DF748BF5D33FCF +:1088B0006634C33F8BDBB4D12D00EF529F95CEDDE4 +:1088C000A89FAA74DE7C1D761967FF97BBB93C6828 +:1088D00030478C9538FE3F56D4A06B4CFAB94C0605 +:1088E000BF86E7BB0C7BCAC279F06AD1CAE7689F32 +:1088F00033104FDEC7E5D6A23BF7D37B65560DCDCF +:10890000F71D982FE2E5B92D269AEF3B0536DA6779 +:10891000BED3CDF7BF8BECC6A099EC8D4F32F15C86 +:10892000EC3BDD063A8F7E2E3EAEA2F3A9EF76BD7C +:10893000407EB877191F37B05B4FF6CABBF6684563 +:1089400018F1E8694E437BB76EF3623ADFBAA85B71 +:10895000EF4379B6A8FBDBBFBA14FD47B36E2EC751 +:10896000295DE158E1F2D862F5D24E5533263D82B9 +:108970007C78C5A753FBAF407BA91BF8A498E7CF31 +:10898000A39DDED77D15D9A58B665A1D382F4FD7ED +:10899000C3D3507FBC3B3397CEE32E7A5C6178051E +:1089A000C322C74A17BE5FA4A8BEC1E8E9E36C3D75 +:1089B000E1B5B2C8E60DE377BFD5139D005FDD805A +:1089C000FAB3A1DB40766FDFACD77F779333C6571E +:1089D000CAACCDD74DC6F63F3150FB017BA7EB5A51 +:1089E000492F2C5C81FB2A8EB7643E3315AD1A8962 +:1089F0007025F3DBA235CD2379FCEA8BF11DEBE288 +:108A0000E773EF70F3FB23BE00DF7DFF8BF01DCB20 +:108A1000CF48D84F9D2BDF02D44EFAFFCD5EA63D46 +:108A20006CA378AFA680FCFD0906AC27E2939F3BC0 +:108A300052FFBA7CE7AB809F316E7F07F26F11D394 +:108A4000CA506F7AA2F62A3C536413F61CEB32C963 +:108A50007D00D9F79BB2D8231BE2FC0F0FBAF93E79 +:108A600009E4C016ECE7F41FFE7110D7A9B1F0D4E9 +:108A700078F4FB367DF2278A17DA7A79BCD9E68D4D +:108A8000523CDDE0F4111D4AF9DEE4E5FA27795E97 +:108A900027DD061EE77546A99F17723C54EE14F1B8 +:108AA00095AD2BADE44FDDEA0C5AB87F21C0503FA5 +:108AB000CD98A4E77132616F5D2BFC91E6F2E71867 +:108AC000C6C7D8149EDFF56AF9736A26947F35E924 +:108AD0004A2F9DCB2B7FB07D18CE7B8A41D40FA728 +:108AE0007B33FE8F5649F5CBDD7A0FF2F78C729E01 +:108AF000DFC8EAD2C86FF26AF9DBCEDBE2E0F73119 +:108B0000B3C70674330B98353E9FEEBA29168F2DE6 +:108B10008E7E3EEA506AB8DDEB499F3D8EFB4548AC +:108B20001F9727E263B9DB48E36ECAAEEC43BAB9DC +:108B3000E2AB7C3D4E3E6E0AA21C3C29CEB924E33A +:108B4000EF376EE1A7534727C4ED9DC65021EAC910 +:108B5000F795C4EF96B4EB296EBEB85D614118EF8E +:108B6000E4AEA70B519EBFF7F0D385F3E2E049FED8 +:108B70004E3EFFE816F42AFC82C97EDEA1FCBBB2A1 +:108B8000DD99CDCC6F1E1E6B7FA6EE6FE4DF9DD707 +:108B90002BFCC39A56E2C4FD90689FDC9F3997D3A3 +:108BA00087B24721BF87F46F1E3BF420465206D69A +:108BB000CFD25BAC8BCF4B94CFC962DDAEC7758390 +:108BC000A958DA7979A8F51A8A1F77083D24D7EDD4 +:108BD00058FBF074C4A3B1D1A6327EDEAC14EDF51F +:108BE0006E66F5223FFD45E4A73AADF0043BCD9813 +:108BF000EBB6A13C93E7FBEFB0A6EDC0E75F44FE08 +:108C0000AAD30A4FE8A720B794FAFB8BCE47FBBA4A +:108C10003BF41D740E3145F049360B2B0A8636960F +:108C20003EA550FE567B22BE5DAD5C8F446B8DA48D +:108C3000BF24DE2F9B773BED5F0759AFCD4847B987 +:108C400093F8BBEA9C62E1EF88501CC13289D9716C +:108C50007FDF7A6980E090EBD5C49B33A55721FB79 +:108C600019F3585232285E1A104F66CB6003F18315 +:108C700014B1DF6549F1826CB0BBB19D8413CA9415 +:108C80000F73AF23D43192C75BC92EC57EF1FDBCF3 +:108C9000B12AF9DBB19D71C2F9E96F804E457EE1E1 +:108CA0000CF9BECE3A687C62069EF3C17500FD8861 +:108CB0007621F31A12CEF974813D8DFB3419FFD55C +:108CC000EB42656EDA9FF447D07F62AC307B50DFB9 +:108CD000A6E843A5B87EC9F1606857CCF310F21D31 +:108CE000A867E4399EC695537D18A702FB2360C68A +:108CF000F59BC9D7AFF1CE4A7AAFCC2A6D41FA6A5B +:108D00005AC5E8BE81A9BD3D94EFD454C3EDB1A6C8 +:108D10003D478D0CE8779EF0E730E17F7689753D21 +:108D200026ECEF58BC2BB20DF3B73B17E7D3B9DDF8 +:108D3000E4BC922F1AEF3C930A08B9382E8E956E38 +:108D4000E67A46ACBFE46F19D74A1DEB2B464BFCC5 +:108D5000C507DE7BD99AF545F2469EBDE773F3461B +:108D6000D8F4EBB0DE8C56BEA84730408F0E9CCBBB +:108D7000B37828EE35508FF72998F72822EFE4ECE6 +:108D8000B5579650DEA8E8AF6F23E67FDF6B610929 +:108D9000E3C5C3A726F56F80FE6D1ED9FEF83557D3 +:108DA000AA14FF15F04FDD88E7FAEE3524F64724C4 +:108DB00028CF119A63E3F9BA7E70CFC6FC983E07BC +:108DC000FDBE3167624CAFAF7B7D46C7C51EE4AFC9 +:108DD0008F290F57EAE72627CF234996630FE470C0 +:108DE000790E76F13454B9EBE62CA3FB0706E2BF0B +:108DF000BDB51ADAC332FEDBB4CA47F9B8600FFC5E +:108E00002887EC8153EFEC6768779EA47D41D327D8 +:108E10002AF713815D81F7C9987B2BC91F8A69A640 +:108E200023E2D67F89D05368C3233F3475DDF8B081 +:108E30001EEA3FCED11EA27E0D83DF27B52F87DB32 +:108E4000F14DA5555B501EB08714BACF6943E94771 +:108E50006477343E73E5C4F87CF2C57BEEE7F9C86D +:108E60003B0D83CE7F5F0E8F0B373EF324F93B4FD4 +:108E700006F931983A35B81EEDD0BA3A1D5A5EACB3 +:108E80003C587B13D90373601E30AF0773387E9A4A +:108E9000765E1FC0FCF626F84F81575B7D0B695F3D +:108EA000B0758ED986719CA6D279CB88FEED560D11 +:108EB000E79F0C672CCE6CA573C81BF6186AD08E82 +:108EC000AA00BBE9E7006F41C6F41A2FC8A53C7D94 +:108ED0004FD9B76C18771F5C2FDF92C7ED8036C56E +:108EE00017F85A39F939597C1E4FD11E6E9FBD961D +:108EF000C3ED43F9FEB51C6E374E09F44F459A7B1E +:108F0000568DA4A09DDCC4B40F71FFCB7C360FF945 +:108F100077198FB33B577BC8BF6B7646EEBE98EC94 +:108F20002895E2CC727F71FA19EE17BB22D77F1415 +:108F3000D7B1421FF9E1D7106F77ABC24FCCE54CE8 +:108F4000E1F5B609E8C7B238233FACF150FE0DF9A0 +:108F500025D22F6FA37578D6C9EC889FA9815A5561 +:108F600089D333526E4C1D3887E324FF6915176B84 +:108F70006C04ACD63B6622D1B6CF326376C2A17FF9 +:108F8000CC56F1A5B41F74663FED73AAE7C0BE11BD +:108F9000E9726DF4A00EFDF5CE7EB21F1B420A8D64 +:108FA000D350FA33CA8F5B2AF2B006F2A1D408E597 +:108FB00087FD3D2745E8C7364E0FAC9FF6C5EC311F +:108FC0008E7FD09B943716B3E35BF8BD67A23FA3B7 +:108FD000883334083F0E208AEA8DB9C2AE137E8DE5 +:108FE000589E1B1F97A99E8A78BFC3A699A04908BF +:108FF0002E4F1AC2DB6EF5A5E7025CC7EA7484A2A5 +:1090000063ED2974BFD426A55F437F64A08CE7C5B8 +:1090100026D351891837FD40741AEA93E83343E5A3 +:10902000C5F23CD82D132FA27CF2F23D1F4E43FA1D +:1090300060358CF8B171CF85E5C58E16EBF1A5E7EB +:10904000C57A156D073C2FC97524E6C57A39DE65EA +:109050007C32391FF6744E58E5796B916D0FE3FE43 +:109060007B8F89F23D66EC79E108FA276798598889 +:10907000E2B54976C061E7F55310DF673E7867DBFC +:109080005D0CF3A29FF2F27392897A7D28BB9E62F7 +:109090001671FBBFEBE4FA7F4976BD94BB4D629F2E +:1090A000F4BE12FDC1489CDF3EBD7DB0732DB7E418 +:1090B000CA38D710F91CBD83E773C8735F3591E2D6 +:1090C00084F8D382017AFE62F1AC3AD48113CF8D59 +:1090D00067A9223F4B55B808600E9EBF23E3596A2B +:1090E000CF688A539962F1AC301B249EA58AF8D0D0 +:1090F0003A83564BFE967D260FDF0FFB480EB5F5E3 +:109100006479514E352D39F9041ECD571DD3DCA895 +:10911000FFDB04FEEB2F3C9ED5923BF1DC78D6764C +:10912000617FBD5DAA0B1B01AFDB1997A3815E199F +:10913000D7D2D1FE347A4F01C1ADCC3213DC6F3FB0 +:109140006BDA817EA6F9325EF52CF793CD1771A903 +:10915000B7678D243FD250789EDF9EE8F7FF21E26B +:10916000398BFC78E46FBFFD3F66929F7D21FAE961 +:1091700087C7CE2F30E1AFF3B4F3F3ED9E9D0ADD48 +:109180002F8A64A223DBD24EF78C2E0571B81545C9 +:109190006800A8E62BF05AD12968D778DAA00CC667 +:1091A000BBBA5E0DB8A1DDF62329E41F5CE7F488A5 +:1091B000FC331E3F0E6C54822378BF74AF58A04D11 +:1091C000A7613F3FCFE57EA59773B95FC293741F38 +:1091D000419B41C481C5782D0CD61D9E3A853FD751 +:1091E000897BEB92F121FB6B33349BD14F172DE040 +:1091F000F7939C356A73C87F9C3192EE216A4B6D60 +:109200006EAFE1F5C4B3672D511FD55FAE72C39247 +:10921000793210DE5DB922EF2E09CF0B3A12CBC99D +:10922000F19BE47353F3997F54CEF073CF15ED4265 +:10923000B909FD9FDD502CD6C54BF1903683E7D799 +:10924000C51407E5F70CB5E473BCE90AF87398A3F5 +:109250009AEE8B037EE1F618E3F00FBBDCA920BF8A +:10926000B43938DDFEBB7027C3FB9BDC91445F6DD6 +:109270000ECEAF6DEB9520C71787FB42FD1D1F4A31 +:10928000B9F425C9C5B715EF23E162FA8EE443E0CE +:109290001E03F1DD5E0B3F0F29E51525E8E03E5288 +:1092A000EC5BFF2EF4D6FC136BE9BEA0AD75C3D208 +:1092B00030EE39F57A1BCDA3F1597EDEB66155A4A7 +:1092C00010E9BAB12A32B27910BCE200AA94AFD048 +:1092D0006E9E93F17B67DA13E378C9F1D9B5999A59 +:1092E00005E33FF7EBDEEE7901D7BBC7427AB271F7 +:1092F00055F411F403DC9CE9B7E7017D9CBAF3F562 +:10930000698A873E23BBFCCCBE51744E705E5BE223 +:10931000B92BB631313EC8DA33F8F9B2CEC4F7789A +:10932000BE28E1BB73E285DC4ED964F48F463BF284 +:109330008AAFF27C880F16EB18AEEB0716BEFE81E3 +:109340007B5285BCF68E8CD707E3F2865A5F68376E +:1093500016E3F23C0F54B66FC0F58575AD17EBFB05 +:10936000C1935F1989EB7BAAE72B23717D37193AEB +:1093700034E48F7FBAFC6588AFE357FAC8CE93799F +:10938000AF174A775ADEFFAE3EBE56E2E50BEA6300 +:10939000FC8BF77F3CFB0F7DC042FA859F338DF934 +:1093A000E14ED27D5B673ED129288F87EAEFBF85EA +:1093B000DFC96D6601F477545445E8BB8ABFE918EC +:1093C000DA75D29E4D86DF2FE05F96A7BD9C83F3B2 +:1093D000107EDB3AD1B739F831B79B1F52C82F6BDB +:1093E000F604D226D33E69C1257A922F3FA7730F88 +:1093F000AC57B1E37E63F1432D547F7ACF7CAAD77B +:1094000099C361DC5735403D96D74D49CC6336EE64 +:10941000E6711DB98F05385E4038529C5123D267E2 +:1094200023DAC90062A3CAFDD78D4EE60D30B46BB6 +:1094300013F77D323EBBD5C7EF73D9DAABD0BD4E43 +:109440002EA3BF381FD735294EFBFD3CAD3B2F2E39 +:109450005E3ED7A505B0EC34B242C4D3BA3C8ECF41 +:1094600088419EBF4A3C0F7868FF0D640FFD99F953 +:10947000D207CF2B0B26C4D1178A739B0BC5B94DCE +:1094800094D3E124391D5FAE8FCB2B0B0F961F10A9 +:10949000975716FF5D7C5E5938419E7588730CCBDB +:1094A000297EDD0474BE72428C0EEB99F8DB1C7DC4 +:1094B0009BCEB1EC34917FAC5EE49536D51DA37D97 +:1094C00047139E8BE1FCA8F173D1DC1EAA87FD1C1B +:1094D000E5D78612F34F770F2937FEDFF8C17F29D2 +:1094E000E581E047392F398FFA5E85F34F129CC929 +:1094F000FBD8647FB6DC875EB0FFFF7F592E4592B4 +:10950000F0F0AFCAA573E20225D134EF97101778B7 +:10951000CFD3E142D7A0CC036EDFC7F380A7E96DBC +:109520001A8F43EA799E42723CD6338DE28D32FE29 +:109530006B7E4A1F5C534CEDBD98BFD5B02F95F2A2 +:1095400006EA3C75647727C72197B09E69B8147FF7 +:1095500066AFD039AC7F3BFE9F2FEE09F6B0E22F0D +:109560001AFFCFE7FBAE0B8A433E67FB38D31F479A +:109570002F5563C1801F3B747E56413E5FFF14919F +:1095800027625603CC11F7FD50DF8DC8E7795FCF16 +:1095900089BCA27B5353E81CBEDBC8CF1DB8753C09 +:1095A000FFE9E31CDF2884DFECE1EBF9E3676E649D +:1095B000788EECC786109D8B0F34D8BCA8C7A4FF4B +:1095C00048F6DF9EC3E1BA503E9A92FFE5F2D1F928 +:1095D000E4C7B47CE58BC5D136030EE2F82B991FA6 +:1095E00086FA6E28F97263BE6F16A70B6D3CC51F15 +:1095F0002E502EA59483DC463DBDDBE4C1FD03FA6D +:1096000051483F6ECC91FB6F7E4FC0BD05A4BF3E5D +:10961000B0F0FD843CC73380BF21F1FDAFD979BFE5 +:1096200073F9EAF3D1BEABD4E81CC0BA54AE5FA262 +:10963000BB781E50F2799664BD22CF63C8F1BEFF9D +:1096400025D3C31795AB77CBF1FF4DB90A7A96F6C0 +:109650002F43C65BCFF93E20F231FB3591F742E74D +:109660001A245C4DFD3C7FEE47827EE5FBEF09FD51 +:109670001BC9D7BA90AE4EFDC16CC67866793997D2 +:109680009F8D3E1BC5031A433C4FA67115A37DBF9A +:109690003CB73AC6ED7F04D76FDDEB36BA87B471BD +:1096A000CFF6F6619447E027FBEEF41FF8FB37B2E4 +:1096B000FD8F62BBA6559184B843C5671FAFAD2926 +:1096C000277869DFEE34259E077A259FEFC7E5F3FB +:1096D000C501FCC2FE04BE3B55C7F3B59B9C9ABDB9 +:1096E00092F207B85F3BC5D34F7EA0C6DDA4241815 +:1096F000258F62FD77F3896E1A775796D17D002109 +:109700004B19DD27F306BF7FE9D49DB9413DF783AF +:10971000EF477853CB8357A39D5904E3A0497AAA16 +:10972000E7EA32F20F26F19DE4B78173A0B7988380 +:10973000AD4A8C1F3719B89E94FAAD27DFC3FDCE12 +:109740004E9107D83B932DB0C5CA3667627EE4B20E +:10975000BC2B7B707D7AF25511BFE6F1F26233ECDF +:109760003E879D4B87C5225E3E53E439B0803996D3 +:10977000DF30ECFCF172099F2CCB7879CA27E2BE6E +:109780007FBB91E822B59DCB0D06748176F6946877 +:10979000FF543C7F55D2199E82F84A47F453BE6964 +:1097A000E4EE8B310E91A94EC138C4B695130E600C +:1097B0007C545DDF7F392E8DA7C35E855BCC316E17 +:1097C000DFE97CB2079B4B91FEAB7E6BE07989EBC6 +:1097D0005348DF7716D6535EE2E9D74D09E76D921D +:1097E0009F01B6C68D7EA361EDBFA13840EA6E65CC +:1097F000D07CD371053691B7B8C68D7EA8D4F6FE5D +:10980000C024F4ABDCA3F0BB1C017AC58DFB7F55F3 +:109810008776C7FC3DFCFCF6FC0E479599E4A9C28F +:10982000E328539C2427D5F5D7E8709FA6B630BA15 +:1098300037ADA480DF9B3AA2D3AEC375FFE5A7FA8C +:1098400041E3639905B13C37445783297AD05D1CC5 +:109850008BEBC9FCB6A1EE2397FA28D99E3DC78EA3 +:1098600015FA68C09E4FA2E3A1BE93F42DE9F997C3 +:10987000064676D82F15339DEB9274DD26F3F53F1F +:10988000E57EDD229137736CC3DFC7F373EB322EB5 +:1098900012E4F7711A226BF3085F91AF0670DEBB1A +:1098A0001DBAC6B1E40F6BA47ED6F3FBCE8ADA876D +:1098B000AF99548E4F3B530084637B9716215F060C +:1098C000800E460C42071FE5F37327EAFA145A3755 +:1098D000F53EBAE999A90E17AD9B7A3F5F9F53F900 +:1098E0007C3E322E2BFD96917C7F55C1C4B87358B7 +:1098F0002BADFC1C9638E79BBAF2F5C7F17CD3364A +:10990000E13F3EF0EC18FA9D86B3EB5505EDD4B37C +:109910008E5AFA5DA26B0BB8BD94AAF633BB2D9E8E +:109920003E0F507EECB07D3CCF4F15E798D5F5CE7D +:10993000ED88CFAF3AFD94077C795B987ECAE059F9 +:10994000FB718AB7815D44E7554F3EA348BB284170 +:109950001FCA7D5BF27EACB6E07FD64EAA2F48F4DC +:109960007B5CF03E8B25EE3707DACBFD63F27E227F +:10997000E9FBA1EC1FA60512F25D568B3C68A9DF3E +:1099800073856C94793003E79659D082E71EF29183 +:109990002927C6F28198C813DAAC58BD682F0D95F7 +:1099A0000F3490AFC39A2FE6FEC8E6AFE053E6133C +:1099B000C97C210BE68D649E9B3762C1BC914CFC37 +:1099C0003D0B7EFE59E67DB41A3C944712F81EA367 +:1099D00078A032AB86FC75193E23D1DF1916DC82E4 +:1099E000F7B90766DBE89C379E0B42BA8F2A6EEA0E +:1099F000776A8D26DBEBB0FDC0BD80B58CEA334ABB +:109A0000B41CB4C32C508FF7150F9C7B5EC0EF4F76 +:109A10004FCE1B91F94B329E9B3BEA2905FDA2E8F4 +:109A2000F6A73C826F89EF8A793F9DDFF490DC7066 +:109A3000B5F2FCA4E8A5CC8E7EF92A297FCC89EB6F +:109A4000BA49F117237F6EB2F273FFDDCCDBAE872C +:109A5000F21D05C3B85F8779F6EB486077D0EF2F2A +:109A6000743AB5A70AB262F424E1629BF9BCCFE074 +:109A7000392F2536DE99C57F2B44FBAAAAD7C4E926 +:109A80003269FCAD03F7AE042DA84F5E2E6044672B +:109A9000DE247B573E5F96FC26E4B21C7FA8F94982 +:109AA000FA3C9F1D2FE96F287A0B5489757A2B8514 +:109AB000EC0F496F0756EFA47B01FB5687E879C688 +:109AC000A284F4783ED6129D8B92B17FDB9FAEC309 +:109AD0007B39CEA4460BF15E8F377FFCD7AFE1BD5B +:109AE0001D67B2A26F61F954E1381FD58F886EC32C +:109AF0007B3E743FEEE1F5B89EB960BF173CF2B50E +:109B0000808DEEC95ADB8F7AAB3C291F25E93E8256 +:109B100014F17B3ED93623D993D922AEC7AA855DED +:109B2000CFF8EFA2B5E694511CCFC63CBBFBB13ECB +:109B3000DFC4EF2D6040FF583FA298E735303E6FFD +:109B4000962FFCD32C12A0DFE72B76D0F703727C84 +:109B5000B749C4A7F8F8879FE47144999FCB98BD93 +:109B600000ED219B872594E57D1E4CB517E0F9FD9E +:109B700056E9F713E52753FCC6C238BD7CF8CA3B4B +:109B8000C6D2EF843CF5DD12949B571913EF59961A +:109B9000CFE78B389D9C11F70936A5F8D30B61DD13 +:109BA0008FA4CC9D8657C3CEC9AC343AC87EDBA502 +:109BB00047399525E8C3319BC3E7A8F629F8FB1C74 +:109BC000F23EBF2CBF4A7E02E6EFD4A35ECD3AEE52 +:109BD000A3BCBF7A73B4107F47E505B33F0FE13CE8 +:109BE0005B7BF4768A17E61E7E0BF3340E1B3AA6D7 +:109BF000A6A11E2916F742604016CA07F38A683FDD +:109C000038201F462814CF9C319B9F5F9DCE422A4F +:109C1000AEF3343B3F4F35ADBCD8DB0AE3CD107912 +:109C20001ED38EF8D250BE4DBB31A2F27B2BA26A5E +:109C30007C5E857C32B7C113CF0F577BE2CA0CEF35 +:109C40001D4E2C5FEB4D2C7F6DD2A7A3E2CBE3140E +:109C5000AD02E7F90B45DCFF00F285CF8BE70F3E45 +:109C60002AF67363DCCC5C84F98D4E2580FB85314C +:109C70004FE7529CE5E9498CCAAE9DE61DE6F8F92E +:109C8000DFA7E37168E10797BF338475A86F9FFA78 +:109C9000838BF0E5B281BC7592F4217A3B20F8F613 +:109CA00080E0D38A3CB315E5FF0183A78BE83CD560 +:109CB000EC413FD5FE5423DDE3DABA8CFF4E8192AE +:109CC000666646E8573F8F97A11DD80650AE3053C1 +:109CD0005EC801916FDDFA3D95FC5C588FF7EBEAA9 +:109CE0007F6025FF76755AE937B05E9F66A4F30E54 +:109CF000FB532BFC623CBA5FFEA15473187FEF202C +:109D0000F93ECDC30817E20DE07A98C341FCA8AF35 +:109D100030921D2ECF9F433F147FD3E79A69BC0337 +:109D20000EFB7EA4BBD6F7C8D283FA491ECCE392C1 +:109D3000F45D9D36897E3F04B8AF24FEBE74BDCB72 +:109D4000EBE1E766F9EF62940EFC4E060C0BEDF0CA +:109D5000378518F12D8FE71548BC3355C3F6394CBC +:109D600096F9B931D740B952A5FB7F14596EA1F2CB +:109D700003A25EDEFF79A890CB29A5F785BF22DD7F +:109D800096A4015E609DBC29839F5B7AA090F3ED51 +:109D9000B9EB57E146BFBF82F31C1B9BFF0187D77E +:109DA000ED8B2B0FB22E41A4B7E4753960F17AD058 +:109DB000CF76FEFE385EE53CF4B91C9F03F3C81C69 +:109DC0007C1E87C43C42E29C7572FDEE426EBF7EF3 +:109DD00089F31C94FEFEE579BA12E7F925C2195100 +:109DE000BE0438F585009F2D061FFD0C5805CA4D91 +:109DF0004E7FD3459E322B4DCC4B6293BC666E2F6B +:109E000026E6215DA574B5A17E7D40C4B95F107CB6 +:109E10007530E5FB25686FBD3077641FC9DBF496AC +:109E200036642E299FA5FC3F9B73B402CBA007DEAE +:109E3000443D73FBB0C373B1F33EC70325A8AF40E5 +:109E40006EFEB170E2B9704AFE1D8017F817F9482E +:109E5000F26F32FC928FD875214ACCEC66617ABAE7 +:109E600019CF8307BB84EE2B679E82D8FC80C9A7DD +:109E7000999BF93C5A0204F7558E1F52FEDF598F09 +:109E8000FF23846BCEC51FD27D48CC5D3B0AF5080D +:109E9000C0FBF1FF26BC209F72F0BDB4F393EDFA36 +:109EA000F3E5834B3893E5A1844799B593ECF82605 +:109EB000B0E379BEB842F2BEA94EC7E5F01E85EC0C +:109EC000FA46D033A8A7E4FDBA578CB4B6E1BD8FEB +:109ED0007B0DDC9F1A78D2E449BC2729396F5CECF2 +:109EE000275631B95FE0F74134D8F93D4842CF7485 +:109EF0007E7B98BC2789EB43D05309F724D57A128F +:109F0000EF491A62BF00FB02B2CF58BA4EEC0BB851 +:109F10009EEEBCD4630F30F23FF3DF7BBCC928EC6C +:109F200041C0852B768F1BEC03E87EBAAF14158BEE +:109F30007BB282FCF73584FD9FEC8FFEA7CB3FB947 +:109F400008E87DC158AD107FEA65BE91FB9B81DEBC +:109F5000BAFA19A63F363F84F7955ECD9A5FD30DC6 +:109F6000277AD3B0FD9C311FF27B4C63F456599491 +:109F7000C5F5122A99F3F1F161A77F7AD144C45F44 +:109F8000E80DBCCF7C6BAF89F02DF34B93F93B0E02 +:109F90009EE3060E8F53AF2778660D06CF85D07DE2 +:109FA0003C5D65334EDF43D13F9EE3489D10A3FFE8 +:109FB000718ABF16C71DE083B57CDF750EDC7A1B86 +:109FC000ADF70D37F1B85C538ADC276B33725CE870 +:109FD00087E4E3DFB09ED3C50DB53C8F68666F03A1 +:109FE000C5E158358FAB79E17F08CF0121DF663BB2 +:109FF000CB0C487A7F66DF30A09F73F68CC4F8DB09 +:10A000001CF35514EFBB61B621E1F72A251EE68843 +:10A01000DFC39E93F43B95C978498EDB0DC80331AD +:10A02000DF3CFCFD1678E6337E7E2647FCAE585BAF +:10A03000D1C0F9DE515F30BE7777D11788EFF519BF +:10A04000A2744FC3F3598BBA9601DF8CFAD158BA78 +:10A050007FFD4AD7E287EE83F24FB65E44E5E75DC7 +:10A06000B7AC388CF5DB4652B95AF7E15CE483D2E1 +:10A070008A9BA6E37DF57D16DE8FDBEAEFC4DF3138 +:10A08000718F1F3601F380AB8D516A77CDC50D9767 +:10A09000603E54B595975F29FBFD042A0F13E5092F +:10A0A000BFB808CB7DCA8773078B0F8E2955C2F8BE +:10A0B0007B65D519BCFD8C09BB72D15F545DC5CBE6 +:10A0C00063BC95EB8763BDEEA3B983D923CF140995 +:10A0D000BF91B0AF7D82DF9FD68EB6E179409F4DB4 +:10A0E000F1E2B90FDFA4A3FC7E3433CF2BF1696515 +:10A0F0002ADE9F59A5713FEF545B4B0ECAC5EBFC9E +:10A10000C672F4E7DB6DC56D6817A74FAA9C88EB94 +:10A110003DD5CC889E80AFF6E13ACCF9CA878569F7 +:10A1200048CCB644BE92743B53F2537522DF803C58 +:10A13000788ECB83447E807E0F11BF5E96A8AF06DB +:10A14000E47D12DF26D3E39076014B9483313A0D00 +:10A1500029F1F4D98DFCCAF9F70F088751D7EFC15F +:10A16000F7458AF7224AB419C2BE90F0A1DB924D9E +:10A1700038172EFC53A53DCE21B0DB5D382EAF87BE +:10A18000EF34FC713909178CFF1EE1672D87A75B3F +:10A190006916BF57C2F761D2DFD128E7BB2771BE6E +:10A1A00015567E7F811BFD3D14C329BBE8F3E06E8D +:10A1B00012FA77B6D9778F09E6F075C77C5AE71B94 +:10A1C00041033A60FEBB52FC7F4778F4BAC0BE88B8 +:10A1D00082BF37A2513E0CACE33FF83AF275917062 +:10A1E00025E3E3FF02863CEC3E0080000000000017 +:10A1F0001F8B080000000000000BE57D097C54D592 +:10A20000D5F87DF3664B324926098484409824644E +:10A21000830426611164712004A3020E8B028AF864 +:10A22000C21AB20B5D624B9B81B0A9684345A5166B +:10A23000754040B0408302A2463A2C2A56ADA94B45 +:10A24000EBD2F22548658718AAE2576BFFE79C7BA3 +:10A250006F66DE4B52A45FBFDFAFDFEF0FB597FB3A +:10A26000EE7ECEB9E79EEDDEA9B43B02EA00C698C9 +:10A2700087F5ED16CF9802FF642EF8EF80E57C732A +:10A2800016A33FFF4865ACB7096AC44279E3EB5FA8 +:10A290002B587F5583C2D218EBC59A12314D64D525 +:10A2A000944F60EE35AA8AAD7AC57CD69F31FCE723 +:10A2B0003F6E60AC2E12FED18DB1D63C9B7F330E2B +:10A2C0006286FF0633F6567186FF7EC85FB238D6C7 +:10A2D00028D19057589619EAF99470F7D614C6BE4B +:10A2E0000A8B1AC0E07BB7704807323662CE0F2661 +:10A2F000B1A88EF3ADB1F37A3F0C8FDA8CE90D196A +:10A30000E12B4CD1D83ED98FF5BB85433A2038FF9D +:10A31000AF4C4CB3C37C7FA8C23A545C47EB32339A +:10A320008CF704ABA7FC68172C7A08633DDAD7E3F7 +:10A3300053BCB98C594DCADD5E07AC09FFDC104C2B +:10A3400047BB4C8C752770290CE65529E1E85298DB +:10A350001DF27344BE52C0BB9BD5D50BFB31C279F5 +:10A360008EDDD642F05D53E869B607BFB3FAC73C4D +:10A37000A1FD74554F01B826C576843FCC9FE637C2 +:10A38000B1A6C07B320EC717F8B83792F031F1DEB4 +:10A3900031F45D9992A534C3BC0A8A5C94C60EFE62 +:10A3A000BD99E5125E6634E404F174B2BB76B30B7A +:10A3B000D76B6E1E321970FBF69067F234283F6E31 +:10A3C000622558CF089FDB113E433AC247C2C308FB +:10A3D00087AEE6BF2FC23BC305FD5C509A8662A1E3 +:10A3E000BDA753C05D4B41FCC43853C6C420DCBF7D +:10A3F00081718732360D8B00CF0FC66B1AB69BCE9C +:10A40000BC8566586F6C9166D11C349C09E7B3D843 +:10A41000C9E753A83A882EDB762A7E1BD41BE7C9EE +:10A420007E6C24E4AB8E59981FCADB18A7DBB68D6F +:10A43000AADF07F4B2F08DE78706E0D3A7824E3398 +:10A440003798984BE203FECBF68733575630DF7FC1 +:10A450007BAC2E9FDBD053577FE081545D795EA0AB +:10A460009FAE7CD0B17C5D7E48D3F5BAFAD77D38FB +:10A4700056971FDE7CB3AEFE88D35374F951AD7787 +:10A48000E8EAD785C1FE1988E0F63465015CE60983 +:10A490003CDD70658EAEDDB9A8F1C7705FCD5BBBEA +:10A4A0007002EEAB31AC4CD70FABB79C40BAAC8668 +:10A4B000BF88CF05CC1B1D007815B2D6D792007E81 +:10A4C000957EC58D705BB881D793ED161DB8676C0E +:10A4D0000CA67EFDF732660EE6A19F9A3F6DFAED5F +:10A4E000D190F271CE6213D2DF465764B7CF2210FB +:10A4F00010ECBA7FA89DE2D71D40FCBDAFBA6DF04D +:10A5000069F11B2AED83C5BB143F837E33587A342F +:10A51000E6AB8EA9CC0FF83FC5AA1F1D09E957B5B8 +:10A52000FEDF1E4D0FC2C796A0C773984B8FE788FA +:10A530002C3D9E23DD7A3C470FD3E339C6A3C77376 +:10A540005C911ECFDDBD7A3CF798A1C773A2A6C768 +:10A550007352891ECFBDABF578EE53A3C7678AAFA0 +:10A56000548F3F03FE25FF4D5BB35857AF9D0EBC84 +:10A570002513304DAFFF91AEDF32B5DC0A1868A766 +:10A58000071FFC457AC864CC1D003857021E02AE76 +:10A590008E7450D2B86E55D2BF40077F42FCF70F81 +:10A5A000C1BF3A2B5AEB845FCB54E23557F19C4044 +:10A5B0007EF6A54BFB0BA633323F4F3603DF60DE42 +:10A5C000E24C6F6490EF3116606C68907FF5C6B511 +:10A5D000E5333A8FCC4383E751577CADC3393A49D1 +:10A5E0009E3F5D9CA3AEDE413E0800F988F95E699E +:10A5F000A641D69A701E33055D1F0EE77479198B3C +:10A6000086433DA8330CE6F511CE1BC6F928BCFFE6 +:10A6100051DCA777B0060BF63F8B35513A9BB5520C +:10A62000AA31A715D339CC4DE93CE6A5F475BB6634 +:10A630004B017894DB9B873298FF97C5BF3FAEE014 +:10A6400064DE8AC3C9760957C9AFDFC37F42BD91B3 +:10A6500029DEE814E0BFE3ECAEEF3D029F0EE339E4 +:10A6600081FC77421CCD9799BDB953723BEB67399A +:10A670009D1B2F2B9A867CD79768776F85B5F54FF2 +:10A6800062F6443CE712FCA953003FC929FAF3B72C +:10A690009FA0895D3D1B16C7201E993F16CF876B73 +:10A6A0001DB75F8A271DD72FEB5F6DBD566BC33D6E +:10A6B00038CFD60A877B33D0E7FB021F4FDF6E0B04 +:10A6C000A851413AFA3062F66BDD016F5511DA207C +:10A6D000EC7FC6F49B56615E391CE75A0CF3BB5401 +:10A6E0000CF0E6F0BF8EC35FEB130F4BBCD05BCB1F +:10A6F0008C46F87B39FCE11FB9DE4EE7CFE753A06B +:10A70000F0F1F745681EECE7B0A929D98DF0303794 +:10A710000DC576CCD19DFAB960E570E90A0E6323C8 +:10A720007ACFC275CDB3D9DC2AF43956E1783D1918 +:10A7300077F7EC2AF8E77C93373EA0EAE63D09F18B +:10A740005DEE2CEE93087473C122E66DEF2EE0EE01 +:10A75000CAC17DD5D5BCEBB07F94037FA2F8510E62 +:10A76000A43F907FC117E3BF1FF236D3E5F7A7A23E +:10A77000FC926B726F86A28DE1D035D0FB3B02DE7E +:10A780004F58201F4BDFD7E0F78470DE3EE1519336 +:10A79000BF0EDA7BC7BE48787ABAD241EB29662E63 +:10A7A0002B6EB2B9CC4374FF97317F7BA519F05162 +:10A7B0009EA22D44B8DD1D674A7E9FE6A1F547792C +:10A7C000878DFC6EF42FF7E914275FC27C01B7A9CF +:10A7D000CC43FBEE36A65970DC772F5A3DC83FDFDD +:10A7E00015FC643AF3D1F799CC4FE99D2C40F5EF75 +:10A7F00062CD94FF7DC480DE3530BFC98F65A6234E +:10A800007F0D81FB4F08EE76EDEE6E9C5E4EF540BF +:10A81000B8AFEFFE9DE877B2A017D8AF2B71DDB0CF +:10A820005F07E7A586EC9B719C5E98D999FECFF6F1 +:10A830004D531B3F2F80313A1261FD370A14DEE879 +:10A8400029A37302E5AC6E00FF26974A7256D19891 +:10A850001633CE7FDBE79C8FBDBE8C45FAA0FCF59E +:10A86000312A437C4DDA30FE0CB67B8B05BA0D865F +:10A87000FA8557B4A3D1B0FE49C0DF8123B3A25EED +:10A88000704E849C4B3727AC1B8772C4CD7DF5DF9F +:10A890006F61F52AC26F428EFE5C9984E78AAC072D +:10A8A000E31D4238C4763C5FB6A708F9A21FEB77D8 +:10A8B0002DE74BA5C9F36BE223406748F773CCCC77 +:10A8C000D3D97E73642A928F91DC72AB18BB6DC2B0 +:10A8D00065EB2558EFA914ED25EC67F1C4BFCC4614 +:10A8E0007E0C7AD4DB83F01CFD9DCAEE87F213B593 +:10A8F0000071385C4FD6DA9907049CCF6A9D943F6B +:10A900005D9B40E9D95A17A5E76BB3A8FC62AD9BE4 +:10A91000F251A9DE23D8EF9C359F9B518E5A1D26FC +:10A92000F1C7E7B144D0EFEA30AE472D895CF26160 +:10A93000318CBB840E4038AF1BEAC723584A0F3412 +:10A94000BC86297C571D58BE4E71E3F934FFA8B66A +:10A950000AC967E15BCD9390ED0CF9E0643CC2ADB0 +:10A96000E28AC234D84A3F48F7BC8BE39FAA1D460F +:10A97000F33A53EBA179791A5B5E8B83F6E76A8B26 +:10A98000289F99EAFD10E9DBC33EB762FB893B5B78 +:10A99000CC49505EE8513CB8BF477B98DF0FF8DBED +:10A9A00060E1E7C506382F907EC6E44E79E27B88E9 +:10A9B000B614ED048E735BECDCC238A4AB61C566E3 +:10A9C000AC37FD1B90B95282F47DB57D72E1A04297 +:10A9D000F0B9703086E021E15421F075617FFF5BB2 +:10A9E0004740BF07418E54617E6D574C34BFB60F50 +:10A9F000C3FD282418DB2FDE97D68339709DD0D86D +:10AA000086F9FE3D18E021C2FEF413A8979DDBF500 +:10AA1000C304C4CBB9D8862F3F46BEF767CEF7181C +:10AA20006BF8EC71E48BBD12DCF743EEA205F43455 +:10AA3000D26BAA23F05CACB4328DE7B5FE983F1719 +:10AA4000CE487F1DBA3B692CEE271CCF9519E46BCD +:10AA5000598A8BD500DD67EC7E2CF5C730EFED0D04 +:10AA6000F33F7E1CD20B7E93CF02E7D605D670F162 +:10AA700025E4CB5B1CEEAD0CEB9BC3B1FE03163E95 +:10AA80002FDF56D0DB5DD89F9FF800945BB1BCFCF4 +:10AA9000B95FF4C4F9BF8C7209E45F5E1741FCEE44 +:10AAA000658BFB780DB67B82F7F7CC43F79E388039 +:10AAB000E98315F9F742DA273596E03DEFE78BFA9F +:10AAC000617B38F75922F0C75FBDA004C2006EB9A0 +:10AAD000EB0F2D4F84F1066E6C31F584346F8B5281 +:10AAE0008769FFDE45C7F0BC4D4F75D13C06ED4C84 +:10AAF00051519EECD7D3FFF10D240FE8E5849CF56E +:10AB00009F8FEDC982F2423FA5E1EC32A087D5BD0F +:10AB1000FF90CFF5C47AEA675FE3D4F7EE64B80E2E +:10AB2000904470DEC556B253E0722D90BFB0376DC1 +:10AB300013DA33F69B7C9BE8FC9AC3E5950B5EDF4A +:10AB40002F90CE2AA0BE0FF21579BEA8EBA1BCE2D1 +:10AB5000CF7DDD4051ACF7933716213C2AF73E32CA +:10AB6000BE27D4BB3092B90115AC64DFE5F1D88EB5 +:10AB7000F586B5603F7BEBE2EF80760FE48C1D82BB +:10AB800074E5551B681C56C5C7794C9C7BAC198075 +:10AB9000132F5809D47B003EE3F7D8C69843492CBD +:10ABA000889FAAC66529686F19ACD9DD2AEE9B1467 +:10ABB0005F62B523788EC2F977632AD44BB48A7E5C +:10ABC0009D5393BDD770FE59C57926FB7BCCCA7CBB +:10ABD00061B15C6E56F07CB6F2737B2BF0979AFCF9 +:10ABE000E0B90DE34E4FE5ED495E4E82433A0FE684 +:10ABF00099F498CD4FB2C1771C5FCA5B55427F91E3 +:10AC000072CB8CB8BA579A61BD8F456873717DF36A +:10AC1000C5B9CFCC6E17CA453F8DF0CC4B25B9AB2B +:10AC20003519D700E76A09E62B5590C3D242E430C4 +:10AC3000FB773B577744782AB1FD77AD6FE4BB4B88 +:10AC4000BE30B13CA083258FD8484FAD13F6863A6D +:10AC500061DFAA8B1C6A477EC18E9ACA5F83F37636 +:10AC600014EFA1BDDF2591F9C44FEA18EB146E076C +:10AC7000810F68C07702706E68C00F465F695539F2 +:10AC8000DD371D891E8CFC9679225D680730312DD9 +:10AC9000E43C35F603787B08E1398645302DE4DC69 +:10ACA000F4B0182BEE5FE688FD97D63F52E04FAE2A +:10ACB00063A4B0E78D6CFB3002F9E6922FF2897F36 +:10ACC00076B5BE57C4FA7E83EB83D492E9DD84F86F +:10ACD00018F557A719D739CA3C3919E51C98FF331D +:10ACE000F87DF45F4DFAF97F13AECB7FD7757C5FAB +:10ACF000613E13EECFCFAD7EDC9F8D40DFB89F1B52 +:10AD000017E5F8910FEC87FD6047BD668A95E4DC96 +:10AD10004661276DECEE24FBD2CB169EF7CD14EDE9 +:10AD2000C3189D238D337B52FB9EB6EA3773B1FF68 +:10AD3000BA08E29F8D16FF9A54ECFF27716E1FE050 +:10AD40004BC5F36310E81B827FD7590277AAD8DF7F +:10AD5000E75686E3AD8F09245541FDF58B7A52FD08 +:10AD60000F419442FBDD0893E9EEC90E2CF724C68F +:10AD7000427EFFB72A9D1BEBF320EF203E4EF6C02C +:10AD8000F5933D89E1DD308D37D17C54564DDF534D +:10AD900078BB8F2DBCDE1D027F1F09FCC03E273E05 +:10ADA000A04D8A30231D5F4C9DD342FB8379121541 +:10ADB00098CFE3F3D219F2D13B4A6F4A21BAA97F67 +:10ADC0008CF8D90C8103D91F36B00F45399AFF99F9 +:10ADD000397F6B18E2F3B69230B28F7E58B23CD214 +:10ADE00005ED6FD3D4800DEDC6D30A3DA1FAF8C5A9 +:10ADF000540F8D5BD1909D763284AEE7D8806F4042 +:10AE0000FF6BC2B5D348CFEC401E951F00E1E61F93 +:10AE1000B0AF4ECC4BDF4D768D79528F0CCC45BC0C +:10AE20001E6CB533D44FBAA2873AC403F4DB479CF7 +:10AE3000EB44AF88FF19E15CCF3103BD40BEAE21CA +:10AE40009BF49CA72CCCA320BEF6D908FF4553EC5D +:10AE50001EB23FCE08DF6483F2BB053FAB9B114EB1 +:10AE6000DFEB5E89F49B14D29F28EFDB63A176E5CC +:10AE700056FF8E6DD04FF9C16C3A6FF65BC5B82F97 +:10AE800045F0F2284FCACAC158DE83E8E0658B2B33 +:10AE90009ACADF50199587073262008E91615A581D +:10AEA000DA10A43BC0B303FBE5DF8F0BFA3A0EDDEB +:10AEB00022FE7CD591D42F6D7DC86B75BD37233EA6 +:10AEC000352B2F673F52A9FCB8D393381FF2C7AB7D +:10AED00093685ED2CE74DC6B25BA3F5EAE90BCF454 +:10AEE000A71A35600DB5E34FD97E5F06B4FBF4A019 +:10AEF00085EC78B37E56F6167E9FB5BC82EC91B396 +:10AF00004A97929FE0E2D24F876E80F5342FFF245C +:10AF1000590BB14BCF2A8756A176D5344F6A1AE028 +:10AF2000E7D6342D1DD75795D3BC00E5EB8BD6A6BD +:10AF300027515F7075D3B2F0FBA5174F6DE37277A1 +:10AF40006B069E1395664E27F2BCAD1274F85F69CE +:10AF5000DA00EC0FE0361BCF95889C26CEFF967E5C +:10AF600037FE7FB671EB7E05C6290B6FACA454F596 +:10AF70000FC07ECE298128258DE0A8E1BE3AEF0CD6 +:10AF80004421FC351397F3CAB6EBD7857FCCF16823 +:10AF9000376364072F6B503D61B80F98DF8AF32F3A +:10AFA00063D660FD9420BEA01FC21773FC69F68FA4 +:10AFB000010FA53BB2F351BF288B39F0D008AA0787 +:10AFC000EDE47E513BE6E57A3ACE87AFEFBCD80799 +:10AFD000E7E18B05E965A74DEAF934FEC5177BD09B +:10AFE000F8F1629F5C5404BDEE08E374E58675E1F8 +:10AFF0003C7FCDE9EA51C92777F07ECAE27C26E49E +:10B000004B65B54EA22BC997602EB4BFCEED4EA2B4 +:10B0100076928F312F63547F77E2662EBF097D17BA +:10B02000270CF54B7FC5C7C13CF2F3B3CF26C971DE +:10B0300049DE369EC7C6752F49E3F62938A77BFC43 +:10B04000337D312B61EE13F30685AC27D22AF882CB +:10B050003B61722EFA17ACBA7E2F465AEFF638D003 +:10B06000CFA0FF2EFBAB4DE3FA641F039E7BAAAD7E +:10B07000876CB80F9F66746E18E7B14AB47BF6D937 +:10B0800076BCAAC29ECE5C929E5C5C9E27FC7D64D0 +:10B0900095F8FB5E12F0E33284556A108EFBF3B430 +:10B0A000243C372E0AFFD0FE18C8E7A03CC5F12289 +:10B0B000F3121F46BA5CFED18224F4473D2FE168AB +:10B0C00080F732802B96D75940BFC9413DF7D8C38E +:10B0D00027D383EBF9ACD6E39917925FB021CF8EDB +:10B0E000FB71E1C63CFB9C107CD46D1F74CC0570D9 +:10B0F0003FBFDDEC46F65E67F63F84727ADD76B5DB +:10B1000001E908CAED08EFF38EC3BFC37A0B36C658 +:10B11000E4A31C2EDB2FDC50E899178287FEDBF5B9 +:10B1200078C96DD0E7071ED0E75F4119B4FBB5B70A +:10B13000CB0BE8F3838EE9F3AC15B03714E5018E41 +:10B14000B71786B98FB9006F7DFCAA1B3FF5714C0C +:10B15000993A11E5888DAA3B1DCAFB2CF5DE827257 +:10B16000C5E98DF3DD88F612D557F963C069C927A3 +:10B17000E38FE1B97A8E35FC6122E06541E33AABB9 +:10B18000D985EBD6D3FB7E93A0DF67B9FD6E915FC7 +:10B190005FDE912F2C93FEC1AC50FA32D2018C7B32 +:10B1A000BB0726545EF3DEC3C8174A2600E1039DA1 +:10B1B0000D6F586745F9EFEAE3F8B87CE9F0B8108D +:10B1C0001EC5C378D9F53505EC53D8776CEDEFC7BC +:10B1D000E3BC8B1F5048FE287E3EF328D257CB9EFF +:10B1E0009937537A7B11AD5FDA0917362A8148C83F +:10B1F0003B87B90E3443BBF97E6EEF98B3C216E4B9 +:10B20000870CFD648679AC0F2987F92F3C70E86BB9 +:10B2100005FA2FD9A86FB708F8349E3FA55BFE61E9 +:10B220000BFD2EF5D1EB1B37A9B8EEF962FEF2FC4F +:10B2300064BED1E4A7B89E376127F1FFE0DC991D19 +:10B24000AF297DBB07CFD1EBD7F3F6C0768B71DD8D +:10B25000150EAB0BD75D6167810898CFB148ABC7BE +:10B2600009DF2F6F88243BDD021BC8ABF994B23095 +:10B27000F47B3037F9CB3E7B4725B9A7228EE3BD5F +:10B28000E22985F4B40A34AE62FE699E5FC402B45A +:10B290001EA4174FE83AFDFA3CABE7FA5DB93970E6 +:10B2A00008E152CA9AB97E06F8F484F8BBCB619DD6 +:10B2B0001FC6A2FC6668CFDC1AF9F11C5C1EAB3A13 +:10B2C000F00F5B68B9D433A51E2CEDC74F6578C36A +:10B2D000711C8B909BD7DFE7C9C0F9AEB4783210F0 +:10B2E0000EBE7561A4EFDFB1899F5FEB63408EED09 +:10B2F00046F233C9E377285C3E6733393F1C617AF5 +:10B300002E80E74DEB2331EECD2EAA4FE7D8FA077A +:10B31000B3B9FCFFAD4AF250EB3A1E17B13E8FC3F2 +:10B320006FFD83B95CFE97E75E7746FD7594B73D88 +:10B33000196887600FF3797D8C4B0A91AFBF8DD769 +:10B340006EE81BB23E2997B392EFE6CFD82AE234DB +:10B350005AD785F9D19F7152F1BE660A916FBD7DB2 +:10B36000F9393174AC679BA8477E8F79A6C9F7DF9E +:10B3700000F39AF7A8C985F6B776787B3C19787EF2 +:10B380009E5C17968F7436742CB7471DCFE37C3FB5 +:10B390006230F3F8219D29FA9DD9D7A44B13C281BD +:10B3A000FEA09F9385DC1E1E39D84B76C0AD2ECEF5 +:10B3B000F78DEB982FFA9967F5FE765427F3917085 +:10B3C00061E3B8DC71F21E65339F17E01BF2437F27 +:10B3D0001E46F6C393E25C92F005BAA1B807C9B75E +:10B3E00062DAE9C5BF230CE8659D85D381D4DB42D1 +:10B3F000E845E0BF37E1F70E815FF66098A01713CC +:10B40000FB6F8463A193D3C335EA5F80EF9F20BEB7 +:10B410008D7A98C43733FB87FC33BF4BC50BBBF623 +:10B42000FB40CE28FDF523510CEA9D31D7C7BBA1C7 +:10B430007DF9D695511E484F9B7D514E18FF8C5F6C +:10B440002DF27702EF97FB4AFBB5C7A184F849CFED +:10B450003EFBC0245CE7975B2D4E640955DB6DA471 +:10B460008F55EE5D44F23AE45B787EF5E7E837AD60 +:10B470003AA0B7CF973EF348BC8BE0ED4B32256046 +:10B480001A486290566EB1B4FB91611890BF5B5739 +:10B49000E1FC8CED711E5700DF550D6AB135BA63C2 +:10B4A0007995E02F557B1FF81CED86557B6F3A850B +:10B4B000FCBECAE0172811FE11A35FE0577DF571AD +:10B4C00007001F8A33F0C1BCD2895CB85DB96EC772 +:10B4D00063035A507ED8F266949213F40F48BF4922 +:10B4E0005BC3DCA75E7275BD2F2F0AFB70106F9CCB +:10B4F0007FB90E2818AC048A3F4FCB2D81A811A824 +:10B50000EF6DB290FC5BBEEBE96D8F239D7D64A374 +:10B51000F3BD6CD7AB7FB81EE5E73D966E13F832EE +:10B520001C4A485C4E958BDBE3247E4A9F7FD5EA1C +:10B53000CAE5DF97C606F154B6E79015E3838CF0B1 +:10B540002C6838646D767482AF8696F16487DAF180 +:10B550009515F7C799830AEB91D2B17DC9A657A378 +:10B56000503E4338E1F924F1D68E47437DE87FD23F +:10B570004B83A99E13F594ABE1F181BE8CE056F1AB +:10B5800042248B8179947C6CF34F40FCEE5E1285F3 +:10B59000EB3965AEE674FFC4CA7894F74A2CBE78DE +:10B5A00027A5FC7BC993DF277A5CA854C73B738827 +:10B5B000DE134D244BF812719DF337DE46EB5CC071 +:10B5C00034A2C7922754AF1FD22FCCAC684F27FBB1 +:10B5D000E6BA74BE6F4E6D06E4C23A4F89F82CDFAE +:10B5E000BBAAD0A3EFA1F3FCFB62CD8C2DA6FC1768 +:10B5F000429E0B4B6F8FAFB287EAA1555B56372146 +:10B600009ECEF6F6F4C079021C7C026ECA3FA05FA3 +:10B61000F5F7853D389E980BE317A81D9CAB05F800 +:10B620001DEB37593C68670F6927F4443EFEF7C4A9 +:10B63000F830EF70D4834FC5771EFFB500D7C7E74A +:10B64000D7141AFFD5251FD8721FD1D75FDFE77C2B +:10B65000A6D23FB988CA9B2C811E58EE3F344D219B +:10B660003E616381CEF6F9168BD8E7FA7298A75936 +:10B670000985EF412E9F4A7A5900725920444E089D +:10B68000D28F35F89DD6FF73C1E79AC99F27FD80F9 +:10B690000B057F30AEDFC82FF2D23B8F53611B3BCF +:10B6A000F73F05F9848FC62D87F31DE591F28F6C66 +:10B6B000244794EFB278114EE7761EF9C31DA8DF38 +:10B6C00036C87DADE7C3C67D5DF2DC904EF7F5B9B7 +:10B6D000B5799DEF6BF8DEE9BE5EAB10BFFB9FF264 +:10B6E0006138F9C82E71B5FDBBB00B3E3C2B5DCF68 +:10B6F00087BF6039D123B0D059DC87F06480AF8434 +:10B70000AB91AFB6F57575CA5719867484C053C22C +:10B7100051D22B631A8DD34ED7926E255DB7D3AD20 +:10B7200071DD7A781ACB9311F73075EF8B1692177B +:10B73000CA1B797C22B4A378BA2AB4CF53EDFAD7C6 +:10B7400092BA85E6FD867C83A1BEC790F71AEA6BA4 +:10B75000867CB5AE7EF9812356AE3F0474F56C3518 +:10B76000B7903ED251CEF073BFD3DECFAD3EA48FA3 +:10B770005EAD56E49396E5CC1709ED5B5F5149EE5B +:10B78000B9E46A8D42B965651897EB2E39453E8656 +:10B79000E75BBB5B57219F94DF5BC3B81DE692B7A5 +:10B7A000352A26449F6F6954A3D0FEDBEC67459D84 +:10B7B000C7B7D4115C9B5957E55CBEBB14CEED0DE9 +:10B7C00097C2B9BDA1507524D7A01DB69EC711CE92 +:10B7D0005B363D8AE2301AD36E9D01DFE7BF4161DF +:10B7E00006184767C6F887B91C95EC34F3513CE15D +:10B7F000DC461E07316FAD1ECF0B1C5B285EEE0BC7 +:10B80000B694D205EBF5F10BA56C2DD159C946C301 +:10B81000F7C65B689F941AF68926ECC3C67D72480A +:10B82000F29F3C96A78B9314FCBC50CDB97506E0F3 +:10B83000E3D23195D920DFD6A8B25583795C2CFAB2 +:10B840009F5021C1FD5709FB15E52609AFF3B88FBD +:10B8500032BB965FCEEFFBF3D01F23DDECFF64C05D +:10B860002F213DBFFFA38C9731FFC21F933F611D66 +:10B87000EB171CFC7A36F2E94B076D0CE9FDD2C1DF +:10B88000D793D11E79E9251BE9D99796DBB89DFBA3 +:10B8900060A41F8F984BBDB95C5CF7CA57039AE947 +:10B8A0005C5E41F83B9F6EE5F255E3DF8EA33DBD44 +:10B8B000AD1156857CFF6004EDA7AA97C2C8CE7C67 +:10B8C000E995AF8686DAE7FEA7EB91FEF74B916C20 +:10B8D000C67348C7315C2FA87A79F8D3E85FAED831 +:10B8E0007BC83A17CA0B7EF3F701C8572F3DC7E54F +:10B8F000A98B96E627D1C6F955FA999F5B86A39D39 +:10B900000F3AEB09BB3B237BAA2FA733B870385CF7 +:10B910000238E0BA002E25781E74058FA88CFF54DB +:10B92000787C3E9BF3B7EB18FAA38370513CFC7B09 +:10B93000A4DFAED0FAF9F7835F0D40FE73B5F5E6EC +:10B94000FC7FB6DE9BFF63D7CBE9FD5D5442867476 +:10B95000A4FB8E74FDC20F28BF3BD24DF3FD8EFBBE +:10B96000BD14D7DFFD3F71FDFF3BF85EF31FBBDE6B +:10B97000ABE1FB0D81EF4827FA332FBDF2F7647678 +:10B980000DEB7EE6FF289D4B397EACEA3E9607F52F +:10B99000DF640DEFBB53481AE9540E793F43AF3FC4 +:10B9A00015307E4E17D8CB48FE2CE8F520C9CB7554 +:10B9B0002C9FFC17BE5E2AF975280804E0F07A4235 +:10B9C0001EDDB362E640AF25901F9B5441F16246F5 +:10B9D000BDB2207C6211CAA74796C1BCA09F23912B +:10B9E0002627FAA8C7F55203B60194B660FA5AF2B0 +:10B9F0002D14F73FCEA1D7AF6E31E84937B9F4E542 +:10BA000045ECB96EE8B72BCAB1D0FD8AF1583F4476 +:10BA1000AF7C2EC349EBBC89D5AF703AAE1D4EE664 +:10BA20004C0EA78E70F8E770EB0027A1479B457D71 +:10BA300023DCCC8EFB9BB09D99815ECCD74BFAB4B6 +:10BA4000D48BAF064F26F46DB3185AC2D7DC8BFBEC +:10BA50006743FA25B848B85F2BBC259E8C7097F0D9 +:10BA6000957033E2E18F194CE8B71CFEBDCC7966C6 +:10BA7000DC77A3845C3FCE1CC3F3BD9A542FED4703 +:10BA80003FA7F3BFBACD28D78F71C4501CA9F1FED0 +:10BA9000C29C61314315586F9299F96CA087A2EF4F +:10BAA0008DECAEF799FDCB53701C6EDFED6DE6F6B5 +:10BAB0006BD8DDBEF07CAAEFB142BEF8E185CC03C5 +:10BAC000F58B93985BE1F559742C85C73115E3C468 +:10BAD00020C576C5D1BCDFE21ECCBF9CE393F082CB +:10BAE000661FB46F40BF1E532C6F1F954FED7D2610 +:10BAF000DEDE6386B44F1A8F53685DC9EDF2C5ABC5 +:10BB00007B6720FF9830566F675E9AC9ED2E323DF5 +:10BB10009DE92278A9267702DDA758914DFA911A5E +:10BB2000EEADD88776FADD3C4EA778D55D1387E079 +:10BB3000FC76C7B9717A6727ED19CAEBCFFCFE070F +:10BB4000F05DDB1E46DF1D59DA7599180FA0B86647 +:10BB5000EF830F736E3B624D8021B486C917D04EC0 +:10BB600038C9B7E777E89F9C344DA5FA93188FC37F +:10BB7000642B22280E73A2EF737302F43711940E14 +:10BB80002C6F097326DF03F32F16F6E102B15FD4A1 +:10BB900070A63DE7C079F5CE4885EF1359E7F1C9A6 +:10BBA000CB447CB23A56D9887EA63E05DC7E2FEB8C +:10BBB000633FD8EFEA4C6EAF9F24529907B852FD0D +:10BBC000796B6C2D69A8FFACB10432213D943D76B0 +:10BBD0000AAE73422A1BBF01E17EAFCA36D37C5B3B +:10BBE0008BC9AF1099E5423C6840D2E45FA94F7120 +:10BBF000A15DAC654C4300FD092DBF4871D7B90864 +:10BC0000CB140F24F5AD963181BE68C76FCDE37EAE +:10BC100089E3CEE648D417E73AECFCFEA4882B9AD9 +:10BC20002FEED1F4A96B7EF03AD4431F51C95F3394 +:10BC3000FF117E3FEC2F0EBB5F41BD6D3DDFA76C5A +:10BC4000AD3E8E8839DD64079A5B3FC68AFAE63CD2 +:10BC500087C78AEB5C9BA5556722DF16F711FB218E +:10BC600012A0CBE2FA628A5751A360DFE13E31BBFA +:10BC7000A2500F36C6215589B823995F13AEDD8BCC +:10BC8000709A13EDDA8DF472A2268DECA30704DD11 +:10BC90004DC0B84AF467989B13713EFDF03B8C3F52 +:10BCA00021D699E1207A0E630887168B3303E9BB0E +:10BCB00065659809FD72139673BA867D663743FBF6 +:10BCC000FBCC2C1CFD0C378A7E672D337B3741BEA5 +:10BCD000979D99236391AEF288AECDFDB449B8BE6D +:10BCE000D33F61C3901EE6AE5D47FE184917CCDC1A +:10BCF000342E0EC639BD35251FF9663B9FEE37B68B +:10BD00001EDBB5D3C33485E800D24369440F531E0C +:10BD1000217A181BE8BB3807F5D172E6C1F33D81E3 +:10BD2000B9514E6863ADE4AF6C73585D68FF92FC27 +:10BD300044F20D795F56D2C13638EFCD16C6B6D76C +:10BD4000DA297DB6D6C9CCE98CEDAC4DA0FCEE5A13 +:10BD500017A50DB559F4FDB95A37E5F7D60EA3FC72 +:10BD6000FE5A0FE50FD41651FA52AD97BE4BBE04E2 +:10BD700070213E24F98AE447731DD616F45F4ABE4B +:10BD800064A49BD900DED1F9D49EF89EE477B80E66 +:10BD9000537E901F49FCA62A5E5F420AF2B1E699E3 +:10BDA00088FF42F5FCAE17502F2F71B8494F679CA2 +:10BDB000EFB501BD225C92ADEC00DA65EBEEF1B4BB +:10BDC000AC4E09C2FFCE12859943E8EAAEEA30666E +:10BDD0000E3937EEAE89D1E567D5BCF76A0FE87F3B +:10BDE0004677ED0DC4DBF19F7EF6C41FE1FB533FA8 +:10BDF0003D9B8EF886796C7D0CC75D1ADE3E8F58B0 +:10BE0000CCAFB0909FAB8FB09FF411F613FC137AB8 +:10BE10009FF9A99FFE37EDF3961A9B0BE5E28F1170 +:10BE20005F00DF3F097CCDA9B1111C8B577EBAEBB7 +:10BE300005DCEF4BADC4EFE6AC10FBD1700FFA445C +:10BE40002223BB0448D514CF7EE227D64004F47FDA +:10BE500042E1FB5801E16016C61FAE79FD43E403E1 +:10BE60004ACD31F2BF6B786F0FE7E7B39CD7DDABFC +:10BE7000AE798DEAB1E65E31685F94F79223067B76 +:10BE8000AC2E583FD236E26F4ED66196887E967AB7 +:10BE9000C589A2DF3CF17DDE1A85FC9A18C7330DF7 +:10BEA000E4BFB64C95F0999B69A6F4018CC127F9C3 +:10BEB000AE9ECE2949B7F3D6423BDC1FF579D605B5 +:10BEC00021FC788EF83E37CB44A9FC6ECAE2FDF621 +:10BED0005C933703E58A9E589E8369FE0C846F4FFE +:10BEE000C778B3124207DF88F173C5F80FE0A68365 +:10BEF000FFDD9F956A9D9F43F701E91C93E3CCC941 +:10BF0000CA5F85F1A573D68E412ECCEA2CEE846EE5 +:10BF100068BFCB92FD88FBD8761E475DDEC539220F +:10BF2000ED6AA7F19FC369DD64F72DDDFDABDD7818 +:10BF3000BFA0F4131BE1B774A088DBCAF10F9D4AC0 +:10BF40000648BD3D7BDCAFFE1C457E8ABD3CBE1372 +:10BF5000526E675D5AC2EDB26ED85F9DF88B8EEE61 +:10BF6000FE24AA533BF65EF53BD9B1AB946FA250C9 +:10BF70008E90EB297CE58B789A877285FC4455AFCF +:10BF8000AC8CEF2CCECB68C76EB7770BBB5ED5D22F +:10BF9000A24EEDDD46FBDDF02C83FFC0CCE89E9980 +:10BFA000B4DF3135271AFD005F88FB275DE939D200 +:10BFB000FE5DB5013A8903BA34BBA2D1BF75A90BA6 +:10BFC000F97A59163FFF2F087BF9A59D2AE93D977D +:10BFD0007646D2BEAADCF9F06BE877ACDCA2D034AE +:10BFE0002A5813C10FE0CAECA1E71AC6B1C5759C67 +:10BFF000779B3F3D1ACF95B25F455623BD2D6A50C2 +:10C000003C5B613E6D765774F790F9DC85F406F47D +:10C0100053666B184AF016F39F9AC5F9A4ACB7A8FB +:10C02000F161B22F43BD8B2417FD3A82F1FB29AD9C +:10C03000BFC3799EDB38C88DFEC2450D7B2A49AE51 +:10C04000D819E144BBC25911B7DCDE8FA0EF4559C6 +:10C050005C8E3927FC47E776F37700709EB8CFCE29 +:10C060002ADC0EDD8E6FD1AE4AC02D368BEF3359F0 +:10C070007F51434B545FA87FEAC07B94DE2BD6B53B +:10C08000C8D13400CFE3537B23C8FF756AEF2FC7B5 +:10C09000BF0CE35D6818D30DF785EC7F759685EAD4 +:10C0A0005FD8A81621BC989FC7CD54207C0785CEA9 +:10C0B000336E932F2574FFF1F8A1737B9F8F32E5C8 +:10C0C00004F15961AFB6279A701FDDE345FA8E403F +:10C0D000E2817AD6BD937D78865535E631A46BDA58 +:10C0E0007F89547F8D29A49ECDE2A63853CB8162EF +:10C0F0000FBF6722EE458938FE423587FC8AB307B9 +:10C10000BAA6DF897CF24D0BE16371B66B3AF2A7F8 +:10C11000CB4D2AC3792E4E6101944F96DC1BB90991 +:10C12000CF3139EFD983383F285FA3300FACAFDC74 +:10C13000AF320DD29E807F1FD25342F3108C936C8E +:10C1400049E172858C1F7DBCC4E4B1C239B8272B8C +:10C1500056F059ED17F3D17F36258BF4B9E356E647 +:10C1600053D1AEF41C8F2F2D4FE571CD8F8B78F806 +:10C17000F2D840461CF4775EE0B77C4A2003E32EF9 +:10C18000CA9F4BA4B88BF356EEF7C4EFE8672DCFE8 +:10C1900087F60E7A674393ED6342E8A97C8EDB85D0 +:10C1A000F5D458B72BCF81F3755E2439775F2443DC +:10C1B00039D7F442248F9B7A266CB32D046FAF0AD3 +:10C1C000FA93EF77B03B789CD1A3161E97FAE8D686 +:10C1D00044BF3F045E8F5AB49908075C07CAF78BC7 +:10C1E000ACF51928FFCAF92E8AAAA7799E17F4BEC2 +:10C1F00028BC9EC7738BFBC0581FF32D220EBD7544 +:10C20000878DE280CE2636EDC7F1CFEEC866B8FE48 +:10C210009614FF8203540EF225E0B3F4595B00D765 +:10C22000736607B7479FB17079EDCCE40417E2B7A6 +:10C2300068CA86D964AFD96253D0CE774661D60436 +:10C240002CDFDA9DE2CF4B6B6B287EBB14D806DE69 +:10C250001F82B408EF019DD99A4DF16667F0DD06A3 +:10C2600085BEAFC1EF1AAB9FFD2384C776AE5F9D3D +:10C270007DF66FD9A1F1DE322DDDA28FAF9374224E +:10C28000CB3FCBE2FAD067595C9F3B9BC5ED1115C4 +:10C29000110D8FA6D23A39DC014FFC1D1BD61CF9BB +:10C2A000CBC1184F91AE201F799C05327E897687CD +:10C2B000ED5CFF3ABBD34271EBA52F447A288E6D1B +:10C2C000F575268AA750B99C5E6A02F041AAFC74F3 +:10C2D0003BC597757B362CDF46F239233DB775ABEE +:10C2E0002AC6015D10D7BD8DC71D4F405992CA7334 +:10C2F000A9FC8CC89FD99F4B721FF4EFC1FB55A5B9 +:10C300003FFA3187E3D492B7B8DC65277E5BDEEE77 +:10C31000E719198DE760C5EA11D1785F91BDA332A5 +:10C32000945B8C70BA6C76F7403E3B3C5BF0DDFD75 +:10C330004F907FAA4CDC23287B56E17E68D8877813 +:10C340009FB36CD588C7883E7F6761E9B09EF30DC7 +:10C350000F4785E2232D9BF3C5F6FA5637D52F8379 +:10C36000FAD84FD9AA37A3683EDB2C14AF62C4E3D6 +:10C37000776EFFACFA9DDAB7D34703B7B374583F73 +:10C380006BFAC127D0FF5F7786B97DF4B581EEC126 +:10C390009DB3342CC0F59FDB15467CEB5C0CE70F9E +:10C3A000A7809FFA32711EB7FC8CE2BBDE9D4AF774 +:10C3B000F716FAF5FDCA71B3B22D3CFE2ACE1D8DDB +:10C3C000F18215EF703E0878B995DABF63A1F6C621 +:10C3D00075D8B239FF6FDF9FBB22881ECEF5E47897 +:10C3E00039B73B93CEA796184EE730DF64BCEF77A2 +:10C3F0006E57661EDDA343A107E8A154E8BFE762BC +:10C400001A929D21E52D16A1C705A026D20DB601D1 +:10C41000FE5E5AC3E5AD32FB5A8A2FC178DDA1F921 +:10C4200094066CB11DE36E815E49BFACCDE6E7209A +:10C43000C3F1E2459C38C9410D56E4DB9A9017CB15 +:10C44000771AE37679F96CD91EAF64C83861A443D2 +:10C450009F42712A652BEE5944F1F7D5EBEEC47D6E +:10C4600026E75F666645A8A7B5282ACDA3258CDDFB +:10C470003D05E5CAD07142E4B945D9EDF656E68CE2 +:10C4800027399684FE8A6C17A71B3C41F19EE20A6D +:10C49000652D8D9322F55DBE2E0927008715E304D7 +:10C4A0005BC688F22ED62DE7695C77BBDC95CDF9AB +:10C4B000514B8AEB672311CF6FAB74FFF7F23783D1 +:10C4C000A2633B91D382E7BC35182F0BF37F289BE7 +:10C4D000D1FCA7647339BD0CE371619E191BF5F1A2 +:10C4E000E2595BF4F97E3BF5F99CBDFAFC80467D90 +:10C4F000DE7D549FFF018E3B84EBE178DF18F57001 +:10C500004C510F77D9B81E8E79D4C331453D1CBF2D +:10C51000A31E8E79D4C3318F7A38E625BC511FC74C +:10C520003CEAE358FE9B6C7E3E968B784BC403D26C +:10C530003B7B314C771FE9D22BFC7E09D001DF37E2 +:10C5400033ADB46F1EC71AA48F70BB53CFA9761733 +:10C55000C60FAF8AD3766477C77B284DAB12116FB5 +:10C56000E6668A63AD7A89C7B196E78739D0FED18E +:10C57000BCF2D42A0C0FBD234EDB8DF52F595AB7D0 +:10C58000217C2B6A8ED07DFDE665AE776EE0F823C8 +:10C590003B0C2B892539AA18CFB9D8AEF1688C2766 +:10C5A000676BF5F1E3C67872631CB9910EA4FCF7D2 +:10C5B00094A53511F9FAA73BEC6B71FE9F8689FBB8 +:10C5C0003033EC86780007F193C50F2A9BF1BC7ECF +:10C5D000279BDFCB6E3B06F27A27E7AC4CE75E1970 +:10C5E0004472797B7EAD62A2F874CD43E7D01231FC +:10C5F000A764A5B56535F2B945263A372F83BC4601 +:10C60000F2E0FB2AC90FF8AE56E87AF05DAD50FAB9 +:10C61000C277B5F4F7257AEAEAE3BB5AFAFB12FDD2 +:10C62000F4F1F9D3961D42BD7FEADA41BA7AF3BC40 +:10C63000230C7014F316F2EC3C383F3C285F2EDDDF +:10C64000908CF85DB2A8AD6535E077C9BE303796FD +:10C6500097E0FF015F2C813EF1DE65C95E717FB915 +:10C66000467F0ECF15E7508999F99CB1413A2C715C +:10C67000324F0CB45FD4AF6900BE9FB5E88DF7862A +:10C680003A5351CF18D303F951B2C54371B5E57B85 +:10C69000D2639641BFCD7DB56F91EE4ED61F7968BE +:10C6A000169E877BB8FEF7E9DAE7A328BE4CD05B7D +:10C6B000B2C5198E78DF54CFE3EBD07EA6C606E96B +:10C6C00062537D5C785F4770BD413AF886F004F8AC +:10C6D000E1769E92C3E417696B10EB1DA3F850CE70 +:10C6E00096EB93EF6EB115BC9FEF89FC49A16FC823 +:10C6F000759ECF3E34C085F73A6A0F24ABC8CF4D44 +:10C700003BB7A11E72C5A625F61B82F1A0E97FC426 +:10C7100077D84A3FE0EBF9CBFA82A8E1287FEEB266 +:10C72000B827407E75FDD356D42B4ACD7E2BC567E6 +:10C73000EED864C578E51BB76FA2EF0BB617533C74 +:10C74000E642564DFAE869F94E828047C95865A31A +:10C7500013E65DDB8FF38F9270EEDF03F9E8557C13 +:10C76000A7E4F276250FE37CA679F7588BE17BBE30 +:10C77000A867DC276D6F4D2DEC4EF0E0F7403E6072 +:10C78000A0DDA775DC1753AFA4D0BE9876A53FE90E +:10C7900069B705B2B93E9C63D087DF52B93DAF910E +:10C7A000EF83126BA0DB54DC27072D24E75698F9A2 +:10C7B0003B4F15F0EFEB21F58E5475F45A352E42B0 +:10C7C00047CF3358ACEE3ECDED185412929F362130 +:10C7D0004D577FFAB4FE06FACF0F96131FB95E7756 +:10C7E000EFAF62A9CFA5909C3956FF9DF1F842C6E4 +:10C7F0006ED6B5AF605382F590BEB7285CEFD91BFB +:10C80000B319ED802526AE3FCDD0F8F7CA03FC3B27 +:10C810009BC174FBB04F9AFB8FFC5CB490DF40DA95 +:10C82000DB67E0BF3B813F63E1EDF7D8F11E3FDA04 +:10C830002774F7BB85BF10E78D78A810F6A48A2C63 +:10C840006E4FAAF03559F19D0480BF392E96EAD972 +:10C85000E330AEB25E217B23A64B29CE521FA785C3 +:10C86000FD61FC63E531B518F789B1BC04DF2942ED +:10C87000FCBEC4E3522BD12E14D5F17DB44AB413BF +:10C88000A17DCBF01EDAA17E2E211FF957F5443889 +:10C890004E50F2E8DEE6CE43568CCF9B362D260F67 +:10C8A000F78F91CE247F877D4D71856D6F1D213A65 +:10C8B0006B2B31131D5F0D1E951E6E6735D2DF0287 +:10C8C000D664C5FB290BF62A6ED44BB11EC2A52730 +:10C8D000D2A5012E71B11DE121E1D40E3743F942F9 +:10C8E000C6E1B5F080E247FED8014E027EC6F97778 +:10C8F000053FB9AE059A361EF9845CDF425C078EAF +:10C9000003EBC071A4DF820D33EED734B25F557AEA +:10C91000799CAD913EA65CE17699DBAF98299D3676 +:10C9200041BF3FB11DEE93DBAEC453F9B5D24F25E5 +:10C93000CC13CF856BA51BB91EC98F83FB84DF4B3E +:10C94000B8DA3B4746FBE4DBFD847D72081BA28B13 +:10C950006F16FCD6D8DE18DF2CE503E3B9531C694B +:10C96000A278CB36472AC91D92FF6AE25CD1567E77 +:10C9700041F534A8C767E3D19D439AB0132E8E4C7E +:10C98000A577249297C5C523BE8AC39C14D75FBCE4 +:10C990004CA538EA62A8E70A915B56AD484BC673CE +:10C9A000E4C47D994FFA409E3F716FB7F86130CE75 +:10C9B000A72B2DDDECAE60BD132B0B9331BEE3D363 +:10C9C00075B619FE4EE0F59538372A7EFA219D732B +:10C9D000174C6F45CD80F6E52BF745E1F581B29513 +:10C9E000FC7C5FDE57FBB21FF97D376D7322FC9C28 +:10C9F0009B06A09DD8C261DA2E5794AE2CEC8172B2 +:10CA000047F9B7479E74E2BDF0659678944BCFBC6A +:10CA10000FE7A442E71CC913A7C3A00BF2C345D27A +:10CA2000FB67A715E6417FD479D3A12F57A3BE9802 +:10CA3000D7901180F47ABB66E98F7AC1CAA7499E64 +:10CA400029BD7F5906BE43A82D4B8FEECC9E22D325 +:10CA50006DE23C47B91E5394EB31BE06E57ACCA398 +:10CA60005C8F29CAF5F8BD6A835E2E8C127E4A69F6 +:10CA700077EE53D79A877E3FDF5896554DE7B083C0 +:10CA8000DE055EA284BB913F2D41190AF37F8E2003 +:10CA9000BB037BFF261D9EE5BBC1F25DE051AD20CF +:10CAA000AB85EC931BAED859E83DDD312C46972F72 +:10CAB000B027EAEA173A5374E5372664EBCA6F7277 +:10CAC000E5E9F2B7640DD7D59FE81EA3CBDF3AECBA +:10CAD000265DFDC99EC9BAFCD4A299BAFAB7798B72 +:10CAE00075E5D3672CD295CFD4EED1E5EF2CB957AD +:10CAF00057FFAEEA65BA72F94E7223EA63367CFFDD +:10CB0000C54EA97C2FF9872AA3F7D8461698B89D59 +:10CB1000D1C6CFA3256FA73B42E9E0D6FE5C2FDD4F +:10CB200095E3B9B9FF90E07B98F29DCBBBFA73BC5B +:10CB300026B180C2F5E1A644A463633D63F9C888C9 +:10CB4000C3975D80CBD7FA1FB9CD8CEF475E77785E +:10CB5000501AE4A372C26EA7FC88C3CFA7423E7EE0 +:10CB6000E7AD3C3FF0F0652CF7E744F1FC5446A2FA +:10CB700049EACEDDB7613CCAC81B52D7BAB91DA578 +:10CB8000D3FBEE324578E03D718407A601A0634CEB +:10CB90000F031D637A14E8789E05E605748CE9316D +:10CBA000D04FF1FB6F413FC5F42DD04F31FD1DE853 +:10CBB000A59836815E8AE9BBB533287DBF56A3763A +:10CBC0007FA82DA1F4C3DA6AFAFE716D0DA57FAAC4 +:10CBD000F5D1F77BFB4BFB4340F7DE6857EF8A4A02 +:10CBE0003FA7F46BD655B3E608E41BCDE698CFEC2F +:10CBF000417F65D7760233FB2C445ECB553C2BFA44 +:10CC0000D3F8BD9C749F427C77A468F7217FF820FD +:10CC1000656AFA2015CFB1EA5731D4E60353E7EF3E +:10CC200047DE25E8C397E37908DB8DB2F3FBC9A3A0 +:10CC3000ECFCFEF12873531DD257DDD7CC85F13FB4 +:10CC40008722F9BB1F75F799FD680755AEF07D3E49 +:10CC5000BA1BA37CDDD7CD745F7994D39D80E79513 +:10CC6000CCB7FBFDF14F489C8FF4C3CBF89E7157B6 +:10CC70009A0A505E18EDB0BA908F84C60DA0BFFD21 +:10CC800050E467723E0CC793FEFD2D5FB380694090 +:10CC9000D08F3FCADE94827683D1DFB3BB43E39665 +:10CCA000A4BF5EB9D2ACA25D55C627C971E47C238E +:10CCB000CDD05F7E30FE6894B3210FFD1D75150E3B +:10CCC000EAAF077CB7E6533D8F4AED1AF2D02E3714 +:10CCD000BADC4171B0324EA0875837D4A3758EBBF1 +:10CCE000A2519CC468112781FDD879B90FFB19DDC9 +:10CCF0002D90887160A3ABF93B644F28D03E3F185C +:10CD0000B780F52342F62DCE13FBEDFBDF305F94A9 +:10CD1000A33C1E82EF54A9D7B9445EFA1DED63C946 +:10CD2000BE552078CDF214ED1DA423AFCDF9E70850 +:10CD3000DADF69BDD16E3A59C8F5FF845EDEFFF7D0 +:10CD4000D08B87E3BB17237B9B916E245E249EBB15 +:10CD5000A22389F7903833C2737BDC98E8C7485F19 +:10CD60005DD195A4A751768E77C42BC6A9493A52B6 +:10CD7000AEF077DD4697DBE9BC937464A4838E74D0 +:10CD8000C4E9B2EEFB76EAAF231D05F18FF0F8D7C8 +:10CD9000E9A85945FFD5B5D2CFDDAD6C7C3414156B +:10CDA000A46A77215D145F71BD86F9B96CCC7824D3 +:10CDB00029593EA18B72EDAFAD96E8103A1B25E8DC +:10CDC0006C4917F5653DF9EE85ECFF61ACDFBD639D +:10CDD000FD3785DCF066988C53F138F28606E34621 +:10CDE000971472FA2A4A5149EE28C8E1EF9F330797 +:10CDF00097B35DF017F9F1CD4C3B1A9D82EF947A11 +:10CE0000E97DD2F1DD0CEF930AF9BCC8E0E7BF3948 +:10CE1000E74692CF6FBECA3BD7C373C43DB71496E3 +:10CE2000728DEF907A72483FFCAEEF90F2F76BC7CD +:10CE300089FD9E24E829CDA5B291B1F89EBB66C6B6 +:10CE4000C3E528BE5F3B00DF79F551FE26E6A7F477 +:10CE50001616203962221C4498BF154458CC1F89ED +:10CE600098340BEF1C160C2AE88BDF43DED9BB0D80 +:10CE7000E757A96AFFE50C7967EFF03817DD5F3DEA +:10CE80006C4F233914F7AB25C45EFA069CCF7D6145 +:10CE90007D47E0FCC6F45538BFFBC239FA3A9CDF47 +:10CEA00098BF396B19C376E35DFAB827D9FE1667C8 +:10CEB00001286A5DC3EF96012FF642F8BE19933937 +:10CEC0000EE9E2CD98EBC6E17ADF8CE961E2A9CD0B +:10CED0004A69EE0B7D3B9393E57E088E379EC63301 +:10CEE000C257C2D3084709DF7F019EB539433AC212 +:10CEF000F32ED423D07E6B7F2F2A2115FD9B9CCF50 +:10CF00005644248BF748DF1EA0A662BCEF089AE7C0 +:10CF1000E89AE1CC8CFE763B87D3A95AE643F89E8B +:10CF2000C125A0C1DB60DF63E6B1A6D038E83D369D +:10CF30006D1DE2F5D44695EEEB5F782E8CEC76A76E +:10CF4000FDDC2E5969D21EC5F272D5B5D68DF2E63A +:10CF50009B2A7F47F49B23C95322AF815EB7F077AA +:10CF60000ECAEDE33BC5A7D42F67A57AEEE2F20D1A +:10CF7000D3FD1E452F1B7F0F42BE4BD995BC3534C8 +:10CF80009CF3BD5E36CEAF257E375A851C00FD0C66 +:10CF9000053E9BF4B370D2B71E8CF7EC463C801E66 +:10CFA00043EF4FB5F58AA4F3E9B0888B1B1DE84F1A +:10CFB000EFAD1589DF1D785DBCE77E58C4CB3564C5 +:10CFC000682F62FBD75D877BA1FDE106C6FD403778 +:10CFD00039F8FBF9D7AA9F1FCA11FAF90036E09A6F +:10CFE0007E27A1BB4AF72946B30CF2C317E07C9118 +:10CFF000CFBD31D78CE764C8EF24D0BAFEAFFD4E69 +:10D000000263AD2AAE2BC9A9B0C753AEFD77135446 +:10D01000A157C9DF4F28E2451D7E37E19751453CB6 +:10D020002EDFB1A0D3DF4D4812EF5A33173F37E45C +:10D03000EF261426E8CF9102E798A34E4AF5769E94 +:10D04000A4ABC48F29B9E2FCB856FC5730C27F7B31 +:10D050009C69371EFF345AEBF733B4CF1774B3B85B +:10D06000FDAE8E74F09FF6BB285DE1C9F87B2946C2 +:10D070003C197F3F25492D37D33B90024F33E02F9A +:10D08000E2E906F1FB16E3F0F72DD8BF0F6FC30CF2 +:10D0900078FB82AD1D82EF965E2AE67CBDAB73FF06 +:10D0A0004B9767742EF0BD9B05DF97F61119976BB0 +:10D0B000FCFD24690790F1BABEB11CDFBEE311E4A8 +:10D0C000BFFAA1DA1C89E7CC7113FFBDA4C4EEDA64 +:10D0D00004ECFFEE9C6A05E191C0BC7B16C0FC67C6 +:10D0E000FFC6968CF9D97DF87B912C87FF5E909CCA +:10D0F000DFEC241ECF352D57E8BB6E1EBF353D97A4 +:10D10000EB01916E27C59917E730113FCB9267E786 +:10D11000227DBE159689F4B79EDB039BF1BDCA6ED6 +:10D12000C1F72A514E47B9B8B7904BEB3EB2DB3945 +:10D130001D32DDF99FEDB7EBE29CFB6F77EAF2B9A8 +:10D140000D09BAFA030FB874E579812C5DF9A06373 +:10D150006E5D7E48D3305DFDEB3EF4E8F2C39B8B01 +:10D1600074F5479CF6EAF249ACF51708DF8772536D +:10D17000091E7D14612771717CCCFE613CDD5792E4 +:10D18000FA878C7BD7043D1BF59A3E562ED7D725C0 +:10D1900032AEB7DA857ECAF4FA8D26E2D6A55CCF28 +:10D1A0007CFAB87519AFDEAE07093D47EA1321F1E5 +:10D1B000EA1E9CBF8C576FC7BB783FD448AFBF14E3 +:10D1C0007837AEA38F95DFAFABBBD74AF784E4FCCB +:10D1D0008CF33A20E298B7DA3B7F0F6A472E971319 +:10D1E000BE4EF36ECA857A4F02BB22787618CFDD29 +:10D1F0008CBF3F50F713AB7BB9EBEAE3CD1EC8D72A +:10D20000330BDFCDCDA1F757E95EA01CF74541DF19 +:10D210009B060A39C530DEEC681E1FC7A2AD74AF8D +:10D22000A5EBF1385C13AC6C05BD5B25EE79DCB584 +:10D23000B6E1412C9A65ADB7F08707FC16B4A34D53 +:10D24000180B72621EE886CF2C7AC40172D1933516 +:10D2500066B28B05769DB8DDD737786FA70FE86982 +:10D2600048271310FFD0EFD0813C8EBC2597AFAF7D +:10D2700050FDA6FDBE854DC7FF19F1FF4EE88EE8B3 +:10D2800051AEE37FEBFE85A45F239CA45ECEC4B9C0 +:10D29000D657CC4BC24FEE0B093F79FFC5758FC5F2 +:10D2A000BBD941F7688A302E4FE2EFA681DC6E1FB2 +:10D2B00087B260775E0FF95157F50AD59C68F4176D +:10D2C000B43157B4F32A76F3FFA57B2904FFAEEE01 +:10D2D000D375C5273AF0872EEED775459FF4E71A28 +:10D2E000EED985F0091E2F25F0E1EF6BA2B884D5A9 +:10D2F00091FA7D5C3080F38753621FC3F9EDC8D388 +:10D30000F30986FE8FBA95AAE0130BDA7F6F04BF8C +:10D31000CF5F6921B99B31EFA318A7F197F5167A72 +:10D32000E771B487917C3367A3E2DFA4047FE7ABA6 +:10D33000D86778A745FD86E4C32FD62A4EFCBD8862 +:10D34000B96BF4E50B1DFC774AE61BDFAB91FEB829 +:10D35000ABE8F5830788F3DDCDDC249789388A12A2 +:10D3600051C72897B5F9B9BF11F57295DBB128FE01 +:10D370004E9EFB2EF47785BCC302700DCFC2737C2A +:10D3800085B9D3B8C876B87611F771DE21E23E1CB4 +:10D390003CCEA56D6F18F70F4B3F9CA87FDE7799A9 +:10D3A000CAB13EF676218FC7AF48FF9BD1BFD7E603 +:10D3B00030917FAA6D6F24C539A0DF2B1AE8E1AC4C +:10D3C000694FFCB094E0FCB46655E73732A6DAB298 +:10D3D0007DA44F2EEFABCD1E8071FA66B7DD0DF93F +:10D3E000FB1C87E91DAF09C20E669C6FFBEFFE8D2B +:10D3F000E4EFEAB4F9B8BCDB56C4DF3B01FEC87009 +:10D400003FC9788EC90CA43B488B03C3693ED7EA59 +:10D41000FF9A7A258FFB7FAF8CA0F6DA9AE194EF22 +:10D42000B3E2C17BF09ED16D750B2D180AD0FC8B39 +:10D43000A585E1D0B4B9B77F7938E26D8CD2A9FF68 +:10D44000A276003F5F9A0DF716647A49EC1BC7403D +:10D4500026F89388E75AA6D07E58AC3019DF45FCF1 +:10D460005CE62FD78B7C21CF2F59C9F3CDE27715FE +:10D47000B6097B0BAE1B535C37DA05760A7B0CAE24 +:10D480001B535C377E47FE8579E45F9847FE8579BC +:10D49000E45F9822FFC2EF739837394FE57EBB7186 +:10D4A00021FB03FD76E342E423F4DB85E6D16F172D +:10D4B0005A1FFD76A1E5E8B70B2D47BF5D681EFD3D +:10D4C00076A1F5D16F179A67C36E0AE691DF7926C8 +:10D4D000EBF25341FE1F17B2BFD16F17DA3FFAEDDF +:10D4E00074FD69F7E8DADFC96A74EDD16F175AFF86 +:10D4F000EE1A45E7D7BB5BBC433B77431CD14F7962 +:10D500008AB711E9FEBF22BEFDBE05F545B5711112 +:10D51000D7DBC2DD1CCFF5451CEF267ECF42699DCF +:10D5200049785E6AE5F9421EE76DA41FF48B8DB35E +:10D5300070BF18A6E817C314FD6298A25F6C5C3A2E +:10D54000F78B618A7E31FC8E7E314CD12F8629FA91 +:10D55000C53045BF18A6E817C314FD62D80EFD629A +:10D5600098A25F0CBFA35F0C53F48BE1F7E3E89F35 +:10D57000B304E785F27C5F9D5E0974A8D32B9DBA46 +:10D580003CCAF3A1F5519E0F2D47793EB41CE5F935 +:10D59000D03CCAF3A1F5519E0FCDFF2DD745FB0C12 +:10D5A000E5FAD07628D787E673EB7DAFA2ED6CE283 +:10D5B000C68B47316D8E549E548065FC7DF78FA6D7 +:10D5C000A3FFB2394C498E01CE69517CD3C7415E6D +:10D5D0001371940358AB897EAF0F95478C73083055 +:10D5E0008A5BCDFD3A91CAA3329DED71CB88F7BC21 +:10D5F000BD8C7E8F46FAD7657B3773AA98CAFAC16D +:10D600007CE7F58CE3CB7AC43F43E68137AD31DE6E +:10D61000276FA9231FE366B789DFCBDDB69CC75B05 +:10D620001BE92A4FC84BDB4C7B0EE37D9AD6628503 +:10D63000EE5D6798D9314B3EC2A93A1FE588C48197 +:10D6400031625DD5D7E3EF8EC9794B3B28F009BA3B +:10D650009F38B2B5A9201AFAD17C63E8F771265831 +:10D66000B9FC80ED50AFECEF533C9B43E83B4DC819 +:10D67000E39A8F8FFFCC539378BB70DEEE99A7A20D +:10D68000088E9356281477367227F3E03DE81C3154 +:10D69000EFFE3B032A8E57BC828F27FB2DDE984C72 +:10D6A000F7428B59F338BCD7C2062B0CF9B6841B52 +:10D6B000ACEF28AE2F03B60ADAB1BFEB7DAA5183D7 +:10D6C000630A311E9135327A5774E2E0DFEBD64BB4 +:10D6D000681F4AFDD2B996E953E81DE749BE65CBFC +:10D6E000F1589FE8BBE7D5EE587F0B73A7B8E82841 +:10D6F000A2FBC7723EFD3C7B4C702CB21CD6640A68 +:10D700005310DFEC485C08FDC0CE9F86F8CE735BFB +:10D71000E85DE5C966A785DEE9E8225EE7B243C6B3 +:10D72000EB18E405435C4EDDD20F93D1DEBC38D25A +:10D73000447693C5FB22486ED03628C4D7A41C5427 +:10D740002CE2FD2EAF78B5FB7484FB1E0BF527E3AE +:10D75000752AD2FCC926BC9FD073D3805895E4802B +:10D76000BB07A21CE07BFEF661586F257F57F4F2E1 +:10D770008A7DFC7749857F47FECEE93C11FF559CA9 +:10D78000EB8DC67818F97B6AF29E8CFC1D5369E715 +:10D79000297E7BD06B88DFE227C4BBDF6B8AE9FE82 +:10D7A000BB31EEAA4CC87F8B5658286E6B91413E18 +:10D7B0002C13715957FB7DD39A8106F950FE4E8E7A +:10D7C000A8C3D45E7F40BBB0BCF739CBC2F9C0ACB4 +:10D7D0003D8CFC55B3961598F0BD6AB68FD3CFAC8F +:10D7E000655CCE99F5A287EE6F4AB9F11D21CF4C49 +:10D7F000B99244F07F4FC82FB761BC2AC0794273F9 +:10D800009888634BA474FA151EBF3AC5C1F941F359 +:10D810002BFCDD8D369F8DCB5547197F37CE409F32 +:10D8200093CD7E135E68748F04FA84FC449487A0C1 +:10D83000BF19281FC521BDA714523C649142F78827 +:10D840008CF43EC152FD2AC6DB4ED8CADC3E164AD5 +:10D85000EF40C7D89F4FA1F71834A1E74A3A36D214 +:10D86000FDEC08619F7270FB53BB9D0265557A44C5 +:10D87000FD83E9184F3C1B6D863D69191E8CDB8BBF +:10D88000CCE1E5CF0DFC60FA0ABCFBD185DD42FDA1 +:10D890009195E0A1C97727BAB023A0FD00F9E55D15 +:10D8A000DFCBB3CE09E197CBF3C6BEEBEE1EC4F7D8 +:10D8B0001CC37DCAC5F7A5D3EF1F752517CF05B8C3 +:10D8C000E2FE981DDDFC7DA054F6FB81CC332E01D9 +:10D8D0007F5F52AE8F05301EF30E91FFF6D77FFFAC +:10D8E000E31A07C185F26F0FFC743ABE3B57616FB4 +:10D8F0001E8F645795535D84F1D9413EA5799252AC +:10D90000904FE505F0F7F80EC87BE006FBC4B703BF +:10D910005DDCFF62B053CCCDE1FC9B89F7C64FDCE8 +:10D92000F7C26E3CB7E4FC4F58F4F76A65FAE5407D +:10D93000D3BFF55E89F13EC94F93B453C83F1E353E +:10D94000F1F7137AAAF54CD88BC8AF2CF90613EF70 +:10D950008E04F1EEB1F2B804C5196AAFD2D628FC34 +:10D96000BD822EEC3A2CABF5175BA1DDEC5A2BFDFA +:10D970009EE353199C7E9E02FA41F96C96B5E955D7 +:10D980007B4A108E9FD4FCDCC2F958201DDF3BBAC5 +:10D99000A33ACC8D7C79799EF7EF38EF881C37F16C +:10D9A000A377DD9CBEAEEBEE656EBCCFB8F6D09330 +:10D9B000F87EC3FF037EDA89FC00800000000000CF +:10D9C0001F8B080000000000000BED7D0B7454D588 +:10D9D000D5F0B973672693CC244C42200F489800A9 +:10D9E000911401270981800837C82358C081100588 +:10D9F0004DC28467B46023D51A2D2D03493020DA37 +:10DA000080C120F53150A5685163B56DA8D80EE2EC +:10DA1000BB682948F5FBDB86E18D8FD608B5DAFFB8 +:10DA2000E7ABDFDEFB9C93B9F7662680DAF5757508 +:10DA3000FDE3721DCE3DE79EC73EFBBDF7B9F9F68B +:10DA40009E1CBB7F1863D5EDF96BD33D8CADC9F738 +:10DA5000DBBC7DA0EE72DB7D2EC66E6948B67BA076 +:10DA6000AC4A63B56DD08FB1CEECD9898C7D81BFC6 +:10DA7000098C657915C6A0FF1FF2A1A988B18F6D29 +:10DA80006C2EEFD76C9B65E867A17EACB95573F43B +:10DA900065CCCFF82FCBCA029602C606D8FD4C4BF8 +:10DAA00065AC3E8379D7E430D60F9EC715F0F6F803 +:10DAB00014E8EFB21F5592E085C0642D9CC7DFFDCE +:10DAC00062206376C6340BB4F783D20EFDDB877811 +:10DAD000689E2C6857E1B92DEFD83C06FD2AEC6C06 +:10DAE0003EEE47AE479633C5FAD95C8785C1BA1674 +:10DAF0003BE0DF30C46475D894B4918CADD8A8B83D +:10DB0000E3E0D12297E7FA31505FF4BA8DAD81FAA4 +:10DB1000F4148F3D03EA9DEB14F776A82FB82DDFA0 +:10DB2000EE817D57C03619AC63D19631CCD31BCA78 +:10DB3000209485DDE795E58D1BF765ED86F958485E +:10DB4000B3FB005E8BDC9A3D6558A47D61B3A205F2 +:10DB50005DDDEBE3BD2AADBB82B14908BFCADB7214 +:10DB6000EC0B5C587FDDB66218EE8BC341BE07FD3F +:10DB700042D86FFA40F62AC375C3BEB6E7F0F90A79 +:10DB800074E32FC0F175F343FFF93EA8977A136948 +:10DB9000BC6A37EC3B074B37AD13E04070EABC176B +:10DBA000C6F3D03C741E0B43419B17D7638579A104 +:10DBB0007E833B68C3791634E4DB1994FE0D7C1E2A +:10DBC0007F53B27D38D4ABAD6E7B16C22F0160910E +:10DBD0004AEB0B6E87A35904704971E13C6CFE6CF3 +:10DBE0005777F8548BF52E6A4EB62F363CDF68C354 +:10DBF000F39807EB698B72EE77E1B917E17A4AEC9B +:10DC00000CDFB76A762FAE47C0F7E4ADF1EB592FC2 +:10DC100078BFA5D59603F59B05FEDE85702D42B82D +:10DC2000847215DCF7ADF15E5CE73C7733EDAF0B4A +:10DC3000BE9B011EF07CB1DB47F005BC083080C301 +:10DC4000A216E37946D69348E32E6AA9267A5B6248 +:10DC5000F5DBDDFA756CD99BAB005CE6D5C67B15B0 +:10DC6000803F73FBB3115F4E6DBE3E9BF609EB44E4 +:10DC7000B8267A3D53D247129E101E4B7CA92AE447 +:10DC8000F42BE7DBE4B5D27C9B705F453DD1A5F674 +:10DC90006A3AD2259CEF1A4F6CBAB433180FE6B526 +:10DCA0002F5282F54A773A95F429E952D2A9A4DF96 +:10DCB000476CBE50BA12E13355BD58EDCFA2C0E952 +:10DCC000A038871BC4B9025C5F46B8CAF617043D8A +:10DCD000570C34D23B8E87E3FE449C7BC5C450EE88 +:10DCE000ADC322FDE5BC1529FC3DC47BC4B79F082C +:10DCF000F860FF15D4DF62E0170BBBF8C5AEC6BEF7 +:10DD0000C82F9E55BCC82F56DCBB2FEB0E80DB8A7C +:10DD1000A79C5E84C187CB1EBF2503E0C0AC413AFF +:10DD200037B9AEC59FE7139F58F2F9959C5F84A25F +:10DD3000F30B579EBFDD5B14A92FBAFFA9CBFC9C48 +:10DD4000DF8490DFFCE9A9170E8F453EC28236DFE3 +:10DD5000F0C87E1634FDDE56EDD2C38FEF777DDE40 +:10DD6000D96A3CAF852EBB4785470B1BAA89FFB2FA +:10DD700074E6CD5522E76FC68BEA0645A3F7EA465F +:10DD800005D5AF914F2FDC300BDE8D9C1B4CCCD8D2 +:10DD900028D827E3F095EBFFA3587F87E06F37087B +:10DDA000FCBEA1A6C49E918AFBAD2E04CEC8E68916 +:10DDB000E7F316199F779D9BBB8BCFAF457A39DB75 +:10DDC000C6CFEDEC061BF19FB3BB12830CF6F7E157 +:10DDD0008A5FBE7D1DF4FBE0816DD94C359E1B2B07 +:10DDE000E4E786E5523837D63BEAB97DECD5F1E178 +:10DDF000A58FF2735BF8F45B7FFE9587F6CBF9DDB8 +:10DE0000BD7141E4C70BDA9EA5739CD7B4D196834C +:10DE1000F4EACD21FCEBE2FFB5F96E06F0BDA16995 +:10DE20009B0DF9C417120E267A8052633A3A43B911 +:10DE3000A4A420FE853310FF647FE48FCFC23CB7DB +:10DE4000DD1A9FC4AE88CC9397CFF17E616D720AC4 +:10DE5000CEB7B0B6FA3E3622220FCCFB3C1ECFE93D +:10DE600065018C87747BBCC49BBD82F0D31255EED8 +:10DE70000EC8E7E7F82300773CE0433F67DB130871 +:10DE8000877EDF4EF022FF183C381CC47911BF7129 +:10DE9000DD76E09F0EE8377859F8135CC760C03034 +:10DEA0007C0FCBC4142A595FA86F8765174339507C +:10DEB000E5E5E47CBE7F680F613B4B0D17E1FE2575 +:10DEC0007E9BF1D7CE1E6B1A887C2C9579EB3D1189 +:10DED0007C95E3487C95F81C6B7F575DE4FE8EE7EC +:10DEE0007078DA13607F2997B03F40D6E294C8BEBD +:10DEF000E4FA581EAC0BE6A9FADEF06DEB619EE386 +:10DF0000ABBDD9B5AE9EF6DB32B96F94FD9AF72959 +:10DF1000E9669183D334D04DAF30ACFB6CF3A05E97 +:10DF200028778E2B20DFE0BDE3B7C65B70FD725F04 +:10DF30003B56416758EBCE550E2A9F5C05843784CB +:10DF4000B15DABD2A9FEF42A0F956DABF2E87975FD +:10DF50007E0A97472C9C887A26E8039C1F84389D6C +:10DF600074D40DA27DC9E7522FE87087135374FC57 +:10DF7000FB44AD909B2C7C2FD237AB1BC41E87A9D2 +:10DF80003A9A8F275A86217EF2F5C9F76EB3751239 +:10DF90003F648976CFE34072CEDB7E3F390DE65B8E +:10DFA000DC9293AFC07B9575851D75D05ED990E6E8 +:10DFB00045BEB1D8E5598B72717120C78B72D1D92A +:10DFC000927F6A0BB42F6EB8DC8BFD6F53980FE90C +:10DFD0000BF82743B82D615D3FCD017C6DA9E06B47 +:10DFE0004B915F02BC96D4ED1BEC86F79778E3F378 +:10DFF00051BE2FDDA284E290DE2CAC4941395CEFAA +:10E000009B827CACF341C58BFA267B08F8AB23C21C +:10E010005F37E4F956E6E3F99F07FC83F187A20C2A +:10E0200056715F6D1AEE83813EF238C375FB48AFBF +:10E03000FF7F428FE968399AE819C6E18DFA3AF311 +:10E040006B16E4BB2B845C1B60EF3C7A37EA3389A8 +:10E0500016EF76CE2F7FE7C17DBEA1B2389237A2F0 +:10E06000BFE0A7037E50EC40FEB62271601AE9556E +:10E070005B54E28F127F6AC49A176F2BEB8B78B3D5 +:10E0800018DA51DE6DC587C042D7B65CDD17F16A7C +:10E09000D1C6C90F04408E650B389EB08667E1F982 +:10E0A0009CD99696B21AF5C2E5F59731685FB4ED42 +:10E0B000EE6C2CCF6C8B9F8BFC7E927BD6A464D8AD +:10E0C000EF928792F3559DDCF8A9A0C79B975F9DBF +:10E0D00086F6C0B27FEE7BC43D08E6075823DC3FDE +:10E0E0006D730603D065D9AAF66C1568ECF338FF9A +:10E0F0000E84E7B72C7BAE1B83FC5F09EEC8A0FE45 +:10E100009E3477147A97E529C0770FE0F3F21FBCAD +:10E1100047E3FCC5B27FE63C787FD9F2E792709C7A +:10E120006F6D3E34CA0DCFD70CF6FF0CC7FF40D938 +:10E13000B6C38D8269CBB61128B79F1376D4F41479 +:10E14000DF75F310EE6FA804F758F3D5B42B045F16 +:10E1500059AF0CF6227DD61F627637966E46FAF2DC +:10E160001995D5A13E20F51AF9FCD57CAE0F9DE995 +:10E17000D59C8D7871D38ED66C942BEF27F27AC50F +:10E180008EEBDF443EE57F2C8EEBED56467AF2C2F5 +:10E1900000D7BB590DD06B4664FE03F94E82F34D98 +:10E1A0005B0A0DF210F4129AE77D2B2BC5750CA8B3 +:10E1B000EFCC47FDEB8FD6D0623CD73F825E1BC8C9 +:10E1C000C173E27CEC8FCDEA147C1E0042427DE4F8 +:10E1D0008FCDCF250E7645F4B8C4916D21E473CB75 +:10E1E0009F4F2E50394A117EDDE296FCC935A55F5E +:10E1F0002AE9636EC4D315BB5F99C2781D04616CB4 +:10E2000078DE2CF4B0AEFAF3CF925DB76C17D72757 +:10E2100096B53DFB6A268C734BBBD027849EB25CBF +:10E22000D0F32DCF73B82C7FFEA87DA1DE1EC94B85 +:10E2300059DB0F34C173F9B6B99B518FC2731BCB35 +:10E240005842DBE7735783EA9CE07573FE6DED245B +:10E25000FD707DDE41B2CB973788F1F20EAE1D48DE +:10E26000FB9DD55BAF0FFD2DDF467095EF033CE8BE +:10E27000BDCFE2934620FF0B2D4F6842B9AEDDE2E1 +:10E28000B26259BFDC4572FEA15A4B9E15E0AB2924 +:10E29000095ED4E3EA1CBCFF1D0949DBB1DC93C075 +:10E2A000EB9FC567939CFACCE27B7609F4BB433DB8 +:10E2B00010CF06E19177EEB3403DA38FDF5900F315 +:10E2C000A731A01E15E54748C1F68F5F3C5D88EB7E +:10E2D000183F207C8EC1D26C4ADCBC49A82215882C +:10E2E0007D0E0B1722BEF77989F3EB876DAC09E53C +:10E2F0001DB3FAD86C781E42FE85E7FF0F4B10F96C +:10E30000F11E25F463BDFE555AC0F1D617E76A52D7 +:10E31000609D6539FEFEB88E6B15DB70545D9847C5 +:10E32000CDC5F13FB6F176A9C74E144C384BD86332 +:10E33000F6CC7417EEAF5EC04BD1345607EB5833B2 +:10E34000ECA585882FF7743A581CCC3FB13381F483 +:10E35000DAACCC52926FF5022E8A2715650E7B69D6 +:10E3600098251007EBBD873982D89F394CFAAF2525 +:10E370005EC3F7943DAFFD03F97D3FF5937DBDA0EE +:10E380007FBF3B146F3DF4A93A7BEAE1DF31B49FD4 +:10E3900083F908BFB97DFCA30A50CF3D5B7AD40F47 +:10E3A000E77D8FBBCDE11DC6C7D3EF63CF9DFF488F +:10E3B0004AB144D6F771E7A9A77E39124B07C9A124 +:10E3C000897B549223E6F57C9CEEB1D239753A42B2 +:10E3D00016ECEFB2041505FBEF7B0FD737D1E10A3E +:10E3E000A9A8C73B6C1FE9E50C3B90957CEA72122B +:10E3F0002DEC0B5016FAD6F3F31BDFCB685FDE581B +:10E40000C0EDA41B0B38DF95F09570631E8DE9E518 +:10E41000CCAF5D3B2A992542C7DF16CFCF7E3E9019 +:10E42000F48BB37B40CF88A277CAF210EA19A857C1 +:10E430000CD416161445E46CB994BA420EAB62DCE7 +:10E440007201AF729785C3678E093E026FCC786107 +:10E450003E77799EECAE03AFF4CAA1731CFE43462F +:10E46000E7770BAEA3E31FFB1B81DC58A6AA1DF5C3 +:10E47000E7FC3B9E5F287E08EA159B2DA457A0DE93 +:10E48000877AA2E41F7EE40357D073AE07E631E239 +:10E490001B556A82777D14BE21F9853F01CA11C8D8 +:10E4A000379A891FDCA176BE6251227C624069786E +:10E4B00038CAE10E30FDB13D6C69A3E7CF170C24DB +:10E4C0007CE9CF0E64E073B0578A500F541D3F7E35 +:10E4D000F804889496759C3EEA6DC10797207F28C2 +:10E4E000777951AFFB386809D8609D2DC99C6FB40E +:10E4F000DC9449F2FC6326F8C85C3BF1912B2D9625 +:10E5000000D95BF332C9DEEAEA9FEB09A2FCF9C548 +:10E510003FD5CBB660FB2C07C9DD1694C7506FB949 +:10E520007738B5BF20F9D24D9C2FB5CCD23212B07E +:10E530007D565F0BCED792EA7F1AE936530D3E1116 +:10E540008FFAE4B712D8E3F83C47CB4079FB80E27E +:10E550009BB718DF1FCED71D9E97F0F40E7E3C218F +:10E56000F42775D4256E5FAF934FED4338BF1C1071 +:10E5700038FA20C22B3091E5A13EDF81F87945E4DD +:10E58000BCC02A67752991734B359D9BC4D7800DFC +:10E59000CE2F959FDF1A25F6F9A58AF353EA00BF1F +:10E5A00089FFF3F3B943E5FC9DFD1A1448284FF4A5 +:10E5B000F1EF473CAFBF15CE850462F87684D7C330 +:10E5C00077266AB88F0E0BAB698B42B7EF1608BF80 +:10E5D000134A63A087F9821EE64BBC5D69C2DB70FB +:10E5E000FFE4534E81B7F0FECF9DBEFFC279FFA27C +:10E5F0001C1A850FF7FFB73A37DA3CC7849C78C1FD +:10E60000E13F4A7CC13AD1A0AFEECF3F9D85728AEF +:10E610009DDFD71FE5EEAE54DF093CBFF8C19D7604 +:10E62000F447746474DA709F1DF33EC842BD687E7F +:10E63000DD6B445F17BBCE35CE11361C3FB934DFDE +:10E640001686F7D34AF35F41FC393823CE131745BA +:10E650000FD93B637416EABF87A68DCE427E77083A +:10E660000EF000DA11566F22F241D65E497C6CB68C +:10E6700098F35069217F2EF866E479598FFCF243B4 +:10E68000E09721D053DF07BB0CCBD3609785807F09 +:10E690009E04BB0CCBE36097E1F3A36097617964C0 +:10E6A00095979E1F2A1DD41E467DB959213B68A10E +:10E6B000D56B8FA60F2FDBA5B290E457F0FFCD8F5F +:10E6C000390DF59A877A1BEA4B5A40737044EA8BEE +:10E6D000360C32D4A5FEB8A0E172C373FFCA424320 +:10E6E000FD3F16DE4D1CDEE827FF778237FE360041 +:10E6F0001CCAF01F80FF878AA6DA508E5B1D2CE0B3 +:10E70000047E928C7406EBB7CE51B85E04BF66A04F +:10E71000BFD9F80FA02BAB8BB737CC5382C88F5023 +:10E7200017427B02E01A72027D95B92F3B89FCE803 +:10E730007AE45C2ADAF3412A6F6421A2CB4A16A656 +:10E74000FA7CD6996D87F21635B416FD76AF39FC92 +:10E75000558540C77F9FF6FB0E0589D15B3D04E9D7 +:10E760009BB952C8CE8C754EC021B97E8A5D47894F +:10E770007DC16F0EF27D78EFA073C4EDB7C3397C15 +:10E780005C1D1E85F32F73F81F4DB5D07CCB0A910D +:10E790001FD9FC437AC3F3B78A466721FF60BE3EA8 +:10E7A00006FB28D67C1B71B30087EA52809382F166 +:10E7B000370E9713E51C2E7B37C6D9D18F71629D1A +:10E7C0008DFC94ADCEEC6CC4DB138D53B311EF56BE +:10E7D0006F1C928DF83EBB69EAFBC8B727ABD3AB81 +:10E7E000F0FD63CD1CEF19BB95F4ADDBC5D91DF36E +:10E7F000306F08DACBA7257A03B01F7F202789D690 +:10E80000CB34573EF45B28F6BDB079E9741C4FEE6B +:10E810007FC18638C3F95F5B6CAC97337B04CF72E2 +:10E82000F09CED91763C7FB5A297BF07FBB9EE4F08 +:10E83000DBDE7C5937DE038589A9A8AFB0D16CF443 +:10E84000176AE4FD5870FD6C55F0CD9773237095F1 +:10E85000F8746BA1EF513C1F784C7136A0259203E0 +:10E86000B774F9B3F62421FC363A7F7DDF9508971B +:10E8700077B87FA3D55945FCE3C369004758FFDE4D +:10E8800069D76785757C41BE1F46FA067A3DFCD480 +:10E89000F5C447F695A7511CE6E0F3DCAF7C44D005 +:10E8A000FDC139D757DE0EF2F1E02E95F4BB83EDB2 +:10E8B000E75E41FFCCC136C52B406ED18F7BB07D6A +:10E8C000D0BD23A1FD539F8DDAF7EE7A8ED669DE97 +:10E8D000F7FB62FED3380FF11537CD775CF097A3C5 +:10E8E000C85F86E03AF2A83C88FC05DAE7EC06FE51 +:10E8F00082E36FE1F32FB6FA88BF30FF5CC3FEBA44 +:10E90000ECE1C754C379D73CE434F115239F59B4E3 +:10E91000A19FA1BEA06190A1EE5F69E42F65A585CE +:10E9200086F6C3368EA7070FABE4676301ED405E42 +:10E930005F1D7E9672FC5C5D1E47F472781AE733A9 +:10E94000B3E7001DA07ECF3C45684B7ED85ED6075E +:10E95000CF856DB01D433DDA0DFFA1BC36C3B19C20 +:10E96000598F8575F8BBEC79E8AF5BDF6C6CD7E14C +:10E97000B3195F3F427C7546F0F553763EDB3E901F +:10E98000B71FE81BE17BF8D3F317C9B724FE02DFFA +:10E99000AA42BE067CE533E463DF2DC87931ACE8DA +:10E9A000F8CA45F2B18DCE7F921C6C75FE93F0F8DB +:10E9B00050B9C0E3F22184C707670CC92279169CBD +:10E9C0004BF4305FD847076DBE44F48F1E5ED93BD1 +:10E9D00009DB8F369411DD497A32CF7744E09FEC22 +:10E9E00037DFDA69F3469187FE9546FC613BE71213 +:10E9F000BEDF6EC2B358E39BFBCB79E69BE2BCE67D +:10EA000079868C14FA665BE545CD8764D8F53EE9D6 +:10EA1000B50911BC54910F7C9618267B9CD349B93B +:10EA200080DB91D2D189A447CC39472513F4DCD5BA +:10EA30003EE7DC5BA391DE4A6D82DE6BE8FD32D1FE +:10EA40006E5EC769A1379C14FCE3B8A06BD9AE6EAB +:10EA50006BEC7B03E2FD4AD58BFCEAF0F442C2F397 +:10EA600033C1729AFFC81C95FC4CD3460EB801FD09 +:10EA70004C723D72BEB219E712D18FF629C00BFD60 +:10EA80006265366F9F68FA85191EB1C695F8B3772F +:10EA9000DA90C3B8CF43C847B1D56F84D3217C1F68 +:10EAA000DA676F5329CE6686D3BE6943882F1DD996 +:10EAB00029F827C015F5EF9A878CE7BAA4C569E253 +:10EAC00037BD0DEDB3CBB95E26F9B55CDFA19583FB +:10EAD000FA30D7C59FB71CE762F1E566F13E8ACDF3 +:10EAE0002F48FEA618C6030BD134DF4053FB50530A +:10EAF0007B81B17E91787C54E08F943F47E3BD9554 +:10EB0000D1E27747AE89ABD1E7256C1AC9FD369BB8 +:10EB1000468A78F725CAED7B471AF9E085DE977CAF +:10EB20006F61A1AF6524D269A88CE2D817CBE774D6 +:10EB300072FEA191B8DEB062C7F7A55E5523F4CF8F +:10EB400056E77DAF22DEFD45D8037B67C4111EFE6C +:10EB5000F529AE77FDF5E7A7499FDAB7FB8EA4B09C +:10EB60000E6F9609BC39DD3E2409F1F0585B7D92A9 +:10EB70009EBE65FB19783E7664445EC75AF7979649 +:10EB8000D7CF0A7B602797D737599BA3DA03FF6A51 +:10EB9000393D595D497A88595E9FF67892DC041FA9 +:10EBA000417742AEC8B8CF5F6D9E24F4171E0B723A +:10EBB000B922F9FA41131C4E201CE222F224161C41 +:10EBC0008F8BF7651DEC511BCE5FE6F0BE928AFE7F +:10EBD000970D8A17E35E989E520CE77C604EFE8F7D +:10EBE000D16F25FBCF2F52492EC8793EDAACB4A1A4 +:10EBF000DFEFB595FBB2BF07FDAB773989AFCAFE32 +:10EC00008BA61BED2CB33CFAA8F193B746C3BC65A9 +:10EC1000CDAAD701EF954D2FE9C3F56AB7118F043F +:10EC20005D9ADF5F6AAD8D7A9E66BE57367D35E9A7 +:10EC3000EB87C47A0FED1D63F324767FAFCCCAE176 +:10EC4000B014F4CDD530EFD2864F48FE2C9DAE7A6D +:10EC5000512D79ADA97E26E2FF519FCD82F471A49A +:10EC6000ADF74C8453608EEACD85FEFB9B06111DEB +:10EC70001C6BBABA2FCED74BC0EB747B9C05FD4FF3 +:10EC8000A77D3616227B3944E7F9514319D9C7A726 +:10EC9000114E78FE5637D149BF22EEC73A0AE370CB +:10ECA000FBD9C3F4F1C02341B53418852FF513F314 +:10ECB0001D3FFF43C2AB5783FB08EF8EB6F1798E41 +:10ECC000AF7427619CEBB70D85248F8F4D87F1A121 +:10ECD000DCBB7BE97D98AF777A834AF2E374FBF57E +:10ECE00033B17E688394BB5C1E558BF957EF1E3D94 +:10ECF000A318DA3FFAB98C6B72BA5E20DAAF9E7550 +:10ED0000F8BE62BD3CDB35D7B0FEC3C1E3646F9D86 +:10ED10006E80B7018ED53306D9D11E5EB4CB786E26 +:10ED2000E51B8C74083F577EDF489ECBA206D06758 +:10ED300081651D9D5E4676F4EC406F93BD6DB4E336 +:10ED4000CADBB8BDB7E0E1B2A210D269E0131B9EE6 +:10ED50005375739C619ED92B8D76DA02935D66B6EE +:10ED6000DBCCF245C263B9ACB755D23ACC7A4B375B +:10ED70007963ABAD8A961F5155C4F5B16AA0CB74C7 +:10ED8000F42B33EF0CB4BB8E017CD7C378D576F768 +:10ED9000DF73414F3EA2B2F1E44CF30658B1F41BCD +:10EDA000E8E65BD0A09AFC1346F882BE7E0AF5F92D +:10EDB000A6DE420E0740AE24A29CD1FC4528272E99 +:10EDC000D61F70D1FA7695D0B7AB0CFAF641ECA20B +:10EDD0007B7F6FF9F5E4773A3CE37AD2BF0F77F99E +:10EDE0009D7C06BF9384EFE1E965067D52F7BC1771 +:10EDF000EB813FC6D21F8F0AFE7A44F89DD60A39AE +:10EE0000D320E4CCE1E9C22E4C65442F56ABC62E8C +:10EE1000862F5D481F5BD0D0CF745E4639E32CF15E +:10EE2000B716015EC4A50F353CB7B90B8C7463C22D +:10EE3000CF7E8CFBC1EF46DB1EE05E5FCEF347F179 +:10EE400039E6B148BC64D01FE573F986A1C1F5BCB1 +:10EE50003DA01660DA1B43158DFA5B795D53783D52 +:10EE6000E012EDAAC85FB341FD688E772EEA519893 +:10EE70009FE34CE1ED8822FD009F935222F88FFE24 +:10EE8000F9781E220F24C17BFDE7E4BC8CF48D7958 +:10EE90003B9741FD5745398437E9E89A2FA0F14364 +:10EEA000989F13AE9F40745CE648E2717690B33D44 +:10EEB000E3DF6A6EDF94F6A6C9FA5BF97A62E2B321 +:10EEC000E877097AD56B442FCC42FE938DCE11366C +:10EED000C4DFD92E5F16C201F0BDF276B4D35FB4A1 +:10EEE00093BCDC5BCEFDAA07A78D7EF836783EE2A8 +:10EEF000191791F1C1C580E724173A13F5787B649F +:10EF0000E5710BE6D3FCA19D79311FF1C8AE8A579C +:10EF1000DE8471F6AD5C786F11D2D17ECEC7CDFEA6 +:10EF2000D89267C6913CBB6E864A79DA874A55C645 +:10EF3000F97C82C1AE88F86955C28F4FF758A91D78 +:10EF4000F3AAF2308F0AFD95986F552ACE45E81541 +:10EF50006DE21C9F10FEDA1D826E5A04DD6C127485 +:10EF6000B3CEECAF7D88D3CDA1763004404EFE6E9B +:10EF7000FAC289E487DEC2289E9C334D5D3F12F6BB +:10EF800077799CD786F02B999ECFE13947B1601CE9 +:10EF9000A6AC34DF86F47E796F8FCD477AD62CAA63 +:10EFA0004F9A934376FBDE95658964BF277AB390C9 +:10EFB0002E074F8F0B5992D00E2C243E71E5198BE2 +:10EFC000815EF2430906BA1BFA588AA17DC8964CA5 +:10EFD00043BD8F6FA0A17FEF52233D260C2E30C979 +:10EFE00025AEE749384F56C791DFEA48445E52BB29 +:10EFF000B4EFA4FF4DF6076819F85A93D0074740BD +:10F000001DF3E2D6CDA97760FEC3A76D562F1FBFB3 +:10F0100082E4BD23E77907D2098648314FAA49CA5D +:10F020001FE18F671A33AD6B03C378E9915246F83D +:10F03000143F9829182F6811E77DBF9817F86A893F +:10F040008DFC6EFC1C7B4FF7513FE633DAA9E94893 +:10F0500067058827FCFD27C4FB3B04BE1C29FDF186 +:10F060009A04C487B98CFCF793D5656B302E78640D +:10F070003A233A690BBD9480EBC77130CFEF57B19B +:10F08000C699F3DC1F6FC1F5ECB4D338658F815C92 +:10F09000043C197AEDD10FDE46F06D71EF8B67DD20 +:10F0A000F5E9118F695E044EDE1916B25119D2903E +:10F0B000FFE49D39A0615C6FE85F777EF034C3792F +:10F0C000B95C6812F86DE6AF3F7DFC170BD663B9EB +:10F0D000636BC17B507E63CD839975503EB1E65B17 +:10F0E0005B6FF344FC9F3B662EDDDE02F521DFFC07 +:10F0F000FE93CF235ECDFCFEFF791ED73BF31F7F2F +:10F1000076C1FA2FAB4F6448DF727DE679D259930E +:10F1100082F14DE4A3C497AD01AA57078C7A7759C1 +:10F12000A9D3807FD8DF0AF02BABFB29C589D3C5D3 +:10F13000FB8766DCADA830EF7BD59CAF1C5CD5D9D6 +:10F1400032C946FD43D81FF824E55DF6EB0F6C0588 +:10F15000DFB707148C6F8382E4C5B86D06B4233F14 +:10F16000671E0FE93BD9127F055FC1EB0A8CFC7B60 +:10F1700056C2B33C115744FE8BFCBE6ED440E2CB6A +:10F18000FD5C4CC3F32D7D618382F966EFFA3D5E31 +:10F19000D20B56B1CD93C0EE1DAAF2FC89BCD2773A +:10F1A0006FC07381AD5AFD059171778ABCA6D217E5 +:10F1B0005C947FFDEE4ED736F2EB1F9869D1EB835E +:10F1C000137FFAD1CF7E8BF8551D4FF865D65B0EB5 +:10F1D0000AFAE8AADB3C0FDF86FAFE8B0E6E27697F +:10F1E0009E2CB2BBBD9E2CCCC3E9EAF77D191FF360 +:10F1F000FE19F9F9EC0A27C50D649C482DFDA411F0 +:10F20000E9717E716D11EAE399780EBD23F1E8F79B +:10F210006EB253DE404049A0FCF25871E79DA372E4 +:10F2200044FCA5F60A5A07AB1D8DE5B9B9F50FDB0D +:10F230003DB1E5558338D758ED363BF3478B0FEF9B +:10F240001CC5F5D07A3C079BEE1C5C7FB801E3BC83 +:10F25000B1CE81598305942FE9700CC67C8E34F1B0 +:10F26000B8D5F983B7505E751CE6F22AADEEB355FA +:10F27000487FD20F5195CEBAE2601ABC6713EFA552 +:10F2800009FD1B6918F5EF2A11FFE9A86414FF496D +:10F29000AB3BFDDF089F8D62FCAA77F8F8766B68C0 +:10F2A0002FE24B95CB4372A7A34F9217EF27B1F3F1 +:10F2B0003CCF2493717C4C33EBF7A809E9D69D969B +:10F2C00050F13B541FE68E672127E28FE2A079338D +:10F2D00057C6517EAAD4AFD2EAEEBE551D61184F73 +:10F2E00041BDFADD0A6E3FA399DB356E8E41AF2238 +:10F2F0003DCBBC0EF95E878DB5A33DA9D3B3480FB6 +:10F3000063FA790619EAC22F66ACDBD2ED063EF14C +:10F31000EEF9B25EB55C0E785247717F1CC243EACB +:10F3200063526FEB36AEA0779D7E19407E21F321AC +:10F33000BAF4A41A9D1D35B0FB7B32EF4C9E83843A +:10F3400067ACF79D25DAB951941711A271FC6218C8 +:10F350008BD3954DF035F14B605B3C2F5EE8A1A05F +:10F36000451AF211A45E29F97387E0BBE19C30F9DC +:10F370000165BE777F78271BDE8F1F9DDC952F8F61 +:10F380007AD091551F533CBD0AF550983FBCE643D7 +:10F39000C37D92A69292F8D1E46F33E63DE8E2A8ED +:10F3A000B45EBFE09B935517E59F74B0042FF2AF96 +:10F3B0008E80D0C7FEE4247D4CF20B337F98E1357C +:10F3C000F2FF6B8B8DFC7F96D6DB144732FAB3CA03 +:10F3D0007DA6F8F63BD30C7C53F29F3B542F6DC2B5 +:10F3E0000A821EE334FB05BF7C5BE88176564BCF77 +:10F3F0001D98F73908F97F1B952E7680CA24D649C7 +:10F40000A59BB9294F268579A94C653E2AFBB25A9E +:10F410002AD319CF8BCA646D54F66707A8CC669DB2 +:10F42000547A98DB82E540E6A57230F351E9636EC9 +:10F430008A7BBF9318CE3A04F09B7E3D233F3C630A +:10F440003FB9518373EA2897754020A4ABC94C207B +:10F45000DFE3376A589F26EB3B78BD84F72FFDE545 +:10F460004F7F141846FC46B43FC1DBBBEA3B6F2C10 +:10F47000213AB5507D0EF687FA8323B569A3015F63 +:10F480002B4733E2A3E70BB56FEAEB0F156A33F4B2 +:10F49000F5978BB46BF5F58F0AB459883FB29E5936 +:10F4A000A895E9EB371769E5BC3FF71FBD63D34863 +:10F4B000DFC50529A338BEE1CFA9FA2B090F7729AB +:10F4C000563CD738416F763C4715E9C8EB88C3D224 +:10F4D000C7F377C2F1AEB0D3D283FD63A2A330F2FB +:10F4E00027C0C3E18AFF665C8F999F280191079826 +:10F4F0006A8C8300BE93FF2CBC92DBE98C456F972E +:10F50000F35E08CF99A6F3DB0E8C8C1B6B1F66FC99 +:10F510003D20F4BC8342CF7B47F899BBF61DB6264D +:10F520009F7244E838B67D6865A7F4FCB2DBBE3F45 +:10F53000AAB4015D87EBE2DC28EF3AE2D9DB68A7E9 +:10F54000050EAB0CF58C4B5D6F69E1940708EEACD2 +:10F55000BF9BE20A725EC1673AF09FA0E75CDE4B98 +:10F56000DA975E078737B73B92C5BAEA27A55C935F +:10F5700047F137AED70FB31D983515D699B681FB35 +:10F58000479390BE3114F6CC9FDC18176B9E6C61CC +:10F59000C8A71A05FF34FBDF364E5AE1D6FBA71B7E +:10F5A00093820AC6233343F1DC0F91CA82F12847C4 +:10F5B0004BBDA594071350DDA558AF6033F3A0BE33 +:10F5C000A045F594C2BCFB5A9E5B817ED84515765A +:10F5D0008A4BD8B42914BF96F9182902CF1BD6C577 +:10F5E000794308C73E2EF2CF0E6B2C28457BB7DE41 +:10F5F000959282B89852B184FC87F52EEFEB784F44 +:10F6000023E0B6509E21736B8E32D057B6DD662D47 +:10F61000453E9EF5ECC82455B7EEE30D67E331CFC8 +:10F62000FD51B785DA1F5D39D1B1C485F711C15ECF +:10F6300080729FFB9886FAFB56E89306E3DD5773CA +:10F64000ACF9B21ECE31A9D46EC05BA7D7588F33A8 +:10F65000F91F6D26BDE0F06891F7318A8DC273BE47 +:10F66000E2C9F364FFCE7779C83F3EB149A17C97E8 +:10F67000F05E6F36EA9BC7EF1D42FEF0862655F816 +:10F68000A3BDE48F0E67B16CBCB753DDAC90BEAACE +:10F69000367CB21ADF1B90E7C9C07106783B33DCB9 +:10F6A0003AFA7BF4FBDF8D4779D78017CF088F18A4 +:10F6B0008D23ED55793FBCDA7DB692FCBBCDBFF70B +:10F6C00021FC93350BD1CC115B301DCF7F7DC96CF4 +:10F6D000A24BBC6F857A4C377DF47358A7EE9E41E0 +:10F6E00063EAC0049C3782BF1AF9CD4F3417927E6B +:10F6F000B4BD6922E5F59BC7B967156B43BDB5710C +:10F7000095A32D9AFE7B4FB62F1BEF619FDC58B25D +:10F7100096C1F99FDC7B533ADE5B5FDC1CC7E23DA0 +:10F72000DDFB9FD8389AE65B8CF7A171DEE659764F +:10F73000942B535B4AEC08B77B56CD7D563FCFC721 +:10F74000257E6731D09FB3F959C213170B0510AE50 +:10F75000BFB94ACB46FDE2442E8B9A97D9A798C7EA +:10F76000177F7B958FEE999CCC8ADE2FA398C71FBD +:10F77000EF2BF6487FF1DB4B53C91E7423BD1E6F80 +:10F780002A4C42BCB5611C1DE4A2ADFDFC2AC4FF9D +:10F7900073150BDF5B0AED8DD3AE3B83E515F65A8F +:10F7A000D29BD91F54A207D00BE9BED7DFE638DCC5 +:10F7B000F5BABC40D41F35835FC3C7D0FEB035A9AE +:10F7C000213BF077DB9E53A48723BE6A3AFCA5DF7A +:10F7D00028A1CF8B7C8FF451747F8E7E8DD75C17E0 +:10F7E0000C318CA32C74443BC7D8F3EBC645FD7693 +:10F7F00012D3E275F383540C915FDBCFE7EBEA277A +:10F80000DAC10CD5687D422F37B7CBF50FD962A48A +:10F81000CF6FE2F91445F4F358EBFD46D0F85E4D96 +:10F8200031137916330DF432546D5B3106CE8DBD34 +:10F83000CBF93FD875CC17255E15E1B3B0F6BE0203 +:10F840007E00CFB5A9B3C93E89B50E7BF080963353 +:10F850002262BF7D23DDB82ED9AF46E05D5C908586 +:10F860006C495886E85E461CBC8FF2FBD38AEFB821 +:10F87000AF894217B234F32DFC79F0BB11F2AC4CD6 +:10F880007C02D160B0D4472CFC7D4DC7E7123773A2 +:10F89000FDF7C41685F4DFF51B795EC4A741A89374 +:10F8A00072C1CF09558B2F84B2E3D2DD1F5CF242C7 +:10F8B000D37D433D06B82D62BA78D29927EF7A1BE3 +:10F8C000DB4F3F7D970F977B77EAA224CEB78E2E32 +:10F8D000C0794E5E6E277F0CFE1C123FA0E3D26003 +:10F8E0009C010FD7EF7E72CB02943BBB1D5E4CAFE9 +:10F8F0005BBCC5D81E97AEDB17E3F81530C0293CBA +:10F900007016D0D191EFFF84EE792720FF447A5C06 +:10F910001947F7BBCC70FE6074D7F742983E0EC70C +:10F92000C4BD0E4957C736D49F54619CB52BED1EFC +:10F93000FA2E82C9FE3AE299A5A5EBE2BDF695FC46 +:10F94000BE25D3DB890323FB97E31E092C74785C67 +:10F95000DDC7EB867731C65B58A2ED2A06845D567B +:10F96000E27B1ACBE31B16D2BEEBDA571E7913FAF1 +:10F970003425F87F867CF3D88641A314BCF762F562 +:10F98000D0FDBF86064B3CF2FDE6366BFC6084770B +:10F990008385E47C735B6AC260944B2E0BC549512E +:10F9A000AEA83AFFFE49C12723F2C397A4D77F121E +:10F9B000043E9ECC13FACF24AEFF28CFEC21BDA38A +:10F9C000A191C7A9A4BEE116F8E316F1C858FA0F31 +:10F9D000321E5C7762D12237F2B5C624FE1D8D45FA +:10F9E00093BC01BC9779B58B91DC1880972350CFDD +:10F9F00072B1E05498477573FDC6DFCC489F4971DA +:10FA0000B9BC08EAB4966080D6AD713A73C07F087D +:10FA1000CF843C8DE1F856935E6137E90DAAA9DEEB +:10FA2000512CF250841EC184FE2DBFDB90786FCF25 +:10FA3000793DD2AFDB2CFC13A03F05E8FE47310B2C +:10FA400022DE324DF3A4F68DD801E877C4F6F462D5 +:10FA5000B6AD5E177F52B457C96F20FD92D2FF201A +:10FA6000FD1C238AC15E4BD2F9237E0DA6A54AF167 +:10FA7000B0CF104F72801D903D398C29FC9AC597EC +:10FA8000D4D3EB2E2EEEF3A397F83D9F064B82774F +:10FA90007B4EF77E19E3B8DF2C611FEC0DF5DAEB36 +:10FAA0001D749F66B2BA8BEECFB78EB4F03C65760C +:10FAB000C08DFA40F218CE776F2FF1B9C7202377A7 +:10FAC000F972106F001E011BDEC3137EDBACDB0777 +:10FAD00026A03EFC5EC6A98DA897071A2DC46F24E8 +:10FAE0001C73565B36211AEAE273216B4124CEB6B1 +:10FAF000DE773680F77ECF5FC9EF1125CC3AB1179C +:10FB0000FDA0EB065BC8CF7E77A246713BA01F87A6 +:10FB1000CAE375AF63BCADC9939282DFCF793A99DE +:10FB2000B733718E0F24F6DDA6CF17E9BC92EFFB39 +:10FB30000125BABEB2F74ABECF8EDD00C85EE4D75B +:10FB4000E2F678607F85E6D2D591F6E0FD1F06B833 +:10FB50003D3D6AF7FE8AC060B29344FBF90AB2E702 +:10FB6000D1C708ED1B776FAE40FBFC919CE8F3DE3C +:10FB70003E8ECBEB47DEF00F407D36BC1BF0A75727 +:10FB8000B4F30D314B318D9B8D71A9F09D7173A331 +:10FB90007D8FE6CD719C9FB4425B5CAF881EDB5AC3 +:10FBA00061D65383C4AFCED51C7B85D2AE817F1482 +:10FBB000013D24B3E8FCF2C2FAAA371DF5CEFA3BA8 +:10FBC00095B5C83FEA415FC5B8609ADB4EFA6A4313 +:10FBD000F2774BF05CCED53037DE5BDD0E6A1FF27C +:10FBE0002FF4ABE27DD4A9759CCFF8DDDCCF0A768B +:10FBF0009CEF6AC4C70C2BE1A3D45FAD159CFF5CDE +:10FC00001EC7F38B3B925DE4374DAEE3F9C4CE00E3 +:10FC1000E8B3B8BF493C1F5883FF900F49FDD63564 +:10FC2000CC6AC80BB69BF286ADA63CE16F8F31DA89 +:10FC3000338945237BD4AB7E0DF62FAE730FF01FB7 +:10FC40002C43600763F912D8ED58BE0C763BC60D05 +:10FC50005E5D9547E5EBABBCF4FCCD55C5544EC895 +:10FC60000E535C91FCC8E4BF612185FC7812BF5E35 +:10FC7000EE3F11F1BD84B76FFFD5CC4703FDA13D29 +:10FC800055F40FE45422FE75D5D9B595D8BF2A9DF9 +:10FC9000D79D636754223E4E9AACAD1B0378D2C702 +:10FCA000E2AB6EC4BE77C579A3D9F77DC7CAFB5E48 +:10FCB000D1ED77869F3A30FA735A894FC4F0E73C0A +:10FCC000A0F075EC7D61F343E887EA35CBEA433C6D +:10FCD000CE1E68F4F37F3E86D3C5D4B19C2EB3DF2D +:10FCE00004FAE801EE923E62B5D7EF061488425757 +:10FCF000B26C4D64E3E99E75A57D6EB47CA66D8201 +:10FD00006FC61CDFC53C715744E8ADDE65A6B73051 +:10FD1000C577CFD57D672FCACBAF4E6F8CECC37044 +:10FD2000A546F23A0CF486FC5CADE1F4A65AF93D26 +:10FD3000CBAAFDDC3FB21DE90BCED98FF406FF9CA8 +:10FD40001AE0F53413BDD59BE9CD65A4B730D21BBD +:10FD50008C971CE0FA85B3A2ED6BA5B73F7F457A7F +:10FD6000FBCD5561CA6BE8C8A9CD40F8B48AEFDA7B +:10FD70005D2A1DDE35D6CEE5C1708DFC020D388EB4 +:10FD80008BF4F90DF8BD94A9FD575B53007ED35356 +:10FD9000F3E97B023963FB0A7A38E0427FCD024DFA +:10FDA000FB94E8EBBA33744FB18F85D36FDFB1AFFB +:10FDB000913CC86A3C386B2AD2DD9D2AC949F3BE02 +:10FDC0006E1A2FE25B0A9F174E2E431FD77308BA95 +:10FDD000F4DC59AF38501FAF66DEDC1CFA3E0C7DF8 +:10FDE000B7E6870D7F73E3B8378D4FA1757956BF9E +:10FDF00093ECE7FEB574B4DFE86A7241777A845F0A +:10FE00009BADAF819E93C7F6E09FBD10FFB84FE852 +:10FE10000F78F4A837F8C53D4C19178949CF263F0C +:10FE20006E4CFFE1700E1FF3FB67855CAD17FE5F44 +:10FE3000B3BE27F73FA4C43F0CF7A7B85EE57EE04A +:10FE40003DCC83EB9471B3AE3C23A91F0658B01E82 +:10FE5000F56D2BA8327DB9BA81E375E51F093DF137 +:10FE6000C512FF681C771BF3EC45F9E6F2F27C053E +:10FE70006789564CF0FC927AE086124D1BDB035EDC +:10FE8000BD38459B34B628763B3B0FA38C8AC4B55E +:10FE90004A6659395FA853041F70ADB543BD351983 +:10FEA000F89907F576BE6F37F00D0FD919463B620A +:10FEB0000A3A23916F201F21E06AD3312F32498CF7 +:10FEC0001F91D7E157502F0D036C3741535280CB10 +:10FED000EBFAFD9CAFD881AF505CBA98DB09F29E7B +:10FEE0008F739897EC2F55EBD97EB09AECFB256376 +:10FEF000051F296023116ED916CFFD63E079E183D8 +:10FF0000930F8D81C7450F2FEE8DE274F4B6C63284 +:10FF1000FC6ED74D8F9FDC867ED231FF15C7C4F7AC +:10FF2000D128CFE05F2867E85CB6ED79B72260455D +:10FF30007E151D8F0BAFE2782CE3AC3DE07123E121 +:10FF4000B188735E021EBB2E80C7CD884F51F078FA +:10FF5000E357C4E307715C0D0F01E34653B41FF58B +:10FF600084B75B276B8FF6D4AE8B1FF0FC21564312 +:10FF7000F6B38C5F9AD7D388F235B707BFD4BAED02 +:10FF8000F168CFD6D76C7F03BFDF585FC7EDEC8E2B +:10FF900044AF03F38D03BF57E9BB54B1DE47BB3B0E +:10FFA00000CC72E8553C0F7ADF9D71A109304EA656 +:10FFB0008BCBDB4C97C630EFDBEA0EDBFC89A8AFBE +:10FFC000F918DA19F6540B0BE8FC3157D80E905C8F +:10FFD000EE00398EF401F4C9E92D998F23E5F384FD +:10FFE0003BEFC7480EBBAA13E4A08E4EDED85D4C93 +:10FFF0007EB8C4A2E757E07B6AA5DD83F83DE173D4 +:020000023000CC +:10000000909BBA794A4013D1D7AF766418C699EC61 +:10001000CE31B44F4DFF86A1FD1AC0173BC5B1F9D3 +:100020003D3FA9D74CF3E41BFA258B38C737F3C6FD +:1000300018C6B3AAE7378D46FA177AC438F80FE91D +:100040005F35E90B667DC2AC3F9C1C6BBCBF32C206 +:100050002AF2D0AC3C3FA29539E8FB12C007E9FB7D +:100060000555913C01A29311F6F0F67BD0AF32CF4B +:10007000E10DC0B386DDD7A4578F8CF8CF5AEBB80B +:10008000DFAFBEDDB10DE961ABA04B495FC3128F9D +:10009000CD6324D7ED0CE5B1995E65BE93F41748A6 +:1000A0007F8252C3FD0CADE37378DE91E03FAD1566 +:1000B000DCFEFD91128A570671BAF4A444BE339750 +:1000C000CE94C0344EDF5A8A2855918F2AF35E7140 +:1000D0001CB4B3D3F97CEC759E37B9FA7BF8BE9BA0 +:1000E00005FA0B7F46564AC44F81F909CBF87B814C +:1000F00069E2BD0122DFB2175F7F68B2986F049496 +:100100006AAD26FCD37E2AE3301E0EE540C59B80F7 +:10011000FE8F41AA8F022D4922BE9E29E2E94E257B +:10012000C499C797E42357001BC5BC0496C2BF13EC +:1001300032F1A72EA6127DD8B7A33CBAFBA8F77759 +:1001400098AADB90F8DDB726C0F3A6DFAB5EF49388 +:10015000DE9D15780FE9DA0AC81020BF96AF1ACFD6 +:100160004D9DE3704F85F7D4C0B6D518DFBDC21ED4 +:10017000DC4BE7B9268EE83D0CEF213E6C4D043A8E +:10018000457C454FD7A8483E908C6384C7781D288E +:1001900047C3D88FFB9B0DFECF28F926E42FB58AE5 +:1001A0007A836B3BE9EF6B53EDF8E54CCCEFC9AECE +:1001B00043BCEC93C0EFD3321E371880FF18A4E382 +:1001C0005BEEE87E4DD0D7080EE1D54BD37BD2BB9A +:1001D00062C6515C96903DE9E2E3288D375F170CCB +:1001E000E9D629F7BDD6B55D59C02E657E668CA3CC +:1001F000D4302D7E4494384A38A8E03A07D4F038F9 +:10020000CB00E1AFFFB2711475FC978BA3C8FDCE94 +:1002100010FF9E0E882DEE0D533C81CECB12599FC0 +:100220000E7E8F113F22DC102802F56B45FDAD5D7F +:10023000073F7A12FEB97FE74BBBB0947ADC2CD132 +:100240003E73C8677B30776BD6BA15228E658C3FBC +:10025000CC00AB4EEFE7C7FBFFFAFA2CD37A265A55 +:100260008D7182492E63FF29A9C6F6D2FE71DDCEBB +:100270000DFDF2B45FA5FB7EEF76DEC7F877A374C1 +:10028000E7A05EB8EEC0BC398CFB78BAE3893E0EBD +:10029000E07BD1CA524622BE58482FDD1A58BAB95F +:1002A0001CE8672DC851CE8B3D06FA8BC43D4A35FC +:1002B000C427E9EF8F454FC75C03C9FF3FA06E6FAE +:1002C000DBA4DEAC2B0ED094E0FFC5958037035C39 +:1002D0006715D44306D4BD4CEDD7CD2BEA118F72F0 +:1002E000EBF6B54DD27D0F30D7EAB3A0FD9C5BF79E +:1002F0002A3D8FA9CF77E72394B7962BF042E605E6 +:100300006EC5BC40807B6E8DF8CE6F4BCFF96F52BF +:100310001E36E8F2FB2899C1A330FDF852EE75F3C2 +:10032000A733EEF795F375E5059AE6ED927F6E2E0D +:10033000FF9C25FE0E845FD7BD0C718F03F61D3523 +:100340000FF4E49522DE143B8F8DDB9D735E7F0FEF +:10035000C7BF64BB33C6B813B2C395D1EE47FD4DDA +:10036000F8AD3AE2C359E837E8B045D7EB3F9E34E1 +:10037000E51F57F660C761DE2CC232D63ABF6CDE8D +:100380006CF6180E2F196F95F9B3322FF642F9B3A8 +:100390005FD50F3F44F8033AAF64DCCF6F8A4398D0 +:1003A000D79B33AE2BFEE019D743FC41F67F2FC31A +:1003B0001ED52F5E3F5EE049F7FB47941F0AEB4DC9 +:1003C000D5DB41F23D99976F1E0FECA2C2713A7FC7 +:1003D000A07F752EF9FB74F696CC8725FA68157EFA +:1003E000882E3A30EB85221E62D60B657C44A9E04C +:1003F000FE09A08F89E3FA70BD0BF3D2A59D27F308 +:100400004965DE28E685523CEA4BEA555FBB3DB5BF +:100410007A32E575D5BB27BEFE55ECA9E5E38DF62E +:1004200094DFC5FD0E7EB4A78677B7A79A4AFC373E +:10043000E13999EDAA233FF890F263C10EBD99F01E +:10044000EAABF209937FCA3186E3B794D3D29FB661 +:1004500077B0C5E0779DA2AEDC4BF9E235DCDF92E8 +:10046000A9B5919D6677D93DE86FB14EE274641BE2 +:10047000C6821A8FF3927F45E695A5B8B83D65F61A +:10048000CB483B312CEDC400FFAE4AC77E1EB7758A +:10049000A2BF053B9672B926FD2DB654E16F31E53A +:1004A000633B4DFE15B3BFA5659CB0BB84BFE51192 +:1004B000C5730F92FA735B26FF1641F1F387163B63 +:1004C000D1D4FF65B0F19BC2DFF2A00BD6B7FB3DE4 +:1004D000A3BFC51CFF8A12F722E7D59BE3B653DC06 +:1004E0004DC257D2ADF46765D6F1EF024C51772972 +:1004F000C85F5A5D1CBE2AFAB35223FE2CE5998FC1 +:10050000BAFC52981FD73D4E5EFB06AED30A0C676D +:100510007D34FF9680AB391E9554C7FDE35F973F4E +:100520002B34CEE8CF2A78B0F07EFC3EF1C887CBE2 +:100530000E61396ADB777ADF0065F1E3F79761F9DD +:10054000F737C239A8779AFD58CFE0C78CFB74877C +:10055000AF198E124FFD35124F5D76A2DB0A0E47A2 +:10056000339CD2348EA7B980A7A02274E15F4732B2 +:10057000A7CFCC49DED7D1BF3660989545C3636B12 +:100580001DBF0F2DE1B855C031A56609F909CD7819 +:100590003AA0E5D2F0F38C097E3FDB52780FC2ED32 +:1005A000F987CA7E8BE52F82DF7122DCDA1FBBFF61 +:1005B0009B027E19F45D5C13FC26C580DF042FB717 +:1005C000AF274FF4FF1DF9F335C021D01FB2BDA9ED +:1005D000C0618C0319F969DAD7E49F0A77F153F601 +:1005E00076EE25F0D32D26FF545A80D34D5AE028BD +:1005F000D16726D0673CFAAB6AB81E09623FE8545F +:10060000D0E6E6FC55CA35643916103E5BDD3CEE9B +:100610001CC54F19A2EFF69AF8303A70F4780772B9 +:1006200035FBAA3E1179B7B586C7D15E9BE4F3E0EE +:1006300073195773966839577D35FFE337AED2F992 +:100640001F014F69FF2AE03B7EA7FC6A902768FFE5 +:100650005B6BC236942B5575B72A7E285F1CCBCFB7 +:100660003F2DDDCF30CEDADD5F174E44BD7DC2E0D9 +:100670002E7C28BE4A870F57DC79EE7EF473C5C204 +:1006800087CC18F94A17C6878906F9DADA850FB5D3 +:10069000EB2E4BBD787C68477CE8A3C30741FF691C +:1006A00035E107917EAD021FAC6EE063000F15F1DE +:1006B000605824EE29E9212CF20FCCF0090706C579 +:1006C000C84358A114F7B0BE8BCE3F10F1D07A11B9 +:1006D0000FF5D7F17CD98E3BE3A618F30FBCB4EE2F +:1006E000A9AE5A459FC71F254FB616CF4FC63965CD +:1006F0005C73F244DF0AC49F0979FC9CC3B1E34CEC +:1007000021BCDF0AE8E736E1F9F708CFE5FD03A1F0 +:10071000C7BD36495B89E38EB00729CF19F4BDD533 +:1007200058DFBAFB49FEDD5CE1879479795FD96FC8 +:1007300096640FE27D49E9376B4DB46FC7F3AE663F +:10074000E1C9F4BD5E8C53A0DFE9DE38CA6B5CA85A +:1007500080E10DEF7F7BA27F33D11FF3513EAE7F4F +:100760008EC38D7A7E43F29474E41B556B5592EBE5 +:10077000B1EC1B496F55C06F88DEEA38BF4903FCF6 +:10078000227C0B28C46F3281DF70FEA331D4EBAC26 +:100790004877AEEEFCA6B507F85F24DF790AE11CC6 +:1007A00085EF3C83CF757CA70DEB5F16EE7957196B +:1007B000F90DC60368FF485FFAFD9BF5D9AE7D1BB6 +:1007C000E94BD2DD7F009DFD19E11A85CE8E209E7A +:1007D0007D053A3B1383CEDE37D1D95FFF4DE9CC9F +:1007E00032BEE8C274B659E095CCDF967AC550B5F2 +:1007F000ED6C2ECEFFBF9CBFFD1D915F77A1FC6D00 +:10080000FC5D8CFFD49CCFFDFFFDA9FFB1FE54FF22 +:10081000F83E5FDD9FFAEB2B3DA4E79AFDAA0F8E11 +:10082000D66E1EDF831F4EF269ABE4D3C08F91F703 +:1008300056013F43FE9C56D1F9975F727BD3EBF490 +:1008400090BFE10E1C2F53F06B335F06BDB36EFCFF +:10085000D7E1978CE16FF857F90D8788BCD20BDD93 +:10086000B71F32CE23FCAED1EFDDD70BFBBE1EC6C9 +:10087000C07B7A5BEFB4071B60C1FF1CCBCF674422 +:10088000CD75D72091FDEE267B42B807BB49FE3DD2 +:1008900088E655FE174EE4EAF7C7A2CAADAEFD9949 +:1008A000F464BDDDE4B904BBE9FF8E37EAC9D61AAA +:1008B0006EE75A41DE515C5F2B0E21BFCE0C286DD6 +:1008C000981AEC4FAD55500EA6D5F8281FFE52E3EE +:1008D000FA663C8A15E7FFBAE3FAE6BC817F9738EF +:1008E000FFB1F1D1E3FCD2FF6A8ECB8FB037979284 +:1008F0007CADB4E05FB2600DBB3FD87E0F9EF73C8D +:1009000007DDD330E703C48ADB8F48B1879D0363DB +:10091000C7EFA5BFE0115BED1B68873FB2DA42E786 +:100920006BCE1B1896C8F3C75BC7AF7A98F27FA44B +:100930003E5C21F84C9D6247FCF7570489CFF8B51F +:100940009DAB319E9CE6626DA867B58FE7F4A2A6C9 +:100950006BC467AC157EC22B199FA8CAE6F7E6E206 +:10096000057EA9836BDFC2F1930FA85E8C6FDF8BCE +:100970005D816724A2AC443D628C85F2225A945A70 +:10098000F27B342B1EFA3B1EC9C3DCA41F3D9DEC39 +:10099000FDC35CCA0FE57F6F64DFB4EFA6E3FAEE38 +:1009A0005EBD3A1DF5C08C093C1F71D3B453950848 +:1009B000675B1EE87F0A9586BF4B2BCB8F26F038EE +:1009C00009F005CA4784756FA1F8FB603BF9D9545B +:1009D000ED81EF201F502F9B4278DDACB8E72DC092 +:1009E000F3CAB5931ED3903B6AEE22D8D7BA3EFE27 +:1009F000A61C3CD7E4C1B4CF86E4BE49A88FAECBD9 +:100A00001A48FA6793524BED812C0BBDA78AF8FC6C +:100A1000BADCEFBEBE18FD59D9FCFE674BEEA9D774 +:100A2000B15FCB18FEC76CCCEB55DDC67B52F8E14D +:100A300023E4DF6A7F0BDD2F54455C5C35C59537B9 +:100A4000C87D8AFB2BF1826F55E5AE994BDF4F488D +:100A5000B5BB11C91A13C3E5586FBCD3C6304EC716 +:100A6000ACCD063DAD7E95310E617519D7D3D475E9 +:100A70003FE1D5F9C8671A15510FFC82D7B19D9295 +:100A8000FEDAE623BE34C6F3FA35BF79723EC511ED +:100A9000C5FA6C727D7DF8DF5BF97430A3FB6D5590 +:100AA000B670D4EF0B5F685DDDC7DDA48971D9FF37 +:100AB000E6B84DB93C4E641E57F6339F9B6E1EA69A +:100AC0005CD23CA7CA09FF0EAB0CF98C793EF3FB54 +:100AD000F2BDAA3EB349DEFDABFAC782EBF2095D77 +:100AE0007FDF8575C52DC43D3B8F2E3E563F651477 +:100AF000DD8B6D556A896E02C996A8F9BFB1E947C9 +:100B0000373E0F8E10BFB5728833B52E9EF2382453 +:100B10003DC93C0F6BBA859E33311EF0E157491F2A +:100B2000D2BACE8BB9FB46C6552BECD4DF7C8FD81E +:100B30004CA7323F84DECB89B45BC5BCE6FC109782 +:100B4000C6BFB7D25AF900F9F32F354FE438D22790 +:100B5000C18D915DD8F05FCD942FC5DAF9F3867C15 +:100B6000377DE770BDEC97C828BF499E83539C032F +:100B7000137691CCBB89969783F65CBA84B9870DBE +:100B8000C67D36CAF73D3E0DF9E53D578CC8C7EF27 +:100B9000773EB873D313680F6DD9B5E67D2CE38724 +:100BA0008DA0EFA726782D5EBC9FE5BAB1BD1D399B +:100BB000E4DA618B9BE938F5E74AF75315CD0DFD73 +:100BC0001D2ED776E4BFCCA1D077AFD41FA605D118 +:100BD0006E4D5F64C48356C5DB17FF3E6660A3425B +:100BE0007A177E6F40DF6EF718EBC7262842BF34B6 +:100BF000DA31CD31EE750DD5B8DEAA9AEEB56EB20A +:100C000079E8FBB99BD6A9A40F6C1271A5F1DADDC6 +:100C1000F357036DDFDEC8FF9E706B893D88F75385 +:100C20005B13DDD7CDC5BA907F32BEDDFC8DCB82A4 +:100C3000FABFFB9439C14378B8B1A46F06E371F0F1 +:100C40000CDFF0D878F165CBFF0132DEFE59008071 +:100C5000000000001F8B080000000000000BC55BB7 +:100C60000F701CE5757F7BBBB777924EA7BDD3C9CC +:100C70009C8C6C56B6146490E5B56C9953B0A3BDCA +:100C8000D3BF9371E9C5FC3333B67BC6C6214D266D +:100C9000114E494C42AA333A59F21F84AC24953381 +:100CA0006D9AB30999CC8401259DB6860073024ADA +:100CB000288144492990690684096E483313A7C1E5 +:100CC00089D2A1A5EFBD6F5777BB3A59B6E34ECF96 +:100CD000237FF7ED7E7FDFBFEFF7DEFB6E8DDAFF60 +:100CE00072DB7A007855361ED6B104154C3FF0E71A +:100CF0000319FFD3F06F09007D857A2AC57B052093 +:100D0000FF810470F57115F2767BFCFB6E4718A02D +:100D10008D6A63905A8DC5E48D1ED800E0B7DA5C09 +:100D2000234FB6AEA0F95E93E1617ED20FA94AECE3 +:100D30004B9F8E42393480135C2DFA284B6855F84E +:100D400059017030B2F54734BCBBBD5DAAB969B377 +:100D5000BE85E681FEC966805551E7FAEC76A73A72 +:100D600070F13500BE1CE4BD412AF326B450396D44 +:100D70004A589EDBFE196DB3BEF03C3E281AB79E62 +:100D8000C603DEB75C4C3F7CEE853413EFFE8A96DB +:100D9000DB01F73D74830AB25482CE8BD455253FD4 +:100DA00025E13AC7EFBDFA468800640EC9D088E352 +:100DB00078A345EDF02FF5D47A9809887564F87911 +:100DC000D2243E053BBCBC5FFAF89730FF0088DFB9 +:100DD000FA8177641CEF4B49553F8CEBFD526AEF6B +:100DE000576EC17AF625D990F83DFE87FCBBC79AAD +:100DF00003C626581EAAFCA2FFFE53F7BDF922F136 +:100E000028A9BE457403AD882E2BB830FD1B0AF30C +:100E10003D183B3DB212E9901D293DFE1DD5FAA7B4 +:100E2000885E369D171AD77E2FEF9F9AEC5A57A8E7 +:100E30008F94A77798C887D180014074D8FF1CBFD2 +:100E400087F52897B50BF31329CAF47993BE62BBD3 +:100E5000AF759A7B4CACCBA770E96B00DEAED46F5C +:100E6000DC8AAFBA236FED20FAEF097834E2A3DD14 +:100E70007FF0A817F2012204CE8B72B70566766C5C +:100E8000C576D0E0653997236BF9F9EECA94E2C1D3 +:100E9000F2F3E60A9617BB7F1F7C59D987CFD77824 +:100EA000B557494EB211895684CF9180B8F4CD0A16 +:100EB00098412C7BF5B8BF1EC74D3E491301748481 +:100EC000C623E0016879E2785DBA99B6614E3721B0 +:100ED0007F4216BBAEF54DA73A71BCC19765E37E64 +:100EE000AC87027BB700CA91F4182E969E8720E744 +:100EF00043BE2B819E77E9F9A6B3005D45F2D4315C +:100F0000EB87AEA6423D8E2317D73BFDB58EF6DDAF +:100F10005ABDE3BD0CA691473AF5465739DA55B6A6 +:100F2000ADD768BD7DFA5AC7F31B9ADA1DFDA14BF8 +:100F3000393D83F58DF88FF82E83A8F37B5C77A07D +:100F400019EB45FD1528AAE3FBBF352B2367AEC57A +:100F5000CA75701DE911F2E5E411B23FDBFC06F140 +:100F600065D00BA7A42A20D5CF402B11DBD4234872 +:100F70003FC992D757CC7A960B29F0FC1F580E9F89 +:100F80009CF148C4D727A0F53036FA1B4D9FF2607C +:100F9000932B6948EC1F4541D7914F0D385E592B73 +:100FA0003F3757623D0A52A60FEBCBB05D54882203 +:100FB000BC40EDFC70E00BA21D2CA3761A64EAB0D5 +:100FC000AE19504E7CADC3713E19E67E993EABDF43 +:100FD00055A25FA62A2CC66FA179D15C76637902EF +:100FE0000CF0C9448714C04AB222FD5C5E45ABC216 +:100FF000E70F81D14AF5469861BB84EC97A87E053E +:101000004C6AC2C8E785DD9E514267FCC2EE97D2AA +:101010009782DE2870C6E607CDDB61FE80F4EFD64E +:10102000DBDBAAD28185FB29FB9F75E8AD1AD79936 +:10103000CECAFE5ED61365FFF3FCFEEA78EA551AC7 +:101040008F48EF6F9D4FEF16350F64BFB27130328E +:101050003844F6F1CDD15DC8DFCCE37EA3112E1F5D +:101060003F2E960F39D0CA89AE72FFA5F2013FB864 +:10107000AFC029FF89C32C8C269F937F045FFEE7B6 +:1010800052F8E2E607DC570DD0BEB81DFD6B295FB4 +:1010900026AD647A98D1D602FDB19E5965D12B6CEC +:1010A000F14316655EB69E2BE185F942E355870B49 +:1010B000FC598C2FD114BE6F2DF047EE379978F67E +:1010C000B9EC83B312952B2483F9B5524E79A85EFF +:1010D00021E52DD093633B1D048DF9B314FAB98C2F +:1010E000786776117FB2FB71229447781F4F59C2FF +:1010F00049D6B9980D24FCF5645F9B14C383F5E6CB +:101100004A4F2A8774BC52813CEDAF56810CD9738B +:1011100044063C7EF6713CADF09CC9E231EDA17E07 +:10112000F7FA7359A9307F8B65B77F54F94D6DA6D7 +:10113000B940E7D364BFD6087A78D8FE4CE6A97FD9 +:101140003409C6A03EDF9E61BB8C6CD9292A77D2B8 +:101150008B76A65B26887569E4FB7F209C41E3299A +:1011600058AF88A77BE3354C770884D92ECD5478C7 +:10117000A0142E300957ECB2E6D9F6117D790AD7C2 +:10118000B96BC4F7168D07599F1317B8FBEB1214F0 +:10119000F7B7FBCDC995BBFF25EA01ECAFB9201C21 +:1011A000107F6C6315D179419C497A525DDC4FF018 +:1011B000498DA41977A8A42FD58B8FE375E1177BF0 +:1011C0001C2F0A2E8DE3B5F08B7D4EED85B35E6549 +:1011D000A5B54EA4D76EB03F11A6E74E8B7E7F46D5 +:1011E000E75590E8A9AB44A43D9052496E3F861064 +:1011F0009A70FC8A437B828C17A04B23FA48F9EB48 +:10120000E50FAEBD083A5A74DA997FD7AB935DDA31 +:101210005F096FDBEF5714DEFF76FB4D8CDBD101EE +:101220006820FE5658EBAB38F5FE0019F5FB2BFE97 +:10123000F2E50E5CFAD0BFC8865C4FEF11CFE23802 +:101240006520CEEF0AD2535C77C59367FE9BDADB4D +:10125000EFC17A4F2343D1B89E8AA38C672B82AA11 +:10126000CE38DB2567368E86F7050E0E58D42B1A3E +:101270005722BC6CFB3D3CAE347FDED5163EC757D3 +:10128000F10F2E00CFBB713ACCE173F13E105085C7 +:101290009E1888738BE9B8809ED9EBB6FBD5A8A9B8 +:1012A0007AA3B9447F8B0FCD685708EF5D5107B91A +:1012B00003B8DE91917DF10AAC1FAB01DD87AF86EB +:1012C0007B3E2B11DE4844842885620217D21434F9 +:1012D000BFD79A2FF40BFD7013BEDF5B173070651C +:1012E00070C5AF4C2D8EE3DC59E7374C7C9005F18F +:1012F0003E13F3087F3203AF101EDD63F1C7FBA47A +:10130000C099CC1BD4C399B8C0577B4E7D720BF1EA +:1013100077347CB391C7767BD03E55131E1BF332D6 +:101320009E435CE7C0FDBE58110EC4BF3B8F7B1DC2 +:1013300075AF0B27BE19471C48CCB470E02FE320D3 +:10134000E6C582CE93CB350F04226C4F572BD31EAC +:10135000ADC4396BF3C3C6DF4FD5083A7BDF1374D6 +:101360004187791F3DF7BD27FC3134E081B62574F4 +:10137000FA0BFAF9DA903EF4F43D711E604F5EB755 +:1013800089FF68DD6E3CEC73E161F77A6D3EC80958 +:101390000B276F800D441FC4E78C13ECFDB8F7F1E9 +:1013A00024FAE75D28144F0FF8B9CC0F685C3E3380 +:1013B00010E5F2B9011DBA10803D3FD0C4E50B0322 +:1013C000063F7F7120C6A54D87F9F44129C4FD5E13 +:1013D00065AD59699E4ED139BAB4CBC3AA70EC3E03 +:1013E0000FD3ED1CCA27295F10BD2005977855D271 +:1013F0009333692F96FF738525AFD7FACE4EF9B098 +:10140000FD682D18F763FF2B627B59CE369DF514CE +:10141000F404C8CF2977C409E250EDA877FAAF7475 +:10142000B4EFD6563ADE87E3336CA77AA3D73ADA1D +:10143000D97CFE3AF959B8BE635DA735A26B9FBE51 +:10144000CED14EB90FF9DF42FECFF58E7141DE628B +:10145000909D0E6F77CA61D0C557F5AEF3FB41364C +:101460009FCD84530F16E2AF5B5E6DBA86E7E82A24 +:10147000FCCA2CF99548D7B026E86AEF77D4DAAFE2 +:101480003DAF1213FBBBDCFE6590FCCBFA52FEE5D0 +:10149000CF2D3A2FE25F269DFEA59BAE8BF9977F5D +:1014A0009E70FA97174ACF9DCB45DC2DFC92CC7EDF +:1014B0008B9CECE773B07A5A367AC9245AB8AC924E +:1014C0006C00B6DBD9A6E608671E8399289DE70F56 +:1014D0004A485594B7EA66A396ECCCA321E3D56DB0 +:1014E000841BFB3CC649ECF26CFCD628E18EA103C0 +:1014F00027A27858C103090FCF3B163FC3F10B4514 +:10150000078E5F6069E64AE013BBFD3D435E3E0F18 +:101510001EDCA1E6246CFF60A576EB36AA5BF32007 +:10152000414C7A3FD1F6A11CF929A309DD8A336524 +:10153000A2E4AF7C69C7865A3EAC14ACAFA6E606FF +:10154000EBC9E1322D487E74768747A37DC9EBFF56 +:10155000EA33241F0F48FD871AC87FABF1009D1F97 +:10156000D9D086DA5DD84EDE893086EA3B36BC4E6D +:10157000367BA2463FD440FD430D4CBFA18DB7FA48 +:10158000699ED1D0923E8A8F8C767B984732E18CCF +:10159000208FD3743EBF47D68ACE77E0B805AF53CD +:1015A0008E78F22A9D57843F82F3E37B87432A3962 +:1015B00005F08F895B4E641AF831DBAF2B2C3F604E +:1015C000E78E84C9F68AF004D267A777A6A6D4B9B5 +:1015D00070D08A77CE9D3B51E77A4ACCC3B8401190 +:1015E00033F247B7E3B4F8C9DED893A373741C523F +:1015F00049B29F998087E31D0BED5F0938E7B3C7B8 +:10160000E7F1648AA395996545FBD7ACF8EFCB0960 +:1016100089F1EA0F89EF6D62199125857529490FC6 +:10162000F7B3FD5794DB6D93240F16BDD1AF78BE91 +:10163000F8BC7D2D21E2B2AFCFC911365D52B48E18 +:101640008DAA359EC1718A35AEF8B59B3F171BBF79 +:10165000FEA5B59FD7B6DF745E3F7955CED9CFD7FB +:101660000962FF56BCDB6BF1FF1A79721FC9E3FFF9 +:1016700077BCDBD77979E3DD6F937D229C8776FE9B +:1016800061FC9EFD698EF5054E9D7D9BF57AD51218 +:101690000BBF40B4C1C68F2BA874E90F017DE4DFF6 +:1016A000F85AC4A5581FB7EA99D5625C28D6CB155D +:1016B000E4178838CAB2CE95C2DF227B42CC558C63 +:1016C000E544D780F29D8C86FB280F1C831096BEC4 +:1016D000C8AE0C951DCBF5D118AE6B7C9587CFAB02 +:1016E000F1CAF489215AFFAA4049BD68EE14F66F89 +:1016F00084E495FD24303DA46F92AD1C90F6209FAC +:101700002640F0D9EC0CF17A146D2C7607CA4DCC3A +:101710009207DC0FF7778FFF611ABFCD31FE374894 +:101720004EB3D6E034CE2E1C27DE29D97A95A1F708 +:101730007E6B3EBF3E16235C90E8D4C47B65AD4112 +:10174000FA301E2A3D5FC29A0F2814B3A1808FAED3 +:10175000D82EC601BFE8FFA07476DBE9F5CC57D6DA +:10176000275A07BDAF309CF6C13D7E5993D3BF5178 +:10177000EB9CED5373FB70FA450F48A5D77BB7D5AB +:10178000BE63B99033928FFB4BC8875BDF558A7B72 +:10179000E2B869E207DB0F617702CA7482FC9D4000 +:1017A0003318834CE029DE6FEAA9865333EBC9CEA8 +:1017B000070DF283143F9ACAD6829FE8DEF7627E55 +:1017C0009EA240C6DB3ADFDFC371CDAA5671CE645C +:1017D0008AC6FB8C252772B13F584FEE887E23EDD9 +:1017E00073EC90CCF1A5B17B7DDB4A9DD3F726CE7F +:1017F0009FD7399E423F829CD4C78E1EDA8DF5DF7B +:101800006A1ECDC76DF492791DCDAACFE57552172A +:1018100096D719EB0AF7355C4C5E678171E7CEE32A +:10182000F9799DE39D48A76301915F99CBEBDC1C9F +:10183000B9A0780E58E772D8B2CB957D961FB15FEC +:10184000623FE299B67F3FB286E4ACCDCB720047EF +:1018500027A0584FB66CD7BF5A4DE7CCEB3E681463 +:1018600076CDA4F16CBFD8A69F6A8D9FF8F64B0A7F +:10187000B51FAFF56CE0F120EFF344793DAA55CAEE +:1018800054AE51F372158D1B06439C0F79899EC788 +:101890009158C5FEC1E8EC4F3AAB284E1200834C7C +:1018A000D0685C3B50455F280B4478A75ECF91BD64 +:1018B000EDF45738ECFF689F2AEC6B23FA4BA43FFA +:1018C00053FA57F760FBE1FD658C9B1EA8F308FDFA +:1018D000CA4839A99EF0B5D3EF199F5C21F0D851C1 +:1018E000AFD188ED1F9914ED77C737E464C6DD4E9C +:1018F000BFA84F77FA45BB6B5B5F25BC08435E8E84 +:10190000C76B16AEBDA1C9E92755D6F7BF403865EC +:10191000E790C0C307A3E125BBD1FEADEDD21D7991 +:10192000B25D437772DE684805CEA78EEE50593F10 +:1019300046BD6F1DDFCDB8B19CE938B143AD4D1741 +:10194000E9CBC7BA7C3CCEC40E813F105EA6274BC4 +:10195000BCFF589765A714E073DC96973FF9B8A0D1 +:1019600073B00E723AE1B8BE7D79F22BC7EB704FBF +:10197000F87E28DAD03745F3BF2203EDD32D87F761 +:1019800090135CB40F5FCCE3A093D797EAA7F1E183 +:1019900006D0C9AE7525B14E7180ED2A507CC017B6 +:1019A000FD0BDE6F18EB6558F727C7320AD6FD0D21 +:1019B000E975848B9FBDF7B6917884CE3BA1DFBEDD +:1019C000ED7B533751FBF55E28A3F5812E45697DEC +:1019D0001909449EDFA90F07B3FFD4457C3A684834 +:1019E000CCA29D7D5BEFA2F59C8B94336E1AF3A67F +:1019F00076B13DBAC5AF65F80C9C613FC2FB051FCF +:101A000090DC4DDCFB4E0DE1EFABBA56B0BE95E974 +:101A10004EFFDA0F637C6E6F34A7B753BF8D3195DD +:101A2000321EF04CFB19E6DB449BCFF0E13A26DA9C +:101A300025A6F3EFDABC399AE769755AA6799FFEB5 +:101A40001DCE5D5F4ABF4BEB95AD47EEF6A3B1AD42 +:101A50007E928B83307D33D127332BE254EE76DFB9 +:101A6000B0E4E060F6962685E3592AE7DB95B38675 +:101A70005985A3876653DFA2D8EB2B9D0AB7BBA776 +:101A8000D6939170BCE13E95F568B8323D42F23C88 +:101A90008C72CF7E5204EBA467B511E370D17CE366 +:101AA000EDB736913D7BB9AD8CF1FD6BCFD6DE91B4 +:101AB000C12113F2AFFEEE31F2ABEA54E6E7B0B764 +:101AC000FF75F283326D65BCDEE796A9E0277B10D7 +:101AD000B9E321F2B3E191ED502CAF1349A1A71363 +:101AE0007542EFA5C7B6B31F302EC94C67B3E6A445 +:101AF0004478CC97B4E34E22CE14B7CCD9C4F6EFD9 +:101B0000721C6A699F88A3C69356BC490E64582EFE +:101B1000AF2B7B88F4DF54BC0EFF78D359A7BFBC32 +:101B2000D4E52FBBE3515BBBAC78841577B2E532CB +:101B300068B5998859767ABD2F27E4B0BF566B9E59 +:101B4000AFDF3FB4F0F3F4801F2502E027031AD77C +:101B500083E66F0E54139F06A2FCFC4F379E908ABB +:101B6000FB8DAEBFC5AFB33D9989D2B86E3BE2964F +:101B70008B373ACB1DE789BDCECAF60410EE3D7710 +:101B8000962D326C0ACC74F2D908D38162BC9FA71F +:101B900075FA284E26D6F91CADD3477132B1BE175F +:101BA00006742E5F1C68E2F23B5D20F201B67DB840 +:101BB0000AED03D2A1AB4ED4C91E10FFC3913B382E +:101BC0004EE68B2A1AE9BBBF6E2C2F15D98789CA1E +:101BD000FE9FDE4976BF26C0F2E8DED7B1AE397C83 +:101BE000E8D8D7CEF67D6C77CEE13C447FB433772E +:101BF000B11D42BBC0F36E576FE775986897D82E3A +:101C0000F47FF536B60B5E203977DB817046E877D6 +:101C10005A17F13BFB9ED09C5DC0797238CF336878 +:101C2000D7A93E8C7680E6196E7FEB1334EFEFFE7A +:101C3000500E34C4C48E57D92EBC7C0EA0FA32DAB2 +:101C4000055B0FD73DF71F27324A293E6FBDED9444 +:101C5000A0870682AEDB5225FCC48BE5339817863D +:101C60006372CACCED22EFA8321D16CC3B663C064F +:101C70008505062795A4957704CA3BDAF9C7A2BC67 +:101C800063B933EFA8E6B28C6F7256DEF1D6CD227F +:101C9000EFA896CF040AEBB0F38D43F4A8B6909F5B +:101CA000FF87AEF4CB5D6D853CA32E893CF8D571E2 +:101CB000F387F41C22613EFFDD794A3B1F89F04E19 +:101CC0004A17E5375BF0B93F5CC87FB9F399F6BDB9 +:101CD0008C1675E6E411A4CBE0ED7EC60FF6FA068D +:101CE0001FFFF0EBE948E13E809DEFB4F39976DE0B +:101CF00013D7FD4EF1BAE14960BB034FF84FD0F95D +:101D0000E65E6F453CFD4B6A3F6FDD17985FDC0276 +:101D1000D6F888BB489FDFB4E838D7BE4BF89F6B36 +:101D20005411DF86A0CAFE4EE2DB0190096757AA74 +:101D300027492F76C14C37D1773024705EF6012FBA +:101D4000DB49E8D6997F35AAC9F7216A3E5F661C50 +:101D5000C0C7D9292D48F1A7AF759AD0DD46EB1839 +:101D6000BB792BAD03713BD9BB371ABF12E17C3F66 +:101D7000DD7BAA22FFCF584E7110BDBBF47DA58E2E +:101D8000E567B7F2BC951E20FF2C5B66BCA013BDB7 +:101D90009F5278BC3E1CC26CE5FB4B5D6A98C61135 +:101DA0007EF260E034F3ABA3D1B796E37A95A5FD5C +:101DB000C0A5DD820E9B712C15C7792A9EAEA57534 +:101DC00053AC34CA722CFC3BBD1B6CFB759F674344 +:101DD000210E5621A7F56EB2D78F480A9D8F3E4B34 +:101DE0006E6C3FB13B61D6770B7E9834BF7D0FC8D8 +:101DF0009EFFEA6E61175FE9323F44EDDA681E929A +:101E00004B2D13273D6C49A33C48AC3FAE3CBC90E6 +:101E10000BB7BCDAF2369787B7E450D244BE16E56A +:101E2000AA8DF6074FEB531E89F2EDE91347A8EF91 +:101E300025E6BB3F9D3037D1BA77C7531D54BE71DD +:101E4000EF6DC0799D0BBCC7D1B1BC3F4A79FCE1B5 +:101E500032819B1F8D1B0E7B77B7459FBBBB055EF9 +:101E6000BA1665669AF44031AA80F5F82EC6D1B646 +:101E70007D1A1B487FEFE78D85FED90198A47CD0A1 +:101E800042EBF01EDAC771DDC1BA849FEC0FDAB7FE +:101E90002AAA0FD799D1E275642B859C679689B8D9 +:101EA00005C5D332BEC2FBBDDD32EFA7B30EF224AF +:101EB0003BBE80C8BBF95071753C7F7C662CCFB8A7 +:101EC0002600931462F814E90FDDFF8B186092BFAF +:101ED000599702D26F9F56E84F79D4CEBA7EBE6F23 +:101EE000B9D03872D4EE9FE6FEE3DD1A8FAB463CE4 +:101EF0008E38C0627473D36588E8D6B830DDD40BF1 +:101F0000A69BD03B37BD0E13BD909FCF863ECBFB2B +:101F100083F73B59CF7C1AEE13CB31CBBEC80113EC +:101F2000D29564A352882029CEDE0F9487B6E92C7F +:101F30006B82CEB2D6CFFD7C7506A457135DD24C12 +:101F400017371DD04E00D9897F7EFC7884F0690751 +:101F5000D6A3C27E800FCB5F5BFEA0ADA75BE0C7C0 +:101F60000111FF769E17F3ECA9553E6AC59FDDCFA0 +:101F70006FE92913B84E0707DD2B2BB7323F4E8E82 +:101F8000B4323EC0F33343F7627A6A1BCBA97EB901 +:101F9000F388EEFCA13B4FE8CE0F16E4C6F4D33A2B +:101FA0007FAB9DCE7CB484BCD8E5114BDF8606FCAC +:101FB00025F5EE08EA3BF16FB8DDCC50DEE860684D +:101FC00026CA7233F52EE362E525D9207CA9288242 +:101FD000CF3DCB66988FBD311328DF746460DB770B +:101FE0008AC7FD753CFD23B26715DAA449E30420D6 +:101FF0009FA1F36773B5D95F0A37FD9B6547BA1395 +:10200000A97F257BD5A10BFEC7E2E6AB6C172FD0CD +:102010006E2DA44F8A4DBB8BD6A7D3429F62FB582F +:102020009F46EBFA19678DFE58262455C091963EBF +:102030008DB69F617DB7F5EA3D4B9F3A63422F28ED +:102040008E40E777B0CE64BBF15F963E29A827A407 +:102050004F3E4B9F825AA13DC5C73B89CEF85CA934 +:102060009BE17EC198A57FA44F01BA3F0C8C0386EB +:1020700051EF282EE2D6AF8E06716E6A89B4A7871B +:10208000F0C5B2AD1C971FAEFBCF6AC62F96FC17EA +:10209000F06E2B9FE7E7463C06E9430B01E8D6824A +:1020A0001ED8FBDE382B431E59B36956E2F223B328 +:1020B000155C76CC967169CE5673199F0D719998FF +:1020C000BD92CBCED95A2EBB66510FD621DF67EB1E +:1020D000B9EC99BD96CBDED9555C2667D771BBBEEE +:1020E000D9B55C6E9EBD9ECB1B66DBC53C4D625F69 +:1020F00025F481D26097411F8C0C54921E7CFC7594 +:10210000B6EF9ACA7794B2A10D9C27F22933AC0F8F +:102110002763C2DEF706049FDCFAD09D48AF25BADC +:10212000BBF5610EDF2AA011FD55B03E2EFC80F8F4 +:10213000A7BDA7E83EB21A3559CE109F7CB887F4E8 +:10214000E31271C21CCE5CAE321EB571E6E832C439 +:1021500099F5059C39DC2EFCB2EC033EF6DF764B9C +:10216000E27ED9A713E91B7BD82F1671A2F4CD7E8E +:102170008D707336D4130D505CEFA00C142F401CDF +:1021800092E2764A4ADC67BD407D8EC5857ED8EDF9 +:102190005BE0B4A7FF2270CC1BF4B57D61BB10BE21 +:1021A000D473D6DB29EC8226EC42B6AE7F84F3D220 +:1021B0002EBB609FB3480F875DF85C8F854B2C3D2D +:1021C0000FD789F3324C7601E9F3C51EDB2E38CFE9 +:1021D00059C5C621491B8758762129FA216E779C5B +:1021E000B3C86E3F14E16294A3C19EB6F9F681CFE5 +:1021F000F3A2736EB0A1314EBF25089D8538896763 +:102200007056DF6C943877B25A2BEBC194D209C563 +:10221000F1958BD6B3907DEE987CEEB8DBD9FA368B +:102220003CD527F6699D4353B87FB348DF7A3571B3 +:102230001EE1F9F3F59E12E74FC772339D2AB1CE26 +:10224000477B84BFF1834D16EE455C690418DF9728 +:10225000C40D8FF608BB4EBFD37802ED4F77329393 +:102260005574D6F34749CE37764DCB1446F8486CB3 +:10227000EC154A89A09E3EF6C7E8E9D1B895EFDB98 +:102280005F2D2E3B5BE562F26FE3225B0FE6EDA371 +:10229000DEDC568A1E4B7B05BE1F1CF1F4D1853F48 +:1022A0005B2EA694958C7F4AD85BD3B82CF6F6C2E9 +:1022B000F0C7149E83C4F7F3E08F374BD9DB85F06A +:1022C000C7991E912747FCF10EF5EB6816F8636974 +:1022D0002FFCDFE08AF869A6DBA5E28A0F6CFBB170 +:1022E00000AEF0F6EAE27715DA0CDB8FE025E20AC1 +:1022F000B79D40FC50DE4BF431C4B96BFFDE842F38 +:1023000050169D5F6867AA7A055ECFD3E5B19381C9 +:102310004446623D4885E8F998B982E5E872E903E8 +:10232000E2C42B7B8BEA8BE9C505B79BDCC171400E +:102330003B9FF9FBB2600BC547F6FB45F9B9F2E0EC +:10234000492AC707441C7A94E27E588E7B81F307A2 +:102350004352B97152A27ECB7322DEDEBF86E29E6B +:10236000D7F786AD7872FF75FCBB1BF8A2236FBA56 +:10237000F0BAC43D5F1AEA03BE0F5EA7711CDDA26E +:102380004B981880F31E5EE5671C78B8EF91E377F1 +:10239000505CA64FC4C140D1EB3F4AE72FC29A58C8 +:1023A000D1B920837286E2F32374B79D41C7367199 +:1023B0000FDA5A4F7512FDF722FFA32A76D7F77E60 +:1023C000EEBC37E429CE231F31B75689CBCA77F14B +:1023D00038B69E1C094CFAB5227B7374C079FFC9CC +:1023E0005DCA6DAFF07DC3634D0AE72F1E581F29EC +:1023F000233D39D42082B4E58D9E54AE843E0FF443 +:102400004A8EB876C83AE7CBBAC5BA169A6F784002 +:10241000C46FEDBA4F4F9924A7E5F56329A26B79F4 +:102420006344A2F8ABFDFEF65E61370E4B46BE0379 +:102430008979B8529C17BEBA0C78080F84F6AE237F +:102440001AFBEBFAE14C80EE6F64E06D2CC3613552 +:102450005D6ADD83D6BA0F7B7329C2538757299CE7 +:10246000E7444C55324EF609CB4E97378EF3FAA01F +:1024700051E17C95BBDD0EBB9D3AC6F98E438DDFE5 +:10248000D4695F87E807374B914BC9871F3A40767D +:102490006600F9EA25794E73597ECDB798FEA32DD3 +:1024A0008A46FBE8969B0FD03CC79260105E71CBCA +:1024B000C531D0CA687CB77C54AC7E8FE34FE54110 +:1024C000CA8C901CCEF8851D157216B0F8336A8838 +:1024D000BCCF684AE4AF6CFE15DE8BFB06E7520A00 +:1024E000FB2576FE6A0940491C67EBE590158F9F36 +:1024F000F77E799ECF9DA39BF251BA2711D4FC465B +:1025000092C67DC4B9AE837876F2BAFA44FE62CE42 +:102510003EAF15FEE1FC758AF881F2CCBBC2AE5A23 +:102520007E42B0F93DB6ABF6BDAFDE8D425FABACDF +:102530007BF755919429E872B7C31E48D7FC224314 +:1025400079A6076BC5DD84F04671AFB65C05234FF5 +:10255000F700FA027CBF6949CCCAD76D13F72BECA0 +:10256000FBE16A4475C41322505427DCE9AA83BCFA +:10257000FDBCF7E0F6FFECC48BCF15F1FDA55EE7DF +:102580003DF2C5FAFF7E20F7E27368908E19E7D717 +:10259000479B6F5F1E887169CBA52DA761DA62EB3F +:1025A000C2FDC743A992799A6052E8C362762DE2D0 +:1025B00033DBDF41BE7BAB81F3675FD9E41CEF37D0 +:1025C00096BEFEC6D22F7539D4129E1A0B093B3027 +:1025D0005606DBBE5B426F972455B61B057D70E245 +:1025E0000A5B8EE6D363115CB1BA4BE00A2D5C4600 +:1025F000B8E898917881F281EF69AA5E2CB7EEB8BD +:10260000BB8D2BD2493BFEA74A840BB4C00CE3ED33 +:10261000395C60E108372E28F7E6B6917E94AF5218 +:102620006D7BC576E5F3DFFFFB8732BCBF8C547C46 +:102630008E8EE66FE771C3AEB83B449CBF63798B67 +:10264000F017AE27AC4F4E2728FFB84511BF6F1BC0 +:1026500033A1F81ECEB8E7FDD83BD6F7F76D1C5274 +:102660004FEF8F4EF3EF6BE01E289EFFE04D3BF9DE +:10267000F7148BF1DF5E17DDEB2AD69F8BD50F2386 +:1026800069E9471994917E9C83FB380F0F6349C712 +:10269000F9C41989256C12C407B7A96CB0A082547B +:1026A000D01BE8B5F2E3E9393BA9503FC3EA564BEA +:1026B000B72C64CA37E4F9778BB6BD39073FE379A5 +:1026C00033CF48D21CEEBA12DD7FFA3DE44A5A827B +:1026D000E6A1D2BDFE1560F0F3064871F921E8E7E6 +:1026E000B209C6B8BC0626B96C86692E5BE02C9789 +:1026F0006B419769927560CAC05737D35CBF0E3281 +:102700005CB643BA9DEE970FD5EC5D4BE7D12D2E0D +:102710003AD9742EA1F78C2B6D7AD8742F27E35DEC +:10272000B3385FB321618F3B6379F61F0201819B50 +:102730006D7FDB1E67211C7CB9F09A8D33FF17CFAC +:10274000A588169043000000000000000000000073 +:102750000000001800000000000000000000004021 +:102760000000000000000000000000280000000041 +:102770000000000000000010000000000000000049 +:102780000000002000000000000000000000001019 +:102790000000000000000000000000080000000031 +:1027A0000000000000000000000000000000000029 +:1027B0000000000000000000000000000000000019 +:1027C0000000000000000000000000000000000009 +:1027D00000000000000000000000000000000000F9 +:1027E00000000000000000000000000000000000E9 +:1027F00000000000000000000000000000000000D9 +:1028000000000000000000000000000000000000C8 +:1028100000000000000000000000000000000000B8 +:1028200000000000000000000000000000000000A8 +:102830000000000000000000000000000000000098 +:102840000000000000000000000000000000000088 +:102850000000000000000000000000000000000078 +:102860000000000000000000000000000000000068 +:102870000000000000000000000000000000000058 +:102880000000000000000000000000000000000048 +:102890000000000000000000000000000000000038 +:1028A0000000000000000000000000000000000028 +:1028B0000000000000000000000090000010000078 +:1028C0000000000800009008001000000000000256 +:1028D00000009000001000000000001000009DA803 +:1028E00000000000000000080000000000000000E0 +:1028F00000000000000000000000000000000000D8 +:10290000000000000000000000000000000091A096 +:102910000000000000000008000093C00001000457 +:1029200000000001000093C8000000000000000249 +:10293000000093D00000000000000008000093D4C5 +:102940000000000000000002000094980000000059 +:1029500000000008000093D80008000000000008F4 +:1029600000009B3800400000000000400000941868 +:102970000008000000000008000094580008000053 +:1029800000000008000094A800C8000000000098A3 +:10299000000096380098000000000028000096789B +:1029A00000980000000000280000C0000540003032 +:1029B000000005400000CB200008000000000001DE +:1029C0000000CB21000800000000000100002008EA +:1029D00000100000000000100000200000000000B7 +:1029E0000000000800009D600008000000000002D8 +:1029F00000009DA000000000000000010000000099 +:102A000000000000000000000000000000000000C6 +:102A100000000000000000000000000000000000B6 +:102A200000000000000000000000000000000000A6 +:102A30000000000000000000000000000000000096 +:102A40000000000000000000000000000000000086 +:102A50000000000000000000000000000000000076 +:102A60000000000000000000000000000000000066 +:102A70000000000000000000000000000000000056 +:102A80000000000000000000000000000000000046 +:102A90000000000000000000000000000000000036 +:102AA0000000000000000000000000000000000026 +:102AB0000000000000000000000000000000000016 +:102AC0000000000000000000000000000000000006 +:102AD00000000000000000000000000000000000F6 +:102AE00000000000000000000000000000000000E6 +:102AF00000000000000000000000000000000000D6 +:102B000000000000000000000000000000000000C5 +:102B100000000000000000000000000000000000B5 +:102B200000000000000000000000000000000000A5 +:102B30000000000000000000000000000000000095 +:102B40000000000000000000000000000000000085 +:102B50000000000000000000000000000000000075 +:102B60000000000000000000000000000000000065 +:102B70000000000000000000000000000000000055 +:102B80000000000000000000000000000000000045 +:102B900000000000000012C800800000000000805B +:102BA0000000000100000000000000000000A00084 +:102BB000071000000000071000001EC80000000001 +:102BC000000000080000AEC000080000000000087F +:102BD0000000AE4000080000000000080000AE80C9 +:102BE000000800000000000800002008001000009D +:102BF000000000100000200000000000000000089D +:102C00000000A01007100040000000400000AF408E +:102C100000080000000000010000AF4100080000B3 +:102C20000000000100001ED00000000000000001B4 +:102C300000001ED8000000000000000200001EDAA4 +:102C40000000000000000002000012B000080000B8 +:102C5000000000080000000000000000000000006C +:102C60000000000000000000000000000000000064 +:102C70000000000000000000000000000000000054 +:102C80000000000000000000000000000000000044 +:102C90000000000000000000000000000000000034 +:102CA0000000000000000000000000000000000024 +:102CB0000000000000000000000000000000000014 +:102CC0000000000000000000000000000000000004 +:102CD00000000000000000000000000000000000F4 +:102CE00000000000000000000000000000000000E4 +:102CF00000000000000000000000000000000000D4 +:102D000000000000000000000000000000000000C3 +:102D100000000000000000000000000000000000B3 +:102D200000000000000000000000000000000000A3 +:102D30000000000000000000000000000000000093 +:102D40000000000000000000000000000000000083 +:102D50000000B00000180000000000180000B300E0 +:102D600000400000000000400000B30000400002EE +:102D7000000000010000B30100400002000000005C +:102D80000000800000400000000000400000000043 +:102D9000000000000000000000008000000800406B +:102DA000000000040000800400080040000000044F +:102DB0000000BB0000280000000000280000BC400C +:102DC00000100000000000100000880000800000DB +:102DD0000000008000008800000800800000000261 +:102DE00000008C00002000000000002000002008EF +:102DF0000010000000000010000020000000000093 +:102E00000000000800001108000800000000000891 +:102E1000000011680008000000000008000011A870 +:102E20000008000000000008000012700008000008 +:102E30000000000100001271000800000000000105 +:102E400000008D00001000040000000400001320AA +:102E50000030001800000010000013280030001897 +:102E60000000000200000000000000000000000060 +:102E7000000000000000000000000000000011E859 +:102E80000000000000000001000000000000000041 +:102E90000000000000000000000000000000000032 +:102EA0000000000000000000000000000000000022 +:102EB0000000000000000000000000000000000012 +:102EC0000000000000000000000000000000000002 +:102ED00000000000000000000000000000000000F2 +:102EE00000000000000000000000000000000000E2 +:102EF00000000000000000000000000000000000D2 +:102F000000000000000000000000000000000000C1 +:102F100000000000000000000000000000000000B1 +:102F20000000000000008308008000000000008016 +:102F30000000000100000000000000000000200868 +:102F40000010000000000010000020000000000041 +:102F50000000000800008D100008000000000008BC +:102F600000008D7000080000000000080000845080 +:102F7000046000280000046000008EA0000800002B +:102F80000000000100008EA1000800000000000108 +:102F900000008408000800000000000800008448C9 +:102FA000000000000000000100008DF40008000097 +:102FB0000000000200008DF6000800000000000282 +:102FC00000008E040010000000000004000000005B +:102FD00000000000000000000000000000000000F1 +:102FE00000000000000000000000000000000000E1 +:102FF00000000000000000000000000000000000D1 +:1030000000000000000000000000000000000000C0 +:1030100000000000000000000000000000000000B0 +:1030200000000000000000000000000000000000A0 +:103030000000000000000000000000000000000090 +:103040000000000000000000000000000000000080 +:103050000000000000000000000000000000000070 +:103060000000000000000000000000000000000060 +:1030700000000000000030000040000000000008D8 +:1030800000003008004000000000002800003390DD +:1030900001C0001000000008000032000020000005 +:1030A00000000020000037200000000000000008A1 +:1030B0000000102006200038000000080000A000DA +:1030C000000000000000200000003EA900000000F9 +:1030D0000000000100003EC80000000000000002E7 +:1030E00000001C4000E00008000000080000000094 +:1030F0000000000000000000000040000008000088 +:103100000000000100004001000800000000000174 +:103110000000404000080004000000020000406081 +:103120000008000400000004000040000008000047 +:10313000000000040000400400080000000000043B +:10314000000040400000000000000008000040486F +:1031500000000000000000080000800000000000E7 +:1031600000000010000050400001000400000001B9 +:103170000000500000000000000000200000500887 +:1031800000100000000000040000500C00100000BF +:1031900000000001000052C7000000000000000114 +:1031A000000052C6000000000000000100003000D6 +:1031B0000030001800000004000030040030001847 +:1031C0000000000400003008003000180000000279 +:1031D0000000300A00300018000000020000300C2F +:1031E00000300018000000010000300D0030001811 +:1031F000000000010000300E003000180000000147 +:1032000000003010003000180000000400003014EE +:103210000030001800000004000050000100008091 +:1032200000080004000050040100008000080004B1 +:103230000000000A000000000000000000005068CC +:1032400001000080000000010000506901000080C2 +:10325000000000010000506C01000080000000022E +:103260000000506E0100008000000002000050705D +:103270000100008000000004000050740100008084 +:103280000000000400005066010000800000000201 +:103290000000506401000080000000010000506048 +:1032A0000100008000000002000050620100008068 +:1032B00000000002000050500100008000000004E7 +:1032C000000050540100008000000004000050582D +:1032D00001000080000000040000505C010000803C +:1032E000000000040000507C01000080000000018C +:1032F0000000507D01000080000000010000401827 +:1033000000100000000000040000409000100000C9 +:1033100000000004000040980010000000000004BD +:1033200000004110000000000000000200004112F7 +:103330000000000000000002000041140000000036 +:103340000000000200004116000000000000000222 +:103350000000604000080000000000020000604221 +:1033600000080000000000020000604400080000A7 +:103370000000000400006080000800000000000859 +:10338000000060C00040000800000008000060006D +:1033900000080000000000020000600200080000B9 +:1033A00000000001000060040008000000000002AE +:1033B0000000634000080000000000080000638077 +:1033C0000008000000000004000063840008000002 +:1033D00000000001000063C00008000000000002BF +:1033E000000063C400080000000000020000640048 +:1033F0000008000000000004000070000010000041 +:103400000000000400007004001000000000000430 +:1034100000007008001000000000000400007000B0 +:103420000008000000000002000070020008000018 +:10343000000000010000700400080000000000020D +:10344000000070400008000000000002000070440E +:1034500000080000000000020000704600080000A4 +:10346000000000020000764800080000000000088C +:10347000000070800008000000000002000070845E +:10348000000800000000000200007688000800002C +:10349000000000080000804000080000000000015B +:1034A0000000804100080000000000010000804290 +:1034B0000008000000000001000080430008000038 +:1034C0000000000100008000000800000000000271 +:1034D00000008002000800000000000100008004DD +:1034E0000008000000000002000080C0000800008A +:1034F00000000002000080C200080000000000027E +:10350000000080C40008000000000002000080806D +:103510000008000000000001000080810008000099 +:10352000000000010000808200080000000000018F +:10353000000080830008000000000001000080847B +:103540000008000000000001000080850008000065 +:10355000000000010000808600080000000000015B +:10356000000060000008000000000002000060028F +:1035700000080000000000010000600400080000D6 +:10358000000000020000604200C0001800000002BD +:103590000000604000C00018000000020000604C05 +:1035A00000C00018000000080000604400C00018BF +:1035B000000000080000605700C000180000000173 +:1035C0000000605400C000180000000200006056B7 +:1035D00000C0001800000001000066400008000064 +:1035E00000000008000066800008000000000008DD +:1035F000000066C000080000000000080000D9427A +:1036000000180000000000020000DE400000000082 +:10361000000000000000E0000000000000000004C6 +:103620000000DD4000000000000000040000DD4458 +:1036300000000000000000040000DD480000000061 +:10364000000000040000DD4C000000000000000449 +:103650000000DD5000000000000000040000DD5408 +:1036600000000000000000040000DD580000000021 +:10367000000000040000DD40000000000000002009 +:103680000000DA0000000000000000040000DA0082 +:1036900000000000000000680000BB6000000000A7 +:1036A000000000000000D000000000000000000446 +:1036B0000000B0C000000000000000040000B0C422 +:1036C00000000000000000040000B0C8000000007E +:1036D000000000040000B0C0000000000000001066 +:1036E0000000D6B000000000000000040000D6B4C6 +:1036F00000000000000000040000D6B80000000038 +:10370000000000040000D6BC00000000000000041F +:103710000000D6B000000000000000100000D348F8 +:1037200000000000000000080000D3580000000066 +:1037300000000080000000100000000000000000F9 +:103740000000D35800000000000000080000000046 +:08375000060022000000000049 +:00000001FF diff --git a/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex b/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex new file mode 100644 index 0000000000000000000000000000000000000000..78b41615e7d9b8049b4495e03b0751c2cec91e1f --- /dev/null +++ b/firmware/bnx2x/bnx2x-e2-6.0.34.0.fw.ihex @@ -0,0 +1,15442 @@ +:10000000000052D8000000680000070C00005348B0 +:100010000000318000005A58000000B000008BE062 +:100020000000C14C00008C98000000D800014DE891 +:100030000000F16400014EC800000074000240306E +:1000400000005250000240A8000000B800029300D7 +:1000500000012110000293C000000FFC0003B4D87F +:10006000000000040003C4D8020400480000000F90 +:1000700002040054000000450204005C0000000679 +:100080000204007000000004020400780000000078 +:100090000204007C121700000204008022170000F6 +:1000A00002040084321700000604008800000005E6 +:1000B0000204009C12150000020400A0221500009A +:1000C000020400A432150000060400A80000000489 +:1000D000020400B802100000020400BC001000007E +:1000E000020400C010100000020400C42010000030 +:1000F000020400C830100000020400CC40100000D0 +:10010000060400D000000003020400DC0010000020 +:10011000020400E012140000020400E422140000B3 +:10012000020400E832140000020400EC4214000053 +:10013000060400F000000003010401240000000098 +:1001400001040128000000000104012C000000004F +:100150000104013000000000020401D00000890603 +:1001600002040258000000360204025C000000365F +:10017000020402600810000002040264081000007B +:1001800002040004000000FF02040008000000FF59 +:100190000204000C000000FF02040010000000FF39 +:1001A000020400140000007F02040018000000FF99 +:1001B0000204001C000000FF02040020000000FFF9 +:1001C000020400240000003E020400280000000099 +:1001D0000204002C0000003F020400300000003F39 +:1001E000020400340000003F020400380000003F19 +:1001F0000204003C0000003F020400400000003FF9 +:10020000020400440000003F020404CC000000018E +:1002100002042008000002110204200C0000020069 +:10022000020420100000020402042014000002193D +:100230000204201C0000FFFF020420200000FFFF3A +:10024000020420240000FFFF020420280000FFFF1A +:1002500002042038000000200604203C0000000FAB +:1002600002042078000000210604207C0000000F1A +:10027000020420B800000001060420BC0000000FAA +:10028000020420F800000001060420FC0000003FEA +:10029000020421F800000001060421FC0000000F08 +:1002A0000204223807FFFFFF0204223C0000007F07 +:1002B0000204224007FFFFFF020422440000003F27 +:1002C00001042248000000000104224C000000004C +:1002D000010422500000000001042254000000002C +:1002E00001042258000000000104225C000000000C +:1002F00001042260000000000104226400000000EC +:1003000001042268000000000104226C00000000CB +:1003100001042270000000000104227400000000AB +:1003200001042278000000000104227C000000008B +:10033000020422C00000FFFF020422C40000FFFFED +:10034000020422C80000FFFF020422CC0000FFFFCD +:100350000C042000000003E80A0420000000000153 +:100360000B042000000000030605400000000D0003 +:100370000205004400000020020500480000003291 +:1003800002050090021500200205009402150020CD +:1003900002050098000000300205009C08100000D3 +:1003A000020500A000000036020500A40000003095 +:1003B000020500A800000031020500B000000004A2 +:1003C000020500B400000005020500C000000000A6 +:1003D000020500C400000004020500D40000000172 +:1003E00002050114000000010205011C00000001CB +:1003F00002050120000000020205020400000001C5 +:100400000205020C0000004002050210000000403E +:100410000205021C00000020020502200000001C52 +:100420000205022400000020060502400000000A28 +:1004300004050280002000000205005000000007B3 +:1004400002050054000000070205005800000000EB +:100450000205005C000000080205006000000001C9 +:100460000605006400000003020500D80000000635 +:100470000205000400000001020500080000000160 +:100480000205000C00000001020500100000000140 +:100490000205001400000001020500180000000120 +:1004A0000205001C00000001020500200000000100 +:1004B00002050024000000010205002800000001E0 +:1004C0000205002C000000010205003000000001C0 +:1004D00002050034000000010205003800000001A0 +:1004E0000205003C00000001020500400000000180 +:1004F000020500E00000000D020500E80000000019 +:10050000020500F000000000020500F800000000F5 +:10051000020500E40000002D020500EC00000020B0 +:10052000020500F400000020020500FC000000208D +:10053000020500E00000001D020500E800000010B8 +:10054000020500F000000010020500F80000001095 +:10055000020500E40000003D020500EC0000003050 +:10056000020500F400000030020500FC000000302D +:10057000020500E00000004D020500E80000004018 +:10058000020500F000000040020500F800000040F5 +:10059000020500E40000006D020500EC00000060B0 +:1005A000020500F400000060020500FC000000608D +:1005B000020500E00000005D020500E800000050B8 +:1005C000020500F000000050020500F80000005095 +:1005D000020500E40000007D020500EC0000007050 +:1005E000020500F400000070020500FC000000702D +:1005F0000406100002000020020600DC00000001DA +:100600000406020000030220020600DC00000000D5 +:100610000718040000AC0000081807D800050223E2 +:10062000071C000029B30000071C8000312E0A6D52 +:10063000071D000034A816B9071D80002E6C23E4A6 +:10064000071E0000034B2F80081E07F03F02022503 +:100650000118000000000000011800040000000064 +:1006600001180008000000000118000C0000000044 +:100670000118001000000000011800140000000024 +:1006800002180020000000010218002400000002EF +:1006900002180028000000030218002C00000000CF +:1006A00002180030000000040218003400000001AD +:1006B00002180038000000000218003C0000000191 +:1006C000021800400000000402180044000000006E +:1006D00002180048000000010218004C000000034E +:1006E0000218005000000000021800540000000131 +:1006F00002180058000000040218005C000000000E +:1007000002180060000000010218006400000003ED +:1007100002180068000000000218006C00000001D0 +:1007200002180070000000040218007400000000AD +:1007300002180078000000040218007C000000038A +:100740000618008000000002021800A400007FFFCD +:10075000021800A8000003FF021802240000000095 +:1007600002180234000000000218024C00000000D1 +:10077000021802E4000000FF061810000000040048 +:10078000021B8BC000000001021B8000000000342F +:10079000021B804000000018021B80800000000C3B +:1007A000021B80C0000000200C1B83000008647046 +:1007B0000A1B8300000001570B1B83000000055F2C +:1007C0000A1B8340000000000C1B8340000002262F +:1007D0000B1B834000000001021B83800008647033 +:1007E000021B83C000000226021B148000000001CF +:1007F0000A1B148000000000021B9440000000014E +:10080000061B944800000002061A1000000002B304 +:10081000041A1ACC00010227061A1AD00000000898 +:10082000061A2008000000C8061A20000000000276 +:10083000041A1BF800900228061A3718000000045A +:10084000061A371000000002061A500000000002CD +:10085000061A500800000004061A50180000000490 +:10086000061A502800000004061A50380000000440 +:10087000061A504800000004061A505800000004F0 +:10088000061A506800000004061A507800000002A2 +:10089000041A52C0000202B8061A405000000006B6 +:1008A000041A4068000202BA041A4040000402BC64 +:1008B000041A8000000102C0061A80040000000330 +:1008C000041A8010000102C1061A801400000003FF +:1008D000041A8020000102C2061A802400000003CE +:1008E000041A8030000102C3061A8034000000039D +:1008F000041A8040000102C4061A8044000000036C +:10090000041A8050000102C5061A8054000000033A +:10091000041A8060000102C6061A80640000000309 +:10092000041A8070000102C7061A807400000003D8 +:10093000041A8080000102C8061A808400000003A7 +:10094000041A8090000102C9061A80940000000376 +:10095000041A80A0000102CA061A80A40000000345 +:10096000041A80B0000102CB061A80B40000000314 +:10097000041A80C0000102CC061A80C400000003E3 +:10098000041A80D0000102CD061A80D400000003B2 +:10099000041A80E0000102CE061A80E40000000381 +:1009A000041A80F0000102CF061A80F40000000350 +:1009B000041A8100000102D0061A8104000000031D +:1009C000041A8110000102D1061A811400000003EC +:1009D000041A8120000102D2061A812400000003BB +:1009E000041A8130000102D3061A8134000000038A +:1009F000041A8140000102D4061A81440000000359 +:100A0000041A8150000102D5061A81540000000327 +:100A1000041A8160000102D6061A816400000003F6 +:100A2000041A8170000102D7061A817400000003C5 +:100A3000041A8180000102D8061A81840000000394 +:100A4000041A8190000102D9061A81940000000363 +:100A5000041A81A0000102DA061A81A40000000332 +:100A6000041A81B0000102DB061A81B40000000301 +:100A7000041A81C0000102DC061A81C400000003D0 +:100A8000041A81D0000102DD061A81D4000000039F +:100A9000041A81E0000102DE061A81E4000000036E +:100AA000041A81F0000102DF061A81F4000000033D +:100AB000041A8200000102E0061A8204000000030A +:100AC000041A8210000102E1061A821400000003D9 +:100AD000041A8220000102E2061A822400000003A8 +:100AE000041A8230000102E3061A82340000000377 +:100AF000041A8240000102E4061A82440000000346 +:100B0000041A8250000102E5061A82540000000314 +:100B1000041A8260000102E6061A826400000003E3 +:100B2000041A8270000102E7061A827400000003B2 +:100B3000041A8280000102E8061A82840000000381 +:100B4000041A8290000102E9061A82940000000350 +:100B5000041A82A0000102EA061A82A4000000031F +:100B6000041A82B0000102EB061A82B400000003EE +:100B7000041A82C0000102EC061A82C400000003BD +:100B8000041A82D0000102ED061A82D4000000038C +:100B9000041A82E0000102EE061A82E4000000035B +:100BA000041A82F0000102EF061A82F4000000032A +:100BB000041A8300000102F0061A830400000003F7 +:100BC000041A8310000102F1061A831400000003C6 +:100BD000041A8320000102F2061A83240000000395 +:100BE000041A8330000102F3061A83340000000364 +:100BF000041A8340000102F4061A83440000000333 +:100C0000041A8350000102F5061A83540000000301 +:100C1000041A8360000102F6061A836400000003D0 +:100C2000041A8370000102F7061A8374000000039F +:100C3000041A8380000102F8061A8384000000036E +:100C4000041A8390000102F9061A8394000000033D +:100C5000041A83A0000102FA061A83A4000000030C +:100C6000041A83B0000102FB061A83B400000003DB +:100C7000041A83C0000102FC061A83C400000003AA +:100C8000041A83D0000102FD061A83D40000000379 +:100C9000041A83E0000102FE061A83E40000000348 +:100CA000041A83F0000102FF061A83F40000000317 +:100CB000041A840000010300061A840400000003E3 +:100CC000041A841000010301061A841400000003B2 +:100CD000041A842000010302061A84240000000381 +:100CE000041A843000010303061A84340000000350 +:100CF000041A844000010304061A8444000000031F +:100D0000041A845000010305061A845400000003ED +:100D1000041A846000010306061A846400000003BC +:100D2000041A847000010307061A8474000000038B +:100D3000041A848000010308061A8484000000035A +:100D4000041A849000010309061A84940000000329 +:100D5000041A84A00001030A061A84A400000003F8 +:100D6000041A84B00001030B061A84B400000003C7 +:100D7000041A84C00001030C061A84C40000000396 +:100D8000041A84D00001030D061A84D40000000365 +:100D9000041A84E00001030E061A84E40000000334 +:100DA000041A84F00001030F061A84F40000000303 +:100DB000041A850000010310061A850400000003D0 +:100DC000041A851000010311061A8514000000039F +:100DD000041A852000010312061A8524000000036E +:100DE000041A853000010313061A8534000000033D +:100DF000041A854000010314061A8544000000030C +:100E0000041A855000010315061A855400000003DA +:100E1000041A856000010316061A856400000003A9 +:100E2000041A857000010317061A85740000000378 +:100E3000041A858000010318061A85840000000347 +:100E4000041A859000010319061A85940000000316 +:100E5000041A85A00001031A061A85A400000003E5 +:100E6000041A85B00001031B061A85B400000003B4 +:100E7000041A85C00001031C061A85C40000000383 +:100E8000041A85D00001031D061A85D40000000352 +:100E9000041A85E00001031E061A85E40000000321 +:100EA000041A85F00001031F061A85F400000003F0 +:100EB000041A860000010320061A860400000003BD +:100EC000041A861000010321061A8614000000038C +:100ED000041A862000010322061A8624000000035B +:100EE000041A863000010323061A8634000000032A +:100EF000041A864000010324061A864400000003F9 +:100F0000041A865000010325061A865400000003C7 +:100F1000041A866000010326061A86640000000396 +:100F2000041A867000010327061A86740000000365 +:100F3000041A868000010328061A86840000000334 +:100F4000041A869000010329061A86940000000303 +:100F5000041A86A00001032A061A86A400000003D2 +:100F6000041A86B00001032B061A86B400000003A1 +:100F7000041A86C00001032C061A86C40000000370 +:100F8000041A86D00001032D061A86D4000000033F +:100F9000041A86E00001032E061A86E4000000030E +:100FA000041A86F00001032F061A86F400000003DD +:100FB000041A870000010330061A870400000003AA +:100FC000041A871000010331061A87140000000379 +:100FD000041A872000010332061A87240000000348 +:100FE000041A873000010333061A87340000000317 +:100FF000041A874000010334061A874400000003E6 +:10100000041A875000010335061A875400000003B4 +:10101000041A876000010336061A87640000000383 +:10102000041A877000010337061A87740000000352 +:10103000041A878000010338061A87840000000321 +:10104000041A879000010339061A879400000003F0 +:10105000041A87A00001033A061A87A400000003BF +:10106000041A87B00001033B061A87B4000000038E +:10107000041A87C00001033C061A87C4000000035D +:10108000041A87D00001033D061A87D4000000032C +:10109000041A87E00001033E061A87E400000003FB +:1010A000041A87F00001033F061A87F400000003CA +:1010B000041A880000010340061A88040000000397 +:1010C000041A881000010341061A88140000000366 +:1010D000041A882000010342061A88240000000335 +:1010E000041A883000010343061A88340000000304 +:1010F000041A884000010344061A884400000003D3 +:10110000041A885000010345061A885400000003A1 +:10111000041A886000010346061A88640000000370 +:10112000041A887000010347061A8874000000033F +:10113000041A888000010348061A8884000000030E +:10114000041A889000010349061A889400000003DD +:10115000041A88A00001034A061A88A400000003AC +:10116000041A88B00001034B061A88B4000000037B +:10117000041A88C00001034C061A88C4000000034A +:10118000041A88D00001034D061A88D40000000319 +:10119000041A88E00001034E061A88E400000003E8 +:1011A000041A88F00001034F061A88F400000003B7 +:1011B000041A890000010350061A89040000000384 +:1011C000041A891000010351061A89140000000353 +:1011D000041A892000010352061A89240000000322 +:1011E000041A893000010353061A893400000003F1 +:1011F000041A894000010354061A894400000003C0 +:10120000041A895000010355061A8954000000038E +:10121000041A896000010356061A8964000000035D +:10122000041A897000010357061A8974000000032C +:10123000041A898000010358061A898400000003FB +:10124000041A899000010359061A899400000003CA +:10125000041A89A00001035A061A89A40000000399 +:10126000041A89B00001035B061A89B40000000368 +:10127000041A89C00001035C061A89C40000000337 +:10128000041A89D00001035D061A89D40000000306 +:10129000041A89E00001035E061A89E400000003D5 +:1012A000041A89F00001035F061A89F400000003A4 +:1012B000041A8A0000010360061A8A040000000371 +:1012C000041A8A1000010361061A8A140000000340 +:1012D000041A8A2000010362061A8A24000000030F +:1012E000041A8A3000010363061A8A3400000003DE +:1012F000041A8A4000010364061A8A4400000003AD +:10130000041A8A5000010365061A8A54000000037B +:10131000041A8A6000010366061A8A64000000034A +:10132000041A8A7000010367061A8A740000000319 +:10133000041A8A8000010368061A8A8400000003E8 +:10134000041A8A9000010369061A8A9400000003B7 +:10135000041A8AA00001036A061A8AA40000000386 +:10136000041A8AB00001036B061A8AB40000000355 +:10137000041A8AC00001036C061A8AC40000000324 +:10138000041A8AD00001036D061A8AD400000003F3 +:10139000041A8AE00001036E061A8AE400000003C2 +:1013A000041A8AF00001036F061A8AF40000000391 +:1013B000041A8B0000010370061A8B04000000035E +:1013C000041A8B1000010371061A8B14000000032D +:1013D000041A8B2000010372061A8B2400000003FC +:1013E000041A8B3000010373061A8B3400000003CB +:1013F000041A8B4000010374061A8B44000000039A +:10140000041A8B5000010375061A8B540000000368 +:10141000041A8B6000010376061A8B640000000337 +:10142000041A8B7000010377061A8B740000000306 +:10143000041A8B8000010378061A8B8400000003D5 +:10144000041A8B9000010379061A8B9400000003A4 +:10145000041A8BA00001037A061A8BA40000000373 +:10146000041A8BB00001037B061A8BB40000000342 +:10147000041A8BC00001037C061A8BC40000000311 +:10148000041A8BD00001037D061A8BD400000003E0 +:10149000041A8BE00001037E061A8BE400000003AF +:1014A000041A8BF00001037F061A8BF4000000037E +:1014B000041A8C0000010380061A8C04000000034B +:1014C000041A8C1000010381061A8C14000000031A +:1014D000041A8C2000010382061A8C2400000003E9 +:1014E000041A8C3000010383061A8C3400000003B8 +:1014F000041A8C4000010384061A8C440000000387 +:10150000041A8C5000010385061A8C540000000355 +:10151000041A8C6000010386061A8C640000000324 +:10152000041A8C7000010387061A8C7400000003F3 +:10153000041A8C8000010388061A8C8400000003C2 +:10154000041A8C9000010389061A8C940000000391 +:10155000041A8CA00001038A061A8CA40000000360 +:10156000041A8CB00001038B061A8CB4000000032F +:10157000041A8CC00001038C061A8CC400000003FE +:10158000041A8CD00001038D061A8CD400000003CD +:10159000041A8CE00001038E061A8CE4000000039C +:1015A000041A8CF00001038F061A8CF4000000036B +:1015B000041A8D0000010390061A8D040000000338 +:1015C000041A8D1000010391061A8D140000000307 +:1015D000041A8D2000010392061A8D2400000003D6 +:1015E000041A8D3000010393061A8D3400000003A5 +:1015F000041A8D4000010394061A8D440000000374 +:10160000041A8D5000010395061A8D540000000342 +:10161000041A8D6000010396061A8D640000000311 +:10162000041A8D7000010397061A8D7400000003E0 +:10163000041A8D8000010398061A8D8400000003AF +:10164000041A8D9000010399061A8D94000000037E +:10165000041A8DA00001039A061A8DA4000000034D +:10166000041A8DB00001039B061A8DB4000000031C +:10167000041A8DC00001039C061A8DC400000003EB +:10168000041A8DD00001039D061A8DD400000003BA +:10169000041A8DE00001039E061A8DE40000000389 +:1016A000041A8DF00001039F061A8DF40000000358 +:1016B000041A8E00000103A0061A8E040000000325 +:1016C000041A8E10000103A1061A8E1400000003F4 +:1016D000041A8E20000103A2061A8E2400000003C3 +:1016E000041A8E30000103A3061A8E340000000392 +:1016F000041A8E40000103A4061A8E440000000361 +:10170000041A8E50000103A5061A8E54000000032F +:10171000041A8E60000103A6061A8E6400000003FE +:10172000041A8E70000103A7061A8E7400000003CD +:10173000041A8E80000103A8061A8E84000000039C +:10174000041A8E90000103A9061A8E94000000036B +:10175000041A8EA0000103AA061A8EA4000000033A +:10176000041A8EB0000103AB061A8EB40000000309 +:10177000041A8EC0000103AC061A8EC400000003D8 +:10178000041A8ED0000103AD061A8ED400000003A7 +:10179000041A8EE0000103AE061A8EE40000000376 +:1017A000041A8EF0000103AF061A8EF40000000345 +:1017B000041A8F00000103B0061A8F040000000312 +:1017C000041A8F10000103B1061A8F1400000003E1 +:1017D000041A8F20000103B2061A8F2400000003B0 +:1017E000041A8F30000103B3061A8F34000000037F +:1017F000041A8F40000103B4061A8F44000000034E +:10180000041A8F50000103B5061A8F54000000031C +:10181000041A8F60000103B6061A8F6400000003EB +:10182000041A8F70000103B7061A8F7400000003BA +:10183000041A8F80000103B8061A8F840000000389 +:10184000041A8F90000103B9061A8F940000000358 +:10185000041A8FA0000103BA061A8FA40000000327 +:10186000041A8FB0000103BB061A8FB400000003F6 +:10187000041A8FC0000103BC061A8FC400000003C5 +:10188000041A8FD0000103BD061A8FD40000000394 +:10189000041A8FE0000103BE061A8FE4000000075F +:1018A000041A62C0002003BF061A1AF000000042AA +:1018B000061AAF0000000008061AE000000005400C +:1018C000061AD00000000072061AD248000000106C +:1018D000061AD6B000000020061AD470000000904E +:1018E000061AD46800000002061AA000000001C415 +:1018F000061A300000000010061A308000000010A8 +:10190000061A310000000010061A31800000001095 +:10191000061A330000000012061A3390000000700F +:10192000061AD45800000002061AD348000000022C +:10193000061AD35800000020061AA710000001C4A0 +:10194000061A304000000010061A30C000000010D7 +:10195000061A314000000010061A31C000000010C5 +:10196000061A334800000012061A355000000070B5 +:10197000061AD46000000002061AD35000000002CC +:10198000061AD3D800000020021AAE200000000082 +:10199000061A500000000002061A508000000012D3 +:1019A000041A4000000203DF041A63C0000203E1CE +:1019B000061A700000000004061A32000000000839 +:1019C000021AAE2400000000061A501000000002A7 +:1019D000061A50C800000012041A4008000203E36F +:1019E000041A63C8000203E5061A70100000000420 +:1019F000061A322000000008021AAE28000000007B +:101A0000061A502000000002061A511000000012B1 +:101A1000041A4010000203E7041A63D0000203E92D +:101A2000061A702000000004061A32400000000868 +:101A3000021AAE2C00000000061A5030000000020E +:101A4000061A515800000012041A4018000203EB55 +:101A5000041A63D8000203ED061A70300000000477 +:101A6000061A326000000008021AAE3000000000C2 +:101A7000061A504000000002061A51A00000001291 +:101A8000041A4020000203EF041A63E0000203F18D +:101A9000061A704000000004061A32800000000898 +:101AA000021AAE3400000000061A50500000000276 +:101AB000061A51E800000012041A4028000203F33D +:101AC000041A63E8000203F5061A705000000004CF +:101AD000061A32A000000008021AAE38000000000A +:101AE000061A506000000002061A52300000001270 +:101AF000041A4030000203F7041A63F0000203F9ED +:101B0000061A706000000004061A32C000000008C7 +:101B1000021AAE3C00000000061A507000000002DD +:101B2000061A527800000012041A4038000203FB23 +:101B3000041A63F8000203FD061A70700000000426 +:101B4000061A32E0000000080200A2A40000020908 +:101B50000200A270000000000200A2740000000059 +:101B60000200A270000000000200A2740000000049 +:101B70000200A270000000000200A2740000000039 +:101B80000200A270000000000200A2740000000029 +:101B9000020100B400000001020100B800000001D1 +:101BA000020100CC00000001020100D00000000191 +:101BB000020100DC00000001020101000000000140 +:101BC00002010104000000010201007C003000005D +:101BD00002010084000000280201008C00000000C7 +:101BE00002010130000000040201025C000000015B +:101BF0000201032800000000020160580000FFFFFE +:101C0000020160700000000702010554000000306E +:101C1000020100C400000001020100F80000000100 +:101C2000020100F00000000102010080003000000D +:101C3000020100880000002802010090000000005E +:101C40000201013400000004020102DC0000000176 +:101C50000201032C000000000201605C0000FFFF95 +:101C600002016074000000070201056400000030FA +:101C7000020100C800000001020100FC0000000198 +:101C8000020100F400000001020C10000000002816 +:101C9000020C200800000211020C200C00000200BF +:101CA000020C201000000204020C201C0000FFFFA8 +:101CB000020C20200000FFFF020C20240000FFFF88 +:101CC000020C20280000FFFF020C2038000000005A +:101CD000020C203C00000037020C204000000021D4 +:101CE000020C204400000020060C20480000001DCB +:101CF000020C20BC00000001060C20C00000003FC8 +:101D0000020C21BC00000001020C21C000000001F7 +:101D1000020C21C400000001060C21C80000001CB8 +:101D2000020C223807FFFFFF020C223C0000007F5C +:101D3000020C224007FFFFFF020C22440000003F7C +:101D4000010C224800000000010C224C00000000A1 +:101D5000010C225000000000010C22540000000081 +:101D6000010C225800000000010C225C0000000061 +:101D7000010C226000000000010C22640000000041 +:101D8000010C226800000000010C226C0000000021 +:101D9000010C227000000000010C22740000000001 +:101DA000010C227800000000010C227C00000000E1 +:101DB000020C22D80000FFFF020C22DC0000FFFF13 +:101DC000020C22E00000FFFF020C22E40000FFFFF3 +:101DD0000C0C2000000003E80A0C200000000001A9 +:101DE0000B0C200000000003020C40080000101142 +:101DF000020C400C00001000020C40100000100407 +:101E0000020C401400001021020C401C0000FFFFD7 +:101E1000020C40200000FFFF020C40240000FFFFE6 +:101E2000020C40280000FFFF020C40380000004672 +:101E3000020C403C0000000C060C40400000000278 +:101E4000020C404800000018020C404C000000F05A +:101E5000060C40500000001F020C40CC00000001A6 +:101E6000060C40D00000003A020C41B8000000010E +:101E7000060C41BC00000003020C41C80000000138 +:101E8000020C41CC00000001060C41D00000001AF9 +:101E9000020C423807FFFFFF020C423C0000007FAB +:101EA000020C424007FFFFFF020C42440000003FCB +:101EB000010C424800000000010C424C00000000F0 +:101EC000010C425000000000010C425400000000D0 +:101ED000010C425800000000010C425C00000000B0 +:101EE000010C426000000000010C42640000000090 +:101EF000010C426800000000010C426C0000000070 +:101F0000010C427000000000010C4274000000004F +:101F1000010C427800000000010C427C000000002F +:101F2000010C428000000000020C42D80000FFFFBC +:101F3000020C42DC0000FFFF020C42E00000FFFF49 +:101F4000020C42E40000FFFF0C0C4000000003E81C +:101F50000A0C4000000000010B0C400000000003D0 +:101F6000060D400000000A00020D0044000000328F +:101F7000020D008C02150020020D009002150020B9 +:101F8000020D009408100000020D009800000036B9 +:101F9000020D00A000000000020D00A400000004DB +:101FA000020D00A800000004060D00AC00000002B5 +:101FB000020D00B800000002020D00C00000000188 +:101FC000020D00C800000002020D00CC000000025B +:101FD000020D015C00000001020D0164000000011F +:101FE000020D016800000002020D02040000000161 +:101FF000020D020C00000020020D02100000004043 +:10200000020D021400000040020D02200000000337 +:10201000020D022400000018060D028000000012CC +:10202000040D0300001803FF060D03600000000C00 +:10203000020D004C00000001020D005000000002E3 +:10204000020D005400000000020D005800000008BE +:10205000060D005C00000004020D00C40000000436 +:10206000020D000400000001020D00080000000144 +:10207000020D000C00000001020D00100000000124 +:10208000020D001400000001020D00180000000104 +:10209000020D001C00000001020D002000000001E4 +:1020A000020D002400000001020D002800000001C4 +:1020B000020D002C00000001020D003000000001A4 +:1020C000020D003400000001020D00380000000184 +:1020D000020D003C00000001020D01140000000987 +:1020E000020D011C0000000A020D01240000000086 +:1020F000020D012C00000000020D01340000000060 +:10210000020D013C0000000B020D01440000000024 +:10211000020D011800000029020D01200000002A14 +:10212000020D012800000020020D013000000020F7 +:10213000020D013800000020020D01400000002BBC +:10214000020D014800000020020D011400000019DA +:10215000020D011C0000001A020D012400000010F5 +:10216000020D012C00000010020D013400000010CF +:10217000020D013C0000001B020D01440000001094 +:10218000020D011800000039020D01200000003A84 +:10219000020D012800000030020D01300000003067 +:1021A000020D013800000030020D01400000003B2C +:1021B000020D014800000030020D0114000000492A +:1021C000020D011C0000004A020D01240000004025 +:1021D000020D012C00000040020D013400000040FF +:1021E000020D013C0000004B020D014400000040C4 +:1021F000020D011800000069020D01200000006AB4 +:10220000020D012800000060020D01300000006096 +:10221000020D013800000060020D01400000006B5B +:10222000020D014800000060020D01140000005979 +:10223000020D011C0000005A020D01240000005094 +:10224000020D012C00000050020D0134000000506E +:10225000020D013C0000005B020D01440000005033 +:10226000020D011800000079020D01200000007A23 +:10227000020D012800000070020D01300000007006 +:10228000020D013800000070020D01400000007BCB +:10229000020D014800000070060E2000000008003A +:1022A000020E004C00000032020E009402150020C5 +:1022B000020E009802150020020E009C0000003063 +:1022C000020E00A008100000020E00A4000000365C +:1022D000020E00A800000030020E00AC0000003129 +:1022E000020E00B400000003020E00B8000000005F +:1022F000020E00C400000000020E00CC0000000628 +:10230000020E00D800000001020E0144000000018E +:10231000020E014C00000001020E015000000002FC +:10232000020E020400000001020E020C0000004038 +:10233000020E021000000040020E021C0000000409 +:10234000020E022000000020020E02240000000EF7 +:10235000020E02280000001B060E030000000012FF +:10236000040E0280001B0417060E02EC000000059C +:10237000020E00540000000C020E00580000000C79 +:10238000020E005C00000000020E00600000001061 +:10239000020E006400000010060E0068000000033A +:1023A000020E00DC00000003020E00040000000129 +:1023B000020E000800000001020E000C00000001E7 +:1023C000020E001000000001020E001400000001C7 +:1023D000020E001800000001020E001C00000001A7 +:1023E000020E002000000001020E00240000000187 +:1023F000020E002800000001020E002C0000000167 +:10240000020E003000000001020E00340000000146 +:10241000020E003800000001020E003C0000000126 +:10242000020E004000000001020E00440000000106 +:10243000020E01100000000F020E01180000000043 +:10244000020E012000000000020E01280000000022 +:10245000020E01140000002F020E011C00000020DB +:10246000020E012400000020020E012C00000020BA +:10247000020E01100000001F020E011800000010E3 +:10248000020E012000000010020E012800000010C2 +:10249000020E01140000003F020E011C000000307B +:1024A000020E012400000030020E012C000000305A +:1024B000020E01100000004F020E01180000004043 +:1024C000020E012000000040020E01280000004022 +:1024D000020E01140000006F020E011C00000060DB +:1024E000020E012400000060020E012C00000060BA +:1024F000020E01100000005F020E011800000050E3 +:10250000020E012000000050020E012800000050C1 +:10251000020E01140000007F020E011C000000707A +:10252000020E012400000070020E012C0000007059 +:102530000730040000D60000083007D80005043238 +:10254000073400003222000007348000312C0C894F +:102550000735000038DD18D5073580002F16270D08 +:1025600007360000261532D30836711031DE0434E8 +:1025700001300000000000000130000400000000F5 +:1025800001300008000000000130000C00000000D5 +:1025900001300010000000000130001400000000B5 +:1025A0000230002000000001023000240000000280 +:1025B00002300028000000030230002C0000000060 +:1025C000023000300000000402300034000000013E +:1025D00002300038000000000230003C0000000122 +:1025E00002300040000000040230004400000000FF +:1025F00002300048000000010230004C00000003DF +:1026000002300050000000000230005400000001C1 +:1026100002300058000000040230005C000000009E +:10262000023000600000000102300064000000037E +:1026300002300068000000000230006C0000000161 +:10264000023000700000000402300074000000003E +:1026500002300078000000040230007C000000031B +:102660000630008000000002023000A400007FFF5E +:10267000023000A8000003FF023002240000000026 +:1026800002300234000000000230024C0000000062 +:10269000023002E40000FFFF0630200000000800C6 +:1026A00002338BC000000001023380000000001ADA +:1026B000023380400000004E023380800000001092 +:1026C000023380C0000000200C33830000086470D7 +:1026D0000A338300000001570B3383000000055FBD +:1026E0000A338340000000000C33834000000226C0 +:1026F0000B338340000000010233838000086470C4 +:10270000023383C00000022602331480000000015F +:102710000A3314800000000006328000000001022D +:1027200006322008000000C8063220000000000227 +:1027300004328520008F04360632875C00000009D1 +:1027400006323EB00000000606323ED00000000215 +:1027500006323E800000000A04323EA8000204C592 +:1027600006323E0000000020063250000000094002 +:102770000632400000000004043294C0000204C786 +:1027800006324110000000020632D0000000007046 +:102790000632DB00000000D40632DEA0000000029A +:1027A0000632E00000000800063324000000011893 +:1027B00006321000000001880632500000000020A0 +:1027C00006325100000000200632520000000020B6 +:1027D00006325300000000200632540000000020A2 +:1027E000063255000000002006325600000000208E +:1027F000063257000000002006325800000000207A +:10280000063259000000002006325A000000002065 +:1028100006325B000000002006325C000000002051 +:1028200006325D000000002006325E00000000203D +:1028300006325F0000000020063284F00000000233 +:1028400004328500000204C9063285080000000237 +:102850000632DE90000000020633286000000118F6 +:102860000632162000000188063250800000002049 +:102870000632518000000020063252800000002005 +:1028800006325380000000200632548000000020F1 +:1028900006325580000000200632568000000020DD +:1028A00006325780000000200632588000000020C9 +:1028B000063259800000002006325A8000000020B5 +:1028C00006325B800000002006325C8000000020A1 +:1028D00006325D800000002006325E80000000208D +:1028E00006325F8000000020063284F800000002FB +:1028F00004328510000204CB063285180000000265 +:102900000632DE980000000202328450000000000F +:102910000632401000000002023284540000000021 +:1029200006324020000000020232845800000000FD +:1029300006324030000000020232845C00000000D9 +:1029400006324040000000020232846000000000B5 +:102950000632405000000002023284640000000091 +:10296000063240600000000202328468000000006D +:1029700006324070000000020232846C0000000049 +:1029800006324080000000020720040000730000AF +:1029900008200780001004CD072400002AD500007D +:1029A0000724800027740AB60824D36063FA04CF92 +:1029B00001200000000000000120000400000000D1 +:1029C00001200008000000000120000C00000000B1 +:1029D0000120001000000000012000140000000091 +:1029E000022000200000000102200024000000025C +:1029F00002200028000000030220002C000000003C +:102A00000220003000000004022000340000000119 +:102A100002200038000000000220003C00000001FD +:102A200002200040000000040220004400000000DA +:102A300002200048000000010220004C00000003BA +:102A4000022000500000000002200054000000019D +:102A500002200058000000040220005C000000007A +:102A6000022000600000000102200064000000035A +:102A700002200068000000000220006C000000013D +:102A8000022000700000000402200074000000001A +:102A900002200078000000040220007C00000003F7 +:102AA0000620008000000002022000A400007FFF3A +:102AB000022000A8000003FF022002240000000002 +:102AC00002200234000000000220024C000000003E +:102AD000022002E40000FFFF0620200000000800A2 +:102AE00002238BC0000000010223800000000010C0 +:102AF000022380400000001202238080000000308A +:102B0000022380C00000000E0C23830000086470C4 +:102B10000A238300000001570B2383000000055F98 +:102B20000A238340000000000C238340000002269B +:102B30000B2383400000000102238380000864709F +:102B4000022383C00000022602231480000000013B +:102B50000A2314800000000006221000000000423A +:102B600006222008000000C8062220000000000203 +:102B70000622B000000003300622F40000000053DB +:102B80000422F54C000104D10622F5500000000398 +:102B90000422F55C000104D20622F5600000000367 +:102BA0000422F56C000104D30622F5700000000336 +:102BB0000422F57C000104D40622F5800000000305 +:102BC0000422F58C000104D50622F59000000003D4 +:102BD0000422F59C000104D60622F5A000000003A3 +:102BE0000422F5AC000104D70622F5B00000000372 +:102BF0000422F5BC000104D80622F5C000000046FE +:102C00000622E2000000044004221240009004D991 +:102C100006223000000000C006226700000001000C +:102C2000062290000000040004226B0800200569C1 +:102C3000062211F000000006042212080006058991 +:102C4000062212200000000206224000000005C0FB +:102C50000622C000000000060422C0180006058FEE +:102C60000622C0300000000A0422C0580006059564 +:102C70000622C0700000000A0422C0980006059BCE +:102C80000622C0B00000000A0422C0D8000605A138 +:102C90000622C0F00000000A0422C118000605A7A1 +:102CA0000622C1300000000A0422C158000605AD0A +:102CB0000622C1700000000A0422C198000605B374 +:102CC0000622C1B00000000A0422C1D8000605B9DE +:102CD0000622C1F00000000A0422C218000605BF47 +:102CE0000622C2300000000A0422C258000605C5B0 +:102CF0000622C2700000000A0422C298000605CB1A +:102D00000622C2B00000000A0422C2D8000605D183 +:102D10000622C2F00000000A0422C318000605D7EC +:102D20000622C3300000000A0422C358000605DD55 +:102D30000622C3700000000A0422C398000605E3BF +:102D40000622C3B00000000A0422C3D8000605E929 +:102D50000622C3F00000000A0422C418000605EF92 +:102D60000622C4300000000A0422C458000605F5FB +:102D70000622C4700000000A0422C498000605FB65 +:102D80000622C4B00000000A0422C4D800060601CE +:102D90000622C4F00000000A0422C5180006060737 +:102DA0000622C5300000000A0422C5580006060DA0 +:102DB0000622C5700000000A0422C598000606130A +:102DC0000622C5B00000000A0422C5D80006061974 +:102DD0000622C5F00000000A0422C6180006061FDD +:102DE0000622C6300000000A0422C6580006062546 +:102DF0000622C6700000000A0422C6980006062BB0 +:102E00000622C6B00000000A0422C6D80006063119 +:102E10000622C6F00000000A0422C7180006063782 +:102E20000622C7300000000A0422C7580006063DEB +:102E30000622C7700000000A0422C7980006064355 +:102E40000622C7B00000000A0422C7D800060649BF +:102E50000622C7F00000000A0422C8180006064F28 +:102E60000622C8300000000A0422C8580006065591 +:102E70000622C8700000000A0422C8980006065BFB +:102E80000622C8B00000000A0422C8D80006066165 +:102E90000622C8F00000000A0422C91800060667CE +:102EA0000622C9300000000A0422C9580006066D37 +:102EB0000622C9700000000A0422C99800060673A1 +:102EC0000622C9B00000000A0422C9D8000606790B +:102ED0000622C9F00000000A0422CA180006067F74 +:102EE0000622CA300000000A0422CA5800060685DD +:102EF0000622CA700000000A0422CA980006068B47 +:102F00000622CAB00000000A0422CAD800060691B0 +:102F10000622CAF00000000A0422CB180006069719 +:102F20000622CB300000000A0422CB580006069D82 +:102F30000622CB700000000A0422CB98000606A3EC +:102F40000622CBB00000000A0422CBD8000606A956 +:102F50000622CBF00000000A0422CC18000606AFBF +:102F60000622CC300000000A0422CC58000606B528 +:102F70000622CC700000000A0422CC98000606BB92 +:102F80000622CCB00000000A0422CCD8000606C1FC +:102F90000622CCF00000000A0422CD18000606C765 +:102FA0000622CD300000000A0422CD58000606CDCE +:102FB0000622CD700000000A0422CD98000606D338 +:102FC0000622CDB00000000A0422CDD8000606D9A2 +:102FD0000622CDF00000000A0422CE18000606DF0B +:102FE0000622CE300000000A0422CE58000606E574 +:102FF0000622CE700000000A0422CE98000606EBDE +:103000000622CEB00000000A0422CED8000606F147 +:103010000622CEF00000000A0422CF18000606F7B0 +:103020000622CF300000000A0422CF58000606FD19 +:103030000622CF700000000A0422CF980006070382 +:103040000622CFB00000000A0422CFD800060709EC +:103050000622CFF00000000A0422D0180006070F55 +:103060000622D0300000000A0422D05800060715BE +:103070000622D0700000000A0422D0980006071B28 +:103080000622D0B00000000A0422D0D80006072192 +:103090000622D0F00000000A0422D11800060727FB +:1030A0000622D1300000000A0422D1580006072D64 +:1030B0000622D1700000000A0422D19800060733CE +:1030C0000622D1B00000000A0422D1D80006073938 +:1030D0000622D1F00000000A0422D2180006073FA1 +:1030E0000622D2300000000A0422D258000607450A +:1030F0000622D2700000000A0422D2980006074B74 +:103100000622D2B00000000A0422D2D800060751DD +:103110000622D2F00000000A0422D3180006075746 +:103120000622D3300000000A0422D3580006075DAF +:103130000622D3700000000A0422D3980006076319 +:103140000622D3B00000000A0422D3D80006076983 +:103150000622D3F00000000A0422D4180006076FEC +:103160000622D4300000000A0422D4580006077555 +:103170000622D4700000000A0422D4980006077BBF +:103180000622D4B00000000A0422D4D80006078129 +:103190000622D4F00000000A0422D5180006078792 +:1031A0000622D5300000000A0422D5580006078DFB +:1031B0000622D5700000000A0422D5980006079365 +:1031C0000622D5B00000000A0422D5D800060799CF +:1031D0000622D5F00000000A0422D6180006079F38 +:1031E0000622D6300000000A0422D658000607A5A1 +:1031F0000622D6700000000A0422D698000607AB0B +:103200000622D6B00000000A0422D6D8000607B174 +:103210000622D6F00000000A0422D718000607B7DD +:103220000622D7300000000A0422D758000607BD46 +:103230000622D7700000000A0422D798000607C3B0 +:103240000622D7B00000000A0422D7D8000607C91A +:103250000622D7F00000000A0422D818000607CF83 +:103260000622D8300000000A0422D858000607D5EC +:103270000622D8700000000A0422D898000607DB56 +:103280000622D8B00000000A0422D8D8000607E1C0 +:103290000622D8F00000000A0422D918000607E729 +:1032A0000622D9300000000A0422D958000607ED92 +:1032B0000622D9700000000A0422D998000607F3FC +:1032C0000622D9B00000000A0422D9D8000607F966 +:1032D0000622D9F00000000A0422DA18000607FFCF +:1032E0000622DA300000000A0422DA580006080537 +:1032F0000622DA700000000A0422DA980006080BA1 +:103300000622DAB00000000A0422DAD8000608110A +:103310000622DAF00000000A0422DB180006081773 +:103320000622DB300000000A0422DB580006081DDC +:103330000622DB700000000A0422DB980006082346 +:103340000622DBB00000000A0422DBD800060829B0 +:103350000622DBF00000000A0422DC180006082F19 +:103360000622DC300000000A0422DC580006083582 +:103370000622DC700000000A0422DC980006083BEC +:103380000622DCB00000000A0422DCD80006084156 +:103390000622DCF00000000A0422DD1800060847BF +:1033A0000622DD300000000A0422DD580006084D28 +:1033B0000622DD700000000A0422DD980006085392 +:1033C0000622DDB00000000A0422DDD800060859FC +:1033D0000622DDF00000000A0422DE180006085F65 +:1033E0000622DE300000000A0422DE5800060865CE +:1033F0000622DE700000000A0422DE980006086B38 +:103400000622DEB00000000A0422DED800060871A1 +:103410000622DEF00000000A0422DF18000608770A +:103420000622DF300000000A0422DF580006087D73 +:103430000622DF700000000A0422DF9800060883DD +:103440000622DFB00000000A0422DFD80006088947 +:103450000622DFF00000000A0422E0180006088FB0 +:103460000622E0300000000A0422E0580006089519 +:103470000622E0700000000A0422E0980006089B83 +:103480000622E0B00000000A0422E0D8000608A1ED +:103490000622E0F00000000A0422E118000608A756 +:1034A0000622E1300000000A0422E158000608ADBF +:1034B0000622E1700000000A0422E198000608B329 +:1034C0000622E1B00000000A0422E1D8000608B993 +:1034D0000622E1F000000004062215380000000278 +:1034E000062211E8000000020622F3000000000896 +:1034F00002221148000000000622590000000006C8 +:103500000622330000000002062260400000003066 +:103510000622F320000000080222114C00000000E7 +:103520000622591800000006062233080000000297 +:1035300006226100000000300622F340000000086F +:10354000022211500000000006225930000000063F +:103550000622331000000002062261C00000003085 +:103560000622F3600000000802221154000000004F +:103570000622594800000006062233180000000207 +:1035800006226280000000300622F380000000085E +:1035900002221158000000000622596000000006B7 +:1035A00006223320000000020622634000000030A3 +:1035B0000622F3A0000000080222115C00000000B7 +:1035C0000622597800000006062233280000000277 +:1035D00006226400000000300622F3C0000000084C +:1035E000022211600000000006225990000000062F +:1035F0000622333000000002062264C000000030C2 +:103600000622F3E00000000802221164000000001E +:10361000062259A8000000060622333800000002E6 +:10362000062265800000003002161000000000280D +:1036300002170008000000020217002C000000031F +:103640000217003C000000040217004400000000C4 +:1036500002170048000000020217004C0000009012 +:1036600002170050000000900217005400800090E4 +:103670000217005808100000021700700000000632 +:1036800002170078000009FF0217007C0000076C99 +:10369000021701C4081000000217034400000001D3 +:1036A000021704000000008A0217040400000080D2 +:1036B00002170408000000810217040C00000080BB +:1036C000021704100000008A021704140000008092 +:1036D00002170418000000810217041C000000807B +:1036E000021704300000008A021704340000008032 +:1036F00002170438000000810217043C000000801B +:10370000021704400000008A0217044400000080F1 +:1037100002170448000000810217044C00000080DA +:10372000021704800000008A021704840000008051 +:1037300002170488000000810217048C000000803A +:1037400002170038007C1004021700040000000F6C +:10375000021701EC00000002021701F40000000251 +:10376000021701EC00000002021701F40000000241 +:10377000021701EC00000002021701F40000000231 +:10378000021701EC00000002021701F40000000221 +:10379000021701EC00000002021701F40000000211 +:1037A000021701EC00000002021701F40000000201 +:1037B000021701EC00000002021701F400000002F1 +:1037C000021701EC00000002021701F400000002E1 +:1037D0000616402400000002021640700000001C83 +:1037E000021642080000000102164210000000010B +:1037F00002164220000000010216422800000001CB +:10380000021642300000000102164238000000019A +:1038100002164260000000020C16401C0003D0900B +:103820000A16401C0000009C0B16401C0000027190 +:103830000216403000000028021640340000002C20 +:1038400002164038000000300216404400000020FC +:103850000216400000000001021640D800000001DE +:1038600002164008000000010216400C0000000192 +:103870000216401000000001021642400000000045 +:1038800002164248000000000616427000000002C6 +:1038900002164250000000000216425800000000CC +:1038A0000616428000000002021660080000121492 +:1038B0000216600C000012000216601000001204D4 +:1038C0000216601C0000FFFF021660200000FFFFD0 +:1038D000021660240000FFFF021660280000FFFFB0 +:1038E00002166038000000200216603C0000001044 +:1038F0000616604000000002021660480000002327 +:103900000216604C000000240216605000000025E2 +:1039100002166054000000260216605800000027BE +:103920000216605C000000110216606000000000DA +:10393000021660640000002B021660680000002C74 +:103940000216606C0000002D02166070000000EC92 +:103950000216607400000000021660780000002962 +:103960000216607C0000002A021660800000002F12 +:10397000061660840000000D021660B80000000109 +:10398000061660BC00000008021660DC00000001A2 +:10399000061660E000000004021660F0000000015E +:1039A000061660F40000000302166100000000012A +:1039B000061661040000002D021661B80000000127 +:1039C000061661BC00000008021661DC0000000160 +:1039D000061661E000000004021661F0000000011C +:1039E000061661F4000000030216620000000001E8 +:1039F000061662040000000D0216623807FFFFFF82 +:103A00000216623C0000007F0216624007FFFFFFC3 +:103A1000021662440000003F0116624800000000E8 +:103A20000116624C00000000011662500000000008 +:103A300001166254000000000116625800000000E8 +:103A40000116625C000000000116626000000000C8 +:103A500001166264000000000116626800000000A8 +:103A60000116626C00000000011662700000000088 +:103A70000116627400000000011662780000000068 +:103A80000116627C00000000011662D400000000F4 +:103A9000021662D80000FFFF021662DC0000FFFF82 +:103AA000021662E00000FFFF021662E40000FFFF62 +:103AB0000C166000000003E80A1660000000000118 +:103AC0000B16600000000003021680400000000694 +:103AD0000216804400000005021680480000000A1B +:103AE0000216804C000000050216805400000002FF +:103AF000021680CC00000004021680D000000004F2 +:103B0000021680D400000004021680D800000004D1 +:103B1000021680DC00000004021680E000000004B1 +:103B2000021680E400000004021680E80000000491 +:103B30000216880400000006021680300000007C97 +:103B4000021680340000003D021680380000003F5D +:103B50000216803C0000009C0216E6E800006000AF +:103B60000216E6EC000060000216E6F000006000BD +:103B70000216E6F40000600002168234000025E41C +:103B8000021682380000800002168094000025E3AF +:103B9000021681F400000C08021681F800000040B3 +:103BA000021681FC000001000216820000000020C5 +:103BB000021682040000001702168208000000802E +:103BC0000216820C000002000216821000000000A3 +:103BD0000216823C0000001302168220008F008F24 +:103BE0000216821C008F008F021680F00000000772 +:103BF0000216821801FF01FF0216821401FF01FF65 +:103C0000061680F4000000020216811C0000000568 +:103C10000216812000000005021681240000000524 +:103C200002168128000000080216812C0000000600 +:103C300002168130000000070616813400000004DF +:103C4000021680FC000000000616814400000002FD +:103C50000216814C00000004021681500000000191 +:103C6000021681540000000202168158000000056F +:103C70000216815C0000000502168160000000054C +:103C80000216816400000005021681680000000829 +:103C900002168100000000000216816C0000000680 +:103CA00002168170000000070616817400000006ED +:103CB0000216818C000000040216819000000001B1 +:103CC0000216810400000000021681940000000228 +:103CD00002168198000000050216819C0000000574 +:103CE000021681A000000005021681A40000000554 +:103CF000021681A800000008021681AC0000000630 +:103D0000021681B000000007061681B40000000210 +:103D10000216810800000000061681BC00000004A5 +:103D2000021681CC00000004021681D000000001C0 +:103D3000021681D400000002021681D8000000059E +:103D4000021681DC00000005021681E0000000057B +:103D50000216810C00000004021681E40000000538 +:103D6000021681E800000008021681EC000000063F +:103D7000021681F000000007021681100000000109 +:103D800002168114000000020216811800000005CE +:103D90000216809C0000004C021680A00000004C1F +:103DA000061680C400000002021680A40000000075 +:103DB000021680A800000000021680AC0000004C33 +:103DC000061680B0000000050216E6F800000204A6 +:103DD00002168240003F003F02168244003F003F2F +:103DE00006168290000000040216824800800080BF +:103DF0000216824C008000800216825001000100F1 +:103E000002168254010001000616825800000002CA +:103E100002168260004000400216826400400040AA +:103E2000021682681E001E000216826C1E001E0012 +:103E3000021682704000400002168274400040006A +:103E400002168278800080000216827C800080004A +:103E500002168280200020000216828420002000AA +:103E60000616828800000002021680900000004BB7 +:103E700002168060000001400216806400000140CC +:103E8000061680880000000202168068000000000C +:103E90000216806C0000000002168070000000C056 +:103EA00006168074000000050216880C010101014D +:103EB000021688100101200402168814200810013F +:103EC00002168818010101200216881C0101010157 +:103ED00002168820010120040216882420081001FF +:103EE00002168828010101200216882C20081001E2 +:103EF00002168830010101200216883401010101F7 +:103F000002168838010120040216883C200810019E +:103F100002168840010101200216884401010101B6 +:103F200002168848010120040216E6BC00000000C9 +:103F30000216E6C0000000020216E6C400000004FB +:103F40000216E6C8000000060216E7940000000111 +:103F5000021680EC000000FF0214000000000001C7 +:103F60000215C024000000000215C0EC0000000192 +:103F70000215C0F0000000010615C100000000029B +:103F800002140004000000010214000800000001F7 +:103F90000214000C000000010214003000000001B7 +:103FA000021400340000000102140040000000016F +:103FB000021400440000FFFF061400040000000388 +:103FC0000214000000000000060280000000200033 +:103FD0000202005800000032020200A00315002077 +:103FE000020200A403150020020200A80100003014 +:103FF000020200AC08100000020200B0000000360F +:10400000020200B400000030020200B800000031DB +:10401000020200BC00000002020200C00000000515 +:10402000020200C400000002020200C800000002F8 +:10403000020200D000000007020200DC00000000C5 +:10404000020200E000000005020200E4000000039C +:10405000020200F000000001020200FC0000000665 +:1040600002020120000000000202013400000002F0 +:10407000020201B0000000010202020C0000000177 +:1040800002020214000000010202021800000002F5 +:1040900002020404000000010202040C00000040BF +:1040A00002020410000000400202041C0000000490 +:1040B000020204200000002002020424000000028A +:1040C0000202042800000020060205000000001281 +:1040D00004020480002008BF020200600000000FFC +:1040E00002020064000000070202006800000000F5 +:1040F0000202006C0000000E020200700000000EC0 +:104100000602007400000003020200F40000000434 +:104110000202000400000001020200080000000189 +:104120000202000C00000001020200100000000169 +:104130000202001400000001020200180000000149 +:104140000202001C00000001020200200000000129 +:104150000202002400000001020200280000000109 +:104160000202002C000000010202003000000001E9 +:1041700002020034000000010202003800000001C9 +:104180000202003C000000010202004000000001A9 +:104190000202004400000001020200480000000189 +:1041A0000202004C00000001020200500000000169 +:1041B00002020108000000C802020118000000020B +:1041C000020201C400000000020201CC0000000055 +:1041D000020201D400000002020201DC0000000221 +:1041E000020201E4000000FF020201EC000000FFF7 +:1041F00002020100000000000202010C000000C8E1 +:104200000202011C00000002020201C800000000BE +:10421000020201D000000000020201D800000002EA +:10422000020201E000000002020201E8000000FFBB +:10423000020201F0000000FF020201040000002061 +:1042400002020108000000C802020118000000027A +:10425000020201C400000000020201CC00000000C4 +:10426000020201D400000002020201DC0000000290 +:10427000020201E4000000FF020201EC000000FF66 +:1042800002020100000000100202010C000000C840 +:104290000202011C00000002020201C8000000002E +:1042A000020201D000000000020201D8000000025A +:1042B000020201E000000002020201E8000000FF2B +:1042C000020201F0000000FF0202010400000030C1 +:1042D00002020108000000C80202011800000002EA +:1042E000020201C400000000020201CC0000000034 +:1042F000020201D400000002020201DC0000000200 +:10430000020201E4000000FF020201EC000000FFD5 +:1043100002020100000000400202010C000000C87F +:104320000202011C00000002020201C8000000009D +:10433000020201D000000000020201D800000002C9 +:10434000020201E000000002020201E8000000FF9A +:10435000020201F0000000FF020201040000006000 +:1043600002020108000000C8020201180000000259 +:10437000020201C400000000020201CC00000000A3 +:10438000020201D400000002020201DC000000026F +:10439000020201E4000000FF020201EC000000FF45 +:1043A00002020100000000500202010C000000C8DF +:1043B0000202011C00000002020201C8000000000D +:1043C000020201D000000000020201D80000000239 +:1043D000020201E000000002020201E8000000FF0A +:1043E000020201F0000000FF020201040000007060 +:1043F0000728040000B50000082807B8000908DFF6 +:10440000072C000028C30000072C800036720A31F8 +:10441000072D000035B617CE072D80003B00253C48 +:10442000072E0000366D33FD072E80001AA8419933 +:10443000082EBF20281C08E1012800000000000011 +:10444000012800040000000001280008000000000E +:104450000128000C000000000128001000000000EE +:1044600001280014000000000228002000000001C4 +:104470000228002400000002022800280000000397 +:104480000228002C00000000022800300000000478 +:10449000022800340000000102280038000000005B +:1044A0000228003C00000001022800400000000437 +:1044B000022800440000000002280048000000011B +:1044C0000228004C000000030228005000000000F9 +:1044D00002280054000000010228005800000004D7 +:1044E0000228005C000000000228006000000001BB +:1044F0000228006400000003022800680000000099 +:104500000228006C00000001022800700000000476 +:104510000228007400000000022800780000000457 +:104520000228007C00000003062800800000000232 +:10453000022800A400007FFF022800A8000003FF5B +:1045400002280224000000000228023400000000BB +:104550000228024C00000000022802E40000FFFFD5 +:104560000628200000000800022B8BC0000000017C +:10457000022B800000000000022B80400000001889 +:10458000022B80800000000C022B80C0000000661F +:104590000C2B8300000864700A2B83000000015775 +:1045A0000B2B83000000055F0A2B834000000000F6 +:1045B0000C2B8340000002260B2B834000000001DF +:1045C000022B838000086470022B83C00000022647 +:1045D000022B1480000000010A2B14800000000050 +:1045E000022B944000000001062B944800000002BA +:1045F000062A9A7000000004042A9A80000408E346 +:10460000062A9A9000000002042A9A98000208E7FD +:10461000062A900000000048062A2008000000C872 +:10462000062A200000000002062A912800000086C9 +:10463000062AC00000000120062A9348000000035B +:10464000042A9354000108E9062A9FB000000002E2 +:10465000042A9418000208EA042A9CD0000108ECFD +:10466000062A9CD400000011042A9D20008F08ED2A +:10467000062A9F5C00000005042A30000002097C25 +:10468000062A300800000100062A40400000001001 +:10469000042A40000010097E042A84080002098EC2 +:1046A000042ACF4000040990042ACF600002099434 +:1046B000062A9FA000000004062A600000000540B2 +:1046C000062A9D1800000002062AB00000000050D3 +:1046D000062ABB7000000070062ABB6800000002BA +:1046E000062AB94800000004062AD000000008008D +:1046F000062AC48000000150062A942000000032DF +:10470000062A502000000002062A50300000000255 +:10471000062A500000000002062A50100000000285 +:10472000022A520800000001042A9AA000020996F9 +:10473000062A95B000000022042A96380001099844 +:10474000062A963C00000003062A96E0000000229C +:10475000042A976800010999062A976C0000000353 +:10476000062A981000000022042A98980001099A4D +:10477000062A989C00000003062A994000000022A7 +:10478000042A99C80001099B062A99CC000000035D +:10479000062ABB5800000002062AC9C000000150CA +:1047A000062A94E800000032062A50280000000281 +:1047B000062A503800000002062A500800000002B5 +:1047C000062A501800000002022A520C00000001C4 +:1047D000042A9AA80002099C062A96480000002292 +:1047E000042A96D00001099E062A96D400000003F0 +:1047F000062A977800000022042A98000001099FE9 +:10480000062A980400000003062A98A80000002247 +:10481000042A9930000109A0062A993400000003F7 +:10482000062A99D800000022042A9A60000109A1F2 +:10483000062A9A6400000003062ABB6000000002FA +:10484000022ACF0000000000042A9AB0001009A23A +:10485000062A50480000000E022ACF040000000083 +:10486000042A9AF0001009B2062A50800000000EB7 +:10487000022ACF0800000000042A9B30001009C261 +:10488000062A50B80000000E022ACF0C00000000DB +:10489000042A9B70001009D2062A50F00000000E76 +:1048A000022ACF1000000000042A9BB0001009E289 +:1048B000062A51280000000E022ACF140000000032 +:1048C000042A9BF0001009F2062A51600000000E35 +:1048D000022ACF1800000000042A9C3000100A02AF +:1048E000062A51980000000E022ACF1C000000008A +:1048F000042A9C7000100A12062A51D00000000EF3 +:104900000210100800000001021010500000000109 +:10491000021010000003D000021010040000003D3F +:104920000910180002000A220910110000100C22C0 +:1049300006101140000000080910116000100C3230 +:10494000061011A00000001806102400000000E06E +:104950000210201C000000000210202000000001B6 +:10496000021020C00000000202102004000000011C +:104970000210200800000001021030D800000001E1 +:1049800009103C0000050C420910380000050C47D6 +:104990000910392000050C4C09103B0000050C5192 +:1049A00006104C000000010002104028000000101A +:1049B0000210404400003FFF021040580028000051 +:1049C000021040840084924A021040580000000007 +:1049D00002104138000000010210413800000001BF +:1049E00002104138000000010210413800000001AF +:1049F000021041380000000102104138000000019F +:104A0000021041380000000102104138000000018E +:104A10000212049001F680400212051400003C10BE +:104A200002120494FFFFFFFF02120498FFFFFFFF32 +:104A30000212049CFFFFFFFF021204A0FFFFFFFF12 +:104A4000021204A4FFFFFFFF021204A8FFFFFFFFF2 +:104A5000021204ACFFFFFFFF021204B0FFFFFFFFD2 +:104A6000021204B8FFFFFFFF021204BCFFFFFFFFAA +:104A7000021204C0FFFFFFFF021204C4FFFFFFFF8A +:104A8000021204C8FFFFFFFF021204CCFFFFFFFF6A +:104A9000021204D0FFFFFFFF021204D8FFFFFFFF46 +:104AA000021204DCFFFFFFFF021204E0FFFFFFFF22 +:104AB000021204E4FFFFFFFF021204E8FFFFFFFF02 +:104AC000021204ECFFFFFFFF021204F0FFFFFFFFE2 +:104AD000021204F4FFFFFFFF021204F8FFFFFFFFC2 +:104AE000021204FCFFFFFFFF02120500FFFFFFFFA1 +:104AF00002120504FFFFFFFF02120508FFFFFFFF80 +:104B00000212050CFFFFFFFF02120510FFFFFFFF5F +:104B1000021204D4F800C000021204B4F0005000E5 +:104B200002120390000000080212039C000000081B +:104B3000021203A000000008021203A400000002F9 +:104B4000021203BC00000004021203C000000005B2 +:104B5000021203C400000004021203D0000000008F +:104B60000212036C00000001021201BC00000040B0 +:104B7000021201C000001808021201C4000008035C +:104B8000021201C800000803021201CC000000401C +:104B9000021201D000000003021201D40000080339 +:104BA000021201D800000803021201DC0000080311 +:104BB000021201E000010003021201E400000803F8 +:104BC000021201E800000803021201EC00000003D9 +:104BD000021201F000000003021201F400000003C1 +:104BE000021201F800000003021201FC00000003A1 +:104BF000021202000000000302120204000000037F +:104C000002120208000000030212020C000000035E +:104C1000021202100000000302120214000000033E +:104C200002120218000000030212021C000000031E +:104C300002120220000000030212022400000003FE +:104C400002120228000024030212022C0000002F8E +:104C500002120230000000090212023400000019A2 +:104C600002120238000001840212023C000001839B +:104C70000212024000000306021202440000001962 +:104C800002120248000000060212024C0000030655 +:104C90000212025000000306021202540000030632 +:104CA0000212025800000C860212025C0000030689 +:104CB00002120260000003060212026400000006F5 +:104CC00002120268000000060212026C00000006D8 +:104CD00002120270000000060212027400000006B8 +:104CE00002120278000000060212027C0000000698 +:104CF0000212028000000006021202840000000678 +:104D000002120288000000060212028C0000000657 +:104D10000212029000000006021202940000000637 +:104D200002120298000000060212029C0000000617 +:104D3000021202A000000306021202A400000013E7 +:104D4000021202A800000006021202B000001004C5 +:104D5000021202B400001004021203240010644086 +:104D60000212032800106440021205B40000000182 +:104D7000021205F800000040021205FC00000019B4 +:104D800002120600000000010212066C0000000181 +:104D9000021201B000000001021207D80000000357 +:104DA000021207D800000003021207D80000000317 +:104DB000021207D800000003021207D80000000307 +:104DC000021207D800000003021207D800000003F7 +:104DD000021207D8000000030600A0000000000C2B +:104DE0000200A050000000000200A05400000000DB +:104DF0000200A0EC555400000200A0F05555555596 +:104E00000200A0F4000055550200A0F8F0000000D8 +:104E10000200A0FC555400000200A1005555555554 +:104E20000200A104000055550200A108F000000096 +:104E30000200A19C000000000200A1A000010000EF +:104E40000200A1A4000050140200A1A8000000006C +:104E50000200A6A8000000000200A6AC00000000AE +:104E60000200A6D0000000000200A45C00000C00BC +:104E70000200A61C000000030200A070FFF55FFF07 +:104E80000200A0740000FFFF0200A078F00003E021 +:104E90000200A07C000000000200A0800000A00032 +:104EA0000600A084000000050200A0980FE00000AA +:104EB0000600A09C000000070200A0B8000004004B +:104EC0000600A0BC000000030200A0C80000100003 +:104ED0000600A0CC000000030200A0D800004000A3 +:104EE0000600A0DC000000030200A0E800010000B2 +:104EF0000600A22C000000040200A688000000FCAE +:104F00000600A68C000000070200A6F400000000C6 +:104F10000200A10CFF5C00000200A110FFF55FFF82 +:104F20000200A1140000FFFF0200A118F00003E03E +:104F30000200A11C000000000200A1200000A0004F +:104F40000600A124000000050200A1380FE00000C7 +:104F50000600A13C000000070200A1580000080064 +:104F60000600A15C000000030200A1680000200010 +:104F70000600A16C000000030200A1780000800080 +:104F80000600A17C000000030200A18800020000CE +:104F90000600A23C000000040200A6B0000000FCD5 +:104FA0000600A6B4000000070200A6F800000000FA +:104FB0000200A030000000000200A0340000000049 +:104FC0000200A038000000000200A03C0000000029 +:104FD0000200A040000000000200A0440000000009 +:104FE0000200A048000000000200A04C00000000E9 +:104FF000020090C40000E000020090CC0000F3002A +:10500000020090D400000003020091A00000000103 +:105010000600917000000003020090EC00006000A8 +:10502000020090F400007300020090FC00000003F6 +:10503000020091A800000001060091880000000312 +:10504000020091000000400002009108000053009F +:105050000200911000000004020091AC0000000169 +:1050600006009194000000020200919C00000001E3 +:10507000020090D800006000020090E00000730081 +:10508000020090E800000003020091A4000000016B +:105090000200917C000000010200918000000001EC +:1050A000020091840000000002009128000003002B +:1050B0000200916C0003F0080200912C0000030034 +:1050C0000200913000000300020091340000030050 +:1050D00002009138000003000200913C0000030030 +:1050E00002009140000003000200942C0000000127 +:1050F000020094300000000102009434000000011E +:105100000200942C00000001020094300000000115 +:1051100002009434000000010200942C0000000101 +:1051200002009430000000010200943400000001ED +:105130000200942C000000010200943000000001E5 +:1051400002009434000000010200942C00000001D1 +:1051500002009430000000010200943400000001BD +:105160000200942C000000010200943000000001B5 +:1051700002009434000000010200942C00000001A1 +:10518000020094300000000102009434000000018D +:105190000200942C00000001020094300000000185 +:1051A00002009434000000010213003C000061A8DA +:1051B00006130108000000030213010400000000B0 +:1051C0000213013400000000061301080000000370 +:1051D000021301040000000002130134000000006B +:1051E0000613010800000003021301040000000080 +:1051F0000213013400000000061301080000000340 +:10520000021301040000000002130134000000003A +:10521000061301080000000302130104000000004F +:10522000021301340000000006130108000000030F +:10523000021301040000000002130134000000000A +:10524000061301080000000302130104000000001F +:1052500002130134000000000613010800000003DF +:1052600002130104000000000213013400000000DA +:10527000021100B8000000010216E6E8000020005C +:105280000216E6EC000020000216E6F0000065556C +:105290000216E6F400006555021681500000000079 +:1052A00002168174000000010216817800000001DE +:1052B0000216817C000000010216818000000001BE +:1052C000021681840000000102168188000000019E +:1052D000021681B400000001021681B8000000012E +:1052E000021681BC00000001021681C0000000010E +:1052F000021681C400000001021681C800000001EE +:1053000002168110000000000216824000BF00BF9C +:1053100006168244000000020216824C00BF00BF45 +:105320000216E6C4000000010216E6C800000003F1 +:105330000216E79400000000042ACF40000A0C5631 +:105340000000000000000000000000340000000029 +:10535000000000000000000000000000000000004D +:10536000000000000000000000000000000000003D +:1053700000000000003400350000000000000000C4 +:10538000000000000000000000000000000000001D +:10539000000000000000000000000000000000000D +:1053A0000035006000000000000000000000000068 +:1053B00000000000000000000000000000000000ED +:1053C00000000000000000000000000000600091EC +:1053D0000000000000000000009100950095009979 +:1053E0000099009D009D00A100A100A500A500A9B5 +:1053F00000A900AD00AD00B100B100B50000000093 +:10540000000000000000000000000000000000009C +:10541000000000000000000000000000000000008C +:105420000000000000B503100310031A031A032440 +:105430000324032B032B03320332033903390340C4 +:10544000034003470347034E034E03550355035CD4 +:10545000000000000000000000000000000000004C +:10546000000000000000000000000000000000003C +:10547000000000000000000000000000000000002C +:10548000000000000000000000000000000000001C +:10549000000000000000000000000000000000000C +:1054A00000000000000000000000000000000000FC +:1054B00000000000000000000000000000000000EC +:1054C00000000000000000000000000000000000DC +:1054D00000000000000000000000000000000000CC +:1054E00000000000000000000000000000000000BC +:1054F00000000000000000000000000000000000AC +:10550000035C035D0000000000000000035D035E1B +:10551000035E035F035F0360036003610361036273 +:105520000362036303630364036403650000000014 +:10553000000000000000000000000000000000006B +:10554000000000000000000000000000000000005B +:1055500000000000000000000365036C036C03788A +:105560000378038400000000000000000000000039 +:10557000000000000000000000000000000000002B +:10558000000000000000000000000000000000001B +:10559000000000000000000000000000000000000B +:1055A00000000000000000000000000000000000FB +:1055B00003840385000000000000000000000000DC +:1055C00000000000000000000000000000000000DB +:1055D000000000000000000000000000038503B090 +:1055E00000000000000000000000000000000000BB +:1055F00000000000000000000000000000000000AB +:10560000000000000000000003B003DF0000000005 +:10561000000000000000000000000000000000008A +:10562000000000000000000000000000000000007A +:105630000000000003DF040E000000000000000076 +:10564000040E04150415041C041C04230423042A5A +:10565000042A0431043104380438043F043F04466A +:105660000446047900000000000000000479047D75 +:10567000047D048104810485048504890489048DE2 +:10568000048D04910491049504950499049904E807 +:1056900004E804FE04FE0514051405160516051895 +:1056A0000518051A051A051C051C051E051E0520F2 +:1056B000052005220522052405240690000000008F +:1056C00000000000069006950695069A069A069F29 +:1056D000069F06A406A406A906A906AE06AE06B352 +:1056E00006B306B806B806B90000000000000000C6 +:1056F00000000000000000000000000000000000AA +:105700000000000000000000000000000000000099 +:1057100006B906DD000000000000000006DD06DF1F +:1057200006DF06E106E106E306E306E506E506E731 +:1057300006E706E906E906EB06EB06ED06ED0702CD +:105740000702070507050708000000000000000029 +:105750000000000000000000000000000000000049 +:1057600000000000000000000708074C00000000D7 +:105770000000000000000000000000000000000029 +:105780000000000000000000000000000000000019 +:1057900000000000074C07DE0000000000000000D1 +:1057A00000000000000000000000000000000000F9 +:1057B00000000000000000000000000000000000E9 +:1057C00007DE07EC00000000000000000000000001 +:1057D00000000000000000000000000000000000C9 +:1057E00000000000000000000000000007EC082995 +:1057F0000000000000000000082908320832083BC1 +:10580000083B08440844084D084D08560856085FF0 +:10581000085F086808680871087108D108D108E6AF +:1058200008E608FB08FB08FE08FE09010901090457 +:10583000090409070907090A090A090D090D0910D0 +:10584000091009130913091C0000000000000000E2 +:105850000000000000000000000000000000000048 +:105860000000000000000000000000000000000038 +:10587000091C0922000000000000000000000000D8 +:105880000000000000000000000000000000000018 +:1058900000000000000000000000000009220927AD +:1058A00000000000000000000000000000000000F8 +:1058B00000000000000000000000000000000000E8 +:1058C00000000000000000000927092D0000000072 +:1058D00000000000092D092E092E092F092F09307B +:1058E00009300931093109320932093309330934E0 +:1058F000093409350000000000000000000000002D +:105900000000000000000000000000000000000097 +:105910000000000000000000000000000000000087 +:10592000093509A6000000000000000009A609A72B +:1059300009A709A809A809A909A909AA09AA09ABD7 +:1059400009AB09AC09AC09AD09AD09AE09AE09C294 +:1059500009C209D509D509E909E909EA09EA09EB02 +:1059600009EB09EC09EC09ED09ED09EE09EE09EF87 +:1059700009EF09F009F009F109F10A10000000002F +:10598000000000000A100A130A130A160A160A1960 +:105990000A190A1C0A1C0A1F0A1F0A220A220A25BF +:1059A0000A250A280A280A29000000000000000031 +:1059B0000A290A2C0A2C0A2F0A2F0A320A320A351F +:1059C0000A350A380A380A3B0A3B0A3E0A3E0A41AF +:1059D0000A410A4200000000000000000000000030 +:1059E00000000000000000000000000000000000B7 +:1059F0000000000000000000000000000A420A5AF7 +:105A00000000000000000000000000000000000096 +:105A10000000000000000000000000000000000086 +:105A200000000000000000000A5A0A5B00000000AD +:105A30000000000000000000000000000000000066 +:105A40000000000000000000000000000000000056 +:105A5000000000000000000000010000000207003C +:105A600000030E000004150000051C0000062300C2 +:105A700000072A000008310000093800000A3F0032 +:105A8000000B4600000C4D00000D5400000E5B00A2 +:105A9000000F620000106900001170000012770012 +:105AA00000137E000014850000158C000016930082 +:105AB00000179A000018A1000019A800001AAF00F2 +:105AC000001BB600001CBD00001DC400001ECB0062 +:105AD000001FD2000000D90000002000000040009C +:105AE00000006000000080000000A0000000C00076 +:105AF0000000E00000010000000120000001400063 +:105B000000016000000180000001A0000001C00051 +:105B10000001E0000002000000022000000240003E +:105B200000026000000280000002A0000002C0002D +:105B30000002E0000003000000032000000340001A +:105B400000036000000380000003A0000003C00009 +:105B50000003E000000400000004200000044000F6 +:105B600000046000000480000004A0000004C000E5 +:105B70000004E000000500000005200000054000D2 +:105B800000056000000580000005A0000005C000C1 +:105B90000005E000000600000006200000064000AE +:105BA00000066000000680000006A0000006C0009D +:105BB0000006E0000007000000072000000740008A +:105BC00000076000000780000007A0000007C00079 +:105BD0000007E00000080000000820000008400066 +:105BE00000086000000880000008A0000008C00055 +:105BF0000008E00000090000000920000009400042 +:105C000000096000000980000009A0000009C00030 +:105C10000009E000000A0000000A2000000A40001D +:105C2000000A6000000A8000000AA000000AC0000C +:105C3000000AE000000B0000000B2000000B4000F9 +:105C4000000B6000000B8000000BA000000BC000E8 +:105C5000000BE000000C0000000C2000000C4000D5 +:105C6000000C6000000C8000000CA000000CC000C4 +:105C7000000CE000000D0000000D2000000D4000B1 +:105C8000000D6000000D8000000DA000000DC000A0 +:105C9000000DE000000E0000000E2000000E40008D +:105CA000000E6000000E8000000EA000000EC0007C +:105CB000000EE000000F0000000F2000000F400069 +:105CC000000F6000000F8000000FA000000FC00058 +:105CD000000FE00000100000001020000010400045 +:105CE00000106000001080000010A0000010C00034 +:105CF0000010E00000110000001120000011400021 +:105D000000116000001180000011A0000011C0000F +:105D10000011E000001200000012200000124000FC +:105D200000126000001280000012A0000012C000EB +:105D30000012E000001300000013200000134000D8 +:105D400000136000001380000013A0000013C000C7 +:105D50000013E000001400000014200000144000B4 +:105D600000146000001480000014A0000014C000A3 +:105D70000014E00000150000001520000015400090 +:105D800000156000001580000015A0000015C0007F +:105D90000015E0000016000000162000001640006C +:105DA00000166000001680000016A0000016C0005B +:105DB0000016E00000170000001720000017400048 +:105DC00000176000001780000017A0000017C00037 +:105DD0000017E00000180000001820000018400024 +:105DE00000186000001880000018A0000018C00013 +:105DF0000018E00000190000001920000019400000 +:105E000000196000001980000019A0000019C000EE +:105E10000019E000001A0000001A2000001A4000DB +:105E2000001A6000001A8000001AA000001AC000CA +:105E3000001AE000001B0000001B2000001B4000B7 +:105E4000001B6000001B8000001BA000001BC000A6 +:105E5000001BE000001C0000001C2000001C400093 +:105E6000001C6000001C8000001CA000001CC00082 +:105E7000001CE000001D0000001D2000001D40006F +:105E8000001D6000001D8000001DA000001DC0005E +:105E9000001DE000001E0000001E2000001E40004B +:105EA000001E6000001E8000001EA000001EC0003A +:105EB000001EE000001F0000001F2000001F400027 +:105EC000001F6000001F8000001FA000001FC00016 +:105ED000001FE00000200000002020000020400003 +:105EE00000206000002080000020A0000020C000F2 +:105EF0000020E000002100000021200000214000DF +:105F000000216000002180000021A0000021C000CD +:105F10000021E000002200000022200000224000BA +:105F200000226000002280000022A0000022C000A9 +:105F30000022E00000230000002320000023400096 +:105F400000236000002380000023A0000023C00085 +:105F50000023E00000240000002420000024400072 +:105F600000246000002480000024A0000024C00061 +:105F70000024E0000025000000252000002540004E +:105F800000256000002580000025A0000025C0003D +:105F90000025E0000026000000262000002640002A +:105FA00000266000002680000026A0000026C00019 +:105FB0000026E00000270000002720000027400006 +:105FC00000276000002780000027A0000027C000F5 +:105FD0000027E000002800000028200000284000E2 +:105FE00000286000002880000028A0000028C000D1 +:105FF0000028E000002900000029200000294000BE +:1060000000296000002980000029A0000029C000AC +:106010000029E000002A0000002A2000002A400099 +:10602000002A6000002A8000002AA000002AC00088 +:10603000002AE000002B0000002B2000002B400075 +:10604000002B6000002B8000002BA000002BC00064 +:10605000002BE000002C0000002C2000002C400051 +:10606000002C6000002C8000002CA000002CC00040 +:10607000002CE000002D0000002D2000002D40002D +:10608000002D6000002D8000002DA000002DC0001C +:10609000002DE000002E0000002E2000002E400009 +:1060A000002E6000002E8000002EA000002EC000F8 +:1060B000002EE000002F0000002F2000002F4000E5 +:1060C000002F6000002F8000002FA000002FC000D4 +:1060D000002FE000003000000030200000304000C1 +:1060E00000306000003080000030A0000030C000B0 +:1060F0000030E0000031000000312000003140009D +:1061000000316000003180000031A0000031C0008B +:106110000031E00000320000003220000032400078 +:1061200000326000003280000032A0000032C00067 +:106130000032E00000330000003320000033400054 +:1061400000336000003380000033A0000033C00043 +:106150000033E00000340000003420000034400030 +:1061600000346000003480000034A0000034C0001F +:106170000034E0000035000000352000003540000C +:1061800000356000003580000035A0000035C000FB +:106190000035E000003600000036200000364000E8 +:1061A00000366000003680000036A0000036C000D7 +:1061B0000036E000003700000037200000374000C4 +:1061C00000376000003780000037A0000037C000B3 +:1061D0000037E000003800000038200000384000A0 +:1061E00000386000003880000038A0000038C0008F +:1061F0000038E0000039000000392000003940007C +:1062000000396000003980000039A0000039C0006A +:106210000039E000003A0000003A2000003A400057 +:10622000003A6000003A8000003AA000003AC00046 +:10623000003AE000003B0000003B2000003B400033 +:10624000003B6000003B8000003BA000003BC00022 +:10625000003BE000003C0000003C2000003C40000F +:10626000003C6000003C8000003CA000003CC000FE +:10627000003CE000003D0000003D2000003D4000EB +:10628000003D6000003D8000003DA000003DC000DA +:10629000003DE000003E0000003E2000003E4000C7 +:1062A000003E6000003E8000003EA000003EC000B6 +:1062B000003EE000003F0000003F2000003F4000A3 +:1062C000003F6000003F8000003FA000003FC00092 +:1062D000003FE000003FE00100000000000001FF7F +:1062E0000000020000007FF800007FF800000A9420 +:1062F00000001500000000010000FF000000000089 +:106300000000FF00000000000000FF00000000008F +:106310000000FF00000000000000FF00000000007F +:106320000000FF00000000000000FF00000000006F +:106330000000FF00000000000000FF00000000005F +:106340000000FF00000000000000FF00000000004F +:106350000000FF00000000000000FF00000000003F +:106360000000FF00000000000000FF00000000002F +:106370000000FF00000000000000FF00000000001F +:106380000000FF00000000000000FF00000000000F +:106390000000FF00000000000000FF0000000000FF +:1063A0000000FF00000000000000FF0000000000EF +:1063B0000000FF00000000000000FF0000000000DF +:1063C0000000FF00000000000000FF0000000000CF +:1063D0000000FF00000000000000FF0000000000BF +:1063E0000000FF00000000000000FF0000000000AF +:1063F0000000FF00000000000000FF00000000009F +:106400000000FF00000000000000FF00000000008E +:106410000000FF00000000000000FF00000000007E +:106420000000FF00000000000000FF00000000006E +:106430000000FF00000000000000FF00000000005E +:106440000000FF00000000000000FF00000000004E +:106450000000FF00000000000000FF00000000003E +:106460000000FF00000000000000FF00000000002E +:106470000000FF00000000000000FF00000000001E +:106480000000FF00000000000000FF00000000000E +:106490000000FF00000000000000FF0000000000FE +:1064A0000000FF00000000000000FF0000000000EE +:1064B0000000FF00000000000000FF0000000000DE +:1064C0000000FF00000000000000FF0000000000CE +:1064D0000000FF00000000000000FF0000000000BE +:1064E0000000FF00000000000000FF0000000000AE +:1064F0000000FF00000000000000FF00000000009E +:106500000000FF00000000000000FF00000000008D +:106510000000FF00000000000000FF00000000007D +:106520000000FF00000000000000FF00000000006D +:106530000000FF000000000000000000140AFF003F +:106540000000000100000000002010010000000019 +:106550000100900000000100000090020000900483 +:1065600000009006000090080000900A0000900CC7 +:106570000000900E00009010000090120000901497 +:1065800000009016000090180000901A0000901C67 +:106590000000901E00009020000090220000902437 +:1065A00000009026000090280000902A0000902C07 +:1065B0000000902E000090300000903200009034D7 +:1065C00000009036000090380000903A0000903CA7 +:1065D0000000903E00009040000090420000904477 +:1065E00000009046000090480000904A0000904C47 +:1065F0000000904E00009050000090520000905417 +:1066000000009056000090580000905A0000905CE6 +:106610000000905E000090600000906200009064B6 +:1066200000009066000090680000906A0000906C86 +:106630000000906E00009070000090720000907456 +:1066400000009076000090780000907A0000907C26 +:106650000000907E000090800000908200009084F6 +:1066600000009086000090880000908A0000908CC6 +:106670000000908E00009090000090920000909496 +:1066800000009096000090980000909A0000909C66 +:106690000000909E000090A0000090A2000090A436 +:1066A000000090A6000090A8000090AA000090AC06 +:1066B000000090AE000090B0000090B2000090B4D6 +:1066C000000090B6000090B8000090BA000090BCA6 +:1066D000000090BE000090C0000090C2000090C476 +:1066E000000090C6000090C8000090CA000090CC46 +:1066F000000090CE000090D0000090D2000090D416 +:10670000000090D6000090D8000090DA000090DCE5 +:10671000000090DE000090E0000090E2000090E4B5 +:10672000000090E6000090E8000090EA000090EC85 +:10673000000090EE000090F0000090F2000090F455 +:10674000000090F6000090F8000090FA000090FC25 +:10675000000090FE000091000000910200009104F2 +:1067600000009106000091080000910A0000910CC1 +:106770000000910E00009110000091120000911491 +:1067800000009116000091180000911A0000911C61 +:106790000000911E00009120000091220000912431 +:1067A00000009126000091280000912A0000912C01 +:1067B0000000912E000091300000913200009134D1 +:1067C00000009136000091380000913A0000913CA1 +:1067D0000000913E00009140000091420000914471 +:1067E00000009146000091480000914A0000914C41 +:1067F0000000914E00009150000091520000915411 +:1068000000009156000091580000915A0000915CE0 +:106810000000915E000091600000916200009164B0 +:1068200000009166000091680000916A0000916C80 +:106830000000916E00009170000091720000917450 +:1068400000009176000091780000917A0000917C20 +:106850000000917E000091800000918200009184F0 +:1068600000009186000091880000918A0000918CC0 +:106870000000918E00009190000091920000919490 +:1068800000009196000091980000919A0000919C60 +:106890000000919E000091A0000091A2000091A430 +:1068A000000091A6000091A8000091AA000091AC00 +:1068B000000091AE000091B0000091B2000091B4D0 +:1068C000000091B6000091B8000091BA000091BCA0 +:1068D000000091BE000091C0000091C2000091C470 +:1068E000000091C6000091C8000091CA000091CC40 +:1068F000000091CE000091D0000091D2000091D410 +:10690000000091D6000091D8000091DA000091DCDF +:10691000000091DE000091E0000091E2000091E4AF +:10692000000091E6000091E8000091EA000091EC7F +:10693000000091EE000091F0000091F2000091F44F +:10694000000091F6000091F8000091FA000091FC1F +:10695000000091FEFFFFFFFFFFFFFFFFFFFFFFFFB4 +:10696000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37 +:10697000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF27 +:10698000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17 +:10699000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07 +:1069A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7 +:1069B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE7 +:1069C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD7 +:1069D000FFFFFFFF0000000300BEBC20000000001E +:1069E000000000050000000300BEBC200000000005 +:1069F000000000050000000300BEBC2000000000F5 +:106A0000000000050000000300BEBC2000000000E4 +:106A1000000000050000000300BEBC2000000000D4 +:106A2000000000050000000300BEBC2000000000C4 +:106A3000000000050000000300BEBC2000000000B4 +:106A4000000000050000000300BEBC2000000000A4 +:106A50000000000500002000000040C00000618030 +:106A6000000082400000A3000000C3C00000E480DA +:106A70000001054000012600000146C000016780BA +:106A8000000188400001A9000001C9C00001EA809E +:106A900000020B4000022C0000024CC000026D807E +:106AA00000028E400002AF000002CFC00002F08062 +:106AB00000001140000080000001038000018700F9 +:106AC00000020A8000028E0000031180000395007E +:106AD0000004188000049C0000051F800005A3002E +:106AE000000626800006AA0000072D800007B100DE +:106AF000000834800008B80000093B800009BF008E +:106B0000000A4280000AC600000B4980000BCD003D +:106B1000000C5080000CD400000D578000005B007A +:106B200000007FF800007FF80000022A0000350016 +:106B30000000FF00000000000000FF000000000057 +:106B40000000FF00000000000000FF000000000047 +:106B50000000FF00000000000000FF000000000037 +:106B60000000FF00000000000000FF000000000027 +:106B70000000FF00000000000000FF000000000017 +:106B80000000FF00000000000000FF000000000007 +:106B90000000FF00000000000000FF0000000000F7 +:106BA0000000FF00000000000000FF0000000000E7 +:106BB0000000FF00000000000000FF0000000000D7 +:106BC0000000FF00000000000000FF0000000000C7 +:106BD0000000FF00000000000000FF0000000000B7 +:106BE0000000FF00000000000000FF0000000000A7 +:106BF0000000FF00000000000000FF000000000097 +:106C00000000FF00000000000000FF000000000086 +:106C10000000FF00000000000000FF000000000076 +:106C20000000FF00000000000000FF000000000066 +:106C30000000FF00000000000000FF000000000056 +:106C40000000FF00000000000000FF000000000046 +:106C50000000FF00000000000000FF000000000036 +:106C60000000FF00000000000000FF000000000026 +:106C70000000FF00000000000000FF000000000016 +:106C80000000FF00000000000000FF000000000006 +:106C90000000FF00000000000000FF0000000000F6 +:106CA0000000FF00000000000000FF0000000000E6 +:106CB0000000FF00000000000000FF0000000000D6 +:106CC0000000FF00000000000000FF0000000000C6 +:106CD0000000FF00000000000000FF0000000000B6 +:106CE0000000FF00000000000000FF0000000000A6 +:106CF0000000FF00000000000000FF000000000096 +:106D00000000FF00000000000000FF000000000085 +:106D10000000FF00000000000000FF000000000075 +:106D20000000FF00000000000000FF000000000065 +:106D30000000FF00000000000000FF000000000055 +:106D40000000FF00000000000000FF000000000045 +:106D50000000FF00000000000000FF000000000035 +:106D60000000FF00000000000000FF00000019000C +:106D70000000000000000000FFFFFFFF0000000017 +:106D800003938700000000000393870000007FF852 +:106D900000007FF800000BA700003500000000FF96 +:106DA000000000FF000000FF000000FF000000FFE7 +:106DB000000000FF000000FF000000FF0000FF00D7 +:106DC000000000000000FF00000000000000FF00C5 +:106DD000000000000000FF00000000000000FF00B5 +:106DE000000000000000FF00000000000000FF00A5 +:106DF000000000000000FF00000000000000FF0095 +:106E0000000000000000FF00000000000000FF0084 +:106E1000000000000000FF00000000000000FF0074 +:106E2000000000000000FF00000000000000FF0064 +:106E3000000000000000FF00000000000000FF0054 +:106E4000000000000000FF00000000000000FF0044 +:106E5000000000000000FF00000000000000FF0034 +:106E6000000000000000FF00000000000000FF0024 +:106E7000000000000000FF00000000000000FF0014 +:106E8000000000000000FF00000000000000FF0004 +:106E9000000000000000FF00000000000000FF00F4 +:106EA000000000000000FF00000000000000FF00E4 +:106EB000000000000000FF00000000000000FF00D4 +:106EC000000000000000FF00000000000000FF00C4 +:106ED000000000000000FF00000000000000FF00B4 +:106EE000000000000000FF00000000000000FF00A4 +:106EF000000000000000FF00000000000000FF0094 +:106F0000000000000000FF00000000000000FF0083 +:106F1000000000000000FF00000000000000FF0073 +:106F2000000000000000FF00000000000000FF0063 +:106F3000000000000000FF00000000000000FF0053 +:106F4000000000000000FF00000000000000FF0043 +:106F5000000000000000FF00000000000000FF0033 +:106F6000000000000000FF00000000000000FF0023 +:106F7000000000000000FF00000000000000FF0013 +:106F8000000000000000FF00000000000000FF0003 +:106F9000000000000000FF00000000000000FF00F3 +:106FA000000000000000FF00000000000000FF00E3 +:106FB000000000000000FF00000000000000FF00D3 +:106FC000000000000000FF00000000000000FF00C3 +:106FD000000000000000FF00000000000000FF00B3 +:106FE000000000000000FF00000000000000FF00A3 +:106FF000000000000000FF0000000000FFFFFFFF96 +:10700000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 +:10701000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 +:10702000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 +:10703000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 +:10704000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 +:10705000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:10706000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 +:10707000FFFFFFFFFFFFFFFFFFFFFFFF000000001C +:10708000000028AD000029180000291900000005A3 +:10709000000000070000FF000FFFFFFF0000FF00DF +:1070A0000FFFFFFF000000FF0000FF000000FF00D7 +:1070B0000FFFFFFF0000FF000FFFFFFF000000FFBA +:1070C0000000FF000000FF000FFFFFFF0000FF00B7 +:1070D0000FFFFFFF000000FF0000FF000000FF00A7 +:1070E0000FFFFFFF0000FF000FFFFFFF000000FF8A +:1070F0000000FF000000FF000FFFFFFF0000FF0087 +:107100000FFFFFFF000000FF0000FF000000FF0076 +:107110000FFFFFFF0000FF000FFFFFFF000000FF59 +:107120000000FF000000FF000FFFFFFF0000FF0056 +:107130000FFFFFFF000000FF0000FF000000FF0046 +:107140000FFFFFFF0000FF000FFFFFFF000000FF29 +:107150000000FF000000FF000FFFFFFF0000FF0026 +:107160000FFFFFFF000000FF0000FF000000FF0016 +:107170000FFFFFFF0000FF000FFFFFFF000000FFF9 +:107180000000FF000000FF000FFFFFFF0000FF00F6 +:107190000FFFFFFF000000FF0000FF000000FF00E6 +:1071A0000FFFFFFF0000FF000FFFFFFF000000FFC9 +:1071B0000000FF000000FF000FFFFFFF0000FF00C6 +:1071C0000FFFFFFF000000FF0000FF000000FF00B6 +:1071D0000FFFFFFF0000FF000FFFFFFF000000FF99 +:1071E0000000FF000000FF000FFFFFFF0000FF0096 +:1071F0000FFFFFFF000000FF0000FF000000FF0086 +:107200000FFFFFFF0000FF000FFFFFFF000000FF68 +:107210000000FF000000FF000FFFFFFF0000FF0065 +:107220000FFFFFFF000000FF0000FF000000FF0055 +:107230000FFFFFFF0000FF000FFFFFFF000000FF38 +:107240000000FF000000FF000FFFFFFF0000FF0035 +:107250000FFFFFFF000000FF0000FF000000FF0025 +:107260000FFFFFFF0000FF000FFFFFFF000000FF08 +:107270000000FF000000FF000FFFFFFF0000FF0005 +:107280000FFFFFFF000000FF0000FF000000FF00F5 +:107290000FFFFFFF0000FF000FFFFFFF000000FFD8 +:1072A0000000FF000000FF000FFFFFFF0000FF00D5 +:1072B0000FFFFFFF000000FF0000FF000000FF00C5 +:1072C0000FFFFFFF0000FF000FFFFFFF000000FFA8 +:1072D0000000FF000000FF000FFFFFFF0000FF00A5 +:1072E0000FFFFFFF000000FF0000FF000000FF0095 +:1072F0000FFFFFFF0000FF000FFFFFFF000000FF78 +:107300000000FF000000FF000FFFFFFF0000FF0074 +:107310000FFFFFFF000000FF0000FF000000FF0064 +:107320000FFFFFFF0000FF000FFFFFFF000000FF47 +:107330000000FF000000FF000FFFFFFF0000FF0044 +:107340000FFFFFFF000000FF0000FF000000FF0034 +:107350000FFFFFFF0000FF000FFFFFFF000000FF17 +:107360000000FF000000FF000FFFFFFF0000FF0014 +:107370000FFFFFFF000000FF0000FF000000FF0004 +:107380000FFFFFFF0000FF000FFFFFFF000000FFE7 +:107390000000FF000000FF000FFFFFFF0000FF00E4 +:1073A0000FFFFFFF000000FF0000FF000000FF00D4 +:1073B0000FFFFFFF0000FF000FFFFFFF000000FFB7 +:1073C0000000FF000000FF000FFFFFFF0000FF00B4 +:1073D0000FFFFFFF000000FF0000FF000000FF00A4 +:1073E0000FFFFFFF0000FF000FFFFFFF000000FF87 +:1073F0000000FF000000FF000FFFFFFF0000FF0084 +:107400000FFFFFFF000000FF0000FF000000FF0073 +:107410000FFFFFFF0000FF000FFFFFFF000000FF56 +:107420000000FF000000FF000FFFFFFF0000FF0053 +:107430000FFFFFFF000000FF0000FF000000FF0043 +:107440000FFFFFFF0000FF000FFFFFFF000000FF26 +:107450000000FF000000FF000FFFFFFF0000FF0023 +:107460000FFFFFFF000000FF0000FF000000FF0013 +:107470000FFFFFFF0000FF000FFFFFFF000000FFF6 +:107480000000FF000000FF000FFFFFFF0000FF00F3 +:107490000FFFFFFF000000FF0000FF000000FF00E3 +:1074A0000FFFFFFF0000FF000FFFFFFF000000FFC6 +:1074B0000000FF000000FF000FFFFFFF0000FF00C3 +:1074C0000FFFFFFF000000FF0000FF000000FF00B3 +:1074D0000FFFFFFF0000FF000FFFFFFF000000FF96 +:1074E0000000FF000000FF000FFFFFFF0000FF0093 +:1074F0000FFFFFFF000000FF0000FF000000FF0083 +:107500000FFFFFFF0000FF000FFFFFFF000000FF65 +:107510000000FF000000FF000FFFFFFF0000FF0062 +:107520000FFFFFFF000000FF0000FF000000FF0052 +:107530000FFFFFFF0000FF000FFFFFFF000000FF35 +:107540000000FF000000FF000FFFFFFF0000FF0032 +:107550000FFFFFFF000000FF0000FF000000FF0022 +:107560000FFFFFFF0000FF000FFFFFFF000000FF05 +:107570000000FF000000FF000FFFFFFF0000FF0002 +:107580000FFFFFFF000000FF0000FF000000FF00F2 +:107590000FFFFFFF0000FF000FFFFFFF000000FFD5 +:1075A0000000FF000000FF000FFFFFFF0000FF00D2 +:1075B0000FFFFFFF000000FF0000FF000000FF00C2 +:1075C0000FFFFFFF0000FF000FFFFFFF000000FFA5 +:1075D0000000FF000000FF000FFFFFFF0000FF00A2 +:1075E0000FFFFFFF000000FF0000FF000000FF0092 +:1075F0000FFFFFFF0000FF000FFFFFFF000000FF75 +:107600000000FF000000FF000FFFFFFF0000FF0071 +:107610000FFFFFFF000000FF0000FF000000FF0061 +:107620000FFFFFFF0000FF000FFFFFFF000000FF44 +:107630000000FF000000FF000FFFFFFF0000FF0041 +:107640000FFFFFFF000000FF0000FF000000FF0031 +:107650000FFFFFFF0000FF000FFFFFFF000000FF14 +:107660000000FF000000FF000FFFFFFF0000FF0011 +:107670000FFFFFFF000000FF0000FF000000FF0001 +:107680000FFFFFFF0000FF000FFFFFFF000000FFE4 +:107690000000FF000000FF000FFFFFFF0000FF00E1 +:1076A0000FFFFFFF000000FF0000FF000000FF00D1 +:1076B0000FFFFFFF0000FF000FFFFFFF000000FFB4 +:1076C0000000FF000000FF000FFFFFFF0000FF00B1 +:1076D0000FFFFFFF000000FF0000FF000000FF00A1 +:1076E0000FFFFFFF0000FF000FFFFFFF000000FF84 +:1076F0000000FF000000FF000FFFFFFF0000FF0081 +:107700000FFFFFFF000000FF0000FF000000FF0070 +:107710000FFFFFFF0000FF000FFFFFFF000000FF53 +:107720000000FF000000FF000FFFFFFF0000FF0050 +:107730000FFFFFFF000000FF0000FF000000FF0040 +:107740000FFFFFFF0000FF000FFFFFFF000000FF23 +:107750000000FF000000FF000FFFFFFF0000FF0020 +:107760000FFFFFFF000000FF0000FF000000FF0010 +:107770000FFFFFFF0000FF000FFFFFFF000000FFF3 +:107780000000FF000000FF000FFFFFFF0000FF00F0 +:107790000FFFFFFF000000FF0000FF000000FF00E0 +:1077A0000FFFFFFF0000FF000FFFFFFF000000FFC3 +:1077B0000000FF000000FF000FFFFFFF0000FF00C0 +:1077C0000FFFFFFF000000FF0000FF000000FF00B0 +:1077D0000FFFFFFF0000FF000FFFFFFF000000FF93 +:1077E0000000FF000000FF000FFFFFFF0000FF0090 +:1077F0000FFFFFFF000000FF0000FF000000FF0080 +:107800000FFFFFFF0000FF000FFFFFFF000000FF62 +:107810000000FF000000FF000FFFFFFF0000FF005F +:107820000FFFFFFF000000FF0000FF000000FF004F +:107830000FFFFFFF0000FF000FFFFFFF000000FF32 +:107840000000FF000000FF000FFFFFFF0000FF002F +:107850000FFFFFFF000000FF0000FF000000FF001F +:107860000FFFFFFF0000FF000FFFFFFF000000FF02 +:107870000000FF000000FF000FFFFFFF0000FF00FF +:107880000FFFFFFF000000FF0000FF000000FF00EF +:107890000FFFFFFF0000FF000FFFFFFF000000FFD2 +:1078A0000000FF000000FF000FFFFFFF0000FF00CF +:1078B0000FFFFFFF000000FF0000FF000000FF00BF +:1078C0000FFFFFFF0000FF000FFFFFFF000000FFA2 +:1078D0000000FF000000FF000FFFFFFF0000FF009F +:1078E0000FFFFFFF000000FF0000FF000000FF008F +:1078F0000FFFFFFF0000FF000FFFFFFF000000FF72 +:107900000000FF000000FF000FFFFFFF0000FF006E +:107910000FFFFFFF000000FF0000FF000000FF005E +:107920000FFFFFFF0000FF000FFFFFFF000000FF41 +:107930000000FF000000FF000FFFFFFF0000FF003E +:107940000FFFFFFF000000FF0000FF000000FF002E +:107950000FFFFFFF0000FF000FFFFFFF000000FF11 +:107960000000FF000000FF000FFFFFFF0000FF000E +:107970000FFFFFFF000000FF0000FF000000FF00FE +:107980000FFFFFFF0000FF000FFFFFFF000000FFE1 +:107990000000FF000000FF000FFFFFFF0000FF00DE +:1079A0000FFFFFFF000000FF0000FF000000FF00CE +:1079B0000FFFFFFF0000FF000FFFFFFF000000FFB1 +:1079C0000000FF000000FF000FFFFFFF0000FF00AE +:1079D0000FFFFFFF000000FF0000FF000000FF009E +:1079E0000FFFFFFF0000FF000FFFFFFF000000FF81 +:1079F0000000FF000000FF000FFFFFFF0000FF007E +:107A00000FFFFFFF000000FF0000FF000000FF006D +:107A10000FFFFFFF0000FF000FFFFFFF000000FF50 +:107A20000000FF000000FF000FFFFFFF0000FF004D +:107A30000FFFFFFF000000FF0000FF000000FF003D +:107A40000FFFFFFF0000FF000FFFFFFF000000FF20 +:107A50000000FF000000FF000FFFFFFF0000FF001D +:107A60000FFFFFFF000000FF0000FF000000FF000D +:107A70000FFFFFFF0000FF000FFFFFFF000000FFF0 +:107A80000000FF000000FF000FFFFFFF0000FF00ED +:107A90000FFFFFFF000000FF0000FF000000FF00DD +:107AA0000FFFFFFF0000FF000FFFFFFF000000FFC0 +:107AB0000000FF000000FF000FFFFFFF0000FF00BD +:107AC0000FFFFFFF000000FF0000FF000000FF00AD +:107AD0000FFFFFFF0000FF000FFFFFFF000000FF90 +:107AE0000000FF000000FF000FFFFFFF0000FF008D +:107AF0000FFFFFFF000000FF0000FF000000FF007D +:107B00000FFFFFFF0000FF000FFFFFFF000000FF5F +:107B10000000FF000000FF000FFFFFFF0000FF005C +:107B20000FFFFFFF000000FF0000FF000000FF004C +:107B30000FFFFFFF0000FF000FFFFFFF000000FF2F +:107B40000000FF000000FF000FFFFFFF0000FF002C +:107B50000FFFFFFF000000FF0000FF000000FF001C +:107B60000FFFFFFF0000FF000FFFFFFF000000FFFF +:107B70000000FF000000FF000FFFFFFF0000FF00FC +:107B80000FFFFFFF000000FF0000FF000000FF00EC +:107B90000FFFFFFF0000FF000FFFFFFF000000FFCF +:107BA0000000FF000000FF000FFFFFFF0000FF00CC +:107BB0000FFFFFFF000000FF0000FF000000FF00BC +:107BC0000FFFFFFF0000FF000FFFFFFF000000FF9F +:107BD0000000FF000000FF000FFFFFFF0000FF009C +:107BE0000FFFFFFF000000FF0000FF000000FF008C +:107BF0000FFFFFFF0000FF000FFFFFFF000000FF6F +:107C00000000FF000000FF000FFFFFFF0000FF006B +:107C10000FFFFFFF000000FF0000FF000000FF005B +:107C20000FFFFFFF0000FF000FFFFFFF000000FF3E +:107C30000000FF000000FF000FFFFFFF0000FF003B +:107C40000FFFFFFF000000FF0000FF000000FF002B +:107C50000FFFFFFF0000FF000FFFFFFF000000FF0E +:107C60000000FF000000FF000FFFFFFF0000FF000B +:107C70000FFFFFFF000000FF0000FF000000FF00FB +:107C80000FFFFFFF0000FF000FFFFFFF000000FFDE +:107C90000000FF000000FF000FFFFFFF0000FF00DB +:107CA0000FFFFFFF000000FF0000FF000000FF00CB +:107CB0000FFFFFFF0000FF000FFFFFFF000000FFAE +:107CC0000000FF000000FF000FFFFFFF0000FF00AB +:107CD0000FFFFFFF000000FF0000FF000000FF009B +:107CE0000FFFFFFF0000FF000FFFFFFF000000FF7E +:107CF0000000FF000000FF000FFFFFFF0000FF007B +:107D00000FFFFFFF000000FF0000FF000000FF006A +:107D10000FFFFFFF0000FF000FFFFFFF000000FF4D +:107D20000000FF000000FF000FFFFFFF0000FF004A +:107D30000FFFFFFF000000FF0000FF000000FF003A +:107D40000FFFFFFF0000FF000FFFFFFF000000FF1D +:107D50000000FF0000001000000020800000310043 +:107D600000004180000052000000628000007300AB +:107D700000008380000094000000A4800000B50093 +:107D80000000C5800000D6000000E6800000F7007B +:107D9000000107800001180000012880000139005F +:107DA0000001498000015A0000016A8000017B0047 +:107DB00000018B8000019C000001AC800001BD002F +:107DC0000001CD800001DE000001EE800001FF0017 +:107DD00000000F8000007FF800007FF8000005F928 +:107DE0000000350010000000000028AD0000291838 +:107DF0000000291900000005000000060001000134 +:107E000000220006CCCCCCC97058103C0000FF000A +:107E1000000000000000FF00000000000000FF0064 +:107E2000000000000000FF00000000000000FF0054 +:107E3000000000000000FF00000000000000FF0044 +:107E4000000000000000FF00000000000000FF0034 +:107E5000000000000000FF00000000000000FF0024 +:107E6000000000000000FF00000000000000FF0014 +:107E7000000000000000FF00000000000000FF0004 +:107E8000000000000000FF00000000000000FF00F4 +:107E9000000000000000FF00000000000000FF00E4 +:107EA000000000000000FF00000000000000FF00D4 +:107EB000000000000000FF00000000000000FF00C4 +:107EC000000000000000FF00000000000000FF00B4 +:107ED000000000000000FF00000000000000FF00A4 +:107EE000000000000000FF00000000000000FF0094 +:107EF000000000000000FF00000000000000FF0084 +:107F0000000000000000FF00000000000000FF0073 +:107F1000000000000000FF00000000000000FF0063 +:107F2000000000000000FF00000000000000FF0053 +:107F3000000000000000FF00000000000000FF0043 +:107F4000000000000000FF00000000000000FF0033 +:107F5000000000000000FF00000000000000FF0023 +:107F6000000000000000FF00000000000000FF0013 +:107F7000000000000000FF00000000000000FF0003 +:107F8000000000000000FF00000000000000FF00F3 +:107F9000000000000000FF00000000000000FF00E3 +:107FA000000000000000FF00000000000000FF00D3 +:107FB000000000000000FF00000000000000FF00C3 +:107FC000000000000000FF00000000000000FF00B3 +:107FD000000000000000FF00000000000000FF00A3 +:107FE000000000000000FF00000000000000FF0093 +:107FF000000000000000FF00000000000000FF0083 +:10800000000000000000FF00000000000000FF0072 +:10801000000000000000FF00000000000000FF0062 +:10802000000000000000FF00000000000000FF0052 +:10803000000000000000FF00000000000000FF0042 +:10804000000000000000FF00000000000000000130 +:10805000CCCC0201CCCCCCCCCCCC0201CCCCCCCC8A +:10806000CCCC0201CCCCCCCCCCCC0201CCCCCCCC7A +:10807000CCCC0201CCCCCCCCCCCC0201CCCCCCCC6A +:10808000CCCC0201CCCCCCCCCCCC0201CCCCCCCC5A +:1080900000000000FFFFFFFF03030303134202027F +:1080A0005050502070608050020002000604060408 +:1080B000000E0000011600D6002625A0002625A0EF +:1080C000002625A0002625A000720000012300F351 +:1080D000002625A0002625A0002625A0002625A0F4 +:1080E0000000FFFF000000000000FFFF0000000094 +:1080F0000000FFFF000000000000FFFF0000000084 +:108100000000FFFF000000000000FFFF0000000073 +:108110000000FFFF000000000000FFFF0000000063 +:108120000000FFFF000000000000FFFF0000000053 +:108130000000FFFF000000000000FFFF0000000043 +:108140000000FFFF000000000000FFFF0000000033 +:108150000000FFFF000000000000FFFF0000000023 +:108160000000FFFF000000000000FFFF0000000013 +:108170000000FFFF000000000000FFFF0000000003 +:108180000000FFFF000000000000FFFF00000000F3 +:108190000000FFFF000000000000FFFF00000000E3 +:1081A0000000FFFF000000000000FFFF00000000D3 +:1081B0000000FFFF000000000000FFFF00000000C3 +:1081C0000000FFFF000000000000FFFF00000000B3 +:1081D0000000FFFF000000000000FFFF00000000A3 +:1081E0000000FFFF000000000000FFFF0000000093 +:1081F0000000FFFF000000000000FFFF0000000083 +:108200000000FFFF000000000000FFFF0000000072 +:108210000000FFFF000000000000FFFF0000000062 +:108220000000FFFF000000000000FFFF0000000052 +:108230000000FFFF000000000000FFFF0000000042 +:108240000000FFFF000000000000FFFF0000000032 +:108250000000FFFF000000000000FFFF0000000022 +:108260000000FFFF000000000000FFFF0000000012 +:108270000000FFFF000000000000FFFF0000000002 +:108280000000FFFF000000000000FFFF00000000F2 +:108290000000FFFF000000000000FFFF00000000E2 +:1082A0000000FFFF000000000000FFFF00000000D2 +:1082B0000000FFFF000000000000FFFF00000000C2 +:1082C0000000FFFF000000000000FFFF00000000B2 +:1082D0000000FFFF000000000000FFFF00000000A2 +:1082E000FFFFFFF3318FFFFF0C30C30CC30C30C313 +:1082F000CF3CF300F3CF3CF30000CF3CCDCDCDCD50 +:10830000FFFFFFF130EFFFFF0C30C30CC30C30C395 +:10831000CF3CF300F3CF3CF30001CF3CCDCDCDCD2E +:10832000FFFFFFF6305FFFFF0C30C30CC30C30C300 +:10833000CF3CF300F3CF3CF30002CF3CCDCDCDCD0D +:10834000FFFFF4061CBFFFFF0C30C305C30C30C396 +:10835000CF300014F3CF3CF30004CF3CCDCDCDCDD6 +:10836000FFFFFFF2304FFFFF0C30C30CC30C30C3D4 +:10837000CF3CF300F3CF3CF30008CF3CCDCDCDCDC7 +:10838000FFFFFFFA302FFFFF0C30C30CC30C30C3CC +:10839000CF3CF300F3CF3CF30010CF3CCDCDCDCD9F +:1083A000FFFFFFF731EFFFFF0C30C30CC30C30C3EE +:1083B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6F +:1083C000FFFFFFF5302FFFFF0C30C30CC30C30C391 +:1083D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2F +:1083E000FFFFFFF3318FFFFF0C30C30CC30C30C312 +:1083F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4F +:10840000FFFFFFF1310FFFFF0C30C30CC30C30C373 +:10841000CF3CF300F3CF3CF30001CF3CCDCDCDCD2D +:10842000FFFFFFF6305FFFFF0C30C30CC30C30C3FF +:10843000CF3CF300F3CF3CF30002CF3CCDCDCDCD0C +:10844000FFFFF4061CBFFFFF0C30C305C30C30C395 +:10845000CF300014F3CF3CF30004CF3CCDCDCDCDD5 +:10846000FFFFFFF2304FFFFF0C30C30CC30C30C3D3 +:10847000CF3CF300F3CF3CF30008CF3CCDCDCDCDC6 +:10848000FFFFFFFA302FFFFF0C30C30CC30C30C3CB +:10849000CF3CF300F3CF3CF30010CF3CCDCDCDCD9E +:1084A000FFFFFFF730EFFFFF0C30C30CC30C30C3EE +:1084B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6E +:1084C000FFFFFFF5304FFFFF0C30C30CC30C30C370 +:1084D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2E +:1084E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C6 +:1084F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD82 +:10850000FFFFFFFF30CFFFFF0C30C30CC30C30C3A5 +:10851000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD60 +:10852000FFFFFFFF30CFFFFF0C30C30CC30C30C385 +:10853000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3F +:10854000FFFFFFFF30CFFFFF0C30C30CC30C30C365 +:10855000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1D +:10856000FFFFFFFF30CFFFFF0C30C30CC30C30C345 +:10857000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF9 +:10858000FFFFFFFF30CFFFFF0C30C30CC30C30C325 +:10859000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDD1 +:1085A000FFFFFFFF30CFFFFF0C30C30CC30C30C305 +:1085B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCDA1 +:1085C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E5 +:1085D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD61 +:1085E000FFFFFFF3320FFFFF0C30C30CC30C30C38F +:1085F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4D +:10860000FFFFFFF1310FFFFF0C30C30CC30C30C371 +:10861000CF3CF300F3CF3CF30001CF3CCDCDCDCD2B +:10862000FFFFFFF6305FFFFF0C30C30CC30C30C3FD +:10863000CF3CF300F3CF3CF30002CF3CCDCDCDCD0A +:10864000FFFFF4061CBFFFFF0C30C305C30C30C393 +:10865000CF300014F3CF3CF30004CF3CCDCDCDCDD3 +:10866000FFFFFFF2304FFFFF0C30C30CC30C30C3D1 +:10867000CF3CF300F3CF3CF30008CF3CCDCDCDCDC4 +:10868000FFFFFF8A042FFFFF0C30C30CC30C30C365 +:10869000CF3CC000F3CF3CF30010CF3CCDCDCDCDCF +:1086A000FFFFFF9705CFFFFF0C30C30CC30C30C397 +:1086B000CF3CC000F3CF3CF30020CF3CCDCDCDCD9F +:1086C000FFFFFFF5310FFFFF0C30C30CC30C30C3AD +:1086D000CF3CF300F3CF3CF30040CF3CCDCDCDCD2C +:1086E000FFFFFFF3320FFFFF0C30C30CC30C30C38E +:1086F000CF3CF300F3CF3CF30000CF3CCDCDCDCD4C +:10870000FFFFFFF1302FFFFF0C30C30CC30C30C351 +:10871000CF3CF300F3CF3CF30001CF3CCDCDCDCD2A +:10872000FFFFFFF6305FFFFF0C30C30CC30C30C3FC +:10873000CF3CF300F3CF3CF30002CF3CCDCDCDCD09 +:10874000FFFFFF061CBFFFFF0C30C30CC30C30C380 +:10875000CF3CC014F3CF3CF30004CF3CCDCDCDCD06 +:10876000FFFFFFF2304FFFFF0C30C30CC30C30C3D0 +:10877000CF3CF300F3CF3CF30008CF3CCDCDCDCDC3 +:10878000FFFFFFFA302FFFFF0C30C30CC30C30C3C8 +:10879000CF3CF300F3CF3CF30010CF3CCDCDCDCD9B +:1087A000FFFFFFF731CFFFFF0C30C30CC30C30C30A +:1087B000CF3CF300F3CF3CF30020CF3CCDCDCDCD6B +:1087C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E3 +:1087D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5F +:1087E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C3 +:1087F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7F +:10880000FFFFFFFF30CFFFFF0C30C30CC30C30C3A2 +:10881000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5D +:10882000FFFFFFFF30CFFFFF0C30C30CC30C30C382 +:10883000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3C +:10884000FFFFFFFF30CFFFFF0C30C30CC30C30C362 +:10885000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD1A +:10886000FFFFFFFF30CFFFFF0C30C30CC30C30C342 +:10887000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF6 +:10888000FFFFFFFF30CFFFFF0C30C30CC30C30C322 +:10889000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCE +:1088A000FFFFFFFF30CFFFFF0C30C30CC30C30C302 +:1088B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9E +:1088C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E2 +:1088D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5E +:1088E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C2 +:1088F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7E +:10890000FFFFFFFF30CFFFFF0C30C30CC30C30C3A1 +:10891000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5C +:10892000FFFFFFFF30CFFFFF0C30C30CC30C30C381 +:10893000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3B +:10894000FFFFFFFF30CFFFFF0C30C30CC30C30C361 +:10895000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD19 +:10896000FFFFFFFF30CFFFFF0C30C30CC30C30C341 +:10897000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF5 +:10898000FFFFFFFF30CFFFFF0C30C30CC30C30C321 +:10899000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCD +:1089A000FFFFFFFF30CFFFFF0C30C30CC30C30C301 +:1089B000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9D +:1089C000FFFFFFFF30CFFFFF0C30C30CC30C30C3E1 +:1089D000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5D +:1089E000FFFFFFFF30CFFFFF0C30C30CC30C30C3C1 +:1089F000CF3CF3CCF3CF3CF30000CF3CCDCDCDCD7D +:108A0000FFFFFFFF30CFFFFF0C30C30CC30C30C3A0 +:108A1000CF3CF3CCF3CF3CF30001CF3CCDCDCDCD5B +:108A2000FFFFFFFF30CFFFFF0C30C30CC30C30C380 +:108A3000CF3CF3CCF3CF3CF30002CF3CCDCDCDCD3A +:108A4000FFFFFFFF30CFFFFF0C30C30CC30C30C360 +:108A5000CF3CF3CCF3CF3CF30004CF3CCDCDCDCD18 +:108A6000FFFFFFFF30CFFFFF0C30C30CC30C30C340 +:108A7000CF3CF3CCF3CF3CF30008CF3CCDCDCDCDF4 +:108A8000FFFFFFFF30CFFFFF0C30C30CC30C30C320 +:108A9000CF3CF3CCF3CF3CF30010CF3CCDCDCDCDCC +:108AA000FFFFFFFF30CFFFFF0C30C30CC30C30C300 +:108AB000CF3CF3CCF3CF3CF30020CF3CCDCDCDCD9C +:108AC000FFFFFFFF30CFFFFF0C30C30CC30C30C3E0 +:108AD000CF3CF3CCF3CF3CF30040CF3CCDCDCDCD5C +:108AE000000C0000000700C000028130000B81581C +:108AF0000002021000010230000F024000010330AA +:108B0000000C0000000800C000028140000B8168DA +:108B1000000202200001024000070250000202C0D1 +:108B2000001000000008010000028180000B81A8F5 +:108B30000002026000018280000E8298000803801B +:108B4000001000000001010000028110000901383E +:108B5000000201C8000101E8000E01F8000002D87F +:108B6000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC45 +:108B700000002000CCCCCCCCCCCCCCCCCCCCCCCC45 +:108B8000CCCCCCCC00002000CCCCCCCCCCCCCCCC35 +:108B9000CCCCCCCCCCCCCCCC04002000CCCCCCCC21 +:108BA000CCCCCCCCCCCCCCCCCCCCCCCC41002000D4 +:108BB00003030303034202025050502070608050B0 +:108BC0001313131313421212505050207060805030 +:108BD000030102000000000000000000000000008F +:108BE0001F8B080000000000000BFB51CFC0F003FA +:108BF0008AF7093230288920F8C4E0427606864D8B +:108C00001C0C0C5BB849D307C32C0C0C0CDA4CE4DD +:108C1000E905E1DBBC0C0CCF8098810F555C80131B +:108C200042FF075A20C80AB4830DBBFEE56A08B6A6 +:108C3000A70A0343011033283130E8AB22C445D4DE +:108C400019182602F99150B1AB403A4C8D7C378F00 +:108C5000E2C1834F1AA3F2971A426807A8F8293491 +:108C6000F96550F9621D087DDA18BBB9253AC4D9F7 +:108C7000BFCB1A953FCD1ABFFA93F6A8FC7568EAE8 +:108C80001741F900B9FAD21DD80300000000000016 +:108C900000000000000000001F8B08000000000022 +:108CA000000BED7D7F7C14D5B5F8999DD9D9D9CD30 +:108CB000EE6608096C20E024861AFAA25D20609016 +:108CC000A843401ABF8FDA15A9A62DED77B5D4E2D7 +:108CD0000F60EBF3097DCF36931092101017B1D5CA +:108CE00056AB2B0F2DF56B25B5D4D2FAA38B581E9E +:108CF000B6EFF3BE4869EBD7621B7FE18F228D5A36 +:108D000084B658BFF79C7B273B33D94D36407FFC58 +:108D1000F1C207863B73EEBDE79E73EEB9E79C7B1D +:108D2000EE8D0A35F0A133003EC09F0B016E0F019E +:108D30004045EE695C7F7E4F7F03C05188A47BCBAA +:108D400001D62860022B5B072399FB25C09F3A853B +:108D50009557C91F8EF75603DC51F2957B117EB5EE +:108D6000A540803D7BDB00B267B1EFA1E816280586 +:108D70002881D476FCCE7E12F7B3F68E05276720C5 +:108D80009AEBBF027C0033F173957EA884E0E00388 +:108D900099FD73303917C601C860FFAC863ED68E88 +:108DA0007240CE60BFB2BC50FF554DAE1DEF53D6E2 +:108DB00055C86AA23DFC475E529A0C17865F7DB08B +:108DC0007AFBD37539F8B320527EE89FD87F1450D0 +:108DD000081F7903201D8E86212357176EE7589BA5 +:108DE000B1FD693FD2F133A589B30BC3D974EA69E8 +:108DF000D3E8D9D5A6433600C05036FBEAD9330CA8 +:108E0000E696FAA1F5E68144F4D20C8BF0E90CFB6E +:108E10003225D588751280D1D78FF491F0FD22CDFF +:108E2000CC53DF7E4239A38F3D5E46C720F0F680EB +:108E30008DEF7ED65E10FBCF43AFCBB07F2627C130 +:108E4000DAA1FD5B0D27DF7F682AC0BE30D2DB448C +:108E50001CC0A7A7202EF8FD51699876049F1583A2 +:108E6000B73312DD4BEA7CB97ED9DFA01172C94954 +:108E70002056E6961BAF5C229D2A905F86F4F29402 +:108E80005CBB2AF22D0FBDAE11F41A989B684D30D1 +:108E90007AAC6D03EB25473D390666260F9D568952 +:108EA0007A767F4A3983CBD33E40BB983F960BBE40 +:108EB00058FCBE7C92F8ADFF1BE1B749C83B409A15 +:108EC0009E03739384A7B7BD7CF38B4DE2C17248B8 +:108ED000C9583E94EF7288DFCF1E7E8DCF33FBFBE7 +:108EE000C3E0A77676A2C661FDAC11F80DCCE5FA19 +:108EF0006FED3435B345227DE4C2F321D45FAC9EDF +:108F000024097A687D80F257725C01188BF8999079 +:108F10008800ACAB6DD686D33FA02B7FEAB7E5AE19 +:108F200066A8DC7D9875837885C2F9E9F4F0A01E07 +:108F30005D62BDC4DAD182ECFD99D86E79AC6A1657 +:108F4000E0E8E8C72FBE83E4933FC0797B82C1CDC0 +:108F5000127A56A6F6498F401590BE97053CF5C388 +:108F6000E0036C58E674F6C4F775A21F6968BBDEAF +:108F70007AC7A08CD347E063EB75191EA77606F17C +:108F80005112442FEF7B3F7BAF874FFDFDA996FD2C +:108F90004681FED212C9D348F57F23E465887C164A +:108FA000E0EB7E31CF14E833E1CC9C1CD9F275B2F2 +:108FB0007274CA72C2BAA7F5A2809C5890A279C3F3 +:108FC000C0ACDE69A397973C729275C22F94C6F02D +:108FD0007128719217868F4272AB737C2AA69753C1 +:108FE0007B12CEF1B3B00551463AB0F15E65D7873A +:108FF00038CDD710DA398EFA6C7084AF244B42EF3B +:1090000073B89BC43C3FBFB98AE30FA27D0FBEACCF +:109010003DCDD99E0C551E39E7786F94B87E63F02C +:1090200059A2A7B77F45227C6548583E566F8BE80A +:10903000DFABBFECE70ED1DE06095AFBC27C3E2D4A +:1090400072AC87CD92D0131A9F675EFDE447B99A40 +:1090500071F27255AC5E5F28E55F77985514BB34AA +:109060005278DD29F5D9EB413626F8362ABE9F29FC +:1090700095B9F85E2CBE579D24BE1387E25B949C85 +:109080004D957CA35A276F3A49FC821EFC4E975C93 +:10909000CF1072562CFEF63C182DFEF250FA163503 +:1090A0008F668F12BF2D2749DF0A9F6D2709FC0AA3 +:1090B000CCDBF305BF2DE0F2A1303B1CFD9C62F13F +:1090C0007B7464FC00CE637FAD172D53217B0D6054 +:1090D00002C0D3ED2F5A9692C3CF04AED747DBFF21 +:1090E0009E91F927FA7FC3326B73FD1F687FC3D54A +:1090F000BFC2E40785ADD87E7F51ECB8E16DD7B82B +:109100005F96DE76F57BB2747FB5E8FEFFE81AF76E +:10911000BBD21FDDE30EB3719F597CBF7F38497905 +:10912000AC16F3A559D25DEB4021FB7D86E0EBDD6B +:1091300036BC8D6F01F8A902AFCE22E1278AF63F37 +:1091400055247C9F68BF0FE12B46863F53C0A78AFA +:1091500084977C7C1E165A3FE74A36FDC0E57FACFB +:10916000D1781CC45CA340F082A17113AB39F5AD7A +:109170007EC67BAB23A0AF29A7B809C545560324FB +:10918000306E7217241B7D187FD9F9E57B11EE1D17 +:1091900045D37B75E013927D0F1E8C6CE9ADCEF547 +:1091A000B74A4EB64A284B6BA2FAFD145F49B54A3E +:1091B000EC596185758CDB1CAB49B45F598EE3308B +:1091C000748BB5F3FCB2CB7661F9364DD265266A65 +:1091D0005FBD60EAA6CB0D06F7FEAEE7CE40B869EC +:1091E000E36A3A485FC6259487B171D594CF61CFC1 +:1091F000C58BB97E07E10FB738CACC0EF864EB27F0 +:109200005CDF3F9D74973FD1F289DC7AC2FE5E91AC +:10921000707FCF8D07B8DF3187EBED6335A9DF7243 +:10922000BC3E546DF1F8028DB7D48AD2F836BCFF3B +:10923000452A6F68AFD73BD8B83F75CD510BC717DC +:109240009680C6178DBF97C532B0F1AA8D00B75E64 +:10925000F04CCF2C28EC7F459B16BBF084B87B9C50 +:10926000ADD7E7C75BD5DF9DF00AB3978EED0A9ABD +:10927000884F74AF9C0956235F07B293B07FAB341D +:10928000C9F93300B5C8575307E463B399CCC8ECA8 +:109290007D3AA6C5032866D0AF21DD372168257B3E +:1092A000DFF88E96ACC7F6DFA3F675F1FDD6C69A49 +:1092B000F1181F79BC6DF54485CDF71FB55913150D +:1092C00066B4EF6CEBA1E7A36D697ABFA3ED4E7AAC +:1092D000DAE3434D62D8E393B11FB303E5ED989F02 +:1092E00099460CAF8DE7FBC8BFDD20F44897782A7C +:1092F0004A562EC5EF7198D60B88D7FE79584E374F +:10930000C0346459BAE929B9948DE3864A988E6DC0 +:10931000EF7AE157FC7B154C0F30F97ACA6CA679CD +:10932000706BA32F13A8A6E7C5D8DFADA60F98C909 +:10933000039138C3CB41D740CC5DD621B926D2406A +:10934000FDC77B0DAC7FC36E2CDF3093194A40ED17 +:10935000CB11A223C4B1BF99074CD2E381261FC50C +:10936000E9D24DBE20D271A47ED248D761E25573B6 +:109370005E77C3CFEE779799C6FBCDA07C70FA3E9F +:10938000EC637A62F70BE37D5639E141E3674F1EE8 +:10939000478CF9326894DE26E86CD3FD5884EB9D47 +:1093A0008DCC3FC47860217C369E776D6CB8788216 +:1093B000DAD8958073F0994E60BC556DCC88671FE4 +:1093C000BDF7C23F8F46D1CC5CB92B367DCC95F52D +:1093D000397CBCF0136495E4FF5805FFDE157B4A29 +:1093E000BF32EC6C4FF27ED73E5FEFFCEEA7FE8EF5 +:1093F00055DADFF76B57D6E7A93F897DCFC397A52D +:1094000032D7C34FBF1068FE1ACAA7A0EFEE175E8F +:10941000DB7B26D2FB800C280FE97DCD240F287F33 +:10942000A8479E62F2D0CFDA1BDBB2E137CEF91C3F +:1094300089BBCBE946864003E71B76F55F821F3F79 +:1094400015F1DABD225EBBA72D46CFA7DB0C7A3E15 +:10945000D55647DFB36D712A3FD9D648E5C7DB4CF7 +:109460002AFFA8AD85CA3BDB12547EB4AD959E3B66 +:10947000DA92F4BCAD6D193DD34D7C9E6F684B51B3 +:10948000B9AB6D35D5B3C7FF31A6359CF2F7CF75B3 +:10949000EEF2C5C659B9F9CEFE7E34E62E5FA47F42 +:1094A000D4559EA7B9CB73E10BAEF62E3C7EB5AB7F +:1094B0007CFE40970B7ECEEBEEF2ECFE075CF0E715 +:1094C0003EE72ECFDCB7C7551EDBE22E47E2875CB6 +:1094D000ED0562EEF256543E5C7F917C74C56AC61F +:1094E000E495BFC1EFD3839F737D978B949FAB7A35 +:1094F000AA517E5A7C71CB40F9E1F294467D260D4B +:1095000095139B6F23C9978DC7DF5AAEFE479E8682 +:1095100097A7A2E5A141895B30541EBC7CF7CAC75E +:10952000103D23E4E57FE4E01F430E607E19EBA4C9 +:10953000F0BA9AC7EE23BB35B015C8EEF3A30D5DA4 +:10954000E95887276793F9F6C1AEF5CD7D4466EDFE +:1095500004CAA10BF749034A01FF56AC73018D7F82 +:109560000FD6A67D284F1130A6CBD30096FFE096EC +:109570000957B1F6F709B8AEFBC1923E02306E82D0 +:109580009A44FF2652EBF673F6CA3CEE613FB77D74 +:109590003FD29AA1987F830BEFA1E3E6FB38F2C498 +:1095A00059ADBF66F340DE326BDB5AF60CD5264D63 +:1095B000D9C0FAE544B7A52183E0CCC68CE563AFFA +:1095C0008255CC6E639FE5B0096887CDF699CFCA06 +:1095D00033C93EDA8F4FDBEED9269E8F8B7978998F +:1095E000CFFC25D287C1FD6A3838BBDF11F90549A8 +:1095F0004BE271ABF8FD0C457F79DC653FD9E35355 +:10960000948499C8C3AF23B2D8E7D1E3AD3C3EA25E +:1096100002EA8742F0AFCBEEFD31FB59CAFC0219DA +:10962000F188F17D2838719971E9D943F150954459 +:1096300012FBC17DEC2DAC9FCE31971B49473F9269 +:1096400022F08999848FAA737C54256E26F2C8D1A2 +:109650009F043E763BF67E9A141B80FE700EBFB5CB +:10966000C144EB95E8B78E51894E9D11B7FD354B3E +:10967000E17276967876FAF3DB87001DDC4F1ED711 +:10968000A861FB6B1A9B35B4AF0D886BE87F7786BA +:1096900017950E676F6F68E3FBE3BDA80F03B84F24 +:1096A000AE8B7DF2183D3BC38FB4E0BC3B5ACFE894 +:1096B000505DB89D48DCBDDF5B5217F2ECEF6608E9 +:1096C000CFA051E6D9079EE0AAE71FA7F8ECFD6EF0 +:1096D0009046C6BF4BE06FC3752B294DCF4BA78C6F +:1096E000CBEE0EC4DCF8FEF5E8C7EB97F8FBF47C94 +:1096F000789D2EBA15DA9FB59FEA583595E1719697 +:1097000098731E2C11F2A58ED55218C702ADD0F752 +:1097100010AF1F4E50DC4B0B270CA8C9EDD36A3895 +:109720001F1C74BA51D47B41B1F74B5331F4AB25B4 +:1097300023D58AF2A455B179240DAD673F3F27EABE +:1097400077BFFF2FCFD13CA9D0689E48069B4779B1 +:10975000FA511473A5827151D94C29B86FF3173996 +:10976000996FBEAC10F3595B9830B41ADADAE3792A +:10977000201E3C36287C1EBF21E0C14A513CAB581C +:10978000FCFFBD48FCED7E18FEDD02FF1E7C16C20C +:10979000BF4BE05306463BC5380DAE67012E359CE6 +:1097A000F918AF89FECB849E02F822F1CDFEFE921D +:1097B000E04BB1E3F96A91E3792DC78FFB900F6C11 +:1097C0003C5B86E34746E0F19AC2D7192D9130629F +:1097D00035B4D4E795AB1F0B7ABD6BCB95F5C5516E +:1097E000C9D5C3A2FE48E3F8718E2F3F12E3786C0F +:1097F00038BEFC50F0252DC3EC5730FE78A65877C4 +:1098000060918B2FC745BBE980CD971B5C7C3932BB +:109810004ABEEC2D723CC773E33920E4EC17C3F168 +:10982000C501FFBC18FFAFC5F829AE7EBCF39A0E88 +:109830002B4CEBF26F9599B9FE185CBF6897E06E00 +:1098400054CEEDB0EA09EE157C2FB5F07590C1BD90 +:10985000EA84034874A0FDB616F74ACF03F896725F +:1098600073B368FF77546FE160FB879DF53628F38B +:109870006C3C06F07DFBBCBFD8706F3BE18E775E21 +:109880006FC31DA5F6128378BCE71CD78F3B9710DA +:10989000DC907CA45871F6AABF3C49797D651049DB +:1098A00063DCB14B49519C193721303EB92A10A7CE +:1098B000149691E2D4158B793D5DD128CE1A80148F +:1098C000DC89F1B97285F64D3EAE24753FDA11524E +:1098D000D2A24D57D097B463FB630DCA0BB3F1D935 +:1098E00054F2D91E6A87E183EDDE5112DD8572756F +:1098F000DB24D540B9DA35E9268AA76F6AE779858E +:109900009B2E56298EB8F98508ADBF6B95F82711A7 +:10991000DE325503E3C5AB427F796E292BF7B7974B +:10992000EAD205340EC2DBF241624D83234F91E14E +:109930001D88539E1DC5E136B5F0FD1EF65389F511 +:1099400057CD3328CE68A01E63DFBB1B55B25F37EF +:1099500055D5CCC5FE36376A646F6C5E58D34E71F0 +:10996000BCC610C531CBC28684F1F7E8B92A33C032 +:1099700059B9DC68477B33322B0418772AABE2FDF8 +:1099800045CE028A43F9219DA865CF688F0AD9B1D7 +:10999000D8DEA2ECE7D09E690CE832C6FD2D737FBD +:1099A000FD384A85E33FF27F01E2E39F2803D2DDE1 +:1099B000E66F343D587FD8FCC668A648B86C717015 +:1099C000911E05B2338A804B17099729122ECBE1DD +:1099D0000270E9B0797E10E7F9851AFBC3F31B1D0D +:1099E000F986D5DC7E77DA2D7ECFF7D1E68B2EF7A0 +:1099F00047CA695E9E0BE7F27CD1E1EBDB79A223DB +:109A00008D17C097C3531E197EADB0FB0A7DF78F2B +:109A1000BB2986FAACBBE2DFC4F366FEAC14EF2BC5 +:109A200057C7CC303EC5F7CA9B5BCD3CFD7DC3CF4D +:109A3000F5701D2486E54399C0FF10C31DF37EEA2F +:109A400014061F290CAF96FB86CDBFD414AB99E644 +:109A5000ED421FCDDB002A039C37557C1EFB219570 +:109A6000A8253D63462B1DF3C7DFB487E6CF7F579C +:109A7000CA2035127FE24847AF9C78E522008E72FB +:109A8000F5A9CBC9237E91577C9AE5C4DF2317350E +:109A90007FFCE922E13245C2658B83537BA4A2F4AB +:109AA0008A9A2E122E53245C96C3AD9DADF2F5DC3E +:109AB0003AD6817900FEF3345779ED7921F7F739F9 +:109AC0006157B96BA6BBBE3ACB5DBF6B96BBBE7A86 +:109AD0002EAF1F567DF3709FBFD879F2EA49CE931F +:109AE0003A6D78F848E308F34AD38358BF4C3120E5 +:109AF0005B4EEB5546AC5B79F7C96B543EFFA7F85C +:109B0000F9BEFD26450FA21FF98F3E4E45E5F8DA56 +:109B1000E31D095F5BFFBE260B7BAB403E38C4F8FC +:109B2000B9083F84E268E718F3B5E6DF303AFA9FF8 +:109B3000E1F9F0DE765F54930DAAC32F66F619247F +:109B40001D71988B2B149E87C3F880F6900A891696 +:109B50008C3BAFA9F2913DA284475837AA1C7A2BBF +:109B60004FBE5E2E2E05269EB3A04F06C0DCD779D1 +:109B7000BFA13810DE11E82767BA1453E8CE0418E5 +:109B80000386C493C1789E0040938EFAAC3C78BAA9 +:109B9000DB5D42ED4AE626F8A06414ED2AFD944709 +:109BA00073DADB1D01DF20DC4DED322FA9FC83B120 +:109BB000B976FDB114BDC4FC59D9914787E7252872 +:109BC0000FC517CF52DEC38428F9656BCB6F70E5E4 +:109BD000897F45AD71C58754BDEB8B12EEE3565DB1 +:109BE0006FF60F23E71D4C5D517CA46AA9D95F571E +:109BF000186E307F1FF340F3CC832E359941FBDD87 +:109C00009A1CE6FEBC92A27863B75436BDB7210712 +:109C1000A754314DCBF00AC74D0BFDBDEEB1BE3898 +:109C2000DAA90A6CD8279DC3EAC90BE3CEF8A5F7D9 +:109C3000A954296F3AC77387EAB6A7D68C20EF23B9 +:109C4000DA3D6A3C992F2EFAA0CAFD637F28FFF700 +:109C50005742CDDF522B86D2ED47485FF46FC740A5 +:109C60000FC6DBED3C5AA56ACF734887B5150B626A +:109C7000C38D9739508707F9C258BC2F64EE5067DF +:109C80000E8BC74E75661EFE858B8B7F03F3D374D8 +:109C9000062A8BF339681F494CDE4383F218874E3E +:109CA000D457CCFFE8657C0BD5C7612B2BC7E66981 +:109CB0000985D94BB7346C018C5BFB99FD44FE8957 +:109CC000DCC4EDA73A6E0F99EC0F8E23DA34BC5D3D +:109CD0002D7BCA0754B73DB4A66D2738F3DFBCE728 +:109CE0002DECE7D650F3F3F9E9519C3FBC99C90B31 +:109CF00033EE60539B46CF5BDB747ADED216A3E76C +:109D0000FA3683F2F33BDBEAA8FC55AC3A1BCF45AD +:109D1000A57AAA19FD7A625B9F5BCA5E6D46DA522C +:109D20009C20330FEDE45E2C53BE1F7303B13C89BE +:109D30007F7FAF2B3D0FE30DBD411B7EED3CD35527 +:109D4000BE73CD5C8417718648F77DF3D0DFDF3CAE +:109D5000C9CE4333B54F38D6BD9A003FAF42BE2B74 +:109D6000D5EF5883FD0715BBFC3D6A3F570613F13D +:109D7000096ABCFCD1C00EC2875400EBEFE381EF4F +:109D80005379F3141EEF87C58B46A0238FEFAF5195 +:109D90000D1EEF5A5C46FB472A939B1AF66AF3188E +:109DA000817791ED8092E4EB9D38DF5778DE8CB0BF +:109DB000AE093C469E0F26C5D1ED736BCA2FF2AF9C +:109DC000D3A7BBDFCDFED1D1456B4A9AD87CB4A5D1 +:109DD0002F8BACFEB19A9C13C07DA4F9FB6859513E +:109DE00063596E3714D9FFB8809D079924BFC9A65F +:109DF000B7A273FB6385879FFE72BE6F1714E7538C +:109E00008AC5FB73AAE847B4030F4DAF1CCECE2A18 +:109E10005FE843636C506F94CD0FB9CA7A539908C9 +:109E2000DAF072B46182AB1CAEAF7195FDFA875D5A +:109E3000F54F965FADC25EB4E13FE61957B3779C2C +:109E400045B6FB6269E25F0233314E05752946D79C +:109E50003B3EF300D13F34385F17749A4D942F2E58 +:109E6000FC8A0B7959B7BF9FD76956B1B2617F9F02 +:109E7000C9BF9BF6F7E9BC6CD9DF3FC2E1D15F6691 +:109E8000E58EEEA99D167E870E8ADF42550A1639A9 +:109E9000F44B787C7317E2377E492666B1F7BDEF45 +:109EA000CB5C6E211D73C2DDA5713FE02753BE164A +:109EB000C3B8E5BAA90FC480F49E94775FF0D900C7 +:109EC000CF1BAB0C256E4739667A6D00F3050F3D4D +:109ED000201B7C5D525EC275D167F17C7D15E2FB73 +:109EE0004CB48FEA78DC3A24BE131FAB73F0837C4A +:109EF000F5943FA2F1F5FDF79864C9C6F3ED52F36E +:109F00003EEA1732520B9BF755160CE0F92410F677 +:109F1000DF445E15CA13198AF74D62F4C47DF6C991 +:109F20008B07DAFD8CD6C612DD8753A46669DC0781 +:109F3000A4076C7B72ACF4017B7E17F9857AF9CBB0 +:109F400029C0757CEDD4075A912E81EC97C06074BE +:109F5000FBD749293018BDDF0E70BC024BD2407AC6 +:109F6000BB364D74F6D26BDD20DD332EBAFF4CD4F8 +:109F70008F2579BD413885C19D3D14AE37989EAB84 +:109F8000A21D3785D3D1DBCFD100DF1FF1E261B74E +:109F9000EB85DF1410FBDB5A86F6397E32F5A61806 +:109FA000C6B7BBA730FED717E6FFA600CFBB324E21 +:109FB0007C99F46FEFA4DB685F735DED16B22B8FB5 +:109FC000327B02F3367BABF3D7EF6EE3793217C205 +:109FD000DD2D358C3FDD07648AD77AE1BE1370DB57 +:109FE000CD5A95DB2F64F2F74A60E6C8F22747B6F0 +:109FF000F279394AB953698AE2BC1BDF89FCF58BD7 +:10A000003273E63A851D40EB6CE5D23438F31E8F8F +:10A01000097E3D2DF474B08ACB47AFDF929CFC8B58 +:10A02000B1F7731DF50AF1AD903CFC58CC877795DC +:10A03000782B19014A4ACFE7572BB17FFEF97CC72D +:10A0400079B04E25A3E9887FDD6D92D3BEFD869958 +:10A050008C6A0E7F3614BBE4E7F3D10F52E279FD30 +:10A06000F5FF659A65DA4CB4B360462D9E5B50AC43 +:10A0700000C2AD57B22DE45FD4FA286EBEAEEA86B8 +:10A08000BDD538EE7A5F1CC1D6543DD582F6C5BA2F +:10A09000DA4774A4DB2BFAA22A6C27105367D48EFC +:10A0A000A5FCEF048E3B5CCFDA75F0DBEE3723E4E2 +:10A0B000FC5EDDAC417C993E3853FB1BE883772185 +:10A0C0001EE3C616A3739E7570289D79BE4077D592 +:10A0D000103ACF71D23980749E81EDC6F3C6311823 +:10A0E0009D2F74D119189DCFCED1B9B78AD3B9BBE2 +:10A0F0006E4B4F8D93CE754FEDAD36B07F4EE7076B +:10A10000357E7E37847476E0E9A57358B2D79FBA5E +:10A110004EB43FBD72CFE87E29E263BFF769FBC84A +:10A12000EE0C8F4F7C82F8C0FC6594833BA482EBDD +:10A13000D227116EA475697D80EF57DEA57139674E +:10A14000ED5F89FD42B968DF5E6FC57A7899B66BBD +:10A150001EAE870CEE6AC2434F913F3C0867C1B008 +:10A16000EB28ABB79CDA0F7BDA376154EB316BE746 +:10A17000266A47F3F46FC029ADF3ACDD761A97E297 +:10A1800069F734DB13AC9F8D9AF0375D74F82BDBE5 +:10A1900031B1A4471E94B44BEFD9F250B9D40D5746 +:10A1A000785D4BF3756DA85D4372FB6CF7DEDDE8FF +:10A1B0009FBDA29BFF07F935DA7960DB8195A1E4A9 +:10A1C000A3482F6607521EA9F58D92CC1A5657F94F +:10A1D000201DE5FBF0EEF568BC6D0FD5F27520385B +:10A1E000CA75E98026F204C7301D55CA9EFE446B2D +:10A1F000BE78C33302CE6B37FF56CC2705121467E7 +:10A20000EB8C5DBEB39FF1CE6C49433E3DBF3494B1 +:10A210007C16E9A3EA29939657112729D46E79C2AF +:10A22000DAB5B781F4EE803C465418C74D6B8CCB41 +:10A230004519DD0E6914528B639CAD62B13517F57B +:10A2400058159317841FD7BA4F4AE6DB2717F41E19 +:10A250008B48E4F15FC67D6A5692F2E216368CE0D6 +:10A26000DFF0FC3C663FFC0EC775484D5F32C541D0 +:10A27000779B4F5F9312975E84FAF47CCEA7D251FE +:10A28000F2E9CFC2AE8685E534F80B4F5C48E77F34 +:10A2900082115F02E3F1417F5A2F73C8D1381F2426 +:10A2A000FB46817F130CECFE00FDBFB08FFCDEDEB1 +:10A2B000F055DFC6FB792C5D8D4F3172FDF6B2F59E +:10A2C000BECCB1FE78E35683FEB4802FDC2F879B93 +:10A2D000629D4BFBFEB9FB85DC79084CB0EA307F10 +:10A2E0006895CCE3E877947C85F211565B013D508C +:10A2F0004EEB18D97FEB445E5BB7C86B5B2BF2DA91 +:10A30000FCD6AAED08BF192081F1C9F6F353B4EFCA +:10A310001F5534BD834E0CA5CEC575225A6ECFCFC6 +:10A32000C7E7A37D3558B6EEEE6C66E38DC6ECF25A +:10A33000ED347F3BDBB9BEF94CF057F351DF18E247 +:10A340003CD6E6C645A5304C5C325CEFCEA30BD5BF +:10A35000865C65ADAACC5556CB270CBB7FB10FE30D +:10A360004515389E7E88239E05F286A70665829352 +:10A37000E5690359CC3B98A3C6B71878CEDA9DCFD0 +:10A38000D913E4F6E08F30303413DD2C21178D7CA7 +:10A390007FB564764D1FEE07C1182E17982FE894ED +:10A3A000874272F1F7A68FAFE4700CF32F6EE98845 +:10A3B00002E6BBDC32FB97F1AC817AB53F86791AB5 +:10A3C0006B9826E960DF37CEFEA5912FAEDCAF2576 +:10A3D0009705917EE104D95F9186243DFFDEE31A63 +:10A3E000899F7705F93A3755F053417E36E4F8B93D +:10A3F000AE91F1B32137CFD72969AD187E7E0CFB22 +:10A400009F897AE8F7E4B7AD6FF4B5A01E32A08F4C +:10A41000F27037D6FB7CD8FEDF8B2E365EE1D94C4E +:10A420003F129FB2095C1736C6151FEA917F383973 +:10A43000FC4B3FBD2F420E7F984F0E97D9F250B282 +:10A44000AF355FFEDDD4A0E4E2D706E417A74B0BDF +:10A45000A78BEFEF4297C1F5424BAE40B959165367 +:10A46000C9EF56CA7ABA68DF88AD7BB86F749D6C45 +:10A470001AB8EF04FFE1E7F735E1BAED585FDE0FF8 +:10A4800006793BF2860594FFC186867E192B7F688C +:10A49000D87DD18C7FC0798F89373FE350D0BDEF15 +:10A4A000F44ED5A252E457A1F6DE6CDBABE3395B88 +:10A4B0003B4FC3FBFD3A1952F9CE2FFAD120263A71 +:10A4C000F4A944879BD95A3B0DE9F1A1F9783EB331 +:10A4D000BBAA631CD931E27CC375DB9ED115079EF4 +:10A4E000D7296CF99B3E743C367DAFC365B2CC5125 +:10A4F0003FB3D755DF5B6FB03D519FD96DC1107B26 +:10A500009A4A6A2FEE3BDBE738D46D73B3B46C160E +:10A51000C09BF1F194F02EF63CC73B5BD774A1BF12 +:10A520008DF6D7794C4E5EFBAE1CEF605F97DD7DFC +:10A53000D67C3CE77A08B8BCD8FC7963EB9A71F911 +:10A54000E4A2107F2E0EFD75E46B7AC8235F7D9721 +:10A550009566E1F4CB57A2907C09FA1CEEE3F480F7 +:10A560003BC7E6E553A1F10CF2C9AE27E4CC5BBFD3 +:10A57000503D26578B433351AEB2D139C5C895C033 +:10A58000D7E6DFA9E23B925C69AB6503CF75552B3B +:10A5900009D29B3DE51D96B8F791F23EE5F4347E75 +:10A5A000BFCC607E3B64D19ED0CA4DB2A343E2FED5 +:10A5B0009E40AD5B6F2A31F7F989586B226BB78BE0 +:10A5C000F14B6DB54AFD0EEE2387211B8C6299EF8E +:10A5D00097A2FA43BF22007751DC93D5CB1BF7B487 +:10A5E0009F8AC85BC39C5EBAB70D3E3D429E8BBB43 +:10A5F0009FD8E2E1F36CBCF010568C430EBA17AE54 +:10A60000A7C021879F739BB877D4A6BFB9ED4ACA6C +:10A610002F0F822F4EFE41EC260BFDBE2E319F7B6D +:10A62000F0399BCEF3EAE4AF197CBFC592AEA638F1 +:10A63000837DFECCEECF3E7766C38DC4FF55389F39 +:10A64000F2CCEF3D21EE8F1DFB4AEAF7E887587FF9 +:10A650000203EFC97CACED38ED575F907D43C6F83F +:10A66000FE33A1710477C140BF3CCF312F2F10E7DB +:10A670003900FAE47CE7BDFC56E0299487270F7384 +:10A680007FECC9C3EF901DFEE41F7C1994BB278F9C +:10A690000F9FFFF098F08B6CB8C7FEC0EDB3C79466 +:10A6A000BE927CF65DAEFF0CF7070FBBE515943E3E +:10A6B00019E5E5D897F7C9181F78AC4D935E66FA8F +:10A6C000E77C31CE0B0EF7CBE8378D34AEEF79F85F +:10A6D0006B8F737B13B747B737BD13C2F8FFF6C74D +:10A6E000F9788F8A73B285F07DAA8DE7796C7F3C0B +:10A6F0003F3D9ACFE7FE71B3DF28CF6BD77ACE5BB1 +:10A70000CDD364F739AFD38CDFEE266E77ED56E20A +:10A71000E193C1C77E5FD2149770BD2B85CCDE0F4D +:10A72000551339F73BE322A507BFDE7E35E6B75E5A +:10A730001936A51896EF9226B3B23E41067F0CF368 +:10A7400037DEC9BEC0F05FDB5A42F91B9D0DE5ED57 +:10A75000786E73ECF2DA5DB88FDC8B1115CA5BB8DA +:10A760006B2DE62174E27F5939B03E7D119D930037 +:10A77000AE0F98456B28E3C4FE469E790EB9FC0ED9 +:10A78000E98340AE5E217AA99E7C90002C1A5E4F30 +:10A790002DE57ACD627F3EA07352EEFCDC312DAA0E +:10A7A0008B7EA59EF6CF2EE1F23862FEF829F65395 +:10A7B000065B3483D15FADF3E9198487F818CC0FB9 +:10A7C0002C59C80C203C1F10D377F98C91E9BE1688 +:10A7D000A085C7B7FBC039BF9A4BB87D3FE1DADB34 +:10A7E00025F4238EC699144CC3F2F178BE79714BCF +:10A7F0009BFB3E915B1A1E21BDD809991E5C4FAC94 +:10A80000061FAD67BD75FB7567FD2B4B24911F6659 +:10A81000F31F0C6516DDEB484138A5CE6706A3276C +:10A82000CF7FC543D791F81F59EAA6FB68F9B21C40 +:10A83000F93F7364FE9F6A3F36DF86CE8F76C1B7DD +:10A840001B35A0FD9DE1F5FA50BE6DA175AEA42E9D +:10A850007F5EEE0D2576DCD672E95D0D521077E451 +:10A860007FC9E367B5DE0785FB95CBDDE31B8C3342 +:10A870001A9689FB7FE35919CF7733998E6701CFF9 +:10A88000F198807610337FC85F933DFEDA6D428E7B +:10A89000343840F5D92CB0745A37785E9A9D877257 +:10A8A000911C8E637CA2470FD3BD48A81F799E0ED2 +:10A8B000CFE72FE528313B600026B37AA14A192C57 +:10A8C0008CEB35097C25267798C77FF08D83E88F40 +:10A8D000841BDCF968CAC192177DE7A09DE6390F99 +:10A8E0007270F972F25F3C7C1E6D7EFFC325229F61 +:10A8F000AD04C2641789FA85F2F46CBBDEA6AF71B1 +:10A90000224279395D0725A247C5E4C47DE87FC1AD +:10A910002F65E0F99760E23DC6AB7E3693BE0FDD52 +:10A92000374854235FDE3858A27754179317994855 +:10A93000B633F8EA8301F29FAA416FD6B0BF7E8991 +:10A94000F8288DD3282F6BD54FFDF70586C9CBB2DC +:10A95000F71707CB4A9AF689D7D54ED79CFB979520 +:10A96000A1E4CF4B1CFB9741B19F3874DFFD769279 +:10A97000F3D1EE6F945F76379DEB2F1F0F62FFFDD3 +:10A98000D30BD04E595701AEBCBC7595BCFCEAFA4E +:10A99000290B701F679DC8BBD337BC73513BE9DBE4 +:10A9A00004C5F95633C1437AC25EBFB84FD2187F8F +:10A9B000E9307AC34B870DCA3ECA8BFF6678FFC564 +:10A9C00067219FE23E8ABB7DF346BEAF6AC3BDA24C +:10A9D00037FFA184E6ABDE89FBD0139320F234DD90 +:10A9E000FB1F1370F560E39CC418E467F43863310F +:10A9F00074A0F8542FE9ABC4F5786DF92363F8F926 +:10AA0000FEF9FA21B2CF65DA872E84AFD71E2F3434 +:10AA10005E7B5FDD5BFFF608BF4FD5BBFFE58DFBBF +:10AA2000DC87F465703DB8EFF411F6F467F2C6AD5B +:10AA30005E2DE1F1E84E6341E2F3382EC59CFD2A1C +:10AA4000A347A63C4A7EA2FFB2FA2BF08A3E1BDE49 +:10AA5000CE5B5384DFE62F4FD1BAA668A656C7C691 +:10AA6000A11D90716681966E277D65DFFF80645D14 +:10AA70007C361F2F8E2B00DCFEC5F3091F38C60D58 +:10AA80003147BC0BF58AF0D34E03BFA787670EE5AD +:10AA9000EFDC1E9E771E5BC6CF334D54F2F37BFC7A +:10AAA00012DDC7F7B94E2F9F0BD52FB4BF79FB2D01 +:10AAB000EA02B453A6E8ABF64E62787759A549DCB2 +:10AAC0007739E64FD13D39BDFFEA832D80E31F7E04 +:10AAD0009DEBF4AC738A9EA0FBF4AA52FA749CE638 +:10AAE00085EA7D2DC5FD1CEFFBCF87F97AB329558B +:10AAF000B609F319CCA753BBFCE857C6B8DF6CFB0B +:10AB0000D94B43C9CF871DFA68CC7C2E3F5392574F +:10AB1000D0FC3F5631FC3D0BEB3D789740FEFB5D92 +:10AB20006F8B707CA618AB78BB93868FBBDAF4383A +:10AB3000DE238BDF8B00E487F8990027187DEF3543 +:10AB4000B87C2806FC14E56CB2E503C3C0EF03ED46 +:10AB5000A877BFE68365F9F0688BF0F935D964A66C +:10AB6000A7A887F6693A62D0FC1CBF84D3695D351B +:10AB7000C4C3ECD519D81EEB7FCF1495E492F9BE6F +:10AB8000742F526035D0BA1DA8838C81FB0ABBBEDE +:10AB900094457EA9F5100FB27ABBA774D17D2BDD49 +:10ABA0000698786F92FF6636B1F07BAD2F6362BE78 +:10ABB0008975157D5FABF37BFCD6D63603D9B131F1 +:10ABC0005ED60C7EDE65DD5485F0B0EF1F27BB93AB +:10ABD000AD0FFEFA812C5E5967C0326AC73F9BF306 +:10ABE000B5EACE263A8FB66ECC0374DFBFB51CF83B +:10ABF0007EA6BDEFAC30B962EF3B97E979E327EF72 +:10AC00008592DF72CA83A2EF2379289407D71DE6C5 +:10AC1000F4BC4DE8B763FE2CDD6FD8BBD647F7B662 +:10AC200078E13F2BE87F77E7A28FD3F5D4629DB11F +:10AC3000BF1F2A315CF765541D57693C0BE49B41EB +:10AC40006778DFC3EC24BAE7052F063D931AB8A452 +:10AC5000D2716EE59E781FD945AA6D17D5737BC654 +:10AC60003EDFC8E890FD26FBAE639E3FF303C7B707 +:10AC7000E6B78FBC7E5921FBA8A7C4FC19D2AB4B09 +:10AC8000E4ED7F7DE9227E6F6581BCFD3BC5F8EF79 +:10AC900094ACEA2ED48F93F83D335EB843C25E6421 +:10ACA000F620C9CD3A8BDFC7B58EB93E8FB272CFD1 +:10ACB0008DFC3EBF1ECBC7CF7FD602C54962375D34 +:10ACC000A5E59BAFB61DBD5EDCAF5568DE95A899C6 +:10ACD00064BE75E99F227C5F6D6CA3417E1B51723F +:10ACE0001C2E279CEEF4C4785E1D5FB7CF007D2E2E +:10ACF000E6316E5E58534DF77CB275036DE27BAA68 +:10AD000033D9F9289712F4DD8F95948CB59495CFAB +:10AD1000888F337A1DE7BAF5AA07B278EEFDF627D9 +:10AD200003106864E5F99EDF67E3E40F2AC83AF789 +:10AD3000EF532934BE629FB7327ABDE488370324CB +:10AD40005B703E85D87A8AF326D894C9D2EFD3B007 +:10AD50008280E3E8D15819F9D21902BC6F36541F2A +:10AD60000F63DC36D43FB7859EF5895E949FE8EC8F +:10AD7000AD7ABE73312D916A97DC87EBDCF99A418D +:10AD800071EE2858A552BE5A30A9E6BDDFF85089A9 +:10AD9000C2ED68D625CEAB1E6B783D7BAA72F1BAA8 +:10ADA0005867F49C7F4C72C14325EC59B5E00DD92E +:10ADB00071DF66C4EB5F78F9E8299F2A1F7B3D7C31 +:10ADC0000C36713E02E323BF07C4EAA17317860F56 +:10ADD0009CE72EC6476A5CFC508E2B748EF6CEB96B +:10ADE000F9EFE31C1FE179DD3D25894B2294570BD8 +:10ADF00012E5F70ABD7091BC81EE3162D2C1EF8FCE +:10AE000067FDDD9F473F8E8F70FF756BC8BC3C525E +:10AE100051785C8F4985F0E0F50F093FBF783DCB55 +:10AE2000C737C57C2D4871CF2F0DBFEEDBEBF3315B +:10AE300036B67D686F2B29D23B4ABF019D389F6390 +:10AE4000BE0CAEABDDB145A417EEB1988C4824978B +:10AE50005086FEADD01350DF1FC4F88B5FCCAB7BA8 +:10AE600056FBE8BED8508542F7D7066E4EB2B510F5 +:10AE7000CF350E6431965F75E702C293AD53372329 +:10AE80009DA3B1BE76D447FEF20CED0BDFADE821F9 +:10AE90005CFF8FA191C8ECB3EF86B777519EBF9945 +:10AEA000C8E29597E81639EFEFCF58EEFED800DAF2 +:10AEB00051EF7436E9646F9F71733F38E72BEB777E +:10AEC0003DF265625D66AE64E4D647AF3D51C88E23 +:10AED00060EBA8F0CBE675A15F46262C2B3F147ED5 +:10AEE000A40BFDB07B75F3AB11F283F2FB0F4C2E7C +:10AEF000BE7E3272F1AC98A7B65C0CC647441CF516 +:10AF0000AA46103FC615BF66785FB3D70F38FE0B51 +:10AF10004FDCBBE79B8C1EB23817C734F99E27D88D +:10AF2000F7A5A696C0F23507CF5631CEFACB093237 +:10AF30009E0146398BA29CBD053E8AFFBC05FBA342 +:10AF4000331CF83C21E60973805EEA77C4173F9F03 +:10AF5000E6655BDF7DE14E77F96A58340EE387578B +:10AF6000DFEE878C84BF57CAED177F27C2F3C5BFBA +:10AF700000A92EA4F35A71EFE9F21F9CADA27D74D3 +:10AF8000CD0CBD1AF72F6D3C7E22D6B337991C1B12 +:10AF90000EFBF5DA7046C57CA79777CCB87C0E60BF +:10AFA0003B99AE09B85E8D81BCEBF4E77ADC788E14 +:10AFB000340E2FDEF679A1427828DBA4BC71AE9F57 +:10AFC0000B7BDAE6E3A9DEBFFE7684EB03FBF7D367 +:10AFD000D97962A7DAEE7BC2AEF6B6BB5CC30BA42E +:10AFE00001562AE916A926B76F15F4A7CC8968DFA0 +:10AFF000ED9C9BC5DC73075C4F91702DBE61E046F4 +:10B000001ACFAAD03D518C07F5337F3FDF3D3A95EB +:10B01000A164245A31F43E1D10BF0FE8D06FEC7BC1 +:10B02000EA0716601C2F00CC6FA7A7427240F11DE3 +:10B0300009EDD17416FD80A0A1B8E4A304F74398EC +:10B040005DBB52D88F2575EEEFDE78CF19512E07F4 +:10B050004DD04FF67D540B6771BD854677FED21DEE +:10B06000259F253B72C53E3F1D015801C6AD4D0DC4 +:10B07000340F29CE75E3BA33699FF7C60A83EEF918 +:10B0800055206E525D8FDCAD3C2E41C6E1FFAF54C2 +:10B0900006549C6F2BD9FAE17C7F434C365EC9F392 +:10B0A000FB99ECA79F69F5701DD2C1C7CFC5EAAC6B +:10B0B000EC18E73B69A985EFAB19A58B87F1CB6F3E +:10B0C00088A9D4CF55EBA694F2B88F5B6F1E11EB15 +:10B0D000D47F3EF41F2AAEBF6F3DF8E2254887EBD0 +:10B0E0001E934163FD1E792802595ABF322AAE5F72 +:10B0F000D7EE90F3DA5598A9447925DB797CF2DA1A +:10B1000047029985ACFEB58FBE7C0E30FC8E740C68 +:10B11000EC9988F3E0411E3704ABFF9CCBD8FB6B66 +:10B1200015F8DFF9ECA62BA2DC0F38FCC312BA7FAE +:10B1300054DAB6EBB3D46EDF15FE80637FED92A8D0 +:10B14000DF86E371CE6F4B992979F6DFECB8FAE12F +:10B150006F4B1CBF9D7EBA8FF5DA6DF7A94986C784 +:10B16000CA6D6F933E99B7FD3B51A4C3CA9DEE7D56 +:10B17000B6EBB6BFDF857924D7C930B010E5593EAC +:10B1800041E5A3A6362093DEE7E7A557104B18DC70 +:10B19000F75E5BF06BF6FDCD980C41A67ADFDCF72D +:10B1A000AAFA189693E1147AB02B77BAF5DECA6D35 +:10B1B0002F535E83EE8381AA39B8BFEF966B2F3C85 +:10B1C0009B3F2ADA212BFBD6BD2D33BDB172C75B65 +:10B1D000CFA3FE58E9D19F6FE27F2A87C6A1DBA2E9 +:10B1E0009E7B66B61597FF70DD778EDE63B17E0FAE +:10B1F0003FF2BB7B304FFEFABFBC7BCFBFA3BDF09D +:10B20000645047FDBFF2C15F44C1218F5F8F727BE5 +:10B21000EBC824B02A19DC91FF17C8E0FD57479E00 +:10B22000786D329E733BF2DD3F8E3318FC8D4F5CA0 +:10B2300044F7EBDFF8FD79E387B3C7515E330127AD +:10B240005E197E5E6CA7C48D97C7C5D3C38FC3DF5D +:10B250003DA6A25DFB9E0403B8CEADE87B5F457FB3 +:10B26000648F0903489FDD3B5EDEF36FACFC16E3A1 +:10B270004F200F7FD8F827FA68FD666A923D57EC99 +:10B28000787901E2BB1206683D1DC2CF038C9F0D89 +:10B29000397E7ABF1F85132AC663573EC4F8770EDE +:10B2A000F291F1EF9CA1FC7B0BFF337B28FF7E101A +:10B2B00075E7091D85EBEFADC48DDA1D63F3E6314B +:10B2C000E4F61186BFCFC4D60723D17799C4F1EA3B +:10B2D0008C9AFF19C579F548C9207F17227FBF7363 +:10B2E00074323A39AFFB073E8B74187822A0E3EF33 +:10B2F0008FB8F6895FD13C3BF2FD675583F66D2030 +:10B300002ACD626518FCD90FACBC82C7B661F9D6EC +:10B310003F2F789ED55F8EBF204327BE51790F9B6C +:10B3200077C487CCA52D06AE9B990A1AF78A0C9F85 +:10B330000F2B32BB16E3BD125EBA4BA5F6BD9E398C +:10B340007EE27D4F2B76BCB800E5AE103FEDF1EB11 +:10B3500038FE73D9F7ADEEF9EA855FC1E627AD5344 +:10B360005EFE6676FD373E8FDC1750F07CC51171AE +:10B37000DEDBCBF71CFDC5F9F751EE33FDD93BBF42 +:10B38000ED7D2641A7C2F2C1E7F948E31B2DFDDEA2 +:10B39000881ADCEFF6D0F1F089FCFA7F7C295FB7E0 +:10B3A0005740BA054D67AFBDA240D29A589DC3F72A +:10B3B00030DA170CDFC30FCA14F7E9EADB4D7ADC89 +:10B3C000AB2F561488BFD6D9FDEDDC750EEAB5C398 +:10B3D0004FFD90E473C5432FAAE877ECD9F63DB54D +:10B3E000BF3E371F707DC838E87DF8E15DE7707DAE +:10B3F000903FAE3553B4BFF27177FB2B1F7ADBD58C +:10B40000FE75561FD90B23F5F3A6625E81E37D73AB +:10B410009F9FEE137CB34FCE1BE79E50EA77D9C1B6 +:10B420005DCF2EF8359E676DD81FA27B1477749878 +:10B43000E36F41FB6DBF5FEC1F9ABF43BB74C7B3A3 +:10B440002103EDB41DFB2FA77C1EBBBD1F78E8793F +:10B45000EE016B5E84B5776E7FA201F345BC7AA3E3 +:10B46000F120F3F71C7270E3B32DE351EFA37F6C6F +:10B47000A0E3ADC4E91C951C5D4079E2B2EED38334 +:10B4800079D76FDE9E3F9CA0FD1C3F134CE7BDECBF +:10B49000179EF8BFE4BF77C5F3C7FBEF2AB5F7BD2A +:10B4A000F9EF77B2DF6F90B8DC58CFF07D8E42F3C2 +:10B4B0006B5B5B2C5ECB4879575B631CF77396978D +:10B4C000F2F8C7D4572C1F9E0D99DD6F4CC7F14F72 +:10B4D000843EC0F3FA3BDA74821FE4FF4266519760 +:10B4E000E37DF3104738EC17FDB5D1F67B73A17EF1 +:10B4F000EBFB882EC5F4AB9D44BFEB4BF979E953C8 +:10B50000E9377C127406DC1D2A62BCDE3C296FFF21 +:10B51000EA349EF7E5ED6F4929B733EDFD039A7ADA +:10B52000C3C4D5FCA29DCF941A2E7902254BF74FA8 +:10B53000E7F22A32527703EECB0D9E174E688EF358 +:10B54000C2EC3B9D175E63F23C56568FE6418F88F6 +:10B550004FE03EE5550E7C9F15FA2350958AA1FDDC +:10B56000D58DFB0D79F4D8F342CEBB23CD943FB2F9 +:10B570004B9F5EDA3FCCBAA1ACBE6B86F35CB1A246 +:10B580006725D7FEB0F932DD8355A8BE77DFD0C678 +:10B59000BF7BD797A006F35CCB13D09107CF3E219A +:10B5A000C708578D70B124B43BE0D4181FA75DEED7 +:10B5B0007E9FDF73FBFCAD07BB515F16A2D30EC1AC +:10B5C000CF6731116426B96F1AE663F6447CA4276D +:10B5D0007B82F9EFA3FF45CE2EA0FA2A9E5FA478C6 +:10B5E000EB3EF21B8D132F9878BFD1ADF52AED0BF2 +:10B5F000459AF653F9A8E923EBBF107DECFB08064A +:10B60000CB05E24F8D3AE7EF6EF311CA6FBDE16CE7 +:10B61000D5182E9F22B47A5A1CCFB36BABE7C43136 +:10B620003F2254C77F9FC2C6F3793C6D6301F998EE +:10B63000A573F958FF453B2E992539D938CD17C444 +:10B64000E7FF075094EC5E00800000001F8B0800AD +:10B6500000000000000BED7D0B5C14D7B9F899DDFC +:10B66000D9D92730C002CBF21A10140D268B226ACA +:10B6700035664134F8885915A326185763521201CC +:10B6800037D636B4B5611010C447486349DADA7664 +:10B69000A5D892366D31A58D491F77D5E8B58FDBDA +:10B6A000A2318937571B34DE5C494D2F7DA4F5DE6E +:10B6B0006BEBFF7CDF996167965D3069DA5FEFFFC6 +:10B6C00077C92F999C39E77CE73BDFF9DEE7CCD9D6 +:10B6D000A3DE6909830E426EC0DF1DA39FE6862F9D +:10B6E0004EAF981E2EB7E5C473FE224276E63C4E5E +:10B6F00006E9D37CBD91F8687F334FBC7DF499E8AF +:10B700002547139CB4EC9D986BCEA54F0749379401 +:10B71000D07E6513B91DB9A3E11FCDFA84EB12EDFC +:10B7200097E625E9F06C2B13D20D1A7C3A3F1320D3 +:10B730003E3A4E6B99B016F034873E49A4384DBD61 +:10B74000682064067D5FDDE9F5D276F42FDD47EBF6 +:10B75000094FD25768DB71644D5FD1E8F1F78B1C5C +:10B76000212984EC56EAF7CD7EFB990728FEA257E3 +:10B770002A365230FB8E0E91BCA9B41C1AF27230DC +:10B780002F27996625A3E140BB5CDA2EDEE5271B57 +:10B7900000CFCC41E2A7E3C7170E1298BF4D22920B +:10B7A000414238887FC2AC6122D3760973075DF2CB +:10B7B000540D9C3F1BA3E27923C18078DA1A4A3CDE +:10B7C000F9C984581AE679F2E9BAC4F10344A470BD +:10B7D000E22446FFC87E6F2530FAA874E92C9B98B6 +:10B7E000E08F065F5DDFC653A9BC49532EEB5C03B7 +:10B7F000F43739FD32CC3F7E16A38B5A1F2F0D1222 +:10B800002F1D379EB0799212E23D441F712532817F +:10B8100071E8905EED7C362AF4DE28B2F9C09F37DD +:10B8200015DB11425FC579170E196F85324F2E1542 +:10B83000B2FA1BB90417F49245291B479763CD67E9 +:10B84000BCE7AE46422E69E66BC9A4F357E1D27F4E +:10B850003B4D241DE8FB41E926B806911FD4F701B2 +:10B8600065FE26E720D26714FD8A18FDEC458C7E24 +:10B87000F608FAED52FAEFFA07A3DF089D38C31A6B +:10B88000E0C3483AAAEDE78DE02DE393F623E423E5 +:10B89000505E5609F2DB6965E5FDE25D9572119334 +:10B8A000AB71E485103721A59D37DAA0BD5B14117B +:10B8B000AE7913D5070E4DD9AFEA0736AE23D7536D +:10B8C00049283F935C03394449DA3E5776C17A757B +:10B8D000A0A484E1BF2A4EC0F66D9260E06EA3CFB3 +:10B8E000530BD20885DB6CE9B4C07CDB4D9D08A707 +:10B8F00039CB207647D16FC794F91A1BECD37BA6BE +:10B90000C7A6A35120FE6872FFA6D2BFF9E8E74F91 +:10B9100019297FF092205929BE20F46FA9EB9B478B +:10B92000FB93BE81DC5C18271EC7712878390A0C8E +:10B93000A429777C3CBFA5F015DF601D134F1EF0D6 +:10B940008CA267543C5B004F676C3CED59E5C8A77F +:10B950007C8303C7F99128A17E729802968D747E2C +:10B960008EA604A9893E77F181F66A780E98884CF4 +:10B970009B9888F75439C59B9F3A8D100AA7F5E22A +:10B980004CCB04E0FD864EE2D3E8F94D36FF05913D +:10B99000C2E3453FF1533C7947C00B68F42A7CA0D1 +:10B9A000AE1B294C2264361DCFCF4F077D6AF70BA3 +:10B9B000F854E1A87C623779895804700CDE207D48 +:10B9C0005A00D8EC70BB8F2432BA35CF0DF908D8A5 +:10B9D000B9629E809D6B33794F6DA0E50E3A9F6EE4 +:10B9E000FA6C51F846EDE74E4C647CA88C6F2355F9 +:10B9F0000921806D7CCEE51FC31EDB806EB47DC344 +:10BA0000F9DCEFBCACD295FEFB3F629CF3ED5B90A2 +:10BA100077D3419EDF2345AB0D86D870FED4287DB9 +:10BA2000E7658DBE6A20CC7E1022A52D9F1ABBDF54 +:10BA3000EE46323DBF205CDEC3072C409F36C7D6A2 +:10BA400053B9749EB2C7E02990004C898E4E914F35 +:10BA5000429A70DD4DC403CC4B9A33CB4F954BB01B +:10BA6000BE2B5C8F43B5D1C1535B4B4C1349D008FF +:10BA700074919C3AB9DC64637C13B9CED6113A1E3A +:10BA800018938E56454E22E9989FF8BF938E2265F3 +:10BA900027E4D7B8150921E8779CFA49747C92A964 +:10BAA000973FB59FCAEF91F3AFF85F3EFF483E194D +:10BAB000DD5E56ED267F9436CDF093600787659F57 +:10BAC0002515BB5218543E2DA126304D59D57DE980 +:10BAD0002708D8E716F16D0BAA2ECF8DE4B1E0F35D +:10BAE000E46D959EC6F0785AFA18C0EE9C32050FA8 +:10BAF00071613AC589F7BB8E920F4EA7B6CCE7C5E8 +:10BB00000D1AFB71592CDF9E48E9B213FCDA28723A +:10BB1000B03EB15C4EA4780986E8FA7C3FE835F483 +:10BB20001B457E011DE78E613D9D6E57E8342FED6C +:10BB3000ED4FC334A996E40955C8E53E4F05D0AD95 +:10BB4000628D0FD8820819D76FF1233F54884017B0 +:10BB50004E9E64B861BF79FAC5A2978323BE687808 +:10BB60007F455CF1259897A388D24DE37F50411023 +:10BB7000DFB66BD6C5E11C87AFD8BA1DBF90669003 +:10BB800069D336972108F18C8904DA81EEE4AC910F +:10BB9000809F961A4AC77AB32B2F08F62E35642554 +:10BBA0005E8C13C4A095B6EF5A7B8F07F5D3B539D9 +:10BBB0002444F906751965323ED31B027F9A17A5F6 +:10BBC00032A304E33C6681F8A6CDB52281307F9B89 +:10BBD00044D35F7589FE17615DF96BF3109EC1E276 +:10BBE000453FF166E7F3F4CA78027E80F53C1734EE +:10BBF000535C9E5C39AF7D90CEC742E23ACDF4D91A +:10BC0000CCCB21B063F279AB04F4DE5A20DF69A01B +:10BC1000CFB25F590B79FABE9DB379800EED0574F2 +:10BC2000C9299C3F7DDE1E24B4BC73E5B2E10480CB +:10BC3000D36394A07EFF8DC06DE04F59AE3F81F17C +:10BC4000A145890F091F9809EB67FD807A6237DFEC +:10BC500089FCBF2B7F9A45EB8FA7DBFCE7812E6A1F +:10BC6000D9EAA2FA6D3AF2D3A541CA4F0699233711 +:10BC7000287F5A1CDB5C2724982F7DAFF2476EB8D3 +:10BC80005D586EF56527A535F89994C316815FD97F +:10BC900006FA06FD562273504E67F5BF7DF2EE455B +:10BCA000E087B659D5FAE58BBCDAB2FC3FA7B0BF46 +:10BCB000E2F7162525ED82F6CE0C1260F4F19155CF +:10BCC0001A7F464AE2510E7B12BD7F4C9C319A2F5F +:10BCD000DBF3195F1EBFD05699077C4AF9D22C01BD +:10BCE0001FEED2C5C9EA53E5C3B67CC667B1E86E9C +:10BCF000BA564C421A3FD0E4EC447EB4387DE84753 +:10BD000047B6BF2B99E90B95FF2D2E82F26091FC6F +:10BD10009F7F10E5C3E101F133E7070847F9C42429 +:10BD2000B27878BC79C4C24FE5FFB6FC3C19F8F58F +:10BD30003D913A1263B4375D2BC1F9D4257A7392E1 +:10BD400034F1873387D23DCA7CBE98C4E6D3EAABD0 +:10BD5000F63D48E17A6B2419E5C6453C1D609728FD +:10BD6000FB83DF49FDCD5B9252B4740A307954E015 +:10BD7000CB5CE0A809E4DC49FBD1B72DE487322C89 +:10BD8000BDC919D4C9F7BE647F4992867F7991C530 +:10BD9000870B8C0E03F900F47982C665A14984EC07 +:10BDA0006D14F1B9A7D185CFF646099F1D8D5E129E +:10BDB00032D3F0875C3BF700F8D90E1BE2371E5FE9 +:10BDC000B4367AB07F4BE32C068753F9BC7017F07A +:10BDD000B5CDA0CAC9AD584E30AAF525BB30BEE3DB +:10BDE00058FDD6A4DB514EE87C50EFB58F33AE3111 +:10BDF000588AEBF7FEE12BFA5BA1DF13B77FA23283 +:10BE00000FF8EF7523D1E63146F14B888D77B3F00B +:10BE1000DB330DA84F9FB87DE7A95CF05B5FA3F013 +:10BE2000C7E2C74E063F263C15DFA3BB105F335D5C +:10BE30006F2B85671699BE8F250F91F3A54F82F260 +:10BE4000E124A8A79F38BA961C07F9A4C35A4590C5 +:10BE5000539F17F25D420BA5B107ECAD2FF455B01F +:10BE6000B734D03944CB822237D4ECCBC7291CC19C +:10BE70006B211DB4DFD1DBEF21D0AFED650BC589A0 +:10BE8000DA87E43CE4776B411569A6ED76565A896A +:10BE900091BE4F98B78600BC9DBFB022FCDC539387 +:10BEA000515E77894C8EC6D5432E030969EDB8C51E +:10BEB000162EE781BEDC447C5351AEBF90A4D18FD7 +:10BEC000D44E7E19CA02A990090776F8210FF343D0 +:10BED000587D4FA2EF206BEFC3FE61BF304044900E +:10BEE000D7B3C66007C49BC65A74FA161A0F580611 +:10BEF00051AEBDCBD24B09713014C82E4F886403AC +:10BF00005DD28DD417A32F3C020951BBD149FF014B +:10BF1000FCF8F343E7C9AD84A4AD1174F3E0CFDBC3 +:10BF20002F1A6E05FC587BD50EF1E7EBEAA03D4FCA +:10BF300034EDC13E19AB13C68A6722FDF81F2529CF +:10BF40007EBC9D6481DD6B693C42DE3285E1F0118F +:10BF50007925F5A9FAF39B930D7AFF4762FCFD1250 +:10BF60008DD3811F5B5F3592EE28FCFD87A45C9D1D +:10BF7000BF9BEE3784E747FF7DF982B9BC4BC79F73 +:10BF800063AF7F468DBE7F56C0A6A3634E4392AE7D +:10BF90009C2BBB75ED27B4E7E9EA0B3AA7E8EA2743 +:10BFA0003D334D579E1CFC88AEFD2DBDE5BAF2D445 +:10BFB000BEC5BAF6B71D59A12B1787EED5B59F7E22 +:10BFC0006AA3AE7EC6C023BAFA99E7B6EACAB30737 +:10BFD0003FA56BEFF28BC78E807C527E34527AED98 +:10BFE0004A979F01FB39D84CFDB879CC3F067B4B73 +:10BFF0003289E21F53C3940A7CC5FE5AC00E809E4C +:10C00000DFF3E9D067D04E1A3C20BF7CFE42EF46FA +:10C01000E8D7221A884BA347A48504DE97EF49C4CA +:10C02000F7DE9226940F819A0D6B3CD86DFD7A1045 +:10C03000E376D207F8BDCEF0E34539AA7E1232F599 +:10C04000FC6F26F725F8C6F0FB4C92BEFDFBE5FF22 +:10C05000AC64CAFFE0706451FE378EDF5FE5FB47DA +:10C060000CDE09C92C5F5E71D6A98B7B90AE237163 +:10C070008F85B4803895550F679C60CD95F8C66C58 +:10C08000B871CBCDC73791F2459F94E6749D5C4C57 +:10C090005FABFEFD687B385DE79F453E9BE31F413C +:10C0A0007D47F5E2EDC93ABDE8F32643DCC77B5195 +:10C0B0002FAAEF737BA7A05E6E17999FD22651B966 +:10C0C0001C835E917AF9F34912D39F31F4B340F5A2 +:10C0D0002C18DC9D2BEF6F07BA79B711B44BD4063F +:10C0E000A19E8D844FFDAA7B006FC1C5FC29351E22 +:10C0F00052E32D0BD51F105F592482F432537AD9A5 +:10C10000D13F7A0CFD4B3A0F09FC23B393FA9F60A1 +:10C11000EFA9FFC9FCCD0FD7BFCC56E63D4217C5EE +:10C120005EF6D8BCB5C929B1E1FF20C67ED4CB49A3 +:10C130006ADCFDBF93FFE6264B887F241FAA7C663E +:10C1400006A6A3E3BD27B175A7D38AE7D4FD0B09E3 +:10C15000FEE3477E3931EB8C3C1FD6CDEFF09AA938 +:10C160005DDD376B05F61326F004F44CDCE086A5A4 +:10C1700060274909D31332FD07F8CD56A4D71B9683 +:10C18000083B2A803D8E1F6D7755FDA0C6E7E3E989 +:10C19000976755FD3293CCD4EA975871B8AA5F548B +:10C1A0003ADC71BD5144BFE33AAD57FD090AC7946B +:10C1B000C5FB20CF2C7888F76014F9FB27C52EEF3C +:10C1C0003D66C5F8DBB146C038CBED0995019FBA95 +:10C1D00003C403F4993518227E0AFF0527E34FB7FD +:10C1E00027C881FFEABE1CE400CF2E13CB0BB9B7E2 +:10C1F00005396DDEE8DF93593EFB4F171EF3C0BAD9 +:10C2000097E738504E3FF620417B3DE0DAD859069B +:10C21000E3CE221E334E97276E289F3307519F7817 +:10C2200006BD024BC1C97174E82B8D64DA261ABFB2 +:10C23000BFD368C1E7D546119FF3730E1CBD83C2FF +:10C24000DD9A6BC37C416B9E0DC769CB16900FFFC7 +:10C2500098F5480EF805BF697461FBF6C703859031 +:10C260004F683BC6F68332BCD3711F14A9E6027C2B +:10C27000426C7F870FB860DF37E3F84FB05D9BC932 +:10C28000FFAF1B283EF25AC17348627480F9B6585A +:10C29000D9FCCDF680279196CD13C8FAE5D1E451AB +:10C2A000A107E524A3900A7940C6A7C22CA909F2E8 +:10C2B00021542BF451F488A935C8C1BE077958948C +:10C2C000202F9469091EA5311FC9AC113DCD04DA98 +:10C2D000136FD0115E0F9395F80E3BA05D887B9491 +:10C2E0008EDBEF64FB13EE736C7D7E7FFECEA35975 +:10C2F00024B61CEF69AC3C53A1C9BB3A48F4FDDF3E +:10C300007373CAFF027A087D045CD79963DAC19B14 +:10C3100085EB75323D75FCC2A434F08B1BF8E8FE4A +:10C32000A45154D7494A8378796B819496E8D0C256 +:10C3300061FAC278EC455C2F7B5110CF17347FEF48 +:10C34000F5FA4F53FAFE8E7684BCD4CB173E8A7131 +:10C35000E2BB49D213105FC93F351258CF77BF3FB8 +:10C36000F32449183DEEAF1B4F25F19ABCD1BBDF3A +:10C370003E5D6AA2F0DF7DFE74298FCA26A8D353E2 +:10C3800075375E29853C95D0F07BF7658AAF5C4EAA +:10C390000A0350A68E32C69B72DD92D01874EB4A07 +:10C3A0007DE851C80B069B1D2247FDB2A7ED7F110A +:10C3B00080EF1A007FFADC6219DEC9D125FEEFAEEC +:10C3C000B71757D078722B27CB0E0EE8269B217E0D +:10C3D00020E7CD1EE09BAD05CC2E6E7D580CCAA08B +:10C3E000AF42012FA6852CAFB82F537D6BFD79107E +:10C3F000F6FA490BE79B1F0779BAA904F97ACED55B +:10C40000400EEC1F2712210FF8D06430229CE10B64 +:10C41000F66037EAD9C04CD0374D171E9B04EBF5B8 +:10C42000FB64762E40CDAFA51A024F56E7427ECD73 +:10C4300083F9B5DD7C1FEE93C59AAFDDC5F60FF825 +:10C44000F944898F7FDB119A1BE60755BE22FBED6D +:10C450006F249E7CCA5F2F355A3C30EE671B457CAB +:10C460001E6974E1F38946099FDF6F2CC4767B1B3C +:10C470003D58DEDD380BCBAD26B2DEA7E1B34F3839 +:10C48000D93C5627947DC2499FFD14EE65DAAE97DC +:10C49000F687E79CB341631CA5C79C2B542F4A50D9 +:10C4A000DFEEB94CE17D91C283E7E87A4B31BC2FD6 +:10C4B0000DF685044ABFD222F6BEB7B157E977041C +:10C4C000E1D27AA47FE955566FAF6570EC57D4F688 +:10C4D00085C5CA38C5D09E8E5BACF48B848BEF29A2 +:10C4E000DCE268F844B6A7DEBC91942AFB1410D7AE +:10C4F00099FA38F067648E840EC17EC6F9A7CBC066 +:10C500002EEC29267906DAC894D2CF41B9B78188B2 +:10C51000C644420AD3A7759401FF98BCF85EDECBEF +:10C52000070FE5A21D42B8AA1DCAA80D79817FE2B6 +:10C530003D24CF584CD741BA84F686D035B6CFA12A +:10C540004353F1B9A4B1B337E87FE0BC01AE0BEDC2 +:10C550009F5EABAF1FAF3DB52711F5D1F9EE833E1E +:10C56000BFD8A83FE7D15547B538D51B5D8A1F76A0 +:10C5700000EA61BDEA4A133642F9D187D2416E7FA3 +:10C580004F5C1CECBB8FF48BF0DB0E349E4AAD2865 +:10C590006078037D32B78907B5FE6CA64CF9552348 +:10C5A000077B037C6537E611FCE92B34F14FABC9FF +:10C5B0009F4E8597FCF6A9D717817E00BB0C7AFAAF +:10C5C0002357981D1FB1DF57997E54FD064159AF7F +:10C5D000CF95FC2E04722F833D02FBE4F19372DAB7 +:10C5E0003F658681033B448AF5EF9D02C3CBED0A8C +:10C5F00072504E76FA5E06F9E1939E21C0477FE8BD +:10C60000374BC06F7B8FAD2D04FF790B8997ACF44E +:10C61000BDFB871705C0A3D5302810AACF86F66FBB +:10C620005BCC537FA75550F4243838741D5B5315E9 +:10C63000BD20FFB1A302FC0D837F08B67AD5F65D5D +:10C6400036FFA350A67F5E0BB5DFFBADAA9E0D742F +:10C6500078298FED37B1F2D0FE2D1D329669FB623D +:10C66000566E4987FD296FBA81D22BBEA9AEE3541D +:10C670001694D5F6751D72265D4BC59E12873F1721 +:10C68000F4DE4859A4E5384D9967656261CFBDC7AE +:10C69000FE4B807DD3D6D4E1931940CF1F737DA08C +:10C6A0005FEB8E3F7B14CAF53544823C9CFBC8414E +:10C6B0005C87678D6543CE1490E353223AE4F0A77C +:10C6C000AE0BF54727BB08E68D852017CC033FADA1 +:10C6D000A8D3807EDA76EA5B1703BDDB53619DE762 +:10C6E000A4323F637290C2D1C8C1649E86EFD3C0AA +:10C6F0005C998607B57115F118005F2439FEE7DCF7 +:10C70000E210C5A777966C9B42C7DBBC81F7344922 +:10C71000607F824DE08F91231CDA89DC53E93BBEB8 +:10C7200041CB57FB92BB21AE30ED607CB039B72FC7 +:10C73000751A7DB65A997EDD9CA89413F5E516C549 +:10C740006F7425CA8949F47DFD9127B3658AC7D0E6 +:10C75000A199182FD6ABF8C87B1783BD1C3A3A3B7A +:10C76000610E9D6FDDCF59FEB2AEBF7831CCBF6E8A +:10C770008F8140BC56DF4FF9492B1F540EBD93E803 +:10C780003CBC9D5378CA1F8B52739758E9FA3E9B65 +:10C79000E715815E1BBAA6ECB6D020E859419C0C87 +:10C7A000F2B2A1CBB31BF869F38C4BC88F96CF794B +:10C7B0007E569944E3AF7B2B17835A4B3530B9A48F +:10C7C0000C877ACE98B80DE9FF9F6564D89C88E401 +:10C7D000C4FDCC1CF83F8ADF24D15B0EEDC5A53427 +:10C7E000F4013E157CC7C00F91CB2D980F2D1797E4 +:10C7F000627DF61A62E8A0F81C9492929A68576BD0 +:10C80000BED7007E4A9ECF86794E635CC50E909B54 +:10C8100043675939BC4EBFC275B21506FB2C14CE06 +:10C8200044072F42CC916AF45A60DDA82C0F1C2AD1 +:10C8300001792168BFE5CF16615EA72B9ED43C4FDE +:10C84000E9D463D8D8F113DAAE27C949C0AF6CE593 +:10C85000B8F52BF07DF994AD146E8FB27EC6448F7F +:10C8600008EBD593A82FEFE7363E0C72B4E5732F93 +:10C870002C86F9A59ABD9DC914BFFACFBDD0E19A07 +:10C880008D74CEB350BAD4A7BCD061A174EF69F255 +:10C89000BA454D79D29FA9B6C679BC8072CA277EA7 +:10C8A000F61190635AFF530BE5DF6793547F80D5F1 +:10C8B000E7E7A9651ABF521D6F6C1A29CB16AAFFAC +:10C8C000F335ED2BA8DC7EEDCB46A2C20FD1B26DC5 +:10C8D000769FC566C479101BF8335379F4676C8969 +:10C8E0006C5D6D93F3D04FEAB1327A0D6719B07E6B +:10C8F000A1F13911F200E6C9BCC18CF173C0672AFD +:10C90000817D579EB0BCEE01EF6409D2A36C1F90ED +:10C91000EB5C8E71A0B550B3EF47205ED5EF13F2FC +:10C9200011E502F360BA81DA61E7F9E55C36855713 +:10C930009BA2C4854E920E79D7400AD3338FF9E477 +:10C940003B4D12F0D8203B9F4A7CD3E099B62E3F56 +:10C950006DAC7385A3F7FF43E897ED711814BA49DE +:10C96000BB43D4476D763C2F821EA1667EC701F083 +:10C97000279D3CF24D01C83F2D6F4B64F9F6DCDE7C +:10C98000C54FCF02FFF0748101E49F173D229CA7A1 +:10C990002B8B2B4900BF8D1FE1D357507E8D4767EE +:10C9A000DF0DF19E00F24BDF1EB0B273A0C3E9A40D +:10C9B0000FF2BFBCCB4BB4FB81AAFCEE6CB4E073AE +:10C9C0006FC98A6FC03EC1D7DB09EE07082E1F96DC +:10C9D000A516C2815C1C2FBD17C7FD2AEF4B580757 +:10C9E000FAF62CF3EB815D309F117A8A837CC67B4B +:10C9F000165F02CC7B5FA2DE9EDE96CAE2613985BD +:10CA0000E9CF3625DF295CBB05F337AD26551F5925 +:10CA100096807F2AF07E3C2F6BF66FF382BEB210B9 +:10CA2000591635F9704BA63EAF255CBB15E1C829F8 +:10CA30006C9CC873050E4E854FD7610C7F597D469F +:10CA40009E4368203ED44764809D6FD8B66B7E5A63 +:10CA50009206CE36CE9B268EC11F5BAE194950730F +:10CA60001E650B3F2CC07CB65C13F03D710DC637C4 +:10CA7000C1FE0B65B80E58C717BF8B76C9463A433F +:10CA80007060CA0CF908CDF94FE2E28747F83F2FF2 +:10CA90002C1FB87FCE45910F495F8EDC370F808DFC +:10CAA000A57EC50EFB6F0498E7BBF3C930F89384ED +:10CAB0000C2E04F9AD9B6FC37CF416D269B1401EF5 +:10CAC00085EF14B579E1BAFE8BF1708E8E2EA90434 +:10CAD000FECD961F96E9F251EA3930B55C7F6403CA +:10CAE000E609B7F45C15A694201A03261A8FD559C7 +:10CAF0003A4F99F3C2EDAD26BF9C01FCFFC347BD81 +:10CB000019F4D5D7004F383FD5306126C47F7F1048 +:10CB10006BD2814E765EB11F6B2C683F5AAC345E8F +:10CB2000033EBD3009ED29ADE6C13EABE32F56E231 +:10CB3000E221F02F6640D73EF4D35B6DBE2B609FA1 +:10CB400080B179EAEFB426A97CB3AD03E4A74B0822 +:10CB5000EB45F09FBA6CAC6CEFDAD6D1C2EC30F397 +:10CB60006F9CDC6EF06F5A157F6968FF75F48FBAA1 +:10CB7000844EE6FF7DDF2C019E5D369F07E2417902 +:10CB8000C76409EC49459A03E7617AC1DC0DFA30C4 +:10CB9000D9E9BF047E0B7132FFE8DD94F3D9200F91 +:10CBA00051E00C733703C7A587639DCBC67F9733CE +:10CBB000FA769484DBD1FE21DCFFBFCF82791EB5EB +:10CBC000FD01935EAED5675E2AA327E813906BF54F +:10CBD000BDE0DF84F26B2601945FB34BBF2FA4CA84 +:10CBE000B3706DB22E4FF9B514B63FA5EA01E15A04 +:10CBF00011D6CB0A9FEE84FDF231C7498A31CE743B +:10CC0000D413B1C72955F40851F2BB3C9E2753E514 +:10CC100024B6BED0E76B23F59FFA54F5DF17143E18 +:10CC20003E6DF5CF4BA5E33C12EC5B68C3DEFE5BCB +:10CC3000617DFEA4F06561EF93C780FD2E8BDE4F12 +:10CC4000A5CC807353DE6FA4A4BC7FB9D990CAE68B +:10CC5000335A8FB1FCC3B68725B4CF5FE53D364F5D +:10CC6000143D5673CDAED35F19296C9C1A5E463DB8 +:10CC700056732D1EEB3F387C2B094E1F0BBE03EB6A +:10CC800047E0F731F8C74B7FDA350BE01F3619CC98 +:10CC90009A786EDBE105699097DC66A57AD9A19355 +:10CCA0005B2FC82D9F4B46E22090F37D23F5F37751 +:10CCB000837FF3AC56CE6781FF15EECFD375DEA729 +:10CCC000C83D9197446F6F8F683FE25F5561FB48A5 +:10CCD0007C543D0265F0B7F83F9B55FC500F3D6911 +:10CCE0008880A7FA637235C2DB3C83F919969407F2 +:10CCF0007F26E703FF05CB200E1A7E9848DD6434BB +:10CD0000DD2D0A1FD65C9BA05BD730BD27EADEFF76 +:10CD100047A38B0435F2F651FFB6856897619D00F5 +:10CD20000E917762BF031924A891BBFFC3E383E28E +:10CD30003127061EF3FECE78E4EAE4328C47BEEEDD +:10CD4000FD07C5C368B9E6BEAC299B4492A12D1767 +:10CD5000872C1997357ECBF453A2AE3C63C0A56BEC +:10CD60003FF39CA4AB9F3D58A8AB9F73C5A32BDF9B +:10CD70003E3C4BD7FE8E6B5E5DB98C2CD2B59F6F5F +:10CD800059AE2B2F10D7EADA4F54F2E477BA36E8CF +:10CD9000DA2D921ED6B5131A92BF03FECB1DD7EF24 +:10CDA000B0407CB1D361A8847D879DBCDF921445DF +:10CDB0003FDEA6C01DB177AE54ECBF400CB4803E40 +:10CDC0005C4043E166EAAFA555FB5AC0EE578A2C9A +:10CDD0008FA8E6CFC9F59515F0FEEE4544EC480C5A +:10CDE00097EFFC14215036677AF1FC9AB5C880E7BA +:10CDF000037617AD1873FF619FE2BFEF89B0F7EAC2 +:10CE000033C1C8CE4946BE2F48637EC29377EC2318 +:10CE1000B04F607104F17B9EA39377BAA0FCF41D20 +:10CE2000DF76419CD13EF9132EE09FB6ACAFE9CE40 +:10CE3000DFD9F2097EDF110977BF0237FFDA631607 +:10CE4000B09FBB33193D23DBA9E7D0775B58DEFCED +:10CE50006F35CFF234263F1FF63C2F2870775B8268 +:10CE600098FFEF28FCDBE05F3D82FFE384E1FB38C5 +:10CE70009E376ECF1224AD9D559FF07D28CCA72DF7 +:10CE800077A70BEC6E7BEE2774FEBF399FEDAB45A9 +:10CE9000F6E35C6CDD768B7FDBF93CF657CF67679A +:10CEA000D4FD754B8C7915A8F3720591CFFE56F31E +:10CEB000FAEC883CFD7DE6F5A2325E7C1AF34F77F2 +:10CEC0004B4C8E128CBE5FE6E5C696BF8459FAF3D2 +:10CED00048711E7D1C9097EF1BF39CD139853EB1A4 +:10CEE000E4758D494E013C5E6B64E769CF021DE934 +:10CEF000F39C7F42397C97F01A9CCBE2A0FF8EB85E +:10CF0000B1D661ADDFA8C3733CFD30258D9DA75C14 +:10CF1000BD46DF6F95CFAE3F17A59C27A0747A0260 +:10CF2000F2CB2ADD46ADF38744A758FC76B374EA0A +:10CF3000287C7F741A8FBFE3D398FD1A8F4E2A1F67 +:10CF4000C582F3FF2B1F95037D6E828F54FEF95B24 +:10CF5000D3E71F8D7FAAFF8F3E63D2E7B19BA48FDB +:10CF6000AA877A055213ED1C48934B40399DC4059E +:10CF7000CE2C8238FB2E239E773873A0A78EE469CF +:10CF8000DB317B7AA6F2AB7578EEAEC68EE7BDDEFE +:10CF90003078FEA504F2528F1831EF1609FF8C424B +:10CFA000BF4DAE44E5BC8E9402F47EA366E598F3D3 +:10CFB00023959A79E1BE9A2D5C3652B84442FACA5A +:10CFC00094BE90173853393D2E9A5D53D72FD6789B +:10CFD00037BB7E6FD434BFAFF51B6F7E2B5D7937C7 +:10CFE000A51FE1C43ACB4BB17301BD8F33FFBDD751 +:10CFF00040D793C2BF0FF2DCB3210E2098FF5BBD78 +:10D0000026ED20E0FB2F2E76FEA25F90EAF01E9028 +:10D01000954B77C3B988B3AB1239486DA8787C4576 +:10D0200059D7D2EAE8FEE7734A7DB83F472645590B +:10D03000E72F2AFECFAA6A0EFD08C27BB3B4F77CA5 +:10D04000FC73447D64FFEFBBE2B1FE6C8CF3975F31 +:10D0500057FAAFAE1ABB3FA94D510E618853B5DFE9 +:10D060009F8FF095220F8B5DFE3E176DFF1AE7FF35 +:10D07000D2C7818F263B90EF094F7261FF7F040E6C +:10D08000EFC5731B97EB18DD23E16AE0BD3416BCD6 +:10D0900058F455E7A58E57427C18DF914A223E315D +:10D0A0001BC737C279B6BBE793008ECF4B884FF2D0 +:10D0B0009B34AECB0DF3C7798358871FCE2870FA07 +:10D0C000FF7BFE1280D37FC620EEC88D8D772CBDEE +:10D0D000F0A6C23F4EA37F079C2F20EBB9A8F27D9C +:10D0E000CE65C576BB5CCC3F24BC3F0BC699B8DF90 +:10D0F0006F9228DC7B94F36784F8B3966BC6DFA548 +:10D10000CC3BB29FD3C8F6C9C9EB4C0FF5763F9222 +:10D11000154D8E5E51FCE65DAE42DD39DF2ADFA3A0 +:10D1200026D003554B979B2407D44B8CEF143C7AA5 +:10D13000057F56B1234CA798FA47A14FFF397F339B +:10D140009CFB59DFC0E139E3A2ED8CFFD66F3F6A4B +:10D15000A8A3CF838A1C2E57E450ED6F4F6772D37C +:10D16000DB6DCB06FC7BB5E730281EF73F43307FF5 +:10D170006748FFE21E99276490234ABEEFC65DB060 +:10D18000EF30A8EC8FE5D0FA26C0B782E1BB7EFB7A +:10D19000728CF72756B278BF5F20781EE8CDDBE3AC +:10D1A000823B0086C57BF4315ABEF4E704D2E10924 +:10D1B000F3C75342682AF0474AB3EFE3BE28EBEDCA +:10D1C00056F0FD8383EDE7C5A28BAACFD5762B78E9 +:10D1D000C914ADFDCA4ABD5E53F14F3687DE2551F5 +:10D1E000F2EA23FC181CDBEEBDAAE8E95722E2A60E +:10D1F000AA73D1E397D274C6C7BDC1F2CD78BE5928 +:10D20000364B789658C1C729AF467ADE5842442833 +:10D21000DF6D96BE0CF8DD53658CD0C34184B37EC0 +:10D22000A95D37AFA7BA7F3A15BE43CACB67FAF7F5 +:10D23000BD42079E0B7F880404D85FAA26F23C9467 +:10D240004B229980BFCF2AF453F13B4BBC71334042 +:10D250005F3444B79FBE742627677DF357A1DD6D09 +:10D2600031E2B9848B55C9CB200F2EFB4C1E38E61A +:10D2700074B16565DC839A7555ED9EEADF9CF3CF4A +:10D280001FD37EADF2E9D7AB57E8C47D40B99C040B +:10D290000E513E9BF4A5CB7B67D2F299A001EF190A +:10D2A000C23F2C67A8E7E0099F4AD75DA91A320C54 +:10D2B000627BF90B6C5EEBAA830B606BECBE673A8A +:10D2C000F7CDA4E587D2993FB0C33EEF7690D75F04 +:10D2D000358C632F23F869E27E9BAE5C7A8E08D092 +:10D2E000DFBF2DBA7DF88F0CBB72AEC8930DEBB0CB +:10D2F0006E7BF476F64C07DB27FC8BB1265AFCBD1F +:10D300003B83C9C9FA1A2EAA3EDF9D11C7EA6BA357 +:10D31000C3BFDBADE22166C3BAAC8F81EF1237B376 +:10D32000676FB5AE5E07FAE08A41AFA7E7BA195F4B +:10D33000B8DD6CFF7BA8FBA5D654E0879D9C08E771 +:10D34000C92E257A2603FF6D68B988F17EA2D2DE48 +:10D3500098E6DB974EDBDF7BEEF913D0BEBF9A7801 +:10D360003829B61DE84A57ED80FA1DB46A0F3BAD67 +:10D37000608FE07F619F15B6FA139260DDE547F09C +:10D380007C4CB74D64DF3D796668FDEB1E45CF0CE4 +:10D39000F5BCBFF5BEAF46EF1745FA7F4382B4B781 +:10D3A000848E3B44F9AD89CE875C7FEA56ADBD5192 +:10D3B000E521D6B837EB070EF5BC3F3F70BC799E30 +:10D3C0004ACFBD293FF0BDCAA7F6954830CFCE5B06 +:10D3D000A3E95B552FBFA1E8C5487E19D1378A3E26 +:10D3E000B9121C1BAF8F3EA3C7675D408F8F2A1FEA +:10D3F0005782CD36B8478B8E3E15D659F54B49C569 +:10D400008C9BBA1F24169E57143C7FD560E451EFC5 +:10D41000F57098A7FE55C353F1D1FCFCC8F90F195C +:10D42000283F007F7C9947FD5350B3E158AA14E68A +:10D43000C7F714F87F2D1FAAFA55B52791FDFF51A4 +:10D44000F94EB567E3F19D33461E7277BA05FB6F5F +:10D45000E04501F69176A74BAC4CC4852EF05F6792 +:10D46000B1F3EFD4EE65C33D1243DD36FCFE4BEE67 +:10D4700030070BE83A5EE99E3359BB8ED3DC8A5EF7 +:10D48000AD4DDC095BD7570C9E4569B07E2BD87D2E +:10D490001E67CF252D4CA3FD9F1A30C08D5864DD2B +:10D4A000B60D4698DF6DEE446697B79F46BFEFFD19 +:10D4B000F2F5FA80DE9E3F9DAE9E3F657EF8DDD49C +:10D4C0002F80F384B1E890E3B660FBFB6A0EA33EC5 +:10D4D0007D603B87FA54724BF8FE013E887A99B41E +:10D4E00030FF9958283DA85EBA0893007A7C8E6375 +:10D4F000E7BC799FA0BD6FE3C13DAB17C0F9CB4836 +:10D50000F9F88EA2C73FEF3628FADCBFC88DF1A12B +:10D510008F0378973EC9F05DBFFD513CA7FC7ABAF6 +:10D52000E25F2BF2F9BAB24EEAFC9295F99DB70D83 +:10D530006F037B41E5C680E74C5E33225E435FFBB1 +:10D540006600DA89531C18EFA31F4BCBBDCBE282D8 +:10D550004D9ABC9DEAD7E479983C54F15E9D5FF802 +:10D56000903B57E7A747FA1BFF670FD8B3C3FDF7F8 +:10D57000B5075DEE0FC71E04D219BF47DA85113912 +:10D58000DEC9E4F8E2B9DF2D8072A41C7F5D91FF53 +:10D59000BF567EAF74DF8B7C2D2F2662812E3ECA54 +:10D5A0000A421C3CC2FFE1388983736E4F75FF6CE1 +:10D5B0002AE4BB2EEE5DBD2EDAF87B33989FB531A1 +:10D5C0005E32E07D90AF313E8BD41391FD46E42274 +:10D5D000469EB16AC56C8C0FCFAE98930DDFBF45E8 +:10D5E000C607A3DA73DE9455101F3729F1F13E7395 +:10D5F0004D77147C93143F352F7FF804D0FBBD5A30 +:10D600000EBF1F863FAD9F7EEF39CF8F06A5D1F8A5 +:10D610008E94D5F8643B1B2F729CCBEE88F844A601 +:10D62000F109A5F36095311ECEB3AAF1C9A0FCE1C2 +:10D63000C6276F92E17F9909EBDC131D2F3E43E172 +:10D640006BC1BF6F36C56368B1D12383BC18683F17 +:10D650004D5C12D9EF9AC2876F6E7F9FFAE89C3EAD +:10D66000AF1C4BDE46F0FA2BE5AD5718CE02B97F62 +:10D67000F3E0F50B8FC17C0EDAF0BEB1483807330A +:10D680008C4A7C60433950ED6FBFD059FF12EDF7E3 +:10D69000E65D6ECF0EA2910B42E582BE3FFF172AD8 +:10D6A000171ED46F28C7BDDDF69A6871CA0F143EE5 +:10D6B0008BCCDB88DDDF08405CEC251E9336EFF475 +:10D6C000BAB2EEAF2A7A292F83D9CF7BAA960B90D4 +:10D6D0002F7A70245F4430B810A7641E84F8F215C6 +:10D6E000E57B0179631CCA5D241EB729741D2F7F59 +:10D6F000B0A65A1FD7DF53A5D71F6F07F346EC48D4 +:10D70000C118FB522AFFC61AEF66ED476FF0FDED18 +:10D710000B8C37BFBA8CDC9BDA17584502B7639E77 +:10D7200083AE0F3CAB4860EA4B149FB79F59897991 +:10D73000F45709A9443FFEFAC7A66AFD927B95F506 +:10D740007EAFEA637701BBBC2E04A646B33F917956 +:10D750009A5783D1CF67F814BDFABAFA5DC53DC6B2 +:10D76000A8EBBB5959DFD7ABC7969BC8BC4DD55268 +:10D77000FDBC3F95212A709A6D7E1657B371BFC0CC +:10D78000C605BBA5F54B3FF521C9EB20E4EF619C35 +:10D79000ED84403EA55790A768CF5FC565323AE457 +:10D7A000158EBD1FF58A4257B55DA49FF513B7A42A +:10D7B0003B3754B5548FD76746FC4111F320436083 +:10D7C0002F9D617B79B7D9F330F001714858FFBCC8 +:10D7D000B2DEF7D6FCD604F3A7FAB315F2A1F2191C +:10D7E0008308FAB3F45CD0A4A5CB6B3719DFBFA6CE +:10D7F000F80BE3E9D1BCC261D46FEF051DF89DC4FD +:10D800009B9FF993291ADCAA6B19BAF3C4EB7DD15B +:10D81000F32AB60CB6DF158BCEB60C49E7A7AEBF20 +:10D82000968DE78363F9FF9FCD6071D07D35075BEF +:10D83000B5FEFF530A9C07547DC633BF3F56FEF525 +:10D84000A71937977F55EDB3DA2E72FDD567A4BDC2 +:10D850001C54E439B2DDBF65DC1CDF8DF83131F8D2 +:10D860002ED6B86AFCA1E67DF38A68FF28FB32A3B6 +:10D87000C651DA458EF3AF197AFE1E1547C4C8DBD0 +:10D880005933991CFB63E4EDAC9971587F8630BB2A +:10D890002807ED68C7AEF43CB00FDCBD87167DFCF1 +:10D8A0002498B78F2AF99AEA9AD327204E55E38A0B +:10D8B000B03FEE6F867DB2A11D1CFA1B91E344FAC6 +:10D8C000E51F853D269047257F5068F4629E9A7C2F +:10D8D0009A9DF37736AC46FF52CD4FF70ABE1D71C5 +:10D8E000F4FDC4EDBFDD06F6558DE32F993C0FB373 +:10D8F0003C33F377CF773BF07BD7DA1179F760BE13 +:10D900007144FE95FCE378EB31A26F62ACC778FA04 +:10D9100026565E447D8EECB308E28C97E17C2A1794 +:10D92000EF817B99979B09E67D962FE130CE5C6E67 +:10D93000F6E27ED6E9330603947317E7EE067F63BB +:10D94000C552A3D74A51F83700359BAAF257AA0B04 +:10D9500000CE5374C210C7F6BF21BE07CF5717C4FD +:10D9600049E0FF9F9E27353969F9F4624EDC41FB9F +:10D97000BDBCF401E3545A7E8586CF70EF8CBD8127 +:10D9800028DF7FDCB26C7E3E21DF00B89AEF3F5E7D +:10D99000216AFD3DFB2A281F4D49E937382849BF38 +:10D9A00075E09E7D160ABFB5C9E782EFF2EECFBCE7 +:10D9B000751F7C0F999AEA1DB883FA519D999E654F +:10D9C000F09D5EFF175478C5FBE03BBC1F18FCB907 +:10D9D0001CAD7F2173D1321EF62326A8F0ABB17E99 +:10D9E000D5C2750FF6D3FA0B07EA97C119F6D26ABA +:10D9F000A5BFFCB165F3794AEFB96AFB8678283B8D +:10DA0000ED24BCCF348B1053F83B3F3CF7DE3F7224 +:10DA10008E7CFBB20ADAF7D5B2C07CF89ED3F3A5B0 +:10DA20001DFB8AAC84CCAC2C13BD743EA5595F5849 +:10DA300066877521941F69FD47B20E2C83F9388DD6 +:10DA40000605FE9710BFD26A790AD47372705F65BB +:10DA5000227C97307812D8724B43A72555F77D4228 +:10DA6000C00BAE8970A42C9481E828FBDA99A1A997 +:10DA7000ECBB3BA55CC8F2142365172BF7EF88FEBF +:10DA80007DC57F6531FDD56F8B5EDF91A9DFDF4EF0 +:10DA90003847BCCF4591FF8F29797F559E4E403E38 +:10DAA000C48957CC059A601FD6C2F08CB58FDBAE07 +:10DAB000E897FCA604BC976869C08EF7E84CF03084 +:10DAC0007D43A5885F09FADF68403C538C1CDE6B00 +:10DAD000926A23FEC3F49992CCEE39594AE517EEC7 +:10DAE0001F5930C1D783E77CD3D28B9BE19C5DD398 +:10DAF0002F79F0C3D4FEA3F1141F053C538C2B8A5D +:10DB00001F2DD2D0AF88E14DD75DE9E7FDE61D209E +:10DB1000170353F2C0AFBE3D536FEF4A07CA4DB073 +:10DB20003FF9AB2C250F26B1FE29F3995E197E54DF +:10DB3000B9B7C2E229D6E5F5153ACF6F5BFA34B42E +:10DB4000AB1D3011388FB8ED7099EE7EF5C8672D9A +:10DB50009C7BD7D8ED5A3E84E7CD6BE1DCFB74802B +:10DB6000F77301CE39021C880FE0FB0EF09B529A2E +:10DB7000A3AFB79A57AEBD9648E4E9DAF78C5E6179 +:10DB8000F84EAC1F6F5E6178FAEFF946C353BEEBF7 +:10DB900053E9CE2B7417A2E3F933952F29BDB5BFF6 +:10DBA000AB52554D94F313EC1EDFF3CB8ABAB5F7A5 +:10DBB0001610B2839DEBE0E93A823F3960C3FB80E7 +:10DBC0004B79AA1F9D002F4994B9D17CA1AE6B7FE0 +:10DBD0005200EF231ABE8B13BBA3F8D967143E2E55 +:10DBE0005DCAF836ADDA6FDCA0E17795FFC3F007C8 +:10DBF0003EA3CAC73A94DBBD0C3FF037800F3DA16E +:10DC0000A9DA73202AFE659904E74FD791D1FF2E38 +:10DC100047B09B0BD36D34FD33C659CF6CAC2F1D71 +:10DC2000382600BFD5C690D3B359F1386EDAB95053 +:10DC30003C9C0F58A0F07F7FDF74EB1C908BA506F7 +:10DC4000C2496CDEE06796CE55F5E73BBF28A7F6E4 +:10DC5000206DA44CF5AB04EB30A26F43164BB8FD1E +:10DC6000C9AC7796B5803E36B3EFBCA9FF68219A60 +:10DC7000EF11B92C96BF9DE58FBE6FFD4616F34799 +:10DC8000547A7FBE613E798BCEEFAE4C66BF670D96 +:10DC9000CA785F922AD7917A29278BAD634616E31B +:10DCA000B3BFBD5EE2C6D14BCB15BDC4EA89D35725 +:10DCB0000BF5A906E5FB0491ADFBC69F4C2F803CFC +:10DCC000DC56975182EF1D56729EAC6FD171AA2C13 +:10DCD000526B9C14E68F2A62911C406F3A027CFFC3 +:10DCE000BA62A915CBF0077EC7EF3A39C67F444A1E +:10DCF000A81AC3AF55F1D9EA1270BC8DBB0A12FC49 +:10DD00005A3C79DF7398DFB32B785A22EC15AF2F8A +:10DD1000A7A686EA0C464DBD83D9AF1697774E1657 +:10DD20002D9F56F242A43659E717AD52E42ED22F5A +:10DD3000FAAD8B287A6205C68F69347E847B02D265 +:10DD4000FA7C781E0C2E322AC0EF76D97DC6970E4B +:10DD500093B91027A9707C59453AFD5EBD1A364D1E +:10DD6000A8705AE67B2F6BF4D929E53E7ACA0F33A7 +:10DD7000405E9767117D3FA32F13BE2F2769660F63 +:10DD8000E89B1382EF00AEAF4812617D17181F3D6C +:10DD9000807C612489CD784EEA20F6AFAC1E2E41FE +:10DDA0003FF5BA310476E797D9E998CF49B133BE48 +:10DDB0003D610D603F9E4849A84714BDF7CBECC9B3 +:10DDC000780F86AA3FC3DFB5A87058FD096E792683 +:10DDD000DC0B7B2265527133A7F777C0FF09FB4B41 +:10DDE000DFDF77673EF8377D218A33D52A2F2E7BF8 +:10DDF0008CB6DF9C25317ECDF5F5C3B82712890896 +:10DE0000F8CF1AF43F07E5452E3BDEDBA6AE47AA66 +:10DE100081FD1E4CAAF27B2B2027F0B4653339EB31 +:10DE2000529E83D96C3D53E3A3FF7ECCB0D26EBF2C +:10DE30008DD1B9A34C7F7F92FADCA9C8719DA5B39F +:10DE4000123EA9D77CEF89DF87F384FA551C7C4FFB +:10DE500042F03DB56748AFF96DD5F8FB61EF0DAC09 +:10DE6000C27B5C477ED703EEABA2EB1E222B9F004A +:10DE7000BA0BAF1AF16EBD56133B772724FA45F85B +:10DE80001E29D91E3DDEFD96824FB291DDCFAD7EBB +:10DE9000C76052BEEBFF8AE28FC5BBAAD83D45944E +:10DEA0008612A55F0219C6EF74D5758C3C976B522C +:10DEB000BEE77FFFFE43710CFFA144E73FA8E346A6 +:10DEC000FA1117E0FE6D4DBE7B9DEBEC02A2697F5F +:10DED0003F196C0578F76FCBD0E52562F91FC715A0 +:10DEE0007D0BFE821C152F41F7FE028D0365EDF8B8 +:10DEF00057D8F8E171ED44D68CDB96E57D390BFD02 +:10DF0000D4B922DE234C7D76380F4BED0EB3D77398 +:10DF1000D9FD84D42E5582FE56E322907B3101E454 +:10DF2000BAECE759291A3BA9F48BD447772AFAE8C7 +:10DF30004EC5DE249C53FD469BC47161BB33DA6E33 +:10DF4000718A1F1DA91F23ED82DEAFA67C2B6BFDFE +:10DF50008051F292F541FDCB0931F863E2DFC5BF94 +:10DF60002C9DEBC7F892547204F6416656E8ED3DDD +:10DF70009FEDC079F1D9769DBD5F51AD6F6751DAE4 +:10DF8000599476E3D1536B8F3823E83D06AF9E63F7 +:10DF9000FC90FBCE19BC4FA9229BF943B7E4781340 +:10DFA000B269FB837F9EDF0BBF3B31DCC4936E27DE +:10DFB000F4F3F60E3A615E1611E2D4B2B515850798 +:10DFC00069BDE9E7260FC4CBE448F4F8DED1C07997 +:10DFD000375196CA54F460AD93CDABD61912F229DD +:10DFE0001EEE5A864F66DF518ED7E8BDCC1AD66E2C +:10DFF00062B649677FA628E5C26C252E21C126F8A6 +:10E00000FD93CC1A2F0FF6CEDDC711E59E4DBC1F38 +:10E01000D5ED61F01D9E20F7405178DEED86E54597 +:10E02000602FDA53ED1EB0175B72FC9E6C90D7F335 +:10E03000A110906DE6F9011EFCBE5D39DE62A0877D +:10E040003A3FC928BA617FDC7E9EE1D719C1FF84BF +:10E05000EC56D6A59BE1E7F015033EA9F112DE4789 +:10E0600044FFF2C0AEA62629762395F8E1DE2062B1 +:10E07000A1EDC00FB2D176DAEF3789AF04F609828D +:10E080002953A7819D5B60F31CB3807D9D963B0D5A +:10E09000EE177AE940F47CFA32C5AE50FC1769F10C +:10E0A0008F251F23F7AB2BED4C31E26895EFED95F3 +:10E0B000D1FD556A09985FBFD6792FCCA7B6452008 +:10E0C000708F844AF75D39BE6AC0C7DD77900379E7 +:10E0D00075F795215FB9659E805FD162CB0EC2BD99 +:10E0E000B12D491F4903FAC7C2BBB6C1E8DDA495EB +:10E0F000E71601D7E360C4F93535CEF87836F3B3C7 +:10E100004339BE5A58E7FA234FE239C1877B2E0ABA +:10E1100063DDEF73B374E36A58FC52BB86DD9B5139 +:10E12000B696473EDCDC22E0BDACB5CF1D0EE17EED +:10E13000F17682FBA0B57D874FC2BDAC19B5DE1963 +:10E14000DADF21C8A865F7C7A5521E192842BD29E4 +:10E1500080DD76F72DAF45BE168948908FFCE877B5 +:10E16000655A983FAAD2F7A410CA7E99B63B692097 +:10E170009E665A7FD52417C24F345DCDB579E01E17 +:10E18000867F3EFCBAF469A033E4C55CB01EFE276E +:10E19000811E1D4DEC3C79C702EAF7D0760BEC648A +:10E1A0002B9417343B08C8C7CDD26166045FCCDC22 +:10E1B000CEE4E4B8A25FE81FDEABF4CD6C16D7A4C2 +:10E1C0001AFCD5E8BFD279B4CD46BC701EB66C6FD0 +:10E1D00010F02262128EEBAE0D71DAEF50D4679818 +:10E1E000AFBC5FCB4E793F78F6E13EE36645CF9416 +:10E1F000ADEDE1DED2F0C1F7B2D97EA9FBB9831C47 +:10E20000C487B4BE698113DB637ED0FD1C8B9B3653 +:10E21000D3FA07757A6503CEA7DDC6FC47AA577EF9 +:10E2200008FC7EC2F0E871D82F39318DE07DB377DC +:10E230009D0F9D44F5ACE07B4260EBC9533A34D16D +:10E24000F2A96CE6DF9D14FC9B60DD4FBAD977DE46 +:10E25000ED861D78EFA92AF791727A4AE173F79A51 +:10E260001ECE50847940F42755FCD476B7E494FF51 +:10E270003C1BE9308074A85BC3B37C8382CF02C1AE +:10E28000970F71DA1B0ABC63ABBF6D7C86E25757F0 +:10E29000C4213FEF7FE134F2655D27C77E27A8F3F5 +:10E2A000B4B04A135F757DEF34DA9525FD6CFFA598 +:10E2B000AEFF30FF8003ECCD31E4CF3ACA7FD612F7 +:10E2C000583709E97CD514CA067B19C99FF64AA6B6 +:10E2D0001721E75AC0EE83C3FDDFE05A0BFAFDAA0F +:10E2E000FEB5652BBF5BE9F0E7827E7D5729ABF079 +:10E2F000C3F1AAD503FC9DFBCEB46370BF5B9D87C1 +:10E30000F3C079E4E1117BC2F4B544D915F4B50A40 +:10E310003F927EAE1C66CFA2D891FF8A6647543BDF +:10E320009BFBE572FCDD3775FD7885EE23F63D87B6 +:10E33000ED4B597278051FAF0BF2D81295E78E128C +:10E34000B8DFCF57043FA1D69262F7407EE79F1314 +:10E350005F933668E87552A0F24ECB27F36C880FB6 +:10E36000950B6B8E66FD6A8BD8EF4AEDFFEE72A4BB +:10E370006B2DAC1DA56BAD7FD326A4B38B888740D6 +:10E38000BFF899FEAA5D730FBB075CB57FCF7348DA +:10E39000FF5AD981F75A2FE95B8EFC499C564F01F1 +:10E3A000877A0DD7599533DB085DD9FD4334AE6FBD +:10E3B000827C891AD7C757FBE43869B49C262B7135 +:10E3C000FD0C25AE37CDB27CA871FDE6869F61FCC1 +:10E3D000F388EB27F854E584C68D3A799AA1ACB35B +:10E3E0003B87D9D3B9394C2E3797F421FF6FBE1C28 +:10E3F00040F97154323DE238AFD77F6A1E8C903DB0 +:10E400008C0FED7D0B611F62C1573811F4402CBC9D +:10E410003FCA057E01E755C861768EE28EEBBF8C60 +:10E42000D7DE47BA3487F1F7D55E230901BDF980FD +:10E430003096FF1B0B5E56A862F6BFD3F5FB756FD7 +:10E44000029E0BBAFADCCA4F4259EE49C0732459F6 +:10E45000A12AE48BABCED91EE0036733A3D3D5BE8C +:10E46000F9C83FEFA44906B82FACA9EFA979F0FB92 +:10E47000D01B15BCDEF9AEB101E8B0E3EBDF9907C4 +:10E48000F74B6E0E72C9F0BDD9D5DEAFFC05EC5E60 +:10E490004DCF163CF7D5FCCD7F42BFDB103CC8DE2C +:10E4A000F72688D06EE8AB4FCE03FA36F73563FD1A +:10E4B0003B5F3D88E5635FFF8EF19992301FBFF3AC +:10E4C000DD833FFE6F28FBE2F1BB9C5AFFFEC7A134 +:10E4D0004CAAE2D97757FE9705EDEF75751D3E8A78 +:10E4E00072A8F2C5923E4EB93F4CC0731E2AFF5E21 +:10E4F0002A2F2A05B9831B768DF368B923AE265AD5 +:10E500001E71A732DF5AE04518770D1704396817D6 +:10E51000E45ED4E7625F36E8737B5148807B5756F0 +:10E52000571F9EC77E76B009EB575AD879B1A954C8 +:10E530005EE01E290AADE706F56B56B63FBC0EE05D +:10E540001D3012D1981EC6B75E90303EAA5FC179C9 +:10E55000A884118E6C3B9102FB5F0D4439D7C5DA5C +:10E56000B5D3F0D29284768858E9B3745BF43CE872 +:10E57000BE1C87229F4C5EDDFDCB33417F10A7D9A7 +:10E5800053901B8697752ED001D7F9BB6B0616C228 +:10E590003C16176E980EF37042BE0FEC8BEC40F8F1 +:10E5A00075909FA4F21454E42655F4E17D2316AF30 +:10E5B0002F057E834D32FB703F4F5AEF3335819EDE +:10E5C000E187B357A1213CA4CB7B7599FCE93300CB +:10E5D0005EBB629F7A18FEB43FC293E67B9DD09FDC +:10E5E000C24778966A2F8FBFF16661EBF09F3FBA02 +:10E5F000F3903E5F1E1C05BFC401F6455E83EB260B +:10E600000938DF77A029D25BBE559BC78ECCF78037 +:10E610003E83FDDE504ED90F7266849F6A1E28929B +:10E62000CE7F817AD01F92179FA437F9A67E0F5014 +:10E63000D5DBF57B14BBFB838BA877EAFD3CB3BB32 +:10E64000FECB68777FDDE8256F51C7B2EBC58BC87D +:10E65000DF0F1C6176B7FE48B100FCACDE8B5C5F5F +:10E660007E15EDAF6C24C8D7F542DF4917C0EF2007 +:10E6700089D4B327F5F3062782FEFBCD8BD635D0A0 +:10E68000FF84C180FC76A2FB9683CD9C163F1607C3 +:10E6900070354194C77AC52F285BBBE94988C7EA22 +:10E6A0006A08C685F5FD8A7CD1780CE85B7FE43486 +:10E6B000F28FEAF7E67E7905F25B22E537FC9D846E +:10E6C0008A01C48FFE790AE833B182DD8FBBB8B00E +:10E6D000B814F8EDD8EA1FEF04BB5D5F414480DF5A +:10E6E00095E57D11EF017E91C37B29BB4C9DE5F043 +:10E6F0009D64D7024904F9A8F7578DD8273C5FEDF0 +:10E70000AFEA47F971AEF380FFD0D1E447BFBA2337 +:10E71000DD8E7E41D78B4D683FEB259B077EBF6426 +:10E72000C9116E2BF6971D84E1CFA19FBF24380736 +:10E73000CF6DA9F458523198CDF405C3FB37A681AB +:10E74000FB61DEBFF99E19EEFE1EE1BFC48AC00167 +:10E75000B8AF768938CD03F76B26F1037EF077A842 +:10E7600009F634C1FEB0C967F640DCBD97C37DA889 +:10E77000FF076B233BDE0080000000001F8B0800BA +:10E7800000000000000BDD7D0B7854D5D5E83E730A +:10E79000CE3C924C26274F1208F14C123040124EBC +:10E7A00020BC114F88416CA90ECA2354C4E11D201E +:10E7B000242362C55F6F33381023BFD71BAB156AA4 +:10E7C000A91DF0516A45A38D354AE01F10107BD575 +:10E7D000466B11FDD18E4A798964E451E957AA77D5 +:10E7E000ADB5CF49E64C263C5A7B3FBF1F3FD9EC25 +:10E7F000B3DF6BAFF75E7B4FEA64A6058B192B780E +:10E8000040D0824EC6EC8AC05826A6163DB5313699 +:10E8100082C19F669ECAFE524F09635F3468ECB3A3 +:10E82000018CFE28598C2DA37F30B67C41C8A640B0 +:10E830007FB5CFF2FE32EC5AD9ED907E837FAE8663 +:10E840007C25BBD503E599A270EB544A2D941AE5BB +:10E85000465AACCFC3FDF8BC87AA3218FB5E0D53F5 +:10E86000136088BE45F01DF2CCC78203DC90AFF187 +:10E87000E42A589EB15815219F99CE7E88E591D5FE +:10E8800036B659E8D9AF8AEB1A81F53CE502D4CB0C +:10E89000EC93AC067028B1C29280EDCA0475B382C5 +:10E8A000F91B9F64E590CFCC51B11FC6823A1C3C46 +:10E8B000E516A877342B595D87DF837F906E047847 +:10E8C0008C5764A3BC0CDB292EC6D69575B7AB2A32 +:10E8D000F0507F557D12D400CC734AB3BF94E573DA +:10E8E00038789CDD7008AE4EAC0E46C16324C20180 +:10E8F000DA0707B1EA966284BFA716FBC9B2A8E996 +:10E90000EB5221EFF497DE948CE304085E57E03C71 +:10E9100020AD82F5F9B0DF02CF4A824766B21A0F06 +:10E920001EA12B383C76CD7C4EDC00F5EA8A85A012 +:10E930001DE6F7C8B6A965B8CEBA694E9541BECEF8 +:10E940002BCDC37199DFC19E823CF32E78A80AF2C9 +:10E9500075351E759D42EB5E80E5B91909EA3A28C6 +:10E960007FF41541C37C9DDF194C80FCF7DB383EFA +:10E97000D4B5BD20CD873409F1CE89EDFCA5534B2C +:10E98000BAE7C3D86A9A4FDDC41379BBA1BD5F64EF +:10E99000AA3801F2B6F04015D65F37213C10E17578 +:10E9A000F295846A6CBFC762F1E3387B360FD914E5 +:10E9B000107AF673D2EA69C5F59F84F5FBA1FCF5E0 +:10E9C00057DE0FDE0DF935800A6236ECD16AA502FA +:10E9D000CBD7553119F7C5D8AFBD367F11E2D5DE9B +:10E9E000FC44C20F9CA707E07C1CFF99C358FD158F +:10E9F0009E250ACED3126A94B0DD9674C6C640FE38 +:10EA0000D5FB077A9D3DE10CED695F1C1223FC7577 +:10EA10000493828128BC7238184B1E46A9DF09690D +:10EA2000D22A0E9FD87EEE519C547FB923BC177614 +:10EA30008ED5AF6A7664011E2D4854E87B82D5A737 +:10EA4000F583F9D8DA2A42FDA03C2B0DFEC27DDB0E +:10EA50009C14C47DCBCA62DE17E3F45BA7D39BB1E1 +:10EA60002FCD698CF032CBC5EBFF4CA79B07F47A16 +:10EA70009BF5348A2ECC78EFF4BA914F6425326F2F +:10EA80004B9CF18CF6303F2A37E6C51CD04F06B6BA +:10EA9000532C84DF317417CC2C1986745795A8EE4B +:10EAA00072203D0D730F0BB0EE710031DD53937B7F +:10EAB000E201AE03E907D78574D65BBDE69D9C3FB6 +:10EAC000C5E2E5B33A9D2C425C87793F27003DC6FD +:10EAD000DD67DE4F93C56D7914E6FB9FFBC5E066ED +:10EAE00077CF7A46FA6003D0A09DB1FC8DB3523C3B +:10EAF00025BDD7DB89F5AE84711B1C54DFA92AAB79 +:10EB000025E87FA2C35D26321C4F9988E3F9613C5A +:10EB1000DCE7E409EC4B11E053DAD65C74AF1BF18F +:10EB2000BCA51AD7355192A532E40B1E0B0B1571FB +:10EB3000FEFD0DFCDFA73A91851CDDF91C6F9A29BB +:10EB4000DFAFA6AFA97E7F5FBEA9FC8A55834DE5E6 +:10EB50006EFF3053BEA069ACA9FE80E689A6FC9585 +:10EB60001BBE67AA3F2878A3293F64CB0F4DF54B06 +:10EB70005AE699CA53BE2ED8F533C4735C7F1C3E47 +:10EB800067A4C71537EDCF444934F537B4CDBC7E03 +:10EB900089852D48EF29138E0E8B47CF465ACAA47C +:10EBA0003361A31DF20187627914E6E17A5F0CAE4E +:10EBB0008BB3EF063E1BF994D1E67D30F8C4C5F067 +:10EBC0002BDF7B617C31F0AAB7F294AFC5B87499A2 +:10EBD000E8E67429310FE3EBAF562FB47E6BECFA05 +:10EBE000994278FFAFAE3FDF3BA82D0CFD9CAD16E0 +:10EBF00048BEBC8745637AF6F751CC3A67AC4C21E6 +:10EC00007D86796E8A5BBF7B1EF7D23C6EB1335F27 +:10EC10003C384C7273B93BCFCDE9FD62F4F9893EC3 +:10EC20008F3F1BF4B9C64DF4C8DE138303A0AB7944 +:10EC30004DC2CE3E8017695EA72AAA909742AC2C9F +:10EC40004ACE3FA2D3F7A3D81ED20D0D32F5F3580A +:10EC50004336A51B1B14FAFE784311A5C10695BEC9 +:10EC60006F6E184DE993A08F61FA74C3644AB7348C +:10EC700078A8DE330DD5943EDBE0A5EFC6FEDCA21E +:10EC8000EF0FF3A4933C8B5DCF9C9566FA30F6852D +:10EC900089C5D47E0ED0997801BED6A3BD383BE598 +:10ECA0004278B4EAA0FBF9DD517830DD9D9C7178A3 +:10ECB00008FC63141BF58D78F1F65F3528CFEFB6AD +:10ECC0005E9C2E0C7C61E73F1B10AFDE2D49503659 +:10ECD00016F893FB97CD7E67EFF0E9C6A3187CF595 +:10ECE00000BEC2D75294ED39581EEE1B3DCE9FF4A4 +:10ECF0007D36F2D3A6717C8DEDF7419D0EA7237E64 +:10ED000042F98C187AFD422FFFC2CDF5F4FDBDF01B +:10ED10008B46B745979F7CDFA7033EA2FCBC3769B3 +:10ED2000CE55DE38E3FEDDAD98E873C634F33EEE33 +:10ED3000B772FEB6FF4F6270759CFDBF587B633D96 +:10ED4000B1EDFEA0AFE773C4C911FF73E86DFFAC6E +:10ED500064D2E7F75BBDFD33A3F667FFACA4EA78A6 +:10ED6000FB7EC66DE57456243394EF2C8D69A8079D +:10ED7000C192FC36D4E558A17C18E9048C21A48BFF +:10ED8000DEF15262870D7A12119E09A48F9F9D9623 +:10ED90004CFBCFBCB2C6A2FA67924C7AE9733F0033 +:10EDA0005D01C793603CD043996AE9DEBF7CFC3BC0 +:10EDB000B19B5F8BBDD3DBC5F0C0E02333908F5C8C +:10EDC000405EF76C77797CE4E37F131F31E8989D10 +:10EDD0009F3FC093DCB37C3AF291BE8C3DECDE4F9A +:10EDE0007CE49F869341B7EF73BA8DE527BDB66B80 +:10EDF000CBB888FCD3F9B9E46B0A035EDC2926376B +:10EE0000AF8326F749BE5F62DEEF97D85390DA579B +:10EE10009DEE7B6838755B2451BDC164DFD925DF69 +:10EE2000AFC2640FDA65ACB73EE9C7CF637E157039 +:10EE30004C3BA45F25E40519D80243F2397F121D2B +:10EE4000E7FA1E8A9A9F5566FDA2F3652147BF43E4 +:10EE500051FB367C9F6CCA8FE8C836D51F75403190 +:10EE6000958F091799CAC71D554DF9AB22A34DF5CA +:10EE7000AF3EA799F215EC3A53FD4AC75453BE4A28 +:10EE80009E65AA7F6DF65C53F975CA1253F9D84294 +:10EE90004F493EEA0F36679390C2D812B7569A0F81 +:10EEA00070484CACF3CD453B69B54B6613B076303A +:10EEB00088706BB439E475C0A73E15B43C0678FA87 +:10EEC000B005ACEE02A82F8619A6072D6A19A6F97F +:10EED000DA162FD269E9A04405F1217120631D28BB +:10EEE000A7243581013FB12585DF2D44BADE06FB1D +:10EEF00007A8559A0A8A3EDA013F480BA2FD9B9368 +:10EF0000E8ADC479ADB334BB56E33E5B98E729ACBA +:10EF1000CFD4FB47437AF87A8B05F7B7B5C3F9C06E +:10EF200058C80F85EE19A59FFDE4FBB8DF1DA28A26 +:10EF30006E9F87A7BC3809BFAFBC8E896259EF7836 +:10EF4000F6F98FB83D15FB7D7D3ED7AF322BB99DCD +:10EF5000195B7E875EFEB92D7EF9C27C2E2F2AEFCB +:10EF60009BB21ED767EDB032F45BACCCD4FAB00BD9 +:10EF7000E9ABE70A587078545EF230D989DF07D2DE +:10EF8000F7CAFB66B3B093F7837EAC95095A1FF4BA +:10EF90003B7C3E31FE3C96EBF3B49E4BEAA55F17FB +:10EFA0007DFF3CFFC2EBB49E4B60C1F478ED9DF455 +:10EFB0003D3310BF7DA301A7B4F8E5F7EA70B29E18 +:10EFC000CB61FEF4E8769CEF748F934BE5D673A982 +:10EFD000CC1F771D19F49D656BD988373B81CE9185 +:10EFE0005F54A466D91890F81C16D9A301FCA7A2F7 +:10EFF000490078CA1C6A19F22926592361832E40D8 +:10F000007ECC65D2A7682F580019BF81A9DDBACA86 +:10F01000FA69388A8EA66AE63CC3FA51F2E630F6FF +:10F020000DF34E1C5C9482F87E8A2929721CFC32F6 +:10F03000D2D90ED12345ADE7602F7AD2EF75381DB6 +:10F04000CC890FC7DFE6733D6AE46C16575FFB7D22 +:10F05000BE8BEB81456A9F0BC90D84AF373DBADF8C +:10F06000D87DC8A0F24B8533E005C9F5C80F9C4197 +:10F07000F2537EEBF036F0A79F092F0E1728FC7B8A +:10F08000D7BCF3A83C2FD7F3663EC9156520CAC587 +:10F09000569D7E5B252D699813F918AB8907FF8C67 +:10F0A000025D4F8D59772BD3B2E7A25F43B2AA4FCF +:10F0B00031E487CCF7421CF8C7AEDBA1CF1BDA578F +:10F0C00087B03D73A99CCF318F230BF47CFC172CA8 +:10F0D000A1C2FF8E15FB9FED73A9EB40053AA9CBAA +:10F0E000ABB92C6C453EDC037ECE0C2BFA6D63E194 +:10F0F000E861CA1CA1E0E2F0B438E4ACADB0BE39BE +:10F100007E1743FFCCADB399AB04E6E1FD41DADBFA +:10F110001AD49977FDE0D235980E19DF2852AB6BDF +:10F1200048DF13FCFDC46F865CBABED7E8F2162137 +:10F130005D1C129445B47E01D68F72A6EFF18173E7 +:10F14000A3E0B7B87FC5DE02F47B5999968E7EE2C4 +:10F15000ED76F257B10D8CF4CFFA1D8336A19CE900 +:10F160002CF0EEC67AA3AED1FDB65A64E08DC997F5 +:10F170000F27F86345FAB8189CCEE7733A3FE88A40 +:10F180008F2FE5057C9F2E954E320A381C22008772 +:10F19000CDE5DF3E9D00FC4C7C63B78E7F466AC0A8 +:10F1A0006DD464B35F77B7BE8EDD059C7F7416782F +:10F1B00008CE9DFDBF3C9C8072DF06EB8F83EFD7AE +:10F1C0005DE6FA7BA3936F8B1F1F4C8C3FCF39DF1B +:10F1D0009179BE6ECCB334FE3C6FBFCC79C2FE2CAD +:10F1E00072147CFBF3EC2CD05E2F403994167F9E7A +:10F1F0003FB9CC7902935B14827A3380FF61BD6F93 +:10F200007BBECC3FB70AE5CF4D5EEEF72F014E8BAC +:10F210007C08A6F2E437C351AF55D76E40BEB3C2E7 +:10F22000A5FA65E223AF237E031F641ACC67DA6474 +:10F2300081FC489D23BE5C2421BE67B1502AF2ABFD +:10F240001D76F263C7AEFF67BA9C003AF925C28902 +:10F250004D890C447E7270607C3EF1CBD8FA4D1122 +:10F26000924BEB2AE2EBA5BFD2E975B9A37972966E +:10F2700025FA5C0516282297F569FD50CE96CB6BD2 +:10F28000909FD8401E215C6DFD06F7C1FD80BC47F4 +:10F2900080B422FBCD03828BE07DA20B7EF9DDE3FF +:10F2A0001C6FD827175A7BE7E7CBC41747FAE2ACA5 +:10F2B000E7578AF7D582287B71D99637E4C268BFB1 +:10F2C000380B5B18098E08F9AFBBFC057DD865F9D2 +:10F2D0000B0622AE64A27CF0907C40B9817673E389 +:10F2E000AB63CA707341EF6022F2D3E4449217819A +:10F2F000BE638B9428781EECD21BC45EF4499BE954 +:10F30000FB470D0E3025BBF3B71C7DAF0AF5F8396E +:10F310002CBC16EBCF599984478F5DEBECEAEF9C40 +:10F3200060D26BBBFB97E87B85C31912C188A970BB +:10F33000FE3EEE7EFC4AD13EC1F5FDB8BFF629A6E1 +:10F34000B1F0F3DF373E95FC0708BFAB7BEE7B6F78 +:10F35000FB7C5AD14E607FADFD65C39FA3D2395C63 +:10F36000A2712E2CC9871DDDF0BED47D7910FF015E +:10F37000767D52A1760EFBD758AD0FE733DBA0EFB9 +:10F3800018FD868D4E233F64A3AB63EDCE283ABCB7 +:10F39000D512C9E4723BBC169D4B7FDE9E40FCA398 +:10F3A00073FBEBFDBD748E66E81D49E23749973E5D +:10F3B0003FC3AF604D8CAF471BE717BBACC585A4FF +:10F3C00097E0F9EE68C80BCA02B4272599A90198FD +:10F3D0006FC5B5804DD0DF4431B73D0CEB38CB4E17 +:10F3E000A45D85E0D3FDAA2BDF199180F39C2859F9 +:10F3F0008F47F3A758FF4F5EA1D9FF738ACD4E09FF +:10F40000215C8AB87FA4F4956B52D00FFAF09489EE +:10F410007D30DDD9D0244BD66E3F50ECFC2B7AB139 +:10F42000478714727CEF48D48614C2FA2A7A59BFEF +:10F43000AAD73B94A8A98599DDFD61FD7871106F6D +:10F440005CA9F37B1DAE37F9E792BE6571005F459D +:10F45000FE097AAB28A37FB0D04AF4AE3145CE2264 +:10F460007F21DF7FE0EB12E4AFD2F342D307016CE0 +:10F47000B7F176179D7F33AFC2503E0060E83CA0E5 +:10F4800051F091BFC181F11E90AE13D40D22A4A200 +:10F490002592CEE922C8E3199857C2FCEB42388086 +:10F4A000F1016B1C3FFE25FABFB580C41226405EF9 +:10F4B00062E45FF41F4CA6F3389A19CCC36ECC4BB0 +:10F4C000CF27EBF9CEE993260F80F4CEC4C75D8831 +:10F4D000A76101F828F4F355E28F434437BE44D5C1 +:10F4E000DA17FD4A1F535E5891A80AD9E8777215BA +:10F4F000A19EBA8A25AA7618477396F8715C9BC2BA +:10F50000C80F9FC85A681D4EE7177E048ACC640155 +:10F51000F33989DEF98564A7303A1F3FFC71F26642 +:10F520005C7F827C2A74377C4A671AD54B8F918F17 +:10F5300099CE9502C56D78A418B9E81510FE7DAA7C +:10F5400063BF9BE5A5831D94111F859027FB1BE0DE +:10F550004F1D08B7F26EB87548DC9E33E0E69FE8B1 +:10F56000FB15C2D57FAF5D0E64F4EE6703008D42DC +:10F570007DBC435EB415EB83C1C42CD85F365F9F5E +:10F58000BFC6CEF741F26EC5F61F5AB365B4770C0D +:10F590003C6B1EA8FB217AF1733C58C8F1B02EEDEC +:10F5A000701DCA3906835AF2C05E4A3E3A12F90605 +:10F5B000C8CB26949709568DE06DC8CDE5ADB7311F +:10F5C000A4ABBAB6B90CE9F543C13B6037D9238C7B +:10F5D000ECB19993FD7B2C0AFAB0A6AD75427AB8CE +:10F5E000309F9F67EC99B487D890E82CC176655717 +:10F5F0007BAA3261DC400953EF857A8104EFD6970C +:10F60000705DEF882AFAB9EA5755B2CF86EBC80485 +:10F61000DF37CD48277F694665A411E30422F7331D +:10F6200019E37A7AD0C77958DF48C69EA0B1A09F67 +:10F63000057208F12707F04D90BBCB9FC4F2029EE4 +:10F64000BF1AF2F57C4B59417BC50D23B85F8CA1E5 +:10F650005FACBE5D207F5BC1B4E1A4D71462794684 +:10F660007479EAB267215F587D958AE4A458BCBFDB +:10F67000B803CBDF66B40EA6F3EF5131F43BAE9B7B +:10F680006EA8BCAC2BEFABC4F9EEB98D91FD5AAFAF +:10F69000CB5B13BDE162A14C1B89F8D7D50FC37EAC +:10F6A0002AF5FC3849A67E727D4CE70B9E8D3FA55E +:10F6B000F3018B8A7EC946A199E0C3FC3ED2F730A4 +:10F6C0005E06E9256FF6CE5D561C2C83D39DBA8F5E +:10F6D000D35D39F38808AF91F2FD011C7FE66C37EA +:10F6E000F199314719C185280FF257A50AB44FB9CE +:10F6F000030A68DFC73BD42611F04814CB0A126016 +:10F70000BCEAD9029D4B4CAF760405F8E774A00F14 +:10F710008A8392BCEE1980EF33BD023FEF85FCEC8B +:10F72000283F3C68C3745E36C3CE7C2FC4C1E7DC7F +:10F73000019C0F1BEDEBD7D84C7E9DEC014E2AFFB0 +:10F74000BA70D261E2138CC7B3E4247A8E217F674A +:10F750005233F1A9C316D0BF51FF651AE9DB37E96F +:10F76000F46EF08BE9DAED64074FF798F5E80F7166 +:10F770004F900E6609A4E7CEACBEB09E7DAE50D0D1 +:10F78000CFF172E5C349DDDF15A6903D7D23EA394F +:10F79000A5F07132E82151FAFDEC3BCFA752FD3EB6 +:10F7A0004F2FFFE60A40851ACE5FEA019EC82F2B35 +:10F7B0006649442F756B6C14F755DFB6DA9A85F8F5 +:10F7C0007C0F5339BE7ED2D80FE6D9AF561B212A03 +:10F7D000DDF0E9571B1490AEB390E710FC2336F42C +:10F7E000C7CDB0A9B5B8AE19694CF6A7025ECEBABE +:10F7F0006E23F6BFC6C16411E46DDFF677828857C9 +:10F80000C0CA55C449C01C8A67CB9593E85CA1C99E +:10F81000328CE2B59A5CC96A747CD4BAD5DD78873B +:10F82000715A8A9D0D93F5FD8D6727150CE0FCEA52 +:10F83000518191BCF0CF72109C330B789C52668A38 +:10F840006A0BA422BFE17CEA5181C7D73D6AF5E685 +:10F850000CC7383C502BF9FEF076B1749F99AEF787 +:10F8600093A4080120C669ED65E516849B3359C54C +:10F87000B844A3DFCA44CD8A7CAB72B0302240F0DA +:10F88000DC242D40FD34C1CCF7AD56BE2FEC23CE89 +:10F89000F763E520C801E2FBE8AF0F9493FC1A3F41 +:10F8A0006004C903EA6795E490ED2AEB21CF323C6E +:10F8B0002C19FD5BC30064A8AF77647BA662DC9E55 +:10F8C000FF4D89FC69E5D5EACD0BA3F6F5E7037595 +:10F8D000BD7D62640EC541DDA3F6C338A83515DDD4 +:10F8E000798C77AC61CD36C4F79A18F9B8D4B99B46 +:10F8F000F4C8A54F5ABBF197617CA85A80FCA3F6C7 +:10F90000D91EFE20E253DDFC2CC6BE64F26BB89E0D +:10F9100011C08F910F6985C922F995D96C2E47D9ED +:10F92000D302FAC544D7AA26947B9D4272B358DE0F +:10F93000CD2747E8FB759FE479ED6E5C37E84B4FC8 +:10F94000C9ACA71C603ED25F2680DC443D5A689F4C +:10F9500029E2B81B1743DF788E2F852B317FE762B2 +:10F960007E3ECAFCB7D1F9D738BF5D46FAFF2A31CF +:10F970006F8D3EAECF0ACCFA987C0FF5C7605F5012 +:10F980006F11901F4279DFC9D014E8605CFB11EA67 +:10F990006F633AA78B583D66B7C519B45890EFFA14 +:10F9A00049EE24B06036C24F2BE47CB6FC00E7B3CE +:10F9B0002FFB4183165195F5DD34C54D7A20958F87 +:10F9C0008D308A9BD9CEBC75BABEE31F908951A2F7 +:10F9D0003ECEC7757DC1D0E3AA62F6F15AE7231285 +:10F9E000F2AD6BB37BEC9788FD4F6602E98BD729AC +:10F9F00017E65B9AC19798992FB9D979DA3F76FFC4 +:10FA0000DE3BD04F1088D1830297A907A5BBBD1B51 +:10FA1000911E62F5A1DEE2289FD2F9FBA5C65182B4 +:10FA2000063107E5D758C3CE8AC19FBABDC7E73CA8 +:10FA3000C0BAF1AE0B9FFD9B6EC675803C97D1EEB0 +:10FA400013FE6B3DD1F51AA8278E47681E0CFC1CCF +:10FA5000F2210BF3619C02F3CAA7114F0DB90B9C65 +:10FA600088F0A47121C7BB5112CFE782228B78198D +:10FA7000181DABAF7BDDE887D6CA4B282ED690C7C2 +:10FA8000C32D1AE1C908A6A6633D034F46867939FE +:10FA9000E0C76EC48F7193015FF231BE76543FD4DC +:10FAA000BB2A9842F8511123D72A9DD324A4F34AA4 +:10FAB00047ECFE6B16ECF71A1D3FAAE47F0E3FAE33 +:10FAC00040FC30E416E8C9F7C5D817F7C5D8179732 +:10FAD000801F615CDFA5E2C7B101971767DB69BDD5 +:10FAE000E7637F39D9B33E31AF277E08ED772E7AB1 +:10FAF00000E93D90CC70DF5F48902B9D30CFFA1A23 +:10FB00001E6F3EFCADC200E6B396BB492F7C21556B +:10FB10007D8DCA7DBCBCBC431393215FB012CA214A +:10FB2000FF82DB5389F9FA55500EF547BCE70D60AB +:10FB3000BEF01E5E5E76AFEFB56494F37EDEFED55A +:10FB4000638DA20BCA838D7AFB8AE64ACCD737F144 +:10FB5000F6230F0403981FF4001FDFD03BAFD6F944 +:10FB6000E70BC2A9D7EEC2FE807F6E06FE39EE8497 +:10FB700056F61CE417C8160BE2EDC288DF8AF8704F +:10FB8000D8523B12F187CDF366239ED9D16E15BBB7 +:10FB9000F997059D3AD06E826425BDEF0DC12761AE +:10FBA000BDC94812286747AB0EE4EF1887BC19E4BB +:10FBB000CD005D1E1971BB787F606AD47E0D18C8B8 +:10FBC000E5BC512F2B8DE3057B8CE38511571C5A27 +:10FBD000CF04F4B7E0DAC80FD123CED847F23BD830 +:10FBE000BF6418E2EDB5185F0CE5D78EE5F1C56589 +:10FBF000DF9C9E14CF2E2AD6C73DAADF8730BED702 +:10FC000004DD16A49F171079FA62FFFDFF88FAD26F +:10FC10000B38D65802A99F8DC67DE4F9B103731E37 +:10FC20006E02BC586CF14988472C4F5071FED77753 +:10FC3000F8AEA1F5D43276434E9C75E8F27E51C001 +:10FC4000B699C78770FE335DDFB763F2EC3D7791FD +:10FC5000FDEC52AD30CEC4F10388EEA7550B06DDA6 +:10FC6000570E443D184F30C89FEDA538F7252C6836 +:10FC7000C34196C4D0FD32E7998F512E2DDB62A689 +:10FC8000EBE52C64E3FEE6C8E31F40FF351B9265FD +:10FC9000943FCB5BCCF56A36BC754028EDC9076A4A +:10FCA0000C3E1034F3015038381F583F98CEBF56E1 +:10FCB000648BCAA174F47FF848DE27302EEFEF93EF +:10FCC000D430D15FBB9DDB51BA7E7EA7C8F5F3046B +:10FCD000E6509C45C8872D7A9C2ACF1BE3B398F841 +:10FCE0009653CDB711BF31E260008024EF4FF9AFDA +:10FCF00095A3FD6C5D7C3E86DECBDAFB84F09E81B5 +:10FD0000E16701FD80EC2BB60038DD38E243B46FCB +:10FD1000C252F87F0CAECB46EB5A9F9447FC7D1540 +:10FD20001084BD0CED62A924847D0EE6F4E4403A13 +:10FD300042FE3ED96C6F2530AEC70FEFE07E9C11BE +:10FD4000DD72BF01F7D7CE540797FBCD0CE9AB5757 +:10FD50007BC5B932AEBD42120AFA9F3199F3F58BD9 +:10FD6000D92BBDD9235DFB99007A1BA4D3BC09CF45 +:10FD7000E3BAAF3E9F921C2F8E6A5A85E841BB6C56 +:10FD80009A55CB4C8B1727897A7666547DAF93FAB8 +:10FD900093BCE9CF63DC12F41B42FEDFF1A62D6EAB +:10FDA0003CB2A4F72F5935395EFFD7A2532ACADFD8 +:10FDB0002E79B3A8DF6F415F7971601C7DC5B62BCA +:10FDC000E69C92F90746C7133CA3FB0347166A6DEE +:10FDD000D8FE60421EF13BA50CECA97E94A7FE0E56 +:10FDE000DE762DC5479C61DA45E323D644F9CF0F73 +:10FDF000A6C63F17795DE773368C7983716F57B468 +:10FE00007D8857476DFCDCE568A29EBAF8B9D51F1E +:10FE1000BBEAF3F498C1272DBCFC689AF9BCC6A8CC +:10FE2000F7B9EE873AD4E0F0AC89F2BF2AEBED3EA9 +:10FE300094D39905FAFD8D958CECE7CE5752374552 +:10FE4000EFEBD98115B62B33B19E66CB4138BEC2DC +:10FE5000E55F9D14B6E1FE3E7285F7139C779DC267 +:10FE6000B417B11F256CBBA904ED061E17D269E5B6 +:10FE7000766067024F8D799D1D38D576259E23DDEE +:10FE80001626BED8959F1A26BE7776A087C6ED9C0B +:10FE90006E94EBF9FFCDF30A93559C6F8543B71F22 +:10FEA0008AE435E47705BD0FFD36B1E7078C8DE7B1 +:10FEB000FAB11EE7A9E5FE83CEF17AF3F35B1C1DD0 +:10FEC0007B7E0EDFE7E8FE606FDB977BEE56087FF8 +:10FED0000EE3B87383098CE2BDFF45BF7E67FF0E5A +:10FEE0005ACFBA8A48DE63E5142F407EB5E5EDAF00 +:10FEF000135F5F6ED07DAB99EED3AEBCB473B5D853 +:10FF0000F3966F81CEAEB8320E9DFD0EE535E0570B +:10FF1000953885F8DAA95681FC210AEB684438AF98 +:10FF200010F8BEAC78637EA50DF30B994C7CBE3502 +:10FF3000969F7903A8272C6B6224EFCA58410AC206 +:10FF4000BB7E9F883E04BA67A344F149BC67A344C3 +:10FF5000D9C578CF263A8FF76CA2EBE33D9BE872C8 +:10FF6000BC67135D8EF76CA2F378CF26BA3EDEB382 +:10FF700089CEE33D9BE8FA78CF263A8FF76CA2EB67 +:10FF80001F61BE47C70B08D7091B10AEADABED32E2 +:10FF9000C295F9B5778BB3489C11FEE17D9CE87E54 +:10FFA00096B926D996031CF6668B4C188DF76B967E +:10FFB0009AFA5D26D6929F00D40E92233EF88FE0E7 +:10FFC0002916939D7CB64D80BD037D68438CFED081 +:10FFD000FE5023EADB4B82E6EFCB5894DFDDDDF306 +:10FFE0001CE8D62BF573A0BEAC2FE27395E85471D4 +:10FFF0009F4FBD27AA76A6BB00709FB7727F64197A +:020000021000EC +:10000000BB72FD78DA472B0B2A783CC2CB4F6D14BC +:10001000837E77F7F9D0A97DBF3DEC857A8B734459 +:1000200019E9CE9E6DDEEF04C5BCDF4945E6FD4E05 +:1000300056CDFB9D32DABCDFB1704ED5CCFBCFC4C0 +:100040002904E765FDC0BC83F1D3279BF1C180EF94 +:1000500068F88FE3AB42F05D04F07D4CC073B507E8 +:10006000F6F6537AC2B9AEED211BEAAF970BE7075C +:1000700010CE49DD703ECBC6573A09B86C9A63641E +:10008000B7BE54BECF474102C7E4DC4AFD3E2F3F16 +:10009000DFD1E10AFA0BD90B51E7504DA248FACC57 +:1000A00063C857B58C64E203EA8624DAAF610EDEDA +:1000B000DF42E625FEB43046AF59EC7CC4867A4D6B +:1000C000EC3A7136E877A969E77A4DEC7A7BF8A3C8 +:1000D0008AE4503FCEB75B1E537199ED069FF6A29E +:1000E0001F238375D8508FE98D0F7E2F5B7B1EF900 +:1000F00011703186F0E0A600FD89AB4FD6771573FD +:10010000FFBCDDC7FDFCCC9F4AF318C5F83CA851E5 +:1001100094BF7F941424BF432EE3FE25C31E8B851A +:1001200027CB15D6BC0BFD8AAF311D8EAA2858BA35 +:10013000FDF760056AA85F8F3CC3F5A7D18E968056 +:10014000A4F4B4CF0F17E8E7DC921EF77991734857 +:100150009C3FFA396ED2E3EEAE6A1FB507F35DE756 +:10016000923BDEE887FB357EC75BE998BE2B284FC4 +:10017000DD0DE3DF2870BC88B52B03DBC729B8FF92 +:10018000570B1EF2574C62BE5C6E8F0449CE4C700A +:100190007849AFB538342B9D47E9FE4BC6C2935022 +:1001A0004F5FAADA681E6BE44F27A13F6619D3FDA3 +:1001B000316DE6FDEB610FC5D841B5B0FFD86FAC2E +:1001C000DD13078F62E201CCF2FE87453A3C198FBE +:1001D000575118BFF75DA3FB916A1C1B5DFC1C0EF9 +:1001E000E45C2EEB61374908F831745EF135E25B6F +:1001F000561AD80374DEAFD8E2C5EB313983CED5B9 +:10020000E73BA7115F9EDFD4C3AF4378BDB0F922AF +:10021000EBD2F58411F80DC6FDF3950AF7A3244E31 +:10022000D9A7617179475EB43E5B6FE3F772992F8E +:10023000DD745F21BF88EBB9E5BADE54E3D0E15449 +:10024000E46F44FDB84B6FEA612FFE73F7638C785F +:100250001780D78022FD7C677546F7F98EB18E2F07 +:1002600046743C1D027889C9D738903F2EEEEF1DA9 +:100270005204EDFA1F081F46BA614E85F4F5936DDE +:10028000C7F68BF9DDEB023C7B741CAEA34D94F9F1 +:100290007D797FE338E8B7B38CE35DEFF6AFDF98A5 +:1002A000D7E878F332E2EBABC4E2947094DEEED49C +:1002B000E17774B06702B62BFF63AE0BE76BCD6FCF +:1002C000D9DB17F5E23BB85E0CFB4A7E10D1CA04BD +:1002D000D44BABC4F3B763FE543693D1FECC48F293 +:1002E0008B2ED4F3E632F21331D5A722AA88FD8BE8 +:1002F000C94ECEBA03EC27E8F7A395F353F15E7F1E +:1003000056F282D40227C637C15407405EB078F84F +:10031000BDEC173FFE8F722C9F4D7EE95BECFC9C81 +:10032000D9FDA3BF2F233A604A9A7D0C8EE7A577AB +:100330000522A922CDAF62D699E1A85FF53DEF1C59 +:1003400086FA590E9EF302488B74FAB8BA3232DC40 +:10035000E7EC865346417CFB254587C7C1C49333F0 +:10036000F03CC4B87FB13EE96D3A0F3FA99F9FE4CE +:100370006B935310CF0F0E34CEB54299E8B2AA4B0F +:10038000D05266E23CDF11199E9B9C91B594542893 +:100390003FC9F8FD0A7F8795CE8956DE5FD927CD04 +:1003A000D97BBCFE7F1471FBA636262EAA560AD92D +:1003B000F03CABF65F8C8B6A058B3BDE7998B1FE27 +:1003C000BA54894943211598E742F5B67D2DC68573 +:1003D000E3A622CB05EF6D6CD0D767DCCBA8C37B3F +:1003E00019F069E52B157DD805ECD0BA73E34CF70D +:1003F0001FD05EC3F5D59D9B40DF2BEF3B6143FCD7 +:10040000C67EF00904E35E466F704E29E2F6461D93 +:10041000DE67488FFEAEF0EF5DFD6750F9333ADCE2 +:100420009ED96799BC39CE3CF7E870199C2991BFD9 +:10043000604888699BE28C6BD433DE35E86D5EAD35 +:1004400013C37370DE18171C6FBC97F57AC67C5BFC +:10045000D3C28B3CFC9C7520BE5BD095972379372B +:1004600046F1D3B3BA7FA0F57BE13C7A27E33A6E3D +:10047000C7F6B6CF53FB7B93903F8C944277ECC981 +:1004800020B38BA11FADCFEC9005E5A44157BDED86 +:1004900077379C45D3FD979E70B65179D7BD33A66B +:1004A000B9842C94438CF481F57F2CB5D960FC631E +:1004B000161641BE5325E64E7A15F3603F205D1EA9 +:1004C00023D901E90691EE311D7BB2C08676D9A20F +:1004D0000A1611816F1D7B37AF11E32E95B9A04924 +:1004E0008E0375678DF9FCB186697B93A1DDFC03F2 +:1004F0009E9410E4173C609663C7DE7DD086F6803C +:1005000030CFE9C3B82298E7A45721BFB0CD46F752 +:10051000B2163D12DB9F590FCED2E56DAC3E7CB2D8 +:1005200048B73B46B29128675E6D68E3EFE6E8F7AF +:100530001041FFD3E2E189A1073F9938F1AF4504AB +:10054000AF1611F9D238297EFD5B8B39DDAD78EA23 +:10055000B4CDA5F44E67C7819F14C2F8271A644A28 +:100560005D83346110F49F37C86B1B04ED45259201 +:10057000F705F939F93928E01BE5EBF17E1ACADBFA +:100580006AAE27D8C5DB6A481FEDC7E400E92F3EF5 +:100590001FF9D32DA09FA462FCC6EDA28BFC0DFC1D +:1005A000DDA0317F59908AEBCDF8CDCC1710AE7815 +:1005B000C781E1FB2B155A19F2F775539D74DEBF05 +:1005C000C9E2A77E3050EB3E8067F09931BBD07D09 +:1005D0005ED8F2D044B4FBE4F69D21B4579A2C5F68 +:1005E000EEC5B884A6094C0D10B483344E7DFBD4FF +:1005F00017B07DDE34A78AF74AD7B9B53239AA7F5A +:1006000085453E463DF364AD85FCA6A7DA9EA0F382 +:100610002AB0EF22A87C9FAACD27BF9911F7436784 +:100620007F71FC862740BEB1A87BDCCB5B3759507D +:100630001F1F821B15155765CCABF6DE50D6CD2893 +:10064000777F2D911CCDF8AFEB287EC02D2902C2FB +:10065000F36641E6FAA8AE27CF62C69FE63DA89FA3 +:10066000CE433D19F0F0332148F19A16D6FE12B66A +:10067000AFCEE6FA20535A46A0FF3A5CABBF4BB46C +:10068000CC9A8AFA8D714ED01B3EF4E6E7819E1615 +:100690007D08E39E1418F99BEA2D913C9CDF716B59 +:1006A0007CF93A7D10C7BFBA81BE20C9F334263F1A +:1006B00085F32AF4BA912EEB2CCA0AF27BBDE7A18E +:1006C000F8904E414E33BDEF2237FF0EF5EE7A8B98 +:1006D000CCED9B035A199EC7744E2DA6F75E4E5A59 +:1006E000C379C44780EF615C56DDA017A649F8DEE8 +:1006F0004E5FD0BB20FFF3413B783E3FBCC802F9C0 +:100700005DBF7E7F9A0470AD1B1C3E8CF937077D60 +:10071000CAF3C3C28B707F8E0C8AF03C1A60806073 +:1007200067067D35CD0FEB3AAEFB3F991A9E83F3FA +:10073000AC7BF54A4BB47F313C88F3CDE309BCDE9A +:100740007137BBF546D43F8AC2741FC6A8B77B90E9 +:1007500011B7C9F17FC9B68410C6091BED5876FCE4 +:10076000FEEFD1DB2DD1DFC902FAFB2DD6DB9DAD2B +:10077000A4D13E1F051E85707965109DF7CC1B9492 +:10078000A6BF7314CE4B2BEE39DE5294F32807AC80 +:10079000E67B6FF70FE27C9B15F3FEEBFACAA9B874 +:1007A0001F5969DCCE800D49BD8FDE2FD8A4EB55D3 +:1007B0007C7F3244B92C2093DC198E76F3EEF3B9AA +:1007C00065643757C6C78B4775BC5812E0E344725F +:1007D000147933DD37671AC6A3EC6E4BA07518F594 +:1007E0008F0CE2FA4578502AC78BAE7DE823D038CB +:1007F000011D2EB900EF926EFC31DA5F6CDD5BFEFD +:100800004DEBEEB14FE57C7EC67A187B88EF2BCCA2 +:100810002F15F4FCE3ABF576A38D7928440F4BB686 +:10082000DDB581F33F258DEC76F6133E5F87316EA3 +:10083000319D4F2ED7F560D1FFB60DED8DE54D1DE5 +:10084000F4EEDAF216FECE5637DD692BA3E92CA3BF +:1008500080AF3343D43202448FB03EA2474D8F372E +:1008600030E34F17BC63E9B8477F4A9AB93F85FA2E +:10087000EB6D1F3EF8B6F721101F9E5DFC25067E2E +:100880005DF4E8D6DB15039E95F7A4C737BBF62FBA +:10089000868EDDFFE478FABD93E577E9F1AA8A193F +:1008A0008F97B7BA2DF38ABBEBDFDFF290273A9E22 +:1008B000D6DE3AD78FF2AFBEBD82E26A97BFBCF5F3 +:1008C000777E68BFF4F99FBA3098FA98D49C857AFD +:1008D00071ED536B5D1A9EB3487E17F2CD63417183 +:1008E00072BC7BABEA60415F1FD7C7EAF09FD0FFC5 +:1008F000F167FEDEF81F30FFBF0AA05F21BF6DFD6C +:100900005B23DA6F7B354704E5F651293C09E5E8BE +:1009100092B94EDF6A15E306CDFAD4D25FFD344BAF +:10092000A1E06E7F3F0BE953A17ED8AEEE49AB8AC2 +:10093000F67BDD7BA20AC3B07A1669C4F9C5B6AFEF +:100940006FF9CC867095411FCC1DD7B31C3809E1D7 +:100950007D7DEB7F7E29BA303DF6212BC5FEA2FCC2 +:100960001100F79A5EF432F760DD4FA9DF0B30E03B +:10097000C38299A4DF047EBDBEF41398D78927FFF4 +:10098000AF4B288E9697F712BC4EB5CCFFE5AB4A1D +:10099000EF72F524EA07F69E7A80D2267025BB9D79 +:1009A000A7B5D6900BFD02B59BACAA1F3ED76E7DB6 +:1009B000E2693C57611FD8553C7AACDD7ADA86EFA4 +:1009C0009ED50A5A44203D8BB98491DDFBB46CEB73 +:1009D0005FB8BF2A476453609F96FEF62CAFAFB155 +:1009E0004802D45FF6C227E4DFAAF53A7D8E38FBD1 +:1009F00054D9B2D31676C6D9A7964F26A11E14F89D +:100A0000F557B40FC77608AC8FBB67FB9A4D7FB123 +:100A100021DD9C800D494FE5F042FBB4BE459C6B47 +:100A20004B89B76FA1EB51FF8372F2835C6CFF843B +:100A3000C18CD3C5CB5B9F437BA0E643BB3A05C7C4 +:100A40007DEE761743FE2AF938BEFF626D9606E307 +:100A5000D658FD5932A5FC7BCDE377101E2E7EE7DC +:100A60008E2CD2EB989663194DEBCDC1752EDC38E8 +:100A70009DD6B98879090F6B7EC1FD196725363976 +:100A8000DE3DE32D8339DFB2B3DB4A913ECE424FE8 +:100A9000E8873962633C9EF75DFEFE989DDD981203 +:100AA000FDBEDCDD83391FF1B3E0C7F8EE643DD84D +:100AB000C5C817C477CE4EC27E56BA259F5DA6F52F +:100AC000FB757809DFF0780E4532E24EF361BFDE48 +:100AD000A9EA8376B09D9DB2DD528EE7BB4C41FF03 +:100AE0006F543B82DB91CDF64401ECFC2359F1EFCE +:100AF00011BEDF45F7EC5D16854FF55B8E103E317C +:100B0000B0BB52B279FE31A443B08B52006E67DEA7 +:100B1000FBCCD617FD1D19163600E7DBF117CA33DB +:100B20003553C1FA46FFF56D76D37B24F54FFE258C +:100B3000869EED31EF9CF8089EF52C45417DF388AB +:100B40002D32691B8E03E362BCE6A247ECA677C296 +:100B5000BAF1C5D6FDDDDD4D9F867DB558A7FFD81E +:100B6000F5C7F2832762F801DB987949EF3ED55A41 +:100B7000834F237C6A815EFD44AF9CFE40478F0C0F +:100B8000007AF8FCD9D7F6FF10FD742DD68C2934E5 +:100B90009A99CFD6BC08F48BFE348077828A7CF693 +:100BA0002B1BEABDD9956007C3BC3F77AA7829AD56 +:100BB00027DDC2F7B874EB6474AEF5FF8BBF2EEE81 +:100BC00085BFBE35D87CEFEA2C2B4EC13B0CC79FAE +:100BD000597605F91562E06BD8BBB17C73F160857D +:100BE000E01CCB37E1CF7E1605C7A5BFF982F0F632 +:100BF000AF39FC1CACEEC9BF91FC02B046EC80B72B +:100C000075C12F29BF16E517E5774EC3F3EA9EEBB2 +:100C100036C333B6FC219D1F75DD73BB97F931EEEA +:100C20002EB25DA4F7173A612E8DA89F3FEBA673F5 +:100C3000C2B5BABEDF29475CA89FAF4D35F2EC566E +:100C40007C07A6D35F2AFBB17D821E7FE089B85264 +:100C5000A3F4A44FDA4517EA75E1209B1CFF3DC0C1 +:100C600000CD23CC7A2B5FCDEF6B89E79F0BEB7622 +:100C7000BD1DC60BAFFEEA393C373F2439E8DC72B4 +:100C8000C1EA992EBAFFD75EF07F102F16BE017011 +:100C9000447AF26BB61C80F37C0E02303FFC741E6B +:100CA0002C2697EFDD06F5160180F19C24D69FB225 +:100CB00094795242EE9E7E1390833694FF8B411EB0 +:100CC00091DF7BA3B97C69FBE784674B63F0CC8B36 +:100CD0007896D313CFFA0ED1E9B68C95E9E7BA64CA +:100CE000CF77EE13E93CFF948391BE81E7BCB063FC +:100CF000EC54BB48FB73EA592148F186FE4CFE6E6A +:100D00002BE03BEA59061EC6DAF7B1E989973E1A8D +:100D100089F7C46A7FF7DFA53F87F4C4EF3E18B8B0 +:100D20000DF32FBF9FF7DFAC67FDCA1D7F233BA6E6 +:100D300073879DFCA19D3B5ECF43B9DCF9AA5D455D +:100D4000FCEDBCD7CEE31A7624D3FB659DFDB9DF5D +:100D50002EB0FDABD230C9AD357C1F87D868BF4FF0 +:100D6000B5FF9DE4C8A976BB82EBA8DF9144FEB134 +:100D7000FA571382E81FE8DCFED5C8E877AEFED547 +:100D8000F5D4E9F7693A935935C6CD74A6F238CB54 +:100D9000FA6D639E588DF648EB4E1BFAFF2BFFEB66 +:100DA0001FA5C8973A5FDC6943BE0576E9E30CF0FE +:100DB000C3F39B9FFED49A83F7C518D9DB277EB374 +:100DC0007F3ABE8BD5132E1C0E9D00075C17C0A565 +:100DD00006F5B2DEE0B1F83B0B8F2FC99EA86D1F60 +:100DE0004574D40D1741E3DF93830E01D7FF8A0BBF +:100DF000FD469DF920FF555CF757A5A83F5D6CDDCA +:100E00008DFF53D66D6197B5EEA786F0F7C8BF7B0F +:100E1000EBE6F83F64089757B174D013CF5FFE112B +:100E2000E59F4B5669BE9748FF7BBEB3EBBFE47DA1 +:100E30002F45BFEDE5EEFBA1EFECBA2FB6EF6FE863 +:100E4000FB9E2CE3FDBACEEDFFC8A3F55EE2BAC56A +:100E5000E2EF2A9D5F78DD5DFA91E871E0D35A0FE9 +:100E6000B0508702E9DA5EF414B5D86C8F88BABE48 +:100E7000B1960DD336A15D057A06DA016B3378BEE3 +:100E800009F40791EE0F52B00A6BCA55F97BB6927E +:100E90008FC990B7BE3F9FE259D6667D8FE597E335 +:100EA0007905F7630456ABDE9DD03E906A51022A65 +:100EB0003E53B5C2BB09CAE5BEA28CF6CD5AE54683 +:100EC00047F43B1692D366B2539C31F64662A1CDED +:100ED000649724B05D32FAE1135489E2FFEC2CAA46 +:100EE0003DD47715F373EB4416F4CBCECB87D32DDB +:100EF000C5BADFECF2E1E4A07B95B20E27A669B893 +:100F00006EBB22911E2631B01FF93AB8DD0970542C +:100F1000A2E0C8743B54D2412E29C3088E604028F9 +:100F20001347235C7D04C7408E28135CBBFBA3756D +:100F3000C7EEC35A6522CBD7F57141FDF6E13CBC43 +:100F400098FF1E432C9C8DB4C05BB11AF5DF95ABA6 +:100F5000F939D78BBFFF1EE55BADA00FC37CC6A7D9 +:100F6000781715A3DFD1A30948A72BA7F27705CBE4 +:100F7000F11E58069AFA3C0E37C391CB24F25782E1 +:100F80009D41FE4A99A1FD274E642DE40FF448319E +:100F900071BD32C53D056EE3714FAC8829FC9D16CD +:100FA00073FC8F7F222BC2B8862AB1B619E7758AE7 +:100FB000253763DCA5CD1ACA23FF707F9085E86FC3 +:100FC000A9F8EB462C77835ECFF03E9914FA18E32C +:100FD0001BEE145318C55545E05314DCAE3EE760D4 +:100FE00052149C2B58AA297FA2FFE156B413F2FD9C +:100FF000761983C72A1D39A6F62772CED17801BB90 +:101000004346FBA84A769BDA8BAE7D1FA35DF37641 +:101010009A85EC826BB30799DA5FFFE9898D737566 +:101020009CC575DCF011BFA70AF6D6E36F42BB770B +:101030001E610CFDC6D72965A6766DBA7F2552655F +:10104000A5F766BE5F34C6346E5B7817C1A53693CC +:1010500009781E5C6B0192807A3F502B4CF56E181C +:101060007D9DA9DFA9DA5453BE76D55F9994CED879 +:10107000B855E719BE1B58166A31B51FBEAFCD541F +:10108000DFF52698429096BDA704301D7590DF23AA +:101090001D0EFB81E71B6DE1792AC6EB94E005D0BC +:1010A000723C16F0546218F2C8A3BED730BD58FC8B +:1010B00032D3DF634DD4CF5FD759822D73DD18FF54 +:1010C000D3FCE04E81E221B7158F40377473650A77 +:1010D000541F7BAEE5354C5B3BC6378D2DA76B436C +:1010E0001D247F9D163A17A812DB4B05B27F92860E +:1010F000DBA3CE5D7A7BA7F3EEB28AB7900ED664FF +:101100006BCD3B91EF4FFC688E98DFB31E93A548E3 +:10111000349EDF5DE6F933C69D197152899522FF31 +:101120001D8A6B799C4CA3454DD09917E907F22491 +:101130002BC5F1CF2DE1726064C7E6166739DA9DE1 +:101140000E05F73531DD7CCF7BFE687E6FEF8B625D +:10115000DD3F2FC999B79460FB64DE1E7D7C38DECD +:10116000140BE9533BAF3A42767AE20D96FE2041EA +:10117000996BB46A41BB7BE4BE3FD17B04AD53F2B3 +:10118000D7EF82FAADFBFEC40428EFF340D95E2B03 +:10119000D2D9688B8CC7F5ADA3279E2EC4F229EF58 +:1011A000524CA3310FD739812951710F734B141A47 +:1011B000DF2585E91D22D73989CA5DB3554B1EF657 +:1011C000B7CF4ABF5BB3E22AAEEFAD1894B815F1C2 +:1011D000D47540E37150454E6500D143389BF88289 +:1011E00014CEBE2599C753291778CFFFF89611A9B9 +:1011F00028B7D22BD454F47BA66F15BBEE99E17CB3 +:101200001FC4BFF020DDBF76FF3550BE0563D57823 +:10121000790878105B67D3CB9105413E5DD0CBFD5B +:101220006B675CE3A477174DF587E677D5D71CD9B4 +:10123000DDFDF7D9BA76FF9A6284F7280BC69124B0 +:10124000FE5F2BBD2BB0629093F4871540BF4CE836 +:101250007D1DAE73491781A78BCA0F094ACC3BB9D4 +:10126000A112CCE7E57AF34A005FAF389F42F7FE60 +:10127000CF342590BCBBE2FC0DF42E67AB4DCBBB4D +:101280008BFC3509145F36F5B6CF37AC423ABEFE5B +:101290007811C62418EF54D6CB7F25FA37E2EABA84 +:1012A000E087F80A78FEA0A53B8FFCC0D50D4F0D56 +:1012B000DFE35A17055FFC6D97A93A3C676E5D3F07 +:1012C00003E1A32C989C8D74789A39298EEFB4FC95 +:1012D000F40C9CEFE92D560A9A6DD5F9A3BF487F0F +:1012E0007F20239C8DF7F04BDEB150FCD141C0072D +:1012F0000DF0A120F44E5A09B6CB90D2309EE1F405 +:10130000F8F7E99D84D3F7300A265E1AB611BC5A65 +:1013100033165456A07C3BA0A4A1BFC1806F8BDEC6 +:10132000CFBA326D6209C947FD7E8836F6B2DE9BC0 +:10133000DC79D557740EB0C60D7A7D2A86189F6B5E +:10134000C4F72457B8AD248756A4FE755206E27B35 +:10135000852382EF3ED4AF3A43F0856EDCD1F7BEF1 +:10136000A4732253A2E2B5FA0CE5FB2F491AEDBF94 +:1013700074CE46E5B5AB4E139F36DA9FD0CF53F10E +:101380001D46BC1F54FBB548F74481FF3509C330E7 +:10139000DD655B117D8ED3F265175F1F6AC1F79F14 +:1013A000DE4D44BFE454419E8EF3FB6DE99919185C +:1013B0001F3035419E8EF105FFABF4239EEF2F4F7A +:1013C000C77882755BAF9E89F1065373E49F5A40DC +:1013D0005E6D7B6ED64C2A77CB7FC2FC132577F2ED +:1013E000F264BEEF752537CDC4F8822A91D3C1A926 +:1013F000A6A4A0FD0274B078D53616FD6E6D8F726E +:10140000FD77A35835E7735FDCDF8FDEE964851D68 +:10141000141FB6BA44D0E3D08CF35426E3796A465D +:1014200001D3D0BF9CF17202FFFDA1431D7908BF1B +:10143000231B6FFF11FA4F970B8CDECBAF65CA48A9 +:10144000A4AB7996F0C798FE66B8B789E34707C59D +:10145000B72E5EB583E6F789AAC729CB9162CF3F45 +:10146000F52E04F41FF75D08735CF1A7166520F6EE +:101470002BE970992776CCB1F179FDBC04CF87D2E6 +:1014800076525CB324776479B9DE5444F6527622FE +:10149000BD0BDDD8F7C3D278BF77D0D200F21D489C +:1014A000EEC586364AEB87325A4F1F296C53A19FEF +:1014B000BA035CCE8CECF8D4161DBFF88A2EA75266 +:1014C000F4DFB58A8DBF7D459743C6F9F6F2BEA11C +:1014D0005CD4078D7DEDDE9750AEBE2F0CE79B915F +:1014E000FEDAB3F8BE09C6B5DE83E7172F2784D02E +:1014F0004FDD3B9E18FBC068BCD644CE37222F255B +:10150000909E14BB8E3F76C957BE9E233A9EF4B67A +:101510008E23B88ECC7FDF3A8E207FCFECB91E832E +:10152000BE8DEF067DF76CCFE77FF978C7EFB15D31 +:101530000CEF0CFE53C7BC45FC7E34E73706BC8D70 +:10154000791A706BED25FE565AF58A693D52C744EB +:10155000347298AD349FF3B796EB18EE87B4AA9D1A +:10156000EAF5B61E31F90C9DDB2C55980FF5DCD849 +:1015700075D5B2166AD7735D11E2C7CB15CE8F7BD6 +:10158000C6ED47883FD7813D86FAB7B1EE2E3E0DB6 +:10159000EB47FABE0A180EF14DBC3B28A03DE135E1 +:1015A000E9C315784322FA9CCA719B295F25DF6540 +:1015B000AA7F6DF66A53F975CAFDA6F2EF173D646E +:1015C000CAFF40FD598C3EBF29469FFFB5A97C7CD0 +:1015D000B883F4EDB71B26533CFA84A311D2BB4366 +:1015E0000D32E577356453BABB4121FADFDB504455 +:1015F000E9BE0695BEFFBE6134A56F3668947634A9 +:1016000078288DE51BE51DE172F4E78FCE48A1F344 +:10161000A707867AA795E2D1C27B9162C4BFB107C2 +:101620005A5E43515010FCF263AC775AB651FCE15C +:101630009A9D63FE703BE4D3DF1459827221BD484A +:10164000645A14FEB8A684199E77BB187F0F2BB678 +:10165000FEAC521E4756CDC2FCFD805574E2CDAAA9 +:101660001DF21E2D83C44604EDF46AE6233DD4B278 +:101670008ABF4B53CD54568EF6AB97F91EA0F82374 +:10168000F37B021E6DEADADF42F90CBC670AED7FDC +:10169000E86CA17BE42FEE4BBBA60CBECFF208F4A6 +:1016A0007B1E0776DC778783EC5DE3BEE98796CB0C +:1016B000D127669572FAEA14D40E9CAF3F95BF57B6 +:1016C00014DBAE545FE7F58108E91F11D03F30BE4F +:1016D000CCA0CBA9F2217DFD8A25650CD2C76ABAC0 +:1016E000CF50DBA1A80180F798439C2E46005DE017 +:1016F000BE8D3DCAE96024D001C941DD1E34E80039 +:10170000ECA7D7B0FDA9834C453BA271C27F8A6884 +:101710006F8D39130C607AF5F9C8CE6FA07C5C0729 +:10172000FF7DA48BD98F865EDADE504D78B4A3C1DD +:101730004B69A8A146C74F1FE57737ACA2FCDE0670 +:101740003FA5FB1A9A74FC6CA6F2371B3650FEEDCF +:1017500086A08EA75BE87B1F5D9EF94B653D2EA999 +:1017600042B72B78EAD1565BE95E3F7C427E528DD0 +:101770007345FCA81182C8BF1BD3FC56CC3726E2A8 +:101780001EE0ACFD54FF66270BA11CA8CDDEC6F5FC +:10179000B0183CA9C8B889F0649A1EB77A20ADF198 +:1017A0000E1BE0C3899687ADE6F7452F0F2F963ABB +:1017B000D7D03DBE58BEB804DF9F107BF243C6545D +:1017C000B5BC9CDFE7C2B8BC4BE5F7B2A543BF1F71 +:1017D000C6EFBBD4E53A29AEF6DF2767645DCEB02D +:1017E000B958BFCBDE4E3C3807DFC3EB0197187BFF +:1017F000FBCF57F2F686BD0D7A26F9A13A8322D99E +:101800005F35EE6617D9DBA3232EDCCF25DB4546FB +:10181000FAA2C4CF771763470AC6F184F68F23393B +:10182000B3722FF2A5A5FAF96EEC396D1D9EEF0A81 +:10183000F1E01DA638FA65FAF96EECBAEBC61FA105 +:10184000F3DDBA8BDC23FD53A9391E23F6BE6E6F80 +:10185000F882F103D1EFB79E3CDF4076DAC7A57777 +:10186000AEF78FFFF7EDDFC232CFE7A53C6E9AEE01 +:10187000C919FBD9A8FFFE66E34407DD5BE81C211C +:10188000D37B379D027F6FA7F36F4C5DADE07B3A52 +:10189000F26E940B57AB36E2ABA3C3FC7D80F178BC +:1018A0000F31CEFB00571D0A0692B1DD413FF99F73 +:1018B000C6BCE70DE03DDB516F6A229257D96E8FAF +:1018C000887860C827435E75D3957E4F0E63300AD3 +:1018D0002E9DFE9405A3B351BFEBB25B9D93E85DD3 +:1018E000A2D32146D1A3861F6CF8414DC47B0823A7 +:1018F0000E7903286F1B753B73D409BF9802DFAFC5 +:101900003AE3233B680CD8A9F8FB31786F5A8B82F5 +:10191000AFE1C732F89CC1D78C7B7AB2CDBB05FD55 +:10192000CDECD5047AEF2576DE7943B95F68717F17 +:101930004FDE50E47BFABDBC2AF1FCCE6FD02EE81E +:10194000E0F101579CEF7C1AED9E952F25D1BDB497 +:101950008BDA07F2E9B8FAA991D65BF8B9C9B04AAF +:101960006538DA9BA8B7A21D6AD8A5B1F50BCB26BE +:10197000960DCDC4798DEFD010BF65CB05F1BB7E40 +:10198000D59717B40B8DF1EBB78F90E7459D1FD41A +:101990000F35CE57FEB977A7AF8A549BE4D8775D51 +:1019A000EF033A2C47FC429B15E5D40F7107601DED +:1019B00037B310E92BB7E8BF5B712BA8E0D1F76212 +:1019C000E7338DF8C31ED5BB08F765218BCCC17CEE +:1019D000BD10A9DD0620FC62C238D9ADF494D797BA +:1019E0002B9F13F57BAFB170BF6B28D7670CFEDF61 +:1019F000EBFEC4F0FFCE3299EE3D77BE34CE82E7E7 +:101A0000369D6F89F45EEA3A0BE72BFE6136F529C5 +:101A100015DF1F997D8DE10FC0F8B258BEB2C5A287 +:101A2000FEE17628F7BF9DCEE2D195915E8FFA2830 +:101A3000E061CAECB094EFA4F7D3D721BCBADEEFD3 +:101A400040BE7205C0FF137E3EC79608E4F76C6B7C +:101A5000E5F99285A934BF4BDD0FE839A914D6B159 +:101A6000B0551A86743A342D928FF45532E6833489 +:101A7000C189BFC3CAEF4501F89A585AF73CDFD273 +:101A8000E1F997A1DAE338BFA1691DEB1E463DF1EC +:101A9000250B43FFDF9131772D6251F2F56B75E233 +:101AA00013C82F9E17F4F7E5B6F3DF21801659D13E +:101AB0007EAA3D6AE5AFB15E0BEA5748579E57E8EC +:101AC000FEFD5499C3925D93A9FFFE63242FDEEFC0 +:101AD0000119E75043513E703F22BD07F6BCEE6747 +:101AE000DC39F4C3996B90918722F9388F2309FC74 +:101AF000FEF3D7AAF7555A07FA6B711DBFE076FEC1 +:101B000091541FDDFFF800F82C9EFBFE778383D2F3 +:101B10008FC0CEC1F4CF60E760FA09D839987E064D +:101B2000760EA60BCF41A7B08F15AAF6C6D00BAC88 +:101B3000A3773EC1D7D1D9CBEF2AEDD2E15FDA7AD4 +:101B4000E8DE24C4833691E29A4B5E9248CF3CD9BA +:101B50003ECAF43BA24077FB711EA56D7FFC09DEF7 +:101B60008F2E6D956441C1FBD4A7B3286E30667E7D +:101B700008073C27886CB7F1DF3FD2E7FB7C6AC7D8 +:101B80003A6CFFFC4BF938433C7FE178B8DD1EF737 +:101B9000F7818D38B99FE972FB067BA43CFADC30F3 +:101BA00036AE8CFCB963109F0BFF80E3F8F7896CAD +:101BB00000E1A5D94F91AC723964A425DB6D145FA7 +:101BC000FCFCF6FD377E1FFABB7EEC75A67775FF31 +:101BD000819B9B8978FDB7C71ECEA0FA320E358B4C +:101BE0006DAA92A1DECD8E9D7B70E9B7C89F54A5EA +:101BF00042FED66C612FA67315F7A43405E71BA42B +:101C000071E61755EC45D49AA24EB5F1771C453CC8 +:101C10006BECE28F958E247A0CFAFF01C9CDB6AA3F +:101C200000800000000000001F8B08000000000082 +:101C3000000BED7D7B7C54D5B5F09A39F34A329395 +:101C40004CC2041220709200060830249390902019 +:101C50002721D088944E225A54D4915A44E53122F7 +:101C6000AD694B9B13122084A04191624518285AFC +:101C7000EDF5ABA9052FF6AA77824AD55A1B149F1A +:101C8000A576A4D66AAB9282D87A6BCB5D6BED73E6 +:101C900032732693F010BE8F3FBEF0D39D7DF63E8B +:101CA000FBB1DE8F7D7600004EE27F33DD83001CCA +:101CB000C03F54FF4AD630808268FD1239DFD07EA3 +:101CC00069C178433B4008A004608EB7D8D06F52FA +:101CD000464F5ED00930E1A9CFEEA8F4E0031384AB +:101CE00047633961EFA76FDF82E5DCA957FA241952 +:101CF000E043E8B862BC09E083B2F55BEEA6972D3D +:101D00008A2D7B30C08DF43BB67F04E1D72BB05DCC +:101D100072AD3C701BBE77739604921760F136EB80 +:101D20009148CC3A96813F2D8CFD6EDE6D7C0E1075 +:101D3000B1857D00B7049CC13637C09247B0DD61E4 +:101D400068E77197EEB3B9A97D1958A2EDB9000DF6 +:101D500087731F7D3666BC4919DD77DD8DE34D7ACB +:101D60007C9EBB19D7F768F9E74365DC67A1D7E527 +:101D7000793F053B4C812927252C25A719B0DF8900 +:101D8000E7A59084EB9A297D911A29C4E73599003B +:101D9000D9F89E49FE6D05B6AB2F48F0008EF3F7DB +:101DA00046F9D167AD343E5CE7C77E27E9673ACD97 +:101DB000BA9AE1AB976F35E2AF1701FCAED1C1E53E +:101DC000EF1BDD5CFEA1318BCB771B652EFFD85856 +:101DD000C0E5DC5720D089E3FDE91F930106D13827 +:101DE0002A4066B49C64F39A87E23A7A7E23857629 +:101DF000E17E8F574E49035AE717387FA98607249B +:101E0000813ADC0394E37F37EC7C2EDBC7CF551798 +:101E10004EB5EC1F122838EE0D5E9358E792AEE7F0 +:101E2000B23DD17658F9AEA13FAC321D30D45B72D1 +:101E30008DF5F6AA03B1EFEB70882F6FDC76AB2D32 +:101E4000E0C272B3490939FBB6EBEB99B93F4931AE +:101E5000E1789627ED213BEE6F995B0105FB5B0076 +:101E600094CEC2BEEF0134F17B574A10EC4C30EEF9 +:101E7000721A17E136677F12486731EE5B481BB470 +:101E80001EF53FEDA107F0BDB7D214F0C7CCF35D4E +:101E90006DDD1FA7777CFF33ECF7F113404FB00ED9 +:101EA000F3693D13F7FCD96CC67252B2A09389EE68 +:101EB000883903CBA38BFFB9E5750F93A9DF743184 +:101EC000B6E7F5BCEE4094AFEE9CB9D581787BDBEC +:101ED0006C06180A02F165D81FC7A0FA06EFCCF904 +:101EE0002DF8FBA5FB93C2E6B3D8CF06E4452A271D +:101EF000550B7EBF96E846CCA300F2C3F235A0CFC7 +:101F0000AB907CA0FD53FD99CEDA3737D31AA0678A +:101F10000BC9878F00C26DBC7E253596FF973FF5B4 +:101F20002DE6CF25D9C8F748EAB04DF0AF03FF9DA5 +:101F3000CC237E0DCD72E27A6F0A23FFC3F9E7FF4F +:101F400087BDCE289F5F9490CF5FB914EBCB9F9055 +:101F5000BC766C3EF6E468C14F1ADFEB7CDE4B4F7B +:101F60005B25E64BBDFEC993526D2801BC376974F1 +:101F700091AFF4D4D37C2B9EB2401BAE6FC5B48B13 +:101F800086C48EDF875E5B259063C67FF469FB6243 +:101F9000E217197A06D721FF4C7AEA444655A12860 +:101FA0009B681CE8D0E44DCF08FF0494D726FFEFD0 +:101FB000BF87F301E2F101844F75D6FC1C9ABFDEA6 +:101FC000094ADB6406CB3C07CA89CB0488E0B2B27D +:101FD000AB7300E1B90DD12521DDCD53EA5EBB1A0B +:101FE000F178B939F05592F36F79F379FC2B5C2BCA +:101FF000AD606672CD31E178F3E7D98B693F739BB1 +:10200000055DBF96DEF3113D7F6D5A8AA919DF7B0E +:10201000CD042D9011DDC76B567F4E90E9A7C6FD0C +:102020003EE2C7A48C934EA6F42F2F8892DFD7F1FF +:102030002845E5DF4CC9A9D23CC7DC66A67B4B76B8 +:10204000BB8DD67513840E2838EF326FD846F2EF69 +:1020500016705BA8C4A2A7973E88FE2AFFD9751206 +:10206000DF5FD62D854CD8BFB3B1132C88DFC71ADC +:10207000F77139F28B912DC3101E2B27DBBC6DA499 +:10208000B734FA32AB263899405FF5A54F4BB41DF3 +:10209000D75DE57086A5547A6CFD28761D3FC85142 +:1020A000FEE945B8AAEB2AD3DF4715CDB43032BAE2 +:1020B000CF49360027C9F9075258CE7FF874A9993D +:1020C000F0F4E18BD69089EADB2F7AE3361FD781D3 +:1020D000E4CD87195EB38DDA33F2422AB6DF6806A3 +:1020E00095E432EC1272EB9969B7BF43726CE50369 +:1020F0002E93DD24E858461340FAC9C677EEC57121 +:102100006E4266B57BA37A63C9F49F6C7904E9607B +:1021100089B9E38E4A7C7602C213DD08CFBF9A3AB2 +:10212000C790DEFEF3FDF6B099DEFBF1D85D128EAE +:10213000FF5C6A207B32E9A92C65482E3E5FFC4A91 +:1021400026B4E1FB337EF2AF97496FDEF46826F3E5 +:10215000974EF733890F713D47910F693DC79ECC6C +:1021600067BE8BE25FC06129CA034038AEDFBDC9DC +:102170004FF8BC2159667AB440501946F8DE773DD5 +:102180000490AE8A24934274DEB31EE165EA4B4F9D +:10219000DEC9667E6F8919F52BD161402E26781C29 +:1021A00035C9451A5F00ADE7C8D36377B5E1FBB524 +:1021B0005AFF28DD1D5EF65F4477DBEC5E3B2EE1C7 +:1021C000A324A3DED7CBCAC9E9DCFF46C7A7602991 +:1021D0008E3E5FD6F0B9B15E080AC98DA266B9F825 +:1021E000562C6FD3E03E63AC7F3AC1F1E6CE4D8F03 +:1021F000BF24D3BCDBBEFD36CDFBBC93E785970483 +:10220000FC8E9A847EE9D5AF8EBFF1F8003B797ED3 +:10221000FDF99FEF7F636200C7FFF3DEF16300E922 +:102220006EA1D4FDFE7D88AF4F5CDDEF7C0FCBC788 +:102230009E7F6530C12F7EBD4B1A8E8325460E7D55 +:102240006432F17E97D03EF0F97F14FB2F9F5CC281 +:102250006CAA10DC16B64DD845F260A654984676A6 +:10226000D3D10F8DEB8B5FA73EBEBE3E7D7CBDDF25 +:1022700042823FEE63F22437971FDBBA3F21FC7E98 +:10228000FCF87813B262F47946F7C4F4C2289EFCD5 +:102290004A9395FA5D41A21E5131DF21F03A7FB198 +:1022A00029D49CCBFDB8FD6A7C4E78AFF234737DA7 +:1022B0009E13F519F65F92F55FBC2E12740ED46B67 +:1022C0009783FE53B7E617D8EFCD15A92C17E6DF95 +:1022D000D861253BB7579EA96F9B4F8E3F73798678 +:1022E000D093DD83817998F427E0E62C589FA6D51A +:1022F0004D65BF6BFE05C9E7DB52BD129A8CB05825 +:102300008630F1F5310811BCD79A826CEF39480F4D +:1023100060D966F26659B094CC3D8380E70909BB69 +:102320000A0216AAFFCA1469067C6F8DA73A8BE8C9 +:10233000FF4D70FAC92EBA3C7DED0492A3D5EE395B +:10234000F3E979BD9AEA6EC3FDB658E50D8564FFE1 +:102350005C2E79C9EED5E1A2EB8FF916AF95E03B83 +:1023600038287B55A4DFE297148789E1EF5069DCB8 +:10237000372CC14C5AD75BCECD134C66B2D342AE8C +:1023800009B8D9B75FF969C96FF0FDDF81328DEC0B +:102390008179BF72B01CBF1E64E6F76F80C272FC09 +:1023A0009B10E0FA8D10B17E8AEFFDA1FC7F1ED854 +:1023B0000FD17DFD61EA677BC9AE9F2F7566E6622E +:1023C000BB5A0D05A4677EE9F8C18E08AE4369B615 +:1023D0004012DA57BF243A25FBFDB02BF400F6BBC0 +:1023E0003D797B6A17D62326617FA9D5C147A9BF4E +:1023F0006A067F3396D9C9815F101FFE30458CD3A2 +:102400006071B8493E928145E3BCFF8E8BE99DF433 +:10241000EEF558AF406C11BC8E660A7A53FF062C5D +:10242000778F5ABDDD0A8D7B42F63E40AFCE30F34A +:10243000FB7052E67554C4E917DF7833BF0FFF9481 +:10244000F9FD693D16837EF14D32071FC3FD4DFF37 +:10245000876540BD737991905FBE41E660227BF055 +:102460002F1A7F2184245A4FF33E53A88D8950D8C8 +:1024700007153A3D42642DD15B254090E81EF6A138 +:102480001ED3E7C9E3FD7FA2FA880EB19DEDC1CE50 +:1024900067484EDA83824FB03E83F6E3088297ECBA +:1024A0003554C860C17A12BE28E4AE1BC88E6DAB2D +:1024B000824EAA4F838844F89E4E9046FC5781CCAA +:1024C000743B0314AEEB74FC1550B9BC04425C5E63 +:1024D0000A61A1EF416EF939CEFFD50F40EC675C80 +:1024E00098E91D1D1937DB8197DC6826BBC3F7F51A +:1024F000C4FE426A910E174488E7F4E1320B025998 +:10250000627E010F3B3DF745E1E188834712C1C37D +:102510001B8507CE21E0D107BE023ED314840FCA2B +:10252000A78BA147A27914CDBEA9062F9735E0E766 +:102530007200B83CDBE4E90B97B248C012284C00AB +:102540009F1989E966884657BF2E022E75F933BB5D +:102550004866B8E97208F9338BECD178F9A43FF7F3 +:10256000A5541F97911E7C45E9575A509FF98AAB95 +:102570006FCBC7FA8CC76451AFA8FE451ED667164D +:10258000E589FAA4EA622BC2ABC9947F650DCA99AA +:10259000FC80690BF1E5CA26B4AB715F81A43B8274 +:1025A00044C7A60C709BB07FA0A9C45B84F500D281 +:1025B0002520DCEC526E13C1D9FE3DF036E32A52E1 +:1025C000D302138B70FD850BBAD70A7C560F998FF7 +:1025D000FD3FEAB6B2DDB2CE160C129E90DDDD4DA7 +:1025E000E5D1FD7DF4D8F716D3F3C786829BF40BB3 +:1025F00078E462BFABEF7ACC0EE0FA52941B14FF82 +:10260000C0F92A69BE00AA2799D6F5732944F05F5C +:10261000D93493FD81DF16F8A717C58E8FFB90265E +:10262000D3BC42CF8127B798E03679AC7F368D7323 +:10263000D485F2358DDA051EFA2B571629B5346E7E +:10264000FC7373CA17D72EC37996238D909CBEA6B0 +:1026500028F0351A77B93932A2189FAD4E79C7C61E +:1026600074A1207D927C207EA5FD2E467A24BADEC0 +:102670002FF81539C0DD6BBF227E3DFE9E6B17F92A +:10268000848893F07FA5F383CFA0594DE35FCDE31A +:102690004B3D8B882E3F497FD5F627E6CBE182EE76 +:1026A00034B9B5FCE9CF997F9E324350D2FC6388A0 +:1026B000E1BBE54F2759C83F5CFE1708A5E0FB15B5 +:1026C0004F3EDC4CFE4E39FAFFE4272FDDF373E674 +:1026D000B727495F22E896FFF753CFDC477C7A693A +:1026E00012C7A1A6BD7A389FECA0E98723CD883612 +:1026F00038FAD41BC304FDEB7EC9DF4D67A3C7675F +:102700004AABEE207CAF40FCDB71BE15A6A0A85BF7 +:102710001D6E95E59EF093176BFBF818BAB72C6009 +:10272000B9A21E28A7FD6449C0F23124FC0919FF93 +:1027300011FFDF7238B496D609D21736923727D0F8 +:102740002FA67DDDF250BCDFD173A09CFC6EF28B16 +:10275000719F4B3B8DEDCB63F543023FF98E222DEC +:102760001E960339B4AF5FA23FF4C7D134EF823471 +:10277000B20FA7525C2181BCD4FDE3DDC9D55B8AD1 +:10278000D85EEE94881F2A2C89FB5F57A8C5793440 +:10279000FB7FC5FD12FB712BEE1F348EFD648D5F38 +:1027A00021EC65FE7D94F40AD199FC021A19643F6C +:1027B0008A35C3B6414C7337B59AD88FB14BB77AC7 +:1027C00049EF4F7A70C8CDDF65BA49754316D5A772 +:1027D000CC7FC8C3F655908435FA556C673E9ADEB7 +:1027E0009347F33F9A2E838AF33527F5E4919C555E +:1027F0009F727849EFC6AFFB454DEEE587276F8D99 +:1028000078049E89CF739F2FDF4A783E867C4EF8EE +:102810005BE11A33049C64375C9C15C1B259B3D395 +:10282000731F1A97568F70F1D17A63ECEAAE835713 +:10283000A490BDBCD7E24F7163BF6387F20C7E509A +:102840007C591246E4140FD0FEC69CFC4002B8EB43 +:10285000A56FAB85E1A5D3ED2F1B15F8A395F0511E +:1028600029F6A1DADD761FD15F6806F9932BBE0940 +:10287000EE36ECBDE2851F373BA8BE1E989A8FD17D +:10288000FFA8FF07E610D9E33F4C99786725D6F7F4 +:102890007C68117E8AAABC521863C7DAB3CC201BAD +:1028A000E8B55B5A4AF298E81EE935494E06398682 +:1028B0001E530A320C759777A8E1FDB4B23C437BF6 +:1028C000BA32CED05E0A0D9100AEA7244B7287704B +:1028D000C5836A8B0CED76A4EB30ADF3536147955D +:1028E000E13FA16F836C0F5544007E847430F52363 +:1028F000A39D5516E9607F33E990C51007B09F226C +:102900000EF53F3A7F0D87E1C45F48FF5E9263C7D3 +:102910000E89B893ACC173458ED0CF2B5E90D80E84 +:102920005CF1A199F5C431F0F6E287E4A3CE77F12A +:1029300070CFF41BE13C64BE11AED901235C872D3E +:1029400036C235276884EBC806235C7355231CF315 +:102950005BA71AFA8FEEA836D42FDA3ADBD07F6C59 +:10296000A8DE501FFFD05586FE133A171ADA27ED5E +:10297000BBD9D01E4F5793C32B0CEDF6D4D799AECD +:102980000E205D99501F143FFFDD38BAB030DC4B8C +:10299000863BBDA118FCABF88FF05FA1E525A680B2 +:1029A000DA4CFC78AEF03FB518F13F3E8A7F5DAE61 +:1029B000F6C7A73A7E0769FA1AF93342783F569666 +:1029C000C2F4F2F2F3C70E2940F84F8522DCEFDCA7 +:1029D000E9228E22C9C156A2936E707590FDB9CEC0 +:1029E0001264FF4545B3F00152CA71FEE6D7CAD062 +:1029F000DF8C59679D92049698FD4E0E771AEAC5B2 +:102A0000CFEF33F42FE90E1BEA930F8144FAAAE8C3 +:102A10004DEF335496BCA770F8ABF483E033549673 +:102A20007F1ABC9DF46FBC9F7B99DA24A5E1A2A616 +:102A3000FEA3F319346BD03F1BA192DF1BB935D530 +:102A40006B1A8AF0487EA799FC6F403BDA8ACA0865 +:102A5000BA7F43C884050EF1FEDF932E5E43FD4D21 +:102A6000E89F13DE112E0564EF3540B297E0427601 +:102A70000BF961305BD8F36B4D2ADBA349688F9269 +:102A80003DD25CE5677B79160487D3F32B4059432D +:102A90007C2799D17EC5E7C72F0AAC2C2E118B2538 +:102AA000FAB9FDB8CCFEF774F2A719980A90DE3B8C +:102AB0004ABFD3FA207CA5427110D265B8FECD6D15 +:102AC0004F5EA952DCC903EE08AE3B204006EDC5BF +:102AD000811F14A31C3E6272AF2DC6775F9EFAD78A +:102AE00011648F34150BBBCF2E21A49006862C5079 +:102AF000809EFF2047595D9C198DB3F4473F7A3C77 +:102B0000538F6FEE690C7369717B25A2BBF8B863B4 +:102B1000C4ECAE994CFA6F8589FDCEBFD2E2CA797A +:102B20009E5496F30EE8B6A7F392D9FFBF46C39B17 +:102B3000D9D1BDE67BF8DEB541616F2D3479D95F1F +:102B4000BF25EB238EA3D82513F8C81F4A2BDC25FD +:102B5000E22F7ABC6498742676D6A9F67B4BD6878A +:102B60008678153C3228617C3D3ABECAF08DD9E7A3 +:102B7000F6AD1EA1D7C8CF3FB23EA71A5213CDF370 +:102B800009C7AFAE091E34F0C5750D6F19F8E07AAC +:102B9000F55D437BC4D363A57865E4F1EC59145F1C +:102BA000FF78AFBD94F080F87FBA38265E17593FA2 +:102BB000BE06269ECE7EFFCAEB38DCD8CD78D5F790 +:102BC000FB4EE39B5C8F3446B88CDFAF1E1FD14BAE +:102BD0001487AD64CFDC2EA1BC207F97E485274607 +:102BE0005E001490FD7FBB34CE4BF46EDB1FFC09FE +:102BF000B5F734D9DDBB7C1C1FE1B84903D205D938 +:102C00000DE014EF2FB439D80EBDDE27FCE9C35513 +:102C10009F5D4BF66B2EA47A5106127FFC9EE22636 +:102C20000B4C69ACFFD7661FE0FA7BEB41E48D16D5 +:102C300087EF277F75796AAAB08B15EC8FF5A319FA +:102C400066AEFFFAA2C0FBCC8F8561CE6F2C1F222F +:102C5000E279E0898C203EBC4DF67F58CC7EBC3BAF +:102C600040ED8B33D0DF46FAFDC0AC4E34E1FBA320 +:102C7000F7645C6541BC7F90AC7E42164D8E2FF5AB +:102C80002AF2333FB009FE9DB0E7EFCCAFEF9924B5 +:102C9000F6CFD5274C1CAF0167C456877ED8E69186 +:102CA0008113347F8715ED49A7785E3F211A973D40 +:102CB0006AC592F83F49945F148B3CE4BF8A85FD56 +:102CC000AB97430866F87C8256CE94DAC750FCED89 +:102CD000D8363B90DCC2F915F2B7D4A7441C7F70FC +:102CE000867F0908BCB8D7E17A3DF9F271E23F8FDF +:102CF000847E2DEEC3EDCBE571F5782E39B0A9D8E1 +:102D00007EE471FB4EC25FEF7A0F8978D8C7EBC7BC +:102D100073BC5BA713B7862FB80140B40FDB49ED36 +:102D20004B5F38F20EC5E7FEA338E0F1E1F80BCDBA +:102D30007229C9C9A5A95D1CA71BE393F93D5C2FA6 +:102D4000EF17E5560BFAE2B0D411E1B8DEA9E2F7CD +:102D5000FDEDFFE36F766F29E478B53C91E48A3EA0 +:102D60002FAE638C2F26CEAEAF233ACEC0FCA3C7C6 +:102D7000A1F5FA9FEF5F3746CB235CE74FA097A7FB +:102D8000E9746C4D1CF79FEF13F88DC74FD145C107 +:102D900010C7F3DCE06EC6FA6C0D4E1F5F89FBE1D5 +:102DA00078883299F0BBB4DEE92538EBE30FCE80AA +:102DB000C0CF079867C6587F0DEDFFE6A0C813E89F +:102DC000ED487F22CEB93E85E975E9D36FBDF33D6D +:102DD0009CE5A69F4C2826FDA1BF1F0F6784EF1816 +:102DE0005ACF4249E4CF10BE75347E7C7EE06CE160 +:102DF0007A34A79BF5C2D19DDF09D1FA8E6683DBB9 +:102E000084FCB8F4C95FBD699A4874E20C4B58C29F +:102E10001E63FC2B5E4FB9217035C9113BCA11B23C +:102E20006FECFA7BC32D86F766672937FA585F2B5C +:102E30001B481ED955E1AFE507AAB8BED22AFCB59A +:102E40003DDD6699F87B8F0542A4C7571ECC50C95B +:102E50007E5C8976077B3A05415E2F24A31F949EF2 +:102E6000C06E307965AA57A6056E277849DF98713C +:102E7000DF23B9517F54D797259ABE570AAF6BA667 +:102E8000F17D5A3C10ED4C8E77964340B323B43815 +:102E9000DCFA031C87D0E5B60DE63B28FEB32E73A3 +:102EA000A183FC431987E5F89AA73E0D06B023D706 +:102EB00034A2A4BD285AB7F6E3C7EBE703788D83A5 +:102EC00069BB40C21ADABF7A20D24276CADC177BCD +:102ED0009EC5B26DC28391D5D4F6C54989EC4887A9 +:102EE0006607703198D629DEB30D5F7BAB09F567B5 +:102EF000B2D7024762F4A00339FF4881362FD903C5 +:102F000059BDEDBF25BCF5B78FF3556E40F81C19C0 +:102F10003D40BBCDBB3811BFC7C32B49C36F52E186 +:102F2000AC0FC9E04D82987DB3DD135397A2F02218 +:102F3000D54DF8B746DB959309F297675A12DE8FA5 +:102F40005863EBE183EF19EC8110AFDF6AF183176F +:102F5000F767F360BBE11C86AAC5C191804B357A47 +:102F6000603638F5BEC82EFFBFB52F1AD73FF8829E +:102F70005E9F7A81AF2F7C81E317EA2E6CF829756A +:102F80001736FCD40B7C7DE10B1CBF507F61AF4F2B +:102F9000A9BFB0F1AB5EE0EB0B5FE0F885CB2E6C28 +:102FA000F829975DD8F0532FF0F5852F6CFCAA6CAB +:102FB000073A2B81CFCDA6B7984374CE46AA0973A2 +:102FC000DE384F058E47A7AE07CE57ECF20A3F4AD0 +:102FD0008FD38FA52164F45BACEE6CF2AB77B5DCDC +:102FE000557D038E73220B174FF9FC9CD7151A677A +:102FF000E74CE0FC85B3E5FDC314FFCA85B0379C00 +:103000004B713509C23176E935C11408C7F813751B +:10301000CA2043BDA47BA8A1FF8D5BF30DEDDFECBF +:10302000186F68FF466BB1A17EBD5A61E86F87DCFF +:10303000B602CABBB658BC9407B3D0DECAFBC20DF9 +:1030400076DBF83D05FF911F938B9E50EFB8B88F4C +:1030500074D56618D719D77EAA7C407C3EA1A654A9 +:10306000CB27F47EBF20DE07B72761DC53CF27E8EC +:10307000F81C6349627C6D5245BE69DD4CE147CE68 +:1030800068719B286FA9E36F3CE83F6E33F99B0F93 +:10309000350A7F5287437A48AD667F74B7A08FB1F7 +:1030A00035E6109DC39D293993699C1092B41BDBB2 +:1030B0004335F59CD7D4E9607CCDA239145F6DCA45 +:1030C000199C4DF184DC1A81F7E5FB8CF8A6B42D30 +:1030D0006D29FD90C4EB4C6FCA28A2BC5D1FF83F60 +:1030E00022E0A99F334F8F83EFD89011FEF1F8397A +:1030F00053F8AFFC92F0B7D5CA5D69140F5541A6DD +:10310000F8CB733963CC0C87562FE3A116BB113C67 +:10311000735B81F33AF174D7DE08E19A183ECDF57E +:10312000861582EF4CA9B09AF909DF1D027C1A942A +:10313000F3EC3B5B459E16CB641A1FF6C943099F0F +:1031400021B59ED7BD6BBD2D99CEED7DD664063AD7 +:1031500017BF2B571E4AF9AF5D4F98E6C79E034233 +:10316000ECDBCD59BC0FBBB98C4B8B2815AD048B58 +:10317000680F4B541FB1CA1C874F55A2F6F4DAE40E +:10318000B8E78A89FA6F28CD63BF344DC930E0CBE8 +:103190005A66E46B04E32B85280747D2EF32D195BA +:1031A000A093D06B526835C7517A4C8B896EB4733B +:1031B00015E96BEA81F24E4D39DF9ECF72AAC9C67E +:1031C000708755822EF4FC9FB555D0613CFDB8BC8C +:1031D00046FAB14AC34D228F25F8445FC74E459B3E +:1031E000375B0295E59B6D28F181356E3C3B0949C3 +:1031F000922B1EC17F4EA8077ACF5966E77C3548CF +:103200008719FFD629008362CE23C4AFF794EBFC65 +:1032100092747EF01CC9999D35E2BCEABA35E27C15 +:10322000E389E7859E98D1EA36B3BC0199E50BD2D4 +:10323000C1DCEC52717E88E0D9AEC91B3BD4A551EC +:10324000BB4EE7B3A4E155B1748E72E44517C9B320 +:10325000172C1CCF5C6795AB6FA0F672BB7B35C398 +:10326000B3B088D6ED6B41B943F1C26E01275D5E04 +:10327000C4C3AD0862EAB9443A89E1D89F3EE893F5 +:10328000FFD7E1588A70CC3F7338DABC42DFA6978B +:10329000097DFB5CCEB7F955F721717E265D0106ED +:1032A000DA7155C07596F45198E4CB2605E50BB656 +:1032B000D76AEDEE32214F7438E78925F6CA934D6F +:1032C0000B2083F8DE4D7076125CDF67FDDC512247 +:1032D000E00C10E13C67AA22F8649D15BC148FED48 +:1032E00028777A292E98A768F06DD5E065025322D9 +:1032F000F8CA71F04D8DAB9F297CC74CD1E03B18CB +:103300004ACF06BE9B525205BF8D12F0B13A237CC4 +:103310007EB935D7E25D8D74D8958BF0C6F6D6D7D9 +:1033200004BC7FA8F55F3301B8DE9AB9368BE1950E +:10333000BB288BE478ABB543A57C552BD11F9FF3FD +:1033400014E7BF5C1A5DCF44FE5E88EFAF45F944D9 +:10335000F9C6D4B28083C66B2DB480C4FBDFE64DC2 +:10336000B47F87CF669083C3161BE19A1207C7A468 +:103370002FC9FF7553BE1CFFDF49BF62BF75A39104 +:10338000E538DF1872109C6C657F71101DB595EDE6 +:10339000E2BA0CA1D63CDCFF1D4E6167B595D50F96 +:1033A000780E6A972617428D0E2EB737BA51330121 +:1033B000DCD598C5F58E4699CBF6C6022EDB1ABD34 +:1033C0005CB6369671B9A651E1FE527951157F0F60 +:1033D00036876915DC8E4FC061EE3B5F7EAB518F47 +:1033E000E5AAC906B88F6C30EAAB41B5467D95AE0B +:1033F000E419DA5DDE7186F694822243BD704AA03C +:10340000794A099D8B9A6A78CFE6A936F4D3CFD151 +:10341000B59589EFA174B8E97AC9A9F1F73A6B2497 +:103420008BE2D8CE32C19FEB35F8B56AF04B5680AF +:10343000CFC5D80E49DE1010DFAF65FABE03713874 +:1034400004E1D295738542F6419B2CEC742B887372 +:10345000BDB62CBFFA0D7C9E847A8BF2B6B6F929E4 +:103460002C0FEEF038BD748EB6AD6C859BD7E3158E +:10347000E765DCF82F519C3FFEFC8C6394F1DC8DFA +:10348000F514E7171F9C12FF3DAF46A7951909E5F4 +:10349000471FF9DA9B5FD96FC8AFB46BF9157B3F53 +:1034A0007248D74F7ADDA9E55760B82F61FFA81D94 +:1034B00025F2071B292E1F937F705526FE7EF3B938 +:1034C0002912AFF3E01499DF7359BA81E474AACFDB +:1034D00018B7772967363FFEF83C8349FE02CBA533 +:1034E0001B92030789EE9447847D92345CE86D1B40 +:1034F000282ACB2510F90EEE6FA252E4737AE50B61 +:10350000898618BA73F6F16745DE833EA320FAB1C7 +:1035100044DF3F27FEEB99962D8D03E77F5AFAC9CA +:10352000FF7C3E45FF3E0C7A3CA500BA6B8EF0FB5B +:10353000BC1FF885095E2DA64DB57964E7F92C5EB0 +:10354000C4005479E57D948F5CA3A4B25E5FE395DB +:103550003B890F8F2B4E2FE16363610D59F090343F +:10356000FA59D63F2D74BC26060F7ADE0914A5BB86 +:10357000468733E9DB82DAEE9A18BA583F610BE7E7 +:10358000EDDABEFA20E7F3DAE6FE94F3796BB3677F +:1035900015505E38C93BEB43CEA3424C5E8AF447DC +:1035A00081317F77F2A4A8331C28FEA0E5F9C0631F +:1035B000CCE359647F743D70EEF104C385FE018B4A +:1035C000C2DF13F4A56FC1D77ABFFEF940D5BF2B78 +:1035D0005D4DE77F5B3D428EB682F7CD00D55F92B1 +:1035E000BCAA4CCF8BDEA4F3A46B875B182F6BB304 +:1035F000EA5B85FD2EFCA556CF6A961BF1FA9ACEA2 +:1036000063C6CA6B3A8F192BCF5BE5FA01F5717669 +:10361000C01CA7EF8DEFE7048D7A477F2F29EBD2EF +:10362000576B62CE43ADB7F81D242FD678EE320526 +:1036300062E8F9474A606E5949B46ECD9ACBEFD92A +:10364000737C09D7355B51EACB3279FF03DA019BF2 +:1036500035B9B845D32FA7DAE756ADFF8FB4FEDBF7 +:10366000489F5F14C5CF98516393583E5F22E43161 +:10367000C13C76DEC2B2C0E2D87D10D3F4C205E907 +:10368000744CE1B824B2379A2F294A223CDD3D67B9 +:10369000E0F5E87973BD9F9E278DCF9FDB3C6603E5 +:1036A000FC7795897322CFBA1655FF08417377AD21 +:1036B000A0A7E64B845E1EF388D8475F3A34AEF786 +:1036C000EEDA81ED9FF8FE1439ECA513AE67C4D590 +:1036D00087C6F5CF8B6B1F17D75E14579F1AD7BFBE +:1036E0003AAE3E3BAE7F7D5CFDAAB8FE0BE3DA6FDF +:1036F0008E6B5F1157FFAE119FBEABD212C1311E50 +:103700007F7ABFD3C5DF6F7D553F23FA1E03054C7B +:103710002F3ABD9D2E1EA276AE97E9CC56366E1F6F +:103720009D8FBB0BED2BB287EEAEAD760BFB22B0BF +:103730007AAF461FA41F2C5F15F374E59426B13FA2 +:10374000ECF418E4C8A9F06D820C63BB12637FE649 +:103750009D7B7C9F9A3E439A7E1C78DD3A1F174ED4 +:10376000F1BF43708790F02F75BB76A72AF867A743 +:10377000BAB07A33C9DB56B3882F6BF79D64D0405B +:103780001C070F684A3862227CB712FEEDE4070876 +:1037900079B25193271BC83FC0E749A3825B29AE8A +:1037A0009B7C888FDFC07A5FD1DF16127ECA4B7791 +:1037B000D2F7611B26943DFC63ACBBFE2141B818D7 +:1037C000EDF3896D0AD92C1D4A46129D174A3139ED +:1037D0003AC93F5C53DCE11F85FD36EEFFB0F319BB +:1037E000C4B39C65F326615DB6F49888DEA0D0CBA7 +:1037F000DF9DE13A55F2FDAC953D8D89CE956E9CED +:10380000ED369173985E2B9B557A6F4AC0548EF0BB +:103810001BD90A663A479CA186F9AC4D75B9CCF222 +:1038200065D713C850BCDF9E6C82D767EB6DFBA9D0 +:10383000DA3F3E40D2E2736755EAE3A409D2A01F03 +:103840008EC3C816ADAE6EDB46F78F3825511FFF0D +:10385000C48E05AB0BA3F5EC27760CA77A7BF10899 +:1038600013C9D3744F6AC27B60A6970BF9B96BFD7D +:10387000A2918101E84B267F6D0896855A4934351F +:1038800005CB515A296BCFB3447D0AC10DE12937CD +:1038900068ED1E519EEB79E2C757CADDBA9D38D458 +:1038A000CFCE3F143A071BECC5E9E599FDDB8B68E9 +:1038B0001E739C7687551E4AE70477ACB701DDEF8F +:1038C000B02307C477C66B6C7C2E142CEEA157B8BE +:1038D000A2EB0EAD19CCE7CF432630C46F2DE5C265 +:1038E0006E3D5E6ED2EC9E2FC2F49DDE0E2D8FB328 +:1038F00003226E8AD747F1FCF0022506CF0F957F91 +:10390000BA8DE8B32B6751F5167C6F538B99E3257D +:103910009B5AF298CE691CB28F4EAC7AC54CC1A5A9 +:1039200042E834939D3F8EBEACCEA72B8E025C76D0 +:103930006AF2F967C49F38F16850F8F908E861E065 +:10394000BC511AB89EE0924FA24D22FE91CD0E9C22 +:1039500067D993E95589F4F62DE5BDF6F8624BA9D0 +:10396000E65FC80CDF5BCA13D8E374029FE38D8A5D +:103970007F29B53BF71D0C0FC3EADE378CF449787D +:10398000AB8FD133AB35FA747BFD0AE1707669E019 +:10399000DBF4FEB2AD7F3B40E6A8ACBACDF4FEFD51 +:1039A0001ADE178583B3689809DE7035F51FDFB01E +:1039B000733FC5D10A82B7560FC1F58D51EAAA3DB2 +:1039C00044434AA091C619D51DA97261DDB9F560BD +:1039D000389BD73391C7CBD3D783F450C774E41641 +:1039E000F17B0DBF847F3A97BC689B800FB667F36D +:1039F000FE2CEEECD8F5EF9C8974E1EC4B170DDA58 +:103A0000BE3647E10856A35FB339111C753AD5E1BC +:103A100071ED233D6B2897B920D4FD1CC941FF5699 +:103A2000F74C2ADDA581FBE87D5F87BF99F37C7B9E +:103A3000BAE9BAA15EF838956E4A1B613F653BE171 +:103A40007DC7AA23D51C97D907C2DF89D3877A6996 +:103A500055E2F30BE23E9C49FB8C7632D2ABB2C509 +:103A6000134BAF66CE5785347D126A45FAA5F956D9 +:103A700009FA0DA92BDC89E8EC414DAFECD6E856EC +:103A80007F3EAA9F73954F97EBDF9343966484E73D +:103A9000D303F17D1A78991F900FF653BF0CE20300 +:103AA000AC8F5C25333DE87CB06CDFDF0E0C637FB0 +:103AB000522EA2FBD9F4795FD2E645FA7C91DE5F03 +:103AC000B6B5E700F98A235709FA7C95EE06CB8C48 +:103AD000D219FA8FBFA17E3AFDC4EFE3D71A5DB8C1 +:103AE0004BFDAF121E176D0DF278C83FAF31FF6C62 +:103AF000ED0E2731CB29D5B49F1D1DE0A6FDD8BF03 +:103B00005FD44572E1448389E17A5D61788D19CB98 +:103B10006B468195AE13AACB42B2C9A33CAD31EF3F +:103B200037BAC3883FA49F3FD23C259E804D04AD49 +:103B3000833696A7FDD04554EFA93AFC57C5C9DD99 +:103B40004F0694BBA739EE774B954F699CD35EC760 +:103B500069F6D3E34D7DE3A6E39289AFDB5AEBF53B +:103B600038552DDDB7B38BE2A608D735AD03DBABF7 +:103B7000218D7EB76BF47B971637EDD0ECA23B4ED0 +:103B8000376EBAFE5815FBBFAB80E340AB53269AA5 +:103B900012D14DAE6AE4CF910DC9717152A3FF9A53 +:103BA000AE18E3A6F49DE799C44DE3E3A58553025F +:103BB000E3A796F48D9B42E45D839DB9A655C805A5 +:103BC0001D7E636A6EE2F8E72E8F3914FB7D845EFA +:103BD000B66B70D3EDC936821BC3B3408B3F7B35C8 +:103BE000789669F0ABE5FA18B2E23C1C471579F714 +:103BF000B177CD5F4870CC02CE1234E53C9895E8A1 +:103C00007C3D64C5D8D148FFEBD66B79B42CE0EF8E +:103C1000439FCB79BD369FF29A59668ECFEEF2EC78 +:103C20002FF831D79399EFACA07614E07C63DE9B3C +:103C3000AFD27CBBCAEC6E711F07A4521E48CF4B9B +:103C4000E8F99CB64C91CF711568F99CB8F9ED7004 +:103C50007D7507CD5F20FC977EE9D9A7E523B43CAD +:103C60005046A1315FE188CB57C4E72BD7AD5FB891 +:103C70007F9788B3B09C1E73C3D864BFABEF3CEE94 +:103C800039463F6EDD58DD9F7AD091089EA93546B2 +:103C9000BA6CD3F0DE9C29F211A71A1F2A930DFEED +:103CA000555BC1E9C513F47EE48FBA13F48FF7476F +:103CB000CFC6CF75F3F8C63872023F77C354115799 +:103CC0006179B26EBDD87F6F5C4DF3AFF47346FA85 +:103CD0003856CD9FE37A6E545EE9F9B0516E1BFB06 +:103CE0006BA3B47BA19AEF4D09ADCEA5FCDADC1E27 +:103CF000CA478EDA2D71DE7D94D33F94E2AA5DF738 +:103D0000CCE2FC78767260C7D498EFE076BBBE9DBB +:103D1000C579032DEECFF7E3A0FE533715772B645B +:103D2000F78E05BE4F27392E2F107F0F4E9FFBD8E1 +:103D30002A841ECBBA1A12DE6FF2BBA9426F46E587 +:103D4000AE3F59F8F1B3194E0F74D4270BB9ABE855 +:103D5000F501FDE073256F1FE87885BFEB39E103BE +:103D60004DDEFE0C2E4479FBBBB2C05B09E5ADA570 +:103D700087E5ED235394B709CFD7D3851E8487EB0E +:103D800012DFC3E3AAB850F1F098C043A18E873B7D +:103D90002091FF7801E021B922111ED0BF2278A91D +:103DA0003E25A52293E2A68A93FAF5E2E3EB89F990 +:103DB000A2E23CE36393868F3BB5FCED460D1F1BEF +:103DC000081F76CA570A7CACEB838F23021F653A23 +:103DD0003E9E3E2B7C64D46418DADD95467CA4FAC2 +:103DE000F20C7567A1111FC9A38A0CE35D5F218BDB +:103DF000FB90864F35F4EB8B0FA35F10A0F706F016 +:103E0000B38607BAABE81BABA1F33BBB483667F9F7 +:103E10003BAAA8D4F7B92DCEAFD3CBEB35FC65CDFB +:103E2000488CDFAF69EDFF2E57E656C4F2E7571214 +:103E3000F3E7E59A1C0D9429F30CF47369E2FE573D +:103E40006BE37F7D8A72556C7FFCD92CC5D8E5FD6C +:103E5000EDFB8664E57A7A2F6B86CCF1D4DD4DA933 +:103E60009C3FDB9D24F2656A93D3703FDD48FA0DD9 +:103E7000EB59DFF8A24BA57376741F105A583B6FAD +:103E80001D9CB70E9B76668C594D70FC56453EAF17 +:103E90002B7F89FF6DCAF328EA51933887B480EFEE +:103EA0003532850799E83E2C70679C561E09E599C6 +:103EB000B8BF6D2488EF8521C87A50F2433A7D9FC0 +:103EC0006C01BFC89B537FF11D216F3E05C25C771B +:103ED0004184EB699ABFB7AE2297C74D07D92480BA +:103EE000E435911CD5F9D4E10932FD7B1ADCA6D565 +:103EF000E4D3599057C91F740EE7EF76A11A54CA3C +:103F00006B99C0C1F6A669F381CF395FA77F67F8C7 +:103F1000C220F19DE169EEEF74FBB5D0FD7B9EE818 +:103F2000FD7B2D9A3DA0DFBFA75607F93B7275B503 +:103F3000DDDDECE9FB1DF9E6A9819D44877F4F1A81 +:103F40001112C9E6E0947AD7391DFFFF9CE7F19F73 +:103F500038CFE33F47FCD0DFF81BE8D772CAEFF950 +:103F60005FA07ECDAE52B63BF5321E6FB3D1FFA738 +:103F7000F54A8E5787BE37286ACF390F9BD82F6AEC +:103F80003689F367EABB26B6BBA050D08153868240 +:103F9000DC49D1719CDEE048117F127198A6DFDF09 +:103FA0007E11D9DF3F4C991B49C3F15E3E28EC3F9F +:103FB000CB8CC836BAC779489ACDBB0BF9EE0E6DDB +:103FC000BDF6F22977DE86BFD64F376BE71CBC976C +:103FD00014F1B9A53911B21F5DA516997206CEB8B4 +:103FE000FC66BBA583CF19B7EFBEAB6A1CD039E521 +:103FF000E7DD2DD6BEFB746AF9CDB1526239F89770 +:104000006949422EF98CF7061FABD0CE41A5422A52 +:10401000D991967F2B6989CE05E8A53E7F892752E5 +:1040200043DF5947E8B236C47349595D52B287CF6E +:104030004774137CABBD6107D9BF0F2F0CDE14FB97 +:10404000DD797B19B8C88ECF9D2ECEC3DEA3482E56 +:10405000BA47E3BE8885EF17BF6FC963EB53B0BEA5 +:10406000EFB0D94DF068F7BFEB4CC6FAC3382EC994 +:10407000BB97778B7B26D505101A8DF06B27EF1237 +:10408000EB7B15E073C0EC90956A57F221FCDFB929 +:104090003853C01B8275743FE7A6948BF9DECA9C27 +:1040A00079222E3C4B3ADC45EFDF576667FCE56B27 +:1040B000E7754C6A1DDF5B99B9C0785EE7BE95DD98 +:1040C0002AE1D75D6E77D33958909CAE89F8BEEB64 +:1040D0002766905835F6F0E4B324A75897579CA369 +:1040E0007B580EAB74AF7126BED7E4E6DB110DE74B +:1040F00082F66E15FE69DA64A717291DD71B776E45 +:10410000485F5707AE8BEE37768DE2B844C63CE386 +:10411000FAD2E2FC06675CDD5BD97B5FCF18C2F7A1 +:1041200071FFB78B5FE556AF9CC8FF6C6F84EE9A4A +:1041300098F309CE7EE281975F2CE8DA96FDAC8396 +:10414000EC94E3FED73D848397FE75E03D3A2BF770 +:10415000D2BF5FDCB31CE1F39BCFDFDCFD28EDAF0A +:1041600061C32B44AFBA3FC66730713DCFD5D91874 +:104170006EFE5AED3CA7AFEB59AB8FDB39CFB47174 +:104180007F12B78FAD845012B68FB528D9DF24BA0D +:10419000EB96BC4D320D22CE23EAF8DF78ADDF047A +:1041A00013088F7E89EEBD9829BDA4B8F0FD7B96DB +:1041B000804CF8B72DE9E4F3EABE95E2BCBA4FA90A +:1041C0004BE2F3A6F3CC7C4EA4A9EE8A4B46637D6A +:1041D000CF25E21EAADA95CA953CBF22E825ADBBE1 +:1041E000D4BC92E8325BDCCBA49F372D811EFECE7F +:1041F00063ACB7B3CB46F266010298D6D7AEE14BBB +:104200008B1B94F8BA55B2275D5E231E33E2F0167D +:104210008FD79B743C8E85B18447193A92491FDE33 +:104220000FD049F707DCB3F2B12BE95CDB71358DB8 +:10423000E1D51F3FBF83F6AA7211DDB7E2E0B21BE2 +:10424000ED552AF7A0BD4AA52B5875F54A5CF7E352 +:104250006FBCFCFCD771BAB94ADDA57C544BCB7F4F +:10426000012C1A518D70BD96B857D4B72BA300FE00 +:10427000E0930CF58D1E4BF4DE7FFCD595ADFD1D56 +:1042800000F5C4764A40B66759B47C9BA8CF253F59 +:1042900024A67DEF1C63FF8AFD31E357E27A97DAAB +:1042A000B87D63E5A2EDEAA868FBC7D3B03E1CE089 +:1042B000A0663F5EF380D9BF2B817C7BA952D87169 +:1042C000967F834A72ED5319D8BF97CC0ACB77C833 +:1042D000B3C889EECF03407918EB97CB46F95AAAB9 +:1042E000F185C55F055A9E0CBED0E30FF8F3F8EFD9 +:1042F000E6F2BD4B6BF22D7CCF10EA03EF40793B29 +:104300008BC7F297D8FBB97EAAD3C168184DF37F4B +:104310000A95BFAD623E88B99F01D73DA3E399617D +:10432000CB711EDFE1648EA74AAECD29344F4B63BB +:104330002BCBF31F29813D9531718A96F445C52415 +:104340005FF4F332D1FB8DAE309FC9FDF65D75078A +:1043500080F4C2A7485AF601E8B0A571DFEBB48E2D +:10436000B58D9D5C3ADD0A0B1BBB25C8719FD94AF0 +:10437000E0C5CA12BA570FDB63F8C4EAC6F70C7E71 +:1043800087F1DE4DD91D7112DCEF29FBA393E66F97 +:104390003F24F8FA9E43F57C8EA1DDFB4A12F1CD55 +:1043A00071BAE0F14BF0894F39C8326CEF1BA9D7D5 +:1043B00010FD3CDE9CC676C5CB2BEFBE8AF8E7BA73 +:1043C000EF5FCEF0EEE51BF5DE11D585317CA3DE87 +:1043D000CB74DDCB375ABD7FBEF944F0452FDF8863 +:1043E000BAAF100CF597E718FBF7F20D8D8F7CF143 +:1043F00070959DDB3F7DF25E03DFFCE1A97B8D7C48 +:10440000F32DE49B0472BF789A46DFE7986FFE3184 +:104410004DE3C7F3C437E9D3B473B55F9E6F864DE0 +:104420002B391F7CF3B8E96CF866585FBE993CEDF8 +:104430002CF8A6DD1DE67375EDF3CC09FF0E487769 +:10444000A5C0FB8C0581EA0EB26B14714FDF4C697D +:104450004EB6CF437C26D15DD1A83F853E7FF99AE9 +:10446000DEEF33583FFB353C6E2684929DB454D02A +:10447000CDAB8D22EE3B5372CE5C4A7A97BE23A021 +:104480002BE3E698B8DF65A8F765B20BA1D3948952 +:10449000F3DC83EABD43A62D07EB46F3F861B6CF04 +:1044A000F2B53C80532A14DF3329E2EF5BE8DFC525 +:1044B000CC9B63BC4776C829EC261C2085FC18776A +:1044C00099F87B2757EAF4D3AB7FD10EC1F5750F6E +:1044D000B7319DDCA35C36609CA8CFF96A5F306180 +:1044E0007EF2C0349320464559342D93E4CBF664D4 +:1044F0003A2FF1B8047C4E6741F0E75712DFB95408 +:10450000216FDA57FD89D292B067E6D78D7A5A8D3E +:1045100018F5B41A31EA69ADDEAFBC81F78D7A5A6D +:10452000ABF7EA69ADDEABA7B57A54DE440C7A7A14 +:10453000F55391ED6A4CFBCB54AF3CB59EEE9A76A9 +:104540007EF4F490F3ACA7779C3B79F3F0F99137C4 +:10455000AF9F95BCC9E92B6FFEFB6CE48D6B5B973D +:104560004AE99945FDF0C137353D73A042F9158DF3 +:104570000F65A717AF89A7AFAEBA456BE9EFC77C48 +:10458000EA15FE5F7FEFBB1A7EF17A4B8C1FAE7F80 +:1045900097E06A789C9FDFB8ED20C7634FB95EBA99 +:1045A0000834B3AF5E45BBC8C1F4EB35734EFC6C49 +:1045B000D7D13E4FF05BD9B4C5CC4F7FD7E28FF156 +:1045C000F66F579DCDCCF3950939DD9F3DD4DFBC07 +:1045D000DD95B2E1FB0C7DFE78FA45FAFC37C9297E +:1045E000A4470BDDFF7DBC1BF8EF51FDE7B12DBFEC +:1045F00056E40B4A2F7A283470A6745AACE133C1C2 +:10460000BE732E2E399FFB3E67FC597C36FBEE9A1B +:10461000067A5C3B7EDF95E777DFE7CC7FA8BFF8C3 +:104620002CE4D24B95BDFBE6EF5232B47DDFF3AF05 +:104630002BDEA5B8C63DFFBEEAE714D7B8EBF38280 +:104640009D14D7D0EF8F4B83E88FAC7F1F8970719B +:10465000F9C5772519F362BE2F02F6EFA3DF9F900D +:10466000BDE1EB6DFF7F727F1CD9274712C4197B18 +:10467000DB6DC6B89E5E4EA53FAA85F4D56EDAC442 +:10468000F1887BD0AF6A42BC75CD13F18876B45304 +:1046900058EECC2B1AD03EDAD3A870DCA9BDD1CF0E +:1046A000E59D8DB55CEE79755905C95DDFAB4B585D +:1046B000EFF9BCFEAB7F8C407257BDE7A4E7777A79 +:1046C00074FB44D82F6964BF60BDE3E9B61DB1FE39 +:1046D000CD90E939AC0FF4785547568CDD23C7F8F7 +:1046E00051582772E9F5A3A83E2AD6AEC9613F6AA0 +:1046F0002FD93558BFFFE91C835DA3CFB3D10C8BF5 +:10470000C9AED9B8DB5C9BC8AEA9A84CEC47619D8B +:10471000F3200E9783BFFF97B4BFF315E59781EDA4 +:104720009AB4E9E7D78FFAE5C5E726FED0CBC79A5A +:104730003DF323457956932B5F527E6C3153FCF841 +:104740004CE5C758921F8506F9F1F6D9C88F8A4AF9 +:10475000B7212EFAB2AC0E9A4876FA6E3334C99A63 +:10476000FEF5907E05FEFB77DFAA92D8CFB9C70B86 +:10477000FC77FC66490B5E207AD8BBC4CCDFBBDF7C +:10478000A7887322F7CF13E7AA7EBCB2A89E3E2764 +:10479000DA9472ED86248A6B575A80FACD922A39C0 +:1047A000CE7D5FADB073729C9D97D0FE5FAEB200C0 +:1047B000D1D5A9E2DC146EE778B57E9E4ADAC67ED2 +:1047C00087EBEB16379D5B8D8F5F3BCBFECCDFCD50 +:1047D00083F4127FDF7DAAF8F599C6ADEDD37BFF98 +:1047E000CEC0D9C6AD991F2FBF38E75AFE0E218E15 +:1047F0003E9FB958E64A7F7A2C9E9FBBEA66A54544 +:10480000063817E524FB29E6BE58A725CC7454A129 +:10481000D9514EB29F8AA374D155573AE0FDB329BE +:104820000D4FBC1E9B174AB174F278290D4FF2F35D +:10483000CD747E81F665F1B25C7DB81AE57382F1C4 +:104840009E6C0C1E22B8FCB2B1E110C5A9A759BAE2 +:1048500025FABBADFB1A55AE3FDED8CAE59EC60EA3 +:10486000EEB7B9712B97773586F8F99D8D0F717D6D +:10487000436327D71FCE13F34CB584789C693D382A +:104880007E0C3F547C80F3C4E0B93CA21ADAA7BC8A +:10489000D96A682FE9EE30D433FD5B0DFD07D5866C +:1048A0000CED072A025F9D9E49E71A1E32F473162B +:1048B000761AEAA7EB2F9CEB7EAB53522DFF447E7A +:1048C0001D11407A423A4B6F9055CE9B2F167C3982 +:1048D000A4C11BA6FA76978DF95BA74B3EBB6C1261 +:1048E000EB37C5DC47DBE5B2B1BC68CE14F194E62A +:1048F000EF88FAF66C715E724C8DC88F340F17E733 +:1049000030F53CFC7697C89B9DF0897B3446144675 +:10491000F8928C11DADF7D73568AFC991BDC9C9F20 +:104920006F6E04ED3BC508E73B32C0EC15F7A82BD2 +:1049300032FFDD240B849A70BEE642B77A23C99910 +:1049400060AAD7ECE53F211B32531E91C4132761A7 +:104950003A35BDA3E5E593FE087CEEA0173E9F889F +:10496000EF121A7AF87EA6210D3D9C8FDBFE7D7139 +:104970008F4D3C5CBBBEFF19DFABB4E33B9F6513BF +:1049800053EFE83DB7D363F82E6DFBE254BE6F6181 +:1049900047431E9FA3D8B1587C772C83D8EFF625C8 +:1049A000363E87B1A3C16C263979628925A4C33B01 +:1049B000A49F5BA1FF158041BEE8DF73DEA59DEFDC +:1049C000E9D0BEBFBA433B6FD5AE9D976DD3CE5BEA +:1049D000B56AE765D7D2F91E3BE919859FEF68589C +:1049E00021CEF70C07ED7CCF270C670BC299E2387C +:1049F0003BACB0CF3409E80F1732FCE2BF971D542F +:104A00009B1C77CECA78EE2A2DEE5E2197D778EEE2 +:104A10002AA5605CDC392BE3B92B7B96F1DC95D5BC +:104A20005D6D3C271A4BA70854D3AA2D4D4407BDF2 +:104A30007FCF911E0EE6BF17C7FB53280F85FBCA19 +:104A4000AA15743948FBFE259DCE85E493FC0F33EF +:104A5000BC5D44AFF9746E44E57A92F6FD9B7EBE70 +:104A6000A43F3A3ADBFBFEA5D589EFFBD7CF1FBCAD +:104A7000A1D94F0BA62BAF4F2F89CEA74E57DE8C57 +:104A8000ADEB657FF2E0FF9789CBFF0532DED6778D +:104A900000800000000000001F8B080000000000E4 +:104AA000000BB555CF6B134114FE36BB69923669C6 +:104AB0001649B5211536C668031122A6A59588D3D7 +:104AC0001A24875AA2F4E0C1430E39F9E3EE6D537C +:104AD000158A92D218C173840A160AEDA17F40AAE2 +:104AE000C1736AAB281609B5F42CA87829C437B36A +:104AF000D9264D36B5170792973733EFCDFBBEF762 +:104B000023CF41CB0F4462EC9AAC0123895AC549AB +:104B10003214072B4581E92A4937ED2F1A526532A5 +:104B200029808BD98434F574AAA62864A7B6D9A5A0 +:104B30000FECECE2DE18B71BE05211F2DCAE13F022 +:104B4000016B49A9F42C08CC6DD0791CF83D269551 +:104B500010E4C1EDD7EBA3C21490F917EBF79F0453 +:104B600066F84F7AAF7FDC379021FF0B3A503ECF8B +:104B7000EFDCF172DD9D284C6A144764AB0A85FCBA +:104B80008D54A19E00C7F78381F6674F5F97157A12 +:104B900077691E3845FB73F65AF22EDD5B1B77A84A +:104BA0008F62DCCF94FD019D4F0764C85C4FDB77BB +:104BB0006A142A2448F533C44F4231745A75FADC1A +:104BC000448B4E714F737DB8A97BF743132AC5F50B +:104BD000703BB852196EDA852814BE7F89797C7BC8 +:104BE0007DB41141A42E3771D4F9BADA29FFE8DA7D +:104BF0004AC5CE71C2C6F98A6FD94A417AA7FF6306 +:104C0000B197E393AB69B946F64812EA71C2B99518 +:104C1000F6E2087FDF387F0E605B770A59D55521B1 +:104C2000D7F44121F7744DC85D7D58C81D3D2664F9 +:104C30004D1F1312C8897C3A2488F7DEE8A9CD6499 +:104C4000B8FB7B1129778BE71DAF14BCE6791E8A70 +:104C50000BBB8E7B25F2D3C217D1258AA1E279390D +:104C6000C1ED5FA46C70907D31A1F9D3D14EFBE210 +:104C70008D492F2CF64D99D76F6F3EB1773F77F75F +:104C800020B36A61FFB851C74041C41148D8C0EB96 +:104C9000D7EF844BA5FBF97597A8EB50CC597271EF +:104CA0007C7937BE9B38A87E16EE1704FEA54545D5 +:104CB000A59A3AF0EB89513C2D7515606F0779DEA6 +:104CC000F257CA836992C58BEF3F9F25BBDC868C68 +:104CD000303AE37ACA241197892BA0AC4AAA45DE60 +:104CE000BBE1BAD7B0C790CF980B6DFCB7DF37F3F5 +:104CF000CE112AA38D16A595EDCD2C30DA67CB9277 +:104D0000E0C13504D1DF3D60658EF718F101978968 +:104D1000E7F24826E76EC6D32D4F661C7D8DFAF369 +:104D200067355786E7E11F75E8B61BF92A646DA958 +:104D300092451CCB8D3957601F9CBC1F11B58EC38B +:104D4000136BAF53239E7985FCF3BC31F26FC1F72F +:104D500057CEB751CF5F646A81E2944DE33DE421C1 +:104D60006E183DE59940291714751E2BD3F92FD6DF +:104D70001313EEDBE643C7FBACA58ECE74CE9D7558 +:104D8000E636E64D18613E6F7E0ECD78CB16F96D96 +:104D9000F689C1A339773A79D40C9C590327A2D656 +:104DA000FDDCCCD76C63A823231FAE9B4F47D54DAA +:104DB00037FEDBEB603E9BF696E9FF01EF5C9276F7 +:104DC00081F371B8FFBAF1D6CED3DE7FE6A9FDBC80 +:104DD0006ACE9563E23CEE3D53FF0BC81D4E69F071 +:104DE00007000000000000001F8B0800000000000A +:104DF000000BFB51CFC0F0030977F3A0F2BFA3F182 +:104E000057F1A3F2CBB851F99E68FC2634FDE7D1E7 +:104E1000E4591820B4033BAA38B15888838141165D +:104E200088353850C5F3A1E656012DE805E265AC9A +:104E300084CD7A27C5C0F05F9681E12890AE06E266 +:104E40004B4036931C0303AF34038307104703F131 +:104E50003B190686A940FA25106F9086E8E3048A7C +:104E60009D9421CFFD6D42E4E91BC5D4C1B7955097 +:104E7000F993B51918AEE93030A8E941F8E791E4A3 +:104E80009D806253B421EC70550686BDBA0C0C8728 +:104E900095B09B1B0194DF07948FD0C36FBF831124 +:104EA0002A7F8B352AFF8B212AFF9A272ABFC11B15 +:104EB000955FE103A10157D509D0D8030000000098 +:104EC00000000000000000001F8B08000000000030 +:104ED000000BCD7D0B7815D5B5F09AC79933E799BE +:104EE0004972028710601283440D3884F0147512E1 +:104EF00082C6368503A2E6B7B61EA955449023D2D2 +:104F00009AF6573379125E6D406FE5F779A0DA5261 +:104F1000AB357AB1F5B66A9340BD784B21526B6DD3 +:104F20004BDBA05EB55EB5D18ADA5E947FAFB56724 +:104F30009299C34988B5FD6CBCBD9B3DB367EFB585 +:104F4000D75E6BEDF5DAFB285002FA2480E3F877A0 +:104F50002EC0E92200CC1C2AA373A04CAE04D8209A +:104F6000048D70312B3F94EABBC2EC1D58F1A55360 +:104F700087BEBB04046AFFB3E2F6783F7BDF31F9FA +:104F80005B712867ED2708D4DE69E79457820450E7 +:104F90000050DAB95C4DB07E368C6B56B17D87BE61 +:104FA000AD1ED878474B159070BCE2ECDFB73702E6 +:104FB000744F01381736AB2531567F4E323642B624 +:104FC000718A691CA7EE8F8BD05D06F4779CFD6F0C +:104FD000C3CD4948B071DB267FAB1EE156BAAF01A5 +:104FE0003D02F0957149D0D9F3E920D2BC9439162D +:104FF00098ACAEEA56DC9A7AE2381D889772ECB526 +:1050000033BE3432F47C898317868F0CBC00CC030A +:10501000D0A0A2DBC27A00E8FBCC7E4D7B7C2D3E8B +:10502000BAF14F9C3F1F7F1AE88407503BE389C8C1 +:10503000103C1B7C03DD12C3B7550CC6FDAC490EFA +:105040001BA7CAD54FE67883F3943B3DEB3F15E1B0 +:105050002CA07908B2ABBF4C7866D9ED66B19963E4 +:10506000E9CC2B673E1FE764FD7F06515C80ED3B7A +:10507000E356C4458FB2E5C17BD06EAF99DE76C3EF +:10508000E12784F89989F8B1E2488F0E1D4B61BD84 +:10509000A996CDA7C082012997C8C6843100F9F826 +:1050A0002FF689ACE95548AF634CD696BD1F1BB3AC +:1050B0009A24F67CDCFCB420B332027769AF84001A +:1050C000A1293D4E1F599CEEBB6674F433BA3D0ACC +:1050D00091CE8DAC6C9159BF88B7C391F4FD0CA4EF +:1050E000A6B353F7F6B37AC492A1B992C6253EBCD3 +:1050F000513ADDD8C8487AA34DFF1D8D2A95ED8D14 +:105100001A74FB015A1BE354DE1EBAE5BBD87F8339 +:10511000E5D7FCAC94BB6E7818EB2D00091C2F1260 +:10512000E3FD83AC6AF76B580713F11E29E5E5B37D +:10513000881706E7B71826112F3FB6F1A44337F1B9 +:105140006B8BB13407B2E0D32943655E3E0BE84177 +:10515000F6E550DD1FCFF3D47D5AA1A73D4011E104 +:105160008DEA4C54AC10B83C8AC87D60209C0C5F22 +:1051700059E5822D572469FA40379B5F78B662EC77 +:10518000649F6E11BCFC354EE0F4512EA854C660ED +:1051900060CF71C48B21A637B2B182D34BBABA6348 +:1051A00038A6624C66EB18F4A5B5BC2CFC0595F24C +:1051B0001BFD0EDC259F3E7E24A92795C832EEBB41 +:1051C000F6FA9D7BECA08AFCAF4E1713E97284D7E8 +:1051D0004AB0C9C3665D1671DE9F1EDC23AFD711CE +:1051E0009B9FDB41A5F632AE57E5D07A75186CBDB2 +:1051F000907F2AF97A75C8963A9AF57A00C0839713 +:10520000D0205EBA385ECA3F65BCB4F4D627B2CCB3 +:10521000A3DD5E4F190CA38CF0A0E808E7E6264E4C +:10522000B716A3DB6CF277383C483987E3C9F21331 +:10523000F17EB1C0C75960F38983A70D86589B0ED4 +:10524000239E3A6B516E6D2E1545944B9F169E1CF6 +:10525000B8360EC295E670957DBA7049A1EEFA6C2B +:10526000FCD89EC18F9B106E4E77B59CEEC44F95B7 +:10527000EE1CB802C80F7C9D137C9DE57F89756E7E +:105280001F5CE7245FE7F8A7B3CECE7E0EAA518F4E +:10529000EBB642637CC8E0B856B2942B707F0D0920 +:1052A00070BFC1E800E11FC7F4CC70F3F3BA0E7011 +:1052B0009B10E0FA8674594ED205EF0A99E92C1535 +:1052C000F87CF3A9C911E60169DF40BF0327E3DFDA +:1052D00086C34DEBF7BAE0BC5988C408CED9301B61 +:1052E000E17C27BC34A71B86EFEFF546B549F601F4 +:1052F000BCDF68ADDFEB3BF1FDB512A4B2E99777F7 +:10530000DA7201D42E85E67F13E3C1E98887536BF7 +:1053100020CAD623DC3C06E70161F6722EEB675704 +:10532000A04976E177B8F90CE2D5F98EA93BFEBC2D +:1053300013BF1FEEBBBF09C97B0586DFB698588334 +:1053400070A9A590C635F0EF5AD25D08C3C3DB162D +:10535000FBC7C03BECBAD9EDDE0937B733D30B5AE4 +:105360007CC63E9DD1496B816834C3101C0EBD388C +:10537000EBE2E071B4EBF2C741FADA7C1E909E09D1 +:10538000BA34FD93D3D53EA4AB33FEF974F5CABF4E +:105390002E5DBD2E14FCEBD295D220E92F333BA31A +:1053A0005836B99CD4965BB4FE3836934B52E7F42A +:1053B0006E94971067F6191F064456573493EBBD49 +:1053C0006000EAAF6AA9574EFA8ABC72325E6F7605 +:1053D0003BFD6ED4715C85C645F308C795C3D01DEF +:1053E00088625DA17E909C8F9FC2F00477D696F074 +:1053F000EF0CFC6EB8F9C8F81D1B0FD58FE3C5F88C +:10540000DDE7731259ECDEA1F97BC7892F4BE42449 +:1054100022A36F0F61597FC585F7E1BF93E115079F +:105420002F8CFECBD04F5230847F73D7F5E4BF086A +:105430008068905D57D46EE1DBF5F8FFE6E2BECF01 +:10544000F97A7D518586FA16B0FD069F5BC2570139 +:10545000EB7F1374E25B673C299C00A21BBBDDC998 +:10546000D6FF46E4A72CFC7D99C8F58DF76F49FD62 +:1054700019ED416BA3A0DFCFF07AA0F1037889F199 +:10548000E5F2EED314F47B5C2E8EA176CBE7172BDE +:105490000B5CFD2C076E1702F4CB4B22EE719BB810 +:1054A0001EDA25F5E2BC5F9C23A571FF7B71CE5F00 +:1054B000483F7FD194D288E4173B2ECC1949EE1C8B +:1054C00068E4F6ACD3EE8029D1FE7E40EE0F67D3C0 +:1054D000E387C64FD3F88BE748DE7D5AEE9771FD20 +:1054E000DFBF197CA83F1F685485972633E317E771 +:1054F000C9E868F99C6205FD0E279BD705B61FCC4D +:10550000C1AF33CFD6B048F36C0D5793DFAA557BAC +:1055100087ECC7A3EC39CA83E1E075FC56ADDAD25B +:10552000ACF850225CDF527CC9ECF6A63D5FA79E2A +:10553000E9CFFAA4F0B565C0D71EE67A56BB9CCC7D +:105540006E4F65C0A3C4448F9C885DD625E03E376E +:10555000168C67A614131A0FA1FF64822D7BC61E3A +:10556000FE4DD3D50CDE0357844D218EF5DF091394 +:10557000199C5AA1043E56FFB7656B7B7E8FFEBD1A +:10558000FA10481A836BD96D4D8C5C61FCCDF7091C +:1055900058DE8A76210A5EEBCB4DE8B76AC54EE746 +:1055A00001DC257EBE0AFD6A327039C0A49C2E8FB4 +:1055B000417F0C9033663879C0FE84E3FEA1EF860C +:1055C000C353C4964F344F924F4B47964FEB78FFDF +:1055D00016FB0FE5CBF8A1F1E8FB712B14CF3A8E47 +:1055E000CD78DF6BD3A11F96FC53C729848A00EACC +:1055F00023913A514B637BE8CA45BF536C950CDD50 +:105600008C6E0A2B3B059F7E72BC333957CBFDC491 +:10561000A6E0E6AB5FDB7268E2D79F1304F4F31AEF +:105620004C859F8EF586E9D9F8E1DF901EFDAEFA34 +:10563000B26A01DBB5327A2A4539B64C243BF7D63B +:10564000BAA5B9EEEFDF131DFBD8597FD0E5595845 +:10565000E7EB2FD7896660DADFBFFEF2C75CFF8217 +:10566000758A872F3EEEBA88686B149C7CFD3FE9F3 +:1056700038CEBA9DC81F4DF6BA9506509E6CABCD7C +:105680002EBF865FB70A01F7B7581D98E92CDFF9DE +:1056900025C123679D528514186C9DA5E724D24F20 +:1056A000A4B1B3EA77C0F0E34A3125C35EB3FBB3DC +:1056B000CC3DA56CFD3F07CE5F9F8C72A62E2EC100 +:1056C00046669F41A5EF65B73F84ADF0509DE1FE72 +:1056D000CDAFEDD97B37FA97E6FAC95F9AF9BE0EDE +:1056E000EB2E7AA891B8FFB4F7B15F9F2AB0710E84 +:1056F0001A7EDDCF1EED17FA5E213F6F9544FB2F1A +:10570000C2A7CEC2EF81949183A664D6B0F67D95F0 +:1057100002ED9B7E78F68BFF97BE0F517CA36FFE48 +:105720004BDF388B7DFFB9B37DC8391C13F83D932F +:1057300095807ACCB1FE6F9CC5DAEF3F3B7F44FD8C +:10574000AA0EE7EBA293C54F78EB9722BDB1F5E81F +:10575000FDFDAB7577B2F10E424EC28FE51C0EDF38 +:1057600041840FE9BEFFB7AFA01E78C014C8FF7414 +:1057700070CE2F63687F579902E9878BE60B697FAC +:1057800096792E9A7FFDA489ACBF8411D202ECFDDC +:10579000FEAAB7379FC5E05DFC1FD2162CDF7A5CEE +:1057A0002A48960F0FAFF37CB1E97D3EA80743D29C +:1057B00042BC83C6E310BE981177D3EBA0DE22274C +:1057C000CC6CFEB59512F7370A9A41FA9C1C56002C +:1057D000E7315CFB2B87A1DF1C18E896100E47DF32 +:1057E0003E76A1BE64EA897028722289E3489A0253 +:1057F0003B71DFCEBD5877CFFF66079EB849F028D2 +:105800001A8747910D339B7FE9AB363C4E3F009D95 +:105810005417E203D01F1E82AF2D90A8473F8595F5 +:10582000CBFD85AD11AFFFEF519B8EBF6D97AD3EA8 +:10583000C81A470168A6FEABC7CC51B1FF96395CC8 +:10584000EFD0C1207F782BB31361043D6EB3AD77E9 +:105850006CC478861FE31A9A1DD788737D24FC28B0 +:10586000F9C58E968B64C70CD74FC4F0EA43A132BA +:10587000AFDDE2E82B013D2FC3EFE3F5F3F8C6C837 +:10588000A2A34721BD9E0CFE41BDCE6EB75E4EA9C0 +:105890005A563CA547D4DFFE79F8E3DF877C5D5A92 +:1058A00036B8FE517873E82AB37F255F49A5294EA3 +:1058B0009788BBE9FFD7365D29F96A0AFD9FA00EDC +:1058C000F73EC8BF0FB3F718BF082774D42B25E0E5 +:1058D000712015F9C0859F3FDBF45F2F8B363FA603 +:1058E00028EE29E829F2D3A9458C7F8413BF73CA17 +:1058F0003FD8E3AEFFF08617883F0A54E20F4167B6 +:10590000FC93651C4B325F9758FB5592F93F58FA50 +:105910003E9292D9F8E44F128FE7AA75095D2DA146 +:105920003822D91F9970F8653EFE950EFC568AE222 +:1059300092A385FFBD51C2EF8CC3E017E59904BF68 +:1059400084E570F00B363C79A037C928D7742E5FF8 +:105950000196E86EBD64B9DD6F9E2D9F00AE8FBBD2 +:10596000F5C02FD8FD8C763E9A3CBAF92C1F9A4F81 +:10597000913D9F0923CD67BCCCD763B9CCF73BB52C +:1059800026A1C7D9BAE40E4357F364BEDED70DAEE5 +:10599000CBF51F8BAE4E1BE53C9C71D83C66CA9C78 +:1059A000AE668D348F4A1B9E4E09E6BE8C7AF12975 +:1059B0008E7F67A9675D6EB0C7EFF43BEBB2D6B3DD +:1059C0002ED7D8F818ED7C168C723E370CADCB6212 +:1059D0007B5D1223CDC7D5FE227BFE17DBEDC9EE22 +:1059E000B8419ED28C768625252E95670E8DC7DA16 +:1059F0007D5E2E186AF7E796779BAC30B5BB9CDAD4 +:105A0000D5F2FD8FB54BBAFB032BD28CFE8036B49A +:105A100015981D53D23AB7DAEEFF2AFAAE6EB0FFF0 +:105A2000ABDDFDFB5BA1D9EEFF5A7CDEB4E023A722 +:105A3000DD2A2FBCA73BED52D84EA81984E37A7714 +:105A4000BB797221CDEB8438C328FD3FBE58B20329 +:105A5000E3FA7910E9C4BC8E7639752FC6FD2D4B5B +:105A600086FB317FC06F08E8538BCE497D17DBE59D +:105A70005A7E8DF23FAA530F63DD1221D15249F9AC +:105A800003941FD020AB9ADFC07C0B03B6B3BA16C9 +:105A900093D39897D326242DDC177F2E2537CB243C +:105AA0005FB5CB9AB0FF7C9DEBE9D04FFB9603D757 +:105AB000D6D01729DF2197C185FEA7B60CB86E0F87 +:105AC0004DECC1FDF6D60285F464666095A17CB903 +:105AD000510A1AD85F4FC15709DE6D4D3C9F61DBFB +:105AE000E7BE4AF0DE2600C5696FF3F17C86AD3E65 +:105AF000556BD6B0BFE8B82F53FE438EE6AFB4E186 +:105B000040F83E5B42F0E5835675A540E2AB07EDF9 +:105B1000DBB6390AE9CBDB621555D4DF1C95F4D42A +:105B2000DB12154DA477CC09924F3E3F6C90DD1AE5 +:105B30009DAD8085F598D1847A66645610735E2099 +:105B4000BF083099002253208D751F747696B232AB +:105B5000DAC1EC927CEC6F295C8976EF1C8677B415 +:105B6000232CF310DA2561B0FFA4FD26CEDB375ECF +:105B700002C9185ADF68E7E0F723DA5DD1F428DBC1 +:105B8000758FAE5DA483D9FD3346D1AE7394EDD24B +:105B9000A36CD7CDDB9DD4DF61707B4F65FFA1DDAA +:105BA00016C8B067516FF7C4F332DE67C6DF32CB79 +:105BB000CCF8C76BB237AE76B2EF9DB8C7C9E68BEB +:105BC0004E894138A593B777F4CDE1DE2B8517C711 +:105BD0004DF67DDBB84BE324D7C65DC6CB09F6F3A3 +:105BE00009F576FD52BB7E59BD9945BE17F8F83EC2 +:105BF0005486FE9011D6211FB8FEF80A83FDB880A6 +:105C0000C94A23FB4F32F5DE4C79A7CA5635F2EB71 +:105C1000B604CFEFF02333221F1601F9357D90EA49 +:105C20002C4539016674E19821FEF1994F9BC8CF4C +:105C300007C64920CCA1F531C87F9E41279974E160 +:105C4000CFF0E77C523A99EAF3C6C9FE5174A274C8 +:105C500048A3E21FA57394EDD2A36CD73DBA76FE9C +:105C60000E6174ED3A47D92E3DCA76DDBC5DFB5C12 +:105C700085EFE7F058B359CAE09EA77AEAEDF382C0 +:105C8000DEF767853DF5F53315DAFF9DBA7F96EAB5 +:105C9000A9AF6772DEF37E7698EAEBDB7E5ACDB66B +:105CA000B251F3C97FFF9D7C52A69EC42F3D47CCC5 +:105CB000B0DB32F84AD503F87DBEAC03E64BE5C74E +:105CC000F83EC5CAAC7EB9BB6DFE4FCB1A95DB64FE +:105CD0003D80F6E3BFFA3C1B7D1C5E67BE2783D781 +:105CE00091BFAF4AB6BE355C9E470DCFC3942148E5 +:105CF0007998A53566B5C9E492FC0C8F7B65F67B77 +:105D000099927CD8E7B2F7652DC9E379767F1714AD +:105D1000C8A497C84CAEA1DEA340A2B698E28622E2 +:105D2000F9FBE4F049F68D2297DC2A19016E3B6FEE +:105D3000955EE90055AFF1718306907C8D403F1967 +:105D4000D339A8F59C827A9A2E007D6F08DC7F3EBD +:105D50005F4379160BFCA3FBBD8CFA15CCAD703CF0 +:105D6000F431FA95FBC9DFF90FEFF724F006309F05 +:105D7000F70C0A21C4DCF9BCBE788A1EC2B1E3C7A5 +:105D8000A559C03FA1BF24C5D365D1207F281446A3 +:105D9000C92E6B8BAD55DDEBFA575F89378EA6B5F3 +:105DA0005F2F445959B4CAEC1F81CE3FC42018FA62 +:105DB000478AAE34FB47D84F07E397189FCFC207F7 +:105DC000ED4A328DFABB3531CCED7939457EC6F5D9 +:105DD000425EC5C64A17FD1629DD0857D8302DB4D6 +:105DE000F7D6E78B06EAA9326CEE13A6B1EFA43A18 +:105DF0002399458F18FA5E7EDD3D9F3CC5BB4FB6AB +:105E00009C84DE9DF8E470EF7D8A91CCE60F9DAC1A +:105E100070BBD617CCFEFEEB62758932F344BCE151 +:105E20007680DFADCF850EE14C4E3E94DF50F4F42A +:105E30000B8887B682F3E223CD17346F9EE555A217 +:105E400079A65230221C33B2C131DAFC0F8014B370 +:105E5000D186E225A81F096330AFC3F933A015ED41 +:105E60000B667F60DC23586EC07DAC1E5FA026648D +:105E7000A62F6DA9DC09E8AFF631FD89EC13693E68 +:105E8000D79FCAB83E64B2FF701ED1F923EBD5523A +:105E9000467DB1E2D59B5B1A1F078CC73BF03B7E6A +:105EA000BCCC79CD13AB2F520AB2E16374F6F0ADDE +:105EB0008C5E9872075B1B552ABFD9A851B9A531D2 +:105EC0004EE5A64646ECE81F6D2CA3FABFE1A7738A +:105ED00091CF531DC50C7F1DF1FB5EB812D02E056E +:105EE000DB4FF08505A82F6FC43AE901CC0CC4FA4A +:105EF00004FEFE7A65D102B4F337069CF6D50B504A +:105F0000AF1EAA5FD45285EF6D3F43877239B5BF8C +:105F10007502D8E7184CF522D7BE77B7E2A379E02F +:105F2000DEC2BF3FB705FB0BC84E3D45F00CD63176 +:105F3000E08A7595D77BDBAFA7FE4904B0F1FEABD5 +:105F40007DED02F42FDC3A99FBF961D9D293E0910F +:105F5000FBF53FC2A02FD2E5B23CCA5F5118DD94D9 +:105F6000B047B7E6DA708FB21F90937CBF7B2EFBF1 +:105F70007E39C43727D9D76C384ECE0FA6ED874867 +:105F80008285E3FE8AF3C53F7BDC5B7D1F0F2FEA32 +:105F9000FCA489DD476BBBBA71A9E729C91F22DDC3 +:105FA000E7D4F4D1B6A2C4BBB9DE30CAF1B72A9A9D +:105FB0001D8F4A92DDE4E0DBD13FFE94B19EBE9896 +:105FC00049F9478130E7C3D1C2FD071F3FC7E3F45A +:105FD000030F568C1B49CF8AD589A88C0DCA8DBC5E +:105FE0009AA0A7AECDCF43236DB01EAD2CF4D4C381 +:105FF000E5259EBA4F3BDDF3FDDFBB5EBFB4F54543 +:10600000A7FDBE8CFA9399F31C65BF4EBDA77F8197 +:1060100058C6D6E1F9F912C5439F9FFFD26D3318D8 +:106020003D3E6FE2EEC9ECDAFA161FC633FA980A63 +:106030005289FB7052B2FDEA3001F1F92BFC171BBB +:10604000EF97F6FEF7AC7DEE876DBC13F09CD4B3F2 +:106050000BDF2FC2F57BD607B65CEA24B97070B0AF +:10606000CEE5C2C100AF9FE9DFDE8272A04FE075CE +:10607000D1BF7D01F73B6E6E3F9FE92F8BF19F6C87 +:10608000FC65F305339D657F0BFB15271F32EC671D +:1060900078326B4C5F01E6BDE9407AAB1F12A49FDA +:1060A00035805525A2DEC3E88FE2DDB236211B7DA7 +:1060B0001C6CE4F9027EB890F4FE65F3A7FBD0A84F +:1060C000F727DE96D14FBA3821F8C0D69B35177C1A +:1060D000A2299848DF89F9FE9DA83F2764461259F6 +:1060E000F691C5A6DFB35F196C2C84BF4FB0F914CD +:1060F000B409EEB893E1E7764FBC7464BBC181DBB1 +:10610000A95F38FFEDBDF9E86FAC158CC9D8ADAA11 +:106110004DF862C4DD6FC8891347B0DFE7EBBFC439 +:10612000FD1A8C2ED0AFFACC91AB7D149F5D96EF0B +:10613000E1BF6575DEFCB6A535214FFDE2F923E729 +:10614000D741D29F21D72CFBFCA548F278E361818F +:10615000E443CEC48134E667C2F312703DD0F1C38C +:10616000CE233F6C74FC808EF9A2F0C79076BF4BB3 +:106170008EB666E021B37CC2CFF55B39AF96E2DC28 +:10618000EF1F1174F4A70A790D5370BEB26236E3A3 +:10619000B8ADC5621AE3DF37966C5371BD37947E94 +:1061A0003C7DD017E3717FDDD22A90FD87FB2E6DF9 +:1061B000F2BCB6CCE7D7FA79DCA1CD5AAA9522D3A6 +:1061C000ECD5AA70FE8122C87ABE94D1FFB57EF2CA +:1061D000BB5BC0E3EC09D2AF4BD5E5947F2B178EA8 +:1061E0001CB7CDC49B6CC70333DB3D68D363E99C0C +:1061F0009DD4EFFBA78DDCAF83970F0C11FA102E07 +:10620000A657607B15D87C18FE3795F1FCDBD6F2DB +:106210004709CF9259457AAD4F4B99D86E53F972D1 +:10622000A2CB36D6269F0D9D5BD345E733377DC87D +:10623000E3140FFAF7B6A05EB1A9E71AC07CCA60F2 +:106240003C0D283F364DBD4A453C6CDAC1788BF495 +:10625000992E72CE856CBF78488334B3A840D6BBE4 +:10626000BA512EC8B56098EC556FBC1A70DD365522 +:1062700072D6CC4FA79A3004B4297EC8C4F8446BB8 +:106280003D50BE4BB0CCAC2D46F8C789240E7448A7 +:106290007660BDB54EA6F9B46B1C2F68871D77F2EA +:1062A000BD302FA694DB61A5E8EF67E32837F3F94B +:1062B000EBDB4BC96FB42957A9473967DAF611D31D +:1062C000532CF4F3B7366859D77DB3987CC0EF925E +:1062D000EFB296A0FCA64CFCBCEF83CFE0BC5BA762 +:1062E0008BB0338BDEF1233FB74BD2C6D2C52559D5 +:1062F000C679C2AF7BF611FD0385E01DAEFD503BB4 +:1063000099FCFB68805CC0E65150CBFDA690717E85 +:10631000350649B273C782D584FCE89C5B1D5F9348 +:10632000F84D9295526419E5D50D778ED5C9E75C85 +:106330003E07EC3FFD92DFB1F95EB3CF0788B7733C +:106340008FDDFB34E64D39F606DB979E7E92BDBFAE +:1063500092A96558BFE6F05405F3809E2F9430470C +:1063600006F9278A74F826889487F6261C8ACE7048 +:10637000D1F9FFD8FB0E4A5694232DB97C5E72B832 +:10638000BD4F8AE27ACB56BF93C747F60FCF6787D8 +:10639000307BAE52165213C9BF0E9E37E4E4497EDD +:1063A000B9D39B4774F5766FFD2A583A06F9E6AAE9 +:1063B000DB7C9066FD5EE3CEFF62E3FFD2CFF58328 +:1063C000AB21D58EFBCF7A5BFF5BFDA3A90AD2F58B +:1063D0003533B4623C7FE1CCE32FF6BABFCEF8543C +:1063E00077F1FFCA589AF29233E7F7E6EE05DD49F6 +:1063F000567F499753DCDEF6CE73BDAF6F11E67D55 +:10640000595B7C8EDEE0C9775CB9ABCAC4BC31860F +:106410003D3DDFFB3DC1FFA50EEF7C4F868FCCF9E4 +:106420003BFAE070F3517665D72382AA376FAA450D +:10643000E57147B34586C039279E8BB6AA5374AE23 +:10644000D96AF66B2D318A53521CB081110EC6F9F0 +:1064500066A83ACF730F4C4C039D3F48CDC673E1FD +:106460009FB4DF392AE7C37F74BF670FD3EF6AB5E4 +:106470005F41FE5C2377D60A2543E702023ECB1C30 +:10648000CFF0ED7F7C49F778F0B4EB1865BB7D78F1 +:10649000F47914ED6AC511FA7BCBDEB7FEF3C16F58 +:1064A0002BB87FBFF9C0914528E7AEFD89042A6B60 +:1064B000F7D68311E8A67D27ADA03C5EB95BA2F5B7 +:1064C00007B97BD6859E3CFB169AFFB50F47687FC0 +:1064D00058F9A83F5DC7BE5FF9C397A601E3DBB7D4 +:1064E0009A079E1E8FF87B40E0F90C56FFB40BD93B +:1064F000F395325C9E2D1F21A972BE7AE33F42F5CF +:10650000B8BF0BBB7ABE48FD765DE2F3BBE4EF2576 +:10651000AACF6947FAA3F53D213D59E0F065CBCFFD +:106520007BE37B3CFEB4F2715F1AF31557EEDAA100 +:106530002459BB35BBDE26FA5EF0F04351C4C39A42 +:10654000C7BD7ADAB50F7FD83EAF92CE390DD4A150 +:10655000FC938E51FDA8A90E70CD9FFB67AE238ED4 +:1065600065EDFEFDD5F37EC7DEBF1E9720C044CA91 +:10657000EB7DFFADFC04EBC9708A8932D6BFEF45D5 +:10658000371FAED9F5129D37D24418283A0BCF41A8 +:1065900064BCCF680F30A0A03C5CD3B5E16D94978C +:1065A0006B76BFF95BA4BB3520BFE8E6E7D7F11FE8 +:1065B000E34E8C6B75A85E3FCE51D83F0BED16D8DD +:1065C000959FD55E74E25A0E7F5FFBD0D17B508FD2 +:1065D00078E3D1FFB907EF6558F5D15FEEC1FC56FE +:1065E000782AA0A1DC5AF3C0AFA2E0C2FFB76DF9D0 +:1065F000F0D6F7BEFB9D3B181EDEFA8D9FB0F6D697 +:1066000093AF4EC4FB39DE7AE4AF6350FF58F7E432 +:10661000C2B14867EB1E5B3076A4F39F48B769BFF1 +:106620007B7DD3FC5E83C705DC04D9866B9719EBB1 +:1066300002FB0714D47BDF136060632E7BDEF5A1C1 +:1066400082FACBD3260C209EF6EC7EE9E9AFB3FAB2 +:106650009B6C9DFC59D689CD7FBC48FB1B631F56A4 +:106660005EB7FBC2C5675762E933B0FB353040FB0C +:10667000C609EBFB1C5BDFCAA1F5CD7C7F148E291C +:1066800088FF350FB2F59C86EBCAD673DA89EBF931 +:1066900026FE63EE89EBD9AB7AFDAF4761D5BD77B6 +:1066A000E0CBDDF959ED5B673D573F76D1887AB98C +:1066B000231F4E86673AD7CBE0FA866A1E520B90AC +:1066C0002EBEFF9D3B627C9DEB1862DE7AE8E844BB +:1066D0003CB4F19A6FE08B88878127FD1AEA512B31 +:1066E0009FFC35F1DD5B8F3D4BE779D85F5460FB54 +:1066F000DD5B30F8770858FD3A815756EB03E7FD2C +:1067000096F5BB9A756119B47EE7FDB612D74F1D99 +:10671000A0F5482FA9D551FEA60B68DED7A5397F75 +:106720005C97EE59867EED4CBC87034E5EE1D0BA95 +:1067300062BCF9BADD47CE43FA1B6E3D9DF96B385A +:10674000FFD9ECFD7D5EFE1D965FEDF57D6BC7FB11 +:106750000AEA57DD3F513491D9ED6FF9069442DCD6 +:106760006F1E91343C679CB9EE43F86FCE7ADE38E9 +:10677000B3CCA40F25903D8EEDE0E964FC7EF2F9E8 +:106780007D3CFCBD6BEF9799787CE358F6FDA02427 +:10679000C0EDB9EBA0B31655CCCCFDCC07296B7C72 +:1067A000F110BCED5D12C9F9377649148FCB9417FF +:1067B000D70D639F19CE388FF74C43B9F646EF7F5C +:1067C000D874C9E9FEBA078F2896BD3FA45DF85D6D +:1067D000339CDFDBEE6FCD13D9FB5BF3E0DB59FBC2 +:1067E0007B5D362F41F85FEFF3517ED2EB5D525661 +:1067F0003BB734E0F3E85DED91592FE460DC201AFB +:10680000A4FCAB9666F3D7E82FB50EF96C3F80F188 +:106810001AE65DB5448274BEBD257A15DD93E4F4B5 +:10682000D79A8127399E20FB498E252A792C2CED79 +:10683000896FF91841B8E106D92A42BDFF40F1AB92 +:1068400032F68B7E15DD65D71F94A10DFD2A074D0D +:10685000C168822CFE8D8CFE13F325D0DD7EC2EE46 +:1068600071E2BBEC7BFF73521A51DB00A96E3A1F39 +:1068700050045DF767E9EFAE469DECE7E2C4E5E45E +:10688000FFF1A75226EA6B45EBB412511F7EDC09DB +:10689000296F1CBB9051FEBB38CE3E1FE983B0EB85 +:1068A00081071E18C3B714D4CB9FC692C9BF7357B4 +:1068B000E84558BFCB9E37E3013ABF38C14AC828E4 +:1068C000E784D812F2832D4C25E4E5AEF55C18136D +:1068D0000A713F4D0F73FFD30F037CFF6C6ABA98A8 +:1068E000F2D9EFBC5924BABE33707E11F2D9DEDC86 +:1068F000D961CC57EC593D6BFF1406E7F8B004683A +:1069000072EE098FEC4FBAC7F62FECB4EF1DBACF79 +:10691000CE33FF8E8DB75D8D65543ED068D0FB07BA +:106920001BE750BDABB196CA471B13F43CFAF560A8 +:1069300012E97377633D3D1F0F6F0BB8FE3F6C4C40 +:1069400052FDDB815C827FD24D2026D9F385888F72 +:10695000F0D0BC1D78D2B6DDFDC30D4FB5A21F62CD +:10696000108F19F83E17FA0415FD573141C775BF4E +:1069700031C0E549267E27FA07048CCF35DCC4F305 +:1069800022EE11BCE71EBE65CBFF476D3E7D3B9AF4 +:106990007C30C0E07CA7765919E943A09523DDDC63 +:1069A00023240E1AC58467CFF9939579C947032E1E +:1069B000BA99D8C1EDFADB035C3EE9EB40447A9B1F +:1069C00090021DE9CD99776F955E8472B15710687A +:1069D000BD91DECA5CF4E6F4776780EBC110CFBEF0 +:1069E0008F0FD12FE7FFF8BCB2AD358897B522F9EC +:1069F0002D5BF095EBBBBFDAF364768B68213DAF7E +:106A000010C99F3BE9F0116122834FD7BE1F403F61 +:106A1000747C22D8FEA6AE00D2D79D2BB87FF1EEB3 +:106A2000C3FC3CD3D175254BA6B0F68B187E30281D +:106A3000957741698E3B7EEA9C63B85B4DE46823A1 +:106A4000F8B732F3DF6E9F74CB07396C9CF1874344 +:106A50003AFAD7B74E7AAA4761F5C27E81FC4985DA +:106A6000E1D4145CCFAA3F7C6F5CBF6B1DEE589DD8 +:106A70009A847A63FBA41F08C80785C77E2AE03E74 +:106A800032494BBE1228C0FC70FB7CB09C9A8D76BC +:106A9000C1A57989D770DD1245E9FF83F474B47616 +:106AA000DD7F62FF4E3CB2A141CF9DE2920F99E79C +:106AB0002AEE4A8DECCF74E67F17CE7F8476CEFC2B +:106AC0009DF53B5A1B5B857231139F99FDE65DB0C6 +:106AD0006CC4F1EFB2EF0F63F357822EFA2C4AF534 +:106AE000CBF89DF3FD70F1D7CCF90EFA894619AFBA +:106AF000EDF2413ED2C523FF3BF1DF0F02924E4241 +:106B000042FF544F20190F16E0BD7129AA33E948FE +:106B100079ED67E472FEBD63CC77C611DFC9E96227 +:106B2000CAFF18E5786D904854E13E678846B67D07 +:106B3000A03CC8E5E77C48917F540CDD3472BCBFB3 +:106B4000C81BEFDF0C3409B0BA553BFE01B286FE1C +:106B5000B07D5081FEC7BC2087BF4AE6F6E58C7D3C +:106B6000FA0E89FBADA4251117FE6CBF9D8F77CD62 +:106B7000E0BE09341DCF7F4DEF115CFCFA7E287911 +:106B800036E24989EB744ED6174B925F72A1141608 +:106B9000C99FDBC9E57F0324D4D3785C0670DE3A55 +:106BA000C445DCEFEF5AC7CF8DEB5A88E0BE2BA669 +:106BB00053BDC1D6531EB1F5FA876CB9FF7D5BEEAC +:106BC0007FCF96FBA55DA9056106D7776DF97FBFDD +:106BD0002DFF77A2FC67E569F7F5C3F72A491E1B6D +:106BE000985FF08D6DF16644C13D8D26BD7FA27129 +:106BF00005957B7EFF7C7588C177DF73DC1F7CDFAA +:106C0000E1319FC1F859DA140D81B5BFCBCA131F0A +:106C100067F51DEBC49D28577EDC98A2EF76A8DDB2 +:106C200012EA314799B56C2119BC66B68458FBC885 +:106C3000BB035A2D2B77B41E0AE0BCF33E2702DEBD +:106C4000D3E7F051F40F5FED8EA21C9B290691ADA6 +:106C5000F20ABAD553D04E5F27523FDFFCD565EA22 +:106C600002C07B1B5E84D5ECFB095784293FA2E858 +:106C7000FA97CDD5ACDD9697C394AF5DB1AFBFFBAE +:106C800021F67ED68A08D5CBBBFACD2DAC5EFA06AE +:106C9000AF4FB0BCFC71FAAE7EF321F67D712A4A8B +:106CA000EF67EEEE6BC2F9FA2ABDE7AF72FED031A4 +:106CB0006E0B836F22187B826C3D1E1352BD01F454 +:106CC0005B2CE1E73C0AD2C92ADC3AC66EEFEAA1A6 +:106CD000D07F0754235EE3BF7D217E0D2BB7E147B4 +:106CE0008C2E66EFE5F8B8BBF5C50BCE67EDF6ACBC +:106CF0005B4BE715FCEBD6717D88E10DE5FF84AFBA +:106D0000EC15AE76C989A25639ABFF6E5BD04FFC4D +:106D1000D1B66E59620A07776F18F5BE52EEB72CDE +:106D20006EABF1E439397192BF09C96D41D23F7937 +:106D3000BC44D652F47C06E37DF4B3C28D22D797CF +:106D4000127D01B73F46FF0ABF9F2D138E9D4199CB +:106D50009F77B46A5EDBCFE6B765A62207108E295F +:106D6000F6FD2C763CD269CFC6DFE9966FB2C6E15C +:106D70009AC00C2505E15ED537EE21D6CF072967ED +:106D80003F3383B89FFD68AB48FBDFE64A7E2E7039 +:106D90008FF14E37DE73E1F0559B21121F6FEB83AD +:106DA000349EB3D85659927B1AD2510C77719AAF50 +:106DB0008A782EED93C1CECFE945FFB81FFDE38C55 +:106DC0009E4A0F878E88E407F4E683175B5E7A108D +:106DD0001BBCE7F02630E5C79DBFCC2C9F213AA312 +:106DE0007DB6A617EF51388AF728A007C532A355FC +:106DF00063C874E2CA917493847EF8D28C73077767 +:106E0000D8FC7E8F7DAE108E5D0F28BFEEB0F38B69 +:106E1000EE5825067586979F598768FF9CD0D05DF0 +:106E2000458199C33C8FC2C9B7F6DFA435E33E5B09 +:106E30009CF2E60D5566E45D977EC2BCEBC341AFA4 +:106E40007FAAF7C74103EFC34B3F2719A8D77EE3BB +:106E5000EB33480E5A2BB9FE925E917707C697F234 +:106E60000530F0B9D3AF63C7BE13CC23BE49CF659D +:106E7000EF7398FC88745DB002D70B72B4E6189E6D +:106E80008FBE117E80FDAFE0EB5F550474BF4E51A5 +:106E90000C28CECFCA8DA7227FAF1331360EC76D17 +:106EA000790F6ADF33F83CF73322DD9F53DC6A9DAC +:106EB00086F3EC9D575888F4B139CCCFC1B4083C67 +:106EC0009FCB2AE0FCB023D24DF9A15B6A4568C68E +:106ED0007563B833B09FE5C19D94D782F0CE24BAD4 +:106EE00023FD0B6315C88FD61541BEFF1CB34E435F +:106EF000FF7234D4DFB587F5135EAF183B512E56C1 +:106F000079EFA99B1CE2FA5E20C4F73FC62F8110DF +:106F1000C6F93703E531B2B9107F33BEB280F60748 +:106F20008DEC2B27CE1FEDBD402C9ECACB1217FF38 +:106F3000EEB4E56DDACE5FB8C7DE471CBDE30E7B6D +:106F40001FD96CEF1FC5E6E26605E976054C473CA4 +:106F500095AEEA129667E1FF533ABC7235935F260D +:106F600065F24BCA7B6E75FC8A12CFFB8871BAE75B +:106F70003D856470DDD93E8E785E1F289750FF9B5B +:106F80000109D32D5786D303F282E634C4DF68F5B6 +:106F900092682891423D34530F3FCB5E972F0412E5 +:106FA00073B1BFE8BC7ACAE75915489C45FDCB6967 +:106FB00001E5E97CFC2E96155E4A061B05BC351FD3 +:106FC000075E900D3ADF75A3E4DC67EB3DDF051942 +:106FD000F7D766DE4F7BCEFFDE44F7D3B6094CE130 +:106FE000C37A8E7D3FAD9FDF4FDB16E1F6579B8F57 +:106FF000E7AD5D67E3E1F210BFEF75954DA7E7845C +:10700000B2DF7FE4F8BF52281BB0DDD8ECF78EA1C9 +:107010006685FD9D333EFBFB5448E1DF4F1A799CAA +:10702000B5380EEB6766D05C1D2A18C2D38C90B9B8 +:10703000C65DBF2164E715C909D22F4D99EF877A44 +:10704000D05CE76EE794791754D2F9BEA3F6F93E07 +:10705000F6DD7681F02A69A3C1BB6307B409FA564D +:107060009283BF62FA5F96F5783F18B5C49CA1B8C9 +:1070700094A327ED0A71BB97D1DB06A20F266110FE +:10708000EE30E85BF15E88F1780FB78EF6E7E17BD2 +:10709000BE8DF2F6ECBE5AD4A356FF58A2FBED4EBD +:1070A000C0D72A4677AEBC14E779E107E3C91E9E34 +:1070B00020256F0FB9F6E9C215030AD23BC25FC3A0 +:1070C000E1E7F9D442FA346E1700C573DAAE897B72 +:1070D000F20B33ED923CBCF780E48A42FA5D265C09 +:1070E0008E5DE1D433CF271CB0E908FFF431784F2F +:1070F0003870A5563625E4AF9990A47236E854321C +:10710000FBA50BD793F19F8E703687269E85F3F8EB +:1071100027E2EDA950C1BF1EDE1C3A2E4E9E3B4811 +:10712000C7D9EEBFBE3D142579DB7038B2D34FFB13 +:10713000C9D788AE2546D7A8F73A79330D60E7D589 +:1071400087A10BFD94C5C9463A277A94D131F62B15 +:1071500069FC5CAB0C5A02E337528CF3874F2ED399 +:10716000440DE3B3961FF51EAB040C94B5E8977479 +:10717000C35B194EBEEAA6BF1B0F6F2579FB854086 +:10718000F275C4EF8DA5961F353B971C7EC32D87E6 +:107190000508EBC87FE71CE3FB65555297911E1667 +:1071A000304E47BC2F8424D5CF078BCA0B204DE52A +:1071B00067F18A23D2E3EC730CDD9788EE730C83BE +:1071C000E7E12A9DBC0E1EAF2AB0E9106C7BF56783 +:1071D000F54B9B16B2F1D9E29B1897FA563DCFEBCF +:1071E000F1CF96E93C6B41FF1575182F82655C0F56 +:1071F00073F221F2EABC7ADA09F75D1DFED361FC75 +:107200002EF3DC9CA3AF65EE5B4E99A9AFE58587B5 +:10721000892F0CB3EF64C6171AF09FDC8EB5EDEB27 +:10722000448EFBDEF8CCF240E340EB5E57DEF941E2 +:10723000BCEF28EB3EC0E3BED1DE3FD52DABA4FBB7 +:10724000E50C4C9DEC6BEC3EE7E5C943F670627EC5 +:10725000EECFD02F9DA8C9AD407B7251FCBDD6BDED +:10726000F9004BCC9E735E76CDB34F63D066D113DD +:1072700006C7337D7F73EFBF6FE0B903F44FD8E3E8 +:1072800045EC38D97AD1F213BFDA7EB8778BB8BD26 +:10729000EED8F9D9E6DB4AF8EA0F233D0C37DF2FA9 +:1072A00085F97E3AA6DEA0FBF25BECFBF25B2638AA +:1072B000795C8686FAE45561EE8F5D1F2EA5386BEA +:1072C0004BCF5CF22B17ECF7915F7DCCB2A460B989 +:1072D000F645CCBF473FEC37997EA753BE7D19D505 +:1072E0007BAB66A9682FDC10A9A0B8EDC646C39396 +:1072F00037E2942DECFBA4CBCFD792A8D630EEDBAF +:107300005A57A1A2DD217DAE92EAF269159DD58C76 +:107310009FBFB079DA7905189F28E7F7935DCEEA29 +:107320004DA500D561BECF1E305E0E239EAAC3BA06 +:10733000433FB48EBE6549D3877221AE5563CE8C70 +:10734000F31C6CFA62CF49BF7E43495E13C67EECE4 +:107350007BB2D62BA9B2B5E5784E9E091CF417ABCB +:10736000DC5F8874D03A6308EEB5367EE7D9E33245 +:1073700081243EE25A3F25CED76FBD082BB2ADCF58 +:107380004D61AEDFB46AA636221D69F2DF3CF78795 +:1073900056C678BE7E8CD1918B9F4FA477CE4F95E9 +:1073A000E1442BCECFAA86B214CD3F4CF287BE93D8 +:1073B00086EEB18C87CD0E6CF78B5C3B4FBA88E7BD +:1073C00043B3E7ED3924FF5224DF1D7D70BDCCF5BA +:1073D000B9D1EA837917AC237DF01DC65A649F7D2D +:1073E0006E1DC9ED753E5543FBB477BE4C71ADE8DB +:1073F0002970B9DB6E91225C1F9422DCFF8DBF9354 +:10740000909EC2F51E3CE7110D4137EE0303137841 +:107410009EE97AD8517B0AC1375973EF675513B883 +:107420009F614B757085DBDF303797C7CDF6E65629 +:10743000FD29CCCAF270BA1A59F30C0DFA31AF0615 +:10744000AAF97932A1889F27F381A1727EADD1F08C +:10745000DE500192741E6DD8F503EFFDA20FC8E94E +:10746000E620E22DC6EF59896C1728794FEA32BB26 +:10747000F14C4F73EED21F8709DF0903F9BB675642 +:1074800090ECBDF77A14B23FDFBB067ED785755FFF +:107490000E586CA99E12C5DF3DCCE63BC0987527FF +:1074A000E68169FCFDF4CD02F9B39EFA5B703CD233 +:1074B000BB1105117FCF6211D32778B22084304EE3 +:1074C0001B5D00DDE7E2F73D61C29F2FFEF3735EB7 +:1074D0009E41FB4F489C83E7B7C43B71FE8FC6219A +:1074E0000FBF9FF1D76A094A86F4A1AD5AF210C2C4 +:1074F0003B1BAC153DECFB2D0AE7AF2D794A1AE397 +:1075000095150522E921E00BA527B3F78BF6BD5CA5 +:1075100083F99D8BE64CC796383EADF7242D79183C +:10752000E9AF465B5293CBDA573EA793FC3D2F7EE3 +:10753000FD5EACCF3ACCEB3E3FD7E3518F719F134A +:1075400058F4C1449AD7AB61AECFB6C6CD3E5318FE +:1075500091AF32EEE5F59E3370E8806DEB3AE6A729 +:10756000D3BF75A28BA44F1CF23FC11CC33E8FE258 +:10757000D083297C1C7AD88D3C89F217F3CE6243E4 +:107580007967EB6DFD6DB4796799FC9477814CEB6D +:10759000F00ED3B7300FFD443EB99EEEFFCCE4278A +:1075A00007CE8D95793194C30EDF68B36F22B9ECA5 +:1075B000BF42A1FB4C1D3E72F86756CE201F7D13C3 +:1075C000E5C5B2B0BE90A76A98E0E6930B4FC257EC +:1075D0008B60606F8CD517C960E530117460EE6BFD +:1075E000A5135D7C9289CF45F30578D1230779DD1A +:1075F000856F6DF01EE02C76F270EB7248D6DB6280 +:107600002E3E6DB7CF99758806E07ED49CBBDC8892 +:10761000CCC47B277357213F6C121229E487C8EC36 +:1076200037425731BCBF37866991E83FD4973F4C0A +:10763000FCFE4288ECB22DB356527CEABD6B9293AD +:10764000707FD9C0F0FE22EDE7E9B122E5DCF68FCC +:10765000E5F9137A9C97C9387F0EF6FBB45D37EDD8 +:1076600076FDD48EADAF476EEE8B723ED817E5FB3C +:10767000D406A553457A1828563577DEF2B9F6FDBB +:10768000C2D746ECFC97632D3AC629AE8D08F67931 +:10769000BB2ED25736343E4E657E5D1A304F2E5883 +:1076A00066E9A857A81F2D10709F85D379DC1D9F10 +:1076B00037B9F4B58B6CB9ADE2BD406CDE6AB3A5E9 +:1076C000BBEF9D554521EB7D41FF15E5FE5FB519EB +:1076D000E8BDDAFBFF283F21BFD410BE8CF5E64E93 +:1076E000FADD9840377F1E2B35852B5DFDC6EABA43 +:1076F0003CFBA32AF6CB640F358066A17127F7D730 +:10770000A0DFAD6369B013F39633E908FF5E74D16F +:1077100083FAD185A417C121AE97D694A844BF6D32 +:107720000DCA0EF4EBBD1BABA63CF5161B6F99F30F +:10773000C1F83AD3F4C84F66F9799CDD9AC2E3ECFC +:1077400058C7383B961867C712E3ECF81EE3EC58AD +:10775000FF41A349758CB7631DE3ED58C7383BD68D +:1077600031BE8EE5E38D2BA8C4F809BE7FA2B1819E +:10777000EAE7DA7213CAF8EF7C757C4D31313FEAE3 +:1077800027F6FAEC3197AEF825FA01216AE07E1D62 +:10779000D8DFFCC27FD975BAFF3A5E928F7E4988E6 +:1077A0008980F184F6F836A6630ECD2F20DF0A3AE1 +:1077B000C5D5AD1598D7B83372E03C99E90FA5F15E +:1077C000EBABF3587D57E4B976CC233D556FAADF78 +:1077D000E1AAEB918A958F6843F549E53BE4207B6C +:1077E000FFD096E7DB510E04625CEFFB51E437E714 +:1077F000353192E82E618A0DCAB162258D748C678D +:10780000395F9C8CF3E07ACB67A1258E797C9374E9 +:10781000A502F98FB5EFE6743FBAF63F89E8F43C6C +:10782000F3BB91DA8995A36A47E770876B87EF8589 +:1078300011FA698316AD8FC1BEC9C7F757AB80FB7C +:107840007F3B7C9CEF3B02BC9C98E3E42F54DF120F +:1078500065E52D51BEBE1D017E0FC1C054917E8FC6 +:10786000071A84CF633F5F2D040DF31F2BA696E408 +:10787000A3FE7FC8A687C993227CDFFEBF2AEDDB6B +:10788000E74F7AA8358FD5277FDB30701FDE04469F +:1078900010EF71B5368B944FF4FDCA53F296B0E6F3 +:1078A00067CC7C2C0FF5DE0A5BEEA46DFBA4A9ED82 +:1078B000AA49681FBCF72C977B47EC7176F8FA52FF +:1078C000B49E33C3749E02A093F492A6B84CC10C2C +:1078D000711C2F159F7629DD93D9A6D0BD4CCA8780 +:1078E000B355F2A77EE0B7EF25EE237D450924B519 +:1078F0005CF6BCD312C9FFD0A205296EB3295C4146 +:10790000BFCB6095CB140FDB54CEE33AA1C8C5744E +:107910004EEB9B3D016ADF1656291F385DBE7B5F2B +:10792000750C4B51C37D3F6D2EA5FB2A2D4DD428E0 +:10793000AF98FD8BDEAF8A919F6713D8EBB28AC7F1 +:10794000217C63F753BDE5228DFA073B7F9F542FBF +:10795000117F2722D1E3BD7F76E0E767A21F642570 +:107960003F9F324D5BDAF3247BDF6AAA8912C60F90 +:107970006DDA3BBD21AC5F06142F0D4D7DB919E3C7 +:10798000A9AD576A06CFC7E2E721C0BEEFB8B57C04 +:1079900059CFEFB1FFFA104C36B07D8D8AFC0AAD9D +:1079A000F034DE4F5564EB33A1DC0A01F5B1B63A91 +:1079B000BA8693C1E73D47D09AF71915E9465A941C +:1079C00047E3B481A9627BAB4EA67DB128AC76A318 +:1079D000DFA0C8F63B38F2203FE53A4FC0FE57B86B +:1079E0004AF69C37187BA5B75E9071DFEE9936FD9D +:1079F00064E22D739EF9B14773119EFC557432E217 +:107A000004F86F8D552CC1798DD37A851D9564D27C +:107A100068BA86A986A926773EC62785775A796BE4 +:107A20001FD2C3345D069DE1E54C1868C6FE37D908 +:107A3000F4DF51ECDD9F0FD9760DE3D3ABA3980FA4 +:107A4000D52082E5EA1FE31D960B9E533AF23CF5E2 +:107A5000C99D859EF653B69778DE9F963EDDF3FE70 +:107A60008C5D159EFAD4AE799EF6673E5EEDA94F09 +:107A7000EFFE8CA7FD8C7D4B3DF5997D977ADACF93 +:107A80007E61B9E7FDDCFE959EF767BDB6D6533F34 +:107A90007BE0EB9EF68E5E9FB96F5E11FDFBF47985 +:107AA000FCDD1FF7B9E24C7BE1847B743E6AD13187 +:107AB000FE07517E6FAE8CFB3BABAFFD1AB7BBD45C +:107AC000730C1DE5CD25365DAECC33AF43F95A15A9 +:107AD00055699F90C3BC9D1C3E8FF49189DB999C96 +:107AE0009A41F6D8E0FB10CAEB46EB9C5297BF2AAE +:107AF000A07502E68155456BE9FE40E77B593301ED +:107B0000F3E32EC12486023C766A51BB80CEBE7759 +:107B1000CD8BD97F7495C400B30F51AF1FB4FFE470 +:107B20001C8AFB32FB8FEC4323C8ED413826D17B06 +:107B3000E39B02607C9AD977641F3E1A66F6E17473 +:107B4000B4C7FA37A11C1AF8854C7144F647F65FA2 +:107B500025B3FF36E6BAFDE0FDC558A6412B247FCC +:107B6000B8D22D8E2D267BF036A4E72FAC7B760580 +:107B7000F63BB592DFB3D731A62E8E7A72477117D6 +:107B8000F1C940B1CCF7213951E6F6EFFDD45EEFF3 +:107B900090FA7DB243D93A905C76D66193D09FC675 +:107BA000FB0CADAF05C9DF3DF18FFE43C86F6A899D +:107BB0003A1EF3008D3D8A89E3DD6AE3B9449B5E9A +:107BC0008D3FF3581A5FD28BE5A93AD347585956DF +:107BD000B6B517CB47A22534DEE9C623D52863D432 +:107BE00073B8DF5A9EA6A49B05F4373338B2D81D6C +:107BF00083FE89E8767E8EBF547E05E90FB5FEE3ED +:107C00006C0A55792AC58D0348170295444F0139EE +:107C100044FB4B000FA3627D8E90C65017EAAF98CD +:107C2000175A95B79DE8C0D16B51DF4D72FBF8A78D +:107C300088D7589D77FD43EA0F084FADF6EFBC7526 +:107C4000E4EAFBABD9B81D052579E8B3457FCA1234 +:107C500097FCD963EFBBF7E6881EF9331B731466F4 +:107C60000EE9458C1FB68BA720BC098AAF07F64BDF +:107C700064CF076EEAA4DF570D68960EA4FF5B3A47 +:107C8000F65B53524FFEBFBFC42A480F0E343C95DB +:107C9000156F817E09CC19C3E3337AEA1DA40FC0A6 +:107CA00098A08EFB6C432C68EEC8621F7C29C2FD35 +:107CB000671B263AFECC049D7B6D437F5B18B7366D +:107CC000557C84F573C32F0A76BAEF87B8A180FB81 +:107CD00027871B3FC0ECCCA40BBE0DAC5F94E36DBB +:107CE000C796D4D2FDAAB8CD54E2B9D0F21DE4A70C +:107CF000B7EDA52FD978BD36C2F1385181053B507B +:107D00009EE431FD88A1B4CAF6AB38FE97780E8F99 +:107D1000EB1B1648DC2FE773F62DF138DE4BA383FF +:107D2000AECCB2AF00211598EF6BECFF7AF07CE09F +:107D3000291DAE7D0E703FF0D6A76CF7D64F4B7B5A +:107D4000EB4C8B7E1EF5806500DCAFB1CBFB3E0CAF +:107D5000A60FE32885CE7DFA097E5E506510207D52 +:107D60009777A57BEE66F34B38F75E66DC9F3F7531 +:107D7000779AF497C54C7FC1F799F7BA171E5EBD85 +:107D80001AF585C28C7DB4C22791BF01FD4486CB14 +:107D90004F3449D33D7695E3EFC994EBC1C35B8182 +:107DA000BD217B3DE9C7FB51B572F42BB417DDF261 +:107DB000C7239543FE957639F5EA11F25F32FD2B24 +:107DC000C6FD1FE897BEE1175FF9F311979FF2ED2B +:107DD00068721AFA336E9FC4BF77EE4F75CEF5BD49 +:107DE000532BFF4CD0391C49171C379659E7737534 +:107DF000254DF76738FE15C78F70699E790BF2DD48 +:107E000026E3506A0FEBB7FA377EC07E164AFBF7BF +:107E100035A2BC9B2053BE88367BD5BD41F467E2BA +:107E20007B56AF2ED6C7127F3CE3237FC27A9BEFEF +:107E30009DF3A98E3FE6B3B61D707E8EA3475941D0 +:107E4000FB5C4610F5E43376B135F4EC87DC1FE8D3 +:107E5000F8FDA67679DF9F8E47BDC9EFB983F29B07 +:107E60008CB93CBF694C7DBA17D7F94C7B9D316EFC +:107E700055356B287E3AF6B2742FEAA1D3EC3CA5B7 +:107E8000F2677E463FE50B5211E5279D3E9EDF4B94 +:107E900064EC953DE742C68040793E639E938C3406 +:107EA000EB67DA13DEF7E5E0AA17237CDE7A665C7F +:107EB0008AA95B6F5F21E0EFA2A60494679B2F6302 +:107EC0003602ABAFC8B1F38B4E8553916E174A6142 +:107ED00003EFD15BFB2B89F214FD47A6FC1AE3A349 +:107EE000F02CCFABD44EE1F156EDE792C1242068DF +:107EF00021983E3D3C14C7FAD67103EFD41FF48F8E +:107F00003DC0D61DF7A10799DD5FEA433B5EA37A2A +:107F100017B3FBB1FE28B3FBB1DCCDEC7E7CFE4396 +:107F200066F763FD7166F763F96366F7E3F3279815 +:107F3000DD8FF5BDB955E48FEFC3FB8DA6E0EFDA19 +:107F4000EEA6BCC6F5AA4F43FAC99467555537A8A3 +:107F5000CB187E378617521CA57A21CFAB6FCF592D +:107F600048F6F4A09F2EC3CF39E4B7EB171CBF1D12 +:107F70001E718EDBF6ECA0FF3369D0FD0527EFC73D +:107F800074FA21FFE909FDD87ED437BFF6DBEFB4E0 +:107F9000B057AB676EEB0896E0B99E147F6FE7159C +:107FA00066FE9ED6EADD4D94E7A78C7B2E85EBBA64 +:107FB000BB324CFA06FEDE12CAED4C3BD1B10F3398 +:107FC000F571A7CCDC0F33F36022B65E72B2BC8CC5 +:107FD0002DBE14C5ADAD26265F70BF684C9FF3B2B1 +:107FE000EF44BF6DA1969771BE99E75DF9F7F17CFB +:107FF000BC0E486AEEF93BE71FC8E62BE1FE43B72B +:10800000DF36589AA6FB19826193F44581E991A461 +:10801000576A498A03B60FF3BBD9AFDA72A269DC9B +:10802000C5B4DFB73FE3237DABC6CE7F6B19A75244 +:10803000BD65DCAC389D3389CC52FBB3F4B336520A +:1080400032E2FE2AB1FD5F1F61FF97FCFCDC574B5B +:10805000EF5C15CF47758497F7A1DDDE118F91FF97 +:10806000BF67DC2CCF3DE4527C0EDD572185B99EE5 +:108070002DC555D2B3659C7FF9507BA7DD9E1CBEF4 +:108080008F3036273F6620DC49EDFC72C2447F8B7F +:108090003FC6F38CFD1A8F17064B4550B39CC7782B +:1080A0002287DFE3D5519ED4D0AFD31197E95C4747 +:1080B000875E315CBC95F4A2FFCD113CF4DB62FB22 +:1080C0001D5A5628A417261A72B59A7C3A97308002 +:1080D0007CDE116E5631FEAA8CAB1CB15F45E3FD10 +:1080E000FE7FA3B2F95D0080000000001F8B080036 +:1080F00000000000000BCD7D0D6014D5B5F09D9DF6 +:10810000D99F24BBC924BB9BECE68F09241A34E019 +:1081100026240134E224048A167111D0D052D98069 +:10812000282A48405B57ABCD8604842035F853A9F4 +:1081300058BAB160ED57ADD1D296D7222F28F2FCB4 +:10814000414DD52A58D400D66A6B6D0469A9FA3E10 +:10815000BE73CE9D497626B34950FBBE872DC39D85 +:10816000B93FE79E7BFEEFB9774F9D823F1730D630 +:10817000BA27456595F05CEA88A71431168E966794 +:10818000D74F60EC1B59E1CF32FC8C393C8BE49823 +:108190009B313B636A173C4F69EDF4A75716188370 +:1081A0007AA2FCF329EF7A077FD79F62FA661681DD +:1081B000F6AC587AAFD7C5984D61C2291B94995B2C +:1081C0007EEF6C467F4E89F8774F20EC49DE8FC7F3 +:1081D000F58B29EF4E18DC6E7959AF4354185BBF0D +:1081E000AD23CCA0FCA900852A843BA6E6C1BCAE89 +:1081F000DFB99245CA18DB28F5B8648063E3E7C2AB +:10820000C270D9E0FE17E37CAAB057298670C21F5E +:10821000DBA973E06F85298E6AC6F2F0CD687CF227 +:10822000EF30CA9E53D07F7937944B3578E0FF13F7 +:108230009E3596AB7A8CE589078C65C642F6F03898 +:10824000C65E6B864ECF646CCEA10F0EB174C6E6CF +:10825000C642CF3CE9632C577585E33263F358E897 +:1082600099B7A09CD790C6BA4330B88D2DC57581FB +:1082700069BE510CF035308295E52D4D65CC35D079 +:10828000FF7C3993D6A9A1B771261BCFD8F76F69A8 +:10829000650CFA89D509F1ED00FFECFA6DB3C7C0A2 +:1082A000F3FE4A5BC143D828627F17E7E782CE4ED0 +:1082B000C17C336D2B478D86FAE1A969422BD4FB33 +:1082C000FEB967AD2F8672CFF49210E21DF0F56E05 +:1082D000FF7C00FFF3C2BCBD3EFECB95C7E68E819E +:1082E000E796CA2766E3734E627DE86FD6A4CE1682 +:1082F00007F477C932A502FB0BD71BDBE7D518CBF8 +:1083000000399F0FFCCB9B3518DEE1E0318FAFF7D2 +:10831000777FB342F8679F033D003EC3F809DA87D1 +:10832000A53E290478CEAD11D438D04D9E2AA89D03 +:1083300016FCD0AEF18319FF622C83219FD5CD139B +:10834000E3ED5025D76527FCE7CE14E20A8C9FBBEE +:10835000B4AFFB14942F73D9E3227CCFCAEC12F094 +:10836000FBFDCB18EB2822F0D26B13D6F77ED71A81 +:108370007B217C9F1714990DE880D58CA1F1088E84 +:10838000D1848F231C1F2EC247DEB2D0333F82F12F +:108390002F9FE49445A87F7903FFAEC3B751023AFB +:1083A00083EF1B81CE624467D29144FCCC39B47C0C +:1083B00039D2E31CD3FB62A88BF3FDDBE403671423 +:1083C000025CCB858E1969004A8ABD89315C68C020 +:1083D00020D2B5CE8F3A9E96EF68217E4CE033FBDB +:1083E00029E467FC7736A186F8EC29D72F65941B22 +:1083F000BB337BB73020E1AD328BD5E733F69FA995 +:108400007D670B50DE2E5FB66EDDF9F03DA5EFE720 +:10841000AC9C31A7F39B336624945353AFA6B24F61 +:108420001B07A610E3EBDD3F2ED1C75F650EDF060D +:10843000956D12A12CD9E44DA1A2817659D84E1880 +:10844000A25D986D922CDAB9F57680A7B5B07EA9B9 +:10845000DABC52B5EF360D9EC4F125C49BACB8050D +:10846000580F69BA2423BD7C5938B2879B77846D35 +:10847000B28F19DC0EC06ED1E1B759C31FC7EF89A7 +:10848000E3DB8780FFABC6C770FD39B4EFA70D1FD4 +:10849000545F9D9D7CBE08971DF595A2B86D09FDA2 +:1084A000DCB9E75F2F9C03C42BCD67A114E843B26E +:1084B000AB7208E8BC4CBEC7859D4B99F57204F8B9 +:1084C000613D945578BFBEABC3A5C0FBB2E2BBD63D +:1084D00021D19775A7329407E3989CF908F43B4E95 +:1084E000965837AEDAF97B6D69506617B35009F4C8 +:1084F0009BB12795E44966D1B93F1160DCCC4C971C +:108500008AEDD332AB7FC2883E982225E023ADF6B8 +:10851000B5BA34846B360B212B4A429CD522938DFD +:10852000051E8272E6B46DAC1ECA157FF32822F2D6 +:10853000B4C4F55D3BB6473DDDC6F6A17E096AF2DF +:10854000679D43DE44FAE35A89A1FE481B778F807A +:10855000F0DC0F5D89C097656559B3EBA15CB6DFB0 +:108560001652149C4F875088F30988A4B7747CEA8C +:1085700072A4E2E36ECEF463597C3BC0DF668F7772 +:10858000A3BC8A4DBE5CDE0EF0E45E9920AFF1AF75 +:108590003EC001C2FBE2A5DBDB8B90BEA57713FBDF +:1085A000CBF838DE8DF28CD53684B1BD6FA66490E1 +:1085B000FFA99A3C4B35E981E62C3BC9335D1F305E +:1085C00055526498B7A0CD9B7D2F4CFAC0C9422E5E +:1085D00007D92B0BC80E1158AF702A0DE68F151155 +:1085E000EE023E8F41EDAB797B1608B9D0CE71A675 +:1085F0003635617DF898D502C815AE4D55513F0B03 +:108600000EE60A56C0BC6D2CD20574D2223009CBBE +:1086100003E375331CCFE94A6B43BBEB2957AB0D22 +:10862000F1D7FA2CE80F98C7ED76D6807641AB1CCF +:10863000726541FBA866BFAD2A1F9D83E50CA0EDC6 +:108640001EB41BA4B08C74B9CA5F9CC3E07DBAB7DA +:10865000F79B2867BF96F9AB19AE0290A37550E758 +:108660005C90FB9B1E5B17AB81F14EE63125C1CEC2 +:10867000734A4D0CED29E7C942C3FBEE6698D199C8 +:108680000365D56DABC771AECD5408AFB54C6EC3A5 +:1086900076B5800C25615D9C27834C9960D57FBEA3 +:1086A000E17D37D8498A7324FDA731A534B1FF3164 +:1086B00049FA3FC3D4BF6CD9FF40BF5E43BF6B24B0 +:1086C000467674CCE7A67537DB05AB33EB5664A270 +:1086D0003DEA644D5D1676674BA68DE0BE3DD0D475 +:1086E000A342FB3A068C0F7472C1E7474446F60C6E +:1086F000AC14D00BCB97FAFAE97834D6E3F46B8B51 +:10870000090CE5D20592DDC0275398B16CB68B4AAF +:1087100060AD715C9BA7B207E967953F55715AC080 +:10872000AF3F7B9AD994E212986F6A7829033EBED4 +:108730003F739F6B4D00CAE99C4E1ECEFCE30CF4C8 +:10874000177A044E7F6B7C36C24BB82EA7534CE889 +:1087500037EC60252817C348DF6E0E0F8EDFE3CF9E +:108760007FB0DD627C10BB06FB61B62A4C294E98B7 +:10877000578F6607F78F3735AF13F9A07F3C27ABCC +:10878000A2F144C07FE278D95F6CBCDFE3FCCA068B +:10879000C69B3DDD38BFD90E99E6375BE35F7DBCF4 +:1087A000DFE3FC8ABEC07838BFC4F1BE669CDF6CD4 +:1087B000A74CF39B2D72FAEA1F2FFB8B8DD7D35C4E +:1087C0004A76F0ED0E904F4027A9E53B5C6360DCF4 +:1087D000DB5D76595006DAD5D6DEE09A8BBAD73D06 +:1087E00075BA1FC6A99B069573B197A9D36B8B1950 +:1087F000DB2470BAF8EBA63FAF43BA383E73552975 +:10880000E913CDBEBE04AB823EBE44E2F0CECA77D1 +:10881000C75B12F0783FC81115E07800F85D057E5F +:10882000DC0A7C89E57873809E0F82BD8ECF6D0057 +:108830002F7E7FA83944E5879B27D153EFA7741279 +:10884000B7DBC7D658DBED676471BF6F53509E7FAF +:1088500025EAB5DAD410EA4536E93CA626DAD5ACE5 +:10886000E9A914F8BEF132568EBAF18CCD1C6E5FB8 +:108870007D36D9EDA9E57B7B9AA17CBB6457502F4F +:10888000DFAEB019567E7311EA992AB457797B7618 +:108890001EF7C37CE1DEBDA8F7E6A09D0E78F5CFFC +:1088A000EDDD8BFEDFA56097935E6687F7BE05DF83 +:1088B0005F03FFAF1DCBA29BC9509E35C74FE3C3DB +:1088C0009FF4DA6CB4DFF99FBB671E23BF229CC202 +:1088D000F5828FCD7E660FC21B722871EA8FDD1B79 +:1088E000463E50ED4A3B8982B01DF5B41FF5347CFD +:1088F000AF3DEC6436846F9A83E4DADCB946BF613D +:10890000534AB78CF6CFA6721F6B81FE2F9D69FC70 +:10891000EE74727E0B9BFC8659A6324848EE778B2C +:108920000B32D0DEBF1D5F4D1E8CB7E8A196DBF782 +:1089300026D0695E96C747718033D81928CF4EB0CC +:10894000B23BEBF1637E16192BE6F6FF6C8EDDBEB3 +:108950001750FF32CABD2AA46F2E3706F307876768 +:10896000B256EFFEE69E29EF960CC0972BC505D4B4 +:1089700003794BE17DC27C255F5C407F87898F94C2 +:10898000A37F639EC7FDC2234166319EFECC65D2A4 +:108990007B88175C4A94E7E6F94E1E34DF9A978B82 +:1089A00099153F299BD09E9BF5AC186A5106F0A102 +:1089B000CFFF7F9AAF8E6A7A86A93ED60DF4F23247 +:1089C000D07B3BF76318DAA93ABD4205B29F2EB9B6 +:1089D00004BE235DA86A01E2F3E5D17DDBAEC27679 +:1089E000203B5AD1DFD5EDA0EE8336B483BE68BFFD +:1089F000975CEB207B8BB17AF9BDD281FE92AD0FF3 +:108A0000F6FB5E82FEECB713F14FB526FA10C69660 +:108A10005080EC819BC13E467F3F5AFF8194CEBF80 +:108A20001F49B053F1CF9184FE5AF7FC4C5000AE71 +:108A3000CEE6AE29EFDA13E4C552D9B606EDB99603 +:108A4000B84071886EA807F6C0E8A58AAD0DF07F22 +:108A500025F683F46992EBA3DBA09F443BA566AEA9 +:108A6000FC08D0435B595D47089EEB37F378995E6D +:108A7000BF3F6EE68B917F6E674D4C00381D29DF3E +:108A8000FB712FCC476D9558CA1428DBB9BDC3DEE6 +:108A9000F2905C10DD4D3FC5EF8118C82D9C775DCD +:108AA000D363588ED958B8159EF7A5F1F651C9254C +:108AB0003B431827699B81D3CF0C46EECD02FCAD1A +:108AC000C94E2539E878DBF320CA294766C552B478 +:108AD0007B1644BF1BC678A4EC650BC316F4B540E7 +:108AE000B31FE2593CEE72C8DE5D900970D706EB09 +:108AF000E2D8EFA0FAD1EF517F53446B3B6CA7D67D +:108B0000CF169BB55C785CFB7EF9F2273E7808E6D1 +:108B10009356EC0E21B9AD3F87ED106C83EBEFF26D +:108B200047BA12E1482996258A83B2AEC968CFAD0B +:108B3000FFEC81AEC700E5599FB949CE66899EB862 +:108B4000506468BF33AB6A70FBDDFF7A3D80EBB3E6 +:108B50003B85917E65EC850BD19FDCD85F6631014A +:108B6000E39C995A39F6F085AAA1BCF8C25A2C2385 +:108B7000ED02514EBEFBDBEB63D85EE06516FB0EEB +:108B8000AF6FE7F573B4EF532EFAF02777A23EA844 +:108B900076901FBA51B38374F8CEF38A443FE779D5 +:108BA00087C6E3414D2EB8468EC7835678DC1D54E8 +:108BB000DFC4F729AC4B403A4EF9CC7523B6FF61C0 +:108BC000330B5F09B06F5176FCEC4E85DA1FB6C2ED +:108BD000E35941F508B6772D3FF2933B010E8F0E16 +:108BE000C74476631238FE32D47AEEC8E6726E9EBF +:108BF0008FEB8D2CCDDE74387A02B3E12957FEE07D +:108C00000619E4CDDAA2AE06ABF8F309AF8DDA654A +:108C10002689B7677839DE76E5843F4538DAE42778 +:108C20005C387EAAC0C2587FC3A45E2624F47BB6FB +:108C30008FAF03C06DF342BBD4C94C453AF3304FFC +:108C40009C019D792A39FC1B02AF3105DA794AE192 +:108C5000E9C6F7BDC4FFE87270A106820ECA0E8D88 +:108C60003E32EE6EBF10E9214BD4E92DAF1DE9C5B0 +:108C700061D3EBE75D84E5CE2C5E2EF7E5B5C7F258 +:108C800041CF38A00DCA855C07D93BE6F9E568F00D +:108C9000B6FB55BFD76F814F672FADD3C6718E50CE +:108CA0000CD6758AADA761317EBBC84DF61ABC6F74 +:108CB0008827CC7FBA4687D3BDDCDEDAF82F57434E +:108CC000DC623D92D1E978EF69D3E978AF359D9EBA +:108CD00083F84FA0D34F98359D565BB5073A9D68F2 +:108CE000850F735964EAE6460050FA74FAC377A216 +:108CF000B6FA7ACDE6C7E039E533B7E4853AE2194A +:108D00008CEC449B8BCBF701B91F9986FD4B7213FA +:108D1000BD17DD61DAAF79318BF73FA8DF89D59BCD +:108D2000516E8DA0DF30CEDBDCEF282F8777CA4570 +:108D3000EE48DC02EF27BD12F74B7D7CFC64FC5251 +:108D4000EAE37E73527ED1E93F271C413886E397E0 +:108D50000B06F865E9C8F86507F14B5A19E797B4AF +:108D600024FCC2624EE28FB545BC7CF3DD3EE28757 +:108D70007EFE899518F9275662E09F69F794507D29 +:108D800073FB749CB7055E625E7D1EE1669C877A0C +:108D9000B6DC2692BDD1CB504E75B2BE3D4EE4C37B +:108DA0001A21B41DDECE8AF5D4BB14FCDEC3668363 +:108DB000FDB14EA3FBAD080FFA43D55A3C4BEA6117 +:108DC000977A06F3B1A7B2BB349280FF020D8F975A +:108DD000F9C277E2F89DAC772CDAA5C9D6E91E0D69 +:108DE000DE1B03EA3D56743E9CDED9897AC78F4F5D +:108DF0000E77D667AE269403663E9F72FD6F3F786E +:108E000068887E7EA5C1F1A8F63C0DBE7FD46BA517 +:108E1000A783EA2F4C7C5F298CB6E4FB5F59B5072A +:108E2000BEFFB5153EBE049F3F65C5E70F7879FFCD +:108E3000C3E159F2713C4BBE2F87E723DA3ABD7983 +:108E4000FA787E33099EFFE8F58F08CF4792C8D79E +:108E5000A35E82C316C37D01E477F4DFD74D8CF5A2 +:108E6000E17EA8051C7F4DECC7A5F07EC0B4FF4491 +:108E7000003A9FF2E9BA50C4822FA1DDB144F8F55F +:108E800076F77865CD8F5056A25DBDE5EB6EDA4F73 +:108E9000003DF80FEF572BE76D3E0B793CC5C6E55B +:108EA000D065771F5E8F719A2FD17FBA55FFCF693A +:108EB000F4359CFE2F4AD0FFD88F59DE75321E4FF5 +:108EC00069F747F27D84AFDE0B513E6DBD254B4007 +:108ED000BF2E5FED16D0FEF76BFA65A397FB337AD2 +:108EE000BBAD52B72061FD2659880986FECE18AA6F +:108EF0003F331C00DF5884EF329F7A163EEFF1F6C5 +:108F0000DB7BA7650F5507D40A6C0F72BA12C757DF +:108F1000CF34CA697D1EB67017EB45FD02EE77DCD3 +:108F200082AEFC9ABE847ECEA77E34795FE5D3E91B +:108F30008AF777BAFA06E09BAEC137039F66F8CC92 +:108F400078190ECE9B104EDEDFA5897026EB4FF709 +:108F5000AFF575227D9A10D75938A0AFAFC0FE5C2F +:108F60006B6C31E61BE05F5D5F83644AC5FEB7381A +:108F7000781C75CBB2BB6A31DFA0F356B91C519295 +:108F8000BB94EB39655921C555AFD1FA35C3DFDF45 +:108F9000DED1357642198DBB1CC7BDA08675A3DC1A +:108FA000C8403B81E20FB284F1852C674700E3B2F1 +:108FB000EB858E8645A8472F7493BE6581B996F1DF +:108FC00029FDA9C79FF479B340E530F55BA8BE9CA5 +:108FD000D6D18476D288EB3B3B2CEDAAEF6B76158D +:108FE000CC6FFD90780DF828BEA5E377F0387CFDB6 +:108FF0006AC34D02E23BB50C8604964C0D77D066F1 +:10900000ABAD38CE7AD17E2A057AA1FE5EB38CFB59 +:109010000DF4B75687EB01A4C72F0B975E2FF97895 +:10902000BC1EEE9F51BCC3CDE5167D80F2B167BD7D +:1090300096FB07FAF3F666599540FF1C93950C8C46 +:1090400017DEAEE941C642814B3DFFFE7A03F3884D +:10905000F378A7A97E9471BA670117D97718864F5C +:10906000A49B577DDC1F6DCF0E3FCBE56328847436 +:109070000DE5E711FFCC05650F95F75359EE2FBFAE +:1090800044F503BC3E93E511E119DAFD81DA49FDAF +:10909000FDBC41FDBAFBC73D48DF7DFDE53FD2F792 +:1090A0007C5E7FA4E324AC2B9F7F8F48F3FF445268 +:1090B00033707FF4B2E8628A13CD8F5E43CF75CDF3 +:1090C000722DC6E35E6AEE6B6B83E765F317CB68C0 +:1090D000F7CF5F7237EDDFEBFD5F827E05F2BB22DB +:1090E000CD20BBA8C816DEE61EE0B70138DAB43CD6 +:1090F000B3DE7AA42397CAFADACBA1FDA48FDBDA18 +:109100000C794E1D943F93A2489F26C6D57539F819 +:10911000A143FD94E63F723A36CD97B1BD30FE27AC +:10912000EEE2788CE8BA4EB6E2177DDEC9FAD7E7F0 +:109130009D4CCEE8F8D3DFAF2FAE9079FE4FDC80A8 +:109140009794927ACAF7B944D0E0F4B8347EE3F544 +:1091500066C1384F94117D2848BFB3343FCEAC1759 +:10916000F4713F74448AFCD80EDEDC5A6181DF1151 +:10917000E2ED40F3D270BD1DE571570AEDDF339982 +:10918000E2FC7ABD8624F33FDFCFF50873AA349F53 +:109190000DB765C4D1EED8D0F82B19832B69E33E07 +:1091A000A98AE153E83BB108E5CB6D1ECAC76868E0 +:1091B0003C51D592D0FFC2A7FFC385F1DE8671ABCB +:1091C000FD187759C8A44F12F31DCCE33644AF27DE +:1091D000BA8DB5080D56FED61BD99CAF17628A8C86 +:1091E00048FD1D49DC476E542A1C189F688C19F7EE +:1091F0007340433A903E16AF33BF4FD8CF11B17F83 +:1092000046F38EE1661EEABD3536A2B72D8037F4EF +:10921000030B415DE2F38DEC2C8D1F7B089FFF6EED +:1092200078DEC896F9BE9B8BC5D2B206E82627D257 +:10923000C1503F792A05DADFF479F4FC882ED25345 +:10924000F7B8F532E82DC07FB84CB3738AF9771BB5 +:1092500096D1FF49EBD96B033E5E73EF531705C6FA +:10926000427F6591804DA6F2F3921FED2F5E66B1AD +:10927000A79EDF4BF6AC7C961002FE6FDBFDFCB3C5 +:1092800005E4CF6BF6D8EEE7C91ED3CB8C753398C7 +:109290004F676A7F597505A03CBABF1CC3F256CD13 +:1092A0008E5F73EFEEE7DBC83E09C7FC097AB29622 +:1092B000F1F8F257AD1F3B035776603E51ACD846EC +:1092C000FE5EAA891F1FF13BA85E514EE42EE2C745 +:1092D0005BFB248C373882AFF9500E8C2A3EA68E69 +:1092E00006FA1F55C3D36458291FB7B37815D90D93 +:1092F0009DDABAC0FF56A3DE1B589F1ED3FAF0F5C5 +:109300000857F6D0FA78CA7A68BD6C58A6B81FDF3D +:109310008FBFB892DB1BB293EF2B6CF7737ED8E153 +:10932000E7FEED0E3FF74F338AEFA2F84ECA0C1B53 +:10933000D5CFD09E6639BEC32F69F29CE3637730E8 +:10934000D2E54FB05BE17DB8B412E59B2F0BF75926 +:109350006B8BA51B919E7FACF9A7B04E77D23A15C7 +:10936000F952237CDD7EE3F75BAC5BE9C8D6EDF513 +:10937000E608C9AB64EB76D97C316C15777B5EC3AC +:10938000C3470D7FFA014E67B9ABCF81FB30EB8B42 +:109390003719F2AA5D3B6677632EB49E57BD3A2D0E +:1093A000BD06E5B679DCD73FFF2F1FE277E6BF9C0D +:1093B00096F2F1634D3EBED6DC40ED608115299BEF +:1093C000E400E3792FFD7962C229274DEF75CC4384 +:1093D000BB82589FB1B9E1C3B45FBD282032DC1F06 +:1093E0005FC88C79652CAAE705F33CD8D725704D6A +:1093F0000185AFC78410608A354AB375B962C80F5A +:109400009B3777F63EDC875FACEDC3837C317C5FB6 +:1094100062CA1BBBBCA1315CAF7D3F4E7FC7094F09 +:1094200073156E37CE75BB49BFCE0BCF0FD727EC68 +:10943000C7BDF1DFA2651EFAF9D93A5EC2E1FA9220 +:10944000C1785914161CB2323C7ECCF8A89538BEAF +:109450001A357C99F163C6C3E2B9B369FDCDF37FD8 +:10946000DD1526FCBC0EF8C17C61333E188B5C8C8C +:1094700074FBC67C91A17D3C5D9C69C73C81C5B3F2 +:109480000586F9454B58289DE707ABB3A625C06B69 +:10949000C6A3195F8B9F64A16EE877F1BD1E5ABF0A +:1094A0005734FC88DD7FA77985615EED7C5E477867 +:1094B000FEAA4CF3BA542D7FC607DF236D206D152D +:1094C0002B3DC2E7B308E6D32E0FD62727584D13FE +:1094D000D2C91253DE82193E33FC33510E4E1EBCEC +:1094E0008F5F91ADEDE38F67216D1F3F838E3584D4 +:1094F000FC43E62D0CF039A7AF85D1D9FDE361BF60 +:10950000028BF49765C0EFCCE7BC1BE7C1BF5705E2 +:109510004405F30467CF1FB306E71F66E18CEE2214 +:10952000B4F7FBEC28472E6560C642BB0B6092A8DF +:109530006FC3F52954D6FB3DD6F1B19DF47884353F +:109540006DA7FD772563EEB8E4F26555C041E39958 +:10955000ED9499E52519282FCCF8D0F1340FF1922C +:109560004678197F3A7879017515FAB318478375EB +:10957000ECBB86B107CB07F68F59BECAEDC96C4666 +:10958000FBFFD764676A764713C51D16687AE190BA +:109590009D353CEEE6FBC81509F2F11BC1DA6BB252 +:1095A00013EC547D1FD9CD7A097F57B8DCDDE27802 +:1095B000A2BB0FFBE983E4979EAF19A17C4D3163F9 +:1095C000994271B1B4F4F12C03EC62C6E70D7ECC84 +:1095D0008DD97E7C5F18472360E6733F59374F195A +:1095E00058B7F5576EEF40799CB2E49731EA5CE1E9 +:1095F000F91C69DABAD56AEBD66F4797C2FB04FC4F +:109600001EEBD0ECB0522D8E8F7FA07CAC588D0F0E +:10961000E5BFEAEB98520AFE87218FB083F0ADAF29 +:109620002738117DC89791804439C336E622FF3828 +:109630007233CFC758C894AD981FB4306A3F96D8DC +:109640004F2428111C91F5295ADC2444FD2C0AF2E0 +:109650007E5829F7F3FAE93E06ED13F21F6D2E301E +:1096600025B17D260BA1FF04FD65A3BE67EB12C6E5 +:10967000193D78DC64FD99DB89DAFEADE80C8542A2 +:1096800009727ABB663F1F0B5476D94627C7DF2283 +:1096900097579512F2628F045D0D567131BD3F5D93 +:1096A0007FF7DB89ECEA1712ED44B7A3F18567CFAA +:1096B0004FB01359E30BB8EFFF45EDC497B21B5FF2 +:1096C0006883F9FDF3ADAF51FEF8B12610988047DD +:1096D0006F742A3BEA45F92093FE2A6C008F0A93A7 +:1096E000BF25652CD27B4A344F9512F265DFC856F0 +:1096F000087E6FB14AFB65D0B40B5D71AF141210D8 +:109700006F7769713320DCB1B33D89EDF8BCF5F1B9 +:109710009C2E99E070E8E3B1500BE5D7CF64A447E5 +:10972000F43C109DAFF57E8E661BE37523E0E7A346 +:10973000D9FEC1FC2C8A4DEFDC8672E20591FCB0AB +:109740006F056EA6F7E678C0DFB2B97D582046FEF9 +:1097500086FDF434BCFAAD9BA0DD8A1DCE10AAE1D3 +:10976000E5DFF9E0FB550AE289AFFFFC258BEFADA1 +:10977000C279954832ED6F14F0388CA34520FF353F +:10978000A5C811DE01CFC3BEDADC9C04B80EFBEA2B +:10979000A93C7A0687EB18F4D9AE60BB4D0DE42FD7 +:1097A0007AF8BEF73145C960245718D913A2933F00 +:1097B000DD393C2EECCEE1F13C2987E3DB7552A08C +:1097C0004542BA6EC27D0B294679D0AE9312BD7761 +:1097D0000882A5BDA6F7E73A09C219F195666EEFB2 +:1097E000A0F7381F6C2F7A99C1BEF1E7703BD9DF23 +:1097F0000F471A87C36BEE279DBFD7F8CF0CC78AD8 +:10980000ECA941C4CB619F9A9BC3E3285C0EBB9F2C +:109810003F208C1F893CE6F9FA17072517C5F56E1E +:1098200013E225209FDA4B8FAD21B955E46AC2734C +:109830005209F693C0CFDDF0731503F669DFB43932 +:109840009518BD66CAFDA1C1F6D63B9527E6CDC1E8 +:1098500082767EE20A5DF6C6A00CF6DCDB5AB151D8 +:1098600019BD1643FD97D470FB6C31DA6721925B0A +:1098700006BBCB6C9FB941DFCF01BA58129064A4EC +:109880000BB39DD65E398FEC9A76B06B305F7BB0B0 +:109890009DC6E5CD1D511B53A1DE4B3522F9192F75 +:1098A00095F63E7701EA8B497685F44569DF1D73AD +:1098B000E8FB041AC7ADF977509F9F7708A5C54B01 +:1098C000E0DDCB3547DD8B13D6FBA54947C7A25F4B +:1098D000B035497E851EA7D97B0BCFFF7AE71E21C5 +:1098E000EE44BCDD2ADAB0DF85E51ECA5B9D26BAF0 +:1098F000699CC51BC5B89370A8A64FCB1EB01B9919 +:109900005893FD2AE2E14E3BC3F3830537F61AEC88 +:10991000DC8551A33D176902FB47397D3BD06CFFC5 +:1099200099ED98E5399AFD52C12AD07E79A9792717 +:109930003B5A3260C7CC4AB2FFADDB31E7DAEABE50 +:10994000ADD133ED1FCC92ACF7F72FD6FC5316E216 +:10995000FEE034F1435AAF63214941FCB96F7E9E6A +:10996000CE75B8FF5B0C5B8D77478E43DF8F237915 +:10997000BBB5228DF2AEF7DC72564E2FAD97725FFB +:109980000DAEFFF3769283C9F45B4A5464C530315F +:109990004F54A0A7BE9EA3A2292C513F8C4A92A748 +:1099A000F0A31C3E0FFFADCC867E76668CA9567E5A +:1099B000A95E0FFCD1E918A386FADD9900DFF5C591 +:1099C000368AFBEB7E698A9D9FF7B5EF5A1943FFF4 +:1099D0007414C0877028001FCAE1A2681A9547470F +:1099E000BDF41C13CDA46771348FBE9744C7D0F368 +:1099F0008C6811BD3F337A36954BA313E839365A3C +:109A00004ECFB3A2E7D1F36CD05B58AF2C5A4BCFFB +:109A100071D1AFD3FBF1D139F43C273A9B9EA1E839 +:109A200037E97B7974313D2BA28DF47E42F43A2ADA +:109A300057466FA0725574253DABA3DFA5E7C468F8 +:109A40002B3D27455BA8DEE4E8062A9F1BBD9B9EB5 +:109A5000E74537D1B326BA85BEEBFC9CA6D9D32FF8 +:109A600006B6C9946FCFBACB503E26E3C3439A3CA7 +:109A7000AECB51F722FDE9F5F66BE70ECCF50EE41F +:109A80000C9D77F3AAB65E1F858EFC008FD3EAEBA0 +:109A9000B63E30741C8195F986D9B7E2F37B3A471C +:109AA000E1F42B7590BDB1B589513E98A7B24740FE +:109AB00079D319906658D1913BC0F3C08A7222477E +:109AC000517FB883EFEEC5FDA84B623DBEA9482F7C +:109AD000215FEA54E86F549B8DDC6B85C902969533 +:109AE0007A2677B381780ED85706BD260574FBAD6C +:109AF00067E60484E7ACE20AB25FB5FDE4FDB78C2B +:109B000066E8776C75740B12CACB558C25DAE15B6D +:109B1000D72E7A28F19C8614E0FC396A1D7B0AE373 +:109B200064451D4A1D9E271CB3597D0A533C4BE2D8 +:109B300091BA54289FF970EC297C8EED8AD7A5C183 +:109B4000F3EC9DDD4FA1F819D7DD5BE786F239CF45 +:109B5000B2A731FC54DEA34CF54079C201F569DCB3 +:109B600026A9EA8D4C4D57109E786B3AC0B3F56D1F +:109B700030B4A03CE9C30E11DC9281F507BBEDF1D6 +:109B800084754929EE5145F867FE8D7239CAD9AD01 +:109B9000526F4A66D9E0F5E9C479E33C41AF6CD72E +:109BA000F6D1E584F50805043D1EE80B24C4033B0B +:109BB000DB5EA1786067AA5C8BA1AEBE694C7E506B +:109BC000413AE67E42EA9AD1A49F74BA03FC1AECA9 +:109BD0004929C0E96E6BBFBD698DDF10E2B7EA7F2E +:109BE0000F7EFF3347935F49F0FB22CE23383C1FA3 +:109BF000D706385F021F9F1FA84A5EEF2A0DFF6637 +:109C00003C6F95E4B3085F6E668B950FAC5BA34623 +:109C1000DFC3E1F59BFFCBE876526068BCB24A2F08 +:109C20008F336BF969C9E4CDFE24E7449A0283E4DB +:109C30001C8F97CA20E7C6249773358161E4579239 +:109C40007C87DB027ABE43F8BB8111C4F5EFB0C953 +:109C5000B598EF121BCFC84F00FBB20DF37746C586 +:109C6000940ADAC642A18C78AC389BFCF422B03757 +:109C7000A40A86A98EDDF8BCB832D3B6A80CF31AB4 +:109C8000347E931B0389FCA6EBFB017ED4E922AB57 +:109C900093CE5900BD623EE12E0D4F03FDF078C416 +:109CA000DA9B733BDB13E46067288FCA7AFD64F4A8 +:109CB000FBA6F61DE405EDF75F5C639D6FF2EB809C +:109CC000A8D9397D2AD2796C0A93E9BC73DB119249 +:109CD0004F99209F84221E1EC2F1F3A3A90F619CFD +:109CE000F657816C4D9ECBA99779FEFFD1733BF857 +:109CF000EAC44F35F21E3C57310AF4908272B20624 +:109D000060AF443DE7A07557185F47A586C5BB0502 +:109D1000C25B37FACD311B3F9FB1DFD1A592DE7117 +:109D200064CA987FB2CB1FD91BF027E70B394D29A6 +:109D3000C745FDC3E66B67BA83989723A762F915F9 +:109D400028DF3109F3847A9956BEC33DF98BC71FCA +:109D5000FE10B8663FEE535507D457919E81AEFF73 +:109D60008070A967CA12C58747B8FFA4F3E7003F10 +:109D7000C9E53A3F3596913C7C2790B04F9ECCBECA +:109D8000F9A1263FFB0243DB373ADD9FB67DA3C135 +:109D9000FBF630FC3FF3B957376F6303F13F4FEEEB +:109DA000EB3D9282F6F654767402C6BD7A38DD3306 +:109DB0001EE75331FE07749052E932C56D85195A7A +:109DC000DC65C878AD1E4FD6E37D7A5C2F5DA32B92 +:109DD000BC3000F578FA24595A44FDF5B24BA13F46 +:109DE0004F90E349E76B945BB83FEF5A93258D2E74 +:109DF0001BE8172425C9A9CE0626B767F2FDD70CA4 +:109E0000902F1DAB19F979B19744EAFFB86AFBC0EE +:109E100009F58E570202512EA84C91B3B573084430 +:109E2000E432D1AB93B12EF4B7D9F7422E07C6B9BD +:109E30003F15980A70EFFF54A4A784116E687471DF +:109E4000A83C848D6B336A42B81F281E8532C059E6 +:109E50009F519381E5FDFB27849845FCEEF248A3D2 +:109E600021BE64C6537FBD6FADA17C852DC3EC7F41 +:109E70004E0A3A74BBB32288F6CE957D6D0E6560AE +:109E8000FF53DFD70B163F7121DEB3135CC6EDCF56 +:109E90005C166F49B49B12F6176BB09F2D03FB8BBA +:109EA0003D6724EE2FAEC8BD158FEEFFB07F7F312A +:109EB000720ED657BD5DE5489F7A3EEC7E07DF0700 +:109EC00060135EF02916F4B1A0FC193FD1A3E64F50 +:109ED0000CFAAEC5CDCC7EF0ACA0318E7F3C3427E1 +:109EE000A31B3F2689E3EBF13CDD0FC6789D6CC9CF +:109EF0007746FCEBE32F10B81FCBEC02C93B5D6F3C +:109F0000823C8904FDD48CE2D1AA53A07CADE3A1AC +:109F1000C50AF94549E44BFFBE01EB2EB1DA675D96 +:109F2000A0E59D98DFDF1CE4FA79819DC72985951E +:109F30004B2238EE82A04B7026D8495705B9FED285 +:109F4000F75F1CB927AB10CF0E4744B19AB7791F02 +:109F5000E5AA20EB3FEF16B2D07BC9F074C0DE411A +:109F6000FB72079688745EF7786422DDFB904C2EB6 +:109F7000BC89F453C25838978F37B08ED678D3F354 +:109F800064CCFB55FDDF1B53E8FC8D395FE6510DBA +:109F90006FFB34BCFCBBF365F669F87B518BCFE8F3 +:109FA000F1AC8B93C8FB736D750F131D0D139739AF +:109FB00043CFF7D1F0C39E1E4BF7726CE8B1C75385 +:109FC0000484C746FB970D7F1043687FE9EDDC26CC +:109FD00079A1E7EFE8E5B493028B27EC23A4495D70 +:109FE00014274D3B29D17B33FFDD6EE23F7D5D922F +:109FF000ADB3BE2EE6F79DDABA1C68FC8F009E77E3 +:10A00000D990C22CF3893E0B1AE3EFE63C8064FB47 +:10A01000DC07B576C7239373502E3738622523E1CA +:10A020007B1D3FAF7FFE1B17F2D98693CE1956EBEF +:10A03000F14A90FB2DA04FD725EE837AE6BFDA8652 +:10A04000BDA649C67D505D9FEAFBA06995E67D34BB +:10A05000EB7DD00DCC5A3E26DB071DB4FFA9E9DB12 +:10A0600013C124FB9F65439F67DFADD1F370791F58 +:10A07000973BF87959F3FB17FAD7617DC10F80AF91 +:10A080006E6874D2EE5377A393F87071630AC56556 +:10A090001797F378EFE27B056DBFCE18877D11E44B +:10A0A000C5323C5FAFE99DA32C5C8DF6E8AC4AC19C +:10A0B000B04F1EAE493194E72FB9FB45BC37E1A53F +:10A0C000497685E2CFD0570CED821A9EA7C894BE80 +:10A0D0003B30CEADC79FF5F57FA9E628DD8316039B +:10A0E0003BBF2484F16791F8EBA5D726F07BE98488 +:10A0F00081FD7005EC840DE78EA17C8F8365DFA068 +:10A1000038EF068C8BC34C377CFE9B194447A094D8 +:10A1100063C8AFE3B3E2281F178FABC846BA7C7A97 +:10A12000FCA71E8C8BBE73EB713FAE536F7313E5B0 +:10A130001D98D7DD1C6736C7974F379E3C31B73F18 +:10A140004F80E8E145533C59975766F991104FBE4F +:10A15000207704F1645D6EE97242975F07CBDADF26 +:10A160007A10FE7930E22498DED4E6DDCF971A5DCE +:10A170001ED4F9F07327D9234F8FFF2DE55BE9F546 +:10A180009A8399C487DF288BDB697F16F3144A070B +:10A19000D6657EE49AFE3276FBCDA52B0DF4D12F49 +:10A1A000A786956343CB293197C72792E56BEA7C55 +:10A1B0003058FF94909D9AF67B7BDC55F4C5F550A2 +:10A1C00043E3AF146C07CFCDD47EBC2312B7D04F7E +:10A1D0006678D24E8A2C3E21F1BDC2DFF7EB010733 +:10A1E0007D8FD529AB57FBB83DDD4AFC1973D2FEF4 +:10A1F000B94F6DCE85FA3EBF1A437A78C8A7B6E448 +:10A2000026C8D3563BDF8F146D2CF2B8055E9ECC6A +:10A21000D5F4320B07B0BF35B5C6F35CFA737B2EAD +:10A22000DFDFDBE3AF0EA07DDD7AB83C80FCB3D787 +:10A23000534DF676B275BB53E727945F2503FEC4F2 +:10A24000466DBD814555DCC75D630F0712E38DEB9D +:10A2500072791E47FAE4277AD06E6E956D9427D8EE +:10A260002AF3FCEB36B734639BD6CE676827E9E761 +:10A27000A8E8BE0CC96DCCAF7E52B37792CDF3C9BE +:10A280005C9B76BF68F73D35C2805EB11FA975D172 +:10A29000FD0F4C95797E53C8904F6DD7F44B9D2997 +:10A2A0005F4394BF98DF16F44776E55AF86D7B7CE0 +:10A2B000EA93B8DE5129E644FA88BAACF9FE696D32 +:10A2C0005DBFA7CDD77CAFAA68BAF74134DDFB10DC +:10A2D000AB6BFA692FD2DB6AA7DCEAA37B1EE8DE50 +:10A2E00087285EB904CF7FA6F07C16F0FF26F2F334 +:10A2F00006A15E94AF2CE0A2785447BEAAE643596B +:10A30000F4D81E5C0DFDB5AA752A1E5DE970DB3A16 +:10A31000719F2F33183988F398EA9148EF745C9451 +:10A320004A7A08BEA77039C264A19AFC41BA3405C2 +:10A330007D703C5F660F38289ED51A61BDCE31FC1A +:10A34000FC3FF653CBBAF7D714A1BDEDAA443CEDC0 +:10A350000F4DC88858C809FD69DEFF7FEBDB6F141D +:10A3600062BB0231F221E2BDA761F146DCD75FB1E9 +:10A37000530CE13EC2B7BE73F00C7EDEC8B8CF7C92 +:10A380005FDA945ED46751B783EAEDF15477209E8B +:10A390005A054F07FABBAD8757FE18F1D8DAC2E36A +:10A3A000DC663CEFF57C87EED7380ECB89F5CDF730 +:10A3B0006BB08E957C9D9C2EDAB784F9B2BC2ABE18 +:10A3C0008E141F3CE4A17BA08EEF7FDA8DF07D8997 +:10A3D00079A7E5F9879A77BE4CF68B463F4C0AAFD2 +:10A3E000C379DD247A3ADA7D784F1AAC37C2BDCB17 +:10A3F0004EFEFE7D69E9B4AE51800FD755F4D4AB63 +:10A40000E892FD7DA748EB1C959A685E2C26B1ED7D +:10A41000F87ED789EF9F8774A066D1AE9658D04456 +:10A4200078F93BE065B5055E807E8A10DEA777DDB2 +:10A4300040FD74385C325A36AD9E6A3AAF3CD2FB6E +:10A4400045CAF2389F24DC2F52965765515FF3B30B +:10A45000D0DFC6716B65F6499C0DE03D59FECA79A7 +:10A460005AFFFDFD0C9FBF725EE2F8FAB85F625DB5 +:10A47000A79FCEBAB6BAFEEF74B4B354313D94522E +:10A4800008655C27C43FAE13AE9716B72115A4200C +:10A490001DC8DD79480737A487903E87931B12E3D8 +:10A4A000EB6E97809EC1AE73CA91037476518BF7A1 +:10A4B000E8F2C4CC67AD2EA3BC6AD5EFE53B3432DD +:10A4C0007905F47215E2C12CB7464A272BF304F341 +:10A4D0003D342BF3FCC9E9C41E0CDF80EB8878CA3D +:10A4E000ABA078C5B7B1FEFEFDE20EC7681C8FC7F2 +:10A4F000CDFA824C7E30212F4B87A70D37BB799C3C +:10A500009AE21F5203639807E72D0D0972D988E874 +:10A51000A82D11BEAF808EEE1C8A8EDCAC87CE6B70 +:10A520002CD7F373760C9D9FF365F50FAC6727E28C +:10A53000B7D5F31DA2CFB57697CCEF513BBD757D56 +:10A5400064F0BA3E32F4BA461EC3EF6A5E35DD638C +:10A55000C4263592DDB4CBAFBE8179A44C0A19E490 +:10A56000E220FED1E4F64D672A94AFBABB4593735F +:10A570002D4E19EDF1677C373C86F5EF624A18E302 +:10A58000A1536CAB084F7F87F93D1822B95A8AFB5B +:10A590003E51961AD2F4E8538887194A8B9005EFFA +:10A5A0007D0B141B5D43AA6C62B6B291E3E1C5C199 +:10A5B00072F0C561E4608F46CF37223DEBE7ED9343 +:10A5C000C9C143A72F070F7DC572F0CF79A7A1D7C7 +:10A5D000BF0279F3098E6796376E8D9FAF08B11071 +:10A5E000C6CB479ACF06F6A682FC559BEE22FA69A7 +:10A5F0007D5CA07C29B0C32354F6B848D8ECF5386C +:10A6000078FEEF0EFE5DACE37836E3E9F3BC2C9EFA +:10A6100077D3B5322C19F2A462C40F77AAC7E462CB +:10A6200011F3FB6B889EBD9A3DA3E7F5A76BF2BFC4 +:10A630005FCFCFB4D178DE022EDFBD60EFA05DC466 +:10A64000A45E867EFC4D793C7F1FF881E81B46099D +:10A65000233F644C924C795A9C5FFC12B777327D51 +:10A660004C205D837962F0FE04D813783F41A66ADE +:10A670006C7753EA1502EAADDE46779340E7F4C300 +:10A680007B7E04E52CCCF702BEF1CE30D6F7B38446 +:10A69000B2857F1EAB63A598B75896AFF9E90E1641 +:10A6A00020FDA8F9E9FA7D81E2F0795F95F9238828 +:10A6B0002F9E9BAFE79918F571570AB38CAFFD57E2 +:10A6C0003E975BF5BDB5756857AFF230B2AB56A19A +:10A6D000EEC472A683EEB509EDA97459DD5791A9B0 +:10A6E000DA0CF7F37A67A41AEEBDF587B30CE59C94 +:10A6F000865C43FD6064B4E17BDED2B30CDF0B9A71 +:10A700002A0CE551D1730DF58B00C189E531EB2E93 +:10A7100032D42FE9B8D4503E73F3370CF5C7C617BF +:10A7200019BE9FFDF0B586EFE3BA5619CAE7ECBC37 +:10A73000C550BF9559DFDFB9219FCB29E0779263E0 +:10A740002DEEBA06FA1D0DD96188F32FD1EAEDC9B5 +:10A75000AC2EC57848EB91F252F287D3CF1DD21FB1 +:10A7600036CBC564F2D8FCBE4D1BEFA3A7DEAB5EB3 +:10A7700086748E421EE4D247EE37D7E29CD697F11C +:10A78000BC04FD7731CCF7F2F7EF534A2ACD67418D +:10A790009683599D0F5892AF58EE2FB4092117EEAA +:10A7A0001525C39B4E8FC3E1ED0EADDE97C5DB21B2 +:10A7B000C11807427DF2B8055C7BF3FBEF3B7828BC +:10A7C0009FEBABCA54F230F83D0EA7AB4F74384044 +:10A7D0009F3C9EEF1F9C1FFE51C3AB57DDA760FD42 +:10A7E000AB787D5BA814D725D9BED2DE7CF3BE52F0 +:10A7F000D55294730B3CA942E27DCDBFD4EAE9F176 +:10A80000ECD6F44F695FA9D5112A1DC9BED22FF12C +:10A81000CE8D2AC4BFC2C7D3D7D5AE06644BFFCEF8 +:10A820006CC7B0E7F01E8C985BA2BC61B37F17D5F4 +:10A83000E4B6EECF497B6BC9DF6F758FA6BC8F5630 +:10A840007515E9CB8E247E2EE8CB3FE657613CE0C0 +:10A8500046833F37100F50693C684B76536B82FF3D +:10A860008FEBA0DEC7EFD5FE0AFCE00FF34FC34E1F +:10A870005018F7838F338EA7E3AA8DEC84E360270B +:10A88000A0FC5D2331DAF78E550A8A955FDCB15A58 +:10A89000B30F5773BC99F7BBCD76C6C5A19584B7E6 +:10A8A00035404FAE4A8CC771FB778D9DDFBF297B4A +:10A8B000C301D4B77D7E077B10A0DDEBE7F1391D26 +:10A8C0002F5F541E65160CB293330B86B093A78985 +:10A8D000655D786FEBB1933C2EA2E051441FDE43DF +:10A8E000CED76FD57373622B504F15494D98BF2E3D +:10A8F000322503F1B2E25991C5059463C6FC7C3B55 +:10A900006BFA01C6E3988FBF8F31570BDA49199361 +:10A910008C7A2C5335EA31EF8C2C935E33EAB19C60 +:10A9200006A31E0B468C7A2C6F698549AF19F5D8A2 +:10A93000A8689D49AF19F5D89875979AF49A518FE0 +:10A940009DB9D9A8C7C6C68D7AECEC875799F49AF9 +:10A95000518F9DB373B5E17B7977BBE1FB8467EFE2 +:10A960003294AB7AEE37D49F78E041C3F7C9BDFF8C +:10A97000C7F01D10FD0A9E67C07B687111CF7BFF79 +:10A9800009E377A63A301FFF3A3C9F09EB787EDF58 +:10A990006F0DFDB10E7E6E2106FFE17AFD9945E84F +:10A9A0001E009063FBF2A0DDF57121D4CD503F3D38 +:10A9B000FE1EEEDB5C1310C98F5B81C156A4874776 +:10A9C0003C71A487AB371BCF3F5C13379663403F86 +:10A9D0000AC615807E90BEAE33FD6E04D883446FE8 +:10A9E000D7295213DA9566FAFAB34E5F31F5153C62 +:10A9F000CFA1CF579F9F5D3F7FAAD19FAAD11F13A1 +:10AA00007711DCD7E589F4FB3BFA7C55F88F7FFFA3 +:10AA1000D081F338B153605EDCDF67B17D7916F326 +:10AA2000B97EE72607F2A7795EE6790CB2530B8C64 +:10AA3000FB8AD3447788F8EE3591F4114D01F9EC97 +:10AA4000517E5E6FD573229D8B413E447F418C3594 +:10AA5000105E56005EF0DE70DD6E3DA6B53BF68002 +:10AA600048E79B87E34745C3873360E4C71425D590 +:10AA7000444F46FCA6951AF9F3BAB72F74A0FCDA36 +:10AA800007F8162631E60919F9F53A7119EDF3E9D7 +:10AA90007856E03F1C57025317E77D3DCCBB5B194E +:10AAA0008CDFA5BB36ADCDB3A09BE1F0FB48817137 +:10AAB0009F4EDF9FAB05EC382CF24A75FCEDF2ABF4 +:10AAC0004FA07C4CE60FEF2E30EEAB8FC01FDE9D0B +:10AAD000286FBF027FF8B98221F55CDF2CF4A79CB8 +:10AAE0002C3DD46E11F79398DC8DF15A7B138FFBBC +:10AAF0000DC4EFBEF238CF3B08A724733D9922E97D +:10AB0000719ED08108DA27196785302F6AA4718E6B +:10AB1000BF140C8A73FCA560E838C71B780E50CDB3 +:10AB2000C8ADB7213349A152BADF1941E079481FB6 +:10AB3000E3BA0CCAD72DCED2F28F9521F38F2FD640 +:10AB4000F677AB03EA498403FAFB149FFDF7B1558E +:10AB5000FAA99FF461FA89D5717B2D66F374B472FA +:10AB60007B8DF699BE8238467A21FAA56E8EFF5605 +:10AB7000078FDB9E6E9C2D583808EFC1C221F0FE76 +:10AB8000CFB772F8B9D5105807E5C9E95B3F87A977 +:10AB900097D7671AFDE5B5151CAE126DFC6F66738D +:10ABA0007F607221E73F3DEF12F316532AA03C93DA +:10ABB0009F53D2CFB5EAFD4C2EF450FD4F02759352 +:10ABC0000BFD9837CBEFDF599B69BC87E76F05B565 +:10ABD00093715E13B4FE2717329ECF3C9AC365CEA5 +:10ABE0003BFD8756FF1F0575F4C473B4E8973844DE +:10ABF000D1129F530A799C40BFF766BA7E7EEE5E03 +:10AC00007EBECE7CEF02F0C9EBF8FB5047EFB0936D +:10AC1000BF07FA88CECF2DC9E3E710CDF729444A04 +:10AC2000E57D285E4FB032CB7B7906E5391CBA99B9 +:10AC3000F2EF5E9ACC6421387CDEC36585C6FB11D9 +:10AC4000BEC039BA2B0A4790F7B0503B47D79BCAD2 +:10AC5000F5585FD0157FD0C2DF8D6AEB7487E6D7D9 +:10AC6000E2FE34EE93E3FDDE56FBE5D1424E3F2398 +:10AC70003D577D97231241BE359FAB4E769EBAD786 +:10AC8000D1BB2607E11DCB4268BFE72C90F7E4401B +:10AC9000BDD47A85CE3FAE2D62E993F07BB92D8489 +:10ACA000E73A32E7CA6BEDC8A7C52C4B80726F6CD0 +:10ACB0000E8D7F4703934580ABB390EFA32FBCF578 +:10ACC000631ACF5F035353E8DCF974F4CF620D8C41 +:10ACD000EE2D34CFF32E8D5F5C6BF83D3919C5D660 +:10ACE00079F87769F408726B13F2456D31DBC1CFE7 +:10ACF000CFF2730A782D3DE56F8652695FF01258E6 +:10AD000037BE7FDE43EB776360EA7DB89E3ABF399A +:10AD1000B43C05F379F2CEC2D33B4F9EBAC01ADEE3 +:10AD2000DF69EBDDE80FFF14E14D2DEDE0BF5FFAC9 +:10AD3000F9A95362B5F6D38E0AB68F4450FFA580A9 +:10AD4000FE13F0A9C8748E96B9043A0FEB529A8894 +:10AD5000AE522685BCF8BB68EC4A1BC37B5CA66A76 +:10AD6000EDD50626E0EF49502E20C969D3EF4BA858 +:10AD7000A1B616683F0DF7CD4298F71D5A8AFDD54A +:10AD8000BB53658C6FA61437D5E27A3DB390F7714B +:10AD90005792F312FA39FB81FBA796BDBCB726E1A7 +:10ADA0005E81B557BD6CBC7FEAAA97BFCCFD530747 +:10ADB000B75EF5F2FFC4BD02BA7C03356447BBFE43 +:10ADC00080C8EFD1FBFB9397DB711DD6D6B22EC4A2 +:10ADD0007BEC53C0B36B00CFF6BAF0335BD02E5987 +:10ADE000951EE2BF2712FB16C2F9761A93B1BD9EDB +:10ADF0006F28B052D2D7731B04B21F98D4773D96F8 +:10AE0000E7EF4A93D17FF8FB936F14C4803EDFBA1B +:10AE1000EDB807F353DF91FA3C08D7FBB7BEEA4120 +:10AE2000FCBD75AB48792874EE3B214FEC738DBEA9 +:10AE3000168C0A1F47FA5AD8FCDFD589F6198BFA07 +:10AE400049DF5F13078813EDDE87D30CBF2BBABC35 +:10AE5000CB6B28EB7A7EB9D3FADC7CE5282E97AE53 +:10AE600079A4D391A7E0F811FB2898E7FBDA39A081 +:10AE7000F77778C88ED7E159F448B903EDE17776D2 +:10AE8000395937C5057BECCCCDF507E65D44F8D0E4 +:10AE900083E0DCB73BCF817CB644607D4E626EB60A +:10AEA0000FF1FD27CDFF33CF63C95BB203D77749DD +:10AEB0002DEBC373678B6E14D6DE04F51745DCE407 +:10AEC000F79BE769D63757E37D3682D53D704DFB5A +:10AED0007E07FD5C09FDA0FDB9A4C3F8FDD8B3371A +:10AEE000ECDB02E3EED8E9207BF1EA61E2FD6347A7 +:10AEF000697AA99A4D3C3586F45FC63825B9DDA13B +:10AF0000EBA3F79B1925A9FC057FDF179E1F36CB06 +:10AF1000F43C5EA8D07A5CB773CF3EFA6D61A9A706 +:10AF20001AE5DDCCE716A77D830DE4155577DEF035 +:10AF3000F41662053D5FB59BE27B13B5FB5FAED6B1 +:10AF4000CE7F541D30E7ABEE79E67768B7C1FC4F92 +:10AF5000E7DE9E0523BCB7E7D8B353D3E87C808EE9 +:10AF600097898017F1CBE32559BBE5497EB745E7C3 +:10AF7000A7E39ADEBD72DBECB5B9307EEB937F2E92 +:10AF8000C4F8718C71FAAE7A80FFFE4F953B9BE856 +:10AF9000CD85F41944BC9AEE7988B1D759027D5F0A +:10AFA000BD2B8DE82400F6907312BEE1F45A85F7AC +:10AFB00076227DBFC6DBBB34FF36B2EB365EFF7751 +:10AFC0000ED91920BE0CD8E8D91DB04DB2B867CB48 +:10AFD0007CBF5887B1FC91BDB710E5CAD5263FF4B8 +:10AFE00023C13A3FED8A51A3497E5DA9A8D3310F11 +:10AFF00060090BAFE5F15B7E6FCFFB52C7BEEF225E +:10B00000BF6F13580CF0B4FC378FFE1AE5D8B58F1C +:10B01000DD9B8E72EC03A9231BC75BB67D4D3ADE28 +:10B020002FF3BE144BC7F61FC4B93C1BA42F47090E +:10B03000DABE949A2E804CBE9E480DFE7F65DFDA04 +:10B040005B609C7F009E91EFAFDFF12F2AEF535D95 +:10B050007D2C80FDF64E4738AE697437B584D0BF7D +:10B0600034F2E7B53FBD375BA13C8F589E86BF3CAD +:10B070006C77FD363BE5F9A21F8FC3AC607D343F92 +:10B0800073FB155D471D28AF651BEBCB3F6FF0775A +:10B09000B0901CC86F2B766CF8584CC7E7076FE26E +:10B0A000EF41AD30D9A74B35F96DA6FF9F9BE81E48 +:10B0B000F043F18518C0C57F8E89CBF1D69FDD376F +:10B0C000FE30C0F7E1B617D2F1F72674FAD7EF7960 +:10B0D0003ED6B578A163887B843ED2F8A45F3F68F2 +:10B0E000FA49D90980E54071177F2EB377A79F07EA +:10B0F000F35DD6690F21CD2F7B5454DD68571D7445 +:10B10000923DB2ECD1E344B7CB04B54F203DC7D25A +:10B11000518EEBEB75DDA37F9A8E72FABAA0C866EA +:10B12000022B5EFBCB13BC3ED0790AD4BFEEF1C339 +:10B13000D3BF8B6590272E8BF59ADAB5C7D1EBB6C6 +:10B1400058AFAEC3D3313EDFFAB37FD27A7CB05B67 +:10B1500060394583DB2FEDFC13C5C13E8485F16664 +:10B16000727CA1BE59D125363A32ACD6AF7BD66FB0 +:10B170002BE93BE5850FB78E1B4631AE1F7FF3E809 +:10B180002F7E0B702C7DD3199A89E3FEE28674061C +:10B1900074F067A989D3FD8FD664A3FE5E6A8F65BC +:10B1A000CBF4E4EF976EFD36D1E3D5BFFF76B6B6AC +:10B1B000DF10B4913C8805719E4B1E9847F3BC8A02 +:10B1C00045881E97FE88DFB37802FC6C2B3FA152A6 +:10B1D000E172CBC9568EBFC5877213EF6C01381C64 +:10B1E0008CDFD7F50ACF7F77B24B3312ED5C87C285 +:10B1F000EDB9188BBF8D76E70A50CB28D7C4DF9FF7 +:10B20000988EFDDC58243539293E6A7D7FCDFF03B9 +:10B2100074C90FBA00800000000000001F8B0800F6 +:10B2200000000000000BE57D0B7854C5F5F8DCBD8F +:10B23000FB0A792D79404220DCBC1309718104128C +:10B2400040DD10C020AF0D444589B0040C0112123E +:10B250009116ACFE9A1B0208946A50AA54D02E088C +:10B260008ACF0604C18AB01145A8FD300AB5F8A2FC +:10B270008B206F6441A8EBBF54FEE79CB9377BEF8E +:10B28000261168FD7D5FFFDF3FFDEA70EECC9D3B40 +:10B2900073DE7366E66C0D83BF64C68A3E1ED6D528 +:10B2A0009BCD98855D34DF97CBD825C6A467EC8C01 +:10B2B000D530A3ECB532FABB9AC4D88975964EC284 +:10B2C000CD507661954DD0FE2AFEDD1628A74A02A4 +:10B2D0006379D4FC13D69FB1D9F82F09FAD97862D3 +:10B2E000F86AE897C5892C328EC3CFC430662B0F1D +:10B2F000AB8DCC87EF1D3C6AEE06F5728C81A5D92B +:10B30000A0BEE51B82993D56C2F66AFF35DB2DCC07 +:10B31000A38E07FE5FB3FE1B33C37E0CCCD77D50DC +:10B32000DB7AC66A737E1583F38894964179C2EC02 +:10B330001BFE367E07BEBB01BE53B112DA676AFA46 +:10B34000DB72EA739683EDCD81E749F8DF057C5E19 +:10B350006259A42B8CB1E9304D56D076FEF3BFACC8 +:10B360007FF43D4D7F395278CCF150F8C70036E07C +:10B37000AA18789FAD89652CBEEDFBDFD7C98FBEBB +:10B3800067C2B765C6A04995C9FD02E2A9EA338B39 +:10B390005D063C56BD76D96C009809CC97D699B11C +:10B3A00033AFEEFEF45E98CF992653CC28FAAA2349 +:10B3B00042E812C07BE5E66F86AF86F626C07B08C2 +:10B3C000D073F696EFCD06681F57C47C1618FF9908 +:10B3D000182763BD116FA6AFBD1ABC15C1736F18D6 +:10B3E0008D23C11087A5278141393B86D93DF0FEC9 +:10B3F000EC83A25D427C31DF625B58DBF76B9A8E97 +:10B4000006D1455FCF98CFECC4EF6EF9CD05314240 +:10B410008B77E3D75E0DDE553C07E3F59E20BC5EDF +:10B4200066D991F01976FAE5593D5DD96DF1ABE237 +:10B43000F5DB3A864CDEFAFC624F89F02C6D870F03 +:10B440007585BA1D4AC9D8A74C83C799AF9C23FEFE +:10B45000FD47BCC844E09BD9EB7F588C7C0568F560 +:10B4600059807F67BB2F10BCC861F531829B4B852B +:10B470009CF6E6ADC767707D77446A5E80FEA605E0 +:10B480004C0E877E7DEF88EE7530B4F3922F220A42 +:10B49000E6B728844D764279DEA6C09D55984D9E2C +:10B4A00002E33C2FE7D8647C2F844D6802FA9C7736 +:10B4B000FA223A8705E67D64871821417BAF9B1508 +:10B4C0003785B5E543C61AE8FB5ED6517D3D8D73E1 +:10B4D0009878E5752F7CEFA26C6416F89EB7FEFB9A +:10B4E000D7BD501E335A6D88A769F5774730037C66 +:10B4F0007F47CAD809D0EEFE7D803F9A9EC31C0FBD +:10B50000F89DCAA7CE4E32F9A9C1303F313C77CF62 +:10B51000DBF07E052056047E9DB65C8F9F99CC198A +:10B52000E94942B93505F884FEEB367BE0BDE9AE6A +:10B53000B0DA65F0DDCA35FAFA993BCE107FCD0C52 +:10B54000E22F17F2577C5BFEDAA0F2571FD607F9FD +:10B550006B981866407E3EBF57745BE09D8B0B4D29 +:10B560006C31C0175F15DC0CFAB9B8031A21BC9D09 +:10B57000C34C8E25BE55F95CC5DB59E4BF8CB6F8CB +:10B580006CADDFFA55FF87A149D59B5FE4AC86F22D +:10B59000EC9B9FA5BF8DF0B6BF257EC1DAB62FDA32 +:10B5A000F9C3241AD74E0BC3719DDFF941E2C308DA +:10B5B000FFC96247BE3DBFC0E260A8EF7686BBD33D +:10B5C000B0BE07F003D0BDE19DEF7350DF33B690FE +:10B5D000E8D82299A9BCB8E39F87059CC70E8B8445 +:10B5E000F3A8D9094880F76BFE14E266F8FE3BDF4A +:10B5F000F77785FD7CF3996D662EE2CF7036613367 +:10B60000F26F67E6C0F9D4BC5DF07C3D7CBF7A4B3D +:10B61000B3792AD417EDFA570EEAA3F39B9BCDA872 +:10B62000AFBE35799F63C01F5F48131B4D80E76F26 +:10B63000C3A1B36E8CCD4D5AED94C3DAC30BC7C30F +:10B6400079C003CE0BF052E9CEEE181F17FF6BF155 +:10B650007161127EBF6AC700262669F12238F8F3AD +:10B6600070B755A0F9F3E73BBFCF6161D79EAF2D0F +:10B67000C94CF2FEFFCB7C7392FE5BE9CBF9FD4D2A +:10B6800089DBA560BE6FCBD7DB7E49F0EBE1761A94 +:10B69000EF75CAFB98FFDAF9FFEFD0BBEABF76BEC1 +:10B6A000D7A2F73E85DEE1360BEAAD77FE95C86E90 +:10B6B00060DEBFF97F74DEADFE8FC16ECD85F17D9A +:10B6C000CEDC77160AE495B4EB8F6C4F12A83D538D +:10B6D000D61D6314BFA2817D3D740A7C57067F028C +:10B6E000FDFD86B0AF8D07016E013F01FD0B86CEDB +:10B6F00009E0A1A5B48F7B19DA6D632DB3016CFA53 +:10B70000742AC113CA7F30E642FB3BC1CFC3F6FBAC +:10B71000EBBDD3EAA17E7F6783D400F058C7F8B4AD +:10B720002D00DBBA89365CC73438FA5925CDF8C606 +:10B73000E6EBD723F706AD2BEE9EA0AFBF8BAD8B0C +:10B7400035427F77559A981BA6746750FBA7926C79 +:10B7500034CFBB59ED225BD88DE3E978125F9F357A +:10B76000B0BE7B25C48B43B46F606DF1C6106F888B +:10B7700097B87E6C991DBFE2351E04D8A2F857F029 +:10B7800047F278678CF505C49385CD61BF84FE2EA2 +:10B790004BC65A6C6F61B06EE4E316AE0A6DF106EB +:10B7A0007F92B13FB9E24482B18E0719E2199FF747 +:10B7B0008CD3BD4FF30EC6F38DE37541DA5388D7B2 +:10B7C000D270BB1BF9C2F17CAC11BED700781684D5 +:10B7D000003E553C05E3FD6DE40D8D5FAE96D9CC82 +:10B7E0003709FDCE0816615F06FD4758BB33239F1E +:10B7F00087CF128F858DE17A4D1CC29A96C17A8DC2 +:10B80000E51BCFB6CE2B99EA3D0FC37B0D0FC0FBD6 +:10B8100088D7EE4C7212FF97D98EF7C2659E8B5D6A +:10B820000D0DF89F1FE583FF994425F1ED47EBB916 +:10B83000BF7979F01B8BFB80283198B3DC1FFD5C4E +:10B84000E54FF696E17B2233D871FDCB1C0EC9D6AD +:10B850001FFB65B4AE89CC37E8D6BF9D1D9D7478BB +:10B860008B2E8ED2C1B1CE6EBAF65D2724EBEAE301 +:10B870005D37E9EA132AFBEAE01EB50375ED7BCEDE +:10B880001FA28393E43B74ED53968CD3C1698DF76B +:10B89000EADA67AC2AD7D567B967EAEA7B6D9CA379 +:10B8A000837B37FD4AD7FEE6ED0B74F57D3CCB7408 +:10B8B000F5FDF63EA183F35A9ED1B51F70689DAE8B +:10B8C000BEC0FBB2AE7ED0C9CD3AF816DF9F74ED94 +:10B8D0006FF3BFAB830BD987BAF645D6033A789896 +:10B8E000ED0B5DFBDBE38E06C53B6CF283B9A8C6AE +:10B8F000809F40CE46486774ED618556867C6352D2 +:10B90000F86164E677BAFAD1F67FEAFA33B35A20DF +:10B9100002B25523959D58139561AC85CA877ABBB1 +:10B920004626A33C3C272F46A6DA5FF07D22DA911B +:10B930008F063F2823DF5D8E6336B10F8C87F98C2D +:10B94000C8D786D02BDD5D9AB851845F649E7EC0D7 +:10B95000877E814A9B3F9479A2810FFD215446F94D +:10B96000A3E979B4BF339531FE047A1EEB8FA7B2F9 +:10B970008B3F85CAAEFE242AE3FCBDA88CF7675135 +:10B98000D9CDDF8FDE4BF0F7A1B2BB7F103DEFE1E9 +:10B990002FA032D15F44CF7BFA0BA994FC23A94C92 +:10B9A000F28FA032D93F9EDAA5F84BA84CF54FA4F0 +:10B9B000E769FE7BA84CF74FA532C33F85CA4CFF11 +:10B9C0002C2AB3FC33A8BCC9FF20BDD7CBFF009500 +:10B9D000D9FE87E9796FFF4354E6F81BA8BCD95F0D +:10B9E0004FA5DDFF1B6AD7C7BF94CABEFE27E97902 +:10B9F0003FFF0A2A73FDABE9799EFFF754F6F73F44 +:10BA00004FE500FF5A2AF3FDAF5059E07F89CA8104 +:10BA1000FE37E8BD41FE4D540EF6BF4DCF6FF1BF6E +:10BA200045E5ADFEDDF4FC367F33950EFF87F4BCB3 +:10BA3000D0BF8FCA21FE03F4BCC8FF319543FD5F20 +:10BA4000D0F361FECFA81CEE3F4AE5EDFE2354166D +:10BA5000FBCF5039C27F8ACA3BFCDFD17B23FD1765 +:10BA6000A81CE5FF273D1FEDFF81CAD678C26053B1 +:10BA7000905E6CD57F86AB50B2B0A876E36DADEF2B +:10BA80002BFA7845E8730CE31E636A055AA73F1D3D +:10BA9000FAED7BA4270B2C12C28BB0693CFF8EAD54 +:10BAA0000B63F7E13F24C69A0B2CB47EDFFF3FFC0B +:10BAB000BDC58547BF7C10EDE3031686F63158FF00 +:10BAC000AADFFD287F772CFA618BFB7AAB30FEF280 +:10BAD000DB246F1996DB92B93FF27A32B7B75B93EA +:10BAE0000D543EDEDB4665D903699114A78AB9BEC1 +:10BAF000795D56ECBEDAFEF7A90A1CE64B247B7191 +:10BB00009DFD5C6FBB45D65FFF01E33A8E06230BBC +:10BB1000B9156023B7F7F297E1EE0D30257948EDBE +:10BB20008B18E79117586C0D3188E75FFF11DBCF59 +:10BB300067CC6981F29964D77ED40BDF8724BAC1C0 +:10BB400038C25FED8071E13F6BFF9FFF2FF77FFCF5 +:10BB5000A7FAFFBBC247B7A7384F27A35F6074E4BB +:10BB6000201D862C881763E0FD29CB051BF2D1D45C +:10BB7000857D86237FF4650E8A93DE17CD263BDB19 +:10BB8000F1CBA2520C8A7F2199EF86F19C63CC8382 +:10BB9000FE44B9C4882FCB77086E99E2D08E88D145 +:10BBA00060BF2B15BE2D5F526F9E07EDAAE379BCD7 +:10BBB0008CB979BCCC0AFF43399AD5B8760F851B6E +:10BBC000C52B141FBB8C7E2FB0CEAC8D6DE3B1F3B3 +:10BBD00030CEBCDD6C43BB51DD1414CF0D8A9B0508 +:10BBE000C7CB4253C263505E999DD9799C3BACE26E +:10BBF0006FF83D16218931D7C68B1A9F9598D415B9 +:10BC0000F1384CCC8EC475CCC5BD69910C4B49EA5A +:10BC10008AED5C408B162805A36B003E077CCA4862 +:10BC2000575F7DA87B1D8CEB08D813A91F0AB76B43 +:10BC30008019E3919FF760CB04A21AF96135EB45B7 +:10BC4000F2EBBD0BFEB918E3D833928CB40E988298 +:10BC500031771CDF5B9DDDB240FD12DE7DAF091444 +:10BC60007795D99C388CEB6AF643C8AF752E8A1D40 +:10BC7000938F745AD2B9AF0569253B3E4DEDA2A111 +:10BC8000CFC206C26B795C34A7CF7613F9B5409F5B +:10BC90007AA4CF0CB7E99816CF97D91533EEC7948D +:10BCA0002FB940F49A19A097AE5D756333D115E8AA +:10BCB000A47B5E537B428DA31FFB297A15A628F136 +:10BCC0004D855E183FBF1B2B1F8926FD50B6C093C4 +:10BCD00056ABE1D3E07D89D46903239D200FC5DDF8 +:10BCE000383D98D1DE05E9F9DDF23CA257309D8A56 +:10BCF0007F9C4AF4609F87B30D309EFB52D8E4715D +:10BD0000F07CB2127FBDAF614431C6CBEF49E1FA9E +:10BD1000F223587F3A60FDF9719D953940351FA88F +:10BD2000B311FCD7BA3882FF562751F9595D2695D1 +:10BD3000C7CCACB249235FC000661CDF6445AE26A9 +:10BD4000A7A8FB5273E330EE5EFCE3813C03AA50EC +:10BD5000B9A964D82DB8BE002468F033A134947C0E +:10BD60006915F69A6CC3E3507F2C15EC1B90AECE90 +:10BD700041BAF62CB35F0046FB65E4FC047CB10ECF +:10BD8000F9EF9E51D1BAF6772D49D0C1F352241A5A +:10BD90005F49718AEEF9BD65BD74F0143FACE7E10F +:10BDA00053A952B14186FE2FFDC544FC7CA97640C3 +:10BDB000D7791C26BE0BC6FF31B34C7104799DC5E3 +:10BDC0008EFAEF6408E7EF937F15DD0DB4EE952949 +:10BDD000EE72D96A93709DF2CBA97222D6FF32140B +:10BDE0005CF23E882F9161FC80BD6C21FD39759518 +:10BDF000C06494111FA3F5F2DC972C34CF69AB44D7 +:10BE0000E6EA477C9288EDE7C64AD4DF7D295213E3 +:10BE1000F2B36F83C5BE0E6AA77A95F785BEB40FDD +:10BE2000523DE76F878D280FE92D3918DF2F4BF230 +:10BE3000C4A21E3CBBDE44FB5ED5E2DA8A3020D1D0 +:10BE4000ACDFBE11512091F8117E4F7F1CBB16E76D +:10BE50001F98AF9BE222DE9ECE6753009FA72BDC8C +:10BE600039B44E7E84C7E3DBE285919E920D11D2F8 +:10BE7000069CEF54D7005BB6D61EF27DBFA9267B89 +:10BE8000177B36727F6E3CEA8163CB4DC518770114 +:10BE9000BD3F06F174AC31DAB08C16559B89BFCA30 +:10BEA0008D9259FBDDF2E5A283DA837E2F417BBDC3 +:10BEB0004274B101083752FFF212C185FB4EA92C22 +:10BEC000BF2BF2ED830F0CE88AF398D4C13EE3B7A1 +:10BED00020332ECD3ED6CC7744A71BBF97EB3596AB +:10BEE000F6D68E9FC781525D4BBACF413A6D0AB1EB +:10BEF0002F9350AFA644E23AF5D441B01BF08D1910 +:10BF00000DCD3912B05ED583DB880E95639AD23D94 +:10BF1000F0BCC5EAFA00F17832BEE9A9411827DA87 +:10BF2000F17CA28C76703EDF5F9BF9F28C9E5A7F8B +:10BF3000BEAD3FC1E20CF95878BA08801797C486A5 +:10BF4000237E27B226257EE1A6F149A874011FB6FB +:10BF50002ABEFF36D5609F742017D11F6E43BAA842 +:10BF6000FD1D35F138D7E72982CE0EC7A672F99E9E +:10BF70006AE072C7760AC4A740B04F5335F6B2865E +:10BF80002D277B19972032DCB73B9512A5E8056E6B +:10BF9000FF66A1FDC37D619B40F251B5D1E27603FE +:10BFA0007FA5A472F99C697EEDA9BED83CA9D68C68 +:10BFB000DF99B14560CF40D3D32677450BEE4BD9FF +:10BFC000D62E8CA2F74C7637F2A9A2DFADA0105086 +:10BFD0002F4CC77F427DF54AC1ED217E71921D9A9B +:10BFE0008671135CFFA39ED7E89136FA3D48AFDF18 +:10BFF000CFF4F68835EAED8B3334DC8AE39CB992D2 +:10C00000FBB581F188EC2AE0AAC2E5DE3386C62BB7 +:10C01000505C24F8FBD3717C385E189FC77EE3E345 +:10C02000A9B07339AD6A14DCEE76C6A7E23572307A +:10C0300093D03ECF5A2FB8911F87C53C40F89D0939 +:10C04000F88D46BCCACE88BB01AE004672537C85D3 +:10C05000E3BF660DC73FD0F913ADDDFD26C66746C9 +:10C06000BC7E03F653C6FDC0DAEF89EE7B80BE28A6 +:10C07000BF3336B9CDB811798635468421DFAFFAA2 +:10C08000780F2E0BBE59F946175CBF964579D20C36 +:10C09000A0B7A2E5A8278A6F09F05FB0BD6E6397CD +:10C0A00083F0233327D9A13678B22E6FC17DEF36C6 +:10C0B000F453E262F7E3BF003FF7AF171D2139BA2F +:10C0C00076CA790499F8BF52F6919F5009F36CB083 +:10C0D000E1537938E2E57E3B23BD7BA3E30D1E27C8 +:10C0E00013CB883F31AE877EC8BF3BDE60FFA32401 +:10C0F000F5A7FD8F603D12EC7F7C69721816A0DFFA +:10C10000F731DF17BF64F4F440F9BD14936C871660 +:10C11000013D1ADBB72BEA79558F5628764BEDF7A0 +:10C120007EB457001F5FF54604D25DA5FF74B413BB +:10C13000D9013BF1CBA9D03F7CEF97DB42A8FF733D +:10C14000A3C14E419F65CF7E10C134FA6F414F5756 +:10C15000752AEA13D5AE896B136DC05FAABEBCD633 +:10C16000BAABC3798505CD2B5C3FAF729C57BF40FE +:10C170007F5395797DBD84CFE7E8723EBF696DE658 +:10C18000C5EDFE2F9FB7D865F20B3CB12887273746 +:10C1900089AC81E8CBFD86CB56E0A73E18BF594E4F +:10C1A00076FD542C9330AED3A1FD5E6121BF60C6F5 +:10C1B00056BEDF7A5A28EC4A1BFFEF79221E42B99D +:10C1C000DE2C32B44381F1B4DAED95A9B11ABB7D0E +:10C1D0009D78C3382BDAB3D9803AE4FBD93BBA3225 +:10C1E0003CE7B2BC903589B40FEF253D062C44F1F5 +:10C1F00069F0C375F1060BB35BAD48A70EE2AFFF64 +:10C2000048BB30690EE1C3978EF857BF5FD3C9634F +:10C21000EA8A7ECD2681FC9AEAB98511850CBFC3D6 +:10C22000E3669B53B99DDAAAE839C1514B7131F0ED +:10C23000696C8FE3B8D6F0F8307B9735217E11A674 +:10C24000F8B181CF43906CACAC2F8FCB5BD1AE8576 +:10C2500019C8AE05E3E16BE53BD5A281FCDF2A33CB +:10C26000F783CF0BFCFCC7BB8A7D7C3795FBC31FD4 +:10C27000A4F238C479F403A1DFF3B758DCF502BAAD +:10C28000AD465A271B075BDCE8CF18AD611E3107AE +:10C29000D16BFCB6559E015F93588B09E93926FF97 +:10C2A000818D389FC3DD984DEC4CD54EDC479848C6 +:10C2B0009A81B1FDA62FDFC778A40C6D45582B4C91 +:10C2C000CC3FD103DBAF4118E67F38A4E97D8CB3C6 +:10C2D0001C4E3232DC1790DFB190FD370DF1F6A025 +:10C2E000386527C61AFA603C66F722E4A33D71D18F +:10C2F0009936683FD9D8C92E72FD33F4028EB752F1 +:10C30000E0FB370BBD79489F9BD942DB712B6D2D2C +:10C310006CB91AFD53FC6364C7553E8031550D81DD +:10C320007F0C649CB1F2099F3A18F04AF0F7A973A8 +:10C33000C7ADEC8E9B26526FA47355B2CF88FB29F4 +:10C340003E81F9D6011EEECCF7191D482F076B1A56 +:10C350000BFCEBD9C704FC0E8A007EF76E4FF2305F +:10C36000C403CB945824D48F354A04772F6651A246 +:10C37000B26F8071AC438304A283C12A9970DECE70 +:10C3800062A12FEE8B562DB8BE71866CF8F5B8956C +:10C3900083013618F87AF621BE9E9D281F19467E25 +:10C3A000D26026201FD6443599681D0DF282E3EF36 +:10C3B00003DD68F137D1E8E5E3AB84F115A05CA4B7 +:10C3C000121FDF5B2B903F59636E3FAE119BA6EEB1 +:10C3D000CBD9246C3F0BFE857C3D6BC7B634FCDEAD +:10C3E0007281F3C12C95CF5ED5CBE58034467CDAE3 +:10C3F000115FE72AFDE7A619F839AED6EF3591DDD2 +:10C400009DB5E38343B8AEECA8FF6A0BF3105EDE84 +:10C41000B150FC4030F852892E8848A0C344F4271C +:10C42000C145EC9BC6FD44953F2BD0FF48C192C748 +:10C43000450CA03CD11E56363E6F46A4059F3F02D8 +:10C44000C787CE01CD5C1FFC5C135711757A87E25C +:10C450009E82D9370DC723DC1A62477D3CD1DC446C +:10C46000EBF2E076A646EE679996703F8BF6D50024 +:10C47000B62CE77EE6C4EEBEDE8CF49C6DB890C4AC +:10C480005AFDE20AFE69785EA5F38B2D1847C0B805 +:10C49000D72AEE0F1A15FFB57CB9DE5F98B850E3C6 +:10C4A0002F52B7BE6A1CAFE991508ABB58D09FD0BB +:10C4B000F8017F3794C8A887E564239DBF34B16035 +:10C4C0007FC2C9783C933F372A7EE2D034936EDF37 +:10C4D0004D1EC232110F65A8875250D53897603C67 +:10C4E000EF220B6FC4B8D930F1118AFF95D5F373E1 +:10C4F00069C1F1BF8BB5EF3F8BEDB11E9FCFEBF460 +:10C500006322EE6FC2B2D429DC0AF2DDE9F06517CE +:10C51000CA07282A13CA7BC8FE6F10160C914CC894 +:10C52000C7EF7B9EC5FE65B3D5867AEBE9D008EAF6 +:10C5300067FE7C81E2C30B6D5CDEBEFA327C1DEAD5 +:10C540002935DEBBB8B0DF2A3CB7F4EBB45DE3AC11 +:10C550003D503D303AB70486F11307CCA7F40AC822 +:10C560000DC1EF8F7344029FBFEF9B64053CADDCB0 +:10C57000F0FE3823F0E3F9DFF99E43F8850DFB392F +:10C58000FC5B5F6208C26907C619418ECED7ABFD5E +:10C590001D18E7C07DF7DF73B801EA6580CB50BF97 +:10C5A000E1BC070AB4EEDF8076293610EF2933BCF0 +:10C5B000CBCB21CC83F6F35AEDFE98E6DC80F65A1D +:10C5C0000C3F168EFEC5960C07C19B539C8FA5A1F0 +:10C5D0001F74D0DD2516E35806D68274013BE66849 +:10C5E0006F5F7A432A97DF4DE9BC3F155FD0CFD309 +:10C5F00069B137DECF6D6DFB71FF3BE3E99401FD5F +:10C60000E4E9FA79E9DFE9A72AA81FD56F030758FB +:10C61000423D7526D3F11ECE73D6AF1D43B6A0FEA4 +:10C62000D92F129F7E57BB2D1DEDFE77AF5AA2D199 +:10C63000FECD7AFDADC40A8C23287ED199E6CFCCFD +:10C6400012BC3FDB2F3207E8E91ABF40E5EC2DCDE5 +:10C65000E6E1D978AEB6D95CA4195795324EE074AC +:10C66000E3388D1FB32F4D8D3FAFA0F1CE7AFD94EF +:10C6700011E939CBD0741CCF1FB3813CEE153CBF00 +:10C68000CDCA7B87F1BC413B71808FD2B8DF11D717 +:10C69000CBB11FE7B709F539F28B819F0F096EDF28 +:10C6A000359DF757D689EBF9BC83F68A03B4EECBF8 +:10C6B000318850F63F546B2E87E70752861C4A6B31 +:10C6C000370EE9E371C81D3C0E5916D532178C1987 +:10C6D0008B4ABFF804CADBC8A755F900D103FD5245 +:10C6E0006C51E190F14307F33817C29737189EC495 +:10C6F00073847B3BB5FCE200DA87A5E16C1DC8D9E9 +:10C700007D03C21337C338A6CA9102D84E566809B2 +:10C710004F9F02ED4E241746A5F3F327E41F9E48D2 +:10C72000769EC3F17993420DE08C309799C7B35C44 +:10C730007F16299EE5CA0975B9DBC1D719059F5136 +:10C74000E9DC3FDB6B8071F6C571F0F3BDF097B8A3 +:10C7500019E34D0B7A0AC877EAF76F4F29EC9C9ED4 +:10C7600017F8FEED29CE1FD362B5ED2319B6BFDE53 +:10C7700071FC53B1A79DD339BD9C8381BF347A7FAF +:10C78000DCD0501D5C3A2A9A39B4F1CDD2041D3C5C +:10C79000A12C45D7FEDE69BD74F5A32D2DB9B537A3 +:10C7A000E0EF8B119991B4FECFE3EB90AF765CFE96 +:10C7B0007422FAB1EB45BB00F39AF1CE864F0751D4 +:10C7C000EF12C5B94EEF15C91E817B6BD6EE9F9C4B +:10C7D000632D74EED8D87921D9BF5971FC7CF70C40 +:10C7E000B77EFF438DCBB7B76F82F6AC0ACFC5B427 +:10C7F000B76F1288C7FFE4FE49BF74653DDC97F54B +:10C80000E5EBE1B37B60A6AC687B33D1AB619F689D +:10C8100047566DE8213001C679FB168B3B04C67D77 +:10C82000EEAD236649B37F52E30703108DEF1D3150 +:10C83000E379AA03695C6FCFDE71C1CC902F763C9F +:10C840004072DDD2EC8A8945FB05FEEAD65CE4AF96 +:10C85000A65CB47F7B0D3627EE87CD5A3282E2CCC0 +:10C8600091FE895456358EA07EABFDE3099EED0FF7 +:10C8700025F823B165CBC7D8CFD39136B4E7D546D9 +:10C88000F955A44BB514DA0FF7AB666FF9F8D2AFD0 +:10C89000D08EDAF8BD8ED1E227B9583FBAA7CDD0F5 +:10C8A000D019C71B42FDB40CF92217ED5231AE0B63 +:10C8B000E079D5E60217CA7D6143B80DE55EC4F3A1 +:10C8C00064EDF0E9E474AE5F4C5E3EDE61FE12EAB8 +:10C8D000AF757D9F9E4CF3576153EC7A23EA0F7539 +:10C8E0001E2630F858DEE1EF4565CD9612239E8B6B +:10C8F000FF73E6F3318827681F8665EAD041A46795 +:10C90000BEAB1D10C9DAD15B6A6951F4F044D4C3DF +:10C91000D05F69A6E3572897631EF11AADA847C3F5 +:10C92000AC36DCFF1893DF47AAD0CC477CF71E5CFF +:10C930004980AFE233A11F30114AADDE9EDC817D1C +:10C9400091D30D8A5F54CFCF75AAFA7DE5130CD72A +:10C950006193F859AD56B9AA56DAABEFB708DC1FA8 +:10C9600090B7F2B87E75A6EB491C6F4B219BB0992E +:10C97000F4694B6249F8CF37FE08630BD139C22600 +:10C9800019705F41AD5FD53A0F2EDFD79AC722A548 +:10C99000FD47229B8F7CF1D16DB7B538A0DFE687CC +:10C9A000FBF5133576EAA5747EAE99D97C57485FBE +:10C9B000EC0C95500F8CC6BD87DC80DF8FE72131F2 +:10C9C000AE51B3D3B20ECF83D544C03A1FBE3FAAF7 +:10C9D00097EB25C447F3AE824B788FC6810B33901B +:10C9E00073C78E0197F09CBDC30ADAC68E7E90E3B2 +:10C9F00065D2FF1D8CF75AFA2C75E8AC18F427BEE7 +:10CA00008321A1BD05BB9F7B90C34EC4976B099743 +:10CA10003F9722875314FE2D57E4708A91CBE1E4AF +:10CA20009591368C77963F22F4C6F3724C0AB7A3E1 +:10CA30000A30215FF643FEE47C59E5EFACC87392FF +:10CA4000D20FE7FF60F99CED8FA676AA9CBE9CE909 +:10CA50003AC4ED5C4BEE7C18D71D20D7A8F75C0BD1 +:10CA6000E273514E027C62B6213F019FC45568F8C3 +:10CA7000A0A1F90723F28969B0407C6281B248C362 +:10CA800047CE56FFC436BC0BFA550B930CCB58A0BF +:10CA9000FEAB74D54FB93E7EFFB3D2BE3C0CFC0852 +:10CAA0008AFF44308CAF5D8C91284E3A67290C1276 +:10CAB0005030C7E449C338CC9C0742280E5671B0A9 +:10CAC0007671B8D4965EF7F873687F79BC3F95CAE3 +:10CAD0000329AE33888F29FEBB143CE65CD7FE5C8D +:10CAE0009E83C7DD4C6E8B7D6D12C6DD5C22EDC76B +:10CAF000F560B627C94EA9FB713CEE86F13C8CEF80 +:10CB000005EFAF611C0ED7D39618836E9FB04D3CD6 +:10CB1000AE50BF9F56D5FC497F03D49F4E72505CE8 +:10CB2000CEDBD365CC8079CC1CE77EDDA4DD6753FA +:10CB3000F0D864F4A4A11D6DAAE5F8695A2E16D3A5 +:10CB40007E1363A1259AF3BAD7E2E399FE14C28F4C +:10CB50006A5F54BDBDAD8E0E7DB6EAEF6BD99D6A9E +:10CB600085DFAB91DFED6DED8CCAAFC1FCACEA6740 +:10CB700053EC41D24377C02BE83FA8FABAB868D04B +:10CB800060B4F3835E4AD9F227987F74A62B3703EB +:10CB9000F8E7B6577AE4AE06F80EA3DB680BBB1EC7 +:10CBA0007DF88389F4E123258CF421945A7D68EA89 +:10CBB000C00F2FC8B8317D9EA1B4073F96FB87A058 +:10CBC000AFB5FD55670E1985E32FC9E076F2E71A78 +:10CBD00077477ABC244395CFEBD3E3B72AEDAFA5D3 +:10CBE000C7A765703D1EACB7411B93DE3EFF4E16D6 +:10CBF000C5C90E33D0F368CF76844A1B9234E7DC84 +:10CC00003B45BAB57A3DAED7D469C8EFD7A1D7EFC7 +:10CC100047FCFDBB7A7D78C926F2ABE0CF39F656EA +:10CC2000587FFC06D677087F04EBBBA4B6F2102C25 +:10CC300007C17C0FEB912D1FC3F8F63ED593E20E92 +:10CC40002007C4F7D5C0F72807AABCCCDED227122C +:10CC5000F70DD85F4486FA3F580E8A8B5E31629C8E +:10CC60000AF538E26B37C83CEA99603BE1CF70AD1A +:10CC7000C4F9ABF2A0CAC1B5F9E82D13AE4B4D55BE +:10CC800017B89E8752ABE73BF2677E7F83FCFF6855 +:10CC9000C6F5F901AF66F07B103F23FFBC9A717DAA +:10CCA0007EC16B19FF915FF036F10FEA4F5CBF8DCB +:10CCB000FCD01E398FF30F9D4B047EC8C5B8F3DE40 +:10CCC000FE3DEC18A7197995FBF5A0D3C9AF0FF677 +:10CCD000AB272AFA6FB212273890E96CC9E0F24A02 +:10CCE0007E7B614A681FB457D7EBEF4D8CA965185E +:10CCF000679A0CA5564F58906EEDF8EB7FCDB83182 +:10CD0000FBBDFB3AE97B3CE33FF6F37CD7A30F5234 +:10CD10001DD6F188CFEF3C468678BAD67AC0B48A61 +:10CD2000E3598517798CAADD8C46BB09FC71E13F7C +:10CD3000E18FD1454D97AC40D7C84C6329C603EF6E +:10CD4000C2B31614CF30AD74A4A2BE61EABE00C552 +:10CD50003B3E1255D87C70288C63E4932CB06F0056 +:10CD6000F5C30647B6C6470416681F91291E5C4ED8 +:10CD7000E3E6E75598CB6BE4FB640A9C0B70B806BE +:10CD8000CE0F82D7F0F611462FB369FB51F4CF18BE +:10CD90001BDF1708ECE7F9867746FF6F8B60C3FD52 +:10CDA000857B079F37633C677491774F02B44BCA0A +:10CDB0000C2F0D03137FEF1681C6DB6763CC4A3956 +:10CDC000958E6C39F0BC61553EDF37B134350F7745 +:10CDD000B4C3877D32F5760AFF8C5D283E467F9688 +:10CDE00026819973793FC949D7F73ED28FDE4FA686 +:10CDF000F73D9698EB7FFFEEC1CCE16E878F6ECB4F +:10CE000054F421C685D5FE8126E39B04477B719BA4 +:10CE1000DB95F62D064335033C8DDD98B912E35EB4 +:10CE2000C318E78B928D19A532E73FE6089AEF4FBA +:10CE30008D372F53BF3EC33F49FFBEE7A7F035A84C +:10CE40000DBE14FA57EAF924D2E87CEF3B18476488 +:10CE50008C60433F75B63364398B44BA2B7C2DF715 +:10CE60002D750C86F985305D1CAF95AFE57EA5C8A4 +:10CE7000D7B399DA3E6F25D2DF69686DCFF97C8729 +:10CE8000D0FA7EA691E127E8FD591B7357629C1CDE +:10CE9000E841F5041B7F82CF9B82E0C14172C1381B +:10CEA0004C72897A19F093D6CEFEED1205BFE704D5 +:10CEB0007EBEA96508F7E75A9279F96226F7DF1E68 +:10CEC00057F0F8B452B674D2E0A17B80CEF0E7C13F +:10CED000F58066DE84A77B629479CBE34B47C1BCC7 +:10CEE0005AA2586F01F864EDC6B12B176AF8E4F93D +:10CEF0008DE34B110FADFDC92507118FF728787A07 +:10CF000071E3B883C84778E404E5AD3A9FEFBF5AB0 +:10CF1000B67CDCAEBCCD69CB3F32E657A82646C214 +:10CF2000F704872997F793DC0E7EE6B77DDF11F4CF +:10CF30003E33C5DCC8FB0A7D4605D1AF38887E4349 +:10CF400083E0323D1CF083A167F09FCAB7AF58D48D +:10CF500005E3671B05BA6305FAD92CC0F31D99F7E1 +:10CF60009586C5239F4AA60468EBC99C7CD09A0588 +:10CF7000F288FA8BF4AF8BF4F578947382A7943A25 +:10CF80006E46BEA95D1407EDF76496AFC47BAFF79C +:10CF90002E5C6142A4FF3973DA4A23F47B4FEE1F03 +:10CFA000F7607F46A1E2E028E127F8B431681E6B04 +:10CFB000826039A8FDCA6BE8F38541EF3F1254BF88 +:10CFC0003C085E15042FD1BF3F651ADFBF9C02F4F9 +:10CFD00043C45D4B5EBC99ADEB8656FB25A03DFB83 +:10CFE00050CFEF231B387C6AE383A54BC23470E635 +:10CFF0002F4AB5FC6B52ECC5C418A7A33DFE3DD427 +:10D0000011FF6406DB3559772EF130633AFBBB5BC9 +:10D01000D4C3CDA22A5F0B0ECECDD6EC07CAF5A5A0 +:10D02000184FE978BF422EC5FD8A918FABEDEB4AD0 +:10D030001D9AF9A9ED87FFEBAA88DFBB9A5957BA69 +:10D040009EF6FF94FDBB285EDE76E56A04D2653865 +:10D050009E1FC5FA4E9EB439D99AF9B1A6749C5F49 +:10D06000F3C3FCBEA1DC00F400392F6776DAFF6E53 +:10D070008E8C9CFF02B4DFFDB0381FEDD7E1F9D1F3 +:10D0800074DE686C16F7B77747F6EC723FC0CDA137 +:10D0900093CD18576D7E741895EF8A8EC53E407EED +:10D0A000F7ACC74AC3B2B03E92F012F7D2D2D27AEE +:10D0B0009083842C89DE7745D9BA6C473F7499896F +:10D0C000E1FE1363F6E7884F7E6B213F754A7D2FA3 +:10D0D000DAEF29FF5DC9F0786857BEC844F17FF8E0 +:10D0E000A3FB18AE65C3CC583F6DA152CAB753B964 +:10D0F000EBC7373ECCA17D1D91CEEDECF4471D076B +:10D1000049665FCBBDE9BEC25125BFCA962C5746C2 +:10D11000168CE3EBB3A9942F85D9A48871E8B7DD09 +:10D12000E4C8CC8A0DB4DBF5A348FB556F9F2DEF07 +:10D1300082FB7B7DB338BFECF4977729D7D8F58A8B +:10D140007346C2F32EB33417F5C6AE4E3D0499E4D0 +:10D15000B6291AE3ACD314BF19F864FE1BEDF061D5 +:10D16000CF2C91F072CC321FCFC2B2E6DFC40EC614 +:10D1700071A9EFE51D743560BE185377A9AFD63F8E +:10D180002E481B722B8E37C05FEB499F937F0CF0AC +:10D1900088ACB52B65B01F6C37F8F5388E18C770A2 +:10D1A000E427F53C1E8B6B4AD7C615027EE8024584 +:10D1B000FE79BBAFF070307CFFAB5743E8DCD7574C +:10D1C000F217E15AFF58958FE911FF73B885D6C55C +:10D1D000919290087C63AC3BFE10BC57F1AC89F493 +:10D1E00066C5B3B18FF8B01EE8895B86C1DF7D3EAE +:10D1F0008B9F07E8583E36970EEDAE958F4DA538BC +:10D20000DF8EE4636AD6A60EE4A3AE0BF2D1F0671C +:10D210004D74BEBAAC53ED5D18472C33DCCC1A60AC +:10D220007C439EFD4517DC6799FEAC85E8EA0D0F4F +:10D230003FCEE7D53309E7D56A7FB2B8BEF2D6173D +:10D2400090BD100DE09D81FE16179B683D22763142 +:10D2500093DE1323ECBCBE134B5A0076795178BE93 +:10D2600084F4752BF200F512F25951E4843BF05C22 +:10D27000CBE1F929B40F762A97EF83CD78E8F90846 +:10D28000F43FBF9ACBCF77CFC47C3BB8CEFD37F706 +:10D29000BD6A947C3BFF5BFB5E4F6429F7865AF7BF +:10D2A000BDF839D0DDF3FBE572BC30C982784AECB9 +:10D2B0004378B9DDCAA410C08B18C5D251FFA8FBB2 +:10D2C0005EE2AFB87E120D02ADD38FD5C994BFA078 +:10D2D00028C2CA9FFF8ADFDB139F2A61B40F16534F +:10D2E0004BFB60E188578CDF0ACC89F27334C49E13 +:10D2F000F84036F25F08D173FA73333EFD7D2ED2CB +:10D300006D748C2E9EA0F09FFAFE89FA5B687C27D4 +:10D310000466437B5FF4878CA1489F66D1F5D43DBA +:10D32000A4374369FF9CD9BCBF1D00F0F47A58674D +:10D3300033E49BF8C4E4EC403FD3173C9C8EF42EBE +:10D34000FA438807CFDF4C5B18B20ACF6154EDE097 +:10D35000F7BCA72CFD8ECEE3B224632DC639BF5E89 +:10D3600018C2CFA96F1940FC33C5C0CFB9B0443340 +:10D37000C597AAC214B87B3EC19AFB4B66A4877AB4 +:10D38000FF660FEA15F8FE71151FE837A2DE55CFCC +:10D39000D1B35A09E5BFCC20B47BCEEB6F59DC3F4B +:10D3A0009D9268A7F3A2D58F59EC0B92389DC5FECC +:10D3B000F85D46EBA26A836FF82AECD7C0A4AD36BD +:10D3C0005C3FB454E07A9B6DC9A03C04354666349A +:10D3D00047C17389EB33753C3552C9EDC44F46766E +:10D3E000C81885786CF9B405F96341B8847191EA7D +:10D3F000CE7617F51B6EB5713BA17C17C79E827C5C +:10D40000E03747211F7C2A182C3CFF80C300F5E73A +:10D4100019AF6FFDCEC2A5D9346FABCD30241EF944 +:10D42000EEC2F055F0DEED4C4A8EC77B624BA3EFA7 +:10D430009A80F5AF89A49740981ECB477FEF35B10E +:10D440001FAE53A72CDD4DF39BB5A90FDE20605313 +:10D450005E3F40F66996C25F5EE5DC5A39C09B10BC +:10D460008F8A5E7089AC96E2610A1E5BF1ABD4577D +:10D470002F35113DAA175988CED5F57FA37EABC3B2 +:10D480005BBA203DAAB79A287F87F5263E8FF2FA2D +:10D490001E830FC1B8CB4D9136011E55C9A3CD08CF +:10D4A00057350A04ABDFAB5EFAD72E866CDE1F96CB +:10D4B0001603DF670DF41B9B88F6ECCCABD18953C8 +:10D4C00034743FB3705B04EE3B1F0DF1A4E1395F90 +:10D4D000DF0321763C57A8C6D3CE2C4CE3F7816CF2 +:10D4E0002DE1B85F3D6D6E4A14DAB9C3368F19EB82 +:10D4F0000F3725E19139E6B0D90623EC30DE4CF048 +:10D5000019E51C09FD61FE4081F34DD5ABBBCDC9CA +:10D51000F0BDDE3771FC9C7BEDE89E81880FE02337 +:10D520001BEA9FC49674B4C3D58696F404A4CFCBEB +:10D5300002F90BB03E7560FE91D9C8577D411F2A94 +:10D540007C357BCBB679289FD56F9E1A8E783D3778 +:10D550009A99313E56ADCC1FD68FEF19A17DF5E6D5 +:10D56000B5C3197FFF3DE43BD5DE03BCD004F05EBC +:10D570003387736EE2FA79AFD94B79EFF6DEC518CF +:10D58000ED9F19D9506C0794E7F7004451B99F56A5 +:10D590001B378EE7DD93B5E7E766637D76A0BE2394 +:10D5A000BE197B9341A1B385ECD258C40BC0DEA554 +:10D5B0005B23902FCEBDB67BCF40948BCD828D69FF +:10D5C000E54195C3441FAF07FC3D81F8DB7C613822 +:10D5D000E6A19879365C421AAA7852E54DC54B0D02 +:10D5E000E37850F1526354F0A4D43B153C54311FFE +:10D5F000F5C7CEF6963660FF6FFE40FB6DE7A630AE +:10D60000819F13E679D1D4F9B9A2F4FBFBF5377108 +:10D61000BE9FA4CCB3CAC6ED62550C93EAFB109F23 +:10D6200039CC6A7E4968726ED311DDF8572972D001 +:10D630004A6F9C078CD36BE0F70483F5D75C85AF0A +:10D640008ED44FF4A05E9929433FB9280FB649B84C +:10D65000CFC95E1715FD0D3653F3DDA2578E101F8F +:10D6600082EE92A260CD62DA08E340FFEB6C0F8A93 +:10D67000171675F5D2BC378CB23103E89323823785 +:10D680007C3BDA838744D253EA381DF287440F4744 +:10D6900013974FE4178C0FB6EA85A0F1D62BE3B5AC +:10D6A00018EC5E3C17CC1608747F4D5C702EFC1095 +:10D6B000B77714490CF47FCB7BB81FE9B814210964 +:10D6C00054633762BBD9972292D17E1F51E20E4735 +:10D6D000166D8B28D7D0E1A98EBEB3788084F42F45 +:10D6E0000A3BF430CAD1634ABBBD66FBD0F9A80F30 +:10D6F0002E4748785E6A6F949C8D7ED45E035BC231 +:10D70000A2381F1ABB04F007F242F8837AE9495B9A +:10D71000402ED57103DD3C483768EFE07264A77D89 +:10D720008CD9317C5FF4DAF2D4CF4BFAA95E90D673 +:10D73000E506DAA9F7F21E55E64D32D225600F90C4 +:10D740003FD1DE59943C46C179506FEFDE3911F17B +:10D7500057136635E0122EB83E180EACA76A8DE856 +:10D76000E7B385717BB4F7D28E86C874FFCC172FD0 +:10D77000B275408FFA073EE0E77977F07B5BAA9DB0 +:10D7800086BFE5ADFC07EF55E65E188EFAF5C502DB +:10D790000BDD6BEADC2B99BE739A35990BD1FE9F9A +:10D7A0006C191E2105D627B75CF28891E42F24E975 +:10D7B000D6075567DF2379AE662D741F7BCAD20367 +:10D7C000A30720BD5F32D1F981698D4964E74EAD71 +:10D7D0009FDA0FE73B65511AC13336DCCFE1A53C38 +:10D7E000FFE19445792FA0FF7534C4311CF9D9B7F6 +:10D7F00042B0E1FA6AD086BC47EE85FA41E13D3B92 +:10D80000E3B8BF5A7F7434D2FDABF922E927C7FAD7 +:10D8100027EFC27AC776116F8CC17AC6F608E63553 +:10D8200065C6481BFA05EAF9C20613D7B76715BDE6 +:10D83000704CD113C714FE2B6A6848477FC9B716CE +:10D84000EC11EE7B9B7D1574BE5BB0D9D701BF9CFC +:10D8500014648299CD965C5F80F759D6507E9CF314 +:10D8600069161BFAC9F759981DFDDAFB76F5E88BA6 +:10D870004B0587B2AE1A1DCDBFABE24BFDFE19E5DD +:10D88000BB4C5C5E41FB0ED15232EAB7BDCAB9F166 +:10D89000A3CA784F2D7CE92EF40B4E6D4C8B621A87 +:10D8A000BC9F52F234CD003DB8B99DF59EFF2635A0 +:10D8B000EEE0A6EF542AF1C07DA6C6EE98F733F845 +:10D8C0007ED789B52156CCCF1B7CCFEB8489DB8FEB +:10D8D00036F7BDB6EBE1E03CB7C1E3695DCF04DFED +:10D8E000FFEF15D6AE1FAFCA59F0FB6DEE93A75EE2 +:10D8F000DFF92ACC4B86F7BD77DFC4E8BDA1A1FFD5 +:10D900007A03F57545A3C586F7EF8F8548B41E9257 +:10D91000F398B401ED8C558AC4F5FCB17DFDE8FCAB +:10D920005FC5978CE4AA628BE8C654C5EFADC87892 +:10D930007C30C0F76F31D9F1FD532B57DCC5C54C96 +:10D940009F67219F71F99C0EEB248F2DB02E0A5EEC +:10D950002FCD5CB589EE11FE5CEB25358E148CEF76 +:10D96000825EFA7C0BC1F7E77601DBE4F76D8BEFA3 +:10D97000B3752E5A177D5B57496541D3DAA2040966 +:10D98000EF531C796C10CA4D7824C543CED6D5D23E +:10D9900026DEB7DBFB5DC1FBA16F8745DA505F7CFC +:10D9A0005B375FB95CA0F089C297B76C6916131832 +:10D9B000B5DF3108DAEF0C8BA4BB2EA98EFC48B47E +:10D9C000F32A5D83EF37ABF33BFD10A7AB3ADED311 +:10D9D0001BA746A0DFD9BC3A7A4701F4278746DA6D +:10D9E000D0DF9EAE9C7F39BE8AEB9B93D6C817468C +:10D9F000E1F99935E3BBE0BAEE7E93CF6C877EED1B +:10DA0000EF9444E07AFF1BA33702EF1B7F03ED3D49 +:10DA100068278C6E11F5DCC06246FB78033D462614 +:10DA200025D19639F145C159A31BE97AC67369F727 +:10DA300055E4A3B3068A770166765F85F6F6F09E15 +:10DA40001427BCFF2DBEDE64FFEAC4EB83EE2D3E3F +:10DA5000D18BEBA5136BDE1843EBF3F5261B8EF38E +:10DA6000DBF57FED82E77066327EBEFEE44681E63E +:10DA70003113F8312409F5038F83CE04BD6F15DA15 +:10DA8000F261D1C67AE2C399C08716F4D31C3C1F59 +:10DA9000F34CCCC72CB136F93F3A2B7C370BF80E40 +:10DAA000EFEFFEDC793F96F50A3EB7CAF950A5BB09 +:10DAB0008A1795FE013E64BAFC82514D7D0A1358C7 +:10DAC000401FA8F73B98D1BB1CEF69CC13C31B3197 +:10DAD0005FD57E63ED1F286F8B6C641BC89EB34CB3 +:10DAE000CC97374FBCC98EF1C006736D6B5E17AC17 +:10DAF0000FCEEB2286F1F74B303F31CC372C3B89F0 +:10DB0000BE37CE661F86E836C578292E2016191C2A +:10DB1000742FAFC142EBE6603DF48A42DF3BD07721 +:10DB200040BFA7173FAFADDEFB534B30343D90DF16 +:10DB30004B42A32E4BD064FB2B9FDF89FBB4258384 +:10DB4000A27E9102DF6FEE75E44EBCB751D22F6A10 +:10DB50006B32C0BB5FF93BAFBF392ACF847E80F008 +:10DB6000F59D43D16FECE578B397E63B6ABFF0FCD7 +:10DB70002D7CFE79A2EB9D5E7CDFB402E97D5E88A0 +:10DB8000E0F9DE527D140755DFFB586087DF16028F +:10DB9000B0D7C41231AFC1DE5E5C9F7654C6643B21 +:10DBA000F6F0EFEB9F2385BEC375A6B2FF63B04AC4 +:10DBB00066F4FF9C76B39DE757644E2BF8556315CA +:10DBC000FE2DB75E194AF6B796D92D98C06489FE26 +:10DBD0003E5656E0DEDE9A1BB9B7C7649E87AF415A +:10DBE000C9C3D7D13D4A61C7073FA07F197C7FAA2F +:10DBF000DF5F5ADE443E19037C85F622B785C36396 +:10DC0000153EA9DE369AF23DCFF9D8E4463F61864B +:10DC1000E28FA5BA3A3109DA5D06F945BD70768C16 +:10DC2000271DF5C7893AD6989A86F12A970FE9B247 +:10DC300037E903CA8B76624D4304FA3DE7603D3114 +:10DC40000ABAA852FC7B7645F4DC867E7052D6BABE +:10DC5000651A7EFBA117B7FF67933C89B8BE919305 +:10DC60002C3C5FE395DD94E7B93879441EC691F604 +:10DC7000D76D6747D302EF75741F65A06108CBD6D7 +:10DC8000EC4B8E31B67F4EE3A49A4F733DB7DF164F +:10DC90006323E5D10252D6D613ECA4B8521CF22865 +:10DCA000C687A507095E3C83D9E81E6B609F8EEE90 +:10DCB00083AAF477D8AF0EC5766380FEA86F0C56A2 +:10DCC0009F116167313F9F920584437DA2D27F9867 +:10DCD000F8C863488739CA3DAE39422D874D563A58 +:10DCE000E71AAC1F31AE59467A53DE5380FE18E86E +:10DCF00049CAABA0E84509FE477991F2D79AA9D95C +:10DD0000B5F322ED29F80FF4634EB63E8FB84A27DB +:10DD1000D5BFEA884EAA9E047AF5BF117AA979CABE +:10DD2000E63CCBE39D739E9D1AD797F0061287FEC3 +:10DD300050DC1F29AE325D99035B134D7C6C1AE2F7 +:10DD40009450DF8EDE9EC024783463BB40E75B478F +:10DD50006D8F2638C21FCFF32A29F67EF48B5D879C +:10DD6000607CF2D40B5FCCC5BCF7A37EC3287E6C6D +:10DD7000080DA37C13E210258F8318F63EDE63BDE9 +:10DD800028196BD15E39599BFC0106A2FF5E7E4EBD +:10DD900016567932A713BFF737671FB7F3730AF91F +:10DDA000BEE0457C03DA5F2C15294FD3D3A139E4BB +:10DDB000BF35DC69A2FB114C767C82EBAA090A3FD5 +:10DDC00058E26061A9A1578804F2AAA1CFA3218FCC +:10DDD000BDEF82FEBDB0EE12BA811F9B19A5AB3715 +:10DDE000CA21DF60FE58539C6873C3F8C3EDDD742D +:10DDF000FD39C52A13C653988BFBD12A7F31F1AC6C +:10DE000091EECD0FE6F92BEE9CA0BF27691A7C613D +:10DE100028D99BC17AFFDB798DBC4DF3557ECA6250 +:10DE2000594A5E7AB2FF170FF2FB211273AE52E528 +:10DE300005F53F78374F237EEEDA6B626E89F0F797 +:10DE40001AD65F942D368C07B4FAE1A9F05E0C1A4D +:10DE5000492BF139E605D5CE13F3826AF182794177 +:10DE6000B530E605D5B6C7BCA0DA7ACC0BAAADC7EB +:10DE7000BCA05A18F3826ADB635E502D8C7941B5E1 +:10DE8000ED312FA816C6BCA0DAF69817545B8F792F +:10DE900041B5F59817540B635E506D7BCC0BAAAD62 +:10DEA000C7BCA0DA7ACC0BAA85312FA8B63DE6050F +:10DEB000D5D6635E506D3DE605D5C2981754DB1E7E +:10DEC000F3826A61CC0BAA6D8F7941B530E605D536 +:10DED000B6C7BCA0DA7ACC03AAADC7BC9F5A18F368 +:10DEE0007E6ADBB7B0856968C7DE4A72EDCD8EC544 +:10DEF0007DA793C4CF87EE037E4639DC3BDE46F92F +:10DF00000B6F709DD892ADAC5B14FEBDCCC226E108 +:10DF100039F48EDE57F9F3257C278FECC112E25FCE +:10DF200016DE88FEDCA34607DD87929BF8FD44667B +:10DF3000E47EC03C51F17F94BC10F34489FC00CCDA +:10DF40001D6CD48CA7B3C3CA8C1A3C4417DB747005 +:10DF5000AC334ED7BEEB0449571FEFCAD4D5275474 +:10DF6000DA75708FDA7C5DFB9EF31D3A38492ED648 +:10DF7000B54F59E2D4C1698D1374ED3356B974F5B8 +:10DF800059EE4A5D7DAF8DB53AB877D37C5DFB9B8A +:10DF9000B7CBBAFA3E9E25BAFA7E7B1B75705ECB74 +:10DFA0002A5DFB0187DCBAFA02EF465DFDA0934DC6 +:10DFB0003AF816DF765DFBDBFC1E1D5CC8F6E9DA7D +:10DFC00017593FD6C1C36C9FE9DADF1E7744573F2C +:10DFD000423AA5ABAF3AC3FD7BD600EB038C538628 +:10DFE000F1FC1AB33DAC09FD8B91991774ED4D31DD +:10DFF000B05E00FEA9067D887EDFF79D12291F33E3 +:10E00000AB8DB0E3BD6F7948ED1FB4F7BC47DB7F44 +:10E01000D07DFFE9D0084F08AD2FAC646F6FE9CD1C +:10E02000EF9BB5E61351EFB3331F8B8BA190900F8D +:10E03000FD23017F6109E00807CF0B0D7E10F94F2A +:10E0400036F08BD0DF6C5D17199292D02E8706FCCC +:10E05000E2EE5735795EAEE5178FC46FE7519E5EED +:10E06000476F2867366D1A8EEBAC194C5E8CFB89B6 +:10E070006A9EC5FD21FAF8965A8EB0027E35DFDB26 +:10E0800017D2D8BDEF4FC8FB08EB596ADFDAAF12E1 +:10E09000FF1260B27334FD3F06EB3F23C875631D6A +:10E0A000C81FF8434FD4D9085E591747F05375126B +:10E0B00095ABEA32A97CA6CE4EF56BEAF2097EAEAC +:10E0C000CE41B0BBAE98CA75754E7ABEBE6E02C167 +:10E0D0002FD4B9A8DC585749E5CB75B554FF6ADD94 +:10E0E0007C825FAF93A96CAA5B42CF37D73512BC55 +:10E0F000A56E15C16FD6B9A9DC5EB791CA3FD535FB +:10E1000051FD0EF0DF10DE59E721D853B797E077C5 +:10E11000EB5A087EAFEE10C17BEABC54EEAD3B4932 +:10E12000E59FEB7C54FF973A3FC167957D8879BDA9 +:10E1300005DD7D3C1536B263DCDFC3BC1598872155 +:10E14000DFF4ED4FE5C70DA6C369A57FD310709727 +:10E15000308EDC2D7D5D83665DD1D09BC72DEB0DB0 +:10E160003C7F4B7D37666B20BFDDC1F8392DEEB7A4 +:10E170004FC77F49F034A66E0FAE372A6A799EF2F8 +:10E180003CE4C74CE2C7BFDCD03A4D59176C4E7126 +:10E190003E81FCC8C2DC9F26E506EED11F4871FD1A +:10E1A0000E9F5FACBD7F0FB69E6EB3A7E347465B85 +:10E1B0003CB198FFCBB74FB4AF933AFE5E8D72FF80 +:10E1C000A1C3FA9DA7BAA3BD2AFE51A4B8FE7E53EF +:10E1D000F804DCE77F51C1C78BBD0DBAF2EE54E7FE +:10E1E0000BBD717F3FADF6850785C0FDFDB1B8C49D +:10E1F00007F92E6112E5C119CF1CEFA30B7E27385A +:10E200008208DFCD642A4F24BBFE88F3B9071620AD +:10E2100008BB065A12DB9B4FF078DE52C6F39632EB +:10E220000EB59C93EADC8EFD1D4B73E8C6F3A292FB +:10E230005F680CF33D87E3FAC73B178E0B29017C1F +:10E24000B7C653582DE5C928633C9EF228E6C58819 +:10E2500009E4C550D70F65FBF8EF1CD11FDACF7961 +:10E2600049B4BE0DCE9BB1B87037CF8301EB31BC42 +:10E27000FF5BF6C02F48FFE2EF41E1BDDD799D0E67 +:10E28000539E19EF0CE0D504CAABC1F3DEB8008190 +:10E2900009945783EA859BE0FFF1382E6BA691C65F +:10E2A000D789F29D3C1DBA9FF2D2604CC1D219F3BE +:10E2B0001E27D13CF73B2F70BF3BC647F75337A70C +:10E2C000B8BEEACDE3E44FF5C33811F2137EC7E6DA +:10E2D000A6F36BC04F660150343D06F8A91D7F437D +:10E2E000E59BD9CA3D1CF539F0E309C4F7B76F0DBA +:10E2F000C844BEA9D9592021BE1B0CFC3E9DFC6719 +:10E30000655F50F93D0431327B2DDD3B40671CE9F0 +:10E310005B104EF70E9A45367F533BFAD59AC3E908 +:10E32000BC3F8EE7936C08DA9F147238DD05A5DDDB +:10E33000E877F7511EB2D97B79BC9AE57AB39DEDA7 +:10E340009CCBAA99FF9BA75235F3A8D97E849FE75F +:10E3500062DE6CED392E49E957E53FD11CEE5A1BC0 +:10E36000A61D5FAB1C5872F2480E8EE3BDEE31164F +:10E3700029F26E817E1FEC5BCC2FE3FA838DCE03F6 +:10E38000AAE702A7312795D3C17222DF3BE51574B6 +:10E390007F7E266BA2E7B3F3A726225CC37C43E310 +:10E3A000707DB4A4FE7D0C078D6F5C312C1EE635AC +:10E3B000CE3DE57D2C4BD60BC76589E4280EBFEF1B +:10E3C000156A177583EFDDFB6AE1228C5B8F1139CB +:10E3D0001DD8879C0E65C0CF6254DBF981DCF4CC7C +:10E3E0008925B9A1F1AB7253B68039F0FC817A3F2F +:10E3F000A4558EF267FD3D01F770C09F447EADD9F4 +:10E400006989A2F529E699417DA5C8CF2223F72F76 +:10E41000654C6D4AFA93FB1B268792CF8B717F6404 +:10E4200096CCD763A74D5CDE4E7F15EE46FE9ED799 +:10E43000E9F544920F932A1F3F4EA2F33D0CFC8F47 +:10E440005BDBFA1FAD7966BA33F23758A22BAE6F99 +:10E450004AC09E9F36B8FB47F0BCFC0EC4D79E381E +:10E46000BE7E9E857968B0BEB353C278E9E9582B69 +:10E47000DD170ACE73C6989DE66752E607239B8098 +:10E48000FEB44589AB3504CDF7FB90449AAF54C830 +:10E490009A183A16469B3C15E5FE416E27E675FA3A +:10E4A000B50BBFEF0D61366110CD87E2B1B2813996 +:10E4B0001B787C96E637DF68B5E1B99CC55344AF5D +:10E4C000407602C689F1BC18AB9DE75555F36F073E +:10E4D0008FD7A11F9F3591E1FC1C22F3850CE2E34D +:10E4E000C5F1C9400FA20FC05334E3837EDD94FF12 +:10E4F0002754B2A11FB6F75F0FF2F8723DF71F6104 +:10E50000FC1B893EF130FE846B8FDF842C0AE39F75 +:10E5100093C3F55403EE208A68673B93FE2D09717F +:10E520003E807C98EA5AD67D0EC6350A2C768CDF62 +:10E53000B12B0DDD514F853189F26A8D71F0BC5AD6 +:10E54000D0DD42E48712CC5B67233FE0AC360F1B83 +:10E550000B8AAF015928BE3A0EE36BFC2ED17B1813 +:10E560009F1DAF9C6FCE625FAAF8A3F89A88E3A3C1 +:10E5700078B58BC66941CA421982711EA2839BE697 +:10E5800011CA3C4A3CBB85FC83150A1F0E3AC4F9EC +:10E59000705018D7773B8F30379EFB6AFEE1AEA2F2 +:10E5A00070842F18494F019E281FE0DB7FE571A979 +:10E5B0009DE78E27E03E4CFD0F7B12D04FDC697249 +:10E5C000893530EE9D0516DB027B20AEB1E3501895 +:10E5D0008FEB2871BE5B9479EE602D0D35509F1F37 +:10E5E0002F328C03E61DF484A23C0F54E2B2C1FA30 +:10E5F00070F025B3EE772D4C363D9CCF34701286EB +:10E60000C8827EFFF306D7B9AFE574F0BB9F2763DE +:10E61000AE6B3F147FCB87CE27E438DFCC21BB36EF +:10E620004E54F02E20BE400F34239D9FA936D3EFC9 +:10E630001A34579BE3BD9AF135CEF847029D73FE1D +:10E64000D73FC86EEDCA53F3E33485E073B31C4E75 +:10E6500071B767AE1828EEB6BAF26B5A9F34E6333C +:10E66000FA1DB1C62BE5E4075C2E66B889C4EA6FD3 +:10E67000FD3F95083F7E8B95BE173CFE6DE0CF7B3E +:10E6800080505BC19FC7D20DFEBC2703FDF4382A22 +:10E69000D7803F8FE533E0CF63FD2AF0E7117E0A94 +:10E6A000FC792C57823F8FCF9F007F1EE177C09F60 +:10E6B00047F86DF0E7117E0BFC792C1BAF7C5248BC +:10E6C000E39ACBE8DEFE82D088A5E8677493C3C9DD +:10E6D000DFF8C8D1B793576367F3BF34E8E8DCFFCE +:10E6E0006027DDEF9D24C95141BF47D32DE8F76A6C +:10E6F000F4BF6F9350A9FF7D9B7857DFA0DFC3194C +:10E7000018F47B3943827E4F47FFFB36B75E1AA76A +:10E71000AB1F7C56FFFB36038F95EBE0C7957C99CA +:10E720002A1DD3A5D742902F56578E8B64EDF8172C +:10E730006A89EB2B8F667FF5C987C409EDC59123E4 +:10E740006FE6F6FEDDAF2CFBD6033E77B14827C659 +:10E75000DD77390CA4979E59154671588B77E029BF +:10E76000E49F5D0E2621FF3C736548271C4F2190D6 +:10E77000119F275472BDD0ED6689F839A1D227E2E6 +:10E780007DD1DBAEF8ECC88F4F46F0DFD9827EDD5D +:10E790000BA0BF7747F7CFC238CE3361C0CF286F09 +:10E7A0001E5F682AC091570D0CF523D84ACAF32F73 +:10E7B000FF3E4C398F7A95EEC345A24E07BDB4ABF0 +:10E7C000927F3FDD7B2554EB0F3DFEE3B5F0C28821 +:10E7D000AF3AACBF6366328E378077508D50A6B3A8 +:10E7E0004AF618E2A38ACB4F63A581E4E932C81345 +:10E7F000E207664D74617838215EFB3DAB9E0E5595 +:10E80000C94B719ECFAC34D26ED930F1D57D37C3B0 +:10E810002BAB0F8AB4CD2ED97CA1EDF977EAB8578E +:10E820003BF8FCA2ECCC80762E0AF0E9A6FD6C7BCE +:10E83000BDF6F7AC7EAFC8E7EFF0FBF0DED30A3FE2 +:10E84000AC54E47398B866443A8E239FEB6BA0A750 +:10E8500080F7B12E4F63F43BA2BF2B4DEED45E9EEA +:10E86000EF95CA389E53E6B54691FB67B05FBCC7CB +:10E870002E9615623FAB9D8CF4F86AC7D7F518B792 +:10E88000BB5CCAFBEDF9885740FC76AFF509D87F31 +:10E890008FB91E2ADDCA38BB55B650BDDA9F6477E2 +:10E8A000737EAFFA9AED85F9E2215B91ECC559CA06 +:10E8B0008FBADA68646887519F217CD96AC43312A1 +:10E8C000ACDB8C630CEF33378619699F62F5ECD3B0 +:10E8D00004AFB0713842AECDC6F3176F29F38990FB +:10E8E0006582DD41F3499726476A7FCFF55A7AF072 +:10E8F0002D93CB7011C631E06F22FD7E4747EFA903 +:10E9000076F65AFAEA4FF88F78B20B0FDD8CEB6788 +:10E91000D94976415DB76D1DC5D76D2B42277D88DE +:10E92000EBFE52858F9E0E1DF33ED61F18C17F074A +:10E93000A779C4ED3DB47A72BB32EE6D0ADE0B8E60 +:10E9400039BE9A0BEF8F745A189EFB18293B7AFC3C +:10E9500002E15122E5351FC01A1BF05CC5C13C55D0 +:10E960002E9CA1287FEF8E9ACA0EE1778AB99DDF8F +:10E970005A3C9E9E4BCC39B237BCFF498B91FC1A56 +:10E9800078FE9372B94F19CF070A1EDF57E8B05BC4 +:10E99000A14333DA132877A13D217B6157EC05B7FA +:10E9A00027DBD09E64201DB83D69417B9281FB6FBF +:10E9B00013A8DD5FD09E40993BA288F6232F232326 +:10E9C000913D99CD16035C08E317DBA1D71DA9A2E1 +:10E9D0008E3EC5DD4375F4191E13AD83878625E889 +:10E9E000E021C6141DECB87253903DE81B640FF48F +:10E9F000F624FFCB21BAF6FD0FDEA1AB2F718CD729 +:10EA0000D58FCD9FA8AB1F6D9FAAAB9759635104BB +:10EA1000CC37EF4B467E685EA73522ADAB957D3493 +:10EA2000D5DF027A923F56F05791E456C5471E6BE8 +:10EA3000DDCF33D07E9ECC243CDF495B96C9BA7AC9 +:10EA4000F2A30E9A9C09780EB1BE04F80FCF231ED4 +:10EA5000AC18C5683F1EF818E42ACF79E24BCA3BD0 +:10EA60002A96F5237FE99251B7AF5610B43F36206E +:10EA70005BBF7F96778DFD33EFCDCAFE431BBFACE6 +:10EA8000FDDF450AF6CB40AE441CF7D3A1937623B5 +:10EA9000DF7CF819B757CD9F3DD51D9F7F824DA1D3 +:10EAA0009F7DBD9FEE8E7CBFAF553E5CA15ABF6B74 +:10EAB0006B26FF1D9A370F266FC7F546AE4920FD1E +:10EAC0009F9BF5249D47BC7CD040BFD3995E5C13CF +:10EAD0008A78D97A685D98FE1E95464F909FAED190 +:10EAE0001322FAF751FA7A6342004EE6C4C1F6FFE8 +:10EAF0001710600A2E008000000000001F8B080025 +:10EB000000000000000BED7D0B7C14D5BDF0D99DFD +:10EB10007D259BC08604DD400293F030228F0D7965 +:10EB20006D42122621D0A03C36801004E384A0D090 +:10EB3000566DEA137B6933493089014B546AC1FA37 +:10EB400058B1DAC7E7FD9A5A0950B15D9E55A1B296 +:10EB500048B051515779685BDA0F155AEFFDF17DD6 +:10EB60007EFFFFFF9C4976864D88BD7DD97B939FB4 +:10EB70004ECECC9933E7FCDFAF73608CB1CF24F875 +:10EB80001F9BC0422E463FBC3DD5D42E62A1ACE8AF +:10EB900076B9A97DB5A9FF0253FB3A53FF1586E765 +:10EBA000AF642D1CAA26C0DFF833FDE2EBB606C623 +:10EBB0004257F4F5CBB30524DFC48BFBE5775BFB51 +:10EBC000C685FF768F5B653D9FC25857B714746644 +:10EBD000C075EC2AA6E5C238DDD620B3D0D5CAE090 +:10EBE000F92B3DBCED64C10D53E1F9B66E9BAF5DF1 +:10EBF00066EC45FCAE93B1F1811B860612192BB170 +:10EC000085637EB7F49CF1BBAFF42C18CA62F4D3D1 +:10EC1000AFBF10E3BED0E0A275ED6CF0505B7F2E6D +:10EC2000FDDF7347E7E3BCB3241FDC86F997273386 +:10EC300058F72F2FAC74E3B8305FC6463036A33395 +:10EC4000ADBA712C63320B2658A1FFB62C89B5C31F +:10EC50003A738FF1EFE7DA95644F0CB8326635C23C +:10EC6000FFA2F1E007E174C11AC4F1F68C5BF2D0A7 +:10EC70005418FF60B7C4703E0E75B53B3009DA3DDD +:10EC80007C5EFAB8D33FB5F6E119FE2B3E136F80D8 +:10EC90004BD1C96186E7B9572E1C8AEF3BE4F9C90D +:10ECA00008DF4BCD93B178131D0D33B54718FA8F9C +:10ECB00097016F93FAC7C37681876D8807B86E8F07 +:10ECC000F3550762E06DDB78E7EA60D43A1B7C40DD +:10ECD0002C7978B5D235F74AC91702F89CEFB6FA05 +:10ECE0001078059E7AA93E06DCFDC78D7492DF1D63 +:10ECF0006F800793960FC8076B8E37B6EE8BEAFFCF +:10ED00000D5F62CA6937FC51C00A68FD9778FFCF72 +:10ED10000D5AEB3E3BD031634A27AC93552E64AC81 +:10ED2000B0FFFE8C35D1FA7438B2CA64C65207837C +:10ED3000A70E7AEF227CF5F37EDF381A63C3019EBB +:10ED4000005E9C57EBE4C0C33E1C275225E1F71F31 +:10ED500070DF2A45607DDF75DFBA17E9F3D07B0EDF +:10ED600019F97AF77B5D6978FF60F6F634A4FB83C6 +:10ED7000F04E18DACC065883B643BBDE8DF4F54A64 +:10ED8000F76DC43F32AB3F3889CB015F3B74DB9EEC +:10ED9000C5E9B0BF79BD24E4CF01C1AFFB04BFEE2C +:10EDA00069F0523BD420D3F5170D59747F57838FE8 +:10EDB000DA3F6FF0537B478342EDAE864ABA1E6955 +:10EDC00008D0FDC30DD5D4FE75834AD76D59B7570A +:10EDD000A03C3A9F0600807535B9E7D962E173B669 +:10EDE0002C19E8E64B5EB781AE667A920DED19AE4E +:10EDF0009186FE656C8CE1F9F44F27189E979C9DD7 +:10EE00006A684FFBB0C8D0BF30526E6817F45C6DB3 +:10EE1000E8BFA062A1E179A07899717E5202C997FA +:10EE20009D6719C9E579B97586E73BF10F94C31F52 +:10EE3000B2A09681705938A03CD5E5F45E819FDD83 +:10EE4000023FBF14F8E942F8139F571AE09D7FBCB8 +:10EE5000F39A29C0AFBF6A584DCF1D5943CF49F02F +:10EE6000DDED67E365947BFB1BEAA9DFC1B71F24D7 +:10EE7000BAD929E671D0CECE4929D8B6C84D968BDD +:10EE8000E793D763E4F3F1953790BCDCD9DDE44632 +:10EE90003ADB115930287DA7F7FBD5B90533902E01 +:10EEA000FCDDA0A3322EADF7747D75A9F1F57EA827 +:10EEB0004F63E909F3B857475489C13AB6F7D43FCD +:10EEC0009488EDD0972519DAF93DEA0CC4D7AE2C19 +:10EED0008B47B250BF190ACEFBE46DD7E0FD1DC7CA +:10EEE0006D569CF72190FFB88E9DA06F9DA87FCF97 +:10EEF0006D754F06F8BFD8F3E03593A19F76C6E64F +:10EF00001BC72E9EC7A86C89E4C2B6894EAB650AA2 +:10EF10005C8FDB5808E5974D25787645B6D215F518 +:10EF20001FBF5F4FF8BA32DB43EF6D3FF95C32B67B +:10EF3000ADAC9EE4C08BC7AD95C118EBBD12BF034D +:10EF4000B223EF4283DB03FD0F1C5FE146B9B2A39E +:10EF5000878F9FB75673239C0E46B626E0FD9D59BA +:10EF60003FA371774FE276C5CEE356A2E79D13AF7C +:10EF7000D8E0CBA575FA1076703F01DBDB7A6CD454 +:10EF80009699CAC2292877A460BB05D7B382BD066B +:10EF9000CFCFFBA420F27D1ED31CC0A26CDBFF6B85 +:10EFA000599CCDC1CF6C9731760B7F994D3B6BD47B +:10EFB000B3453D463DE2885C383A1FC6EB3AC3E5AF +:10EFC000DB8C4F8D7AF7E01B999B028897337C3E50 +:10EFD0003B8E2F58548572E77989DA8D93563DFA26 +:10EFE000757CBECDED73C2F7BE9CFB644B327F7D5A +:10EFF000C85C9847B19853DE19E33C0E5E59C73E92 +:10F00000C6759EB4D13AB61DE7F6D5F92CBEAE9DB5 +:10F01000BE3AF66DE42F617FCD78FBFBD74C4A41B9 +:10F02000BAB0925DF182EF67C939289F3C9281EEB8 +:10F03000004E4437E7BB198D031245BA15C629F0B7 +:10F040003B3DED1EE4C70EA29F836FDB7C4DF8585D +:10F050003AB4F736E89F375262B8A22F074DF2F262 +:10F06000876E43FB16D9282F9DAC6A40BB61DA59E5 +:10F070008751BE7EEA308C57C0A29E133EA39E6786 +:10F08000FC0576895D5D8676090B2F1A94BE66AC09 +:10F090009EE4C50EC67CED404085574A0AC1EFB8D4 +:10F0A0008BE057F0DDAA698CF4B43A0DF981883110 +:10F0B0004A2F5FD24EF1682C255F7C0AE980D94E39 +:10F0C00047A07F1B10C967A8BB851E378FDB9FBE7B +:10F0D0007FC03D84E47D718585F8E7BBEE5749BF6D +:10F0E000779DE2FA1D7F224077D7E21FA8EF4F39C4 +:10F0F000881E5E986D2139A2DB0B0B996247BE9981 +:10F10000E73F67BB1FE836E0AA99740B5C5F78A302 +:10F110006B24F2EF0B6817907CE8207E7668895AA2 +:10F12000328CB3ABC7497CB813F8CA85DFDDE52460 +:10F13000FA043E5D8F76C2AE30E7A3AEB3566EE7FB +:10F14000ED72139FECFE8383E6DDB5D6CDFD8B33E8 +:10F150000E05EDF09D6B13E9FDF17262C88676FC39 +:10F160001A3E7E8FC0EBEB02AF07859E7A19F594AD +:10F1700013F5904CD7FDC28ED88B768413F5995F2A +:10F18000E833AEC79E3FFBDC5B48FFE777C591BD28 +:10F19000399E6575E2BC762538689E66382F558D98 +:10F1A000F4BFA4DA682FCC9968A4FFABC78E34B43F +:10F1B0002BD3C618DE9F957295E17945428EE17991 +:10F1C000B96D9AA1AD5C30DA0BF3FDD718E9498926 +:10F1D000B21732F1FF467FF1DA687F11E5C8D90531 +:10F1E00064AFEDEC117AF964E65075E2C5FCB3F357 +:10F1F00024D79FDB8F7F9CA8C6B01F3E14FD7E27BF +:10F20000F07146E0E3B7A39493D94097E74F7EECC3 +:10F2100000A5D12F1DEBEFEBEF7D183C31245AAF49 +:10F22000A74B32D1B7DEFE43D75BE3F1F960F902B9 +:10F23000F4585B04F07CB794D8D10EAFB4DAEA9FEF +:10F24000C0B6A6D9D8D3B9048E2C1B3D9FE0437B12 +:10F25000A539B1FE07F87C5BA3D3B33505F9E85BAC +:10F260003FC1F61A6005275CFF1C372AC880D51CF1 +:10F2700053B9DFF28C3D30D2877AD31258760BF433 +:10F28000D7B6387C4FCB17CF2761AA4567F61DA8A4 +:10F290008724C1F7FF695113A6C27DE5590BF163BD +:10F2A0001C38A2380F270B8490FED96A6519F20723 +:10F2B000B302FFC0F51B39EA30ECCF14267B601C8B +:10F2C0001215F03D4BF8C07F58605E7656AFE138BE +:10F2D000CED52061809F1FC85653A9BF6D018DFFF9 +:10F2E000FC5CC6DA492106A89D7B17F3B427C1FC54 +:10F2F000986AFD18DACBC0CFC7EF5BDD37931E7A73 +:10F30000EBB7D6A014C35EEA85F3CDF633119DCEDC +:10F3100032FBEEEF1078ED1274B12323B02C965F20 +:10F320003815E182F6C5BBF324A4AF5CD71005ED18 +:10F330000A58A05405F27DC7FB57BB6B63BC37333B +:10F34000B776EAD428BAC80D774AB509080A4DC27B +:10F35000756D83BF715D3FEFB68610BFE7131C2448 +:10F36000B7FB5B4761C4A8870B7A8C7E3763CB3DC4 +:10F37000A7AF427877583EBB2A9ABE94F5D1F4F5F0 +:10F38000FCC5F44570BEFB6816C1B5D9C2E94B0394 +:10F39000FAC2E75A793DD197666581E65CA2377A71 +:10F3A0007F8DCDE57182845C353593E8A62B71CED7 +:10F3B0005B2199BE376601F97135C28FAB2139FFE8 +:10F3C000F23190F331ECE8DDC7168F8C00FCB68D7E +:10F3D0005B3212F9BC0B15C0089C7EFE52B42F7B29 +:10F3E000DB802EB20367320C55C1F3DCA50AF69F11 +:10F3F000ADB7F378FF32DEFFA6A99BB668F8FC7ABA +:10F40000F19C2DE4FDF5B656B0B40CFBDBADD47E1B +:10F410005BF47FC8A7AC42BC3D90ADACC66B361A5E +:10F420002B703D3D45F90AD2E9AAA98CD67BD714A9 +:10F43000E5E6E8F6CF262BB746B7B7F5FAA71DC223 +:10F440003FBD85ECD2977B16905E9259E01AD43B73 +:10F450002F87791C6ADBD881FD9F5F097B7EBFF017 +:10F460007FF6A23C223F88FB3FBF147AE545A157B7 +:10F470005E107A65A7D02BDB857FAAFB47AFA27F02 +:10F480000AD743C23F7D05FD25E8973BEE04D91519 +:10F49000E73F65C4BC4DEE5F48B1E46A659AD17E32 +:10F4A0009B9562B4B72A128CFAA6DC66D437CA855B +:10F4B0004C43BBF4DC0443BBF88CD13F2D3A596478 +:10F4C00068FB8F971BDAF9DD579BF4CF42C3F355E6 +:10F4D0005365C2E35C9FD14FBD26ABCED0AF0F6F5B +:10F4E00001613F3C968076DCB6B175026FDC5ED080 +:10F4F000F1D6F54F83B7BDE49F9D3FCB445CE171EE +:10F500002996FFF9AF8FB74BF05B02B7F32EC56FAB +:10F5100007847ED827F4C31EA1FF43C28EFB8588D3 +:10F5200007ED42BC511C88C7837620DEA2E211CFD2 +:10F5300023DE9CFDE3AD79EC439CDF4EEA78BB35DE +:10F5400026DEBEE435DA77333D46FB6E86CB88B7E0 +:10F5500032668C074DFFD488B792B3C678D0B40F0B +:10F560008D782B8C18E341053D46FB2E2F6C8C07C4 +:10F5700099F10676404ACE20F0067E924274EB1353 +:10F580007A3FB890F451CB5CAE1F810FC9FE7EE686 +:10F590004EB003B2FBE0F1BCC97F7ABE1FFD3D3E19 +:10F5A00087DB355D6FD5105CF3507FC7E8972DFA88 +:10F5B00065E778E8EAB4312D7E2A4D73DF08988F2D +:10F5C0006D2CB77B6C891B18D98B406ED6FC3E3BEB +:10F5D000494A08301C1FECA5EC9CBCBE716D9E7A9C +:10F5E00086F253723EB81CD7C524AB8FF4AEC93E29 +:10F5F00062AB3DCA6D78FFB621BE7680C54D3949F4 +:10F60000340F2FEBB4A39DF18D1CA508C795667030 +:10F61000786C4B071F1EE0B12D8EB73580D7D3D045 +:10F6200096862E27F87501BCA46C1C3F85DD05F37A +:10F630005A98E3E07058CA843E7DDAA80FD1608002 +:10F64000F633F1BC7D6DCE334BB5B43EFD5BF3B309 +:10F65000AE2D1A8C333E61441D9B0CE36ED686A101 +:10F660009D3911E687F2D1EADE951E4B4FF467878C +:10F6700069939545481F7709FD3A1E20629BDAFF82 +:10F68000FBCFC407BE8AF8CD457844C5BDE6E67019 +:10F69000FB6C218E9347F6A5126D5FB2F0426AB7FC +:10F6A0006473FA7A6AC302A2B70480979484F3E77A +:10F6B000F05B7607A7AFCFBB0E7DFE03D04920DA03 +:10F6C0009E8EA293BB62D1099BE3F392BFDE9F3D66 +:10F6D000A7F1F9360BFB51B7939D69BADD1C147085 +:10F6E00060A1A26174653301AEC33C8CE234351E67 +:10F6F0006B3008208B4B9A6A21B95361619E0C1CB8 +:10F700005D611C8F73E468F9638E0FFA8FC79BE409 +:10F71000BB31EE547C6684A15D7A2ED3E4274E3053 +:10F72000F99139263F739A493FCD30F4AF4CBBC6AF +:10F73000E4C72E34F9B946796363364DE0CB4A719C +:10F740000BCD22DBF2F13E23FC443D27BFB317CEA5 +:10F750008F2AD5C4AFC2AF31F3EB37726482B3C521 +:10F76000C3FD1A9D1FF4F775F839BC1AE17563BE25 +:10F77000AE9F7CA4775CA12F338CABBA7C3C4FA3AB +:10F78000F7DFDAE07AAB621C63DF6F606F5500F27F +:10F79000820D1EBA3EDEE0A5EBA30D325D1F69C8E7 +:10F7A000A27E9B1B7CD47EB8C14FD74D0D0ADD7F56 +:10F7B000B0A192DA1D0D016A6F68A8A66B7B834A1F +:10F7C000F7C7DA540DE32063DB984F83A58CEB80F9 +:10F7D000EF45C16D4C1BCC230AEE199AC7D01EBD54 +:10F7E000C66BE89F5E2F1B9E8F5C9D65789EAAFA74 +:10F7F0000CEDCBABFD86FEC3038AA19D5C5969E885 +:10F800009FA4040CED445FB5A1BF3B4B353CDF53D7 +:10F810005A343432001F773484C20887F686305D4C +:10F820003734BC44D796869E30C2E90CCA5FC0A369 +:10F83000C7D649F2C333D1C3304FE17201BE008F46 +:10F8400049368F25296AFC2405C6CB8A9E1F8C6702 +:10F85000F0CF82442FEEACB0E1BED3DB63786FA66D +:10F8600094508EF98923C512C5BD8E142727A2FD99 +:10F87000B2DEEE999B0BF3387C4CF26DC5F5E20BD2 +:10F8800031E4E529616FBA27BB482ECCDF64D92A61 +:10F89000115DF3F76FEA1E13337E74F89BAC1AD731 +:10F8A000E5DEB35346BA985F5C9B1C17E5AFCD0FFE +:10F8B000FD47452A8D979D1F07F4327F73ADA36ED8 +:10F8C00062DFBAF47E376D32DA977D741F74E13AE5 +:10F8D000C66BDF74A17C6B4FDB4AEDF6AC81F32481 +:10F8E000BF13EBF950D8CFA7851D7652D861EF0B27 +:10F8F0003B2C22ECB07784FD7C5CD8CF6F0A3BAC0C +:10F9000047D861AF0B3BAC5BD861AF093BAC3DEB7B +:10F91000B959240F9FB53029869FAA5FBFFA43A328 +:10F920001DF6E5A0D10E5BB5D96887DDD861B4C3FB +:10F93000EADA8C79B95AED2AC3F31BD618E36CD7EF +:10F94000D71BE5E1B2D5330CEDA5AA31CEB6A4DACA +:10F950006887E9F8B93660948B0B2B8D76587FEB6E +:10F960007D21349BF23F88C413517AAF378F8B7A55 +:10F9700005E825F702E8158A83079A317FB203BBB1 +:10F9800080FE2DB1868F4E41F9F9BAC430EEB4E74E +:10F990007CFE9CF9F2C5DFC9D78C74B3FCB831BECC +:10F9A00071DD1D46B856DD6CF44B1C9546B82A69CE +:10F9B00046BF64A159CF048C700529CD902ECDFA95 +:10F9C000C6EABE5946F9FD79F58E83815EE16D8305 +:10F9D000DE71E09D4CC373D23B6DB93C5E970FF373 +:10F9E0004063A131AEE010E693F6BC61A3FA109833 +:10F9F000E06B6341FF94E2DF00BF17EDAA560FF4FE +:10FA0000FACB42A7A7094C56269DD9FB35E8EF1043 +:10FA1000F910F6A9ED248EAFC22FE22B9F413B4A8D +:10FA2000CFE585F9F3A8F91A9E7F0F7136E07C9433 +:10FA3000D7C6E6FF3DE7939882F6109BC2A6509D7D +:10FA40004164D8A0E2ABE6FBB9216E07E5A6713BA5 +:10FA5000C89FBE40127927E6C1B695B9289E398A5B +:10FA6000059FC63867FC21F73C6836E390A9E85744 +:10FA700019F97FD19C81F3F25FF21AF97FB63CC687 +:10FA8000E40F19F97FAECFC8FF4E66B25F224C4635 +:10FA90007B927060353C2738BD26E8A8F1BD96659D +:10FAA00094874DE771379D7EA6097C31D6B9B7168C +:10FAB000F3CDE057A2BFE1645AF214AC2B0AD72B66 +:10FAC0007ADE8DF026ADF5915D7A86E3C70FBF88AB +:10FAD0003F3F8BC217E2EFB8117F4ED3F3D3829E24 +:10FAE0002E9E17A7A37FDCBC4C749530EC12F9B79F +:10FAF000D874551656A44498DF7E8F85F2A9FBC3AF +:10FB0000F5E132687FE2E5F542AD690B6C345FA642 +:10FB10000C9909789825D6EB1779ADAE064676C7CD +:10FB2000F30D2EBA32562FA13C6AF1DE968CFAB153 +:10FB30006B943A12EBD2BA8627ADC3FCFC367B52EB +:10FB40005AAC7A96DDF602D2A75DBB536D32BC5F2C +:10FB500066F3D8F0BDB2B41512FA7B5FEA616417A0 +:10FB600094A5F1BA8CE71B4247F8F754AABF8175F8 +:10FB7000CC40FBB4C2533B233105E3B3608BC9686F +:10FB8000E72691FFBA6FB893F0E6F4ACAAC0FCF197 +:10FB9000ABA912B3F8013F3EE60BA11E484BF0059E +:10FBA0007138AFFD7D84F36AF8FD2CB34F2F009FB1 +:10FBB000BF1F8D8F0216D5A6BC82B13D224FD43F08 +:10FBC00009FCC84CA53A8B961E9E1F6291D8799667 +:10FBD0007785DDA0C7F78F0BBBE14D11773B22EC9A +:10FBE000861661378484DD7054D80DFB84DD704047 +:10FBF000D80D2F09BBE11561371C127643AFBFC08A +:10FC0000EAC99EAE65AE08C6D95F05FF1CE58877D8 +:10FC1000A5255809EB98A17604CAA1ED5C6727F9E0 +:10FC2000393A4D6BC4F8B8B35A9B89EBF02E3FBB01 +:10FC30001AFBA7A6396405FA3796B6A746789E61DF +:10FC4000C85CE08F95825E96AAB30E207FE870674D +:10FC5000D2A379946FEAE0F076C12FC23B55857646 +:10FC6000941CA935C17529B6A3E48603E910E058B0 +:10FC70009927F82187E570786B7108EFB85A016F02 +:10FC80006F4A4CFED82CE0ADC36377E957AC1A74C9 +:10FC90003D9AC6EB258E167FC5FA2AACAF5B91283C +:10FCA0006FDA9DC6C75B20E8DF3C9E9E47DD583E6D +:10FCB000709CEEB0E8D7DB6E63B27368D438E5FFB2 +:10FCC0006697E1FD25A17BD2911F360ED1F3C33E8D +:10FCD000B2AB674AC5BFCE80798645DDA32E271714 +:10FCE00033011BD3F78E8A75F6379FA3E5D7D86506 +:10FCF000187751E81E86DF73DAEABDD1F5A4DD621C +:10FD00007EAD55B733E4C7F028C03BFAEF01A78CAE +:10FD1000F6F6E834DFBD88776F9A6ABF13EECF033B +:10FD200039287B705A1DBB53B01FBCF30843FA98A7 +:10FD3000D089FC7634DD45F2A6BFF95CA43F828C05 +:10FD4000EC90FEF407D031D941CE391F1C477F76A5 +:10FD500021ABF785E0BD70AE6F38F22FABB6935E86 +:10FD6000CE82DFE87C9A7E5D68D2DB6EBF7D40F993 +:10FD70003BFA42431BF2CD51C137AD3696887539F7 +:10FD8000E139B7BB103EF3D333F7207E58992B32BD +:10FD90000EE0D05A7CE7F508AFD639AB3C16A4ABE1 +:10FDA0009231F43C5CE63A8D9538BF29BB3B5D8EC1 +:10FDB0008277EB7DAC544578A7DFE5BD09D69599F0 +:10FDC000F6A7067532F4B3737FA7A7FCF76919513C +:10FDD000FD27E595FD200FF9B97238F1C378879AB0 +:10FDE00019AB1E58A7F3C6D278E2F3F76B799D02E0 +:10FDF000DCBF770DCC47C5BA155F1FFFDE28E829A9 +:10FE00006EDC39E273F53EA78C7E069396B7AC8123 +:10FE10007635DA4968376DE27CABF3717ABD515EB5 +:10FE2000AA26BEAD36F1B5CEC7BB75B9D9C7C7894D +:10FE300088D7B85ACE4FFDF1F1D24FC1BEA142A032 +:10FE4000A0C1AF7B63E59878AEBFA2ECDA2924931A +:10FE500064473E568132B26BE3C57320C9DD389FDB +:10FE6000F03D3973115F5A23D8FF38B735F63E7A23 +:10FE7000CBC475B2217E587FFC5A291BF329ACDE16 +:10FE8000DE6717671ABE4775028BA3DB48AF9AF28D +:10FE90001BB41F308C891FFDF37B47F637C3F7DA9D +:10FEA0004724B34684E71D9CFE5CF010C703353D34 +:10FEB000C48FCFBF352E1B53F72C9A5E61FC88C6CA +:10FEC0009FBFB36678369999A25D73CF98A9D8AED3 +:10FED0000AD84F46CB55566123FC5FBBD6B215E31B +:10FEE0007EE3A58FCEEE85FEF157397CCD30FEB591 +:10FEF0000FACB0235C1669EAFE3AB8BF08E822E806 +:10FF0000A37518F8E4A8CD63C7718E56585807B486 +:10FF1000E31719BF53B3D6C847663BE458A23ACAA1 +:10FF20000AEF7F6071B2AD70DDBD65D5E338DEA943 +:10FF3000079C544FC870AC7CD4034CC42595C7EFC4 +:10FF400081E72B363B19C603960A3B3F313F83C6F8 +:10FF5000B5BA97D3FBB5ED89E40F9FDE72F964C49F +:10FF60007FDBB0FA5B03C037A792D41AC4EB8AD602 +:10FF7000ABAC1A3C6F8BEF9889FD3FB032CFD66C9B +:10FF800068CB0FDA713E3D6017609C559F676D5BD3 +:10FF9000147EE1BFEA7C1E779F67656A670C7BA6CB +:10FFA00023DFA2C7573567D4FC1FCA97E9FEBCCC34 +:10FFB000612D0FE17700FB1E9F800BAE7B268F87A4 +:10FFC000B6A5F96A8643FBA485799A52F0AABC8348 +:10FFD000FCA9DDEF644F13FA19F5778C1CF1647BF3 +:10FFE00094DF3F497CF744127FFEBE373E88EB7CAE +:10FFF0005FE66DCD9B10247AB6A9598B13F97A2C44 +:020000022000DC +:1000000097E1AE073EBF6389B22393F0C1E4E76096 +:100010005E2B367D97F0BB0DE083FCD9E3915B76D8 +:10002000C33C4E83F2D6F0B9F7919908CFDBA70213 +:10003000A1A65E0CA77BF287F13CF4E6E644D2F77A +:100040001EA63A2EEB83476DC7F6BB2D9349CF6BA7 +:100050005C7E70FEB3B028F90EF89D57F81DFB0AC0 +:100060005C6F1CEB40BC58F7AD73E13C97D6DA29C6 +:100070002E94C00295284F6B3759A80D3F1B505F37 +:10008000AC10FCD5260F3B5087F0403B9CFCBC4796 +:10009000F7635D40AD905FD52B8D747AA3D766A0D2 +:1000A000E3AA3546BA86751ADA9BF379FEA5C77FAF +:1000B0002A05F5731B2C1BE1F2418B25B895E46BE7 +:1000C0006054745D9D9C6FD5EB56647B14FC5700A7 +:1000D000FDAD40BDE1621DE5A9B8EE71B390DE1D36 +:1000E000C7E2699E66F8FEB3C3E144BA5C331CE61E +:1000F0007302E818EB7EDEDFD24CF60BFE4806BE3C +:10010000F6B4207DDF04B37CC443F4E9C0FC914E17 +:100110002F3A7C6A37671CC07EDEFF932883D3C4E6 +:100120006ABD45AB30AFD34B4726F8E09A6DFA77FE +:10013000C6F4D1193D8F4167E5D097E345237EA9E9 +:10014000ADE8CDE78D1AA86E99F05D049FEB9ABCDF +:100150004C2B16EF03DD6F2C7D85E8E0130F0B4A67 +:10016000DC9F7D1DE57EA2989BC69410CAD721A274 +:100170005E14F512FAC9C962BD496B2C6F56E430A2 +:10018000366C8DF46605DC4CAA0887504F38BD42AA +:10019000EFEE2AF8C9F8CBFAF4D890F839BE10ADD2 +:1001A000C6934AFB12EC9E54B47F1EB058AA315E2F +:1001B0003F8419EDAA64133C58AEED64B43D1E2F84 +:1001C000E4FDAA99632CE4E7541AFD529BC92EFA68 +:1001D00011D2F5F0BEF5CBF827C0B105FC3694532B +:1001E000C3421D1D489F3560B70669FD3ECAE7380A +:1001F000407F3C62E98B5BFDA3E21617C5BF44DC80 +:10020000A2BFF8971E0758C86FB18D0ED58BF9BEE7 +:1002100085DE9BE6A01DDA58FA152FF94BDED36474 +:10022000973A845D1A376EA587E7CD38FFE87100ED +:10023000335D99E34966FE33DBA5BFCD17F6D304E2 +:1002400036E1F3C405F4F87D6B16F77B5AB35634E8 +:1002500061DDDA79E1F778342BE171F1220BE151BC +:10026000B7D716FBCF2E42FE7B55F81797F27BDAF5 +:100270004D7E48BCFF494589A13FED055C3EBA8BE8 +:10028000F9F3C52E667345E50D1C055CFF2E063D92 +:10029000E88225CE633CBF319F19F35249621CFDB1 +:1002A0000A3FE1A9F9863AC1A4027E9FF2A04E91CD +:1002B0000775893AC1B2EC737B3FC3FB0AAFFF7588 +:1002C0002AB58FDD8976DFA2449F95E8577DFA3BFA +:1002D000E81F2F7293BC4DC992A9DEB53ACDE52334 +:1002E000DAD794D7D12F5BC488B701D40AC9DB25EC +:1002F0005817E119C0DF710D1C2F4BD0FD9D624EC8 +:1003000057BD71A50097DF56F8457ABAB6DA482F7F +:100310004BD481E927BB40F8D162DFD6F8C885DD30 +:100320009F115D70FEDD388AE7A1CFCF813E98B77F +:10033000EDC71ED7FDDB043BF8450968BFEE257A03 +:100340000F67317B34BE03C592A1AE215CC8E23D8C +:1003500043713641C257D8CED21F80FE87CB3E6054 +:1003600077C0A712BE33CC82F57BFD7DD74CD7F783 +:100370008DBB89E2FCDF9E0D2082F9DE878965AAAC +:1003800023F8E9329CC7B7B14D75753F5A8675752C +:10039000DF8ED3DBCF7F4F89AA2BF87AC1AEEFA1D6 +:1003A0005C575DA05F613CB7CCA88E8AB14E92C706 +:1003B00012C6FD501E4F8C8227F90946F89AED7639 +:1003C00009F13719E9D1C8E7E6EFAE32E1A5BF750B +:1003D0009BDF839FEA09467AFF5AC10075B1E6F7B1 +:1003E00013B04E22F1F3D71780E0A43CB4C4AC3E66 +:1003F000F48F5939A3EF593C9C8E50A2A0DEB3D79D +:100400000FF111DCA01D877A20E8D6E3A734E93884 +:10041000A40309F38621D2DF309588650CF6D7EB6B +:100420000C54F6997BF0720EE42F8D2357F23CF2B8 +:100430001B0A8BE0F7C63FB239908FFEF931D0AB83 +:1004400032EAEDAF682E689F5BCB280FE0F6A8D4A8 +:10045000864F459A61BE5E95B76B0046A8879D5E44 +:10046000639DEBEED247CA1CF0BCA582C7550F377F +:1004700084DE588779DAE222928FEBB063D47CC3B2 +:100480007BE21C187751B5AFBBD04E7E77ADE4C090 +:100490006BB8A956C345BF91AA755A648C33A80C92 +:1004A000FD7AC7DAE69948BF6FD835DF30B8BE8726 +:1004B000715818BFAD49BB05FD1C459E539901728B +:1004C000616B9B8DF613BD57FEFB34398AEF7E5B63 +:1004D000C0FD845777C77D1BE1D06A7145E2F06AA1 +:1004E00057B7DE9782DF73F81A618A6F343E948EB5 +:1004F000DF69BDB1D5B7079F373A7187296BDDE258 +:10050000AAC6715BD36FF2DE1435AE6BA4A31EEFE7 +:100510008747B450FE59ADF439E292705D1F257AD9 +:10052000E1FDB6B539C9488B2DA98E5175D8EFA616 +:100530003FFFBA00F12E5BF391F51CDE0E3BAE7B64 +:10054000B457D5300F7E214FDD87F4BA74CD7B339D +:10055000A93EAE22E95EBC8EBEF0B53684FF1B22FA +:10056000FE12495D4179D99695752E9CEFFCD4CC4D +:10057000A6E8F84B4BF18DAEF1F05EA6D75ABB6AF8 +:10058000C8C5F4D182F19629382F58CF24ECF7A7AB +:100590000615FA45D21DD5B1F663BD2BE0E76A5EBC +:1005A00095897190962D2E4CC3B0168BBA19E39C89 +:1005B0005A4642CC7AF5097EFE5E8DEA99E99009A9 +:1005C0003FC46FBFDDFEFAF7B4B1684772FCB96C87 +:1005D000CC658FD27793F2CA4E1644F9CD177D378A +:1005E000B585E47F8B85F3EF04FF1FBF87754FCF81 +:1005F000E605CE20FC5ADBD4CD082FA6B9D890D280 +:10060000FEF924721F1BC540FEB6343AAB63D59B7E +:1006100045564AF3904F8083DE1B322A4ADE37D597 +:1006200065623C24D2780571776FFF2DAE77100F8D +:10063000912D5949A8FF22E92B3233916E055D9A1D +:10064000C7FFF7026E3FFE242760F5A35E9EC8F346 +:100650009BB30B02366AB30E2FDAB55F00BA1DE901 +:100660001FFE0FA55BD273EF6EFF1DD115F30C2E8D +:10067000EF1810F2B6B1F43F29BEBBBE90E74DF4BF +:1006800078A06EE7C68DFB7E08FDF140A19ED72ABB +:10069000BEF7768C1FE979D3393C1EE881DF58F12B +:1006A000C080291E18DF4F5C7F865FE83D61CFA6C2 +:1006B000C91D817294BB87241FFA0F98AEC079566A +:1006C000052CC110E51FE25D34EF1211D714FED6E0 +:1006D0005231EF371B5C0CF3461B1DCA7E9C7FBB5F +:1006E000C8FB5EB7FA817BD1EFC6B835CE7F1EE37B +:1006F000761C2B8EF351BC05892095F5FA670BF01B +:100700001EFAADD29CBC68BD083320BB653E33DA0F +:10071000730B98C9CF5AC9ED30DDCF5A66B213CCEE +:1007200076FE22D3F3BE7C0078174037E7FC391BF6 +:10073000B1B4ABC6BFEFDE480CB9734CE4E98E36FA +:10074000286FA21EBA77D1CF5C48A7EB6D9D2ED43F +:1007500027EBE7DC9E88F4B77EB9447C79A4A192AC +:10076000FA1D6E08D0F55BFEA4DE785648CF33C084 +:100770003C5EC953EE423AD7EDB14573CADE5C1711 +:1007800085E70515B30DED4071D59BEBA2E3903ADB +:10079000DD49AC3E561CED593FB7DB6D4097545FC9 +:1007A000283DEB1BA8EE06E8E85C349CD6FB8DE701 +:1007B00010BCEA9F3174203B465FAF0E271D0EFA36 +:1007C000F3FEE679A79FCBADBF749EC1CF394FF33F +:1007D000FCF479F7D73F2071BD70A7BF6C39EE17D5 +:1007E00079254FED4479BAA832693FC61A8EDA38B6 +:1007F0001F1D5512695FFBFE89566ABBB378BED5D3 +:100800008C5777652DC9B54BE137BED8C2E3CCE034 +:100810003F29F0E72CB1BFBE7D2223FE6C2CFDF1F9 +:100820004B987FFE4D999D0939336F6E94BFB4D1BB +:10083000D119BA338A4F81DFEE45BE75EB798780D7 +:10084000317F08FE8E217F6896336E53DEE1B00E55 +:10085000F77C80FB983EB8F7EFD7C4A60F407C1E0C +:10086000E2DD0CA75B4DF031E72702BBAA8CCF0776 +:10087000E9D76C6DCBDD8F79350DECCB7100A7D747 +:10088000F011BC17AFFC94D220AE42CE37E3236701 +:1008900036A09EEC069580FA66E382DB3763FB3C6C +:1008A000D80188DFFEF980FB6FCFE6291FFB63D4F8 +:1008B0000DE8D76EB417A6605E30B6BDD0BD72C667 +:1008C000DC98F6C282BACC3C9C5795D15EE8DE52E9 +:1008D000F9580EDE477B017EBA0BEB0CF602ABCC6F +:1008E000B9047CB8FC8D1B971BB33E6F7E9E3AB457 +:1008F000306A3DEEAC7A165DC7F8C77CC55308EF89 +:1009000057F59E43C2BF07F6D83E7B8CBA45FD7BA8 +:1009100053FC7C3FBF7E8EC860CF13D1EBA7D7DBE3 +:10092000956AB4FBF4B897DE6F4A218F73B4652AD9 +:10093000ABF1394B987A89711BF5384756F665A2A9 +:100940005E5866BDFED17F5A647A1EC3FF639897D6 +:100950008C4F3BBBCF035D4EFAD55C8443C9D9A015 +:1009600086F910E71C0BD94FCE344676CE60FDAD2C +:10097000C1F66B6BE2F2A775058F979765DBA81D33 +:10098000AF4A5B51FE4CBF30D4827223A04A4FE283 +:100990007CE3958F3E7C0AF535D801188709B07A3B +:1009A000DA5F9D600F507CA27D0E8C9C8D71982625 +:1009B0007B26C5D3337E9AE8C5AF05DB305EEEF407 +:1009C000F17D50D57EED5E3C2F637EC9380B83E709 +:1009D000F3025CEF2FC6F80D8EBBE8EC6E8CFF5C6B +:1009E000EBE7F20BFD38F4B396D4DD3DE961F92F66 +:1009F00089DB04DB9273299E2453FCC0141F7216FA +:100A0000CFA2F8905E271128E6E7F7B0B4043A7F4A +:100A1000C21CDF31C773CCF11E737CA7BE90EB7193 +:100A2000DDBEFA5AA1D1BEBA0BF71E0C47790B2ACC +:100A30000AF8BADDCED23B2646C75FAC0CE32F776F +:100A4000159AE28C83945B61902B2770217B5FB6B3 +:100A5000A3BFBB5CA9A5F89E99EE1F10F2ABB930FD +:100A6000C150D7116E5823DE8FD310CFCBC73A8237 +:100A700071197DE30C963FB6E42BF717723F6323A1 +:100A80005E994FA57D04B30B3C06BA65F5C3D989C1 +:100A9000E8BCAEE9BBFA7CF4F13FEF3C3608780FD6 +:100AA000964F369616B91CF0FD4F00C7BC3E1A0C87 +:100AB000ECA8F8B41E3FD7DFABC1BC410EDA9316E9 +:100AC000CA1FE8F7A3E2D836A4DBF8345509C4906E +:100AD00097E1C2DEB829E531F5EF308B4A72A14EBD +:100AE000E46BF4F16CCCDB487C80B4ADCF4B8A1165 +:100AF00037673E97134866C50689613C2881291DE2 +:100B0000187F76B4D9A9CDB4EA0363A3EA871CC5DC +:100B1000B30E609C4DE70B73DEC621A5CDC261EB21 +:100B20003A8CF92B737ECA6C57EBF1751B7C04E78A +:100B3000F507C4075F6F501ADC7A9FA4F57C41D794 +:100B4000ABD3D59C9CAF7AB1FEA4254EDD5C0BF3F4 +:100B5000D21E7351FCC28D73439884E017E5E463A1 +:100B6000FEA750FE5E28E4E7D1B458783DCABED453 +:100B70003FA544EF5BB850C8EDE1A70A651E27B159 +:100B8000B110EE93621353882FF4FA93C3A9DCBE1D +:100B90009C5F7263E87668FF2F51277955C9D37A35 +:100BA000BE7F48593EA3D20F6E0FF27AB4C357F6F8 +:100BB0009EA7B207FD4EBD5EF7AA4EA39F794D9644 +:100BC000DDD0BEC8CF34B5938ACC7564AA8BEAC891 +:100BD00052451D9998BF994F7ED8C0F31A3F16F51C +:100BE000FECF8AFDB2FF5BD4ED758AFDB2CF89FDE1 +:100BF000B23ADCD7DB558A4F9F9A0D365D765F5C43 +:100C00007063E937BCC8C7938B2C7A7E660FEAA95C +:100C1000BEFD15039F0BB6B0D29837BB3660CC9B98 +:100C20002DA936E6CDFE94A34C29C27CCBE4D54D4C +:100C3000783E41D52689CE27D8F8F0271F3E85F685 +:100C400062313F7FC7FC9D2362FF85BE7F43BF5F4C +:100C500056C4E9C3BD27D58E75F8559BAA66613C7D +:100C60009D79A60ECA7E9B8D317858B7BBC963C7E4 +:100C70007320AA424B1D38CE8D9B619C84C18F731B +:100C8000DFB8CB286EDD1BF7D7AEBC1EDF3FA2C797 +:100C9000FD59D6F565F0FC8888FB2FFBF984C7D099 +:100CA0003F7AAA50A94278FC5BA1B200AFCBC47CCA +:100CB000A0BD28BA0D3F2F2519CF9D585634407C32 +:100CC0005D9A6189E93FAE2CE27216F4516D118E86 +:100CD000EBEA8D7BD5E178CCD541FBEBEE2EE2F251 +:100CE000A9F94DB61AC769FE395BFD5C0CBBFBD692 +:100CF000228B3EDE57693CAFAEDF02B7F0F18DE3E9 +:100D000049CEAA5108E753585F1663BCBB8B1CFA47 +:100D10007877D2FB69BDF3BB3B7A7E7DFB663C896D +:100D2000C8B4EE1AD5DA03F4C31E96A82EDDDDE5AD +:100D3000995B88ED5963A88EE548C5C0E76BFEBD99 +:100D4000F6D11CA9F8D9BFE43E9AE78A3206B58FDE +:100D5000C6BD80A9B1F0FE7341977B8A73864606B3 +:100D6000C09363CDC130DA19BD6D9BCA30EFE7582F +:100D7000F32ADD5F1F17A889B5CF392CE8B4A56227 +:100D800065005344ADE9B30CE736FC3E57DD57141C +:100D9000E52F3BBCDC5FFA64ECB9BDA89A16545849 +:100DA0006C9614B2B77D16306D73D756495E993183 +:100DB0007FFD03332E87E78BD2C0BF8B5A77D1EAF2 +:100DC0009FEE057665C515479A53A0DFCE7C358C1E +:100DD000E3977AE57DD85E14C8A67AF7F5498CECDE +:100DE000BC53E31CE48F98E77D42CC1BE47293ED87 +:100DF00073C8E516939C6C4D1FDF84F31F5FCE22F2 +:100E0000286133BD67CB301F38294F3D817C96E97F +:100E1000658A7332DD5758543EC73CAE6B1AD7B75C +:100E2000E32369F7637CF9B0EEEF977E6E7FFF6C8A +:100E3000D100FEFE29911F68FD8E33665EE4D4CAA0 +:100E400085B1F3030FD7AD40BE3FF51DA3BF7F6A49 +:100E50004B750DEEEF3B25F203A766D60D981FD01C +:100E6000D70972C8310DE5506F7E40D8ED22CE3DD6 +:100E70003F4F89C3E7E0CFC74FCBA37DE86EBC32BD +:100E8000CD733DED4366B1F7C7B2473D0AFA39FA73 +:100E90007EF6297E3505C7D1F7C98E47D1368CF647 +:100EA00075DF1A8B9E478BF9FDE579D3DEBCA695DD +:100EB000F64F0F326E3FD87EB2BF93D7E3D8789DFE +:100EC000615C6AB917F355E727BA48BFB7E1FFA2DB +:100ED000F46A7A919A376D78F438A6F354E5C17DB7 +:100EE000375EF89BA8AF506F75335689F2E6DB4941 +:100EF000F514F79821E066BECE9A26F0CA3C290880 +:100F0000CFF4A2C04CC2E3F39D329DFB2AEEB3ACFA +:100F1000C1F99FCF38026FD3BEFA7249E675798C5A +:100F2000F8E28A2C0FE969DDFEAA9DC6E5A6934585 +:100F3000C63A609DCDCADE841CE8F7EEA3B66C7C91 +:100F4000ED0789CC8EF30E64819C8375947BD5D19B +:100F500003C9473C89C88AFB1E58C862F5D2359937 +:100F60005F350BDEBF881F1F3D371CEDF11F3CC6F0 +:100F7000F355573CB6D2B5226AFC87A709B999C682 +:100F8000E75FA358827206CEE72CE5A5AA64AB4FB3 +:100F90006198473E7F6C09C609C17E1B47ED4FA88B +:100FA0001D96AD3998E77ED7FBF131EC7FC5376FE1 +:100FB000BC8CE85FC0E386B539CF909D9FA7DE81EA +:100FC000F80F177F92386622D9F19B91FE6FB0B06F +:100FD000402C3B6683C0DBD54AFD754867572B4ED6 +:100FE00086FBD5C2654E82FB0F4A2C32DA95F3910F +:100FF000E6319EF3A88DE2CD008F9BF1F9219F9BF6 +:10100000CE892E577E6AC3F69F2659D8E503E8E3BA +:10101000CF0DD7E24F86233FBE8BF41763FEB56238 +:10102000FE3A3F01DCCB695E0AAF1FE98FAEFE5886 +:10103000A87C17E1D496A9AEA6F3103D0B06751E49 +:10104000E2FC1F06A976CFF9FDFA112C46FDD76107 +:10105000C127E6FB3F9CC6FD821BA7F17ACB2B1E66 +:101060003B776836F2F55ABB07F1FA5461E0C7D313 +:10107000A2FDAEBFB21C99292D27FC85E7C0DCF983 +:1010800041A089D89E37D646F8D3CAC5F91E773114 +:101090004F7312BD456DD75A0BF1993BA1A31A8D21 +:1010A000665B61FDB16BF1BD3289F6F347ED7319F3 +:1010B000B08E2C22F2592DB8EF0C6CF9F03A493F62 +:1010C0006F8B5940B6852B6CC2BEFFE031652CF0AA +:1010D000BDA8CF3CFEA2F571AC6B3966E5EDF08B97 +:1010E000D6514D400791517C1EED0F587C8D325EDC +:1010F0009FDC8C7906758DC55709ED9AD03D5E0C45 +:1011000071AD58E764E82ABC77EF15642F7EE2657D +:1011100074AEEC9254CE37756116B466F4F9B7EF3D +:10112000A4B3A09E3FC5FD737EA1671EC4FD6B30B6 +:10113000EF2F6DF8BA7637BC1700BF17E36AC37C90 +:101140003CBF191FB6F9820CFD5D5E1FD9D26861E4 +:101150000FE238D28666F4CF9D22FF11AFD492FF02 +:10116000380CE853C68879C466D8BFA63295E837EC +:10117000B91238231BAF46FF38F712FBD8965C3FF5 +:101180003C09F9E5DC34A35FDC5F7C5DBFE2393705 +:10119000889F2E916FDD01763BAEF7E760B7E37570 +:1011A00017D8ED781FCFA5C62BEE63C3EB1EB0DBBF +:1011B000F18AFBD8F08AFBD8F08AFBD8F03DDCC777 +:1011C0008657DCC746FB0E4BB4D050844F593CC306 +:1011D000FC508B9DD39996EEA03AF75009A37C7EE4 +:1011E00038DDB1B509E375168E272D893F0F27AA83 +:1011F0005FA176C64499D7C5B351B87F709D65A2EB +:101200008CF6539B43A63AFC534D36DA9F7062AE80 +:10121000E56DCCBB308BD527817DF3CBCF6E25F828 +:10122000D72ACC8AF2A109CF0B4579FC2113E71705 +:1012300084253C57AE3991097ABC2EA880CC7E1FFC +:10124000BF45F47A4045BF78BA536FEF55F179ED59 +:101250001A8BE8FFAB20D26FABDE5F3BF404FAAF32 +:10126000EB4CED6EABFEFE686A1FEBFDDEC81A05A7 +:10127000E93D537F9E7A03B62371FAFB7FBC01FBE5 +:10128000135CA8EEEDD413389F13E97A7FB986DAA0 +:10129000BD7573D7ABD8FFC470DE7FCB9E834F6222 +:1012A0009DC95F7BBC6655A338BEB688B1A7932E97 +:1012B000A6AF77A74BC678A86231C443F5F8BBD573 +:1012C000BDFC72DA7FD6E424B91849F7D5A0DEEE6A +:1012D0002F2E1A15AFA7B8E88FA6EBF5CCA6F827E6 +:1012E00070168E5B8DF1401F7D558DDE9FC62CF5EF +:1012F00021AC530F9C4994D18E74A445C5EF840C46 +:1013000018285ED85CCFE38361D54EE777E875FD9A +:101310008E6251D72FE2857A5D83A3F86143DEC0E8 +:101320001C2F64D2CD948F0EAC34C603E7AB9F2F35 +:101330005EB89C85EC9723FD2B16AA8B58EE91DFA7 +:10134000B90CED6836819FCB28BF14ECADEB9769E3 +:101350001819CF9BAA16EDF65BDE7B1BFB079BE201 +:1013600064DC84BFECE6B2772E23D32D81617C6BE5 +:1013700059093F9731EF43DF4B32CA53AFD5C7CD41 +:10138000B4C03751FE06562651DEE4FA3B2CF4DD9C +:101390005ACDCD104E60570A7AEF7A1CE94B725B3A +:1013A0000CEDDC513ABD5DFB38D2FFF464BD1DFF8E +:1013B00004F25B99437F3F8FDA4B558B789EF5841F +:1013C00002AAE458B94EDF2FD7E0F36BC7F48E477B +:1013D000F43DDDADB7AFB9019FB7F58E5747DFFBE1 +:1013E0000D9E6844ED194F203F9755097DA5BDF727 +:1013F000388EDFB25C1F7F7C10EB509759F5F759A0 +:1014000010C7AF63BD6D05F5E25B82FFBB8B3B6B25 +:10141000305E755DEFF34E5AEF72D17EBD587D029E +:10142000F9E95F7E7D7FE7EF99DBD7B3F0CCCB7333 +:10143000FBF8C22CAF7E55CAE5887FF54F91CCD919 +:10144000F2FA27E95C378C07F07C56EAA200D2B7A3 +:101450004BF20167B08037302B565DFCCA123ECE8E +:10146000E962635EACC594170B88FC547FE31C2AC9 +:10147000E5719DB6F2D87EECA4BCF28F8A319EC095 +:10148000CE4A389E470550823DDB98A3FE19EF03F4 +:10149000EB56903DC7980FEF835FACA19D390FC00D +:1014A0008979D8C6D247284E7FA2D06E380744CF5C +:1014B000736E7428241FDFC3BA0E908FCBCA959920 +:1014C00058CF78E308896DA57AB204CA37D8463A6E +:1014D0009E24B92EF29EFA391CF32EB12FC2BC2FD6 +:1014E000E58F62BD9F14B7DB513E6B4C9B59914B0E +:1014F000F23A8CF5C756F706CA033B4BED9447D03A +:10150000F3CF75E2DC6F3DEF3BFDC250AEDFB3F4CD +:10151000B8EEC0F9DFBA35BB03641F7448CC9A71CA +:10152000713EB836A0A5DF85F66F4522ED17A85E9F +:10153000F1328D7F6414A3F87BFCA27ADA1F640376 +:10154000FB50C17A17912FD6F7798FBEF035DA3775 +:10155000AAEAF5E7D29C2128279DADE067D1801C3F +:101560002E7ABEB8CA24EF6B8BF939730CECF87184 +:1015700049F89D81F73DDF3F9D9FEF77B283D7F319 +:10158000179418F3C7EBED3CCED79669A4ABEF4F99 +:10159000E7FEEA83D3453CB1F4C7D508974F98D509 +:1015A000877931F6283F0F0E632CB4DFCA7C0E73A7 +:1015B000D662B2EB1E1D0D4B045BDBB6E62D8A2B0B +:1015C0005A36F3F73E9CCCEAD16FB1D9781B2E1A6C +:1015D000E6FFA7F8D53925583FB6E61DEADFACF19E +:1015E000FAEFFEE237D525BABEE7F19B65DE033D93 +:1015F000B8AFECBF1CC731ED7B0DC8BCBE645DB19C +:10160000ACDB17741E2110AE1DEDC5F4A2C00A9C00 +:10161000379BD829E33C7479132AFD6A0DCA1BA6AF +:10162000C4CE4BEB7CDF62CA4B07BCFCFD43BFB8AA +:10163000AB06FF3D88FEF2109BCA7AF306B795E031 +:10164000BC52F4BC81723BB6FBF4282CC86FD0A30B +:1016500037ACFE6FA0477BED76ED580DCAD52FDA7B +:10166000FC81AEFE9DE8AA92C7CFBE68F32F9AA672 +:10167000ECC3F9FFADBF73D5B4C06BF89DFB2C4A2A +:1016800075024FEEF92CC63C5F4FC90079BE4BC5C1 +:101690001FFE27DE3070BCC15AFACF196FB0E39E2F +:1016A000AA3CE2A3CB4A918F8A391FFDABCB3D58B0 +:1016B0006F6E29F14367307ECC5FDFDF4F2F52CB57 +:1016C0004B490FAAD63D403FF795B9B83D13E2F01C +:1016D000ED8B67C0FCFD8678C613ABFF06F10C5896 +:1016E000EF02C26F85F8FE171F7F37137C156E4F10 +:1016F000FC0BD2671BADAF93AFEF1FF0FDCD442FB6 +:10170000CF727AE9830FB793A2E073C3EA7F0C7CB0 +:101710009E25F8ECE0F3FB02E0730FC1D3C7E77B33 +:1017200029FFFAAD629E0F81F75EA675E6723A78E0 +:101730005BD8D7E077CFB85CEEF3BBB7E42BBF2E16 +:10174000E579E4C3A586FA4F258CED01FCE2EED2E3 +:10175000D87EF19B38DF2F9A5FEC2EE170EBCBBB8C +:1017600004F979B7ACFAEA2BE13BEF00BC31DED6E5 +:10177000BE4622FBE27C1AA3F300747BE34412AF63 +:10178000DFBB787F584508E7ED2CE4E78CE8E703FA +:10179000D8A4E54343F2C5707D7588ECC07D482B25 +:1017A000144B0B9E133843FB88F69F391427FD3BDF +:1017B0005BA3BD3EFB1DE847839FFB25ACBF5CEDF3 +:1017C000A1FD27FA3E337DFFC78A50EA01DC77DBB3 +:1017D0000EF4900ADF995F61DC0F62B6376CA6B633 +:1017E000F9DF314D9E6E3C8F0AE04FF6CFF9365E41 +:1017F0001FD76E637BB0FE43DD2005C164624F6B73 +:10180000163A877325C0C90AED191D19544FEE48C1 +:10181000E3E79DE9FFCE29D041079DE7744C62784C +:101820009F897D65FAF9DE7173F9B97A11583F9E87 +:10183000DFA39F335125E8448767DCFDC90497F394 +:1018400000178671663FB747E7ADE1F9E096E537E7 +:1018500086918D6A8A3F5A17AB2E65B1D7784EBAFA +:10186000399E613E67DCC60243F1FC8AF9C5651A00 +:10187000DAAB4E51AF19CF143AD722A23DC5CFB53E +:10188000A8B01BCE11317F37DE44A74E53DCC14CCC +:10189000A766BCCC32E1E5691B3FC7B1A55BF26925 +:1018A00070BB65D3CA36DCA7AF6DB2F2BA79A6D0E9 +:1018B000B94F2D60F1D27E74982CC6EB970878EA68 +:1018C00078C183BCEE49413921F6A55BEBEFC5FD3C +:1018D000A54BC5BEF4EB5827ED33B89E45ECE80C9C +:1018E000DC80217209E3DDB2833B071E86F3A8ABDF +:1018F000E6E76458710D9827D864257E6DF1EEA156 +:101900007FEF2B34C29E743A8BFB13B1ECD9DEB857 +:101910000240E274541CFF7FE257FFB5F8555E09A0 +:101920003F8FAA252EE429CCE0E74DE03E87BC128C +:10193000599C37218FEA003E397CDF071ACA617D46 +:10194000BF03FCACBDCC788EC2E6E903F87FC525A9 +:101950008C7F2723928E7595EF8873FBCCF8FD253D +:101960003A0E5C0F3D399DF2EF60FFE6A2DCE3F634 +:10197000EFEC82C053D3A91E9DEF7BD6E34827FD31 +:10198000EA0FF17E09FEBB39B9B43F2788FB77E641 +:101990002758F65BE4BEEF33731DFB7FD3BCD5ED58 +:1019A000C51C1EE1385EDF1ACE60D5CFC5C0C74367 +:1019B000E55C1F86B363E34B7F0E76C6EB882FF49E +:1019C000878670A238E330C6078E0F441F3A1E93F5 +:1019D000672AEF10DEF57AF002F524B69BD5C0DB5E +:1019E000747EDB06496E44FD1A925FC5FDF5F3BEB9 +:1019F0002579108E7FEB3CDCBAE28C41E5E1962143 +:101A00009DE5F52FBFFED2EBFF0742E7FBCB008041 +:101A1000000000001F8B080000000000000BED7D9F +:101A20000B7855D595F03EF79CFBC8931B08F42224 +:101A3000014F0268D4602FEF04089E9B9B272470FF +:101A400041C0280F4F08626CD1466514289D9C90B8 +:101A5000104244C119ABAD75F4120CFE7FC7AFA69E +:101A6000FDAD15E9E38268A9851A6DA8B1551A90F4 +:101A70005AFA8F9DC10A63EBE8386BADBDCFBDE765 +:101A8000DCDCCBCBD8A1DF4CF8F4649FFD5A7BEDB6 +:101A9000B5D65EAF7D72D4C9189B01FF1993EBB424 +:101AA00002C63AB07C19C31F8D4179E9504B390702 +:101AB0009AF6F2F65768FF1636C63156CF447FD1F4 +:101AC000FE37126F7F34302C6CA4337693A887B224 +:101AD0008E65B33F634A6E4081FE0D9259DEA9299F +:101AE000D6F932776A30DF09A77DFC6562BC42ED2A +:101AF000131A3F149DFF93B006E5FE38F897335E46 +:101B00002ED5FE42EDEB9859FF171DD77B5C32CBEB +:101B1000E375EC7FC46596C7D6E1FC0FE4F2F1678C +:101B2000978C0F1B97203C9FF7F817DAFEED592A88 +:101B300063C3011F0DDF0D7E017E5DD6B853D6A1B4 +:101B4000DF5167E86D960D64F6A0A476419F42D6FA +:101B50002D3399C076C95360084D621D30D7AA1243 +:101B6000F8DF54C063BA83CF63F8C31AD0D9D2D98F +:101B7000269DD68671DE6474F79B7D773C8EEB8E56 +:101B8000C26DDCB1C206B731BE4E9B15833BB81F98 +:101B9000DAC3784BEFB8CD87702ECD33D73783E6D5 +:101BA00069CB32FBF59F75DE57F79512BE9746E776 +:101BB000A9A2F64B53CDF1168471DE183E97D07E64 +:101BC000C4E01A6DC3A7BF6409E133E40D6F1E01C1 +:101BD000F809F998DF007CDED4D02CEB05163E32F4 +:101BE000822AF1912F5A0EDBF9A880F868B0E11A29 +:101BF0003D23B455837D62F9DD6A68C2E7B1EE88A2 +:101C0000F30BB8EE6D12ADDBA4A3655E0BBD7B607C +:101C1000DDAA59BEB2AE217D30E6ED29A379DF03FE +:101C20007CB3183F3163649D967EE1E3B5A4E7B9C8 +:101C300070BF566A921686FE9FE2CF75B1E7DBB39E +:101C400024E217C0E7FF237C16023E33F03D233E1B +:101C5000786672E8071AD4335577EC07B85C9A8730 +:101C600075000EAAA687F6507BB6C387F8070068F2 +:101C70009CB6D798827C06BCE577CC84B293D576A7 +:101C8000170C9CF7E11207B56F61ACB21BE09AB27A +:101C900029B43A6469E72DE370658AE7918CFEE523 +:101CA000C361FE77A06A138CDFB20D98179EC71A26 +:101CB000A4B0044D8EE578E715427D4FAEC3BF0951 +:101CC000A6EF59EF1EBD16CA7DB9E97E84AE2F6B13 +:101CD000478617E639E697059DDE761CF9FA4846F1 +:101CE000949F0C3C5F7A245EFE9556D489FCF4A642 +:101CF000CACBDF2AFDF271A300E98D79D908C003B0 +:101D0000F6005E75A4CDF2B8010E57398813ECEBDE +:101D100065BA0BEADD580F4B5CB079D7D7AFA7D1C6 +:101D20006B5F1E378DB15AFC5DC5FE8AD1EFA1797C +:101D3000954F257A32E7B4D8B8AED696975A108F19 +:101D40003E9995206FF9787B1FEB6FFED481E343BA +:101D5000399F2109EEFB14F65C1265FCF914969884 +:101D6000CE4295B908573EF377C07C0B74E789687B +:101D70003D7F6C53A60938111E79636521FC9ADA00 +:101D8000606F37371FCA9E58794E6B7D0903BCCEF2 +:101D9000D1A0DB44C60EB5D647EA619E43856EAF3F +:101DA000049876E528B6F67359772BE29DA9070FBC +:101DB000C880971562BE16EF82B7719C95F95002E4 +:101DC000F88F7C359031351BF94DF63B441B8789E4 +:101DD0000F46ED9C8E6C92D37EDCEF9617CC7D9BEC +:101DE000DE897C20A749B672C065D64FE8443E3CE8 +:101DF0001295ABE3566279F158936F323A91AFAED8 +:101E00004B33CBAE95C847EF284E4127C33B914E8D +:101E1000DACDF18CED245FDE6066BD83EA4351F9D3 +:101E200057BE13CB4BBC021EE31F481EB668FC3CDA +:101E3000B96A5FA4DFB888F6C09F570690DF425C9E +:101E4000DEC5D7CFE80DB76422BD007EC6AB03F96F +:101E50006D4340263E0A69EFCBC837A58D8033D845 +:101E6000BF60ADD43B15695C61A391EFDB9A60ED77 +:101E7000E3A1FC62914BCD40B91E2AD712C88D1F39 +:101E80000438FFCE08A467BF8BB89BCC2623DDB5F2 +:101E900035AD13FD530CDCDFFA71AE704A6EF27192 +:101EA0005E0D3A48CEF448DE45FC7C96199ECF8103 +:101EB00007C7A617B158BBA783FC5C6E9EAC550440 +:101EC00060DE79207E19EC61F3EC47432530CF8941 +:101ED00022A7DF8DEB30B4D791CF160A1ADAEED2F3 +:101EE000D87A941B456EEF2694DD72C14BEBA0AC03 +:101EF0008C027EC57225A76F1DFE7D9A87E32A316D +:101F0000FA073816ACB3F383C22CF40DF53705325B +:101F1000B2DFBD060A57B3AB71FDF739432B508EC4 +:101F2000B5E785EEB0CAB3A7825C8E85C57AF7CFD8 +:101F3000FE762DE2E703E6F0A3FCD89D1A2279F69F +:101F4000BB4CC63A27E23E32D53B02F99AAF43CAB0 +:101F50005FC2B0FD6397C31246021CEB7ED3533AB7 +:101F600019DE7F83F73B792D6B64F85EE1657818A5 +:101F7000C6446C7794DADD1BC8A379D9E37E8F075A +:101F8000691F9AE37EA7B36E273E1D693F1CAD27EC +:101F900090D3E693AD71BE17C503F2129C84B86E60 +:101FA00089E98E4F71FD42FE039D6EC4FD01A94F6C +:101FB000E7C88C93A76CF43629A0121CF17407FDB6 +:101FC0005AA8DF22B31F73EA167D7D43E09170F3B8 +:101FD000383A8FB652BB74388FB26DE7D17D810429 +:101FE000E7D19555DAFDFC3D2F43FF0793F4FFC77A +:101FF00044FDA1FDC3F4DEA313BEAAA66B8F6079D6 +:10200000CA18539E4043109CD70D33CBA93737E4F1 +:1020100058E5CFD427505EDCA84BA23EFF09E4EF81 +:102020002325A6BCF9D90AAC8FCA23B6F809945F58 +:102030005179C4E6DE8CF551F9C3EA1F47F91595CD +:102040003F2CF804CA8FC002598C77EC711CBF6D0D +:102050009939FE15E100EA250EB33F0BE3F8C9F408 +:10206000C8DE59DD2BF09CBB295ADFFDB866B133C1 +:102070007E354B7F02CF45B66D387BC7E483BC818C +:10208000FC6ECA01937E4CFDF0D517C3BA01ED1664 +:10209000566A11EBBE44F5CC7EAEF7C4F4CBDF73C9 +:1020A000FD7BF0F5C7D768FE024E6F9FC3F86F5BEC +:1020B000C737F52978DF4FF427DE5F6AF61CC07753 +:1020C0009AE09BC2E1BB88FE1FD3BAFDFC9CFA2BB1 +:1020D000C09B5A62B1032E417C8EB9C4E19B5482ED +:1020E000FB5DCDF7FB698D99727C2AC13D800ECED8 +:1020F0009BFE8B69DC52BE6ECBB89A75BE64F63A15 +:10210000B42BB3B78BF24F25C125C63D4BFF1A7BCD +:10211000BB68FF5089853E0781CF6FB2EEEFE720A5 +:102120004756D3F8E3F8F8D7C7F0789BF5FDFFFAE8 +:10213000CDCE49E7DB899E1A393D9D87BEFD75C42A +:10214000EF56A95BCF243F9161E2FD1B380EBCEF37 +:1021500077C1FB88D88F5D45A16FE17B2CFA2659AA +:10216000EC1363E14E842F669FC04005D6F3FE86D4 +:102170009DD6F3FE7B2537ED34804EE4206FFFD4EF +:10218000FE97EB70FDF165D04BFE2FED7F36E82515 +:1021900013482FF936CE7FAE7101FE6EC2C3F39C99 +:1021A0006E12D43F4BE33ECDEBDB5D5C8F7D63D99C +:1021B00007A4C76977AA0ED4E3CC73FD27255C9FDB +:1021C000057DA432917FE127C29F06E3FE84E6ED00 +:1021D000E6F8EF0DC919A86F46F51616213B28A69B +:1021E00057AD223A8AE955B75279B6D8E7D74BBEF0 +:1021F0005427E07D85E341ACE7DCED7B080E1F6FE3 +:102200009FA0BE97C6CBE170B2F48327D06E257A2B +:10221000E53FE31C505E89BFA900BF73717136E8CA +:102220002DFB5B255586725DBBB9CF77135FC4F478 +:1022300036CE87370ABAFF53C906DAC71B4F9BFC55 +:10224000BF97DA4F89DAA91B08FE37857FE26BC199 +:102250000D267C27093E95C3F7398C7F9AF0C33849 +:102260007E6A99E144BD0CEDCA2E36707F3F167E22 +:102270001CE8F71FD4CFC3E1AAD525D2DF43AB8E2C +:102280003991DE57F4B284FE2739E832FBCB41D2D4 +:10229000CB857DEBE77EA1F8F629C1283DA5507BD3 +:1022A0002F9FEFAB45A1B420BC9FA5BF161CC1F763 +:1022B000C983FA68A8540A77E4A27D935E560AE5BA +:1022C000050ED64F761F639BD1EFEBFEA1C23AFC01 +:1022D000D45A552C7E1DE0D25FA11DB9586CFA026C +:1022E00016F5AF38D05F63F1DF901DE80EDE9BFF7F +:1022F000904A7E97975AD04FE693C9AE08DCBF2A22 +:10230000520FE5D442B7D78DF3C83964E7BAEE036C +:10231000FB1365D4226E5F3AE01FEAD1A9EB18D90E +:102320006FF30C29ACC23C6ECDEE7FD1379E6A2193 +:10233000FB6E15F36A59F02CB4D7BBE2ECD7E6C9B3 +:10234000BA1FF174BCBDDE81F80854713BEC78FB18 +:10235000D874E4BF783BFA78723BDA40BBB92766A1 +:10236000473BD70EA21D1D0CDAEDE8D145A132DCAA +:102370004FA66824DFF6CF9EB190EC6543666E6889 +:10238000DFFF909289FE3E639BE24777C331A7B699 +:1023900082FC07604FCB63689B18FAB7E60BF8FB2B +:1023A0008B4E9522FCDADD63FC48EFFDCD6EC273E7 +:1023B000FF2D59E134182FD3F8B03505EA5F0E8FA1 +:1023C00042275BD4BE8EB7C3C17C32906EFAD96807 +:1023D000D681FBA078D97A7C3666FA0D7FCCDE9E5A +:1023E0009FEF3570BCFA701AC37D8FFC8C49EFE605 +:1023F000330A39201D2F60AA130BD733CD89F85F1C +:10240000CC742ADF00FC268DC5F9F20DA203E03B57 +:10241000F4DF6D98ACDF46F8788CD3077B40D98920 +:10242000F18AFE6D0F66209FED4EB5FB1BCCE75A7F +:10243000E16FF0A09D3F6150EDFCF5048F9013E734 +:1024400021579AF87E727E3D8DF6EF703A271B90E9 +:10245000CF7B841FF8812CEE3F7928C8E54AFC1316 +:10246000183E1BFB5FE83901E7E5F6A0DD8EDF8152 +:10247000E5F3382F1F2639F32C5F675B9099F2E75D +:102480009B41AE07A899E44F01513C8DEF2FFE7C94 +:1024900024E94FE0F8DAD312ED578ACA480EB95949 +:1024A00028C289C910EB611B47D8FBED3E5BBF9B7F +:1024B000037CFE1385FA3FE3FCC5A78042A19DBBC8 +:1024C0005A0A4BD06E7EBAF492A4C6DA1D413F542C +:1024D00002397A54C85168167180BEB23D13F600B5 +:1024E000FDDB8A7F08CAEB379AB4A3A8C31D69AA8B +:1024F000A4679FD248F2A3AF5D0E37C33CBF6862AA +:102500003DA5E3078E5BBB2C70F484451ECD2F7B6D +:10251000D2034291B5E4771E94D05FAFB955E4DFA2 +:102520009E0CEF0385C8AFAFC9AC0BE05DB2A8EA63 +:10253000E8098B7C881F17E66306B0EC1B41EEC7E9 +:102540007C31E08E5C07F0ACDA268571BC55DB8E01 +:1025500039D15FB9625D1DD3619F5C85C714DCCF43 +:10256000F28097D639BF50668605AE6F4ED37A8219 +:10257000DCBFF33AEDAF3FAA47FD12CB01A796E9C6 +:102580002D88F921CDB8C0D3C15DA48FF664319AEE +:102590003FE463848FA096EBEAC7388BCF4B7ED3A2 +:1025A000434195E6AD6BDD49F0A4CE7A9FE001DDB5 +:1025B00039E2183A10DF261FBC26F0DE26F09E0C0A +:1025C000CF7F0A727F9E599E5FA664209E5F5754FC +:1025D0008A7324E3EF85A5F6FD71FB2A6DE516ED00 +:1025E0006E07D2D3F15639EC96E87918F7ED34EC52 +:1025F0001BFAE9CD717A3258ADF57C36F76756A9EA +:102600004C7099FBB3C2E0FBB3C208105E569456FF +:10261000B946F2B85A37D036AB2FAC6388179776E5 +:102620004C4139966CBF80DFDCA516FDF122FCE73A +:10263000434A2D7AEDE7EDDF87F946D37C717AF6D0 +:102640005F2BBE60D2532FCAD582985C2D2BE5E755 +:1026500041FCD394AB167D92FC9A163856365C0436 +:102660001C269F209F3643D3E00EC9897C12427EF0 +:102670009D80FAD91F367F211BF98675A7C0308E41 +:1026800052CE37AE59592EA48BBAF6F7153CAF008F +:102690009F15844F2187279632F31C9A4374D1C02B +:1026A000E9E2BF3BAE03F02C23389771382FB5B861 +:1026B000D3ED35A146842FA4815C4A477FBC57ECFB +:1026C0003F1BCDFDDE1716DF3CD67A37433D70C188 +:1026D0001F3354D4036F2AEAD272D584F14D55B218 +:1026E000C537EB4B488FD1182B19C9CE19DF8C8F0A +:1026F0009F0E8C771A142F35F5EEF878677C5C9373 +:1027000025897F0E8C77BE588D7AE61CBFEC55D597 +:10271000583CD335EBDDB7D8B503E39D9FC07A04B1 +:102720003EB39965BD7DA3D5EE08C0D731D2E3EFA6 +:10273000E4CD993C2D864738073C6E98A7B50CE050 +:10274000477D39B793E2C6163CBA080F1788478A07 +:102750006F235E5AA5F026DC07A5D140795EC7BC81 +:10276000EAA3DED87E46C7CBBF47F341FD57EBD384 +:10277000990310B239FB2E5607E5D443294C063D88 +:10278000F6907A17EDF7A1F732548CF7BA7D967D63 +:1027900010B8544CF8E48176D25F611F3D7989F618 +:1027A00051ED2CC573F67CF76F5751E808CA150F29 +:1027B0009CD7CAA4D8FBBED11C9FEF5CC5C29DD2DA +:1027C000C07D047C6B6477E6B39D846FD6C8D03F30 +:1027D000D02A31F551FF40BA70A46D341C682FAE79 +:1027E0004C273BAAA5B191F0FD1AE0DBF072FEC2C6 +:1027F00038D559F8CBA40B268D387FBA88DF778C73 +:10280000E3AFCBBEA4F735097FEEBAA07D9D3B5365 +:102810001B5236DCBACF5A56D9542BDF1A222FC599 +:10282000A07D341631D69535508FBA4CE4A5C078CA +:1028300023B1FFA83226FC80DA282C5F7F396B4C4D +:1028400094F7E2ACE076CC3250C1C9AF62A4B2AE2C +:10285000296865ED787B04EE9771958A65A61E0C54 +:10286000235DD589F51FD9B2B30FDBCF074C621EAC +:1028700004BE7558F0E32FCBA5718BD61C3BAC5230 +:10288000B5F7288EE702E18F76EA327C89E382BED3 +:102890008AF175A6E86C21C8FBE56BA5B771DC5A17 +:1028A000238DA15D1BCBAB782A2EAF8297E7E788FB +:1028B0007AE3FB74FEC4E298FBE2CEB7373A6D715F +:1028C0004CE3D84A7B1C93E7DB98E7D99197FE65E8 +:1028D000A5A158E398EFD3F8479799F315EEB2C73F +:1028E000313FA1F14D3F35631F765AE3946049D1E2 +:1028F000F96AFA91FF5C36BD9EFB4DF585B83F72D3 +:10290000506A44FD080E184D227F8DB713ED69D033 +:10291000FFAFC7FABFF575821E727B9925FEF1B72E +:1029200006FF31D3BF6F1C5AA9155CFAF002BEBF77 +:1029300045F8AEE4F8FE1B80F7BB6509E20097108E +:102940007C2F117CD138C47F3B3C6F9459ECCFCFA6 +:102950007BBE1933B51338DFE7B08E536596FC8321 +:10296000F368FFEFD45EC44BE3EB6F2FF7723F9633 +:102970008813BF198DE365D6C7C5F528EE158B23DF +:102980005E3E3630CE0AFFE5BBB0BD19479C5D9E6A +:102990005B4F79D149E2981AD62BD6FE2AF5EF88FB +:1029A0009BCF25EA17955F536FD8F07335B5EF8944 +:1029B0006B5F2BD6B7B27CD22EC3820FB038A97D05 +:1029C000542EB1E9F5F6B8E3D47A6BDC714DF9F425 +:1029D0005D66FCBF1CF1336E403EC4FF487C04CAF8 +:1029E00085BD29E2E5261D8E9EA195944FBDF4E09C +:1029F00085FD5B526EA1FFBFC27CABCA2D79171754 +:102A0000DA3FCA8FE2DC37F32700BF77E03A6EAFD8 +:102A10005009FFF1F912A69D18EA676427CE646198 +:102A200019E31221BFCED00F1AE56B43AB277F5DB0 +:102A3000F47E44E52EFBFD88E65DA85FC4CEEFE79B +:102A4000EAED790EE536B8B7BFFC9CB9EE96724B4D +:102A50003EC3608FBFA6C28E976859E067E91DDF4D +:102A60001C6DBF7F11DA45718CE8FD8B9B68DE58C9 +:102A70007EC7ADBBECF91D6BA91CDBAFA6B8FDFA98 +:102A80009A0DAE8FCB9B082E97C87B73AD9292DCCC +:102A9000AFB891E48219D785B24D2E50F97380EB0F +:102AA000804947824FA3700EC8CFABDB857EA6C19D +:102AB0009EDF22175E42BA187CBCF3FB1D26DE9314 +:102AC000DDEFB85135CB5FA96F28F8ECF362FE5FFC +:102AD00079C2FCA38B5D07BF2FE28ABF2FC2D6D776 +:102AE000DBE5CF79C3773AB1FC39BFFE9F24973F2E +:102AF000FF89F2A725DDE1423CEB3EA68513D8C74E +:102B0000B757F0B854943FC57D94EBB727B6A7BF2D +:102B10005CC1FDD7A6BF3BE03AB5CA1A071D26EA3D +:102B2000BD15D1BC016F058EBB8EC33706E521C62E +:102B30007B98C234E0A945D78FCE41F85A7ECDC7E5 +:102B4000633EB0933362E3CD14E399F3EC5B9051B1 +:102B50006BCD6BC811F38CA9904CFFF4980AC4E7B5 +:102B600046BE0E79C81ABAE715B5AB8D87487EB553 +:102B7000394D3BFBB15D24CFA272E89B44178BDD3E +:102B800026FD877759FDC6653FDDC5CF5528621CF8 +:102B90002FD6EF1BF564E79DA3DF6413CFAD62BFB3 +:102BA0008CE87E4D41B8CFD5DF624747A4EC981D35 +:102BB000FDCC646D16E219ECE9E2F31907F014A4F8 +:102BC0007D596BB7472CF51515B6BCA4536B30AEC9 +:102BD000992C2F6961C5D9F39216C6E86161854DBC +:102BE000AF0F664C453FC94847C27B14BAD8D75887 +:102BF0007ED77768BFDA4CBE13E507B278FDF29F47 +:102C00003E532FE0BFB9C212BF30E32DACE06004E9 +:102C1000FD3C96FC22CD61F5FB048F3971BC15ADEE +:102C2000D2F9F14BBB187F5B741F6FAFE0FE681DDC +:102C3000FD8E378A498EDCDA4CE3D6AEE2F7C2E28B +:102C4000F9E65EE1A7BA3746C7F7D2385A34DF66ED +:102C50003DE20D5306DC9362E39BF77B02CED08FFF +:102C600030AED366482ACA577D5D1DC51559256308 +:102C7000E3619F0223F3B6A1E830E7BBBC92EF17F4 +:102C8000FC5A8AED7C20218D9198275E4771E76977 +:102C90001ACF5B995EDD2C0F5729AFA503E72F5A9A +:102CA000B4B305977DC3B2EFCA89F2597A309F0554 +:102CB0006132D8EBE346007F0BF8F05EC85A98E724 +:102CC000CD683E4B75D93DD67C96D067CB6731FD3C +:102CD0007F4B4B00AF16FACBAAE478CDAAE4788DEF +:102CE000C58119C56FAF60B573AEC2BC14BCB70562 +:102CF000AF7B0C7ECFED4C0E0B63FCBF79762AF9CF +:102D0000F1FAB318C5556143326BA6611E09FF493C +:102D1000195FCA30CFC50DEBC275605C3672250CE9 +:102D20002F2F1B124940CFBFC8D4993F1DFDFEC6AF +:102D300066067413D41FA4F8DCE5ABDE6FC07957C8 +:102D4000E86E1549E0C6066F19E571ADF13BEF81FC +:102D5000F7F37D32D3D09F5DED3CCEE3341EC2D37A +:102D6000FC525E36F1E266CA712B5E94B8F2BAB7D5 +:102D70009AB71CB0B477455232302EF85285C80746 +:102D800012F78A989C4E7470C6E708631CAA4761C4 +:102D9000FB158C63E832C515BB5AEF3C8C7CBBC27B +:102DA000A7F81DB0CEE03A89F2BF6EF4723C7DD830 +:102DB000646C39003A6CCAC83C8AC39CF17AC81B5F +:102DC000DFB6AC8BFCF6402F3D0AB43FB69EE7174A +:102DD00099F94F0B04BD98784CA9FB80F07206E37B +:102DE000E18897C22CCA839A07F850BD14E76F4553 +:102DF0003CA5B2C6C830186789CFC122163F34AC93 +:102E0000DF9647066353DE99426F6CF5849FD4F5D5 +:102E1000419E8F26576BE89F3F53C8F715CA7EA483 +:102E20007756CAE9D4C47F6A1C9DBAE3F2C3E2E9CB +:102E3000341EFFA711EF96FB5C5D0AF34790DE7A24 +:102E400065D22FA279570F3928EF8AB130DD63EAB6 +:102E50006243FD1D28372312C5096E107833F1CE69 +:102E600058E3E695E8E76ECCF4A3FF9F391A376381 +:102E70007ED48DE134CABFBB8975531ED472B49021 +:102E800061DE9B99D785E595CC4F4F8915D0FD9292 +:102E900025BA447CA1B348CD5580BFC865CE2C6B04 +:102EA0005E55D2BC2658F9BB9678C4D04A212F3D36 +:102EB000BA8FE779EAE2DE8F46F9415965A51E3DF2 +:102EC000C1B931BB481F5969C9BB50BC8D8CE2D315 +:102ED00045A151955363FD9F9AACE554C2F85F2C10 +:102EE000D446E37337EA79701E040F8E7F12CF83C6 +:102EF000E6C99A8AEDE3E5D5B1E4F9771AF2751FD0 +:102F0000CA2BCA232C203E1CACFCBBC99503F2EF94 +:102F1000A6565AF2EF8E3AF9BD32CA459EC906DE70 +:102F20004F5B7703D59BF7D3E2EFA5B1C7781916AE +:102F30006474801C6F311A69DD26DEE3F1C3C4BD01 +:102F4000B4A5BE97FBA46B07216FCD0BCADDC8B338 +:102F5000D187C1EF2FD7DCD987F13A83299447D89D +:102F600096CBEF2FCFC385E23AC6717D9055F1F332 +:102F70006A4B56A3CF0FF55B9C3C1F86E5EBECFA42 +:102F8000099671AB64332EB402F1097A1FE94BA69E +:102F9000BE6AB6AB17E7C26A712E3C3339740BE1D7 +:102FA0003F96DFBD1AE988A547C20E336EC77F285A +:102FB0000E64EA0F474635523E8D3BC97DEF3B2BF1 +:102FC000A3E7F99D34FE43E679AEDD85E35F37CCB8 +:102FD000BB08F9CC159459279E63F36F27B9FB1CE6 +:102FE000E68D824E335D6F0E8E80FD6EAA14F1A6C3 +:102FF000862C4417EBD1783E69A4B8D187E7DD96DB +:103000009189EF7DBF2AD63965CC2919C7DD028A9F +:10301000CEA689883F83F2D88CC5204BA00CE6FE53 +:10302000018CCB78500F28C27391B7F736401BD86C +:10303000876EA12F04AE00FA41FD6BBC3D1FC97C19 +:103040009AEDE2F3AD409467E0BAE3F3DCCC7CABFD +:103050003EC5C8F027807F7ED95A0FE56BE5ACF4FA +:10306000E039D9A60569BCF8BCB72D396C34C21556 +:103070009FD766E64D99F952E6B8FFA7D29ED7E6EC +:10308000F6F1730B9E9427F39D4A957F9742B3E721 +:10309000B799F935D89EF26B7218CFAFF13532EC93 +:1030A000E78632B60F89FCB3F8BC2A9043DFC57DB2 +:1030B000BF50BDA92DA6376DAE1B44BDE93CE4EF62 +:1030C000CF10DE04F2F7E7C41F31F97B08E91BE4F7 +:1030D000EF617C9AF2E5CF959B48BE6C91387D6E8E +:1030E00081FDF85E8279FA049F6CC94A4C57A704A7 +:1030F0001D374F0EFD1AE7D5B2F9BD8F4B058F80F6 +:103100008F3F5AE537E0E35F13E1017E5A519E5845 +:10311000F24FFF9DD69324FF34BEFFC5DE1F5640FD +:103120009EF0EF4B685215D989AAB0F751A8602BD1 +:10313000F31E6E9C1C17F5E792E3BD0E90AF000FD7 +:10314000EA0A56B93FAC8AEFEB3533F56155442FA7 +:10315000FC1EF0D600BF07CC221AE9034732F45A0E +:10316000E45F963FE91CE746B3C8B3D51B4224FF92 +:10317000179EA3FD266A7FCD4C55F8C187D27AB63B +:103180004ADA3752E558F95CEB4BABD2F2ABD0EFF1 +:10319000A187E83B0A5BF21DAA014BBB6FBA7E2DEB +:1031A000BEDF92BF89F6AF03084E02793ACF71EACB +:1031B000FE3C89F2849F9786C0D303965C02BA9E38 +:1031C00029F0033A08D5B3B7349FD5FFB1BA2AEA3C +:1031D0006F11F6EFB79FB4E6092CFED9D3AB0CCB39 +:1031E000F9867E94EF25A08BB22ACE3FB2FB4EDB50 +:1031F000F919DFAEA28ADF0F595225E206E23C5CE4 +:10320000ECE6F6153B04F059CEDB6B6696CCC5F5C3 +:10321000039A0CC9724E9AE722D558DEBB7DFC5E3C +:103220000AEBB58F63AEF35641A7E6BC40AF3770EB +:103230007AD56AF169D62F9619F783F4D8F105F09B +:103240002CE774C64E2481E7C984F0F4D9E1B9357E +:103250004AB7DAADB83E38AF1B70DCF612A0BB043B +:10326000F89D30B5640DD62BCC68CFCB3DAB3CBDC3 +:10327000BB2AB13CFDBB2ABB3E7B4F1597A7F75637 +:10328000911C493CEF2681B741FBAEC079EA6DF74E +:10329000E1AF09F8A6A3FFD9B46B81D5DC6EE36E6C +:1032A000E2CF8249E7E02FCECF378F69243BFB473F +:1032B000423FF99193299877033CE64F940FF462CB +:1032C00095A98F8447215E5E48A28F44DB25C9BB48 +:1032D000BF92ED48BB18BDA463D69134D24B4E7754 +:1032E000A6E1F9FFC28992847AC98F72768C4AA4CA +:1032F00097EC49A297EC15FAEB8BBF73919E517C2A +:1033000092EB25C52777C8A85FECABE272BBE84417 +:103310008FAC03DCC5A897C0387B845E82ED492F53 +:1033200039BD4346B88A4EF650BF6228A35E529418 +:10333000442F012864C4C3F3C51DBFC4FD8B5F6F58 +:10334000F514FD152BDD16F6F790FFC7ECD791BFEE +:10335000294DA7FDB6D3CFEC22D596375FD8CFE95C +:103360003DBE5D323A2B93ABDBFB615D5B59C60E14 +:10337000CAD7541A9FC0B2612894C7851FDE40BACD +:10338000B9773EC09085ED1A9FEAC7F3C5707BF10F +:10339000BB071FA6AEE076D05AE675CE8CC9235A7D +:1033A0003A80669488F15C1E6F0BD8798FA4651201 +:1033B0001ED7794D7FCF8ECA3CE87FEF95E3E85E5C +:1033C00050C98330109467F6CA546FFA870E8F6421 +:1033D00094BF0FFC3BAF06C69F2EC687F34EBB1BA8 +:1033E000DA2F2E747BD1EE2E97D3A9FD7DF9BCFD8B +:1033F0004CE35403968BFA5D2ADE3F63F246F90EE6 +:10340000F4EBA25E02EDEFFB61A8CC03F5A9470047 +:10341000121CEF2D17F93734F887FC3BB5B79BF03A +:103420009976C265F37BA482848B58F417575C9914 +:10343000C9CB8624924FE633DE4F913247F829AE4E +:10344000655FFC14F4AD336C633BAED13DBEE4C5A7 +:103450005D6C607FD30FF12F53B42173601FC739A8 +:1034600075B26BF65402AE619FF63CF4D0DC6B1182 +:10347000EF3B14F2FB1EDD9046FBB4F7416527FAE3 +:103480009B8E029F72FFEEFA5B905EF76630334EC2 +:103490001441BFDDDEE87DE7E1B76896F2D8572634 +:1034A000FE0ECFC3BDC3CDF60FF3FE66D9D8760BA3 +:1034B000E675EC1DC9CB35AF3CD365101DF72B6409 +:1034C00077AF7B273D91FCCC9FCBF9CE2CCF2BBC8B +:1034D00093D3F139FA81BC9F382741BF941A6E7F8C +:1034E000ED5D06204D443CE9D3E6009FECE9BBAB23 +:1034F0007D024C3565D6861E92A3C3FAD72692FB71 +:103500006573F8F914290E933D06363EB787997214 +:1035100000F35BE7317512DAFDDB67BFF0F36B6137 +:103520009E5F148D9F2427E06B7D4E5EDCBA5E9318 +:1035300057A25C7AEFF8A24472606B953ED7BE1E2C +:103540001E3F6DD9A110FEBF3CF7F49398F71E29DA +:10355000DE41FEBD3D7F74B04D406F7B2670FD1F88 +:103560006FF0C9D98302DF43D313D01DC077732214 +:10357000F8AE9ACB689CEA295A1DD6C7C3ABA21FE6 +:103580001CE00535CB8F7224E50FFFD083FECE3DC6 +:10359000FD0E72BA9C39D129230976F4E595A2DA99 +:1035A0007A5DF5311949AAD8FBE0660C0DEB1B6575 +:1035B0001BFF4DEF4BB59597370EB39597368C8A19 +:1035C000F123C37B42636D65B7EF6A5B39C026DBCD +:1035D000CA8BAA67DAC62BF3066DE50ADF5C5BFBD4 +:1035E0002AF57A5B796EFE525BFB1A7FBDAD3E54C5 +:1035F0003051C12B7E40975B115F69BD1AF1F9967E +:10360000BEBBBC481791E210D9DB47327A72D09F1B +:103610007D38C977E77E394716E73BA8462827E17A +:103620003CDF94156B1FC8EBB7F9EB5F98C3F5D47B +:10363000EFCF89F7D727BB27C7CFE7F3BD1F177F8A +:103640000ECFBFEA2E924B1D8BE430DEB76AC97FE6 +:103650003DBD1FD7B388FB193A72609DE994AF4115 +:10366000FCF5E2E21B4663DC2D355F1F86F2DF3C92 +:10367000BF83F961F60ED4A77AC36C2CDE3F837248 +:10368000BDB887162CE0EFAF10EF57E313CEED7205 +:103690000BBEE2CFE38067E24B6036B0D97FF6D253 +:1036A000F7FD1615707F50E9E97029DEB79EABED86 +:1036B0003BC0AF5573F9F38BE2FF9F9DE4DCDE372F +:1036C00067AA9D7F901FF69C587856F9FFDB26EE7F +:1036D0007F7FAEC9C322B0BEB79ABCF4FC75938F8E +:1036E000DEBFD6A4D2B3AD299F9E91263FD5FFB2AF +:1036F000A9909E079A347ABEDC5449CF834D216A43 +:10370000F74A532D3D0F35E9F4FE777318D1C7A55D +:10371000028F966FFA15422F3A24C2EB224CE59D98 +:10372000715293ADF21DF0FA5E22BC5EEC391229A3 +:10373000EE1E15E2E756423EF2CC35EF8D713D7933 +:103740009E4E323F0A9F0BFD77D931FF9D1B559A44 +:10375000A104A73477F8E0C1B957F871F666B1DA79 +:10376000EF717BAA55A2F3C63B91CBF347432524C7 +:10377000CF874F4C2CCF7307C8F33A3AB7D841F4F0 +:10378000AB62DA110AE3069C7F6A42BF883124F7F4 +:10379000AC78A078A68907CB7EE5CDBD88FD8A5F91 +:1037A000FFEC22ED2AC427DE53710E1D788E5CD10A +:1037B000FFB186BEA9E70B38BCDB8F2F1C82FA8ACB +:1037C0001B9D52A4AF80E25688FBCD843EF2685721 +:1037D000C3AC81E3FCB6B89BCEF5FBA27ACE3F9199 +:1037E0009E13DF0E7E0E101EF0DCB2E021811C283D +:1037F00049B4FE32F987FD9BA0FFDE7E467E33157D +:10380000756A80FF05857FC761EF4907E1F98C473D +:1038100022F9E85E7FB7077DDFCF7F8DB7336A245B +:10382000BADF90B67F8F8A7A6AA05F1F86DF232B6C +:103830008C5439F1FBA125B326FA532C7450A2D82D +:10384000CF49D454A3E70E39C586C6952F8BB597BB +:1038500071FFF362E55CBA97BD1CD7B5F0542353F2 +:103860000B84FF35319ED64816BF9BC2FCEDD37347 +:1038700049EF3C7019C675C6B3307D1F02CC8390EA +:10388000C59F20A787E8DE9E69A77F2469B7E17CF2 +:1038900003C66FD0282EC71C0E8ACB6D98ACDF896B +:1038A0007432206EE37DF92F129C69ED0E1641FDF6 +:1038B000C2C87411FEE2F7EB8B8555F7E03CBECF32 +:1038C0006CD7EF90ACDF11B842BD8EECA933604FDE +:1038D000E13D951685DF9F32DECA087711902C1FD7 +:1038E000F5B67BE5ABFDB8FF8FA4FD3DD947EBC036 +:1038F000DE42FB6B9B90C30FA01C86E73627B7B751 +:10390000DA9ADDDECE6CB4B7320D071C5C1FA68CD4 +:10391000093358E723426EB9D9F221A10967815FC3 +:10392000D827CEE8BEE778C9DE10E57497EEF81325 +:10393000DA7547E430FADDB64E7CAC7625E26FA24C +:1039400087C7459588BA001534AFC1B22DF7FB651E +:10395000A6BC8B7EDA76506630FE7BBFB89F9BE1BB +:1039600077D8F49D2185767DED3B8304B70B251137 +:10397000DAADD9AE30E6E9A828B700EE769F83F835 +:10398000AB55E5F2A1355DF37813ECEF16C4B73B08 +:10399000F9FC726EAB17FDDE3BD21DC4BFEDAAB2BF +:1039A0003517CAEDE90AFFEEABEAA84C94C7F2CE90 +:1039B0005C9EC7024D52284F2AB090F49D64F37468 +:1039C000887D37CBA905BA467CA6FA43B89E96F403 +:1039D0006C09F7C5ACFFF15C497C6F81FB95B70AB8 +:1039E000FD2935BF3B827E9DB691AB2723BA3CA013 +:1039F0000FBD0BEF3D05DDA43FA55FE6D213C1FB74 +:103A00007B31DE56A7BF12F1B935C3C10CC0DFD67A +:103A1000DC2471AFB95C8F6C51278588BE011FE330 +:103A2000A581EDF68B7DDEECDCE1C3FB6C5BC72F83 +:103A3000A17CB1ADA3B97CFE4A755F577301F2CD8D +:103A400057D89F906FB215DA3795F93D78CEB57992 +:103A5000152FFA05A664DFE30958E45C3C9F38475C +:103A60002EACADA37C82543F22BD4C3E44DF1B698B +:103A7000F383DCCDC57CA646AFF53B02A0777F84FF +:103A8000F2E35C74AA32DD83F885F1898E92ED5FF2 +:103A90003C3CE92899269DA57D965E9BE83B16F95E +:103AA000D50E1BDD38CF4137E782DF762EE6C4CE58 +:103AB00045DF21DF6A8C77DCCF78FD65D5EF75A116 +:103AC0005D1F5FFEACFCD9A2EC20B9DD32CE45F41F +:103AD00014DF7F6B2E87E7E8CF7F4FF3A1FB01F761 +:103AE0002DCBC3FD4D0F140E4D492497CBA6E8FEF8 +:103AF0006A8B9E9355DA4DE76D4A3523BA4C57438E +:103B0000DE71304E7AAF0C340AF8767CFCE763EA5B +:103B1000C5E351D9D1C842305E66AF4CF4893F1F2E +:103B2000831C1C22E4E096CBFF95615EC9F6B18A46 +:103B30009FE7B3BCE73FDB799239CBEE4FBA507FBA +:103B4000D1FC6A91DF90C252783E51758942793C2E +:103B50000E7ECE6AF0DF08212224B1FF2378C89FB1 +:103B6000CE49C6FD64D9CB18C9CD685E0B7E9706D9 +:103B7000C7D119E92378B116DB5DB686EB5B39ACAA +:103B80005FC278E0E598DD2323BD73F97986E538D7 +:103B900028AF07A6C1BC14C970D0B9F8F0E547A595 +:103BA00000BC7DA068F544C447FC3A1A06ACE3ECBF +:103BB0007830E11C6C3A35CFEF160F3F8F3538B8AF +:103BC0005350598EF37F96C91BF9796CB8BD785E56 +:103BD000B7288DCF60197A87C85F1AE7FFFC308558 +:103BE000FB47A57B98572A22FF673EEED33A96EA19 +:103BF00047FFE41045F7607DDA3885FE5E03E8DDB7 +:103C0000D331DE12B3CBD5749E47B78EF20D7F82CF +:103C1000E71AB4DBFFF1D9E5D1B3E738D73A7AC771 +:103C2000A5937FDD539F86F6F873BEBC4368DF9C87 +:103C3000F1F03C30B3DDFEB8EFA2B40939F76AB554 +:103C4000F0A3A77C2863FFEB7CAA82F976259E89E6 +:103C500024DF5BA4C4F18237847CBB427D95D3D939 +:103C60001AF37B666B48FEFF2643D06F83BE94FC3D +:103C7000CA42DF639AA67AA7C5F43CF3BCF4295E76 +:103C8000E3761C47E4610D58E7FEDB187EA785F953 +:103C90002CFED93C9C7F4834FF8EF8394EBF4B86B2 +:103CA000CF0E611FB7F84A287FE30CCAAC04F113AA +:103CB000F3097AEA4F514E4DEDB1CB97B47CBB7C02 +:103CC000697734523E987135F362BE08ABF6FBACAF +:103CD0007A32E8AB87AAC93EB5EB9D6B6A18FFFE46 +:103CE0007696AAA09F26E809308C4B28393AC3FD66 +:103CF00070F9FC67DD8FAE6AAEA7B4E5AF0CA15DCD +:103D0000B37DF697082F532A797EAAD90ECECBA37E +:103D1000D516FBC6E5E3FAFA797F67C9EBB8A0EFE1 +:103D20002C75CCBA857F67C9B792BEB3F41CD02579 +:103D3000F2CBFE0C3D0DF5AF0BFDCED22D35E23BA7 +:103D40003E293C1F45E9E3F107A54FA7BC1297EFB9 +:103D500014C56FAE137928F1FE22B7BB91E26D91C5 +:103D6000E2C6A5567FB189BF2E41D7BF2DD6295FA8 +:103D700028D9DF8930DB21C6705D6EE10FDD52BCD2 +:103D800081F0BFB0328BFC518AF047B94EE9941FE5 +:103D90001C9EA267D658F0EFCE31E8BC4BFB7BC629 +:103DA000EFC17FC4EFC1A76D622578EFBDE4E349A1 +:103DB00014A72A89A4109FCD3EEDA7EF5897C94FAD +:103DC000B7E741FDFE5E85F2F2F6CF4ECDC673ED4C +:103DD000835EAEDFA6EDBFEAD017A15CDC5B8F3E51 +:103DE00001903B00CBD081EB987DDAF199ECCCA926 +:103DF00068675AE225E6B83F683A48F4F16C530F19 +:103E00003DF73445E8D9D1D447CF42450BE27A0A91 +:103E10007B2876C9669C807A0B1C856F417F0B3DA1 +:103E200078A7E8D36B88FF7A6CEDD2F2FB6CEDC01B +:103E3000CE9D89F8557C1C9FAE6AFE7738E6F7B1B7 +:103E4000CD92FA3F4A5E2D473C0C82BC5A597356BC +:103E500079C5E3A9257DE27B63A6DC12FCF8976AAD +:103E6000957F37C9E44B115735CFE976FC15CED392 +:103E700096CC2F71F966E66F887B8CE6F7EAD7D788 +:103E80009CDC8DDFBD6B7BD3ACFF78B766A967C6C2 +:103E9000BFADC6FB28FBD0B8053DF4B7353F5E8DFE +:103EA000FE8625B5598A06F00531009B15BB476390 +:103EB000E63BC6E3ED780DB7878EE479C90FDF06E0 +:103EC0007BD29900CF2FD708BB4DB5FF3D90D424AE +:103ED000F7872262DC43026FED2E9EA790EC9EC80E +:103EE000D745FB64F7447E5523E2F5E7B817F21D8A +:103EF000D1EEFB38EF70CAAFFC27E423F3EF75FC7B +:103F000040C013FD3B1D3E96709C2E217747CFE3AA +:103F1000F9C92E9F46DF4583F19EA2F1C4DF5530DB +:103F2000EB679C8CD6FF33D547FF7E824E7E22F313 +:103F30009E5ED7E1D776372BB1BC9CB6E8F71679F1 +:103F40009ED3FB02FEF8A7794F25F65DA9C3BB35CA +:103F5000CB77A51E3FDCFBAEF8EED55EA25F713FCE +:103F6000675B0C0F3FA6F771DF19D853F3F26EF1C0 +:103F70007DC5FD047763DCF7BBD8D1DDD6EF266CB9 +:103F80003BFCD66AD1FE20B517DFFB4A4017826E94 +:103F9000FB77E3BDD1F318EF75824F7CAF6B630DF8 +:103FA000E7A364F40CEDFBA87DF43BC6F51E3C577B +:103FB00062DF317E83F0731EF83A46E3E8E6BC4CDC +:103FC000E443717E31F3C94CBA90E7713ADD5C236A +:103FD00099F796FE407858356878F880E089BB9F5D +:103FE00074AE753C3339F411F5F345F394FF83CA8D +:103FF0009F111EF35E593C7F0C9D2799F9D129F33F +:10400000709E9CE8F73C53E725961317342F8C9B42 +:104010004DE3C6BE133A7CDE20AC87A9E7975FF27A +:104020005FBC10FE351071000000000000000000B1 +:104030001F8B080000000000000B0B146060F8519B +:104040008FC0DC687C5AE3BF4C0C0CFACC0C0C978C +:10405000D81818DC38191844F8C833E7329ABE87E4 +:1040600040B366F130302C636560D809C4865CD8F3 +:10407000F5D90922D8C7817E5F05C497E91C06A33C +:1040800078F0E03A11068629A208BE8118AA7CBD04 +:104090000882AD2745995D2E40FD00C5F694E2806B +:1040A00003000000000000001F8B0800000000005B +:1040B000000BD57D0D7854D5B5E83A3367CE9CF921 +:1040C0004B4E92012721E0991031D840074C145AE9 +:1040D0005A27116D14D4887FD17A7B07DB228ACAD4 +:1040E000D47A956BB199FC4F4280008A142D8C3F95 +:1040F00054B0FA9A2A5AACB577A2146DF55DD15A2C +:10410000ABBDB42F566BAB551B5B29F415E5EDB574 +:10411000F63E99734E66328348DB173FBFCD3EFBB8 +:104120006FEDF5B7D75E7BED3D0A5441D569008749 +:10413000F18FA5F7F900A03E93CEFAC605CB1EACD1 +:1041400063FFF6B923DB5832EBE97995B1DA4CFD20 +:104150007A90002600343E7DF91F81D5FB2F70EA4E +:104160006EF6E9C9C0882FC2F209C909D8CE0D0D73 +:1041700065E70459F94147A48FE5D3871C7E60FDAC +:10418000CC04278DA383E66F9EC1BECB171483A9F1 +:104190007F7BFAF94D32A4CB009EBA05E46656AF98 +:1041A0002B70EAE5C37E80E75BD37F7DE304806804 +:1041B0007ABAACB37E76B73E43F91FB7EEFDEB1B80 +:1041C0002E801894D0388DF3DE9717B3764FB9A0B0 +:1041D0006590B56B8C4AAEC5A6F162623E4F7944DC +:1041E000B9D620672D0FB072F6BD31787ED6F218A1 +:1041F0009B11D52B11FD1C1C76623D1D467C34CFD6 +:10420000438BB2CEF338D1CEC8D70DF3F93EF9EBDC +:10421000030B900E69286E76637AA86A1FE27B48CA +:1042200095740833FC0E9F4DF84D237E5917075E99 +:10423000E3F87EEA4347A48DE1BB51D5FC11960714 +:1042400099D1839537FA214A70C92C65702C10706A +:104250005F2AD24598125D74A2CB90CAE8E2CF0FD4 +:10426000EF699B1482D798E710CEB38076065DD9AC +:10427000577F7380B583EC7C30163F6CBC938F1CEA +:104280004E03AFCDF386FEFA860AF47798FD7F865B +:10429000F6D3BFBE5193C99F7670AF25CF381AD4DD +:1042A0005318BCF84F1D53F98361A33CCCCB719CD0 +:1042B00064ABFE4135E3BF8156F8A09AF1DF9A5610 +:1042C00095F2FDAD1AE5FB5A43944FCAAC09A363BE +:1042D000B21F5209D6BE24CAEA9BC62B9EC3DA99E6 +:1042E000E00B44344BDE5713B2D4F7E8BAA53CA92F +:1042F0005FEF4831BAF7D63A524E09E16032722286 +:10430000C2A152CAC07D39C4E653CD9BC06A97FE94 +:10431000CB2A84E70527B4B37C911E755CC1F253A8 +:10432000424E4845D8F8452300ACBFE42D00EB5978 +:104330007FFDB34E715CC1F27D73DD9A530348B1CA +:10434000FE936ED6CF4769BD03FB99A144B01F18F9 +:10435000907F8B7852D97F87AB00A6EACA6B8E22FA +:104360008070827D37CFCF9D08A15C17CFB17E9F33 +:10437000AA2FB91658FDA960FA1ECED0D318D7C8F7 +:10438000DBC7B38F73FC0A5BFFB67EA7E8C30D5A89 +:104390006DA6DFE361A44DF3FF2BF71B6D94904EE8 +:1043A00011D053B38E1DDCFE157F2979E3E40C9EFA +:1043B000FB5D5C0FDAE56D181CA43F409E005106C2 +:1043C00097AE3B527DAC9FBEB083F847EF8214EAB4 +:1043D000ADD593F7C631DF1756F476960FD7EC6953 +:1043E000916602AC9AAC11DFF53DE186F6088723B1 +:1043F000C8F8748AC1A71F0D3754211F4A1059CF1E +:10440000CAC3FA9B6D585F7BD9ABBBE68C9D1FACD2 +:10441000E0F3A73C9BFF08FEA37E6CBF3FAB57A217 +:10442000CDC8B70948B9193CBDD5ED4D0936CE9672 +:10443000840C283F7DB70CBE82784E9EC0E1B5CF7C +:104440007B8AAE2C46BE06F3F86CBC29D5172FC369 +:1044500079D9E130F4C59DAD1A4419BD36B7D6906F +:104460005C6E69D506514F6CFED09915BF0B24AE1A +:104470009FEF70353B12B8CE4E77A4B649D85F6C2B +:10448000F3550CDED5F51367E33A70FD748EEF0F2C +:10449000FA05BEA5D4A540F5159DEADBE47F8B1C8B +:1044A0006D47795E1D2A8304C3EB14D7DEA6A99855 +:1044B0005F51352B8178AFBBFB35EC6FCAF4693A9D +:1044C000E2636ACD9BFB502E377F9422B99D5AC37D +:1044D000E49ACD73CA8A8983D58C4F2AF5D4D7A89C +:1044E0007E8DA2A7A40C5F4E86483BD2EBF8161F28 +:1044F000A4B5FCFC39393E3E7F1E3B3DF08F91ABAD +:104500004936B9BA23875C2D941CC42FA37255C3B6 +:10451000E48AE175C74956B9DA3C39F55631CACF54 +:104520000CCEA7763E0FD7BCD98074ED67F2531A34 +:1045300002A8700FFC5942399CC5EA4B542E7D9954 +:10454000E5FFF40BAF0E284FB59CAEF9E4CAE0E7E7 +:104550004C6A1D774B9DA3B19981FAB3AB36BEED82 +:10456000C6F16A151DE5AC4FDEF467C4B35EAFE873 +:1045700009C9244FB55C9EA6D431F9C92257F9C6A2 +:104580004FB6A6E0752647EB5A43245F6B5B7592E6 +:10459000AF5542CED660D5B92C2FE40CE6CCA67C24 +:1045A0002EFB13A08DE44ED5F702DAC1EB58DF5095 +:1045B00081DFD3D1E83C80D23A230F69075BDBD798 +:1045C0008E9643142A09DF009F41F0FE9888B2F6C8 +:1045D0005A1DCF3FDEF6C7440713C2751E5EFF09A2 +:1045E000A9A62131CFDC7E0FF56FD467F97463B5CE +:1045F000A93FECDF028FA301EB1BFDBDDA56D19082 +:1046000060E3AF1579A5BD84E78F71FF4CDF841897 +:10461000D3439FAD9FD592E827F16C34EACF8C73DA +:10462000BBF456346129FF4314F164947FB7EDD98C +:104630004482D57F1F9ABF25313A4C9F1FAB605BE8 +:1046400018F036ED0534A5D6D9F09D99DF0B34BFAF +:10465000400DCFDFDDF66114F16D943F2A05DA10CD +:10466000DFC837FE89CCAEC27FB23157FDE4474B7D +:104670009FC37FCF29052867E3E803CCD264B3AF9B +:104680004E01EE3B7C35F29BA3FC0719BE63F03D67 +:1046900028B174FABCD865B81466812F6186CF182A +:1046A0003F1FBC061CB9F9938F6FE7A3C633E73CE5 +:1046B0003F8FC99B77AF2BC2C480CD4393701D2819 +:1046C00045A0985E2BF9E8E721DC8A81CCF478607C +:1046D0006CBFA5F32B206592FB4F9A9EDFC23CC7AF +:1046E000DB4B66BAB2FCCB663C3E88F5EAC7F29D6E +:1046F000313F8F989F67CCFCEE69C1F9E5C29B7D85 +:104700007E6B3D032DCD59F6119F7788FDEEE7E7CF +:104710009C87FDB3F100F597471F213B5EC3F1D89D +:1047200056B3F8A39FB720DFE71A4F9BC7C6AB3934 +:1047300076F8CCC7C701A6BF888FEB181FD7E6E66F +:1047400063BB3C1BF3F68A797B73CC9BAD9421DC75 +:104750008FFDFF3AEFBFC87C5E37B03E127C5E5CD7 +:104760003EFE49F3FACB736512AEEF088F93F373F5 +:10477000281B7FBD2EE9967DAE9DAF73CDEB9FC507 +:10478000A763E7353E9E8FB51E2A54BFB6BFEC2502 +:104790003CF6D5B27D02EE0B9E3983FC157DCF9D94 +:1047A0007E1CFA1FBCC94F41B40C601AF6CFEC89CD +:1047B0003EB42FB0FF4D7505D917FDAD30D8790245 +:1047C000C023450C0F7E9A27B5DFCCECCF14537075 +:1047D000752FEC5617637EE9432AFA95FA84BD5883 +:1047E000F7C2BDEBCE64F8F4CF289DE564ACD0E70A +:1047F00031BEEFFCE934B4E36BD977C45B80F7C713 +:10480000BEBF80F50333F8F75C70F994540CEDFBF0 +:104810004084C165E207A3FC6107B74B77A09D7593 +:1048200022C2A993BDE5F30EC690BEDECD8A7E7787 +:1048300096FDD2FF16FA74FB8C3D092FC285F61A3D +:104840009BF7937775575CCDDAF9EE04D2E7BE9A01 +:1048500054C2C150E7AB03DA0DEE7099E85E4970BF +:1048600009BA2E924E67EBA4CF96DF3C5AFF8B64B9 +:10487000B74CAAE5E58FB6FF4743876C2A4F5CD952 +:1048800010ADCC943FDF7E6D03AEBBD3D5D8AFE681 +:10489000B1F1A733BDD7C1F03A5D1E70C4899EC186 +:1048A000ACFCB27D9BDA92627D6CBF6B63D557B373 +:1048B000AC238C8A4467237FD2BD56BEDE21F0B77D +:1048C00059E0B39FA117EBFB6A07DA119F27DD0BB5 +:1048D000116738B7BECB49C73BADFA6EBA6C9DD7EE +:1048E000B19ACFFBA0F1FDB6E89FADEB2F3AF87C73 +:1048F0001C284727311A384B8E7E3E69C413B723D4 +:104900007E93ADFF7FD47CA7FBD938C14F7E1C9F1F +:104910006D9C5CFDDAF555A2112419F7FD151041C7 +:10492000784AE6C769FFE2F4EF0D25989E95B561D8 +:104930004A5DC1915082D97F4A482FC7D45D192959 +:10494000C7EFAB3F740A79EA6943BDBA6634DFDB6F +:10495000867A742DE6497E5651F9FAD1FC6ACA6FFF +:1049600098CCE5EB78E76D43A887AB503931B85662 +:104970000FBDDAF2650657D96E7F044D8D327F0484 +:10498000500F1BE56B86DE0AA968C7EDF68387F139 +:1049900043A9160573FBB5437F0BE19EC52FCAFDE6 +:1049A000C1664BF9FAA1E9E521D43FA2DC1B8A518B +:1049B000F986A1B9E53AEA93DD7E0DBFFB2AE3341F +:1049C000EEE94F5F43FC925CE820BD6EE031B970C8 +:1049D00036F9952F9762D39D8C1E0D4FF7AB68FF6C +:1049E0002777D792BEA7358BFC49F2FF457E245D21 +:1049F0004AEB985F7BF353825ECE0C3DFAF1BC82AA +:104A0000FCC0FC9C2229CE29128DE934F9678A3832 +:104A10009D184767FCCFD4FE998CBF9AF27B2DF985 +:104A200080968AE23E5E0E32FDC0DAFBA28928D271 +:104A30005DA9E479A73F9246FD71C75510F1EB4897 +:104A4000F72860FDB57379DE156CA6F6BDF53CAFB1 +:104A5000846209CC2767F1BCBB329EC6FCAAE93C44 +:104A60007F874167D861E503F813D1BD7734EF69DB +:104A7000C7F2A4C137E06BC7F2559FE37AB6426E26 +:104A80007812F17FC7D063AF2E61FD17233FB0FED0 +:104A90008B97462C74D9AC5BE9B259E7749955CC25 +:104AA0003081749075A2C7ACE3AF776878DEF129E6 +:104AB000EE176B7CFA471EB4F7EEA8994DE55364E8 +:104AC000A7F00F707FF836E10FA862D285FB9F6DCB +:104AD000C21FF0E46DD38AB1DD939B7F48F4FE3CA6 +:104AE0002A11D66E550D3FBF7990ADD3E8C7FF6E42 +:104AF000AB4AFEBA5DACBF18D3DB8FB6AA943ED4E6 +:104B0000AA418CF5FB3DA6C7313FC0CAD36E3A0F10 +:104B10008034FBFED84E47538AF5BBA9959966AC05 +:104B20009F8DAD2AA5B7B66A7F91597FEB5B439401 +:104B3000BFD2B1688593FC1A030B66B2793DF2626D +:104B400035F9F7E63EE868C6F6A00D5C706E5DE6E6 +:104B5000BB819F2B1D8DB720BFFE60A7DC847A062A +:104B6000E4F8B333B2D76BC77AA73E283753BD609A +:104B7000FCE7E704B3D6EBC17A0FEFE270831A7952 +:104B8000B6367B7FFD08EFC9DF77F0FE42919F2F9D +:104B9000CCDEDF3AAC37B84BE6FDF999CACE5E6F92 +:104BA000238E1BF9BE80AF12CA16661FF70EEC4F9C +:104BB0002DE5F6CA9C28905F6CD235FA5D92896F1C +:104BC0006EBF765072303AAB65A938D63B657E4AE7 +:104BD000AA62E97157A72407D3779396B272068F1A +:104BE00007FB61E9EC39BCFC762C0F98CAB13D4B50 +:104BF0003F3D8F95B3F4B865D67263BC495F815170 +:104C0000BF103A5B27C5C0B05F283FCDC1F38F3BD3 +:104C10007FDB80FA699AC2EBFF19F3AC9F492DD66E +:104C2000F6D3BC3CFF5BA37E116FEF90795E6566A7 +:104C30002CEDD336AB29B4BB6E3DBF3B74853F33FF +:104C4000DFE0A264CD15A6F9DDBA6873E88ADACC94 +:104C50007C8217DC5983F95CEB8A477740D4B40E29 +:104C60004D1BA8257BF75F5DBF5C645A37705DA95B +:104C7000C07581E1A782310A9633BC25B8BDCAF15F +:104C8000B6FE2C2BDE4ACFB6E26DFDD956BC952E72 +:104C9000181F6F3F13E3E7C21F1B3F6A1EFFB68B4F +:104CA000ACE34FB8D83AFE6D175BC79F70C9518F00 +:104CB0009F36F3CD8673ACE3979D6B1D7FC3B9D64A +:104CC000F1CBCE3BBAF10DFAF40E7DCBBAAED735AF +:104CD00083997EC9A1DE90655D8FF075DD285F3513 +:104CE000F45808D7770FAEEFE89FA9E1EBFBACD7FC +:104CF000DF0FA1DF7EEDE7F6846298B2BA7B6B33FB +:104D0000EBC6939FBBD1713FEBF7EBD31D74FE3322 +:104D1000F4B94755D4FFAB6A6693BE4F8AF3DCBE45 +:104D2000D6F4FE6B5C997905921E889AFCF7A3F67F +:104D300012FCAE01F93059E310F652797B94D9A2F6 +:104D4000EA74D992EFADE5E5377796B727D0972289 +:104D50000F96E33AE4AB810F6A4D7832FA37C637E3 +:104D6000E0C93D3EDF1767C69F6A1B7FAA657C23AB +:104D7000EF99C1CB13727523C27387D827DF20FF49 +:104D80008EF4CBB1836F467BB4DA0C1FCF67E0E3C0 +:104D90007903BE6FCA331B13D5FF48F84EB5E1EF58 +:104DA000541BFE4EB5E06F853CE788F067AFD76FC8 +:104DB000E3CF6510BD499E807204646FC6654D9C4B +:104DC00007F1FEEA64215F383EFAF2AF55522784BC +:104DD00079F922B6AE5D2E8B7D98A8DF64CB1BF6E9 +:104DE0002B2E4787C98F97DD7E5580EB6DB6AD8B37 +:104DF0006C23BD1E2179CAEC3BB81F43969BA3CD03 +:104E000059F4C146999F0F4B5AA405E194FD0AF944 +:104E10001373D51F9025615F272CE73BC530927631 +:104E2000221C21A0F8243874817EFE8CB170287277 +:104E3000730CC7716A0AA05EEB2CB95837C731ED05 +:104E400030E00945091E45E3F02872249ACD0F7C15 +:104E5000B7CCFD16463F0C42D17E84CE050CF8BA85 +:104E60003CCD2D8BD19E2F51084F9D01EBB9DE6FAC +:104E7000C4BC9E1769A7884BB28F07188D81F14B70 +:104E800013E7901DDA31A75145BED421A2A29FACF1 +:104E9000D39F3D9EC848FBD1EE3C11F95E25FB3304 +:104EA000C9EC52CC7733BB14D34EFF434DB8EEEC74 +:104EB000473ECEE2A719D5731107A44DFB6D5F8D58 +:104EC00017D2E6FDA8D8AF7AF452CB7777A8C2D232 +:104ED000CE3551267BBED3EF48E13E3F1FFCDD02BD +:104EE0007EA35E8F1C57B502F6CBEE9015DE63876E +:104EF0003FDEDEE71AD4B2C1F549E1CDE02B7BFFFE +:104F00004A991227FB596E0E99F9DFE9E27CAA94BF +:104F1000A971B29BD55CE55EDEDECFCAD12EF63735 +:104F2000EB78FEC2449EE2C4549403137E26897635 +:104F30009D2E711E0D713A3792F4780BF2915AC979 +:104F4000E4471ADBCE48BDA27DCF875F7F85E4634F +:104F5000824AF221E923E497B78FF3801C9DE8622F +:104F6000E926397A1CA6AE8F9CB16C7232C1C5E5B8 +:104F7000586D6ED6557E249E15FE9345BF0306FCE4 +:104F80008938F99B0B85BFAA40F84FCEC03FD35557 +:104F90004FF07F1AD35CF0CF10F094416408F7ED26 +:104FA000C8A0D82FC0F9BAD91FBE46F45B26E003CB +:104FB000F81AD1CD28EF157828743EF30A9CCF9AC1 +:104FC000CC7C9AC47CCE1A6F3E5F10F359E3E2EBBF +:104FD00095DAD4AC87185F95E6A0CB12D1FFE651E5 +:104FE000BA7CED88F8EAA202E7B124338FC582AF1C +:104FF000AE186F1E3101CF8013E6BE11443349ACA9 +:1050000037B0C84297AD065FB9F9BA0170BD852EB9 +:10501000B7897E0A9DCFF202E7B335339F6F08BA96 +:10502000AC1C6F3EA6FA6DA27EBB902BB25BB6BAEB +:105030009E6847FBE301B9B9DB559F198FD5EB316A +:10504000D79BD4D567D45B85DFA585A3F5FAC5F8D2 +:10505000C22EBA87F6635D686330FBE6DCAEE71B01 +:10506000D11E67EDD653FFCD7CDD64ED3698FB3F56 +:10507000B96B63BBA8773BD66B3BFD23A3FF4DE623 +:10508000FEB7BAD2061C77121C4DA3FD7DDB5C6F08 +:10509000896BB09D9F13566A6FFA4C764DA834CF3A +:1050A000B90CD7BBAE602C398CFE4A080CA0DDD100 +:1050B0002DC7B70E233F30236F1BFB7E933B2A493E +:1050C0006CFDD4A2F1FBB05E69C2AD39916E8DF179 +:1050D000EF613EE180668C8BBCDDF7CDAD985F2142 +:1050E000AB9A3B82F6964E47436B8232C5C97549EF +:1050F000B104AE8B07E4D82E17D93DAC4B36CE4D5C +:10510000653AC5FB94CC0789DB1D1CAE75BE2F2507 +:10511000110E37830BE383BB6C70B1F1685FDE3B2C +:1051200081C7DB800C3532F6E7F446B0BFA1093702 +:1051300012BCC936B786ED9327DC48F0B2B2668A56 +:10514000CF73C509DE1E97AA613CDEEDBEEB36616A +:10515000FCD68A4431D5273870FE53AB087E0FC485 +:10516000D38BC3A8BE06A2786ED3B550A1B8E464B1 +:10517000703DED6FFB16AAE4DFEFAB599FC076FBE5 +:10518000177A29BECEE31F008C032A5BA000C6C39A +:105190007A82036467969EEDE5F94AA0714A3FCB97 +:1051A000E3655D30AC55B1B42CC9E38EFB6A1625BE +:1051B00016A31D3387C7A34222FA22C6B79580F8EB +:1051C00073560E61FFAE494E704632F42D1B186DBA +:1051D0005F1CCB222FA3F55205D64B1756AF3429AF +:1051E00017566FA0C07AA902EBA5793D379C5F9C4A +:1051F000ED9C7594EFE72B647F18F16D45CCF21FA1 +:10520000B54FC2DC6E37DB2B2E5032F60AF299F323 +:10521000F271E158B1AF2DB8DB64DF04954090F630 +:105220001BA7C2A9249779DA1F684D0477BBF2CF78 +:1052300017252C6DF293E7ABBFAA95FB697395FB1D +:10524000665E1C227D36E332915ECED359EC7B2D17 +:10525000A62D227F99C85FDE12CD325E83C2F57023 +:105260000D348F4B078F80FF4D3CAB674D6A645602 +:105270003F4B9C8E91FA6B1D36BBD1AAEF5439D1AE +:1052800048E71C353C2ED78DC288721301D22F2ED1 +:10529000486B55B8178568D1E28919F9718526924E +:1052A000FCFC77B913A439449F08E2D1CE2776BE1F +:1052B000F0DBF8E268F9E4D263C427BEA4B320F9B6 +:1052C000F10D14582F5560BD7461F5FC49A9B07AF1 +:1052D0000305D64B15582FCDEBAD3A4711FED60539 +:1052E0001DE887F19DAB5AF2ABCEF55ACBCFF35BFD +:1052F000F2FD6759DBFBCFB6B6EF3FDBDADEBF80EE +:10530000B77FB8FBA2D3D1CF53A89CFCEE63CA49A8 +:105310008D3A7EFDD28579E44A4DD07ED223EB9042 +:105320000EE2FAC5D62989D2682A8B7DF75321FF70 +:10533000CFB9B81F272927685FFBAF3ECFEF2ADC24 +:105340006F64CC371FBC86FEFDBD53D85B76FB6B0C +:10535000D4AF73E8F0E153508F00064B83A6B3A996 +:10536000A11F17BC110C15F1540FD0F9B4BDFF5E8D +:1053700023BE0612A14526389E7373BFCA4FC2DDF5 +:10538000213AAF3D616308F7E9BD93A5AC7E968FE6 +:10539000147E2E5815F3919DD1A3ABA40F7B27F358 +:1053A0007B4CBDAE01F21FF786ADED55613F7CA48D +:1053B000F0F17A6F8903DAFF5D276C6CC171DDE96A +:1053C000FF049DC1FD1F93E3A0E3F86EBE0F70477D +:1053D0001380EB82AA27E8FCDD0E4FD2884B868132 +:1053E000D022D3BC2F32E6C5E653C8BC5E57141A90 +:1053F0004F8B72FCE5C257FA08F1B5D4ADF07B6271 +:10540000210FE16BFF3CBE7E20219D8C8EE452D4A7 +:10541000292F99F9CDBE1E037805BF1DA6BC2E5FAE +:105420003A2E3FAD12E7A7BDE88761EBB47EE76592 +:10543000E3F2738F58CFDDF045EAD7ADC7A3A8EFED +:105440007CB569403BDE53ADCD767270A23051F031 +:105450001FC1DD197504291E25B299B1BC6F426FB9 +:10546000242DE51E47AD55AC727384EB5A9DDBBA13 +:10547000AEED877E72C6AE76C0D26CF7018C754DEC +:105480000F5E3AEEFC57D9E6EFA88D0B3FE54A1EBA +:1054900057C5742BDECB84502FD9EB3E89CD3752C4 +:1054A000F83C5F75733DA687C687636D2BF7A3AD88 +:1054B00016F4CB556F353AA031BED7BDAD03F76BAF +:1054C00025F3B97C8CCA833C60E1DB830AF777F46F +:1054D0007AF4368A730973BFC9987E057FDBE52DA0 +:1054E00099E39E8D21CF7F5374AE9FD401F247186C +:1054F00072A7EBFF49FAAF7772BB8AFA21A9AF27EF +:10550000FFF1FE6A05303ECBAE278CB44FE0E134AC +:10551000E857F11E53DF4B4EBA176BAFE7C1CD9A78 +:10552000C9DFE7ABB1EAE57C7A66B39BE3E5E3EA82 +:10553000991F0ABA66D133B42E2FEDE97C0AE9D35C +:105540002BE20C4B9B12B0D834DFB542CFFDBB5BD6 +:10555000AC17951C8E5E97D660A65309FBDE60D60D +:10556000A739E8938BEE976190E0840C1CF6F9ED77 +:10557000107828C5F16BF3E3612C1D381F74BBB3A1 +:10558000F3C127359F2E81AF7C7CBC55CC67ABC067 +:10559000AB31AF7C7262F4FF30E2AB1EEBDBD603C3 +:1055A0003961A1BFD3C05B93AD9E6AAD67E047761A +:1055B000733BC6583FF2F5FF6B85C363EF3F971C03 +:1055C000FE66540E13E4AF35C671C3E3E457D8CF7B +:1055D000F474DF2C80623F48E837706A3CEE291093 +:1055E0006C06F3798F5D7F197A31973EB2EF67F2DF +:1055F000D55782CAB8F69361EF948A7B5FAA881365 +:105600005E2F653FFFF9BBA01B53F405C5FB61F896 +:1056100008E2039A21B58DE244A3436D2C3F31A2E9 +:10562000E87DE81791CF18BA8BE527FCC80D7D11EE +:1056300074C5CC1F1A62FCB62AAA366379851A1E75 +:10564000BD1F39700AFABBB83D06CE95AFE0FDE04C +:105650008997C8807875C35C8ADFDEBF02EF8E8DC4 +:105660008567A20C30A994A5C26F40E78AB8D5BC63 +:10567000D08A4F5868CAB3FDE304D5B6BF2B70DE9D +:10568000767872B5CB0B4F667FFA068EEF86F1D730 +:10569000B5239DDFA8BD5BE0BC686D36D50B1F74DC +:1056A000828EF7DE0F4A941E7FD047E994831E4A0C +:1056B000271F2C039D11ADF26009A5930E4EA2EF9A +:1056C0001507CB292D3F3895D2D0C130A525073FEE +:1056D00045A976703AA5EB841C161F3C99F250330D +:1056E0009BC62F3A388BF281839FA5D47F702E2FD3 +:1056F00017E7ACEB6E8901FAB1155C87987C749D55 +:10570000B184D625FBBC6E55F9BAD22DE2D6BB6D5D +:105710007AFB6151FEA048D709B900390E667F7A3D +:105720004AE57A615D558CECF26E633D2C5F6259FF +:105730000FEDF5BB73DCAF7CCC804BC003358BF237 +:10574000D0879FCBBA8331BA4F001023BD0472CCEF +:10575000A277BB0DF8051E73F727F078C6A3C4C760 +:105760001E85C72D7BBE7067CBBDA877CEBC71E907 +:105770006E267723EED8CD2AF2FB17AE26A6BBE322 +:10578000BA9B43741FF18C8D74EF09CD72BC4FD15D +:1057900073E6CAF8BDC4758C2E33A85D9B6A3A1FA8 +:1057A000ED5D7273CB77587F7AA7037413BF4E59A0 +:1057B000E905DDACBF0E959563FBCA1B4A2DDF2BB7 +:1057C000AEA9B0B4831AEE470F7DA5CA524F9B7F96 +:1057D00092A55ED1BCD9D676E2FCDC5FF7194B3BD3 +:1057E000B7DFC02B3F5F64F4B7AC1F3D52763A7E03 +:1057F0005D758CCB3797AAC22EF21746B75CFD1B9E +:10580000F3CDAB978279E741F6EED7D573E7E3396D +:10581000865B8BD1FD9523AF7F6CE751683DBBBEA6 +:105820002A427D5586FA44A2D48FFAAA0CF58887BD +:1058300052A3DE6AC36E29504E56A3BEF19BF44DAF +:105840003D93FB2CFC50EC195FDFCC14E535225D59 +:105850002DF8CACE37938C72D437B5F9F5CD24DB49 +:10586000B876B8EA3C421FFD93F54DEFEC8DB12FB1 +:10587000B39CE7D43B5BEE6169CFAC1B29CFF485C9 +:10588000DBC3CA7B4E5919BFC7A447E0D0CF395FED +:105890000A7E289E63D51F46FF81884D8F18F2F03F +:1058A00031E55AF270B9CD459FDF1FA55C1BFD7F26 +:1058B000D2722DF5AE3A22B91E5BFFD8CEA3D07AB4 +:1058C0008946489F86FB9269DE5407FAE31C031160 +:1058D0007EDF3346F13CBD3F75D17902AB41FBE23F +:1058E0007A357A0EF24FBDDA7C1EA6D787F5E370C3 +:1058F0009D66F9F36DF90B3C132CF98B6CF94B6C2D +:10590000F52FB5957FD15C9ED4F5E3D08F917CC601 +:1059100045E78649DDD194F53D0581A767D5E62F9A +:1059200063FB1353271D877461F9AF527F1EDE1F7F +:10593000CB5F49E365F257D9CA97D9CAAFB5E597A6 +:10594000DBEA7FCD9CEFFD68EAEDB8DE277EE682DC +:105950006D59FC4BAF083DD273C2CDB1762E97374F +:10596000935C4E5B19BF02882F00E176FA6DFB3F16 +:10597000C667667E7956E89B9F4CBE91F64D3D6C9E +:10598000FF44F18DE8DFCB829FDF78C4FB5CFA55E2 +:10599000742F22597E3DF9397A2ADB297E61BFAE08 +:1059A000D0B96D329CBD7D6F2BF773F454663F5FA9 +:1059B000F88D276C89D7826AEE17443138ECC077AE +:1059C00086B87EEF0A77937E55D25771FF46798C61 +:1059D000FC1BDB3C7CFD52FC71F22BB82BE359F72E +:1059E000F53DA3F8B0FA3B7F22F06AEC234DF82096 +:1059F00039ECF2FC6937FA37929EEC72B6538CEFB1 +:105A00000A1536FED8F9F3F1EFC6CB2E28AFB67DD6 +:105A10006DD2C5E3E71393B91F4066E398FD0AF61C +:105A2000F146E769DB67DF25F83CE9E1F1F7467FFE +:105A30007678EE17F3B9DFA359E6256B7C9C7CFDE5 +:105A4000FF182F71A11F40B3FB21AC7AAE55D4775C +:105A500005ADF572E127318A1F1EA765F06F3E7E06 +:105A600037C67916E1A2F385ECFB70FDD01C8AEBFA +:105A7000D80F81813EDC37CBDA2BE817BE896D93D6 +:105A8000D09FDD2127C8BF90D041E3EFECF07389B0 +:105A90009B9C274550DFA922DE0230DE22688A5710 +:105AA000147ECEDB7DDFBC0FCB5724DC1ABE7BF22D +:105AB00077CF543E9F432B28CEA297EDD471DC03C1 +:105AC0009E29297C4FC759DC4FF6BCD3392B9E2D1C +:105AD000FED4EDE5727CDAA1B5A467BB997EC3F371 +:105AE000A56E39A696D6A2EB3A41F2DAAB8F1FD754 +:105AF000688F8F7469F6B8442BBE225E4EDFA458BF +:105B00007F939E488B252ED0EBA1F2BF7BACF0F5A6 +:105B1000E8FCBE900E718A334D563A1C88B7630577 +:105B20009F31AE12E6F78F8210A338163524D3B812 +:105B30000E1FC76FAE714197DF31BF2B73ACF039C9 +:105B4000BAFEC6383FC9E0257ED2E7AB8DDB31FF18 +:105B50005327ADA7F6717EEF8D7DC66BD29BB21633 +:105B6000033A8717FD9D3581C77FCB95FC7EBA022E +:105B7000CD4D6136FF8E4AFEFEA2ECCF132F516948 +:105B8000F757E43AAFE3E72554C444B4E10F7C5C33 +:105B9000AF882308C030059116A34A9F8A7104BAC2 +:105BA000C4EFF747241E6F3E8FE2CB839E4FBADFD0 +:105BB000CBA95F29BA0E0EFB8EA05F7998FC5C9F83 +:105BC00078BF79E0F5C09DD42F86AC1E2ECBF48B28 +:105BD000FA979C4A870E1FC6F334714605861D2E20 +:105BE0003BF87D2BA828A278C4AEE0F5AA99AE9D1B +:105BF000DE2ACBFAAA68DD5FC3779494CA6BA2C38E +:105C0000E3F06552C89152F995E870017E4C994DC8 +:105C10003F9B3FB45B89A5DAD05E9CE2E771AC7232 +:105C20009CCE477AA4D2D97D7526FEAD54D2089772 +:105C30003F124D609C634F992382F15932F4EFA5D6 +:105C400077D39C0B23E3C9AB5C29BF6D9ECFB7BD57 +:105C50008120C129FC871D79F8BD4BE8EB5CE52E5E +:105C60002512CBA68707BD621DF3662F3FE06B7C34 +:105C7000D09B65DD490BFCF6943055FA69CE3EC8E1 +:105C80000772E59E57100F5D13CE1C5F3F6956FDEE +:105C9000F4BA2FFA43EFF870FCD85B9F857EFE6064 +:105CA00061FB038803DEA775BEE414E7BBD122695C +:105CB000229EDA1A7F11E864E5AE396E0DFDC9DE69 +:105CC000DA08DCCBF2A1D3D566790EBD1B47E7AC71 +:105CD000AE7227505C9E731E8F1BAAE17ED628FBF6 +:105CE0008FE2CBE68D1F4FE6B4E57F65A773EB2E01 +:105CF0007A3FC280DF885FB7CFEB07BEC6E1ECF822 +:105D0000286C1FB481F10BB8F15D3195D2B5AD1A95 +:105D1000A5AB5B4394AE6A65CC4EEB7F0DE56FC3DC +:105D2000A673312E249E0CE37E2474EF2B78257409 +:105D300003E296EE19DD7306DA597D98E7F7421310 +:105D400012E627F3F2437D1BCEC0FD609FC7A89FDC +:105D5000E4F547F37774A15DD827E26BCB56DD7B82 +:105D600006DAAD1B261BFEAFA87A91C9FEAAF1B9CF +:105D7000B89F266CB4EFEAC27DAC4736F28F9E61C5 +:105D8000CD4314E1F1A83C7F8EEF07040FA9003644 +:105D9000DE45BE5D94DF7082D8975FB8280F1EB9CC +:105DA0001FA3D7AB733BE842FEEE8AC2F8A68A7DFA +:105DB000DA20DECD2DB41FDCFFD07AF752F6F532B3 +:105DC000233779D6B50B0B7BFF85A183EC0BD4C3AE +:105DD000F8FEA2FC0B2E17C77ADC0DAE23C38B3A5C +:105DE0002F16C5EE8B9A06D348EA9F78630D3ED6F0 +:105DF0004FF1FCBDB4AC28A134B71B0A1CBFD2279D +:105E0000EE9BB179E3BA63E0DBB03F6E407A4EC8F7 +:105E1000F4E70A46E9DCCD23DE1B2E14EEABBC9A78 +:105E2000A51F786076F978E76DC1850E0C421AD50A +:105E30001BA5F3BD96BC36AF540475F07C515D854F +:105E400025EFAFADB2E45DDA4996F61F975E5FF2DB +:105E50006A16FEBEC036AF26FB3C0BECD7B3C2A918 +:105E6000BFC1EC84B06CD8A5EBE9DEF27EC431EAA8 +:105E7000C98159748F17AA8D7B0A40712C1E3D4A27 +:105E80007CEA65FA9AECE34AABBD2A07ADF66AA84C +:105E9000259136FAC5F86DCF0A85C61D5DAFFC9019 +:105EA000F6E0DD73A19769DF3E1555DE379E09F3F5 +:105EB0007611F3FD7C7B2A8B7333BA9B1FCE7FAEAA +:105EC0006A1F2774E1F8716CF6FAE097F5374D72A6 +:105ED00098BB9D0C6F9ADEDDD886B49F90C17F740D +:105EE000FB62F27FB881D9D30CCF1DA18B21C6E60E +:105EF000D98D5518FD9298323EEF0ECDD6284E5FC3 +:105F0000E77475A85C4E6EF2E916BBCCE9E77262E5 +:105F1000D4CB47FF9B9C10CFB6AEBDEAE3FBE503B5 +:105F2000DF8CFF09F799891741C7F3DFC1D683F4E6 +:105F30000E665DFA2C27FA4FF6F92652BDBADD51EE +:105F4000E7E9A67EEA80BF07CEFE9C66BFAAE127EE +:105F500086432AC50DEF4CF3B8E19DE93F3F751824 +:105F6000F3CF38E8DDD19D7BC7B7B306859D65D4F7 +:105F70001B7C86EF5B0765F0958E67EF88FB71B33E +:105F8000D2B6B844199C48FF03B7E84EB47B065B11 +:105F90005509D7FFD9629E75E9A813D7B17CF3DA0A +:105FA00063A3AF314FBC9F88F3ECF4F3FB829D1ADF +:105FB0009B2FF1357F4F3B17BCA3FB7F2D3B3E94BE +:105FC000007FB74371C5B46CF3CE778FF168E1EB16 +:105FD000B2C1D7EDE7FB73C37F900F1E25E8B0E891 +:105FE000096F9D26E182128081A6696142E38BB828 +:105FF0001F2255C1583DB06FAEB404E3C617FBA3D2 +:106000005208F39F95A63038B50A27DBE3307BA909 +:10601000F6C5F4AF713E2D3EBA97D151FB01C517BD +:10602000947C556EC375AA173B27BBA8BABB81C128 +:10603000D781FF642ABCBCBFFC4CB43B64E07A80CF +:1060400049982E4F44BB11F031979CFA80FD498747 +:10605000DD9976B9F064B73FDDB0687CFD24CEF9F8 +:1060600013EC3FD42F25B6F6C551AB7D1BB0DDA791 +:10607000380DF5777D01F7328E721C0DD6AB187A8C +:10608000E0AA766829AC0F5A09DE07F2CE9701E341 +:106090001BB5E048C2A1E7C77B275BC2B85CA52C53 +:1060A000E73017FAB9FF2774451DC5E1EC8F302E94 +:1060B0009885F957B2EEE3ECF72D56D5DE4D7AB25E +:1060C00083F113C69B246A1DB47FECAD7E4833CBAD +:1060D000D3D7C53819FA832E1BFB64BCBF5AED8891 +:1060E0007A667E7CFADBF71BF9E8EF5B688DFB399B +:1060F00052BAB4FA41C4B18C4FFFA31DC7A0DB58FC +:10610000F9681374FB0AE993EED091DD935955BBFE +:106110009EE8E6ADCE1EEFDEE997AC7A56A42ADB08 +:106120005F464CFB4BE771A7B4DC05E3D0654C7CC4 +:1061300015EFC7E9E77EB4D592378243ADCEE1577C +:106140009E1630E018E6717C73F784F0DCB8BFFE71 +:10615000CD109E6FACF930FBF9E382008F0FD7A30F +:10616000AF92FDBFA69EFB03F10FF5CE4DFC9F50F5 +:1061700095786B13BE6BB67A9FCF62FF18EB42AE79 +:106180007929154BE9BDC403AF49F4BEBA54B1E255 +:1061900044846B68EE127A87A4BBEE493A7FE98F9C +:1061A0008C4F1723BEB45BDC571F1D3FC779E1DF5F +:1061B000045DAA12CBC89E5C53FE228DB3BA6EFC5E +:1061C000719236FADB53D50131F213DBCE73F70946 +:1061D000B9DDE717E712AEE6F3A686318E2A4EFE4A +:1061E000B10935D121D4FB170662AFF859F99AB934 +:1061F0004BCA691FA15BD7C15B73CC2714E0FD1AA2 +:1062000076D281AAF8FFB9A50E7FAF62DAAC848995 +:106210001EFD39E2DA6B03C6B99787F639DD780FD0 +:1062200080C1D75F5E18FE0D3A9F06CFA9F8CE7ADF +:10623000778EF85E23B5AFEFF9F06EC7C31AD7308B +:10624000C53FAD91B2CF674180E37BCD2D697E9E86 +:1062500036F74D3A4FF3A75FA5B889FFA8DF4BE7A4 +:10626000697A809FFF04FCC3144F5A3487BF0F988C +:106270004B8E527E5E5FD6ACF5401EB69E0FF98DFA +:10628000F39EF1FB33E00475989FF38C954B5A7F96 +:10629000EEEBDFB687DE5181349D2774FFC2496F74 +:1062A000C11A7818235749FE3B316B241EB7BC2016 +:1062B000D0DA8DFE9135C6F9DA2CBE4F92EBD2744E +:1062C000BEE60DE8167BC71F31DE492C6C9E45B833 +:1062D00016D573B580EB2AFAE111BECE5917933F5C +:1062E00037175D6FF2C5EA03F5667F3EDF67FDABEA +:1062F000F1E1DFFCBA252EDDCE8F6EF8B723DAC7C9 +:10630000E5F22B1F10F269BCA36BB45F1C50B2E323 +:10631000F7D797E4C3EFE2C0846CF83DCB4BFB8822 +:1063200075E39FEF6CB2E9EF4D469C8D78D797F5FA +:10633000577E7E167BC258570F048CF77C9ABD3867 +:106340004E55A2D68B78DA965C44F96DB78E4F4FD6 +:1063500063FC2D42AF6F15EF9018E55B055FA66CEF +:10636000FAF66521D75B857C6D53A35E8C5F82A7AF +:10637000CEF24E67F80B33BE4057E2F15D2325E3C2 +:106380008DAFAFB4DAFD477ABF652060F5D7167AD6 +:106390006FF368F1921271352F07D224F7CE743162 +:1063A000C9537829903C85632369DC37550D3852F1 +:1063B0003AC5AF347BA733928696CA3AC5B2897B79 +:1063C000B0278AF51D9C2B1DB87F09897BE48C853D +:1063D0002FA338983BADBF07B24D8D342A78AEDC81 +:1063E00049118E104E9A7EAF8240B2FE1E4868DF81 +:1063F0005BF47B2A2130D50B1F3DDEFF2BF0F1EE45 +:10640000CB1E353FCA231EB33E3E5E82E66C7AFF4A +:1064100017C21E3BFE969D12C9E5357E78DDE4A7C6 +:106420004949232588DF2D2BDB25C467A2132227AA +:1064300064D1636F047C865ED88DEF2EB82A397DD7 +:10644000BBFEEDE2E12798CADAB2A211B2ED3F98A5 +:106450005E782340EB13D70B5B572EE2E92127F13F +:1064600049751252F83B2AF307626D2EA4FB52FEC7 +:106470002E75A8333E84F9F03510D159FF55E8D474 +:1064800067E356B7402A4A7C042F8726E2EFDDF007 +:10649000BFC9C38B87BECDEAEF99E3D6F07755E04D +:1064A000062BBF545C63FD7D95EA4E2BBF4CB4F1C7 +:1064B0008BBD7D581F390BE19D9A7400EEEB82175E +:1064C000DAFA83E11DF7E17C76FB2369066F75BF7D +:1064D000B5DCDEBF0C317711A3CB23371FEAAD61EA +:1064E000F5EF4E3696215EB6A9C0EF5B342B74BF34 +:1064F00035D73BC463F8D6B0FB0B7CB7D858F77AD6 +:10650000F649FCDD8B29DA6B61F46BBECC7FC72EBC +:10651000F38EC567E81D8BE320C6ED478852DA2964 +:10652000EC53EDF4CA30FA3F93BFF669782F4B2B4A +:10653000B3FACFE4D2267A1F6CD4EE2E6576372BD1 +:106540004F9658EDCBD38B389FCE2EE2F6A1E6E3E3 +:10655000FD801A2F37BFABB4B148B296FBE3E51705 +:1065600098CAE71789F767C5BBE30D450B7A502F2B +:10657000699358FD2CFC79A618D7288760642FBE34 +:106580000772FBA58BEACDFB8B8D45FC5C473B5E20 +:106590008C5B991DAE64988F7B9B18776391F10E8D +:1065A0005C9CBF03A7F1D4F87E5B6089F406FB7C9A +:1065B000C0058D18A7D231C141EF43DE34D1880721 +:1065C0001B5F4F187418C5B7C6E3902A96F27B97E5 +:1065D000B9DA6D6EE2FE41FBF7989847E7D2C681C3 +:1065E0006A36FFE86E203E710721EBF90F93EF58F2 +:1065F0005136BBAAB389F671074AB2FF4EA1917614 +:10660000D8D67D59F813C7D41374D25F0A118B778B +:1066100086B87FEE4089234AF7026B81DE3B3B5010 +:10662000CEFD75F6F6BDB6713CB0288AEB349EB34C +:10663000623CA3520D293CC8F10607B4B08EF101AB +:106640007BC94FA303C3272BEF8E00D9779D216E03 +:10665000C7C8A1810607AE1FD0A499EDB10AF17B8E +:106660008B1E7FACA3C812479220FD7BC095223DB4 +:10667000D21176C0DD59FC886B8AB89DBB595FF496 +:106680007C380BFD3614E916FBB9E220B7BF73D591 +:10669000CFD4E3708DF263284EE73EA0737EBC300A +:1066A00010BDBD689C382EC3EF78C51CA17041BFDA +:1066B000E47FD83CAE7AC64531E9A71DDABAE7DBFC +:1066C0000C4F4E714ECD56E53D4FB0F2AFE0BD27B9 +:1066D00096BF6ADF0C650A2B7FB9C2898B30FB6BD2 +:1066E0002EC271DF054713CAD3BBF062D1C926BAE7 +:1066F0003D5224ECD0A48BF4A6E18FFBEA80CBA220 +:1067000057AFDC64CD2F814513D14FB1E45617D973 +:106710002657D9D6FB6D62FE5742BC1BD7CF2E1130 +:106720003F7EED0F66282837579DAC859DA6FB560A +:106730004F087ABCCDF84737C9D9D5FE9482FBB84B +:10674000D7779E7CF16701FB497557E0FA59923D76 +:10675000FEEFCB492B9CF9E66187DB38BFCB058781 +:10676000BC5D8AA6B2C8D9B34556BF5087CADF47B9 +:106770008A76C8E0F93CC6DF01C94F625F80DEF36C +:106780004E34C6299E2ED1EED63A82145F477174DC +:106790002B18C1F03DA23F08FE33E2E900E2A7E278 +:1067A0003EED5A7558417FF47239DE843FA5669CF0 +:1067B000C3B85DB1E82406BF6B57437A1258EA2587 +:1067C0000BACF78C545550BD26C738FDBD27F4E4FB +:1067D000D30FDCA3E0FAF3EEFDAF9D8B72B8EC7142 +:1067E00027E095BCF71E08409AF60F2905E5FBEA5D +:1067F0009DCEAC7E36F2D4323C2EFB5E80F4E2D5E8 +:106800000FB9530B59FBAB1F7D7D2630797AAF7DD5 +:1068100064CF24C4DFFD123F1F4C0CCFC4F5E96ADE +:1068200019FE3DDB3B64BE62CE5FEF3CE66B41FA96 +:1068300049DB87BE44FD0E5EE232BFC7EE28E6EBC1 +:106840000FABC7E3257748A913B2E80F633FF4CE37 +:106850000E89C3B7CB95C250E0ABB7DFA5C4181CF7 +:10686000CBB7BF4FFC72FAF71E2C423C2CDFE5B4CD +:10687000EC2F977DEFC3EECF303A2F73C2C842940E +:1068800063E721CAEF8FAA234E926B1E9F721DA948 +:106890000056EFE1DF9FF93FACFCED901330B4F50B +:1068A000EDBDBF531EC77CCC1FC75F1459BECBCAFA +:1068B000D7CBB7BFAE205C9A03462A3F8BE79C56E6 +:1068C0003BC95E1F6044413DB57CB0F77D27E3B70F +:1068D000E53BDFFD15F2DD729B7CBC8DFF281F6B55 +:1068E0009F9F5C6CB3CFB797151487B2ECC1FD5B6B +:1068F000D01FF1CE437FDC82F767AFF9E82F5BBE94 +:1069000081F1603FF66828DFCBEFFF451198F4FE78 +:1069100039C55CCEDEDB71DF7736B3F9BFF7AA9BF2 +:10692000B0F5DE13BF9F82FE9FF7BEFFB789E80F69 +:10693000BAE189338E43FEBAE111FE7B36B9E040FD +:106940007E4D997F6F519C13E9BBC81803F891489D +:106950006DF480811105D7B3BF4A30D257C2BE0F44 +:106960007EA8A07DB6270A23889FA776BEBEE766CD +:10697000967F97D1C79D853E6CFE931CA49F99D8A6 +:10698000B0F4BA9D179CF7B93A4C5D11EC7E398C86 +:1069900090DE1C43D797185DEB3274B597EF8743B1 +:1069A0000A9E1B2C7F80D17126D293D171E6583A72 +:1069B000BE8BFF983B968ED714DBDF6FB866EB6615 +:1069C0002CDC5996D5DE35F659D73E72D1B8F69300 +:1069D000A117F2E179A9F093CC298EAE2C46397C2F +:1069E000E8BBDFD91CE4745EC810F3DE83FBA7E0CC +:1069F000A31C7F708D7C09F130F2845BC3F5FDEA46 +:106A0000277E49F2F6DE232F283AC5B54091740A55 +:106A1000CBC3E8DF8BC0F2D7493C73EDBD7F3FF3BA +:106A200057ACFDB5F853AA1AD18FF27B98FC113DF3 +:106A300052E737E9A877531368DED7A5B85C5C97AF +:106A40001ABA10E3F9EC787F44E817335DF17DA9B9 +:106A5000EB76BE7626F25F2E7A1AF3D770FEA7B2D7 +:106A6000F27BAD729B534E057DDFBBEB8082F6411E +:106A7000FA714573307BF83DD78842EBE3F79DDA36 +:106A8000B6C858BA67F02FE28E8E701F3E586CF36E +:106A90007F08FCE493F3FCF33A32BC6D29D62DFC5D +:106AA00063E0EF9D43D9F5FFB3C5DCDEBE0EE24DDA +:106AB0001553C7AE5F323427268533F0BE8371632A +:106AC0000CDE77EE77D23B7DDD834F911EB7EB8BEB +:106AD000EB72D8D1FB8CF1760DCD44BDF6CE938F01 +:106AE000115F5EF7C06B0AEE57F66C7F5819AECD9A +:106AF000C801AE0FE6DF297BE77F0DCD44FDB53C35 +:106B000047FCDF5BA2FFE53FB2F6BFFC81F72DFD3E +:106B10002F4B0C2AF43BAF79C6795B8E5E82F37DF6 +:106B20007BAF0B703FFCF6A0B3299B9DF3DF627D2A +:106B300034F0D41D38E595623CF72AE5EF3276B69D +:106B4000457F89BF379C78C125F6B7D157D09EE9DC +:106B50002851E81E4267E062F2D71BFD0DD8F0A96C +:106B600005B506DC0768F39BEBCCFB2A03FE92A875 +:106B7000C302FFFF03C228CF4D00800000000000C9 +:106B80001F8B080000000000000BD57C0B7C54D547 +:106B9000B5F73A73CE3C42269393D7E4693C4978E3 +:106BA0004AC02109101ED58120A6986A50AA5CEB24 +:106BB000D50121444832292A5AEB779990885EF012 +:106BC000B3B1D28296B60317AA95C40E1034B6811B +:106BD0000E606950B4019F7851A3D68A15C8180574 +:106BE0006DAFD6BBD6DAE730332783D0EFFEBEEFEA +:106BF000F7FBC2CFDF769FB3CF3E7BAFF55FCFBD54 +:106C0000CEDC91529DAD3901DA560268A30040F105 +:106C1000E4D4A600C8AED9D59089AD6A519324803A +:106C2000AFE9EFF2680B100498086075D6820F9FE9 +:106C3000B7AA16D01CC07F5F03CFD3DE8FCFDF256E +:106C4000A7B4AFA179ACCDBFA43EB428B0B58287BC +:106C50008D562AE8FE259E354500EB93FFED71BA6F +:106C60007F77C0AEDAB16D4D59F11BEAFF4A825A07 +:106C700019C7B5D2F3D806AC0E75AB8AD7D3607EF0 +:106C8000C8195D4FBE2AF17AC6E33AA8C53F1F4C2A +:106C9000C2F78A25412B34008E80A4CC60805AE351 +:106CA000B97F577D25EAC4685F76F681AF14E00AA4 +:106CB000D969A1FDDF9F6309DA8BA8BD36154A8724 +:106CC000D2C168EF5B590BE151E7BEDF9EE558B0DA +:106CD0000978DD010BCE1B901CC1ADB4102F68AA42 +:106CE0001B786DA0E17F484347CCBA718097F6A12D +:106CF000E8F7ADB82DBA698700B749C4076C93218E +:106D00000C500270A55A0C90059002FDFA2411A8AF +:106D10001D07302FC5E7A57D660FF749342E0BBC44 +:106D2000DC5640AD44F72DC937E5FABE617F304FE0 +:106D300039D13F5AE72FBEE25756417F450165588A +:106D400019AD63A3FA97B1380FDDCFA051015EC72B +:106D500084AAEBC7B6111C68F131747E78D6CC0CCE +:106D6000C28D31AED551785442BA78E52435A91098 +:106D7000FB0A5286F87D2C85E9F4A3E93833DEFF5F +:106D8000F1B194CD32F2E36149E0294078225C41CF +:106D9000F3E3840F17E2670D3D37B3F9378C170B18 +:106DA000D4B656E8947413FDC41FE28DF174B7E2B3 +:106DB00050ED1EA2AD5753681E1B04D748B45E1F8A +:106DC000D3D301EDDC0E8310B74EE8E37605D1791D +:106DD00022F1C1C3FD54E86F1F8ECFD5A8B50D2A8F +:106DE000EEE7C7D5E912EDCF09AA4EDF825C9FF32B +:106DF0001BE83B0BE9EB88D2D74EF44C1E4A4F07F9 +:106E0000A84C87340F78D64CE079218CFB78780633 +:106E1000046506910A2AE2255BDF6786CE67C20F0A +:106E2000ED2F6BBED89FF97D39D0CEE3F220C46D33 +:106E300001F4719BEE502585D7734CE7EF7BF0751D +:106E400072743D466B2704E3FCA70B70FE22A6B6C6 +:106E50004B72D3FE8DBF5AC6E11F2AF679AB709CE8 +:106E6000E2737AEDB895FF5D31934008D68B15201B +:106E7000BE3AFB17D4800B877B6C101E4DB307788E +:106E80007D49A345DFD02F766454D8583F3E673DF7 +:106E9000F6D1317ACE0A31E3681DF24DA944F78765 +:106EA000E8C294A174BFFB584BE67331F36E5153A3 +:106EB00032699F3019267F2D479F87CA7480DCA1D5 +:106EC000CF7FBE3290F99C354A8736C7BF312EBD81 +:106ED00008E0A4CBB04F38CE8CE21871C97A2EB03E +:106EE000CAAEB666320E19A7772381ECD87E9E54BF +:106EF00018E4FD43F3E46B510F5B1C5E49C2EB0DDC +:106F0000AA2B48F469748666B39E30E98D19F3D4D0 +:106F1000701E8E1B68060FD175FDCE6B8E135D073C +:106F2000DCA0D9D3042EBC93484F187A043419F945 +:106F3000BB5A9AE090B06DECFAE4A5DFE1F8A41E2C +:106F40001964BC3F807BEEA37D2BDE346262323C51 +:106F50001827DFAD0E213FC63ECDF2FACFEE133932 +:106F6000CFF3331F64D2BF0FFE3B3D3F0829ED3402 +:106F70007E8382AFA6F97BADC1AD4887E50765C6C4 +:106F8000DBF24E2908C467454BA5FE5D2FC820F0F3 +:106F9000077CFFAE5F96301E6518FBA3E9F8BC7F47 +:106FA000A3D5831A13D2BCF1F62AA37A1868313814 +:106FB0008080F7480ED26B914EAFF5C90F6DA2F5E8 +:106FC0006C6811F629AB363D6EFCE74957DBEA7079 +:106FD0007E2D17D7359570D3337235F697E5CBAA4A +:106FE0008C2A227B7E5EBC7D6CB7BE47F2A7E13F58 +:106FF000C2B7A1BFEA487F911E92EF65FB771AE9FD +:107000002593BC80B07F4DA8AFC238DF920DE279E6 +:1070100063BEFA9E8757E7637B5B30FEFA3250A26D +:107020007DB6B3AED1A407EE86611EBB3414FF4A11 +:107030001AE29F40E204A7E083D343FA65F015D932 +:107040006317A4607925BA931E91FB47AD9F8EF319 +:10705000F97BAD10D4885FE2FEE0463918288ACA71 +:10706000C760EF4EA6C7925CA407E2D39E134FFF02 +:10707000242D9EFEC9A3D3BF911F291E133DE51ADF +:10708000A63FD21B68FED4CAE2F8E7757A8FC67FA6 +:1070900082DE5E5E675DB7048F4944E7070FE46BED +:1070A00043E9DAD4FDB08DE4FF7C7435D3715C9A8A +:1070B000AE47743A9E869EBD3A2A6B1D6E5625BC1D +:1070C0000F456D9F41382D40B9259C98E5DAA09F6A +:1070D0003553F5DA70DC45340EF797E7080961F4AB +:1070E00080F232E165A1D0BBADAA97ED91A16F937B +:1070F000CFEAEDF7E16B6C33E7563C4038BA5D4AB6 +:107100006967BFCA24B76BC7AD60FD55B00AF531DA +:10711000DBD5783F2DB4D2E15984EB796A25781616 +:107120008D00D8B152E5D6ECBF19F2BE11FD37BBC8 +:10713000B0CF3CAF82F85DA392FEF1A8B4CE876CCD +:10714000C0723A500AC1CDF8FE50F83337F9A30F98 +:107150009545AEAE457FC4BF186A43D86E4DB7B0F3 +:107160007E7D365DF877D5E9366ED7D45AC08BEF81 +:1071700039D52307255CDF29D57BF072D23B3D56FC +:107180008DFD2B35F2D2F7F87EB9BA06E9996B6915 +:107190009F40EFC5F1D5419C77A0E77DD7AD317613 +:1071A000F954F72363C80F7AD402F5A104FE5063A3 +:1071B0009A78FFA9D1EFB971DBD0E888D800F174D3 +:1071C0007F7F732DF95B77256B7CDFD635239CCFD2 +:1071D000F899CBFEF17375C3186FBB4E4090E46E07 +:1071E000B67CD355E3B03FE555C56367A1F25EBDFC +:1071F00060120F61BEAFFBB27C03D1CF8FF45CC5D0 +:1072000017DB5F267E3DFB670548EE2A9A9F7EDFEF +:1072100087FB3C908368A80498E40D958771D4ACF3 +:107220009EB41924DFFE63C0F23AB14F89C32DC862 +:107230000DFBF349AFBC21DCC3C96F98EE43402678 +:10724000FF7F4A7FFCF569E7C1FB5A03EF2E7013FD +:10725000DE1F5BD90DEF935DD4ED671E6E30113DDF +:107260000D7C3F933CF39134F6274026DC7A94C49E +:10727000E3FF9C2E310ED67D294B84CB81087856B6 +:1072800021BD0616E5F1BE073E23870CDB2FE5EA9C +:1072900050027FEB89341B3FFFA84DE0FED13A67D7 +:1072A000B005F7B3AF6EE9C5FDF8BE333FF05DAC96 +:1072B0007E931F8CAAC552C9FC4A25BADF3EB74D42 +:1072C000623984F65CA29B79BC212786DC18F29295 +:1072D0005B37CC174CF09ED1FAFE66D68D966C8447 +:1072E000DB3D12101F4FADC2757D83FF188055F92D +:1072F000B41E7FF7A736B2D78E1EC91B4C30BE37DF +:10730000CD25F0BB2AD0320DE9B562213E4B72612A +:107310006B2F4A347F00D6E5A37308BF49D3785D4D +:10732000A71C700BC92528EDB964B74F75577D9B15 +:10733000F4FA632887E4373C6AF5F0BA038D28B382 +:107340004416723CB15F70356C5A1313471E499B4B +:10735000F1761AAEE3ED3495E7CDF079245AB7E72C +:10736000ABCF5D34FFC01776E65F1EC9708CDF7649 +:10737000264DD0E78174EF1B8C97FA4C56A61E9FC2 +:10738000CBB3A81CE0D26EA4770C2EA37C0BF073B9 +:10739000E9BE00AF27BD0F03278EBFBC1AF9CB7E15 +:1073A0005D394358026552543F57380AC2F9227E6C +:1073B0000865237DD3EB7FCCFA3A09F530B9E2D0EA +:1073C000171F17B146C6E749F6492FB4AAC2CF6ABC +:1073D0004B137AAEED6125D88AEFDDA8F4278DC076 +:1073E000B6C8ABCD5434D2F7A53C6FCE1DC0F26DFC +:1073F000710425D243C9253F4F3BEB774D03D8FE9F +:1074000095CCF437F3695CBA4117DF574497F1BD67 +:10741000917DE4BE79922083F83A5B76F2BEA79C18 +:1074200014FAC7AC6FE4F02F1F257D33A0C74F09B6 +:10743000F4CDAD645F0D7D0372E97EC2CFB417F465 +:107440003053D733187D301D261FF2B53A13E89715 +:107450004AA84D45129F57BF98F988CEFED97E01A4 +:1074600012A3BC17E528E679B33EBA283D5E1F9DFE +:1074700086E9D9576851BC94DDEDD96F8FC187A1DA +:1074800087A27809B29C98DF2381E36C5F2D21FDF0 +:1074900071484E25BD3303F98EF33FAFCB49DA6710 +:1074A000C16F13FFD7F55C9944B8DED15BE520B11D +:1074B000599E236B7F46FF59D93B2F003A5C48DF2A +:1074C00019EFB58243738E267A58980EB28AFD98CA +:1074D000F70FB64BD5A4179169A9F3C69D5B1F2C76 +:1074E000CFB1F17B76F416A7128E9C80F12DF2AF0E +:1074F000A247623FC18C6B338E5BF105168E1B6B0E +:10750000D99F90A5909E77888F4B8B0253D84EDDE4 +:10751000817138F9AD83BD68B7B0DD81769EFC948A +:1075200056E76CDEB7B15F637D77A4CCCC86D2A181 +:10753000FB375AFF1732043362FA4AC44638F67FE3 +:10754000618BBB6ED0F35C7430E83995E829FD9F00 +:10755000D3F35BE91AE3C14CD7FFE9FE0B96574220 +:10756000A2BCC0FF2FFB9F06BEDFF58B78EBB51CDE +:1075700077549F142CAF9697201D26913FEE89EAF1 +:107580000707FE237C8DEF6E677D5389FA86FCCC5E +:10759000FC8610EB97C939225E32EB8D4B7BE03ACB +:1075A000D28F53C2E8975E80FEF88CFE2797F3389F +:1075B000C174CA43FD71FEB20EBC345E838C1A7C6A +:1075C000CFF83EC543760FFA3212E605CC76C3F00B +:1075D0004B0D7FD43CCEF0470D7BD2A4D3E170BAE3 +:1075E0002F44EF07550D90BCA15C851EF330EC35A0 +:1075F000F2178EA4D5EEE4FBA343018E038A41A5C6 +:10760000BC0ECA2BFB61150E67581E3F543E934DAE +:10761000721842BA509E20E0B404474843D781EE26 +:107620007680FC3E7C80DF5F9F2EF2A50538869930 +:10763000D604ECFF178C071FD9DD82326C719F7F57 +:10764000D2ED4A9F3EDE6871DD07D329FFAB40C013 +:107650005EF6CFAF9796985F46F4F1FE91E67154CF +:107660007B79FDF92A78C88FCF57429207DF9FDEDA +:10767000A049679348869DC6F9F26B34B697F9C363 +:10768000B14FE3C9DF49C097F7D2ADBCDE4647FF33 +:10769000011BD2C15FD35CEDB244FD74BBD5E7CD15 +:1076A000A7FC51B7F0D781F27D9C3FF648B41F6527 +:1076B000A6A08F5F15F1951354D69B153A1F2B1C6E +:1076C000359CDF219B689F3274DF92E6E5C179F338 +:1076D000400B4C89EA5523FEC16980DE63D6AB03BB +:1076E000BB5FBF2880F2F8D6FFFA3405F0FE3B4AB4 +:1076F0002485E871FCDE9753BC488FB7EE15F1CBBB +:10770000CD26FFC89621F8539751FB15D1F59695D4 +:107710005F4D8AD52F707716CBC56D419982E1B345 +:10772000F2B3EC8964CE3D1BFDC650465CDF90830E +:10773000463B3427F2AB2FCB10F1D96D1D9B6C1457 +:1077400047D765F85233F0FDC775FFEF78570AE762 +:10775000038CF52CEC9860237ABFD36387302BC859 +:107760003EABE0B3F76A691225EFC59F799D07F636 +:10777000E4DB2C38DF62092222AF05077E86FD0F8D +:10778000726458E319BA8FC56FA936CAB72F9E0124 +:107790009100CAD5C23BA4D577E1F8853E27797020 +:1077A00043F6B920101FE72FD1FD955B1FB09AE279 +:1077B000A4E603942F5B84F3503CBBB83DFEFE600F +:1077C000EFED077E4676A0DBC67660C979E2A7F2C8 +:1077D0000C3DEF3209267F5D42FE4AE98F4AB573C0 +:1077E000EB25C35F39BE12083CF0D7950E6E4FAC47 +:1077F00054B9FD4AD7D7CBBAF71E605C2B7D93C82E +:10780000CEEEE87D3FF9462D6A372EDBF4E9FE9F88 +:1078100061BF9CF65944FA326C253C5EAEDB8D2587 +:10782000BA1F52FE85D96EECFDC3EF28CEC6FD6FA0 +:10783000E588EBC2FC919B40F92C960E861D31D356 +:1078400063B0B724997072BD41173D1FFB3FA5CBB4 +:10785000B99E6B9411D709F487214F5FE979874569 +:107860005BE6AECEC3F7B7EEFEB0B05FE8A5D7C01B +:107870001DC52B2A7AC6DB1280C81AC4A7AFE7073A +:1078800007884E07086F95D4BF88EFE754217E51D3 +:107890006E97F47CF4268C67F9CAB1E4501BCEA134 +:1078A000F8D28C4333FECC783B65ED2F24FD60C6C7 +:1078B000D92909E627DA577D8638BF58A479675356 +:1078C000BC8B666DB5CAFB11FAEFB8D27EE0872497 +:1078D000B75B248E0F1B9FE97C9AF4D1D2DFFCC4E6 +:1078E00045FAE823A5DD4DEF6BD87A9FCB4B7A495B +:1078F00009B8E8F98F82422F99DFB747A7A3712E05 +:1079000070D62E3D10597D0FD2E30CCA33C96F5388 +:10791000D7DF56DF437186D711A1B8F3B8D23F9BAA +:10792000D671DB0267738B87E2DBF87D2F7DFC2746 +:107930006E8DF3C7817C9D7E1CAF366DB17AC238E7 +:107940006FD32BB2875EE38708EFCFFCBC3FF4BE5A +:107950008DF4B76A8148C1B4A1F7918D36921B7F2F +:10796000D7DA4F6417B5825F7EA273CC3943BDAEC0 +:1079700087CD387E2A23FE3C01E9C3F9D400AE8BC3 +:10798000F2471014FAB8F5D7EBC7BF8BEB3BB1E564 +:107990000597541A7BAEB08AE93618BAF5970ECB24 +:1079A000B9F17B4AC77BD46F09F2735AB7240E83AF +:1079B0007A44DB600DBB286E6BD864F504F072432B +:1079C000A70C0EB25F47EDEC3734747ECAF86C90AA +:1079D000BC1169026FC325C5F811CB3A3F984DFA27 +:1079E0007659AE0C3528524B779E16E3BD1049C22E +:1079F000F1CBB6BF3BFB87D447BC3B12F0AB2AB4FC +:107A0000D726E4C6C4AFD0BBB3C91F6EFDF5E7CC23 +:107A10008F8FF648905D34F4F9FA4D1FD8C89E9CBC +:107A200040C664A4097A91DDF087E405B6D444FC2D +:107A30000B5FFDDB0ABECFF9BFF3F1F1213A6BCB4F +:107A400062BC3FF55B5C47FD9B764F0DBDF7A9DB44 +:107A50005D8038F8506916B8FFF97D6EB2C3F5D66F +:107A6000805BE5565CAFFFC59D8CC72587EF748BA7 +:107A7000F8C69B2BF245815CDAE7E28DDFE57DD627 +:107A8000818FF158FF73B996F234A715A8DE9E4096 +:107A90006E26654AFAF9DAF7C7DF23CE0380E2F3F0 +:107AA0000FF5BC69E088CC7E9B1DAE4D9D1B937F7E +:107AB0004ACA14F63800C1B7E95CD58FE695CF41C4 +:107AC0000E9F9E4DF3DC51A434D33911EE3FA0D369 +:107AD0004BFA9AF302A029317E56D5E12BB2292F19 +:107AE000668741DBBF56B05FAD91DF13F31CD3ED6A +:107AF000C3CDF661D2A5D8BA13E74D17EBFBC0BFD3 +:107B000023108327FF131F329E00ED776A8EE83F14 +:107B100046F2B8D0D99C8A74FBEC95F76D74AE151B +:107B2000C0FD8CA0F5F67DC07DF0646934DE98DF81 +:107B3000DF6D8F9E07925C6FF9C024D7F1F7D17E7D +:107B4000333DFD90AA51DCF6A12D329BEC7900DF8C +:107B50004BF50575EBEC71E78D51BC98CE1775F9B7 +:107B600034F29C4B4CFE98D19AF5C284CC78BB067B +:107B70001BB3129E2F9AE390066BF057449F86A387 +:107B8000768E5F1A3A85FCA1431D1981F2F071C708 +:107B9000FED76EC47D7C1CB266D6F0DBE2F56DFDCF +:107BA0000E945F1C2F23BD9358DF7ECEFE94618F11 +:107BB0003E76E2C57109E416AF27945B27B03EFB21 +:107BC0007FA567979C43CF7E2F73889F908AAF8154 +:107BD000BF3EB9EC62F22FCCF435F4AB596F9ECEB8 +:107BE000D012EA4DD0EDBC41C7A5DB4E326ECFE4DA +:107BF0008AF3A6A62D7F633B86648DD811B74DC14D +:107C00004FB87F1FD931EEEF9D278D4FB4EF787AB3 +:107C10009AEF5F4CBC65B989DC4C74962D2E8FC8E9 +:107C2000CFA97C9EDF4A7693F4B4A602F111664296 +:107C300088FC0EA9E78F7FA3F799E38AC04C18DD73 +:107C4000CCE7BAB036B63E27A4E8F51481C4F539BE +:107C5000ADB6E8792EDD3FD779EE715DCE3D4E951C +:107C6000CB11AC999A9CA8AEC45365491847ACCFC8 +:107C7000147ED608DA33B67FCAD4C4B9BA5CAB274F +:107C80001A45BC443954D67F692E3E0FB6EAF51921 +:107C900038730E9F1F245B3E4592C0CE7573E72854 +:107CA000941F2EB7DC5E82FDE7D72D9AA3207E3C81 +:107CB000D32C3B8BB17F68DD6271FF524BB915A1AC +:107CC000FF78A06ECE2CCA1B58DEFD29ED4F59A5BA +:107CD00000D58F94B47DC0FD3BACE2FCAAE9D95D30 +:107CE000F5F4FE26091981F46F73859AB98E210780 +:107CF000D455943CD676FAE8FEEA5C8CE7911FFBFB +:107D0000527DDB33C9AE38C22EAD98E24AEFFAEFAE +:107D1000E17DE588956242DCA7C8838FDD392D8738 +:107D2000F4EEFF85F7EFCD9C78EEF79FD871D57C08 +:107D30001A3F560655C6F9CA14AD8AFA768CAF2991 +:107D40006E33F850A608BA973A6D1CCFB5A5797373 +:107D5000084F7FCA34F875616DAB55F8A572B2C093 +:107D6000819C6A69DE8EED6B3AFF5FD7E9417F94B3 +:107D70001718D89DBD99EB56205248FC95E5CD9D2E +:107D8000448F488B029B29FFBAFBF14EC2E7EB36CA +:107D900007E78F6E487DD07A092EB9CC51783B81A8 +:107DA000FF4DA9E34E6A7F9FE57B2F53D4878569FA +:107DB000DE1B6F96C5BCCEE614B29FE045B91279C2 +:107DC0001AF6DFC18772456BDE8772358154417CBC +:107DD0009D93791D726A07AFE306BB58C7FC6071BB +:107DE0006B3FAE63823D7811C557F8FE41C2C18D2D +:107DF000E86E119E0305D04B7C7BFD964B3789FDC9 +:107E000015B0BCB2FCF3F9FB89A7683E3FCE4FE743 +:107E1000A87EA99FFB3B15871A50857E5F1093773C +:107E20007B16DA5F2E15F9FD568A3BA6E971B191F2 +:107E30007F33EA0D26F7FAAA9CA4B0E51E99F4CA8E +:107E400069F4D7488F99F36E534CFA775AF7C7AC59 +:107E500097CF771E9892A5FBBD799047FB08D17903 +:107E60002039BCBA9DF4D0796002F98F390FCCCAA1 +:107E7000BA80F3C03B33455CA1519D1CEE631027D3 +:107E800026BE0D1E5A0865155C8FD00C69E7B6AB8F +:107E90005D26FD6FE07CDC2BEAADA4CFC6BD02B74A +:107EA000D07EAFD0CF4F068F03D7034EE877707DDB +:107EB000A0B5D71A0C4A31F528472D5C8F32089EA1 +:107EC00020D7AF04EC6A80F5E578AE3F693BAA9F06 +:107ED000F7EAF50CE58264FF743D84B9FE61AAAB54 +:107EE000525E50C1E73320550EAD7F982ADF2493B0 +:107EF0005E8143829F67EB20E45299F6753A0C400D +:107F000021DAA45762F88DFF4DCE0CC85CFE742CAC +:107F1000FEFA54132ECCFCFF4E966E8F75FE9FB367 +:107F20008EE42391579B00E3B98EC46AAE2379C3D4 +:107F3000C2059BD13A92F220C9DBA41691373E5F6D +:107F40001D8FB94EC75C8793EB8BA7537EFD2571C0 +:107F5000F72F6A2E8BEB5F7CF7D4B8F1456850633E +:107F6000FB250FCC891B3FA2FDDAB8FEA80D37C652 +:107F70008D1F135C18777FEC134B13D6BD1838197F +:107F8000175A1E777F7DF253EF13BEDA726595FCA8 +:107F9000F94BBBEF31D5C54C675C4C35F2F03AFF7D +:107FA0008DBA3A2A03233A4F44FE3F56447ED3BD4E +:107FB00055923614079E7080EDF83F8B83874C38BE +:107FC00030E4FF7CF99B75BADF2327154AE4E77894 +:107FD000D1AF4A9A4675C4E2DC1EDE12F52A9F270D +:107FE000FD83FD224D7279E0327AAB2A911F7457DE +:107FF00095C67ED05DC30AF752FEA0FFFB2E8F947C +:1080000037B42ED45C079AEEF04E012EA115759070 +:108010006DA8E8B95E77A683FD8C872C965B6A63B2 +:10802000D6DF9125F44F4796B05B3FB385B6931EDC +:10803000501CA0B6E48AE7A9F801A8B207F9E2CA81 +:1080400000511F0647D7CC9A4EF6B37FB49646F53B +:10805000B3D8BF082F2B41B62737B62A1CE7AD4A45 +:108060007E8AED499922ECC90459D80DB423BFCDBD +:108070009A4876ED5EABF0B30256E24FBE0302AE15 +:1080800032B6AF7C4E9C0699D2F252AA4F3D6BB7E6 +:10809000B4AF114CFB974EB3109D0617C97C1EFC64 +:1080A000122D09D73B583F86EB9C07CFD6FF69A915 +:1080B000145F0F2E7AE4E49D1551B93C6A4B1CE71E +:1080C0009D2FEF56BFE991143A47393A1AE2EA3345 +:1080D0008E6509BFF158962CEA13821FB8894C03AC +:1080E0008BFF6B242DDA2FF5AD76E290FB377CBF4A +:1080F00096F862EB9A1BA0BCA691C73F1B07F6CC73 +:10810000E0FA6D235EBAE17591D7BBE1BFE2F3D629 +:1081100027B3AC7CFF24BD8FFC9A5EDF44E2DB35E5 +:1081200024109C57F64D24FFA056058DECFE7CDFF5 +:10813000823B0F617FEE8312FBFB749FC65F5B8007 +:10814000F606EFBF0C9E5777E1FAFE9E25D6330F59 +:108150006AADB4CED76E6E4C213CBD9E26C6472478 +:10816000D036C7CC778D3EDFEB372FDB45713ABD7C +:108170008FDE4FEBA1F7CF55A198FAAF81EFE4ABBB +:108180004543DF7B1D78AD7ABD9795EC6409043BD0 +:108190009F26BD7AD0E25903DC8633D82ED9D92E5A +:1081A0000DB4449E5A81EB7C67E9DF764948D7B726 +:1081B00017447EF5345EFF970D3268888B4FD37D70 +:1081C000567756944E47177D9A42F4447F65EB4F9D +:1081D00049EEB6D93D54D7F1E6D26D2363FDFA548A +:1081E000F78C616EF2AB2A2FEC3CADEAC9298CBF4B +:1081F000E55B05FE96FF7A5436E16C79CA59DC8955 +:10820000FED6123E279D2441C2F878CF4AF1DDC246 +:108210000EC4998638DBF385A82BDF7928BD9CD660 +:10822000A780EFE2D8FDEC7CE9C6B15CCFFB46E667 +:1082300005AD93643680FAF7065695002FEA723240 +:10824000BF27A35CF727C7D2FC37FEEED727FF93E3 +:10825000E8B27BDBD61FB28C5C181D86D6D1AADBB8 +:10826000583F197118D5BD529CB6DFC276F20AF993 +:108270005E8EC3A84E83E3AE61853C1E158E6A15E3 +:10828000FA4D7C27817E70AB87EB3D595EEF5685BA +:10829000DF62C449B2C593A3888F0C5E98C6F317FA +:1082A00003E5C75C145819FA0AFD08976CD1F51557 +:1082B000781D189F8ED5F559B57BC2556DE2BC2649 +:1082C000CEFFC47E554702BFB316FFB1DFB9D1D789 +:1082D0009AC47669A35C4A7E87D711263B6EF63B2B +:1082E000A7C1839C0718E27F3EF7D70BF23FFFD56B +:1082F0001DEF7F5EA8DDA9776BE2BC77B4D073A1D8 +:10830000F0308E73F0AF9CE46B64B6B04B7D1463B9 +:10831000519D9F746AB403E5B3C15DBEF6019449F3 +:10832000C770411FEAB7E2FF97689FEEFF9AFCC053 +:108330003E85F937F8DC25DFF81D4905CA2119FB10 +:10834000F081A95CEF3CD02BE4A3335DFBD3348AEE +:1083500033D0CFDC8C4B4C52FA6D6909F6F334E91B +:108360005F9207B7B0478E6E712EEAD0BC40FA25F7 +:1083700049552750606E8CAF730BFBD578E0CD422A +:108380001BF2E7A4E5908BCE571A76ED70E176E10B +:10839000BE0CDFFD84EF65478F4C52B9CE6D532183 +:1083A000C5DFA1F09199EC9F552369279C7B3FFE87 +:1083B0000DE5F41102346DC8E0760CE555F0923FFE +:1083C0002CF679AABB353D517EC0FFFBB7F6D17EB6 +:1083D000B7BD98C47ECBB6AC3E9683C05C80AD483A +:1083E000EF27BF18CBF32127781D97D46A12D9FB4A +:1083F0005FEAFBD9A6C797A7BE90799C31EFB8EE8C +:1084000019B28AB82A0DB7EFE33AAE1EBB46FC4D4F +:10841000DA02823E3D495C17E6DF73A5883BD3C490 +:108420007974E7B0C8DBF49EC86EBB4675AA496A8A +:108430003BA4E3FC9D366167C720F07738A3D78D56 +:10844000F725F5ACE78F2010175C8F97A4B4C3B75E +:108450009CB1F44FE1F586DD02579DC3C21627D9C2 +:10846000098C9536F3BAA2EB047EAFB1CE31EC178E +:1084700077DA227FA17C3BAE4B255C8C01B14EE8C4 +:1084800019A591BF92A48A73F52455F304A4A1EB16 +:10849000F28F87203A07F0D02A382BE75C47382C38 +:1084A000DA77A02C7416EB7E4C60F1DA5905317D39 +:1084B000526495D1E75F75D7AF6D2BA07D093BA8BE +:1084C00028213E1F77CD0795CEBF93142FC749496A +:1084D000F3406B417E253BBC7CDF8D73B44CE17E69 +:1084E00098D6AFD27DCACBA4AAC97370DDA95FA606 +:1084F000F2734D7D56AE3B6FF8C775A9A5B8BF1393 +:10850000967D2B3AB0FD784168249DD356A6FADEBD +:1085100021BC3E736CE1DA7138FEAF9D564F0DE918 +:10852000A5FEC08FE9DC7EE993568DECE2FD6F0C71 +:1085300086BF26FE3E2BB15E1CB08AFBD8D75AF010 +:108540007E53CF87363AD7BAB2FB5D1BE5BFEFC982 +:10855000F61D27FB56D9DD5245749B02EDAD94E71D +:10856000447DC8F512A11CA12F065F19B9B9258653 +:10857000CEAE6CFDDC2BE2BB98E4A64797CF3DE482 +:108580001F61BB4BF7D376EDFD97122DE6FC34004F +:10859000FB381FB80A9EE3BA4EE3FA4050A9261CE6 +:1085A0008D7DCD718B3706678E6C5DDEF5F7FD3CFA +:1085B000DBF70F96DBBDEFD95CB87FFF9F43856487 +:1085C000AF42E8CF7D531DA9DF242F67EB8E8E03CA +:1085D000EB916DAF75B3FFBDED1E358DE41ED70F6A +:1085E000A9D8DF85FE05C9D1AE2221772DAF9E190E +:1085F0004FF9E233BB975D4CF48AB8AD06BE670E07 +:108600002339DA0EACC70C392C2539C4A597AA2218 +:10861000DF534AF826B9B3F5CD61B9DB6501923B6A +:10862000C437E31DF1AD921F52AA22DEF9F9512C95 +:10863000C79D7D472EE17A7624EF8809D4B730BEF6 +:108640003AC37382123E5F610DEFA3E72BF0FD2D5D +:108650005A542E2BA4F8BA9E3AB7A89335F4E3EDFA +:108660006EA1EF43A3B5540F8E4F96E538FCC7D8E3 +:1086700049D1D7EDE80FD6FF74ED3A9487126FB960 +:108680006512F93B2FCA6C07F6E87EF2F23F4CBD4B +:10869000A6435C67FB19D671B14FF79B9F5B99C3EB +:1086A0007DB20B1AF26522B6DE72AAF76EAEA25444 +:1086B0005C6575FB7E6AA7D686AAE8B870FAFCBE30 +:1086C000FDE21B37EF58C25BD7BE6F8FE53AE9A3D7 +:1086D00076A0EF38BBFE1E79FB49DCFF8A3D486F70 +:1086E00048E89730DED06233FECE859301A9FFEAD9 +:1086F00069A897AF59FFF8550A1AF4260202EEBF8F +:1087000066FDD6B5E8BAC0ABD9DE6BB291DF5FE5E6 +:10871000F8AEC946BA0D1CFEBB9BECC9AE57DE7362 +:10872000911DEEB279C712AEBA8A318E4880C7E980 +:10873000D9A26EA7E21CF526CBB3C5F9D6C800AC0A +:1087400025BC3475C96A90ECB4B7EF6AB21B7F419F +:1087500052525EBB6E46C045F152FDAEFD5CA76F46 +:10876000C4D38B41FF936F9A4DF43F9D23E2E3BA4C +:1087700075D6B8F87614846D748EECF7399BC3C83F +:10878000927A93DF715BF726FE6E64E996F8E71A3A +:10879000C84F4108359C273E5E9EADFB29255042BF +:1087A0007E0AE286F324915765CF66E0FAAA5EAAB4 +:1087B000AFDA6611744A76405B6A7AD45F1993EB3C +:1087C0005D4272BE44C767A75EAF14E994F87B8A26 +:1087D000314F887879EA716D137F2715F0729D5EAD +:1087E0003D2D00D73D5509F0FEA7E6944000F75F08 +:1087F00089EA99E4A5AE470A323DF5EF5E14FC27FD +:10880000F2451B65FECE6FA3041945346F84E9B3AE +:1088100054CF1F2E7B22FEFCA261C3E103E42A3564 +:10882000864CE7413A7DCCE73B3BE87F129CEFACBE +:10883000CFD6F308855018F75D5EEF857D97F7B1C9 +:10884000FEBDEA117D7E63DC2E5D6F36E9FB6E08AE +:10885000CA62DFC80AAA8FBE5587891F3C4CA7464B +:10886000C409E1001E14FC36EA199742AD8DEAC82E +:108870001ABB5A0ED0F95B9DEED79AF18404657A43 +:108880002DD1EB86EA37C6DF5FAAD365A9892E4DC5 +:108890003EC9B43EE1775FE8FA50735D4F3858DA6D +:1088A00061E57AEED37013D75F35766DE2F5D4E9E2 +:1088B000FC1BBADE00EF6709EE87E4E942D76BE6FE +:1088C000DF9F0C9C5F0297C4F1AF3AE382F8570236 +:1088D000EA32DADF60AF886B077B8B392F61E0C546 +:1088E000FCFC6CDD8FBE7283F0374F765725933FCB +:1088F000307048F14888FBF2173F73D1F73765BBFA +:1089000065A073D2819EF2B501D4973B7B875FA7A8 +:10891000A11D287B5161BB51FE625930A988FA65BF +:10892000C9255C67A265501C80F3B01D1E3834FC5D +:10893000E552F6D367555088DA72A82C99FC859DCC +:1089400020F21BD28B1519FD3176E5C36C91DF58EF +:108950009DF3FE43A4A7AEDC6EE57CF095D6C84B34 +:108960001487EDEC553C2DD86F7871E1AA24E2F71D +:10897000AF250FB9DD07FA9667D2794D638F55B5EC +:10898000F37AEFDC47F7031D9267048EF7EFBE62C0 +:108990006C27E58936957B88BCC6FBCAD2B447A84C +:1089A000DE157293396EBFF2222BDBD71379C9FF24 +:1089B0005183FB5AEADD349BF4F089DFEEE4BA8A96 +:1089C000814E097224CA23EF7F8AEA7D4E3C7DD80E +:1089D00046E7C1555D87B96EE35CF6E0641071C788 +:1089E000717BBB8DE29BC64D46BF9FBF47A9D5FD9E +:1089F000A8A62DEF727F29C50184C78D7250C3FFD1 +:108A0000DDBFFB193E1F6EEA10751F67EF6F91F80F +:108A1000BE81F785BADE5A061AE37D998177BD3E9D +:108A2000CAC0FB69A8E13AAD651D0F33BE17EBF86C +:108A300036D74D0134DB4A3385BC52BECDFCFDDF59 +:108A40006D3ABE6F3B0FBEC7E6E8F81E036308DF52 +:108A50006766887ABA33878725D3FC670E72F6F586 +:108A60009B70CE76F790EE170C862D5EDBA5D1714C +:108A7000A7BA3FE5EF10FD87066D547732BBE713C9 +:108A8000E6474DCFDE5944EFEF80AF81E8F79D9E7A +:108A90006495FCE09A7EA1CFE6F4D8F97CE23B1025 +:108AA0006A233E0FEC79BC2D9D70F32B811B43CFC5 +:108AB0002DD1E97A55E9F76753FCBE54B78783BDDA +:108AC000B7CF66BD33018AC8DF9BA37FE73D27A4EC +:108AD000EBA18DF174A7736AE25B538F9DEB4DAEF2 +:108AE000827E1BD9B3AB74FB69B69303B9C9CCE7DB +:108AF00000DAAB1138BEA1C35447A9F4F37A06BB20 +:108B00006D7CDED564B2BF97E508BFF27CF1BD99FC +:108B10005F0B72747BA2F3AB2622EA18E6BC227BC1 +:108B2000E8FCA137BCAA94FC05836E667EF56A2535 +:108B3000A9DFF47B092FE97EBED1BF46FFFE2DA43D +:108B4000B63B63E3F6833916FD9C33F8D372DCE75A +:108B50001D12F4110E31BEB9A64C4A18DFDC938306 +:108B6000FAE38F05B73E382136BEF16E1A49FEDEB4 +:108B7000FDA857CA2BB87EA78FCF0B95F61A3A07D8 +:108B8000F377583D14D7F8BB65F607FC1DF6A00532 +:108B9000E7BD927084EBAAED91AE201C61DCB09A27 +:108BA000E69F4B29651C37B71BFD117C6EEEAC4F61 +:108BB000187F07878B7D0F2A5A76A238C2881F9AA2 +:108BC000BE10FEAA71BD09F5008D6FD2BF4BEBDA66 +:108BD000F7B7C2A2143AB7FDBC7001B64FE7083B25 +:108BE0006CF8AB11F4578B757F85EA2EEA04EBA085 +:108BF000EEB97B6CA4BF0ED00F5B50FDA4EA5B4DB9 +:108C0000F1B0EA83E61F91A321B5B11C35914C1157 +:108C10000E7749227FF3AC956A43A0E5C830AE0BCE +:108C20003CF59A388732CBFBA9857DAC2FCE2C70D2 +:108C30003613DE96956E5A9D4EF2BDE775D63763B4 +:108C40007F6B532D6A745F2DF4DD1DC7696D71FE56 +:108C5000F2A9EE561BE7A163BF1B2E1EEA1F359E2D +:108C6000278F75D0A45770FDECEF0E1C9455CA0BDE +:108C7000211D7F91174B2FDD1FEADA97C4F66BE0B9 +:108C8000B033487EFF5F753C9ED0F3F22D9532D312 +:108C9000C33245B463F73C534CFC257EF850DF6F7C +:108CA000DBF3CC255ECEA307451DF113F175D88DFE +:108CB000A1F83A6B83AE7E9DAEB8AE91F4BDB2B171 +:108CC000AE5D4ABFCB93408E24691FF3CB22C5C74C +:108CD000B9FE67E5DAD83A52DCCF2DA4F7FED3907F +:108CE0001725E2263BFC4E8EC6EB6BE911FCB5EC7A +:108CF000162DBEFF7A91AFB1F2FB87DC9F1968A0F9 +:108D0000FB678A92B9BE01BE08D4507F45B1F8FD19 +:108D1000801547968E8ACDD38124E271BF35C2F586 +:108D20007EFEC3165E9FFFF0A07BB893F4E2A659C7 +:108D300054477B95AE2F0E1427D713CE03F4DEECE9 +:108D4000E83C4B72C47903D07E73A2DF571AFB5DF7 +:108D500005D7321D56E9B87A4B8F73308EFA222729 +:108D6000411C752EFFF7ECBA75FFE9CC0CEDE5EF71 +:108D7000210ECA0E2A018AD777BE911424FBDFB2D6 +:108D80007BC93B140FFBDFB403F9212BF62C19C56B +:108D900075F83EDFA5A44FCEECB9ED52AE6394C496 +:108DA000F7A5015A5F0EF953AFBAC94F6ADCFD2A25 +:108DB000D73936EE9AF808F94FE82F5D45D7D18FAD +:108DC00061FC95BD58C1F8DB79A822A384160E9EDC +:108DD000649AB7F1A0C2758F8D072B5EA821BFE6FC +:108DE000C599EC3F19FE5239C5E3E43F1D1C1EE74F +:108DF0003FA5E60AFA0DEC4DE2FC8704C5023F30C0 +:108E00003C0E3F0D5D7F603FA301F55D2C8E8CE72E +:108E10004A72159E6754AE8E9F90E4657C6C176D08 +:108E200043F74EDEDF326B88F9DDD26115F73B4543 +:108E30006BD44907203D40F478812E211FE6D8826B +:108E400005146F3E5F14FFFB4446DB912BF209CF04 +:108E50001F15DF193F3FC3372AD1F7C6019829E212 +:108E60007049A77797B53AD1F7BC4FEAF3B93220EA +:108E7000EE5CD2687F922BF4EA1C9BC85399EF2FCB +:108E8000CC35EC0FACA5F398976BACAAF1FB2DB9E0 +:108E9000A877AF06E3CFF3EABC4C3AE7127135404E +:108EA000FF2CD287DFA53C3FF95F95C2AE1B79FE50 +:108EB000B91BE13E91E7BFC94A7AC1A82F99EB35AA +:108EC000FB5FB557D03CD7A27DA779AEAB8EBFFF75 +:108ED000DDF3F85D37E6EA767C248C1471853399EE +:108EE000ECC1E95EAB2AF33E82C3137D5F68E89F65 +:108EF000032BC5F9512FEA456A5BC6BCCE79ABE7B7 +:108F0000F71E7D2A8DF56A121423892FFFF21D7733 +:108F1000A2795ACECAEBBC38FC19FC3A497140E937 +:108F2000507EDDA9D3BDD171C2C6E79BD0FC804580 +:108F30003EF777492D633E6F23793AA97FF782EB9D +:108F40002BB4C7E8FD93B99FF0FD15332112C0FB88 +:108F50007BC7D8D9FE35CE92F8FCA0312CEC61E36A +:108F60003C610F4776CD65BE5C8F7CF17A584DBC75 +:108F70004675B906BF2FFF726096114FD2394E0B5E +:108F8000E19CF57426B78D5DEFB6F17925DA5DF2D7 +:108F90000BAFA98CE7DB28F0DD9785F76FA8963C2F +:108FA000684186F0FD869BE632DFAFD3BF8F391F65 +:108FB000DFB7E7FA36E492DCF70D5E3F0E49F4FCCA +:108FC000980F0BC9BE369D03D75B0C5C0F8F3C4DD1 +:108FD000E7659EB3E7E9FF783AF63C7DB8DBF71F1B +:108FE000B9A4572D5FBA2E019AAFFF17CB25E21314 +:108FF000F0F3E792AB2775B97A325715F9DD4C716A +:109000003E3456EF3F6F0D16F0F714A517760ED8C5 +:10901000F2EC1FC7939E3BB5F7E0785B0C5F4F2CDB +:1090200047FD40F666F77EFEFE308A3B8B8E3B8521 +:109030005B49BA56B7A3F1383C413824FDBC7DFFEB +:10904000D5143F9EECBA2E53D262ECECAE975D2362 +:1090500062E63DA9FF2E06C66D23BF9B12BBCEFB69 +:10906000C4797948CC87F23FF2BA71B1F75B753CAD +:10907000F7339EEF1FDDCCE7F4069E151078367EA1 +:109080000FE3EC779536E0EF1E037BEC5C5F31601D +:109090008D14A6C5C8CBC73A9D314E930B32999417 +:1090A0005CEF3A19D655F1390106EF6BA7D0E77797 +:1090B0002159D4873673DDE2F466F0106E25D8C8E6 +:1090C000FD49D5E2BC7C2AF4C9B4AECB20C2AD17B1 +:1090D0005485DA995461866DA52324933AE9ECDA34 +:1090E000974CF80ABB95B4BF3844E96922FE45F7AE +:1090F000AFC05F0CBCE2607482127EA7EFCE137526 +:109100000E9E64218F9193E2774FBE05FDBCFE69F0 +:109110004A1FAF3745D3D2E9BC64FB73CB65AA7F46 +:10912000D9035A84E4CC93D1CCF9B7C80C086D4E5E +:109130008BEEB792F6AB46FB53E78385F62B418760 +:10914000D87F33A4D3F9D81408F37B2EA705E37E88 +:109150006780A650DF9157A4D359C46F557AFC6637 +:109160007104B8EE27354FE03A5909CAB9159CDAAF +:109170000E3D4CE73325629F93F13A9FE3348B75A4 +:109180009FB5D77942DF4D8510F319EA417D817F84 +:109190005C61964AF492C26E0BFD9ED885D275C072 +:1091A0000DBC7ED7AD91533FAC889E7B797AB2B926 +:1091B0001EFA41C91291695D8E02510F1D86107F02 +:1091C00097198EFFBDB392BC6B8BF268BF3EF11D49 +:1091D000AEB9AEF389E066AEBB991F40F2D03C0554 +:1091E00000C7DDD13A006B7190EF5BE99C5DE53A19 +:1091F000D3728A177F9FE52BCACBE27AD3113C99B1 +:10920000129C589B12C53BAE8C7F7F271952DA49BE +:109210001FB5EAF5B401D5A5D73315F23E34D4F322 +:10922000FC23128AA8EBBEAB4AD49FDE356C0FD765 +:10923000F9F64BA04AF974FEBF87EB80E987E1ACF1 +:10924000F9DF70FE9FA9FFEE43B1EF8DC925BA92F9 +:10925000C7E75A8FA570FDAB32D3AB511DAFB95ED6 +:10926000BCA46DE203FD1C971AEB35D5892B1EBEFD +:109270007F97AE5F5B1DE27780A45576559A4EDFEF +:10928000BF2FE7DFB16A25D7A082BE7B5FCECF5369 +:109290001D33158146527DDF257A997F970AE13586 +:1092A000F83CCD9B3A92F37D89F831DDE087656823 +:1092B0009D14F2E166E2AF51776BD4DB122068DFD8 +:1092C000C95EF13B782AE2847FF70F9762275C7AC8 +:1092D000CDBFE721EA7FDB74FAE3BA9EE0BA4F879D +:1092E000F84EDBF89ED74C3703BFFF0D047C0BCE46 +:1092F00060530000000000000000000000000000BB +:109300001F8B080000000000000B9B29C3C0F0A3C6 +:109310001E8145A451F9E8F82C9A3C0B0303C34F76 +:10932000209EC7835F1F2E1CCD82607B8A3330183E +:109330008932301803F14C209E05C43F80D8408C00 +:1093400081C110888B80EC6220F6016207A0DA2FC1 +:109350001C0C0C138419186603F1326154739F328C +:109360004268252E06065320FEC784DDFEC96A0C1E +:109370000CDB7510FC385D068635FAE4F965140FD0 +:109380003DBCCD1195BFC70A95FFDC8681C1DE09C2 +:10939000C1DF6B459AF9D540BD354EB8E58FB9A10F +:1093A000F2F779A0F22DD1E41787416800E6955CC9 +:1093B000CAB8030000000000000000000000000028 +:1093C0001F8B080000000000000BED7D0D981C5560 +:1093D00095E8ADAEEAEAEAEEEA9E9A494FD293CC1E +:1093E00040CDA443069884CAFF04265033C130AC54 +:1093F000A84D94ECA0A89D1F312ACB6B780A01C11F +:10940000A9F9EF9924A4F3F342F89134D12CA0AE3A +:109410000EC87323B2CF4E88BCE0DBA711D12F6AF0 +:10942000F01B621E4FD45D67D92F4BBB06F3EE399C +:10943000F7D64C574DFF4D02ABDF7EAFF3E1F5544D +:10944000DD9F73CE3DF7DC73CE3D7547264D247608 +:109450000D21E7E047CB3F780921CB264BABC3C8B2 +:1094600092A5B4FC0A31FAE8A3CBB56C8740CB05D2 +:10947000EA9847D009B9229226C443486CF431E2F5 +:10948000A1F552F532196924C4AFAFAD22EA64BF29 +:10949000EEB2AF9B90ECFCE2EFC523C3513D44FB21 +:1094A0007B6A799749FB493DDDDA65B64CBEAF83EF +:1094B00041297E4D8462534BC840C35EE28910321D +:1094C00044C79E4FFF53EE4B90386D27678789BE88 +:1094D00000EA55637DE5D9E39EF5F4F99097748D24 +:1094E000D2523964658314EF85CF6B8B454A8F5F09 +:1094F000323DBFA5B03FEAC95840477417F67B8696 +:10950000D20543BD5BF42C017A281D6D15D2D356CC +:109510008C9EE72D0BE8B9E290BE289F1EA59ED138 +:10952000A3D4F7E23C9D89527A1A2F849E7B909EA9 +:10953000214ECF908B9EF7717AD6D9F4D40D223D6F +:10954000830D941EFAC8779F45E2B4BE02F484A04E +:109550009E939E41A0A7A5003DCA9F879E4F72790A +:109560004B023DCBCAD393047A6A2BA0474D138D8F +:109570003EF713C11C6D998A979FF371C1B3E9A897 +:1095800045FB1D7E5BC479A62B32BA76C164BD3122 +:109590008ED7F71A07A363205FF3F64609ED6FB87D +:1095A00041C0FAEE7E1F2232D6AFAD377BA0FFCB93 +:1095B0009E74F63FDCC0F0B5EBFF139FC77F2222FD +:1095C000B6AB51E3C3000FCFFB1649C038DE74546D +:1095D00083768DACDDC0BCE55D636AA1F68C9EE14F +:1095E000FB2D9467257B0FF2EB730D69A253D8FF17 +:1095F000648200FFE528C3C76E4FF122E44A20FBD6 +:109600002ED364F811329BCE937557D6A2E3C5D200 +:10961000B72B71CA8FE1BA5E05E84EE9BBBA406F5D +:109620009D89C9446C04BC0AF3C1968B6BC836A5EE +:1096300089CE67DF2BA23142A6D6B340B86A276134 +:1096400049F5906C33C1DF3902F42470FE07E6ED72 +:1096500045BA65A06B01D095243A7DFE1C971FDFAB +:10966000B31601B952742B6A2D983A4E0AF8DF02EC +:10967000BDA6A36BF3E8FFB93DBF745E5DF38B7CC1 +:10968000798898590BF8E277CE9B5DBEC4F97E4588 +:10969000BD85FC2D37FE54FAD9F87F4F74EC87282E +:1096A000E9683C3489CFB077AC17E49AAE49E3203F +:1096B000ADB2908ED39EC76FF77813744A69871C3A +:1096C0007F8BF369D83F7E24BF3F373EDFE5F5BE91 +:1096D0004B342C6DBA161E62E394EBFFC7C0E25AFE +:1096E000A8EF5A5792E5E0FBBDBCFE15CF3BEB154A +:1096F000E3CFE727F86345411EEDF5083F732621C8 +:109700005C64F0A72E27E452F83FB4C9EFD78FDD91 +:10971000054BEB1791C419E8E73692B8383097AE8D +:10972000176FE20928AF95CC7F83E7B495F6FAE589 +:109730005CEE44D4036C3CDA3DA1FD87787F92D087 +:10974000490895675F2BC98C50D4DE239ECC0A94C0 +:109750009FBB0831666979FBFA29B6AFAFD432AB4B +:10976000613FBF4AA284D0F1AA88E68712EA6769FE +:10977000BDF032D5A023111FF94855BC80DCF89705 +:1097800012CB5F45C76F951DEBC26F2608E8855069 +:109790009464FD614234211441FC5790150C7F5DA7 +:1097A00080FE6A24BD47A2E388318F71803EAD6A96 +:1097B000232B37E4C9A12E30F9ED89793C40D7201D +:1097C000D5FF3EBA24C30D74BDC37A88527BA380F3 +:1097D000DC4EE8F79C48B23368BF39816497505833 +:1097E000252B13B45DDA47569EC6718971A0809C03 +:1097F000AD13D8BC0AB1F173E7D02E2099EBD02E6F +:1098000048E33A96636913F601C50C1B3E98F6B31C +:109810003B985E93880972521D4B67ABE0BD7E4951 +:1098200023E03B2B9624AFB5B0F2541EBE8A6A45A6 +:10983000D17E6ABC44E8CDDBC70E53F93995276F5A +:10984000A9FB991D30D038C8F5CCA7507FDAEF3F7F +:10985000C6F9248F5164802E5DCE340953E53A2534 +:1098600014D6131B39BDF0BB76B9535EA5995C5E67 +:10987000E9103E89A07C0D3D4532802FE5E491F54D +:1098800014BEFCA84246A87CB590E31E909F856458 +:109890001C4B836822948B8981E55212C7F2F7ED45 +:1098A00054EE69799B49E5BD09E5FF2601F68986F5 +:1098B000C4FC307DEE8F5957C2FE42E57F1D3CA7A8 +:1098C0007222803CD598A4E07E592DB0F5BA53D2CF +:1098D000FC506FA749503FEE11FA2CD82752DC4EAE +:1098E0004AF989631D3FC0E94EF1B23A96206330D0 +:1098F000BF745E40AF1F6EBC15D7B14F62F0209DA4 +:109900001794BB556C1F73E3A1C0BC2C38FF79586A +:10991000F7E79F87416159C179188279582730FD4F +:1099200029FF9A8D5F823EDCA737F63C8EFC974F6D +:109930004FAFBE4DFF7297DE5CC1F5DC5564FC2273 +:1099400089EA91DB7D59591210EF2F02DEFFF6B341 +:10995000E31F037AC858623EEC5314EFC704E46770 +:10996000921CA7E34BAF8819F0533CC11B944409E8 +:109970003F8568549F295C9F35C1FFD66BAF07A711 +:10998000EADF4B463F7902ED0DA22446403FAD4A47 +:109990002A20177DF56B1590A3A17A0A83DC446514 +:1099A00045B882962AE904F9B3ED8F17A21B14D0AB +:1099B000CF723431C397B7FE574713E457B0CEB5D3 +:1099C0004454A474C899EB14A067405BABE4FB5704 +:1099D000B29A88CA54DE86A05F18C79B5404D493F9 +:1099E00064462FE5CBEAFA24F67338DA81F80C687E +:1099F0001BB0BD4EE26837BD50BFA1B311F68B5707 +:109A00003612D063C5F8E1B6A37D6A92C879FB81AE +:109A10004F4B12316F3E7D52320B7888D1C2FAF52E +:109A20000497738F1EC77D85A41F34152ADF5E3E01 +:109A3000D7DE28F999B0306F3E2279FB0B9D8F411C +:109A4000BFD15568FDD19DC2D9AF21106579E5FD23 +:109A50004EEEAB7C7ED32B526338BFA134CC6F1F4C +:109A6000D5EFB87F9E0C650E52127A5625F7C37B50 +:109A7000AF2591DE0876D30CFBD9DDE26506C8D9A7 +:109A800003C037CAD86DDD0A9623DD1A96A9EE28E1 +:109A9000960F06BFF0C4186DB7C5F2693E5ACAE901 +:109AA000BBBF01FD51EF3A3E02FD4668FFD0AFA4B7 +:109AB00068073580D9FEE28DB1F2660FE3A3EA09AB +:109AC00020BE8B3CCCDED68989F292D64AFBE35588 +:109AD000AD4E7B36640426E59EFE176CAE71C07EEB +:109AE0007DB6A3BE7B5DFC80EA26C0C72BC589D1AD +:109AF0000265617D7D5610114F515C340E768634BF +:109B00004BC6FD7F4070EAE7473C6C5FCB7814ECB6 +:109B1000374AC65F3847F9E1D53C68DF84AB9B46DE +:109B2000B3C09F5AD998478BB0774CAB29301E8968 +:109B300048BF1BCB5BCF4F0966A3E72F804F53E88D +:109B4000EFE970C875CAC3F6B5B37CBD883EB30BE8 +:109B5000F449948A2141F9D01F073E78826D46333B +:109B6000E5C340B5AC83DFD3DFE329B8BFB8F92044 +:109B700056DD12053DE8E6FBF35C8E9EE27CBFE617 +:109B8000EC07505F6CD73C9D19D41FC73B419FF732 +:109B90002FF57840CEFF62F8E7A2E3735C7ECE0A31 +:109BA000137420DFFA23CC3EDEA651F981F51C6147 +:109BB000F2A3936C27BE37285DC254BADCFC7BB796 +:109BC000E9B3F95E55ED89675A00BFF138E2D7264F +:109BD00015C4EF3F8AEF365EEA045E598697F19727 +:109BE00081D7534262BF87C20F70797D401A5340BC +:109BF0002F34423DD03B41B68EA6EA25C1DDCF933E +:109C0000A02776403FB4FE0E69DCD18F5D2F047C27 +:109C100060EB22CED685F4675D17365E231C6F9D00 +:109C200064985C371796EB771B2F7B3FED0D5E4DED +:109C300040DF54AB71B4B367A9F12CF0ABAF56D68B +:109C4000C1FEA10E11EED7D854CFF3876AD745D104 +:109C50007E09AD43FB7BC01B477BFC58EDB7CCF5C1 +:109C600094AEBEB355C46750BB3F78F5311DF4E2E6 +:109C70003111FDB2BEB37367250BCC7310E26014D3 +:109C8000FF00E087F6B33C616C03BE7D2A557CB4CF +:109C90009F375B4806F4A95735A3605FF72D508CBA +:109CA0005EAC1527C0DFDEE0C75A132D53DB07D5A6 +:109CB000C13BC48593E3D09F700E6C5CBA8783BFB1 +:109CC0008EF4098EF705F128077B27610DFBA7B0FD +:109CD000AE40D782796EEE24DF292DCD12EC9B2485 +:109CE00060C0FCC7E29DBD7F043EBD24A21E74F38C +:109CF000E75931E113F3E25EDE4802E7CDEEEFFA19 +:109D00005A09F5A8544F323E01468DA31DD957EF8D +:109D1000C1389AA4AEAD2A695FD757665F131EDFBC +:109D2000B0E5A1FDD76CDC80C1F477888C11889FE9 +:109D3000541116BFA826BA40B0BD21C43128D2861E +:109D4000719388FF9DEEF716EC5730779273C169D7 +:109D5000F42BD17EE7BE0BFD96C1D74F1EC57EA961 +:109D60007A889C9B31D9AF379AC487E4ECB973E207 +:109D700072C29AE02F81F22D790C5C9F6476D838FC +:109D8000488B81C89D0EBFE946B1C9111F95B5C169 +:109D90003B84302DEB6F33C7F2F4837B7E6F82817F +:109DA0009641BD4DE658057A03CCEE42F1A7413904 +:109DB00091E981FDFB2215E385444A62FC7748A8BE +:109DC000590CF6B35D4FAA97B380976A9816E88B43 +:109DD000A1191E4334A0DF6DC7C11F20E20D46A2AA +:109DE000441C49AA977E934FCFA745673CABAF8CE5 +:109DF000BC0F74973E87F0CA46A2903F73BFC8EC71 +:109E0000176FA0F0FBEBE58E7BC56553F9B69DF3AC +:109E100077A89ABAD65730F1013990EA5F3C017CB5 +:109E200018A85D132D452FD1A89D93E7172D93CD2D +:109E300021B1341E5BC5DA02F3A752E15959629C85 +:109E400009F94E120DFCC557983EA2F88685994C2B +:109E50003FB39F01361BF1B6FAB4113A6F811683F6 +:109E60007C99C2D1D54A5C6AA5F42E3D4044785F06 +:109E700027121174ACD866A0BE6A66FE9D49FF0128 +:109E80001DE136D9B16F81FE9CD8B71A41FE9DF015 +:109E90001330CFC1BC79EE3E447E356F127FFAC8D5 +:109EA0002C1417F6CB1D7F57981F3515F163379586 +:109EB0001770C87752BF11CA1DD46F84723BF51B4F +:109EC000A1DCDA4D859DCA537F7733C2FF0D9AAE70 +:109ED0008473B264AAB111E2A25F3EB1893EDA0D89 +:109EE00038CC866EFD1D10271F01F84A44C71200AA +:109EF000E6E7292F89FFDE0E719711BF5DFF9FDB1B +:109F0000B1FE042CF4425C7F24C4DA8F89C10EA810 +:109F1000BFBB81F0F8B9A9DC94E7FF9F11BD287F92 +:109F20006003B1F6BFED81FEFC920DD777401C7542 +:109F300002A67C047CFC0A8367F73774C0B906AAC2 +:109F4000003A5E53FF456CBC792C6E463EB4B60CAD +:109F50001F7B71FC7570D806347FA8060E8F894C64 +:109F6000E5A6893EDA5DCDF1AEB01F2225D87EC7C9 +:109F7000E347C5D74D997D8DE3517E3D9868BF81FC +:109F80001EB660DC9F14DEA7DFE971777BA7C717D9 +:109F9000A52D6142F7E1CED12C4CF52E31119668FA +:109FA0003F55D71EC76D458E6699DD50E1F86F8825 +:109FB0001A8F7F26305E68F35BD298FDD1EE9A4F00 +:109FC0006FC4C47348BFCAD661A5782F8771F2FAEF +:109FD000215F5B5C57687FB1CBC80D9E49BB8BFE90 +:109FE00057736DC0016B6D3593761CF063E96C0798 +:109FF000ACB6343960AF7699A3FDF9CED7E52E3AE9 +:10A00000749B7F1CAE75C195CB9FA4F3FDCE627689 +:10A01000E404CCF7E572F0D9F94E98F5EB231FAEC6 +:10A0200062760EB3673E4E781D371E469E1E16A101 +:10A030001E83758F406C3B37DB3CB5FF3EE50B184C +:10A040008F33FB24E2BF7A6ABCCEEA4862BCCDEA19 +:10A05000F5697D118CBF61BC6D0B35E87DB4BCDD4D +:10A060009BB855A2FC7ACB7F518684A1DFE40A8895 +:10A0700053F7B9E20A6E798A3D7A73C1F331BBECCA +:10A08000EF6671401B96EA0B9FFB6F9164A4E3257A +:10A090006F620BAC2349234731CE43ED6C11ED6C5D +:10A0A00013EDC7C3D56BA260C7A44C19FD1C297D55 +:10A0B0003BAE9707DA3CB85E7A241DF1EA5FD97BA4 +:10A0C0006C2EF8A3BA87737A0CED801DABE43A5876 +:10A0D00037616A8FC27949382614DCC7B64BFCFC5D +:10A0E0009A7CB4247DEEF9F838CF234A3708786E8D +:10A0F00067853CC8FF94EA413DBABD4D7E1CFC9F7C +:10A10000ED4B3D37C3FB336DB2472CA1DF06B9FDE4 +:10A11000B415E2A8B0EFA91BB09F33862753497E40 +:10A12000CEE1556B30FEDD2798CA5C3C5FF690832C +:10A13000C8B71F60FC6FC7A20ECC1FB02416F7DA99 +:10A14000BA20D09529741E2E85F1FD8EC6F6230FF8 +:10A15000015D542F1F44BF6DFCC4C6089C5F6A8B11 +:10A160004774A0DBF4BC01E3ACF4E0FB7463F20AD7 +:10A1700003E2B66D1E87FD915EC9F8B12342908E51 +:10A18000336DA7206909F653F321387F8D2C9DB0DC +:10A1900087EAF2ECA1706B724522EF1CC1B69F8A70 +:10A1A000ED4FA26C8C59F4BD7AD287FEAB107E9233 +:10A1B0008810A79E2DA2DF7CED82A3088B6382E12D +:10A1C000D3216E6F9904FD3D93C5F1EB0979983E5B +:10A1D0000FFE41C4736112E2F636B7AF34FA0FF6E0 +:10A1E0001D9FEE3C079E625F9D7CE324AC2BF164D7 +:10A1F000F0350F94AD89BF21E027BFFD4D8C1F3D89 +:10A20000D07A67A047986A879D59FA4C7A6E013DCB +:10A210006197C1B1309EF312F1969276B87AF253FB +:10A220003F3C9A87DFAF24971DCFED3BBB9F62F683 +:10A23000DD5BDD9B7F7894CAF8062F8B17F965F3F9 +:10A24000B7A0374EF1FD330DF93779F2B3C1CBD654 +:10A25000D11FF8FA8619067F1CFC6798DFFEF67599 +:10A2600038EFC5F0A6FAE00F4C1FD87E38B3E77779 +:10A27000B495F63B26F35CCEA21E2896E7F20129A0 +:10A28000217B97E5E927579E8BBD9E075799244A66 +:10A29000E7695B35C9C0F912B9C6241B417E056266 +:10A2A000F41AACFEF872BED5417E14794F16D6C5AD +:10A2B000195D32E05C3235EBFDD4A12C8EAFE49217 +:10A2C0009F72F3B9C5359F0D5EE77C8A245E0586D3 +:10A2D000492CAED46D02BDA3CA06AC4FEA1FE8F903 +:10A2E000FE8F3D9F64058B8B896A86141A7788EBF5 +:10A2F000F1A4D7BCD40BFB8D377902F4B0B54A4634 +:10A30000FFD85DFFE35EE6BF0D3612C962792DA866 +:10A310000749A769C2B95F4AD0920F6B887E1CCEED +:10A32000BF4097837FEF8BBE6EC2BA7B5424C9199E +:10A330006DD45FF63622FF77ACBA8BD9A1EF2582B8 +:10A34000580DF52DDCDFEA4C4DB0EA26F3CD88D66A +:10A3500013BD314F5FDFE4657A6DF2BD15BDC9F104 +:10A360009ED9EB83216EFF697DD11B4305DA571718 +:10A370003EB77E1FA7F3262FB747AC3ECC83494597 +:10A380006E3804269B74CD607A3D2D4D2D89725B0D +:10A3900040BE6F02F9F352F9663B15936FDB5E28FE +:10A3A00036FF6E3BC1AD7F2A3DC78DEDB9B9E438AC +:10A3B0006EFF7D90E7BB516977F0C9C7D7F942BE00 +:10A3C0005E26EDA934870DE48B0FFC7D3817075905 +:10A3D000C8B3C776733EFA02ECBD1B0FEA676F0184 +:10A3E000B9F385991F8E8B11EC3AC970CCF7047FB5 +:10A3F000F879E8418E4F2C7D358B0B87EC7CB94A80 +:10A40000F547E93C39AA3F1E28A53F4894C5016C91 +:10A41000FAA7E2C9F814E5F33ED430EDF8C42330CE +:10A420007E09BEED3F1FBE8DF03CBBEE811F1FE1DC +:10A4300079094EBD7DE93A8C9F15C393CAF5A8B73B +:10A4400080DE7E17E7E1BBDEDA0B9F07BB5E51FEC5 +:10A45000F37AFE2DA27E9AEEBB8D928576D4B0BEA5 +:10A46000CB427B0E6885FD3EBD08F3CD488CA07EB7 +:10A4700084869037E5D74DE45F801818D793EB9D1D +:10A48000784A11E77943B4CBCADAFD82FEF66F91C0 +:10A4900071DC89B896CAF2CC6C3B149615F82D3E47 +:10A4A000F2F9638DAC1DEAFD62F44884E90938FED7 +:10A4B000017BA358BEDB24FDCE71A21F8A97D65321 +:10A4C000AEFA4495F4D70B9C234E6D2791D7F3F445 +:10A4D000DB5BB08EF3F213CC27D77761BE1FF11888 +:10A4E00010EFEC8BAE23094AE720617A2505E54A97 +:10A4F000C83F59ACE13985CEFC3F8FC2E4F125AFAE +:10A50000EE88DF8A2AF3A7ED7AE5E6FF6EBA3F15FB +:10A51000B28F2E97D97EF1D61792BF87BC066B44B7 +:10A52000D0C10E3EDD9D43FB6A43F65219F2D716A9 +:10A53000CA33B1DE863D8DF2EA7C7B89B0BC018AEC +:10A54000889CBF3EED7529A77D4780EE536916179D +:10A550003995FE57CC0B38B54F443BFA54EA832566 +:10A56000D7D369BE8FDBF54EEF134DF453524266DD +:10A570001E6D7F5A32C305F308A8994EF2F4DC270A +:10A58000D2A2436EDFBA3F2183FE39DDAD08BFA200 +:10A5900073752BD049F1DF906E9421FE558E2E48B5 +:10A5A00067CFDF376C3AFB55E6D7F5ABCC4FE9D731 +:10A5B000DE447ACFD0E7A5FCA614A7B35F2BAC5F2F +:10A5C00094103BBF55BC56E1BC0917BD7EDDB94EAA +:10A5D000DF69FC8655765E3B2CA595F3C127645A4E +:10A5E00002D8D11AC9A6203F9FB2F165883360888E +:10A5F000918ABA76F229E19314AF1FAC574D210A24 +:10A60000F057858B28AC513FC81B05FFC373F85525 +:10A61000BA8E86BB8218471E6CDD7418CC84E83D68 +:10A620009FC5D0D33650F6183F7D5F5F7B0B5F67C9 +:10A63000B4F3CF0C76AC8678A544E23CBEE1D125DC +:10A64000DB5F2BB0BEF3FC65E19C6FB25D313E0574 +:10A650005CFE908FAC2DAD9F36337D66D17FA05FC1 +:10A66000A2AEF6336F71C6C1359207D3F73B65C210 +:10A67000E33537BEABE3CC2247141DCFB13C5A06BD +:10A68000EA13AB1AF2A742098980DD3EAB39D10E3D +:10A69000FC2FC7F761C2F2EA08394EF2D7D5DF7254 +:10A6A0003D547FE79705B0A7CF18540A1601AC2C8C +:10A6B0002A645FD8F95A1370EBCBA80F0729D61874 +:10A6C0003768F5A0DFBBCD38A5E5AFA7EFF1712660 +:10A6D000E79FE8D2723CADC5F9970D8FE95F78FE30 +:10A6E000F32F4F73FEC39B9D76F074E7E5475C0F35 +:10A6F000959BFF0B1DC79EB7A9EB83E9C3FA3B9F50 +:10A70000C57CC5AD2DA5EDA3A9F37604F7B790419F +:10A71000CC4C81763F9505977DCE4A8524899177EB +:10A720000E255EBE7C1FE415151B574CB8FC0DDED4 +:10A730004FEE135412F15C442FF33DDCE81E89EE1A +:10A7400087C12D57ED919640DE9689F95FC3DD26CE +:10A750003E9F987F9F87E32B108FED5FEB782EBA9B +:10A760004742BBC243CE2D21C861DD963B02F53A7C +:10A77000F7480A3EE5F905B4EA4C6847D06E5D0437 +:10A78000C19E5A3CBFC77EA023A827912E06D38620 +:10A79000006FF59A669CEBE53BE97AD8EAE7B0CE24 +:10A7A000E16A0E6B1C6EE430D9857050A630C4E9A6 +:10A7B000BD690DE100871B395CC3E16A0E37715832 +:10A7C000D885F05699F537226558FF010EEB1CAE7F +:10A7D000E1B0C6E1260E93036C7C1F8303DE0CEB15 +:10A7E0003FC8E1460ECFE0703587E7725838807079 +:10A7F00051BD1C3391BF93F3DFC9F84608F72FE32F +:10A800002EB86BB27E9EFF39D0AD0BF9E78ADE22FF +:10A8100071A7C53EA667C6DBE398BF44FD52EB5463 +:10A82000FE792475A00AC52D4DDE6EE23C3D5278BE +:10A830005DD8EBCEBD2E2AC56FCD79E2F7A1FF2002 +:10A84000FC3EECB3D73DF3C7C7DB0DC4D3DD9FBBE4 +:10A85000DD08D52F24CFFF0F48190BBEDBA0B60FA4 +:10A86000FA355EC599E77AB7CFCBBE5BF1B13CD77D +:10A870003E8EDF783B3B8F189817C81C10A6C61772 +:10A880003FE763FEFFF76D3C9551F48F8239BA6262 +:10A89000F3FC9DE1584799FC75E9DFF3F314DD7192 +:10A8A0008F7F8577749C805A984F774FE89B5BAC7D +:10A8B00053B4AEE2A7CFC16FD122D1FAFC7C6AFEBD +:10A8C0009E081E11F5CB595ACFCE2311B17F3C976C +:10A8D00020F52CEE25F2FA384E23FB8EC15C0CFBE2 +:10A8E0000C7DDECCC711A6F6EB6E97F5D5B0F9E27C +:10A8F000F8D8792B22791EFB99C0478A23BFDCCF79 +:10A90000213F59532FFCF985C25EBDC87869763E58 +:10A9100054AEFD135C5EA6C86791797DC467DB29E0 +:10A92000A3269C23D97264CBD7F9CAD105CB096C75 +:10A93000484B8BCB894592B86E247025174D5F5ECE +:10A940000AC84936BF7EAD52CDCFF90D94178A8F14 +:10A950008472AB317C6A1747B03F01D6389EB7701E +:10A9600018F840E9BD5CA9E67C60F18C009C3BE6F0 +:10A97000B5A7C421BE02758698DE67F5AE51D83AF8 +:10A980005FD551CFF027BC7F17BEB43F25BF3F91A5 +:10A99000D4BBE49CE1FDD70A9B5F5A9FC55DDCE315 +:10A9A0004B02E22B92B8E5A1ED3EC3EBBBF5975D00 +:10A9B000DECFF11BF690CD2CCF234EF2BFAB0C2A8D +:10A9C0001EFEDD235B676EFDE405B95A72FE72550B +:10A9D000A95EAF550AEF3B54CF37437CB6D8BE7360 +:10A9E0004299D80F9AF9BC4D6BDE7F077A68D9E49B +:10A9F0007C568AEFE57CDCE9E27B7A2ABE15C9D970 +:10AA00009B5C4F548ADF35E789DFCB2EFCDE29B90A +:10AA10003ECBF7A34AF1FFEBF394877F9CCADF8A12 +:10AA2000D69147991E7F3F739EF8FDD28D5F917539 +:10AA30002B2B8C5F1661F221A904E33395E2D75DDD +:10AA40001E3FEE8FAFE9376368AFA13FBE5D59D3BC +:10AA50006F4993F89984E9F5E98EBFA3E2F1DFDF4E +:10AA60006F4A93E37F5179BF637C89CA0F085BA566 +:10AA7000E33E56E9B8D64D0EBABF96BAC931EEF9E3 +:10AA8000F2FDEB158FFF5107DDCFA73EEAA45B3542 +:10AA9000304FA4D271FFE13CD7FB6F38BE41457304 +:10AAA000EC03C5ECF7B3DCAEFD84A239E4B858FD85 +:10AAB00037B9BDF2BE0AEB9FE6FDCFB5F12953FFD2 +:10AAC0001E8EFF3D15D6FF1DC7676585F87C9FAFBD +:10AAD000C362FB6780F33D083A32CFAFB9D03CA6E2 +:10AAE0004DBE84E08773CD67BBF1FBC1372545833D +:10AAF000F377D249D01EF79F0C1DC0DC4C3BCE4CE7 +:10AB00001296C0F430C6B7BC11239AEF5FD87E9777 +:10AB100024C5CD42E76BD57EA6FF04CDE862EB5D90 +:10AB200026F03D47B1FA417FE1F84B1519CF421E9F +:10AB30002F89F2F3A2B31FD40BC6FFA57802BFAFD3 +:10AB4000D6647200E2CED5EB1CE7F9311B9FA889D1 +:10AB5000F8C81AC347960CB350FE72839FCDABDD85 +:10AB60008FED1F0AD171C2EE7160F80DF8E35D78C8 +:10AB7000DE5F2D239FFA43CEF3F09B793F7FC5E93B +:10AB8000EBF796CE1BEB98D9AA40FF7DAD2C6EAEAD +:10AB90001303CF05FBD5D2F71A6CEB66E78123FCD4 +:10ABA000BBD2147C573A1FF2A4A23C3FEA19FC3EE8 +:10ABB000EF4C8BA7E4FD3821C3193F0F363BCFDDA7 +:10ABC000EC78BB5F777EEFE38B3ABFF7F1CE943C36 +:10ABD000F87D91CAF2B1CAE16FE773D9F586A4A4F2 +:10ABE000A215E453C611EFF7459DF8BE7BFC63ED5B +:10ABF00083DE51AD105EEF14DF8AC51B26E8AD92EF +:10AC00009319A6371CE7D4DD5CBE7C554A12F4329A +:10AC1000D5BB45DE07587B358E790A4A34AE633C96 +:10AC20009AEF030AAC873C3E3D68AFCB80C7CE436A +:10AC3000C6FB5E04DDC4734605D69130B5DDC4BCE9 +:10AC4000DA72FFF66ACC4FB46A155C27823E8EDF5B +:10AC50007BB9C799EF3777F96939C36FEE86D2FBB5 +:10AC600027315168BDECF4333DAADC10D79526742A +:10AC700055D1EE71E3F10DBEFE541B7FCBC473EED4 +:10AC80004AF17FAC42FCED7128FE5F013D4BF1FFC4 +:10AC90002A94C5F07F8AEBA31AA2F7E09EAD333D5C +:10ACA0004BC88D7A7E7C3D1060FDD6703D4548BB1B +:10ACB00023BFC4CBE9AA949E43B65E2B438F3D2E9F +:10ACC000A5E7289F8FEF959A8F17383D8100DBB756 +:10ACD000947D719D2E4D7249917939C5F19819E095 +:10ACE0007125AB7D5A72F5A30AE93835392FAFF2D9 +:10ACF00079F965293A4E72B94A8B64E569D84FE70C +:10AD0000DA790A6B1DF33287F327EDB3E7A5C33178 +:10AD10002FD5D39C97DF5648CF9CC979798BCF4BE1 +:10AD2000AE949CE5D57F9BD7FF13AF8F76E29CC096 +:10AD30001FFBE1BC6CBE3FEE09D44EEE6FB49E1813 +:10AD4000583659EFC1E163763D1FD6EB9CA8A704A6 +:10AD5000F2FA23D66BFD70AE3DC0BF0BF9FE70E872 +:10AD60003DBC5D18DBDDC0E8A1EDAAF2FBFFC6F03B +:10AD70002B76FF33A05ECFEA3FD9F522F9F5E60442 +:10AD8000FE64D78BC27361DF447F75F9789CF2FF54 +:10AD9000733FCBCF71E5776995E531782309BCE73F +:10ADA000A18684D290073B28B17B172C6A541F845C +:10ADB0003C595F224B2AB0BB3C0A6BE7A3F6167CDA +:10ADC0005F36432387FD3AB82006D907F9AD11094C +:10ADD000FD813BFD89A5815A8627C8CBC0ABCC1E1F +:10ADE000EB5197F2380AC36B67F06329E84FA378F9 +:10ADF00041FF0F06C387A1FEAE065907F93ADC7082 +:10AE000017DA893B7B2402EF775E2FA39DB8FBD531 +:10AE100010EEC3039281F9D59629EB6037DE1DF859 +:10AE2000D3894D141EEBA9D284AB911EC4DFF290DE +:10AE3000781FF6CFECCE2D147FC80BC6AD0BFAED04 +:10AE4000647E0CFDD541FBBB57EB984FA313767F77 +:10AE5000D350AB8CF9483BEB9BDA61BCDDAD0ADA31 +:10AE60001DBB6F68EAC13CEDD600813C801A5517C6 +:10AE700020EF31BC422616C011BD07ECCED0F20047 +:10AE8000E446929A7A365E683EC17BFEBC241D8FF2 +:10AE9000D1329C9231BF77F70D6B593E69AB4FC3EE +:10AEA000EFBC2CF3E5D872C25295E127FE23017C5A +:10AEB000BC734402FCB7E7399C9E685FF21C319C6E +:10AEC000A9B05EB6B27AA19484F74E95AD97AEB0B4 +:10AED0005EA6C27A5956AFECF93DCF9F54E83F8841 +:10AEE000C3F95DE7B760C797FA5E6EBAF9B93B037D +:10AEF000CEEFE9CAB5B7F372CBD10B879913788A35 +:10AF0000E5EB97FD1E73E65D51F83E6DA8F65E5EBB +:10AF1000DEC7CA3AFEBC6E4B14EF8BACE3EFEBEE30 +:10AF2000C3FB23DDFDFC0FAE8F9B49BCE43CD4701A +:10AF3000FC5FA7B8433CBB592A930F10F1B8EC4D06 +:10AF4000A7DE5324AB03D7ED0D2C2FC707CA00D6BD +:10AF50004D3D5BC75E928CC7309E658617CD9C5C6D +:10AF60003FDEB61771FDFCA04E24422BCE0FFB8EA8 +:10AF7000D225276EB9F0B9CEF52F544E7EFA2EC9E0 +:10AF800089372556B47EBCE90AEB652AAC97ADAC8F +:10AF90009E9C122AD22B72BAC27A990AEB6559BDCD +:10AFA000819532DFD7870720BEE5BD5271C00357B8 +:10AFB000069CEFAF521DF0E032677B79B9B3FDE03C +:10AFC00072677B79056B6F04F7BCC78A55BE4EFE6E +:10AFD000CF79AE9366A574FD506B9975A5687E68B0 +:10AFE0005F23E904EE1DA2FB5586EF5B05E33F6B93 +:10AFF000826CFD5F1FD01CF7D3FDA5D3D91C64F86C +:10B00000DAF496C3D7D6BFFF57E47657913CFB6A74 +:10B01000D03990774DB275D0EFE13BBE550776E55C +:10B0200023AFADC07B3DFADE67E7CD1898F7239DCF +:10B03000F8FECDA0C71E49CA04F2711EAD368E5D62 +:10B0400012C1EFC908D8CBD48DC2FB3E1ED92CA1AA +:10B05000FDD1775BE97B4DBED1CDF284FE8EFBFD49 +:10B060005FE5F7713DC5EFE37AA25BC7F260773326 +:10B07000965FEA36B07CBCBB15CBFDDD26EE1B5FD0 +:10B08000ECEEC4725F771CCBBDDD5D58EEE84E6020 +:10B09000B9BD7B33FF5E2D89E570F7162C87BA2D7D +:10B0A0002C07BA5358F675A7B19CFD3707862F5960 +:10B0B0008AF99290A156147FE37967DC61E1B301CC +:10B0C00007DCF23567BCE1B22FCF76CAC5A34D8E3F +:10B0D000FA97ECB9CCF13EB66DB1E37D53FF950E16 +:10B0E00058BFAFC3015FF4D9BF72B4AF4BAC75BCEE +:10B0F0009FD5F56167FE57DB06C7FBF0D24F3B607B +:10B10000B5E54E47FD40EC5E070CF73EE7D7BF3193 +:10B11000D8C4E2819111473D49DDE5A8F7A999E638 +:10B12000FE20C443D361B42F1F3929E03E38E32207 +:10B13000E3359027F25311E5895CCBF2DE673425C5 +:10B14000AF80FBCB88945CF1C150F97BA4ED788F84 +:10B15000186E4DC03EFBD66B820EF6AE10DE323F4F +:10B16000DF9FB3CBCD67926414E2923CCF4C9B4DF2 +:10B170004C13FC46AA4F08DAD9C9ECFD18B7F4E025 +:10B180007753692181F74E539BD9F8EF1AE4CBBB73 +:10B19000F7DF20DAE5673482EBA0BD4369ECA7ED69 +:10B1A000B72F90F17BBE29F8BABE8B7923C8FCD7A4 +:10B1B000ADF7B378A576C4DFA82C85FB321233C077 +:10B1C00055B5DBA9D997F0DE5335662C87AB01D492 +:10B1D000E60CD9A842BD2CDEBF40EB7F1396FD44A0 +:10B1E000FD4D594BA6CFEB3627E6C2773DDB79FF05 +:10B1F000DB0FFF8C5C42F91A5A7A9CDC8AFECE5E29 +:10B20000E45FA8758CACC95BBFDBDF2EFCBDD12F22 +:10B21000832CAF667B8F85F7CC29D96FE37DA8F6A9 +:10B220003C045B8E9304F4DF368EF7036FBF9F7D83 +:10B230008FB75DF85134CAE9EA71D285F8001DB7BD +:10B24000523DA7DE9214D6B4B0E773F3FA85F71B2C +:10B25000E17DC212205FBD127EC9F07C13E5179D0F +:10B260000775734628C9AF58967D1FD15C845F94DB +:10B270003FB7A29F3BE8881BDA7CDADE739C2C6F19 +:10B2800001FB9FD59FE02BE5C3AD797C9CE0C7B265 +:10B290009F627E6BC8FA1159A2B276406F88D2B70E +:10B2A000B100DF29FFB07F9B1FF63821CA2F869798 +:10B2B000657FDF88F775DAF91F767DF8752EE7F977 +:10B2C00087941FDEB1EA8DF03D687B4B02BF131EF1 +:10B2D000503D789FD080FA4CD6C3E519EA4992D9FF +:10B2E000FB639E67DE2B145A7F4EFB1F32A6F3BF13 +:10B2F0000BEB57D9BD990391327610BF2F58E4F765 +:10B3000005CB52BCB391AD53A3874CC64DA78EBF9E +:10B310000BE916A3CE7DB57F93733F8B691FC6F8EB +:10B32000745FA403E16279F976E9CB31BB51E6F8A9 +:10B33000787341768F71CE8F789AB919585E93AB36 +:10B34000C6F2EADC1C7CBF2A5787705B6E2EC257A0 +:10B35000E51AB1BC3277393E5F99BB14E1D6DC12F5 +:10B360002C57E416E1F3E5B9AB105E965B89F0D299 +:10B37000DC6A2C97E4DAB15C9C7B2FBE5F94BB1E29 +:10B380006123F7412C2FCDDD886573EE23F87E7E97 +:10B39000EE66842FC96D44785E6E3DC2B1DC6710E5 +:10B3A0009E9BFB14964DB9FF8A6563EE0E7CAFE75A +:10B3B0003E8FF0C5B97B10BE28D7877043AE07E13A +:10B3C000FADC5684E7E486B19C9DDB8D655D6E27D3 +:10B3D000BE9F957B08CB99B92FE1F3EADCE3586A6D +:10B3E000B9AFF27BA09FC2329CFB2696A1DCD3F8BA +:10B3F0005ECD7D07E160EEDB5806722F60A9E40E9A +:10B4000063596E9EDCDF2F8911E7BE7C0D99E190B8 +:10B410008B5539E7BE7CD57893035EF96BE7BEBCEC +:10B42000626CB1035E76C2B92F2F39DEE178BFE8D6 +:10B4300098735FBE34EBDC97E7673EEC80E7EDDBAB +:10B44000E0A83F37FD6907DC98BAD351FF62CBB95A +:10B450002F376C71EECB7392230EB86EF32E47FD2F +:10B4600059E461877F58DD75C051BFCAFC8AA37E4D +:10B47000A8F519D7B94986E979E339C773A5F94819 +:10B48000C1F395D89EEB3D6F803ED13DFC7B7A7E2B +:10B490004F2BBF0FCD3D9F355C0FCCC831BF28C2AD +:10B4A000D75D2DACBBBC7C266A3F3436417E08B7E5 +:10B4B0001F6634E94F1FA5F05B4DB2D14361DB7EBF +:10B4C000B0EB97FD7B14FC3B7D1F7CA7AFA3FD80F9 +:10B4D000F7B7DF7D4AC07B1E6AE6107EFEDFD90922 +:10B4E000FB5A0A6C69767F0EDEE7936AE0EFC9FAD1 +:10B4F000EBF07D23835FD876EF1A88A3A6BC76FB9A +:10B50000AF5E07718B949FC12F6F5B3F08EF6BAAF3 +:10B510001275B09FEE2D726EF973957DBFAEAAE6DF +:10B520004B6AEDE4FDD1BF8824FE37C0B729898B73 +:10B53000E12A6EB8BF1EEE67BE56327F00CF3F20B5 +:10B54000993F54715F70FA05EB20A7B516FFAEC4A2 +:10B550002B2ADA4F87703FAA79EF36FCFE3315A20B +:10B56000F8A8C5F139A68A13FB0DB1F79B268C9379 +:10B57000A29D37D840F0BEF85475DC82FBFBACEFDF +:10B5800029E4A00174A7591212CF3B4C5DAADB72CB +:10B59000E1D89FE09EBF0DF47D30A1EA6087A9E469 +:10B5A00038E65584C938961AD104C73DDA36FD0D00 +:10B5B0008C7ECA9771A04B26E6A1317EDECEEFA528 +:10B5C000FE17CE9737D565C5F9F21EF13EA2D1F12F +:10B5D000F7533B11F6C5FD5081D2F17494FA9D02E8 +:10B5E000E09988B760BFEC7E08FB7E38E9E4B7F1EC +:10B5F000DE063B8E23896D9DB83DB730BBAF93FE11 +:10B6000003BBAF36EEB423DDDF9948AEB8CE74E3AA +:10B61000385521771C47C573E2335D1EBC57B158BE +:10B620003F763CE7E9AED2FEDCD7F97AFA1ABF17CB +:10B63000E42BFC1CF7497E8EFBB7E0CFD1F2CBE0C8 +:10B64000CFD1F200F873B4CC803F47CBC7C09FCBBB +:10B65000FB6EE4B122F7BC5C526DE72B6C41BB3D45 +:10B66000C8EFD9206414ED7409EC742A574F1FED0C +:10B670009D19A37CA7BE06D2B7F9FA0EFC8E9F0EC9 +:10B6800061C077FEB7BFF1FACCFF1281AF6FD9F777 +:10B69000C3B43EE6494A2DEEEF48CA8C2399A81759 +:10B6A00082D41F481BC5F933ED7E1513AF6C9B7E0A +:10B6B000BFEC3E9FC975D389F924414EB78F7C07F3 +:10B6C000C739C3FD1922D6FF2FCC8FBA4222A5BE9F +:10B6D0000F9C32CE34E5EFE365E40FEECA44BB3392 +:10B6E000C9E663E173C7EA0ADD0B61CB61CF6B3E4C +:10B6F0008CAB0E7D8FFD1D8AA30DF21C885F8C1E06 +:10B700007EB111BF5FE4F2D877D4997F509F244275 +:10B710007EBF0F75B338445F84F5ABAB2C6FC14D62 +:10B720008FFD5D53AA4C3EC3837CDCAF07CDFB424B +:10B73000A80FB378EFE3C2E7948F00BE8FDEA114A9 +:10B74000E4F3D78389FE50ED543CF3DBE33D14C5AD +:10B75000DB6F0B2D2BDEBEE519E517A474FB3DA5B1 +:10B76000DA5FF615E59132F83F5A187F6B3FB4ABBC +:10B770008FB2BF4BD653F7FA81AD14DE7B07F38748 +:10B780008FDEBC0EFFAEC3402D9BB702FD3E510ABB +:10B79000AF85CF757595C1EB1BA5F9DAD55586AF89 +:10B7A0007F5FAA7DCB335D27CAF0F5BBA5F9DAB57B +:10B7B000AF0CFEFFB3707BEB62D03BF53A8BC7F565 +:10B7C0003452BE523C866CBEBAD643817E5F2E2771 +:10B7D0006F65F0FA79E979292BAFA74AF3B5ACBCCC +:10B7E000FEE602E5F5CD227CDD0F785F80BCBE7DF4 +:10B7F00081F2EA0D5F98BC86C225F5405979AD2DDE +:10B80000D5BE02796D2884BF8F044DB0A7CFB4B0E8 +:10B8100073AFCDED1EF6F79134A6EF8327AFC37D4E +:10B82000B49FEE53335A61BF3EB5F7F6A593FBB311 +:10B830007BFF71F7E7DE3F6FFF973544A5F022BE2F +:10B84000EFD9F80462EE7E4ADF2F31DD7125FE77F5 +:10B8500096ECF6B337BDD3E339F777E9281B9FD0D1 +:10B86000F157E33921BB3FB7AAD51D979CEEB8A588 +:10B87000EB476FB9307B607DD8793FD49C2DDFDCFE +:10B880007F3AEFDEB039FC3B2F2FF910DECF446E4C +:10B8900063F940E296A7F79F5E92774F141915F26D +:10B8A000F37FC4DB46F79FCEA33B07711F8C1F5B62 +:10B8B000989718D3AEC4FDBDDC3EFE28DFEF1FE62F +:10B8C000F6EC3E7E3EB1979F4FA4B93DFB003F9FF3 +:10B8D000D8C6EDD9117E3E91E2E71303FC7CE279F4 +:10B8E0007EBEF05CF73E7C7FA83B83E5B7BA9FC481 +:10B8F000F2D9EE517CFF4CF7218447BBB3CC2EBE6E +:10B90000E756CC839DA4C3E474DC8BF7BCF4D797D3 +:10B91000B6CB1B92CE78C89CCD01D73981F39C62FF +:10B920005697332FB2DA74C643AA5A2F73DD47EF06 +:10B930003CA708365FE9BA8FDE190F9123CE78C88D +:10B9400015879CF19005A3CE738ACB9F749E535CA0 +:10B950009A71C643E6EF739E53CC4BDFEBA83F379B +:10B96000D5EB8C9F58CE78C8AA71E7F9C455BF7E35 +:10B97000D819FF1973C643569C70C643961D7FC6DF +:10B98000012F39E68C837C2098C8823E5C9475C771 +:10B990004332A84F7FA2B2F33DDBCFA6F55F0CA3E5 +:10B9A000BFA966AFA2EBBE6F33BBD7BD8F687E0D5C +:10B9B000F5F067D16FF04EDCCF1CCFDE1F99D43F7E +:10B9C0003BAF3DF553F06BBC21764FE5EDC27559A9 +:10B9D00092EFF778DF12F2CF23A588534F94ED5FF3 +:10B9E00062F7107AC12FD18ACBDDD47EDD7EC9B556 +:10B9F00059C893F2025E06EA1B1C27CF2F1946BFD7 +:10BA00006496444AF9A753C699A61E7AD3A58726F9 +:10BA1000FC9228BB2F4597482FE0B1F7A8A7E0BDBF +:10BA2000BFB61EDA192DBD0EED3C979D5D95E56301 +:10BA3000EF3C5ABA9E1DBFD2F97DEC5EADF0B9F76E +:10BA40008B619657F9C12AC2FDE6FF2F3FEFA4FC98 +:10BA50005C59F59F467E78FC72E3107CCF24BB6076 +:10BA600091C3E1AA4FAF81EF9BB610760E445E61A1 +:10BA7000F7AE961B27D6F6D1CAEEF5D398BCC65AB8 +:10BA80005761FE24DE33562A2EE1BA57CDAB5AF069 +:10BA900047F726FEFEA3BBFECF6B58FC28D6F5B1B8 +:10BAA00092F6CD41BEFF7F89EFFF31B3F4BDBB8F6E +:10BAB00071FC5F787516DAB57B6F637A5BEAFA879B +:10BAC000C3609F8D72F9F791CFF85B80AEDB2402E3 +:10BAD000E7C373419669FD8B55928173D02DC440A5 +:10BAE000B9A63F3C5FB6FB176F73DA5B7FB0F91402 +:10BAF0002FCD57FB9E4CF7731FF94E3BF25727C9CA +:10BB000087ABE15AF52FC4FD149E534B10AFD41EE2 +:10BB100003ED2E99E2A11558A76E7CECF5697F4FD5 +:10BB20002A6DBADA82F673043BEE1434204FE78CA8 +:10BB3000AA96BCFF6D4ABFD35C8F5F9BB21E6FE8B5 +:10BB4000FD4964F2FE2BB285FE964FDEEF596C3D47 +:10BB5000DAF00BAF0EE1772D29D5BE1FD0BE4F8B8B +:10BB6000948C9B6EE57C1FE6F92D5B5B3A7A5F87D0 +:10BB70007353BA5EF2DB05173C8B71C77EED19BCBF +:10BB8000C7689BC1BED756171D55C01EE8D78EE0AB +:10BB90007D71C1FA7427DC3718A472043AD03F6F64 +:10BBA0000F7FBF0BDFABF599149C7FA8F09ED235B9 +:10BBB000D2FCCA61F89C3B50FDE6E10EA85F3F7ADB +:10BBC0000CDEFB3582ED2575F47807C8D966827FD7 +:10BBD0006FCBE2F72A356435CC5BB858653049D075 +:10BBE000F73ABED756537876177B6FA819F4D74823 +:10BBF0003331597B8A1F85A347359CDF996A3A8E7A +:10BC0000FD4758FB99C6B326E0311C637FCF47ED53 +:10BC1000228F031F16A90C6FF8CE8C8DC3E988B153 +:10BC200071BC6A26DD017AA6DEC693C210378DB0DC +:10BC30007164957D0F49C7C7FBA67C2ADB0727F4F3 +:10BC40004E5718C73B13218F97FA7B01F67A7F9CDA +:10BC5000DBF9FBB99D2F2973BE783AEF3E867EFE55 +:10BC6000F7421B55E777987FAC62EBF1C51A9667F0 +:10BC700056EE1E49F259763EFDFF00D7C62C0E0047 +:10BC8000800000001F8B080000000000000BC53D75 +:10BC90000B7854D59967EEDC796526E126992493D3 +:10BCA000D7E426241021E0000141B19D445454D42E +:10BCB00088B6069F43409E01026A89169B9B172403 +:10BCC00021C0A02E445E99605154D0C18252ABEE87 +:10BCD0008029C5D6B6A9F54195DA08181501532A69 +:10BCE000CAEEEABAFFFF9F7B93B9934982B5BB9B2B +:10BCF000EFD3C3B9E7FDBFCF7FFE738631C6BECD9C +:10BD000081FFCD8B61212BA33FCAFB1258283F2C0A +:10BD10005F9AA6CF7B72F4F98211FA7CEE587D7F90 +:10BD2000CE4B75E55F5DCF58870332A2D7CA0A2094 +:10BD300039F2A0B52496B1BA8C1A2B83EFE7EFD174 +:10BD4000CA991DF3B9528CC09C8CB5960A81260302 +:10BD500063C115350D79858CADCC10189321754DC7 +:10BD60001FE2837ADFE2DF0FFBA6DBAB180B0D6768 +:10BD7000ACA9CA4F6963550B0B59185B953170BB61 +:10BD800000B6837ADBAAAC946EA992A8FDA62A1706 +:10BD9000E55BAA644A3754E553EAAFF2505A573587 +:10BDA00091EAADADF252DA5C3595D2BD552554FE1F +:10BDB0007C5529E583553E4A9FAD9A47DF77555517 +:10BDC00050FEE9AA4ACAAF1E23DD5E02F0D959A58A +:10BDD00050FE89AA064AAB2558F77828BFD2E3C29D +:10BDE000F2DA2B596930CA3AAA2503D55B23012C14 +:10BDF0009318B3318F6006B831C8EF00B80D553CC9 +:10BE00003516C827DFC1088E432B3C356680B33416 +:10BE100085E7D7E138D0AE92312FC376B92CB02365 +:10BE20009BB19C06F69601F2AE7CA9CD98DD3BDE77 +:10BE3000F5EA7850EE12A89C05B0FCB8D97B839443 +:10BE400084FD312A1F16EA1400DDECE2B742350EFC +:10BE50001867D41B811A23E4474E56044C630BFD2C +:10BE600082AF00F12A14E338E75608D48F5CC80487 +:10BE700001E61774713A585D04F0095BB7EDFC36C2 +:10BE8000161AC758C38AE943D800784D29157AE9AC +:10BE900011FE8BF786D13FFCD710120E1A619C73EE +:10BEA000406F2CBBFF7E2EDEAFEF675430A29FD2D7 +:10BEB00081E73172A7BEFD458188F640D7C81FFDD6 +:10BEC000B51F76FE065A6F7F747CCA5C56258DEFCF +:10BED000CD8BE77FC042898CBDED90080F09D73527 +:10BEE000BB10CEF03705D72B6630822BA03B540613 +:10BEF0007913FCAB09AA8A0592978DC65456538FC5 +:10BF000097C561EA55F325947FDDE45B83781625B8 +:10BF10001FC3F920D9205FAFBE08FE9986F9AC0691 +:10BF2000EF64C8FF08FE792963374A23A62A90FFE9 +:10BF3000CAE4132A61BC3DD942603BC07B79CE582C +:10BF40009203B58E81F9B34EE5CF9EF549255E0388 +:10BF5000F4935E2E8D453AEAAFDDA3E5CFBF3E0CEC +:10BF6000EA294EC19327F72DDFA5D2F1A325C214EC +:10BF700007C22193D3B1B69EC8FAB0EE5DB86E93F6 +:10BF800093AF3BE996124A73775D632D1905EB8BEE +:10BF90001F980EB644AC2303060A46C1FB499C1702 +:10BFA0008C93FBC67C1BF53B63E07E1B55B9773E4B +:10BFB00020B00EC4B35841F236E9161FCB85753553 +:10BFC000A40A0107ACABE19B7B1BB2111E070492D4 +:10BFD0000B49B754305F41DF71C5DCEE6A01E9F20D +:10BFE000C07C26C3F8165705530A30AFC96B9F01B2 +:10BFF000E7932C495750CA025EEC3F79854FC171D7 +:10C00000CD2E3FC1A521B5A7BE0DBF6F080924DF06 +:10C0100057CAC06F064A9903F9BE82513E23F561A3 +:10C020001A977D0DF39900FDE0BF01C1960CBF1773 +:10C03000E541C345CC8372C496CF8ACCD928A60EDD +:10C040001B50AED91E609E269C6FEA130ACA23E5D8 +:10C050007246F80605C7107E30BEF526C0677ACB5B +:10C0600068E20B5B6EC880EBBEDDECEB427C6AEBFA +:10C0700037BB3A091E0DDF184BA3E1E537AA9CCC6C +:10C0800044BC45C1476C3C97D75F9982D7A01CDD63 +:10C090009324B0ED86BEF52C6ABDCDCEE97F94E544 +:10C0A0005EFED4CADFC64586F173FA7933CD3BF71D +:10C0B000963B87E07AFAA383552A7DAD1BC2F540F3 +:10C0C000EEE43BBD08EF73F05F5394792C182253D4 +:10C0D000BD9EF53B059D5CBAF0F989249F724F35F2 +:10C0E000927EFF2A7B607A6D50E7F955A6DE3E10FE +:10C0F000725B08CFAB5C804F19ED0481C5011C5BFE +:10C1000055FA804F84DF20E8A726C07FEB8AB3B6BC +:10C1100002C867BC6D4432017A98A7A01EB15DC405 +:10C12000E941923BBD0CEC9098FC6EA2C78C8A4E04 +:10C1300003A680F7BCF8F1480F1374F47046D59F3E +:10C14000F057E79AA08A3299F8BE201EBE7B77C1CD +:10C15000249CC80F7C7C13F32A669217952C08E365 +:10C16000DADF32D2779861E8A142945382A7C903FB +:10C1700074D05E938C7C684FE2F265DE35C524BFD7 +:10C1800000049E4D30E6E24FBB929740DEE3E27240 +:10C1900019EA5B719E628159A737061D47F48670C4 +:10C1A000FD7603F3F83DFDC3FF3BF76BF532948F4B +:10C1B000DFBD5F10A4C968DE7138323655C175DB4A +:10C1C000D5755BD8AF689C73380EC2DE98F13B849E +:10C1D000AF78B1C88C51E8B5DF718C770CA83F2AD5 +:10C1E0008FCEFF637B58FDD9F1B1CE2E9804BB846E +:10C1F0005DF22D128ED12120BFA21D40F607F20064 +:10C20000CCA3BE82E363F44B8753C3E9FFABAA79A7 +:10C210007F6C07A5B947D5FBD51F5A8AB1FDAA5F28 +:10C220000B010BB46FCF34A777C2F7E08143D93845 +:10C230002F4D3ED7B6EBF57C46053384F7FB98CA05 +:10C2400017B54EDEAFECF058A3F1FB5AB55E836331 +:10C2500060BB61A33AEEB3766F753CD175C880FCC4 +:10C2600039FA25EBED38DF2D4BAD51E1FCACDDD7D4 +:10C27000189FD4779EE1ED118F03B45F3F50FB828E +:10C28000E7ADEFB381DB3F163FBEFFF6239EB66EF0 +:10C290001E64FE6DD1C7575AB15D86CBCC90CEAB34 +:10C2A00053BBB6AF86FC86A5668F05E8B37DC68F07 +:10C2B0005D88B7FA248EB728FDEE1A685EA35F2A60 +:10C2C0002D1D645E7B076B3F085C5F1E18AEA547A3 +:10C2D00006816BFB40ED473C5DDA32C8FCDF883EEF +:10C2E0007F250BE54E866C263D539D0D704539AE7E +:10C2F000C135821FA2F4FBEEC07019945EFFF63DBB +:10C30000E9F5E381C6BF007AFD7C60B80E4AAF5FF5 +:10C31000F547AF38EFEF41AF42C2807019945E63CA +:10C3200012BE1FBD260CD4FE02E8356DA0F95F00D9 +:10C33000BDE6441BDFC2EC5E05EDA202AEC7E71509 +:10C34000095CAF4B5CDEDB8F5E4D7AB40EF454E2D9 +:10C3500044D4D7C7362C2EECD5CF91FA27B2BF489C +:10C36000FDB9F8EF57919D3B46D57BDA7C6272238D +:10C37000FBB97D40FBEEBB8E2BBA58C816D7DB3E0F +:10C380006DF6BF7A3CBD7E17DBF9F80CC6BF6222A2 +:10C39000EAD5691E84F79089669D5DF9DDC71DB8F1 +:10C3A000BEEB8EEF670FCC49007B6064AF3D905EC3 +:10C3B000F98BD61389BDFDA48B254C72A0BD778B5C +:10C3C00017E9829533CF0E2CAEDCD37A625CAF3D99 +:10C3D00000F037DC14B66F3496075B4F84ADFBFC7E +:10C3E0006CA6EECF14B27773A54B49BF0FA6C7B5A5 +:10C3F0007DE326F44F0D477F94A4FAA35CAA3F4A3D +:10C4000056FD50DC3FD58CFE29F2834DE47682EA5E +:10C410009FAA57FD532FABFEB19754FFD8FEAA0039 +:10C42000A52F54EDA4746F5590CA9FAFDA4FF960F1 +:10C430005588F2DB1E9823233E7BD7E155D7A1F91F +:10C44000F506B6FB332BF47E90F4797A3F482AFA4E +:10C4500023C3F229E1FE4886FE9B1C5DF9908923E7 +:10C4600074E5B19EB1BABC3DFF525D7D9B5CACCB27 +:10C470009B9DD7EAF217EF9F1EE1E7B94D573E7239 +:10C480006759841F6781AE7C78CB325D3ECFFFA0B9 +:10C49000AEFED0861A5D79B6D2A42BBFBCFB615D1F +:10C4A000FEB24F36E9EA4FEADCAE2BBFE4C8D3BA9E +:10C4B000F2F11DCFEBF2E30EBFA4AB7FA3DDF76B70 +:10C4C000948763420723ECF400C9D310C80ADCFF49 +:10C4D000B857485778A3E0F1BF86F07D2BD8ED45DB +:10C4E000642F833C6B1A83ED95121BE4D37F0D34CC +:10C4F00027E396DD676043216DD7CB1F63F977E3B0 +:10C500006BF400607D37FC215FFE97B6AFDD6953A9 +:10C510007E80E3FBB83C56A4008BD64FAD6AFFE6A5 +:10C52000EE9C3184E8532A96A2C985E366DF27E1B1 +:10C530007A4674E8E934D71BCBBC385EB9E637E3FA +:10C5400072CFC8ABB0F4A3571F36A09FACF4D57818 +:10C550009CC73675DC06955F57229F0EC7F55E16A1 +:10C56000B2A870DB04F29919277B06925391F0FA76 +:10C57000AE72CD90A8976B208F431FA1FC2E17039E +:10C5800003EDAF347996FBD6DD03E24783AF8647F0 +:10C59000A3245D81F2C196ABB032475F3819654E76 +:10C5A0000FFFDBEB9623D67D8EBD5CE4C5F309E679 +:10C5B000894A273DEB2DBD8BD6A1E133B2DE0E5566 +:10C5C0000E3FAEE2B54D95C342B347403BAC5595E7 +:10C5D000C7C2A3DE1A84731EECA7713F686EAE0853 +:10C5E0005901EFA60C467AD2E804388CEEED77D8E4 +:10C5F000A37ABF4B6EB35E2EE6D425E8E021AF48A8 +:10C60000FB4EFAB42FDF5D46F68D468783F11F920D +:10C61000FCB743FF99712E8CBFDB672753FF0FAA2E +:10C62000FC0D1CCD5385BD89F4533651252026DFE2 +:10C63000FA3EC075FE611343FFCE0FBF6E3DB415C9 +:10C64000D6619C6891D0DE014D78E815289FEDB544 +:10C6500096607EFED151663794BF930644E0C2F2E5 +:10C6600092389403A7993015FD77A7D99B71E3C23F +:10C67000F4EEB244331FB7C174ACD38AC32B748EAB +:10C68000758F9FE7B575CD6DD1E7E7B0E9C9228C0D +:10C6900033E751134852189789C73A353800FECB13 +:10C6A0001225EA772EAB58897644BD89917F71D1E6 +:10C6B0008BA3CC683FCF1F27651BC7F4CEE3C144D3 +:10C6C000EE673C09F42687F98B173802662FB43BD6 +:10C6D000BE77DC8F2F63D84F60651AFA3BE3C11E2B +:10C6E00091FBC27756837E9E83AD2372DE8CD590FC +:10C6F000BCEF6F1EE24E833710852F1B12B95F5DB2 +:10C70000C363ADF567AD9D304F6FADC86C3F80BC66 +:10C71000C8CF9994A3B1811D28BF8B2B9EEC44BF39 +:10C72000748D45AA8574A3FD67CF61FD4A4018CA80 +:10C73000CB3D8932F7ABDADC013C7F60ACE292E9B9 +:10C74000B1DFBFDF17B0DFA47F7DBFBFEA67BE8B5D +:10C75000AC9D66E4FF2562C55483807E453EBEC520 +:10C76000E4F3A6A33F717F51289DE9EA355C60BDE3 +:10C77000C3869C0BAA375518A0BF33AA7CFBCDAE4D +:10C78000C7CD28CF4E3FFDE10DB82F5AF82B23B36C +:10C7900042BD33BB625988ECBE8019EDBE057B8D6E +:10C7A000DE00E543136E8E0DE7EB5AEA7FE173B1CD +:10C7B000B4AF5AF0BC25300DDA2F78E1F86806F2F4 +:10C7C000E04C4DF7A17484DFD306B2A399D239FAB5 +:10C7D00066F8BE4064779744B1833F48E476C7A9C2 +:10C7E0005FDA4B91DE0C3B0FDC45FD066F3559C21D +:10C7F000F4D8DB8926AD1EF9BD95A70C813C039FBB +:10C80000DF4DA3C2E757CDEB3DC5FDB90BF69B024B +:10C81000369CDFCE36B30FEA2DD9F977A2EF2B9EE7 +:10C82000DB1D877058B2DFA8936B0B9FFB66E5A5F5 +:10C8300080E78546D63D8DF4F8D7943FE7B5761B63 +:10C84000490E79E30C20B71693C8827ABFF8F8AA8C +:10C85000F7A1FCA4CBC86C200A4E767C64FE15E6DA +:10C860007D8E0A5049D0BF9E0F97EC3C6EC6794929 +:10C8700002EBCE0046FFC117617CC9FAD667ACDB7C +:10C880008C727649B0F1EF46A0B7257B4FBF877415 +:10C89000B724829F4FE23F52FBEA4BB333525FBE55 +:10C8A0003101FDE66C276C8226F5AF2F35FE5EB8B0 +:10C8B000FBDC3605C63FF5FC67DB144079F97FFFEA +:10C8C00063DB4F61FEEC559B847269C9D36FC7B1BE +:10C8D00030F8673BF939D399A79E7C6213C0E1CC4D +:10C8E0005F2C04B533AF7CEC96D10FBFE73F92F1DC +:10C8F000DCE9BE57AE4C413ABB6FDF152903ED2B87 +:10C90000906E039670FC0608BFF27E182705B22FC2 +:10C91000AB69045E4EEDF9CA8CE7095F1A5837CA55 +:10C92000DFC5C16FCC78FE70C8CBBA114EAFED3DFC +:10C930007EE841C89F063C59A2E009D69F2E905E32 +:10C9400001F68174F1DE9B6FBCBC10539347463CEB +:10C95000B16E92F77DF0FB16E0B7B017BF91E5E737 +:10C96000D8D76684FF925D80CFD18857C0E7E8BEF4 +:10C97000F83C8DFF98D4179F5EA7DEBF7D8E95B7DC +:10C980006EC2C2BD8984FFFEF0B968DF8F06B4B302 +:10C9900034F930189CE719F8BC1C4E6F893309E94B +:10C9A000C2AEB8389E03D3A0ECCCEE736E0674F220 +:10C9B00089A9FB2E8443F72B1609CFC916BCF22E8A +:10C9C000F1DD997D7F3223FEE12FCE3001F2ACE71D +:10C9D000EF4D06F9C5DC06678B58F755EF1562CAAF +:10C9E000BA150FE18FF287800F091F819BA6CA2815 +:10C9F0007F0349B4EEC501CE1F8B03076E318CEE69 +:10CA00000BF726A7A0E9AD1EBC1A26223E3FBC0AA2 +:10CA1000E9AF3F7C6AEB9770FD9740F9CFF5FC1BBF +:10CA2000597F31F02BEE8FFAE03770E00F989E6956 +:10CA3000B38806B085CE9878BC4724DE7BE1CFF57D +:10CA4000F377B58FEB9C91FB02DE5E83D360FC3EF7 +:10CA5000D8FABE2BFC963965EA37128EA7BE8EAE89 +:10CA60000F02AAFC58CC2AA6A60DEDABCF4456A2C5 +:10CA7000A467F7CE7765D04872FED44EB0C70D7D5F +:10CA8000E5C5E27ECEE19F75723B66F1FE03A351E0 +:10CA9000AE9D3AF84B952E39DD2FDEF5A15951F5B3 +:10CAA00043205C3EF7733EBC5F9DF79297A3F7B7B8 +:10CAB00064D7DFA3F67752F4DE8AF33FD961620AC6 +:10CAC000747132689C1ACDEEDAEE34E9ECE795B178 +:10CAD000138E0C8176C6B81819D75D5BE37D57417C +:10CAE0003BE64D139DFF33D1F38905CA6B63636445 +:10CAF000F4E7D5C6CD6172981EAF8B8093E82AA16A +:10CB0000F355D15952C8F77401DD39B00908227CB8 +:10CB1000DEA07733502F7D30E66313AEF36F1176CE +:10CB2000E4DF44B63205FAFB9B62F054CBD1F60742 +:10CB3000FAFE7D2B8C4C0EEB7FB1A5FB03F2C7FDFB +:10CB4000BB8DA15D667CD5664079B2649B89F65D3C +:10CB50004B601B8570FB78AB2DA0407EE32FAAEEC7 +:10CB600042BDF4F9360B9EBDB2D7F62DEF7A00E543 +:10CB7000D26603437FFAE7BFACFA12F5F2FC2D460A +:10CB8000DC2AB2B9F6EE27B0FDDCE7D2592DB4FFAE +:10CB9000CC109C809BD9AEA4D004DC8774ED4EF5FC +:10CBA00028D4CF8B8BB1DF33CFD9A9DF33FFFE2E53 +:10CBB0008D73E6DF6349AF69F3077B5B0ED7E360F4 +:10CBC0006FCB3D7C40F41A96877116629ED7377CF6 +:10CBD000ABCA3C947F0B3105BA5FB87F8817F791D9 +:10CBE00061F5A89F2596EE9F7868FFADA409B477FC +:10CBF0000AA5213F2EDCA91FFFBF5579B7C4DC3D34 +:10CC000087D7F7A771BEEDA076F624955ED5F2C85A +:10CC1000F65A7D5B528EAE9ED67EB1855544E38337 +:10CC200064B5DF853BBF19AEEF4F51BF478EC3BF21 +:10CC3000DF6F600AEA67B6C746F169E5E6D0B0047F +:10CC4000E0DB17CC6C1EF26F795C68583C8CF72BDC +:10CC5000556E96C7401EBEA7A9F3C0FA9867D6CEF8 +:10CC60003388D7452FDAE85C65D10BEF7E89F83C35 +:10CC70008530068C9D4AEAF8F2A74007A7B61A99B4 +:10CC800002F6DA224BC8BD19F5D41E0BDB8EFCFD73 +:10CC9000EAEBA4B74E3F6F11C2E3E222D34541A0B5 +:10CCA000066BDF7528C52CBF02E6A3ACF70A6DB88A +:10CCB0006F386C0C54C3D895A2B7E6395CDF6113AA +:10CCC000ED33CECE66F9B8AF3CCBD23C0AE15F7E05 +:10CCD0005784F2E5BF35199AA28C6B3A0F4A7F1C34 +:10CCE000F0C1F9EB983C0EE3C08652BADC5C311C13 +:10CCF000E5AE5182C51590FF81EC7693D3C3E64231 +:10CD0000BA3C81F9107ECC716D0F7FFD1150BAECE9 +:10CD1000313905DBFD2089DBD5F393BDD726917E24 +:10CD20007448A43F543A55F6F1797E6588F154630E +:10CD30005CCEF907EF46F82EFBD02087C79DF4C6DE +:10CD4000837A28EEAB5294DF950B69BD248F72A5D0 +:10CD50001886703D2B0974BE7076B63C243E4C2E6E +:10CD6000AFAE92487E3456B9285D5595CF64F26BCC +:10CD70007B286F54D76F29509811FA419EC63F8B7C +:10CD8000A3C48B761ECE09E3828C0E1FD111C6354B +:10CD9000A11CB33A18ED638D0E85CD453FBF83C30B +:10CDA000C7E82821F898D5BCD8328DE009EDE9FB19 +:10CDB00094645F4512E0D39A31422797CCCEB1BA42 +:10CDC0007C1F7869F8DFFD7F053746706AACB25288 +:10CDD000BAAA6A22C1ABBECA4BF9FF07B86DE470AC +:10CDE000BB94C75AF4C0AD5897EF176E8F01DF3868 +:10CDF000C3F906E0887CC3623C3BA2AC3F32DD5005 +:10CE0000C528F8E6E1AA164AB5EF09FDE8ED2F932B +:10CE1000B81D50C97CD5261C47E2FE16E65458C6FC +:10CE2000845EFF2673294CC63CF22AE2E5480CC119 +:10CE30006ED95F6DE437364A6257B85C5B76BD9C4D +:10CE400082F2CB58F9383B9E18E6479B566293090D +:10CE5000AE1E3AAFAC55F5667D0FFEF47CB0BA4A13 +:10CE6000A6748DCA0FEB547E588F78C6B8130F3F47 +:10CE7000DF6C9ECA482FFE1BE4F93E3EC4C2CF9D24 +:10CE8000E23DC19009F04D3252A63444F1C0472C26 +:10CE9000813C68672F605EA48FF8230F90FF1823F2 +:10CEA00074D19F16AFC28DBD9C133F23969667E247 +:10CEB0007A871979EA37A13D1E09D75ACF412BEE5F +:10CEC000AFFB9B4FD107F30D38DE5733084DCC79BC +:10CED00047F008C6AB3A9AEDA457933D1559E8DFE1 +:10CEE00063472D449F0E8FCF30370C7FC9FDD87517 +:10CEF00095C9D79C40FAFB086D25C0EBC32D436D47 +:10CF000008E7D5A6A00BE5DDEA78AE3FE45280C283 +:10CF100025BDEDFEA0CAC1B8423DBF6BF2559A3C9B +:10CF20005647BF9A5C4D98A2A7734DAEEE4FE2F6FE +:10CF3000DAFCE4922F51AE269EDF427C1849F7B905 +:10CF4000D2A5A53E27EA01E669427B0D6D46B4E312 +:10CF50003E340438BD73FFD4D9CEECED68E7C0AEE3 +:10CF600080E48A82FC4078EA7EED5B68B75B950FCF +:10CF700035D6E9568A73043A6214B72E1380F1FC51 +:10CF800090A9F1ED9C3F2652AAD1676672B62E5E3B +:10CF9000D0987B48407CD5831D4171C5B0BF73E0FC +:10CFA000F9F8814956B4F74493E730CAA9EE5821FD +:10CFB000887AB3DE31DD8AE74A86F842C2FB97B150 +:10CFC0006559039D7B82DD427E5BC9E161C7701CB0 +:10CFD000C6C86F6B94C632DC27EE7674C4E0BEC55B +:10CFE000912CE8ECC4F9C9BE9CE4B0FC281C5DC5DA +:10CFF0001776BB5BED2772BCD1C9AADF324361DE75 +:10D00000B0738B4A8DBE65854D09E3EF9ABCAB5872 +:10D0100067415FBEEE576EEDF87E72AB362B40F87F +:10D020003245CA0B27C87107A58A0028352A59AB93 +:10D030006F1F4374558C70608EED3D76C80F73A2E0 +:10D04000D0D791112914B7D9A36760D75C407A660D +:10D05000E3446E8FA87A86EBA7B3CD76D24F67678D +:10D0600057503CD5D9E61419E9EEC0DACB46233C3B +:10D07000E69C6F6432CC6FEEF94994CE6B7984D222 +:10D08000B296362072C6AAD7CC5D3B03DA1D7FCCA0 +:10D09000E841BEEE0A8C3B5309F9AE660B9E11B116 +:10D0A000AE2DF766A15FBC0BC641FBAA6B4B1ED130 +:10D0B0005717C08DF20DFAFA182F6C04BC9431A6E4 +:10D0C000C619CA5EAC3FE775635B343BA96C9DC56E +:10D0D0001BED7CA7A7BC25BADD568BFF4CC5FF55C1 +:10D0E0000C4778157DF04016AE57E3FFE509208F19 +:10D0F000105E1F5858347FFC94E42B17223EA62460 +:10D100007BEFE5784988EA5FEBA57F3EEE7101ECA5 +:10D110005BC28B2FEE269D9F95FB318FABF62FB315 +:10D12000F6531EA7B697A2972F6AFEECD043905BEA +:10D130005550518244AFEDA745C6F7D38BF7DFA416 +:10D14000C6F9F3F9809D4A74CC001F285F66ABFED8 +:10D150001E80FB8D78AFE4F8EB4603D2472F3DF9F4 +:10D16000E2D06E31ACBEBE663794FFE330DF9FCDB8 +:10D170003FBF9EE49D61F5A88D93E0FBBDAF9B484A +:10D18000CE57375DB6EE0EC0EF176F18293FEFBCD4 +:10D190008DEA7DFA9067E31D50AFFBF726B2C3BF5F +:10D1A000387C25C54D7C6AD2FB092E4BE17CBC5FE7 +:10D1B000E5E739E75793FDA195CF69986596894EC4 +:10D1C000D7D2F739786883C1BECAADBF2B12F13C04 +:10D1D00087D1BD85FDC9B75C57437A6D2CD9FB73E8 +:10D1E000D7583CD1E2A8F727CB3AF933B7B399FA2D +:10D1F0006560173993D5FEC2E4C8DCF389C4074CD7 +:10D200005218C619CF51E549CFFCB69874F2E453D1 +:10D210005B743FC8E164BE8F9A73FE32E2AFBEEB2F +:10D22000FB017D9FA38DDBC9F9B1773D1B27455BD2 +:10D230004FEF3A2653FD4FE3A38FFFB93A7E57D500 +:10D240003CE605B95466817A0E1CFFDE95130B711E +:10D250001DF10986B075CD6D59C8BC61EB9ABB65EF +:10D26000A6B92CACDF5E3C2CFD5D516E2F1E3EDF5F +:10D27000507E5D0DCAA3E492F7916FCA565F3E1AC5 +:10D28000E9716E4B23C1F9B8C9E346F9FA71CBBD18 +:10D2900071BEA8F394757A6B6E8B8A1FB0770BC33F +:10D2A000F0A3E125B27DD75FE77EF910CA9FC7B82A +:10D2B00071D31FBCFAE02D3B3ADC6C291ADCF299E1 +:10D2C0008FE026BF7004E97A8DDD8374DD3FFC4674 +:10D2D00032DF40F0EBC77E057B474849C27119D168 +:10D2E000E9DC164E0783C1AD775C950E8AA2AFE7E5 +:10D2F0001295DFBAAA2A99020C7BCC3C181DFC942B +:10D3000029D601D6D14307FFA6A3834B52D6101DC1 +:10D310007C82F6CAF0BEF83F6656E22EC5739F26A1 +:10D32000239D2B1D8B51926FE3F931288F8FC5F907 +:10D330006FC0731A2D3F7F475EDCCCB0713F6E002B +:10D34000384481DF252911FCADD14FAEC20A26FC3D +:10D35000EFD1CF71F59C38B2DE94E4A2CB52507F6E +:10D36000F8A3FB6BB55493D7C6218E9E7D26EACFDA +:10D37000638E9C2F0350DA94ECBB1AFBA98BFFC978 +:10D38000DD280F8E1D3390BEADFEEBF2E1A8D72253 +:10D39000ED04D87F36E0B9E77263AC9FEC50B1A2E0 +:10D3A00095CE411591ED28C47D4AC5A61379E8377D +:10D3B000ACA494A976E872E3080FEA6123AB781273 +:10D3C000CF49814824AC2FB20A3A3705415882F937 +:10D3D0008D767EEE5A295A254B585CC252955FEAEB +:10D3E000AB4A1E39817E68ABC2A4F0B843C6EDAF2C +:10D3F000FFC47986E97BB3C92779701F6A6025C8A5 +:10D400001726D1D7900DFD9B5CCE314A181E96A4ED +:10D41000F0F3765B7B7B4336B4B7DDF37B89EE1D9F +:10D42000C138E867B3668867C3FDD5266790EE0903 +:10D43000B1DCB0EF6057390A20AFF303C07C07B00E +:10D440000B7F65F0B8BE447AACE6F098882082F491 +:10D450002FB387B6A15C9E28D61931EE68C63D79F8 +:10D4600094DF38EBDB619D51E861C6CBAB3AD09ECF +:10D4700099F172EA2C3C3F98E118F611A6B05DB024 +:10D48000C640FBD70C2CD804E914EBE314D7F89A68 +:10D49000EA1F6BC77C985E6C57E90DEC9CA97B205A +:10D4A0009D61F59B9616F4FAD322C7DDA0E2A5DDB7 +:10D4B000144C1A817400E3E03AEE7C39F02350FDFD +:10D4C000EC8E60E0FA51809FBB58B709E1E8631227 +:10D4D0009D7B687EDD32E651F38CF6A7EF979BB615 +:10D4E000239D44F6774788F777673BF407E95D8724 +:10D4F000BB7F8D6AD91794AEB2B3B0FEF67B0ED95E +:10D5000059DFFE22E1EC11AD46250CAE8022211C34 +:10D51000EE7DE03BA4F45A36BA7F3EEB85379F4759 +:10D52000243EBEC022E0D3408AF77994C35529DE59 +:10D530005F605A6EED768B4037EF3B7D2F221F2EBA +:10D5400036FAB292011EA7337DC393102E1DD1CFA0 +:10D550005F23F93BB7F4F456E49BBBAA4586785E9B +:10D56000B9EFE3ADC897A74DC047B01F78ED818FE5 +:10D5700063916E16010386CB930F2AF3C87E3ABBE4 +:10D5800077F880F1A71FA8FE923FAA7CA2ADF36EA8 +:10D59000644018EFEEBD76DACFDC5D69ECD9672127 +:10D5A000BDDF5DC9E34398D831FA169DDD59A79ECA +:10D5B000B3F5ED07F71191FD7455F95A89EF45DF81 +:10D5C00004B4BB8F57CD6B45F91239CF3C97EF1898 +:10D5D000C2756ECB4C5DDCEDECE6F9ADE17CA8D517 +:10D5E000AFED47BEBE344C5DA7958FC7E48B8B1C57 +:10D5F00013F05E35FFB385AC1F1AC2E861B0F15875 +:10D60000EE146F8F5CA07BF702EC59FBF617594FB5 +:10D61000EBDF5579053B3E0ED7E7FDCF94F183CF85 +:10D62000DFE452E599DA4EFB6EF3F919DA85B6AF0D +:10D6300087909DF0D230EECFF80FD52E600E582F88 +:10D6400032987FA3F7FF63BD3030C5E7D9B658A243 +:10D65000C615A5B9443ECFE0A1226B94F9F5E92F98 +:10D6600024B20BA9F7D230BE7E749391BF6B580CD5 +:10D67000ED6BCA2A6B699FDD08F203F541E47C8EED +:10D68000356DA678689BD92FA35FB4715872760D5B +:10D69000B403A9467E1F5B8C5F16C3BFABFE205B45 +:10D6A0008D5FC6FD6D635E1A7DD7FA6B347039AB42 +:10D6B000F14523ECFB9E27BF98C7351DE0D2F856F5 +:10D6C000606A2CB4DBBE92858C6EC60EBAD346E27D +:10D6D0003ED75F6FA6F3BDC67C217536E4E332AD5D +:10D6E000E41F6B8B0FCDC07B078A4124FDEA8F9727 +:10D6F000AF8945FF6E4D4A07CABF834BCDB4DED517 +:10D7000093F8BD35CBA527FC5760FFF7310FEAD55D +:10D71000EDE77FD182F7FE9423B09F45BF21760AC3 +:10D72000F268FBD4B336DCCFA5605C1DD0D91653AC +:10D7300090E6B5A9DA42FD6E6A339746C3DFC95455 +:10D7400091EA070C9D141F9CC8823684EBC353A733 +:10D750006FCC8576D9B94CC2FDFCEA82B3DABD72D2 +:10D76000233F8FD2FC88CCA69E6759D5732ADDFD56 +:10D77000B8CDFEBDE43FB44F0BF274AA40FEE7C83B +:10D7800079DCEBE27E37FBE48EA9A827EC85023337 +:10D79000A07F3397D1BD66692A58E19066E7B37ED2 +:10D7A000DAF3754B5E685FC8DBA34F48BAC0F60B6F +:10D7B0005D3CCE700DFAA1A03C60F218AE817904F8 +:10D7C000AE970C8ADC5BAFCEC5F56B2BF41F22390C +:10D7D0001AA075B9F38321A43777B940785A33F189 +:10D7E000189D0B3C5CA8F9513D348F2DD5EF1C40A2 +:10D7F000FB6BCBFD8CECA42D2843A1DD96EB59806F +:10D800009F27B134946F9BE69BAFA3F3FC0280BFCC +:10D8100081D2A8F3F6A55A892EDD2B1E0EE13DFE1E +:10D82000180FA37713208D5ABF2195C369932990B0 +:10D830008AFE91FEE8E256151FEE4AD5AE627E17CB +:10D84000E275AD0A1F76CB58EE5F10BD72781C579B +:10D85000AF3EE17E0C581FDDAB4DAC33933E12A6BC +:10D860008566E0BA12F2CDECEA6CE42F0E376594CF +:10D87000C0E3CE58A005F9B3EDA2648A275D250464 +:10D880005CE86F568ACD749E7C70A230631E94AFA4 +:10D89000AB33931F02F2C42F7E6F4E1BF29B7D723F +:10D8A00071E93CC8AF97CC12C2B7B640B2211DD7C0 +:10D8B0007A05C900F9B525DA3D091683781B63346A +:10D8C000DAF2A1BC3555401F2D6B351888DFEBBD52 +:10D8D000C5FEA1F0BD5E721AC2FD002FB9F8BEAA46 +:10D8E00022ABE42517F28DF761FF5099E3529C407B +:10D8F00024467FB12C340F636EDAEA9FA0FB546B91 +:10D90000C65819DAF199F7F9E97E57EC456619F12D +:10D91000BAFD7CE2485A5F9D59467E5E6F085C8383 +:10D920007CBF65E92105FDEAB68F1CCC08F682A311 +:10D93000F3EF55183FE62834479C633101E5B836CC +:10D94000AEE3AD10D153A7C1F7E758F2FF1434E5A9 +:10D950003BF11E46CC0484E7DA4BDFCB9F13852EC8 +:10D96000C8653B16ED6521346134CA29AEC79828D5 +:10D97000A586E3777D66DA5FD0CFB4AD08E68FE3A6 +:10D980005576DD41F3F2BEF353B4AB1C473FFD26A1 +:10D99000FA3CDF243D127BD41E124663BA681AD9C2 +:10D9A00067E1F540EEAFCDF29E70017C775773B919 +:10D9B000DF7C0FA37729F02F3F0CBECD0520A5E912 +:10D9C0006102803CD62B90C88FBE4A90832184E7A9 +:10D9D000682BD1538A7AEF2172BDF6A38D4B31EEBD +:10D9E000C8EED1CFF32B15BFF82726D379055AA25D +:10D9F000CC9C3ADB86F26FCF583915F7DB0FC7475F +:10DA0000D7F3EFA572F9B0DB10DD3EFF22D5C6FBE0 +:10DA10000759199A40A86214D707792199CE6DF851 +:10DA2000FB0A02970BEC5A467A2F6E4CA7CD1336A1 +:10DA30005E501D87FEA09F216A3B267587AA61FD67 +:10DA40006D40B578AF2D2E93C3D1A1F4C211EB4B2D +:10DA5000EABA800FAA8717221025AACF4ACC742EC3 +:10DA600002D250F956E88543AC5A7FD344D1608541 +:10DA700079E500300C503F7EAA59778E22D5BDA3A0 +:10DA800060F94F8D4C4E98D83BFED6312C5003E3B5 +:10DA90000FF1EAE11D7BDF0BCBD12E8FA4039C415C +:10DAA0004FBF182A3E5BDF2EF98E3E7C40F0A479F2 +:10DAB00002689ADF62DBCD0094E69DA2161F4BF24E +:10DAC00077BCB143417F28C0AA641FCC7FC4536F89 +:10DAD000797741BED9C7F92C36FF85E54897521AA8 +:10DAE000C7D311F42D039C3733E91F18B7A3540A89 +:10DAF00032E2635B2887F47823134B104F8D15EFC8 +:10DB00000828D757EF651E8301E9FFBF2DE1F39B7E +:10DB100091CACF69982893FC13DDFCFEE8EA02C1A4 +:10DB20008EF2F5E0D21748EF6D3D2030E4FFE2DFE2 +:10DB30001C7DCC8E74FD170BE59B5FAF20B9F113F4 +:10DB400068A744F19F0FA69723EBE72EDA6EC0F388 +:10DB500089AC79417A8F25D12F7AAE467CCCEBF017 +:10DB6000D23DF7427ECEE6981652288F5A0D6C525F +:10DB7000D9AFA6CDBC9CDD9240FBA85196CE866B5A +:10DB8000617E9B9F1219EA4BA325983A17FA35BE7E +:10DB9000E8404DD0677FB4795A2815E5784C058563 +:10DBA00041F7B5E352391FBAA7C9BF1D06FDC64FDD +:10DBB000E6B0B4F9530EA0BC449B19EF35D915AEAD +:10DBC000E7D68A012FC679AFBDCF67C6F199BA7F74 +:10DBD000695C54F604C2F91355EFB18A79F48E8961 +:10DBE0005BE5177B252B8AB6CFDAE88AE1F12D0FAA +:10DBF0000907903FDC5E46FA43AA0C8686AB7A1989 +:10DC0000272EAD78BE11F58BA35CA075AC153BAA91 +:10DC1000F15D89B5F731A95AEEDBDF3FDB7E79AAEA +:10DC200085E0B1D1C574EBA0F73040BEB9E7455FE0 +:10DC3000C7BFE1B8E37BD711A3AD23BF93F2DA3CB2 +:10DC40005ABDC10B9AC706B53F7F2A7FC7C85EC0C1 +:10DC5000DFEF8894F735F60FE85D9900D8EA46BA09 +:10DC60008F16BC16F3F27302E3F7B5F4FCDD27AFB1 +:10DC7000D255E47799858D938D74C7F10C74A7DA2A +:10DC80004FC07756140182FC2DF931FC34CF487A0D +:10DC9000FC5F978BE1F386FE631B9841BDA72A17B3 +:10DCA000A7F6958B4C958B56A68450FEFD5FCB4511 +:10DCB000908324179B61A589B053896D6F5A8A7A26 +:10DCC0005C9387E31127976227D6EB8B0B685F4441 +:10DCD000F909A9BF6FC6F8C855827ADEA5C205DD6D +:10DCE000500897AF5D728F9EC2EF1BF01F39F89EF0 +:10DCF0004AC2750530DEC6D29C31B8BFB0F95F2488 +:10DD0000FBC05DC0E357DC95FCFCDC9E3BE789F083 +:10DD10007B714B52B99DBE44A3BF4ABF0BC7598B01 +:10DD2000FDA27CCE3593BEDCCC825C1FAAF6E95600 +:10DD3000971A47ACD255249F44CAA771BF7716A340 +:10DD40007C4F355824DCCFA17E3E98ACD7D7482FE6 +:10DD50009ABE6EE9A889477F58B6EAEFCFB6EAE3E4 +:10DD60001C26A4717926A6723FC02AA182F69B4A7E +:10DD7000B140FB388DFE7AF478041C23E18784BA25 +:10DD80007202C5C7503EAEA89B21FF6E03925D8F05 +:10DD90007A2C5583BB44706EBB53188BF2724F7B49 +:10DDA000990DFDEB06B7F51ADC1FAE3330BAFFB89C +:10DDB000AEE84D8A2B69AA849E61518E7C61A6795A +:10DDC000745F3C031FD37ED5AE583AD0AF150C6DAF +:10DDD000A7B885A6C0A1198CDBB10CE3529AF26BEF +:10DDE000D216A07CCF2F2944FCB6D59B296E46CAFB +:10DDF0006751FD0827711F43F3FD6E7ACCAEED2FFE +:10DE0000CBA3EF2B6F4CE3FBDBA008A20AE69391B8 +:10DE10002F7890FF33EACC51E751ACE2292D8DDF0A +:10DE20000F6BAB3F44EFCC00BE026C207CC1F46BA7 +:10DE300092C3F031A91F7CB8347C881A3EE2671285 +:10DE40001F7676085CDE925E5BCBA4DB503F2A1522 +:10DE500066B2631B4D7C5FBEBD40E50BC9DA86C46C +:10DE6000F65DE93A6E9140F7703227F2F7F5ECE58E +:10DE7000CF535CD366D6FD3ACA3BA580DFA38F6C37 +:10DE80007F679AA0C2513678683FCDF10878A5F92E +:10DE90006CC94B6E0BE7D38DAA1DBDD1C5F9744B70 +:10DEA000FD06E2D30B9DA726B76B553B7ABED7671D +:10DEB0004675A0184AAE4A45FDF973FE1E15333A61 +:10DEC000C82EFF049B84F9652B337C4BD2C2FC72B5 +:10DED00092B742C07A57E2BB42D0FEE320BF07FAB6 +:10DEE00071F01745F41E978F1133CF671D066272CC +:10DEF00090A13B20EF128354EE9A077389A7DB9120 +:10DF000094B75A412FC2844E57F1FB175DF8BEE417 +:10DF1000707C2792BF2FF999FA9EE4A89655C59B6D +:10DF2000713C59F4A1CC3889EF4BE2FDE789EF5100 +:10DF30005CF42990B54DF1180FC3EF6F4B0F3249C8 +:10DF40009884F935C518F77CEFAB16F59E64470D3C +:10DF5000DE7B795C60F48EC46A11F4FD502C6A306B +:10DF60005484D1F1EECB3BE2F09CEF74F0E601FD7E +:10DF7000C7787F10E7B143A5F7F5F6C574BF6C8E7F +:10DF800023E4C6F607F63CF9C42618EFB37D567AAB +:10DF9000D764A37DB11BCB3F7BEC5D37EA8BD3FB12 +:10DFA000DE35473B9F5C2406AFC27B64E5CA105652 +:10DFB00003F32F0ACE3453FCC9AE03743F6D91E4D2 +:10DFC0003363FFE52D7B283F65D79FDC587E348D7A +:10DFD000F3C7E9549F1BFD12B92D969000FA67779D +:10DFE0008E7F41D47376951ED7DB5FA5FE37DA5F4F +:10DFF0003D847839FD9885FC6E071EFB0DF57B6A24 +:10E00000DF8B34DFCF76BF7B17DAD3E58C79509E78 +:10E010009FB6A97E3D6B475CF8FEF615151E5AFEAD +:10E0200074ACBA0FCE18A49E7A1EC31C007FBA3FF0 +:10E03000D01187F70B3F33F9CC088F85080F488B39 +:10E04000000E28F717060D34CF852D6D74DF6AE1B9 +:10E050005EEE1F5C08F022B8B41CA0F9BF8F7019E7 +:10E060008FEBF8B39BDE75D86BA1FDB3B6EE850ED2 +:10E070009F1BE1A3AD17E0C0D7BDFBC2F03447C37F +:10E0800053CB9F685EE57BF9BCCA77F179CCD90B9D +:10E090007872209E6612FE4FED6332DE83E9DAF37A +:10E0A000EE49B4674EEFB3CA685768F3CA00711BF4 +:10E0B0003716F988EB63B6D740FA98891D749EB37A +:10E0C0004892247C9FA0A73C600E7079DA519C0E88 +:10E0D000E5CF3C0AF62142420A8E40FFEAE934EDE0 +:10E0E000FE4F871BFD62BB2FF7137D7E1AABC25B11 +:10E0F000EC7063FCCC8674DFE9B4B07882D31FBEC9 +:10E100003802D7BDDC58F19B4C1CE7491E1FFA555D +:10E110004EC5DF1EA2790FD59D3746A600B7383C05 +:10E12000FFCE17988FEE25EF7D2D26FC1C5A48E771 +:10E130007EB78DF60FE83EE2697CE791E613A438DE +:10E14000AD61DE32379EF37DCA1C3E3C97FDECE7A5 +:10E15000AF51BC4D57AAE67FEAA07AA7F6BE9680DB +:10E1600069991A0FCF0237931C03383658C7469364 +:10E170008FEAFDA200BF3776C6000213F5C4560D24 +:10E18000CE15E6E9BA731D2E4733B664B793BF25A3 +:10E1900010FDBE59A4FCCD7D74129D2B9F63D1CF81 +:10E1A00095991A27B7DC1843F1371BED3FA3FBB74E +:10E1B000958A45C2FB2BC754B97842BD97FF554C91 +:10E1C0009C2200DDEC4FF7E5A48FEF7B0FB76CF5D9 +:10E1D0002237C2B70CCF3D28CEA0ED7A8C27EC4A6F +:10E1E00062AADDC942043F9356BE9197C7F3FCA4CF +:10E1F000CDC135F81E26C297D77F829767F3F21FED +:10E20000A9E573D24AC6A473FF0EBDAFC19829BE5B +:10E21000CBCA55783478F4C245645D9A5D0D95E7B4 +:10E22000E1E5DC24EAEF32EA4F84FE467DFFFE00A2 +:10E23000EF8A35E15FD08FF55FD54F90F492E0C360 +:10E24000B7AEE09B87EBBFC78B99D414FFFDFBFFF4 +:10E2500067DB2F377A854F910E870844F71A5F776F +:10E260003D367C0CEEFFCD0D4B43A836BB628BCD0B +:10E27000A9F0FD9CCCCF4FEE79743D8B164FA2BD1B +:10E280009BD19357CFF1CC43F5E7B3ABD3B9DE596C +:10E290009DDEEB7FC373393CAEA28D33FC35275333 +:10E2A000280CB7D3598580F187F9ED567ACFF7223C +:10E2B000068202E63F928504D4DFA35827E52F4665 +:10E2C000100CC5F7A8647A38731CEB768B43F1FC0D +:10E2D00039B412EDB4F79DBEC67418EFCBC73A3E01 +:10E2E0003040F94FD27C2F75A25F289DDB570EF589 +:10E2F0007D5C0953A043C13ECD154DEEF7C05312CE +:10E300004F859FB7DD287A1F49A7F564485DF65E03 +:10E31000386BF26081FAFE92D6FEE4534FE2563734 +:10E32000ECBD70EF80F781E754CE7FF4E7E3062879 +:10E3300057E5ECEEEAC06DE1FAFEC974AE679F4E98 +:10E34000177476218C4A76DCD33771FB69F7E5DEEA +:10E350009AC751DEB618693FFD69CB9FE9FDC773C7 +:10E36000258CECBAFEC6FD3402EF9FEE78328D9F0D +:10E370007704F4F1CB4FFC724478BC258059764E7B +:10E38000E0EF7010DE0F79148B91EE39923FC6CC1E +:10E390002A789C0ACE17D218DC8F0E453C75501A8D +:10E3A000C7BA29959844FEE904E6A1D4C94A284D84 +:10E3B0006615066EDFF9294D63414A33D03E457F2D +:10E3C0000FEBA654C61B9F61F11B3978623A14DF2C +:10E3D0005D2DE1DF23E28344C4E3B828F23C222E22 +:10E3E00048DC5949F21CE382F29C7DDF53D0E4F70C +:10E3F00086F4E2F7906EF6A77BDFC7F4F0B3BFE5D3 +:10E40000F72BD618C8BE3E6E9B66960175CF247852 +:10E41000E91D104560253B40BFCFD6FCFFF8A7C5DE +:10E420000923309B4DA7C2E37798D5918FE7C5B3F9 +:10E43000D4AAB3D4739059AA1F248631F59E9E871F +:10E44000EEDBCF52CF1F6645F85F98DFA2F3A3281B +:10E45000F80F58C72CBF81CE0D66C54C7BB593F520 +:10E460004F2761FDD1BDBFB2083FD4A0FEAC88FCF0 +:10E47000ECC8F65603B326E3774E4FCFFC4026BBDD +:10E480004EF36701C1C9D4AEC1F221F985FC577AB8 +:10E49000C3E19490C1F9C4E6BF3A2EDA3BD95A3AA7 +:10E4A0001BEC335342DFF6B0238C47BED7E4B046B3 +:10E4B000E7D9B8B1453ECA3707068A4B5DADEAFBDE +:10E4C000A687FC0CE76D0B3D40EF54DF9FA990AF92 +:10E4D000D65A10A0FB0131F9019712657E4DF8BEA6 +:10E4E00033F05753ACFEDC64A9BAAEA519DC7F7BD0 +:10E4F000E8A2E4623CCF5E250B746F7895BC8CCEAD +:10E500005907FB3D815AF57704B4FCCAC46D0CED84 +:10E5100036DBD7AD0CED499B18FD5ECA0C75FCF5DA +:10E520006AFD8D89DBC84FD290C7CFF723EB1FC898 +:10E53000DBE042FBBB311BF6BB983EA450FFF579F4 +:10E540001B4AB1BD35D4A8BBCFEBCBE0F6AD752FE0 +:10E55000A74763AE399083F420FA29BE40ABD7D8E1 +:10E56000CF79D2F56AFB265380EEC934A9F6D0D212 +:10E570002DB16BC92F97B1FD08BD6F95CBE8BCD10C +:10E58000167A8ACE11ACF9666683BC55F6337C5F89 +:10E59000C3561024FCA0B329A4A3DB98DE77368CE5 +:10E5A0007DFBAFFBD6EFC2F53566FB69FCC1D65BE0 +:10E5B000ACC2B351D5AF8D36FD39DAC20CAE57AF10 +:10E5C000CDE0F2DEFA32237932005CC8DEBB3E23B6 +:10E5D000EF06B4EFACFB0785A3AE7E362B1D128D84 +:10E5E0005F22E5BFA340887847C940F33AB7D7A078 +:10E5F000BEBBC8DFB1E8B5038266ECF7D75BCA0ED5 +:10E600005E03F359E07378317EF2C92DDBE99EFE9B +:10E61000C2174D149F30AC732697832DFC3D46EDF9 +:10E620007DA38B5A2CBAF7A416B1B0F71A61BC853A +:10E63000473F3DCAE89EB1FEBBF66EC06AFC10259E +:10E640004E2DF2DD81473222DF5D56DF1D2888EE38 +:10E65000A7897C7760575020BDB10CE358691FB083 +:10E66000AD18F73D95470DE437E8CB87F2D65C53FC +:10E6700058DEE0217A546263BC3BA2F0D37B999CC4 +:10E680005E76E3A11AD9FD3F5B1BC237BB581DC3A1 +:10E69000F3A6DAFB4409CFB56B033174BFA456125D +:10E6A00002183792195B6C45FF238B1724BC8776C1 +:10E6B000957132DD7B32DF2F8EA3775AB72FE8C0FA +:10E6C0007B75B52E91211F67C6F33802962AD0FBC1 +:10E6D0003475D29BF1B3701FE7E0F7F4B2241690C3 +:10E6E0000D68D779199E2FC366A52204A657A6C127 +:10E6F0001BC2F7AED8248BB483BF3373C39809E42D +:10E7000007A6BF036D57855EC171BCD612C4FF94C6 +:10E71000FB9D640F065C467CDB947D9CC1CF05CDE0 +:10E72000B1C5A1BFE2FC66D8C9B71B508404C4C3FD +:10E73000EB6D2BA75F0DDF4D0191E21DF2BFA9BD6F +:10E74000ED6A68DFDD66A6FB161A9CE43A51F77E97 +:10E75000837B853E6F8E78AF426461E5903FA2CEA9 +:10E7600083B152160A8FE3757AF9A1BBE4A0F729A9 +:10E770003E02FEA4F30F35FF9E9ADF69F213DE77A7 +:10E78000FED540FED5836D73B2485EDA17B7DA71F5 +:10E790005F78849F63F6279F7766C8DA3B0936F572 +:10E7A0009D0A1BFABD22E9A9AE8A7930CED01A683B +:10E7B0008F1989F83D6CF2605873BD2A1F45079781 +:10E7C000E31ADD44A6F511F4576FF2E4FBA17EFDD8 +:10E7D000374675DF78FA86D0640C7B90695F6DCA26 +:10E7E000601E640F93B3234D82798C7CD1ECC1DF22 +:10E7F00055B8EAB9822128E747BE3683E41BC289AF +:10E80000DE87AF347BD04EB6543A3DE238ACE720D9 +:10E81000BA3CEB30933D2456DAFD647FB54D70C9A8 +:10E8200061726F6595E4114DF47B3794AEEC47DE71 +:10E8300067C50B25E87735ABF672B2BAAEE44C3B50 +:10E84000A5496ABE5554A6233DB702DD60DCCD81E3 +:10E85000159CBE97A55A496F2E7B7D68CA40FEC1A4 +:10E8600027AA5C9E5C00ECB61565E4B72D7AE044FF +:10E8700023D2DDB258AB8474688C1BB67132D2FDE2 +:10E880006F4D74CFB33676823C2BAC3F63DC4417BC +:10E89000C2C328286948CF233383378893904E9486 +:10E8A0004D789F7FDCD68D3788205F76C62A6978C1 +:10E8B0005E76D9D6CDBC3C49D96480F22BB6B6F28F +:10E8C000F24C254D80FC755B1FE7E579CA26CCDF4D +:10E8D000BCF5495E3E8AEBA3DBB73E7303EAA35A5D +:10E8E00093A714FDD3CFC2FC0BF2F09D549EDEA97A +:10E8F000C2452B7F1EBF9BF05D559E4696BFA0B6BE +:10E90000DBDF4FF94B6AF9CBFDF4FFAADA2ED44FC7 +:10E91000FB836ABBF67EDA1F52DB1DEEA7FCB76AEB +:10E92000F91BFDF4FF07B55D473FEDDF54DBBDD5B7 +:10E930004FFB77D47647FA297F4F2D3F1AD1FF0737 +:10E940006AFD4EF5BB3BB6E13DB4D7DC20AF509E2F +:10E95000E4C73690BF6B5B6521D17FED78AEFF35A4 +:10E960007A77ABF702DECEE471A56F6772FB66794A +:10E9700026B70B8A1EC85D3719E9F0F7FC9E22E81E +:10E980008F23780F57794020FFDEB2D7F9BB32CB07 +:10E990001E1075BF1FA4B5D7E61F50E759A7A64B99 +:10E9A0003273689C6CC5E59916A61F4D923E6F05A3 +:10E9B0007EC2F8FF3A27D733F90F1437E0B9492D53 +:10E9C000E8195C5FBDC31C42FF57BD2452799DB35B +:10E9D000D88FE7FD8A24921EAA772684F0BDE6BA76 +:10E9E000BA42DD7B9F759248EFC788F153ACB31CE8 +:10E9F0002837A649283FEB98945044E76AB04F4324 +:10EA00007D52592CA1DCC98E7726A05C9E95C5E16C +:10EA1000DE1EDB65C37B14E24302BD15304C128958 +:10EA2000DF73EB84800CF368979691FF7547B37A98 +:10EA3000A6C8F879A226E777FEEC2AD263B5A0C76C +:10EA400064D2636CC898E4DEFB9BE2D19166D45B30 +:10EA5000529A9199402E1FCA4CA071773CCAF55624 +:10EA60001EE82D7C67ADB590F177DE5C56F2EB9633 +:10EA700089CC9518E6C73C946954DF47E2EF50E72C +:10EA8000E17B8861F01DEAD7EBADEC41F4565625E9 +:10EA9000C8CBB0FA1697A4CB3F97A9BEABE4611ED2 +:10EAA000B46FAE7A6E0BE993B3A84F18EA973FC4E0 +:10EAB0008C44FD027AC4C2FACA414D1E6B768B2685 +:10EAC000A76B55BD511BA1370697BBFF787D38D189 +:10EAD000A7A07B87A63FF9BB1CE304005E269F81AD +:10EAE000F40A137D74BF7F30B8994C2512DAE383A2 +:10EAF000C1CF94F4453CCA69934FF49C88724F6A25 +:10EB000030F86AF5CCD6F4ADA8D7BE38BA3C1FFDB4 +:10EB10005E2B4D1D337721DD1A86D0FD0E59F53B56 +:10EB20006CABDACF8EE7E1EFFABCBFA56E1CDE1F3F +:10EB3000F74AE42F492D96B19D0DF6E98964C7F196 +:10EB4000FD26937CFE0568CFBF6896F15CE0F0B3CC +:10EB5000EAFB0D990E82E7BD7BEEA3762643858BFB +:10EB60009FF73382F7AAB404B2CBE59D56D56E3C2D +:10EB7000BDCE0B65B542A701F5CF5BAD817556D40F +:10EB800027EA7E8029811B71FF130C98D5A01ABC3F +:10EB9000E8CED81EC1A0F99FBDA22BDC0E35DD3812 +:10EBA00065329E874A2345E82FD56D5B67CAC472DC +:10EBB000416BEFC5CB4328BEB4BC087878A65D2B6B +:10EBC0004F593705E6B3C7CCB4FE15ACBF071F835A +:10EBD000A4BCB40EFBDF5DACB6573E5F87BFDF055C +:10EBE000F3B9CE087BB0E1DBD2D639527BE79BD3B9 +:10EBF0002AAFABCE052A943BE3701BB7A8ED443295 +:10EC0000EAED55A5FCFEB0F6FB59DA3DE21EBCED7F +:10EC1000BD494157ECE787FE33AE008A96183B0F9B +:10EC2000D9016E8BF657584D02BEDFC5DFEDD2DA43 +:10EC30002DDA3B93EC9C252F17515C70947687F16D +:10EC4000FECC3FD1CE6ABE80F14E87DE5CBC4BC6A7 +:10EC50007B33150D0E23D567DCFF157D7D5AFBD365 +:10EC6000BBDEFC318E7746EE4CBE166AAF0A015C05 +:10EC7000A2B4D3EA6BF7AB27B9BC13DCF0FD3FDCE1 +:10EC80009C0F9958E1413F53D0EAA77B6C3693BF64 +:10EC900004F509803E80710A5A3AC99D4BF523BF9D +:10ECA00047F257D0CA12A7A1BCBC4FA473F7A05516 +:10ECB000B18F867C33EC53AA614A3563DE198BF140 +:10ECC00002CDFB1C24D76BEF6B77E1EF2B291E33B2 +:10ECD00043BBB7F9F28E5409E65177BFB9F4E74860 +:10ECE000BFA165AE7BC2ECB09C2C1EC79D19EF2F57 +:10ECF000457EB4013FA23E6E34F9ACF86E8A922A8A +:10ED0000505CB50DCADFA0F24CB5DC33F56ADA977A +:10ED10000912CEAB3E77F6D462D46BAE04D207B6FE +:10ED2000BC29A573A13C20992524AF8AACB2BB11A4 +:10ED30004ECF889E0AE4BF671C0E09E3B14056928D +:10ED40003E10F39C149F6551EF3B658EE17ABE67E0 +:10ED50005FEE56FD026E1EDFD31CDB715311B48BC8 +:10ED600079509014E8BFF1FE0D25189FB8F5FE7795 +:10ED7000FE84F1AD4DC922BD33B0BB3AE4C57ADDA6 +:10ED800006D6B11DECC83595D33B703FBA86C93263 +:10ED9000DAEBBB0DD3FDA89FBB9344B65DE6BFEF96 +:10EDA000101EAFEA28D0C74B6594EBF36BB37C0F12 +:10EDB000BAC7633C5061118E936490657C3AB8B0D9 +:10EDC00083517C7E726EAE8471DD71851171B0935A +:10EDD000F5FD244CD1973BA745C46DDDA22FC7DFBD +:10EDE0004F08CFE3EF4484E74F223D523C093F7F79 +:10EDF00088E145009F2718EAE9C6AF87503C2BC23F +:10EE000011EDF69861A207CF4532CD1D33300E8E3D +:10EE10008D88217BE9A03B86C990B72C66244F2DB5 +:10EE200009C103B85FB5085289421A2A78E0AF5089 +:10EE30006E87FD2ACADF48F8656672FFA043FD3D74 +:10EE4000B0A018223BC2F6C010A9DA835BC7083F06 +:10EE50006C79589EC77B6F77ABE7282E2D4E8DF0CF +:10EE60000A2B43BC4D62017C8732F3FE134A08E64D +:10EE7000B146CEAD403B6395D049E328650E1FEE09 +:10EE8000BB9330CEDB88F1DE0AA591F8D8E3E6F635 +:10EE90009FCC66FB118FAE9902C58FD41F8AA9C380 +:10EEA000C3977AF5BD062D8E4DA3CB97DCDCFEDC37 +:10EEB000D32E085EF483DF91BB1DF1ADE55B7C4E84 +:10EEC000FA1DCECC31159D4897EC7A6E87821EA034 +:10EED0007BD95A9C981657F85196999FE767093D38 +:10EEE000F80B6971446171E0747467C4A30BBF844B +:10EEF000E73D99634A2494338F68F72F18EF179FE3 +:10EF00002FA473836982F722D59F8E765DA23A5E25 +:10EF1000A253F4D2FBEE302701EA3FCA78FDC4DCED +:10EF2000BDCBF1DED51E241CE49F7B389C23E93643 +:10EF3000B5DD5F320AE165007D98D1978E0DEE1642 +:10EF40003A0FAC7F902558C6F4A5EBF1466EFF74DE +:10EF5000CF9729CE72303AFFC41DCFFDD8499B24EC +:10EF6000B46FD3721FADA67B300F3209F55D5A7BAB +:10EF7000C74DE8F78AE487803D6E2C8F93FB6E7E49 +:10EF800078A391F3074B11096F91F1A591F1A43981 +:10EF900059F1AA9F02F4402CDE0790AEC038C1EEB2 +:10EFA0000718BD1350FC62F36DBF83FEBECC334B1C +:10EFB00028AFB3DEF23D6987797DF94B5F16CAE968 +:10EFC0006D62A72D3ECCEF290AFCFE59A4BCCEC928 +:10EFD000E27427A3DE70FDF36926D2F710FC7DBE34 +:10EFE000E4919284FDAEFFA335E9FFD06E61563FF8 +:10EFF000DA2DEE762D9F417658D65B3C7F893B63B8 +:10F000009D928B702B277FD1C1CC39E42F12DFE387 +:10F01000FEA251466F00F3EC7D1BC5DDEDDC77C72A +:10F020003C8C57AB4FBE5646FD3C4EDDFF8CC9D2E3 +:10F03000F85BBF7ED1ECF521DF447E1F99A5C59515 +:10F04000947C3213F037EA7133C5DDE50B65F47B50 +:10F050009CDD8D46C26799515EBC3A6C9FD6945C2C +:10F06000549495C47F97D8071B06F9BC81F980D9C1 +:10F07000DCCE634548AF59C066285FB2146E406667 +:10F0800055C6305F189DCAE745AADF94EC2DCAE249 +:10F09000710874EE635259FA9984123613F5327C72 +:10F0A00043BD6BDA15C3CF7B9CFAFB9146238F17C8 +:10F0B000B9415DBF09CF75C6E27B6F42C832BA6FF6 +:10F0C000FD9BD57AA2D511320E413FD91B47E8DE10 +:10F0D00065C43930EE6F292EA79C911F14E142F9C7 +:10F0E0007B25FE6E77258F07A85DC10C781650AB87 +:10F0F000DE5351EEE2BF4FCCBC5E19DF57A12DA607 +:10F100008CFF0B11FFBAAC2C01EBA7B20E8A636423 +:10F11000ED4CE6F112FA73A76DFDBC03A5F901C42D +:10F120004A23ED5346BE66A3714D958CDE09A73781 +:10F130009B70FFBB82054443AF1FEEED4C99DA692B +:10F14000E7B1BBBFF9200DE572BEB0DDF706D90D02 +:10F15000B1D276D48F317A3ED4EEAFD5A874B2ADA9 +:10F160004A227C6BE56EE518C5DB67B1EE6ADC67A9 +:10F17000655526E8F0DCE3973D9FCE7CE3C2FB0DAE +:10F1800070BECE15E99D2EF9BC9BCAB755C983F454 +:10F190009FD34FFFA9444FFDF79F41E5ADA12FE25B +:10F1A0006F00506CEB3E115F22F7DAAD917076AFD5 +:10F1B000D0CBEF8BF747C69373B8D84C5EE74D00C2 +:10F1C00037DB4382A78DE1EFDEE8EB4DCD3E17CF75 +:10F1D000CFCBB5FA21E7CD581FF6BD6D32FE8E8E2E +:10F1E000BE7E49D147F1FCDC5DABCFE7F7C3F3FA54 +:10F1F0007A91F8899C2FCC2BE94761F3BAC26AD186 +:10F200009597CEEC33AFA45BC3E675B54B5FDF5784 +:10F210001D7D5ED7E55B069C9756EFC68917562F76 +:10F22000721D374FB5F403775EFFD6D20BEBF7F6BE +:10F230007903D7BBBB32721C85DF53377BDF46397E +:10F2400057C6E495F84E3873C4448D0B2E52F9E33B +:10F25000EFE8A748C27800EF516CF779268F4B3959 +:10F26000FCEC023F9EC32CDB6796F1BC2353F55B9D +:10F2700083E05988FCBBC72AC5633CA0C52DABFB06 +:10F28000AB8E6C8CE7DBB3F39DDB48EE31BD3DC349 +:10F2900098A708F5358830BA97F1276C97141E4760 +:10F2A000E125FBAF5EF0FC99F6553FE6FB2A2D7E8B +:10F2B0003FDCCE62137AED2C2D7E7BBD3ACE3759E2 +:10F2C000DC1F08763EFD3E6A72AE48F1CD8F583B9A +:10F2D000D6E3FDA3479CCE78DCCFFC469DB76637CE +:10F2E0006AF71A5266E68E3146819796FE0F29DC40 +:10F2F000A2280080000000001F8B08000000000012 +:10F30000000BDD7D0B7814559AE8A9AEEA57D2DDE3 +:10F31000A90E9D178F509D7720840A8418909126FE +:10F3200009195486E9A022E80C360908485E181F1E +:10F330006165C7CA431E51C7384604046CA228BE83 +:10F34000669A59D488C16DA3C3E82E8E61D7191D62 +:10F35000C7CBB6C05506105ADD41BDABC33DFF7FDC +:10F36000AA92EE4AB7C2E8CEDDEF663EA73875EA4C +:10F37000BCFEF3BFFFFF9CBE2B81AC0C1411FCE361 +:10F380004A0971E6E4F476B9091957E215A7D0F7EE +:10F39000BFCD3410328D900DF44168BD9227F877BF +:10F3A00073F4DF2221EBCBE8F7D0308B9007C44118 +:10F3B000A740EB1F7009A2C2413B09DBED7DCD6088 +:10F3C000F0B80879E82739BDBC7BB8BCC5E7DA05D9 +:10F3D000E57106E20BD8A0137135A1EFF75A446727 +:10F3E00057092D0A83EE1A3B2DEFF9C3759C8390C4 +:10F3F000CCF1F45D0A2175AD95E4D854429E378571 +:10F400005F3D0FF3D9CCF977D37E5EE829A9166862 +:10F41000FBE52708B1D24FEBD65EF5C0F151844C25 +:10F420003F2ECE86F775DB9D324FDF370E3657C342 +:10F4300038A499C8B9322169FC6CDE4EFB49BBFB8C +:10F44000B0DC41A7FCE080D417A2E5F02E4EEE958B +:10F45000A07E4DC91A808FCD23D9E87A97C254F186 +:10F46000BDB3DA08EDAE32C99DB49FD346B208E011 +:10F47000781EFE660D3F97FE442A2774FE4B036BF1 +:10F4800097E2B8220559062D5B449C87451293DB11 +:10F4900068392D8158AC5308296B170FDE01E3AF93 +:10F4A000B28BBD14C68E72F1E0C3B0AEE64C91973C +:10F4B00061703FC255EB7FB9C76B2274DC897B4C0E +:10F4C000B433B68FE7E97F9302D1E5C97DD1E592E8 +:10F4D000607479EAEBD1E57D1283F70CCB981DC7F8 +:10F4E00029BC070E9809CC77F5A904BF99C27BBF48 +:10F4F000911058BFF2AC19F1A172B5CD03F871EAC1 +:10F5000064C22E332DBFF25E027E7FD3D356F6BD8A +:10F5100021F04B282BBF4C24F0FDEA5181B2643A14 +:10F52000EF97BEE66FF016B16519A1FF5F16EEEA20 +:10F5300082FAA9813291BE7F7E022183502FF88BFF +:10F54000619DCFFF95C77EC34F9AFDBDB4DF532F9A +:10F550003EF14B80D7A927C7247374CE971A7AA798 +:10F5600076417D9B5DEAA5EF679C7A26DB17B12F7C +:10F57000ABF798A3D6D92C71B8CE56C1D3FE28ECE0 +:10F58000CF2123E253CB727F5D90B66FE1326505E8 +:10F59000FA31513C2D82B29CE6A4F83AC3C1F0B6D0 +:10F5A000C54ACB31F65D7BD66EE1896FEA70F9E82A +:10F5B000A627703E0527DE45BCDE6F540C0900C748 +:10F5C0004D9CBC9BCE7FBFD5514C92E099E907BCC6 +:10F5D000B95332E0FCE8BA1E6E04BC7893977B49BD +:10F5E000FCF10AD2FFB4BD6AEA37D4D371DDC58419 +:10F5F0009CFD73C20D1E3A8FFC2DD1FB5EE88F2E51 +:10F600006F00F8507CAB2511EFDD309FACF5E94879 +:10F610002704E75370E2FDEBDC74BEA3CDA419E030 +:10F62000A21FB75B627CE4A9A7683F05D80D7F9E47 +:10F6300067FD49A9745F54BA7A89637444FF6E19EF +:10F6400043E96D35C7F88BF67EB56E1E5AFFD3D5EC +:10F65000FE5D26F9BE10EEBF5984FD3F79E7DC0759 +:10F660008E1B47CEE7C33B3D9EAA88F7376E597382 +:10F670003083B6ABDF9B32858F806FFD93AFA65E84 +:10F680004FDF9FDE23C8C002EB173FFEF319F0DD0A +:10F69000937C00E60BF51EBADED381DF38E0BB1B9E +:10F6A000B73BA7F0D270FB155BE678AA0A86E17932 +:10F6B000B174FA4239E373AB0346BF05E822F0FBAD +:10F6C000EA3180A75B3839978E5326F878A03B7BC8 +:10F6D000A9C7A84C2764D657FF7C7034AD6F3A3069 +:10F6E000ADAC8BD67719BC57FD08E86E272FEFA677 +:10F6F000CD9E7BFBE6545FC4FEFC56C5FFAE85F590 +:10F70000D88F4271239732F58182DA4A28CF282296 +:10F710009C99F263C709E2F1DB603CF2AE2199905B +:10F7200013FD77150B06E447D7039D9C220E19E8BD +:10F730006EBFBDF9DF71BC678D38DEAC601207FCAF +:10F7400077FF639CDC45001ED1F477E244BB63364F +:10F75000A3EB1BBC28070CC445FB5BF9E824E403BE +:10F76000DA7BFDFEADF247F7A3C78B132ADE026AF0 +:10F7700046E297FEBB51F31413D0637D2B9517110E +:10F7800074537FBCDB446C23C72164087F09E02FDE +:10F79000C54B22E17AADC837E81F67A1787B12FE1E +:10F7A00095CDCA848E7F13874B23AB2704F280CF7D +:10F7B000718258D19931CC5F49B91FF9FC69FACFF0 +:10F7C0002E19F842E008D03BC8D2DD205FC4E09992 +:10F7D0006D50AF8CF7003F1A0D484A9FE45789C817 +:10F7E0007F4F4BA1C7B1FD33936485BE3E0BF462DE +:10F7F000C3768EE408FED41678D511A2E5537B4774 +:10F8000055F00EC0DB7F75C03A4F064655981CF187 +:10F81000F9869E6FD29921DE7C00FFA47897E4F6EA +:10F8200024B869997452A10BF26C547349738C7D9E +:10F83000D3DAB94CCD2512F08F9FDA64E0E3C99694 +:10F84000BA47405EC39F87BEFFF4F551BDB0FFBF0E +:10F8500050E5EA528E8DA3F533DACDE8FDF557F287 +:10F860009242749C4F899404F2E2E96CEF38377D40 +:10F870009F5E31E8E1293CD2AF2072076D7A8C9708 +:10F880006F13E97E2C23545EC2B3D46702BE423AA2 +:10F890005370BE84C8D500CF15F328FC4B5819E42B +:10F8A000DB2AAF49EEA272B84E60F0AEDBC3F93B83 +:10F8B000E85C96DD130D8F1B7BCCC37801FFB73D51 +:10F8C000A29E8EB34AF0AF07B935968A9C51E514D3 +:10F8D0001F1E8BFE7E3509E2BCEA9F396F8E05E75D +:10F8E000BFA8707E3ADB7309AC8F5B60C1F9B43C92 +:10F8F000CBA17C759902A84F84D7507E4CE74BDE94 +:10F9000066FB709DAA2F35AD5DEA59469F675BEB9C +:10F910003CCB6815921AF0919E24C49FD5558183E3 +:10F92000C85788F8EBEBD3A13FE211A1BCD9CEF4C4 +:10F930003DF2D8ABC057FE42C400E0E18C951CB646 +:10F940009FF136DF4B319C5C37B47F5E8463BD44EE +:10F950004480E37B462FAE5B5945C4DD94AFD45B56 +:10F96000BC9AFE25FE90AEE746D28CEB5EE8CEC296 +:10F97000FD5C49BAB1DC404226C2C3FE962501BEF9 +:10F980007E4664DC5FAA27116BF248BC02F87B223A +:10F99000E0B6727B74993C1651CE0238D37204FCE7 +:10F9A0001BF79D377B62C0FDC12179E42FAC991410 +:10F9B00089C76D38DF23EABE3C78CD8D19C047EE8C +:10F9C000038578B4DA4139F05FFAAF19580E5A68F6 +:10F9D000FF095387CA585FD6CECA2DEE17BD5B28E4 +:10F9E000726C36FA3244BA3975BCF7A081C27561BF +:10F9F0008EEF76D8EF3A832753407EE2C9F3D2796F +:10FA00009056B6BF0F4D692E6C8EA17F68F3DFCC88 +:10FA1000058206E0232F32FDC25E1A3646F2FFFB56 +:10FA2000DD8C4F260D8470FFC3CF7104F4DEADDC96 +:10FA3000FD19B08F5B3324AE83AEA9745FDB6CE439 +:10FA4000379417E5D27D6DD8F7C1C131B45C3A77F0 +:10FA500010B689AEDBBBE63740CFD31298DE9CD818 +:10FA6000BCCB40FB4BBBA1604A07C5CFCD6E09E7BD +:10FA70009330B5FB15E827BC46127B693FE9ED8A58 +:10FA8000FBE62218BFB90DF1B786E0FB946BD7B542 +:10FA9000C177778F26C93C7C47DA38F8EE410741B9 +:10FAA0007D31C5C0DF5003E529AC9CBC8EF3F42248 +:10FAB00052DF8FE3A499C95C2E99BDF71721297AEB +:10FAC000F662BD1FD79B56D95C02FDA565B3A7CBD7 +:10FAD000E433E4D0F10E1D36FADBE97C0FA9FB7E9E +:10FAE000CBAE8AB448FE79E8B4453050FDEC50BA4C +:10FAF000A697066DA097DE52529906449595333726 +:10FB000009F6C795195D7FD6E8499A0A7470982757 +:10FB1000B00FFF69F324811E79A989CD5FBF7FFFF4 +:10FB2000ACEE4BD3171CF147C8A5A645E750DF6FD5 +:10FB3000FA42887A7FFA4E0B01513524BF560E5493 +:10FB4000C3770D64703DE053432091F823F0FBD25E +:10FB500084D8E36A78DDF4054F9498E39AA2DF7FB6 +:10FB6000318A28A3627D971AFD9EAE23AADCF7F99D +:10FB7000D03AE03D290F39BCD4DE9B07F29096CFF6 +:10FB8000FA0D8A7132A8E34C8E9D11430ED0B3A9B1 +:10FB9000DC6B867D39238550AE9D25642ED45F6A4B +:10FBA00030DC5003FB2B841D0BECC3E368F5D03E27 +:10FBB000721FCF2C329120EE4F18E701F053F2095B +:10FBC000D9D6FF8949027DA0FF15849F862F9170A9 +:10FBD0005422F8466AC760D040E9E3FFB8BFEA2E76 +:10FBE0002AA4A837A0D1F75FBB3D33693D6F88A237 +:10FBF000F7C4D221FA4776F3A08157F9C5F9EEAAE6 +:10FC0000999165F67D44FB9A2ACA1F4A8B587B213D +:10FC10008B3BDC9E03AFBB999E238433017E4365FF +:10FC20008BAE6CA3E54911655157EFD2D5A7EBCA4E +:10FC300063D9F7A7EDC14CB04393B28C3502E57B95 +:10FC4000A733824B385ABEA7C35C5345CB0DA54C96 +:10FC5000EE36F673328A0D157E8D32D31F6D72C863 +:10FC600054570470183C08FCA1BE8F13394A0FB6D4 +:10FC7000C0DE2096A19D14D12EC061BBFAC007D86A +:10FC80002E6EFF0506A4F3AE82A3ECBBC04728DFAF +:10FC90003774AEF102837AC3C8F88F407C9E3194EA +:10FCA000BE1BFB6A88CF36CC27CF64785E453E7991 +:10FCB0008013813E87F014FAB50DD385F6FD9F269B +:10FCC000F5FF1ED487C45B3E6913E8F7FFABE1A3E1 +:10FCD00069A0DFFD4995079B397F218CBB8DF80A10 +:10FCE000419EFDB421F71503FDEE8831B40378E899 +:10FCF0008FB3C6D508947F1FB187C671545ED76491 +:10FD000015B0724A6807C0F3C9AC42561E171A678D +:10FD1000A0E56B7AAF46781FC90DED80F2CF7A6708 +:10FD2000B1FA49A1713C6D9FAD7810FEBBC5D87486 +:10FD30003D278BF1136D7EFF36D5E3C982F5D433B1 +:10FD400039B2E4A6F71603FF5D622022A1FC76F724 +:10FD5000E963CFEEA6F0D8DD9A487A193A7A05AA77 +:10FD6000D7A631D4A7FCBE1BF973D84DF9353A811B +:10FD70000643E03F4A9C6691BADCC3FBA28D9F36E6 +:10FD8000A1792FF49FB6A408E581C5ED790AC6D7FD +:10FD90009E6F15B2E7535922E3DFBCC183DFDF61F9 +:10FDA000F7C3F7F759D9BA28FDE03EDBD47DB95E39 +:10FDB0005DD7F5594C1F9CE69EF354560AE823AADA +:10FDC0005EBD31903281CEAB872301B04FDE33125E +:10FDD000C58AFA4802EA353D3077A8BF3FC3AFD0A5 +:10FDE00071AEE78817F88BC64F7A9C9E8CE408FBAF +:10FDF000A4A784966DC3F6684F8D2723C105CF5401 +:10FE000003E8EA1A7FEA71B3769A7C4AEB60E3A4CE +:10FE1000DD57D80BEB491408FA4B962FCAEB6D430C +:10FE200039BF00E74D3C9E0C8EF6777C559601E07D +:10FE3000A8EDD767533DB7017CAEE3997DADED9B4F +:10FE400006DFA7B2989FA08EA77A02C5BBE21C1F4F +:10FE5000C293EA0DC528A055BDE12940DA08381340 +:10FE600021340DDEFF7F08AFED8807DF115E0DAD99 +:10FE7000948F182E808FA870DCCC058D698C8FA094 +:10FE8000FD0BEF411EAD73FB025911F4B0E48E0679 +:10FE9000D417B57925DEFEC2DC6B09D0E149A4BBDD +:10FEA00025FF9088F6AA5E9FD3EC244DEFFC451CFD +:10FEB000BFE3CBEAFA64CDBFAACE23B128F4ECBDF0 +:10FEC000145EC9C42E021F3D620A4D9269FB2306CF +:10FED000DFA32FC0BC47F322E52123FABB2D9B47AC +:10FEE000BCB16A7842C28E09AE613CD944F1C40209 +:10FEF000ED6B4C6807F738FD5B6F043CB966ACAC42 +:10FF0000482887919E95D644ACBFD4709480BF3862 +:10FF10003C5D14415FA47885F53D8BF3FC0AB3FB8F +:10FF2000152BFA4113FCBD8077251400D0DFE209C0 +:10FF3000580F7637FA2B165BD87823F18AD9C7F990 +:10FF400084D5BB55BC5D9585789BDA4198BF41F05F +:10FF500014D744E80B85D90C6E89A5A1E7DE013BD7 +:10FF6000E51EAB9C4B9829077E0CD29D86FD517CEB +:10FF70003995C5FC0B8897CB7E6EDFC5F89E5C0675 +:10FF800070DE60EF266BD10F65C4F96FB706519F25 +:10FF900036582427F87B97F064731EF4D761140158 +:10FFA0004FF4F0B667C7F34B866E8DF44B2E312BB2 +:10FFB000E64CA8BFD38AFABDE69F5C92C4E84AF338 +:10FFC0004F027DC6920B9A7FF20615AF46D4777D1D +:10FFD000995B4BFBFB0F15CFE4812F7297DAD8BAF0 +:10FFE000C1CF510BFFA2E3D6AEB37E00FECC5AC503 +:10FFF00018343B808FCCF18422EC2DB285ADC3F751 +:020000023000CC +:10000000A6D10F706A15C8E6C7617F14B6FE96E5E3 +:10001000FE5591EBDA6662EB52FEC11EB5AE6D0E77 +:1000200016AFF8EEEBFAF3B4E8759D98A6AE8B58D0 +:1000300052693B55CEDDD06AFF802BA64F58177D05 +:100040009275745D05C3EB9A93CDF8E912958F8D87 +:1000500090BB71F7F17FC87ABB1FF2C45AAF7E9D87 +:100060004F677BAAB353906E8262E9305EFBB6D2D3 +:100070007595C2BEA6F8DB705F197E12E290818F83 +:10008000B52CA7EB82675B1AFAA59698A53EF0CF30 +:10009000928793D47512E4032D5BC7215D52BC6532 +:1000A00074FB108BEBB45899BFA0658D282B22AC44 +:1000B000FFD768CF86297F45BDA4359AAF7F3B1C0B +:1000C000AC99B5459170B0642E2D8AB1EF8A19F1C3 +:1000D00039DEBEFF071FBE95CB8EEF2F23EBA2FDAF +:1000E0000DE0371C2AF323CB7AFF05B51FCCD1DFF7 +:1000F0002BF1F8C14F23F1E88851C5A3B556943FC1 +:100100001A1E1DB1B3F5EAF188502D1AE8585BB7F5 +:100110001E8E4B008E31E209149F72018E4754FBF4 +:100120008CE2532EC051A3831B5A193FD0C3ED89D3 +:10013000F87CEDBBAD4387C7DF751D5A7DBC756884 +:10014000FAED166ECD56C0CF2D1944EC403D383433 +:1001500009EC2497C95F08F3DA66A2F44BFBAD55AE +:10016000C707CD01F0FBB343CCBF79541D573FAF58 +:10017000E75539A4F77F3539C23B410F694A60F230 +:10018000F0CC013BD20DC9092D01FDFBEC7E330102 +:10019000FEDAC885F2E0BB339C67297ED7962881BA +:1001A0005CD4FC86C79E677E438550FB17FC753E7A +:1001B000E6F76C52FE753DECC3F96CA119ECCFA6C5 +:1001C000BE683F195D9F03D67BC64006E1FB46DE55 +:1001D000BF0A4CD6CD26A60F6C369000ECDFB05D82 +:1001E0007E340FED840C91805FA7D1F041DECD11FC +:1001F000767CA35ADF98C9FC4C1057467F390CE532 +:100200001E0997C67B4E7D0D71B1C67D7A7A89A68F +:10021000A7FAE132779E83FE22EADDC3F484F63842 +:10022000E06115F1E772E01F63E5C4B9837E884F92 +:1002300037A9FED394815035E80BF6D200013EDA9F +:100240007482D92133FA77BD0A7E33E7DCC171A00D +:100250009234A97104BDFD33BDFF7E1EFC439AFD9F +:1002600012E18F2A5C10E5576CC776E0DF82F1421D +:10027000F00AFCD302D37337AB7A2ED587916F2E59 +:10028000EFCE477D18F455D03B34FF18E821A08FFE +:100290002ECCA91072E83ABFCCA9380FFC1BC6437C +:1002A000BB1F9C2ED3BF817FA9F0D1BE033FD9379E +:1002B000FBF3993E3543E7C7BFF98D14C4F3FD71D5 +:1002C000F4D45139437EFC34F0E3DFCC496980E754 +:1002D0001FF23EF4D7AF200AFA8157817F1CF960E4 +:1002E00010FDCB373513B90BE3E1BEF5506E58491D +:1002F000C42EF02F57F9B01EFCCB574E67F12629BC +:10030000027F219E1359267B68398A4F0FA2BFBAFC +:1003100091F6B04D063F42F4F74DC45F29005EF4FC +:100320009D3747F5D3C3E074838A2F5BADCC4F3D37 +:1003300063DD2E9E44F81992A678DC77013DBC61FE +:10034000443FE9FF56F75783C7D3D915D61C0A8F08 +:1003500004F0FBC077779951CE1E379095802FF728 +:1003600039C90D0BC09F7527F1E418012FC4CC4883 +:100370007F97F6ECDA6F5D0978362B87F111EDFD8A +:10038000996C2396D1EF8CFA6922C6D1295B2A0693 +:100390003C2CCBD2F462520CFEEE0F54FED4B8D0FB +:1003A000E683FE4206C6CFE6E530BB7B5E8E09FBE8 +:1003B000D3CA43FE2215CFE838D85FC2541215C7FE +:1003C000BB2A87C901CD5F4BD4F8CAE655094C8FCB +:1003D0001EC27703F2B3C422AFC987FCA402F95945 +:1003E000F8CF3609E032F754FD2A58C7A78B120818 +:1003F000E41D2C53E3448D394EEC578B0BC5D0BF15 +:10040000AE0FBA86E58D869F9A9CD96F67EBBED8F2 +:10041000F8BEFE39B7AB10F9B7368F193ABD241EB6 +:100420005DDC364C1751F12D0AD744E0B3FB0DCCFF +:10043000EEDA4F110BFD560135FE48ED649003FBDB +:10044000F7E5A39EBD54F5A7523989F65598CA0B16 +:10045000B6DFBEADCBE1BB402EC6653F30FA9F7C18 +:100460001CE4ED01664768FBB17FFF183FD0EF8CBD +:10047000535F6502FCF79F786A0CC4BBF7ABF1C50C +:100480007A53300FED7D13D353EB1DC13C80DF4B0E +:100490002ADED427D0327D9F95E2EB063EA4E50705 +:1004A000403B27AE477280BFE1986A471EA576257C +:1004B000CC8B52CB20C43DE97E674039BC298DE905 +:1004C0007B745E8017C70E4CC2F56D36323C565EAB +:1004D000E4D03F71D418FEB0957E7F34632A69134F +:1004E00041DE7DF1F841E87F274FCC22E45F7C7E3E +:1004F000AE8F7E7F96DAB9E037AB3378AB33805F6F +:100500003CCFEC75FD3E80FC8B8CC79D21E14CF40B +:10051000EBADCC0A00FE9CE92FC4BC22E21289425A +:10052000CB4D2F32FB461F273E6E8CC67F7DBFB062 +:100530002EF0AF35C1BF41BE47B68FD1DFB795CFE3 +:100540001843796B293CAA245F302785B163D8CF43 +:10055000A69733901F1FBBF773DC4FD2CDE29FC726 +:100560008D9E25303F6755D0541B818FEFA8FCA38B +:10057000CECCE435E5BFA6487EA3D59755909871BB +:10058000FA3FA87CC13EC8E4DEC87A86E7B7924746 +:1005900079E017EFE448D8DF7835DFE056F2D92B61 +:1005A00066D04F022598CF307E5D10F9009D2FE276 +:1005B000E7F1AD49C81FC93D0C5F6F7CD88CFCE3E7 +:1005C000462A3F98BDCDF2ABC83D2C8FE2C3BBDCC1 +:1005D00088CF65EDC132A4072791412F79A1F3039C +:1005E00085A7F54BF77025903FB6B4D38D76CA4DED +:1005F000FBDCB8BF3354BE5E67F660BE187984C5B5 +:10060000D396FD62158ED390489C3CEA7F7E13C83A +:10061000E5957B3802743523C0F87FBD107C05F466 +:10062000487DFE03F147C789411E91083D13E40F41 +:10063000D1D905D1FBAE5C94FCD5CB1B3E37B6FCC3 +:10064000A5F69E90CBF695C989BD1CE31BAAFC6D4F +:1006500000F90BBA9A2AF734B9B942959B1FF24CAC +:100660006EDF68BE1F9F19B96E1CE72688EB621CFF +:10067000336C02FD241E5E64E432BCD2F062746E00 +:10068000345ED49F081E34A39D293F0FF1EAFA750A +:100690002468A776DA8D4233CA87D1221131AFAEF2 +:1006A000D287F34A6BA1FA39DDE71B21063BE5E26D +:1006B000F582117A804EFE6BF3D6F044AFFFCD5831 +:1006C000E7E7219E74328FE07BED29924009CCB799 +:1006D000C6C2F4EF1A8B2DC883BD59653C1D696FE6 +:1006E000FC58F094E5A25C1DEBFC7022B20802FD00 +:1006F0004E737B664D9836AC57269686D7DF4BFBFC +:1007000033926203F0496D7C8B7BF692220ABF26FE +:100710006110ED15924EC4DD74BC2B8B249C4722D6 +:10072000DD875D14AE464141F8192DA2B3CD09FB1A +:100730003F887199700A413F9DB65F3BEC44817CD4 +:10074000C52B8B187D5F5924E293B6C738AEB180B4 +:10075000B6A7FD57ECB7225D9E7BD1EE07F94CE5BD +:10076000CE7827AD4FFD13B55368F9CC7E3BEA290F +:10077000675479E1D2FCB5643DEEF722156F14524F +:100780003106EC11C25D3186CE9D687A7283335E8C +:100790001C53AD770F2E64F86B467DE19C33741BC0 +:1007A00094E97C30B7C69BCBD6DFB4AFB2E40EE0A1 +:1007B000DF5E9BCCA0EE2B01FDC7CCDFB2D0428127 +:1007C0005DCDAF0BAF05BC1F6713CDB449D5F8F7AE +:1007D000FFB09896FFBCCF48CC803FBBAF4A0A42DF +:1007E00033C193EE9D34723EABFCC6A3A1083A5EC2 +:1007F000BD27BADC10882E3711E1682882FFB7BE0A +:10080000BFEAADD722F06D6DAEDD05784024229FA2 +:10081000A7F474FCCE3E720C6421FF9324E08FCBCE +:1008200028F9C7D22B3EBF73E55BAFD1EFACA68AE8 +:10083000B65C940B9209E8AB96EA0DB1ECD0C9B95D +:100840004C4F339B9B4FECA2F031BF6496DB68ABFF +:1008500079B9BE2EC0C74643F820ECAB79FCE962FB +:10086000F067578CFF0AF302CEFD2391014EE7ACEF +:10087000B3119FCE6DB54A60A7F664DA981FF6658E +:10088000CECF31BB65FEB454C8FBC0B5503E165E3A +:10089000BF15F8F474B3D82EE2722D06DC6F6ABD72 +:1008A000D1678F49590F7ED51E6A40B6C960E70DE2 +:1008B0003A80180655FED0C43F63B2D07FBA3B3DA4 +:1008C000856DF4BBD5DE0402F978C2D78217F06CCF +:1008D00003741561F73CAEF2BF46F1EDF5307ED3FF +:1008E00057B7CC4D310CFBF9CD46E6E737F6CD0EC8 +:1008F0008EA14D57B456A27D47F92DE38B07185FA3 +:100900005CB17636BEE716CCC5F57E48D70B70795C +:1009100075AB19D7FBE1381BDADB1FEEE0B0BC4248 +:1009200034613E1FD54F46CD76C17BA3682623E1B7 +:10093000D1B465C3FAADB4FE77193CE128FE7FB4AB +:10094000FDB7188FF888B0F1957D3CEA3D1F89E12D +:10095000B220C0536A7644DA932B76F05EE0972B90 +:1009600076DCFABBE900B705D795023C66396F49DA +:10097000956CC3F59ABE2724973F0E7439EBEBCAEA +:10098000C159A077EDA07443E72D18880FEC8FD7DD +:1009900076FC10F5ED1535094E589FB47D7735C8B6 +:1009A000B78F6A461B705DCF72440478385B53E1A1 +:1009B000FD0A4EF0C6C2AB65B92C9E307BBC4D061D +:1009C0007FC38ADFF3882F94CE16421CA161871162 +:1009D000F5F9D716BCF787C5AE613AE3166C993FB7 +:1009E00003BE7FC288DF0FE953DB3F7E1FFC02F0AE +:1009F00047253BC821849F9EEECCE3D7E5C1BCF4DC +:100A0000F4B7A2BD398FC5F72F8E0EC9764687275A +:100A1000299D9C37FC4D74F829E3EB174687646CDD +:100A20007294FC1EC9F714FC4E8B8F5A64E2D96D88 +:100A3000C37C180F47F9F5983C01E13E268FD96D2C +:100A4000C29737EF7993C26947AE4FC8A3EFC71378 +:100A50004F09C867292C56802BD6A6EA8D643BCB5C +:100A6000F306FB02F67F730A79BC2BC23F93A6F60E +:100A700047F9821DFA39F3C7AF0EC27E35669E2E46 +:100A800006BDBAE98BFFC4BC0A5B3FCBC7B1C961E5 +:100A9000CC3732BABC888F1ADF6F92991CD2AFABB9 +:100AA0003D8FD9AD4DAE30F6F3423EA34F2D1EB96A +:100AB000AD3501E342DB5C7E2BF3B3507D8FF63F17 +:100AC000AF94473E6329ED2020C748398FF19C59E8 +:100AD0005FBD4520FEF5BB999532E895B6D25785A6 +:100AE00051B0CE72A35AFFAB8D59B4FEAD9973D0FD +:100AF0003EBA399D9740AF9A579AADA0FCF4B0FC2E +:100B0000DB595F25211DCE5F351FF54A6DBE5E6244 +:100B1000916C144F1650628DCC539E3FD32AD9222C +:100B2000F0EBD36E6E2ED3ABA5A4AB2731BF50A094 +:100B300088C9F34838DC9C6EC2F1BFCC997D09C0EE +:100B400077D6656C1F4E3E6BF6B7D3714F5A63DB99 +:100B500091D5790C6FB284CB912FDDF2AC19E3F310 +:100B6000A7B8D8DFDFB491C7BCA2551B39E2A7E311 +:100B70009D7CF2854CE0EB7FDEFD42666DC47CE23D +:100B8000B5AFCB63FAC0487B3BB82CD2DE9E676220 +:100B9000710132C51CE5DF9DE750F3EC2F30DEF12B +:100BA000A3B87EFE37C6C27CDF1CF2F3BF3E3632EE +:100BB000DE3114B792999F5F1FAFCA29FF1775BE28 +:100BC0002CAFB95550E72B9B59DC62398B8BB71C86 +:100BD00018857837CF14FE39C6B35EE64535AEE1E9 +:100BE000B160FB74561F675DC4E3C97195A1BF096D +:100BF000E7C3F57141BBE33BAC8FB038867E7DB572 +:100C0000FD7CCCB8DC97F92C0F20B1288C76D5D19F +:100C1000D71F85C8FB10BE5BFBDD86C87CF8217D35 +:100C200056C5EFAB00BFE9FAAC1B59391E5EC7E3EE +:100C300057A9798C8E35FC3EBA313B09F0ED2E4B2D +:100C400063E820859F874F22D6D1B4ACC6FF95F7C5 +:100C5000593E2A1F61E7001DEC78DF8E764E87B182 +:100C6000F91138BFA3B40964377DEF4A68F4B7D1EE +:100C7000B264B463DED4ED09F377815D17A20A2E66 +:100C800047CB9F271CD9057A02B12411231D47A900 +:100C900050DB9B2C6207D52F1E4A74207F695D466E +:100CA000507EA79120C75180ECCF63F9AA29AB9F52 +:100CB000E7308F98523CE87D72766C7DF4572A5D60 +:100CC000BC0B0934F42957C6FE6E7F9EE617137CD1 +:100CD000A1083B6F03274BC877E85FDB74D0EF07B1 +:100CE00017235FA67AFC5B541E8CE17F8DFED963CF +:100CF00077FA1E8975DE6148EE56C6B6D35F55E7B2 +:100D000057D0CDF98D0EA45FC3AE28FA55E378F61F +:100D100054994A1888DFB2385D0ED1F2DEB780DF11 +:100D20007E74399BA3C31322A05FA4775F4E7CA37C +:100D3000809E66A4817C6B591EED4F4BAFDD988180 +:100D40007EBDDADBE683FCDE62B46DE492E019ED91 +:100D50008FDBA2F3C77D1B5F488F4B37D3D3C1BF57 +:100D6000B16538FE87F8D3B154F4F31CAE8244C6A3 +:100D7000B5533BA4833ED083665BE45E7924FD904B +:100D800072391DFD9CF9EABEA9F4DCA4A226D7CFD6 +:100D9000A15D3A921FAAF06C188BF0B476DF8E76C4 +:100DA000536209F36327AEAAF501FF49A4FC07ECDF +:100DB0003893A999C3FD9FC1ECB6168E955B668BDF +:100DC000A242BF37399A6763FD152CCFBAC5EAF343 +:100DD00045C6D32E35DC3C3B32BF5624B43DF0E152 +:100DE000456CBC7996752CBFD74775A48C61385675 +:100DF000A870CC294F60F9E6B75AD0BFB5DDDA8DBF +:100E0000F33548CCCEAEEDB222BF1BC31760DC6415 +:100E1000C0C8F043B15B905EE58177313F6CCC2573 +:100E2000E912EF8EC09F5B58BD861744975760321A +:100E30004907C17F472722435E4A0B271DACC07577 +:100E40008961458675AB7CB93881C9116A6EA63354 +:100E5000B8B2B8986EBF28DE30BFFA241BF31B115E +:100E60009F847A976EBD23F1E6C502E0B70343780D +:100E7000D357108BDFDEE7940EF646E20B91D68354 +:100E80005FF56E030977C5C21F39DACED7E7C9E926 +:100E9000EDFDC6D64AAF6A7F2816DC4F13DA1F8DE8 +:100EA0006B677B99FD51D006FEA7A6755452D136CB +:100EB00095FD9C05FA6B5AE440FBBBA96F2FC6CF8A +:100EC0001BE71219A651ABFA87B5751E35B2381E4D +:100ED00095590188DFF738433BE17C5DCF2A2D8FA0 +:100EE00087E5B5287D9C9AC7A3E57D858F80FFB3F4 +:100EF0008793D00F3A744E8FEE3FCBDFB9B83C30BA +:100F00007B91D70D96F8F4DCDE7F4B98763179B47F +:100F10001FF5409E6CDC3C5A25780DD45B602FD4C5 +:100F20007A4003AA2F6B658F5582FC9DE17A81DAA6 +:100F30009D963E4E1DAFFA9A393978BE46EDAFFF09 +:100F4000013847779F95448D17393F41D73F989691 +:100F50003649FB7EFB02E8EFC1296A59F9FA17907E +:100F6000377C9F31BA3F4419B53D14B4F1D29E7E0F +:100F7000ACE79E99C37A3BD5E3FF317FDAB0FEBE82 +:100F8000E1BD79DD93E95889E267789E49D3C39B37 +:100F90005C2CAF568FE71B553ED6600955836ABD62 +:100FA00061D11A2FF43B94F7D6BFD40376B096F7ED +:100FB000D6B4CE8BE79AA8DE7F4F3EE4D1FEF1F4A3 +:100FC00087AF10B0334FA23FA0E90B81F99DA9FD77 +:100FD000C0517CB1F4DF8FF843F618FDE0DAE97117 +:100FE0002A04F0B1E700370DF08B90E6CC6B28ECCB +:100FF0008FE77B7A601D67E2C4C79FCD67767B531E +:1010000041C5D63C80F5631C017DBCABE053B42BDD +:101010001A5F9C332DF21CDEAABE07D979AE3DC6FD +:1010200098EB7E369FC7F535BEF81CC64F4EFA3991 +:10103000A4B995827F13D89B2B571AC0B222A5FE64 +:10104000A598274B169908CCFF01D50E69DA739540 +:1010500002E7029BE87F9404C836EF8DA86F6F5BB0 +:1010600064B1411CBBA9A0760DF23B31C103A69C23 +:101070007E9E43F96F6B13308FA6ABCF3817ECA46D +:10108000324A17FF6403BE7AD8BD0BF8E7A8297C63 +:1010900087087986B1F5EF670A991CEFE4BCCA8F1F +:1010A0004B312E4222F399C7F731FBEBB57C5354F9 +:1010B0005CF0B57C6617CE54062B01D75E164289CC +:1010C000600F3711CF27E0F7225E9B847121124019 +:1010D0007FA0EB4E09ED268B2B74F764A89F29A007 +:1010E000DDA4F911CEBC9886FA584981EF30E0456D +:1010F000191F7AE0C700B7BB0535BEC4F84AE655EC +:10110000B629605F195D4C9FB1527D06CE7B5CB6FF +:10111000E9F8BF56026F7579518F2054C8C1B9F1F3 +:101120004A0BC7E22B3ABD99887215B4AF56FDD26F +:10113000B974B73EB4206A769E1F05FE0C9702F084 +:101140007E9D2E6014AD9F433C9DB02F5FAAFBB7E0 +:10115000D9C4F4F5CD060BEAEB9A3E9CE81A443B61 +:10116000B121C0E1380D05BFC6F302ABD5BCF4A177 +:10117000FC702184F9F2A7F313D5F86727C34F3227 +:1011800088FE30F20CDB07AA79621EBD06772DAF10 +:101190005CEBCFA4C64B1B547F2E0518D67F9EAFA9 +:1011A000C557DBA3E3ACEAB84490CA22FD8E9B6B23 +:1011B0000819C479490E986F57AA9714D0EF8F5227 +:1011C0003C063C3BBA31D10FE7B63673831E887BB1 +:1011D00028252C9EA1C7A794024E3D1F14AEC6BC65 +:1011E000AB17E39C0FEA8B3E1F44F9C39ADFD07123 +:1011F0004A4BDF9301BFEF73AAED2F27984FAE3F05 +:101200001F34BA40C271FEDBCE07C99CA7973E735C +:101210000A9CECFC8F763E486670D7F231F4E78288 +:10122000CE64040596C71FDAB91BE59E19EDBB977E +:101230003E3ED809FEE2B3252619CE43A45EF77AD6 +:1012400027E6C5704233C415F5727D97BBB218E02E +:10125000FFE035CFCB98F7AB93EBF1EC798C794687 +:10126000F87B3CEA7E7C5FF6BCB5FB7307E0CD29DA +:101270002EFC73C847550EF031F3516F28E0E2E4BD +:101280006D791645EA999D5ADE9633212A8FB1333E +:101290004EDE563CFD5D889BAF7539EA619D43F992 +:1012A0005A73353D2C3A1F554CF846BB571B7F6E81 +:1012B000C81D155FBFE582D7A9DA2371D617CFFE07 +:1012C000BAD87C013D1C3AE3C8C37505F1F2053C70 +:1012D00022C4D73B21BE4E9F024714F483ED1DCAA2 +:1012E0001708A2DFF7B97CF45F99E3E60BB03C3254 +:1012F000E140BE04DF6D307A3D6097287B8D2A3F48 +:10130000F73F09FE8FCE0319E82F2305A162E07392 +:1013100082B33A1DF4A34E153FEB2F3C5F6073413F +:101320008C7C815DFE293FCF6276F06022D5AF765E +:1013300011266F947EE69FA4F346FF5CF8DE71A849 +:1013400077720B2CB88E632F9B7BCDA84FCB18FFE9 +:10135000AF4DE74590133D35651F821C3A46155049 +:10136000A0E3BA9BD6A11D1A6F7FEA3646C763B5C4 +:10137000F717BA4FCFA9FB7414EC7414980AFA7DCE +:10138000576EE45EC1BC5B5D3CF805E021C8EFA38D +:10139000E3FBE7ACB331AE7ADB2F6A309EAA9DA3A4 +:1013A000D5CECF12356E226D1490DF4B7B38BFE463 +:1013B000666462401B5D34E07D1E544C6D03D1A613 +:1013C00050AAB984BEE60C1CE89B52272DA7D17504 +:1013D0006D129474FADDAE7713D18FBAC125A9E7E7 +:1013E00021981DA5DCC3A11E47FB453B58E9A47805 +:1013F00043FB79A780F9F7CF16303D83A2881FE71A +:10140000A33E3BD57C086DBC366208C2D3C0B1E7B1 +:101410000651981B4B4FD3FAEB34365B206E121EED +:1014200067C0B8E439936711C6F592F308D87D9D7B +:10143000F6E68D73593DF2D073D6B017EB7F2030AE +:10144000859F48C930DF37D5FDD0EFEBF2EEE8B22B +:101450003E6EAFBF17A08EF8F233B2479E937F5314 +:10146000956BE7BADCEABEC818F7EE344AFFE60629 +:1014700039B7494079DA3696C1CD308E3DB39C55A7 +:101480008B509E3AA99E89F365F3CFFA818B03FABC +:10149000EB7432FCFAAEF3D6CFF7F3823CA63F8270 +:1014A000F24FC7EBDCC4F919BCD8BC2FD4EF9C5267 +:1014B000F8FDFA9D8F71F2E341C0339BFF61F0DFCD +:1014C000D5B59945E067A73895FE37F1C8CFB6ADD9 +:1014D0004CC6F2D18DB9E8CF19A2DB13EBD7C07D92 +:1014E00007179A7F955FC8F0E2773A7F5A6D397790 +:1014F00018FAD1C31D104AD0E40F6D5A79555135F1 +:10150000F0C7460391D2401FD8A8CBF3D0D1739532 +:10151000E49B5608FAA269F020E353A13C01F56868 +:10152000AB0C707BD0706CEF6F015FF65A316FB00F +:10153000715DF871F03BA64ABE998514CEA7D7BE5F +:1015400057CD49D81DDA5B670FE4E3FD19B59DBAA5 +:101550007B09EE89CE2F211B9359FE464FF47B3831 +:101560003F1FD56E44DE09D33F379B7C856027CC77 +:10157000BA8CE5EB7DBCCA40002F3EB632FC51EE82 +:10158000B5AB7246CE8BD44F1717EAF4987BAD8873 +:101590001F75EA7925FD7E34007ED07DAB57F1E3DF +:1015A000E3E72EC903FC38BDF7923CC08FCDC66E71 +:1015B0000FDE2390E3FB29C0F1F81CEF4103E34B5E +:1015C000791783B7F5FA79FD9DF4ABBB0BE3C54DF5 +:1015D000A49F44C64D068CCCDFA558A3CFFB0C5C62 +:1015E000A47F34BE9FAB3027DACF55901353BFB2E0 +:1015F00058BF51BFBAF875103CEFA5C55306ECE1D2 +:101600009F3F1E01AF162BCB2B69291445A504D68D +:10161000579B8DE7C7FE68917BB9EF759D51FEBC66 +:1016200097BFCA5EDF0DF3F030FFE3CB8274F05258 +:101630003AEECB84F91FF5EBFE7D3ECB83D1EC6710 +:10164000CD9ED38FBF57DDEF8142CF4B601FCFFAC6 +:10165000EA3CFA034EC03D39745C8BFF9FD02E23C9 +:10166000FD9C88E7CF2416CF6C7C71F9A3E03F5D29 +:10167000E557E390FB38B4BB573DF609D69FE9AB7D +:10168000C37A5B3F17847866D35803CA6D2D8F41A8 +:10169000F3E334F5CF2680A79A1F87CEE30598475A +:1016A000A22B6C42BE0576226DD728B0386DA38B75 +:1016B000C80AB0DABE68FF8796E7B4CD6B427ADF1E +:1016C000D6CFF9C1AE4E35F9DC63119E63C50F1359 +:1016D00087F9C65B859ECF805F6979684F677B0E0F +:1016E00003BDBA4C2413F3DDD5FDF00DC577D879D1 +:1016F00089BFBCCDCE4B84E2F0EBF70BB5F3120BF8 +:10170000517FFE0BF126C5CE23F7B33CF2A1BC35C9 +:10171000962F5E3F8FDAC84E56867B5F1AE0DE1743 +:1017200099C9CFA04E7E4696214F2C18C137EB8524 +:1017300041CC47D7EE7981BCB1C8EF1BE1BC45363F +:10174000CB1F8BEA47E5A769FCCD18C789113FFD80 +:1017500049A4FD7148B3B34AB4F3316113F8695A2F +:10176000DA5C6188071CB2ABE776D5BCD8166BF89B +:1017700018F8315A9E4CC3732043FAFDB366D50F57 +:10178000CEF0BE9EFD9334AD3C8AF67A139CCFE733 +:1017900086E9695E5CBBEC8D1C88AB1C1AB2CB5E23 +:1017A000CF8173341A9FAD9719BFA8EFE3D879AAF8 +:1017B00040F4799A3113BE5FBEAB7D17AFFDF409DB +:1017C000F1F8EDB7C199F1DB43F1CE21A97C528349 +:1017D000A39E1F5D2CFC86E492063F4AD7C86F7516 +:1017E000F0D3FBC334BF16E914D1EF45759200E482 +:1017F000656A7EAD0B9587F3BFE77DB95079D83028 +:10180000219E1DFEDDF6279E9CB8D87D19210F6113 +:101810007F8AE3CBC39CF27F51E7ADCF2750E7AD82 +:10182000CB2738640CCF67F75150F8B847E613C49C +:10183000C5BF6FC927F81BD6A9CB27F8E675EAF311 +:10184000091E39F09003426E70EE0CFC0E03BB8D46 +:101850001847AFE66D1E96E7C5B3BC50E2C1FB3139 +:101860009B2C56F42FE8F3E028A75ADF0CFA6539D1 +:10187000D5FBE15CCE8E0E94CB0D193CFA1C21EF0A +:101880004F9462E4590A3549416964BE17E4B1E3F3 +:10189000F9FE8BCCF7DA336128EFD2FD37E65D062F +:1018A000265C40BE57712EA3BB576D9F8D8ABCBF6F +:1018B000B2A2881AEA45F1F3ED5F56E93551CDD36E +:1018C000B5080A89F447C56B777002B3775E358532 +:1018D000DF0D805E45BB81F865BA895AD3A5C3E7A1 +:1018E000D68FE77B5F87F9537D04F7F7CC8BEFA0AA +:1018F000DFFE910C2242FEFB234605F75949218861 +:10190000D75A5E8236CE5AD58F7DA1FCE7C8DF5903 +:101910002EFCD7FF74BE33227F89D1E3DFC06F90E6 +:10192000FE86F88991C575B47B2BBE55CE7DDF7CD4 +:10193000469777116F5D5FE613C487F113BD1913E6 +:10194000918E3CE867BC58F997584AF52180C73E0C +:10195000B304A46651EFA720F764687E5176DFDFF9 +:101960007DE350EFFCD8CAE6ABDDBBA1AD67CAC4CE +:10197000EFD78E2DCEF1964EA4F33E3EDB83E77774 +:1019800037D899DE167E92E5AFEBEF91A074C3EEE7 +:10199000D550EFE1D59F87AFD6CFEFEF24BF974F5C +:1019A000FC1F4E471729BF2F7E1DD1F6EC213BCBE4 +:1019B0000F1CB667FFDBD67551F25ACB172EAB184A +:1019C00054FDFD1C017FBF364ED3203B6FB351DD6C +:1019D0004FEDFDEF54FFDEA1899E4D4087A5A5C1C7 +:1019E0009D70EEA49138F01EF1C6C0ED7BDE74B19F +:1019F00073B4582E607147E2B5E139EB1DB9BE07EB +:101A000018FD86D6037D8E779132881B74152C20A5 +:101A10007536CC277808E860FCBAD0CE374B319FBA +:101A2000AA19E855CB272E3BFFD9FAB9A5385FF4A0 +:101A3000FFBACCD1F76FF44D64F6A0F67C4EA50347 +:101A4000BAED19309FD32BD9B9D2269747043FB2AC +:101A500016BF4E940631FEDFB88F194565602B42E4 +:101A6000FD1D6391BE1AF7CD2E81B82609584BF0A3 +:101A7000FEDD3FB17BAF4FAF1D8DFEC69202DF2F63 +:101A8000615DF652FFE560478FA7E340FCF3F4DEAB +:101A9000CB4B7C31F8661A9FAC407C388D27810790 +:101AA000C461BE45EDE7C5E82F5E1F463FD6CE892F +:101AB000128B27BB985C6FEAAF21CB6DC3659B2B64 +:101AC000FA1CD540E19C9D308F9D13595C5FCBE79C +:101AD0007453350CFC867A7C72ABF99C356ABE3245 +:101AE000512CC379CA59DF9ECFA9CD4F2B6BF99CDE +:101AF000895F30FB3D4B3461FE877D23E3AB641D82 +:101B0000C1B8C1CCF060651285534E4F7026C02914 +:101B100009C08EF7B186EE9E4CDFBB460933C11F6C +:101B2000B2B375CA00E8BFC2A6C11FC09648DD6245 +:101B300005B81877E47ADF033C21427301F0A58AE7 +:101B4000DF1BD979A34D89A857F664D6E379A3336F +:101B5000EF9963DE27A03D15D29E0E7187AC8DFFF5 +:101B60008EF17DFB3E2EE6B9B44B8B6CEA79A4F680 +:101B7000748863D8370E2AE5B4FFAC7B39A29AD1BA +:101B8000195C3AF8870503C8D7BA3E764F5D5DB752 +:101B9000B3C282F286F96BC84C17CA1161D395069D +:101BA000E013421BD562E93AA714B1F8746E8F684E +:101BB0000039F5CF5FF331E348E755BC6EB0844C94 +:101BC00000AE0673F860BA7B385F473BAFA2F97B83 +:101BD00086E4CFBEA5E8EFB9F8FCECF0F598FFF786 +:101BE000752AC657E639983D4205917A4F4B74FBEA +:101BF00011F7B4A87A8B6617EBE9409FEF9C533E30 +:101C00001AE982F2D1C036318AEFC5CC7B6E1598C5 +:101C1000DE4DD7616A8179CC4E97C13F77A179E6D5 +:101C20007A7B7A48CF51F5126DDE7F6B5EB6565FD8 +:101C30000FF9D831FC1F9A5ED3A99D67FE9ADDA3E8 +:101C4000355EB5278E76FD5731BBAF50CBFFF0E345 +:101C5000533052FE89F813BA4C013CD8E73434169D +:101C6000617CA911FBD9C4EEDB1FBF31BBBDBC1425 +:101C70009E22E128BC8FEE5F3D1EE3B7942E726377 +:101C8000D0C5918946D6FFA644C463E17E82D98C33 +:101C9000823315F1587890E1EBBB13197E69F9672F +:101CA0005A1CF0D0449F17CE1B0EDDAFD19AC0EE68 +:101CB000D750F3B8EDADEF3D0BF756EC54E3C0034E +:101CC0002F4F5C80F1B94D0207F6E139E7D2F1E020 +:101CD000BFBBBE88E1B95D1824A22D925E07F01C3F +:101CE00060D601767E4950F34D854DAE5D809F16DE +:101CF000B70FCF3BFEA033C8633E9378FC81B91287 +:101D0000D81D6113E49F9D6C13C2ED4ED49FA2FCBD +:101D1000647ABF171102985FD354F4F7B543EE2DE0 +:101D20008AEB9FFA4EE728C8B7F8A7BE2B5EC7F329 +:101D30004F5DFC3AF4E727987D425E66794A31D6DA +:101D400015E5BFFCDED7A5F92DF5796723E898F9ED +:101D50003F347B488B3F108F1295173E601483A051 +:101D6000F7409EED7332E8D54F5823F3C29E57F1EA +:101D70007EE8FE3EE2B7C2B9FB8FE1DC30CA3B79B8 +:101D800023C4416FE7EDDD60DF7540BE3EE897009C +:101D90005F2EE2DCC2FB76CC7B6815D8B906A2B018 +:101DA00073112DCB9B9F80F62D6D6922C05FA968B2 +:101DB000FE159E7B30106F077D7EAEFEFE84361FC3 +:101DC0002D8F3F9EFC1C91C7FF2DE71032E29C43F4 +:101DD000785BC5FB826504CF21908D9E5D30AF9E00 +:101DE000368140BC37792E2B8F172CF87B2856C8AC +:101DF000871E85E746316F394CE109F9D756C88708 +:101E00001E05E744D87D85DC82B9887FC9143EA0D1 +:101E1000177418D9FD84CA3536C4A7CAB92C7E995F +:101E2000EC3521FF394B64CC9F57E01E3317E05946 +:101E30003BE267D89E8AF1D7E41CA6475ABD2683A9 +:101E4000C58DF9CE88AF614ECB77667CAF67A9842C +:101E500079E843F7152E27B83F9B72AB33E0770044 +:101E6000465F65E2205EA3C9990A153F7A76A9ED1F +:101E70001B587BB8CF10E6475A58FBA1FB0C7FCA12 +:101E8000EA5B8510DE07447518F53E3D56DFB23833 +:101E900015E98757CFAB92EBD47C7B8EDD1FD5B293 +:101EA0007834AB77303E486E4A50E5B9DAFED664F6 +:101EB000BF1A2F6079F3AB0CEA3D00DD24329EABF4 +:101EC000D159F2B79CBBF8C570FE3CD273C7E5226E +:101ED000E6076AF73156D84CEC3C96259AAE9E2917 +:101EE0004A66785F2E5B60DC656E4FFAA498FCD181 +:101EF000BF3492AF8CD6F8CA4D269D5D96C6E0EAF7 +:101F000008EF64E7B6CC176597C58F2B3E99111D76 +:101F100057DC93111957D4F6B762A509F94A8F53C4 +:101F20007A0DF28FB651D0C2FD76FA756F1BBAA743 +:101F3000DA6F05BD546F0F1E8A9367B46812F3E71A +:101F4000C971FC108B26C5932F71E2B425E6FFA65C +:101F50007833E3BF0371CEE90DC14BD39B2CFAB8A4 +:101F60008772517E9F01CBCF900F7A3A0462BD8C6D +:101F70009675E7CA281F44BEA8B49BC50E17F0D1BA +:101F80009F215F6CA596AB39822F5273F412E0C784 +:101F9000037716E0EFCBBC76A78CCFB3562EC04F9D +:101FA00086677809684C4B8A0F2C847B9BCFDAC3F9 +:101FB0009970CFF3BAC96F5C8BE594F01128DF51AB +:101FC0004C16613937BC13EE7DBEBFB8FD5AB8D789 +:101FD000F92CD0D868426E7DF6B66B9522FC3D8414 +:101FE000F583A0DF97EAF2F175F7D0C2B951584FE7 +:101FF0009ACD8471DF34F5BC2EA952FD4390E905DA +:1020000074975182797A3622ED1B84FAB14CEED264 +:10201000FA36B8E7B423D7CDE2D084F1013256CDF9 +:10202000E3202105FC511D6E27B61FD2EFF699D58E +:102030003C3036FEE1E7D8FD3CDA396442C47160D9 +:1020400037DA241255D6EE752682380EEE61ED5041 +:10205000F1402BF7A7F91E9A1461571E9E737B114E +:10206000ACF3E3E7EFC8017DEA87EAEF32E9F1EA92 +:10207000C6C90CBFDB13FFBA04F8F8BBBC4306FFAC +:10208000414B9A6F17F4B7DCD536CD49F1A74A9C7E +:102090008DBFFF324359CC015F715ECDE6E7ACF2F4 +:1020A00072CB8B867F1726C527A09F9EF87A78D0A3 +:1020B000B7538E7B45804FBD259C29D07EFEE4F230 +:1020C0003D03FD9E5BFAC16D989737FAF011B81F7A +:1020D000F2B0B1BBD201F8E456EF03A63B06E763CA +:1020E0000E8E19DFABFEBE0D3B2793CBA971D860D6 +:1020F00015C8852B08C35B2843FD95EA7D67D5226B +:10210000BB3FB3BAD48DBF57369F8405C087EA77EB +:10211000BD0E02F471B5AF34D6FD13DA93A41BA53E +:1021200048FAB95C8A28D3FFAE2C882EFF488E2E41 +:10213000FFB8FCEBFCA8B2E07963520AC837267FEF +:1021400094E94CFE8824D00EF2F1A966710AC6D536 +:102150005D9C02E5892F8CC6BC2492CEF2192638EC +:10216000B2FC0C0ED9DB615D612AE77B5DF0BB47F9 +:10217000EC1EABD4774DBBE09E042249DB810E9F61 +:10218000371660DE66AAADF69FDA509FB1935CE425 +:1021900053D276C46BBB4582DF6F78C5CEF2113A5D +:1021A000EE3760BC8973580C1EFA1DDF2B30F96FB7 +:1021B0005F5909F57C19DD102AAB079CEC77943A3E +:1021C000A611637B09EC9BFC2EEA45760BE6ED57E6 +:1021D000390A7E02F5BCC384F73ABC622FF3A9E347 +:1021E00011E8FF31FB4A6C0F3CDA48E977C0CAFCC2 +:1021F000EB3CB58FDBD9F8F87B69FCCD441DDF42A1 +:102200004C50AE2598873FE014D97C6F35603C0474 +:10221000EA2FC3F959B05EBB8770F8DCEB6C01EFB5 +:1022200063E7881A1F6BC3F2432A1FEC308AAF00A2 +:102230009E2A7F2604F6A3CAF105D2016F70C878E2 +:102240006F8E87E4B85209F359D0EFF9543108F989 +:10225000ECFCCD0EB49B41F3817AF02110A46BC14C +:1022600043CA54D70C8EE7390A783C9E235ED88F38 +:102270006B8BB3901F3D6A38BC05F32B6C5EB34C7F +:10228000C7315D47707FE5C4D8E75DF38A199D8E3D +:10229000DCBFB274C8E3E01CE5123C3BECE5129CE9 +:1022A000DF1970CAE9DE88728C7DF103DE0CEF8BDA +:1022B00025682886FD9025D02FBEBD3F5A6F83F537 +:1022C00048382F7EB42C811D9AE3A0FD50BE2F8F7D +:1022D0008ABD8E6BD57504D4FBF1F4F595C586EFF8 +:1022E0007B9D3AFCFB8EEB4C8D5EE7F738CF10F709 +:1022F0003DCC93CFA4F3B30DCF8FFE13EFEBBAC257 +:102300006640FCBA42BB37A920FADC85FE9C0595E5 +:10231000C05B81CFFC50CD1FAD48FC47F4E35F4E5E +:10232000F57C906B07137F9603F99BD5496D9D8CC7 +:10233000389A4F2F077E6CE190EF5C4982EBE1FD0C +:10234000D9D9BE479CD9C8F75717C3B931DE979F73 +:102350004CCB1F1BBB73D6B8912FD6C37B1B092355 +:10236000DD5D01BF8F067437CFDF09653A4633DE86 +:102370009F45E910E856A3C391F3A77449BF1FD343 +:10238000ECC0734D3B48100FA6A5936E8EF95B9A77 +:10239000516E1169DCF03A29D1565B9A711DBF6DFF +:1023A00053503EFCD0F98000E587655F1BCC6BD1B4 +:1023B000E44FF0DE7B92BE341FEC4E3ADFF6FF971F +:1023C000F31D79DEFC9BCF51FCBDECD1C78B599C32 +:1023D00043B3475D09549FA0F39438874CA8FE3857 +:1023E000649F1A2D9897307C3E375C87E780B9242C +:1023F0002FC833ED7CAE9EEFCEBA8CF1DD8FD7388F +:10240000E476BCAF700FDAA54D57DBB4F3BBA87F01 +:1024100035AD34A8E77739942B8DC482F7070DFDCD +:102420007E1CFDE352877F9F633F9CE32DFDA673D7 +:10243000BC129E1356D6B138FD907DD72032FB5585 +:10244000FB9D875BB3B4FBF8999EB2865C907D1BC5 +:10245000E37C2FEA8D24C9A0DAAF4C5FE8992E897E +:102460000AC1F82AD3C3179BB07E73821F7F37A59A +:102470008EEF4624F963B153BD17C16FC5DF5732E4 +:10248000C979C027B438EBC21CDFFB80BFCB8B3CC3 +:10249000991C5D4A9D89C54F291D6C1FA4ADE6920C +:1024A000E6C7E0F7B32E27CD6F1BB2910E8E221D2B +:1024B0004CFC84FDAED6301D1C2B86FC06C2FC01F4 +:1024C00057A871A2973E7EBC13F6FD2C47D8F9AEF3 +:1024D00002FDF92EEFA9629C5F48FD5D9D68BE1369 +:1024E000318FE346360F17CFE33C3E8B358F1174A7 +:1024F00048FC383EDDDF663C47AEC323FD7CB8FEBA +:10250000DBF1BCFFF6EB89C84F07393E6805788ED2 +:10251000058CC88675FA0C93A7A13CF7C1FD669A95 +:102520005D3D62DEBC0DF775E1E2A13C9DF91965E8 +:10253000102762E33E94D8F820F83D9AAE37227F08 +:10254000AFE99F847ADA41C52C421224A962F93599 +:1025500032FD1FCC6B11F1CC71D27EAE126BF0BE8E +:10256000B4ABE7E9F37294BB9A69FB6BD43C9F85EB +:10257000571B8F46EA9B678DF718010E4A9DAD9950 +:102580009F01FD09C3EDDD23E132E2BEA64EC69FE9 +:1025900008D573A0FF8EF200F2A7787C2A6FF25064 +:1025A000BE4FFEDF98EF533C19F1E29BF37D64359B +:1025B000DFE7356318EFE1FC4DCA8AED6BE83AF3CB +:1025C0001F2EC2DF139D93BAEAB1FB69F9896D131F +:1025D000B0FC9BD4EB6F390CF53BF3B05C65F86451 +:1025E00009D04341D9E22BE077585FB3B27ED213D2 +:1025F0007C3D35F4BBF4E2AC2970B14B95298CDFFE +:102600005D39B9612AF863AA1258F950C93B53B031 +:102610009CA596A7BC3401CAAF719F2C89C517270A +:102620001670C1422A6FAB92D9F7F3A63C391AEC67 +:10263000F8AA0A569E28CFDE940DF5864F97C4D28D +:1026400097AE9FCCF8EAACAFCE768E72415898FD2B +:102650003EE80B9E0FF07736BC54DEC2397C6F39F2 +:102660008BC3793D2502FCAE538587952B6D6D1983 +:10267000C007E7FB4CA51077156DEE4EF8BDC2A460 +:10268000F2D9D360DF2BA9BA0D714E4A5F37009E95 +:102690002FBAE4934C07EAA51A7D8946787EC37D5C +:1026A0008BCBD8BE45D303ED6F15F67769B4FC1C10 +:1026B00041AF3A3CBCC23296E11D958BE6F291F4F3 +:1026C000AAE7DF647D808BA4D71D80973CD2ED5AAA +:1026D00018DF641894E0FD784E9E207E03FD9E3541 +:1026E000BEEFC638107DC15F1A836FD03F41D3F370 +:1026F000D92C443115F397595E4FFF3BD81E8E837A +:10270000F01938FE26189FAC67F3D901F790F060F6 +:10271000EFF91E053ED198CE7EF711E2FA40A7E907 +:102720001ABFEA8B5E6F47B97C93931F395F83852D +:10273000C1F16A551FFB7DAB37A5844E7621693602 +:10274000C27A1F4A742810CF6DAA65F74906D27C59 +:102750000FC33EF106E540889697138F89F137CF76 +:102760007698A7B62F8DEABE345ADEC77C36F8833A +:102770007B4E46C0A34FCF47A3D73FBC2F8319F052 +:10278000CC807B54B2619DF2463EC67A88D0BC298B +:10279000D24FFFD0B7FAE909F3B7C866F55E94F0F7 +:1027A00092487F5C87BDF991483B999A65789FD1A3 +:1027B000A1B61C120BEF343DE910A7FAB5A8DE0B49 +:1027C000FAC0E7097F45FD84528CD798097EADF9A0 +:1027D000A8C770268B08F1EBF4DA74C4D72D542FF8 +:1027E000013FBB5211C8467FF94E9EC0FD03C37026 +:1027F000A033710FE3E7F1C9CC0E4C1B8287827CBA +:10280000D464E062EA57C7271BD47B50D9F9D2467B +:102810008B99E57FAABF4BA1E5B1345A8AD637E33D +:10282000FA2C8C7E74FB3422AF459F27674943FD09 +:10283000429C4264908723F360F4768282EBF8D165 +:10284000507C8130FD67AD1DF59F1FA9F1056EC15C +:1028500017B83FC914BFCC2E8823481CD82BC9A554 +:1028600087053269F87724E1F797C09FF57C96EFEA +:1028700093C911F1F837A73D817921470C2C0EAA95 +:1028800087CF5743F00961BE6AA3C6AFF4EB8F331D +:10289000FFFE34EF5F61BC8FB9C132A8D4E253545C +:1028A000ECBBA1BFFF0B8F9234BF00800000000083 +:1028B0001F8B080000000000000BE57D097C5445DB +:1028C000B677DDBEBD25E9249D859010960E3B129E +:1028D000B03B21618726408651C000A2A008371076 +:1028E000D6AC82CEA0E3980E0144079D38A2328A6E +:1028F000DA202028308D02A246A70544FC74346EED +:10290000E3FA98C40551B61844719E6FFCCEFFD40B +:10291000BDA46F13467CCBEF37EFFBF0375339B7CD +:10292000EADEAA3AE7D4D9EA5475923B6B5492474F +:1029300008F1C38F3FFE982FC495F4A7E82644639F +:1029400037CDEECD13E26A5134D6AA08913C4EB38E +:10295000692E21C6AAF47F038468D9A6041DF47CDD +:102960008C3FC6225285A83C640B06095EFC8A2A6D +:10297000002F7E480D0A825B84776D23DA071CEEF8 +:102980000095F7C7F5FFFD302A3F7DC8E675A0DF4B +:1029900080FFADDED46F09FA25B8D75A8BF0380521 +:1029A000FFFB91FED727182B3CBD5BE1BE5B924D30 +:1029B00070BF500753FB4BF77635D5FBC29798EAAB +:1029C000730FE598E0BC8621A6F603DF2F30C183A4 +:1029D0001B2F33B51F7A74B2091EDE7C8DA9FDC88A +:1029E000B3B34DF5A509850797D27C0FA6AB421965 +:1029F00024C428516A6A5FAA96D98585FEA8B37D4A +:102A0000D248EF55D17F3F7625589D61059ECFEC8A +:102A100055444A9610F3D7CA7AE3BD05F577AFCC93 +:102A2000A47261D0FCBC54585B617A6FE9C70BDFBC +:102A30003810D15FAFD4624B1295A3BCF1A947FA0D +:102A400062C262E08F2AD3D51B069DDE51BD0E49BE +:102A50000AA6F3E2ED4AF00EA2634FD1E37ED08DD9 +:102A6000E82C821ED055D6B7AC538301EAE7BBEA07 +:102A7000056F1CB0117C28776D23D17F7E8DC3AD8F +:102A800052BD23DD4CCF188F999E71BDCDF48CF7CC +:102A90009AE99938C84CCF24BF999E29E3CCF46CAD +:102AA0005764A667FB69667A6668667A662E30D3D5 +:102AB000B35395999E5D969AE999155864AA8FE645 +:102AC000DF6EAB169BEAEF8F7BE188467848EDA07E +:102AD000BA1D6E217AD4DD6CFA9E50C7DB5710BE4A +:102AE0004A3355A1BA5BF92040FF311F882A5E5F47 +:102AF000F3880F1E203A9C11AB0F667ACEE7878AC7 +:102B0000BD77DBB13E7F2E3F2C8BE203E2BB447CE2 +:102B1000E747FC1B797E69D0F90AAB7F95B79D101A +:102B20000F7AB5DFA19CD6EBEBCE56921BA2A8B8CC +:102B30005751BC102ED13C13FC542112BC77A07409 +:102B40007E9C057EC13F4706FD9F5F74B712DE1471 +:102B50001D6F62AFED78A3312E9AB752FF5E16E675 +:102B6000BD8E985145FB892145D0F83A8A860CC81C +:102B7000A70C51A5A04C17DE552AC6EDE99484791F +:102B8000E0CF1F3399309630BDFF41898DF97759D9 +:102B90005CFF6DE0CBF76B255F9E4693C1425C23E3 +:102BA00042367CE783D8073BA1BF0242B832189572 +:102BB00075D761FC33307EAF10D789461B3E3E4B44 +:102BC000083BCA62E1E1728EF0DBF1FE5C115E89C6 +:102BD000C97C94AA6D073E2A54AD4B1AF0D1B1A11D +:102BE00073513F2A5F4BC1A02F8857505CD07B6F39 +:102BF000E34F6AF789B76837BE33DAE9B9E15EC2F5 +:102C0000CF3E8B581022BA88F1293C6E612DEA37ED +:102C1000B95F5BDF5946424D88E7144D03BE031987 +:102C20004EEF2620393DF4A442F3BB24D9937347D9 +:102C3000526BFB035E0BB727D60B28D4FEF15DB1B8 +:102C40008CAFBEEDD727635E3FB7DF06AFFF558C75 +:102C5000DB68FF53F3B5DBBD8B6EA47E9B1551B5CE +:102C60008106F18E4E974C07F10F8D37534DF0D6FC +:102C7000826E71330FB6233C2C69AF7D00BD34EDFD +:102C8000EA5FAE04ACEC4BF12CA6F19D2A6ECCC7EA +:102C90007809FFFF86FA3227E19FA676A293D62B0A +:102CA000114C5124F14F7FF42B6A73FC723C077472 +:102CB000FCD7B7D78EE03BFB2C0D9DBDA0A3B52163 +:102CC0009FE9E896F33A619778B9101E0AE23ACD87 +:102CD00000FE4B1C0EAF4AF82C50E4773F4B9C355E +:102CE000B392C63DD7529416564DE3FE06782B7329 +:102CF0001577C9C0B86DFAB89DED74BC7BB2B1AEA2 +:102D00002E34EE5A7C9FF014F8AD12DC9485E7E186 +:102D1000AD809F166EF71D3E5A7316A9979B6B9454 +:102D2000E006AA7F43C7F343366A8775E914C935BD +:102D300034BE2B86AF588F76BFD39C3CEE4DC27B02 +:102D4000C99A2CD043B0BCCFBC4D09D6123C5B789D +:102D500099EF4B4451E75DB00F7C5ABC8FC6F1B779 +:102D6000B87FE465597819E7BD43DFD9B3ACBDF747 +:102D70000E40C32E8EFF7B93E440FF932748BD3364 +:102D800057C7DB95A288D7E955A28A4B5AF0272A64 +:102D9000A8DD34FA0BEB93E07E18DF74C0BED67565 +:102DA0003D4334703953B89F6FA46FBD55D3FEC6F1 +:102DB0009BA8CD644B7367BB8A754AEB368BF1DFFA +:102DC0001DE3FF76EC9B8715E0FD169263A0F79A52 +:102DD0007617C5C79314894F5AB7D9BE3C5EB7035F +:102DE0007C9688F533A69DE43FABBBC73F5B3F2491 +:102DF000181332D284F8851485E2FED3092295E6B1 +:102E0000D9D0550D3AB2A0A76FB1EEA27936903D58 +:102E1000E1C0BCFDC51D4E51FD38D2B77748F91A47 +:102E20001F2078A25F1577301F342E5F48CF5F1BBD +:102E300044F5D4FEE51A113F80E0977D366F2DF101 +:102E4000E1D8B3DA81442A2792DC0F53EBCBD2EFDF +:102E50001E03FB605C47D223117AE2B2EE6698163D +:102E60004247D0E9721DDFE3B3CD7A6722F48ED1F9 +:102E7000BE0DBD43F255057E27FB74FD7389B80472 +:102E8000FA677FF55EF129E917430F8DA61986B21F +:102E90002FAC8762EC05D7806E447F3BD6C76C2B86 +:102EA000B507BEDD5A874911EB656FBEC274F2905B +:102EB000E2B1D0FCDF38A406811FAB3F3C14F85BC5 +:102EC000FCBCC27CFA079F3617DF3B696B9C07BED0 +:102ED0006918969B28A8FF4FAA6920BD68FD563B3C +:102EE000859FD6C2916A37C347ABD3B9FCAADAC370 +:102EF000E5F1EADE5C7FB2DACBF0B3BEA20AF0C342 +:102F0000EC555F5BB56CF45FC5F6D1921AAB00BDB2 +:102F100096C42F96B0CDE98610BEADD3414B1CC1EF +:102F2000B705152FF4E2C25DC1957134AED27ABFF8 +:102F3000DD05F9D72979B40BEDEF5598EBE71DAA1C +:102F40003A88E99E7CE793AB2688D6F9969F55840C +:102F5000464BAE5B9EFFB798CF17D583785C5F5624 +:102F6000FB795CFEFAA68329F4BD63D5E3187EC71E +:102F700057548B767EF135DB1113B6355961678C6A +:102F8000F52B7ED079845F048384AFB536A957D6FC +:102F9000925E811C18D56FF2433708C87DED4ECC88 +:102FA000736AF29CB1B057270E2A66FBF5EA1F043C +:102FB000DBAF06FFFFD43AF288869399D4DF89808D +:102FC000C44FCBAEB7196EB1127E68C62FEC2A2D56 +:102FD00015641FB49C7D4B3EA7766CA7EE96ED164C +:102FE000DB64BBC5BB7F97CCCF15A55944E8BB6359 +:102FF000444741788873663EF419E1E7D8F65FA745 +:103000006B11FC752C39F4ED879093FF66F16E60BF +:103010003ED53E7D167274B99BE5CC495BE8C8038A +:1030200090B39D48AF727D55DC64E2B30ABBD09883 +:10303000EF84D617F0B15831ABC825FBF3F492CF2B +:10304000C18F3D77DCDFF5379ED6FEB684E67EF88D +:1030500000E8B0E3A3844B68BC7D541152317F215A +:10306000C711D818CBFD943D797BB29FE0AD8A683B +:1030700051594E04595EFCCE26A6A1DFDE8AD5BE8C +:103080003499FCAA3B9FCEC4BC7BA9A24AA5753942 +:10309000E7AE67329FA1F71E2359A4D2F89FB379F8 +:1030A0004FEEC5771FA2F153BF8FDD599E037958AC +:1030B000F2878597000F7F81D0223A3CF1F44EB61B +:1030C000178827BDA349AEF55BF3E2B20C6A7FE92E +:1030D000BA264B072A7D1B955A94A5DB76BE55432D +:1030E000FDE5BA2D55B05FDFF279785C39A1F51BAB +:1030F00014E8811F1EED807599BDE6EB820EE2C2D9 +:1031000076C6139DDF6F29F6B05CE0F777D74F796D +:10311000FB5A013B862C188CB7D8EE65BD46D3B65A +:10312000013FBBBAADC7FB7B2C01D65781D9D2CEAC +:10313000395114F823E65F4EED030497FB1A9A6E9B +:10314000A2FAF2A4AE2240F33F1A5C321DF5031539 +:10315000E1067E2A76DD5BD881E013C38457A1FEA9 +:1031600017EC3E5DC8FAB013D9EAF8DEAEDAB46BFC +:10317000A00FB30BF254AA2F5243DC9FA894FD5525 +:10318000D6EF740226D427ABC46749F5A3F6677A55 +:103190005AE96369BC2BCB4ADF6B47FA14E35D9BAA +:1031A00015C8A872B5EADF645FD169AC1BE1BEA7A0 +:1031B00018DFF99CC605FBEC62F5A5DD52B590C79A +:1031C000932EDC81C1ADDFED64092FC43C6875B876 +:1031D00003F49D4DEE86E9DC8EE0DF73BF9A9A938F +:1031E00007FB8AB09E2AF57B2DFA754FE90C7A5DB4 +:1031F0006CFFF7C7FD83EDB44A4B82D731A0D5CE23 +:10320000999652FB7C23D12BD85E4BCC6907FB5897 +:10321000DAC9C2EAF540EE57B7F7BB73D84E233D83 +:103220006C61FD9B9A1361379FB3DB9C17A77F43AB +:10323000EDFD1DF0BD8B6DEFD1E312E7E4F0991CBD +:10324000931CAE8DB70B1F3DAF5DE3E03886386051 +:10325000293B48FECA707CC2D2FABD25F139EDA1E6 +:103260001F6A8568135F2FD0FAD708B761D21B1A7F +:10327000C98111679B558DE544C3FEC40190B7C257 +:103280001FEF41DCC022B408FD18FD1DA2D760CCA1 +:103290006F9488135A849EF58B243BD6AD70255FBE +:1032A000E4BCC38F9AF5CFBE4723E73DACE5FD38BC +:1032B0009860848FF6282F34AFE7F579FD19F3A2D3 +:1032C00072677ED1E5A0DFF06FDC56CC6FB8755227 +:1032D000675F571EF7243C1FF18DC53CEE1F624D02 +:1032E000F0C58EFF46851C3BF0F1D7F620D65F3D3A +:1032F0006C059A47FDC2EC20D6FB1EBB0838E1F7EF +:103300004CB6B31D5C1F1F88875CAD57DC21C49F82 +:103310009EB3354C977E91706FF2817F5F7F10FC7A +:103320007F4D8B5D413CAB83431C817D25D444B1F3 +:103330002935E2FBEDDC1CE750A13772091EAC3FDA +:103340009F6EE7E7B536C17A32303D96C7B526A9FC +:10335000EAD57E54BFA626D34B2317EF8BE0AAAE47 +:10336000A8BF4565793ED4B261D37DF07B26A5B375 +:103370009E599314CEAC44FB85977803C40F7BFE13 +:10338000A1B2FE58E3F36724BB200749CE139DD7B3 +:103390004CF267C4A6A24CB360BE1D48CEF3F32C1A +:1033A0006A47E58736D9EE039D6E84E90CC8DB07D2 +:1033B0004A7A08963F390577F03AA10A27F1F35483 +:1033C0004902317DEEBDE226B4D3D4A09A05BCDC1F +:1033D00075674F82AF99ADBA11A79BBA20A649E98C +:1033E0004FA5A6861D09F4C29563FD91FEFADA1C6D +:1033F000FF1DA07379A84FB7CF22F878FADC1EBF63 +:10340000827CF884FC68F8DD77A4697FE0FEF7FA37 +:10341000B8DD5E326E7E849E707AFAB3BD5D62F86E +:1034200099E139C0EF0BCD4EB6632FC40F42789DA2 +:1034300097D0F7EFB38810F8B98BAED76B110000B7 +:103440009D4331CC07E3263BFD1CAF725936C08E3D +:103450007E84E805FD16D8ED607A91A064FADDF768 +:103460004227D64BB37439563B2D96DFABDD690B43 +:103470005A406725B87533DE7B3E86F567995DB0A7 +:10348000BF52F66C5FE6833D767FD60AF4FB82433B +:10349000EAED044F22D7FF9F1481FAE7747D5D1691 +:1034A0001BEE994474EADA4E7B0A7823BEABE2E75E +:1034B00076F9FC70B0603DD6A520FB266E04C1C233 +:1034C000BF1EF22A4076D026AFA41FC6A5D576DA55 +:1034D00080F16A340ED059DCACF27C0ED35AC6FCB3 +:1034E0000E5775E2712993C765CCA5FA4F17C771BE +:1034F000DCF570D1C133B0030EA7ABBCEE4942DDA1 +:103500003990EA49E736DC4170E5C24F5E1F484F0B +:103510002B6A3FE8BCD7D38AF719CBCAC70BE28323 +:10352000198B6E9928122EBC5E679439E053B6AEA3 +:103530006F618773276192EB4D39FE06F0C17FE41E +:10354000686FA3ACCC267B9BF8E8A4BDE161C455B1 +:103550008E7AB4BF022FA79EF962339E0B6B734F16 +:10356000E60F676321E23265161957BA2B57FB380D +:1035700087F56C02D3AF32E460FAC5653748B97895 +:10358000CBC5E983AFEA37ED51A89FD2D8FA0A2E0E +:10359000D5607FE8AB634A3841E9C6F8D5B0AE8E56 +:1035A000BBC309A08F6691F65EE996E879D250D345 +:1035B00010771342FAA921FB501AD72212BD0FB877 +:1035C000F1DCDEDA3EAB958EF41DA6A3707D3CF3F4 +:1035D0003768BFB54FCE1D84F7D2A4BD770DCD3A65 +:1035E0001F7FD1B0319FF3C7A3AF93A27002D6C99A +:1035F0003145AE93E342CAAFC096183D5E20C77115 +:10360000F299F63C8E347D1D9D54F4765B1DB21DFF +:10361000F11EEC99D23F49BEBBCFE665BD19207DB6 +:103620000279599A22E15247BA1BF656073560894A +:10363000055F560B5E2F34365E97C77664F2FB86C5 +:103640005C13454240AE95EEC8D820ED3ADD6FC61A +:1036500004A8FDA227647F8021FFBF7A3C53EF5F5F +:10366000AEA768BA46E3A15BAE8C73D5C6E7B7FFD9 +:1036700067F1CDDEE91FAD8308BACF26D775205E8E +:10368000EA11B25BD227F5C3FE84DDF4DD93F1F6D7 +:10369000597E17F629CCCF8DEF5D9AAB70BF5DA236 +:1036A000E8DE416D7E11F6927854B09C881E477E0C +:1036B000AEF4571F7FFC1C9D554977622483BF3CA5 +:1036C0008C3F61037D3EB01B74BC2193E47A29706A +:1036D000D5B5158F7B7C5A26F4C849C084EF3D4987 +:1036E0000467C3DE92FAC3800D7A44F3E9B20FE6B1 +:1036F0006536D2FB7372A57F501B93D05F24A2EC7A +:103700001C841CA821BCA29EF4E0ACA26CF8C3E30C +:10371000EEF9CCD63A9F23D57E3FA9A073F0BCB575 +:103720003E27D6E7FC753EE7EC087AD46EC93DE447 +:1037300021BC1FDF62456452D45A83770D49C5739B +:103740003514105CEF04BE8FBBF6BD8E76F3D62524 +:10375000E5A811F269FEDAB1FE92083AF4DD62A63C +:103760004BBF9019BE74AF192E27DD8EF9FDDCF723 +:103770007C61339C7BC80C3F3DA859FD11FAC9659B +:10378000093A15942DEA8F90EF4135083FA3CB2DD0 +:10379000455326107C74DD1C2FC83CFFDD65F9A065 +:1037A000DF89DDB7ED29A7F78E265BBCF0AF8E89E8 +:1037B000D05F27103DE6D5DF6DB77A305F339FEFDE +:1037C000B1E87CFBB88C032E0C9AEBCF970F357ABF +:1037D000DC49F48EE4AB68FA53BF57F96960654B76 +:1037E000A7DC03FB67C17862781ADFE0D0DD76E101 +:1037F000BA987E028C576B8208A7D3F89A6E8BE733 +:10380000F8CB90A5A3C5A7F4BD72AB3BFF3734CF6F +:10381000D94EC51D70B7C6D59B766654409F6E7253 +:103820005BBCE4E308F7A0AA839903E04F8890DB30 +:103830008BB8FEAD2BE1F72FA84A60FC2C14418E0B +:10384000CBCF5EEE68958FF4BF92D551E3591351FB +:103850004FF358B0CEDC7ED1C61F1D91B0E1970E5C +:10386000A95FAF62BE73F571AB8189AC9787E8F150 +:103870008ACFD094F4CD13DD8A76E4D27C87AC195C +:1038800025EBAD4E5DCFFAD9CF2B77D93D2CCFAC00 +:103890006FAEE4FD1D5A87D00F87E2E7FD0AF2EE16 +:1038A000B453B81D3EB4D7183E9222FD42DEB7A0F5 +:1038B000F6A7D729ACD7CB53245CFEA812440CB88A +:1038C0001C415BC08FC9386D998E0FF0893F623EF5 +:1038D000A057242CEA8CF87898FDDF8A2AE1851D10 +:1038E00020888E7E036FBC1F15B61F859E0D28A1F4 +:1038F000077CB0F7CCDFA9DCFBA323123E175F26C1 +:10390000D2D5F0F7838C47D52EFC90E3EAADB16CAD +:10391000B7930288857EB7E9F6B558156C077DB573 +:1039200006FA8ACA15BA1D1EB85BEAAB3549FE9E77 +:103930006ED4DF9DE1051EAE5174FF16767D12EC4C +:10394000EB7DDC6FB3E2766F48427B11884965FB03 +:103950005AFA09FF5059DF3593FDBE01F6BA2F140C +:10396000C678D6DC9BC5F6FA7386DEBB3346DAF33F +:10397000E7DBDD6C5F897BA4FDF8A1E0BEC555DD0A +:10398000B593B934BF396A116F46952CF367E0BB24 +:103990002593ED16D0432CB8B87D914D56D97F3381 +:1039A000CD17F1FACF94A28396483B58D70FF9056B +:1039B000FECD7A3B2FDA9558DE643C9458841BFE8A +:1039C000FCA6B3AAB012BCA9CE115C46AF9474F5A4 +:1039D000F75C9C8DF7647CEAB04FCAFBB801C21F4C +:1039E000A4D239407ED739C0622AC5181967F92C8C +:1039F00046F2E10C5154C8FB031E29EFA3E7913AAC +:103A000040EABD127B83793C1FEF67BA90CE732FDB +:103A1000037F8F9176C767D72BACCF693E3DDD041E +:103A2000E7FF2186E38B9FE9FAC8C02FF14F1EE222 +:103A30006886DC4AD2F965CDEDC1AD3184EFBB6D4E +:103A4000C437A01BF1CDA6014C77B60BD74C4F6302 +:103A5000BA5FA3D355DC19CF741B6AB1483CDF9918 +:103A6000C178A6F6E2EF786FAC47DAF317E9871171 +:103A7000DDB307E49DEF8F19F416D660DE3FDBBFA0 +:103A8000297F7AFB9E00F1FFA23FDD9B20A8DD97F6 +:103A9000D6BA342FBD5FB66945829FCAA3D640828D +:103AA0009BFAFF32A88E0BB681EF453ABEB17FA0DC +:103AB000A461DF55CAF1AF1EFFF79537D338BF5564 +:103AC0004433E463C5AEEF57DE4CF33BE87736434F +:103AD0009E1EB5361642EE2E2C7655D578B17ECD8B +:103AE00071FC458FDD9BE6617C07322DE9BCFE331E +:103AF000F15EC5469B177E5DC53BAAD783752F9A9D +:103B000057627CD1EF57863EB503FF6E8B68EE3867 +:103B1000B48D7AD1C872BE72D7EFBE5613507EF9FB +:103B200021FC8BCAA8FD8305FAFE4AF43EC2350388 +:103B3000E2538F2040AEEF5F137E388F2140E3EADF +:103B4000C1EC22E3CEB55BEFEFDF04BB61E3AB0971 +:103B50004A76EBFE81B1EFD2129AF3C8B39E0BAF57 +:103B6000CB937ADCB8956E528E79F6D2C0DA0B041C +:103B700018B82CB3851360EF97ADB7B11C29DBFEE5 +:103B8000E8E607C06F1F38BC3D3C804FDB210FCA01 +:103B9000147FB3C2F25D2428F9ADF42ADDFE79E189 +:103BA00083B0AF3354319EE8B5E8A933B2BD5F347A +:103BB000C750FBD29D4D85F00FCA345795B30D7A8F +:103BC0008D0EBD686F74B541AF505321C7A9B67E45 +:103BD000C7F4F8F20545B4CF3AFFFD05EB3FB70B4C +:103BE000E91F34A724497C41DF5586D4627BE2F982 +:103BF000EDE9FB139F1DC0F56EF82B3F45C721C0B3 +:103C000005F37BBC4882DEFED0111C0FFAEE589201 +:103C10002088FFBFB05649BE7F68451AECBC05B688 +:103C2000409A9B4BF97CC1C337323FCE57AAD2DCB6 +:103C3000D9CCEF1996413CDF0CCC73EEBAA93CCF3E +:103C40007942637E5CF0905A14A4F28C558CDBD9D7 +:103C5000C6BAF94C5F370E717D7FAC9333F425E81B +:103C6000F12F74BF3EF096F4A71D627262E47ED21B +:103C70006E5D2E0644F030F44065838DE314EA9BBC +:103C8000670AF19D1BB2AC55C8F7A0F907747C29EF +:103C90003F4AFFC583BC874AFC45FA74F49B63DB4B +:103CA0003766E3FB2DF6EBA8DF6FE0277A4DEF31A7 +:103CB000DEBED8E088552EA5324DDAEFD1F348C9E3 +:103CC00033D6BF784B44F053E5962F989F44BA2AD9 +:103CD00012D3258CFD0BF76C575522E1ED9B773EF7 +:103CE000B523FE1D48B5881E186FC3E70C0B6F3B4C +:103CF0000FDA1BDFAFDCEB10E1C875BBF1F3A87581 +:103D00006DAE17A28AF15929123DD0DF5FD89B0B07 +:103D10009F433FD4EF26EA671ED95F61937DD55C50 +:103D2000F820E4C95EBB9BE30F647F8623F8E6DCE2 +:103D3000FEA8BE2F385F9707D17888960F87A3E437 +:103D400083F1BE58D7F67E54AB5C08307DCB6C2235 +:103D5000003BA3EC0307EB8FB2ED723D0A92A73D47 +:103D6000687D1CDBB6FFAFD7C09F0DD952C773AFBC +:103D700066F9BBE0C9CF795E7308FF315EC8DFEF3B +:103D8000ECF07FD3478B66078DFFD86A9F1D7C7F41 +:103D9000DE3AA6E76DAEE3D50ACBB7FFAADC257CF9 +:103DA000DB616FFDD47A9D7F01B91B9367CE1B3A0F +:103DB00023B21387A2D25DDC85F70FA2F06BE0354A +:103DC0005A8EAE1FE09171E928394AFFFE2A22F08F +:103DD000284423F3F1B72417B10F57B1F17BD66B09 +:103DE00084D66607F17145F06B865740AF31FCE22F +:103DF0009588579E3F6F333EA3EB5F05EF139F15EA +:103E00003D6363BBA0AC5EE639D27BEC7754225EA7 +:103E1000CFADEB0E66A646C2C1283814D5DE1F050D +:103E20001745B5D7A2E02A53FBB2BDFBD9CFA2718B +:103E30009BDA39965ECE7EC8F9764590E751B9EBAC +:103E40006B7B00FCD1B1D90EB9685B2602F1F47E20 +:103E5000F3F32ADBBDA73CCD09B05356C4483BEE73 +:103E6000945B87930C58CC2AA6719C0AF47723AFF5 +:103E7000A03946C65B4E1535272445F8ED4DF56A49 +:103E80008287DA3706C5B8B6F3626A99CE8DE24208 +:103E9000F5D29E1BABFEB043E68B5A8583FA6BAC22 +:103EA000F96E07E2499F91FF04FBA5A4E6EA04EC42 +:103EB000BF9CAAEF76C534F881AFA89CF325027E9B +:103EC0003BF226E648528AA32270DF309A9F1A3FBF +:103ED000E0E073F0AF8851B0FF59B23ACABE114565 +:103EE0008961F8D36BA2F31B8276D837F349CF42AE +:103EF0001E2D5867AE5F547F8CD7CBA2A8F5A2E9E0 +:103F000071E3E8F55269AC179FF0E9F9969CD77711 +:103F1000EA90CAFCD5B2DC2656A6CABC5AE4A3B4C1 +:103F2000D4CB7C9D96BD1216013D0F485FB706DECF +:103F30008E633DF5BAB0DD727CF7BFE5FF06FCB3DA +:103F4000E7A3FE0F52797CCF073D9F03FCF47B9DD6 +:103F50003F12E7B71FFDC2F733795C2F3804C675EF +:103F6000EA85973BC3DE38F5AC83F3114E2D73B071 +:103F7000BD1E78219EE316A73A497BB8F6F9EFFA01 +:103F800037B23E5ECE747C20CF2EEDAAFA7F67FD5D +:103F9000D852EFF0601E952FC4F1BAAA7C3686F78E +:103FA000D54E3DFF5D7E643CEEBF3A1F631FFE545D +:103FB000BC98F624F857B7FF2B9F1BFC680DFCE557 +:103FC0005D2FDAE720AFE4CFFFD11FF2F5D4932FB6 +:103FD000B2FC3D696B7C18B1CD4D79E1076C831162 +:103FE000D7A38F75106244BEB83690DD165E241ECE +:103FF0004E111E302FC2CB02D8E517C2473DF0D17B +:10400000EE5F111F5FCF94726EA0C0BE4F2B5E1487 +:10401000BF7C1ECFF12A9ABF7CFEC277FD21877E2E +:104020006ABE1FFE7F36DFB3FFB2F395FC1EC8F3F6 +:10403000F038A3F9FE7CBE7EFA570CEF88F7F278D1 +:104040002F72BDA7E7FFABAEF7FF197AE7FFCBCE24 +:10405000F7A7E8FD8A4EEF7837F6414F3DFF1F9DE9 +:10406000C5CF98F7D4FFA5F336ECF902D57BC84746 +:10407000ED5F15A177BC596C95B4698F2CD3F3050E +:1040800085EE4F8DC65F1EB4CF591EC27A207B02CB +:104090007E4CAD2BE7C09B04BF4C7682CAFBB2328C +:1040A0009EF472BA2F28E3BB5502F1AC82F7E630DA +:1040B000FC9AEF1707905752A8CA78CCFE1AEFC6A1 +:1040C000069AC7FE248BA796E0311DE77CB693EADB +:1040D000DD1D5437FCB3DA8EB94E4FC4F8C6B8CCE8 +:1040E0007ED6E5517ED22F3DE6FA71E2C954ECD777 +:1040F0008DCBB6099CCF2944FB08BF52CB77F33C4C +:104100007F29EA96BB5D3F1F4FA17CE977125E785D +:10411000DF26D051D5F3E2CC7813C05B2AF092CBE6 +:10412000F67B40780FBC49B055B7AF84BEFF58E866 +:104130008CDF0C3FDA210AC24182CF78AC55686F20 +:1041400015E40FCB79B21F1D8D37A1FBD5569D0409 +:10415000633A8E0E03CF78DE25DDF43ECF3B1ACFD7 +:104160003F1FAFFB3A2E015ED3E3BD41F045C7A729 +:10417000521167AD253C2B4A2B3E0D3C45E37D0596 +:104180008D55F297C47747ABCF8A75365CB7E7C7D2 +:10419000589324DCB1412DE2F517947CFD8DD70AAC +:1041A0007B7E942B89F349857ECE42D5F7C39161FE +:1041B000C7E320FF1479B95758B5703EFCE6F16E9D +:1041C0005100BFB5408410BF55EA5FFE1EFE11CE00 +:1041D0009714F1BEE6C1F701F772BAC2F007C53A0B +:1041E000EBF1737632E2FE51E72B260EDA390AF450 +:1041F0009ABD949E218EE5F61CC47A2CBEC7E101BF +:10420000FD3A5A1BB89E7C2D77CD60EC5687188EF0 +:104210002D214B3F03ED5E1EC5ED9708B7928474C8 +:10422000BB9002D8E596F96AE4BC7E0BD8BE3CDEB2 +:10423000532BE32602FCD41D65577C5FB64F1F430A +:10424000DF43BE9BD0D85E8EEDCE9120D15529E2C2 +:10425000FDF72EDD645E44F30A07FB3BC5B775EA44 +:1042600009B934BEC01CB7CE1D28F7878D3238502F +:10427000CA11D5E24DC777662FEFC3FE971A5B547C +:10428000BE1B78DC11C77C5EBCF2BA0979F4FDE292 +:104290001D295E0CF3AB893BF365FBE937BE4BCFC1 +:1042A000B52D31FC7CFF40AD391F79068A67E66E7B +:1042B0007A307BEA7E7B3A75A185269D40DC71626F +:1042C00060E7EBD8E79C78A5CAED27EAF99F627909 +:1042D0001CEF9B4F087C6D4DA7EF4D20A706F54DB9 +:1042E00031EECED7D3F88BF578F30FBABC52638595 +:1042F000F6A40BE3EAD4B32B3D9F20643E74F4BADA +:104300001D3450B6EF32DAEB49057E9418F786017A +:10431000ADEDF11D7C77C44019E772E8A501135E8D +:10432000392E5EB2CAD1D42D01A52DDC8BCA5F0D0A +:104330002E881B48F5E3BB8AC2B5F8EE4DAAD8C05B +:10434000E36D2EE6387B7C6F0FE8A0893ACE3712FA +:104350006B7AF07E4ED328C1FCD3747796416FCE32 +:104360004F32FCB9A651DE83C8DF6A1EE5F46EF059 +:1043700022BF2514461CE5F05AB95FD3A536DC1DD3 +:1043800072B6D927F7413E5F9AEB019FCCBD774AC1 +:1043900002E4E79C356AD8017E5F6DCE5B126E2F1A +:1043A000E78DCFA91B6587FF5AE2F2DB312FFF2093 +:1043B000AD17E6619C8BBC0463C2B99FBAE2D7E03B +:1043C000F7A909B49EB1FEAC9E04F8D5D1794F95FA +:1043D0007A7E9301DF91A679F1BDD9899E1DE08F88 +:1043E0004F9676E3B86AD540297F8535DC1DF8798C +:1043F00098D602D6E7A7F992FFC627BB7BBA987F6B +:104400006304E6D56473F7043F37AD88B1004FE32A +:1044100097493EBEDD2AD757D0EFB10490C7A9F324 +:10442000EF8C1A6BD17AEAA7A35358E39385786A85 +:10443000B0E6C03826046A0EC3BF9EA3EBAB39AB0F +:10444000E5F9B12EA3255D85B5614C0A3D3FBA293A +:104450002B0779F106DF3C35B8E01703F35AE93F43 +:10446000BEC05FD88EBE33DEE269811C2EB95279A0 +:10447000B19BE483F1E867AC5ACFEBBC85E48423BD +:1044800009E7061B248C7C55C88DBAFBFDCE08BFFE +:10449000DD2E7671BDBD44E6A376B1876B38FFEAA9 +:1044A0007AE15E46F066B223AC3621B6543BB97C65 +:1044B000BC9AE45D0F21B655A733BCA3DAC365A847 +:1044C000BA373F7FB2DACBF0AEEA410CEFA9F63350 +:1044D000BCB77A1C97CF5617F1F368F933C7358FFD +:1044E000E589BB27D17AF0F97C33D343E382FC71B1 +:1044F0000AF76D38AF24A4BC4BEA2DE58FD0E55107 +:10450000D73E82CFDF54811E840FDBAA51163EEFC7 +:10451000696DCC00DF8D558F6F7F1AF18E052ECE21 +:10452000CB6A118DBC4E5A84C51B1820E58F83F8C9 +:10453000AECBADE3B222F3D4AF5DA0086B047F5DD8 +:10454000571523AC11FA69D6D224133C63E9DB2F4B +:10455000B5A7EFF7EAAAD5802E876F3DF2D07BF49E +:10456000FC915BBFEA21CFF5FEB03E32EED2229A3B +:10457000256C75F27EFC233767A4A57495DF03BD17 +:1045800066E30F0FE8D3FCE56358872B54EF3282C4 +:104590003F047D089F1FEBF4295ED16DE5AFB1AEFE +:1045A000FD4EAF42DF397C73DFC241D4FE117D3F47 +:1045B0004AAC22BC46EA9974A9BF3E81FE4A92FAEF +:1045C000AC0072342CF5D627BF4D0BDC86FAEB130A +:1045D000BC3801A1AD6A1F984FF06A9FDDAB22AED7 +:1045E000572F56226E4338967645C066D6638D1D8A +:1045F00093100F663D3612FB9E41279FD3A28EB0CB +:104600001F33BBF73E9101B954A7B8B15F83739DC7 +:10461000CE64C83785F74791077425E9CBC707AA49 +:104620004CCF23F95679DE0BC97204C7082FC76730 +:104630004A56537BC8C73A9F7D5E84FC9DAD3F9F21 +:10464000D3DBC2A5F1FC197C0FFB87AB7CD3C01F69 +:104650001D509F8D32671AC6D7C155685522F67F07 +:104660009F1A68D5FB97FD1680A8F4FE1DBDBBDA26 +:10467000E766F3F92CD65B463FB37BE7ACEC0A7DEB +:10468000BD7A14B0236A6DDEF4546A577FEE3B6E38 +:10469000195F77CAFCECB20BE80D234E77147FCA82 +:1046A00073923CDF453B9ED88173128B3E72B0FE05 +:1046B0005A74A9D44B223B983F85039AE6B8F898E0 +:1046C000274E1CBC8DC67302E79810EFDFF5A91DBD +:1046D000F9A1B46CAA123300AB4DC8338D8ECF1E36 +:1046E000D8F151429B71F15DEAC5C5C5951F12A075 +:1046F000178CF98C7DFE4C1AECAC4AE52CEF335547 +:104700003EBF22ADADFCB0E8B8F8B9F8B958FDB578 +:104710008A38F32D47DB8C9F47C7019B0746EF473D +:10472000B80A2027CE1C5283D84F6F09F648146D63 +:10473000F46FC4CF2BD7D24B2958979E44EC879D5A +:10474000BA805D9E3748DAE527F478FBA96D2AFB2D +:104750004BA7B6C507619F566CBBE720F6292B36E1 +:104760002A6C9E978B06C617E1513823F518F2DDA7 +:1047700052605C7B1221AF8CF1953E115F05BE5AF1 +:104780001852FC9B681C2D4E4F62BB8871240D9201 +:10479000EBA2D411CA67BCEAE3760C9272D068B778 +:1047A000B0FE1E8E4B53BB936CEFFC294E709EA047 +:1047B000687E1DE33BB62ED78B7DC585A19D159CDC +:1047C000DFB12DCE8D38C4577A9EB3F19D4E7A7FDE +:1047D0009D0649FBED98BE7F776C873C9F8E71628A +:1047E0003D7DA598F305BB0D92FCDF6D90B4875E0F +:1047F000D1D7B1D17E61A829A13BB5FF62EFDB5CC7 +:10480000F6D3FB59E86AE80FBDFBC5AE38DE8FFF73 +:1048100062D7838588339F088D4A05FF1BDF1F3AC7 +:10482000C826E9B04E1D077C89A0CCB329075E736A +:1048300023C799B23E9015B9CE64BED1B15D4F2564 +:1048400058B25BE958EEAC72E27C68E5AEEB8BC027 +:10485000C7AFD8243EEDBB260570ECB992D42DF439 +:1048600004AFB30C6EBFCA12D1CE61F3B3F0B3ED97 +:104870002DF6A3BD11875EBCDBC6E70B675EEAB908 +:10488000FA5AACC3576D4C87C57D3C57733E528373 +:10489000CAF9CB8BB34418F6C7929BE2D7633FCCDF +:1048A00018EFCC5CB9DECB5629C24FF32A0BAA42D3 +:1048B000A3B203D13D801CA5F4C63CE44F36650588 +:1048C0006FEF99CAE77DC31B525BF34C691DF7C4B8 +:1048D000B9C89241C93CEFFBA617B2BE3B6C1701A9 +:1048E000C885C093320FA7ACABCC8F7E007C8FFE07 +:1048F00092C33D5308AFC775BA964D0EF7445E4656 +:10490000D993199C9771DC2EF74BF11CFBC56539C7 +:10491000F43EB54BD5F379F17E52041F95CDF67A6E +:10492000D04E4DF67A7C2E8CD77D92EDD6DDF102FD +:1049300076ABE5E9783DBF2A86F3C88DF796EA7C29 +:1049400097AAD3535C23F331EFB3C97CD5FB36650B +:10495000F0FD1846FBFB6CDA74D84F9807ECF58530 +:10496000F6BA9ED87731C6BB30A18EC7795CE7F323 +:1049700085B175322F5C3F778CF6809BF43CF6E670 +:10498000AD0ECE5FF92AA3E15B8CF7ABAD7D900352 +:10499000037CCFDBCBF5643F123D173DEE08A3FE51 +:1049A000CBAD326EFDA52DF82DE4F0970FA5F0F9F3 +:1049B000A82FDB05F3393F40715B609F7DA9E8B00C +:1049C000CDCD7665173BC1D43E35565890BF336E7A +:1049D000F2DA99C86F68D9E8007B8AAF36DF9FC6E4 +:1049E0007E8DF024729ECD2155806E5F3DFEEF7D61 +:1049F00022ED17A35CB4D19C77D79425ED4AA37E12 +:104A0000ADBE2ED70E927EC7BA41524F95C785EEE6 +:104A1000EBCAF393F826FAB07F470A3E9EF327B617 +:104A2000F75020371E10C15F7D3480BD6C0FF2E659 +:104A3000CB9EDCFA3AF66BBFB28806D81FCAAD5BD4 +:104A40007E85FB3952EF4A643D24C4469EDF976E53 +:104A500079AE95162CCF7F617B092F9AB2A527E0FE +:104A600083A473145A5F8B2C0AF7BF684F3FCEB7ED +:104A7000237A58789F6CA7AA8F876C4AE06FB3CCD3 +:104A8000571E9F1CDC0C7BAFF9A16E02E7DDC7AAA5 +:104A9000EBFA837EA737C659C04FE5B70D4D1C0A08 +:104AA000BCBDA10AD81FA7ADDEF6917184687C4514 +:104AB000E7819FD0E55319AD3B9CFF2CDDF310DF60 +:104AC0002F520ABE045E1E57781FBB74E5D0FB99B7 +:104AD0004F5FB7891ED4EFF1D03D0991F4792FFAD9 +:104AE0003B762FB72FA5F6F2FD5713789C9B6D9C54 +:104AF000D7124DD78B7EFF71F5A2DE3F37FF10D95D +:104B000005FDCFC7C369D1F0AB8FE8FBDF6C8B61CC +:104B10007F903C003EC776CC169A87791FDB1EC378 +:104B2000F2EB589294135F903C0DF4C2382EFF3D87 +:104B3000F3E95B53F8BCDFFCA0F9BB46BF1FEB7287 +:104B4000BC3CC59B08BFB3FC0D290F895E57F0FB29 +:104B50006FD8F8FDE8793C87F7DA45ACD3ED71CC36 +:104B600017C73A487A1CDBD18BF55353925B30DF81 +:104B70006CB5C97A5BA833ECE063DB7BF96A23BED2 +:104B80007B2C29D4D91DF1BCC9165C3950CAD36617 +:104B9000F8C5228C583CF28B04C73F8CF74A9DAB7A +:104BA0001B60A720BF373F87CBB023F9FC3CDDF16A +:104BB000C9D29F1C3058DA0F9CB39AA6E793B3DD95 +:104BC00013B2438E6BBA7D58B62D3ACF57D6A7187D +:104BD000EFD3BA4B35F28A2D186FC89ECEF106E19D +:104BE0007992C65BBAFCFA85C81F2FADBAFB5AD8BA +:104BF0004FA55631CE4EE36A52541E47538C98351A +:104C0000197664643F11F65BE7C1E7E2B4C29DC662 +:104C1000762BEBB7AE83A5BE035C47DF2B5BAEAC58 +:104C2000C6F70DF9C281C2B4563C21AF15F93D4D0E +:104C3000A3F4FA0BCCBBC926EBA3E76D8C277FB09E +:104C400094534D599EDF0F035DFEA2F2F9AED33FA0 +:104C5000E42626B761A7B5EA7B7B6B9E2D8D1F6787 +:104C60006E595F0F96F2AE94C68771F65C67CE2BD5 +:104C7000EFBDD10C5FB2CD0C67EF32C3FDEBCDB011 +:104C8000F78019EE8B7EF3A49F8D73CBF0B351C2E6 +:104C9000CFF638A49F0D187E364AF8D9780E3F1B00 +:104CA00030FC6CC0F0B3011BF886BF0D18FE36EA6D +:104CB0006FD0F124FCE134E46B5658649E2FD1C3CD +:104CC000CFE798A6DB4DE7524E3D2FCFA5103F48CA +:104CD00079BFD0C5EBE401B4180CBD24D753EAB3B7 +:104CE0008EE032C4773DDACCC158AF6BBF9E07BEB1 +:104CF000ABE8DAC879AF4D2B5EEE790FB56B54E2B5 +:104D000005EC8A8AB55FCF841D95E6D14A06D37833 +:104D10002A631B560EE4B87D98E547638DE78D91B5 +:104D2000928E1C7F2956715306D52F486E337F28EB +:104D30003AEF5CAC36E799FF54DE79341F1876E021 +:104D400023B6E60C37FBE9C31E469C77B112EF860B +:104D50009FFE698C5886FB8302AFC83CB5964336EC +:104D60009937B05AD92022EC93653ABE0D78CED946 +:104D70005CB6C7CFC1AB158BB85488EE5A7313FC21 +:104D8000EBD30B2C6C779F5E5050D80EF61FF96555 +:104D90005813B89F2B72BCB89FCBC43F5B92A3CE75 +:104DA0004D7430B5C7FD5CE673139798EAA7ACCE97 +:104DB00035D597140D35D57717727C4B16CAF195FA +:104DC000907EF0A7005EC6798B4B403BB2533A2BE6 +:104DD00081952C97D72B7C6EDCB3745521F0729C97 +:104DE000D8197104836FE6E8FA45580376F0DD9927 +:104DF0005459FFA5D270E4367AEF84AF6E33AE4ECD +:104E000039615977DF300FF2EBD77776D33ABC416F +:104E100009A541F4FC7E80B61D7CF399B57112EFB3 +:104E200027EE6C975C03BBF350DEEB83D0DF369547 +:104E3000F3260C7EE96C9371BAF5838866644FACF7 +:104E4000AF93F9BCEBEB5262BB47ECBF18F36C01BC +:104E50001D04CA6569A91C17120D9807D9EDCB600E +:104E6000B79D3E24ED76633EDD97873B2EA1FA1B6E +:104E700076C6307E3ED3FD86E37D5EECEFC1F98DD4 +:104E8000EABD9D55D803966D9BE147B852B597B0E2 +:104E90004E16ACEFF11EEEF75AF4AE2A709EE6F312 +:104EA00035A31306D377BEDA6EF38E27F8B6BA476A +:104EB000EDF09317598376CEC3DCBADE8EBCE45F87 +:104EC0006C59CFCFE76D29E6BCCBF9A28AFDC8A308 +:104ED000FAB92C63DE0B0A94756EE2AF5E43241FB1 +:104EE0002E8895FB79C4CF2F615EA7B7283ED88F57 +:104EF0005716EDB417D3F3C33ABF7AA64D1B0BFE7A +:104F00006B09C9FB395A5E53E5BD6357AA322FE6D8 +:104F100002F7F94C399BC5FC7DE5D9BEEC674D0D18 +:104F2000F7917E6CB6941F2DF52AEFC7B5BCB63F3E +:104F3000750ABE576FE3DDBB05F60679FEDF22AAD0 +:104F4000708EC033AD41F25596A882FDB7E42F6F45 +:104F50001FC4BA5B92E5F4603D140D534DFC593902 +:104F600026CEC4BFD344B2E91CCD55482A8980AFB0 +:104F70001CDFCDD4FEEA2BFB46C9839CD67A96076C +:104F800043A2CE011698E0722A6F817C129799DEB7 +:104F90002B17935BDBC11FDE28EDD6F25D491BB0FA +:104FA0002FBEC022FDA1699A7C5EB1573E1722F642 +:104FB000DCB9749CC7477CC0746E5BDFE743BF1CE1 +:104FC0000FECD6C0719DE60C929784D1F2DE8D76FF +:104FD000C4D3C85C6E469CB43C4030FAF58BE65AAC +:104FE0009C1FB14AFCBABCEEAECB325AF9A2629712 +:104FF00039DFAAE2D0DBDCCEC8678CAE273B7D650B +:10500000078C7BBCE2E37393DB9AEC88075DA975A0 +:10501000E47B29A2EF4B2B0B35F138A7EE4D7363E0 +:10502000DFB622EA9EB485433C523FE9F17FDC3390 +:1050300024ED8406BB8CDBBAF65978FDC97B79CEAA +:10504000F1E5028BBC2F200A2FE37DEF727F1D322A +:10505000641E1AF0628DC04B341F014FD6083CCD40 +:1050600013124FF3489A0409EE003E8BC4CFCFC40D +:10507000D77CFC41F5F3F72A41E4BF45E3679ED6B0 +:10508000C8F89BA7B9AA82EEF3E75371CBFB0721BF +:105090009F7664C87B0DA3F1375F34AC84DF3B9F00 +:1050A000F4463889F9C2EE643F4DF1426F7B063514 +:1050B000DA6D529E719CB7E5B5B779DDB578695563 +:1050C000832F04D5537B97DFD3BCAC8D3CDFC967FE +:1050D00065FCE4AAB3562EAF1C6F5E7753CFA6F1E2 +:1050E000F39F8B970AE0197C8EB85E421BF7EC2188 +:1050F000CE9770FE7C8DFD10430EB7DA75E6BCE5E9 +:105100000BD97FD171C21B87E871C23C9167CA5B22 +:10511000BE80DD119DB76CE8F11697D49363D5EC92 +:10512000373C34EFE25754F6D33DD3C659F8FCF878 +:105130002BF27E3C6DC59926F0A7166F6139B83801 +:10514000BE2BDF6BA1E971BB73F6764D4A1AE27F85 +:10515000C5316ECEC72FAE518BA0BF8AA99D27A2A5 +:10516000DDCAE5DD3A432F7C727BAF8703B45E3E38 +:10517000B929350D71FF4F57D85249729E6BF7C947 +:105180008AB19D919FF1E9DD8E69C136F0F3D010AF +:10519000195729BFF57DD65B272CAF254CA3F7CB3C +:1051A00056EC4E40DA7FE98AB7F3DD6452F80668C0 +:1051B000EB86E421BEB77EB31BF872AFE7FB04B603 +:1051C00093B8043E8A57AC60BA2F52E47EF50D4A7C +:1051D000F8C8486A773CE6EE8469443F8DFE87FD57 +:1051E000C3331BE3F5F368359C37743C96EC016AD6 +:1051F0007F3446E2F3E8CE782FDF89E10D7466FF55 +:10520000AD9DDCDF29B5D45F85F14C4CD5B60FE1FF +:105210007DDEE0E67495DBF1B975ADA647625BF122 +:105220000FA3DCACEB69D8DB28616F235F06F63691 +:1052300060D8DB28616FE379E55AB3FDF6B2BE5F53 +:1052400068C483BBD436FB60EF060A44EF2AD6B3AA +:10525000E30BFE08BDF58AB4179628DE558D6C2F3A +:10526000C5D7C1EFACB54A3B3BF0B13C1745FF7A1F +:10527000433EFD5ABDC48BFDFCFBE36E7D04ED9700 +:10528000627F6800EE3D25DB2B825F479E758AC8F2 +:1052900073B7A3C8088B84473B334CEDC7BAB34CF4 +:1052A000F5BF48EF63AAFFA5C767822FEF3DD8D4AB +:1052B0007E82779409BE62D02F4DED27F92799E0C1 +:1052C00029E3A69BDA4F2D2A36D55F3D6DA1A97E35 +:1052D000BA76BD09BE76C14DA6F6D755D598EA85F2 +:1052E000A87A0CF8F107E43D6CF5F09F1CB8FFC5F7 +:1052F000C925D5FF0979CCA348D4F3BD2B7FB9F1DB +:1053000011C0FB90D74C2B6ED8684B555B71FC1FBE +:10531000747BE9EA61FE6F87B03FDDC0F7682276F3 +:105320000BBE8B1BEAD1FD5FF9BCA3D5885B35644E +:10533000F07D0951ED2FD46E58DCBED31E62B92525 +:10534000431FB8CE4AF26BD8C07DB9DD08DEFDDC64 +:10535000C7121EBAEFA9AE043F3FB4C74C862FDD7B +:10536000771AF5970F6B92F553049B262F3FB7E200 +:105370003AE4A70C1BD975B557C645DA3CDF6E94E5 +:10538000C013CE85034F28C3C4F728F711DFA33C11 +:10539000407C5F4272ED20F13DCA43E467E2F9FFD1 +:1053A000213F13E56BE467A27C9DFC4B940DE45F09 +:1053B000A27CAB7A1A97EF546BFCDE5FAB1770F9E7 +:1053C0007E75153FFFB07A29971F5707F879CFA14F +:1053D000328EE022BD03FD5E813C18E40B44DD4BC0 +:1053E0002AAADC7CFF41ADAEB744BD9E57B38FFC0B +:1053F00057E0B3D19A74C4D9BABF78617FDF2A8EDF +:1054000044D86D5758FD3943998E1DDD2CF7F5E7CB +:105410004F7AB5814389EEEF664DE991AB42DF5596 +:10542000BD944875EF5ADABE7F326EA8E497DEC3AA +:10543000FCC3F0DE70E761DE4FF76490B53A94612B +:1054400005F4577264FC72B8B5A116F5B5DF0B0F01 +:10545000FCE617E3FFCAFBE0B5642EE3FCB172562D +:10546000FA2B23F4FDFBDAEFE5FEFD088C9DEA87BD +:10547000BB657DED5CD2743ED487F8FB2370DA59AE +:105480009E6F33E5ED8C39DB309AEB5D760FF24D94 +:105490004738C3F27B4EE1467CF9C5F83DB2FFB117 +:1054A000B2FF8DDF87F9FBF03E91973DDCD93A9E44 +:1054B000653CBE06793F5DB66C5FABB71FA151FF7F +:1054C00049185F951C5F31B597E367393702DF4CA8 +:1054D00082B72DEB63D3E5F9E43167F57AAF9C6FC2 +:1054E0007BAB8471A604F599299AF0537F9999C2F0 +:1054F0008BF8DB88D4860C6EAFE733C45BE5F7121C +:10550000BDF23EAEEE7FD7E47E002100E337F2929B +:105510008C75DB29399C013BAFD3623B7F2F53DD78 +:10552000E983BCEEE3D37E0D7EB03A2D3CBF5ABF7B +:105530003C2FFFE6F39E4EB88F74926EAFFF13FAC6 +:10554000DF82F7873B5F90F4C7256F99ADB0328F4C +:10555000FE37B84DFA4B7C11BF60FE447FA607E8CA +:10556000A9D35F31F0A3D3FF1CBD9645D6EBFC71E8 +:105570003EFD4392DE3A3F8D70CABC09B407FD87F9 +:105580005B253FD4C6C87C8F17E30B1FC03D5984F1 +:105590009B22C4E7871BFC5225CF0FFF6FA5FF009E +:1055A000ABBC47CE51E6E47BEA7E8A1F66358B4270 +:1055B000DCD379CAA7C5615D179FF51C043C478CF5 +:1055C0002A84796ED49FBD40BDF64DB30DB0F1BCB9 +:1055D0004B8E6C67D45B9D6FC541EE19DF31DA8D60 +:1055E00038AF5D8E13FA62C9D8D03AE8AF7135563C +:1055F0008E5B9365C2F021D267329FD39FE04B8BC5 +:10560000CCFFF41E583C00F78BCAF35BC225ED6A51 +:105610000FFD07B95AF843D172F427D46D56F81D1F +:1056200067904F4BDF294C35DBE7E3A2F6D72FCB52 +:10563000FE82EDF1CB7EE29EEBBF0DD5CFDF64891C +:10564000ACFFE43DA35F48F97C71F78CF616F5CC0E +:1056500007638A653E17CDDF9283B88D5F54012EB4 +:10566000145556F0C1385167957EA5FF78C500F6F0 +:10567000DA193F978B303F9F400A05CAE40A621F40 +:10568000C0FBE326CEC0FDC1A3734777C7F388FBF9 +:10569000F37EC0F82A54ED6FEE88FBF3F68D91EBA4 +:1056A0006DF154196FDAE7ECD6A61DFA0AE9DBEEC4 +:1056B0003D8017C1E54BA48FBBD3BC5F267D0CF8A2 +:1056C000B2DE35BCAF5CE831E71D19EF5FEE1E2D91 +:1056D000AC2917D67797F77FA623F0FC6A52AF3133 +:1056E000A0D7AB4903C7201EFF6A527B8B2C1D76C7 +:1056F0002EFB3DDDBDADF119EBA3B5BF42EECFB83A +:105700002F784C3B795F70345E2F1321137EC7EBEB +:10571000F8FD1978ED352CEF7CBCC6E1B0631EF0C6 +:10572000F9F61E236F0AF1E4EECB1B18BEC126D793 +:1057300041F9D3130A9017BDF85D99DFF125860270 +:10574000BDBB74288F7FC4D2C1C29ACBFB5101E08C +:10575000BBCC29F17822F0627FDC6BFE528A3608DE +:10576000FD7FB14EE5F3F6279E8CE178DCD1E05366 +:1057700009C0A7C1C765AA67B517EBF05555DEB3D9 +:10578000F4C3FECEB887F4427C4DFC3C6A585E1BE5 +:10579000FCEC227EEE773E3F8B8DF21E83326761FA +:1057A0009B7436FC4E678E3F0E7CE816E1EBC1FF22 +:1057B0001542FA4715CED7E43D9504E3DC6BB45DA2 +:1057C000951F4BEDA9DEEE94F9C206BD331DF21E06 +:1057D000CBCC38E1461C4468B997705CBE9B7F1AFD +:1057E000C64F7EEDB6C8BCB511E1BEBCEF3CEE9035 +:1057F000CAF9EE2FC7CA7BDF1B891E0AD9A7BFE8EB +:105800005BE5EA4A749C99AFCD198679A93FA8E86F +:10581000F7B51E8A48E1F879AE8BFDEC9FE9AF97AA +:105820000ED3FDF5FEA2FF3FFD3D8576F2DEE1C51C +:10583000AFE40631EEC535A4D552F97731F89EB8FC +:105840005AF8E759AD726784E8C9BF97313AD5C6AF +:1058500079E6FFDB7E4F215368BCFEFEB3BFAB3061 +:105860004E3E3AEF77153213561DD0525B7F5723C9 +:10587000FA771532F5FBAC8547EA0FE3F714460AD1 +:105880003FE7E58F4D37EB95D1EE5107DC5C9AE3AE +:105890003D993F91CFF5F8305DAFFC14DDCB854EDF +:1058A0007779AE137CA0FF3E4A10FC69FC3E8A412A +:1058B00077E377526ADBC9DF49F957FB5D9468FAF1 +:1058C00044FF4E4A347DA27F37658416CB781A5D3B +:1058D000E662BE36E8348DFE637B00E77295FF7E9C +:1058E0007A3546ADD33362751EEE293D552CE5FA67 +:1058F00085F4FF835EFF11C88B6F114FC27917A724 +:105900008C87F86BAD226684C0FD849C2FFBEB5A1C +:10591000790F54AD55C603024457DC8BF75DEC3F5D +:10592000E47D8E641FD93A202E53C5EF07EC4E77E5 +:10593000AD17F44E603E59BA549E073E6CA9E3DFA2 +:10594000BB98955DA560FFF268967616FDA78BA2C1 +:105950009DF3382E5F3510F27DE69F1D9D513FB3BC +:105960008BBC3F526437E645DA233333F53CCCE158 +:10597000FA7EBC57E661A9C3655C2DDEEBE6730DCC +:10598000C5D942CF6F159D67F6031F7FCC767C8B00 +:1059900047DAD58D36798F65E01599CFB3AEEA2D0C +:1059A000B6FB37915DAB4AFB66ED9D1C674810D88E +:1059B000C77D24A63909E3EFB55698EC853E41A78B +:1059C000292FB9EF16B709EE174A37B5BF74AFC71D +:1059D00054EF0BF736D5E71EF29AE0BC8641A6F6E7 +:1059E00003DFF79BE0C18DE34CED871E2D32C3C36F +:1059F000BB4A3C8127693E3397B883F21E7D192745 +:105A0000E96297F654ED4DD29F30F2D7357D1D44B3 +:105A1000E7AF77B2CAFC757B95D46B9A4BFAB7EEB9 +:105A200064E156F95C4C03C3B81B82F3C603E63C41 +:105A3000F38E4EE95F59C648FFC3AEE799C7F696A5 +:105A4000E75E8CBC72F22BFCC07777D1389D7FEF7C +:105A500040BF4F349A9F7FA1D33D7ADC5DECF23C8E +:105A60005DED4D76DE3FD75CF62625E1FCF1540D69 +:105A700094FCBFC9D9F6BD4F53753E7B2CB768C2A5 +:105A8000702A1F26B5C5F6D779FD791B21EF6A7FED +:105A90006BE7BCF19FEA6FE6A5723E332C965993F3 +:105AA000B2D91FE4738046BF73F57E7F39526973A4 +:105AB0007E33139BF9DE359168F7807F35D74A86B0 +:105AC000DDB122496D03EFADE732649EFE75AB4355 +:105AD00077F6A271CEB0D7D9E48503411BF8617C7B +:105AE00001D991B43E5EDE33FC2117D1E3E1A55626 +:105AF0008E83950D7F6666A03BECCC66E60724A2FC +:105B0000603F11F6A79AD33AEEA611328FFC4E5C95 +:105B10002CCDE7257EE071B5E8F19116113A777E3C +:105B200022D006BF69AE837C0EC1BD58F253A78850 +:105B30007356F03FFFA7CE4B08EC90523FB63A2188 +:105B4000CF39FE04FE8C732A9EEB6D451B5C382F0B +:105B500022C6291178F866848C5BFC79B8A437DA00 +:105B6000411E5DA81DD97D89D85F68119E44F74FFD +:105B7000C4D5FF27E69F69957186CE4E795EA493C2 +:105B800055637961EFADDF73771EBFEB72438F937F +:105B900075B4CA75DFD12BD7F5F972E1007FDFAE9E +:105BA000C97BD3A2F1CBFF22E22AC6F995D83152A4 +:105BB0008E1872E1DC39941ED20FB5E9F221D8DDDE +:105BC000C27907B7C59BD771B32E1FEE31F445805C +:105BD000FCF87C939C10D8D7AB5DA1B29C2039799E +:105BE00050A37116E35E1677EBEFC3CDBD57EAB154 +:105BF00011FEA2FBB06F327B8D4DACE77D05793F86 +:105C0000EC7C3D4E5E1C88BA9F45B7C7CFAC56DCD6 +:105C1000F8DD8839ABCCF5F35D473E86FF3837FABF +:105C20009E1A63BFEE27E2008DC3757BCD2BBC7A35 +:105C3000FEFD328CEF4C50DE7B7DEEBC921EFF6988 +:105C4000093E25E15B8488FC1D09C32E30600FF6F8 +:105C5000C922EE6121FCC6F6867E5F6E6D33BFD130 +:105C6000C0EFB93C0F7D9F8ECA652BD89F91F90D6F +:105C7000240F785FEE38D5C30E3C1E38CDED8FEF84 +:105C80008AE1BC9213BE86FED8BF35F6E9BA6B72C4 +:105C90001FAB6557BCCC6F705924BC45DE63BFE8B1 +:105CA000EFC1FEF0631B034F99CE39688DE67DBED0 +:105CB000E852ABD9CDFEA66F80163382F8EA98D5AC +:105CC000EBF4127CBB6B1FDFD3359EFC47C835E479 +:105CD000A5AC4895E367F915382DF15725F17705FF +:105CE000197A909FEF0A929E88630AF26AA92C0E95 +:105CF0000FE6FE7FEE3ED894B33EB9FF7B7628BF19 +:105D0000AFAD1ACC70EF60F3A8F7A9DFAB349707FB +:105D100071A4A9B5BF1E1B0BFAFFD1B582CB4EE60D +:105D2000F30346D97B84A44BA3ADEDFA3F8E90EBF1 +:105D300063CF08A1DF5723F97D718DC2FB6A8BC148 +:105D4000E380EF94F7731AF0E93A1D1E2BE1252B3F +:105D5000240CD5043B78B6FE3B699BF5F80BE68F27 +:105D600012F3475C609B1E9FC1FC5162FE780E7966 +:105D70000518F20A30E41560C82B94905778FE7924 +:105D8000D268DED7C6BEDD9888F5847DBB3111EBC5 +:105D900003FB769130F6ED22DB63DF2EB21EFB763D +:105DA00091F5D8B78B84B16F17D91EFB7691B018D7 +:105DB000F4CB561872CD3FC9044F217F604CC47A92 +:105DC000C6BE5DE4F7B16F67FA9E76BDE9FD6BC5AF +:105DD00052D3FBD8B78B6C3F6BA962DAD72309C8C3 +:105DE0007A7DCEDA14E6A3645FD1BC1179FCBB5690 +:105DF00037DABAB27CE038C6E2F258AFA477DD38C1 +:105E0000497F8B3C1FA134F3EF0B9CBEC52EE1B143 +:105E1000E6FC6DA3C4BED7189BDCF742897D2F94A6 +:105E2000D8F742897DAF313DE4BE174AEC7BE139BA +:105E3000F6BD5062DF0B25F6BD5062DF0B25F6BDC7 +:105E40005062DF0BEF61DF0B25F6BDF01CFB5E2817 +:105E5000B1EF85E787691C2511720CF67A77939F5D +:105E6000497C68F233DD2618F67A647BD8EB91F52D +:105E7000B0D723EB61AF47C2B0D723DBC35E8F84BB +:105E80001F1BEE613D06BB3DF23DD8ED9170BFBAE0 +:105E9000C04B88AD4D5877F200CAC678E5619C3793 +:105EA0007CEC852B6659491F36C6289D9348A6DB96 +:105EB00094A9B3C640DFEAF98FFD45B305F24783E5 +:105EC000333980CF19725E69BFEF33B8FE65E35C8A +:105ED0001CFE11DD7DBB04FFEE8CB1DF6EBCEF2537 +:105EE000B58DD268DF0AB7DD2EBA7FA31DE7564510 +:105EF0008C03279A9137E3BBC595033F64B345E113 +:105F00003C93CDCB645E74345F7DACDB479B2D3B13 +:105F1000F7E11C4C73B1E2C5B98FEE751A9F33EBF4 +:105F2000374358545FEB7C7A3D92C079B50746C839 +:105F3000389F317E233E4AF282CF0F0E6B6E189D42 +:105F400048EDB5C028FE1D9CF176693790A5310457 +:105F5000FE64DF80E2DF10C1E7AFEBDFD302721C2B +:105F60008F3D3251BE172BDF7BEC9104EE7FE27246 +:105F700085F3CC866D137E9C537E4F97AF7DB7859E +:105F800055F457BC5CF6677CB7785D673BCE731BF6 +:105F9000F82A168D63709FB418A0E04E59D1D3AA89 +:105FA000B15DDA7E86DB023BE862CF410D1F9034A3 +:105FB000167988A25EF0BDA11306BC699A2FA32BA7 +:105FC0001FBF832AD837D402D75BD0EF4442400AA0 +:105FD000E2C904633E9A26AAB208BF574D2B667CDD +:105FE000F79E2114E0BBCF8CF596547AAFAFF6A2A2 +:105FF00005F65ABFBA462E8D79788725A980C7DB6A +:10600000DC6331FEF16315961FD1793CB00F185E49 +:106010006E637D6ED80F8BE3CFE5F9BC873C9FD3D1 +:10602000876C9CE7737AF919AE2FDE1DC3793DDAD0 +:106030005A85E59A613718793B65D7BF9B0FFC7C81 +:106040009515DC9CD48DF5BC7D24F269BAEE4CC06C +:10605000119CE3CB775F85A37BA797EF96BF57ABE8 +:10606000EFEF18BF7B2AB2FD9C0F66D88142ADB717 +:1060700047EEE318BF9F46F293DB9DDE6B77F3EFAD +:10608000D7E9BF776AC47D8AFF927B10782D7E485E +:10609000FEFED9EC5577174E23789EDF19C6EF62C6 +:1060A00045E7632D8CB2037FEAF74E3D23F5F84FA9 +:1060B000ABFDC7FC72E63569FF15FF65FF5469AF9C +:1060C000D838EF7F468D8CD7899D82EF3F9A513328 +:1060D000DA827BA467ECF67B154FAB1DF8866EB7B2 +:1060E0004C3E9BC9F87D5BB753A622FF94F03BBEA4 +:1060F0003146CF57CBE0F2EAB3321F75B24BAEF761 +:10610000C66704DBD32D0187CC23AC177A7EAB990D +:10611000EF7C82F883E873895FD98FB4E509B07B9F +:10612000E87BD36007A5808F8B57205F96DE66BB28 +:10613000339A8F275BC357E2FB93BD36E6AF7FC62A +:10614000C7B897E39C5C12552FE19CBFD8287FC746 +:10615000619A26F9BBAFCEDF33E3F4F8934BC697D1 +:10616000CEC59F3048C4CCC4D659C8179E89E48593 +:106170000E3C2D3FF2F5E2B365FD3523B7CE5A0E46 +:1061800067E6027109F5663BDF5FADB99CFC3B3405 +:10619000178A13203E00F978DD0D3EFBEC08F95814 +:1061A00030AA608D3F2FE2BCE3ED320F6AF1ED3D86 +:1061B000DAB775DED628E7107EB13E662636DE8871 +:1061C000F3E64B470AFF9841F27726E5BC4418797D +:1061D00098D7E8F0C63F37FC6D958BF1C1F00D7F85 +:1061E000DE330BF7C7953B1B0BC16E95D955E3907A +:1061F00077DD2A87347F6616E4D0A830E4D085E2C4 +:106200000E1B474A3A44C71FE6644BF92CF4FBC205 +:106210003FB9FDE91D90E7C6F83FB9C0EF63AC1B7D +:10622000A9EB89EAFF9E731ED1E73BDEE8A3DD35CB +:10623000B21D7E97C7DF843CFA0E6A9D9E3F2BEF0E +:10624000F530E81B53F71DC73B4AF4FBF0499EB0FD +:106250003F39DBEFF4D6408EF4162B715E68A62A28 +:106260009A79DFF83CBA4B3C3E32FDEF0B918FFB45 +:10627000C86F63E5791D1D7F33EC0D2F39B35AF1DB +:10628000F7D1D23FD8A4FC0AF7C0BEDC3555319C0B +:10629000DF5630AAE851C8BBB86C2FDF83B1C62FD8 +:1062A000F9C9DEB568339E97AF7EF161DC9750592E +:1062B0009FC5BF2B53BCD7B712E71C0B46694F6075 +:1062C0009EC52E37DF1B52B13C89F5D3CCF67ADC64 +:1062D0005534F33E9C81F7037A7CEA9E51F2FBA78A +:1062E000743F03827092A9DD85E27432FF06F939AA +:1062F000883F6AAE3D1C2770DF2CEFA9B08B776416 +:10630000FC31BDEDB841A61E6FCCF0CAF89081BF3C +:106310003B7ACF66396733E2B9E7F0673E8F69941D +:106320006EBFD4EFB36F50D85F2D59A3F2B9F2B15D +:10633000EA78BEC765F1DD8A87D7D7BDDD38DF7B58 +:10634000F1ED648D7970BECC53D87E00EE5B57DCE6 +:10635000B04B66801611F19D92B58379BD9504A965 +:106360006CE35E53A3BCF6EEFD9D9EF1808C7EDE59 +:10637000BF2C71FBEDC911EB7D4E9D62BA5FC180F0 +:10638000855FC6DB66085290348E19DD3D0AF6152E +:10639000DD7E8987EB6EC8B2E3F74866D0972D396A +:1063A00017EEFFFF95F2FF02371C2052008000001D +:1063B000000000001F8B080000000000000BE57DBE +:1063C000097854E5B9F077E6CC99992433E1640172 +:1063D0009200F1241088803861A72E1C1202130845 +:1063E000305940F086308120A1456F0497D04699FE +:1063F0009085104143890D52D461F3564B352ED709 +:1064000042C57600EB525131486B1793617169DDDB +:106410005228B5BD0FF7FABFEFFB9D93CC39990415 +:10642000B4F6FEFD9F3F3E78F29D6F7FBF777FDF22 +:10643000EF243F9DBDCC2632D6B54D90F7A4315602 +:106440002EABB6F14EC6BEC49FE98C2D6F16D4C0DC +:10645000D89E727E3A5BE68572B4EA626C1263651E +:10646000B2624B4EC3A76C8B87F7CBEF3822B14497 +:10647000C6568C604CC882F6F16E9B13C75F0DE365 +:106480000B8CDD2C0773B1FEE6B10AAB8983F67580 +:10649000593606F3F9B6F0797C8D71B66BA05C665F +:1064A000956DC3A05C12CD18B687F505B07F795005 +:1064B000B5C53B715CB6ACD0C9D71B1FB6BE326D3B +:1064C000BDE5CD71B69586F7DB2405CA4B1853DBC5 +:1064D000C2F6A73FA7AB02ED67795D416A2BACB767 +:1064E000DCEF9271DE72AB6A73E3BA705CE8B7A45A +:1064F000A5554A0BEB7F8D6AA17ED355859EF9E9A0 +:10650000C10C01F77B7B941BD7BB446E96109EF9A0 +:106510003A9C1FE4705829073370FC950E0E077DD6 +:10652000BCF2163E4FEFF5717897B794D914A8BF17 +:10653000C5EA4D6D85FEB7C03AFDF05CB2E3488612 +:1065400080CFCA28B700E7C1645FAAD7D5D3FF833D +:10655000076F4AA5FDC3FA11DE2EB7322B09D6B359 +:10656000A21916A3D093E62D9DC02ADBC2E0769334 +:106570006A656C203E2DF464CDADAA6310C083F132 +:106580009FAB6C2766E03E6AAF666C23ECC3E77C8A +:106590007E06EE53FE2E63E23458EF96B7A97E4591 +:1065A000129305A8B7B1E704ACB795431F28337F12 +:1065B000AE1ACAE4637D99CED8301C19DA3B017F4C +:1065C000FCC98C554E5168DE252CB4840D8771B6FC +:1065D00014C01CB0CEC17C9DA50358E53311E0D595 +:1065E000A2ADF766EDBC4B2CEC2516DF537FAF76E2 +:1065F000DE2588CF61FD713C1C778D5E9F1DCCB878 +:106600007D6C4F7B7DDE9278DE0FE901F1708D8627 +:1066100007D87E2DB5E7E55CD1B9B11EF6B376ABF0 +:1066200018B00BF8DC5B3F08CB4F0B6E84FBC76BDD +:106630007FFAE62278FEE907BB4B717FFA3A56FEF5 +:106640002D8B290970BE7FBB8E9EE5C1694C99D008 +:106650007B9FC7A6F8BEA74E0AC39FED3F19E983EB +:10666000F93F7EF2F50C84F31F00074480F3BFFD71 +:1066700064AFC4D27BD6BFBCF16DA9CC190E2F81FB +:10668000E0D594D94EE7B72293F75B51F7E7323C58 +:106690000FE6B4291969BDCFBFACEE69DEBECA4DA5 +:1066A000ED7DCE5FF3F34F61B2987CF9F3D6CFD78F +:1066B0007CEE8F48DE609280E7D36CA07FF3FE1FF4 +:1066C000D6D61DD0E8EF660D8F6FAED846FD963753 +:1066D00096ED1561DD4B74FA2D37BED7CFE7FC166A +:1066E00089CEE7FC968C86242CB7F1F3F98ED83648 +:1066F000EE6E68F7F19AFDB725A7E3AA03A9DE6B52 +:10670000F8F9B009FC7CF0B90ACE8725443C9FA774 +:10671000C2CF67D5A3FC7C563CF9C67B3F5308FF2C +:10672000F8FEB6DA03C87F97B73D7DEA5BF07E4995 +:10673000E336290DDAFD424DA37DE9FD575466C9C4 +:106740002C16F6D7B85B423EF00B558988E73A5CC9 +:106750009995F399472438DB38AA67427C4FFB258B +:106760004C1D8C7C84F987B2FD89BDD7FF278D8EA7 +:10677000F2D3DDB6C1C8BFEA63D81E19D751763F40 +:106780001BD7BBBDFE3C1BC5E96239CC83F47976CF +:10679000863B15E9A2C46231D09BFE3CADD1D790B7 +:1067A00098B625B8DE21094CAE0510FF305ACDB69B +:1067B000C0BC3FFC9643AE75637F9F82F57607931E +:1067C000FD00F23D16653CE1276C795332C232344C +:1067D00009F9DE8835A13FE3FA109DA2C6F3A70BA5 +:1067E000F66D9FC1F104CA6C107F1FC4E7306B1BAC +:1067F000F1A9E82A8E7F36F60E956DC0B7106FF5B9 +:106800007E43D80901DF27C35A70FEA6CCE5747E0B +:10681000D2084E2F7DEDEFCB2BDCDFD9345F80E447 +:10682000441493F7C4D1FED662B97B7F994CB5402E +:10683000FFD2EF5DB3BB09863C5BA31EB541FDD91A +:10684000F54EEAFF4DEDD7BCCF25E565867D76D3C5 +:106850004D33F0B5347C4E48C5759E77C044507FAB +:10686000F6F6280BC2FF6C1AD717180BB90AE15CB1 +:106870001EDB00BFDA19FBD106073D9FD800C834E4 +:106880008AB1031B92A8FCE406859E6D1B32E97D4C +:10689000FA0C8E7F25D16A2CCAE5AE1A97BC07E1A7 +:1068A00011E474D351359CE0007A02E7C79A5ED0B8 +:1068B00021875CF1617C1AE4C7569477AC6A38DBB7 +:1068C0000F5374349F7559C6225EF2F5E9EDEF90CF +:1068D0009AD97A6CF79010D80FE3C6DCF176EE60A7 +:1068E00094D32D695902F45B5A7581F8E152E7207F +:1068F00085A11C77FA1AA660FD8E347923748B6902 +:10690000C9EAA882FE2BEB46B9B1FD1D82D240F345 +:10691000D6086E9C177E54C764E003F81B94573961 +:106920005F1EA1F14B0BF2CB15F7AF6F4886F269F2 +:106930000BEB120134F996825958CEDF19E7AE45B8 +:10694000795BCBF7C376011F75F4F05175AAF7FA9E +:106950001970CEEC12E01B8C3F1AD6C644DC4F9B5C +:106960008AEB67A077EC67B85EAF0DFBBFA0F1CBF9 +:106970008E96D32E453B9F02A41B5FD7E94D78AE80 +:106980004E8BBB4941F9AEBCA520DC5F13D91E0577 +:10699000F187D7AF75F17A786EAC87FAB5BBC500D1 +:1069A000C223572C191442FD6B87487C71E5EEA277 +:1069B00041A86FAC8432CAAF9D3815E053434B0EEB +:1069C0006FB72DF7077EE0A7A902F3223F3A670DC4 +:1069D00015203C3EDA3D38BE06F5BD5B6B4732A85C +:1069E0002FDFBD29159F1FED8E5A8C7C7CA65C3055 +:1069F000330EF59F5D7159A2D243671533389D7DE3 +:106A0000FBD69CC128EFD6FCCFB1476490AB2B01DD +:106A1000476518F7625B4CC00F4DD66C38982A0258 +:106A20006A39137D2B106EDFB11C5E340DE5B0109A +:106A3000782C99DA2B83E54874ACEB5380C70AE0D5 +:106A4000E9ADF7BE4BE37C6A393E7F09F45F73EB37 +:106A5000B3B138CE771E3C395986F759137DFF8E76 +:106A6000E3FF49D8FD980C20613B768F43F95139FB +:106A70008371BE1AEF5DB484C3D7BD47E97BBE8A7C +:106A80008302C1532F2F0D0CB031D44B83CC26E39E +:106A90005366A4077F24B22A94EFBA5EA2BFAFD593 +:106AA000E0F2D180E6543CFFD58FB5A6A2FCF8A356 +:106AB0008B977DFB5E59F95D5887AFC52233C03B8C +:106AC0009F9591DEBBC2CFF5695601CC24B967FE14 +:106AD000AD336268FDAB774C30C83D908F34CF1F2B +:106AE000ADCC83EBB8AAB62B0BF5A7DF5B832BF1FC +:106AF0005C7F0FFAA93F0DCF89E3DFEF9BC559F803 +:106B0000DE7F87C032042C3FEB1AE1243DCC427C6F +:106B1000FD0529B01FDABB26B60591EFDDFA5CDC76 +:106B2000780463AE387630E2CFDA43D2AC215C9F92 +:106B30009271F635D6A02DD2B97D5BD3A3BACBCF57 +:106B40003D6D43BC5F7300F401A4CFE78400EA37D6 +:106B50006BDA9E7E3905C6BBED60D9049C476F7F1A +:106B6000DB731C0E512C642B0AD3ABCB32E31B8698 +:106B7000008F7C72C6BBCB1E842D95E1397D0BF84E +:106B8000D7F45FFB6A46E053A67D326B17E9E3A0BA +:106B90005FD950FEDF5AC7C7BB35B3BD219DF6553F +:106BA00090C0C2CEFFA91912F5D3FBC3BEA95FAD39 +:106BB000E3DE4743B05EB5D6CAA26E84B295FDE16E +:106BC00031841F8B95F7E33EACECDCCBF0BC5B1C57 +:106BD000C09AE0B9AB72ED7F50FB1ABB2CC2B3F682 +:106BE000D6EAA742309F22322F83FEFEEC4A1ACF0C +:106BF0006FE3F2A735E6C9876E817255B1D30DE810 +:106C00000DE55882CFE1BB2CC4E79359D7310B3C3B +:106C10000733A02200D04769BEE3C47718E7C777DF +:106C2000AF5302C88F61E502E2F9E72F7E3801D742 +:106C30007DE355A10B885752CD87BE9940FFEFCC1D +:106C400090B97E32363401DB0D3CAAF135EB099266 +:106C50008F5292128FFA4A10C7C2F5FDDD4278704A +:106C60005808EEC5797538456573FDEFEF6EDF7B2B +:106C7000B80E5590EE0C42FB0542AC1BF77B225E32 +:106C8000CC180FF4FCB9F487341CD70F682B0EE92D +:106C9000D163B3B5A5DB52A6EE40B8CC0080B2EB11 +:106CA000C196191BCFAC50BE8F59BAECB08EECAE6A +:106CB000DFEDAE81B2FCFD014C0451551B95CAB20B +:106CC000617CE1286C14F67374ECD115B8CEFBBA74 +:106CD0001C0CE1C41C463DD766490E7E0FF1B9324B +:106CE000D6CD92500EB565213F62B739DD4DD07ECD +:106CF000E9A550C6BFA35CFAFB71D2D347A5FBBE82 +:106D00009801FB4A11D5D33EA8BF4F0E0E7F00C796 +:106D1000AF8A71D77039C2C2D77F78FDDF6313A005 +:106D2000DFE75D23AD4F41BBCF55871B3458D6F10C +:106D3000DD312F5D07E5EB3579625ED7E7498A15CE +:106D4000ED8ECFBB1C41D4433E775A02028034FB08 +:106D5000F0B1770590DFD90E67508CC57ED227E160 +:106D6000F2869D1816F7C1181231EC4B80E7204DC2 +:106D70002EDD38C0683FA664733B28259BF31FAB0C +:106D8000E226389FF75B5913E2218332CE6B75C838 +:106D90004DB0BE9F3B1F5B0A94CFCEFF2D7D00CA36 +:106DA0008DF387870F6063FBE68B27519F003D6162 +:106DB000D178352D7B528F7C5DA8C125AAF9260993 +:106DC000E1510BF06802782C745A8276D8172B3672 +:106DD000C28155759522DE304BAC1BE906CF17CF2B +:106DE0005F112C5DECBADEE73DFD921CFC1E949712 +:106DF000C279225C4BCF7F70CD038CCEED1A5C073D +:106E00009C63FDB5ACE7FCFED5CE8B59DD8D780ECD +:106E1000778BAE663C875A2BD7F7FC805BFBE3A8E9 +:106E2000DB63782E77D78EA0731A540B7C02ED9417 +:106E30001A2BDB93887CA59DDAEFD7F4419659494C +:106E40007CA6B4D62E23FCBE888EA5FE0CCE554A59 +:106E500089C467385FA92A67C457968DAD14F0DCE2 +:106E6000937006D84F8725E4C27D86A2408B84E7C5 +:106E7000FAEC74A2F321C81186F373C6FE0FAF7744 +:106E8000ED417E233A863C7C0E44116BEC8A1D0D4D +:106E9000EB6A11581BED4BD2F8C76A27E9732D71C5 +:106EA00001E26F2D0B87BA71AF9F33ADBE229AF806 +:106EB000CB75160B95BB960C227BAC250E582B8EF2 +:106EC000B76434E90DCFFF8FC8EDB50CC6EBB3D86E +:106ED000C81D585F9049E3BDA0F3ABAD2E1AAFA516 +:106EE000404D8EA6FA4116EC5F9EE65B87F8912234 +:106EF000F276A07850BB9D3BD5643CCF9D85366A29 +:106F0000F703C1BB64258E738D93F4C6D092E82736 +:106F10001FE3C71944FF524715DFB74E0795533893 +:106F20003FBDCA7FFA21E41FFE6C381127CA8BCF00 +:106F300096225EAB62AC1B50B8D7397FD18DE7ACDF +:106F40000B80CB12A33BC85E573218021BCE4F6694 +:106F5000D98827C7009ED0DE2FC13927F273DE986B +:106F600088E73C7F77F839C378FEBBE1BDB036D601 +:106F70002D4CA573CEC4F1AB58B41BEDEBEEF3FB77 +:106F800079200B9FA2C59D6407583C9FEE7B307B08 +:106F9000608F1C79F83DD81FC0A5D41E9AD48CFAF6 +:106FA000B98555B445E0038F6673FB40665D12CA30 +:106FB000D7653AFE579BF03F3434EE83180DFFA19E +:106FC000DFE1C1DEDD780E9F0A2727E3CBE3FF2D4B +:106FD0002E8E34FEE39A7C792BD1FB235CDF08EB09 +:106FE000D1A1EB50DF586F27FD975D3A3614E7AD1E +:106FF0004EF3FE18C78B1AD16543FF54477297842E +:10700000FBEB58F2A761A8672DAB7A85E8F34AD766 +:10701000B731669C847233CE932585A0FF604FD62E +:107020002FF15CDAE7D9157B043FC891795386A12B +:107030003E74326FCA30E497278701C9933C75BB11 +:10704000908F4A07AF71E13A4F7A265059618A56BC +:107050002EEA97BF7E0CFC35088AC01FC15EC3E7CD +:107060008760AF0581DFBE0FF61A3ECF82BD86EF87 +:107070004F83BD86CFCE0D6E7A7FD233FC20E2C522 +:10708000C566EE4759617547D4CBD61C105950E7F9 +:107090006FF0EFDBFB620CE58A5D0986F22D2D8037 +:1070A000418E9E72F996E186B2AE7F2EAF1B637859 +:1070B000EFAB9E60286F8C2995F09CE28AD3387CD8 +:1070C0008BD308BEA7F2FA806FDE28826FFBC25115 +:1070D000C3107EED085FD48BAD8A0BE1271D5CEAFF +:1070E000423DA6BD78389501BE5B27E2789A1DD552 +:1070F0005EDC3F9CFF88701E85F07568F095099EE8 +:107100006735389F46388F42F866D2B31DE10CF5DB +:10711000B5C50067C0C78B7E941E805FD62E29A29E +:10712000FEBB4F34ECBF62578C09AE4638976F19DF +:1071300062282FAF1B6E28EB70F6551BE15CE499BB +:10714000606AC7D816907B45F80BE0F91B9366136D +:107150003F3D29B0CA0478C6C99C0F5ABD02F9DF69 +:10716000F0A719E47721FE02F463752AF5585F074A +:10717000EDBF0F6DD106463B8431B75406EF177A49 +:10718000A26494EB8B5825D1DB62D64CCF9B591B64 +:107190003D4BD8097A96324E8F9F978526E3F3F7B9 +:1071A00089BEF41CA0E7350EDFA38968BF0DF38DFF +:1071B0004A40BEE48C27FBB4AF73424D9B697CCA46 +:1071C0003959DB17FC14E3DAA15F7BCCB83BEF54F1 +:1071D0007AE6D1C787F9DC38DFA7129FE78D4953DC +:1071E0008621FE31EF40835DD5D77CDB347959E6CB +:1071F000E17042DF2D96CF2D14021BA17C649BDD34 +:10720000867E86739B254D6FBF97ECDDD3A7B87F35 +:10721000E65CFDEC54C4BF9A6DA35211DFCF494A1E +:107220007D15C0FFDC34E0E36EF2E7B8514E9CF10F +:10723000B8A83F488CD82C38B715DAFECE286EDBBC +:107240007A68BF3059647E68EFF3A7C5E2FAF57D2E +:107250009BD7BD7C8BDD80170BA61ACB0B99AD0796 +:107260004FD2F0BC6D3DF5A82F8925037CFDD8DFFA +:10727000557F58FDD64B6178F66F39AE44D46FD840 +:107280001436E54BB1A77F5FF0FD6243C55B2F4924 +:107290003DF0D5F16A528EB71CCF095EDB903F02FC +:1072A0005C2C28974F1EE470DC1673E3D6EB000EBF +:1072B00085EF888CC3B9D4FF7BC4E743DCBF6F9EE6 +:1072C00027A4D175A7C63FCBEADE263B6E597501D0 +:1072D000F19F4267D730F43F1DB907F80BF295795B +:1072E0009CBF1CCB1BF5F01D306E67BEE8B6033E9D +:1072F0001DC9BFB015CB27AB4519E7ED3C7841E37D +:10730000E35D6F4C81F57DE69188CF741EFCE7F05C +:10731000F3C2431A9F09707EBECAEA650D30EF2A98 +:10732000800BDAF3FF6CBE7E397EDE2E7973072286 +:10733000BC6A0437FAE16AF2ECA447B4037DD83999 +:107340003ED5DF81F2682AD8C132E29B7712DA9605 +:10735000270F0E1F88F0627EB53D73720FBEAFA877 +:107360005E958F7E76B6453A83FA373A45504E178A +:1073700032EB9950189EFA9E937ACA84D7D633A1DD +:1073800030BC36E3699B094F2FB24BA9B6745E7FC0 +:1073900062500FDFC39F70FE729B186C60693D786E +:1073A000FBD7BCB74B515900BEF202E2EB5DE3D311 +:1073B0005E0C09617CE50AF918E033C9BFD6981B59 +:1073C000B97EB190CBBF230B6F3AFA3B80DFC7F396 +:1073D000385E7F9CF753E21F1F839685F87A2A3F19 +:1073E0002116F1EF745D11D1994E3FE679DA357CC3 +:1073F000D3DB155A15C91D013F8B3C467CC9786EFD +:10740000E90094A77DAD5F1F576FA78F5B88718DD3 +:10741000B17D8FFB610EB74733F695F43B3E188282 +:107420003DF885FC8445F78C03E5233FB98961DC91 +:10743000F5643187CFC903A3881EDB8B75FDCA476E +:10744000F5A73C6200F5D893C513DE9888F4E39560 +:10745000484EF735EF396D5F67343DA053D303F4E1 +:107460007AF1C1858B96E0B81A5F38E5E1F8FB7ECA +:10747000CB42D23B603DE47FB2CDFC9F32F43F81F2 +:107480007DED42FED59E2F325C47615E11D9D585D8 +:10749000923230929E60DEB779BC233FB1935F0E8B +:1074A000C623BA2A9E57C41A705FC5DCFFDB8EED77 +:1074B00061BEE20779F918B69F688013F19176E012 +:1074C00023283AA4833790DEB4B2D9784E2B1A63BE +:1074D0004CF46EE417C50B399F6BCFCF191889DFB9 +:1074E0005DEEFCF4FE577AFE15D81FCAB8E62F49A8 +:1074F0004F89378C07169D69BE7453FD6853FD781C +:1075000043F972F8D8A9C991761D2FA294A5DE0877 +:10751000EB6F7FD25E119EAF317726B75FE6CED498 +:10752000E2F75F51AECE9A09FC2A86F592AB7DF563 +:10753000D7F9D3A81CEFBC99385FB048C27D5D294C +:107540003F0A93C30BA97F48B061FF6D9A9CAD6859 +:10755000E378D41A73FFCB88879F6AF6D091799C21 +:10756000DF7FA6F1FBCFFE532BFF440820DF3C76E4 +:10757000E8EE58D4DF3F3C382A16EDB1336DB5B193 +:107580005C4FF7C77E0BF0F313A0CB2698EEA3B6A3 +:107590007F8E9E5EFCB4660FFD88EBE9ABADCD91AE +:1075A000FDD4DFB09E6ED6CF73C592A3BF83757C2A +:1075B00018E07034EBEB1F2A4AAC4CF0E170F84C49 +:1075C0005262D1AF7726C0F97D5FF8A8C3E11CC233 +:1075D000218CDFF705C7B35A7FBD0CF621D92D45A5 +:1075E0000EF72F13D19FB0457063BC8A59199B0ABF +:1075F000E778A2386B6F53989E11972B12BE9CAE02 +:107600003B569A8CFC070C5DF4F7BE527D2C15FDA1 +:10761000AC650762883F9AE72DCF37F2994FEA0BA6 +:10762000B27F0FFD8ADE11030E84477E1CE75F4F99 +:107630008B0111CA9DD539B1E1FBF8D02477565999 +:107640002B239E63C52EE33916E5D7D038271F14A8 +:10765000DA8401F03C324D525CBDFB1559F9FE57FE +:107660001D10C9CFBBAAEECF6F607C7115F07B54A3 +:10767000135E69AC9D8F787DDA2B5910CF3BDB12FE +:10768000E6237CFCC5A23B03DA1F6F1C4E787EA666 +:10769000316710CEF7CB9922C9BB0F0FDA2DC2B5D7 +:1076A000F0F44A2C487E81209DE727754524AF3EA3 +:1076B00044B8903D2B135D9C98C9E30EA7611CACA8 +:1076C000B7009DA03EDC19103D8108F47162263F91 +:1076D0008FB3971E20FC7939702C16F58AD36D7CF8 +:1076E000FCB3D5722CC6A95EAF9BE0A2F5E5C3B88A +:1076F000A8F71EE272F4C33A8E8FB84EB20F1BB9D0 +:10770000FC3859B7E2FE69008F4FB788A4777EDA5C +:1077100058347F1A9EF71689CA39050B29CE713263 +:10772000C0E5D1A9C0D9523CBF0FEBE0F4A15C7316 +:10773000680AC9DD4FEA25C287F203C67359B82526 +:10774000C66CAFC66681DE558EBF29F83F7516DA66 +:1077500049CB93407E02E59ECE2F92D04F59E84F01 +:10776000308C63670512E21DEA97D86EF9C3459322 +:1077700082487F7E81E4DFB2E7009F603DD2BEEBAE +:1077800049DE9535DB0DF316561BEDA3E5267BC8C8 +:107790006C2F5D4E5E9CD6F054B73B4E4B95A59139 +:1077A000F212E45C4D2E307916C2FD0C18D64D59FC +:1077B00000CFE74415CB17EBA2887F962D3B7F8344 +:1077C000A697DE8878C0DC7E3655B7D3C3E86C79DF +:1077D0009D6892DB46F882FEFC01EAC78D099A1C7F +:1077E000F51791DF6E548E1A9F8BEBB852FBFB8A14 +:1077F000F5DB524DBF2D25FDF624EAB7B09F766C20 +:1078000012D61FF45DF2EF9C9A7713D95FA7BAFDE9 +:10781000675ECD7FC6F59453F9459A7FC7AD97074C +:10782000B07EF89CCE2FDED7CEE1ACC6274F6B7C66 +:10783000B253B3B71A347951A7C98B53F99ABD958E +:10784000C8485E58AD2ABB123E734B4B8C493E2450 +:1078500098ECA821A6F331CA8BED5EDF6C3C077B68 +:10786000D268C37B491E6FD4CFF71D263FF24585F2 +:10787000E7156D429CC0B8C9429EA7C51C6DE44780 +:107880005EE856A87E08C60BA13D9A54984FA2E325 +:10789000A7FE5E4EE4EFF5723CECBA06DBA5B551EF +:1078A000B9762163980F33421F07C051037AC21083 +:1078B000F467C33C4960A0617B1DDF87166FA37628 +:1078C000D9154C16A0DDEADC34C28724A6127F1934 +:1078D000B486A998F7C202CF52BBBDF7C23E00EFF3 +:1078E00043B5D3C92E2F72C4F2B837C8C7FEF1AC66 +:1078F00086C7773D09A4B70CB572D4EC136FB57683 +:1079000097C3DB303DE82EA20B66217FC4B6987189 +:1079100012E269A1D34B7E03C0EBA577A27EFFA242 +:107920008DFB0916723F707BDE9487D1DE1DF794C4 +:10793000937CCAED2B757F6517E1736775911FE521 +:10794000DEAF3D5CCE8D79EA130BE6BD751E646E2D +:107950002C1FAB7EF6FCAF486F17C81F74B23A8776 +:10796000F365C6BC98C779D293B391CA53C130CEE0 +:10797000427A50375A711D00D726AA5FB17512EAB4 +:107980003BC745C2DF242DDF48C6734DEE2927AA29 +:107990005A991DA472523ECF13FC99A61FB469E7F1 +:1079A000F9B8E6A7784CA39B168D6EBEAFD1CD6615 +:1079B000B3DF7917A79B9156F7D618288FF4BB48E9 +:1079C000CEBC957F96D60DF42F635C372D4F6C9A05 +:1079D00008701B630F119F2E02B1B711F63323BF3E +:1079E00086F2188B7C8CE21685C535B4BE10C6981D +:1079F000AE43BDA94610B57AE48F631282D4BED0DF +:107A0000C164EC5FE479FA08E6E32EF40168A03C77 +:107A1000B3B84620F894C178D0FE48F5761AEF54F2 +:107A2000055F47BB8BF73F59C6643F943398E7E83F +:107A30001D7C9D5E8C8B9EAA7EF608C1BB98C3FB05 +:107A4000BA8F2C067ACC0A461BE87AF4BE7843FD3E +:107A5000A81D2986F2406FBAA17D82C748EFD123C5 +:107A6000C61BEA4F7A8A2C2867753B4FF78B757ACD +:107A7000B8DC9DF194D382F058A4F90B1061D920A1 +:107A8000B4BA18F97D1B353D91350F6798C7B1F72A +:107A9000BB16CA13D85C5CEBC0FC878B6D563A2FC3 +:107AA0001897F8C8A9C3561AD7915627A01FF33EB6 +:107AB00080B318A6FF35EAF24D8B5FE07AAC61EB3C +:107AC000895718668E75B76FD1F069BBB60EE0DBCB +:107AD0003324B2C7399E24E4338B04FD071673396F +:107AE0006DA6CB36ADFFE35AFFC7347CECF4ECDD7A +:107AF000188D7059CC481FC915D76C8CC275E433EA +:107B0000A2C7B6E0D1E870FDF1677D8D533C2197A7 +:107B1000C6F1733E3A7A81501B85E7BA2BF4A7373A +:107B2000E1F9C2A70D1B6361BD4F08AC0D294AE7FF +:107B30009FBAFE7DDD678D543F7A3C986850FFC246 +:107B4000674DBCFD64A6A0BFEB679ADC69D4E8274B +:107B500063DF58F22F5EDC6123BBE7B1F9ABF6B40B +:107B6000C07A47CDBDE789E7105FE6DFF3BBE79456 +:107B70001E3DBF687E7207E6F18FDCE062C81FF42D +:107B80007933F67D924DEB96AD0CF1F4C7FB9F5F18 +:107B90008EE33DFE58B44585F17FBCC74AFCE5EA5B +:107BA000FB1EDEB383E48D492FF618EDFCC737B713 +:107BB0003E7110DF573DFBE8B9B07C9D93F3360D65 +:107BC00043BF69FB868A9699197DF3CF221BF3A1E7 +:107BD000FFC7F3C227CFBC0EF3FFC677F5F8703BA3 +:107BE00060D42CEEFF69DF50D53213ECD4D122CF14 +:107BF000576056FF4684C7E89F0E52507F0352B02D +:107C0000FA00969E39511615F6F79B807537F1816B +:107C1000399B33F03CB37F9C7FF4233CE7531ABE7F +:107C2000F7A18FE87EAAEEB2A410DCFD2F3AB87D52 +:107C3000A32AC3C83E762BC30AC3F4B9F67BF43833 +:107C40009EFB3DE4E3852531145FD6E32EA2E7CF0A +:107C5000F5C8E7974DAD9C24D3FA8DF1FC1484DF71 +:107C6000048CF7F2B8BDDF6F65941F045B433AB92B +:107C70005B1C4D7927EFAEBE8BE2F6FE1ABB9C91E2 +:107C8000487183A7B05C057CC73E91E2B901CA3751 +:107C90009EC5F3372E2CAE7DD8A6F40DFFBACB9C33 +:107CA0008FA49D8FF9FDCDDAB9D4E2B96418CEE581 +:107CB000A86F6284738975107EE9E722C636D2B94F +:107CC00030873313F33F067394C2FDBC8172A8E37F +:107CD000944872EC3725EB6AEE86F2F94B0318D222 +:107CE000851E57294DE279087424C0B724ADFF6082 +:107CF0004DEF463E867A77A91677E958CA28EEA254 +:107D00008F77B16A80CCC7BB8DF4E6D24AA07F944E +:107D100025313F27FDA27E38CF932875762DA5BC4F +:107D200055C1E2C6F8F960935EEF6795B4DEC1EF26 +:107D300088E4CFB7C46CA1FE83013C6216B6B211D1 +:107D400010A83D0A76305A31AF24055F28617A9633 +:107D500096B73BB8EAA75C3FCA819EC986F9842FD3 +:107D600069FDB5EF8BC807AAEC0AF23DCCD142BE43 +:107D70004DF04B433C6AA5FEF2B7998CF73998CA8F +:107D800094C4C9DC0F86F399D70FE371BD10F433A7 +:107D9000DCAF50CDE7DF3597DF07618799126EB70B +:107DA000B0F0F50C3794353F99B12C25D90C72EA17 +:107DB00037978A0654F6EBC733F6B728DEFEFDBECA +:107DC000156176577A4F7B3D5F4C87734A95FDB4BA +:107DD00010DB77BFED5EF5C02CC06727F366FF0AA6 +:107DE000E0E17B4724796789394EF0084571F874E2 +:107DF000EBB38BB9BE0BDA790DE55D83BCC3F3C37E +:107E00007CED9180EFCC6FCC17D0E7D5E34B1D1AFA +:107E10003F0EA58522FA058F69F4DBB9E173CA2B01 +:107E20002845FD167039B4F163C33D900105338ECA +:107E3000E1BACDF908BA5E8A7296F0D7CFE56C87C1 +:107E40007F02F19D8BCCD54CFABF99DF5819E57FA5 +:107E5000DC2D46BB9BC86F772FE58F54F9EDB21D23 +:107E60009EF3DC467FCC82A9467950A02698E48513 +:107E7000D1DFB5D06B8C138D68594FFCEB22EA4DE6 +:107E8000C4EFF87AAC5A7E9984F74C44B4D7FDF429 +:107E90003CAEF1E737353D330AF92BBC8FC1047393 +:107EA000C047170B517900A2FC704C6D5728EF3179 +:107EB00081A9541EC87C54D6F3219359809E7A9E82 +:107EC000CB3016A2F255A80F8948520A3D87A31D50 +:107ED000321CF53C7777BC87F22773D2285E50C0FE +:107EE000D4F7B05DFE844F49EEE5DFC4C80FCFFC88 +:107EF000F52B5428772CD4CA98098FF926B98C23EE +:107F0000A7BF96D7E7E9E5BA152AD6CFE0EDA5D900 +:107F10004D7BFD4EE25F5AFD265EDF5D6E583103FC +:107F2000CB9285CA715AFBC299AA6D36E62DCD66F1 +:107F30008407C11CD5317B604FB92C478D0E2FAF04 +:107F4000CB559DE1E567B3D5D8F07267B62A879720 +:107F500087E6AAF1BCCCFD4EEF48EA30B477E1E702 +:107F600047C2648E87F8F39AE44BC176EA0181E058 +:107F70006507BE8DF092981A44A60464E3C07C2283 +:107F8000E033B63BA19E8DB751DE9F25C699DA9F9F +:107F90003FD24C5F21891D443FDD02AB2F13F76DAB +:107FA000E67B82FF95BF633E0FD04336EAF9A16AB4 +:107FB000AE0784AAB93F40A713FDBD79BECBE13D12 +:107FC00053C3FCBCE93DE3F6B57E331E9FD0F4BD40 +:107FD000764DDF7B47F34B77EF37648DFBC0D143A2 +:107FE000DF7DF34F2BFB208C7FF6DEEFD9A51297B8 +:107FF0001F32CA8B8E28B638D2FDCABED6E7CC99BE +:1080000055309BECDBA132C51998CEF739BFE9C0DA +:108010005F810F8E19A0DBAF6E07C2218325CDC90A +:108020008479B77918E9AFB5338F1622FFB95802B2 +:10803000120CD675F68E7348714C788ADB13CDC35B +:1080400018ADD7952647A1BE54AFF14D3B8BCB1B46 +:1080500081EB1F6A25796B5E777D6C40C0B8624A00 +:10806000308AFB371259200AC649F1B83D94B7E26D +:1080700017650F964BD8FC4C282F6F11150F8C737A +:10808000ACA58895C3B8E55381CF51663ACFA78890 +:10809000D7F0788C9D51BE45EB4027C5ABEB368FB2 +:1080A0003AB212F966B2C832A0FDD8FAF11EF47BDA +:1080B000D63AE3E329E6A4ADA7D6E97E15EF63F847 +:1080C000650BBF4F22AB0ECC47DF7D87D583FC7C91 +:1080D000D8D31363C530F89FAD3B1F8579EE8FCAA7 +:1080E00016AA7FB43ADB718B13EF130655CA33908F +:1080F000CFA84E987727B4190CE3DD5F71A67924D9 +:10810000EB1B1F623D36039EC6B86D263FA8D16F9C +:108110002999F483E6D95AFC7B329B8CE77CED13DA +:108120009724D473973915F2A367370A949F123AAC +:10813000E24EC5733ABB7514F9CDEB1A45CD6FED20 +:1081400026BF7568184BC57B3665CD02E9C562DD73 +:108150009F6BB0DF55994A328E73D5C4AEE4707F01 +:10816000D9A3F7DC15857CB4AEC4A2F9B9198DA3E7 +:1081700028AA230DF6FF7E9DC0F3272459C0FBCC0F +:10818000AE07C5285C57A7C4FD144DC04FF19E6EC5 +:10819000D38CC27EE950FA1BAC33CC6EA94F4C8F06 +:1081A000C6797BF05725FFFAB9E609141FD9D39891 +:1081B0004DF920E671EEDBC0DAD03EA9DFE0A06722 +:1081C000AFFA546FAA1BFABFBF6D46030829F6FE2B +:1081D00091D549784F6865B39D4545C0E373DBA6EB +:1081E000D07C2BF13E33CEDB5C60433931BB6586FE +:1081F0000DE176DF06F5E9F079EE2CF0BD8C7C2FF1 +:10820000A6F969C213270BFA119EBFB8414D45FD6F +:10821000E25C068B982F796236D7335EBFC14BF78D +:108220004ADE1F16B9DD3BB3B9DF792E120BCA0F38 +:108230002B7B7315C0B90CE8A9065E9D6D9C108B55 +:10824000782BB135C4A47E5352E4477BEE02EAEDAD +:10825000C0CF1BEE59B4A31CDAD5DF3BF22D64CF9F +:10826000D7DAB8DECC7E2D125D805E5886F4F997A1 +:1082700062875C1BC67F517F540DF9825E86FA9D32 +:10828000D428066DC0CFA5C31FFC37DA3B88B76A78 +:10829000181ED3CF64CD2ED0F235922693364E3FA2 +:1082A000F5731605820CE32E2B1C789E663DBD17D8 +:1082B0009EF45A47D8F8A8E7CE646A54D83A802585 +:1082C00004C95FEEE3F376B7D3EAADC060BE0CD36A +:1082D000DFCDF5FA3E46ED30D2ABC3C3CF0BE0DBCA +:1082E0006FBCEEEA80B1DF480FA3731B2DAA473F96 +:1082F0004039DB2A527EF598561EFFBF3894919F75 +:10830000A8AFF174FE8B3FD6411A1C01AE0D8985D2 +:10831000749E7DF5B3054EA869E37AECC3AB938CEC +:10832000EBD2DB8DECDED73A16CDF5C136B4CFEC0F +:1083300001E07BE3F0794245F99DB9FB0EB9BF7DC1 +:108340009BF9D94A5669437D4D51427BEE43BED1DC +:10835000E222F983E83062325D5D24B983FDD430D6 +:10836000BEE77A706FD36858C7B95DDC1FDAB46DA9 +:10837000EF134FA0DCD915E3E671267E4EE3982E6D +:10838000FF78FECF2DACE74719A48D0FED3FD2E467 +:1083900029C350D5A09E78D50707967FF604FCFA2E +:1083A0003EAB9C8A7C4CDA5DE4B819CAE36C81244C +:1083B000E4A7B7ECB2F7AC0BFED95B8C65699FBD47 +:1083C000175E3A747C82F19A0E3DB16339CAA943B3 +:1083D0000E37A688237EF90D74124A2F007AEABC64 +:1083E000E73FE89E7EB47C7E29E5B957DBE97E97BE +:1083F00019BEFB6673BB9F69F736747A8A6A1EC51D +:10840000D0BF7846B39BCE6C013B15CA0DD536055F +:10841000BF6FD0E92E5093228C67ABB69DC67365B3 +:10842000E176627ACF3EF4F13BFDDC0FD900E30B3D +:1084300011FC7D971BEF4F5EB5C203F87FC1EBFDCA +:10844000B607D67F76CB0ADA6FD5C1EACE5FE1F9FF +:108450000EF2DD86F567B60C9F2CA023D2AAD0BD04 +:10846000BFBABA67489E344F857760CF37B759A3F4 +:1084700050FFF0D759287EDBDC96183D02E594D3F7 +:108480001231CE1AF070BED9234FBCB1E1FA50D3ED +:108490004CAE0F094F95DC9F0EF0AA3BC5F3147547 +:1084A000FD43D6F0648C5D26FE2CD7F13CB71E7DD3 +:1084B00088EBD51751AF467D6952B91C2E9FEA63F0 +:1084C000F9F730CA67BAFD781F33C7C9487E5C85A3 +:1084D0009716D06FE16481D969F8BD0C37C3FCDC15 +:1084E00078D07F14C0F8C12D5CDF89763ADD2AE2AE +:1084F000BBCAE9CA01FF213CA3335586F3584DFAA4 +:1085000085CDA43F88A6F24E8F519F50983B16E12F +:10851000ECDADA7F1E87EECF05BD89EE9BF919C034 +:108520001FF1D4E1A7F389054302ED0AA6AA4AE2A6 +:10853000A01EBD1FEFB571FF8A4CF122416D20BF17 +:10854000FDAE09DCBF91CC78DC2B45E5F6FCB8A983 +:108550007E2A83FD407128F673168D7C79BBD7F790 +:108560000CE24D9A1020FB2F7E2C1388ECBFA65EE8 +:10857000CEAAAE2CAEF4C3A3DCFF576B897647FAC4 +:108580009EC2A1B99C1EA38FC1DEA09D789383E2F9 +:1085900079B9E28146C4A79D132DE4D7DEC94EC840 +:1085A000C84F8E7B787ED125AFF7750FC565BD6945 +:1085B00008FF242B5854A0ECDA343FEEB03BD3A391 +:1085C00051D4BF9BFC3CC1C30FB0CB807FBBAB126F +:1085D000E333E1FD23551B09AECA40EE27D3EF9FDD +:1085E00027C8FC9E7F93F7BC1FEFF9FE702EBF07D4 +:1085F000145D609D930EE5ABAA4302D2DD26977B06 +:1086000031E273A3F20C9D475A9662417FD9102B39 +:108610007BD53E9EB127E3783D0A4AACFFC1D241EB +:10862000BBC3F3491ED0F6FD0321B2BEB27C2E9728 +:10863000271D87009003D03E669AFDFD7839D9CF7B +:10864000DD65801BF47FC0CFEDE73F7B1E2FF75B1E +:10865000C92ED2ECF7F672B2CF315E0AF573F2D6BC +:1086600095FBA1FC485AE47913F2397C1F794DDD62 +:108670001103F0F86B0D8F63F57DCEAA6001DE5219 +:108680003B90A5E23AEB5CB6C591BE27B3329FEFB3 +:10869000B723B18DE0C5409EC75E47F7E94DFA6A42 +:1086A00080F4E00B15E3FD536877958CE2FFC04F33 +:1086B000264DA6ABFEF4E39AC4E5A8596FD5F52B79 +:1086C0007DDEFB522B9351FF6C75A9C43F5A416F5D +:1086D000453C2BADE67A6BA9B5EB3DBC3F94729C53 +:1086E000E7BF084F8D6DC2EF1B00BC14C4BBD94E51 +:1086F0009521BF1963F7D23DA35ACC5F977BF457FE +:10870000260E3DE283F7D21091F4C418B98DF457C8 +:108710003693E7E5AAF01FF21B5D9F758EB51AF23E +:1087200077EDA6FC5EC994CF9B99A7E5C369FCC60B +:10873000356962BF7AD3CFC1DEC5751D067E83CF92 +:1087400020D8BDF83C0A76393E5F02BB1CFDDD2F08 +:108750006FC8A4E7AB1BDCF4FE571BA6D2737A6A82 +:1087600048427D9BFCCEE47C644181FC773A3E0527 +:1087700046648FC5FBC7BC7EE69C94FFF05F0FF597 +:10878000895A7BFF17849FDD65A6ACC4F6A549BC5A +:108790007C302F7525FA775E2B56B3F300CF065A3F +:1087A000BC65F85D07F65D3BC527CCFB3996A7CBCA +:1087B000EBC8F63AC34F1618FD35DEBC7EFC353FDC +:1087C00010F83A96CF5DB70FD731A0C0EA457C4D7F +:1087D0004D37C609F6E769F107ED99FAABCA878804 +:1087E0001E04A08789FDD14390213DEC74B11B91FB +:1087F0001E5A5747A6871BF2B95C6D75727B8FCDE9 +:10880000017A1802E512B3FD16A2FC8F0B557B8F7F +:10881000647C23F4A026A13CAD5B0DF214C6A93BF9 +:10882000B2FA5D92A3480FD07A30D203D247183DF6 +:10883000E077585AE3347A900302C681801E82782A +:108840005FB04EBBCF11460F02CAE16E7AA8F86640 +:10885000E9A129CF287FBF2A3DFCE28610E53174CB +:10886000A40592110E3B25EE3FFAAA74326C8E8D50 +:10887000FB8BAE7127217FA995383F9D3DF434F9DC +:10888000E1F21D6E11E58A47E178983B71027DFFA8 +:10889000E7CD3C1BFF5EC102750FE1FFA28FC8DF71 +:1088A0003AD0C2E9EBD86B7BCB112F87D5B717CC69 +:1088B00046BC582F92DEDB6B7FF334FC11F8FA4193 +:1088C000034A0E8FE7FD671EAF57D69FE4FC368E36 +:1088D000C919B09E24BF5CE8C1F8CCF516FABEC732 +:1088E0008082F6389493FA78CC5A998CF8852AA825 +:1088F000637C6F7A819F36699081DE7EDE1FBD5D6D +:108900008EBE676BF4053F9477EBD3EE2D7E55FF5B +:10891000699FFEBC6B22FB07B76872AE55E27918FF +:10892000D05AC67BFA4F797DBFCD23FFAB490F3BB1 +:108930002C07D15FC6D6C6927F37C9CAF5AE24854B +:10894000E78F0C617E82B31E07D3F53645E5793E8D +:10895000B905BEB338EE6EA61CC1EF1938DD6C3117 +:10896000C5B9407FC578F576AF7A8EE6FD9AFA589C +:108970004281FA497FF874FD22B50BC7EFAB7E4602 +:10898000C15F8E7D89718B6A9ECF6CADBE9DEE738B +:108990008960AF5830DEE969A3EF02C9B24D51C812 +:1089A000EE52E763DE62AC069F59E227A47FB7264A +:1089B00081FEEFEEF183EE4CE6714E113DDCA077C7 +:1089C000B61E77FB6F81796CC037FC788F3D1FF442 +:1089D0007428C7A09E8E634DE5FAB87EFF2566AC6D +:1089E000A6A7ABC638DCE5F4F4017334B9399E4D63 +:1089F00044F8A45A94EDD3E0FD8487724FE2F14C21 +:108A00007A7865028AB329BBEB8BF0FB57ABF7BFD3 +:108A1000BF1BFD92D37E6B6748A7AD87B89EA22E81 +:108A200060742FF90AF83CD1C90DF94F97FB472024 +:108A30007F898C77AF6B78D781789768C0BBCC394A +:108A40000323E29D1FF9F13F8077E3E718F12EDF62 +:108A5000847713E6FC6378771DAEFB138CFFC03878 +:108A6000EF2D546F98D30F1EA62E5467CCE9070F35 +:108A7000C3FCEE644F8D645551E1DF15D49F0D2882 +:108A8000E7FA89FBDB379F21B9595B95E340FDADE0 +:108A9000AEE4CC1B1847F84B955D09F713819E6730 +:108AA000D083615CE60703F6683ECF633EB6DE1E08 +:108AB0009C0EFD4A65EECF2F95DD0CF3A845679718 +:108AC000E4037EB52CC9C750BFB627597AFC12F013 +:108AD000EF5AE9843707E0DC097214CE984DBF677E +:108AE0007B22FA9B5E3B3495FC4E3A7D74C4F17157 +:108AF0006FE802F914D67FFADF406E85E1FB0C6067 +:108B0000E0E1E51C47B2A17DAE9C66A89F9D74B5CF +:108B1000A1DE3569DF4CC40BB14C8BEB6BF7CF7426 +:108B2000FD618C5D253C6BD5F4DB3C25CBD01FF57E +:108B30005CE47F5694EB503F37739A613E5DBE5FB5 +:108B40000FFF21DD8A26B96D96F356939CEFACBEDC +:108B5000108FFCBE618EF1BEDA666B289BF808E3CD +:108B6000796A575DFA05E17FA7C2F1BB4EE2F8EEE4 +:108B70009FAA7D67C5443FE36CDC6F56BBC4417E52 +:108B8000FBDA43DF7AD717E64F622CF01ADE671C58 +:108B9000171BAFA03F7E8895DBCFB2CAEDC0B1AE48 +:108BA000EFD3F86C35979F82CCBF37B90BF8027EB4 +:108BB0003F8B1D0E913DCFBE6BA3FB4EE3E6C7116D +:108BC000DEECACB0501ED60F856094301CE9562503 +:108BD00039C392985C47F9876FF3EF1432E6DE9C55 +:108BE0008CA6B44A79826CAAA3EB352D2F15ED948F +:108BF000280F736F9C867C90EF337E223F3FA79BAC +:108C000097E5EB7959B75FE3925833E6990EC1F1D6 +:108C1000A06D6215936BC94F10A4FAA11E76A2969F +:108C2000E6E7FD0797336F2394C54A55F3DFFAB49F +:108C3000787517C591D3057734F2EDE1A297E2C8B4 +:108C4000B14CA638730AABA4678C10E44CE36BF20A +:108C50008F6B010018AF67B136F2E766FFD8C9D055 +:108C6000EFD6EAB2EDA1FC9890427EB94DA7F8BDCF +:108C7000B6DAA577BD3109DA37BEC1F3F3370DF3A4 +:108C8000BF8B748D3889F742456725D50F7E5574A3 +:108C9000CF56F07D33C37BC4CB9C9600860AAEB51D +:108CA00075FD12F3EE58BC8DA13E5207FDCBA0BE60 +:108CB00073A905793143CDB4DBFF88F53778FDAF73 +:108CC000A39EFBDF03E81E3233F90D5B7D5C5F6E14 +:108CD0004DB4119DD7966427E1780D89D174DF6C6E +:108CE000F18D956F20FFA87D5B746F14781FF4A73A +:108CF00013EE613CDFE64D433DD4E6B4517E87D9A7 +:108D0000EF6763DEB726C1BEEAE26E49EA4F1FEAAB +:108D100033CE506209DA62AF3CCE507FEF4D14572C +:108D2000D0D7A9EFB3A1E4BCB45CC1DFFEC1384326 +:108D3000B51039CE10E2DFD3C8C0FA71081FEECFEC +:108D4000FEBA71861DF3BE5E9C41DFF73CEDF77CF9 +:108D5000406C2D5F82FCED746E969EF585C1711F8F +:108D6000AEAF147F53F87BF49F2FD0CA6F1C68FFFF +:108D700004FDE4C77F74F4003EA75F7AB4642DE07D +:108D800045C154EECF7FEB7B710FF2E18C7EF97918 +:108D90006EA3BF1C7F103F691D02BFE71E5E5F60B0 +:108DA0005A57B6D5E85F9FE934B69F9568ACF70C83 +:108DB0003596F5BC15F37E37C6DC4F79679BD63107 +:108DC000FA1E110B3F0FF1F265BBD21B4FC2FDE53E +:108DD000CC9D4674DFF90EA77BEF8B7F71915D9977 +:108DE0006491D10EBDB0B87ED3EB4A783CC0A322CB +:108DF0001E7DF193B16FA25F9BC9BE20E6F12DCF1E +:108E0000E1DF61EAE59FD7FCE3195547DA6686C5DD +:108E10004F9B06F96E9A0BFA4B4649A105F5878CD4 +:108E2000AA97A87ED19249FDE291AFEA98611CFC15 +:108E30009E1DDAB7BEAA97E97D5FFA8E45F1F37CF5 +:108E4000B86ABB42FE5FD3F76E7D98CF867C3E9DAD +:108E5000CB9B5A89CB273815265EC7485909DF971F +:108E600045E17CFDE2547E4F820117427EA58F676B +:108E7000968FBA1C70AA5C7FF4559BF2EF4CE36F9F +:108E8000F7FAEE990B7425381B789E5D8ED6EE307E +:108E9000D74BD91C26A35C867D46CCBBAC9BABD9FB +:108EA000997DE47B31DD0E2C7EF55DE4875FD90E84 +:108EB000EC63DCE9A9A1A591EE23EDCED3F4F1A8F2 +:108EC000D030E4C31D5264BDFDF6E2593BE6F6A383 +:108ED000D7629E6A78DE44AF7D7FCD3CD5DF7AB81D +:108EE000FF4B8F3FEAF9AACC1A188FDFCFCC74FE64 +:108EF000FA668A2BF691A7BAC9E50EA1BFAAB62CCD +:108F00008ABEF7F875FDD56734BFFB037319F78781 +:108F10009BFCF5E6751FD1FCD797BCDE20E24B5FCA +:108F20007E7ABDFDBBC991FD64C9F3F5FBF3DAFDA3 +:108F30001F0FD7FB54C9CD22D9057A7EA2F93DD89F +:108F400041EDB80EBD5C569F417EB65689E32DE5D6 +:108F5000740CE9C96775A2FE477A5433D5C75670B9 +:108F60007D50D7B3642D4E60A627A08FD3441F2514 +:108F70003CEED0A3276AF4B108E803E87228E37452 +:108F80006CD1F230873A784AF7D7D5A37ADB4D1EF9 +:108F900047A4BCD3CBDA4DF5931C643739C7BF8ADD +:108FA0007A556715BFBFD6E1EA7261DE8AFF6D911F +:108FB000BE67DB577FDD7E12E71BEDA76525DCCEA4 +:108FC0005956A2DB4F21C9E742BF30D84FE487F59D +:108FD000D9F307F6B6A3305F14CF09EC4C47FE3740 +:108FE000C11F4C7EA263985700EB3C32E23CF93F34 +:108FF000065771FFC7E02AEEFF4841FF471AFA37CC +:10900000B8BD56EBE6FE0CDD7EABD3F2BC747FC878 +:10901000551A1E8CB157727F88664FD51EEF22FB02 +:10902000C9A97DCF06E3758847B66A21802E4226FE +:109030005ECA453DD83E983E6FCA58B5D10F62CE44 +:1090400043769AFC1DE6BC816BF3353B4AF37F3CCB +:109050002228F74D83799EDD91FB3AA2ED7FEE5AEF +:109060001983FE8F9F06EAE76AFE8F87F0BEC5A1CF +:1090700077B9FFA3EE10F74BFB5081B92E12FEF526 +:109080008AFB90FF6365BE9FFC1FBA3F6999533B03 +:109090007727DF2FC297BEE7E9E165F4432804CFC5 +:1090A0004F7E8971C2BA6B782EB89D6511FCF4FBB6 +:1090B000AD3AFC772619E1ADFB9FC6D803AFE1FAC4 +:1090C0003B92AD6C23CA51F1138AD7889A1FFA9B41 +:1090D000F22BDD9C6FF42B8D7F68C276FC0EEFC403 +:1090E000878B4EE273F2EE750937C373EAFEED45E6 +:1090F000F864AF7238FE751EE75B98311DCEB796E7 +:10910000E729C44F7BE0CAFD4A3A3EF6F8E378BC53 +:10911000BBB482913FAE54ADA43B8C98E78DF8A3CD +:10912000C3A7D5849FB5C3783965666510EDDE0C9D +:1091300080A72AF7C6D7D6E36D6B89EFADB6297E37 +:1091400082DFA51AF4D3D9357BDF8C8F197EE3FD3E +:10915000E1CBE1638D096ECFEC98701FC2EBB95D76 +:1091600045AFE3F3F9C0BA1884D7C17DDBE7F60158 +:10917000B764431E3FC26D526F7C3C5EE06BCE878E +:10918000F7D3DD012BF1DB0A8CD961DEDBDA286352 +:109190005C45E7933F8AFA5A7C72F379BAD7585BF9 +:1091A0007D81FC4A7555FCBB101D2EB571E4C42BA6 +:1091B000E793D7CEE3F7D8753E99A2F99952E41018 +:1091C000D1E332A047CCFF5C56CDE30A78CC310026 +:1091D0000F31890563C87FE0207ADA89F9C3D7F6B1 +:1091E000E04F27B4B30F60BDE49399BF825C7C1E4F +:1091F000E1D5599D407ED93DDAF74555AB9BECC78B +:10920000D9C5DE8358AFC7A5B67BD543C487BFBEDB +:10921000BFF0487E98BFB0238E75FBD76A601F39B8 +:1092200055590CE34BA2DC2529E85FABDE2DA09C51 +:10923000583A87D349CAD04A9217BDFD6D5D396847 +:109240002F74E04DF12CC283B771DD1D557B090FE2 +:10925000AE5DCDFD241D55171222E3C1DF5C5FCF4B +:10926000CF389EF2837579B9B31B0F02AF4DF90A5F +:10927000F272FE3CA3BC4CD1E83EA5FAF443E89759 +:1092800016353C109DDC2F8DFC13F160701FFE47DE +:109290001D0FEA1056801775B239AEC8EFE55EA80B +:1092A000DE4B7FBEA5AFF55D3E2F548BAF633C9187 +:1092B000C7D7DF453CB556F17862C7FAD964275E57 +:1092C000A81664F437EFA9BE5DC0F39B5D1210428F +:1092D000CEF0797AE5833AE60DEC891FEAF1C2E334 +:1092E00005DE687C3F1D702A291EFD7F9A1F7D6860 +:1092F00064FF1FE077FC3CD43F0FCB244F743F3A10 +:109300009374FC561370BC71B6AE6132E1B72F098D +:10931000DB771EFA2FCA0BE8F113F23CB37FD8CFEC +:10932000556AF473ED5C6ADB43DFD763A15C8A8F17 +:10933000601C01F9F6363BE533960B0AE5FFFDB5F7 +:10934000C03796F6C1BC9467EA2B76C8E40F734D1C +:109350004E42FC286D10496EF7659FF4A6B3D3C446 +:109360005F5200AF347E437044391D158774271057 +:109370007F1181BFC4A01C44BA1B1BCE5F024B8867 +:10938000BF328B3B36F58AF84C0EC2B91F3E933B79 +:10939000CFC86766CDFB07E212C17CC6ED3A6DDF30 +:1093A000A87FD2BE357AEADE77099733A287EFBB72 +:1093B0005B2FD5F88C998ECCFBFA7F90AED6F54119 +:1093C000577722BCBF025DDD7319BABA17EBC3E849 +:1093D000AA96CEFF5F8FAE5AAF84AEC6CE63C6FCF0 +:1093E00063ED3BCA63BE63E1F98BFF97F38F13E72D +:1093F00072FBDC9C7F8CF92258CE87B3A1F3D1CAD3 +:10940000F3273205EFA7D977BFB465B4C2C70BF70E +:109410007B3293BF9399FC9B66FD2E823FD4E0FF85 +:109420003CFEC4EF8E8F865F7FFCE47F915EFBC6BF +:109430002C81E28FF3477D7118F5FD82CD6BB53C31 +:10944000F7FEFD9FFF6C7F27FE84FB57CDFBDA14F0 +:1094500073BF068FAFE6EF64EE1AFA7E7867257366 +:1094600013DC2FE3FFEC94471AF285BD2F963FB82B +:1094700010FD9FC7F977F8CC7E4F3D0FB8B5643922 +:10948000E9F96754875B8CE0F75C9EA0DC46FEDC64 +:10949000DE7ECFBF221DFCA37ECF657315C243B312 +:1094A000FFB318D8D5FC7EE2BE1D719502F2BB9CBD +:1094B0001237E5DBB14BEBE8EF39882521D2034BBE +:1094C000ABB81E38A0C0E7C2715286B27107D13E58 +:1094D000A912DC16A5375F063D33767E785EC93764 +:1094E000EC2FF867F9FB5E99FBD5EEA5BF82F09EE5 +:1094F000D4CFFD7425F430E6AD3D52E3A2EF563DE6 +:10950000A2E9D11D929A84DF397F2BEE030BF2EF93 +:10951000408B85E1BD31B35EDCF7FEB8FCEACBCF12 +:1095200024A17D34B6C73EAAEDF623B91DE17EA481 +:10953000FA0D9E43E722C049D78BB7CD37DA47A54E +:1095400025DC9E2D2D51C98F549AE861387E8A936F +:10955000B5A15C1493BA24D4539655F8C8BE37C746 +:10956000E1CD78628ECB9BE3F0E638FDFFAF71F979 +:10957000F5F38DDF651CA7E5A1206FC7EFE998E340 +:10958000F09BADDC4ED9A9C23BDCCC578CCB5F75D0 +:10959000E9011EE757B9BF3499713D2D259FFB4B5B +:1095A000CD7AC723526033DADD8FD458F4EF5618E2 +:1095B000E2FA635D3C3F7ADCFC05FB293F47D70BB1 +:1095C0002B402F14482FA4EF1C9556540A1CAFAA09 +:1095D0008EE03DD36532C7ABF9F339DD5887BA4920 +:1095E0000F16AB6F67FCDE959FDE97A6F2FB60D18E +:1095F0008867D054CCE4715FF984E8C6FB095BB19D +:10960000E934BC0FCAB81F679A85FEBE438B5099D8 +:109610008CFCF80141A627E84A748FF0C93875D050 +:1096200012F2DF58C86F7F2CB72109D7D758B32D56 +:1096300009F336DB34BFF8B6DC0FE8FB0EE2582640 +:10964000A39E02CF887FCFF39E0582F67781DA92C0 +:10965000E8FB02AC99F44931D3C6F8DFCF71075764 +:10966000201E9D73929EF08010E0F76E5C0EBADFB4 +:10967000D67CB52DB91CD6D3E4B291165177F5AC92 +:109680001369F0BE69A01C8B7180BAB474D94F7194 +:10969000EA865791BE9BD2D219E6CF37964CA67B6D +:1096A000748D9780B140CFDAD123DF9A04EF370B66 +:1096B00021FA0E8F7F9A85E2F02D57CF4A0EBFE731 +:1096C00028CA3653DC93EB95A262A17B73A216CF16 +:1096D000167BC5B38DF1E9AB1670BD4861CD8BE942 +:1096E0005EA5D326E37E4BAF1E4F79AF179D36CADA +:1096F000072A9518FF8EC6D58CCE2502BF337C571E +:109700004532AD6F3306A629FFF98155A887E31DC1 +:10971000409E9F5FC3CBDDF5DF5B85F8431FDB8198 +:10972000F2D937EF5A85F9F80AE37FF7A33693E7C2 +:109730004F96BA0A89FF964AA188DFCDBDDC7A141C +:109740001650B5F1D8FFE6789BAFB62DC67B44978F +:109750001BAFE75C02C4BFBFEAB87A3BF3B8E67E52 +:10976000FF5BEDFBDAA76581FEBD43467910A41AC5 +:109770006AF7C3503FB66AFCB0367B7220A8603EE1 +:10978000AF9FD3459C2562BE6CDFF411363E4FCEB1 +:10979000257E4BE3E3B75CAAF2826913F9FBC2A40E +:1097A0001EBAE9CEBFD0C683AA97514E6CD2F90536 +:1097B000560DEA19F7372513280F16EC0B25C11D96 +:1097C00081FEB43C0D6A9F46F7647F8B79E26C346E +:1097D000233EA2B7B76AF39AF336B66BF37ED5BCD5 +:1097E0008D73B88789246BC80EACFB6D33E52F31C0 +:1097F000FCB813FA67B364BA5F769F10A07B91FE42 +:10980000951CBEFA3944B1EE1FB27BF47C9848F93E +:109810003268BF25E9ADC3CF219DCE7204EAED9B2E +:10982000478DA3BF136965CD8F3F01CF1D0736FE5E +:1098300011F33EA2478CBB7FEA44BCC76E71E3F2D2 +:109840009CFFB6E36FA80A378C5DD98CC3ACD822D5 +:10985000A8E8D7B7CBCE3D681F318740768375FB2C +:1098600060E20B49E5C6736F15D45FE377F4FC5BE8 +:1098700005E2A3516EA35D611B6A6CBF4EA33BB3AF +:109880007DF2801039EEFDCC022E67AC686F84E962 +:109890000DDB2485BE0BBB6DB388914CB66DBD9DB1 +:1098A000F8D9CB6F15AEC2EF76DF592F11DC5B6FA5 +:1098B000B0D1DF8B6A75C98B16635993677A9CF9AF +:1098C000816B4606C2FFAED0D39A9C6DBEC146F2F4 +:1098D0008059BB92D02F6BBE6FDDCBBE32E1DDE590 +:1098E000F02C7741BC86DF01922BDD76FD280BBF83 +:1098F000573CCAF22F71AF786E373D7CB3F78AE7D9 +:10990000A2613EB027DFCFDA2BBF2795FC7BF5B3F2 +:109910006DF4FDB5AF6AEF6E5BBF8AE485FF76E656 +:10992000CE70F7CE0BF3BE3882F0476C14C90F2708 +:109930009AECD9FDF3A56EFEE308E3937A5ED07648 +:10994000ED9EEE766F03E5CFD479F83DDDA8E655C0 +:1099500064276F033D0CF3AA74BBF8CCD4F4C9029E +:10996000E5FDA87EFC4EC6996C2D2F48367E4789B2 +:1099700069F97DFA7CDBA6A6D37C756887F7830737 +:10998000568F766FD7345E37BF467B3BECEF6982EC +:10999000BD7D6E01C0FF7EA71B9D7050FF12D5B329 +:1099A00089F15774AFB2137F85761945EAC7384EEF +:1099B0005EC6243FDA7967D80086F038E772CF4276 +:1099C000B5BB43723BC2FFFE416DB3A47D8F02E67F +:1099D0001D4BF96D4B0B11EF4748C43FC4C42C7AA3 +:1099E0005FEEF25A2DB02EC19B6E884FE6B116EB9A +:1099F0005AB2AB023329FE5DCE648CB794B99A2972 +:109A0000CE928B0B8489672B33C8CEF31CE6DF59CB +:109A10009C1EF7FD449443FF0700378FAE00800083 +:109A2000000000001F8B080000000000000BAD3B91 +:109A30006B705BD599DFD5BDBA926C49BEB2652318 +:109A40001313AEED189CC43137217165089BEB47A9 +:109A5000880D29556CC749769C548140C3B4D36A9C +:109A60005BBA4D76682DC772E2386014D3D661CBED +:109A7000B622C0B6BB74C0A52FC8D08E1CB29467E6 +:109A8000715BDAC2B643454ABDA5D31FEE23E0EEB3 +:109A90006427FB7DDFB93796642571D28881C3B90D +:109AA000E79CEF9CF3BD1FC78DC78E54451B00205C +:109AB0006EFEB4BE092000E2B7DC3515695B0D30DF +:109AC000F89A6CECE32FDA643408A084641831004F +:109AD000A4A7D686325EEC7BA77F0D7E809B6600B6 +:109AE000DADD62ED19FC77DDAC1BDAEBE7FA2D0865 +:109AF00039BBDFE6AECC99BF5EABCE1997C134D28D +:109B000012C086D0D29C79BE35AB353A6FA7BE3233 +:109B1000E7FBADF5CD39EBA15D3999C1FE5AFCE704 +:109B20004C0DC1137D1EAF06F036603F6BBD025970 +:109B30007D1CAF8BF882D3C5D8F9107CE88C0CB0B3 +:109B4000118CAD10A45187F138E2A5E2983B53EC9B +:109B5000C0AE69EAC10AC4070DE9007D115CBC060C +:109B6000FBDE6907E0BC8711865C09D0A8651C9FF5 +:109B7000263C6B13127F0798184164871493E741C2 +:109B800008B404CE5B047149C3BE2F0449EA5F05E3 +:109B9000499E8FBFE483CD004BDC62BDBF0B8C07B9 +:109BA00070BCB8212E49D82FED004346785E634A39 +:109BB000A2736AB85E5E09500969EE5775C0D42079 +:109BC000C337F7D1FACA3DA00D5512D8388FA7FA7E +:109BD000204EE779040C70C9848F08402D800A312B +:109BE0006EAF06BD1491088F82B18AFA759021A4D8 +:109BF00022555312F5AF80098DFA006988ACC02652 +:109C0000A304A6DD3C05CEACC37FE957A0A59DA665 +:109C10006DBAE0E4AFDC667647107FBDDBD69444D6 +:109C2000BDE75EA7EC797EA2FDFAB9FE6804915FFC +:109C30004EDF37003450FB028F3F1589EC88E0F788 +:109C40004684EF5E75F1F86F54053E131218719C4F +:109C50009F78F696D04E1C8F3FEB36EA80F08BF85B +:109C600024BE08BB675E6A16EB891E41A407E1BBF0 +:109C7000B40124C2C1554407FCAE221D0E321D930F +:109C80000C77710C8C016B5FEA57221D882E29D04E +:109C90008A08AF72ECE2E8C03F8473C533EE4746F2 +:109CA00024C22ED2A5F6B2D0653FE1F162E9924F0F +:109CB0000FB8B70CA0F97CFBC6998E5F91D21EA994 +:109CC00096C882F4C1FB48481FC26708043D54008F +:109CD00083F05408FFD4F7AC067D1FF7C57CA2675C +:109CE000BC798EFF4B90FF455FC85700E920FA8290 +:109CF0004E419217EC872213BCBE741744EEAF247A +:109D00007A988C3C2744B975C18C446D8D6430BD04 +:109D10006AE58883FAC5525A20192949FAC00F1AF0 +:109D2000D3E74A88711B74CE4C9EC17D125E472AD0 +:109D30005E4DEDD32DB4CFE046D43028B70DBEB183 +:109D400016E6CBBB41AB43BE5BAC9AEE6AE29765CD +:109D50008A11D7B3F1B58FE1836E1E29A671870FE3 +:109D60004656CFED9B701AA124D2EB75DFF4F12893 +:109D70007E2FAA94C165CCE1F9A453DC8F60CA8B15 +:109D8000481E847C84C27896C07CFD165204DF7A1B +:109D90007723FE101F3B6800F1240D7F9FBF3FDC3F +:109DA00026F4DD8391E8EB24C7A49F187F2668A4DE +:109DB0009F3403586F3AF4F8EF64FC7E6AD8A51319 +:109DC0009F4272DC74E33E3BAD7D760EBBDE91FCC0 +:109DD00059F74CB8206DEBE71A5A1F29617E3624DB +:109DE00070372D7CDDA5F23FEC292766BB20DFB65E +:109DF0003CB5B624D370EE792AC94759F63A4127C3 +:109E00003588FCE4A5F11778FC42709C7B2673E44E +:109E1000CC86E30C45188E73CF09216F64B7909EF2 +:109E200077A1DD1A417C7FD4D454C19733FF45F626 +:109E3000FCF698DF207BCE28C2797724A5D408F2DF +:109E4000E39D1053894F25581227FAED884BC60819 +:109E50004EA939B8CBCFFE02B46B841F297DA37CF9 +:109E600066F945E0D1C2D38EF47B4EDD4778F5C16B +:109E70006FEDF19AB9F1BFF4D5BEBE4627A5EDADA1 +:109E800027FA165BF445B51D7F05CFE93C5D02233B +:109E90001A727FF1175E5B87E71BFA996CC8D5349D +:109EA0004F0513E11581B0E3C524A7B5C42F13E90D +:109EB0008F13BFED29D1E8BEF63CB0E6C5216AD2CA +:109EC0003D8B510F105C47F17DCC9FC57E55979916 +:109ED000F951E364DFC38D7C57C1A8E65FB99A4EA0 +:109EE000937C95B7BA8D815CF8D2195A8F30A1C294 +:109EF000BA87347FFF15D477F350CB196B3FD39DCE +:109F0000B55F5EDF19CAEA83188F67CF3754486799 +:109F1000E1F5ACBC5872669FDBEB5573E5256F9D90 +:109F20004D8F06A7E08F4008520378DEE1E1D2961C +:109F300062EC8F064077E1D0FE1B2A2440B96ED533 +:109F4000C43C7F15A45C12EDA38FD4B3DFE865FE9B +:109F5000F1FFDE4C7F9CF831ECD274C453E08FC625 +:109F60009489FD3B436EC3C4F1419A4FF6B50AFD97 +:109F70002C9DB7FF05F9A57758E7BD82708372F86D +:109F8000B14DC2CF927DABF7BF82F00F5C29834CFD +:109F90007BCB1B0DE2CF3B1480B252ECDFE764BFFA +:109FA0000FFD3BBE8F5A95EBF7DD79C439E717C239 +:109FB0007C3FF0AE4DB97E606C13F0BE749EB2551E +:109FC0007F3F7CE80BB2FE5CA14C39B40276D5C66B +:109FD000BFF49497F1FA8372C42BAD8388F929EC0E +:109FE000BB108FC4AFA8A8FD6B104F84439213DF42 +:109FF0009AEF7C9AE6BB4E21FFD27CD9DBFE29DCAE +:10A00000CAB908F1C4FADFC9E730F11F3A77BE3F99 +:10A01000ECCA3BA733CF7F962D3A8C107E50FEA121 +:10A02000099A083FE89FB37F00DE60413BFF5C3F39 +:10A030006A0EE4A51FF6BBB94DF76BDC1EEF0F717E +:10A040007BA25F877674AC5EE8AFE7F6C57E83BF20 +:10A05000BFDC1FE6D6C6C7B9F48DAFDCC1FEC2E1D6 +:10A060007B1D291226A5417BE95AC4C3956FC8AC54 +:10A070003EFCA07B14D4077EC48182F3AEEE505226 +:10A0800026DDC58A7FAEB0F86CB96B66D245FC5D43 +:10A0900009C63E5A08B1813B56CFC53F37CD38E699 +:10A0A000E40428DE299AB33340F14E594EBFCDBDAA +:10A0B0002867FE7AAD3667DCA6EFD79A85DC6C0898 +:10A0C0002DCF997FB8BD35FD313CAFBFD9A5119FCC +:10A0D00077EAD7E78CDF5A7F630E3C5B0E4AFB942E +:10A0E0001CFEF3E7D155DD7DFE38C8A6F38F6C3A30 +:10A0F0005B72702EFAE6F3AD8DD7D2B37815716529 +:10A1000082E24A9DEEDD20ED0C129E6DBFC4848874 +:10A110008FF480D85709637CD978F9E34B3FC59712 +:10A12000D585E2CB7735E2DF0BC6971DB9F1653EE9 +:10A130005E2F145FFE691E3E4B1784CF1D8B63AFED +:10A14000ADA178EF5599FD40B923C6F6AF6C4A36FC +:10A150003620DC72CB1FF391CCE3BC1D6B54F62F81 +:10A160000F43264476FF0109B18AFC5FD660549202 +:10A17000BE793260566CA338BFD3611CC525CFB7FA +:10A180007C39447EC7C1814742689420D8E5607D10 +:10A19000976C99DE4E72A5E8E8C749DC9AA902FEE1 +:10A1A000893DFFB3434E8E431ED8AEA6249CFF804C +:10A1B0004FEBDD4A7D6B1F4408DBDBF135D7A4C8CC +:10A1C000FF2BEFD205BF403C44F47F707B53251B2F +:10A1D0002905FB2B68BAC1767CC46798248789DF80 +:10A1E00079218E9FEE9734BF44FEEB7687F638DEFA +:10A1F00073BC63D55BBBB07FD0AB1A24F0894053EE +:10A2000025F197BC03DD1EEC8F758CBDC8725CE731 +:10A21000E07E62FB35AF93FB3C5EAE75D6509CB7DB +:10A22000BE86300DF233A7FB29AF91084C8768FD3D +:10A23000E00D62FDB9E8236B59F61C387FC1E79544 +:10A240009738D22AC2919F9BFE3F822767DB71D647 +:10A25000E3B97EC54840A52001CCAE2BFF23BE84C8 +:10A2600054B969121DC751E6094F3BB67795503C6A +:10A27000B5C399292F642F8650BFA6AFCDF237837F +:10A28000B97E423E7CFE35117EF1E7105DBDC20A0B +:10A290005DF097B8EDE6549AF006C98E1AB2CB5E1F +:10A2A000B4CB709EF8CF9B8B071B3EC3C3FFC87B0C +:10A2B0003CA6270B0F78AD34F93BBD5D12F3CD966C +:10A2C000B37C001C77D8E7523A1CBCCED60FC8C767 +:10A2D0005B27883F2CBC87D064901CDAE7885AF053 +:10A2E00076CEC103AD22EB1C6B550B9EC171F1758F +:10A2F000AA902BF885CC7EC73C3A59FE1BAFAF9E87 +:10A300001B57ACF35F7B44CDD1BF9FA1FD71DF5FD5 +:10A31000F6759F375E5E9ACA5D77B80BF8DCCB6442 +:10A32000F3F834C5B5D73A528F23A8E5D73A589EEB +:10A330004FA15F4576ED5CF06CFAB388553077A19C +:10A34000D38EFE59B08BF9FC5CEBD4D49459DD4824 +:10A35000FB426C02F96B6928F75CF6BCC367EFF54A +:10A360001928A2F3A0434EF6C8954A9BA4A75D08FE +:10A3700047C2B6FE917BB4F3DDDB0559F0119FEFC8 +:10A380004A425FC503C0F74DBC9562F98167667E9E +:10A390004BF29D585AA18FB0BC40684913F923E293 +:10A3A0005ECE3C3A8D78049CB195C24F1DB3FAF154 +:10A3B00015022E64CB29AEF7587995AF77D5F2BD4B +:10A3C00054D2334464C55C4C7CE155BE15D7901F14 +:10A3D0008ABC872180AD2BB8334EEDBAC5FA681818 +:10A3E000CF35B6D4C1766CCC177D6488F4D0526F6B +:10A3F00041F9F81EE945843F4C7CCBF113980E924D +:10A400003BC91612883A905EE3CCF9002F750544DB +:10A410003E4B4B866F473C1EB7F802EFC3EBF3E1B0 +:10A420009F980FFF31E2D784059CE0EC44382F5B06 +:10A43000720164502AACB80FF773EBC930F90BAF57 +:10A440007469425E949506DD7F2C5078BF57ACFD51 +:10A450004C474CA27957F489F5E016EB1E9066B68E +:10A460009E14F46479A2FD69BCD8C8D50FF9703D7B +:10A47000F5B9FA4AADCA9DFF96C57FF9F1D0FD52F4 +:10A48000E173FEAF75DF758B81ED11F1C5BE027C06 +:10A49000912FEF2AE53F11EE7B4407C697D03B5E34 +:10A4A00065AA95E21E6F0318ECA328937CDF7DC597 +:10A4B000B7719C3C74ABC873A88AD0DB555B110C98 +:10A4C000DAE3C80FDAE3D497EF01CD15988F878BC5 +:10A4D0008DF7C8DEC4B3D69F26FE2817F78867DD40 +:10A4E00023E9D46FA37D930765203F20B9D7B5B585 +:10A4F00090DD862EE7593DE9B6F52ED20D8C6A70B7 +:10A50000E0FA236FC89C173812DECF717122A2EADD +:10A510005235E5291E86BD38FE17D3C17EEB9E67F6 +:10A52000EEFDCDCBB8EC647B4D93E46039823B719A +:10A53000FE498C8BC96F26F9CBC9C72062DD4D73EC +:10A54000FB25DB6B78BF04EE279D47CF29118C5B81 +:10A550001BE7C33B6B8FF3F223231551BD1BEF7732 +:10A56000D86B703E52B6F3233DC105E5757448A61D +:10A57000F7905EE903C683AF730CF6523E2124E2E6 +:10A580008CE36B5C82BFF64A567C06ED60EB29FCDF +:10A590006DECD31F2A23FBF2A60BEA70BCF589579A +:10A5A00015EA8F553A9A287EBE4ECD1CBA8EC69BB0 +:10A5B0009CAC3F5A9092E91CFE48BB1C213E8F6A1E +:10A5C000B5B268D312B56DEEE21C7DBD5ECB8D3F9A +:10A5D00046678FCB25C49F1A1812E279B4C5304B59 +:10A5E00048F7189941FA3EBA5E374674F28773E32A +:10A5F00094D14E55E8D36A6177C626F587C8BF3A2D +:10A60000B0C7C3FEE7FD550E71EF2590227EE8D45A +:10A6100073E39AB1899A834B48CE924ECE977F735B +:10A6200042CCDF35B0324571A966F9ABBB2A5BD9A4 +:10A630000F852131EFD6FAE579F79FD2882F927BEB +:10A640009D40F83F5075FB30E543DF4938AF277137 +:10A65000F96EB7CE726AD36DE7D09D5C271A52614E +:10A660001B9D7F74BBCAFC3F5AFECE913B484F975F +:10A6700017319EC7B7AB95D12C7978AFDBC570C6C3 +:10A68000B70BFFA2DC01D18902E3EF750BBDF2E14C +:10A69000BB81EF43F90E1D3FE94A2CED227C5401AA +:10A6A000FC2B5D27F4EE97F8FE1D0EA8C3238E0544 +:10A6B000FBD87FCBE7B30FBAEB72CEEF0A3B72F059 +:10A6C000E87445629CE7BE1574D257ED1DD8A7F813 +:10A6D000BE4F05E23757E81EBE6729F63DD87777AB +:10A6E00024E30AF6DD4BA2D793DFFAFCDE2DC32D5F +:10A6F00041B25F0E8DF8CDD57757A49BE6AF768239 +:10A7000007C78740974274CEB804A4AF7588769087 +:10A71000BF3E16726894B7D998D8BC9BF6DF182C48 +:10A7200002A2F38E4E07EF77CA543969554E8E0652 +:10A73000E5BF2ABC6C77DF76C61EDA82F3DF467A85 +:10A74000C561EE5E8F76D7F03D3D7A6EFCEC8624D7 +:10A75000DBE1B5E6541FEDB336AC5245038E374FFF +:10A760001F217F7D7C8DCB70E1B9C69B25C6F7FB91 +:10A770006B9C293C2AFC509D9269DF1FBE8FBC5107 +:10A780005D487ECF2F37F9F347C35D6EE287FD301A +:10A79000D543F889CF8A3C54FEBC253D82FEFB118F +:10A7A0002F84E7389EB78EE2A219942B841E988DD1 +:10A7B0007C837244DBBA15D61F9FAD74C4A92E7476 +:10A7C000A053653939E08B0E57531FF99DE3A16003 +:10A7D00094F979AC32C87268EF33D6DC5B4FFCF287 +:10A7E000DA1A0FFBED7D3FFBD5DDE4B7B7CA7FFC7E +:10A7F000F653143F55A94CCF03CE48FA65E2EB4E11 +:10A80000E12F9EB8EA9F59EE86FA6E07C21BC46319 +:10A810006F52DD6A687533C3B7F30D6357897CD215 +:10A8200050F0D3F15DD84F87457EC12C3F2A01EB14 +:10A830006791576AB1F4D87257ECA53A5A77B722A4 +:10A84000EAC2725582F4816B91C8BF998A3327EEB0 +:10A85000BD6926370EBE322F0ECECF33817B6A49BB +:10A8600037DAD39F775B79372BAF445760395EED8A +:10A87000E278713C2CE2A0A43356A935CC97E31FB3 +:10A880005B7EF054BF1B3900E0A7FD1AF7FDE69F81 +:10A8900006CA10D41BFD21FEFE91B58F48D9EB46A8 +:10A8A000576F76EBAC373221829BAF2FF2F9E08EF7 +:10A8B000EE22E6038CD380E83B3A038C5F5FF3AA79 +:10A8C00034F1E9A9BF02C7A1FFD03EE5859AF9EBB3 +:10A8D000D3744E17E5BFC4394FD0395D94FF12E7EA +:10A8E0007BB15FE7F6E5FE7A6E57F680C8F3DBFAD8 +:10A8F000E06AD40788B7F62AD127F9273B5C1ABC4F +:10A900003D42FCE50A291AC9B7BB2A9996B2F4C19F +:10A91000B82FF616D9E503E55EE6BFFC73057A1C91 +:10A92000D6BD62DB08EE28C225BC3FBFF77FBE5410 +:10A930004BFBBC21335F95F6F5EE66BD837AC1C350 +:10A94000FE86D087C9722FE71DC6F7D64921ECEFE6 +:10A9500018108EEE05E51EF749E1BAE3A8AFA97F0E +:10A9600000E59CEE73A0F99D8FD33EEFFFAD882AE2 +:10A970007C48EF5FB0DCBF860148D965947B5BCE35 +:10A98000BEDFFDA4157F47B63C23EECF7A70DC37DF +:10A9900095A4FB1FF8B90C85F076A9740573617E48 +:10A9A000484A99993C132C50373445DD7070E23B8E +:10A9B000DC8F6F04A8C3FE579DA69BF8E0AB038E07 +:10A9C000F3D60DBF3A70FEBA61EA8B0E706973E779 +:10A9D000580419CEB352084F75C0211AC2B6A92720 +:10A9E0007A5B0FFBCBA2AEA83753CE81FA5A11F98E +:10A9F000CF4F45CC8FF4909F1914F9AE9032912629 +:10AA0000BB1EA27AB94EEF17E25CF7D4280C5B3973 +:10AA1000FFFE83CE4C2BDF0FA750BD32BF3E2979FE +:10AA2000BF27EAFBB5A20E69D7271BD5CCD143843B +:10AA3000A76D6EC6C3E0B337BC49F52FBB8E1FB2FE +:10AA4000EAC0DA6ED006C43D3EC6E77C4ED443E190 +:10AA500006BCC74ADA2453B36905D7373F41E31729 +:10AA60003AFF42EB861B2DFD86CC9D2279FE8D851B +:10AA70004F7BDE80258FD7A9226F0D7E95F57CEB6D +:10AA8000135E90C95FF6A947494E7642663DC9D329 +:10AA90006040F86D89C34EF6DBF6F5E8BCBE5C3568 +:10AAA000F9FD42F9BF788C01049398D4FC9447AA2D +:10AAB000EB36F7F5F039923D5D748E6199F5DDDB8B +:10AAC00075EBE3C41F9D5209CBA3A2998BB3F5E5A7 +:10AAD000A33D3539F9F84EF8A242EF5CD62D9EE938 +:10AAE000E2FD7D0EA0782BE1315ED409DF3F5018E6 +:10AAF0006E27A4DAF9BEBB346918EF39E83DC9F412 +:10AB00005957E75A49FAE951CBBE267C85E3BA7F0B +:10AB1000EB11F1E7FA4DD187E9DCB7C04C1BE937FF +:10AB2000146D23CEEF5A445EE751D29722AEB9D7C7 +:10AB3000D13497D77AC9197D94D699DF14FE842B26 +:10AB400024FC7A279869C2D7AB9BCCC7888F371271 +:10AB50009FAF6645058FAF9C7F8E27AC73F4F69848 +:10AB6000FF49F08E59FAB95133B9EEDA080E633065 +:10AB7000985557D717565797B4EF897AFA8D828F21 +:10AB8000E1B9B8E0C356D0489E90FF8ED1F9ECF7FA +:10AB9000258DC7765773DDE512EBDBEF6F328F1330 +:10ABA000BC3F442227E81E6FEFDD020C6F81EF35BA +:10ABB000D62DCE8422642F3DC26F7EB2C5D81AC96D +:10ABC000CAFF9CB2F8F79445D7E5C84E53942F506E +:10ABD0000CB6E3D740D84DFA211F7EA21F26A8EE5F +:10ABE00073AEFD9D074FBA294F3C186E75D37BB4E9 +:10ABF00084B7B584FAA3556688F61FEAEF78F6DDC8 +:10AC00003AE223C1F7F166918FD88FFA39EE9A8331 +:10AC1000F3871E99CFD5168634E5D3FD5EE117F98B +:10AC2000315ED4918FFCC130DB73FC3E41A9833F80 +:10AC3000933C51BC1D32C0A478321C05920BBF3628 +:10AC4000B79E4C5E5B380374AE73C191AB70BD9719 +:10AC5000D6C718DFE59B353E872BE4988BE361E18F +:10AC6000F8DA4FF8AA3B4FDE8DF0D5706E7C9DC5AB +:10AC7000BB2577F978F26D96F9DECF07A6F95E70FD +:10AC8000BA8DF3227E547854CF2FDB2CF48CEC3524 +:10AC900021EAA37A5994EF970864C06898C32FFA01 +:10ACA0008A8C5F59CBF03A7FD880E80AC2478CF192 +:10ACB000997FFFC663DF6827BCBDB453E8D5758AAA +:10ACC000A53F627817E4CF7FB2F41B5876A9D3234F +:10ACD000ECCE46F88957E4B5059F36A23BEE2E9D93 +:10ACE000AF5FEDF6492BAF9CFFFDE79B3D220FA028 +:10ACF0004FB07E1FEC10F07D3EE1871E1D5EC5FE4D +:10AD0000C3CD957545D9FAF172D709F3EB8217AA2D +:10AD100003CEF18DC974FF8B7632BE493F377F1C5D +:10AD2000B2E46DA8DF5D50EE0E2D8E840C92AB6602 +:10AD3000330E48B7FD814C88F86768F23DF693956D +:10AD4000576583FC4D458900CDBBB93CC3F4DF108A +:10AD50003681EA4A87FACD6F65C3FDECA668F766CF +:10AD60007A27A44D9804C70BE938D9A35BCACC58FD +:10AD7000A4001D3EBA59E4FF5EDD14D9B699F40E65 +:10AD8000E9CE55E86B45CC7FA4FE42F5D57C79EA47 +:10AD90007093BDB87479EA72D3FD46AB22FC4E6B5A +:10ADA000F42732795873FEA5254FA3CDD3AC276C79 +:10ADB000B9FADCE63CBD13B4F44ED064B9F8FC66D5 +:10ADC000DDCA0347583E9C244FD97A2668EB199375 +:10ADD000E55109DAF264C91FC9137EBFCE39D346E3 +:10ADE0007ECA1088778CF9F235BE299A203A5C57D2 +:10ADF000FEE7EE6A7DEEFDA7AE0B791AADB2F8BDA7 +:10AE0000F969E6FF53C8FFF45878D05B93C3EF7637 +:10AE1000BB7656863492E2A65989DB7F982DE6767A +:10AE2000DDAC875B73B68CDB96D900B7ADB38BB85E +:10AE30006D9BADE4B67D16F9FE7AE4FFD96A6E6FBC +:10AE40009E5DCEED86D9A5DC76CC5ECFF33A675712 +:10AE5000727BCBEC8DDCDE3ADB2CF6A19A5069419B +:10AE6000FEA772D665E07F234EF5D1A1C9BBDF24D2 +:10AE7000FC383595F328894013D77B9C4A86F9FF27 +:10AE80006858D8870D5E419F7CFE7F7553F4DB8543 +:10AE9000F87FD009CF90CB95EF27A0BFF32CF1B965 +:10AEA000E47DE16F9CFF740A3F07FD8F63CCFF9741 +:10AEB00068FFCFFA9515B97EE56879AE5F39D46C35 +:10AEC000FB95AE14D5C176493ABF137B7F53F4C7C7 +:10AED0009B59FF4676D278B4C7AD913F9508DC1CEC +:10AEE000F2627FC77E1928DF87FEC514CF43FD407D +:10AEF0007663A1F29AB6DEF7DAF31BE1A4237611AA +:10AF0000FEC9DBF4BFCD85E4BEDE734976D4D92615 +:10AF1000E45E13729FA88A0C53BE259127F7B61DD5 +:10AF2000453CE4C8FDFBB6DC5B725C1A14EF3E4A9C +:10AF300049EE919EA7CFCA7DAE1D55ACF9CE0E51FC +:10AF4000DF6A0B0ABDAA74087DA168B97614F905F9 +:10AF50007A0BF8137145F04D67DD77CFDA33B2AB7A +:10AF6000A5C18054825B6B7FCDC489FD26955A961E +:10AF7000EF7C394A68AB98CF2795362824FF0B968B +:10AF8000A3806D474CB623F9F36C791A9AEC64BC34 +:10AF9000D8766512EF6D66D9930D9AC003DA93AB3C +:10AFA0007A0BC8D3BAC5663452E09C2B7A85FFFE73 +:10AFB000CA4D11E12FA29F487E4AC259D80F58D1DD +:10AFC0002BE856DA9154086FEB758895A11EECE8D2 +:10AFD00048B7510D03E579452FC2BBC9CC0C920C83 +:10AFE0000E7AC782747E94CF463AD7A5CA67D9260F +:10AFF000AB2EB7A78CFD16BBBD10DFDBFE8ECDFFE1 +:10B00000F9F39EAC36B716C2CB915EE1AF1F1D7E41 +:10B010003A873F924AED2D865E50AF9AC665D1AB16 +:10B020000BF32B26D1CEB15E3DB75FB183E8B050B4 +:10B03000BFE2CEDEB37EC52EA2D3BA06E1571CE92D +:10B0400085CBEB2FB4D8F1CAA5F90B9FEF3DBFBF5D +:10B0500030D8ABF3B8827E35E90DBFA5372ED65F69 +:10B0600028E01F1CECE5387A46A6FA1FA2DA10F990 +:10B07000105117453D733FE10DE378F6178E7A05C1 +:10B08000BF988A6D9F220FD078D214FEC2E592033A +:10B09000F4FB1EEA2D5FB83C2C745EDD636B8733D6 +:10B0A000E4E7802F49EFA607E9BD12C58FBFF689F7 +:10B0B000770400F594F7FF9CBCCC203B375EFC8501 +:10B0C000AFD1FC3D7105E8DDE083FD22FF374AF991 +:10B0D000BF6BB1EF8C7D9DC6F70FB8B4A308EF83AB +:10B0E000227FDC813CF58167718ADE051DB3E4CDEA +:10B0F00005DB4B0AF1D5DCF9C4FB5C7ABA7286FF3A +:10B10000AEA34AE33CB98D1F350271843FB2C2C180 +:10B11000F591910F7FF3C8ED74EE0FBB0DAA3F714F +:10B12000A115FB65CB429C47476F10C25979111995 +:10B130009469CAC70FD31BF5ACFA6B7023C6D159FB +:10B140007146493892D3D721CAFB1E0E3A18EEA198 +:10B150007611171DF24EB8B502FAE5BEFEDC774A4D +:10B16000F9ADBCE60D7E273856AF70DDE7FED54B56 +:10B170003A494E0E2EE14A3114D53922A902727C89 +:10B18000DA92631D740FE1D1D3D95552C8AED8ED10 +:10B1900060DE39642D6A92BE2EAA4E46888F8BEAF5 +:10B1A00082523C0B0FBFB4E08F48F1F43A7E8F26F9 +:10B1B000EC04C5BBF44E65A8FC2EAE47BA31DE9F49 +:10B1C000C6EF6EB44BBFC5B6AC428D163A2F6C11AC +:10B1D000F99011672A42741959AA709D1279AA60D0 +:10B1E000DEEBF796BD2AAA1BE3F3419DC275A7FCCF +:10B1F00079BFB2E7A949AE631CACFB779DE4EEE0F2 +:10B2000055C0F9EDFFFEE5AE270648BFF4231D9DAE +:10B21000C4AF1DDC162DFB06E37DB451D1E81EEB57 +:10B22000E5B5035C27DA0806F927F97C50BC62898A +:10B2300087F39D1D0EF6EFF2F9A20819758AFC340A +:10B2400025C376C2092FB2DE1C3544DCA463B42AC0 +:10B25000FA825FEC7A53D0E2C7FC7B8D5A72B5DF7D +:10B26000CAAB97587F8733D6F167AEF78E2E4EB3B1 +:10B270001DB9AF251DA2BAA13FE836285439D01C0C +:10B28000E1FCF6E84A07FBADF3E0AE147A39FF3C87 +:10B29000CEE3EF09FDA888FC85BF4191C8EE7CC9CB +:10B2A0003AC70653C8931616FE9BD613030D0F5FBD +:10B2B000FE869CD2711F69D9EFE34E1C4F6E136F4F +:10B2C0008B8B54912753CD9B07C8AEFDB8520629EE +:10B2D0004C82F70983F36D1121DFF6BBEC8A1E3532 +:10B2E00027BE2F81AC3EBF53C9ED83DC77DEF76606 +:10B2F0007B7E7DF7EB27B2E0B56EC9ADB35D68FD2F +:10B3000007FDBB5F3F817C32669C5FAE6CFA24FB1D +:10B31000C342FF59FC65F31B8580F428F85CEB1FE2 +:10B320000C440BFA25FBB6083D79217DA4B9A23166 +:10B330005A7FF8A65C387759F2769705C7B558ABAF +:10B34000E479D63BA7C31ED8FA74817B8D6C517902 +:10B35000FE1C3FDB7EC08B9796875BD123E2876024 +:10B360008D87EC30E2F345D21F7F0DAA7A367F0E2F +:10B37000F972FD50DB0FF8E9162B0F575E21D1FA59 +:10B38000806EDBF1DC3C41BE1D2F72A6382F5DB410 +:10B3900054B5F50CEB830F7AEF79224EF2933EC849 +:10B3A000FE9E8AFC4BF5BC32328805E804A1DCBF66 +:10B3B00013D9B205183F65FAC4542BDEA32CA27032 +:10B3C0003D4449829126781B8BF8EF3FE877BA8994 +:10B3D000EC1C70509B6CFB24A471FE03B58AC1EF7A +:10B3E00008C1D9FC2ED9DD2A3FD7516DB9B810BD9F +:10B3F000ED73D17BB1DC77F017270F8F6DB1DE6570 +:10B400007BC023E461A36388F31D8E14BF85477955 +:10B41000579AAC9202D5FB4908703C48EF8224ABA6 +:10B420008E543B272770ABF56E73B7783FC37F5FB1 +:10B43000584B7F0F9AE1BF1BBC9A5EB7CA82AE24FD +:10B4400027A7A0CA4175E2F871493AEB1F2DA2A7C0 +:10B450008E8683D62D8108B7F9E7BE0662FCBD1E35 +:10B4600092DC2E83096E1B608ADB4698E196D41528 +:10B470009DC73821EA1DABC090E9FB6A8870DB04E8 +:10B48000316EC390E4F6CB6D9FFCD64EA4C38FE61D +:10B49000E145E0B5805CA711E8D9FBDB78FEC21678 +:10B4A0007D41723B14107993B6709AFD7AAF1EE11C +:10B4B000B8CF19147C6DC3719E234FFCF7FA4FF976 +:10B4C0007F5FF2FF519E9355203F00000000000077 +:10B4D0000000000000000000000000180000000054 +:10B4E000000000000000004000000000000000001C +:10B4F0000000002800000000000000000000001014 +:10B50000000000000000000000000020000000001B +:10B51000000000000000001000000000000000001B +:10B520000000000800000000000000000000000013 +:10B5300000000000000000000000003900000000D2 +:10B5400000000000000000380000000000000000C3 +:10B5500000000000000000000000000000000008E3 +:10B5600000000000000000000000000000000000DB +:10B57000000000000000000C0000000000000000BF +:10B580000000000E000000000000000000000004A9 +:10B590000000000000000000000000180000000093 +:10B5A000000000000000001C00000000000000007F +:10B5B0000000001C0000000000000000000000135C +:10B5C00000000000000000000000003A0000000041 +:10B5D000000000000000000100000000000000006A +:10B5E0000000000200000000000000000000000158 +:10B5F000000000000000000000000010000000003B +:10B6000000000000000000500000000000000000EA +:10B610000000000000000000000000000000000327 +:10B620000000000000000000000000AB000000006F +:10B630000000000000000008000000000000000002 +:10B640000000C00000100000000000080000C0085A +:10B6500000100000000000020000C0000010000008 +:10B660000000001000009FB0000000000000000873 +:10B670000000C08000100000000000040000C0882E +:10B6800000100000000000020000C0800010000058 +:10B6900000000010000091200000000000000008E1 +:10B6A00000009340000100040000000100009348E6 +:10B6B00000000000000000020000935000000000A5 +:10B6C0000000000800009354000000000000000289 +:10B6D00000009418000000000000000800009358CB +:10B6E000000800000000000800009AB000400000C0 +:10B6F00000000040000093980008000000000008CF +:10B70000000093D80008000000000008000094200A +:10B7100000C8000000000098000095B000980000EC +:10B7200000000028000095F00098000000000028AC +:10B730000000C480054000300000054000009D204E +:10B74000000800000000000100009D21000800002A +:10B7500000000001000020080010000000000010A0 +:10B7600000002000000000000000000800009CD83D +:10B77000000800000000000200009D18000000000A +:10B7800000000001000000010000000000000000B7 +:10B79000000000090000000000000000000000029E +:10B7A00000000000000000000000CF2000000000AA +:10B7B000000000200000CF46000000000000000153 +:10B7C0000000600000200000000000200000730066 +:10B7D000000800000000000800009FA0000000001A +:10B7E0000000000100009FA8000000000000000110 +:10B7F00000009F60000000000000001000009F6338 +:10B80000000000000000000100009F610000000037 +:10B810000000000100009F66000000000000000121 +:10B8200000009F67000000000000000000009F680B +:10B83000000000000000000400009F6C00000000F9 +:10B8400000000004000000520000000000000000A2 +:10B8500000000003000000000000000000000003E2 +:10B8600000000000000000000000000500000000D3 +:10B8700000000000000000020000000000000000C6 +:10B8800000060000000000000000002000009F7083 +:10B89000000000000000000100009F900000000078 +:10B8A000000000080000005300000000000000003D +:10B8B00000009F98000000000000000200009F9C14 +:10B8C000000000000000000100009F9D000000003B +:10B8D000000000010000000900000000000000005E +:10B8E0000000000100000000000000000000004413 +:10B8F0000000000000000000000000010000000047 +:10B9000000000000000000500000000000000000E7 +:10B91000000000890000000000000000000012C8C4 +:10B920000080000000000080000000010000000016 +:10B93000000000000000A000071000000000071039 +:10B9400000001AC800000000000000080000AEC09F +:10B9500000080000000000080000AE4000080000E1 +:10B96000000000080000AE80000800000000000891 +:10B97000000020080010000000000010000020005F +:10B9800000000000000000080000A01007100040A8 +:10B990000000004000001BF800080000000000014B +:10B9A00000001BF9000800000000000100001AD090 +:10B9B000000000000000000100001AD80000000094 +:10B9C0000000000200001ADA00000000000000027F +:10B9D0000000000000000000000000000000AF00B8 +:10B9E000000000000000002000001B78002800007C +:10B9F000000000040000E000002000000000002023 +:10BA00000000F300000800000000000800001AF029 +:10BA1000000000000000010800001B3700000000CB +:10BA20000000000100001B0F0000000000000001EA +:10BA300000001B70000000000000000400001B74E8 +:10BA400000000000000000040000005000000000A2 +:10BA500000000000000000030000000000000000E3 +:10BA600000000005000000000000000000000006CB +:10BA700000000000000000000000000700000000BF +:10BA80000000000000001BC80000000000000001D2 +:10BA900000001BE80000000000000008000000514A +:10BAA000000000000000000000001BD000000000AB +:10BAB0000000000400001BD400000000000000048F +:10BAC00000001BD8000000000000000400001BDC88 +:10BAD00000000000000000080000B0000018000096 +:10BAE000000000180000C0000040000000000040FE +:10BAF0000000C00000400002000000010000C00182 +:10BB000000400002000000000000E20000200000F1 +:10BB1000000000200000E2040002000800200002F3 +:10BB20000000000000000000000000000000E20033 +:10BB300000080020000000040000F40000280000BD +:10BB4000000000280000F540001000000000001078 +:10BB50000000F5C000200000000000200000F5C03B +:10BB600000020020000000020000F300002000009E +:10BB7000000000200000200800100000000000105D +:10BB80000000200000000000000000080000110874 +:10BB90000008000000000008000011680008000014 +:10BBA00000000008000011A80008000000000008C4 +:10BBB00000001240000800000000000100001241D7 +:10BBC0000008000000000001000040000020000408 +:10BBD00000000010000059000030001800000010A4 +:10BBE0000000590800300018000000020000570053 +:10BBF00000080000000000010000570100080000DC +:10BC000000000001000011E8000000000000000139 +:10BC1000000011F00000000000000001000011F819 +:10BC200000000000000000100000124400080000A6 +:10BC30000000000400004000002000000000002080 +:10BC40000000530000100000000000100000153834 +:10BC500000000000000000010000000300000000E0 +:10BC600000000000000000000000000000000000D4 +:10BC700000000001000000000000000000000004BF +:10BC80000000000000000000000015080000000097 +:10BC9000000000010000152800000000000000085E +:10BCA00000000050000000000000000000008308B9 +:10BCB0000080000000000080000000010000000083 +:10BCC000000000000000200800100000000000102C +:10BCD00000002000000000000000000800008410A8 +:10BCE0000008000000000008000084700008000048 +:10BCF0000000000800060000046000280000046046 +:10BD000000008520000800000000000100008521DF +:10BD1000000800000000000100000000000000001A +:10BD20000000000000008408000000000000000186 +:10BD3000000084F40008000000000002000084F607 +:10BD40000008000000000002000085040010000050 +:10BD500000000004000087600000000000000020D8 +:10BD600000006000002000000000002000007300C0 +:10BD700000080000000000080000000300000000B0 +:10BD800000000000000000050000000000000000AE +:10BD90000000000600000000000000000000000796 +:10BDA0000000000000000000000088080000000003 +:10BDB00000000001000088280000000000000008CA +:10BDC000000000500000000000000000000088108B +:10BDD00000000000000000040000881400000000C3 +:10BDE00000000004000088180000000000000004AB +:10BDF0000000881C00000000000000080000300067 +:10BE00000040000000000008000030080040000072 +:10BE1000000000280000339001C00010000000085E +:10BE20000000320000200000000000200000372049 +:10BE3000000000000000000800001020062000386C +:10BE4000000000080000A00000000000000020002A +:10BE500000003EA9000000000000000100003EC8F4 +:10BE600000000000000000020000000000000000D0 +:10BE7000000000000000600000200000000000083A +:10BE80000000400000080000000000010000400128 +:10BE9000000800000000000100004040000800040D +:10BEA00000000002000040600008000400000004E0 +:10BEB00000004000000800000000000400004004F2 +:10BEC00000080000000000040000404000000000E6 +:10BED00000000008000040480000000000000008CA +:10BEE0000000800000000000000000100000504032 +:10BEF00000010004000000010000500000000000EC +:10BF000000000020000050080010000000000004A5 +:10BF10000000500C0010000000000001000052C79B +:10BF20000000000000000001000052C600000000F8 +:10BF30000000000100003000003000180000000484 +:10BF40000000300400300018000000040000300839 +:10BF500000300018000000020000300A0030001815 +:10BF6000000000020000300C00300018000000014A +:10BF70000000300D00300018000000010000300EFD +:10BF800000300018000000010000301000300018E0 +:10BF9000000000040000301400300018000000040D +:10BFA0000000500001000080000800040000500460 +:10BFB00001000080000800040000000A00000000EA +:10BFC0000000000000005068010000800000000137 +:10BFD0000000506901000080000000010000506C6A +:10BFE00001000080000000020000506E010000808F +:10BFF00000000002000050700100008000000004FA +:10C000000000507401000080000000040000506631 +:10C010000100008000000002000050640100008068 +:10C0200000000001000050600100008000000002DC +:10C03000000050620100008000000002000050502B +:10C040000100008000000004000050540100008046 +:10C0500000000004000050580100008000000004AF +:10C060000000505C01000080000000040000507CD3 +:10C0700001000080000000010000507D01000080F0 +:10C080000000000100004018001000000000000443 +:10C0900000004090001000000000000400004098E4 +:10C0A000001000000000000400004110000000002B +:10C0B0000000000200004112000000000000000229 +:10C0C00000004114000000000000000200004116C2 +:10C0D00000000000000000020000604000080000B6 +:10C0E00000000002000060420008000000000002A2 +:10C0F00000006044000800000000000400006080B0 +:10C100000008000000000008000060C000400008B7 +:10C1100000000008000060000008000000000002AD +:10C120000000600200080000000000010000600440 +:10C13000000800000000000200006340000800004A +:10C1400000000008000063800008000000000004F8 +:10C15000000063840008000000000001000063C0CC +:10C160000008000000000002000063C40008000096 +:10C17000000000020000640000080000000000044D +:10C1800000007000001000000000000400007004B7 +:10C190000010000000000004000070080010000003 +:10C1A00000000004000090000008000000000002F1 +:10C1B0000000900200080000000000010000900450 +:10C1C000000800000000000200009040000800008D +:10C1D000000000020000904400080000000000027F +:10C1E0000000904600080000000000020000964891 +:10C1F0000008000000000008000090800008000017 +:10C20000000000020000908400080000000000020E +:10C210000000968800080000000000080000804030 +:10C22000000800000000000100008041000800003C +:10C230000000000100008042000800000000000132 +:10C2400000008043000800000000000100008000A2 +:10C25000000800000000000200008002000800004A +:10C26000000000010000800400080000000000023F +:10C27000000080C00008000000000002000080C232 +:10C280000008000000000002000080C40008000058 +:10C290000000000200008080000800000000000193 +:10C2A0000000808100080000000000010000808282 +:10C2B000000800000000000100008083000800006A +:10C2C0000000000100008084000800000000000160 +:10C2D000000080850008000000000001000080864A +:10C2E00000080000000000010000600000080000DD +:10C2F00000000002000060020008000000000001D1 +:10C30000000060040008000000000002000060421D +:10C3100000C00018000000020000604000C00018CB +:10C32000000000020000604C00C00018000000087F +:10C330000000604400C000180000000800006057C2 +:10C3400000C00018000000010000605400C0001888 +:10C35000000000020000605600C00018000000014C +:10C360000000664000080000000000080000668031 +:10C370000008000000000008000066C0000800007F +:10C38000000000080000DA4200180000000000026F +:10C390000000DE4000000000000000000000E0009F +:10C3A00000000000000000040000D0C000000000F9 +:10C3B000000000040000D0C40000000000000004E1 +:10C3C0000000D0C800000000000000040000D0CC35 +:10C3D00000000000000000040000D0D000000000B9 +:10C3E000000000040000D0D40000000000000004A1 +:10C3F0000000D0D800000000000000040000D0C001 +:10C4000000000000000000200000DB000000000031 +:10C41000000000040000DB000000000000000068D5 +:10C420000000B94800000000000000000000D0003B +:10C4300000000000000000040000B0C00000000088 +:10C44000000000040000B0C4000000000000000470 +:10C450000000B0C800000000000000040000B0C0F0 +:10C4600000000000000000100000D6B00000000036 +:10C47000000000040000D6B400000000000000042A +:10C480000000D6B800000000000000040000D6BC88 +:10C4900000000000000000040000D6B00000000012 +:10C4A000000000100000D348000000000000000859 +:10C4B0000000D358000000000000008000000010C1 +:10C4C00000000000000000000000D3580000000041 +:10C4D000000000080000000006002200000000002C +:00000001FF diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 4e8ea8c8ec1e7f6fc04ebf992294b63cb23b1bbb..831c4634162c6eb8db5dd72fe830a57c3c9a95fb 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -301,6 +301,7 @@ header-y += quota.h header-y += radeonfb.h header-y += random.h header-y += raw.h +header-y += rds.h header-y += reboot.h header-y += reiserfs_fs.h header-y += reiserfs_xattr.h diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index f6481daf6e52b2cc6387952120bdcd05bc26f051..a8e4e832cdbb094d8a99ad9d831db3d14cbdbe23 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -449,7 +449,7 @@ void vcc_insert_socket(struct sock *sk); static inline int atm_guess_pdu2truesize(int size) { - return (SKB_DATA_ALIGN(size) + sizeof(struct skb_shared_info)); + return SKB_DATA_ALIGN(size) + sizeof(struct skb_shared_info); } diff --git a/include/linux/can/platform/mcp251x.h b/include/linux/can/platform/mcp251x.h index dba28268e651931d8b3094438158d15c10d3ca2c..8e20540043f55dfffc4b2096ceee6ca817e994df 100644 --- a/include/linux/can/platform/mcp251x.h +++ b/include/linux/can/platform/mcp251x.h @@ -12,7 +12,6 @@ /** * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data * @oscillator_frequency: - oscillator frequency in Hz - * @model: - actual type of chip * @board_specific_setup: - called before probing the chip (power,reset) * @transceiver_enable: - called to power on/off the transceiver * @power_enable: - called to power on/off the mcp *and* the @@ -25,9 +24,6 @@ struct mcp251x_platform_data { unsigned long oscillator_frequency; - int model; -#define CAN_MCP251X_MCP2510 0x2510 -#define CAN_MCP251X_MCP2515 0x2515 int (*board_specific_setup)(struct spi_device *spi); int (*transceiver_enable)(int enable); int (*power_enable) (int enable); diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 7434a8353e2301dcb548ad94965ef0e73390335f..7187bd8a75f62c23b13ac73f4416488a0e42a0c7 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -165,8 +165,10 @@ enum { DCCPO_TIMESTAMP_ECHO = 42, DCCPO_ELAPSED_TIME = 43, DCCPO_MAX = 45, - DCCPO_MIN_CCID_SPECIFIC = 128, - DCCPO_MAX_CCID_SPECIFIC = 255, + DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */ + DCCPO_MAX_RX_CCID_SPECIFIC = 191, + DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */ + DCCPO_MAX_TX_CCID_SPECIFIC = 255, }; /* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */ #define DCCP_SINGLE_OPT_MAXLEN 253 diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 2308fbb4523a399abce0809860f6f398c8844ed5..f16a01081e150035438dfc886d15943a79085a00 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -71,7 +71,7 @@ static inline int is_zero_ether_addr(const u8 *addr) */ static inline int is_multicast_ether_addr(const u8 *addr) { - return (0x01 & addr[0]); + return 0x01 & addr[0]; } /** @@ -82,7 +82,7 @@ static inline int is_multicast_ether_addr(const u8 *addr) */ static inline int is_local_ether_addr(const u8 *addr) { - return (0x02 & addr[0]); + return 0x02 & addr[0]; } /** @@ -237,13 +237,29 @@ static inline bool is_etherdev_addr(const struct net_device *dev, * entry points. */ -static inline int compare_ether_header(const void *a, const void *b) +static inline unsigned long compare_ether_header(const void *a, const void *b) { +#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 + unsigned long fold; + + /* + * We want to compare 14 bytes: + * [a0 ... a13] ^ [b0 ... b13] + * Use two long XOR, ORed together, with an overlap of two bytes. + * [a0 a1 a2 a3 a4 a5 a6 a7 ] ^ [b0 b1 b2 b3 b4 b5 b6 b7 ] | + * [a6 a7 a8 a9 a10 a11 a12 a13] ^ [b6 b7 b8 b9 b10 b11 b12 b13] + * This means the [a6 a7] ^ [b6 b7] part is done two times. + */ + fold = *(unsigned long *)a ^ *(unsigned long *)b; + fold |= *(unsigned long *)(a + 6) ^ *(unsigned long *)(b + 6); + return fold; +#else u32 *a32 = (u32 *)((u8 *)a + 2); u32 *b32 = (u32 *)((u8 *)b + 2); return (*(u16 *)a ^ *(u16 *)b) | (a32[0] ^ b32[0]) | (a32[1] ^ b32[1]) | (a32[2] ^ b32[2]); +#endif } #endif /* _LINUX_ETHERDEVICE_H */ diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 991269e5b152f1179aefb68e947111104d25bce0..6628a507fd3b5dff0184048ec56d3e57257343ad 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -14,6 +14,7 @@ #define _LINUX_ETHTOOL_H #include +#include /* This should work for both 32 and 64 bit userland. */ struct ethtool_cmd { @@ -308,15 +309,28 @@ struct ethtool_perm_addr { * flag differs from the read-only value. */ enum ethtool_flags { + ETH_FLAG_TXVLAN = (1 << 7), /* TX VLAN offload enabled */ + ETH_FLAG_RXVLAN = (1 << 8), /* RX VLAN offload enabled */ ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ ETH_FLAG_NTUPLE = (1 << 27), /* N-tuple filters enabled */ ETH_FLAG_RXHASH = (1 << 28), }; /* The following structures are for supporting RX network flow - * classification configuration. Note, all multibyte fields, e.g., - * ip4src, ip4dst, psrc, pdst, spi, etc. are expected to be in network - * byte order. + * classification and RX n-tuple configuration. Note, all multibyte + * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to + * be in network byte order. + */ + +/** + * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc. + * @ip4src: Source host + * @ip4dst: Destination host + * @psrc: Source port + * @pdst: Destination port + * @tos: Type-of-service + * + * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow. */ struct ethtool_tcpip4_spec { __be32 ip4src; @@ -326,6 +340,15 @@ struct ethtool_tcpip4_spec { __u8 tos; }; +/** + * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4 + * @ip4src: Source host + * @ip4dst: Destination host + * @spi: Security parameters index + * @tos: Type-of-service + * + * This can be used to specify an IPsec transport or tunnel over IPv4. + */ struct ethtool_ah_espip4_spec { __be32 ip4src; __be32 ip4dst; @@ -333,21 +356,17 @@ struct ethtool_ah_espip4_spec { __u8 tos; }; -struct ethtool_rawip4_spec { - __be32 ip4src; - __be32 ip4dst; - __u8 hdata[64]; -}; - -struct ethtool_ether_spec { - __be16 ether_type; - __u8 frame_size; - __u8 eframe[16]; -}; - #define ETH_RX_NFC_IP4 1 -#define ETH_RX_NFC_IP6 2 +/** + * struct ethtool_usrip4_spec - general flow specification for IPv4 + * @ip4src: Source host + * @ip4dst: Destination host + * @l4_4_bytes: First 4 bytes of transport (layer 4) header + * @tos: Type-of-service + * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0 + * @proto: Transport protocol number; mask must be 0 + */ struct ethtool_usrip4_spec { __be32 ip4src; __be32 ip4dst; @@ -357,6 +376,15 @@ struct ethtool_usrip4_spec { __u8 proto; }; +/** + * struct ethtool_rx_flow_spec - specification for RX flow filter + * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW + * @h_u: Flow fields to match (dependent on @flow_type) + * @m_u: Masks for flow field bits to be ignored + * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC + * if packets should be discarded + * @location: Index of filter in hardware table + */ struct ethtool_rx_flow_spec { __u32 flow_type; union { @@ -365,36 +393,91 @@ struct ethtool_rx_flow_spec { struct ethtool_tcpip4_spec sctp_ip4_spec; struct ethtool_ah_espip4_spec ah_ip4_spec; struct ethtool_ah_espip4_spec esp_ip4_spec; - struct ethtool_rawip4_spec raw_ip4_spec; - struct ethtool_ether_spec ether_spec; struct ethtool_usrip4_spec usr_ip4_spec; - __u8 hdata[64]; - } h_u, m_u; /* entry, mask */ + struct ethhdr ether_spec; + __u8 hdata[72]; + } h_u, m_u; __u64 ring_cookie; __u32 location; }; +/** + * struct ethtool_rxnfc - command to get or set RX flow classification rules + * @cmd: Specific command number - %ETHTOOL_GRXFH, %ETHTOOL_SRXFH, + * %ETHTOOL_GRXRINGS, %ETHTOOL_GRXCLSRLCNT, %ETHTOOL_GRXCLSRULE, + * %ETHTOOL_GRXCLSRLALL, %ETHTOOL_SRXCLSRLDEL or %ETHTOOL_SRXCLSRLINS + * @flow_type: Type of flow to be affected, e.g. %TCP_V4_FLOW + * @data: Command-dependent value + * @fs: Flow filter specification + * @rule_cnt: Number of rules to be affected + * @rule_locs: Array of valid rule indices + * + * For %ETHTOOL_GRXFH and %ETHTOOL_SRXFH, @data is a bitmask indicating + * the fields included in the flow hash, e.g. %RXH_IP_SRC. The following + * structure fields must not be used. + * + * For %ETHTOOL_GRXRINGS, @data is set to the number of RX rings/queues + * on return. + * + * For %ETHTOOL_GRXCLSRLCNT, @rule_cnt is set to the number of defined + * rules on return. + * + * For %ETHTOOL_GRXCLSRULE, @fs.@location specifies the index of an + * existing filter rule on entry and @fs contains the rule on return. + * + * For %ETHTOOL_GRXCLSRLALL, @rule_cnt specifies the array size of the + * user buffer for @rule_locs on entry. On return, @data is the size + * of the filter table and @rule_locs contains the indices of the + * defined rules. + * + * For %ETHTOOL_SRXCLSRLINS, @fs specifies the filter rule to add or + * update. @fs.@location specifies the index to use and must not be + * ignored. + * + * For %ETHTOOL_SRXCLSRLDEL, @fs.@location specifies the index of an + * existing filter rule on entry. + * + * Implementation of indexed classification rules generally requires a + * TCAM. + */ struct ethtool_rxnfc { __u32 cmd; __u32 flow_type; - /* The rx flow hash value or the rule DB size */ __u64 data; - /* The following fields are not valid and must not be used for - * the ETHTOOL_{G,X}RXFH commands. */ struct ethtool_rx_flow_spec fs; __u32 rule_cnt; __u32 rule_locs[0]; }; +/** + * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection + * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR + * @size: On entry, the array size of the user buffer. On return from + * %ETHTOOL_GRXFHINDIR, the array size of the hardware indirection table. + * @ring_index: RX ring/queue index for each hash value + */ struct ethtool_rxfh_indir { __u32 cmd; - /* On entry, this is the array size of the user buffer. On - * return from ETHTOOL_GRXFHINDIR, this is the array size of - * the hardware indirection table. */ __u32 size; - __u32 ring_index[0]; /* ring/queue index for each hash value */ + __u32 ring_index[0]; }; +/** + * struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter + * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW + * @h_u: Flow field values to match (dependent on @flow_type) + * @m_u: Masks for flow field value bits to be ignored + * @vlan_tag: VLAN tag to match + * @vlan_tag_mask: Mask for VLAN tag bits to be ignored + * @data: Driver-dependent data to match + * @data_mask: Mask for driver-dependent data bits to be ignored + * @action: RX ring/queue index to deliver to (non-negative) or other action + * (negative, e.g. %ETHTOOL_RXNTUPLE_ACTION_DROP) + * + * For flow types %TCP_V4_FLOW, %UDP_V4_FLOW and %SCTP_V4_FLOW, where + * a field value and mask are both zero this is treated as if all mask + * bits are set i.e. the field is ignored. + */ struct ethtool_rx_ntuple_flow_spec { __u32 flow_type; union { @@ -403,22 +486,26 @@ struct ethtool_rx_ntuple_flow_spec { struct ethtool_tcpip4_spec sctp_ip4_spec; struct ethtool_ah_espip4_spec ah_ip4_spec; struct ethtool_ah_espip4_spec esp_ip4_spec; - struct ethtool_rawip4_spec raw_ip4_spec; - struct ethtool_ether_spec ether_spec; struct ethtool_usrip4_spec usr_ip4_spec; - __u8 hdata[64]; - } h_u, m_u; /* entry, mask */ + struct ethhdr ether_spec; + __u8 hdata[72]; + } h_u, m_u; __u16 vlan_tag; __u16 vlan_tag_mask; - __u64 data; /* user-defined flow spec data */ - __u64 data_mask; /* user-defined flow spec mask */ + __u64 data; + __u64 data_mask; - /* signed to distinguish between queue and actions (DROP) */ __s32 action; -#define ETHTOOL_RXNTUPLE_ACTION_DROP -1 +#define ETHTOOL_RXNTUPLE_ACTION_DROP (-1) /* drop packet */ +#define ETHTOOL_RXNTUPLE_ACTION_CLEAR (-2) /* clear filter */ }; +/** + * struct ethtool_rx_ntuple - command to set or clear RX flow filter + * @cmd: Command number - %ETHTOOL_SRXNTUPLE + * @fs: Flow filter specification + */ struct ethtool_rx_ntuple { __u32 cmd; struct ethtool_rx_ntuple_flow_spec fs; @@ -759,22 +846,23 @@ struct ethtool_ops { #define WAKE_MAGIC (1 << 5) #define WAKE_MAGICSECURE (1 << 6) /* only meaningful if WAKE_MAGIC */ -/* L3-L4 network traffic flow types */ -#define TCP_V4_FLOW 0x01 -#define UDP_V4_FLOW 0x02 -#define SCTP_V4_FLOW 0x03 -#define AH_ESP_V4_FLOW 0x04 -#define TCP_V6_FLOW 0x05 -#define UDP_V6_FLOW 0x06 -#define SCTP_V6_FLOW 0x07 -#define AH_ESP_V6_FLOW 0x08 -#define AH_V4_FLOW 0x09 -#define ESP_V4_FLOW 0x0a -#define AH_V6_FLOW 0x0b -#define ESP_V6_FLOW 0x0c -#define IP_USER_FLOW 0x0d -#define IPV4_FLOW 0x10 -#define IPV6_FLOW 0x11 +/* L2-L4 network traffic flow types */ +#define TCP_V4_FLOW 0x01 /* hash or spec (tcp_ip4_spec) */ +#define UDP_V4_FLOW 0x02 /* hash or spec (udp_ip4_spec) */ +#define SCTP_V4_FLOW 0x03 /* hash or spec (sctp_ip4_spec) */ +#define AH_ESP_V4_FLOW 0x04 /* hash only */ +#define TCP_V6_FLOW 0x05 /* hash only */ +#define UDP_V6_FLOW 0x06 /* hash only */ +#define SCTP_V6_FLOW 0x07 /* hash only */ +#define AH_ESP_V6_FLOW 0x08 /* hash only */ +#define AH_V4_FLOW 0x09 /* hash or spec (ah_ip4_spec) */ +#define ESP_V4_FLOW 0x0a /* hash or spec (esp_ip4_spec) */ +#define AH_V6_FLOW 0x0b /* hash only */ +#define ESP_V6_FLOW 0x0c /* hash only */ +#define IP_USER_FLOW 0x0d /* spec only (usr_ip4_spec) */ +#define IPV4_FLOW 0x10 /* hash only */ +#define IPV6_FLOW 0x11 /* hash only */ +#define ETHER_FLOW 0x12 /* spec only (ether_spec) */ /* L3-L4 network traffic flow hash options */ #define RXH_L2DA (1 << 1) diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 97b2eae6a22cfe302d9a5956830a93c8cc37dab0..ed5a03cbe184eba3c77799d164d5e8b9b77c0780 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -986,6 +986,7 @@ struct ieee80211_ht_info { #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 #define WLAN_AUTH_FT 2 +#define WLAN_AUTH_SAE 3 #define WLAN_AUTH_LEAP 128 #define WLAN_AUTH_CHALLENGE_LEN 128 @@ -1072,6 +1073,10 @@ enum ieee80211_statuscode { WLAN_STATUS_NO_DIRECT_LINK = 48, WLAN_STATUS_STA_NOT_PRESENT = 49, WLAN_STATUS_STA_NOT_QSTA = 50, + /* 802.11s */ + WLAN_STATUS_ANTI_CLOG_REQUIRED = 76, + WLAN_STATUS_FCG_NOT_SUPP = 78, + WLAN_STATUS_STA_NO_TBTT = 78, }; @@ -1112,6 +1117,22 @@ enum ieee80211_reasoncode { WLAN_REASON_QSTA_REQUIRE_SETUP = 38, WLAN_REASON_QSTA_TIMEOUT = 39, WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45, + /* 802.11s */ + WLAN_REASON_MESH_PEER_CANCELED = 52, + WLAN_REASON_MESH_MAX_PEERS = 53, + WLAN_REASON_MESH_CONFIG = 54, + WLAN_REASON_MESH_CLOSE = 55, + WLAN_REASON_MESH_MAX_RETRIES = 56, + WLAN_REASON_MESH_CONFIRM_TIMEOUT = 57, + WLAN_REASON_MESH_INVALID_GTK = 58, + WLAN_REASON_MESH_INCONSISTENT_PARAM = 59, + WLAN_REASON_MESH_INVALID_SECURITY = 60, + WLAN_REASON_MESH_PATH_ERROR = 61, + WLAN_REASON_MESH_PATH_NOFORWARD = 62, + WLAN_REASON_MESH_PATH_DEST_UNREACHABLE = 63, + WLAN_REASON_MAC_EXISTS_IN_MBSS = 64, + WLAN_REASON_MESH_CHAN_REGULATORY = 65, + WLAN_REASON_MESH_CHAN = 66, }; @@ -1139,20 +1160,33 @@ enum ieee80211_eid { WLAN_EID_TS_DELAY = 43, WLAN_EID_TCLAS_PROCESSING = 44, WLAN_EID_QOS_CAPA = 46, - /* 802.11s - * - * All mesh EID numbers are pending IEEE 802.11 ANA approval. - * The numbers have been incremented from those suggested in - * 802.11s/D2.0 so that MESH_CONFIG does not conflict with - * EXT_SUPP_RATES. + /* 802.11s */ + WLAN_EID_MESH_CONFIG = 113, + WLAN_EID_MESH_ID = 114, + WLAN_EID_LINK_METRIC_REPORT = 115, + WLAN_EID_CONGESTION_NOTIFICATION = 116, + /* Note that the Peer Link IE has been replaced with the similar + * Peer Management IE. We will keep the former definition until mesh + * code is changed to comply with latest 802.11s drafts. */ - WLAN_EID_MESH_CONFIG = 51, - WLAN_EID_MESH_ID = 52, - WLAN_EID_PEER_LINK = 55, - WLAN_EID_PREQ = 68, - WLAN_EID_PREP = 69, - WLAN_EID_PERR = 70, - WLAN_EID_RANN = 49, /* compatible with FreeBSD */ + WLAN_EID_PEER_LINK = 55, /* no longer in 802.11s drafts */ + WLAN_EID_PEER_MGMT = 117, + WLAN_EID_CHAN_SWITCH_PARAM = 118, + WLAN_EID_MESH_AWAKE_WINDOW = 119, + WLAN_EID_BEACON_TIMING = 120, + WLAN_EID_MCCAOP_SETUP_REQ = 121, + WLAN_EID_MCCAOP_SETUP_RESP = 122, + WLAN_EID_MCCAOP_ADVERT = 123, + WLAN_EID_MCCAOP_TEARDOWN = 124, + WLAN_EID_GANN = 125, + WLAN_EID_RANN = 126, + WLAN_EID_PREQ = 130, + WLAN_EID_PREP = 131, + WLAN_EID_PERR = 132, + WLAN_EID_PXU = 137, + WLAN_EID_PXUC = 138, + WLAN_EID_AUTH_MESH_PEER_EXCH = 139, + WLAN_EID_MIC = 140, WLAN_EID_PWR_CONSTRAINT = 32, WLAN_EID_PWR_CAPABILITY = 33, @@ -1211,9 +1245,14 @@ enum ieee80211_category { WLAN_CATEGORY_HT = 7, WLAN_CATEGORY_SA_QUERY = 8, WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9, + WLAN_CATEGORY_MESH_ACTION = 13, + WLAN_CATEGORY_MULTIHOP_ACTION = 14, + WLAN_CATEGORY_SELF_PROTECTED = 15, WLAN_CATEGORY_WMM = 17, - WLAN_CATEGORY_MESH_PLINK = 30, /* Pending ANA approval */ - WLAN_CATEGORY_MESH_PATH_SEL = 32, /* Pending ANA approval */ + /* TODO: remove MESH_PLINK and MESH_PATH_SEL after */ + /* mesh is updated to current 802.11s draft */ + WLAN_CATEGORY_MESH_PLINK = 30, + WLAN_CATEGORY_MESH_PATH_SEL = 32, WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, WLAN_CATEGORY_VENDOR_SPECIFIC = 127, }; @@ -1351,6 +1390,8 @@ enum ieee80211_sa_query_action { /* AKM suite selectors */ #define WLAN_AKM_SUITE_8021X 0x000FAC01 #define WLAN_AKM_SUITE_PSK 0x000FAC02 +#define WLAN_AKM_SUITE_SAE 0x000FAC08 +#define WLAN_AKM_SUITE_FT_OVER_SAE 0x000FAC09 #define WLAN_MAX_KEY_LEN 32 diff --git a/include/linux/if.h b/include/linux/if.h index 53558ec59e1b16d4272f9cdd51e1a0ba4957facc..123959927745b7934cacea3e1aacf5c6303bcb1c 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -75,6 +75,8 @@ #define IFF_DISABLE_NETPOLL 0x2000 /* disable netpoll at run-time */ #define IFF_MACVLAN_PORT 0x4000 /* device used as macvlan port */ #define IFF_BRIDGE_PORT 0x8000 /* device used as bridge port */ +#define IFF_OVS_DATAPATH 0x10000 /* device used as Open vSwitch + * datapath port */ #define IF_GET_IFACE 0x0001 /* for querying only */ #define IF_GET_PROTO 0x0002 diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h index 2c7994372bde965fe5b37bd6335963ef3d490c3d..a17edda8a7816c2ba92e7c1b7aee3cce23b93f8f 100644 --- a/include/linux/if_bonding.h +++ b/include/linux/if_bonding.h @@ -84,6 +84,9 @@ #define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */ #define BOND_DEFAULT_TX_QUEUES 16 /* Default number of tx queues per device */ + +#define BOND_DEFAULT_RESEND_IGMP 1 /* Default number of IGMP membership reports */ + /* hashing types */ #define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ #define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */ diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index bed7a4682b90734935e3dd6680d5e646b0b895c0..f9c3df03db0f0babecddf685250798807c9a7b97 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -137,8 +137,6 @@ extern struct ctl_table ether_table[]; extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" - #endif #endif /* _LINUX_IF_ETHER_H */ diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h index 35280b302290459ff20293b2e4bcafd5aa6b9b2a..8a2fd66a8b5f8b51bd5f9475dc04580c0ccd6757 100644 --- a/include/linux/if_macvlan.h +++ b/include/linux/if_macvlan.h @@ -40,6 +40,12 @@ struct macvlan_rx_stats { unsigned long rx_errors; }; +/* + * Maximum times a macvtap device can be opened. This can be used to + * configure the number of receive queue, e.g. for multiqueue virtio. + */ +#define MAX_MACVTAP_QUEUES (NR_CPUS < 16 ? NR_CPUS : 16) + struct macvlan_dev { struct net_device *dev; struct list_head list; @@ -50,7 +56,8 @@ struct macvlan_dev { enum macvlan_mode mode; int (*receive)(struct sk_buff *skb); int (*forward)(struct net_device *dev, struct sk_buff *skb); - struct macvtap_queue *tap; + struct macvtap_queue *taps[MAX_MACVTAP_QUEUES]; + int numvtaps; }; static inline void macvlan_count_rx(const struct macvlan_dev *vlan, diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h index 27741e05446f97dfad3e5f35e83f328d02520588..397921b09ef9b792153e84fa8af24c8a96c98dc1 100644 --- a/include/linux/if_pppox.h +++ b/include/linux/if_pppox.h @@ -40,25 +40,35 @@ * PPPoE addressing definition */ typedef __be16 sid_t; -struct pppoe_addr{ - sid_t sid; /* Session identifier */ - unsigned char remote[ETH_ALEN]; /* Remote address */ - char dev[IFNAMSIZ]; /* Local device to use */ +struct pppoe_addr { + sid_t sid; /* Session identifier */ + unsigned char remote[ETH_ALEN]; /* Remote address */ + char dev[IFNAMSIZ]; /* Local device to use */ }; /************************************************************************ - * Protocols supported by AF_PPPOX - */ + * PPTP addressing definition + */ +struct pptp_addr { + __be16 call_id; + struct in_addr sin_addr; +}; + +/************************************************************************ + * Protocols supported by AF_PPPOX + */ #define PX_PROTO_OE 0 /* Currently just PPPoE */ #define PX_PROTO_OL2TP 1 /* Now L2TP also */ -#define PX_MAX_PROTO 2 - -struct sockaddr_pppox { - sa_family_t sa_family; /* address family, AF_PPPOX */ - unsigned int sa_protocol; /* protocol identifier */ - union{ - struct pppoe_addr pppoe; - }sa_addr; +#define PX_PROTO_PPTP 2 +#define PX_MAX_PROTO 3 + +struct sockaddr_pppox { + sa_family_t sa_family; /* address family, AF_PPPOX */ + unsigned int sa_protocol; /* protocol identifier */ + union { + struct pppoe_addr pppoe; + struct pptp_addr pptp; + } sa_addr; } __attribute__((packed)); /* The use of the above union isn't viable because the size of this @@ -150,15 +160,23 @@ struct pppoe_opt { relayed to (PPPoE relaying) */ }; +struct pptp_opt { + struct pptp_addr src_addr; + struct pptp_addr dst_addr; + u32 ack_sent, ack_recv; + u32 seq_sent, seq_recv; + int ppp_flags; +}; #include struct pppox_sock { /* struct sock must be the first member of pppox_sock */ - struct sock sk; - struct ppp_channel chan; + struct sock sk; + struct ppp_channel chan; struct pppox_sock *next; /* for hash table */ union { struct pppoe_opt pppoe; + struct pptp_opt pptp; } proto; __be16 num; }; @@ -186,7 +204,7 @@ struct pppox_proto { struct module *owner; }; -extern int register_pppox_proto(int proto_num, struct pppox_proto *pp); +extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp); extern void unregister_pppox_proto(int proto_num); extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */ extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 3d870fda8c4ff3ca3477796a9c454e01e4598996..c2f3a72712cec86a63699690096b928f1a1db6a2 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -16,6 +16,7 @@ #ifdef __KERNEL__ #include #include +#include #define VLAN_HLEN 4 /* The additional bytes (on top of the Ethernet header) * that VLAN requires. @@ -68,6 +69,7 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb) #define VLAN_CFI_MASK 0x1000 /* Canonical Format Indicator */ #define VLAN_TAG_PRESENT VLAN_CFI_MASK #define VLAN_VID_MASK 0x0fff /* VLAN Identifier */ +#define VLAN_N_VID 4096 /* found in socket.c */ extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); @@ -76,9 +78,8 @@ extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *)); * depends on completely exhausting the VLAN identifier space. Thus * it gives constant time look-up, but in many cases it wastes memory. */ -#define VLAN_GROUP_ARRAY_LEN 4096 #define VLAN_GROUP_ARRAY_SPLIT_PARTS 8 -#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_GROUP_ARRAY_LEN/VLAN_GROUP_ARRAY_SPLIT_PARTS) +#define VLAN_GROUP_ARRAY_PART_LEN (VLAN_N_VID/VLAN_GROUP_ARRAY_SPLIT_PARTS) struct vlan_group { struct net_device *real_dev; /* The ethernet(like) device @@ -114,12 +115,24 @@ static inline void vlan_group_set_device(struct vlan_group *vg, #define vlan_tx_tag_get(__skb) ((__skb)->vlan_tci & ~VLAN_TAG_PRESENT) #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +/* Must be invoked with rcu_read_lock or with RTNL. */ +static inline struct net_device *vlan_find_dev(struct net_device *real_dev, + u16 vlan_id) +{ + struct vlan_group *grp = rcu_dereference_rtnl(real_dev->vlgrp); + + if (grp) + return vlan_group_get_device(grp, vlan_id); + + return NULL; +} + extern struct net_device *vlan_dev_real_dev(const struct net_device *dev); extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci, int polling); -extern int vlan_hwaccel_do_receive(struct sk_buff *skb); +extern bool vlan_hwaccel_do_receive(struct sk_buff **skb); extern gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb); @@ -128,6 +141,12 @@ vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci); #else +static inline struct net_device *vlan_find_dev(struct net_device *real_dev, + u16 vlan_id) +{ + return NULL; +} + static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev) { BUG(); @@ -147,9 +166,11 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, return NET_XMIT_SUCCESS; } -static inline int vlan_hwaccel_do_receive(struct sk_buff *skb) +static inline bool vlan_hwaccel_do_receive(struct sk_buff **skb) { - return 0; + if ((*skb)->vlan_tci & VLAN_VID_MASK) + (*skb)->pkt_type = PACKET_OTHERHOST; + return false; } static inline gro_result_t diff --git a/include/linux/in.h b/include/linux/in.h index 41d88a4689af0a77a000cfc88437a70d8abdc1fb..beeb6dee2b49d416cc3f74537e920ca2ae93dd17 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -250,6 +250,25 @@ struct sockaddr_in { #ifdef __KERNEL__ +#include + +static inline int proto_ports_offset(int proto) +{ + switch (proto) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_DCCP: + case IPPROTO_ESP: /* SPI */ + case IPPROTO_SCTP: + case IPPROTO_UDPLITE: + return 0; + case IPPROTO_AH: /* SPI */ + return 4; + default: + return -EINVAL; + } +} + static inline bool ipv4_is_loopback(__be32 addr) { return (addr & htonl(0xff000000)) == htonl(0x7f000000); diff --git a/include/linux/in6.h b/include/linux/in6.h index c4bf46f764bf34bffab67e6de3ec9c8ddee70b0e..097a34b55560a9d4434f61f78b85f5fbbef8e2e7 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -268,6 +268,10 @@ struct in6_flowlabel_req { /* RFC5082: Generalized Ttl Security Mechanism */ #define IPV6_MINHOPCOUNT 73 +#define IPV6_ORIGDSTADDR 74 +#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR +#define IPV6_TRANSPARENT 75 + /* * Multicast Routing: * see include/linux/mroute6.h. diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index 2be1a1a2beb96455cc8d2bea2e1c47071c768fff..ccd5b07d678deb8a61ff759ba943dceae6bf1507 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -9,6 +9,7 @@ #include #include #include +#include enum { @@ -158,7 +159,12 @@ struct in_ifaddr { extern int register_inetaddr_notifier(struct notifier_block *nb); extern int unregister_inetaddr_notifier(struct notifier_block *nb); -extern struct net_device *ip_dev_find(struct net *net, __be32 addr); +extern struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref); +static inline struct net_device *ip_dev_find(struct net *net, __be32 addr) +{ + return __ip_dev_find(net, addr, true); +} + extern int inet_addr_onlink(struct in_device *in_dev, __be32 a, __be32 b); extern int devinet_ioctl(struct net *net, unsigned int cmd, void __user *); extern void devinet_init(void); @@ -198,14 +204,10 @@ static __inline__ int bad_mask(__be32 mask, __be32 addr) static inline struct in_device *__in_dev_get_rcu(const struct net_device *dev) { - struct in_device *in_dev = dev->ip_ptr; - if (in_dev) - in_dev = rcu_dereference(in_dev); - return in_dev; + return rcu_dereference(dev->ip_ptr); } -static __inline__ struct in_device * -in_dev_get(const struct net_device *dev) +static inline struct in_device *in_dev_get(const struct net_device *dev) { struct in_device *in_dev; @@ -217,10 +219,9 @@ in_dev_get(const struct net_device *dev) return in_dev; } -static __inline__ struct in_device * -__in_dev_get_rtnl(const struct net_device *dev) +static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev) { - return (struct in_device*)dev->ip_ptr; + return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held()); } extern void in_dev_finish_destroy(struct in_device *idev); diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h index 9708de265bb1e24f1b6130c2f0ca3ace1b249dfc..5f43a3b2e3ad7149c13f2552987c8b5ce1749fcb 100644 --- a/include/linux/ip_vs.h +++ b/include/linux/ip_vs.h @@ -70,6 +70,7 @@ /* * IPVS Connection Flags + * Only flags 0..15 are sent to backup server */ #define IP_VS_CONN_F_FWD_MASK 0x0007 /* mask for the fwd methods */ #define IP_VS_CONN_F_MASQ 0x0000 /* masquerading/NAT */ @@ -88,9 +89,20 @@ #define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */ #define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */ +/* Flags that are not sent to backup server start from bit 16 */ +#define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */ + +/* Connection flags from destination that can be changed by user space */ +#define IP_VS_CONN_F_DEST_MASK (IP_VS_CONN_F_FWD_MASK | \ + IP_VS_CONN_F_ONE_PACKET | \ + IP_VS_CONN_F_NFCT | \ + 0) + #define IP_VS_SCHEDNAME_MAXLEN 16 +#define IP_VS_PENAME_MAXLEN 16 #define IP_VS_IFNAME_MAXLEN 16 +#define IP_VS_PEDATA_MAXLEN 255 /* * The struct ip_vs_service_user and struct ip_vs_dest_user are @@ -324,6 +336,9 @@ enum { IPVS_SVC_ATTR_NETMASK, /* persistent netmask */ IPVS_SVC_ATTR_STATS, /* nested attribute for service stats */ + + IPVS_SVC_ATTR_PE_NAME, /* name of ct retriever */ + __IPVS_SVC_ATTR_MAX, }; diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index e62683ba88e6824e72b3e8c81c7315998868f606..8e429d0e0405df6f50ebbfe9273d719f18facc57 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -341,7 +341,9 @@ struct ipv6_pinfo { odstopts:1, rxflow:1, rxtclass:1, - rxpmtu:1; + rxpmtu:1, + rxorigdstaddr:1; + /* 2 bits hole */ } bits; __u16 all; } rxopt; diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 0f82293a82edf23da15a2ae51447d7db8c1b674f..78a1b96717523ba47b84867fc875aacef4f51e20 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -56,6 +56,7 @@ enum { MLX4_CMD_QUERY_HCA = 0xb, MLX4_CMD_QUERY_PORT = 0x43, MLX4_CMD_SENSE_PORT = 0x4d, + MLX4_CMD_HW_HEALTH_CHECK = 0x50, MLX4_CMD_SET_PORT = 0xc, MLX4_CMD_ACCESS_DDR = 0x2e, MLX4_CMD_MAP_ICM = 0xffa, diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 7a7f9c1e679a30e5b2f8366926cf7b7991360723..7338654c02b4de5402cbba6c80a3f96106e3b717 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -186,6 +186,10 @@ struct mlx4_caps { int eth_mtu_cap[MLX4_MAX_PORTS + 1]; int gid_table_len[MLX4_MAX_PORTS + 1]; int pkey_table_len[MLX4_MAX_PORTS + 1]; + int trans_type[MLX4_MAX_PORTS + 1]; + int vendor_oui[MLX4_MAX_PORTS + 1]; + int wavelength[MLX4_MAX_PORTS + 1]; + u64 trans_code[MLX4_MAX_PORTS + 1]; int local_ca_ack_delay; int num_uars; int bf_reg_size; @@ -229,6 +233,8 @@ struct mlx4_caps { u32 bmme_flags; u32 reserved_lkey; u16 stat_rate_support; + int udp_rss; + int loopback_support; u8 port_width_cap[MLX4_MAX_PORTS + 1]; int max_gso_sz; int reserved_qps_cnt[MLX4_NUM_QP_REGION]; @@ -480,5 +486,6 @@ void mlx4_fmr_unmap(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u32 *lkey, u32 *rkey); int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr); int mlx4_SYNC_TPT(struct mlx4_dev *dev); +int mlx4_test_interrupts(struct mlx4_dev *dev); #endif /* MLX4_DEVICE_H */ diff --git a/include/linux/mmc/sdio_ids.h b/include/linux/mmc/sdio_ids.h index 33b2ea09a4ad5a616957c2fc417ca34db677ae79..a36ab3bc7b03bbc69978c9a3d0d7b31303818572 100644 --- a/include/linux/mmc/sdio_ids.h +++ b/include/linux/mmc/sdio_ids.h @@ -18,6 +18,7 @@ #define SDIO_CLASS_PHS 0x06 /* PHS standard interface */ #define SDIO_CLASS_WLAN 0x07 /* WLAN interface */ #define SDIO_CLASS_ATA 0x08 /* Embedded SDIO-ATA std interface */ +#define SDIO_CLASS_BT_AMP 0x09 /* Type-A Bluetooth AMP interface */ /* * Vendors and devices. Sort key: vendor first, device next. diff --git a/include/linux/mroute.h b/include/linux/mroute.h index fa04b246c9ae997f18b8030fa7b5650d19956e7e..0fa7a3a874c8bc72872f429a7f185b9c2c184796 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h @@ -213,6 +213,7 @@ struct mfc_cache { unsigned char ttls[MAXVIFS]; /* TTL thresholds */ } res; } mfc_un; + struct rcu_head rcu; }; #define MFC_STATIC 1 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 46c36ffe20eed83f4be29dfd4b75bc694c110c68..fcd3dda8632282c1d23882c28f0a1b4d3bb9828f 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -228,9 +228,9 @@ struct netdev_hw_addr { #define NETDEV_HW_ADDR_T_SLAVE 3 #define NETDEV_HW_ADDR_T_UNICAST 4 #define NETDEV_HW_ADDR_T_MULTICAST 5 - int refcount; bool synced; bool global_use; + int refcount; struct rcu_head rcu_head; }; @@ -281,6 +281,12 @@ struct hh_cache { unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)]; }; +static inline void hh_cache_put(struct hh_cache *hh) +{ + if (atomic_dec_and_test(&hh->hh_refcnt)) + kfree(hh); +} + /* Reserve HH_DATA_MOD byte aligned hard_header_len, but at least that much. * Alternative is: * dev->hard_header_len ? (dev->hard_header_len + @@ -884,6 +890,9 @@ struct net_device { int iflink; struct net_device_stats stats; + atomic_long_t rx_dropped; /* dropped packets by core network + * Do not use this in drivers. + */ #ifdef CONFIG_WIRELESS_EXT /* List of functions to handle Wireless Extensions (instead of ioctl). @@ -901,7 +910,7 @@ struct net_device { unsigned int flags; /* interface flags (a la BSD) */ unsigned short gflags; - unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */ + unsigned int priv_flags; /* Like 'flags' but invisible to userspace. */ unsigned short padded; /* How much padding added by alloc_netdev() */ unsigned char operstate; /* RFC2863 operstate */ @@ -918,10 +927,6 @@ struct net_device { unsigned short needed_headroom; unsigned short needed_tailroom; - struct net_device *master; /* Pointer to master device of a group, - * which this device is member of. - */ - /* Interface address info. */ unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */ unsigned char addr_assign_type; /* hw address assignment type */ @@ -937,12 +942,15 @@ struct net_device { /* Protocol specific pointers */ - + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + struct vlan_group *vlgrp; /* VLAN group */ +#endif #ifdef CONFIG_NET_DSA void *dsa_ptr; /* dsa specific data */ #endif void *atalk_ptr; /* AppleTalk link */ - void *ip_ptr; /* IPv4 specific data */ + struct in_device __rcu *ip_ptr; /* IPv4 specific data */ void *dn_ptr; /* DECnet specific data */ void *ip6_ptr; /* IPv6 specific data */ void *ec_ptr; /* Econet specific data */ @@ -951,9 +959,20 @@ struct net_device { assign before registering */ /* - * Cache line mostly used on receive path (including eth_type_trans()) + * Cache lines mostly used on receive path (including eth_type_trans()) */ - unsigned long last_rx; /* Time of last Rx */ + unsigned long last_rx; /* Time of last Rx + * This should not be set in + * drivers, unless really needed, + * because network stack (bonding) + * use it if/when necessary, to + * avoid dirtying this cache line. + */ + + struct net_device *master; /* Pointer to master device of a group, + * which this device is member of. + */ + /* Interface address info used in eth_type_trans() */ unsigned char *dev_addr; /* hw address, (before bcast because most packets are @@ -969,14 +988,21 @@ struct net_device { struct netdev_rx_queue *_rx; - /* Number of RX queues allocated at alloc_netdev_mq() time */ + /* Number of RX queues allocated at register_netdev() time */ unsigned int num_rx_queues; + + /* Number of RX queues currently active in device */ + unsigned int real_num_rx_queues; #endif - struct netdev_queue rx_queue; rx_handler_func_t *rx_handler; void *rx_handler_data; + struct netdev_queue __rcu *ingress_queue; + +/* + * Cache lines mostly used on transmit path + */ struct netdev_queue *_tx ____cacheline_aligned_in_smp; /* Number of TX queues allocated at alloc_netdev_mq() time */ @@ -990,9 +1016,7 @@ struct net_device { unsigned long tx_queue_len; /* Max frames per queue allowed */ spinlock_t tx_global_lock; -/* - * One part is mostly used on xmit path (device) - */ + /* These may be needed for future network-power-down code. */ /* @@ -1005,7 +1029,7 @@ struct net_device { struct timer_list watchdog_timer; /* Number of references to this device */ - atomic_t refcnt ____cacheline_aligned_in_smp; + int __percpu *pcpu_refcnt; /* delayed register/unregister */ struct list_head todo_list; @@ -1041,8 +1065,12 @@ struct net_device { #endif /* mid-layer private */ - void *ml_priv; - + union { + void *ml_priv; + struct pcpu_lstats __percpu *lstats; /* loopback stats */ + struct pcpu_tstats __percpu *tstats; /* tunnel stats */ + struct pcpu_dstats __percpu *dstats; /* dummy stats */ + }; /* GARP */ struct garp_port *garp_port; @@ -1305,6 +1333,7 @@ static inline void unregister_netdevice(struct net_device *dev) unregister_netdevice_queue(dev, NULL); } +extern int netdev_refcnt_read(const struct net_device *dev); extern void free_netdev(struct net_device *dev); extern void synchronize_net(void); extern int register_netdevice_notifier(struct notifier_block *nb); @@ -1667,11 +1696,34 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index) */ static inline int netif_is_multiqueue(const struct net_device *dev) { - return (dev->num_tx_queues > 1); + return dev->num_tx_queues > 1; } -extern void netif_set_real_num_tx_queues(struct net_device *dev, - unsigned int txq); +extern int netif_set_real_num_tx_queues(struct net_device *dev, + unsigned int txq); + +#ifdef CONFIG_RPS +extern int netif_set_real_num_rx_queues(struct net_device *dev, + unsigned int rxq); +#else +static inline int netif_set_real_num_rx_queues(struct net_device *dev, + unsigned int rxq) +{ + return 0; +} +#endif + +static inline int netif_copy_real_num_queues(struct net_device *to_dev, + const struct net_device *from_dev) +{ + netif_set_real_num_tx_queues(to_dev, from_dev->real_num_tx_queues); +#ifdef CONFIG_RPS + return netif_set_real_num_rx_queues(to_dev, + from_dev->real_num_rx_queues); +#else + return 0; +#endif +} /* Use this variant when it is known for sure that it * is executing from hardware interrupt context or with hardware interrupts @@ -1695,8 +1747,7 @@ extern gro_result_t dev_gro_receive(struct napi_struct *napi, extern gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb); extern gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb); -extern void napi_reuse_skb(struct napi_struct *napi, - struct sk_buff *skb); +extern void napi_gro_flush(struct napi_struct *napi); extern struct sk_buff * napi_get_frags(struct napi_struct *napi); extern gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, @@ -1715,7 +1766,6 @@ extern int netdev_rx_handler_register(struct net_device *dev, void *rx_handler_data); extern void netdev_rx_handler_unregister(struct net_device *dev); -extern void netif_nit_deliver(struct sk_buff *skb); extern int dev_valid_name(const char *name); extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *); extern int dev_ethtool(struct net *net, struct ifreq *); @@ -1749,7 +1799,7 @@ extern void netdev_run_todo(void); */ static inline void dev_put(struct net_device *dev) { - atomic_dec(&dev->refcnt); + irqsafe_cpu_dec(*dev->pcpu_refcnt); } /** @@ -1760,7 +1810,7 @@ static inline void dev_put(struct net_device *dev) */ static inline void dev_hold(struct net_device *dev) { - atomic_inc(&dev->refcnt); + irqsafe_cpu_inc(*dev->pcpu_refcnt); } /* Carrier loss detection, dial on demand. The functions netif_carrier_on @@ -2171,6 +2221,8 @@ extern void dev_seq_stop(struct seq_file *seq, void *v); extern int netdev_class_create_file(struct class_attribute *class_attr); extern void netdev_class_remove_file(struct class_attribute *class_attr); +extern struct kobj_ns_type_operations net_ns_type_operations; + extern char *netdev_drivername(const struct net_device *dev, char *buffer, int len); extern void linkwatch_run_queue(void); @@ -2191,14 +2243,22 @@ static inline int net_gso_ok(int features, int gso_type) static inline int skb_gso_ok(struct sk_buff *skb, int features) { return net_gso_ok(features, skb_shinfo(skb)->gso_type) && - (!skb_has_frags(skb) || (features & NETIF_F_FRAGLIST)); + (!skb_has_frag_list(skb) || (features & NETIF_F_FRAGLIST)); } static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) { - return skb_is_gso(skb) && - (!skb_gso_ok(skb, dev->features) || - unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); + if (skb_is_gso(skb)) { + int features = dev->features; + + if (skb->protocol == htons(ETH_P_8021Q) || skb->vlan_tci) + features &= dev->vlan_features; + + return (!skb_gso_ok(skb, features) || + unlikely(skb->ip_summed != CHECKSUM_PARTIAL)); + } + + return 0; } static inline void netif_set_gso_max_size(struct net_device *dev, diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h index 1afd18c855ec99d9cf8cb4b9570b06b6e28b74d2..50cdc2559a5aa05a10e4d1115c48da7185a5e7bd 100644 --- a/include/linux/netfilter/nf_conntrack_common.h +++ b/include/linux/netfilter/nf_conntrack_common.h @@ -98,8 +98,14 @@ enum ip_conntrack_events { enum ip_conntrack_expect_events { IPEXP_NEW, /* new expectation */ + IPEXP_DESTROY, /* destroyed expectation */ }; +/* expectation flags */ +#define NF_CT_EXPECT_PERMANENT 0x1 +#define NF_CT_EXPECT_INACTIVE 0x2 +#define NF_CT_EXPECT_USERSPACE 0x4 + #ifdef __KERNEL__ struct ip_conntrack_stat { unsigned int searched; diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h index ff8cfbcf3b81148e483831281752572b2faaac1b..0ce91d56a5f264c989ee5b17a027b489eaabc593 100644 --- a/include/linux/netfilter/nf_conntrack_sip.h +++ b/include/linux/netfilter/nf_conntrack_sip.h @@ -89,6 +89,7 @@ enum sip_header_types { SIP_HDR_VIA_TCP, SIP_HDR_EXPIRES, SIP_HDR_CONTENT_LENGTH, + SIP_HDR_CALL_ID, }; enum sdp_header_types { diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h index 70cd0603911c97b865bc576a3f4490f523e2fc08..19711e3ffd428a83d3368ccee182a0b3f466bbb1 100644 --- a/include/linux/netfilter/nfnetlink_conntrack.h +++ b/include/linux/netfilter/nfnetlink_conntrack.h @@ -162,6 +162,7 @@ enum ctattr_expect { CTA_EXPECT_ID, CTA_EXPECT_HELP_NAME, CTA_EXPECT_ZONE, + CTA_EXPECT_FLAGS, __CTA_EXPECT_MAX }; #define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1) diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 24e5d01d27d07b860bfed06701fb2d864ee89bc3..742bec051440e4f800bbf00c5aee2ab468541958 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -66,6 +66,11 @@ struct xt_standard_target { int verdict; }; +struct xt_error_target { + struct xt_entry_target target; + char errorname[XT_FUNCTION_MAXNAMELEN]; +}; + /* The argument to IPT_SO_GET_REVISION_*. Returns highest revision * kernel supports, if >= revision. */ struct xt_get_revision { diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/linux/netfilter/xt_TPROXY.h index 152e8f97132b1a213271075c16c3ac0b2ce9895d..3f3d69361289ca4cecda2182f71d62e0b7137053 100644 --- a/include/linux/netfilter/xt_TPROXY.h +++ b/include/linux/netfilter/xt_TPROXY.h @@ -1,5 +1,5 @@ -#ifndef _XT_TPROXY_H_target -#define _XT_TPROXY_H_target +#ifndef _XT_TPROXY_H +#define _XT_TPROXY_H /* TPROXY target is capable of marking the packet to perform * redirection. We can get rid of that whenever we get support for @@ -11,4 +11,11 @@ struct xt_tproxy_target_info { __be16 lport; }; -#endif /* _XT_TPROXY_H_target */ +struct xt_tproxy_target_info_v1 { + u_int32_t mark_mask; + u_int32_t mark_value; + union nf_inet_addr laddr; + __be16 lport; +}; + +#endif /* _XT_TPROXY_H */ diff --git a/include/linux/netfilter_arp/arp_tables.h b/include/linux/netfilter_arp/arp_tables.h index e9948c0560f6fb302d29b5be35c6fd083d8409a7..adbf4bff87eda6823689222410cb625b63488150 100644 --- a/include/linux/netfilter_arp/arp_tables.h +++ b/include/linux/netfilter_arp/arp_tables.h @@ -21,8 +21,21 @@ #include +#ifndef __KERNEL__ #define ARPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN #define ARPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN +#define arpt_entry_target xt_entry_target +#define arpt_standard_target xt_standard_target +#define arpt_error_target xt_error_target +#define ARPT_CONTINUE XT_CONTINUE +#define ARPT_RETURN XT_RETURN +#define arpt_counters_info xt_counters_info +#define arpt_counters xt_counters +#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET +#define ARPT_ERROR_TARGET XT_ERROR_TARGET +#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args) +#endif #define ARPT_DEV_ADDR_LEN_MAX 16 @@ -63,9 +76,6 @@ struct arpt_arp { u_int16_t invflags; }; -#define arpt_entry_target xt_entry_target -#define arpt_standard_target xt_standard_target - /* Values for "flag" field in struct arpt_ip (general arp structure). * No flags defined yet. */ @@ -125,16 +135,10 @@ struct arpt_entry #define ARPT_SO_GET_REVISION_TARGET (ARPT_BASE_CTL + 3) #define ARPT_SO_GET_MAX (ARPT_SO_GET_REVISION_TARGET) -/* CONTINUE verdict for targets */ -#define ARPT_CONTINUE XT_CONTINUE - -/* For standard target */ -#define ARPT_RETURN XT_RETURN - /* The argument to ARPT_SO_GET_INFO */ struct arpt_getinfo { /* Which table: caller fills this in. */ - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Kernel fills these in. */ /* Which hook entry points are valid: bitmask */ @@ -156,7 +160,7 @@ struct arpt_getinfo { /* The argument to ARPT_SO_SET_REPLACE. */ struct arpt_replace { /* Which table. */ - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Which hook entry points are valid: bitmask. You can't change this. */ @@ -184,14 +188,10 @@ struct arpt_replace { struct arpt_entry entries[0]; }; -/* The argument to ARPT_SO_ADD_COUNTERS. */ -#define arpt_counters_info xt_counters_info -#define arpt_counters xt_counters - /* The argument to ARPT_SO_GET_ENTRIES. */ struct arpt_get_entries { /* Which table: user fills this in. */ - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* User fills this in: total entry size. */ unsigned int size; @@ -200,23 +200,12 @@ struct arpt_get_entries { struct arpt_entry entrytable[0]; }; -/* Standard return verdict, or do jump. */ -#define ARPT_STANDARD_TARGET XT_STANDARD_TARGET -/* Error verdict. */ -#define ARPT_ERROR_TARGET XT_ERROR_TARGET - /* Helper functions */ -static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e) +static __inline__ struct xt_entry_target *arpt_get_target(struct arpt_entry *e) { return (void *)e + e->target_offset; } -#ifndef __KERNEL__ -/* fn returns 0 to continue iteration */ -#define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ - XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args) -#endif - /* * Main firewall chains definitions and global var's definitions. */ @@ -225,17 +214,12 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e /* Standard entry. */ struct arpt_standard { struct arpt_entry entry; - struct arpt_standard_target target; -}; - -struct arpt_error_target { - struct arpt_entry_target target; - char errorname[ARPT_FUNCTION_MAXNAMELEN]; + struct xt_standard_target target; }; struct arpt_error { struct arpt_entry entry; - struct arpt_error_target target; + struct xt_error_target target; }; #define ARPT_ENTRY_INIT(__size) \ @@ -247,16 +231,16 @@ struct arpt_error { #define ARPT_STANDARD_INIT(__verdict) \ { \ .entry = ARPT_ENTRY_INIT(sizeof(struct arpt_standard)), \ - .target = XT_TARGET_INIT(ARPT_STANDARD_TARGET, \ - sizeof(struct arpt_standard_target)), \ + .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \ + sizeof(struct xt_standard_target)), \ .target.verdict = -(__verdict) - 1, \ } #define ARPT_ERROR_INIT \ { \ .entry = ARPT_ENTRY_INIT(sizeof(struct arpt_error)), \ - .target = XT_TARGET_INIT(ARPT_ERROR_TARGET, \ - sizeof(struct arpt_error_target)), \ + .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ + sizeof(struct xt_error_target)), \ .target.errorname = "ERROR", \ } @@ -271,8 +255,6 @@ extern unsigned int arpt_do_table(struct sk_buff *skb, const struct net_device *out, struct xt_table *table); -#define ARPT_ALIGN(s) XT_ALIGN(s) - #ifdef CONFIG_COMPAT #include @@ -285,14 +267,12 @@ struct compat_arpt_entry { unsigned char elems[0]; }; -static inline struct arpt_entry_target * +static inline struct xt_entry_target * compat_arpt_get_target(struct compat_arpt_entry *e) { return (void *)e + e->target_offset; } -#define COMPAT_ARPT_ALIGN(s) COMPAT_XT_ALIGN(s) - #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _ARPTABLES_H */ diff --git a/include/linux/netfilter_bridge/Kbuild b/include/linux/netfilter_bridge/Kbuild index d4d78672873e6ad29c886a8125dbe3a37078e6c8..e48f1a3f5a4affda5e9ee3f39fe6709c893dfd7c 100644 --- a/include/linux/netfilter_bridge/Kbuild +++ b/include/linux/netfilter_bridge/Kbuild @@ -3,11 +3,13 @@ header-y += ebt_among.h header-y += ebt_arp.h header-y += ebt_arpreply.h header-y += ebt_ip.h +header-y += ebt_ip6.h header-y += ebt_limit.h header-y += ebt_log.h header-y += ebt_mark_m.h header-y += ebt_mark_t.h header-y += ebt_nat.h +header-y += ebt_nflog.h header-y += ebt_pkttype.h header-y += ebt_redirect.h header-y += ebt_stp.h diff --git a/include/linux/netfilter_ipv4/ip_tables.h b/include/linux/netfilter_ipv4/ip_tables.h index 704a7b6e81698a2585f766ef7b5a0e0ac8896b8f..64a5d95c58e8a6057679a402186f0188931e35b1 100644 --- a/include/linux/netfilter_ipv4/ip_tables.h +++ b/include/linux/netfilter_ipv4/ip_tables.h @@ -27,12 +27,49 @@ #include +#ifndef __KERNEL__ #define IPT_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN #define IPT_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN #define ipt_match xt_match #define ipt_target xt_target #define ipt_table xt_table #define ipt_get_revision xt_get_revision +#define ipt_entry_match xt_entry_match +#define ipt_entry_target xt_entry_target +#define ipt_standard_target xt_standard_target +#define ipt_error_target xt_error_target +#define ipt_counters xt_counters +#define IPT_CONTINUE XT_CONTINUE +#define IPT_RETURN XT_RETURN + +/* This group is older than old (iptables < v1.4.0-rc1~89) */ +#include +#define ipt_udp xt_udp +#define ipt_tcp xt_tcp +#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT +#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT +#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS +#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION +#define IPT_TCP_INV_MASK XT_TCP_INV_MASK +#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT +#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT +#define IPT_UDP_INV_MASK XT_UDP_INV_MASK + +/* The argument to IPT_SO_ADD_COUNTERS. */ +#define ipt_counters_info xt_counters_info +/* Standard return verdict, or do jump. */ +#define IPT_STANDARD_TARGET XT_STANDARD_TARGET +/* Error verdict. */ +#define IPT_ERROR_TARGET XT_ERROR_TARGET + +/* fn returns 0 to continue iteration */ +#define IPT_MATCH_ITERATE(e, fn, args...) \ + XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) + +/* fn returns 0 to continue iteration */ +#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) +#endif /* Yes, Virginia, you have to zero the padding. */ struct ipt_ip { @@ -52,12 +89,6 @@ struct ipt_ip { u_int8_t invflags; }; -#define ipt_entry_match xt_entry_match -#define ipt_entry_target xt_entry_target -#define ipt_standard_target xt_standard_target - -#define ipt_counters xt_counters - /* Values for "flag" field in struct ipt_ip (general ip structure). */ #define IPT_F_FRAG 0x01 /* Set if rule is a fragment rule */ #define IPT_F_GOTO 0x02 /* Set if jump is a goto */ @@ -116,23 +147,6 @@ struct ipt_entry { #define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) #define IPT_SO_GET_MAX IPT_SO_GET_REVISION_TARGET -#define IPT_CONTINUE XT_CONTINUE -#define IPT_RETURN XT_RETURN - -#include -#define ipt_udp xt_udp -#define ipt_tcp xt_tcp - -#define IPT_TCP_INV_SRCPT XT_TCP_INV_SRCPT -#define IPT_TCP_INV_DSTPT XT_TCP_INV_DSTPT -#define IPT_TCP_INV_FLAGS XT_TCP_INV_FLAGS -#define IPT_TCP_INV_OPTION XT_TCP_INV_OPTION -#define IPT_TCP_INV_MASK XT_TCP_INV_MASK - -#define IPT_UDP_INV_SRCPT XT_UDP_INV_SRCPT -#define IPT_UDP_INV_DSTPT XT_UDP_INV_DSTPT -#define IPT_UDP_INV_MASK XT_UDP_INV_MASK - /* ICMP matching stuff */ struct ipt_icmp { u_int8_t type; /* type to match */ @@ -146,7 +160,7 @@ struct ipt_icmp { /* The argument to IPT_SO_GET_INFO */ struct ipt_getinfo { /* Which table: caller fills this in. */ - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Kernel fills these in. */ /* Which hook entry points are valid: bitmask */ @@ -168,7 +182,7 @@ struct ipt_getinfo { /* The argument to IPT_SO_SET_REPLACE. */ struct ipt_replace { /* Which table. */ - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Which hook entry points are valid: bitmask. You can't change this. */ @@ -196,13 +210,10 @@ struct ipt_replace { struct ipt_entry entries[0]; }; -/* The argument to IPT_SO_ADD_COUNTERS. */ -#define ipt_counters_info xt_counters_info - /* The argument to IPT_SO_GET_ENTRIES. */ struct ipt_get_entries { /* Which table: user fills this in. */ - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* User fills this in: total entry size. */ unsigned int size; @@ -211,28 +222,13 @@ struct ipt_get_entries { struct ipt_entry entrytable[0]; }; -/* Standard return verdict, or do jump. */ -#define IPT_STANDARD_TARGET XT_STANDARD_TARGET -/* Error verdict. */ -#define IPT_ERROR_TARGET XT_ERROR_TARGET - /* Helper functions */ -static __inline__ struct ipt_entry_target * +static __inline__ struct xt_entry_target * ipt_get_target(struct ipt_entry *e) { return (void *)e + e->target_offset; } -#ifndef __KERNEL__ -/* fn returns 0 to continue iteration */ -#define IPT_MATCH_ITERATE(e, fn, args...) \ - XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) - -/* fn returns 0 to continue iteration */ -#define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ - XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) -#endif - /* * Main firewall chains definitions and global var's definitions. */ @@ -249,17 +245,12 @@ extern void ipt_unregister_table(struct net *net, struct xt_table *table); /* Standard entry. */ struct ipt_standard { struct ipt_entry entry; - struct ipt_standard_target target; -}; - -struct ipt_error_target { - struct ipt_entry_target target; - char errorname[IPT_FUNCTION_MAXNAMELEN]; + struct xt_standard_target target; }; struct ipt_error { struct ipt_entry entry; - struct ipt_error_target target; + struct xt_error_target target; }; #define IPT_ENTRY_INIT(__size) \ @@ -271,7 +262,7 @@ struct ipt_error { #define IPT_STANDARD_INIT(__verdict) \ { \ .entry = IPT_ENTRY_INIT(sizeof(struct ipt_standard)), \ - .target = XT_TARGET_INIT(IPT_STANDARD_TARGET, \ + .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \ sizeof(struct xt_standard_target)), \ .target.verdict = -(__verdict) - 1, \ } @@ -279,8 +270,8 @@ struct ipt_error { #define IPT_ERROR_INIT \ { \ .entry = IPT_ENTRY_INIT(sizeof(struct ipt_error)), \ - .target = XT_TARGET_INIT(IPT_ERROR_TARGET, \ - sizeof(struct ipt_error_target)), \ + .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ + sizeof(struct xt_error_target)), \ .target.errorname = "ERROR", \ } @@ -291,8 +282,6 @@ extern unsigned int ipt_do_table(struct sk_buff *skb, const struct net_device *out, struct xt_table *table); -#define IPT_ALIGN(s) XT_ALIGN(s) - #ifdef CONFIG_COMPAT #include @@ -307,14 +296,12 @@ struct compat_ipt_entry { }; /* Helper functions */ -static inline struct ipt_entry_target * +static inline struct xt_entry_target * compat_ipt_get_target(struct compat_ipt_entry *e) { return (void *)e + e->target_offset; } -#define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s) - #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IPTABLES_H */ diff --git a/include/linux/netfilter_ipv6/ip6_tables.h b/include/linux/netfilter_ipv6/ip6_tables.h index 18442ff19c07ce1a213d5a4f81244907af8cd178..c9784f7a9c1f31675d7a64cff2246623aea495ef 100644 --- a/include/linux/netfilter_ipv6/ip6_tables.h +++ b/include/linux/netfilter_ipv6/ip6_tables.h @@ -27,13 +27,42 @@ #include +#ifndef __KERNEL__ #define IP6T_FUNCTION_MAXNAMELEN XT_FUNCTION_MAXNAMELEN #define IP6T_TABLE_MAXNAMELEN XT_TABLE_MAXNAMELEN - #define ip6t_match xt_match #define ip6t_target xt_target #define ip6t_table xt_table #define ip6t_get_revision xt_get_revision +#define ip6t_entry_match xt_entry_match +#define ip6t_entry_target xt_entry_target +#define ip6t_standard_target xt_standard_target +#define ip6t_error_target xt_error_target +#define ip6t_counters xt_counters +#define IP6T_CONTINUE XT_CONTINUE +#define IP6T_RETURN XT_RETURN + +/* Pre-iptables-1.4.0 */ +#include +#define ip6t_tcp xt_tcp +#define ip6t_udp xt_udp +#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT +#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT +#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS +#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION +#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK +#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT +#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT +#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK + +#define ip6t_counters_info xt_counters_info +#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET +#define IP6T_ERROR_TARGET XT_ERROR_TARGET +#define IP6T_MATCH_ITERATE(e, fn, args...) \ + XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) +#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ + XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) +#endif /* Yes, Virginia, you have to zero the padding. */ struct ip6t_ip6 { @@ -62,12 +91,6 @@ struct ip6t_ip6 { u_int8_t invflags; }; -#define ip6t_entry_match xt_entry_match -#define ip6t_entry_target xt_entry_target -#define ip6t_standard_target xt_standard_target - -#define ip6t_counters xt_counters - /* Values for "flag" field in struct ip6t_ip6 (general ip6 structure). */ #define IP6T_F_PROTO 0x01 /* Set if rule cares about upper protocols */ @@ -112,17 +135,12 @@ struct ip6t_entry { /* Standard entry */ struct ip6t_standard { struct ip6t_entry entry; - struct ip6t_standard_target target; -}; - -struct ip6t_error_target { - struct ip6t_entry_target target; - char errorname[IP6T_FUNCTION_MAXNAMELEN]; + struct xt_standard_target target; }; struct ip6t_error { struct ip6t_entry entry; - struct ip6t_error_target target; + struct xt_error_target target; }; #define IP6T_ENTRY_INIT(__size) \ @@ -134,16 +152,16 @@ struct ip6t_error { #define IP6T_STANDARD_INIT(__verdict) \ { \ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_standard)), \ - .target = XT_TARGET_INIT(IP6T_STANDARD_TARGET, \ - sizeof(struct ip6t_standard_target)), \ + .target = XT_TARGET_INIT(XT_STANDARD_TARGET, \ + sizeof(struct xt_standard_target)), \ .target.verdict = -(__verdict) - 1, \ } #define IP6T_ERROR_INIT \ { \ .entry = IP6T_ENTRY_INIT(sizeof(struct ip6t_error)), \ - .target = XT_TARGET_INIT(IP6T_ERROR_TARGET, \ - sizeof(struct ip6t_error_target)), \ + .target = XT_TARGET_INIT(XT_ERROR_TARGET, \ + sizeof(struct xt_error_target)), \ .target.errorname = "ERROR", \ } @@ -166,30 +184,6 @@ struct ip6t_error { #define IP6T_SO_GET_REVISION_TARGET (IP6T_BASE_CTL + 5) #define IP6T_SO_GET_MAX IP6T_SO_GET_REVISION_TARGET -/* CONTINUE verdict for targets */ -#define IP6T_CONTINUE XT_CONTINUE - -/* For standard target */ -#define IP6T_RETURN XT_RETURN - -/* TCP/UDP matching stuff */ -#include - -#define ip6t_tcp xt_tcp -#define ip6t_udp xt_udp - -/* Values for "inv" field in struct ipt_tcp. */ -#define IP6T_TCP_INV_SRCPT XT_TCP_INV_SRCPT -#define IP6T_TCP_INV_DSTPT XT_TCP_INV_DSTPT -#define IP6T_TCP_INV_FLAGS XT_TCP_INV_FLAGS -#define IP6T_TCP_INV_OPTION XT_TCP_INV_OPTION -#define IP6T_TCP_INV_MASK XT_TCP_INV_MASK - -/* Values for "invflags" field in struct ipt_udp. */ -#define IP6T_UDP_INV_SRCPT XT_UDP_INV_SRCPT -#define IP6T_UDP_INV_DSTPT XT_UDP_INV_DSTPT -#define IP6T_UDP_INV_MASK XT_UDP_INV_MASK - /* ICMP matching stuff */ struct ip6t_icmp { u_int8_t type; /* type to match */ @@ -203,7 +197,7 @@ struct ip6t_icmp { /* The argument to IP6T_SO_GET_INFO */ struct ip6t_getinfo { /* Which table: caller fills this in. */ - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Kernel fills these in. */ /* Which hook entry points are valid: bitmask */ @@ -225,7 +219,7 @@ struct ip6t_getinfo { /* The argument to IP6T_SO_SET_REPLACE. */ struct ip6t_replace { /* Which table. */ - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* Which hook entry points are valid: bitmask. You can't change this. */ @@ -253,13 +247,10 @@ struct ip6t_replace { struct ip6t_entry entries[0]; }; -/* The argument to IP6T_SO_ADD_COUNTERS. */ -#define ip6t_counters_info xt_counters_info - /* The argument to IP6T_SO_GET_ENTRIES. */ struct ip6t_get_entries { /* Which table: user fills this in. */ - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; /* User fills this in: total entry size. */ unsigned int size; @@ -268,28 +259,13 @@ struct ip6t_get_entries { struct ip6t_entry entrytable[0]; }; -/* Standard return verdict, or do jump. */ -#define IP6T_STANDARD_TARGET XT_STANDARD_TARGET -/* Error verdict. */ -#define IP6T_ERROR_TARGET XT_ERROR_TARGET - /* Helper functions */ -static __inline__ struct ip6t_entry_target * +static __inline__ struct xt_entry_target * ip6t_get_target(struct ip6t_entry *e) { return (void *)e + e->target_offset; } -#ifndef __KERNEL__ -/* fn returns 0 to continue iteration */ -#define IP6T_MATCH_ITERATE(e, fn, args...) \ - XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) - -/* fn returns 0 to continue iteration */ -#define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ - XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) -#endif - /* * Main firewall chains definitions and global var's definitions. */ @@ -316,8 +292,6 @@ extern int ip6t_ext_hdr(u8 nexthdr); extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, int target, unsigned short *fragoff); -#define IP6T_ALIGN(s) XT_ALIGN(s) - #ifdef CONFIG_COMPAT #include @@ -331,14 +305,12 @@ struct compat_ip6t_entry { unsigned char elems[0]; }; -static inline struct ip6t_entry_target * +static inline struct xt_entry_target * compat_ip6t_get_target(struct compat_ip6t_entry *e) { return (void *)e + e->target_offset; } -#define COMPAT_IP6T_ALIGN(s) COMPAT_XT_ALIGN(s) - #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IP6_TABLES_H */ diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 50d8009be86c023cbee9607cb728927ba86fb531..79358bb712c6905e474a55b09b1edae58c3a5c43 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -14,7 +14,6 @@ struct netpoll { struct net_device *dev; - struct net_device *real_dev; char dev_name[IFNAMSIZ]; const char *name; void (*rx_hook)(struct netpoll *, int, char *, int); @@ -53,7 +52,13 @@ void netpoll_set_trap(int trap); void __netpoll_cleanup(struct netpoll *np); void netpoll_cleanup(struct netpoll *np); int __netpoll_rx(struct sk_buff *skb); -void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb); +void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, + struct net_device *dev); +static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) +{ + netpoll_send_skb_on_dev(np, skb, np->dev); +} + #ifdef CONFIG_NETPOLL diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 2c8701687336c94327297274e6bf0502c5b3633c..0edb2566c14ca6602a188c422fe0a10fdc17bdff 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -39,6 +39,43 @@ * TODO: need more info? */ +/** + * DOC: Frame transmission/registration support + * + * Frame transmission and registration support exists to allow userspace + * management entities such as wpa_supplicant react to management frames + * that are not being handled by the kernel. This includes, for example, + * certain classes of action frames that cannot be handled in the kernel + * for various reasons. + * + * Frame registration is done on a per-interface basis and registrations + * cannot be removed other than by closing the socket. It is possible to + * specify a registration filter to register, for example, only for a + * certain type of action frame. In particular with action frames, those + * that userspace registers for will not be returned as unhandled by the + * driver, so that the registered application has to take responsibility + * for doing that. + * + * The type of frame that can be registered for is also dependent on the + * driver and interface type. The frame types are advertised in wiphy + * attributes so applications know what to expect. + * + * NOTE: When an interface changes type while registrations are active, + * these registrations are ignored until the interface type is + * changed again. This means that changing the interface type can + * lead to a situation that couldn't otherwise be produced, but + * any such registrations will be dormant in the sense that they + * will not be serviced, i.e. they will not receive any frames. + * + * Frame transmission allows userspace to send for example the required + * responses to action frames. It is subject to some sanity checking, + * but many frames can be transmitted. When a frame was transmitted, its + * status is indicated to the sending socket. + * + * For more technical details, see the corresponding command descriptions + * below. + */ + /** * enum nl80211_commands - supported nl80211 commands * @@ -258,7 +295,9 @@ * auth and assoc steps. For this, you need to specify the SSID in a * %NL80211_ATTR_SSID attribute, and can optionally specify the association * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC, - * %NL80211_ATTR_WIPHY_FREQ and %NL80211_ATTR_CONTROL_PORT. + * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. * It is also sent as an event, with the BSSID and response IEs when the * connection is established or failed to be established. This can be * determined by the STATUS_CODE attribute. @@ -276,8 +315,8 @@ * channel for the specified amount of time. This can be used to do * off-channel operations like transmit a Public Action frame and wait for * a response while being associated to an AP on another channel. - * %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify which - * radio is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the + * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus + * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the * frequency for the operation and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be * optionally used to specify additional channel parameters. * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds @@ -301,16 +340,20 @@ * rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface * and @NL80211_ATTR_TX_RATES the set of allowed rates. * - * @NL80211_CMD_REGISTER_ACTION: Register for receiving certain action frames - * (via @NL80211_CMD_ACTION) for processing in userspace. This command - * requires an interface index and a match attribute containing the first - * few bytes of the frame that should match, e.g. a single byte for only - * a category match or four bytes for vendor frames including the OUI. - * The registration cannot be dropped, but is removed automatically - * when the netlink socket is closed. Multiple registrations can be made. - * @NL80211_CMD_ACTION: Action frame TX request and RX notification. This - * command is used both as a request to transmit an Action frame and as an - * event indicating reception of an Action frame that was not processed in + * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames + * (via @NL80211_CMD_FRAME) for processing in userspace. This command + * requires an interface index, a frame type attribute (optional for + * backward compatibility reasons, if not given assumes action frames) + * and a match attribute containing the first few bytes of the frame + * that should match, e.g. a single byte for only a category match or + * four bytes for vendor frames including the OUI. The registration + * cannot be dropped, but is removed automatically when the netlink + * socket is closed. Multiple registrations can be made. + * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for + * backward compatibility + * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This + * command is used both as a request to transmit a management frame and + * as an event indicating reception of a frame that was not processed in * kernel code, but is for us (i.e., which may need to be processed in a * user space application). %NL80211_ATTR_FRAME is used to specify the * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and @@ -320,11 +363,14 @@ * operational channel). When called, this operation returns a cookie * (%NL80211_ATTR_COOKIE) that will be included with the TX status event * pertaining to the TX request. - * @NL80211_CMD_ACTION_TX_STATUS: Report TX status of an Action frame - * transmitted with %NL80211_CMD_ACTION. %NL80211_ATTR_COOKIE identifies + * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility. + * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame + * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies * the TX command and %NL80211_ATTR_FRAME includes the contents of the * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged * the frame. + * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for + * backward compatibility. * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command * is used to configure connection quality monitoring notification trigger * levels. @@ -341,6 +387,8 @@ * of any other interfaces, and other interfaces will again take * precedence when they are used. * + * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -429,9 +477,12 @@ enum nl80211_commands { NL80211_CMD_SET_TX_BITRATE_MASK, - NL80211_CMD_REGISTER_ACTION, - NL80211_CMD_ACTION, - NL80211_CMD_ACTION_TX_STATUS, + NL80211_CMD_REGISTER_FRAME, + NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME, + NL80211_CMD_FRAME, + NL80211_CMD_ACTION = NL80211_CMD_FRAME, + NL80211_CMD_FRAME_TX_STATUS, + NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS, NL80211_CMD_SET_POWER_SAVE, NL80211_CMD_GET_POWER_SAVE, @@ -440,6 +491,7 @@ enum nl80211_commands { NL80211_CMD_NOTIFY_CQM, NL80211_CMD_SET_CHANNEL, + NL80211_CMD_SET_WDS_PEER, /* add new commands above here */ @@ -639,6 +691,15 @@ enum nl80211_commands { * request, the driver will assume that the port is unauthorized until * authorized by user space. Otherwise, port is marked authorized by * default in station mode. + * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the + * ethertype that will be used for key negotiation. It can be + * specified with the associate and connect commands. If it is not + * specified, the value defaults to 0x888E (PAE, 802.1X). This + * attribute is also used as a flag in the wiphy information to + * indicate that protocols other than PAE are supported. + * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom + * ethertype frames used for key negotiation must not be encrypted. * * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. * We recommend using nested, driver-specific attributes within this. @@ -708,7 +769,16 @@ enum nl80211_commands { * is used with %NL80211_CMD_SET_TX_BITRATE_MASK. * * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain - * at least one byte, currently used with @NL80211_CMD_REGISTER_ACTION. + * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. + * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the + * @NL80211_CMD_REGISTER_FRAME command. + * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a + * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing + * information about which frame types can be transmitted with + * %NL80211_CMD_FRAME. + * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a + * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing + * information about which frame types can be registered for RX. * * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was * acknowledged by the recipient. @@ -731,6 +801,9 @@ enum nl80211_commands { * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING * for non-automatic settings. * + * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly + * means support for per-station GTKs. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -891,6 +964,15 @@ enum nl80211_attrs { NL80211_ATTR_WIPHY_TX_POWER_SETTING, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, + NL80211_ATTR_TX_FRAME_TYPES, + NL80211_ATTR_RX_FRAME_TYPES, + NL80211_ATTR_FRAME_TYPE, + + NL80211_ATTR_CONTROL_PORT_ETHERTYPE, + NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, + + NL80211_ATTR_SUPPORT_IBSS_RSN, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -946,8 +1028,10 @@ enum nl80211_attrs { * @NL80211_IFTYPE_WDS: wireless distribution interface * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames * @NL80211_IFTYPE_MESH_POINT: mesh point + * @NL80211_IFTYPE_P2P_CLIENT: P2P client + * @NL80211_IFTYPE_P2P_GO: P2P group owner * @NL80211_IFTYPE_MAX: highest interface type number currently defined - * @__NL80211_IFTYPE_AFTER_LAST: internal use + * @NUM_NL80211_IFTYPES: number of defined interface types * * These values are used with the %NL80211_ATTR_IFTYPE * to set the type of an interface. @@ -962,10 +1046,12 @@ enum nl80211_iftype { NL80211_IFTYPE_WDS, NL80211_IFTYPE_MONITOR, NL80211_IFTYPE_MESH_POINT, + NL80211_IFTYPE_P2P_CLIENT, + NL80211_IFTYPE_P2P_GO, /* keep last */ - __NL80211_IFTYPE_AFTER_LAST, - NL80211_IFTYPE_MAX = __NL80211_IFTYPE_AFTER_LAST - 1 + NUM_NL80211_IFTYPES, + NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 }; /** @@ -974,11 +1060,14 @@ enum nl80211_iftype { * Station flags. When a station is added to an AP interface, it is * assumed to be already associated (and hence authenticated.) * + * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X) * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames * with short barker preamble * @NL80211_STA_FLAG_WME: station is WME/QoS capable * @NL80211_STA_FLAG_MFP: station uses management frame protection + * @NL80211_STA_FLAG_MAX: highest station flag number currently defined + * @__NL80211_STA_FLAG_AFTER_LAST: internal use */ enum nl80211_sta_flags { __NL80211_STA_FLAG_INVALID, @@ -1048,6 +1137,8 @@ enum nl80211_rate_info { * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this * station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) */ enum nl80211_sta_info { __NL80211_STA_INFO_INVALID, @@ -1061,6 +1152,8 @@ enum nl80211_sta_info { NL80211_STA_INFO_TX_BITRATE, NL80211_STA_INFO_RX_PACKETS, NL80211_STA_INFO_TX_PACKETS, + NL80211_STA_INFO_TX_RETRIES, + NL80211_STA_INFO_TX_FAILED, /* keep last */ __NL80211_STA_INFO_AFTER_LAST, @@ -1091,14 +1184,17 @@ enum nl80211_mpath_flags { * information about a mesh path. * * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved - * @NL80211_ATTR_MPATH_FRAME_QLEN: number of queued frames for this destination - * @NL80211_ATTR_MPATH_SN: destination sequence number - * @NL80211_ATTR_MPATH_METRIC: metric (cost) of this mesh path - * @NL80211_ATTR_MPATH_EXPTIME: expiration time for the path, in msec from now - * @NL80211_ATTR_MPATH_FLAGS: mesh path flags, enumerated in + * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination + * @NL80211_MPATH_INFO_SN: destination sequence number + * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path + * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now + * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in * &enum nl80211_mpath_flags; - * @NL80211_ATTR_MPATH_DISCOVERY_TIMEOUT: total path discovery timeout, in msec - * @NL80211_ATTR_MPATH_DISCOVERY_RETRIES: mesh path discovery retries + * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec + * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries + * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number + * currently defind + * @__NL80211_MPATH_INFO_AFTER_LAST: internal use */ enum nl80211_mpath_info { __NL80211_MPATH_INFO_INVALID, @@ -1127,6 +1223,8 @@ enum nl80211_mpath_info { * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n + * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined + * @__NL80211_BAND_ATTR_AFTER_LAST: internal use */ enum nl80211_band_attr { __NL80211_BAND_ATTR_INVALID, @@ -1147,6 +1245,7 @@ enum nl80211_band_attr { /** * enum nl80211_frequency_attr - frequency attributes + * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current * regulatory domain. @@ -1158,6 +1257,9 @@ enum nl80211_band_attr { * on this channel in current regulatory domain. * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm * (100 * dBm). + * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number + * currently defined + * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use */ enum nl80211_frequency_attr { __NL80211_FREQUENCY_ATTR_INVALID, @@ -1177,9 +1279,13 @@ enum nl80211_frequency_attr { /** * enum nl80211_bitrate_attr - bitrate attributes + * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported * in 2.4 GHz band. + * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number + * currently defined + * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use */ enum nl80211_bitrate_attr { __NL80211_BITRATE_ATTR_INVALID, @@ -1235,6 +1341,7 @@ enum nl80211_reg_type { /** * enum nl80211_reg_rule_attr - regulatory rule attributes + * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional * considerations for a given frequency range. These are the * &enum nl80211_reg_rule_flags. @@ -1251,6 +1358,9 @@ enum nl80211_reg_type { * If you don't have one then don't send this. * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for * a given frequency range. The value is in mBm (100 * dBm). + * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number + * currently defined + * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use */ enum nl80211_reg_rule_attr { __NL80211_REG_RULE_ATTR_INVALID, @@ -1302,11 +1412,31 @@ enum nl80211_reg_rule_flags { * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) + * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used + * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio + * spent on this channel + * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary + * channel was sensed busy (either due to activity or energy detect) + * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension + * channel was sensed busy + * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent + * receiving data + * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent + * transmitting data + * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number + * currently defined + * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use */ enum nl80211_survey_info { __NL80211_SURVEY_INFO_INVALID, NL80211_SURVEY_INFO_FREQUENCY, NL80211_SURVEY_INFO_NOISE, + NL80211_SURVEY_INFO_IN_USE, + NL80211_SURVEY_INFO_CHANNEL_TIME, + NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + NL80211_SURVEY_INFO_CHANNEL_TIME_TX, /* keep last */ __NL80211_SURVEY_INFO_AFTER_LAST, @@ -1466,6 +1596,7 @@ enum nl80211_channel_type { * enum nl80211_bss - netlink attributes for a BSS * * @__NL80211_BSS_INVALID: invalid + * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets) * @NL80211_BSS_FREQUENCY: frequency in MHz (u32) * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64) * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) @@ -1509,6 +1640,12 @@ enum nl80211_bss { /** * enum nl80211_bss_status - BSS "status" + * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. + * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. + * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. + * + * The BSS status is a BSS attribute in scan dumps, which + * indicates the status the interface has wrt. this BSS. */ enum nl80211_bss_status { NL80211_BSS_STATUS_AUTHENTICATED, @@ -1546,11 +1683,14 @@ enum nl80211_auth_type { * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS) + * @NUM_NL80211_KEYTYPES: number of defined key types */ enum nl80211_key_type { NL80211_KEYTYPE_GROUP, NL80211_KEYTYPE_PAIRWISE, NL80211_KEYTYPE_PEERKEY, + + NUM_NL80211_KEYTYPES }; /** @@ -1581,6 +1721,9 @@ enum nl80211_wpa_versions { * CCMP keys, each six bytes in little endian * @NL80211_KEY_DEFAULT: flag indicating default key * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key + * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not + * specified the default depends on whether a MAC address was + * given with the command using the key or not (u32) * @__NL80211_KEY_AFTER_LAST: internal * @NL80211_KEY_MAX: highest key attribute */ @@ -1592,6 +1735,7 @@ enum nl80211_key_attributes { NL80211_KEY_SEQ, NL80211_KEY_DEFAULT, NL80211_KEY_DEFAULT_MGMT, + NL80211_KEY_TYPE, /* keep last */ __NL80211_KEY_AFTER_LAST, @@ -1619,8 +1763,8 @@ enum nl80211_tx_rate_attributes { /** * enum nl80211_band - Frequency band - * @NL80211_BAND_2GHZ - 2.4 GHz ISM band - * @NL80211_BAND_5GHZ - around 5 GHz band (4.9 - 5.7 GHz) + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) */ enum nl80211_band { NL80211_BAND_2GHZ, @@ -1658,9 +1802,9 @@ enum nl80211_attr_cqm { /** * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event - * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW - The RSSI level is lower than the + * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the * configured threshold - * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH - The RSSI is higher than the + * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the * configured threshold */ enum nl80211_cqm_rssi_threshold_event { diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e4471b27c396d12413cc96771f6fbe11d0508420..90c038c0ad96a00b0c9e38f3fb37eb5a539431f2 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2194,6 +2194,9 @@ #define PCI_VENDOR_ID_ARIMA 0x161f #define PCI_VENDOR_ID_BROCADE 0x1657 +#define PCI_DEVICE_ID_BROCADE_CT 0x0014 +#define PCI_DEVICE_ID_BROCADE_FC_8G1P 0x0017 +#define PCI_DEVICE_ID_BROCADE_CT_FC 0x0021 #define PCI_VENDOR_ID_SIBYTE 0x166d #define PCI_DEVICE_ID_BCM1250_PCI 0x0001 diff --git a/include/linux/phonet.h b/include/linux/phonet.h index 76edadf046d3d3b68215c23ef2a30ce18a86992a..26c8df7869180d4b94e4daf8b6c3b8988f7070ba 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -36,6 +36,9 @@ /* Socket options for SOL_PNPIPE level */ #define PNPIPE_ENCAP 1 #define PNPIPE_IFINDEX 2 +#define PNPIPE_PIPE_HANDLE 3 +#define PNPIPE_ENABLE 4 +/* unused slot */ #define PNADDR_ANY 0 #define PNADDR_BROADCAST 0xFC @@ -47,6 +50,8 @@ /* ioctls */ #define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0) +#define SIOCPNADDRESOURCE (SIOCPROTOPRIVATE + 14) +#define SIOCPNDELRESOURCE (SIOCPROTOPRIVATE + 15) /* Phonet protocol header */ struct phonethdr { diff --git a/include/linux/phy.h b/include/linux/phy.h index 6b0a782c6224f60d4530139a90ebc479ac6b3513..a6e047a04f798ed1ae0f75583ad7a2430b2c3958 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -116,7 +116,7 @@ struct mii_bus { /* list of all PHYs on bus */ struct phy_device *phy_map[PHY_MAX_ADDR]; - /* Phy addresses to be ignored when probing */ + /* PHY addresses to be ignored when probing */ u32 phy_mask; /* @@ -283,7 +283,7 @@ struct phy_device { phy_interface_t interface; - /* Bus address of the PHY (0-32) */ + /* Bus address of the PHY (0-31) */ int addr; /* diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 7f6ba8658abe4909d27c3699fba92332b059a1dd..defbde203d0782034d23173063a9f7313d0b2e81 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -332,6 +332,7 @@ enum { FLOW_KEY_SKUID, FLOW_KEY_SKGID, FLOW_KEY_VLAN_TAG, + FLOW_KEY_RXHASH, __FLOW_KEY_MAX, }; diff --git a/include/linux/rds.h b/include/linux/rds.h index 24bce3ded9eade070774b40a517446b62df7fce9..91950950aa598060a8e0e370f82654cd9a75e7d6 100644 --- a/include/linux/rds.h +++ b/include/linux/rds.h @@ -36,15 +36,6 @@ #include -/* These sparse annotated types shouldn't be in any user - * visible header file. We should clean this up rather - * than kludging around them. */ -#ifndef __KERNEL__ -#define __be16 u_int16_t -#define __be32 u_int32_t -#define __be64 u_int64_t -#endif - #define RDS_IB_ABI_VERSION 0x301 /* @@ -82,6 +73,10 @@ #define RDS_CMSG_RDMA_MAP 3 #define RDS_CMSG_RDMA_STATUS 4 #define RDS_CMSG_CONG_UPDATE 5 +#define RDS_CMSG_ATOMIC_FADD 6 +#define RDS_CMSG_ATOMIC_CSWP 7 +#define RDS_CMSG_MASKED_ATOMIC_FADD 8 +#define RDS_CMSG_MASKED_ATOMIC_CSWP 9 #define RDS_INFO_FIRST 10000 #define RDS_INFO_COUNTERS 10000 @@ -98,9 +93,9 @@ #define RDS_INFO_LAST 10010 struct rds_info_counter { - u_int8_t name[32]; - u_int64_t value; -} __packed; + uint8_t name[32]; + uint64_t value; +} __attribute__((packed)); #define RDS_INFO_CONNECTION_FLAG_SENDING 0x01 #define RDS_INFO_CONNECTION_FLAG_CONNECTING 0x02 @@ -109,56 +104,48 @@ struct rds_info_counter { #define TRANSNAMSIZ 16 struct rds_info_connection { - u_int64_t next_tx_seq; - u_int64_t next_rx_seq; - __be32 laddr; - __be32 faddr; - u_int8_t transport[TRANSNAMSIZ]; /* null term ascii */ - u_int8_t flags; -} __packed; - -struct rds_info_flow { + uint64_t next_tx_seq; + uint64_t next_rx_seq; __be32 laddr; __be32 faddr; - u_int32_t bytes; - __be16 lport; - __be16 fport; -} __packed; + uint8_t transport[TRANSNAMSIZ]; /* null term ascii */ + uint8_t flags; +} __attribute__((packed)); #define RDS_INFO_MESSAGE_FLAG_ACK 0x01 #define RDS_INFO_MESSAGE_FLAG_FAST_ACK 0x02 struct rds_info_message { - u_int64_t seq; - u_int32_t len; + uint64_t seq; + uint32_t len; __be32 laddr; __be32 faddr; __be16 lport; __be16 fport; - u_int8_t flags; -} __packed; + uint8_t flags; +} __attribute__((packed)); struct rds_info_socket { - u_int32_t sndbuf; + uint32_t sndbuf; __be32 bound_addr; __be32 connected_addr; __be16 bound_port; __be16 connected_port; - u_int32_t rcvbuf; - u_int64_t inum; -} __packed; + uint32_t rcvbuf; + uint64_t inum; +} __attribute__((packed)); struct rds_info_tcp_socket { __be32 local_addr; __be16 local_port; __be32 peer_addr; __be16 peer_port; - u_int64_t hdr_rem; - u_int64_t data_rem; - u_int32_t last_sent_nxt; - u_int32_t last_expected_una; - u_int32_t last_seen_una; -} __packed; + uint64_t hdr_rem; + uint64_t data_rem; + uint32_t last_sent_nxt; + uint32_t last_expected_una; + uint32_t last_seen_una; +} __attribute__((packed)); #define RDS_IB_GID_LEN 16 struct rds_info_rdma_connection { @@ -212,42 +199,69 @@ struct rds_info_rdma_connection { * (so that the application does not have to worry about * alignment). */ -typedef u_int64_t rds_rdma_cookie_t; +typedef uint64_t rds_rdma_cookie_t; struct rds_iovec { - u_int64_t addr; - u_int64_t bytes; + uint64_t addr; + uint64_t bytes; }; struct rds_get_mr_args { struct rds_iovec vec; - u_int64_t cookie_addr; + uint64_t cookie_addr; uint64_t flags; }; struct rds_get_mr_for_dest_args { struct sockaddr_storage dest_addr; struct rds_iovec vec; - u_int64_t cookie_addr; + uint64_t cookie_addr; uint64_t flags; }; struct rds_free_mr_args { rds_rdma_cookie_t cookie; - u_int64_t flags; + uint64_t flags; }; struct rds_rdma_args { rds_rdma_cookie_t cookie; struct rds_iovec remote_vec; - u_int64_t local_vec_addr; - u_int64_t nr_local; - u_int64_t flags; - u_int64_t user_token; + uint64_t local_vec_addr; + uint64_t nr_local; + uint64_t flags; + uint64_t user_token; +}; + +struct rds_atomic_args { + rds_rdma_cookie_t cookie; + uint64_t local_addr; + uint64_t remote_addr; + union { + struct { + uint64_t compare; + uint64_t swap; + } cswp; + struct { + uint64_t add; + } fadd; + struct { + uint64_t compare; + uint64_t swap; + uint64_t compare_mask; + uint64_t swap_mask; + } m_cswp; + struct { + uint64_t add; + uint64_t nocarry_mask; + } m_fadd; + }; + uint64_t flags; + uint64_t user_token; }; struct rds_rdma_notify { - u_int64_t user_token; + uint64_t user_token; int32_t status; }; @@ -266,5 +280,6 @@ struct rds_rdma_notify { #define RDS_RDMA_USE_ONCE 0x0008 /* free MR after use */ #define RDS_RDMA_DONTWAIT 0x0010 /* Don't wait in SET_BARRIER */ #define RDS_RDMA_NOTIFY_ME 0x0020 /* Notify when operation completes */ +#define RDS_RDMA_SILENT 0x0040 /* Do not interrupt remote */ #endif /* IB_RDS_H */ diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 58d44491880fa79ec30d7c863f609547c4ed7439..d42f274418b884ea72f8de09cda464af817fd774 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -6,6 +6,7 @@ #include #include #include +#include /* rtnetlink families. Values up to 127 are reserved for real address * families, values above 128 may be used arbitrarily. @@ -749,6 +750,35 @@ extern int rtnl_is_locked(void); extern int lockdep_rtnl_is_held(void); #endif /* #ifdef CONFIG_PROVE_LOCKING */ +/** + * rcu_dereference_rtnl - rcu_dereference with debug checking + * @p: The pointer to read, prior to dereferencing + * + * Do an rcu_dereference(p), but check caller either holds rcu_read_lock() + * or RTNL. Note : Please prefer rtnl_dereference() or rcu_dereference() + */ +#define rcu_dereference_rtnl(p) \ + rcu_dereference_check(p, rcu_read_lock_held() || \ + lockdep_rtnl_is_held()) + +/** + * rtnl_dereference - fetch RCU pointer when updates are prevented by RTNL + * @p: The pointer to read, prior to dereferencing + * + * Return the value of the specified RCU-protected pointer, but omit + * both the smp_read_barrier_depends() and the ACCESS_ONCE(), because + * caller holds RTNL. + */ +#define rtnl_dereference(p) \ + rcu_dereference_protected(p, lockdep_rtnl_is_held()) + +static inline struct netdev_queue *dev_ingress_queue(struct net_device *dev) +{ + return rtnl_dereference(dev->ingress_queue); +} + +extern struct netdev_queue *dev_ingress_queue_create(struct net_device *dev); + extern void rtnetlink_init(void); extern void __rtnl_unlock(void); diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 77eb60d2b496e0139a182d047077ea0b0949178e..e6ba898de61c181cea2cad515ce78cb63719136b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -129,8 +129,13 @@ typedef struct skb_frag_struct skb_frag_t; struct skb_frag_struct { struct page *page; +#if (BITS_PER_LONG > 32) || (PAGE_SIZE >= 65536) __u32 page_offset; __u32 size; +#else + __u16 page_offset; + __u16 size; +#endif }; #define HAVE_HW_TIME_STAMP @@ -163,26 +168,19 @@ struct skb_shared_hwtstamps { ktime_t syststamp; }; -/** - * struct skb_shared_tx - instructions for time stamping of outgoing packets - * @hardware: generate hardware time stamp - * @software: generate software time stamp - * @in_progress: device driver is going to provide - * hardware time stamp - * @prevent_sk_orphan: make sk reference available on driver level - * @flags: all shared_tx flags - * - * These flags are attached to packets as part of the - * &skb_shared_info. Use skb_tx() to get a pointer. - */ -union skb_shared_tx { - struct { - __u8 hardware:1, - software:1, - in_progress:1, - prevent_sk_orphan:1; - }; - __u8 flags; +/* Definitions for tx_flags in struct skb_shared_info */ +enum { + /* generate hardware time stamp */ + SKBTX_HW_TSTAMP = 1 << 0, + + /* generate software time stamp */ + SKBTX_SW_TSTAMP = 1 << 1, + + /* device driver is going to provide hardware time stamp */ + SKBTX_IN_PROGRESS = 1 << 2, + + /* ensure the originating sk reference is available on driver level */ + SKBTX_DRV_NEEDS_SK_REF = 1 << 3, }; /* This data is invariant across clones and lives at @@ -195,7 +193,7 @@ struct skb_shared_info { unsigned short gso_segs; unsigned short gso_type; __be32 ip6_frag_id; - union skb_shared_tx tx_flags; + __u8 tx_flags; struct sk_buff *frag_list; struct skb_shared_hwtstamps hwtstamps; @@ -462,19 +460,7 @@ static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) skb->_skb_refdst = (unsigned long)dst; } -/** - * skb_dst_set_noref - sets skb dst, without a reference - * @skb: buffer - * @dst: dst entry - * - * Sets skb dst, assuming a reference was not taken on dst - * skb_dst_drop() should not dst_release() this dst - */ -static inline void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst) -{ - WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); - skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF; -} +extern void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst); /** * skb_dst_is_noref - Test if skb dst isnt refcounted @@ -498,13 +484,13 @@ extern struct sk_buff *__alloc_skb(unsigned int size, static inline struct sk_buff *alloc_skb(unsigned int size, gfp_t priority) { - return __alloc_skb(size, priority, 0, -1); + return __alloc_skb(size, priority, 0, NUMA_NO_NODE); } static inline struct sk_buff *alloc_skb_fclone(unsigned int size, gfp_t priority) { - return __alloc_skb(size, priority, 1, -1); + return __alloc_skb(size, priority, 1, NUMA_NO_NODE); } extern bool skb_recycle_check(struct sk_buff *skb, int skb_size); @@ -558,6 +544,15 @@ extern unsigned int skb_find_text(struct sk_buff *skb, unsigned int from, unsigned int to, struct ts_config *config, struct ts_state *state); +extern __u32 __skb_get_rxhash(struct sk_buff *skb); +static inline __u32 skb_get_rxhash(struct sk_buff *skb) +{ + if (!skb->rxhash) + skb->rxhash = __skb_get_rxhash(skb); + + return skb->rxhash; +} + #ifdef NET_SKBUFF_DATA_USES_OFFSET static inline unsigned char *skb_end_pointer(const struct sk_buff *skb) { @@ -578,11 +573,6 @@ static inline struct skb_shared_hwtstamps *skb_hwtstamps(struct sk_buff *skb) return &skb_shinfo(skb)->hwtstamps; } -static inline union skb_shared_tx *skb_tx(struct sk_buff *skb) -{ - return &skb_shinfo(skb)->tx_flags; -} - /** * skb_queue_empty - check if a queue is empty * @list: queue head @@ -604,7 +594,7 @@ static inline int skb_queue_empty(const struct sk_buff_head *list) static inline bool skb_queue_is_last(const struct sk_buff_head *list, const struct sk_buff *skb) { - return (skb->next == (struct sk_buff *) list); + return skb->next == (struct sk_buff *)list; } /** @@ -617,7 +607,7 @@ static inline bool skb_queue_is_last(const struct sk_buff_head *list, static inline bool skb_queue_is_first(const struct sk_buff_head *list, const struct sk_buff *skb) { - return (skb->prev == (struct sk_buff *) list); + return skb->prev == (struct sk_buff *)list; } /** @@ -1123,7 +1113,7 @@ extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, int size); #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) -#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frags(skb)) +#define SKB_FRAG_ASSERT(skb) BUG_ON(skb_has_frag_list(skb)) #define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb)) #ifdef NET_SKBUFF_DATA_USES_OFFSET @@ -1561,13 +1551,25 @@ static inline struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, return skb; } -extern struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask); +/** + * __netdev_alloc_page - allocate a page for ps-rx on a specific device + * @dev: network device to receive on + * @gfp_mask: alloc_pages_node mask + * + * Allocate a new page. dev currently unused. + * + * %NULL is returned if there is no free memory. + */ +static inline struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask) +{ + return alloc_pages_node(NUMA_NO_NODE, gfp_mask, 0); +} /** * netdev_alloc_page - allocate a page for ps-rx on a specific device * @dev: network device to receive on * - * Allocate a new page node local to the specified device. + * Allocate a new page. dev currently unused. * * %NULL is returned if there is no free memory. */ @@ -1787,7 +1789,7 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) skb = skb->prev) -static inline bool skb_has_frags(const struct sk_buff *skb) +static inline bool skb_has_frag_list(const struct sk_buff *skb) { return skb_shinfo(skb)->frag_list != NULL; } @@ -1987,8 +1989,8 @@ extern void skb_tstamp_tx(struct sk_buff *orig_skb, static inline void sw_tx_timestamp(struct sk_buff *skb) { - union skb_shared_tx *shtx = skb_tx(skb); - if (shtx->software && !shtx->in_progress) + if (skb_shinfo(skb)->tx_flags & SKBTX_SW_TSTAMP && + !(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) skb_tstamp_tx(skb, NULL); } @@ -2159,7 +2161,7 @@ static inline u16 skb_get_rx_queue(const struct sk_buff *skb) static inline bool skb_rx_queue_recorded(const struct sk_buff *skb) { - return (skb->queue_mapping != 0); + return skb->queue_mapping != 0; } extern u16 skb_tx_hash(const struct net_device *dev, @@ -2209,6 +2211,21 @@ static inline void skb_forward_csum(struct sk_buff *skb) skb->ip_summed = CHECKSUM_NONE; } +/** + * skb_checksum_none_assert - make sure skb ip_summed is CHECKSUM_NONE + * @skb: skb to check + * + * fresh skbs have their ip_summed set to CHECKSUM_NONE. + * Instead of forcing ip_summed to CHECKSUM_NONE, we can + * use this helper, to document places where we make this assertion. + */ +static inline void skb_checksum_none_assert(struct sk_buff *skb) +{ +#ifdef DEBUG + BUG_ON(skb->ip_summed != CHECKSUM_NONE); +#endif +} + bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off); #endif /* __KERNEL__ */ #endif /* _LINUX_SKBUFF_H */ diff --git a/include/linux/socket.h b/include/linux/socket.h index a8f56e1ec7602705d70ca326e620f1a8927e3925..5146b50202cefabcb4604d94dd83af4bb8863ac9 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -326,7 +326,6 @@ extern long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *a extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len); extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata, int offset, int len); -extern int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, int __user *ulen); extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr); extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index a6d5225b9275e73b2d4beaf2c0017df325bb054b..11daf9c140e78f7e82a62aafff0419992abdd09a 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -97,6 +97,7 @@ #define SSB_TMSLOW_RESET 0x00000001 /* Reset */ #define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */ #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */ +#define SSB_TMSLOW_PHYCLK 0x00000010 /* MAC PHY Clock Control Enable */ #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */ #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ #define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */ diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index 632ff7c0328040f4f3ceb5dd8f06655bf05e84b5..d66c61774d954ba3866bcad34d280fc5676853be 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -32,10 +32,14 @@ struct plat_stmmacenet_data { int bus_id; int pbl; + int clk_csr; int has_gmac; int enh_desc; + int tx_coe; + int bugged_jumbo; + int pmt; void (*fix_mac_speed)(void *priv, unsigned int speed); - void (*bus_setup)(unsigned long ioaddr); + void (*bus_setup)(void __iomem *ioaddr); #ifdef CONFIG_STM_DRIVERS struct stm_pad_config *pad_config; #endif diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild index 76990937f4c9517f0aa46b86a905de58ccd95119..67b501c302b20fa3cddfd605c1e45172f02c5500 100644 --- a/include/linux/tc_act/Kbuild +++ b/include/linux/tc_act/Kbuild @@ -4,3 +4,4 @@ header-y += tc_mirred.h header-y += tc_pedit.h header-y += tc_nat.h header-y += tc_skbedit.h +header-y += tc_csum.h diff --git a/include/linux/tc_act/tc_csum.h b/include/linux/tc_act/tc_csum.h new file mode 100644 index 0000000000000000000000000000000000000000..a047c49a31531e0df45d29943216689795746584 --- /dev/null +++ b/include/linux/tc_act/tc_csum.h @@ -0,0 +1,32 @@ +#ifndef __LINUX_TC_CSUM_H +#define __LINUX_TC_CSUM_H + +#include +#include + +#define TCA_ACT_CSUM 16 + +enum { + TCA_CSUM_UNSPEC, + TCA_CSUM_PARMS, + TCA_CSUM_TM, + __TCA_CSUM_MAX +}; +#define TCA_CSUM_MAX (__TCA_CSUM_MAX - 1) + +enum { + TCA_CSUM_UPDATE_FLAG_IPV4HDR = 1, + TCA_CSUM_UPDATE_FLAG_ICMP = 2, + TCA_CSUM_UPDATE_FLAG_IGMP = 4, + TCA_CSUM_UPDATE_FLAG_TCP = 8, + TCA_CSUM_UPDATE_FLAG_UDP = 16, + TCA_CSUM_UPDATE_FLAG_UDPLITE = 32 +}; + +struct tc_csum { + tc_gen; + + __u32 update_flags; +}; + +#endif /* __LINUX_TC_CSUM_H */ diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index 0864206ec1a331b2aadacef8fa4a7fae4f3aa47e..7138962664f81912b974c29c12900606ae07306a 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h @@ -79,6 +79,7 @@ enum { TCF_META_ID_SK_SENDMSG_OFF, TCF_META_ID_SK_WRITE_PENDING, TCF_META_ID_VLAN_TAG, + TCF_META_ID_RXHASH, __TCF_META_ID_MAX }; #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index a778ee024590dafb3357caed05da1cb1f6133821..e64f4c67d0ef7d4dcf65232bd58f9de2b5cb86d4 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -105,6 +105,7 @@ enum { #define TCP_COOKIE_TRANSACTIONS 15 /* TCP Cookie Transactions */ #define TCP_THIN_LINEAR_TIMEOUTS 16 /* Use linear timeouts for thin streams*/ #define TCP_THIN_DUPACK 17 /* Fast retrans. after 1 dupack */ +#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */ /* for TCP_INFO socket option */ #define TCPI_OPT_TIMESTAMPS 1 diff --git a/include/linux/tipc.h b/include/linux/tipc.h index 181c8d0e6f739fbfd091876c0726206491b8b1cd..d10614b29d592a4df809aa40a904c39fe3f33340 100644 --- a/include/linux/tipc.h +++ b/include/linux/tipc.h @@ -127,17 +127,23 @@ static inline unsigned int tipc_node(__u32 addr) * TIPC topology subscription service definitions */ -#define TIPC_SUB_SERVICE 0x00 /* Filter for service availability */ -#define TIPC_SUB_PORTS 0x01 /* Filter for port availability */ -#define TIPC_SUB_CANCEL 0x04 /* Cancel a subscription */ +#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ +#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ +#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ +#if 0 +/* The following filter options are not currently implemented */ +#define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */ +#define TIPC_SUB_NO_UNBIND_EVTS 0x08 /* filter out "withdraw" events */ +#define TIPC_SUB_SINGLE_EVT 0x10 /* expire after first event */ +#endif #define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */ struct tipc_subscr { - struct tipc_name_seq seq; /* NBO. Name sequence of interest */ - __u32 timeout; /* NBO. Subscription duration (in ms) */ - __u32 filter; /* NBO. Bitmask of filter options */ - char usr_handle[8]; /* Opaque. Available for subscriber use */ + struct tipc_name_seq seq; /* name sequence of interest */ + __u32 timeout; /* subscription duration (in ms) */ + __u32 filter; /* bitmask of filter options */ + char usr_handle[8]; /* available for subscriber use */ }; #define TIPC_PUBLISHED 1 /* publication event */ @@ -145,11 +151,11 @@ struct tipc_subscr { #define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */ struct tipc_event { - __u32 event; /* NBO. Event type, as defined above */ - __u32 found_lower; /* NBO. Matching name seq instances */ - __u32 found_upper; /* " " " " " */ - struct tipc_portid port; /* NBO. Associated port */ - struct tipc_subscr s; /* Original, associated subscription */ + __u32 event; /* event type */ + __u32 found_lower; /* matching name seq instances */ + __u32 found_upper; /* " " " " */ + struct tipc_portid port; /* associated port */ + struct tipc_subscr s; /* associated subscription */ }; /* diff --git a/include/linux/wireless.h b/include/linux/wireless.h index e6827eedf18bc4934f0f6b47e7b7a7c4de76f0df..4395b28bb86c3bc2db796c284eec108fb4baab4c 100644 --- a/include/linux/wireless.h +++ b/include/linux/wireless.h @@ -1157,6 +1157,6 @@ struct __compat_iw_event { #define IW_EV_PARAM_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_param)) #define IW_EV_ADDR_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct sockaddr)) #define IW_EV_QUAL_PK_LEN (IW_EV_LCP_PK_LEN + sizeof(struct iw_quality)) -#define IW_EV_POINT_PK_LEN (IW_EV_LCP_LEN + 4) +#define IW_EV_POINT_PK_LEN (IW_EV_LCP_PK_LEN + 4) #endif /* _LINUX_WIRELESS_H */ diff --git a/include/linux/spi/wl12xx.h b/include/linux/wl12xx.h similarity index 68% rename from include/linux/spi/wl12xx.h rename to include/linux/wl12xx.h index a223ecbc71eff8160c0c0b96921cd4e81e0e9d4f..4f902e1908aaa191095c2f90741f96679b4b3113 100644 --- a/include/linux/spi/wl12xx.h +++ b/include/linux/wl12xx.h @@ -3,7 +3,7 @@ * * Copyright (C) 2009 Nokia Corporation * - * Contact: Kalle Valo + * Contact: Luciano Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,14 +21,31 @@ * */ -#ifndef _LINUX_SPI_WL12XX_H -#define _LINUX_SPI_WL12XX_H +#ifndef _LINUX_WL12XX_H +#define _LINUX_WL12XX_H struct wl12xx_platform_data { void (*set_power)(bool enable); /* SDIO only: IRQ number if WLAN_IRQ line is used, 0 for SDIO IRQs */ int irq; bool use_eeprom; + int board_ref_clock; }; +#ifdef CONFIG_WL12XX_PLATFORM_DATA + +int wl12xx_set_platform_data(const struct wl12xx_platform_data *data); + +#else + +static inline +int wl12xx_set_platform_data(const struct wl12xx_platform_data *data) +{ + return -ENOSYS; +} + +#endif + +const struct wl12xx_platform_data *wl12xx_get_platform_data(void); + #endif diff --git a/include/net/9p/client.h b/include/net/9p/client.h index d1aa2cfb30f0f46b915e55118a29e7a8e91fe7e7..7f63d5ab7b44e21dba3a40476ed231438ebe9187 100644 --- a/include/net/9p/client.h +++ b/include/net/9p/client.h @@ -212,15 +212,12 @@ struct p9_dirent { int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb); int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name); -int p9_client_version(struct p9_client *); struct p9_client *p9_client_create(const char *dev_name, char *options); void p9_client_destroy(struct p9_client *clnt); void p9_client_disconnect(struct p9_client *clnt); void p9_client_begin_disconnect(struct p9_client *clnt); struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, char *uname, u32 n_uname, char *aname); -struct p9_fid *p9_client_auth(struct p9_client *clnt, char *uname, - u32 n_uname, char *aname); struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int clone); int p9_client_open(struct p9_fid *fid, int mode); diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 4d40c4d0230baeffbafcb57cb6fac99a1f0174b3..a9441249306c4847f6f641ae320110ebd86f3694 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -175,20 +175,32 @@ extern int ipv6_chk_acast_addr(struct net *net, struct net_device *dev, extern int register_inet6addr_notifier(struct notifier_block *nb); extern int unregister_inet6addr_notifier(struct notifier_block *nb); -static inline struct inet6_dev * -__in6_dev_get(struct net_device *dev) +/** + * __in6_dev_get - get inet6_dev pointer from netdevice + * @dev: network device + * + * Caller must hold rcu_read_lock or RTNL, because this function + * does not take a reference on the inet6_dev. + */ +static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev) { - return rcu_dereference_check(dev->ip6_ptr, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + return rcu_dereference_rtnl(dev->ip6_ptr); } -static inline struct inet6_dev * -in6_dev_get(struct net_device *dev) +/** + * in6_dev_get - get inet6_dev pointer from netdevice + * @dev: network device + * + * This version can be used in any context, and takes a reference + * on the inet6_dev. Callers must use in6_dev_put() later to + * release this reference. + */ +static inline struct inet6_dev *in6_dev_get(const struct net_device *dev) { - struct inet6_dev *idev = NULL; + struct inet6_dev *idev; + rcu_read_lock(); - idev = __in6_dev_get(dev); + idev = rcu_dereference(dev->ip6_ptr); if (idev) atomic_inc(&idev->refcnt); rcu_read_unlock(); @@ -197,16 +209,21 @@ in6_dev_get(struct net_device *dev) extern void in6_dev_finish_destroy(struct inet6_dev *idev); -static inline void -in6_dev_put(struct inet6_dev *idev) +static inline void in6_dev_put(struct inet6_dev *idev) { if (atomic_dec_and_test(&idev->refcnt)) in6_dev_finish_destroy(idev); } -#define __in6_dev_put(idev) atomic_dec(&(idev)->refcnt) -#define in6_dev_hold(idev) atomic_inc(&(idev)->refcnt) +static inline void __in6_dev_put(struct inet6_dev *idev) +{ + atomic_dec(&idev->refcnt); +} +static inline void in6_dev_hold(struct inet6_dev *idev) +{ + atomic_inc(&idev->refcnt); +} extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp); @@ -216,9 +233,15 @@ static inline void in6_ifa_put(struct inet6_ifaddr *ifp) inet6_ifa_finish_destroy(ifp); } -#define __in6_ifa_put(ifp) atomic_dec(&(ifp)->refcnt) -#define in6_ifa_hold(ifp) atomic_inc(&(ifp)->refcnt) +static inline void __in6_ifa_put(struct inet6_ifaddr *ifp) +{ + atomic_dec(&ifp->refcnt); +} +static inline void in6_ifa_hold(struct inet6_ifaddr *ifp) +{ + atomic_inc(&ifp->refcnt); +} /* @@ -241,23 +264,21 @@ static inline int ipv6_addr_is_multicast(const struct in6_addr *addr) static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr) { - return (((addr->s6_addr32[0] ^ htonl(0xff020000)) | + return ((addr->s6_addr32[0] ^ htonl(0xff020000)) | addr->s6_addr32[1] | addr->s6_addr32[2] | - (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0); + (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0; } static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr) { - return (((addr->s6_addr32[0] ^ htonl(0xff020000)) | + return ((addr->s6_addr32[0] ^ htonl(0xff020000)) | addr->s6_addr32[1] | addr->s6_addr32[2] | - (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0); + (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0; } -extern int __ipv6_isatap_ifid(u8 *eui, __be32 addr); - static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) { - return ((addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE)); + return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE); } #ifdef CONFIG_PROC_FS diff --git a/include/net/arp.h b/include/net/arp.h index 716f43c5c98eb92061cc2eb416c270ea8c68cd4a..f4cf6ce66586e03164703575283af6354de12385 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -26,6 +26,4 @@ extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, const unsigned char *target_hw); extern void arp_xmit(struct sk_buff *skb); -extern const struct neigh_ops arp_broken_ops; - #endif /* _ARP_H */ diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 30fce0128dd72fa0281795bc0ae03809b85bc9d0..d81ea799770196be373d3304c25a7837097479a0 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -126,6 +126,8 @@ int bt_sock_unregister(int proto); void bt_sock_link(struct bt_sock_list *l, struct sock *s); void bt_sock_unlink(struct bt_sock_list *l, struct sock *s); int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); +int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t len, int flags); uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index bcbdd6d4e6dd43f1dfb4196a5eb3998309cf5909..e30e00834340a1330e373d7397fadbbccb1f035f 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -54,7 +54,7 @@ /* HCI controller types */ #define HCI_BREDR 0x00 -#define HCI_80211 0x01 +#define HCI_AMP 0x01 /* HCI device quirks */ enum { diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 4568b938ca35ab56062ba202c0294df37dae037d..ebec8c9a929dce74d022f16dcf02aa56a17ac640 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -233,7 +233,7 @@ static inline void inquiry_cache_init(struct hci_dev *hdev) static inline int inquiry_cache_empty(struct hci_dev *hdev) { struct inquiry_cache *c = &hdev->inq_cache; - return (c->list == NULL); + return c->list == NULL; } static inline long inquiry_cache_age(struct hci_dev *hdev) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 6c241444f902800baf1c4cd16aa89d767d751065..c819c8bf9b68345b3f448fbaa2e6d19a189e5e86 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -414,7 +414,7 @@ static inline int l2cap_tx_window_full(struct sock *sk) if (sub < 0) sub += 64; - return (sub == pi->remote_tx_win); + return sub == pi->remote_tx_win; } #define __get_txseq(ctrl) ((ctrl) & L2CAP_CTRL_TXSEQ) >> 1 diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index a140847d622c4e5ad4dc252bd117a0d2e1861efe..71047bc0af842a2b72f379096d8baaf84234f16e 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -213,11 +213,6 @@ struct rfcomm_dlc { #define RFCOMM_DEFER_SETUP 8 /* Scheduling flags and events */ -#define RFCOMM_SCHED_STATE 0 -#define RFCOMM_SCHED_RX 1 -#define RFCOMM_SCHED_TX 2 -#define RFCOMM_SCHED_TIMEO 3 -#define RFCOMM_SCHED_AUTH 4 #define RFCOMM_SCHED_WAKEUP 31 /* MSC exchange flags */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 2fd06c60ffbba1b81af86303d46e5187f98e946d..2a7936d7851d55de60251fc708672a87d5beb81b 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -25,6 +25,43 @@ #include +/** + * DOC: Introduction + * + * cfg80211 is the configuration API for 802.11 devices in Linux. It bridges + * userspace and drivers, and offers some utility functionality associated + * with 802.11. cfg80211 must, directly or indirectly via mac80211, be used + * by all modern wireless drivers in Linux, so that they offer a consistent + * API through nl80211. For backward compatibility, cfg80211 also offers + * wireless extensions to userspace, but hides them from drivers completely. + * + * Additionally, cfg80211 contains code to help enforce regulatory spectrum + * use restrictions. + */ + + +/** + * DOC: Device registration + * + * In order for a driver to use cfg80211, it must register the hardware device + * with cfg80211. This happens through a number of hardware capability structs + * described below. + * + * The fundamental structure for each device is the 'wiphy', of which each + * instance describes a physical wireless device connected to the system. Each + * such wiphy can have zero, one, or many virtual interfaces associated with + * it, which need to be identified as such by pointing the network interface's + * @ieee80211_ptr pointer to a &struct wireless_dev which further describes + * the wireless part of the interface, normally this struct is embedded in the + * network interface's private data area. Drivers can optionally allow creating + * or destroying virtual interfaces on the fly, but without at least one or the + * ability to create some the wireless device isn't useful. + * + * Each wiphy structure contains device capability information, and also has + * a pointer to the various operations the driver offers. The definitions and + * structures here describe these capabilities in detail. + */ + /* * wireless hardware capability structures */ @@ -204,6 +241,21 @@ struct ieee80211_supported_band { * Wireless hardware/device configuration structures and methods */ +/** + * DOC: Actions and configuration + * + * Each wireless device and each virtual interface offer a set of configuration + * operations and other actions that are invoked by userspace. Each of these + * actions is described in the operations structure, and the parameters these + * operations use are described separately. + * + * Additionally, some operations are asynchronous and expect to get status + * information via some functions that drivers need to call. + * + * Scanning and BSS list handling with its associated functionality is described + * in a separate chapter. + */ + /** * struct vif_params - describes virtual interface parameters * @mesh_id: mesh ID to use @@ -241,12 +293,24 @@ struct key_params { * enum survey_info_flags - survey information flags * * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in + * @SURVEY_INFO_IN_USE: channel is currently being used + * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in + * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in + * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in + * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in + * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in * * Used by the driver to indicate which info in &struct survey_info * it has filled in during the get_survey(). */ enum survey_info_flags { SURVEY_INFO_NOISE_DBM = 1<<0, + SURVEY_INFO_IN_USE = 1<<1, + SURVEY_INFO_CHANNEL_TIME = 1<<2, + SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3, + SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4, + SURVEY_INFO_CHANNEL_TIME_RX = 1<<5, + SURVEY_INFO_CHANNEL_TIME_TX = 1<<6, }; /** @@ -256,6 +320,11 @@ enum survey_info_flags { * @filled: bitflag of flags from &enum survey_info_flags * @noise: channel noise in dBm. This and all following fields are * optional + * @channel_time: amount of time in ms the radio spent on the channel + * @channel_time_busy: amount of time the primary channel was sensed busy + * @channel_time_ext_busy: amount of time the extension channel was sensed busy + * @channel_time_rx: amount of time the radio spent receiving data + * @channel_time_tx: amount of time the radio spent transmitting data * * Used by dump_survey() to report back per-channel survey information. * @@ -264,6 +333,11 @@ enum survey_info_flags { */ struct survey_info { struct ieee80211_channel *channel; + u64 channel_time; + u64 channel_time_busy; + u64 channel_time_ext_busy; + u64 channel_time_rx; + u64 channel_time_tx; u32 filled; s8 noise; }; @@ -347,6 +421,9 @@ struct station_parameters { * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) * @STATION_INFO_RX_PACKETS: @rx_packets filled * @STATION_INFO_TX_PACKETS: @tx_packets filled + * @STATION_INFO_TX_RETRIES: @tx_retries filled + * @STATION_INFO_TX_FAILED: @tx_failed filled + * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled */ enum station_info_flags { STATION_INFO_INACTIVE_TIME = 1<<0, @@ -359,6 +436,9 @@ enum station_info_flags { STATION_INFO_TX_BITRATE = 1<<7, STATION_INFO_RX_PACKETS = 1<<8, STATION_INFO_TX_PACKETS = 1<<9, + STATION_INFO_TX_RETRIES = 1<<10, + STATION_INFO_TX_FAILED = 1<<11, + STATION_INFO_RX_DROP_MISC = 1<<12, }; /** @@ -408,6 +488,9 @@ struct rate_info { * @txrate: current unicast bitrate to this station * @rx_packets: packets received from this station * @tx_packets: packets transmitted to this station + * @tx_retries: cumulative retry counts + * @tx_failed: number of failed transmissions (retries exceeded, no ACK) + * @rx_dropped_misc: Dropped for un-specified reason. * @generation: generation number for nl80211 dumps. * This number should increase every time the list of stations * changes, i.e. when a station is added or removed, so that @@ -425,6 +508,9 @@ struct station_info { struct rate_info txrate; u32 rx_packets; u32 tx_packets; + u32 tx_retries; + u32 tx_failed; + u32 rx_dropped_misc; int generation; }; @@ -570,8 +656,28 @@ struct ieee80211_txq_params { /* from net/wireless.h */ struct wiphy; -/* from net/ieee80211.h */ -struct ieee80211_channel; +/** + * DOC: Scanning and BSS list handling + * + * The scanning process itself is fairly simple, but cfg80211 offers quite + * a bit of helper functionality. To start a scan, the scan operation will + * be invoked with a scan definition. This scan definition contains the + * channels to scan, and the SSIDs to send probe requests for (including the + * wildcard, if desired). A passive scan is indicated by having no SSIDs to + * probe. Additionally, a scan request may contain extra information elements + * that should be added to the probe request. The IEs are guaranteed to be + * well-formed, and will not exceed the maximum length the driver advertised + * in the wiphy structure. + * + * When scanning finds a BSS, cfg80211 needs to be notified of that, because + * it is responsible for maintaining the BSS list; the driver should not + * maintain a list itself. For this notification, various functions exist. + * + * Since drivers do not maintain a BSS list, there are also a number of + * functions to search for a BSS and obtain information about it from the + * BSS structure cfg80211 maintains. The BSS list is also made available + * to userspace. + */ /** * struct cfg80211_ssid - SSID description @@ -691,6 +797,10 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is * required to assume that the port is unauthorized until authorized by * user space. Otherwise, port is marked authorized by default. + * @control_port_ethertype: the control port protocol that should be + * allowed through even on unauthorized ports + * @control_port_no_encrypt: TRUE to prevent encryption of control port + * protocol frames. */ struct cfg80211_crypto_settings { u32 wpa_versions; @@ -700,6 +810,8 @@ struct cfg80211_crypto_settings { int n_akm_suites; u32 akm_suites[NL80211_MAX_NR_AKM_SUITES]; bool control_port; + __be16 control_port_ethertype; + bool control_port_no_encrypt; }; /** @@ -1020,7 +1132,7 @@ struct cfg80211_pmksa { * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation. * This allows the operation to be terminated prior to timeout based on * the duration value. - * @action: Transmit an action frame + * @mgmt_tx: Transmit a management frame * * @testmode_cmd: run a test mode command * @@ -1035,6 +1147,9 @@ struct cfg80211_pmksa { * allows the driver to adjust the dynamic ps timeout value. * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. * + * @mgmt_frame_register: Notify driver that a management frame type was + * registered. Note that this callback may not sleep, and cannot run + * concurrently with itself. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy); @@ -1050,13 +1165,14 @@ struct cfg80211_ops { struct vif_params *params); int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr, + u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params); int (*get_key)(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr, void *cookie, + u8 key_index, bool pairwise, const u8 *mac_addr, + void *cookie, void (*callback)(void *cookie, struct key_params*)); int (*del_key)(struct wiphy *wiphy, struct net_device *netdev, - u8 key_index, const u8 *mac_addr); + u8 key_index, bool pairwise, const u8 *mac_addr); int (*set_default_key)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); @@ -1140,7 +1256,7 @@ struct cfg80211_ops { int (*get_tx_power)(struct wiphy *wiphy, int *dbm); int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, - u8 *addr); + const u8 *addr); void (*rfkill_poll)(struct wiphy *wiphy); @@ -1172,7 +1288,7 @@ struct cfg80211_ops { struct net_device *dev, u64 cookie); - int (*action)(struct wiphy *wiphy, struct net_device *dev, + int (*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type, bool channel_type_valid, @@ -1184,6 +1300,10 @@ struct cfg80211_ops { int (*set_cqm_rssi_config)(struct wiphy *wiphy, struct net_device *dev, s32 rssi_thold, u32 rssi_hyst); + + void (*mgmt_frame_register)(struct wiphy *wiphy, + struct net_device *dev, + u16 frame_type, bool reg); }; /* @@ -1221,21 +1341,31 @@ struct cfg80211_ops { * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station * on a VLAN interface) * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station + * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the + * control port protocol ethertype. The device also honours the + * control_port_no_encrypt flag. + * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. */ enum wiphy_flags { - WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), - WIPHY_FLAG_STRICT_REGULATORY = BIT(1), - WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), - WIPHY_FLAG_NETNS_OK = BIT(3), - WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), - WIPHY_FLAG_4ADDR_AP = BIT(5), - WIPHY_FLAG_4ADDR_STATION = BIT(6), + WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), + WIPHY_FLAG_STRICT_REGULATORY = BIT(1), + WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), + WIPHY_FLAG_NETNS_OK = BIT(3), + WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), + WIPHY_FLAG_4ADDR_AP = BIT(5), + WIPHY_FLAG_4ADDR_STATION = BIT(6), + WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), + WIPHY_FLAG_IBSS_RSN = BIT(7), }; struct mac_address { u8 addr[ETH_ALEN]; }; +struct ieee80211_txrx_stypes { + u16 tx, rx; +}; + /** * struct wiphy - wireless hardware description * @reg_notifier: the driver's regulatory notification callback @@ -1286,6 +1416,10 @@ struct mac_address { * @privid: a pointer that drivers can use to identify if an arbitrary * wiphy is theirs, e.g. in global notifiers * @bands: information about bands/channels supported by this device + * + * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or + * transmitted through nl80211, points to an array indexed by interface + * type */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -1294,9 +1428,12 @@ struct wiphy { u8 perm_addr[ETH_ALEN]; u8 addr_mask[ETH_ALEN]; - u16 n_addresses; struct mac_address *addresses; + const struct ieee80211_txrx_stypes *mgmt_stypes; + + u16 n_addresses; + /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ u16 interface_modes; @@ -1492,8 +1629,8 @@ struct cfg80211_cached_keys; * set by driver (if supported) on add_interface BEFORE registering the * netdev and may otherwise be used by driver read-only, will be update * by cfg80211 on change_interface - * @action_registrations: list of registrations for action frames - * @action_registrations_lock: lock for the list + * @mgmt_registrations: list of registrations for management frames + * @mgmt_registrations_lock: lock for the list * @mtx: mutex used to lock data in this struct * @cleanup_work: work struct used for cleanup that can't be done directly */ @@ -1505,8 +1642,8 @@ struct wireless_dev { struct list_head list; struct net_device *netdev; - struct list_head action_registrations; - spinlock_t action_registrations_lock; + struct list_head mgmt_registrations; + spinlock_t mgmt_registrations_lock; struct mutex mtx; @@ -1563,8 +1700,10 @@ static inline void *wdev_priv(struct wireless_dev *wdev) return wiphy_priv(wdev->wiphy); } -/* - * Utility functions +/** + * DOC: Utility functions + * + * cfg80211 offers a number of utility functions that can be useful. */ /** @@ -1715,7 +1854,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); * ieee80211_hdrlen - get header length in bytes from frame control * @fc: frame control field in little-endian format */ -unsigned int ieee80211_hdrlen(__le16 fc); +unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); + +/** + * DOC: Data path helpers + * + * In addition to generic utilities, cfg80211 also offers + * functions that help implement the data path for devices + * that do not do the 802.11/802.3 conversion on the device. + */ /** * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 @@ -1777,8 +1924,10 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb); */ const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len); -/* - * Regulatory helper functions for wiphys +/** + * DOC: Regulatory enforcement infrastructure + * + * TODO */ /** @@ -2180,6 +2329,20 @@ void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, */ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); +/** + * DOC: RFkill integration + * + * RFkill integration in cfg80211 is almost invisible to drivers, + * as cfg80211 automatically registers an rfkill instance for each + * wireless device it knows about. Soft kill is also translated + * into disconnecting and turning all interfaces off, drivers are + * expected to turn off the device when all interfaces are down. + * + * However, devices may have a hard RFkill line, in which case they + * also need to interact with the rfkill subsystem, via cfg80211. + * They can do this with a few helper functions documented here. + */ + /** * wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state * @wiphy: the wiphy @@ -2200,6 +2363,17 @@ void wiphy_rfkill_start_polling(struct wiphy *wiphy); void wiphy_rfkill_stop_polling(struct wiphy *wiphy); #ifdef CONFIG_NL80211_TESTMODE +/** + * DOC: Test mode + * + * Test mode is a set of utility functions to allow drivers to + * interact with driver-specific tools to aid, for instance, + * factory programming. + * + * This chapter describes how drivers interact with it, for more + * information see the nl80211 book's chapter on it. + */ + /** * cfg80211_testmode_alloc_reply_skb - allocate testmode reply * @wiphy: the wiphy @@ -2373,38 +2547,39 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo, gfp_t gfp); /** - * cfg80211_rx_action - notification of received, unprocessed Action frame + * cfg80211_rx_mgmt - notification of received, unprocessed management frame * @dev: network device * @freq: Frequency on which the frame was received in MHz - * @buf: Action frame (header + body) + * @buf: Management frame (header + body) * @len: length of the frame data * @gfp: context flags - * Returns %true if a user space application is responsible for rejecting the - * unrecognized Action frame; %false if no such application is registered - * (i.e., the driver is responsible for rejecting the unrecognized Action - * frame) + * + * Returns %true if a user space application has registered for this frame. + * For action frames, that makes it responsible for rejecting unrecognized + * action frames; %false otherwise, in which case for action frames the + * driver is responsible for rejecting the frame. * * This function is called whenever an Action frame is received for a station * mode interface, but is not processed in kernel. */ -bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf, - size_t len, gfp_t gfp); +bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, + size_t len, gfp_t gfp); /** - * cfg80211_action_tx_status - notification of TX status for Action frame + * cfg80211_mgmt_tx_status - notification of TX status for management frame * @dev: network device - * @cookie: Cookie returned by cfg80211_ops::action() - * @buf: Action frame (header + body) + * @cookie: Cookie returned by cfg80211_ops::mgmt_tx() + * @buf: Management frame (header + body) * @len: length of the frame data * @ack: Whether frame was acknowledged * @gfp: context flags * - * This function is called whenever an Action frame was requested to be - * transmitted with cfg80211_ops::action() to report the TX status of the + * This function is called whenever a management frame was requested to be + * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the * transmission attempt. */ -void cfg80211_action_tx_status(struct net_device *dev, u64 cookie, - const u8 *buf, size_t len, bool ack, gfp_t gfp); +void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie, + const u8 *buf, size_t len, bool ack, gfp_t gfp); /** @@ -2420,56 +2595,41 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, enum nl80211_cqm_rssi_threshold_event rssi_event, gfp_t gfp); -#ifdef __KERNEL__ - /* Logging, debugging and troubleshooting/diagnostic helpers. */ /* wiphy_printk helpers, similar to dev_printk */ #define wiphy_printk(level, wiphy, format, args...) \ - printk(level "%s: " format, wiphy_name(wiphy), ##args) + dev_printk(level, &(wiphy)->dev, format, ##args) #define wiphy_emerg(wiphy, format, args...) \ - wiphy_printk(KERN_EMERG, wiphy, format, ##args) + dev_emerg(&(wiphy)->dev, format, ##args) #define wiphy_alert(wiphy, format, args...) \ - wiphy_printk(KERN_ALERT, wiphy, format, ##args) + dev_alert(&(wiphy)->dev, format, ##args) #define wiphy_crit(wiphy, format, args...) \ - wiphy_printk(KERN_CRIT, wiphy, format, ##args) + dev_crit(&(wiphy)->dev, format, ##args) #define wiphy_err(wiphy, format, args...) \ - wiphy_printk(KERN_ERR, wiphy, format, ##args) + dev_err(&(wiphy)->dev, format, ##args) #define wiphy_warn(wiphy, format, args...) \ - wiphy_printk(KERN_WARNING, wiphy, format, ##args) + dev_warn(&(wiphy)->dev, format, ##args) #define wiphy_notice(wiphy, format, args...) \ - wiphy_printk(KERN_NOTICE, wiphy, format, ##args) + dev_notice(&(wiphy)->dev, format, ##args) #define wiphy_info(wiphy, format, args...) \ - wiphy_printk(KERN_INFO, wiphy, format, ##args) + dev_info(&(wiphy)->dev, format, ##args) -int wiphy_debug(const struct wiphy *wiphy, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); - -#if defined(DEBUG) -#define wiphy_dbg(wiphy, format, args...) \ +#define wiphy_debug(wiphy, format, args...) \ wiphy_printk(KERN_DEBUG, wiphy, format, ##args) -#elif defined(CONFIG_DYNAMIC_DEBUG) + #define wiphy_dbg(wiphy, format, args...) \ - dynamic_pr_debug("%s: " format, wiphy_name(wiphy), ##args) -#else -#define wiphy_dbg(wiphy, format, args...) \ -({ \ - if (0) \ - wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ - 0; \ -}) -#endif + dev_dbg(&(wiphy)->dev, format, ##args) #if defined(VERBOSE_DEBUG) #define wiphy_vdbg wiphy_dbg #else - #define wiphy_vdbg(wiphy, format, args...) \ ({ \ if (0) \ wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ - 0; \ + 0; \ }) #endif @@ -2481,6 +2641,4 @@ int wiphy_debug(const struct wiphy *wiphy, const char *format, ...) #define wiphy_WARN(wiphy, format, args...) \ WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args); -#endif - #endif /* __NET_CFG80211_H */ diff --git a/include/net/dst.h b/include/net/dst.h index 02386505033d975e666cd924a3bafe3ca02bb100..a217c838ec0dc649463a999c5c4d55cf6d53585d 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -43,10 +43,11 @@ struct dst_entry { short error; short obsolete; int flags; -#define DST_HOST 1 -#define DST_NOXFRM 2 -#define DST_NOPOLICY 4 -#define DST_NOHASH 8 +#define DST_HOST 0x0001 +#define DST_NOXFRM 0x0002 +#define DST_NOPOLICY 0x0004 +#define DST_NOHASH 0x0008 +#define DST_NOCACHE 0x0010 unsigned long expires; unsigned short header_len; /* more space at head required */ @@ -227,6 +228,23 @@ static inline void skb_dst_force(struct sk_buff *skb) } +/** + * __skb_tunnel_rx - prepare skb for rx reinsert + * @skb: buffer + * @dev: tunnel device + * + * After decapsulation, packet is going to re-enter (netif_rx()) our stack, + * so make some cleanups. (no accounting done) + */ +static inline void __skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) +{ + skb->dev = dev; + skb->rxhash = 0; + skb_set_queue_mapping(skb, 0); + skb_dst_drop(skb); + nf_reset(skb); +} + /** * skb_tunnel_rx - prepare skb for rx reinsert * @skb: buffer @@ -234,17 +252,14 @@ static inline void skb_dst_force(struct sk_buff *skb) * * After decapsulation, packet is going to re-enter (netif_rx()) our stack, * so make some cleanups, and perform accounting. + * Note: this accounting is not SMP safe. */ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) { - skb->dev = dev; /* TODO : stats should be SMP safe */ dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; - skb->rxhash = 0; - skb_set_queue_mapping(skb, 0); - skb_dst_drop(skb); - nf_reset(skb); + __skb_tunnel_rx(skb, dev); } /* Children define the path of the packet through the diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index d1ff9b7e99b80fd0ef4a3a6405be2f42a0ea1b62..1fa5306e3e230d8340b3d01fb5ce5f99a679a6fd 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h @@ -1,6 +1,7 @@ #ifndef _NET_DST_OPS_H #define _NET_DST_OPS_H #include +#include struct dst_entry; struct kmem_cachep; @@ -22,7 +23,41 @@ struct dst_ops { void (*update_pmtu)(struct dst_entry *dst, u32 mtu); int (*local_out)(struct sk_buff *skb); - atomic_t entries; struct kmem_cache *kmem_cachep; + + struct percpu_counter pcpuc_entries ____cacheline_aligned_in_smp; }; + +static inline int dst_entries_get_fast(struct dst_ops *dst) +{ + return percpu_counter_read_positive(&dst->pcpuc_entries); +} + +static inline int dst_entries_get_slow(struct dst_ops *dst) +{ + int res; + + local_bh_disable(); + res = percpu_counter_sum_positive(&dst->pcpuc_entries); + local_bh_enable(); + return res; +} + +static inline void dst_entries_add(struct dst_ops *dst, int val) +{ + local_bh_disable(); + percpu_counter_add(&dst->pcpuc_entries, val); + local_bh_enable(); +} + +static inline int dst_entries_init(struct dst_ops *dst) +{ + return percpu_counter_init(&dst->pcpuc_entries, 0); +} + +static inline void dst_entries_destroy(struct dst_ops *dst) +{ + percpu_counter_destroy(&dst->pcpuc_entries); +} + #endif diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index e8923bc20f9ff8f28b586af3b795bcf6230df92f..106f3097d38452e9764e60115f88ea768d6cb15c 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -31,6 +31,8 @@ struct fib_lookup_arg { void *lookup_ptr; void *result; struct fib_rule *rule; + int flags; +#define FIB_LOOKUP_NOREF 1 }; struct fib_rules_ops { @@ -106,7 +108,6 @@ static inline u32 frh_get_table(struct fib_rule_hdr *frh, struct nlattr **nla) extern struct fib_rules_ops *fib_rules_register(const struct fib_rules_ops *, struct net *); extern void fib_rules_unregister(struct fib_rules_ops *); -extern void fib_rules_cleanup_ops(struct fib_rules_ops *); extern int fib_rules_lookup(struct fib_rules_ops *, struct flowi *, int flags, diff --git a/include/net/flow.h b/include/net/flow.h index bb08692a20b08841ead94acce78c9ead82293d94..0ac3fb5e0973460f3046cdf1f00a0e1114a13dff 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -49,6 +49,7 @@ struct flowi { __u8 proto; __u8 flags; #define FLOWI_FLAG_ANYSRC 0x01 +#define FLOWI_FLAG_MATCH_ANY_IIF 0x02 union { struct { __be16 sport; diff --git a/include/net/genetlink.h b/include/net/genetlink.h index f7dcd2c7041266fadc9794efc50136c44c36d4f4..8a64b811a39aba9278a258396f268aa35a422e22 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -20,6 +20,9 @@ struct genl_multicast_group { u32 id; }; +struct genl_ops; +struct genl_info; + /** * struct genl_family - generic netlink family * @id: protocol family idenfitier @@ -29,6 +32,10 @@ struct genl_multicast_group { * @maxattr: maximum number of attributes supported * @netnsok: set to true if the family can handle network * namespaces and should be presented in all of them + * @pre_doit: called before an operation's doit callback, it may + * do additional, common, filtering and return an error + * @post_doit: called after an operation's doit callback, it may + * undo operations done by pre_doit, for example release locks * @attrbuf: buffer to store parsed attributes * @ops_list: list of all assigned operations * @family_list: family list @@ -41,6 +48,12 @@ struct genl_family { unsigned int version; unsigned int maxattr; bool netnsok; + int (*pre_doit)(struct genl_ops *ops, + struct sk_buff *skb, + struct genl_info *info); + void (*post_doit)(struct genl_ops *ops, + struct sk_buff *skb, + struct genl_info *info); struct nlattr ** attrbuf; /* private */ struct list_head ops_list; /* private */ struct list_head family_list; /* private */ @@ -55,6 +68,8 @@ struct genl_family { * @genlhdr: generic netlink message header * @userhdr: user specific header * @attrs: netlink attributes + * @_net: network namespace + * @user_ptr: user pointers */ struct genl_info { u32 snd_seq; @@ -66,6 +81,7 @@ struct genl_info { #ifdef CONFIG_NET_NS struct net * _net; #endif + void * user_ptr[2]; }; static inline struct net *genl_info_net(struct genl_info *info) @@ -81,6 +97,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) /** * struct genl_ops - generic netlink operations * @cmd: command identifier + * @internal_flags: flags used by the family * @flags: flags * @policy: attribute validation policy * @doit: standard command callback @@ -90,6 +107,7 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net) */ struct genl_ops { u8 cmd; + u8 internal_flags; unsigned int flags; const struct nla_policy *policy; int (*doit)(struct sk_buff *skb, diff --git a/include/net/gre.h b/include/net/gre.h new file mode 100644 index 0000000000000000000000000000000000000000..82665474bcb7c6e1389b2741fd9eda141f617270 --- /dev/null +++ b/include/net/gre.h @@ -0,0 +1,18 @@ +#ifndef __LINUX_GRE_H +#define __LINUX_GRE_H + +#include + +#define GREPROTO_CISCO 0 +#define GREPROTO_PPTP 1 +#define GREPROTO_MAX 2 + +struct gre_protocol { + int (*handler)(struct sk_buff *skb); + void (*err_handler)(struct sk_buff *skb, u32 info); +}; + +int gre_add_protocol(const struct gre_protocol *proto, u8 version); +int gre_del_protocol(const struct gre_protocol *proto, u8 version); + +#endif diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index b6d3b55da19b49e71d5cc7e0206090240cca0346..e4f494b42e060e1d4309acce8532aaa7f4b036eb 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -125,6 +125,7 @@ struct inet_connection_sock { int probe_size; } icsk_mtup; u32 icsk_ca_priv[16]; + u32 icsk_user_timeout; #define ICSK_CA_PRIV_SIZE (16 * sizeof(u32)) }; diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h index 9b5d08f4f6e8bb2459769463aceb19fbfd3da317..88bdd010d65d3791eb634cae72709e01fc2c2090 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -27,7 +27,7 @@ static inline int INET_ECN_is_not_ect(__u8 dsfield) static inline int INET_ECN_is_capable(__u8 dsfield) { - return (dsfield & INET_ECN_ECT_0); + return dsfield & INET_ECN_ECT_0; } static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner) diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 74358d1b3f439ba6f995ceb0c928730f8c180252..e9c2ed8af864b4fc197e8310551eb6f7ba71dd25 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -245,7 +245,7 @@ static inline int inet_sk_listen_hashfn(const struct sock *sk) } /* Caller must disable local BH processing. */ -extern void __inet_inherit_port(struct sock *sk, struct sock *child); +extern int __inet_inherit_port(struct sock *sk, struct sock *child); extern void inet_put_port(struct sock *sk); diff --git a/include/net/ip.h b/include/net/ip.h index 890f9725d68156b8d4df25adea50880ae3bf46a0..dbee3fe260e13877e28357c2477a66582cd1c03e 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -53,7 +53,7 @@ struct ipcm_cookie { __be32 addr; int oif; struct ip_options *opt; - union skb_shared_tx shtx; + __u8 tx_flags; }; #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) @@ -238,9 +238,9 @@ int ip_decrease_ttl(struct iphdr *iph) static inline int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) { - return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO || + return inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO || (inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT && - !(dst_metric_locked(dst, RTAX_MTU)))); + !(dst_metric_locked(dst, RTAX_MTU))); } extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index c93f94edc610fc440f38ca5f191b7b6c7e7dd72c..ba3666d31766864b354687cc543d9ba3a365193d 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -86,6 +86,7 @@ struct fib_info { #ifdef CONFIG_IP_ROUTE_MULTIPATH int fib_power; #endif + struct rcu_head rcu; struct fib_nh fib_nh[0]; #define fib_dev fib_nh[0].nh_dev }; @@ -148,7 +149,7 @@ struct fib_table { }; extern int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, - struct fib_result *res); + struct fib_result *res, int fib_flags); extern int fib_table_insert(struct fib_table *, struct fib_config *); extern int fib_table_delete(struct fib_table *, struct fib_config *); extern int fib_table_dump(struct fib_table *table, struct sk_buff *skb, @@ -185,11 +186,11 @@ static inline int fib_lookup(struct net *net, const struct flowi *flp, struct fib_table *table; table = fib_get_table(net, RT_TABLE_LOCAL); - if (!fib_table_lookup(table, flp, res)) + if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF)) return 0; table = fib_get_table(net, RT_TABLE_MAIN); - if (!fib_table_lookup(table, flp, res)) + if (!fib_table_lookup(table, flp, res, FIB_LOOKUP_NOREF)) return 0; return -ENETUNREACH; } @@ -254,16 +255,6 @@ static inline void fib_info_put(struct fib_info *fi) free_fib_info(fi); } -static inline void fib_res_put(struct fib_result *res) -{ - if (res->fi) - fib_info_put(res->fi); -#ifdef CONFIG_IP_MULTIPLE_TABLES - if (res->r) - fib_rule_put(res->r); -#endif -} - #ifdef CONFIG_PROC_FS extern int __net_init fib_proc_init(struct net *net); extern void __net_exit fib_proc_exit(struct net *net); diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index f976885f686f67f593d2928175e9f06de1c94f56..b7bbd6c28cfa17dde6fa3a972d33635c5a498312 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -25,7 +25,9 @@ #include #include /* for struct ipv6hdr */ #include /* for ipv6_addr_copy */ - +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) +#include +#endif /* Connections' size value needed by ip_vs_ctl.c */ extern int ip_vs_conn_tab_size; @@ -134,24 +136,24 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len, if (net_ratelimit()) \ printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__); \ } while (0) -#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) \ +#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) \ do { \ if (level <= ip_vs_get_debug_level()) \ - pp->debug_packet(pp, skb, ofs, msg); \ + pp->debug_packet(af, pp, skb, ofs, msg); \ } while (0) -#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) \ +#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) \ do { \ if (level <= ip_vs_get_debug_level() && \ net_ratelimit()) \ - pp->debug_packet(pp, skb, ofs, msg); \ + pp->debug_packet(af, pp, skb, ofs, msg); \ } while (0) #else /* NO DEBUGGING at ALL */ #define IP_VS_DBG_BUF(level, msg...) do {} while (0) #define IP_VS_ERR_BUF(msg...) do {} while (0) #define IP_VS_DBG(level, msg...) do {} while (0) #define IP_VS_DBG_RL(msg...) do {} while (0) -#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg) do {} while (0) -#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg) do {} while (0) +#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg) do {} while (0) +#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg) do {} while (0) #endif #define IP_VS_BUG() BUG() @@ -343,7 +345,7 @@ struct ip_vs_protocol { int (*app_conn_bind)(struct ip_vs_conn *cp); - void (*debug_packet)(struct ip_vs_protocol *pp, + void (*debug_packet)(int af, struct ip_vs_protocol *pp, const struct sk_buff *skb, int offset, const char *msg); @@ -355,6 +357,19 @@ struct ip_vs_protocol { extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); +struct ip_vs_conn_param { + const union nf_inet_addr *caddr; + const union nf_inet_addr *vaddr; + __be16 cport; + __be16 vport; + __u16 protocol; + u16 af; + + const struct ip_vs_pe *pe; + char *pe_data; + __u8 pe_data_len; +}; + /* * IP_VS structure allocated for each dynamically scheduled connection */ @@ -366,6 +381,7 @@ struct ip_vs_conn { union nf_inet_addr caddr; /* client address */ union nf_inet_addr vaddr; /* virtual address */ union nf_inet_addr daddr; /* destination address */ + volatile __u32 flags; /* status flags */ __be16 cport; __be16 vport; __be16 dport; @@ -378,7 +394,6 @@ struct ip_vs_conn { /* Flags and state transition */ spinlock_t lock; /* lock for state transition */ - volatile __u16 flags; /* status flags */ volatile __u16 state; /* state info */ volatile __u16 old_state; /* old state, to be used for * state transition triggerd @@ -394,6 +409,7 @@ struct ip_vs_conn { /* packet transmitter for different forwarding methods. If it mangles the packet, it must return NF_DROP or better NF_STOLEN, otherwise this must be changed to a sk_buff **. + NF_ACCEPT can be returned when destination is local. */ int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp); @@ -405,6 +421,9 @@ struct ip_vs_conn { void *app_data; /* Application private data */ struct ip_vs_seq in_seq; /* incoming seq. struct */ struct ip_vs_seq out_seq; /* outgoing seq. struct */ + + char *pe_data; + __u8 pe_data_len; }; @@ -426,6 +445,7 @@ struct ip_vs_service_user_kern { /* virtual service options */ char *sched_name; + char *pe_name; unsigned flags; /* virtual service flags */ unsigned timeout; /* persistent timeout in sec */ u32 netmask; /* persistent netmask */ @@ -475,6 +495,9 @@ struct ip_vs_service { struct ip_vs_scheduler *scheduler; /* bound scheduler object */ rwlock_t sched_lock; /* lock sched_data */ void *sched_data; /* scheduler application data */ + + /* alternate persistence engine */ + struct ip_vs_pe *pe; }; @@ -507,6 +530,10 @@ struct ip_vs_dest { spinlock_t dst_lock; /* lock of dst_cache */ struct dst_entry *dst_cache; /* destination cache entry */ u32 dst_rtos; /* RT_TOS(tos) for dst */ + u32 dst_cookie; +#ifdef CONFIG_IP_VS_IPV6 + struct in6_addr dst_saddr; +#endif /* for virtual service */ struct ip_vs_service *svc; /* service it belongs to */ @@ -538,6 +565,21 @@ struct ip_vs_scheduler { const struct sk_buff *skb); }; +/* The persistence engine object */ +struct ip_vs_pe { + struct list_head n_list; /* d-linked list head */ + char *name; /* scheduler name */ + atomic_t refcnt; /* reference counter */ + struct module *module; /* THIS_MODULE/NULL */ + + /* get the connection template, if any */ + int (*fill_param)(struct ip_vs_conn_param *p, struct sk_buff *skb); + bool (*ct_match)(const struct ip_vs_conn_param *p, + struct ip_vs_conn *ct); + u32 (*hashkey_raw)(const struct ip_vs_conn_param *p, u32 initval, + bool inverse); + int (*show_pe_data)(const struct ip_vs_conn *cp, char *buf); +}; /* * The application module object (a.k.a. app incarnation) @@ -556,11 +598,19 @@ struct ip_vs_app { __be16 port; /* port number in net order */ atomic_t usecnt; /* usage counter */ - /* output hook: return false if can't linearize. diff set for TCP. */ + /* + * output hook: Process packet in inout direction, diff set for TCP. + * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, + * 2=Mangled but checksum was not updated + */ int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *, struct sk_buff *, int *diff); - /* input hook: return false if can't linearize. diff set for TCP. */ + /* + * input hook: Process packet in outin direction, diff set for TCP. + * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok, + * 2=Mangled but checksum was not updated + */ int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *, struct sk_buff *, int *diff); @@ -624,13 +674,25 @@ enum { IP_VS_DIR_LAST, }; -extern struct ip_vs_conn *ip_vs_conn_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port); +static inline void ip_vs_conn_fill_param(int af, int protocol, + const union nf_inet_addr *caddr, + __be16 cport, + const union nf_inet_addr *vaddr, + __be16 vport, + struct ip_vs_conn_param *p) +{ + p->af = af; + p->protocol = protocol; + p->caddr = caddr; + p->cport = cport; + p->vaddr = vaddr; + p->vport = vport; + p->pe = NULL; + p->pe_data = NULL; +} -extern struct ip_vs_conn *ip_vs_ct_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port); +struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p); +struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p); struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, @@ -638,9 +700,7 @@ struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, unsigned int proto_off, int inverse); -extern struct ip_vs_conn *ip_vs_conn_out_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port); +struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p); struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, @@ -656,11 +716,10 @@ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp) extern void ip_vs_conn_put(struct ip_vs_conn *cp); extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport); -extern struct ip_vs_conn * -ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, - const union nf_inet_addr *vaddr, __be16 vport, - const union nf_inet_addr *daddr, __be16 dport, unsigned flags, - struct ip_vs_dest *dest); +struct ip_vs_conn *ip_vs_conn_new(const struct ip_vs_conn_param *p, + const union nf_inet_addr *daddr, + __be16 dport, unsigned flags, + struct ip_vs_dest *dest); extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp); extern const char * ip_vs_state_name(__u16 proto, int state); @@ -751,6 +810,12 @@ extern int ip_vs_app_pkt_in(struct ip_vs_conn *, struct sk_buff *skb); extern int ip_vs_app_init(void); extern void ip_vs_app_cleanup(void); +void ip_vs_bind_pe(struct ip_vs_service *svc, struct ip_vs_pe *pe); +void ip_vs_unbind_pe(struct ip_vs_service *svc); +int register_ip_vs_pe(struct ip_vs_pe *pe); +int unregister_ip_vs_pe(struct ip_vs_pe *pe); +extern struct ip_vs_pe *ip_vs_pe_get(const char *name); +extern void ip_vs_pe_put(struct ip_vs_pe *pe); /* * IPVS protocol functions (from ip_vs_proto.c) @@ -763,7 +828,8 @@ extern int ip_vs_set_state_timeout(int *table, int num, const char *const *names, const char *name, int to); extern void -ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb, +ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, + const struct sk_buff *skb, int offset, const char *msg); extern struct ip_vs_protocol ip_vs_protocol_tcp; @@ -785,7 +851,8 @@ extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc); extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name); extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler); extern struct ip_vs_conn * -ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb); +ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, + struct ip_vs_protocol *pp, int *ignored); extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, struct ip_vs_protocol *pp); @@ -798,6 +865,8 @@ extern int sysctl_ip_vs_expire_nodest_conn; extern int sysctl_ip_vs_expire_quiescent_template; extern int sysctl_ip_vs_sync_threshold[2]; extern int sysctl_ip_vs_nat_icmp_send; +extern int sysctl_ip_vs_conntrack; +extern int sysctl_ip_vs_snat_reroute; extern struct ip_vs_stats ip_vs_stats; extern const struct ctl_path net_vs_ctl_path[]; @@ -955,8 +1024,65 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) return csum_partial(diff, sizeof(diff), oldsum); } +/* + * Forget current conntrack (unconfirmed) and attach notrack entry + */ +static inline void ip_vs_notrack(struct sk_buff *skb) +{ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (!ct || !nf_ct_is_untracked(ct)) { + nf_reset(skb); + skb->nfct = &nf_ct_untracked_get()->ct_general; + skb->nfctinfo = IP_CT_NEW; + nf_conntrack_get(skb->nfct); + } +#endif +} + +#ifdef CONFIG_IP_VS_NFCT +/* + * Netfilter connection tracking + * (from ip_vs_nfct.c) + */ +static inline int ip_vs_conntrack_enabled(void) +{ + return sysctl_ip_vs_conntrack; +} + extern void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin); +extern int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp); +extern void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct, + struct ip_vs_conn *cp, u_int8_t proto, + const __be16 port, int from_rs); +extern void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp); + +#else + +static inline int ip_vs_conntrack_enabled(void) +{ + return 0; +} + +static inline void ip_vs_update_conntrack(struct sk_buff *skb, + struct ip_vs_conn *cp, int outin) +{ +} + +static inline int ip_vs_confirm_conntrack(struct sk_buff *skb, + struct ip_vs_conn *cp) +{ + return NF_ACCEPT; +} + +static inline void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp) +{ +} +/* CONFIG_IP_VS_NFCT */ +#endif #endif /* __KERNEL__ */ diff --git a/include/net/ipip.h b/include/net/ipip.h index 65caea8b414f0c5c60f7c4331bd7d7d6684ba9fb..58abbf966b0c816a3f22d0060fa0ad8aa08113ea 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -45,7 +45,7 @@ struct ip_tunnel_prl_entry { struct rcu_head rcu_head; }; -#define IPTUNNEL_XMIT() do { \ +#define __IPTUNNEL_XMIT(stats1, stats2) do { \ int err; \ int pkt_len = skb->len - skb_transport_offset(skb); \ \ @@ -54,12 +54,14 @@ struct ip_tunnel_prl_entry { \ err = ip_local_out(skb); \ if (likely(net_xmit_eval(err) == 0)) { \ - txq->tx_bytes += pkt_len; \ - txq->tx_packets++; \ + (stats1)->tx_bytes += pkt_len; \ + (stats1)->tx_packets++; \ } else { \ - stats->tx_errors++; \ - stats->tx_aborted_errors++; \ + (stats2)->tx_errors++; \ + (stats2)->tx_aborted_errors++; \ } \ } while (0) +#define IPTUNNEL_XMIT() __IPTUNNEL_XMIT(txq, stats) + #endif diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 1f841241099802145a8e1cff634e7e26c2f7c16c..4a3cd2cd2f5e1c54184391efef96dfd7608e4400 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -262,7 +262,7 @@ static inline int ipv6_addr_scope(const struct in6_addr *addr) static inline int __ipv6_addr_src_scope(int type) { - return (type == IPV6_ADDR_ANY ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16)); + return (type == IPV6_ADDR_ANY) ? __IPV6_ADDR_SCOPE_INVALID : (type >> 16); } static inline int ipv6_addr_src_scope(const struct in6_addr *addr) @@ -279,10 +279,10 @@ static inline int ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m, const struct in6_addr *a2) { - return (!!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) | - ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) | - ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) | - ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3]))); + return !!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) | + ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) | + ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) | + ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3])); } static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) @@ -317,10 +317,10 @@ static inline void ipv6_addr_set(struct in6_addr *addr, static inline int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2) { - return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) | - (a1->s6_addr32[1] ^ a2->s6_addr32[1]) | - (a1->s6_addr32[2] ^ a2->s6_addr32[2]) | - (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0); + return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) | + (a1->s6_addr32[1] ^ a2->s6_addr32[1]) | + (a1->s6_addr32[2] ^ a2->s6_addr32[2]) | + (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0; } static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, @@ -373,20 +373,20 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a); static inline int ipv6_addr_any(const struct in6_addr *a) { - return ((a->s6_addr32[0] | a->s6_addr32[1] | - a->s6_addr32[2] | a->s6_addr32[3] ) == 0); + return (a->s6_addr32[0] | a->s6_addr32[1] | + a->s6_addr32[2] | a->s6_addr32[3]) == 0; } static inline int ipv6_addr_loopback(const struct in6_addr *a) { - return ((a->s6_addr32[0] | a->s6_addr32[1] | - a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0); + return (a->s6_addr32[0] | a->s6_addr32[1] | + a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0; } static inline int ipv6_addr_v4mapped(const struct in6_addr *a) { - return ((a->s6_addr32[0] | a->s6_addr32[1] | - (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0); + return (a->s6_addr32[0] | a->s6_addr32[1] | + (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0; } /* @@ -395,8 +395,7 @@ static inline int ipv6_addr_v4mapped(const struct in6_addr *a) */ static inline int ipv6_addr_orchid(const struct in6_addr *a) { - return ((a->s6_addr32[0] & htonl(0xfffffff0)) - == htonl(0x20010010)); + return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010); } static inline void ipv6_addr_set_v4mapped(const __be32 addr, @@ -441,7 +440,7 @@ static inline int __ipv6_addr_diff(const void *token1, const void *token2, int a * if returned value is greater than prefix length. * --ANK (980803) */ - return (addrlen << 5); + return addrlen << 5; } static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_addr *a2) diff --git a/include/net/irda/irlan_common.h b/include/net/irda/irlan_common.h index 73cacb3ac16cae48a2e494ec10874bb8258b44db..0af8b8dfbc227898badec117e2abe759889f8a20 100644 --- a/include/net/irda/irlan_common.h +++ b/include/net/irda/irlan_common.h @@ -171,7 +171,6 @@ struct irlan_cb { int magic; struct list_head dev_list; struct net_device *dev; /* Ethernet device structure*/ - struct net_device_stats stats; __u32 saddr; /* Source device address */ __u32 daddr; /* Destination device address */ diff --git a/include/net/irda/irlan_event.h b/include/net/irda/irlan_event.h index 6d9539f05806a63efc03757bcadca6b496c59ae8..018b5a77e61087ccd6bc104f2944759a7bdd263d 100644 --- a/include/net/irda/irlan_event.h +++ b/include/net/irda/irlan_event.h @@ -67,7 +67,7 @@ typedef enum { IRLAN_WATCHDOG_TIMEOUT, } IRLAN_EVENT; -extern char *irlan_state[]; +extern const char * const irlan_state[]; void irlan_do_client_event(struct irlan_cb *self, IRLAN_EVENT event, struct sk_buff *skb); diff --git a/include/net/irda/irlap.h b/include/net/irda/irlap.h index 9d0c78ea92f5a994b3b615041316f427d9504be9..17fcd964f9d9ca43415a2721e94cb488016ffaa6 100644 --- a/include/net/irda/irlap.h +++ b/include/net/irda/irlap.h @@ -282,7 +282,7 @@ static inline int irlap_is_primary(struct irlap_cb *self) default: ret = -1; } - return(ret); + return ret; } /* Clear a pending IrLAP disconnect. - Jean II */ diff --git a/include/net/irda/irlmp.h b/include/net/irda/irlmp.h index 3ffc1d0f93d6ac40178911208e07279f20f7ece3..fff11b7fe8a44c67e6641bcc39a48fb3278012da 100644 --- a/include/net/irda/irlmp.h +++ b/include/net/irda/irlmp.h @@ -274,7 +274,7 @@ static inline int irlmp_lap_tx_queue_full(struct lsap_cb *self) if (self->lap->irlap == NULL) return 0; - return(IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD); + return IRLAP_GET_TX_QUEUE_LEN(self->lap->irlap) >= LAP_HIGH_THRESHOLD; } /* After doing a irlmp_dup(), this get one of the two socket back into diff --git a/include/net/irda/irttp.h b/include/net/irda/irttp.h index 11aee7a2972a67e08eb7afa508264e23a37ac833..af4b87721d13d1abe5618786d1e494d5757fe01a 100644 --- a/include/net/irda/irttp.h +++ b/include/net/irda/irttp.h @@ -204,7 +204,7 @@ static inline int irttp_is_primary(struct tsap_cb *self) (self->lsap->lap == NULL) || (self->lsap->lap->irlap == NULL)) return -2; - return(irlap_is_primary(self->lsap->lap->irlap)); + return irlap_is_primary(self->lsap->lap->irlap); } #endif /* IRTTP_H */ diff --git a/include/net/mac80211.h b/include/net/mac80211.h index b0787a1dea904c69c3ca5f29c0674b54053c41bb..9fdf982d1286a95c02a73bae4131746f05de9343 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -149,6 +149,7 @@ struct ieee80211_low_level_stats { * @BSS_CHANGED_ARP_FILTER: Hardware ARP filter address list or state changed. * @BSS_CHANGED_QOS: QoS for this association was enabled/disabled. Note * that it is only ever disabled for station mode. + * @BSS_CHANGED_IDLE: Idle changed for this BSS/interface. */ enum ieee80211_bss_change { BSS_CHANGED_ASSOC = 1<<0, @@ -165,6 +166,7 @@ enum ieee80211_bss_change { BSS_CHANGED_IBSS = 1<<11, BSS_CHANGED_ARP_FILTER = 1<<12, BSS_CHANGED_QOS = 1<<13, + BSS_CHANGED_IDLE = 1<<14, /* when adding here, make sure to change ieee80211_reconfig */ }; @@ -223,6 +225,9 @@ enum ieee80211_bss_change { * hardware must not perform any ARP filtering. Note, that the filter will * be enabled also in promiscuous mode. * @qos: This is a QoS-enabled BSS. + * @idle: This interface is idle. There's also a global idle flag in the + * hardware config which may be more appropriate depending on what + * your driver/device needs to do. */ struct ieee80211_bss_conf { const u8 *bssid; @@ -247,6 +252,7 @@ struct ieee80211_bss_conf { u8 arp_addr_cnt; bool arp_filter_enabled; bool qos; + bool idle; }; /** @@ -315,6 +321,9 @@ struct ieee80211_bss_conf { * @IEEE80211_TX_CTL_LDPC: tells the driver to use LDPC for this frame * @IEEE80211_TX_CTL_STBC: Enables Space-Time Block Coding (STBC) for this * frame and selects the maximum number of streams that it can use. + * + * Note: If you have to add new flags to the enumeration, then don't + * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. */ enum mac80211_tx_control_flags { IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), @@ -344,6 +353,19 @@ enum mac80211_tx_control_flags { #define IEEE80211_TX_CTL_STBC_SHIFT 23 +/* + * This definition is used as a mask to clear all temporary flags, which are + * set by the tx handlers for each transmission attempt by the mac80211 stack. + */ +#define IEEE80211_TX_TEMPORARY_FLAGS (IEEE80211_TX_CTL_NO_ACK | \ + IEEE80211_TX_CTL_CLEAR_PS_FILT | IEEE80211_TX_CTL_FIRST_FRAGMENT | \ + IEEE80211_TX_CTL_SEND_AFTER_DTIM | IEEE80211_TX_CTL_AMPDU | \ + IEEE80211_TX_STAT_TX_FILTERED | IEEE80211_TX_STAT_ACK | \ + IEEE80211_TX_STAT_AMPDU | IEEE80211_TX_STAT_AMPDU_NO_BACK | \ + IEEE80211_TX_CTL_RATE_CTRL_PROBE | IEEE80211_TX_CTL_PSPOLL_RESPONSE | \ + IEEE80211_TX_CTL_MORE_FRAMES | IEEE80211_TX_CTL_LDPC | \ + IEEE80211_TX_CTL_STBC) + /** * enum mac80211_rate_control_flags - per-rate flags set by the * Rate Control algorithm. @@ -559,9 +581,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index * @RX_FLAG_40MHZ: HT40 (40 MHz) was used * @RX_FLAG_SHORT_GI: Short guard interval was used - * @RX_FLAG_INTERNAL_CMTR: set internally after frame was reported - * on cooked monitor to avoid double-reporting it for multiple - * virtual interfaces */ enum mac80211_rx_flags { RX_FLAG_MMIC_ERROR = 1<<0, @@ -575,7 +594,6 @@ enum mac80211_rx_flags { RX_FLAG_HT = 1<<9, RX_FLAG_40MHZ = 1<<10, RX_FLAG_SHORT_GI = 1<<11, - RX_FLAG_INTERNAL_CMTR = 1<<12, }; /** @@ -596,6 +614,7 @@ enum mac80211_rx_flags { * @rate_idx: index of data rate into band's supported rates or MCS index if * HT rates are use (RX_FLAG_HT) * @flag: %RX_FLAG_* + * @rx_flags: internal RX flags for mac80211 */ struct ieee80211_rx_status { u64 mactime; @@ -605,6 +624,7 @@ struct ieee80211_rx_status { int antenna; int rate_idx; int flag; + unsigned int rx_flags; }; /** @@ -763,6 +783,8 @@ struct ieee80211_channel_switch { * @bss_conf: BSS configuration for this interface, either our own * or the BSS we're associated to * @addr: address of this interface + * @p2p: indicates whether this AP or STA interface is a p2p + * interface, i.e. a GO or p2p-sta respectively * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *). */ @@ -770,6 +792,7 @@ struct ieee80211_vif { enum nl80211_iftype type; struct ieee80211_bss_conf bss_conf; u8 addr[ETH_ALEN]; + bool p2p; /* must be last */ u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); }; @@ -782,20 +805,6 @@ static inline bool ieee80211_vif_is_mesh(struct ieee80211_vif *vif) return false; } -/** - * enum ieee80211_key_alg - key algorithm - * @ALG_WEP: WEP40 or WEP104 - * @ALG_TKIP: TKIP - * @ALG_CCMP: CCMP (AES) - * @ALG_AES_CMAC: AES-128-CMAC - */ -enum ieee80211_key_alg { - ALG_WEP, - ALG_TKIP, - ALG_CCMP, - ALG_AES_CMAC, -}; - /** * enum ieee80211_key_flags - key flags * @@ -833,7 +842,7 @@ enum ieee80211_key_flags { * @hw_key_idx: To be set by the driver, this is the key index the driver * wants to be given when a frame is transmitted and needs to be * encrypted in hardware. - * @alg: The key algorithm. + * @cipher: The key's cipher suite selector. * @flags: key flags, see &enum ieee80211_key_flags. * @keyidx: the key index (0-3) * @keylen: key material length @@ -846,7 +855,7 @@ enum ieee80211_key_flags { * @iv_len: The IV length for this key type */ struct ieee80211_key_conf { - enum ieee80211_key_alg alg; + u32 cipher; u8 icv_len; u8 iv_len; u8 hw_key_idx; @@ -1032,6 +1041,13 @@ enum ieee80211_tkip_key_type { * @IEEE80211_HW_NEED_DTIM_PERIOD: * This device needs to know the DTIM period for the BSS before * associating. + * + * @IEEE80211_HW_SUPPORTS_PER_STA_GTK: The device's crypto engine supports + * per-station GTKs as used by IBSS RSN or during fast transition. If + * the device doesn't support per-station GTKs, but can be asked not + * to decrypt group addressed frames, then IBSS RSN support is still + * possible but software crypto will be used. Advertise the wiphy flag + * only in that case. */ enum ieee80211_hw_flags { IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, @@ -1055,6 +1071,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, IEEE80211_HW_CONNECTION_MONITOR = 1<<19, IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20, + IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, }; /** @@ -1100,8 +1117,15 @@ enum ieee80211_hw_flags { * @sta_data_size: size (in bytes) of the drv_priv data area * within &struct ieee80211_sta. * - * @max_rates: maximum number of alternate rate retry stages + * @max_rates: maximum number of alternate rate retry stages the hw + * can handle. + * @max_report_rates: maximum number of alternate rate retry stages + * the hw can report back. * @max_rate_tries: maximum number of tries for each stage + * + * @napi_weight: weight used for NAPI polling. You must specify an + * appropriate value here if a napi_poll operation is provided + * by your driver. */ struct ieee80211_hw { struct ieee80211_conf conf; @@ -1113,10 +1137,12 @@ struct ieee80211_hw { int channel_change_time; int vif_data_size; int sta_data_size; + int napi_weight; u16 queues; u16 max_listen_interval; s8 max_signal; u8 max_rates; + u8 max_report_rates; u8 max_rate_tries; }; @@ -1245,8 +1271,8 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * %IEEE80211_CONF_PS flag enabled means that the powersave mode defined in * IEEE 802.11-2007 section 11.2 is enabled. This is not to be confused * with hardware wakeup and sleep states. Driver is responsible for waking - * up the hardware before issueing commands to the hardware and putting it - * back to sleep at approriate times. + * up the hardware before issuing commands to the hardware and putting it + * back to sleep at appropriate times. * * When PS is enabled, hardware needs to wakeup for beacons and receive the * buffered multicast/broadcast frames after the beacon. Also it must be @@ -1267,7 +1293,7 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * there's data traffic and still saving significantly power in idle * periods. * - * Dynamic powersave is supported by simply mac80211 enabling and disabling + * Dynamic powersave is simply supported by mac80211 enabling and disabling * PS based on traffic. Driver needs to only set %IEEE80211_HW_SUPPORTS_PS * flag and mac80211 will handle everything automatically. Additionally, * hardware having support for the dynamic PS feature may set the @@ -1452,12 +1478,14 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, * honour this flag if possible. * * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS - * is not set then only those addressed to this station. + * is not set then only those addressed to this station. * * @FIF_OTHER_BSS: pass frames destined to other BSSes * - * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only - * those addressed to this station. + * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only + * those addressed to this station. + * + * @FIF_PROBE_REQ: pass probe request frames */ enum ieee80211_filter_flags { FIF_PROMISC_IN_BSS = 1<<0, @@ -1468,6 +1496,7 @@ enum ieee80211_filter_flags { FIF_CONTROL = 1<<5, FIF_OTHER_BSS = 1<<6, FIF_PSPOLL = 1<<7, + FIF_PROBE_REQ = 1<<8, }; /** @@ -1540,6 +1569,12 @@ enum ieee80211_ampdu_mlme_action { * negative error code (which will be seen in userspace.) * Must be implemented and can sleep. * + * @change_interface: Called when a netdevice changes type. This callback + * is optional, but only if it is supported can interface types be + * switched while the interface is UP. The callback may sleep. + * Note that while an interface is being switched, it will not be + * found by the interface iteration callbacks. + * * @remove_interface: Notifies a driver that an interface is going down. * The @stop callback is called after this if it is the last interface * and no monitor interfaces are present. @@ -1687,6 +1722,8 @@ enum ieee80211_ampdu_mlme_action { * switch operation for CSAs received from the AP may implement this * callback. They must then call ieee80211_chswitch_done() to indicate * completion of the channel switch. + * + * @napi_poll: Poll Rx queue for incoming data frames. */ struct ieee80211_ops { int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); @@ -1694,6 +1731,9 @@ struct ieee80211_ops { void (*stop)(struct ieee80211_hw *hw); int (*add_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); + int (*change_interface)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + enum nl80211_iftype new_type, bool p2p); void (*remove_interface)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); int (*config)(struct ieee80211_hw *hw, u32 changed); @@ -1752,6 +1792,7 @@ struct ieee80211_ops { void (*flush)(struct ieee80211_hw *hw, bool drop); void (*channel_switch)(struct ieee80211_hw *hw, struct ieee80211_channel_switch *ch_switch); + int (*napi_poll)(struct ieee80211_hw *hw, int budget); }; /** @@ -1897,6 +1938,22 @@ void ieee80211_free_hw(struct ieee80211_hw *hw); */ void ieee80211_restart_hw(struct ieee80211_hw *hw); +/** ieee80211_napi_schedule - schedule NAPI poll + * + * Use this function to schedule NAPI polling on a device. + * + * @hw: the hardware to start polling + */ +void ieee80211_napi_schedule(struct ieee80211_hw *hw); + +/** ieee80211_napi_complete - complete NAPI polling + * + * Use this function to finish NAPI polling on a device. + * + * @hw: the hardware to stop polling + */ +void ieee80211_napi_complete(struct ieee80211_hw *hw); + /** * ieee80211_rx - receive frame * @@ -2252,7 +2309,8 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw); * * When hardware scan offload is used (i.e. the hw_scan() callback is * assigned) this function needs to be called by the driver to notify - * mac80211 that the scan finished. + * mac80211 that the scan finished. This function can be called from + * any context, including hardirq context. * * @hw: the hardware that finished the scan * @aborted: set to true if scan was aborted @@ -2267,6 +2325,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted); * This function allows the iterator function to sleep, when the iterator * function is atomic @ieee80211_iterate_active_interfaces_atomic can * be used. + * Does not iterate over a new interface during add_interface() * * @hw: the hardware struct of which the interfaces should be iterated over * @iterator: the iterator function to call @@ -2284,6 +2343,7 @@ void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw, * hardware that are currently active and calls the callback for them. * This function requires the iterator callback function to be atomic, * if that is not desired, use @ieee80211_iterate_active_interfaces instead. + * Does not iterate over a new interface during add_interface() * * @hw: the hardware struct of which the interfaces should be iterated over * @iterator: the iterator function to call, cannot sleep @@ -2385,25 +2445,28 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *addr); /** - * ieee80211_find_sta_by_hw - find a station on hardware + * ieee80211_find_sta_by_ifaddr - find a station on hardware * * @hw: pointer as obtained from ieee80211_alloc_hw() - * @addr: station's address + * @addr: remote station's address + * @localaddr: local address (vif->sdata->vif.addr). Use NULL for 'any'. * * This function must be called under RCU lock and the * resulting pointer is only valid under RCU lock as well. * - * NOTE: This function should not be used! When mac80211 is converted - * internally to properly keep track of stations on multiple - * virtual interfaces, it will not always know which station to - * return here since a single address might be used by multiple - * logical stations (e.g. consider a station connecting to another - * BSSID on the same AP hardware without disconnecting first). + * NOTE: You may pass NULL for localaddr, but then you will just get + * the first STA that matches the remote address 'addr'. + * We can have multiple STA associated with multiple + * logical stations (e.g. consider a station connecting to another + * BSSID on the same AP hardware without disconnecting first). + * In this case, the result of this method with localaddr NULL + * is not reliable. * - * DO NOT USE THIS FUNCTION. + * DO NOT USE THIS FUNCTION with localaddr NULL if at all possible. */ -struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, - const u8 *addr); +struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, + const u8 *addr, + const u8 *localaddr); /** * ieee80211_sta_block_awake - block station from waking up @@ -2442,7 +2505,7 @@ void ieee80211_sta_block_awake(struct ieee80211_hw *hw, * * @vif: &struct ieee80211_vif pointer from the add_interface callback. * - * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING and + * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER and * %IEEE80211_CONF_PS is set, the driver needs to inform whenever the * hardware is not receiving beacons with this function. */ @@ -2453,7 +2516,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif); * * @vif: &struct ieee80211_vif pointer from the add_interface callback. * - * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTERING, and + * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER, and * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver * needs to inform if the connection to the AP has been lost. * @@ -2518,6 +2581,34 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, */ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success); +/** + * ieee80211_request_smps - request SM PS transition + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @smps_mode: new SM PS mode + * + * This allows the driver to request an SM PS transition in managed + * mode. This is useful when the driver has more information than + * the stack about possible interference, for example by bluetooth. + */ +void ieee80211_request_smps(struct ieee80211_vif *vif, + enum ieee80211_smps_mode smps_mode); + +/** + * ieee80211_key_removed - disable hw acceleration for key + * @key_conf: The key hw acceleration should be disabled for + * + * This allows drivers to indicate that the given key has been + * removed from hardware acceleration, due to a new key that + * was added. Don't use this if the key can continue to be used + * for TX, if the key restriction is on RX only it is permitted + * to keep the key for TX only and not call this function. + * + * Due to locking constraints, it may only be called during + * @set_key. This function must be allowed to sleep, and the + * key it tries to disable may still be used until it returns. + */ +void ieee80211_key_removed(struct ieee80211_key_conf *key_conf); + /* Rate control API */ /** @@ -2681,4 +2772,26 @@ conf_is_ht(struct ieee80211_conf *conf) return conf->channel_type != NL80211_CHAN_NO_HT; } +static inline enum nl80211_iftype +ieee80211_iftype_p2p(enum nl80211_iftype type, bool p2p) +{ + if (p2p) { + switch (type) { + case NL80211_IFTYPE_STATION: + return NL80211_IFTYPE_P2P_CLIENT; + case NL80211_IFTYPE_AP: + return NL80211_IFTYPE_P2P_GO; + default: + break; + } + } + return type; +} + +static inline enum nl80211_iftype +ieee80211_vif_type_p2p(struct ieee80211_vif *vif) +{ + return ieee80211_iftype_p2p(vif->type, vif->p2p); +} + #endif /* MAC80211_H */ diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 242879b6c4df8a4f539c3746dabb26bfe08a9dd8..55590ab16b3ed5192413b4b6415a8785c1d1a5bb 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -91,26 +91,28 @@ struct neigh_statistics { #define NEIGH_CACHE_STAT_INC(tbl, field) this_cpu_inc((tbl)->stats->field) struct neighbour { - struct neighbour *next; + struct neighbour __rcu *next; struct neigh_table *tbl; struct neigh_parms *parms; - struct net_device *dev; - unsigned long used; unsigned long confirmed; unsigned long updated; __u8 flags; __u8 nud_state; __u8 type; __u8 dead; + atomic_t refcnt; + struct sk_buff_head arp_queue; + struct timer_list timer; + unsigned long used; atomic_t probes; rwlock_t lock; + seqlock_t ha_lock; unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; struct hh_cache *hh; - atomic_t refcnt; int (*output)(struct sk_buff *skb); - struct sk_buff_head arp_queue; - struct timer_list timer; const struct neigh_ops *ops; + struct rcu_head rcu; + struct net_device *dev; u8 primary_key[0]; }; @@ -138,13 +140,22 @@ struct pneigh_entry { * neighbour table manipulation */ +struct neigh_hash_table { + struct neighbour __rcu **hash_buckets; + unsigned int hash_mask; + __u32 hash_rnd; + struct rcu_head rcu; +}; + struct neigh_table { struct neigh_table *next; int family; int entry_size; int key_len; - __u32 (*hash)(const void *pkey, const struct net_device *); + __u32 (*hash)(const void *pkey, + const struct net_device *dev, + __u32 hash_rnd); int (*constructor)(struct neighbour *); int (*pconstructor)(struct pneigh_entry *); void (*pdestructor)(struct pneigh_entry *); @@ -163,11 +174,9 @@ struct neigh_table { atomic_t entries; rwlock_t lock; unsigned long last_rand; - struct kmem_cache *kmem_cachep; + struct kmem_cache *kmem_cachep; struct neigh_statistics __percpu *stats; - struct neighbour **hash_buckets; - unsigned int hash_mask; - __u32 hash_rnd; + struct neigh_hash_table __rcu *nht; struct pneigh_entry **phash_buckets; }; @@ -237,6 +246,7 @@ extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_en struct neigh_seq_state { struct seq_net_private p; struct neigh_table *tbl; + struct neigh_hash_table *nht; void *(*neigh_sub_iter)(struct neigh_seq_state *state, struct neighbour *n, loff_t *pos); unsigned int bucket; @@ -293,7 +303,10 @@ static inline void neigh_confirm(struct neighbour *neigh) static inline int neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) { - neigh->used = jiffies; + unsigned long now = ACCESS_ONCE(jiffies); + + if (neigh->used != now) + neigh->used = now; if (!(neigh->nud_state&(NUD_CONNECTED|NUD_DELAY|NUD_PROBE))) return __neigh_event_send(neigh, skb); return 0; @@ -364,4 +377,14 @@ struct neighbour_cb { #define NEIGH_CB(skb) ((struct neighbour_cb *)(skb)->cb) +static inline void neigh_ha_snapshot(char *dst, const struct neighbour *n, + const struct net_device *dev) +{ + unsigned int seq; + + do { + seq = read_seqbegin(&n->ha_lock); + memcpy(dst, n->ha, dev->addr_len); + } while (read_seqretry(&n->ha_lock, seq)); +} #endif diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index bd10a7908993fc369de73957751588d933a9bb12..65af9a07cf766b3fe0309149cd46fcc6495aaffb 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -41,6 +41,8 @@ struct net { * destroy on demand */ #endif + spinlock_t rules_mod_lock; + struct list_head list; /* list of network namespaces */ struct list_head cleanup_list; /* namespaces on death row */ struct list_head exit_list; /* Use only net_mutex */ @@ -52,7 +54,8 @@ struct net { struct ctl_table_set sysctls; #endif - struct net_device *loopback_dev; /* The loopback */ + struct sock *rtnl; /* rtnetlink socket */ + struct sock *genl_sock; struct list_head dev_base_head; struct hlist_head *dev_name_head; @@ -60,11 +63,9 @@ struct net { /* core fib_rules */ struct list_head rules_ops; - spinlock_t rules_mod_lock; - struct sock *rtnl; /* rtnetlink socket */ - struct sock *genl_sock; + struct net_device *loopback_dev; /* The loopback */ struct netns_core core; struct netns_mib mib; struct netns_packet packet; @@ -84,13 +85,15 @@ struct net { struct sock *nfnl; struct sock *nfnl_stash; #endif -#ifdef CONFIG_XFRM - struct netns_xfrm xfrm; -#endif #ifdef CONFIG_WEXT_CORE struct sk_buff_head wext_nlevents; #endif struct net_generic *gen; + + /* Note : following structs are cache line aligned */ +#ifdef CONFIG_XFRM + struct netns_xfrm xfrm; +#endif }; diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h new file mode 100644 index 0000000000000000000000000000000000000000..94dd54d76b48d215729059d53b9e6a983070138a --- /dev/null +++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h @@ -0,0 +1,6 @@ +#ifndef _NF_DEFRAG_IPV6_H +#define _NF_DEFRAG_IPV6_H + +extern void nf_defrag_ipv6_enable(void); + +#endif /* _NF_DEFRAG_IPV6_H */ diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index 11e815084fcf05cb1a680b3c61968a1eb66a1ac5..0f8a8c587532f78ac5f191d93a1088b03ba1fd78 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -67,9 +67,6 @@ struct nf_conntrack_expect_policy { #define NF_CT_EXPECT_CLASS_DEFAULT 0 -#define NF_CT_EXPECT_PERMANENT 0x1 -#define NF_CT_EXPECT_INACTIVE 0x2 - int nf_conntrack_expect_init(struct net *net); void nf_conntrack_expect_fini(struct net *net); @@ -85,9 +82,16 @@ struct nf_conntrack_expect * nf_ct_find_expectation(struct net *net, u16 zone, const struct nf_conntrack_tuple *tuple); -void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); +void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, + u32 pid, int report); +static inline void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) +{ + nf_ct_unlink_expect_report(exp, 0, 0); +} + void nf_ct_remove_expectations(struct nf_conn *ct); void nf_ct_unexpect_related(struct nf_conntrack_expect *exp); +void nf_ct_remove_userspace_expectations(void); /* Allocate space for an expectation: this is mandatory before calling nf_ct_expect_related. You will have to call put afterwards. */ diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h index df17bac46bf5ef81cc4a1f3114e99eb54a913758..93cc90d28e66e31047f7219e2c4a1cbd8ce6774c 100644 --- a/include/net/netfilter/nf_nat_protocol.h +++ b/include/net/netfilter/nf_nat_protocol.h @@ -45,9 +45,6 @@ struct nf_nat_protocol { extern int nf_nat_protocol_register(const struct nf_nat_protocol *proto); extern void nf_nat_protocol_unregister(const struct nf_nat_protocol *proto); -extern const struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol); -extern void nf_nat_proto_put(const struct nf_nat_protocol *proto); - /* Built-in protocols. */ extern const struct nf_nat_protocol nf_nat_protocol_tcp; extern const struct nf_nat_protocol nf_nat_protocol_udp; diff --git a/include/net/netfilter/nf_tproxy_core.h b/include/net/netfilter/nf_tproxy_core.h index 208b46f4d6d2b2bfbf9b2439b783dbfa6a7a7a46..cd85b3bc8327219f1e036698c253034c27765d66 100644 --- a/include/net/netfilter/nf_tproxy_core.h +++ b/include/net/netfilter/nf_tproxy_core.h @@ -5,15 +5,201 @@ #include #include #include -#include +#include +#include #include +#define NFT_LOOKUP_ANY 0 +#define NFT_LOOKUP_LISTENER 1 +#define NFT_LOOKUP_ESTABLISHED 2 + /* look up and get a reference to a matching socket */ -extern struct sock * + + +/* This function is used by the 'TPROXY' target and the 'socket' + * match. The following lookups are supported: + * + * Explicit TProxy target rule + * =========================== + * + * This is used when the user wants to intercept a connection matching + * an explicit iptables rule. In this case the sockets are assumed + * matching in preference order: + * + * - match: if there's a fully established connection matching the + * _packet_ tuple, it is returned, assuming the redirection + * already took place and we process a packet belonging to an + * established connection + * + * - match: if there's a listening socket matching the redirection + * (e.g. on-port & on-ip of the connection), it is returned, + * regardless if it was bound to 0.0.0.0 or an explicit + * address. The reasoning is that if there's an explicit rule, it + * does not really matter if the listener is bound to an interface + * or to 0. The user already stated that he wants redirection + * (since he added the rule). + * + * "socket" match based redirection (no specific rule) + * =================================================== + * + * There are connections with dynamic endpoints (e.g. FTP data + * connection) that the user is unable to add explicit rules + * for. These are taken care of by a generic "socket" rule. It is + * assumed that the proxy application is trusted to open such + * connections without explicit iptables rule (except of course the + * generic 'socket' rule). In this case the following sockets are + * matched in preference order: + * + * - match: if there's a fully established connection matching the + * _packet_ tuple + * + * - match: if there's a non-zero bound listener (possibly with a + * non-local address) We don't accept zero-bound listeners, since + * then local services could intercept traffic going through the + * box. + * + * Please note that there's an overlap between what a TPROXY target + * and a socket match will match. Normally if you have both rules the + * "socket" match will be the first one, effectively all packets + * belonging to established connections going through that one. + */ +static inline struct sock * nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, const __be32 saddr, const __be32 daddr, const __be16 sport, const __be16 dport, - const struct net_device *in, bool listening); + const struct net_device *in, int lookup_type) +{ + struct sock *sk; + + /* look up socket */ + switch (protocol) { + case IPPROTO_TCP: + switch (lookup_type) { + case NFT_LOOKUP_ANY: + sk = __inet_lookup(net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); + break; + case NFT_LOOKUP_LISTENER: + sk = inet_lookup_listener(net, &tcp_hashinfo, + daddr, dport, + in->ifindex); + + /* NOTE: we return listeners even if bound to + * 0.0.0.0, those are filtered out in + * xt_socket, since xt_TPROXY needs 0 bound + * listeners too */ + + break; + case NFT_LOOKUP_ESTABLISHED: + sk = inet_lookup_established(net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); + break; + default: + WARN_ON(1); + sk = NULL; + break; + } + break; + case IPPROTO_UDP: + sk = udp4_lib_lookup(net, saddr, sport, daddr, dport, + in->ifindex); + if (sk && lookup_type != NFT_LOOKUP_ANY) { + int connected = (sk->sk_state == TCP_ESTABLISHED); + int wildcard = (inet_sk(sk)->inet_rcv_saddr == 0); + + /* NOTE: we return listeners even if bound to + * 0.0.0.0, those are filtered out in + * xt_socket, since xt_TPROXY needs 0 bound + * listeners too */ + if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || + (lookup_type == NFT_LOOKUP_LISTENER && connected)) { + sock_put(sk); + sk = NULL; + } + } + break; + default: + WARN_ON(1); + sk = NULL; + } + + pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, lookup type: %d, sock %p\n", + protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), lookup_type, sk); + + return sk; +} + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static inline struct sock * +nf_tproxy_get_sock_v6(struct net *net, const u8 protocol, + const struct in6_addr *saddr, const struct in6_addr *daddr, + const __be16 sport, const __be16 dport, + const struct net_device *in, int lookup_type) +{ + struct sock *sk; + + /* look up socket */ + switch (protocol) { + case IPPROTO_TCP: + switch (lookup_type) { + case NFT_LOOKUP_ANY: + sk = inet6_lookup(net, &tcp_hashinfo, + saddr, sport, daddr, dport, + in->ifindex); + break; + case NFT_LOOKUP_LISTENER: + sk = inet6_lookup_listener(net, &tcp_hashinfo, + daddr, ntohs(dport), + in->ifindex); + + /* NOTE: we return listeners even if bound to + * 0.0.0.0, those are filtered out in + * xt_socket, since xt_TPROXY needs 0 bound + * listeners too */ + + break; + case NFT_LOOKUP_ESTABLISHED: + sk = __inet6_lookup_established(net, &tcp_hashinfo, + saddr, sport, daddr, ntohs(dport), + in->ifindex); + break; + default: + WARN_ON(1); + sk = NULL; + break; + } + break; + case IPPROTO_UDP: + sk = udp6_lib_lookup(net, saddr, sport, daddr, dport, + in->ifindex); + if (sk && lookup_type != NFT_LOOKUP_ANY) { + int connected = (sk->sk_state == TCP_ESTABLISHED); + int wildcard = ipv6_addr_any(&inet6_sk(sk)->rcv_saddr); + + /* NOTE: we return listeners even if bound to + * 0.0.0.0, those are filtered out in + * xt_socket, since xt_TPROXY needs 0 bound + * listeners too */ + if ((lookup_type == NFT_LOOKUP_ESTABLISHED && (!connected || wildcard)) || + (lookup_type == NFT_LOOKUP_LISTENER && connected)) { + sock_put(sk); + sk = NULL; + } + } + break; + default: + WARN_ON(1); + sk = NULL; + } + + pr_debug("tproxy socket lookup: proto %u %pI6:%u -> %pI6:%u, lookup type: %d, sock %p\n", + protocol, saddr, ntohs(sport), daddr, ntohs(dport), lookup_type, sk); + + return sk; +} +#endif static inline void nf_tproxy_put_sock(struct sock *sk) diff --git a/include/net/netfilter/xt_log.h b/include/net/netfilter/xt_log.h new file mode 100644 index 0000000000000000000000000000000000000000..0dfb34a5b53c3440469e51873d886a5312ec9615 --- /dev/null +++ b/include/net/netfilter/xt_log.h @@ -0,0 +1,54 @@ +#define S_SIZE (1024 - (sizeof(unsigned int) + 1)) + +struct sbuff { + unsigned int count; + char buf[S_SIZE + 1]; +}; +static struct sbuff emergency, *emergency_ptr = &emergency; + +static int sb_add(struct sbuff *m, const char *f, ...) +{ + va_list args; + int len; + + if (likely(m->count < S_SIZE)) { + va_start(args, f); + len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args); + va_end(args); + if (likely(m->count + len < S_SIZE)) { + m->count += len; + return 0; + } + } + m->count = S_SIZE; + printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n"); + return -1; +} + +static struct sbuff *sb_open(void) +{ + struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC); + + if (unlikely(!m)) { + local_bh_disable(); + do { + m = xchg(&emergency_ptr, NULL); + } while (!m); + } + m->count = 0; + return m; +} + +static void sb_close(struct sbuff *m) +{ + m->buf[m->count] = 0; + printk("%s\n", m->buf); + + if (likely(m != &emergency)) + kfree(m); + else { + xchg(&emergency_ptr, m); + local_bh_enable(); + } +} + diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index 74f119a2829a2fe8749e28fdccd99822e58e76dc..748f91f87cd573783efcf59a615292a86b2c289e 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h @@ -43,10 +43,6 @@ struct netns_xfrm { unsigned int policy_count[XFRM_POLICY_MAX * 2]; struct work_struct policy_hash_work; - struct dst_ops xfrm4_dst_ops; -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - struct dst_ops xfrm6_dst_ops; -#endif struct sock *nlsk; struct sock *nlsk_stash; @@ -58,6 +54,11 @@ struct netns_xfrm { #ifdef CONFIG_SYSCTL struct ctl_table_header *sysctl_hdr; #endif + + struct dst_ops xfrm4_dst_ops; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct dst_ops xfrm6_dst_ops; +#endif }; #endif diff --git a/include/net/phonet/pep.h b/include/net/phonet/pep.h index 35672b1cf44a3b76d258f84996c4abd779219fbc..b60b28c99e8704a3d0a77c1ec1b3095ac7180053 100644 --- a/include/net/phonet/pep.h +++ b/include/net/phonet/pep.h @@ -45,6 +45,10 @@ struct pep_sock { u8 tx_fc; /* TX flow control */ u8 init_enable; /* auto-enable at creation */ u8 aligned; +#ifdef CONFIG_PHONET_PIPECTRLR + u8 pipe_state; + struct sockaddr_pn remote_pep; +#endif }; static inline struct pep_sock *pep_sk(struct sock *sk) @@ -77,6 +81,11 @@ static inline struct pnpipehdr *pnp_hdr(struct sk_buff *skb) #define MAX_PNPIPE_HEADER (MAX_PHONET_HEADER + 4) enum { + PNS_PIPE_CREATE_REQ = 0x00, + PNS_PIPE_CREATE_RESP, + PNS_PIPE_REMOVE_REQ, + PNS_PIPE_REMOVE_RESP, + PNS_PIPE_DATA = 0x20, PNS_PIPE_ALIGNED_DATA, @@ -160,4 +169,21 @@ enum { PEP_IND_READY, }; +#ifdef CONFIG_PHONET_PIPECTRLR +#define PNS_PEP_CONNECT_UTID 0x02 +#define PNS_PIPE_CREATED_IND_UTID 0x04 +#define PNS_PIPE_ENABLE_UTID 0x0A +#define PNS_PIPE_ENABLED_IND_UTID 0x0C +#define PNS_PIPE_DISABLE_UTID 0x0F +#define PNS_PIPE_DISABLED_IND_UTID 0x11 +#define PNS_PEP_DISCONNECT_UTID 0x06 + +/* Used for tracking state of a pipe */ +enum { + PIPE_IDLE, + PIPE_DISABLED, + PIPE_ENABLED, +}; +#endif /* CONFIG_PHONET_PIPECTRLR */ + #endif diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h index 7b114079a51bb18327c96005cd7c6a9864bc4a25..d5df797f954048b458071b544d8e5de94785b4e6 100644 --- a/include/net/phonet/phonet.h +++ b/include/net/phonet/phonet.h @@ -54,6 +54,11 @@ void pn_sock_hash(struct sock *sk); void pn_sock_unhash(struct sock *sk); int pn_sock_get_port(struct sock *sk, unsigned short sport); +struct sock *pn_find_sock_by_res(struct net *net, u8 res); +int pn_sock_bind_res(struct sock *sock, u8 res); +int pn_sock_unbind_res(struct sock *sk, u8 res); +void pn_sock_unbind_all_res(struct sock *sk); + int pn_skb_send(struct sock *sk, struct sk_buff *skb, const struct sockaddr_pn *target); diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h index 2d16783d5e201232d8ff47c1165d767ea91435de..13649eb57413d1058176459e9103688540b6213f 100644 --- a/include/net/phonet/pn_dev.h +++ b/include/net/phonet/pn_dev.h @@ -57,5 +57,6 @@ struct net_device *phonet_route_output(struct net *net, u8 daddr); #define PN_NO_ADDR 0xff extern const struct file_operations pn_sock_seq_fops; +extern const struct file_operations pn_res_seq_fops; #endif diff --git a/include/net/raw.h b/include/net/raw.h index 43c57502659b230c637d9c8d1e21aa986bde3de9..42ce6fe7a2d519c84c0f171cebaad87f537b23b9 100644 --- a/include/net/raw.h +++ b/include/net/raw.h @@ -45,7 +45,10 @@ struct raw_iter_state { struct raw_hashinfo *h; }; -#define raw_seq_private(seq) ((struct raw_iter_state *)(seq)->private) +static inline struct raw_iter_state *raw_seq_private(struct seq_file *seq) +{ + return seq->private; +} void *raw_seq_start(struct seq_file *seq, loff_t *pos); void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos); void raw_seq_stop(struct seq_file *seq, void *v); diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index af60fd050844e6f8178290ff533bd1e37ecf1c4f..e013c68bfb0047330f27d50cdb5714957b997403 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -79,7 +79,6 @@ struct rtnl_link_ops { extern int __rtnl_link_register(struct rtnl_link_ops *ops); extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); -extern void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops); extern int rtnl_link_register(struct rtnl_link_ops *ops); extern void rtnl_link_unregister(struct rtnl_link_ops *ops); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 3c8728aaab4e061a53a80fd12810548c25fed168..ea1f8a83160df419e986d51ad864a14a215cbea3 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -328,8 +328,7 @@ extern void qdisc_destroy(struct Qdisc *qdisc); extern void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n); extern struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, struct Qdisc_ops *ops); -extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, - struct netdev_queue *dev_queue, +extern struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, struct Qdisc_ops *ops, u32 parentid); extern void qdisc_calculate_pkt_len(struct sk_buff *skb, struct qdisc_size_table *stab); @@ -601,7 +600,7 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen) slot = 0; slot >>= rtab->rate.cell_log; if (slot > 255) - return (rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF]); + return rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF]; return rtab->data[slot]; } diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 65946bc43d00876e4c90165627cb46ee68f4d8e0..505845ddb0bec9445478f1810623f13df27e5a82 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -275,24 +275,35 @@ struct sctp_mib { /* Print debugging messages. */ #if SCTP_DEBUG extern int sctp_debug_flag; -#define SCTP_DEBUG_PRINTK(whatever...) \ - ((void) (sctp_debug_flag && printk(KERN_DEBUG whatever))) -#define SCTP_DEBUG_PRINTK_IPADDR(lead, trail, leadparm, saddr, otherparms...) \ - if (sctp_debug_flag) { \ - if (saddr->sa.sa_family == AF_INET6) { \ - printk(KERN_DEBUG \ - lead "%pI6" trail, \ - leadparm, \ - &saddr->v6.sin6_addr, \ - otherparms); \ - } else { \ - printk(KERN_DEBUG \ - lead "%pI4" trail, \ - leadparm, \ - &saddr->v4.sin_addr.s_addr, \ - otherparms); \ - } \ - } +#define SCTP_DEBUG_PRINTK(fmt, args...) \ +do { \ + if (sctp_debug_flag) \ + printk(KERN_DEBUG pr_fmt(fmt), ##args); \ +} while (0) +#define SCTP_DEBUG_PRINTK_CONT(fmt, args...) \ +do { \ + if (sctp_debug_flag) \ + pr_cont(fmt, ##args); \ +} while (0) +#define SCTP_DEBUG_PRINTK_IPADDR(fmt_lead, fmt_trail, \ + args_lead, saddr, args_trail...) \ +do { \ + if (sctp_debug_flag) { \ + if (saddr->sa.sa_family == AF_INET6) { \ + printk(KERN_DEBUG \ + pr_fmt(fmt_lead "%pI6" fmt_trail), \ + args_lead, \ + &saddr->v6.sin6_addr, \ + args_trail); \ + } else { \ + printk(KERN_DEBUG \ + pr_fmt(fmt_lead "%pI4" fmt_trail), \ + args_lead, \ + &saddr->v4.sin_addr.s_addr, \ + args_trail); \ + } \ + } \ +} while (0) #define SCTP_ENABLE_DEBUG { sctp_debug_flag = 1; } #define SCTP_DISABLE_DEBUG { sctp_debug_flag = 0; } @@ -306,6 +317,7 @@ extern int sctp_debug_flag; #else /* SCTP_DEBUG */ #define SCTP_DEBUG_PRINTK(whatever...) +#define SCTP_DEBUG_PRINTK_CONT(fmt, args...) #define SCTP_DEBUG_PRINTK_IPADDR(whatever...) #define SCTP_ENABLE_DEBUG #define SCTP_DISABLE_DEBUG @@ -393,7 +405,7 @@ static inline void sctp_v6_del_protocol(void) { return; } /* Map an association to an assoc_id. */ static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc) { - return (asoc?asoc->assoc_id:0); + return asoc ? asoc->assoc_id : 0; } /* Look up the association by its id. */ @@ -461,7 +473,7 @@ static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk) /* Tests if the list has one and only one entry. */ static inline int sctp_list_single_entry(struct list_head *head) { - return ((head->next != head) && (head->next == head->prev)); + return (head->next != head) && (head->next == head->prev); } /* Generate a random jitter in the range of -50% ~ +50% of input RTO. */ @@ -619,13 +631,13 @@ static inline int sctp_sanity_check(void) /* This is the hash function for the SCTP port hash table. */ static inline int sctp_phashfn(__u16 lport) { - return (lport & (sctp_port_hashsize - 1)); + return lport & (sctp_port_hashsize - 1); } /* This is the hash function for the endpoint hash table. */ static inline int sctp_ep_hashfn(__u16 lport) { - return (lport & (sctp_ep_hashsize - 1)); + return lport & (sctp_ep_hashsize - 1); } /* This is the hash function for the association hash table. */ @@ -633,7 +645,7 @@ static inline int sctp_assoc_hashfn(__u16 lport, __u16 rport) { int h = (lport << 16) + rport; h ^= h>>8; - return (h & (sctp_assoc_hashsize - 1)); + return h & (sctp_assoc_hashsize - 1); } /* This is the hash function for the association hash table. This is @@ -644,7 +656,7 @@ static inline int sctp_vtag_hashfn(__u16 lport, __u16 rport, __u32 vtag) { int h = (lport << 16) + rport; h ^= vtag; - return (h & (sctp_assoc_hashsize-1)); + return h & (sctp_assoc_hashsize - 1); } #define sctp_for_each_hentry(epb, node, head) \ diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 4088c89a9055ee5b0a33bc72690f431fa701a1b8..9352d12f02de01f45c83a3f47b4c423ae872f8eb 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -345,12 +345,12 @@ enum { static inline int TSN_lt(__u32 s, __u32 t) { - return (((s) - (t)) & TSN_SIGN_BIT); + return ((s) - (t)) & TSN_SIGN_BIT; } static inline int TSN_lte(__u32 s, __u32 t) { - return (((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT)); + return ((s) == (t)) || (((s) - (t)) & TSN_SIGN_BIT); } /* Compare two SSNs */ @@ -369,12 +369,12 @@ enum { static inline int SSN_lt(__u16 s, __u16 t) { - return (((s) - (t)) & SSN_SIGN_BIT); + return ((s) - (t)) & SSN_SIGN_BIT; } static inline int SSN_lte(__u16 s, __u16 t) { - return (((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT)); + return ((s) == (t)) || (((s) - (t)) & SSN_SIGN_BIT); } /* @@ -388,7 +388,7 @@ enum { static inline int ADDIP_SERIAL_gte(__u16 s, __u16 t) { - return (((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT)); + return ((s) == (t)) || (((t) - (s)) & ADDIP_SERIAL_SIGN_BIT); } /* Check VTAG of the packet matches the sender's own tag. */ diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index f9e7473613bdbb038aad94befb0807040c20b774..69fef4fb79c078e775520fa047b15c92e88f6116 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -847,7 +847,7 @@ void sctp_packet_free(struct sctp_packet *); static inline int sctp_packet_empty(struct sctp_packet *packet) { - return (packet->size == packet->overhead); + return packet->size == packet->overhead; } /* This represents a remote transport address. diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h index 4aabc5a96cf675f150a7b6823e8a4c787765cf7e..e7728bc14ccfde5bd85c3b08f990487af66ab072 100644 --- a/include/net/sctp/tsnmap.h +++ b/include/net/sctp/tsnmap.h @@ -157,7 +157,7 @@ __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map); /* Is there a gap in the TSN map? */ static inline int sctp_tsnmap_has_gap(const struct sctp_tsnmap *map) { - return (map->cumulative_tsn_ack_point != map->max_tsn_seen); + return map->cumulative_tsn_ack_point != map->max_tsn_seen; } /* Mark a duplicate TSN. Note: limit the storage of duplicate TSN diff --git a/include/net/sock.h b/include/net/sock.h index adab9dc5818355c603a699101c4787c99434eb12..73a4f9702a65c816c3701ab7fa9777fdbcaa2c72 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1558,7 +1558,11 @@ static inline void sk_wake_async(struct sock *sk, int how, int band) } #define SOCK_MIN_SNDBUF 2048 -#define SOCK_MIN_RCVBUF 256 +/* + * Since sk_rmem_alloc sums skb->truesize, even a small frame might need + * sizeof(sk_buff) + MTU + padding, unless net driver perform copybreak + */ +#define SOCK_MIN_RCVBUF (2048 + sizeof(struct sk_buff)) static inline void sk_stream_moderate_sndbuf(struct sock *sk) { @@ -1670,17 +1674,13 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, /** * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped - * @msg: outgoing packet * @sk: socket sending this packet - * @shtx: filled with instructions for time stamping + * @tx_flags: filled with instructions for time stamping * * Currently only depends on SOCK_TIMESTAMPING* flags. Returns error code if * parameters are invalid. */ -extern int sock_tx_timestamp(struct msghdr *msg, - struct sock *sk, - union skb_shared_tx *shtx); - +extern int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags); /** * sk_eat_skb - Release a skb if it is no longer needed diff --git a/include/net/tc_act/tc_csum.h b/include/net/tc_act/tc_csum.h new file mode 100644 index 0000000000000000000000000000000000000000..9e8710be7a04f0d43cd8358bd07208e5a6adb14a --- /dev/null +++ b/include/net/tc_act/tc_csum.h @@ -0,0 +1,15 @@ +#ifndef __NET_TC_CSUM_H +#define __NET_TC_CSUM_H + +#include +#include + +struct tcf_csum { + struct tcf_common common; + + u32 update_flags; +}; +#define to_tcf_csum(pc) \ + container_of(pc,struct tcf_csum,common) + +#endif /* __NET_TC_CSUM_H */ diff --git a/include/net/tcp.h b/include/net/tcp.h index 3e4b33e36602caade361654d0561a65b3fba2224..4fee0424af7eff7a053f0eef9376ad2644b2b723 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -346,8 +346,6 @@ static inline void tcp_dec_quickack_mode(struct sock *sk, } } -extern void tcp_enter_quickack_mode(struct sock *sk); - #define TCP_ECN_OK 1 #define TCP_ECN_QUEUE_CWR 2 #define TCP_ECN_DEMAND_CWR 4 @@ -803,6 +801,15 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk) /* Use define here intentionally to get WARN_ON location shown at the caller */ #define tcp_verify_left_out(tp) WARN_ON(tcp_left_out(tp) > tp->packets_out) +/* + * Convert RFC 3390 larger initial window into an equivalent number of packets. + * This is based on the numbers specified in RFC 5681, 3.1. + */ +static inline u32 rfc3390_bytes_to_packets(const u32 smss) +{ + return smss <= 1095 ? 4 : (smss > 2190 ? 2 : 3); +} + extern void tcp_enter_cwr(struct sock *sk, const int set_ssthresh); extern __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst); diff --git a/include/net/tipc/tipc.h b/include/net/tipc/tipc.h index 15af6dca0b493f982f6de117402a19f04c7b03a1..1e0645e1eed22c9b26156c6f285b68f1be38256e 100644 --- a/include/net/tipc/tipc.h +++ b/include/net/tipc/tipc.h @@ -50,8 +50,6 @@ * TIPC operating mode routines */ -u32 tipc_get_addr(void); - #define TIPC_NOT_RUNNING 0 #define TIPC_NODE_MODE 1 #define TIPC_NET_MODE 2 @@ -62,8 +60,6 @@ int tipc_attach(unsigned int *userref, tipc_mode_event, void *usr_handle); void tipc_detach(unsigned int userref); -int tipc_get_mode(void); - /* * TIPC port manipulation routines */ @@ -153,12 +149,6 @@ int tipc_disconnect(u32 portref); int tipc_shutdown(u32 ref); -int tipc_isconnected(u32 portref, int *isconnected); - -int tipc_peer(u32 portref, struct tipc_portid *peer); - -int tipc_ref_valid(u32 portref); - /* * TIPC messaging routines */ @@ -170,38 +160,12 @@ int tipc_send(u32 portref, unsigned int num_sect, struct iovec const *msg_sect); -int tipc_send_buf(u32 portref, - struct sk_buff *buf, - unsigned int dsz); - int tipc_send2name(u32 portref, struct tipc_name const *name, u32 domain, unsigned int num_sect, struct iovec const *msg_sect); -int tipc_send_buf2name(u32 portref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz); - -int tipc_forward2name(u32 portref, - struct tipc_name const *name, - u32 domain, - unsigned int section_count, - struct iovec const *msg_sect, - struct tipc_portid const *origin, - unsigned int importance); - -int tipc_forward_buf2name(u32 portref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance); - int tipc_send2port(u32 portref, struct tipc_portid const *dest, unsigned int num_sect, @@ -212,46 +176,11 @@ int tipc_send_buf2port(u32 portref, struct sk_buff *buf, unsigned int dsz); -int tipc_forward2port(u32 portref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *origin, - unsigned int importance); - -int tipc_forward_buf2port(u32 portref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance); - int tipc_multicast(u32 portref, struct tipc_name_seq const *seq, u32 domain, /* currently unused */ unsigned int section_count, struct iovec const *msg); - -#if 0 -int tipc_multicast_buf(u32 portref, - struct tipc_name_seq const *seq, - u32 domain, - void *buf, - unsigned int size); -#endif - -/* - * TIPC subscription routines - */ - -int tipc_ispublished(struct tipc_name const *name); - -/* - * Get number of available nodes within specified domain (excluding own node) - */ - -unsigned int tipc_available_nodes(const u32 domain); - #endif #endif diff --git a/include/net/tipc/tipc_msg.h b/include/net/tipc/tipc_msg.h index 2e159a812f83e5271e9553897d37b7b878360917..ffe50b4e7b9333d4b47e5b07294c16e6adcda2b7 100644 --- a/include/net/tipc/tipc_msg.h +++ b/include/net/tipc/tipc_msg.h @@ -107,7 +107,7 @@ static inline u32 msg_hdr_sz(struct tipc_msg *m) static inline int msg_short(struct tipc_msg *m) { - return (msg_hdr_sz(m) == 24); + return msg_hdr_sz(m) == 24; } static inline u32 msg_size(struct tipc_msg *m) @@ -117,7 +117,7 @@ static inline u32 msg_size(struct tipc_msg *m) static inline u32 msg_data_sz(struct tipc_msg *m) { - return (msg_size(m) - msg_hdr_sz(m)); + return msg_size(m) - msg_hdr_sz(m); } static inline unchar *msg_data(struct tipc_msg *m) @@ -132,17 +132,17 @@ static inline u32 msg_type(struct tipc_msg *m) static inline u32 msg_named(struct tipc_msg *m) { - return (msg_type(m) == TIPC_NAMED_MSG); + return msg_type(m) == TIPC_NAMED_MSG; } static inline u32 msg_mcast(struct tipc_msg *m) { - return (msg_type(m) == TIPC_MCAST_MSG); + return msg_type(m) == TIPC_MCAST_MSG; } static inline u32 msg_connected(struct tipc_msg *m) { - return (msg_type(m) == TIPC_CONN_MSG); + return msg_type(m) == TIPC_CONN_MSG; } static inline u32 msg_errcode(struct tipc_msg *m) diff --git a/include/net/tipc/tipc_port.h b/include/net/tipc/tipc_port.h index c54917cbfa48fb3ea792db913c51b7fcc823672a..1893aaf49426cc27ac95d292babc27d5c0398e2c 100644 --- a/include/net/tipc/tipc_port.h +++ b/include/net/tipc/tipc_port.h @@ -88,8 +88,6 @@ void tipc_acknowledge(u32 port_ref,u32 ack); struct tipc_port *tipc_get_port(const u32 ref); -void *tipc_get_handle(const u32 ref); - /* * The following routines require that the port be locked on entry */ diff --git a/include/net/udp.h b/include/net/udp.h index a184d3496b1369deefd62aba376f04320f76a773..200b82848c9a3606b0076c3f8621fb63342af6a9 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -183,6 +183,9 @@ extern int udp_lib_setsockopt(struct sock *sk, int level, int optname, extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport, __be32 daddr, __be16 dport, int dif); +extern struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, + int dif); /* * SNMP statistics for UDP and UDP-Lite diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 4f53532d4c2f0f6e20d200fabafe1ac51dd1632c..f28d7c9b9f8d4d46978e83060e51dbbcda32bf3b 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1419,7 +1419,6 @@ extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family); extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family); extern __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); -extern void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr); extern __be32 xfrm6_tunnel_spi_lookup(struct net *net, xfrm_address_t *saddr); extern int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); extern int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); @@ -1466,8 +1465,6 @@ struct xfrm_state *xfrm_find_acq(struct net *net, struct xfrm_mark *mark, xfrm_address_t *saddr, int create, unsigned short family); extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol); -extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, - struct flowi *fl, int family, int strict); #ifdef CONFIG_XFRM_MIGRATE extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, diff --git a/net/802/fc.c b/net/802/fc.c index 34cf1ee014b8a10e668408052ff916916630906c..1e49f2d4ea9624e804ae0588d96976e32430bc9a 100644 --- a/net/802/fc.c +++ b/net/802/fc.c @@ -70,7 +70,7 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev, if(daddr) { memcpy(fch->daddr,daddr,dev->addr_len); - return(hdr_len); + return hdr_len; } return -hdr_len; } diff --git a/net/802/fddi.c b/net/802/fddi.c index 3ef0ab0a543a5bfbf7e4b4cc709ba7919c82bfa5..94b3ad08f39a12ce92d5ccd9d65ade1d01157470 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c @@ -82,10 +82,10 @@ static int fddi_header(struct sk_buff *skb, struct net_device *dev, if (daddr != NULL) { memcpy(fddi->daddr, daddr, dev->addr_len); - return(hl); + return hl; } - return(-hl); + return -hl; } @@ -108,7 +108,7 @@ static int fddi_rebuild_header(struct sk_buff *skb) { printk("%s: Don't know how to resolve type %04X addresses.\n", skb->dev->name, ntohs(fddi->hdr.llc_snap.ethertype)); - return(0); + return 0; } } @@ -162,7 +162,7 @@ __be16 fddi_type_trans(struct sk_buff *skb, struct net_device *dev) /* Assume 802.2 SNAP frames, for now */ - return(type); + return type; } EXPORT_SYMBOL(fddi_type_trans); @@ -170,9 +170,9 @@ EXPORT_SYMBOL(fddi_type_trans); int fddi_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < FDDI_K_SNAP_HLEN) || (new_mtu > FDDI_K_SNAP_DLEN)) - return(-EINVAL); + return -EINVAL; dev->mtu = new_mtu; - return(0); + return 0; } EXPORT_SYMBOL(fddi_change_mtu); diff --git a/net/802/hippi.c b/net/802/hippi.c index cd3e8e9295295fd3746cc20bd9068de5c7338d5b..91aca8780fd05bea28a084dced4821cfb48caf3b 100644 --- a/net/802/hippi.c +++ b/net/802/hippi.c @@ -152,7 +152,7 @@ int hippi_change_mtu(struct net_device *dev, int new_mtu) if ((new_mtu < 68) || (new_mtu > 65280)) return -EINVAL; dev->mtu = new_mtu; - return(0); + return 0; } EXPORT_SYMBOL(hippi_change_mtu); diff --git a/net/802/tr.c b/net/802/tr.c index 1c6e596074dff99fe4571ff4df1d40c081186f01..5e20cf8a074bb56429320118b460b06dba8b0466 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -145,7 +145,7 @@ static int tr_header(struct sk_buff *skb, struct net_device *dev, { memcpy(trh->daddr,daddr,dev->addr_len); tr_source_route(skb, trh, dev); - return(hdr_len); + return hdr_len; } return -hdr_len; diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index a2ad1525057590ef6fce28eb342a101ae8c2ed19..05b867e43757dadceaf89d1287b5209a60ca5a65 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -44,9 +44,6 @@ int vlan_net_id __read_mostly; -/* Our listing of VLAN group(s) */ -static struct hlist_head vlan_group_hash[VLAN_GRP_HASH_SIZE]; - const char vlan_fullname[] = "802.1Q VLAN Support"; const char vlan_version[] = DRV_VERSION; static const char vlan_copyright[] = "Ben Greear "; @@ -59,40 +56,6 @@ static struct packet_type vlan_packet_type __read_mostly = { /* End of global variables definitions. */ -static inline unsigned int vlan_grp_hashfn(unsigned int idx) -{ - return ((idx >> VLAN_GRP_HASH_SHIFT) ^ idx) & VLAN_GRP_HASH_MASK; -} - -/* Must be invoked with RCU read lock (no preempt) */ -static struct vlan_group *__vlan_find_group(struct net_device *real_dev) -{ - struct vlan_group *grp; - struct hlist_node *n; - int hash = vlan_grp_hashfn(real_dev->ifindex); - - hlist_for_each_entry_rcu(grp, n, &vlan_group_hash[hash], hlist) { - if (grp->real_dev == real_dev) - return grp; - } - - return NULL; -} - -/* Find the protocol handler. Assumes VID < VLAN_VID_MASK. - * - * Must be invoked with RCU read lock (no preempt) - */ -struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id) -{ - struct vlan_group *grp = __vlan_find_group(real_dev); - - if (grp) - return vlan_group_get_device(grp, vlan_id); - - return NULL; -} - static void vlan_group_free(struct vlan_group *grp) { int i; @@ -111,8 +74,6 @@ static struct vlan_group *vlan_group_alloc(struct net_device *real_dev) return NULL; grp->real_dev = real_dev; - hlist_add_head_rcu(&grp->hlist, - &vlan_group_hash[vlan_grp_hashfn(real_dev->ifindex)]); return grp; } @@ -151,7 +112,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) ASSERT_RTNL(); - grp = __vlan_find_group(real_dev); + grp = real_dev->vlgrp; BUG_ON(!grp); /* Take it out of our own structures, but be sure to interlock with @@ -173,11 +134,10 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) if (grp->nr_vlans == 0) { vlan_gvrp_uninit_applicant(real_dev); - if (real_dev->features & NETIF_F_HW_VLAN_RX) + rcu_assign_pointer(real_dev->vlgrp, NULL); + if (ops->ndo_vlan_rx_register) ops->ndo_vlan_rx_register(real_dev, NULL); - hlist_del_rcu(&grp->hlist); - /* Free the group, after all cpu's are done. */ call_rcu(&grp->rcu, vlan_rcu_free); } @@ -196,18 +156,13 @@ int vlan_check_real_dev(struct net_device *real_dev, u16 vlan_id) return -EOPNOTSUPP; } - if ((real_dev->features & NETIF_F_HW_VLAN_RX) && !ops->ndo_vlan_rx_register) { - pr_info("8021q: device %s has buggy VLAN hw accel\n", name); - return -EOPNOTSUPP; - } - if ((real_dev->features & NETIF_F_HW_VLAN_FILTER) && (!ops->ndo_vlan_rx_add_vid || !ops->ndo_vlan_rx_kill_vid)) { pr_info("8021q: Device %s has buggy VLAN hw accel\n", name); return -EOPNOTSUPP; } - if (__find_vlan_dev(real_dev, vlan_id) != NULL) + if (vlan_find_dev(real_dev, vlan_id) != NULL) return -EEXIST; return 0; @@ -222,7 +177,7 @@ int register_vlan_dev(struct net_device *dev) struct vlan_group *grp, *ngrp = NULL; int err; - grp = __vlan_find_group(real_dev); + grp = real_dev->vlgrp; if (!grp) { ngrp = grp = vlan_group_alloc(real_dev); if (!grp) @@ -252,8 +207,11 @@ int register_vlan_dev(struct net_device *dev) vlan_group_set_device(grp, vlan_id, dev); grp->nr_vlans++; - if (ngrp && real_dev->features & NETIF_F_HW_VLAN_RX) - ops->ndo_vlan_rx_register(real_dev, ngrp); + if (ngrp) { + if (ops->ndo_vlan_rx_register) + ops->ndo_vlan_rx_register(real_dev, ngrp); + rcu_assign_pointer(real_dev->vlgrp, ngrp); + } if (real_dev->features & NETIF_F_HW_VLAN_FILTER) ops->ndo_vlan_rx_add_vid(real_dev, vlan_id); @@ -264,7 +222,6 @@ int register_vlan_dev(struct net_device *dev) vlan_gvrp_uninit_applicant(real_dev); out_free_group: if (ngrp) { - hlist_del_rcu(&ngrp->hlist); /* Free the group, after all cpu's are done. */ call_rcu(&ngrp->rcu, vlan_rcu_free); } @@ -321,7 +278,7 @@ static int register_vlan_device(struct net_device *real_dev, u16 vlan_id) if (new_dev == NULL) return -ENOBUFS; - new_dev->real_num_tx_queues = real_dev->real_num_tx_queues; + netif_copy_real_num_queues(new_dev, real_dev); dev_net_set(new_dev, net); /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. @@ -428,7 +385,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, dev->netdev_ops->ndo_vlan_rx_add_vid(dev, 0); } - grp = __vlan_find_group(dev); + grp = dev->vlgrp; if (!grp) goto out; @@ -439,7 +396,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, switch (event) { case NETDEV_CHANGE: /* Propagate real device state to vlan devices */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -450,7 +407,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_CHANGEADDR: /* Adjust unicast filters on underlying device */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -464,7 +421,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, break; case NETDEV_CHANGEMTU: - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -478,7 +435,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_FEAT_CHANGE: /* Propagate device features to underlying device */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -490,7 +447,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_DOWN: /* Put all VLANs for this dev in the down state too. */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -508,7 +465,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, case NETDEV_UP: /* Put all VLANs for this dev in the up state too. */ - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -525,10 +482,14 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, break; case NETDEV_UNREGISTER: + /* twiddle thumbs on netns device moves */ + if (dev->reg_state != NETREG_UNREGISTERING) + break; + /* Delete all VLANs for this dev. */ grp->killall = 1; - for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { + for (i = 0; i < VLAN_N_VID; i++) { vlandev = vlan_group_get_device(grp, i); if (!vlandev) continue; @@ -536,7 +497,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event, /* unregistration of last vlan destroys group, abort * afterwards */ if (grp->nr_vlans == 1) - i = VLAN_GROUP_ARRAY_LEN; + i = VLAN_N_VID; unregister_vlan_dev(vlandev, &list); } @@ -742,8 +703,6 @@ static int __init vlan_proto_init(void) static void __exit vlan_cleanup_module(void) { - unsigned int i; - vlan_ioctl_set(NULL); vlan_netlink_fini(); @@ -751,10 +710,6 @@ static void __exit vlan_cleanup_module(void) dev_remove_pack(&vlan_packet_type); - /* This table must be empty if there are no module references left. */ - for (i = 0; i < VLAN_GRP_HASH_SIZE; i++) - BUG_ON(!hlist_empty(&vlan_group_hash[i])); - unregister_pernet_subsys(&vlan_net_ops); rcu_barrier(); /* Wait for completion of call_rcu()'s */ diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 8d9503ad01daa65729212de33f579b32aeffc1dc..db01b3181fdc4a9cd950dfaf60df1abecdec294f 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -72,23 +72,6 @@ static inline struct vlan_dev_info *vlan_dev_info(const struct net_device *dev) return netdev_priv(dev); } -#define VLAN_GRP_HASH_SHIFT 5 -#define VLAN_GRP_HASH_SIZE (1 << VLAN_GRP_HASH_SHIFT) -#define VLAN_GRP_HASH_MASK (VLAN_GRP_HASH_SIZE - 1) - -/* Find a VLAN device by the MAC address of its Ethernet device, and - * it's VLAN ID. The default configuration is to have VLAN's scope - * to be box-wide, so the MAC will be ignored. The mac will only be - * looked at if we are configured to have a separate set of VLANs per - * each MAC addressable interface. Note that this latter option does - * NOT follow the spec for VLANs, but may be useful for doing very - * large quantities of VLAN MUX/DEMUX onto FrameRelay or ATM PVCs. - * - * Must be invoked with rcu_read_lock (ie preempt disabled) - * or with RTNL. - */ -struct net_device *__find_vlan_dev(struct net_device *real_dev, u16 vlan_id); - /* found in vlan_dev.c */ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev); diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 0eb96f7e44befb0155e364749f38eb37af0c2354..69b2f79800a52c3e07e0f7c668daa1028025931e 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -4,53 +4,29 @@ #include #include "vlan.h" -/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ -int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, - u16 vlan_tci, int polling) +bool vlan_hwaccel_do_receive(struct sk_buff **skbp) { + struct sk_buff *skb = *skbp; + u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; struct net_device *vlan_dev; - u16 vlan_id; - - if (netpoll_rx(skb)) - return NET_RX_DROP; - - if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) - skb->deliver_no_wcard = 1; + struct vlan_rx_stats *rx_stats; - skb->skb_iif = skb->dev->ifindex; - __vlan_hwaccel_put_tag(skb, vlan_tci); - vlan_id = vlan_tci & VLAN_VID_MASK; - vlan_dev = vlan_group_get_device(grp, vlan_id); - - if (vlan_dev) - skb->dev = vlan_dev; - else if (vlan_id) { - if (!(skb->dev->flags & IFF_PROMISC)) - goto drop; - skb->pkt_type = PACKET_OTHERHOST; + vlan_dev = vlan_find_dev(skb->dev, vlan_id); + if (!vlan_dev) { + if (vlan_id) + skb->pkt_type = PACKET_OTHERHOST; + return false; } - return (polling ? netif_receive_skb(skb) : netif_rx(skb)); + skb = *skbp = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) + return false; -drop: - dev_kfree_skb_any(skb); - return NET_RX_DROP; -} -EXPORT_SYMBOL(__vlan_hwaccel_rx); - -int vlan_hwaccel_do_receive(struct sk_buff *skb) -{ - struct net_device *dev = skb->dev; - struct vlan_rx_stats *rx_stats; - - skb->dev = vlan_dev_info(dev)->real_dev; - netif_nit_deliver(skb); - - skb->dev = dev; - skb->priority = vlan_get_ingress_priority(dev, skb->vlan_tci); + skb->dev = vlan_dev; + skb->priority = vlan_get_ingress_priority(vlan_dev, skb->vlan_tci); skb->vlan_tci = 0; - rx_stats = this_cpu_ptr(vlan_dev_info(dev)->vlan_rx_stats); + rx_stats = this_cpu_ptr(vlan_dev_info(vlan_dev)->vlan_rx_stats); u64_stats_update_begin(&rx_stats->syncp); rx_stats->rx_packets++; @@ -67,12 +43,13 @@ int vlan_hwaccel_do_receive(struct sk_buff *skb) * This allows the VLAN to have a different MAC than the * underlying device, and still route correctly. */ if (!compare_ether_addr(eth_hdr(skb)->h_dest, - dev->dev_addr)) + vlan_dev->dev_addr)) skb->pkt_type = PACKET_HOST; break; } u64_stats_update_end(&rx_stats->syncp); - return 0; + + return true; } struct net_device *vlan_dev_real_dev(const struct net_device *dev) @@ -87,71 +64,27 @@ u16 vlan_dev_vlan_id(const struct net_device *dev) } EXPORT_SYMBOL(vlan_dev_vlan_id); -static gro_result_t -vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp, - unsigned int vlan_tci, struct sk_buff *skb) +/* VLAN rx hw acceleration helper. This acts like netif_{rx,receive_skb}(). */ +int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, + u16 vlan_tci, int polling) { - struct sk_buff *p; - struct net_device *vlan_dev; - u16 vlan_id; - - if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) - skb->deliver_no_wcard = 1; - - skb->skb_iif = skb->dev->ifindex; __vlan_hwaccel_put_tag(skb, vlan_tci); - vlan_id = vlan_tci & VLAN_VID_MASK; - vlan_dev = vlan_group_get_device(grp, vlan_id); - - if (vlan_dev) - skb->dev = vlan_dev; - else if (vlan_id) { - if (!(skb->dev->flags & IFF_PROMISC)) - goto drop; - skb->pkt_type = PACKET_OTHERHOST; - } - - for (p = napi->gro_list; p; p = p->next) { - NAPI_GRO_CB(p)->same_flow = - p->dev == skb->dev && !compare_ether_header( - skb_mac_header(p), skb_gro_mac_header(skb)); - NAPI_GRO_CB(p)->flush = 0; - } - - return dev_gro_receive(napi, skb); - -drop: - return GRO_DROP; + return polling ? netif_receive_skb(skb) : netif_rx(skb); } +EXPORT_SYMBOL(__vlan_hwaccel_rx); gro_result_t vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci, struct sk_buff *skb) { - if (netpoll_rx_on(skb)) - return vlan_hwaccel_receive_skb(skb, grp, vlan_tci) - ? GRO_DROP : GRO_NORMAL; - - skb_gro_reset_offset(skb); - - return napi_skb_finish(vlan_gro_common(napi, grp, vlan_tci, skb), skb); + __vlan_hwaccel_put_tag(skb, vlan_tci); + return napi_gro_receive(napi, skb); } EXPORT_SYMBOL(vlan_gro_receive); gro_result_t vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp, unsigned int vlan_tci) { - struct sk_buff *skb = napi_frags_skb(napi); - - if (!skb) - return GRO_DROP; - - if (netpoll_rx_on(skb)) { - skb->protocol = eth_type_trans(skb, skb->dev); - return vlan_hwaccel_receive_skb(skb, grp, vlan_tci) - ? GRO_DROP : GRO_NORMAL; - } - - return napi_frags_finish(napi, skb, - vlan_gro_common(napi, grp, vlan_tci, skb)); + __vlan_hwaccel_put_tag(napi->skb, vlan_tci); + return napi_gro_frags(napi); } EXPORT_SYMBOL(vlan_gro_frags); diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 3bccdd12a2642a06e1c5078b5c4065419a57428a..14e3d1fa07a0f70df457515f3aede2d31e77c9cb 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -158,7 +158,7 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, vlan_id = vlan_tci & VLAN_VID_MASK; rcu_read_lock(); - vlan_dev = __find_vlan_dev(dev, vlan_id); + vlan_dev = vlan_find_dev(dev, vlan_id); /* If the VLAN device is defined, we use it. * If not, and the VID is 0, it is a 802.1p packet (not @@ -177,8 +177,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, } else { skb->dev = vlan_dev; - rx_stats = per_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats, - smp_processor_id()); + rx_stats = this_cpu_ptr(vlan_dev_info(skb->dev)->vlan_rx_stats); + u64_stats_update_begin(&rx_stats->syncp); rx_stats->rx_packets++; rx_stats->rx_bytes += skb->len; @@ -226,12 +226,14 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev, } netif_rx(skb); + rcu_read_unlock(); return NET_RX_SUCCESS; err_unlock: rcu_read_unlock(); err_free: + atomic_long_inc(&dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; } @@ -843,7 +845,7 @@ static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, st accum.rx_packets += rxpackets; accum.rx_bytes += rxbytes; accum.rx_multicast += rxmulticast; - /* rx_errors is an ulong, not protected by syncp */ + /* rx_errors is ulong, not protected by syncp */ accum.rx_errors += p->rx_errors; } stats->rx_packets = accum.rx_packets; diff --git a/net/9p/client.c b/net/9p/client.c index 9eb72505308fc697d2857737f8dd3f4ec04d5bd3..83bf0541d66f5889f129ac800d764b06b925e37d 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -61,13 +61,13 @@ static const match_table_t tokens = { inline int p9_is_proto_dotl(struct p9_client *clnt) { - return (clnt->proto_version == p9_proto_2000L); + return clnt->proto_version == p9_proto_2000L; } EXPORT_SYMBOL(p9_is_proto_dotl); inline int p9_is_proto_dotu(struct p9_client *clnt) { - return (clnt->proto_version == p9_proto_2000u); + return clnt->proto_version == p9_proto_2000u; } EXPORT_SYMBOL(p9_is_proto_dotu); @@ -671,7 +671,7 @@ static void p9_fid_destroy(struct p9_fid *fid) kfree(fid); } -int p9_client_version(struct p9_client *c) +static int p9_client_version(struct p9_client *c) { int err = 0; struct p9_req_t *req; @@ -730,7 +730,6 @@ int p9_client_version(struct p9_client *c) return err; } -EXPORT_SYMBOL(p9_client_version); struct p9_client *p9_client_create(const char *dev_name, char *options) { @@ -887,54 +886,6 @@ struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid, } EXPORT_SYMBOL(p9_client_attach); -struct p9_fid * -p9_client_auth(struct p9_client *clnt, char *uname, u32 n_uname, char *aname) -{ - int err; - struct p9_req_t *req; - struct p9_qid qid; - struct p9_fid *afid; - - P9_DPRINTK(P9_DEBUG_9P, ">>> TAUTH uname %s aname %s\n", uname, aname); - err = 0; - - afid = p9_fid_create(clnt); - if (IS_ERR(afid)) { - err = PTR_ERR(afid); - afid = NULL; - goto error; - } - - req = p9_client_rpc(clnt, P9_TAUTH, "dss?d", - afid ? afid->fid : P9_NOFID, uname, aname, n_uname); - if (IS_ERR(req)) { - err = PTR_ERR(req); - goto error; - } - - err = p9pdu_readf(req->rc, clnt->proto_version, "Q", &qid); - if (err) { - p9pdu_dump(1, req->rc); - p9_free_req(clnt, req); - goto error; - } - - P9_DPRINTK(P9_DEBUG_9P, "<<< RAUTH qid %x.%llx.%x\n", - qid.type, - (unsigned long long)qid.path, - qid.version); - - memmove(&afid->qid, &qid, sizeof(struct p9_qid)); - p9_free_req(clnt, req); - return afid; - -error: - if (afid) - p9_fid_destroy(afid); - return ERR_PTR(err); -} -EXPORT_SYMBOL(p9_client_auth); - struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames, int clone) { diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index c85109d809caa4767ef2576c1947fcd877e432b7..078eb162d9bfc4e7d6c05cd5b59c6b8920fec31e 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -222,7 +222,7 @@ static void p9_conn_cancel(struct p9_conn *m, int err) } } -static unsigned int +static int p9_fd_poll(struct p9_client *client, struct poll_table_struct *pt) { int ret, n; diff --git a/net/atm/clip.c b/net/atm/clip.c index 95fdd1185067a859d49d0f5f5ea246e4fcad0893..ff956d1115bcee4636a68011a38457d87bea3cdd 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -310,9 +310,9 @@ static int clip_constructor(struct neighbour *neigh) return 0; } -static u32 clip_hash(const void *pkey, const struct net_device *dev) +static u32 clip_hash(const void *pkey, const struct net_device *dev, __u32 rnd) { - return jhash_2words(*(u32 *) pkey, dev->ifindex, clip_tbl.hash_rnd); + return jhash_2words(*(u32 *) pkey, dev->ifindex, rnd); } static struct neigh_table clip_tbl = { diff --git a/net/atm/common.c b/net/atm/common.c index 940404a73b3dddf05e262a7c5c727784c1a65bf3..1b9c52a02cd31995c63040377d4e24443bad85a3 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -792,7 +792,7 @@ int vcc_getsockopt(struct socket *sock, int level, int optname, default: if (level == SOL_SOCKET) return -EINVAL; - break; + break; } if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL; diff --git a/net/atm/lec.c b/net/atm/lec.c index d98bde1a0ac8ffafb95ef961382a51e2d2c179cb..181d70c73d708bd730f49e4b61f88ac72e373a20 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -220,7 +220,6 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc) static int lec_open(struct net_device *dev) { netif_start_queue(dev); - memset(&dev->stats, 0, sizeof(struct net_device_stats)); return 0; } diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index cfdfd7e2a1726b1399633bdcb6625a6a5731a310..26eaebf4aaa9b11c3b9d8820b835ae07c50219e2 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1103,7 +1103,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) out: release_sock(sk); - return 0; + return err; } /* diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 7805945a5fd6d311f54f26a66dc5ad9c0e83ece1..a1690845dc6ecf9ecb12de37ac2b9342d678de01 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c @@ -412,7 +412,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) { ax25_uid_assoc *user; ax25_route *ax25_rt; - int err; + int err = 0; if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL) return -EHOSTUNREACH; @@ -453,7 +453,7 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) put: ax25_put_route(ax25_rt); - return 0; + return err; } struct sk_buff *ax25_rt_build_path(struct sk_buff *skb, ax25_address *src, diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 421c45bd1b95232e0a4ac7a282fdaeabd18fb21d..c4cf3f595004d3c549e3bfb66e2f138732130c6c 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -265,6 +265,115 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, } EXPORT_SYMBOL(bt_sock_recvmsg); +static long bt_sock_data_wait(struct sock *sk, long timeo) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(sk_sleep(sk), &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + + if (!skb_queue_empty(&sk->sk_receive_queue)) + break; + + if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN)) + break; + + if (signal_pending(current) || !timeo) + break; + + set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + release_sock(sk); + timeo = schedule_timeout(timeo); + lock_sock(sk); + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + } + + __set_current_state(TASK_RUNNING); + remove_wait_queue(sk_sleep(sk), &wait); + return timeo; +} + +int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, + struct msghdr *msg, size_t size, int flags) +{ + struct sock *sk = sock->sk; + int err = 0; + size_t target, copied = 0; + long timeo; + + if (flags & MSG_OOB) + return -EOPNOTSUPP; + + msg->msg_namelen = 0; + + BT_DBG("sk %p size %zu", sk, size); + + lock_sock(sk); + + target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); + timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); + + do { + struct sk_buff *skb; + int chunk; + + skb = skb_dequeue(&sk->sk_receive_queue); + if (!skb) { + if (copied >= target) + break; + + if ((err = sock_error(sk)) != 0) + break; + if (sk->sk_shutdown & RCV_SHUTDOWN) + break; + + err = -EAGAIN; + if (!timeo) + break; + + timeo = bt_sock_data_wait(sk, timeo); + + if (signal_pending(current)) { + err = sock_intr_errno(timeo); + goto out; + } + continue; + } + + chunk = min_t(unsigned int, skb->len, size); + if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { + skb_queue_head(&sk->sk_receive_queue, skb); + if (!copied) + copied = -EFAULT; + break; + } + copied += chunk; + size -= chunk; + + sock_recv_ts_and_drops(msg, sk, skb); + + if (!(flags & MSG_PEEK)) { + skb_pull(skb, chunk); + if (skb->len) { + skb_queue_head(&sk->sk_receive_queue, skb); + break; + } + kfree_skb(skb); + + } else { + /* put message back and return */ + skb_queue_head(&sk->sk_receive_queue, skb); + break; + } + } while (size); + +out: + release_sock(sk); + return copied ? : err; +} +EXPORT_SYMBOL(bt_sock_stream_recvmsg); + static inline unsigned int bt_accept_poll(struct sock *parent) { struct list_head *p, *n; @@ -297,13 +406,12 @@ unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *w mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; if (sk->sk_state == BT_CLOSED) diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index d4c6af082d488f025ff22664fe7274370a2bb061..ec0a1347f933cbdb9ca70be4f869d459f0ec9565 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -321,14 +321,10 @@ static int cmtp_session(void *arg) int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) { struct cmtp_session *session, *s; - bdaddr_t src, dst; int i, err; BT_DBG(""); - baswap(&src, &bt_sk(sock->sk)->src); - baswap(&dst, &bt_sk(sock->sk)->dst); - session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); if (!session) return -ENOMEM; @@ -347,7 +343,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) BT_DBG("mtu %d", session->mtu); - sprintf(session->name, "%s", batostr(&dst)); + sprintf(session->name, "%s", batostr(&bt_sk(sock->sk)->dst)); session->sock = sock; session->state = BT_CONFIG; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c52f091ee6de2c4b1e81f68363086e2af4a51660..bc2a052e518b37518eaf9e128ce418d195bd91e1 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -562,7 +562,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) hci_dev_lock_bh(hdev); inquiry_cache_flush(hdev); hci_conn_hash_flush(hdev); - hci_blacklist_clear(hdev); hci_dev_unlock_bh(hdev); hci_notify(hdev, HCI_DEV_DOWN); diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 8fb967beee80bd617597d5e8f7eba981206361c9..5fce3d6d07b4acc2a656b367121b06478c92061e 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c @@ -37,9 +37,7 @@ static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_conn *conn = dev_get_drvdata(dev); - bdaddr_t bdaddr; - baswap(&bdaddr, &conn->dst); - return sprintf(buf, "%s\n", batostr(&bdaddr)); + return sprintf(buf, "%s\n", batostr(&conn->dst)); } static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf) @@ -196,8 +194,8 @@ static inline char *host_typetostr(int type) switch (type) { case HCI_BREDR: return "BR/EDR"; - case HCI_80211: - return "802.11"; + case HCI_AMP: + return "AMP"; default: return "UNKNOWN"; } @@ -238,9 +236,7 @@ static ssize_t show_class(struct device *dev, struct device_attribute *attr, cha static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = dev_get_drvdata(dev); - bdaddr_t bdaddr; - baswap(&bdaddr, &hdev->bdaddr); - return sprintf(buf, "%s\n", batostr(&bdaddr)); + return sprintf(buf, "%s\n", batostr(&hdev->bdaddr)); } static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf) @@ -408,10 +404,8 @@ static int inquiry_cache_show(struct seq_file *f, void *p) for (e = cache->list; e; e = e->next) { struct inquiry_data *data = &e->data; - bdaddr_t bdaddr; - baswap(&bdaddr, &data->bdaddr); seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n", - batostr(&bdaddr), + batostr(&data->bdaddr), data->pscan_rep_mode, data->pscan_period_mode, data->pscan_mode, data->dev_class[2], data->dev_class[1], data->dev_class[0], @@ -445,13 +439,10 @@ static int blacklist_show(struct seq_file *f, void *p) list_for_each(l, &hdev->blacklist) { struct bdaddr_list *b; - bdaddr_t bdaddr; b = list_entry(l, struct bdaddr_list, list); - baswap(&bdaddr, &b->bdaddr); - - seq_printf(f, "%s\n", batostr(&bdaddr)); + seq_printf(f, "%s\n", batostr(&b->bdaddr)); } hci_dev_unlock_bh(hdev); diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index bfe641b7dfaf0e0ba70fa604ebffec7155cbaec8..c0ee8b3928ed9b97eeaf7ef8d195a222bc2a3225 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -758,7 +758,6 @@ static int hidp_setup_hid(struct hidp_session *session, struct hidp_connadd_req *req) { struct hid_device *hid; - bdaddr_t src, dst; int err; session->rd_data = kzalloc(req->rd_size, GFP_KERNEL); @@ -781,9 +780,6 @@ static int hidp_setup_hid(struct hidp_session *session, hid->driver_data = session; - baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); - baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); - hid->bus = BUS_BLUETOOTH; hid->vendor = req->vendor; hid->product = req->product; @@ -791,8 +787,8 @@ static int hidp_setup_hid(struct hidp_session *session, hid->country = req->country; strncpy(hid->name, req->name, 128); - strncpy(hid->phys, batostr(&src), 64); - strncpy(hid->uniq, batostr(&dst), 64); + strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64); + strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64); hid->dev.parent = hidp_get_device(session); hid->ll_driver = &hidp_hid_driver; diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 0b54b7dd84010a52147a54155c4f8db2b61752a7..daa7a988d9a6b4de7c7767748f1f18e1524cb78f 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1008,10 +1008,20 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) goto done; } - if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 && - !capable(CAP_NET_BIND_SERVICE)) { - err = -EACCES; - goto done; + if (la.l2_psm) { + __u16 psm = __le16_to_cpu(la.l2_psm); + + /* PSM must be odd and lsb of upper byte must be 0 */ + if ((psm & 0x0101) != 0x0001) { + err = -EINVAL; + goto done; + } + + /* Restrict usage of well-known PSMs */ + if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { + err = -EACCES; + goto done; + } } write_lock_bh(&l2cap_sk_list.lock); @@ -1190,6 +1200,13 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al goto done; } + /* PSM must be odd and lsb of upper byte must be 0 */ + if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && + sk->sk_type != SOCK_RAW) { + err = -EINVAL; + goto done; + } + /* Set destination address and psm */ bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); l2cap_pi(sk)->psm = la.l2_psm; @@ -1635,7 +1652,7 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in *frag = bt_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err); if (!*frag) - return -EFAULT; + return err; if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) return -EFAULT; @@ -1661,7 +1678,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr skb = bt_skb_send_alloc(sk, count + hlen, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) - return ERR_PTR(-ENOMEM); + return ERR_PTR(err); /* Create L2CAP header */ lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); @@ -1690,7 +1707,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *ms skb = bt_skb_send_alloc(sk, count + hlen, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) - return ERR_PTR(-ENOMEM); + return ERR_PTR(err); /* Create L2CAP header */ lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); @@ -1727,7 +1744,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *m skb = bt_skb_send_alloc(sk, count + hlen, msg->msg_flags & MSG_DONTWAIT, &err); if (!skb) - return ERR_PTR(-ENOMEM); + return ERR_PTR(err); /* Create L2CAP header */ lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); @@ -1934,6 +1951,9 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms release_sock(sk); + if (sock->type == SOCK_STREAM) + return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); + return bt_sock_recvmsg(iocb, sock, msg, len, flags); } @@ -2891,7 +2911,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd struct l2cap_chan_list *list = &conn->chan_list; struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; - struct sock *parent, *uninitialized_var(sk); + struct sock *parent, *sk = NULL; int result, status = L2CAP_CS_NO_INFO; u16 dcid = 0, scid = __le16_to_cpu(req->scid); @@ -3000,7 +3020,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd L2CAP_INFO_REQ, sizeof(info), &info); } - if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && + if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) && result == L2CAP_CR_SUCCESS) { u8 buf[128]; l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; @@ -3151,6 +3171,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) { u8 buf[64]; + l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, l2cap_build_conf_req(sk, buf), buf); l2cap_pi(sk)->num_conf_req++; @@ -4643,6 +4664,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl if (flags & ACL_START) { struct l2cap_hdr *hdr; + struct sock *sk; + u16 cid; int len; if (conn->rx_len) { @@ -4653,7 +4676,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl l2cap_conn_unreliable(conn, ECOMM); } - if (skb->len < 2) { + /* Start fragment always begin with Basic L2CAP header */ + if (skb->len < L2CAP_HDR_SIZE) { BT_ERR("Frame is too short (len %d)", skb->len); l2cap_conn_unreliable(conn, ECOMM); goto drop; @@ -4661,6 +4685,7 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl hdr = (struct l2cap_hdr *) skb->data; len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE; + cid = __le16_to_cpu(hdr->cid); if (len == skb->len) { /* Complete frame received */ @@ -4677,6 +4702,19 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl goto drop; } + sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); + + if (sk && l2cap_pi(sk)->imtu < len - L2CAP_HDR_SIZE) { + BT_ERR("Frame exceeding recv MTU (len %d, MTU %d)", + len, l2cap_pi(sk)->imtu); + bh_unlock_sock(sk); + l2cap_conn_unreliable(conn, ECOMM); + goto drop; + } + + if (sk) + bh_unlock_sock(sk); + /* Allocate skb for the complete frame (with header) */ conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); if (!conn->rx_skb) diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c index ad2af5814e40163e0e21e4c82a5a760e9e404894..b826d1bf10df5ce53f9674a061a65e940af73913 100644 --- a/net/bluetooth/lib.c +++ b/net/bluetooth/lib.c @@ -51,8 +51,8 @@ char *batostr(bdaddr_t *ba) i ^= 1; sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X", - ba->b[0], ba->b[1], ba->b[2], - ba->b[3], ba->b[4], ba->b[5]); + ba->b[5], ba->b[4], ba->b[3], + ba->b[2], ba->b[1], ba->b[0]); return str[i]; } diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 7dca91bb8c576397e571994655efbe9d1832d7b6..39a5d87e33b4221b7657933da0a1e2e1b5fe1784 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -113,11 +113,10 @@ static void rfcomm_session_del(struct rfcomm_session *s); #define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1) #define __get_rpn_parity(line) (((line) >> 3) & 0x7) -static inline void rfcomm_schedule(uint event) +static inline void rfcomm_schedule(void) { if (!rfcomm_thread) return; - //set_bit(event, &rfcomm_event); set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); wake_up_process(rfcomm_thread); } @@ -179,13 +178,13 @@ static unsigned char rfcomm_crc_table[256] = { /* FCS on 2 bytes */ static inline u8 __fcs(u8 *data) { - return (0xff - __crc(data)); + return 0xff - __crc(data); } /* FCS on 3 bytes */ static inline u8 __fcs2(u8 *data) { - return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]); + return 0xff - rfcomm_crc_table[__crc(data) ^ data[2]]; } /* Check FCS */ @@ -203,13 +202,13 @@ static inline int __check_fcs(u8 *data, int type, u8 fcs) static void rfcomm_l2state_change(struct sock *sk) { BT_DBG("%p state %d", sk, sk->sk_state); - rfcomm_schedule(RFCOMM_SCHED_STATE); + rfcomm_schedule(); } static void rfcomm_l2data_ready(struct sock *sk, int bytes) { BT_DBG("%p bytes %d", sk, bytes); - rfcomm_schedule(RFCOMM_SCHED_RX); + rfcomm_schedule(); } static int rfcomm_l2sock_create(struct socket **sock) @@ -255,7 +254,7 @@ static void rfcomm_session_timeout(unsigned long arg) BT_DBG("session %p state %ld", s, s->state); set_bit(RFCOMM_TIMED_OUT, &s->flags); - rfcomm_schedule(RFCOMM_SCHED_TIMEO); + rfcomm_schedule(); } static void rfcomm_session_set_timer(struct rfcomm_session *s, long timeout) @@ -283,7 +282,7 @@ static void rfcomm_dlc_timeout(unsigned long arg) set_bit(RFCOMM_TIMED_OUT, &d->flags); rfcomm_dlc_put(d); - rfcomm_schedule(RFCOMM_SCHED_TIMEO); + rfcomm_schedule(); } static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout) @@ -465,7 +464,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) case BT_CONFIG: if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { set_bit(RFCOMM_AUTH_REJECT, &d->flags); - rfcomm_schedule(RFCOMM_SCHED_AUTH); + rfcomm_schedule(); break; } /* Fall through */ @@ -485,7 +484,7 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) case BT_CONNECT2: if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { set_bit(RFCOMM_AUTH_REJECT, &d->flags); - rfcomm_schedule(RFCOMM_SCHED_AUTH); + rfcomm_schedule(); break; } /* Fall through */ @@ -533,7 +532,7 @@ int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb) skb_queue_tail(&d->tx_queue, skb); if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags)) - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); return len; } @@ -545,7 +544,7 @@ void __rfcomm_dlc_throttle(struct rfcomm_dlc *d) d->v24_sig |= RFCOMM_V24_FC; set_bit(RFCOMM_MSC_PENDING, &d->flags); } - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); } void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) @@ -556,7 +555,7 @@ void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d) d->v24_sig &= ~RFCOMM_V24_FC; set_bit(RFCOMM_MSC_PENDING, &d->flags); } - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); } /* @@ -577,7 +576,7 @@ int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig) d->v24_sig = v24_sig; if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags)) - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); return 0; } @@ -816,7 +815,7 @@ static int rfcomm_queue_disc(struct rfcomm_dlc *d) cmd->fcs = __fcs2((u8 *) cmd); skb_queue_tail(&d->tx_queue, skb); - rfcomm_schedule(RFCOMM_SCHED_TX); + rfcomm_schedule(); return 0; } @@ -1415,8 +1414,8 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_ return 0; if (len == 1) { - /* This is a request, return default settings */ - bit_rate = RFCOMM_RPN_BR_115200; + /* This is a request, return default (according to ETSI TS 07.10) settings */ + bit_rate = RFCOMM_RPN_BR_9600; data_bits = RFCOMM_RPN_DATA_8; stop_bits = RFCOMM_RPN_STOP_1; parity = RFCOMM_RPN_PARITY_NONE; @@ -1431,9 +1430,9 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_ if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_BITRATE)) { bit_rate = rpn->bit_rate; - if (bit_rate != RFCOMM_RPN_BR_115200) { + if (bit_rate > RFCOMM_RPN_BR_230400) { BT_DBG("RPN bit rate mismatch 0x%x", bit_rate); - bit_rate = RFCOMM_RPN_BR_115200; + bit_rate = RFCOMM_RPN_BR_9600; rpn_mask ^= RFCOMM_RPN_PM_BITRATE; } } @@ -1698,7 +1697,7 @@ static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb) break; default: - BT_ERR("Unknown packet type 0x%02x\n", type); + BT_ERR("Unknown packet type 0x%02x", type); break; } kfree_skb(skb); @@ -1884,7 +1883,7 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s) * L2CAP MTU minus UIH header and FCS. */ s->mtu = min(l2cap_pi(nsock->sk)->omtu, l2cap_pi(nsock->sk)->imtu) - 5; - rfcomm_schedule(RFCOMM_SCHED_RX); + rfcomm_schedule(); } else sock_release(nsock); } @@ -2093,7 +2092,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) rfcomm_session_put(s); - rfcomm_schedule(RFCOMM_SCHED_AUTH); + rfcomm_schedule(); } static struct hci_cb rfcomm_cb = { diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 194b3a04cfd38a3b4a13817d5aecace4f355ea49..aec505f934dff30d8f711a13e3d2ef95ae5f8016 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -621,121 +621,29 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, return sent; } -static long rfcomm_sock_data_wait(struct sock *sk, long timeo) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(sk_sleep(sk), &wait); - for (;;) { - set_current_state(TASK_INTERRUPTIBLE); - - if (!skb_queue_empty(&sk->sk_receive_queue) || - sk->sk_err || - (sk->sk_shutdown & RCV_SHUTDOWN) || - signal_pending(current) || - !timeo) - break; - - set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - release_sock(sk); - timeo = schedule_timeout(timeo); - lock_sock(sk); - clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - } - - __set_current_state(TASK_RUNNING); - remove_wait_queue(sk_sleep(sk), &wait); - return timeo; -} - static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t size, int flags) { struct sock *sk = sock->sk; struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; - int err = 0; - size_t target, copied = 0; - long timeo; + int len; if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { rfcomm_dlc_accept(d); return 0; } - if (flags & MSG_OOB) - return -EOPNOTSUPP; - - msg->msg_namelen = 0; - - BT_DBG("sk %p size %zu", sk, size); + len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags); lock_sock(sk); + if (!(flags & MSG_PEEK) && len > 0) + atomic_sub(len, &sk->sk_rmem_alloc); - target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); - timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); - - do { - struct sk_buff *skb; - int chunk; - - skb = skb_dequeue(&sk->sk_receive_queue); - if (!skb) { - if (copied >= target) - break; - - if ((err = sock_error(sk)) != 0) - break; - if (sk->sk_shutdown & RCV_SHUTDOWN) - break; - - err = -EAGAIN; - if (!timeo) - break; - - timeo = rfcomm_sock_data_wait(sk, timeo); - - if (signal_pending(current)) { - err = sock_intr_errno(timeo); - goto out; - } - continue; - } - - chunk = min_t(unsigned int, skb->len, size); - if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) { - skb_queue_head(&sk->sk_receive_queue, skb); - if (!copied) - copied = -EFAULT; - break; - } - copied += chunk; - size -= chunk; - - sock_recv_ts_and_drops(msg, sk, skb); - - if (!(flags & MSG_PEEK)) { - atomic_sub(chunk, &sk->sk_rmem_alloc); - - skb_pull(skb, chunk); - if (skb->len) { - skb_queue_head(&sk->sk_receive_queue, skb); - break; - } - kfree_skb(skb); - - } else { - /* put message back and return */ - skb_queue_head(&sk->sk_receive_queue, skb); - break; - } - } while (size); - -out: if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2)) rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc); - release_sock(sk); - return copied ? : err; + + return len; } static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 84c2a4d013c669b570b354a400089be785018470..a9b81f5dacd14c942d46e46c4bdcacc9f2070ac8 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -183,9 +183,7 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev) static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf) { struct rfcomm_dev *dev = dev_get_drvdata(tty_dev); - bdaddr_t bdaddr; - baswap(&bdaddr, &dev->dst); - return sprintf(buf, "%s\n", batostr(&bdaddr)); + return sprintf(buf, "%s\n", batostr(&dev->dst)); } static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf) diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index cf09fe591fc20cc73a2fdd20d13860f88c33134d..17cb0b633576eb96582b2b0ff22030bef02c3830 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -212,6 +212,11 @@ static int br_set_tx_csum(struct net_device *dev, u32 data) return 0; } +static int br_set_flags(struct net_device *netdev, u32 data) +{ + return ethtool_op_set_flags(netdev, data, ETH_FLAG_TXVLAN); +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void br_poll_controller(struct net_device *br_dev) { @@ -304,6 +309,7 @@ static const struct ethtool_ops br_ethtool_ops = { .get_ufo = ethtool_op_get_ufo, .set_ufo = ethtool_op_set_ufo, .get_flags = ethtool_op_get_flags, + .set_flags = br_set_flags, }; static const struct net_device_ops br_netdev_ops = { @@ -343,5 +349,5 @@ void br_dev_setup(struct net_device *dev) dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | - NETIF_F_NETNS_LOCAL | NETIF_F_GSO; + NETIF_F_NETNS_LOCAL | NETIF_F_GSO | NETIF_F_HW_VLAN_TX; } diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index c03d2c3ff03ed6cb99dc05d7a4cde5033d951190..89ad25a76202924eadf9bce8aadf761dcea3e8d5 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -61,30 +61,27 @@ static int port_cost(struct net_device *dev) } -/* - * Check for port carrier transistions. - * Called from work queue to allow for calling functions that - * might sleep (such as speed check), and to debounce. - */ +/* Check for port carrier transistions. */ void br_port_carrier_check(struct net_bridge_port *p) { struct net_device *dev = p->dev; struct net_bridge *br = p->br; - if (netif_carrier_ok(dev)) + if (netif_running(dev) && netif_carrier_ok(dev)) p->path_cost = port_cost(dev); - if (netif_running(br->dev)) { - spin_lock_bh(&br->lock); - if (netif_carrier_ok(dev)) { - if (p->state == BR_STATE_DISABLED) - br_stp_enable_port(p); - } else { - if (p->state != BR_STATE_DISABLED) - br_stp_disable_port(p); - } - spin_unlock_bh(&br->lock); + if (!netif_running(br->dev)) + return; + + spin_lock_bh(&br->lock); + if (netif_running(dev) && netif_carrier_ok(dev)) { + if (p->state == BR_STATE_DISABLED) + br_stp_enable_port(p); + } else { + if (p->state != BR_STATE_DISABLED) + br_stp_disable_port(p); } + spin_unlock_bh(&br->lock); } static void release_nbp(struct kobject *kobj) diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 826cd5221536cadd3b0d13dfec2e9d3639b92a93..25207a1f182be33d9b588a3d5fdbc1273c269409 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -141,7 +141,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) const unsigned char *dest = eth_hdr(skb)->h_dest; int (*rhook)(struct sk_buff *skb); - if (skb->pkt_type == PACKET_LOOPBACK) + if (unlikely(skb->pkt_type == PACKET_LOOPBACK)) return skb; if (!is_valid_ether_addr(eth_hdr(skb)->h_source)) @@ -159,7 +159,7 @@ struct sk_buff *br_handle_frame(struct sk_buff *skb) goto drop; /* If STP is turned off, then forward */ - if (p->br->stp_enabled == BR_NO_STP && dest[5] == 0) + if (p->br->stp_enabled == BR_NO_STP) goto forward; if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 137f23259a93947ce581a9d14c8f6048f3ca2c19..865fd7634b673d4233c8a6758e2426db55696514 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -64,22 +64,24 @@ static int brnf_filter_pppoe_tagged __read_mostly = 0; static inline __be16 vlan_proto(const struct sk_buff *skb) { - return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + if (vlan_tx_tag_present(skb)) + return skb->protocol; + else if (skb->protocol == htons(ETH_P_8021Q)) + return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + else + return 0; } #define IS_VLAN_IP(skb) \ - (skb->protocol == htons(ETH_P_8021Q) && \ - vlan_proto(skb) == htons(ETH_P_IP) && \ + (vlan_proto(skb) == htons(ETH_P_IP) && \ brnf_filter_vlan_tagged) #define IS_VLAN_IPV6(skb) \ - (skb->protocol == htons(ETH_P_8021Q) && \ - vlan_proto(skb) == htons(ETH_P_IPV6) &&\ + (vlan_proto(skb) == htons(ETH_P_IPV6) && \ brnf_filter_vlan_tagged) #define IS_VLAN_ARP(skb) \ - (skb->protocol == htons(ETH_P_8021Q) && \ - vlan_proto(skb) == htons(ETH_P_ARP) && \ + (vlan_proto(skb) == htons(ETH_P_ARP) && \ brnf_filter_vlan_tagged) static inline __be16 pppoe_proto(const struct sk_buff *skb) @@ -106,7 +108,6 @@ static struct dst_ops fake_dst_ops = { .family = AF_INET, .protocol = cpu_to_be16(ETH_P_IP), .update_pmtu = fake_update_pmtu, - .entries = ATOMIC_INIT(0), }; /* @@ -209,6 +210,72 @@ static inline void nf_bridge_update_protocol(struct sk_buff *skb) skb->protocol = htons(ETH_P_PPP_SES); } +/* When handing a packet over to the IP layer + * check whether we have a skb that is in the + * expected format + */ + +static int br_parse_ip_options(struct sk_buff *skb) +{ + struct ip_options *opt; + struct iphdr *iph; + struct net_device *dev = skb->dev; + u32 len; + + iph = ip_hdr(skb); + opt = &(IPCB(skb)->opt); + + /* Basic sanity checks */ + if (iph->ihl < 5 || iph->version != 4) + goto inhdr_error; + + if (!pskb_may_pull(skb, iph->ihl*4)) + goto inhdr_error; + + iph = ip_hdr(skb); + if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) + goto inhdr_error; + + len = ntohs(iph->tot_len); + if (skb->len < len) { + IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INTRUNCATEDPKTS); + goto drop; + } else if (len < (iph->ihl*4)) + goto inhdr_error; + + if (pskb_trim_rcsum(skb, len)) { + IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS); + goto drop; + } + + /* Zero out the CB buffer if no options present */ + if (iph->ihl == 5) { + memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); + return 0; + } + + opt->optlen = iph->ihl*4 - sizeof(struct iphdr); + if (ip_options_compile(dev_net(dev), opt, skb)) + goto inhdr_error; + + /* Check correct handling of SRR option */ + if (unlikely(opt->srr)) { + struct in_device *in_dev = __in_dev_get_rcu(dev); + if (in_dev && !IN_DEV_SOURCE_ROUTE(in_dev)) + goto drop; + + if (ip_options_rcv_srr(skb)) + goto drop; + } + + return 0; + +inhdr_error: + IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INHDRERRORS); +drop: + return -1; +} + /* Fill in the header for fragmented IP packets handled by * the IPv4 connection tracking code. */ @@ -549,7 +616,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, { struct net_bridge_port *p; struct net_bridge *br; - struct iphdr *iph; __u32 len = nf_bridge_encap_header_len(skb); if (unlikely(!pskb_may_pull(skb, len))) @@ -578,28 +644,9 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, nf_bridge_pull_encap_header_rcsum(skb); - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - goto inhdr_error; - - iph = ip_hdr(skb); - if (iph->ihl < 5 || iph->version != 4) - goto inhdr_error; - - if (!pskb_may_pull(skb, 4 * iph->ihl)) - goto inhdr_error; - - iph = ip_hdr(skb); - if (ip_fast_csum((__u8 *) iph, iph->ihl) != 0) - goto inhdr_error; - - len = ntohs(iph->tot_len); - if (skb->len < len || len < 4 * iph->ihl) - goto inhdr_error; - - pskb_trim_rcsum(skb, len); - - /* BUG: Should really parse the IP options here. */ - memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); + if (br_parse_ip_options(skb)) + /* Drop invalid packet */ + goto out; nf_bridge_put(skb->nf_bridge); if (!nf_bridge_alloc(skb)) @@ -614,8 +661,6 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff *skb, return NF_STOLEN; -inhdr_error: -// IP_INC_STATS_BH(IpInHdrErrors); out: return NF_DROP; } @@ -759,14 +804,19 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff *skb, #if defined(CONFIG_NF_CONNTRACK_IPV4) || defined(CONFIG_NF_CONNTRACK_IPV4_MODULE) static int br_nf_dev_queue_xmit(struct sk_buff *skb) { + int ret; + if (skb->nfct != NULL && skb->protocol == htons(ETH_P_IP) && skb->len + nf_bridge_mtu_reduction(skb) > skb->dev->mtu && !skb_is_gso(skb)) { - /* BUG: Should really parse the IP options here. */ - memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); - return ip_fragment(skb, br_dev_queue_push_xmit); + if (br_parse_ip_options(skb)) + /* Drop invalid packet */ + return NF_DROP; + ret = ip_fragment(skb, br_dev_queue_push_xmit); } else - return br_dev_queue_push_xmit(skb); + ret = br_dev_queue_push_xmit(skb); + + return ret; } #else static int br_nf_dev_queue_xmit(struct sk_buff *skb) @@ -954,15 +1004,22 @@ int __init br_netfilter_init(void) { int ret; - ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); + ret = dst_entries_init(&fake_dst_ops); if (ret < 0) return ret; + + ret = nf_register_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); + if (ret < 0) { + dst_entries_destroy(&fake_dst_ops); + return ret; + } #ifdef CONFIG_SYSCTL brnf_sysctl_header = register_sysctl_paths(brnf_path, brnf_table); if (brnf_sysctl_header == NULL) { printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); nf_unregister_hooks(br_nf_ops, ARRAY_SIZE(br_nf_ops)); + dst_entries_destroy(&fake_dst_ops); return -ENOMEM; } #endif @@ -976,4 +1033,5 @@ void br_netfilter_fini(void) #ifdef CONFIG_SYSCTL unregister_sysctl_table(brnf_sysctl_header); #endif + dst_entries_destroy(&fake_dst_ops); } diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c index 87b53b3a921daefd40c0fd85ade33d5240f4262a..eae67bf0446c8023b6e3895562e48912b6c29330 100644 --- a/net/bridge/netfilter/ebt_vlan.c +++ b/net/bridge/netfilter/ebt_vlan.c @@ -39,8 +39,6 @@ static bool ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par) { const struct ebt_vlan_info *info = par->matchinfo; - const struct vlan_hdr *fp; - struct vlan_hdr _frame; unsigned short TCI; /* Whole TCI, given from parsed frame */ unsigned short id; /* VLAN ID, given from frame TCI */ @@ -48,9 +46,20 @@ ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par) /* VLAN encapsulated Type/Length field, given from orig frame */ __be16 encap; - fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); - if (fp == NULL) - return false; + if (vlan_tx_tag_present(skb)) { + TCI = vlan_tx_tag_get(skb); + encap = skb->protocol; + } else { + const struct vlan_hdr *fp; + struct vlan_hdr _frame; + + fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); + if (fp == NULL) + return false; + + TCI = ntohs(fp->h_vlan_TCI); + encap = fp->h_vlan_encapsulated_proto; + } /* Tag Control Information (TCI) consists of the following elements: * - User_priority. The user_priority field is three bits in length, @@ -59,10 +68,8 @@ ebt_vlan_mt(const struct sk_buff *skb, struct xt_action_param *par) * (CFI) is a single bit flag value. Currently ignored. * - VLAN Identifier (VID). The VID is encoded as * an unsigned binary number. */ - TCI = ntohs(fp->h_vlan_TCI); id = TCI & VLAN_VID_MASK; prio = (TCI >> 13) & 0x7; - encap = fp->h_vlan_encapsulated_proto; /* Checking VLAN Identifier (VID) */ if (GET_BITMASK(EBT_VLAN_ID)) @@ -111,10 +118,10 @@ static int ebt_vlan_mt_check(const struct xt_mtchk_param *par) * 0 - The null VLAN ID. * 1 - The default Port VID (PVID) * 0x0FFF - Reserved for implementation use. - * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096. */ + * if_vlan.h: VLAN_N_VID 4096. */ if (GET_BITMASK(EBT_VLAN_ID)) { if (!!info->id) { /* if id!=0 => check vid range */ - if (info->id > VLAN_GROUP_ARRAY_LEN) { + if (info->id > VLAN_N_VID) { pr_debug("id %d is out of range (1-4096)\n", info->id); return -EINVAL; diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index bcc102e3be4daa2c5f09ee27710cc5ed03b096fa..a1dcf83f0d5860743906f75bcae5a23477c9b098 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -124,16 +124,23 @@ ebt_dev_check(const char *entry, const struct net_device *device) #define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg)) /* process standard matches */ static inline int -ebt_basic_match(const struct ebt_entry *e, const struct ethhdr *h, +ebt_basic_match(const struct ebt_entry *e, const struct sk_buff *skb, const struct net_device *in, const struct net_device *out) { + const struct ethhdr *h = eth_hdr(skb); + __be16 ethproto; int verdict, i; + if (vlan_tx_tag_present(skb)) + ethproto = htons(ETH_P_8021Q); + else + ethproto = h->h_proto; + if (e->bitmask & EBT_802_3) { - if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO)) + if (FWINV2(ntohs(ethproto) >= 1536, EBT_IPROTO)) return 1; } else if (!(e->bitmask & EBT_NOPROTO) && - FWINV2(e->ethproto != h->h_proto, EBT_IPROTO)) + FWINV2(e->ethproto != ethproto, EBT_IPROTO)) return 1; if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN)) @@ -213,7 +220,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb, base = private->entries; i = 0; while (i < nentries) { - if (ebt_basic_match(point, eth_hdr(skb), in, out)) + if (ebt_basic_match(point, skb, in, out)) goto letscontinue; if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &acpar) != 0) diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 0b586e9d1378fb209e2f377354938788abfd1ad8..b99369a055d13df6414421a28cfaee5d000c6c72 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -9,6 +9,8 @@ * and Sakari Ailus */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -171,7 +173,7 @@ static int receive(struct sk_buff *skb, struct net_device *dev, net = dev_net(dev); pkt = cfpkt_fromnative(CAIF_DIR_IN, skb); caifd = caif_get(dev); - if (!caifd || !caifd->layer.up || !caifd->layer.up->ctrlcmd) + if (!caifd || !caifd->layer.up || !caifd->layer.up->receive) return NET_RX_DROP; if (caifd->layer.up->receive(caifd->layer.up, pkt)) @@ -214,7 +216,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, switch (what) { case NETDEV_REGISTER: - pr_info("CAIF: %s():register %s\n", __func__, dev->name); + netdev_info(dev, "register\n"); caifd = caif_device_alloc(dev); if (caifd == NULL) break; @@ -225,14 +227,13 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, break; case NETDEV_UP: - pr_info("CAIF: %s(): up %s\n", __func__, dev->name); + netdev_info(dev, "up\n"); caifd = caif_get(dev); if (caifd == NULL) break; caifdev = netdev_priv(dev); if (atomic_read(&caifd->state) == NETDEV_UP) { - pr_info("CAIF: %s():%s already up\n", - __func__, dev->name); + netdev_info(dev, "already up\n"); break; } atomic_set(&caifd->state, what); @@ -273,7 +274,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, caifd = caif_get(dev); if (caifd == NULL) break; - pr_info("CAIF: %s():going down %s\n", __func__, dev->name); + netdev_info(dev, "going down\n"); if (atomic_read(&caifd->state) == NETDEV_GOING_DOWN || atomic_read(&caifd->state) == NETDEV_DOWN) @@ -295,11 +296,10 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, caifd = caif_get(dev); if (caifd == NULL) break; - pr_info("CAIF: %s(): down %s\n", __func__, dev->name); + netdev_info(dev, "down\n"); if (atomic_read(&caifd->in_use)) - pr_warning("CAIF: %s(): " - "Unregistering an active CAIF device: %s\n", - __func__, dev->name); + netdev_warn(dev, + "Unregistering an active CAIF device\n"); cfcnfg_del_phy_layer(get_caif_conf(), &caifd->layer); dev_put(dev); atomic_set(&caifd->state, what); @@ -307,7 +307,7 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, case NETDEV_UNREGISTER: caifd = caif_get(dev); - pr_info("CAIF: %s(): unregister %s\n", __func__, dev->name); + netdev_info(dev, "unregister\n"); atomic_set(&caifd->state, what); caif_device_destroy(dev); break; @@ -391,7 +391,7 @@ static int __init caif_device_init(void) int result; cfg = cfcnfg_create(); if (!cfg) { - pr_warning("CAIF: %s(): can't create cfcnfg.\n", __func__); + pr_warn("can't create cfcnfg\n"); goto err_cfcnfg_create_failed; } result = register_pernet_device(&caif_net_ops); diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 4bf28f25f368b399a6ef220e06c08c0f5d2621f5..2eca2dd0000fd7dce7fc614ed5e476f0ca886874 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -15,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -28,9 +29,6 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS_NETPROTO(AF_CAIF); -#define CAIF_DEF_SNDBUF (4096*10) -#define CAIF_DEF_RCVBUF (4096*100) - /* * CAIF state is re-using the TCP socket states. * caif_states stored in sk_state reflect the state as reported by @@ -157,9 +155,7 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= (unsigned)sk->sk_rcvbuf && rx_flow_is_on(cf_sk)) { - trace_printk("CAIF: %s():" - " sending flow OFF (queue len = %d %d)\n", - __func__, + pr_debug("sending flow OFF (queue len = %d %d)\n", atomic_read(&cf_sk->sk.sk_rmem_alloc), sk_rcvbuf_lowwater(cf_sk)); set_rx_flow_off(cf_sk); @@ -172,9 +168,7 @@ static int caif_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) return err; if (!sk_rmem_schedule(sk, skb->truesize) && rx_flow_is_on(cf_sk)) { set_rx_flow_off(cf_sk); - trace_printk("CAIF: %s():" - " sending flow OFF due to rmem_schedule\n", - __func__); + pr_debug("sending flow OFF due to rmem_schedule\n"); dbfs_atomic_inc(&cnt.num_rx_flow_off); caif_flow_ctrl(sk, CAIF_MODEMCMD_FLOW_OFF_REQ); } @@ -275,8 +269,7 @@ static void caif_ctrl_cb(struct cflayer *layr, break; default: - pr_debug("CAIF: %s(): Unexpected flow command %d\n", - __func__, flow); + pr_debug("Unexpected flow command %d\n", flow); } } @@ -536,8 +529,7 @@ static int transmit_skb(struct sk_buff *skb, struct caifsock *cf_sk, /* Slight paranoia, probably not needed. */ if (unlikely(loopcnt++ > 1000)) { - pr_warning("CAIF: %s(): transmit retries failed," - " error = %d\n", __func__, ret); + pr_warn("transmit retries failed, error = %d\n", ret); break; } @@ -912,8 +904,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, cf_sk->tailroom = tailroom; cf_sk->maxframe = mtu - (headroom + tailroom); if (cf_sk->maxframe < 1) { - pr_warning("CAIF: %s(): CAIF Interface MTU too small (%u)\n", - __func__, mtu); + pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); goto out; } @@ -1132,10 +1123,6 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, /* Store the protocol */ sk->sk_protocol = (unsigned char) protocol; - /* Sendbuf dictates the amount of outbound packets not yet sent */ - sk->sk_sndbuf = CAIF_DEF_SNDBUF; - sk->sk_rcvbuf = CAIF_DEF_RCVBUF; - /* * Lock in order to try to stop someone from opening the socket * too early. diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 1c29189b344daa1d885b56f09a9d72871129b7ab..41adafd1891422ab1aa32a95a46aee7d9ae77b82 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -3,6 +3,9 @@ * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ + +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -78,7 +81,7 @@ struct cfcnfg *cfcnfg_create(void) /* Initiate this layer */ this = kzalloc(sizeof(struct cfcnfg), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } this->mux = cfmuxl_create(); @@ -106,7 +109,7 @@ struct cfcnfg *cfcnfg_create(void) layer_set_up(this->ctrl, this); return this; out_of_mem: - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); kfree(this->mux); kfree(this->ctrl); kfree(this); @@ -194,7 +197,7 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) caif_assert(adap_layer != NULL); channel_id = adap_layer->id; if (adap_layer->dn == NULL || channel_id == 0) { - pr_err("CAIF: %s():adap_layer->id is 0\n", __func__); + pr_err("adap_layer->dn == NULL or adap_layer->id is 0\n"); ret = -ENOTCONN; goto end; } @@ -204,9 +207,8 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) layer_set_up(servl, NULL); ret = cfctrl_linkdown_req(cnfg->ctrl, channel_id, adap_layer); if (servl == NULL) { - pr_err("CAIF: %s(): PROTOCOL ERROR " - "- Error removing service_layer Channel_Id(%d)", - __func__, channel_id); + pr_err("PROTOCOL ERROR - Error removing service_layer Channel_Id(%d)", + channel_id); ret = -EINVAL; goto end; } @@ -216,18 +218,14 @@ int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) phyinfo = cfcnfg_get_phyinfo(cnfg, phyid); if (phyinfo == NULL) { - pr_warning("CAIF: %s(): " - "No interface to send disconnect to\n", - __func__); + pr_warn("No interface to send disconnect to\n"); ret = -ENODEV; goto end; } if (phyinfo->id != phyid || phyinfo->phy_layer->id != phyid || phyinfo->frm_layer->id != phyid) { - pr_err("CAIF: %s(): " - "Inconsistency in phy registration\n", - __func__); + pr_err("Inconsistency in phy registration\n"); ret = -EINVAL; goto end; } @@ -276,21 +274,20 @@ int cfcnfg_add_adaptation_layer(struct cfcnfg *cnfg, { struct cflayer *frml; if (adap_layer == NULL) { - pr_err("CAIF: %s(): adap_layer is zero", __func__); + pr_err("adap_layer is zero\n"); return -EINVAL; } if (adap_layer->receive == NULL) { - pr_err("CAIF: %s(): adap_layer->receive is NULL", __func__); + pr_err("adap_layer->receive is NULL\n"); return -EINVAL; } if (adap_layer->ctrlcmd == NULL) { - pr_err("CAIF: %s(): adap_layer->ctrlcmd == NULL", __func__); + pr_err("adap_layer->ctrlcmd == NULL\n"); return -EINVAL; } frml = cnfg->phy_layers[param->phyid].frm_layer; if (frml == NULL) { - pr_err("CAIF: %s(): Specified PHY type does not exist!", - __func__); + pr_err("Specified PHY type does not exist!\n"); return -ENODEV; } caif_assert(param->phyid == cnfg->phy_layers[param->phyid].id); @@ -330,9 +327,7 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, struct net_device *netdev; if (adapt_layer == NULL) { - pr_debug("CAIF: %s(): link setup response " - "but no client exist, send linkdown back\n", - __func__); + pr_debug("link setup response but no client exist, send linkdown back\n"); cfctrl_linkdown_req(cnfg->ctrl, channel_id, NULL); return; } @@ -374,13 +369,11 @@ cfcnfg_linkup_rsp(struct cflayer *layer, u8 channel_id, enum cfctrl_srv serv, servicel = cfdbgl_create(channel_id, &phyinfo->dev_info); break; default: - pr_err("CAIF: %s(): Protocol error. " - "Link setup response - unknown channel type\n", - __func__); + pr_err("Protocol error. Link setup response - unknown channel type\n"); return; } if (!servicel) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } layer_set_dn(servicel, cnfg->mux); @@ -418,7 +411,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, } } if (*phyid == 0) { - pr_err("CAIF: %s(): No Available PHY ID\n", __func__); + pr_err("No Available PHY ID\n"); return; } @@ -427,7 +420,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, phy_driver = cfserl_create(CFPHYTYPE_FRAG, *phyid, stx); if (!phy_driver) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } @@ -436,7 +429,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, phy_driver = NULL; break; default: - pr_err("CAIF: %s(): %d", __func__, phy_type); + pr_err("%d\n", phy_type); return; break; } @@ -455,7 +448,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, enum cfcnfg_phy_type phy_type, phy_layer->type = phy_type; frml = cffrml_create(*phyid, fcs); if (!frml) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } cnfg->phy_layers[*phyid].frm_layer = frml; diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 563145fdc4c368de2c50c8d9d3510742a7d2e658..08f267a109aa3c677efc4a6795ccfea31fc8d581 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -36,7 +38,7 @@ struct cflayer *cfctrl_create(void) struct cfctrl *this = kmalloc(sizeof(struct cfctrl), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfctrl, serv.layer) == 0); @@ -132,9 +134,7 @@ struct cfctrl_request_info *cfctrl_remove_req(struct cfctrl *ctrl, list_for_each_entry_safe(p, tmp, &ctrl->list, list) { if (cfctrl_req_eq(req, p)) { if (p != first) - pr_warning("CAIF: %s(): Requests are not " - "received in order\n", - __func__); + pr_warn("Requests are not received in order\n"); atomic_set(&ctrl->rsp_seq_no, p->sequence_no); @@ -177,7 +177,7 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) int ret; struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } caif_assert(offsetof(struct cfctrl, serv.layer) == 0); @@ -189,8 +189,7 @@ void cfctrl_enum_req(struct cflayer *layer, u8 physlinkid) ret = cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); if (ret < 0) { - pr_err("CAIF: %s(): Could not transmit enum message\n", - __func__); + pr_err("Could not transmit enum message\n"); cfpkt_destroy(pkt); } } @@ -208,7 +207,7 @@ int cfctrl_linkup_request(struct cflayer *layer, char utility_name[16]; struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_SETUP); @@ -253,13 +252,13 @@ int cfctrl_linkup_request(struct cflayer *layer, param->u.utility.paramlen); break; default: - pr_warning("CAIF: %s():Request setup of bad link type = %d\n", - __func__, param->linktype); + pr_warn("Request setup of bad link type = %d\n", + param->linktype); return -EINVAL; } req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } req->client_layer = user_layer; @@ -276,8 +275,7 @@ int cfctrl_linkup_request(struct cflayer *layer, ret = cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); if (ret < 0) { - pr_err("CAIF: %s(): Could not transmit linksetup request\n", - __func__); + pr_err("Could not transmit linksetup request\n"); cfpkt_destroy(pkt); return -ENODEV; } @@ -291,7 +289,7 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } cfpkt_addbdy(pkt, CFCTRL_CMD_LINK_DESTROY); @@ -300,8 +298,7 @@ int cfctrl_linkdown_req(struct cflayer *layer, u8 channelid, ret = cfctrl->serv.layer.dn->transmit(cfctrl->serv.layer.dn, pkt); if (ret < 0) { - pr_err("CAIF: %s(): Could not transmit link-down request\n", - __func__); + pr_err("Could not transmit link-down request\n"); cfpkt_destroy(pkt); } return ret; @@ -313,7 +310,7 @@ void cfctrl_sleep_req(struct cflayer *layer) struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } cfpkt_addbdy(pkt, CFCTRL_CMD_SLEEP); @@ -330,7 +327,7 @@ void cfctrl_wake_req(struct cflayer *layer) struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } cfpkt_addbdy(pkt, CFCTRL_CMD_WAKE); @@ -347,7 +344,7 @@ void cfctrl_getstartreason_req(struct cflayer *layer) struct cfctrl *cfctrl = container_obj(layer); struct cfpkt *pkt = cfpkt_create(CFPKT_CTRL_PKT_LEN); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return; } cfpkt_addbdy(pkt, CFCTRL_CMD_START_REASON); @@ -364,12 +361,11 @@ void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) struct cfctrl_request_info *p, *tmp; struct cfctrl *ctrl = container_obj(layr); spin_lock(&ctrl->info_list_lock); - pr_warning("CAIF: %s(): enter\n", __func__); + pr_warn("enter\n"); list_for_each_entry_safe(p, tmp, &ctrl->list, list) { if (p->client_layer == adap_layer) { - pr_warning("CAIF: %s(): cancel req :%d\n", __func__, - p->sequence_no); + pr_warn("cancel req :%d\n", p->sequence_no); list_del(&p->list); kfree(p); } @@ -520,9 +516,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) cfpkt_extr_head(pkt, ¶m, len); break; default: - pr_warning("CAIF: %s(): Request setup " - "- invalid link type (%d)", - __func__, serv); + pr_warn("Request setup - invalid link type (%d)\n", + serv); goto error; } @@ -532,9 +527,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || cfpkt_erroneous(pkt)) { - pr_err("CAIF: %s(): Invalid O/E bit or parse " - "error on CAIF control channel", - __func__); + pr_err("Invalid O/E bit or parse error on CAIF control channel\n"); cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0, req ? req->client_layer @@ -556,8 +549,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) cfctrl->res.linkdestroy_rsp(cfctrl->serv.layer.up, linkid); break; case CFCTRL_CMD_LINK_ERR: - pr_err("CAIF: %s(): Frame Error Indication received\n", - __func__); + pr_err("Frame Error Indication received\n"); cfctrl->res.linkerror_ind(); break; case CFCTRL_CMD_ENUM: @@ -576,7 +568,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) cfctrl->res.radioset_rsp(); break; default: - pr_err("CAIF: %s(): Unrecognized Control Frame\n", __func__); + pr_err("Unrecognized Control Frame\n"); goto error; break; } @@ -595,8 +587,7 @@ static void cfctrl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, case CAIF_CTRLCMD_FLOW_OFF_IND: spin_lock(&this->info_list_lock); if (!list_empty(&this->list)) { - pr_debug("CAIF: %s(): Received flow off in " - "control layer", __func__); + pr_debug("Received flow off in control layer\n"); } spin_unlock(&this->info_list_lock); break; @@ -620,7 +611,7 @@ static int handle_loop(struct cfctrl *ctrl, int cmd, struct cfpkt *pkt) if (!ctrl->loop_linkused[linkid]) goto found; spin_unlock(&ctrl->loop_linkid_lock); - pr_err("CAIF: %s(): Out of link-ids\n", __func__); + pr_err("Out of link-ids\n"); return -EINVAL; found: if (!ctrl->loop_linkused[linkid]) diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c index 676648cac8ddf3aa77f8659187b6aab8738388a0..496fda9ac66f56bee42568e8c0386566c3208be4 100644 --- a/net/caif/cfdbgl.c +++ b/net/caif/cfdbgl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -17,7 +19,7 @@ struct cflayer *cfdbgl_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *dbg = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!dbg) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c index ed9d53aff28053e5dd98bbaf9eb1ad8d3bb6b591..d3ed264ad6c42b932d84a721b270f88d0d6b574b 100644 --- a/net/caif/cfdgml.c +++ b/net/caif/cfdgml.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -26,7 +28,7 @@ struct cflayer *cfdgml_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *dgm = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!dgm) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -49,14 +51,14 @@ static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt) caif_assert(layr->ctrlcmd != NULL); if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } if ((cmd & DGM_CMD_BIT) == 0) { if (cfpkt_extr_head(pkt, &dgmhdr, 3) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -75,8 +77,7 @@ static int cfdgml_receive(struct cflayer *layr, struct cfpkt *pkt) return 0; default: cfpkt_destroy(pkt); - pr_info("CAIF: %s(): Unknown datagram control %d (0x%x)\n", - __func__, cmd, cmd); + pr_info("Unknown datagram control %d (0x%x)\n", cmd, cmd); return -EPROTO; } } diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c index e86a4ca3b2179e6ae26d0136c5df773e4efa64ac..a445043931ae3f97af3df8a8c2b470ef7cea1321 100644 --- a/net/caif/cffrml.c +++ b/net/caif/cffrml.c @@ -6,6 +6,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -32,7 +34,7 @@ struct cflayer *cffrml_create(u16 phyid, bool use_fcs) { struct cffrml *this = kmalloc(sizeof(struct cffrml), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cffrml, layer) == 0); @@ -83,7 +85,7 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) if (cfpkt_setlen(pkt, len) < 0) { ++cffrml_rcv_error; - pr_err("CAIF: %s():Framing length error (%d)\n", __func__, len); + pr_err("Framing length error (%d)\n", len); cfpkt_destroy(pkt); return -EPROTO; } @@ -99,14 +101,14 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) cfpkt_add_trail(pkt, &tmp, 2); ++cffrml_rcv_error; ++cffrml_rcv_checsum_error; - pr_info("CAIF: %s(): Frame checksum error " - "(0x%x != 0x%x)\n", __func__, hdrchks, pktchks); + pr_info("Frame checksum error (0x%x != 0x%x)\n", + hdrchks, pktchks); return -EILSEQ; } } if (cfpkt_erroneous(pkt)) { ++cffrml_rcv_error; - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -132,7 +134,7 @@ static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt) cfpkt_add_head(pkt, &tmp, 2); cfpkt_info(pkt)->hdr_len += 2; if (cfpkt_erroneous(pkt)) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); return -EPROTO; } ret = layr->dn->transmit(layr->dn, pkt); diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 80c8d332b2586fb1a4a2ddacca97f20fba9047ae..46f34b2e04784d8fd379384851c3d5b19377ddee 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c @@ -3,6 +3,9 @@ * Author: Sjur Brendeland/sjur.brandeland@stericsson.com * License terms: GNU General Public License (GPL) version 2 */ + +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -190,7 +193,7 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt) u8 id; struct cflayer *up; if (cfpkt_extr_head(pkt, &id, 1) < 0) { - pr_err("CAIF: %s(): erroneous Caif Packet\n", __func__); + pr_err("erroneous Caif Packet\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -199,8 +202,8 @@ static int cfmuxl_receive(struct cflayer *layr, struct cfpkt *pkt) up = get_up(muxl, id); spin_unlock(&muxl->receive_lock); if (up == NULL) { - pr_info("CAIF: %s():Received data on unknown link ID = %d " - "(0x%x) up == NULL", __func__, id, id); + pr_info("Received data on unknown link ID = %d (0x%x) up == NULL", + id, id); cfpkt_destroy(pkt); /* * Don't return ERROR, since modem misbehaves and sends out @@ -223,9 +226,8 @@ static int cfmuxl_transmit(struct cflayer *layr, struct cfpkt *pkt) struct caif_payload_info *info = cfpkt_info(pkt); dn = get_dn(muxl, cfpkt_info(pkt)->dev_info); if (dn == NULL) { - pr_warning("CAIF: %s(): Send data on unknown phy " - "ID = %d (0x%x)\n", - __func__, info->dev_info->id, info->dev_info->id); + pr_warn("Send data on unknown phy ID = %d (0x%x)\n", + info->dev_info->id, info->dev_info->id); return -ENOTCONN; } info->hdr_len += 1; diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c index c49a6695793ac8361b072077aefa4e2b863e8f5c..d7e865e2ff651c13d21a1ad45d402a924864f0bf 100644 --- a/net/caif/cfpkt_skbuff.c +++ b/net/caif/cfpkt_skbuff.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -12,11 +14,12 @@ #define PKT_PREFIX 48 #define PKT_POSTFIX 2 #define PKT_LEN_WHEN_EXTENDING 128 -#define PKT_ERROR(pkt, errmsg) do { \ - cfpkt_priv(pkt)->erronous = true; \ - skb_reset_tail_pointer(&pkt->skb); \ - pr_warning("CAIF: " errmsg);\ - } while (0) +#define PKT_ERROR(pkt, errmsg) \ +do { \ + cfpkt_priv(pkt)->erronous = true; \ + skb_reset_tail_pointer(&pkt->skb); \ + pr_warn(errmsg); \ +} while (0) struct cfpktq { struct sk_buff_head head; @@ -130,13 +133,13 @@ int cfpkt_extr_head(struct cfpkt *pkt, void *data, u16 len) return -EPROTO; if (unlikely(len > skb->len)) { - PKT_ERROR(pkt, "cfpkt_extr_head read beyond end of packet\n"); + PKT_ERROR(pkt, "read beyond end of packet\n"); return -EPROTO; } if (unlikely(len > skb_headlen(skb))) { if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_extr_head linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } } @@ -156,11 +159,11 @@ int cfpkt_extr_trail(struct cfpkt *pkt, void *dta, u16 len) return -EPROTO; if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_extr_trail linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } if (unlikely(skb->data + len > skb_tail_pointer(skb))) { - PKT_ERROR(pkt, "cfpkt_extr_trail read beyond end of packet\n"); + PKT_ERROR(pkt, "read beyond end of packet\n"); return -EPROTO; } from = skb_tail_pointer(skb) - len; @@ -202,7 +205,7 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len) /* Make sure data is writable */ if (unlikely(skb_cow_data(skb, addlen, &lastskb) < 0)) { - PKT_ERROR(pkt, "cfpkt_add_body: cow failed\n"); + PKT_ERROR(pkt, "cow failed\n"); return -EPROTO; } /* @@ -211,8 +214,7 @@ int cfpkt_add_body(struct cfpkt *pkt, const void *data, u16 len) * lengths of the top SKB. */ if (lastskb != skb) { - pr_warning("CAIF: %s(): Packet is non-linear\n", - __func__); + pr_warn("Packet is non-linear\n"); skb->len += len; skb->data_len += len; } @@ -242,14 +244,14 @@ int cfpkt_add_head(struct cfpkt *pkt, const void *data2, u16 len) if (unlikely(is_erronous(pkt))) return -EPROTO; if (unlikely(skb_headroom(skb) < len)) { - PKT_ERROR(pkt, "cfpkt_add_head: no headroom\n"); + PKT_ERROR(pkt, "no headroom\n"); return -EPROTO; } /* Make sure data is writable */ ret = skb_cow_data(skb, 0, &lastskb); if (unlikely(ret < 0)) { - PKT_ERROR(pkt, "cfpkt_add_head: cow failed\n"); + PKT_ERROR(pkt, "cow failed\n"); return ret; } @@ -283,7 +285,7 @@ inline u16 cfpkt_iterate(struct cfpkt *pkt, if (unlikely(is_erronous(pkt))) return -EPROTO; if (unlikely(skb_linearize(&pkt->skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_iterate: linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } return iter_func(data, pkt->skb.data, cfpkt_getlen(pkt)); @@ -309,7 +311,7 @@ int cfpkt_setlen(struct cfpkt *pkt, u16 len) /* Need to expand SKB */ if (unlikely(!cfpkt_pad_trail(pkt, len - skb->len))) - PKT_ERROR(pkt, "cfpkt_setlen: skb_pad_trail failed\n"); + PKT_ERROR(pkt, "skb_pad_trail failed\n"); return cfpkt_getlen(pkt); } @@ -380,8 +382,7 @@ struct cfpkt *cfpkt_split(struct cfpkt *pkt, u16 pos) return NULL; if (skb->data + pos > skb_tail_pointer(skb)) { - PKT_ERROR(pkt, - "cfpkt_split: trying to split beyond end of packet"); + PKT_ERROR(pkt, "trying to split beyond end of packet\n"); return NULL; } @@ -455,17 +456,17 @@ int cfpkt_raw_append(struct cfpkt *pkt, void **buf, unsigned int buflen) return -EPROTO; /* Make sure SKB is writable */ if (unlikely(skb_cow_data(skb, 0, &lastskb) < 0)) { - PKT_ERROR(pkt, "cfpkt_raw_append: skb_cow_data failed\n"); + PKT_ERROR(pkt, "skb_cow_data failed\n"); return -EPROTO; } if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_raw_append: linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } if (unlikely(skb_tailroom(skb) < buflen)) { - PKT_ERROR(pkt, "cfpkt_raw_append: buffer too short - failed\n"); + PKT_ERROR(pkt, "buffer too short - failed\n"); return -EPROTO; } @@ -483,14 +484,13 @@ int cfpkt_raw_extract(struct cfpkt *pkt, void **buf, unsigned int buflen) return -EPROTO; if (unlikely(buflen > skb->len)) { - PKT_ERROR(pkt, "cfpkt_raw_extract: buflen too large " - "- failed\n"); + PKT_ERROR(pkt, "buflen too large - failed\n"); return -EPROTO; } if (unlikely(buflen > skb_headlen(skb))) { if (unlikely(skb_linearize(skb) != 0)) { - PKT_ERROR(pkt, "cfpkt_raw_extract: linearize failed\n"); + PKT_ERROR(pkt, "linearize failed\n"); return -EPROTO; } } diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index 9a699242d104be7fbef70ed4560d6ca3a63ebda3..bde8481e8d2574dd939f84595f8e4354370aa5a7 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -48,7 +50,7 @@ struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info, kzalloc(sizeof(struct cfrfml), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } @@ -178,9 +180,7 @@ static int cfrfml_receive(struct cflayer *layr, struct cfpkt *pkt) cfpkt_destroy(rfml->incomplete_frm); rfml->incomplete_frm = NULL; - pr_info("CAIF: %s(): " - "Connection error %d triggered on RFM link\n", - __func__, err); + pr_info("Connection error %d triggered on RFM link\n", err); /* Trigger connection error upon failure.*/ layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, @@ -280,9 +280,7 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt) out: if (err != 0) { - pr_info("CAIF: %s(): " - "Connection error %d triggered on RFM link\n", - __func__, err); + pr_info("Connection error %d triggered on RFM link\n", err); /* Trigger connection error upon failure.*/ layr->up->ctrlcmd(layr->up, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index a11fbd68a13dec6debe45e647122523400f9f5a1..9297f7dea9d8c164d4d5652d7930866154556350 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -34,7 +36,7 @@ struct cflayer *cfserl_create(int type, int instance, bool use_stx) { struct cfserl *this = kmalloc(sizeof(struct cfserl), GFP_ATOMIC); if (!this) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfserl, layer) == 0); diff --git a/net/caif/cfsrvl.c b/net/caif/cfsrvl.c index f40939a91211b8e2b6ba985f2e1562064723e681..ab5e542526bf4e9e2f65562e56a97ccb96ba85bf 100644 --- a/net/caif/cfsrvl.c +++ b/net/caif/cfsrvl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -79,8 +81,7 @@ static void cfservl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, layr->up->ctrlcmd(layr->up, ctrl, phyid); break; default: - pr_warning("CAIF: %s(): " - "Unexpected ctrl in cfsrvl (%d)\n", __func__, ctrl); + pr_warn("Unexpected ctrl in cfsrvl (%d)\n", ctrl); /* We have both modem and phy flow on, send flow on */ layr->up->ctrlcmd(layr->up, ctrl, phyid); service->phy_flow_on = true; @@ -107,14 +108,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) u8 flow_on = SRVL_FLOW_ON; pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", - __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } if (cfpkt_add_head(pkt, &flow_on, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", - __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -131,14 +130,12 @@ static int cfservl_modemcmd(struct cflayer *layr, enum caif_modemcmd ctrl) u8 flow_off = SRVL_FLOW_OFF; pkt = cfpkt_create(SRVL_CTRL_PKT_SIZE); if (!pkt) { - pr_warning("CAIF: %s(): Out of memory\n", - __func__); + pr_warn("Out of memory\n"); return -ENOMEM; } if (cfpkt_add_head(pkt, &flow_off, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", - __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c index 02795aff57a426fbbd1080214f46c5a1fb569d34..efad410e4c829d098fd7b02f2aaa106d4ea8f782 100644 --- a/net/caif/cfutill.c +++ b/net/caif/cfutill.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -26,7 +28,7 @@ struct cflayer *cfutill_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *util = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!util) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -47,7 +49,7 @@ static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt) caif_assert(layr->up->receive != NULL); caif_assert(layr->up->ctrlcmd != NULL); if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -64,16 +66,14 @@ static int cfutill_receive(struct cflayer *layr, struct cfpkt *pkt) cfpkt_destroy(pkt); return 0; case UTIL_REMOTE_SHUTDOWN: /* Remote Shutdown Request */ - pr_err("CAIF: %s(): REMOTE SHUTDOWN REQUEST RECEIVED\n", - __func__); + pr_err("REMOTE SHUTDOWN REQUEST RECEIVED\n"); layr->ctrlcmd(layr, CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND, 0); service->open = false; cfpkt_destroy(pkt); return 0; default: cfpkt_destroy(pkt); - pr_warning("CAIF: %s(): Unknown service control %d (0x%x)\n", - __func__, cmd, cmd); + pr_warn("Unknown service control %d (0x%x)\n", cmd, cmd); return -EPROTO; } } diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c index 77cc09faac9a305cfa4a05554ad95bea6d52e08e..3b425b189a99f7dc55885ccf61fa2d951ec12ee1 100644 --- a/net/caif/cfveil.c +++ b/net/caif/cfveil.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -25,7 +27,7 @@ struct cflayer *cfvei_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *vei = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!vei) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -47,7 +49,7 @@ static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt) if (cfpkt_extr_head(pkt, &cmd, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } @@ -67,8 +69,7 @@ static int cfvei_receive(struct cflayer *layr, struct cfpkt *pkt) cfpkt_destroy(pkt); return 0; default: /* SET RS232 PIN */ - pr_warning("CAIF: %s():Unknown VEI control packet %d (0x%x)!\n", - __func__, cmd, cmd); + pr_warn("Unknown VEI control packet %d (0x%x)!\n", cmd, cmd); cfpkt_destroy(pkt); return -EPROTO; } @@ -86,7 +87,7 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt) caif_assert(layr->dn->transmit != NULL); if (cfpkt_add_head(pkt, &tmp, 1) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); return -EPROTO; } diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c index ada6ee2d48f50a3ab4df69f102778535c4292eba..bf6fef2a0eff19ddacfc0ef980a625886404469f 100644 --- a/net/caif/cfvidl.c +++ b/net/caif/cfvidl.c @@ -4,6 +4,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -21,7 +23,7 @@ struct cflayer *cfvidl_create(u8 channel_id, struct dev_info *dev_info) { struct cfsrvl *vid = kmalloc(sizeof(struct cfsrvl), GFP_ATOMIC); if (!vid) { - pr_warning("CAIF: %s(): Out of memory\n", __func__); + pr_warn("Out of memory\n"); return NULL; } caif_assert(offsetof(struct cfsrvl, layer) == 0); @@ -38,7 +40,7 @@ static int cfvidl_receive(struct cflayer *layr, struct cfpkt *pkt) { u32 videoheader; if (cfpkt_extr_head(pkt, &videoheader, 4) < 0) { - pr_err("CAIF: %s(): Packet is erroneous!\n", __func__); + pr_err("Packet is erroneous!\n"); cfpkt_destroy(pkt); return -EPROTO; } diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 4293e190ec5328f1da7f40065c9eefcdff5d1f66..84a422c989414d31c502de65d13b74d51c6a8f0c 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c @@ -5,6 +5,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ":%s(): " fmt, __func__ + #include #include #include @@ -28,9 +30,6 @@ #define CONNECT_TIMEOUT (5 * HZ) #define CAIF_NET_DEFAULT_QUEUE_LEN 500 -#undef pr_debug -#define pr_debug pr_warning - /*This list is protected by the rtnl lock. */ static LIST_HEAD(chnl_net_list); @@ -142,8 +141,7 @@ static void chnl_flowctrl_cb(struct cflayer *layr, enum caif_ctrlcmd flow, int phyid) { struct chnl_net *priv = container_of(layr, struct chnl_net, chnl); - pr_debug("CAIF: %s(): NET flowctrl func called flow: %s\n", - __func__, + pr_debug("NET flowctrl func called flow: %s\n", flow == CAIF_CTRLCMD_FLOW_ON_IND ? "ON" : flow == CAIF_CTRLCMD_INIT_RSP ? "INIT" : flow == CAIF_CTRLCMD_FLOW_OFF_IND ? "OFF" : @@ -196,12 +194,12 @@ static int chnl_net_start_xmit(struct sk_buff *skb, struct net_device *dev) priv = netdev_priv(dev); if (skb->len > priv->netdev->mtu) { - pr_warning("CAIF: %s(): Size of skb exceeded MTU\n", __func__); + pr_warn("Size of skb exceeded MTU\n"); return -ENOSPC; } if (!priv->flowenabled) { - pr_debug("CAIF: %s(): dropping packets flow off\n", __func__); + pr_debug("dropping packets flow off\n"); return NETDEV_TX_BUSY; } @@ -237,7 +235,7 @@ static int chnl_net_open(struct net_device *dev) ASSERT_RTNL(); priv = netdev_priv(dev); if (!priv) { - pr_debug("CAIF: %s(): chnl_net_open: no priv\n", __func__); + pr_debug("chnl_net_open: no priv\n"); return -ENODEV; } @@ -246,18 +244,17 @@ static int chnl_net_open(struct net_device *dev) result = caif_connect_client(&priv->conn_req, &priv->chnl, &llifindex, &headroom, &tailroom); if (result != 0) { - pr_debug("CAIF: %s(): err: " - "Unable to register and open device," - " Err:%d\n", - __func__, - result); + pr_debug("err: " + "Unable to register and open device," + " Err:%d\n", + result); goto error; } lldev = dev_get_by_index(dev_net(dev), llifindex); if (lldev == NULL) { - pr_debug("CAIF: %s(): no interface?\n", __func__); + pr_debug("no interface?\n"); result = -ENODEV; goto error; } @@ -279,9 +276,7 @@ static int chnl_net_open(struct net_device *dev) dev_put(lldev); if (mtu < 100) { - pr_warning("CAIF: %s(): " - "CAIF Interface MTU too small (%d)\n", - __func__, mtu); + pr_warn("CAIF Interface MTU too small (%d)\n", mtu); result = -ENODEV; goto error; } @@ -296,33 +291,32 @@ static int chnl_net_open(struct net_device *dev) rtnl_lock(); if (result == -ERESTARTSYS) { - pr_debug("CAIF: %s(): wait_event_interruptible" - " woken by a signal\n", __func__); + pr_debug("wait_event_interruptible woken by a signal\n"); result = -ERESTARTSYS; goto error; } if (result == 0) { - pr_debug("CAIF: %s(): connect timeout\n", __func__); + pr_debug("connect timeout\n"); caif_disconnect_client(&priv->chnl); priv->state = CAIF_DISCONNECTED; - pr_debug("CAIF: %s(): state disconnected\n", __func__); + pr_debug("state disconnected\n"); result = -ETIMEDOUT; goto error; } if (priv->state != CAIF_CONNECTED) { - pr_debug("CAIF: %s(): connect failed\n", __func__); + pr_debug("connect failed\n"); result = -ECONNREFUSED; goto error; } - pr_debug("CAIF: %s(): CAIF Netdevice connected\n", __func__); + pr_debug("CAIF Netdevice connected\n"); return 0; error: caif_disconnect_client(&priv->chnl); priv->state = CAIF_DISCONNECTED; - pr_debug("CAIF: %s(): state disconnected\n", __func__); + pr_debug("state disconnected\n"); return result; } @@ -413,7 +407,7 @@ static void caif_netlink_parms(struct nlattr *data[], struct caif_connect_request *conn_req) { if (!data) { - pr_warning("CAIF: %s: no params data found\n", __func__); + pr_warn("no params data found\n"); return; } if (data[IFLA_CAIF_IPV4_CONNID]) @@ -442,8 +436,7 @@ static int ipcaif_newlink(struct net *src_net, struct net_device *dev, ret = register_netdevice(dev); if (ret) - pr_warning("CAIF: %s(): device rtml registration failed\n", - __func__); + pr_warn("device rtml registration failed\n"); return ret; } diff --git a/net/can/raw.c b/net/can/raw.c index a10e3338f084aaf15eb73b40d46f1f28e96aaaf7..e88f610fdb7bb11e69cc1f5a0bf10846d5c7165c 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -90,23 +90,39 @@ struct raw_sock { can_err_mask_t err_mask; }; +/* + * Return pointer to store the extra msg flags for raw_recvmsg(). + * We use the space of one unsigned int beyond the 'struct sockaddr_can' + * in skb->cb. + */ +static inline unsigned int *raw_flags(struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(skb->cb) <= (sizeof(struct sockaddr_can) + + sizeof(unsigned int))); + + /* return pointer after struct sockaddr_can */ + return (unsigned int *)(&((struct sockaddr_can *)skb->cb)[1]); +} + static inline struct raw_sock *raw_sk(const struct sock *sk) { return (struct raw_sock *)sk; } -static void raw_rcv(struct sk_buff *skb, void *data) +static void raw_rcv(struct sk_buff *oskb, void *data) { struct sock *sk = (struct sock *)data; struct raw_sock *ro = raw_sk(sk); struct sockaddr_can *addr; + struct sk_buff *skb; + unsigned int *pflags; /* check the received tx sock reference */ - if (!ro->recv_own_msgs && skb->sk == sk) + if (!ro->recv_own_msgs && oskb->sk == sk) return; /* clone the given skb to be able to enqueue it into the rcv queue */ - skb = skb_clone(skb, GFP_ATOMIC); + skb = skb_clone(oskb, GFP_ATOMIC); if (!skb) return; @@ -123,6 +139,14 @@ static void raw_rcv(struct sk_buff *skb, void *data) addr->can_family = AF_CAN; addr->can_ifindex = skb->dev->ifindex; + /* add CAN specific message flags for raw_recvmsg() */ + pflags = raw_flags(skb); + *pflags = 0; + if (oskb->sk) + *pflags |= MSG_DONTROUTE; + if (oskb->sk == sk) + *pflags |= MSG_CONFIRM; + if (sock_queue_rcv_skb(sk, skb) < 0) kfree_skb(skb); } @@ -647,12 +671,12 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock, err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); if (err < 0) goto free_skb; - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); if (err < 0) goto free_skb; /* to be able to check the received tx sock reference in raw_rcv() */ - skb_tx(skb)->prevent_sk_orphan = 1; + skb_shinfo(skb)->tx_flags |= SKBTX_DRV_NEEDS_SK_REF; skb->dev = dev; skb->sk = sk; @@ -707,6 +731,9 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, memcpy(msg->msg_name, skb->cb, msg->msg_namelen); } + /* assign the flags that have been recorded in raw_rcv() */ + msg->msg_flags |= *(raw_flags(skb)); + skb_free_datagram(sk, skb); return size; diff --git a/net/core/datagram.c b/net/core/datagram.c index 282806ba7a57e60991f2f7806bc3015d9b8596a5..cd1e039c87559a236db754e738917b5e34666aaa 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c @@ -747,13 +747,12 @@ unsigned int datagram_poll(struct file *file, struct socket *sock, if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ diff --git a/net/core/dev.c b/net/core/dev.c index 7ec85e27beed840b8da5f9dae620bcd48453f3f7..78b5a89b0f40a455e4229fb04b291e87877b491b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -131,6 +131,7 @@ #include #include #include +#include #include "net-sysfs.h" @@ -373,6 +374,14 @@ static inline void netdev_set_addr_lockdep_class(struct net_device *dev) * --ANK (980803) */ +static inline struct list_head *ptype_head(const struct packet_type *pt) +{ + if (pt->type == htons(ETH_P_ALL)) + return &ptype_all; + else + return &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK]; +} + /** * dev_add_pack - add packet handler * @pt: packet type declaration @@ -388,16 +397,11 @@ static inline void netdev_set_addr_lockdep_class(struct net_device *dev) void dev_add_pack(struct packet_type *pt) { - int hash; + struct list_head *head = ptype_head(pt); - spin_lock_bh(&ptype_lock); - if (pt->type == htons(ETH_P_ALL)) - list_add_rcu(&pt->list, &ptype_all); - else { - hash = ntohs(pt->type) & PTYPE_HASH_MASK; - list_add_rcu(&pt->list, &ptype_base[hash]); - } - spin_unlock_bh(&ptype_lock); + spin_lock(&ptype_lock); + list_add_rcu(&pt->list, head); + spin_unlock(&ptype_lock); } EXPORT_SYMBOL(dev_add_pack); @@ -416,15 +420,10 @@ EXPORT_SYMBOL(dev_add_pack); */ void __dev_remove_pack(struct packet_type *pt) { - struct list_head *head; + struct list_head *head = ptype_head(pt); struct packet_type *pt1; - spin_lock_bh(&ptype_lock); - - if (pt->type == htons(ETH_P_ALL)) - head = &ptype_all; - else - head = &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK]; + spin_lock(&ptype_lock); list_for_each_entry(pt1, head, list) { if (pt == pt1) { @@ -435,7 +434,7 @@ void __dev_remove_pack(struct packet_type *pt) printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt); out: - spin_unlock_bh(&ptype_lock); + spin_unlock(&ptype_lock); } EXPORT_SYMBOL(__dev_remove_pack); @@ -1486,8 +1485,9 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) skb_orphan(skb); nf_reset(skb); - if (!(dev->flags & IFF_UP) || - (skb->len > (dev->mtu + dev->hard_header_len))) { + if (unlikely(!(dev->flags & IFF_UP) || + (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) { + atomic_long_inc(&dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; } @@ -1555,21 +1555,56 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues * greater then real_num_tx_queues stale skbs on the qdisc must be flushed. */ -void netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) +int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq) { - unsigned int real_num = dev->real_num_tx_queues; + if (txq < 1 || txq > dev->num_tx_queues) + return -EINVAL; - if (unlikely(txq > dev->num_tx_queues)) - ; - else if (txq > real_num) - dev->real_num_tx_queues = txq; - else if (txq < real_num) { - dev->real_num_tx_queues = txq; - qdisc_reset_all_tx_gt(dev, txq); + if (dev->reg_state == NETREG_REGISTERED) { + ASSERT_RTNL(); + + if (txq < dev->real_num_tx_queues) + qdisc_reset_all_tx_gt(dev, txq); } + + dev->real_num_tx_queues = txq; + return 0; } EXPORT_SYMBOL(netif_set_real_num_tx_queues); +#ifdef CONFIG_RPS +/** + * netif_set_real_num_rx_queues - set actual number of RX queues used + * @dev: Network device + * @rxq: Actual number of RX queues + * + * This must be called either with the rtnl_lock held or before + * registration of the net device. Returns 0 on success, or a + * negative error code. If called before registration, it always + * succeeds. + */ +int netif_set_real_num_rx_queues(struct net_device *dev, unsigned int rxq) +{ + int rc; + + if (rxq < 1 || rxq > dev->num_rx_queues) + return -EINVAL; + + if (dev->reg_state == NETREG_REGISTERED) { + ASSERT_RTNL(); + + rc = net_rx_queue_update_kobjects(dev, dev->real_num_rx_queues, + rxq); + if (rc) + return rc; + } + + dev->real_num_rx_queues = rxq; + return 0; +} +EXPORT_SYMBOL(netif_set_real_num_rx_queues); +#endif + static inline void __netif_reschedule(struct Qdisc *q) { struct softnet_data *sd; @@ -1661,7 +1696,12 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol) static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) { - if (can_checksum_protocol(dev->features, skb->protocol)) + int features = dev->features; + + if (vlan_tx_tag_present(skb)) + features &= dev->vlan_features; + + if (can_checksum_protocol(features, skb->protocol)) return true; if (skb->protocol == htons(ETH_P_8021Q)) { @@ -1760,6 +1800,16 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) __be16 type = skb->protocol; int err; + if (type == htons(ETH_P_8021Q)) { + struct vlan_ethhdr *veh; + + if (unlikely(!pskb_may_pull(skb, VLAN_ETH_HLEN))) + return ERR_PTR(-EINVAL); + + veh = (struct vlan_ethhdr *)skb->data; + type = veh->h_vlan_encapsulated_proto; + } + skb_reset_mac_header(skb); skb->mac_len = skb->network_header - skb->mac_header; __skb_pull(skb, skb->mac_len); @@ -1904,14 +1954,14 @@ static int dev_gso_segment(struct sk_buff *skb) /* * Try to orphan skb early, right before transmission by the device. - * We cannot orphan skb if tx timestamp is requested, since - * drivers need to call skb_tstamp_tx() to send the timestamp. + * We cannot orphan skb if tx timestamp is requested or the sk-reference + * is needed on driver level for other reasons, e.g. see net/can/raw.c */ static inline void skb_orphan_try(struct sk_buff *skb) { struct sock *sk = skb->sk; - if (sk && !skb_tx(skb)->flags) { + if (sk && !skb_shinfo(skb)->tx_flags) { /* skb_tx_hash() wont be able to get sk. * We copy sk_hash into skb->rxhash */ @@ -1931,9 +1981,14 @@ static inline void skb_orphan_try(struct sk_buff *skb) static inline int skb_needs_linearize(struct sk_buff *skb, struct net_device *dev) { + int features = dev->features; + + if (skb->protocol == htons(ETH_P_8021Q) || vlan_tx_tag_present(skb)) + features &= dev->vlan_features; + return skb_is_nonlinear(skb) && - ((skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) || - (skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) || + ((skb_has_frag_list(skb) && !(features & NETIF_F_FRAGLIST)) || + (skb_shinfo(skb)->nr_frags && (!(features & NETIF_F_SG) || illegal_highdma(dev, skb)))); } @@ -1956,6 +2011,15 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, skb_orphan_try(skb); + if (vlan_tx_tag_present(skb) && + !(dev->features & NETIF_F_HW_VLAN_TX)) { + skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); + if (unlikely(!skb)) + goto out; + + skb->vlan_tci = 0; + } + if (netif_needs_gso(dev, skb)) { if (unlikely(dev_gso_segment(skb))) goto out_kfree_skb; @@ -2019,6 +2083,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, skb->destructor = DEV_GSO_CB(skb)->destructor; out_kfree_skb: kfree_skb(skb); +out: return rc; } @@ -2147,6 +2212,9 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q, return rc; } +static DEFINE_PER_CPU(int, xmit_recursion); +#define RECURSION_LIMIT 3 + /** * dev_queue_xmit - transmit a buffer * @skb: buffer to transmit @@ -2213,10 +2281,15 @@ int dev_queue_xmit(struct sk_buff *skb) if (txq->xmit_lock_owner != cpu) { + if (__this_cpu_read(xmit_recursion) > RECURSION_LIMIT) + goto recursion_alert; + HARD_TX_LOCK(dev, txq, cpu); if (!netif_tx_queue_stopped(txq)) { + __this_cpu_inc(xmit_recursion); rc = dev_hard_start_xmit(skb, dev, txq); + __this_cpu_dec(xmit_recursion); if (dev_xmit_complete(rc)) { HARD_TX_UNLOCK(dev, txq); goto out; @@ -2228,7 +2301,9 @@ int dev_queue_xmit(struct sk_buff *skb) "queue packet!\n", dev->name); } else { /* Recursion is detected! It is possible, - * unfortunately */ + * unfortunately + */ +recursion_alert: if (net_ratelimit()) printk(KERN_CRIT "Dead loop on virtual device " "%s, fix it urgently!\n", dev->name); @@ -2264,69 +2339,44 @@ static inline void ____napi_schedule(struct softnet_data *sd, __raise_softirq_irqoff(NET_RX_SOFTIRQ); } -#ifdef CONFIG_RPS - -/* One global table that all flow-based protocols share. */ -struct rps_sock_flow_table *rps_sock_flow_table __read_mostly; -EXPORT_SYMBOL(rps_sock_flow_table); - /* - * get_rps_cpu is called from netif_receive_skb and returns the target - * CPU from the RPS map of the receiving queue for a given skb. - * rcu_read_lock must be held on entry. + * __skb_get_rxhash: calculate a flow hash based on src/dst addresses + * and src/dst port numbers. Returns a non-zero hash number on success + * and 0 on failure. */ -static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, - struct rps_dev_flow **rflowp) +__u32 __skb_get_rxhash(struct sk_buff *skb) { + int nhoff, hash = 0, poff; struct ipv6hdr *ip6; struct iphdr *ip; - struct netdev_rx_queue *rxqueue; - struct rps_map *map; - struct rps_dev_flow_table *flow_table; - struct rps_sock_flow_table *sock_flow_table; - int cpu = -1; u8 ip_proto; - u16 tcpu; u32 addr1, addr2, ihl; union { u32 v32; u16 v16[2]; } ports; - if (skb_rx_queue_recorded(skb)) { - u16 index = skb_get_rx_queue(skb); - if (unlikely(index >= dev->num_rx_queues)) { - WARN_ONCE(dev->num_rx_queues > 1, "%s received packet " - "on queue %u, but number of RX queues is %u\n", - dev->name, index, dev->num_rx_queues); - goto done; - } - rxqueue = dev->_rx + index; - } else - rxqueue = dev->_rx; - - if (!rxqueue->rps_map && !rxqueue->rps_flow_table) - goto done; - - if (skb->rxhash) - goto got_hash; /* Skip hash computation on packet header */ + nhoff = skb_network_offset(skb); switch (skb->protocol) { case __constant_htons(ETH_P_IP): - if (!pskb_may_pull(skb, sizeof(*ip))) + if (!pskb_may_pull(skb, sizeof(*ip) + nhoff)) goto done; - ip = (struct iphdr *) skb->data; - ip_proto = ip->protocol; + ip = (struct iphdr *) (skb->data + nhoff); + if (ip->frag_off & htons(IP_MF | IP_OFFSET)) + ip_proto = 0; + else + ip_proto = ip->protocol; addr1 = (__force u32) ip->saddr; addr2 = (__force u32) ip->daddr; ihl = ip->ihl; break; case __constant_htons(ETH_P_IPV6): - if (!pskb_may_pull(skb, sizeof(*ip6))) + if (!pskb_may_pull(skb, sizeof(*ip6) + nhoff)) goto done; - ip6 = (struct ipv6hdr *) skb->data; + ip6 = (struct ipv6hdr *) (skb->data + nhoff); ip_proto = ip6->nexthdr; addr1 = (__force u32) ip6->saddr.s6_addr32[3]; addr2 = (__force u32) ip6->daddr.s6_addr32[3]; @@ -2335,33 +2385,81 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, default: goto done; } - switch (ip_proto) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_DCCP: - case IPPROTO_ESP: - case IPPROTO_AH: - case IPPROTO_SCTP: - case IPPROTO_UDPLITE: - if (pskb_may_pull(skb, (ihl * 4) + 4)) { - ports.v32 = * (__force u32 *) (skb->data + (ihl * 4)); + + ports.v32 = 0; + poff = proto_ports_offset(ip_proto); + if (poff >= 0) { + nhoff += ihl * 4 + poff; + if (pskb_may_pull(skb, nhoff + 4)) { + ports.v32 = * (__force u32 *) (skb->data + nhoff); if (ports.v16[1] < ports.v16[0]) swap(ports.v16[0], ports.v16[1]); - break; } - default: - ports.v32 = 0; - break; } /* get a consistent hash (same value on both flow directions) */ if (addr2 < addr1) swap(addr1, addr2); - skb->rxhash = jhash_3words(addr1, addr2, ports.v32, hashrnd); - if (!skb->rxhash) - skb->rxhash = 1; -got_hash: + hash = jhash_3words(addr1, addr2, ports.v32, hashrnd); + if (!hash) + hash = 1; + +done: + return hash; +} +EXPORT_SYMBOL(__skb_get_rxhash); + +#ifdef CONFIG_RPS + +/* One global table that all flow-based protocols share. */ +struct rps_sock_flow_table *rps_sock_flow_table __read_mostly; +EXPORT_SYMBOL(rps_sock_flow_table); + +/* + * get_rps_cpu is called from netif_receive_skb and returns the target + * CPU from the RPS map of the receiving queue for a given skb. + * rcu_read_lock must be held on entry. + */ +static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, + struct rps_dev_flow **rflowp) +{ + struct netdev_rx_queue *rxqueue; + struct rps_map *map = NULL; + struct rps_dev_flow_table *flow_table; + struct rps_sock_flow_table *sock_flow_table; + int cpu = -1; + u16 tcpu; + + if (skb_rx_queue_recorded(skb)) { + u16 index = skb_get_rx_queue(skb); + if (unlikely(index >= dev->real_num_rx_queues)) { + WARN_ONCE(dev->real_num_rx_queues > 1, + "%s received packet on queue %u, but number " + "of RX queues is %u\n", + dev->name, index, dev->real_num_rx_queues); + goto done; + } + rxqueue = dev->_rx + index; + } else + rxqueue = dev->_rx; + + if (rxqueue->rps_map) { + map = rcu_dereference(rxqueue->rps_map); + if (map && map->len == 1) { + tcpu = map->cpus[0]; + if (cpu_online(tcpu)) + cpu = tcpu; + goto done; + } + } else if (!rxqueue->rps_flow_table) { + goto done; + } + + skb_reset_network_header(skb); + if (!skb_get_rxhash(skb)) + goto done; + flow_table = rcu_dereference(rxqueue->rps_flow_table); sock_flow_table = rcu_dereference(rps_sock_flow_table); if (flow_table && sock_flow_table) { @@ -2401,7 +2499,6 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, } } - map = rcu_dereference(rxqueue->rps_map); if (map) { tcpu = map->cpus[((u64) skb->rxhash * map->len) >> 32]; @@ -2487,6 +2584,7 @@ static int enqueue_to_backlog(struct sk_buff *skb, int cpu, local_irq_restore(flags); + atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); return NET_RX_DROP; } @@ -2643,11 +2741,10 @@ EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook); * the ingress scheduler, you just cant add policies on ingress. * */ -static int ing_filter(struct sk_buff *skb) +static int ing_filter(struct sk_buff *skb, struct netdev_queue *rxq) { struct net_device *dev = skb->dev; u32 ttl = G_TC_RTTL(skb->tc_verd); - struct netdev_queue *rxq; int result = TC_ACT_OK; struct Qdisc *q; @@ -2661,8 +2758,6 @@ static int ing_filter(struct sk_buff *skb) skb->tc_verd = SET_TC_RTTL(skb->tc_verd, ttl); skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_INGRESS); - rxq = &dev->rx_queue; - q = rxq->qdisc; if (q != &noop_qdisc) { spin_lock(qdisc_lock(q)); @@ -2678,7 +2773,9 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, struct packet_type **pt_prev, int *ret, struct net_device *orig_dev) { - if (skb->dev->rx_queue.qdisc == &noop_qdisc) + struct netdev_queue *rxq = rcu_dereference(skb->dev->ingress_queue); + + if (!rxq || rxq->qdisc == &noop_qdisc) goto out; if (*pt_prev) { @@ -2686,7 +2783,7 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, *pt_prev = NULL; } - switch (ing_filter(skb)) { + switch (ing_filter(skb, rxq)) { case TC_ACT_SHOT: case TC_ACT_STOLEN: kfree_skb(skb); @@ -2699,33 +2796,6 @@ static inline struct sk_buff *handle_ing(struct sk_buff *skb, } #endif -/* - * netif_nit_deliver - deliver received packets to network taps - * @skb: buffer - * - * This function is used to deliver incoming packets to network - * taps. It should be used when the normal netif_receive_skb path - * is bypassed, for example because of VLAN acceleration. - */ -void netif_nit_deliver(struct sk_buff *skb) -{ - struct packet_type *ptype; - - if (list_empty(&ptype_all)) - return; - - skb_reset_network_header(skb); - skb_reset_transport_header(skb); - skb->mac_len = skb->network_header - skb->mac_header; - - rcu_read_lock(); - list_for_each_entry_rcu(ptype, &ptype_all, list) { - if (!ptype->dev || ptype->dev == skb->dev) - deliver_skb(skb, ptype, skb->dev); - } - rcu_read_unlock(); -} - /** * netdev_rx_handler_register - register receive handler * @dev: device to register a handler for @@ -2836,8 +2906,6 @@ static int __netif_receive_skb(struct sk_buff *skb) net_timestamp_check(skb); trace_netif_receive_skb(skb); - if (vlan_tx_tag_present(skb) && vlan_hwaccel_do_receive(skb)) - return NET_RX_SUCCESS; /* if we've gotten here through NAPI, check netpoll */ if (netpoll_receive_skb(skb)) @@ -2851,8 +2919,7 @@ static int __netif_receive_skb(struct sk_buff *skb) * be delivered to pkt handlers that are exact matches. Also * the deliver_no_wcard flag will be set. If packet handlers * are sensitive to duplicate packets these skbs will need to - * be dropped at the handler. The vlan accel path may have - * already set the deliver_no_wcard flag. + * be dropped at the handler. */ null_or_orig = NULL; orig_dev = skb->dev; @@ -2911,6 +2978,18 @@ static int __netif_receive_skb(struct sk_buff *skb) goto out; } + if (vlan_tx_tag_present(skb)) { + if (pt_prev) { + ret = deliver_skb(skb, pt_prev, orig_dev); + pt_prev = NULL; + } + if (vlan_hwaccel_do_receive(&skb)) { + ret = __netif_receive_skb(skb); + goto out; + } else if (unlikely(!skb)) + goto out; + } + /* * Make sure frames received on VLAN interfaces stacked on * bonding interfaces still make their way to any base bonding @@ -2938,6 +3017,7 @@ static int __netif_receive_skb(struct sk_buff *skb) if (pt_prev) { ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); } else { + atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); /* Jamal, now you will not able to escape explaining * me how you were going to use this. :-) @@ -3058,7 +3138,7 @@ static int napi_gro_complete(struct sk_buff *skb) return netif_receive_skb(skb); } -static void napi_gro_flush(struct napi_struct *napi) +inline void napi_gro_flush(struct napi_struct *napi) { struct sk_buff *skb, *next; @@ -3071,6 +3151,7 @@ static void napi_gro_flush(struct napi_struct *napi) napi->gro_count = 0; napi->gro_list = NULL; } +EXPORT_SYMBOL(napi_gro_flush); enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) { @@ -3085,7 +3166,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) if (!(skb->dev->features & NETIF_F_GRO) || netpoll_rx_on(skb)) goto normal; - if (skb_is_gso(skb) || skb_has_frags(skb)) + if (skb_is_gso(skb) || skb_has_frag_list(skb)) goto normal; rcu_read_lock(); @@ -3164,16 +3245,19 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) } EXPORT_SYMBOL(dev_gro_receive); -static gro_result_t +static inline gro_result_t __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) { struct sk_buff *p; for (p = napi->gro_list; p; p = p->next) { - NAPI_GRO_CB(p)->same_flow = - (p->dev == skb->dev) && - !compare_ether_header(skb_mac_header(p), + unsigned long diffs; + + diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev; + diffs |= p->vlan_tci ^ skb->vlan_tci; + diffs |= compare_ether_header(skb_mac_header(p), skb_gro_mac_header(skb)); + NAPI_GRO_CB(p)->same_flow = !diffs; NAPI_GRO_CB(p)->flush = 0; } @@ -3226,14 +3310,14 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) } EXPORT_SYMBOL(napi_gro_receive); -void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) +static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) { __skb_pull(skb, skb_headlen(skb)); skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); + skb->vlan_tci = 0; napi->skb = skb; } -EXPORT_SYMBOL(napi_reuse_skb); struct sk_buff *napi_get_frags(struct napi_struct *napi) { @@ -4867,21 +4951,6 @@ static void rollback_registered(struct net_device *dev) rollback_registered_many(&single); } -static void __netdev_init_queue_locks_one(struct net_device *dev, - struct netdev_queue *dev_queue, - void *_unused) -{ - spin_lock_init(&dev_queue->_xmit_lock); - netdev_set_xmit_lockdep_class(&dev_queue->_xmit_lock, dev->type); - dev_queue->xmit_lock_owner = -1; -} - -static void netdev_init_queue_locks(struct net_device *dev) -{ - netdev_for_each_tx_queue(dev, __netdev_init_queue_locks_one, NULL); - __netdev_init_queue_locks_one(dev, &dev->rx_queue, NULL); -} - unsigned long netdev_fix_features(unsigned long features, const char *name) { /* Fix illegal SG+CSUM combinations. */ @@ -4949,6 +5018,66 @@ void netif_stacked_transfer_operstate(const struct net_device *rootdev, } EXPORT_SYMBOL(netif_stacked_transfer_operstate); +static int netif_alloc_rx_queues(struct net_device *dev) +{ +#ifdef CONFIG_RPS + unsigned int i, count = dev->num_rx_queues; + struct netdev_rx_queue *rx; + + BUG_ON(count < 1); + + rx = kcalloc(count, sizeof(struct netdev_rx_queue), GFP_KERNEL); + if (!rx) { + pr_err("netdev: Unable to allocate %u rx queues.\n", count); + return -ENOMEM; + } + dev->_rx = rx; + + /* + * Set a pointer to first element in the array which holds the + * reference count. + */ + for (i = 0; i < count; i++) + rx[i].first = rx; +#endif + return 0; +} + +static int netif_alloc_netdev_queues(struct net_device *dev) +{ + unsigned int count = dev->num_tx_queues; + struct netdev_queue *tx; + + BUG_ON(count < 1); + + tx = kcalloc(count, sizeof(struct netdev_queue), GFP_KERNEL); + if (!tx) { + pr_err("netdev: Unable to allocate %u tx queues.\n", + count); + return -ENOMEM; + } + dev->_tx = tx; + return 0; +} + +static void netdev_init_one_queue(struct net_device *dev, + struct netdev_queue *queue, + void *_unused) +{ + queue->dev = dev; + + /* Initialize queue lock */ + spin_lock_init(&queue->_xmit_lock); + netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type); + queue->xmit_lock_owner = -1; +} + +static void netdev_init_queues(struct net_device *dev) +{ + netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL); + spin_lock_init(&dev->tx_global_lock); +} + /** * register_netdevice - register a network device * @dev: device to register @@ -4982,28 +5111,19 @@ int register_netdevice(struct net_device *dev) spin_lock_init(&dev->addr_list_lock); netdev_set_addr_lockdep_class(dev); - netdev_init_queue_locks(dev); dev->iflink = -1; -#ifdef CONFIG_RPS - if (!dev->num_rx_queues) { - /* - * Allocate a single RX queue if driver never called - * alloc_netdev_mq - */ + ret = netif_alloc_rx_queues(dev); + if (ret) + goto out; - dev->_rx = kzalloc(sizeof(struct netdev_rx_queue), GFP_KERNEL); - if (!dev->_rx) { - ret = -ENOMEM; - goto out; - } + ret = netif_alloc_netdev_queues(dev); + if (ret) + goto out; + + netdev_init_queues(dev); - dev->_rx->first = dev->_rx; - atomic_set(&dev->_rx->count, 1); - dev->num_rx_queues = 1; - } -#endif /* Init, if this function is available */ if (dev->netdev_ops->ndo_init) { ret = dev->netdev_ops->ndo_init(dev); @@ -5043,6 +5163,12 @@ int register_netdevice(struct net_device *dev) if (dev->features & NETIF_F_SG) dev->features |= NETIF_F_GSO; + /* Enable GRO and NETIF_F_HIGHDMA for vlans by default, + * vlan_dev_init() will do the dev->features check, so these features + * are enabled only if supported by underlying device. + */ + dev->vlan_features |= (NETIF_F_GRO | NETIF_F_HIGHDMA); + ret = call_netdevice_notifiers(NETDEV_POST_INIT, dev); ret = notifier_to_errno(ret); if (ret) @@ -5113,9 +5239,6 @@ int init_dummy_netdev(struct net_device *dev) */ dev->reg_state = NETREG_DUMMY; - /* initialize the ref count */ - atomic_set(&dev->refcnt, 1); - /* NAPI wants this */ INIT_LIST_HEAD(&dev->napi_list); @@ -5123,6 +5246,11 @@ int init_dummy_netdev(struct net_device *dev) set_bit(__LINK_STATE_PRESENT, &dev->state); set_bit(__LINK_STATE_START, &dev->state); + /* Note : We dont allocate pcpu_refcnt for dummy devices, + * because users of this 'device' dont need to change + * its refcount. + */ + return 0; } EXPORT_SYMBOL_GPL(init_dummy_netdev); @@ -5164,6 +5292,16 @@ int register_netdev(struct net_device *dev) } EXPORT_SYMBOL(register_netdev); +int netdev_refcnt_read(const struct net_device *dev) +{ + int i, refcnt = 0; + + for_each_possible_cpu(i) + refcnt += *per_cpu_ptr(dev->pcpu_refcnt, i); + return refcnt; +} +EXPORT_SYMBOL(netdev_refcnt_read); + /* * netdev_wait_allrefs - wait until all references are gone. * @@ -5178,11 +5316,14 @@ EXPORT_SYMBOL(register_netdev); static void netdev_wait_allrefs(struct net_device *dev) { unsigned long rebroadcast_time, warning_time; + int refcnt; linkwatch_forget_dev(dev); rebroadcast_time = warning_time = jiffies; - while (atomic_read(&dev->refcnt) != 0) { + refcnt = netdev_refcnt_read(dev); + + while (refcnt != 0) { if (time_after(jiffies, rebroadcast_time + 1 * HZ)) { rtnl_lock(); @@ -5209,11 +5350,13 @@ static void netdev_wait_allrefs(struct net_device *dev) msleep(250); + refcnt = netdev_refcnt_read(dev); + if (time_after(jiffies, warning_time + 10 * HZ)) { printk(KERN_EMERG "unregister_netdevice: " "waiting for %s to become free. Usage " "count = %d\n", - dev->name, atomic_read(&dev->refcnt)); + dev->name, refcnt); warning_time = jiffies; } } @@ -5271,8 +5414,8 @@ void netdev_run_todo(void) netdev_wait_allrefs(dev); /* paranoia */ - BUG_ON(atomic_read(&dev->refcnt)); - WARN_ON(dev->ip_ptr); + BUG_ON(netdev_refcnt_read(dev)); + WARN_ON(rcu_dereference_raw(dev->ip_ptr)); WARN_ON(dev->ip6_ptr); WARN_ON(dev->dn_ptr); @@ -5350,30 +5493,34 @@ struct rtnl_link_stats64 *dev_get_stats(struct net_device *dev, if (ops->ndo_get_stats64) { memset(storage, 0, sizeof(*storage)); - return ops->ndo_get_stats64(dev, storage); - } - if (ops->ndo_get_stats) { + ops->ndo_get_stats64(dev, storage); + } else if (ops->ndo_get_stats) { netdev_stats_to_stats64(storage, ops->ndo_get_stats(dev)); - return storage; + } else { + netdev_stats_to_stats64(storage, &dev->stats); + dev_txq_stats_fold(dev, storage); } - netdev_stats_to_stats64(storage, &dev->stats); - dev_txq_stats_fold(dev, storage); + storage->rx_dropped += atomic_long_read(&dev->rx_dropped); return storage; } EXPORT_SYMBOL(dev_get_stats); -static void netdev_init_one_queue(struct net_device *dev, - struct netdev_queue *queue, - void *_unused) +struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) { - queue->dev = dev; -} + struct netdev_queue *queue = dev_ingress_queue(dev); -static void netdev_init_queues(struct net_device *dev) -{ - netdev_init_one_queue(dev, &dev->rx_queue, NULL); - netdev_for_each_tx_queue(dev, netdev_init_one_queue, NULL); - spin_lock_init(&dev->tx_global_lock); +#ifdef CONFIG_NET_CLS_ACT + if (queue) + return queue; + queue = kzalloc(sizeof(*queue), GFP_KERNEL); + if (!queue) + return NULL; + netdev_init_one_queue(dev, queue, NULL); + queue->qdisc = &noop_qdisc; + queue->qdisc_sleeping = &noop_qdisc; + rcu_assign_pointer(dev->ingress_queue, queue); +#endif + return queue; } /** @@ -5390,17 +5537,18 @@ static void netdev_init_queues(struct net_device *dev) struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, void (*setup)(struct net_device *), unsigned int queue_count) { - struct netdev_queue *tx; struct net_device *dev; size_t alloc_size; struct net_device *p; -#ifdef CONFIG_RPS - struct netdev_rx_queue *rx; - int i; -#endif BUG_ON(strlen(name) >= sizeof(dev->name)); + if (queue_count < 1) { + pr_err("alloc_netdev: Unable to allocate device " + "with zero queues.\n"); + return NULL; + } + alloc_size = sizeof(struct net_device); if (sizeof_priv) { /* ensure 32-byte alignment of private area */ @@ -5416,55 +5564,31 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, return NULL; } - tx = kcalloc(queue_count, sizeof(struct netdev_queue), GFP_KERNEL); - if (!tx) { - printk(KERN_ERR "alloc_netdev: Unable to allocate " - "tx qdiscs.\n"); - goto free_p; - } - -#ifdef CONFIG_RPS - rx = kcalloc(queue_count, sizeof(struct netdev_rx_queue), GFP_KERNEL); - if (!rx) { - printk(KERN_ERR "alloc_netdev: Unable to allocate " - "rx queues.\n"); - goto free_tx; - } - - atomic_set(&rx->count, queue_count); - - /* - * Set a pointer to first element in the array which holds the - * reference count. - */ - for (i = 0; i < queue_count; i++) - rx[i].first = rx; -#endif - dev = PTR_ALIGN(p, NETDEV_ALIGN); dev->padded = (char *)dev - (char *)p; + dev->pcpu_refcnt = alloc_percpu(int); + if (!dev->pcpu_refcnt) + goto free_p; + if (dev_addr_init(dev)) - goto free_rx; + goto free_pcpu; dev_mc_init(dev); dev_uc_init(dev); dev_net_set(dev, &init_net); - dev->_tx = tx; dev->num_tx_queues = queue_count; dev->real_num_tx_queues = queue_count; #ifdef CONFIG_RPS - dev->_rx = rx; dev->num_rx_queues = queue_count; + dev->real_num_rx_queues = queue_count; #endif dev->gso_max_size = GSO_MAX_SIZE; - netdev_init_queues(dev); - INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list); dev->ethtool_ntuple_list.count = 0; INIT_LIST_HEAD(&dev->napi_list); @@ -5475,12 +5599,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, strcpy(dev->name, name); return dev; -free_rx: -#ifdef CONFIG_RPS - kfree(rx); -free_tx: -#endif - kfree(tx); +free_pcpu: + free_percpu(dev->pcpu_refcnt); free_p: kfree(p); return NULL; @@ -5503,6 +5623,8 @@ void free_netdev(struct net_device *dev) kfree(dev->_tx); + kfree(rcu_dereference_raw(dev->ingress_queue)); + /* Flush device addresses */ dev_addr_flush(dev); @@ -5512,6 +5634,9 @@ void free_netdev(struct net_device *dev) list_for_each_entry_safe(p, n, &dev->napi_list, dev_list) netif_napi_del(p); + free_percpu(dev->pcpu_refcnt); + dev->pcpu_refcnt = NULL; + /* Compatibility with error handling in drivers */ if (dev->reg_state == NETREG_UNINITIALIZED) { kfree((char *)dev - dev->padded); @@ -5666,6 +5791,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char /* Notify protocols, that we are about to destroy this device. They should clean all the things. + + Note that dev->reg_state stays at NETREG_REGISTERED. + This is wanted because this way 8021q and macvlan know + the device is just moving and can keep their slaves up. */ call_netdevice_notifiers(NETDEV_UNREGISTER, dev); call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev); diff --git a/net/core/dst.c b/net/core/dst.c index 6c41b1fac3db56a62f5e0f24f3cb76f34e978800..8abe628b79f173f96fc9e2372f442c91dacc2984 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -168,7 +168,7 @@ void *dst_alloc(struct dst_ops *ops) { struct dst_entry *dst; - if (ops->gc && atomic_read(&ops->entries) > ops->gc_thresh) { + if (ops->gc && dst_entries_get_fast(ops) > ops->gc_thresh) { if (ops->gc(ops)) return NULL; } @@ -183,7 +183,7 @@ void *dst_alloc(struct dst_ops *ops) #if RT_CACHE_DEBUG >= 2 atomic_inc(&dst_total); #endif - atomic_inc(&ops->entries); + dst_entries_add(ops, 1); return dst; } EXPORT_SYMBOL(dst_alloc); @@ -228,15 +228,15 @@ struct dst_entry *dst_destroy(struct dst_entry * dst) child = dst->child; dst->hh = NULL; - if (hh && atomic_dec_and_test(&hh->hh_refcnt)) - kfree(hh); + if (hh) + hh_cache_put(hh); if (neigh) { dst->neighbour = NULL; neigh_release(neigh); } - atomic_dec(&dst->ops->entries); + dst_entries_add(dst->ops, -1); if (dst->ops->destroy) dst->ops->destroy(dst); @@ -271,13 +271,40 @@ void dst_release(struct dst_entry *dst) if (dst) { int newrefcnt; - smp_mb__before_atomic_dec(); newrefcnt = atomic_dec_return(&dst->__refcnt); WARN_ON(newrefcnt < 0); + if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt) { + dst = dst_destroy(dst); + if (dst) + __dst_free(dst); + } } } EXPORT_SYMBOL(dst_release); +/** + * skb_dst_set_noref - sets skb dst, without a reference + * @skb: buffer + * @dst: dst entry + * + * Sets skb dst, assuming a reference was not taken on dst + * skb_dst_drop() should not dst_release() this dst + */ +void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst) +{ + WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); + /* If dst not in cache, we must take a reference, because + * dst_release() will destroy dst as soon as its refcount becomes zero + */ + if (unlikely(dst->flags & DST_NOCACHE)) { + dst_hold(dst); + skb_dst_set(skb, dst); + } else { + skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF; + } +} +EXPORT_SYMBOL(skb_dst_set_noref); + /* Dirty hack. We did it in 2.2 (in __dst_free), * we have _very_ good reasons not to repeat * this mistake in 2.3, but we have no choice diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 8451ab481095fc523c47fa01ccb11392b15dbc30..956a9f4971cbc2e7f81c4ab5d8c8a8b909d00bf1 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -19,6 +19,7 @@ #include #include #include +#include #include /* @@ -131,7 +132,8 @@ EXPORT_SYMBOL(ethtool_op_set_ufo); * NETIF_F_xxx values in include/linux/netdevice.h */ static const u32 flags_dup_features = - (ETH_FLAG_LRO | ETH_FLAG_NTUPLE | ETH_FLAG_RXHASH); + (ETH_FLAG_LRO | ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN | ETH_FLAG_NTUPLE | + ETH_FLAG_RXHASH); u32 ethtool_op_get_flags(struct net_device *dev) { @@ -205,18 +207,24 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo info; const struct ethtool_ops *ops = dev->ethtool_ops; - if (!ops->get_drvinfo) - return -EOPNOTSUPP; - memset(&info, 0, sizeof(info)); info.cmd = ETHTOOL_GDRVINFO; - ops->get_drvinfo(dev, &info); + if (ops && ops->get_drvinfo) { + ops->get_drvinfo(dev, &info); + } else if (dev->dev.parent && dev->dev.parent->driver) { + strlcpy(info.bus_info, dev_name(dev->dev.parent), + sizeof(info.bus_info)); + strlcpy(info.driver, dev->dev.parent->driver->name, + sizeof(info.driver)); + } else { + return -EOPNOTSUPP; + } /* * this method of obtaining string set info is deprecated; * Use ETHTOOL_GSSET_INFO instead. */ - if (ops->get_sset_count) { + if (ops && ops->get_sset_count) { int rc; rc = ops->get_sset_count(dev, ETH_SS_TEST); @@ -229,9 +237,9 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, if (rc >= 0) info.n_priv_flags = rc; } - if (ops->get_regs_len) + if (ops && ops->get_regs_len) info.regdump_len = ops->get_regs_len(dev); - if (ops->get_eeprom_len) + if (ops && ops->get_eeprom_len) info.eedump_len = ops->get_eeprom_len(dev); if (copy_to_user(useraddr, &info, sizeof(info))) @@ -479,6 +487,38 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, list->count++; } +/* + * ethtool does not (or did not) set masks for flow parameters that are + * not specified, so if both value and mask are 0 then this must be + * treated as equivalent to a mask with all bits set. Implement that + * here rather than in drivers. + */ +static void rx_ntuple_fix_masks(struct ethtool_rx_ntuple_flow_spec *fs) +{ + struct ethtool_tcpip4_spec *entry = &fs->h_u.tcp_ip4_spec; + struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec; + + if (fs->flow_type != TCP_V4_FLOW && + fs->flow_type != UDP_V4_FLOW && + fs->flow_type != SCTP_V4_FLOW) + return; + + if (!(entry->ip4src | mask->ip4src)) + mask->ip4src = htonl(0xffffffff); + if (!(entry->ip4dst | mask->ip4dst)) + mask->ip4dst = htonl(0xffffffff); + if (!(entry->psrc | mask->psrc)) + mask->psrc = htons(0xffff); + if (!(entry->pdst | mask->pdst)) + mask->pdst = htons(0xffff); + if (!(entry->tos | mask->tos)) + mask->tos = 0xff; + if (!(fs->vlan_tag | fs->vlan_tag_mask)) + fs->vlan_tag_mask = 0xffff; + if (!(fs->data | fs->data_mask)) + fs->data_mask = 0xffffffffffffffffULL; +} + static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr) { @@ -493,6 +533,8 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, if (copy_from_user(&cmd, useraddr, sizeof(cmd))) return -EFAULT; + rx_ntuple_fix_masks(&cmd.fs); + /* * Cache filter in dev struct for GET operation only if * the underlying driver doesn't have its own GET operation, and @@ -667,19 +709,19 @@ static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr) break; case IP_USER_FLOW: sprintf(p, "\tSrc IP addr: 0x%x\n", - fsc->fs.h_u.raw_ip4_spec.ip4src); + fsc->fs.h_u.usr_ip4_spec.ip4src); p += ETH_GSTRING_LEN; num_strings++; sprintf(p, "\tSrc IP mask: 0x%x\n", - fsc->fs.m_u.raw_ip4_spec.ip4src); + fsc->fs.m_u.usr_ip4_spec.ip4src); p += ETH_GSTRING_LEN; num_strings++; sprintf(p, "\tDest IP addr: 0x%x\n", - fsc->fs.h_u.raw_ip4_spec.ip4dst); + fsc->fs.h_u.usr_ip4_spec.ip4dst); p += ETH_GSTRING_LEN; num_strings++; sprintf(p, "\tDest IP mask: 0x%x\n", - fsc->fs.m_u.raw_ip4_spec.ip4dst); + fsc->fs.m_u.usr_ip4_spec.ip4dst); p += ETH_GSTRING_LEN; num_strings++; break; @@ -775,7 +817,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) if (regs.len > reglen) regs.len = reglen; - regbuf = kzalloc(reglen, GFP_USER); + regbuf = vmalloc(reglen); if (!regbuf) return -ENOMEM; @@ -790,7 +832,7 @@ static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) ret = 0; out: - kfree(regbuf); + vfree(regbuf); return ret; } @@ -1175,8 +1217,11 @@ static int ethtool_set_gro(struct net_device *dev, char __user *useraddr) return -EFAULT; if (edata.data) { - if (!dev->ethtool_ops->get_rx_csum || - !dev->ethtool_ops->get_rx_csum(dev)) + u32 rxcsum = dev->ethtool_ops->get_rx_csum ? + dev->ethtool_ops->get_rx_csum(dev) : + ethtool_op_get_rx_csum(dev); + + if (!rxcsum) return -EINVAL; dev->features |= NETIF_F_GRO; } else @@ -1402,14 +1447,22 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) if (!dev || !netif_device_present(dev)) return -ENODEV; - if (!dev->ethtool_ops) - return -EOPNOTSUPP; - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) return -EFAULT; + if (!dev->ethtool_ops) { + /* ETHTOOL_GDRVINFO does not require any driver support. + * It is also unprivileged and does not change anything, + * so we can take a shortcut to it. */ + if (ethcmd == ETHTOOL_GDRVINFO) + return ethtool_get_drvinfo(dev, useraddr); + else + return -EOPNOTSUPP; + } + /* Allow some commands to be done by anyone */ switch (ethcmd) { + case ETHTOOL_GSET: case ETHTOOL_GDRVINFO: case ETHTOOL_GMSGLVL: case ETHTOOL_GCOALESCE: diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 42e84e08a1becd4b64a65a74758bf4e13783a8ae..1bc3f253ba6c76efe7e8b97c78c2e6a72d771b23 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c @@ -144,7 +144,7 @@ fib_rules_register(const struct fib_rules_ops *tmpl, struct net *net) } EXPORT_SYMBOL_GPL(fib_rules_register); -void fib_rules_cleanup_ops(struct fib_rules_ops *ops) +static void fib_rules_cleanup_ops(struct fib_rules_ops *ops) { struct fib_rule *rule, *tmp; @@ -153,7 +153,6 @@ void fib_rules_cleanup_ops(struct fib_rules_ops *ops) fib_rule_put(rule); } } -EXPORT_SYMBOL_GPL(fib_rules_cleanup_ops); static void fib_rules_put_rcu(struct rcu_head *head) { @@ -182,7 +181,8 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, { int ret = 0; - if (rule->iifindex && (rule->iifindex != fl->iif)) + if (rule->iifindex && (rule->iifindex != fl->iif) && + !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF)) goto out; if (rule->oifindex && (rule->oifindex != fl->oif)) @@ -225,9 +225,12 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, err = ops->action(rule, fl, flags, arg); if (err != -EAGAIN) { - fib_rule_get(rule); - arg->rule = rule; - goto out; + if ((arg->flags & FIB_LOOKUP_NOREF) || + likely(atomic_inc_not_zero(&rule->refcnt))) { + arg->rule = rule; + goto out; + } + break; } } @@ -491,7 +494,6 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) } } - synchronize_rcu(); notify_rule_change(RTM_DELRULE, rule, ops, nlh, NETLINK_CB(skb).pid); fib_rule_put(rule); diff --git a/net/core/filter.c b/net/core/filter.c index 52b051f82a016e37c792efc8bc30dca3d71fd537..7adf50352918713af197b55283faf6b105087f4e 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -638,10 +638,9 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) return err; } - rcu_read_lock_bh(); - old_fp = rcu_dereference_bh(sk->sk_filter); + old_fp = rcu_dereference_protected(sk->sk_filter, + sock_owned_by_user(sk)); rcu_assign_pointer(sk->sk_filter, fp); - rcu_read_unlock_bh(); if (old_fp) sk_filter_delayed_uncharge(sk, old_fp); @@ -654,14 +653,13 @@ int sk_detach_filter(struct sock *sk) int ret = -ENOENT; struct sk_filter *filter; - rcu_read_lock_bh(); - filter = rcu_dereference_bh(sk->sk_filter); + filter = rcu_dereference_protected(sk->sk_filter, + sock_owned_by_user(sk)); if (filter) { rcu_assign_pointer(sk->sk_filter, NULL); sk_filter_delayed_uncharge(sk, filter); ret = 0; } - rcu_read_unlock_bh(); return ret; } EXPORT_SYMBOL_GPL(sk_detach_filter); diff --git a/net/core/flow.c b/net/core/flow.c index f67dcbfe54efa91cbc154c093f076540ded5c23f..127c8a7ffd61fbc350fafe503fe692622e16374e 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -53,8 +53,7 @@ struct flow_flush_info { struct flow_cache { u32 hash_shift; - unsigned long order; - struct flow_cache_percpu *percpu; + struct flow_cache_percpu __percpu *percpu; struct notifier_block hotcpu_notifier; int low_watermark; int high_watermark; @@ -64,7 +63,7 @@ struct flow_cache { atomic_t flow_cache_genid = ATOMIC_INIT(0); EXPORT_SYMBOL(flow_cache_genid); static struct flow_cache flow_cache_global; -static struct kmem_cache *flow_cachep; +static struct kmem_cache *flow_cachep __read_mostly; static DEFINE_SPINLOCK(flow_cache_gc_lock); static LIST_HEAD(flow_cache_gc_list); @@ -177,15 +176,11 @@ static u32 flow_hash_code(struct flow_cache *fc, { u32 *k = (u32 *) key; - return (jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd) - & (flow_cache_hash_size(fc) - 1)); + return jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd) + & (flow_cache_hash_size(fc) - 1); } -#if (BITS_PER_LONG == 64) -typedef u64 flow_compare_t; -#else -typedef u32 flow_compare_t; -#endif +typedef unsigned long flow_compare_t; /* I hear what you're saying, use memcmp. But memcmp cannot make * important assumptions that we can here, such as alignment and @@ -357,62 +352,73 @@ void flow_cache_flush(void) put_online_cpus(); } -static void __init flow_cache_cpu_prepare(struct flow_cache *fc, - struct flow_cache_percpu *fcp) +static int __cpuinit flow_cache_cpu_prepare(struct flow_cache *fc, int cpu) { - fcp->hash_table = (struct hlist_head *) - __get_free_pages(GFP_KERNEL|__GFP_ZERO, fc->order); - if (!fcp->hash_table) - panic("NET: failed to allocate flow cache order %lu\n", fc->order); + struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu); + size_t sz = sizeof(struct hlist_head) * flow_cache_hash_size(fc); - fcp->hash_rnd_recalc = 1; - fcp->hash_count = 0; - tasklet_init(&fcp->flush_tasklet, flow_cache_flush_tasklet, 0); + if (!fcp->hash_table) { + fcp->hash_table = kzalloc_node(sz, GFP_KERNEL, cpu_to_node(cpu)); + if (!fcp->hash_table) { + pr_err("NET: failed to allocate flow cache sz %zu\n", sz); + return -ENOMEM; + } + fcp->hash_rnd_recalc = 1; + fcp->hash_count = 0; + tasklet_init(&fcp->flush_tasklet, flow_cache_flush_tasklet, 0); + } + return 0; } -static int flow_cache_cpu(struct notifier_block *nfb, +static int __cpuinit flow_cache_cpu(struct notifier_block *nfb, unsigned long action, void *hcpu) { struct flow_cache *fc = container_of(nfb, struct flow_cache, hotcpu_notifier); - int cpu = (unsigned long) hcpu; + int res, cpu = (unsigned long) hcpu; struct flow_cache_percpu *fcp = per_cpu_ptr(fc->percpu, cpu); - if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) + switch (action) { + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: + res = flow_cache_cpu_prepare(fc, cpu); + if (res) + return notifier_from_errno(res); + break; + case CPU_DEAD: + case CPU_DEAD_FROZEN: __flow_cache_shrink(fc, fcp, 0); + break; + } return NOTIFY_OK; } -static int flow_cache_init(struct flow_cache *fc) +static int __init flow_cache_init(struct flow_cache *fc) { - unsigned long order; int i; fc->hash_shift = 10; fc->low_watermark = 2 * flow_cache_hash_size(fc); fc->high_watermark = 4 * flow_cache_hash_size(fc); - for (order = 0; - (PAGE_SIZE << order) < - (sizeof(struct hlist_head)*flow_cache_hash_size(fc)); - order++) - /* NOTHING */; - fc->order = order; fc->percpu = alloc_percpu(struct flow_cache_percpu); + if (!fc->percpu) + return -ENOMEM; - setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd, - (unsigned long) fc); - fc->rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; - add_timer(&fc->rnd_timer); - - for_each_possible_cpu(i) - flow_cache_cpu_prepare(fc, per_cpu_ptr(fc->percpu, i)); - + for_each_online_cpu(i) { + if (flow_cache_cpu_prepare(fc, i)) + return -ENOMEM; + } fc->hotcpu_notifier = (struct notifier_block){ .notifier_call = flow_cache_cpu, }; register_hotcpu_notifier(&fc->hotcpu_notifier); + setup_timer(&fc->rnd_timer, flow_cache_new_hashrnd, + (unsigned long) fc); + fc->rnd_timer.expires = jiffies + FLOW_HASH_RND_PERIOD; + add_timer(&fc->rnd_timer); + return 0; } diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index 6743146e4d6b49a61204395b49e4ded721de2703..7c2373321b74317c1c36918c20726cba10490768 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -274,9 +274,9 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats, while ((e = gen_find_node(bstats, rate_est))) { rb_erase(&e->node, &est_root); - write_lock_bh(&est_lock); + write_lock(&est_lock); e->bstats = NULL; - write_unlock_bh(&est_lock); + write_unlock(&est_lock); list_del_rcu(&e->list); call_rcu(&e->e_rcu, __gen_kill_estimator); diff --git a/net/core/iovec.c b/net/core/iovec.c index e6b133b77ccb5615d65bcdac0ecc01b759808c76..72aceb1fe4fae6c072b12e5acc4c97bc4ed73cf7 100644 --- a/net/core/iovec.c +++ b/net/core/iovec.c @@ -42,7 +42,9 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, if (m->msg_namelen) { if (mode == VERIFY_READ) { - err = move_addr_to_kernel(m->msg_name, m->msg_namelen, + void __user *namep; + namep = (void __user __force *) m->msg_name; + err = move_addr_to_kernel(namep, m->msg_namelen, address); if (err < 0) return err; @@ -53,7 +55,7 @@ long verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, } size = m->msg_iovlen * sizeof(struct iovec); - if (copy_from_user(iov, m->msg_iov, size)) + if (copy_from_user(iov, (void __user __force *) m->msg_iov, size)) return -EFAULT; m->msg_iov = iov; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index a4e0a7482c2bc878bdd6e0986ac45e0dc6659b3d..8cc8f9a79db91fe20a86ad46b0199c3e98ebe8ac 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -122,7 +122,7 @@ static void neigh_cleanup_and_release(struct neighbour *neigh) unsigned long neigh_rand_reach_time(unsigned long base) { - return (base ? (net_random() % base) + (base >> 1) : 0); + return base ? (net_random() % base) + (base >> 1) : 0; } EXPORT_SYMBOL(neigh_rand_reach_time); @@ -131,15 +131,20 @@ static int neigh_forced_gc(struct neigh_table *tbl) { int shrunk = 0; int i; + struct neigh_hash_table *nht; NEIGH_CACHE_STAT_INC(tbl, forced_gc_runs); write_lock_bh(&tbl->lock); - for (i = 0; i <= tbl->hash_mask; i++) { - struct neighbour *n, **np; + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); + for (i = 0; i <= nht->hash_mask; i++) { + struct neighbour *n; + struct neighbour __rcu **np; - np = &tbl->hash_buckets[i]; - while ((n = *np) != NULL) { + np = &nht->hash_buckets[i]; + while ((n = rcu_dereference_protected(*np, + lockdep_is_held(&tbl->lock))) != NULL) { /* Neighbour record may be discarded if: * - nobody refers to it. * - it is not permanent @@ -147,7 +152,9 @@ static int neigh_forced_gc(struct neigh_table *tbl) write_lock(&n->lock); if (atomic_read(&n->refcnt) == 1 && !(n->nud_state & NUD_PERMANENT)) { - *np = n->next; + rcu_assign_pointer(*np, + rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock))); n->dead = 1; shrunk = 1; write_unlock(&n->lock); @@ -199,16 +206,24 @@ static void pneigh_queue_purge(struct sk_buff_head *list) static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) { int i; + struct neigh_hash_table *nht; - for (i = 0; i <= tbl->hash_mask; i++) { - struct neighbour *n, **np = &tbl->hash_buckets[i]; + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); - while ((n = *np) != NULL) { + for (i = 0; i <= nht->hash_mask; i++) { + struct neighbour *n; + struct neighbour __rcu **np = &nht->hash_buckets[i]; + + while ((n = rcu_dereference_protected(*np, + lockdep_is_held(&tbl->lock))) != NULL) { if (dev && n->dev != dev) { np = &n->next; continue; } - *np = n->next; + rcu_assign_pointer(*np, + rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock))); write_lock(&n->lock); neigh_del_timer(n); n->dead = 1; @@ -279,6 +294,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl) skb_queue_head_init(&n->arp_queue); rwlock_init(&n->lock); + seqlock_init(&n->ha_lock); n->updated = n->used = now; n->nud_state = NUD_NONE; n->output = neigh_blackhole; @@ -297,64 +313,86 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl) goto out; } -static struct neighbour **neigh_hash_alloc(unsigned int entries) +static struct neigh_hash_table *neigh_hash_alloc(unsigned int entries) { - unsigned long size = entries * sizeof(struct neighbour *); - struct neighbour **ret; + size_t size = entries * sizeof(struct neighbour *); + struct neigh_hash_table *ret; + struct neighbour **buckets; - if (size <= PAGE_SIZE) { - ret = kzalloc(size, GFP_ATOMIC); - } else { - ret = (struct neighbour **) - __get_free_pages(GFP_ATOMIC|__GFP_ZERO, get_order(size)); + ret = kmalloc(sizeof(*ret), GFP_ATOMIC); + if (!ret) + return NULL; + if (size <= PAGE_SIZE) + buckets = kzalloc(size, GFP_ATOMIC); + else + buckets = (struct neighbour **) + __get_free_pages(GFP_ATOMIC | __GFP_ZERO, + get_order(size)); + if (!buckets) { + kfree(ret); + return NULL; } + rcu_assign_pointer(ret->hash_buckets, buckets); + ret->hash_mask = entries - 1; + get_random_bytes(&ret->hash_rnd, sizeof(ret->hash_rnd)); return ret; } -static void neigh_hash_free(struct neighbour **hash, unsigned int entries) +static void neigh_hash_free_rcu(struct rcu_head *head) { - unsigned long size = entries * sizeof(struct neighbour *); + struct neigh_hash_table *nht = container_of(head, + struct neigh_hash_table, + rcu); + size_t size = (nht->hash_mask + 1) * sizeof(struct neighbour *); + struct neighbour **buckets = nht->hash_buckets; if (size <= PAGE_SIZE) - kfree(hash); + kfree(buckets); else - free_pages((unsigned long)hash, get_order(size)); + free_pages((unsigned long)buckets, get_order(size)); + kfree(nht); } -static void neigh_hash_grow(struct neigh_table *tbl, unsigned long new_entries) +static struct neigh_hash_table *neigh_hash_grow(struct neigh_table *tbl, + unsigned long new_entries) { - struct neighbour **new_hash, **old_hash; - unsigned int i, new_hash_mask, old_entries; + unsigned int i, hash; + struct neigh_hash_table *new_nht, *old_nht; NEIGH_CACHE_STAT_INC(tbl, hash_grows); BUG_ON(!is_power_of_2(new_entries)); - new_hash = neigh_hash_alloc(new_entries); - if (!new_hash) - return; - - old_entries = tbl->hash_mask + 1; - new_hash_mask = new_entries - 1; - old_hash = tbl->hash_buckets; + old_nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); + new_nht = neigh_hash_alloc(new_entries); + if (!new_nht) + return old_nht; - get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd)); - for (i = 0; i < old_entries; i++) { + for (i = 0; i <= old_nht->hash_mask; i++) { struct neighbour *n, *next; - for (n = old_hash[i]; n; n = next) { - unsigned int hash_val = tbl->hash(n->primary_key, n->dev); - - hash_val &= new_hash_mask; - next = n->next; - - n->next = new_hash[hash_val]; - new_hash[hash_val] = n; + for (n = rcu_dereference_protected(old_nht->hash_buckets[i], + lockdep_is_held(&tbl->lock)); + n != NULL; + n = next) { + hash = tbl->hash(n->primary_key, n->dev, + new_nht->hash_rnd); + + hash &= new_nht->hash_mask; + next = rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock)); + + rcu_assign_pointer(n->next, + rcu_dereference_protected( + new_nht->hash_buckets[hash], + lockdep_is_held(&tbl->lock))); + rcu_assign_pointer(new_nht->hash_buckets[hash], n); } } - tbl->hash_buckets = new_hash; - tbl->hash_mask = new_hash_mask; - neigh_hash_free(old_hash, old_entries); + rcu_assign_pointer(tbl->nht, new_nht); + call_rcu(&old_nht->rcu, neigh_hash_free_rcu); + return new_nht; } struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, @@ -363,19 +401,26 @@ struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, struct neighbour *n; int key_len = tbl->key_len; u32 hash_val; + struct neigh_hash_table *nht; NEIGH_CACHE_STAT_INC(tbl, lookups); - read_lock_bh(&tbl->lock); - hash_val = tbl->hash(pkey, dev); - for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; + + for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); + n != NULL; + n = rcu_dereference_bh(n->next)) { if (dev == n->dev && !memcmp(n->primary_key, pkey, key_len)) { - neigh_hold(n); + if (!atomic_inc_not_zero(&n->refcnt)) + n = NULL; NEIGH_CACHE_STAT_INC(tbl, hits); break; } } - read_unlock_bh(&tbl->lock); + + rcu_read_unlock_bh(); return n; } EXPORT_SYMBOL(neigh_lookup); @@ -386,20 +431,27 @@ struct neighbour *neigh_lookup_nodev(struct neigh_table *tbl, struct net *net, struct neighbour *n; int key_len = tbl->key_len; u32 hash_val; + struct neigh_hash_table *nht; NEIGH_CACHE_STAT_INC(tbl, lookups); - read_lock_bh(&tbl->lock); - hash_val = tbl->hash(pkey, NULL); - for (n = tbl->hash_buckets[hash_val & tbl->hash_mask]; n; n = n->next) { + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + hash_val = tbl->hash(pkey, NULL, nht->hash_rnd) & nht->hash_mask; + + for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); + n != NULL; + n = rcu_dereference_bh(n->next)) { if (!memcmp(n->primary_key, pkey, key_len) && net_eq(dev_net(n->dev), net)) { - neigh_hold(n); + if (!atomic_inc_not_zero(&n->refcnt)) + n = NULL; NEIGH_CACHE_STAT_INC(tbl, hits); break; } } - read_unlock_bh(&tbl->lock); + + rcu_read_unlock_bh(); return n; } EXPORT_SYMBOL(neigh_lookup_nodev); @@ -411,6 +463,7 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, int key_len = tbl->key_len; int error; struct neighbour *n1, *rc, *n = neigh_alloc(tbl); + struct neigh_hash_table *nht; if (!n) { rc = ERR_PTR(-ENOBUFS); @@ -437,18 +490,24 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, n->confirmed = jiffies - (n->parms->base_reachable_time << 1); write_lock_bh(&tbl->lock); + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); - if (atomic_read(&tbl->entries) > (tbl->hash_mask + 1)) - neigh_hash_grow(tbl, (tbl->hash_mask + 1) << 1); + if (atomic_read(&tbl->entries) > (nht->hash_mask + 1)) + nht = neigh_hash_grow(tbl, (nht->hash_mask + 1) << 1); - hash_val = tbl->hash(pkey, dev) & tbl->hash_mask; + hash_val = tbl->hash(pkey, dev, nht->hash_rnd) & nht->hash_mask; if (n->parms->dead) { rc = ERR_PTR(-EINVAL); goto out_tbl_unlock; } - for (n1 = tbl->hash_buckets[hash_val]; n1; n1 = n1->next) { + for (n1 = rcu_dereference_protected(nht->hash_buckets[hash_val], + lockdep_is_held(&tbl->lock)); + n1 != NULL; + n1 = rcu_dereference_protected(n1->next, + lockdep_is_held(&tbl->lock))) { if (dev == n1->dev && !memcmp(n1->primary_key, pkey, key_len)) { neigh_hold(n1); rc = n1; @@ -456,10 +515,12 @@ struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, } } - n->next = tbl->hash_buckets[hash_val]; - tbl->hash_buckets[hash_val] = n; n->dead = 0; neigh_hold(n); + rcu_assign_pointer(n->next, + rcu_dereference_protected(nht->hash_buckets[hash_val], + lockdep_is_held(&tbl->lock))); + rcu_assign_pointer(nht->hash_buckets[hash_val], n); write_unlock_bh(&tbl->lock); NEIGH_PRINTK2("neigh %p is created.\n", n); rc = n; @@ -616,6 +677,12 @@ static inline void neigh_parms_put(struct neigh_parms *parms) neigh_parms_destroy(parms); } +static void neigh_destroy_rcu(struct rcu_head *head) +{ + struct neighbour *neigh = container_of(head, struct neighbour, rcu); + + kmem_cache_free(neigh->tbl->kmem_cachep, neigh); +} /* * neighbour must already be out of the table; * @@ -643,8 +710,7 @@ void neigh_destroy(struct neighbour *neigh) write_seqlock_bh(&hh->hh_lock); hh->hh_output = neigh_blackhole; write_sequnlock_bh(&hh->hh_lock); - if (atomic_dec_and_test(&hh->hh_refcnt)) - kfree(hh); + hh_cache_put(hh); } skb_queue_purge(&neigh->arp_queue); @@ -655,7 +721,7 @@ void neigh_destroy(struct neighbour *neigh) NEIGH_PRINTK2("neigh %p is destroyed.\n", neigh); atomic_dec(&neigh->tbl->entries); - kmem_cache_free(neigh->tbl->kmem_cachep, neigh); + call_rcu(&neigh->rcu, neigh_destroy_rcu); } EXPORT_SYMBOL(neigh_destroy); @@ -696,12 +762,16 @@ static void neigh_connect(struct neighbour *neigh) static void neigh_periodic_work(struct work_struct *work) { struct neigh_table *tbl = container_of(work, struct neigh_table, gc_work.work); - struct neighbour *n, **np; + struct neighbour *n; + struct neighbour __rcu **np; unsigned int i; + struct neigh_hash_table *nht; NEIGH_CACHE_STAT_INC(tbl, periodic_gc_runs); write_lock_bh(&tbl->lock); + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); /* * periodically recompute ReachableTime from random function @@ -715,10 +785,11 @@ static void neigh_periodic_work(struct work_struct *work) neigh_rand_reach_time(p->base_reachable_time); } - for (i = 0 ; i <= tbl->hash_mask; i++) { - np = &tbl->hash_buckets[i]; + for (i = 0 ; i <= nht->hash_mask; i++) { + np = &nht->hash_buckets[i]; - while ((n = *np) != NULL) { + while ((n = rcu_dereference_protected(*np, + lockdep_is_held(&tbl->lock))) != NULL) { unsigned int state; write_lock(&n->lock); @@ -766,9 +837,9 @@ static void neigh_periodic_work(struct work_struct *work) static __inline__ int neigh_max_probes(struct neighbour *n) { struct neigh_parms *p = n->parms; - return (n->nud_state & NUD_PROBE ? + return (n->nud_state & NUD_PROBE) ? p->ucast_probes : - p->ucast_probes + p->app_probes + p->mcast_probes); + p->ucast_probes + p->app_probes + p->mcast_probes; } static void neigh_invalidate(struct neighbour *neigh) @@ -945,7 +1016,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) } EXPORT_SYMBOL(__neigh_event_send); -static void neigh_update_hhs(struct neighbour *neigh) +static void neigh_update_hhs(const struct neighbour *neigh) { struct hh_cache *hh; void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *) @@ -1081,7 +1152,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, } if (lladdr != neigh->ha) { + write_seqlock(&neigh->ha_lock); memcpy(&neigh->ha, lladdr, dev->addr_len); + write_sequnlock(&neigh->ha_lock); neigh_update_hhs(neigh); if (!(new & NUD_CONNECTED)) neigh->confirmed = jiffies - @@ -1139,44 +1212,73 @@ struct neighbour *neigh_event_ns(struct neigh_table *tbl, } EXPORT_SYMBOL(neigh_event_ns); +static inline bool neigh_hh_lookup(struct neighbour *n, struct dst_entry *dst, + __be16 protocol) +{ + struct hh_cache *hh; + + smp_rmb(); /* paired with smp_wmb() in neigh_hh_init() */ + for (hh = n->hh; hh; hh = hh->hh_next) { + if (hh->hh_type == protocol) { + atomic_inc(&hh->hh_refcnt); + if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) + hh_cache_put(hh); + return true; + } + } + return false; +} + +/* called with read_lock_bh(&n->lock); */ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst, __be16 protocol) { struct hh_cache *hh; struct net_device *dev = dst->dev; - for (hh = n->hh; hh; hh = hh->hh_next) - if (hh->hh_type == protocol) - break; + if (likely(neigh_hh_lookup(n, dst, protocol))) + return; - if (!hh && (hh = kzalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) { - seqlock_init(&hh->hh_lock); - hh->hh_type = protocol; - atomic_set(&hh->hh_refcnt, 0); - hh->hh_next = NULL; + /* slow path */ + hh = kzalloc(sizeof(*hh), GFP_ATOMIC); + if (!hh) + return; - if (dev->header_ops->cache(n, hh)) { - kfree(hh); - hh = NULL; - } else { - atomic_inc(&hh->hh_refcnt); - hh->hh_next = n->hh; - n->hh = hh; - if (n->nud_state & NUD_CONNECTED) - hh->hh_output = n->ops->hh_output; - else - hh->hh_output = n->ops->output; - } + seqlock_init(&hh->hh_lock); + hh->hh_type = protocol; + atomic_set(&hh->hh_refcnt, 2); + + if (dev->header_ops->cache(n, hh)) { + kfree(hh); + return; } - if (hh) { - atomic_inc(&hh->hh_refcnt); - dst->hh = hh; + + write_lock_bh(&n->lock); + + /* must check if another thread already did the insert */ + if (neigh_hh_lookup(n, dst, protocol)) { + kfree(hh); + goto end; } + + if (n->nud_state & NUD_CONNECTED) + hh->hh_output = n->ops->hh_output; + else + hh->hh_output = n->ops->output; + + hh->hh_next = n->hh; + smp_wmb(); /* paired with smp_rmb() in neigh_hh_lookup() */ + n->hh = hh; + + if (unlikely(cmpxchg(&dst->hh, NULL, hh) != NULL)) + hh_cache_put(hh); +end: + write_unlock_bh(&n->lock); } /* This function can be used in contexts, where only old dev_queue_xmit - worked, f.e. if you want to override normal output path (eql, shaper), - but resolution is not made yet. + * worked, f.e. if you want to override normal output path (eql, shaper), + * but resolution is not made yet. */ int neigh_compat_output(struct sk_buff *skb) @@ -1210,19 +1312,19 @@ int neigh_resolve_output(struct sk_buff *skb) if (!neigh_event_send(neigh, skb)) { int err; struct net_device *dev = neigh->dev; - if (dev->header_ops->cache && !dst->hh) { - write_lock_bh(&neigh->lock); - if (!dst->hh) - neigh_hh_init(neigh, dst, dst->ops->protocol); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); - write_unlock_bh(&neigh->lock); - } else { - read_lock_bh(&neigh->lock); + unsigned int seq; + + if (dev->header_ops->cache && + !dst->hh && + !(dst->flags & DST_NOCACHE)) + neigh_hh_init(neigh, dst, dst->ops->protocol); + + do { + seq = read_seqbegin(&neigh->ha_lock); err = dev_hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, NULL, skb->len); - read_unlock_bh(&neigh->lock); - } + } while (read_seqretry(&neigh->ha_lock, seq)); + if (err >= 0) rc = neigh->ops->queue_xmit(skb); else @@ -1248,13 +1350,16 @@ int neigh_connected_output(struct sk_buff *skb) struct dst_entry *dst = skb_dst(skb); struct neighbour *neigh = dst->neighbour; struct net_device *dev = neigh->dev; + unsigned int seq; __skb_pull(skb, skb_network_offset(skb)); - read_lock_bh(&neigh->lock); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - neigh->ha, NULL, skb->len); - read_unlock_bh(&neigh->lock); + do { + seq = read_seqbegin(&neigh->ha_lock); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), + neigh->ha, NULL, skb->len); + } while (read_seqretry(&neigh->ha_lock, seq)); + if (err >= 0) err = neigh->ops->queue_xmit(skb); else { @@ -1436,17 +1541,14 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl) panic("cannot create neighbour proc dir entry"); #endif - tbl->hash_mask = 1; - tbl->hash_buckets = neigh_hash_alloc(tbl->hash_mask + 1); + tbl->nht = neigh_hash_alloc(8); phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *); tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL); - if (!tbl->hash_buckets || !tbl->phash_buckets) + if (!tbl->nht || !tbl->phash_buckets) panic("cannot allocate neighbour cache hashes"); - get_random_bytes(&tbl->hash_rnd, sizeof(tbl->hash_rnd)); - rwlock_init(&tbl->lock); INIT_DELAYED_WORK_DEFERRABLE(&tbl->gc_work, neigh_periodic_work); schedule_delayed_work(&tbl->gc_work, tbl->parms.reachable_time); @@ -1486,8 +1588,7 @@ int neigh_table_clear(struct neigh_table *tbl) struct neigh_table **tp; /* It is not clean... Fix it to unload IPv6 module safely */ - cancel_delayed_work(&tbl->gc_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&tbl->gc_work); del_timer_sync(&tbl->proxy_timer); pneigh_queue_purge(&tbl->proxy_queue); neigh_ifdown(tbl, NULL); @@ -1502,8 +1603,8 @@ int neigh_table_clear(struct neigh_table *tbl) } write_unlock(&neigh_tbl_lock); - neigh_hash_free(tbl->hash_buckets, tbl->hash_mask + 1); - tbl->hash_buckets = NULL; + call_rcu(&tbl->nht->rcu, neigh_hash_free_rcu); + tbl->nht = NULL; kfree(tbl->phash_buckets); tbl->phash_buckets = NULL; @@ -1529,6 +1630,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct net_device *dev = NULL; int err = -EINVAL; + ASSERT_RTNL(); if (nlmsg_len(nlh) < sizeof(*ndm)) goto out; @@ -1538,7 +1640,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ndm = nlmsg_data(nlh); if (ndm->ndm_ifindex) { - dev = dev_get_by_index(net, ndm->ndm_ifindex); + dev = __dev_get_by_index(net, ndm->ndm_ifindex); if (dev == NULL) { err = -ENODEV; goto out; @@ -1554,34 +1656,31 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) read_unlock(&neigh_tbl_lock); if (nla_len(dst_attr) < tbl->key_len) - goto out_dev_put; + goto out; if (ndm->ndm_flags & NTF_PROXY) { err = pneigh_delete(tbl, net, nla_data(dst_attr), dev); - goto out_dev_put; + goto out; } if (dev == NULL) - goto out_dev_put; + goto out; neigh = neigh_lookup(tbl, nla_data(dst_attr), dev); if (neigh == NULL) { err = -ENOENT; - goto out_dev_put; + goto out; } err = neigh_update(neigh, NULL, NUD_FAILED, NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN); neigh_release(neigh); - goto out_dev_put; + goto out; } read_unlock(&neigh_tbl_lock); err = -EAFNOSUPPORT; -out_dev_put: - if (dev) - dev_put(dev); out: return err; } @@ -1595,6 +1694,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) struct net_device *dev = NULL; int err; + ASSERT_RTNL(); err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); if (err < 0) goto out; @@ -1605,14 +1705,14 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) ndm = nlmsg_data(nlh); if (ndm->ndm_ifindex) { - dev = dev_get_by_index(net, ndm->ndm_ifindex); + dev = __dev_get_by_index(net, ndm->ndm_ifindex); if (dev == NULL) { err = -ENODEV; goto out; } if (tb[NDA_LLADDR] && nla_len(tb[NDA_LLADDR]) < dev->addr_len) - goto out_dev_put; + goto out; } read_lock(&neigh_tbl_lock); @@ -1626,7 +1726,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) read_unlock(&neigh_tbl_lock); if (nla_len(tb[NDA_DST]) < tbl->key_len) - goto out_dev_put; + goto out; dst = nla_data(tb[NDA_DST]); lladdr = tb[NDA_LLADDR] ? nla_data(tb[NDA_LLADDR]) : NULL; @@ -1639,29 +1739,29 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) pn->flags = ndm->ndm_flags; err = 0; } - goto out_dev_put; + goto out; } if (dev == NULL) - goto out_dev_put; + goto out; neigh = neigh_lookup(tbl, dst, dev); if (neigh == NULL) { if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { err = -ENOENT; - goto out_dev_put; + goto out; } neigh = __neigh_lookup_errno(tbl, dst, dev); if (IS_ERR(neigh)) { err = PTR_ERR(neigh); - goto out_dev_put; + goto out; } } else { if (nlh->nlmsg_flags & NLM_F_EXCL) { err = -EEXIST; neigh_release(neigh); - goto out_dev_put; + goto out; } if (!(nlh->nlmsg_flags & NLM_F_REPLACE)) @@ -1674,15 +1774,11 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) } else err = neigh_update(neigh, lladdr, ndm->ndm_state, flags); neigh_release(neigh); - goto out_dev_put; + goto out; } read_unlock(&neigh_tbl_lock); err = -EAFNOSUPPORT; - -out_dev_put: - if (dev) - dev_put(dev); out: return err; } @@ -1748,18 +1844,22 @@ static int neightbl_fill_info(struct sk_buff *skb, struct neigh_table *tbl, unsigned long now = jiffies; unsigned int flush_delta = now - tbl->last_flush; unsigned int rand_delta = now - tbl->last_rand; - + struct neigh_hash_table *nht; struct ndt_config ndc = { .ndtc_key_len = tbl->key_len, .ndtc_entry_size = tbl->entry_size, .ndtc_entries = atomic_read(&tbl->entries), .ndtc_last_flush = jiffies_to_msecs(flush_delta), .ndtc_last_rand = jiffies_to_msecs(rand_delta), - .ndtc_hash_rnd = tbl->hash_rnd, - .ndtc_hash_mask = tbl->hash_mask, .ndtc_proxy_qlen = tbl->proxy_queue.qlen, }; + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + ndc.ndtc_hash_rnd = nht->hash_rnd; + ndc.ndtc_hash_mask = nht->hash_mask; + rcu_read_unlock_bh(); + NLA_PUT(skb, NDTA_CONFIG, sizeof(ndc), &ndc); } @@ -2056,10 +2156,14 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *neigh, read_lock_bh(&neigh->lock); ndm->ndm_state = neigh->nud_state; - if ((neigh->nud_state & NUD_VALID) && - nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, neigh->ha) < 0) { - read_unlock_bh(&neigh->lock); - goto nla_put_failure; + if (neigh->nud_state & NUD_VALID) { + char haddr[MAX_ADDR_LEN]; + + neigh_ha_snapshot(haddr, neigh, neigh->dev); + if (nla_put(skb, NDA_LLADDR, neigh->dev->addr_len, haddr) < 0) { + read_unlock_bh(&neigh->lock); + goto nla_put_failure; + } } ci.ndm_used = jiffies_to_clock_t(now - neigh->used); @@ -2087,18 +2191,23 @@ static void neigh_update_notify(struct neighbour *neigh) static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, struct netlink_callback *cb) { - struct net * net = sock_net(skb->sk); + struct net *net = sock_net(skb->sk); struct neighbour *n; int rc, h, s_h = cb->args[1]; int idx, s_idx = idx = cb->args[2]; + struct neigh_hash_table *nht; - read_lock_bh(&tbl->lock); - for (h = 0; h <= tbl->hash_mask; h++) { + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + + for (h = 0; h <= nht->hash_mask; h++) { if (h < s_h) continue; if (h > s_h) s_idx = 0; - for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) { + for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0; + n != NULL; + n = rcu_dereference_bh(n->next)) { if (!net_eq(dev_net(n->dev), net)) continue; if (idx < s_idx) @@ -2107,17 +2216,16 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb, cb->nlh->nlmsg_seq, RTM_NEWNEIGH, NLM_F_MULTI) <= 0) { - read_unlock_bh(&tbl->lock); rc = -1; goto out; } - next: +next: idx++; } } - read_unlock_bh(&tbl->lock); rc = skb->len; out: + rcu_read_unlock_bh(); cb->args[1] = h; cb->args[2] = idx; return rc; @@ -2150,15 +2258,22 @@ static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb) void neigh_for_each(struct neigh_table *tbl, void (*cb)(struct neighbour *, void *), void *cookie) { int chain; + struct neigh_hash_table *nht; - read_lock_bh(&tbl->lock); - for (chain = 0; chain <= tbl->hash_mask; chain++) { + rcu_read_lock_bh(); + nht = rcu_dereference_bh(tbl->nht); + + read_lock(&tbl->lock); /* avoid resizes */ + for (chain = 0; chain <= nht->hash_mask; chain++) { struct neighbour *n; - for (n = tbl->hash_buckets[chain]; n; n = n->next) + for (n = rcu_dereference_bh(nht->hash_buckets[chain]); + n != NULL; + n = rcu_dereference_bh(n->next)) cb(n, cookie); } - read_unlock_bh(&tbl->lock); + read_unlock(&tbl->lock); + rcu_read_unlock_bh(); } EXPORT_SYMBOL(neigh_for_each); @@ -2167,18 +2282,25 @@ void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct neighbour *)) { int chain; + struct neigh_hash_table *nht; - for (chain = 0; chain <= tbl->hash_mask; chain++) { - struct neighbour *n, **np; + nht = rcu_dereference_protected(tbl->nht, + lockdep_is_held(&tbl->lock)); + for (chain = 0; chain <= nht->hash_mask; chain++) { + struct neighbour *n; + struct neighbour __rcu **np; - np = &tbl->hash_buckets[chain]; - while ((n = *np) != NULL) { + np = &nht->hash_buckets[chain]; + while ((n = rcu_dereference_protected(*np, + lockdep_is_held(&tbl->lock))) != NULL) { int release; write_lock(&n->lock); release = cb(n); if (release) { - *np = n->next; + rcu_assign_pointer(*np, + rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock))); n->dead = 1; } else np = &n->next; @@ -2196,13 +2318,13 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) { struct neigh_seq_state *state = seq->private; struct net *net = seq_file_net(seq); - struct neigh_table *tbl = state->tbl; + struct neigh_hash_table *nht = state->nht; struct neighbour *n = NULL; int bucket = state->bucket; state->flags &= ~NEIGH_SEQ_IS_PNEIGH; - for (bucket = 0; bucket <= tbl->hash_mask; bucket++) { - n = tbl->hash_buckets[bucket]; + for (bucket = 0; bucket <= nht->hash_mask; bucket++) { + n = rcu_dereference_bh(nht->hash_buckets[bucket]); while (n) { if (!net_eq(dev_net(n->dev), net)) @@ -2219,8 +2341,8 @@ static struct neighbour *neigh_get_first(struct seq_file *seq) break; if (n->nud_state & ~NUD_NOARP) break; - next: - n = n->next; +next: + n = rcu_dereference_bh(n->next); } if (n) @@ -2237,14 +2359,14 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, { struct neigh_seq_state *state = seq->private; struct net *net = seq_file_net(seq); - struct neigh_table *tbl = state->tbl; + struct neigh_hash_table *nht = state->nht; if (state->neigh_sub_iter) { void *v = state->neigh_sub_iter(state, n, pos); if (v) return n; } - n = n->next; + n = rcu_dereference_bh(n->next); while (1) { while (n) { @@ -2261,17 +2383,17 @@ static struct neighbour *neigh_get_next(struct seq_file *seq, if (n->nud_state & ~NUD_NOARP) break; - next: - n = n->next; +next: + n = rcu_dereference_bh(n->next); } if (n) break; - if (++state->bucket > tbl->hash_mask) + if (++state->bucket > nht->hash_mask) break; - n = tbl->hash_buckets[state->bucket]; + n = rcu_dereference_bh(nht->hash_buckets[state->bucket]); } if (n && pos) @@ -2369,7 +2491,7 @@ static void *neigh_get_idx_any(struct seq_file *seq, loff_t *pos) } void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags) - __acquires(tbl->lock) + __acquires(rcu_bh) { struct neigh_seq_state *state = seq->private; @@ -2377,7 +2499,8 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl state->bucket = 0; state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH); - read_lock_bh(&tbl->lock); + rcu_read_lock_bh(); + state->nht = rcu_dereference_bh(tbl->nht); return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN; } @@ -2411,12 +2534,9 @@ void *neigh_seq_next(struct seq_file *seq, void *v, loff_t *pos) EXPORT_SYMBOL(neigh_seq_next); void neigh_seq_stop(struct seq_file *seq, void *v) - __releases(tbl->lock) + __releases(rcu_bh) { - struct neigh_seq_state *state = seq->private; - struct neigh_table *tbl = state->tbl; - - read_unlock_bh(&tbl->lock); + rcu_read_unlock_bh(); } EXPORT_SYMBOL(neigh_seq_stop); diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index af4dfbadf2a09ea496653990ae8e1da823a059e1..b143173e3eb2bd9259e1c0122800848146b4c136 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -515,7 +515,7 @@ static ssize_t rx_queue_attr_store(struct kobject *kobj, struct attribute *attr, return attribute->store(queue, attribute, buf, count); } -static struct sysfs_ops rx_queue_sysfs_ops = { +static const struct sysfs_ops rx_queue_sysfs_ops = { .show = rx_queue_attr_show, .store = rx_queue_attr_store, }; @@ -726,6 +726,7 @@ static struct kobj_type rx_queue_ktype = { static int rx_queue_add_kobject(struct net_device *net, int index) { struct netdev_rx_queue *queue = net->_rx + index; + struct netdev_rx_queue *first = queue->first; struct kobject *kobj = &queue->kobj; int error = 0; @@ -738,38 +739,43 @@ static int rx_queue_add_kobject(struct net_device *net, int index) } kobject_uevent(kobj, KOBJ_ADD); + atomic_inc(&first->count); return error; } -static int rx_queue_register_kobjects(struct net_device *net) +int +net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num) { int i; int error = 0; - net->queues_kset = kset_create_and_add("queues", - NULL, &net->dev.kobj); - if (!net->queues_kset) - return -ENOMEM; - for (i = 0; i < net->num_rx_queues; i++) { + for (i = old_num; i < new_num; i++) { error = rx_queue_add_kobject(net, i); - if (error) + if (error) { + new_num = old_num; break; + } } - if (error) - while (--i >= 0) - kobject_put(&net->_rx[i].kobj); + while (--i >= new_num) + kobject_put(&net->_rx[i].kobj); return error; } -static void rx_queue_remove_kobjects(struct net_device *net) +static int rx_queue_register_kobjects(struct net_device *net) { - int i; + net->queues_kset = kset_create_and_add("queues", + NULL, &net->dev.kobj); + if (!net->queues_kset) + return -ENOMEM; + return net_rx_queue_update_kobjects(net, 0, net->real_num_rx_queues); +} - for (i = 0; i < net->num_rx_queues; i++) - kobject_put(&net->_rx[i].kobj); +static void rx_queue_remove_kobjects(struct net_device *net) +{ + net_rx_queue_update_kobjects(net, net->real_num_rx_queues, 0); kset_unregister(net->queues_kset); } #endif /* CONFIG_RPS */ @@ -789,12 +795,13 @@ static const void *net_netlink_ns(struct sock *sk) return sock_net(sk); } -static struct kobj_ns_type_operations net_ns_type_operations = { +struct kobj_ns_type_operations net_ns_type_operations = { .type = KOBJ_NS_TYPE_NET, .current_ns = net_current_ns, .netlink_ns = net_netlink_ns, .initial_ns = net_initial_ns, }; +EXPORT_SYMBOL_GPL(net_ns_type_operations); static void net_kobj_ns_exit(struct net *net) { diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h index 805555e8b18700de21fd0d28cb2125a228899abd..778e1571548d6aac4e931b96e6a3b2363b8baca5 100644 --- a/net/core/net-sysfs.h +++ b/net/core/net-sysfs.h @@ -4,4 +4,8 @@ int netdev_kobject_init(void); int netdev_register_kobject(struct net_device *); void netdev_unregister_kobject(struct net_device *); +#ifdef CONFIG_RPS +int net_rx_queue_update_kobjects(struct net_device *, int old_num, int new_num); +#endif + #endif diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 537e01afd81baf1e9bc7269e0c97ca3fb3844ffe..4e98ffac3af0259bda8cbadfb9609fa6b57405a8 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -288,11 +288,11 @@ static int netpoll_owner_active(struct net_device *dev) return 0; } -void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) +void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, + struct net_device *dev) { int status = NETDEV_TX_BUSY; unsigned long tries; - struct net_device *dev = np->dev; const struct net_device_ops *ops = dev->netdev_ops; /* It is up to the caller to keep npinfo alive. */ struct netpoll_info *npinfo = np->dev->npinfo; @@ -346,7 +346,7 @@ void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) schedule_delayed_work(&npinfo->tx_work,0); } } -EXPORT_SYMBOL(netpoll_send_skb); +EXPORT_SYMBOL(netpoll_send_skb_on_dev); void netpoll_send_udp(struct netpoll *np, const char *msg, int len) { diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 10a1ea72010d329295ce3936228aa5bffe7dc745..2c0df0f95b3d488c8e6f8818857f19c02726e200 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -729,16 +729,14 @@ static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, *num = 0; for (; i < maxlen; i++) { + int value; char c; *num <<= 4; if (get_user(c, &user_buffer[i])) return -EFAULT; - if ((c >= '0') && (c <= '9')) - *num |= c - '0'; - else if ((c >= 'a') && (c <= 'f')) - *num |= c - 'a' + 10; - else if ((c >= 'A') && (c <= 'F')) - *num |= c - 'A' + 10; + value = hex_to_bin(c); + if (value >= 0) + *num |= value; else break; } @@ -3907,8 +3905,6 @@ static void __exit pg_cleanup(void) { struct pktgen_thread *t; struct list_head *q, *n; - wait_queue_head_t queue; - init_waitqueue_head(&queue); /* Stop all interfaces & threads */ diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f78d821bd9357dc3a88feb1259219478268858a3..8121268ddbddfcd2da9845c8254fe0406b031be9 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -299,14 +299,6 @@ static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) unregister_netdevice_many(&list_kill); } -void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) -{ - rtnl_lock(); - __rtnl_kill_links(net, ops); - rtnl_unlock(); -} -EXPORT_SYMBOL_GPL(rtnl_kill_links); - /** * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. * @ops: struct rtnl_link_ops * to unregister @@ -612,36 +604,7 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a, static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b) { - struct rtnl_link_stats64 a; - - a.rx_packets = b->rx_packets; - a.tx_packets = b->tx_packets; - a.rx_bytes = b->rx_bytes; - a.tx_bytes = b->tx_bytes; - a.rx_errors = b->rx_errors; - a.tx_errors = b->tx_errors; - a.rx_dropped = b->rx_dropped; - a.tx_dropped = b->tx_dropped; - - a.multicast = b->multicast; - a.collisions = b->collisions; - - a.rx_length_errors = b->rx_length_errors; - a.rx_over_errors = b->rx_over_errors; - a.rx_crc_errors = b->rx_crc_errors; - a.rx_frame_errors = b->rx_frame_errors; - a.rx_fifo_errors = b->rx_fifo_errors; - a.rx_missed_errors = b->rx_missed_errors; - - a.tx_aborted_errors = b->tx_aborted_errors; - a.tx_carrier_errors = b->tx_carrier_errors; - a.tx_fifo_errors = b->tx_fifo_errors; - a.tx_heartbeat_errors = b->tx_heartbeat_errors; - a.tx_window_errors = b->tx_window_errors; - - a.rx_compressed = b->rx_compressed; - a.tx_compressed = b->tx_compressed; - memcpy(v, &a, sizeof(a)); + memcpy(v, b, sizeof(*b)); } /* All VF info */ diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 56ba3c4e4761c6584375a8acf45022bc5c40d6e8..104f8444754aa160fe7922458980ddb57485a2a5 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -202,8 +202,6 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, skb->data = data; skb_reset_tail_pointer(skb); skb->end = skb->tail + size; - kmemcheck_annotate_bitfield(skb, flags1); - kmemcheck_annotate_bitfield(skb, flags2); #ifdef NET_SKBUFF_DATA_USES_OFFSET skb->mac_header = ~0U; #endif @@ -249,10 +247,9 @@ EXPORT_SYMBOL(__alloc_skb); struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int length, gfp_t gfp_mask) { - int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; struct sk_buff *skb; - skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node); + skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, NUMA_NO_NODE); if (likely(skb)) { skb_reserve(skb, NET_SKB_PAD); skb->dev = dev; @@ -261,16 +258,6 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, } EXPORT_SYMBOL(__netdev_alloc_skb); -struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask) -{ - int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1; - struct page *page; - - page = alloc_pages_node(node, gfp_mask, 0); - return page; -} -EXPORT_SYMBOL(__netdev_alloc_page); - void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, int size) { @@ -340,7 +327,7 @@ static void skb_release_data(struct sk_buff *skb) put_page(skb_shinfo(skb)->frags[i].page); } - if (skb_has_frags(skb)) + if (skb_has_frag_list(skb)) skb_drop_fraglist(skb); kfree(skb->head); @@ -686,16 +673,10 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask) { - int headerlen = skb->data - skb->head; - /* - * Allocate the copy buffer - */ - struct sk_buff *n; -#ifdef NET_SKBUFF_DATA_USES_OFFSET - n = alloc_skb(skb->end + skb->data_len, gfp_mask); -#else - n = alloc_skb(skb->end - skb->head + skb->data_len, gfp_mask); -#endif + int headerlen = skb_headroom(skb); + unsigned int size = (skb_end_pointer(skb) - skb->head) + skb->data_len; + struct sk_buff *n = alloc_skb(size, gfp_mask); + if (!n) return NULL; @@ -727,20 +708,14 @@ EXPORT_SYMBOL(skb_copy); struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) { - /* - * Allocate the copy buffer - */ - struct sk_buff *n; -#ifdef NET_SKBUFF_DATA_USES_OFFSET - n = alloc_skb(skb->end, gfp_mask); -#else - n = alloc_skb(skb->end - skb->head, gfp_mask); -#endif + unsigned int size = skb_end_pointer(skb) - skb->head; + struct sk_buff *n = alloc_skb(size, gfp_mask); + if (!n) goto out; /* Set the data pointer */ - skb_reserve(n, skb->data - skb->head); + skb_reserve(n, skb_headroom(skb)); /* Set the tail pointer and length */ skb_put(n, skb_headlen(skb)); /* Copy the bytes */ @@ -760,7 +735,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask) skb_shinfo(n)->nr_frags = i; } - if (skb_has_frags(skb)) { + if (skb_has_frag_list(skb)) { skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list; skb_clone_fraglist(n); } @@ -792,12 +767,9 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, { int i; u8 *data; -#ifdef NET_SKBUFF_DATA_USES_OFFSET - int size = nhead + skb->end + ntail; -#else - int size = nhead + (skb->end - skb->head) + ntail; -#endif + int size = nhead + (skb_end_pointer(skb) - skb->head) + ntail; long off; + bool fastpath; BUG_ON(nhead < 0); @@ -811,23 +783,36 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail, goto nodata; /* Copy only real data... and, alas, header. This should be - * optimized for the cases when header is void. */ -#ifdef NET_SKBUFF_DATA_USES_OFFSET - memcpy(data + nhead, skb->head, skb->tail); -#else - memcpy(data + nhead, skb->head, skb->tail - skb->head); -#endif - memcpy(data + size, skb_end_pointer(skb), + * optimized for the cases when header is void. + */ + memcpy(data + nhead, skb->head, skb_tail_pointer(skb) - skb->head); + + memcpy((struct skb_shared_info *)(data + size), + skb_shinfo(skb), offsetof(struct skb_shared_info, frags[skb_shinfo(skb)->nr_frags])); - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) - get_page(skb_shinfo(skb)->frags[i].page); + /* Check if we can avoid taking references on fragments if we own + * the last reference on skb->head. (see skb_release_data()) + */ + if (!skb->cloned) + fastpath = true; + else { + int delta = skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1; - if (skb_has_frags(skb)) - skb_clone_fraglist(skb); + fastpath = atomic_read(&skb_shinfo(skb)->dataref) == delta; + } - skb_release_data(skb); + if (fastpath) { + kfree(skb->head); + } else { + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) + get_page(skb_shinfo(skb)->frags[i].page); + if (skb_has_frag_list(skb)) + skb_clone_fraglist(skb); + + skb_release_data(skb); + } off = (data + nhead) - skb->head; skb->head = data; @@ -1100,7 +1085,7 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) for (; i < nfrags; i++) put_page(skb_shinfo(skb)->frags[i].page); - if (skb_has_frags(skb)) + if (skb_has_frag_list(skb)) skb_drop_fraglist(skb); goto done; } @@ -1195,7 +1180,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) /* Optimization: no fragments, no reasons to preestimate * size of pulled pages. Superb. */ - if (!skb_has_frags(skb)) + if (!skb_has_frag_list(skb)) goto pull_pages; /* Estimate size of pulled pages. */ @@ -2324,7 +2309,7 @@ unsigned int skb_seq_read(unsigned int consumed, const u8 **data, st->frag_data = NULL; } - if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) { + if (st->root_skb == st->cur_skb && skb_has_frag_list(st->root_skb)) { st->cur_skb = skb_shinfo(st->root_skb)->frag_list; st->frag_idx = 0; goto next_skb; @@ -2894,7 +2879,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) return -ENOMEM; /* Easy case. Most of packets will go this way. */ - if (!skb_has_frags(skb)) { + if (!skb_has_frag_list(skb)) { /* A little of trouble, not enough of space for trailer. * This should not happen, when stack is tuned to generate * good frames. OK, on miss we reallocate and reserve even more @@ -2929,7 +2914,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) if (skb1->next == NULL && tailbits) { if (skb_shinfo(skb1)->nr_frags || - skb_has_frags(skb1) || + skb_has_frag_list(skb1) || skb_tailroom(skb1) < tailbits) ntail = tailbits + 128; } @@ -2938,7 +2923,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) skb_cloned(skb1) || ntail || skb_shinfo(skb1)->nr_frags || - skb_has_frags(skb1)) { + skb_has_frag_list(skb1)) { struct sk_buff *skb2; /* Fuck, we are miserable poor guys... */ @@ -3021,7 +3006,7 @@ void skb_tstamp_tx(struct sk_buff *orig_skb, } else { /* * no hardware time stamps available, - * so keep the skb_shared_tx and only + * so keep the shared tx_flags and only * store software time stamp */ skb->tstamp = ktime_get_real(); diff --git a/net/core/sock.c b/net/core/sock.c index 7d99e13148e6287f1cca0f5e3417ee5d535c366c..11db43632df8712576b4ff8f6c8eed7a8fdfd21d 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1560,6 +1560,8 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size, EXPORT_SYMBOL(sock_alloc_send_skb); static void __lock_sock(struct sock *sk) + __releases(&sk->sk_lock.slock) + __acquires(&sk->sk_lock.slock) { DEFINE_WAIT(wait); @@ -1576,6 +1578,8 @@ static void __lock_sock(struct sock *sk) } static void __release_sock(struct sock *sk) + __releases(&sk->sk_lock.slock) + __acquires(&sk->sk_lock.slock) { struct sk_buff *skb = sk->sk_backlog.head; diff --git a/net/core/utils.c b/net/core/utils.c index f41854470539855adee387a4c488f4be66a017a2..5fea0ab2190274faf53705ee6bb87338072a26cc 100644 --- a/net/core/utils.c +++ b/net/core/utils.c @@ -75,7 +75,7 @@ __be32 in_aton(const char *str) str++; } } - return(htonl(l)); + return htonl(l); } EXPORT_SYMBOL(in_aton); @@ -92,18 +92,19 @@ EXPORT_SYMBOL(in_aton); static inline int xdigit2bin(char c, int delim) { + int val; + if (c == delim || c == '\0') return IN6PTON_DELIM; if (c == ':') return IN6PTON_COLON_MASK; if (c == '.') return IN6PTON_DOT; - if (c >= '0' && c <= '9') - return (IN6PTON_XDIGIT | IN6PTON_DIGIT| (c - '0')); - if (c >= 'a' && c <= 'f') - return (IN6PTON_XDIGIT | (c - 'a' + 10)); - if (c >= 'A' && c <= 'F') - return (IN6PTON_XDIGIT | (c - 'A' + 10)); + + val = hex_to_bin(c); + if (val >= 0) + return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0); + if (delim == -1) return IN6PTON_DELIM; return IN6PTON_UNKNOWN; diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 6df6f8ac963664e2174b55c890ce7f45cbe05128..117fb093dcafeebab54ee687e6d50317b4e88239 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h @@ -62,22 +62,18 @@ struct ccid_operations { void (*ccid_hc_tx_exit)(struct sock *sk); void (*ccid_hc_rx_packet_recv)(struct sock *sk, struct sk_buff *skb); - int (*ccid_hc_rx_parse_options)(struct sock *sk, - unsigned char option, - unsigned char len, u16 idx, - unsigned char* value); + int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt, + u8 opt, u8 *val, u8 len); int (*ccid_hc_rx_insert_options)(struct sock *sk, struct sk_buff *skb); void (*ccid_hc_tx_packet_recv)(struct sock *sk, struct sk_buff *skb); - int (*ccid_hc_tx_parse_options)(struct sock *sk, - unsigned char option, - unsigned char len, u16 idx, - unsigned char* value); + int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt, + u8 opt, u8 *val, u8 len); int (*ccid_hc_tx_send_packet)(struct sock *sk, struct sk_buff *skb); void (*ccid_hc_tx_packet_sent)(struct sock *sk, - int more, unsigned int len); + unsigned int len); void (*ccid_hc_rx_get_info)(struct sock *sk, struct tcp_info *info); void (*ccid_hc_tx_get_info)(struct sock *sk, @@ -148,10 +144,10 @@ static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk, } static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, - int more, unsigned int len) + unsigned int len) { if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL) - ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, more, len); + ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, len); } static inline void ccid_hc_rx_packet_recv(struct ccid *ccid, struct sock *sk, @@ -168,27 +164,31 @@ static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk, ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb); } +/** + * ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver + * @pkt: type of packet that @opt appears on (RFC 4340, 5.1) + * @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3) + * @val: value of @opt + * @len: length of @val in bytes + */ static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk, - unsigned char option, - unsigned char len, u16 idx, - unsigned char* value) + u8 pkt, u8 opt, u8 *val, u8 len) { - int rc = 0; - if (ccid->ccid_ops->ccid_hc_tx_parse_options != NULL) - rc = ccid->ccid_ops->ccid_hc_tx_parse_options(sk, option, len, idx, - value); - return rc; + if (ccid->ccid_ops->ccid_hc_tx_parse_options == NULL) + return 0; + return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len); } +/** + * ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender + * Arguments are analogous to ccid_hc_tx_parse_options() + */ static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk, - unsigned char option, - unsigned char len, u16 idx, - unsigned char* value) + u8 pkt, u8 opt, u8 *val, u8 len) { - int rc = 0; - if (ccid->ccid_ops->ccid_hc_rx_parse_options != NULL) - rc = ccid->ccid_ops->ccid_hc_rx_parse_options(sk, option, len, idx, value); - return rc; + if (ccid->ccid_ops->ccid_hc_rx_parse_options == NULL) + return 0; + return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len); } static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig index 8408398cd44e814cece7b9ec92615b1c615d32bd..0581143cb800d9b0b43bd86d0d2dcebf24abd3c1 100644 --- a/net/dccp/ccids/Kconfig +++ b/net/dccp/ccids/Kconfig @@ -47,37 +47,6 @@ config IP_DCCP_CCID3_DEBUG If in doubt, say N. -config IP_DCCP_CCID3_RTO - int "Use higher bound for nofeedback timer" - default 100 - depends on IP_DCCP_CCID3 && EXPERIMENTAL - ---help--- - Use higher lower bound for nofeedback timer expiration. - - The TFRC nofeedback timer normally expires after the maximum of 4 - RTTs and twice the current send interval (RFC 3448, 4.3). On LANs - with a small RTT this can mean a high processing load and reduced - performance, since then the nofeedback timer is triggered very - frequently. - - This option enables to set a higher lower bound for the nofeedback - value. Values in units of milliseconds can be set here. - - A value of 0 disables this feature by enforcing the value specified - in RFC 3448. The following values have been suggested as bounds for - experimental use: - * 16-20ms to match the typical multimedia inter-frame interval - * 100ms as a reasonable compromise [default] - * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4) - - The default of 100ms is a compromise between a large value for - efficient DCCP implementations, and a small value to avoid disrupting - the network in times of congestion. - - The purpose of the nofeedback timer is to slow DCCP down when there - is serious network congestion: experimenting with larger values should - therefore not be performed on WANs. - config IP_DCCP_TFRC_LIB def_bool y if IP_DCCP_CCID3 diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 9b3ae9922be1aa446f8b57973356d216de9f82ee..d850e291f87c8b23defdba15d89849892038b251 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c @@ -25,59 +25,14 @@ */ #include #include "../feat.h" -#include "../ccid.h" -#include "../dccp.h" #include "ccid2.h" #ifdef CONFIG_IP_DCCP_CCID2_DEBUG static int ccid2_debug; #define ccid2_pr_debug(format, a...) DCCP_PR_DEBUG(ccid2_debug, format, ##a) - -static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hc) -{ - int len = 0; - int pipe = 0; - struct ccid2_seq *seqp = hc->tx_seqh; - - /* there is data in the chain */ - if (seqp != hc->tx_seqt) { - seqp = seqp->ccid2s_prev; - len++; - if (!seqp->ccid2s_acked) - pipe++; - - while (seqp != hc->tx_seqt) { - struct ccid2_seq *prev = seqp->ccid2s_prev; - - len++; - if (!prev->ccid2s_acked) - pipe++; - - /* packets are sent sequentially */ - BUG_ON(dccp_delta_seqno(seqp->ccid2s_seq, - prev->ccid2s_seq ) >= 0); - BUG_ON(time_before(seqp->ccid2s_sent, - prev->ccid2s_sent)); - - seqp = prev; - } - } - - BUG_ON(pipe != hc->tx_pipe); - ccid2_pr_debug("len of chain=%d\n", len); - - do { - seqp = seqp->ccid2s_prev; - len++; - } while (seqp != hc->tx_seqh); - - ccid2_pr_debug("total len=%d\n", len); - BUG_ON(len != hc->tx_seqbufc * CCID2_SEQBUF_LEN); -} #else #define ccid2_pr_debug(format, a...) -#define ccid2_hc_tx_check_sanity(hc) #endif static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc) @@ -156,19 +111,10 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val) dp->dccps_l_ack_ratio = val; } -static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hc, long val) -{ - ccid2_pr_debug("change SRTT to %ld\n", val); - hc->tx_srtt = val; -} - -static void ccid2_start_rto_timer(struct sock *sk); - static void ccid2_hc_tx_rto_expire(unsigned long data) { struct sock *sk = (struct sock *)data; struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - long s; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -178,23 +124,19 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) ccid2_pr_debug("RTO_EXPIRE\n"); - ccid2_hc_tx_check_sanity(hc); - /* back-off timer */ hc->tx_rto <<= 1; + if (hc->tx_rto > DCCP_RTO_MAX) + hc->tx_rto = DCCP_RTO_MAX; - s = hc->tx_rto / HZ; - if (s > 60) - hc->tx_rto = 60 * HZ; - - ccid2_start_rto_timer(sk); + sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); /* adjust pipe, cwnd etc */ hc->tx_ssthresh = hc->tx_cwnd / 2; if (hc->tx_ssthresh < 2) hc->tx_ssthresh = 2; - hc->tx_cwnd = 1; - hc->tx_pipe = 0; + hc->tx_cwnd = 1; + hc->tx_pipe = 0; /* clear state about stuff we sent */ hc->tx_seqt = hc->tx_seqh; @@ -204,23 +146,12 @@ static void ccid2_hc_tx_rto_expire(unsigned long data) hc->tx_rpseq = 0; hc->tx_rpdupack = -1; ccid2_change_l_ack_ratio(sk, 1); - ccid2_hc_tx_check_sanity(hc); out: bh_unlock_sock(sk); sock_put(sk); } -static void ccid2_start_rto_timer(struct sock *sk) -{ - struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - - ccid2_pr_debug("setting RTO timeout=%ld\n", hc->tx_rto); - - BUG_ON(timer_pending(&hc->tx_rtotimer)); - sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); -} - -static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) +static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len) { struct dccp_sock *dp = dccp_sk(sk); struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); @@ -230,7 +161,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) hc->tx_seqh->ccid2s_seq = dp->dccps_gss; hc->tx_seqh->ccid2s_acked = 0; - hc->tx_seqh->ccid2s_sent = jiffies; + hc->tx_seqh->ccid2s_sent = ccid2_time_stamp; next = hc->tx_seqh->ccid2s_next; /* check if we need to alloc more space */ @@ -296,23 +227,20 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len) } #endif - /* setup RTO timer */ - if (!timer_pending(&hc->tx_rtotimer)) - ccid2_start_rto_timer(sk); + sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); #ifdef CONFIG_IP_DCCP_CCID2_DEBUG do { struct ccid2_seq *seqp = hc->tx_seqt; while (seqp != hc->tx_seqh) { - ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n", + ccid2_pr_debug("out seq=%llu acked=%d time=%u\n", (unsigned long long)seqp->ccid2s_seq, seqp->ccid2s_acked, seqp->ccid2s_sent); seqp = seqp->ccid2s_next; } } while (0); ccid2_pr_debug("=========\n"); - ccid2_hc_tx_check_sanity(hc); #endif } @@ -378,17 +306,87 @@ static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset, return -1; } -static void ccid2_hc_tx_kill_rto_timer(struct sock *sk) +/** + * ccid2_rtt_estimator - Sample RTT and compute RTO using RFC2988 algorithm + * This code is almost identical with TCP's tcp_rtt_estimator(), since + * - it has a higher sampling frequency (recommended by RFC 1323), + * - the RTO does not collapse into RTT due to RTTVAR going towards zero, + * - it is simple (cf. more complex proposals such as Eifel timer or research + * which suggests that the gain should be set according to window size), + * - in tests it was found to work well with CCID2 [gerrit]. + */ +static void ccid2_rtt_estimator(struct sock *sk, const long mrtt) { struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); + long m = mrtt ? : 1; - sk_stop_timer(sk, &hc->tx_rtotimer); - ccid2_pr_debug("deleted RTO timer\n"); + if (hc->tx_srtt == 0) { + /* First measurement m */ + hc->tx_srtt = m << 3; + hc->tx_mdev = m << 1; + + hc->tx_mdev_max = max(hc->tx_mdev, tcp_rto_min(sk)); + hc->tx_rttvar = hc->tx_mdev_max; + + hc->tx_rtt_seq = dccp_sk(sk)->dccps_gss; + } else { + /* Update scaled SRTT as SRTT += 1/8 * (m - SRTT) */ + m -= (hc->tx_srtt >> 3); + hc->tx_srtt += m; + + /* Similarly, update scaled mdev with regard to |m| */ + if (m < 0) { + m = -m; + m -= (hc->tx_mdev >> 2); + /* + * This neutralises RTO increase when RTT < SRTT - mdev + * (see P. Sarolahti, A. Kuznetsov,"Congestion Control + * in Linux TCP", USENIX 2002, pp. 49-62). + */ + if (m > 0) + m >>= 3; + } else { + m -= (hc->tx_mdev >> 2); + } + hc->tx_mdev += m; + + if (hc->tx_mdev > hc->tx_mdev_max) { + hc->tx_mdev_max = hc->tx_mdev; + if (hc->tx_mdev_max > hc->tx_rttvar) + hc->tx_rttvar = hc->tx_mdev_max; + } + + /* + * Decay RTTVAR at most once per flight, exploiting that + * 1) pipe <= cwnd <= Sequence_Window = W (RFC 4340, 7.5.2) + * 2) AWL = GSS-W+1 <= GAR <= GSS (RFC 4340, 7.5.1) + * GAR is a useful bound for FlightSize = pipe. + * AWL is probably too low here, as it over-estimates pipe. + */ + if (after48(dccp_sk(sk)->dccps_gar, hc->tx_rtt_seq)) { + if (hc->tx_mdev_max < hc->tx_rttvar) + hc->tx_rttvar -= (hc->tx_rttvar - + hc->tx_mdev_max) >> 2; + hc->tx_rtt_seq = dccp_sk(sk)->dccps_gss; + hc->tx_mdev_max = tcp_rto_min(sk); + } + } + + /* + * Set RTO from SRTT and RTTVAR + * As in TCP, 4 * RTTVAR >= TCP_RTO_MIN, giving a minimum RTO of 200 ms. + * This agrees with RFC 4341, 5: + * "Because DCCP does not retransmit data, DCCP does not require + * TCP's recommended minimum timeout of one second". + */ + hc->tx_rto = (hc->tx_srtt >> 3) + hc->tx_rttvar; + + if (hc->tx_rto > DCCP_RTO_MAX) + hc->tx_rto = DCCP_RTO_MAX; } -static inline void ccid2_new_ack(struct sock *sk, - struct ccid2_seq *seqp, - unsigned int *maxincr) +static void ccid2_new_ack(struct sock *sk, struct ccid2_seq *seqp, + unsigned int *maxincr) { struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); @@ -402,93 +400,27 @@ static inline void ccid2_new_ack(struct sock *sk, hc->tx_cwnd += 1; hc->tx_packets_acked = 0; } - - /* update RTO */ - if (hc->tx_srtt == -1 || - time_after(jiffies, hc->tx_lastrtt + hc->tx_srtt)) { - unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent; - int s; - - /* first measurement */ - if (hc->tx_srtt == -1) { - ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", - r, jiffies, - (unsigned long long)seqp->ccid2s_seq); - ccid2_change_srtt(hc, r); - hc->tx_rttvar = r >> 1; - } else { - /* RTTVAR */ - long tmp = hc->tx_srtt - r; - long srtt; - - if (tmp < 0) - tmp *= -1; - - tmp >>= 2; - hc->tx_rttvar *= 3; - hc->tx_rttvar >>= 2; - hc->tx_rttvar += tmp; - - /* SRTT */ - srtt = hc->tx_srtt; - srtt *= 7; - srtt >>= 3; - tmp = r >> 3; - srtt += tmp; - ccid2_change_srtt(hc, srtt); - } - s = hc->tx_rttvar << 2; - /* clock granularity is 1 when based on jiffies */ - if (!s) - s = 1; - hc->tx_rto = hc->tx_srtt + s; - - /* must be at least a second */ - s = hc->tx_rto / HZ; - /* DCCP doesn't require this [but I like it cuz my code sux] */ -#if 1 - if (s < 1) - hc->tx_rto = HZ; -#endif - /* max 60 seconds */ - if (s > 60) - hc->tx_rto = HZ * 60; - - hc->tx_lastrtt = jiffies; - - ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n", - hc->tx_srtt, hc->tx_rttvar, - hc->tx_rto, HZ, r); - } - - /* we got a new ack, so re-start RTO timer */ - ccid2_hc_tx_kill_rto_timer(sk); - ccid2_start_rto_timer(sk); -} - -static void ccid2_hc_tx_dec_pipe(struct sock *sk) -{ - struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - - if (hc->tx_pipe == 0) - DCCP_BUG("pipe == 0"); - else - hc->tx_pipe--; - - if (hc->tx_pipe == 0) - ccid2_hc_tx_kill_rto_timer(sk); + /* + * FIXME: RTT is sampled several times per acknowledgment (for each + * entry in the Ack Vector), instead of once per Ack (as in TCP SACK). + * This causes the RTT to be over-estimated, since the older entries + * in the Ack Vector have earlier sending times. + * The cleanest solution is to not use the ccid2s_sent field at all + * and instead use DCCP timestamps: requires changes in other places. + */ + ccid2_rtt_estimator(sk, ccid2_time_stamp - seqp->ccid2s_sent); } static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp) { struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); - if (time_before(seqp->ccid2s_sent, hc->tx_last_cong)) { + if ((s32)(seqp->ccid2s_sent - hc->tx_last_cong) < 0) { ccid2_pr_debug("Multiple losses in an RTT---treating as one\n"); return; } - hc->tx_last_cong = jiffies; + hc->tx_last_cong = ccid2_time_stamp; hc->tx_cwnd = hc->tx_cwnd / 2 ? : 1U; hc->tx_ssthresh = max(hc->tx_cwnd, 2U); @@ -510,7 +442,6 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) int done = 0; unsigned int maxincr = 0; - ccid2_hc_tx_check_sanity(hc); /* check reverse path congestion */ seqno = DCCP_SKB_CB(skb)->dccpd_seq; @@ -620,7 +551,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) seqp->ccid2s_acked = 1; ccid2_pr_debug("Got ack for %llu\n", (unsigned long long)seqp->ccid2s_seq); - ccid2_hc_tx_dec_pipe(sk); + hc->tx_pipe--; } if (seqp == hc->tx_seqt) { done = 1; @@ -677,7 +608,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) * one ack vector. */ ccid2_congestion_event(sk, seqp); - ccid2_hc_tx_dec_pipe(sk); + hc->tx_pipe--; } if (seqp == hc->tx_seqt) break; @@ -695,7 +626,11 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) hc->tx_seqt = hc->tx_seqt->ccid2s_next; } - ccid2_hc_tx_check_sanity(hc); + /* restart RTO timer if not all outstanding data has been acked */ + if (hc->tx_pipe == 0) + sk_stop_timer(sk, &hc->tx_rtotimer); + else + sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto); } static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) @@ -707,12 +642,8 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) /* RFC 4341, 5: initialise ssthresh to arbitrarily high (max) value */ hc->tx_ssthresh = ~0U; - /* - * RFC 4341, 5: "The cwnd parameter is initialized to at most four - * packets for new connections, following the rules from [RFC3390]". - * We need to convert the bytes of RFC3390 into the packets of RFC 4341. - */ - hc->tx_cwnd = clamp(4380U / dp->dccps_mss_cache, 2U, 4U); + /* Use larger initial windows (RFC 4341, section 5). */ + hc->tx_cwnd = rfc3390_bytes_to_packets(dp->dccps_mss_cache); /* Make sure that Ack Ratio is enabled and within bounds. */ max_ratio = DIV_ROUND_UP(hc->tx_cwnd, 2); @@ -723,15 +654,11 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk) if (ccid2_hc_tx_alloc_seq(hc)) return -ENOMEM; - hc->tx_rto = 3 * HZ; - ccid2_change_srtt(hc, -1); - hc->tx_rttvar = -1; + hc->tx_rto = DCCP_TIMEOUT_INIT; hc->tx_rpdupack = -1; - hc->tx_last_cong = jiffies; + hc->tx_last_cong = ccid2_time_stamp; setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire, (unsigned long)sk); - - ccid2_hc_tx_check_sanity(hc); return 0; } @@ -740,7 +667,7 @@ static void ccid2_hc_tx_exit(struct sock *sk) struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk); int i; - ccid2_hc_tx_kill_rto_timer(sk); + sk_stop_timer(sk, &hc->tx_rtotimer); for (i = 0; i < hc->tx_seqbufc; i++) kfree(hc->tx_seqbuf[i]); diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h index 1ec6a30103bbb3247b0a25385ab8aa318899ccc7..9731c2dc148715eacace932c37f695989f526450 100644 --- a/net/dccp/ccids/ccid2.h +++ b/net/dccp/ccids/ccid2.h @@ -18,18 +18,23 @@ #ifndef _DCCP_CCID2_H_ #define _DCCP_CCID2_H_ -#include #include #include #include "../ccid.h" +#include "../dccp.h" + +/* + * CCID-2 timestamping faces the same issues as TCP timestamping. + * Hence we reuse/share as much of the code as possible. + */ +#define ccid2_time_stamp tcp_time_stamp + /* NUMDUPACK parameter from RFC 4341, p. 6 */ #define NUMDUPACK 3 -struct sock; - struct ccid2_seq { u64 ccid2s_seq; - unsigned long ccid2s_sent; + u32 ccid2s_sent; int ccid2s_acked; struct ccid2_seq *ccid2s_prev; struct ccid2_seq *ccid2s_next; @@ -42,7 +47,12 @@ struct ccid2_seq { * struct ccid2_hc_tx_sock - CCID2 TX half connection * @tx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5 * @tx_packets_acked: Ack counter for deriving cwnd growth (RFC 3465) - * @tx_lastrtt: time RTT was last measured + * @tx_srtt: smoothed RTT estimate, scaled by 2^3 + * @tx_mdev: smoothed RTT variation, scaled by 2^2 + * @tx_mdev_max: maximum of @mdev during one flight + * @tx_rttvar: moving average/maximum of @mdev_max + * @tx_rto: RTO value deriving from SRTT and RTTVAR (RFC 2988) + * @tx_rtt_seq: to decay RTTVAR at most once per flight * @tx_rpseq: last consecutive seqno * @tx_rpdupack: dupacks since rpseq */ @@ -55,14 +65,19 @@ struct ccid2_hc_tx_sock { int tx_seqbufc; struct ccid2_seq *tx_seqh; struct ccid2_seq *tx_seqt; - long tx_rto; - long tx_srtt; - long tx_rttvar; - unsigned long tx_lastrtt; + + /* RTT measurement: variables/principles are the same as in TCP */ + u32 tx_srtt, + tx_mdev, + tx_mdev_max, + tx_rttvar, + tx_rto; + u64 tx_rtt_seq:48; struct timer_list tx_rtotimer; + u64 tx_rpseq; int tx_rpdupack; - unsigned long tx_last_cong; + u32 tx_last_cong; u64 tx_high_ack; }; diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index 95f7529864972aa34be0ba8ab3fd66b6eb640e47..3060a60ed5abd7f6212f6ccd7fa76b9ffe88bc01 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -54,7 +54,6 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) [TFRC_SSTATE_NO_SENT] = "NO_SENT", [TFRC_SSTATE_NO_FBACK] = "NO_FBACK", [TFRC_SSTATE_FBACK] = "FBACK", - [TFRC_SSTATE_TERM] = "TERM", }; return ccid3_state_names[state]; @@ -91,19 +90,16 @@ static inline u64 rfc3390_initial_rate(struct sock *sk) return scaled_div(w_init << 6, hc->tx_rtt); } -/* - * Recalculate t_ipi and delta (should be called whenever X changes) +/** + * ccid3_update_send_interval - Calculate new t_ipi = s / X_inst + * This respects the granularity of X_inst (64 * bytes/second). */ static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hc) { - /* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */ hc->tx_t_ipi = scaled_div32(((u64)hc->tx_s) << 6, hc->tx_x); - /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */ - hc->tx_delta = min_t(u32, hc->tx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN); - - ccid3_pr_debug("t_ipi=%u, delta=%u, s=%u, X=%u\n", hc->tx_t_ipi, - hc->tx_delta, hc->tx_s, (unsigned)(hc->tx_x >> 6)); + ccid3_pr_debug("t_ipi=%u, s=%u, X=%u\n", hc->tx_t_ipi, + hc->tx_s, (unsigned)(hc->tx_x >> 6)); } static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hc, ktime_t now) @@ -211,16 +207,19 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk, ccid3_tx_state_name(hc->tx_state)); + /* Ignore and do not restart after leaving the established state */ + if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN)) + goto out; + + /* Reset feedback state to "no feedback received" */ if (hc->tx_state == TFRC_SSTATE_FBACK) ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); - else if (hc->tx_state != TFRC_SSTATE_NO_FBACK) - goto out; /* * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4 + * RTO is 0 if and only if no feedback has been received yet. */ - if (hc->tx_t_rto == 0 || /* no feedback received yet */ - hc->tx_p == 0) { + if (hc->tx_t_rto == 0 || hc->tx_p == 0) { /* halve send rate directly */ hc->tx_x = max(hc->tx_x / 2, @@ -256,7 +255,7 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data) * Set new timeout for the nofeedback timer. * See comments in packet_recv() regarding the value of t_RTO. */ - if (unlikely(hc->tx_t_rto == 0)) /* no feedback yet */ + if (unlikely(hc->tx_t_rto == 0)) /* no feedback received yet */ t_nfb = TFRC_INITIAL_TIMEOUT; else t_nfb = max(hc->tx_t_rto, 2 * hc->tx_t_ipi); @@ -290,8 +289,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) if (unlikely(skb->len == 0)) return -EBADMSG; - switch (hc->tx_state) { - case TFRC_SSTATE_NO_SENT: + if (hc->tx_state == TFRC_SSTATE_NO_SENT) { sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT))); hc->tx_last_win_count = 0; @@ -326,27 +324,22 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) ccid3_update_send_interval(hc); ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); - break; - case TFRC_SSTATE_NO_FBACK: - case TFRC_SSTATE_FBACK: + + } else { delay = ktime_us_delta(hc->tx_t_nom, now); ccid3_pr_debug("delay=%ld\n", (long)delay); /* - * Scheduling of packet transmissions [RFC 3448, 4.6] + * Scheduling of packet transmissions (RFC 5348, 8.3) * * if (t_now > t_nom - delta) * // send the packet now * else * // send the packet in (t_nom - t_now) milliseconds. */ - if (delay - (s64)hc->tx_delta >= 1000) - return (u32)delay / 1000L; + if (delay >= TFRC_T_DELTA) + return (u32)delay / USEC_PER_MSEC; ccid3_hc_tx_update_win_count(hc, now); - break; - case TFRC_SSTATE_TERM: - DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk); - return -EINVAL; } /* prepare to send now (add options etc.) */ @@ -358,8 +351,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) return 0; } -static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, - unsigned int len) +static void ccid3_hc_tx_packet_sent(struct sock *sk, unsigned int len) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); @@ -372,48 +364,34 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); - struct ccid3_options_received *opt_recv; + struct tfrc_tx_hist_entry *acked; ktime_t now; unsigned long t_nfb; - u32 pinv, r_sample; + u32 r_sample; /* we are only interested in ACKs */ if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK)) return; - /* ... and only in the established state */ - if (hc->tx_state != TFRC_SSTATE_FBACK && - hc->tx_state != TFRC_SSTATE_NO_FBACK) - return; - - opt_recv = &hc->tx_options_received; - now = ktime_get_real(); - - /* Estimate RTT from history if ACK number is valid */ - r_sample = tfrc_tx_hist_rtt(hc->tx_hist, - DCCP_SKB_CB(skb)->dccpd_ack_seq, now); - if (r_sample == 0) { - DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk, - dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type), - (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq); - return; - } - - /* Update receive rate in units of 64 * bytes/second */ - hc->tx_x_recv = opt_recv->ccid3or_receive_rate; - hc->tx_x_recv <<= 6; - - /* Update loss event rate (which is scaled by 1e6) */ - pinv = opt_recv->ccid3or_loss_event_rate; - if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */ - hc->tx_p = 0; - else /* can not exceed 100% */ - hc->tx_p = scaled_div(1, pinv); /* - * Validate new RTT sample and update moving average + * Locate the acknowledged packet in the TX history. + * + * Returning "entry not found" here can for instance happen when + * - the host has not sent out anything (e.g. a passive server), + * - the Ack is outdated (packet with higher Ack number was received), + * - it is a bogus Ack (for a packet not sent on this connection). */ - r_sample = dccp_sample_rtt(sk, r_sample); + acked = tfrc_tx_hist_find_entry(hc->tx_hist, dccp_hdr_ack_seq(skb)); + if (acked == NULL) + return; + /* For the sake of RTT sampling, ignore/remove all older entries */ + tfrc_tx_hist_purge(&acked->next); + + /* Update the moving average for the RTT estimate (RFC 3448, 4.3) */ + now = ktime_get_real(); + r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp)); hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9); + /* * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 */ @@ -461,13 +439,12 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) sk->sk_write_space(sk); /* - * Update timeout interval for the nofeedback timer. - * We use a configuration option to increase the lower bound. - * This can help avoid triggering the nofeedback timer too - * often ('spinning') on LANs with small RTTs. + * Update timeout interval for the nofeedback timer. In order to control + * rate halving on networks with very low RTTs (<= 1 ms), use per-route + * tunable RTAX_RTO_MIN value as the lower bound. */ - hc->tx_t_rto = max_t(u32, 4 * hc->tx_rtt, (CONFIG_IP_DCCP_CCID3_RTO * - (USEC_PER_SEC / 1000))); + hc->tx_t_rto = max_t(u32, 4 * hc->tx_rtt, + USEC_PER_SEC/HZ * tcp_rto_min(sk)); /* * Schedule no feedback timer to expire in * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi) @@ -482,66 +459,41 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) jiffies + usecs_to_jiffies(t_nfb)); } -static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, - unsigned char len, u16 idx, - unsigned char *value) +static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type, + u8 option, u8 *optval, u8 optlen) { - int rc = 0; - const struct dccp_sock *dp = dccp_sk(sk); struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); - struct ccid3_options_received *opt_recv; __be32 opt_val; - opt_recv = &hc->tx_options_received; - - if (opt_recv->ccid3or_seqno != dp->dccps_gsr) { - opt_recv->ccid3or_seqno = dp->dccps_gsr; - opt_recv->ccid3or_loss_event_rate = ~0; - opt_recv->ccid3or_loss_intervals_idx = 0; - opt_recv->ccid3or_loss_intervals_len = 0; - opt_recv->ccid3or_receive_rate = 0; - } - switch (option) { + case TFRC_OPT_RECEIVE_RATE: case TFRC_OPT_LOSS_EVENT_RATE: - if (unlikely(len != 4)) { - DCCP_WARN("%s(%p), invalid len %d " - "for TFRC_OPT_LOSS_EVENT_RATE\n", - dccp_role(sk), sk, len); - rc = -EINVAL; - } else { - opt_val = get_unaligned((__be32 *)value); - opt_recv->ccid3or_loss_event_rate = ntohl(opt_val); - ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", - dccp_role(sk), sk, - opt_recv->ccid3or_loss_event_rate); + /* Must be ignored on Data packets, cf. RFC 4342 8.3 and 8.5 */ + if (packet_type == DCCP_PKT_DATA) + break; + if (unlikely(optlen != 4)) { + DCCP_WARN("%s(%p), invalid len %d for %u\n", + dccp_role(sk), sk, optlen, option); + return -EINVAL; } - break; - case TFRC_OPT_LOSS_INTERVALS: - opt_recv->ccid3or_loss_intervals_idx = idx; - opt_recv->ccid3or_loss_intervals_len = len; - ccid3_pr_debug("%s(%p), LOSS_INTERVALS=(%u, %u)\n", - dccp_role(sk), sk, - opt_recv->ccid3or_loss_intervals_idx, - opt_recv->ccid3or_loss_intervals_len); - break; - case TFRC_OPT_RECEIVE_RATE: - if (unlikely(len != 4)) { - DCCP_WARN("%s(%p), invalid len %d " - "for TFRC_OPT_RECEIVE_RATE\n", - dccp_role(sk), sk, len); - rc = -EINVAL; - } else { - opt_val = get_unaligned((__be32 *)value); - opt_recv->ccid3or_receive_rate = ntohl(opt_val); + opt_val = ntohl(get_unaligned((__be32 *)optval)); + + if (option == TFRC_OPT_RECEIVE_RATE) { + /* Receive Rate is kept in units of 64 bytes/second */ + hc->tx_x_recv = opt_val; + hc->tx_x_recv <<= 6; + ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", - dccp_role(sk), sk, - opt_recv->ccid3or_receive_rate); + dccp_role(sk), sk, opt_val); + } else { + /* Update the fixpoint Loss Event Rate fraction */ + hc->tx_p = tfrc_invert_loss_event_rate(opt_val); + + ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", + dccp_role(sk), sk, opt_val); } - break; } - - return rc; + return 0; } static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) @@ -559,42 +511,36 @@ static void ccid3_hc_tx_exit(struct sock *sk) { struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); - ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM); sk_stop_timer(sk, &hc->tx_no_feedback_timer); - tfrc_tx_hist_purge(&hc->tx_hist); } static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) { - struct ccid3_hc_tx_sock *hc; - - /* Listen socks doesn't have a private CCID block */ - if (sk->sk_state == DCCP_LISTEN) - return; - - hc = ccid3_hc_tx_sk(sk); - info->tcpi_rto = hc->tx_t_rto; - info->tcpi_rtt = hc->tx_rtt; + info->tcpi_rto = ccid3_hc_tx_sk(sk)->tx_t_rto; + info->tcpi_rtt = ccid3_hc_tx_sk(sk)->tx_rtt; } static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len, u32 __user *optval, int __user *optlen) { - const struct ccid3_hc_tx_sock *hc; + const struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); + struct tfrc_tx_info tfrc; const void *val; - /* Listen socks doesn't have a private CCID block */ - if (sk->sk_state == DCCP_LISTEN) - return -EINVAL; - - hc = ccid3_hc_tx_sk(sk); switch (optname) { case DCCP_SOCKOPT_CCID_TX_INFO: - if (len < sizeof(hc->tx_tfrc)) + if (len < sizeof(tfrc)) return -EINVAL; - len = sizeof(hc->tx_tfrc); - val = &hc->tx_tfrc; + tfrc.tfrctx_x = hc->tx_x; + tfrc.tfrctx_x_recv = hc->tx_x_recv; + tfrc.tfrctx_x_calc = hc->tx_x_calc; + tfrc.tfrctx_rtt = hc->tx_rtt; + tfrc.tfrctx_p = hc->tx_p; + tfrc.tfrctx_rto = hc->tx_t_rto; + tfrc.tfrctx_ipi = hc->tx_t_ipi; + len = sizeof(tfrc); + val = &tfrc; break; default: return -ENOPROTOOPT; @@ -624,7 +570,6 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) static const char *const ccid3_rx_state_names[] = { [TFRC_RSTATE_NO_DATA] = "NO_DATA", [TFRC_RSTATE_DATA] = "DATA", - [TFRC_RSTATE_TERM] = "TERM", }; return ccid3_rx_state_names[state]; @@ -650,14 +595,9 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, { struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); struct dccp_sock *dp = dccp_sk(sk); - ktime_t now; + ktime_t now = ktime_get_real(); s64 delta = 0; - if (unlikely(hc->rx_state == TFRC_RSTATE_TERM)) - return; - - now = ktime_get_real(); - switch (fbtype) { case CCID3_FBACK_INITIAL: hc->rx_x_recv = 0; @@ -701,14 +641,12 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk, static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb) { - const struct ccid3_hc_rx_sock *hc; + const struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); __be32 x_recv, pinv; if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)) return 0; - hc = ccid3_hc_rx_sk(sk); - if (dccp_packet_without_ack(skb)) return 0; @@ -749,10 +687,11 @@ static u32 ccid3_first_li(struct sock *sk) x_recv = scaled_div32(hc->rx_bytes_recv, delta); if (x_recv == 0) { /* would also trigger divide-by-zero */ DCCP_WARN("X_recv==0\n"); - if ((x_recv = hc->rx_x_recv) == 0) { + if (hc->rx_x_recv == 0) { DCCP_BUG("stored value of X_recv is zero"); return ~0U; } + x_recv = hc->rx_x_recv; } fval = scaled_div(hc->rx_s, hc->rx_rtt); @@ -862,46 +801,31 @@ static void ccid3_hc_rx_exit(struct sock *sk) { struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); - ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM); - tfrc_rx_hist_purge(&hc->rx_hist); tfrc_lh_cleanup(&hc->rx_li_hist); } static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) { - const struct ccid3_hc_rx_sock *hc; - - /* Listen socks doesn't have a private CCID block */ - if (sk->sk_state == DCCP_LISTEN) - return; - - hc = ccid3_hc_rx_sk(sk); - info->tcpi_ca_state = hc->rx_state; + info->tcpi_ca_state = ccid3_hc_rx_sk(sk)->rx_state; info->tcpi_options |= TCPI_OPT_TIMESTAMPS; - info->tcpi_rcv_rtt = hc->rx_rtt; + info->tcpi_rcv_rtt = ccid3_hc_rx_sk(sk)->rx_rtt; } static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len, u32 __user *optval, int __user *optlen) { - const struct ccid3_hc_rx_sock *hc; + const struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); struct tfrc_rx_info rx_info; const void *val; - /* Listen socks doesn't have a private CCID block */ - if (sk->sk_state == DCCP_LISTEN) - return -EINVAL; - - hc = ccid3_hc_rx_sk(sk); switch (optname) { case DCCP_SOCKOPT_CCID_RX_INFO: if (len < sizeof(rx_info)) return -EINVAL; rx_info.tfrcrx_x_recv = hc->rx_x_recv; rx_info.tfrcrx_rtt = hc->rx_rtt; - rx_info.tfrcrx_p = hc->rx_pinv == 0 ? ~0U : - scaled_div(1, hc->rx_pinv); + rx_info.tfrcrx_p = tfrc_invert_loss_event_rate(hc->rx_pinv); len = sizeof(rx_info); val = &rx_info; break; diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h index 03263577665323894733d7d59febb18b556fa49d..1a9933c29672bfa3d1e8396a33437a5712970b5d 100644 --- a/net/dccp/ccids/ccid3.h +++ b/net/dccp/ccids/ccid3.h @@ -42,35 +42,36 @@ #include "lib/tfrc.h" #include "../ccid.h" -/* Two seconds as per RFC 3448 4.2 */ +/* Two seconds as per RFC 5348, 4.2 */ #define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC) -/* In usecs - half the scheduling granularity as per RFC3448 4.6 */ -#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ)) - /* Parameter t_mbi from [RFC 3448, 4.3]: backoff interval in seconds */ #define TFRC_T_MBI 64 +/* + * The t_delta parameter (RFC 5348, 8.3): delays of less than %USEC_PER_MSEC are + * rounded down to 0, since sk_reset_timer() here uses millisecond granularity. + * Hence we can use a constant t_delta = %USEC_PER_MSEC when HZ >= 500. A coarse + * resolution of HZ < 500 means that the error is below one timer tick (t_gran) + * when using the constant t_delta = t_gran / 2 = %USEC_PER_SEC / (2 * HZ). + */ +#if (HZ >= 500) +# define TFRC_T_DELTA USEC_PER_MSEC +#else +# define TFRC_T_DELTA (USEC_PER_SEC / (2 * HZ)) +#endif + enum ccid3_options { TFRC_OPT_LOSS_EVENT_RATE = 192, TFRC_OPT_LOSS_INTERVALS = 193, TFRC_OPT_RECEIVE_RATE = 194, }; -struct ccid3_options_received { - u64 ccid3or_seqno:48, - ccid3or_loss_intervals_idx:16; - u16 ccid3or_loss_intervals_len; - u32 ccid3or_loss_event_rate; - u32 ccid3or_receive_rate; -}; - /* TFRC sender states */ enum ccid3_hc_tx_states { TFRC_SSTATE_NO_SENT = 1, TFRC_SSTATE_NO_FBACK, TFRC_SSTATE_FBACK, - TFRC_SSTATE_TERM, }; /** @@ -90,19 +91,16 @@ enum ccid3_hc_tx_states { * @tx_no_feedback_timer: Handle to no feedback timer * @tx_t_ld: Time last doubled during slow start * @tx_t_nom: Nominal send time of next packet - * @tx_delta: Send timer delta (RFC 3448, 4.6) in usecs * @tx_hist: Packet history - * @tx_options_received: Parsed set of retrieved options */ struct ccid3_hc_tx_sock { - struct tfrc_tx_info tx_tfrc; -#define tx_x tx_tfrc.tfrctx_x -#define tx_x_recv tx_tfrc.tfrctx_x_recv -#define tx_x_calc tx_tfrc.tfrctx_x_calc -#define tx_rtt tx_tfrc.tfrctx_rtt -#define tx_p tx_tfrc.tfrctx_p -#define tx_t_rto tx_tfrc.tfrctx_rto -#define tx_t_ipi tx_tfrc.tfrctx_ipi + u64 tx_x; + u64 tx_x_recv; + u32 tx_x_calc; + u32 tx_rtt; + u32 tx_p; + u32 tx_t_rto; + u32 tx_t_ipi; u16 tx_s; enum ccid3_hc_tx_states tx_state:8; u8 tx_last_win_count; @@ -110,9 +108,7 @@ struct ccid3_hc_tx_sock { struct timer_list tx_no_feedback_timer; ktime_t tx_t_ld; ktime_t tx_t_nom; - u32 tx_delta; struct tfrc_tx_hist_entry *tx_hist; - struct ccid3_options_received tx_options_received; }; static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) @@ -126,21 +122,16 @@ static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) enum ccid3_hc_rx_states { TFRC_RSTATE_NO_DATA = 1, TFRC_RSTATE_DATA, - TFRC_RSTATE_TERM = 127, }; /** * struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket - * @rx_x_recv: Receiver estimate of send rate (RFC 3448 4.3) - * @rx_rtt: Receiver estimate of rtt (non-standard) - * @rx_p: Current loss event rate (RFC 3448 5.4) * @rx_last_counter: Tracks window counter (RFC 4342, 8.1) * @rx_state: Receiver state, one of %ccid3_hc_rx_states * @rx_bytes_recv: Total sum of DCCP payload bytes * @rx_x_recv: Receiver estimate of send rate (RFC 3448, sec. 4.3) * @rx_rtt: Receiver estimate of RTT * @rx_tstamp_last_feedback: Time at which last feedback was sent - * @rx_tstamp_last_ack: Time at which last feedback was sent * @rx_hist: Packet history (loss detection + RTT sampling) * @rx_li_hist: Loss Interval database * @rx_s: Received packet size in bytes diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c index 8fc3cbf79071fdc7dc904d154864b007f9768a42..497723c4d4bbccf1a584230d99739a2799f80932 100644 --- a/net/dccp/ccids/lib/loss_interval.c +++ b/net/dccp/ccids/lib/loss_interval.c @@ -116,7 +116,7 @@ u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb) cur->li_length = len; tfrc_lh_calc_i_mean(lh); - return (lh->i_mean < old_i_mean); + return lh->i_mean < old_i_mean; } /* Determine if `new_loss' does begin a new loss interval [RFC 4342, 10.2] */ diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c index 3a4f414e94a0051bf66429739680d3d5ee8fb432..de8fe294bf0bccfce4d865ea15590162e1225e06 100644 --- a/net/dccp/ccids/lib/packet_history.c +++ b/net/dccp/ccids/lib/packet_history.c @@ -38,18 +38,6 @@ #include "packet_history.h" #include "../../dccp.h" -/** - * tfrc_tx_hist_entry - Simple singly-linked TX history list - * @next: next oldest entry (LIFO order) - * @seqno: sequence number of this entry - * @stamp: send time of packet with sequence number @seqno - */ -struct tfrc_tx_hist_entry { - struct tfrc_tx_hist_entry *next; - u64 seqno; - ktime_t stamp; -}; - /* * Transmitter History Routines */ @@ -71,15 +59,6 @@ void tfrc_tx_packet_history_exit(void) } } -static struct tfrc_tx_hist_entry * - tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno) -{ - while (head != NULL && head->seqno != seqno) - head = head->next; - - return head; -} - int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno) { struct tfrc_tx_hist_entry *entry = kmem_cache_alloc(tfrc_tx_hist_slab, gfp_any()); @@ -107,24 +86,6 @@ void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp) *headp = NULL; } -u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, const u64 seqno, - const ktime_t now) -{ - u32 rtt = 0; - struct tfrc_tx_hist_entry *packet = tfrc_tx_hist_find_entry(head, seqno); - - if (packet != NULL) { - rtt = ktime_us_delta(now, packet->stamp); - /* - * Garbage-collect older (irrelevant) entries: - */ - tfrc_tx_hist_purge(&packet->next); - } - - return rtt; -} - - /* * Receiver History Routines */ diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h index 7df6c52999999a4c76c99802d0dbcf54a8654211..7ee4a9d9d3352337bb5e899d214a754b740ac8c0 100644 --- a/net/dccp/ccids/lib/packet_history.h +++ b/net/dccp/ccids/lib/packet_history.h @@ -40,12 +40,28 @@ #include #include "tfrc.h" -struct tfrc_tx_hist_entry; +/** + * tfrc_tx_hist_entry - Simple singly-linked TX history list + * @next: next oldest entry (LIFO order) + * @seqno: sequence number of this entry + * @stamp: send time of packet with sequence number @seqno + */ +struct tfrc_tx_hist_entry { + struct tfrc_tx_hist_entry *next; + u64 seqno; + ktime_t stamp; +}; + +static inline struct tfrc_tx_hist_entry * + tfrc_tx_hist_find_entry(struct tfrc_tx_hist_entry *head, u64 seqno) +{ + while (head != NULL && head->seqno != seqno) + head = head->next; + return head; +} extern int tfrc_tx_hist_add(struct tfrc_tx_hist_entry **headp, u64 seqno); extern void tfrc_tx_hist_purge(struct tfrc_tx_hist_entry **headp); -extern u32 tfrc_tx_hist_rtt(struct tfrc_tx_hist_entry *head, - const u64 seqno, const ktime_t now); /* Subtraction a-b modulo-16, respects circular wrap-around */ #define SUB16(a, b) (((a) + 16 - (b)) & 0xF) diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h index 01bb48e96c2ed0b6955c50ee348817e1415f61fd..f8ee3f5497702c300c43c6529358c4dd5ee137f3 100644 --- a/net/dccp/ccids/lib/tfrc.h +++ b/net/dccp/ccids/lib/tfrc.h @@ -57,6 +57,7 @@ static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight) extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); +extern u32 tfrc_invert_loss_event_rate(u32 loss_event_rate); extern int tfrc_tx_packet_history_init(void); extern void tfrc_tx_packet_history_exit(void); diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c index 22ca1cf0eb5503fe6ed2db69172771f0e207b182..a052a4377e262a6f2e1af8e354cfd649f006e343 100644 --- a/net/dccp/ccids/lib/tfrc_equation.c +++ b/net/dccp/ccids/lib/tfrc_equation.c @@ -687,3 +687,17 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue) index = tfrc_binsearch(fvalue, 0); return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE; } + +/** + * tfrc_invert_loss_event_rate - Compute p so that 10^6 corresponds to 100% + * When @loss_event_rate is large, there is a chance that p is truncated to 0. + * To avoid re-entering slow-start in that case, we set p = TFRC_SMALLEST_P > 0. + */ +u32 tfrc_invert_loss_event_rate(u32 loss_event_rate) +{ + if (loss_event_rate == UINT_MAX) /* see RFC 4342, 8.5 */ + return 0; + if (unlikely(loss_event_rate == 0)) /* map 1/0 into 100% */ + return 1000000; + return max_t(u32, scaled_div(1, loss_event_rate), TFRC_SMALLEST_P); +} diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index 3ccef1b70feef57556f6b5a71c6ed84bc1a12f02..3eb264b608239c74c16d27625cc4b3b5199a3ef8 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h @@ -153,18 +153,27 @@ static inline u64 max48(const u64 seq1, const u64 seq2) } /** - * dccp_loss_free - Evaluates condition for data loss from RFC 4340, 7.7.1 - * @s1: start sequence number - * @s2: end sequence number + * dccp_loss_count - Approximate the number of lost data packets in a burst loss + * @s1: last known sequence number before the loss ('hole') + * @s2: first sequence number seen after the 'hole' * @ndp: NDP count on packet with sequence number @s2 - * Returns true if the sequence range s1...s2 has no data loss. */ -static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp) +static inline u64 dccp_loss_count(const u64 s1, const u64 s2, const u64 ndp) { s64 delta = dccp_delta_seqno(s1, s2); WARN_ON(delta < 0); - return (u64)delta <= ndp + 1; + delta -= ndp + 1; + + return delta > 0 ? delta : 0; +} + +/** + * dccp_loss_free - Evaluate condition for data loss from RFC 4340, 7.7.1 + */ +static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp) +{ + return dccp_loss_count(s1, s2, ndp) == 0; } enum { @@ -246,7 +255,6 @@ static inline void dccp_clear_xmit_timers(struct sock *sk) extern unsigned int dccp_sync_mss(struct sock *sk, u32 pmtu); extern const char *dccp_packet_name(const int type); -extern const char *dccp_state_name(const int state); extern void dccp_set_state(struct sock *sk, const int state); extern void dccp_done(struct sock *sk); @@ -415,6 +423,23 @@ static inline void dccp_update_gsr(struct sock *sk, u64 seq) dp->dccps_gsr = seq; /* Sequence validity window depends on remote Sequence Window (7.5.1) */ dp->dccps_swl = SUB48(ADD48(dp->dccps_gsr, 1), dp->dccps_r_seq_win / 4); + /* + * Adjust SWL so that it is not below ISR. In contrast to RFC 4340, + * 7.5.1 we perform this check beyond the initial handshake: W/W' are + * always > 32, so for the first W/W' packets in the lifetime of a + * connection we always have to adjust SWL. + * A second reason why we are doing this is that the window depends on + * the feature-remote value of Sequence Window: nothing stops the peer + * from updating this value while we are busy adjusting SWL for the + * first W packets (we would have to count from scratch again then). + * Therefore it is safer to always make sure that the Sequence Window + * is not artificially extended by a peer who grows SWL downwards by + * continually updating the feature-remote Sequence-Window. + * If sequence numbers wrap it is bad luck. But that will take a while + * (48 bit), and this measure prevents Sequence-number attacks. + */ + if (before48(dp->dccps_swl, dp->dccps_isr)) + dp->dccps_swl = dp->dccps_isr; dp->dccps_swh = ADD48(dp->dccps_gsr, (3 * dp->dccps_r_seq_win) / 4); } @@ -425,14 +450,16 @@ static inline void dccp_update_gss(struct sock *sk, u64 seq) dp->dccps_gss = seq; /* Ack validity window depends on local Sequence Window value (7.5.1) */ dp->dccps_awl = SUB48(ADD48(dp->dccps_gss, 1), dp->dccps_l_seq_win); + /* Adjust AWL so that it is not below ISS - see comment above for SWL */ + if (before48(dp->dccps_awl, dp->dccps_iss)) + dp->dccps_awl = dp->dccps_iss; dp->dccps_awh = dp->dccps_gss; } static inline int dccp_ack_pending(const struct sock *sk) { const struct dccp_sock *dp = dccp_sk(sk); - return dp->dccps_timestamp_echo != 0 || - (dp->dccps_hc_rx_ackvec != NULL && + return (dp->dccps_hc_rx_ackvec != NULL && dccp_ackvec_pending(dp->dccps_hc_rx_ackvec)) || inet_csk_ack_scheduled(sk); } @@ -449,7 +476,6 @@ extern int dccp_insert_options_rsk(struct dccp_request_sock*, struct sk_buff*); extern int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed); extern u32 dccp_timestamp(void); extern void dccp_timestamping_init(void); -extern int dccp_insert_option_timestamp(struct sk_buff *skb); extern int dccp_insert_option(struct sk_buff *skb, unsigned char option, const void *value, unsigned char len); diff --git a/net/dccp/feat.c b/net/dccp/feat.c index df7dd26cf07eb8c5fa131f2ce7aee8eb87f065e9..568def9527224d662bb3928b2a4258aafd2e0cfa 100644 --- a/net/dccp/feat.c +++ b/net/dccp/feat.c @@ -730,16 +730,6 @@ int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, 0, list, len); } -/* Analogous to dccp_feat_register_sp(), but for non-negotiable values */ -int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val) -{ - /* any changes must be registered before establishing the connection */ - if (sk->sk_state != DCCP_CLOSED) - return -EISCONN; - if (dccp_feat_type(feat) != FEAT_NN) - return -EINVAL; - return __feat_register_nn(&dccp_sk(sk)->dccps_featneg, feat, 0, val); -} /* * Tracking features whose value depend on the choice of CCID diff --git a/net/dccp/feat.h b/net/dccp/feat.h index f96721619defecb9d844fd56e5e9f3e9d65f6eb6..e56a4e5e634e61a2b0239c513c021f789e00f32c 100644 --- a/net/dccp/feat.h +++ b/net/dccp/feat.h @@ -111,7 +111,6 @@ extern int dccp_feat_init(struct sock *sk); extern void dccp_feat_initialise_sysctls(void); extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, u8 const *list, u8 len); -extern int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val); extern int dccp_feat_parse_options(struct sock *, struct dccp_request_sock *, u8 mand, u8 opt, u8 feat, u8 *val, u8 len); extern int dccp_feat_clone_list(struct list_head const *, struct list_head *); diff --git a/net/dccp/input.c b/net/dccp/input.c index 10c957a88f4f7c9c65da3cf2ba825686349c03f4..265985370fa1de664b1b7f3de427cb043fc74665 100644 --- a/net/dccp/input.c +++ b/net/dccp/input.c @@ -259,7 +259,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb) sysctl_dccp_sync_ratelimit))) return 0; - DCCP_WARN("DCCP: Step 6 failed for %s packet, " + DCCP_WARN("Step 6 failed for %s packet, " "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " "sending SYNC...\n", dccp_packet_name(dh->dccph_type), @@ -441,20 +441,14 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk, kfree_skb(sk->sk_send_head); sk->sk_send_head = NULL; - dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; - dccp_update_gsr(sk, dp->dccps_isr); /* - * SWL and AWL are initially adjusted so that they are not less than - * the initial Sequence Numbers received and sent, respectively: - * SWL := max(GSR + 1 - floor(W/4), ISR), - * AWL := max(GSS - W' + 1, ISS). - * These adjustments MUST be applied only at the beginning of the - * connection. - * - * AWL was adjusted in dccp_v4_connect -acme + * Set ISR, GSR from packet. ISS was set in dccp_v{4,6}_connect + * and GSS in dccp_transmit_skb(). Setting AWL/AWH and SWL/SWH + * is done as part of activating the feature values below, since + * these settings depend on the local/remote Sequence Window + * features, which were undefined or not confirmed until now. */ - dccp_set_seqno(&dp->dccps_swl, - max48(dp->dccps_swl, dp->dccps_isr)); + dp->dccps_gsr = dp->dccps_isr = DCCP_SKB_CB(skb)->dccpd_seq; dccp_sync_mss(sk, icsk->icsk_pmtu_cookie); diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index d4a166f0f391d6bfccd85471b2616057d808c848..3f69ea1148291ce2e5ad4956f4c27931d8db7e8f 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -392,7 +392,7 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb, newsk = dccp_create_openreq_child(sk, req, skb); if (newsk == NULL) - goto exit; + goto exit_nonewsk; sk_setup_caps(newsk, dst); @@ -409,16 +409,20 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb, dccp_sync_mss(newsk, dst_mtu(dst)); + if (__inet_inherit_port(sk, newsk) < 0) { + sock_put(newsk); + goto exit; + } __inet_hash_nolisten(newsk, NULL); - __inet_inherit_port(sk, newsk); return newsk; exit_overflow: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); +exit_nonewsk: + dst_release(dst); exit: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); - dst_release(dst); return NULL; } diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 6e3f32575df78bbf75fc8e3cd46ea0cb52f4f771..dca711df9b60cea9e8ecf259cfdfc3909c60d3bb 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c @@ -564,7 +564,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, newsk = dccp_create_openreq_child(sk, req, skb); if (newsk == NULL) - goto out; + goto out_nonewsk; /* * No need to charge this sock to the relevant IPv6 refcnt debug socks @@ -632,18 +632,22 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6; newinet->inet_rcv_saddr = LOOPBACK4_IPV6; + if (__inet_inherit_port(sk, newsk) < 0) { + sock_put(newsk); + goto out; + } __inet6_hash(newsk, NULL); - __inet_inherit_port(sk, newsk); return newsk; out_overflow: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); +out_nonewsk: + dst_release(dst); out: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); if (opt != NULL && opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); - dst_release(dst); return NULL; } diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c index 128b089d3aefb0d05f7899a240ad3ced0a708d33..d7041a0963af9588142133187c28e7c3a9abc215 100644 --- a/net/dccp/minisocks.c +++ b/net/dccp/minisocks.c @@ -121,30 +121,18 @@ struct sock *dccp_create_openreq_child(struct sock *sk, * * Choose S.ISS (initial seqno) or set from Init Cookies * Initialize S.GAR := S.ISS - * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies - */ - newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss; - dccp_update_gss(newsk, dreq->dreq_iss); - - newdp->dccps_isr = dreq->dreq_isr; - dccp_update_gsr(newsk, dreq->dreq_isr); - - /* - * SWL and AWL are initially adjusted so that they are not less than - * the initial Sequence Numbers received and sent, respectively: - * SWL := max(GSR + 1 - floor(W/4), ISR), - * AWL := max(GSS - W' + 1, ISS). - * These adjustments MUST be applied only at the beginning of the - * connection. + * Set S.ISR, S.GSR from packet (or Init Cookies) + * + * Setting AWL/AWH and SWL/SWH happens as part of the feature + * activation below, as these windows all depend on the local + * and remote Sequence Window feature values (7.5.2). */ - dccp_set_seqno(&newdp->dccps_swl, - max48(newdp->dccps_swl, newdp->dccps_isr)); - dccp_set_seqno(&newdp->dccps_awl, - max48(newdp->dccps_awl, newdp->dccps_iss)); + newdp->dccps_gss = newdp->dccps_iss = dreq->dreq_iss; + newdp->dccps_gar = newdp->dccps_iss; + newdp->dccps_gsr = newdp->dccps_isr = dreq->dreq_isr; /* - * Activate features after initialising the sequence numbers, - * since CCID initialisation may depend on GSS, ISR, ISS etc. + * Activate features: initialise CCIDs, sequence windows etc. */ if (dccp_feat_activate_values(newsk, &dreq->dreq_featneg)) { /* It is still raw copy of parent, so invalidate diff --git a/net/dccp/options.c b/net/dccp/options.c index bfda087bd90dd792f8190840878379d304152c1d..cd306181300940f924b682c9f77e5881323ce6a0 100644 --- a/net/dccp/options.c +++ b/net/dccp/options.c @@ -96,18 +96,11 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, } /* - * CCID-Specific Options (from RFC 4340, sec. 10.3): - * - * Option numbers 128 through 191 are for options sent from the - * HC-Sender to the HC-Receiver; option numbers 192 through 255 - * are for options sent from the HC-Receiver to the HC-Sender. - * * CCID-specific options are ignored during connection setup, as * negotiation may still be in progress (see RFC 4340, 10.3). * The same applies to Ack Vectors, as these depend on the CCID. - * */ - if (dreq != NULL && (opt >= 128 || + if (dreq != NULL && (opt >= DCCPO_MIN_RX_CCID_SPECIFIC || opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1)) goto ignore_option; @@ -170,6 +163,8 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, dccp_role(sk), ntohl(opt_val), (unsigned long long) DCCP_SKB_CB(skb)->dccpd_ack_seq); + /* schedule an Ack in case this sender is quiescent */ + inet_csk_schedule_ack(sk); break; case DCCPO_TIMESTAMP_ECHO: if (len != 4 && len != 6 && len != 8) @@ -226,23 +221,15 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", dccp_role(sk), elapsed_time); break; - case 128 ... 191: { - const u16 idx = value - options; - + case DCCPO_MIN_RX_CCID_SPECIFIC ... DCCPO_MAX_RX_CCID_SPECIFIC: if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, - opt, len, idx, - value) != 0) + pkt_type, opt, value, len)) goto out_invalid_option; - } break; - case 192 ... 255: { - const u16 idx = value - options; - + case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC: if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, - opt, len, idx, - value) != 0) + pkt_type, opt, value, len)) goto out_invalid_option; - } break; default: DCCP_CRIT("DCCP(%p): option %d(len=%d) not " @@ -384,7 +371,7 @@ int dccp_insert_option_elapsed_time(struct sk_buff *skb, u32 elapsed_time) EXPORT_SYMBOL_GPL(dccp_insert_option_elapsed_time); -int dccp_insert_option_timestamp(struct sk_buff *skb) +static int dccp_insert_option_timestamp(struct sk_buff *skb) { __be32 now = htonl(dccp_timestamp()); /* yes this will overflow but that is the point as we want a @@ -393,8 +380,6 @@ int dccp_insert_option_timestamp(struct sk_buff *skb) return dccp_insert_option(skb, DCCPO_TIMESTAMP, &now, sizeof(now)); } -EXPORT_SYMBOL_GPL(dccp_insert_option_timestamp); - static int dccp_insert_option_timestamp_echo(struct dccp_sock *dp, struct dccp_request_sock *dreq, struct sk_buff *skb) diff --git a/net/dccp/output.c b/net/dccp/output.c index aadbdb58758b754b2d712c6632b7457865f0a2cf..a988fe9ffcbafdf74b6e90b24f4e8b8caa57591d 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -304,7 +304,7 @@ void dccp_write_xmit(struct sock *sk, int block) dcb->dccpd_type = DCCP_PKT_DATA; err = dccp_transmit_skb(sk, skb); - ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len); + ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, len); if (err) DCCP_BUG("err=%d after ccid_hc_tx_packet_sent", err); @@ -474,8 +474,9 @@ int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code) /* * Do all connect socket setups that can be done AF independent. */ -static inline void dccp_connect_init(struct sock *sk) +int dccp_connect(struct sock *sk) { + struct sk_buff *skb; struct dccp_sock *dp = dccp_sk(sk); struct dst_entry *dst = __sk_dst_get(sk); struct inet_connection_sock *icsk = inet_csk(sk); @@ -485,22 +486,12 @@ static inline void dccp_connect_init(struct sock *sk) dccp_sync_mss(sk, dst_mtu(dst)); - /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */ - dp->dccps_gar = dp->dccps_iss; - - icsk->icsk_retransmits = 0; -} - -int dccp_connect(struct sock *sk) -{ - struct sk_buff *skb; - struct inet_connection_sock *icsk = inet_csk(sk); - /* do not connect if feature negotiation setup fails */ if (dccp_feat_finalise_settings(dccp_sk(sk))) return -EPROTO; - dccp_connect_init(sk); + /* Initialise GAR as per 8.5; AWL/AWH are set in dccp_transmit_skb() */ + dp->dccps_gar = dp->dccps_iss; skb = alloc_skb(sk->sk_prot->max_header, sk->sk_allocation); if (unlikely(skb == NULL)) @@ -516,6 +507,7 @@ int dccp_connect(struct sock *sk) DCCP_INC_STATS(DCCP_MIB_ACTIVEOPENS); /* Timer for repeating the REQUEST until an answer. */ + icsk->icsk_retransmits = 0; inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, DCCP_RTO_MAX); return 0; diff --git a/net/dccp/proto.c b/net/dccp/proto.c index 096250d1323b9960c0a73d449c9b6589077e7015..7e5fc04eb6d1989986b7c7241f0e5cb2106ce4d8 100644 --- a/net/dccp/proto.c +++ b/net/dccp/proto.c @@ -50,6 +50,30 @@ EXPORT_SYMBOL_GPL(dccp_hashinfo); /* the maximum queue length for tx in packets. 0 is no limit */ int sysctl_dccp_tx_qlen __read_mostly = 5; +#ifdef CONFIG_IP_DCCP_DEBUG +static const char *dccp_state_name(const int state) +{ + static const char *const dccp_state_names[] = { + [DCCP_OPEN] = "OPEN", + [DCCP_REQUESTING] = "REQUESTING", + [DCCP_PARTOPEN] = "PARTOPEN", + [DCCP_LISTEN] = "LISTEN", + [DCCP_RESPOND] = "RESPOND", + [DCCP_CLOSING] = "CLOSING", + [DCCP_ACTIVE_CLOSEREQ] = "CLOSEREQ", + [DCCP_PASSIVE_CLOSE] = "PASSIVE_CLOSE", + [DCCP_PASSIVE_CLOSEREQ] = "PASSIVE_CLOSEREQ", + [DCCP_TIME_WAIT] = "TIME_WAIT", + [DCCP_CLOSED] = "CLOSED", + }; + + if (state >= DCCP_MAX_STATES) + return "INVALID STATE!"; + else + return dccp_state_names[state]; +} +#endif + void dccp_set_state(struct sock *sk, const int state) { const int oldstate = sk->sk_state; @@ -146,30 +170,6 @@ const char *dccp_packet_name(const int type) EXPORT_SYMBOL_GPL(dccp_packet_name); -const char *dccp_state_name(const int state) -{ - static const char *const dccp_state_names[] = { - [DCCP_OPEN] = "OPEN", - [DCCP_REQUESTING] = "REQUESTING", - [DCCP_PARTOPEN] = "PARTOPEN", - [DCCP_LISTEN] = "LISTEN", - [DCCP_RESPOND] = "RESPOND", - [DCCP_CLOSING] = "CLOSING", - [DCCP_ACTIVE_CLOSEREQ] = "CLOSEREQ", - [DCCP_PASSIVE_CLOSE] = "PASSIVE_CLOSE", - [DCCP_PASSIVE_CLOSEREQ] = "PASSIVE_CLOSEREQ", - [DCCP_TIME_WAIT] = "TIME_WAIT", - [DCCP_CLOSED] = "CLOSED", - }; - - if (state >= DCCP_MAX_STATES) - return "INVALID STATE!"; - else - return dccp_state_names[state]; -} - -EXPORT_SYMBOL_GPL(dccp_state_name); - int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) { struct dccp_sock *dp = dccp_sk(sk); @@ -944,7 +944,7 @@ void dccp_close(struct sock *sk, long timeout) if (data_was_unread) { /* Unread data was tossed, send an appropriate Reset Code */ - DCCP_WARN("DCCP: ABORT -- %u bytes unread\n", data_was_unread); + DCCP_WARN("ABORT with %u bytes unread\n", data_was_unread); dccp_send_reset(sk, DCCP_RESET_CODE_ABORTED); dccp_set_state(sk, DCCP_CLOSED); } else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 0363bb95cc7db606d45dd08bac34340ba48a3a84..a085dbcf5c7fa4fde69419dd135c8c8570bb4fb2 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -48,7 +48,6 @@ #include #include -static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev); static int dn_neigh_construct(struct neighbour *); static void dn_long_error_report(struct neighbour *, struct sk_buff *); static void dn_short_error_report(struct neighbour *, struct sk_buff *); @@ -93,6 +92,13 @@ static const struct neigh_ops dn_phase3_ops = { .queue_xmit = dev_queue_xmit }; +static u32 dn_neigh_hash(const void *pkey, + const struct net_device *dev, + __u32 hash_rnd) +{ + return jhash_2words(*(__u16 *)pkey, 0, hash_rnd); +} + struct neigh_table dn_neigh_table = { .family = PF_DECnet, .entry_size = sizeof(struct dn_neigh), @@ -122,11 +128,6 @@ struct neigh_table dn_neigh_table = { .gc_thresh3 = 1024, }; -static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev) -{ - return jhash_2words(*(__u16 *)pkey, 0, dn_neigh_table.hash_rnd); -} - static int dn_neigh_construct(struct neighbour *neigh) { struct net_device *dev = neigh->dev; diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index baeb1eaf011be83a0dff59717f54e30241e4f0ad..2ef115277bea86a68e644a6c004690ccdb807184 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c @@ -693,22 +693,22 @@ void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg) aux = scp->accessdata.acc_userl; *skb_put(skb, 1) = aux; if (aux > 0) - memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux); + memcpy(skb_put(skb, aux), scp->accessdata.acc_user, aux); aux = scp->accessdata.acc_passl; *skb_put(skb, 1) = aux; if (aux > 0) - memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux); + memcpy(skb_put(skb, aux), scp->accessdata.acc_pass, aux); aux = scp->accessdata.acc_accl; *skb_put(skb, 1) = aux; if (aux > 0) - memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux); + memcpy(skb_put(skb, aux), scp->accessdata.acc_acc, aux); aux = (__u8)le16_to_cpu(scp->conndata_out.opt_optl); *skb_put(skb, 1) = aux; if (aux > 0) - memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux); + memcpy(skb_put(skb, aux), scp->conndata_out.opt_data, aux); scp->persist = dn_nsp_persist(sk); scp->persist_fxn = dn_nsp_retrans_conninit; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 6585ea6d1182798ef399c61950e06044b5180027..df0f3e54ff8aba58dac157ab2b2c866453437310 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -132,7 +132,6 @@ static struct dst_ops dn_dst_ops = { .negative_advice = dn_dst_negative_advice, .link_failure = dn_dst_link_failure, .update_pmtu = dn_dst_update_pmtu, - .entries = ATOMIC_INIT(0), }; static __inline__ unsigned dn_hash(__le16 src, __le16 dst) @@ -1758,6 +1757,7 @@ void __init dn_route_init(void) dn_dst_ops.kmem_cachep = kmem_cache_create("dn_dst_cache", sizeof(struct dn_route), 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); + dst_entries_init(&dn_dst_ops); setup_timer(&dn_route_timer, dn_dst_check_expire, 0); dn_route_timer.expires = jiffies + decnet_dst_gc_interval * HZ; add_timer(&dn_route_timer); @@ -1816,5 +1816,6 @@ void __exit dn_route_cleanup(void) dn_run_flush(0); proc_net_remove(&init_net, "decnet_cache"); + dst_entries_destroy(&dn_dst_ops); } diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index dc54bd0d083ba63f9cdec105d38d05d304007357..f8c1ae4b41f03641f7bb7db11feb88893df65519 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c @@ -392,7 +392,7 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock, dev_queue_xmit(skb); dev_put(dev); mutex_unlock(&econet_mutex); - return(len); + return len; out_free: kfree_skb(skb); @@ -637,7 +637,7 @@ static int econet_create(struct net *net, struct socket *sock, int protocol, eo->num = protocol; econet_insert_socket(&econet_sklist, sk); - return(0); + return 0; out: return err; } @@ -1009,7 +1009,6 @@ static int __init aun_udp_initialise(void) struct sockaddr_in sin; skb_queue_head_init(&aun_queue); - spin_lock_init(&aun_queue_lock); setup_timer(&ab_cleanup_timer, ab_cleanup, 0); ab_cleanup_timer.expires = jiffies + (HZ*2); add_timer(&ab_cleanup_timer); @@ -1167,7 +1166,6 @@ static int __init econet_proto_init(void) goto out; sock_register(&econet_family_ops); #ifdef CONFIG_ECONET_AUNUDP - spin_lock_init(&aun_queue_lock); aun_udp_initialise(); #endif #ifdef CONFIG_ECONET_NATIVE diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 215c83986a9d4562f472a07e05bbbf607c56bbb0..f00ef2f1d814ebb2494c50b80a5464833d3e8eec 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -367,7 +367,7 @@ struct net_device *alloc_etherdev_mq(int sizeof_priv, unsigned int queue_count) EXPORT_SYMBOL(alloc_etherdev_mq); static size_t _format_mac_addr(char *buf, int buflen, - const unsigned char *addr, int len) + const unsigned char *addr, int len) { int i; char *cp = buf; @@ -376,7 +376,7 @@ static size_t _format_mac_addr(char *buf, int buflen, cp += scnprintf(cp, buflen - (cp - buf), "%02x", addr[i]); if (i == len - 1) break; - cp += strlcpy(cp, ":", buflen - (cp - buf)); + cp += scnprintf(cp, buflen - (cp - buf), ":"); } return cp - buf; } @@ -386,7 +386,7 @@ ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len) size_t l; l = _format_mac_addr(buf, PAGE_SIZE, addr, len); - l += strlcpy(buf + l, "\n", PAGE_SIZE - l); - return ((ssize_t) l); + l += scnprintf(buf + l, PAGE_SIZE - l, "\n"); + return (ssize_t)l; } EXPORT_SYMBOL(sysfs_format_mac); diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 7cd7760144f7dd1998276f4e2976e4a4a1c8135d..e848e6c062cddbc29d8b846227476f778a20e6ab 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -215,9 +215,15 @@ config NET_IPIP be inserted in and removed from the running kernel whenever you want). Most people won't need this and can say N. +config NET_IPGRE_DEMUX + tristate "IP: GRE demultiplexer" + help + This is helper module to demultiplex GRE packets on GRE version field criteria. + Required by ip_gre and pptp modules. + config NET_IPGRE tristate "IP: GRE tunnels over IP" - depends on IPV6 || IPV6=n + depends on (IPV6 || IPV6=n) && NET_IPGRE_DEMUX help Tunneling means encapsulating data of one protocol type within another protocol and sending it over a channel that understands the diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile index 80ff87ce43aac6a350bbe8e973f91e8eb58e14e9..4978d22f9a75eafe3fe10d8cf93f6e8a2a7f647a 100644 --- a/net/ipv4/Makefile +++ b/net/ipv4/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_IP_MULTIPLE_TABLES) += fib_rules.o obj-$(CONFIG_IP_MROUTE) += ipmr.o obj-$(CONFIG_NET_IPIP) += ipip.o +obj-$(CONFIG_NET_IPGRE_DEMUX) += gre.o obj-$(CONFIG_NET_IPGRE) += ip_gre.o obj-$(CONFIG_SYN_COOKIES) += syncookies.o obj-$(CONFIG_INET_AH) += ah4.o diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 6a1100c25a9f881f204934b1687b422384527f9a..f581f77d1097ca140c74e93072113d88ae0cc9bc 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -227,18 +227,16 @@ EXPORT_SYMBOL(inet_ehash_secret); /* * inet_ehash_secret must be set exactly once - * Instead of using a dedicated spinlock, we (ab)use inetsw_lock */ void build_ehash_secret(void) { u32 rnd; + do { get_random_bytes(&rnd, sizeof(rnd)); } while (rnd == 0); - spin_lock_bh(&inetsw_lock); - if (!inet_ehash_secret) - inet_ehash_secret = rnd; - spin_unlock_bh(&inetsw_lock); + + cmpxchg(&inet_ehash_secret, 0, rnd); } EXPORT_SYMBOL(build_ehash_secret); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 96c1955b3e2f5b47181c6fe331b581fc161baf27..d8e540c5b0710327fd44c8f269eb51e6fcfedfc5 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -55,7 +55,7 @@ * Stuart Cheshire : Metricom and grat arp fixes * *** FOR 2.1 clean this up *** * Lawrence V. Stefani: (08/12/96) Added FDDI support. - * Alan Cox : Took the AP1000 nasty FDDI hack and + * Alan Cox : Took the AP1000 nasty FDDI hack and * folded into the mainstream FDDI code. * Ack spit, Linus how did you allow that * one in... @@ -120,14 +120,14 @@ EXPORT_SYMBOL(clip_tbl_hook); #endif #include -#include +#include #include /* * Interface to generic neighbour cache. */ -static u32 arp_hash(const void *pkey, const struct net_device *dev); +static u32 arp_hash(const void *pkey, const struct net_device *dev, __u32 rnd); static int arp_constructor(struct neighbour *neigh); static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb); static void arp_error_report(struct neighbour *neigh, struct sk_buff *skb); @@ -161,7 +161,7 @@ static const struct neigh_ops arp_direct_ops = { .queue_xmit = dev_queue_xmit, }; -const struct neigh_ops arp_broken_ops = { +static const struct neigh_ops arp_broken_ops = { .family = AF_INET, .solicit = arp_solicit, .error_report = arp_error_report, @@ -170,35 +170,34 @@ const struct neigh_ops arp_broken_ops = { .hh_output = dev_queue_xmit, .queue_xmit = dev_queue_xmit, }; -EXPORT_SYMBOL(arp_broken_ops); struct neigh_table arp_tbl = { - .family = AF_INET, - .entry_size = sizeof(struct neighbour) + 4, - .key_len = 4, - .hash = arp_hash, - .constructor = arp_constructor, - .proxy_redo = parp_redo, - .id = "arp_cache", - .parms = { - .tbl = &arp_tbl, - .base_reachable_time = 30 * HZ, - .retrans_time = 1 * HZ, - .gc_staletime = 60 * HZ, - .reachable_time = 30 * HZ, - .delay_probe_time = 5 * HZ, - .queue_len = 3, - .ucast_probes = 3, - .mcast_probes = 3, - .anycast_delay = 1 * HZ, - .proxy_delay = (8 * HZ) / 10, - .proxy_qlen = 64, - .locktime = 1 * HZ, + .family = AF_INET, + .entry_size = sizeof(struct neighbour) + 4, + .key_len = 4, + .hash = arp_hash, + .constructor = arp_constructor, + .proxy_redo = parp_redo, + .id = "arp_cache", + .parms = { + .tbl = &arp_tbl, + .base_reachable_time = 30 * HZ, + .retrans_time = 1 * HZ, + .gc_staletime = 60 * HZ, + .reachable_time = 30 * HZ, + .delay_probe_time = 5 * HZ, + .queue_len = 3, + .ucast_probes = 3, + .mcast_probes = 3, + .anycast_delay = 1 * HZ, + .proxy_delay = (8 * HZ) / 10, + .proxy_qlen = 64, + .locktime = 1 * HZ, }, - .gc_interval = 30 * HZ, - .gc_thresh1 = 128, - .gc_thresh2 = 512, - .gc_thresh3 = 1024, + .gc_interval = 30 * HZ, + .gc_thresh1 = 128, + .gc_thresh2 = 512, + .gc_thresh3 = 1024, }; EXPORT_SYMBOL(arp_tbl); @@ -226,14 +225,16 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir) } -static u32 arp_hash(const void *pkey, const struct net_device *dev) +static u32 arp_hash(const void *pkey, + const struct net_device *dev, + __u32 hash_rnd) { - return jhash_2words(*(u32 *)pkey, dev->ifindex, arp_tbl.hash_rnd); + return jhash_2words(*(u32 *)pkey, dev->ifindex, hash_rnd); } static int arp_constructor(struct neighbour *neigh) { - __be32 addr = *(__be32*)neigh->primary_key; + __be32 addr = *(__be32 *)neigh->primary_key; struct net_device *dev = neigh->dev; struct in_device *in_dev; struct neigh_parms *parms; @@ -296,16 +297,19 @@ static int arp_constructor(struct neighbour *neigh) neigh->ops = &arp_broken_ops; neigh->output = neigh->ops->output; return 0; +#else + break; #endif - ;} + } #endif if (neigh->type == RTN_MULTICAST) { neigh->nud_state = NUD_NOARP; arp_mc_map(addr, neigh->ha, dev, 1); - } else if (dev->flags&(IFF_NOARP|IFF_LOOPBACK)) { + } else if (dev->flags & (IFF_NOARP | IFF_LOOPBACK)) { neigh->nud_state = NUD_NOARP; memcpy(neigh->ha, dev->dev_addr, dev->addr_len); - } else if (neigh->type == RTN_BROADCAST || dev->flags&IFF_POINTOPOINT) { + } else if (neigh->type == RTN_BROADCAST || + (dev->flags & IFF_POINTOPOINT)) { neigh->nud_state = NUD_NOARP; memcpy(neigh->ha, dev->broadcast, dev->addr_len); } @@ -315,7 +319,7 @@ static int arp_constructor(struct neighbour *neigh) else neigh->ops = &arp_generic_ops; - if (neigh->nud_state&NUD_VALID) + if (neigh->nud_state & NUD_VALID) neigh->output = neigh->ops->connected_output; else neigh->output = neigh->ops->output; @@ -334,7 +338,7 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) __be32 saddr = 0; u8 *dst_ha = NULL; struct net_device *dev = neigh->dev; - __be32 target = *(__be32*)neigh->primary_key; + __be32 target = *(__be32 *)neigh->primary_key; int probes = atomic_read(&neigh->probes); struct in_device *in_dev; @@ -347,7 +351,8 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) switch (IN_DEV_ARP_ANNOUNCE(in_dev)) { default: case 0: /* By default announce any local IP */ - if (skb && inet_addr_type(dev_net(dev), ip_hdr(skb)->saddr) == RTN_LOCAL) + if (skb && inet_addr_type(dev_net(dev), + ip_hdr(skb)->saddr) == RTN_LOCAL) saddr = ip_hdr(skb)->saddr; break; case 1: /* Restrict announcements of saddr in same subnet */ @@ -369,16 +374,21 @@ static void arp_solicit(struct neighbour *neigh, struct sk_buff *skb) if (!saddr) saddr = inet_select_addr(dev, target, RT_SCOPE_LINK); - if ((probes -= neigh->parms->ucast_probes) < 0) { - if (!(neigh->nud_state&NUD_VALID)) - printk(KERN_DEBUG "trying to ucast probe in NUD_INVALID\n"); + probes -= neigh->parms->ucast_probes; + if (probes < 0) { + if (!(neigh->nud_state & NUD_VALID)) + printk(KERN_DEBUG + "trying to ucast probe in NUD_INVALID\n"); dst_ha = neigh->ha; read_lock_bh(&neigh->lock); - } else if ((probes -= neigh->parms->app_probes) < 0) { + } else { + probes -= neigh->parms->app_probes; + if (probes < 0) { #ifdef CONFIG_ARPD - neigh_app_ns(neigh); + neigh_app_ns(neigh); #endif - return; + return; + } } arp_send(ARPOP_REQUEST, ETH_P_ARP, target, dev, saddr, @@ -451,7 +461,8 @@ static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) * is allowed to use this function, it is scheduled to be removed. --ANK */ -static int arp_set_predefined(int addr_hint, unsigned char * haddr, __be32 paddr, struct net_device * dev) +static int arp_set_predefined(int addr_hint, unsigned char *haddr, + __be32 paddr, struct net_device *dev) { switch (addr_hint) { case RTN_LOCAL: @@ -483,17 +494,16 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb) paddr = skb_rtable(skb)->rt_gateway; - if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev)) + if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, + paddr, dev)) return 0; n = __neigh_lookup(&arp_tbl, &paddr, dev, 1); if (n) { n->used = jiffies; - if (n->nud_state&NUD_VALID || neigh_event_send(n, skb) == 0) { - read_lock_bh(&n->lock); - memcpy(haddr, n->ha, dev->addr_len); - read_unlock_bh(&n->lock); + if (n->nud_state & NUD_VALID || neigh_event_send(n, skb) == 0) { + neigh_ha_snapshot(haddr, n, dev); neigh_release(n); return 0; } @@ -515,13 +525,14 @@ int arp_bind_neighbour(struct dst_entry *dst) return -EINVAL; if (n == NULL) { __be32 nexthop = ((struct rtable *)dst)->rt_gateway; - if (dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT)) + if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) nexthop = 0; n = __neigh_lookup_errno( #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) - dev->type == ARPHRD_ATM ? clip_tbl_hook : + dev->type == ARPHRD_ATM ? + clip_tbl_hook : #endif - &arp_tbl, &nexthop, dev); + &arp_tbl, &nexthop, dev); if (IS_ERR(n)) return PTR_ERR(n); dst->neighbour = n; @@ -543,8 +554,8 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, if (!IN_DEV_PROXY_ARP(in_dev)) return 0; - - if ((imi = IN_DEV_MEDIUM_ID(in_dev)) == 0) + imi = IN_DEV_MEDIUM_ID(in_dev); + if (imi == 0) return 1; if (imi == -1) return 0; @@ -555,7 +566,7 @@ static inline int arp_fwd_proxy(struct in_device *in_dev, if (out_dev) omi = IN_DEV_MEDIUM_ID(out_dev); - return (omi != imi && omi != -1); + return omi != imi && omi != -1; } /* @@ -685,7 +696,7 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, arp->ar_pln = 4; arp->ar_op = htons(type); - arp_ptr=(unsigned char *)(arp+1); + arp_ptr = (unsigned char *)(arp + 1); memcpy(arp_ptr, src_hw, dev->addr_len); arp_ptr += dev->addr_len; @@ -735,9 +746,8 @@ void arp_send(int type, int ptype, __be32 dest_ip, skb = arp_create(type, ptype, dest_ip, dev, src_ip, dest_hw, src_hw, target_hw); - if (skb == NULL) { + if (skb == NULL) return; - } arp_xmit(skb); } @@ -815,7 +825,7 @@ static int arp_process(struct sk_buff *skb) /* * Extract fields */ - arp_ptr= (unsigned char *)(arp+1); + arp_ptr = (unsigned char *)(arp + 1); sha = arp_ptr; arp_ptr += dev->addr_len; memcpy(&sip, arp_ptr, 4); @@ -869,16 +879,17 @@ static int arp_process(struct sk_buff *skb) addr_type = rt->rt_type; if (addr_type == RTN_LOCAL) { - int dont_send = 0; + int dont_send; - if (!dont_send) - dont_send |= arp_ignore(in_dev,sip,tip); + dont_send = arp_ignore(in_dev, sip, tip); if (!dont_send && IN_DEV_ARPFILTER(in_dev)) - dont_send |= arp_filter(sip,tip,dev); + dont_send |= arp_filter(sip, tip, dev); if (!dont_send) { n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) { - arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); + arp_send(ARPOP_REPLY, ETH_P_ARP, sip, + dev, tip, sha, dev->dev_addr, + sha); neigh_release(n); } } @@ -887,8 +898,7 @@ static int arp_process(struct sk_buff *skb) if (addr_type == RTN_UNICAST && (arp_fwd_proxy(in_dev, dev, rt) || arp_fwd_pvlan(in_dev, dev, rt, sip, tip) || - pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) - { + pneigh_lookup(&arp_tbl, net, &tip, dev, 0))) { n = neigh_event_ns(&arp_tbl, sha, &sip, dev); if (n) neigh_release(n); @@ -896,9 +906,12 @@ static int arp_process(struct sk_buff *skb) if (NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED || skb->pkt_type == PACKET_HOST || in_dev->arp_parms->proxy_delay == 0) { - arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); + arp_send(ARPOP_REPLY, ETH_P_ARP, sip, + dev, tip, sha, dev->dev_addr, + sha); } else { - pneigh_enqueue(&arp_tbl, in_dev->arp_parms, skb); + pneigh_enqueue(&arp_tbl, + in_dev->arp_parms, skb); return 0; } goto out; @@ -939,7 +952,8 @@ static int arp_process(struct sk_buff *skb) if (arp->ar_op != htons(ARPOP_REPLY) || skb->pkt_type != PACKET_HOST) state = NUD_STALE; - neigh_update(n, sha, state, override ? NEIGH_UPDATE_F_OVERRIDE : 0); + neigh_update(n, sha, state, + override ? NEIGH_UPDATE_F_OVERRIDE : 0); neigh_release(n); } @@ -975,7 +989,8 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev, arp->ar_pln != 4) goto freeskb; - if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + skb = skb_share_check(skb, GFP_ATOMIC); + if (skb == NULL) goto out_of_mem; memset(NEIGH_CB(skb), 0, sizeof(struct neighbour_cb)); @@ -1019,7 +1034,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r, return -EINVAL; if (!dev && (r->arp_flags & ATF_COM)) { dev = dev_getbyhwaddr(net, r->arp_ha.sa_family, - r->arp_ha.sa_data); + r->arp_ha.sa_data); if (!dev) return -ENODEV; } @@ -1033,7 +1048,7 @@ static int arp_req_set_public(struct net *net, struct arpreq *r, } static int arp_req_set(struct net *net, struct arpreq *r, - struct net_device * dev) + struct net_device *dev) { __be32 ip; struct neighbour *neigh; @@ -1046,10 +1061,11 @@ static int arp_req_set(struct net *net, struct arpreq *r, if (r->arp_flags & ATF_PERM) r->arp_flags |= ATF_COM; if (dev == NULL) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, - .tos = RTO_ONLINK } } }; - struct rtable * rt; - if ((err = ip_route_output_key(net, &rt, &fl)) != 0) + struct flowi fl = { .nl_u.ip4_u = { .daddr = ip, + .tos = RTO_ONLINK } }; + struct rtable *rt; + err = ip_route_output_key(net, &rt, &fl); + if (err != 0) return err; dev = rt->dst.dev; ip_rt_put(rt); @@ -1083,9 +1099,9 @@ static int arp_req_set(struct net *net, struct arpreq *r, unsigned state = NUD_STALE; if (r->arp_flags & ATF_PERM) state = NUD_PERMANENT; - err = neigh_update(neigh, (r->arp_flags&ATF_COM) ? + err = neigh_update(neigh, (r->arp_flags & ATF_COM) ? r->arp_ha.sa_data : NULL, state, - NEIGH_UPDATE_F_OVERRIDE| + NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN); neigh_release(neigh); } @@ -1094,12 +1110,12 @@ static int arp_req_set(struct net *net, struct arpreq *r, static unsigned arp_state_to_flags(struct neighbour *neigh) { - unsigned flags = 0; if (neigh->nud_state&NUD_PERMANENT) - flags = ATF_PERM|ATF_COM; + return ATF_PERM | ATF_COM; else if (neigh->nud_state&NUD_VALID) - flags = ATF_COM; - return flags; + return ATF_COM; + else + return 0; } /* @@ -1142,7 +1158,7 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r, } static int arp_req_delete(struct net *net, struct arpreq *r, - struct net_device * dev) + struct net_device *dev) { int err; __be32 ip; @@ -1153,10 +1169,11 @@ static int arp_req_delete(struct net *net, struct arpreq *r, ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; if (dev == NULL) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, - .tos = RTO_ONLINK } } }; - struct rtable * rt; - if ((err = ip_route_output_key(net, &rt, &fl)) != 0) + struct flowi fl = { .nl_u.ip4_u = { .daddr = ip, + .tos = RTO_ONLINK } }; + struct rtable *rt; + err = ip_route_output_key(net, &rt, &fl); + if (err != 0) return err; dev = rt->dst.dev; ip_rt_put(rt); @@ -1166,7 +1183,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r, err = -ENXIO; neigh = neigh_lookup(&arp_tbl, &ip, dev); if (neigh) { - if (neigh->nud_state&~NUD_NOARP) + if (neigh->nud_state & ~NUD_NOARP) err = neigh_update(neigh, NULL, NUD_FAILED, NEIGH_UPDATE_F_OVERRIDE| NEIGH_UPDATE_F_ADMIN); @@ -1186,24 +1203,24 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) struct net_device *dev = NULL; switch (cmd) { - case SIOCDARP: - case SIOCSARP: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - case SIOCGARP: - err = copy_from_user(&r, arg, sizeof(struct arpreq)); - if (err) - return -EFAULT; - break; - default: - return -EINVAL; + case SIOCDARP: + case SIOCSARP: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + case SIOCGARP: + err = copy_from_user(&r, arg, sizeof(struct arpreq)); + if (err) + return -EFAULT; + break; + default: + return -EINVAL; } if (r.arp_pa.sa_family != AF_INET) return -EPFNOSUPPORT; if (!(r.arp_flags & ATF_PUBL) && - (r.arp_flags & (ATF_NETMASK|ATF_DONTPUB))) + (r.arp_flags & (ATF_NETMASK | ATF_DONTPUB))) return -EINVAL; if (!(r.arp_flags & ATF_NETMASK)) ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr = @@ -1211,7 +1228,8 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) rtnl_lock(); if (r.arp_dev[0]) { err = -ENODEV; - if ((dev = __dev_get_by_name(net, r.arp_dev)) == NULL) + dev = __dev_get_by_name(net, r.arp_dev); + if (dev == NULL) goto out; /* Mmmm... It is wrong... ARPHRD_NETROM==0 */ @@ -1243,7 +1261,8 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg) return err; } -static int arp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) +static int arp_netdev_event(struct notifier_block *this, unsigned long event, + void *ptr) { struct net_device *dev = ptr; @@ -1311,12 +1330,13 @@ static char *ax2asc2(ax25_address *a, char *buf) for (n = 0, s = buf; n < 6; n++) { c = (a->ax25_call[n] >> 1) & 0x7F; - if (c != ' ') *s++ = c; + if (c != ' ') + *s++ = c; } *s++ = '-'; - - if ((n = ((a->ax25_call[6] >> 1) & 0x0F)) > 9) { + n = (a->ax25_call[6] >> 1) & 0x0F; + if (n > 9) { *s++ = '1'; n -= 10; } @@ -1325,10 +1345,9 @@ static char *ax2asc2(ax25_address *a, char *buf) *s++ = '\0'; if (*buf == '\0' || *buf == '-') - return "*"; + return "*"; return buf; - } #endif /* CONFIG_AX25 */ @@ -1408,10 +1427,10 @@ static void *arp_seq_start(struct seq_file *seq, loff_t *pos) /* ------------------------------------------------------------------------ */ static const struct seq_operations arp_seq_ops = { - .start = arp_seq_start, - .next = neigh_seq_next, - .stop = neigh_seq_stop, - .show = arp_seq_show, + .start = arp_seq_start, + .next = neigh_seq_next, + .stop = neigh_seq_stop, + .show = arp_seq_show, }; static int arp_seq_open(struct inode *inode, struct file *file) diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c index 721a8a37b45c77ce1d3ae78afffe57cf9eaeedf1..174be6caa5c8245b105b3d4c504ed0c977a00f2c 100644 --- a/net/ipv4/datagram.c +++ b/net/ipv4/datagram.c @@ -73,6 +73,6 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) inet->inet_id = jiffies; sk_dst_set(sk, &rt->dst); - return(0); + return 0; } EXPORT_SYMBOL(ip4_datagram_connect); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index da14c49284f41677f17d273badbbbd0560381ddb..dc94b0316b783fd1c1985e407fb0339782c66df5 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -209,7 +209,7 @@ static void inetdev_destroy(struct in_device *in_dev) inet_free_ifa(ifa); } - dev->ip_ptr = NULL; + rcu_assign_pointer(dev->ip_ptr, NULL); devinet_sysctl_unregister(in_dev); neigh_parms_release(&arp_tbl, in_dev->arp_parms); @@ -403,6 +403,9 @@ static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa) return inet_insert_ifa(ifa); } +/* Caller must hold RCU or RTNL : + * We dont take a reference on found in_device + */ struct in_device *inetdev_by_index(struct net *net, int ifindex) { struct net_device *dev; @@ -411,7 +414,7 @@ struct in_device *inetdev_by_index(struct net *net, int ifindex) rcu_read_lock(); dev = dev_get_by_index_rcu(net, ifindex); if (dev) - in_dev = in_dev_get(dev); + in_dev = rcu_dereference_rtnl(dev->ip_ptr); rcu_read_unlock(); return in_dev; } @@ -453,8 +456,6 @@ static int inet_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg goto errout; } - __in_dev_put(in_dev); - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) { if (tb[IFA_LOCAL] && @@ -1059,7 +1060,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, switch (event) { case NETDEV_REGISTER: printk(KERN_DEBUG "inetdev_event: bug\n"); - dev->ip_ptr = NULL; + rcu_assign_pointer(dev->ip_ptr, NULL); break; case NETDEV_UP: if (!inetdev_valid_mtu(dev->mtu)) diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 7d02a9f999fabcebeb61800816d722e6f6c054ff..36e27c2107de9f8286e7848c9b0dfe3560ab2907 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -147,35 +147,43 @@ static void fib_flush(struct net *net) rt_cache_flush(net, -1); } -/* - * Find the first device with a given source address. +/** + * __ip_dev_find - find the first device with a given source address. + * @net: the net namespace + * @addr: the source address + * @devref: if true, take a reference on the found device + * + * If a caller uses devref=false, it should be protected by RCU, or RTNL */ - -struct net_device * ip_dev_find(struct net *net, __be32 addr) +struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) { - struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } }; - struct fib_result res; + struct flowi fl = { + .nl_u = { + .ip4_u = { + .daddr = addr + } + }, + .flags = FLOWI_FLAG_MATCH_ANY_IIF + }; + struct fib_result res = { 0 }; struct net_device *dev = NULL; - struct fib_table *local_table; -#ifdef CONFIG_IP_MULTIPLE_TABLES - res.r = NULL; -#endif - - local_table = fib_get_table(net, RT_TABLE_LOCAL); - if (!local_table || fib_table_lookup(local_table, &fl, &res)) + rcu_read_lock(); + if (fib_lookup(net, &fl, &res)) { + rcu_read_unlock(); return NULL; + } if (res.type != RTN_LOCAL) goto out; dev = FIB_RES_DEV(res); - if (dev) + if (dev && devref) dev_hold(dev); out: - fib_res_put(&res); + rcu_read_unlock(); return dev; } -EXPORT_SYMBOL(ip_dev_find); +EXPORT_SYMBOL(__ip_dev_find); /* * Find address type as if only "dev" was present in the system. If @@ -202,11 +210,12 @@ static inline unsigned __inet_dev_addr_type(struct net *net, local_table = fib_get_table(net, RT_TABLE_LOCAL); if (local_table) { ret = RTN_UNICAST; - if (!fib_table_lookup(local_table, &fl, &res)) { + rcu_read_lock(); + if (!fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) { if (!dev || dev == res.fi->fib_dev) ret = res.type; - fib_res_put(&res); } + rcu_read_unlock(); } return ret; } @@ -220,30 +229,34 @@ EXPORT_SYMBOL(inet_addr_type); unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr) { - return __inet_dev_addr_type(net, dev, addr); + return __inet_dev_addr_type(net, dev, addr); } EXPORT_SYMBOL(inet_dev_addr_type); /* Given (packet source, input interface) and optional (dst, oif, tos): - - (main) check, that source is valid i.e. not broadcast or our local - address. - - figure out what "logical" interface this packet arrived - and calculate "specific destination" address. - - check, that packet arrived from expected physical interface. + * - (main) check, that source is valid i.e. not broadcast or our local + * address. + * - figure out what "logical" interface this packet arrived + * and calculate "specific destination" address. + * - check, that packet arrived from expected physical interface. + * called with rcu_read_lock() */ - int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, __be32 *spec_dst, u32 *itag, u32 mark) { struct in_device *in_dev; - struct flowi fl = { .nl_u = { .ip4_u = - { .daddr = src, - .saddr = dst, - .tos = tos } }, - .mark = mark, - .iif = oif }; - + struct flowi fl = { + .nl_u = { + .ip4_u = { + .daddr = src, + .saddr = dst, + .tos = tos + } + }, + .mark = mark, + .iif = oif + }; struct fib_result res; int no_addr, rpf, accept_local; bool dev_match; @@ -251,7 +264,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, struct net *net; no_addr = rpf = accept_local = 0; - rcu_read_lock(); in_dev = __in_dev_get_rcu(dev); if (in_dev) { no_addr = in_dev->ifa_list == NULL; @@ -260,7 +272,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, if (mark && !IN_DEV_SRC_VMARK(in_dev)) fl.mark = 0; } - rcu_read_unlock(); if (in_dev == NULL) goto e_inval; @@ -270,7 +281,7 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, goto last_resort; if (res.type != RTN_UNICAST) { if (res.type != RTN_LOCAL || !accept_local) - goto e_inval_res; + goto e_inval; } *spec_dst = FIB_RES_PREFSRC(res); fib_combine_itag(itag, &res); @@ -291,10 +302,8 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, #endif if (dev_match) { ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; - fib_res_put(&res); return ret; } - fib_res_put(&res); if (no_addr) goto last_resort; if (rpf == 1) @@ -307,7 +316,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, *spec_dst = FIB_RES_PREFSRC(res); ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; } - fib_res_put(&res); } return ret; @@ -318,8 +326,6 @@ int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, *itag = 0; return 0; -e_inval_res: - fib_res_put(&res); e_inval: return -EINVAL; e_rpf: @@ -472,9 +478,9 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt, } /* - * Handle IP routing ioctl calls. These are used to manipulate the routing tables + * Handle IP routing ioctl calls. + * These are used to manipulate the routing tables */ - int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg) { struct fib_config cfg; @@ -518,7 +524,7 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg) return -EINVAL; } -const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = { +const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = { [RTA_DST] = { .type = NLA_U32 }, [RTA_SRC] = { .type = NLA_U32 }, [RTA_IIF] = { .type = NLA_U32 }, @@ -532,7 +538,7 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = { }; static int rtm_to_fib_config(struct net *net, struct sk_buff *skb, - struct nlmsghdr *nlh, struct fib_config *cfg) + struct nlmsghdr *nlh, struct fib_config *cfg) { struct nlattr *attr; int err, remaining; @@ -687,12 +693,11 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) } /* Prepare and feed intra-kernel routing request. - Really, it should be netlink message, but :-( netlink - can be not configured, so that we feed it directly - to fib engine. It is legal, because all events occur - only when netlink is already locked. + * Really, it should be netlink message, but :-( netlink + * can be not configured, so that we feed it directly + * to fib engine. It is legal, because all events occur + * only when netlink is already locked. */ - static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa) { struct net *net = dev_net(ifa->ifa_dev->dev); @@ -738,9 +743,9 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) struct in_ifaddr *prim = ifa; __be32 mask = ifa->ifa_mask; __be32 addr = ifa->ifa_local; - __be32 prefix = ifa->ifa_address&mask; + __be32 prefix = ifa->ifa_address & mask; - if (ifa->ifa_flags&IFA_F_SECONDARY) { + if (ifa->ifa_flags & IFA_F_SECONDARY) { prim = inet_ifa_byprefix(in_dev, prefix, mask); if (prim == NULL) { printk(KERN_WARNING "fib_add_ifaddr: bug: prim == NULL\n"); @@ -750,22 +755,24 @@ void fib_add_ifaddr(struct in_ifaddr *ifa) fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim); - if (!(dev->flags&IFF_UP)) + if (!(dev->flags & IFF_UP)) return; /* Add broadcast address, if it is explicitly assigned. */ if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); - if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) && + if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) && (prefix != addr || ifa->ifa_prefixlen < 32)) { - fib_magic(RTM_NEWROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL : - RTN_UNICAST, prefix, ifa->ifa_prefixlen, prim); + fib_magic(RTM_NEWROUTE, + dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST, + prefix, ifa->ifa_prefixlen, prim); /* Add network specific broadcasts, when it takes a sense */ if (ifa->ifa_prefixlen < 31) { fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix, 32, prim); - fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix|~mask, 32, prim); + fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix | ~mask, + 32, prim); } } } @@ -776,17 +783,18 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) struct net_device *dev = in_dev->dev; struct in_ifaddr *ifa1; struct in_ifaddr *prim = ifa; - __be32 brd = ifa->ifa_address|~ifa->ifa_mask; - __be32 any = ifa->ifa_address&ifa->ifa_mask; + __be32 brd = ifa->ifa_address | ~ifa->ifa_mask; + __be32 any = ifa->ifa_address & ifa->ifa_mask; #define LOCAL_OK 1 #define BRD_OK 2 #define BRD0_OK 4 #define BRD1_OK 8 unsigned ok = 0; - if (!(ifa->ifa_flags&IFA_F_SECONDARY)) - fib_magic(RTM_DELROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL : - RTN_UNICAST, any, ifa->ifa_prefixlen, prim); + if (!(ifa->ifa_flags & IFA_F_SECONDARY)) + fib_magic(RTM_DELROUTE, + dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST, + any, ifa->ifa_prefixlen, prim); else { prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); if (prim == NULL) { @@ -796,9 +804,9 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) } /* Deletion is more complicated than add. - We should take care of not to delete too much :-) - - Scan address list to be sure that addresses are really gone. + * We should take care of not to delete too much :-) + * + * Scan address list to be sure that addresses are really gone. */ for (ifa1 = in_dev->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { @@ -812,23 +820,23 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) ok |= BRD0_OK; } - if (!(ok&BRD_OK)) + if (!(ok & BRD_OK)) fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); - if (!(ok&BRD1_OK)) + if (!(ok & BRD1_OK)) fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim); - if (!(ok&BRD0_OK)) + if (!(ok & BRD0_OK)) fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim); - if (!(ok&LOCAL_OK)) { + if (!(ok & LOCAL_OK)) { fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim); /* Check, that this local address finally disappeared. */ if (inet_addr_type(dev_net(dev), ifa->ifa_local) != RTN_LOCAL) { /* And the last, but not the least thing. - We must flush stray FIB entries. - - First of all, we scan fib_info list searching - for stray nexthop entries, then ignite fib_flush. - */ + * We must flush stray FIB entries. + * + * First of all, we scan fib_info list searching + * for stray nexthop entries, then ignite fib_flush. + */ if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local)) fib_flush(dev_net(dev)); } @@ -839,14 +847,20 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa) #undef BRD1_OK } -static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) +static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb) { struct fib_result res; - struct flowi fl = { .mark = frn->fl_mark, - .nl_u = { .ip4_u = { .daddr = frn->fl_addr, - .tos = frn->fl_tos, - .scope = frn->fl_scope } } }; + struct flowi fl = { + .mark = frn->fl_mark, + .nl_u = { + .ip4_u = { + .daddr = frn->fl_addr, + .tos = frn->fl_tos, + .scope = frn->fl_scope + } + } + }; #ifdef CONFIG_IP_MULTIPLE_TABLES res.r = NULL; @@ -857,15 +871,16 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) local_bh_disable(); frn->tb_id = tb->tb_id; - frn->err = fib_table_lookup(tb, &fl, &res); + rcu_read_lock(); + frn->err = fib_table_lookup(tb, &fl, &res, FIB_LOOKUP_NOREF); if (!frn->err) { frn->prefixlen = res.prefixlen; frn->nh_sel = res.nh_sel; frn->type = res.type; frn->scope = res.scope; - fib_res_put(&res); } + rcu_read_unlock(); local_bh_enable(); } } @@ -894,8 +909,8 @@ static void nl_fib_input(struct sk_buff *skb) nl_fib_lookup(frn, tb); - pid = NETLINK_CB(skb).pid; /* pid of sending process */ - NETLINK_CB(skb).pid = 0; /* from kernel */ + pid = NETLINK_CB(skb).pid; /* pid of sending process */ + NETLINK_CB(skb).pid = 0; /* from kernel */ NETLINK_CB(skb).dst_group = 0; /* unicast */ netlink_unicast(net->ipv4.fibnl, skb, pid, MSG_DONTWAIT); } @@ -942,7 +957,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, fib_del_ifaddr(ifa); if (ifa->ifa_dev->ifa_list == NULL) { /* Last address was deleted from this interface. - Disable IP. + * Disable IP. */ fib_disable_ip(dev, 1, 0); } else { @@ -1001,16 +1016,15 @@ static struct notifier_block fib_netdev_notifier = { static int __net_init ip_fib_net_init(struct net *net) { int err; - unsigned int i; + size_t size = sizeof(struct hlist_head) * FIB_TABLE_HASHSZ; - net->ipv4.fib_table_hash = kzalloc( - sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL); + /* Avoid false sharing : Use at least a full cache line */ + size = max_t(size_t, size, L1_CACHE_BYTES); + + net->ipv4.fib_table_hash = kzalloc(size, GFP_KERNEL); if (net->ipv4.fib_table_hash == NULL) return -ENOMEM; - for (i = 0; i < FIB_TABLE_HASHSZ; i++) - INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]); - err = fib4_rules_init(net); if (err < 0) goto fail; diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 4ed7e0dea1bc0e8b33bb1f094e712b59fb6715ad..43e1c594ce8f38aeae59dbf32dd6dfac747d2c46 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -54,36 +54,37 @@ struct fib_node { struct fib_alias fn_embedded_alias; }; -struct fn_zone { - struct fn_zone *fz_next; /* Next not empty zone */ - struct hlist_head *fz_hash; /* Hash table pointer */ - int fz_nent; /* Number of entries */ +#define EMBEDDED_HASH_SIZE (L1_CACHE_BYTES / sizeof(struct hlist_head)) - int fz_divisor; /* Hash divisor */ +struct fn_zone { + struct fn_zone __rcu *fz_next; /* Next not empty zone */ + struct hlist_head __rcu *fz_hash; /* Hash table pointer */ + seqlock_t fz_lock; u32 fz_hashmask; /* (fz_divisor - 1) */ -#define FZ_HASHMASK(fz) ((fz)->fz_hashmask) - int fz_order; /* Zone order */ - __be32 fz_mask; + u8 fz_order; /* Zone order (0..32) */ + u8 fz_revorder; /* 32 - fz_order */ + __be32 fz_mask; /* inet_make_mask(order) */ #define FZ_MASK(fz) ((fz)->fz_mask) -}; -/* NOTE. On fast computers evaluation of fz_hashmask and fz_mask - * can be cheaper than memory lookup, so that FZ_* macros are used. - */ + struct hlist_head fz_embedded_hash[EMBEDDED_HASH_SIZE]; + + int fz_nent; /* Number of entries */ + int fz_divisor; /* Hash size (mask+1) */ +}; struct fn_hash { - struct fn_zone *fn_zones[33]; - struct fn_zone *fn_zone_list; + struct fn_zone *fn_zones[33]; + struct fn_zone __rcu *fn_zone_list; }; static inline u32 fn_hash(__be32 key, struct fn_zone *fz) { - u32 h = ntohl(key)>>(32 - fz->fz_order); + u32 h = ntohl(key) >> fz->fz_revorder; h ^= (h>>20); h ^= (h>>10); h ^= (h>>5); - h &= FZ_HASHMASK(fz); + h &= fz->fz_hashmask; return h; } @@ -92,7 +93,6 @@ static inline __be32 fz_key(__be32 dst, struct fn_zone *fz) return dst & FZ_MASK(fz); } -static DEFINE_RWLOCK(fib_hash_lock); static unsigned int fib_hash_genid; #define FZ_MAX_DIVISOR ((PAGE_SIZE<fn_hash); + hlist_del_rcu(&f->fn_hash); new_head = &fz->fz_hash[fn_hash(f->fn_key, fz)]; - hlist_add_head(&f->fn_hash, new_head); + hlist_add_head_rcu(&f->fn_hash, new_head); } } } @@ -147,14 +146,14 @@ static void fn_rehash_zone(struct fn_zone *fz) int old_divisor, new_divisor; u32 new_hashmask; - old_divisor = fz->fz_divisor; + new_divisor = old_divisor = fz->fz_divisor; switch (old_divisor) { - case 16: - new_divisor = 256; + case EMBEDDED_HASH_SIZE: + new_divisor *= EMBEDDED_HASH_SIZE; break; - case 256: - new_divisor = 1024; + case EMBEDDED_HASH_SIZE*EMBEDDED_HASH_SIZE: + new_divisor *= (EMBEDDED_HASH_SIZE/2); break; default: if ((old_divisor << 1) > FZ_MAX_DIVISOR) { @@ -175,31 +174,55 @@ static void fn_rehash_zone(struct fn_zone *fz) ht = fz_hash_alloc(new_divisor); if (ht) { - write_lock_bh(&fib_hash_lock); + struct fn_zone nfz; + + memcpy(&nfz, fz, sizeof(nfz)); + + write_seqlock_bh(&fz->fz_lock); old_ht = fz->fz_hash; - fz->fz_hash = ht; + nfz.fz_hash = ht; + nfz.fz_hashmask = new_hashmask; + nfz.fz_divisor = new_divisor; + fn_rebuild_zone(&nfz, old_ht, old_divisor); + fib_hash_genid++; + rcu_assign_pointer(fz->fz_hash, ht); fz->fz_hashmask = new_hashmask; fz->fz_divisor = new_divisor; - fn_rebuild_zone(fz, old_ht, old_divisor); - fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); + write_sequnlock_bh(&fz->fz_lock); - fz_hash_free(old_ht, old_divisor); + if (old_ht != fz->fz_embedded_hash) { + synchronize_rcu(); + fz_hash_free(old_ht, old_divisor); + } } } -static inline void fn_free_node(struct fib_node * f) +static void fn_free_node_rcu(struct rcu_head *head) { + struct fib_node *f = container_of(head, struct fib_node, fn_embedded_alias.rcu); + kmem_cache_free(fn_hash_kmem, f); } +static inline void fn_free_node(struct fib_node *f) +{ + call_rcu(&f->fn_embedded_alias.rcu, fn_free_node_rcu); +} + +static void fn_free_alias_rcu(struct rcu_head *head) +{ + struct fib_alias *fa = container_of(head, struct fib_alias, rcu); + + kmem_cache_free(fn_alias_kmem, fa); +} + static inline void fn_free_alias(struct fib_alias *fa, struct fib_node *f) { fib_release_info(fa->fa_info); if (fa == &f->fn_embedded_alias) fa->fa_info = NULL; else - kmem_cache_free(fn_alias_kmem, fa); + call_rcu(&fa->rcu, fn_free_alias_rcu); } static struct fn_zone * @@ -210,68 +233,71 @@ fn_new_zone(struct fn_hash *table, int z) if (!fz) return NULL; - if (z) { - fz->fz_divisor = 16; - } else { - fz->fz_divisor = 1; - } - fz->fz_hashmask = (fz->fz_divisor - 1); - fz->fz_hash = fz_hash_alloc(fz->fz_divisor); - if (!fz->fz_hash) { - kfree(fz); - return NULL; - } + seqlock_init(&fz->fz_lock); + fz->fz_divisor = z ? EMBEDDED_HASH_SIZE : 1; + fz->fz_hashmask = fz->fz_divisor - 1; + fz->fz_hash = fz->fz_embedded_hash; fz->fz_order = z; + fz->fz_revorder = 32 - z; fz->fz_mask = inet_make_mask(z); /* Find the first not empty zone with more specific mask */ - for (i=z+1; i<=32; i++) + for (i = z + 1; i <= 32; i++) if (table->fn_zones[i]) break; - write_lock_bh(&fib_hash_lock); - if (i>32) { + if (i > 32) { /* No more specific masks, we are the first. */ - fz->fz_next = table->fn_zone_list; - table->fn_zone_list = fz; + rcu_assign_pointer(fz->fz_next, + rtnl_dereference(table->fn_zone_list)); + rcu_assign_pointer(table->fn_zone_list, fz); } else { - fz->fz_next = table->fn_zones[i]->fz_next; - table->fn_zones[i]->fz_next = fz; + rcu_assign_pointer(fz->fz_next, + rtnl_dereference(table->fn_zones[i]->fz_next)); + rcu_assign_pointer(table->fn_zones[i]->fz_next, fz); } table->fn_zones[z] = fz; fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); return fz; } int fib_table_lookup(struct fib_table *tb, - const struct flowi *flp, struct fib_result *res) + const struct flowi *flp, struct fib_result *res, + int fib_flags) { int err; struct fn_zone *fz; struct fn_hash *t = (struct fn_hash *)tb->tb_data; - read_lock(&fib_hash_lock); - for (fz = t->fn_zone_list; fz; fz = fz->fz_next) { - struct hlist_head *head; + rcu_read_lock(); + for (fz = rcu_dereference(t->fn_zone_list); + fz != NULL; + fz = rcu_dereference(fz->fz_next)) { + struct hlist_head __rcu *head; struct hlist_node *node; struct fib_node *f; - __be32 k = fz_key(flp->fl4_dst, fz); + __be32 k; + unsigned int seq; - head = &fz->fz_hash[fn_hash(k, fz)]; - hlist_for_each_entry(f, node, head, fn_hash) { - if (f->fn_key != k) - continue; + do { + seq = read_seqbegin(&fz->fz_lock); + k = fz_key(flp->fl4_dst, fz); + + head = &fz->fz_hash[fn_hash(k, fz)]; + hlist_for_each_entry_rcu(f, node, head, fn_hash) { + if (f->fn_key != k) + continue; - err = fib_semantic_match(&f->fn_alias, + err = fib_semantic_match(&f->fn_alias, flp, res, - fz->fz_order); - if (err <= 0) - goto out; - } + fz->fz_order, fib_flags); + if (err <= 0) + goto out; + } + } while (read_seqretry(&fz->fz_lock, seq)); } err = 1; out: - read_unlock(&fib_hash_lock); + rcu_read_unlock(); return err; } @@ -293,11 +319,11 @@ void fib_table_select_default(struct fib_table *tb, last_resort = NULL; order = -1; - read_lock(&fib_hash_lock); - hlist_for_each_entry(f, node, &fz->fz_hash[0], fn_hash) { + rcu_read_lock(); + hlist_for_each_entry_rcu(f, node, &fz->fz_hash[0], fn_hash) { struct fib_alias *fa; - list_for_each_entry(fa, &f->fn_alias, fa_list) { + list_for_each_entry_rcu(fa, &f->fn_alias, fa_list) { struct fib_info *next_fi = fa->fa_info; if (fa->fa_scope != res->scope || @@ -309,7 +335,8 @@ void fib_table_select_default(struct fib_table *tb, if (!next_fi->fib_nh[0].nh_gw || next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) continue; - fa->fa_state |= FA_S_ACCESSED; + + fib_alias_accessed(fa); if (fi == NULL) { if (next_fi != res->fi) @@ -341,7 +368,7 @@ void fib_table_select_default(struct fib_table *tb, fib_result_assign(res, last_resort); tb->tb_default = last_idx; out: - read_unlock(&fib_hash_lock); + rcu_read_unlock(); } /* Insert node F to FZ. */ @@ -349,7 +376,7 @@ static inline void fib_insert_node(struct fn_zone *fz, struct fib_node *f) { struct hlist_head *head = &fz->fz_hash[fn_hash(f->fn_key, fz)]; - hlist_add_head(&f->fn_hash, head); + hlist_add_head_rcu(&f->fn_hash, head); } /* Return the node in FZ matching KEY. */ @@ -359,7 +386,7 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key) struct hlist_node *node; struct fib_node *f; - hlist_for_each_entry(f, node, head, fn_hash) { + hlist_for_each_entry_rcu(f, node, head, fn_hash) { if (f->fn_key == key) return f; } @@ -367,6 +394,17 @@ static struct fib_node *fib_find_node(struct fn_zone *fz, __be32 key) return NULL; } + +static struct fib_alias *fib_fast_alloc(struct fib_node *f) +{ + struct fib_alias *fa = &f->fn_embedded_alias; + + if (fa->fa_info != NULL) + fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); + return fa; +} + +/* Caller must hold RTNL. */ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) { struct fn_hash *table = (struct fn_hash *) tb->tb_data; @@ -451,7 +489,6 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) } if (cfg->fc_nlflags & NLM_F_REPLACE) { - struct fib_info *fi_drop; u8 state; fa = fa_first; @@ -460,21 +497,25 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) err = 0; goto out; } - write_lock_bh(&fib_hash_lock); - fi_drop = fa->fa_info; - fa->fa_info = fi; - fa->fa_type = cfg->fc_type; - fa->fa_scope = cfg->fc_scope; + err = -ENOBUFS; + new_fa = fib_fast_alloc(f); + if (new_fa == NULL) + goto out; + + new_fa->fa_tos = fa->fa_tos; + new_fa->fa_info = fi; + new_fa->fa_type = cfg->fc_type; + new_fa->fa_scope = cfg->fc_scope; state = fa->fa_state; - fa->fa_state &= ~FA_S_ACCESSED; + new_fa->fa_state = state & ~FA_S_ACCESSED; fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); + list_replace_rcu(&fa->fa_list, &new_fa->fa_list); - fib_release_info(fi_drop); + fn_free_alias(fa, f); if (state & FA_S_ACCESSED) rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); - rtmsg_fib(RTM_NEWROUTE, key, fa, cfg->fc_dst_len, tb->tb_id, - &cfg->fc_nlinfo, NLM_F_REPLACE); + rtmsg_fib(RTM_NEWROUTE, key, new_fa, cfg->fc_dst_len, + tb->tb_id, &cfg->fc_nlinfo, NLM_F_REPLACE); return 0; } @@ -506,12 +547,10 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) f = new_f; } - new_fa = &f->fn_embedded_alias; - if (new_fa->fa_info != NULL) { - new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL); - if (new_fa == NULL) - goto out; - } + new_fa = fib_fast_alloc(f); + if (new_fa == NULL) + goto out; + new_fa->fa_info = fi; new_fa->fa_tos = tos; new_fa->fa_type = cfg->fc_type; @@ -522,13 +561,11 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) * Insert new entry to the list. */ - write_lock_bh(&fib_hash_lock); if (new_f) fib_insert_node(fz, new_f); - list_add_tail(&new_fa->fa_list, + list_add_tail_rcu(&new_fa->fa_list, (fa ? &fa->fa_list : &f->fn_alias)); fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); if (new_f) fz->fz_nent++; @@ -603,14 +640,12 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg) tb->tb_id, &cfg->fc_nlinfo, 0); kill_fn = 0; - write_lock_bh(&fib_hash_lock); - list_del(&fa->fa_list); + list_del_rcu(&fa->fa_list); if (list_empty(&f->fn_alias)) { - hlist_del(&f->fn_hash); + hlist_del_rcu(&f->fn_hash); kill_fn = 1; } fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); if (fa->fa_state & FA_S_ACCESSED) rt_cache_flush(cfg->fc_nlinfo.nl_net, -1); @@ -641,14 +676,12 @@ static int fn_flush_list(struct fn_zone *fz, int idx) struct fib_info *fi = fa->fa_info; if (fi && (fi->fib_flags&RTNH_F_DEAD)) { - write_lock_bh(&fib_hash_lock); - list_del(&fa->fa_list); + list_del_rcu(&fa->fa_list); if (list_empty(&f->fn_alias)) { - hlist_del(&f->fn_hash); + hlist_del_rcu(&f->fn_hash); kill_f = 1; } fib_hash_genid++; - write_unlock_bh(&fib_hash_lock); fn_free_alias(fa, f); found++; @@ -662,13 +695,16 @@ static int fn_flush_list(struct fn_zone *fz, int idx) return found; } +/* caller must hold RTNL. */ int fib_table_flush(struct fib_table *tb) { struct fn_hash *table = (struct fn_hash *) tb->tb_data; struct fn_zone *fz; int found = 0; - for (fz = table->fn_zone_list; fz; fz = fz->fz_next) { + for (fz = rtnl_dereference(table->fn_zone_list); + fz != NULL; + fz = rtnl_dereference(fz->fz_next)) { int i; for (i = fz->fz_divisor - 1; i >= 0; i--) @@ -690,10 +726,10 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, s_i = cb->args[4]; i = 0; - hlist_for_each_entry(f, node, head, fn_hash) { + hlist_for_each_entry_rcu(f, node, head, fn_hash) { struct fib_alias *fa; - list_for_each_entry(fa, &f->fn_alias, fa_list) { + list_for_each_entry_rcu(fa, &f->fn_alias, fa_list) { if (i < s_i) goto next; @@ -711,7 +747,7 @@ fn_hash_dump_bucket(struct sk_buff *skb, struct netlink_callback *cb, cb->args[4] = i; return -1; } - next: +next: i++; } } @@ -746,23 +782,26 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb, int fib_table_dump(struct fib_table *tb, struct sk_buff *skb, struct netlink_callback *cb) { - int m, s_m; + int m = 0, s_m; struct fn_zone *fz; struct fn_hash *table = (struct fn_hash *)tb->tb_data; s_m = cb->args[2]; - read_lock(&fib_hash_lock); - for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) { - if (m < s_m) continue; + rcu_read_lock(); + for (fz = rcu_dereference(table->fn_zone_list); + fz != NULL; + fz = rcu_dereference(fz->fz_next), m++) { + if (m < s_m) + continue; if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) { cb->args[2] = m; - read_unlock(&fib_hash_lock); + rcu_read_unlock(); return -1; } memset(&cb->args[3], 0, sizeof(cb->args) - 3*sizeof(cb->args[0])); } - read_unlock(&fib_hash_lock); + rcu_read_unlock(); cb->args[2] = m; return skb->len; } @@ -825,8 +864,9 @@ static struct fib_alias *fib_get_first(struct seq_file *seq) iter->genid = fib_hash_genid; iter->valid = 1; - for (iter->zone = table->fn_zone_list; iter->zone; - iter->zone = iter->zone->fz_next) { + for (iter->zone = rcu_dereference(table->fn_zone_list); + iter->zone != NULL; + iter->zone = rcu_dereference(iter->zone->fz_next)) { int maxslot; if (!iter->zone->fz_nent) @@ -911,7 +951,7 @@ static struct fib_alias *fib_get_next(struct seq_file *seq) } } - iter->zone = iter->zone->fz_next; + iter->zone = rcu_dereference(iter->zone->fz_next); if (!iter->zone) goto out; @@ -950,11 +990,11 @@ static struct fib_alias *fib_get_idx(struct seq_file *seq, loff_t pos) } static void *fib_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(fib_hash_lock) + __acquires(RCU) { void *v = NULL; - read_lock(&fib_hash_lock); + rcu_read_lock(); if (fib_get_table(seq_file_net(seq), RT_TABLE_MAIN)) v = *pos ? fib_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; return v; @@ -967,15 +1007,16 @@ static void *fib_seq_next(struct seq_file *seq, void *v, loff_t *pos) } static void fib_seq_stop(struct seq_file *seq, void *v) - __releases(fib_hash_lock) + __releases(RCU) { - read_unlock(&fib_hash_lock); + rcu_read_unlock(); } static unsigned fib_flag_trans(int type, __be32 mask, struct fib_info *fi) { static const unsigned type2flags[RTN_MAX + 1] = { - [7] = RTF_REJECT, [8] = RTF_REJECT, + [7] = RTF_REJECT, + [8] = RTF_REJECT, }; unsigned flags = type2flags[type]; diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index 637b133973bd88e601aee3b833de0efed5b2a017..a29edf2219c8437b811bcce27fdd2cd9fca0a9fc 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h @@ -12,17 +12,22 @@ struct fib_alias { u8 fa_type; u8 fa_scope; u8 fa_state; -#ifdef CONFIG_IP_FIB_TRIE struct rcu_head rcu; -#endif }; #define FA_S_ACCESSED 0x01 +/* Dont write on fa_state unless needed, to keep it shared on all cpus */ +static inline void fib_alias_accessed(struct fib_alias *fa) +{ + if (!(fa->fa_state & FA_S_ACCESSED)) + fa->fa_state |= FA_S_ACCESSED; +} + /* Exported by fib_semantics.c */ extern int fib_semantic_match(struct list_head *head, const struct flowi *flp, - struct fib_result *res, int prefixlen); + struct fib_result *res, int prefixlen, int fib_flags); extern void fib_release_info(struct fib_info *); extern struct fib_info *fib_create_info(struct fib_config *cfg); extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi); diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 76daeb5ff5642e656622f0da906f73a32d603643..7981a24f5c7b3b51e5c23c825f98e12b02dfcd87 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -6,7 +6,7 @@ * IPv4 Forwarding Information Base: policy rules. * * Authors: Alexey Kuznetsov, - * Thomas Graf + * Thomas Graf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -14,7 +14,7 @@ * 2 of the License, or (at your option) any later version. * * Fixes: - * Rani Assaf : local_rule cannot be deleted + * Rani Assaf : local_rule cannot be deleted * Marc Boucher : routing by fwmark */ @@ -32,8 +32,7 @@ #include #include -struct fib4_rule -{ +struct fib4_rule { struct fib_rule common; u8 dst_len; u8 src_len; @@ -58,6 +57,7 @@ int fib_lookup(struct net *net, struct flowi *flp, struct fib_result *res) { struct fib_lookup_arg arg = { .result = res, + .flags = FIB_LOOKUP_NOREF, }; int err; @@ -91,10 +91,11 @@ static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp, goto errout; } - if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL) + tbl = fib_get_table(rule->fr_net, rule->table); + if (!tbl) goto errout; - err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result); + err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result, arg->flags); if (err > 0) err = -EAGAIN; errout: diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 20f09c5b31e8bba5e3580255fe5f8d541c14d374..3e0da3ef6116df8b9b4fa6a70272ddeac8cac0d4 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -60,21 +60,30 @@ static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE]; static DEFINE_SPINLOCK(fib_multipath_lock); -#define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \ -for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++) - -#define change_nexthops(fi) { int nhsel; struct fib_nh *nexthop_nh; \ -for (nhsel=0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nexthop_nh++, nhsel++) +#define for_nexthops(fi) { \ + int nhsel; const struct fib_nh *nh; \ + for (nhsel = 0, nh = (fi)->fib_nh; \ + nhsel < (fi)->fib_nhs; \ + nh++, nhsel++) + +#define change_nexthops(fi) { \ + int nhsel; struct fib_nh *nexthop_nh; \ + for (nhsel = 0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \ + nhsel < (fi)->fib_nhs; \ + nexthop_nh++, nhsel++) #else /* CONFIG_IP_ROUTE_MULTIPATH */ /* Hope, that gcc will optimize it to get rid of dummy loop */ -#define for_nexthops(fi) { int nhsel = 0; const struct fib_nh * nh = (fi)->fib_nh; \ -for (nhsel=0; nhsel < 1; nhsel++) +#define for_nexthops(fi) { \ + int nhsel; const struct fib_nh *nh = (fi)->fib_nh; \ + for (nhsel = 0; nhsel < 1; nhsel++) -#define change_nexthops(fi) { int nhsel = 0; struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \ -for (nhsel=0; nhsel < 1; nhsel++) +#define change_nexthops(fi) { \ + int nhsel; \ + struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \ + for (nhsel = 0; nhsel < 1; nhsel++) #endif /* CONFIG_IP_ROUTE_MULTIPATH */ @@ -86,63 +95,70 @@ static const struct int error; u8 scope; } fib_props[RTN_MAX + 1] = { - { + [RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE, - }, /* RTN_UNSPEC */ - { + }, + [RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_UNICAST */ - { + }, + [RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST, - }, /* RTN_LOCAL */ - { + }, + [RTN_BROADCAST] = { .error = 0, .scope = RT_SCOPE_LINK, - }, /* RTN_BROADCAST */ - { + }, + [RTN_ANYCAST] = { .error = 0, .scope = RT_SCOPE_LINK, - }, /* RTN_ANYCAST */ - { + }, + [RTN_MULTICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_MULTICAST */ - { + }, + [RTN_BLACKHOLE] = { .error = -EINVAL, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_BLACKHOLE */ - { + }, + [RTN_UNREACHABLE] = { .error = -EHOSTUNREACH, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_UNREACHABLE */ - { + }, + [RTN_PROHIBIT] = { .error = -EACCES, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_PROHIBIT */ - { + }, + [RTN_THROW] = { .error = -EAGAIN, .scope = RT_SCOPE_UNIVERSE, - }, /* RTN_THROW */ - { + }, + [RTN_NAT] = { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE, - }, /* RTN_NAT */ - { + }, + [RTN_XRESOLVE] = { .error = -EINVAL, .scope = RT_SCOPE_NOWHERE, - }, /* RTN_XRESOLVE */ + }, }; /* Release a nexthop info record */ +static void free_fib_info_rcu(struct rcu_head *head) +{ + struct fib_info *fi = container_of(head, struct fib_info, rcu); + + kfree(fi); +} + void free_fib_info(struct fib_info *fi) { if (fi->fib_dead == 0) { - printk(KERN_WARNING "Freeing alive fib_info %p\n", fi); + pr_warning("Freeing alive fib_info %p\n", fi); return; } change_nexthops(fi) { @@ -152,7 +168,7 @@ void free_fib_info(struct fib_info *fi) } endfor_nexthops(fi); fib_info_cnt--; release_net(fi->fib_net); - kfree(fi); + call_rcu(&fi->rcu, free_fib_info_rcu); } void fib_release_info(struct fib_info *fi) @@ -173,7 +189,7 @@ void fib_release_info(struct fib_info *fi) spin_unlock_bh(&fib_info_lock); } -static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) +static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) { const struct fib_nh *onh = ofi->fib_nh; @@ -187,7 +203,7 @@ static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info * #ifdef CONFIG_NET_CLS_ROUTE nh->nh_tclassid != onh->nh_tclassid || #endif - ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD)) + ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD)) return -1; onh++; } endfor_nexthops(fi); @@ -238,7 +254,7 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi) nfi->fib_priority == fi->fib_priority && memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 && - ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 && + ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 && (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0)) return fi; } @@ -247,9 +263,8 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi) } /* Check, that the gateway is already configured. - Used only by redirect accept routine. + * Used only by redirect accept routine. */ - int ip_fib_check_default(__be32 gw, struct net_device *dev) { struct hlist_head *head; @@ -264,7 +279,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev) hlist_for_each_entry(nh, node, head, nh_hash) { if (nh->nh_dev == dev && nh->nh_gw == gw && - !(nh->nh_flags&RTNH_F_DEAD)) { + !(nh->nh_flags & RTNH_F_DEAD)) { spin_unlock(&fib_info_lock); return 0; } @@ -362,10 +377,10 @@ int fib_detect_death(struct fib_info *fi, int order, } if (state == NUD_REACHABLE) return 0; - if ((state&NUD_VALID) && order != dflt) + if ((state & NUD_VALID) && order != dflt) return 0; - if ((state&NUD_VALID) || - (*last_idx<0 && order > dflt)) { + if ((state & NUD_VALID) || + (*last_idx < 0 && order > dflt)) { *last_resort = fi; *last_idx = order; } @@ -476,75 +491,76 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi) /* - Picture - ------- - - Semantics of nexthop is very messy by historical reasons. - We have to take into account, that: - a) gateway can be actually local interface address, - so that gatewayed route is direct. - b) gateway must be on-link address, possibly - described not by an ifaddr, but also by a direct route. - c) If both gateway and interface are specified, they should not - contradict. - d) If we use tunnel routes, gateway could be not on-link. - - Attempt to reconcile all of these (alas, self-contradictory) conditions - results in pretty ugly and hairy code with obscure logic. - - I chose to generalized it instead, so that the size - of code does not increase practically, but it becomes - much more general. - Every prefix is assigned a "scope" value: "host" is local address, - "link" is direct route, - [ ... "site" ... "interior" ... ] - and "universe" is true gateway route with global meaning. - - Every prefix refers to a set of "nexthop"s (gw, oif), - where gw must have narrower scope. This recursion stops - when gw has LOCAL scope or if "nexthop" is declared ONLINK, - which means that gw is forced to be on link. - - Code is still hairy, but now it is apparently logically - consistent and very flexible. F.e. as by-product it allows - to co-exists in peace independent exterior and interior - routing processes. - - Normally it looks as following. - - {universe prefix} -> (gw, oif) [scope link] - | - |-> {link prefix} -> (gw, oif) [scope local] - | - |-> {local prefix} (terminal node) + * Picture + * ------- + * + * Semantics of nexthop is very messy by historical reasons. + * We have to take into account, that: + * a) gateway can be actually local interface address, + * so that gatewayed route is direct. + * b) gateway must be on-link address, possibly + * described not by an ifaddr, but also by a direct route. + * c) If both gateway and interface are specified, they should not + * contradict. + * d) If we use tunnel routes, gateway could be not on-link. + * + * Attempt to reconcile all of these (alas, self-contradictory) conditions + * results in pretty ugly and hairy code with obscure logic. + * + * I chose to generalized it instead, so that the size + * of code does not increase practically, but it becomes + * much more general. + * Every prefix is assigned a "scope" value: "host" is local address, + * "link" is direct route, + * [ ... "site" ... "interior" ... ] + * and "universe" is true gateway route with global meaning. + * + * Every prefix refers to a set of "nexthop"s (gw, oif), + * where gw must have narrower scope. This recursion stops + * when gw has LOCAL scope or if "nexthop" is declared ONLINK, + * which means that gw is forced to be on link. + * + * Code is still hairy, but now it is apparently logically + * consistent and very flexible. F.e. as by-product it allows + * to co-exists in peace independent exterior and interior + * routing processes. + * + * Normally it looks as following. + * + * {universe prefix} -> (gw, oif) [scope link] + * | + * |-> {link prefix} -> (gw, oif) [scope local] + * | + * |-> {local prefix} (terminal node) */ - static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, struct fib_nh *nh) { int err; struct net *net; + struct net_device *dev; net = cfg->fc_nlinfo.nl_net; if (nh->nh_gw) { struct fib_result res; - if (nh->nh_flags&RTNH_F_ONLINK) { - struct net_device *dev; + if (nh->nh_flags & RTNH_F_ONLINK) { if (cfg->fc_scope >= RT_SCOPE_LINK) return -EINVAL; if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST) return -EINVAL; - if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL) + dev = __dev_get_by_index(net, nh->nh_oif); + if (!dev) return -ENODEV; - if (!(dev->flags&IFF_UP)) + if (!(dev->flags & IFF_UP)) return -ENETDOWN; nh->nh_dev = dev; dev_hold(dev); nh->nh_scope = RT_SCOPE_LINK; return 0; } + rcu_read_lock(); { struct flowi fl = { .nl_u = { @@ -559,50 +575,53 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, /* It is not necessary, but requires a bit of thinking */ if (fl.fl4_scope < RT_SCOPE_LINK) fl.fl4_scope = RT_SCOPE_LINK; - if ((err = fib_lookup(net, &fl, &res)) != 0) + err = fib_lookup(net, &fl, &res); + if (err) { + rcu_read_unlock(); return err; + } } err = -EINVAL; if (res.type != RTN_UNICAST && res.type != RTN_LOCAL) goto out; nh->nh_scope = res.scope; nh->nh_oif = FIB_RES_OIF(res); - if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL) + nh->nh_dev = dev = FIB_RES_DEV(res); + if (!dev) goto out; - dev_hold(nh->nh_dev); - err = -ENETDOWN; - if (!(nh->nh_dev->flags & IFF_UP)) - goto out; - err = 0; -out: - fib_res_put(&res); - return err; + dev_hold(dev); + err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN; } else { struct in_device *in_dev; - if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK)) + if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK)) return -EINVAL; + rcu_read_lock(); + err = -ENODEV; in_dev = inetdev_by_index(net, nh->nh_oif); if (in_dev == NULL) - return -ENODEV; - if (!(in_dev->dev->flags&IFF_UP)) { - in_dev_put(in_dev); - return -ENETDOWN; - } + goto out; + err = -ENETDOWN; + if (!(in_dev->dev->flags & IFF_UP)) + goto out; nh->nh_dev = in_dev->dev; dev_hold(nh->nh_dev); nh->nh_scope = RT_SCOPE_HOST; - in_dev_put(in_dev); + err = 0; } - return 0; +out: + rcu_read_unlock(); + return err; } static inline unsigned int fib_laddr_hashfn(__be32 val) { unsigned int mask = (fib_hash_size - 1); - return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask; + return ((__force u32)val ^ + ((__force u32)val >> 7) ^ + ((__force u32)val >> 14)) & mask; } static struct hlist_head *fib_hash_alloc(int bytes) @@ -611,7 +630,8 @@ static struct hlist_head *fib_hash_alloc(int bytes) return kzalloc(bytes, GFP_KERNEL); else return (struct hlist_head *) - __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(bytes)); + __get_free_pages(GFP_KERNEL | __GFP_ZERO, + get_order(bytes)); } static void fib_hash_free(struct hlist_head *hash, int bytes) @@ -806,7 +826,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) goto failure; } else { change_nexthops(fi) { - if ((err = fib_check_nh(cfg, fi, nexthop_nh)) != 0) + err = fib_check_nh(cfg, fi, nexthop_nh); + if (err != 0) goto failure; } endfor_nexthops(fi) } @@ -819,7 +840,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) } link_it: - if ((ofi = fib_find_info(fi)) != NULL) { + ofi = fib_find_info(fi); + if (ofi) { fi->fib_dead = 1; free_fib_info(fi); ofi->fib_treeref++; @@ -864,7 +886,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) /* Note! fib_semantic_match intentionally uses RCU list functions. */ int fib_semantic_match(struct list_head *head, const struct flowi *flp, - struct fib_result *res, int prefixlen) + struct fib_result *res, int prefixlen, int fib_flags) { struct fib_alias *fa; int nh_sel = 0; @@ -879,7 +901,7 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp, if (fa->fa_scope < flp->fl4_scope) continue; - fa->fa_state |= FA_S_ACCESSED; + fib_alias_accessed(fa); err = fib_props[fa->fa_type].error; if (err == 0) { @@ -895,7 +917,7 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp, case RTN_ANYCAST: case RTN_MULTICAST: for_nexthops(fi) { - if (nh->nh_flags&RTNH_F_DEAD) + if (nh->nh_flags & RTNH_F_DEAD) continue; if (!flp->oif || flp->oif == nh->nh_oif) break; @@ -906,16 +928,15 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp, goto out_fill_res; } #else - if (nhsel < 1) { + if (nhsel < 1) goto out_fill_res; - } #endif endfor_nexthops(fi); continue; default: - printk(KERN_WARNING "fib_semantic_match bad type %#x\n", - fa->fa_type); + pr_warning("fib_semantic_match bad type %#x\n", + fa->fa_type); return -EINVAL; } } @@ -929,7 +950,8 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp, res->type = fa->fa_type; res->scope = fa->fa_scope; res->fi = fa->fa_info; - atomic_inc(&res->fi->fib_clntref); + if (!(fib_flags & FIB_LOOKUP_NOREF)) + atomic_inc(&res->fi->fib_clntref); return 0; } @@ -1028,10 +1050,10 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, } /* - Update FIB if: - - local address disappeared -> we must delete all the entries - referring to it. - - device went down -> we must shutdown all nexthops going via it. + * Update FIB if: + * - local address disappeared -> we must delete all the entries + * referring to it. + * - device went down -> we must shutdown all nexthops going via it. */ int fib_sync_down_addr(struct net *net, __be32 local) { @@ -1078,7 +1100,7 @@ int fib_sync_down_dev(struct net_device *dev, int force) prev_fi = fi; dead = 0; change_nexthops(fi) { - if (nexthop_nh->nh_flags&RTNH_F_DEAD) + if (nexthop_nh->nh_flags & RTNH_F_DEAD) dead++; else if (nexthop_nh->nh_dev == dev && nexthop_nh->nh_scope != scope) { @@ -1110,10 +1132,9 @@ int fib_sync_down_dev(struct net_device *dev, int force) #ifdef CONFIG_IP_ROUTE_MULTIPATH /* - Dead device goes up. We wake up dead nexthops. - It takes sense only on multipath routes. + * Dead device goes up. We wake up dead nexthops. + * It takes sense only on multipath routes. */ - int fib_sync_up(struct net_device *dev) { struct fib_info *prev_fi; @@ -1123,7 +1144,7 @@ int fib_sync_up(struct net_device *dev) struct fib_nh *nh; int ret; - if (!(dev->flags&IFF_UP)) + if (!(dev->flags & IFF_UP)) return 0; prev_fi = NULL; @@ -1142,12 +1163,12 @@ int fib_sync_up(struct net_device *dev) prev_fi = fi; alive = 0; change_nexthops(fi) { - if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) { + if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) { alive++; continue; } if (nexthop_nh->nh_dev == NULL || - !(nexthop_nh->nh_dev->flags&IFF_UP)) + !(nexthop_nh->nh_dev->flags & IFF_UP)) continue; if (nexthop_nh->nh_dev != dev || !__in_dev_get_rtnl(dev)) @@ -1169,10 +1190,9 @@ int fib_sync_up(struct net_device *dev) } /* - The algorithm is suboptimal, but it provides really - fair weighted route distribution. + * The algorithm is suboptimal, but it provides really + * fair weighted route distribution. */ - void fib_select_multipath(const struct flowi *flp, struct fib_result *res) { struct fib_info *fi = res->fi; @@ -1182,7 +1202,7 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res) if (fi->fib_power <= 0) { int power = 0; change_nexthops(fi) { - if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) { + if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) { power += nexthop_nh->nh_weight; nexthop_nh->nh_power = nexthop_nh->nh_weight; } @@ -1198,15 +1218,16 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res) /* w should be random number [0..fi->fib_power-1], - it is pretty bad approximation. + * it is pretty bad approximation. */ w = jiffies % fi->fib_power; change_nexthops(fi) { - if (!(nexthop_nh->nh_flags&RTNH_F_DEAD) && + if (!(nexthop_nh->nh_flags & RTNH_F_DEAD) && nexthop_nh->nh_power) { - if ((w -= nexthop_nh->nh_power) <= 0) { + w -= nexthop_nh->nh_power; + if (w <= 0) { nexthop_nh->nh_power--; fi->fib_power--; res->nh_sel = nhsel; diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 4a8e370862bca453cd6e939162ded09de6bdf831..cd5e13aee7d5b689b76c834673d70dd7c334361e 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -186,9 +186,7 @@ static inline struct tnode *node_parent_rcu(struct node *node) { struct tnode *ret = node_parent(node); - return rcu_dereference_check(ret, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + return rcu_dereference_rtnl(ret); } /* Same as rcu_assign_pointer @@ -211,9 +209,7 @@ static inline struct node *tnode_get_child_rcu(struct tnode *tn, unsigned int i) { struct node *ret = tnode_get_child(tn, i); - return rcu_dereference_check(ret, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + return rcu_dereference_rtnl(ret); } static inline int tnode_child_length(const struct tnode *tn) @@ -459,8 +455,8 @@ static struct tnode *tnode_new(t_key key, int pos, int bits) tn->empty_children = 1<trie, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + n = rcu_dereference_rtnl(t->trie); while (n != NULL && NODE_TYPE(n) == T_TNODE) { tn = (struct tnode *) n; @@ -1349,7 +1342,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) /* should be called with rcu_read_lock */ static int check_leaf(struct trie *t, struct leaf *l, t_key key, const struct flowi *flp, - struct fib_result *res) + struct fib_result *res, int fib_flags) { struct leaf_info *li; struct hlist_head *hhead = &l->list; @@ -1363,7 +1356,7 @@ static int check_leaf(struct trie *t, struct leaf *l, if (l->key != (key & ntohl(mask))) continue; - err = fib_semantic_match(&li->falh, flp, res, plen); + err = fib_semantic_match(&li->falh, flp, res, plen, fib_flags); #ifdef CONFIG_IP_FIB_TRIE_STATS if (err <= 0) @@ -1379,7 +1372,7 @@ static int check_leaf(struct trie *t, struct leaf *l, } int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, - struct fib_result *res) + struct fib_result *res, int fib_flags) { struct trie *t = (struct trie *) tb->tb_data; int ret; @@ -1391,8 +1384,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, t_key cindex = 0; int current_prefix_length = KEYLENGTH; struct tnode *cn; - t_key node_prefix, key_prefix, pref_mismatch; - int mp; + t_key pref_mismatch; rcu_read_lock(); @@ -1406,7 +1398,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, /* Just a leaf? */ if (IS_LEAF(n)) { - ret = check_leaf(t, (struct leaf *)n, key, flp, res); + ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags); goto found; } @@ -1431,7 +1423,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, } if (IS_LEAF(n)) { - ret = check_leaf(t, (struct leaf *)n, key, flp, res); + ret = check_leaf(t, (struct leaf *)n, key, flp, res, fib_flags); if (ret > 0) goto backtrace; goto found; @@ -1507,10 +1499,7 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, * matching prefix. */ - node_prefix = mask_pfx(cn->key, cn->pos); - key_prefix = mask_pfx(key, cn->pos); - pref_mismatch = key_prefix^node_prefix; - mp = 0; + pref_mismatch = mask_pfx(cn->key ^ key, cn->pos); /* * In short: If skipped bits in this node do not match @@ -1518,13 +1507,9 @@ int fib_table_lookup(struct fib_table *tb, const struct flowi *flp, * state.directly. */ if (pref_mismatch) { - while (!(pref_mismatch & (1<<(KEYLENGTH-1)))) { - mp++; - pref_mismatch = pref_mismatch << 1; - } - key_prefix = tkey_extract_bits(cn->key, mp, cn->pos-mp); + int mp = KEYLENGTH - fls(pref_mismatch); - if (key_prefix != 0) + if (tkey_extract_bits(cn->key, mp, cn->pos - mp) != 0) goto backtrace; if (current_prefix_length >= cn->pos) @@ -1748,16 +1733,14 @@ static struct leaf *leaf_walk_rcu(struct tnode *p, struct node *c) /* Node empty, walk back up to parent */ c = (struct node *) p; - } while ( (p = node_parent_rcu(c)) != NULL); + } while ((p = node_parent_rcu(c)) != NULL); return NULL; /* Root of trie */ } static struct leaf *trie_firstleaf(struct trie *t) { - struct tnode *n = (struct tnode *) rcu_dereference_check(t->trie, - rcu_read_lock_held() || - lockdep_rtnl_is_held()); + struct tnode *n = (struct tnode *)rcu_dereference_rtnl(t->trie); if (!n) return NULL; @@ -1855,7 +1838,8 @@ void fib_table_select_default(struct fib_table *tb, if (!next_fi->fib_nh[0].nh_gw || next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK) continue; - fa->fa_state |= FA_S_ACCESSED; + + fib_alias_accessed(fa); if (fi == NULL) { if (next_fi != res->fi) @@ -2043,14 +2027,14 @@ struct fib_trie_iter { struct seq_net_private p; struct fib_table *tb; struct tnode *tnode; - unsigned index; - unsigned depth; + unsigned int index; + unsigned int depth; }; static struct node *fib_trie_get_next(struct fib_trie_iter *iter) { struct tnode *tn = iter->tnode; - unsigned cindex = iter->index; + unsigned int cindex = iter->index; struct tnode *p; /* A single entry routing table */ @@ -2159,7 +2143,7 @@ static void trie_collect_stats(struct trie *t, struct trie_stat *s) */ static void trie_show_stats(struct seq_file *seq, struct trie_stat *stat) { - unsigned i, max, pointers, bytes, avdepth; + unsigned int i, max, pointers, bytes, avdepth; if (stat->leaves) avdepth = stat->totdepth*100 / stat->leaves; @@ -2356,7 +2340,8 @@ static void fib_trie_seq_stop(struct seq_file *seq, void *v) static void seq_indent(struct seq_file *seq, int n) { - while (n-- > 0) seq_puts(seq, " "); + while (n-- > 0) + seq_puts(seq, " "); } static inline const char *rtn_scope(char *buf, size_t len, enum rt_scope_t s) @@ -2388,7 +2373,7 @@ static const char *const rtn_type_names[__RTN_MAX] = { [RTN_XRESOLVE] = "XRESOLVE", }; -static inline const char *rtn_type(char *buf, size_t len, unsigned t) +static inline const char *rtn_type(char *buf, size_t len, unsigned int t) { if (t < __RTN_MAX && rtn_type_names[t]) return rtn_type_names[t]; @@ -2544,13 +2529,12 @@ static void fib_route_seq_stop(struct seq_file *seq, void *v) rcu_read_unlock(); } -static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) +static unsigned int fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) { - static unsigned type2flags[RTN_MAX + 1] = { - [7] = RTF_REJECT, [8] = RTF_REJECT, - }; - unsigned flags = type2flags[type]; + unsigned int flags = 0; + if (type == RTN_UNREACHABLE || type == RTN_PROHIBIT) + flags = RTF_REJECT; if (fi && fi->fib_nh->nh_gw) flags |= RTF_GATEWAY; if (mask == htonl(0xFFFFFFFF)) @@ -2562,7 +2546,7 @@ static unsigned fib_flag_trans(int type, __be32 mask, const struct fib_info *fi) /* * This outputs /proc/net/route. * The format of the file is not supposed to be changed - * and needs to be same as fib_hash output to avoid breaking + * and needs to be same as fib_hash output to avoid breaking * legacy utilities */ static int fib_route_seq_show(struct seq_file *seq, void *v) @@ -2587,7 +2571,7 @@ static int fib_route_seq_show(struct seq_file *seq, void *v) list_for_each_entry_rcu(fa, &li->falh, fa_list) { const struct fib_info *fi = fa->fa_info; - unsigned flags = fib_flag_trans(fa->fa_type, mask, fi); + unsigned int flags = fib_flag_trans(fa->fa_type, mask, fi); int len; if (fa->fa_type == RTN_BROADCAST diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c new file mode 100644 index 0000000000000000000000000000000000000000..caea6885fdbd0810ea3e8d9eeefd5f74282a0930 --- /dev/null +++ b/net/ipv4/gre.c @@ -0,0 +1,151 @@ +/* + * GRE over IPv4 demultiplexer driver + * + * Authors: Dmitry Kozlov (xeb@mail.ru) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +static const struct gre_protocol *gre_proto[GREPROTO_MAX] __read_mostly; +static DEFINE_SPINLOCK(gre_proto_lock); + +int gre_add_protocol(const struct gre_protocol *proto, u8 version) +{ + if (version >= GREPROTO_MAX) + goto err_out; + + spin_lock(&gre_proto_lock); + if (gre_proto[version]) + goto err_out_unlock; + + rcu_assign_pointer(gre_proto[version], proto); + spin_unlock(&gre_proto_lock); + return 0; + +err_out_unlock: + spin_unlock(&gre_proto_lock); +err_out: + return -1; +} +EXPORT_SYMBOL_GPL(gre_add_protocol); + +int gre_del_protocol(const struct gre_protocol *proto, u8 version) +{ + if (version >= GREPROTO_MAX) + goto err_out; + + spin_lock(&gre_proto_lock); + if (gre_proto[version] != proto) + goto err_out_unlock; + rcu_assign_pointer(gre_proto[version], NULL); + spin_unlock(&gre_proto_lock); + synchronize_rcu(); + return 0; + +err_out_unlock: + spin_unlock(&gre_proto_lock); +err_out: + return -1; +} +EXPORT_SYMBOL_GPL(gre_del_protocol); + +static int gre_rcv(struct sk_buff *skb) +{ + const struct gre_protocol *proto; + u8 ver; + int ret; + + if (!pskb_may_pull(skb, 12)) + goto drop; + + ver = skb->data[1]&0x7f; + if (ver >= GREPROTO_MAX) + goto drop; + + rcu_read_lock(); + proto = rcu_dereference(gre_proto[ver]); + if (!proto || !proto->handler) + goto drop_unlock; + ret = proto->handler(skb); + rcu_read_unlock(); + return ret; + +drop_unlock: + rcu_read_unlock(); +drop: + kfree_skb(skb); + return NET_RX_DROP; +} + +static void gre_err(struct sk_buff *skb, u32 info) +{ + const struct gre_protocol *proto; + u8 ver; + + if (!pskb_may_pull(skb, 12)) + goto drop; + + ver = skb->data[1]&0x7f; + if (ver >= GREPROTO_MAX) + goto drop; + + rcu_read_lock(); + proto = rcu_dereference(gre_proto[ver]); + if (!proto || !proto->err_handler) + goto drop_unlock; + proto->err_handler(skb, info); + rcu_read_unlock(); + return; + +drop_unlock: + rcu_read_unlock(); +drop: + kfree_skb(skb); +} + +static const struct net_protocol net_gre_protocol = { + .handler = gre_rcv, + .err_handler = gre_err, + .netns_ok = 1, +}; + +static int __init gre_init(void) +{ + pr_info("GRE over IPv4 demultiplexor driver"); + + if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) { + pr_err("gre: can't add protocol\n"); + return -EAGAIN; + } + + return 0; +} + +static void __exit gre_exit(void) +{ + inet_del_protocol(&net_gre_protocol, IPPROTO_GRE); +} + +module_init(gre_init); +module_exit(gre_exit); + +MODULE_DESCRIPTION("GRE over IPv4 demultiplexer driver"); +MODULE_AUTHOR("D. Kozlov (xeb@mail.ru)"); +MODULE_LICENSE("GPL"); + diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index a0d847c7cba5c89aec43b340036bf456468f9e9a..96bc7f9475a3f2f0124685cc1b7afb7b58c23d8d 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -379,7 +379,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) inet->tos = ip_hdr(skb)->tos; daddr = ipc.addr = rt->rt_src; ipc.opt = NULL; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; if (icmp_param->replyopts.optlen) { ipc.opt = &icmp_param->replyopts; if (ipc.opt->srr) @@ -538,7 +538,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) inet_sk(sk)->tos = tos; ipc.addr = iph->saddr; ipc.opt = &icmp_param.replyopts; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; { struct flowi fl = { diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 2a4bb76f2132957da25326ce98653b249d9ccaaf..c8877c6c72164ccaee2af4def0025f8300bc7e80 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1269,14 +1269,14 @@ void ip_mc_rejoin_group(struct ip_mc_list *im) if (im->multiaddr == IGMP_ALL_HOSTS) return; - if (IGMP_V1_SEEN(in_dev) || IGMP_V2_SEEN(in_dev)) { - igmp_mod_timer(im, IGMP_Initial_Report_Delay); - return; - } - /* else, v3 */ - im->crcount = in_dev->mr_qrv ? in_dev->mr_qrv : - IGMP_Unsolicited_Report_Count; - igmp_ifc_event(in_dev); + /* a failover is happening and switches + * must be notified immediately */ + if (IGMP_V1_SEEN(in_dev)) + igmp_send_report(in_dev, im, IGMP_HOST_MEMBERSHIP_REPORT); + else if (IGMP_V2_SEEN(in_dev)) + igmp_send_report(in_dev, im, IGMPV2_HOST_MEMBERSHIP_REPORT); + else + igmp_send_report(in_dev, im, IGMPV3_HOST_MEMBERSHIP_REPORT); #endif } EXPORT_SYMBOL(ip_mc_rejoin_group); @@ -1418,6 +1418,7 @@ void ip_mc_destroy_dev(struct in_device *in_dev) write_unlock_bh(&in_dev->mc_list_lock); } +/* RTNL is locked */ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) { struct flowi fl = { .nl_u = { .ip4_u = @@ -1428,15 +1429,12 @@ static struct in_device *ip_mc_find_dev(struct net *net, struct ip_mreqn *imr) if (imr->imr_ifindex) { idev = inetdev_by_index(net, imr->imr_ifindex); - if (idev) - __in_dev_put(idev); return idev; } if (imr->imr_address.s_addr) { - dev = ip_dev_find(net, imr->imr_address.s_addr); + dev = __ip_dev_find(net, imr->imr_address.s_addr, false); if (!dev) return NULL; - dev_put(dev); } if (!dev && !ip_route_output_key(net, &rt, &fl)) { diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index e5fa2ddce320adafac68cdbf19bfefdae534cf2c..ba80426658498ba4082c54a19c5af2d2c00cdb10 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -425,7 +425,7 @@ static int inet_diag_bc_run(const void *bc, int len, bc += op->no; } } - return (len == 0); + return len == 0; } static int valid_cc(const void *bc, int len, int cc) diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index fb7ad5a21ff3e2e86b2d9018ea29ccd2e3921848..1b344f30b463fab9ed70a8f19a19d348d7c626f7 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -101,19 +101,43 @@ void inet_put_port(struct sock *sk) } EXPORT_SYMBOL(inet_put_port); -void __inet_inherit_port(struct sock *sk, struct sock *child) +int __inet_inherit_port(struct sock *sk, struct sock *child) { struct inet_hashinfo *table = sk->sk_prot->h.hashinfo; - const int bhash = inet_bhashfn(sock_net(sk), inet_sk(child)->inet_num, + unsigned short port = inet_sk(child)->inet_num; + const int bhash = inet_bhashfn(sock_net(sk), port, table->bhash_size); struct inet_bind_hashbucket *head = &table->bhash[bhash]; struct inet_bind_bucket *tb; spin_lock(&head->lock); tb = inet_csk(sk)->icsk_bind_hash; + if (tb->port != port) { + /* NOTE: using tproxy and redirecting skbs to a proxy + * on a different listener port breaks the assumption + * that the listener socket's icsk_bind_hash is the same + * as that of the child socket. We have to look up or + * create a new bind bucket for the child here. */ + struct hlist_node *node; + inet_bind_bucket_for_each(tb, node, &head->chain) { + if (net_eq(ib_net(tb), sock_net(sk)) && + tb->port == port) + break; + } + if (!node) { + tb = inet_bind_bucket_create(table->bind_bucket_cachep, + sock_net(sk), head, port); + if (!tb) { + spin_unlock(&head->lock); + return -ENOMEM; + } + } + } sk_add_bind_node(child, &tb->owners); inet_csk(child)->icsk_bind_hash = tb; spin_unlock(&head->lock); + + return 0; } EXPORT_SYMBOL_GPL(__inet_inherit_port); diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index b7c41654dde543ff310ac63aa696d65a58fd4d36..168440834adedd4935b05229b533c6dad9b16e81 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -116,11 +116,11 @@ static int ip4_frag_match(struct inet_frag_queue *q, void *a) struct ip4_create_arg *arg = a; qp = container_of(q, struct ipq, q); - return (qp->id == arg->iph->id && + return qp->id == arg->iph->id && qp->saddr == arg->iph->saddr && qp->daddr == arg->iph->daddr && qp->protocol == arg->iph->protocol && - qp->user == arg->user); + qp->user == arg->user; } /* Memory Tracking Functions. */ @@ -542,7 +542,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_has_frag_list(head)) { struct sk_buff *clone; int i, plen = 0; diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 35c93e8b6a4694561c838641e546b609e8cbfaa0..d0ffcbe369b76b4a000c5f5e23b6e61dc64fb3dd 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -44,6 +44,7 @@ #include #include #include +#include #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) #include @@ -63,13 +64,13 @@ We cannot track such dead loops during route installation, it is infeasible task. The most general solutions would be to keep skb->encapsulation counter (sort of local ttl), - and silently drop packet when it expires. It is the best + and silently drop packet when it expires. It is a good solution, but it supposes maintaing new variable in ALL skb, even if no tunneling is used. - Current solution: HARD_TX_LOCK lock breaks dead loops. - - + Current solution: xmit_recursion breaks dead loops. This is a percpu + counter, since when we enter the first ndo_xmit(), cpu migration is + forbidden. We force an exit if this counter reaches RECURSION_LIMIT 2. Networking dead loops would not kill routers, but would really kill network. IP hop limit plays role of "t->recursion" in this case, @@ -128,7 +129,7 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev); static int ipgre_net_id __read_mostly; struct ipgre_net { - struct ip_tunnel *tunnels[4][HASH_SIZE]; + struct ip_tunnel __rcu *tunnels[4][HASH_SIZE]; struct net_device *fb_tunnel_dev; }; @@ -158,13 +159,40 @@ struct ipgre_net { #define tunnels_l tunnels[1] #define tunnels_wc tunnels[0] /* - * Locking : hash tables are protected by RCU and a spinlock + * Locking : hash tables are protected by RCU and RTNL */ -static DEFINE_SPINLOCK(ipgre_lock); #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) +/* often modified stats are per cpu, other are shared (netdev->stats) */ +struct pcpu_tstats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +static struct net_device_stats *ipgre_get_stats(struct net_device *dev) +{ + struct pcpu_tstats sum = { 0 }; + int i; + + for_each_possible_cpu(i) { + const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); + + sum.rx_packets += tstats->rx_packets; + sum.rx_bytes += tstats->rx_bytes; + sum.tx_packets += tstats->tx_packets; + sum.tx_bytes += tstats->tx_bytes; + } + dev->stats.rx_packets = sum.rx_packets; + dev->stats.rx_bytes = sum.rx_bytes; + dev->stats.tx_packets = sum.tx_packets; + dev->stats.tx_bytes = sum.tx_bytes; + return &dev->stats; +} + /* Given src, dst and key, find appropriate for input tunnel. */ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev, @@ -173,8 +201,8 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev, { struct net *net = dev_net(dev); int link = dev->ifindex; - unsigned h0 = HASH(remote); - unsigned h1 = HASH(key); + unsigned int h0 = HASH(remote); + unsigned int h1 = HASH(key); struct ip_tunnel *t, *cand = NULL; struct ipgre_net *ign = net_generic(net, ipgre_net_id); int dev_type = (gre_proto == htons(ETH_P_TEB)) ? @@ -289,13 +317,13 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev, return NULL; } -static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign, +static struct ip_tunnel __rcu **__ipgre_bucket(struct ipgre_net *ign, struct ip_tunnel_parm *parms) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; __be32 key = parms->i_key; - unsigned h = HASH(key); + unsigned int h = HASH(key); int prio = 0; if (local) @@ -308,7 +336,7 @@ static struct ip_tunnel **__ipgre_bucket(struct ipgre_net *ign, return &ign->tunnels[prio][h]; } -static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign, +static inline struct ip_tunnel __rcu **ipgre_bucket(struct ipgre_net *ign, struct ip_tunnel *t) { return __ipgre_bucket(ign, &t->parms); @@ -316,23 +344,22 @@ static inline struct ip_tunnel **ipgre_bucket(struct ipgre_net *ign, static void ipgre_tunnel_link(struct ipgre_net *ign, struct ip_tunnel *t) { - struct ip_tunnel **tp = ipgre_bucket(ign, t); + struct ip_tunnel __rcu **tp = ipgre_bucket(ign, t); - spin_lock_bh(&ipgre_lock); - t->next = *tp; + rcu_assign_pointer(t->next, rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); - spin_unlock_bh(&ipgre_lock); } static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t) { - struct ip_tunnel **tp; - - for (tp = ipgre_bucket(ign, t); *tp; tp = &(*tp)->next) { - if (t == *tp) { - spin_lock_bh(&ipgre_lock); - *tp = t->next; - spin_unlock_bh(&ipgre_lock); + struct ip_tunnel __rcu **tp; + struct ip_tunnel *iter; + + for (tp = ipgre_bucket(ign, t); + (iter = rtnl_dereference(*tp)) != NULL; + tp = &iter->next) { + if (t == iter) { + rcu_assign_pointer(*tp, t->next); break; } } @@ -346,10 +373,13 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net, __be32 local = parms->iph.saddr; __be32 key = parms->i_key; int link = parms->link; - struct ip_tunnel *t, **tp; + struct ip_tunnel *t; + struct ip_tunnel __rcu **tp; struct ipgre_net *ign = net_generic(net, ipgre_net_id); - for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next) + for (tp = __ipgre_bucket(ign, parms); + (t = rtnl_dereference(*tp)) != NULL; + tp = &t->next) if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr && key == t->parms.i_key && @@ -360,7 +390,7 @@ static struct ip_tunnel *ipgre_tunnel_find(struct net *net, return t; } -static struct ip_tunnel * ipgre_tunnel_locate(struct net *net, +static struct ip_tunnel *ipgre_tunnel_locate(struct net *net, struct ip_tunnel_parm *parms, int create) { struct ip_tunnel *t, *nt; @@ -582,7 +612,7 @@ static int ipgre_rcv(struct sk_buff *skb) if ((tunnel = ipgre_tunnel_lookup(skb->dev, iph->saddr, iph->daddr, key, gre_proto))) { - struct net_device_stats *stats = &tunnel->dev->stats; + struct pcpu_tstats *tstats; secpath_reset(skb); @@ -606,22 +636,22 @@ static int ipgre_rcv(struct sk_buff *skb) /* Looped back packet, drop it! */ if (skb_rtable(skb)->fl.iif == 0) goto drop; - stats->multicast++; + tunnel->dev->stats.multicast++; skb->pkt_type = PACKET_BROADCAST; } #endif if (((flags&GRE_CSUM) && csum) || (!(flags&GRE_CSUM) && tunnel->parms.i_flags&GRE_CSUM)) { - stats->rx_crc_errors++; - stats->rx_errors++; + tunnel->dev->stats.rx_crc_errors++; + tunnel->dev->stats.rx_errors++; goto drop; } if (tunnel->parms.i_flags&GRE_SEQ) { if (!(flags&GRE_SEQ) || (tunnel->i_seqno && (s32)(seqno - tunnel->i_seqno) < 0)) { - stats->rx_fifo_errors++; - stats->rx_errors++; + tunnel->dev->stats.rx_fifo_errors++; + tunnel->dev->stats.rx_errors++; goto drop; } tunnel->i_seqno = seqno + 1; @@ -630,8 +660,8 @@ static int ipgre_rcv(struct sk_buff *skb) /* Warning: All skb pointers will be invalidated! */ if (tunnel->dev->type == ARPHRD_ETHER) { if (!pskb_may_pull(skb, ETH_HLEN)) { - stats->rx_length_errors++; - stats->rx_errors++; + tunnel->dev->stats.rx_length_errors++; + tunnel->dev->stats.rx_errors++; goto drop; } @@ -640,14 +670,19 @@ static int ipgre_rcv(struct sk_buff *skb) skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN); } - skb_tunnel_rx(skb, tunnel->dev); + tstats = this_cpu_ptr(tunnel->dev->tstats); + tstats->rx_packets++; + tstats->rx_bytes += skb->len; + + __skb_tunnel_rx(skb, tunnel->dev); skb_reset_network_header(skb); ipgre_ecn_decapsulate(iph, skb); netif_rx(skb); + rcu_read_unlock(); - return(0); + return 0; } icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); @@ -655,20 +690,19 @@ static int ipgre_rcv(struct sk_buff *skb) rcu_read_unlock(); drop_nolock: kfree_skb(skb); - return(0); + return 0; } static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; - struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); + struct pcpu_tstats *tstats; struct iphdr *old_iph = ip_hdr(skb); struct iphdr *tiph; u8 tos; __be16 df; struct rtable *rt; /* Route to the other host */ - struct net_device *tdev; /* Device to other host */ + struct net_device *tdev; /* Device to other host */ struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ int gre_hlen; @@ -690,7 +724,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev /* NBMA tunnel */ if (skb_dst(skb) == NULL) { - stats->tx_fifo_errors++; + dev->stats.tx_fifo_errors++; goto tx_error; } @@ -736,14 +770,20 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev } { - struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { .ip4_u = - { .daddr = dst, - .saddr = tiph->saddr, - .tos = RT_TOS(tos) } }, - .proto = IPPROTO_GRE }; + struct flowi fl = { + .oif = tunnel->parms.link, + .nl_u = { + .ip4_u = { + .daddr = dst, + .saddr = tiph->saddr, + .tos = RT_TOS(tos) + } + }, + .proto = IPPROTO_GRE + } +; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { - stats->tx_carrier_errors++; + dev->stats.tx_carrier_errors++; goto tx_error; } } @@ -751,7 +791,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev if (tdev == dev) { ip_rt_put(rt); - stats->collisions++; + dev->stats.collisions++; goto tx_error; } @@ -814,7 +854,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev dev->needed_headroom = max_headroom; if (!new_skb) { ip_rt_put(rt); - txq->tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -881,15 +921,15 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev } nf_reset(skb); - - IPTUNNEL_XMIT(); + tstats = this_cpu_ptr(dev->tstats); + __IPTUNNEL_XMIT(tstats, &dev->stats); return NETDEV_TX_OK; tx_error_icmp: dst_link_failure(skb); tx_error: - stats->tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -909,13 +949,19 @@ static int ipgre_tunnel_bind_dev(struct net_device *dev) /* Guess output device to choose reasonable mtu and needed_headroom */ if (iph->daddr) { - struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { .ip4_u = - { .daddr = iph->daddr, - .saddr = iph->saddr, - .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_GRE }; + struct flowi fl = { + .oif = tunnel->parms.link, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_GRE + }; struct rtable *rt; + if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { tdev = rt->dst.dev; ip_rt_put(rt); @@ -1012,7 +1058,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) break; } } else { - unsigned nflags = 0; + unsigned int nflags = 0; t = netdev_priv(dev); @@ -1125,7 +1171,7 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - const void *daddr, const void *saddr, unsigned len) + const void *daddr, const void *saddr, unsigned int len) { struct ip_tunnel *t = netdev_priv(dev); struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen); @@ -1167,13 +1213,19 @@ static int ipgre_open(struct net_device *dev) struct ip_tunnel *t = netdev_priv(dev); if (ipv4_is_multicast(t->parms.iph.daddr)) { - struct flowi fl = { .oif = t->parms.link, - .nl_u = { .ip4_u = - { .daddr = t->parms.iph.daddr, - .saddr = t->parms.iph.saddr, - .tos = RT_TOS(t->parms.iph.tos) } }, - .proto = IPPROTO_GRE }; + struct flowi fl = { + .oif = t->parms.link, + .nl_u = { + .ip4_u = { + .daddr = t->parms.iph.daddr, + .saddr = t->parms.iph.saddr, + .tos = RT_TOS(t->parms.iph.tos) + } + }, + .proto = IPPROTO_GRE + }; struct rtable *rt; + if (ip_route_output_key(dev_net(dev), &rt, &fl)) return -EADDRNOTAVAIL; dev = rt->dst.dev; @@ -1193,10 +1245,8 @@ static int ipgre_close(struct net_device *dev) if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) { struct in_device *in_dev; in_dev = inetdev_by_index(dev_net(dev), t->mlink); - if (in_dev) { + if (in_dev) ip_mc_dec_group(in_dev, t->parms.iph.daddr); - in_dev_put(in_dev); - } } return 0; } @@ -1213,12 +1263,19 @@ static const struct net_device_ops ipgre_netdev_ops = { .ndo_start_xmit = ipgre_tunnel_xmit, .ndo_do_ioctl = ipgre_tunnel_ioctl, .ndo_change_mtu = ipgre_tunnel_change_mtu, + .ndo_get_stats = ipgre_get_stats, }; +static void ipgre_dev_free(struct net_device *dev) +{ + free_percpu(dev->tstats); + free_netdev(dev); +} + static void ipgre_tunnel_setup(struct net_device *dev) { dev->netdev_ops = &ipgre_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ipgre_dev_free; dev->type = ARPHRD_IPGRE; dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4; @@ -1256,6 +1313,10 @@ static int ipgre_tunnel_init(struct net_device *dev) } else dev->header_ops = &ipgre_header_ops; + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + return 0; } @@ -1274,14 +1335,13 @@ static void ipgre_fb_tunnel_init(struct net_device *dev) tunnel->hlen = sizeof(struct iphdr) + 4; dev_hold(dev); - ign->tunnels_wc[0] = tunnel; + rcu_assign_pointer(ign->tunnels_wc[0], tunnel); } -static const struct net_protocol ipgre_protocol = { - .handler = ipgre_rcv, - .err_handler = ipgre_err, - .netns_ok = 1, +static const struct gre_protocol ipgre_protocol = { + .handler = ipgre_rcv, + .err_handler = ipgre_err, }; static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head) @@ -1291,11 +1351,13 @@ static void ipgre_destroy_tunnels(struct ipgre_net *ign, struct list_head *head) for (prio = 0; prio < 4; prio++) { int h; for (h = 0; h < HASH_SIZE; h++) { - struct ip_tunnel *t = ign->tunnels[prio][h]; + struct ip_tunnel *t; + + t = rtnl_dereference(ign->tunnels[prio][h]); while (t != NULL) { unregister_netdevice_queue(t->dev, head); - t = t->next; + t = rtnl_dereference(t->next); } } } @@ -1441,6 +1503,10 @@ static int ipgre_tap_init(struct net_device *dev) ipgre_tunnel_bind_dev(dev); + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + return 0; } @@ -1451,6 +1517,7 @@ static const struct net_device_ops ipgre_tap_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, .ndo_change_mtu = ipgre_tunnel_change_mtu, + .ndo_get_stats = ipgre_get_stats, }; static void ipgre_tap_setup(struct net_device *dev) @@ -1459,7 +1526,7 @@ static void ipgre_tap_setup(struct net_device *dev) ether_setup(dev); dev->netdev_ops = &ipgre_tap_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ipgre_dev_free; dev->iflink = 0; dev->features |= NETIF_F_NETNS_LOCAL; @@ -1487,6 +1554,10 @@ static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nla if (!tb[IFLA_MTU]) dev->mtu = mtu; + /* Can use a lockless transmit, unless we generate output sequences */ + if (!(nt->parms.o_flags & GRE_SEQ)) + dev->features |= NETIF_F_LLTX; + err = register_netdevice(dev); if (err) goto out; @@ -1522,7 +1593,7 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], t = nt; if (dev->type != ARPHRD_ETHER) { - unsigned nflags = 0; + unsigned int nflags = 0; if (ipv4_is_multicast(p.iph.daddr)) nflags = IFF_BROADCAST; @@ -1663,7 +1734,7 @@ static int __init ipgre_init(void) if (err < 0) return err; - err = inet_add_protocol(&ipgre_protocol, IPPROTO_GRE); + err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO); if (err < 0) { printk(KERN_INFO "ipgre init: can't add protocol\n"); goto add_proto_failed; @@ -1683,7 +1754,7 @@ static int __init ipgre_init(void) tap_ops_failed: rtnl_link_unregister(&ipgre_link_ops); rtnl_link_failed: - inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); + gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO); add_proto_failed: unregister_pernet_device(&ipgre_net_ops); goto out; @@ -1693,7 +1764,7 @@ static void __exit ipgre_fini(void) { rtnl_link_unregister(&ipgre_tap_ops); rtnl_link_unregister(&ipgre_link_ops); - if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) + if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0) printk(KERN_INFO "ipgre close: can't remove protocol\n"); unregister_pernet_device(&ipgre_net_ops); } diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index ba9836c488ed915388e4c9d38b842bef8b241dda..1906fa35860c88a0919cd434268cbbcd679a3c39 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -466,7 +466,7 @@ int ip_options_compile(struct net *net, } return -EINVAL; } - +EXPORT_SYMBOL(ip_options_compile); /* * Undo all the changes done by ip_options_compile(). @@ -646,3 +646,4 @@ int ip_options_rcv_srr(struct sk_buff *skb) } return 0; } +EXPORT_SYMBOL(ip_options_rcv_srr); diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 7649d7750075d184896a9da6d37ed9a35ea5f403..439d2a34ee4411b932eefb3a6fc51383e8db7125 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -487,7 +487,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) * LATER: this step can be merged to real generation of fragments, * we can switch to copy when see the first bad fragment. */ - if (skb_has_frags(skb)) { + if (skb_has_frag_list(skb)) { struct sk_buff *frag, *frag2; int first_len = skb_pagelen(skb); @@ -844,10 +844,9 @@ int ip_append_data(struct sock *sk, inet->cork.length = 0; sk->sk_sndmsg_page = NULL; sk->sk_sndmsg_off = 0; - if ((exthdrlen = rt->dst.header_len) != 0) { - length += exthdrlen; - transhdrlen += exthdrlen; - } + exthdrlen = rt->dst.header_len; + length += exthdrlen; + transhdrlen += exthdrlen; } else { rt = (struct rtable *)inet->cork.dst; if (inet->cork.flags & IPCORK_OPT) @@ -934,16 +933,19 @@ int ip_append_data(struct sock *sk, !(rt->dst.dev->features&NETIF_F_SG)) alloclen = mtu; else - alloclen = datalen + fragheaderlen; + alloclen = fraglen; /* The last fragment gets additional space at tail. * Note, with MSG_MORE we overallocate on fragments, * because we have no idea what fragment will be * the last. */ - if (datalen == length + fraggap) + if (datalen == length + fraggap) { alloclen += rt->dst.trailer_len; - + /* make sure mtu is not reached */ + if (datalen > mtu - fragheaderlen - rt->dst.trailer_len) + datalen -= ALIGN(rt->dst.trailer_len, 8); + } if (transhdrlen) { skb = sock_alloc_send_skb(sk, alloclen + hh_len + 15, @@ -960,7 +962,7 @@ int ip_append_data(struct sock *sk, else /* only the initial fragment is time stamped */ - ipc->shtx.flags = 0; + ipc->tx_flags = 0; } if (skb == NULL) goto error; @@ -971,7 +973,7 @@ int ip_append_data(struct sock *sk, skb->ip_summed = csummode; skb->csum = 0; skb_reserve(skb, hh_len); - *skb_tx(skb) = ipc->shtx; + skb_shinfo(skb)->tx_flags = ipc->tx_flags; /* * Find where to start putting bytes. @@ -1391,7 +1393,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar daddr = ipc.addr = rt->rt_src; ipc.opt = NULL; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; if (replyopts.opt.optlen) { ipc.opt = &replyopts.opt; diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c index ec036731a70ba0774164de8574c30d0f0e1baa64..e9b816e6cd73a681ea02e9540d6849eb924f4a8a 100644 --- a/net/ipv4/ipip.c +++ b/net/ipv4/ipip.c @@ -122,31 +122,59 @@ static int ipip_net_id __read_mostly; struct ipip_net { - struct ip_tunnel *tunnels_r_l[HASH_SIZE]; - struct ip_tunnel *tunnels_r[HASH_SIZE]; - struct ip_tunnel *tunnels_l[HASH_SIZE]; - struct ip_tunnel *tunnels_wc[1]; - struct ip_tunnel **tunnels[4]; + struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_r[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_l[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_wc[1]; + struct ip_tunnel __rcu **tunnels[4]; struct net_device *fb_tunnel_dev; }; -static void ipip_tunnel_init(struct net_device *dev); +static int ipip_tunnel_init(struct net_device *dev); static void ipip_tunnel_setup(struct net_device *dev); +static void ipip_dev_free(struct net_device *dev); /* - * Locking : hash tables are protected by RCU and a spinlock + * Locking : hash tables are protected by RCU and RTNL */ -static DEFINE_SPINLOCK(ipip_lock); #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) +/* often modified stats are per cpu, other are shared (netdev->stats) */ +struct pcpu_tstats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +static struct net_device_stats *ipip_get_stats(struct net_device *dev) +{ + struct pcpu_tstats sum = { 0 }; + int i; + + for_each_possible_cpu(i) { + const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); + + sum.rx_packets += tstats->rx_packets; + sum.rx_bytes += tstats->rx_bytes; + sum.tx_packets += tstats->tx_packets; + sum.tx_bytes += tstats->tx_bytes; + } + dev->stats.rx_packets = sum.rx_packets; + dev->stats.rx_bytes = sum.rx_bytes; + dev->stats.tx_packets = sum.tx_packets; + dev->stats.tx_bytes = sum.tx_bytes; + return &dev->stats; +} + static struct ip_tunnel * ipip_tunnel_lookup(struct net *net, __be32 remote, __be32 local) { - unsigned h0 = HASH(remote); - unsigned h1 = HASH(local); + unsigned int h0 = HASH(remote); + unsigned int h1 = HASH(local); struct ip_tunnel *t; struct ipip_net *ipn = net_generic(net, ipip_net_id); @@ -169,12 +197,12 @@ static struct ip_tunnel * ipip_tunnel_lookup(struct net *net, return NULL; } -static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn, +static struct ip_tunnel __rcu **__ipip_bucket(struct ipip_net *ipn, struct ip_tunnel_parm *parms) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; - unsigned h = 0; + unsigned int h = 0; int prio = 0; if (remote) { @@ -188,7 +216,7 @@ static struct ip_tunnel **__ipip_bucket(struct ipip_net *ipn, return &ipn->tunnels[prio][h]; } -static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn, +static inline struct ip_tunnel __rcu **ipip_bucket(struct ipip_net *ipn, struct ip_tunnel *t) { return __ipip_bucket(ipn, &t->parms); @@ -196,13 +224,14 @@ static inline struct ip_tunnel **ipip_bucket(struct ipip_net *ipn, static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t) { - struct ip_tunnel **tp; - - for (tp = ipip_bucket(ipn, t); *tp; tp = &(*tp)->next) { - if (t == *tp) { - spin_lock_bh(&ipip_lock); - *tp = t->next; - spin_unlock_bh(&ipip_lock); + struct ip_tunnel __rcu **tp; + struct ip_tunnel *iter; + + for (tp = ipip_bucket(ipn, t); + (iter = rtnl_dereference(*tp)) != NULL; + tp = &iter->next) { + if (t == iter) { + rcu_assign_pointer(*tp, t->next); break; } } @@ -210,12 +239,10 @@ static void ipip_tunnel_unlink(struct ipip_net *ipn, struct ip_tunnel *t) static void ipip_tunnel_link(struct ipip_net *ipn, struct ip_tunnel *t) { - struct ip_tunnel **tp = ipip_bucket(ipn, t); + struct ip_tunnel __rcu **tp = ipip_bucket(ipn, t); - spin_lock_bh(&ipip_lock); - t->next = *tp; + rcu_assign_pointer(t->next, rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); - spin_unlock_bh(&ipip_lock); } static struct ip_tunnel * ipip_tunnel_locate(struct net *net, @@ -223,12 +250,15 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net, { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; - struct ip_tunnel *t, **tp, *nt; + struct ip_tunnel *t, *nt; + struct ip_tunnel __rcu **tp; struct net_device *dev; char name[IFNAMSIZ]; struct ipip_net *ipn = net_generic(net, ipip_net_id); - for (tp = __ipip_bucket(ipn, parms); (t = *tp) != NULL; tp = &t->next) { + for (tp = __ipip_bucket(ipn, parms); + (t = rtnl_dereference(*tp)) != NULL; + tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) return t; } @@ -238,7 +268,7 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net, if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else - sprintf(name, "tunl%%d"); + strcpy(name, "tunl%d"); dev = alloc_netdev(sizeof(*t), name, ipip_tunnel_setup); if (dev == NULL) @@ -254,7 +284,8 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net, nt = netdev_priv(dev); nt->parms = *parms; - ipip_tunnel_init(dev); + if (ipip_tunnel_init(dev) < 0) + goto failed_free; if (register_netdevice(dev) < 0) goto failed_free; @@ -264,20 +295,19 @@ static struct ip_tunnel * ipip_tunnel_locate(struct net *net, return nt; failed_free: - free_netdev(dev); + ipip_dev_free(dev); return NULL; } +/* called with RTNL */ static void ipip_tunnel_uninit(struct net_device *dev) { struct net *net = dev_net(dev); struct ipip_net *ipn = net_generic(net, ipip_net_id); - if (dev == ipn->fb_tunnel_dev) { - spin_lock_bh(&ipip_lock); - ipn->tunnels_wc[0] = NULL; - spin_unlock_bh(&ipip_lock); - } else + if (dev == ipn->fb_tunnel_dev) + rcu_assign_pointer(ipn->tunnels_wc[0], NULL); + else ipip_tunnel_unlink(ipn, netdev_priv(dev)); dev_put(dev); } @@ -359,8 +389,10 @@ static int ipip_rcv(struct sk_buff *skb) const struct iphdr *iph = ip_hdr(skb); rcu_read_lock(); - if ((tunnel = ipip_tunnel_lookup(dev_net(skb->dev), - iph->saddr, iph->daddr)) != NULL) { + tunnel = ipip_tunnel_lookup(dev_net(skb->dev), iph->saddr, iph->daddr); + if (tunnel != NULL) { + struct pcpu_tstats *tstats; + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { rcu_read_unlock(); kfree_skb(skb); @@ -374,10 +406,16 @@ static int ipip_rcv(struct sk_buff *skb) skb->protocol = htons(ETH_P_IP); skb->pkt_type = PACKET_HOST; - skb_tunnel_rx(skb, tunnel->dev); + tstats = this_cpu_ptr(tunnel->dev->tstats); + tstats->rx_packets++; + tstats->rx_bytes += skb->len; + + __skb_tunnel_rx(skb, tunnel->dev); ipip_ecn_decapsulate(iph, skb); + netif_rx(skb); + rcu_read_unlock(); return 0; } @@ -394,13 +432,12 @@ static int ipip_rcv(struct sk_buff *skb) static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; - struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); + struct pcpu_tstats *tstats; struct iphdr *tiph = &tunnel->parms.iph; u8 tos = tunnel->parms.iph.tos; __be16 df = tiph->frag_off; struct rtable *rt; /* Route to the other host */ - struct net_device *tdev; /* Device to other host */ + struct net_device *tdev; /* Device to other host */ struct iphdr *old_iph = ip_hdr(skb); struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ @@ -410,13 +447,13 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (skb->protocol != htons(ETH_P_IP)) goto tx_error; - if (tos&1) + if (tos & 1) tos = old_iph->tos; if (!dst) { /* NBMA tunnel */ if ((rt = skb_rtable(skb)) == NULL) { - stats->tx_fifo_errors++; + dev->stats.tx_fifo_errors++; goto tx_error; } if ((dst = rt->rt_gateway) == 0) @@ -424,14 +461,20 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) } { - struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { .ip4_u = - { .daddr = dst, - .saddr = tiph->saddr, - .tos = RT_TOS(tos) } }, - .proto = IPPROTO_IPIP }; + struct flowi fl = { + .oif = tunnel->parms.link, + .nl_u = { + .ip4_u = { + .daddr = dst, + .saddr = tiph->saddr, + .tos = RT_TOS(tos) + } + }, + .proto = IPPROTO_IPIP + }; + if (ip_route_output_key(dev_net(dev), &rt, &fl)) { - stats->tx_carrier_errors++; + dev->stats.tx_carrier_errors++; goto tx_error_icmp; } } @@ -439,7 +482,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) if (tdev == dev) { ip_rt_put(rt); - stats->collisions++; + dev->stats.collisions++; goto tx_error; } @@ -449,7 +492,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); if (mtu < 68) { - stats->collisions++; + dev->stats.collisions++; ip_rt_put(rt); goto tx_error; } @@ -485,7 +528,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt); - txq->tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -522,14 +565,14 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) iph->ttl = old_iph->ttl; nf_reset(skb); - - IPTUNNEL_XMIT(); + tstats = this_cpu_ptr(dev->tstats); + __IPTUNNEL_XMIT(tstats, &dev->stats); return NETDEV_TX_OK; tx_error_icmp: dst_link_failure(skb); tx_error: - stats->tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -544,13 +587,19 @@ static void ipip_tunnel_bind_dev(struct net_device *dev) iph = &tunnel->parms.iph; if (iph->daddr) { - struct flowi fl = { .oif = tunnel->parms.link, - .nl_u = { .ip4_u = - { .daddr = iph->daddr, - .saddr = iph->saddr, - .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_IPIP }; + struct flowi fl = { + .oif = tunnel->parms.link, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_IPIP + }; struct rtable *rt; + if (!ip_route_output_key(dev_net(dev), &rt, &fl)) { tdev = rt->dst.dev; ip_rt_put(rt); @@ -696,13 +745,19 @@ static const struct net_device_ops ipip_netdev_ops = { .ndo_start_xmit = ipip_tunnel_xmit, .ndo_do_ioctl = ipip_tunnel_ioctl, .ndo_change_mtu = ipip_tunnel_change_mtu, - + .ndo_get_stats = ipip_get_stats, }; +static void ipip_dev_free(struct net_device *dev) +{ + free_percpu(dev->tstats); + free_netdev(dev); +} + static void ipip_tunnel_setup(struct net_device *dev) { dev->netdev_ops = &ipip_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ipip_dev_free; dev->type = ARPHRD_TUNNEL; dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); @@ -711,10 +766,11 @@ static void ipip_tunnel_setup(struct net_device *dev) dev->iflink = 0; dev->addr_len = 4; dev->features |= NETIF_F_NETNS_LOCAL; + dev->features |= NETIF_F_LLTX; dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; } -static void ipip_tunnel_init(struct net_device *dev) +static int ipip_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); @@ -725,9 +781,15 @@ static void ipip_tunnel_init(struct net_device *dev) memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); ipip_tunnel_bind_dev(dev); + + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + + return 0; } -static void __net_init ipip_fb_tunnel_init(struct net_device *dev) +static int __net_init ipip_fb_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); struct iphdr *iph = &tunnel->parms.iph; @@ -740,11 +802,16 @@ static void __net_init ipip_fb_tunnel_init(struct net_device *dev) iph->protocol = IPPROTO_IPIP; iph->ihl = 5; + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + dev_hold(dev); - ipn->tunnels_wc[0] = tunnel; + rcu_assign_pointer(ipn->tunnels_wc[0], tunnel); + return 0; } -static struct xfrm_tunnel ipip_handler = { +static struct xfrm_tunnel ipip_handler __read_mostly = { .handler = ipip_rcv, .err_handler = ipip_err, .priority = 1, @@ -760,11 +827,12 @@ static void ipip_destroy_tunnels(struct ipip_net *ipn, struct list_head *head) for (prio = 1; prio < 4; prio++) { int h; for (h = 0; h < HASH_SIZE; h++) { - struct ip_tunnel *t = ipn->tunnels[prio][h]; + struct ip_tunnel *t; + t = rtnl_dereference(ipn->tunnels[prio][h]); while (t != NULL) { unregister_netdevice_queue(t->dev, head); - t = t->next; + t = rtnl_dereference(t->next); } } } @@ -789,7 +857,9 @@ static int __net_init ipip_init_net(struct net *net) } dev_net_set(ipn->fb_tunnel_dev, net); - ipip_fb_tunnel_init(ipn->fb_tunnel_dev); + err = ipip_fb_tunnel_init(ipn->fb_tunnel_dev); + if (err) + goto err_reg_dev; if ((err = register_netdev(ipn->fb_tunnel_dev))) goto err_reg_dev; @@ -797,7 +867,7 @@ static int __net_init ipip_init_net(struct net *net) return 0; err_reg_dev: - free_netdev(ipn->fb_tunnel_dev); + ipip_dev_free(ipn->fb_tunnel_dev); err_alloc_dev: /* nothing */ return err; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 179fcab866fc5f550d580f3ca06b5abd24f0f58a..86dd5691af46dfc4d87631127e9fa06b7329dc3c 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -75,7 +75,7 @@ struct mr_table { struct net *net; #endif u32 id; - struct sock *mroute_sk; + struct sock __rcu *mroute_sk; struct timer_list ipmr_expire_timer; struct list_head mfc_unres_queue; struct list_head mfc_cache_array[MFC_LINES]; @@ -98,7 +98,7 @@ struct ipmr_result { }; /* Big lock, protecting vif table, mrt cache and mroute socket state. - Note that the changes are semaphored via rtnl_lock. + * Note that the changes are semaphored via rtnl_lock. */ static DEFINE_RWLOCK(mrt_lock); @@ -113,11 +113,11 @@ static DEFINE_RWLOCK(mrt_lock); static DEFINE_SPINLOCK(mfc_unres_lock); /* We return to original Alan's scheme. Hash table of resolved - entries is changed only in process context and protected - with weak lock mrt_lock. Queue of unresolved entries is protected - with strong spinlock mfc_unres_lock. - - In this case data path is free of exclusive locks at all. + * entries is changed only in process context and protected + * with weak lock mrt_lock. Queue of unresolved entries is protected + * with strong spinlock mfc_unres_lock. + * + * In this case data path is free of exclusive locks at all. */ static struct kmem_cache *mrt_cachep __read_mostly; @@ -396,9 +396,9 @@ struct net_device *ipmr_new_tunnel(struct net *net, struct vifctl *v) set_fs(KERNEL_DS); err = ops->ndo_do_ioctl(dev, &ifr, SIOCADDTUNNEL); set_fs(oldfs); - } else + } else { err = -EOPNOTSUPP; - + } dev = NULL; if (err == 0 && @@ -495,7 +495,8 @@ static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt) dev->iflink = 0; rcu_read_lock(); - if ((in_dev = __in_dev_get_rcu(dev)) == NULL) { + in_dev = __in_dev_get_rcu(dev); + if (!in_dev) { rcu_read_unlock(); goto failure; } @@ -552,9 +553,10 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify, mrt->mroute_reg_vif_num = -1; #endif - if (vifi+1 == mrt->maxvif) { + if (vifi + 1 == mrt->maxvif) { int tmp; - for (tmp=vifi-1; tmp>=0; tmp--) { + + for (tmp = vifi - 1; tmp >= 0; tmp--) { if (VIF_EXISTS(mrt, tmp)) break; } @@ -565,25 +567,33 @@ static int vif_delete(struct mr_table *mrt, int vifi, int notify, dev_set_allmulti(dev, -1); - if ((in_dev = __in_dev_get_rtnl(dev)) != NULL) { + in_dev = __in_dev_get_rtnl(dev); + if (in_dev) { IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)--; ip_rt_multicast_event(in_dev); } - if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER) && !notify) + if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER) && !notify) unregister_netdevice_queue(dev, head); dev_put(dev); return 0; } -static inline void ipmr_cache_free(struct mfc_cache *c) +static void ipmr_cache_free_rcu(struct rcu_head *head) { + struct mfc_cache *c = container_of(head, struct mfc_cache, rcu); + kmem_cache_free(mrt_cachep, c); } +static inline void ipmr_cache_free(struct mfc_cache *c) +{ + call_rcu(&c->rcu, ipmr_cache_free_rcu); +} + /* Destroy an unresolved cache entry, killing queued skbs - and reporting error to netlink readers. + * and reporting error to netlink readers. */ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c) @@ -605,8 +615,9 @@ static void ipmr_destroy_unres(struct mr_table *mrt, struct mfc_cache *c) memset(&e->msg, 0, sizeof(e->msg)); rtnl_unicast(skb, net, NETLINK_CB(skb).pid); - } else + } else { kfree_skb(skb); + } } ipmr_cache_free(c); @@ -724,13 +735,13 @@ static int vif_add(struct net *net, struct mr_table *mrt, case 0: if (vifc->vifc_flags == VIFF_USE_IFINDEX) { dev = dev_get_by_index(net, vifc->vifc_lcl_ifindex); - if (dev && dev->ip_ptr == NULL) { + if (dev && __in_dev_get_rtnl(dev) == NULL) { dev_put(dev); return -EADDRNOTAVAIL; } - } else + } else { dev = ip_dev_find(net, vifc->vifc_lcl_addr.s_addr); - + } if (!dev) return -EADDRNOTAVAIL; err = dev_set_allmulti(dev, 1); @@ -743,16 +754,16 @@ static int vif_add(struct net *net, struct mr_table *mrt, return -EINVAL; } - if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) { + in_dev = __in_dev_get_rtnl(dev); + if (!in_dev) { dev_put(dev); return -EADDRNOTAVAIL; } IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++; ip_rt_multicast_event(in_dev); - /* - * Fill in the VIF structures - */ + /* Fill in the VIF structures */ + v->rate_limit = vifc->vifc_rate_limit; v->local = vifc->vifc_lcl_addr.s_addr; v->remote = vifc->vifc_rmt_addr.s_addr; @@ -765,14 +776,14 @@ static int vif_add(struct net *net, struct mr_table *mrt, v->pkt_in = 0; v->pkt_out = 0; v->link = dev->ifindex; - if (v->flags&(VIFF_TUNNEL|VIFF_REGISTER)) + if (v->flags & (VIFF_TUNNEL | VIFF_REGISTER)) v->link = dev->iflink; /* And finish update writing critical data */ write_lock_bh(&mrt_lock); v->dev = dev; #ifdef CONFIG_IP_PIMSM - if (v->flags&VIFF_REGISTER) + if (v->flags & VIFF_REGISTER) mrt->mroute_reg_vif_num = vifi; #endif if (vifi+1 > mrt->maxvif) @@ -781,6 +792,7 @@ static int vif_add(struct net *net, struct mr_table *mrt, return 0; } +/* called with rcu_read_lock() */ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, __be32 origin, __be32 mcastgrp) @@ -788,7 +800,7 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, int line = MFC_HASH(mcastgrp, origin); struct mfc_cache *c; - list_for_each_entry(c, &mrt->mfc_cache_array[line], list) { + list_for_each_entry_rcu(c, &mrt->mfc_cache_array[line], list) { if (c->mfc_origin == origin && c->mfc_mcastgrp == mcastgrp) return c; } @@ -801,19 +813,20 @@ static struct mfc_cache *ipmr_cache_find(struct mr_table *mrt, static struct mfc_cache *ipmr_cache_alloc(void) { struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL); - if (c == NULL) - return NULL; - c->mfc_un.res.minvif = MAXVIFS; + + if (c) + c->mfc_un.res.minvif = MAXVIFS; return c; } static struct mfc_cache *ipmr_cache_alloc_unres(void) { struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC); - if (c == NULL) - return NULL; - skb_queue_head_init(&c->mfc_un.unres.unresolved); - c->mfc_un.unres.expires = jiffies + 10*HZ; + + if (c) { + skb_queue_head_init(&c->mfc_un.unres.unresolved); + c->mfc_un.unres.expires = jiffies + 10*HZ; + } return c; } @@ -827,17 +840,15 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt, struct sk_buff *skb; struct nlmsgerr *e; - /* - * Play the pending entries through our router - */ + /* Play the pending entries through our router */ while ((skb = __skb_dequeue(&uc->mfc_un.unres.unresolved))) { if (ip_hdr(skb)->version == 0) { struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct iphdr)); if (__ipmr_fill_mroute(mrt, skb, c, NLMSG_DATA(nlh)) > 0) { - nlh->nlmsg_len = (skb_tail_pointer(skb) - - (u8 *)nlh); + nlh->nlmsg_len = skb_tail_pointer(skb) - + (u8 *)nlh; } else { nlh->nlmsg_type = NLMSG_ERROR; nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); @@ -848,8 +859,9 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt, } rtnl_unicast(skb, net, NETLINK_CB(skb).pid); - } else + } else { ip_mr_forward(net, mrt, skb, c, 0); + } } } @@ -867,6 +879,7 @@ static int ipmr_cache_report(struct mr_table *mrt, const int ihl = ip_hdrlen(pkt); struct igmphdr *igmp; struct igmpmsg *msg; + struct sock *mroute_sk; int ret; #ifdef CONFIG_IP_PIMSM @@ -882,9 +895,9 @@ static int ipmr_cache_report(struct mr_table *mrt, #ifdef CONFIG_IP_PIMSM if (assert == IGMPMSG_WHOLEPKT) { /* Ugly, but we have no choice with this interface. - Duplicate old header, fix ihl, length etc. - And all this only to mangle msg->im_msgtype and - to set msg->im_mbz to "mbz" :-) + * Duplicate old header, fix ihl, length etc. + * And all this only to mangle msg->im_msgtype and + * to set msg->im_mbz to "mbz" :-) */ skb_push(skb, sizeof(struct iphdr)); skb_reset_network_header(skb); @@ -901,39 +914,38 @@ static int ipmr_cache_report(struct mr_table *mrt, #endif { - /* - * Copy the IP header - */ + /* Copy the IP header */ skb->network_header = skb->tail; skb_put(skb, ihl); skb_copy_to_linear_data(skb, pkt->data, ihl); - ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ + ip_hdr(skb)->protocol = 0; /* Flag to the kernel this is a route add */ msg = (struct igmpmsg *)skb_network_header(skb); msg->im_vif = vifi; skb_dst_set(skb, dst_clone(skb_dst(pkt))); - /* - * Add our header - */ + /* Add our header */ - igmp=(struct igmphdr *)skb_put(skb, sizeof(struct igmphdr)); + igmp = (struct igmphdr *)skb_put(skb, sizeof(struct igmphdr)); igmp->type = msg->im_msgtype = assert; - igmp->code = 0; - ip_hdr(skb)->tot_len = htons(skb->len); /* Fix the length */ + igmp->code = 0; + ip_hdr(skb)->tot_len = htons(skb->len); /* Fix the length */ skb->transport_header = skb->network_header; } - if (mrt->mroute_sk == NULL) { + rcu_read_lock(); + mroute_sk = rcu_dereference(mrt->mroute_sk); + if (mroute_sk == NULL) { + rcu_read_unlock(); kfree_skb(skb); return -EINVAL; } - /* - * Deliver to mrouted - */ - ret = sock_queue_rcv_skb(mrt->mroute_sk, skb); + /* Deliver to mrouted */ + + ret = sock_queue_rcv_skb(mroute_sk, skb); + rcu_read_unlock(); if (ret < 0) { if (net_ratelimit()) printk(KERN_WARNING "mroute: pending queue full, dropping entries.\n"); @@ -965,9 +977,7 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb) } if (!found) { - /* - * Create a new entry if allowable - */ + /* Create a new entry if allowable */ if (atomic_read(&mrt->cache_resolve_queue_len) >= 10 || (c = ipmr_cache_alloc_unres()) == NULL) { @@ -977,16 +987,14 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb) return -ENOBUFS; } - /* - * Fill in the new cache entry - */ + /* Fill in the new cache entry */ + c->mfc_parent = -1; c->mfc_origin = iph->saddr; c->mfc_mcastgrp = iph->daddr; - /* - * Reflect first query at mrouted. - */ + /* Reflect first query at mrouted. */ + err = ipmr_cache_report(mrt, skb, vifi, IGMPMSG_NOCACHE); if (err < 0) { /* If the report failed throw the cache entry @@ -1006,10 +1014,9 @@ ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi, struct sk_buff *skb) mod_timer(&mrt->ipmr_expire_timer, c->mfc_un.unres.expires); } - /* - * See if we can append the packet - */ - if (c->mfc_un.unres.unresolved.qlen>3) { + /* See if we can append the packet */ + + if (c->mfc_un.unres.unresolved.qlen > 3) { kfree_skb(skb); err = -ENOBUFS; } else { @@ -1035,9 +1042,7 @@ static int ipmr_mfc_delete(struct mr_table *mrt, struct mfcctl *mfc) list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[line], list) { if (c->mfc_origin == mfc->mfcc_origin.s_addr && c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { - write_lock_bh(&mrt_lock); - list_del(&c->list); - write_unlock_bh(&mrt_lock); + list_del_rcu(&c->list); ipmr_cache_free(c); return 0; @@ -1090,9 +1095,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt, if (!mrtsock) c->mfc_flags |= MFC_STATIC; - write_lock_bh(&mrt_lock); - list_add(&c->list, &mrt->mfc_cache_array[line]); - write_unlock_bh(&mrt_lock); + list_add_rcu(&c->list, &mrt->mfc_cache_array[line]); /* * Check to see if we resolved a queued list. If so we @@ -1130,26 +1133,21 @@ static void mroute_clean_tables(struct mr_table *mrt) LIST_HEAD(list); struct mfc_cache *c, *next; - /* - * Shut down all active vif entries - */ + /* Shut down all active vif entries */ + for (i = 0; i < mrt->maxvif; i++) { - if (!(mrt->vif_table[i].flags&VIFF_STATIC)) + if (!(mrt->vif_table[i].flags & VIFF_STATIC)) vif_delete(mrt, i, 0, &list); } unregister_netdevice_many(&list); - /* - * Wipe the cache - */ + /* Wipe the cache */ + for (i = 0; i < MFC_LINES; i++) { list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) { - if (c->mfc_flags&MFC_STATIC) + if (c->mfc_flags & MFC_STATIC) continue; - write_lock_bh(&mrt_lock); - list_del(&c->list); - write_unlock_bh(&mrt_lock); - + list_del_rcu(&c->list); ipmr_cache_free(c); } } @@ -1164,6 +1162,9 @@ static void mroute_clean_tables(struct mr_table *mrt) } } +/* called from ip_ra_control(), before an RCU grace period, + * we dont need to call synchronize_rcu() here + */ static void mrtsock_destruct(struct sock *sk) { struct net *net = sock_net(sk); @@ -1171,13 +1172,9 @@ static void mrtsock_destruct(struct sock *sk) rtnl_lock(); ipmr_for_each_table(mrt, net) { - if (sk == mrt->mroute_sk) { + if (sk == rtnl_dereference(mrt->mroute_sk)) { IPV4_DEVCONF_ALL(net, MC_FORWARDING)--; - - write_lock_bh(&mrt_lock); - mrt->mroute_sk = NULL; - write_unlock_bh(&mrt_lock); - + rcu_assign_pointer(mrt->mroute_sk, NULL); mroute_clean_tables(mrt); } } @@ -1204,7 +1201,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi return -ENOENT; if (optname != MRT_INIT) { - if (sk != mrt->mroute_sk && !capable(CAP_NET_ADMIN)) + if (sk != rcu_dereference_raw(mrt->mroute_sk) && + !capable(CAP_NET_ADMIN)) return -EACCES; } @@ -1217,23 +1215,20 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi return -ENOPROTOOPT; rtnl_lock(); - if (mrt->mroute_sk) { + if (rtnl_dereference(mrt->mroute_sk)) { rtnl_unlock(); return -EADDRINUSE; } ret = ip_ra_control(sk, 1, mrtsock_destruct); if (ret == 0) { - write_lock_bh(&mrt_lock); - mrt->mroute_sk = sk; - write_unlock_bh(&mrt_lock); - + rcu_assign_pointer(mrt->mroute_sk, sk); IPV4_DEVCONF_ALL(net, MC_FORWARDING)++; } rtnl_unlock(); return ret; case MRT_DONE: - if (sk != mrt->mroute_sk) + if (sk != rcu_dereference_raw(mrt->mroute_sk)) return -EACCES; return ip_ra_control(sk, 0, NULL); case MRT_ADD_VIF: @@ -1246,7 +1241,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi return -ENFILE; rtnl_lock(); if (optname == MRT_ADD_VIF) { - ret = vif_add(net, mrt, &vif, sk == mrt->mroute_sk); + ret = vif_add(net, mrt, &vif, + sk == rtnl_dereference(mrt->mroute_sk)); } else { ret = vif_delete(mrt, vif.vifc_vifi, 0, NULL); } @@ -1267,7 +1263,8 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi if (optname == MRT_DEL_MFC) ret = ipmr_mfc_delete(mrt, &mfc); else - ret = ipmr_mfc_add(net, mrt, &mfc, sk == mrt->mroute_sk); + ret = ipmr_mfc_add(net, mrt, &mfc, + sk == rtnl_dereference(mrt->mroute_sk)); rtnl_unlock(); return ret; /* @@ -1276,7 +1273,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi case MRT_ASSERT: { int v; - if (get_user(v,(int __user *)optval)) + if (get_user(v, (int __user *)optval)) return -EFAULT; mrt->mroute_do_assert = (v) ? 1 : 0; return 0; @@ -1286,7 +1283,7 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi { int v; - if (get_user(v,(int __user *)optval)) + if (get_user(v, (int __user *)optval)) return -EFAULT; v = (v) ? 1 : 0; @@ -1309,14 +1306,16 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, unsi return -EINVAL; if (get_user(v, (u32 __user *)optval)) return -EFAULT; - if (sk == mrt->mroute_sk) - return -EBUSY; rtnl_lock(); ret = 0; - if (!ipmr_new_table(net, v)) - ret = -ENOMEM; - raw_sk(sk)->ipmr_table = v; + if (sk == rtnl_dereference(mrt->mroute_sk)) { + ret = -EBUSY; + } else { + if (!ipmr_new_table(net, v)) + ret = -ENOMEM; + raw_sk(sk)->ipmr_table = v; + } rtnl_unlock(); return ret; } @@ -1347,9 +1346,9 @@ int ip_mroute_getsockopt(struct sock *sk, int optname, char __user *optval, int if (optname != MRT_VERSION && #ifdef CONFIG_IP_PIMSM - optname!=MRT_PIM && + optname != MRT_PIM && #endif - optname!=MRT_ASSERT) + optname != MRT_ASSERT) return -ENOPROTOOPT; if (get_user(olr, optlen)) @@ -1416,19 +1415,19 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) if (copy_from_user(&sr, arg, sizeof(sr))) return -EFAULT; - read_lock(&mrt_lock); + rcu_read_lock(); c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); if (c) { sr.pktcnt = c->mfc_un.res.pkt; sr.bytecnt = c->mfc_un.res.bytes; sr.wrong_if = c->mfc_un.res.wrong_if; - read_unlock(&mrt_lock); + rcu_read_unlock(); if (copy_to_user(arg, &sr, sizeof(sr))) return -EFAULT; return 0; } - read_unlock(&mrt_lock); + rcu_read_unlock(); return -EADDRNOTAVAIL; default: return -ENOIOCTLCMD; @@ -1465,7 +1464,7 @@ static struct notifier_block ip_mr_notifier = { }; /* - * Encapsulate a packet by attaching a valid IPIP header to it. + * Encapsulate a packet by attaching a valid IPIP header to it. * This avoids tunnel drivers and other mess and gives us the speed so * important for multicast video. */ @@ -1480,7 +1479,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) skb_reset_network_header(skb); iph = ip_hdr(skb); - iph->version = 4; + iph->version = 4; iph->tos = old_iph->tos; iph->ttl = old_iph->ttl; iph->frag_off = 0; @@ -1498,7 +1497,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr) static inline int ipmr_forward_finish(struct sk_buff *skb) { - struct ip_options * opt = &(IPCB(skb)->opt); + struct ip_options *opt = &(IPCB(skb)->opt); IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS); @@ -1535,22 +1534,34 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, } #endif - if (vif->flags&VIFF_TUNNEL) { - struct flowi fl = { .oif = vif->link, - .nl_u = { .ip4_u = - { .daddr = vif->remote, - .saddr = vif->local, - .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_IPIP }; + if (vif->flags & VIFF_TUNNEL) { + struct flowi fl = { + .oif = vif->link, + .nl_u = { + .ip4_u = { + .daddr = vif->remote, + .saddr = vif->local, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_IPIP + }; + if (ip_route_output_key(net, &rt, &fl)) goto out_free; encap = sizeof(struct iphdr); } else { - struct flowi fl = { .oif = vif->link, - .nl_u = { .ip4_u = - { .daddr = iph->daddr, - .tos = RT_TOS(iph->tos) } }, - .proto = IPPROTO_IPIP }; + struct flowi fl = { + .oif = vif->link, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .tos = RT_TOS(iph->tos) + } + }, + .proto = IPPROTO_IPIP + }; + if (ip_route_output_key(net, &rt, &fl)) goto out_free; } @@ -1559,8 +1570,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, if (skb->len+encap > dst_mtu(&rt->dst) && (ntohs(iph->frag_off) & IP_DF)) { /* Do not fragment multicasts. Alas, IPv4 does not - allow to send ICMP, so that packets will disappear - to blackhole. + * allow to send ICMP, so that packets will disappear + * to blackhole. */ IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_FRAGFAILS); @@ -1583,7 +1594,8 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, ip_decrease_ttl(ip_hdr(skb)); /* FIXME: forward and output firewalls used to be called here. - * What do we do with netfilter? -- RR */ + * What do we do with netfilter? -- RR + */ if (vif->flags & VIFF_TUNNEL) { ip_encap(skb, vif->local, vif->remote); /* FIXME: extra output firewall step used to be here. --RR */ @@ -1644,15 +1656,15 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, if (skb_rtable(skb)->fl.iif == 0) { /* It is our own packet, looped back. - Very complicated situation... - - The best workaround until routing daemons will be - fixed is not to redistribute packet, if it was - send through wrong interface. It means, that - multicast applications WILL NOT work for - (S,G), which have default multicast route pointing - to wrong oif. In any case, it is not a good - idea to use multicasting applications on router. + * Very complicated situation... + * + * The best workaround until routing daemons will be + * fixed is not to redistribute packet, if it was + * send through wrong interface. It means, that + * multicast applications WILL NOT work for + * (S,G), which have default multicast route pointing + * to wrong oif. In any case, it is not a good + * idea to use multicasting applications on router. */ goto dont_forward; } @@ -1662,9 +1674,9 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, if (true_vifi >= 0 && mrt->mroute_do_assert && /* pimsm uses asserts, when switching from RPT to SPT, - so that we cannot check that packet arrived on an oif. - It is bad, but otherwise we would need to move pretty - large chunk of pimd to kernel. Ough... --ANK + * so that we cannot check that packet arrived on an oif. + * It is bad, but otherwise we would need to move pretty + * large chunk of pimd to kernel. Ough... --ANK */ (mrt->mroute_do_pim || cache->mfc_un.res.ttls[true_vifi] < 255) && @@ -1682,10 +1694,12 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, /* * Forward the frame */ - for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) { + for (ct = cache->mfc_un.res.maxvif - 1; + ct >= cache->mfc_un.res.minvif; ct--) { if (ip_hdr(skb)->ttl > cache->mfc_un.res.ttls[ct]) { if (psend != -1) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2) ipmr_queue_xmit(net, mrt, skb2, cache, psend); @@ -1696,6 +1710,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, if (psend != -1) { if (local) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); + if (skb2) ipmr_queue_xmit(net, mrt, skb2, cache, psend); } else { @@ -1713,6 +1728,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt, /* * Multicast packets for forwarding arrive here + * Called with rcu_read_lock(); */ int ip_mr_input(struct sk_buff *skb) @@ -1724,9 +1740,9 @@ int ip_mr_input(struct sk_buff *skb) int err; /* Packet is looped back after forward, it should not be - forwarded second time, but still can be delivered locally. + * forwarded second time, but still can be delivered locally. */ - if (IPCB(skb)->flags&IPSKB_FORWARDED) + if (IPCB(skb)->flags & IPSKB_FORWARDED) goto dont_forward; err = ipmr_fib_lookup(net, &skb_rtable(skb)->fl, &mrt); @@ -1736,28 +1752,28 @@ int ip_mr_input(struct sk_buff *skb) } if (!local) { - if (IPCB(skb)->opt.router_alert) { - if (ip_call_ra_chain(skb)) - return 0; - } else if (ip_hdr(skb)->protocol == IPPROTO_IGMP){ - /* IGMPv1 (and broken IGMPv2 implementations sort of - Cisco IOS <= 11.2(8)) do not put router alert - option to IGMP packets destined to routable - groups. It is very bad, because it means - that we can forward NO IGMP messages. - */ - read_lock(&mrt_lock); - if (mrt->mroute_sk) { - nf_reset(skb); - raw_rcv(mrt->mroute_sk, skb); - read_unlock(&mrt_lock); - return 0; - } - read_unlock(&mrt_lock); + if (IPCB(skb)->opt.router_alert) { + if (ip_call_ra_chain(skb)) + return 0; + } else if (ip_hdr(skb)->protocol == IPPROTO_IGMP) { + /* IGMPv1 (and broken IGMPv2 implementations sort of + * Cisco IOS <= 11.2(8)) do not put router alert + * option to IGMP packets destined to routable + * groups. It is very bad, because it means + * that we can forward NO IGMP messages. + */ + struct sock *mroute_sk; + + mroute_sk = rcu_dereference(mrt->mroute_sk); + if (mroute_sk) { + nf_reset(skb); + raw_rcv(mroute_sk, skb); + return 0; + } } } - read_lock(&mrt_lock); + /* already under rcu_read_lock() */ cache = ipmr_cache_find(mrt, ip_hdr(skb)->saddr, ip_hdr(skb)->daddr); /* @@ -1769,13 +1785,12 @@ int ip_mr_input(struct sk_buff *skb) if (local) { struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); ip_local_deliver(skb); - if (skb2 == NULL) { - read_unlock(&mrt_lock); + if (skb2 == NULL) return -ENOBUFS; - } skb = skb2; } + read_lock(&mrt_lock); vif = ipmr_find_vif(mrt, skb->dev); if (vif >= 0) { int err2 = ipmr_cache_unresolved(mrt, vif, skb); @@ -1788,8 +1803,8 @@ int ip_mr_input(struct sk_buff *skb) return -ENODEV; } + read_lock(&mrt_lock); ip_mr_forward(net, mrt, skb, cache, local); - read_unlock(&mrt_lock); if (local) @@ -1805,6 +1820,7 @@ int ip_mr_input(struct sk_buff *skb) } #ifdef CONFIG_IP_PIMSM +/* called with rcu_read_lock() */ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, unsigned int pimlen) { @@ -1813,10 +1829,10 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, encap = (struct iphdr *)(skb_transport_header(skb) + pimlen); /* - Check that: - a. packet is really destinted to a multicast group - b. packet is not a NULL-REGISTER - c. packet is not truncated + * Check that: + * a. packet is really sent to a multicast group + * b. packet is not a NULL-REGISTER + * c. packet is not truncated */ if (!ipv4_is_multicast(encap->daddr) || encap->tot_len == 0 || @@ -1826,26 +1842,23 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, read_lock(&mrt_lock); if (mrt->mroute_reg_vif_num >= 0) reg_dev = mrt->vif_table[mrt->mroute_reg_vif_num].dev; - if (reg_dev) - dev_hold(reg_dev); read_unlock(&mrt_lock); if (reg_dev == NULL) return 1; skb->mac_header = skb->network_header; - skb_pull(skb, (u8*)encap - skb->data); + skb_pull(skb, (u8 *)encap - skb->data); skb_reset_network_header(skb); skb->protocol = htons(ETH_P_IP); - skb->ip_summed = 0; + skb->ip_summed = CHECKSUM_NONE; skb->pkt_type = PACKET_HOST; skb_tunnel_rx(skb, reg_dev); netif_rx(skb); - dev_put(reg_dev); - return 0; + return NET_RX_SUCCESS; } #endif @@ -1854,7 +1867,7 @@ static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb, * Handle IGMP messages of PIMv1 */ -int pim_rcv_v1(struct sk_buff * skb) +int pim_rcv_v1(struct sk_buff *skb) { struct igmphdr *pim; struct net *net = dev_net(skb->dev); @@ -1881,7 +1894,7 @@ int pim_rcv_v1(struct sk_buff * skb) #endif #ifdef CONFIG_IP_PIMSM_V2 -static int pim_rcv(struct sk_buff * skb) +static int pim_rcv(struct sk_buff *skb) { struct pimreghdr *pim; struct net *net = dev_net(skb->dev); @@ -1891,8 +1904,8 @@ static int pim_rcv(struct sk_buff * skb) goto drop; pim = (struct pimreghdr *)skb_transport_header(skb); - if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) || - (pim->flags&PIM_NULL_REGISTER) || + if (pim->type != ((PIM_VERSION << 4) | (PIM_REGISTER)) || + (pim->flags & PIM_NULL_REGISTER) || (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && csum_fold(skb_checksum(skb, 0, skb->len, 0)))) goto drop; @@ -1958,28 +1971,33 @@ int ipmr_get_route(struct net *net, if (mrt == NULL) return -ENOENT; - read_lock(&mrt_lock); + rcu_read_lock(); cache = ipmr_cache_find(mrt, rt->rt_src, rt->rt_dst); if (cache == NULL) { struct sk_buff *skb2; struct iphdr *iph; struct net_device *dev; - int vif; + int vif = -1; if (nowait) { - read_unlock(&mrt_lock); + rcu_read_unlock(); return -EAGAIN; } dev = skb->dev; - if (dev == NULL || (vif = ipmr_find_vif(mrt, dev)) < 0) { + read_lock(&mrt_lock); + if (dev) + vif = ipmr_find_vif(mrt, dev); + if (vif < 0) { read_unlock(&mrt_lock); + rcu_read_unlock(); return -ENODEV; } skb2 = skb_clone(skb, GFP_ATOMIC); if (!skb2) { read_unlock(&mrt_lock); + rcu_read_unlock(); return -ENOMEM; } @@ -1992,13 +2010,16 @@ int ipmr_get_route(struct net *net, iph->version = 0; err = ipmr_cache_unresolved(mrt, vif, skb2); read_unlock(&mrt_lock); + rcu_read_unlock(); return err; } - if (!nowait && (rtm->rtm_flags&RTM_F_NOTIFY)) + read_lock(&mrt_lock); + if (!nowait && (rtm->rtm_flags & RTM_F_NOTIFY)) cache->mfc_flags |= MFC_NOTIFY; err = __ipmr_fill_mroute(mrt, skb, cache, rtm); read_unlock(&mrt_lock); + rcu_read_unlock(); return err; } @@ -2050,14 +2071,14 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) s_h = cb->args[1]; s_e = cb->args[2]; - read_lock(&mrt_lock); + rcu_read_lock(); ipmr_for_each_table(mrt, net) { if (t < s_t) goto next_table; if (t > s_t) s_h = 0; for (h = s_h; h < MFC_LINES; h++) { - list_for_each_entry(mfc, &mrt->mfc_cache_array[h], list) { + list_for_each_entry_rcu(mfc, &mrt->mfc_cache_array[h], list) { if (e < s_e) goto next_entry; if (ipmr_fill_mroute(mrt, skb, @@ -2075,7 +2096,7 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) t++; } done: - read_unlock(&mrt_lock); + rcu_read_unlock(); cb->args[2] = e; cb->args[1] = h; @@ -2086,7 +2107,8 @@ static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb) #ifdef CONFIG_PROC_FS /* - * The /proc interfaces to multicast routing /proc/ip_mr_cache /proc/ip_mr_vif + * The /proc interfaces to multicast routing : + * /proc/net/ip_mr_cache & /proc/net/ip_mr_vif */ struct ipmr_vif_iter { struct seq_net_private p; @@ -2208,14 +2230,14 @@ static struct mfc_cache *ipmr_mfc_seq_idx(struct net *net, struct mr_table *mrt = it->mrt; struct mfc_cache *mfc; - read_lock(&mrt_lock); + rcu_read_lock(); for (it->ct = 0; it->ct < MFC_LINES; it->ct++) { it->cache = &mrt->mfc_cache_array[it->ct]; - list_for_each_entry(mfc, it->cache, list) + list_for_each_entry_rcu(mfc, it->cache, list) if (pos-- == 0) return mfc; } - read_unlock(&mrt_lock); + rcu_read_unlock(); spin_lock_bh(&mfc_unres_lock); it->cache = &mrt->mfc_unres_queue; @@ -2274,7 +2296,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) } /* exhausted cache_array, show unresolved */ - read_unlock(&mrt_lock); + rcu_read_unlock(); it->cache = &mrt->mfc_unres_queue; it->ct = 0; @@ -2282,7 +2304,7 @@ static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) if (!list_empty(it->cache)) return list_first_entry(it->cache, struct mfc_cache, list); - end_of_list: +end_of_list: spin_unlock_bh(&mfc_unres_lock); it->cache = NULL; @@ -2297,7 +2319,7 @@ static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) if (it->cache == &mrt->mfc_unres_queue) spin_unlock_bh(&mfc_unres_lock); else if (it->cache == &mrt->mfc_cache_array[it->ct]) - read_unlock(&mrt_lock); + rcu_read_unlock(); } static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) @@ -2323,7 +2345,7 @@ static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) mfc->mfc_un.res.bytes, mfc->mfc_un.res.wrong_if); for (n = mfc->mfc_un.res.minvif; - n < mfc->mfc_un.res.maxvif; n++ ) { + n < mfc->mfc_un.res.maxvif; n++) { if (VIF_EXISTS(mrt, n) && mfc->mfc_un.res.ttls[n] < 255) seq_printf(seq, @@ -2421,7 +2443,7 @@ int __init ip_mr_init(void) mrt_cachep = kmem_cache_create("ip_mrt_cache", sizeof(struct mfc_cache), - 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, + 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); if (!mrt_cachep) return -ENOMEM; diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 1833bdbf9805474c729483e5abef53ffe99e120d..8e3350643b63e003747661aa46470670773a4b34 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -324,10 +324,10 @@ config IP_NF_TARGET_ECN config IP_NF_TARGET_TTL tristate '"TTL" target support' - depends on NETFILTER_ADVANCED + depends on NETFILTER_ADVANCED && IP_NF_MANGLE select NETFILTER_XT_TARGET_HL ---help--- - This is a backwards-compat option for the user's convenience + This is a backwards-compatible option for the user's convenience (e.g. when running oldconfig). It selects CONFIG_NETFILTER_XT_TARGET_HL. diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index e8f4f9a57f1258fb1a589c87a956797019c67504..3cad2591ace0c15fdad446ab528b0f40c2624d09 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -72,7 +72,7 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap, for (i = 0; i < len; i++) ret |= (hdr_addr[i] ^ ap->addr[i]) & ap->mask[i]; - return (ret != 0); + return ret != 0; } /* @@ -228,7 +228,7 @@ arpt_error(struct sk_buff *skb, const struct xt_action_param *par) return NF_DROP; } -static inline const struct arpt_entry_target * +static inline const struct xt_entry_target * arpt_get_target_c(const struct arpt_entry *e) { return arpt_get_target((struct arpt_entry *)e); @@ -282,7 +282,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, arp = arp_hdr(skb); do { - const struct arpt_entry_target *t; + const struct xt_entry_target *t; if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { e = arpt_next_entry(e); @@ -297,10 +297,10 @@ unsigned int arpt_do_table(struct sk_buff *skb, if (!t->u.kernel.target->target) { int v; - v = ((struct arpt_standard_target *)t)->verdict; + v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ - if (v != ARPT_RETURN) { + if (v != XT_RETURN) { verdict = (unsigned)(-v) - 1; break; } @@ -332,7 +332,7 @@ unsigned int arpt_do_table(struct sk_buff *skb, /* Target might have changed stuff. */ arp = arp_hdr(skb); - if (verdict == ARPT_CONTINUE) + if (verdict == XT_CONTINUE) e = arpt_next_entry(e); else /* Verdict */ @@ -377,7 +377,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; for (;;) { - const struct arpt_standard_target *t + const struct xt_standard_target *t = (void *)arpt_get_target_c(e); int visited = e->comefrom & (1 << hook); @@ -392,13 +392,13 @@ static int mark_source_chains(const struct xt_table_info *newinfo, /* Unconditional return/END. */ if ((e->target_offset == sizeof(struct arpt_entry) && (strcmp(t->target.u.user.name, - ARPT_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < 0 && unconditional(&e->arp)) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, - ARPT_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < -NF_MAX_VERDICT - 1) { duprintf("mark_source_chains: bad " "negative verdict (%i)\n", @@ -433,7 +433,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo, int newpos = t->verdict; if (strcmp(t->target.u.user.name, - ARPT_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && newpos >= 0) { if (newpos > newinfo->size - sizeof(struct arpt_entry)) { @@ -464,14 +464,14 @@ static int mark_source_chains(const struct xt_table_info *newinfo, static inline int check_entry(const struct arpt_entry *e, const char *name) { - const struct arpt_entry_target *t; + const struct xt_entry_target *t; if (!arp_checkentry(&e->arp)) { duprintf("arp_tables: arp check failed %p %s.\n", e, name); return -EINVAL; } - if (e->target_offset + sizeof(struct arpt_entry_target) > e->next_offset) + if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; t = arpt_get_target_c(e); @@ -483,7 +483,7 @@ static inline int check_entry(const struct arpt_entry *e, const char *name) static inline int check_target(struct arpt_entry *e, const char *name) { - struct arpt_entry_target *t = arpt_get_target(e); + struct xt_entry_target *t = arpt_get_target(e); int ret; struct xt_tgchk_param par = { .table = name, @@ -506,7 +506,7 @@ static inline int check_target(struct arpt_entry *e, const char *name) static inline int find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) { - struct arpt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; int ret; @@ -536,7 +536,7 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) static bool check_underflow(const struct arpt_entry *e) { - const struct arpt_entry_target *t; + const struct xt_entry_target *t; unsigned int verdict; if (!unconditional(&e->arp)) @@ -544,7 +544,7 @@ static bool check_underflow(const struct arpt_entry *e) t = arpt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) return false; - verdict = ((struct arpt_standard_target *)t)->verdict; + verdict = ((struct xt_standard_target *)t)->verdict; verdict = -verdict - 1; return verdict == NF_DROP || verdict == NF_ACCEPT; } @@ -566,7 +566,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, } if (e->next_offset - < sizeof(struct arpt_entry) + sizeof(struct arpt_entry_target)) { + < sizeof(struct arpt_entry) + sizeof(struct xt_entry_target)) { duprintf("checking: element %p size %u\n", e, e->next_offset); return -EINVAL; @@ -598,7 +598,7 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e, static inline void cleanup_entry(struct arpt_entry *e) { struct xt_tgdtor_param par; - struct arpt_entry_target *t; + struct xt_entry_target *t; t = arpt_get_target(e); par.target = t->u.kernel.target; @@ -794,7 +794,7 @@ static int copy_entries_to_user(unsigned int total_size, /* FIXME: use iterator macros --RR */ /* ... then go back and fix counters and names */ for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ - const struct arpt_entry_target *t; + const struct xt_entry_target *t; e = (struct arpt_entry *)(loc_cpu_entry + off); if (copy_to_user(userptr + off @@ -807,7 +807,7 @@ static int copy_entries_to_user(unsigned int total_size, t = arpt_get_target_c(e); if (copy_to_user(userptr + off + e->target_offset - + offsetof(struct arpt_entry_target, + + offsetof(struct xt_entry_target, u.user.name), t->u.kernel.target->name, strlen(t->u.kernel.target->name)+1) != 0) { @@ -844,7 +844,7 @@ static int compat_calc_entry(const struct arpt_entry *e, const struct xt_table_info *info, const void *base, struct xt_table_info *newinfo) { - const struct arpt_entry_target *t; + const struct xt_entry_target *t; unsigned int entry_offset; int off, i, ret; @@ -895,7 +895,7 @@ static int compat_table_info(const struct xt_table_info *info, static int get_info(struct net *net, void __user *user, const int *len, int compat) { - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; struct xt_table *t; int ret; @@ -908,7 +908,7 @@ static int get_info(struct net *net, void __user *user, if (copy_from_user(name, user, sizeof(name)) != 0) return -EFAULT; - name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; + name[XT_TABLE_MAXNAMELEN-1] = '\0'; #ifdef CONFIG_COMPAT if (compat) xt_compat_lock(NFPROTO_ARP); @@ -1204,7 +1204,7 @@ static int do_add_counters(struct net *net, const void __user *user, #ifdef CONFIG_COMPAT static inline void compat_release_entry(struct compat_arpt_entry *e) { - struct arpt_entry_target *t; + struct xt_entry_target *t; t = compat_arpt_get_target(e); module_put(t->u.kernel.target->me); @@ -1220,7 +1220,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e, const unsigned int *underflows, const char *name) { - struct arpt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; unsigned int entry_offset; int ret, off, h; @@ -1288,7 +1288,7 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr, unsigned int *size, const char *name, struct xt_table_info *newinfo, unsigned char *base) { - struct arpt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; struct arpt_entry *de; unsigned int origsize; @@ -1474,7 +1474,7 @@ static int translate_compat_table(const char *name, } struct compat_arpt_replace { - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; u32 valid_hooks; u32 num_entries; u32 size; @@ -1567,7 +1567,7 @@ static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr, struct xt_counters *counters, unsigned int i) { - struct arpt_entry_target *t; + struct xt_entry_target *t; struct compat_arpt_entry __user *ce; u_int16_t target_offset, next_offset; compat_uint_t origsize; @@ -1628,7 +1628,7 @@ static int compat_copy_entries_to_user(unsigned int total_size, } struct compat_arpt_get_entries { - char name[ARPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; compat_uint_t size; struct compat_arpt_entry entrytable[0]; }; @@ -1828,7 +1828,7 @@ void arpt_unregister_table(struct xt_table *table) /* The built-in targets: standard (NULL) and error. */ static struct xt_target arpt_builtin_tg[] __read_mostly = { { - .name = ARPT_STANDARD_TARGET, + .name = XT_STANDARD_TARGET, .targetsize = sizeof(int), .family = NFPROTO_ARP, #ifdef CONFIG_COMPAT @@ -1838,9 +1838,9 @@ static struct xt_target arpt_builtin_tg[] __read_mostly = { #endif }, { - .name = ARPT_ERROR_TARGET, + .name = XT_ERROR_TARGET, .target = arpt_error, - .targetsize = ARPT_FUNCTION_MAXNAMELEN, + .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_ARP, }, }; diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index e1be7dd1171b368eb4a0e1593abc9b8b2294838a..b8ddcc480ed97157fbda78f741d9091b4e854006 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c @@ -63,7 +63,7 @@ static int checkentry(const struct xt_tgchk_param *par) return false; if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && - mangle->target != ARPT_CONTINUE) + mangle->target != XT_CONTINUE) return false; return true; } diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index d163f2e3b2e99e5f18ae9997d3c74867b3e79354..d31b007a6d80dcda45f7f7913ec72af7556b79bf 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -186,7 +186,7 @@ static inline bool unconditional(const struct ipt_ip *ip) } /* for const-correctness */ -static inline const struct ipt_entry_target * +static inline const struct xt_entry_target * ipt_get_target_c(const struct ipt_entry *e) { return ipt_get_target((struct ipt_entry *)e); @@ -230,9 +230,9 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, const char *hookname, const char **chainname, const char **comment, unsigned int *rulenum) { - const struct ipt_standard_target *t = (void *)ipt_get_target_c(s); + const struct xt_standard_target *t = (void *)ipt_get_target_c(s); - if (strcmp(t->target.u.kernel.target->name, IPT_ERROR_TARGET) == 0) { + if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) { /* Head of user chain: ERROR target with chainname */ *chainname = t->target.data; (*rulenum) = 0; @@ -241,7 +241,7 @@ get_chainname_rulenum(const struct ipt_entry *s, const struct ipt_entry *e, if (s->target_offset == sizeof(struct ipt_entry) && strcmp(t->target.u.kernel.target->name, - IPT_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && t->verdict < 0 && unconditional(&s->ip)) { /* Tail of chains: STANDARD target (return/policy) */ @@ -346,7 +346,7 @@ ipt_do_table(struct sk_buff *skb, get_entry(table_base, private->underflow[hook])); do { - const struct ipt_entry_target *t; + const struct xt_entry_target *t; const struct xt_entry_match *ematch; IP_NF_ASSERT(e); @@ -380,10 +380,10 @@ ipt_do_table(struct sk_buff *skb, if (!t->u.kernel.target->target) { int v; - v = ((struct ipt_standard_target *)t)->verdict; + v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ - if (v != IPT_RETURN) { + if (v != XT_RETURN) { verdict = (unsigned)(-v) - 1; break; } @@ -421,7 +421,7 @@ ipt_do_table(struct sk_buff *skb, verdict = t->u.kernel.target->target(skb, &acpar); /* Target might have changed stuff. */ ip = ip_hdr(skb); - if (verdict == IPT_CONTINUE) + if (verdict == XT_CONTINUE) e = ipt_next_entry(e); else /* Verdict */ @@ -461,7 +461,7 @@ mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; for (;;) { - const struct ipt_standard_target *t + const struct xt_standard_target *t = (void *)ipt_get_target_c(e); int visited = e->comefrom & (1 << hook); @@ -475,13 +475,13 @@ mark_source_chains(const struct xt_table_info *newinfo, /* Unconditional return/END. */ if ((e->target_offset == sizeof(struct ipt_entry) && (strcmp(t->target.u.user.name, - IPT_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < 0 && unconditional(&e->ip)) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, - IPT_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < -NF_MAX_VERDICT - 1) { duprintf("mark_source_chains: bad " "negative verdict (%i)\n", @@ -524,7 +524,7 @@ mark_source_chains(const struct xt_table_info *newinfo, int newpos = t->verdict; if (strcmp(t->target.u.user.name, - IPT_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && newpos >= 0) { if (newpos > newinfo->size - sizeof(struct ipt_entry)) { @@ -552,7 +552,7 @@ mark_source_chains(const struct xt_table_info *newinfo, return 1; } -static void cleanup_match(struct ipt_entry_match *m, struct net *net) +static void cleanup_match(struct xt_entry_match *m, struct net *net) { struct xt_mtdtor_param par; @@ -568,14 +568,14 @@ static void cleanup_match(struct ipt_entry_match *m, struct net *net) static int check_entry(const struct ipt_entry *e, const char *name) { - const struct ipt_entry_target *t; + const struct xt_entry_target *t; if (!ip_checkentry(&e->ip)) { duprintf("ip check failed %p %s.\n", e, par->match->name); return -EINVAL; } - if (e->target_offset + sizeof(struct ipt_entry_target) > + if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; @@ -587,7 +587,7 @@ check_entry(const struct ipt_entry *e, const char *name) } static int -check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) +check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { const struct ipt_ip *ip = par->entryinfo; int ret; @@ -605,7 +605,7 @@ check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) } static int -find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) +find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { struct xt_match *match; int ret; @@ -630,7 +630,7 @@ find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) static int check_target(struct ipt_entry *e, struct net *net, const char *name) { - struct ipt_entry_target *t = ipt_get_target(e); + struct xt_entry_target *t = ipt_get_target(e); struct xt_tgchk_param par = { .net = net, .table = name, @@ -656,7 +656,7 @@ static int find_check_entry(struct ipt_entry *e, struct net *net, const char *name, unsigned int size) { - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; int ret; unsigned int j; @@ -707,7 +707,7 @@ find_check_entry(struct ipt_entry *e, struct net *net, const char *name, static bool check_underflow(const struct ipt_entry *e) { - const struct ipt_entry_target *t; + const struct xt_entry_target *t; unsigned int verdict; if (!unconditional(&e->ip)) @@ -715,7 +715,7 @@ static bool check_underflow(const struct ipt_entry *e) t = ipt_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) return false; - verdict = ((struct ipt_standard_target *)t)->verdict; + verdict = ((struct xt_standard_target *)t)->verdict; verdict = -verdict - 1; return verdict == NF_DROP || verdict == NF_ACCEPT; } @@ -738,7 +738,7 @@ check_entry_size_and_hooks(struct ipt_entry *e, } if (e->next_offset - < sizeof(struct ipt_entry) + sizeof(struct ipt_entry_target)) { + < sizeof(struct ipt_entry) + sizeof(struct xt_entry_target)) { duprintf("checking: element %p size %u\n", e, e->next_offset); return -EINVAL; @@ -771,7 +771,7 @@ static void cleanup_entry(struct ipt_entry *e, struct net *net) { struct xt_tgdtor_param par; - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_entry_match *ematch; /* Cleanup all matches */ @@ -972,8 +972,8 @@ copy_entries_to_user(unsigned int total_size, /* ... then go back and fix counters and names */ for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ unsigned int i; - const struct ipt_entry_match *m; - const struct ipt_entry_target *t; + const struct xt_entry_match *m; + const struct xt_entry_target *t; e = (struct ipt_entry *)(loc_cpu_entry + off); if (copy_to_user(userptr + off @@ -990,7 +990,7 @@ copy_entries_to_user(unsigned int total_size, m = (void *)e + i; if (copy_to_user(userptr + off + i - + offsetof(struct ipt_entry_match, + + offsetof(struct xt_entry_match, u.user.name), m->u.kernel.match->name, strlen(m->u.kernel.match->name)+1) @@ -1002,7 +1002,7 @@ copy_entries_to_user(unsigned int total_size, t = ipt_get_target_c(e); if (copy_to_user(userptr + off + e->target_offset - + offsetof(struct ipt_entry_target, + + offsetof(struct xt_entry_target, u.user.name), t->u.kernel.target->name, strlen(t->u.kernel.target->name)+1) != 0) { @@ -1040,7 +1040,7 @@ static int compat_calc_entry(const struct ipt_entry *e, const void *base, struct xt_table_info *newinfo) { const struct xt_entry_match *ematch; - const struct ipt_entry_target *t; + const struct xt_entry_target *t; unsigned int entry_offset; int off, i, ret; @@ -1092,7 +1092,7 @@ static int compat_table_info(const struct xt_table_info *info, static int get_info(struct net *net, void __user *user, const int *len, int compat) { - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; struct xt_table *t; int ret; @@ -1105,7 +1105,7 @@ static int get_info(struct net *net, void __user *user, if (copy_from_user(name, user, sizeof(name)) != 0) return -EFAULT; - name[IPT_TABLE_MAXNAMELEN-1] = '\0'; + name[XT_TABLE_MAXNAMELEN-1] = '\0'; #ifdef CONFIG_COMPAT if (compat) xt_compat_lock(AF_INET); @@ -1400,14 +1400,14 @@ do_add_counters(struct net *net, const void __user *user, #ifdef CONFIG_COMPAT struct compat_ipt_replace { - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; u32 valid_hooks; u32 num_entries; u32 size; u32 hook_entry[NF_INET_NUMHOOKS]; u32 underflow[NF_INET_NUMHOOKS]; u32 num_counters; - compat_uptr_t counters; /* struct ipt_counters * */ + compat_uptr_t counters; /* struct xt_counters * */ struct compat_ipt_entry entries[0]; }; @@ -1416,7 +1416,7 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, unsigned int *size, struct xt_counters *counters, unsigned int i) { - struct ipt_entry_target *t; + struct xt_entry_target *t; struct compat_ipt_entry __user *ce; u_int16_t target_offset, next_offset; compat_uint_t origsize; @@ -1451,7 +1451,7 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, } static int -compat_find_calc_match(struct ipt_entry_match *m, +compat_find_calc_match(struct xt_entry_match *m, const char *name, const struct ipt_ip *ip, unsigned int hookmask, @@ -1473,7 +1473,7 @@ compat_find_calc_match(struct ipt_entry_match *m, static void compat_release_entry(struct compat_ipt_entry *e) { - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_entry_match *ematch; /* Cleanup all matches */ @@ -1494,7 +1494,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e, const char *name) { struct xt_entry_match *ematch; - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; unsigned int entry_offset; unsigned int j; @@ -1576,7 +1576,7 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr, unsigned int *size, const char *name, struct xt_table_info *newinfo, unsigned char *base) { - struct ipt_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; struct ipt_entry *de; unsigned int origsize; @@ -1884,7 +1884,7 @@ compat_do_ipt_set_ctl(struct sock *sk, int cmd, void __user *user, } struct compat_ipt_get_entries { - char name[IPT_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; compat_uint_t size; struct compat_ipt_entry entrytable[0]; }; @@ -2039,7 +2039,7 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) case IPT_SO_GET_REVISION_MATCH: case IPT_SO_GET_REVISION_TARGET: { - struct ipt_get_revision rev; + struct xt_get_revision rev; int target; if (*len != sizeof(rev)) { @@ -2176,7 +2176,7 @@ static int icmp_checkentry(const struct xt_mtchk_param *par) static struct xt_target ipt_builtin_tg[] __read_mostly = { { - .name = IPT_STANDARD_TARGET, + .name = XT_STANDARD_TARGET, .targetsize = sizeof(int), .family = NFPROTO_IPV4, #ifdef CONFIG_COMPAT @@ -2186,9 +2186,9 @@ static struct xt_target ipt_builtin_tg[] __read_mostly = { #endif }, { - .name = IPT_ERROR_TARGET, + .name = XT_ERROR_TARGET, .target = ipt_error, - .targetsize = IPT_FUNCTION_MAXNAMELEN, + .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_IPV4, }, }; diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 3a43cf36db8701f9b8a99317a60da0e3ac2ad8f4..1e26a4897655bddd2720730956ebe2d15d265ebf 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -29,6 +29,7 @@ #include #include #include +#include #define CLUSTERIP_VERSION "0.8" @@ -231,24 +232,22 @@ clusterip_hashfn(const struct sk_buff *skb, { const struct iphdr *iph = ip_hdr(skb); unsigned long hashval; - u_int16_t sport, dport; - const u_int16_t *ports; - - switch (iph->protocol) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - case IPPROTO_SCTP: - case IPPROTO_DCCP: - case IPPROTO_ICMP: - ports = (const void *)iph+iph->ihl*4; - sport = ports[0]; - dport = ports[1]; - break; - default: + u_int16_t sport = 0, dport = 0; + int poff; + + poff = proto_ports_offset(iph->protocol); + if (poff >= 0) { + const u_int16_t *ports; + u16 _ports[2]; + + ports = skb_header_pointer(skb, iph->ihl * 4 + poff, 4, _ports); + if (ports) { + sport = ports[0]; + dport = ports[1]; + } + } else { if (net_ratelimit()) pr_info("unknown protocol %u\n", iph->protocol); - sport = dport = 0; } switch (config->hash_mode) { diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 915fc17d7ce214a017f1993e0ab82a0603a3f4f6..72ffc8fda2e9faca3ab8c4cf3682df0de4a44faa 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -24,16 +24,15 @@ #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Netfilter Core Team "); MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog"); -/* Use lock to serialize, so printks don't overlap */ -static DEFINE_SPINLOCK(log_lock); - /* One level of recursion won't kill us */ -static void dump_packet(const struct nf_loginfo *info, +static void dump_packet(struct sbuff *m, + const struct nf_loginfo *info, const struct sk_buff *skb, unsigned int iphoff) { @@ -48,32 +47,32 @@ static void dump_packet(const struct nf_loginfo *info, ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph); if (ih == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Important fields: * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */ /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */ - printk("SRC=%pI4 DST=%pI4 ", + sb_add(m, "SRC=%pI4 DST=%pI4 ", &ih->saddr, &ih->daddr); /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */ - printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", + sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ", ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK, ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id)); /* Max length: 6 "CE DF MF " */ if (ntohs(ih->frag_off) & IP_CE) - printk("CE "); + sb_add(m, "CE "); if (ntohs(ih->frag_off) & IP_DF) - printk("DF "); + sb_add(m, "DF "); if (ntohs(ih->frag_off) & IP_MF) - printk("MF "); + sb_add(m, "MF "); /* Max length: 11 "FRAG:65535 " */ if (ntohs(ih->frag_off) & IP_OFFSET) - printk("FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); + sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET); if ((logflags & IPT_LOG_IPOPT) && ih->ihl * 4 > sizeof(struct iphdr)) { @@ -85,15 +84,15 @@ static void dump_packet(const struct nf_loginfo *info, op = skb_header_pointer(skb, iphoff+sizeof(_iph), optsize, _opt); if (op == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Max length: 127 "OPT (" 15*4*2chars ") " */ - printk("OPT ("); + sb_add(m, "OPT ("); for (i = 0; i < optsize; i++) - printk("%02X", op[i]); - printk(") "); + sb_add(m, "%02X", op[i]); + sb_add(m, ") "); } switch (ih->protocol) { @@ -102,7 +101,7 @@ static void dump_packet(const struct nf_loginfo *info, const struct tcphdr *th; /* Max length: 10 "PROTO=TCP " */ - printk("PROTO=TCP "); + sb_add(m, "PROTO=TCP "); if (ntohs(ih->frag_off) & IP_OFFSET) break; @@ -111,41 +110,41 @@ static void dump_packet(const struct nf_loginfo *info, th = skb_header_pointer(skb, iphoff + ih->ihl * 4, sizeof(_tcph), &_tcph); if (th == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Max length: 20 "SPT=65535 DPT=65535 " */ - printk("SPT=%u DPT=%u ", + sb_add(m, "SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest)); /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ if (logflags & IPT_LOG_TCPSEQ) - printk("SEQ=%u ACK=%u ", + sb_add(m, "SEQ=%u ACK=%u ", ntohl(th->seq), ntohl(th->ack_seq)); /* Max length: 13 "WINDOW=65535 " */ - printk("WINDOW=%u ", ntohs(th->window)); + sb_add(m, "WINDOW=%u ", ntohs(th->window)); /* Max length: 9 "RES=0x3F " */ - printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); + sb_add(m, "RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ if (th->cwr) - printk("CWR "); + sb_add(m, "CWR "); if (th->ece) - printk("ECE "); + sb_add(m, "ECE "); if (th->urg) - printk("URG "); + sb_add(m, "URG "); if (th->ack) - printk("ACK "); + sb_add(m, "ACK "); if (th->psh) - printk("PSH "); + sb_add(m, "PSH "); if (th->rst) - printk("RST "); + sb_add(m, "RST "); if (th->syn) - printk("SYN "); + sb_add(m, "SYN "); if (th->fin) - printk("FIN "); + sb_add(m, "FIN "); /* Max length: 11 "URGP=65535 " */ - printk("URGP=%u ", ntohs(th->urg_ptr)); + sb_add(m, "URGP=%u ", ntohs(th->urg_ptr)); if ((logflags & IPT_LOG_TCPOPT) && th->doff * 4 > sizeof(struct tcphdr)) { @@ -158,15 +157,15 @@ static void dump_packet(const struct nf_loginfo *info, iphoff+ih->ihl*4+sizeof(_tcph), optsize, _opt); if (op == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Max length: 127 "OPT (" 15*4*2chars ") " */ - printk("OPT ("); + sb_add(m, "OPT ("); for (i = 0; i < optsize; i++) - printk("%02X", op[i]); - printk(") "); + sb_add(m, "%02X", op[i]); + sb_add(m, ") "); } break; } @@ -177,9 +176,9 @@ static void dump_packet(const struct nf_loginfo *info, if (ih->protocol == IPPROTO_UDP) /* Max length: 10 "PROTO=UDP " */ - printk("PROTO=UDP " ); + sb_add(m, "PROTO=UDP " ); else /* Max length: 14 "PROTO=UDPLITE " */ - printk("PROTO=UDPLITE "); + sb_add(m, "PROTO=UDPLITE "); if (ntohs(ih->frag_off) & IP_OFFSET) break; @@ -188,13 +187,13 @@ static void dump_packet(const struct nf_loginfo *info, uh = skb_header_pointer(skb, iphoff+ih->ihl*4, sizeof(_udph), &_udph); if (uh == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Max length: 20 "SPT=65535 DPT=65535 " */ - printk("SPT=%u DPT=%u LEN=%u ", + sb_add(m, "SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest), ntohs(uh->len)); break; @@ -221,7 +220,7 @@ static void dump_packet(const struct nf_loginfo *info, [ICMP_ADDRESSREPLY] = 12 }; /* Max length: 11 "PROTO=ICMP " */ - printk("PROTO=ICMP "); + sb_add(m, "PROTO=ICMP "); if (ntohs(ih->frag_off) & IP_OFFSET) break; @@ -230,19 +229,19 @@ static void dump_packet(const struct nf_loginfo *info, ich = skb_header_pointer(skb, iphoff + ih->ihl * 4, sizeof(_icmph), &_icmph); if (ich == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Max length: 18 "TYPE=255 CODE=255 " */ - printk("TYPE=%u CODE=%u ", ich->type, ich->code); + sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code); /* Max length: 25 "INCOMPLETE [65535 bytes] " */ if (ich->type <= NR_ICMP_TYPES && required_len[ich->type] && skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } @@ -251,35 +250,35 @@ static void dump_packet(const struct nf_loginfo *info, case ICMP_ECHOREPLY: case ICMP_ECHO: /* Max length: 19 "ID=65535 SEQ=65535 " */ - printk("ID=%u SEQ=%u ", + sb_add(m, "ID=%u SEQ=%u ", ntohs(ich->un.echo.id), ntohs(ich->un.echo.sequence)); break; case ICMP_PARAMETERPROB: /* Max length: 14 "PARAMETER=255 " */ - printk("PARAMETER=%u ", + sb_add(m, "PARAMETER=%u ", ntohl(ich->un.gateway) >> 24); break; case ICMP_REDIRECT: /* Max length: 24 "GATEWAY=255.255.255.255 " */ - printk("GATEWAY=%pI4 ", &ich->un.gateway); + sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway); /* Fall through */ case ICMP_DEST_UNREACH: case ICMP_SOURCE_QUENCH: case ICMP_TIME_EXCEEDED: /* Max length: 3+maxlen */ if (!iphoff) { /* Only recurse once. */ - printk("["); - dump_packet(info, skb, + sb_add(m, "["); + dump_packet(m, info, skb, iphoff + ih->ihl*4+sizeof(_icmph)); - printk("] "); + sb_add(m, "] "); } /* Max length: 10 "MTU=65535 " */ if (ich->type == ICMP_DEST_UNREACH && ich->code == ICMP_FRAG_NEEDED) - printk("MTU=%u ", ntohs(ich->un.frag.mtu)); + sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu)); } break; } @@ -292,19 +291,19 @@ static void dump_packet(const struct nf_loginfo *info, break; /* Max length: 9 "PROTO=AH " */ - printk("PROTO=AH "); + sb_add(m, "PROTO=AH "); /* Max length: 25 "INCOMPLETE [65535 bytes] " */ ah = skb_header_pointer(skb, iphoff+ih->ihl*4, sizeof(_ahdr), &_ahdr); if (ah == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Length: 15 "SPI=0xF1234567 " */ - printk("SPI=0x%x ", ntohl(ah->spi)); + sb_add(m, "SPI=0x%x ", ntohl(ah->spi)); break; } case IPPROTO_ESP: { @@ -312,7 +311,7 @@ static void dump_packet(const struct nf_loginfo *info, const struct ip_esp_hdr *eh; /* Max length: 10 "PROTO=ESP " */ - printk("PROTO=ESP "); + sb_add(m, "PROTO=ESP "); if (ntohs(ih->frag_off) & IP_OFFSET) break; @@ -321,25 +320,25 @@ static void dump_packet(const struct nf_loginfo *info, eh = skb_header_pointer(skb, iphoff+ih->ihl*4, sizeof(_esph), &_esph); if (eh == NULL) { - printk("INCOMPLETE [%u bytes] ", + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - iphoff - ih->ihl*4); break; } /* Length: 15 "SPI=0xF1234567 " */ - printk("SPI=0x%x ", ntohl(eh->spi)); + sb_add(m, "SPI=0x%x ", ntohl(eh->spi)); break; } /* Max length: 10 "PROTO 255 " */ default: - printk("PROTO=%u ", ih->protocol); + sb_add(m, "PROTO=%u ", ih->protocol); } /* Max length: 15 "UID=4294967295 " */ if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) { read_lock_bh(&skb->sk->sk_callback_lock); if (skb->sk->sk_socket && skb->sk->sk_socket->file) - printk("UID=%u GID=%u ", + sb_add(m, "UID=%u GID=%u ", skb->sk->sk_socket->file->f_cred->fsuid, skb->sk->sk_socket->file->f_cred->fsgid); read_unlock_bh(&skb->sk->sk_callback_lock); @@ -347,7 +346,7 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 16 "MARK=0xFFFFFFFF " */ if (!iphoff && skb->mark) - printk("MARK=0x%x ", skb->mark); + sb_add(m, "MARK=0x%x ", skb->mark); /* Proto Max log string length */ /* IP: 40+46+6+11+127 = 230 */ @@ -364,7 +363,8 @@ static void dump_packet(const struct nf_loginfo *info, /* maxlen = 230+ 91 + 230 + 252 = 803 */ } -static void dump_mac_header(const struct nf_loginfo *info, +static void dump_mac_header(struct sbuff *m, + const struct nf_loginfo *info, const struct sk_buff *skb) { struct net_device *dev = skb->dev; @@ -378,7 +378,7 @@ static void dump_mac_header(const struct nf_loginfo *info, switch (dev->type) { case ARPHRD_ETHER: - printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ", + sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ", eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, ntohs(eth_hdr(skb)->h_proto)); return; @@ -387,17 +387,17 @@ static void dump_mac_header(const struct nf_loginfo *info, } fallback: - printk("MAC="); + sb_add(m, "MAC="); if (dev->hard_header_len && skb->mac_header != skb->network_header) { const unsigned char *p = skb_mac_header(skb); unsigned int i; - printk("%02x", *p++); + sb_add(m, "%02x", *p++); for (i = 1; i < dev->hard_header_len; i++, p++) - printk(":%02x", *p); + sb_add(m, ":%02x", *p); } - printk(" "); + sb_add(m, " "); } static struct nf_loginfo default_loginfo = { @@ -419,11 +419,12 @@ ipt_log_packet(u_int8_t pf, const struct nf_loginfo *loginfo, const char *prefix) { + struct sbuff *m = sb_open(); + if (!loginfo) loginfo = &default_loginfo; - spin_lock_bh(&log_lock); - printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, + sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, prefix, in ? in->name : "", out ? out->name : ""); @@ -434,20 +435,20 @@ ipt_log_packet(u_int8_t pf, physindev = skb->nf_bridge->physindev; if (physindev && in != physindev) - printk("PHYSIN=%s ", physindev->name); + sb_add(m, "PHYSIN=%s ", physindev->name); physoutdev = skb->nf_bridge->physoutdev; if (physoutdev && out != physoutdev) - printk("PHYSOUT=%s ", physoutdev->name); + sb_add(m, "PHYSOUT=%s ", physoutdev->name); } #endif /* MAC logging for input path only. */ if (in && !out) - dump_mac_header(loginfo, skb); + dump_mac_header(m, loginfo, skb); + + dump_packet(m, loginfo, skb, 0); - dump_packet(loginfo, skb, 0); - printk("\n"); - spin_unlock_bh(&log_lock); + sb_close(m); } static unsigned int diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c index c31b876682502c5d6c13523ff086103e49c5fd7f..0f23b3f06df05e7643e1cd337325955dc6942794 100644 --- a/net/ipv4/netfilter/nf_nat_amanda.c +++ b/net/ipv4/netfilter/nf_nat_amanda.c @@ -44,9 +44,16 @@ static unsigned int help(struct sk_buff *skb, /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + port = 0; break; + } } if (port == 0) diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 957c9241fb0ce1d91cde6c1b098f81b52337690a..295c97431e4358408dc45fc7c493536bb41434fc 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -47,7 +47,7 @@ __nf_nat_proto_find(u_int8_t protonum) return rcu_dereference(nf_nat_protos[protonum]); } -const struct nf_nat_protocol * +static const struct nf_nat_protocol * nf_nat_proto_find_get(u_int8_t protonum) { const struct nf_nat_protocol *p; @@ -60,14 +60,12 @@ nf_nat_proto_find_get(u_int8_t protonum) return p; } -EXPORT_SYMBOL_GPL(nf_nat_proto_find_get); -void +static void nf_nat_proto_put(const struct nf_nat_protocol *p) { module_put(p->me); } -EXPORT_SYMBOL_GPL(nf_nat_proto_put); /* We keep an extra hash for each conntrack, for fast searching. */ static inline unsigned int @@ -262,11 +260,17 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple, proto = __nf_nat_proto_find(orig_tuple->dst.protonum); /* Only bother mapping if it's not already in range and unique */ - if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM) && - (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) || - proto->in_range(tuple, maniptype, &range->min, &range->max)) && - !nf_nat_used_tuple(tuple, ct)) - goto out; + if (!(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { + if (range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) { + if (proto->in_range(tuple, maniptype, &range->min, + &range->max) && + (range->min.all == range->max.all || + !nf_nat_used_tuple(tuple, ct))) + goto out; + } else if (!nf_nat_used_tuple(tuple, ct)) { + goto out; + } + } /* Last change: get protocol to try to obtain unique tuple. */ proto->unique_tuple(tuple, range, maniptype, ct); @@ -458,6 +462,18 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, return 0; } + if (manip == IP_NAT_MANIP_SRC) + statusbit = IPS_SRC_NAT; + else + statusbit = IPS_DST_NAT; + + /* Invert if this is reply dir. */ + if (dir == IP_CT_DIR_REPLY) + statusbit ^= IPS_NAT_MASK; + + if (!(ct->status & statusbit)) + return 1; + pr_debug("icmp_reply_translation: translating error %p manip %u " "dir %s\n", skb, manip, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY"); @@ -492,20 +508,9 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct, /* Change outer to look the reply to an incoming packet * (proto 0 means don't invert per-proto part). */ - if (manip == IP_NAT_MANIP_SRC) - statusbit = IPS_SRC_NAT; - else - statusbit = IPS_DST_NAT; - - /* Invert if this is reply dir. */ - if (dir == IP_CT_DIR_REPLY) - statusbit ^= IPS_NAT_MASK; - - if (ct->status & statusbit) { - nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple); - if (!manip_pkt(0, skb, 0, &target, manip)) - return 0; - } + nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple); + if (!manip_pkt(0, skb, 0, &target, manip)) + return 0; return 1; } diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c index 86e0e84ff0a04fe09cd3b5d67dddcf93457ffa15..dc73abb3fe27ecea0537ab8fa2a5e029435fb783 100644 --- a/net/ipv4/netfilter/nf_nat_ftp.c +++ b/net/ipv4/netfilter/nf_nat_ftp.c @@ -79,9 +79,16 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb, /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + port = 0; break; + } } if (port == 0) diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c index 5045196d853c7878050161ea5e43e1aac26eff83..790f3160e0121c19ed5f2bef07388656ae7310a6 100644 --- a/net/ipv4/netfilter/nf_nat_h323.c +++ b/net/ipv4/netfilter/nf_nat_h323.c @@ -222,13 +222,24 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, /* Try to get a pair of ports. */ for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port); nated_port != 0; nated_port += 2) { + int ret; + rtp_exp->tuple.dst.u.udp.port = htons(nated_port); - if (nf_ct_expect_related(rtp_exp) == 0) { + ret = nf_ct_expect_related(rtp_exp); + if (ret == 0) { rtcp_exp->tuple.dst.u.udp.port = htons(nated_port + 1); - if (nf_ct_expect_related(rtcp_exp) == 0) + ret = nf_ct_expect_related(rtcp_exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + nf_ct_unexpect_related(rtp_exp); + nated_port = 0; break; - nf_ct_unexpect_related(rtp_exp); + } + } else if (ret != -EBUSY) { + nated_port = 0; + break; } } @@ -284,9 +295,16 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct, /* Try to get same port: if not, try to change it. */ for (; nated_port != 0; nated_port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(nated_port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + nated_port = 0; break; + } } if (nated_port == 0) { /* No port available */ @@ -334,9 +352,16 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, /* Try to get same port: if not, try to change it. */ for (; nated_port != 0; nated_port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(nated_port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) break; + else if (ret != -EBUSY) { + nated_port = 0; + break; + } } if (nated_port == 0) { /* No port available */ @@ -418,9 +443,16 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, /* Try to get same port: if not, try to change it. */ for (; nated_port != 0; nated_port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(nated_port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + nated_port = 0; break; + } } if (nated_port == 0) { /* No port available */ @@ -500,9 +532,16 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, /* Try to get same port: if not, try to change it. */ for (nated_port = ntohs(port); nated_port != 0; nated_port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(nated_port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) break; + else if (ret != -EBUSY) { + nated_port = 0; + break; + } } if (nated_port == 0) { /* No port available */ diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 4a0c6b548eee22f1dfc0e6d01187f209319f10d7..31427fb57aa8abdc299bc1a2c1ab2ebc3929b543 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c @@ -153,6 +153,35 @@ void nf_nat_set_seq_adjust(struct nf_conn *ct, enum ip_conntrack_info ctinfo, } EXPORT_SYMBOL_GPL(nf_nat_set_seq_adjust); +static void nf_nat_csum(struct sk_buff *skb, struct iphdr *iph, void *data, + int datalen, __sum16 *check, int oldlen) +{ + struct rtable *rt = skb_rtable(skb); + + if (skb->ip_summed != CHECKSUM_PARTIAL) { + if (!(rt->rt_flags & RTCF_LOCAL) && + skb->dev->features & NETIF_F_V4_CSUM) { + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum_start = skb_headroom(skb) + + skb_network_offset(skb) + + iph->ihl * 4; + skb->csum_offset = (void *)check - data; + *check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + datalen, iph->protocol, 0); + } else { + *check = 0; + *check = csum_tcpudp_magic(iph->saddr, iph->daddr, + datalen, iph->protocol, + csum_partial(data, datalen, + 0)); + if (iph->protocol == IPPROTO_UDP && !*check) + *check = CSUM_MANGLED_0; + } + } else + inet_proto_csum_replace2(check, skb, + htons(oldlen), htons(datalen), 1); +} + /* Generic function for mangling variable-length address changes inside * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX * command in FTP). @@ -169,7 +198,6 @@ int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, const char *rep_buffer, unsigned int rep_len, bool adjust) { - struct rtable *rt = skb_rtable(skb); struct iphdr *iph; struct tcphdr *tcph; int oldlen, datalen; @@ -192,26 +220,7 @@ int __nf_nat_mangle_tcp_packet(struct sk_buff *skb, match_offset, match_len, rep_buffer, rep_len); datalen = skb->len - iph->ihl*4; - if (skb->ip_summed != CHECKSUM_PARTIAL) { - if (!(rt->rt_flags & RTCF_LOCAL) && - skb->dev->features & NETIF_F_V4_CSUM) { - skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum_start = skb_headroom(skb) + - skb_network_offset(skb) + - iph->ihl * 4; - skb->csum_offset = offsetof(struct tcphdr, check); - tcph->check = ~tcp_v4_check(datalen, - iph->saddr, iph->daddr, 0); - } else { - tcph->check = 0; - tcph->check = tcp_v4_check(datalen, - iph->saddr, iph->daddr, - csum_partial(tcph, - datalen, 0)); - } - } else - inet_proto_csum_replace2(&tcph->check, skb, - htons(oldlen), htons(datalen), 1); + nf_nat_csum(skb, iph, tcph, datalen, &tcph->check, oldlen); if (adjust && rep_len != match_len) nf_nat_set_seq_adjust(ct, ctinfo, tcph->seq, @@ -240,7 +249,6 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb, const char *rep_buffer, unsigned int rep_len) { - struct rtable *rt = skb_rtable(skb); struct iphdr *iph; struct udphdr *udph; int datalen, oldlen; @@ -274,29 +282,7 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb, if (!udph->check && skb->ip_summed != CHECKSUM_PARTIAL) return 1; - if (skb->ip_summed != CHECKSUM_PARTIAL) { - if (!(rt->rt_flags & RTCF_LOCAL) && - skb->dev->features & NETIF_F_V4_CSUM) { - skb->ip_summed = CHECKSUM_PARTIAL; - skb->csum_start = skb_headroom(skb) + - skb_network_offset(skb) + - iph->ihl * 4; - skb->csum_offset = offsetof(struct udphdr, check); - udph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, - datalen, IPPROTO_UDP, - 0); - } else { - udph->check = 0; - udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, - datalen, IPPROTO_UDP, - csum_partial(udph, - datalen, 0)); - if (!udph->check) - udph->check = CSUM_MANGLED_0; - } - } else - inet_proto_csum_replace2(&udph->check, skb, - htons(oldlen), htons(datalen), 1); + nf_nat_csum(skb, iph, udph, datalen, &udph->check, oldlen); return 1; } diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c index ea83a886b03e6ac3204f410047542a9edea8c4dc..535e1a80235688480bb9b58d2492291183e7703a 100644 --- a/net/ipv4/netfilter/nf_nat_irc.c +++ b/net/ipv4/netfilter/nf_nat_irc.c @@ -45,9 +45,16 @@ static unsigned int help(struct sk_buff *skb, /* Try to get same port: if not, try to change it. */ for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) { + int ret; + exp->tuple.dst.u.tcp.port = htons(port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + port = 0; break; + } } if (port == 0) diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index ebbd319f62f56741ea2d22da8529cda0586089a0..21c30426480b0d08cdc10a0257ee2f6ce736840f 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c @@ -106,16 +106,15 @@ alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) { /* Force range to this IP; let proto decide mapping for per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). - Use reply in case it's already been mangled (eg local packet). */ - __be32 ip - = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC - ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip - : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip); - struct nf_nat_range range - = { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } }; - - pr_debug("Allocating NULL binding for %p (%pI4)\n", ct, &ip); + struct nf_nat_range range; + + range.flags = 0; + pr_debug("Allocating NULL binding for %p (%pI4)\n", ct, + HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC ? + &ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip : + &ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip); + return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); } diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index 11b538deaaec1f996505d387d549b3de6dd4bb37..e40cf7816fdbb4e0088efd200a46cbd3a9041ed2 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c @@ -307,9 +307,16 @@ static unsigned int ip_nat_sip_expect(struct sk_buff *skb, unsigned int dataoff, exp->expectfn = ip_nat_sip_expected; for (; port != 0; port++) { + int ret; + exp->tuple.dst.u.udp.port = htons(port); - if (nf_ct_expect_related(exp) == 0) + ret = nf_ct_expect_related(exp); + if (ret == 0) + break; + else if (ret != -EBUSY) { + port = 0; break; + } } if (port == 0) @@ -480,13 +487,25 @@ static unsigned int ip_nat_sdp_media(struct sk_buff *skb, unsigned int dataoff, /* Try to get same pair of ports: if not, try to change them. */ for (port = ntohs(rtp_exp->tuple.dst.u.udp.port); port != 0; port += 2) { + int ret; + rtp_exp->tuple.dst.u.udp.port = htons(port); - if (nf_ct_expect_related(rtp_exp) != 0) + ret = nf_ct_expect_related(rtp_exp); + if (ret == -EBUSY) continue; + else if (ret < 0) { + port = 0; + break; + } rtcp_exp->tuple.dst.u.udp.port = htons(port + 1); - if (nf_ct_expect_related(rtcp_exp) == 0) + ret = nf_ct_expect_related(rtcp_exp); + if (ret == 0) break; - nf_ct_unexpect_related(rtp_exp); + else if (ret != -EBUSY) { + nf_ct_unexpect_related(rtp_exp); + port = 0; + break; + } } if (port == 0) diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index f2d297351405d8fab1262bb308142202d72e7f5b..65699c24411cfb5cb3ee55428e7e0302feb64716 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c @@ -28,8 +28,7 @@ #include #include -const struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp; -static DEFINE_SPINLOCK(inet_proto_lock); +const struct net_protocol *inet_protos[MAX_INET_PROTOS] __read_mostly; /* * Add a protocol handler to the hash tables @@ -37,20 +36,9 @@ static DEFINE_SPINLOCK(inet_proto_lock); int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) { - int hash, ret; + int hash = protocol & (MAX_INET_PROTOS - 1); - hash = protocol & (MAX_INET_PROTOS - 1); - - spin_lock_bh(&inet_proto_lock); - if (inet_protos[hash]) { - ret = -1; - } else { - inet_protos[hash] = prot; - ret = 0; - } - spin_unlock_bh(&inet_proto_lock); - - return ret; + return !cmpxchg(&inet_protos[hash], NULL, prot) ? 0 : -1; } EXPORT_SYMBOL(inet_add_protocol); @@ -60,18 +48,9 @@ EXPORT_SYMBOL(inet_add_protocol); int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) { - int hash, ret; - - hash = protocol & (MAX_INET_PROTOS - 1); + int ret, hash = protocol & (MAX_INET_PROTOS - 1); - spin_lock_bh(&inet_proto_lock); - if (inet_protos[hash] == prot) { - inet_protos[hash] = NULL; - ret = 0; - } else { - ret = -1; - } - spin_unlock_bh(&inet_proto_lock); + ret = (cmpxchg(&inet_protos[hash], prot, NULL) == prot) ? 0 : -1; synchronize_net(); diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 009a7b2aa1ef0493f542b4745b334e2964c0b826..1f85ef289895a8c2a4a567089ad5bef7c1271dae 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c @@ -505,7 +505,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ipc.addr = inet->inet_saddr; ipc.opt = NULL; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; ipc.oif = sk->sk_bound_dev_if; if (msg->msg_controllen) { diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ac6559cb54f9f650986e4dd86996349e328cd92a..d6cb2bfcd8e1baf7495e55ce83b534b2b0955b2f 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -159,7 +159,6 @@ static struct dst_ops ipv4_dst_ops = { .link_failure = ipv4_link_failure, .update_pmtu = ip_rt_update_pmtu, .local_out = __ip_local_out, - .entries = ATOMIC_INIT(0), }; #define ECN_OR_COST(class) TC_PRIO_##class @@ -466,7 +465,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v) seq_printf(seq,"%08x %08x %08x %08x %08x %08x %08x %08x " " %08x %08x %08x %08x %08x %08x %08x %08x %08x \n", - atomic_read(&ipv4_dst_ops.entries), + dst_entries_get_slow(&ipv4_dst_ops), st->in_hit, st->in_slow_tot, st->in_slow_mc, @@ -945,6 +944,7 @@ static int rt_garbage_collect(struct dst_ops *ops) struct rtable *rth, **rthp; unsigned long now = jiffies; int goal; + int entries = dst_entries_get_fast(&ipv4_dst_ops); /* * Garbage collection is pretty expensive, @@ -954,28 +954,28 @@ static int rt_garbage_collect(struct dst_ops *ops) RT_CACHE_STAT_INC(gc_total); if (now - last_gc < ip_rt_gc_min_interval && - atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) { + entries < ip_rt_max_size) { RT_CACHE_STAT_INC(gc_ignored); goto out; } + entries = dst_entries_get_slow(&ipv4_dst_ops); /* Calculate number of entries, which we want to expire now. */ - goal = atomic_read(&ipv4_dst_ops.entries) - - (ip_rt_gc_elasticity << rt_hash_log); + goal = entries - (ip_rt_gc_elasticity << rt_hash_log); if (goal <= 0) { if (equilibrium < ipv4_dst_ops.gc_thresh) equilibrium = ipv4_dst_ops.gc_thresh; - goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium; + goal = entries - equilibrium; if (goal > 0) { equilibrium += min_t(unsigned int, goal >> 1, rt_hash_mask + 1); - goal = atomic_read(&ipv4_dst_ops.entries) - equilibrium; + goal = entries - equilibrium; } } else { /* We are in dangerous area. Try to reduce cache really * aggressively. */ goal = max_t(unsigned int, goal >> 1, rt_hash_mask + 1); - equilibrium = atomic_read(&ipv4_dst_ops.entries) - goal; + equilibrium = entries - goal; } if (now - last_gc >= ip_rt_gc_min_interval) @@ -1032,14 +1032,16 @@ static int rt_garbage_collect(struct dst_ops *ops) expire >>= 1; #if RT_CACHE_DEBUG >= 2 printk(KERN_DEBUG "expire>> %u %d %d %d\n", expire, - atomic_read(&ipv4_dst_ops.entries), goal, i); + dst_entries_get_fast(&ipv4_dst_ops), goal, i); #endif - if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) + if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size) goto out; } while (!in_softirq() && time_before_eq(jiffies, now)); - if (atomic_read(&ipv4_dst_ops.entries) < ip_rt_max_size) + if (dst_entries_get_fast(&ipv4_dst_ops) < ip_rt_max_size) + goto out; + if (dst_entries_get_slow(&ipv4_dst_ops) < ip_rt_max_size) goto out; if (net_ratelimit()) printk(KERN_WARNING "dst cache overflow\n"); @@ -1049,11 +1051,12 @@ static int rt_garbage_collect(struct dst_ops *ops) work_done: expire += ip_rt_gc_min_interval; if (expire > ip_rt_gc_timeout || - atomic_read(&ipv4_dst_ops.entries) < ipv4_dst_ops.gc_thresh) + dst_entries_get_fast(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh || + dst_entries_get_slow(&ipv4_dst_ops) < ipv4_dst_ops.gc_thresh) expire = ip_rt_gc_timeout; #if RT_CACHE_DEBUG >= 2 printk(KERN_DEBUG "expire++ %u %d %d %d\n", expire, - atomic_read(&ipv4_dst_ops.entries), goal, rover); + dst_entries_get_fast(&ipv4_dst_ops), goal, rover); #endif out: return 0; } @@ -1102,23 +1105,23 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, * Note that we do rt_free on this new route entry, so that * once its refcount hits zero, we are still able to reap it * (Thanks Alexey) - * Note also the rt_free uses call_rcu. We don't actually - * need rcu protection here, this is just our path to get - * on the route gc list. + * Note: To avoid expensive rcu stuff for this uncached dst, + * we set DST_NOCACHE so that dst_release() can free dst without + * waiting a grace period. */ + rt->dst.flags |= DST_NOCACHE; if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { int err = arp_bind_neighbour(&rt->dst); if (err) { if (net_ratelimit()) printk(KERN_WARNING "Neighbour table failure & not caching routes.\n"); - rt_drop(rt); + ip_rt_put(rt); return err; } } - rt_free(rt); goto skip_hashing; } @@ -1268,18 +1271,11 @@ static int rt_intern_hash(unsigned hash, struct rtable *rt, void rt_bind_peer(struct rtable *rt, int create) { - static DEFINE_SPINLOCK(rt_peer_lock); struct inet_peer *peer; peer = inet_getpeer(rt->rt_dst, create); - spin_lock_bh(&rt_peer_lock); - if (rt->peer == NULL) { - rt->peer = peer; - peer = NULL; - } - spin_unlock_bh(&rt_peer_lock); - if (peer) + if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL) inet_putpeer(peer); } @@ -1779,12 +1775,15 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt) if (rt->fl.iif == 0) src = rt->rt_src; - else if (fib_lookup(dev_net(rt->dst.dev), &rt->fl, &res) == 0) { - src = FIB_RES_PREFSRC(res); - fib_res_put(&res); - } else - src = inet_select_addr(rt->dst.dev, rt->rt_gateway, + else { + rcu_read_lock(); + if (fib_lookup(dev_net(rt->dst.dev), &rt->fl, &res) == 0) + src = FIB_RES_PREFSRC(res); + else + src = inet_select_addr(rt->dst.dev, rt->rt_gateway, RT_SCOPE_UNIVERSE); + rcu_read_unlock(); + } memcpy(addr, &src, 4); } @@ -2087,6 +2086,7 @@ static int ip_mkroute_input(struct sk_buff *skb, * Such approach solves two big problems: * 1. Not simplex devices are handled properly. * 2. IP spoofing attempts are filtered with 100% of guarantee. + * called with rcu_read_lock() */ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, @@ -2108,7 +2108,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, unsigned hash; __be32 spec_dst; int err = -EINVAL; - int free_res = 0; struct net * net = dev_net(dev); /* IP on this device is disabled. */ @@ -2124,7 +2123,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, ipv4_is_loopback(saddr)) goto martian_source; - if (daddr == htonl(0xFFFFFFFF) || (saddr == 0 && daddr == 0)) + if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0)) goto brd_input; /* Accept zero addresses only to limited broadcast; @@ -2133,19 +2132,18 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (ipv4_is_zeronet(saddr)) goto martian_source; - if (ipv4_is_lbcast(daddr) || ipv4_is_zeronet(daddr) || - ipv4_is_loopback(daddr)) + if (ipv4_is_zeronet(daddr) || ipv4_is_loopback(daddr)) goto martian_destination; /* * Now we are ready to route packet. */ - if ((err = fib_lookup(net, &fl, &res)) != 0) { + err = fib_lookup(net, &fl, &res); + if (err != 0) { if (!IN_DEV_FORWARD(in_dev)) goto e_hostunreach; goto no_route; } - free_res = 1; RT_CACHE_STAT_INC(in_slow_tot); @@ -2154,8 +2152,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (res.type == RTN_LOCAL) { err = fib_validate_source(saddr, daddr, tos, - net->loopback_dev->ifindex, - dev, &spec_dst, &itag, skb->mark); + net->loopback_dev->ifindex, + dev, &spec_dst, &itag, skb->mark); if (err < 0) goto martian_source_keep_err; if (err) @@ -2170,9 +2168,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, goto martian_destination; err = ip_mkroute_input(skb, &res, &fl, in_dev, daddr, saddr, tos); -done: - if (free_res) - fib_res_put(&res); out: return err; brd_input: @@ -2232,7 +2227,7 @@ out: return err; rth->rt_type = res.type; hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); err = rt_intern_hash(hash, rth, NULL, skb, fl.iif); - goto done; + goto out; no_route: RT_CACHE_STAT_INC(in_no_route); @@ -2255,21 +2250,21 @@ out: return err; e_hostunreach: err = -EHOSTUNREACH; - goto done; + goto out; e_inval: err = -EINVAL; - goto done; + goto out; e_nobufs: err = -ENOBUFS; - goto done; + goto out; martian_source: err = -EINVAL; martian_source_keep_err: ip_handle_martian_source(dev, in_dev, skb, daddr, saddr); - goto done; + goto out; } int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, @@ -2355,6 +2350,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, } EXPORT_SYMBOL(ip_route_input_common); +/* called with rcu_read_lock() */ static int __mkroute_output(struct rtable **result, struct fib_result *res, const struct flowi *fl, @@ -2365,53 +2361,47 @@ static int __mkroute_output(struct rtable **result, struct rtable *rth; struct in_device *in_dev; u32 tos = RT_FL_TOS(oldflp); - int err = 0; - if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags&IFF_LOOPBACK)) + if (ipv4_is_loopback(fl->fl4_src) && !(dev_out->flags & IFF_LOOPBACK)) return -EINVAL; - if (fl->fl4_dst == htonl(0xFFFFFFFF)) + if (ipv4_is_lbcast(fl->fl4_dst)) res->type = RTN_BROADCAST; else if (ipv4_is_multicast(fl->fl4_dst)) res->type = RTN_MULTICAST; - else if (ipv4_is_lbcast(fl->fl4_dst) || ipv4_is_zeronet(fl->fl4_dst)) + else if (ipv4_is_zeronet(fl->fl4_dst)) return -EINVAL; if (dev_out->flags & IFF_LOOPBACK) flags |= RTCF_LOCAL; - /* get work reference to inet device */ - in_dev = in_dev_get(dev_out); + in_dev = __in_dev_get_rcu(dev_out); if (!in_dev) return -EINVAL; if (res->type == RTN_BROADCAST) { flags |= RTCF_BROADCAST | RTCF_LOCAL; - if (res->fi) { - fib_info_put(res->fi); - res->fi = NULL; - } + res->fi = NULL; } else if (res->type == RTN_MULTICAST) { - flags |= RTCF_MULTICAST|RTCF_LOCAL; + flags |= RTCF_MULTICAST | RTCF_LOCAL; if (!ip_check_mc(in_dev, oldflp->fl4_dst, oldflp->fl4_src, oldflp->proto)) flags &= ~RTCF_LOCAL; /* If multicast route do not exist use - default one, but do not gateway in this case. - Yes, it is hack. + * default one, but do not gateway in this case. + * Yes, it is hack. */ - if (res->fi && res->prefixlen < 4) { - fib_info_put(res->fi); + if (res->fi && res->prefixlen < 4) res->fi = NULL; - } } rth = dst_alloc(&ipv4_dst_ops); - if (!rth) { - err = -ENOBUFS; - goto cleanup; - } + if (!rth) + return -ENOBUFS; + + in_dev_hold(in_dev); + rth->idev = in_dev; atomic_set(&rth->dst.__refcnt, 1); rth->dst.flags= DST_HOST; @@ -2432,7 +2422,6 @@ static int __mkroute_output(struct rtable **result, cache entry */ rth->dst.dev = dev_out; dev_hold(dev_out); - rth->idev = in_dev_get(dev_out); rth->rt_gateway = fl->fl4_dst; rth->rt_spec_dst= fl->fl4_src; @@ -2467,15 +2456,11 @@ static int __mkroute_output(struct rtable **result, rt_set_nexthop(rth, res, 0); rth->rt_flags = flags; - *result = rth; - cleanup: - /* release work reference to inet device */ - in_dev_put(in_dev); - - return err; + return 0; } +/* called with rcu_read_lock() */ static int ip_mkroute_output(struct rtable **rp, struct fib_result *res, const struct flowi *fl, @@ -2497,6 +2482,7 @@ static int ip_mkroute_output(struct rtable **rp, /* * Major route resolver routine. + * called with rcu_read_lock(); */ static int ip_route_output_slow(struct net *net, struct rtable **rp, @@ -2515,9 +2501,8 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, .iif = net->loopback_dev->ifindex, .oif = oldflp->oif }; struct fib_result res; - unsigned flags = 0; + unsigned int flags = 0; struct net_device *dev_out = NULL; - int free_res = 0; int err; @@ -2543,9 +2528,9 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, if (oldflp->oif == 0 && (ipv4_is_multicast(oldflp->fl4_dst) || - oldflp->fl4_dst == htonl(0xFFFFFFFF))) { + ipv4_is_lbcast(oldflp->fl4_dst))) { /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ - dev_out = ip_dev_find(net, oldflp->fl4_src); + dev_out = __ip_dev_find(net, oldflp->fl4_src, false); if (dev_out == NULL) goto out; @@ -2570,29 +2555,24 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) { /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */ - dev_out = ip_dev_find(net, oldflp->fl4_src); - if (dev_out == NULL) + if (!__ip_dev_find(net, oldflp->fl4_src, false)) goto out; - dev_put(dev_out); - dev_out = NULL; } } if (oldflp->oif) { - dev_out = dev_get_by_index(net, oldflp->oif); + dev_out = dev_get_by_index_rcu(net, oldflp->oif); err = -ENODEV; if (dev_out == NULL) goto out; /* RACE: Check return value of inet_select_addr instead. */ - if (__in_dev_get_rtnl(dev_out) == NULL) { - dev_put(dev_out); + if (rcu_dereference(dev_out->ip_ptr) == NULL) goto out; /* Wrong error code */ - } if (ipv4_is_local_multicast(oldflp->fl4_dst) || - oldflp->fl4_dst == htonl(0xFFFFFFFF)) { + ipv4_is_lbcast(oldflp->fl4_dst)) { if (!fl.fl4_src) fl.fl4_src = inet_select_addr(dev_out, 0, RT_SCOPE_LINK); @@ -2612,10 +2592,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, fl.fl4_dst = fl.fl4_src; if (!fl.fl4_dst) fl.fl4_dst = fl.fl4_src = htonl(INADDR_LOOPBACK); - if (dev_out) - dev_put(dev_out); dev_out = net->loopback_dev; - dev_hold(dev_out); fl.oif = net->loopback_dev->ifindex; res.type = RTN_LOCAL; flags |= RTCF_LOCAL; @@ -2649,23 +2626,15 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, res.type = RTN_UNICAST; goto make_route; } - if (dev_out) - dev_put(dev_out); err = -ENETUNREACH; goto out; } - free_res = 1; if (res.type == RTN_LOCAL) { if (!fl.fl4_src) fl.fl4_src = fl.fl4_dst; - if (dev_out) - dev_put(dev_out); dev_out = net->loopback_dev; - dev_hold(dev_out); fl.oif = dev_out->ifindex; - if (res.fi) - fib_info_put(res.fi); res.fi = NULL; flags |= RTCF_LOCAL; goto make_route; @@ -2682,28 +2651,21 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, if (!fl.fl4_src) fl.fl4_src = FIB_RES_PREFSRC(res); - if (dev_out) - dev_put(dev_out); dev_out = FIB_RES_DEV(res); - dev_hold(dev_out); fl.oif = dev_out->ifindex; make_route: err = ip_mkroute_output(rp, &res, &fl, oldflp, dev_out, flags); - - if (free_res) - fib_res_put(&res); - if (dev_out) - dev_put(dev_out); out: return err; } int __ip_route_output_key(struct net *net, struct rtable **rp, const struct flowi *flp) { - unsigned hash; + unsigned int hash; + int res; struct rtable *rth; if (!rt_caching(net)) @@ -2734,7 +2696,10 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, rcu_read_unlock_bh(); slow_output: - return ip_route_output_slow(net, rp, flp); + rcu_read_lock(); + res = ip_route_output_slow(net, rp, flp); + rcu_read_unlock(); + return res; } EXPORT_SYMBOL_GPL(__ip_route_output_key); @@ -2753,7 +2718,6 @@ static struct dst_ops ipv4_dst_blackhole_ops = { .destroy = ipv4_dst_destroy, .check = ipv4_blackhole_dst_check, .update_pmtu = ipv4_rt_blackhole_update_pmtu, - .entries = ATOMIC_INIT(0), }; @@ -2798,7 +2762,7 @@ static int ipv4_dst_blackhole(struct net *net, struct rtable **rp, struct flowi dst_release(&(*rp)->dst); *rp = rt; - return (rt ? 0 : -ENOMEM); + return rt ? 0 : -ENOMEM; } int ip_route_output_flow(struct net *net, struct rtable **rp, struct flowi *flp, @@ -3323,6 +3287,12 @@ int __init ip_rt_init(void) ipv4_dst_blackhole_ops.kmem_cachep = ipv4_dst_ops.kmem_cachep; + if (dst_entries_init(&ipv4_dst_ops) < 0) + panic("IP: failed to allocate ipv4_dst_ops counter\n"); + + if (dst_entries_init(&ipv4_dst_blackhole_ops) < 0) + panic("IP: failed to allocate ipv4_dst_blackhole_ops counter\n"); + rt_hash_table = (struct rt_hash_bucket *) alloc_large_system_hash("IP route cache", sizeof(struct rt_hash_bucket), diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f115ea68a4efa264c59b20f61222db97a6050a9d..1664a0590bb8f28fe5662e2cfdbc3a6d660d4549 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2392,7 +2392,12 @@ static int do_tcp_setsockopt(struct sock *sk, int level, err = tp->af_specific->md5_parse(sk, optval, optlen); break; #endif - + case TCP_USER_TIMEOUT: + /* Cap the max timeout in ms TCP will retry/retrans + * before giving up and aborting (ETIMEDOUT) a connection. + */ + icsk->icsk_user_timeout = msecs_to_jiffies(val); + break; default: err = -ENOPROTOOPT; break; @@ -2611,6 +2616,10 @@ static int do_tcp_getsockopt(struct sock *sk, int level, case TCP_THIN_DUPACK: val = tp->thin_dupack; break; + + case TCP_USER_TIMEOUT: + val = jiffies_to_msecs(icsk->icsk_user_timeout); + break; default: return -ENOPROTOOPT; } diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b55f60f6fcbe934c1364ee3aece309dff4d1be4b..ee0df48174989093e24862f61ae316d573cb1703 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -182,7 +182,7 @@ static void tcp_incr_quickack(struct sock *sk) icsk->icsk_ack.quick = min(quickacks, TCP_MAX_QUICKACKS); } -void tcp_enter_quickack_mode(struct sock *sk) +static void tcp_enter_quickack_mode(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); tcp_incr_quickack(sk); @@ -805,25 +805,12 @@ void tcp_update_metrics(struct sock *sk) } } -/* Numbers are taken from RFC3390. - * - * John Heffner states: - * - * The RFC specifies a window of no more than 4380 bytes - * unless 2*MSS > 4380. Reading the pseudocode in the RFC - * is a bit misleading because they use a clamp at 4380 bytes - * rather than use a multiplier in the relevant range. - */ __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) { __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); - if (!cwnd) { - if (tp->mss_cache > 1460) - cwnd = 2; - else - cwnd = (tp->mss_cache > 1095) ? 3 : 4; - } + if (!cwnd) + cwnd = rfc3390_bytes_to_packets(tp->mss_cache); return min_t(__u32, cwnd, tp->snd_cwnd_clamp); } @@ -2314,7 +2301,7 @@ static inline int tcp_dupack_heuristics(struct tcp_sock *tp) static inline int tcp_skb_timedout(struct sock *sk, struct sk_buff *skb) { - return (tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto); + return tcp_time_stamp - TCP_SKB_CB(skb)->when > inet_csk(sk)->icsk_rto; } static inline int tcp_head_timedout(struct sock *sk) @@ -2508,7 +2495,7 @@ static void tcp_timeout_skbs(struct sock *sk) /* Mark head of queue up as lost. With RFC3517 SACK, the packets is * is against sacked "cnt", otherwise it's against facked "cnt" */ -static void tcp_mark_head_lost(struct sock *sk, int packets) +static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; @@ -2516,13 +2503,13 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) int err; unsigned int mss; - if (packets == 0) - return; - WARN_ON(packets > tp->packets_out); if (tp->lost_skb_hint) { skb = tp->lost_skb_hint; cnt = tp->lost_cnt_hint; + /* Head already handled? */ + if (mark_head && skb != tcp_write_queue_head(sk)) + return; } else { skb = tcp_write_queue_head(sk); cnt = 0; @@ -2557,6 +2544,9 @@ static void tcp_mark_head_lost(struct sock *sk, int packets) } tcp_skb_mark_lost(tp, skb); + + if (mark_head) + break; } tcp_verify_left_out(tp); } @@ -2568,17 +2558,18 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit) struct tcp_sock *tp = tcp_sk(sk); if (tcp_is_reno(tp)) { - tcp_mark_head_lost(sk, 1); + tcp_mark_head_lost(sk, 1, 1); } else if (tcp_is_fack(tp)) { int lost = tp->fackets_out - tp->reordering; if (lost <= 0) lost = 1; - tcp_mark_head_lost(sk, lost); + tcp_mark_head_lost(sk, lost, 0); } else { int sacked_upto = tp->sacked_out - tp->reordering; - if (sacked_upto < fast_rexmit) - sacked_upto = fast_rexmit; - tcp_mark_head_lost(sk, sacked_upto); + if (sacked_upto >= 0) + tcp_mark_head_lost(sk, sacked_upto, 0); + else if (fast_rexmit) + tcp_mark_head_lost(sk, 1, 1); } tcp_timeout_skbs(sk); @@ -2887,7 +2878,7 @@ static void tcp_mtup_probe_success(struct sock *sk) icsk->icsk_mtup.probe_size; tp->snd_cwnd_cnt = 0; tp->snd_cwnd_stamp = tcp_time_stamp; - tp->rcv_ssthresh = tcp_current_ssthresh(sk); + tp->snd_ssthresh = tcp_current_ssthresh(sk); icsk->icsk_mtup.search_low = icsk->icsk_mtup.probe_size; icsk->icsk_mtup.probe_size = 0; @@ -2984,7 +2975,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag) before(tp->snd_una, tp->high_seq) && icsk->icsk_ca_state != TCP_CA_Open && tp->fackets_out > tp->reordering) { - tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering); + tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0); NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSS); } @@ -3412,8 +3403,8 @@ static void tcp_ack_probe(struct sock *sk) static inline int tcp_ack_is_dubious(const struct sock *sk, const int flag) { - return (!(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) || - inet_csk(sk)->icsk_ca_state != TCP_CA_Open); + return !(flag & FLAG_NOT_DUP) || (flag & FLAG_CA_ALERT) || + inet_csk(sk)->icsk_ca_state != TCP_CA_Open; } static inline int tcp_may_raise_cwnd(const struct sock *sk, const int flag) @@ -3430,9 +3421,9 @@ static inline int tcp_may_update_window(const struct tcp_sock *tp, const u32 ack, const u32 ack_seq, const u32 nwin) { - return (after(ack, tp->snd_una) || + return after(ack, tp->snd_una) || after(ack_seq, tp->snd_wl1) || - (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd)); + (ack_seq == tp->snd_wl1 && nwin > tp->snd_wnd); } /* Update our send window. diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 020766292bb01009201ec11e60bb0e214854414c..8f8527d4168225be9429766df1d1e2c085057868 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1422,7 +1422,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk = tcp_create_openreq_child(sk, req, skb); if (!newsk) - goto exit; + goto exit_nonewsk; newsk->sk_gso_type = SKB_GSO_TCPV4; sk_setup_caps(newsk, dst); @@ -1469,16 +1469,20 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, } #endif + if (__inet_inherit_port(sk, newsk) < 0) { + sock_put(newsk); + goto exit; + } __inet_hash_nolisten(newsk, NULL); - __inet_inherit_port(sk, newsk); return newsk; exit_overflow: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); +exit_nonewsk: + dst_release(dst); exit: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); - dst_release(dst); return NULL; } EXPORT_SYMBOL(tcp_v4_syn_recv_sock); @@ -2571,7 +2575,6 @@ struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb) return tcp_gro_receive(head, skb); } -EXPORT_SYMBOL(tcp4_gro_receive); int tcp4_gro_complete(struct sk_buff *skb) { @@ -2584,7 +2587,6 @@ int tcp4_gro_complete(struct sk_buff *skb) return tcp_gro_complete(skb); } -EXPORT_SYMBOL(tcp4_gro_complete); struct proto tcp_prot = { .name = "TCP", diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index f25b56cb85cbd1b7a743bd7348158afff332811d..43cf901d765970b6a1a80f167a80ec285a8397b6 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -55,7 +55,7 @@ static __inline__ int tcp_in_window(u32 seq, u32 end_seq, u32 s_win, u32 e_win) return 1; if (after(end_seq, s_win) && before(seq, e_win)) return 1; - return (seq == e_win && seq == end_seq); + return seq == e_win && seq == end_seq; } /* diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index de3bd84585881f99f8a23eb28fa9f380516d087c..05b1ecf367632763cbdb1f3bfe0e74c9c4d20c0c 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -224,16 +224,10 @@ void tcp_select_initial_window(int __space, __u32 mss, } } - /* Set initial window to value enough for senders, - * following RFC2414. Senders, not following this RFC, - * will be satisfied with 2. - */ + /* Set initial window to value enough for senders, following RFC5681. */ if (mss > (1 << *rcv_wscale)) { - int init_cwnd = 4; - if (mss > 1460 * 3) - init_cwnd = 2; - else if (mss > 1460) - init_cwnd = 3; + int init_cwnd = rfc3390_bytes_to_packets(mss); + /* when initializing use the value from init_rcv_wnd * rather than the default from above */ @@ -1376,9 +1370,9 @@ static inline int tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, unsigned mss_now, int nonagle) { - return (skb->len < mss_now && + return skb->len < mss_now && ((nonagle & TCP_NAGLE_CORK) || - (!nonagle && tp->packets_out && tcp_minshall_check(tp)))); + (!nonagle && tp->packets_out && tcp_minshall_check(tp))); } /* Return non-zero if the Nagle test allows this packet to be @@ -1449,10 +1443,10 @@ int tcp_may_send_now(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb = tcp_send_head(sk); - return (skb && + return skb && tcp_snd_test(sk, skb, tcp_current_mss(sk), (tcp_skb_is_last(sk, skb) ? - tp->nonagle : TCP_NAGLE_PUSH))); + tp->nonagle : TCP_NAGLE_PUSH)); } /* Trim TSO SKB to LEN bytes, put the remaining data into a new packet @@ -2429,6 +2423,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, __u8 rcv_wscale; /* Set this up on the first call only */ req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); + + /* limit the window selection if the user enforce a smaller rx buffer */ + if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && + (req->window_clamp > tcp_full_space(sk) || req->window_clamp == 0)) + req->window_clamp = tcp_full_space(sk); + /* tcp_full_space because it is guaranteed to be the first packet */ tcp_select_initial_window(tcp_full_space(sk), mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), @@ -2555,6 +2555,11 @@ static void tcp_connect_init(struct sock *sk) tcp_initialize_rcv_mss(sk); + /* limit the window selection if the user enforce a smaller rx buffer */ + if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && + (tp->window_clamp > tcp_full_space(sk) || tp->window_clamp == 0)) + tp->window_clamp = tcp_full_space(sk); + tcp_select_initial_window(tcp_full_space(sk), tp->advmss - (tp->rx_opt.ts_recent_stamp ? tp->tcp_header_len - sizeof(struct tcphdr) : 0), &tp->rcv_wnd, diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 74c54b30600f618522e07581c43130eea031f2db..74a6aa003657392d45d97f040ba6a987ee413004 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -140,10 +140,10 @@ static void tcp_mtu_probing(struct inet_connection_sock *icsk, struct sock *sk) */ static bool retransmits_timed_out(struct sock *sk, unsigned int boundary, + unsigned int timeout, bool syn_set) { - unsigned int timeout, linear_backoff_thresh; - unsigned int start_ts; + unsigned int linear_backoff_thresh, start_ts; unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN; if (!inet_csk(sk)->icsk_retransmits) @@ -154,14 +154,15 @@ static bool retransmits_timed_out(struct sock *sk, else start_ts = tcp_sk(sk)->retrans_stamp; - linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); - - if (boundary <= linear_backoff_thresh) - timeout = ((2 << boundary) - 1) * rto_base; - else - timeout = ((2 << linear_backoff_thresh) - 1) * rto_base + - (boundary - linear_backoff_thresh) * TCP_RTO_MAX; + if (likely(timeout == 0)) { + linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); + if (boundary <= linear_backoff_thresh) + timeout = ((2 << boundary) - 1) * rto_base; + else + timeout = ((2 << linear_backoff_thresh) - 1) * rto_base + + (boundary - linear_backoff_thresh) * TCP_RTO_MAX; + } return (tcp_time_stamp - start_ts) >= timeout; } @@ -178,7 +179,7 @@ static int tcp_write_timeout(struct sock *sk) retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; syn_set = 1; } else { - if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) { + if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0, 0)) { /* Black hole detection */ tcp_mtu_probing(icsk, sk); @@ -191,14 +192,15 @@ static int tcp_write_timeout(struct sock *sk) retry_until = tcp_orphan_retries(sk, alive); do_reset = alive || - !retransmits_timed_out(sk, retry_until, 0); + !retransmits_timed_out(sk, retry_until, 0, 0); if (tcp_out_of_resources(sk, do_reset)) return 1; } } - if (retransmits_timed_out(sk, retry_until, syn_set)) { + if (retransmits_timed_out(sk, retry_until, + syn_set ? 0 : icsk->icsk_user_timeout, syn_set)) { /* Has it gone just too far? */ tcp_write_err(sk); return 1; @@ -365,18 +367,19 @@ void tcp_retransmit_timer(struct sock *sk) if (icsk->icsk_retransmits == 0) { int mib_idx; - if (icsk->icsk_ca_state == TCP_CA_Disorder) { - if (tcp_is_sack(tp)) - mib_idx = LINUX_MIB_TCPSACKFAILURES; - else - mib_idx = LINUX_MIB_TCPRENOFAILURES; - } else if (icsk->icsk_ca_state == TCP_CA_Recovery) { + if (icsk->icsk_ca_state == TCP_CA_Recovery) { if (tcp_is_sack(tp)) mib_idx = LINUX_MIB_TCPSACKRECOVERYFAIL; else mib_idx = LINUX_MIB_TCPRENORECOVERYFAIL; } else if (icsk->icsk_ca_state == TCP_CA_Loss) { mib_idx = LINUX_MIB_TCPLOSSFAILURES; + } else if ((icsk->icsk_ca_state == TCP_CA_Disorder) || + tp->sacked_out) { + if (tcp_is_sack(tp)) + mib_idx = LINUX_MIB_TCPSACKFAILURES; + else + mib_idx = LINUX_MIB_TCPRENOFAILURES; } else { mib_idx = LINUX_MIB_TCPTIMEOUTS; } @@ -440,7 +443,7 @@ void tcp_retransmit_timer(struct sock *sk) icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); } inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); - if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0)) + if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0, 0)) __sk_dst_reset(sk); out:; @@ -560,7 +563,14 @@ static void tcp_keepalive_timer (unsigned long data) elapsed = keepalive_time_elapsed(tp); if (elapsed >= keepalive_time_when(tp)) { - if (icsk->icsk_probes_out >= keepalive_probes(tp)) { + /* If the TCP_USER_TIMEOUT option is enabled, use that + * to determine when to timeout instead. + */ + if ((icsk->icsk_user_timeout != 0 && + elapsed >= icsk->icsk_user_timeout && + icsk->icsk_probes_out > 0) || + (icsk->icsk_user_timeout == 0 && + icsk->icsk_probes_out >= keepalive_probes(tp))) { tcp_send_active_reset(sk, GFP_ATOMIC); tcp_write_err(sk); goto out; diff --git a/net/ipv4/tcp_westwood.c b/net/ipv4/tcp_westwood.c index 20151d6a62413e09e4cb5b95d12fdb253148af61..a534dda5456e4bbf0a4dfca5b0731dc660985ec8 100644 --- a/net/ipv4/tcp_westwood.c +++ b/net/ipv4/tcp_westwood.c @@ -80,7 +80,7 @@ static void tcp_westwood_init(struct sock *sk) */ static inline u32 westwood_do_filter(u32 a, u32 b) { - return (((7 * a) + b) >> 3); + return ((7 * a) + b) >> 3; } static void westwood_filter(struct westwood *w, u32 delta) diff --git a/net/ipv4/tunnel4.c b/net/ipv4/tunnel4.c index 59186ca7808a20fcf6eda607491bcaba60cf2263..9a17bd2a0a37fdae55aca5aff11324dfa31ac1ca 100644 --- a/net/ipv4/tunnel4.c +++ b/net/ipv4/tunnel4.c @@ -14,8 +14,8 @@ #include #include -static struct xfrm_tunnel *tunnel4_handlers; -static struct xfrm_tunnel *tunnel64_handlers; +static struct xfrm_tunnel *tunnel4_handlers __read_mostly; +static struct xfrm_tunnel *tunnel64_handlers __read_mostly; static DEFINE_MUTEX(tunnel4_mutex); static inline struct xfrm_tunnel **fam_handlers(unsigned short family) @@ -39,7 +39,7 @@ int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family) } handler->next = *pprev; - *pprev = handler; + rcu_assign_pointer(*pprev, handler); ret = 0; @@ -73,6 +73,11 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family) } EXPORT_SYMBOL(xfrm4_tunnel_deregister); +#define for_each_tunnel_rcu(head, handler) \ + for (handler = rcu_dereference(head); \ + handler != NULL; \ + handler = rcu_dereference(handler->next)) \ + static int tunnel4_rcv(struct sk_buff *skb) { struct xfrm_tunnel *handler; @@ -80,7 +85,7 @@ static int tunnel4_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto drop; - for (handler = tunnel4_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel4_handlers, handler) if (!handler->handler(skb)) return 0; @@ -99,7 +104,7 @@ static int tunnel64_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto drop; - for (handler = tunnel64_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel64_handlers, handler) if (!handler->handler(skb)) return 0; @@ -115,7 +120,7 @@ static void tunnel4_err(struct sk_buff *skb, u32 info) { struct xfrm_tunnel *handler; - for (handler = tunnel4_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel4_handlers, handler) if (!handler->err_handler(skb, info)) break; } @@ -125,7 +130,7 @@ static void tunnel64_err(struct sk_buff *skb, u32 info) { struct xfrm_tunnel *handler; - for (handler = tunnel64_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel64_handlers, handler) if (!handler->err_handler(skb, info)) break; } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index fb23c2e63b5281a7ca505af3ac94f411e10c4ee6..b3f7e8cf18ac4227d298c7d4d659a7d19c50a244 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -797,7 +797,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, return -EOPNOTSUPP; ipc.opt = NULL; - ipc.shtx.flags = 0; + ipc.tx_flags = 0; if (up->pending) { /* @@ -845,7 +845,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, ipc.addr = inet->inet_saddr; ipc.oif = sk->sk_bound_dev_if; - err = sock_tx_timestamp(msg, sk, &ipc.shtx); + err = sock_tx_timestamp(sk, &ipc.tx_flags); if (err) return err; if (msg->msg_controllen) { diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index a580349f0b8ab53c77b04b00d504de0bf1f83e09..4464f3bff6a7a7d902b72806bb9d5e7c1752bf96 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -174,7 +174,7 @@ static inline int xfrm4_garbage_collect(struct dst_ops *ops) struct net *net = container_of(ops, struct net, xfrm.xfrm4_dst_ops); xfrm4_policy_afinfo.garbage_collect(net); - return (atomic_read(&ops->entries) > ops->gc_thresh * 2); + return (dst_entries_get_slow(ops) > ops->gc_thresh * 2); } static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) @@ -232,7 +232,6 @@ static struct dst_ops xfrm4_dst_ops = { .ifdown = xfrm4_dst_ifdown, .local_out = __ip_local_out, .gc_thresh = 1024, - .entries = ATOMIC_INIT(0), }; static struct xfrm_policy_afinfo xfrm4_policy_afinfo = { @@ -288,6 +287,7 @@ void __init xfrm4_init(int rt_max_size) * and start cleaning when were 1/2 full */ xfrm4_dst_ops.gc_thresh = rt_max_size/2; + dst_entries_init(&xfrm4_dst_ops); xfrm4_state_init(); xfrm4_policy_init(); diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index 41f5982d20876ecb7ab1df92f5533d451b932ee2..82806455e8598862d1e925ff24a05403e8cd6519 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c @@ -58,14 +58,14 @@ static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) return -ENOENT; } -static struct xfrm_tunnel xfrm_tunnel_handler = { +static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = { .handler = xfrm_tunnel_rcv, .err_handler = xfrm_tunnel_err, .priority = 2, }; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -static struct xfrm_tunnel xfrm64_tunnel_handler = { +static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = { .handler = xfrm_tunnel_rcv, .err_handler = xfrm_tunnel_err, .priority = 2, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 324fac3b6c16db0238d1139649038bcaa9aaced2..ec7a91d9e86553475555b9df19d22ced2dc5eb31 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -243,7 +243,7 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev) /* Check if a route is valid prefix route */ static inline int addrconf_is_prefix_route(const struct rt6_info *rt) { - return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0); + return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0; } static void addrconf_del_timer(struct inet6_ifaddr *ifp) @@ -1544,7 +1544,7 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev) return 0; } -int __ipv6_isatap_ifid(u8 *eui, __be32 addr) +static int __ipv6_isatap_ifid(u8 *eui, __be32 addr) { if (addr == 0) return -1; @@ -1560,7 +1560,6 @@ int __ipv6_isatap_ifid(u8 *eui, __be32 addr) memcpy(eui + 4, &addr, 4); return 0; } -EXPORT_SYMBOL(__ipv6_isatap_ifid); static int addrconf_ifid_sit(u8 *eui, struct net_device *dev) { @@ -2964,7 +2963,8 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) start sending router solicitations. */ - if (ifp->idev->cnf.forwarding == 0 && + if ((ifp->idev->cnf.forwarding == 0 || + ifp->idev->cnf.forwarding == 2) && ifp->idev->cnf.rtr_solicits > 0 && (dev->flags&IFF_LOOPBACK) == 0 && (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 8175f802651bec4481080823a73f60a21d3a2f36..c8993e5a337c25dd2dbe85f182a137dd82386c5d 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c @@ -518,10 +518,9 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb) static inline int ip6addrlbl_msgsize(void) { - return (NLMSG_ALIGN(sizeof(struct ifaddrlblmsg)) + return NLMSG_ALIGN(sizeof(struct ifaddrlblmsg)) + nla_total_size(16) /* IFAL_ADDRESS */ - + nla_total_size(4) /* IFAL_LABEL */ - ); + + nla_total_size(4); /* IFAL_LABEL */ } static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 56b9bf2516f4d45b5b866e1e3086f54a05a7b530..54e8e42f7a88ad675aae5fb4782d6ce36d9a4ba9 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -343,7 +343,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) */ v4addr = LOOPBACK4_IPV6; if (!(addr_type & IPV6_ADDR_MULTICAST)) { - if (!ipv6_chk_addr(net, &addr->sin6_addr, + if (!inet->transparent && + !ipv6_chk_addr(net, &addr->sin6_addr, dev, 0)) { err = -EADDRNOTAVAIL; goto out_unlock; @@ -467,7 +468,7 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr, if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) sin->sin6_scope_id = sk->sk_bound_dev_if; *uaddr_len = sizeof(*sin); - return(0); + return 0; } EXPORT_SYMBOL(inet6_getname); @@ -488,7 +489,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case SIOCADDRT: case SIOCDELRT: - return(ipv6_route_ioctl(net, cmd, (void __user *)arg)); + return ipv6_route_ioctl(net, cmd, (void __user *)arg); case SIOCSIFADDR: return addrconf_add_ifaddr(net, (void __user *) arg); @@ -502,7 +503,7 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) return sk->sk_prot->ioctl(sk, cmd, arg); } /*NOTREACHED*/ - return(0); + return 0; } EXPORT_SYMBOL(inet6_ioctl); diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index ef371aa01ac50724f9dff9cbf7d084e062d844c9..320bdb877eed2ff61da25c6c9a1ac2f6cc00baac 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -577,6 +577,25 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) u8 *ptr = nh + opt->dst1; put_cmsg(msg, SOL_IPV6, IPV6_2292DSTOPTS, (ptr[1]+1)<<3, ptr); } + if (np->rxopt.bits.rxorigdstaddr) { + struct sockaddr_in6 sin6; + u16 *ports = (u16 *) skb_transport_header(skb); + + if (skb_transport_offset(skb) + 4 <= skb->len) { + /* All current transport protocols have the port numbers in the + * first four bytes of the transport header and this function is + * written with this assumption in mind. + */ + + sin6.sin6_family = AF_INET6; + ipv6_addr_copy(&sin6.sin6_addr, &ipv6_hdr(skb)->daddr); + sin6.sin6_port = ports[1]; + sin6.sin6_flowinfo = 0; + sin6.sin6_scope_id = 0; + + put_cmsg(msg, SOL_IPV6, IPV6_ORIGDSTADDR, sizeof(sin6), &sin6); + } + } return 0; } diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index e1caa5d526c2537bf610f29e4fabaa94eccb111a..14ed0a955b563e08a03dfbd010733c3f6c6d36a7 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c @@ -13,12 +13,12 @@ int ipv6_ext_hdr(u8 nexthdr) /* * find out if nexthdr is an extension header or a protocol */ - return ( (nexthdr == NEXTHDR_HOP) || + return (nexthdr == NEXTHDR_HOP) || (nexthdr == NEXTHDR_ROUTING) || (nexthdr == NEXTHDR_FRAGMENT) || (nexthdr == NEXTHDR_AUTH) || (nexthdr == NEXTHDR_NONE) || - (nexthdr == NEXTHDR_DEST) ); + (nexthdr == NEXTHDR_DEST); } /* diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index b1108ede18e1c4cec4eea90f9741441add7047fb..d829874d8946e75e6735fd8df4c0ad6facf58bc0 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c @@ -34,11 +34,10 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, { struct fib_lookup_arg arg = { .lookup_ptr = lookup, + .flags = FIB_LOOKUP_NOREF, }; fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg); - if (arg.rule) - fib_rule_put(arg.rule); if (arg.result) return arg.result; diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index b6a585909d3560d0f9c0396fe8ed4b136c0ef5f6..de382114609b7de8d0cbf5c5447a18d4f5a89a2d 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1500,15 +1500,18 @@ static void fib6_gc_timer_cb(unsigned long arg) static int __net_init fib6_net_init(struct net *net) { + size_t size = sizeof(struct hlist_head) * FIB6_TABLE_HASHSZ; + setup_timer(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, (unsigned long)net); net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); if (!net->ipv6.rt6_stats) goto out_timer; - net->ipv6.fib_table_hash = kcalloc(FIB6_TABLE_HASHSZ, - sizeof(*net->ipv6.fib_table_hash), - GFP_KERNEL); + /* Avoid false sharing : Use at least a full cache line */ + size = max_t(size_t, size, L1_CACHE_BYTES); + + net->ipv6.fib_table_hash = kzalloc(size, GFP_KERNEL); if (!net->ipv6.fib_table_hash) goto out_rt6_stats; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 980912ed7a388bd2404b8cb934b2b61e67e12a6c..99157b4cd56e2fa619939a17aa5b716680fc8799 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -637,7 +637,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) } mtu -= hlen + sizeof(struct frag_hdr); - if (skb_has_frags(skb)) { + if (skb_has_frag_list(skb)) { int first_len = skb_pagelen(skb); struct sk_buff *frag2; @@ -878,8 +878,8 @@ static inline int ip6_rt_check(struct rt6key *rt_key, struct in6_addr *fl_addr, struct in6_addr *addr_cache) { - return ((rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) && - (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache))); + return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) && + (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache)); } static struct dst_entry *ip6_sk_dst_check(struct sock *sk, diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 0fd027f3f47e170608d75ea735a74f535838b80a..c2c0f89397b1164bacefdb449cd2b97dbe41d66c 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -75,7 +75,7 @@ MODULE_LICENSE("GPL"); (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ (HASH_SIZE - 1)) -static void ip6_tnl_dev_init(struct net_device *dev); +static int ip6_tnl_dev_init(struct net_device *dev); static void ip6_tnl_dev_setup(struct net_device *dev); static int ip6_tnl_net_id __read_mostly; @@ -83,15 +83,42 @@ struct ip6_tnl_net { /* the IPv6 tunnel fallback device */ struct net_device *fb_tnl_dev; /* lists for storing tunnels in use */ - struct ip6_tnl *tnls_r_l[HASH_SIZE]; - struct ip6_tnl *tnls_wc[1]; - struct ip6_tnl **tnls[2]; + struct ip6_tnl __rcu *tnls_r_l[HASH_SIZE]; + struct ip6_tnl __rcu *tnls_wc[1]; + struct ip6_tnl __rcu **tnls[2]; }; +/* often modified stats are per cpu, other are shared (netdev->stats) */ +struct pcpu_tstats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +static struct net_device_stats *ip6_get_stats(struct net_device *dev) +{ + struct pcpu_tstats sum = { 0 }; + int i; + + for_each_possible_cpu(i) { + const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); + + sum.rx_packets += tstats->rx_packets; + sum.rx_bytes += tstats->rx_bytes; + sum.tx_packets += tstats->tx_packets; + sum.tx_bytes += tstats->tx_bytes; + } + dev->stats.rx_packets = sum.rx_packets; + dev->stats.rx_bytes = sum.rx_bytes; + dev->stats.tx_packets = sum.tx_packets; + dev->stats.tx_bytes = sum.tx_bytes; + return &dev->stats; +} + /* - * Locking : hash tables are protected by RCU and a spinlock + * Locking : hash tables are protected by RCU and RTNL */ -static DEFINE_SPINLOCK(ip6_tnl_lock); static inline struct dst_entry *ip6_tnl_dst_check(struct ip6_tnl *t) { @@ -138,8 +165,8 @@ static inline void ip6_tnl_dst_store(struct ip6_tnl *t, struct dst_entry *dst) static struct ip6_tnl * ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local) { - unsigned h0 = HASH(remote); - unsigned h1 = HASH(local); + unsigned int h0 = HASH(remote); + unsigned int h1 = HASH(local); struct ip6_tnl *t; struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); @@ -167,7 +194,7 @@ ip6_tnl_lookup(struct net *net, struct in6_addr *remote, struct in6_addr *local) * Return: head of IPv6 tunnel list **/ -static struct ip6_tnl ** +static struct ip6_tnl __rcu ** ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p) { struct in6_addr *remote = &p->raddr; @@ -190,12 +217,10 @@ ip6_tnl_bucket(struct ip6_tnl_net *ip6n, struct ip6_tnl_parm *p) static void ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) { - struct ip6_tnl **tp = ip6_tnl_bucket(ip6n, &t->parms); + struct ip6_tnl __rcu **tp = ip6_tnl_bucket(ip6n, &t->parms); - spin_lock_bh(&ip6_tnl_lock); - t->next = *tp; + rcu_assign_pointer(t->next , rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); - spin_unlock_bh(&ip6_tnl_lock); } /** @@ -206,18 +231,25 @@ ip6_tnl_link(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) static void ip6_tnl_unlink(struct ip6_tnl_net *ip6n, struct ip6_tnl *t) { - struct ip6_tnl **tp; - - for (tp = ip6_tnl_bucket(ip6n, &t->parms); *tp; tp = &(*tp)->next) { - if (t == *tp) { - spin_lock_bh(&ip6_tnl_lock); - *tp = t->next; - spin_unlock_bh(&ip6_tnl_lock); + struct ip6_tnl __rcu **tp; + struct ip6_tnl *iter; + + for (tp = ip6_tnl_bucket(ip6n, &t->parms); + (iter = rtnl_dereference(*tp)) != NULL; + tp = &iter->next) { + if (t == iter) { + rcu_assign_pointer(*tp, t->next); break; } } } +static void ip6_dev_free(struct net_device *dev) +{ + free_percpu(dev->tstats); + free_netdev(dev); +} + /** * ip6_tnl_create() - create a new tunnel * @p: tunnel parameters @@ -256,7 +288,9 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) t = netdev_priv(dev); t->parms = *p; - ip6_tnl_dev_init(dev); + err = ip6_tnl_dev_init(dev); + if (err < 0) + goto failed_free; if ((err = register_netdevice(dev)) < 0) goto failed_free; @@ -266,7 +300,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct ip6_tnl_parm *p) return t; failed_free: - free_netdev(dev); + ip6_dev_free(dev); failed: return NULL; } @@ -290,10 +324,13 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net, { struct in6_addr *remote = &p->raddr; struct in6_addr *local = &p->laddr; + struct ip6_tnl __rcu **tp; struct ip6_tnl *t; struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - for (t = *ip6_tnl_bucket(ip6n, p); t; t = t->next) { + for (tp = ip6_tnl_bucket(ip6n, p); + (t = rtnl_dereference(*tp)) != NULL; + tp = &t->next) { if (ipv6_addr_equal(local, &t->parms.laddr) && ipv6_addr_equal(remote, &t->parms.raddr)) return t; @@ -318,13 +355,10 @@ ip6_tnl_dev_uninit(struct net_device *dev) struct net *net = dev_net(dev); struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); - if (dev == ip6n->fb_tnl_dev) { - spin_lock_bh(&ip6_tnl_lock); - ip6n->tnls_wc[0] = NULL; - spin_unlock_bh(&ip6_tnl_lock); - } else { + if (dev == ip6n->fb_tnl_dev) + rcu_assign_pointer(ip6n->tnls_wc[0], NULL); + else ip6_tnl_unlink(ip6n, t); - } ip6_tnl_dst_reset(t); dev_put(dev); } @@ -702,6 +736,8 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, if ((t = ip6_tnl_lookup(dev_net(skb->dev), &ipv6h->saddr, &ipv6h->daddr)) != NULL) { + struct pcpu_tstats *tstats; + if (t->parms.proto != ipproto && t->parms.proto != 0) { rcu_read_unlock(); goto discard; @@ -724,10 +760,16 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol, skb->pkt_type = PACKET_HOST; memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); - skb_tunnel_rx(skb, t->dev); + tstats = this_cpu_ptr(t->dev->tstats); + tstats->rx_packets++; + tstats->rx_bytes += skb->len; + + __skb_tunnel_rx(skb, t->dev); dscp_ecn_decapsulate(t, ipv6h, skb); + netif_rx(skb); + rcu_read_unlock(); return 0; } @@ -934,8 +976,10 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, err = ip6_local_out(skb); if (net_xmit_eval(err) == 0) { - stats->tx_bytes += pkt_len; - stats->tx_packets++; + struct pcpu_tstats *tstats = this_cpu_ptr(t->dev->tstats); + + tstats->tx_bytes += pkt_len; + tstats->tx_packets++; } else { stats->tx_errors++; stats->tx_aborted_errors++; @@ -1300,12 +1344,14 @@ ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) static const struct net_device_ops ip6_tnl_netdev_ops = { - .ndo_uninit = ip6_tnl_dev_uninit, + .ndo_uninit = ip6_tnl_dev_uninit, .ndo_start_xmit = ip6_tnl_xmit, - .ndo_do_ioctl = ip6_tnl_ioctl, + .ndo_do_ioctl = ip6_tnl_ioctl, .ndo_change_mtu = ip6_tnl_change_mtu, + .ndo_get_stats = ip6_get_stats, }; + /** * ip6_tnl_dev_setup - setup virtual tunnel device * @dev: virtual device associated with tunnel @@ -1317,7 +1363,7 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { static void ip6_tnl_dev_setup(struct net_device *dev) { dev->netdev_ops = &ip6_tnl_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ip6_dev_free; dev->type = ARPHRD_TUNNEL6; dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); @@ -1333,12 +1379,17 @@ static void ip6_tnl_dev_setup(struct net_device *dev) * @dev: virtual device associated with tunnel **/ -static inline void +static inline int ip6_tnl_dev_init_gen(struct net_device *dev) { struct ip6_tnl *t = netdev_priv(dev); + t->dev = dev; strcpy(t->parms.name, dev->name); + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + return 0; } /** @@ -1346,11 +1397,15 @@ ip6_tnl_dev_init_gen(struct net_device *dev) * @dev: virtual device associated with tunnel **/ -static void ip6_tnl_dev_init(struct net_device *dev) +static int ip6_tnl_dev_init(struct net_device *dev) { struct ip6_tnl *t = netdev_priv(dev); - ip6_tnl_dev_init_gen(dev); + int err = ip6_tnl_dev_init_gen(dev); + + if (err) + return err; ip6_tnl_link_config(t); + return 0; } /** @@ -1360,25 +1415,29 @@ static void ip6_tnl_dev_init(struct net_device *dev) * Return: 0 **/ -static void __net_init ip6_fb_tnl_dev_init(struct net_device *dev) +static int __net_init ip6_fb_tnl_dev_init(struct net_device *dev) { struct ip6_tnl *t = netdev_priv(dev); struct net *net = dev_net(dev); struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); + int err = ip6_tnl_dev_init_gen(dev); + + if (err) + return err; - ip6_tnl_dev_init_gen(dev); t->parms.proto = IPPROTO_IPV6; dev_hold(dev); - ip6n->tnls_wc[0] = t; + rcu_assign_pointer(ip6n->tnls_wc[0], t); + return 0; } -static struct xfrm6_tunnel ip4ip6_handler = { +static struct xfrm6_tunnel ip4ip6_handler __read_mostly = { .handler = ip4ip6_rcv, .err_handler = ip4ip6_err, .priority = 1, }; -static struct xfrm6_tunnel ip6ip6_handler = { +static struct xfrm6_tunnel ip6ip6_handler __read_mostly = { .handler = ip6ip6_rcv, .err_handler = ip6ip6_err, .priority = 1, @@ -1391,14 +1450,14 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n) LIST_HEAD(list); for (h = 0; h < HASH_SIZE; h++) { - t = ip6n->tnls_r_l[h]; + t = rtnl_dereference(ip6n->tnls_r_l[h]); while (t != NULL) { unregister_netdevice_queue(t->dev, &list); - t = t->next; + t = rtnl_dereference(t->next); } } - t = ip6n->tnls_wc[0]; + t = rtnl_dereference(ip6n->tnls_wc[0]); unregister_netdevice_queue(t->dev, &list); unregister_netdevice_many(&list); } @@ -1419,7 +1478,9 @@ static int __net_init ip6_tnl_init_net(struct net *net) goto err_alloc_dev; dev_net_set(ip6n->fb_tnl_dev, net); - ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); + err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev); + if (err < 0) + goto err_register; err = register_netdev(ip6n->fb_tnl_dev); if (err < 0) @@ -1427,7 +1488,7 @@ static int __net_init ip6_tnl_init_net(struct net *net) return 0; err_register: - free_netdev(ip6n->fb_tnl_dev); + ip6_dev_free(ip6n->fb_tnl_dev); err_alloc_dev: return err; } diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 66078dad7fe8c353bd4de83115dc4eee73ba978f..6f32ffce7022c198e4c78c9126c3df90026697c2 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -667,6 +667,7 @@ static int pim6_rcv(struct sk_buff *skb) skb_tunnel_rx(skb, reg_dev); netif_rx(skb); + dev_put(reg_dev); return 0; drop: diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index a7f66bc8f0b0ef2a8b0eee454c1e103344eda417..0553867a317f4466b31df3bd6d2695e180537be9 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -342,6 +342,21 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, retv = 0; break; + case IPV6_TRANSPARENT: + if (optlen < sizeof(int)) + goto e_inval; + /* we don't have a separate transparent bit for IPV6 we use the one in the IPv4 socket */ + inet_sk(sk)->transparent = valbool; + retv = 0; + break; + + case IPV6_RECVORIGDSTADDR: + if (optlen < sizeof(int)) + goto e_inval; + np->rxopt.bits.rxorigdstaddr = valbool; + retv = 0; + break; + case IPV6_HOPOPTS: case IPV6_RTHDRDSTOPTS: case IPV6_RTHDR: @@ -1104,6 +1119,14 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, break; } + case IPV6_TRANSPARENT: + val = inet_sk(sk)->transparent; + break; + + case IPV6_RECVORIGDSTADDR: + val = np->rxopt.bits.rxorigdstaddr; + break; + case IPV6_UNICAST_HOPS: case IPV6_MULTICAST_HOPS: { diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 58841c4ae947f982d3377009066ed636fa37ea75..998d6d27e7cf293383b7c4e944899790170ba690 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -91,7 +91,9 @@ #include #include -static u32 ndisc_hash(const void *pkey, const struct net_device *dev); +static u32 ndisc_hash(const void *pkey, + const struct net_device *dev, + __u32 rnd); static int ndisc_constructor(struct neighbour *neigh); static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb); static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb); @@ -228,12 +230,12 @@ static struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, do { cur = ((void *)cur) + (cur->nd_opt_len << 3); } while(cur < end && cur->nd_opt_type != type); - return (cur <= end && cur->nd_opt_type == type ? cur : NULL); + return cur <= end && cur->nd_opt_type == type ? cur : NULL; } static inline int ndisc_is_useropt(struct nd_opt_hdr *opt) { - return (opt->nd_opt_type == ND_OPT_RDNSS); + return opt->nd_opt_type == ND_OPT_RDNSS; } static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur, @@ -244,7 +246,7 @@ static struct nd_opt_hdr *ndisc_next_useropt(struct nd_opt_hdr *cur, do { cur = ((void *)cur) + (cur->nd_opt_len << 3); } while(cur < end && !ndisc_is_useropt(cur)); - return (cur <= end && ndisc_is_useropt(cur) ? cur : NULL); + return cur <= end && ndisc_is_useropt(cur) ? cur : NULL; } static struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, @@ -319,7 +321,7 @@ static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p, int prepad = ndisc_addr_option_pad(dev->type); if (lladdrlen != NDISC_OPT_SPACE(dev->addr_len + prepad)) return NULL; - return (lladdr + prepad); + return lladdr + prepad; } int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir) @@ -350,7 +352,9 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d EXPORT_SYMBOL(ndisc_mc_map); -static u32 ndisc_hash(const void *pkey, const struct net_device *dev) +static u32 ndisc_hash(const void *pkey, + const struct net_device *dev, + __u32 hash_rnd) { const u32 *p32 = pkey; u32 addr_hash, i; @@ -359,7 +363,7 @@ static u32 ndisc_hash(const void *pkey, const struct net_device *dev) for (i = 0; i < (sizeof(struct in6_addr) / sizeof(u32)); i++) addr_hash ^= *p32++; - return jhash_2words(addr_hash, dev->ifindex, nd_tbl.hash_rnd); + return jhash_2words(addr_hash, dev->ifindex, hash_rnd); } static int ndisc_constructor(struct neighbour *neigh) @@ -1105,6 +1109,18 @@ static void ndisc_ra_useropt(struct sk_buff *ra, struct nd_opt_hdr *opt) rtnl_set_sk_err(net, RTNLGRP_ND_USEROPT, err); } +static inline int accept_ra(struct inet6_dev *in6_dev) +{ + /* + * If forwarding is enabled, RA are not accepted unless the special + * hybrid mode (accept_ra=2) is enabled. + */ + if (in6_dev->cnf.forwarding && in6_dev->cnf.accept_ra < 2) + return 0; + + return in6_dev->cnf.accept_ra; +} + static void ndisc_router_discovery(struct sk_buff *skb) { struct ra_msg *ra_msg = (struct ra_msg *)skb_transport_header(skb); @@ -1158,8 +1174,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) return; } - /* skip route and link configuration on routers */ - if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) + if (!accept_ra(in6_dev)) goto skip_linkparms; #ifdef CONFIG_IPV6_NDISC_NODETYPE @@ -1309,8 +1324,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) NEIGH_UPDATE_F_ISROUTER); } - /* skip route and link configuration on routers */ - if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) + if (!accept_ra(in6_dev)) goto out; #ifdef CONFIG_IPV6_ROUTE_INFO diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 29d643bcafa4b38be01c7ff40cb65760f8c9af17..44d2eeac089b4fedc3a65c312263b667231838dc 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig @@ -132,10 +132,10 @@ config IP6_NF_MATCH_RT # The targets config IP6_NF_TARGET_HL tristate '"HL" hoplimit target support' - depends on NETFILTER_ADVANCED + depends on NETFILTER_ADVANCED && IP6_NF_MANGLE select NETFILTER_XT_TARGET_HL ---help--- - This is a backwards-compat option for the user's convenience + This is a backwards-compatible option for the user's convenience (e.g. when running oldconfig). It selects CONFIG_NETFILTER_XT_TARGET_HL. diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index aafbba30c899fac569184a5ef9943f13ecfdb3b9..3f8e4a3d83ce107bdf2280c35fac189f8a2a2838 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile @@ -11,10 +11,11 @@ obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o # objects for l3 independent conntrack -nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o nf_conntrack_reasm.o +nf_conntrack_ipv6-objs := nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o +nf_defrag_ipv6-objs := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o # l3 independent conntrack -obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o +obj-$(CONFIG_NF_CONNTRACK_IPV6) += nf_conntrack_ipv6.o nf_defrag_ipv6.o # matches obj-$(CONFIG_IP6_NF_MATCH_AH) += ip6t_ah.o diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 8e754be92c2450e7142a958466b493dc077f5772..51df035897e77dfa5b89e6328817cfcb638702cb 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -82,13 +82,13 @@ EXPORT_SYMBOL_GPL(ip6t_alloc_initial_table); int ip6t_ext_hdr(u8 nexthdr) { - return ( (nexthdr == IPPROTO_HOPOPTS) || - (nexthdr == IPPROTO_ROUTING) || - (nexthdr == IPPROTO_FRAGMENT) || - (nexthdr == IPPROTO_ESP) || - (nexthdr == IPPROTO_AH) || - (nexthdr == IPPROTO_NONE) || - (nexthdr == IPPROTO_DSTOPTS) ); + return (nexthdr == IPPROTO_HOPOPTS) || + (nexthdr == IPPROTO_ROUTING) || + (nexthdr == IPPROTO_FRAGMENT) || + (nexthdr == IPPROTO_ESP) || + (nexthdr == IPPROTO_AH) || + (nexthdr == IPPROTO_NONE) || + (nexthdr == IPPROTO_DSTOPTS); } /* Returns whether matches rule or not. */ @@ -215,7 +215,7 @@ static inline bool unconditional(const struct ip6t_ip6 *ipv6) return memcmp(ipv6, &uncond, sizeof(uncond)) == 0; } -static inline const struct ip6t_entry_target * +static inline const struct xt_entry_target * ip6t_get_target_c(const struct ip6t_entry *e) { return ip6t_get_target((struct ip6t_entry *)e); @@ -260,9 +260,9 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, const char *hookname, const char **chainname, const char **comment, unsigned int *rulenum) { - const struct ip6t_standard_target *t = (void *)ip6t_get_target_c(s); + const struct xt_standard_target *t = (void *)ip6t_get_target_c(s); - if (strcmp(t->target.u.kernel.target->name, IP6T_ERROR_TARGET) == 0) { + if (strcmp(t->target.u.kernel.target->name, XT_ERROR_TARGET) == 0) { /* Head of user chain: ERROR target with chainname */ *chainname = t->target.data; (*rulenum) = 0; @@ -271,7 +271,7 @@ get_chainname_rulenum(const struct ip6t_entry *s, const struct ip6t_entry *e, if (s->target_offset == sizeof(struct ip6t_entry) && strcmp(t->target.u.kernel.target->name, - IP6T_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && t->verdict < 0 && unconditional(&s->ipv6)) { /* Tail of chains: STANDARD target (return/policy) */ @@ -369,7 +369,7 @@ ip6t_do_table(struct sk_buff *skb, e = get_entry(table_base, private->hook_entry[hook]); do { - const struct ip6t_entry_target *t; + const struct xt_entry_target *t; const struct xt_entry_match *ematch; IP_NF_ASSERT(e); @@ -403,10 +403,10 @@ ip6t_do_table(struct sk_buff *skb, if (!t->u.kernel.target->target) { int v; - v = ((struct ip6t_standard_target *)t)->verdict; + v = ((struct xt_standard_target *)t)->verdict; if (v < 0) { /* Pop from stack? */ - if (v != IP6T_RETURN) { + if (v != XT_RETURN) { verdict = (unsigned)(-v) - 1; break; } @@ -434,7 +434,7 @@ ip6t_do_table(struct sk_buff *skb, acpar.targinfo = t->data; verdict = t->u.kernel.target->target(skb, &acpar); - if (verdict == IP6T_CONTINUE) + if (verdict == XT_CONTINUE) e = ip6t_next_entry(e); else /* Verdict */ @@ -474,7 +474,7 @@ mark_source_chains(const struct xt_table_info *newinfo, e->counters.pcnt = pos; for (;;) { - const struct ip6t_standard_target *t + const struct xt_standard_target *t = (void *)ip6t_get_target_c(e); int visited = e->comefrom & (1 << hook); @@ -488,13 +488,13 @@ mark_source_chains(const struct xt_table_info *newinfo, /* Unconditional return/END. */ if ((e->target_offset == sizeof(struct ip6t_entry) && (strcmp(t->target.u.user.name, - IP6T_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < 0 && unconditional(&e->ipv6)) || visited) { unsigned int oldpos, size; if ((strcmp(t->target.u.user.name, - IP6T_STANDARD_TARGET) == 0) && + XT_STANDARD_TARGET) == 0) && t->verdict < -NF_MAX_VERDICT - 1) { duprintf("mark_source_chains: bad " "negative verdict (%i)\n", @@ -537,7 +537,7 @@ mark_source_chains(const struct xt_table_info *newinfo, int newpos = t->verdict; if (strcmp(t->target.u.user.name, - IP6T_STANDARD_TARGET) == 0 && + XT_STANDARD_TARGET) == 0 && newpos >= 0) { if (newpos > newinfo->size - sizeof(struct ip6t_entry)) { @@ -565,7 +565,7 @@ mark_source_chains(const struct xt_table_info *newinfo, return 1; } -static void cleanup_match(struct ip6t_entry_match *m, struct net *net) +static void cleanup_match(struct xt_entry_match *m, struct net *net) { struct xt_mtdtor_param par; @@ -581,14 +581,14 @@ static void cleanup_match(struct ip6t_entry_match *m, struct net *net) static int check_entry(const struct ip6t_entry *e, const char *name) { - const struct ip6t_entry_target *t; + const struct xt_entry_target *t; if (!ip6_checkentry(&e->ipv6)) { duprintf("ip_tables: ip check failed %p %s.\n", e, name); return -EINVAL; } - if (e->target_offset + sizeof(struct ip6t_entry_target) > + if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset) return -EINVAL; @@ -599,7 +599,7 @@ check_entry(const struct ip6t_entry *e, const char *name) return 0; } -static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) +static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { const struct ip6t_ip6 *ipv6 = par->entryinfo; int ret; @@ -618,7 +618,7 @@ static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) } static int -find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) +find_check_match(struct xt_entry_match *m, struct xt_mtchk_param *par) { struct xt_match *match; int ret; @@ -643,7 +643,7 @@ find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) static int check_target(struct ip6t_entry *e, struct net *net, const char *name) { - struct ip6t_entry_target *t = ip6t_get_target(e); + struct xt_entry_target *t = ip6t_get_target(e); struct xt_tgchk_param par = { .net = net, .table = name, @@ -670,7 +670,7 @@ static int find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, unsigned int size) { - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; int ret; unsigned int j; @@ -721,7 +721,7 @@ find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, static bool check_underflow(const struct ip6t_entry *e) { - const struct ip6t_entry_target *t; + const struct xt_entry_target *t; unsigned int verdict; if (!unconditional(&e->ipv6)) @@ -729,7 +729,7 @@ static bool check_underflow(const struct ip6t_entry *e) t = ip6t_get_target_c(e); if (strcmp(t->u.user.name, XT_STANDARD_TARGET) != 0) return false; - verdict = ((struct ip6t_standard_target *)t)->verdict; + verdict = ((struct xt_standard_target *)t)->verdict; verdict = -verdict - 1; return verdict == NF_DROP || verdict == NF_ACCEPT; } @@ -752,7 +752,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, } if (e->next_offset - < sizeof(struct ip6t_entry) + sizeof(struct ip6t_entry_target)) { + < sizeof(struct ip6t_entry) + sizeof(struct xt_entry_target)) { duprintf("checking: element %p size %u\n", e, e->next_offset); return -EINVAL; @@ -784,7 +784,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e, static void cleanup_entry(struct ip6t_entry *e, struct net *net) { struct xt_tgdtor_param par; - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_entry_match *ematch; /* Cleanup all matches */ @@ -985,8 +985,8 @@ copy_entries_to_user(unsigned int total_size, /* ... then go back and fix counters and names */ for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ unsigned int i; - const struct ip6t_entry_match *m; - const struct ip6t_entry_target *t; + const struct xt_entry_match *m; + const struct xt_entry_target *t; e = (struct ip6t_entry *)(loc_cpu_entry + off); if (copy_to_user(userptr + off @@ -1003,7 +1003,7 @@ copy_entries_to_user(unsigned int total_size, m = (void *)e + i; if (copy_to_user(userptr + off + i - + offsetof(struct ip6t_entry_match, + + offsetof(struct xt_entry_match, u.user.name), m->u.kernel.match->name, strlen(m->u.kernel.match->name)+1) @@ -1015,7 +1015,7 @@ copy_entries_to_user(unsigned int total_size, t = ip6t_get_target_c(e); if (copy_to_user(userptr + off + e->target_offset - + offsetof(struct ip6t_entry_target, + + offsetof(struct xt_entry_target, u.user.name), t->u.kernel.target->name, strlen(t->u.kernel.target->name)+1) != 0) { @@ -1053,7 +1053,7 @@ static int compat_calc_entry(const struct ip6t_entry *e, const void *base, struct xt_table_info *newinfo) { const struct xt_entry_match *ematch; - const struct ip6t_entry_target *t; + const struct xt_entry_target *t; unsigned int entry_offset; int off, i, ret; @@ -1105,7 +1105,7 @@ static int compat_table_info(const struct xt_table_info *info, static int get_info(struct net *net, void __user *user, const int *len, int compat) { - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; struct xt_table *t; int ret; @@ -1118,7 +1118,7 @@ static int get_info(struct net *net, void __user *user, if (copy_from_user(name, user, sizeof(name)) != 0) return -EFAULT; - name[IP6T_TABLE_MAXNAMELEN-1] = '\0'; + name[XT_TABLE_MAXNAMELEN-1] = '\0'; #ifdef CONFIG_COMPAT if (compat) xt_compat_lock(AF_INET6); @@ -1415,14 +1415,14 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len, #ifdef CONFIG_COMPAT struct compat_ip6t_replace { - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; u32 valid_hooks; u32 num_entries; u32 size; u32 hook_entry[NF_INET_NUMHOOKS]; u32 underflow[NF_INET_NUMHOOKS]; u32 num_counters; - compat_uptr_t counters; /* struct ip6t_counters * */ + compat_uptr_t counters; /* struct xt_counters * */ struct compat_ip6t_entry entries[0]; }; @@ -1431,7 +1431,7 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, unsigned int *size, struct xt_counters *counters, unsigned int i) { - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct compat_ip6t_entry __user *ce; u_int16_t target_offset, next_offset; compat_uint_t origsize; @@ -1466,7 +1466,7 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, } static int -compat_find_calc_match(struct ip6t_entry_match *m, +compat_find_calc_match(struct xt_entry_match *m, const char *name, const struct ip6t_ip6 *ipv6, unsigned int hookmask, @@ -1488,7 +1488,7 @@ compat_find_calc_match(struct ip6t_entry_match *m, static void compat_release_entry(struct compat_ip6t_entry *e) { - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_entry_match *ematch; /* Cleanup all matches */ @@ -1509,7 +1509,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e, const char *name) { struct xt_entry_match *ematch; - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; unsigned int entry_offset; unsigned int j; @@ -1591,7 +1591,7 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr, unsigned int *size, const char *name, struct xt_table_info *newinfo, unsigned char *base) { - struct ip6t_entry_target *t; + struct xt_entry_target *t; struct xt_target *target; struct ip6t_entry *de; unsigned int origsize; @@ -1899,7 +1899,7 @@ compat_do_ip6t_set_ctl(struct sock *sk, int cmd, void __user *user, } struct compat_ip6t_get_entries { - char name[IP6T_TABLE_MAXNAMELEN]; + char name[XT_TABLE_MAXNAMELEN]; compat_uint_t size; struct compat_ip6t_entry entrytable[0]; }; @@ -2054,7 +2054,7 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) case IP6T_SO_GET_REVISION_MATCH: case IP6T_SO_GET_REVISION_TARGET: { - struct ip6t_get_revision rev; + struct xt_get_revision rev; int target; if (*len != sizeof(rev)) { @@ -2191,7 +2191,7 @@ static int icmp6_checkentry(const struct xt_mtchk_param *par) /* The built-in targets: standard (NULL) and error. */ static struct xt_target ip6t_builtin_tg[] __read_mostly = { { - .name = IP6T_STANDARD_TARGET, + .name = XT_STANDARD_TARGET, .targetsize = sizeof(int), .family = NFPROTO_IPV6, #ifdef CONFIG_COMPAT @@ -2201,9 +2201,9 @@ static struct xt_target ip6t_builtin_tg[] __read_mostly = { #endif }, { - .name = IP6T_ERROR_TARGET, + .name = XT_ERROR_TARGET, .target = ip6t_error, - .targetsize = IP6T_FUNCTION_MAXNAMELEN, + .targetsize = XT_FUNCTION_MAXNAMELEN, .family = NFPROTO_IPV6, }, }; diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c index 0a07ae7b933f2fbbac6fbf8cf9741d8bea6882e6..09c88891a753e725d8594edc68941b293d171100 100644 --- a/net/ipv6/netfilter/ip6t_LOG.c +++ b/net/ipv6/netfilter/ip6t_LOG.c @@ -23,6 +23,7 @@ #include #include #include +#include MODULE_AUTHOR("Jan Rekorajski "); MODULE_DESCRIPTION("Xtables: IPv6 packet logging to syslog"); @@ -32,11 +33,9 @@ struct in_device; #include #include -/* Use lock to serialize, so printks don't overlap */ -static DEFINE_SPINLOCK(log_lock); - /* One level of recursion won't kill us */ -static void dump_packet(const struct nf_loginfo *info, +static void dump_packet(struct sbuff *m, + const struct nf_loginfo *info, const struct sk_buff *skb, unsigned int ip6hoff, int recurse) { @@ -55,15 +54,15 @@ static void dump_packet(const struct nf_loginfo *info, ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h); if (ih == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */ - printk("SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr); + sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr); /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ - printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", + sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", ntohs(ih->payload_len) + sizeof(struct ipv6hdr), (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20, ih->hop_limit, @@ -78,35 +77,35 @@ static void dump_packet(const struct nf_loginfo *info, hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); if (hp == NULL) { - printk("TRUNCATED"); + sb_add(m, "TRUNCATED"); return; } /* Max length: 48 "OPT (...) " */ if (logflags & IP6T_LOG_IPOPT) - printk("OPT ( "); + sb_add(m, "OPT ( "); switch (currenthdr) { case IPPROTO_FRAGMENT: { struct frag_hdr _fhdr; const struct frag_hdr *fh; - printk("FRAG:"); + sb_add(m, "FRAG:"); fh = skb_header_pointer(skb, ptr, sizeof(_fhdr), &_fhdr); if (fh == NULL) { - printk("TRUNCATED "); + sb_add(m, "TRUNCATED "); return; } /* Max length: 6 "65535 " */ - printk("%u ", ntohs(fh->frag_off) & 0xFFF8); + sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8); /* Max length: 11 "INCOMPLETE " */ if (fh->frag_off & htons(0x0001)) - printk("INCOMPLETE "); + sb_add(m, "INCOMPLETE "); - printk("ID:%08x ", ntohl(fh->identification)); + sb_add(m, "ID:%08x ", ntohl(fh->identification)); if (ntohs(fh->frag_off) & 0xFFF8) fragment = 1; @@ -120,7 +119,7 @@ static void dump_packet(const struct nf_loginfo *info, case IPPROTO_HOPOPTS: if (fragment) { if (logflags & IP6T_LOG_IPOPT) - printk(")"); + sb_add(m, ")"); return; } hdrlen = ipv6_optlen(hp); @@ -132,10 +131,10 @@ static void dump_packet(const struct nf_loginfo *info, const struct ip_auth_hdr *ah; /* Max length: 3 "AH " */ - printk("AH "); + sb_add(m, "AH "); if (fragment) { - printk(")"); + sb_add(m, ")"); return; } @@ -146,13 +145,13 @@ static void dump_packet(const struct nf_loginfo *info, * Max length: 26 "INCOMPLETE [65535 * bytes] )" */ - printk("INCOMPLETE [%u bytes] )", + sb_add(m, "INCOMPLETE [%u bytes] )", skb->len - ptr); return; } /* Length: 15 "SPI=0xF1234567 */ - printk("SPI=0x%x ", ntohl(ah->spi)); + sb_add(m, "SPI=0x%x ", ntohl(ah->spi)); } @@ -164,10 +163,10 @@ static void dump_packet(const struct nf_loginfo *info, const struct ip_esp_hdr *eh; /* Max length: 4 "ESP " */ - printk("ESP "); + sb_add(m, "ESP "); if (fragment) { - printk(")"); + sb_add(m, ")"); return; } @@ -177,23 +176,23 @@ static void dump_packet(const struct nf_loginfo *info, eh = skb_header_pointer(skb, ptr, sizeof(_esph), &_esph); if (eh == NULL) { - printk("INCOMPLETE [%u bytes] )", + sb_add(m, "INCOMPLETE [%u bytes] )", skb->len - ptr); return; } /* Length: 16 "SPI=0xF1234567 )" */ - printk("SPI=0x%x )", ntohl(eh->spi) ); + sb_add(m, "SPI=0x%x )", ntohl(eh->spi) ); } return; default: /* Max length: 20 "Unknown Ext Hdr 255" */ - printk("Unknown Ext Hdr %u", currenthdr); + sb_add(m, "Unknown Ext Hdr %u", currenthdr); return; } if (logflags & IP6T_LOG_IPOPT) - printk(") "); + sb_add(m, ") "); currenthdr = hp->nexthdr; ptr += hdrlen; @@ -205,7 +204,7 @@ static void dump_packet(const struct nf_loginfo *info, const struct tcphdr *th; /* Max length: 10 "PROTO=TCP " */ - printk("PROTO=TCP "); + sb_add(m, "PROTO=TCP "); if (fragment) break; @@ -213,40 +212,40 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 25 "INCOMPLETE [65535 bytes] " */ th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph); if (th == NULL) { - printk("INCOMPLETE [%u bytes] ", skb->len - ptr); + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr); return; } /* Max length: 20 "SPT=65535 DPT=65535 " */ - printk("SPT=%u DPT=%u ", + sb_add(m, "SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest)); /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */ if (logflags & IP6T_LOG_TCPSEQ) - printk("SEQ=%u ACK=%u ", + sb_add(m, "SEQ=%u ACK=%u ", ntohl(th->seq), ntohl(th->ack_seq)); /* Max length: 13 "WINDOW=65535 " */ - printk("WINDOW=%u ", ntohs(th->window)); + sb_add(m, "WINDOW=%u ", ntohs(th->window)); /* Max length: 9 "RES=0x3C " */ - printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); + sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22)); /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */ if (th->cwr) - printk("CWR "); + sb_add(m, "CWR "); if (th->ece) - printk("ECE "); + sb_add(m, "ECE "); if (th->urg) - printk("URG "); + sb_add(m, "URG "); if (th->ack) - printk("ACK "); + sb_add(m, "ACK "); if (th->psh) - printk("PSH "); + sb_add(m, "PSH "); if (th->rst) - printk("RST "); + sb_add(m, "RST "); if (th->syn) - printk("SYN "); + sb_add(m, "SYN "); if (th->fin) - printk("FIN "); + sb_add(m, "FIN "); /* Max length: 11 "URGP=65535 " */ - printk("URGP=%u ", ntohs(th->urg_ptr)); + sb_add(m, "URGP=%u ", ntohs(th->urg_ptr)); if ((logflags & IP6T_LOG_TCPOPT) && th->doff * 4 > sizeof(struct tcphdr)) { @@ -260,15 +259,15 @@ static void dump_packet(const struct nf_loginfo *info, ptr + sizeof(struct tcphdr), optsize, _opt); if (op == NULL) { - printk("OPT (TRUNCATED)"); + sb_add(m, "OPT (TRUNCATED)"); return; } /* Max length: 127 "OPT (" 15*4*2chars ") " */ - printk("OPT ("); + sb_add(m, "OPT ("); for (i =0; i < optsize; i++) - printk("%02X", op[i]); - printk(") "); + sb_add(m, "%02X", op[i]); + sb_add(m, ") "); } break; } @@ -279,9 +278,9 @@ static void dump_packet(const struct nf_loginfo *info, if (currenthdr == IPPROTO_UDP) /* Max length: 10 "PROTO=UDP " */ - printk("PROTO=UDP " ); + sb_add(m, "PROTO=UDP " ); else /* Max length: 14 "PROTO=UDPLITE " */ - printk("PROTO=UDPLITE "); + sb_add(m, "PROTO=UDPLITE "); if (fragment) break; @@ -289,12 +288,12 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 25 "INCOMPLETE [65535 bytes] " */ uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph); if (uh == NULL) { - printk("INCOMPLETE [%u bytes] ", skb->len - ptr); + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr); return; } /* Max length: 20 "SPT=65535 DPT=65535 " */ - printk("SPT=%u DPT=%u LEN=%u ", + sb_add(m, "SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest), ntohs(uh->len)); break; @@ -304,7 +303,7 @@ static void dump_packet(const struct nf_loginfo *info, const struct icmp6hdr *ic; /* Max length: 13 "PROTO=ICMPv6 " */ - printk("PROTO=ICMPv6 "); + sb_add(m, "PROTO=ICMPv6 "); if (fragment) break; @@ -312,18 +311,18 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 25 "INCOMPLETE [65535 bytes] " */ ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h); if (ic == NULL) { - printk("INCOMPLETE [%u bytes] ", skb->len - ptr); + sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr); return; } /* Max length: 18 "TYPE=255 CODE=255 " */ - printk("TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code); + sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code); switch (ic->icmp6_type) { case ICMPV6_ECHO_REQUEST: case ICMPV6_ECHO_REPLY: /* Max length: 19 "ID=65535 SEQ=65535 " */ - printk("ID=%u SEQ=%u ", + sb_add(m, "ID=%u SEQ=%u ", ntohs(ic->icmp6_identifier), ntohs(ic->icmp6_sequence)); break; @@ -334,35 +333,35 @@ static void dump_packet(const struct nf_loginfo *info, case ICMPV6_PARAMPROB: /* Max length: 17 "POINTER=ffffffff " */ - printk("POINTER=%08x ", ntohl(ic->icmp6_pointer)); + sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer)); /* Fall through */ case ICMPV6_DEST_UNREACH: case ICMPV6_PKT_TOOBIG: case ICMPV6_TIME_EXCEED: /* Max length: 3+maxlen */ if (recurse) { - printk("["); - dump_packet(info, skb, ptr + sizeof(_icmp6h), - 0); - printk("] "); + sb_add(m, "["); + dump_packet(m, info, skb, + ptr + sizeof(_icmp6h), 0); + sb_add(m, "] "); } /* Max length: 10 "MTU=65535 " */ if (ic->icmp6_type == ICMPV6_PKT_TOOBIG) - printk("MTU=%u ", ntohl(ic->icmp6_mtu)); + sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu)); } break; } /* Max length: 10 "PROTO=255 " */ default: - printk("PROTO=%u ", currenthdr); + sb_add(m, "PROTO=%u ", currenthdr); } /* Max length: 15 "UID=4294967295 " */ if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) { read_lock_bh(&skb->sk->sk_callback_lock); if (skb->sk->sk_socket && skb->sk->sk_socket->file) - printk("UID=%u GID=%u ", + sb_add(m, "UID=%u GID=%u ", skb->sk->sk_socket->file->f_cred->fsuid, skb->sk->sk_socket->file->f_cred->fsgid); read_unlock_bh(&skb->sk->sk_callback_lock); @@ -370,10 +369,11 @@ static void dump_packet(const struct nf_loginfo *info, /* Max length: 16 "MARK=0xFFFFFFFF " */ if (!recurse && skb->mark) - printk("MARK=0x%x ", skb->mark); + sb_add(m, "MARK=0x%x ", skb->mark); } -static void dump_mac_header(const struct nf_loginfo *info, +static void dump_mac_header(struct sbuff *m, + const struct nf_loginfo *info, const struct sk_buff *skb) { struct net_device *dev = skb->dev; @@ -387,7 +387,7 @@ static void dump_mac_header(const struct nf_loginfo *info, switch (dev->type) { case ARPHRD_ETHER: - printk("MACSRC=%pM MACDST=%pM MACPROTO=%04x ", + sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ", eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest, ntohs(eth_hdr(skb)->h_proto)); return; @@ -396,7 +396,7 @@ static void dump_mac_header(const struct nf_loginfo *info, } fallback: - printk("MAC="); + sb_add(m, "MAC="); if (dev->hard_header_len && skb->mac_header != skb->network_header) { const unsigned char *p = skb_mac_header(skb); @@ -408,19 +408,19 @@ static void dump_mac_header(const struct nf_loginfo *info, p = NULL; if (p != NULL) { - printk("%02x", *p++); + sb_add(m, "%02x", *p++); for (i = 1; i < len; i++) - printk(":%02x", p[i]); + sb_add(m, ":%02x", p[i]); } - printk(" "); + sb_add(m, " "); if (dev->type == ARPHRD_SIT) { const struct iphdr *iph = (struct iphdr *)skb_mac_header(skb); - printk("TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr); + sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr); } } else - printk(" "); + sb_add(m, " "); } static struct nf_loginfo default_loginfo = { @@ -442,22 +442,23 @@ ip6t_log_packet(u_int8_t pf, const struct nf_loginfo *loginfo, const char *prefix) { + struct sbuff *m = sb_open(); + if (!loginfo) loginfo = &default_loginfo; - spin_lock_bh(&log_lock); - printk("<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, - prefix, - in ? in->name : "", - out ? out->name : ""); + sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level, + prefix, + in ? in->name : "", + out ? out->name : ""); /* MAC logging for input path only. */ if (in && !out) - dump_mac_header(loginfo, skb); + dump_mac_header(m, loginfo, skb); + + dump_packet(m, loginfo, skb, skb_network_offset(skb), 1); - dump_packet(loginfo, skb, skb_network_offset(skb), 1); - printk("\n"); - spin_unlock_bh(&log_lock); + sb_close(m); } static unsigned int diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index ff43461704be5c9433d7468f1fe99c63aab7d613..c8af58b225620795af240156ae1e5b735fa78a2d 100644 --- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include #include static bool ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, @@ -189,53 +189,6 @@ static unsigned int ipv6_confirm(unsigned int hooknum, return nf_conntrack_confirm(skb); } -static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, - struct sk_buff *skb) -{ - u16 zone = NF_CT_DEFAULT_ZONE; - - if (skb->nfct) - zone = nf_ct_zone((struct nf_conn *)skb->nfct); - -#ifdef CONFIG_BRIDGE_NETFILTER - if (skb->nf_bridge && - skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) - return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; -#endif - if (hooknum == NF_INET_PRE_ROUTING) - return IP6_DEFRAG_CONNTRACK_IN + zone; - else - return IP6_DEFRAG_CONNTRACK_OUT + zone; - -} - -static unsigned int ipv6_defrag(unsigned int hooknum, - struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) -{ - struct sk_buff *reasm; - - /* Previously seen (loopback)? */ - if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) - return NF_ACCEPT; - - reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); - /* queued */ - if (reasm == NULL) - return NF_STOLEN; - - /* error occured or not fragmented */ - if (reasm == skb) - return NF_ACCEPT; - - nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in, - (struct net_device *)out, okfn); - - return NF_STOLEN; -} - static unsigned int __ipv6_conntrack_in(struct net *net, unsigned int hooknum, struct sk_buff *skb, @@ -287,13 +240,6 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum, } static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { - { - .hook = ipv6_defrag, - .owner = THIS_MODULE, - .pf = NFPROTO_IPV6, - .hooknum = NF_INET_PRE_ROUTING, - .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, - }, { .hook = ipv6_conntrack_in, .owner = THIS_MODULE, @@ -308,13 +254,6 @@ static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { .hooknum = NF_INET_LOCAL_OUT, .priority = NF_IP6_PRI_CONNTRACK, }, - { - .hook = ipv6_defrag, - .owner = THIS_MODULE, - .pf = NFPROTO_IPV6, - .hooknum = NF_INET_LOCAL_OUT, - .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, - }, { .hook = ipv6_confirm, .owner = THIS_MODULE, @@ -386,10 +325,6 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 __read_mostly = { .nlattr_tuple_size = ipv6_nlattr_tuple_size, .nlattr_to_tuple = ipv6_nlattr_to_tuple, .nla_policy = ipv6_nla_policy, -#endif -#ifdef CONFIG_SYSCTL - .ctl_table_path = nf_net_netfilter_sysctl_path, - .ctl_table = nf_ct_ipv6_sysctl_table, #endif .me = THIS_MODULE, }; @@ -403,16 +338,12 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) int ret = 0; need_conntrack(); + nf_defrag_ipv6_enable(); - ret = nf_ct_frag6_init(); - if (ret < 0) { - pr_err("nf_conntrack_ipv6: can't initialize frag6.\n"); - return ret; - } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6); if (ret < 0) { pr_err("nf_conntrack_ipv6: can't register tcp.\n"); - goto cleanup_frag6; + return ret; } ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6); @@ -450,8 +381,6 @@ static int __init nf_conntrack_l3proto_ipv6_init(void) nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); cleanup_tcp: nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); - cleanup_frag6: - nf_ct_frag6_cleanup(); return ret; } @@ -463,7 +392,6 @@ static void __exit nf_conntrack_l3proto_ipv6_fini(void) nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6); nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6); - nf_ct_frag6_cleanup(); } module_init(nf_conntrack_l3proto_ipv6_init); diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 578f3c1a16db614614f986947cbae5a7960fcdb5..489d71b844ac9ba7c85d7f5612922e4ceeb712cc 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -73,7 +73,7 @@ static struct inet_frags nf_frags; static struct netns_frags nf_init_frags; #ifdef CONFIG_SYSCTL -struct ctl_table nf_ct_ipv6_sysctl_table[] = { +struct ctl_table nf_ct_frag6_sysctl_table[] = { { .procname = "nf_conntrack_frag6_timeout", .data = &nf_init_frags.timeout, @@ -97,6 +97,8 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = { }, { } }; + +static struct ctl_table_header *nf_ct_frag6_sysctl_header; #endif static unsigned int nf_hashfn(struct inet_frag_queue *q) @@ -363,7 +365,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_has_frag_list(head)) { struct sk_buff *clone; int i, plen = 0; @@ -623,11 +625,21 @@ int nf_ct_frag6_init(void) inet_frags_init_net(&nf_init_frags); inet_frags_init(&nf_frags); + nf_ct_frag6_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, + nf_ct_frag6_sysctl_table); + if (!nf_ct_frag6_sysctl_header) { + inet_frags_fini(&nf_frags); + return -ENOMEM; + } + return 0; } void nf_ct_frag6_cleanup(void) { + unregister_sysctl_table(nf_ct_frag6_sysctl_header); + nf_ct_frag6_sysctl_header = NULL; + inet_frags_fini(&nf_frags); nf_init_frags.low_thresh = 0; diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c new file mode 100644 index 0000000000000000000000000000000000000000..99abfb53bab91def61a8d7cdeaf2ee64ed8aa8f6 --- /dev/null +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c @@ -0,0 +1,131 @@ +/* (C) 1999-2001 Paul `Rusty' Russell + * (C) 2002-2004 Netfilter Core Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, + struct sk_buff *skb) +{ + u16 zone = NF_CT_DEFAULT_ZONE; + + if (skb->nfct) + zone = nf_ct_zone((struct nf_conn *)skb->nfct); + +#ifdef CONFIG_BRIDGE_NETFILTER + if (skb->nf_bridge && + skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING) + return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone; +#endif + if (hooknum == NF_INET_PRE_ROUTING) + return IP6_DEFRAG_CONNTRACK_IN + zone; + else + return IP6_DEFRAG_CONNTRACK_OUT + zone; + +} + +static unsigned int ipv6_defrag(unsigned int hooknum, + struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + struct sk_buff *reasm; + + /* Previously seen (loopback)? */ + if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) + return NF_ACCEPT; + + reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb)); + /* queued */ + if (reasm == NULL) + return NF_STOLEN; + + /* error occured or not fragmented */ + if (reasm == skb) + return NF_ACCEPT; + + nf_ct_frag6_output(hooknum, reasm, (struct net_device *)in, + (struct net_device *)out, okfn); + + return NF_STOLEN; +} + +static struct nf_hook_ops ipv6_defrag_ops[] = { + { + .hook = ipv6_defrag, + .owner = THIS_MODULE, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_PRE_ROUTING, + .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, + }, + { + .hook = ipv6_defrag, + .owner = THIS_MODULE, + .pf = NFPROTO_IPV6, + .hooknum = NF_INET_LOCAL_OUT, + .priority = NF_IP6_PRI_CONNTRACK_DEFRAG, + }, +}; + +static int __init nf_defrag_init(void) +{ + int ret = 0; + + ret = nf_ct_frag6_init(); + if (ret < 0) { + pr_err("nf_defrag_ipv6: can't initialize frag6.\n"); + return ret; + } + ret = nf_register_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops)); + if (ret < 0) { + pr_err("nf_defrag_ipv6: can't register hooks\n"); + goto cleanup_frag6; + } + return ret; + +cleanup_frag6: + nf_ct_frag6_cleanup(); + return ret; + +} + +static void __exit nf_defrag_fini(void) +{ + nf_unregister_hooks(ipv6_defrag_ops, ARRAY_SIZE(ipv6_defrag_ops)); + nf_ct_frag6_cleanup(); +} + +void nf_defrag_ipv6_enable(void) +{ +} +EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable); + +module_init(nf_defrag_init); +module_exit(nf_defrag_fini); + +MODULE_LICENSE("GPL"); diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 1fa3468f0f323782413c1931258c61aa9130f450..9bb936ae24524362fd5748b42360b2955dc474a9 100644 --- a/net/ipv6/protocol.c +++ b/net/ipv6/protocol.c @@ -25,28 +25,14 @@ #include #include -const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; -static DEFINE_SPINLOCK(inet6_proto_lock); - +const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS] __read_mostly; int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) { - int ret, hash = protocol & (MAX_INET_PROTOS - 1); - - spin_lock_bh(&inet6_proto_lock); - - if (inet6_protos[hash]) { - ret = -1; - } else { - inet6_protos[hash] = prot; - ret = 0; - } - - spin_unlock_bh(&inet6_proto_lock); + int hash = protocol & (MAX_INET_PROTOS - 1); - return ret; + return !cmpxchg(&inet6_protos[hash], NULL, prot) ? 0 : -1; } - EXPORT_SYMBOL(inet6_add_protocol); /* @@ -57,20 +43,10 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol { int ret, hash = protocol & (MAX_INET_PROTOS - 1); - spin_lock_bh(&inet6_proto_lock); - - if (inet6_protos[hash] != prot) { - ret = -1; - } else { - inet6_protos[hash] = NULL; - ret = 0; - } - - spin_unlock_bh(&inet6_proto_lock); + ret = (cmpxchg(&inet6_protos[hash], prot, NULL) == prot) ? 0 : -1; synchronize_net(); return ret; } - EXPORT_SYMBOL(inet6_del_protocol); diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index e677937a07fc2e4e4a28cd6b3ac044a808d3d355..45e6efb7f17120554bb963d983d74028a2001342 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c @@ -764,7 +764,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, return -EINVAL; if (sin6->sin6_family && sin6->sin6_family != AF_INET6) - return(-EAFNOSUPPORT); + return -EAFNOSUPPORT; /* port is the proto value [0..255] carried in nexthdr */ proto = ntohs(sin6->sin6_port); @@ -772,10 +772,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, if (!proto) proto = inet->inet_num; else if (proto != inet->inet_num) - return(-EINVAL); + return -EINVAL; if (proto > 255) - return(-EINVAL); + return -EINVAL; daddr = &sin6->sin6_addr; if (np->sndflow) { @@ -985,7 +985,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, /* You may get strange result with a positive odd offset; RFC2292bis agrees with me. */ if (val > 0 && (val&1)) - return(-EINVAL); + return -EINVAL; if (val < 0) { rp->checksum = 0; } else { @@ -997,7 +997,7 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname, break; default: - return(-ENOPROTOOPT); + return -ENOPROTOOPT; } } @@ -1190,7 +1190,7 @@ static int rawv6_init_sk(struct sock *sk) default: break; } - return(0); + return 0; } struct proto rawv6_prot = { diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index 64cfef1b0a4c556ccf63c2f912c86ec3a1599b82..c7ba3149633fcf79160849498d87ae5e53f695b1 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c @@ -458,7 +458,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev, /* If the first fragment is fragmented itself, we split * it to two chunks: the first with data and paged part * and the second, holding only fragments. */ - if (skb_has_frags(head)) { + if (skb_has_frag_list(head)) { struct sk_buff *clone; int i, plen = 0; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a275c6e1e25c23884d7d1859e46a2ee82c00acef..25661f968f3fb2c2976575f4233fd03c42edb863 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -109,7 +109,6 @@ static struct dst_ops ip6_dst_ops_template = { .link_failure = ip6_link_failure, .update_pmtu = ip6_rt_update_pmtu, .local_out = __ip6_local_out, - .entries = ATOMIC_INIT(0), }; static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) @@ -122,7 +121,6 @@ static struct dst_ops ip6_dst_blackhole_ops = { .destroy = ip6_dst_destroy, .check = ip6_dst_check, .update_pmtu = ip6_rt_blackhole_update_pmtu, - .entries = ATOMIC_INIT(0), }; static struct rt6_info ip6_null_entry_template = { @@ -217,14 +215,14 @@ static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, static __inline__ int rt6_check_expired(const struct rt6_info *rt) { - return (rt->rt6i_flags & RTF_EXPIRES && - time_after(jiffies, rt->rt6i_expires)); + return (rt->rt6i_flags & RTF_EXPIRES) && + time_after(jiffies, rt->rt6i_expires); } static inline int rt6_need_strict(struct in6_addr *daddr) { - return (ipv6_addr_type(daddr) & - (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK)); + return ipv6_addr_type(daddr) & + (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK); } /* @@ -440,7 +438,7 @@ static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) __func__, match); net = dev_net(rt0->rt6i_dev); - return (match ? match : net->ipv6.ip6_null_entry); + return match ? match : net->ipv6.ip6_null_entry; } #ifdef CONFIG_IPV6_ROUTE_INFO @@ -859,7 +857,7 @@ int ip6_dst_blackhole(struct sock *sk, struct dst_entry **dstp, struct flowi *fl dst_release(*dstp); *dstp = new; - return (new ? 0 : -ENOMEM); + return new ? 0 : -ENOMEM; } EXPORT_SYMBOL_GPL(ip6_dst_blackhole); @@ -1058,19 +1056,22 @@ static int ip6_dst_gc(struct dst_ops *ops) int rt_elasticity = net->ipv6.sysctl.ip6_rt_gc_elasticity; int rt_gc_timeout = net->ipv6.sysctl.ip6_rt_gc_timeout; unsigned long rt_last_gc = net->ipv6.ip6_rt_last_gc; + int entries; + entries = dst_entries_get_fast(ops); if (time_after(rt_last_gc + rt_min_interval, now) && - atomic_read(&ops->entries) <= rt_max_size) + entries <= rt_max_size) goto out; net->ipv6.ip6_rt_gc_expire++; fib6_run_gc(net->ipv6.ip6_rt_gc_expire, net); net->ipv6.ip6_rt_last_gc = now; - if (atomic_read(&ops->entries) < ops->gc_thresh) + entries = dst_entries_get_slow(ops); + if (entries < ops->gc_thresh) net->ipv6.ip6_rt_gc_expire = rt_gc_timeout>>1; out: net->ipv6.ip6_rt_gc_expire -= net->ipv6.ip6_rt_gc_expire>>rt_elasticity; - return (atomic_read(&ops->entries) > rt_max_size); + return entries > rt_max_size; } /* Clean host part of a prefix. Not necessary in radix tree, @@ -1169,6 +1170,8 @@ int ip6_route_add(struct fib6_config *cfg) if (addr_type & IPV6_ADDR_MULTICAST) rt->dst.input = ip6_mc_input; + else if (cfg->fc_flags & RTF_LOCAL) + rt->dst.input = ip6_input; else rt->dst.input = ip6_forward; @@ -1190,7 +1193,8 @@ int ip6_route_add(struct fib6_config *cfg) they would result in kernel looping; promote them to reject routes */ if ((cfg->fc_flags & RTF_REJECT) || - (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { + (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK) + && !(cfg->fc_flags&RTF_LOCAL))) { /* hold loopback dev/idev if we haven't done so. */ if (dev != net->loopback_dev) { if (dev) { @@ -2102,6 +2106,9 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, if (rtm->rtm_type == RTN_UNREACHABLE) cfg->fc_flags |= RTF_REJECT; + if (rtm->rtm_type == RTN_LOCAL) + cfg->fc_flags |= RTF_LOCAL; + cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; cfg->fc_nlinfo.nlh = nlh; cfg->fc_nlinfo.nl_net = sock_net(skb->sk); @@ -2222,6 +2229,8 @@ static int rt6_fill_node(struct net *net, NLA_PUT_U32(skb, RTA_TABLE, table); if (rt->rt6i_flags&RTF_REJECT) rtm->rtm_type = RTN_UNREACHABLE; + else if (rt->rt6i_flags&RTF_LOCAL) + rtm->rtm_type = RTN_LOCAL; else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) rtm->rtm_type = RTN_LOCAL; else @@ -2516,7 +2525,7 @@ static int rt6_stats_seq_show(struct seq_file *seq, void *v) net->ipv6.rt6_stats->fib_rt_alloc, net->ipv6.rt6_stats->fib_rt_entries, net->ipv6.rt6_stats->fib_rt_cache, - atomic_read(&net->ipv6.ip6_dst_ops.entries), + dst_entries_get_slow(&net->ipv6.ip6_dst_ops), net->ipv6.rt6_stats->fib_discarded_routes); return 0; @@ -2658,11 +2667,14 @@ static int __net_init ip6_route_net_init(struct net *net) memcpy(&net->ipv6.ip6_dst_ops, &ip6_dst_ops_template, sizeof(net->ipv6.ip6_dst_ops)); + if (dst_entries_init(&net->ipv6.ip6_dst_ops) < 0) + goto out_ip6_dst_ops; + net->ipv6.ip6_null_entry = kmemdup(&ip6_null_entry_template, sizeof(*net->ipv6.ip6_null_entry), GFP_KERNEL); if (!net->ipv6.ip6_null_entry) - goto out_ip6_dst_ops; + goto out_ip6_dst_entries; net->ipv6.ip6_null_entry->dst.path = (struct dst_entry *)net->ipv6.ip6_null_entry; net->ipv6.ip6_null_entry->dst.ops = &net->ipv6.ip6_dst_ops; @@ -2712,6 +2724,8 @@ static int __net_init ip6_route_net_init(struct net *net) out_ip6_null_entry: kfree(net->ipv6.ip6_null_entry); #endif +out_ip6_dst_entries: + dst_entries_destroy(&net->ipv6.ip6_dst_ops); out_ip6_dst_ops: goto out; } @@ -2750,10 +2764,14 @@ int __init ip6_route_init(void) if (!ip6_dst_ops_template.kmem_cachep) goto out; - ret = register_pernet_subsys(&ip6_route_net_ops); + ret = dst_entries_init(&ip6_dst_blackhole_ops); if (ret) goto out_kmem_cache; + ret = register_pernet_subsys(&ip6_route_net_ops); + if (ret) + goto out_dst_entries; + ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep; /* Registering of the loopback is done before this portion of code, @@ -2800,6 +2818,8 @@ int __init ip6_route_init(void) fib6_gc_cleanup(); out_register_subsys: unregister_pernet_subsys(&ip6_route_net_ops); +out_dst_entries: + dst_entries_destroy(&ip6_dst_blackhole_ops); out_kmem_cache: kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); goto out; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 4699cd3c3118ffefb90d4f1e587683aedddcc866..367a6cc584ccc40bb1c5a7fc03022bd89f304d10 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -63,36 +63,63 @@ #define HASH_SIZE 16 #define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF) -static void ipip6_tunnel_init(struct net_device *dev); +static int ipip6_tunnel_init(struct net_device *dev); static void ipip6_tunnel_setup(struct net_device *dev); +static void ipip6_dev_free(struct net_device *dev); static int sit_net_id __read_mostly; struct sit_net { - struct ip_tunnel *tunnels_r_l[HASH_SIZE]; - struct ip_tunnel *tunnels_r[HASH_SIZE]; - struct ip_tunnel *tunnels_l[HASH_SIZE]; - struct ip_tunnel *tunnels_wc[1]; - struct ip_tunnel **tunnels[4]; + struct ip_tunnel __rcu *tunnels_r_l[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_r[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_l[HASH_SIZE]; + struct ip_tunnel __rcu *tunnels_wc[1]; + struct ip_tunnel __rcu **tunnels[4]; struct net_device *fb_tunnel_dev; }; /* - * Locking : hash tables are protected by RCU and a spinlock + * Locking : hash tables are protected by RCU and RTNL */ -static DEFINE_SPINLOCK(ipip6_lock); #define for_each_ip_tunnel_rcu(start) \ for (t = rcu_dereference(start); t; t = rcu_dereference(t->next)) +/* often modified stats are per cpu, other are shared (netdev->stats) */ +struct pcpu_tstats { + unsigned long rx_packets; + unsigned long rx_bytes; + unsigned long tx_packets; + unsigned long tx_bytes; +}; + +static struct net_device_stats *ipip6_get_stats(struct net_device *dev) +{ + struct pcpu_tstats sum = { 0 }; + int i; + + for_each_possible_cpu(i) { + const struct pcpu_tstats *tstats = per_cpu_ptr(dev->tstats, i); + + sum.rx_packets += tstats->rx_packets; + sum.rx_bytes += tstats->rx_bytes; + sum.tx_packets += tstats->tx_packets; + sum.tx_bytes += tstats->tx_bytes; + } + dev->stats.rx_packets = sum.rx_packets; + dev->stats.rx_bytes = sum.rx_bytes; + dev->stats.tx_packets = sum.tx_packets; + dev->stats.tx_bytes = sum.tx_bytes; + return &dev->stats; +} /* * Must be invoked with rcu_read_lock */ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, struct net_device *dev, __be32 remote, __be32 local) { - unsigned h0 = HASH(remote); - unsigned h1 = HASH(local); + unsigned int h0 = HASH(remote); + unsigned int h1 = HASH(local); struct ip_tunnel *t; struct sit_net *sitn = net_generic(net, sit_net_id); @@ -121,12 +148,12 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net, return NULL; } -static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn, +static struct ip_tunnel __rcu **__ipip6_bucket(struct sit_net *sitn, struct ip_tunnel_parm *parms) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; - unsigned h = 0; + unsigned int h = 0; int prio = 0; if (remote) { @@ -140,7 +167,7 @@ static struct ip_tunnel **__ipip6_bucket(struct sit_net *sitn, return &sitn->tunnels[prio][h]; } -static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn, +static inline struct ip_tunnel __rcu **ipip6_bucket(struct sit_net *sitn, struct ip_tunnel *t) { return __ipip6_bucket(sitn, &t->parms); @@ -148,13 +175,14 @@ static inline struct ip_tunnel **ipip6_bucket(struct sit_net *sitn, static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t) { - struct ip_tunnel **tp; - - for (tp = ipip6_bucket(sitn, t); *tp; tp = &(*tp)->next) { - if (t == *tp) { - spin_lock_bh(&ipip6_lock); - *tp = t->next; - spin_unlock_bh(&ipip6_lock); + struct ip_tunnel __rcu **tp; + struct ip_tunnel *iter; + + for (tp = ipip6_bucket(sitn, t); + (iter = rtnl_dereference(*tp)) != NULL; + tp = &iter->next) { + if (t == iter) { + rcu_assign_pointer(*tp, t->next); break; } } @@ -162,12 +190,10 @@ static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t) static void ipip6_tunnel_link(struct sit_net *sitn, struct ip_tunnel *t) { - struct ip_tunnel **tp = ipip6_bucket(sitn, t); + struct ip_tunnel __rcu **tp = ipip6_bucket(sitn, t); - spin_lock_bh(&ipip6_lock); - t->next = *tp; + rcu_assign_pointer(t->next, rtnl_dereference(*tp)); rcu_assign_pointer(*tp, t); - spin_unlock_bh(&ipip6_lock); } static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) @@ -187,17 +213,20 @@ static void ipip6_tunnel_clone_6rd(struct net_device *dev, struct sit_net *sitn) #endif } -static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, +static struct ip_tunnel *ipip6_tunnel_locate(struct net *net, struct ip_tunnel_parm *parms, int create) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; - struct ip_tunnel *t, **tp, *nt; + struct ip_tunnel *t, *nt; + struct ip_tunnel __rcu **tp; struct net_device *dev; char name[IFNAMSIZ]; struct sit_net *sitn = net_generic(net, sit_net_id); - for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) { + for (tp = __ipip6_bucket(sitn, parms); + (t = rtnl_dereference(*tp)) != NULL; + tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr && parms->link == t->parms.link) { @@ -213,7 +242,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else - sprintf(name, "sit%%d"); + strcpy(name, "sit%d"); dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); if (dev == NULL) @@ -229,7 +258,8 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, nt = netdev_priv(dev); nt->parms = *parms; - ipip6_tunnel_init(dev); + if (ipip6_tunnel_init(dev) < 0) + goto failed_free; ipip6_tunnel_clone_6rd(dev, sitn); if (parms->i_flags & SIT_ISATAP) @@ -244,7 +274,7 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, return nt; failed_free: - free_netdev(dev); + ipip6_dev_free(dev); failed: return NULL; } @@ -340,7 +370,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) ASSERT_RTNL(); - for (p = t->prl; p; p = p->next) { + for (p = rtnl_dereference(t->prl); p; p = rtnl_dereference(p->next)) { if (p->addr == a->addr) { if (chg) { p->flags = a->flags; @@ -451,15 +481,12 @@ static void ipip6_tunnel_uninit(struct net_device *dev) struct sit_net *sitn = net_generic(net, sit_net_id); if (dev == sitn->fb_tunnel_dev) { - spin_lock_bh(&ipip6_lock); - sitn->tunnels_wc[0] = NULL; - spin_unlock_bh(&ipip6_lock); - dev_put(dev); + rcu_assign_pointer(sitn->tunnels_wc[0], NULL); } else { ipip6_tunnel_unlink(sitn, netdev_priv(dev)); ipip6_tunnel_del_prl(netdev_priv(dev), NULL); - dev_put(dev); } + dev_put(dev); } @@ -548,6 +575,8 @@ static int ipip6_rcv(struct sk_buff *skb) tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev, iph->saddr, iph->daddr); if (tunnel != NULL) { + struct pcpu_tstats *tstats; + secpath_reset(skb); skb->mac_header = skb->network_header; skb_reset_network_header(skb); @@ -563,10 +592,16 @@ static int ipip6_rcv(struct sk_buff *skb) return 0; } - skb_tunnel_rx(skb, tunnel->dev); + tstats = this_cpu_ptr(tunnel->dev->tstats); + tstats->rx_packets++; + tstats->rx_bytes += skb->len; + + __skb_tunnel_rx(skb, tunnel->dev); ipip6_ecn_decapsulate(iph, skb); + netif_rx(skb); + rcu_read_unlock(); return 0; } @@ -590,7 +625,7 @@ __be32 try_6rd(struct in6_addr *v6dst, struct ip_tunnel *tunnel) #ifdef CONFIG_IPV6_SIT_6RD if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix, tunnel->ip6rd.prefixlen)) { - unsigned pbw0, pbi0; + unsigned int pbw0, pbi0; int pbi1; u32 d; @@ -625,14 +660,13 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; - struct netdev_queue *txq = netdev_get_tx_queue(dev, 0); + struct pcpu_tstats *tstats; struct iphdr *tiph = &tunnel->parms.iph; struct ipv6hdr *iph6 = ipv6_hdr(skb); u8 tos = tunnel->parms.iph.tos; __be16 df = tiph->frag_off; struct rtable *rt; /* Route to the other host */ - struct net_device *tdev; /* Device to other host */ + struct net_device *tdev; /* Device to other host */ struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ __be32 dst = tiph->daddr; @@ -703,20 +737,20 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, .oif = tunnel->parms.link, .proto = IPPROTO_IPV6 }; if (ip_route_output_key(dev_net(dev), &rt, &fl)) { - stats->tx_carrier_errors++; + dev->stats.tx_carrier_errors++; goto tx_error_icmp; } } if (rt->rt_type != RTN_UNICAST) { ip_rt_put(rt); - stats->tx_carrier_errors++; + dev->stats.tx_carrier_errors++; goto tx_error_icmp; } tdev = rt->dst.dev; if (tdev == dev) { ip_rt_put(rt); - stats->collisions++; + dev->stats.collisions++; goto tx_error; } @@ -724,7 +758,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); if (mtu < 68) { - stats->collisions++; + dev->stats.collisions++; ip_rt_put(rt); goto tx_error; } @@ -763,7 +797,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); if (!new_skb) { ip_rt_put(rt); - txq->tx_dropped++; + dev->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -799,14 +833,14 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, iph->ttl = iph6->hop_limit; nf_reset(skb); - - IPTUNNEL_XMIT(); + tstats = this_cpu_ptr(dev->tstats); + __IPTUNNEL_XMIT(tstats, &dev->stats); return NETDEV_TX_OK; tx_error_icmp: dst_link_failure(skb); tx_error: - stats->tx_errors++; + dev->stats.tx_errors++; dev_kfree_skb(skb); return NETDEV_TX_OK; } @@ -1083,12 +1117,19 @@ static const struct net_device_ops ipip6_netdev_ops = { .ndo_start_xmit = ipip6_tunnel_xmit, .ndo_do_ioctl = ipip6_tunnel_ioctl, .ndo_change_mtu = ipip6_tunnel_change_mtu, + .ndo_get_stats = ipip6_get_stats, }; +static void ipip6_dev_free(struct net_device *dev) +{ + free_percpu(dev->tstats); + free_netdev(dev); +} + static void ipip6_tunnel_setup(struct net_device *dev) { dev->netdev_ops = &ipip6_netdev_ops; - dev->destructor = free_netdev; + dev->destructor = ipip6_dev_free; dev->type = ARPHRD_SIT; dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr); @@ -1098,9 +1139,10 @@ static void ipip6_tunnel_setup(struct net_device *dev) dev->iflink = 0; dev->addr_len = 4; dev->features |= NETIF_F_NETNS_LOCAL; + dev->features |= NETIF_F_LLTX; } -static void ipip6_tunnel_init(struct net_device *dev) +static int ipip6_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); @@ -1111,9 +1153,14 @@ static void ipip6_tunnel_init(struct net_device *dev) memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); ipip6_tunnel_bind_dev(dev); + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; + + return 0; } -static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) +static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); struct iphdr *iph = &tunnel->parms.iph; @@ -1128,11 +1175,15 @@ static void __net_init ipip6_fb_tunnel_init(struct net_device *dev) iph->ihl = 5; iph->ttl = 64; + dev->tstats = alloc_percpu(struct pcpu_tstats); + if (!dev->tstats) + return -ENOMEM; dev_hold(dev); sitn->tunnels_wc[0] = tunnel; + return 0; } -static struct xfrm_tunnel sit_handler = { +static struct xfrm_tunnel sit_handler __read_mostly = { .handler = ipip6_rcv, .err_handler = ipip6_err, .priority = 1, @@ -1173,7 +1224,10 @@ static int __net_init sit_init_net(struct net *net) } dev_net_set(sitn->fb_tunnel_dev, net); - ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); + err = ipip6_fb_tunnel_init(sitn->fb_tunnel_dev); + if (err) + goto err_dev_free; + ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn); if ((err = register_netdev(sitn->fb_tunnel_dev))) @@ -1183,7 +1237,8 @@ static int __net_init sit_init_net(struct net *net) err_reg_dev: dev_put(sitn->fb_tunnel_dev); - free_netdev(sitn->fb_tunnel_dev); +err_dev_free: + ipip6_dev_free(sitn->fb_tunnel_dev); err_alloc_dev: return err; } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index fe6d40418c0b8fdba3b58fd7b88d3fedc2a7f6a2..7e41e2cbb85e39b78ea3c66c5b85273fc04fa036 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -139,7 +139,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, return -EINVAL; if (usin->sin6_family != AF_INET6) - return(-EAFNOSUPPORT); + return -EAFNOSUPPORT; memset(&fl, 0, sizeof(fl)); @@ -1409,7 +1409,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, newsk = tcp_create_openreq_child(sk, req, skb); if (newsk == NULL) - goto out; + goto out_nonewsk; /* * No need to charge this sock to the relevant IPv6 refcnt debug socks @@ -1497,18 +1497,22 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, } #endif + if (__inet_inherit_port(sk, newsk) < 0) { + sock_put(newsk); + goto out; + } __inet6_hash(newsk, NULL); - __inet_inherit_port(sk, newsk); return newsk; out_overflow: NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS); -out: - NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); +out_nonewsk: if (opt && opt != np->opt) sock_kfree_s(sk, opt, opt->tot_len); dst_release(dst); +out: + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS); return NULL; } diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c index fc3c86a474526ee1c3b9c3f644fbe1d14c458f0e..d9864725d0c6a259ba8a4d35cbe08762de5e53f4 100644 --- a/net/ipv6/tunnel6.c +++ b/net/ipv6/tunnel6.c @@ -30,8 +30,8 @@ #include #include -static struct xfrm6_tunnel *tunnel6_handlers; -static struct xfrm6_tunnel *tunnel46_handlers; +static struct xfrm6_tunnel *tunnel6_handlers __read_mostly; +static struct xfrm6_tunnel *tunnel46_handlers __read_mostly; static DEFINE_MUTEX(tunnel6_mutex); int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) @@ -51,7 +51,7 @@ int xfrm6_tunnel_register(struct xfrm6_tunnel *handler, unsigned short family) } handler->next = *pprev; - *pprev = handler; + rcu_assign_pointer(*pprev, handler); ret = 0; @@ -88,6 +88,11 @@ int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler, unsigned short family) EXPORT_SYMBOL(xfrm6_tunnel_deregister); +#define for_each_tunnel_rcu(head, handler) \ + for (handler = rcu_dereference(head); \ + handler != NULL; \ + handler = rcu_dereference(handler->next)) \ + static int tunnel6_rcv(struct sk_buff *skb) { struct xfrm6_tunnel *handler; @@ -95,7 +100,7 @@ static int tunnel6_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto drop; - for (handler = tunnel6_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel6_handlers, handler) if (!handler->handler(skb)) return 0; @@ -113,7 +118,7 @@ static int tunnel46_rcv(struct sk_buff *skb) if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto drop; - for (handler = tunnel46_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel46_handlers, handler) if (!handler->handler(skb)) return 0; @@ -129,7 +134,7 @@ static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, { struct xfrm6_tunnel *handler; - for (handler = tunnel6_handlers; handler; handler = handler->next) + for_each_tunnel_rcu(tunnel6_handlers, handler) if (!handler->err_handler(skb, opt, type, code, offset, info)) break; } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 5acb3560ff15267021266f59c7b2102f633f3d6a..c84dad432114ef0d885b29244bf9df0854f750e2 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -122,8 +122,8 @@ static void udp_v6_rehash(struct sock *sk) static inline int compute_score(struct sock *sk, struct net *net, unsigned short hnum, - struct in6_addr *saddr, __be16 sport, - struct in6_addr *daddr, __be16 dport, + const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, int dif) { int score = -1; @@ -239,8 +239,8 @@ static struct sock *udp6_lib_lookup2(struct net *net, } static struct sock *__udp6_lib_lookup(struct net *net, - struct in6_addr *saddr, __be16 sport, - struct in6_addr *daddr, __be16 dport, + const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, int dif, struct udp_table *udptable) { struct sock *sk, *result; @@ -320,6 +320,14 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb, udptable); } +struct sock *udp6_lib_lookup(struct net *net, const struct in6_addr *saddr, __be16 sport, + const struct in6_addr *daddr, __be16 dport, int dif) +{ + return __udp6_lib_lookup(net, saddr, sport, daddr, dport, dif, &udp_table); +} +EXPORT_SYMBOL_GPL(udp6_lib_lookup); + + /* * This should be easy, if there is something there we * return it, otherwise we block. diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 6baeabbbca82416ffb940be126de520a847779a9..7e74023ea6e4381ae006eb672369f98fb899cc79 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -199,7 +199,7 @@ static inline int xfrm6_garbage_collect(struct dst_ops *ops) struct net *net = container_of(ops, struct net, xfrm.xfrm6_dst_ops); xfrm6_policy_afinfo.garbage_collect(net); - return (atomic_read(&ops->entries) > ops->gc_thresh * 2); + return dst_entries_get_fast(ops) > ops->gc_thresh * 2; } static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu) @@ -255,7 +255,6 @@ static struct dst_ops xfrm6_dst_ops = { .ifdown = xfrm6_dst_ifdown, .local_out = __ip6_local_out, .gc_thresh = 1024, - .entries = ATOMIC_INIT(0), }; static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { @@ -312,11 +311,13 @@ int __init xfrm6_init(void) */ gc_thresh = FIB6_TABLE_HASHSZ * 8; xfrm6_dst_ops.gc_thresh = (gc_thresh < 1024) ? 1024 : gc_thresh; + dst_entries_init(&xfrm6_dst_ops); ret = xfrm6_policy_init(); - if (ret) + if (ret) { + dst_entries_destroy(&xfrm6_dst_ops); goto out; - + } ret = xfrm6_state_init(); if (ret) goto out_policy; @@ -341,4 +342,5 @@ void xfrm6_fini(void) //xfrm6_input_fini(); xfrm6_policy_fini(); xfrm6_state_fini(); + dst_entries_destroy(&xfrm6_dst_ops); } diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 2ce3a8278f26576668ffafd178891451e2b5fc87..2969cad408deef8e5c798606157a052064489156 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c @@ -199,7 +199,7 @@ static void x6spi_destroy_rcu(struct rcu_head *head) container_of(head, struct xfrm6_tunnel_spi, rcu_head)); } -void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr) +static void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr) { struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); struct xfrm6_tunnel_spi *x6spi; @@ -223,8 +223,6 @@ void xfrm6_tunnel_free_spi(struct net *net, xfrm_address_t *saddr) spin_unlock_bh(&xfrm6_tunnel_spi_lock); } -EXPORT_SYMBOL(xfrm6_tunnel_free_spi); - static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) { skb_push(skb, -skb_network_offset(skb)); @@ -317,13 +315,13 @@ static const struct xfrm_type xfrm6_tunnel_type = { .output = xfrm6_tunnel_output, }; -static struct xfrm6_tunnel xfrm6_tunnel_handler = { +static struct xfrm6_tunnel xfrm6_tunnel_handler __read_mostly = { .handler = xfrm6_tunnel_rcv, .err_handler = xfrm6_tunnel_err, .priority = 2, }; -static struct xfrm6_tunnel xfrm46_tunnel_handler = { +static struct xfrm6_tunnel xfrm46_tunnel_handler __read_mostly = { .handler = xfrm6_tunnel_rcv, .err_handler = xfrm6_tunnel_err, .priority = 2, diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index fd55b5135de5aad91f547281a9c7a07c44f676b0..7f097989cde2149714eab1ea7b1de02280531ed2 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c @@ -573,9 +573,9 @@ static int irda_find_lsap_sel(struct irda_sock *self, char *name) /* Requested object/attribute doesn't exist */ if((self->errno == IAS_CLASS_UNKNOWN) || (self->errno == IAS_ATTRIB_UNKNOWN)) - return (-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; else - return (-EHOSTUNREACH); + return -EHOSTUNREACH; } /* Get the remote TSAP selector */ @@ -663,7 +663,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) __func__, name); self->daddr = DEV_ADDR_ANY; kfree(discoveries); - return(-ENOTUNIQ); + return -ENOTUNIQ; } /* First time we found that one, save it ! */ daddr = self->daddr; @@ -677,7 +677,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) IRDA_DEBUG(0, "%s(), unexpected IAS query failure\n", __func__); self->daddr = DEV_ADDR_ANY; kfree(discoveries); - return(-EHOSTUNREACH); + return -EHOSTUNREACH; break; } } @@ -689,7 +689,7 @@ static int irda_discover_daddr_and_lsap_sel(struct irda_sock *self, char *name) IRDA_DEBUG(1, "%s(), cannot discover service ''%s'' in any device !!!\n", __func__, name); self->daddr = DEV_ADDR_ANY; - return(-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; } /* Revert back to discovered device & service */ @@ -715,14 +715,11 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, struct sockaddr_irda saddr; struct sock *sk = sock->sk; struct irda_sock *self = irda_sk(sk); - int err; - lock_kernel(); memset(&saddr, 0, sizeof(saddr)); if (peer) { - err = -ENOTCONN; if (sk->sk_state != TCP_ESTABLISHED) - goto out; + return -ENOTCONN; saddr.sir_family = AF_IRDA; saddr.sir_lsap_sel = self->dtsap_sel; @@ -739,10 +736,8 @@ static int irda_getname(struct socket *sock, struct sockaddr *uaddr, /* uaddr_len come to us uninitialised */ *uaddr_len = sizeof (struct sockaddr_irda); memcpy(uaddr, &saddr, *uaddr_len); - err = 0; -out: - unlock_kernel(); - return err; + + return 0; } /* @@ -758,7 +753,8 @@ static int irda_listen(struct socket *sock, int backlog) IRDA_DEBUG(2, "%s()\n", __func__); - lock_kernel(); + lock_sock(sk); + if ((sk->sk_type != SOCK_STREAM) && (sk->sk_type != SOCK_SEQPACKET) && (sk->sk_type != SOCK_DGRAM)) goto out; @@ -770,7 +766,7 @@ static int irda_listen(struct socket *sock, int backlog) err = 0; } out: - unlock_kernel(); + release_sock(sk); return err; } @@ -793,7 +789,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (addr_len != sizeof(struct sockaddr_irda)) return -EINVAL; - lock_kernel(); + lock_sock(sk); #ifdef CONFIG_IRDA_ULTRA /* Special care for Ultra sockets */ if ((sk->sk_type == SOCK_DGRAM) && @@ -836,7 +832,7 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) err = 0; out: - unlock_kernel(); + release_sock(sk); return err; } @@ -856,12 +852,13 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) IRDA_DEBUG(2, "%s()\n", __func__); - lock_kernel(); err = irda_create(sock_net(sk), newsock, sk->sk_protocol, 0); if (err) - goto out; + return err; err = -EINVAL; + + lock_sock(sk); if (sock->state != SS_UNCONNECTED) goto out; @@ -947,7 +944,7 @@ static int irda_accept(struct socket *sock, struct socket *newsock, int flags) irda_connect_response(new); err = 0; out: - unlock_kernel(); + release_sock(sk); return err; } @@ -981,7 +978,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, IRDA_DEBUG(2, "%s(%p)\n", __func__, self); - lock_kernel(); + lock_sock(sk); /* Don't allow connect for Ultra sockets */ err = -ESOCKTNOSUPPORT; if ((sk->sk_type == SOCK_DGRAM) && (sk->sk_protocol == IRDAPROTO_ULTRA)) @@ -1072,6 +1069,8 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, if (sk->sk_state != TCP_ESTABLISHED) { sock->state = SS_UNCONNECTED; + if (sk->sk_prot->disconnect(sk, flags)) + sock->state = SS_DISCONNECTING; err = sock_error(sk); if (!err) err = -ECONNRESET; @@ -1084,7 +1083,7 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr, self->saddr = irttp_get_saddr(self->tsap); err = 0; out: - unlock_kernel(); + release_sock(sk); return err; } @@ -1231,7 +1230,6 @@ static int irda_release(struct socket *sock) if (sk == NULL) return 0; - lock_kernel(); lock_sock(sk); sk->sk_state = TCP_CLOSE; sk->sk_shutdown |= SEND_SHUTDOWN; @@ -1250,7 +1248,6 @@ static int irda_release(struct socket *sock) /* Destroy networking socket if we are the last reference on it, * i.e. if(sk->sk_refcnt == 0) -> sk_free(sk) */ sock_put(sk); - unlock_kernel(); /* Notes on socket locking and deallocation... - Jean II * In theory we should put pairs of sock_hold() / sock_put() to @@ -1298,7 +1295,6 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); - lock_kernel(); /* Note : socket.c set MSG_EOR on SEQPACKET sockets */ if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_EOR | MSG_CMSG_COMPAT | MSG_NOSIGNAL)) { @@ -1306,6 +1302,8 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, goto out; } + lock_sock(sk); + if (sk->sk_shutdown & SEND_SHUTDOWN) goto out_err; @@ -1361,14 +1359,14 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock, goto out_err; } - unlock_kernel(); + release_sock(sk); /* Tell client how much data we actually sent */ return len; out_err: err = sk_stream_error(sk, msg->msg_flags, err); out: - unlock_kernel(); + release_sock(sk); return err; } @@ -1390,14 +1388,10 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(4, "%s()\n", __func__); - lock_kernel(); - if ((err = sock_error(sk)) < 0) - goto out; - skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); if (!skb) - goto out; + return err; skb_reset_transport_header(skb); copied = skb->len; @@ -1425,12 +1419,8 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock, irttp_flow_request(self->tsap, FLOW_START); } } - unlock_kernel(); - return copied; -out: - unlock_kernel(); - return err; + return copied; } /* @@ -1448,17 +1438,15 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(3, "%s()\n", __func__); - lock_kernel(); if ((err = sock_error(sk)) < 0) - goto out; + return err; - err = -EINVAL; if (sock->flags & __SO_ACCEPTCON) - goto out; + return -EINVAL; err =-EOPNOTSUPP; if (flags & MSG_OOB) - goto out; + return -EOPNOTSUPP; err = 0; target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); @@ -1500,7 +1488,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, finish_wait(sk_sleep(sk), &wait); if (err) - goto out; + return err; if (sk->sk_shutdown & RCV_SHUTDOWN) break; @@ -1553,9 +1541,7 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock, } } -out: - unlock_kernel(); - return err ? : copied; + return copied; } /* @@ -1573,13 +1559,12 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, struct sk_buff *skb; int err; - lock_kernel(); - IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); - err = -EINVAL; if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) - goto out; + return -EINVAL; + + lock_sock(sk); if (sk->sk_shutdown & SEND_SHUTDOWN) { send_sig(SIGPIPE, current, 0); @@ -1630,10 +1615,12 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); goto out; } - unlock_kernel(); + + release_sock(sk); return len; + out: - unlock_kernel(); + release_sock(sk); return err; } @@ -1656,10 +1643,11 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, IRDA_DEBUG(4, "%s(), len=%zd\n", __func__, len); - lock_kernel(); err = -EINVAL; if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) - goto out; + return -EINVAL; + + lock_sock(sk); err = -EPIPE; if (sk->sk_shutdown & SEND_SHUTDOWN) { @@ -1732,7 +1720,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock, if (err) IRDA_DEBUG(0, "%s(), err=%d\n", __func__, err); out: - unlock_kernel(); + release_sock(sk); return err ? : len; } #endif /* CONFIG_IRDA_ULTRA */ @@ -1747,7 +1735,7 @@ static int irda_shutdown(struct socket *sock, int how) IRDA_DEBUG(1, "%s(%p)\n", __func__, self); - lock_kernel(); + lock_sock(sk); sk->sk_state = TCP_CLOSE; sk->sk_shutdown |= SEND_SHUTDOWN; @@ -1769,7 +1757,7 @@ static int irda_shutdown(struct socket *sock, int how) self->daddr = DEV_ADDR_ANY; /* Until we get re-connected */ self->saddr = 0x0; /* so IrLMP assign us any link */ - unlock_kernel(); + release_sock(sk); return 0; } @@ -1786,7 +1774,6 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, IRDA_DEBUG(4, "%s()\n", __func__); - lock_kernel(); poll_wait(file, sk_sleep(sk), wait); mask = 0; @@ -1834,20 +1821,8 @@ static unsigned int irda_poll(struct file * file, struct socket *sock, default: break; } - unlock_kernel(); - return mask; -} -static unsigned int irda_datagram_poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - int err; - - lock_kernel(); - err = datagram_poll(file, sock, wait); - unlock_kernel(); - - return err; + return mask; } /* @@ -1860,7 +1835,6 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) IRDA_DEBUG(4, "%s(), cmd=%#x\n", __func__, cmd); - lock_kernel(); err = -EINVAL; switch (cmd) { case TIOCOUTQ: { @@ -1903,7 +1877,6 @@ static int irda_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) IRDA_DEBUG(1, "%s(), doing device ioctl!\n", __func__); err = -ENOIOCTLCMD; } - unlock_kernel(); return err; } @@ -1927,7 +1900,7 @@ static int irda_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned lon * Set some options for the socket * */ -static int __irda_setsockopt(struct socket *sock, int level, int optname, +static int irda_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; @@ -1935,13 +1908,15 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, struct irda_ias_set *ias_opt; struct ias_object *ias_obj; struct ias_attrib * ias_attr; /* Attribute in IAS object */ - int opt, free_ias = 0; + int opt, free_ias = 0, err = 0; IRDA_DEBUG(2, "%s(%p)\n", __func__, self); if (level != SOL_IRLMP) return -ENOPROTOOPT; + lock_sock(sk); + switch (optname) { case IRLMP_IAS_SET: /* The user want to add an attribute to an existing IAS object @@ -1951,17 +1926,22 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, * create the right attribute... */ - if (optlen != sizeof(struct irda_ias_set)) - return -EINVAL; + if (optlen != sizeof(struct irda_ias_set)) { + err = -EINVAL; + goto out; + } ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); - if (ias_opt == NULL) - return -ENOMEM; + if (ias_opt == NULL) { + err = -ENOMEM; + goto out; + } /* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, optlen)) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Find the object we target. @@ -1971,7 +1951,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, if(ias_opt->irda_class_name[0] == '\0') { if(self->ias_obj == NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } ias_obj = self->ias_obj; } else @@ -1983,7 +1964,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, if((!capable(CAP_NET_ADMIN)) && ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { kfree(ias_opt); - return -EPERM; + err = -EPERM; + goto out; } /* If the object doesn't exist, create it */ @@ -1993,7 +1975,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, jiffies); if (ias_obj == NULL) { kfree(ias_opt); - return -ENOMEM; + err = -ENOMEM; + goto out; } free_ias = 1; } @@ -2005,7 +1988,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, kfree(ias_obj->name); kfree(ias_obj); } - return -EINVAL; + err = -EINVAL; + goto out; } /* Look at the type */ @@ -2028,7 +2012,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, kfree(ias_obj); } - return -EINVAL; + err = -EINVAL; + goto out; } /* Add an octet sequence attribute */ irias_add_octseq_attrib( @@ -2060,7 +2045,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, kfree(ias_obj->name); kfree(ias_obj); } - return -EINVAL; + err = -EINVAL; + goto out; } irias_insert_object(ias_obj); kfree(ias_opt); @@ -2071,17 +2057,22 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, * object is not owned by the kernel and delete it. */ - if (optlen != sizeof(struct irda_ias_set)) - return -EINVAL; + if (optlen != sizeof(struct irda_ias_set)) { + err = -EINVAL; + goto out; + } ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); - if (ias_opt == NULL) - return -ENOMEM; + if (ias_opt == NULL) { + err = -ENOMEM; + goto out; + } /* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, optlen)) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Find the object we target. @@ -2094,7 +2085,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, ias_obj = irias_find_object(ias_opt->irda_class_name); if(ias_obj == (struct ias_object *) NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } /* Only ROOT can mess with the global IAS database. @@ -2103,7 +2095,8 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, if((!capable(CAP_NET_ADMIN)) && ((ias_obj == NULL) || (ias_obj != self->ias_obj))) { kfree(ias_opt); - return -EPERM; + err = -EPERM; + goto out; } /* Find the attribute (in the object) we target */ @@ -2111,14 +2104,16 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, ias_opt->irda_attrib_name); if(ias_attr == (struct ias_attrib *) NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } /* Check is the user space own the object */ if(ias_attr->value->owner != IAS_USER_ATTR) { IRDA_DEBUG(1, "%s(), attempting to delete a kernel attribute\n", __func__); kfree(ias_opt); - return -EPERM; + err = -EPERM; + goto out; } /* Remove the attribute (and maybe the object) */ @@ -2126,11 +2121,15 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, kfree(ias_opt); break; case IRLMP_MAX_SDU_SIZE: - if (optlen < sizeof(int)) - return -EINVAL; + if (optlen < sizeof(int)) { + err = -EINVAL; + goto out; + } - if (get_user(opt, (int __user *)optval)) - return -EFAULT; + if (get_user(opt, (int __user *)optval)) { + err = -EFAULT; + goto out; + } /* Only possible for a seqpacket service (TTP with SAR) */ if (sk->sk_type != SOCK_SEQPACKET) { @@ -2140,16 +2139,21 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, } else { IRDA_WARNING("%s: not allowed to set MAXSDUSIZE for this socket type!\n", __func__); - return -ENOPROTOOPT; + err = -ENOPROTOOPT; + goto out; } break; case IRLMP_HINTS_SET: - if (optlen < sizeof(int)) - return -EINVAL; + if (optlen < sizeof(int)) { + err = -EINVAL; + goto out; + } /* The input is really a (__u8 hints[2]), easier as an int */ - if (get_user(opt, (int __user *)optval)) - return -EFAULT; + if (get_user(opt, (int __user *)optval)) { + err = -EFAULT; + goto out; + } /* Unregister any old registration */ if (self->skey) @@ -2163,12 +2167,16 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, * making a discovery (nodes which don't match any hint * bit in the mask are not reported). */ - if (optlen < sizeof(int)) - return -EINVAL; + if (optlen < sizeof(int)) { + err = -EINVAL; + goto out; + } /* The input is really a (__u8 hints[2]), easier as an int */ - if (get_user(opt, (int __user *)optval)) - return -EFAULT; + if (get_user(opt, (int __user *)optval)) { + err = -EFAULT; + goto out; + } /* Set the new hint mask */ self->mask.word = (__u16) opt; @@ -2180,19 +2188,12 @@ static int __irda_setsockopt(struct socket *sock, int level, int optname, break; default: - return -ENOPROTOOPT; + err = -ENOPROTOOPT; + break; } - return 0; -} -static int irda_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, unsigned int optlen) -{ - int err; - - lock_kernel(); - err = __irda_setsockopt(sock, level, optname, optval, optlen); - unlock_kernel(); +out: + release_sock(sk); return err; } @@ -2249,7 +2250,7 @@ static int irda_extract_ias_value(struct irda_ias_set *ias_opt, /* * Function irda_getsockopt (sock, level, optname, optval, optlen) */ -static int __irda_getsockopt(struct socket *sock, int level, int optname, +static int irda_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; @@ -2262,7 +2263,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, int daddr = DEV_ADDR_ANY; /* Dest address for IAS queries */ int val = 0; int len = 0; - int err; + int err = 0; int offset, total; IRDA_DEBUG(2, "%s(%p)\n", __func__, self); @@ -2276,15 +2277,18 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, if(len < 0) return -EINVAL; + lock_sock(sk); + switch (optname) { case IRLMP_ENUMDEVICES: /* Ask lmp for the current discovery log */ discoveries = irlmp_get_discoveries(&list.len, self->mask.word, self->nslots); /* Check if the we got some results */ - if (discoveries == NULL) - return -EAGAIN; /* Didn't find any devices */ - err = 0; + if (discoveries == NULL) { + err = -EAGAIN; + goto out; /* Didn't find any devices */ + } /* Write total list length back to client */ if (copy_to_user(optval, &list, @@ -2297,8 +2301,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, sizeof(struct irda_device_info); /* Copy the list itself - watch for overflow */ - if(list.len > 2048) - { + if (list.len > 2048) { err = -EINVAL; goto bed; } @@ -2314,17 +2317,20 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, bed: /* Free up our buffer */ kfree(discoveries); - if (err) - return err; break; case IRLMP_MAX_SDU_SIZE: val = self->max_data_size; len = sizeof(int); - if (put_user(len, optlen)) - return -EFAULT; + if (put_user(len, optlen)) { + err = -EFAULT; + goto out; + } + + if (copy_to_user(optval, &val, len)) { + err = -EFAULT; + goto out; + } - if (copy_to_user(optval, &val, len)) - return -EFAULT; break; case IRLMP_IAS_GET: /* The user want an object from our local IAS database. @@ -2332,17 +2338,22 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, * that we found */ /* Check that the user has allocated the right space for us */ - if (len != sizeof(struct irda_ias_set)) - return -EINVAL; + if (len != sizeof(struct irda_ias_set)) { + err = -EINVAL; + goto out; + } ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); - if (ias_opt == NULL) - return -ENOMEM; + if (ias_opt == NULL) { + err = -ENOMEM; + goto out; + } /* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, len)) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Find the object we target. @@ -2355,7 +2366,8 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, ias_obj = irias_find_object(ias_opt->irda_class_name); if(ias_obj == (struct ias_object *) NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } /* Find the attribute (in the object) we target */ @@ -2363,21 +2375,23 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, ias_opt->irda_attrib_name); if(ias_attr == (struct ias_attrib *) NULL) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } /* Translate from internal to user structure */ err = irda_extract_ias_value(ias_opt, ias_attr->value); if(err) { kfree(ias_opt); - return err; + goto out; } /* Copy reply to the user */ if (copy_to_user(optval, ias_opt, sizeof(struct irda_ias_set))) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Note : don't need to put optlen, we checked it */ kfree(ias_opt); @@ -2388,17 +2402,22 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, * then wait for the answer to come back. */ /* Check that the user has allocated the right space for us */ - if (len != sizeof(struct irda_ias_set)) - return -EINVAL; + if (len != sizeof(struct irda_ias_set)) { + err = -EINVAL; + goto out; + } ias_opt = kmalloc(sizeof(struct irda_ias_set), GFP_ATOMIC); - if (ias_opt == NULL) - return -ENOMEM; + if (ias_opt == NULL) { + err = -ENOMEM; + goto out; + } /* Copy query to the driver. */ if (copy_from_user(ias_opt, optval, len)) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* At this point, there are two cases... @@ -2419,7 +2438,8 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, daddr = ias_opt->daddr; if((!daddr) || (daddr == DEV_ADDR_ANY)) { kfree(ias_opt); - return -EINVAL; + err = -EINVAL; + goto out; } } @@ -2428,7 +2448,8 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, IRDA_WARNING("%s: busy with a previous query\n", __func__); kfree(ias_opt); - return -EBUSY; + err = -EBUSY; + goto out; } self->iriap = iriap_open(LSAP_ANY, IAS_CLIENT, self, @@ -2436,7 +2457,8 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, if (self->iriap == NULL) { kfree(ias_opt); - return -ENOMEM; + err = -ENOMEM; + goto out; } /* Treat unexpected wakeup as disconnect */ @@ -2455,7 +2477,8 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, * we can free it regardless! */ kfree(ias_opt); /* Treat signals as disconnect */ - return -EHOSTUNREACH; + err = -EHOSTUNREACH; + goto out; } /* Check what happened */ @@ -2465,9 +2488,11 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, /* Requested object/attribute doesn't exist */ if((self->errno == IAS_CLASS_UNKNOWN) || (self->errno == IAS_ATTRIB_UNKNOWN)) - return (-EADDRNOTAVAIL); + err = -EADDRNOTAVAIL; else - return (-EHOSTUNREACH); + err = -EHOSTUNREACH; + + goto out; } /* Translate from internal to user structure */ @@ -2476,14 +2501,15 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, irias_delete_value(self->ias_result); if (err) { kfree(ias_opt); - return err; + goto out; } /* Copy reply to the user */ if (copy_to_user(optval, ias_opt, sizeof(struct irda_ias_set))) { kfree(ias_opt); - return -EFAULT; + err = -EFAULT; + goto out; } /* Note : don't need to put optlen, we checked it */ kfree(ias_opt); @@ -2504,11 +2530,15 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, */ /* Check that the user is passing us an int */ - if (len != sizeof(int)) - return -EINVAL; + if (len != sizeof(int)) { + err = -EINVAL; + goto out; + } /* Get timeout in ms (max time we block the caller) */ - if (get_user(val, (int __user *)optval)) - return -EFAULT; + if (get_user(val, (int __user *)optval)) { + err = -EFAULT; + goto out; + } /* Tell IrLMP we want to be notified */ irlmp_update_client(self->ckey, self->mask.word, @@ -2520,8 +2550,6 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, /* Wait until a node is discovered */ if (!self->cachedaddr) { - int ret = 0; - IRDA_DEBUG(1, "%s(), nothing discovered yet, going to sleep...\n", __func__); /* Set watchdog timer to expire in ms. */ @@ -2534,7 +2562,7 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, /* Wait for IR-LMP to call us back */ __wait_event_interruptible(self->query_wait, (self->cachedaddr != 0 || self->errno == -ETIME), - ret); + err); /* If watchdog is still activated, kill it! */ if(timer_pending(&(self->watchdog))) @@ -2542,8 +2570,8 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, IRDA_DEBUG(1, "%s(), ...waking up !\n", __func__); - if (ret != 0) - return ret; + if (err != 0) + goto out; } else IRDA_DEBUG(1, "%s(), found immediately !\n", @@ -2566,25 +2594,19 @@ static int __irda_getsockopt(struct socket *sock, int level, int optname, * If the user want more details, he should query * the whole discovery log and pick one device... */ - if (put_user(daddr, (int __user *)optval)) - return -EFAULT; + if (put_user(daddr, (int __user *)optval)) { + err = -EFAULT; + goto out; + } break; default: - return -ENOPROTOOPT; + err = -ENOPROTOOPT; } - return 0; -} - -static int irda_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) -{ - int err; +out: - lock_kernel(); - err = __irda_getsockopt(sock, level, optname, optval, optlen); - unlock_kernel(); + release_sock(sk); return err; } @@ -2628,7 +2650,7 @@ static const struct proto_ops irda_seqpacket_ops = { .socketpair = sock_no_socketpair, .accept = irda_accept, .getname = irda_getname, - .poll = irda_datagram_poll, + .poll = datagram_poll, .ioctl = irda_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, @@ -2652,7 +2674,7 @@ static const struct proto_ops irda_dgram_ops = { .socketpair = sock_no_socketpair, .accept = irda_accept, .getname = irda_getname, - .poll = irda_datagram_poll, + .poll = datagram_poll, .ioctl = irda_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, @@ -2677,7 +2699,7 @@ static const struct proto_ops irda_ultra_ops = { .socketpair = sock_no_socketpair, .accept = sock_no_accept, .getname = irda_getname, - .poll = irda_datagram_poll, + .poll = datagram_poll, .ioctl = irda_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = irda_compat_ioctl, diff --git a/net/irda/discovery.c b/net/irda/discovery.c index c1c8ae939126027c5d3ddb6192d2da88677da419..36c3f037f1727f38d4601d07ec635e5d81b77373 100644 --- a/net/irda/discovery.c +++ b/net/irda/discovery.c @@ -315,7 +315,7 @@ struct irda_device_info *irlmp_copy_discoveries(hashbin_t *log, int *pn, /* Get the actual number of device in the buffer and return */ *pn = i; - return(buffer); + return buffer; } #ifdef CONFIG_PROC_FS diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index faa82ca2dfdcf9c8cff71b486434997d832c87cf..a39cca8331dfdf16c0d8cea14682e93472a75ce1 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -449,8 +449,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) } #ifdef SERIAL_DO_RESTART - return ((self->flags & ASYNC_HUP_NOTIFY) ? - -EAGAIN : -ERESTARTSYS); + return (self->flags & ASYNC_HUP_NOTIFY) ? + -EAGAIN : -ERESTARTSYS; #else return -EAGAIN; #endif diff --git a/net/irda/iriap.c b/net/irda/iriap.c index fce364c6c71a5e612fb9f0c2c65b0166749821af..5b743bdd89ba26a3a30b1110de67cea27636f047 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c @@ -502,7 +502,8 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self, IRDA_DEBUG(4, "%s(), strlen=%d\n", __func__, value_len); /* Make sure the string is null-terminated */ - fp[n+value_len] = 0x00; + if (n + value_len < skb->len) + fp[n + value_len] = 0x00; IRDA_DEBUG(4, "Got string %s\n", fp+n); /* Will truncate to IAS_MAX_STRING bytes */ diff --git a/net/irda/irlan/irlan_eth.c b/net/irda/irlan/irlan_eth.c index 5bb8353105cca7c761647b94c346cc1da82c42e9..8ee1ff6c742fd6745482f8e0327ab7a3c2d86fe5 100644 --- a/net/irda/irlan/irlan_eth.c +++ b/net/irda/irlan/irlan_eth.c @@ -45,13 +45,11 @@ static int irlan_eth_close(struct net_device *dev); static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, struct net_device *dev); static void irlan_eth_set_multicast_list( struct net_device *dev); -static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev); static const struct net_device_ops irlan_eth_netdev_ops = { .ndo_open = irlan_eth_open, .ndo_stop = irlan_eth_close, .ndo_start_xmit = irlan_eth_xmit, - .ndo_get_stats = irlan_eth_get_stats, .ndo_set_multicast_list = irlan_eth_set_multicast_list, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, @@ -208,10 +206,10 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, * tried :-) DB */ /* irttp_data_request already free the packet */ - self->stats.tx_dropped++; + dev->stats.tx_dropped++; } else { - self->stats.tx_packets++; - self->stats.tx_bytes += len; + dev->stats.tx_packets++; + dev->stats.tx_bytes += len; } return NETDEV_TX_OK; @@ -226,15 +224,16 @@ static netdev_tx_t irlan_eth_xmit(struct sk_buff *skb, int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb) { struct irlan_cb *self = instance; + struct net_device *dev = self->dev; if (skb == NULL) { - ++self->stats.rx_dropped; + dev->stats.rx_dropped++; return 0; } if (skb->len < ETH_HLEN) { IRDA_DEBUG(0, "%s() : IrLAN frame too short (%d)\n", __func__, skb->len); - ++self->stats.rx_dropped; + dev->stats.rx_dropped++; dev_kfree_skb(skb); return 0; } @@ -244,10 +243,10 @@ int irlan_eth_receive(void *instance, void *sap, struct sk_buff *skb) * might have been previously set by the low level IrDA network * device driver */ - skb->protocol = eth_type_trans(skb, self->dev); /* Remove eth header */ + skb->protocol = eth_type_trans(skb, dev); /* Remove eth header */ - self->stats.rx_packets++; - self->stats.rx_bytes += skb->len; + dev->stats.rx_packets++; + dev->stats.rx_bytes += skb->len; netif_rx(skb); /* Eat it! */ @@ -348,16 +347,3 @@ static void irlan_eth_set_multicast_list(struct net_device *dev) else irlan_set_broadcast_filter(self, FALSE); } - -/* - * Function irlan_get_stats (dev) - * - * Get the current statistics for this device - * - */ -static struct net_device_stats *irlan_eth_get_stats(struct net_device *dev) -{ - struct irlan_cb *self = netdev_priv(dev); - - return &self->stats; -} diff --git a/net/irda/irlan/irlan_event.c b/net/irda/irlan/irlan_event.c index cbcb4eb54037bb71db6ddd8cb5cf03118509c499..43f16040a6fe0f3016ae66136c84573e6d97be8f 100644 --- a/net/irda/irlan/irlan_event.c +++ b/net/irda/irlan/irlan_event.c @@ -24,7 +24,7 @@ #include -char *irlan_state[] = { +const char * const irlan_state[] = { "IRLAN_IDLE", "IRLAN_QUERY", "IRLAN_CONN", diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 0e7d8bde145d0c9af8d9fc87cc4193b11549ffb4..6115a44c0a24f9ba1cb3248de38b8579118e5dbf 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c @@ -939,7 +939,7 @@ struct irda_device_info *irlmp_get_discoveries(int *pn, __u16 mask, int nslots) } /* Return current cached discovery log */ - return(irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE)); + return irlmp_copy_discoveries(irlmp->cachelog, pn, mask, TRUE); } EXPORT_SYMBOL(irlmp_get_discoveries); diff --git a/net/irda/irlmp_frame.c b/net/irda/irlmp_frame.c index 3750884094daf2996b04d89c2de7970cf7247113..062e63b1c5c4cf32d8722e602975db4b15cbf2bd 100644 --- a/net/irda/irlmp_frame.c +++ b/net/irda/irlmp_frame.c @@ -448,7 +448,7 @@ static struct lsap_cb *irlmp_find_lsap(struct lap_cb *self, __u8 dlsap_sel, (self->cache.slsap_sel == slsap_sel) && (self->cache.dlsap_sel == dlsap_sel)) { - return (self->cache.lsap); + return self->cache.lsap; } #endif diff --git a/net/irda/irnet/irnet.h b/net/irda/irnet/irnet.h index 4300df35d37d0fee2796aa58c53467efa05b7799..0d82ff5aeff1e0629348739788026f2ce151edca 100644 --- a/net/irda/irnet/irnet.h +++ b/net/irda/irnet/irnet.h @@ -458,6 +458,8 @@ typedef struct irnet_socket int disco_index; /* Last read in the discovery log */ int disco_number; /* Size of the discovery log */ + struct mutex lock; + } irnet_socket; /* diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c index e98e40d76f4f4f256e6bf43d95d577f4eedeb312..7f17a8020e8a0b99c82f236f34bb0f7fc8d604be 100644 --- a/net/irda/irnet/irnet_irda.c +++ b/net/irda/irnet/irnet_irda.c @@ -238,7 +238,7 @@ irnet_ias_to_tsap(irnet_socket * self, DEXIT(IRDA_SR_TRACE, "\n"); /* Return the TSAP */ - return(dtsap_sel); + return dtsap_sel; } /*------------------------------------------------------------------*/ @@ -301,7 +301,7 @@ irnet_connect_tsap(irnet_socket * self) { clear_bit(0, &self->ttp_connect); DERROR(IRDA_SR_ERROR, "connect aborted!\n"); - return(err); + return err; } /* Connect to remote device */ @@ -312,7 +312,7 @@ irnet_connect_tsap(irnet_socket * self) { clear_bit(0, &self->ttp_connect); DERROR(IRDA_SR_ERROR, "connect aborted!\n"); - return(err); + return err; } /* The above call is non-blocking. @@ -321,7 +321,7 @@ irnet_connect_tsap(irnet_socket * self) * See you there ;-) */ DEXIT(IRDA_SR_TRACE, "\n"); - return(err); + return err; } /*------------------------------------------------------------------*/ @@ -362,10 +362,10 @@ irnet_discover_next_daddr(irnet_socket * self) /* The above request is non-blocking. * After a while, IrDA will call us back in irnet_discovervalue_confirm() * We will then call irnet_ias_to_tsap() and come back here again... */ - return(0); + return 0; } else - return(1); + return 1; } /*------------------------------------------------------------------*/ @@ -436,7 +436,7 @@ irnet_discover_daddr_and_lsap_sel(irnet_socket * self) /* Follow me in irnet_discovervalue_confirm() */ DEXIT(IRDA_SR_TRACE, "\n"); - return(0); + return 0; } /*------------------------------------------------------------------*/ @@ -485,7 +485,7 @@ irnet_dname_to_daddr(irnet_socket * self) /* No luck ! */ DEBUG(IRDA_SR_INFO, "cannot discover device ``%s'' !!!\n", self->rname); kfree(discoveries); - return(-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; } @@ -527,7 +527,7 @@ irda_irnet_create(irnet_socket * self) INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect); DEXIT(IRDA_SOCK_TRACE, "\n"); - return(0); + return 0; } /*------------------------------------------------------------------*/ @@ -601,7 +601,7 @@ irda_irnet_connect(irnet_socket * self) * We will finish the connection procedure in irnet_connect_tsap(). */ DEXIT(IRDA_SOCK_TRACE, "\n"); - return(0); + return 0; } /*------------------------------------------------------------------*/ @@ -733,7 +733,7 @@ irnet_daddr_to_dname(irnet_socket * self) /* No luck ! */ DEXIT(IRDA_SERV_INFO, ": cannot discover device 0x%08x !!!\n", self->daddr); kfree(discoveries); - return(-EADDRNOTAVAIL); + return -EADDRNOTAVAIL; } /*------------------------------------------------------------------*/ diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index dfe7b38dd4afc9e91bb9455ef5ff4bffeeae931a..0993bd454ea5811b3b72a66e33a49a1288ea7c04 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c @@ -166,7 +166,7 @@ irnet_ctrl_write(irnet_socket * ap, } /* Success : we have parsed all commands successfully */ - return(count); + return count; } #ifdef INITIAL_DISCOVERY @@ -300,7 +300,7 @@ irnet_ctrl_read(irnet_socket * ap, } DEXIT(CTRL_TRACE, "\n"); - return(strlen(event)); + return strlen(event); } #endif /* INITIAL_DISCOVERY */ @@ -409,7 +409,7 @@ irnet_ctrl_read(irnet_socket * ap, } DEXIT(CTRL_TRACE, "\n"); - return(strlen(event)); + return strlen(event); } /*------------------------------------------------------------------*/ @@ -480,7 +480,6 @@ dev_irnet_open(struct inode * inode, ap = kzalloc(sizeof(*ap), GFP_KERNEL); DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n"); - lock_kernel(); /* initialize the irnet structure */ ap->file = file; @@ -502,18 +501,20 @@ dev_irnet_open(struct inode * inode, { DERROR(FS_ERROR, "Can't setup IrDA link...\n"); kfree(ap); - unlock_kernel(); + return err; } /* For the control channel */ ap->event_index = irnet_events.index; /* Cancel all past events */ + mutex_init(&ap->lock); + /* Put our stuff where we will be able to find it later */ file->private_data = ap; DEXIT(FS_TRACE, " - ap=0x%p\n", ap); - unlock_kernel(); + return 0; } @@ -623,7 +624,7 @@ dev_irnet_poll(struct file * file, mask |= irnet_ctrl_poll(ap, file, wait); DEXIT(FS_TRACE, " - mask=0x%X\n", mask); - return(mask); + return mask; } /*------------------------------------------------------------------*/ @@ -664,7 +665,9 @@ dev_irnet_ioctl( { DEBUG(FS_INFO, "Entering PPP discipline.\n"); /* PPP channel setup (ap->chan in configued in dev_irnet_open())*/ - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + err = ppp_register_channel(&ap->chan); if(err == 0) { @@ -677,14 +680,17 @@ dev_irnet_ioctl( } else DERROR(FS_ERROR, "Can't setup PPP channel...\n"); - unlock_kernel(); + + mutex_unlock(&ap->lock); } else { /* In theory, should be N_TTY */ DEBUG(FS_INFO, "Exiting PPP discipline.\n"); /* Disconnect from the generic PPP layer */ - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + if(ap->ppp_open) { ap->ppp_open = 0; @@ -693,24 +699,31 @@ dev_irnet_ioctl( else DERROR(FS_ERROR, "Channel not registered !\n"); err = 0; - unlock_kernel(); + + mutex_unlock(&ap->lock); } break; /* Query PPP channel and unit number */ case PPPIOCGCHAN: - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + if(ap->ppp_open && !put_user(ppp_channel_index(&ap->chan), (int __user *)argp)) err = 0; - unlock_kernel(); + + mutex_unlock(&ap->lock); break; case PPPIOCGUNIT: - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + if(ap->ppp_open && !put_user(ppp_unit_number(&ap->chan), (int __user *)argp)) err = 0; - unlock_kernel(); + + mutex_unlock(&ap->lock); break; /* All these ioctls can be passed both directly and from ppp_generic, @@ -730,9 +743,12 @@ dev_irnet_ioctl( if(!capable(CAP_NET_ADMIN)) err = -EPERM; else { - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + err = ppp_irnet_ioctl(&ap->chan, cmd, arg); - unlock_kernel(); + + mutex_unlock(&ap->lock); } break; @@ -740,7 +756,9 @@ dev_irnet_ioctl( /* Get termios */ case TCGETS: DEBUG(FS_INFO, "Get termios.\n"); - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + #ifndef TCGETS2 if(!kernel_termios_to_user_termios((struct termios __user *)argp, &ap->termios)) err = 0; @@ -748,12 +766,15 @@ dev_irnet_ioctl( if(kernel_termios_to_user_termios_1((struct termios __user *)argp, &ap->termios)) err = 0; #endif - unlock_kernel(); + + mutex_unlock(&ap->lock); break; /* Set termios */ case TCSETSF: DEBUG(FS_INFO, "Set termios.\n"); - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; + #ifndef TCGETS2 if(!user_termios_to_kernel_termios(&ap->termios, (struct termios __user *)argp)) err = 0; @@ -761,7 +782,8 @@ dev_irnet_ioctl( if(!user_termios_to_kernel_termios_1(&ap->termios, (struct termios __user *)argp)) err = 0; #endif - unlock_kernel(); + + mutex_unlock(&ap->lock); break; /* Set DTR/RTS */ @@ -784,9 +806,10 @@ dev_irnet_ioctl( * We should also worry that we don't accept junk here and that * we get rid of our own buffers */ #ifdef FLUSH_TO_PPP - lock_kernel(); + if (mutex_lock_interruptible(&ap->lock)) + return -EINTR; ppp_output_wakeup(&ap->chan); - unlock_kernel(); + mutex_unlock(&ap->lock); #endif /* FLUSH_TO_PPP */ err = 0; break; diff --git a/net/irda/irnet/irnet_ppp.h b/net/irda/irnet/irnet_ppp.h index b5df2418f90c42b3ced4c1917ccf1e71b45c55f1..940225866da09a6133af23d0c776928a37daf7dd 100644 --- a/net/irda/irnet/irnet_ppp.h +++ b/net/irda/irnet/irnet_ppp.h @@ -103,7 +103,8 @@ static const struct file_operations irnet_device_fops = .poll = dev_irnet_poll, .unlocked_ioctl = dev_irnet_ioctl, .open = dev_irnet_open, - .release = dev_irnet_close + .release = dev_irnet_close, + .llseek = noop_llseek, /* Also : llseek, readdir, mmap, flush, fsync, fasync, lock, readv, writev */ }; diff --git a/net/irda/parameters.c b/net/irda/parameters.c index fc1a20565e2d7ab3cbef897ac4ed2d5793189a62..71cd38c1a67fcfe241215effff78efba06be966c 100644 --- a/net/irda/parameters.c +++ b/net/irda/parameters.c @@ -298,6 +298,8 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, p.pi = pi; /* In case handler needs to know */ p.pl = buf[1]; /* Extract length of value */ + if (p.pl > 32) + p.pl = 32; IRDA_DEBUG(2, "%s(), pi=%#x, pl=%d\n", __func__, p.pi, p.pl); @@ -318,7 +320,7 @@ static int irda_extract_string(void *self, __u8 *buf, int len, __u8 pi, (__u8) str[0], (__u8) str[1]); /* Null terminate string */ - str[p.pl+1] = '\0'; + str[p.pl] = '\0'; p.pv.c = str; /* Handler will need to take a copy */ diff --git a/net/key/af_key.c b/net/key/af_key.c index 43040e97c474b54dc36cfdc635b2639c28766c74..d87c22df6f1eb3e7f7d8daa3704a612f9e032179 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -565,12 +565,12 @@ pfkey_proto2satype(uint16_t proto) static uint8_t pfkey_proto_to_xfrm(uint8_t proto) { - return (proto == IPSEC_PROTO_ANY ? 0 : proto); + return proto == IPSEC_PROTO_ANY ? 0 : proto; } static uint8_t pfkey_proto_from_xfrm(uint8_t proto) { - return (proto ? proto : IPSEC_PROTO_ANY); + return proto ? proto : IPSEC_PROTO_ANY; } static inline int pfkey_sockaddr_len(sa_family_t family) diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 1ae697681bc735f3f4ed8cf98f9f63745157be36..8d9ce0accc98229e8255853e18b18c2ea4a2d410 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -144,7 +144,6 @@ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, nf_reset(skb); if (dev_forward_skb(dev, skb) == NET_RX_SUCCESS) { - dev->last_rx = jiffies; dev->stats.rx_packets++; dev->stats.rx_bytes += data_len; } else diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 226a0ae3bcfd7891775ec83c7035d99e2539923f..1c770c0644d1a3111eddbac4463ecd8bd4821850 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -65,9 +65,7 @@ static struct sock *__l2tp_ip_bind_lookup(struct net *net, __be32 laddr, int dif continue; if ((l2tp->conn_id == tunnel_id) && -#ifdef CONFIG_NET_NS - (sk->sk_net == net) && -#endif + net_eq(sock_net(sk), net) && !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) && !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)) goto found; diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index ff954b3e94b6b3d6daab8bf7a538c15101bad782..39a21d0c61c48f2506bc7d24e7eeeee1610a11ae 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c @@ -1768,7 +1768,7 @@ static const struct proto_ops pppol2tp_ops = { .ioctl = pppox_ioctl, }; -static struct pppox_proto pppol2tp_proto = { +static const struct pppox_proto pppol2tp_proto = { .create = pppol2tp_create, .ioctl = pppol2tp_ioctl }; diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index a87cb3ba2df6eeb146a94a4aba539e99b20b5889..d2b03e0851ef6502f6eeb3064ea93db8e31e7977 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c @@ -138,10 +138,8 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) struct crypto_cipher *tfm; tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - return NULL; - - crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN); + if (!IS_ERR(tfm)) + crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN); return tfm; } diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c index 3d097b3d7b62ad86c94a86eec92a3b9b3554c526..b4d66cca76d6d719324cee76d2706881df69e4a0 100644 --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c @@ -119,10 +119,8 @@ struct crypto_cipher * ieee80211_aes_cmac_key_setup(const u8 key[]) struct crypto_cipher *tfm; tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(tfm)) - return NULL; - - crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN); + if (!IS_ERR(tfm)) + crypto_cipher_setkey(tfm, key, AES_CMAC_KEY_LEN); return tfm; } diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 965b272499fd7616e4df039e3c878dda678f5cf9..720b7a84af590f0660d4862c717113daaf0c65af 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -56,7 +56,7 @@ static void ieee80211_free_tid_rx(struct rcu_head *h) } void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, - u16 initiator, u16 reason) + u16 initiator, u16 reason, bool tx) { struct ieee80211_local *local = sta->local; struct tid_ampdu_rx *tid_rx; @@ -81,20 +81,21 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, "aggregation for tid %d\n", tid); /* check if this is a self generated aggregation halt */ - if (initiator == WLAN_BACK_RECIPIENT) + if (initiator == WLAN_BACK_RECIPIENT && tx) ieee80211_send_delba(sta->sdata, sta->sta.addr, tid, 0, reason); del_timer_sync(&tid_rx->session_timer); + del_timer_sync(&tid_rx->reorder_timer); call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); } void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, - u16 initiator, u16 reason) + u16 initiator, u16 reason, bool tx) { mutex_lock(&sta->ampdu_mlme.mtx); - ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason); + ___ieee80211_stop_rx_ba_session(sta, tid, initiator, reason, tx); mutex_unlock(&sta->ampdu_mlme.mtx); } @@ -120,6 +121,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); } +static void sta_rx_agg_reorder_timer_expired(unsigned long data) +{ + u8 *ptid = (u8 *)data; + u8 *timer_to_id = ptid - *ptid; + struct sta_info *sta = container_of(timer_to_id, struct sta_info, + timer_to_tid[0]); + + rcu_read_lock(); + spin_lock(&sta->lock); + ieee80211_release_reorder_timeout(sta, *ptid); + spin_unlock(&sta->lock); + rcu_read_unlock(); +} + static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid, u8 dialog_token, u16 status, u16 policy, u16 buf_size, u16 timeout) @@ -251,11 +266,18 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, goto end; } + spin_lock_init(&tid_agg_rx->reorder_lock); + /* rx timer */ tid_agg_rx->session_timer.function = sta_rx_agg_session_timer_expired; tid_agg_rx->session_timer.data = (unsigned long)&sta->timer_to_tid[tid]; init_timer(&tid_agg_rx->session_timer); + /* rx reorder timer */ + tid_agg_rx->reorder_timer.function = sta_rx_agg_reorder_timer_expired; + tid_agg_rx->reorder_timer.data = (unsigned long)&sta->timer_to_tid[tid]; + init_timer(&tid_agg_rx->reorder_timer); + /* prepare reordering buffer */ tid_agg_rx->reorder_buf = kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC); diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 8f23401832b7729d28c9e0791a78ce8acd797728..d4679b265ba88698298a403dac25392b61dc04e7 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -145,7 +145,8 @@ static void kfree_tid_tx(struct rcu_head *rcu_head) } int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, - enum ieee80211_back_parties initiator) + enum ieee80211_back_parties initiator, + bool tx) { struct ieee80211_local *local = sta->local; struct tid_ampdu_tx *tid_tx = sta->ampdu_mlme.tid_tx[tid]; @@ -185,6 +186,7 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state); tid_tx->stop_initiator = initiator; + tid_tx->tx_stop = tx; ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_TX_STOP, @@ -577,13 +579,14 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, - enum ieee80211_back_parties initiator) + enum ieee80211_back_parties initiator, + bool tx) { int ret; mutex_lock(&sta->ampdu_mlme.mtx); - ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); + ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator, tx); mutex_unlock(&sta->ampdu_mlme.mtx); @@ -672,7 +675,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) goto unlock_sta; } - if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR) + if (tid_tx->stop_initiator == WLAN_BACK_INITIATOR && tid_tx->tx_stop) ieee80211_send_delba(sta->sdata, ra, tid, WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); @@ -772,7 +775,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, sta->ampdu_mlme.addba_req_num[tid] = 0; } else { - ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); + ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR, + true); } out: diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 29ac8e1a509e48ec1170f61f668d8d3d5712d501..18bd0e550600fccac46a106d3f29ffd7d609ce5b 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -19,33 +19,6 @@ #include "rate.h" #include "mesh.h" -static bool nl80211_type_check(enum nl80211_iftype type) -{ - switch (type) { - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_MONITOR: -#ifdef CONFIG_MAC80211_MESH - case NL80211_IFTYPE_MESH_POINT: -#endif - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_WDS: - return true; - default: - return false; - } -} - -static bool nl80211_params_check(enum nl80211_iftype type, - struct vif_params *params) -{ - if (!nl80211_type_check(type)) - return false; - - return true; -} - static int ieee80211_add_iface(struct wiphy *wiphy, char *name, enum nl80211_iftype type, u32 *flags, struct vif_params *params) @@ -55,9 +28,6 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name, struct ieee80211_sub_if_data *sdata; int err; - if (!nl80211_params_check(type, params)) - return -EINVAL; - err = ieee80211_if_add(local, name, &dev, type, params); if (err || type != NL80211_IFTYPE_MONITOR || !flags) return err; @@ -82,12 +52,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); int ret; - if (ieee80211_sdata_running(sdata)) - return -EBUSY; - - if (!nl80211_params_check(type, params)) - return -EINVAL; - ret = ieee80211_if_change_type(sdata, type); if (ret) return ret; @@ -104,54 +68,71 @@ static int ieee80211_change_iface(struct wiphy *wiphy, params && params->use_4addr >= 0) sdata->u.mgd.use_4addr = params->use_4addr; - if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) - sdata->u.mntr_flags = *flags; + if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) { + struct ieee80211_local *local = sdata->local; + + if (ieee80211_sdata_running(sdata)) { + /* + * Prohibit MONITOR_FLAG_COOK_FRAMES to be + * changed while the interface is up. + * Else we would need to add a lot of cruft + * to update everything: + * cooked_mntrs, monitor and all fif_* counters + * reconfigure hardware + */ + if ((*flags & MONITOR_FLAG_COOK_FRAMES) != + (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) + return -EBUSY; + + ieee80211_adjust_monitor_flags(sdata, -1); + sdata->u.mntr_flags = *flags; + ieee80211_adjust_monitor_flags(sdata, 1); + + ieee80211_configure_filter(local); + } else { + /* + * Because the interface is down, ieee80211_do_stop + * and ieee80211_do_open take care of "everything" + * mentioned in the comment above. + */ + sdata->u.mntr_flags = *flags; + } + } return 0; } static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr, + u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params) { - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct sta_info *sta = NULL; - enum ieee80211_key_alg alg; struct ieee80211_key *key; int err; - if (!netif_running(dev)) + if (!ieee80211_sdata_running(sdata)) return -ENETDOWN; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - + /* reject WEP and TKIP keys if WEP failed to initialize */ switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - alg = ALG_WEP; - break; case WLAN_CIPHER_SUITE_TKIP: - alg = ALG_TKIP; - break; - case WLAN_CIPHER_SUITE_CCMP: - alg = ALG_CCMP; - break; - case WLAN_CIPHER_SUITE_AES_CMAC: - alg = ALG_AES_CMAC; + case WLAN_CIPHER_SUITE_WEP104: + if (IS_ERR(sdata->local->wep_tx_tfm)) + return -EINVAL; break; default: - return -EINVAL; + break; } - /* reject WEP and TKIP keys if WEP failed to initialize */ - if ((alg == ALG_WEP || alg == ALG_TKIP) && - IS_ERR(sdata->local->wep_tx_tfm)) - return -EINVAL; + key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len, + params->key, params->seq_len, params->seq); + if (IS_ERR(key)) + return PTR_ERR(key); - key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key, - params->seq_len, params->seq); - if (!key) - return -ENOMEM; + if (pairwise) + key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; mutex_lock(&sdata->local->sta_mtx); @@ -164,9 +145,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, } } - ieee80211_key_link(key, sdata, sta); + err = ieee80211_key_link(key, sdata, sta); + if (err) + ieee80211_key_free(sdata->local, key); - err = 0; out_unlock: mutex_unlock(&sdata->local->sta_mtx); @@ -174,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr) + u8 key_idx, bool pairwise, const u8 *mac_addr) { struct ieee80211_sub_if_data *sdata; struct sta_info *sta; @@ -191,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, if (!sta) goto out_unlock; - if (sta->key) { - ieee80211_key_free(sdata->local, sta->key); - WARN_ON(sta->key); - ret = 0; + if (pairwise) { + if (sta->ptk) { + ieee80211_key_free(sdata->local, sta->ptk); + ret = 0; + } + } else { + if (sta->gtk[key_idx]) { + ieee80211_key_free(sdata->local, + sta->gtk[key_idx]); + ret = 0; + } } goto out_unlock; @@ -216,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, } static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, - u8 key_idx, const u8 *mac_addr, void *cookie, + u8 key_idx, bool pairwise, const u8 *mac_addr, + void *cookie, void (*callback)(void *cookie, struct key_params *params)) { @@ -224,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, struct sta_info *sta = NULL; u8 seq[6] = {0}; struct key_params params; - struct ieee80211_key *key; + struct ieee80211_key *key = NULL; u32 iv32; u16 iv16; int err = -ENOENT; @@ -238,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, if (!sta) goto out; - key = sta->key; + if (pairwise) + key = sta->ptk; + else if (key_idx < NUM_DEFAULT_KEYS) + key = sta->gtk[key_idx]; } else key = sdata->keys[key_idx]; @@ -247,10 +240,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, memset(¶ms, 0, sizeof(params)); - switch (key->conf.alg) { - case ALG_TKIP: - params.cipher = WLAN_CIPHER_SUITE_TKIP; + params.cipher = key->conf.cipher; + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_TKIP: iv32 = key->u.tkip.tx.iv32; iv16 = key->u.tkip.tx.iv16; @@ -268,8 +261,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, params.seq = seq; params.seq_len = 6; break; - case ALG_CCMP: - params.cipher = WLAN_CIPHER_SUITE_CCMP; + case WLAN_CIPHER_SUITE_CCMP: seq[0] = key->u.ccmp.tx_pn[5]; seq[1] = key->u.ccmp.tx_pn[4]; seq[2] = key->u.ccmp.tx_pn[3]; @@ -279,14 +271,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, params.seq = seq; params.seq_len = 6; break; - case ALG_WEP: - if (key->conf.keylen == 5) - params.cipher = WLAN_CIPHER_SUITE_WEP40; - else - params.cipher = WLAN_CIPHER_SUITE_WEP104; - break; - case ALG_AES_CMAC: - params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; + case WLAN_CIPHER_SUITE_AES_CMAC: seq[0] = key->u.aes_cmac.tx_pn[5]; seq[1] = key->u.aes_cmac.tx_pn[4]; seq[2] = key->u.aes_cmac.tx_pn[3]; @@ -342,13 +327,19 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) STATION_INFO_TX_BYTES | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS | - STATION_INFO_TX_BITRATE; + STATION_INFO_TX_RETRIES | + STATION_INFO_TX_FAILED | + STATION_INFO_TX_BITRATE | + STATION_INFO_RX_DROP_MISC; sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); sinfo->rx_bytes = sta->rx_bytes; sinfo->tx_bytes = sta->tx_bytes; sinfo->rx_packets = sta->rx_packets; sinfo->tx_packets = sta->tx_packets; + sinfo->tx_retries = sta->tx_retry_count; + sinfo->tx_failed = sta->tx_retry_failed; + sinfo->rx_dropped_misc = sta->rx_dropped; if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { @@ -634,6 +625,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, struct sta_info *sta, struct station_parameters *params) { + unsigned long flags; u32 rates; int i, j; struct ieee80211_supported_band *sband; @@ -642,7 +634,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, sband = local->hw.wiphy->bands[local->oper_channel->band]; - spin_lock_bh(&sta->lock); + spin_lock_irqsave(&sta->flaglock, flags); mask = params->sta_flags_mask; set = params->sta_flags_set; @@ -669,7 +661,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, if (set & BIT(NL80211_STA_FLAG_MFP)) sta->flags |= WLAN_STA_MFP; } - spin_unlock_bh(&sta->lock); + spin_unlock_irqrestore(&sta->flaglock, flags); /* * cfg80211 validates this (1-2007) and allows setting the AID @@ -1143,9 +1135,9 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, p.uapsd = false; if (drv_conf_tx(local, params->queue, &p)) { - printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", - wiphy_name(local->hw.wiphy), params->queue); + wiphy_debug(local->hw.wiphy, + "failed to set TX queue parameters for queue %d\n", + params->queue); return -EINVAL; } @@ -1207,15 +1199,26 @@ static int ieee80211_scan(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_scan_request *req) { - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->vif.type != NL80211_IFTYPE_STATION && - sdata->vif.type != NL80211_IFTYPE_ADHOC && - sdata->vif.type != NL80211_IFTYPE_MESH_POINT && - (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon)) + switch (ieee80211_vif_type_p2p(&sdata->vif)) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_MESH_POINT: + case NL80211_IFTYPE_P2P_CLIENT: + break; + case NL80211_IFTYPE_P2P_GO: + if (sdata->local->ops->hw_scan) + break; + /* FIXME: implement NoA while scanning in software */ + return -EOPNOTSUPP; + case NL80211_IFTYPE_AP: + if (sdata->u.ap.beacon) + return -EOPNOTSUPP; + break; + default: return -EOPNOTSUPP; + } return ieee80211_request_scan(sdata, req); } @@ -1362,7 +1365,7 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm) } static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, - u8 *addr) + const u8 *addr) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -1411,7 +1414,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, if (!sdata->u.mgd.associated || sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { mutex_lock(&sdata->local->iflist_mtx); - ieee80211_recalc_smps(sdata->local, sdata); + ieee80211_recalc_smps(sdata->local); mutex_unlock(&sdata->local->iflist_mtx); return 0; } @@ -1541,11 +1544,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); } -static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, - const u8 *buf, size_t len, u64 *cookie) +static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; @@ -1566,7 +1569,11 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, switch (sdata->vif.type) { case NL80211_IFTYPE_ADHOC: - if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: + if (!ieee80211_is_action(mgmt->frame_control) || + mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) break; rcu_read_lock(); sta = sta_info_get(sdata, mgmt->da); @@ -1575,8 +1582,7 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, return -ENOLINK; break; case NL80211_IFTYPE_STATION: - if (!(sdata->u.mgd.flags & IEEE80211_STA_MFP_ENABLED)) - flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + case NL80211_IFTYPE_P2P_CLIENT: break; default: return -EOPNOTSUPP; @@ -1598,6 +1604,23 @@ static int ieee80211_action(struct wiphy *wiphy, struct net_device *dev, return 0; } +static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, + struct net_device *dev, + u16 frame_type, bool reg) +{ + struct ieee80211_local *local = wiphy_priv(wiphy); + + if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) + return; + + if (reg) + local->probe_req_reg++; + else + local->probe_req_reg--; + + ieee80211_queue_work(&local->hw, &local->reconfig_filter); +} + struct cfg80211_ops mac80211_config_ops = { .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface, @@ -1647,6 +1670,7 @@ struct cfg80211_ops mac80211_config_ops = { .set_bitrate_mask = ieee80211_set_bitrate_mask, .remain_on_channel = ieee80211_remain_on_channel, .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, - .action = ieee80211_action, + .mgmt_tx = ieee80211_mgmt_tx, .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, + .mgmt_frame_register = ieee80211_mgmt_frame_register, }; diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 32be11e4c4d92dbe9d34d8cae84d7e0a482e8882..5b24740fc0b0698c65cc1141c981631160a1efc8 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -11,7 +11,7 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local, { struct ieee80211_sub_if_data *sdata; - WARN_ON(!mutex_is_locked(&local->iflist_mtx)); + lockdep_assert_held(&local->iflist_mtx); list_for_each_entry(sdata, &local->interfaces, list) { if (sdata == ignore) diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index b8b0ae79a74390568707a29b5a98747f5573e1fa..18260aa99c56f40c509616276029cd7d55f4753d 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -86,13 +86,15 @@ static ssize_t tsf_write(struct file *file, if (strncmp(buf, "reset", 5) == 0) { if (local->ops->reset_tsf) { drv_reset_tsf(local); - printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy)); + wiphy_info(local->hw.wiphy, "debugfs reset TSF\n"); } } else { tsf = simple_strtoul(buf, NULL, 0); if (local->ops->set_tsf) { drv_set_tsf(local, tsf); - printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf); + wiphy_info(local->hw.wiphy, + "debugfs set TSF to %#018llx\n", tsf); + } } @@ -375,7 +377,6 @@ void debugfs_hw_add(struct ieee80211_local *local) if (!phyd) return; - local->debugfs.stations = debugfs_create_dir("stations", phyd); local->debugfs.keys = debugfs_create_dir("keys", phyd); DEBUGFS_ADD(frequency); diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 7cd8dd9fc240ee027795a550d89ede7f0d66f3b4..4aa47d074a7964cd8e47f85d1f003c393a9efe24 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c @@ -66,26 +66,13 @@ static ssize_t key_algorithm_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos) { - char *alg; + char buf[15]; struct ieee80211_key *key = file->private_data; + u32 c = key->conf.cipher; - switch (key->conf.alg) { - case ALG_WEP: - alg = "WEP\n"; - break; - case ALG_TKIP: - alg = "TKIP\n"; - break; - case ALG_CCMP: - alg = "CCMP\n"; - break; - case ALG_AES_CMAC: - alg = "AES-128-CMAC\n"; - break; - default: - return 0; - } - return simple_read_from_buffer(userbuf, count, ppos, alg, strlen(alg)); + sprintf(buf, "%.2x-%.2x-%.2x:%d\n", + c >> 24, (c >> 16) & 0xff, (c >> 8) & 0xff, c & 0xff); + return simple_read_from_buffer(userbuf, count, ppos, buf, strlen(buf)); } KEY_OPS(algorithm); @@ -97,21 +84,22 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, int len; struct ieee80211_key *key = file->private_data; - switch (key->conf.alg) { - case ALG_WEP: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: len = scnprintf(buf, sizeof(buf), "\n"); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: len = scnprintf(buf, sizeof(buf), "%08x %04x\n", key->u.tkip.tx.iv32, key->u.tkip.tx.iv16); break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: tpn = key->u.ccmp.tx_pn; len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: tpn = key->u.aes_cmac.tx_pn; len = scnprintf(buf, sizeof(buf), "%02x%02x%02x%02x%02x%02x\n", tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], @@ -132,11 +120,12 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, int i, len; const u8 *rpn; - switch (key->conf.alg) { - case ALG_WEP: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: len = scnprintf(buf, sizeof(buf), "\n"); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: for (i = 0; i < NUM_RX_DATA_QUEUES; i++) p += scnprintf(p, sizeof(buf)+buf-p, "%08x %04x\n", @@ -144,7 +133,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, key->u.tkip.rx[i].iv16); len = p - buf; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: for (i = 0; i < NUM_RX_DATA_QUEUES + 1; i++) { rpn = key->u.ccmp.rx_pn[i]; p += scnprintf(p, sizeof(buf)+buf-p, @@ -154,7 +143,7 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, } len = p - buf; break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: rpn = key->u.aes_cmac.rx_pn; p += scnprintf(p, sizeof(buf)+buf-p, "%02x%02x%02x%02x%02x%02x\n", @@ -176,11 +165,11 @@ static ssize_t key_replays_read(struct file *file, char __user *userbuf, char buf[20]; int len; - switch (key->conf.alg) { - case ALG_CCMP: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_CCMP: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.ccmp.replays); break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.aes_cmac.replays); break; @@ -198,8 +187,8 @@ static ssize_t key_icverrors_read(struct file *file, char __user *userbuf, char buf[20]; int len; - switch (key->conf.alg) { - case ALG_AES_CMAC: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_AES_CMAC: len = scnprintf(buf, sizeof(buf), "%u\n", key->u.aes_cmac.icverrors); break; diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 8ad33eef7dda460155901f611f082af4060c34ca..cbdf36d7841cf022432f4bf9b1188cc1789a8f7f 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c @@ -410,6 +410,9 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) sprintf(buf, "netdev:%s", sdata->name); sdata->debugfs.dir = debugfs_create_dir(buf, sdata->local->hw.wiphy->debugfsdir); + if (sdata->debugfs.dir) + sdata->debugfs.subdir_stations = debugfs_create_dir("stations", + sdata->debugfs.dir); add_files(sdata); } diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 6a8fdc372c43e2ff236da5423a58ab5f74dd8e8a..4601fea1784dd7404b2d91c2635b211453e9e0c6 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -198,7 +198,8 @@ static ssize_t sta_agg_status_write(struct file *file, const char __user *userbu else ret = ieee80211_stop_tx_ba_session(&sta->sta, tid); } else { - __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); + __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, + 3, true); ret = 0; } @@ -302,7 +303,7 @@ STA_OPS(ht_capa); void ieee80211_sta_debugfs_add(struct sta_info *sta) { - struct dentry *stations_dir = sta->local->debugfs.stations; + struct dentry *stations_dir = sta->sdata->debugfs.subdir_stations; u8 mac[3*ETH_ALEN]; sta->debugfs.add_has_run = true; diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 14123dce544bf960a57d6f06fdbda6bbcc83f88a..16983825f8e856c3bfcf83c9afe5aa25673b0a70 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -54,6 +54,20 @@ static inline int drv_add_interface(struct ieee80211_local *local, return ret; } +static inline int drv_change_interface(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + enum nl80211_iftype type, bool p2p) +{ + int ret; + + might_sleep(); + + trace_drv_change_interface(local, sdata, type, p2p); + ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); + trace_drv_return_int(local, ret); + return ret; +} + static inline void drv_remove_interface(struct ieee80211_local *local, struct ieee80211_vif *vif) { diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 5d5d2a97466837b75b14961bc3b14a48bd5d488e..6831fb1641c8a375d64059a4f83ae6eee2d631eb 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h @@ -25,12 +25,14 @@ static inline void trace_ ## name(proto) {} #define STA_PR_FMT " sta:%pM" #define STA_PR_ARG __entry->sta_addr -#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ +#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ + __field(bool, p2p) \ __string(vif_name, sdata->dev ? sdata->dev->name : "") -#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ +#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ + __entry->p2p = sdata->vif.p2p; \ __assign_str(vif_name, sdata->dev ? sdata->dev->name : "") -#define VIF_PR_FMT " vif:%s(%d)" -#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type +#define VIF_PR_FMT " vif:%s(%d%s)" +#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" /* * Tracing for driver callbacks. @@ -136,6 +138,34 @@ TRACE_EVENT(drv_add_interface, ) ); +TRACE_EVENT(drv_change_interface, + TP_PROTO(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + enum nl80211_iftype type, bool p2p), + + TP_ARGS(local, sdata, type, p2p), + + TP_STRUCT__entry( + LOCAL_ENTRY + VIF_ENTRY + __field(u32, new_type) + __field(bool, new_p2p) + ), + + TP_fast_assign( + LOCAL_ASSIGN; + VIF_ASSIGN; + __entry->new_type = type; + __entry->new_p2p = p2p; + ), + + TP_printk( + LOCAL_PR_FMT VIF_PR_FMT " new type:%d%s", + LOCAL_PR_ARG, VIF_PR_ARG, __entry->new_type, + __entry->new_p2p ? "/p2p" : "" + ) +); + TRACE_EVENT(drv_remove_interface, TP_PROTO(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata), @@ -336,7 +366,7 @@ TRACE_EVENT(drv_set_key, LOCAL_ENTRY VIF_ENTRY STA_ENTRY - __field(enum ieee80211_key_alg, alg) + __field(u32, cipher) __field(u8, hw_key_idx) __field(u8, flags) __field(s8, keyidx) @@ -346,7 +376,7 @@ TRACE_EVENT(drv_set_key, LOCAL_ASSIGN; VIF_ASSIGN; STA_ASSIGN; - __entry->alg = key->alg; + __entry->cipher = key->cipher; __entry->flags = key->flags; __entry->keyidx = key->keyidx; __entry->hw_key_idx = key->hw_key_idx; diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 9d101fb33861f67ce1c9058b60f680709ca2d27c..75d679d75e63e92143d55a47601a1dfc1377ba03 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -101,16 +101,16 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, ht_cap->mcs.rx_mask[32/8] |= 1; } -void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta) +void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx) { int i; cancel_work_sync(&sta->ampdu_mlme.work); for (i = 0; i < STA_TID_NUM; i++) { - __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR); + __ieee80211_stop_tx_ba_session(sta, i, WLAN_BACK_INITIATOR, tx); __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, - WLAN_REASON_QSTA_LEAVE_QBSS); + WLAN_REASON_QSTA_LEAVE_QBSS, tx); } } @@ -135,7 +135,7 @@ void ieee80211_ba_session_work(struct work_struct *work) if (test_and_clear_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired)) ___ieee80211_stop_rx_ba_session( sta, tid, WLAN_BACK_RECIPIENT, - WLAN_REASON_QSTA_TIMEOUT); + WLAN_REASON_QSTA_TIMEOUT, true); tid_tx = sta->ampdu_mlme.tid_tx[tid]; if (!tid_tx) @@ -146,7 +146,8 @@ void ieee80211_ba_session_work(struct work_struct *work) else if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state)) ___ieee80211_stop_tx_ba_session(sta, tid, - WLAN_BACK_INITIATOR); + WLAN_BACK_INITIATOR, + true); } mutex_unlock(&sta->ampdu_mlme.mtx); } @@ -214,9 +215,11 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, #endif /* CONFIG_MAC80211_HT_DEBUG */ if (initiator == WLAN_BACK_INITIATOR) - __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0); + __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, + true); else - __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT); + __ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, + true); } int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, @@ -265,3 +268,33 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, return 0; } + +void ieee80211_request_smps_work(struct work_struct *work) +{ + struct ieee80211_sub_if_data *sdata = + container_of(work, struct ieee80211_sub_if_data, + u.mgd.request_smps_work); + + mutex_lock(&sdata->u.mgd.mtx); + __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); + mutex_unlock(&sdata->u.mgd.mtx); +} + +void ieee80211_request_smps(struct ieee80211_vif *vif, + enum ieee80211_smps_mode smps_mode) +{ + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + + if (WARN_ON(vif->type != NL80211_IFTYPE_STATION)) + return; + + if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) + smps_mode = IEEE80211_SMPS_AUTOMATIC; + + sdata->u.mgd.driver_smps_mode = smps_mode; + + ieee80211_queue_work(&sdata->local->hw, + &sdata->u.mgd.request_smps_work); +} +/* this might change ... don't want non-open drivers using it */ +EXPORT_SYMBOL_GPL(ieee80211_request_smps); diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index c691780725a7fcfbaef4ac39802540288696ee6a..ff60c022f51de8b4d2f7dd2e910aa6912a4e780c 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -173,6 +173,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, memcpy(skb_put(skb, ifibss->ie_len), ifibss->ie, ifibss->ie_len); + if (local->hw.queues >= 4) { + pos = skb_put(skb, 9); + *pos++ = WLAN_EID_VENDOR_SPECIFIC; + *pos++ = 7; /* len */ + *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ + *pos++ = 0x50; + *pos++ = 0xf2; + *pos++ = 2; /* WME */ + *pos++ = 0; /* WME info */ + *pos++ = 1; /* WME ver */ + *pos++ = 0; /* U-APSD no in use */ + } + rcu_assign_pointer(ifibss->presp, skb); sdata->vif.bss_conf.beacon_int = beacon_int; @@ -266,37 +279,45 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) return; - if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates && + if (sdata->vif.type == NL80211_IFTYPE_ADHOC && memcmp(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN) == 0) { - supp_rates = ieee80211_sta_get_rates(local, elems, band); rcu_read_lock(); - sta = sta_info_get(sdata, mgmt->sa); - if (sta) { - u32 prev_rates; - prev_rates = sta->sta.supp_rates[band]; - /* make sure mandatory rates are always added */ - sta->sta.supp_rates[band] = supp_rates | - ieee80211_mandatory_rates(local, band); + if (elems->supp_rates) { + supp_rates = ieee80211_sta_get_rates(local, elems, + band); + if (sta) { + u32 prev_rates; + + prev_rates = sta->sta.supp_rates[band]; + /* make sure mandatory rates are always added */ + sta->sta.supp_rates[band] = supp_rates | + ieee80211_mandatory_rates(local, band); - if (sta->sta.supp_rates[band] != prev_rates) { + if (sta->sta.supp_rates[band] != prev_rates) { #ifdef CONFIG_MAC80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: updated supp_rates set " - "for %pM based on beacon/probe_response " - "(0x%x -> 0x%x)\n", - sdata->name, sta->sta.addr, - prev_rates, sta->sta.supp_rates[band]); + printk(KERN_DEBUG + "%s: updated supp_rates set " + "for %pM based on beacon" + "/probe_resp (0x%x -> 0x%x)\n", + sdata->name, sta->sta.addr, + prev_rates, + sta->sta.supp_rates[band]); #endif - rate_control_rate_init(sta); - } - rcu_read_unlock(); - } else { - rcu_read_unlock(); - ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, - supp_rates, GFP_KERNEL); + rate_control_rate_init(sta); + } + } else + sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, + mgmt->sa, supp_rates, + GFP_ATOMIC); } + + if (sta && elems->wmm_info) + set_sta_flags(sta, WLAN_STA_WME); + + rcu_read_unlock(); } bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems, @@ -427,8 +448,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, return NULL; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n", - wiphy_name(local->hw.wiphy), addr, sdata->name); + wiphy_debug(local->hw.wiphy, "Adding new IBSS station %pM (dev=%s)\n", + addr, sdata->name); #endif sta = sta_info_alloc(sdata, addr, gfp); @@ -920,12 +941,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); sdata->u.ibss.ssid_len = params->ssid_len; + mutex_unlock(&sdata->u.ibss.mtx); + + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); ieee80211_queue_work(&sdata->local->hw, &sdata->work); - mutex_unlock(&sdata->u.ibss.mtx); - return 0; } @@ -980,7 +1003,9 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_unlock(&sdata->u.ibss.mtx); + mutex_lock(&local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&local->mtx); return 0; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 65e0ed6c29753c07084e9a884868df2bd40f2474..b80c386899276dd436ebc93caab1957622389be5 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -50,12 +50,6 @@ struct ieee80211_local; * increased memory use (about 2 kB of RAM per entry). */ #define IEEE80211_FRAGMENT_MAX 4 -/* - * Time after which we ignore scan results and no longer report/use - * them in any way. - */ -#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) - #define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) #define IEEE80211_DEFAULT_UAPSD_QUEUES \ @@ -165,12 +159,37 @@ typedef unsigned __bitwise__ ieee80211_rx_result; #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) #define RX_QUEUED ((__force ieee80211_rx_result) 3u) -#define IEEE80211_RX_IN_SCAN BIT(0) -/* frame is destined to interface currently processed (incl. multicast frames) */ -#define IEEE80211_RX_RA_MATCH BIT(1) -#define IEEE80211_RX_AMSDU BIT(2) -#define IEEE80211_RX_FRAGMENTED BIT(3) -/* only add flags here that do not change with subframes of an aMPDU */ +/** + * enum ieee80211_packet_rx_flags - packet RX flags + * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed + * (incl. multicast frames) + * @IEEE80211_RX_IN_SCAN: received while scanning + * @IEEE80211_RX_FRAGMENTED: fragmented frame + * @IEEE80211_RX_AMSDU: a-MSDU packet + * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed + * + * These are per-frame flags that are attached to a frame in the + * @rx_flags field of &struct ieee80211_rx_status. + */ +enum ieee80211_packet_rx_flags { + IEEE80211_RX_IN_SCAN = BIT(0), + IEEE80211_RX_RA_MATCH = BIT(1), + IEEE80211_RX_FRAGMENTED = BIT(2), + IEEE80211_RX_AMSDU = BIT(3), + IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), +}; + +/** + * enum ieee80211_rx_flags - RX data flags + * + * @IEEE80211_RX_CMNTR: received on cooked monitor already + * + * These flags are used across handling multiple interfaces + * for a single frame. + */ +enum ieee80211_rx_flags { + IEEE80211_RX_CMNTR = BIT(0), +}; struct ieee80211_rx_data { struct sk_buff *skb; @@ -343,10 +362,14 @@ struct ieee80211_if_managed { unsigned long timers_running; /* used for quiesce/restart */ bool powersave; /* powersave requested for this iface */ enum ieee80211_smps_mode req_smps, /* requested smps mode */ - ap_smps; /* smps mode AP thinks we're in */ + ap_smps, /* smps mode AP thinks we're in */ + driver_smps_mode; /* smps mode request */ + + struct work_struct request_smps_work; unsigned int flags; + bool beacon_crc_valid; u32 beacon_crc; enum { @@ -370,6 +393,13 @@ struct ieee80211_if_managed { */ int ave_beacon_signal; + /* + * Number of Beacon frames used in ave_beacon_signal. This can be used + * to avoid generating less reliable cqm events that would be based + * only on couple of received frames. + */ + unsigned int count_beacon_signal; + /* * Last Beacon frame signal strength average (ave_beacon_signal / 16) * that triggered a cqm event. 0 indicates that no event has been @@ -474,6 +504,19 @@ enum ieee80211_sub_if_data_flags { IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), }; +/** + * enum ieee80211_sdata_state_bits - virtual interface state bits + * @SDATA_STATE_RUNNING: virtual interface is up & running; this + * mirrors netif_running() but is separate for interface type + * change handling while the interface is up + * @SDATA_STATE_OFFCHANNEL: This interface is currently in offchannel + * mode, so queues are stopped + */ +enum ieee80211_sdata_state_bits { + SDATA_STATE_RUNNING, + SDATA_STATE_OFFCHANNEL, +}; + struct ieee80211_sub_if_data { struct list_head list; @@ -487,6 +530,8 @@ struct ieee80211_sub_if_data { unsigned int flags; + unsigned long state; + int drop_unencrypted; char name[IFNAMSIZ]; @@ -497,17 +542,20 @@ struct ieee80211_sub_if_data { */ bool ht_opmode_valid; + /* to detect idle changes */ + bool old_idle; + /* Fragment table for host-based reassembly */ struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; unsigned int fragment_next; -#define NUM_DEFAULT_KEYS 4 -#define NUM_DEFAULT_MGMT_KEYS 2 struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; struct ieee80211_key *default_key; struct ieee80211_key *default_mgmt_key; u16 sequence_number; + __be16 control_port_protocol; + bool control_port_no_encrypt; struct work_struct work; struct sk_buff_head skb_queue; @@ -539,6 +587,7 @@ struct ieee80211_sub_if_data { #ifdef CONFIG_MAC80211_DEBUGFS struct { struct dentry *dir; + struct dentry *subdir_stations; struct dentry *default_key; struct dentry *default_mgmt_key; } debugfs; @@ -595,11 +644,17 @@ enum queue_stop_reason { * determine if we are on the operating channel or not * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, * gets only set in conjunction with SCAN_SW_SCANNING + * @SCAN_COMPLETED: Set for our scan work function when the driver reported + * that the scan completed. + * @SCAN_ABORTED: Set for our scan work function when the driver reported + * a scan complete for an aborted scan. */ enum { SCAN_SW_SCANNING, SCAN_HW_SCANNING, SCAN_OFF_CHANNEL, + SCAN_COMPLETED, + SCAN_ABORTED, }; /** @@ -634,7 +689,6 @@ struct ieee80211_local { /* * work stuff, potentially off-channel (in the future) */ - struct mutex work_mtx; struct list_head work_list; struct timer_list work_timer; struct work_struct work_work; @@ -653,9 +707,13 @@ struct ieee80211_local { int open_count; int monitors, cooked_mntrs; /* number of interfaces with corresponding FIF_ flags */ - int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; + int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll, + fif_probe_req; + int probe_req_reg; unsigned int filter_flags; /* FIF_* */ + bool wiphy_ciphers_allocated; + /* protects the aggregated multicast list and filter calls */ spinlock_t filter_lock; @@ -746,9 +804,10 @@ struct ieee80211_local { */ struct mutex key_mtx; + /* mutex for scan and work locking */ + struct mutex mtx; /* Scanning and BSS list */ - struct mutex scan_mtx; unsigned long scanning; struct cfg80211_ssid scan_ssid; struct cfg80211_scan_request *int_scan_req; @@ -866,10 +925,14 @@ struct ieee80211_local { #ifdef CONFIG_MAC80211_DEBUGFS struct local_debugfsdentries { struct dentry *rcdir; - struct dentry *stations; struct dentry *keys; } debugfs; #endif + + /* dummy netdev for use w/ NAPI */ + struct net_device napi_dev; + + struct napi_struct napi; }; static inline struct ieee80211_sub_if_data * @@ -1003,6 +1066,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata); void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); +void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata); +void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); /* IBSS code */ void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); @@ -1068,10 +1133,12 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); void ieee80211_remove_interfaces(struct ieee80211_local *local); u32 __ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_recalc_idle(struct ieee80211_local *local); +void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, + const int offset); static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata) { - return netif_running(sdata->dev); + return test_bit(SDATA_STATE_RUNNING, &sdata->state); } /* tx handling */ @@ -1105,12 +1172,13 @@ void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps, const u8 *da, const u8 *bssid); +void ieee80211_request_smps_work(struct work_struct *work); void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, - u16 initiator, u16 reason); + u16 initiator, u16 reason, bool stop); void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, - u16 initiator, u16 reason); -void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); + u16 initiator, u16 reason, bool stop); +void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, bool tx); void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct ieee80211_mgmt *mgmt, size_t len); @@ -1124,13 +1192,16 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, size_t len); int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, - enum ieee80211_back_parties initiator); + enum ieee80211_back_parties initiator, + bool tx); int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, - enum ieee80211_back_parties initiator); + enum ieee80211_back_parties initiator, + bool tx); void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); void ieee80211_ba_session_work(struct work_struct *work); void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); +void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); /* Spectrum management */ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, @@ -1146,6 +1217,12 @@ int __ieee80211_suspend(struct ieee80211_hw *hw); static inline int __ieee80211_resume(struct ieee80211_hw *hw) { + struct ieee80211_local *local = hw_to_local(hw); + + WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), + "%s: resume with hardware scan still in progress\n", + wiphy_name(hw->wiphy)); + return ieee80211_reconfig(hw_to_local(hw)); } #else @@ -1208,7 +1285,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, const u8 *key, u8 key_len, u8 key_idx); int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, const u8 *ie, size_t ie_len, - enum ieee80211_band band); + enum ieee80211_band band, u32 rate_mask, + u8 channel); void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, const u8 *ssid, size_t ssid_len, const u8 *ie, size_t ie_len); @@ -1221,8 +1299,7 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local, enum ieee80211_band band); int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, enum ieee80211_smps_mode smps_mode); -void ieee80211_recalc_smps(struct ieee80211_local *local, - struct ieee80211_sub_if_data *forsdata); +void ieee80211_recalc_smps(struct ieee80211_local *local); size_t ieee80211_ie_split(const u8 *ies, size_t ielen, const u8 *ids, int n_ids, size_t offset); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index ebbe264e2b0bc659b0e1303bcec285c87158df9f..f9163b12c7f17aca87970366d3069f563b8a6655 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -24,6 +24,7 @@ #include "led.h" #include "driver-ops.h" #include "wme.h" +#include "rate.h" /** * DOC: Interface list locking @@ -94,21 +95,14 @@ static inline int identical_mac_addr_allowed(int type1, int type2) type2 == NL80211_IFTYPE_AP_VLAN)); } -static int ieee80211_open(struct net_device *dev) +static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, + enum nl80211_iftype iftype) { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_sub_if_data *nsdata; struct ieee80211_local *local = sdata->local; - struct sta_info *sta; - u32 changed = 0; - int res; - u32 hw_reconf_flags = 0; - u8 null_addr[ETH_ALEN] = {0}; + struct ieee80211_sub_if_data *nsdata; + struct net_device *dev = sdata->dev; - /* fail early if user set an invalid address */ - if (compare_ether_addr(dev->dev_addr, null_addr) && - !is_valid_ether_addr(dev->dev_addr)) - return -EADDRNOTAVAIL; + ASSERT_RTNL(); /* we hold the RTNL here so can safely walk the list */ list_for_each_entry(nsdata, &local->interfaces, list) { @@ -125,7 +119,7 @@ static int ieee80211_open(struct net_device *dev) * belonging to the same hardware. Then, however, we're * faced with having to adopt two different TSF timers... */ - if (sdata->vif.type == NL80211_IFTYPE_ADHOC && + if (iftype == NL80211_IFTYPE_ADHOC && nsdata->vif.type == NL80211_IFTYPE_ADHOC) return -EBUSY; @@ -139,19 +133,56 @@ static int ieee80211_open(struct net_device *dev) /* * check whether it may have the same address */ - if (!identical_mac_addr_allowed(sdata->vif.type, + if (!identical_mac_addr_allowed(iftype, nsdata->vif.type)) return -ENOTUNIQ; /* * can only add VLANs to enabled APs */ - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && + if (iftype == NL80211_IFTYPE_AP_VLAN && nsdata->vif.type == NL80211_IFTYPE_AP) sdata->bss = &nsdata->u.ap; } } + return 0; +} + +void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, + const int offset) +{ + struct ieee80211_local *local = sdata->local; + u32 flags = sdata->u.mntr_flags; + +#define ADJUST(_f, _s) do { \ + if (flags & MONITOR_FLAG_##_f) \ + local->fif_##_s += offset; \ + } while (0) + + ADJUST(FCSFAIL, fcsfail); + ADJUST(PLCPFAIL, plcpfail); + ADJUST(CONTROL, control); + ADJUST(CONTROL, pspoll); + ADJUST(OTHER_BSS, other_bss); + +#undef ADJUST +} + +/* + * NOTE: Be very careful when changing this function, it must NOT return + * an error on interface type changes that have been pre-checked, so most + * checks should be in ieee80211_check_concurrent_iface. + */ +static int ieee80211_do_open(struct net_device *dev, bool coming_up) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + u32 changed = 0; + int res; + u32 hw_reconf_flags = 0; + switch (sdata->vif.type) { case NL80211_IFTYPE_WDS: if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) @@ -177,7 +208,9 @@ static int ieee80211_open(struct net_device *dev) /* no special treatment */ break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: /* cannot happen */ WARN_ON(1); break; @@ -187,39 +220,30 @@ static int ieee80211_open(struct net_device *dev) res = drv_start(local); if (res) goto err_del_bss; + if (local->ops->napi_poll) + napi_enable(&local->napi); /* we're brought up, everything changes */ hw_reconf_flags = ~0; ieee80211_led_radio(local, true); } /* - * Check all interfaces and copy the hopefully now-present - * MAC address to those that have the special null one. + * Copy the hopefully now-present MAC address to + * this interface, if it has the special null one. */ - list_for_each_entry(nsdata, &local->interfaces, list) { - struct net_device *ndev = nsdata->dev; - - /* - * No need to check running since we do not allow - * it to start up with this invalid address. - */ - if (compare_ether_addr(null_addr, ndev->dev_addr) == 0) { - memcpy(ndev->dev_addr, - local->hw.wiphy->perm_addr, - ETH_ALEN); - memcpy(ndev->perm_addr, ndev->dev_addr, ETH_ALEN); + if (is_zero_ether_addr(dev->dev_addr)) { + memcpy(dev->dev_addr, + local->hw.wiphy->perm_addr, + ETH_ALEN); + memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); + + if (!is_valid_ether_addr(dev->dev_addr)) { + if (!local->open_count) + drv_stop(local); + return -EADDRNOTAVAIL; } } - /* - * Validate the MAC address for this device. - */ - if (!is_valid_ether_addr(dev->dev_addr)) { - if (!local->open_count) - drv_stop(local); - return -EADDRNOTAVAIL; - } - switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: /* no need to tell driver */ @@ -237,25 +261,17 @@ static int ieee80211_open(struct net_device *dev) hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; } - if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) - local->fif_fcsfail++; - if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) - local->fif_plcpfail++; - if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { - local->fif_control++; - local->fif_pspoll++; - } - if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) - local->fif_other_bss++; - + ieee80211_adjust_monitor_flags(sdata, 1); ieee80211_configure_filter(local); netif_carrier_on(dev); break; default: - res = drv_add_interface(local, &sdata->vif); - if (res) - goto err_stop; + if (coming_up) { + res = drv_add_interface(local, &sdata->vif); + if (res) + goto err_stop; + } if (ieee80211_vif_is_mesh(&sdata->vif)) { local->fif_other_bss++; @@ -264,8 +280,11 @@ static int ieee80211_open(struct net_device *dev) ieee80211_start_mesh(sdata); } else if (sdata->vif.type == NL80211_IFTYPE_AP) { local->fif_pspoll++; + local->fif_probe_req++; ieee80211_configure_filter(local); + } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { + local->fif_probe_req++; } changed |= ieee80211_reset_erp_info(sdata); @@ -277,6 +296,8 @@ static int ieee80211_open(struct net_device *dev) netif_carrier_on(dev); } + set_bit(SDATA_STATE_RUNNING, &sdata->state); + if (sdata->vif.type == NL80211_IFTYPE_WDS) { /* Create STA entry for the WDS peer */ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, @@ -294,6 +315,8 @@ static int ieee80211_open(struct net_device *dev) /* STA has been freed */ goto err_del_interface; } + + rate_control_rate_init(sta); } /* @@ -307,9 +330,13 @@ static int ieee80211_open(struct net_device *dev) if (sdata->flags & IEEE80211_SDATA_PROMISC) atomic_inc(&local->iff_promiscs); + mutex_lock(&local->mtx); hw_reconf_flags |= __ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); + + if (coming_up) + local->open_count++; - local->open_count++; if (hw_reconf_flags) { ieee80211_hw_config(local, hw_reconf_flags); /* @@ -334,22 +361,42 @@ static int ieee80211_open(struct net_device *dev) sdata->bss = NULL; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) list_del(&sdata->u.vlan.list); + clear_bit(SDATA_STATE_RUNNING, &sdata->state); return res; } -static int ieee80211_stop(struct net_device *dev) +static int ieee80211_open(struct net_device *dev) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + int err; + + /* fail early if user set an invalid address */ + if (!is_zero_ether_addr(dev->dev_addr) && + !is_valid_ether_addr(dev->dev_addr)) + return -EADDRNOTAVAIL; + + err = ieee80211_check_concurrent_iface(sdata, sdata->vif.type); + if (err) + return err; + + return ieee80211_do_open(dev, true); +} + +static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, + bool going_down) +{ struct ieee80211_local *local = sdata->local; unsigned long flags; struct sk_buff *skb, *tmp; u32 hw_reconf_flags = 0; int i; + clear_bit(SDATA_STATE_RUNNING, &sdata->state); + /* * Stop TX on this interface first. */ - netif_tx_stop_all_queues(dev); + netif_tx_stop_all_queues(sdata->dev); /* * Purge work for this interface. @@ -366,12 +413,9 @@ static int ieee80211_stop(struct net_device *dev) * (because if we remove a STA after ops->remove_interface() * the driver will have removed the vif info already!) * - * We could relax this and only unlink the stations from the - * hash table and list but keep them on a per-sdata list that - * will be inserted back again when the interface is brought - * up again, but I don't currently see a use case for that, - * except with WDS which gets a STA entry created when it is - * brought up. + * This is relevant only in AP, WDS and mesh modes, since in + * all other modes we've already removed all stations when + * disconnecting etc. */ sta_info_flush(local, sdata); @@ -387,14 +431,19 @@ static int ieee80211_stop(struct net_device *dev) if (sdata->flags & IEEE80211_SDATA_PROMISC) atomic_dec(&local->iff_promiscs); - if (sdata->vif.type == NL80211_IFTYPE_AP) + if (sdata->vif.type == NL80211_IFTYPE_AP) { local->fif_pspoll--; + local->fif_probe_req--; + } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { + local->fif_probe_req--; + } - netif_addr_lock_bh(dev); + netif_addr_lock_bh(sdata->dev); spin_lock_bh(&local->filter_lock); - __hw_addr_unsync(&local->mc_list, &dev->mc, dev->addr_len); + __hw_addr_unsync(&local->mc_list, &sdata->dev->mc, + sdata->dev->addr_len); spin_unlock_bh(&local->filter_lock); - netif_addr_unlock_bh(dev); + netif_addr_unlock_bh(sdata->dev); ieee80211_configure_filter(local); @@ -406,11 +455,21 @@ static int ieee80211_stop(struct net_device *dev) struct ieee80211_sub_if_data *vlan, *tmpsdata; struct beacon_data *old_beacon = sdata->u.ap.beacon; + /* sdata_running will return false, so this will disable */ + ieee80211_bss_info_change_notify(sdata, + BSS_CHANGED_BEACON_ENABLED); + /* remove beacon */ rcu_assign_pointer(sdata->u.ap.beacon, NULL); synchronize_rcu(); kfree(old_beacon); + /* free all potentially still buffered bcast frames */ + while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { + local->total_ps_buffered--; + dev_kfree_skb(skb); + } + /* down all dependent devices, that is VLANs */ list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, u.vlan.list) @@ -418,7 +477,8 @@ static int ieee80211_stop(struct net_device *dev) WARN_ON(!list_empty(&sdata->u.ap.vlans)); } - local->open_count--; + if (going_down) + local->open_count--; switch (sdata->vif.type) { case NL80211_IFTYPE_AP_VLAN: @@ -437,40 +497,9 @@ static int ieee80211_stop(struct net_device *dev) hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; } - if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) - local->fif_fcsfail--; - if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) - local->fif_plcpfail--; - if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) { - local->fif_pspoll--; - local->fif_control--; - } - if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) - local->fif_other_bss--; - + ieee80211_adjust_monitor_flags(sdata, -1); ieee80211_configure_filter(local); break; - case NL80211_IFTYPE_STATION: - del_timer_sync(&sdata->u.mgd.chswitch_timer); - del_timer_sync(&sdata->u.mgd.timer); - del_timer_sync(&sdata->u.mgd.conn_mon_timer); - del_timer_sync(&sdata->u.mgd.bcn_mon_timer); - /* - * If any of the timers fired while we waited for it, it will - * have queued its work. Now the work will be running again - * but will not rearm the timer again because it checks - * whether the interface is running, which, at this point, - * it no longer is. - */ - cancel_work_sync(&sdata->u.mgd.chswitch_work); - cancel_work_sync(&sdata->u.mgd.monitor_work); - cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work); - - /* fall through */ - case NL80211_IFTYPE_ADHOC: - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - del_timer_sync(&sdata->u.ibss.timer); - /* fall through */ case NL80211_IFTYPE_MESH_POINT: if (ieee80211_vif_is_mesh(&sdata->vif)) { /* other_bss and allmulti are always set on mesh @@ -498,27 +527,34 @@ static int ieee80211_stop(struct net_device *dev) ieee80211_scan_cancel(local); /* - * Disable beaconing for AP and mesh, IBSS can't - * still be joined to a network at this point. + * Disable beaconing here for mesh only, AP and IBSS + * are already taken care of. */ - if (sdata->vif.type == NL80211_IFTYPE_AP || - sdata->vif.type == NL80211_IFTYPE_MESH_POINT) { + if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); - } - /* free all remaining keys, there shouldn't be any */ + /* + * Free all remaining keys, there shouldn't be any, + * except maybe group keys in AP more or WDS? + */ ieee80211_free_keys(sdata); - drv_remove_interface(local, &sdata->vif); + + if (going_down) + drv_remove_interface(local, &sdata->vif); } sdata->bss = NULL; + mutex_lock(&local->mtx); hw_reconf_flags |= __ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); ieee80211_recalc_ps(local, -1); if (local->open_count == 0) { + if (local->ops->napi_poll) + napi_disable(&local->napi); ieee80211_clear_tx_pending(local); ieee80211_stop_device(local); @@ -541,6 +577,13 @@ static int ieee80211_stop(struct net_device *dev) } } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); +} + +static int ieee80211_stop(struct net_device *dev) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + ieee80211_do_stop(sdata, true); return 0; } @@ -585,8 +628,6 @@ static void ieee80211_teardown_sdata(struct net_device *dev) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_local *local = sdata->local; - struct beacon_data *beacon; - struct sk_buff *skb; int flushed; int i; @@ -599,37 +640,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev) __skb_queue_purge(&sdata->fragments[i].skb_list); sdata->fragment_next = 0; - switch (sdata->vif.type) { - case NL80211_IFTYPE_AP: - beacon = sdata->u.ap.beacon; - rcu_assign_pointer(sdata->u.ap.beacon, NULL); - synchronize_rcu(); - kfree(beacon); - - while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) { - local->total_ps_buffered--; - dev_kfree_skb(skb); - } - - break; - case NL80211_IFTYPE_MESH_POINT: - if (ieee80211_vif_is_mesh(&sdata->vif)) - mesh_rmc_free(sdata); - break; - case NL80211_IFTYPE_ADHOC: - if (WARN_ON(sdata->u.ibss.presp)) - kfree_skb(sdata->u.ibss.presp); - break; - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_MONITOR: - break; - case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: - BUG(); - break; - } + if (ieee80211_vif_is_mesh(&sdata->vif)) + mesh_rmc_free(sdata); flushed = sta_info_flush(local, sdata); WARN_ON(flushed); @@ -791,7 +803,8 @@ static void ieee80211_iface_work(struct work_struct *work) __ieee80211_stop_rx_ba_session( sta, tid, WLAN_BACK_RECIPIENT, - WLAN_REASON_QSTA_REQUIRE_SETUP); + WLAN_REASON_QSTA_REQUIRE_SETUP, + true); } mutex_unlock(&local->sta_mtx); } else switch (sdata->vif.type) { @@ -844,9 +857,13 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, /* and set some type-dependent values */ sdata->vif.type = type; + sdata->vif.p2p = false; sdata->dev->netdev_ops = &ieee80211_dataif_ops; sdata->wdev.iftype = type; + sdata->control_port_protocol = cpu_to_be16(ETH_P_PAE); + sdata->control_port_no_encrypt = false; + /* only monitor differs */ sdata->dev->type = ARPHRD_ETHER; @@ -854,10 +871,20 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, INIT_WORK(&sdata->work, ieee80211_iface_work); switch (type) { + case NL80211_IFTYPE_P2P_GO: + type = NL80211_IFTYPE_AP; + sdata->vif.type = type; + sdata->vif.p2p = true; + /* fall through */ case NL80211_IFTYPE_AP: skb_queue_head_init(&sdata->u.ap.ps_bc_buf); INIT_LIST_HEAD(&sdata->u.ap.vlans); break; + case NL80211_IFTYPE_P2P_CLIENT: + type = NL80211_IFTYPE_STATION; + sdata->vif.type = type; + sdata->vif.p2p = true; + /* fall through */ case NL80211_IFTYPE_STATION: ieee80211_sta_setup_sdata(sdata); break; @@ -878,7 +905,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP_VLAN: break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: BUG(); break; } @@ -886,12 +913,85 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, ieee80211_debugfs_add_netdev(sdata); } +static int ieee80211_runtime_change_iftype(struct ieee80211_sub_if_data *sdata, + enum nl80211_iftype type) +{ + struct ieee80211_local *local = sdata->local; + int ret, err; + enum nl80211_iftype internal_type = type; + bool p2p = false; + + ASSERT_RTNL(); + + if (!local->ops->change_interface) + return -EBUSY; + + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + /* + * Could maybe also all others here? + * Just not sure how that interacts + * with the RX/config path e.g. for + * mesh. + */ + break; + default: + return -EBUSY; + } + + switch (type) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: + /* + * Could probably support everything + * but WDS here (WDS do_open can fail + * under memory pressure, which this + * code isn't prepared to handle). + */ + break; + case NL80211_IFTYPE_P2P_CLIENT: + p2p = true; + internal_type = NL80211_IFTYPE_STATION; + break; + case NL80211_IFTYPE_P2P_GO: + p2p = true; + internal_type = NL80211_IFTYPE_AP; + break; + default: + return -EBUSY; + } + + ret = ieee80211_check_concurrent_iface(sdata, internal_type); + if (ret) + return ret; + + ieee80211_do_stop(sdata, false); + + ieee80211_teardown_sdata(sdata->dev); + + ret = drv_change_interface(local, sdata, internal_type, p2p); + if (ret) + type = sdata->vif.type; + + ieee80211_setup_sdata(sdata, type); + + err = ieee80211_do_open(sdata->dev, false); + WARN(err, "type change: do_open returned %d", err); + + return ret; +} + int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type) { + int ret; + ASSERT_RTNL(); - if (type == sdata->vif.type) + if (type == ieee80211_vif_type_p2p(&sdata->vif)) return 0; /* Setting ad-hoc mode on non-IBSS channel is not supported. */ @@ -899,18 +999,15 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, type == NL80211_IFTYPE_ADHOC) return -EOPNOTSUPP; - /* - * We could, here, on changes between IBSS/STA/MESH modes, - * invoke an MLME function instead that disassociates etc. - * and goes into the requested mode. - */ - - if (ieee80211_sdata_running(sdata)) - return -EBUSY; - - /* Purge and reset type-dependent state. */ - ieee80211_teardown_sdata(sdata->dev); - ieee80211_setup_sdata(sdata, type); + if (ieee80211_sdata_running(sdata)) { + ret = ieee80211_runtime_change_iftype(sdata, type); + if (ret) + return ret; + } else { + /* Purge and reset type-dependent state. */ + ieee80211_teardown_sdata(sdata->dev); + ieee80211_setup_sdata(sdata, type); + } /* reset some values that shouldn't be kept across type changes */ sdata->vif.bss_conf.basic_rates = @@ -1167,8 +1264,7 @@ static u32 ieee80211_idle_off(struct ieee80211_local *local, return 0; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: device no longer idle - %s\n", - wiphy_name(local->hw.wiphy), reason); + wiphy_debug(local->hw.wiphy, "device no longer idle - %s\n", reason); #endif local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; @@ -1181,8 +1277,7 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) return 0; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: device now idle\n", - wiphy_name(local->hw.wiphy)); + wiphy_debug(local->hw.wiphy, "device now idle\n"); #endif drv_flush(local, false); @@ -1195,28 +1290,61 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; int count = 0; + bool working = false, scanning = false; + struct ieee80211_work *wk; - if (!list_empty(&local->work_list)) - return ieee80211_idle_off(local, "working"); - - if (local->scanning) - return ieee80211_idle_off(local, "scanning"); +#ifdef CONFIG_PROVE_LOCKING + WARN_ON(debug_locks && !lockdep_rtnl_is_held() && + !lockdep_is_held(&local->iflist_mtx)); +#endif + lockdep_assert_held(&local->mtx); list_for_each_entry(sdata, &local->interfaces, list) { - if (!ieee80211_sdata_running(sdata)) + if (!ieee80211_sdata_running(sdata)) { + sdata->vif.bss_conf.idle = true; continue; + } + + sdata->old_idle = sdata->vif.bss_conf.idle; + /* do not count disabled managed interfaces */ if (sdata->vif.type == NL80211_IFTYPE_STATION && - !sdata->u.mgd.associated) + !sdata->u.mgd.associated) { + sdata->vif.bss_conf.idle = true; continue; + } /* do not count unused IBSS interfaces */ if (sdata->vif.type == NL80211_IFTYPE_ADHOC && - !sdata->u.ibss.ssid_len) + !sdata->u.ibss.ssid_len) { + sdata->vif.bss_conf.idle = true; continue; + } /* count everything else */ count++; } + list_for_each_entry(wk, &local->work_list, list) { + working = true; + wk->sdata->vif.bss_conf.idle = false; + } + + if (local->scan_sdata) { + scanning = true; + local->scan_sdata->vif.bss_conf.idle = false; + } + + list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->old_idle == sdata->vif.bss_conf.idle) + continue; + if (!ieee80211_sdata_running(sdata)) + continue; + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); + } + + if (working) + return ieee80211_idle_off(local, "working"); + if (scanning) + return ieee80211_idle_off(local, "scanning"); if (!count) return ieee80211_idle_on(local); else diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 1b9d87ed143a1a3b3e46e31f5649ba67f68321b2..ccd676b2f5999b6779e02903b853e838c8836612 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c @@ -49,7 +49,7 @@ static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; static void assert_key_lock(struct ieee80211_local *local) { - WARN_ON(!mutex_is_locked(&local->key_mtx)); + lockdep_assert_held(&local->key_mtx); } static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) @@ -60,7 +60,7 @@ static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key) return NULL; } -static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) +static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) { struct ieee80211_sub_if_data *sdata; struct ieee80211_sta *sta; @@ -69,12 +69,20 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) might_sleep(); if (!key->local->ops->set_key) - return; + goto out_unsupported; assert_key_lock(key->local); sta = get_sta_for_key(key); + /* + * If this is a per-STA GTK, check if it + * is supported; if not, return. + */ + if (sta && !(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE) && + !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)) + goto out_unsupported; + sdata = key->sdata; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) sdata = container_of(sdata->bss, @@ -83,14 +91,28 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key) ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); - if (!ret) + if (!ret) { key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; + return 0; + } - if (ret && ret != -ENOSPC && ret != -EOPNOTSUPP) - printk(KERN_ERR "mac80211-%s: failed to set key " - "(%d, %pM) to hardware (%d)\n", - wiphy_name(key->local->hw.wiphy), - key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); + if (ret != -ENOSPC && ret != -EOPNOTSUPP) + wiphy_err(key->local->hw.wiphy, + "failed to set key (%d, %pM) to hardware (%d)\n", + key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); + + out_unsupported: + switch (key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: + case WLAN_CIPHER_SUITE_CCMP: + case WLAN_CIPHER_SUITE_AES_CMAC: + /* all of these we can do in software */ + return 0; + default: + return -EINVAL; + } } static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) @@ -121,14 +143,33 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) sta, &key->conf); if (ret) - printk(KERN_ERR "mac80211-%s: failed to remove key " - "(%d, %pM) from hardware (%d)\n", - wiphy_name(key->local->hw.wiphy), - key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); + wiphy_err(key->local->hw.wiphy, + "failed to remove key (%d, %pM) from hardware (%d)\n", + key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; } +void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) +{ + struct ieee80211_key *key; + + key = container_of(key_conf, struct ieee80211_key, conf); + + might_sleep(); + assert_key_lock(key->local); + + key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; + + /* + * Flush TX path to avoid attempts to use this key + * after this function returns. Until then, drivers + * must be prepared to handle the key. + */ + synchronize_rcu(); +} +EXPORT_SYMBOL_GPL(ieee80211_key_removed); + static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) { @@ -184,6 +225,7 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, + bool pairwise, struct ieee80211_key *old, struct ieee80211_key *new) { @@ -192,8 +234,14 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, if (new) list_add(&new->list, &sdata->key_list); - if (sta) { - rcu_assign_pointer(sta->key, new); + if (sta && pairwise) { + rcu_assign_pointer(sta->ptk, new); + } else if (sta) { + if (old) + idx = old->conf.keyidx; + else + idx = new->conf.keyidx; + rcu_assign_pointer(sta->gtk[idx], new); } else { WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx); @@ -227,20 +275,18 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, } } -struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, - int idx, - size_t key_len, +struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, const u8 *key_data, size_t seq_len, const u8 *seq) { struct ieee80211_key *key; - int i, j; + int i, j, err; BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS); key = kzalloc(sizeof(struct ieee80211_key) + key_len, GFP_KERNEL); if (!key) - return NULL; + return ERR_PTR(-ENOMEM); /* * Default to software encryption; we'll later upload the @@ -249,15 +295,16 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, key->conf.flags = 0; key->flags = 0; - key->conf.alg = alg; + key->conf.cipher = cipher; key->conf.keyidx = idx; key->conf.keylen = key_len; - switch (alg) { - case ALG_WEP: + switch (cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: key->conf.iv_len = WEP_IV_LEN; key->conf.icv_len = WEP_ICV_LEN; break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: key->conf.iv_len = TKIP_IV_LEN; key->conf.icv_len = TKIP_ICV_LEN; if (seq) { @@ -269,7 +316,7 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, } } break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: key->conf.iv_len = CCMP_HDR_LEN; key->conf.icv_len = CCMP_MIC_LEN; if (seq) { @@ -278,42 +325,38 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, key->u.ccmp.rx_pn[i][j] = seq[CCMP_PN_LEN - j - 1]; } - break; - case ALG_AES_CMAC: - key->conf.iv_len = 0; - key->conf.icv_len = sizeof(struct ieee80211_mmie); - if (seq) - for (j = 0; j < 6; j++) - key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1]; - break; - } - memcpy(key->conf.key, key_data, key_len); - INIT_LIST_HEAD(&key->list); - - if (alg == ALG_CCMP) { /* * Initialize AES key state here as an optimization so that * it does not need to be initialized for every packet. */ key->u.ccmp.tfm = ieee80211_aes_key_setup_encrypt(key_data); - if (!key->u.ccmp.tfm) { + if (IS_ERR(key->u.ccmp.tfm)) { + err = PTR_ERR(key->u.ccmp.tfm); kfree(key); - return NULL; + key = ERR_PTR(err); } - } - - if (alg == ALG_AES_CMAC) { + break; + case WLAN_CIPHER_SUITE_AES_CMAC: + key->conf.iv_len = 0; + key->conf.icv_len = sizeof(struct ieee80211_mmie); + if (seq) + for (j = 0; j < 6; j++) + key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1]; /* * Initialize AES key state here as an optimization so that * it does not need to be initialized for every packet. */ key->u.aes_cmac.tfm = ieee80211_aes_cmac_key_setup(key_data); - if (!key->u.aes_cmac.tfm) { + if (IS_ERR(key->u.aes_cmac.tfm)) { + err = PTR_ERR(key->u.aes_cmac.tfm); kfree(key); - return NULL; + key = ERR_PTR(err); } + break; } + memcpy(key->conf.key, key_data, key_len); + INIT_LIST_HEAD(&key->list); return key; } @@ -326,9 +369,9 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) if (key->local) ieee80211_key_disable_hw_accel(key); - if (key->conf.alg == ALG_CCMP) + if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP) ieee80211_aes_key_free(key->u.ccmp.tfm); - if (key->conf.alg == ALG_AES_CMAC) + if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); if (key->local) ieee80211_debugfs_key_remove(key); @@ -336,12 +379,13 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) kfree(key); } -void ieee80211_key_link(struct ieee80211_key *key, - struct ieee80211_sub_if_data *sdata, - struct sta_info *sta) +int ieee80211_key_link(struct ieee80211_key *key, + struct ieee80211_sub_if_data *sdata, + struct sta_info *sta) { struct ieee80211_key *old_key; - int idx; + int idx, ret; + bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; BUG_ON(!sdata); BUG_ON(!key); @@ -358,13 +402,6 @@ void ieee80211_key_link(struct ieee80211_key *key, */ if (test_sta_flags(sta, WLAN_STA_WME)) key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; - - /* - * This key is for a specific sta interface, - * inform the driver that it should try to store - * this key as pairwise key. - */ - key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; } else { if (sdata->vif.type == NL80211_IFTYPE_STATION) { struct sta_info *ap; @@ -386,19 +423,23 @@ void ieee80211_key_link(struct ieee80211_key *key, mutex_lock(&sdata->local->key_mtx); - if (sta) - old_key = sta->key; + if (sta && pairwise) + old_key = sta->ptk; + else if (sta) + old_key = sta->gtk[idx]; else old_key = sdata->keys[idx]; - __ieee80211_key_replace(sdata, sta, old_key, key); + __ieee80211_key_replace(sdata, sta, pairwise, old_key, key); __ieee80211_key_destroy(old_key); ieee80211_debugfs_key_add(key); - ieee80211_key_enable_hw_accel(key); + ret = ieee80211_key_enable_hw_accel(key); mutex_unlock(&sdata->local->key_mtx); + + return ret; } static void __ieee80211_key_free(struct ieee80211_key *key) @@ -408,7 +449,8 @@ static void __ieee80211_key_free(struct ieee80211_key *key) */ if (key->sdata) __ieee80211_key_replace(key->sdata, key->sta, - key, NULL); + key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE, + key, NULL); __ieee80211_key_destroy(key); } diff --git a/net/mac80211/key.h b/net/mac80211/key.h index b665bbb7a4711a7bcef6b7c27b41fd331d458d34..0db1c0f5f697fefd06b58766ec01d287a6cec95f 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h @@ -16,6 +16,9 @@ #include #include +#define NUM_DEFAULT_KEYS 4 +#define NUM_DEFAULT_MGMT_KEYS 2 + #define WEP_IV_LEN 4 #define WEP_ICV_LEN 4 #define ALG_TKIP_KEY_LEN 32 @@ -123,18 +126,16 @@ struct ieee80211_key { struct ieee80211_key_conf conf; }; -struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, - int idx, - size_t key_len, +struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, const u8 *key_data, size_t seq_len, const u8 *seq); /* * Insert a key into data structures (sdata, sta if necessary) * to make it used, free old key. */ -void ieee80211_key_link(struct ieee80211_key *key, - struct ieee80211_sub_if_data *sdata, - struct sta_info *sta); +int __must_check ieee80211_key_link(struct ieee80211_key *key, + struct ieee80211_sub_if_data *sdata, + struct sta_info *sta); void ieee80211_key_free(struct ieee80211_local *local, struct ieee80211_key *key); void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index ded5c3843e061a13e1d82be4666b746c829c467c..22bc42b18991c2c61c8562f8a5d841e53ed73e37 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local) if (local->monitors || local->scanning) new_flags |= FIF_BCN_PRBRESP_PROMISC; + if (local->fif_probe_req || local->probe_req_reg) + new_flags |= FIF_PROBE_REQ; + if (local->fif_fcsfail) new_flags |= FIF_FCSFAIL; @@ -99,16 +102,19 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) int ret = 0; int power; enum nl80211_channel_type channel_type; + u32 offchannel_flag; might_sleep(); scan_chan = local->scan_channel; + offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; if (scan_chan) { chan = scan_chan; channel_type = NL80211_CHAN_NO_HT; local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; - } else if (local->tmp_channel) { + } else if (local->tmp_channel && + local->oper_channel != local->tmp_channel) { chan = scan_chan = local->tmp_channel; channel_type = local->tmp_channel_type; local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; @@ -117,8 +123,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) channel_type = local->_oper_channel_type; local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; } + offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; - if (chan != local->hw.conf.channel || + if (offchannel_flag || chan != local->hw.conf.channel || channel_type != local->hw.conf.channel_type) { local->hw.conf.channel = chan; local->hw.conf.channel_type = channel_type; @@ -197,6 +204,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; else if (sdata->vif.type == NL80211_IFTYPE_AP) sdata->vif.bss_conf.bssid = sdata->vif.addr; + else if (sdata->vif.type == NL80211_IFTYPE_WDS) + sdata->vif.bss_conf.bssid = NULL; else if (ieee80211_vif_is_mesh(&sdata->vif)) { sdata->vif.bss_conf.bssid = zero; } else { @@ -207,6 +216,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, switch (sdata->vif.type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: break; default: @@ -291,7 +301,16 @@ static void ieee80211_restart_work(struct work_struct *work) struct ieee80211_local *local = container_of(work, struct ieee80211_local, restart_work); + /* wait for scan work complete */ + flush_workqueue(local->workqueue); + + mutex_lock(&local->mtx); + WARN(test_bit(SCAN_HW_SCANNING, &local->scanning), + "%s called with hardware scan in progress\n", __func__); + mutex_unlock(&local->mtx); + rtnl_lock(); + ieee80211_scan_cancel(local); ieee80211_reconfig(local); rtnl_unlock(); } @@ -302,7 +321,7 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) trace_api_restart_hw(local); - /* use this reason, __ieee80211_resume will unblock it */ + /* use this reason, ieee80211_reconfig will unblock it */ ieee80211_stop_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); @@ -316,7 +335,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work) container_of(work, struct ieee80211_local, recalc_smps); mutex_lock(&local->iflist_mtx); - ieee80211_recalc_smps(local, NULL); + ieee80211_recalc_smps(local); mutex_unlock(&local->iflist_mtx); } @@ -336,9 +355,6 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, struct ieee80211_if_managed *ifmgd; int c = 0; - if (!netif_running(ndev)) - return NOTIFY_DONE; - /* Make sure it's our interface that got changed */ if (!wdev) return NOTIFY_DONE; @@ -349,11 +365,14 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, sdata = IEEE80211_DEV_TO_SUB_IF(ndev); bss_conf = &sdata->vif.bss_conf; + if (!ieee80211_sdata_running(sdata)) + return NOTIFY_DONE; + /* ARP filtering is only supported in managed mode */ if (sdata->vif.type != NL80211_IFTYPE_STATION) return NOTIFY_DONE; - idev = sdata->dev->ip_ptr; + idev = __in_dev_get_rtnl(sdata->dev); if (!idev) return NOTIFY_DONE; @@ -390,6 +409,80 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, } #endif +static int ieee80211_napi_poll(struct napi_struct *napi, int budget) +{ + struct ieee80211_local *local = + container_of(napi, struct ieee80211_local, napi); + + return local->ops->napi_poll(&local->hw, budget); +} + +void ieee80211_napi_schedule(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + napi_schedule(&local->napi); +} +EXPORT_SYMBOL(ieee80211_napi_schedule); + +void ieee80211_napi_complete(struct ieee80211_hw *hw) +{ + struct ieee80211_local *local = hw_to_local(hw); + + napi_complete(&local->napi); +} +EXPORT_SYMBOL(ieee80211_napi_complete); + +/* There isn't a lot of sense in it, but you can transmit anything you like */ +static const struct ieee80211_txrx_stypes +ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_ADHOC] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4), + }, + [NL80211_IFTYPE_STATION] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4), + }, + [NL80211_IFTYPE_AP] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4), + }, + [NL80211_IFTYPE_AP_VLAN] = { + /* copy AP */ + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4), + }, + [NL80211_IFTYPE_P2P_CLIENT] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4), + }, + [NL80211_IFTYPE_P2P_GO] = { + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_DISASSOC >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4) | + BIT(IEEE80211_STYPE_DEAUTH >> 4) | + BIT(IEEE80211_STYPE_ACTION >> 4), + }, +}; + struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, const struct ieee80211_ops *ops) { @@ -419,6 +512,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, if (!wiphy) return NULL; + wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes; + wiphy->flags |= WIPHY_FLAG_NETNS_OK | WIPHY_FLAG_4ADDR_AP | WIPHY_FLAG_4ADDR_STATION; @@ -444,6 +539,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, /* set up some defaults */ local->hw.queues = 1; local->hw.max_rates = 1; + local->hw.max_report_rates = 0; local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; local->user_power_level = -1; @@ -455,7 +551,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, __hw_addr_init(&local->mc_list); mutex_init(&local->iflist_mtx); - mutex_init(&local->scan_mtx); + mutex_init(&local->mtx); mutex_init(&local->key_mtx); spin_lock_init(&local->filter_lock); @@ -494,6 +590,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, skb_queue_head_init(&local->skb_queue); skb_queue_head_init(&local->skb_queue_unreliable); + /* init dummy netdev for use w/ NAPI */ + init_dummy_netdev(&local->napi_dev); + return local_to_hw(local); } EXPORT_SYMBOL(ieee80211_alloc_hw); @@ -506,6 +605,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) int channels, max_bitrates; bool supp_ht; static const u32 cipher_suites[] = { + /* keep WEP first, it may be removed below */ WLAN_CIPHER_SUITE_WEP40, WLAN_CIPHER_SUITE_WEP104, WLAN_CIPHER_SUITE_TKIP, @@ -515,6 +615,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) WLAN_CIPHER_SUITE_AES_CMAC }; + if (hw->max_report_rates == 0) + hw->max_report_rates = hw->max_rates; + /* * generic code guarantees at least one band, * set this very early because much code assumes @@ -554,6 +657,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) /* mac80211 always supports monitor */ local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); +#ifndef CONFIG_MAC80211_MESH + /* mesh depends on Kconfig, but drivers should set it if they want */ + local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT); +#endif + + /* mac80211 supports control port protocol changing */ + local->hw.wiphy->flags |= WIPHY_FLAG_CONTROL_PORT_PROTOCOL; + if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) @@ -589,10 +700,41 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->hw.wiphy->max_scan_ie_len) local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len; - local->hw.wiphy->cipher_suites = cipher_suites; - local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) - local->hw.wiphy->n_cipher_suites--; + /* Set up cipher suites unless driver already did */ + if (!local->hw.wiphy->cipher_suites) { + local->hw.wiphy->cipher_suites = cipher_suites; + local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE)) + local->hw.wiphy->n_cipher_suites--; + } + if (IS_ERR(local->wep_tx_tfm) || IS_ERR(local->wep_rx_tfm)) { + if (local->hw.wiphy->cipher_suites == cipher_suites) { + local->hw.wiphy->cipher_suites += 2; + local->hw.wiphy->n_cipher_suites -= 2; + } else { + u32 *suites; + int r, w = 0; + + /* Filter out WEP */ + + suites = kmemdup( + local->hw.wiphy->cipher_suites, + sizeof(u32) * local->hw.wiphy->n_cipher_suites, + GFP_KERNEL); + if (!suites) + return -ENOMEM; + for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { + u32 suite = local->hw.wiphy->cipher_suites[r]; + if (suite == WLAN_CIPHER_SUITE_WEP40 || + suite == WLAN_CIPHER_SUITE_WEP104) + continue; + suites[w++] = suite; + } + local->hw.wiphy->cipher_suites = suites; + local->hw.wiphy->n_cipher_suites = w; + local->wiphy_ciphers_allocated = true; + } + } result = wiphy_register(local->hw.wiphy); if (result < 0) @@ -641,16 +783,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) result = ieee80211_wep_init(local); if (result < 0) - printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n", - wiphy_name(local->hw.wiphy), result); + wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", + result); rtnl_lock(); result = ieee80211_init_rate_ctrl_alg(local, hw->rate_control_algorithm); if (result < 0) { - printk(KERN_DEBUG "%s: Failed to initialize rate control " - "algorithm\n", wiphy_name(local->hw.wiphy)); + wiphy_debug(local->hw.wiphy, + "Failed to initialize rate control algorithm\n"); goto fail_rate; } @@ -659,8 +801,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) result = ieee80211_if_add(local, "wlan%d", NULL, NL80211_IFTYPE_STATION, NULL); if (result) - printk(KERN_WARNING "%s: Failed to add default virtual iface\n", - wiphy_name(local->hw.wiphy)); + wiphy_warn(local->hw.wiphy, + "Failed to add default virtual iface\n"); } rtnl_unlock(); @@ -683,6 +825,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) goto fail_ifa; #endif + netif_napi_add(&local->napi_dev, &local->napi, ieee80211_napi_poll, + local->hw.napi_weight); + return 0; #ifdef CONFIG_INET @@ -703,6 +848,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) fail_workqueue: wiphy_unregister(local->hw.wiphy); fail_wiphy_register: + if (local->wiphy_ciphers_allocated) + kfree(local->hw.wiphy->cipher_suites); kfree(local->int_scan_req); return result; } @@ -738,6 +885,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) */ del_timer_sync(&local->work_timer); + cancel_work_sync(&local->restart_work); cancel_work_sync(&local->reconfig_filter); ieee80211_clear_tx_pending(local); @@ -746,8 +894,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) if (skb_queue_len(&local->skb_queue) || skb_queue_len(&local->skb_queue_unreliable)) - printk(KERN_WARNING "%s: skb_queue not empty\n", - wiphy_name(local->hw.wiphy)); + wiphy_warn(local->hw.wiphy, "skb_queue not empty\n"); skb_queue_purge(&local->skb_queue); skb_queue_purge(&local->skb_queue_unreliable); @@ -764,7 +911,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) struct ieee80211_local *local = hw_to_local(hw); mutex_destroy(&local->iflist_mtx); - mutex_destroy(&local->scan_mtx); + mutex_destroy(&local->mtx); + + if (local->wiphy_ciphers_allocated) + kfree(local->hw.wiphy->cipher_suites); wiphy_free(local->hw.wiphy); } diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index ea13a80a476c1fe0db6dc5e0059e2014f340926e..1c91f0f3c3079ba9f6a8d94097d6e637b948cdad 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m enum plink_event event; enum plink_frame_type ftype; size_t baselen; - bool deactivated; + bool deactivated, matches_local = true; u8 ie_len; u8 *baseaddr; __le16 plid, llid, reason; @@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m /* Now we will figure out the appropriate event... */ event = PLINK_UNDEFINED; if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { + matches_local = false; switch (ftype) { case PLINK_OPEN: event = OPN_RJCT; @@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m /* avoid warning */ break; } - spin_lock_bh(&sta->lock); + } + + if (!sta && !matches_local) { + rcu_read_unlock(); + reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION); + llid = 0; + mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid, + plid, reason); + return; } else if (!sta) { /* ftype == PLINK_OPEN */ u32 rates; @@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } event = OPN_ACPT; spin_lock_bh(&sta->lock); - } else { + } else if (matches_local) { spin_lock_bh(&sta->lock); switch (ftype) { case PLINK_OPEN: @@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m rcu_read_unlock(); return; } + } else { + spin_lock_bh(&sta->lock); } mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b6c163ac22da39fd3327a30f77478e27cb81756c..a3a9421555af30201e13d8ea24c36f4bb759680f 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -54,6 +54,12 @@ */ #define IEEE80211_SIGNAL_AVE_WEIGHT 3 +/* + * How many Beacon frames need to have been used in average signal strength + * before starting to indicate signal change events. + */ +#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 + #define TMR_RUNNING_TIMER 0 #define TMR_RUNNING_CHANSW 1 @@ -86,7 +92,7 @@ enum rx_mgmt_action { /* utils */ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd) { - WARN_ON(!mutex_is_locked(&ifmgd->mtx)); + lockdep_assert_held(&ifmgd->mtx); } /* @@ -109,7 +115,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd, mod_timer(&ifmgd->timer, timeout); } -static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) +void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) { if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) return; @@ -118,6 +124,19 @@ static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata) round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME)); } +void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + + if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) + return; + + mod_timer(&sdata->u.mgd.conn_mon_timer, + round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); + + ifmgd->probe_send_count = 0; +} + static int ecw2cw(int ecw) { return (1 << ecw) - 1; @@ -778,16 +797,17 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, params.uapsd = uapsd; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " - "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", - wiphy_name(local->hw.wiphy), queue, aci, acm, - params.aifs, params.cw_min, params.cw_max, params.txop, - params.uapsd); + wiphy_debug(local->hw.wiphy, + "WMM queue=%d aci=%d acm=%d aifs=%d " + "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", + queue, aci, acm, + params.aifs, params.cw_min, params.cw_max, + params.txop, params.uapsd); #endif if (drv_conf_tx(local, queue, ¶ms)) - printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", - wiphy_name(local->hw.wiphy), queue); + wiphy_debug(local->hw.wiphy, + "failed to set TX queue parameters for queue %d\n", + queue); } /* enable WMM or activate new settings */ @@ -860,14 +880,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | IEEE80211_STA_BEACON_POLL); - /* - * Always handle WMM once after association regardless - * of the first value the AP uses. Setting -1 here has - * that effect because the AP values is an unsigned - * 4-bit value. - */ - sdata->u.mgd.wmm_last_param_set = -1; - ieee80211_led_assoc(local, 1); if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) @@ -901,7 +913,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, mutex_lock(&local->iflist_mtx); ieee80211_recalc_ps(local, -1); - ieee80211_recalc_smps(local, sdata); + ieee80211_recalc_smps(local); mutex_unlock(&local->iflist_mtx); netif_tx_start_all_queues(sdata->dev); @@ -909,7 +921,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, } static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, - bool remove_sta) + bool remove_sta, bool tx) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_local *local = sdata->local; @@ -948,7 +960,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, sta = sta_info_get(sdata, bssid); if (sta) { set_sta_flags(sta, WLAN_STA_BLOCK_BA); - ieee80211_sta_tear_down_BA_sessions(sta); + ieee80211_sta_tear_down_BA_sessions(sta, tx); } mutex_unlock(&local->sta_mtx); @@ -990,6 +1002,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, if (remove_sta) sta_info_destroy_addr(sdata, bssid); + + del_timer_sync(&sdata->u.mgd.conn_mon_timer); + del_timer_sync(&sdata->u.mgd.bcn_mon_timer); + del_timer_sync(&sdata->u.mgd.timer); + del_timer_sync(&sdata->u.mgd.chswitch_timer); } void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, @@ -1006,21 +1023,26 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, if (is_multicast_ether_addr(hdr->addr1)) return; - if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) - return; - - mod_timer(&sdata->u.mgd.conn_mon_timer, - round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); + ieee80211_sta_reset_conn_monitor(sdata); } static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; const u8 *ssid; + u8 *dst = ifmgd->associated->bssid; + u8 unicast_limit = max(1, IEEE80211_MAX_PROBE_TRIES - 3); + + /* + * Try sending broadcast probe requests for the last three + * probe requests after the first ones failed since some + * buggy APs only support broadcast probe requests. + */ + if (ifmgd->probe_send_count >= unicast_limit) + dst = NULL; ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); - ieee80211_send_probe_req(sdata, ifmgd->associated->bssid, - ssid + 2, ssid[1], NULL, 0); + ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0); ifmgd->probe_send_count++; ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT; @@ -1102,9 +1124,12 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); - ieee80211_set_disassoc(sdata, true); - ieee80211_recalc_idle(local); + ieee80211_set_disassoc(sdata, true, true); mutex_unlock(&ifmgd->mtx); + + mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); /* * must be outside lock due to cfg80211, * but that's not a problem. @@ -1172,8 +1197,10 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", sdata->name, bssid, reason_code); - ieee80211_set_disassoc(sdata, true); + ieee80211_set_disassoc(sdata, true, false); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); return RX_MGMT_CFG80211_DEAUTH; } @@ -1202,8 +1229,10 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", sdata->name, mgmt->sa, reason_code); - ieee80211_set_disassoc(sdata, true); + ieee80211_set_disassoc(sdata, true, false); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); return RX_MGMT_CFG80211_DISASSOC; } @@ -1262,7 +1291,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, rates = 0; basic_rates = 0; - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + sband = local->hw.wiphy->bands[wk->chan->band]; for (i = 0; i < elems.supp_rates_len; i++) { int rate = (elems.supp_rates[i] & 0x7f) * 5; @@ -1298,11 +1327,11 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, } } - sta->sta.supp_rates[local->hw.conf.channel->band] = rates; + sta->sta.supp_rates[wk->chan->band] = rates; sdata->vif.bss_conf.basic_rates = basic_rates; /* cf. IEEE 802.11 9.2.12 */ - if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && + if (wk->chan->band == IEEE80211_BAND_2GHZ && have_higher_than_11mbit) sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE; else @@ -1330,6 +1359,14 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, return false; } + /* + * Always handle WMM once after association regardless + * of the first value the AP uses. Setting -1 here has + * that effect because the AP values is an unsigned + * 4-bit value. + */ + ifmgd->wmm_last_param_set = -1; + if (elems.wmm_param) ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, elems.wmm_param_len); @@ -1362,7 +1399,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk, * Also start the timer that will detect beacon loss. */ ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); - mod_beacon_timer(sdata); + ieee80211_sta_reset_beacon_monitor(sdata); return true; } @@ -1465,7 +1502,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, * we have or will be receiving any beacons or data, so let's * schedule the timers again, just in case. */ - mod_beacon_timer(sdata); + ieee80211_sta_reset_beacon_monitor(sdata); mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(jiffies + @@ -1540,15 +1577,18 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ifmgd->last_beacon_signal = rx_status->signal; if (ifmgd->flags & IEEE80211_STA_RESET_SIGNAL_AVE) { ifmgd->flags &= ~IEEE80211_STA_RESET_SIGNAL_AVE; - ifmgd->ave_beacon_signal = rx_status->signal; + ifmgd->ave_beacon_signal = rx_status->signal * 16; ifmgd->last_cqm_event_signal = 0; + ifmgd->count_beacon_signal = 1; } else { ifmgd->ave_beacon_signal = (IEEE80211_SIGNAL_AVE_WEIGHT * rx_status->signal * 16 + (16 - IEEE80211_SIGNAL_AVE_WEIGHT) * ifmgd->ave_beacon_signal) / 16; + ifmgd->count_beacon_signal++; } if (bss_conf->cqm_rssi_thold && + ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { int sig = ifmgd->ave_beacon_signal / 16; int last_event = ifmgd->last_cqm_event_signal; @@ -1588,7 +1628,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, * Push the beacon loss detection into the future since * we are processing a beacon from the AP just now. */ - mod_beacon_timer(sdata); + ieee80211_sta_reset_beacon_monitor(sdata); ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, @@ -1599,7 +1639,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, ifmgd->aid); - if (ncrc != ifmgd->beacon_crc) { + if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) { ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true); @@ -1630,9 +1670,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } } - if (ncrc == ifmgd->beacon_crc) + if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) return; ifmgd->beacon_crc = ncrc; + ifmgd->beacon_crc_valid = true; if (elems.erp_info && elems.erp_info_len >= 1) { erp_valid = true; @@ -1751,7 +1792,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_work *wk; - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; @@ -1783,7 +1824,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, free_work(wk); break; } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); } @@ -1823,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "No probe response from AP %pM" - " after %dms, try %d\n", bssid, - (1000 * IEEE80211_PROBE_WAIT)/HZ, - ifmgd->probe_send_count); + wiphy_debug(local->hw.wiphy, + "%s: No probe response from AP %pM" + " after %dms, try %d\n", + sdata->name, + bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ, + ifmgd->probe_send_count); #endif ieee80211_mgd_probe_ap_send(sdata); } else { @@ -1836,12 +1879,16 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) */ ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | IEEE80211_STA_BEACON_POLL); - printk(KERN_DEBUG "No probe response from AP %pM" - " after %dms, disconnecting.\n", - bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); - ieee80211_set_disassoc(sdata, true); - ieee80211_recalc_idle(local); + wiphy_debug(local->hw.wiphy, + "%s: No probe response from AP %pM" + " after %dms, disconnecting.\n", + sdata->name, + bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); + ieee80211_set_disassoc(sdata, true, true); mutex_unlock(&ifmgd->mtx); + mutex_lock(&local->mtx); + ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); /* * must be outside lock due to cfg80211, * but that's not a problem. @@ -1917,6 +1964,8 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) * time -- the code here is properly synchronised. */ + cancel_work_sync(&ifmgd->request_smps_work); + cancel_work_sync(&ifmgd->beacon_connection_loss_work); if (del_timer_sync(&ifmgd->timer)) set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); @@ -1952,6 +2001,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); INIT_WORK(&ifmgd->beacon_connection_loss_work, ieee80211_beacon_connection_loss_work); + INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work); setup_timer(&ifmgd->timer, ieee80211_sta_timer, (unsigned long) sdata); setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, @@ -2158,7 +2208,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, } /* Trying to reassociate - clear previous association state */ - ieee80211_set_disassoc(sdata, true); + ieee80211_set_disassoc(sdata, true, false); } mutex_unlock(&ifmgd->mtx); @@ -2169,6 +2219,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, ifmgd->flags &= ~IEEE80211_STA_DISABLE_11N; ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; + ifmgd->beacon_crc_valid = false; + for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || @@ -2249,6 +2301,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, else ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; + sdata->control_port_protocol = req->crypto.control_port_ethertype; + sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt; + ieee80211_add_work(wk); return 0; } @@ -2267,7 +2322,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, memcpy(bssid, req->bss->bssid, ETH_ALEN); if (ifmgd->associated == req->bss) { - ieee80211_set_disassoc(sdata, false); + ieee80211_set_disassoc(sdata, false, true); mutex_unlock(&ifmgd->mtx); assoc_bss = true; } else { @@ -2275,7 +2330,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, mutex_unlock(&ifmgd->mtx); - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; @@ -2294,7 +2349,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, free_work(wk); break; } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); /* * If somebody requests authentication and we haven't @@ -2319,7 +2374,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, if (assoc_bss) sta_info_destroy_addr(sdata, bssid); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); return 0; } @@ -2348,7 +2405,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, sdata->name, req->bss->bssid, req->reason_code); memcpy(bssid, req->bss->bssid, ETH_ALEN); - ieee80211_set_disassoc(sdata, false); + ieee80211_set_disassoc(sdata, false, true); mutex_unlock(&ifmgd->mtx); @@ -2357,7 +2414,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, cookie, !req->local_state_change); sta_info_destroy_addr(sdata, bssid); + mutex_lock(&sdata->local->mtx); ieee80211_recalc_idle(sdata->local); + mutex_unlock(&sdata->local->mtx); return 0; } diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index c36b1911987afec08262139ccaaf5e7887a17735..4b564091e51d52ae983058a8e4dfa9b10f704152 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -22,12 +22,16 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local = sdata->local; + struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; local->offchannel_ps_enabled = false; /* FIXME: what to do when local->pspolling is true? */ del_timer_sync(&local->dynamic_ps_timer); + del_timer_sync(&ifmgd->bcn_mon_timer); + del_timer_sync(&ifmgd->conn_mon_timer); + cancel_work_sync(&local->dynamic_ps_enable_work); if (local->hw.conf.flags & IEEE80211_CONF_PS) { @@ -85,6 +89,9 @@ static void ieee80211_offchannel_ps_disable(struct ieee80211_sub_if_data *sdata) mod_timer(&local->dynamic_ps_timer, jiffies + msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); } + + ieee80211_sta_reset_beacon_monitor(sdata); + ieee80211_sta_reset_conn_monitor(sdata); } void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) @@ -112,8 +119,10 @@ void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local) * used from user space controlled off-channel operations. */ if (sdata->vif.type != NL80211_IFTYPE_STATION && - sdata->vif.type != NL80211_IFTYPE_MONITOR) + sdata->vif.type != NL80211_IFTYPE_MONITOR) { + set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); netif_tx_stop_all_queues(sdata->dev); + } } mutex_unlock(&local->iflist_mtx); } @@ -131,6 +140,7 @@ void ieee80211_offchannel_stop_station(struct ieee80211_local *local) continue; if (sdata->vif.type == NL80211_IFTYPE_STATION) { + set_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); netif_tx_stop_all_queues(sdata->dev); if (sdata->u.mgd.associated) ieee80211_offchannel_ps_enable(sdata); @@ -155,8 +165,20 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, ieee80211_offchannel_ps_disable(sdata); } - if (sdata->vif.type != NL80211_IFTYPE_MONITOR) + if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { + clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state); + /* + * This may wake up queues even though the driver + * currently has them stopped. This is not very + * likely, since the driver won't have gotten any + * (or hardly any) new packets while we weren't + * on the right channel, and even if it happens + * it will at most lead to queueing up one more + * packet per queue in mac80211 rather than on + * the interface qdisc. + */ netif_tx_wake_all_queues(sdata->dev); + } /* re-enable beaconing */ if (enable_beaconing && diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index d287fde0431d6b2e688da5400d0ef9f41d9cf1c2..e37355193ed185679aa88b23a1a88789bec09678 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -45,7 +45,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) list_for_each_entry(sta, &local->sta_list, list) { if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { set_sta_flags(sta, WLAN_STA_BLOCK_BA); - ieee80211_sta_tear_down_BA_sessions(sta); + ieee80211_sta_tear_down_BA_sessions(sta, true); } if (sta->uploaded) { diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 334cbd3d2aae9ceffb708f6c2c4b361b6e6359d4..809cf230d251bccec01c32b6e60608f19ac32cf3 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -208,7 +208,7 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc) fc = hdr->frame_control; - return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc)); + return (info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc); } static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx) @@ -369,8 +369,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, ref = rate_control_alloc(name, local); if (!ref) { - printk(KERN_WARNING "%s: Failed to select rate control " - "algorithm\n", wiphy_name(local->hw.wiphy)); + wiphy_warn(local->hw.wiphy, + "Failed to select rate control algorithm\n"); return -ENOENT; } @@ -381,9 +381,8 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, sta_info_flush(local, NULL); } - printk(KERN_DEBUG "%s: Selected rate control " - "algorithm '%s'\n", wiphy_name(local->hw.wiphy), - ref->ops->name); + wiphy_debug(local->hw.wiphy, "Selected rate control algorithm '%s'\n", + ref->ops->name); return 0; } diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index c5b465904e3bfcec2ac0199e64dda46072022330..2a18d6602d4ade8bc385fecc4bca919811875ba1 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, !(info->flags & IEEE80211_TX_STAT_AMPDU)) return; - if (!info->status.ampdu_len) { - info->status.ampdu_ack_len = 1; + if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) { + info->status.ampdu_ack_len = + (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0); info->status.ampdu_len = 1; } @@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, group = minstrel_ht_get_group_idx(&ar[i]); rate = &mi->groups[group].rates[ar[i].idx % 8]; - if (last && (info->flags & IEEE80211_TX_STAT_ACK)) + if (last) rate->success += info->status.ampdu_ack_len; rate->attempts += ar[i].count * info->status.ampdu_len; diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index 7905f79cc2e43197e644a5e44931de4cd735e6a0..4851e9e2daeda8e7988de6e74ca90913e8c30c0d 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c @@ -162,7 +162,7 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, file_info->next_entry = (file_info->next_entry + 1) % RC_PID_EVENT_RING_SIZE; - /* Print information about the event. Note that userpace needs to + /* Print information about the event. Note that userspace needs to * provide large enough buffers. */ length = length < RC_PID_PRINT_BUF_SIZE ? length : RC_PID_PRINT_BUF_SIZE; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 28624282c5f36ad5bed8f74c0e8bf7df42ee2d6c..902b03ee8f60789bab002691e2db69d1f8c12cf4 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -315,6 +315,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); int tid; /* does the frame have a qos control field? */ @@ -323,9 +324,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) /* frame has qos control */ tid = *qc & IEEE80211_QOS_CTL_TID_MASK; if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) - rx->flags |= IEEE80211_RX_AMSDU; - else - rx->flags &= ~IEEE80211_RX_AMSDU; + status->rx_flags |= IEEE80211_RX_AMSDU; } else { /* * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): @@ -387,26 +386,25 @@ static ieee80211_rx_result debug_noinline ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) { struct ieee80211_local *local = rx->local; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); struct sk_buff *skb = rx->skb; - if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning))) + if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN))) + return RX_CONTINUE; + + if (test_bit(SCAN_HW_SCANNING, &local->scanning)) return ieee80211_scan_rx(rx->sdata, skb); - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) && - (rx->flags & IEEE80211_RX_IN_SCAN))) { + if (test_bit(SCAN_SW_SCANNING, &local->scanning)) { /* drop all the other packets during a software scan anyway */ if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) dev_kfree_skb(skb); return RX_QUEUED; } - if (unlikely(rx->flags & IEEE80211_RX_IN_SCAN)) { - /* scanning finished during invoking of handlers */ - I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); - return RX_DROP_UNUSABLE; - } - - return RX_CONTINUE; + /* scanning finished during invoking of handlers */ + I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); + return RX_DROP_UNUSABLE; } @@ -538,20 +536,12 @@ static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, int index, struct sk_buff_head *frames) { - struct ieee80211_supported_band *sband; - struct ieee80211_rate *rate = NULL; struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; - struct ieee80211_rx_status *status; if (!skb) goto no_frame; - status = IEEE80211_SKB_RXCB(skb); - - /* release the reordered frames to stack */ - sband = hw->wiphy->bands[status->band]; - if (!(status->flag & RX_FLAG_HT)) - rate = &sband->bitrates[status->rate_idx]; + /* release the frame from the reorder ring buffer */ tid_agg_rx->stored_mpdu_num--; tid_agg_rx->reorder_buf[index] = NULL; __skb_queue_tail(frames, skb); @@ -580,9 +570,102 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, * frames that have not yet been received are assumed to be lost and the skb * can be released for processing. This may also release other skb's from the * reorder buffer if there are no additional gaps between the frames. + * + * Callers must hold tid_agg_rx->reorder_lock. */ #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) +static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, + struct tid_ampdu_rx *tid_agg_rx, + struct sk_buff_head *frames) +{ + int index, j; + + /* release the buffer until next missing frame */ + index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % + tid_agg_rx->buf_size; + if (!tid_agg_rx->reorder_buf[index] && + tid_agg_rx->stored_mpdu_num > 1) { + /* + * No buffers ready to be released, but check whether any + * frames in the reorder buffer have timed out. + */ + int skipped = 1; + for (j = (index + 1) % tid_agg_rx->buf_size; j != index; + j = (j + 1) % tid_agg_rx->buf_size) { + if (!tid_agg_rx->reorder_buf[j]) { + skipped++; + continue; + } + if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + + HT_RX_REORDER_BUF_TIMEOUT)) + goto set_release_timer; + +#ifdef CONFIG_MAC80211_HT_DEBUG + if (net_ratelimit()) + wiphy_debug(hw->wiphy, + "release an RX reorder frame due to timeout on earlier frames\n"); +#endif + ieee80211_release_reorder_frame(hw, tid_agg_rx, + j, frames); + + /* + * Increment the head seq# also for the skipped slots. + */ + tid_agg_rx->head_seq_num = + (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; + skipped = 0; + } + } else while (tid_agg_rx->reorder_buf[index]) { + ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); + index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % + tid_agg_rx->buf_size; + } + + /* + * Disable the reorder release timer for now. + * + * The current implementation lacks a proper locking scheme + * which would protect vital statistic and debug counters + * from being updated by two different but concurrent BHs. + * + * More information about the topic is available from: + * - thread: http://marc.info/?t=128635927000001 + * + * What was wrong: + * => http://marc.info/?l=linux-wireless&m=128636170811964 + * "Basically the thing is that until your patch, the data + * in the struct didn't actually need locking because it + * was accessed by the RX path only which is not concurrent." + * + * List of what needs to be fixed: + * => http://marc.info/?l=linux-wireless&m=128656352920957 + * + + if (tid_agg_rx->stored_mpdu_num) { + j = index = seq_sub(tid_agg_rx->head_seq_num, + tid_agg_rx->ssn) % tid_agg_rx->buf_size; + + for (; j != (index - 1) % tid_agg_rx->buf_size; + j = (j + 1) % tid_agg_rx->buf_size) { + if (tid_agg_rx->reorder_buf[j]) + break; + } + + set_release_timer: + + mod_timer(&tid_agg_rx->reorder_timer, + tid_agg_rx->reorder_time[j] + + HT_RX_REORDER_BUF_TIMEOUT); + } else { + del_timer(&tid_agg_rx->reorder_timer); + } + */ + +set_release_timer: + return; +} + /* * As this function belongs to the RX path it must be under * rcu_read_lock protection. It returns false if the frame @@ -598,14 +681,16 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, u16 mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; u16 head_seq_num, buf_size; int index; + bool ret = true; buf_size = tid_agg_rx->buf_size; head_seq_num = tid_agg_rx->head_seq_num; + spin_lock(&tid_agg_rx->reorder_lock); /* frame with out of date sequence number */ if (seq_less(mpdu_seq_num, head_seq_num)) { dev_kfree_skb(skb); - return true; + goto out; } /* @@ -626,7 +711,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, /* check if we already stored this frame */ if (tid_agg_rx->reorder_buf[index]) { dev_kfree_skb(skb); - return true; + goto out; } /* @@ -636,58 +721,19 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, if (mpdu_seq_num == tid_agg_rx->head_seq_num && tid_agg_rx->stored_mpdu_num == 0) { tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); - return false; + ret = false; + goto out; } /* put the frame in the reordering buffer */ tid_agg_rx->reorder_buf[index] = skb; tid_agg_rx->reorder_time[index] = jiffies; tid_agg_rx->stored_mpdu_num++; - /* release the buffer until next missing frame */ - index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % - tid_agg_rx->buf_size; - if (!tid_agg_rx->reorder_buf[index] && - tid_agg_rx->stored_mpdu_num > 1) { - /* - * No buffers ready to be released, but check whether any - * frames in the reorder buffer have timed out. - */ - int j; - int skipped = 1; - for (j = (index + 1) % tid_agg_rx->buf_size; j != index; - j = (j + 1) % tid_agg_rx->buf_size) { - if (!tid_agg_rx->reorder_buf[j]) { - skipped++; - continue; - } - if (!time_after(jiffies, tid_agg_rx->reorder_time[j] + - HT_RX_REORDER_BUF_TIMEOUT)) - break; + ieee80211_sta_reorder_release(hw, tid_agg_rx, frames); -#ifdef CONFIG_MAC80211_HT_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "%s: release an RX reorder " - "frame due to timeout on earlier " - "frames\n", - wiphy_name(hw->wiphy)); -#endif - ieee80211_release_reorder_frame(hw, tid_agg_rx, - j, frames); - - /* - * Increment the head seq# also for the skipped slots. - */ - tid_agg_rx->head_seq_num = - (tid_agg_rx->head_seq_num + skipped) & SEQ_MASK; - skipped = 0; - } - } else while (tid_agg_rx->reorder_buf[index]) { - ieee80211_release_reorder_frame(hw, tid_agg_rx, index, frames); - index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % - tid_agg_rx->buf_size; - } - - return true; + out: + spin_unlock(&tid_agg_rx->reorder_lock); + return ret; } /* @@ -761,13 +807,14 @@ static ieee80211_rx_result debug_noinline ieee80211_rx_h_check(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { if (unlikely(ieee80211_has_retry(hdr->frame_control) && rx->sta->last_seq_ctrl[rx->queue] == hdr->seq_ctrl)) { - if (rx->flags & IEEE80211_RX_RA_MATCH) { + if (status->rx_flags & IEEE80211_RX_RA_MATCH) { rx->local->dot11FrameDuplicateCount++; rx->sta->num_duplicates++; } @@ -796,11 +843,12 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) if (unlikely((ieee80211_is_data(hdr->frame_control) || ieee80211_is_pspoll(hdr->frame_control)) && rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && + rx->sdata->vif.type != NL80211_IFTYPE_WDS && (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { if ((!ieee80211_has_fromds(hdr->frame_control) && !ieee80211_has_tods(hdr->frame_control) && ieee80211_is_data(hdr->frame_control)) || - !(rx->flags & IEEE80211_RX_RA_MATCH)) { + !(status->rx_flags & IEEE80211_RX_RA_MATCH)) { /* Drop IBSS frames and frames for other hosts * silently. */ return RX_DROP_MONITOR; @@ -822,7 +870,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) int keyidx; int hdrlen; ieee80211_rx_result result = RX_DROP_UNUSABLE; - struct ieee80211_key *stakey = NULL; + struct ieee80211_key *sta_ptk = NULL; int mmie_keyidx = -1; __le16 fc; @@ -857,22 +905,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) * No point in finding a key and decrypting if the frame is neither * addressed to us nor a multicast frame. */ - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_CONTINUE; /* start without a key */ rx->key = NULL; if (rx->sta) - stakey = rcu_dereference(rx->sta->key); + sta_ptk = rcu_dereference(rx->sta->ptk); fc = hdr->frame_control; if (!ieee80211_has_protected(fc)) mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); - if (!is_multicast_ether_addr(hdr->addr1) && stakey) { - rx->key = stakey; + if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) { + rx->key = sta_ptk; + if ((status->flag & RX_FLAG_DECRYPTED) && + (status->flag & RX_FLAG_IV_STRIPPED)) + return RX_CONTINUE; /* Skip decryption if the frame is not protected. */ if (!ieee80211_has_protected(fc)) return RX_CONTINUE; @@ -885,7 +936,10 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) if (mmie_keyidx < NUM_DEFAULT_KEYS || mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) return RX_DROP_MONITOR; /* unexpected BIP keyidx */ - rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); + if (rx->sta) + rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]); + if (!rx->key) + rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); } else if (!ieee80211_has_protected(fc)) { /* * The frame was not protected, so skip decryption. However, we @@ -928,16 +982,25 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); keyidx = keyid >> 6; - rx->key = rcu_dereference(rx->sdata->keys[keyidx]); + /* check per-station GTK first, if multicast packet */ + if (is_multicast_ether_addr(hdr->addr1) && rx->sta) + rx->key = rcu_dereference(rx->sta->gtk[keyidx]); - /* - * RSNA-protected unicast frames should always be sent with - * pairwise or station-to-station keys, but for WEP we allow - * using a key index as well. - */ - if (rx->key && rx->key->conf.alg != ALG_WEP && - !is_multicast_ether_addr(hdr->addr1)) - rx->key = NULL; + /* if not found, try default key */ + if (!rx->key) { + rx->key = rcu_dereference(rx->sdata->keys[keyidx]); + + /* + * RSNA-protected unicast frames should always be + * sent with pairwise or station-to-station keys, + * but for WEP we allow using a key index as well. + */ + if (rx->key && + rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 && + rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 && + !is_multicast_ether_addr(hdr->addr1)) + rx->key = NULL; + } } if (rx->key) { @@ -951,8 +1014,9 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) return RX_DROP_UNUSABLE; /* the hdr variable is invalid now! */ - switch (rx->key->conf.alg) { - case ALG_WEP: + switch (rx->key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: /* Check for weak IVs if possible */ if (rx->sta && ieee80211_is_data(fc) && (!(status->flag & RX_FLAG_IV_STRIPPED) || @@ -962,15 +1026,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) result = ieee80211_crypto_wep_decrypt(rx); break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: result = ieee80211_crypto_tkip_decrypt(rx); break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: result = ieee80211_crypto_ccmp_decrypt(rx); break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: result = ieee80211_crypto_aes_cmac_decrypt(rx); break; + default: + /* + * We can reach here only with HW-only algorithms + * but why didn't it decrypt the frame?! + */ + return RX_DROP_UNUSABLE; } /* either the frame has been decrypted or will be dropped */ @@ -1079,7 +1149,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) sta->last_rx = jiffies; } - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_CONTINUE; if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) @@ -1236,6 +1306,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) unsigned int frag, seq; struct ieee80211_fragment_entry *entry; struct sk_buff *skb; + struct ieee80211_rx_status *status; hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; @@ -1265,7 +1336,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) /* This is the first fragment of a new frame. */ entry = ieee80211_reassemble_add(rx->sdata, frag, seq, rx->queue, &(rx->skb)); - if (rx->key && rx->key->conf.alg == ALG_CCMP && + if (rx->key && rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP && ieee80211_has_protected(fc)) { int queue = ieee80211_is_mgmt(fc) ? NUM_RX_DATA_QUEUES : rx->queue; @@ -1294,7 +1365,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) int i; u8 pn[CCMP_PN_LEN], *rpn; int queue; - if (!rx->key || rx->key->conf.alg != ALG_CCMP) + if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) return RX_DROP_UNUSABLE; memcpy(pn, entry->last_pn, CCMP_PN_LEN); for (i = CCMP_PN_LEN - 1; i >= 0; i--) { @@ -1335,7 +1406,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) } /* Complete frame has been reassembled - process it now */ - rx->flags |= IEEE80211_RX_FRAGMENTED; + status = IEEE80211_SKB_RXCB(rx->skb); + status->rx_flags |= IEEE80211_RX_FRAGMENTED; out: if (rx->sta) @@ -1352,9 +1424,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) { struct ieee80211_sub_if_data *sdata = rx->sdata; __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || - !(rx->flags & IEEE80211_RX_RA_MATCH))) + !(status->rx_flags & IEEE80211_RX_RA_MATCH))) return RX_CONTINUE; if ((sdata->vif.type != NL80211_IFTYPE_AP) && @@ -1492,7 +1565,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc) * Allow EAPOL frames to us/the PAE group address regardless * of whether the frame was encrypted or not. */ - if (ehdr->h_proto == htons(ETH_P_PAE) && + if (ehdr->h_proto == rx->sdata->control_port_protocol && (compare_ether_addr(ehdr->h_dest, rx->sdata->vif.addr) == 0 || compare_ether_addr(ehdr->h_dest, pae_group_addr) == 0)) return true; @@ -1515,6 +1588,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) struct sk_buff *skb, *xmit_skb; struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; struct sta_info *dsta; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); skb = rx->skb; xmit_skb = NULL; @@ -1522,7 +1596,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) if ((sdata->vif.type == NL80211_IFTYPE_AP || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && - (rx->flags & IEEE80211_RX_RA_MATCH) && + (status->rx_flags & IEEE80211_RX_RA_MATCH) && (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { if (is_multicast_ether_addr(ehdr->h_dest)) { /* @@ -1599,6 +1673,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; __le16 fc = hdr->frame_control; struct sk_buff_head frame_list; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); if (unlikely(!ieee80211_is_data(fc))) return RX_CONTINUE; @@ -1606,7 +1681,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) if (unlikely(!ieee80211_is_data_present(fc))) return RX_DROP_MONITOR; - if (!(rx->flags & IEEE80211_RX_AMSDU)) + if (!(status->rx_flags & IEEE80211_RX_AMSDU)) return RX_CONTINUE; if (ieee80211_has_a4(hdr->frame_control) && @@ -1657,6 +1732,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) struct sk_buff *skb = rx->skb, *fwd_skb; struct ieee80211_local *local = rx->local; struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); @@ -1702,7 +1778,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mesh_hdr->ttl--; - if (rx->flags & IEEE80211_RX_RA_MATCH) { + if (status->rx_flags & IEEE80211_RX_RA_MATCH) { if (!mesh_hdr->ttl) IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, dropped_frames_ttl); @@ -1908,14 +1984,39 @@ static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, ieee80211_tx_skb(sdata, skb); } +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) +{ + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + + /* + * From here on, look only at management frames. + * Data and control frames are already handled, + * and unknown (reserved) frames are useless. + */ + if (rx->skb->len < 24) + return RX_DROP_MONITOR; + + if (!ieee80211_is_mgmt(mgmt->frame_control)) + return RX_DROP_MONITOR; + + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) + return RX_DROP_MONITOR; + + if (ieee80211_drop_unencrypted_mgmt(rx)) + return RX_DROP_UNUSABLE; + + return RX_CONTINUE; +} + static ieee80211_rx_result debug_noinline ieee80211_rx_h_action(struct ieee80211_rx_data *rx) { struct ieee80211_local *local = rx->local; struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; - struct sk_buff *nskb; - struct ieee80211_rx_status *status; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); int len = rx->skb->len; if (!ieee80211_is_action(mgmt->frame_control)) @@ -1928,10 +2029,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) return RX_DROP_UNUSABLE; - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) - return RX_DROP_UNUSABLE; - - if (ieee80211_drop_unencrypted_mgmt(rx)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_DROP_UNUSABLE; switch (mgmt->u.action.category) { @@ -2024,17 +2122,36 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) goto queue; } + return RX_CONTINUE; + invalid: - /* - * For AP mode, hostapd is responsible for handling any action - * frames that we didn't handle, including returning unknown - * ones. For all other modes we will return them to the sender, - * setting the 0x80 bit in the action category, as required by - * 802.11-2007 7.3.1.11. - */ - if (sdata->vif.type == NL80211_IFTYPE_AP || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - return RX_DROP_MONITOR; + status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM; + /* will return in the next handlers */ + return RX_CONTINUE; + + handled: + if (rx->sta) + rx->sta->rx_packets++; + dev_kfree_skb(rx->skb); + return RX_QUEUED; + + queue: + rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; + skb_queue_tail(&sdata->skb_queue, rx->skb); + ieee80211_queue_work(&local->hw, &sdata->work); + if (rx->sta) + rx->sta->rx_packets++; + return RX_QUEUED; +} + +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) +{ + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + + /* skip known-bad action frames and return them in the next handler */ + if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) + return RX_CONTINUE; /* * Getting here means the kernel doesn't know how to handle @@ -2042,12 +2159,46 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) * so userspace can register for those to know whether ones * it transmitted were processed or returned. */ - status = IEEE80211_SKB_RXCB(rx->skb); - if (cfg80211_rx_action(rx->sdata->dev, status->freq, - rx->skb->data, rx->skb->len, - GFP_ATOMIC)) - goto handled; + if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, + rx->skb->data, rx->skb->len, + GFP_ATOMIC)) { + if (rx->sta) + rx->sta->rx_packets++; + dev_kfree_skb(rx->skb); + return RX_QUEUED; + } + + + return RX_CONTINUE; +} + +static ieee80211_rx_result debug_noinline +ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) +{ + struct ieee80211_local *local = rx->local; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; + struct sk_buff *nskb; + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); + + if (!ieee80211_is_action(mgmt->frame_control)) + return RX_CONTINUE; + + /* + * For AP mode, hostapd is responsible for handling any action + * frames that we didn't handle, including returning unknown + * ones. For all other modes we will return them to the sender, + * setting the 0x80 bit in the action category, as required by + * 802.11-2007 7.3.1.11. + * Newer versions of hostapd shall also use the management frame + * registration mechanisms, but older ones still use cooked + * monitor interfaces so push all frames there. + */ + if (!(status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) && + (sdata->vif.type == NL80211_IFTYPE_AP || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) + return RX_DROP_MONITOR; /* do not return rejected action frames */ if (mgmt->u.action.category & 0x80) @@ -2066,20 +2217,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) ieee80211_tx_skb(rx->sdata, nskb); } - - handled: - if (rx->sta) - rx->sta->rx_packets++; dev_kfree_skb(rx->skb); return RX_QUEUED; - - queue: - rx->skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; - skb_queue_tail(&sdata->skb_queue, rx->skb); - ieee80211_queue_work(&local->hw, &sdata->work); - if (rx->sta) - rx->sta->rx_packets++; - return RX_QUEUED; } static ieee80211_rx_result debug_noinline @@ -2090,15 +2229,6 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; __le16 stype; - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) - return RX_DROP_MONITOR; - - if (rx->skb->len < 24) - return RX_DROP_MONITOR; - - if (ieee80211_drop_unencrypted_mgmt(rx)) - return RX_DROP_UNUSABLE; - rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb); if (rxs != RX_CONTINUE) return rxs; @@ -2199,6 +2329,14 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, struct net_device *prev_dev = NULL; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + /* + * If cooked monitor has been processed already, then + * don't do it again. If not, set the flag. + */ + if (rx->flags & IEEE80211_RX_CMNTR) + goto out_free_skb; + rx->flags |= IEEE80211_RX_CMNTR; + if (skb_headroom(skb) < sizeof(*rthdr) && pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) goto out_free_skb; @@ -2253,29 +2391,53 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, if (prev_dev) { skb->dev = prev_dev; netif_receive_skb(skb); - skb = NULL; - } else - goto out_free_skb; - - return; + return; + } out_free_skb: dev_kfree_skb(skb); } +static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx, + ieee80211_rx_result res) +{ + switch (res) { + case RX_DROP_MONITOR: + I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); + if (rx->sta) + rx->sta->rx_dropped++; + /* fall through */ + case RX_CONTINUE: { + struct ieee80211_rate *rate = NULL; + struct ieee80211_supported_band *sband; + struct ieee80211_rx_status *status; + + status = IEEE80211_SKB_RXCB((rx->skb)); + + sband = rx->local->hw.wiphy->bands[status->band]; + if (!(status->flag & RX_FLAG_HT)) + rate = &sband->bitrates[status->rate_idx]; + + ieee80211_rx_cooked_monitor(rx, rate); + break; + } + case RX_DROP_UNUSABLE: + I802_DEBUG_INC(rx->sdata->local->rx_handlers_drop); + if (rx->sta) + rx->sta->rx_dropped++; + dev_kfree_skb(rx->skb); + break; + case RX_QUEUED: + I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued); + break; + } +} -static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, - struct ieee80211_rx_data *rx, - struct sk_buff *skb, - struct ieee80211_rate *rate) +static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, + struct sk_buff_head *frames) { - struct sk_buff_head reorder_release; ieee80211_rx_result res = RX_DROP_MONITOR; - - __skb_queue_head_init(&reorder_release); - - rx->skb = skb; - rx->sdata = sdata; + struct sk_buff *skb; #define CALL_RXH(rxh) \ do { \ @@ -2284,23 +2446,14 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, goto rxh_next; \ } while (0); - /* - * NB: the rxh_next label works even if we jump - * to it from here because then the list will - * be empty, which is a trivial check - */ - CALL_RXH(ieee80211_rx_h_passive_scan) - CALL_RXH(ieee80211_rx_h_check) - - ieee80211_rx_reorder_ampdu(rx, &reorder_release); - - while ((skb = __skb_dequeue(&reorder_release))) { + while ((skb = __skb_dequeue(frames))) { /* * all the other fields are valid across frames * that belong to an aMPDU since they are on the * same TID from the same station */ rx->skb = skb; + rx->flags = 0; CALL_RXH(ieee80211_rx_h_decrypt) CALL_RXH(ieee80211_rx_h_check_more_data) @@ -2312,50 +2465,92 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, CALL_RXH(ieee80211_rx_h_remove_qos_control) CALL_RXH(ieee80211_rx_h_amsdu) #ifdef CONFIG_MAC80211_MESH - if (ieee80211_vif_is_mesh(&sdata->vif)) + if (ieee80211_vif_is_mesh(&rx->sdata->vif)) CALL_RXH(ieee80211_rx_h_mesh_fwding); #endif CALL_RXH(ieee80211_rx_h_data) /* special treatment -- needs the queue */ - res = ieee80211_rx_h_ctrl(rx, &reorder_release); + res = ieee80211_rx_h_ctrl(rx, frames); if (res != RX_CONTINUE) goto rxh_next; + CALL_RXH(ieee80211_rx_h_mgmt_check) CALL_RXH(ieee80211_rx_h_action) + CALL_RXH(ieee80211_rx_h_userspace_mgmt) + CALL_RXH(ieee80211_rx_h_action_return) CALL_RXH(ieee80211_rx_h_mgmt) + rxh_next: + ieee80211_rx_handlers_result(rx, res); + #undef CALL_RXH + } +} + +static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) +{ + struct sk_buff_head reorder_release; + ieee80211_rx_result res = RX_DROP_MONITOR; + + __skb_queue_head_init(&reorder_release); + +#define CALL_RXH(rxh) \ + do { \ + res = rxh(rx); \ + if (res != RX_CONTINUE) \ + goto rxh_next; \ + } while (0); + + CALL_RXH(ieee80211_rx_h_passive_scan) + CALL_RXH(ieee80211_rx_h_check) + + ieee80211_rx_reorder_ampdu(rx, &reorder_release); + + ieee80211_rx_handlers(rx, &reorder_release); + return; rxh_next: - switch (res) { - case RX_DROP_MONITOR: - I802_DEBUG_INC(sdata->local->rx_handlers_drop); - if (rx->sta) - rx->sta->rx_dropped++; - /* fall through */ - case RX_CONTINUE: - ieee80211_rx_cooked_monitor(rx, rate); - break; - case RX_DROP_UNUSABLE: - I802_DEBUG_INC(sdata->local->rx_handlers_drop); - if (rx->sta) - rx->sta->rx_dropped++; - dev_kfree_skb(rx->skb); - break; - case RX_QUEUED: - I802_DEBUG_INC(sdata->local->rx_handlers_queued); - break; - } - } + ieee80211_rx_handlers_result(rx, res); + +#undef CALL_RXH +} + +/* + * This function makes calls into the RX path. Therefore the + * caller must hold the sta_info->lock and everything has to + * be under rcu_read_lock protection as well. + */ +void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) +{ + struct sk_buff_head frames; + struct ieee80211_rx_data rx = { + .sta = sta, + .sdata = sta->sdata, + .local = sta->local, + .queue = tid, + }; + struct tid_ampdu_rx *tid_agg_rx; + + tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); + if (!tid_agg_rx) + return; + + __skb_queue_head_init(&frames); + + spin_lock(&tid_agg_rx->reorder_lock); + ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); + spin_unlock(&tid_agg_rx->reorder_lock); + + ieee80211_rx_handlers(&rx, &frames); } /* main receive path */ -static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, - struct ieee80211_rx_data *rx, +static int prepare_for_handlers(struct ieee80211_rx_data *rx, struct ieee80211_hdr *hdr) { + struct ieee80211_sub_if_data *sdata = rx->sdata; struct sk_buff *skb = rx->skb; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); @@ -2369,7 +2564,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } break; case NL80211_IFTYPE_ADHOC: @@ -2379,15 +2574,15 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, return 1; } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { - if (!(rx->flags & IEEE80211_RX_IN_SCAN)) + if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } else if (!multicast && compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { if (!(sdata->dev->flags & IFF_PROMISC)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } else if (!rx->sta) { int rate_idx; if (status->flag & RX_FLAG_HT) @@ -2405,7 +2600,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, if (!(sdata->dev->flags & IFF_PROMISC)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } break; case NL80211_IFTYPE_AP_VLAN: @@ -2416,9 +2611,9 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, return 0; } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) { - if (!(rx->flags & IEEE80211_RX_IN_SCAN)) + if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) return 0; - rx->flags &= ~IEEE80211_RX_RA_MATCH; + status->rx_flags &= ~IEEE80211_RX_RA_MATCH; } break; case NL80211_IFTYPE_WDS: @@ -2427,9 +2622,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) return 0; break; - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + default: /* should never get here */ WARN_ON(1); break; @@ -2438,13 +2631,57 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, return 1; } +/* + * This function returns whether or not the SKB + * was destined for RX processing or not, which, + * if consume is true, is equivalent to whether + * or not the skb was consumed. + */ +static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, + struct sk_buff *skb, bool consume) +{ + struct ieee80211_local *local = rx->local; + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + int prepares; + + rx->skb = skb; + status->rx_flags |= IEEE80211_RX_RA_MATCH; + prepares = prepare_for_handlers(rx, hdr); + + if (!prepares) + return false; + + if (status->flag & RX_FLAG_MMIC_ERROR) { + if (status->rx_flags & IEEE80211_RX_RA_MATCH) + ieee80211_rx_michael_mic_report(hdr, rx); + return false; + } + + if (!consume) { + skb = skb_copy(skb, GFP_ATOMIC); + if (!skb) { + if (net_ratelimit()) + wiphy_debug(local->hw.wiphy, + "failed to copy multicast frame for %s\n", + sdata->name); + return true; + } + + rx->skb = skb; + } + + ieee80211_invoke_rx_handlers(rx); + return true; +} + /* * This is the actual Rx frames handler. as it blongs to Rx path it must * be called with rcu_read_lock protection. */ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, - struct sk_buff *skb, - struct ieee80211_rate *rate) + struct sk_buff *skb) { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_local *local = hw_to_local(hw); @@ -2452,11 +2689,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr; __le16 fc; struct ieee80211_rx_data rx; - int prepares; - struct ieee80211_sub_if_data *prev = NULL; - struct sk_buff *skb_new; - struct sta_info *sta, *tmp; - bool found_sta = false; + struct ieee80211_sub_if_data *prev; + struct sta_info *sta, *tmp, *prev_sta; int err = 0; fc = ((struct ieee80211_hdr *)skb->data)->frame_control; @@ -2469,7 +2703,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || test_bit(SCAN_OFF_CHANNEL, &local->scanning))) - rx.flags |= IEEE80211_RX_IN_SCAN; + status->rx_flags |= IEEE80211_RX_IN_SCAN; if (ieee80211_is_mgmt(fc)) err = skb_linearize(skb); @@ -2486,91 +2720,67 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, ieee80211_verify_alignment(&rx); if (ieee80211_is_data(fc)) { + prev_sta = NULL; + for_each_sta_info(local, hdr->addr2, sta, tmp) { - rx.sta = sta; - found_sta = true; - rx.sdata = sta->sdata; - - rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(rx.sdata, &rx, hdr); - if (prepares) { - if (status->flag & RX_FLAG_MMIC_ERROR) { - if (rx.flags & IEEE80211_RX_RA_MATCH) - ieee80211_rx_michael_mic_report(hdr, &rx); - } else - prev = rx.sdata; - } - } - } - if (!found_sta) { - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - if (!ieee80211_sdata_running(sdata)) + if (!prev_sta) { + prev_sta = sta; continue; + } - if (sdata->vif.type == NL80211_IFTYPE_MONITOR || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - continue; + rx.sta = prev_sta; + rx.sdata = prev_sta->sdata; + ieee80211_prepare_and_rx_handle(&rx, skb, false); - /* - * frame is destined for this interface, but if it's - * not also for the previous one we handle that after - * the loop to avoid copying the SKB once too much - */ + prev_sta = sta; + } - if (!prev) { - prev = sdata; - continue; - } + if (prev_sta) { + rx.sta = prev_sta; + rx.sdata = prev_sta->sdata; - rx.sta = sta_info_get_bss(prev, hdr->addr2); + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) + return; + } + } - rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(prev, &rx, hdr); + prev = NULL; - if (!prepares) - goto next; + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (!ieee80211_sdata_running(sdata)) + continue; - if (status->flag & RX_FLAG_MMIC_ERROR) { - rx.sdata = prev; - if (rx.flags & IEEE80211_RX_RA_MATCH) - ieee80211_rx_michael_mic_report(hdr, - &rx); - goto next; - } + if (sdata->vif.type == NL80211_IFTYPE_MONITOR || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + continue; - /* - * frame was destined for the previous interface - * so invoke RX handlers for it - */ + /* + * frame is destined for this interface, but if it's + * not also for the previous one we handle that after + * the loop to avoid copying the SKB once too much + */ - skb_new = skb_copy(skb, GFP_ATOMIC); - if (!skb_new) { - if (net_ratelimit()) - printk(KERN_DEBUG "%s: failed to copy " - "multicast frame for %s\n", - wiphy_name(local->hw.wiphy), - prev->name); - goto next; - } - ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate); -next: + if (!prev) { prev = sdata; + continue; } - if (prev) { - rx.sta = sta_info_get_bss(prev, hdr->addr2); + rx.sta = sta_info_get_bss(prev, hdr->addr2); + rx.sdata = prev; + ieee80211_prepare_and_rx_handle(&rx, skb, false); - rx.flags |= IEEE80211_RX_RA_MATCH; - prepares = prepare_for_handlers(prev, &rx, hdr); + prev = sdata; + } - if (!prepares) - prev = NULL; - } + if (prev) { + rx.sta = sta_info_get_bss(prev, hdr->addr2); + rx.sdata = prev; + + if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) + return; } - if (prev) - ieee80211_invoke_rx_handlers(prev, &rx, skb, rate); - else - dev_kfree_skb(skb); + + dev_kfree_skb(skb); } /* @@ -2611,30 +2821,41 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) if (WARN_ON(!local->started)) goto drop; - if (status->flag & RX_FLAG_HT) { + if (likely(!(status->flag & RX_FLAG_FAILED_PLCP_CRC))) { /* - * rate_idx is MCS index, which can be [0-76] as documented on: - * - * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n - * - * Anything else would be some sort of driver or hardware error. - * The driver should catch hardware errors. + * Validate the rate, unless a PLCP error means that + * we probably can't have a valid rate here anyway. */ - if (WARN((status->rate_idx < 0 || - status->rate_idx > 76), - "Rate marked as an HT rate but passed " - "status->rate_idx is not " - "an MCS index [0-76]: %d (0x%02x)\n", - status->rate_idx, - status->rate_idx)) - goto drop; - } else { - if (WARN_ON(status->rate_idx < 0 || - status->rate_idx >= sband->n_bitrates)) - goto drop; - rate = &sband->bitrates[status->rate_idx]; + + if (status->flag & RX_FLAG_HT) { + /* + * rate_idx is MCS index, which can be [0-76] + * as documented on: + * + * http://wireless.kernel.org/en/developers/Documentation/ieee80211/802.11n + * + * Anything else would be some sort of driver or + * hardware error. The driver should catch hardware + * errors. + */ + if (WARN((status->rate_idx < 0 || + status->rate_idx > 76), + "Rate marked as an HT rate but passed " + "status->rate_idx is not " + "an MCS index [0-76]: %d (0x%02x)\n", + status->rate_idx, + status->rate_idx)) + goto drop; + } else { + if (WARN_ON(status->rate_idx < 0 || + status->rate_idx >= sband->n_bitrates)) + goto drop; + rate = &sband->bitrates[status->rate_idx]; + } } + status->rx_flags = 0; + /* * key references and virtual interfaces are protected using RCU * and this requires that we are in a read-side RCU section during @@ -2654,7 +2875,7 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) return; } - __ieee80211_rx_handle_packet(hw, skb, rate); + __ieee80211_rx_handle_packet(hw, skb); rcu_read_unlock(); diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 872d7b6ef6b34f6dabdfbd0c491d94306d2fdf04..fb274db77e3cc73a1b1d9f537966ffc0a8a0cd14 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c @@ -242,20 +242,19 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) local->hw_scan_req->n_channels = n_chans; ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, - req->ie, req->ie_len, band); + req->ie, req->ie_len, band, (u32) -1, + 0); local->hw_scan_req->ie_len = ielen; return true; } -void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) +static bool __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, + bool was_hw_scan) { struct ieee80211_local *local = hw_to_local(hw); - bool was_hw_scan; - - trace_api_scan_completed(local, aborted); - mutex_lock(&local->scan_mtx); + lockdep_assert_held(&local->mtx); /* * It's ok to abort a not-yet-running scan (that @@ -266,17 +265,13 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) if (WARN_ON(!local->scanning && !aborted)) aborted = true; - if (WARN_ON(!local->scan_req)) { - mutex_unlock(&local->scan_mtx); - return; - } + if (WARN_ON(!local->scan_req)) + return false; - was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { - ieee80211_queue_delayed_work(&local->hw, - &local->scan_work, 0); - mutex_unlock(&local->scan_mtx); - return; + int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); + if (rc == 0) + return false; } kfree(local->hw_scan_req); @@ -290,26 +285,42 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) local->scanning = 0; local->scan_channel = NULL; - /* we only have to protect scan_req and hw/sw scan */ - mutex_unlock(&local->scan_mtx); - - ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - if (was_hw_scan) - goto done; - - ieee80211_configure_filter(local); + return true; +} - drv_sw_scan_complete(local); +static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw, + bool was_hw_scan) +{ + struct ieee80211_local *local = hw_to_local(hw); - ieee80211_offchannel_return(local, true); + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); + if (!was_hw_scan) { + ieee80211_configure_filter(local); + drv_sw_scan_complete(local); + ieee80211_offchannel_return(local, true); + } - done: + mutex_lock(&local->mtx); ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); + ieee80211_mlme_notify_scan_completed(local); ieee80211_ibss_notify_scan_completed(local); ieee80211_mesh_notify_scan_completed(local); ieee80211_queue_work(&local->hw, &local->work_work); } + +void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) +{ + struct ieee80211_local *local = hw_to_local(hw); + + trace_api_scan_completed(local, aborted); + + set_bit(SCAN_COMPLETED, &local->scanning); + if (aborted) + set_bit(SCAN_ABORTED, &local->scanning); + ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); +} EXPORT_SYMBOL(ieee80211_scan_completed); static int ieee80211_start_sw_scan(struct ieee80211_local *local) @@ -353,6 +364,8 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; int rc; + lockdep_assert_held(&local->mtx); + if (local->scan_req) return -EBUSY; @@ -434,8 +447,8 @@ ieee80211_scan_get_channel_time(struct ieee80211_channel *chan) return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; } -static int ieee80211_scan_state_decision(struct ieee80211_local *local, - unsigned long *next_delay) +static void ieee80211_scan_state_decision(struct ieee80211_local *local, + unsigned long *next_delay) { bool associated = false; bool tx_empty = true; @@ -445,12 +458,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata; struct ieee80211_channel *next_chan; - /* if no more bands/channels left, complete scan and advance to the idle state */ - if (local->scan_channel_idx >= local->scan_req->n_channels) { - ieee80211_scan_completed(&local->hw, false); - return 1; - } - /* * check if at least one STA interface is associated, * check if at least one STA interface has pending tx frames @@ -522,7 +529,6 @@ static int ieee80211_scan_state_decision(struct ieee80211_local *local, } *next_delay = 0; - return 0; } static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local, @@ -638,21 +644,18 @@ void ieee80211_scan_work(struct work_struct *work) container_of(work, struct ieee80211_local, scan_work.work); struct ieee80211_sub_if_data *sdata = local->scan_sdata; unsigned long next_delay = 0; + bool aborted, hw_scan, finish; - mutex_lock(&local->scan_mtx); - if (!sdata || !local->scan_req) { - mutex_unlock(&local->scan_mtx); - return; - } + mutex_lock(&local->mtx); - if (local->hw_scan_req) { - int rc = drv_hw_scan(local, sdata, local->hw_scan_req); - mutex_unlock(&local->scan_mtx); - if (rc) - ieee80211_scan_completed(&local->hw, true); - return; + if (test_and_clear_bit(SCAN_COMPLETED, &local->scanning)) { + aborted = test_and_clear_bit(SCAN_ABORTED, &local->scanning); + goto out_complete; } + if (!sdata || !local->scan_req) + goto out; + if (local->scan_req && !local->scanning) { struct cfg80211_scan_request *req = local->scan_req; int rc; @@ -661,21 +664,21 @@ void ieee80211_scan_work(struct work_struct *work) local->scan_sdata = NULL; rc = __ieee80211_start_scan(sdata, req); - mutex_unlock(&local->scan_mtx); - - if (rc) - ieee80211_scan_completed(&local->hw, true); - return; + if (rc) { + /* need to complete scan in cfg80211 */ + local->scan_req = req; + aborted = true; + goto out_complete; + } else + goto out; } - mutex_unlock(&local->scan_mtx); - /* * Avoid re-scheduling when the sdata is going away. */ if (!ieee80211_sdata_running(sdata)) { - ieee80211_scan_completed(&local->hw, true); - return; + aborted = true; + goto out_complete; } /* @@ -685,8 +688,12 @@ void ieee80211_scan_work(struct work_struct *work) do { switch (local->next_scan_state) { case SCAN_DECISION: - if (ieee80211_scan_state_decision(local, &next_delay)) - return; + /* if no more bands/channels left, complete scan */ + if (local->scan_channel_idx >= local->scan_req->n_channels) { + aborted = false; + goto out_complete; + } + ieee80211_scan_state_decision(local, &next_delay); break; case SCAN_SET_CHANNEL: ieee80211_scan_state_set_channel(local, &next_delay); @@ -704,6 +711,19 @@ void ieee80211_scan_work(struct work_struct *work) } while (next_delay == 0); ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay); + mutex_unlock(&local->mtx); + return; + +out_complete: + hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); + finish = __ieee80211_scan_completed(&local->hw, aborted, hw_scan); + mutex_unlock(&local->mtx); + if (finish) + __ieee80211_scan_completed_finish(&local->hw, hw_scan); + return; + +out: + mutex_unlock(&local->mtx); } int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, @@ -711,9 +731,9 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, { int res; - mutex_lock(&sdata->local->scan_mtx); + mutex_lock(&sdata->local->mtx); res = __ieee80211_start_scan(sdata, req); - mutex_unlock(&sdata->local->scan_mtx); + mutex_unlock(&sdata->local->mtx); return res; } @@ -726,7 +746,7 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, int ret = -EBUSY; enum ieee80211_band band; - mutex_lock(&local->scan_mtx); + mutex_lock(&local->mtx); /* busy scanning */ if (local->scan_req) @@ -761,25 +781,44 @@ int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, ret = __ieee80211_start_scan(sdata, sdata->local->int_scan_req); unlock: - mutex_unlock(&local->scan_mtx); + mutex_unlock(&local->mtx); return ret; } +/* + * Only call this function when a scan can't be queued -- under RTNL. + */ void ieee80211_scan_cancel(struct ieee80211_local *local) { bool abortscan; - - cancel_delayed_work_sync(&local->scan_work); + bool finish = false; /* - * Only call this function when a scan can't be - * queued -- mostly at suspend under RTNL. + * We are only canceling software scan, or deferred scan that was not + * yet really started (see __ieee80211_start_scan ). + * + * Regarding hardware scan: + * - we can not call __ieee80211_scan_completed() as when + * SCAN_HW_SCANNING bit is set this function change + * local->hw_scan_req to operate on 5G band, what race with + * driver which can use local->hw_scan_req + * + * - we can not cancel scan_work since driver can schedule it + * by ieee80211_scan_completed(..., true) to finish scan + * + * Hence low lever driver is responsible for canceling HW scan. */ - mutex_lock(&local->scan_mtx); - abortscan = test_bit(SCAN_SW_SCANNING, &local->scanning) || - (!local->scanning && local->scan_req); - mutex_unlock(&local->scan_mtx); + mutex_lock(&local->mtx); + abortscan = local->scan_req && !test_bit(SCAN_HW_SCANNING, &local->scanning); if (abortscan) - ieee80211_scan_completed(&local->hw, true); + finish = __ieee80211_scan_completed(&local->hw, true, false); + mutex_unlock(&local->mtx); + + if (abortscan) { + /* The scan is canceled, but stop work from being pending */ + cancel_delayed_work_sync(&local->scan_work); + } + if (finish) + __ieee80211_scan_completed_finish(&local->hw, false); } diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 6d86f0c1ad0415acc4d96d0131d27bb2dc77f614..6d8f897d87636c8422b23ec9447c27dbb0937096 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -125,7 +125,7 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, lockdep_is_held(&local->sta_mtx)); while (sta) { if ((sta->sdata == sdata || - sta->sdata->bss == sdata->bss) && + (sta->sdata->bss && sta->sdata->bss == sdata->bss)) && memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) break; sta = rcu_dereference_check(sta->hnext, @@ -174,8 +174,7 @@ static void __sta_info_free(struct ieee80211_local *local, } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Destroyed STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ kfree(sta); @@ -262,8 +261,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Allocated STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Allocated STA %pM\n", sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ #ifdef CONFIG_MAC80211_MESH @@ -282,7 +280,7 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async) unsigned long flags; int err = 0; - WARN_ON(!mutex_is_locked(&local->sta_mtx)); + lockdep_assert_held(&local->sta_mtx); /* notify driver */ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) @@ -300,8 +298,9 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async) sta->uploaded = true; #ifdef CONFIG_MAC80211_VERBOSE_DEBUG if (async) - printk(KERN_DEBUG "%s: Finished adding IBSS STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, + "Finished adding IBSS STA %pM\n", + sta->sta.addr); #endif } @@ -411,8 +410,8 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) spin_unlock_irqrestore(&local->sta_lock, flags); #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Added IBSS STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Added IBSS STA %pM\n", + sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ ieee80211_queue_work(&local->hw, &local->sta_finish_work); @@ -459,8 +458,7 @@ int sta_info_insert_rcu(struct sta_info *sta) __acquires(RCU) } #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Inserted STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ /* move reference to rcu-protected */ @@ -618,7 +616,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) struct ieee80211_sub_if_data *sdata; struct sk_buff *skb; unsigned long flags; - int ret; + int ret, i; might_sleep(); @@ -635,7 +633,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) * will be sufficient. */ set_sta_flags(sta, WLAN_STA_BLOCK_BA); - ieee80211_sta_tear_down_BA_sessions(sta); + ieee80211_sta_tear_down_BA_sessions(sta, true); spin_lock_irqsave(&local->sta_lock, flags); ret = sta_info_hash_del(local, sta); @@ -646,10 +644,10 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) if (ret) return ret; - if (sta->key) { - ieee80211_key_free(local, sta->key); - WARN_ON(sta->key); - } + for (i = 0; i < NUM_DEFAULT_KEYS; i++) + ieee80211_key_free(local, sta->gtk[i]); + if (sta->ptk) + ieee80211_key_free(local, sta->ptk); sta->dead = true; @@ -690,8 +688,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) #endif #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Removed STA %pM\n", - wiphy_name(local->hw.wiphy), sta->sta.addr); + wiphy_debug(local->hw.wiphy, "Removed STA %pM\n", sta->sta.addr); #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ cancel_work_sync(&sta->drv_unblock_wk); @@ -841,13 +838,20 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, mutex_unlock(&local->sta_mtx); } -struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, - const u8 *addr) +struct ieee80211_sta *ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, + const u8 *addr, + const u8 *localaddr) { struct sta_info *sta, *nxt; - /* Just return a random station ... first in list ... */ + /* + * Just return a random station if localaddr is NULL + * ... first in list. + */ for_each_sta_info(hw_to_local(hw), addr, sta, nxt) { + if (localaddr && + compare_ether_addr(sta->sdata->vif.addr, localaddr) != 0) + continue; if (!sta->uploaded) return NULL; return &sta->sta; @@ -855,7 +859,7 @@ struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, return NULL; } -EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); +EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_ifaddr); struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *addr) diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 54262e72376d0e662ebbb1b27b02a14e6a869cdb..9265acadef32d862c11889c2d96575147fcec972 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -79,6 +79,7 @@ enum ieee80211_sta_info_flags { * @dialog_token: dialog token for aggregation session * @state: session state (see above) * @stop_initiator: initiator of a session stop + * @tx_stop: TX DelBA frame when stopping * * This structure is protected by RCU and the per-station * spinlock. Assignments to the array holding it must hold @@ -95,6 +96,7 @@ struct tid_ampdu_tx { unsigned long state; u8 dialog_token; u8 stop_initiator; + bool tx_stop; }; /** @@ -103,6 +105,7 @@ struct tid_ampdu_tx { * @reorder_buf: buffer to reorder incoming aggregated MPDUs * @reorder_time: jiffies when skb was added * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value) + * @reorder_timer: releases expired frames from the reorder buffer. * @head_seq_num: head sequence number in reordering buffer. * @stored_mpdu_num: number of MPDUs in reordering buffer * @ssn: Starting Sequence Number expected to be aggregated. @@ -110,20 +113,25 @@ struct tid_ampdu_tx { * @timeout: reset timer value (in TUs). * @dialog_token: dialog token for aggregation session * @rcu_head: RCU head used for freeing this struct + * @reorder_lock: serializes access to reorder buffer, see below. * * This structure is protected by RCU and the per-station * spinlock. Assignments to the array holding it must hold - * the spinlock, only the RX path can access it under RCU - * lock-free. The RX path, since it is single-threaded, - * can even modify the structure without locking since the - * only other modifications to it are done when the struct - * can not yet or no longer be found by the RX path. + * the spinlock. + * + * The @reorder_lock is used to protect the variables and + * arrays such as @reorder_buf, @reorder_time, @head_seq_num, + * @stored_mpdu_num and @reorder_time from being corrupted by + * concurrent access of the RX path and the expired frame + * release timer. */ struct tid_ampdu_rx { struct rcu_head rcu_head; + spinlock_t reorder_lock; struct sk_buff **reorder_buf; unsigned long *reorder_time; struct timer_list session_timer; + struct timer_list reorder_timer; u16 head_seq_num; u16 stored_mpdu_num; u16 ssn; @@ -191,7 +199,8 @@ enum plink_state { * @hnext: hash table linked list pointer * @local: pointer to the global information * @sdata: virtual interface this station belongs to - * @key: peer key negotiated with this station, if any + * @ptk: peer key negotiated with this station, if any + * @gtk: group keys negotiated with this station, if any * @rate_ctrl: rate control algorithm reference * @rate_ctrl_priv: rate control private per-STA pointer * @last_tx_rate: rate used for last transmit, to report to userspace as @@ -246,7 +255,8 @@ struct sta_info { struct sta_info *hnext; struct ieee80211_local *local; struct ieee80211_sub_if_data *sdata; - struct ieee80211_key *key; + struct ieee80211_key *gtk[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; + struct ieee80211_key *ptk; struct rate_control_ref *rate_ctrl; void *rate_ctrl_priv; spinlock_t lock; diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 34da67995d94ae91c8982776fd3e9104c161079f..3153c19893b81ebe1309290b41491010cd296999 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -58,6 +58,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, info->control.vif = &sta->sdata->vif; info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING | IEEE80211_TX_INTFL_RETRANSMISSION; + info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; sta->tx_filtered_count++; @@ -114,11 +115,10 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, #ifdef CONFIG_MAC80211_VERBOSE_DEBUG if (net_ratelimit()) - printk(KERN_DEBUG "%s: dropped TX filtered frame, " - "queue_len=%d PS=%d @%lu\n", - wiphy_name(local->hw.wiphy), - skb_queue_len(&sta->tx_filtered), - !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); + wiphy_debug(local->hw.wiphy, + "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", + skb_queue_len(&sta->tx_filtered), + !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); #endif dev_kfree_skb(skb); } @@ -176,7 +176,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { /* the HW cannot have attempted that rate */ - if (i >= hw->max_rates) { + if (i >= hw->max_report_rates) { info->status.rates[i].idx = -1; info->status.rates[i].count = 0; } else if (info->status.rates[i].idx >= 0) { @@ -296,7 +296,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) } if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) - cfg80211_action_tx_status( + cfg80211_mgmt_tx_status( skb->dev, (unsigned long) skb, skb->data, skb->len, !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c54db966926b455dc3d72ae0f71b7c71d3204861..96c594309506432b897b4ab8c749aed4cb3c1349 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -273,6 +273,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) */ return TX_DROP; + if (tx->sdata->vif.type == NL80211_IFTYPE_WDS) + return TX_CONTINUE; + if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) return TX_CONTINUE; @@ -351,8 +354,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) local->total_ps_buffered = total; #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG - printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", - wiphy_name(local->hw.wiphy), purged); + wiphy_debug(local->hw.wiphy, "PS buffers full - purged %d frames\n", + purged); #endif } @@ -508,6 +511,18 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) return ieee80211_tx_h_multicast_ps_buf(tx); } +static ieee80211_tx_result debug_noinline +ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) +{ + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); + + if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol && + tx->sdata->control_port_no_encrypt)) + info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; + + return TX_CONTINUE; +} + static ieee80211_tx_result debug_noinline ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) { @@ -517,7 +532,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) tx->key = NULL; - else if (tx->sta && (key = rcu_dereference(tx->sta->key))) + else if (tx->sta && (key = rcu_dereference(tx->sta->ptk))) tx->key = key; else if (ieee80211_is_mgmt(hdr->frame_control) && is_multicast_ether_addr(hdr->addr1) && @@ -527,7 +542,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) else if ((key = rcu_dereference(tx->sdata->default_key))) tx->key = key; else if (tx->sdata->drop_unencrypted && - (tx->skb->protocol != cpu_to_be16(ETH_P_PAE)) && + (tx->skb->protocol != tx->sdata->control_port_protocol) && !(info->flags & IEEE80211_TX_CTL_INJECTED) && (!ieee80211_is_robust_mgmt_frame(hdr) || (ieee80211_is_action(hdr->frame_control) && @@ -543,15 +558,16 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) tx->key->tx_rx_count++; /* TODO: add threshold stuff again */ - switch (tx->key->conf.alg) { - case ALG_WEP: + switch (tx->key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: if (ieee80211_is_auth(hdr->frame_control)) break; - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: if (!ieee80211_is_data_present(hdr->frame_control)) tx->key = NULL; break; - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: if (!ieee80211_is_data_present(hdr->frame_control) && !ieee80211_use_mfp(hdr->frame_control, tx->sta, tx->skb)) @@ -561,7 +577,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) IEEE80211_KEY_FLAG_SW_MGMT) && ieee80211_is_mgmt(hdr->frame_control); break; - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: if (!ieee80211_is_mgmt(hdr->frame_control)) tx->key = NULL; break; @@ -946,22 +962,31 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) static ieee80211_tx_result debug_noinline ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); + if (!tx->key) return TX_CONTINUE; - switch (tx->key->conf.alg) { - case ALG_WEP: + switch (tx->key->conf.cipher) { + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: return ieee80211_crypto_wep_encrypt(tx); - case ALG_TKIP: + case WLAN_CIPHER_SUITE_TKIP: return ieee80211_crypto_tkip_encrypt(tx); - case ALG_CCMP: + case WLAN_CIPHER_SUITE_CCMP: return ieee80211_crypto_ccmp_encrypt(tx); - case ALG_AES_CMAC: + case WLAN_CIPHER_SUITE_AES_CMAC: return ieee80211_crypto_aes_cmac_encrypt(tx); + default: + /* handle hw-only algorithm */ + if (info->control.hw_key) { + ieee80211_tx_set_protected(tx); + return TX_CONTINUE; + } + break; + } - /* not reached */ - WARN_ON(1); return TX_DROP; } @@ -1339,6 +1364,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) CALL_TXH(ieee80211_tx_h_dynamic_ps); CALL_TXH(ieee80211_tx_h_check_assoc); CALL_TXH(ieee80211_tx_h_ps_buf); + CALL_TXH(ieee80211_tx_h_check_control_port_protocol); CALL_TXH(ieee80211_tx_h_select_key); if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) CALL_TXH(ieee80211_tx_h_rate_ctrl); @@ -1511,8 +1537,8 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, I802_DEBUG_INC(local->tx_expand_skb_head); if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { - printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n", - wiphy_name(local->hw.wiphy)); + wiphy_debug(local->hw.wiphy, + "failed to reallocate TX buffer\n"); return -ENOMEM; } @@ -1586,6 +1612,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, return; } + hdr = (struct ieee80211_hdr *) skb->data; info->control.vif = &sdata->vif; if (ieee80211_vif_is_mesh(&sdata->vif) && @@ -1699,7 +1726,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, u16 ethertype, hdrlen, meshhdrlen = 0; __le16 fc; struct ieee80211_hdr hdr; - struct ieee80211s_hdr mesh_hdr; + struct ieee80211s_hdr mesh_hdr __maybe_unused; const u8 *encaps_data; int encaps_len, skip_header_bytes; int nh_pos, h_pos; @@ -1816,7 +1843,8 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, #endif case NL80211_IFTYPE_STATION: memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); - if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { + if (sdata->u.mgd.use_4addr && + cpu_to_be16(ethertype) != sdata->control_port_protocol) { fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); /* RA TA DA SA */ memcpy(hdr.addr2, sdata->vif.addr, ETH_ALEN); @@ -1869,7 +1897,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, if (!ieee80211_vif_is_mesh(&sdata->vif) && unlikely(!is_multicast_ether_addr(hdr.addr1) && !(sta_flags & WLAN_STA_AUTHORIZED) && - !(ethertype == ETH_P_PAE && + !(cpu_to_be16(ethertype) == sdata->control_port_protocol && compare_ether_addr(sdata->vif.addr, skb->data + ETH_ALEN) == 0))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG @@ -2068,8 +2096,7 @@ void ieee80211_tx_pending(unsigned long data) if (skb_queue_empty(&local->pending[i])) list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_tx_wake_queue( - netdev_get_tx_queue(sdata->dev, i)); + netif_wake_subqueue(sdata->dev, i); } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 748387d45bc05f8fbab8a579066c7c0771a6cca8..0b6fc92bc0d7520bbb9050c2850acaa5da71a1ff 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -283,8 +283,11 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, if (skb_queue_empty(&local->pending[queue])) { rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue)); + list_for_each_entry_rcu(sdata, &local->interfaces, list) { + if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) + continue; + netif_wake_subqueue(sdata->dev, queue); + } rcu_read_unlock(); } else tasklet_schedule(&local->tx_pending_tasklet); @@ -323,7 +326,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) - netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue)); + netif_stop_subqueue(sdata->dev, queue); rcu_read_unlock(); } @@ -471,16 +474,10 @@ void ieee80211_iterate_active_interfaces( list_for_each_entry(sdata, &local->interfaces, list) { switch (sdata->vif.type) { - case __NL80211_IFTYPE_AFTER_LAST: - case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: continue; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: + default: break; } if (ieee80211_sdata_running(sdata)) @@ -505,16 +502,10 @@ void ieee80211_iterate_active_interfaces_atomic( list_for_each_entry_rcu(sdata, &local->interfaces, list) { switch (sdata->vif.type) { - case __NL80211_IFTYPE_AFTER_LAST: - case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: continue; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_MESH_POINT: + default: break; } if (ieee80211_sdata_running(sdata)) @@ -904,26 +895,34 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, const u8 *ie, size_t ie_len, - enum ieee80211_band band) + enum ieee80211_band band, u32 rate_mask, + u8 channel) { struct ieee80211_supported_band *sband; u8 *pos; size_t offset = 0, noffset; int supp_rates_len, i; + u8 rates[32]; + int num_rates; + int ext_rates_len; sband = local->hw.wiphy->bands[band]; pos = buffer; - supp_rates_len = min_t(int, sband->n_bitrates, 8); + num_rates = 0; + for (i = 0; i < sband->n_bitrates; i++) { + if ((BIT(i) & rate_mask) == 0) + continue; /* skip rate */ + rates[num_rates++] = (u8) (sband->bitrates[i].bitrate / 5); + } + + supp_rates_len = min_t(int, num_rates, 8); *pos++ = WLAN_EID_SUPP_RATES; *pos++ = supp_rates_len; - - for (i = 0; i < supp_rates_len; i++) { - int rate = sband->bitrates[i].bitrate; - *pos++ = (u8) (rate / 5); - } + memcpy(pos, rates, supp_rates_len); + pos += supp_rates_len; /* insert "request information" if in custom IEs */ if (ie && ie_len) { @@ -941,14 +940,18 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, offset = noffset; } - if (sband->n_bitrates > i) { + ext_rates_len = num_rates - supp_rates_len; + if (ext_rates_len > 0) { *pos++ = WLAN_EID_EXT_SUPP_RATES; - *pos++ = sband->n_bitrates - i; + *pos++ = ext_rates_len; + memcpy(pos, rates + supp_rates_len, ext_rates_len); + pos += ext_rates_len; + } - for (; i < sband->n_bitrates; i++) { - int rate = sband->bitrates[i].bitrate; - *pos++ = (u8) (rate / 5); - } + if (channel && sband->band == IEEE80211_BAND_2GHZ) { + *pos++ = WLAN_EID_DS_PARAMS; + *pos++ = 1; + *pos++ = channel; } /* insert custom IEs that go before HT */ @@ -1017,6 +1020,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, struct ieee80211_mgmt *mgmt; size_t buf_len; u8 *buf; + u8 chan; /* FIXME: come up with a proper value */ buf = kmalloc(200 + ie_len, GFP_KERNEL); @@ -1026,8 +1030,14 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, return; } + chan = ieee80211_frequency_to_channel( + local->hw.conf.channel->center_freq); + buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, - local->hw.conf.channel->band); + local->hw.conf.channel->band, + sdata->rc_rateidx_mask + [local->hw.conf.channel->band], + chan); skb = ieee80211_probereq_get(&local->hw, &sdata->vif, ssid, ssid_len, @@ -1189,7 +1199,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) /* ignore virtual */ break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: WARN_ON(1); break; } @@ -1209,7 +1221,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) mutex_lock(&local->sta_mtx); list_for_each_entry(sta, &local->sta_list, list) { - ieee80211_sta_tear_down_BA_sessions(sta); + ieee80211_sta_tear_down_BA_sessions(sta, true); clear_sta_flags(sta, WLAN_STA_BLOCK_BA); } @@ -1285,17 +1297,13 @@ static int check_mgd_smps(struct ieee80211_if_managed *ifmgd, } /* must hold iflist_mtx */ -void ieee80211_recalc_smps(struct ieee80211_local *local, - struct ieee80211_sub_if_data *forsdata) +void ieee80211_recalc_smps(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF; int count = 0; - if (forsdata) - WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx)); - - WARN_ON(!mutex_is_locked(&local->iflist_mtx)); + lockdep_assert_held(&local->iflist_mtx); /* * This function could be improved to handle multiple @@ -1308,22 +1316,12 @@ void ieee80211_recalc_smps(struct ieee80211_local *local, */ list_for_each_entry(sdata, &local->interfaces, list) { - if (!netif_running(sdata->dev)) + if (!ieee80211_sdata_running(sdata)) continue; if (sdata->vif.type != NL80211_IFTYPE_STATION) goto set; - if (sdata != forsdata) { - /* - * This nested is ok -- we are holding the iflist_mtx - * so can't get here twice or so. But it's required - * since normally we acquire it first and then the - * iflist_mtx. - */ - mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING); - count += check_mgd_smps(&sdata->u.mgd, &smps_mode); - mutex_unlock(&sdata->u.mgd.mtx); - } else - count += check_mgd_smps(&sdata->u.mgd, &smps_mode); + + count += check_mgd_smps(&sdata->u.mgd, &smps_mode); if (count > 1) { smps_mode = IEEE80211_SMPS_OFF; diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index 9ebc8d8a1f5b20d3e6872610042128848ec0a4a8..2ff6d1e3ed21565524fc55c724b24bbee67dd0c6 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c @@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, struct ieee80211_key *key) { u32 klen; - u8 *rc4key; + u8 rc4key[3 + WLAN_KEY_LEN_WEP104]; u8 keyidx; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; unsigned int hdrlen; @@ -240,15 +240,11 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, keyidx = skb->data[hdrlen + 3] >> 6; - if (!key || keyidx != key->conf.keyidx || key->conf.alg != ALG_WEP) + if (!key || keyidx != key->conf.keyidx) return -1; klen = 3 + key->conf.keylen; - rc4key = kmalloc(klen, GFP_ATOMIC); - if (!rc4key) - return -1; - /* Prepend 24-bit IV to RC4 key */ memcpy(rc4key, skb->data + hdrlen, 3); @@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, len)) ret = -1; - kfree(rc4key); - /* Trim ICV */ skb_trim(skb, skb->len - WEP_ICV_LEN); diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 81d4ad64184a2e76d35414586746fa6d03f8cf9d..ae344d1ba0560480665e1b939b15b058f5fddc4c 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -43,7 +43,7 @@ enum work_action { /* utils */ static inline void ASSERT_WORK_MTX(struct ieee80211_local *local) { - WARN_ON(!mutex_is_locked(&local->work_mtx)); + lockdep_assert_held(&local->mtx); } /* @@ -757,7 +757,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, mgmt = (struct ieee80211_mgmt *) skb->data; fc = le16_to_cpu(mgmt->frame_control); - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { const u8 *bssid = NULL; @@ -833,7 +833,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, WARN(1, "unexpected: %d", rma); } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); if (rma != WORK_ACT_DONE) goto out; @@ -845,9 +845,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, case WORK_DONE_REQUEUE: synchronize_rcu(); wk->started = false; /* restart */ - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_add_tail(&wk->list, &local->work_list); - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); } out: @@ -888,9 +888,9 @@ static void ieee80211_work_work(struct work_struct *work) while ((skb = skb_dequeue(&local->work_skb_queue))) ieee80211_work_rx_queued_mgmt(local, skb); - ieee80211_recalc_idle(local); + mutex_lock(&local->mtx); - mutex_lock(&local->work_mtx); + ieee80211_recalc_idle(local); list_for_each_entry_safe(wk, tmp, &local->work_list, list) { bool started = wk->started; @@ -995,20 +995,16 @@ static void ieee80211_work_work(struct work_struct *work) run_again(local, jiffies + HZ/2); } - mutex_lock(&local->scan_mtx); - if (list_empty(&local->work_list) && local->scan_req && !local->scanning) ieee80211_queue_delayed_work(&local->hw, &local->scan_work, round_jiffies_relative(0)); - mutex_unlock(&local->scan_mtx); - - mutex_unlock(&local->work_mtx); - ieee80211_recalc_idle(local); + mutex_unlock(&local->mtx); + list_for_each_entry_safe(wk, tmp, &free_work, list) { wk->done(wk, NULL); list_del(&wk->list); @@ -1035,16 +1031,15 @@ void ieee80211_add_work(struct ieee80211_work *wk) wk->started = false; local = wk->sdata->local; - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_add_tail(&wk->list, &local->work_list); - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); ieee80211_queue_work(&local->hw, &local->work_work); } void ieee80211_work_init(struct ieee80211_local *local) { - mutex_init(&local->work_mtx); INIT_LIST_HEAD(&local->work_list); setup_timer(&local->work_timer, ieee80211_work_timer, (unsigned long)local); @@ -1057,7 +1052,7 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) struct ieee80211_local *local = sdata->local; struct ieee80211_work *wk; - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; @@ -1065,19 +1060,19 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) wk->started = true; wk->timeout = jiffies; } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); /* run cleanups etc. */ ieee80211_work_work(&local->work_work); - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry(wk, &local->work_list, list) { if (wk->sdata != sdata) continue; WARN_ON(1); break; } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); } ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, @@ -1163,7 +1158,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, struct ieee80211_work *wk, *tmp; bool found = false; - mutex_lock(&local->work_mtx); + mutex_lock(&local->mtx); list_for_each_entry_safe(wk, tmp, &local->work_list, list) { if ((unsigned long) wk == cookie) { wk->timeout = jiffies; @@ -1171,7 +1166,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, break; } } - mutex_unlock(&local->work_mtx); + mutex_unlock(&local->mtx); if (!found) return -ENOENT; diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 8d59d27d887e3a0b96d9d995e3138595f0a13c79..bee230d8fd1168849c14c6dfaee26b5b696ed220 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -36,8 +36,8 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) int tail; hdr = (struct ieee80211_hdr *)skb->data; - if (!tx->key || tx->key->conf.alg != ALG_TKIP || skb->len < 24 || - !ieee80211_is_data_present(hdr->frame_control)) + if (!tx->key || tx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || + skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) return TX_CONTINUE; hdrlen = ieee80211_hdrlen(hdr->frame_control); @@ -94,7 +94,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) if (status->flag & RX_FLAG_MMIC_STRIPPED) return RX_CONTINUE; - if (!rx->key || rx->key->conf.alg != ALG_TKIP || + if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_TKIP || !ieee80211_has_protected(hdr->frame_control) || !ieee80211_is_data_present(hdr->frame_control)) return RX_CONTINUE; @@ -117,7 +117,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) key = &rx->key->conf.key[key_offset]; michael_mic(key, hdr, data, data_len, mic); if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { - if (!(rx->flags & IEEE80211_RX_RA_MATCH)) + if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_DROP_UNUSABLE; mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, @@ -221,19 +221,13 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) if (!rx->sta || skb->len - hdrlen < 12) return RX_DROP_UNUSABLE; - if (status->flag & RX_FLAG_DECRYPTED) { - if (status->flag & RX_FLAG_IV_STRIPPED) { - /* - * Hardware took care of all processing, including - * replay protection, and stripped the ICV/IV so - * we cannot do any checks here. - */ - return RX_CONTINUE; - } - - /* let TKIP code verify IV, but skip decryption */ + /* + * Let TKIP code verify IV, but skip decryption. + * In the case where hardware checks the IV as well, + * we don't even get here, see ieee80211_rx_h_decrypt() + */ + if (status->flag & RX_FLAG_DECRYPTED) hwaccel = 1; - } res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, key, skb->data + hdrlen, @@ -447,10 +441,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) if (!rx->sta || data_len < 0) return RX_DROP_UNUSABLE; - if ((status->flag & RX_FLAG_DECRYPTED) && - (status->flag & RX_FLAG_IV_STRIPPED)) - return RX_CONTINUE; - ccmp_hdr2pn(pn, skb->data + hdrlen); queue = ieee80211_is_mgmt(hdr->frame_control) ? @@ -564,10 +554,6 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) if (!ieee80211_is_mgmt(hdr->frame_control)) return RX_CONTINUE; - if ((status->flag & RX_FLAG_DECRYPTED) && - (status->flag & RX_FLAG_IV_STRIPPED)) - return RX_CONTINUE; - if (skb->len < 24 + sizeof(*mmie)) return RX_DROP_UNUSABLE; diff --git a/net/netfilter/core.c b/net/netfilter/core.c index fdaec7daff1d539038ef6ee6c0d0acfeae6e7cf6..85dabb86be6f45dda9b5686466ce487c2b848a5c 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -105,10 +105,8 @@ EXPORT_SYMBOL(nf_register_hooks); void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) { - unsigned int i; - - for (i = 0; i < n; i++) - nf_unregister_hook(®[i]); + while (n-- > 0) + nf_unregister_hook(®[n]); } EXPORT_SYMBOL(nf_unregister_hooks); diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig index 46a77d5c3887dc7c874b327a77afb539c8d92777..a22dac227055e7499bfd9d8dd509ee5fba3e1c9b 100644 --- a/net/netfilter/ipvs/Kconfig +++ b/net/netfilter/ipvs/Kconfig @@ -3,7 +3,7 @@ # menuconfig IP_VS tristate "IP virtual server support" - depends on NET && INET && NETFILTER && NF_CONNTRACK + depends on NET && INET && NETFILTER ---help--- IP Virtual Server support will let you build a high-performance virtual server based on cluster of two or more real servers. This @@ -235,7 +235,8 @@ comment 'IPVS application helper' config IP_VS_FTP tristate "FTP protocol helper" - depends on IP_VS_PROTO_TCP && NF_NAT + depends on IP_VS_PROTO_TCP && NF_CONNTRACK && NF_NAT + select IP_VS_NFCT ---help--- FTP is a protocol that transfers IP address and/or port number in the payload. In the virtual server via Network Address Translation, @@ -247,4 +248,19 @@ config IP_VS_FTP If you want to compile it in kernel, say Y. To compile it as a module, choose M here. If unsure, say N. +config IP_VS_NFCT + bool "Netfilter connection tracking" + depends on NF_CONNTRACK + ---help--- + The Netfilter connection tracking support allows the IPVS + connection state to be exported to the Netfilter framework + for filtering purposes. + +config IP_VS_PE_SIP + tristate "SIP persistence engine" + depends on IP_VS_PROTO_UDP + depends on NF_CONNTRACK_SIP + ---help--- + Allow persistence based on the SIP Call-ID + endif # IP_VS diff --git a/net/netfilter/ipvs/Makefile b/net/netfilter/ipvs/Makefile index e3baefd7066e56d9ceaad6025c6de3e710a2e870..34ee602ddb667d806691111c4f6cede4227a6872 100644 --- a/net/netfilter/ipvs/Makefile +++ b/net/netfilter/ipvs/Makefile @@ -9,10 +9,13 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_UDP) += ip_vs_proto_udp.o ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH_ESP) += ip_vs_proto_ah_esp.o ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_SCTP) += ip_vs_proto_sctp.o +ip_vs-extra_objs-y := +ip_vs-extra_objs-$(CONFIG_IP_VS_NFCT) += ip_vs_nfct.o + ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ - ip_vs_est.o ip_vs_proto.o \ - $(ip_vs_proto-objs-y) + ip_vs_est.o ip_vs_proto.o ip_vs_pe.o \ + $(ip_vs_proto-objs-y) $(ip_vs-extra_objs-y) # IPVS core @@ -32,3 +35,6 @@ obj-$(CONFIG_IP_VS_NQ) += ip_vs_nq.o # IPVS application helpers obj-$(CONFIG_IP_VS_FTP) += ip_vs_ftp.o + +# IPVS connection template retrievers +obj-$(CONFIG_IP_VS_PE_SIP) += ip_vs_pe_sip.o diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c index e76f87f4aca80fdc4e9f0557c0b491dcdeff7556..a475edee0912e8fef842aa1632ecc2d19599f59d 100644 --- a/net/netfilter/ipvs/ip_vs_app.c +++ b/net/netfilter/ipvs/ip_vs_app.c @@ -103,8 +103,8 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port) goto out; list_add(&inc->a_list, &app->incs_list); - IP_VS_DBG(9, "%s application %s:%u registered\n", - pp->name, inc->name, inc->port); + IP_VS_DBG(9, "%s App %s:%u registered\n", + pp->name, inc->name, ntohs(inc->port)); return 0; @@ -130,7 +130,7 @@ ip_vs_app_inc_release(struct ip_vs_app *inc) pp->unregister_app(inc); IP_VS_DBG(9, "%s App %s:%u unregistered\n", - pp->name, inc->name, inc->port); + pp->name, inc->name, ntohs(inc->port)); list_del(&inc->a_list); diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index b71c69a2db138ac30aadb13e02a697322d54ac90..e9adecdc8ca4779468c494c1a2418049ca2384eb 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -148,6 +148,42 @@ static unsigned int ip_vs_conn_hashkey(int af, unsigned proto, & ip_vs_conn_tab_mask; } +static unsigned int ip_vs_conn_hashkey_param(const struct ip_vs_conn_param *p, + bool inverse) +{ + const union nf_inet_addr *addr; + __be16 port; + + if (p->pe_data && p->pe->hashkey_raw) + return p->pe->hashkey_raw(p, ip_vs_conn_rnd, inverse) & + ip_vs_conn_tab_mask; + + if (likely(!inverse)) { + addr = p->caddr; + port = p->cport; + } else { + addr = p->vaddr; + port = p->vport; + } + + return ip_vs_conn_hashkey(p->af, p->protocol, addr, port); +} + +static unsigned int ip_vs_conn_hashkey_conn(const struct ip_vs_conn *cp) +{ + struct ip_vs_conn_param p; + + ip_vs_conn_fill_param(cp->af, cp->protocol, &cp->caddr, cp->cport, + NULL, 0, &p); + + if (cp->dest && cp->dest->svc->pe) { + p.pe = cp->dest->svc->pe; + p.pe_data = cp->pe_data; + p.pe_data_len = cp->pe_data_len; + } + + return ip_vs_conn_hashkey_param(&p, false); +} /* * Hashes ip_vs_conn in ip_vs_conn_tab by proto,addr,port. @@ -162,7 +198,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp) return 0; /* Hash by protocol, client address and port */ - hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); + hash = ip_vs_conn_hashkey_conn(cp); ct_write_lock(hash); spin_lock(&cp->lock); @@ -195,7 +231,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp) int ret; /* unhash it and decrease its reference counter */ - hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); + hash = ip_vs_conn_hashkey_conn(cp); ct_write_lock(hash); spin_lock(&cp->lock); @@ -218,27 +254,26 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp) /* * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. * Called for pkts coming from OUTside-to-INside. - * s_addr, s_port: pkt source address (foreign host) - * d_addr, d_port: pkt dest address (load balancer) + * p->caddr, p->cport: pkt source address (foreign host) + * p->vaddr, p->vport: pkt dest address (load balancer) */ -static inline struct ip_vs_conn *__ip_vs_conn_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port) +static inline struct ip_vs_conn * +__ip_vs_conn_in_get(const struct ip_vs_conn_param *p) { unsigned hash; struct ip_vs_conn *cp; - hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port); + hash = ip_vs_conn_hashkey_param(p, false); ct_read_lock(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (cp->af == af && - ip_vs_addr_equal(af, s_addr, &cp->caddr) && - ip_vs_addr_equal(af, d_addr, &cp->vaddr) && - s_port == cp->cport && d_port == cp->vport && - ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && - protocol == cp->protocol) { + if (cp->af == p->af && + ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) && + ip_vs_addr_equal(p->af, p->vaddr, &cp->vaddr) && + p->cport == cp->cport && p->vport == cp->vport && + ((!p->cport) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && + p->protocol == cp->protocol) { /* HIT */ atomic_inc(&cp->refcnt); ct_read_unlock(hash); @@ -251,99 +286,111 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get return NULL; } -struct ip_vs_conn *ip_vs_conn_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port) +struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p) { struct ip_vs_conn *cp; - cp = __ip_vs_conn_in_get(af, protocol, s_addr, s_port, d_addr, d_port); - if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) - cp = __ip_vs_conn_in_get(af, protocol, s_addr, 0, d_addr, - d_port); + cp = __ip_vs_conn_in_get(p); + if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) { + struct ip_vs_conn_param cport_zero_p = *p; + cport_zero_p.cport = 0; + cp = __ip_vs_conn_in_get(&cport_zero_p); + } IP_VS_DBG_BUF(9, "lookup/in %s %s:%d->%s:%d %s\n", - ip_vs_proto_name(protocol), - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), + ip_vs_proto_name(p->protocol), + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), cp ? "hit" : "not hit"); return cp; } +static int +ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb, + const struct ip_vs_iphdr *iph, + unsigned int proto_off, int inverse, + struct ip_vs_conn_param *p) +{ + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); + if (pptr == NULL) + return 1; + + if (likely(!inverse)) + ip_vs_conn_fill_param(af, iph->protocol, &iph->saddr, pptr[0], + &iph->daddr, pptr[1], p); + else + ip_vs_conn_fill_param(af, iph->protocol, &iph->daddr, pptr[1], + &iph->saddr, pptr[0], p); + return 0; +} + struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, const struct ip_vs_iphdr *iph, unsigned int proto_off, int inverse) { - __be16 _ports[2], *pptr; + struct ip_vs_conn_param p; - pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); - if (pptr == NULL) + if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p)) return NULL; - if (likely(!inverse)) - return ip_vs_conn_in_get(af, iph->protocol, - &iph->saddr, pptr[0], - &iph->daddr, pptr[1]); - else - return ip_vs_conn_in_get(af, iph->protocol, - &iph->daddr, pptr[1], - &iph->saddr, pptr[0]); + return ip_vs_conn_in_get(&p); } EXPORT_SYMBOL_GPL(ip_vs_conn_in_get_proto); /* Get reference to connection template */ -struct ip_vs_conn *ip_vs_ct_in_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port) +struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p) { unsigned hash; struct ip_vs_conn *cp; - hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port); + hash = ip_vs_conn_hashkey_param(p, false); ct_read_lock(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (cp->af == af && - ip_vs_addr_equal(af, s_addr, &cp->caddr) && + if (p->pe_data && p->pe->ct_match) { + if (p->pe->ct_match(p, cp)) + goto out; + continue; + } + + if (cp->af == p->af && + ip_vs_addr_equal(p->af, p->caddr, &cp->caddr) && /* protocol should only be IPPROTO_IP if - * d_addr is a fwmark */ - ip_vs_addr_equal(protocol == IPPROTO_IP ? AF_UNSPEC : af, - d_addr, &cp->vaddr) && - s_port == cp->cport && d_port == cp->vport && + * p->vaddr is a fwmark */ + ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC : + p->af, p->vaddr, &cp->vaddr) && + p->cport == cp->cport && p->vport == cp->vport && cp->flags & IP_VS_CONN_F_TEMPLATE && - protocol == cp->protocol) { - /* HIT */ - atomic_inc(&cp->refcnt); + p->protocol == cp->protocol) goto out; - } } cp = NULL; out: + if (cp) + atomic_inc(&cp->refcnt); ct_read_unlock(hash); IP_VS_DBG_BUF(9, "template lookup/in %s %s:%d->%s:%d %s\n", - ip_vs_proto_name(protocol), - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), + ip_vs_proto_name(p->protocol), + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), cp ? "hit" : "not hit"); return cp; } -/* - * Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. - * Called for pkts coming from inside-to-OUTside. - * s_addr, s_port: pkt source address (inside host) - * d_addr, d_port: pkt dest address (foreign host) - */ -struct ip_vs_conn *ip_vs_conn_out_get -(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port, - const union nf_inet_addr *d_addr, __be16 d_port) +/* Gets ip_vs_conn associated with supplied parameters in the ip_vs_conn_tab. + * Called for pkts coming from inside-to-OUTside. + * p->caddr, p->cport: pkt source address (inside host) + * p->vaddr, p->vport: pkt dest address (foreign host) */ +struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p) { unsigned hash; struct ip_vs_conn *cp, *ret=NULL; @@ -351,16 +398,16 @@ struct ip_vs_conn *ip_vs_conn_out_get /* * Check for "full" addressed entries */ - hash = ip_vs_conn_hashkey(af, protocol, d_addr, d_port); + hash = ip_vs_conn_hashkey_param(p, true); ct_read_lock(hash); list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { - if (cp->af == af && - ip_vs_addr_equal(af, d_addr, &cp->caddr) && - ip_vs_addr_equal(af, s_addr, &cp->daddr) && - d_port == cp->cport && s_port == cp->dport && - protocol == cp->protocol) { + if (cp->af == p->af && + ip_vs_addr_equal(p->af, p->vaddr, &cp->caddr) && + ip_vs_addr_equal(p->af, p->caddr, &cp->daddr) && + p->vport == cp->cport && p->cport == cp->dport && + p->protocol == cp->protocol) { /* HIT */ atomic_inc(&cp->refcnt); ret = cp; @@ -371,9 +418,9 @@ struct ip_vs_conn *ip_vs_conn_out_get ct_read_unlock(hash); IP_VS_DBG_BUF(9, "lookup/out %s %s:%d->%s:%d %s\n", - ip_vs_proto_name(protocol), - IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port), - IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port), + ip_vs_proto_name(p->protocol), + IP_VS_DBG_ADDR(p->af, p->caddr), ntohs(p->cport), + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), ret ? "hit" : "not hit"); return ret; @@ -385,20 +432,12 @@ ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, const struct ip_vs_iphdr *iph, unsigned int proto_off, int inverse) { - __be16 _ports[2], *pptr; + struct ip_vs_conn_param p; - pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports); - if (pptr == NULL) + if (ip_vs_conn_fill_param_proto(af, skb, iph, proto_off, inverse, &p)) return NULL; - if (likely(!inverse)) - return ip_vs_conn_out_get(af, iph->protocol, - &iph->saddr, pptr[0], - &iph->daddr, pptr[1]); - else - return ip_vs_conn_out_get(af, iph->protocol, - &iph->daddr, pptr[1], - &iph->saddr, pptr[0]); + return ip_vs_conn_out_get(&p); } EXPORT_SYMBOL_GPL(ip_vs_conn_out_get_proto); @@ -505,6 +544,8 @@ static inline int ip_vs_dest_totalconns(struct ip_vs_dest *dest) static inline void ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) { + unsigned int conn_flags; + /* if dest is NULL, then return directly */ if (!dest) return; @@ -512,16 +553,20 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) /* Increase the refcnt counter of the dest */ atomic_inc(&dest->refcnt); + conn_flags = atomic_read(&dest->conn_flags); + if (cp->protocol != IPPROTO_UDP) + conn_flags &= ~IP_VS_CONN_F_ONE_PACKET; /* Bind with the destination and its corresponding transmitter */ - if ((cp->flags & IP_VS_CONN_F_SYNC) && - (!(cp->flags & IP_VS_CONN_F_TEMPLATE))) + if (cp->flags & IP_VS_CONN_F_SYNC) { /* if the connection is not template and is created * by sync, preserve the activity flag. */ - cp->flags |= atomic_read(&dest->conn_flags) & - (~IP_VS_CONN_F_INACTIVE); - else - cp->flags |= atomic_read(&dest->conn_flags); + if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) + conn_flags &= ~IP_VS_CONN_F_INACTIVE; + /* connections inherit forwarding method from dest */ + cp->flags &= ~IP_VS_CONN_F_FWD_MASK; + } + cp->flags |= conn_flags; cp->dest = dest; IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d " @@ -717,6 +762,10 @@ static void ip_vs_conn_expire(unsigned long data) if (cp->control) ip_vs_control_del(cp); + if (cp->flags & IP_VS_CONN_F_NFCT) + ip_vs_conn_drop_conntrack(cp); + + kfree(cp->pe_data); if (unlikely(cp->app != NULL)) ip_vs_unbind_app(cp); ip_vs_unbind_dest(cp); @@ -751,13 +800,12 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp) * Create a new connection entry and hash it into the ip_vs_conn_tab */ struct ip_vs_conn * -ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, - const union nf_inet_addr *vaddr, __be16 vport, +ip_vs_conn_new(const struct ip_vs_conn_param *p, const union nf_inet_addr *daddr, __be16 dport, unsigned flags, struct ip_vs_dest *dest) { struct ip_vs_conn *cp; - struct ip_vs_protocol *pp = ip_vs_proto_get(proto); + struct ip_vs_protocol *pp = ip_vs_proto_get(p->protocol); cp = kmem_cache_zalloc(ip_vs_conn_cachep, GFP_ATOMIC); if (cp == NULL) { @@ -767,17 +815,21 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, INIT_LIST_HEAD(&cp->c_list); setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp); - cp->af = af; - cp->protocol = proto; - ip_vs_addr_copy(af, &cp->caddr, caddr); - cp->cport = cport; - ip_vs_addr_copy(af, &cp->vaddr, vaddr); - cp->vport = vport; + cp->af = p->af; + cp->protocol = p->protocol; + ip_vs_addr_copy(p->af, &cp->caddr, p->caddr); + cp->cport = p->cport; + ip_vs_addr_copy(p->af, &cp->vaddr, p->vaddr); + cp->vport = p->vport; /* proto should only be IPPROTO_IP if d_addr is a fwmark */ - ip_vs_addr_copy(proto == IPPROTO_IP ? AF_UNSPEC : af, + ip_vs_addr_copy(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af, &cp->daddr, daddr); cp->dport = dport; cp->flags = flags; + if (flags & IP_VS_CONN_F_TEMPLATE && p->pe_data) { + cp->pe_data = p->pe_data; + cp->pe_data_len = p->pe_data_len; + } spin_lock_init(&cp->lock); /* @@ -803,7 +855,7 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, /* Bind its packet transmitter */ #ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) + if (p->af == AF_INET6) ip_vs_bind_xmit_v6(cp); else #endif @@ -812,13 +864,22 @@ ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport, if (unlikely(pp && atomic_read(&pp->appcnt))) ip_vs_bind_app(cp, pp); + /* + * Allow conntrack to be preserved. By default, conntrack + * is created and destroyed for every packet. + * Sometimes keeping conntrack can be useful for + * IP_VS_CONN_F_ONE_PACKET too. + */ + + if (ip_vs_conntrack_enabled()) + cp->flags |= IP_VS_CONN_F_NFCT; + /* Hash it in the ip_vs_conn_tab finally */ ip_vs_conn_hash(cp); return cp; } - /* * /proc/net/ip_vs_conn entries */ @@ -834,7 +895,7 @@ static void *ip_vs_conn_array(struct seq_file *seq, loff_t pos) list_for_each_entry(cp, &ip_vs_conn_tab[idx], c_list) { if (pos-- == 0) { seq->private = &ip_vs_conn_tab[idx]; - return cp; + return cp; } } ct_read_unlock_bh(idx); @@ -891,30 +952,45 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v) if (v == SEQ_START_TOKEN) seq_puts(seq, - "Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires\n"); + "Pro FromIP FPrt ToIP TPrt DestIP DPrt State Expires PEName PEData\n"); else { const struct ip_vs_conn *cp = v; + char pe_data[IP_VS_PENAME_MAXLEN + IP_VS_PEDATA_MAXLEN + 3]; + size_t len = 0; + + if (cp->dest && cp->pe_data && + cp->dest->svc->pe->show_pe_data) { + pe_data[0] = ' '; + len = strlen(cp->dest->svc->pe->name); + memcpy(pe_data + 1, cp->dest->svc->pe->name, len); + pe_data[len + 1] = ' '; + len += 2; + len += cp->dest->svc->pe->show_pe_data(cp, + pe_data + len); + } + pe_data[len] = '\0'; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) - seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X %pI6 %04X %-11s %7lu\n", + seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X " + "%pI6 %04X %-11s %7lu%s\n", ip_vs_proto_name(cp->protocol), &cp->caddr.in6, ntohs(cp->cport), &cp->vaddr.in6, ntohs(cp->vport), &cp->daddr.in6, ntohs(cp->dport), ip_vs_state_name(cp->protocol, cp->state), - (cp->timer.expires-jiffies)/HZ); + (cp->timer.expires-jiffies)/HZ, pe_data); else #endif seq_printf(seq, "%-3s %08X %04X %08X %04X" - " %08X %04X %-11s %7lu\n", + " %08X %04X %-11s %7lu%s\n", ip_vs_proto_name(cp->protocol), ntohl(cp->caddr.ip), ntohs(cp->cport), ntohl(cp->vaddr.ip), ntohs(cp->vport), ntohl(cp->daddr.ip), ntohs(cp->dport), ip_vs_state_name(cp->protocol, cp->state), - (cp->timer.expires-jiffies)/HZ); + (cp->timer.expires-jiffies)/HZ, pe_data); } return 0; } diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 4c2f89df5ccecc40f1dc9200772a4e8bb3e85b95..b4e51e9c5a04ad4e1314a338529cc0284407feb3 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -40,6 +40,7 @@ #include #include /* for icmp_send */ #include +#include #include #include @@ -47,6 +48,7 @@ #ifdef CONFIG_IP_VS_IPV6 #include #include +#include #endif #include @@ -175,6 +177,18 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction, return pp->state_transition(cp, direction, skb, pp); } +static inline void +ip_vs_conn_fill_param_persist(const struct ip_vs_service *svc, + struct sk_buff *skb, int protocol, + const union nf_inet_addr *caddr, __be16 cport, + const union nf_inet_addr *vaddr, __be16 vport, + struct ip_vs_conn_param *p) +{ + ip_vs_conn_fill_param(svc->af, protocol, caddr, cport, vaddr, vport, p); + p->pe = svc->pe; + if (p->pe && p->pe->fill_param) + p->pe->fill_param(p, skb); +} /* * IPVS persistent scheduling function @@ -185,15 +199,16 @@ ip_vs_set_state(struct ip_vs_conn *cp, int direction, */ static struct ip_vs_conn * ip_vs_sched_persist(struct ip_vs_service *svc, - const struct sk_buff *skb, + struct sk_buff *skb, __be16 ports[2]) { struct ip_vs_conn *cp = NULL; struct ip_vs_iphdr iph; struct ip_vs_dest *dest; struct ip_vs_conn *ct; - __be16 dport; /* destination port to forward */ - __be16 flags; + __be16 dport = 0; /* destination port to forward */ + unsigned int flags; + struct ip_vs_conn_param param; union nf_inet_addr snet; /* source network of the client, after masking */ @@ -226,120 +241,75 @@ ip_vs_sched_persist(struct ip_vs_service *svc, * service, and a template like * is created for other persistent services. */ - if (ports[1] == svc->port) { - /* Check if a template already exists */ - if (svc->port != FTPPORT) - ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, - &iph.daddr, ports[1]); - else - ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, - &iph.daddr, 0); - - if (!ct || !ip_vs_check_template(ct)) { - /* - * No template found or the dest of the connection - * template is not available. - */ - dest = svc->scheduler->schedule(svc, skb); - if (dest == NULL) { - IP_VS_DBG(1, "p-schedule: no dest found.\n"); - return NULL; - } - - /* - * Create a template like for non-ftp service, - * and - * for ftp service. + { + int protocol = iph.protocol; + const union nf_inet_addr *vaddr = &iph.daddr; + const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; + __be16 vport = 0; + + if (ports[1] == svc->port) { + /* non-FTP template: + * + * FTP template: + * */ if (svc->port != FTPPORT) - ct = ip_vs_conn_new(svc->af, iph.protocol, - &snet, 0, - &iph.daddr, - ports[1], - &dest->addr, dest->port, - IP_VS_CONN_F_TEMPLATE, - dest); - else - ct = ip_vs_conn_new(svc->af, iph.protocol, - &snet, 0, - &iph.daddr, 0, - &dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, - dest); - if (ct == NULL) - return NULL; - - ct->timeout = svc->timeout; + vport = ports[1]; } else { - /* set destination with the found template */ - dest = ct->dest; - } - dport = dest->port; - } else { - /* - * Note: persistent fwmark-based services and persistent - * port zero service are handled here. - * fwmark template: - * port zero template: - */ - if (svc->fwmark) { - union nf_inet_addr fwmark = { - .ip = htonl(svc->fwmark) - }; - - ct = ip_vs_ct_in_get(svc->af, IPPROTO_IP, &snet, 0, - &fwmark, 0); - } else - ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, - &iph.daddr, 0); - - if (!ct || !ip_vs_check_template(ct)) { - /* - * If it is not persistent port zero, return NULL, - * otherwise create a connection template. + /* Note: persistent fwmark-based services and + * persistent port zero service are handled here. + * fwmark template: + * + * port zero template: + * */ - if (svc->port) - return NULL; - - dest = svc->scheduler->schedule(svc, skb); - if (dest == NULL) { - IP_VS_DBG(1, "p-schedule: no dest found.\n"); - return NULL; + if (svc->fwmark) { + protocol = IPPROTO_IP; + vaddr = &fwmark; } + } + ip_vs_conn_fill_param_persist(svc, skb, protocol, &snet, 0, + vaddr, vport, ¶m); + } - /* - * Create a template according to the service - */ - if (svc->fwmark) { - union nf_inet_addr fwmark = { - .ip = htonl(svc->fwmark) - }; - - ct = ip_vs_conn_new(svc->af, IPPROTO_IP, - &snet, 0, - &fwmark, 0, - &dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, - dest); - } else - ct = ip_vs_conn_new(svc->af, iph.protocol, - &snet, 0, - &iph.daddr, 0, - &dest->addr, 0, - IP_VS_CONN_F_TEMPLATE, - dest); - if (ct == NULL) - return NULL; - - ct->timeout = svc->timeout; - } else { - /* set destination with the found template */ - dest = ct->dest; + /* Check if a template already exists */ + ct = ip_vs_ct_in_get(¶m); + if (!ct || !ip_vs_check_template(ct)) { + /* No template found or the dest of the connection + * template is not available. + */ + dest = svc->scheduler->schedule(svc, skb); + if (!dest) { + IP_VS_DBG(1, "p-schedule: no dest found.\n"); + kfree(param.pe_data); + return NULL; } - dport = ports[1]; + + if (ports[1] == svc->port && svc->port != FTPPORT) + dport = dest->port; + + /* Create a template + * This adds param.pe_data to the template, + * and thus param.pe_data will be destroyed + * when the template expires */ + ct = ip_vs_conn_new(¶m, &dest->addr, dport, + IP_VS_CONN_F_TEMPLATE, dest); + if (ct == NULL) { + kfree(param.pe_data); + return NULL; + } + + ct->timeout = svc->timeout; + } else { + /* set destination with the found template */ + dest = ct->dest; + kfree(param.pe_data); } + dport = ports[1]; + if (dport == svc->port && dest->port) + dport = dest->port; + flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && iph.protocol == IPPROTO_UDP)? IP_VS_CONN_F_ONE_PACKET : 0; @@ -347,12 +317,9 @@ ip_vs_sched_persist(struct ip_vs_service *svc, /* * Create a new connection according to the template */ - cp = ip_vs_conn_new(svc->af, iph.protocol, - &iph.saddr, ports[0], - &iph.daddr, ports[1], - &dest->addr, dport, - flags, - dest); + ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, ports[0], + &iph.daddr, ports[1], ¶m); + cp = ip_vs_conn_new(¶m, &dest->addr, dport, flags, dest); if (cp == NULL) { ip_vs_conn_put(ct); return NULL; @@ -376,23 +343,53 @@ ip_vs_sched_persist(struct ip_vs_service *svc, * Protocols supported: TCP, UDP */ struct ip_vs_conn * -ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) +ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb, + struct ip_vs_protocol *pp, int *ignored) { struct ip_vs_conn *cp = NULL; struct ip_vs_iphdr iph; struct ip_vs_dest *dest; - __be16 _ports[2], *pptr, flags; + __be16 _ports[2], *pptr; + unsigned int flags; + *ignored = 1; ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports); if (pptr == NULL) return NULL; + /* + * FTPDATA needs this check when using local real server. + * Never schedule Active FTPDATA connections from real server. + * For LVS-NAT they must be already created. For other methods + * with persistence the connection is created on SYN+ACK. + */ + if (pptr[0] == FTPDATA) { + IP_VS_DBG_PKT(12, svc->af, pp, skb, 0, + "Not scheduling FTPDATA"); + return NULL; + } + + /* + * Do not schedule replies from local real server. It is risky + * for fwmark services but mostly for persistent services. + */ + if ((!skb->dev || skb->dev->flags & IFF_LOOPBACK) && + (svc->flags & IP_VS_SVC_F_PERSISTENT || svc->fwmark) && + (cp = pp->conn_in_get(svc->af, skb, pp, &iph, iph.len, 1))) { + IP_VS_DBG_PKT(12, svc->af, pp, skb, 0, + "Not scheduling reply for existing connection"); + __ip_vs_conn_put(cp); + return NULL; + } + /* * Persistent service */ - if (svc->flags & IP_VS_SVC_F_PERSISTENT) + if (svc->flags & IP_VS_SVC_F_PERSISTENT) { + *ignored = 0; return ip_vs_sched_persist(svc, skb, pptr); + } /* * Non-persistent service @@ -405,6 +402,8 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) return NULL; } + *ignored = 0; + dest = svc->scheduler->schedule(svc, skb); if (dest == NULL) { IP_VS_DBG(1, "Schedule: no dest found.\n"); @@ -418,14 +417,16 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) /* * Create a connection entry. */ - cp = ip_vs_conn_new(svc->af, iph.protocol, - &iph.saddr, pptr[0], - &iph.daddr, pptr[1], - &dest->addr, dest->port ? dest->port : pptr[1], - flags, - dest); - if (cp == NULL) - return NULL; + { + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(svc->af, iph.protocol, &iph.saddr, + pptr[0], &iph.daddr, pptr[1], &p); + cp = ip_vs_conn_new(&p, &dest->addr, + dest->port ? dest->port : pptr[1], + flags, dest); + if (!cp) + return NULL; + } IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u " "d:%s:%u conn->flags:%X conn->refcnt:%d\n", @@ -472,23 +473,26 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) { int ret, cs; struct ip_vs_conn *cp; - __u16 flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && - iph.protocol == IPPROTO_UDP)? - IP_VS_CONN_F_ONE_PACKET : 0; + unsigned int flags = (svc->flags & IP_VS_SVC_F_ONEPACKET && + iph.protocol == IPPROTO_UDP)? + IP_VS_CONN_F_ONE_PACKET : 0; union nf_inet_addr daddr = { .all = { 0, 0, 0, 0 } }; ip_vs_service_put(svc); /* create a new connection entry */ IP_VS_DBG(6, "%s(): create a cache_bypass entry\n", __func__); - cp = ip_vs_conn_new(svc->af, iph.protocol, - &iph.saddr, pptr[0], - &iph.daddr, pptr[1], - &daddr, 0, - IP_VS_CONN_F_BYPASS | flags, - NULL); - if (cp == NULL) - return NF_DROP; + { + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(svc->af, iph.protocol, + &iph.saddr, pptr[0], + &iph.daddr, pptr[1], &p); + cp = ip_vs_conn_new(&p, &daddr, 0, + IP_VS_CONN_F_BYPASS | flags, + NULL); + if (!cp) + return NF_DROP; + } /* statistics */ ip_vs_in_stats(cp, skb); @@ -526,9 +530,14 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb, * ICMP_PORT_UNREACH is sent here no matter it is TCP/UDP. --WZ */ #ifdef CONFIG_IP_VS_IPV6 - if (svc->af == AF_INET6) + if (svc->af == AF_INET6) { + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0); - else + } else #endif icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); @@ -540,6 +549,15 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); } +static inline enum ip_defrag_users ip_vs_defrag_user(unsigned int hooknum) +{ + if (NF_INET_LOCAL_IN == hooknum) + return IP_DEFRAG_VS_IN; + if (NF_INET_FORWARD == hooknum) + return IP_DEFRAG_VS_FWD; + return IP_DEFRAG_VS_OUT; +} + static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) { int err = ip_defrag(skb, user); @@ -600,10 +618,10 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, skb->ip_summed = CHECKSUM_UNNECESSARY; if (inout) - IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, + IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph, "Forwarding altered outgoing ICMP"); else - IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, + IP_VS_DBG_PKT(11, AF_INET, pp, skb, (void *)ciph - (void *)iph, "Forwarding altered incoming ICMP"); } @@ -637,17 +655,21 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp, } /* And finally the ICMP checksum */ - icmph->icmp6_cksum = 0; - /* TODO IPv6: is this correct for ICMPv6? */ - ip_vs_checksum_complete(skb, icmp_offset); - skb->ip_summed = CHECKSUM_UNNECESSARY; + icmph->icmp6_cksum = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, + skb->len - icmp_offset, + IPPROTO_ICMPV6, 0); + skb->csum_start = skb_network_header(skb) - skb->head + icmp_offset; + skb->csum_offset = offsetof(struct icmp6hdr, icmp6_cksum); + skb->ip_summed = CHECKSUM_PARTIAL; if (inout) - IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, - "Forwarding altered outgoing ICMPv6"); + IP_VS_DBG_PKT(11, AF_INET6, pp, skb, + (void *)ciph - (void *)iph, + "Forwarding altered outgoing ICMPv6"); else - IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph, - "Forwarding altered incoming ICMPv6"); + IP_VS_DBG_PKT(11, AF_INET6, pp, skb, + (void *)ciph - (void *)iph, + "Forwarding altered incoming ICMPv6"); } #endif @@ -688,10 +710,25 @@ static int handle_response_icmp(int af, struct sk_buff *skb, #endif ip_vs_nat_icmp(skb, pp, cp, 1); +#ifdef CONFIG_IP_VS_IPV6 + if (af == AF_INET6) { + if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0) + goto out; + } else +#endif + if ((sysctl_ip_vs_snat_reroute || + skb_rtable(skb)->rt_flags & RTCF_LOCAL) && + ip_route_me_harder(skb, RTN_LOCAL) != 0) + goto out; + /* do the statistics and put it back */ ip_vs_out_stats(cp, skb); skb->ipvs_property = 1; + if (!(cp->flags & IP_VS_CONN_F_NFCT)) + ip_vs_notrack(skb); + else + ip_vs_update_conntrack(skb, cp, 0); verdict = NF_ACCEPT; out: @@ -705,7 +742,8 @@ static int handle_response_icmp(int af, struct sk_buff *skb, * Find any that might be relevant, check against existing connections. * Currently handles error types - unreachable, quench, ttl exceeded. */ -static int ip_vs_out_icmp(struct sk_buff *skb, int *related) +static int ip_vs_out_icmp(struct sk_buff *skb, int *related, + unsigned int hooknum) { struct iphdr *iph; struct icmphdr _icmph, *ic; @@ -720,7 +758,7 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related) /* reassemble IP fragments */ if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { - if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) + if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -763,7 +801,8 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related) pp->dont_defrag)) return NF_ACCEPT; - IP_VS_DBG_PKT(11, pp, skb, offset, "Checking outgoing ICMP for"); + IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset, + "Checking outgoing ICMP for"); offset += cih->ihl * 4; @@ -779,7 +818,8 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related) } #ifdef CONFIG_IP_VS_IPV6 -static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related) +static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related, + unsigned int hooknum) { struct ipv6hdr *iph; struct icmp6hdr _icmph, *ic; @@ -795,7 +835,7 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related) /* reassemble IP fragments */ if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { - if (ip_vs_gather_frags_v6(skb, IP_DEFRAG_VS_OUT)) + if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -838,7 +878,8 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related) if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag)) return NF_ACCEPT; - IP_VS_DBG_PKT(11, pp, skb, offset, "Checking outgoing ICMPv6 for"); + IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset, + "Checking outgoing ICMPv6 for"); offset += sizeof(struct ipv6hdr); @@ -886,7 +927,7 @@ static unsigned int handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, struct ip_vs_conn *cp, int ihl) { - IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet"); + IP_VS_DBG_PKT(11, af, pp, skb, 0, "Outgoing packet"); if (!skb_make_writable(skb, ihl)) goto drop; @@ -905,6 +946,15 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, ip_send_check(ip_hdr(skb)); } + /* + * nf_iterate does not expect change in the skb->dst->dev. + * It looks like it is not fatal to enable this code for hooks + * where our handlers are at the end of the chain list and + * when all next handlers use skb->dst->dev and not outdev. + * It will definitely route properly the inout NAT traffic + * when multiple paths are used. + */ + /* For policy routing, packets originating from this * machine itself may be routed differently to packets * passing through. We want this packet to be routed as @@ -913,21 +963,25 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, */ #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { - if (ip6_route_me_harder(skb) != 0) + if (sysctl_ip_vs_snat_reroute && ip6_route_me_harder(skb) != 0) goto drop; } else #endif - if (ip_route_me_harder(skb, RTN_LOCAL) != 0) + if ((sysctl_ip_vs_snat_reroute || + skb_rtable(skb)->rt_flags & RTCF_LOCAL) && + ip_route_me_harder(skb, RTN_LOCAL) != 0) goto drop; - IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT"); + IP_VS_DBG_PKT(10, af, pp, skb, 0, "After SNAT"); ip_vs_out_stats(cp, skb); ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp); - ip_vs_update_conntrack(skb, cp, 0); - ip_vs_conn_put(cp); - skb->ipvs_property = 1; + if (!(cp->flags & IP_VS_CONN_F_NFCT)) + ip_vs_notrack(skb); + else + ip_vs_update_conntrack(skb, cp, 0); + ip_vs_conn_put(cp); LeaveFunction(11); return NF_ACCEPT; @@ -935,35 +989,46 @@ handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, drop: ip_vs_conn_put(cp); kfree_skb(skb); + LeaveFunction(11); return NF_STOLEN; } /* - * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT. * Check if outgoing packet belongs to the established ip_vs_conn. */ static unsigned int -ip_vs_out(unsigned int hooknum, struct sk_buff *skb, - const struct net_device *in, const struct net_device *out, - int (*okfn)(struct sk_buff *)) +ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af) { struct ip_vs_iphdr iph; struct ip_vs_protocol *pp; struct ip_vs_conn *cp; - int af; EnterFunction(11); - af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6; - + /* Already marked as IPVS request or reply? */ if (skb->ipvs_property) return NF_ACCEPT; + /* Bad... Do not break raw sockets */ + if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT && + af == AF_INET)) { + struct sock *sk = skb->sk; + struct inet_sock *inet = inet_sk(skb->sk); + + if (inet && sk->sk_family == PF_INET && inet->nodefrag) + return NF_ACCEPT; + } + + if (unlikely(!skb_dst(skb))) + return NF_ACCEPT; + ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { - int related, verdict = ip_vs_out_icmp_v6(skb, &related); + int related; + int verdict = ip_vs_out_icmp_v6(skb, &related, + hooknum); if (related) return verdict; @@ -972,7 +1037,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, } else #endif if (unlikely(iph.protocol == IPPROTO_ICMP)) { - int related, verdict = ip_vs_out_icmp(skb, &related); + int related; + int verdict = ip_vs_out_icmp(skb, &related, hooknum); if (related) return verdict; @@ -986,19 +1052,19 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, /* reassemble IP fragments */ #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { - if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { - int related, verdict = ip_vs_out_icmp_v6(skb, &related); - - if (related) - return verdict; - - ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); + if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { + if (ip_vs_gather_frags_v6(skb, + ip_vs_defrag_user(hooknum))) + return NF_STOLEN; } + + ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); } else #endif if (unlikely(ip_hdr(skb)->frag_off & htons(IP_MF|IP_OFFSET) && !pp->dont_defrag)) { - if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) + if (ip_vs_gather_frags(skb, + ip_vs_defrag_user(hooknum))) return NF_STOLEN; ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); @@ -1009,55 +1075,123 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, */ cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0); - if (unlikely(!cp)) { - if (sysctl_ip_vs_nat_icmp_send && - (pp->protocol == IPPROTO_TCP || - pp->protocol == IPPROTO_UDP || - pp->protocol == IPPROTO_SCTP)) { - __be16 _ports[2], *pptr; - - pptr = skb_header_pointer(skb, iph.len, - sizeof(_ports), _ports); - if (pptr == NULL) - return NF_ACCEPT; /* Not for me */ - if (ip_vs_lookup_real_service(af, iph.protocol, - &iph.saddr, - pptr[0])) { - /* - * Notify the real server: there is no - * existing entry if it is not RST - * packet or not TCP packet. - */ - if ((iph.protocol != IPPROTO_TCP && - iph.protocol != IPPROTO_SCTP) - || ((iph.protocol == IPPROTO_TCP - && !is_tcp_reset(skb, iph.len)) - || (iph.protocol == IPPROTO_SCTP - && !is_sctp_abort(skb, - iph.len)))) { + if (likely(cp)) + return handle_response(af, skb, pp, cp, iph.len); + if (sysctl_ip_vs_nat_icmp_send && + (pp->protocol == IPPROTO_TCP || + pp->protocol == IPPROTO_UDP || + pp->protocol == IPPROTO_SCTP)) { + __be16 _ports[2], *pptr; + + pptr = skb_header_pointer(skb, iph.len, + sizeof(_ports), _ports); + if (pptr == NULL) + return NF_ACCEPT; /* Not for me */ + if (ip_vs_lookup_real_service(af, iph.protocol, + &iph.saddr, + pptr[0])) { + /* + * Notify the real server: there is no + * existing entry if it is not RST + * packet or not TCP packet. + */ + if ((iph.protocol != IPPROTO_TCP && + iph.protocol != IPPROTO_SCTP) + || ((iph.protocol == IPPROTO_TCP + && !is_tcp_reset(skb, iph.len)) + || (iph.protocol == IPPROTO_SCTP + && !is_sctp_abort(skb, + iph.len)))) { #ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) - icmpv6_send(skb, - ICMPV6_DEST_UNREACH, - ICMPV6_PORT_UNREACH, - 0); - else + if (af == AF_INET6) { + struct net *net = + dev_net(skb_dst(skb)->dev); + + if (!skb->dev) + skb->dev = net->loopback_dev; + icmpv6_send(skb, + ICMPV6_DEST_UNREACH, + ICMPV6_PORT_UNREACH, + 0); + } else #endif - icmp_send(skb, - ICMP_DEST_UNREACH, - ICMP_PORT_UNREACH, 0); - return NF_DROP; - } + icmp_send(skb, + ICMP_DEST_UNREACH, + ICMP_PORT_UNREACH, 0); + return NF_DROP; } } - IP_VS_DBG_PKT(12, pp, skb, 0, - "packet continues traversal as normal"); - return NF_ACCEPT; } + IP_VS_DBG_PKT(12, af, pp, skb, 0, + "ip_vs_out: packet continues traversal as normal"); + return NF_ACCEPT; +} + +/* + * It is hooked at the NF_INET_FORWARD and NF_INET_LOCAL_IN chain, + * used only for VS/NAT. + * Check if packet is reply for established ip_vs_conn. + */ +static unsigned int +ip_vs_reply4(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip_vs_out(hooknum, skb, AF_INET); +} + +/* + * It is hooked at the NF_INET_LOCAL_OUT chain, used only for VS/NAT. + * Check if packet is reply for established ip_vs_conn. + */ +static unsigned int +ip_vs_local_reply4(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + unsigned int verdict; + + /* Disable BH in LOCAL_OUT until all places are fixed */ + local_bh_disable(); + verdict = ip_vs_out(hooknum, skb, AF_INET); + local_bh_enable(); + return verdict; +} + +#ifdef CONFIG_IP_VS_IPV6 + +/* + * It is hooked at the NF_INET_FORWARD and NF_INET_LOCAL_IN chain, + * used only for VS/NAT. + * Check if packet is reply for established ip_vs_conn. + */ +static unsigned int +ip_vs_reply6(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip_vs_out(hooknum, skb, AF_INET6); +} - return handle_response(af, skb, pp, cp, iph.len); +/* + * It is hooked at the NF_INET_LOCAL_OUT chain, used only for VS/NAT. + * Check if packet is reply for established ip_vs_conn. + */ +static unsigned int +ip_vs_local_reply6(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + unsigned int verdict; + + /* Disable BH in LOCAL_OUT until all places are fixed */ + local_bh_disable(); + verdict = ip_vs_out(hooknum, skb, AF_INET6); + local_bh_enable(); + return verdict; } +#endif /* * Handle ICMP messages in the outside-to-inside direction (incoming). @@ -1081,8 +1215,7 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) /* reassemble IP fragments */ if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { - if (ip_vs_gather_frags(skb, hooknum == NF_INET_LOCAL_IN ? - IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD)) + if (ip_vs_gather_frags(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -1125,7 +1258,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) pp->dont_defrag)) return NF_ACCEPT; - IP_VS_DBG_PKT(11, pp, skb, offset, "Checking incoming ICMP for"); + IP_VS_DBG_PKT(11, AF_INET, pp, skb, offset, + "Checking incoming ICMP for"); offset += cih->ihl * 4; @@ -1159,7 +1293,14 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) offset += 2 * sizeof(__u16); verdict = ip_vs_icmp_xmit(skb, cp, pp, offset); - /* do not touch skb anymore */ + /* LOCALNODE from FORWARD hook is not supported */ + if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD && + skb_rtable(skb)->rt_flags & RTCF_LOCAL) { + IP_VS_DBG(1, "%s(): " + "local delivery to %pI4 but in FORWARD\n", + __func__, &skb_rtable(skb)->rt_dst); + verdict = NF_DROP; + } out: __ip_vs_conn_put(cp); @@ -1180,14 +1321,13 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) struct ip_vs_protocol *pp; unsigned int offset, verdict; union nf_inet_addr snet; + struct rt6_info *rt; *related = 1; /* reassemble IP fragments */ if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) { - if (ip_vs_gather_frags_v6(skb, hooknum == NF_INET_LOCAL_IN ? - IP_DEFRAG_VS_IN : - IP_DEFRAG_VS_FWD)) + if (ip_vs_gather_frags_v6(skb, ip_vs_defrag_user(hooknum))) return NF_STOLEN; } @@ -1230,7 +1370,8 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag)) return NF_ACCEPT; - IP_VS_DBG_PKT(11, pp, skb, offset, "Checking incoming ICMPv6 for"); + IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset, + "Checking incoming ICMPv6 for"); offset += sizeof(struct ipv6hdr); @@ -1258,7 +1399,15 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) IPPROTO_SCTP == cih->nexthdr) offset += 2 * sizeof(__u16); verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset); - /* do not touch skb anymore */ + /* LOCALNODE from FORWARD hook is not supported */ + if (verdict == NF_ACCEPT && hooknum == NF_INET_FORWARD && + (rt = (struct rt6_info *) skb_dst(skb)) && + rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK) { + IP_VS_DBG(1, "%s(): " + "local delivery to %pI6 but in FORWARD\n", + __func__, &rt->rt6i_dst); + verdict = NF_DROP; + } __ip_vs_conn_put(cp); @@ -1272,35 +1421,49 @@ ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum) * and send it on its way... */ static unsigned int -ip_vs_in(unsigned int hooknum, struct sk_buff *skb, - const struct net_device *in, const struct net_device *out, - int (*okfn)(struct sk_buff *)) +ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) { struct ip_vs_iphdr iph; struct ip_vs_protocol *pp; struct ip_vs_conn *cp; - int ret, restart, af, pkts; + int ret, restart, pkts; - af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6; - - ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); + /* Already marked as IPVS request or reply? */ + if (skb->ipvs_property) + return NF_ACCEPT; /* - * Big tappo: only PACKET_HOST, including loopback for local client - * Don't handle local packets on IPv6 for now + * Big tappo: + * - remote client: only PACKET_HOST + * - route: used for struct net when skb->dev is unset */ - if (unlikely(skb->pkt_type != PACKET_HOST)) { - IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s ignored\n", - skb->pkt_type, - iph.protocol, - IP_VS_DBG_ADDR(af, &iph.daddr)); + if (unlikely((skb->pkt_type != PACKET_HOST && + hooknum != NF_INET_LOCAL_OUT) || + !skb_dst(skb))) { + ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); + IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s" + " ignored in hook %u\n", + skb->pkt_type, iph.protocol, + IP_VS_DBG_ADDR(af, &iph.daddr), hooknum); return NF_ACCEPT; } + ip_vs_fill_iphdr(af, skb_network_header(skb), &iph); + + /* Bad... Do not break raw sockets */ + if (unlikely(skb->sk != NULL && hooknum == NF_INET_LOCAL_OUT && + af == AF_INET)) { + struct sock *sk = skb->sk; + struct inet_sock *inet = inet_sk(skb->sk); + + if (inet && sk->sk_family == PF_INET && inet->nodefrag) + return NF_ACCEPT; + } #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { if (unlikely(iph.protocol == IPPROTO_ICMPV6)) { - int related, verdict = ip_vs_in_icmp_v6(skb, &related, hooknum); + int related; + int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum); if (related) return verdict; @@ -1309,7 +1472,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, } else #endif if (unlikely(iph.protocol == IPPROTO_ICMP)) { - int related, verdict = ip_vs_in_icmp(skb, &related, hooknum); + int related; + int verdict = ip_vs_in_icmp(skb, &related, hooknum); if (related) return verdict; @@ -1329,23 +1493,18 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, if (unlikely(!cp)) { int v; - /* For local client packets, it could be a response */ - cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0); - if (cp) - return handle_response(af, skb, pp, cp, iph.len); - if (!pp->conn_schedule(af, skb, pp, &v, &cp)) return v; } if (unlikely(!cp)) { /* sorry, all this trouble for a no-hit :) */ - IP_VS_DBG_PKT(12, pp, skb, 0, - "packet continues traversal as normal"); + IP_VS_DBG_PKT(12, af, pp, skb, 0, + "ip_vs_in: packet continues traversal as normal"); return NF_ACCEPT; } - IP_VS_DBG_PKT(11, pp, skb, 0, "Incoming packet"); + IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); /* Check the server status */ if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { @@ -1381,8 +1540,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, if (af == AF_INET && (ip_vs_sync_state & IP_VS_STATE_MASTER) && cp->protocol == IPPROTO_SCTP) { if ((cp->state == IP_VS_SCTP_S_ESTABLISHED && - (atomic_read(&cp->in_pkts) % - sysctl_ip_vs_sync_threshold[1] + (pkts % sysctl_ip_vs_sync_threshold[1] == sysctl_ip_vs_sync_threshold[0])) || (cp->old_state != cp->state && ((cp->state == IP_VS_SCTP_S_CLOSED) || @@ -1393,7 +1551,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, } } - if (af == AF_INET && + /* Keep this block last: TCP and others with pp->num_states <= 1 */ + else if (af == AF_INET && (ip_vs_sync_state & IP_VS_STATE_MASTER) && (((cp->protocol != IPPROTO_TCP || cp->state == IP_VS_TCP_S_ESTABLISHED) && @@ -1412,6 +1571,72 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, return ret; } +/* + * AF_INET handler in NF_INET_LOCAL_IN chain + * Schedule and forward packets from remote clients + */ +static unsigned int +ip_vs_remote_request4(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip_vs_in(hooknum, skb, AF_INET); +} + +/* + * AF_INET handler in NF_INET_LOCAL_OUT chain + * Schedule and forward packets from local clients + */ +static unsigned int +ip_vs_local_request4(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + unsigned int verdict; + + /* Disable BH in LOCAL_OUT until all places are fixed */ + local_bh_disable(); + verdict = ip_vs_in(hooknum, skb, AF_INET); + local_bh_enable(); + return verdict; +} + +#ifdef CONFIG_IP_VS_IPV6 + +/* + * AF_INET6 handler in NF_INET_LOCAL_IN chain + * Schedule and forward packets from remote clients + */ +static unsigned int +ip_vs_remote_request6(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip_vs_in(hooknum, skb, AF_INET6); +} + +/* + * AF_INET6 handler in NF_INET_LOCAL_OUT chain + * Schedule and forward packets from local clients + */ +static unsigned int +ip_vs_local_request6(unsigned int hooknum, struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + unsigned int verdict; + + /* Disable BH in LOCAL_OUT until all places are fixed */ + local_bh_disable(); + verdict = ip_vs_in(hooknum, skb, AF_INET6); + local_bh_enable(); + return verdict; +} + +#endif + /* * It is hooked at the NF_INET_FORWARD chain, in order to catch ICMP @@ -1452,23 +1677,39 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, static struct nf_hook_ops ip_vs_ops[] __read_mostly = { + /* After packet filtering, change source only for VS/NAT */ + { + .hook = ip_vs_reply4, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_LOCAL_IN, + .priority = 99, + }, /* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be * applied to IPVS. */ { - .hook = ip_vs_in, + .hook = ip_vs_remote_request4, .owner = THIS_MODULE, .pf = PF_INET, - .hooknum = NF_INET_LOCAL_IN, - .priority = 100, + .hooknum = NF_INET_LOCAL_IN, + .priority = 101, }, - /* After packet filtering, change source only for VS/NAT */ + /* Before ip_vs_in, change source only for VS/NAT */ { - .hook = ip_vs_out, + .hook = ip_vs_local_reply4, .owner = THIS_MODULE, .pf = PF_INET, - .hooknum = NF_INET_FORWARD, - .priority = 100, + .hooknum = NF_INET_LOCAL_OUT, + .priority = -99, + }, + /* After mangle, schedule and forward local requests */ + { + .hook = ip_vs_local_request4, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_LOCAL_OUT, + .priority = -98, }, /* After packet filtering (but before ip_vs_out_icmp), catch icmp * destined for 0.0.0.0/0, which is for incoming IPVS connections */ @@ -1476,27 +1717,51 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hook = ip_vs_forward_icmp, .owner = THIS_MODULE, .pf = PF_INET, - .hooknum = NF_INET_FORWARD, - .priority = 99, + .hooknum = NF_INET_FORWARD, + .priority = 99, + }, + /* After packet filtering, change source only for VS/NAT */ + { + .hook = ip_vs_reply4, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_FORWARD, + .priority = 100, }, #ifdef CONFIG_IP_VS_IPV6 + /* After packet filtering, change source only for VS/NAT */ + { + .hook = ip_vs_reply6, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_INET_LOCAL_IN, + .priority = 99, + }, /* After packet filtering, forward packet through VS/DR, VS/TUN, * or VS/NAT(change destination), so that filtering rules can be * applied to IPVS. */ { - .hook = ip_vs_in, + .hook = ip_vs_remote_request6, .owner = THIS_MODULE, .pf = PF_INET6, - .hooknum = NF_INET_LOCAL_IN, - .priority = 100, + .hooknum = NF_INET_LOCAL_IN, + .priority = 101, }, - /* After packet filtering, change source only for VS/NAT */ + /* Before ip_vs_in, change source only for VS/NAT */ + { + .hook = ip_vs_local_reply6, + .owner = THIS_MODULE, + .pf = PF_INET, + .hooknum = NF_INET_LOCAL_OUT, + .priority = -99, + }, + /* After mangle, schedule and forward local requests */ { - .hook = ip_vs_out, + .hook = ip_vs_local_request6, .owner = THIS_MODULE, .pf = PF_INET6, - .hooknum = NF_INET_FORWARD, - .priority = 100, + .hooknum = NF_INET_LOCAL_OUT, + .priority = -98, }, /* After packet filtering (but before ip_vs_out_icmp), catch icmp * destined for 0.0.0.0/0, which is for incoming IPVS connections */ @@ -1504,8 +1769,16 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = { .hook = ip_vs_forward_icmp_v6, .owner = THIS_MODULE, .pf = PF_INET6, - .hooknum = NF_INET_FORWARD, - .priority = 99, + .hooknum = NF_INET_FORWARD, + .priority = 99, + }, + /* After packet filtering, change source only for VS/NAT */ + { + .hook = ip_vs_reply6, + .owner = THIS_MODULE, + .pf = PF_INET6, + .hooknum = NF_INET_FORWARD, + .priority = 100, }, #endif }; diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 0f0c079c422a03f87616a1c1df76c0e387245a9e..5f5daa30b0afe541d00c1577850ce565c31fb13b 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -61,7 +61,7 @@ static DEFINE_RWLOCK(__ip_vs_svc_lock); static DEFINE_RWLOCK(__ip_vs_rs_lock); /* lock for state and timeout tables */ -static DEFINE_RWLOCK(__ip_vs_securetcp_lock); +static DEFINE_SPINLOCK(ip_vs_securetcp_lock); /* lock for drop entry handling */ static DEFINE_SPINLOCK(__ip_vs_dropentry_lock); @@ -88,6 +88,10 @@ int sysctl_ip_vs_expire_nodest_conn = 0; int sysctl_ip_vs_expire_quiescent_template = 0; int sysctl_ip_vs_sync_threshold[2] = { 3, 50 }; int sysctl_ip_vs_nat_icmp_send = 0; +#ifdef CONFIG_IP_VS_NFCT +int sysctl_ip_vs_conntrack; +#endif +int sysctl_ip_vs_snat_reroute = 1; #ifdef CONFIG_IP_VS_DEBUG @@ -204,7 +208,7 @@ static void update_defense_level(void) spin_unlock(&__ip_vs_droppacket_lock); /* secure_tcp */ - write_lock(&__ip_vs_securetcp_lock); + spin_lock(&ip_vs_securetcp_lock); switch (sysctl_ip_vs_secure_tcp) { case 0: if (old_secure_tcp >= 2) @@ -238,7 +242,7 @@ static void update_defense_level(void) old_secure_tcp = sysctl_ip_vs_secure_tcp; if (to_change >= 0) ip_vs_protocol_timeout_change(sysctl_ip_vs_secure_tcp>1); - write_unlock(&__ip_vs_securetcp_lock); + spin_unlock(&ip_vs_securetcp_lock); local_bh_enable(); } @@ -401,7 +405,7 @@ static int ip_vs_svc_unhash(struct ip_vs_service *svc) * Get service by {proto,addr,port} in the service table. */ static inline struct ip_vs_service * -__ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr, +__ip_vs_service_find(int af, __u16 protocol, const union nf_inet_addr *vaddr, __be16 vport) { unsigned hash; @@ -416,7 +420,6 @@ __ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr, && (svc->port == vport) && (svc->protocol == protocol)) { /* HIT */ - atomic_inc(&svc->usecnt); return svc; } } @@ -429,7 +432,7 @@ __ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr, * Get service by {fwmark} in the service table. */ static inline struct ip_vs_service * -__ip_vs_svc_fwm_get(int af, __u32 fwmark) +__ip_vs_svc_fwm_find(int af, __u32 fwmark) { unsigned hash; struct ip_vs_service *svc; @@ -440,7 +443,6 @@ __ip_vs_svc_fwm_get(int af, __u32 fwmark) list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) { if (svc->fwmark == fwmark && svc->af == af) { /* HIT */ - atomic_inc(&svc->usecnt); return svc; } } @@ -459,14 +461,14 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol, /* * Check the table hashed by fwmark first */ - if (fwmark && (svc = __ip_vs_svc_fwm_get(af, fwmark))) + if (fwmark && (svc = __ip_vs_svc_fwm_find(af, fwmark))) goto out; /* * Check the table hashed by * for "full" addressed entries */ - svc = __ip_vs_service_get(af, protocol, vaddr, vport); + svc = __ip_vs_service_find(af, protocol, vaddr, vport); if (svc == NULL && protocol == IPPROTO_TCP @@ -476,7 +478,7 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol, * Check if ftp service entry exists, the packet * might belong to FTP data connections. */ - svc = __ip_vs_service_get(af, protocol, vaddr, FTPPORT); + svc = __ip_vs_service_find(af, protocol, vaddr, FTPPORT); } if (svc == NULL @@ -484,10 +486,12 @@ ip_vs_service_get(int af, __u32 fwmark, __u16 protocol, /* * Check if the catch-all port (port zero) exists */ - svc = __ip_vs_service_get(af, protocol, vaddr, 0); + svc = __ip_vs_service_find(af, protocol, vaddr, 0); } out: + if (svc) + atomic_inc(&svc->usecnt); read_unlock(&__ip_vs_svc_lock); IP_VS_DBG_BUF(9, "lookup service: fwm %u %s %s:%u %s\n", @@ -506,14 +510,19 @@ __ip_vs_bind_svc(struct ip_vs_dest *dest, struct ip_vs_service *svc) dest->svc = svc; } -static inline void +static void __ip_vs_unbind_svc(struct ip_vs_dest *dest) { struct ip_vs_service *svc = dest->svc; dest->svc = NULL; - if (atomic_dec_and_test(&svc->refcnt)) + if (atomic_dec_and_test(&svc->refcnt)) { + IP_VS_DBG_BUF(3, "Removing service %u/%s:%u usecnt=%d\n", + svc->fwmark, + IP_VS_DBG_ADDR(svc->af, &svc->addr), + ntohs(svc->port), atomic_read(&svc->usecnt)); kfree(svc); + } } @@ -758,31 +767,18 @@ ip_vs_zero_stats(struct ip_vs_stats *stats) * Update a destination in the given service */ static void -__ip_vs_update_dest(struct ip_vs_service *svc, - struct ip_vs_dest *dest, struct ip_vs_dest_user_kern *udest) +__ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest, + struct ip_vs_dest_user_kern *udest, int add) { int conn_flags; /* set the weight and the flags */ atomic_set(&dest->weight, udest->weight); - conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE; - - /* check if local node and update the flags */ -#ifdef CONFIG_IP_VS_IPV6 - if (svc->af == AF_INET6) { - if (__ip_vs_addr_is_local_v6(&udest->addr.in6)) { - conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK) - | IP_VS_CONN_F_LOCALNODE; - } - } else -#endif - if (inet_addr_type(&init_net, udest->addr.ip) == RTN_LOCAL) { - conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK) - | IP_VS_CONN_F_LOCALNODE; - } + conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK; + conn_flags |= IP_VS_CONN_F_INACTIVE; /* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */ - if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != 0) { + if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) { conn_flags |= IP_VS_CONN_F_NOOUTPUT; } else { /* @@ -813,6 +809,29 @@ __ip_vs_update_dest(struct ip_vs_service *svc, dest->flags &= ~IP_VS_DEST_F_OVERLOAD; dest->u_threshold = udest->u_threshold; dest->l_threshold = udest->l_threshold; + + spin_lock(&dest->dst_lock); + ip_vs_dst_reset(dest); + spin_unlock(&dest->dst_lock); + + if (add) + ip_vs_new_estimator(&dest->stats); + + write_lock_bh(&__ip_vs_svc_lock); + + /* Wait until all other svc users go away */ + IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); + + if (add) { + list_add(&dest->n_list, &svc->destinations); + svc->num_dests++; + } + + /* call the update_service, because server weight may be changed */ + if (svc->scheduler->update_service) + svc->scheduler->update_service(svc); + + write_unlock_bh(&__ip_vs_svc_lock); } @@ -843,7 +862,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, return -EINVAL; } - dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC); + dest = kzalloc(sizeof(struct ip_vs_dest), GFP_KERNEL); if (dest == NULL) { pr_err("%s(): no memory.\n", __func__); return -ENOMEM; @@ -860,13 +879,12 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, atomic_set(&dest->activeconns, 0); atomic_set(&dest->inactconns, 0); atomic_set(&dest->persistconns, 0); - atomic_set(&dest->refcnt, 0); + atomic_set(&dest->refcnt, 1); INIT_LIST_HEAD(&dest->d_list); spin_lock_init(&dest->dst_lock); spin_lock_init(&dest->stats.lock); - __ip_vs_update_dest(svc, dest, udest); - ip_vs_new_estimator(&dest->stats); + __ip_vs_update_dest(svc, dest, udest, 1); *dest_p = dest; @@ -926,65 +944,22 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) IP_VS_DBG_ADDR(svc->af, &dest->vaddr), ntohs(dest->vport)); - __ip_vs_update_dest(svc, dest, udest); - /* * Get the destination from the trash */ list_del(&dest->n_list); - ip_vs_new_estimator(&dest->stats); - - write_lock_bh(&__ip_vs_svc_lock); - + __ip_vs_update_dest(svc, dest, udest, 1); + ret = 0; + } else { /* - * Wait until all other svc users go away. + * Allocate and initialize the dest structure */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); - - list_add(&dest->n_list, &svc->destinations); - svc->num_dests++; - - /* call the update_service function of its scheduler */ - if (svc->scheduler->update_service) - svc->scheduler->update_service(svc); - - write_unlock_bh(&__ip_vs_svc_lock); - return 0; - } - - /* - * Allocate and initialize the dest structure - */ - ret = ip_vs_new_dest(svc, udest, &dest); - if (ret) { - return ret; + ret = ip_vs_new_dest(svc, udest, &dest); } - - /* - * Add the dest entry into the list - */ - atomic_inc(&dest->refcnt); - - write_lock_bh(&__ip_vs_svc_lock); - - /* - * Wait until all other svc users go away. - */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); - - list_add(&dest->n_list, &svc->destinations); - svc->num_dests++; - - /* call the update_service function of its scheduler */ - if (svc->scheduler->update_service) - svc->scheduler->update_service(svc); - - write_unlock_bh(&__ip_vs_svc_lock); - LeaveFunction(2); - return 0; + return ret; } @@ -1023,19 +998,7 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) return -ENOENT; } - __ip_vs_update_dest(svc, dest, udest); - - write_lock_bh(&__ip_vs_svc_lock); - - /* Wait until all other svc users go away */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); - - /* call the update_service, because server weight may be changed */ - if (svc->scheduler->update_service) - svc->scheduler->update_service(svc); - - write_unlock_bh(&__ip_vs_svc_lock); - + __ip_vs_update_dest(svc, dest, udest, 0); LeaveFunction(2); return 0; @@ -1062,6 +1025,10 @@ static void __ip_vs_del_dest(struct ip_vs_dest *dest) * the destination into the trash. */ if (atomic_dec_and_test(&dest->refcnt)) { + IP_VS_DBG_BUF(3, "Removing destination %u/%s:%u\n", + dest->vfwmark, + IP_VS_DBG_ADDR(dest->af, &dest->addr), + ntohs(dest->port)); ip_vs_dst_reset(dest); /* simply decrease svc->refcnt here, let the caller check and release the service if nobody refers to it. @@ -1128,7 +1095,7 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) /* * Wait until all other svc users go away. */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); + IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); /* * Unlink dest from the service @@ -1157,6 +1124,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, { int ret = 0; struct ip_vs_scheduler *sched = NULL; + struct ip_vs_pe *pe = NULL; struct ip_vs_service *svc = NULL; /* increase the module use count */ @@ -1167,7 +1135,17 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, if (sched == NULL) { pr_info("Scheduler module ip_vs_%s not found\n", u->sched_name); ret = -ENOENT; - goto out_mod_dec; + goto out_err; + } + + if (u->pe_name && *u->pe_name) { + pe = ip_vs_pe_get(u->pe_name); + if (pe == NULL) { + pr_info("persistence engine module ip_vs_pe_%s " + "not found\n", u->pe_name); + ret = -ENOENT; + goto out_err; + } } #ifdef CONFIG_IP_VS_IPV6 @@ -1177,7 +1155,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, } #endif - svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC); + svc = kzalloc(sizeof(struct ip_vs_service), GFP_KERNEL); if (svc == NULL) { IP_VS_DBG(1, "%s(): no memory\n", __func__); ret = -ENOMEM; @@ -1185,7 +1163,7 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, } /* I'm the first user of the service */ - atomic_set(&svc->usecnt, 1); + atomic_set(&svc->usecnt, 0); atomic_set(&svc->refcnt, 0); svc->af = u->af; @@ -1207,6 +1185,10 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, goto out_err; sched = NULL; + /* Bind the ct retriever */ + ip_vs_bind_pe(svc, pe); + pe = NULL; + /* Update the virtual service counters */ if (svc->port == FTPPORT) atomic_inc(&ip_vs_ftpsvc_counter); @@ -1227,10 +1209,9 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, *svc_p = svc; return 0; - out_err: + out_err: if (svc != NULL) { - if (svc->scheduler) - ip_vs_unbind_scheduler(svc); + ip_vs_unbind_scheduler(svc); if (svc->inc) { local_bh_disable(); ip_vs_app_inc_put(svc->inc); @@ -1239,8 +1220,8 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u, kfree(svc); } ip_vs_scheduler_put(sched); + ip_vs_pe_put(pe); - out_mod_dec: /* decrease the module use count */ ip_vs_use_count_dec(); @@ -1255,6 +1236,7 @@ static int ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) { struct ip_vs_scheduler *sched, *old_sched; + struct ip_vs_pe *pe = NULL, *old_pe = NULL; int ret = 0; /* @@ -1267,6 +1249,17 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) } old_sched = sched; + if (u->pe_name && *u->pe_name) { + pe = ip_vs_pe_get(u->pe_name); + if (pe == NULL) { + pr_info("persistence engine module ip_vs_pe_%s " + "not found\n", u->pe_name); + ret = -ENOENT; + goto out; + } + old_pe = pe; + } + #ifdef CONFIG_IP_VS_IPV6 if (u->af == AF_INET6 && (u->netmask < 1 || u->netmask > 128)) { ret = -EINVAL; @@ -1279,7 +1272,7 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) /* * Wait until all other svc users go away. */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); + IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); /* * Set the flags and timeout value @@ -1318,15 +1311,17 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) } } + old_pe = svc->pe; + if (pe != old_pe) { + ip_vs_unbind_pe(svc); + ip_vs_bind_pe(svc, pe); + } + out_unlock: write_unlock_bh(&__ip_vs_svc_lock); -#ifdef CONFIG_IP_VS_IPV6 out: -#endif - - if (old_sched) - ip_vs_scheduler_put(old_sched); - + ip_vs_scheduler_put(old_sched); + ip_vs_pe_put(old_pe); return ret; } @@ -1340,6 +1335,9 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) { struct ip_vs_dest *dest, *nxt; struct ip_vs_scheduler *old_sched; + struct ip_vs_pe *old_pe; + + pr_info("%s: enter\n", __func__); /* Count only IPv4 services for old get/setsockopt interface */ if (svc->af == AF_INET) @@ -1350,8 +1348,12 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) /* Unbind scheduler */ old_sched = svc->scheduler; ip_vs_unbind_scheduler(svc); - if (old_sched) - ip_vs_scheduler_put(old_sched); + ip_vs_scheduler_put(old_sched); + + /* Unbind persistence engine */ + old_pe = svc->pe; + ip_vs_unbind_pe(svc); + ip_vs_pe_put(old_pe); /* Unbind app inc */ if (svc->inc) { @@ -1378,21 +1380,23 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) /* * Free the service if nobody refers to it */ - if (atomic_read(&svc->refcnt) == 0) + if (atomic_read(&svc->refcnt) == 0) { + IP_VS_DBG_BUF(3, "Removing service %u/%s:%u usecnt=%d\n", + svc->fwmark, + IP_VS_DBG_ADDR(svc->af, &svc->addr), + ntohs(svc->port), atomic_read(&svc->usecnt)); kfree(svc); + } /* decrease the module use count */ ip_vs_use_count_dec(); } /* - * Delete a service from the service list + * Unlink a service from list and try to delete it if its refcnt reached 0 */ -static int ip_vs_del_service(struct ip_vs_service *svc) +static void ip_vs_unlink_service(struct ip_vs_service *svc) { - if (svc == NULL) - return -EEXIST; - /* * Unhash it from the service table */ @@ -1403,11 +1407,21 @@ static int ip_vs_del_service(struct ip_vs_service *svc) /* * Wait until all the svc users go away. */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); + IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); __ip_vs_del_service(svc); write_unlock_bh(&__ip_vs_svc_lock); +} + +/* + * Delete a service from the service list + */ +static int ip_vs_del_service(struct ip_vs_service *svc) +{ + if (svc == NULL) + return -EEXIST; + ip_vs_unlink_service(svc); return 0; } @@ -1426,14 +1440,7 @@ static int ip_vs_flush(void) */ for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { list_for_each_entry_safe(svc, nxt, &ip_vs_svc_table[idx], s_list) { - write_lock_bh(&__ip_vs_svc_lock); - ip_vs_svc_unhash(svc); - /* - * Wait until all the svc users go away. - */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); - __ip_vs_del_service(svc); - write_unlock_bh(&__ip_vs_svc_lock); + ip_vs_unlink_service(svc); } } @@ -1443,14 +1450,7 @@ static int ip_vs_flush(void) for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { list_for_each_entry_safe(svc, nxt, &ip_vs_svc_fwm_table[idx], f_list) { - write_lock_bh(&__ip_vs_svc_lock); - ip_vs_svc_unhash(svc); - /* - * Wait until all the svc users go away. - */ - IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 0); - __ip_vs_del_service(svc); - write_unlock_bh(&__ip_vs_svc_lock); + ip_vs_unlink_service(svc); } } @@ -1579,6 +1579,15 @@ static struct ctl_table vs_vars[] = { .mode = 0644, .proc_handler = proc_do_defense_mode, }, +#ifdef CONFIG_IP_VS_NFCT + { + .procname = "conntrack", + .data = &sysctl_ip_vs_conntrack, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, +#endif { .procname = "secure_tcp", .data = &sysctl_ip_vs_secure_tcp, @@ -1586,6 +1595,13 @@ static struct ctl_table vs_vars[] = { .mode = 0644, .proc_handler = proc_do_defense_mode, }, + { + .procname = "snat_reroute", + .data = &sysctl_ip_vs_snat_reroute, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, #if 0 { .procname = "timeout_established", @@ -2041,6 +2057,8 @@ static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = { static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc, struct ip_vs_service_user *usvc_compat) { + memset(usvc, 0, sizeof(*usvc)); + usvc->af = AF_INET; usvc->protocol = usvc_compat->protocol; usvc->addr.ip = usvc_compat->addr; @@ -2058,6 +2076,8 @@ static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc, static void ip_vs_copy_udest_compat(struct ip_vs_dest_user_kern *udest, struct ip_vs_dest_user *udest_compat) { + memset(udest, 0, sizeof(*udest)); + udest->addr.ip = udest_compat->addr; udest->port = udest_compat->port; udest->conn_flags = udest_compat->conn_flags; @@ -2147,10 +2167,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) /* Lookup the exact service by or fwmark */ if (usvc.fwmark == 0) - svc = __ip_vs_service_get(usvc.af, usvc.protocol, - &usvc.addr, usvc.port); + svc = __ip_vs_service_find(usvc.af, usvc.protocol, + &usvc.addr, usvc.port); else - svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); + svc = __ip_vs_svc_fwm_find(usvc.af, usvc.fwmark); if (cmd != IP_VS_SO_SET_ADD && (svc == NULL || svc->protocol != usvc.protocol)) { @@ -2189,9 +2209,6 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) ret = -EINVAL; } - if (svc) - ip_vs_service_put(svc); - out_unlock: mutex_unlock(&__ip_vs_mutex); out_dec: @@ -2284,10 +2301,10 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get, int ret = 0; if (get->fwmark) - svc = __ip_vs_svc_fwm_get(AF_INET, get->fwmark); + svc = __ip_vs_svc_fwm_find(AF_INET, get->fwmark); else - svc = __ip_vs_service_get(AF_INET, get->protocol, &addr, - get->port); + svc = __ip_vs_service_find(AF_INET, get->protocol, &addr, + get->port); if (svc) { int count = 0; @@ -2315,7 +2332,6 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get, } count++; } - ip_vs_service_put(svc); } else ret = -ESRCH; return ret; @@ -2436,15 +2452,14 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) entry = (struct ip_vs_service_entry *)arg; addr.ip = entry->addr; if (entry->fwmark) - svc = __ip_vs_svc_fwm_get(AF_INET, entry->fwmark); + svc = __ip_vs_svc_fwm_find(AF_INET, entry->fwmark); else - svc = __ip_vs_service_get(AF_INET, entry->protocol, - &addr, entry->port); + svc = __ip_vs_service_find(AF_INET, entry->protocol, + &addr, entry->port); if (svc) { ip_vs_copy_service(entry, svc); if (copy_to_user(user, entry, sizeof(*entry)) != 0) ret = -EFAULT; - ip_vs_service_put(svc); } else ret = -ESRCH; } @@ -2559,6 +2574,8 @@ static const struct nla_policy ip_vs_svc_policy[IPVS_SVC_ATTR_MAX + 1] = { [IPVS_SVC_ATTR_FWMARK] = { .type = NLA_U32 }, [IPVS_SVC_ATTR_SCHED_NAME] = { .type = NLA_NUL_STRING, .len = IP_VS_SCHEDNAME_MAXLEN }, + [IPVS_SVC_ATTR_PE_NAME] = { .type = NLA_NUL_STRING, + .len = IP_VS_PENAME_MAXLEN }, [IPVS_SVC_ATTR_FLAGS] = { .type = NLA_BINARY, .len = sizeof(struct ip_vs_flags) }, [IPVS_SVC_ATTR_TIMEOUT] = { .type = NLA_U32 }, @@ -2635,6 +2652,8 @@ static int ip_vs_genl_fill_service(struct sk_buff *skb, } NLA_PUT_STRING(skb, IPVS_SVC_ATTR_SCHED_NAME, svc->scheduler->name); + if (svc->pe) + NLA_PUT_STRING(skb, IPVS_SVC_ATTR_PE_NAME, svc->pe->name); NLA_PUT(skb, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags); NLA_PUT_U32(skb, IPVS_SVC_ATTR_TIMEOUT, svc->timeout / HZ); NLA_PUT_U32(skb, IPVS_SVC_ATTR_NETMASK, svc->netmask); @@ -2711,10 +2730,12 @@ static int ip_vs_genl_dump_services(struct sk_buff *skb, } static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, - struct nlattr *nla, int full_entry) + struct nlattr *nla, int full_entry, + struct ip_vs_service **ret_svc) { struct nlattr *attrs[IPVS_SVC_ATTR_MAX + 1]; struct nlattr *nla_af, *nla_port, *nla_fwmark, *nla_protocol, *nla_addr; + struct ip_vs_service *svc; /* Parse mandatory identifying service fields first */ if (nla == NULL || @@ -2750,14 +2771,21 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, usvc->fwmark = 0; } + if (usvc->fwmark) + svc = __ip_vs_svc_fwm_find(usvc->af, usvc->fwmark); + else + svc = __ip_vs_service_find(usvc->af, usvc->protocol, + &usvc->addr, usvc->port); + *ret_svc = svc; + /* If a full entry was requested, check for the additional fields */ if (full_entry) { - struct nlattr *nla_sched, *nla_flags, *nla_timeout, + struct nlattr *nla_sched, *nla_flags, *nla_pe, *nla_timeout, *nla_netmask; struct ip_vs_flags flags; - struct ip_vs_service *svc; nla_sched = attrs[IPVS_SVC_ATTR_SCHED_NAME]; + nla_pe = attrs[IPVS_SVC_ATTR_PE_NAME]; nla_flags = attrs[IPVS_SVC_ATTR_FLAGS]; nla_timeout = attrs[IPVS_SVC_ATTR_TIMEOUT]; nla_netmask = attrs[IPVS_SVC_ATTR_NETMASK]; @@ -2768,21 +2796,14 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, nla_memcpy(&flags, nla_flags, sizeof(flags)); /* prefill flags from service if it already exists */ - if (usvc->fwmark) - svc = __ip_vs_svc_fwm_get(usvc->af, usvc->fwmark); - else - svc = __ip_vs_service_get(usvc->af, usvc->protocol, - &usvc->addr, usvc->port); - if (svc) { + if (svc) usvc->flags = svc->flags; - ip_vs_service_put(svc); - } else - usvc->flags = 0; /* set new flags from userland */ usvc->flags = (usvc->flags & ~flags.mask) | (flags.flags & flags.mask); usvc->sched_name = nla_data(nla_sched); + usvc->pe_name = nla_pe ? nla_data(nla_pe) : NULL; usvc->timeout = nla_get_u32(nla_timeout); usvc->netmask = nla_get_u32(nla_netmask); } @@ -2793,17 +2814,11 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, static struct ip_vs_service *ip_vs_genl_find_service(struct nlattr *nla) { struct ip_vs_service_user_kern usvc; + struct ip_vs_service *svc; int ret; - ret = ip_vs_genl_parse_service(&usvc, nla, 0); - if (ret) - return ERR_PTR(ret); - - if (usvc.fwmark) - return __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); - else - return __ip_vs_service_get(usvc.af, usvc.protocol, - &usvc.addr, usvc.port); + ret = ip_vs_genl_parse_service(&usvc, nla, 0, &svc); + return ret ? ERR_PTR(ret) : svc; } static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest) @@ -2894,7 +2909,6 @@ static int ip_vs_genl_dump_dests(struct sk_buff *skb, nla_put_failure: cb->args[0] = idx; - ip_vs_service_put(svc); out_err: mutex_unlock(&__ip_vs_mutex); @@ -3107,17 +3121,10 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) ret = ip_vs_genl_parse_service(&usvc, info->attrs[IPVS_CMD_ATTR_SERVICE], - need_full_svc); + need_full_svc, &svc); if (ret) goto out; - /* Lookup the exact service by or fwmark */ - if (usvc.fwmark == 0) - svc = __ip_vs_service_get(usvc.af, usvc.protocol, - &usvc.addr, usvc.port); - else - svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark); - /* Unless we're adding a new service, the service must already exist */ if ((cmd != IPVS_CMD_NEW_SERVICE) && (svc == NULL)) { ret = -ESRCH; @@ -3151,6 +3158,7 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) break; case IPVS_CMD_DEL_SERVICE: ret = ip_vs_del_service(svc); + /* do not use svc, it can be freed */ break; case IPVS_CMD_NEW_DEST: ret = ip_vs_add_dest(svc, &udest); @@ -3169,8 +3177,6 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) } out: - if (svc) - ip_vs_service_put(svc); mutex_unlock(&__ip_vs_mutex); return ret; @@ -3216,7 +3222,6 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info) goto out_err; } else if (svc) { ret = ip_vs_genl_fill_service(msg, svc); - ip_vs_service_put(svc); if (ret) goto nla_put_failure; } else { @@ -3385,6 +3390,16 @@ int __init ip_vs_control_init(void) EnterFunction(2); + /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */ + for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { + INIT_LIST_HEAD(&ip_vs_svc_table[idx]); + INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); + } + for(idx = 0; idx < IP_VS_RTAB_SIZE; idx++) { + INIT_LIST_HEAD(&ip_vs_rtable[idx]); + } + smp_wmb(); + ret = nf_register_sockopt(&ip_vs_sockopts); if (ret) { pr_err("cannot register sockopt.\n"); @@ -3403,15 +3418,6 @@ int __init ip_vs_control_init(void) sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars); - /* Initialize ip_vs_svc_table, ip_vs_svc_fwm_table, ip_vs_rtable */ - for(idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { - INIT_LIST_HEAD(&ip_vs_svc_table[idx]); - INIT_LIST_HEAD(&ip_vs_svc_fwm_table[idx]); - } - for(idx = 0; idx < IP_VS_RTAB_SIZE; idx++) { - INIT_LIST_HEAD(&ip_vs_rtable[idx]); - } - ip_vs_new_estimator(&ip_vs_stats); /* Hook the defense timer */ diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c index 7e9af5b76d9eb280cc7d197538e5ce6161c42e66..75455000ad1c1cde82b2134970ab3a67a5a97b82 100644 --- a/net/netfilter/ipvs/ip_vs_ftp.c +++ b/net/netfilter/ipvs/ip_vs_ftp.c @@ -20,17 +20,6 @@ * * Author: Wouter Gadeyne * - * - * Code for ip_vs_expect_related and ip_vs_expect_callback is taken from - * http://www.ssi.bg/~ja/nfct/: - * - * ip_vs_nfct.c: Netfilter connection tracking support for IPVS - * - * Portions Copyright (C) 2001-2002 - * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland. - * - * Portions Copyright (C) 2003-2008 - * Julian Anastasov */ #define KMSG_COMPONENT "IPVS" @@ -58,16 +47,6 @@ #define SERVER_STRING "227 Entering Passive Mode (" #define CLIENT_STRING "PORT " -#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u" -#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \ - &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \ - (T)->dst.protonum - -#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u" -#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \ - &((C)->vaddr.ip), ntohs((C)->vport), \ - &((C)->daddr.ip), ntohs((C)->dport), \ - (C)->protocol, (C)->state /* * List of ports (up to IP_VS_APP_MAX_PORTS) to be handled by helper @@ -85,6 +64,8 @@ static int ip_vs_ftp_pasv; static int ip_vs_ftp_init_conn(struct ip_vs_app *app, struct ip_vs_conn *cp) { + /* We use connection tracking for the command connection */ + cp->flags |= IP_VS_CONN_F_NFCT; return 0; } @@ -148,120 +129,6 @@ static int ip_vs_ftp_get_addrport(char *data, char *data_limit, return 1; } -/* - * Called from init_conntrack() as expectfn handler. - */ -static void -ip_vs_expect_callback(struct nf_conn *ct, - struct nf_conntrack_expect *exp) -{ - struct nf_conntrack_tuple *orig, new_reply; - struct ip_vs_conn *cp; - - if (exp->tuple.src.l3num != PF_INET) - return; - - /* - * We assume that no NF locks are held before this callback. - * ip_vs_conn_out_get and ip_vs_conn_in_get should match their - * expectations even if they use wildcard values, now we provide the - * actual values from the newly created original conntrack direction. - * The conntrack is confirmed when packet reaches IPVS hooks. - */ - - /* RS->CLIENT */ - orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; - cp = ip_vs_conn_out_get(exp->tuple.src.l3num, orig->dst.protonum, - &orig->src.u3, orig->src.u.tcp.port, - &orig->dst.u3, orig->dst.u.tcp.port); - if (cp) { - /* Change reply CLIENT->RS to CLIENT->VS */ - new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " - FMT_TUPLE ", found inout cp=" FMT_CONN "\n", - __func__, ct, ct->status, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - new_reply.dst.u3 = cp->vaddr; - new_reply.dst.u.tcp.port = cp->vport; - IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE - ", inout cp=" FMT_CONN "\n", - __func__, ct, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - goto alter; - } - - /* CLIENT->VS */ - cp = ip_vs_conn_in_get(exp->tuple.src.l3num, orig->dst.protonum, - &orig->src.u3, orig->src.u.tcp.port, - &orig->dst.u3, orig->dst.u.tcp.port); - if (cp) { - /* Change reply VS->CLIENT to RS->CLIENT */ - new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " - FMT_TUPLE ", found outin cp=" FMT_CONN "\n", - __func__, ct, ct->status, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - new_reply.src.u3 = cp->daddr; - new_reply.src.u.tcp.port = cp->dport; - IP_VS_DBG(7, "%s(): ct=%p, new tuples=" FMT_TUPLE ", " - FMT_TUPLE ", outin cp=" FMT_CONN "\n", - __func__, ct, - ARG_TUPLE(orig), ARG_TUPLE(&new_reply), - ARG_CONN(cp)); - goto alter; - } - - IP_VS_DBG(7, "%s(): ct=%p, status=0x%lX, tuple=" FMT_TUPLE - " - unknown expect\n", - __func__, ct, ct->status, ARG_TUPLE(orig)); - return; - -alter: - /* Never alter conntrack for non-NAT conns */ - if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ) - nf_conntrack_alter_reply(ct, &new_reply); - ip_vs_conn_put(cp); - return; -} - -/* - * Create NF conntrack expectation with wildcard (optional) source port. - * Then the default callback function will alter the reply and will confirm - * the conntrack entry when the first packet comes. - */ -static void -ip_vs_expect_related(struct sk_buff *skb, struct nf_conn *ct, - struct ip_vs_conn *cp, u_int8_t proto, - const __be16 *port, int from_rs) -{ - struct nf_conntrack_expect *exp; - - BUG_ON(!ct || ct == &nf_conntrack_untracked); - - exp = nf_ct_expect_alloc(ct); - if (!exp) - return; - - if (from_rs) - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, - nf_ct_l3num(ct), &cp->daddr, &cp->caddr, - proto, port, &cp->cport); - else - nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, - nf_ct_l3num(ct), &cp->caddr, &cp->vaddr, - proto, port, &cp->vport); - - exp->expectfn = ip_vs_expect_callback; - - IP_VS_DBG(7, "%s(): ct=%p, expect tuple=" FMT_TUPLE "\n", - __func__, ct, ARG_TUPLE(&exp->tuple)); - nf_ct_expect_related(exp); - nf_ct_expect_put(exp); -} - /* * Look at outgoing ftp packets to catch the response to a PASV command * from the server (inside-to-outside). @@ -328,14 +195,19 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, /* * Now update or create an connection entry for it */ - n_cp = ip_vs_conn_out_get(AF_INET, iph->protocol, &from, port, - &cp->caddr, 0); + { + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(AF_INET, iph->protocol, + &from, port, &cp->caddr, 0, &p); + n_cp = ip_vs_conn_out_get(&p); + } if (!n_cp) { - n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP, - &cp->caddr, 0, - &cp->vaddr, port, - &from, port, - IP_VS_CONN_F_NO_CPORT, + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(AF_INET, IPPROTO_TCP, &cp->caddr, + 0, &cp->vaddr, port, &p); + n_cp = ip_vs_conn_new(&p, &from, port, + IP_VS_CONN_F_NO_CPORT | + IP_VS_CONN_F_NFCT, cp->dest); if (!n_cp) return 0; @@ -370,9 +242,14 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp, ret = nf_nat_mangle_tcp_packet(skb, ct, ctinfo, start-data, end-start, buf, buf_len); - if (ret) - ip_vs_expect_related(skb, ct, n_cp, - IPPROTO_TCP, NULL, 0); + if (ret) { + ip_vs_nfct_expect_related(skb, ct, n_cp, + IPPROTO_TCP, 0, 0); + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->ip_summed = CHECKSUM_UNNECESSARY; + /* csum is updated */ + ret = 1; + } } /* @@ -479,21 +356,22 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp, ip_vs_proto_name(iph->protocol), &to.ip, ntohs(port), &cp->vaddr.ip, 0); - n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol, - &to, port, - &cp->vaddr, htons(ntohs(cp->vport)-1)); - if (!n_cp) { - n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP, - &to, port, + { + struct ip_vs_conn_param p; + ip_vs_conn_fill_param(AF_INET, iph->protocol, &to, port, &cp->vaddr, htons(ntohs(cp->vport)-1), - &cp->daddr, htons(ntohs(cp->dport)-1), - 0, - cp->dest); - if (!n_cp) - return 0; + &p); + n_cp = ip_vs_conn_in_get(&p); + if (!n_cp) { + n_cp = ip_vs_conn_new(&p, &cp->daddr, + htons(ntohs(cp->dport)-1), + IP_VS_CONN_F_NFCT, cp->dest); + if (!n_cp) + return 0; - /* add its controller */ - ip_vs_control_add(n_cp, cp); + /* add its controller */ + ip_vs_control_add(n_cp, cp); + } } /* diff --git a/net/netfilter/ipvs/ip_vs_nfct.c b/net/netfilter/ipvs/ip_vs_nfct.c new file mode 100644 index 0000000000000000000000000000000000000000..4680647cd450ec3b397a40630090e95b967bcbab --- /dev/null +++ b/net/netfilter/ipvs/ip_vs_nfct.c @@ -0,0 +1,292 @@ +/* + * ip_vs_nfct.c: Netfilter connection tracking support for IPVS + * + * Portions Copyright (C) 2001-2002 + * Antefacto Ltd, 181 Parnell St, Dublin 1, Ireland. + * + * Portions Copyright (C) 2003-2010 + * Julian Anastasov + * + * + * This code is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * Authors: + * Ben North + * Julian Anastasov Reorganize and sync with latest kernels + * Hannes Eder Extend NFCT support for FTP, ipvs match + * + * + * Current status: + * + * - provide conntrack confirmation for new and related connections, by + * this way we can see their proper conntrack state in all hooks + * - support for all forwarding methods, not only NAT + * - FTP support (NAT), ability to support other NAT apps with expectations + * - to correctly create expectations for related NAT connections the proper + * NF conntrack support must be already installed, eg. ip_vs_ftp requires + * nf_conntrack_ftp ... iptables_nat for the same ports (but no iptables + * NAT rules are needed) + * - alter reply for NAT when forwarding packet in original direction: + * conntrack from client in NEW or RELATED (Passive FTP DATA) state or + * when RELATED conntrack is created from real server (Active FTP DATA) + * - if iptables_nat is not loaded the Passive FTP will not work (the + * PASV response can not be NAT-ed) but Active FTP should work + * + */ + +#define KMSG_COMPONENT "IPVS" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define FMT_TUPLE "%pI4:%u->%pI4:%u/%u" +#define ARG_TUPLE(T) &(T)->src.u3.ip, ntohs((T)->src.u.all), \ + &(T)->dst.u3.ip, ntohs((T)->dst.u.all), \ + (T)->dst.protonum + +#define FMT_CONN "%pI4:%u->%pI4:%u->%pI4:%u/%u:%u" +#define ARG_CONN(C) &((C)->caddr.ip), ntohs((C)->cport), \ + &((C)->vaddr.ip), ntohs((C)->vport), \ + &((C)->daddr.ip), ntohs((C)->dport), \ + (C)->protocol, (C)->state + +void +ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) +{ + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + struct nf_conntrack_tuple new_tuple; + + if (ct == NULL || nf_ct_is_confirmed(ct) || nf_ct_is_untracked(ct) || + nf_ct_is_dying(ct)) + return; + + /* Never alter conntrack for non-NAT conns */ + if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) + return; + + /* Alter reply only in original direction */ + if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) + return; + + /* + * The connection is not yet in the hashtable, so we update it. + * CIP->VIP will remain the same, so leave the tuple in + * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the + * real-server we will see RIP->DIP. + */ + new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; + /* + * This will also take care of UDP and other protocols. + */ + if (outin) { + new_tuple.src.u3 = cp->daddr; + if (new_tuple.dst.protonum != IPPROTO_ICMP && + new_tuple.dst.protonum != IPPROTO_ICMPV6) + new_tuple.src.u.tcp.port = cp->dport; + } else { + new_tuple.dst.u3 = cp->vaddr; + if (new_tuple.dst.protonum != IPPROTO_ICMP && + new_tuple.dst.protonum != IPPROTO_ICMPV6) + new_tuple.dst.u.tcp.port = cp->vport; + } + IP_VS_DBG(7, "%s: Updating conntrack ct=%p, status=0x%lX, " + "ctinfo=%d, old reply=" FMT_TUPLE + ", new reply=" FMT_TUPLE ", cp=" FMT_CONN "\n", + __func__, ct, ct->status, ctinfo, + ARG_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple), + ARG_TUPLE(&new_tuple), ARG_CONN(cp)); + nf_conntrack_alter_reply(ct, &new_tuple); +} + +int ip_vs_confirm_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp) +{ + return nf_conntrack_confirm(skb); +} + +/* + * Called from init_conntrack() as expectfn handler. + */ +static void ip_vs_nfct_expect_callback(struct nf_conn *ct, + struct nf_conntrack_expect *exp) +{ + struct nf_conntrack_tuple *orig, new_reply; + struct ip_vs_conn *cp; + struct ip_vs_conn_param p; + + if (exp->tuple.src.l3num != PF_INET) + return; + + /* + * We assume that no NF locks are held before this callback. + * ip_vs_conn_out_get and ip_vs_conn_in_get should match their + * expectations even if they use wildcard values, now we provide the + * actual values from the newly created original conntrack direction. + * The conntrack is confirmed when packet reaches IPVS hooks. + */ + + /* RS->CLIENT */ + orig = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; + ip_vs_conn_fill_param(exp->tuple.src.l3num, orig->dst.protonum, + &orig->src.u3, orig->src.u.tcp.port, + &orig->dst.u3, orig->dst.u.tcp.port, &p); + cp = ip_vs_conn_out_get(&p); + if (cp) { + /* Change reply CLIENT->RS to CLIENT->VS */ + new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; + IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " + FMT_TUPLE ", found inout cp=" FMT_CONN "\n", + __func__, ct, ct->status, + ARG_TUPLE(orig), ARG_TUPLE(&new_reply), + ARG_CONN(cp)); + new_reply.dst.u3 = cp->vaddr; + new_reply.dst.u.tcp.port = cp->vport; + IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", " FMT_TUPLE + ", inout cp=" FMT_CONN "\n", + __func__, ct, + ARG_TUPLE(orig), ARG_TUPLE(&new_reply), + ARG_CONN(cp)); + goto alter; + } + + /* CLIENT->VS */ + cp = ip_vs_conn_in_get(&p); + if (cp) { + /* Change reply VS->CLIENT to RS->CLIENT */ + new_reply = ct->tuplehash[IP_CT_DIR_REPLY].tuple; + IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuples=" FMT_TUPLE ", " + FMT_TUPLE ", found outin cp=" FMT_CONN "\n", + __func__, ct, ct->status, + ARG_TUPLE(orig), ARG_TUPLE(&new_reply), + ARG_CONN(cp)); + new_reply.src.u3 = cp->daddr; + new_reply.src.u.tcp.port = cp->dport; + IP_VS_DBG(7, "%s: ct=%p, new tuples=" FMT_TUPLE ", " + FMT_TUPLE ", outin cp=" FMT_CONN "\n", + __func__, ct, + ARG_TUPLE(orig), ARG_TUPLE(&new_reply), + ARG_CONN(cp)); + goto alter; + } + + IP_VS_DBG(7, "%s: ct=%p, status=0x%lX, tuple=" FMT_TUPLE + " - unknown expect\n", + __func__, ct, ct->status, ARG_TUPLE(orig)); + return; + +alter: + /* Never alter conntrack for non-NAT conns */ + if (IP_VS_FWD_METHOD(cp) == IP_VS_CONN_F_MASQ) + nf_conntrack_alter_reply(ct, &new_reply); + ip_vs_conn_put(cp); + return; +} + +/* + * Create NF conntrack expectation with wildcard (optional) source port. + * Then the default callback function will alter the reply and will confirm + * the conntrack entry when the first packet comes. + * Use port 0 to expect connection from any port. + */ +void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct, + struct ip_vs_conn *cp, u_int8_t proto, + const __be16 port, int from_rs) +{ + struct nf_conntrack_expect *exp; + + if (ct == NULL || nf_ct_is_untracked(ct)) + return; + + exp = nf_ct_expect_alloc(ct); + if (!exp) + return; + + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, nf_ct_l3num(ct), + from_rs ? &cp->daddr : &cp->caddr, + from_rs ? &cp->caddr : &cp->vaddr, + proto, port ? &port : NULL, + from_rs ? &cp->cport : &cp->vport); + + exp->expectfn = ip_vs_nfct_expect_callback; + + IP_VS_DBG(7, "%s: ct=%p, expect tuple=" FMT_TUPLE "\n", + __func__, ct, ARG_TUPLE(&exp->tuple)); + nf_ct_expect_related(exp); + nf_ct_expect_put(exp); +} +EXPORT_SYMBOL(ip_vs_nfct_expect_related); + +/* + * Our connection was terminated, try to drop the conntrack immediately + */ +void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp) +{ + struct nf_conntrack_tuple_hash *h; + struct nf_conn *ct; + struct nf_conntrack_tuple tuple; + + if (!cp->cport) + return; + + tuple = (struct nf_conntrack_tuple) { + .dst = { .protonum = cp->protocol, .dir = IP_CT_DIR_ORIGINAL } }; + tuple.src.u3 = cp->caddr; + tuple.src.u.all = cp->cport; + tuple.src.l3num = cp->af; + tuple.dst.u3 = cp->vaddr; + tuple.dst.u.all = cp->vport; + + IP_VS_DBG(7, "%s: dropping conntrack with tuple=" FMT_TUPLE + " for conn " FMT_CONN "\n", + __func__, ARG_TUPLE(&tuple), ARG_CONN(cp)); + + h = nf_conntrack_find_get(&init_net, NF_CT_DEFAULT_ZONE, &tuple); + if (h) { + ct = nf_ct_tuplehash_to_ctrack(h); + /* Show what happens instead of calling nf_ct_kill() */ + if (del_timer(&ct->timeout)) { + IP_VS_DBG(7, "%s: ct=%p, deleted conntrack timer for tuple=" + FMT_TUPLE "\n", + __func__, ct, ARG_TUPLE(&tuple)); + if (ct->timeout.function) + ct->timeout.function(ct->timeout.data); + } else { + IP_VS_DBG(7, "%s: ct=%p, no conntrack timer for tuple=" + FMT_TUPLE "\n", + __func__, ct, ARG_TUPLE(&tuple)); + } + nf_ct_put(ct); + } else { + IP_VS_DBG(7, "%s: no conntrack for tuple=" FMT_TUPLE "\n", + __func__, ARG_TUPLE(&tuple)); + } +} + diff --git a/net/netfilter/ipvs/ip_vs_pe.c b/net/netfilter/ipvs/ip_vs_pe.c new file mode 100644 index 0000000000000000000000000000000000000000..3414af70ee127c0f30f7b49cf0c15d91683bde5b --- /dev/null +++ b/net/netfilter/ipvs/ip_vs_pe.c @@ -0,0 +1,147 @@ +#define KMSG_COMPONENT "IPVS" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include +#include +#include +#include +#include + +#include + +/* IPVS pe list */ +static LIST_HEAD(ip_vs_pe); + +/* lock for service table */ +static DEFINE_SPINLOCK(ip_vs_pe_lock); + +/* Bind a service with a pe */ +void ip_vs_bind_pe(struct ip_vs_service *svc, struct ip_vs_pe *pe) +{ + svc->pe = pe; +} + +/* Unbind a service from its pe */ +void ip_vs_unbind_pe(struct ip_vs_service *svc) +{ + svc->pe = NULL; +} + +/* Get pe in the pe list by name */ +static struct ip_vs_pe * +ip_vs_pe_getbyname(const char *pe_name) +{ + struct ip_vs_pe *pe; + + IP_VS_DBG(2, "%s(): pe_name \"%s\"\n", __func__, + pe_name); + + spin_lock_bh(&ip_vs_pe_lock); + + list_for_each_entry(pe, &ip_vs_pe, n_list) { + /* Test and get the modules atomically */ + if (pe->module && + !try_module_get(pe->module)) { + /* This pe is just deleted */ + continue; + } + if (strcmp(pe_name, pe->name)==0) { + /* HIT */ + spin_unlock_bh(&ip_vs_pe_lock); + return pe; + } + if (pe->module) + module_put(pe->module); + } + + spin_unlock_bh(&ip_vs_pe_lock); + return NULL; +} + +/* Lookup pe and try to load it if it doesn't exist */ +struct ip_vs_pe *ip_vs_pe_get(const char *name) +{ + struct ip_vs_pe *pe; + + /* Search for the pe by name */ + pe = ip_vs_pe_getbyname(name); + + /* If pe not found, load the module and search again */ + if (!pe) { + request_module("ip_vs_pe_%s", name); + pe = ip_vs_pe_getbyname(name); + } + + return pe; +} + +void ip_vs_pe_put(struct ip_vs_pe *pe) +{ + if (pe && pe->module) + module_put(pe->module); +} + +/* Register a pe in the pe list */ +int register_ip_vs_pe(struct ip_vs_pe *pe) +{ + struct ip_vs_pe *tmp; + + /* increase the module use count */ + ip_vs_use_count_inc(); + + spin_lock_bh(&ip_vs_pe_lock); + + if (!list_empty(&pe->n_list)) { + spin_unlock_bh(&ip_vs_pe_lock); + ip_vs_use_count_dec(); + pr_err("%s(): [%s] pe already linked\n", + __func__, pe->name); + return -EINVAL; + } + + /* Make sure that the pe with this name doesn't exist + * in the pe list. + */ + list_for_each_entry(tmp, &ip_vs_pe, n_list) { + if (strcmp(tmp->name, pe->name) == 0) { + spin_unlock_bh(&ip_vs_pe_lock); + ip_vs_use_count_dec(); + pr_err("%s(): [%s] pe already existed " + "in the system\n", __func__, pe->name); + return -EINVAL; + } + } + /* Add it into the d-linked pe list */ + list_add(&pe->n_list, &ip_vs_pe); + spin_unlock_bh(&ip_vs_pe_lock); + + pr_info("[%s] pe registered.\n", pe->name); + + return 0; +} +EXPORT_SYMBOL_GPL(register_ip_vs_pe); + +/* Unregister a pe from the pe list */ +int unregister_ip_vs_pe(struct ip_vs_pe *pe) +{ + spin_lock_bh(&ip_vs_pe_lock); + if (list_empty(&pe->n_list)) { + spin_unlock_bh(&ip_vs_pe_lock); + pr_err("%s(): [%s] pe is not in the list. failed\n", + __func__, pe->name); + return -EINVAL; + } + + /* Remove it from the d-linked pe list */ + list_del(&pe->n_list); + spin_unlock_bh(&ip_vs_pe_lock); + + /* decrease the module use count */ + ip_vs_use_count_dec(); + + pr_info("[%s] pe unregistered.\n", pe->name); + + return 0; +} +EXPORT_SYMBOL_GPL(unregister_ip_vs_pe); diff --git a/net/netfilter/ipvs/ip_vs_pe_sip.c b/net/netfilter/ipvs/ip_vs_pe_sip.c new file mode 100644 index 0000000000000000000000000000000000000000..b8b4e9620f3e936251da71d452f1d1f7aed68d04 --- /dev/null +++ b/net/netfilter/ipvs/ip_vs_pe_sip.c @@ -0,0 +1,169 @@ +#define KMSG_COMPONENT "IPVS" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include +#include + +#include +#include +#include + +#ifdef CONFIG_IP_VS_DEBUG +static const char *ip_vs_dbg_callid(char *buf, size_t buf_len, + const char *callid, size_t callid_len, + int *idx) +{ + size_t len = min(min(callid_len, (size_t)64), buf_len - *idx - 1); + memcpy(buf + *idx, callid, len); + buf[*idx+len] = '\0'; + *idx += len + 1; + return buf + *idx - len; +} + +#define IP_VS_DEBUG_CALLID(callid, len) \ + ip_vs_dbg_callid(ip_vs_dbg_buf, sizeof(ip_vs_dbg_buf), \ + callid, len, &ip_vs_dbg_idx) +#endif + +static int get_callid(const char *dptr, unsigned int dataoff, + unsigned int datalen, + unsigned int *matchoff, unsigned int *matchlen) +{ + /* Find callid */ + while (1) { + int ret = ct_sip_get_header(NULL, dptr, dataoff, datalen, + SIP_HDR_CALL_ID, matchoff, + matchlen); + if (ret > 0) + break; + if (!ret) + return 0; + dataoff += *matchoff; + } + + /* Empty callid is useless */ + if (!*matchlen) + return -EINVAL; + + /* Too large is useless */ + if (*matchlen > IP_VS_PEDATA_MAXLEN) + return -EINVAL; + + /* SIP headers are always followed by a line terminator */ + if (*matchoff + *matchlen == datalen) + return -EINVAL; + + /* RFC 2543 allows lines to be terminated with CR, LF or CRLF, + * RFC 3261 allows only CRLF, we support both. */ + if (*(dptr + *matchoff + *matchlen) != '\r' && + *(dptr + *matchoff + *matchlen) != '\n') + return -EINVAL; + + IP_VS_DBG_BUF(9, "SIP callid %s (%d bytes)\n", + IP_VS_DEBUG_CALLID(dptr + *matchoff, *matchlen), + *matchlen); + return 0; +} + +static int +ip_vs_sip_fill_param(struct ip_vs_conn_param *p, struct sk_buff *skb) +{ + struct ip_vs_iphdr iph; + unsigned int dataoff, datalen, matchoff, matchlen; + const char *dptr; + + ip_vs_fill_iphdr(p->af, skb_network_header(skb), &iph); + + /* Only useful with UDP */ + if (iph.protocol != IPPROTO_UDP) + return -EINVAL; + + /* No Data ? */ + dataoff = iph.len + sizeof(struct udphdr); + if (dataoff >= skb->len) + return -EINVAL; + + dptr = skb->data + dataoff; + datalen = skb->len - dataoff; + + if (get_callid(dptr, dataoff, datalen, &matchoff, &matchlen)) + return -EINVAL; + + p->pe_data = kmalloc(matchlen, GFP_ATOMIC); + if (!p->pe_data) + return -ENOMEM; + + /* N.B: pe_data is only set on success, + * this allows fallback to the default persistence logic on failure + */ + memcpy(p->pe_data, dptr + matchoff, matchlen); + p->pe_data_len = matchlen; + + return 0; +} + +static bool ip_vs_sip_ct_match(const struct ip_vs_conn_param *p, + struct ip_vs_conn *ct) + +{ + bool ret = 0; + + if (ct->af == p->af && + ip_vs_addr_equal(p->af, p->caddr, &ct->caddr) && + /* protocol should only be IPPROTO_IP if + * d_addr is a fwmark */ + ip_vs_addr_equal(p->protocol == IPPROTO_IP ? AF_UNSPEC : p->af, + p->vaddr, &ct->vaddr) && + ct->vport == p->vport && + ct->flags & IP_VS_CONN_F_TEMPLATE && + ct->protocol == p->protocol && + ct->pe_data && ct->pe_data_len == p->pe_data_len && + !memcmp(ct->pe_data, p->pe_data, p->pe_data_len)) + ret = 1; + + IP_VS_DBG_BUF(9, "SIP template match %s %s->%s:%d %s\n", + ip_vs_proto_name(p->protocol), + IP_VS_DEBUG_CALLID(p->pe_data, p->pe_data_len), + IP_VS_DBG_ADDR(p->af, p->vaddr), ntohs(p->vport), + ret ? "hit" : "not hit"); + + return ret; +} + +static u32 ip_vs_sip_hashkey_raw(const struct ip_vs_conn_param *p, + u32 initval, bool inverse) +{ + return jhash(p->pe_data, p->pe_data_len, initval); +} + +static int ip_vs_sip_show_pe_data(const struct ip_vs_conn *cp, char *buf) +{ + memcpy(buf, cp->pe_data, cp->pe_data_len); + return cp->pe_data_len; +} + +static struct ip_vs_pe ip_vs_sip_pe = +{ + .name = "sip", + .refcnt = ATOMIC_INIT(0), + .module = THIS_MODULE, + .n_list = LIST_HEAD_INIT(ip_vs_sip_pe.n_list), + .fill_param = ip_vs_sip_fill_param, + .ct_match = ip_vs_sip_ct_match, + .hashkey_raw = ip_vs_sip_hashkey_raw, + .show_pe_data = ip_vs_sip_show_pe_data, +}; + +static int __init ip_vs_sip_init(void) +{ + return register_ip_vs_pe(&ip_vs_sip_pe); +} + +static void __exit ip_vs_sip_cleanup(void) +{ + unregister_ip_vs_pe(&ip_vs_sip_pe); +} + +module_init(ip_vs_sip_init); +module_exit(ip_vs_sip_cleanup); +MODULE_LICENSE("GPL"); diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c index 027f654799feb969fe5a64de8b262e37287e8f48..c539983908771ead7df2e14b7d4eb9c259369064 100644 --- a/net/netfilter/ipvs/ip_vs_proto.c +++ b/net/netfilter/ipvs/ip_vs_proto.c @@ -172,8 +172,8 @@ ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp, else if (ih->frag_off & htons(IP_OFFSET)) sprintf(buf, "%pI4->%pI4 frag", &ih->saddr, &ih->daddr); else { - __be16 _ports[2], *pptr -; + __be16 _ports[2], *pptr; + pptr = skb_header_pointer(skb, offset + ih->ihl*4, sizeof(_ports), _ports); if (pptr == NULL) @@ -223,13 +223,13 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp, void -ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, +ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp, const struct sk_buff *skb, int offset, const char *msg) { #ifdef CONFIG_IP_VS_IPV6 - if (skb->protocol == htons(ETH_P_IPV6)) + if (af == AF_INET6) ip_vs_tcpudp_debug_packet_v6(pp, skb, offset, msg); else #endif diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c index 1892dfc12fdd96ffa1169d5922243cfd0010e7e5..3a0461117d3fad6216747b60b5ec24856ca9d7fc 100644 --- a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c +++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c @@ -40,6 +40,19 @@ struct isakmp_hdr { #define PORT_ISAKMP 500 +static void +ah_esp_conn_fill_param_proto(int af, const struct ip_vs_iphdr *iph, + int inverse, struct ip_vs_conn_param *p) +{ + if (likely(!inverse)) + ip_vs_conn_fill_param(af, IPPROTO_UDP, + &iph->saddr, htons(PORT_ISAKMP), + &iph->daddr, htons(PORT_ISAKMP), p); + else + ip_vs_conn_fill_param(af, IPPROTO_UDP, + &iph->daddr, htons(PORT_ISAKMP), + &iph->saddr, htons(PORT_ISAKMP), p); +} static struct ip_vs_conn * ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, @@ -47,21 +60,10 @@ ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp, int inverse) { struct ip_vs_conn *cp; + struct ip_vs_conn_param p; - if (likely(!inverse)) { - cp = ip_vs_conn_in_get(af, IPPROTO_UDP, - &iph->saddr, - htons(PORT_ISAKMP), - &iph->daddr, - htons(PORT_ISAKMP)); - } else { - cp = ip_vs_conn_in_get(af, IPPROTO_UDP, - &iph->daddr, - htons(PORT_ISAKMP), - &iph->saddr, - htons(PORT_ISAKMP)); - } - + ah_esp_conn_fill_param_proto(af, iph, inverse, &p); + cp = ip_vs_conn_in_get(&p); if (!cp) { /* * We are not sure if the packet is from our @@ -87,21 +89,10 @@ ah_esp_conn_out_get(int af, const struct sk_buff *skb, int inverse) { struct ip_vs_conn *cp; + struct ip_vs_conn_param p; - if (likely(!inverse)) { - cp = ip_vs_conn_out_get(af, IPPROTO_UDP, - &iph->saddr, - htons(PORT_ISAKMP), - &iph->daddr, - htons(PORT_ISAKMP)); - } else { - cp = ip_vs_conn_out_get(af, IPPROTO_UDP, - &iph->daddr, - htons(PORT_ISAKMP), - &iph->saddr, - htons(PORT_ISAKMP)); - } - + ah_esp_conn_fill_param_proto(af, iph, inverse, &p); + cp = ip_vs_conn_out_get(&p); if (!cp) { IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet " "%s%s %s->%s\n", @@ -126,54 +117,6 @@ ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, return 0; } - -static void -ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb, - int offset, const char *msg) -{ - char buf[256]; - struct iphdr _iph, *ih; - - ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); - if (ih == NULL) - sprintf(buf, "TRUNCATED"); - else - sprintf(buf, "%pI4->%pI4", &ih->saddr, &ih->daddr); - - pr_debug("%s: %s %s\n", msg, pp->name, buf); -} - -#ifdef CONFIG_IP_VS_IPV6 -static void -ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb, - int offset, const char *msg) -{ - char buf[256]; - struct ipv6hdr _iph, *ih; - - ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); - if (ih == NULL) - sprintf(buf, "TRUNCATED"); - else - sprintf(buf, "%pI6->%pI6", &ih->saddr, &ih->daddr); - - pr_debug("%s: %s %s\n", msg, pp->name, buf); -} -#endif - -static void -ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb, - int offset, const char *msg) -{ -#ifdef CONFIG_IP_VS_IPV6 - if (skb->protocol == htons(ETH_P_IPV6)) - ah_esp_debug_packet_v6(pp, skb, offset, msg); - else -#endif - ah_esp_debug_packet_v4(pp, skb, offset, msg); -} - - static void ah_esp_init(struct ip_vs_protocol *pp) { /* nothing to do now */ @@ -204,7 +147,7 @@ struct ip_vs_protocol ip_vs_protocol_ah = { .register_app = NULL, .unregister_app = NULL, .app_conn_bind = NULL, - .debug_packet = ah_esp_debug_packet, + .debug_packet = ip_vs_tcpudp_debug_packet, .timeout_change = NULL, /* ISAKMP */ .set_state_timeout = NULL, }; @@ -228,7 +171,7 @@ struct ip_vs_protocol ip_vs_protocol_esp = { .register_app = NULL, .unregister_app = NULL, .app_conn_bind = NULL, - .debug_packet = ah_esp_debug_packet, + .debug_packet = ip_vs_tcpudp_debug_packet, .timeout_change = NULL, /* ISAKMP */ }; #endif diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index 4c0855cb006ee93c721d53ff0b95cef5ec1853bf..1ea96bcd342b8fc81eb437a6826fc6652c2be4c2 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -31,6 +31,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, if ((sch->type == SCTP_CID_INIT) && (svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr, sh->dest))) { + int ignored; + if (ip_vs_todrop()) { /* * It seems that we are very loaded. @@ -44,8 +46,8 @@ sctp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, * Let the virtual server select a real server for the * incoming connection, and create a connection entry. */ - *cpp = ip_vs_schedule(svc, skb); - if (!*cpp) { + *cpp = ip_vs_schedule(svc, skb, pp, &ignored); + if (!*cpp && !ignored) { *verdict = ip_vs_leave(svc, skb, pp); return 0; } @@ -61,6 +63,7 @@ sctp_snat_handler(struct sk_buff *skb, { sctp_sctphdr_t *sctph; unsigned int sctphoff; + struct sk_buff *iter; __be32 crc32; #ifdef CONFIG_IP_VS_IPV6 @@ -89,8 +92,8 @@ sctp_snat_handler(struct sk_buff *skb, /* Calculate the checksum */ crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff); - for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) - crc32 = sctp_update_cksum((u8 *) skb->data, skb_headlen(skb), + skb_walk_frags(skb, iter) + crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter), crc32); crc32 = sctp_end_cksum(crc32); sctph->checksum = crc32; @@ -102,9 +105,9 @@ static int sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, struct ip_vs_conn *cp) { - sctp_sctphdr_t *sctph; unsigned int sctphoff; + struct sk_buff *iter; __be32 crc32; #ifdef CONFIG_IP_VS_IPV6 @@ -133,8 +136,8 @@ sctp_dnat_handler(struct sk_buff *skb, /* Calculate the checksum */ crc32 = sctp_start_cksum((u8 *) sctph, skb_headlen(skb) - sctphoff); - for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next) - crc32 = sctp_update_cksum((u8 *) skb->data, skb_headlen(skb), + skb_walk_frags(skb, iter) + crc32 = sctp_update_cksum((u8 *) iter->data, skb_headlen(iter), crc32); crc32 = sctp_end_cksum(crc32); sctph->checksum = crc32; @@ -145,9 +148,9 @@ sctp_dnat_handler(struct sk_buff *skb, static int sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) { - struct sk_buff *list = skb_shinfo(skb)->frag_list; unsigned int sctphoff; struct sctphdr *sh, _sctph; + struct sk_buff *iter; __le32 cmp; __le32 val; __u32 tmp; @@ -166,15 +169,15 @@ sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) cmp = sh->checksum; tmp = sctp_start_cksum((__u8 *) sh, skb_headlen(skb)); - for (; list; list = list->next) - tmp = sctp_update_cksum((__u8 *) list->data, - skb_headlen(list), tmp); + skb_walk_frags(skb, iter) + tmp = sctp_update_cksum((__u8 *) iter->data, + skb_headlen(iter), tmp); val = sctp_end_cksum(tmp); if (val != cmp) { /* CRC failure, dump it. */ - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c index 282d24de8592e659466657533b10ad6eadf4bd5c..f6c5200e214663fe915b2136532c54d03861e5eb 100644 --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -43,9 +43,12 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, return 0; } + /* No !th->ack check to allow scheduling on SYN+ACK for Active FTP */ if (th->syn && (svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr, th->dest))) { + int ignored; + if (ip_vs_todrop()) { /* * It seems that we are very loaded. @@ -60,8 +63,8 @@ tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, * Let the virtual server select a real server for the * incoming connection, and create a connection entry. */ - *cpp = ip_vs_schedule(svc, skb); - if (!*cpp) { + *cpp = ip_vs_schedule(svc, skb, pp, &ignored); + if (!*cpp && !ignored) { *verdict = ip_vs_leave(svc, skb, pp); return 0; } @@ -101,15 +104,15 @@ tcp_partial_csum_update(int af, struct tcphdr *tcph, #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) tcph->check = - csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6, + ~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6, ip_vs_check_diff2(oldlen, newlen, - ~csum_unfold(tcph->check)))); + csum_unfold(tcph->check)))); else #endif tcph->check = - csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip, + ~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip, ip_vs_check_diff2(oldlen, newlen, - ~csum_unfold(tcph->check)))); + csum_unfold(tcph->check)))); } @@ -120,6 +123,7 @@ tcp_snat_handler(struct sk_buff *skb, struct tcphdr *tcph; unsigned int tcphoff; int oldlen; + int payload_csum = 0; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) @@ -134,13 +138,20 @@ tcp_snat_handler(struct sk_buff *skb, return 0; if (unlikely(cp->app != NULL)) { + int ret; + /* Some checks before mangling */ if (pp->csum_check && !pp->csum_check(cp->af, skb, pp)) return 0; /* Call application helper if needed */ - if (!ip_vs_app_pkt_out(cp, skb)) + if (!(ret = ip_vs_app_pkt_out(cp, skb))) return 0; + /* ret=2: csum update is needed after payload mangling */ + if (ret == 1) + oldlen = skb->len - tcphoff; + else + payload_csum = 1; } tcph = (void *)skb_network_header(skb) + tcphoff; @@ -151,12 +162,13 @@ tcp_snat_handler(struct sk_buff *skb, tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr, htons(oldlen), htons(skb->len - tcphoff)); - } else if (!cp->app) { + } else if (!payload_csum) { /* Only port and addr are changed, do fast csum update */ tcp_fast_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr, cp->dport, cp->vport); if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = (cp->app && pp->csum_check) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; } else { /* full checksum calculation */ tcph->check = 0; @@ -174,6 +186,7 @@ tcp_snat_handler(struct sk_buff *skb, skb->len - tcphoff, cp->protocol, skb->csum); + skb->ip_summed = CHECKSUM_UNNECESSARY; IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", pp->name, tcph->check, @@ -190,6 +203,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct tcphdr *tcph; unsigned int tcphoff; int oldlen; + int payload_csum = 0; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) @@ -204,6 +218,8 @@ tcp_dnat_handler(struct sk_buff *skb, return 0; if (unlikely(cp->app != NULL)) { + int ret; + /* Some checks before mangling */ if (pp->csum_check && !pp->csum_check(cp->af, skb, pp)) return 0; @@ -212,8 +228,13 @@ tcp_dnat_handler(struct sk_buff *skb, * Attempt ip_vs_app call. * It will fix ip_vs_conn and iph ack_seq stuff */ - if (!ip_vs_app_pkt_in(cp, skb)) + if (!(ret = ip_vs_app_pkt_in(cp, skb))) return 0; + /* ret=2: csum update is needed after payload mangling */ + if (ret == 1) + oldlen = skb->len - tcphoff; + else + payload_csum = 1; } tcph = (void *)skb_network_header(skb) + tcphoff; @@ -223,15 +244,16 @@ tcp_dnat_handler(struct sk_buff *skb, * Adjust TCP checksums */ if (skb->ip_summed == CHECKSUM_PARTIAL) { - tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr, + tcp_partial_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr, htons(oldlen), htons(skb->len - tcphoff)); - } else if (!cp->app) { + } else if (!payload_csum) { /* Only port and addr are changed, do fast csum update */ tcp_fast_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr, cp->vport, cp->dport); if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = (cp->app && pp->csum_check) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; } else { /* full checksum calculation */ tcph->check = 0; @@ -278,7 +300,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) skb->len - tcphoff, ipv6_hdr(skb)->nexthdr, skb->csum)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } @@ -289,7 +311,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) skb->len - tcphoff, ip_hdr(skb)->protocol, skb->csum)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c index 8553231b5d412ca557f8699ee998e05351152213..9d106a06bb0a46376252b32f2d30882d921b8b16 100644 --- a/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -46,6 +46,8 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr, uh->dest); if (svc) { + int ignored; + if (ip_vs_todrop()) { /* * It seems that we are very loaded. @@ -60,8 +62,8 @@ udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, * Let the virtual server select a real server for the * incoming connection, and create a connection entry. */ - *cpp = ip_vs_schedule(svc, skb); - if (!*cpp) { + *cpp = ip_vs_schedule(svc, skb, pp, &ignored); + if (!*cpp && !ignored) { *verdict = ip_vs_leave(svc, skb, pp); return 0; } @@ -102,15 +104,15 @@ udp_partial_csum_update(int af, struct udphdr *uhdr, #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) uhdr->check = - csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6, + ~csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6, ip_vs_check_diff2(oldlen, newlen, - ~csum_unfold(uhdr->check)))); + csum_unfold(uhdr->check)))); else #endif uhdr->check = - csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip, + ~csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip, ip_vs_check_diff2(oldlen, newlen, - ~csum_unfold(uhdr->check)))); + csum_unfold(uhdr->check)))); } @@ -121,6 +123,7 @@ udp_snat_handler(struct sk_buff *skb, struct udphdr *udph; unsigned int udphoff; int oldlen; + int payload_csum = 0; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) @@ -135,6 +138,8 @@ udp_snat_handler(struct sk_buff *skb, return 0; if (unlikely(cp->app != NULL)) { + int ret; + /* Some checks before mangling */ if (pp->csum_check && !pp->csum_check(cp->af, skb, pp)) return 0; @@ -142,8 +147,13 @@ udp_snat_handler(struct sk_buff *skb, /* * Call application helper if needed */ - if (!ip_vs_app_pkt_out(cp, skb)) + if (!(ret = ip_vs_app_pkt_out(cp, skb))) return 0; + /* ret=2: csum update is needed after payload mangling */ + if (ret == 1) + oldlen = skb->len - udphoff; + else + payload_csum = 1; } udph = (void *)skb_network_header(skb) + udphoff; @@ -156,12 +166,13 @@ udp_snat_handler(struct sk_buff *skb, udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr, htons(oldlen), htons(skb->len - udphoff)); - } else if (!cp->app && (udph->check != 0)) { + } else if (!payload_csum && (udph->check != 0)) { /* Only port and addr are changed, do fast csum update */ udp_fast_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr, cp->dport, cp->vport); if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = (cp->app && pp->csum_check) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; } else { /* full checksum calculation */ udph->check = 0; @@ -181,6 +192,7 @@ udp_snat_handler(struct sk_buff *skb, skb->csum); if (udph->check == 0) udph->check = CSUM_MANGLED_0; + skb->ip_summed = CHECKSUM_UNNECESSARY; IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", pp->name, udph->check, (char*)&(udph->check) - (char*)udph); @@ -196,6 +208,7 @@ udp_dnat_handler(struct sk_buff *skb, struct udphdr *udph; unsigned int udphoff; int oldlen; + int payload_csum = 0; #ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) @@ -210,6 +223,8 @@ udp_dnat_handler(struct sk_buff *skb, return 0; if (unlikely(cp->app != NULL)) { + int ret; + /* Some checks before mangling */ if (pp->csum_check && !pp->csum_check(cp->af, skb, pp)) return 0; @@ -218,8 +233,13 @@ udp_dnat_handler(struct sk_buff *skb, * Attempt ip_vs_app call. * It will fix ip_vs_conn */ - if (!ip_vs_app_pkt_in(cp, skb)) + if (!(ret = ip_vs_app_pkt_in(cp, skb))) return 0; + /* ret=2: csum update is needed after payload mangling */ + if (ret == 1) + oldlen = skb->len - udphoff; + else + payload_csum = 1; } udph = (void *)skb_network_header(skb) + udphoff; @@ -229,15 +249,16 @@ udp_dnat_handler(struct sk_buff *skb, * Adjust UDP checksums */ if (skb->ip_summed == CHECKSUM_PARTIAL) { - udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr, + udp_partial_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr, htons(oldlen), htons(skb->len - udphoff)); - } else if (!cp->app && (udph->check != 0)) { + } else if (!payload_csum && (udph->check != 0)) { /* Only port and addr are changed, do fast csum update */ udp_fast_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr, cp->vport, cp->dport); if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->ip_summed = CHECKSUM_NONE; + skb->ip_summed = (cp->app && pp->csum_check) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE; } else { /* full checksum calculation */ udph->check = 0; @@ -293,7 +314,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) skb->len - udphoff, ipv6_hdr(skb)->nexthdr, skb->csum)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } @@ -304,7 +325,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) skb->len - udphoff, ip_hdr(skb)->protocol, skb->csum)) { - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); return 0; } diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c index bbc1ac795952349b0dd9813bced3e329b6aaf6c2..076ebe00435deef930f428fbb02414c550c14b98 100644 --- a/net/netfilter/ipvs/ip_vs_sched.c +++ b/net/netfilter/ipvs/ip_vs_sched.c @@ -35,7 +35,7 @@ static LIST_HEAD(ip_vs_schedulers); /* lock for service table */ -static DEFINE_RWLOCK(__ip_vs_sched_lock); +static DEFINE_SPINLOCK(ip_vs_sched_lock); /* @@ -46,15 +46,6 @@ int ip_vs_bind_scheduler(struct ip_vs_service *svc, { int ret; - if (svc == NULL) { - pr_err("%s(): svc arg NULL\n", __func__); - return -EINVAL; - } - if (scheduler == NULL) { - pr_err("%s(): scheduler arg NULL\n", __func__); - return -EINVAL; - } - svc->scheduler = scheduler; if (scheduler->init_service) { @@ -74,18 +65,10 @@ int ip_vs_bind_scheduler(struct ip_vs_service *svc, */ int ip_vs_unbind_scheduler(struct ip_vs_service *svc) { - struct ip_vs_scheduler *sched; + struct ip_vs_scheduler *sched = svc->scheduler; - if (svc == NULL) { - pr_err("%s(): svc arg NULL\n", __func__); - return -EINVAL; - } - - sched = svc->scheduler; - if (sched == NULL) { - pr_err("%s(): svc isn't bound\n", __func__); - return -EINVAL; - } + if (!sched) + return 0; if (sched->done_service) { if (sched->done_service(svc) != 0) { @@ -108,7 +91,7 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name) IP_VS_DBG(2, "%s(): sched_name \"%s\"\n", __func__, sched_name); - read_lock_bh(&__ip_vs_sched_lock); + spin_lock_bh(&ip_vs_sched_lock); list_for_each_entry(sched, &ip_vs_schedulers, n_list) { /* @@ -122,14 +105,14 @@ static struct ip_vs_scheduler *ip_vs_sched_getbyname(const char *sched_name) } if (strcmp(sched_name, sched->name)==0) { /* HIT */ - read_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); return sched; } if (sched->module) module_put(sched->module); } - read_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); return NULL; } @@ -159,7 +142,7 @@ struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name) void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler) { - if (scheduler->module) + if (scheduler && scheduler->module) module_put(scheduler->module); } @@ -184,10 +167,10 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) /* increase the module use count */ ip_vs_use_count_inc(); - write_lock_bh(&__ip_vs_sched_lock); + spin_lock_bh(&ip_vs_sched_lock); if (!list_empty(&scheduler->n_list)) { - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); ip_vs_use_count_dec(); pr_err("%s(): [%s] scheduler already linked\n", __func__, scheduler->name); @@ -200,7 +183,7 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) */ list_for_each_entry(sched, &ip_vs_schedulers, n_list) { if (strcmp(scheduler->name, sched->name) == 0) { - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); ip_vs_use_count_dec(); pr_err("%s(): [%s] scheduler already existed " "in the system\n", __func__, scheduler->name); @@ -211,7 +194,7 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) * Add it into the d-linked scheduler list */ list_add(&scheduler->n_list, &ip_vs_schedulers); - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); pr_info("[%s] scheduler registered.\n", scheduler->name); @@ -229,9 +212,9 @@ int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) return -EINVAL; } - write_lock_bh(&__ip_vs_sched_lock); + spin_lock_bh(&ip_vs_sched_lock); if (list_empty(&scheduler->n_list)) { - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); pr_err("%s(): [%s] scheduler is not in the list. failed\n", __func__, scheduler->name); return -EINVAL; @@ -241,7 +224,7 @@ int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler) * Remove it from the d-linked scheduler list */ list_del(&scheduler->n_list); - write_unlock_bh(&__ip_vs_sched_lock); + spin_unlock_bh(&ip_vs_sched_lock); /* decrease the module use count */ ip_vs_use_count_dec(); diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 7ba06939829f3774ca34d813a41e58e8725cc6a8..ab85aedea17eea6100eb1aefe48b028d371f29d2 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -288,6 +288,16 @@ void ip_vs_sync_conn(struct ip_vs_conn *cp) ip_vs_sync_conn(cp->control); } +static inline int +ip_vs_conn_fill_param_sync(int af, int protocol, + const union nf_inet_addr *caddr, __be16 cport, + const union nf_inet_addr *vaddr, __be16 vport, + struct ip_vs_conn_param *p) +{ + /* XXX: Need to take into account persistence engine */ + ip_vs_conn_fill_param(af, protocol, caddr, cport, vaddr, vport, p); + return 0; +} /* * Process received multicast message and create the corresponding @@ -301,6 +311,7 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) struct ip_vs_conn *cp; struct ip_vs_protocol *pp; struct ip_vs_dest *dest; + struct ip_vs_conn_param param; char *p; int i; @@ -370,18 +381,20 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) } } - if (!(flags & IP_VS_CONN_F_TEMPLATE)) - cp = ip_vs_conn_in_get(AF_INET, s->protocol, - (union nf_inet_addr *)&s->caddr, - s->cport, - (union nf_inet_addr *)&s->vaddr, - s->vport); - else - cp = ip_vs_ct_in_get(AF_INET, s->protocol, - (union nf_inet_addr *)&s->caddr, - s->cport, - (union nf_inet_addr *)&s->vaddr, - s->vport); + { + if (ip_vs_conn_fill_param_sync(AF_INET, s->protocol, + (union nf_inet_addr *)&s->caddr, + s->cport, + (union nf_inet_addr *)&s->vaddr, + s->vport, ¶m)) { + pr_err("ip_vs_conn_fill_param_sync failed"); + return; + } + if (!(flags & IP_VS_CONN_F_TEMPLATE)) + cp = ip_vs_conn_in_get(¶m); + else + cp = ip_vs_ct_in_get(¶m); + } if (!cp) { /* * Find the appropriate destination for the connection. @@ -406,14 +419,9 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen) else flags &= ~IP_VS_CONN_F_INACTIVE; } - cp = ip_vs_conn_new(AF_INET, s->protocol, - (union nf_inet_addr *)&s->caddr, - s->cport, - (union nf_inet_addr *)&s->vaddr, - s->vport, + cp = ip_vs_conn_new(¶m, (union nf_inet_addr *)&s->daddr, - s->dport, - flags, dest); + s->dport, flags, dest); if (dest) atomic_dec(&dest->refcnt); if (!cp) { diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 49df6bea6a2ddaec391ce077cf9f72a72efc4a7f..de04ea39cde8990025bdb5f63ff408fcc948fb0a 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -11,6 +11,16 @@ * * Changes: * + * Description of forwarding methods: + * - all transmitters are called from LOCAL_IN (remote clients) and + * LOCAL_OUT (local clients) but for ICMP can be called from FORWARD + * - not all connections have destination server, for example, + * connections in backup server when fwmark is used + * - bypass connections use daddr from packet + * LOCAL_OUT rules: + * - skb->dev is NULL, skb->protocol is not set (both are set in POST_ROUTING) + * - skb->pkt_type is not set yet + * - the only place where we can see skb->sk != NULL */ #define KMSG_COMPONENT "IPVS" @@ -26,9 +36,9 @@ #include /* for ip_route_output */ #include #include +#include #include #include -#include #include #include @@ -38,26 +48,27 @@ * Destination cache to speed up outgoing route lookup */ static inline void -__ip_vs_dst_set(struct ip_vs_dest *dest, u32 rtos, struct dst_entry *dst) +__ip_vs_dst_set(struct ip_vs_dest *dest, u32 rtos, struct dst_entry *dst, + u32 dst_cookie) { struct dst_entry *old_dst; old_dst = dest->dst_cache; dest->dst_cache = dst; dest->dst_rtos = rtos; + dest->dst_cookie = dst_cookie; dst_release(old_dst); } static inline struct dst_entry * -__ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie) +__ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos) { struct dst_entry *dst = dest->dst_cache; if (!dst) return NULL; - if ((dst->obsolete - || (dest->af == AF_INET && rtos != dest->dst_rtos)) && - dst->ops->check(dst, cookie) == NULL) { + if ((dst->obsolete || rtos != dest->dst_rtos) && + dst->ops->check(dst, dest->dst_cookie) == NULL) { dest->dst_cache = NULL; dst_release(dst); return NULL; @@ -66,16 +77,24 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie) return dst; } +/* + * Get route to destination or remote server + * rt_mode: flags, &1=Allow local dest, &2=Allow non-local dest, + * &4=Allow redirect from remote daddr to local + */ static struct rtable * -__ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos) +__ip_vs_get_out_rt(struct sk_buff *skb, struct ip_vs_dest *dest, + __be32 daddr, u32 rtos, int rt_mode) { + struct net *net = dev_net(skb_dst(skb)->dev); struct rtable *rt; /* Route to the other host */ - struct ip_vs_dest *dest = cp->dest; + struct rtable *ort; /* Original route */ + int local; if (dest) { spin_lock(&dest->dst_lock); if (!(rt = (struct rtable *) - __ip_vs_dst_check(dest, rtos, 0))) { + __ip_vs_dst_check(dest, rtos))) { struct flowi fl = { .oif = 0, .nl_u = { @@ -85,13 +104,13 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos) .tos = rtos, } }, }; - if (ip_route_output_key(&init_net, &rt, &fl)) { + if (ip_route_output_key(net, &rt, &fl)) { spin_unlock(&dest->dst_lock); IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", &dest->addr.ip); return NULL; } - __ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst)); + __ip_vs_dst_set(dest, rtos, dst_clone(&rt->dst), 0); IP_VS_DBG(10, "new dst %pI4, refcnt=%d, rtos=%X\n", &dest->addr.ip, atomic_read(&rt->dst.__refcnt), rtos); @@ -102,78 +121,199 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos) .oif = 0, .nl_u = { .ip4_u = { - .daddr = cp->daddr.ip, + .daddr = daddr, .saddr = 0, .tos = rtos, } }, }; - if (ip_route_output_key(&init_net, &rt, &fl)) { + if (ip_route_output_key(net, &rt, &fl)) { IP_VS_DBG_RL("ip_route_output error, dest: %pI4\n", - &cp->daddr.ip); + &daddr); return NULL; } } + local = rt->rt_flags & RTCF_LOCAL; + if (!((local ? 1 : 2) & rt_mode)) { + IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI4\n", + (rt->rt_flags & RTCF_LOCAL) ? + "local":"non-local", &rt->rt_dst); + ip_rt_put(rt); + return NULL; + } + if (local && !(rt_mode & 4) && !((ort = skb_rtable(skb)) && + ort->rt_flags & RTCF_LOCAL)) { + IP_VS_DBG_RL("Redirect from non-local address %pI4 to local " + "requires NAT method, dest: %pI4\n", + &ip_hdr(skb)->daddr, &rt->rt_dst); + ip_rt_put(rt); + return NULL; + } + if (unlikely(!local && ipv4_is_loopback(ip_hdr(skb)->saddr))) { + IP_VS_DBG_RL("Stopping traffic from loopback address %pI4 " + "to non-local address, dest: %pI4\n", + &ip_hdr(skb)->saddr, &rt->rt_dst); + ip_rt_put(rt); + return NULL; + } + return rt; } +/* Reroute packet to local IPv4 stack after DNAT */ +static int +__ip_vs_reroute_locally(struct sk_buff *skb) +{ + struct rtable *rt = skb_rtable(skb); + struct net_device *dev = rt->dst.dev; + struct net *net = dev_net(dev); + struct iphdr *iph = ip_hdr(skb); + + if (rt->fl.iif) { + unsigned long orefdst = skb->_skb_refdst; + + if (ip_route_input(skb, iph->daddr, iph->saddr, + iph->tos, skb->dev)) + return 0; + refdst_drop(orefdst); + } else { + struct flowi fl = { + .oif = 0, + .nl_u = { + .ip4_u = { + .daddr = iph->daddr, + .saddr = iph->saddr, + .tos = RT_TOS(iph->tos), + } + }, + .mark = skb->mark, + }; + struct rtable *rt; + + if (ip_route_output_key(net, &rt, &fl)) + return 0; + if (!(rt->rt_flags & RTCF_LOCAL)) { + ip_rt_put(rt); + return 0; + } + /* Drop old route. */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } + return 1; +} + #ifdef CONFIG_IP_VS_IPV6 + +static inline int __ip_vs_is_local_route6(struct rt6_info *rt) +{ + return rt->rt6i_dev && rt->rt6i_dev->flags & IFF_LOOPBACK; +} + +static struct dst_entry * +__ip_vs_route_output_v6(struct net *net, struct in6_addr *daddr, + struct in6_addr *ret_saddr, int do_xfrm) +{ + struct dst_entry *dst; + struct flowi fl = { + .oif = 0, + .nl_u = { + .ip6_u = { + .daddr = *daddr, + }, + }, + }; + + dst = ip6_route_output(net, NULL, &fl); + if (dst->error) + goto out_err; + if (!ret_saddr) + return dst; + if (ipv6_addr_any(&fl.fl6_src) && + ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev, + &fl.fl6_dst, 0, &fl.fl6_src) < 0) + goto out_err; + if (do_xfrm && xfrm_lookup(net, &dst, &fl, NULL, 0) < 0) + goto out_err; + ipv6_addr_copy(ret_saddr, &fl.fl6_src); + return dst; + +out_err: + dst_release(dst); + IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n", daddr); + return NULL; +} + +/* + * Get route to destination or remote server + * rt_mode: flags, &1=Allow local dest, &2=Allow non-local dest, + * &4=Allow redirect from remote daddr to local + */ static struct rt6_info * -__ip_vs_get_out_rt_v6(struct ip_vs_conn *cp) +__ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest, + struct in6_addr *daddr, struct in6_addr *ret_saddr, + int do_xfrm, int rt_mode) { + struct net *net = dev_net(skb_dst(skb)->dev); struct rt6_info *rt; /* Route to the other host */ - struct ip_vs_dest *dest = cp->dest; + struct rt6_info *ort; /* Original route */ + struct dst_entry *dst; + int local; if (dest) { spin_lock(&dest->dst_lock); - rt = (struct rt6_info *)__ip_vs_dst_check(dest, 0, 0); + rt = (struct rt6_info *)__ip_vs_dst_check(dest, 0); if (!rt) { - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip6_u = { - .daddr = dest->addr.in6, - .saddr = { - .s6_addr32 = - { 0, 0, 0, 0 }, - }, - }, - }, - }; + u32 cookie; - rt = (struct rt6_info *)ip6_route_output(&init_net, - NULL, &fl); - if (!rt) { + dst = __ip_vs_route_output_v6(net, &dest->addr.in6, + &dest->dst_saddr, + do_xfrm); + if (!dst) { spin_unlock(&dest->dst_lock); - IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n", - &dest->addr.in6); return NULL; } - __ip_vs_dst_set(dest, 0, dst_clone(&rt->dst)); - IP_VS_DBG(10, "new dst %pI6, refcnt=%d\n", - &dest->addr.in6, + rt = (struct rt6_info *) dst; + cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; + __ip_vs_dst_set(dest, 0, dst_clone(&rt->dst), cookie); + IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n", + &dest->addr.in6, &dest->dst_saddr, atomic_read(&rt->dst.__refcnt)); } + if (ret_saddr) + ipv6_addr_copy(ret_saddr, &dest->dst_saddr); spin_unlock(&dest->dst_lock); } else { - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip6_u = { - .daddr = cp->daddr.in6, - .saddr = { - .s6_addr32 = { 0, 0, 0, 0 }, - }, - }, - }, - }; - - rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); - if (!rt) { - IP_VS_DBG_RL("ip6_route_output error, dest: %pI6\n", - &cp->daddr.in6); + dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm); + if (!dst) return NULL; - } + rt = (struct rt6_info *) dst; + } + + local = __ip_vs_is_local_route6(rt); + if (!((local ? 1 : 2) & rt_mode)) { + IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6\n", + local ? "local":"non-local", daddr); + dst_release(&rt->dst); + return NULL; + } + if (local && !(rt_mode & 4) && + !((ort = (struct rt6_info *) skb_dst(skb)) && + __ip_vs_is_local_route6(ort))) { + IP_VS_DBG_RL("Redirect from non-local address %pI6 to local " + "requires NAT method, dest: %pI6\n", + &ipv6_hdr(skb)->daddr, daddr); + dst_release(&rt->dst); + return NULL; + } + if (unlikely(!local && (!skb->dev || skb->dev->flags & IFF_LOOPBACK) && + ipv6_addr_type(&ipv6_hdr(skb)->saddr) & + IPV6_ADDR_LOOPBACK)) { + IP_VS_DBG_RL("Stopping traffic from loopback address %pI6 " + "to non-local address, dest: %pI6\n", + &ipv6_hdr(skb)->saddr, daddr); + dst_release(&rt->dst); + return NULL; } return rt; @@ -194,12 +334,44 @@ ip_vs_dst_reset(struct ip_vs_dest *dest) dst_release(old_dst); } -#define IP_VS_XMIT(pf, skb, rt) \ +#define IP_VS_XMIT_TUNNEL(skb, cp) \ +({ \ + int __ret = NF_ACCEPT; \ + \ + (skb)->ipvs_property = 1; \ + if (unlikely((cp)->flags & IP_VS_CONN_F_NFCT)) \ + __ret = ip_vs_confirm_conntrack(skb, cp); \ + if (__ret == NF_ACCEPT) { \ + nf_reset(skb); \ + skb_forward_csum(skb); \ + } \ + __ret; \ +}) + +#define IP_VS_XMIT_NAT(pf, skb, cp, local) \ +do { \ + (skb)->ipvs_property = 1; \ + if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ + ip_vs_notrack(skb); \ + else \ + ip_vs_update_conntrack(skb, cp, 1); \ + if (local) \ + return NF_ACCEPT; \ + skb_forward_csum(skb); \ + NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ + skb_dst(skb)->dev, dst_output); \ +} while (0) + +#define IP_VS_XMIT(pf, skb, cp, local) \ do { \ (skb)->ipvs_property = 1; \ + if (likely(!((cp)->flags & IP_VS_CONN_F_NFCT))) \ + ip_vs_notrack(skb); \ + if (local) \ + return NF_ACCEPT; \ skb_forward_csum(skb); \ NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \ - (rt)->dst.dev, dst_output); \ + skb_dst(skb)->dev, dst_output); \ } while (0) @@ -211,7 +383,7 @@ ip_vs_null_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { /* we do not touch skb and do not need pskb ptr */ - return NF_ACCEPT; + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1); } @@ -226,24 +398,13 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, { struct rtable *rt; /* Route to the other host */ struct iphdr *iph = ip_hdr(skb); - u8 tos = iph->tos; int mtu; - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip4_u = { - .daddr = iph->daddr, - .saddr = 0, - .tos = RT_TOS(tos), } }, - }; EnterFunction(10); - if (ip_route_output_key(&init_net, &rt, &fl)) { - IP_VS_DBG_RL("%s(): ip_route_output error, dest: %pI4\n", - __func__, &iph->daddr); + if (!(rt = __ip_vs_get_out_rt(skb, NULL, iph->daddr, + RT_TOS(iph->tos), 2))) goto tx_error_icmp; - } /* MTU checking */ mtu = dst_mtu(&rt->dst); @@ -271,7 +432,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 0); LeaveFunction(10); return NF_STOLEN; @@ -292,28 +453,22 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct rt6_info *rt; /* Route to the other host */ struct ipv6hdr *iph = ipv6_hdr(skb); int mtu; - struct flowi fl = { - .oif = 0, - .nl_u = { - .ip6_u = { - .daddr = iph->daddr, - .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } }, - }; EnterFunction(10); - rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl); - if (!rt) { - IP_VS_DBG_RL("%s(): ip6_route_output error, dest: %pI6\n", - __func__, &iph->daddr); + if (!(rt = __ip_vs_get_out_rt_v6(skb, NULL, &iph->daddr, NULL, 0, 2))) goto tx_error_icmp; - } /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { - dst_release(&rt->dst); + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + dst_release(&rt->dst); IP_VS_DBG_RL("%s(): frag needed\n", __func__); goto tx_error; } @@ -335,7 +490,7 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, rt); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 0); LeaveFunction(10); return NF_STOLEN; @@ -349,36 +504,6 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, } #endif -void -ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin) -{ - struct nf_conn *ct = (struct nf_conn *)skb->nfct; - struct nf_conntrack_tuple new_tuple; - - if (ct == NULL || nf_ct_is_untracked(ct) || nf_ct_is_confirmed(ct)) - return; - - /* - * The connection is not yet in the hashtable, so we update it. - * CIP->VIP will remain the same, so leave the tuple in - * IP_CT_DIR_ORIGINAL untouched. When the reply comes back from the - * real-server we will see RIP->DIP. - */ - new_tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; - if (outin) - new_tuple.src.u3 = cp->daddr; - else - new_tuple.dst.u3 = cp->vaddr; - /* - * This will also take care of UDP and other protocols. - */ - if (outin) - new_tuple.src.u.tcp.port = cp->dport; - else - new_tuple.dst.u.tcp.port = cp->vport; - nf_conntrack_alter_reply(ct, &new_tuple); -} - /* * NAT transmitter (only for outside-to-inside nat forwarding) * Not used for related ICMP @@ -390,6 +515,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct rtable *rt; /* Route to the other host */ int mtu; struct iphdr *iph = ip_hdr(skb); + int local; EnterFunction(10); @@ -403,16 +529,42 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p)); } - if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(iph->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, + RT_TOS(iph->tos), 1|2|4))) goto tx_error_icmp; + local = rt->rt_flags & RTCF_LOCAL; + /* + * Avoid duplicate tuple in reply direction for NAT traffic + * to local address when connection is sync-ed + */ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (cp->flags & IP_VS_CONN_F_SYNC && local) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (ct && !nf_ct_is_untracked(ct)) { + IP_VS_DBG_RL_PKT(10, AF_INET, pp, skb, 0, + "ip_vs_nat_xmit(): " + "stopping DNAT to local address"); + goto tx_error_put; + } + } +#endif + + /* From world but DNAT to loopback address? */ + if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { + IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): " + "stopping DNAT to loopback address"); + goto tx_error_put; + } /* MTU checking */ mtu = dst_mtu(&rt->dst); if ((skb->len > mtu) && (iph->frag_off & htons(IP_DF))) { - ip_rt_put(rt); icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu)); - IP_VS_DBG_RL_PKT(0, pp, skb, 0, "ip_vs_nat_xmit(): frag needed for"); - goto tx_error; + IP_VS_DBG_RL_PKT(0, AF_INET, pp, skb, 0, + "ip_vs_nat_xmit(): frag needed for"); + goto tx_error_put; } /* copy-on-write the packet before mangling it */ @@ -422,19 +574,28 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_cow(skb, rt->dst.dev->hard_header_len)) goto tx_error_put; - /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - /* mangle the packet */ if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) - goto tx_error; + goto tx_error_put; ip_hdr(skb)->daddr = cp->daddr.ip; ip_send_check(ip_hdr(skb)); - IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); + if (!local) { + /* drop old route */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } else { + ip_rt_put(rt); + /* + * Some IPv4 replies get local address from routes, + * not from iph, so while we DNAT after routing + * we need this second input/output route. + */ + if (!__ip_vs_reroute_locally(skb)) + goto tx_error; + } - ip_vs_update_conntrack(skb, cp, 1); + IP_VS_DBG_PKT(10, AF_INET, pp, skb, 0, "After DNAT"); /* FIXME: when application helper enlarges the packet and the length is larger than the MTU of outgoing device, there will be still @@ -443,7 +604,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, rt); + IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp, local); LeaveFunction(10); return NF_STOLEN; @@ -451,8 +612,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, tx_error_icmp: dst_link_failure(skb); tx_error: - LeaveFunction(10); kfree_skb(skb); + LeaveFunction(10); return NF_STOLEN; tx_error_put: ip_rt_put(rt); @@ -466,6 +627,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, { struct rt6_info *rt; /* Route to the other host */ int mtu; + int local; EnterFunction(10); @@ -480,18 +642,49 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p)); } - rt = __ip_vs_get_out_rt_v6(cp); - if (!rt) + if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL, + 0, 1|2|4))) goto tx_error_icmp; + local = __ip_vs_is_local_route6(rt); + /* + * Avoid duplicate tuple in reply direction for NAT traffic + * to local address when connection is sync-ed + */ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (cp->flags & IP_VS_CONN_F_SYNC && local) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (ct && !nf_ct_is_untracked(ct)) { + IP_VS_DBG_RL_PKT(10, AF_INET6, pp, skb, 0, + "ip_vs_nat_xmit_v6(): " + "stopping DNAT to local address"); + goto tx_error_put; + } + } +#endif + + /* From world but DNAT to loopback address? */ + if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) && + ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) { + IP_VS_DBG_RL_PKT(1, AF_INET6, pp, skb, 0, + "ip_vs_nat_xmit_v6(): " + "stopping DNAT to loopback address"); + goto tx_error_put; + } /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { - dst_release(&rt->dst); + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); - IP_VS_DBG_RL_PKT(0, pp, skb, 0, + IP_VS_DBG_RL_PKT(0, AF_INET6, pp, skb, 0, "ip_vs_nat_xmit_v6(): frag needed for"); - goto tx_error; + goto tx_error_put; } /* copy-on-write the packet before mangling it */ @@ -501,18 +694,21 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_cow(skb, rt->dst.dev->hard_header_len)) goto tx_error_put; - /* drop old route */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - /* mangle the packet */ if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) goto tx_error; - ipv6_hdr(skb)->daddr = cp->daddr.in6; + ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &cp->daddr.in6); - IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); + if (!local || !skb->dev) { + /* drop the old route when skb is not shared */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } else { + /* destined to loopback, do we need to change route? */ + dst_release(&rt->dst); + } - ip_vs_update_conntrack(skb, cp, 1); + IP_VS_DBG_PKT(10, AF_INET6, pp, skb, 0, "After DNAT"); /* FIXME: when application helper enlarges the packet and the length is larger than the MTU of outgoing device, there will be still @@ -521,7 +717,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, rt); + IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp, local); LeaveFunction(10); return NF_STOLEN; @@ -567,30 +763,27 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct iphdr *old_iph = ip_hdr(skb); u8 tos = old_iph->tos; __be16 df = old_iph->frag_off; - sk_buff_data_t old_transport_header = skb->transport_header; struct iphdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ int mtu; + int ret; EnterFunction(10); - if (skb->protocol != htons(ETH_P_IP)) { - IP_VS_DBG_RL("%s(): protocol error, " - "ETH_P_IP: %d, skb protocol: %d\n", - __func__, htons(ETH_P_IP), skb->protocol); - goto tx_error; - } - - if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, + RT_TOS(tos), 1|2))) goto tx_error_icmp; + if (rt->rt_flags & RTCF_LOCAL) { + ip_rt_put(rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1); + } tdev = rt->dst.dev; mtu = dst_mtu(&rt->dst) - sizeof(struct iphdr); if (mtu < 68) { - ip_rt_put(rt); IP_VS_DBG_RL("%s(): mtu less than 68\n", __func__); - goto tx_error; + goto tx_error_put; } if (skb_dst(skb)) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); @@ -600,9 +793,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, if ((old_iph->frag_off & htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) { icmp_send(skb, ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED, htonl(mtu)); - ip_rt_put(rt); IP_VS_DBG_RL("%s(): frag needed\n", __func__); - goto tx_error; + goto tx_error_put; } /* @@ -625,7 +817,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, old_iph = ip_hdr(skb); } - skb->transport_header = old_transport_header; + skb->transport_header = skb->network_header; /* fix old IP header checksum */ ip_send_check(old_iph); @@ -655,7 +847,11 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - ip_local_out(skb); + ret = IP_VS_XMIT_TUNNEL(skb, cp); + if (ret == NF_ACCEPT) + ip_local_out(skb); + else if (ret == NF_DROP) + kfree_skb(skb); LeaveFunction(10); @@ -667,6 +863,9 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, kfree_skb(skb); LeaveFunction(10); return NF_STOLEN; +tx_error_put: + ip_rt_put(rt); + goto tx_error; } #ifdef CONFIG_IP_VS_IPV6 @@ -675,43 +874,44 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp) { struct rt6_info *rt; /* Route to the other host */ + struct in6_addr saddr; /* Source for tunnel */ struct net_device *tdev; /* Device to other host */ struct ipv6hdr *old_iph = ipv6_hdr(skb); - sk_buff_data_t old_transport_header = skb->transport_header; struct ipv6hdr *iph; /* Our new IP header */ unsigned int max_headroom; /* The extra header space needed */ int mtu; + int ret; EnterFunction(10); - if (skb->protocol != htons(ETH_P_IPV6)) { - IP_VS_DBG_RL("%s(): protocol error, " - "ETH_P_IPV6: %d, skb protocol: %d\n", - __func__, htons(ETH_P_IPV6), skb->protocol); - goto tx_error; - } - - rt = __ip_vs_get_out_rt_v6(cp); - if (!rt) + if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, + &saddr, 1, 1|2))) goto tx_error_icmp; + if (__ip_vs_is_local_route6(rt)) { + dst_release(&rt->dst); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 1); + } tdev = rt->dst.dev; mtu = dst_mtu(&rt->dst) - sizeof(struct ipv6hdr); - /* TODO IPv6: do we need this check in IPv6? */ - if (mtu < 1280) { - dst_release(&rt->dst); - IP_VS_DBG_RL("%s(): mtu less than 1280\n", __func__); - goto tx_error; + if (mtu < IPV6_MIN_MTU) { + IP_VS_DBG_RL("%s(): mtu less than %d\n", __func__, + IPV6_MIN_MTU); + goto tx_error_put; } if (skb_dst(skb)) skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu); if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) { + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); - dst_release(&rt->dst); IP_VS_DBG_RL("%s(): frag needed\n", __func__); - goto tx_error; + goto tx_error_put; } /* @@ -734,7 +934,7 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, old_iph = ipv6_hdr(skb); } - skb->transport_header = old_transport_header; + skb->transport_header = skb->network_header; skb_push(skb, sizeof(struct ipv6hdr)); skb_reset_network_header(skb); @@ -754,14 +954,18 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, be16_add_cpu(&iph->payload_len, sizeof(*old_iph)); iph->priority = old_iph->priority; memset(&iph->flow_lbl, 0, sizeof(iph->flow_lbl)); - iph->daddr = rt->rt6i_dst.addr; - iph->saddr = cp->vaddr.in6; /* rt->rt6i_src.addr; */ + ipv6_addr_copy(&iph->daddr, &cp->daddr.in6); + ipv6_addr_copy(&iph->saddr, &saddr); iph->hop_limit = old_iph->hop_limit; /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - ip6_local_out(skb); + ret = IP_VS_XMIT_TUNNEL(skb, cp); + if (ret == NF_ACCEPT) + ip6_local_out(skb); + else if (ret == NF_DROP) + kfree_skb(skb); LeaveFunction(10); @@ -773,6 +977,9 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, kfree_skb(skb); LeaveFunction(10); return NF_STOLEN; +tx_error_put: + dst_release(&rt->dst); + goto tx_error; } #endif @@ -791,8 +998,13 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(iph->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, + RT_TOS(iph->tos), 1|2))) goto tx_error_icmp; + if (rt->rt_flags & RTCF_LOCAL) { + ip_rt_put(rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 1); + } /* MTU checking */ mtu = dst_mtu(&rt->dst); @@ -820,7 +1032,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, rt); + IP_VS_XMIT(NFPROTO_IPV4, skb, cp, 0); LeaveFunction(10); return NF_STOLEN; @@ -843,13 +1055,22 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, EnterFunction(10); - rt = __ip_vs_get_out_rt_v6(cp); - if (!rt) + if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL, + 0, 1|2))) goto tx_error_icmp; + if (__ip_vs_is_local_route6(rt)) { + dst_release(&rt->dst); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 1); + } /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); dst_release(&rt->dst); IP_VS_DBG_RL("%s(): frag needed\n", __func__); @@ -873,7 +1094,7 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, rt); + IP_VS_XMIT(NFPROTO_IPV6, skb, cp, 0); LeaveFunction(10); return NF_STOLEN; @@ -899,6 +1120,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct rtable *rt; /* Route to the other host */ int mtu; int rc; + int local; EnterFunction(10); @@ -919,16 +1141,43 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, * mangle and send the packet here (only for VS/NAT) */ - if (!(rt = __ip_vs_get_out_rt(cp, RT_TOS(ip_hdr(skb)->tos)))) + if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, + RT_TOS(ip_hdr(skb)->tos), 1|2|4))) goto tx_error_icmp; + local = rt->rt_flags & RTCF_LOCAL; + + /* + * Avoid duplicate tuple in reply direction for NAT traffic + * to local address when connection is sync-ed + */ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (cp->flags & IP_VS_CONN_F_SYNC && local) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (ct && !nf_ct_is_untracked(ct)) { + IP_VS_DBG(10, "%s(): " + "stopping DNAT to local address %pI4\n", + __func__, &cp->daddr.ip); + goto tx_error_put; + } + } +#endif + + /* From world but DNAT to loopback address? */ + if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { + IP_VS_DBG(1, "%s(): " + "stopping DNAT to loopback %pI4\n", + __func__, &cp->daddr.ip); + goto tx_error_put; + } /* MTU checking */ mtu = dst_mtu(&rt->dst); if ((skb->len > mtu) && (ip_hdr(skb)->frag_off & htons(IP_DF))) { - ip_rt_put(rt); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); IP_VS_DBG_RL("%s(): frag needed\n", __func__); - goto tx_error; + goto tx_error_put; } /* copy-on-write the packet before mangling it */ @@ -938,16 +1187,27 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_cow(skb, rt->dst.dev->hard_header_len)) goto tx_error_put; - /* drop the old route when skb is not shared */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - ip_vs_nat_icmp(skb, pp, cp, 0); + if (!local) { + /* drop the old route when skb is not shared */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } else { + ip_rt_put(rt); + /* + * Some IPv4 replies get local address from routes, + * not from iph, so while we DNAT after routing + * we need this second input/output route. + */ + if (!__ip_vs_reroute_locally(skb)) + goto tx_error; + } + /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV4, skb, rt); + IP_VS_XMIT_NAT(NFPROTO_IPV4, skb, cp, local); rc = NF_STOLEN; goto out; @@ -973,6 +1233,7 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct rt6_info *rt; /* Route to the other host */ int mtu; int rc; + int local; EnterFunction(10); @@ -993,17 +1254,49 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, * mangle and send the packet here (only for VS/NAT) */ - rt = __ip_vs_get_out_rt_v6(cp); - if (!rt) + if (!(rt = __ip_vs_get_out_rt_v6(skb, cp->dest, &cp->daddr.in6, NULL, + 0, 1|2|4))) goto tx_error_icmp; + local = __ip_vs_is_local_route6(rt); + /* + * Avoid duplicate tuple in reply direction for NAT traffic + * to local address when connection is sync-ed + */ +#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) + if (cp->flags & IP_VS_CONN_F_SYNC && local) { + enum ip_conntrack_info ctinfo; + struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo); + + if (ct && !nf_ct_is_untracked(ct)) { + IP_VS_DBG(10, "%s(): " + "stopping DNAT to local address %pI6\n", + __func__, &cp->daddr.in6); + goto tx_error_put; + } + } +#endif + + /* From world but DNAT to loopback address? */ + if (local && skb->dev && !(skb->dev->flags & IFF_LOOPBACK) && + ipv6_addr_type(&rt->rt6i_dst.addr) & IPV6_ADDR_LOOPBACK) { + IP_VS_DBG(1, "%s(): " + "stopping DNAT to loopback %pI6\n", + __func__, &cp->daddr.in6); + goto tx_error_put; + } + /* MTU checking */ mtu = dst_mtu(&rt->dst); if (skb->len > mtu) { - dst_release(&rt->dst); + if (!skb->dev) { + struct net *net = dev_net(skb_dst(skb)->dev); + + skb->dev = net->loopback_dev; + } icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); IP_VS_DBG_RL("%s(): frag needed\n", __func__); - goto tx_error; + goto tx_error_put; } /* copy-on-write the packet before mangling it */ @@ -1013,16 +1306,21 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, if (skb_cow(skb, rt->dst.dev->hard_header_len)) goto tx_error_put; - /* drop the old route when skb is not shared */ - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - ip_vs_nat_icmp_v6(skb, pp, cp, 0); + if (!local || !skb->dev) { + /* drop the old route when skb is not shared */ + skb_dst_drop(skb); + skb_dst_set(skb, &rt->dst); + } else { + /* destined to loopback, do we need to change route? */ + dst_release(&rt->dst); + } + /* Another hack: avoid icmp_send in ip_fragment */ skb->local_df = 1; - IP_VS_XMIT(NFPROTO_IPV6, skb, rt); + IP_VS_XMIT_NAT(NFPROTO_IPV6, skb, cp, local); rc = NF_STOLEN; goto out; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index df3eedb142ff809b9ce8f9dd49c41782f91aba42..1eacf8d9966aa292f7f051964f822a00c0ab6605 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -65,32 +65,42 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max); DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked); EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked); -static int nf_conntrack_hash_rnd_initted; -static unsigned int nf_conntrack_hash_rnd; +static unsigned int nf_conntrack_hash_rnd __read_mostly; -static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple, - u16 zone, unsigned int size, unsigned int rnd) +static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, u16 zone) { unsigned int n; - u_int32_t h; /* The direction must be ignored, so we hash everything up to the * destination ports (which is a multiple of 4) and treat the last * three bytes manually. */ n = (sizeof(tuple->src) + sizeof(tuple->dst.u3)) / sizeof(u32); - h = jhash2((u32 *)tuple, n, - zone ^ rnd ^ (((__force __u16)tuple->dst.u.all << 16) | - tuple->dst.protonum)); + return jhash2((u32 *)tuple, n, zone ^ nf_conntrack_hash_rnd ^ + (((__force __u16)tuple->dst.u.all << 16) | + tuple->dst.protonum)); +} + +static u32 __hash_bucket(u32 hash, unsigned int size) +{ + return ((u64)hash * size) >> 32; +} + +static u32 hash_bucket(u32 hash, const struct net *net) +{ + return __hash_bucket(hash, net->ct.htable_size); +} - return ((u64)h * size) >> 32; +static u_int32_t __hash_conntrack(const struct nf_conntrack_tuple *tuple, + u16 zone, unsigned int size) +{ + return __hash_bucket(hash_conntrack_raw(tuple, zone), size); } static inline u_int32_t hash_conntrack(const struct net *net, u16 zone, const struct nf_conntrack_tuple *tuple) { - return __hash_conntrack(tuple, zone, net->ct.htable_size, - nf_conntrack_hash_rnd); + return __hash_conntrack(tuple, zone, net->ct.htable_size); } bool @@ -292,20 +302,20 @@ static void death_by_timeout(unsigned long ul_conntrack) * OR * - Caller must lock nf_conntrack_lock before calling this function */ -struct nf_conntrack_tuple_hash * -__nf_conntrack_find(struct net *net, u16 zone, - const struct nf_conntrack_tuple *tuple) +static struct nf_conntrack_tuple_hash * +____nf_conntrack_find(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple, u32 hash) { struct nf_conntrack_tuple_hash *h; struct hlist_nulls_node *n; - unsigned int hash = hash_conntrack(net, zone, tuple); + unsigned int bucket = hash_bucket(hash, net); /* Disable BHs the entire time since we normally need to disable them * at least once for the stats anyway. */ local_bh_disable(); begin: - hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnnode) { + hlist_nulls_for_each_entry_rcu(h, n, &net->ct.hash[bucket], hnnode) { if (nf_ct_tuple_equal(tuple, &h->tuple) && nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)) == zone) { NF_CT_STAT_INC(net, found); @@ -319,7 +329,7 @@ __nf_conntrack_find(struct net *net, u16 zone, * not the expected one, we must restart lookup. * We probably met an item that was moved to another chain. */ - if (get_nulls_value(n) != hash) { + if (get_nulls_value(n) != bucket) { NF_CT_STAT_INC(net, search_restart); goto begin; } @@ -327,19 +337,27 @@ __nf_conntrack_find(struct net *net, u16 zone, return NULL; } + +struct nf_conntrack_tuple_hash * +__nf_conntrack_find(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple) +{ + return ____nf_conntrack_find(net, zone, tuple, + hash_conntrack_raw(tuple, zone)); +} EXPORT_SYMBOL_GPL(__nf_conntrack_find); /* Find a connection corresponding to a tuple. */ -struct nf_conntrack_tuple_hash * -nf_conntrack_find_get(struct net *net, u16 zone, - const struct nf_conntrack_tuple *tuple) +static struct nf_conntrack_tuple_hash * +__nf_conntrack_find_get(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple, u32 hash) { struct nf_conntrack_tuple_hash *h; struct nf_conn *ct; rcu_read_lock(); begin: - h = __nf_conntrack_find(net, zone, tuple); + h = ____nf_conntrack_find(net, zone, tuple, hash); if (h) { ct = nf_ct_tuplehash_to_ctrack(h); if (unlikely(nf_ct_is_dying(ct) || @@ -357,6 +375,14 @@ nf_conntrack_find_get(struct net *net, u16 zone, return h; } + +struct nf_conntrack_tuple_hash * +nf_conntrack_find_get(struct net *net, u16 zone, + const struct nf_conntrack_tuple *tuple) +{ + return __nf_conntrack_find_get(net, zone, tuple, + hash_conntrack_raw(tuple, zone)); +} EXPORT_SYMBOL_GPL(nf_conntrack_find_get); static void __nf_conntrack_hash_insert(struct nf_conn *ct, @@ -409,8 +435,11 @@ __nf_conntrack_confirm(struct sk_buff *skb) return NF_ACCEPT; zone = nf_ct_zone(ct); - hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); - repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple); + /* reuse the hash saved before */ + hash = *(unsigned long *)&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev; + hash = hash_bucket(hash, net); + repl_hash = hash_conntrack(net, zone, + &ct->tuplehash[IP_CT_DIR_REPLY].tuple); /* We're not in hash table, and we refuse to set up related connections for unconfirmed conns. But packet copies and @@ -567,17 +596,29 @@ static noinline int early_drop(struct net *net, unsigned int hash) return dropped; } -struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, - const struct nf_conntrack_tuple *orig, - const struct nf_conntrack_tuple *repl, - gfp_t gfp) +static struct nf_conn * +__nf_conntrack_alloc(struct net *net, u16 zone, + const struct nf_conntrack_tuple *orig, + const struct nf_conntrack_tuple *repl, + gfp_t gfp, u32 hash) { struct nf_conn *ct; - if (unlikely(!nf_conntrack_hash_rnd_initted)) { - get_random_bytes(&nf_conntrack_hash_rnd, - sizeof(nf_conntrack_hash_rnd)); - nf_conntrack_hash_rnd_initted = 1; + if (unlikely(!nf_conntrack_hash_rnd)) { + unsigned int rand; + + /* + * Why not initialize nf_conntrack_rnd in a "init()" function ? + * Because there isn't enough entropy when system initializing, + * and we initialize it as late as possible. + */ + do { + get_random_bytes(&rand, sizeof(rand)); + } while (!rand); + cmpxchg(&nf_conntrack_hash_rnd, 0, rand); + + /* recompute the hash as nf_conntrack_hash_rnd is initialized */ + hash = hash_conntrack_raw(orig, zone); } /* We don't want any race condition at early drop stage */ @@ -585,8 +626,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, if (nf_conntrack_max && unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) { - unsigned int hash = hash_conntrack(net, zone, orig); - if (!early_drop(net, hash)) { + if (!early_drop(net, hash_bucket(hash, net))) { atomic_dec(&net->ct.count); if (net_ratelimit()) printk(KERN_WARNING @@ -616,7 +656,8 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig; ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL; ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; - ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev = NULL; + /* save hash for reusing when confirming */ + *(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash; /* Don't set timer yet: wait for confirmation */ setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); write_pnet(&ct->ct_net, net); @@ -643,6 +684,14 @@ struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, return ERR_PTR(-ENOMEM); #endif } + +struct nf_conn *nf_conntrack_alloc(struct net *net, u16 zone, + const struct nf_conntrack_tuple *orig, + const struct nf_conntrack_tuple *repl, + gfp_t gfp) +{ + return __nf_conntrack_alloc(net, zone, orig, repl, gfp, 0); +} EXPORT_SYMBOL_GPL(nf_conntrack_alloc); void nf_conntrack_free(struct nf_conn *ct) @@ -664,7 +713,7 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, struct nf_conntrack_l3proto *l3proto, struct nf_conntrack_l4proto *l4proto, struct sk_buff *skb, - unsigned int dataoff) + unsigned int dataoff, u32 hash) { struct nf_conn *ct; struct nf_conn_help *help; @@ -678,7 +727,8 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, return NULL; } - ct = nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC); + ct = __nf_conntrack_alloc(net, zone, tuple, &repl_tuple, GFP_ATOMIC, + hash); if (IS_ERR(ct)) { pr_debug("Can't allocate conntrack.\n"); return (struct nf_conntrack_tuple_hash *)ct; @@ -755,6 +805,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, struct nf_conntrack_tuple_hash *h; struct nf_conn *ct; u16 zone = tmpl ? nf_ct_zone(tmpl) : NF_CT_DEFAULT_ZONE; + u32 hash; if (!nf_ct_get_tuple(skb, skb_network_offset(skb), dataoff, l3num, protonum, &tuple, l3proto, @@ -764,10 +815,11 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, } /* look for tuple match */ - h = nf_conntrack_find_get(net, zone, &tuple); + hash = hash_conntrack_raw(&tuple, zone); + h = __nf_conntrack_find_get(net, zone, &tuple, hash); if (!h) { h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto, - skb, dataoff); + skb, dataoff, hash); if (!h) return NULL; if (IS_ERR(h)) @@ -1307,8 +1359,7 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp) ct = nf_ct_tuplehash_to_ctrack(h); hlist_nulls_del_rcu(&h->hnnode); bucket = __hash_conntrack(&h->tuple, nf_ct_zone(ct), - hashsize, - nf_conntrack_hash_rnd); + hashsize); hlist_nulls_add_head_rcu(&h->hnnode, &hash[bucket]); } } diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index acb29ccaa41fd46624754adb794b5d9389a45c3c..46e8966912b1d9db01fc2997ce0574f0c6094062 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -38,25 +38,30 @@ static int nf_ct_expect_hash_rnd_initted __read_mostly; static struct kmem_cache *nf_ct_expect_cachep __read_mostly; +static HLIST_HEAD(nf_ct_userspace_expect_list); + /* nf_conntrack_expect helper functions */ -void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) +void nf_ct_unlink_expect_report(struct nf_conntrack_expect *exp, + u32 pid, int report) { struct nf_conn_help *master_help = nfct_help(exp->master); struct net *net = nf_ct_exp_net(exp); - NF_CT_ASSERT(master_help); NF_CT_ASSERT(!timer_pending(&exp->timeout)); hlist_del_rcu(&exp->hnode); net->ct.expect_count--; hlist_del(&exp->lnode); - master_help->expecting[exp->class]--; + if (!(exp->flags & NF_CT_EXPECT_USERSPACE)) + master_help->expecting[exp->class]--; + + nf_ct_expect_event_report(IPEXP_DESTROY, exp, pid, report); nf_ct_expect_put(exp); NF_CT_STAT_INC(net, expect_delete); } -EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); +EXPORT_SYMBOL_GPL(nf_ct_unlink_expect_report); static void nf_ct_expectation_timed_out(unsigned long ul_expect) { @@ -320,16 +325,21 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) atomic_inc(&exp->use); - hlist_add_head(&exp->lnode, &master_help->expectations); - master_help->expecting[exp->class]++; + if (master_help) { + hlist_add_head(&exp->lnode, &master_help->expectations); + master_help->expecting[exp->class]++; + } else if (exp->flags & NF_CT_EXPECT_USERSPACE) + hlist_add_head(&exp->lnode, &nf_ct_userspace_expect_list); hlist_add_head_rcu(&exp->hnode, &net->ct.expect_hash[h]); net->ct.expect_count++; setup_timer(&exp->timeout, nf_ct_expectation_timed_out, (unsigned long)exp); - p = &master_help->helper->expect_policy[exp->class]; - exp->timeout.expires = jiffies + p->timeout * HZ; + if (master_help) { + p = &master_help->helper->expect_policy[exp->class]; + exp->timeout.expires = jiffies + p->timeout * HZ; + } add_timer(&exp->timeout); atomic_inc(&exp->use); @@ -380,7 +390,9 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) unsigned int h; int ret = 1; - if (!master_help->helper) { + /* Don't allow expectations created from kernel-space with no helper */ + if (!(expect->flags & NF_CT_EXPECT_USERSPACE) && + (!master_help || (master_help && !master_help->helper))) { ret = -ESHUTDOWN; goto out; } @@ -398,13 +410,16 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) } } /* Will be over limit? */ - p = &master_help->helper->expect_policy[expect->class]; - if (p->max_expected && - master_help->expecting[expect->class] >= p->max_expected) { - evict_oldest_expect(master, expect); - if (master_help->expecting[expect->class] >= p->max_expected) { - ret = -EMFILE; - goto out; + if (master_help) { + p = &master_help->helper->expect_policy[expect->class]; + if (p->max_expected && + master_help->expecting[expect->class] >= p->max_expected) { + evict_oldest_expect(master, expect); + if (master_help->expecting[expect->class] + >= p->max_expected) { + ret = -EMFILE; + goto out; + } } } @@ -439,6 +454,21 @@ int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, } EXPORT_SYMBOL_GPL(nf_ct_expect_related_report); +void nf_ct_remove_userspace_expectations(void) +{ + struct nf_conntrack_expect *exp; + struct hlist_node *n, *next; + + hlist_for_each_entry_safe(exp, n, next, + &nf_ct_userspace_expect_list, lnode) { + if (del_timer(&exp->timeout)) { + nf_ct_unlink_expect(exp); + nf_ct_expect_put(exp); + } + } +} +EXPORT_SYMBOL_GPL(nf_ct_remove_userspace_expectations); + #ifdef CONFIG_PROC_FS struct ct_expect_iter_state { struct seq_net_private p; @@ -529,8 +559,12 @@ static int exp_seq_show(struct seq_file *s, void *v) seq_printf(s, "PERMANENT"); delim = ","; } - if (expect->flags & NF_CT_EXPECT_INACTIVE) + if (expect->flags & NF_CT_EXPECT_INACTIVE) { seq_printf(s, "%sINACTIVE", delim); + delim = ","; + } + if (expect->flags & NF_CT_EXPECT_USERSPACE) + seq_printf(s, "%sUSERSPACE", delim); helper = rcu_dereference(nfct_help(expect->master)->helper); if (helper) { diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 146476c6441a9ea8894d78bc5a00c558c84a0874..b729ace1dcc14614d88c51edc6f8968f9cb0a71f 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -1588,8 +1588,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, const struct nf_conntrack_expect *exp) { struct nf_conn *master = exp->master; - struct nf_conntrack_helper *helper; long timeout = (exp->timeout.expires - jiffies) / HZ; + struct nf_conn_help *help; if (timeout < 0) timeout = 0; @@ -1605,9 +1605,15 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb, NLA_PUT_BE32(skb, CTA_EXPECT_TIMEOUT, htonl(timeout)); NLA_PUT_BE32(skb, CTA_EXPECT_ID, htonl((unsigned long)exp)); - helper = rcu_dereference(nfct_help(master)->helper); - if (helper) - NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name); + NLA_PUT_BE32(skb, CTA_EXPECT_FLAGS, htonl(exp->flags)); + help = nfct_help(master); + if (help) { + struct nf_conntrack_helper *helper; + + helper = rcu_dereference(help->helper); + if (helper) + NLA_PUT_STRING(skb, CTA_EXPECT_HELP_NAME, helper->name); + } return 0; @@ -1654,17 +1660,20 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) struct nlmsghdr *nlh; struct nfgenmsg *nfmsg; struct sk_buff *skb; - unsigned int type; + unsigned int type, group; int flags = 0; - if (events & (1 << IPEXP_NEW)) { + if (events & (1 << IPEXP_DESTROY)) { + type = IPCTNL_MSG_EXP_DELETE; + group = NFNLGRP_CONNTRACK_EXP_DESTROY; + } else if (events & (1 << IPEXP_NEW)) { type = IPCTNL_MSG_EXP_NEW; flags = NLM_F_CREATE|NLM_F_EXCL; + group = NFNLGRP_CONNTRACK_EXP_NEW; } else return 0; - if (!item->report && - !nfnetlink_has_listeners(net, NFNLGRP_CONNTRACK_EXP_NEW)) + if (!item->report && !nfnetlink_has_listeners(net, group)) return 0; skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); @@ -1687,8 +1696,7 @@ ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item) rcu_read_unlock(); nlmsg_end(skb, nlh); - nfnetlink_send(skb, net, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, - item->report, GFP_ATOMIC); + nfnetlink_send(skb, net, item->pid, group, item->report, GFP_ATOMIC); return 0; nla_put_failure: @@ -1761,6 +1769,8 @@ static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { [CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 }, [CTA_EXPECT_ID] = { .type = NLA_U32 }, [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING }, + [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, + [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, }; static int @@ -1869,7 +1879,13 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, } /* after list removal, usage count == 1 */ - nf_ct_unexpect_related(exp); + spin_lock_bh(&nf_conntrack_lock); + if (del_timer(&exp->timeout)) { + nf_ct_unlink_expect_report(exp, NETLINK_CB(skb).pid, + nlmsg_report(nlh)); + nf_ct_expect_put(exp); + } + spin_unlock_bh(&nf_conntrack_lock); /* have to put what we 'get' above. * after this line usage count == 0 */ nf_ct_expect_put(exp); @@ -1886,7 +1902,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, m_help = nfct_help(exp->master); if (!strcmp(m_help->helper->name, name) && del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); + nf_ct_unlink_expect_report(exp, + NETLINK_CB(skb).pid, + nlmsg_report(nlh)); nf_ct_expect_put(exp); } } @@ -1900,7 +1918,9 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, &net->ct.expect_hash[i], hnode) { if (del_timer(&exp->timeout)) { - nf_ct_unlink_expect(exp); + nf_ct_unlink_expect_report(exp, + NETLINK_CB(skb).pid, + nlmsg_report(nlh)); nf_ct_expect_put(exp); } } @@ -1946,23 +1966,35 @@ ctnetlink_create_expect(struct net *net, u16 zone, if (!h) return -ENOENT; ct = nf_ct_tuplehash_to_ctrack(h); - help = nfct_help(ct); - - if (!help || !help->helper) { - /* such conntrack hasn't got any helper, abort */ - err = -EOPNOTSUPP; - goto out; - } - exp = nf_ct_expect_alloc(ct); if (!exp) { err = -ENOMEM; goto out; } + help = nfct_help(ct); + if (!help) { + if (!cda[CTA_EXPECT_TIMEOUT]) { + err = -EINVAL; + goto out; + } + exp->timeout.expires = + jiffies + ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ; + + exp->flags = NF_CT_EXPECT_USERSPACE; + if (cda[CTA_EXPECT_FLAGS]) { + exp->flags |= + ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS])); + } + } else { + if (cda[CTA_EXPECT_FLAGS]) { + exp->flags = ntohl(nla_get_be32(cda[CTA_EXPECT_FLAGS])); + exp->flags &= ~NF_CT_EXPECT_USERSPACE; + } else + exp->flags = 0; + } exp->class = 0; exp->expectfn = NULL; - exp->flags = 0; exp->master = ct; exp->helper = NULL; memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); @@ -2130,6 +2162,7 @@ static void __exit ctnetlink_exit(void) { pr_info("ctnetlink: unregistering from nfnetlink.\n"); + nf_ct_remove_userspace_expectations(); #ifdef CONFIG_NF_CONNTRACK_EVENTS nf_ct_expect_unregister_notifier(&ctnl_notifier_exp); nf_conntrack_unregister_notifier(&ctnl_notifier); diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index f64de95448669242cf23ac5d8a38987c2f8cd344..bcf47eb518effb4645440a6f64726089984eaeb7 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c @@ -130,6 +130,44 @@ static int digits_len(const struct nf_conn *ct, const char *dptr, return len; } +static int iswordc(const char c) +{ + if (isalnum(c) || c == '!' || c == '"' || c == '%' || + (c >= '(' && c <= '/') || c == ':' || c == '<' || c == '>' || + c == '?' || (c >= '[' && c <= ']') || c == '_' || c == '`' || + c == '{' || c == '}' || c == '~') + return 1; + return 0; +} + +static int word_len(const char *dptr, const char *limit) +{ + int len = 0; + while (dptr < limit && iswordc(*dptr)) { + dptr++; + len++; + } + return len; +} + +static int callid_len(const struct nf_conn *ct, const char *dptr, + const char *limit, int *shift) +{ + int len, domain_len; + + len = word_len(dptr, limit); + dptr += len; + if (!len || dptr == limit || *dptr != '@') + return len; + dptr++; + len++; + + domain_len = word_len(dptr, limit); + if (!domain_len) + return 0; + return len + domain_len; +} + /* get media type + port length */ static int media_len(const struct nf_conn *ct, const char *dptr, const char *limit, int *shift) @@ -152,6 +190,9 @@ static int parse_addr(const struct nf_conn *ct, const char *cp, const char *end; int ret = 0; + if (!ct) + return 0; + memset(addr, 0, sizeof(*addr)); switch (nf_ct_l3num(ct)) { case AF_INET: @@ -296,6 +337,7 @@ static const struct sip_header ct_sip_hdrs[] = { [SIP_HDR_VIA_TCP] = SIP_HDR("Via", "v", "TCP ", epaddr_len), [SIP_HDR_EXPIRES] = SIP_HDR("Expires", NULL, NULL, digits_len), [SIP_HDR_CONTENT_LENGTH] = SIP_HDR("Content-Length", "l", NULL, digits_len), + [SIP_HDR_CALL_ID] = SIP_HDR("Call-Id", "i", NULL, callid_len), }; static const char *sip_follow_continuation(const char *dptr, const char *limit) diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c index daab8c4a903ca20103c1c5d6ebe997fdb657f581..4d87befb04c04c793a54360de809e5eb64ee44c2 100644 --- a/net/netfilter/nf_tproxy_core.c +++ b/net/netfilter/nf_tproxy_core.c @@ -18,41 +18,6 @@ #include #include -struct sock * -nf_tproxy_get_sock_v4(struct net *net, const u8 protocol, - const __be32 saddr, const __be32 daddr, - const __be16 sport, const __be16 dport, - const struct net_device *in, bool listening_only) -{ - struct sock *sk; - - /* look up socket */ - switch (protocol) { - case IPPROTO_TCP: - if (listening_only) - sk = __inet_lookup_listener(net, &tcp_hashinfo, - daddr, ntohs(dport), - in->ifindex); - else - sk = __inet_lookup(net, &tcp_hashinfo, - saddr, sport, daddr, dport, - in->ifindex); - break; - case IPPROTO_UDP: - sk = udp4_lib_lookup(net, saddr, sport, daddr, dport, - in->ifindex); - break; - default: - WARN_ON(1); - sk = NULL; - } - - pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, listener only: %d, sock %p\n", - protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), listening_only, sk); - - return sk; -} -EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4); static void nf_tproxy_destructor(struct sk_buff *skb) diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index e34622fa000357c5e24eeddd2aad835d616fd8ce..80463507420edffe34544074be18b891928c7dc5 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -116,10 +116,8 @@ EXPORT_SYMBOL(xt_register_targets); void xt_unregister_targets(struct xt_target *target, unsigned int n) { - unsigned int i; - - for (i = 0; i < n; i++) - xt_unregister_target(&target[i]); + while (n-- > 0) + xt_unregister_target(&target[n]); } EXPORT_SYMBOL(xt_unregister_targets); @@ -174,10 +172,8 @@ EXPORT_SYMBOL(xt_register_matches); void xt_unregister_matches(struct xt_match *match, unsigned int n) { - unsigned int i; - - for (i = 0; i < n; i++) - xt_unregister_match(&match[i]); + while (n-- > 0) + xt_unregister_match(&match[n]); } EXPORT_SYMBOL(xt_unregister_matches); diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index c61294d85fdafbcb4696b704a6754f9f1c9476c1..19c482caf30b7f1587f41cd7b3c26a3d598bc084 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c @@ -1,7 +1,7 @@ /* * Transparent proxy support for Linux/iptables * - * Copyright (c) 2006-2007 BalaBit IT Ltd. + * Copyright (c) 2006-2010 BalaBit IT Ltd. * Author: Balazs Scheidler, Krisztian Kovacs * * This program is free software; you can redistribute it and/or modify @@ -16,19 +16,96 @@ #include #include #include - +#include #include #include -#include #include +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +#include +#include +#include +#include +#endif + #include +#include + +static inline __be32 +tproxy_laddr4(struct sk_buff *skb, __be32 user_laddr, __be32 daddr) +{ + struct in_device *indev; + __be32 laddr; + + if (user_laddr) + return user_laddr; + + laddr = 0; + rcu_read_lock(); + indev = __in_dev_get_rcu(skb->dev); + for_primary_ifa(indev) { + laddr = ifa->ifa_local; + break; + } endfor_ifa(indev); + rcu_read_unlock(); + + return laddr ? laddr : daddr; +} + +/** + * tproxy_handle_time_wait4() - handle IPv4 TCP TIME_WAIT reopen redirections + * @skb: The skb being processed. + * @laddr: IPv4 address to redirect to or zero. + * @lport: TCP port to redirect to or zero. + * @sk: The TIME_WAIT TCP socket found by the lookup. + * + * We have to handle SYN packets arriving to TIME_WAIT sockets + * differently: instead of reopening the connection we should rather + * redirect the new connection to the proxy if there's a listener + * socket present. + * + * tproxy_handle_time_wait4() consumes the socket reference passed in. + * + * Returns the listener socket if there's one, the TIME_WAIT socket if + * no such listener is found, or NULL if the TCP header is incomplete. + */ +static struct sock * +tproxy_handle_time_wait4(struct sk_buff *skb, __be32 laddr, __be16 lport, + struct sock *sk) +{ + const struct iphdr *iph = ip_hdr(skb); + struct tcphdr _hdr, *hp; + + hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr); + if (hp == NULL) { + inet_twsk_put(inet_twsk(sk)); + return NULL; + } + + if (hp->syn && !hp->rst && !hp->ack && !hp->fin) { + /* SYN to a TIME_WAIT socket, we'd rather redirect it + * to a listener socket if there's one */ + struct sock *sk2; + + sk2 = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, + iph->saddr, laddr ? laddr : iph->daddr, + hp->source, lport ? lport : hp->dest, + skb->dev, NFT_LOOKUP_LISTENER); + if (sk2) { + inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); + inet_twsk_put(inet_twsk(sk)); + sk = sk2; + } + } + + return sk; +} static unsigned int -tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) +tproxy_tg4(struct sk_buff *skb, __be32 laddr, __be16 lport, + u_int32_t mark_mask, u_int32_t mark_value) { const struct iphdr *iph = ip_hdr(skb); - const struct xt_tproxy_target_info *tgi = par->targinfo; struct udphdr _hdr, *hp; struct sock *sk; @@ -36,12 +113,195 @@ tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) if (hp == NULL) return NF_DROP; + /* check if there's an ongoing connection on the packet + * addresses, this happens if the redirect already happened + * and the current packet belongs to an already established + * connection */ sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, - iph->saddr, - tgi->laddr ? tgi->laddr : iph->daddr, - hp->source, - tgi->lport ? tgi->lport : hp->dest, - par->in, true); + iph->saddr, iph->daddr, + hp->source, hp->dest, + skb->dev, NFT_LOOKUP_ESTABLISHED); + + laddr = tproxy_laddr4(skb, laddr, iph->daddr); + if (!lport) + lport = hp->dest; + + /* UDP has no TCP_TIME_WAIT state, so we never enter here */ + if (sk && sk->sk_state == TCP_TIME_WAIT) + /* reopening a TIME_WAIT connection needs special handling */ + sk = tproxy_handle_time_wait4(skb, laddr, lport, sk); + else if (!sk) + /* no, there's no established connection, check if + * there's a listener on the redirected addr/port */ + sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol, + iph->saddr, laddr, + hp->source, lport, + skb->dev, NFT_LOOKUP_LISTENER); + + /* NOTE: assign_sock consumes our sk reference */ + if (sk && nf_tproxy_assign_sock(skb, sk)) { + /* This should be in a separate target, but we don't do multiple + targets on the same rule yet */ + skb->mark = (skb->mark & ~mark_mask) ^ mark_value; + + pr_debug("redirecting: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n", + iph->protocol, &iph->daddr, ntohs(hp->dest), + &laddr, ntohs(lport), skb->mark); + return NF_ACCEPT; + } + + pr_debug("no socket, dropping: proto %hhu %pI4:%hu -> %pI4:%hu, mark: %x\n", + iph->protocol, &iph->saddr, ntohs(hp->source), + &iph->daddr, ntohs(hp->dest), skb->mark); + return NF_DROP; +} + +static unsigned int +tproxy_tg4_v0(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct xt_tproxy_target_info *tgi = par->targinfo; + + return tproxy_tg4(skb, tgi->laddr, tgi->lport, tgi->mark_mask, tgi->mark_value); +} + +static unsigned int +tproxy_tg4_v1(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; + + return tproxy_tg4(skb, tgi->laddr.ip, tgi->lport, tgi->mark_mask, tgi->mark_value); +} + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + +static inline const struct in6_addr * +tproxy_laddr6(struct sk_buff *skb, const struct in6_addr *user_laddr, + const struct in6_addr *daddr) +{ + struct inet6_dev *indev; + struct inet6_ifaddr *ifa; + struct in6_addr *laddr; + + if (!ipv6_addr_any(user_laddr)) + return user_laddr; + laddr = NULL; + + rcu_read_lock(); + indev = __in6_dev_get(skb->dev); + if (indev) + list_for_each_entry(ifa, &indev->addr_list, if_list) { + if (ifa->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED)) + continue; + + laddr = &ifa->addr; + break; + } + rcu_read_unlock(); + + return laddr ? laddr : daddr; +} + +/** + * tproxy_handle_time_wait6() - handle IPv6 TCP TIME_WAIT reopen redirections + * @skb: The skb being processed. + * @tproto: Transport protocol. + * @thoff: Transport protocol header offset. + * @par: Iptables target parameters. + * @sk: The TIME_WAIT TCP socket found by the lookup. + * + * We have to handle SYN packets arriving to TIME_WAIT sockets + * differently: instead of reopening the connection we should rather + * redirect the new connection to the proxy if there's a listener + * socket present. + * + * tproxy_handle_time_wait6() consumes the socket reference passed in. + * + * Returns the listener socket if there's one, the TIME_WAIT socket if + * no such listener is found, or NULL if the TCP header is incomplete. + */ +static struct sock * +tproxy_handle_time_wait6(struct sk_buff *skb, int tproto, int thoff, + const struct xt_action_param *par, + struct sock *sk) +{ + const struct ipv6hdr *iph = ipv6_hdr(skb); + struct tcphdr _hdr, *hp; + const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; + + hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr); + if (hp == NULL) { + inet_twsk_put(inet_twsk(sk)); + return NULL; + } + + if (hp->syn && !hp->rst && !hp->ack && !hp->fin) { + /* SYN to a TIME_WAIT socket, we'd rather redirect it + * to a listener socket if there's one */ + struct sock *sk2; + + sk2 = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + &iph->saddr, + tproxy_laddr6(skb, &tgi->laddr.in6, &iph->daddr), + hp->source, + tgi->lport ? tgi->lport : hp->dest, + skb->dev, NFT_LOOKUP_LISTENER); + if (sk2) { + inet_twsk_deschedule(inet_twsk(sk), &tcp_death_row); + inet_twsk_put(inet_twsk(sk)); + sk = sk2; + } + } + + return sk; +} + +static unsigned int +tproxy_tg6_v1(struct sk_buff *skb, const struct xt_action_param *par) +{ + const struct ipv6hdr *iph = ipv6_hdr(skb); + const struct xt_tproxy_target_info_v1 *tgi = par->targinfo; + struct udphdr _hdr, *hp; + struct sock *sk; + const struct in6_addr *laddr; + __be16 lport; + int thoff; + int tproto; + + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); + if (tproto < 0) { + pr_debug("unable to find transport header in IPv6 packet, dropping\n"); + return NF_DROP; + } + + hp = skb_header_pointer(skb, thoff, sizeof(_hdr), &_hdr); + if (hp == NULL) { + pr_debug("unable to grab transport header contents in IPv6 packet, dropping\n"); + return NF_DROP; + } + + /* check if there's an ongoing connection on the packet + * addresses, this happens if the redirect already happened + * and the current packet belongs to an already established + * connection */ + sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + &iph->saddr, &iph->daddr, + hp->source, hp->dest, + par->in, NFT_LOOKUP_ESTABLISHED); + + laddr = tproxy_laddr6(skb, &tgi->laddr.in6, &iph->daddr); + lport = tgi->lport ? tgi->lport : hp->dest; + + /* UDP has no TCP_TIME_WAIT state, so we never enter here */ + if (sk && sk->sk_state == TCP_TIME_WAIT) + /* reopening a TIME_WAIT connection needs special handling */ + sk = tproxy_handle_time_wait6(skb, tproto, thoff, par, sk); + else if (!sk) + /* no there's no established connection, check if + * there's a listener on the redirected addr/port */ + sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + &iph->saddr, laddr, + hp->source, lport, + par->in, NFT_LOOKUP_LISTENER); /* NOTE: assign_sock consumes our sk reference */ if (sk && nf_tproxy_assign_sock(skb, sk)) { @@ -49,19 +309,34 @@ tproxy_tg(struct sk_buff *skb, const struct xt_action_param *par) targets on the same rule yet */ skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value; - pr_debug("redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n", - iph->protocol, ntohl(iph->daddr), ntohs(hp->dest), - ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark); + pr_debug("redirecting: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n", + tproto, &iph->saddr, ntohs(hp->source), + laddr, ntohs(lport), skb->mark); return NF_ACCEPT; } - pr_debug("no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n", - iph->protocol, ntohl(iph->daddr), ntohs(hp->dest), - ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark); + pr_debug("no socket, dropping: proto %hhu %pI6:%hu -> %pI6:%hu, mark: %x\n", + tproto, &iph->saddr, ntohs(hp->source), + &iph->daddr, ntohs(hp->dest), skb->mark); + return NF_DROP; } -static int tproxy_tg_check(const struct xt_tgchk_param *par) +static int tproxy_tg6_check(const struct xt_tgchk_param *par) +{ + const struct ip6t_ip6 *i = par->entryinfo; + + if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP) + && !(i->flags & IP6T_INV_PROTO)) + return 0; + + pr_info("Can be used only in combination with " + "either -p tcp or -p udp\n"); + return -EINVAL; +} +#endif + +static int tproxy_tg4_check(const struct xt_tgchk_param *par) { const struct ipt_ip *i = par->entryinfo; @@ -74,31 +349,64 @@ static int tproxy_tg_check(const struct xt_tgchk_param *par) return -EINVAL; } -static struct xt_target tproxy_tg_reg __read_mostly = { - .name = "TPROXY", - .family = AF_INET, - .table = "mangle", - .target = tproxy_tg, - .targetsize = sizeof(struct xt_tproxy_target_info), - .checkentry = tproxy_tg_check, - .hooks = 1 << NF_INET_PRE_ROUTING, - .me = THIS_MODULE, +static struct xt_target tproxy_tg_reg[] __read_mostly = { + { + .name = "TPROXY", + .family = NFPROTO_IPV4, + .table = "mangle", + .target = tproxy_tg4_v0, + .revision = 0, + .targetsize = sizeof(struct xt_tproxy_target_info), + .checkentry = tproxy_tg4_check, + .hooks = 1 << NF_INET_PRE_ROUTING, + .me = THIS_MODULE, + }, + { + .name = "TPROXY", + .family = NFPROTO_IPV4, + .table = "mangle", + .target = tproxy_tg4_v1, + .revision = 1, + .targetsize = sizeof(struct xt_tproxy_target_info_v1), + .checkentry = tproxy_tg4_check, + .hooks = 1 << NF_INET_PRE_ROUTING, + .me = THIS_MODULE, + }, +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + { + .name = "TPROXY", + .family = NFPROTO_IPV6, + .table = "mangle", + .target = tproxy_tg6_v1, + .revision = 1, + .targetsize = sizeof(struct xt_tproxy_target_info_v1), + .checkentry = tproxy_tg6_check, + .hooks = 1 << NF_INET_PRE_ROUTING, + .me = THIS_MODULE, + }, +#endif + }; static int __init tproxy_tg_init(void) { nf_defrag_ipv4_enable(); - return xt_register_target(&tproxy_tg_reg); +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + nf_defrag_ipv6_enable(); +#endif + + return xt_register_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg)); } static void __exit tproxy_tg_exit(void) { - xt_unregister_target(&tproxy_tg_reg); + xt_unregister_targets(tproxy_tg_reg, ARRAY_SIZE(tproxy_tg_reg)); } module_init(tproxy_tg_init); module_exit(tproxy_tg_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Krisztian Kovacs"); +MODULE_AUTHOR("Balazs Scheidler, Krisztian Kovacs"); MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module."); MODULE_ALIAS("ipt_TPROXY"); +MODULE_ALIAS("ip6t_TPROXY"); diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index b46a8390896d012dc4524e220a14d817d378dfd7..9228ee0dc11a307a49d131e7f879c738351dcef5 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -448,6 +448,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo, { __be16 _ports[2], *ports; u8 nexthdr; + int poff; memset(dst, 0, sizeof(*dst)); @@ -492,19 +493,13 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo, return 0; } - switch (nexthdr) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - case IPPROTO_SCTP: - case IPPROTO_DCCP: - ports = skb_header_pointer(skb, protoff, sizeof(_ports), + poff = proto_ports_offset(nexthdr); + if (poff >= 0) { + ports = skb_header_pointer(skb, protoff + poff, sizeof(_ports), &_ports); - break; - default: + } else { _ports[0] = _ports[1] = 0; ports = _ports; - break; } if (!ports) return -1; diff --git a/net/netfilter/xt_ipvs.c b/net/netfilter/xt_ipvs.c index 7a4d66db95aed4bade12679308045c942c155ba3..9127a3d8aa355d5ff94612bae755d69cb89fa402 100644 --- a/net/netfilter/xt_ipvs.c +++ b/net/netfilter/xt_ipvs.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 1ca89908cbad84d2dc45093aa474cca056f239e3..2dbd4c857735abdddde389dd5154bbba0e5f2aef 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include #include @@ -30,7 +32,7 @@ #endif static int -extract_icmp_fields(const struct sk_buff *skb, +extract_icmp4_fields(const struct sk_buff *skb, u8 *protocol, __be32 *raddr, __be32 *laddr, @@ -86,7 +88,6 @@ extract_icmp_fields(const struct sk_buff *skb, return 0; } - static bool socket_match(const struct sk_buff *skb, struct xt_action_param *par, const struct xt_socket_mtinfo1 *info) @@ -115,7 +116,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, dport = hp->dest; } else if (iph->protocol == IPPROTO_ICMP) { - if (extract_icmp_fields(skb, &protocol, &saddr, &daddr, + if (extract_icmp4_fields(skb, &protocol, &saddr, &daddr, &sport, &dport)) return false; } else { @@ -142,7 +143,7 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, #endif sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol, - saddr, daddr, sport, dport, par->in, false); + saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY); if (sk != NULL) { bool wildcard; bool transparent = true; @@ -165,32 +166,157 @@ socket_match(const struct sk_buff *skb, struct xt_action_param *par, sk = NULL; } - pr_debug("proto %u %08x:%u -> %08x:%u (orig %08x:%u) sock %p\n", - protocol, ntohl(saddr), ntohs(sport), - ntohl(daddr), ntohs(dport), - ntohl(iph->daddr), hp ? ntohs(hp->dest) : 0, sk); + pr_debug("proto %hhu %pI4:%hu -> %pI4:%hu (orig %pI4:%hu) sock %p\n", + protocol, &saddr, ntohs(sport), + &daddr, ntohs(dport), + &iph->daddr, hp ? ntohs(hp->dest) : 0, sk); return (sk != NULL); } static bool -socket_mt_v0(const struct sk_buff *skb, struct xt_action_param *par) +socket_mt4_v0(const struct sk_buff *skb, struct xt_action_param *par) { return socket_match(skb, par, NULL); } static bool -socket_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) +socket_mt4_v1(const struct sk_buff *skb, struct xt_action_param *par) { return socket_match(skb, par, par->matchinfo); } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + +static int +extract_icmp6_fields(const struct sk_buff *skb, + unsigned int outside_hdrlen, + u8 *protocol, + struct in6_addr **raddr, + struct in6_addr **laddr, + __be16 *rport, + __be16 *lport) +{ + struct ipv6hdr *inside_iph, _inside_iph; + struct icmp6hdr *icmph, _icmph; + __be16 *ports, _ports[2]; + u8 inside_nexthdr; + int inside_hdrlen; + + icmph = skb_header_pointer(skb, outside_hdrlen, + sizeof(_icmph), &_icmph); + if (icmph == NULL) + return 1; + + if (icmph->icmp6_type & ICMPV6_INFOMSG_MASK) + return 1; + + inside_iph = skb_header_pointer(skb, outside_hdrlen + sizeof(_icmph), sizeof(_inside_iph), &_inside_iph); + if (inside_iph == NULL) + return 1; + inside_nexthdr = inside_iph->nexthdr; + + inside_hdrlen = ipv6_skip_exthdr(skb, outside_hdrlen + sizeof(_icmph) + sizeof(_inside_iph), &inside_nexthdr); + if (inside_hdrlen < 0) + return 1; /* hjm: Packet has no/incomplete transport layer headers. */ + + if (inside_nexthdr != IPPROTO_TCP && + inside_nexthdr != IPPROTO_UDP) + return 1; + + ports = skb_header_pointer(skb, inside_hdrlen, + sizeof(_ports), &_ports); + if (ports == NULL) + return 1; + + /* the inside IP packet is the one quoted from our side, thus + * its saddr is the local address */ + *protocol = inside_nexthdr; + *laddr = &inside_iph->saddr; + *lport = ports[0]; + *raddr = &inside_iph->daddr; + *rport = ports[1]; + + return 0; +} + +static bool +socket_mt6_v1(const struct sk_buff *skb, struct xt_action_param *par) +{ + struct ipv6hdr *iph = ipv6_hdr(skb); + struct udphdr _hdr, *hp = NULL; + struct sock *sk; + struct in6_addr *daddr, *saddr; + __be16 dport, sport; + int thoff; + u8 tproto; + const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; + + tproto = ipv6_find_hdr(skb, &thoff, -1, NULL); + if (tproto < 0) { + pr_debug("unable to find transport header in IPv6 packet, dropping\n"); + return NF_DROP; + } + + if (tproto == IPPROTO_UDP || tproto == IPPROTO_TCP) { + hp = skb_header_pointer(skb, thoff, + sizeof(_hdr), &_hdr); + if (hp == NULL) + return false; + + saddr = &iph->saddr; + sport = hp->source; + daddr = &iph->daddr; + dport = hp->dest; + + } else if (tproto == IPPROTO_ICMPV6) { + if (extract_icmp6_fields(skb, thoff, &tproto, &saddr, &daddr, + &sport, &dport)) + return false; + } else { + return false; + } + + sk = nf_tproxy_get_sock_v6(dev_net(skb->dev), tproto, + saddr, daddr, sport, dport, par->in, NFT_LOOKUP_ANY); + if (sk != NULL) { + bool wildcard; + bool transparent = true; + + /* Ignore sockets listening on INADDR_ANY */ + wildcard = (sk->sk_state != TCP_TIME_WAIT && + ipv6_addr_any(&inet6_sk(sk)->rcv_saddr)); + + /* Ignore non-transparent sockets, + if XT_SOCKET_TRANSPARENT is used */ + if (info && info->flags & XT_SOCKET_TRANSPARENT) + transparent = ((sk->sk_state != TCP_TIME_WAIT && + inet_sk(sk)->transparent) || + (sk->sk_state == TCP_TIME_WAIT && + inet_twsk(sk)->tw_transparent)); + + nf_tproxy_put_sock(sk); + + if (wildcard || !transparent) + sk = NULL; + } + + pr_debug("proto %hhu %pI6:%hu -> %pI6:%hu " + "(orig %pI6:%hu) sock %p\n", + tproto, saddr, ntohs(sport), + daddr, ntohs(dport), + &iph->daddr, hp ? ntohs(hp->dest) : 0, sk); + + return (sk != NULL); +} +#endif + static struct xt_match socket_mt_reg[] __read_mostly = { { .name = "socket", .revision = 0, .family = NFPROTO_IPV4, - .match = socket_mt_v0, + .match = socket_mt4_v0, .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN), .me = THIS_MODULE, @@ -199,17 +325,33 @@ static struct xt_match socket_mt_reg[] __read_mostly = { .name = "socket", .revision = 1, .family = NFPROTO_IPV4, - .match = socket_mt_v1, + .match = socket_mt4_v1, .matchsize = sizeof(struct xt_socket_mtinfo1), .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN), .me = THIS_MODULE, }, +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + { + .name = "socket", + .revision = 1, + .family = NFPROTO_IPV6, + .match = socket_mt6_v1, + .matchsize = sizeof(struct xt_socket_mtinfo1), + .hooks = (1 << NF_INET_PRE_ROUTING) | + (1 << NF_INET_LOCAL_IN), + .me = THIS_MODULE, + }, +#endif }; static int __init socket_mt_init(void) { nf_defrag_ipv4_enable(); +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + nf_defrag_ipv6_enable(); +#endif + return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg)); } @@ -225,3 +367,4 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Krisztian Kovacs, Balazs Scheidler"); MODULE_DESCRIPTION("x_tables socket match module"); MODULE_ALIAS("ipt_socket"); +MODULE_ALIAS("ip6t_socket"); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 26ed3e8587c20f13a22c7aa2e2abf91dedf3d62a..1781d99145e2d2594fc961e1a2fc9307aad957a5 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -547,8 +547,20 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; info.attrs = family->attrbuf; genl_info_net_set(&info, net); + memset(&info.user_ptr, 0, sizeof(info.user_ptr)); - return ops->doit(skb, &info); + if (family->pre_doit) { + err = family->pre_doit(ops, skb, &info); + if (err) + return err; + } + + err = ops->doit(skb, &info); + + if (family->post_doit) + family->post_doit(ops, skb, &info); + + return err; } static void genl_rcv(struct sk_buff *skb) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9a17f28b1253cc2c96fc57a1b94cac4fa1621238..3616f27b9d46c08e0f750b47865cc17c3130c5f2 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -488,7 +488,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock, skb->dev = dev; skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); if (err < 0) goto out_unlock; @@ -1209,7 +1209,7 @@ static int packet_snd(struct socket *sock, err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len); if (err) goto out_free; - err = sock_tx_timestamp(msg, sk, skb_tx(skb)); + err = sock_tx_timestamp(sk, &skb_shinfo(skb)->tx_flags); if (err < 0) goto out_free; diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig index 6ec7d55b1769933f399af5f4673b95c2de83150c..0d9b8a220a7871a5bed180567a50036a1520d920 100644 --- a/net/phonet/Kconfig +++ b/net/phonet/Kconfig @@ -14,3 +14,15 @@ config PHONET To compile this driver as a module, choose M here: the module will be called phonet. If unsure, say N. + +config PHONET_PIPECTRLR + bool "Phonet Pipe Controller (EXPERIMENTAL)" + depends on PHONET && EXPERIMENTAL + default N + help + The Pipe Controller implementation in Phonet stack to support Pipe + data with Nokia Slim modems like WG2.5 used on ST-Ericsson U8500 + platform. + + This option is incompatible with older Nokia modems. + Say N here unless you really know what you are doing. diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c index 73aee7f2fcdccd56b77f19f818d95085b89e2843..fd95beb72f5de707f968f24954942827225a3029 100644 --- a/net/phonet/af_phonet.c +++ b/net/phonet/af_phonet.c @@ -251,6 +251,16 @@ int pn_skb_send(struct sock *sk, struct sk_buff *skb, else if (phonet_address_lookup(net, daddr) == 0) { dev = phonet_device_get(net); skb->pkt_type = PACKET_LOOPBACK; + } else if (pn_sockaddr_get_object(target) == 0) { + /* Resource routing (small race until phonet_rcv()) */ + struct sock *sk = pn_find_sock_by_res(net, + target->spn_resource); + if (sk) { + sock_put(sk); + dev = phonet_device_get(net); + skb->pkt_type = PACKET_LOOPBACK; + } else + dev = phonet_route_output(net, daddr); } else dev = phonet_route_output(net, daddr); @@ -383,6 +393,13 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev, goto out; } + /* resource routing */ + if (pn_sockaddr_get_object(&sa) == 0) { + struct sock *sk = pn_find_sock_by_res(net, sa.spn_resource); + if (sk) + return sk_receive_skb(sk, skb, 0); + } + /* check if we are the destination */ if (phonet_address_lookup(net, pn_sockaddr_get_addr(&sa)) == 0) { /* Phonet packet input */ diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c index 1bd38db4fe1e996df47396d43acd296e9811fa1b..2f032381bd4554226cd7d30a4bd104777caa5758 100644 --- a/net/phonet/datagram.c +++ b/net/phonet/datagram.c @@ -52,6 +52,19 @@ static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg) answ = skb ? skb->len : 0; release_sock(sk); return put_user(answ, (int __user *)arg); + + case SIOCPNADDRESOURCE: + case SIOCPNDELRESOURCE: { + u32 res; + if (get_user(res, (u32 __user *)arg)) + return -EFAULT; + if (res >= 256) + return -EINVAL; + if (cmd == SIOCPNADDRESOURCE) + return pn_sock_bind_res(sk, res); + else + return pn_sock_unbind_res(sk, res); + } } return -ENOIOCTLCMD; diff --git a/net/phonet/pep.c b/net/phonet/pep.c index 15003021f4f0a8706e540150425b4f995dc582a6..3e60f2e4e6c2d1e5982b2a56aed64fc38aa49259 100644 --- a/net/phonet/pep.c +++ b/net/phonet/pep.c @@ -109,6 +109,210 @@ static int pep_reply(struct sock *sk, struct sk_buff *oskb, } #define PAD 0x00 + +#ifdef CONFIG_PHONET_PIPECTRLR +static u8 pipe_negotiate_fc(u8 *host_fc, u8 *remote_fc, int len) +{ + int i, j; + u8 base_fc, final_fc; + + for (i = 0; i < len; i++) { + base_fc = host_fc[i]; + for (j = 0; j < len; j++) { + if (remote_fc[j] == base_fc) { + final_fc = base_fc; + goto done; + } + } + } + return -EINVAL; + +done: + return final_fc; + +} + +static int pipe_get_flow_info(struct sock *sk, struct sk_buff *skb, + u8 *pref_rx_fc, u8 *req_tx_fc) +{ + struct pnpipehdr *hdr; + u8 n_sb; + + if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) + return -EINVAL; + + hdr = pnp_hdr(skb); + n_sb = hdr->data[4]; + + __skb_pull(skb, sizeof(*hdr) + 4); + while (n_sb > 0) { + u8 type, buf[3], len = sizeof(buf); + u8 *data = pep_get_sb(skb, &type, &len, buf); + + if (data == NULL) + return -EINVAL; + + switch (type) { + case PN_PIPE_SB_REQUIRED_FC_TX: + if (len < 3 || (data[2] | data[3] | data[4]) > 3) + break; + req_tx_fc[0] = data[2]; + req_tx_fc[1] = data[3]; + req_tx_fc[2] = data[4]; + break; + + case PN_PIPE_SB_PREFERRED_FC_RX: + if (len < 3 || (data[2] | data[3] | data[4]) > 3) + break; + pref_rx_fc[0] = data[2]; + pref_rx_fc[1] = data[3]; + pref_rx_fc[2] = data[4]; + break; + + } + n_sb--; + } + return 0; +} + +static int pipe_handler_send_req(struct sock *sk, u8 utid, + u8 msg_id, gfp_t priority) +{ + int len; + struct pnpipehdr *ph; + struct sk_buff *skb; + struct pep_sock *pn = pep_sk(sk); + + static const u8 data[4] = { + PAD, PAD, PAD, PAD, + }; + + switch (msg_id) { + case PNS_PEP_CONNECT_REQ: + len = sizeof(data); + break; + + case PNS_PEP_DISCONNECT_REQ: + case PNS_PEP_ENABLE_REQ: + case PNS_PEP_DISABLE_REQ: + len = 0; + break; + + default: + return -EINVAL; + } + + skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority); + if (!skb) + return -ENOMEM; + skb_set_owner_w(skb, sk); + + skb_reserve(skb, MAX_PNPIPE_HEADER); + if (len) { + __skb_put(skb, len); + skb_copy_to_linear_data(skb, data, len); + } + __skb_push(skb, sizeof(*ph)); + skb_reset_transport_header(skb); + ph = pnp_hdr(skb); + ph->utid = utid; + ph->message_id = msg_id; + ph->pipe_handle = pn->pipe_handle; + ph->error_code = PN_PIPE_NO_ERROR; + + return pn_skb_send(sk, skb, &pn->remote_pep); +} + +static int pipe_handler_send_created_ind(struct sock *sk, + u8 utid, u8 msg_id) +{ + int err_code; + struct pnpipehdr *ph; + struct sk_buff *skb; + + struct pep_sock *pn = pep_sk(sk); + static u8 data[4] = { + 0x03, 0x04, + }; + data[2] = pn->tx_fc; + data[3] = pn->rx_fc; + + /* + * actually, below is number of sub-blocks and not error code. + * Pipe_created_ind message format does not have any + * error code field. However, the Phonet stack will always send + * an error code as part of pnpipehdr. So, use that err_code to + * specify the number of sub-blocks. + */ + err_code = 0x01; + + skb = alloc_skb(MAX_PNPIPE_HEADER + sizeof(data), GFP_ATOMIC); + if (!skb) + return -ENOMEM; + skb_set_owner_w(skb, sk); + + skb_reserve(skb, MAX_PNPIPE_HEADER); + __skb_put(skb, sizeof(data)); + skb_copy_to_linear_data(skb, data, sizeof(data)); + __skb_push(skb, sizeof(*ph)); + skb_reset_transport_header(skb); + ph = pnp_hdr(skb); + ph->utid = utid; + ph->message_id = msg_id; + ph->pipe_handle = pn->pipe_handle; + ph->error_code = err_code; + + return pn_skb_send(sk, skb, &pn->remote_pep); +} + +static int pipe_handler_send_ind(struct sock *sk, u8 utid, u8 msg_id) +{ + int err_code; + struct pnpipehdr *ph; + struct sk_buff *skb; + struct pep_sock *pn = pep_sk(sk); + + /* + * actually, below is a filler. + * Pipe_enabled/disabled_ind message format does not have any + * error code field. However, the Phonet stack will always send + * an error code as part of pnpipehdr. So, use that err_code to + * specify the filler value. + */ + err_code = 0x0; + + skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + skb_set_owner_w(skb, sk); + + skb_reserve(skb, MAX_PNPIPE_HEADER); + __skb_push(skb, sizeof(*ph)); + skb_reset_transport_header(skb); + ph = pnp_hdr(skb); + ph->utid = utid; + ph->message_id = msg_id; + ph->pipe_handle = pn->pipe_handle; + ph->error_code = err_code; + + return pn_skb_send(sk, skb, &pn->remote_pep); +} + +static int pipe_handler_enable_pipe(struct sock *sk, int enable) +{ + int utid, req; + + if (enable) { + utid = PNS_PIPE_ENABLE_UTID; + req = PNS_PEP_ENABLE_REQ; + } else { + utid = PNS_PIPE_DISABLE_UTID; + req = PNS_PEP_DISABLE_REQ; + } + return pipe_handler_send_req(sk, utid, req, GFP_ATOMIC); +} +#endif + static int pep_accept_conn(struct sock *sk, struct sk_buff *skb) { static const u8 data[20] = { @@ -192,7 +396,11 @@ static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority) ph->data[3] = PAD; ph->data[4] = status; +#ifdef CONFIG_PHONET_PIPECTRLR + return pn_skb_send(sk, skb, &pn->remote_pep); +#else return pn_skb_send(sk, skb, &pipe_srv); +#endif } /* Send our RX flow control information to the sender. @@ -324,11 +532,35 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) sk->sk_state_change(sk); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_DISCONNECT_RESP: + pn->pipe_state = PIPE_IDLE; + sk->sk_state = TCP_CLOSE; + break; +#endif + case PNS_PEP_ENABLE_REQ: /* Wait for PNS_PIPE_(ENABLED|REDIRECTED)_IND */ pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_ENABLE_RESP: + pn->pipe_state = PIPE_ENABLED; + pipe_handler_send_ind(sk, PNS_PIPE_ENABLED_IND_UTID, + PNS_PIPE_ENABLED_IND); + + if (!pn_flow_safe(pn->tx_fc)) { + atomic_set(&pn->tx_credits, 1); + sk->sk_write_space(sk); + } + if (sk->sk_state == TCP_ESTABLISHED) + break; /* Nothing to do */ + sk->sk_state = TCP_ESTABLISHED; + pipe_grant_credits(sk); + break; +#endif + case PNS_PEP_RESET_REQ: switch (hdr->state_after_reset) { case PN_PIPE_DISABLE: @@ -347,6 +579,17 @@ static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb) pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_DISABLE_RESP: + pn->pipe_state = PIPE_DISABLED; + atomic_set(&pn->tx_credits, 0); + pipe_handler_send_ind(sk, PNS_PIPE_DISABLED_IND_UTID, + PNS_PIPE_DISABLED_IND); + sk->sk_state = TCP_SYN_RECV; + pn->rx_credits = 0; + break; +#endif + case PNS_PEP_CTRL_REQ: if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX) { atomic_inc(&sk->sk_drops); @@ -438,6 +681,42 @@ static void pipe_destruct(struct sock *sk) skb_queue_purge(&pn->ctrlreq_queue); } +#ifdef CONFIG_PHONET_PIPECTRLR +static int pep_connresp_rcv(struct sock *sk, struct sk_buff *skb) +{ + struct pep_sock *pn = pep_sk(sk); + u8 host_pref_rx_fc[3] = {3, 2, 1}, host_req_tx_fc[3] = {3, 2, 1}; + u8 remote_pref_rx_fc[3], remote_req_tx_fc[3]; + u8 negotiated_rx_fc, negotiated_tx_fc; + int ret; + + pipe_get_flow_info(sk, skb, remote_pref_rx_fc, + remote_req_tx_fc); + negotiated_tx_fc = pipe_negotiate_fc(remote_req_tx_fc, + host_pref_rx_fc, + sizeof(host_pref_rx_fc)); + negotiated_rx_fc = pipe_negotiate_fc(host_req_tx_fc, + remote_pref_rx_fc, + sizeof(host_pref_rx_fc)); + + pn->pipe_state = PIPE_DISABLED; + sk->sk_state = TCP_SYN_RECV; + sk->sk_backlog_rcv = pipe_do_rcv; + sk->sk_destruct = pipe_destruct; + pn->rx_credits = 0; + pn->rx_fc = negotiated_rx_fc; + pn->tx_fc = negotiated_tx_fc; + sk->sk_state_change(sk); + + ret = pipe_handler_send_created_ind(sk, + PNS_PIPE_CREATED_IND_UTID, + PNS_PIPE_CREATED_IND + ); + + return ret; +} +#endif + static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb) { struct sock *newsk; @@ -601,6 +880,12 @@ static int pep_do_rcv(struct sock *sk, struct sk_buff *skb) err = pep_connreq_rcv(sk, skb); break; +#ifdef CONFIG_PHONET_PIPECTRLR + case PNS_PEP_CONNECT_RESP: + err = pep_connresp_rcv(sk, skb); + break; +#endif + case PNS_PEP_DISCONNECT_REQ: pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC); break; @@ -621,6 +906,28 @@ static int pep_do_rcv(struct sock *sk, struct sk_buff *skb) return err; } +static int pipe_do_remove(struct sock *sk) +{ + struct pep_sock *pn = pep_sk(sk); + struct pnpipehdr *ph; + struct sk_buff *skb; + + skb = alloc_skb(MAX_PNPIPE_HEADER, GFP_KERNEL); + if (!skb) + return -ENOMEM; + + skb_reserve(skb, MAX_PNPIPE_HEADER); + __skb_push(skb, sizeof(*ph)); + skb_reset_transport_header(skb); + ph = pnp_hdr(skb); + ph->utid = 0; + ph->message_id = PNS_PIPE_REMOVE_REQ; + ph->pipe_handle = pn->pipe_handle; + ph->data[0] = PAD; + + return pn_skb_send(sk, skb, &pipe_srv); +} + /* associated socket ceases to exist */ static void pep_sock_close(struct sock *sk, long timeout) { @@ -639,7 +946,22 @@ static void pep_sock_close(struct sock *sk, long timeout) sk_for_each_safe(sknode, p, n, &pn->ackq) sk_del_node_init(sknode); sk->sk_state = TCP_CLOSE; + } else if ((1 << sk->sk_state) & (TCPF_SYN_RECV|TCPF_ESTABLISHED)) + /* Forcefully remove dangling Phonet pipe */ + pipe_do_remove(sk); + +#ifdef CONFIG_PHONET_PIPECTRLR + if (pn->pipe_state != PIPE_IDLE) { + /* send pep disconnect request */ + pipe_handler_send_req(sk, + PNS_PEP_DISCONNECT_UTID, PNS_PEP_DISCONNECT_REQ, + GFP_KERNEL); + + pn->pipe_state = PIPE_IDLE; + sk->sk_state = TCP_CLOSE; } +#endif + ifindex = pn->ifindex; pn->ifindex = 0; release_sock(sk); @@ -716,6 +1038,20 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp) return newsk; } +#ifdef CONFIG_PHONET_PIPECTRLR +static int pep_sock_connect(struct sock *sk, struct sockaddr *addr, int len) +{ + struct pep_sock *pn = pep_sk(sk); + struct sockaddr_pn *spn = (struct sockaddr_pn *)addr; + + memcpy(&pn->remote_pep, spn, sizeof(struct sockaddr_pn)); + + return pipe_handler_send_req(sk, + PNS_PEP_CONNECT_UTID, PNS_PEP_CONNECT_REQ, + GFP_ATOMIC); +} +#endif + static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg) { struct pep_sock *pn = pep_sk(sk); @@ -767,6 +1103,18 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, lock_sock(sk); switch (optname) { +#ifdef CONFIG_PHONET_PIPECTRLR + case PNPIPE_PIPE_HANDLE: + if (val) { + if (pn->pipe_state > PIPE_IDLE) { + err = -EFAULT; + break; + } + pn->pipe_handle = val; + break; + } +#endif + case PNPIPE_ENCAP: if (val && val != PNPIPE_ENCAP_IP) { err = -EINVAL; @@ -792,6 +1140,17 @@ static int pep_setsockopt(struct sock *sk, int level, int optname, err = 0; } goto out_norel; + +#ifdef CONFIG_PHONET_PIPECTRLR + case PNPIPE_ENABLE: + if (pn->pipe_state <= PIPE_IDLE) { + err = -ENOTCONN; + break; + } + err = pipe_handler_enable_pipe(sk, val); + break; +#endif + default: err = -ENOPROTOOPT; } @@ -816,9 +1175,19 @@ static int pep_getsockopt(struct sock *sk, int level, int optname, case PNPIPE_ENCAP: val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE; break; + case PNPIPE_IFINDEX: val = pn->ifindex; break; + +#ifdef CONFIG_PHONET_PIPECTRLR + case PNPIPE_ENABLE: + if (pn->pipe_state <= PIPE_IDLE) + return -ENOTCONN; + val = pn->pipe_state != PIPE_DISABLED; + break; +#endif + default: return -ENOPROTOOPT; } @@ -835,6 +1204,7 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) { struct pep_sock *pn = pep_sk(sk); struct pnpipehdr *ph; + int err; if (pn_flow_safe(pn->tx_fc) && !atomic_add_unless(&pn->tx_credits, -1, 0)) { @@ -852,8 +1222,16 @@ static int pipe_skb_send(struct sock *sk, struct sk_buff *skb) } else ph->message_id = PNS_PIPE_DATA; ph->pipe_handle = pn->pipe_handle; +#ifdef CONFIG_PHONET_PIPECTRLR + err = pn_skb_send(sk, skb, &pn->remote_pep); +#else + err = pn_skb_send(sk, skb, &pipe_srv); +#endif + + if (err && pn_flow_safe(pn->tx_fc)) + atomic_inc(&pn->tx_credits); + return err; - return pn_skb_send(sk, skb, &pipe_srv); } static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, @@ -873,7 +1251,7 @@ static int pep_sendmsg(struct kiocb *iocb, struct sock *sk, skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len, flags & MSG_DONTWAIT, &err); if (!skb) - return -ENOBUFS; + return err; skb_reserve(skb, MAX_PHONET_HEADER + 3); err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); @@ -1045,6 +1423,8 @@ static void pep_sock_unhash(struct sock *sk) struct sock *skparent = NULL; lock_sock(sk); + +#ifndef CONFIG_PHONET_PIPECTRLR if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) { skparent = pn->listener; release_sock(sk); @@ -1054,6 +1434,7 @@ static void pep_sock_unhash(struct sock *sk) sk_del_node_init(sk); sk = skparent; } +#endif /* Unhash a listening sock only when it is closed * and all of its active connected pipes are closed. */ if (hlist_empty(&pn->hlist)) @@ -1067,6 +1448,9 @@ static void pep_sock_unhash(struct sock *sk) static struct proto pep_proto = { .close = pep_sock_close, .accept = pep_sock_accept, +#ifdef CONFIG_PHONET_PIPECTRLR + .connect = pep_sock_connect, +#endif .ioctl = pep_ioctl, .init = pep_init, .setsockopt = pep_setsockopt, diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index b18e48fae9759cf20d735031bc1f18a7e8857a11..947038ddd04cb0e0b763a5048d0bf553125a3914 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -292,8 +292,7 @@ static void phonet_route_autodel(struct net_device *dev) if (bitmap_empty(deleted, 64)) return; /* short-circuit RCU */ synchronize_rcu(); - for (i = find_first_bit(deleted, 64); i < 64; - i = find_next_bit(deleted, 64, i + 1)) { + for_each_set_bit(i, deleted, 64) { rtm_phonet_notify(RTM_DELROUTE, dev, i); dev_put(dev); } @@ -374,6 +373,7 @@ int __init phonet_device_init(void) if (err) return err; + proc_net_fops_create(&init_net, "pnresource", 0, &pn_res_seq_fops); register_netdevice_notifier(&phonet_device_notifier); err = phonet_netlink_register(); if (err) @@ -386,6 +386,7 @@ void phonet_device_exit(void) rtnl_unregister_all(PF_PHONET); unregister_netdevice_notifier(&phonet_device_notifier); unregister_pernet_device(&phonet_net_ops); + proc_net_remove(&init_net, "pnresource"); } int phonet_route_add(struct net_device *dev, u8 daddr) diff --git a/net/phonet/socket.c b/net/phonet/socket.c index 6e9848bf0370dff4a78827839a9a1057e52fb2b0..25f746d20c1f2dcbf42826cf33f07a35e44ace1c 100644 --- a/net/phonet/socket.c +++ b/net/phonet/socket.c @@ -158,6 +158,7 @@ void pn_sock_unhash(struct sock *sk) spin_lock_bh(&pnsocks.lock); sk_del_node_init(sk); spin_unlock_bh(&pnsocks.lock); + pn_sock_unbind_all_res(sk); } EXPORT_SYMBOL(pn_sock_unhash); @@ -224,6 +225,101 @@ static int pn_socket_autobind(struct socket *sock) return 0; /* socket was already bound */ } +#ifdef CONFIG_PHONET_PIPECTRLR +static int pn_socket_connect(struct socket *sock, struct sockaddr *addr, + int len, int flags) +{ + struct sock *sk = sock->sk; + struct sockaddr_pn *spn = (struct sockaddr_pn *)addr; + long timeo; + int err; + + if (len < sizeof(struct sockaddr_pn)) + return -EINVAL; + if (spn->spn_family != AF_PHONET) + return -EAFNOSUPPORT; + + lock_sock(sk); + + switch (sock->state) { + case SS_UNCONNECTED: + sk->sk_state = TCP_CLOSE; + break; + case SS_CONNECTING: + switch (sk->sk_state) { + case TCP_SYN_RECV: + sock->state = SS_CONNECTED; + err = -EISCONN; + goto out; + case TCP_CLOSE: + err = -EALREADY; + if (flags & O_NONBLOCK) + goto out; + goto wait_connect; + } + break; + case SS_CONNECTED: + switch (sk->sk_state) { + case TCP_SYN_RECV: + err = -EISCONN; + goto out; + case TCP_CLOSE: + sock->state = SS_UNCONNECTED; + break; + } + break; + case SS_DISCONNECTING: + case SS_FREE: + break; + } + sk->sk_state = TCP_CLOSE; + sk_stream_kill_queues(sk); + + sock->state = SS_CONNECTING; + err = sk->sk_prot->connect(sk, addr, len); + if (err < 0) { + sock->state = SS_UNCONNECTED; + sk->sk_state = TCP_CLOSE; + goto out; + } + + err = -EINPROGRESS; +wait_connect: + if (sk->sk_state != TCP_SYN_RECV && (flags & O_NONBLOCK)) + goto out; + + timeo = sock_sndtimeo(sk, flags & O_NONBLOCK); + release_sock(sk); + + err = -ERESTARTSYS; + timeo = wait_event_interruptible_timeout(*sk_sleep(sk), + sk->sk_state != TCP_CLOSE, + timeo); + + lock_sock(sk); + if (timeo < 0) + goto out; /* -ERESTARTSYS */ + + err = -ETIMEDOUT; + if (timeo == 0 && sk->sk_state != TCP_SYN_RECV) + goto out; + + if (sk->sk_state != TCP_SYN_RECV) { + sock->state = SS_UNCONNECTED; + err = sock_error(sk); + if (!err) + err = -ECONNREFUSED; + goto out; + } + sock->state = SS_CONNECTED; + err = 0; + +out: + release_sock(sk); + return err; +} +#endif + static int pn_socket_accept(struct socket *sock, struct socket *newsock, int flags) { @@ -281,7 +377,9 @@ static unsigned int pn_socket_poll(struct file *file, struct socket *sock, if (!mask && sk->sk_state == TCP_CLOSE_WAIT) return POLLHUP; - if (sk->sk_state == TCP_ESTABLISHED && atomic_read(&pn->tx_credits)) + if (sk->sk_state == TCP_ESTABLISHED && + atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf && + atomic_read(&pn->tx_credits)) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; return mask; @@ -390,7 +488,11 @@ const struct proto_ops phonet_stream_ops = { .owner = THIS_MODULE, .release = pn_socket_release, .bind = pn_socket_bind, +#ifdef CONFIG_PHONET_PIPECTRLR + .connect = pn_socket_connect, +#else .connect = sock_no_connect, +#endif .socketpair = sock_no_socketpair, .accept = pn_socket_accept, .getname = pn_socket_getname, @@ -563,3 +665,188 @@ const struct file_operations pn_sock_seq_fops = { .release = seq_release_net, }; #endif + +static struct { + struct sock *sk[256]; +} pnres; + +/* + * Find and hold socket based on resource. + */ +struct sock *pn_find_sock_by_res(struct net *net, u8 res) +{ + struct sock *sk; + + if (!net_eq(net, &init_net)) + return NULL; + + rcu_read_lock(); + sk = rcu_dereference(pnres.sk[res]); + if (sk) + sock_hold(sk); + rcu_read_unlock(); + return sk; +} + +static DEFINE_MUTEX(resource_mutex); + +int pn_sock_bind_res(struct sock *sk, u8 res) +{ + int ret = -EADDRINUSE; + + if (!net_eq(sock_net(sk), &init_net)) + return -ENOIOCTLCMD; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (pn_socket_autobind(sk->sk_socket)) + return -EAGAIN; + + mutex_lock(&resource_mutex); + if (pnres.sk[res] == NULL) { + sock_hold(sk); + rcu_assign_pointer(pnres.sk[res], sk); + ret = 0; + } + mutex_unlock(&resource_mutex); + return ret; +} + +int pn_sock_unbind_res(struct sock *sk, u8 res) +{ + int ret = -ENOENT; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + mutex_lock(&resource_mutex); + if (pnres.sk[res] == sk) { + rcu_assign_pointer(pnres.sk[res], NULL); + ret = 0; + } + mutex_unlock(&resource_mutex); + + if (ret == 0) { + synchronize_rcu(); + sock_put(sk); + } + return ret; +} + +void pn_sock_unbind_all_res(struct sock *sk) +{ + unsigned res, match = 0; + + mutex_lock(&resource_mutex); + for (res = 0; res < 256; res++) { + if (pnres.sk[res] == sk) { + rcu_assign_pointer(pnres.sk[res], NULL); + match++; + } + } + mutex_unlock(&resource_mutex); + + if (match == 0) + return; + synchronize_rcu(); + while (match > 0) { + sock_put(sk); + match--; + } +} + +#ifdef CONFIG_PROC_FS +static struct sock **pn_res_get_idx(struct seq_file *seq, loff_t pos) +{ + struct net *net = seq_file_net(seq); + unsigned i; + + if (!net_eq(net, &init_net)) + return NULL; + + for (i = 0; i < 256; i++) { + if (pnres.sk[i] == NULL) + continue; + if (!pos) + return pnres.sk + i; + pos--; + } + return NULL; +} + +static struct sock **pn_res_get_next(struct seq_file *seq, struct sock **sk) +{ + struct net *net = seq_file_net(seq); + unsigned i; + + BUG_ON(!net_eq(net, &init_net)); + + for (i = (sk - pnres.sk) + 1; i < 256; i++) + if (pnres.sk[i]) + return pnres.sk + i; + return NULL; +} + +static void *pn_res_seq_start(struct seq_file *seq, loff_t *pos) + __acquires(resource_mutex) +{ + mutex_lock(&resource_mutex); + return *pos ? pn_res_get_idx(seq, *pos - 1) : SEQ_START_TOKEN; +} + +static void *pn_res_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + struct sock **sk; + + if (v == SEQ_START_TOKEN) + sk = pn_res_get_idx(seq, 0); + else + sk = pn_res_get_next(seq, v); + (*pos)++; + return sk; +} + +static void pn_res_seq_stop(struct seq_file *seq, void *v) + __releases(resource_mutex) +{ + mutex_unlock(&resource_mutex); +} + +static int pn_res_seq_show(struct seq_file *seq, void *v) +{ + int len; + + if (v == SEQ_START_TOKEN) + seq_printf(seq, "%s%n", "rs uid inode", &len); + else { + struct sock **psk = v; + struct sock *sk = *psk; + + seq_printf(seq, "%02X %5d %lu%n", + (int) (psk - pnres.sk), sock_i_uid(sk), + sock_i_ino(sk), &len); + } + seq_printf(seq, "%*s\n", 63 - len, ""); + return 0; +} + +static const struct seq_operations pn_res_seq_ops = { + .start = pn_res_seq_start, + .next = pn_res_seq_next, + .stop = pn_res_seq_stop, + .show = pn_res_seq_show, +}; + +static int pn_res_open(struct inode *inode, struct file *file) +{ + return seq_open_net(inode, file, &pn_res_seq_ops, + sizeof(struct seq_net_private)); +} + +const struct file_operations pn_res_seq_fops = { + .owner = THIS_MODULE, + .open = pn_res_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_net, +}; +#endif diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index aebfecbdb8417cfa3bd3196e2c22f18433a7b08b..bb6ad81b671d055b89fbe74287ed328a834aac03 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c @@ -39,7 +39,15 @@ #include #include "rds.h" -#include "rdma.h" + +char *rds_str_array(char **array, size_t elements, size_t index) +{ + if ((index < elements) && array[index]) + return array[index]; + else + return "unknown"; +} +EXPORT_SYMBOL(rds_str_array); /* this is just used for stats gathering :/ */ static DEFINE_SPINLOCK(rds_sock_lock); @@ -62,7 +70,7 @@ static int rds_release(struct socket *sock) struct rds_sock *rs; unsigned long flags; - if (sk == NULL) + if (!sk) goto out; rs = rds_sk_to_rs(sk); @@ -73,7 +81,15 @@ static int rds_release(struct socket *sock) * with the socket. */ rds_clear_recv_queue(rs); rds_cong_remove_socket(rs); + + /* + * the binding lookup hash uses rcu, we need to + * make sure we sychronize_rcu before we free our + * entry + */ rds_remove_bound(rs); + synchronize_rcu(); + rds_send_drop_to(rs, NULL); rds_rdma_drop_keys(rs); rds_notify_queue_get(rs, NULL); @@ -83,6 +99,8 @@ static int rds_release(struct socket *sock) rds_sock_count--; spin_unlock_irqrestore(&rds_sock_lock, flags); + rds_trans_put(rs->rs_transport); + sock->sk = NULL; sock_put(sk); out: @@ -514,7 +532,7 @@ static void rds_sock_info(struct socket *sock, unsigned int len, spin_unlock_irqrestore(&rds_sock_lock, flags); } -static void __exit rds_exit(void) +static void rds_exit(void) { sock_unregister(rds_family_ops.family); proto_unregister(&rds_proto); @@ -529,7 +547,7 @@ static void __exit rds_exit(void) } module_exit(rds_exit); -static int __init rds_init(void) +static int rds_init(void) { int ret; diff --git a/net/rds/bind.c b/net/rds/bind.c index 5d95fc007f1aa6244d500561ccc0324063cda221..2f6b3fcc79f81b9985ca5774a7fa3e070a105d11 100644 --- a/net/rds/bind.c +++ b/net/rds/bind.c @@ -34,45 +34,52 @@ #include #include #include +#include #include "rds.h" -/* - * XXX this probably still needs more work.. no INADDR_ANY, and rbtrees aren't - * particularly zippy. - * - * This is now called for every incoming frame so we arguably care much more - * about it than we used to. - */ +#define BIND_HASH_SIZE 1024 +static struct hlist_head bind_hash_table[BIND_HASH_SIZE]; static DEFINE_SPINLOCK(rds_bind_lock); -static struct rb_root rds_bind_tree = RB_ROOT; -static struct rds_sock *rds_bind_tree_walk(__be32 addr, __be16 port, - struct rds_sock *insert) +static struct hlist_head *hash_to_bucket(__be32 addr, __be16 port) +{ + return bind_hash_table + (jhash_2words((u32)addr, (u32)port, 0) & + (BIND_HASH_SIZE - 1)); +} + +static struct rds_sock *rds_bind_lookup(__be32 addr, __be16 port, + struct rds_sock *insert) { - struct rb_node **p = &rds_bind_tree.rb_node; - struct rb_node *parent = NULL; struct rds_sock *rs; + struct hlist_node *node; + struct hlist_head *head = hash_to_bucket(addr, port); u64 cmp; u64 needle = ((u64)be32_to_cpu(addr) << 32) | be16_to_cpu(port); - while (*p) { - parent = *p; - rs = rb_entry(parent, struct rds_sock, rs_bound_node); - + rcu_read_lock(); + hlist_for_each_entry_rcu(rs, node, head, rs_bound_node) { cmp = ((u64)be32_to_cpu(rs->rs_bound_addr) << 32) | be16_to_cpu(rs->rs_bound_port); - if (needle < cmp) - p = &(*p)->rb_left; - else if (needle > cmp) - p = &(*p)->rb_right; - else + if (cmp == needle) { + rcu_read_unlock(); return rs; + } } + rcu_read_unlock(); if (insert) { - rb_link_node(&insert->rs_bound_node, parent, p); - rb_insert_color(&insert->rs_bound_node, &rds_bind_tree); + /* + * make sure our addr and port are set before + * we are added to the list, other people + * in rcu will find us as soon as the + * hlist_add_head_rcu is done + */ + insert->rs_bound_addr = addr; + insert->rs_bound_port = port; + rds_sock_addref(insert); + + hlist_add_head_rcu(&insert->rs_bound_node, head); } return NULL; } @@ -86,15 +93,13 @@ static struct rds_sock *rds_bind_tree_walk(__be32 addr, __be16 port, struct rds_sock *rds_find_bound(__be32 addr, __be16 port) { struct rds_sock *rs; - unsigned long flags; - spin_lock_irqsave(&rds_bind_lock, flags); - rs = rds_bind_tree_walk(addr, port, NULL); + rs = rds_bind_lookup(addr, port, NULL); + if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD)) rds_sock_addref(rs); else rs = NULL; - spin_unlock_irqrestore(&rds_bind_lock, flags); rdsdebug("returning rs %p for %pI4:%u\n", rs, &addr, ntohs(port)); @@ -121,22 +126,15 @@ static int rds_add_bound(struct rds_sock *rs, __be32 addr, __be16 *port) do { if (rover == 0) rover++; - if (rds_bind_tree_walk(addr, cpu_to_be16(rover), rs) == NULL) { - *port = cpu_to_be16(rover); + if (!rds_bind_lookup(addr, cpu_to_be16(rover), rs)) { + *port = rs->rs_bound_port; ret = 0; + rdsdebug("rs %p binding to %pI4:%d\n", + rs, &addr, (int)ntohs(*port)); break; } } while (rover++ != last); - if (ret == 0) { - rs->rs_bound_addr = addr; - rs->rs_bound_port = *port; - rds_sock_addref(rs); - - rdsdebug("rs %p binding to %pI4:%d\n", - rs, &addr, (int)ntohs(*port)); - } - spin_unlock_irqrestore(&rds_bind_lock, flags); return ret; @@ -153,7 +151,7 @@ void rds_remove_bound(struct rds_sock *rs) rs, &rs->rs_bound_addr, ntohs(rs->rs_bound_port)); - rb_erase(&rs->rs_bound_node, &rds_bind_tree); + hlist_del_init_rcu(&rs->rs_bound_node); rds_sock_put(rs); rs->rs_bound_addr = 0; } @@ -184,7 +182,7 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) goto out; trans = rds_trans_get_preferred(sin->sin_addr.s_addr); - if (trans == NULL) { + if (!trans) { ret = -EADDRNOTAVAIL; rds_remove_bound(rs); if (printk_ratelimit()) @@ -198,5 +196,9 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) out: release_sock(sk); + + /* we might have called rds_remove_bound on error */ + if (ret) + synchronize_rcu(); return ret; } diff --git a/net/rds/cong.c b/net/rds/cong.c index 0871a29f078000ee79370fd20e6d94ca46ba3efd..75ea686f27d5aeedfd220dfbfa514295d6cc8ecc 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c @@ -141,7 +141,7 @@ static struct rds_cong_map *rds_cong_from_addr(__be32 addr) unsigned long flags; map = kzalloc(sizeof(struct rds_cong_map), GFP_KERNEL); - if (map == NULL) + if (!map) return NULL; map->m_addr = addr; @@ -159,7 +159,7 @@ static struct rds_cong_map *rds_cong_from_addr(__be32 addr) ret = rds_cong_tree_walk(addr, map); spin_unlock_irqrestore(&rds_cong_lock, flags); - if (ret == NULL) { + if (!ret) { ret = map; map = NULL; } @@ -205,7 +205,7 @@ int rds_cong_get_maps(struct rds_connection *conn) conn->c_lcong = rds_cong_from_addr(conn->c_laddr); conn->c_fcong = rds_cong_from_addr(conn->c_faddr); - if (conn->c_lcong == NULL || conn->c_fcong == NULL) + if (!(conn->c_lcong && conn->c_fcong)) return -ENOMEM; return 0; @@ -221,7 +221,7 @@ void rds_cong_queue_updates(struct rds_cong_map *map) list_for_each_entry(conn, &map->m_conn_list, c_map_item) { if (!test_and_set_bit(0, &conn->c_map_queued)) { rds_stats_inc(s_cong_update_queued); - queue_delayed_work(rds_wq, &conn->c_send_w, 0); + rds_send_xmit(conn); } } diff --git a/net/rds/connection.c b/net/rds/connection.c index 7619b671ca2829f0e197a93f6abd06df2f108229..9334d892366ebb16091bd18fbdaacc9697eabb2a 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -37,7 +37,6 @@ #include "rds.h" #include "loop.h" -#include "rdma.h" #define RDS_CONNECTION_HASH_BITS 12 #define RDS_CONNECTION_HASH_ENTRIES (1 << RDS_CONNECTION_HASH_BITS) @@ -63,18 +62,7 @@ static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) var |= RDS_INFO_CONNECTION_FLAG_##suffix; \ } while (0) -static inline int rds_conn_is_sending(struct rds_connection *conn) -{ - int ret = 0; - - if (!mutex_trylock(&conn->c_send_lock)) - ret = 1; - else - mutex_unlock(&conn->c_send_lock); - - return ret; -} - +/* rcu read lock must be held or the connection spinlock */ static struct rds_connection *rds_conn_lookup(struct hlist_head *head, __be32 laddr, __be32 faddr, struct rds_transport *trans) @@ -82,7 +70,7 @@ static struct rds_connection *rds_conn_lookup(struct hlist_head *head, struct rds_connection *conn, *ret = NULL; struct hlist_node *pos; - hlist_for_each_entry(conn, pos, head, c_hash_node) { + hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) { if (conn->c_faddr == faddr && conn->c_laddr == laddr && conn->c_trans == trans) { ret = conn; @@ -100,7 +88,7 @@ static struct rds_connection *rds_conn_lookup(struct hlist_head *head, * and receiving over this connection again in the future. It is up to * the transport to have serialized this call with its send and recv. */ -void rds_conn_reset(struct rds_connection *conn) +static void rds_conn_reset(struct rds_connection *conn) { rdsdebug("connection %pI4 to %pI4 reset\n", &conn->c_laddr, &conn->c_faddr); @@ -129,10 +117,11 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, { struct rds_connection *conn, *parent = NULL; struct hlist_head *head = rds_conn_bucket(laddr, faddr); + struct rds_transport *loop_trans; unsigned long flags; int ret; - spin_lock_irqsave(&rds_conn_lock, flags); + rcu_read_lock(); conn = rds_conn_lookup(head, laddr, faddr, trans); if (conn && conn->c_loopback && conn->c_trans != &rds_loop_transport && !is_outgoing) { @@ -143,12 +132,12 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, parent = conn; conn = parent->c_passive; } - spin_unlock_irqrestore(&rds_conn_lock, flags); + rcu_read_unlock(); if (conn) goto out; conn = kmem_cache_zalloc(rds_conn_slab, gfp); - if (conn == NULL) { + if (!conn) { conn = ERR_PTR(-ENOMEM); goto out; } @@ -159,7 +148,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, spin_lock_init(&conn->c_lock); conn->c_next_tx_seq = 1; - mutex_init(&conn->c_send_lock); + init_waitqueue_head(&conn->c_waitq); INIT_LIST_HEAD(&conn->c_send_queue); INIT_LIST_HEAD(&conn->c_retrans); @@ -175,7 +164,9 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, * can bind to the destination address then we'd rather the messages * flow through loopback rather than either transport. */ - if (rds_trans_get_preferred(faddr)) { + loop_trans = rds_trans_get_preferred(faddr); + if (loop_trans) { + rds_trans_put(loop_trans); conn->c_loopback = 1; if (is_outgoing && trans->t_prefer_loopback) { /* "outgoing" connection - and the transport @@ -238,7 +229,7 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr, kmem_cache_free(rds_conn_slab, conn); conn = found; } else { - hlist_add_head(&conn->c_hash_node, head); + hlist_add_head_rcu(&conn->c_hash_node, head); rds_cong_add_conn(conn); rds_conn_count++; } @@ -263,21 +254,91 @@ struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr, } EXPORT_SYMBOL_GPL(rds_conn_create_outgoing); +void rds_conn_shutdown(struct rds_connection *conn) +{ + /* shut it down unless it's down already */ + if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) { + /* + * Quiesce the connection mgmt handlers before we start tearing + * things down. We don't hold the mutex for the entire + * duration of the shutdown operation, else we may be + * deadlocking with the CM handler. Instead, the CM event + * handler is supposed to check for state DISCONNECTING + */ + mutex_lock(&conn->c_cm_lock); + if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) + && !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) { + rds_conn_error(conn, "shutdown called in state %d\n", + atomic_read(&conn->c_state)); + mutex_unlock(&conn->c_cm_lock); + return; + } + mutex_unlock(&conn->c_cm_lock); + + wait_event(conn->c_waitq, + !test_bit(RDS_IN_XMIT, &conn->c_flags)); + + conn->c_trans->conn_shutdown(conn); + rds_conn_reset(conn); + + if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) { + /* This can happen - eg when we're in the middle of tearing + * down the connection, and someone unloads the rds module. + * Quite reproduceable with loopback connections. + * Mostly harmless. + */ + rds_conn_error(conn, + "%s: failed to transition to state DOWN, " + "current state is %d\n", + __func__, + atomic_read(&conn->c_state)); + return; + } + } + + /* Then reconnect if it's still live. + * The passive side of an IB loopback connection is never added + * to the conn hash, so we never trigger a reconnect on this + * conn - the reconnect is always triggered by the active peer. */ + cancel_delayed_work_sync(&conn->c_conn_w); + rcu_read_lock(); + if (!hlist_unhashed(&conn->c_hash_node)) { + rcu_read_unlock(); + rds_queue_reconnect(conn); + } else { + rcu_read_unlock(); + } +} + +/* + * Stop and free a connection. + * + * This can only be used in very limited circumstances. It assumes that once + * the conn has been shutdown that no one else is referencing the connection. + * We can only ensure this in the rmmod path in the current code. + */ void rds_conn_destroy(struct rds_connection *conn) { struct rds_message *rm, *rtmp; + unsigned long flags; rdsdebug("freeing conn %p for %pI4 -> " "%pI4\n", conn, &conn->c_laddr, &conn->c_faddr); - hlist_del_init(&conn->c_hash_node); + /* Ensure conn will not be scheduled for reconnect */ + spin_lock_irq(&rds_conn_lock); + hlist_del_init_rcu(&conn->c_hash_node); + spin_unlock_irq(&rds_conn_lock); + synchronize_rcu(); - /* wait for the rds thread to shut it down */ - atomic_set(&conn->c_state, RDS_CONN_ERROR); - cancel_delayed_work(&conn->c_conn_w); - queue_work(rds_wq, &conn->c_down_w); - flush_workqueue(rds_wq); + /* shut the connection down */ + rds_conn_drop(conn); + flush_work(&conn->c_down_w); + + /* make sure lingering queued work won't try to ref the conn */ + cancel_delayed_work_sync(&conn->c_send_w); + cancel_delayed_work_sync(&conn->c_recv_w); /* tear down queued messages */ list_for_each_entry_safe(rm, rtmp, @@ -302,7 +363,9 @@ void rds_conn_destroy(struct rds_connection *conn) BUG_ON(!list_empty(&conn->c_retrans)); kmem_cache_free(rds_conn_slab, conn); + spin_lock_irqsave(&rds_conn_lock, flags); rds_conn_count--; + spin_unlock_irqrestore(&rds_conn_lock, flags); } EXPORT_SYMBOL_GPL(rds_conn_destroy); @@ -316,23 +379,23 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, struct list_head *list; struct rds_connection *conn; struct rds_message *rm; - unsigned long flags; unsigned int total = 0; + unsigned long flags; size_t i; len /= sizeof(struct rds_info_message); - spin_lock_irqsave(&rds_conn_lock, flags); + rcu_read_lock(); for (i = 0, head = rds_conn_hash; i < ARRAY_SIZE(rds_conn_hash); i++, head++) { - hlist_for_each_entry(conn, pos, head, c_hash_node) { + hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) { if (want_send) list = &conn->c_send_queue; else list = &conn->c_retrans; - spin_lock(&conn->c_lock); + spin_lock_irqsave(&conn->c_lock, flags); /* XXX too lazy to maintain counts.. */ list_for_each_entry(rm, list, m_conn_item) { @@ -343,11 +406,10 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len, conn->c_faddr, 0); } - spin_unlock(&conn->c_lock); + spin_unlock_irqrestore(&conn->c_lock, flags); } } - - spin_unlock_irqrestore(&rds_conn_lock, flags); + rcu_read_unlock(); lens->nr = total; lens->each = sizeof(struct rds_info_message); @@ -377,19 +439,17 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len, uint64_t buffer[(item_len + 7) / 8]; struct hlist_head *head; struct hlist_node *pos; - struct hlist_node *tmp; struct rds_connection *conn; - unsigned long flags; size_t i; - spin_lock_irqsave(&rds_conn_lock, flags); + rcu_read_lock(); lens->nr = 0; lens->each = item_len; for (i = 0, head = rds_conn_hash; i < ARRAY_SIZE(rds_conn_hash); i++, head++) { - hlist_for_each_entry_safe(conn, pos, tmp, head, c_hash_node) { + hlist_for_each_entry_rcu(conn, pos, head, c_hash_node) { /* XXX no c_lock usage.. */ if (!visitor(conn, buffer)) @@ -405,8 +465,7 @@ void rds_for_each_conn_info(struct socket *sock, unsigned int len, lens->nr++; } } - - spin_unlock_irqrestore(&rds_conn_lock, flags); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(rds_for_each_conn_info); @@ -423,8 +482,8 @@ static int rds_conn_info_visitor(struct rds_connection *conn, sizeof(cinfo->transport)); cinfo->flags = 0; - rds_conn_info_set(cinfo->flags, - rds_conn_is_sending(conn), SENDING); + rds_conn_info_set(cinfo->flags, test_bit(RDS_IN_XMIT, &conn->c_flags), + SENDING); /* XXX Future: return the state rather than these funky bits */ rds_conn_info_set(cinfo->flags, atomic_read(&conn->c_state) == RDS_CONN_CONNECTING, @@ -444,12 +503,12 @@ static void rds_conn_info(struct socket *sock, unsigned int len, sizeof(struct rds_info_connection)); } -int __init rds_conn_init(void) +int rds_conn_init(void) { rds_conn_slab = kmem_cache_create("rds_connection", sizeof(struct rds_connection), 0, 0, NULL); - if (rds_conn_slab == NULL) + if (!rds_conn_slab) return -ENOMEM; rds_info_register_func(RDS_INFO_CONNECTIONS, rds_conn_info); @@ -486,6 +545,18 @@ void rds_conn_drop(struct rds_connection *conn) } EXPORT_SYMBOL_GPL(rds_conn_drop); +/* + * If the connection is down, trigger a connect. We may have scheduled a + * delayed reconnect however - in this case we should not interfere. + */ +void rds_conn_connect_if_down(struct rds_connection *conn) +{ + if (rds_conn_state(conn) == RDS_CONN_DOWN && + !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) + queue_delayed_work(rds_wq, &conn->c_conn_w, 0); +} +EXPORT_SYMBOL_GPL(rds_conn_connect_if_down); + /* * An error occurred on the connection */ diff --git a/net/rds/ib.c b/net/rds/ib.c index 8f2d6dd7700a8a0e20192b521c30dc7bc2df553b..4123967d4d651e77e4ca59cf1794fcff207d4847 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -42,7 +42,7 @@ #include "rds.h" #include "ib.h" -unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE; +static unsigned int fmr_pool_size = RDS_FMR_POOL_SIZE; unsigned int fmr_message_size = RDS_FMR_SIZE + 1; /* +1 allows for unaligned MRs */ unsigned int rds_ib_retry_count = RDS_IB_DEFAULT_RETRY_COUNT; @@ -53,13 +53,72 @@ MODULE_PARM_DESC(fmr_message_size, " Max size of a RDMA transfer"); module_param(rds_ib_retry_count, int, 0444); MODULE_PARM_DESC(rds_ib_retry_count, " Number of hw retries before reporting an error"); +/* + * we have a clumsy combination of RCU and a rwsem protecting this list + * because it is used both in the get_mr fast path and while blocking in + * the FMR flushing path. + */ +DECLARE_RWSEM(rds_ib_devices_lock); struct list_head rds_ib_devices; /* NOTE: if also grabbing ibdev lock, grab this first */ DEFINE_SPINLOCK(ib_nodev_conns_lock); LIST_HEAD(ib_nodev_conns); -void rds_ib_add_one(struct ib_device *device) +static void rds_ib_nodev_connect(void) +{ + struct rds_ib_connection *ic; + + spin_lock(&ib_nodev_conns_lock); + list_for_each_entry(ic, &ib_nodev_conns, ib_node) + rds_conn_connect_if_down(ic->conn); + spin_unlock(&ib_nodev_conns_lock); +} + +static void rds_ib_dev_shutdown(struct rds_ib_device *rds_ibdev) +{ + struct rds_ib_connection *ic; + unsigned long flags; + + spin_lock_irqsave(&rds_ibdev->spinlock, flags); + list_for_each_entry(ic, &rds_ibdev->conn_list, ib_node) + rds_conn_drop(ic->conn); + spin_unlock_irqrestore(&rds_ibdev->spinlock, flags); +} + +/* + * rds_ib_destroy_mr_pool() blocks on a few things and mrs drop references + * from interrupt context so we push freing off into a work struct in krdsd. + */ +static void rds_ib_dev_free(struct work_struct *work) +{ + struct rds_ib_ipaddr *i_ipaddr, *i_next; + struct rds_ib_device *rds_ibdev = container_of(work, + struct rds_ib_device, free_work); + + if (rds_ibdev->mr_pool) + rds_ib_destroy_mr_pool(rds_ibdev->mr_pool); + if (rds_ibdev->mr) + ib_dereg_mr(rds_ibdev->mr); + if (rds_ibdev->pd) + ib_dealloc_pd(rds_ibdev->pd); + + list_for_each_entry_safe(i_ipaddr, i_next, &rds_ibdev->ipaddr_list, list) { + list_del(&i_ipaddr->list); + kfree(i_ipaddr); + } + + kfree(rds_ibdev); +} + +void rds_ib_dev_put(struct rds_ib_device *rds_ibdev) +{ + BUG_ON(atomic_read(&rds_ibdev->refcount) <= 0); + if (atomic_dec_and_test(&rds_ibdev->refcount)) + queue_work(rds_wq, &rds_ibdev->free_work); +} + +static void rds_ib_add_one(struct ib_device *device) { struct rds_ib_device *rds_ibdev; struct ib_device_attr *dev_attr; @@ -77,11 +136,14 @@ void rds_ib_add_one(struct ib_device *device) goto free_attr; } - rds_ibdev = kmalloc(sizeof *rds_ibdev, GFP_KERNEL); + rds_ibdev = kzalloc_node(sizeof(struct rds_ib_device), GFP_KERNEL, + ibdev_to_node(device)); if (!rds_ibdev) goto free_attr; spin_lock_init(&rds_ibdev->spinlock); + atomic_set(&rds_ibdev->refcount, 1); + INIT_WORK(&rds_ibdev->free_work, rds_ib_dev_free); rds_ibdev->max_wrs = dev_attr->max_qp_wr; rds_ibdev->max_sge = min(dev_attr->max_sge, RDS_IB_MAX_SGE); @@ -91,68 +153,107 @@ void rds_ib_add_one(struct ib_device *device) min_t(unsigned int, dev_attr->max_fmr, fmr_pool_size) : fmr_pool_size; + rds_ibdev->max_initiator_depth = dev_attr->max_qp_init_rd_atom; + rds_ibdev->max_responder_resources = dev_attr->max_qp_rd_atom; + rds_ibdev->dev = device; rds_ibdev->pd = ib_alloc_pd(device); - if (IS_ERR(rds_ibdev->pd)) - goto free_dev; + if (IS_ERR(rds_ibdev->pd)) { + rds_ibdev->pd = NULL; + goto put_dev; + } - rds_ibdev->mr = ib_get_dma_mr(rds_ibdev->pd, - IB_ACCESS_LOCAL_WRITE); - if (IS_ERR(rds_ibdev->mr)) - goto err_pd; + rds_ibdev->mr = ib_get_dma_mr(rds_ibdev->pd, IB_ACCESS_LOCAL_WRITE); + if (IS_ERR(rds_ibdev->mr)) { + rds_ibdev->mr = NULL; + goto put_dev; + } rds_ibdev->mr_pool = rds_ib_create_mr_pool(rds_ibdev); if (IS_ERR(rds_ibdev->mr_pool)) { rds_ibdev->mr_pool = NULL; - goto err_mr; + goto put_dev; } INIT_LIST_HEAD(&rds_ibdev->ipaddr_list); INIT_LIST_HEAD(&rds_ibdev->conn_list); - list_add_tail(&rds_ibdev->list, &rds_ib_devices); + + down_write(&rds_ib_devices_lock); + list_add_tail_rcu(&rds_ibdev->list, &rds_ib_devices); + up_write(&rds_ib_devices_lock); + atomic_inc(&rds_ibdev->refcount); ib_set_client_data(device, &rds_ib_client, rds_ibdev); + atomic_inc(&rds_ibdev->refcount); - goto free_attr; + rds_ib_nodev_connect(); -err_mr: - ib_dereg_mr(rds_ibdev->mr); -err_pd: - ib_dealloc_pd(rds_ibdev->pd); -free_dev: - kfree(rds_ibdev); +put_dev: + rds_ib_dev_put(rds_ibdev); free_attr: kfree(dev_attr); } -void rds_ib_remove_one(struct ib_device *device) +/* + * New connections use this to find the device to associate with the + * connection. It's not in the fast path so we're not concerned about the + * performance of the IB call. (As of this writing, it uses an interrupt + * blocking spinlock to serialize walking a per-device list of all registered + * clients.) + * + * RCU is used to handle incoming connections racing with device teardown. + * Rather than use a lock to serialize removal from the client_data and + * getting a new reference, we use an RCU grace period. The destruction + * path removes the device from client_data and then waits for all RCU + * readers to finish. + * + * A new connection can get NULL from this if its arriving on a + * device that is in the process of being removed. + */ +struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device) { struct rds_ib_device *rds_ibdev; - struct rds_ib_ipaddr *i_ipaddr, *i_next; + rcu_read_lock(); rds_ibdev = ib_get_client_data(device, &rds_ib_client); - if (!rds_ibdev) - return; + if (rds_ibdev) + atomic_inc(&rds_ibdev->refcount); + rcu_read_unlock(); + return rds_ibdev; +} - list_for_each_entry_safe(i_ipaddr, i_next, &rds_ibdev->ipaddr_list, list) { - list_del(&i_ipaddr->list); - kfree(i_ipaddr); - } +/* + * The IB stack is letting us know that a device is going away. This can + * happen if the underlying HCA driver is removed or if PCI hotplug is removing + * the pci function, for example. + * + * This can be called at any time and can be racing with any other RDS path. + */ +static void rds_ib_remove_one(struct ib_device *device) +{ + struct rds_ib_device *rds_ibdev; - rds_ib_destroy_conns(rds_ibdev); + rds_ibdev = ib_get_client_data(device, &rds_ib_client); + if (!rds_ibdev) + return; - if (rds_ibdev->mr_pool) - rds_ib_destroy_mr_pool(rds_ibdev->mr_pool); + rds_ib_dev_shutdown(rds_ibdev); - ib_dereg_mr(rds_ibdev->mr); + /* stop connection attempts from getting a reference to this device. */ + ib_set_client_data(device, &rds_ib_client, NULL); - while (ib_dealloc_pd(rds_ibdev->pd)) { - rdsdebug("Failed to dealloc pd %p\n", rds_ibdev->pd); - msleep(1); - } + down_write(&rds_ib_devices_lock); + list_del_rcu(&rds_ibdev->list); + up_write(&rds_ib_devices_lock); - list_del(&rds_ibdev->list); - kfree(rds_ibdev); + /* + * This synchronize rcu is waiting for readers of both the ib + * client data and the devices list to finish before we drop + * both of those references. + */ + synchronize_rcu(); + rds_ib_dev_put(rds_ibdev); + rds_ib_dev_put(rds_ibdev); } struct ib_client rds_ib_client = { @@ -186,7 +287,7 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn, rdma_addr_get_sgid(dev_addr, (union ib_gid *) &iinfo->src_gid); rdma_addr_get_dgid(dev_addr, (union ib_gid *) &iinfo->dst_gid); - rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); + rds_ibdev = ic->rds_ibdev; iinfo->max_send_wr = ic->i_send_ring.w_nr; iinfo->max_recv_wr = ic->i_recv_ring.w_nr; iinfo->max_send_sge = rds_ibdev->max_sge; @@ -248,29 +349,36 @@ static int rds_ib_laddr_check(__be32 addr) return ret; } +static void rds_ib_unregister_client(void) +{ + ib_unregister_client(&rds_ib_client); + /* wait for rds_ib_dev_free() to complete */ + flush_workqueue(rds_wq); +} + void rds_ib_exit(void) { rds_info_deregister_func(RDS_INFO_IB_CONNECTIONS, rds_ib_ic_info); + rds_ib_unregister_client(); rds_ib_destroy_nodev_conns(); - ib_unregister_client(&rds_ib_client); rds_ib_sysctl_exit(); rds_ib_recv_exit(); rds_trans_unregister(&rds_ib_transport); + rds_ib_fmr_exit(); } struct rds_transport rds_ib_transport = { .laddr_check = rds_ib_laddr_check, .xmit_complete = rds_ib_xmit_complete, .xmit = rds_ib_xmit, - .xmit_cong_map = NULL, .xmit_rdma = rds_ib_xmit_rdma, + .xmit_atomic = rds_ib_xmit_atomic, .recv = rds_ib_recv, .conn_alloc = rds_ib_conn_alloc, .conn_free = rds_ib_conn_free, .conn_connect = rds_ib_conn_connect, .conn_shutdown = rds_ib_conn_shutdown, .inc_copy_to_user = rds_ib_inc_copy_to_user, - .inc_purge = rds_ib_inc_purge, .inc_free = rds_ib_inc_free, .cm_initiate_connect = rds_ib_cm_initiate_connect, .cm_handle_connect = rds_ib_cm_handle_connect, @@ -286,16 +394,20 @@ struct rds_transport rds_ib_transport = { .t_type = RDS_TRANS_IB }; -int __init rds_ib_init(void) +int rds_ib_init(void) { int ret; INIT_LIST_HEAD(&rds_ib_devices); - ret = ib_register_client(&rds_ib_client); + ret = rds_ib_fmr_init(); if (ret) goto out; + ret = ib_register_client(&rds_ib_client); + if (ret) + goto out_fmr_exit; + ret = rds_ib_sysctl_init(); if (ret) goto out_ibreg; @@ -317,7 +429,9 @@ int __init rds_ib_init(void) out_sysctl: rds_ib_sysctl_exit(); out_ibreg: - ib_unregister_client(&rds_ib_client); + rds_ib_unregister_client(); +out_fmr_exit: + rds_ib_fmr_exit(); out: return ret; } diff --git a/net/rds/ib.h b/net/rds/ib.h index 64df4e79b29f27ffcb8e8242df4b344284734e74..e34ad032b66dea3c057080f6b905f50764f2b79c 100644 --- a/net/rds/ib.h +++ b/net/rds/ib.h @@ -3,11 +3,13 @@ #include #include +#include +#include #include "rds.h" #include "rdma_transport.h" #define RDS_FMR_SIZE 256 -#define RDS_FMR_POOL_SIZE 4096 +#define RDS_FMR_POOL_SIZE 8192 #define RDS_IB_MAX_SGE 8 #define RDS_IB_RECV_SGE 2 @@ -19,6 +21,9 @@ #define RDS_IB_SUPPORTED_PROTOCOLS 0x00000003 /* minor versions supported */ +#define RDS_IB_RECYCLE_BATCH_COUNT 32 + +extern struct rw_semaphore rds_ib_devices_lock; extern struct list_head rds_ib_devices; /* @@ -26,20 +31,29 @@ extern struct list_head rds_ib_devices; * try and minimize the amount of memory tied up both the device and * socket receive queues. */ -/* page offset of the final full frag that fits in the page */ -#define RDS_PAGE_LAST_OFF (((PAGE_SIZE / RDS_FRAG_SIZE) - 1) * RDS_FRAG_SIZE) struct rds_page_frag { struct list_head f_item; - struct page *f_page; - unsigned long f_offset; - dma_addr_t f_mapped; + struct list_head f_cache_entry; + struct scatterlist f_sg; }; struct rds_ib_incoming { struct list_head ii_frags; + struct list_head ii_cache_entry; struct rds_incoming ii_inc; }; +struct rds_ib_cache_head { + struct list_head *first; + unsigned long count; +}; + +struct rds_ib_refill_cache { + struct rds_ib_cache_head *percpu; + struct list_head *xfer; + struct list_head *ready; +}; + struct rds_ib_connect_private { /* Add new fields at the end, and don't permute existing fields. */ __be32 dp_saddr; @@ -53,8 +67,7 @@ struct rds_ib_connect_private { }; struct rds_ib_send_work { - struct rds_message *s_rm; - struct rds_rdma_op *s_op; + void *s_op; struct ib_send_wr s_wr; struct ib_sge s_sge[RDS_IB_MAX_SGE]; unsigned long s_queued; @@ -92,10 +105,11 @@ struct rds_ib_connection { /* tx */ struct rds_ib_work_ring i_send_ring; - struct rds_message *i_rm; + struct rm_data_op *i_data_op; struct rds_header *i_send_hdrs; u64 i_send_hdrs_dma; struct rds_ib_send_work *i_sends; + atomic_t i_signaled_sends; /* rx */ struct tasklet_struct i_recv_tasklet; @@ -106,8 +120,9 @@ struct rds_ib_connection { struct rds_header *i_recv_hdrs; u64 i_recv_hdrs_dma; struct rds_ib_recv_work *i_recvs; - struct rds_page_frag i_frag; u64 i_ack_recv; /* last ACK received */ + struct rds_ib_refill_cache i_cache_incs; + struct rds_ib_refill_cache i_cache_frags; /* sending acks */ unsigned long i_ack_flags; @@ -138,7 +153,6 @@ struct rds_ib_connection { /* Batched completions */ unsigned int i_unsignaled_wrs; - long i_unsignaled_bytes; }; /* This assumes that atomic_t is at least 32 bits */ @@ -164,9 +178,17 @@ struct rds_ib_device { unsigned int max_fmrs; int max_sge; unsigned int max_wrs; + unsigned int max_initiator_depth; + unsigned int max_responder_resources; spinlock_t spinlock; /* protect the above */ + atomic_t refcount; + struct work_struct free_work; }; +#define pcidev_to_node(pcidev) pcibus_to_node(pcidev->bus) +#define ibdev_to_node(ibdev) pcidev_to_node(to_pci_dev(ibdev->dma_device)) +#define rdsibdev_to_node(rdsibdev) ibdev_to_node(rdsibdev->dev) + /* bits for i_ack_flags */ #define IB_ACK_IN_FLIGHT 0 #define IB_ACK_REQUESTED 1 @@ -202,6 +224,8 @@ struct rds_ib_statistics { uint64_t s_ib_rdma_mr_pool_flush; uint64_t s_ib_rdma_mr_pool_wait; uint64_t s_ib_rdma_mr_pool_depleted; + uint64_t s_ib_atomic_cswp; + uint64_t s_ib_atomic_fadd; }; extern struct workqueue_struct *rds_ib_wq; @@ -241,11 +265,10 @@ static inline void rds_ib_dma_sync_sg_for_device(struct ib_device *dev, /* ib.c */ extern struct rds_transport rds_ib_transport; -extern void rds_ib_add_one(struct ib_device *device); -extern void rds_ib_remove_one(struct ib_device *device); +struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device); +void rds_ib_dev_put(struct rds_ib_device *rds_ibdev); extern struct ib_client rds_ib_client; -extern unsigned int fmr_pool_size; extern unsigned int fmr_message_size; extern unsigned int rds_ib_retry_count; @@ -258,7 +281,7 @@ void rds_ib_conn_free(void *arg); int rds_ib_conn_connect(struct rds_connection *conn); void rds_ib_conn_shutdown(struct rds_connection *conn); void rds_ib_state_change(struct sock *sk); -int __init rds_ib_listen_init(void); +int rds_ib_listen_init(void); void rds_ib_listen_stop(void); void __rds_ib_conn_error(struct rds_connection *conn, const char *, ...); int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, @@ -275,15 +298,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr); void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn); void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn); -void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock); -static inline void rds_ib_destroy_nodev_conns(void) -{ - __rds_ib_destroy_conns(&ib_nodev_conns, &ib_nodev_conns_lock); -} -static inline void rds_ib_destroy_conns(struct rds_ib_device *rds_ibdev) -{ - __rds_ib_destroy_conns(&rds_ibdev->conn_list, &rds_ibdev->spinlock); -} +void rds_ib_destroy_nodev_conns(void); struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *); void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_connection *iinfo); void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *); @@ -292,14 +307,16 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, void rds_ib_sync_mr(void *trans_private, int dir); void rds_ib_free_mr(void *trans_private, int invalidate); void rds_ib_flush_mrs(void); +int rds_ib_fmr_init(void); +void rds_ib_fmr_exit(void); /* ib_recv.c */ -int __init rds_ib_recv_init(void); +int rds_ib_recv_init(void); void rds_ib_recv_exit(void); int rds_ib_recv(struct rds_connection *conn); -int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, - gfp_t page_gfp, int prefill); -void rds_ib_inc_purge(struct rds_incoming *inc); +int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic); +void rds_ib_recv_free_caches(struct rds_ib_connection *ic); +void rds_ib_recv_refill(struct rds_connection *conn, int prefill); void rds_ib_inc_free(struct rds_incoming *inc); int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, size_t size); @@ -325,17 +342,19 @@ u32 rds_ib_ring_completed(struct rds_ib_work_ring *ring, u32 wr_id, u32 oldest); extern wait_queue_head_t rds_ib_ring_empty_wait; /* ib_send.c */ +char *rds_ib_wc_status_str(enum ib_wc_status status); void rds_ib_xmit_complete(struct rds_connection *conn); int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off); void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context); void rds_ib_send_init_ring(struct rds_ib_connection *ic); void rds_ib_send_clear_ring(struct rds_ib_connection *ic); -int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op); +int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op); void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted, u32 *adv_credits, int need_posted, int max_posted); +int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op); /* ib_stats.c */ DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats); @@ -344,7 +363,7 @@ unsigned int rds_ib_stats_info_copy(struct rds_info_iterator *iter, unsigned int avail); /* ib_sysctl.c */ -int __init rds_ib_sysctl_init(void); +int rds_ib_sysctl_init(void); void rds_ib_sysctl_exit(void); extern unsigned long rds_ib_sysctl_max_send_wr; extern unsigned long rds_ib_sysctl_max_recv_wr; @@ -352,30 +371,5 @@ extern unsigned long rds_ib_sysctl_max_unsig_wrs; extern unsigned long rds_ib_sysctl_max_unsig_bytes; extern unsigned long rds_ib_sysctl_max_recv_allocation; extern unsigned int rds_ib_sysctl_flow_control; -extern ctl_table rds_ib_sysctl_table[]; - -/* - * Helper functions for getting/setting the header and data SGEs in - * RDS packets (not RDMA) - * - * From version 3.1 onwards, header is in front of data in the sge. - */ -static inline struct ib_sge * -rds_ib_header_sge(struct rds_ib_connection *ic, struct ib_sge *sge) -{ - if (ic->conn->c_version > RDS_PROTOCOL_3_0) - return &sge[0]; - else - return &sge[1]; -} - -static inline struct ib_sge * -rds_ib_data_sge(struct rds_ib_connection *ic, struct ib_sge *sge) -{ - if (ic->conn->c_version > RDS_PROTOCOL_3_0) - return &sge[1]; - else - return &sge[0]; -} #endif diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index f68832798db224d6abffcc08f4ad494fa2b3bc17..ee369d201a65891b8f8e3b562bf738067665df2f 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -38,6 +38,36 @@ #include "rds.h" #include "ib.h" +static char *rds_ib_event_type_strings[] = { +#define RDS_IB_EVENT_STRING(foo) \ + [IB_EVENT_##foo] = __stringify(IB_EVENT_##foo) + RDS_IB_EVENT_STRING(CQ_ERR), + RDS_IB_EVENT_STRING(QP_FATAL), + RDS_IB_EVENT_STRING(QP_REQ_ERR), + RDS_IB_EVENT_STRING(QP_ACCESS_ERR), + RDS_IB_EVENT_STRING(COMM_EST), + RDS_IB_EVENT_STRING(SQ_DRAINED), + RDS_IB_EVENT_STRING(PATH_MIG), + RDS_IB_EVENT_STRING(PATH_MIG_ERR), + RDS_IB_EVENT_STRING(DEVICE_FATAL), + RDS_IB_EVENT_STRING(PORT_ACTIVE), + RDS_IB_EVENT_STRING(PORT_ERR), + RDS_IB_EVENT_STRING(LID_CHANGE), + RDS_IB_EVENT_STRING(PKEY_CHANGE), + RDS_IB_EVENT_STRING(SM_CHANGE), + RDS_IB_EVENT_STRING(SRQ_ERR), + RDS_IB_EVENT_STRING(SRQ_LIMIT_REACHED), + RDS_IB_EVENT_STRING(QP_LAST_WQE_REACHED), + RDS_IB_EVENT_STRING(CLIENT_REREGISTER), +#undef RDS_IB_EVENT_STRING +}; + +static char *rds_ib_event_str(enum ib_event_type type) +{ + return rds_str_array(rds_ib_event_type_strings, + ARRAY_SIZE(rds_ib_event_type_strings), type); +}; + /* * Set the selected protocol version */ @@ -95,7 +125,6 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even { const struct rds_ib_connect_private *dp = NULL; struct rds_ib_connection *ic = conn->c_transport_data; - struct rds_ib_device *rds_ibdev; struct ib_qp_attr qp_attr; int err; @@ -111,11 +140,21 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even } } - printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n", - &conn->c_faddr, - RDS_PROTOCOL_MAJOR(conn->c_version), - RDS_PROTOCOL_MINOR(conn->c_version), - ic->i_flowctl ? ", flow control" : ""); + if (conn->c_version < RDS_PROTOCOL(3,1)) { + printk(KERN_NOTICE "RDS/IB: Connection to %pI4 version %u.%u failed," + " no longer supported\n", + &conn->c_faddr, + RDS_PROTOCOL_MAJOR(conn->c_version), + RDS_PROTOCOL_MINOR(conn->c_version)); + rds_conn_destroy(conn); + return; + } else { + printk(KERN_NOTICE "RDS/IB: connected to %pI4 version %u.%u%s\n", + &conn->c_faddr, + RDS_PROTOCOL_MAJOR(conn->c_version), + RDS_PROTOCOL_MINOR(conn->c_version), + ic->i_flowctl ? ", flow control" : ""); + } /* * Init rings and fill recv. this needs to wait until protocol negotiation @@ -125,7 +164,7 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even rds_ib_recv_init_ring(ic); /* Post receive buffers - as a side effect, this will update * the posted credit count. */ - rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 1); + rds_ib_recv_refill(conn, 1); /* Tune RNR behavior */ rds_ib_tune_rnr(ic, &qp_attr); @@ -135,12 +174,11 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even if (err) printk(KERN_NOTICE "ib_modify_qp(IB_QP_STATE, RTS): err=%d\n", err); - /* update ib_device with this local ipaddr & conn */ - rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); - err = rds_ib_update_ipaddr(rds_ibdev, conn->c_laddr); + /* update ib_device with this local ipaddr */ + err = rds_ib_update_ipaddr(ic->rds_ibdev, conn->c_laddr); if (err) - printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n", err); - rds_ib_add_conn(rds_ibdev, conn); + printk(KERN_ERR "rds_ib_update_ipaddr failed (%d)\n", + err); /* If the peer gave us the last packet it saw, process this as if * we had received a regular ACK. */ @@ -153,18 +191,23 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even static void rds_ib_cm_fill_conn_param(struct rds_connection *conn, struct rdma_conn_param *conn_param, struct rds_ib_connect_private *dp, - u32 protocol_version) + u32 protocol_version, + u32 max_responder_resources, + u32 max_initiator_depth) { + struct rds_ib_connection *ic = conn->c_transport_data; + struct rds_ib_device *rds_ibdev = ic->rds_ibdev; + memset(conn_param, 0, sizeof(struct rdma_conn_param)); - /* XXX tune these? */ - conn_param->responder_resources = 1; - conn_param->initiator_depth = 1; + + conn_param->responder_resources = + min_t(u32, rds_ibdev->max_responder_resources, max_responder_resources); + conn_param->initiator_depth = + min_t(u32, rds_ibdev->max_initiator_depth, max_initiator_depth); conn_param->retry_count = min_t(unsigned int, rds_ib_retry_count, 7); conn_param->rnr_retry_count = 7; if (dp) { - struct rds_ib_connection *ic = conn->c_transport_data; - memset(dp, 0, sizeof(*dp)); dp->dp_saddr = conn->c_laddr; dp->dp_daddr = conn->c_faddr; @@ -189,7 +232,8 @@ static void rds_ib_cm_fill_conn_param(struct rds_connection *conn, static void rds_ib_cq_event_handler(struct ib_event *event, void *data) { - rdsdebug("event %u data %p\n", event->event, data); + rdsdebug("event %u (%s) data %p\n", + event->event, rds_ib_event_str(event->event), data); } static void rds_ib_qp_event_handler(struct ib_event *event, void *data) @@ -197,16 +241,18 @@ static void rds_ib_qp_event_handler(struct ib_event *event, void *data) struct rds_connection *conn = data; struct rds_ib_connection *ic = conn->c_transport_data; - rdsdebug("conn %p ic %p event %u\n", conn, ic, event->event); + rdsdebug("conn %p ic %p event %u (%s)\n", conn, ic, event->event, + rds_ib_event_str(event->event)); switch (event->event) { case IB_EVENT_COMM_EST: rdma_notify(ic->i_cm_id, IB_EVENT_COMM_EST); break; default: - rdsdebug("Fatal QP Event %u " + rdsdebug("Fatal QP Event %u (%s) " "- connection %pI4->%pI4, reconnecting\n", - event->event, &conn->c_laddr, &conn->c_faddr); + event->event, rds_ib_event_str(event->event), + &conn->c_laddr, &conn->c_faddr); rds_conn_drop(conn); break; } @@ -224,18 +270,16 @@ static int rds_ib_setup_qp(struct rds_connection *conn) struct rds_ib_device *rds_ibdev; int ret; - /* rds_ib_add_one creates a rds_ib_device object per IB device, - * and allocates a protection domain, memory range and FMR pool - * for each. If that fails for any reason, it will not register - * the rds_ibdev at all. + /* + * It's normal to see a null device if an incoming connection races + * with device removal, so we don't print a warning. */ - rds_ibdev = ib_get_client_data(dev, &rds_ib_client); - if (rds_ibdev == NULL) { - if (printk_ratelimit()) - printk(KERN_NOTICE "RDS/IB: No client_data for device %s\n", - dev->name); + rds_ibdev = rds_ib_get_client_data(dev); + if (!rds_ibdev) return -EOPNOTSUPP; - } + + /* add the conn now so that connection establishment has the dev */ + rds_ib_add_conn(rds_ibdev, conn); if (rds_ibdev->max_wrs < ic->i_send_ring.w_nr + 1) rds_ib_ring_resize(&ic->i_send_ring, rds_ibdev->max_wrs - 1); @@ -306,7 +350,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_send_ring.w_nr * sizeof(struct rds_header), &ic->i_send_hdrs_dma, GFP_KERNEL); - if (ic->i_send_hdrs == NULL) { + if (!ic->i_send_hdrs) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent send failed\n"); goto out; @@ -316,7 +360,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_recv_ring.w_nr * sizeof(struct rds_header), &ic->i_recv_hdrs_dma, GFP_KERNEL); - if (ic->i_recv_hdrs == NULL) { + if (!ic->i_recv_hdrs) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent recv failed\n"); goto out; @@ -324,22 +368,24 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header), &ic->i_ack_dma, GFP_KERNEL); - if (ic->i_ack == NULL) { + if (!ic->i_ack) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent ack failed\n"); goto out; } - ic->i_sends = vmalloc(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work)); - if (ic->i_sends == NULL) { + ic->i_sends = vmalloc_node(ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work), + ibdev_to_node(dev)); + if (!ic->i_sends) { ret = -ENOMEM; rdsdebug("send allocation failed\n"); goto out; } memset(ic->i_sends, 0, ic->i_send_ring.w_nr * sizeof(struct rds_ib_send_work)); - ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work)); - if (ic->i_recvs == NULL) { + ic->i_recvs = vmalloc_node(ic->i_recv_ring.w_nr * sizeof(struct rds_ib_recv_work), + ibdev_to_node(dev)); + if (!ic->i_recvs) { ret = -ENOMEM; rdsdebug("recv allocation failed\n"); goto out; @@ -352,6 +398,7 @@ static int rds_ib_setup_qp(struct rds_connection *conn) ic->i_send_cq, ic->i_recv_cq); out: + rds_ib_dev_put(rds_ibdev); return ret; } @@ -409,7 +456,7 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, struct rds_ib_connection *ic = NULL; struct rdma_conn_param conn_param; u32 version; - int err, destroy = 1; + int err = 1, destroy = 1; /* Check whether the remote protocol version matches ours. */ version = rds_ib_protocol_compatible(event); @@ -448,7 +495,6 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, /* Wait and see - our connect may still be succeeding */ rds_ib_stats_inc(s_ib_connect_raced); } - mutex_unlock(&conn->c_cm_lock); goto out; } @@ -475,24 +521,23 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, err = rds_ib_setup_qp(conn); if (err) { rds_ib_conn_error(conn, "rds_ib_setup_qp failed (%d)\n", err); - mutex_unlock(&conn->c_cm_lock); goto out; } - rds_ib_cm_fill_conn_param(conn, &conn_param, &dp_rep, version); + rds_ib_cm_fill_conn_param(conn, &conn_param, &dp_rep, version, + event->param.conn.responder_resources, + event->param.conn.initiator_depth); /* rdma_accept() calls rdma_reject() internally if it fails */ err = rdma_accept(cm_id, &conn_param); - mutex_unlock(&conn->c_cm_lock); - if (err) { + if (err) rds_ib_conn_error(conn, "rdma_accept failed (%d)\n", err); - goto out; - } - - return 0; out: - rdma_reject(cm_id, NULL, 0); + if (conn) + mutex_unlock(&conn->c_cm_lock); + if (err) + rdma_reject(cm_id, NULL, 0); return destroy; } @@ -516,8 +561,8 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id) goto out; } - rds_ib_cm_fill_conn_param(conn, &conn_param, &dp, RDS_PROTOCOL_VERSION); - + rds_ib_cm_fill_conn_param(conn, &conn_param, &dp, RDS_PROTOCOL_VERSION, + UINT_MAX, UINT_MAX); ret = rdma_connect(cm_id, &conn_param); if (ret) rds_ib_conn_error(conn, "rdma_connect failed (%d)\n", ret); @@ -601,9 +646,19 @@ void rds_ib_conn_shutdown(struct rds_connection *conn) ic->i_cm_id, err); } + /* + * We want to wait for tx and rx completion to finish + * before we tear down the connection, but we have to be + * careful not to get stuck waiting on a send ring that + * only has unsignaled sends in it. We've shutdown new + * sends before getting here so by waiting for signaled + * sends to complete we're ensured that there will be no + * more tx processing. + */ wait_event(rds_ib_ring_empty_wait, - rds_ib_ring_empty(&ic->i_send_ring) && - rds_ib_ring_empty(&ic->i_recv_ring)); + rds_ib_ring_empty(&ic->i_recv_ring) && + (atomic_read(&ic->i_signaled_sends) == 0)); + tasklet_kill(&ic->i_recv_tasklet); if (ic->i_send_hdrs) ib_dma_free_coherent(dev, @@ -654,9 +709,12 @@ void rds_ib_conn_shutdown(struct rds_connection *conn) BUG_ON(ic->rds_ibdev); /* Clear pending transmit */ - if (ic->i_rm) { - rds_message_put(ic->i_rm); - ic->i_rm = NULL; + if (ic->i_data_op) { + struct rds_message *rm; + + rm = container_of(ic->i_data_op, struct rds_message, data); + rds_message_put(rm); + ic->i_data_op = NULL; } /* Clear the ACK state */ @@ -690,12 +748,19 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) { struct rds_ib_connection *ic; unsigned long flags; + int ret; /* XXX too lazy? */ ic = kzalloc(sizeof(struct rds_ib_connection), GFP_KERNEL); - if (ic == NULL) + if (!ic) return -ENOMEM; + ret = rds_ib_recv_alloc_caches(ic); + if (ret) { + kfree(ic); + return ret; + } + INIT_LIST_HEAD(&ic->ib_node); tasklet_init(&ic->i_recv_tasklet, rds_ib_recv_tasklet_fn, (unsigned long) ic); @@ -703,6 +768,7 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) #ifndef KERNEL_HAS_ATOMIC64 spin_lock_init(&ic->i_ack_lock); #endif + atomic_set(&ic->i_signaled_sends, 0); /* * rds_ib_conn_shutdown() waits for these to be emptied so they @@ -744,6 +810,8 @@ void rds_ib_conn_free(void *arg) list_del(&ic->ib_node); spin_unlock_irq(lock_ptr); + rds_ib_recv_free_caches(ic); + kfree(ic); } diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index a54cd63f9e35bd0f3e33a80d9ac06801fb3e0122..18a833c450c88bde4d3ed180d907cc8156906ee2 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -32,11 +32,16 @@ */ #include #include +#include #include "rds.h" -#include "rdma.h" #include "ib.h" +#include "xlist.h" +static struct workqueue_struct *rds_ib_fmr_wq; + +static DEFINE_PER_CPU(unsigned long, clean_list_grace); +#define CLEAN_LIST_BUSY_BIT 0 /* * This is stored as mr->r_trans_private. @@ -45,7 +50,11 @@ struct rds_ib_mr { struct rds_ib_device *device; struct rds_ib_mr_pool *pool; struct ib_fmr *fmr; - struct list_head list; + + struct xlist_head xlist; + + /* unmap_list is for freeing */ + struct list_head unmap_list; unsigned int remap_count; struct scatterlist *sg; @@ -59,14 +68,16 @@ struct rds_ib_mr { */ struct rds_ib_mr_pool { struct mutex flush_lock; /* serialize fmr invalidate */ - struct work_struct flush_worker; /* flush worker */ + struct delayed_work flush_worker; /* flush worker */ - spinlock_t list_lock; /* protect variables below */ atomic_t item_count; /* total # of MRs */ atomic_t dirty_count; /* # dirty of MRs */ - struct list_head drop_list; /* MRs that have reached their max_maps limit */ - struct list_head free_list; /* unused MRs */ - struct list_head clean_list; /* unused & unamapped MRs */ + + struct xlist_head drop_list; /* MRs that have reached their max_maps limit */ + struct xlist_head free_list; /* unused MRs */ + struct xlist_head clean_list; /* global unused & unamapped MRs */ + wait_queue_head_t flush_wait; + atomic_t free_pinned; /* memory pinned by free MRs */ unsigned long max_items; unsigned long max_items_soft; @@ -74,7 +85,7 @@ struct rds_ib_mr_pool { struct ib_fmr_attr fmr_attr; }; -static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all); +static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all, struct rds_ib_mr **); static void rds_ib_teardown_mr(struct rds_ib_mr *ibmr); static void rds_ib_mr_pool_flush_worker(struct work_struct *work); @@ -83,16 +94,17 @@ static struct rds_ib_device *rds_ib_get_device(__be32 ipaddr) struct rds_ib_device *rds_ibdev; struct rds_ib_ipaddr *i_ipaddr; - list_for_each_entry(rds_ibdev, &rds_ib_devices, list) { - spin_lock_irq(&rds_ibdev->spinlock); - list_for_each_entry(i_ipaddr, &rds_ibdev->ipaddr_list, list) { + rcu_read_lock(); + list_for_each_entry_rcu(rds_ibdev, &rds_ib_devices, list) { + list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) { if (i_ipaddr->ipaddr == ipaddr) { - spin_unlock_irq(&rds_ibdev->spinlock); + atomic_inc(&rds_ibdev->refcount); + rcu_read_unlock(); return rds_ibdev; } } - spin_unlock_irq(&rds_ibdev->spinlock); } + rcu_read_unlock(); return NULL; } @@ -108,7 +120,7 @@ static int rds_ib_add_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) i_ipaddr->ipaddr = ipaddr; spin_lock_irq(&rds_ibdev->spinlock); - list_add_tail(&i_ipaddr->list, &rds_ibdev->ipaddr_list); + list_add_tail_rcu(&i_ipaddr->list, &rds_ibdev->ipaddr_list); spin_unlock_irq(&rds_ibdev->spinlock); return 0; @@ -116,17 +128,24 @@ static int rds_ib_add_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) static void rds_ib_remove_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) { - struct rds_ib_ipaddr *i_ipaddr, *next; + struct rds_ib_ipaddr *i_ipaddr; + struct rds_ib_ipaddr *to_free = NULL; + spin_lock_irq(&rds_ibdev->spinlock); - list_for_each_entry_safe(i_ipaddr, next, &rds_ibdev->ipaddr_list, list) { + list_for_each_entry_rcu(i_ipaddr, &rds_ibdev->ipaddr_list, list) { if (i_ipaddr->ipaddr == ipaddr) { - list_del(&i_ipaddr->list); - kfree(i_ipaddr); + list_del_rcu(&i_ipaddr->list); + to_free = i_ipaddr; break; } } spin_unlock_irq(&rds_ibdev->spinlock); + + if (to_free) { + synchronize_rcu(); + kfree(to_free); + } } int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) @@ -134,8 +153,10 @@ int rds_ib_update_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) struct rds_ib_device *rds_ibdev_old; rds_ibdev_old = rds_ib_get_device(ipaddr); - if (rds_ibdev_old) + if (rds_ibdev_old) { rds_ib_remove_ipaddr(rds_ibdev_old, ipaddr); + rds_ib_dev_put(rds_ibdev_old); + } return rds_ib_add_ipaddr(rds_ibdev, ipaddr); } @@ -150,12 +171,13 @@ void rds_ib_add_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *con BUG_ON(list_empty(&ic->ib_node)); list_del(&ic->ib_node); - spin_lock_irq(&rds_ibdev->spinlock); + spin_lock(&rds_ibdev->spinlock); list_add_tail(&ic->ib_node, &rds_ibdev->conn_list); - spin_unlock_irq(&rds_ibdev->spinlock); + spin_unlock(&rds_ibdev->spinlock); spin_unlock_irq(&ib_nodev_conns_lock); ic->rds_ibdev = rds_ibdev; + atomic_inc(&rds_ibdev->refcount); } void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection *conn) @@ -175,18 +197,18 @@ void rds_ib_remove_conn(struct rds_ib_device *rds_ibdev, struct rds_connection * spin_unlock(&ib_nodev_conns_lock); ic->rds_ibdev = NULL; + rds_ib_dev_put(rds_ibdev); } -void __rds_ib_destroy_conns(struct list_head *list, spinlock_t *list_lock) +void rds_ib_destroy_nodev_conns(void) { struct rds_ib_connection *ic, *_ic; LIST_HEAD(tmp_list); /* avoid calling conn_destroy with irqs off */ - spin_lock_irq(list_lock); - list_splice(list, &tmp_list); - INIT_LIST_HEAD(list); - spin_unlock_irq(list_lock); + spin_lock_irq(&ib_nodev_conns_lock); + list_splice(&ib_nodev_conns, &tmp_list); + spin_unlock_irq(&ib_nodev_conns_lock); list_for_each_entry_safe(ic, _ic, &tmp_list, ib_node) rds_conn_destroy(ic->conn); @@ -200,12 +222,12 @@ struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev) if (!pool) return ERR_PTR(-ENOMEM); - INIT_LIST_HEAD(&pool->free_list); - INIT_LIST_HEAD(&pool->drop_list); - INIT_LIST_HEAD(&pool->clean_list); + INIT_XLIST_HEAD(&pool->free_list); + INIT_XLIST_HEAD(&pool->drop_list); + INIT_XLIST_HEAD(&pool->clean_list); mutex_init(&pool->flush_lock); - spin_lock_init(&pool->list_lock); - INIT_WORK(&pool->flush_worker, rds_ib_mr_pool_flush_worker); + init_waitqueue_head(&pool->flush_wait); + INIT_DELAYED_WORK(&pool->flush_worker, rds_ib_mr_pool_flush_worker); pool->fmr_attr.max_pages = fmr_message_size; pool->fmr_attr.max_maps = rds_ibdev->fmr_max_remaps; @@ -233,34 +255,60 @@ void rds_ib_get_mr_info(struct rds_ib_device *rds_ibdev, struct rds_info_rdma_co void rds_ib_destroy_mr_pool(struct rds_ib_mr_pool *pool) { - flush_workqueue(rds_wq); - rds_ib_flush_mr_pool(pool, 1); + cancel_delayed_work_sync(&pool->flush_worker); + rds_ib_flush_mr_pool(pool, 1, NULL); WARN_ON(atomic_read(&pool->item_count)); WARN_ON(atomic_read(&pool->free_pinned)); kfree(pool); } +static void refill_local(struct rds_ib_mr_pool *pool, struct xlist_head *xl, + struct rds_ib_mr **ibmr_ret) +{ + struct xlist_head *ibmr_xl; + ibmr_xl = xlist_del_head_fast(xl); + *ibmr_ret = list_entry(ibmr_xl, struct rds_ib_mr, xlist); +} + static inline struct rds_ib_mr *rds_ib_reuse_fmr(struct rds_ib_mr_pool *pool) { struct rds_ib_mr *ibmr = NULL; - unsigned long flags; + struct xlist_head *ret; + unsigned long *flag; - spin_lock_irqsave(&pool->list_lock, flags); - if (!list_empty(&pool->clean_list)) { - ibmr = list_entry(pool->clean_list.next, struct rds_ib_mr, list); - list_del_init(&ibmr->list); - } - spin_unlock_irqrestore(&pool->list_lock, flags); + preempt_disable(); + flag = &__get_cpu_var(clean_list_grace); + set_bit(CLEAN_LIST_BUSY_BIT, flag); + ret = xlist_del_head(&pool->clean_list); + if (ret) + ibmr = list_entry(ret, struct rds_ib_mr, xlist); + clear_bit(CLEAN_LIST_BUSY_BIT, flag); + preempt_enable(); return ibmr; } +static inline void wait_clean_list_grace(void) +{ + int cpu; + unsigned long *flag; + + for_each_online_cpu(cpu) { + flag = &per_cpu(clean_list_grace, cpu); + while (test_bit(CLEAN_LIST_BUSY_BIT, flag)) + cpu_relax(); + } +} + static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) { struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool; struct rds_ib_mr *ibmr = NULL; int err = 0, iter = 0; + if (atomic_read(&pool->dirty_count) >= pool->max_items / 10) + queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10); + while (1) { ibmr = rds_ib_reuse_fmr(pool); if (ibmr) @@ -287,19 +335,24 @@ static struct rds_ib_mr *rds_ib_alloc_fmr(struct rds_ib_device *rds_ibdev) /* We do have some empty MRs. Flush them out. */ rds_ib_stats_inc(s_ib_rdma_mr_pool_wait); - rds_ib_flush_mr_pool(pool, 0); + rds_ib_flush_mr_pool(pool, 0, &ibmr); + if (ibmr) + return ibmr; } - ibmr = kzalloc(sizeof(*ibmr), GFP_KERNEL); + ibmr = kzalloc_node(sizeof(*ibmr), GFP_KERNEL, rdsibdev_to_node(rds_ibdev)); if (!ibmr) { err = -ENOMEM; goto out_no_cigar; } + memset(ibmr, 0, sizeof(*ibmr)); + ibmr->fmr = ib_alloc_fmr(rds_ibdev->pd, (IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_READ | - IB_ACCESS_REMOTE_WRITE), + IB_ACCESS_REMOTE_WRITE| + IB_ACCESS_REMOTE_ATOMIC), &pool->fmr_attr); if (IS_ERR(ibmr->fmr)) { err = PTR_ERR(ibmr->fmr); @@ -367,7 +420,8 @@ static int rds_ib_map_fmr(struct rds_ib_device *rds_ibdev, struct rds_ib_mr *ibm if (page_cnt > fmr_message_size) return -EINVAL; - dma_pages = kmalloc(sizeof(u64) * page_cnt, GFP_ATOMIC); + dma_pages = kmalloc_node(sizeof(u64) * page_cnt, GFP_ATOMIC, + rdsibdev_to_node(rds_ibdev)); if (!dma_pages) return -ENOMEM; @@ -441,7 +495,7 @@ static void __rds_ib_teardown_mr(struct rds_ib_mr *ibmr) /* FIXME we need a way to tell a r/w MR * from a r/o MR */ - BUG_ON(in_interrupt()); + BUG_ON(irqs_disabled()); set_page_dirty(page); put_page(page); } @@ -476,34 +530,110 @@ static inline unsigned int rds_ib_flush_goal(struct rds_ib_mr_pool *pool, int fr return 0; } +/* + * given an xlist of mrs, put them all into the list_head for more processing + */ +static void xlist_append_to_list(struct xlist_head *xlist, struct list_head *list) +{ + struct rds_ib_mr *ibmr; + struct xlist_head splice; + struct xlist_head *cur; + struct xlist_head *next; + + splice.next = NULL; + xlist_splice(xlist, &splice); + cur = splice.next; + while (cur) { + next = cur->next; + ibmr = list_entry(cur, struct rds_ib_mr, xlist); + list_add_tail(&ibmr->unmap_list, list); + cur = next; + } +} + +/* + * this takes a list head of mrs and turns it into an xlist of clusters. + * each cluster has an xlist of MR_CLUSTER_SIZE mrs that are ready for + * reuse. + */ +static void list_append_to_xlist(struct rds_ib_mr_pool *pool, + struct list_head *list, struct xlist_head *xlist, + struct xlist_head **tail_ret) +{ + struct rds_ib_mr *ibmr; + struct xlist_head *cur_mr = xlist; + struct xlist_head *tail_mr = NULL; + + list_for_each_entry(ibmr, list, unmap_list) { + tail_mr = &ibmr->xlist; + tail_mr->next = NULL; + cur_mr->next = tail_mr; + cur_mr = tail_mr; + } + *tail_ret = tail_mr; +} + /* * Flush our pool of MRs. * At a minimum, all currently unused MRs are unmapped. * If the number of MRs allocated exceeds the limit, we also try * to free as many MRs as needed to get back to this limit. */ -static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all) +static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, + int free_all, struct rds_ib_mr **ibmr_ret) { struct rds_ib_mr *ibmr, *next; + struct xlist_head clean_xlist; + struct xlist_head *clean_tail; LIST_HEAD(unmap_list); LIST_HEAD(fmr_list); unsigned long unpinned = 0; - unsigned long flags; unsigned int nfreed = 0, ncleaned = 0, free_goal; int ret = 0; rds_ib_stats_inc(s_ib_rdma_mr_pool_flush); - mutex_lock(&pool->flush_lock); + if (ibmr_ret) { + DEFINE_WAIT(wait); + while(!mutex_trylock(&pool->flush_lock)) { + ibmr = rds_ib_reuse_fmr(pool); + if (ibmr) { + *ibmr_ret = ibmr; + finish_wait(&pool->flush_wait, &wait); + goto out_nolock; + } + + prepare_to_wait(&pool->flush_wait, &wait, + TASK_UNINTERRUPTIBLE); + if (xlist_empty(&pool->clean_list)) + schedule(); + + ibmr = rds_ib_reuse_fmr(pool); + if (ibmr) { + *ibmr_ret = ibmr; + finish_wait(&pool->flush_wait, &wait); + goto out_nolock; + } + } + finish_wait(&pool->flush_wait, &wait); + } else + mutex_lock(&pool->flush_lock); + + if (ibmr_ret) { + ibmr = rds_ib_reuse_fmr(pool); + if (ibmr) { + *ibmr_ret = ibmr; + goto out; + } + } - spin_lock_irqsave(&pool->list_lock, flags); /* Get the list of all MRs to be dropped. Ordering matters - - * we want to put drop_list ahead of free_list. */ - list_splice_init(&pool->free_list, &unmap_list); - list_splice_init(&pool->drop_list, &unmap_list); + * we want to put drop_list ahead of free_list. + */ + xlist_append_to_list(&pool->drop_list, &unmap_list); + xlist_append_to_list(&pool->free_list, &unmap_list); if (free_all) - list_splice_init(&pool->clean_list, &unmap_list); - spin_unlock_irqrestore(&pool->list_lock, flags); + xlist_append_to_list(&pool->clean_list, &unmap_list); free_goal = rds_ib_flush_goal(pool, free_all); @@ -511,19 +641,20 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all) goto out; /* String all ib_mr's onto one list and hand them to ib_unmap_fmr */ - list_for_each_entry(ibmr, &unmap_list, list) + list_for_each_entry(ibmr, &unmap_list, unmap_list) list_add(&ibmr->fmr->list, &fmr_list); + ret = ib_unmap_fmr(&fmr_list); if (ret) printk(KERN_WARNING "RDS/IB: ib_unmap_fmr failed (err=%d)\n", ret); /* Now we can destroy the DMA mapping and unpin any pages */ - list_for_each_entry_safe(ibmr, next, &unmap_list, list) { + list_for_each_entry_safe(ibmr, next, &unmap_list, unmap_list) { unpinned += ibmr->sg_len; __rds_ib_teardown_mr(ibmr); if (nfreed < free_goal || ibmr->remap_count >= pool->fmr_attr.max_maps) { rds_ib_stats_inc(s_ib_rdma_mr_free); - list_del(&ibmr->list); + list_del(&ibmr->unmap_list); ib_dealloc_fmr(ibmr->fmr); kfree(ibmr); nfreed++; @@ -531,9 +662,27 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all) ncleaned++; } - spin_lock_irqsave(&pool->list_lock, flags); - list_splice(&unmap_list, &pool->clean_list); - spin_unlock_irqrestore(&pool->list_lock, flags); + if (!list_empty(&unmap_list)) { + /* we have to make sure that none of the things we're about + * to put on the clean list would race with other cpus trying + * to pull items off. The xlist would explode if we managed to + * remove something from the clean list and then add it back again + * while another CPU was spinning on that same item in xlist_del_head. + * + * This is pretty unlikely, but just in case wait for an xlist grace period + * here before adding anything back into the clean list. + */ + wait_clean_list_grace(); + + list_append_to_xlist(pool, &unmap_list, &clean_xlist, &clean_tail); + if (ibmr_ret) + refill_local(pool, &clean_xlist, ibmr_ret); + + /* refill_local may have emptied our list */ + if (!xlist_empty(&clean_xlist)) + xlist_add(clean_xlist.next, clean_tail, &pool->clean_list); + + } atomic_sub(unpinned, &pool->free_pinned); atomic_sub(ncleaned, &pool->dirty_count); @@ -541,14 +690,35 @@ static int rds_ib_flush_mr_pool(struct rds_ib_mr_pool *pool, int free_all) out: mutex_unlock(&pool->flush_lock); + if (waitqueue_active(&pool->flush_wait)) + wake_up(&pool->flush_wait); +out_nolock: return ret; } +int rds_ib_fmr_init(void) +{ + rds_ib_fmr_wq = create_workqueue("rds_fmr_flushd"); + if (!rds_ib_fmr_wq) + return -ENOMEM; + return 0; +} + +/* + * By the time this is called all the IB devices should have been torn down and + * had their pools freed. As each pool is freed its work struct is waited on, + * so the pool flushing work queue should be idle by the time we get here. + */ +void rds_ib_fmr_exit(void) +{ + destroy_workqueue(rds_ib_fmr_wq); +} + static void rds_ib_mr_pool_flush_worker(struct work_struct *work) { - struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker); + struct rds_ib_mr_pool *pool = container_of(work, struct rds_ib_mr_pool, flush_worker.work); - rds_ib_flush_mr_pool(pool, 0); + rds_ib_flush_mr_pool(pool, 0, NULL); } void rds_ib_free_mr(void *trans_private, int invalidate) @@ -556,47 +726,49 @@ void rds_ib_free_mr(void *trans_private, int invalidate) struct rds_ib_mr *ibmr = trans_private; struct rds_ib_device *rds_ibdev = ibmr->device; struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool; - unsigned long flags; rdsdebug("RDS/IB: free_mr nents %u\n", ibmr->sg_len); /* Return it to the pool's free list */ - spin_lock_irqsave(&pool->list_lock, flags); if (ibmr->remap_count >= pool->fmr_attr.max_maps) - list_add(&ibmr->list, &pool->drop_list); + xlist_add(&ibmr->xlist, &ibmr->xlist, &pool->drop_list); else - list_add(&ibmr->list, &pool->free_list); + xlist_add(&ibmr->xlist, &ibmr->xlist, &pool->free_list); atomic_add(ibmr->sg_len, &pool->free_pinned); atomic_inc(&pool->dirty_count); - spin_unlock_irqrestore(&pool->list_lock, flags); /* If we've pinned too many pages, request a flush */ if (atomic_read(&pool->free_pinned) >= pool->max_free_pinned || atomic_read(&pool->dirty_count) >= pool->max_items / 10) - queue_work(rds_wq, &pool->flush_worker); + queue_delayed_work(rds_ib_fmr_wq, &pool->flush_worker, 10); if (invalidate) { if (likely(!in_interrupt())) { - rds_ib_flush_mr_pool(pool, 0); + rds_ib_flush_mr_pool(pool, 0, NULL); } else { /* We get here if the user created a MR marked * as use_once and invalidate at the same time. */ - queue_work(rds_wq, &pool->flush_worker); + queue_delayed_work(rds_ib_fmr_wq, + &pool->flush_worker, 10); } } + + rds_ib_dev_put(rds_ibdev); } void rds_ib_flush_mrs(void) { struct rds_ib_device *rds_ibdev; + down_read(&rds_ib_devices_lock); list_for_each_entry(rds_ibdev, &rds_ib_devices, list) { struct rds_ib_mr_pool *pool = rds_ibdev->mr_pool; if (pool) - rds_ib_flush_mr_pool(pool, 0); + rds_ib_flush_mr_pool(pool, 0, NULL); } + up_read(&rds_ib_devices_lock); } void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, @@ -628,6 +800,7 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, printk(KERN_WARNING "RDS/IB: map_fmr failed (errno=%d)\n", ret); ibmr->device = rds_ibdev; + rds_ibdev = NULL; out: if (ret) { @@ -635,5 +808,8 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, rds_ib_free_mr(ibmr, 0); ibmr = ERR_PTR(ret); } + if (rds_ibdev) + rds_ib_dev_put(rds_ibdev); return ibmr; } + diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index c74e9904a6b2c20872917c79bf06a905c1ecd403..e29e0ca32f740d978aeccf23a4fba5453a4e8aa4 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c @@ -43,42 +43,6 @@ static struct kmem_cache *rds_ib_incoming_slab; static struct kmem_cache *rds_ib_frag_slab; static atomic_t rds_ib_allocation = ATOMIC_INIT(0); -static void rds_ib_frag_drop_page(struct rds_page_frag *frag) -{ - rdsdebug("frag %p page %p\n", frag, frag->f_page); - __free_page(frag->f_page); - frag->f_page = NULL; -} - -static void rds_ib_frag_free(struct rds_page_frag *frag) -{ - rdsdebug("frag %p page %p\n", frag, frag->f_page); - BUG_ON(frag->f_page != NULL); - kmem_cache_free(rds_ib_frag_slab, frag); -} - -/* - * We map a page at a time. Its fragments are posted in order. This - * is called in fragment order as the fragments get send completion events. - * Only the last frag in the page performs the unmapping. - * - * It's OK for ring cleanup to call this in whatever order it likes because - * DMA is not in flight and so we can unmap while other ring entries still - * hold page references in their frags. - */ -static void rds_ib_recv_unmap_page(struct rds_ib_connection *ic, - struct rds_ib_recv_work *recv) -{ - struct rds_page_frag *frag = recv->r_frag; - - rdsdebug("recv %p frag %p page %p\n", recv, frag, frag->f_page); - if (frag->f_mapped) - ib_dma_unmap_page(ic->i_cm_id->device, - frag->f_mapped, - RDS_FRAG_SIZE, DMA_FROM_DEVICE); - frag->f_mapped = 0; -} - void rds_ib_recv_init_ring(struct rds_ib_connection *ic) { struct rds_ib_recv_work *recv; @@ -95,16 +59,161 @@ void rds_ib_recv_init_ring(struct rds_ib_connection *ic) recv->r_wr.sg_list = recv->r_sge; recv->r_wr.num_sge = RDS_IB_RECV_SGE; - sge = rds_ib_data_sge(ic, recv->r_sge); + sge = &recv->r_sge[0]; + sge->addr = ic->i_recv_hdrs_dma + (i * sizeof(struct rds_header)); + sge->length = sizeof(struct rds_header); + sge->lkey = ic->i_mr->lkey; + + sge = &recv->r_sge[1]; sge->addr = 0; sge->length = RDS_FRAG_SIZE; sge->lkey = ic->i_mr->lkey; + } +} - sge = rds_ib_header_sge(ic, recv->r_sge); - sge->addr = ic->i_recv_hdrs_dma + (i * sizeof(struct rds_header)); - sge->length = sizeof(struct rds_header); - sge->lkey = ic->i_mr->lkey; +/* + * The entire 'from' list, including the from element itself, is put on + * to the tail of the 'to' list. + */ +static void list_splice_entire_tail(struct list_head *from, + struct list_head *to) +{ + struct list_head *from_last = from->prev; + + list_splice_tail(from_last, to); + list_add_tail(from_last, to); +} + +static void rds_ib_cache_xfer_to_ready(struct rds_ib_refill_cache *cache) +{ + struct list_head *tmp; + + tmp = xchg(&cache->xfer, NULL); + if (tmp) { + if (cache->ready) + list_splice_entire_tail(tmp, cache->ready); + else + cache->ready = tmp; + } +} + +static int rds_ib_recv_alloc_cache(struct rds_ib_refill_cache *cache) +{ + struct rds_ib_cache_head *head; + int cpu; + + cache->percpu = alloc_percpu(struct rds_ib_cache_head); + if (!cache->percpu) + return -ENOMEM; + + for_each_possible_cpu(cpu) { + head = per_cpu_ptr(cache->percpu, cpu); + head->first = NULL; + head->count = 0; + } + cache->xfer = NULL; + cache->ready = NULL; + + return 0; +} + +int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic) +{ + int ret; + + ret = rds_ib_recv_alloc_cache(&ic->i_cache_incs); + if (!ret) { + ret = rds_ib_recv_alloc_cache(&ic->i_cache_frags); + if (ret) + free_percpu(ic->i_cache_incs.percpu); } + + return ret; +} + +static void rds_ib_cache_splice_all_lists(struct rds_ib_refill_cache *cache, + struct list_head *caller_list) +{ + struct rds_ib_cache_head *head; + int cpu; + + for_each_possible_cpu(cpu) { + head = per_cpu_ptr(cache->percpu, cpu); + if (head->first) { + list_splice_entire_tail(head->first, caller_list); + head->first = NULL; + } + } + + if (cache->ready) { + list_splice_entire_tail(cache->ready, caller_list); + cache->ready = NULL; + } +} + +void rds_ib_recv_free_caches(struct rds_ib_connection *ic) +{ + struct rds_ib_incoming *inc; + struct rds_ib_incoming *inc_tmp; + struct rds_page_frag *frag; + struct rds_page_frag *frag_tmp; + LIST_HEAD(list); + + rds_ib_cache_xfer_to_ready(&ic->i_cache_incs); + rds_ib_cache_splice_all_lists(&ic->i_cache_incs, &list); + free_percpu(ic->i_cache_incs.percpu); + + list_for_each_entry_safe(inc, inc_tmp, &list, ii_cache_entry) { + list_del(&inc->ii_cache_entry); + WARN_ON(!list_empty(&inc->ii_frags)); + kmem_cache_free(rds_ib_incoming_slab, inc); + } + + rds_ib_cache_xfer_to_ready(&ic->i_cache_frags); + rds_ib_cache_splice_all_lists(&ic->i_cache_frags, &list); + free_percpu(ic->i_cache_frags.percpu); + + list_for_each_entry_safe(frag, frag_tmp, &list, f_cache_entry) { + list_del(&frag->f_cache_entry); + WARN_ON(!list_empty(&frag->f_item)); + kmem_cache_free(rds_ib_frag_slab, frag); + } +} + +/* fwd decl */ +static void rds_ib_recv_cache_put(struct list_head *new_item, + struct rds_ib_refill_cache *cache); +static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache); + + +/* Recycle frag and attached recv buffer f_sg */ +static void rds_ib_frag_free(struct rds_ib_connection *ic, + struct rds_page_frag *frag) +{ + rdsdebug("frag %p page %p\n", frag, sg_page(&frag->f_sg)); + + rds_ib_recv_cache_put(&frag->f_cache_entry, &ic->i_cache_frags); +} + +/* Recycle inc after freeing attached frags */ +void rds_ib_inc_free(struct rds_incoming *inc) +{ + struct rds_ib_incoming *ibinc; + struct rds_page_frag *frag; + struct rds_page_frag *pos; + struct rds_ib_connection *ic = inc->i_conn->c_transport_data; + + ibinc = container_of(inc, struct rds_ib_incoming, ii_inc); + + /* Free attached frags */ + list_for_each_entry_safe(frag, pos, &ibinc->ii_frags, f_item) { + list_del_init(&frag->f_item); + rds_ib_frag_free(ic, frag); + } + BUG_ON(!list_empty(&ibinc->ii_frags)); + + rdsdebug("freeing ibinc %p inc %p\n", ibinc, inc); + rds_ib_recv_cache_put(&ibinc->ii_cache_entry, &ic->i_cache_incs); } static void rds_ib_recv_clear_one(struct rds_ib_connection *ic, @@ -115,10 +224,8 @@ static void rds_ib_recv_clear_one(struct rds_ib_connection *ic, recv->r_ibinc = NULL; } if (recv->r_frag) { - rds_ib_recv_unmap_page(ic, recv); - if (recv->r_frag->f_page) - rds_ib_frag_drop_page(recv->r_frag); - rds_ib_frag_free(recv->r_frag); + ib_dma_unmap_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 1, DMA_FROM_DEVICE); + rds_ib_frag_free(ic, recv->r_frag); recv->r_frag = NULL; } } @@ -129,84 +236,111 @@ void rds_ib_recv_clear_ring(struct rds_ib_connection *ic) for (i = 0; i < ic->i_recv_ring.w_nr; i++) rds_ib_recv_clear_one(ic, &ic->i_recvs[i]); - - if (ic->i_frag.f_page) - rds_ib_frag_drop_page(&ic->i_frag); } -static int rds_ib_recv_refill_one(struct rds_connection *conn, - struct rds_ib_recv_work *recv, - gfp_t kptr_gfp, gfp_t page_gfp) +static struct rds_ib_incoming *rds_ib_refill_one_inc(struct rds_ib_connection *ic, + gfp_t slab_mask) { - struct rds_ib_connection *ic = conn->c_transport_data; - dma_addr_t dma_addr; - struct ib_sge *sge; - int ret = -ENOMEM; + struct rds_ib_incoming *ibinc; + struct list_head *cache_item; + int avail_allocs; - if (recv->r_ibinc == NULL) { - if (!atomic_add_unless(&rds_ib_allocation, 1, rds_ib_sysctl_max_recv_allocation)) { + cache_item = rds_ib_recv_cache_get(&ic->i_cache_incs); + if (cache_item) { + ibinc = container_of(cache_item, struct rds_ib_incoming, ii_cache_entry); + } else { + avail_allocs = atomic_add_unless(&rds_ib_allocation, + 1, rds_ib_sysctl_max_recv_allocation); + if (!avail_allocs) { rds_ib_stats_inc(s_ib_rx_alloc_limit); - goto out; + return NULL; } - recv->r_ibinc = kmem_cache_alloc(rds_ib_incoming_slab, - kptr_gfp); - if (recv->r_ibinc == NULL) { + ibinc = kmem_cache_alloc(rds_ib_incoming_slab, slab_mask); + if (!ibinc) { atomic_dec(&rds_ib_allocation); - goto out; + return NULL; } - INIT_LIST_HEAD(&recv->r_ibinc->ii_frags); - rds_inc_init(&recv->r_ibinc->ii_inc, conn, conn->c_faddr); } + INIT_LIST_HEAD(&ibinc->ii_frags); + rds_inc_init(&ibinc->ii_inc, ic->conn, ic->conn->c_faddr); - if (recv->r_frag == NULL) { - recv->r_frag = kmem_cache_alloc(rds_ib_frag_slab, kptr_gfp); - if (recv->r_frag == NULL) - goto out; - INIT_LIST_HEAD(&recv->r_frag->f_item); - recv->r_frag->f_page = NULL; + return ibinc; +} + +static struct rds_page_frag *rds_ib_refill_one_frag(struct rds_ib_connection *ic, + gfp_t slab_mask, gfp_t page_mask) +{ + struct rds_page_frag *frag; + struct list_head *cache_item; + int ret; + + cache_item = rds_ib_recv_cache_get(&ic->i_cache_frags); + if (cache_item) { + frag = container_of(cache_item, struct rds_page_frag, f_cache_entry); + } else { + frag = kmem_cache_alloc(rds_ib_frag_slab, slab_mask); + if (!frag) + return NULL; + + sg_init_table(&frag->f_sg, 1); + ret = rds_page_remainder_alloc(&frag->f_sg, + RDS_FRAG_SIZE, page_mask); + if (ret) { + kmem_cache_free(rds_ib_frag_slab, frag); + return NULL; + } } - if (ic->i_frag.f_page == NULL) { - ic->i_frag.f_page = alloc_page(page_gfp); - if (ic->i_frag.f_page == NULL) - goto out; - ic->i_frag.f_offset = 0; + INIT_LIST_HEAD(&frag->f_item); + + return frag; +} + +static int rds_ib_recv_refill_one(struct rds_connection *conn, + struct rds_ib_recv_work *recv, int prefill) +{ + struct rds_ib_connection *ic = conn->c_transport_data; + struct ib_sge *sge; + int ret = -ENOMEM; + gfp_t slab_mask = GFP_NOWAIT; + gfp_t page_mask = GFP_NOWAIT; + + if (prefill) { + slab_mask = GFP_KERNEL; + page_mask = GFP_HIGHUSER; } - dma_addr = ib_dma_map_page(ic->i_cm_id->device, - ic->i_frag.f_page, - ic->i_frag.f_offset, - RDS_FRAG_SIZE, - DMA_FROM_DEVICE); - if (ib_dma_mapping_error(ic->i_cm_id->device, dma_addr)) - goto out; + if (!ic->i_cache_incs.ready) + rds_ib_cache_xfer_to_ready(&ic->i_cache_incs); + if (!ic->i_cache_frags.ready) + rds_ib_cache_xfer_to_ready(&ic->i_cache_frags); /* - * Once we get the RDS_PAGE_LAST_OFF frag then rds_ib_frag_unmap() - * must be called on this recv. This happens as completions hit - * in order or on connection shutdown. + * ibinc was taken from recv if recv contained the start of a message. + * recvs that were continuations will still have this allocated. */ - recv->r_frag->f_page = ic->i_frag.f_page; - recv->r_frag->f_offset = ic->i_frag.f_offset; - recv->r_frag->f_mapped = dma_addr; + if (!recv->r_ibinc) { + recv->r_ibinc = rds_ib_refill_one_inc(ic, slab_mask); + if (!recv->r_ibinc) + goto out; + } - sge = rds_ib_data_sge(ic, recv->r_sge); - sge->addr = dma_addr; - sge->length = RDS_FRAG_SIZE; + WARN_ON(recv->r_frag); /* leak! */ + recv->r_frag = rds_ib_refill_one_frag(ic, slab_mask, page_mask); + if (!recv->r_frag) + goto out; + + ret = ib_dma_map_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, + 1, DMA_FROM_DEVICE); + WARN_ON(ret != 1); - sge = rds_ib_header_sge(ic, recv->r_sge); + sge = &recv->r_sge[0]; sge->addr = ic->i_recv_hdrs_dma + (recv - ic->i_recvs) * sizeof(struct rds_header); sge->length = sizeof(struct rds_header); - get_page(recv->r_frag->f_page); - - if (ic->i_frag.f_offset < RDS_PAGE_LAST_OFF) { - ic->i_frag.f_offset += RDS_FRAG_SIZE; - } else { - put_page(ic->i_frag.f_page); - ic->i_frag.f_page = NULL; - ic->i_frag.f_offset = 0; - } + sge = &recv->r_sge[1]; + sge->addr = sg_dma_address(&recv->r_frag->f_sg); + sge->length = sg_dma_len(&recv->r_frag->f_sg); ret = 0; out: @@ -216,13 +350,11 @@ static int rds_ib_recv_refill_one(struct rds_connection *conn, /* * This tries to allocate and post unused work requests after making sure that * they have all the allocations they need to queue received fragments into - * sockets. The i_recv_mutex is held here so that ring_alloc and _unalloc - * pairs don't go unmatched. + * sockets. * * -1 is returned if posting fails due to temporary resource exhaustion. */ -int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, - gfp_t page_gfp, int prefill) +void rds_ib_recv_refill(struct rds_connection *conn, int prefill) { struct rds_ib_connection *ic = conn->c_transport_data; struct rds_ib_recv_work *recv; @@ -236,28 +368,25 @@ int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, if (pos >= ic->i_recv_ring.w_nr) { printk(KERN_NOTICE "Argh - ring alloc returned pos=%u\n", pos); - ret = -EINVAL; break; } recv = &ic->i_recvs[pos]; - ret = rds_ib_recv_refill_one(conn, recv, kptr_gfp, page_gfp); + ret = rds_ib_recv_refill_one(conn, recv, prefill); if (ret) { - ret = -1; break; } /* XXX when can this fail? */ ret = ib_post_recv(ic->i_cm_id->qp, &recv->r_wr, &failed_wr); rdsdebug("recv %p ibinc %p page %p addr %lu ret %d\n", recv, - recv->r_ibinc, recv->r_frag->f_page, - (long) recv->r_frag->f_mapped, ret); + recv->r_ibinc, sg_page(&recv->r_frag->f_sg), + (long) sg_dma_address(&recv->r_frag->f_sg), ret); if (ret) { rds_ib_conn_error(conn, "recv post on " "%pI4 returned %d, disconnecting and " "reconnecting\n", &conn->c_faddr, ret); - ret = -1; break; } @@ -270,37 +399,73 @@ int rds_ib_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, if (ret) rds_ib_ring_unalloc(&ic->i_recv_ring, 1); - return ret; } -void rds_ib_inc_purge(struct rds_incoming *inc) +/* + * We want to recycle several types of recv allocations, like incs and frags. + * To use this, the *_free() function passes in the ptr to a list_head within + * the recyclee, as well as the cache to put it on. + * + * First, we put the memory on a percpu list. When this reaches a certain size, + * We move it to an intermediate non-percpu list in a lockless manner, with some + * xchg/compxchg wizardry. + * + * N.B. Instead of a list_head as the anchor, we use a single pointer, which can + * be NULL and xchg'd. The list is actually empty when the pointer is NULL, and + * list_empty() will return true with one element is actually present. + */ +static void rds_ib_recv_cache_put(struct list_head *new_item, + struct rds_ib_refill_cache *cache) { - struct rds_ib_incoming *ibinc; - struct rds_page_frag *frag; - struct rds_page_frag *pos; + unsigned long flags; + struct rds_ib_cache_head *chp; + struct list_head *old; - ibinc = container_of(inc, struct rds_ib_incoming, ii_inc); - rdsdebug("purging ibinc %p inc %p\n", ibinc, inc); + local_irq_save(flags); - list_for_each_entry_safe(frag, pos, &ibinc->ii_frags, f_item) { - list_del_init(&frag->f_item); - rds_ib_frag_drop_page(frag); - rds_ib_frag_free(frag); - } + chp = per_cpu_ptr(cache->percpu, smp_processor_id()); + if (!chp->first) + INIT_LIST_HEAD(new_item); + else /* put on front */ + list_add_tail(new_item, chp->first); + chp->first = new_item; + chp->count++; + + if (chp->count < RDS_IB_RECYCLE_BATCH_COUNT) + goto end; + + /* + * Return our per-cpu first list to the cache's xfer by atomically + * grabbing the current xfer list, appending it to our per-cpu list, + * and then atomically returning that entire list back to the + * cache's xfer list as long as it's still empty. + */ + do { + old = xchg(&cache->xfer, NULL); + if (old) + list_splice_entire_tail(old, chp->first); + old = cmpxchg(&cache->xfer, NULL, chp->first); + } while (old); + + chp->first = NULL; + chp->count = 0; +end: + local_irq_restore(flags); } -void rds_ib_inc_free(struct rds_incoming *inc) +static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache) { - struct rds_ib_incoming *ibinc; - - ibinc = container_of(inc, struct rds_ib_incoming, ii_inc); + struct list_head *head = cache->ready; + + if (head) { + if (!list_empty(head)) { + cache->ready = head->next; + list_del_init(head); + } else + cache->ready = NULL; + } - rds_ib_inc_purge(inc); - rdsdebug("freeing ibinc %p inc %p\n", ibinc, inc); - BUG_ON(!list_empty(&ibinc->ii_frags)); - kmem_cache_free(rds_ib_incoming_slab, ibinc); - atomic_dec(&rds_ib_allocation); - BUG_ON(atomic_read(&rds_ib_allocation) < 0); + return head; } int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, @@ -336,13 +501,13 @@ int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, to_copy = min_t(unsigned long, to_copy, len - copied); rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag " - "[%p, %lu] + %lu\n", + "[%p, %u] + %lu\n", to_copy, iov->iov_base, iov->iov_len, iov_off, - frag->f_page, frag->f_offset, frag_off); + sg_page(&frag->f_sg), frag->f_sg.offset, frag_off); /* XXX needs + offset for multiple recvs per page */ - ret = rds_page_copy_to_user(frag->f_page, - frag->f_offset + frag_off, + ret = rds_page_copy_to_user(sg_page(&frag->f_sg), + frag->f_sg.offset + frag_off, iov->iov_base + iov_off, to_copy); if (ret) { @@ -557,47 +722,6 @@ u64 rds_ib_piggyb_ack(struct rds_ib_connection *ic) return rds_ib_get_ack(ic); } -static struct rds_header *rds_ib_get_header(struct rds_connection *conn, - struct rds_ib_recv_work *recv, - u32 data_len) -{ - struct rds_ib_connection *ic = conn->c_transport_data; - void *hdr_buff = &ic->i_recv_hdrs[recv - ic->i_recvs]; - void *addr; - u32 misplaced_hdr_bytes; - - /* - * Support header at the front (RDS 3.1+) as well as header-at-end. - * - * Cases: - * 1) header all in header buff (great!) - * 2) header all in data page (copy all to header buff) - * 3) header split across hdr buf + data page - * (move bit in hdr buff to end before copying other bit from data page) - */ - if (conn->c_version > RDS_PROTOCOL_3_0 || data_len == RDS_FRAG_SIZE) - return hdr_buff; - - if (data_len <= (RDS_FRAG_SIZE - sizeof(struct rds_header))) { - addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0); - memcpy(hdr_buff, - addr + recv->r_frag->f_offset + data_len, - sizeof(struct rds_header)); - kunmap_atomic(addr, KM_SOFTIRQ0); - return hdr_buff; - } - - misplaced_hdr_bytes = (sizeof(struct rds_header) - (RDS_FRAG_SIZE - data_len)); - - memmove(hdr_buff + misplaced_hdr_bytes, hdr_buff, misplaced_hdr_bytes); - - addr = kmap_atomic(recv->r_frag->f_page, KM_SOFTIRQ0); - memcpy(hdr_buff, addr + recv->r_frag->f_offset + data_len, - sizeof(struct rds_header) - misplaced_hdr_bytes); - kunmap_atomic(addr, KM_SOFTIRQ0); - return hdr_buff; -} - /* * It's kind of lame that we're copying from the posted receive pages into * long-lived bitmaps. We could have posted the bitmaps and rdma written into @@ -639,7 +763,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn, to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off); BUG_ON(to_copy & 7); /* Must be 64bit aligned. */ - addr = kmap_atomic(frag->f_page, KM_SOFTIRQ0); + addr = kmap_atomic(sg_page(&frag->f_sg), KM_SOFTIRQ0); src = addr + frag_off; dst = (void *)map->m_page_addrs[map_page] + map_off; @@ -710,7 +834,7 @@ static void rds_ib_process_recv(struct rds_connection *conn, } data_len -= sizeof(struct rds_header); - ihdr = rds_ib_get_header(conn, recv, data_len); + ihdr = &ic->i_recv_hdrs[recv - ic->i_recvs]; /* Validate the checksum. */ if (!rds_message_verify_checksum(ihdr)) { @@ -742,12 +866,12 @@ static void rds_ib_process_recv(struct rds_connection *conn, * the inc is freed. We don't go that route, so we have to drop the * page ref ourselves. We can't just leave the page on the recv * because that confuses the dma mapping of pages and each recv's use - * of a partial page. We can leave the frag, though, it will be - * reused. + * of a partial page. * * FIXME: Fold this into the code path below. */ - rds_ib_frag_drop_page(recv->r_frag); + rds_ib_frag_free(ic, recv->r_frag); + recv->r_frag = NULL; return; } @@ -757,7 +881,7 @@ static void rds_ib_process_recv(struct rds_connection *conn, * into the inc and save the inc so we can hang upcoming fragments * off its list. */ - if (ibinc == NULL) { + if (!ibinc) { ibinc = recv->r_ibinc; recv->r_ibinc = NULL; ic->i_ibinc = ibinc; @@ -842,32 +966,38 @@ static inline void rds_poll_cq(struct rds_ib_connection *ic, struct rds_ib_recv_work *recv; while (ib_poll_cq(ic->i_recv_cq, 1, &wc) > 0) { - rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", - (unsigned long long)wc.wr_id, wc.status, wc.byte_len, + rdsdebug("wc wr_id 0x%llx status %u (%s) byte_len %u imm_data %u\n", + (unsigned long long)wc.wr_id, wc.status, + rds_ib_wc_status_str(wc.status), wc.byte_len, be32_to_cpu(wc.ex.imm_data)); rds_ib_stats_inc(s_ib_rx_cq_event); recv = &ic->i_recvs[rds_ib_ring_oldest(&ic->i_recv_ring)]; - rds_ib_recv_unmap_page(ic, recv); + ib_dma_unmap_sg(ic->i_cm_id->device, &recv->r_frag->f_sg, 1, DMA_FROM_DEVICE); /* * Also process recvs in connecting state because it is possible * to get a recv completion _before_ the rdmacm ESTABLISHED * event is processed. */ - if (rds_conn_up(conn) || rds_conn_connecting(conn)) { + if (wc.status == IB_WC_SUCCESS) { + rds_ib_process_recv(conn, recv, wc.byte_len, state); + } else { /* We expect errors as the qp is drained during shutdown */ - if (wc.status == IB_WC_SUCCESS) { - rds_ib_process_recv(conn, recv, wc.byte_len, state); - } else { - rds_ib_conn_error(conn, "recv completion on " - "%pI4 had status %u, disconnecting and " - "reconnecting\n", &conn->c_faddr, - wc.status); - } + if (rds_conn_up(conn) || rds_conn_connecting(conn)) + rds_ib_conn_error(conn, "recv completion on %pI4 had " + "status %u (%s), disconnecting and " + "reconnecting\n", &conn->c_faddr, + wc.status, + rds_ib_wc_status_str(wc.status)); } + /* + * It's very important that we only free this ring entry if we've truly + * freed the resources allocated to the entry. The refilling path can + * leak if we don't. + */ rds_ib_ring_free(&ic->i_recv_ring, 1); } } @@ -897,11 +1027,8 @@ void rds_ib_recv_tasklet_fn(unsigned long data) if (rds_ib_ring_empty(&ic->i_recv_ring)) rds_ib_stats_inc(s_ib_rx_ring_empty); - /* - * If the ring is running low, then schedule the thread to refill. - */ if (rds_ib_ring_low(&ic->i_recv_ring)) - queue_delayed_work(rds_wq, &conn->c_recv_w, 0); + rds_ib_recv_refill(conn, 0); } int rds_ib_recv(struct rds_connection *conn) @@ -910,25 +1037,13 @@ int rds_ib_recv(struct rds_connection *conn) int ret = 0; rdsdebug("conn %p\n", conn); - - /* - * If we get a temporary posting failure in this context then - * we're really low and we want the caller to back off for a bit. - */ - mutex_lock(&ic->i_recv_mutex); - if (rds_ib_recv_refill(conn, GFP_KERNEL, GFP_HIGHUSER, 0)) - ret = -ENOMEM; - else - rds_ib_stats_inc(s_ib_rx_refill_from_thread); - mutex_unlock(&ic->i_recv_mutex); - if (rds_conn_up(conn)) rds_ib_attempt_ack(ic); return ret; } -int __init rds_ib_recv_init(void) +int rds_ib_recv_init(void) { struct sysinfo si; int ret = -ENOMEM; @@ -939,14 +1054,14 @@ int __init rds_ib_recv_init(void) rds_ib_incoming_slab = kmem_cache_create("rds_ib_incoming", sizeof(struct rds_ib_incoming), - 0, 0, NULL); - if (rds_ib_incoming_slab == NULL) + 0, SLAB_HWCACHE_ALIGN, NULL); + if (!rds_ib_incoming_slab) goto out; rds_ib_frag_slab = kmem_cache_create("rds_ib_frag", sizeof(struct rds_page_frag), - 0, 0, NULL); - if (rds_ib_frag_slab == NULL) + 0, SLAB_HWCACHE_ALIGN, NULL); + if (!rds_ib_frag_slab) kmem_cache_destroy(rds_ib_incoming_slab); else ret = 0; diff --git a/net/rds/ib_send.c b/net/rds/ib_send.c index 17fa80803ab01ccbd0fa1279ed448c1bd51d501d..71f373c421bc4d8b6a97f2be7201a2dc8c2290e8 100644 --- a/net/rds/ib_send.c +++ b/net/rds/ib_send.c @@ -36,11 +36,49 @@ #include #include "rds.h" -#include "rdma.h" #include "ib.h" -static void rds_ib_send_rdma_complete(struct rds_message *rm, - int wc_status) +static char *rds_ib_wc_status_strings[] = { +#define RDS_IB_WC_STATUS_STR(foo) \ + [IB_WC_##foo] = __stringify(IB_WC_##foo) + RDS_IB_WC_STATUS_STR(SUCCESS), + RDS_IB_WC_STATUS_STR(LOC_LEN_ERR), + RDS_IB_WC_STATUS_STR(LOC_QP_OP_ERR), + RDS_IB_WC_STATUS_STR(LOC_EEC_OP_ERR), + RDS_IB_WC_STATUS_STR(LOC_PROT_ERR), + RDS_IB_WC_STATUS_STR(WR_FLUSH_ERR), + RDS_IB_WC_STATUS_STR(MW_BIND_ERR), + RDS_IB_WC_STATUS_STR(BAD_RESP_ERR), + RDS_IB_WC_STATUS_STR(LOC_ACCESS_ERR), + RDS_IB_WC_STATUS_STR(REM_INV_REQ_ERR), + RDS_IB_WC_STATUS_STR(REM_ACCESS_ERR), + RDS_IB_WC_STATUS_STR(REM_OP_ERR), + RDS_IB_WC_STATUS_STR(RETRY_EXC_ERR), + RDS_IB_WC_STATUS_STR(RNR_RETRY_EXC_ERR), + RDS_IB_WC_STATUS_STR(LOC_RDD_VIOL_ERR), + RDS_IB_WC_STATUS_STR(REM_INV_RD_REQ_ERR), + RDS_IB_WC_STATUS_STR(REM_ABORT_ERR), + RDS_IB_WC_STATUS_STR(INV_EECN_ERR), + RDS_IB_WC_STATUS_STR(INV_EEC_STATE_ERR), + RDS_IB_WC_STATUS_STR(FATAL_ERR), + RDS_IB_WC_STATUS_STR(RESP_TIMEOUT_ERR), + RDS_IB_WC_STATUS_STR(GENERAL_ERR), +#undef RDS_IB_WC_STATUS_STR +}; + +char *rds_ib_wc_status_str(enum ib_wc_status status) +{ + return rds_str_array(rds_ib_wc_status_strings, + ARRAY_SIZE(rds_ib_wc_status_strings), status); +} + +/* + * Convert IB-specific error message to RDS error message and call core + * completion handler. + */ +static void rds_ib_send_complete(struct rds_message *rm, + int wc_status, + void (*complete)(struct rds_message *rm, int status)) { int notify_status; @@ -60,69 +98,125 @@ static void rds_ib_send_rdma_complete(struct rds_message *rm, notify_status = RDS_RDMA_OTHER_ERROR; break; } - rds_rdma_send_complete(rm, notify_status); + complete(rm, notify_status); +} + +static void rds_ib_send_unmap_data(struct rds_ib_connection *ic, + struct rm_data_op *op, + int wc_status) +{ + if (op->op_nents) + ib_dma_unmap_sg(ic->i_cm_id->device, + op->op_sg, op->op_nents, + DMA_TO_DEVICE); } static void rds_ib_send_unmap_rdma(struct rds_ib_connection *ic, - struct rds_rdma_op *op) + struct rm_rdma_op *op, + int wc_status) { - if (op->r_mapped) { + if (op->op_mapped) { ib_dma_unmap_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, - op->r_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - op->r_mapped = 0; + op->op_sg, op->op_nents, + op->op_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + op->op_mapped = 0; } + + /* If the user asked for a completion notification on this + * message, we can implement three different semantics: + * 1. Notify when we received the ACK on the RDS message + * that was queued with the RDMA. This provides reliable + * notification of RDMA status at the expense of a one-way + * packet delay. + * 2. Notify when the IB stack gives us the completion event for + * the RDMA operation. + * 3. Notify when the IB stack gives us the completion event for + * the accompanying RDS messages. + * Here, we implement approach #3. To implement approach #2, + * we would need to take an event for the rdma WR. To implement #1, + * don't call rds_rdma_send_complete at all, and fall back to the notify + * handling in the ACK processing code. + * + * Note: There's no need to explicitly sync any RDMA buffers using + * ib_dma_sync_sg_for_cpu - the completion for the RDMA + * operation itself unmapped the RDMA buffers, which takes care + * of synching. + */ + rds_ib_send_complete(container_of(op, struct rds_message, rdma), + wc_status, rds_rdma_send_complete); + + if (op->op_write) + rds_stats_add(s_send_rdma_bytes, op->op_bytes); + else + rds_stats_add(s_recv_rdma_bytes, op->op_bytes); } -static void rds_ib_send_unmap_rm(struct rds_ib_connection *ic, - struct rds_ib_send_work *send, - int wc_status) +static void rds_ib_send_unmap_atomic(struct rds_ib_connection *ic, + struct rm_atomic_op *op, + int wc_status) { - struct rds_message *rm = send->s_rm; - - rdsdebug("ic %p send %p rm %p\n", ic, send, rm); - - ib_dma_unmap_sg(ic->i_cm_id->device, - rm->m_sg, rm->m_nents, - DMA_TO_DEVICE); - - if (rm->m_rdma_op != NULL) { - rds_ib_send_unmap_rdma(ic, rm->m_rdma_op); - - /* If the user asked for a completion notification on this - * message, we can implement three different semantics: - * 1. Notify when we received the ACK on the RDS message - * that was queued with the RDMA. This provides reliable - * notification of RDMA status at the expense of a one-way - * packet delay. - * 2. Notify when the IB stack gives us the completion event for - * the RDMA operation. - * 3. Notify when the IB stack gives us the completion event for - * the accompanying RDS messages. - * Here, we implement approach #3. To implement approach #2, - * call rds_rdma_send_complete from the cq_handler. To implement #1, - * don't call rds_rdma_send_complete at all, and fall back to the notify - * handling in the ACK processing code. - * - * Note: There's no need to explicitly sync any RDMA buffers using - * ib_dma_sync_sg_for_cpu - the completion for the RDMA - * operation itself unmapped the RDMA buffers, which takes care - * of synching. - */ - rds_ib_send_rdma_complete(rm, wc_status); + /* unmap atomic recvbuf */ + if (op->op_mapped) { + ib_dma_unmap_sg(ic->i_cm_id->device, op->op_sg, 1, + DMA_FROM_DEVICE); + op->op_mapped = 0; + } - if (rm->m_rdma_op->r_write) - rds_stats_add(s_send_rdma_bytes, rm->m_rdma_op->r_bytes); - else - rds_stats_add(s_recv_rdma_bytes, rm->m_rdma_op->r_bytes); + rds_ib_send_complete(container_of(op, struct rds_message, atomic), + wc_status, rds_atomic_send_complete); + + if (op->op_type == RDS_ATOMIC_TYPE_CSWP) + rds_ib_stats_inc(s_ib_atomic_cswp); + else + rds_ib_stats_inc(s_ib_atomic_fadd); +} + +/* + * Unmap the resources associated with a struct send_work. + * + * Returns the rm for no good reason other than it is unobtainable + * other than by switching on wr.opcode, currently, and the caller, + * the event handler, needs it. + */ +static struct rds_message *rds_ib_send_unmap_op(struct rds_ib_connection *ic, + struct rds_ib_send_work *send, + int wc_status) +{ + struct rds_message *rm = NULL; + + /* In the error case, wc.opcode sometimes contains garbage */ + switch (send->s_wr.opcode) { + case IB_WR_SEND: + if (send->s_op) { + rm = container_of(send->s_op, struct rds_message, data); + rds_ib_send_unmap_data(ic, send->s_op, wc_status); + } + break; + case IB_WR_RDMA_WRITE: + case IB_WR_RDMA_READ: + if (send->s_op) { + rm = container_of(send->s_op, struct rds_message, rdma); + rds_ib_send_unmap_rdma(ic, send->s_op, wc_status); + } + break; + case IB_WR_ATOMIC_FETCH_AND_ADD: + case IB_WR_ATOMIC_CMP_AND_SWP: + if (send->s_op) { + rm = container_of(send->s_op, struct rds_message, atomic); + rds_ib_send_unmap_atomic(ic, send->s_op, wc_status); + } + break; + default: + if (printk_ratelimit()) + printk(KERN_NOTICE + "RDS/IB: %s: unexpected opcode 0x%x in WR!\n", + __func__, send->s_wr.opcode); + break; } - /* If anyone waited for this message to get flushed out, wake - * them up now */ - rds_message_unmapped(rm); + send->s_wr.opcode = 0xdead; - rds_message_put(rm); - send->s_rm = NULL; + return rm; } void rds_ib_send_init_ring(struct rds_ib_connection *ic) @@ -133,23 +227,18 @@ void rds_ib_send_init_ring(struct rds_ib_connection *ic) for (i = 0, send = ic->i_sends; i < ic->i_send_ring.w_nr; i++, send++) { struct ib_sge *sge; - send->s_rm = NULL; send->s_op = NULL; send->s_wr.wr_id = i; send->s_wr.sg_list = send->s_sge; - send->s_wr.num_sge = 1; - send->s_wr.opcode = IB_WR_SEND; - send->s_wr.send_flags = 0; send->s_wr.ex.imm_data = 0; - sge = rds_ib_data_sge(ic, send->s_sge); - sge->lkey = ic->i_mr->lkey; - - sge = rds_ib_header_sge(ic, send->s_sge); + sge = &send->s_sge[0]; sge->addr = ic->i_send_hdrs_dma + (i * sizeof(struct rds_header)); sge->length = sizeof(struct rds_header); sge->lkey = ic->i_mr->lkey; + + send->s_sge[1].lkey = ic->i_mr->lkey; } } @@ -159,15 +248,23 @@ void rds_ib_send_clear_ring(struct rds_ib_connection *ic) u32 i; for (i = 0, send = ic->i_sends; i < ic->i_send_ring.w_nr; i++, send++) { - if (send->s_wr.opcode == 0xdead) - continue; - if (send->s_rm) - rds_ib_send_unmap_rm(ic, send, IB_WC_WR_FLUSH_ERR); - if (send->s_op) - rds_ib_send_unmap_rdma(ic, send->s_op); + if (send->s_op && send->s_wr.opcode != 0xdead) + rds_ib_send_unmap_op(ic, send, IB_WC_WR_FLUSH_ERR); } } +/* + * The only fast path caller always has a non-zero nr, so we don't + * bother testing nr before performing the atomic sub. + */ +static void rds_ib_sub_signaled(struct rds_ib_connection *ic, int nr) +{ + if ((atomic_sub_return(nr, &ic->i_signaled_sends) == 0) && + waitqueue_active(&rds_ib_ring_empty_wait)) + wake_up(&rds_ib_ring_empty_wait); + BUG_ON(atomic_read(&ic->i_signaled_sends) < 0); +} + /* * The _oldest/_free ring operations here race cleanly with the alloc/unalloc * operations performed in the send path. As the sender allocs and potentially @@ -178,12 +275,14 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) { struct rds_connection *conn = context; struct rds_ib_connection *ic = conn->c_transport_data; + struct rds_message *rm = NULL; struct ib_wc wc; struct rds_ib_send_work *send; u32 completed; u32 oldest; u32 i = 0; int ret; + int nr_sig = 0; rdsdebug("cq %p conn %p\n", cq, conn); rds_ib_stats_inc(s_ib_tx_cq_call); @@ -192,8 +291,9 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) rdsdebug("ib_req_notify_cq send failed: %d\n", ret); while (ib_poll_cq(cq, 1, &wc) > 0) { - rdsdebug("wc wr_id 0x%llx status %u byte_len %u imm_data %u\n", - (unsigned long long)wc.wr_id, wc.status, wc.byte_len, + rdsdebug("wc wr_id 0x%llx status %u (%s) byte_len %u imm_data %u\n", + (unsigned long long)wc.wr_id, wc.status, + rds_ib_wc_status_str(wc.status), wc.byte_len, be32_to_cpu(wc.ex.imm_data)); rds_ib_stats_inc(s_ib_tx_cq_event); @@ -210,51 +310,30 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) for (i = 0; i < completed; i++) { send = &ic->i_sends[oldest]; + if (send->s_wr.send_flags & IB_SEND_SIGNALED) + nr_sig++; - /* In the error case, wc.opcode sometimes contains garbage */ - switch (send->s_wr.opcode) { - case IB_WR_SEND: - if (send->s_rm) - rds_ib_send_unmap_rm(ic, send, wc.status); - break; - case IB_WR_RDMA_WRITE: - case IB_WR_RDMA_READ: - /* Nothing to be done - the SG list will be unmapped - * when the SEND completes. */ - break; - default: - if (printk_ratelimit()) - printk(KERN_NOTICE - "RDS/IB: %s: unexpected opcode 0x%x in WR!\n", - __func__, send->s_wr.opcode); - break; - } + rm = rds_ib_send_unmap_op(ic, send, wc.status); - send->s_wr.opcode = 0xdead; - send->s_wr.num_sge = 1; if (send->s_queued + HZ/2 < jiffies) rds_ib_stats_inc(s_ib_tx_stalled); - /* If a RDMA operation produced an error, signal this right - * away. If we don't, the subsequent SEND that goes with this - * RDMA will be canceled with ERR_WFLUSH, and the application - * never learn that the RDMA failed. */ - if (unlikely(wc.status == IB_WC_REM_ACCESS_ERR && send->s_op)) { - struct rds_message *rm; - - rm = rds_send_get_message(conn, send->s_op); - if (rm) { - if (rm->m_rdma_op) - rds_ib_send_unmap_rdma(ic, rm->m_rdma_op); - rds_ib_send_rdma_complete(rm, wc.status); - rds_message_put(rm); + if (send->s_op) { + if (send->s_op == rm->m_final_op) { + /* If anyone waited for this message to get flushed out, wake + * them up now */ + rds_message_unmapped(rm); } + rds_message_put(rm); + send->s_op = NULL; } oldest = (oldest + 1) % ic->i_send_ring.w_nr; } rds_ib_ring_free(&ic->i_send_ring, completed); + rds_ib_sub_signaled(ic, nr_sig); + nr_sig = 0; if (test_and_clear_bit(RDS_LL_SEND_FULL, &conn->c_flags) || test_bit(0, &conn->c_map_queued)) @@ -262,10 +341,10 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) /* We expect errors as the qp is drained during shutdown */ if (wc.status != IB_WC_SUCCESS && rds_conn_up(conn)) { - rds_ib_conn_error(conn, - "send completion on %pI4 " - "had status %u, disconnecting and reconnecting\n", - &conn->c_faddr, wc.status); + rds_ib_conn_error(conn, "send completion on %pI4 had status " + "%u (%s), disconnecting and reconnecting\n", + &conn->c_faddr, wc.status, + rds_ib_wc_status_str(wc.status)); } } } @@ -294,7 +373,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context) * credits (see rds_ib_send_add_credits below). * * The RDS send code is essentially single-threaded; rds_send_xmit - * grabs c_send_lock to ensure exclusive access to the send ring. + * sets RDS_IN_XMIT to ensure exclusive access to the send ring. * However, the ACK sending code is independent and can race with * message SENDs. * @@ -413,40 +492,21 @@ void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted) set_bit(IB_ACK_REQUESTED, &ic->i_ack_flags); } -static inline void -rds_ib_xmit_populate_wr(struct rds_ib_connection *ic, - struct rds_ib_send_work *send, unsigned int pos, - unsigned long buffer, unsigned int length, - int send_flags) +static inline int rds_ib_set_wr_signal_state(struct rds_ib_connection *ic, + struct rds_ib_send_work *send, + bool notify) { - struct ib_sge *sge; - - WARN_ON(pos != send - ic->i_sends); - - send->s_wr.send_flags = send_flags; - send->s_wr.opcode = IB_WR_SEND; - send->s_wr.num_sge = 2; - send->s_wr.next = NULL; - send->s_queued = jiffies; - send->s_op = NULL; - - if (length != 0) { - sge = rds_ib_data_sge(ic, send->s_sge); - sge->addr = buffer; - sge->length = length; - sge->lkey = ic->i_mr->lkey; - - sge = rds_ib_header_sge(ic, send->s_sge); - } else { - /* We're sending a packet with no payload. There is only - * one SGE */ - send->s_wr.num_sge = 1; - sge = &send->s_sge[0]; + /* + * We want to delay signaling completions just enough to get + * the batching benefits but not so much that we create dead time + * on the wire. + */ + if (ic->i_unsignaled_wrs-- == 0 || notify) { + ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; + send->s_wr.send_flags |= IB_SEND_SIGNALED; + return 1; } - - sge->addr = ic->i_send_hdrs_dma + (pos * sizeof(struct rds_header)); - sge->length = sizeof(struct rds_header); - sge->lkey = ic->i_mr->lkey; + return 0; } /* @@ -475,13 +535,14 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, u32 pos; u32 i; u32 work_alloc; - u32 credit_alloc; + u32 credit_alloc = 0; u32 posted; u32 adv_credits = 0; int send_flags = 0; - int sent; + int bytes_sent = 0; int ret; int flow_controlled = 0; + int nr_sig = 0; BUG_ON(off % RDS_FRAG_SIZE); BUG_ON(hdr_off != 0 && hdr_off != sizeof(struct rds_header)); @@ -507,14 +568,13 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, goto out; } - credit_alloc = work_alloc; if (ic->i_flowctl) { credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT); adv_credits += posted; if (credit_alloc < work_alloc) { rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc); work_alloc = credit_alloc; - flow_controlled++; + flow_controlled = 1; } if (work_alloc == 0) { set_bit(RDS_LL_SEND_FULL, &conn->c_flags); @@ -525,31 +585,25 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, } /* map the message the first time we see it */ - if (ic->i_rm == NULL) { - /* - printk(KERN_NOTICE "rds_ib_xmit prep msg dport=%u flags=0x%x len=%d\n", - be16_to_cpu(rm->m_inc.i_hdr.h_dport), - rm->m_inc.i_hdr.h_flags, - be32_to_cpu(rm->m_inc.i_hdr.h_len)); - */ - if (rm->m_nents) { - rm->m_count = ib_dma_map_sg(dev, - rm->m_sg, rm->m_nents, DMA_TO_DEVICE); - rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->m_count); - if (rm->m_count == 0) { + if (!ic->i_data_op) { + if (rm->data.op_nents) { + rm->data.op_count = ib_dma_map_sg(dev, + rm->data.op_sg, + rm->data.op_nents, + DMA_TO_DEVICE); + rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.op_count); + if (rm->data.op_count == 0) { rds_ib_stats_inc(s_ib_tx_sg_mapping_failure); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); ret = -ENOMEM; /* XXX ? */ goto out; } } else { - rm->m_count = 0; + rm->data.op_count = 0; } - ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; - ic->i_unsignaled_bytes = rds_ib_sysctl_max_unsig_bytes; rds_message_addref(rm); - ic->i_rm = rm; + ic->i_data_op = &rm->data; /* Finalize the header */ if (test_bit(RDS_MSG_ACK_REQUIRED, &rm->m_flags)) @@ -559,10 +613,10 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* If it has a RDMA op, tell the peer we did it. This is * used by the peer to release use-once RDMA MRs. */ - if (rm->m_rdma_op) { + if (rm->rdma.op_active) { struct rds_ext_header_rdma ext_hdr; - ext_hdr.h_rdma_rkey = cpu_to_be32(rm->m_rdma_op->r_key); + ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.op_rkey); rds_message_add_extension(&rm->m_inc.i_hdr, RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr)); } @@ -582,99 +636,77 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, /* * Update adv_credits since we reset the ACK_REQUIRED bit. */ - rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits); - adv_credits += posted; - BUG_ON(adv_credits > 255); + if (ic->i_flowctl) { + rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits); + adv_credits += posted; + BUG_ON(adv_credits > 255); + } } - send = &ic->i_sends[pos]; - first = send; - prev = NULL; - scat = &rm->m_sg[sg]; - sent = 0; - i = 0; - /* Sometimes you want to put a fence between an RDMA * READ and the following SEND. * We could either do this all the time * or when requested by the user. Right now, we let * the application choose. */ - if (rm->m_rdma_op && rm->m_rdma_op->r_fence) + if (rm->rdma.op_active && rm->rdma.op_fence) send_flags = IB_SEND_FENCE; - /* - * We could be copying the header into the unused tail of the page. - * That would need to be changed in the future when those pages might - * be mapped userspace pages or page cache pages. So instead we always - * use a second sge and our long-lived ring of mapped headers. We send - * the header after the data so that the data payload can be aligned on - * the receiver. - */ + /* Each frag gets a header. Msgs may be 0 bytes */ + send = &ic->i_sends[pos]; + first = send; + prev = NULL; + scat = &ic->i_data_op->op_sg[sg]; + i = 0; + do { + unsigned int len = 0; - /* handle a 0-len message */ - if (be32_to_cpu(rm->m_inc.i_hdr.h_len) == 0) { - rds_ib_xmit_populate_wr(ic, send, pos, 0, 0, send_flags); - goto add_header; - } + /* Set up the header */ + send->s_wr.send_flags = send_flags; + send->s_wr.opcode = IB_WR_SEND; + send->s_wr.num_sge = 1; + send->s_wr.next = NULL; + send->s_queued = jiffies; + send->s_op = NULL; - /* if there's data reference it with a chain of work reqs */ - for (; i < work_alloc && scat != &rm->m_sg[rm->m_count]; i++) { - unsigned int len; + send->s_sge[0].addr = ic->i_send_hdrs_dma + + (pos * sizeof(struct rds_header)); + send->s_sge[0].length = sizeof(struct rds_header); - send = &ic->i_sends[pos]; + memcpy(&ic->i_send_hdrs[pos], &rm->m_inc.i_hdr, sizeof(struct rds_header)); - len = min(RDS_FRAG_SIZE, ib_sg_dma_len(dev, scat) - off); - rds_ib_xmit_populate_wr(ic, send, pos, - ib_sg_dma_address(dev, scat) + off, len, - send_flags); + /* Set up the data, if present */ + if (i < work_alloc + && scat != &rm->data.op_sg[rm->data.op_count]) { + len = min(RDS_FRAG_SIZE, ib_sg_dma_len(dev, scat) - off); + send->s_wr.num_sge = 2; - /* - * We want to delay signaling completions just enough to get - * the batching benefits but not so much that we create dead time - * on the wire. - */ - if (ic->i_unsignaled_wrs-- == 0) { - ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; - send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; - } + send->s_sge[1].addr = ib_sg_dma_address(dev, scat) + off; + send->s_sge[1].length = len; - ic->i_unsignaled_bytes -= len; - if (ic->i_unsignaled_bytes <= 0) { - ic->i_unsignaled_bytes = rds_ib_sysctl_max_unsig_bytes; - send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; + bytes_sent += len; + off += len; + if (off == ib_sg_dma_len(dev, scat)) { + scat++; + off = 0; + } } + rds_ib_set_wr_signal_state(ic, send, 0); + /* * Always signal the last one if we're stopping due to flow control. */ - if (flow_controlled && i == (work_alloc-1)) + if (ic->i_flowctl && flow_controlled && i == (work_alloc-1)) send->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; + if (send->s_wr.send_flags & IB_SEND_SIGNALED) + nr_sig++; + rdsdebug("send %p wr %p num_sge %u next %p\n", send, &send->s_wr, send->s_wr.num_sge, send->s_wr.next); - sent += len; - off += len; - if (off == ib_sg_dma_len(dev, scat)) { - scat++; - off = 0; - } - -add_header: - /* Tack on the header after the data. The header SGE should already - * have been set up to point to the right header buffer. */ - memcpy(&ic->i_send_hdrs[pos], &rm->m_inc.i_hdr, sizeof(struct rds_header)); - - if (0) { - struct rds_header *hdr = &ic->i_send_hdrs[pos]; - - printk(KERN_NOTICE "send WR dport=%u flags=0x%x len=%d\n", - be16_to_cpu(hdr->h_dport), - hdr->h_flags, - be32_to_cpu(hdr->h_len)); - } - if (adv_credits) { + if (ic->i_flowctl && adv_credits) { struct rds_header *hdr = &ic->i_send_hdrs[pos]; /* add credit and redo the header checksum */ @@ -689,20 +721,25 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, prev = send; pos = (pos + 1) % ic->i_send_ring.w_nr; - } + send = &ic->i_sends[pos]; + i++; + + } while (i < work_alloc + && scat != &rm->data.op_sg[rm->data.op_count]); /* Account the RDS header in the number of bytes we sent, but just once. * The caller has no concept of fragmentation. */ if (hdr_off == 0) - sent += sizeof(struct rds_header); + bytes_sent += sizeof(struct rds_header); /* if we finished the message then send completion owns it */ - if (scat == &rm->m_sg[rm->m_count]) { - prev->s_rm = ic->i_rm; - prev->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; - ic->i_rm = NULL; + if (scat == &rm->data.op_sg[rm->data.op_count]) { + prev->s_op = ic->i_data_op; + prev->s_wr.send_flags |= IB_SEND_SOLICITED; + ic->i_data_op = NULL; } + /* Put back wrs & credits we didn't use */ if (i < work_alloc) { rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - i); work_alloc = i; @@ -710,6 +747,9 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, if (ic->i_flowctl && i < credit_alloc) rds_ib_send_add_credits(conn, credit_alloc - i); + if (nr_sig) + atomic_add(nr_sig, &ic->i_signaled_sends); + /* XXX need to worry about failed_wr and partial sends. */ failed_wr = &first->s_wr; ret = ib_post_send(ic->i_cm_id->qp, &first->s_wr, &failed_wr); @@ -720,32 +760,127 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm, printk(KERN_WARNING "RDS/IB: ib_post_send to %pI4 " "returned %d\n", &conn->c_faddr, ret); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); - if (prev->s_rm) { - ic->i_rm = prev->s_rm; - prev->s_rm = NULL; + rds_ib_sub_signaled(ic, nr_sig); + if (prev->s_op) { + ic->i_data_op = prev->s_op; + prev->s_op = NULL; } rds_ib_conn_error(ic->conn, "ib_post_send failed\n"); goto out; } - ret = sent; + ret = bytes_sent; out: BUG_ON(adv_credits); return ret; } -int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) +/* + * Issue atomic operation. + * A simplified version of the rdma case, we always map 1 SG, and + * only 8 bytes, for the return value from the atomic operation. + */ +int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op) +{ + struct rds_ib_connection *ic = conn->c_transport_data; + struct rds_ib_send_work *send = NULL; + struct ib_send_wr *failed_wr; + struct rds_ib_device *rds_ibdev; + u32 pos; + u32 work_alloc; + int ret; + int nr_sig = 0; + + rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); + + work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, 1, &pos); + if (work_alloc != 1) { + rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_stats_inc(s_ib_tx_ring_full); + ret = -ENOMEM; + goto out; + } + + /* address of send request in ring */ + send = &ic->i_sends[pos]; + send->s_queued = jiffies; + + if (op->op_type == RDS_ATOMIC_TYPE_CSWP) { + send->s_wr.opcode = IB_WR_MASKED_ATOMIC_CMP_AND_SWP; + send->s_wr.wr.atomic.compare_add = op->op_m_cswp.compare; + send->s_wr.wr.atomic.swap = op->op_m_cswp.swap; + send->s_wr.wr.atomic.compare_add_mask = op->op_m_cswp.compare_mask; + send->s_wr.wr.atomic.swap_mask = op->op_m_cswp.swap_mask; + } else { /* FADD */ + send->s_wr.opcode = IB_WR_MASKED_ATOMIC_FETCH_AND_ADD; + send->s_wr.wr.atomic.compare_add = op->op_m_fadd.add; + send->s_wr.wr.atomic.swap = 0; + send->s_wr.wr.atomic.compare_add_mask = op->op_m_fadd.nocarry_mask; + send->s_wr.wr.atomic.swap_mask = 0; + } + nr_sig = rds_ib_set_wr_signal_state(ic, send, op->op_notify); + send->s_wr.num_sge = 1; + send->s_wr.next = NULL; + send->s_wr.wr.atomic.remote_addr = op->op_remote_addr; + send->s_wr.wr.atomic.rkey = op->op_rkey; + send->s_op = op; + rds_message_addref(container_of(send->s_op, struct rds_message, atomic)); + + /* map 8 byte retval buffer to the device */ + ret = ib_dma_map_sg(ic->i_cm_id->device, op->op_sg, 1, DMA_FROM_DEVICE); + rdsdebug("ic %p mapping atomic op %p. mapped %d pg\n", ic, op, ret); + if (ret != 1) { + rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_stats_inc(s_ib_tx_sg_mapping_failure); + ret = -ENOMEM; /* XXX ? */ + goto out; + } + + /* Convert our struct scatterlist to struct ib_sge */ + send->s_sge[0].addr = ib_sg_dma_address(ic->i_cm_id->device, op->op_sg); + send->s_sge[0].length = ib_sg_dma_len(ic->i_cm_id->device, op->op_sg); + send->s_sge[0].lkey = ic->i_mr->lkey; + + rdsdebug("rva %Lx rpa %Lx len %u\n", op->op_remote_addr, + send->s_sge[0].addr, send->s_sge[0].length); + + if (nr_sig) + atomic_add(nr_sig, &ic->i_signaled_sends); + + failed_wr = &send->s_wr; + ret = ib_post_send(ic->i_cm_id->qp, &send->s_wr, &failed_wr); + rdsdebug("ic %p send %p (wr %p) ret %d wr %p\n", ic, + send, &send->s_wr, ret, failed_wr); + BUG_ON(failed_wr != &send->s_wr); + if (ret) { + printk(KERN_WARNING "RDS/IB: atomic ib_post_send to %pI4 " + "returned %d\n", &conn->c_faddr, ret); + rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_sub_signaled(ic, nr_sig); + goto out; + } + + if (unlikely(failed_wr != &send->s_wr)) { + printk(KERN_WARNING "RDS/IB: atomic ib_post_send() rc=%d, but failed_wqe updated!\n", ret); + BUG_ON(failed_wr != &send->s_wr); + } + +out: + return ret; +} + +int rds_ib_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) { struct rds_ib_connection *ic = conn->c_transport_data; struct rds_ib_send_work *send = NULL; struct rds_ib_send_work *first; struct rds_ib_send_work *prev; struct ib_send_wr *failed_wr; - struct rds_ib_device *rds_ibdev; struct scatterlist *scat; unsigned long len; - u64 remote_addr = op->r_remote_addr; + u64 remote_addr = op->op_remote_addr; + u32 max_sge = ic->rds_ibdev->max_sge; u32 pos; u32 work_alloc; u32 i; @@ -753,29 +888,28 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) int sent; int ret; int num_sge; - - rds_ibdev = ib_get_client_data(ic->i_cm_id->device, &rds_ib_client); - - /* map the message the first time we see it */ - if (!op->r_mapped) { - op->r_count = ib_dma_map_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, (op->r_write) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE); - rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->r_count); - if (op->r_count == 0) { + int nr_sig = 0; + + /* map the op the first time we see it */ + if (!op->op_mapped) { + op->op_count = ib_dma_map_sg(ic->i_cm_id->device, + op->op_sg, op->op_nents, (op->op_write) ? + DMA_TO_DEVICE : DMA_FROM_DEVICE); + rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->op_count); + if (op->op_count == 0) { rds_ib_stats_inc(s_ib_tx_sg_mapping_failure); ret = -ENOMEM; /* XXX ? */ goto out; } - op->r_mapped = 1; + op->op_mapped = 1; } /* * Instead of knowing how to return a partial rdma read/write we insist that there * be enough work requests to send the entire message. */ - i = ceil(op->r_count, rds_ibdev->max_sge); + i = ceil(op->op_count, max_sge); work_alloc = rds_ib_ring_alloc(&ic->i_send_ring, i, &pos); if (work_alloc != i) { @@ -788,30 +922,24 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) send = &ic->i_sends[pos]; first = send; prev = NULL; - scat = &op->r_sg[0]; + scat = &op->op_sg[0]; sent = 0; - num_sge = op->r_count; + num_sge = op->op_count; - for (i = 0; i < work_alloc && scat != &op->r_sg[op->r_count]; i++) { + for (i = 0; i < work_alloc && scat != &op->op_sg[op->op_count]; i++) { send->s_wr.send_flags = 0; send->s_queued = jiffies; - /* - * We want to delay signaling completions just enough to get - * the batching benefits but not so much that we create dead time on the wire. - */ - if (ic->i_unsignaled_wrs-- == 0) { - ic->i_unsignaled_wrs = rds_ib_sysctl_max_unsig_wrs; - send->s_wr.send_flags = IB_SEND_SIGNALED; - } + send->s_op = NULL; + + nr_sig += rds_ib_set_wr_signal_state(ic, send, op->op_notify); - send->s_wr.opcode = op->r_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ; + send->s_wr.opcode = op->op_write ? IB_WR_RDMA_WRITE : IB_WR_RDMA_READ; send->s_wr.wr.rdma.remote_addr = remote_addr; - send->s_wr.wr.rdma.rkey = op->r_key; - send->s_op = op; + send->s_wr.wr.rdma.rkey = op->op_rkey; - if (num_sge > rds_ibdev->max_sge) { - send->s_wr.num_sge = rds_ibdev->max_sge; - num_sge -= rds_ibdev->max_sge; + if (num_sge > max_sge) { + send->s_wr.num_sge = max_sge; + num_sge -= max_sge; } else { send->s_wr.num_sge = num_sge; } @@ -821,7 +949,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) if (prev) prev->s_wr.next = &send->s_wr; - for (j = 0; j < send->s_wr.num_sge && scat != &op->r_sg[op->r_count]; j++) { + for (j = 0; j < send->s_wr.num_sge && scat != &op->op_sg[op->op_count]; j++) { len = ib_sg_dma_len(ic->i_cm_id->device, scat); send->s_sge[j].addr = ib_sg_dma_address(ic->i_cm_id->device, scat); @@ -843,15 +971,20 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) send = ic->i_sends; } - /* if we finished the message then send completion owns it */ - if (scat == &op->r_sg[op->r_count]) - prev->s_wr.send_flags = IB_SEND_SIGNALED; + /* give a reference to the last op */ + if (scat == &op->op_sg[op->op_count]) { + prev->s_op = op; + rds_message_addref(container_of(op, struct rds_message, rdma)); + } if (i < work_alloc) { rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - i); work_alloc = i; } + if (nr_sig) + atomic_add(nr_sig, &ic->i_signaled_sends); + failed_wr = &first->s_wr; ret = ib_post_send(ic->i_cm_id->qp, &first->s_wr, &failed_wr); rdsdebug("ic %p first %p (wr %p) ret %d wr %p\n", ic, @@ -861,6 +994,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) printk(KERN_WARNING "RDS/IB: rdma ib_post_send to %pI4 " "returned %d\n", &conn->c_faddr, ret); rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc); + rds_ib_sub_signaled(ic, nr_sig); goto out; } diff --git a/net/rds/ib_stats.c b/net/rds/ib_stats.c index d2c904dd6fbcb9e1eeb275f84cc062a273bb98ec..2d5965d6e97c039517d219bfdad3f28f7437b1d7 100644 --- a/net/rds/ib_stats.c +++ b/net/rds/ib_stats.c @@ -67,6 +67,8 @@ static const char *const rds_ib_stat_names[] = { "ib_rdma_mr_pool_flush", "ib_rdma_mr_pool_wait", "ib_rdma_mr_pool_depleted", + "ib_atomic_cswp", + "ib_atomic_fadd", }; unsigned int rds_ib_stats_info_copy(struct rds_info_iterator *iter, diff --git a/net/rds/ib_sysctl.c b/net/rds/ib_sysctl.c index 03f01cb4e0fee40487585088b9a6a0b2d9219049..1253b006efdb3b25f2f4bdb5bb3011e0e71fbdf3 100644 --- a/net/rds/ib_sysctl.c +++ b/net/rds/ib_sysctl.c @@ -49,10 +49,6 @@ unsigned long rds_ib_sysctl_max_unsig_wrs = 16; static unsigned long rds_ib_sysctl_max_unsig_wr_min = 1; static unsigned long rds_ib_sysctl_max_unsig_wr_max = 64; -unsigned long rds_ib_sysctl_max_unsig_bytes = (16 << 20); -static unsigned long rds_ib_sysctl_max_unsig_bytes_min = 1; -static unsigned long rds_ib_sysctl_max_unsig_bytes_max = ~0UL; - /* * This sysctl does nothing. * @@ -65,7 +61,7 @@ static unsigned long rds_ib_sysctl_max_unsig_bytes_max = ~0UL; */ unsigned int rds_ib_sysctl_flow_control = 0; -ctl_table rds_ib_sysctl_table[] = { +static ctl_table rds_ib_sysctl_table[] = { { .procname = "max_send_wr", .data = &rds_ib_sysctl_max_send_wr, @@ -93,15 +89,6 @@ ctl_table rds_ib_sysctl_table[] = { .extra1 = &rds_ib_sysctl_max_unsig_wr_min, .extra2 = &rds_ib_sysctl_max_unsig_wr_max, }, - { - .procname = "max_unsignaled_bytes", - .data = &rds_ib_sysctl_max_unsig_bytes, - .maxlen = sizeof(unsigned long), - .mode = 0644, - .proc_handler = proc_doulongvec_minmax, - .extra1 = &rds_ib_sysctl_max_unsig_bytes_min, - .extra2 = &rds_ib_sysctl_max_unsig_bytes_max, - }, { .procname = "max_recv_allocation", .data = &rds_ib_sysctl_max_recv_allocation, @@ -132,10 +119,10 @@ void rds_ib_sysctl_exit(void) unregister_sysctl_table(rds_ib_sysctl_hdr); } -int __init rds_ib_sysctl_init(void) +int rds_ib_sysctl_init(void) { rds_ib_sysctl_hdr = register_sysctl_paths(rds_ib_sysctl_path, rds_ib_sysctl_table); - if (rds_ib_sysctl_hdr == NULL) + if (!rds_ib_sysctl_hdr) return -ENOMEM; return 0; } diff --git a/net/rds/info.c b/net/rds/info.c index c45c4173a44d44eb9ceee633e0cec271f2182411..4fdf1b6e84fff6fd25b2040544245921332b9f89 100644 --- a/net/rds/info.c +++ b/net/rds/info.c @@ -76,7 +76,7 @@ void rds_info_register_func(int optname, rds_info_func func) BUG_ON(optname < RDS_INFO_FIRST || optname > RDS_INFO_LAST); spin_lock(&rds_info_lock); - BUG_ON(rds_info_funcs[offset] != NULL); + BUG_ON(rds_info_funcs[offset]); rds_info_funcs[offset] = func; spin_unlock(&rds_info_lock); } @@ -102,7 +102,7 @@ EXPORT_SYMBOL_GPL(rds_info_deregister_func); */ void rds_info_iter_unmap(struct rds_info_iterator *iter) { - if (iter->addr != NULL) { + if (iter->addr) { kunmap_atomic(iter->addr, KM_USER0); iter->addr = NULL; } @@ -117,7 +117,7 @@ void rds_info_copy(struct rds_info_iterator *iter, void *data, unsigned long this; while (bytes) { - if (iter->addr == NULL) + if (!iter->addr) iter->addr = kmap_atomic(*iter->pages, KM_USER0); this = min(bytes, PAGE_SIZE - iter->offset); @@ -188,7 +188,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval, >> PAGE_SHIFT; pages = kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); - if (pages == NULL) { + if (!pages) { ret = -ENOMEM; goto out; } @@ -206,7 +206,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval, call_func: func = rds_info_funcs[optname - RDS_INFO_FIRST]; - if (func == NULL) { + if (!func) { ret = -ENOPROTOOPT; goto out; } @@ -234,7 +234,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval, ret = -EFAULT; out: - for (i = 0; pages != NULL && i < nr_pages; i++) + for (i = 0; pages && i < nr_pages; i++) put_page(pages[i]); kfree(pages); diff --git a/net/rds/iw.c b/net/rds/iw.c index c8f3d3525cb9b187daeca402f71cb5b88356ce41..5a9676fe594f412215e75c2a4dc44fe3e599d58f 100644 --- a/net/rds/iw.c +++ b/net/rds/iw.c @@ -56,7 +56,7 @@ struct list_head rds_iw_devices; DEFINE_SPINLOCK(iw_nodev_conns_lock); LIST_HEAD(iw_nodev_conns); -void rds_iw_add_one(struct ib_device *device) +static void rds_iw_add_one(struct ib_device *device) { struct rds_iw_device *rds_iwdev; struct ib_device_attr *dev_attr; @@ -124,7 +124,7 @@ void rds_iw_add_one(struct ib_device *device) kfree(dev_attr); } -void rds_iw_remove_one(struct ib_device *device) +static void rds_iw_remove_one(struct ib_device *device) { struct rds_iw_device *rds_iwdev; struct rds_iw_cm_id *i_cm_id, *next; @@ -264,7 +264,6 @@ struct rds_transport rds_iw_transport = { .laddr_check = rds_iw_laddr_check, .xmit_complete = rds_iw_xmit_complete, .xmit = rds_iw_xmit, - .xmit_cong_map = NULL, .xmit_rdma = rds_iw_xmit_rdma, .recv = rds_iw_recv, .conn_alloc = rds_iw_conn_alloc, @@ -272,7 +271,6 @@ struct rds_transport rds_iw_transport = { .conn_connect = rds_iw_conn_connect, .conn_shutdown = rds_iw_conn_shutdown, .inc_copy_to_user = rds_iw_inc_copy_to_user, - .inc_purge = rds_iw_inc_purge, .inc_free = rds_iw_inc_free, .cm_initiate_connect = rds_iw_cm_initiate_connect, .cm_handle_connect = rds_iw_cm_handle_connect, @@ -289,7 +287,7 @@ struct rds_transport rds_iw_transport = { .t_prefer_loopback = 1, }; -int __init rds_iw_init(void) +int rds_iw_init(void) { int ret; diff --git a/net/rds/iw.h b/net/rds/iw.h index eef2f0c2847604078a326df106c09403520410e8..90151922178ca9806ecbd02922f8fe46d6bf727f 100644 --- a/net/rds/iw.h +++ b/net/rds/iw.h @@ -70,7 +70,7 @@ struct rds_iw_send_work { struct rds_message *s_rm; /* We should really put these into a union: */ - struct rds_rdma_op *s_op; + struct rm_rdma_op *s_op; struct rds_iw_mapping *s_mapping; struct ib_mr *s_mr; struct ib_fast_reg_page_list *s_page_list; @@ -268,8 +268,6 @@ static inline u32 rds_iw_local_dma_lkey(struct rds_iw_connection *ic) /* ib.c */ extern struct rds_transport rds_iw_transport; -extern void rds_iw_add_one(struct ib_device *device); -extern void rds_iw_remove_one(struct ib_device *device); extern struct ib_client rds_iw_client; extern unsigned int fastreg_pool_size; @@ -284,7 +282,7 @@ void rds_iw_conn_free(void *arg); int rds_iw_conn_connect(struct rds_connection *conn); void rds_iw_conn_shutdown(struct rds_connection *conn); void rds_iw_state_change(struct sock *sk); -int __init rds_iw_listen_init(void); +int rds_iw_listen_init(void); void rds_iw_listen_stop(void); void __rds_iw_conn_error(struct rds_connection *conn, const char *, ...); int rds_iw_cm_handle_connect(struct rdma_cm_id *cm_id, @@ -318,15 +316,13 @@ void *rds_iw_get_mr(struct scatterlist *sg, unsigned long nents, void rds_iw_sync_mr(void *trans_private, int dir); void rds_iw_free_mr(void *trans_private, int invalidate); void rds_iw_flush_mrs(void); -void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id); /* ib_recv.c */ -int __init rds_iw_recv_init(void); +int rds_iw_recv_init(void); void rds_iw_recv_exit(void); int rds_iw_recv(struct rds_connection *conn); int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, gfp_t page_gfp, int prefill); -void rds_iw_inc_purge(struct rds_incoming *inc); void rds_iw_inc_free(struct rds_incoming *inc); int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, size_t size); @@ -358,7 +354,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context); void rds_iw_send_init_ring(struct rds_iw_connection *ic); void rds_iw_send_clear_ring(struct rds_iw_connection *ic); -int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op); +int rds_iw_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op); void rds_iw_send_add_credits(struct rds_connection *conn, unsigned int credits); void rds_iw_advertise_credits(struct rds_connection *conn, unsigned int posted); int rds_iw_send_grab_credits(struct rds_iw_connection *ic, u32 wanted, @@ -371,7 +367,7 @@ unsigned int rds_iw_stats_info_copy(struct rds_info_iterator *iter, unsigned int avail); /* ib_sysctl.c */ -int __init rds_iw_sysctl_init(void); +int rds_iw_sysctl_init(void); void rds_iw_sysctl_exit(void); extern unsigned long rds_iw_sysctl_max_send_wr; extern unsigned long rds_iw_sysctl_max_recv_wr; @@ -379,7 +375,6 @@ extern unsigned long rds_iw_sysctl_max_unsig_wrs; extern unsigned long rds_iw_sysctl_max_unsig_bytes; extern unsigned long rds_iw_sysctl_max_recv_allocation; extern unsigned int rds_iw_sysctl_flow_control; -extern ctl_table rds_iw_sysctl_table[]; /* * Helper functions for getting/setting the header and data SGEs in diff --git a/net/rds/iw_cm.c b/net/rds/iw_cm.c index b5dd6ac39be86b87afc1bd7761971a11550e572f..712cf2d1f28ef36e3bf567540b036ca41179faaf 100644 --- a/net/rds/iw_cm.c +++ b/net/rds/iw_cm.c @@ -257,7 +257,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn) * the rds_iwdev at all. */ rds_iwdev = ib_get_client_data(dev, &rds_iw_client); - if (rds_iwdev == NULL) { + if (!rds_iwdev) { if (printk_ratelimit()) printk(KERN_NOTICE "RDS/IW: No client_data for device %s\n", dev->name); @@ -292,7 +292,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn) ic->i_send_ring.w_nr * sizeof(struct rds_header), &ic->i_send_hdrs_dma, GFP_KERNEL); - if (ic->i_send_hdrs == NULL) { + if (!ic->i_send_hdrs) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent send failed\n"); goto out; @@ -302,7 +302,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn) ic->i_recv_ring.w_nr * sizeof(struct rds_header), &ic->i_recv_hdrs_dma, GFP_KERNEL); - if (ic->i_recv_hdrs == NULL) { + if (!ic->i_recv_hdrs) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent recv failed\n"); goto out; @@ -310,14 +310,14 @@ static int rds_iw_setup_qp(struct rds_connection *conn) ic->i_ack = ib_dma_alloc_coherent(dev, sizeof(struct rds_header), &ic->i_ack_dma, GFP_KERNEL); - if (ic->i_ack == NULL) { + if (!ic->i_ack) { ret = -ENOMEM; rdsdebug("ib_dma_alloc_coherent ack failed\n"); goto out; } ic->i_sends = vmalloc(ic->i_send_ring.w_nr * sizeof(struct rds_iw_send_work)); - if (ic->i_sends == NULL) { + if (!ic->i_sends) { ret = -ENOMEM; rdsdebug("send allocation failed\n"); goto out; @@ -325,7 +325,7 @@ static int rds_iw_setup_qp(struct rds_connection *conn) rds_iw_send_init_ring(ic); ic->i_recvs = vmalloc(ic->i_recv_ring.w_nr * sizeof(struct rds_iw_recv_work)); - if (ic->i_recvs == NULL) { + if (!ic->i_recvs) { ret = -ENOMEM; rdsdebug("recv allocation failed\n"); goto out; @@ -696,7 +696,7 @@ int rds_iw_conn_alloc(struct rds_connection *conn, gfp_t gfp) /* XXX too lazy? */ ic = kzalloc(sizeof(struct rds_iw_connection), GFP_KERNEL); - if (ic == NULL) + if (!ic) return -ENOMEM; INIT_LIST_HEAD(&ic->iw_node); diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c index 13dc1862d86264288eb0455056d289008d072234..59509e9a9e723813d78d930381dccffc588add00 100644 --- a/net/rds/iw_rdma.c +++ b/net/rds/iw_rdma.c @@ -34,7 +34,6 @@ #include #include "rds.h" -#include "rdma.h" #include "iw.h" @@ -158,7 +157,8 @@ static int rds_iw_add_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id * return 0; } -void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id) +static void rds_iw_remove_cm_id(struct rds_iw_device *rds_iwdev, + struct rdma_cm_id *cm_id) { struct rds_iw_cm_id *i_cm_id; @@ -207,9 +207,9 @@ void rds_iw_add_conn(struct rds_iw_device *rds_iwdev, struct rds_connection *con BUG_ON(list_empty(&ic->iw_node)); list_del(&ic->iw_node); - spin_lock_irq(&rds_iwdev->spinlock); + spin_lock(&rds_iwdev->spinlock); list_add_tail(&ic->iw_node, &rds_iwdev->conn_list); - spin_unlock_irq(&rds_iwdev->spinlock); + spin_unlock(&rds_iwdev->spinlock); spin_unlock_irq(&iw_nodev_conns_lock); ic->rds_iwdev = rds_iwdev; diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c index 3d479067d54dbd02810f9c6b1bf2d373d9388cbf..5e57347f49ff040968067b50ac35283e4463acd7 100644 --- a/net/rds/iw_recv.c +++ b/net/rds/iw_recv.c @@ -53,7 +53,7 @@ static void rds_iw_frag_drop_page(struct rds_page_frag *frag) static void rds_iw_frag_free(struct rds_page_frag *frag) { rdsdebug("frag %p page %p\n", frag, frag->f_page); - BUG_ON(frag->f_page != NULL); + BUG_ON(frag->f_page); kmem_cache_free(rds_iw_frag_slab, frag); } @@ -143,14 +143,14 @@ static int rds_iw_recv_refill_one(struct rds_connection *conn, struct ib_sge *sge; int ret = -ENOMEM; - if (recv->r_iwinc == NULL) { + if (!recv->r_iwinc) { if (!atomic_add_unless(&rds_iw_allocation, 1, rds_iw_sysctl_max_recv_allocation)) { rds_iw_stats_inc(s_iw_rx_alloc_limit); goto out; } recv->r_iwinc = kmem_cache_alloc(rds_iw_incoming_slab, kptr_gfp); - if (recv->r_iwinc == NULL) { + if (!recv->r_iwinc) { atomic_dec(&rds_iw_allocation); goto out; } @@ -158,17 +158,17 @@ static int rds_iw_recv_refill_one(struct rds_connection *conn, rds_inc_init(&recv->r_iwinc->ii_inc, conn, conn->c_faddr); } - if (recv->r_frag == NULL) { + if (!recv->r_frag) { recv->r_frag = kmem_cache_alloc(rds_iw_frag_slab, kptr_gfp); - if (recv->r_frag == NULL) + if (!recv->r_frag) goto out; INIT_LIST_HEAD(&recv->r_frag->f_item); recv->r_frag->f_page = NULL; } - if (ic->i_frag.f_page == NULL) { + if (!ic->i_frag.f_page) { ic->i_frag.f_page = alloc_page(page_gfp); - if (ic->i_frag.f_page == NULL) + if (!ic->i_frag.f_page) goto out; ic->i_frag.f_offset = 0; } @@ -273,7 +273,7 @@ int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp, return ret; } -void rds_iw_inc_purge(struct rds_incoming *inc) +static void rds_iw_inc_purge(struct rds_incoming *inc) { struct rds_iw_incoming *iwinc; struct rds_page_frag *frag; @@ -716,7 +716,7 @@ static void rds_iw_process_recv(struct rds_connection *conn, * into the inc and save the inc so we can hang upcoming fragments * off its list. */ - if (iwinc == NULL) { + if (!iwinc) { iwinc = recv->r_iwinc; recv->r_iwinc = NULL; ic->i_iwinc = iwinc; @@ -887,7 +887,7 @@ int rds_iw_recv(struct rds_connection *conn) return ret; } -int __init rds_iw_recv_init(void) +int rds_iw_recv_init(void) { struct sysinfo si; int ret = -ENOMEM; @@ -899,13 +899,13 @@ int __init rds_iw_recv_init(void) rds_iw_incoming_slab = kmem_cache_create("rds_iw_incoming", sizeof(struct rds_iw_incoming), 0, 0, NULL); - if (rds_iw_incoming_slab == NULL) + if (!rds_iw_incoming_slab) goto out; rds_iw_frag_slab = kmem_cache_create("rds_iw_frag", sizeof(struct rds_page_frag), 0, 0, NULL); - if (rds_iw_frag_slab == NULL) + if (!rds_iw_frag_slab) kmem_cache_destroy(rds_iw_incoming_slab); else ret = 0; diff --git a/net/rds/iw_send.c b/net/rds/iw_send.c index 52182ff7519edcde8b7dee746b72282fe6eb832f..6280ea020d4eb0293b3c76be3a2e8e87920aff49 100644 --- a/net/rds/iw_send.c +++ b/net/rds/iw_send.c @@ -36,7 +36,6 @@ #include #include "rds.h" -#include "rdma.h" #include "iw.h" static void rds_iw_send_rdma_complete(struct rds_message *rm, @@ -64,13 +63,13 @@ static void rds_iw_send_rdma_complete(struct rds_message *rm, } static void rds_iw_send_unmap_rdma(struct rds_iw_connection *ic, - struct rds_rdma_op *op) + struct rm_rdma_op *op) { - if (op->r_mapped) { + if (op->op_mapped) { ib_dma_unmap_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, - op->r_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); - op->r_mapped = 0; + op->op_sg, op->op_nents, + op->op_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + op->op_mapped = 0; } } @@ -83,11 +82,11 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, rdsdebug("ic %p send %p rm %p\n", ic, send, rm); ib_dma_unmap_sg(ic->i_cm_id->device, - rm->m_sg, rm->m_nents, + rm->data.op_sg, rm->data.op_nents, DMA_TO_DEVICE); - if (rm->m_rdma_op != NULL) { - rds_iw_send_unmap_rdma(ic, rm->m_rdma_op); + if (rm->rdma.op_active) { + rds_iw_send_unmap_rdma(ic, &rm->rdma); /* If the user asked for a completion notification on this * message, we can implement three different semantics: @@ -111,10 +110,10 @@ static void rds_iw_send_unmap_rm(struct rds_iw_connection *ic, */ rds_iw_send_rdma_complete(rm, wc_status); - if (rm->m_rdma_op->r_write) - rds_stats_add(s_send_rdma_bytes, rm->m_rdma_op->r_bytes); + if (rm->rdma.op_write) + rds_stats_add(s_send_rdma_bytes, rm->rdma.op_bytes); else - rds_stats_add(s_recv_rdma_bytes, rm->m_rdma_op->r_bytes); + rds_stats_add(s_recv_rdma_bytes, rm->rdma.op_bytes); } /* If anyone waited for this message to get flushed out, wake @@ -556,25 +555,27 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, } /* map the message the first time we see it */ - if (ic->i_rm == NULL) { + if (!ic->i_rm) { /* printk(KERN_NOTICE "rds_iw_xmit prep msg dport=%u flags=0x%x len=%d\n", be16_to_cpu(rm->m_inc.i_hdr.h_dport), rm->m_inc.i_hdr.h_flags, be32_to_cpu(rm->m_inc.i_hdr.h_len)); */ - if (rm->m_nents) { - rm->m_count = ib_dma_map_sg(dev, - rm->m_sg, rm->m_nents, DMA_TO_DEVICE); - rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->m_count); - if (rm->m_count == 0) { + if (rm->data.op_nents) { + rm->data.op_count = ib_dma_map_sg(dev, + rm->data.op_sg, + rm->data.op_nents, + DMA_TO_DEVICE); + rdsdebug("ic %p mapping rm %p: %d\n", ic, rm, rm->data.op_count); + if (rm->data.op_count == 0) { rds_iw_stats_inc(s_iw_tx_sg_mapping_failure); rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc); ret = -ENOMEM; /* XXX ? */ goto out; } } else { - rm->m_count = 0; + rm->data.op_count = 0; } ic->i_unsignaled_wrs = rds_iw_sysctl_max_unsig_wrs; @@ -590,10 +591,10 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, /* If it has a RDMA op, tell the peer we did it. This is * used by the peer to release use-once RDMA MRs. */ - if (rm->m_rdma_op) { + if (rm->rdma.op_active) { struct rds_ext_header_rdma ext_hdr; - ext_hdr.h_rdma_rkey = cpu_to_be32(rm->m_rdma_op->r_key); + ext_hdr.h_rdma_rkey = cpu_to_be32(rm->rdma.op_rkey); rds_message_add_extension(&rm->m_inc.i_hdr, RDS_EXTHDR_RDMA, &ext_hdr, sizeof(ext_hdr)); } @@ -621,7 +622,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, send = &ic->i_sends[pos]; first = send; prev = NULL; - scat = &rm->m_sg[sg]; + scat = &rm->data.op_sg[sg]; sent = 0; i = 0; @@ -631,7 +632,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, * or when requested by the user. Right now, we let * the application choose. */ - if (rm->m_rdma_op && rm->m_rdma_op->r_fence) + if (rm->rdma.op_active && rm->rdma.op_fence) send_flags = IB_SEND_FENCE; /* @@ -650,7 +651,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, } /* if there's data reference it with a chain of work reqs */ - for (; i < work_alloc && scat != &rm->m_sg[rm->m_count]; i++) { + for (; i < work_alloc && scat != &rm->data.op_sg[rm->data.op_count]; i++) { unsigned int len; send = &ic->i_sends[pos]; @@ -728,7 +729,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm, sent += sizeof(struct rds_header); /* if we finished the message then send completion owns it */ - if (scat == &rm->m_sg[rm->m_count]) { + if (scat == &rm->data.op_sg[rm->data.op_count]) { prev->s_rm = ic->i_rm; prev->s_wr.send_flags |= IB_SEND_SIGNALED | IB_SEND_SOLICITED; ic->i_rm = NULL; @@ -784,7 +785,7 @@ static void rds_iw_build_send_fastreg(struct rds_iw_device *rds_iwdev, struct rd ib_update_fast_reg_key(send->s_mr, send->s_remap_count++); } -int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) +int rds_iw_xmit_rdma(struct rds_connection *conn, struct rm_rdma_op *op) { struct rds_iw_connection *ic = conn->c_transport_data; struct rds_iw_send_work *send = NULL; @@ -794,7 +795,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) struct rds_iw_device *rds_iwdev; struct scatterlist *scat; unsigned long len; - u64 remote_addr = op->r_remote_addr; + u64 remote_addr = op->op_remote_addr; u32 pos, fr_pos; u32 work_alloc; u32 i; @@ -806,21 +807,21 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) rds_iwdev = ib_get_client_data(ic->i_cm_id->device, &rds_iw_client); /* map the message the first time we see it */ - if (!op->r_mapped) { - op->r_count = ib_dma_map_sg(ic->i_cm_id->device, - op->r_sg, op->r_nents, (op->r_write) ? - DMA_TO_DEVICE : DMA_FROM_DEVICE); - rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->r_count); - if (op->r_count == 0) { + if (!op->op_mapped) { + op->op_count = ib_dma_map_sg(ic->i_cm_id->device, + op->op_sg, op->op_nents, (op->op_write) ? + DMA_TO_DEVICE : DMA_FROM_DEVICE); + rdsdebug("ic %p mapping op %p: %d\n", ic, op, op->op_count); + if (op->op_count == 0) { rds_iw_stats_inc(s_iw_tx_sg_mapping_failure); ret = -ENOMEM; /* XXX ? */ goto out; } - op->r_mapped = 1; + op->op_mapped = 1; } - if (!op->r_write) { + if (!op->op_write) { /* Alloc space on the send queue for the fastreg */ work_alloc = rds_iw_ring_alloc(&ic->i_send_ring, 1, &fr_pos); if (work_alloc != 1) { @@ -835,7 +836,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) * Instead of knowing how to return a partial rdma read/write we insist that there * be enough work requests to send the entire message. */ - i = ceil(op->r_count, rds_iwdev->max_sge); + i = ceil(op->op_count, rds_iwdev->max_sge); work_alloc = rds_iw_ring_alloc(&ic->i_send_ring, i, &pos); if (work_alloc != i) { @@ -846,17 +847,17 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) } send = &ic->i_sends[pos]; - if (!op->r_write) { + if (!op->op_write) { first = prev = &ic->i_sends[fr_pos]; } else { first = send; prev = NULL; } - scat = &op->r_sg[0]; + scat = &op->op_sg[0]; sent = 0; - num_sge = op->r_count; + num_sge = op->op_count; - for (i = 0; i < work_alloc && scat != &op->r_sg[op->r_count]; i++) { + for (i = 0; i < work_alloc && scat != &op->op_sg[op->op_count]; i++) { send->s_wr.send_flags = 0; send->s_queued = jiffies; @@ -873,13 +874,13 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) * for local access after RDS is finished with it, using * IB_WR_RDMA_READ_WITH_INV will invalidate it after the read has completed. */ - if (op->r_write) + if (op->op_write) send->s_wr.opcode = IB_WR_RDMA_WRITE; else send->s_wr.opcode = IB_WR_RDMA_READ_WITH_INV; send->s_wr.wr.rdma.remote_addr = remote_addr; - send->s_wr.wr.rdma.rkey = op->r_key; + send->s_wr.wr.rdma.rkey = op->op_rkey; send->s_op = op; if (num_sge > rds_iwdev->max_sge) { @@ -893,7 +894,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) if (prev) prev->s_wr.next = &send->s_wr; - for (j = 0; j < send->s_wr.num_sge && scat != &op->r_sg[op->r_count]; j++) { + for (j = 0; j < send->s_wr.num_sge && scat != &op->op_sg[op->op_count]; j++) { len = ib_sg_dma_len(ic->i_cm_id->device, scat); if (send->s_wr.opcode == IB_WR_RDMA_READ_WITH_INV) @@ -927,7 +928,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) } /* if we finished the message then send completion owns it */ - if (scat == &op->r_sg[op->r_count]) + if (scat == &op->op_sg[op->op_count]) first->s_wr.send_flags = IB_SEND_SIGNALED; if (i < work_alloc) { @@ -941,9 +942,9 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op) * adapters do not allow using the lkey for this at all. To bypass this use a * fastreg_mr (or possibly a dma_mr) */ - if (!op->r_write) { + if (!op->op_write) { rds_iw_build_send_fastreg(rds_iwdev, ic, &ic->i_sends[fr_pos], - op->r_count, sent, conn->c_xmit_rm->m_rs->rs_user_addr); + op->op_count, sent, conn->c_xmit_rm->m_rs->rs_user_addr); work_alloc++; } diff --git a/net/rds/iw_sysctl.c b/net/rds/iw_sysctl.c index 1c4428a61a0259baf3c1af1611f23608ffea0c5d..e2e47176e729f5a8c24cb1359335a7412d5e7ea8 100644 --- a/net/rds/iw_sysctl.c +++ b/net/rds/iw_sysctl.c @@ -55,7 +55,7 @@ static unsigned long rds_iw_sysctl_max_unsig_bytes_max = ~0UL; unsigned int rds_iw_sysctl_flow_control = 1; -ctl_table rds_iw_sysctl_table[] = { +static ctl_table rds_iw_sysctl_table[] = { { .procname = "max_send_wr", .data = &rds_iw_sysctl_max_send_wr, @@ -122,10 +122,10 @@ void rds_iw_sysctl_exit(void) unregister_sysctl_table(rds_iw_sysctl_hdr); } -int __init rds_iw_sysctl_init(void) +int rds_iw_sysctl_init(void) { rds_iw_sysctl_hdr = register_sysctl_paths(rds_iw_sysctl_path, rds_iw_sysctl_table); - if (rds_iw_sysctl_hdr == NULL) + if (!rds_iw_sysctl_hdr) return -ENOMEM; return 0; } diff --git a/net/rds/loop.c b/net/rds/loop.c index dd9879379457e29bc9afcb45bacbb58b4ffd092e..c390156b426fc936c6b05fd607f4c32ddb1e3a81 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c @@ -61,10 +61,17 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off) { + /* Do not send cong updates to loopback */ + if (rm->m_inc.i_hdr.h_flags & RDS_FLAG_CONG_BITMAP) { + rds_cong_map_updated(conn->c_fcong, ~(u64) 0); + return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; + } + BUG_ON(hdr_off || sg || off); rds_inc_init(&rm->m_inc, conn, conn->c_laddr); - rds_message_addref(rm); /* for the inc */ + /* For the embedded inc. Matching put is in loop_inc_free() */ + rds_message_addref(rm); rds_recv_incoming(conn, conn->c_laddr, conn->c_faddr, &rm->m_inc, GFP_KERNEL, KM_USER0); @@ -77,16 +84,14 @@ static int rds_loop_xmit(struct rds_connection *conn, struct rds_message *rm, return sizeof(struct rds_header) + be32_to_cpu(rm->m_inc.i_hdr.h_len); } -static int rds_loop_xmit_cong_map(struct rds_connection *conn, - struct rds_cong_map *map, - unsigned long offset) +/* + * See rds_loop_xmit(). Since our inc is embedded in the rm, we + * make sure the rm lives at least until the inc is done. + */ +static void rds_loop_inc_free(struct rds_incoming *inc) { - BUG_ON(offset); - BUG_ON(map != conn->c_lcong); - - rds_cong_map_updated(conn->c_fcong, ~(u64) 0); - - return sizeof(struct rds_header) + RDS_CONG_MAP_BYTES; + struct rds_message *rm = container_of(inc, struct rds_message, m_inc); + rds_message_put(rm); } /* we need to at least give the thread something to succeed */ @@ -112,7 +117,7 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp) unsigned long flags; lc = kzalloc(sizeof(struct rds_loop_connection), GFP_KERNEL); - if (lc == NULL) + if (!lc) return -ENOMEM; INIT_LIST_HEAD(&lc->loop_node); @@ -169,14 +174,12 @@ void rds_loop_exit(void) */ struct rds_transport rds_loop_transport = { .xmit = rds_loop_xmit, - .xmit_cong_map = rds_loop_xmit_cong_map, .recv = rds_loop_recv, .conn_alloc = rds_loop_conn_alloc, .conn_free = rds_loop_conn_free, .conn_connect = rds_loop_conn_connect, .conn_shutdown = rds_loop_conn_shutdown, .inc_copy_to_user = rds_message_inc_copy_to_user, - .inc_purge = rds_message_inc_purge, - .inc_free = rds_message_inc_free, + .inc_free = rds_loop_inc_free, .t_name = "loopback", }; diff --git a/net/rds/message.c b/net/rds/message.c index 9a1d67e001ba60a79608275ecfa3ed452f373b19..a84545dae3709bc0140b65f8acd7648852d89935 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -34,9 +34,6 @@ #include #include "rds.h" -#include "rdma.h" - -static DECLARE_WAIT_QUEUE_HEAD(rds_message_flush_waitq); static unsigned int rds_exthdr_size[__RDS_EXTHDR_MAX] = { [RDS_EXTHDR_NONE] = 0, @@ -63,29 +60,31 @@ static void rds_message_purge(struct rds_message *rm) if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags))) return; - for (i = 0; i < rm->m_nents; i++) { - rdsdebug("putting data page %p\n", (void *)sg_page(&rm->m_sg[i])); + for (i = 0; i < rm->data.op_nents; i++) { + rdsdebug("putting data page %p\n", (void *)sg_page(&rm->data.op_sg[i])); /* XXX will have to put_page for page refs */ - __free_page(sg_page(&rm->m_sg[i])); + __free_page(sg_page(&rm->data.op_sg[i])); } - rm->m_nents = 0; + rm->data.op_nents = 0; - if (rm->m_rdma_op) - rds_rdma_free_op(rm->m_rdma_op); - if (rm->m_rdma_mr) - rds_mr_put(rm->m_rdma_mr); -} + if (rm->rdma.op_active) + rds_rdma_free_op(&rm->rdma); + if (rm->rdma.op_rdma_mr) + rds_mr_put(rm->rdma.op_rdma_mr); -void rds_message_inc_purge(struct rds_incoming *inc) -{ - struct rds_message *rm = container_of(inc, struct rds_message, m_inc); - rds_message_purge(rm); + if (rm->atomic.op_active) + rds_atomic_free_op(&rm->atomic); + if (rm->atomic.op_rdma_mr) + rds_mr_put(rm->atomic.op_rdma_mr); } void rds_message_put(struct rds_message *rm) { rdsdebug("put rm %p ref %d\n", rm, atomic_read(&rm->m_refcount)); - + if (atomic_read(&rm->m_refcount) == 0) { +printk(KERN_CRIT "danger refcount zero on %p\n", rm); +WARN_ON(1); + } if (atomic_dec_and_test(&rm->m_refcount)) { BUG_ON(!list_empty(&rm->m_sock_item)); BUG_ON(!list_empty(&rm->m_conn_item)); @@ -96,12 +95,6 @@ void rds_message_put(struct rds_message *rm) } EXPORT_SYMBOL_GPL(rds_message_put); -void rds_message_inc_free(struct rds_incoming *inc) -{ - struct rds_message *rm = container_of(inc, struct rds_message, m_inc); - rds_message_put(rm); -} - void rds_message_populate_header(struct rds_header *hdr, __be16 sport, __be16 dport, u64 seq) { @@ -113,8 +106,8 @@ void rds_message_populate_header(struct rds_header *hdr, __be16 sport, } EXPORT_SYMBOL_GPL(rds_message_populate_header); -int rds_message_add_extension(struct rds_header *hdr, - unsigned int type, const void *data, unsigned int len) +int rds_message_add_extension(struct rds_header *hdr, unsigned int type, + const void *data, unsigned int len) { unsigned int ext_len = sizeof(u8) + len; unsigned char *dst; @@ -184,26 +177,6 @@ int rds_message_next_extension(struct rds_header *hdr, return RDS_EXTHDR_NONE; } -int rds_message_add_version_extension(struct rds_header *hdr, unsigned int version) -{ - struct rds_ext_header_version ext_hdr; - - ext_hdr.h_version = cpu_to_be32(version); - return rds_message_add_extension(hdr, RDS_EXTHDR_VERSION, &ext_hdr, sizeof(ext_hdr)); -} - -int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *version) -{ - struct rds_ext_header_version ext_hdr; - unsigned int pos = 0, len = sizeof(ext_hdr); - - /* We assume the version extension is the only one present */ - if (rds_message_next_extension(hdr, &pos, &ext_hdr, &len) != RDS_EXTHDR_VERSION) - return 0; - *version = be32_to_cpu(ext_hdr.h_version); - return 1; -} - int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset) { struct rds_ext_header_rdma_dest ext_hdr; @@ -214,41 +187,68 @@ int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 o } EXPORT_SYMBOL_GPL(rds_message_add_rdma_dest_extension); -struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp) +/* + * Each rds_message is allocated with extra space for the scatterlist entries + * rds ops will need. This is to minimize memory allocation count. Then, each rds op + * can grab SGs when initializing its part of the rds_message. + */ +struct rds_message *rds_message_alloc(unsigned int extra_len, gfp_t gfp) { struct rds_message *rm; - rm = kzalloc(sizeof(struct rds_message) + - (nents * sizeof(struct scatterlist)), gfp); + rm = kzalloc(sizeof(struct rds_message) + extra_len, gfp); if (!rm) goto out; - if (nents) - sg_init_table(rm->m_sg, nents); + rm->m_used_sgs = 0; + rm->m_total_sgs = extra_len / sizeof(struct scatterlist); + atomic_set(&rm->m_refcount, 1); INIT_LIST_HEAD(&rm->m_sock_item); INIT_LIST_HEAD(&rm->m_conn_item); spin_lock_init(&rm->m_rs_lock); + init_waitqueue_head(&rm->m_flush_wait); out: return rm; } +/* + * RDS ops use this to grab SG entries from the rm's sg pool. + */ +struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents) +{ + struct scatterlist *sg_first = (struct scatterlist *) &rm[1]; + struct scatterlist *sg_ret; + + WARN_ON(rm->m_used_sgs + nents > rm->m_total_sgs); + WARN_ON(!nents); + + sg_ret = &sg_first[rm->m_used_sgs]; + sg_init_table(sg_ret, nents); + rm->m_used_sgs += nents; + + return sg_ret; +} + struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len) { struct rds_message *rm; unsigned int i; + int num_sgs = ceil(total_len, PAGE_SIZE); + int extra_bytes = num_sgs * sizeof(struct scatterlist); - rm = rds_message_alloc(ceil(total_len, PAGE_SIZE), GFP_KERNEL); - if (rm == NULL) + rm = rds_message_alloc(extra_bytes, GFP_NOWAIT); + if (!rm) return ERR_PTR(-ENOMEM); set_bit(RDS_MSG_PAGEVEC, &rm->m_flags); rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); - rm->m_nents = ceil(total_len, PAGE_SIZE); + rm->data.op_nents = ceil(total_len, PAGE_SIZE); + rm->data.op_sg = rds_message_alloc_sgs(rm, num_sgs); - for (i = 0; i < rm->m_nents; ++i) { - sg_set_page(&rm->m_sg[i], + for (i = 0; i < rm->data.op_nents; ++i) { + sg_set_page(&rm->data.op_sg[i], virt_to_page(page_addrs[i]), PAGE_SIZE, 0); } @@ -256,40 +256,33 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in return rm; } -struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, +int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, size_t total_len) { unsigned long to_copy; unsigned long iov_off; unsigned long sg_off; - struct rds_message *rm; struct iovec *iov; struct scatterlist *sg; - int ret; - - rm = rds_message_alloc(ceil(total_len, PAGE_SIZE), GFP_KERNEL); - if (rm == NULL) { - ret = -ENOMEM; - goto out; - } + int ret = 0; rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len); /* * now allocate and copy in the data payload. */ - sg = rm->m_sg; + sg = rm->data.op_sg; iov = first_iov; iov_off = 0; sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */ while (total_len) { - if (sg_page(sg) == NULL) { + if (!sg_page(sg)) { ret = rds_page_remainder_alloc(sg, total_len, GFP_HIGHUSER); if (ret) goto out; - rm->m_nents++; + rm->data.op_nents++; sg_off = 0; } @@ -320,14 +313,8 @@ struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, sg++; } - ret = 0; out: - if (ret) { - if (rm) - rds_message_put(rm); - rm = ERR_PTR(ret); - } - return rm; + return ret; } int rds_message_inc_copy_to_user(struct rds_incoming *inc, @@ -348,7 +335,7 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, iov = first_iov; iov_off = 0; - sg = rm->m_sg; + sg = rm->data.op_sg; vec_off = 0; copied = 0; @@ -394,15 +381,14 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc, */ void rds_message_wait(struct rds_message *rm) { - wait_event(rds_message_flush_waitq, + wait_event_interruptible(rm->m_flush_wait, !test_bit(RDS_MSG_MAPPED, &rm->m_flags)); } void rds_message_unmapped(struct rds_message *rm) { clear_bit(RDS_MSG_MAPPED, &rm->m_flags); - if (waitqueue_active(&rds_message_flush_waitq)) - wake_up(&rds_message_flush_waitq); + wake_up_interruptible(&rm->m_flush_wait); } EXPORT_SYMBOL_GPL(rds_message_unmapped); diff --git a/net/rds/page.c b/net/rds/page.c index 1dfbfea12e9bc82ba8482277b4331289effa275b..d8acdebe3c7cde6436b03505824fd22a12e32f25 100644 --- a/net/rds/page.c +++ b/net/rds/page.c @@ -40,7 +40,8 @@ struct rds_page_remainder { unsigned long r_offset; }; -DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder, rds_page_remainders); +static DEFINE_PER_CPU_SHARED_ALIGNED(struct rds_page_remainder, + rds_page_remainders); /* * returns 0 on success or -errno on failure. @@ -103,7 +104,7 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes, /* jump straight to allocation if we're trying for a huge page */ if (bytes >= PAGE_SIZE) { page = alloc_page(gfp); - if (page == NULL) { + if (!page) { ret = -ENOMEM; } else { sg_set_page(scat, page, PAGE_SIZE, 0); @@ -149,7 +150,7 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes, rem = &per_cpu(rds_page_remainders, get_cpu()); local_irq_save(flags); - if (page == NULL) { + if (!page) { ret = -ENOMEM; break; } @@ -173,6 +174,7 @@ int rds_page_remainder_alloc(struct scatterlist *scat, unsigned long bytes, ret ? 0 : scat->length); return ret; } +EXPORT_SYMBOL_GPL(rds_page_remainder_alloc); static int rds_page_remainder_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 75fd13bb631bbc06bf8493c06c266951b6e47c95..1a41debca1ce6aa6d57d7c6fda1e135c7babdf30 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -35,7 +35,7 @@ #include #include /* for DMA_*_DEVICE */ -#include "rdma.h" +#include "rds.h" /* * XXX @@ -130,14 +130,22 @@ void rds_rdma_drop_keys(struct rds_sock *rs) { struct rds_mr *mr; struct rb_node *node; + unsigned long flags; /* Release any MRs associated with this socket */ + spin_lock_irqsave(&rs->rs_rdma_lock, flags); while ((node = rb_first(&rs->rs_rdma_keys))) { mr = container_of(node, struct rds_mr, r_rb_node); if (mr->r_trans == rs->rs_transport) mr->r_invalidate = 0; + rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys); + RB_CLEAR_NODE(&mr->r_rb_node); + spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); + rds_destroy_mr(mr); rds_mr_put(mr); + spin_lock_irqsave(&rs->rs_rdma_lock, flags); } + spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); if (rs->rs_transport && rs->rs_transport->flush_mrs) rs->rs_transport->flush_mrs(); @@ -181,7 +189,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, goto out; } - if (rs->rs_transport->get_mr == NULL) { + if (!rs->rs_transport->get_mr) { ret = -EOPNOTSUPP; goto out; } @@ -197,13 +205,13 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, /* XXX clamp nr_pages to limit the size of this alloc? */ pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); - if (pages == NULL) { + if (!pages) { ret = -ENOMEM; goto out; } mr = kzalloc(sizeof(struct rds_mr), GFP_KERNEL); - if (mr == NULL) { + if (!mr) { ret = -ENOMEM; goto out; } @@ -230,13 +238,13 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, * r/o or r/w. We need to assume r/w, or we'll do a lot of RDMA to * the zero page. */ - ret = rds_pin_pages(args->vec.addr & PAGE_MASK, nr_pages, pages, 1); + ret = rds_pin_pages(args->vec.addr, nr_pages, pages, 1); if (ret < 0) goto out; nents = ret; sg = kcalloc(nents, sizeof(*sg), GFP_KERNEL); - if (sg == NULL) { + if (!sg) { ret = -ENOMEM; goto out; } @@ -406,68 +414,127 @@ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force) spin_lock_irqsave(&rs->rs_rdma_lock, flags); mr = rds_mr_tree_walk(&rs->rs_rdma_keys, r_key, NULL); - if (mr && (mr->r_use_once || force)) { + if (!mr) { + printk(KERN_ERR "rds: trying to unuse MR with unknown r_key %u!\n", r_key); + spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); + return; + } + + if (mr->r_use_once || force) { rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys); RB_CLEAR_NODE(&mr->r_rb_node); zot_me = 1; - } else if (mr) - atomic_inc(&mr->r_refcount); + } spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); /* May have to issue a dma_sync on this memory region. * Note we could avoid this if the operation was a RDMA READ, * but at this point we can't tell. */ - if (mr != NULL) { - if (mr->r_trans->sync_mr) - mr->r_trans->sync_mr(mr->r_trans_private, DMA_FROM_DEVICE); - - /* If the MR was marked as invalidate, this will - * trigger an async flush. */ - if (zot_me) - rds_destroy_mr(mr); - rds_mr_put(mr); - } + if (mr->r_trans->sync_mr) + mr->r_trans->sync_mr(mr->r_trans_private, DMA_FROM_DEVICE); + + /* If the MR was marked as invalidate, this will + * trigger an async flush. */ + if (zot_me) + rds_destroy_mr(mr); + rds_mr_put(mr); } -void rds_rdma_free_op(struct rds_rdma_op *ro) +void rds_rdma_free_op(struct rm_rdma_op *ro) { unsigned int i; - for (i = 0; i < ro->r_nents; i++) { - struct page *page = sg_page(&ro->r_sg[i]); + for (i = 0; i < ro->op_nents; i++) { + struct page *page = sg_page(&ro->op_sg[i]); /* Mark page dirty if it was possibly modified, which * is the case for a RDMA_READ which copies from remote * to local memory */ - if (!ro->r_write) { - BUG_ON(in_interrupt()); + if (!ro->op_write) { + BUG_ON(irqs_disabled()); set_page_dirty(page); } put_page(page); } - kfree(ro->r_notifier); - kfree(ro); + kfree(ro->op_notifier); + ro->op_notifier = NULL; + ro->op_active = 0; +} + +void rds_atomic_free_op(struct rm_atomic_op *ao) +{ + struct page *page = sg_page(ao->op_sg); + + /* Mark page dirty if it was possibly modified, which + * is the case for a RDMA_READ which copies from remote + * to local memory */ + set_page_dirty(page); + put_page(page); + + kfree(ao->op_notifier); + ao->op_notifier = NULL; + ao->op_active = 0; } + /* - * args is a pointer to an in-kernel copy in the sendmsg cmsg. + * Count the number of pages needed to describe an incoming iovec. */ -static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, - struct rds_rdma_args *args) +static int rds_rdma_pages(struct rds_rdma_args *args) { struct rds_iovec vec; - struct rds_rdma_op *op = NULL; + struct rds_iovec __user *local_vec; + unsigned int tot_pages = 0; unsigned int nr_pages; - unsigned int max_pages; + unsigned int i; + + local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; + + /* figure out the number of pages in the vector */ + for (i = 0; i < args->nr_local; i++) { + if (copy_from_user(&vec, &local_vec[i], + sizeof(struct rds_iovec))) + return -EFAULT; + + nr_pages = rds_pages_in_vec(&vec); + if (nr_pages == 0) + return -EINVAL; + + tot_pages += nr_pages; + } + + return tot_pages; +} + +int rds_rdma_extra_size(struct rds_rdma_args *args) +{ + return rds_rdma_pages(args) * sizeof(struct scatterlist); +} + +/* + * The application asks for a RDMA transfer. + * Extract all arguments and set up the rdma_op + */ +int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg) +{ + struct rds_rdma_args *args; + struct rds_iovec vec; + struct rm_rdma_op *op = &rm->rdma; + int nr_pages; unsigned int nr_bytes; struct page **pages = NULL; struct rds_iovec __user *local_vec; - struct scatterlist *sg; unsigned int nr; unsigned int i, j; - int ret; + int ret = 0; + if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) + || rm->rdma.op_active) + return -EINVAL; + + args = CMSG_DATA(cmsg); if (rs->rs_bound_addr == 0) { ret = -ENOTCONN; /* XXX not a great errno */ @@ -479,61 +546,38 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, goto out; } - nr_pages = 0; - max_pages = 0; - - local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; - - /* figure out the number of pages in the vector */ - for (i = 0; i < args->nr_local; i++) { - if (copy_from_user(&vec, &local_vec[i], - sizeof(struct rds_iovec))) { - ret = -EFAULT; - goto out; - } - - nr = rds_pages_in_vec(&vec); - if (nr == 0) { - ret = -EINVAL; - goto out; - } - - max_pages = max(nr, max_pages); - nr_pages += nr; - } - - pages = kcalloc(max_pages, sizeof(struct page *), GFP_KERNEL); - if (pages == NULL) { - ret = -ENOMEM; + nr_pages = rds_rdma_pages(args); + if (nr_pages < 0) goto out; - } - op = kzalloc(offsetof(struct rds_rdma_op, r_sg[nr_pages]), GFP_KERNEL); - if (op == NULL) { + pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); + if (!pages) { ret = -ENOMEM; goto out; } - op->r_write = !!(args->flags & RDS_RDMA_READWRITE); - op->r_fence = !!(args->flags & RDS_RDMA_FENCE); - op->r_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); - op->r_recverr = rs->rs_recverr; + op->op_write = !!(args->flags & RDS_RDMA_READWRITE); + op->op_fence = !!(args->flags & RDS_RDMA_FENCE); + op->op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); + op->op_silent = !!(args->flags & RDS_RDMA_SILENT); + op->op_active = 1; + op->op_recverr = rs->rs_recverr; WARN_ON(!nr_pages); - sg_init_table(op->r_sg, nr_pages); + op->op_sg = rds_message_alloc_sgs(rm, nr_pages); - if (op->r_notify || op->r_recverr) { + if (op->op_notify || op->op_recverr) { /* We allocate an uninitialized notifier here, because * we don't want to do that in the completion handler. We * would have to use GFP_ATOMIC there, and don't want to deal * with failed allocations. */ - op->r_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL); - if (!op->r_notifier) { + op->op_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL); + if (!op->op_notifier) { ret = -ENOMEM; goto out; } - op->r_notifier->n_user_token = args->user_token; - op->r_notifier->n_status = RDS_RDMA_SUCCESS; + op->op_notifier->n_user_token = args->user_token; + op->op_notifier->n_status = RDS_RDMA_SUCCESS; } /* The cookie contains the R_Key of the remote memory region, and @@ -543,15 +587,17 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, * destination address (which is really an offset into the MR) * FIXME: We may want to move this into ib_rdma.c */ - op->r_key = rds_rdma_cookie_key(args->cookie); - op->r_remote_addr = args->remote_vec.addr + rds_rdma_cookie_offset(args->cookie); + op->op_rkey = rds_rdma_cookie_key(args->cookie); + op->op_remote_addr = args->remote_vec.addr + rds_rdma_cookie_offset(args->cookie); nr_bytes = 0; rdsdebug("RDS: rdma prepare nr_local %llu rva %llx rkey %x\n", (unsigned long long)args->nr_local, (unsigned long long)args->remote_vec.addr, - op->r_key); + op->op_rkey); + + local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; for (i = 0; i < args->nr_local; i++) { if (copy_from_user(&vec, &local_vec[i], @@ -569,15 +615,10 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, rs->rs_user_addr = vec.addr; rs->rs_user_bytes = vec.bytes; - /* did the user change the vec under us? */ - if (nr > max_pages || op->r_nents + nr > nr_pages) { - ret = -EINVAL; - goto out; - } /* If it's a WRITE operation, we want to pin the pages for reading. * If it's a READ operation, we need to pin the pages for writing. */ - ret = rds_pin_pages(vec.addr & PAGE_MASK, nr, pages, !op->r_write); + ret = rds_pin_pages(vec.addr, nr, pages, !op->op_write); if (ret < 0) goto out; @@ -588,8 +629,9 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, for (j = 0; j < nr; j++) { unsigned int offset = vec.addr & ~PAGE_MASK; + struct scatterlist *sg; - sg = &op->r_sg[op->r_nents + j]; + sg = &op->op_sg[op->op_nents + j]; sg_set_page(sg, pages[j], min_t(unsigned int, vec.bytes, PAGE_SIZE - offset), offset); @@ -601,10 +643,9 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, vec.bytes -= sg->length; } - op->r_nents += nr; + op->op_nents += nr; } - if (nr_bytes > args->remote_vec.bytes) { rdsdebug("RDS nr_bytes %u remote_bytes %u do not match\n", nr_bytes, @@ -612,38 +653,17 @@ static struct rds_rdma_op *rds_rdma_prepare(struct rds_sock *rs, ret = -EINVAL; goto out; } - op->r_bytes = nr_bytes; + op->op_bytes = nr_bytes; ret = 0; out: kfree(pages); - if (ret) { - if (op) - rds_rdma_free_op(op); - op = ERR_PTR(ret); - } - return op; -} - -/* - * The application asks for a RDMA transfer. - * Extract all arguments and set up the rdma_op - */ -int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg) -{ - struct rds_rdma_op *op; - - if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_rdma_args)) || - rm->m_rdma_op != NULL) - return -EINVAL; + if (ret) + rds_rdma_free_op(op); - op = rds_rdma_prepare(rs, CMSG_DATA(cmsg)); - if (IS_ERR(op)) - return PTR_ERR(op); rds_stats_inc(s_send_rdma); - rm->m_rdma_op = op; - return 0; + + return ret; } /* @@ -673,7 +693,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, spin_lock_irqsave(&rs->rs_rdma_lock, flags); mr = rds_mr_tree_walk(&rs->rs_rdma_keys, r_key, NULL); - if (mr == NULL) + if (!mr) err = -EINVAL; /* invalid r_key */ else atomic_inc(&mr->r_refcount); @@ -681,7 +701,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, if (mr) { mr->r_trans->sync_mr(mr->r_trans_private, DMA_TO_DEVICE); - rm->m_rdma_mr = mr; + rm->rdma.op_rdma_mr = mr; } return err; } @@ -699,5 +719,98 @@ int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, rm->m_rdma_cookie != 0) return -EINVAL; - return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->m_rdma_mr); + return __rds_rdma_map(rs, CMSG_DATA(cmsg), &rm->m_rdma_cookie, &rm->rdma.op_rdma_mr); +} + +/* + * Fill in rds_message for an atomic request. + */ +int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg) +{ + struct page *page = NULL; + struct rds_atomic_args *args; + int ret = 0; + + if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct rds_atomic_args)) + || rm->atomic.op_active) + return -EINVAL; + + args = CMSG_DATA(cmsg); + + /* Nonmasked & masked cmsg ops converted to masked hw ops */ + switch (cmsg->cmsg_type) { + case RDS_CMSG_ATOMIC_FADD: + rm->atomic.op_type = RDS_ATOMIC_TYPE_FADD; + rm->atomic.op_m_fadd.add = args->fadd.add; + rm->atomic.op_m_fadd.nocarry_mask = 0; + break; + case RDS_CMSG_MASKED_ATOMIC_FADD: + rm->atomic.op_type = RDS_ATOMIC_TYPE_FADD; + rm->atomic.op_m_fadd.add = args->m_fadd.add; + rm->atomic.op_m_fadd.nocarry_mask = args->m_fadd.nocarry_mask; + break; + case RDS_CMSG_ATOMIC_CSWP: + rm->atomic.op_type = RDS_ATOMIC_TYPE_CSWP; + rm->atomic.op_m_cswp.compare = args->cswp.compare; + rm->atomic.op_m_cswp.swap = args->cswp.swap; + rm->atomic.op_m_cswp.compare_mask = ~0; + rm->atomic.op_m_cswp.swap_mask = ~0; + break; + case RDS_CMSG_MASKED_ATOMIC_CSWP: + rm->atomic.op_type = RDS_ATOMIC_TYPE_CSWP; + rm->atomic.op_m_cswp.compare = args->m_cswp.compare; + rm->atomic.op_m_cswp.swap = args->m_cswp.swap; + rm->atomic.op_m_cswp.compare_mask = args->m_cswp.compare_mask; + rm->atomic.op_m_cswp.swap_mask = args->m_cswp.swap_mask; + break; + default: + BUG(); /* should never happen */ + } + + rm->atomic.op_notify = !!(args->flags & RDS_RDMA_NOTIFY_ME); + rm->atomic.op_silent = !!(args->flags & RDS_RDMA_SILENT); + rm->atomic.op_active = 1; + rm->atomic.op_recverr = rs->rs_recverr; + rm->atomic.op_sg = rds_message_alloc_sgs(rm, 1); + + /* verify 8 byte-aligned */ + if (args->local_addr & 0x7) { + ret = -EFAULT; + goto err; + } + + ret = rds_pin_pages(args->local_addr, 1, &page, 1); + if (ret != 1) + goto err; + ret = 0; + + sg_set_page(rm->atomic.op_sg, page, 8, offset_in_page(args->local_addr)); + + if (rm->atomic.op_notify || rm->atomic.op_recverr) { + /* We allocate an uninitialized notifier here, because + * we don't want to do that in the completion handler. We + * would have to use GFP_ATOMIC there, and don't want to deal + * with failed allocations. + */ + rm->atomic.op_notifier = kmalloc(sizeof(*rm->atomic.op_notifier), GFP_KERNEL); + if (!rm->atomic.op_notifier) { + ret = -ENOMEM; + goto err; + } + + rm->atomic.op_notifier->n_user_token = args->user_token; + rm->atomic.op_notifier->n_status = RDS_RDMA_SUCCESS; + } + + rm->atomic.op_rkey = rds_rdma_cookie_key(args->cookie); + rm->atomic.op_remote_addr = args->remote_addr + rds_rdma_cookie_offset(args->cookie); + + return ret; +err: + if (page) + put_page(page); + kfree(rm->atomic.op_notifier); + + return ret; } diff --git a/net/rds/rdma.h b/net/rds/rdma.h deleted file mode 100644 index 909c39835a5dab689dccc4cf76e1729582f56d34..0000000000000000000000000000000000000000 --- a/net/rds/rdma.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _RDS_RDMA_H -#define _RDS_RDMA_H - -#include -#include -#include - -#include "rds.h" - -struct rds_mr { - struct rb_node r_rb_node; - atomic_t r_refcount; - u32 r_key; - - /* A copy of the creation flags */ - unsigned int r_use_once:1; - unsigned int r_invalidate:1; - unsigned int r_write:1; - - /* This is for RDS_MR_DEAD. - * It would be nice & consistent to make this part of the above - * bit field here, but we need to use test_and_set_bit. - */ - unsigned long r_state; - struct rds_sock *r_sock; /* back pointer to the socket that owns us */ - struct rds_transport *r_trans; - void *r_trans_private; -}; - -/* Flags for mr->r_state */ -#define RDS_MR_DEAD 0 - -struct rds_rdma_op { - u32 r_key; - u64 r_remote_addr; - unsigned int r_write:1; - unsigned int r_fence:1; - unsigned int r_notify:1; - unsigned int r_recverr:1; - unsigned int r_mapped:1; - struct rds_notifier *r_notifier; - unsigned int r_bytes; - unsigned int r_nents; - unsigned int r_count; - struct scatterlist r_sg[0]; -}; - -static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset) -{ - return r_key | (((u64) offset) << 32); -} - -static inline u32 rds_rdma_cookie_key(rds_rdma_cookie_t cookie) -{ - return cookie; -} - -static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie) -{ - return cookie >> 32; -} - -int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen); -int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen); -int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen); -void rds_rdma_drop_keys(struct rds_sock *rs); -int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg); -int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg); -int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg); -int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, - struct cmsghdr *cmsg); -void rds_rdma_free_op(struct rds_rdma_op *ro); -void rds_rdma_send_complete(struct rds_message *rm, int); - -extern void __rds_put_mr_final(struct rds_mr *mr); -static inline void rds_mr_put(struct rds_mr *mr) -{ - if (atomic_dec_and_test(&mr->r_refcount)) - __rds_put_mr_final(mr); -} - -#endif diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index e599ba2f950d72e03c4bc98f7b1a9b86742134e7..4195a0539829a85ebc2485d060172493a4817fe7 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c @@ -36,6 +36,34 @@ static struct rdma_cm_id *rds_rdma_listen_id; +static char *rds_cm_event_strings[] = { +#define RDS_CM_EVENT_STRING(foo) \ + [RDMA_CM_EVENT_##foo] = __stringify(RDMA_CM_EVENT_##foo) + RDS_CM_EVENT_STRING(ADDR_RESOLVED), + RDS_CM_EVENT_STRING(ADDR_ERROR), + RDS_CM_EVENT_STRING(ROUTE_RESOLVED), + RDS_CM_EVENT_STRING(ROUTE_ERROR), + RDS_CM_EVENT_STRING(CONNECT_REQUEST), + RDS_CM_EVENT_STRING(CONNECT_RESPONSE), + RDS_CM_EVENT_STRING(CONNECT_ERROR), + RDS_CM_EVENT_STRING(UNREACHABLE), + RDS_CM_EVENT_STRING(REJECTED), + RDS_CM_EVENT_STRING(ESTABLISHED), + RDS_CM_EVENT_STRING(DISCONNECTED), + RDS_CM_EVENT_STRING(DEVICE_REMOVAL), + RDS_CM_EVENT_STRING(MULTICAST_JOIN), + RDS_CM_EVENT_STRING(MULTICAST_ERROR), + RDS_CM_EVENT_STRING(ADDR_CHANGE), + RDS_CM_EVENT_STRING(TIMEWAIT_EXIT), +#undef RDS_CM_EVENT_STRING +}; + +static char *rds_cm_event_str(enum rdma_cm_event_type type) +{ + return rds_str_array(rds_cm_event_strings, + ARRAY_SIZE(rds_cm_event_strings), type); +}; + int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, struct rdma_cm_event *event) { @@ -44,8 +72,8 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, struct rds_transport *trans; int ret = 0; - rdsdebug("conn %p id %p handling event %u\n", conn, cm_id, - event->event); + rdsdebug("conn %p id %p handling event %u (%s)\n", conn, cm_id, + event->event, rds_cm_event_str(event->event)); if (cm_id->device->node_type == RDMA_NODE_RNIC) trans = &rds_iw_transport; @@ -109,7 +137,8 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, default: /* things like device disconnect? */ - printk(KERN_ERR "RDS: unknown event %u!\n", event->event); + printk(KERN_ERR "RDS: unknown event %u (%s)!\n", + event->event, rds_cm_event_str(event->event)); break; } @@ -117,12 +146,13 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, if (conn) mutex_unlock(&conn->c_cm_lock); - rdsdebug("id %p event %u handling ret %d\n", cm_id, event->event, ret); + rdsdebug("id %p event %u (%s) handling ret %d\n", cm_id, event->event, + rds_cm_event_str(event->event), ret); return ret; } -static int __init rds_rdma_listen_init(void) +static int rds_rdma_listen_init(void) { struct sockaddr_in sin; struct rdma_cm_id *cm_id; @@ -177,7 +207,7 @@ static void rds_rdma_listen_stop(void) } } -int __init rds_rdma_init(void) +static int rds_rdma_init(void) { int ret; @@ -204,7 +234,7 @@ int __init rds_rdma_init(void) } module_init(rds_rdma_init); -void rds_rdma_exit(void) +static void rds_rdma_exit(void) { /* stop listening first to ensure no new connections are attempted */ rds_rdma_listen_stop(); diff --git a/net/rds/rdma_transport.h b/net/rds/rdma_transport.h index 2f2c7d976c219c787d337db96a46a020a6a3355d..faba4e382695e36c12c25f981b043077f4d7363c 100644 --- a/net/rds/rdma_transport.h +++ b/net/rds/rdma_transport.h @@ -11,10 +11,6 @@ int rds_rdma_conn_connect(struct rds_connection *conn); int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, struct rdma_cm_event *event); -/* from rdma_transport.c */ -int rds_rdma_init(void); -void rds_rdma_exit(void); - /* from ib.c */ extern struct rds_transport rds_ib_transport; int rds_ib_init(void); diff --git a/net/rds/rds.h b/net/rds/rds.h index c224b5bb3ba9368fd00fad5f6a25f90d68364ebd..9542449c0720864af4697dd73cfb0685fd821a55 100644 --- a/net/rds/rds.h +++ b/net/rds/rds.h @@ -80,6 +80,7 @@ enum { /* Bits for c_flags */ #define RDS_LL_SEND_FULL 0 #define RDS_RECONNECT_PENDING 1 +#define RDS_IN_XMIT 2 struct rds_connection { struct hlist_node c_hash_node; @@ -91,12 +92,13 @@ struct rds_connection { struct rds_cong_map *c_lcong; struct rds_cong_map *c_fcong; - struct mutex c_send_lock; /* protect send ring */ struct rds_message *c_xmit_rm; unsigned long c_xmit_sg; unsigned int c_xmit_hdr_off; unsigned int c_xmit_data_off; + unsigned int c_xmit_atomic_sent; unsigned int c_xmit_rdma_sent; + unsigned int c_xmit_data_sent; spinlock_t c_lock; /* protect msg queues */ u64 c_next_tx_seq; @@ -116,11 +118,10 @@ struct rds_connection { struct delayed_work c_conn_w; struct work_struct c_down_w; struct mutex c_cm_lock; /* protect conn state & cm */ + wait_queue_head_t c_waitq; struct list_head c_map_item; unsigned long c_map_queued; - unsigned long c_map_offset; - unsigned long c_map_bytes; unsigned int c_unacked_packets; unsigned int c_unacked_bytes; @@ -206,6 +207,48 @@ struct rds_incoming { rds_rdma_cookie_t i_rdma_cookie; }; +struct rds_mr { + struct rb_node r_rb_node; + atomic_t r_refcount; + u32 r_key; + + /* A copy of the creation flags */ + unsigned int r_use_once:1; + unsigned int r_invalidate:1; + unsigned int r_write:1; + + /* This is for RDS_MR_DEAD. + * It would be nice & consistent to make this part of the above + * bit field here, but we need to use test_and_set_bit. + */ + unsigned long r_state; + struct rds_sock *r_sock; /* back pointer to the socket that owns us */ + struct rds_transport *r_trans; + void *r_trans_private; +}; + +/* Flags for mr->r_state */ +#define RDS_MR_DEAD 0 + +static inline rds_rdma_cookie_t rds_rdma_make_cookie(u32 r_key, u32 offset) +{ + return r_key | (((u64) offset) << 32); +} + +static inline u32 rds_rdma_cookie_key(rds_rdma_cookie_t cookie) +{ + return cookie; +} + +static inline u32 rds_rdma_cookie_offset(rds_rdma_cookie_t cookie) +{ + return cookie >> 32; +} + +/* atomic operation types */ +#define RDS_ATOMIC_TYPE_CSWP 0 +#define RDS_ATOMIC_TYPE_FADD 1 + /* * m_sock_item and m_conn_item are on lists that are serialized under * conn->c_lock. m_sock_item has additional meaning in that once it is empty @@ -258,13 +301,71 @@ struct rds_message { * -> rs->rs_lock */ spinlock_t m_rs_lock; + wait_queue_head_t m_flush_wait; + struct rds_sock *m_rs; - struct rds_rdma_op *m_rdma_op; + + /* cookie to send to remote, in rds header */ rds_rdma_cookie_t m_rdma_cookie; - struct rds_mr *m_rdma_mr; - unsigned int m_nents; - unsigned int m_count; - struct scatterlist m_sg[0]; + + unsigned int m_used_sgs; + unsigned int m_total_sgs; + + void *m_final_op; + + struct { + struct rm_atomic_op { + int op_type; + union { + struct { + uint64_t compare; + uint64_t swap; + uint64_t compare_mask; + uint64_t swap_mask; + } op_m_cswp; + struct { + uint64_t add; + uint64_t nocarry_mask; + } op_m_fadd; + }; + + u32 op_rkey; + u64 op_remote_addr; + unsigned int op_notify:1; + unsigned int op_recverr:1; + unsigned int op_mapped:1; + unsigned int op_silent:1; + unsigned int op_active:1; + struct scatterlist *op_sg; + struct rds_notifier *op_notifier; + + struct rds_mr *op_rdma_mr; + } atomic; + struct rm_rdma_op { + u32 op_rkey; + u64 op_remote_addr; + unsigned int op_write:1; + unsigned int op_fence:1; + unsigned int op_notify:1; + unsigned int op_recverr:1; + unsigned int op_mapped:1; + unsigned int op_silent:1; + unsigned int op_active:1; + unsigned int op_bytes; + unsigned int op_nents; + unsigned int op_count; + struct scatterlist *op_sg; + struct rds_notifier *op_notifier; + + struct rds_mr *op_rdma_mr; + } rdma; + struct rm_data_op { + unsigned int op_active:1; + unsigned int op_nents; + unsigned int op_count; + struct scatterlist *op_sg; + } data; + }; }; /* @@ -305,10 +406,6 @@ struct rds_notifier { * transport is responsible for other serialization, including * rds_recv_incoming(). This is called in process context but * should try hard not to block. - * - * @xmit_cong_map: This asks the transport to send the local bitmap down the - * given connection. XXX get a better story about the bitmap - * flag and header. */ #define RDS_TRANS_IB 0 @@ -332,13 +429,11 @@ struct rds_transport { void (*xmit_complete)(struct rds_connection *conn); int (*xmit)(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off); - int (*xmit_cong_map)(struct rds_connection *conn, - struct rds_cong_map *map, unsigned long offset); - int (*xmit_rdma)(struct rds_connection *conn, struct rds_rdma_op *op); + int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op); + int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op); int (*recv)(struct rds_connection *conn); int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov, size_t size); - void (*inc_purge)(struct rds_incoming *inc); void (*inc_free)(struct rds_incoming *inc); int (*cm_handle_connect)(struct rdma_cm_id *cm_id, @@ -367,17 +462,11 @@ struct rds_sock { * bound_addr used for both incoming and outgoing, no INADDR_ANY * support. */ - struct rb_node rs_bound_node; + struct hlist_node rs_bound_node; __be32 rs_bound_addr; __be32 rs_conn_addr; __be16 rs_bound_port; __be16 rs_conn_port; - - /* - * This is only used to communicate the transport between bind and - * initiating connections. All other trans use is referenced through - * the connection. - */ struct rds_transport *rs_transport; /* @@ -466,8 +555,8 @@ struct rds_statistics { uint64_t s_recv_ping; uint64_t s_send_queue_empty; uint64_t s_send_queue_full; - uint64_t s_send_sem_contention; - uint64_t s_send_sem_queue_raced; + uint64_t s_send_lock_contention; + uint64_t s_send_lock_queue_raced; uint64_t s_send_immediate_retry; uint64_t s_send_delayed_retry; uint64_t s_send_drop_acked; @@ -487,6 +576,7 @@ struct rds_statistics { }; /* af_rds.c */ +char *rds_str_array(char **array, size_t elements, size_t index); void rds_sock_addref(struct rds_sock *rs); void rds_sock_put(struct rds_sock *rs); void rds_wake_sk_sleep(struct rds_sock *rs); @@ -521,15 +611,16 @@ void rds_cong_exit(void); struct rds_message *rds_cong_update_alloc(struct rds_connection *conn); /* conn.c */ -int __init rds_conn_init(void); +int rds_conn_init(void); void rds_conn_exit(void); struct rds_connection *rds_conn_create(__be32 laddr, __be32 faddr, struct rds_transport *trans, gfp_t gfp); struct rds_connection *rds_conn_create_outgoing(__be32 laddr, __be32 faddr, struct rds_transport *trans, gfp_t gfp); +void rds_conn_shutdown(struct rds_connection *conn); void rds_conn_destroy(struct rds_connection *conn); -void rds_conn_reset(struct rds_connection *conn); void rds_conn_drop(struct rds_connection *conn); +void rds_conn_connect_if_down(struct rds_connection *conn); void rds_for_each_conn_info(struct socket *sock, unsigned int len, struct rds_info_iterator *iter, struct rds_info_lengths *lens, @@ -566,7 +657,8 @@ rds_conn_connecting(struct rds_connection *conn) /* message.c */ struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp); -struct rds_message *rds_message_copy_from_user(struct iovec *first_iov, +struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents); +int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov, size_t total_len); struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len); void rds_message_populate_header(struct rds_header *hdr, __be16 sport, @@ -575,12 +667,9 @@ int rds_message_add_extension(struct rds_header *hdr, unsigned int type, const void *data, unsigned int len); int rds_message_next_extension(struct rds_header *hdr, unsigned int *pos, void *buf, unsigned int *buflen); -int rds_message_add_version_extension(struct rds_header *hdr, unsigned int version); -int rds_message_get_version_extension(struct rds_header *hdr, unsigned int *version); int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset); int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov, size_t size); -void rds_message_inc_purge(struct rds_incoming *inc); void rds_message_inc_free(struct rds_incoming *inc); void rds_message_addref(struct rds_message *rm); void rds_message_put(struct rds_message *rm); @@ -614,7 +703,6 @@ void rds_page_exit(void); /* recv.c */ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn, __be32 saddr); -void rds_inc_addref(struct rds_incoming *inc); void rds_inc_put(struct rds_incoming *inc); void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr, struct rds_incoming *inc, gfp_t gfp, enum km_type km); @@ -636,14 +724,38 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest); typedef int (*is_acked_func)(struct rds_message *rm, uint64_t ack); void rds_send_drop_acked(struct rds_connection *conn, u64 ack, is_acked_func is_acked); -int rds_send_acked_before(struct rds_connection *conn, u64 seq); -void rds_send_remove_from_sock(struct list_head *messages, int status); int rds_send_pong(struct rds_connection *conn, __be16 dport); struct rds_message *rds_send_get_message(struct rds_connection *, - struct rds_rdma_op *); + struct rm_rdma_op *); /* rdma.c */ void rds_rdma_unuse(struct rds_sock *rs, u32 r_key, int force); +int rds_get_mr(struct rds_sock *rs, char __user *optval, int optlen); +int rds_get_mr_for_dest(struct rds_sock *rs, char __user *optval, int optlen); +int rds_free_mr(struct rds_sock *rs, char __user *optval, int optlen); +void rds_rdma_drop_keys(struct rds_sock *rs); +int rds_rdma_extra_size(struct rds_rdma_args *args); +int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); +int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); +int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); +int rds_cmsg_rdma_map(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); +void rds_rdma_free_op(struct rm_rdma_op *ro); +void rds_atomic_free_op(struct rm_atomic_op *ao); +void rds_rdma_send_complete(struct rds_message *rm, int wc_status); +void rds_atomic_send_complete(struct rds_message *rm, int wc_status); +int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, + struct cmsghdr *cmsg); + +extern void __rds_put_mr_final(struct rds_mr *mr); +static inline void rds_mr_put(struct rds_mr *mr) +{ + if (atomic_dec_and_test(&mr->r_refcount)) + __rds_put_mr_final(mr); +} /* stats.c */ DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats); @@ -657,14 +769,14 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_statistics, rds_stats); put_cpu(); \ } while (0) #define rds_stats_add(member, count) rds_stats_add_which(rds_stats, member, count) -int __init rds_stats_init(void); +int rds_stats_init(void); void rds_stats_exit(void); void rds_stats_info_copy(struct rds_info_iterator *iter, uint64_t *values, const char *const *names, size_t nr); /* sysctl.c */ -int __init rds_sysctl_init(void); +int rds_sysctl_init(void); void rds_sysctl_exit(void); extern unsigned long rds_sysctl_sndbuf_min; extern unsigned long rds_sysctl_sndbuf_default; @@ -678,9 +790,10 @@ extern unsigned long rds_sysctl_trace_flags; extern unsigned int rds_sysctl_trace_level; /* threads.c */ -int __init rds_threads_init(void); +int rds_threads_init(void); void rds_threads_exit(void); extern struct workqueue_struct *rds_wq; +void rds_queue_reconnect(struct rds_connection *conn); void rds_connect_worker(struct work_struct *); void rds_shutdown_worker(struct work_struct *); void rds_send_worker(struct work_struct *); @@ -691,9 +804,10 @@ void rds_connect_complete(struct rds_connection *conn); int rds_trans_register(struct rds_transport *trans); void rds_trans_unregister(struct rds_transport *trans); struct rds_transport *rds_trans_get_preferred(__be32 addr); +void rds_trans_put(struct rds_transport *trans); unsigned int rds_trans_stats_info_copy(struct rds_info_iterator *iter, unsigned int avail); -int __init rds_trans_init(void); +int rds_trans_init(void); void rds_trans_exit(void); #endif diff --git a/net/rds/recv.c b/net/rds/recv.c index c93588c2d553cf6b162ab500cf1fd72dbbc9c26c..596689e592727f93eaf749490cf6fb6af4956463 100644 --- a/net/rds/recv.c +++ b/net/rds/recv.c @@ -36,7 +36,6 @@ #include #include "rds.h" -#include "rdma.h" void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn, __be32 saddr) @@ -49,12 +48,11 @@ void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn, } EXPORT_SYMBOL_GPL(rds_inc_init); -void rds_inc_addref(struct rds_incoming *inc) +static void rds_inc_addref(struct rds_incoming *inc) { rdsdebug("addref inc %p ref %d\n", inc, atomic_read(&inc->i_refcount)); atomic_inc(&inc->i_refcount); } -EXPORT_SYMBOL_GPL(rds_inc_addref); void rds_inc_put(struct rds_incoming *inc) { @@ -210,7 +208,7 @@ void rds_recv_incoming(struct rds_connection *conn, __be32 saddr, __be32 daddr, } rs = rds_find_bound(daddr, inc->i_hdr.h_dport); - if (rs == NULL) { + if (!rs) { rds_stats_inc(s_recv_drop_no_sock); goto out; } @@ -251,7 +249,7 @@ static int rds_next_incoming(struct rds_sock *rs, struct rds_incoming **inc) { unsigned long flags; - if (*inc == NULL) { + if (!*inc) { read_lock_irqsave(&rs->rs_recv_lock, flags); if (!list_empty(&rs->rs_recv_queue)) { *inc = list_entry(rs->rs_recv_queue.next, @@ -334,10 +332,10 @@ int rds_notify_queue_get(struct rds_sock *rs, struct msghdr *msghdr) if (msghdr) { cmsg.user_token = notifier->n_user_token; - cmsg.status = notifier->n_status; + cmsg.status = notifier->n_status; err = put_cmsg(msghdr, SOL_RDS, RDS_CMSG_RDMA_STATUS, - sizeof(cmsg), &cmsg); + sizeof(cmsg), &cmsg); if (err) break; } diff --git a/net/rds/send.c b/net/rds/send.c index 9c1c6bcaa6c9532e9abdbbd198b8ab6e6c7b9400..0bc9db17a87dd216bcc5ae914dbae20d0953ac89 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -37,7 +37,6 @@ #include #include "rds.h" -#include "rdma.h" /* When transmitting messages in rds_send_xmit, we need to emerge from * time to time and briefly release the CPU. Otherwise the softlock watchdog @@ -53,8 +52,11 @@ static int send_batch_count = 64; module_param(send_batch_count, int, 0444); MODULE_PARM_DESC(send_batch_count, " batch factor when working the send queue"); +static void rds_send_remove_from_sock(struct list_head *messages, int status); + /* - * Reset the send state. Caller must hold c_send_lock when calling here. + * Reset the send state. Callers must ensure that this doesn't race with + * rds_send_xmit(). */ void rds_send_reset(struct rds_connection *conn) { @@ -62,18 +64,22 @@ void rds_send_reset(struct rds_connection *conn) unsigned long flags; if (conn->c_xmit_rm) { + rm = conn->c_xmit_rm; + conn->c_xmit_rm = NULL; /* Tell the user the RDMA op is no longer mapped by the * transport. This isn't entirely true (it's flushed out * independently) but as the connection is down, there's * no ongoing RDMA to/from that memory */ - rds_message_unmapped(conn->c_xmit_rm); - rds_message_put(conn->c_xmit_rm); - conn->c_xmit_rm = NULL; + rds_message_unmapped(rm); + rds_message_put(rm); } + conn->c_xmit_sg = 0; conn->c_xmit_hdr_off = 0; conn->c_xmit_data_off = 0; + conn->c_xmit_atomic_sent = 0; conn->c_xmit_rdma_sent = 0; + conn->c_xmit_data_sent = 0; conn->c_map_queued = 0; @@ -90,6 +96,25 @@ void rds_send_reset(struct rds_connection *conn) spin_unlock_irqrestore(&conn->c_lock, flags); } +static int acquire_in_xmit(struct rds_connection *conn) +{ + return test_and_set_bit(RDS_IN_XMIT, &conn->c_flags) == 0; +} + +static void release_in_xmit(struct rds_connection *conn) +{ + clear_bit(RDS_IN_XMIT, &conn->c_flags); + smp_mb__after_clear_bit(); + /* + * We don't use wait_on_bit()/wake_up_bit() because our waking is in a + * hot path and finding waiters is very rare. We don't want to walk + * the system-wide hashed waitqueue buckets in the fast path only to + * almost never find waiters. + */ + if (waitqueue_active(&conn->c_waitq)) + wake_up_all(&conn->c_waitq); +} + /* * We're making the concious trade-off here to only send one message * down the connection at a time. @@ -109,102 +134,69 @@ int rds_send_xmit(struct rds_connection *conn) struct rds_message *rm; unsigned long flags; unsigned int tmp; - unsigned int send_quota = send_batch_count; struct scatterlist *sg; int ret = 0; - int was_empty = 0; LIST_HEAD(to_be_dropped); +restart: + /* * sendmsg calls here after having queued its message on the send * queue. We only have one task feeding the connection at a time. If * another thread is already feeding the queue then we back off. This * avoids blocking the caller and trading per-connection data between * caches per message. - * - * The sem holder will issue a retry if they notice that someone queued - * a message after they stopped walking the send queue but before they - * dropped the sem. */ - if (!mutex_trylock(&conn->c_send_lock)) { - rds_stats_inc(s_send_sem_contention); + if (!acquire_in_xmit(conn)) { + rds_stats_inc(s_send_lock_contention); ret = -ENOMEM; goto out; } + /* + * rds_conn_shutdown() sets the conn state and then tests RDS_IN_XMIT, + * we do the opposite to avoid races. + */ + if (!rds_conn_up(conn)) { + release_in_xmit(conn); + ret = 0; + goto out; + } + if (conn->c_trans->xmit_prepare) conn->c_trans->xmit_prepare(conn); /* * spin trying to push headers and data down the connection until - * the connection doens't make forward progress. + * the connection doesn't make forward progress. */ - while (--send_quota) { - /* - * See if need to send a congestion map update if we're - * between sending messages. The send_sem protects our sole - * use of c_map_offset and _bytes. - * Note this is used only by transports that define a special - * xmit_cong_map function. For all others, we create allocate - * a cong_map message and treat it just like any other send. - */ - if (conn->c_map_bytes) { - ret = conn->c_trans->xmit_cong_map(conn, conn->c_lcong, - conn->c_map_offset); - if (ret <= 0) - break; + while (1) { - conn->c_map_offset += ret; - conn->c_map_bytes -= ret; - if (conn->c_map_bytes) - continue; - } - - /* If we're done sending the current message, clear the - * offset and S/G temporaries. - */ rm = conn->c_xmit_rm; - if (rm != NULL && - conn->c_xmit_hdr_off == sizeof(struct rds_header) && - conn->c_xmit_sg == rm->m_nents) { - conn->c_xmit_rm = NULL; - conn->c_xmit_sg = 0; - conn->c_xmit_hdr_off = 0; - conn->c_xmit_data_off = 0; - conn->c_xmit_rdma_sent = 0; - - /* Release the reference to the previous message. */ - rds_message_put(rm); - rm = NULL; - } - /* If we're asked to send a cong map update, do so. + /* + * If between sending messages, we can send a pending congestion + * map update. */ - if (rm == NULL && test_and_clear_bit(0, &conn->c_map_queued)) { - if (conn->c_trans->xmit_cong_map != NULL) { - conn->c_map_offset = 0; - conn->c_map_bytes = sizeof(struct rds_header) + - RDS_CONG_MAP_BYTES; - continue; - } - + if (!rm && test_and_clear_bit(0, &conn->c_map_queued)) { rm = rds_cong_update_alloc(conn); if (IS_ERR(rm)) { ret = PTR_ERR(rm); break; } + rm->data.op_active = 1; conn->c_xmit_rm = rm; } /* - * Grab the next message from the send queue, if there is one. + * If not already working on one, grab the next message. * * c_xmit_rm holds a ref while we're sending this message down * the connction. We can use this ref while holding the * send_sem.. rds_send_reset() is serialized with it. */ - if (rm == NULL) { + if (!rm) { unsigned int len; spin_lock_irqsave(&conn->c_lock, flags); @@ -224,10 +216,8 @@ int rds_send_xmit(struct rds_connection *conn) spin_unlock_irqrestore(&conn->c_lock, flags); - if (rm == NULL) { - was_empty = 1; + if (!rm) break; - } /* Unfortunately, the way Infiniband deals with * RDMA to a bad MR key is by moving the entire @@ -236,13 +226,12 @@ int rds_send_xmit(struct rds_connection *conn) * connection. * Therefore, we never retransmit messages with RDMA ops. */ - if (rm->m_rdma_op && + if (rm->rdma.op_active && test_bit(RDS_MSG_RETRANSMITTED, &rm->m_flags)) { spin_lock_irqsave(&conn->c_lock, flags); if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) list_move(&rm->m_conn_item, &to_be_dropped); spin_unlock_irqrestore(&conn->c_lock, flags); - rds_message_put(rm); continue; } @@ -263,23 +252,55 @@ int rds_send_xmit(struct rds_connection *conn) conn->c_xmit_rm = rm; } - /* - * Try and send an rdma message. Let's see if we can - * keep this simple and require that the transport either - * send the whole rdma or none of it. - */ - if (rm->m_rdma_op && !conn->c_xmit_rdma_sent) { - ret = conn->c_trans->xmit_rdma(conn, rm->m_rdma_op); + /* The transport either sends the whole rdma or none of it */ + if (rm->rdma.op_active && !conn->c_xmit_rdma_sent) { + rm->m_final_op = &rm->rdma; + ret = conn->c_trans->xmit_rdma(conn, &rm->rdma); if (ret) break; conn->c_xmit_rdma_sent = 1; + /* The transport owns the mapped memory for now. * You can't unmap it while it's on the send queue */ set_bit(RDS_MSG_MAPPED, &rm->m_flags); } - if (conn->c_xmit_hdr_off < sizeof(struct rds_header) || - conn->c_xmit_sg < rm->m_nents) { + if (rm->atomic.op_active && !conn->c_xmit_atomic_sent) { + rm->m_final_op = &rm->atomic; + ret = conn->c_trans->xmit_atomic(conn, &rm->atomic); + if (ret) + break; + conn->c_xmit_atomic_sent = 1; + + /* The transport owns the mapped memory for now. + * You can't unmap it while it's on the send queue */ + set_bit(RDS_MSG_MAPPED, &rm->m_flags); + } + + /* + * A number of cases require an RDS header to be sent + * even if there is no data. + * We permit 0-byte sends; rds-ping depends on this. + * However, if there are exclusively attached silent ops, + * we skip the hdr/data send, to enable silent operation. + */ + if (rm->data.op_nents == 0) { + int ops_present; + int all_ops_are_silent = 1; + + ops_present = (rm->atomic.op_active || rm->rdma.op_active); + if (rm->atomic.op_active && !rm->atomic.op_silent) + all_ops_are_silent = 0; + if (rm->rdma.op_active && !rm->rdma.op_silent) + all_ops_are_silent = 0; + + if (ops_present && all_ops_are_silent + && !rm->m_rdma_cookie) + rm->data.op_active = 0; + } + + if (rm->data.op_active && !conn->c_xmit_data_sent) { + rm->m_final_op = &rm->data; ret = conn->c_trans->xmit(conn, rm, conn->c_xmit_hdr_off, conn->c_xmit_sg, @@ -295,7 +316,7 @@ int rds_send_xmit(struct rds_connection *conn) ret -= tmp; } - sg = &rm->m_sg[conn->c_xmit_sg]; + sg = &rm->data.op_sg[conn->c_xmit_sg]; while (ret) { tmp = min_t(int, ret, sg->length - conn->c_xmit_data_off); @@ -306,49 +327,63 @@ int rds_send_xmit(struct rds_connection *conn) sg++; conn->c_xmit_sg++; BUG_ON(ret != 0 && - conn->c_xmit_sg == rm->m_nents); + conn->c_xmit_sg == rm->data.op_nents); } } + + if (conn->c_xmit_hdr_off == sizeof(struct rds_header) && + (conn->c_xmit_sg == rm->data.op_nents)) + conn->c_xmit_data_sent = 1; } - } - /* Nuke any messages we decided not to retransmit. */ - if (!list_empty(&to_be_dropped)) - rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED); + /* + * A rm will only take multiple times through this loop + * if there is a data op. Thus, if the data is sent (or there was + * none), then we're done with the rm. + */ + if (!rm->data.op_active || conn->c_xmit_data_sent) { + conn->c_xmit_rm = NULL; + conn->c_xmit_sg = 0; + conn->c_xmit_hdr_off = 0; + conn->c_xmit_data_off = 0; + conn->c_xmit_rdma_sent = 0; + conn->c_xmit_atomic_sent = 0; + conn->c_xmit_data_sent = 0; + + rds_message_put(rm); + } + } if (conn->c_trans->xmit_complete) conn->c_trans->xmit_complete(conn); - /* - * We might be racing with another sender who queued a message but - * backed off on noticing that we held the c_send_lock. If we check - * for queued messages after dropping the sem then either we'll - * see the queued message or the queuer will get the sem. If we - * notice the queued message then we trigger an immediate retry. - * - * We need to be careful only to do this when we stopped processing - * the send queue because it was empty. It's the only way we - * stop processing the loop when the transport hasn't taken - * responsibility for forward progress. - */ - mutex_unlock(&conn->c_send_lock); + release_in_xmit(conn); - if (conn->c_map_bytes || (send_quota == 0 && !was_empty)) { - /* We exhausted the send quota, but there's work left to - * do. Return and (re-)schedule the send worker. - */ - ret = -EAGAIN; + /* Nuke any messages we decided not to retransmit. */ + if (!list_empty(&to_be_dropped)) { + /* irqs on here, so we can put(), unlike above */ + list_for_each_entry(rm, &to_be_dropped, m_conn_item) + rds_message_put(rm); + rds_send_remove_from_sock(&to_be_dropped, RDS_RDMA_DROPPED); } - if (ret == 0 && was_empty) { - /* A simple bit test would be way faster than taking the - * spin lock */ - spin_lock_irqsave(&conn->c_lock, flags); + /* + * Other senders can queue a message after we last test the send queue + * but before we clear RDS_IN_XMIT. In that case they'd back off and + * not try and send their newly queued message. We need to check the + * send queue after having cleared RDS_IN_XMIT so that their message + * doesn't get stuck on the send queue. + * + * If the transport cannot continue (i.e ret != 0), then it must + * call us when more room is available, such as from the tx + * completion handler. + */ + if (ret == 0) { + smp_mb(); if (!list_empty(&conn->c_send_queue)) { - rds_stats_inc(s_send_sem_queue_raced); - ret = -EAGAIN; + rds_stats_inc(s_send_lock_queue_raced); + goto restart; } - spin_unlock_irqrestore(&conn->c_lock, flags); } out: return ret; @@ -376,52 +411,60 @@ static inline int rds_send_is_acked(struct rds_message *rm, u64 ack, } /* - * Returns true if there are no messages on the send and retransmit queues - * which have a sequence number greater than or equal to the given sequence - * number. + * This is pretty similar to what happens below in the ACK + * handling code - except that we call here as soon as we get + * the IB send completion on the RDMA op and the accompanying + * message. */ -int rds_send_acked_before(struct rds_connection *conn, u64 seq) +void rds_rdma_send_complete(struct rds_message *rm, int status) { - struct rds_message *rm, *tmp; - int ret = 1; + struct rds_sock *rs = NULL; + struct rm_rdma_op *ro; + struct rds_notifier *notifier; + unsigned long flags; - spin_lock(&conn->c_lock); + spin_lock_irqsave(&rm->m_rs_lock, flags); - list_for_each_entry_safe(rm, tmp, &conn->c_retrans, m_conn_item) { - if (be64_to_cpu(rm->m_inc.i_hdr.h_sequence) < seq) - ret = 0; - break; - } + ro = &rm->rdma; + if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && + ro->op_active && ro->op_notify && ro->op_notifier) { + notifier = ro->op_notifier; + rs = rm->m_rs; + sock_hold(rds_rs_to_sk(rs)); - list_for_each_entry_safe(rm, tmp, &conn->c_send_queue, m_conn_item) { - if (be64_to_cpu(rm->m_inc.i_hdr.h_sequence) < seq) - ret = 0; - break; + notifier->n_status = status; + spin_lock(&rs->rs_lock); + list_add_tail(¬ifier->n_list, &rs->rs_notify_queue); + spin_unlock(&rs->rs_lock); + + ro->op_notifier = NULL; } - spin_unlock(&conn->c_lock); + spin_unlock_irqrestore(&rm->m_rs_lock, flags); - return ret; + if (rs) { + rds_wake_sk_sleep(rs); + sock_put(rds_rs_to_sk(rs)); + } } +EXPORT_SYMBOL_GPL(rds_rdma_send_complete); /* - * This is pretty similar to what happens below in the ACK - * handling code - except that we call here as soon as we get - * the IB send completion on the RDMA op and the accompanying - * message. + * Just like above, except looks at atomic op */ -void rds_rdma_send_complete(struct rds_message *rm, int status) +void rds_atomic_send_complete(struct rds_message *rm, int status) { struct rds_sock *rs = NULL; - struct rds_rdma_op *ro; + struct rm_atomic_op *ao; struct rds_notifier *notifier; + unsigned long flags; - spin_lock(&rm->m_rs_lock); + spin_lock_irqsave(&rm->m_rs_lock, flags); - ro = rm->m_rdma_op; - if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) && - ro && ro->r_notify && ro->r_notifier) { - notifier = ro->r_notifier; + ao = &rm->atomic; + if (test_bit(RDS_MSG_ON_SOCK, &rm->m_flags) + && ao->op_active && ao->op_notify && ao->op_notifier) { + notifier = ao->op_notifier; rs = rm->m_rs; sock_hold(rds_rs_to_sk(rs)); @@ -430,17 +473,17 @@ void rds_rdma_send_complete(struct rds_message *rm, int status) list_add_tail(¬ifier->n_list, &rs->rs_notify_queue); spin_unlock(&rs->rs_lock); - ro->r_notifier = NULL; + ao->op_notifier = NULL; } - spin_unlock(&rm->m_rs_lock); + spin_unlock_irqrestore(&rm->m_rs_lock, flags); if (rs) { rds_wake_sk_sleep(rs); sock_put(rds_rs_to_sk(rs)); } } -EXPORT_SYMBOL_GPL(rds_rdma_send_complete); +EXPORT_SYMBOL_GPL(rds_atomic_send_complete); /* * This is the same as rds_rdma_send_complete except we @@ -448,15 +491,23 @@ EXPORT_SYMBOL_GPL(rds_rdma_send_complete); * socket, socket lock) and can just move the notifier. */ static inline void -__rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status) +__rds_send_complete(struct rds_sock *rs, struct rds_message *rm, int status) { - struct rds_rdma_op *ro; + struct rm_rdma_op *ro; + struct rm_atomic_op *ao; + + ro = &rm->rdma; + if (ro->op_active && ro->op_notify && ro->op_notifier) { + ro->op_notifier->n_status = status; + list_add_tail(&ro->op_notifier->n_list, &rs->rs_notify_queue); + ro->op_notifier = NULL; + } - ro = rm->m_rdma_op; - if (ro && ro->r_notify && ro->r_notifier) { - ro->r_notifier->n_status = status; - list_add_tail(&ro->r_notifier->n_list, &rs->rs_notify_queue); - ro->r_notifier = NULL; + ao = &rm->atomic; + if (ao->op_active && ao->op_notify && ao->op_notifier) { + ao->op_notifier->n_status = status; + list_add_tail(&ao->op_notifier->n_list, &rs->rs_notify_queue); + ao->op_notifier = NULL; } /* No need to wake the app - caller does this */ @@ -468,7 +519,7 @@ __rds_rdma_send_complete(struct rds_sock *rs, struct rds_message *rm, int status * So speed is not an issue here. */ struct rds_message *rds_send_get_message(struct rds_connection *conn, - struct rds_rdma_op *op) + struct rm_rdma_op *op) { struct rds_message *rm, *tmp, *found = NULL; unsigned long flags; @@ -476,7 +527,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn, spin_lock_irqsave(&conn->c_lock, flags); list_for_each_entry_safe(rm, tmp, &conn->c_retrans, m_conn_item) { - if (rm->m_rdma_op == op) { + if (&rm->rdma == op) { atomic_inc(&rm->m_refcount); found = rm; goto out; @@ -484,7 +535,7 @@ struct rds_message *rds_send_get_message(struct rds_connection *conn, } list_for_each_entry_safe(rm, tmp, &conn->c_send_queue, m_conn_item) { - if (rm->m_rdma_op == op) { + if (&rm->rdma == op) { atomic_inc(&rm->m_refcount); found = rm; break; @@ -506,7 +557,7 @@ EXPORT_SYMBOL_GPL(rds_send_get_message); * removing the messages from the 'messages' list regardless of if it found * the messages on the socket list or not. */ -void rds_send_remove_from_sock(struct list_head *messages, int status) +static void rds_send_remove_from_sock(struct list_head *messages, int status) { unsigned long flags; struct rds_sock *rs = NULL; @@ -544,19 +595,20 @@ void rds_send_remove_from_sock(struct list_head *messages, int status) spin_lock(&rs->rs_lock); if (test_and_clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags)) { - struct rds_rdma_op *ro = rm->m_rdma_op; + struct rm_rdma_op *ro = &rm->rdma; struct rds_notifier *notifier; list_del_init(&rm->m_sock_item); rds_send_sndbuf_remove(rs, rm); - if (ro && ro->r_notifier && (status || ro->r_notify)) { - notifier = ro->r_notifier; + if (ro->op_active && ro->op_notifier && + (ro->op_notify || (ro->op_recverr && status))) { + notifier = ro->op_notifier; list_add_tail(¬ifier->n_list, &rs->rs_notify_queue); if (!notifier->n_status) notifier->n_status = status; - rm->m_rdma_op->r_notifier = NULL; + rm->rdma.op_notifier = NULL; } was_on_sock = 1; rm->m_rs = NULL; @@ -619,9 +671,8 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) { struct rds_message *rm, *tmp; struct rds_connection *conn; - unsigned long flags, flags2; + unsigned long flags; LIST_HEAD(list); - int wake = 0; /* get all the messages we're dropping under the rs lock */ spin_lock_irqsave(&rs->rs_lock, flags); @@ -631,59 +682,54 @@ void rds_send_drop_to(struct rds_sock *rs, struct sockaddr_in *dest) dest->sin_port != rm->m_inc.i_hdr.h_dport)) continue; - wake = 1; list_move(&rm->m_sock_item, &list); rds_send_sndbuf_remove(rs, rm); clear_bit(RDS_MSG_ON_SOCK, &rm->m_flags); } /* order flag updates with the rs lock */ - if (wake) - smp_mb__after_clear_bit(); + smp_mb__after_clear_bit(); spin_unlock_irqrestore(&rs->rs_lock, flags); - conn = NULL; + if (list_empty(&list)) + return; - /* now remove the messages from the conn list as needed */ + /* Remove the messages from the conn */ list_for_each_entry(rm, &list, m_sock_item) { - /* We do this here rather than in the loop above, so that - * we don't have to nest m_rs_lock under rs->rs_lock */ - spin_lock_irqsave(&rm->m_rs_lock, flags2); - /* If this is a RDMA operation, notify the app. */ - spin_lock(&rs->rs_lock); - __rds_rdma_send_complete(rs, rm, RDS_RDMA_CANCELED); - spin_unlock(&rs->rs_lock); - rm->m_rs = NULL; - spin_unlock_irqrestore(&rm->m_rs_lock, flags2); + conn = rm->m_inc.i_conn; + + spin_lock_irqsave(&conn->c_lock, flags); /* - * If we see this flag cleared then we're *sure* that someone - * else beat us to removing it from the conn. If we race - * with their flag update we'll get the lock and then really - * see that the flag has been cleared. + * Maybe someone else beat us to removing rm from the conn. + * If we race with their flag update we'll get the lock and + * then really see that the flag has been cleared. */ - if (!test_bit(RDS_MSG_ON_CONN, &rm->m_flags)) + if (!test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) { + spin_unlock_irqrestore(&conn->c_lock, flags); continue; - - if (conn != rm->m_inc.i_conn) { - if (conn) - spin_unlock_irqrestore(&conn->c_lock, flags); - conn = rm->m_inc.i_conn; - spin_lock_irqsave(&conn->c_lock, flags); } + list_del_init(&rm->m_conn_item); + spin_unlock_irqrestore(&conn->c_lock, flags); - if (test_and_clear_bit(RDS_MSG_ON_CONN, &rm->m_flags)) { - list_del_init(&rm->m_conn_item); - rds_message_put(rm); - } - } + /* + * Couldn't grab m_rs_lock in top loop (lock ordering), + * but we can now. + */ + spin_lock_irqsave(&rm->m_rs_lock, flags); - if (conn) - spin_unlock_irqrestore(&conn->c_lock, flags); + spin_lock(&rs->rs_lock); + __rds_send_complete(rs, rm, RDS_RDMA_CANCELED); + spin_unlock(&rs->rs_lock); - if (wake) - rds_wake_sk_sleep(rs); + rm->m_rs = NULL; + spin_unlock_irqrestore(&rm->m_rs_lock, flags); + + rds_message_put(rm); + } + + rds_wake_sk_sleep(rs); while (!list_empty(&list)) { rm = list_entry(list.next, struct rds_message, m_sock_item); @@ -763,6 +809,63 @@ static int rds_send_queue_rm(struct rds_sock *rs, struct rds_connection *conn, return *queued; } +/* + * rds_message is getting to be quite complicated, and we'd like to allocate + * it all in one go. This figures out how big it needs to be up front. + */ +static int rds_rm_size(struct msghdr *msg, int data_len) +{ + struct cmsghdr *cmsg; + int size = 0; + int cmsg_groups = 0; + int retval; + + for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (!CMSG_OK(msg, cmsg)) + return -EINVAL; + + if (cmsg->cmsg_level != SOL_RDS) + continue; + + switch (cmsg->cmsg_type) { + case RDS_CMSG_RDMA_ARGS: + cmsg_groups |= 1; + retval = rds_rdma_extra_size(CMSG_DATA(cmsg)); + if (retval < 0) + return retval; + size += retval; + + break; + + case RDS_CMSG_RDMA_DEST: + case RDS_CMSG_RDMA_MAP: + cmsg_groups |= 2; + /* these are valid but do no add any size */ + break; + + case RDS_CMSG_ATOMIC_CSWP: + case RDS_CMSG_ATOMIC_FADD: + case RDS_CMSG_MASKED_ATOMIC_CSWP: + case RDS_CMSG_MASKED_ATOMIC_FADD: + cmsg_groups |= 1; + size += sizeof(struct scatterlist); + break; + + default: + return -EINVAL; + } + + } + + size += ceil(data_len, PAGE_SIZE) * sizeof(struct scatterlist); + + /* Ensure (DEST, MAP) are never used with (ARGS, ATOMIC) */ + if (cmsg_groups == 3) + return -EINVAL; + + return size; +} + static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, struct msghdr *msg, int *allocated_mr) { @@ -777,7 +880,7 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, continue; /* As a side effect, RDMA_DEST and RDMA_MAP will set - * rm->m_rdma_cookie and rm->m_rdma_mr. + * rm->rdma.m_rdma_cookie and rm->rdma.m_rdma_mr. */ switch (cmsg->cmsg_type) { case RDS_CMSG_RDMA_ARGS: @@ -793,6 +896,12 @@ static int rds_cmsg_send(struct rds_sock *rs, struct rds_message *rm, if (!ret) *allocated_mr = 1; break; + case RDS_CMSG_ATOMIC_CSWP: + case RDS_CMSG_ATOMIC_FADD: + case RDS_CMSG_MASKED_ATOMIC_CSWP: + case RDS_CMSG_MASKED_ATOMIC_FADD: + ret = rds_cmsg_atomic(rs, rm, cmsg); + break; default: return -EINVAL; @@ -850,13 +959,26 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, goto out; } - rm = rds_message_copy_from_user(msg->msg_iov, payload_len); - if (IS_ERR(rm)) { - ret = PTR_ERR(rm); - rm = NULL; + /* size of rm including all sgs */ + ret = rds_rm_size(msg, payload_len); + if (ret < 0) + goto out; + + rm = rds_message_alloc(ret, GFP_KERNEL); + if (!rm) { + ret = -ENOMEM; goto out; } + /* Attach data to the rm */ + if (payload_len) { + rm->data.op_sg = rds_message_alloc_sgs(rm, ceil(payload_len, PAGE_SIZE)); + ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len); + if (ret) + goto out; + } + rm->data.op_active = 1; + rm->m_daddr = daddr; /* rds_conn_create has a spinlock that runs with IRQ off. @@ -879,22 +1001,23 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, if (ret) goto out; - if ((rm->m_rdma_cookie || rm->m_rdma_op) && - conn->c_trans->xmit_rdma == NULL) { + if (rm->rdma.op_active && !conn->c_trans->xmit_rdma) { if (printk_ratelimit()) printk(KERN_NOTICE "rdma_op %p conn xmit_rdma %p\n", - rm->m_rdma_op, conn->c_trans->xmit_rdma); + &rm->rdma, conn->c_trans->xmit_rdma); ret = -EOPNOTSUPP; goto out; } - /* If the connection is down, trigger a connect. We may - * have scheduled a delayed reconnect however - in this case - * we should not interfere. - */ - if (rds_conn_state(conn) == RDS_CONN_DOWN && - !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) - queue_delayed_work(rds_wq, &conn->c_conn_w, 0); + if (rm->atomic.op_active && !conn->c_trans->xmit_atomic) { + if (printk_ratelimit()) + printk(KERN_NOTICE "atomic_op %p conn xmit_atomic %p\n", + &rm->atomic, conn->c_trans->xmit_atomic); + ret = -EOPNOTSUPP; + goto out; + } + + rds_conn_connect_if_down(conn); ret = rds_cong_wait(conn->c_fcong, dport, nonblock, rs); if (ret) { @@ -938,7 +1061,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, rds_stats_inc(s_send_queued); if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags)) - rds_send_worker(&conn->c_send_w.work); + rds_send_xmit(conn); rds_message_put(rm); return payload_len; @@ -966,20 +1089,15 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) int ret = 0; rm = rds_message_alloc(0, GFP_ATOMIC); - if (rm == NULL) { + if (!rm) { ret = -ENOMEM; goto out; } rm->m_daddr = conn->c_faddr; + rm->data.op_active = 1; - /* If the connection is down, trigger a connect. We may - * have scheduled a delayed reconnect however - in this case - * we should not interfere. - */ - if (rds_conn_state(conn) == RDS_CONN_DOWN && - !test_and_set_bit(RDS_RECONNECT_PENDING, &conn->c_flags)) - queue_delayed_work(rds_wq, &conn->c_conn_w, 0); + rds_conn_connect_if_down(conn); ret = rds_cong_wait(conn->c_fcong, dport, 1, NULL); if (ret) @@ -999,7 +1117,9 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) rds_stats_inc(s_send_queued); rds_stats_inc(s_send_pong); - queue_delayed_work(rds_wq, &conn->c_send_w, 0); + if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags)) + rds_send_xmit(conn); + rds_message_put(rm); return 0; diff --git a/net/rds/stats.c b/net/rds/stats.c index 7598eb07cfb149264355695d4582f28e7b9b0962..10c759ccac0c7a5d134e1cd49b41c45651e657c1 100644 --- a/net/rds/stats.c +++ b/net/rds/stats.c @@ -57,8 +57,8 @@ static const char *const rds_stat_names[] = { "recv_ping", "send_queue_empty", "send_queue_full", - "send_sem_contention", - "send_sem_queue_raced", + "send_lock_contention", + "send_lock_queue_raced", "send_immediate_retry", "send_delayed_retry", "send_drop_acked", @@ -143,7 +143,7 @@ void rds_stats_exit(void) rds_info_deregister_func(RDS_INFO_COUNTERS, rds_stats_info); } -int __init rds_stats_init(void) +int rds_stats_init(void) { rds_info_register_func(RDS_INFO_COUNTERS, rds_stats_info); return 0; diff --git a/net/rds/sysctl.c b/net/rds/sysctl.c index 7829a20325d3281018dfe0520c450d47a066e890..25ad0c77a26cd16cca2d96681fae4f77373757bf 100644 --- a/net/rds/sysctl.c +++ b/net/rds/sysctl.c @@ -105,13 +105,13 @@ void rds_sysctl_exit(void) unregister_sysctl_table(rds_sysctl_reg_table); } -int __init rds_sysctl_init(void) +int rds_sysctl_init(void) { rds_sysctl_reconnect_min = msecs_to_jiffies(1); rds_sysctl_reconnect_min_jiffies = rds_sysctl_reconnect_min; rds_sysctl_reg_table = register_sysctl_paths(rds_sysctl_path, rds_sysctl_rds_table); - if (rds_sysctl_reg_table == NULL) + if (!rds_sysctl_reg_table) return -ENOMEM; return 0; } diff --git a/net/rds/tcp.c b/net/rds/tcp.c index babf4577ff7d3f06835e073e48733edeceb97db3..08a8c6cf2d100f8f05a6c932d8190326277747e9 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -41,7 +41,7 @@ /* only for info exporting */ static DEFINE_SPINLOCK(rds_tcp_tc_list_lock); static LIST_HEAD(rds_tcp_tc_list); -unsigned int rds_tcp_tc_count; +static unsigned int rds_tcp_tc_count; /* Track rds_tcp_connection structs so they can be cleaned up */ static DEFINE_SPINLOCK(rds_tcp_conn_lock); @@ -200,7 +200,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) struct rds_tcp_connection *tc; tc = kmem_cache_alloc(rds_tcp_conn_slab, gfp); - if (tc == NULL) + if (!tc) return -ENOMEM; tc->t_sock = NULL; @@ -243,7 +243,7 @@ static void rds_tcp_destroy_conns(void) } } -void rds_tcp_exit(void) +static void rds_tcp_exit(void) { rds_info_deregister_func(RDS_INFO_TCP_SOCKETS, rds_tcp_tc_info); rds_tcp_listen_stop(); @@ -258,7 +258,6 @@ struct rds_transport rds_tcp_transport = { .laddr_check = rds_tcp_laddr_check, .xmit_prepare = rds_tcp_xmit_prepare, .xmit_complete = rds_tcp_xmit_complete, - .xmit_cong_map = rds_tcp_xmit_cong_map, .xmit = rds_tcp_xmit, .recv = rds_tcp_recv, .conn_alloc = rds_tcp_conn_alloc, @@ -266,7 +265,6 @@ struct rds_transport rds_tcp_transport = { .conn_connect = rds_tcp_conn_connect, .conn_shutdown = rds_tcp_conn_shutdown, .inc_copy_to_user = rds_tcp_inc_copy_to_user, - .inc_purge = rds_tcp_inc_purge, .inc_free = rds_tcp_inc_free, .stats_info_copy = rds_tcp_stats_info_copy, .exit = rds_tcp_exit, @@ -276,14 +274,14 @@ struct rds_transport rds_tcp_transport = { .t_prefer_loopback = 1, }; -int __init rds_tcp_init(void) +static int rds_tcp_init(void) { int ret; rds_tcp_conn_slab = kmem_cache_create("rds_tcp_connection", sizeof(struct rds_tcp_connection), 0, 0, NULL); - if (rds_tcp_conn_slab == NULL) { + if (!rds_tcp_conn_slab) { ret = -ENOMEM; goto out; } diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 844fa6b9cf5aeb2e5bc1a9cad3a3b2b747449929..9cf2927d0021445f4e4e54f906b989e87c49f3f1 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h @@ -43,8 +43,6 @@ struct rds_tcp_statistics { }; /* tcp.c */ -int __init rds_tcp_init(void); -void rds_tcp_exit(void); void rds_tcp_tune(struct socket *sock); void rds_tcp_nonagle(struct socket *sock); void rds_tcp_set_callbacks(struct socket *sock, struct rds_connection *conn); @@ -61,16 +59,15 @@ void rds_tcp_conn_shutdown(struct rds_connection *conn); void rds_tcp_state_change(struct sock *sk); /* tcp_listen.c */ -int __init rds_tcp_listen_init(void); +int rds_tcp_listen_init(void); void rds_tcp_listen_stop(void); void rds_tcp_listen_data_ready(struct sock *sk, int bytes); /* tcp_recv.c */ -int __init rds_tcp_recv_init(void); +int rds_tcp_recv_init(void); void rds_tcp_recv_exit(void); void rds_tcp_data_ready(struct sock *sk, int bytes); int rds_tcp_recv(struct rds_connection *conn); -void rds_tcp_inc_purge(struct rds_incoming *inc); void rds_tcp_inc_free(struct rds_incoming *inc); int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov, size_t size); @@ -81,8 +78,6 @@ void rds_tcp_xmit_complete(struct rds_connection *conn); int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off); void rds_tcp_write_space(struct sock *sk); -int rds_tcp_xmit_cong_map(struct rds_connection *conn, - struct rds_cong_map *map, unsigned long offset); /* tcp_stats.c */ DECLARE_PER_CPU(struct rds_tcp_statistics, rds_tcp_stats); diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c index c519939e8da98fd3ae8252355a0ebb9efac4acd5..af95c8e058fc0d45096234aa8aeb7c8da6fda175 100644 --- a/net/rds/tcp_connect.c +++ b/net/rds/tcp_connect.c @@ -45,7 +45,7 @@ void rds_tcp_state_change(struct sock *sk) read_lock_bh(&sk->sk_callback_lock); conn = sk->sk_user_data; - if (conn == NULL) { + if (!conn) { state_change = sk->sk_state_change; goto out; } diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 27844f231d103a4e49e542d670eaca66d01e761d..8b5cc4aa8868702cc743a87c96a100e58809865f 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c @@ -116,7 +116,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) read_lock_bh(&sk->sk_callback_lock); ready = sk->sk_user_data; - if (ready == NULL) { /* check for teardown race */ + if (!ready) { /* check for teardown race */ ready = sk->sk_data_ready; goto out; } @@ -135,7 +135,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes) ready(sk, bytes); } -int __init rds_tcp_listen_init(void) +int rds_tcp_listen_init(void) { struct sockaddr_in sin; struct socket *sock = NULL; @@ -178,7 +178,7 @@ void rds_tcp_listen_stop(void) struct socket *sock = rds_tcp_listen_sock; struct sock *sk; - if (sock == NULL) + if (!sock) return; sk = sock->sk; diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c index e43797404102efcc2ed45117456e839b5425adb1..78205e25500a5b40d5ec64a59b35c4c07062f62c 100644 --- a/net/rds/tcp_recv.c +++ b/net/rds/tcp_recv.c @@ -39,7 +39,7 @@ static struct kmem_cache *rds_tcp_incoming_slab; -void rds_tcp_inc_purge(struct rds_incoming *inc) +static void rds_tcp_inc_purge(struct rds_incoming *inc) { struct rds_tcp_incoming *tinc; tinc = container_of(inc, struct rds_tcp_incoming, ti_inc); @@ -190,10 +190,10 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb, * processing. */ while (left) { - if (tinc == NULL) { + if (!tinc) { tinc = kmem_cache_alloc(rds_tcp_incoming_slab, arg->gfp); - if (tinc == NULL) { + if (!tinc) { desc->error = -ENOMEM; goto out; } @@ -229,7 +229,7 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb, if (left && tc->t_tinc_data_rem) { clone = skb_clone(skb, arg->gfp); - if (clone == NULL) { + if (!clone) { desc->error = -ENOMEM; goto out; } @@ -272,7 +272,8 @@ static int rds_tcp_data_recv(read_descriptor_t *desc, struct sk_buff *skb, } /* the caller has to hold the sock lock */ -int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp, enum km_type km) +static int rds_tcp_read_sock(struct rds_connection *conn, gfp_t gfp, + enum km_type km) { struct rds_tcp_connection *tc = conn->c_transport_data; struct socket *sock = tc->t_sock; @@ -326,7 +327,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) read_lock_bh(&sk->sk_callback_lock); conn = sk->sk_user_data; - if (conn == NULL) { /* check for teardown race */ + if (!conn) { /* check for teardown race */ ready = sk->sk_data_ready; goto out; } @@ -342,12 +343,12 @@ void rds_tcp_data_ready(struct sock *sk, int bytes) ready(sk, bytes); } -int __init rds_tcp_recv_init(void) +int rds_tcp_recv_init(void) { rds_tcp_incoming_slab = kmem_cache_create("rds_tcp_incoming", sizeof(struct rds_tcp_incoming), 0, 0, NULL); - if (rds_tcp_incoming_slab == NULL) + if (!rds_tcp_incoming_slab) return -ENOMEM; return 0; } diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index 2f012a07d94d16d3aa01d4c78d0894e939dfd751..1b4fd68f0c7c4db1f97859f407cded3a1e4f8144 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c @@ -63,7 +63,7 @@ void rds_tcp_xmit_complete(struct rds_connection *conn) } /* the core send_sem serializes this with other xmit and shutdown */ -int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) +static int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) { struct kvec vec = { .iov_base = data, @@ -76,56 +76,6 @@ int rds_tcp_sendmsg(struct socket *sock, void *data, unsigned int len) return kernel_sendmsg(sock, &msg, &vec, 1, vec.iov_len); } -/* the core send_sem serializes this with other xmit and shutdown */ -int rds_tcp_xmit_cong_map(struct rds_connection *conn, - struct rds_cong_map *map, unsigned long offset) -{ - static struct rds_header rds_tcp_map_header = { - .h_flags = RDS_FLAG_CONG_BITMAP, - }; - struct rds_tcp_connection *tc = conn->c_transport_data; - unsigned long i; - int ret; - int copied = 0; - - /* Some problem claims cpu_to_be32(constant) isn't a constant. */ - rds_tcp_map_header.h_len = cpu_to_be32(RDS_CONG_MAP_BYTES); - - if (offset < sizeof(struct rds_header)) { - ret = rds_tcp_sendmsg(tc->t_sock, - (void *)&rds_tcp_map_header + offset, - sizeof(struct rds_header) - offset); - if (ret <= 0) - return ret; - offset += ret; - copied = ret; - if (offset < sizeof(struct rds_header)) - return ret; - } - - offset -= sizeof(struct rds_header); - i = offset / PAGE_SIZE; - offset = offset % PAGE_SIZE; - BUG_ON(i >= RDS_CONG_MAP_PAGES); - - do { - ret = tc->t_sock->ops->sendpage(tc->t_sock, - virt_to_page(map->m_page_addrs[i]), - offset, PAGE_SIZE - offset, - MSG_DONTWAIT); - if (ret <= 0) - break; - copied += ret; - offset += ret; - if (offset == PAGE_SIZE) { - offset = 0; - i++; - } - } while (i < RDS_CONG_MAP_PAGES); - - return copied ? copied : ret; -} - /* the core send_sem serializes this with other xmit and shutdown */ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, unsigned int hdr_off, unsigned int sg, unsigned int off) @@ -166,21 +116,21 @@ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, goto out; } - while (sg < rm->m_nents) { + while (sg < rm->data.op_nents) { ret = tc->t_sock->ops->sendpage(tc->t_sock, - sg_page(&rm->m_sg[sg]), - rm->m_sg[sg].offset + off, - rm->m_sg[sg].length - off, + sg_page(&rm->data.op_sg[sg]), + rm->data.op_sg[sg].offset + off, + rm->data.op_sg[sg].length - off, MSG_DONTWAIT|MSG_NOSIGNAL); - rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->m_sg[sg]), - rm->m_sg[sg].offset + off, rm->m_sg[sg].length - off, + rdsdebug("tcp sendpage %p:%u:%u ret %d\n", (void *)sg_page(&rm->data.op_sg[sg]), + rm->data.op_sg[sg].offset + off, rm->data.op_sg[sg].length - off, ret); if (ret <= 0) break; off += ret; done += ret; - if (off == rm->m_sg[sg].length) { + if (off == rm->data.op_sg[sg].length) { off = 0; sg++; } @@ -226,7 +176,7 @@ void rds_tcp_write_space(struct sock *sk) read_lock_bh(&sk->sk_callback_lock); conn = sk->sk_user_data; - if (conn == NULL) { + if (!conn) { write_space = sk->sk_write_space; goto out; } diff --git a/net/rds/threads.c b/net/rds/threads.c index 786c20eaaf5e44a1cb1a2d7bdd284c7ad2cedf53..0fd90f8c5f59c75c18c244701f3230f93c408d85 100644 --- a/net/rds/threads.c +++ b/net/rds/threads.c @@ -61,7 +61,7 @@ * * Transition to state DISCONNECTING/DOWN: * - Inside the shutdown worker; synchronizes with xmit path - * through c_send_lock, and with connection management callbacks + * through RDS_IN_XMIT, and with connection management callbacks * via c_cm_lock. * * For receive callbacks, we rely on the underlying transport @@ -110,7 +110,7 @@ EXPORT_SYMBOL_GPL(rds_connect_complete); * We should *always* start with a random backoff; otherwise a broken connection * will always take several iterations to be re-established. */ -static void rds_queue_reconnect(struct rds_connection *conn) +void rds_queue_reconnect(struct rds_connection *conn) { unsigned long rand; @@ -156,58 +156,6 @@ void rds_connect_worker(struct work_struct *work) } } -void rds_shutdown_worker(struct work_struct *work) -{ - struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w); - - /* shut it down unless it's down already */ - if (!rds_conn_transition(conn, RDS_CONN_DOWN, RDS_CONN_DOWN)) { - /* - * Quiesce the connection mgmt handlers before we start tearing - * things down. We don't hold the mutex for the entire - * duration of the shutdown operation, else we may be - * deadlocking with the CM handler. Instead, the CM event - * handler is supposed to check for state DISCONNECTING - */ - mutex_lock(&conn->c_cm_lock); - if (!rds_conn_transition(conn, RDS_CONN_UP, RDS_CONN_DISCONNECTING) && - !rds_conn_transition(conn, RDS_CONN_ERROR, RDS_CONN_DISCONNECTING)) { - rds_conn_error(conn, "shutdown called in state %d\n", - atomic_read(&conn->c_state)); - mutex_unlock(&conn->c_cm_lock); - return; - } - mutex_unlock(&conn->c_cm_lock); - - mutex_lock(&conn->c_send_lock); - conn->c_trans->conn_shutdown(conn); - rds_conn_reset(conn); - mutex_unlock(&conn->c_send_lock); - - if (!rds_conn_transition(conn, RDS_CONN_DISCONNECTING, RDS_CONN_DOWN)) { - /* This can happen - eg when we're in the middle of tearing - * down the connection, and someone unloads the rds module. - * Quite reproduceable with loopback connections. - * Mostly harmless. - */ - rds_conn_error(conn, - "%s: failed to transition to state DOWN, " - "current state is %d\n", - __func__, - atomic_read(&conn->c_state)); - return; - } - } - - /* Then reconnect if it's still live. - * The passive side of an IB loopback connection is never added - * to the conn hash, so we never trigger a reconnect on this - * conn - the reconnect is always triggered by the active peer. */ - cancel_delayed_work(&conn->c_conn_w); - if (!hlist_unhashed(&conn->c_hash_node)) - rds_queue_reconnect(conn); -} - void rds_send_worker(struct work_struct *work) { struct rds_connection *conn = container_of(work, struct rds_connection, c_send_w.work); @@ -252,15 +200,22 @@ void rds_recv_worker(struct work_struct *work) } } +void rds_shutdown_worker(struct work_struct *work) +{ + struct rds_connection *conn = container_of(work, struct rds_connection, c_down_w); + + rds_conn_shutdown(conn); +} + void rds_threads_exit(void) { destroy_workqueue(rds_wq); } -int __init rds_threads_init(void) +int rds_threads_init(void) { - rds_wq = create_workqueue("krdsd"); - if (rds_wq == NULL) + rds_wq = create_singlethread_workqueue("krdsd"); + if (!rds_wq) return -ENOMEM; return 0; diff --git a/net/rds/transport.c b/net/rds/transport.c index 7e106790135353c036d6fa0dcba3345cf072f3dd..7f2ac4fec3678b28715b95094c6346bcc49333e1 100644 --- a/net/rds/transport.c +++ b/net/rds/transport.c @@ -71,19 +71,28 @@ void rds_trans_unregister(struct rds_transport *trans) } EXPORT_SYMBOL_GPL(rds_trans_unregister); +void rds_trans_put(struct rds_transport *trans) +{ + if (trans && trans->t_owner) + module_put(trans->t_owner); +} + struct rds_transport *rds_trans_get_preferred(__be32 addr) { struct rds_transport *ret = NULL; - int i; + struct rds_transport *trans; + unsigned int i; if (IN_LOOPBACK(ntohl(addr))) return &rds_loop_transport; down_read(&rds_trans_sem); - for (i = 0; i < RDS_TRANS_COUNT; i++) - { - if (transports[i] && (transports[i]->laddr_check(addr) == 0)) { - ret = transports[i]; + for (i = 0; i < RDS_TRANS_COUNT; i++) { + trans = transports[i]; + + if (trans && (trans->laddr_check(addr) == 0) && + (!trans->t_owner || try_module_get(trans->t_owner))) { + ret = trans; break; } } diff --git a/net/rds/xlist.h b/net/rds/xlist.h new file mode 100644 index 0000000000000000000000000000000000000000..e6b5190dadddc7307d80bc0bc87bc2dc4436ded6 --- /dev/null +++ b/net/rds/xlist.h @@ -0,0 +1,80 @@ +#ifndef _LINUX_XLIST_H +#define _LINUX_XLIST_H + +#include +#include +#include +#include + +struct xlist_head { + struct xlist_head *next; +}; + +static inline void INIT_XLIST_HEAD(struct xlist_head *list) +{ + list->next = NULL; +} + +static inline int xlist_empty(struct xlist_head *head) +{ + return head->next == NULL; +} + +static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail, + struct xlist_head *head) +{ + struct xlist_head *cur; + struct xlist_head *check; + + while (1) { + cur = head->next; + tail->next = cur; + check = cmpxchg(&head->next, cur, new); + if (check == cur) + break; + } +} + +static inline struct xlist_head *xlist_del_head(struct xlist_head *head) +{ + struct xlist_head *cur; + struct xlist_head *check; + struct xlist_head *next; + + while (1) { + cur = head->next; + if (!cur) + goto out; + + next = cur->next; + check = cmpxchg(&head->next, cur, next); + if (check == cur) + goto out; + } +out: + return cur; +} + +static inline struct xlist_head *xlist_del_head_fast(struct xlist_head *head) +{ + struct xlist_head *cur; + + cur = head->next; + if (!cur) + return NULL; + + head->next = cur->next; + return cur; +} + +static inline void xlist_splice(struct xlist_head *list, + struct xlist_head *head) +{ + struct xlist_head *cur; + + WARN_ON(head->next); + cur = xchg(&list->next, NULL); + head->next = cur; +} + +#endif diff --git a/net/rfkill/input.c b/net/rfkill/input.c index 3713d7ecab96b85ccde3024a763aa100e94ca683..1bca6d49ec968bbe32cc75248f07ea6fa59265df 100644 --- a/net/rfkill/input.c +++ b/net/rfkill/input.c @@ -142,7 +142,7 @@ static unsigned long rfkill_last_scheduled; static unsigned long rfkill_ratelimit(const unsigned long last) { const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY); - return (time_after(jiffies, last + delay)) ? 0 : delay; + return time_after(jiffies, last + delay) ? 0 : delay; } static void rfkill_schedule_ratelimited(void) diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c index a750a28e02219770539fcfe08b0010fe9cca0cdd..fa5f5641a2c24c0e907d8b6251dbf1ac2ed63f64 100644 --- a/net/rose/rose_link.c +++ b/net/rose/rose_link.c @@ -114,7 +114,7 @@ static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh) if (ax25s) ax25_cb_put(ax25s); - return (neigh->ax25 != NULL); + return neigh->ax25 != NULL; } /* @@ -137,7 +137,7 @@ static int rose_link_up(struct rose_neigh *neigh) if (ax25s) ax25_cb_put(ax25s); - return (neigh->ax25 != NULL); + return neigh->ax25 != NULL; } /* diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 2f691fb180d127751877003af00e624334da474c..a36270a994d763d75f5d1c7cff272d0305a88835 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -518,6 +518,16 @@ config NET_ACT_SKBEDIT To compile this code as a module, choose M here: the module will be called act_skbedit. +config NET_ACT_CSUM + tristate "Checksum Updating" + depends on NET_CLS_ACT && INET + ---help--- + Say Y here to update some common checksum after some direct + packet alterations. + + To compile this code as a module, choose M here: the + module will be called act_csum. + config NET_CLS_IND bool "Incoming device classification" depends on NET_CLS_U32 || NET_CLS_FW diff --git a/net/sched/Makefile b/net/sched/Makefile index f14e71bfa58fdcea59bf31485ea1f26ae998574a..960f5dba63041559835978dd0c5d63c2d3229436 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_NET_ACT_NAT) += act_nat.o obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o +obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c new file mode 100644 index 0000000000000000000000000000000000000000..67dc7ce9b63ad0796d038058ceeeaf7672ac2361 --- /dev/null +++ b/net/sched/act_csum.c @@ -0,0 +1,595 @@ +/* + * Checksum updating actions + * + * Copyright (c) 2010 Gregoire Baron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#define CSUM_TAB_MASK 15 +static struct tcf_common *tcf_csum_ht[CSUM_TAB_MASK + 1]; +static u32 csum_idx_gen; +static DEFINE_RWLOCK(csum_lock); + +static struct tcf_hashinfo csum_hash_info = { + .htab = tcf_csum_ht, + .hmask = CSUM_TAB_MASK, + .lock = &csum_lock, +}; + +static const struct nla_policy csum_policy[TCA_CSUM_MAX + 1] = { + [TCA_CSUM_PARMS] = { .len = sizeof(struct tc_csum), }, +}; + +static int tcf_csum_init(struct nlattr *nla, struct nlattr *est, + struct tc_action *a, int ovr, int bind) +{ + struct nlattr *tb[TCA_CSUM_MAX + 1]; + struct tc_csum *parm; + struct tcf_common *pc; + struct tcf_csum *p; + int ret = 0, err; + + if (nla == NULL) + return -EINVAL; + + err = nla_parse_nested(tb, TCA_CSUM_MAX, nla,csum_policy); + if (err < 0) + return err; + + if (tb[TCA_CSUM_PARMS] == NULL) + return -EINVAL; + parm = nla_data(tb[TCA_CSUM_PARMS]); + + pc = tcf_hash_check(parm->index, a, bind, &csum_hash_info); + if (!pc) { + pc = tcf_hash_create(parm->index, est, a, sizeof(*p), bind, + &csum_idx_gen, &csum_hash_info); + if (IS_ERR(pc)) + return PTR_ERR(pc); + p = to_tcf_csum(pc); + ret = ACT_P_CREATED; + } else { + p = to_tcf_csum(pc); + if (!ovr) { + tcf_hash_release(pc, bind, &csum_hash_info); + return -EEXIST; + } + } + + spin_lock_bh(&p->tcf_lock); + p->tcf_action = parm->action; + p->update_flags = parm->update_flags; + spin_unlock_bh(&p->tcf_lock); + + if (ret == ACT_P_CREATED) + tcf_hash_insert(pc, &csum_hash_info); + + return ret; +} + +static int tcf_csum_cleanup(struct tc_action *a, int bind) +{ + struct tcf_csum *p = a->priv; + return tcf_hash_release(&p->common, bind, &csum_hash_info); +} + +/** + * tcf_csum_skb_nextlayer - Get next layer pointer + * @skb: sk_buff to use + * @ihl: previous summed headers length + * @ipl: complete packet length + * @jhl: next header length + * + * Check the expected next layer availability in the specified sk_buff. + * Return the next layer pointer if pass, NULL otherwise. + */ +static void *tcf_csum_skb_nextlayer(struct sk_buff *skb, + unsigned int ihl, unsigned int ipl, + unsigned int jhl) +{ + int ntkoff = skb_network_offset(skb); + int hl = ihl + jhl; + + if (!pskb_may_pull(skb, ipl + ntkoff) || (ipl < hl) || + (skb_cloned(skb) && + !skb_clone_writable(skb, hl + ntkoff) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) + return NULL; + else + return (void *)(skb_network_header(skb) + ihl); +} + +static int tcf_csum_ipv4_icmp(struct sk_buff *skb, + unsigned int ihl, unsigned int ipl) +{ + struct icmphdr *icmph; + + icmph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmph)); + if (icmph == NULL) + return 0; + + icmph->checksum = 0; + skb->csum = csum_partial(icmph, ipl - ihl, 0); + icmph->checksum = csum_fold(skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv4_igmp(struct sk_buff *skb, + unsigned int ihl, unsigned int ipl) +{ + struct igmphdr *igmph; + + igmph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*igmph)); + if (igmph == NULL) + return 0; + + igmph->csum = 0; + skb->csum = csum_partial(igmph, ipl - ihl, 0); + igmph->csum = csum_fold(skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv6_icmp(struct sk_buff *skb, struct ipv6hdr *ip6h, + unsigned int ihl, unsigned int ipl) +{ + struct icmp6hdr *icmp6h; + + icmp6h = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*icmp6h)); + if (icmp6h == NULL) + return 0; + + icmp6h->icmp6_cksum = 0; + skb->csum = csum_partial(icmp6h, ipl - ihl, 0); + icmp6h->icmp6_cksum = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + ipl - ihl, IPPROTO_ICMPV6, + skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv4_tcp(struct sk_buff *skb, struct iphdr *iph, + unsigned int ihl, unsigned int ipl) +{ + struct tcphdr *tcph; + + tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph)); + if (tcph == NULL) + return 0; + + tcph->check = 0; + skb->csum = csum_partial(tcph, ipl - ihl, 0); + tcph->check = tcp_v4_check(ipl - ihl, + iph->saddr, iph->daddr, skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv6_tcp(struct sk_buff *skb, struct ipv6hdr *ip6h, + unsigned int ihl, unsigned int ipl) +{ + struct tcphdr *tcph; + + tcph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*tcph)); + if (tcph == NULL) + return 0; + + tcph->check = 0; + skb->csum = csum_partial(tcph, ipl - ihl, 0); + tcph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + ipl - ihl, IPPROTO_TCP, + skb->csum); + + skb->ip_summed = CHECKSUM_NONE; + + return 1; +} + +static int tcf_csum_ipv4_udp(struct sk_buff *skb, struct iphdr *iph, + unsigned int ihl, unsigned int ipl, int udplite) +{ + struct udphdr *udph; + u16 ul; + + /* + * Support both UDP and UDPLITE checksum algorithms, Don't use + * udph->len to get the real length without any protocol check, + * UDPLITE uses udph->len for another thing, + * Use iph->tot_len, or just ipl. + */ + + udph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*udph)); + if (udph == NULL) + return 0; + + ul = ntohs(udph->len); + + if (udplite || udph->check) { + + udph->check = 0; + + if (udplite) { + if (ul == 0) + skb->csum = csum_partial(udph, ipl - ihl, 0); + else if ((ul >= sizeof(*udph)) && (ul <= ipl - ihl)) + skb->csum = csum_partial(udph, ul, 0); + else + goto ignore_obscure_skb; + } else { + if (ul != ipl - ihl) + goto ignore_obscure_skb; + + skb->csum = csum_partial(udph, ul, 0); + } + + udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, + ul, iph->protocol, + skb->csum); + + if (!udph->check) + udph->check = CSUM_MANGLED_0; + } + + skb->ip_summed = CHECKSUM_NONE; + +ignore_obscure_skb: + return 1; +} + +static int tcf_csum_ipv6_udp(struct sk_buff *skb, struct ipv6hdr *ip6h, + unsigned int ihl, unsigned int ipl, int udplite) +{ + struct udphdr *udph; + u16 ul; + + /* + * Support both UDP and UDPLITE checksum algorithms, Don't use + * udph->len to get the real length without any protocol check, + * UDPLITE uses udph->len for another thing, + * Use ip6h->payload_len + sizeof(*ip6h) ... , or just ipl. + */ + + udph = tcf_csum_skb_nextlayer(skb, ihl, ipl, sizeof(*udph)); + if (udph == NULL) + return 0; + + ul = ntohs(udph->len); + + udph->check = 0; + + if (udplite) { + if (ul == 0) + skb->csum = csum_partial(udph, ipl - ihl, 0); + + else if ((ul >= sizeof(*udph)) && (ul <= ipl - ihl)) + skb->csum = csum_partial(udph, ul, 0); + + else + goto ignore_obscure_skb; + } else { + if (ul != ipl - ihl) + goto ignore_obscure_skb; + + skb->csum = csum_partial(udph, ul, 0); + } + + udph->check = csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, ul, + udplite ? IPPROTO_UDPLITE : IPPROTO_UDP, + skb->csum); + + if (!udph->check) + udph->check = CSUM_MANGLED_0; + + skb->ip_summed = CHECKSUM_NONE; + +ignore_obscure_skb: + return 1; +} + +static int tcf_csum_ipv4(struct sk_buff *skb, u32 update_flags) +{ + struct iphdr *iph; + int ntkoff; + + ntkoff = skb_network_offset(skb); + + if (!pskb_may_pull(skb, sizeof(*iph) + ntkoff)) + goto fail; + + iph = ip_hdr(skb); + + switch (iph->frag_off & htons(IP_OFFSET) ? 0 : iph->protocol) { + case IPPROTO_ICMP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP) + if (!tcf_csum_ipv4_icmp(skb, iph->ihl * 4, + ntohs(iph->tot_len))) + goto fail; + break; + case IPPROTO_IGMP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_IGMP) + if (!tcf_csum_ipv4_igmp(skb, iph->ihl * 4, + ntohs(iph->tot_len))) + goto fail; + break; + case IPPROTO_TCP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) + if (!tcf_csum_ipv4_tcp(skb, iph, iph->ihl * 4, + ntohs(iph->tot_len))) + goto fail; + break; + case IPPROTO_UDP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) + if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4, + ntohs(iph->tot_len), 0)) + goto fail; + break; + case IPPROTO_UDPLITE: + if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) + if (!tcf_csum_ipv4_udp(skb, iph, iph->ihl * 4, + ntohs(iph->tot_len), 1)) + goto fail; + break; + } + + if (update_flags & TCA_CSUM_UPDATE_FLAG_IPV4HDR) { + if (skb_cloned(skb) && + !skb_clone_writable(skb, sizeof(*iph) + ntkoff) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto fail; + + ip_send_check(iph); + } + + return 1; + +fail: + return 0; +} + +static int tcf_csum_ipv6_hopopts(struct ipv6_opt_hdr *ip6xh, + unsigned int ixhl, unsigned int *pl) +{ + int off, len, optlen; + unsigned char *xh = (void *)ip6xh; + + off = sizeof(*ip6xh); + len = ixhl - off; + + while (len > 1) { + switch (xh[off]) { + case IPV6_TLV_PAD0: + optlen = 1; + break; + case IPV6_TLV_JUMBO: + optlen = xh[off + 1] + 2; + if (optlen != 6 || len < 6 || (off & 3) != 2) + /* wrong jumbo option length/alignment */ + return 0; + *pl = ntohl(*(__be32 *)(xh + off + 2)); + goto done; + default: + optlen = xh[off + 1] + 2; + if (optlen > len) + /* ignore obscure options */ + goto done; + break; + } + off += optlen; + len -= optlen; + } + +done: + return 1; +} + +static int tcf_csum_ipv6(struct sk_buff *skb, u32 update_flags) +{ + struct ipv6hdr *ip6h; + struct ipv6_opt_hdr *ip6xh; + unsigned int hl, ixhl; + unsigned int pl; + int ntkoff; + u8 nexthdr; + + ntkoff = skb_network_offset(skb); + + hl = sizeof(*ip6h); + + if (!pskb_may_pull(skb, hl + ntkoff)) + goto fail; + + ip6h = ipv6_hdr(skb); + + pl = ntohs(ip6h->payload_len); + nexthdr = ip6h->nexthdr; + + do { + switch (nexthdr) { + case NEXTHDR_FRAGMENT: + goto ignore_skb; + case NEXTHDR_ROUTING: + case NEXTHDR_HOP: + case NEXTHDR_DEST: + if (!pskb_may_pull(skb, hl + sizeof(*ip6xh) + ntkoff)) + goto fail; + ip6xh = (void *)(skb_network_header(skb) + hl); + ixhl = ipv6_optlen(ip6xh); + if (!pskb_may_pull(skb, hl + ixhl + ntkoff)) + goto fail; + if ((nexthdr == NEXTHDR_HOP) && + !(tcf_csum_ipv6_hopopts(ip6xh, ixhl, &pl))) + goto fail; + nexthdr = ip6xh->nexthdr; + hl += ixhl; + break; + case IPPROTO_ICMPV6: + if (update_flags & TCA_CSUM_UPDATE_FLAG_ICMP) + if (!tcf_csum_ipv6_icmp(skb, ip6h, + hl, pl + sizeof(*ip6h))) + goto fail; + goto done; + case IPPROTO_TCP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_TCP) + if (!tcf_csum_ipv6_tcp(skb, ip6h, + hl, pl + sizeof(*ip6h))) + goto fail; + goto done; + case IPPROTO_UDP: + if (update_flags & TCA_CSUM_UPDATE_FLAG_UDP) + if (!tcf_csum_ipv6_udp(skb, ip6h, hl, + pl + sizeof(*ip6h), 0)) + goto fail; + goto done; + case IPPROTO_UDPLITE: + if (update_flags & TCA_CSUM_UPDATE_FLAG_UDPLITE) + if (!tcf_csum_ipv6_udp(skb, ip6h, hl, + pl + sizeof(*ip6h), 1)) + goto fail; + goto done; + default: + goto ignore_skb; + } + } while (pskb_may_pull(skb, hl + 1 + ntkoff)); + +done: +ignore_skb: + return 1; + +fail: + return 0; +} + +static int tcf_csum(struct sk_buff *skb, + struct tc_action *a, struct tcf_result *res) +{ + struct tcf_csum *p = a->priv; + int action; + u32 update_flags; + + spin_lock(&p->tcf_lock); + p->tcf_tm.lastuse = jiffies; + p->tcf_bstats.bytes += qdisc_pkt_len(skb); + p->tcf_bstats.packets++; + action = p->tcf_action; + update_flags = p->update_flags; + spin_unlock(&p->tcf_lock); + + if (unlikely(action == TC_ACT_SHOT)) + goto drop; + + switch (skb->protocol) { + case cpu_to_be16(ETH_P_IP): + if (!tcf_csum_ipv4(skb, update_flags)) + goto drop; + break; + case cpu_to_be16(ETH_P_IPV6): + if (!tcf_csum_ipv6(skb, update_flags)) + goto drop; + break; + } + + return action; + +drop: + spin_lock(&p->tcf_lock); + p->tcf_qstats.drops++; + spin_unlock(&p->tcf_lock); + return TC_ACT_SHOT; +} + +static int tcf_csum_dump(struct sk_buff *skb, + struct tc_action *a, int bind, int ref) +{ + unsigned char *b = skb_tail_pointer(skb); + struct tcf_csum *p = a->priv; + struct tc_csum opt = { + .update_flags = p->update_flags, + .index = p->tcf_index, + .action = p->tcf_action, + .refcnt = p->tcf_refcnt - ref, + .bindcnt = p->tcf_bindcnt - bind, + }; + struct tcf_t t; + + NLA_PUT(skb, TCA_CSUM_PARMS, sizeof(opt), &opt); + t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse); + t.expires = jiffies_to_clock_t(p->tcf_tm.expires); + NLA_PUT(skb, TCA_CSUM_TM, sizeof(t), &t); + + return skb->len; + +nla_put_failure: + nlmsg_trim(skb, b); + return -1; +} + +static struct tc_action_ops act_csum_ops = { + .kind = "csum", + .hinfo = &csum_hash_info, + .type = TCA_ACT_CSUM, + .capab = TCA_CAP_NONE, + .owner = THIS_MODULE, + .act = tcf_csum, + .dump = tcf_csum_dump, + .cleanup = tcf_csum_cleanup, + .lookup = tcf_hash_search, + .init = tcf_csum_init, + .walk = tcf_generic_walker +}; + +MODULE_DESCRIPTION("Checksum updating actions"); +MODULE_LICENSE("GPL"); + +static int __init csum_init_module(void) +{ + return tcf_register_action(&act_csum_ops); +} + +static void __exit csum_cleanup_module(void) +{ + tcf_unregister_action(&act_csum_ops); +} + +module_init(csum_init_module); +module_exit(csum_cleanup_module); diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index c7e59e6ec34938a3762fead555fc6748ab5d0e09..8daef9632255349f135867672941caa8181c6b54 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -39,7 +39,7 @@ static struct tcf_hashinfo ipt_hash_info = { .lock = &ipt_lock, }; -static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) +static int ipt_init_target(struct xt_entry_target *t, char *table, unsigned int hook) { struct xt_tgchk_param par; struct xt_target *target; @@ -66,7 +66,7 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int return 0; } -static void ipt_destroy_target(struct ipt_entry_target *t) +static void ipt_destroy_target(struct xt_entry_target *t) { struct xt_tgdtor_param par = { .target = t->u.kernel.target, @@ -99,7 +99,7 @@ static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = { [TCA_IPT_TABLE] = { .type = NLA_STRING, .len = IFNAMSIZ }, [TCA_IPT_HOOK] = { .type = NLA_U32 }, [TCA_IPT_INDEX] = { .type = NLA_U32 }, - [TCA_IPT_TARG] = { .len = sizeof(struct ipt_entry_target) }, + [TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) }, }; static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, @@ -108,7 +108,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, struct nlattr *tb[TCA_IPT_MAX + 1]; struct tcf_ipt *ipt; struct tcf_common *pc; - struct ipt_entry_target *td, *t; + struct xt_entry_target *td, *t; char *tname; int ret = 0, err; u32 hook = 0; @@ -126,7 +126,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est, if (tb[TCA_IPT_TARG] == NULL) return -EINVAL; - td = (struct ipt_entry_target *)nla_data(tb[TCA_IPT_TARG]); + td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]); if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) return -EINVAL; @@ -230,7 +230,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a, result = TC_ACT_SHOT; ipt->tcf_qstats.drops++; break; - case IPT_CONTINUE: + case XT_CONTINUE: result = TC_ACT_PIPE; break; default: @@ -249,7 +249,7 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int { unsigned char *b = skb_tail_pointer(skb); struct tcf_ipt *ipt = a->priv; - struct ipt_entry_target *t; + struct xt_entry_target *t; struct tcf_t tm; struct tc_cnt c; diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index e17096e3913ccb983cf8abd533da20d30cf37b62..5b271a18bc3a54199510d8d7c6b8f2844afefcf9 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -111,44 +111,41 @@ static u32 flow_get_proto(struct sk_buff *skb) } } -static int has_ports(u8 protocol) -{ - switch (protocol) { - case IPPROTO_TCP: - case IPPROTO_UDP: - case IPPROTO_UDPLITE: - case IPPROTO_SCTP: - case IPPROTO_DCCP: - case IPPROTO_ESP: - return 1; - default: - return 0; - } -} - static u32 flow_get_proto_src(struct sk_buff *skb) { switch (skb->protocol) { case htons(ETH_P_IP): { struct iphdr *iph; + int poff; if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ip_hdr(skb); - if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && - has_ports(iph->protocol) && - pskb_network_may_pull(skb, iph->ihl * 4 + 2)) - return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); + if (iph->frag_off & htons(IP_MF|IP_OFFSET)) + break; + poff = proto_ports_offset(iph->protocol); + if (poff >= 0 && + pskb_network_may_pull(skb, iph->ihl * 4 + 2 + poff)) { + iph = ip_hdr(skb); + return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + + poff)); + } break; } case htons(ETH_P_IPV6): { struct ipv6hdr *iph; + int poff; - if (!pskb_network_may_pull(skb, sizeof(*iph) + 2)) + if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ipv6_hdr(skb); - if (has_ports(iph->nexthdr)) - return ntohs(*(__be16 *)&iph[1]); + poff = proto_ports_offset(iph->nexthdr); + if (poff >= 0 && + pskb_network_may_pull(skb, sizeof(*iph) + poff + 2)) { + iph = ipv6_hdr(skb); + return ntohs(*(__be16 *)((void *)iph + sizeof(*iph) + + poff)); + } break; } } @@ -161,24 +158,36 @@ static u32 flow_get_proto_dst(struct sk_buff *skb) switch (skb->protocol) { case htons(ETH_P_IP): { struct iphdr *iph; + int poff; if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ip_hdr(skb); - if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && - has_ports(iph->protocol) && - pskb_network_may_pull(skb, iph->ihl * 4 + 4)) - return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); + if (iph->frag_off & htons(IP_MF|IP_OFFSET)) + break; + poff = proto_ports_offset(iph->protocol); + if (poff >= 0 && + pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) { + iph = ip_hdr(skb); + return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + + 2 + poff)); + } break; } case htons(ETH_P_IPV6): { struct ipv6hdr *iph; + int poff; - if (!pskb_network_may_pull(skb, sizeof(*iph) + 4)) + if (!pskb_network_may_pull(skb, sizeof(*iph))) break; iph = ipv6_hdr(skb); - if (has_ports(iph->nexthdr)) - return ntohs(*(__be16 *)((void *)&iph[1] + 2)); + poff = proto_ports_offset(iph->nexthdr); + if (poff >= 0 && + pskb_network_may_pull(skb, sizeof(*iph) + poff + 4)) { + iph = ipv6_hdr(skb); + return ntohs(*(__be16 *)((void *)iph + sizeof(*iph) + + poff + 2)); + } break; } } @@ -297,6 +306,11 @@ static u32 flow_get_vlan_tag(const struct sk_buff *skb) return tag & VLAN_VID_MASK; } +static u32 flow_get_rxhash(struct sk_buff *skb) +{ + return skb_get_rxhash(skb); +} + static u32 flow_key_get(struct sk_buff *skb, int key) { switch (key) { @@ -334,6 +348,8 @@ static u32 flow_key_get(struct sk_buff *skb, int key) return flow_get_skgid(skb); case FLOW_KEY_VLAN_TAG: return flow_get_vlan_tag(skb); + case FLOW_KEY_RXHASH: + return flow_get_rxhash(skb); default: WARN_ON(1); return 0; diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 3bcac8aa333c2a322fb7283ce0803480e893d5d4..34da5e29ea1a8026388805cfba52e782ba01c9ec 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -223,6 +223,11 @@ META_COLLECTOR(int_maclen) dst->value = skb->mac_len; } +META_COLLECTOR(int_rxhash) +{ + dst->value = skb_get_rxhash(skb); +} + /************************************************************************** * Netfilter **************************************************************************/ @@ -541,6 +546,7 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off), [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend), [META_ID(VLAN_TAG)] = META_FUNC(int_vlan_tag), + [META_ID(RXHASH)] = META_FUNC(int_rxhash), } }; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 408eea7086aace341d1ed9812d956db35cfdfb86..b22ca2d1cebca4e2495f1fd15502e7f39fe82342 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -240,7 +240,10 @@ struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) if (q) goto out; - q = qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle); + if (dev_ingress_queue(dev)) + q = qdisc_match_from_root( + dev_ingress_queue(dev)->qdisc_sleeping, + handle); out: return q; } @@ -360,7 +363,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt) tsize = nla_len(tb[TCA_STAB_DATA]) / sizeof(u16); } - if (!s || tsize != s->tsize || (!tab && tsize > 0)) + if (tsize != s->tsize || (!tab && tsize > 0)) return ERR_PTR(-EINVAL); spin_lock(&qdisc_stab_lock); @@ -690,6 +693,8 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, (new && new->flags & TCQ_F_INGRESS)) { num_q = 1; ingress = 1; + if (!dev_ingress_queue(dev)) + return -ENOENT; } if (dev->flags & IFF_UP) @@ -701,7 +706,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, } for (i = 0; i < num_q; i++) { - struct netdev_queue *dev_queue = &dev->rx_queue; + struct netdev_queue *dev_queue = dev_ingress_queue(dev); if (!ingress) dev_queue = netdev_get_tx_queue(dev, i); @@ -979,7 +984,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) return -ENOENT; q = qdisc_leaf(p, clid); } else { /* ingress */ - q = dev->rx_queue.qdisc_sleeping; + if (dev_ingress_queue(dev)) + q = dev_ingress_queue(dev)->qdisc_sleeping; } } else { q = dev->qdisc; @@ -1043,8 +1049,9 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL) return -ENOENT; q = qdisc_leaf(p, clid); - } else { /*ingress */ - q = dev->rx_queue.qdisc_sleeping; + } else { /* ingress */ + if (dev_ingress_queue_create(dev)) + q = dev_ingress_queue(dev)->qdisc_sleeping; } } else { q = dev->qdisc; @@ -1123,11 +1130,14 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) create_n_graft: if (!(n->nlmsg_flags&NLM_F_CREATE)) return -ENOENT; - if (clid == TC_H_INGRESS) - q = qdisc_create(dev, &dev->rx_queue, p, - tcm->tcm_parent, tcm->tcm_parent, - tca, &err); - else { + if (clid == TC_H_INGRESS) { + if (dev_ingress_queue(dev)) + q = qdisc_create(dev, dev_ingress_queue(dev), p, + tcm->tcm_parent, tcm->tcm_parent, + tca, &err); + else + err = -ENOENT; + } else { struct netdev_queue *dev_queue; if (p && p->ops->cl_ops && p->ops->cl_ops->select_queue) @@ -1304,8 +1314,10 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) if (tc_dump_qdisc_root(dev->qdisc, skb, cb, &q_idx, s_q_idx) < 0) goto done; - dev_queue = &dev->rx_queue; - if (tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, &q_idx, s_q_idx) < 0) + dev_queue = dev_ingress_queue(dev); + if (dev_queue && + tc_dump_qdisc_root(dev_queue->qdisc_sleeping, skb, cb, + &q_idx, s_q_idx) < 0) goto done; cont: @@ -1595,8 +1607,10 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) if (tc_dump_tclass_root(dev->qdisc, skb, tcm, cb, &t, s_t) < 0) goto done; - dev_queue = &dev->rx_queue; - if (tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, &t, s_t) < 0) + dev_queue = dev_ingress_queue(dev); + if (dev_queue && + tc_dump_tclass_root(dev_queue->qdisc_sleeping, skb, tcm, cb, + &t, s_t) < 0) goto done; done: diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c index 6318e1136b83de86f1b73150a0a5199522293f4f..282540778aa8d5907aab2976071a081f18daa29a 100644 --- a/net/sched/sch_atm.c +++ b/net/sched/sch_atm.c @@ -275,8 +275,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, goto err_out; } flow->filter_list = NULL; - flow->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, classid); + flow->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); if (!flow->q) flow->q = &noop_qdisc; pr_debug("atm_tc_change: qdisc %p\n", flow->q); @@ -543,7 +542,7 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt) INIT_LIST_HEAD(&p->flows); INIT_LIST_HEAD(&p->link.list); list_add(&p->link.list, &p->flows); - p->link.q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + p->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); if (!p->link.q) p->link.q = &noop_qdisc; diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 28c01ef5abc815ae5429e29c34bba8b97b7d50f6..eb763159086501aa2887c2c80680e37fbf0aa4fc 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1379,9 +1379,9 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt) q->link.sibling = &q->link; q->link.common.classid = sch->handle; q->link.qdisc = sch; - if (!(q->link.q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, - sch->handle))) + q->link.q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, + sch->handle); + if (!q->link.q) q->link.q = &noop_qdisc; q->link.priority = TC_CBQ_MAXPRIO-1; @@ -1623,7 +1623,7 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, struct cbq_class *cl = (struct cbq_class*)arg; if (new == NULL) { - new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->common.classid); if (new == NULL) return -ENOBUFS; @@ -1874,8 +1874,8 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct nlattr **t cl->R_tab = rtab; rtab = NULL; cl->refcnt = 1; - if (!(cl->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, classid))) + cl->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); + if (!cl->q) cl->q = &noop_qdisc; cl->common.classid = classid; cl->tparent = parent; diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index b74046a95397c6d2e3d9a90e648c3414dd18c50f..aa8b5313f8cf4d1a4a11e7077f9445fed11dd424 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -110,7 +110,7 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, cl->refcnt = 1; cl->common.classid = classid; cl->quantum = quantum; - cl->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); if (cl->qdisc == NULL) cl->qdisc = &noop_qdisc; @@ -218,7 +218,7 @@ static int drr_graft_class(struct Qdisc *sch, unsigned long arg, struct drr_class *cl = (struct drr_class *)arg; if (new == NULL) { - new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->common.classid); if (new == NULL) new = &noop_qdisc; diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 63d41f86679c0653951090c81f189665c5deaa00..1d295d62bb5ca4cfdf8a3a9c4dc24b36731232ed 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -61,8 +61,7 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg, sch, p, new, old); if (new == NULL) { - new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); if (new == NULL) new = &noop_qdisc; @@ -384,8 +383,7 @@ static int dsmark_init(struct Qdisc *sch, struct nlattr *opt) p->default_index = default_index; p->set_tc_index = nla_get_flag(tb[TCA_DSMARK_SET_TC_INDEX]); - p->q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, sch->handle); + p->q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); if (p->q == NULL) p->q = &noop_qdisc; diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index 5948bafa8ce29de97bf4a824139ee2f033579810..4dfecb0cba371c1e07eb6061ab009cb87239cfee 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c @@ -172,8 +172,7 @@ struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops, struct Qdisc *q; int err = -ENOMEM; - q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - ops, TC_H_MAKE(sch->handle, 1)); + q = qdisc_create_dflt(sch->dev_queue, ops, TC_H_MAKE(sch->handle, 1)); if (q) { err = fifo_set_limit(q, limit); if (err < 0) { diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 2aeb3a4386a10f499f020c961bada4803653985b..5dbb3cd96e590f7188a78814e2ee4ddfc492db89 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -383,6 +383,7 @@ struct Qdisc noop_qdisc = { .list = LIST_HEAD_INIT(noop_qdisc.list), .q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock), .dev_queue = &noop_netdev_queue, + .busylock = __SPIN_LOCK_UNLOCKED(noop_qdisc.busylock), }; EXPORT_SYMBOL(noop_qdisc); @@ -409,6 +410,7 @@ static struct Qdisc noqueue_qdisc = { .list = LIST_HEAD_INIT(noqueue_qdisc.list), .q.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock), .dev_queue = &noqueue_netdev_queue, + .busylock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.busylock), }; @@ -574,10 +576,8 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, return ERR_PTR(err); } -struct Qdisc * qdisc_create_dflt(struct net_device *dev, - struct netdev_queue *dev_queue, - struct Qdisc_ops *ops, - unsigned int parentid) +struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, + struct Qdisc_ops *ops, unsigned int parentid) { struct Qdisc *sch; @@ -682,7 +682,7 @@ static void attach_one_default_qdisc(struct net_device *dev, struct Qdisc *qdisc; if (dev->tx_queue_len) { - qdisc = qdisc_create_dflt(dev, dev_queue, + qdisc = qdisc_create_dflt(dev_queue, &pfifo_fast_ops, TC_H_ROOT); if (!qdisc) { printk(KERN_INFO "%s: activation failed\n", dev->name); @@ -709,7 +709,7 @@ static void attach_default_qdiscs(struct net_device *dev) dev->qdisc = txq->qdisc_sleeping; atomic_inc(&dev->qdisc->refcnt); } else { - qdisc = qdisc_create_dflt(dev, txq, &mq_qdisc_ops, TC_H_ROOT); + qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT); if (qdisc) { qdisc->ops->attach(qdisc); dev->qdisc = qdisc; @@ -753,7 +753,8 @@ void dev_activate(struct net_device *dev) need_watchdog = 0; netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog); - transition_one_qdisc(dev, &dev->rx_queue, NULL); + if (dev_ingress_queue(dev)) + transition_one_qdisc(dev, dev_ingress_queue(dev), NULL); if (need_watchdog) { dev->trans_start = jiffies; @@ -812,7 +813,8 @@ static bool some_qdisc_is_busy(struct net_device *dev) void dev_deactivate(struct net_device *dev) { netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); - dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc); + if (dev_ingress_queue(dev)) + dev_deactivate_queue(dev, dev_ingress_queue(dev), &noop_qdisc); dev_watchdog_down(dev); @@ -838,7 +840,8 @@ void dev_init_scheduler(struct net_device *dev) { dev->qdisc = &noop_qdisc; netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc); - dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); + if (dev_ingress_queue(dev)) + dev_init_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc); setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev); } @@ -861,7 +864,8 @@ static void shutdown_scheduler_queue(struct net_device *dev, void dev_shutdown(struct net_device *dev) { netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc); - shutdown_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); + if (dev_ingress_queue(dev)) + shutdown_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc); qdisc_destroy(dev->qdisc); dev->qdisc = &noop_qdisc; diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index 47496098d35c2876cd0b5a88e1365922cc369ce9..069c62b7bb3691ac8b4008202c4d3d9aee006d0a 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1088,7 +1088,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, cl->refcnt = 1; cl->sched = q; cl->cl_parent = parent; - cl->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + cl->qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); if (cl->qdisc == NULL) cl->qdisc = &noop_qdisc; @@ -1209,8 +1209,7 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, if (cl->level > 0) return -EINVAL; if (new == NULL) { - new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->cl_common.classid); if (new == NULL) new = &noop_qdisc; @@ -1452,8 +1451,7 @@ hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) q->root.cl_common.classid = sch->handle; q->root.refcnt = 1; q->root.sched = q; - q->root.qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + q->root.qdisc = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, sch->handle); if (q->root.qdisc == NULL) q->root.qdisc = &noop_qdisc; diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 4be8d04b262d18963ac6617abaaeefc5151e16f5..01b519d6c52d3e2bf5f5baf5852594793ba6e7f5 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1121,8 +1121,7 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new, if (cl->level) return -EINVAL; if (new == NULL && - (new = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + (new = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->common.classid)) == NULL) return -ENOBUFS; @@ -1247,8 +1246,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) return -EBUSY; if (!cl->level && htb_parent_last_child(cl)) { - new_q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &pfifo_qdisc_ops, + new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, cl->parent->common.classid); last_child = 1; } @@ -1302,14 +1300,14 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, struct htb_class *cl = (struct htb_class *)*arg, *parent; struct nlattr *opt = tca[TCA_OPTIONS]; struct qdisc_rate_table *rtab = NULL, *ctab = NULL; - struct nlattr *tb[TCA_HTB_RTAB + 1]; + struct nlattr *tb[__TCA_HTB_MAX]; struct tc_htb_opt *hopt; /* extract all subattrs from opt attr */ if (!opt) goto failure; - err = nla_parse_nested(tb, TCA_HTB_RTAB, opt, htb_policy); + err = nla_parse_nested(tb, TCA_HTB_MAX, opt, htb_policy); if (err < 0) goto failure; @@ -1377,7 +1375,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL) so that can't be used inside of sch_tree_lock -- thanks to Karlis Peisenieks */ - new_q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + new_q = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, classid); sch_tree_lock(sch); if (parent && !parent->level) { diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index fe91e50f9d98e7f2819242fc5a3b68ff905219a2..ecc302f4d2a1ce35dde04a15fd810617a76807ee 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -56,7 +56,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt) for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { dev_queue = netdev_get_tx_queue(dev, ntx); - qdisc = qdisc_create_dflt(dev, dev_queue, &pfifo_fast_ops, + qdisc = qdisc_create_dflt(dev_queue, &pfifo_fast_ops, TC_H_MAKE(TC_H_MAJ(sch->handle), TC_H_MIN(ntx + 1))); if (qdisc == NULL) diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 6ae251279fc2f53c86aa339d39bff13b71c79991..32690deab5d07cfed26eb7d1fda6656d7d1b8fe0 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -227,8 +227,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt) for (i = 0; i < q->bands; i++) { if (q->queues[i] == &noop_qdisc) { struct Qdisc *child, *old; - child = qdisc_create_dflt(qdisc_dev(sch), - sch->dev_queue, + child = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, TC_H_MAKE(sch->handle, i + 1)); diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 4714ff162bbd2cdf42eb77c7b629e0331391bfeb..e5593c083a7883f99e548e182e90d8a2ae84bb65 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -538,8 +538,7 @@ static int netem_init(struct Qdisc *sch, struct nlattr *opt) qdisc_watchdog_init(&q->watchdog, sch); - q->qdisc = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, - &tfifo_qdisc_ops, + q->qdisc = qdisc_create_dflt(sch->dev_queue, &tfifo_qdisc_ops, TC_H_MAKE(sch->handle, 1)); if (!q->qdisc) { pr_debug("netem: qdisc create failed\n"); diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 0748fb1e3a49b397e87d5f1c13169f4b3eb5a980..b1c95bce33ce6f2f8a360e93ab234f8db1ab42c9 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c @@ -200,7 +200,7 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt) for (i=0; ibands; i++) { if (q->queues[i] == &noop_qdisc) { struct Qdisc *child, *old; - child = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, + child = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, TC_H_MAKE(sch->handle, i + 1)); if (child) { diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 201cbac2b32ce0ccd8375b066005b6ba69759ddd..3cf478d012dd4f29b7a67f951c2cfa901b64248f 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -123,40 +123,39 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb) case htons(ETH_P_IP): { const struct iphdr *iph; + int poff; if (!pskb_network_may_pull(skb, sizeof(*iph))) goto err; iph = ip_hdr(skb); h = (__force u32)iph->daddr; h2 = (__force u32)iph->saddr ^ iph->protocol; - if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && - (iph->protocol == IPPROTO_TCP || - iph->protocol == IPPROTO_UDP || - iph->protocol == IPPROTO_UDPLITE || - iph->protocol == IPPROTO_SCTP || - iph->protocol == IPPROTO_DCCP || - iph->protocol == IPPROTO_ESP) && - pskb_network_may_pull(skb, iph->ihl * 4 + 4)) - h2 ^= *(((u32*)iph) + iph->ihl); + if (iph->frag_off & htons(IP_MF|IP_OFFSET)) + break; + poff = proto_ports_offset(iph->protocol); + if (poff >= 0 && + pskb_network_may_pull(skb, iph->ihl * 4 + 4 + poff)) { + iph = ip_hdr(skb); + h2 ^= *(u32*)((void *)iph + iph->ihl * 4 + poff); + } break; } case htons(ETH_P_IPV6): { struct ipv6hdr *iph; + int poff; if (!pskb_network_may_pull(skb, sizeof(*iph))) goto err; iph = ipv6_hdr(skb); h = (__force u32)iph->daddr.s6_addr32[3]; h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr; - if ((iph->nexthdr == IPPROTO_TCP || - iph->nexthdr == IPPROTO_UDP || - iph->nexthdr == IPPROTO_UDPLITE || - iph->nexthdr == IPPROTO_SCTP || - iph->nexthdr == IPPROTO_DCCP || - iph->nexthdr == IPPROTO_ESP) && - pskb_network_may_pull(skb, sizeof(*iph) + 4)) - h2 ^= *(u32*)&iph[1]; + poff = proto_ports_offset(iph->nexthdr); + if (poff >= 0 && + pskb_network_may_pull(skb, sizeof(*iph) + 4 + poff)) { + iph = ipv6_hdr(skb); + h2 ^= *(u32*)((void *)iph + sizeof(*iph) + poff); + } break; } default: diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index feaabc103ce6a061e350ddb07e1a2faf5d1ee4bd..401af95967092c218b499b064df39c4b1d272216 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -241,11 +241,11 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device * } if (neigh_event_send(n, skb_res) == 0) { int err; + char haddr[MAX_ADDR_LEN]; - read_lock(&n->lock); - err = dev_hard_header(skb, dev, ntohs(skb->protocol), - n->ha, NULL, skb->len); - read_unlock(&n->lock); + neigh_ha_snapshot(haddr, n, dev); + err = dev_hard_header(skb, dev, ntohs(skb->protocol), haddr, + NULL, skb->len); if (err < 0) { neigh_release(n); diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 0b85e5256434858783e4cbb586faab2841ecbdd4..5f1fb8bd862dea391a2930f34d59d2129743ebaf 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -48,6 +48,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 476caaf100ed740e0b72138721f1baf6ff90f584..6c8556459a751b3e2faa6b0442b804396ff6de7e 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -37,6 +37,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c index ccb6dc48d15b6ecf123887cd23d00ffec1ec3c4a..397296fb156fd094169db1cacb0f940d936c6bc6 100644 --- a/net/sctp/inqueue.c +++ b/net/sctp/inqueue.c @@ -43,6 +43,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 732689140fb864d40f0cd109e92288bb74373a4c..95e0c8eda1a0b2c16463297ee7a0d5f45d3e884d 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -47,6 +47,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -336,7 +338,7 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk, memcpy(saddr, baddr, sizeof(union sctp_addr)); SCTP_DEBUG_PRINTK("saddr: %pI6\n", &saddr->v6.sin6_addr); } else { - printk(KERN_ERR "%s: asoc:%p Could not find a valid source " + pr_err("%s: asoc:%p Could not find a valid source " "address for the dest:%pI6\n", __func__, asoc, &daddr->v6.sin6_addr); } diff --git a/net/sctp/objcnt.c b/net/sctp/objcnt.c index f73ec0ea93ba374f6b15810abe6789828dafa0d4..8ef8e7d9eb61bbf74b6c023f4e33ee360085f84c 100644 --- a/net/sctp/objcnt.c +++ b/net/sctp/objcnt.c @@ -38,6 +38,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include @@ -134,8 +136,7 @@ void sctp_dbg_objcnt_init(void) ent = proc_create("sctp_dbg_objcnt", 0, proc_net_sctp, &sctp_objcnt_ops); if (!ent) - printk(KERN_WARNING - "sctp_dbg_objcnt: Unable to create /proc entry.\n"); + pr_warn("sctp_dbg_objcnt: Unable to create /proc entry.\n"); } /* Cleanup the objcount entry in the proc filesystem. */ diff --git a/net/sctp/output.c b/net/sctp/output.c index bcc4590ccaf21bb988a7827614f71a39ffa31318..60600d337a3a9c6d4a589918dee8f18edf5f6961 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -41,6 +41,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index c04b2eb591868627280269fd5379d2307f9802f7..8c6d379b4bb682634c27c3fef9f4bfc17786e507 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c @@ -46,6 +46,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include /* For struct list_head */ #include @@ -1463,23 +1465,23 @@ static void sctp_check_transmitted(struct sctp_outq *q, /* Display the end of the * current range. */ - SCTP_DEBUG_PRINTK("-%08x", - dbg_last_ack_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x", + dbg_last_ack_tsn); } /* Start a new range. */ - SCTP_DEBUG_PRINTK(",%08x", tsn); + SCTP_DEBUG_PRINTK_CONT(",%08x", tsn); dbg_ack_tsn = tsn; break; case 1: /* The last TSN was NOT ACKed. */ if (dbg_last_kept_tsn != dbg_kept_tsn) { /* Display the end of current range. */ - SCTP_DEBUG_PRINTK("-%08x", - dbg_last_kept_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x", + dbg_last_kept_tsn); } - SCTP_DEBUG_PRINTK("\n"); + SCTP_DEBUG_PRINTK_CONT("\n"); /* FALL THROUGH... */ default: @@ -1526,18 +1528,18 @@ static void sctp_check_transmitted(struct sctp_outq *q, break; if (dbg_last_kept_tsn != dbg_kept_tsn) - SCTP_DEBUG_PRINTK("-%08x", - dbg_last_kept_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x", + dbg_last_kept_tsn); - SCTP_DEBUG_PRINTK(",%08x", tsn); + SCTP_DEBUG_PRINTK_CONT(",%08x", tsn); dbg_kept_tsn = tsn; break; case 0: if (dbg_last_ack_tsn != dbg_ack_tsn) - SCTP_DEBUG_PRINTK("-%08x", - dbg_last_ack_tsn); - SCTP_DEBUG_PRINTK("\n"); + SCTP_DEBUG_PRINTK_CONT("-%08x", + dbg_last_ack_tsn); + SCTP_DEBUG_PRINTK_CONT("\n"); /* FALL THROUGH... */ default: @@ -1556,17 +1558,17 @@ static void sctp_check_transmitted(struct sctp_outq *q, switch (dbg_prt_state) { case 0: if (dbg_last_ack_tsn != dbg_ack_tsn) { - SCTP_DEBUG_PRINTK("-%08x\n", dbg_last_ack_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x\n", dbg_last_ack_tsn); } else { - SCTP_DEBUG_PRINTK("\n"); + SCTP_DEBUG_PRINTK_CONT("\n"); } break; case 1: if (dbg_last_kept_tsn != dbg_kept_tsn) { - SCTP_DEBUG_PRINTK("-%08x\n", dbg_last_kept_tsn); + SCTP_DEBUG_PRINTK_CONT("-%08x\n", dbg_last_kept_tsn); } else { - SCTP_DEBUG_PRINTK("\n"); + SCTP_DEBUG_PRINTK_CONT("\n"); } } #endif /* SCTP_DEBUG */ diff --git a/net/sctp/probe.c b/net/sctp/probe.c index 289b1ba62cac6623886f8bf47c50b74cc86cd66e..bc6cd75cc1dcdc82792b7056ce2b1566bbb945d5 100644 --- a/net/sctp/probe.c +++ b/net/sctp/probe.c @@ -22,6 +22,8 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -193,7 +195,7 @@ static __init int sctpprobe_init(void) if (ret) goto remove_proc; - pr_info("SCTP probe registered (port=%d)\n", port); + pr_info("probe registered (port=%d)\n", port); return 0; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5027b83f1cc0c840f6015bb9418356ae61c17242..1ef29c74d85ead34a6c0dd5cb03954e91677ae00 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -46,6 +46,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -707,8 +709,7 @@ static int sctp_ctl_sock_init(void) &init_net); if (err < 0) { - printk(KERN_ERR - "SCTP: Failed to create the SCTP control socket.\n"); + pr_err("Failed to create the SCTP control socket\n"); return err; } return 0; @@ -798,7 +799,7 @@ static void sctp_inet_skb_msgname(struct sk_buff *skb, char *msgname, int *len) static int sctp_inet_af_supported(sa_family_t family, struct sctp_sock *sp) { /* PF_INET only supports AF_INET addresses. */ - return (AF_INET == family); + return AF_INET == family; } /* Address matching with wildcards allowed. */ @@ -1206,7 +1207,7 @@ SCTP_STATIC __init int sctp_init(void) __get_free_pages(GFP_ATOMIC, order); } while (!sctp_assoc_hashtable && --order > 0); if (!sctp_assoc_hashtable) { - printk(KERN_ERR "SCTP: Failed association hash alloc.\n"); + pr_err("Failed association hash alloc\n"); status = -ENOMEM; goto err_ahash_alloc; } @@ -1220,7 +1221,7 @@ SCTP_STATIC __init int sctp_init(void) sctp_ep_hashtable = (struct sctp_hashbucket *) kmalloc(64 * sizeof(struct sctp_hashbucket), GFP_KERNEL); if (!sctp_ep_hashtable) { - printk(KERN_ERR "SCTP: Failed endpoint_hash alloc.\n"); + pr_err("Failed endpoint_hash alloc\n"); status = -ENOMEM; goto err_ehash_alloc; } @@ -1239,7 +1240,7 @@ SCTP_STATIC __init int sctp_init(void) __get_free_pages(GFP_ATOMIC, order); } while (!sctp_port_hashtable && --order > 0); if (!sctp_port_hashtable) { - printk(KERN_ERR "SCTP: Failed bind hash alloc."); + pr_err("Failed bind hash alloc\n"); status = -ENOMEM; goto err_bhash_alloc; } @@ -1248,8 +1249,7 @@ SCTP_STATIC __init int sctp_init(void) INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain); } - printk(KERN_INFO "SCTP: Hash tables configured " - "(established %d bind %d)\n", + pr_info("Hash tables configured (established %d bind %d)\n", sctp_assoc_hashsize, sctp_port_hashsize); /* Disable ADDIP by default. */ @@ -1290,8 +1290,7 @@ SCTP_STATIC __init int sctp_init(void) /* Initialize the control inode/socket for handling OOTB packets. */ if ((status = sctp_ctl_sock_init())) { - printk (KERN_ERR - "SCTP: Failed to initialize the SCTP control sock.\n"); + pr_err("Failed to initialize the SCTP control sock\n"); goto err_ctl_sock_init; } diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 246f92924658b7d5dca18ae4d4a212d590b3e4d8..2cc46f0962ca37b63e398c633f794c5986977095 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -50,6 +50,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index f5e5e27cac5ee5918f815fecf1cebbbc6be3203e..b21b218d564f20f9f9b04e39412a0499377d8d62 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -47,6 +47,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1146,26 +1148,23 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, case SCTP_DISPOSITION_VIOLATION: if (net_ratelimit()) - printk(KERN_ERR "sctp protocol violation state %d " - "chunkid %d\n", state, subtype.chunk); + pr_err("protocol violation state %d chunkid %d\n", + state, subtype.chunk); break; case SCTP_DISPOSITION_NOT_IMPL: - printk(KERN_WARNING "sctp unimplemented feature in state %d, " - "event_type %d, event_id %d\n", - state, event_type, subtype.chunk); + pr_warn("unimplemented feature in state %d, event_type %d, event_id %d\n", + state, event_type, subtype.chunk); break; case SCTP_DISPOSITION_BUG: - printk(KERN_ERR "sctp bug in state %d, " - "event_type %d, event_id %d\n", + pr_err("bug in state %d, event_type %d, event_id %d\n", state, event_type, subtype.chunk); BUG(); break; default: - printk(KERN_ERR "sctp impossible disposition %d " - "in state %d, event_type %d, event_id %d\n", + pr_err("impossible disposition %d in state %d, event_type %d, event_id %d\n", status, state, event_type, subtype.chunk); BUG(); break; @@ -1679,8 +1678,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, sctp_cmd_send_asconf(asoc); break; default: - printk(KERN_WARNING "Impossible command: %u, %p\n", - cmd->verb, cmd->obj.ptr); + pr_warn("Impossible command: %u, %p\n", + cmd->verb, cmd->obj.ptr); break; } diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index d344dc481ccc7a22d517c13995e825a73bed21ce..4b4eb7c96bbdb32027834f38ec4ad2f307e84616 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -50,6 +50,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -1138,18 +1140,16 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, if (unlikely(!link)) { if (from_addr.sa.sa_family == AF_INET6) { if (net_ratelimit()) - printk(KERN_WARNING - "%s association %p could not find address %pI6\n", - __func__, - asoc, - &from_addr.v6.sin6_addr); + pr_warn("%s association %p could not find address %pI6\n", + __func__, + asoc, + &from_addr.v6.sin6_addr); } else { if (net_ratelimit()) - printk(KERN_WARNING - "%s association %p could not find address %pI4\n", - __func__, - asoc, - &from_addr.v4.sin_addr.s_addr); + pr_warn("%s association %p could not find address %pI4\n", + __func__, + asoc, + &from_addr.v4.sin_addr.s_addr); } return SCTP_DISPOSITION_DISCARD; } diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 6d9b3aafcc5dbd4327a0d5a89e4fa03d4b710e5c..546d4387fb3caee906ad543c0528674b0f4f876b 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c @@ -46,6 +46,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -66,15 +68,19 @@ static const sctp_sm_table_entry_t bug = { .name = "sctp_sf_bug" }; -#define DO_LOOKUP(_max, _type, _table) \ - if ((event_subtype._type > (_max))) { \ - printk(KERN_WARNING \ - "sctp table %p possible attack:" \ - " event %d exceeds max %d\n", \ - _table, event_subtype._type, _max); \ - return &bug; \ - } \ - return &_table[event_subtype._type][(int)state]; +#define DO_LOOKUP(_max, _type, _table) \ +({ \ + const sctp_sm_table_entry_t *rtn; \ + \ + if ((event_subtype._type > (_max))) { \ + pr_warn("table %p possible attack: event %d exceeds max %d\n", \ + _table, event_subtype._type, _max); \ + rtn = &bug; \ + } else \ + rtn = &_table[event_subtype._type][(int)state]; \ + \ + rtn; \ +}) const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, sctp_state_t state, @@ -83,21 +89,15 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type, switch (event_type) { case SCTP_EVENT_T_CHUNK: return sctp_chunk_event_lookup(event_subtype.chunk, state); - break; case SCTP_EVENT_T_TIMEOUT: - DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout, - timeout_event_table); - break; - + return DO_LOOKUP(SCTP_EVENT_TIMEOUT_MAX, timeout, + timeout_event_table); case SCTP_EVENT_T_OTHER: - DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other, other_event_table); - break; - + return DO_LOOKUP(SCTP_EVENT_OTHER_MAX, other, + other_event_table); case SCTP_EVENT_T_PRIMITIVE: - DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive, - primitive_event_table); - break; - + return DO_LOOKUP(SCTP_EVENT_PRIMITIVE_MAX, primitive, + primitive_event_table); default: /* Yikes! We got an illegal event type. */ return &bug; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index fbb70770ad05d05807d25b5527e5616a621f58e8..e34ca9cc11675e249cd703ea58ba4fe2e5feeb82 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -57,6 +57,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -2469,9 +2471,8 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk, if (params.sack_delay == 0 && params.sack_freq == 0) return 0; } else if (optlen == sizeof(struct sctp_assoc_value)) { - printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " - "in delayed_ack socket option deprecated\n"); - printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); + pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); + pr_warn("Use struct sctp_sack_info instead\n"); if (copy_from_user(¶ms, optval, optlen)) return -EFAULT; @@ -2879,10 +2880,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned int val; if (optlen == sizeof(int)) { - printk(KERN_WARNING - "SCTP: Use of int in maxseg socket option deprecated\n"); - printk(KERN_WARNING - "SCTP: Use struct sctp_assoc_value instead\n"); + pr_warn("Use of int in maxseg socket option deprecated\n"); + pr_warn("Use struct sctp_assoc_value instead\n"); if (copy_from_user(&val, optval, optlen)) return -EFAULT; params.assoc_id = 0; @@ -3132,10 +3131,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk, int assoc_id = 0; if (optlen == sizeof(int)) { - printk(KERN_WARNING - "SCTP: Use of int in max_burst socket option deprecated\n"); - printk(KERN_WARNING - "SCTP: Use struct sctp_assoc_value instead\n"); + pr_warn("Use of int in max_burst socket option deprecated\n"); + pr_warn("Use struct sctp_assoc_value instead\n"); if (copy_from_user(&val, optval, optlen)) return -EFAULT; } else if (optlen == sizeof(struct sctp_assoc_value)) { @@ -3606,7 +3603,40 @@ SCTP_STATIC struct sock *sctp_accept(struct sock *sk, int flags, int *err) /* The SCTP ioctl handler. */ SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) { - return -ENOIOCTLCMD; + int rc = -ENOTCONN; + + sctp_lock_sock(sk); + + /* + * SEQPACKET-style sockets in LISTENING state are valid, for + * SCTP, so only discard TCP-style sockets in LISTENING state. + */ + if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) + goto out; + + switch (cmd) { + case SIOCINQ: { + struct sk_buff *skb; + unsigned int amount = 0; + + skb = skb_peek(&sk->sk_receive_queue); + if (skb != NULL) { + /* + * We will only return the amount of this packet since + * that is all that will be read. + */ + amount = skb->len; + } + rc = put_user(amount, (int __user *)arg); + break; + } + default: + rc = -ENOIOCTLCMD; + break; + } +out: + sctp_release_sock(sk); + return rc; } /* This is the function which gets called during socket creation to @@ -3865,7 +3895,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, } out: - return (retval); + return retval; } @@ -3921,7 +3951,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, } out: - return (retval); + return retval; } /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) @@ -4292,9 +4322,8 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, if (copy_from_user(¶ms, optval, len)) return -EFAULT; } else if (len == sizeof(struct sctp_assoc_value)) { - printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " - "in delayed_ack socket option deprecated\n"); - printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); + pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); + pr_warn("Use struct sctp_sack_info instead\n"); if (copy_from_user(¶ms, optval, len)) return -EFAULT; } else @@ -4940,10 +4969,8 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, struct sctp_association *asoc; if (len == sizeof(int)) { - printk(KERN_WARNING - "SCTP: Use of int in maxseg socket option deprecated\n"); - printk(KERN_WARNING - "SCTP: Use struct sctp_assoc_value instead\n"); + pr_warn("Use of int in maxseg socket option deprecated\n"); + pr_warn("Use struct sctp_assoc_value instead\n"); params.assoc_id = 0; } else if (len >= sizeof(struct sctp_assoc_value)) { len = sizeof(struct sctp_assoc_value); @@ -5034,10 +5061,8 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, struct sctp_association *asoc; if (len == sizeof(int)) { - printk(KERN_WARNING - "SCTP: Use of int in max_burst socket option deprecated\n"); - printk(KERN_WARNING - "SCTP: Use struct sctp_assoc_value instead\n"); + pr_warn("Use of int in max_burst socket option deprecated\n"); + pr_warn("Use struct sctp_assoc_value instead\n"); params.assoc_id = 0; } else if (len >= sizeof(struct sctp_assoc_value)) { len = sizeof(struct sctp_assoc_value); @@ -5580,7 +5605,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum) /* Note: sk->sk_num gets filled in if ephemeral port request. */ ret = sctp_get_port_local(sk, &addr); - return (ret ? 1 : 0); + return ret ? 1 : 0; } /* @@ -5597,8 +5622,7 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog) tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { if (net_ratelimit()) { - printk(KERN_INFO - "SCTP: failed to load transform for %s: %ld\n", + pr_info("failed to load transform for %s: %ld\n", sctp_hmac_alg, PTR_ERR(tfm)); } return -ENOSYS; @@ -5727,13 +5751,12 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) mask |= POLLERR; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; /* Is it readable? Reconsider this code with TCP-style support. */ - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; /* The association is either gone or not ready. */ diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 132046cb82fc764ae758a0535aad8816946ae1d2..d3ae493d234aaebe0e60c97e17479659e4a4c181 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -48,6 +48,8 @@ * be incorporated into the next SCTP release. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -244,10 +246,9 @@ void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) struct dst_entry *dst; if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { - printk(KERN_WARNING "%s: Reported pmtu %d too low, " - "using default minimum of %d\n", - __func__, pmtu, - SCTP_DEFAULT_MINSEGMENT); + pr_warn("%s: Reported pmtu %d too low, using default minimum of %d\n", + __func__, pmtu, + SCTP_DEFAULT_MINSEGMENT); /* Use default minimum segment size and disable * pmtu discovery on this transport. */ diff --git a/net/socket.c b/net/socket.c index 9eac5c3941340c60343233402886780117aa93d3..abf3e2561521acc1ce82167b9edaf71eaf263ee9 100644 --- a/net/socket.c +++ b/net/socket.c @@ -209,8 +209,8 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr) * specified. Zero is returned for a success. */ -int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, - int __user *ulen) +static int move_addr_to_user(struct sockaddr *kaddr, int klen, + void __user *uaddr, int __user *ulen) { int err; int len; @@ -536,14 +536,13 @@ void sock_release(struct socket *sock) } EXPORT_SYMBOL(sock_release); -int sock_tx_timestamp(struct msghdr *msg, struct sock *sk, - union skb_shared_tx *shtx) +int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags) { - shtx->flags = 0; + *tx_flags = 0; if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE)) - shtx->hardware = 1; + *tx_flags |= SKBTX_HW_TSTAMP; if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) - shtx->software = 1; + *tx_flags |= SKBTX_SW_TSTAMP; return 0; } EXPORT_SYMBOL(sock_tx_timestamp); @@ -663,7 +662,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, } EXPORT_SYMBOL_GPL(__sock_recv_timestamp); -inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) +static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, + struct sk_buff *skb) { if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount) put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL, @@ -1920,7 +1920,8 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) * Afterwards, it will be a kernel pointer. Thus the compiler-assisted * checking falls down on this. */ - if (copy_from_user(ctl_buf, (void __user *)msg_sys.msg_control, + if (copy_from_user(ctl_buf, + (void __user __force *)msg_sys.msg_control, ctl_len)) goto out_freectl; msg_sys.msg_control = ctl_buf; @@ -3055,14 +3056,19 @@ int kernel_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) { mm_segment_t oldfs = get_fs(); + char __user *uoptval; + int __user *uoptlen; int err; + uoptval = (char __user __force *) optval; + uoptlen = (int __user __force *) optlen; + set_fs(KERNEL_DS); if (level == SOL_SOCKET) - err = sock_getsockopt(sock, level, optname, optval, optlen); + err = sock_getsockopt(sock, level, optname, uoptval, uoptlen); else - err = sock->ops->getsockopt(sock, level, optname, optval, - optlen); + err = sock->ops->getsockopt(sock, level, optname, uoptval, + uoptlen); set_fs(oldfs); return err; } @@ -3072,13 +3078,16 @@ int kernel_setsockopt(struct socket *sock, int level, int optname, char *optval, unsigned int optlen) { mm_segment_t oldfs = get_fs(); + char __user *uoptval; int err; + uoptval = (char __user __force *) optval; + set_fs(KERNEL_DS); if (level == SOL_SOCKET) - err = sock_setsockopt(sock, level, optname, optval, optlen); + err = sock_setsockopt(sock, level, optname, uoptval, optlen); else - err = sock->ops->setsockopt(sock, level, optname, optval, + err = sock->ops->setsockopt(sock, level, optname, uoptval, optlen); set_fs(oldfs); return err; diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 12c4859828146cbdff7a0e9c38a039eaa3395426..3835ce35e224fc5915372cdc2d4422c7f842c3c5 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1050,7 +1050,7 @@ gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) out: if (acred->machine_cred != gss_cred->gc_machine_cred) return 0; - return (rc->cr_uid == acred->uid); + return rc->cr_uid == acred->uid; } /* diff --git a/net/sunrpc/auth_gss/gss_generic_token.c b/net/sunrpc/auth_gss/gss_generic_token.c index 310b78e994567e961984debbe99b0092b551cc94..c586e92bcf7614dc370d1011c037230ce8efc94f 100644 --- a/net/sunrpc/auth_gss/gss_generic_token.c +++ b/net/sunrpc/auth_gss/gss_generic_token.c @@ -76,19 +76,19 @@ static int der_length_size( int length) { if (length < (1<<7)) - return(1); + return 1; else if (length < (1<<8)) - return(2); + return 2; #if (SIZEOF_INT == 2) else - return(3); + return 3; #else else if (length < (1<<16)) - return(3); + return 3; else if (length < (1<<24)) - return(4); + return 4; else - return(5); + return 5; #endif } @@ -121,14 +121,14 @@ der_read_length(unsigned char **buf, int *bufsize) int ret; if (*bufsize < 1) - return(-1); + return -1; sf = *(*buf)++; (*bufsize)--; if (sf & 0x80) { if ((sf &= 0x7f) > ((*bufsize)-1)) - return(-1); + return -1; if (sf > SIZEOF_INT) - return (-1); + return -1; ret = 0; for (; sf; sf--) { ret = (ret<<8) + (*(*buf)++); @@ -138,7 +138,7 @@ der_read_length(unsigned char **buf, int *bufsize) ret = sf; } - return(ret); + return ret; } /* returns the length of a token, given the mech oid and the body size */ @@ -148,7 +148,7 @@ g_token_size(struct xdr_netobj *mech, unsigned int body_size) { /* set body_size to sequence contents size */ body_size += 2 + (int) mech->len; /* NEED overflow check */ - return(1 + der_length_size(body_size) + body_size); + return 1 + der_length_size(body_size) + body_size; } EXPORT_SYMBOL_GPL(g_token_size); @@ -186,27 +186,27 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size, int ret = 0; if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if (*buf++ != 0x60) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if ((seqsize = der_read_length(&buf, &toksize)) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if (seqsize != toksize) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if (*buf++ != 0x06) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if ((toksize-=1) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; toid.len = *buf++; if ((toksize-=toid.len) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; toid.data = buf; buf+=toid.len; @@ -217,17 +217,17 @@ g_verify_token_header(struct xdr_netobj *mech, int *body_size, to return G_BAD_TOK_HEADER if the token header is in fact bad */ if ((toksize-=2) < 0) - return(G_BAD_TOK_HEADER); + return G_BAD_TOK_HEADER; if (ret) - return(ret); + return ret; if (!ret) { *buf_in = buf; *body_size = toksize; } - return(ret); + return ret; } EXPORT_SYMBOL_GPL(g_verify_token_header); diff --git a/net/sunrpc/auth_gss/gss_krb5_seqnum.c b/net/sunrpc/auth_gss/gss_krb5_seqnum.c index 415c013ba382126cf88691cac6dc58d2febc59c3..62ac90c62cb12a8b7fb61d814aef5dbfd0a3b94c 100644 --- a/net/sunrpc/auth_gss/gss_krb5_seqnum.c +++ b/net/sunrpc/auth_gss/gss_krb5_seqnum.c @@ -162,5 +162,5 @@ krb5_get_seq_num(struct krb5_ctx *kctx, *seqnum = ((plain[0]) | (plain[1] << 8) | (plain[2] << 16) | (plain[3] << 24)); - return (0); + return 0; } diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 2689de39dc78c06d78a16d4c12fdfe28a633ef99..8b4061049d764a86320974f6e6eda39c7033affb 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -331,7 +331,7 @@ gss_delete_sec_context(struct gss_ctx **context_handle) *context_handle); if (!*context_handle) - return(GSS_S_NO_CONTEXT); + return GSS_S_NO_CONTEXT; if ((*context_handle)->internal_ctx_id) (*context_handle)->mech_type->gm_ops ->gss_delete_sec_context((*context_handle) diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index cace6049e4a5a1d3184829231aa776d7689ad8d0..aa5dbda6608cab75db59c6305ddbf38ac6cc4ade 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -376,7 +376,7 @@ int rpc_queue_empty(struct rpc_wait_queue *queue) spin_lock_bh(&queue->lock); res = queue->qlen; spin_unlock_bh(&queue->lock); - return (res == 0); + return res == 0; } EXPORT_SYMBOL_GPL(rpc_queue_empty); diff --git a/net/tipc/addr.c b/net/tipc/addr.c index c048543ffbebbb6ce37f8b57c8c6a758e4c629a9..8a2e89bffde5ca6677b3562a65b61380a3f7e0a7 100644 --- a/net/tipc/addr.c +++ b/net/tipc/addr.c @@ -41,11 +41,6 @@ #include "cluster.h" #include "net.h" -u32 tipc_get_addr(void) -{ - return tipc_own_addr; -} - /** * tipc_addr_domain_valid - validates a network domain address * @@ -89,7 +84,7 @@ int tipc_addr_domain_valid(u32 addr) int tipc_addr_node_valid(u32 addr) { - return (tipc_addr_domain_valid(addr) && tipc_node(addr)); + return tipc_addr_domain_valid(addr) && tipc_node(addr); } int tipc_in_scope(u32 domain, u32 addr) diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index a008c6689305bd7b037a5226f1107a878c943060..22a60fc98392de04e9b0d1ee4506309aa117cbba 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -121,6 +121,9 @@ static DEFINE_SPINLOCK(bc_lock); const char tipc_bclink_name[] = "broadcast-link"; +static void tipc_nmap_diff(struct tipc_node_map *nm_a, + struct tipc_node_map *nm_b, + struct tipc_node_map *nm_diff); static u32 buf_seqno(struct sk_buff *buf) { @@ -143,6 +146,19 @@ static void bcbuf_decr_acks(struct sk_buff *buf) } +static void bclink_set_last_sent(void) +{ + if (bcl->next_out) + bcl->fsm_msg_cnt = mod(buf_seqno(bcl->next_out) - 1); + else + bcl->fsm_msg_cnt = mod(bcl->next_out_no - 1); +} + +u32 tipc_bclink_get_last_sent(void) +{ + return bcl->fsm_msg_cnt; +} + /** * bclink_set_gap - set gap according to contents of current deferred pkt queue * @@ -171,7 +187,7 @@ static void bclink_set_gap(struct tipc_node *n_ptr) static int bclink_ack_allowed(u32 n) { - return((n % TIPC_MIN_LINK_WIN) == tipc_own_tag); + return (n % TIPC_MIN_LINK_WIN) == tipc_own_tag; } @@ -237,8 +253,10 @@ void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked) /* Try resolving broadcast link congestion, if necessary */ - if (unlikely(bcl->next_out)) + if (unlikely(bcl->next_out)) { tipc_link_push_queue(bcl); + bclink_set_last_sent(); + } if (unlikely(released && !list_empty(&bcl->waiting_ports))) tipc_link_wakeup_ports(bcl, 0); spin_unlock_bh(&bc_lock); @@ -272,7 +290,7 @@ static void bclink_send_nack(struct tipc_node *n_ptr) if (!less(n_ptr->bclink.gap_after, n_ptr->bclink.gap_to)) return; - buf = buf_acquire(INT_H_SIZE); + buf = tipc_buf_acquire(INT_H_SIZE); if (buf) { msg = buf_msg(buf); tipc_msg_init(msg, BCAST_PROTOCOL, STATE_MSG, @@ -395,7 +413,7 @@ int tipc_bclink_send_msg(struct sk_buff *buf) if (unlikely(res == -ELINKCONG)) buf_discard(buf); else - bcl->stats.sent_info++; + bclink_set_last_sent(); if (bcl->out_queue_size > bcl->stats.max_queue_sz) bcl->stats.max_queue_sz = bcl->out_queue_size; @@ -529,15 +547,6 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf) tipc_node_unlock(node); } -u32 tipc_bclink_get_last_sent(void) -{ - u32 last_sent = mod(bcl->next_out_no - 1); - - if (bcl->next_out) - last_sent = mod(buf_seqno(bcl->next_out) - 1); - return last_sent; -} - u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr) { return (n_ptr->bclink.supported && @@ -570,6 +579,7 @@ static int tipc_bcbearer_send(struct sk_buff *buf, msg = buf_msg(buf); msg_set_non_seq(msg, 1); msg_set_mc_netid(msg, tipc_net_id); + bcl->stats.sent_info++; } /* Send buffer over bearers until all targets reached */ @@ -609,11 +619,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf, bcbearer->remains = bcbearer->remains_new; } - /* Unable to reach all targets */ + /* + * Unable to reach all targets (indicate success, since currently + * there isn't code in place to properly block & unblock the + * pseudo-bearer used by the broadcast link) + */ - bcbearer->bearer.publ.blocked = 1; - bcl->stats.bearer_congs++; - return 1; + return TIPC_OK; } /** @@ -862,8 +874,9 @@ void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node) * @nm_diff: output node map A-B (i.e. nodes of A that are not in B) */ -void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b, - struct tipc_node_map *nm_diff) +static void tipc_nmap_diff(struct tipc_node_map *nm_a, + struct tipc_node_map *nm_b, + struct tipc_node_map *nm_diff) { int stop = ARRAY_SIZE(nm_a->map); int w; diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h index e8c2b81658c7513c1a49e8bf0c3d57a99348e0ea..011c03f0a4abebb16c104fbeec5386ea8e94022d 100644 --- a/net/tipc/bcast.h +++ b/net/tipc/bcast.h @@ -84,9 +84,6 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_m return !memcmp(nm_a, nm_b, sizeof(*nm_a)); } -void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b, - struct tipc_node_map *nm_diff); - void tipc_port_list_add(struct port_list *pl_ptr, u32 port); void tipc_port_list_free(struct port_list *pl_ptr); diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 52ae17b2583e3457c77652a9f842ed2aba237916..9927d1d56c4f1f8e2a015752be33b781c6ea6480 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -63,7 +63,7 @@ static int media_name_valid(const char *name) len = strlen(name); if ((len + 1) > TIPC_MAX_MEDIA_NAME) return 0; - return (strspn(name, tipc_alphabet) == len); + return strspn(name, tipc_alphabet) == len; } /** @@ -288,9 +288,6 @@ static struct bearer *bearer_find(const char *name) struct bearer *b_ptr; u32 i; - if (tipc_mode != TIPC_NET_MODE) - return NULL; - for (i = 0, b_ptr = tipc_bearers; i < MAX_BEARERS; i++, b_ptr++) { if (b_ptr->active && (!strcmp(b_ptr->publ.name, name))) return b_ptr; @@ -559,8 +556,6 @@ int tipc_enable_bearer(const char *name, u32 bcast_scope, u32 priority) } b_ptr = &tipc_bearers[bearer_id]; - memset(b_ptr, 0, sizeof(struct bearer)); - strcpy(b_ptr->publ.name, name); res = m_ptr->enable_bearer(&b_ptr->publ); if (res) { @@ -630,30 +625,17 @@ int tipc_block_bearer(const char *name) * Note: This routine assumes caller holds tipc_net_lock. */ -static int bearer_disable(const char *name) +static int bearer_disable(struct bearer *b_ptr) { - struct bearer *b_ptr; struct link *l_ptr; struct link *temp_l_ptr; - b_ptr = bearer_find(name); - if (!b_ptr) { - warn("Attempt to disable unknown bearer <%s>\n", name); - return -EINVAL; - } - - info("Disabling bearer <%s>\n", name); + info("Disabling bearer <%s>\n", b_ptr->publ.name); tipc_disc_stop_link_req(b_ptr->link_req); spin_lock_bh(&b_ptr->publ.lock); b_ptr->link_req = NULL; b_ptr->publ.blocked = 1; - if (b_ptr->media->disable_bearer) { - spin_unlock_bh(&b_ptr->publ.lock); - write_unlock_bh(&tipc_net_lock); - b_ptr->media->disable_bearer(&b_ptr->publ); - write_lock_bh(&tipc_net_lock); - spin_lock_bh(&b_ptr->publ.lock); - } + b_ptr->media->disable_bearer(&b_ptr->publ); list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { tipc_link_delete(l_ptr); } @@ -664,10 +646,16 @@ static int bearer_disable(const char *name) int tipc_disable_bearer(const char *name) { + struct bearer *b_ptr; int res; write_lock_bh(&tipc_net_lock); - res = bearer_disable(name); + b_ptr = bearer_find(name); + if (b_ptr == NULL) { + warn("Attempt to disable unknown bearer <%s>\n", name); + res = -EINVAL; + } else + res = bearer_disable(b_ptr); write_unlock_bh(&tipc_net_lock); return res; } @@ -680,13 +668,7 @@ void tipc_bearer_stop(void) for (i = 0; i < MAX_BEARERS; i++) { if (tipc_bearers[i].active) - tipc_bearers[i].publ.blocked = 1; - } - for (i = 0; i < MAX_BEARERS; i++) { - if (tipc_bearers[i].active) - bearer_disable(tipc_bearers[i].publ.name); + bearer_disable(&tipc_bearers[i]); } media_count = 0; } - - diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c index e68f705381bc345a75283dc69074c737fba26f7a..7fea14b98b9716ba927e0476979cbf9747f9850b 100644 --- a/net/tipc/cluster.c +++ b/net/tipc/cluster.c @@ -113,25 +113,6 @@ void tipc_cltr_delete(struct cluster *c_ptr) kfree(c_ptr); } -u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr) -{ - struct tipc_node *n_ptr; - u32 n_num = tipc_node(addr) + 1; - - if (!c_ptr) - return addr; - for (; n_num <= c_ptr->highest_node; n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && tipc_node_has_active_links(n_ptr)) - return n_ptr->addr; - } - for (n_num = 1; n_num < tipc_node(addr); n_num++) { - n_ptr = c_ptr->nodes[n_num]; - if (n_ptr && tipc_node_has_active_links(n_ptr)) - return n_ptr->addr; - } - return 0; -} void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr) { @@ -232,7 +213,7 @@ struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector) static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest) { u32 size = INT_H_SIZE + data_size; - struct sk_buff *buf = buf_acquire(size); + struct sk_buff *buf = tipc_buf_acquire(size); struct tipc_msg *msg; if (buf) { diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h index 333efb0b9c44c28c1c479c293e58213de473b821..32636d98c9c6878e2266bfca65dc3ab65b4fce3c 100644 --- a/net/tipc/cluster.h +++ b/net/tipc/cluster.h @@ -75,7 +75,7 @@ void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr); void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest); void tipc_cltr_broadcast(struct sk_buff *buf); int tipc_cltr_init(void); -u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr); + void tipc_cltr_bcast_new_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); void tipc_cltr_send_local_routes(struct cluster *c_ptr, u32 dest); void tipc_cltr_bcast_lost_route(struct cluster *c_ptr, u32 dest, u32 lo, u32 hi); diff --git a/net/tipc/config.c b/net/tipc/config.c index 961d1b097146d99dd90f45721937668f22b5d7f6..50a6133a3668f082daf5bb5f6e63a1b67191ab52 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c @@ -95,7 +95,7 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, return 1; } -struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) +static struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) { struct sk_buff *buf; __be32 value_net; @@ -109,6 +109,11 @@ struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) return buf; } +static struct sk_buff *tipc_cfg_reply_unsigned(u32 value) +{ + return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value); +} + struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) { struct sk_buff *buf; @@ -120,139 +125,6 @@ struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string) return buf; } - -#if 0 - -/* Now obsolete code for handling commands not yet implemented the new way */ - -/* - * Some of this code assumed that the manager structure contains two added - * fields: - * u32 link_subscriptions; - * struct list_head link_subscribers; - * which are currently not present. These fields may need to be re-introduced - * if and when support for link subscriptions is added. - */ - -void tipc_cfg_link_event(u32 addr, char *name, int up) -{ - /* TIPC DOESN'T HANDLE LINK EVENT SUBSCRIPTIONS AT THE MOMENT */ -} - -int tipc_cfg_cmd(const struct tipc_cmd_msg * msg, - char *data, - u32 sz, - u32 *ret_size, - struct tipc_portid *orig) -{ - int rv = -EINVAL; - u32 cmd = msg->cmd; - - *ret_size = 0; - switch (cmd) { - case TIPC_REMOVE_LINK: - case TIPC_CMD_BLOCK_LINK: - case TIPC_CMD_UNBLOCK_LINK: - if (!cfg_check_connection(orig)) - rv = link_control(msg->argv.link_name, msg->cmd, 0); - break; - case TIPC_ESTABLISH: - { - int connected; - - tipc_isconnected(mng.conn_port_ref, &connected); - if (connected || !orig) { - rv = TIPC_FAILURE; - break; - } - rv = tipc_connect2port(mng.conn_port_ref, orig); - if (rv == TIPC_OK) - orig = 0; - break; - } - case TIPC_GET_PEER_ADDRESS: - *ret_size = link_peer_addr(msg->argv.link_name, data, sz); - break; - case TIPC_GET_ROUTES: - rv = TIPC_OK; - break; - default: {} - } - if (*ret_size) - rv = TIPC_OK; - return rv; -} - -static void cfg_cmd_event(struct tipc_cmd_msg *msg, - char *data, - u32 sz, - struct tipc_portid const *orig) -{ - int rv = -EINVAL; - struct tipc_cmd_result_msg rmsg; - struct iovec msg_sect[2]; - int *arg; - - msg->cmd = ntohl(msg->cmd); - - cfg_prepare_res_msg(msg->cmd, msg->usr_handle, rv, &rmsg, msg_sect, - data, 0); - if (ntohl(msg->magic) != TIPC_MAGIC) - goto exit; - - switch (msg->cmd) { - case TIPC_CREATE_LINK: - if (!cfg_check_connection(orig)) - rv = disc_create_link(&msg->argv.create_link); - break; - case TIPC_LINK_SUBSCRIBE: - { - struct subscr_data *sub; - - if (mng.link_subscriptions > 64) - break; - sub = kmalloc(sizeof(*sub), - GFP_ATOMIC); - if (sub == NULL) { - warn("Memory squeeze; dropped remote link subscription\n"); - break; - } - INIT_LIST_HEAD(&sub->subd_list); - tipc_createport(mng.user_ref, - (void *)sub, - TIPC_HIGH_IMPORTANCE, - 0, - 0, - (tipc_conn_shutdown_event)cfg_linksubscr_cancel, - 0, - 0, - (tipc_conn_msg_event)cfg_linksubscr_cancel, - 0, - &sub->port_ref); - if (!sub->port_ref) { - kfree(sub); - break; - } - memcpy(sub->usr_handle,msg->usr_handle, - sizeof(sub->usr_handle)); - sub->domain = msg->argv.domain; - list_add_tail(&sub->subd_list, &mng.link_subscribers); - tipc_connect2port(sub->port_ref, orig); - rmsg.retval = TIPC_OK; - tipc_send(sub->port_ref, 2u, msg_sect); - mng.link_subscriptions++; - return; - } - default: - rv = tipc_cfg_cmd(msg, data, sz, (u32 *)&msg_sect[1].iov_len, orig); - } -exit: - rmsg.result_len = htonl(msg_sect[1].iov_len); - rmsg.retval = htonl(rv); - tipc_cfg_respond(msg_sect, 2u, orig); -} -#endif - #define MAX_STATS_INFO 2000 static struct sk_buff *tipc_show_stats(void) @@ -557,14 +429,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area case TIPC_CMD_SHOW_PORTS: rep_tlv_buf = tipc_port_get_ports(); break; -#if 0 - case TIPC_CMD_SHOW_PORT_STATS: - rep_tlv_buf = port_show_stats(req_tlv_area, req_tlv_space); - break; - case TIPC_CMD_RESET_PORT_STATS: - rep_tlv_buf = tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED); - break; -#endif case TIPC_CMD_SET_LOG_SIZE: rep_tlv_buf = tipc_log_resize_cmd(req_tlv_area, req_tlv_space); break; diff --git a/net/tipc/config.h b/net/tipc/config.h index 5cd7cc56c54d13ee43a1a5155ff3d0a99dfa5a88..481e12ece715dcc9c02b44928e1cf2b3b2635eb1 100644 --- a/net/tipc/config.h +++ b/net/tipc/config.h @@ -45,7 +45,6 @@ struct sk_buff *tipc_cfg_reply_alloc(int payload_size); int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type, void *tlv_data, int tlv_data_size); -struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value); struct sk_buff *tipc_cfg_reply_string_type(u16 tlv_type, char *string); static inline struct sk_buff *tipc_cfg_reply_none(void) @@ -53,11 +52,6 @@ static inline struct sk_buff *tipc_cfg_reply_none(void) return tipc_cfg_reply_alloc(0); } -static inline struct sk_buff *tipc_cfg_reply_unsigned(u32 value) -{ - return tipc_cfg_reply_unsigned_type(TIPC_TLV_UNSIGNED, value); -} - static inline struct sk_buff *tipc_cfg_reply_error_string(char *string) { return tipc_cfg_reply_string_type(TIPC_TLV_ERROR_STRING, string); diff --git a/net/tipc/core.c b/net/tipc/core.c index 69646811798542cb29b37e66dd424679464a30a9..e2a09eb8efd459957c79475a24e9b5849537f90f 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c @@ -96,13 +96,8 @@ int tipc_net_id; int tipc_remote_management; -int tipc_get_mode(void) -{ - return tipc_mode; -} - /** - * buf_acquire - creates a TIPC message buffer + * tipc_buf_acquire - creates a TIPC message buffer * @size: message size (including TIPC header) * * Returns a new buffer with data pointers set to the specified size. @@ -111,7 +106,7 @@ int tipc_get_mode(void) * There may also be unrequested tailroom present at the buffer's end. */ -struct sk_buff *buf_acquire(u32 size) +struct sk_buff *tipc_buf_acquire(u32 size) { struct sk_buff *skb; unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u; @@ -129,7 +124,7 @@ struct sk_buff *buf_acquire(u32 size) * tipc_core_stop_net - shut down TIPC networking sub-systems */ -void tipc_core_stop_net(void) +static void tipc_core_stop_net(void) { tipc_eth_media_stop(); tipc_net_stop(); @@ -154,7 +149,7 @@ int tipc_core_start_net(unsigned long addr) * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode */ -void tipc_core_stop(void) +static void tipc_core_stop(void) { if (tipc_mode != TIPC_NODE_MODE) return; @@ -169,13 +164,14 @@ void tipc_core_stop(void) tipc_nametbl_stop(); tipc_ref_table_stop(); tipc_socket_stop(); + tipc_log_resize(0); } /** * tipc_core_start - switch TIPC from NOT RUNNING to SINGLE NODE mode */ -int tipc_core_start(void) +static int tipc_core_start(void) { int res; @@ -203,7 +199,9 @@ static int __init tipc_init(void) { int res; - tipc_log_resize(CONFIG_TIPC_LOG); + if (tipc_log_resize(CONFIG_TIPC_LOG) != 0) + warn("Unable to create log buffer\n"); + info("Activated (version " TIPC_MOD_VER " compiled " __DATE__ " " __TIME__ ")\n"); @@ -230,7 +228,6 @@ static void __exit tipc_exit(void) tipc_core_stop_net(); tipc_core_stop(); info("Deactivated\n"); - tipc_log_resize(0); } module_init(tipc_init); @@ -244,8 +241,6 @@ MODULE_VERSION(TIPC_MOD_VER); EXPORT_SYMBOL(tipc_attach); EXPORT_SYMBOL(tipc_detach); -EXPORT_SYMBOL(tipc_get_addr); -EXPORT_SYMBOL(tipc_get_mode); EXPORT_SYMBOL(tipc_createport); EXPORT_SYMBOL(tipc_deleteport); EXPORT_SYMBOL(tipc_ownidentity); @@ -260,23 +255,10 @@ EXPORT_SYMBOL(tipc_withdraw); EXPORT_SYMBOL(tipc_connect2port); EXPORT_SYMBOL(tipc_disconnect); EXPORT_SYMBOL(tipc_shutdown); -EXPORT_SYMBOL(tipc_isconnected); -EXPORT_SYMBOL(tipc_peer); -EXPORT_SYMBOL(tipc_ref_valid); EXPORT_SYMBOL(tipc_send); -EXPORT_SYMBOL(tipc_send_buf); EXPORT_SYMBOL(tipc_send2name); -EXPORT_SYMBOL(tipc_forward2name); -EXPORT_SYMBOL(tipc_send_buf2name); -EXPORT_SYMBOL(tipc_forward_buf2name); EXPORT_SYMBOL(tipc_send2port); -EXPORT_SYMBOL(tipc_forward2port); -EXPORT_SYMBOL(tipc_send_buf2port); -EXPORT_SYMBOL(tipc_forward_buf2port); EXPORT_SYMBOL(tipc_multicast); -/* EXPORT_SYMBOL(tipc_multicast_buf); not available yet */ -EXPORT_SYMBOL(tipc_ispublished); -EXPORT_SYMBOL(tipc_available_nodes); /* TIPC API for external bearers (see tipc_bearer.h) */ @@ -293,6 +275,4 @@ EXPORT_SYMBOL(tipc_createport_raw); EXPORT_SYMBOL(tipc_reject_msg); EXPORT_SYMBOL(tipc_send_buf_fast); EXPORT_SYMBOL(tipc_acknowledge); -EXPORT_SYMBOL(tipc_get_port); -EXPORT_SYMBOL(tipc_get_handle); diff --git a/net/tipc/core.h b/net/tipc/core.h index 188799017abdb35aa5416862539395dbb412974b..e19389e57227572a5da156393ab90bc7b3573a1c 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h @@ -83,9 +83,7 @@ * Note: TIPC_LOG is configured to echo its output to the system console; * user-defined buffers can be configured to do the same thing. */ - extern struct print_buf *const TIPC_NULL; -extern struct print_buf *const TIPC_CONS; extern struct print_buf *const TIPC_LOG; void tipc_printf(struct print_buf *, const char *fmt, ...); @@ -204,10 +202,7 @@ extern atomic_t tipc_user_count; * Routines available to privileged subsystems */ -extern int tipc_core_start(void); -extern void tipc_core_stop(void); -extern int tipc_core_start_net(unsigned long addr); -extern void tipc_core_stop_net(void); +extern int tipc_core_start_net(unsigned long); extern int tipc_handler_start(void); extern void tipc_handler_stop(void); extern int tipc_netlink_start(void); @@ -328,7 +323,7 @@ static inline struct tipc_msg *buf_msg(struct sk_buff *skb) return (struct tipc_msg *)skb->data; } -extern struct sk_buff *buf_acquire(u32 size); +extern struct sk_buff *tipc_buf_acquire(u32 size); /** * buf_discard - frees a TIPC message buffer diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c index 1885a7edb0c8014831e3e6f2a9f9a91ba326674d..46f51d208e5e55193f410ae1c9c512f6144ff791 100644 --- a/net/tipc/dbg.c +++ b/net/tipc/dbg.c @@ -52,7 +52,7 @@ static struct print_buf null_buf = { NULL, 0, NULL, 0 }; struct print_buf *const TIPC_NULL = &null_buf; static struct print_buf cons_buf = { NULL, 0, NULL, 1 }; -struct print_buf *const TIPC_CONS = &cons_buf; +static struct print_buf *const TIPC_CONS = &cons_buf; static struct print_buf log_buf = { NULL, 0, NULL, 1 }; struct print_buf *const TIPC_LOG = &log_buf; @@ -76,6 +76,10 @@ struct print_buf *const TIPC_LOG = &log_buf; static char print_string[TIPC_PB_MAX_STR]; static DEFINE_SPINLOCK(print_lock); +static void tipc_printbuf_reset(struct print_buf *pb); +static int tipc_printbuf_empty(struct print_buf *pb); +static void tipc_printbuf_move(struct print_buf *pb_to, + struct print_buf *pb_from); #define FORMAT(PTR,LEN,FMT) \ {\ @@ -116,7 +120,7 @@ void tipc_printbuf_init(struct print_buf *pb, char *raw, u32 size) * @pb: pointer to print buffer structure */ -void tipc_printbuf_reset(struct print_buf *pb) +static void tipc_printbuf_reset(struct print_buf *pb) { if (pb->buf) { pb->crs = pb->buf; @@ -132,9 +136,9 @@ void tipc_printbuf_reset(struct print_buf *pb) * Returns non-zero if print buffer is empty. */ -int tipc_printbuf_empty(struct print_buf *pb) +static int tipc_printbuf_empty(struct print_buf *pb) { - return (!pb->buf || (pb->crs == pb->buf)); + return !pb->buf || (pb->crs == pb->buf); } /** @@ -169,7 +173,7 @@ int tipc_printbuf_validate(struct print_buf *pb) tipc_printf(pb, err); } } - return (pb->crs - pb->buf + 1); + return pb->crs - pb->buf + 1; } /** @@ -181,7 +185,8 @@ int tipc_printbuf_validate(struct print_buf *pb) * Source print buffer becomes empty if a successful move occurs. */ -void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from) +static void tipc_printbuf_move(struct print_buf *pb_to, + struct print_buf *pb_from) { int len; diff --git a/net/tipc/dbg.h b/net/tipc/dbg.h index 5ef1bc8f64ef186b5db3dfedbe839fe25ef4c52e..3ba6ba8b434ae38a8815982729057036fa0459dd 100644 --- a/net/tipc/dbg.h +++ b/net/tipc/dbg.h @@ -56,10 +56,7 @@ struct print_buf { #define TIPC_PB_MAX_STR 512 /* max printable string (with trailing NUL) */ void tipc_printbuf_init(struct print_buf *pb, char *buf, u32 size); -void tipc_printbuf_reset(struct print_buf *pb); -int tipc_printbuf_empty(struct print_buf *pb); int tipc_printbuf_validate(struct print_buf *pb); -void tipc_printbuf_move(struct print_buf *pb_to, struct print_buf *pb_from); int tipc_log_resize(int log_size); diff --git a/net/tipc/discover.c b/net/tipc/discover.c index fc1fcf5e6b53625e4bc22ad29228af151de6288f..4a7cd3719b781f42739d8c5c524e4a324e09d79b 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -46,16 +46,6 @@ #define TIPC_LINK_REQ_FAST 2000 /* normal delay if bearer has no links */ #define TIPC_LINK_REQ_SLOW 600000 /* normal delay if bearer has links */ -#if 0 -#define GET_NODE_INFO 300 -#define GET_NODE_INFO_RESULT 301 -#define FORWARD_LINK_PROBE 302 -#define LINK_REQUEST_REJECTED 303 -#define LINK_REQUEST_ACCEPTED 304 -#define DROP_LINK_REQUEST 305 -#define CHECK_LINK_COUNT 306 -#endif - /* * TODO: Most of the inter-cluster setup stuff should be * rewritten, and be made conformant with specification. @@ -78,30 +68,6 @@ struct link_req { unsigned int timer_intv; }; - -#if 0 -int disc_create_link(const struct tipc_link_create *argv) -{ - /* - * Code for inter cluster link setup here - */ - return TIPC_OK; -} -#endif - -/* - * disc_lost_link(): A link has lost contact - */ - -void tipc_disc_link_event(u32 addr, char *name, int up) -{ - if (in_own_cluster(addr)) - return; - /* - * Code for inter cluster link setup here - */ -} - /** * tipc_disc_init_msg - initialize a link setup message * @type: message type (request or response) @@ -115,7 +81,7 @@ static struct sk_buff *tipc_disc_init_msg(u32 type, u32 dest_domain, struct bearer *b_ptr) { - struct sk_buff *buf = buf_acquire(DSC_H_SIZE); + struct sk_buff *buf = tipc_buf_acquire(DSC_H_SIZE); struct tipc_msg *msg; if (buf) { @@ -203,6 +169,14 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr) return; } spin_lock_bh(&n_ptr->lock); + + /* Don't talk to neighbor during cleanup after last session */ + + if (n_ptr->cleanup_required) { + spin_unlock_bh(&n_ptr->lock); + return; + } + link = n_ptr->links[b_ptr->identity]; if (!link) { dbg("creating link\n"); diff --git a/net/tipc/discover.h b/net/tipc/discover.h index c36eaeb7d5d0bb2e55461468d430a0c8b15734ac..f8e75063612340fa8ea7e3f653dd5e1978ee47f8 100644 --- a/net/tipc/discover.h +++ b/net/tipc/discover.h @@ -50,9 +50,4 @@ void tipc_disc_stop_link_req(struct link_req *req); void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr); -void tipc_disc_link_event(u32 addr, char *name, int up); -#if 0 -int disc_create_link(const struct tipc_link_create *argv); -#endif - #endif diff --git a/net/tipc/eth_media.c b/net/tipc/eth_media.c index 6230d16020c49917f5f28e06b514d379f698205d..6e988ba485fde54bed1b2dde5038a05f354d24d8 100644 --- a/net/tipc/eth_media.c +++ b/net/tipc/eth_media.c @@ -72,17 +72,26 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, { struct sk_buff *clone; struct net_device *dev; + int delta; clone = skb_clone(buf, GFP_ATOMIC); - if (clone) { - skb_reset_network_header(clone); - dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; - clone->dev = dev; - dev_hard_header(clone, dev, ETH_P_TIPC, - &dest->dev_addr.eth_addr, - dev->dev_addr, clone->len); - dev_queue_xmit(clone); + if (!clone) + return 0; + + dev = ((struct eth_bearer *)(tb_ptr->usr_handle))->dev; + delta = dev->hard_header_len - skb_headroom(buf); + + if ((delta > 0) && + pskb_expand_head(clone, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) { + kfree_skb(clone); + return 0; } + + skb_reset_network_header(clone); + clone->dev = dev; + dev_hard_header(clone, dev, ETH_P_TIPC, &dest->dev_addr.eth_addr, + dev->dev_addr, clone->len); + dev_queue_xmit(clone); return 0; } @@ -92,15 +101,12 @@ static int send_msg(struct sk_buff *buf, struct tipc_bearer *tb_ptr, * Accept only packets explicitly sent to this node, or broadcast packets; * ignores packets sent using Ethernet multicast, and traffic sent to other * nodes (which can happen if interface is running in promiscuous mode). - * Routine truncates any Ethernet padding/CRC appended to the message, - * and ensures message size matches actual length */ static int recv_msg(struct sk_buff *buf, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) { struct eth_bearer *eb_ptr = (struct eth_bearer *)pt->af_packet_priv; - u32 size; if (!net_eq(dev_net(dev), &init_net)) { kfree_skb(buf); @@ -109,13 +115,9 @@ static int recv_msg(struct sk_buff *buf, struct net_device *dev, if (likely(eb_ptr->bearer)) { if (likely(buf->pkt_type <= PACKET_BROADCAST)) { - size = msg_size((struct tipc_msg *)buf->data); - skb_trim(buf, size); - if (likely(buf->len == size)) { - buf->next = NULL; - tipc_recv_msg(buf, eb_ptr->bearer); - return 0; - } + buf->next = NULL; + tipc_recv_msg(buf, eb_ptr->bearer); + return 0; } } kfree_skb(buf); @@ -133,6 +135,16 @@ static int enable_bearer(struct tipc_bearer *tb_ptr) struct eth_bearer *eb_ptr = ð_bearers[0]; struct eth_bearer *stop = ð_bearers[MAX_ETH_BEARERS]; char *driver_name = strchr((const char *)tb_ptr->name, ':') + 1; + int pending_dev = 0; + + /* Find unused Ethernet bearer structure */ + + while (eb_ptr->dev) { + if (!eb_ptr->bearer) + pending_dev++; + if (++eb_ptr == stop) + return pending_dev ? -EAGAIN : -EDQUOT; + } /* Find device with specified name */ diff --git a/net/tipc/link.c b/net/tipc/link.c index a3616b99529b72ef1085fe95c99fd972e95e6b93..b31992ccd5d3a2dc60c3d0e4ca9de186ff9e6682 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -99,23 +99,6 @@ struct link_name { char if_peer[TIPC_MAX_IF_NAME]; }; -#if 0 - -/* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ - -/** - * struct link_event - link up/down event notification - */ - -struct link_event { - u32 addr; - int up; - void (*fcn)(u32, char *, int); - char name[TIPC_MAX_LINK_NAME]; -}; - -#endif - static void link_handle_out_of_seq_msg(struct link *l_ptr, struct sk_buff *buf); static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf); @@ -129,6 +112,9 @@ static void link_state_event(struct link *l_ptr, u32 event); static void link_reset_statistics(struct link *l_ptr); static void link_print(struct link *l_ptr, struct print_buf *buf, const char *str); +static void link_start(struct link *l_ptr); +static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf); + /* * Debugging code used by link routines only @@ -239,13 +225,13 @@ int tipc_link_is_up(struct link *l_ptr) { if (!l_ptr) return 0; - return (link_working_working(l_ptr) || link_working_unknown(l_ptr)); + return link_working_working(l_ptr) || link_working_unknown(l_ptr); } int tipc_link_is_active(struct link *l_ptr) { - return ((l_ptr->owner->active_links[0] == l_ptr) || - (l_ptr->owner->active_links[1] == l_ptr)); + return (l_ptr->owner->active_links[0] == l_ptr) || + (l_ptr->owner->active_links[1] == l_ptr); } /** @@ -459,7 +445,7 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); list_add_tail(&l_ptr->link_list, &b_ptr->links); - tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr); + tipc_k_signal((Handler)link_start, (unsigned long)l_ptr); dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n", l_ptr->tolerance, l_ptr->continuity_interval, l_ptr->abort_limit); @@ -499,9 +485,9 @@ void tipc_link_delete(struct link *l_ptr) kfree(l_ptr); } -void tipc_link_start(struct link *l_ptr) +static void link_start(struct link *l_ptr) { - dbg("tipc_link_start %x\n", l_ptr); + dbg("link_start %x\n", l_ptr); link_state_event(l_ptr, STARTING_EVT); } @@ -634,39 +620,9 @@ void tipc_link_stop(struct link *l_ptr) l_ptr->proto_msg_queue = NULL; } -#if 0 - /* LINK EVENT CODE IS NOT SUPPORTED AT PRESENT */ - -static void link_recv_event(struct link_event *ev) -{ - ev->fcn(ev->addr, ev->name, ev->up); - kfree(ev); -} - -static void link_send_event(void (*fcn)(u32 a, char *n, int up), - struct link *l_ptr, int up) -{ - struct link_event *ev; - - ev = kmalloc(sizeof(*ev), GFP_ATOMIC); - if (!ev) { - warn("Link event allocation failure\n"); - return; - } - ev->addr = l_ptr->addr; - ev->up = up; - ev->fcn = fcn; - memcpy(ev->name, l_ptr->name, TIPC_MAX_LINK_NAME); - tipc_k_signal((Handler)link_recv_event, (unsigned long)ev); -} - -#else - #define link_send_event(fcn, l_ptr, up) do { } while (0) -#endif - void tipc_link_reset(struct link *l_ptr) { struct sk_buff *buf; @@ -690,10 +646,7 @@ void tipc_link_reset(struct link *l_ptr) tipc_node_link_down(l_ptr->owner, l_ptr); tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr); -#if 0 - tipc_printf(TIPC_CONS, "\nReset link <%s>\n", l_ptr->name); - dbg_link_dump(); -#endif + if (was_active_link && tipc_node_has_active_links(l_ptr->owner) && l_ptr->owner->permit_changeover) { l_ptr->reset_checkpoint = checkpoint; @@ -1050,7 +1003,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) /* Fragmentation needed ? */ if (size > max_packet) - return tipc_link_send_long_buf(l_ptr, buf); + return link_send_long_buf(l_ptr, buf); /* Packet can be queued or sent: */ @@ -1086,7 +1039,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf) /* Try creating a new bundle */ if (size <= max_packet * 2 / 3) { - struct sk_buff *bundler = buf_acquire(max_packet); + struct sk_buff *bundler = tipc_buf_acquire(max_packet); struct tipc_msg bundler_hdr; if (bundler) { @@ -1362,7 +1315,7 @@ static int link_send_sections_long(struct port *sender, /* Prepare header of first fragment: */ - buf_chain = buf = buf_acquire(max_pkt); + buf_chain = buf = tipc_buf_acquire(max_pkt); if (!buf) return -ENOMEM; buf->next = NULL; @@ -1419,7 +1372,7 @@ static int link_send_sections_long(struct port *sender, msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); msg_set_fragm_no(&fragm_hdr, ++fragm_no); prev = buf; - buf = buf_acquire(fragm_sz + INT_H_SIZE); + buf = tipc_buf_acquire(fragm_sz + INT_H_SIZE); if (!buf) goto error; @@ -1802,6 +1755,15 @@ static int link_recv_buf_validate(struct sk_buff *buf) return pskb_may_pull(buf, hdr_size); } +/** + * tipc_recv_msg - process TIPC messages arriving from off-node + * @head: pointer to message buffer chain + * @tb_ptr: pointer to bearer message arrived on + * + * Invoked with no locks held. Bearer pointer must point to a valid bearer + * structure (i.e. cannot be NULL), but bearer can be inactive. + */ + void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) { read_lock_bh(&tipc_net_lock); @@ -1819,6 +1781,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) head = head->next; + /* Ensure bearer is still enabled */ + + if (unlikely(!b_ptr->active)) + goto cont; + /* Ensure message is well-formed */ if (unlikely(!link_recv_buf_validate(buf))) @@ -1855,13 +1822,22 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr) goto cont; } - /* Locate unicast link endpoint that should handle message */ + /* Locate neighboring node that sent message */ n_ptr = tipc_node_find(msg_prevnode(msg)); if (unlikely(!n_ptr)) goto cont; tipc_node_lock(n_ptr); + /* Don't talk to neighbor during cleanup after last session */ + + if (n_ptr->cleanup_required) { + tipc_node_unlock(n_ptr); + goto cont; + } + + /* Locate unicast link endpoint that should handle message */ + l_ptr = n_ptr->links[b_ptr->identity]; if (unlikely(!l_ptr)) { tipc_node_unlock(n_ptr); @@ -2172,7 +2148,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { if (!l_ptr->proto_msg_queue) { l_ptr->proto_msg_queue = - buf_acquire(sizeof(l_ptr->proto_msg)); + tipc_buf_acquire(sizeof(l_ptr->proto_msg)); } buf = l_ptr->proto_msg_queue; if (!buf) @@ -2186,7 +2162,7 @@ void tipc_link_send_proto_msg(struct link *l_ptr, u32 msg_typ, int probe_msg, msg_dbg(msg, ">>"); - buf = buf_acquire(msg_size); + buf = tipc_buf_acquire(msg_size); if (!buf) return; @@ -2345,10 +2321,10 @@ static void link_recv_proto_msg(struct link *l_ptr, struct sk_buff *buf) * tipc_link_tunnel(): Send one message via a link belonging to * another bearer. Owner node is locked. */ -void tipc_link_tunnel(struct link *l_ptr, - struct tipc_msg *tunnel_hdr, - struct tipc_msg *msg, - u32 selector) +static void tipc_link_tunnel(struct link *l_ptr, + struct tipc_msg *tunnel_hdr, + struct tipc_msg *msg, + u32 selector) { struct link *tunnel; struct sk_buff *buf; @@ -2361,7 +2337,7 @@ void tipc_link_tunnel(struct link *l_ptr, return; } msg_set_size(tunnel_hdr, length + INT_H_SIZE); - buf = buf_acquire(length + INT_H_SIZE); + buf = tipc_buf_acquire(length + INT_H_SIZE); if (!buf) { warn("Link changeover error, " "unable to send tunnel msg\n"); @@ -2407,7 +2383,7 @@ void tipc_link_changeover(struct link *l_ptr) if (!l_ptr->first_out) { struct sk_buff *buf; - buf = buf_acquire(INT_H_SIZE); + buf = tipc_buf_acquire(INT_H_SIZE); if (buf) { skb_copy_to_linear_data(buf, &tunnel_hdr, INT_H_SIZE); msg_set_size(&tunnel_hdr, INT_H_SIZE); @@ -2468,7 +2444,7 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *tunnel) msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); /* Update */ msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); msg_set_size(&tunnel_hdr, length + INT_H_SIZE); - outbuf = buf_acquire(length + INT_H_SIZE); + outbuf = tipc_buf_acquire(length + INT_H_SIZE); if (outbuf == NULL) { warn("Link changeover error, " "unable to send duplicate msg\n"); @@ -2504,7 +2480,7 @@ static struct sk_buff *buf_extract(struct sk_buff *skb, u32 from_pos) u32 size = msg_size(msg); struct sk_buff *eb; - eb = buf_acquire(size); + eb = tipc_buf_acquire(size); if (eb) skb_copy_to_linear_data(eb, msg, size); return eb; @@ -2632,11 +2608,11 @@ void tipc_link_recv_bundle(struct sk_buff *buf) /* - * tipc_link_send_long_buf: Entry for buffers needing fragmentation. + * link_send_long_buf: Entry for buffers needing fragmentation. * The buffer is complete, inclusive total message length. * Returns user data length. */ -int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) +static int link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) { struct tipc_msg *inmsg = buf_msg(buf); struct tipc_msg fragm_hdr; @@ -2675,7 +2651,7 @@ int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf) fragm_sz = rest; msg_set_type(&fragm_hdr, LAST_FRAGMENT); } - fragm = buf_acquire(fragm_sz + INT_H_SIZE); + fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); if (fragm == NULL) { warn("Link unable to fragment message\n"); dsz = -ENOMEM; @@ -2780,7 +2756,7 @@ int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, buf_discard(fbuf); return 0; } - pbuf = buf_acquire(msg_size(imsg)); + pbuf = tipc_buf_acquire(msg_size(imsg)); if (pbuf != NULL) { pbuf->next = *pending; *pending = pbuf; @@ -3174,44 +3150,6 @@ struct sk_buff *tipc_link_cmd_show_stats(const void *req_tlv_area, int req_tlv_s return buf; } -#if 0 -int link_control(const char *name, u32 op, u32 val) -{ - int res = -EINVAL; - struct link *l_ptr; - u32 bearer_id; - struct tipc_node * node; - u32 a; - - a = link_name2addr(name, &bearer_id); - read_lock_bh(&tipc_net_lock); - node = tipc_node_find(a); - if (node) { - tipc_node_lock(node); - l_ptr = node->links[bearer_id]; - if (l_ptr) { - if (op == TIPC_REMOVE_LINK) { - struct bearer *b_ptr = l_ptr->b_ptr; - spin_lock_bh(&b_ptr->publ.lock); - tipc_link_delete(l_ptr); - spin_unlock_bh(&b_ptr->publ.lock); - } - if (op == TIPC_CMD_BLOCK_LINK) { - tipc_link_reset(l_ptr); - l_ptr->blocked = 1; - } - if (op == TIPC_CMD_UNBLOCK_LINK) { - l_ptr->blocked = 0; - } - res = 0; - } - tipc_node_unlock(node); - } - read_unlock_bh(&tipc_net_lock); - return res; -} -#endif - /** * tipc_link_get_max_pkt - get maximum packet size to use when sending to destination * @dest: network address of destination node @@ -3242,28 +3180,6 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector) return res; } -#if 0 -static void link_dump_rec_queue(struct link *l_ptr) -{ - struct sk_buff *crs; - - if (!l_ptr->oldest_deferred_in) { - info("Reception queue empty\n"); - return; - } - info("Contents of Reception queue:\n"); - crs = l_ptr->oldest_deferred_in; - while (crs) { - if (crs->data == (void *)0x0000a3a3) { - info("buffer %x invalid\n", crs); - return; - } - msg_dbg(buf_msg(crs), "In rec queue:\n"); - crs = crs->next; - } -} -#endif - static void link_dump_send_queue(struct link *l_ptr) { if (l_ptr->next_out) { diff --git a/net/tipc/link.h b/net/tipc/link.h index 2e5385c47d30ccbe67bad535ff21c6f58fe93b0d..f98bc613de67b247b0369df611044bf75604e5cd 100644 --- a/net/tipc/link.h +++ b/net/tipc/link.h @@ -210,10 +210,6 @@ struct link { u32 msg_length_counts; u32 msg_lengths_total; u32 msg_length_profile[7]; -#if 0 - u32 sent_tunneled; - u32 recv_tunneled; -#endif } stats; struct print_buf print_buf; @@ -229,7 +225,6 @@ void tipc_link_send_duplicate(struct link *l_ptr, struct link *dest); void tipc_link_reset_fragments(struct link *l_ptr); int tipc_link_is_up(struct link *l_ptr); int tipc_link_is_active(struct link *l_ptr); -void tipc_link_start(struct link *l_ptr); u32 tipc_link_push_packet(struct link *l_ptr); void tipc_link_stop(struct link *l_ptr); struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space, u16 cmd); @@ -243,9 +238,6 @@ int tipc_link_send_sections_fast(struct port* sender, struct iovec const *msg_sect, const u32 num_sect, u32 destnode); -int tipc_link_send_long_buf(struct link *l_ptr, struct sk_buff *buf); -void tipc_link_tunnel(struct link *l_ptr, struct tipc_msg *tnl_hdr, - struct tipc_msg *msg, u32 selector); void tipc_link_recv_bundle(struct sk_buff *buf); int tipc_link_recv_fragment(struct sk_buff **pending, struct sk_buff **fb, @@ -279,12 +271,12 @@ static inline int between(u32 lower, u32 upper, u32 n) static inline int less_eq(u32 left, u32 right) { - return (mod(right - left) < 32768u); + return mod(right - left) < 32768u; } static inline int less(u32 left, u32 right) { - return (less_eq(left, right) && (mod(right) != mod(left))); + return less_eq(left, right) && (mod(right) != mod(left)); } static inline u32 lesser(u32 left, u32 right) @@ -299,32 +291,32 @@ static inline u32 lesser(u32 left, u32 right) static inline int link_working_working(struct link *l_ptr) { - return (l_ptr->state == WORKING_WORKING); + return l_ptr->state == WORKING_WORKING; } static inline int link_working_unknown(struct link *l_ptr) { - return (l_ptr->state == WORKING_UNKNOWN); + return l_ptr->state == WORKING_UNKNOWN; } static inline int link_reset_unknown(struct link *l_ptr) { - return (l_ptr->state == RESET_UNKNOWN); + return l_ptr->state == RESET_UNKNOWN; } static inline int link_reset_reset(struct link *l_ptr) { - return (l_ptr->state == RESET_RESET); + return l_ptr->state == RESET_RESET; } static inline int link_blocked(struct link *l_ptr) { - return (l_ptr->exp_msg_count || l_ptr->blocked); + return l_ptr->exp_msg_count || l_ptr->blocked; } static inline int link_congested(struct link *l_ptr) { - return (l_ptr->out_queue_size >= l_ptr->queue_limit[0]); + return l_ptr->out_queue_size >= l_ptr->queue_limit[0]; } #endif diff --git a/net/tipc/msg.c b/net/tipc/msg.c index 381063817b41b393069c54945e092540610f047e..ecb532fb03512f69720f1c47c6ce9a03b0e7264f 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c @@ -112,7 +112,7 @@ int tipc_msg_build(struct tipc_msg *hdr, return dsz; } - *buf = buf_acquire(sz); + *buf = tipc_buf_acquire(sz); if (!(*buf)) return -ENOMEM; skb_copy_to_linear_data(*buf, hdr, hsz); diff --git a/net/tipc/msg.h b/net/tipc/msg.h index 995d2da35b01d238fe7ad439d8a8d765e94f8c0e..031aad18efce4306c19a2d6b215f73ed9826a418 100644 --- a/net/tipc/msg.h +++ b/net/tipc/msg.h @@ -104,7 +104,7 @@ static inline u32 msg_user(struct tipc_msg *m) static inline u32 msg_isdata(struct tipc_msg *m) { - return (msg_user(m) <= TIPC_CRITICAL_IMPORTANCE); + return msg_user(m) <= TIPC_CRITICAL_IMPORTANCE; } static inline void msg_set_user(struct tipc_msg *m, u32 n) @@ -289,7 +289,7 @@ static inline void msg_set_destnode(struct tipc_msg *m, u32 a) static inline int msg_is_dest(struct tipc_msg *m, u32 d) { - return(msg_short(m) || (msg_destnode(m) == d)); + return msg_short(m) || (msg_destnode(m) == d); } static inline u32 msg_routed(struct tipc_msg *m) @@ -632,7 +632,7 @@ static inline void msg_set_bcast_tag(struct tipc_msg *m, u32 n) static inline u32 msg_max_pkt(struct tipc_msg *m) { - return (msg_bits(m, 9, 16, 0xffff) * 4); + return msg_bits(m, 9, 16, 0xffff) * 4; } static inline void msg_set_max_pkt(struct tipc_msg *m, u32 n) diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 6ac3c543250bfebc1f7f82d4ea7b516393cbf974..7b907171f879ecf7ab2c1a33c0ce6cf2e1f5fca4 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c @@ -98,7 +98,7 @@ static void publ_to_item(struct distr_item *i, struct publication *p) static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest) { - struct sk_buff *buf = buf_acquire(LONG_H_SIZE + size); + struct sk_buff *buf = tipc_buf_acquire(LONG_H_SIZE + size); struct tipc_msg *msg; if (buf != NULL) { diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 8ba79620db3f705941fa04ba25aeda92f1215d98..3a8de4334da15905adb23e9c84f72bdb58c01fed 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -116,7 +116,7 @@ DEFINE_RWLOCK(tipc_nametbl_lock); static int hash(int x) { - return(x & (tipc_nametbl_size - 1)); + return x & (tipc_nametbl_size - 1); } /** @@ -613,8 +613,7 @@ struct publication *tipc_nametbl_remove_publ(u32 type, u32 lower, } /* - * tipc_nametbl_translate(): Translate tipc_name -> tipc_portid. - * Very time-critical. + * tipc_nametbl_translate - translate name to port id * * Note: on entry 'destnode' is the search domain used during translation; * on exit it passes back the node address of the matching port (if any) @@ -685,7 +684,6 @@ u32 tipc_nametbl_translate(u32 type, u32 instance, u32 *destnode) } spin_unlock_bh(&seq->lock); not_found: - *destnode = 0; read_unlock_bh(&tipc_nametbl_lock); return 0; } @@ -877,7 +875,7 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, u32 index) { char portIdStr[27]; - char *scopeStr; + const char *scope_str[] = {"", " zone", " cluster", " node"}; struct publication *publ = sseq->zone_list; tipc_printf(buf, "%-10u %-10u ", sseq->lower, sseq->upper); @@ -893,15 +891,8 @@ static void subseq_list(struct sub_seq *sseq, struct print_buf *buf, u32 depth, tipc_node(publ->node), publ->ref); tipc_printf(buf, "%-26s ", portIdStr); if (depth > 3) { - if (publ->node != tipc_own_addr) - scopeStr = ""; - else if (publ->scope == TIPC_NODE_SCOPE) - scopeStr = "node"; - else if (publ->scope == TIPC_CLUSTER_SCOPE) - scopeStr = "cluster"; - else - scopeStr = "zone"; - tipc_printf(buf, "%-10u %s", publ->key, scopeStr); + tipc_printf(buf, "%-10u %s", publ->key, + scope_str[publ->scope]); } publ = publ->zone_list_next; @@ -951,24 +942,19 @@ static void nameseq_list(struct name_seq *seq, struct print_buf *buf, u32 depth, static void nametbl_header(struct print_buf *buf, u32 depth) { - tipc_printf(buf, "Type "); - - if (depth > 1) - tipc_printf(buf, "Lower Upper "); - if (depth > 2) - tipc_printf(buf, "Port Identity "); - if (depth > 3) - tipc_printf(buf, "Publication"); - - tipc_printf(buf, "\n-----------"); - - if (depth > 1) - tipc_printf(buf, "--------------------- "); - if (depth > 2) - tipc_printf(buf, "-------------------------- "); - if (depth > 3) - tipc_printf(buf, "------------------"); - + const char *header[] = { + "Type ", + "Lower Upper ", + "Port Identity ", + "Publication Scope" + }; + + int i; + + if (depth > 4) + depth = 4; + for (i = 0; i < depth; i++) + tipc_printf(buf, header[i]); tipc_printf(buf, "\n"); } @@ -1023,16 +1009,6 @@ static void nametbl_list(struct print_buf *buf, u32 depth_info, } } -#if 0 -void tipc_nametbl_print(struct print_buf *buf, const char *str) -{ - tipc_printf(buf, str); - read_lock_bh(&tipc_nametbl_lock); - nametbl_list(buf, 0, 0, 0, 0); - read_unlock_bh(&tipc_nametbl_lock); -} -#endif - #define MAX_NAME_TBL_QUERY 32768 struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) @@ -1065,13 +1041,6 @@ struct sk_buff *tipc_nametbl_get(const void *req_tlv_area, int req_tlv_space) return buf; } -#if 0 -void tipc_nametbl_dump(void) -{ - nametbl_list(TIPC_CONS, 0, 0, 0, 0); -} -#endif - int tipc_nametbl_init(void) { table.types = kcalloc(tipc_nametbl_size, sizeof(struct hlist_head), diff --git a/net/tipc/net.c b/net/tipc/net.c index f61b7694138b5f7c0a208cfd2ce883d7a6c88d4b..1a621cfd66046566df9c4e6a4fb33797fe3464ea 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c @@ -129,15 +129,6 @@ u32 tipc_net_select_router(u32 addr, u32 ref) return tipc_zone_select_router(tipc_net.zones[tipc_zone(addr)], addr, ref); } -#if 0 -u32 tipc_net_next_node(u32 a) -{ - if (tipc_net.zones[tipc_zone(a)]) - return tipc_zone_next_node(a); - return 0; -} -#endif - void tipc_net_remove_as_router(u32 router) { u32 z_num; @@ -248,6 +239,7 @@ void tipc_net_route_msg(struct sk_buff *buf) /* Handle message for another node */ msg_dbg(msg, "NET>SEND>: "); + skb_trim(buf, msg_size(msg)); tipc_link_send(buf, dnode, msg_link_selector(msg)); } diff --git a/net/tipc/node.c b/net/tipc/node.c index b634942caba5d5ed9204269c327b9fa6fef4512f..b4d87eb2dc5d871352d6d1f54ea73df830d83779 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -50,7 +50,8 @@ void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str); static void node_lost_contact(struct tipc_node *n_ptr); static void node_established_contact(struct tipc_node *n_ptr); -struct tipc_node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ +/* sorted list of nodes within cluster */ +static struct tipc_node *tipc_nodes = NULL; static DEFINE_SPINLOCK(node_create_lock); @@ -125,16 +126,6 @@ void tipc_node_delete(struct tipc_node *n_ptr) if (!n_ptr) return; -#if 0 - /* Not needed because links are already deleted via tipc_bearer_stop() */ - - u32 l_num; - - for (l_num = 0; l_num < MAX_BEARERS; l_num++) { - link_delete(n_ptr->links[l_num]); - } -#endif - dbg("node %x deleted\n", n_ptr->addr); kfree(n_ptr); } @@ -237,23 +228,22 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr) int tipc_node_has_active_links(struct tipc_node *n_ptr) { - return (n_ptr && - ((n_ptr->active_links[0]) || (n_ptr->active_links[1]))); + return n_ptr->active_links[0] != NULL; } int tipc_node_has_redundant_links(struct tipc_node *n_ptr) { - return (n_ptr->working_links > 1); + return n_ptr->working_links > 1; } static int tipc_node_has_active_routes(struct tipc_node *n_ptr) { - return (n_ptr && (n_ptr->last_router >= 0)); + return n_ptr && (n_ptr->last_router >= 0); } int tipc_node_is_up(struct tipc_node *n_ptr) { - return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr)); + return tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr); } struct tipc_node *tipc_node_attach_link(struct link *l_ptr) @@ -384,6 +374,20 @@ static void node_established_contact(struct tipc_node *n_ptr) tipc_highest_allowed_slave); } +static void node_cleanup_finished(unsigned long node_addr) +{ + struct tipc_node *n_ptr; + + read_lock_bh(&tipc_net_lock); + n_ptr = tipc_node_find(node_addr); + if (n_ptr) { + tipc_node_lock(n_ptr); + n_ptr->cleanup_required = 0; + tipc_node_unlock(n_ptr); + } + read_unlock_bh(&tipc_net_lock); +} + static void node_lost_contact(struct tipc_node *n_ptr) { struct cluster *c_ptr; @@ -458,6 +462,11 @@ static void node_lost_contact(struct tipc_node *n_ptr) tipc_k_signal((Handler)ns->handle_node_down, (unsigned long)ns->usr_handle); } + + /* Prevent re-contact with node until all cleanup is done */ + + n_ptr->cleanup_required = 1; + tipc_k_signal((Handler)node_cleanup_finished, n_ptr->addr); } /** @@ -579,38 +588,6 @@ void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router) node_lost_contact(n_ptr); } -#if 0 -void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str) -{ - u32 i; - - tipc_printf(buf, "\n\n%s", str); - for (i = 0; i < MAX_BEARERS; i++) { - if (!n_ptr->links[i]) - continue; - tipc_printf(buf, "Links[%u]: %x, ", i, n_ptr->links[i]); - } - tipc_printf(buf, "Active links: [%x,%x]\n", - n_ptr->active_links[0], n_ptr->active_links[1]); -} -#endif - -u32 tipc_available_nodes(const u32 domain) -{ - struct tipc_node *n_ptr; - u32 cnt = 0; - - read_lock_bh(&tipc_net_lock); - for (n_ptr = tipc_nodes; n_ptr; n_ptr = n_ptr->next) { - if (!tipc_in_scope(domain, n_ptr->addr)) - continue; - if (tipc_node_is_up(n_ptr)) - cnt++; - } - read_unlock_bh(&tipc_net_lock); - return cnt; -} - struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space) { u32 domain; diff --git a/net/tipc/node.h b/net/tipc/node.h index 6f990da5d143cb30b63a87576c21f483186fbbc6..fff331b2d26c46103b64b5a986444af3c579de08 100644 --- a/net/tipc/node.h +++ b/net/tipc/node.h @@ -52,6 +52,7 @@ * @active_links: pointers to active links to node * @links: pointers to all links to node * @working_links: number of working links to node (both active and standby) + * @cleanup_required: non-zero if cleaning up after a prior loss of contact * @link_cnt: number of links to node * @permit_changeover: non-zero if node has redundant links to this system * @routers: bitmap (used for multicluster communication) @@ -78,6 +79,7 @@ struct tipc_node { struct link *links[MAX_BEARERS]; int link_cnt; int working_links; + int cleanup_required; int permit_changeover; u32 routers[512/32]; int last_router; @@ -94,7 +96,6 @@ struct tipc_node { } bclink; }; -extern struct tipc_node *tipc_nodes; extern u32 tipc_own_tag; struct tipc_node *tipc_node_create(u32 addr); diff --git a/net/tipc/port.c b/net/tipc/port.c index 0737680e9266021f528f5addec9ff0acefbec406..82092eaa15366f4262689bd58e37b9a2d91c60b8 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c @@ -293,34 +293,6 @@ int tipc_deleteport(u32 ref) return 0; } -/** - * tipc_get_port() - return port associated with 'ref' - * - * Note: Port is not locked. - */ - -struct tipc_port *tipc_get_port(const u32 ref) -{ - return (struct tipc_port *)tipc_ref_deref(ref); -} - -/** - * tipc_get_handle - return user handle associated to port 'ref' - */ - -void *tipc_get_handle(const u32 ref) -{ - struct port *p_ptr; - void * handle; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return NULL; - handle = p_ptr->publ.usr_handle; - tipc_port_unlock(p_ptr); - return handle; -} - static int port_unreliable(struct port *p_ptr) { return msg_src_droppable(&p_ptr->publ.phdr); @@ -392,7 +364,7 @@ static struct sk_buff *port_build_proto_msg(u32 destport, u32 destnode, struct sk_buff *buf; struct tipc_msg *msg; - buf = buf_acquire(LONG_H_SIZE); + buf = tipc_buf_acquire(LONG_H_SIZE); if (buf) { msg = buf_msg(buf); tipc_msg_init(msg, usr, type, LONG_H_SIZE, destnode); @@ -433,7 +405,7 @@ int tipc_reject_msg(struct sk_buff *buf, u32 err) hdr_sz = MCAST_H_SIZE; else hdr_sz = LONG_H_SIZE; - rbuf = buf_acquire(data_sz + hdr_sz); + rbuf = tipc_buf_acquire(data_sz + hdr_sz); if (rbuf == NULL) { buf_discard(buf); return data_sz; @@ -588,19 +560,10 @@ void tipc_port_recv_proto_msg(struct sk_buff *buf) if (!p_ptr) { err = TIPC_ERR_NO_PORT; } else if (p_ptr->publ.connected) { - if (port_peernode(p_ptr) != msg_orignode(msg)) + if ((port_peernode(p_ptr) != msg_orignode(msg)) || + (port_peerport(p_ptr) != msg_origport(msg))) { err = TIPC_ERR_NO_PORT; - if (port_peerport(p_ptr) != msg_origport(msg)) - err = TIPC_ERR_NO_PORT; - if (!err && msg_routed(msg)) { - u32 seqno = msg_transp_seqno(msg); - u32 myno = ++p_ptr->last_in_seqno; - if (seqno != myno) { - err = TIPC_ERR_NO_PORT; - abort_buf = port_build_self_abort_msg(p_ptr, err); - } - } - if (msg_type(msg) == CONN_ACK) { + } else if (msg_type(msg) == CONN_ACK) { int wakeup = tipc_port_congested(p_ptr) && p_ptr->publ.congested && p_ptr->wakeup; @@ -719,50 +682,6 @@ struct sk_buff *tipc_port_get_ports(void) return buf; } -#if 0 - -#define MAX_PORT_STATS 2000 - -struct sk_buff *port_show_stats(const void *req_tlv_area, int req_tlv_space) -{ - u32 ref; - struct port *p_ptr; - struct sk_buff *buf; - struct tlv_desc *rep_tlv; - struct print_buf pb; - int str_len; - - if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_PORT_REF)) - return cfg_reply_error_string(TIPC_CFG_TLV_ERROR); - - ref = *(u32 *)TLV_DATA(req_tlv_area); - ref = ntohl(ref); - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return cfg_reply_error_string("port not found"); - - buf = tipc_cfg_reply_alloc(TLV_SPACE(MAX_PORT_STATS)); - if (!buf) { - tipc_port_unlock(p_ptr); - return NULL; - } - rep_tlv = (struct tlv_desc *)buf->data; - - tipc_printbuf_init(&pb, TLV_DATA(rep_tlv), MAX_PORT_STATS); - port_print(p_ptr, &pb, 1); - /* NEED TO FILL IN ADDITIONAL PORT STATISTICS HERE */ - tipc_port_unlock(p_ptr); - str_len = tipc_printbuf_validate(&pb); - - skb_put(buf, TLV_SPACE(str_len)); - TLV_SET(rep_tlv, TIPC_TLV_ULTRA_STRING, NULL, str_len); - - return buf; -} - -#endif - void tipc_port_reinit(void) { struct port *p_ptr; @@ -1295,50 +1214,13 @@ int tipc_shutdown(u32 ref) return tipc_disconnect(ref); } -int tipc_isconnected(u32 ref, int *isconnected) -{ - struct port *p_ptr; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - *isconnected = p_ptr->publ.connected; - tipc_port_unlock(p_ptr); - return 0; -} - -int tipc_peer(u32 ref, struct tipc_portid *peer) -{ - struct port *p_ptr; - int res; - - p_ptr = tipc_port_lock(ref); - if (!p_ptr) - return -EINVAL; - if (p_ptr->publ.connected) { - peer->ref = port_peerport(p_ptr); - peer->node = port_peernode(p_ptr); - res = 0; - } else - res = -ENOTCONN; - tipc_port_unlock(p_ptr); - return res; -} - -int tipc_ref_valid(u32 ref) -{ - /* Works irrespective of type */ - return !!tipc_ref_deref(ref); -} - - /* * tipc_port_recv_sections(): Concatenate and deliver sectioned * message for this node. */ -int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, - struct iovec const *msg_sect) +static int tipc_port_recv_sections(struct port *sender, unsigned int num_sect, + struct iovec const *msg_sect) { struct sk_buff *buf; int res; @@ -1388,66 +1270,17 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect) return -ELINKCONG; } -/** - * tipc_send_buf - send message buffer on connection - */ - -int tipc_send_buf(u32 ref, struct sk_buff *buf, unsigned int dsz) -{ - struct port *p_ptr; - struct tipc_msg *msg; - u32 destnode; - u32 hsz; - u32 sz; - u32 res; - - p_ptr = tipc_port_deref(ref); - if (!p_ptr || !p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - hsz = msg_hdr_sz(msg); - sz = hsz + dsz; - msg_set_size(msg, sz); - if (skb_cow(buf, hsz)) - return -ENOMEM; - - skb_push(buf, hsz); - skb_copy_to_linear_data(buf, msg, hsz); - destnode = msg_destnode(msg); - p_ptr->publ.congested = 1; - if (!tipc_port_congested(p_ptr)) { - if (likely(destnode != tipc_own_addr)) - res = tipc_send_buf_fast(buf, destnode); - else { - tipc_port_recv_msg(buf); - res = sz; - } - if (likely(res != -ELINKCONG)) { - port_incr_out_seqno(p_ptr); - p_ptr->sent++; - p_ptr->publ.congested = 0; - return res; - } - } - if (port_unreliable(p_ptr)) { - p_ptr->publ.congested = 0; - return dsz; - } - return -ELINKCONG; -} - /** * tipc_forward2name - forward message sections to port name */ -int tipc_forward2name(u32 ref, - struct tipc_name const *name, - u32 domain, - u32 num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *orig, - unsigned int importance) +static int tipc_forward2name(u32 ref, + struct tipc_name const *name, + u32 domain, + u32 num_sect, + struct iovec const *msg_sect, + struct tipc_portid const *orig, + unsigned int importance) { struct port *p_ptr; struct tipc_msg *msg; @@ -1473,7 +1306,7 @@ int tipc_forward2name(u32 ref, msg_set_destnode(msg, destnode); msg_set_destport(msg, destport); - if (likely(destport || destnode)) { + if (likely(destport)) { p_ptr->sent++; if (likely(destnode == tipc_own_addr)) return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); @@ -1509,90 +1342,16 @@ int tipc_send2name(u32 ref, TIPC_PORT_IMPORTANCE); } -/** - * tipc_forward_buf2name - forward message buffer to port name - */ - -int tipc_forward_buf2name(u32 ref, - struct tipc_name const *name, - u32 domain, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance) -{ - struct port *p_ptr; - struct tipc_msg *msg; - u32 destnode = domain; - u32 destport; - int res; - - p_ptr = (struct port *)tipc_ref_deref(ref); - if (!p_ptr || p_ptr->publ.connected) - return -EINVAL; - - msg = &p_ptr->publ.phdr; - if (importance <= TIPC_CRITICAL_IMPORTANCE) - msg_set_importance(msg, importance); - msg_set_type(msg, TIPC_NAMED_MSG); - msg_set_orignode(msg, orig->node); - msg_set_origport(msg, orig->ref); - msg_set_nametype(msg, name->type); - msg_set_nameinst(msg, name->instance); - msg_set_lookup_scope(msg, tipc_addr_scope(domain)); - msg_set_hdr_sz(msg, LONG_H_SIZE); - msg_set_size(msg, LONG_H_SIZE + dsz); - destport = tipc_nametbl_translate(name->type, name->instance, &destnode); - msg_set_destnode(msg, destnode); - msg_set_destport(msg, destport); - msg_dbg(msg, "forw2name ==> "); - if (skb_cow(buf, LONG_H_SIZE)) - return -ENOMEM; - skb_push(buf, LONG_H_SIZE); - skb_copy_to_linear_data(buf, msg, LONG_H_SIZE); - msg_dbg(buf_msg(buf),"PREP:"); - if (likely(destport || destnode)) { - p_ptr->sent++; - if (destnode == tipc_own_addr) - return tipc_port_recv_msg(buf); - res = tipc_send_buf_fast(buf, destnode); - if (likely(res != -ELINKCONG)) - return res; - if (port_unreliable(p_ptr)) - return dsz; - return -ELINKCONG; - } - return tipc_reject_msg(buf, TIPC_ERR_NO_NAME); -} - -/** - * tipc_send_buf2name - send message buffer to port name - */ - -int tipc_send_buf2name(u32 ref, - struct tipc_name const *dest, - u32 domain, - struct sk_buff *buf, - unsigned int dsz) -{ - struct tipc_portid orig; - - orig.ref = ref; - orig.node = tipc_own_addr; - return tipc_forward_buf2name(ref, dest, domain, buf, dsz, &orig, - TIPC_PORT_IMPORTANCE); -} - /** * tipc_forward2port - forward message sections to port identity */ -int tipc_forward2port(u32 ref, - struct tipc_portid const *dest, - unsigned int num_sect, - struct iovec const *msg_sect, - struct tipc_portid const *orig, - unsigned int importance) +static int tipc_forward2port(u32 ref, + struct tipc_portid const *dest, + unsigned int num_sect, + struct iovec const *msg_sect, + struct tipc_portid const *orig, + unsigned int importance) { struct port *p_ptr; struct tipc_msg *msg; @@ -1644,12 +1403,12 @@ int tipc_send2port(u32 ref, /** * tipc_forward_buf2port - forward message buffer to port identity */ -int tipc_forward_buf2port(u32 ref, - struct tipc_portid const *dest, - struct sk_buff *buf, - unsigned int dsz, - struct tipc_portid const *orig, - unsigned int importance) +static int tipc_forward_buf2port(u32 ref, + struct tipc_portid const *dest, + struct sk_buff *buf, + unsigned int dsz, + struct tipc_portid const *orig, + unsigned int importance) { struct port *p_ptr; struct tipc_msg *msg; diff --git a/net/tipc/port.h b/net/tipc/port.h index 8d1652aab298c0ba1132e045b3fb37e66bb14e12..73bbf442b346750791965913bed1b146a07e68e0 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h @@ -109,8 +109,6 @@ struct port { extern spinlock_t tipc_port_list_lock; struct port_list; -int tipc_port_recv_sections(struct port *p_ptr, u32 num_sect, - struct iovec const *msg_sect); int tipc_port_reject_sections(struct port *p_ptr, struct tipc_msg *hdr, struct iovec const *msg_sect, u32 num_sect, int err); @@ -157,7 +155,7 @@ static inline u32 tipc_peer_node(struct port *p_ptr) static inline int tipc_port_congested(struct port *p_ptr) { - return((p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2)); + return (p_ptr->sent - p_ptr->acked) >= (TIPC_FLOW_CONTROL_WIN * 2); } /** diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 8dea66500cf5ce65d6427aad77152f437e0c92ac..ab8ad32d8c202260d283c555b3b435b71dc0ab04 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c @@ -282,23 +282,6 @@ void *tipc_ref_lock(u32 ref) return NULL; } -/** - * tipc_ref_unlock - unlock referenced object - */ - -void tipc_ref_unlock(u32 ref) -{ - if (likely(tipc_ref_table.entries)) { - struct reference *entry; - - entry = &tipc_ref_table.entries[ref & - tipc_ref_table.index_mask]; - if (likely((entry->ref == ref) && (entry->object))) - spin_unlock_bh(&entry->lock); - else - err("Attempt to unlock non-existent reference\n"); - } -} /** * tipc_ref_deref - return pointer referenced object (without locking it) diff --git a/net/tipc/ref.h b/net/tipc/ref.h index 7e3798ea93b9bd437787f2051167f4425432bc6d..5bc8e7ab84de8192ca71c97a0ae415474f8e266c 100644 --- a/net/tipc/ref.h +++ b/net/tipc/ref.h @@ -44,7 +44,6 @@ u32 tipc_ref_acquire(void *object, spinlock_t **lock); void tipc_ref_discard(u32 ref); void *tipc_ref_lock(u32 ref); -void tipc_ref_unlock(u32 ref); void *tipc_ref_deref(u32 ref); #endif diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 66e889ba48fd4d61088bd6e3f5e0721d7348d20b..33217fc3d697436cc5a82643a9d1fecb0986aac0 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -64,6 +64,7 @@ struct tipc_sock { struct sock sk; struct tipc_port *p; struct tipc_portid peer_name; + long conn_timeout; }; #define tipc_sk(sk) ((struct tipc_sock *)(sk)) @@ -240,9 +241,9 @@ static int tipc_create(struct net *net, struct socket *sock, int protocol, sock->state = state; sock_init_data(sock, sk); - sk->sk_rcvtimeo = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); sk->sk_backlog_rcv = backlog_rcv; tipc_sk(sk)->p = tp_ptr; + tipc_sk(sk)->conn_timeout = msecs_to_jiffies(CONN_TIMEOUT_DEFAULT); spin_unlock_bh(tp_ptr->lock); @@ -429,36 +430,55 @@ static int get_name(struct socket *sock, struct sockaddr *uaddr, * to handle any preventable race conditions, so TIPC will do the same ... * * TIPC sets the returned events as follows: - * a) POLLRDNORM and POLLIN are set if the socket's receive queue is non-empty - * or if a connection-oriented socket is does not have an active connection - * (i.e. a read operation will not block). - * b) POLLOUT is set except when a socket's connection has been terminated - * (i.e. a write operation will not block). - * c) POLLHUP is set when a socket's connection has been terminated. - * - * IMPORTANT: The fact that a read or write operation will not block does NOT - * imply that the operation will succeed! + * + * socket state flags set + * ------------ --------- + * unconnected no read flags + * no write flags + * + * connecting POLLIN/POLLRDNORM if ACK/NACK in rx queue + * no write flags + * + * connected POLLIN/POLLRDNORM if data in rx queue + * POLLOUT if port is not congested + * + * disconnecting POLLIN/POLLRDNORM/POLLHUP + * no write flags + * + * listening POLLIN if SYN in rx queue + * no write flags + * + * ready POLLIN/POLLRDNORM if data in rx queue + * [connectionless] POLLOUT (since port cannot be congested) + * + * IMPORTANT: The fact that a read or write operation is indicated does NOT + * imply that the operation will succeed, merely that it should be performed + * and will not block. */ static unsigned int poll(struct file *file, struct socket *sock, poll_table *wait) { struct sock *sk = sock->sk; - u32 mask; + u32 mask = 0; poll_wait(file, sk_sleep(sk), wait); - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sock->state == SS_UNCONNECTED) || - (sock->state == SS_DISCONNECTING)) - mask = (POLLRDNORM | POLLIN); - else - mask = 0; - - if (sock->state == SS_DISCONNECTING) - mask |= POLLHUP; - else - mask |= POLLOUT; + switch ((int)sock->state) { + case SS_READY: + case SS_CONNECTED: + if (!tipc_sk_port(sk)->congested) + mask |= POLLOUT; + /* fall thru' */ + case SS_CONNECTING: + case SS_LISTENING: + if (!skb_queue_empty(&sk->sk_receive_queue)) + mask |= (POLLIN | POLLRDNORM); + break; + case SS_DISCONNECTING: + mask = (POLLIN | POLLRDNORM | POLLHUP); + break; + } return mask; } @@ -1026,9 +1046,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, struct sk_buff *buf; struct tipc_msg *msg; unsigned int sz; - int sz_to_copy; + int sz_to_copy, target, needed; int sz_copied = 0; - int needed; char __user *crs = m->msg_iov->iov_base; unsigned char *buf_crs; u32 err; @@ -1050,6 +1069,8 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, goto exit; } + target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); + restart: /* Look for a message in receive queue; wait if necessary */ @@ -1138,7 +1159,7 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock, if ((sz_copied < buf_len) && /* didn't get all requested data */ (!skb_queue_empty(&sk->sk_receive_queue) || - (flags & MSG_WAITALL)) && /* and more is ready or required */ + (sz_copied < target)) && /* and more is ready or required */ (!(flags & MSG_PEEK)) && /* and aren't just peeking at data */ (!err)) /* and haven't reached a FIN */ goto restart; @@ -1174,7 +1195,7 @@ static int rx_queue_full(struct tipc_msg *msg, u32 queue_size, u32 base) if (msg_connected(msg)) threshold *= 4; - return (queue_size >= threshold); + return queue_size >= threshold; } /** @@ -1365,6 +1386,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, struct msghdr m = {NULL,}; struct sk_buff *buf; struct tipc_msg *msg; + long timeout; int res; lock_sock(sk); @@ -1379,7 +1401,7 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, /* For now, TIPC does not support the non-blocking form of connect() */ if (flags & O_NONBLOCK) { - res = -EWOULDBLOCK; + res = -EOPNOTSUPP; goto exit; } @@ -1425,11 +1447,12 @@ static int connect(struct socket *sock, struct sockaddr *dest, int destlen, /* Wait until an 'ACK' or 'RST' arrives, or a timeout occurs */ + timeout = tipc_sk(sk)->conn_timeout; release_sock(sk); res = wait_event_interruptible_timeout(*sk_sleep(sk), (!skb_queue_empty(&sk->sk_receive_queue) || (sock->state != SS_CONNECTING)), - sk->sk_rcvtimeo); + timeout ? timeout : MAX_SCHEDULE_TIMEOUT); lock_sock(sk); if (res > 0) { @@ -1692,7 +1715,7 @@ static int setsockopt(struct socket *sock, res = tipc_set_portunreturnable(tport->ref, value); break; case TIPC_CONN_TIMEOUT: - sk->sk_rcvtimeo = msecs_to_jiffies(value); + tipc_sk(sk)->conn_timeout = msecs_to_jiffies(value); /* no need to set "res", since already 0 at this point */ break; default: @@ -1747,7 +1770,7 @@ static int getsockopt(struct socket *sock, res = tipc_portunreturnable(tport->ref, &value); break; case TIPC_CONN_TIMEOUT: - value = jiffies_to_msecs(sk->sk_rcvtimeo); + value = jiffies_to_msecs(tipc_sk(sk)->conn_timeout); /* no need to set "res", since already 0 at this point */ break; case TIPC_NODE_RECVQ_DEPTH: diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index ab6eab4c45e2b0ecbbc460ddbed0045d48792f1c..33313961d01008548175a6d25e4b54592fed21a2 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -75,6 +75,19 @@ struct top_srv { static struct top_srv topsrv = { 0 }; +/** + * htohl - convert value to endianness used by destination + * @in: value to convert + * @swap: non-zero if endianness must be reversed + * + * Returns converted value + */ + +static u32 htohl(u32 in, int swap) +{ + return swap ? swab32(in) : in; +} + /** * subscr_send_event - send a message containing a tipc_event to the subscriber * @@ -94,11 +107,11 @@ static void subscr_send_event(struct subscription *sub, msg_sect.iov_base = (void *)&sub->evt; msg_sect.iov_len = sizeof(struct tipc_event); - sub->evt.event = htonl(event); - sub->evt.found_lower = htonl(found_lower); - sub->evt.found_upper = htonl(found_upper); - sub->evt.port.ref = htonl(port_ref); - sub->evt.port.node = htonl(node); + sub->evt.event = htohl(event, sub->swap); + sub->evt.found_lower = htohl(found_lower, sub->swap); + sub->evt.found_upper = htohl(found_upper, sub->swap); + sub->evt.port.ref = htohl(port_ref, sub->swap); + sub->evt.port.node = htohl(node, sub->swap); tipc_send(sub->server_ref, 1, &msg_sect); } @@ -274,29 +287,16 @@ static void subscr_cancel(struct tipc_subscr *s, { struct subscription *sub; struct subscription *sub_temp; - __u32 type, lower, upper, timeout, filter; int found = 0; /* Find first matching subscription, exit if not found */ - type = ntohl(s->seq.type); - lower = ntohl(s->seq.lower); - upper = ntohl(s->seq.upper); - timeout = ntohl(s->timeout); - filter = ntohl(s->filter) & ~TIPC_SUB_CANCEL; - list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, subscription_list) { - if ((type == sub->seq.type) && - (lower == sub->seq.lower) && - (upper == sub->seq.upper) && - (timeout == sub->timeout) && - (filter == sub->filter) && - !memcmp(s->usr_handle,sub->evt.s.usr_handle, - sizeof(s->usr_handle)) ){ - found = 1; - break; - } + if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { + found = 1; + break; + } } if (!found) return; @@ -310,7 +310,7 @@ static void subscr_cancel(struct tipc_subscr *s, k_term_timer(&sub->timer); spin_lock_bh(subscriber->lock); } - dbg("Cancel: removing sub %u,%u,%u from subscriber %p list\n", + dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n", sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); subscr_del(sub); } @@ -325,10 +325,16 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, struct subscriber *subscriber) { struct subscription *sub; + int swap; + + /* Determine subscriber's endianness */ + + swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)); /* Detect & process a subscription cancellation request */ - if (ntohl(s->filter) & TIPC_SUB_CANCEL) { + if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { + s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); subscr_cancel(s, subscriber); return NULL; } @@ -353,12 +359,13 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, /* Initialize subscription object */ - sub->seq.type = ntohl(s->seq.type); - sub->seq.lower = ntohl(s->seq.lower); - sub->seq.upper = ntohl(s->seq.upper); - sub->timeout = ntohl(s->timeout); - sub->filter = ntohl(s->filter); - if ((sub->filter && (sub->filter != TIPC_SUB_PORTS)) || + sub->seq.type = htohl(s->seq.type, swap); + sub->seq.lower = htohl(s->seq.lower, swap); + sub->seq.upper = htohl(s->seq.upper, swap); + sub->timeout = htohl(s->timeout, swap); + sub->filter = htohl(s->filter, swap); + if ((!(sub->filter & TIPC_SUB_PORTS) == + !(sub->filter & TIPC_SUB_SERVICE)) || (sub->seq.lower > sub->seq.upper)) { warn("Subscription rejected, illegal request\n"); kfree(sub); @@ -369,6 +376,7 @@ static struct subscription *subscr_subscribe(struct tipc_subscr *s, INIT_LIST_HEAD(&sub->nameseq_list); list_add(&sub->subscription_list, &subscriber->subscription_list); sub->server_ref = subscriber->port_ref; + sub->swap = swap; memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); atomic_inc(&topsrv.subscription_count); if (sub->timeout != TIPC_WAIT_FOREVER) { @@ -598,12 +606,3 @@ void tipc_subscr_stop(void) topsrv.user_ref = 0; } } - - -int tipc_ispublished(struct tipc_name const *name) -{ - u32 domain = 0; - - return(tipc_nametbl_translate(name->type, name->instance,&domain) != 0); -} - diff --git a/net/tipc/subscr.h b/net/tipc/subscr.h index c20f496d95b251e84f96d96f4ed2bb9fff531acb..45d89bf4d202b6217b565a5c8e7730a5f6bebcfd 100644 --- a/net/tipc/subscr.h +++ b/net/tipc/subscr.h @@ -53,6 +53,7 @@ typedef void (*tipc_subscr_event) (struct subscription *sub, * @nameseq_list: adjacent subscriptions in name sequence's subscription list * @subscription_list: adjacent subscriptions in subscriber's subscription list * @server_ref: object reference of server port associated with subscription + * @swap: indicates if subscriber uses opposite endianness in its messages * @evt: template for events generated by subscription */ @@ -65,6 +66,7 @@ struct subscription { struct list_head nameseq_list; struct list_head subscription_list; u32 server_ref; + int swap; struct tipc_event evt; }; diff --git a/net/tipc/zone.c b/net/tipc/zone.c index 2c01ba2d86bf57f1667897b0993fe9ece6053534..83f8b5e91fc8e45e7f0181dc36f1d5a623e0ae4b 100644 --- a/net/tipc/zone.c +++ b/net/tipc/zone.c @@ -160,14 +160,3 @@ u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref) } return 0; } - - -u32 tipc_zone_next_node(u32 addr) -{ - struct cluster *c_ptr = tipc_cltr_find(addr); - - if (c_ptr) - return tipc_cltr_next_node(c_ptr, addr); - return 0; -} - diff --git a/net/tipc/zone.h b/net/tipc/zone.h index 7bdc3406ba9b0a1841f34c21411c72824e327fe0..bd1c20ce9d0656212d653a7bfab17dbf775a458c 100644 --- a/net/tipc/zone.h +++ b/net/tipc/zone.h @@ -61,7 +61,6 @@ void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest); struct _zone *tipc_zone_create(u32 addr); void tipc_zone_delete(struct _zone *z_ptr); void tipc_zone_attach_cluster(struct _zone *z_ptr, struct cluster *c_ptr); -u32 tipc_zone_next_node(u32 addr); static inline struct _zone *tipc_zone_find(u32 addr) { diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 0b39b2451ea59958c0819c51faf337d000cbb88d..0ebc777a66601e05d48cc8805e57cb957d9512d4 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1511,6 +1511,8 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, goto restart; } + if (sock_flag(other, SOCK_RCVTSTAMP)) + __net_timestamp(skb); skb_queue_tail(&other->sk_receive_queue, skb); unix_state_unlock(other); other->sk_data_ready(other, len); @@ -1722,6 +1724,9 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock, if (err) goto out_free; + if (sock_flag(sk, SOCK_RCVTSTAMP)) + __sock_recv_timestamp(msg, sk, skb); + if (!siocb->scm) { siocb->scm = &tmp_scm; memset(&tmp_scm, 0, sizeof(tmp_scm)); @@ -2033,11 +2038,10 @@ static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLRDHUP; + mask |= POLLRDHUP | POLLIN | POLLRDNORM; /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue) || - (sk->sk_shutdown & RCV_SHUTDOWN)) + if (!skb_queue_empty(&sk->sk_receive_queue)) mask |= POLLIN | POLLRDNORM; /* Connection-based need to check for termination and startup */ diff --git a/net/wireless/core.c b/net/wireless/core.c index d6d046b9f6f2d7d85f8a10680cf662519838e877..9c21ebf9780ea21ff22c9326da29a423061d088b 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -253,11 +253,16 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, WARN_ON(err); wdev->netdev->features |= NETIF_F_NETNS_LOCAL; } + + return err; } wiphy_net_set(&rdev->wiphy, net); - return err; + err = device_rename(&rdev->wiphy.dev, dev_name(&rdev->wiphy.dev)); + WARN_ON(err); + + return 0; } static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) @@ -428,7 +433,7 @@ int wiphy_register(struct wiphy *wiphy) /* sanity check ifmodes */ WARN_ON(!ifmodes); - ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1; + ifmodes &= ((1 << NUM_NL80211_IFTYPES) - 1) & ~1; if (WARN_ON(ifmodes != wiphy->interface_modes)) wiphy->interface_modes = ifmodes; @@ -683,8 +688,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work); INIT_LIST_HEAD(&wdev->event_list); spin_lock_init(&wdev->event_lock); - INIT_LIST_HEAD(&wdev->action_registrations); - spin_lock_init(&wdev->action_registrations_lock); + INIT_LIST_HEAD(&wdev->mgmt_registrations); + spin_lock_init(&wdev->mgmt_registrations_lock); mutex_lock(&rdev->devlist_mtx); list_add_rcu(&wdev->list, &rdev->netdev_list); @@ -724,6 +729,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, dev->ethtool_ops = &cfg80211_ethtool_ops; if ((wdev->iftype == NL80211_IFTYPE_STATION || + wdev->iftype == NL80211_IFTYPE_P2P_CLIENT || wdev->iftype == NL80211_IFTYPE_ADHOC) && !wdev->use_4addr) dev->priv_flags |= IFF_DONT_BRIDGE; break; @@ -732,6 +738,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, case NL80211_IFTYPE_ADHOC: cfg80211_leave_ibss(rdev, dev, true); break; + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: wdev_lock(wdev); #ifdef CONFIG_CFG80211_WEXT @@ -804,7 +811,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, sysfs_remove_link(&dev->dev.kobj, "phy80211"); list_del_rcu(&wdev->list); rdev->devlist_generation++; - cfg80211_mlme_purge_actions(wdev); + cfg80211_mlme_purge_registrations(wdev); #ifdef CONFIG_CFG80211_WEXT kfree(wdev->wext.keys); #endif @@ -910,52 +917,3 @@ static void __exit cfg80211_exit(void) destroy_workqueue(cfg80211_wq); } module_exit(cfg80211_exit); - -static int ___wiphy_printk(const char *level, const struct wiphy *wiphy, - struct va_format *vaf) -{ - if (!wiphy) - return printk("%s(NULL wiphy *): %pV", level, vaf); - - return printk("%s%s: %pV", level, wiphy_name(wiphy), vaf); -} - -int __wiphy_printk(const char *level, const struct wiphy *wiphy, - const char *fmt, ...) -{ - struct va_format vaf; - va_list args; - int r; - - va_start(args, fmt); - - vaf.fmt = fmt; - vaf.va = &args; - - r = ___wiphy_printk(level, wiphy, &vaf); - va_end(args); - - return r; -} -EXPORT_SYMBOL(__wiphy_printk); - -#define define_wiphy_printk_level(func, kern_level) \ -int func(const struct wiphy *wiphy, const char *fmt, ...) \ -{ \ - struct va_format vaf; \ - va_list args; \ - int r; \ - \ - va_start(args, fmt); \ - \ - vaf.fmt = fmt; \ - vaf.va = &args; \ - \ - r = ___wiphy_printk(kern_level, wiphy, &vaf); \ - va_end(args); \ - \ - return r; \ -} \ -EXPORT_SYMBOL(func); - -define_wiphy_printk_level(wiphy_debug, KERN_DEBUG); diff --git a/net/wireless/core.h b/net/wireless/core.h index 63d57ae399c3f9d73da4f2bf963867a6699af4c4..6583cca0e2ee52a8bec5403cb2a77d59e945d983 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h @@ -86,7 +86,7 @@ struct cfg80211_registered_device *wiphy_to_dev(struct wiphy *wiphy) static inline bool wiphy_idx_valid(int wiphy_idx) { - return (wiphy_idx >= 0); + return wiphy_idx >= 0; } @@ -95,7 +95,10 @@ extern struct mutex cfg80211_mutex; extern struct list_head cfg80211_rdev_list; extern int cfg80211_rdev_list_generation; -#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex)) +static inline void assert_cfg80211_lock(void) +{ + lockdep_assert_held(&cfg80211_mutex); +} /* * You can use this to mark a wiphy_idx as not having an associated wiphy. @@ -202,8 +205,8 @@ static inline void wdev_unlock(struct wireless_dev *wdev) mutex_unlock(&wdev->mtx); } -#define ASSERT_RDEV_LOCK(rdev) WARN_ON(!mutex_is_locked(&(rdev)->mtx)); -#define ASSERT_WDEV_LOCK(wdev) WARN_ON(!mutex_is_locked(&(wdev)->mtx)); +#define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) +#define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) enum cfg80211_event_type { EVENT_CONNECT_RESULT, @@ -331,16 +334,17 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, const u8 *resp_ie, size_t resp_ie_len, u16 status, bool wextev, struct cfg80211_bss *bss); -int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid, - const u8 *match_data, int match_len); -void cfg80211_mlme_unregister_actions(struct wireless_dev *wdev, u32 nlpid); -void cfg80211_mlme_purge_actions(struct wireless_dev *wdev); -int cfg80211_mlme_action(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, - const u8 *buf, size_t len, u64 *cookie); +int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, + u16 frame_type, const u8 *match_data, + int match_len); +void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); +void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); +int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie); /* SME */ int __cfg80211_connect(struct cfg80211_registered_device *rdev, @@ -371,7 +375,7 @@ bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); /* internal helpers */ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, struct key_params *params, int key_idx, - const u8 *mac_addr); + bool pairwise, const u8 *mac_addr); void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, size_t ie_len, u16 reason, bool from_ap); void cfg80211_sme_scan_done(struct net_device *dev); diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 27a8ce9343c3e6d7a3bfdd6f801a7e852504a9c3..f33fbb79437c3280b980447c9f36cd8c99436dc7 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -88,6 +88,25 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, if (wdev->ssid_len) return -EALREADY; + if (!params->basic_rates) { + /* + * If no rates were explicitly configured, + * use the mandatory rate set for 11b or + * 11a for maximum compatibility. + */ + struct ieee80211_supported_band *sband = + rdev->wiphy.bands[params->channel->band]; + int j; + u32 flag = params->channel->band == IEEE80211_BAND_5GHZ ? + IEEE80211_RATE_MANDATORY_A : + IEEE80211_RATE_MANDATORY_B; + + for (j = 0; j < sband->n_bitrates; j++) { + if (sband->bitrates[j].flags & flag) + params->basic_rates |= BIT(j); + } + } + if (WARN_ON(wdev->connect_keys)) kfree(wdev->connect_keys); wdev->connect_keys = connkeys; @@ -141,7 +160,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) - rdev->ops->del_key(wdev->wiphy, dev, i, NULL); + rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL); if (wdev->current_bss) { cfg80211_unhold_bss(wdev->current_bss); diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index d1a3fb99fdf2caaa83e5b476dd3166c18f436161..26838d903b9a962b2efb5f274cad5ef01c24c4fc 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -149,7 +149,7 @@ void __cfg80211_send_deauth(struct net_device *dev, struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; const u8 *bssid = mgmt->bssid; int i; - bool found = false; + bool found = false, was_current = false; ASSERT_WDEV_LOCK(wdev); @@ -159,6 +159,7 @@ void __cfg80211_send_deauth(struct net_device *dev, cfg80211_put_bss(&wdev->current_bss->pub); wdev->current_bss = NULL; found = true; + was_current = true; } else for (i = 0; i < MAX_AUTH_BSSES; i++) { if (wdev->auth_bsses[i] && memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { @@ -183,7 +184,7 @@ void __cfg80211_send_deauth(struct net_device *dev, nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL); - if (wdev->sme_state == CFG80211_SME_CONNECTED) { + if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) { u16 reason_code; bool from_ap; @@ -747,31 +748,53 @@ void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, } EXPORT_SYMBOL(cfg80211_new_sta); -struct cfg80211_action_registration { +struct cfg80211_mgmt_registration { struct list_head list; u32 nlpid; int match_len; + __le16 frame_type; + u8 match[]; }; -int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid, - const u8 *match_data, int match_len) +int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, + u16 frame_type, const u8 *match_data, + int match_len) { - struct cfg80211_action_registration *reg, *nreg; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + struct cfg80211_mgmt_registration *reg, *nreg; int err = 0; + u16 mgmt_type; + + if (!wdev->wiphy->mgmt_stypes) + return -EOPNOTSUPP; + + if ((frame_type & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT) + return -EINVAL; + + if (frame_type & ~(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) + return -EINVAL; + + mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4; + if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].rx & BIT(mgmt_type))) + return -EINVAL; nreg = kzalloc(sizeof(*reg) + match_len, GFP_KERNEL); if (!nreg) return -ENOMEM; - spin_lock_bh(&wdev->action_registrations_lock); + spin_lock_bh(&wdev->mgmt_registrations_lock); - list_for_each_entry(reg, &wdev->action_registrations, list) { + list_for_each_entry(reg, &wdev->mgmt_registrations, list) { int mlen = min(match_len, reg->match_len); + if (frame_type != le16_to_cpu(reg->frame_type)) + continue; + if (memcmp(reg->match, match_data, mlen) == 0) { err = -EALREADY; break; @@ -786,140 +809,212 @@ int cfg80211_mlme_register_action(struct wireless_dev *wdev, u32 snd_pid, memcpy(nreg->match, match_data, match_len); nreg->match_len = match_len; nreg->nlpid = snd_pid; - list_add(&nreg->list, &wdev->action_registrations); + nreg->frame_type = cpu_to_le16(frame_type); + list_add(&nreg->list, &wdev->mgmt_registrations); + + if (rdev->ops->mgmt_frame_register) + rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, + frame_type, true); out: - spin_unlock_bh(&wdev->action_registrations_lock); + spin_unlock_bh(&wdev->mgmt_registrations_lock); + return err; } -void cfg80211_mlme_unregister_actions(struct wireless_dev *wdev, u32 nlpid) +void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) { - struct cfg80211_action_registration *reg, *tmp; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + struct cfg80211_mgmt_registration *reg, *tmp; - spin_lock_bh(&wdev->action_registrations_lock); + spin_lock_bh(&wdev->mgmt_registrations_lock); - list_for_each_entry_safe(reg, tmp, &wdev->action_registrations, list) { - if (reg->nlpid == nlpid) { - list_del(®->list); - kfree(reg); + list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { + if (reg->nlpid != nlpid) + continue; + + if (rdev->ops->mgmt_frame_register) { + u16 frame_type = le16_to_cpu(reg->frame_type); + + rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, + frame_type, false); } + + list_del(®->list); + kfree(reg); } - spin_unlock_bh(&wdev->action_registrations_lock); + spin_unlock_bh(&wdev->mgmt_registrations_lock); } -void cfg80211_mlme_purge_actions(struct wireless_dev *wdev) +void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) { - struct cfg80211_action_registration *reg, *tmp; + struct cfg80211_mgmt_registration *reg, *tmp; - spin_lock_bh(&wdev->action_registrations_lock); + spin_lock_bh(&wdev->mgmt_registrations_lock); - list_for_each_entry_safe(reg, tmp, &wdev->action_registrations, list) { + list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { list_del(®->list); kfree(reg); } - spin_unlock_bh(&wdev->action_registrations_lock); + spin_unlock_bh(&wdev->mgmt_registrations_lock); } -int cfg80211_mlme_action(struct cfg80211_registered_device *rdev, - struct net_device *dev, - struct ieee80211_channel *chan, - enum nl80211_channel_type channel_type, - bool channel_type_valid, - const u8 *buf, size_t len, u64 *cookie) +int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, + struct net_device *dev, + struct ieee80211_channel *chan, + enum nl80211_channel_type channel_type, + bool channel_type_valid, + const u8 *buf, size_t len, u64 *cookie) { struct wireless_dev *wdev = dev->ieee80211_ptr; const struct ieee80211_mgmt *mgmt; + u16 stype; - if (rdev->ops->action == NULL) + if (!wdev->wiphy->mgmt_stypes) return -EOPNOTSUPP; + + if (!rdev->ops->mgmt_tx) + return -EOPNOTSUPP; + if (len < 24 + 1) return -EINVAL; mgmt = (const struct ieee80211_mgmt *) buf; - if (!ieee80211_is_action(mgmt->frame_control)) + + if (!ieee80211_is_mgmt(mgmt->frame_control)) return -EINVAL; - if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { - /* Verify that we are associated with the destination AP */ + + stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; + if (!(wdev->wiphy->mgmt_stypes[wdev->iftype].tx & BIT(stype >> 4))) + return -EINVAL; + + if (ieee80211_is_action(mgmt->frame_control) && + mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) { + int err = 0; + wdev_lock(wdev); - if (!wdev->current_bss || - memcmp(wdev->current_bss->pub.bssid, mgmt->bssid, - ETH_ALEN) != 0 || - (wdev->iftype == NL80211_IFTYPE_STATION && - memcmp(wdev->current_bss->pub.bssid, mgmt->da, - ETH_ALEN) != 0)) { - wdev_unlock(wdev); - return -ENOTCONN; - } + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + if (!wdev->current_bss) { + err = -ENOTCONN; + break; + } + + if (memcmp(wdev->current_bss->pub.bssid, + mgmt->bssid, ETH_ALEN)) { + err = -ENOTCONN; + break; + } + + /* + * check for IBSS DA must be done by driver as + * cfg80211 doesn't track the stations + */ + if (wdev->iftype == NL80211_IFTYPE_ADHOC) + break; + /* for station, check that DA is the AP */ + if (memcmp(wdev->current_bss->pub.bssid, + mgmt->da, ETH_ALEN)) { + err = -ENOTCONN; + break; + } + break; + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_AP_VLAN: + if (memcmp(mgmt->bssid, dev->dev_addr, ETH_ALEN)) + err = -EINVAL; + break; + default: + err = -EOPNOTSUPP; + break; + } wdev_unlock(wdev); + + if (err) + return err; } if (memcmp(mgmt->sa, dev->dev_addr, ETH_ALEN) != 0) return -EINVAL; /* Transmit the Action frame as requested by user space */ - return rdev->ops->action(&rdev->wiphy, dev, chan, channel_type, - channel_type_valid, buf, len, cookie); + return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, channel_type, + channel_type_valid, buf, len, cookie); } -bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf, - size_t len, gfp_t gfp) +bool cfg80211_rx_mgmt(struct net_device *dev, int freq, const u8 *buf, + size_t len, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); - struct cfg80211_action_registration *reg; - const u8 *action_data; - int action_data_len; + struct cfg80211_mgmt_registration *reg; + const struct ieee80211_txrx_stypes *stypes = + &wiphy->mgmt_stypes[wdev->iftype]; + struct ieee80211_mgmt *mgmt = (void *)buf; + const u8 *data; + int data_len; bool result = false; + __le16 ftype = mgmt->frame_control & + cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE); + u16 stype; - /* frame length - min size excluding category */ - action_data_len = len - (IEEE80211_MIN_ACTION_SIZE - 1); + stype = (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) >> 4; - /* action data starts with category */ - action_data = buf + IEEE80211_MIN_ACTION_SIZE - 1; + if (!(stypes->rx & BIT(stype))) + return false; - spin_lock_bh(&wdev->action_registrations_lock); + data = buf + ieee80211_hdrlen(mgmt->frame_control); + data_len = len - ieee80211_hdrlen(mgmt->frame_control); + + spin_lock_bh(&wdev->mgmt_registrations_lock); + + list_for_each_entry(reg, &wdev->mgmt_registrations, list) { + if (reg->frame_type != ftype) + continue; - list_for_each_entry(reg, &wdev->action_registrations, list) { - if (reg->match_len > action_data_len) + if (reg->match_len > data_len) continue; - if (memcmp(reg->match, action_data, reg->match_len)) + if (memcmp(reg->match, data, reg->match_len)) continue; /* found match! */ /* Indicate the received Action frame to user space */ - if (nl80211_send_action(rdev, dev, reg->nlpid, freq, - buf, len, gfp)) + if (nl80211_send_mgmt(rdev, dev, reg->nlpid, freq, + buf, len, gfp)) continue; result = true; break; } - spin_unlock_bh(&wdev->action_registrations_lock); + spin_unlock_bh(&wdev->mgmt_registrations_lock); return result; } -EXPORT_SYMBOL(cfg80211_rx_action); +EXPORT_SYMBOL(cfg80211_rx_mgmt); -void cfg80211_action_tx_status(struct net_device *dev, u64 cookie, - const u8 *buf, size_t len, bool ack, gfp_t gfp) +void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie, + const u8 *buf, size_t len, bool ack, gfp_t gfp) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct wiphy *wiphy = wdev->wiphy; struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); /* Indicate TX status of the Action frame to user space */ - nl80211_send_action_tx_status(rdev, dev, cookie, buf, len, ack, gfp); + nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp); } -EXPORT_SYMBOL(cfg80211_action_tx_status); +EXPORT_SYMBOL(cfg80211_mgmt_tx_status); void cfg80211_cqm_rssi_notify(struct net_device *dev, enum nl80211_cqm_rssi_threshold_event rssi_event, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 37902a54e9c154fb8dbed3e1d996d8a198bdc17b..c506241f863706426e76d66736d0258eda34d769 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -23,6 +23,11 @@ #include "nl80211.h" #include "reg.h" +static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); +static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info); + /* the netlink family */ static struct genl_family nl80211_fam = { .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ @@ -31,6 +36,8 @@ static struct genl_family nl80211_fam = { .version = 1, /* no particular meaning now */ .maxattr = NL80211_ATTR_MAX, .netnsok = true, + .pre_doit = nl80211_pre_doit, + .post_doit = nl80211_post_doit, }; /* internal helper: get rdev and dev */ @@ -86,6 +93,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, + [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, @@ -136,6 +144,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { .len = sizeof(struct nl80211_sta_flag_update), }, [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG }, + [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 }, + [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG }, [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, @@ -156,9 +166,10 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 }, [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 }, + [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, }; -/* policy for the attributes */ +/* policy for the key attributes */ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, [NL80211_KEY_IDX] = { .type = NLA_U8 }, @@ -166,6 +177,7 @@ static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 }, [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, + [NL80211_KEY_TYPE] = { .type = NLA_U32 }, }; /* ifidx get helper */ @@ -188,6 +200,47 @@ static int nl80211_get_ifidx(struct netlink_callback *cb) return res; } +static int nl80211_prepare_netdev_dump(struct sk_buff *skb, + struct netlink_callback *cb, + struct cfg80211_registered_device **rdev, + struct net_device **dev) +{ + int ifidx = cb->args[0]; + int err; + + if (!ifidx) + ifidx = nl80211_get_ifidx(cb); + if (ifidx < 0) + return ifidx; + + cb->args[0] = ifidx; + + rtnl_lock(); + + *dev = __dev_get_by_index(sock_net(skb->sk), ifidx); + if (!*dev) { + err = -ENODEV; + goto out_rtnl; + } + + *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); + if (IS_ERR(dev)) { + err = PTR_ERR(dev); + goto out_rtnl; + } + + return 0; + out_rtnl: + rtnl_unlock(); + return err; +} + +static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev) +{ + cfg80211_unlock_rdev(rdev); + rtnl_unlock(); +} + /* IE validation */ static bool is_valid_ie_attr(const struct nlattr *attr) { @@ -255,6 +308,7 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct key_parse { struct key_params p; int idx; + int type; bool def, defmgmt; }; @@ -285,6 +339,12 @@ static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) if (tb[NL80211_KEY_CIPHER]) k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]); + if (tb[NL80211_KEY_TYPE]) { + k->type = nla_get_u32(tb[NL80211_KEY_TYPE]); + if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) + return -EINVAL; + } + return 0; } @@ -309,6 +369,12 @@ static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k) k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; + if (info->attrs[NL80211_ATTR_KEY_TYPE]) { + k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); + if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) + return -EINVAL; + } + return 0; } @@ -318,6 +384,7 @@ static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) memset(k, 0, sizeof(*k)); k->idx = -1; + k->type = -1; if (info->attrs[NL80211_ATTR_KEY]) err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k); @@ -382,7 +449,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, } else if (parse.defmgmt) goto error; err = cfg80211_validate_key_settings(rdev, &parse.p, - parse.idx, NULL); + parse.idx, false, NULL); if (err) goto error; result->params[parse.idx].cipher = parse.p.cipher; @@ -401,18 +468,17 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) { ASSERT_WDEV_LOCK(wdev); - if (!netif_running(wdev->netdev)) - return -ENETDOWN; - switch (wdev->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: break; case NL80211_IFTYPE_ADHOC: if (!wdev->current_bss) return -ENOLINK; break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: if (wdev->sme_state != CFG80211_SME_CONNECTED) return -ENOLINK; break; @@ -437,6 +503,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, struct ieee80211_rate *rate; int i; u16 ifmodes = dev->wiphy.interface_modes; + const struct ieee80211_txrx_stypes *mgmt_stypes = + dev->wiphy.mgmt_stypes; hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); if (!hdr) @@ -464,6 +532,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, dev->wiphy.max_scan_ie_len); + if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) + NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); + NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, sizeof(u32) * dev->wiphy.n_cipher_suites, dev->wiphy.cipher_suites); @@ -471,6 +542,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, dev->wiphy.max_num_pmkids); + if (dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) + NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE); + nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES); if (!nl_modes) goto nla_put_failure; @@ -587,12 +661,13 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, CMD(flush_pmksa, FLUSH_PMKSA); CMD(remain_on_channel, REMAIN_ON_CHANNEL); CMD(set_bitrate_mask, SET_TX_BITRATE_MASK); - CMD(action, ACTION); + CMD(mgmt_tx, FRAME); if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { i++; NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); } CMD(set_channel, SET_CHANNEL); + CMD(set_wds_peer, SET_WDS_PEER); #undef CMD @@ -608,6 +683,55 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_cmds); + if (mgmt_stypes) { + u16 stypes; + struct nlattr *nl_ftypes, *nl_ifs; + enum nl80211_iftype ift; + + nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES); + if (!nl_ifs) + goto nla_put_failure; + + for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { + nl_ftypes = nla_nest_start(msg, ift); + if (!nl_ftypes) + goto nla_put_failure; + i = 0; + stypes = mgmt_stypes[ift].tx; + while (stypes) { + if (stypes & 1) + NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, + (i << 4) | IEEE80211_FTYPE_MGMT); + stypes >>= 1; + i++; + } + nla_nest_end(msg, nl_ftypes); + } + + nla_nest_end(msg, nl_ifs); + + nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES); + if (!nl_ifs) + goto nla_put_failure; + + for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { + nl_ftypes = nla_nest_start(msg, ift); + if (!nl_ftypes) + goto nla_put_failure; + i = 0; + stypes = mgmt_stypes[ift].rx; + while (stypes) { + if (stypes & 1) + NLA_PUT_U16(msg, NL80211_ATTR_FRAME_TYPE, + (i << 4) | IEEE80211_FTYPE_MGMT); + stypes >>= 1; + i++; + } + nla_nest_end(msg, nl_ftypes); + } + nla_nest_end(msg, nl_ifs); + } + return genlmsg_end(msg, hdr); nla_put_failure: @@ -644,28 +768,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; - struct cfg80211_registered_device *dev; - - dev = cfg80211_get_dev_from_info(info); - if (IS_ERR(dev)) - return PTR_ERR(dev); + struct cfg80211_registered_device *dev = info->user_ptr[0]; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - goto out_err; - - if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) - goto out_free; + return -ENOMEM; - cfg80211_unlock_rdev(dev); + if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } return genlmsg_reply(msg, info); - - out_free: - nlmsg_free(msg); - out_err: - cfg80211_unlock_rdev(dev); - return -ENOBUFS; } static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = { @@ -709,7 +823,8 @@ static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) wdev->iftype == NL80211_IFTYPE_AP || wdev->iftype == NL80211_IFTYPE_WDS || wdev->iftype == NL80211_IFTYPE_MESH_POINT || - wdev->iftype == NL80211_IFTYPE_MONITOR; + wdev->iftype == NL80211_IFTYPE_MONITOR || + wdev->iftype == NL80211_IFTYPE_P2P_GO; } static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, @@ -753,38 +868,48 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *netdev; - int result; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *netdev = info->user_ptr[1]; - rtnl_lock(); + return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); +} - result = get_rdev_dev_by_info_ifindex(info, &rdev, &netdev); - if (result) - goto unlock; +static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) +{ + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + const u8 *bssid; - result = __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); + if (!info->attrs[NL80211_ATTR_MAC]) + return -EINVAL; - unlock: - rtnl_unlock(); + if (netif_running(dev)) + return -EBUSY; - return result; + if (!rdev->ops->set_wds_peer) + return -EOPNOTSUPP; + + if (wdev->iftype != NL80211_IFTYPE_WDS) + return -EOPNOTSUPP; + + bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); + return rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid); } + static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev; struct net_device *netdev = NULL; struct wireless_dev *wdev; - int result, rem_txq_params = 0; + int result = 0, rem_txq_params = 0; struct nlattr *nl_txq_params; u32 changed; u8 retry_short = 0, retry_long = 0; u32 frag_threshold = 0, rts_threshold = 0; u8 coverage_class = 0; - rtnl_lock(); - /* * Try to find the wiphy and netdev. Normally this * function shouldn't need the netdev, but this is @@ -811,8 +936,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) rdev = __cfg80211_rdev_from_info(info); if (IS_ERR(rdev)) { mutex_unlock(&cfg80211_mutex); - result = PTR_ERR(rdev); - goto unlock; + return PTR_ERR(rdev); } wdev = NULL; netdev = NULL; @@ -994,8 +1118,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) mutex_unlock(&rdev->mtx); if (netdev) dev_put(netdev); - unlock: - rtnl_unlock(); return result; } @@ -1075,33 +1197,20 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; - struct cfg80211_registered_device *dev; - struct net_device *netdev; - int err; - - err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev); - if (err) - return err; + struct cfg80211_registered_device *dev = info->user_ptr[0]; + struct net_device *netdev = info->user_ptr[1]; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - goto out_err; + return -ENOMEM; if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, - dev, netdev) < 0) - goto out_free; - - dev_put(netdev); - cfg80211_unlock_rdev(dev); + dev, netdev) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } return genlmsg_reply(msg, info); - - out_free: - nlmsg_free(msg); - out_err: - dev_put(netdev); - cfg80211_unlock_rdev(dev); - return -ENOBUFS; } static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { @@ -1161,39 +1270,29 @@ static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev, static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct vif_params params; int err; enum nl80211_iftype otype, ntype; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; u32 _flags, *flags = NULL; bool change = false; memset(¶ms, 0, sizeof(params)); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - otype = ntype = dev->ieee80211_ptr->iftype; if (info->attrs[NL80211_ATTR_IFTYPE]) { ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); if (otype != ntype) change = true; - if (ntype > NL80211_IFTYPE_MAX) { - err = -EINVAL; - goto unlock; - } + if (ntype > NL80211_IFTYPE_MAX) + return -EINVAL; } if (info->attrs[NL80211_ATTR_MESH_ID]) { - if (ntype != NL80211_IFTYPE_MESH_POINT) { - err = -EINVAL; - goto unlock; - } + if (ntype != NL80211_IFTYPE_MESH_POINT) + return -EINVAL; params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); change = true; @@ -1204,20 +1303,18 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) change = true; err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype); if (err) - goto unlock; + return err; } else { params.use_4addr = -1; } if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { - if (ntype != NL80211_IFTYPE_MONITOR) { - err = -EINVAL; - goto unlock; - } + if (ntype != NL80211_IFTYPE_MONITOR) + return -EINVAL; err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS], &_flags); if (err) - goto unlock; + return err; flags = &_flags; change = true; @@ -1231,17 +1328,12 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) if (!err && params.use_4addr != -1) dev->ieee80211_ptr->use_4addr = params.use_4addr; - unlock: - dev_put(dev); - cfg80211_unlock_rdev(rdev); - unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct vif_params params; int err; enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; @@ -1258,19 +1350,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } - rtnl_lock(); - - rdev = cfg80211_get_dev_from_info(info); - if (IS_ERR(rdev)) { - err = PTR_ERR(rdev); - goto unlock_rtnl; - } - if (!rdev->ops->add_virtual_intf || - !(rdev->wiphy.interface_modes & (1 << type))) { - err = -EOPNOTSUPP; - goto unlock; - } + !(rdev->wiphy.interface_modes & (1 << type))) + return -EOPNOTSUPP; if (type == NL80211_IFTYPE_MESH_POINT && info->attrs[NL80211_ATTR_MESH_ID]) { @@ -1282,7 +1364,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); if (err) - goto unlock; + return err; } err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? @@ -1292,38 +1374,18 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) nla_data(info->attrs[NL80211_ATTR_IFNAME]), type, err ? NULL : &flags, ¶ms); - unlock: - cfg80211_unlock_rdev(rdev); - unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->del_virtual_intf) { - err = -EOPNOTSUPP; - goto out; - } + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; - err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev); + if (!rdev->ops->del_virtual_intf) + return -EOPNOTSUPP; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; + return rdev->ops->del_virtual_intf(&rdev->wiphy, dev); } struct get_key_cookie { @@ -1376,11 +1438,12 @@ static void get_key_callback(void *c, struct key_params *params) static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; u8 key_idx = 0; - u8 *mac_addr = NULL; + const u8 *mac_addr = NULL; + bool pairwise; struct get_key_cookie cookie = { .error = 0, }; @@ -1396,30 +1459,28 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->get_key) { - err = -EOPNOTSUPP; - goto out; + pairwise = !!mac_addr; + if (info->attrs[NL80211_ATTR_KEY_TYPE]) { + u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); + if (kt >= NUM_NL80211_KEYTYPES) + return -EINVAL; + if (kt != NL80211_KEYTYPE_GROUP && + kt != NL80211_KEYTYPE_PAIRWISE) + return -EINVAL; + pairwise = kt == NL80211_KEYTYPE_PAIRWISE; } + if (!rdev->ops->get_key) + return -EOPNOTSUPP; + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOMEM; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_NEW_KEY); - - if (IS_ERR(hdr)) { - err = PTR_ERR(hdr); - goto free_msg; - } + if (IS_ERR(hdr)) + return PTR_ERR(hdr); cookie.msg = msg; cookie.idx = key_idx; @@ -1429,8 +1490,12 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) if (mac_addr) NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); - err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, mac_addr, - &cookie, get_key_callback); + if (pairwise && mac_addr && + !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + return -ENOENT; + + err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise, + mac_addr, &cookie, get_key_callback); if (err) goto free_msg; @@ -1439,28 +1504,21 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) goto nla_put_failure; genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + return genlmsg_reply(msg, info); nla_put_failure: err = -ENOBUFS; free_msg: nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; } static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct key_parse key; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; int (*func)(struct wiphy *wiphy, struct net_device *netdev, u8 key_index); @@ -1475,21 +1533,13 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) if (!key.def && !key.defmgmt) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - if (key.def) func = rdev->ops->set_default_key; else func = rdev->ops->set_default_mgmt_key; - if (!func) { - err = -EOPNOTSUPP; - goto out; - } + if (!func) + return -EOPNOTSUPP; wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); @@ -1506,23 +1556,16 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) #endif wdev_unlock(dev->ieee80211_ptr); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - - unlock_rtnl: - rtnl_unlock(); - return err; } static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct key_parse key; - u8 *mac_addr = NULL; + const u8 *mac_addr = NULL; err = nl80211_parse_key(info, &key); if (err) @@ -1534,43 +1577,42 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); + if (key.type == -1) { + if (mac_addr) + key.type = NL80211_KEYTYPE_PAIRWISE; + else + key.type = NL80211_KEYTYPE_GROUP; + } - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; + /* for now */ + if (key.type != NL80211_KEYTYPE_PAIRWISE && + key.type != NL80211_KEYTYPE_GROUP) + return -EINVAL; - if (!rdev->ops->add_key) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->add_key) + return -EOPNOTSUPP; - if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) { - err = -EINVAL; - goto out; - } + if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, + key.type == NL80211_KEYTYPE_PAIRWISE, + mac_addr)) + return -EINVAL; wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); if (!err) err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx, + key.type == NL80211_KEYTYPE_PAIRWISE, mac_addr, &key.p); wdev_unlock(dev->ieee80211_ptr); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; } static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; u8 *mac_addr = NULL; struct key_parse key; @@ -1581,21 +1623,32 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); + if (key.type == -1) { + if (mac_addr) + key.type = NL80211_KEYTYPE_PAIRWISE; + else + key.type = NL80211_KEYTYPE_GROUP; + } - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; + /* for now */ + if (key.type != NL80211_KEYTYPE_PAIRWISE && + key.type != NL80211_KEYTYPE_GROUP) + return -EINVAL; - if (!rdev->ops->del_key) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->del_key) + return -EOPNOTSUPP; wdev_lock(dev->ieee80211_ptr); err = nl80211_key_allowed(dev->ieee80211_ptr); + + if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr && + !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + err = -ENOENT; + if (!err) - err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, mac_addr); + err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, + key.type == NL80211_KEYTYPE_PAIRWISE, + mac_addr); #ifdef CONFIG_CFG80211_WEXT if (!err) { @@ -1607,13 +1660,6 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) #endif wdev_unlock(dev->ieee80211_ptr); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - - unlock_rtnl: - rtnl_unlock(); - return err; } @@ -1621,35 +1667,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) { int (*call)(struct wiphy *wiphy, struct net_device *dev, struct beacon_parameters *info); - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct beacon_parameters params; int haveinfo = 0; if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { - err = -EOPNOTSUPP; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; switch (info->genlhdr->cmd) { case NL80211_CMD_NEW_BEACON: /* these are required for NEW_BEACON */ if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || !info->attrs[NL80211_ATTR_DTIM_PERIOD] || - !info->attrs[NL80211_ATTR_BEACON_HEAD]) { - err = -EINVAL; - goto out; - } + !info->attrs[NL80211_ATTR_BEACON_HEAD]) + return -EINVAL; call = rdev->ops->add_beacon; break; @@ -1658,14 +1694,11 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) break; default: WARN_ON(1); - err = -EOPNOTSUPP; - goto out; + return -EOPNOTSUPP; } - if (!call) { - err = -EOPNOTSUPP; - goto out; - } + if (!call) + return -EOPNOTSUPP; memset(¶ms, 0, sizeof(params)); @@ -1695,52 +1728,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info) haveinfo = 1; } - if (!haveinfo) { - err = -EINVAL; - goto out; - } - - err = call(&rdev->wiphy, dev, ¶ms); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); + if (!haveinfo) + return -EINVAL; - return err; + return call(&rdev->wiphy, dev, ¶ms); } static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; - if (!rdev->ops->del_beacon) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { - err = -EOPNOTSUPP; - goto out; - } - err = rdev->ops->del_beacon(&rdev->wiphy, dev); + if (!rdev->ops->del_beacon) + return -EOPNOTSUPP; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; - return err; + return rdev->ops->del_beacon(&rdev->wiphy, dev); } static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { @@ -1861,6 +1867,12 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq, if (sinfo->filled & STATION_INFO_TX_PACKETS) NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS, sinfo->tx_packets); + if (sinfo->filled & STATION_INFO_TX_RETRIES) + NLA_PUT_U32(msg, NL80211_STA_INFO_TX_RETRIES, + sinfo->tx_retries); + if (sinfo->filled & STATION_INFO_TX_FAILED) + NLA_PUT_U32(msg, NL80211_STA_INFO_TX_FAILED, + sinfo->tx_failed); nla_nest_end(msg, sinfoattr); return genlmsg_end(msg, hdr); @@ -1877,28 +1889,12 @@ static int nl80211_dump_station(struct sk_buff *skb, struct cfg80211_registered_device *dev; struct net_device *netdev; u8 mac_addr[ETH_ALEN]; - int ifidx = cb->args[0]; int sta_idx = cb->args[1]; int err; - if (!ifidx) - ifidx = nl80211_get_ifidx(cb); - if (ifidx < 0) - return ifidx; - - rtnl_lock(); - - netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); - if (!netdev) { - err = -ENODEV; - goto out_rtnl; - } - - dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(dev)) { - err = PTR_ERR(dev); - goto out_rtnl; - } + err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); + if (err) + return err; if (!dev->ops->dump_station) { err = -EOPNOTSUPP; @@ -1928,21 +1924,19 @@ static int nl80211_dump_station(struct sk_buff *skb, cb->args[1] = sta_idx; err = skb->len; out_err: - cfg80211_unlock_rdev(dev); - out_rtnl: - rtnl_unlock(); + nl80211_finish_netdev_dump(dev); return err; } static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct station_info sinfo; struct sk_buff *msg; u8 *mac_addr = NULL; + int err; memset(&sinfo, 0, sizeof(sinfo)); @@ -1951,41 +1945,24 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->get_station) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->get_station) + return -EOPNOTSUPP; err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo); if (err) - goto out; + return err; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - goto out; + return -ENOMEM; if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0, - dev, mac_addr, &sinfo) < 0) - goto out_free; - - err = genlmsg_reply(msg, info); - goto out; - - out_free: - nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + dev, mac_addr, &sinfo) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } - return err; + return genlmsg_reply(msg, info); } /* @@ -2015,9 +1992,9 @@ static int get_vlan(struct genl_info *info, static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct station_parameters params; u8 *mac_addr = NULL; @@ -2055,12 +2032,6 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) params.plink_action = nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - err = get_vlan(info, rdev, ¶ms.vlan); if (err) goto out; @@ -2071,10 +2042,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) switch (dev->ieee80211_ptr->iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: /* disallow mesh-specific things */ if (params.plink_action) err = -EINVAL; break; + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: /* disallow everything but AUTHORIZED flag */ if (params.plink_action) @@ -2120,19 +2093,15 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) out: if (params.vlan) dev_put(params.vlan); - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); return err; } static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct station_parameters params; u8 *mac_addr = NULL; @@ -2169,17 +2138,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) if (parse_station_flags(info, ¶ms)) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { - err = -EINVAL; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EINVAL; err = get_vlan(info, rdev, ¶ms.vlan); if (err) @@ -2193,61 +2155,33 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) goto out; } - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } - err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, ¶ms); out: if (params.vlan) dev_put(params.vlan); - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); - return err; } static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u8 *mac_addr = NULL; if (info->attrs[NL80211_ATTR_MAC]) mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { - err = -EINVAL; - goto out; - } - - if (!rdev->ops->del_station) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->del_station(&rdev->wiphy, dev, mac_addr); + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EINVAL; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (!rdev->ops->del_station) + return -EOPNOTSUPP; - return err; + return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr); } static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq, @@ -2310,28 +2244,12 @@ static int nl80211_dump_mpath(struct sk_buff *skb, struct net_device *netdev; u8 dst[ETH_ALEN]; u8 next_hop[ETH_ALEN]; - int ifidx = cb->args[0]; int path_idx = cb->args[1]; int err; - if (!ifidx) - ifidx = nl80211_get_ifidx(cb); - if (ifidx < 0) - return ifidx; - - rtnl_lock(); - - netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); - if (!netdev) { - err = -ENODEV; - goto out_rtnl; - } - - dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(dev)) { - err = PTR_ERR(dev); - goto out_rtnl; - } + err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); + if (err) + return err; if (!dev->ops->dump_mpath) { err = -EOPNOTSUPP; @@ -2365,18 +2283,15 @@ static int nl80211_dump_mpath(struct sk_buff *skb, cb->args[1] = path_idx; err = skb->len; out_err: - cfg80211_unlock_rdev(dev); - out_rtnl: - rtnl_unlock(); - + nl80211_finish_netdev_dump(dev); return err; } static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct mpath_info pinfo; struct sk_buff *msg; u8 *dst = NULL; @@ -2389,53 +2304,33 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) dst = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->get_mpath) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->get_mpath) + return -EOPNOTSUPP; - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { - err = -EOPNOTSUPP; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo); if (err) - goto out; + return err; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) - goto out; + return -ENOMEM; if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0, - dev, dst, next_hop, &pinfo) < 0) - goto out_free; - - err = genlmsg_reply(msg, info); - goto out; - - out_free: - nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + dev, dst, next_hop, &pinfo) < 0) { + nlmsg_free(msg); + return -ENOBUFS; + } - return err; + return genlmsg_reply(msg, info); } static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u8 *dst = NULL; u8 *next_hop = NULL; @@ -2448,42 +2343,19 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) dst = nla_data(info->attrs[NL80211_ATTR_MAC]); next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->change_mpath) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } - - err = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); + if (!rdev->ops->change_mpath) + return -EOPNOTSUPP; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; - return err; + return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop); } + static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u8 *dst = NULL; u8 *next_hop = NULL; @@ -2496,75 +2368,34 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) dst = nla_data(info->attrs[NL80211_ATTR_MAC]); next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->add_mpath) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } - - err = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); + if (!rdev->ops->add_mpath) + return -EOPNOTSUPP; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) + return -EOPNOTSUPP; - return err; + return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop); } static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u8 *dst = NULL; if (info->attrs[NL80211_ATTR_MAC]) dst = nla_data(info->attrs[NL80211_ATTR_MAC]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->del_mpath) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->del_mpath(&rdev->wiphy, dev, dst); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (!rdev->ops->del_mpath) + return -EOPNOTSUPP; - return err; + return rdev->ops->del_mpath(&rdev->wiphy, dev, dst); } static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct bss_parameters params; memset(¶ms, 0, sizeof(params)); @@ -2592,31 +2423,14 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_AP_ISOLATE]) params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->change_bss) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->change_bss(&rdev->wiphy, dev, ¶ms); + if (!rdev->ops->change_bss) + return -EOPNOTSUPP; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; - return err; + return rdev->ops->change_bss(&rdev->wiphy, dev, ¶ms); } static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { @@ -2695,37 +2509,26 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) static int nl80211_get_mesh_params(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct mesh_config cur_params; int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; void *hdr; struct nlattr *pinfoattr; struct sk_buff *msg; - rtnl_lock(); - - /* Look up our device */ - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->get_mesh_params) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->get_mesh_params) + return -EOPNOTSUPP; /* Get the mesh params */ err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params); if (err) - goto out; + return err; /* Draw up a netlink message to send back */ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOBUFS; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_GET_MESH_PARAMS); if (!hdr) @@ -2764,21 +2567,12 @@ static int nl80211_get_mesh_params(struct sk_buff *skb, cur_params.dot11MeshHWMPRootMode); nla_nest_end(msg, pinfoattr); genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + return genlmsg_reply(msg, info); nla_put_failure: genlmsg_cancel(msg, hdr); nlmsg_free(msg); - err = -EMSGSIZE; - out: - /* Cleanup */ - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); - - return err; + return -ENOBUFS; } #define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \ @@ -2808,10 +2602,9 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) { - int err; u32 mask; - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct mesh_config cfg; struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; struct nlattr *parent_attr; @@ -2823,16 +2616,8 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) parent_attr, nl80211_meshconf_params_policy)) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (!rdev->ops->set_mesh_params) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->set_mesh_params) + return -EOPNOTSUPP; /* This makes sure that there aren't more than 32 mesh config * parameters (otherwise our bitfield scheme would not work.) */ @@ -2878,16 +2663,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info) nla_get_u8); /* Apply changes */ - err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); - - out: - /* cleanup */ - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); - - return err; + return rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask); } #undef FILL_IN_MESH_PARAM_IF_SET @@ -3070,8 +2846,8 @@ static int validate_scan_freqs(struct nlattr *freqs) static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_scan_request *request; struct cfg80211_ssid *ssid; struct ieee80211_channel *channel; @@ -3084,36 +2860,19 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - wiphy = &rdev->wiphy; - if (!rdev->ops->scan) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->scan) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } - - if (rdev->scan_req) { - err = -EBUSY; - goto out; - } + if (rdev->scan_req) + return -EBUSY; if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { n_channels = validate_scan_freqs( info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); - if (!n_channels) { - err = -EINVAL; - goto out; - } + if (!n_channels) + return -EINVAL; } else { n_channels = 0; @@ -3126,29 +2885,23 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) n_ssids++; - if (n_ssids > wiphy->max_scan_ssids) { - err = -EINVAL; - goto out; - } + if (n_ssids > wiphy->max_scan_ssids) + return -EINVAL; if (info->attrs[NL80211_ATTR_IE]) ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); else ie_len = 0; - if (ie_len > wiphy->max_scan_ie_len) { - err = -EINVAL; - goto out; - } + if (ie_len > wiphy->max_scan_ie_len) + return -EINVAL; request = kzalloc(sizeof(*request) + sizeof(*ssid) * n_ssids + sizeof(channel) * n_channels + ie_len, GFP_KERNEL); - if (!request) { - err = -ENOMEM; - goto out; - } + if (!request) + return -ENOMEM; if (n_ssids) request->ssids = (void *)&request->channels[n_channels]; @@ -3236,18 +2989,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) if (!err) { nl80211_send_scan_start(rdev, dev); dev_hold(dev); - } - + } else { out_free: - if (err) { rdev->scan_req = NULL; kfree(request); } - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); return err; } @@ -3306,6 +3052,7 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, } switch (wdev->iftype) { + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_STATION: if (intbss == wdev->current_bss) NLA_PUT_U32(msg, NL80211_BSS_STATUS, @@ -3343,25 +3090,12 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct net_device *dev; struct cfg80211_internal_bss *scan; struct wireless_dev *wdev; - int ifidx = cb->args[0]; int start = cb->args[1], idx = 0; int err; - if (!ifidx) - ifidx = nl80211_get_ifidx(cb); - if (ifidx < 0) - return ifidx; - cb->args[0] = ifidx; - - dev = dev_get_by_index(sock_net(skb->sk), ifidx); - if (!dev) - return -ENODEV; - - rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(rdev)) { - err = PTR_ERR(rdev); - goto out_put_netdev; - } + err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev); + if (err) + return err; wdev = dev->ieee80211_ptr; @@ -3377,21 +3111,17 @@ static int nl80211_dump_scan(struct sk_buff *skb, cb->nlh->nlmsg_seq, NLM_F_MULTI, rdev, wdev, scan) < 0) { idx--; - goto out; + break; } } - out: spin_unlock_bh(&rdev->bss_lock); wdev_unlock(wdev); cb->args[1] = idx; - err = skb->len; - cfg80211_unlock_rdev(rdev); - out_put_netdev: - dev_put(dev); + nl80211_finish_netdev_dump(rdev); - return err; + return skb->len; } static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, @@ -3421,6 +3151,23 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, if (survey->filled & SURVEY_INFO_NOISE_DBM) NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise); + if (survey->filled & SURVEY_INFO_IN_USE) + NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME, + survey->channel_time); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + survey->channel_time_busy); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + survey->channel_time_ext_busy); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + survey->channel_time_rx); + if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) + NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX, + survey->channel_time_tx); nla_nest_end(msg, infoattr); @@ -3437,29 +3184,12 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct survey_info survey; struct cfg80211_registered_device *dev; struct net_device *netdev; - int ifidx = cb->args[0]; int survey_idx = cb->args[1]; int res; - if (!ifidx) - ifidx = nl80211_get_ifidx(cb); - if (ifidx < 0) - return ifidx; - cb->args[0] = ifidx; - - rtnl_lock(); - - netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); - if (!netdev) { - res = -ENODEV; - goto out_rtnl; - } - - dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); - if (IS_ERR(dev)) { - res = PTR_ERR(dev); - goto out_rtnl; - } + res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); + if (res) + return res; if (!dev->ops->dump_survey) { res = -EOPNOTSUPP; @@ -3487,10 +3217,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, cb->args[1] = survey_idx; res = skb->len; out_err: - cfg80211_unlock_rdev(dev); - out_rtnl: - rtnl_unlock(); - + nl80211_finish_netdev_dump(dev); return res; } @@ -3523,8 +3250,8 @@ static bool nl80211_valid_cipher_suite(u32 cipher) static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct ieee80211_channel *chan; const u8 *bssid, *ssid, *ie = NULL; int err, ssid_len, ie_len = 0; @@ -3552,6 +3279,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) return err; if (key.idx >= 0) { + if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP) + return -EINVAL; if (!key.p.key || !key.p.key_len) return -EINVAL; if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 || @@ -3566,34 +3295,31 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) key.p.key = NULL; } - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->auth) { - err = -EOPNOTSUPP; - goto out; + if (key.idx >= 0) { + int i; + bool ok = false; + for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) { + if (key.p.cipher == rdev->wiphy.cipher_suites[i]) { + ok = true; + break; + } + } + if (!ok) + return -EINVAL; } - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->auth) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); chan = ieee80211_get_channel(&rdev->wiphy, nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); - if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { - err = -EINVAL; - goto out; - } + if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) + return -EINVAL; ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); @@ -3604,27 +3330,19 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) } auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); - if (!nl80211_valid_auth_type(auth_type)) { - err = -EINVAL; - goto out; - } + if (!nl80211_valid_auth_type(auth_type)) + return -EINVAL; local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; - err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, - ssid, ssid_len, ie, ie_len, - key.p.key, key.p.key_len, key.idx, - local_state_change); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, + ssid, ssid_len, ie, ie_len, + key.p.key, key.p.key_len, key.idx, + local_state_change); } -static int nl80211_crypto_settings(struct genl_info *info, +static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, + struct genl_info *info, struct cfg80211_crypto_settings *settings, int cipher_limit) { @@ -3632,6 +3350,19 @@ static int nl80211_crypto_settings(struct genl_info *info, settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT]; + if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) { + u16 proto; + proto = nla_get_u16( + info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]); + settings->control_port_ethertype = cpu_to_be16(proto); + if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && + proto != ETH_P_PAE) + return -EINVAL; + if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]) + settings->control_port_no_encrypt = true; + } else + settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE); + if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) { void *data; int len, i; @@ -3691,8 +3422,8 @@ static int nl80211_crypto_settings(struct genl_info *info, static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_crypto_settings crypto; struct ieee80211_channel *chan; const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; @@ -3707,35 +3438,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) !info->attrs[NL80211_ATTR_WIPHY_FREQ]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->assoc) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->assoc) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); chan = ieee80211_get_channel(&rdev->wiphy, nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); - if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) { - err = -EINVAL; - goto out; - } + if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) + return -EINVAL; ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); @@ -3750,35 +3465,28 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); if (mfp == NL80211_MFP_REQUIRED) use_mfp = true; - else if (mfp != NL80211_MFP_NO) { - err = -EINVAL; - goto out; - } + else if (mfp != NL80211_MFP_NO) + return -EINVAL; } if (info->attrs[NL80211_ATTR_PREV_BSSID]) prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); - err = nl80211_crypto_settings(info, &crypto, 1); + err = nl80211_crypto_settings(rdev, info, &crypto, 1); if (!err) err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, ssid, ssid_len, ie, ie_len, use_mfp, &crypto); -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; const u8 *ie = NULL, *bssid; - int err, ie_len = 0; + int ie_len = 0; u16 reason_code; bool local_state_change; @@ -3791,34 +3499,19 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL80211_ATTR_REASON_CODE]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->deauth) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->deauth) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); if (reason_code == 0) { /* Reason Code 0 is reserved */ - err = -EINVAL; - goto out; + return -EINVAL; } if (info->attrs[NL80211_ATTR_IE]) { @@ -3828,23 +3521,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; - err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, - local_state_change); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, + local_state_change); } static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; const u8 *ie = NULL, *bssid; - int err, ie_len = 0; + int ie_len = 0; u16 reason_code; bool local_state_change; @@ -3857,34 +3543,19 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL80211_ATTR_REASON_CODE]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->disassoc) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->disassoc) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); if (reason_code == 0) { /* Reason Code 0 is reserved */ - err = -EINVAL; - goto out; + return -EINVAL; } if (info->attrs[NL80211_ATTR_IE]) { @@ -3894,21 +3565,14 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; - err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, - local_state_change); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, + local_state_change); } static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_ibss_params ibss; struct wiphy *wiphy; struct cfg80211_cached_keys *connkeys = NULL; @@ -3933,26 +3597,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) return -EINVAL; } - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->join_ibss) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->join_ibss) + return -EOPNOTSUPP; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) + return -EOPNOTSUPP; wiphy = &rdev->wiphy; @@ -3970,24 +3619,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); if (!ibss.channel || ibss.channel->flags & IEEE80211_CHAN_NO_IBSS || - ibss.channel->flags & IEEE80211_CHAN_DISABLED) { - err = -EINVAL; - goto out; - } + ibss.channel->flags & IEEE80211_CHAN_DISABLED) + return -EINVAL; ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; - if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { - connkeys = nl80211_parse_connkeys(rdev, - info->attrs[NL80211_ATTR_KEYS]); - if (IS_ERR(connkeys)) { - err = PTR_ERR(connkeys); - connkeys = NULL; - goto out; - } - } - if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); @@ -3997,10 +3634,8 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) wiphy->bands[ibss.channel->band]; int i, j; - if (n_rates == 0) { - err = -EINVAL; - goto out; - } + if (n_rates == 0) + return -EINVAL; for (i = 0; i < n_rates; i++) { int rate = (rates[i] & 0x7f) * 5; @@ -4013,77 +3648,36 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) break; } } - if (!found) { - err = -EINVAL; - goto out; - } - } - } else { - /* - * If no rates were explicitly configured, - * use the mandatory rate set for 11b or - * 11a for maximum compatibility. - */ - struct ieee80211_supported_band *sband = - wiphy->bands[ibss.channel->band]; - int j; - u32 flag = ibss.channel->band == IEEE80211_BAND_5GHZ ? - IEEE80211_RATE_MANDATORY_A : - IEEE80211_RATE_MANDATORY_B; - - for (j = 0; j < sband->n_bitrates; j++) { - if (sband->bitrates[j].flags & flag) - ibss.basic_rates |= BIT(j); + if (!found) + return -EINVAL; } } - err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); + if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { + connkeys = nl80211_parse_connkeys(rdev, + info->attrs[NL80211_ATTR_KEYS]); + if (IS_ERR(connkeys)) + return PTR_ERR(connkeys); + } -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: + err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); if (err) kfree(connkeys); - rtnl_unlock(); return err; } static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; - int err; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->leave_ibss) { - err = -EOPNOTSUPP; - goto out; - } - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { - err = -EOPNOTSUPP; - goto out; - } + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!rdev->ops->leave_ibss) + return -EOPNOTSUPP; - err = cfg80211_leave_ibss(rdev, dev, false); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) + return -EOPNOTSUPP; -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_leave_ibss(rdev, dev, false); } #ifdef CONFIG_NL80211_TESTMODE @@ -4093,20 +3687,12 @@ static struct genl_multicast_group nl80211_testmode_mcgrp = { static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int err; if (!info->attrs[NL80211_ATTR_TESTDATA]) return -EINVAL; - rtnl_lock(); - - rdev = cfg80211_get_dev_from_info(info); - if (IS_ERR(rdev)) { - err = PTR_ERR(rdev); - goto unlock_rtnl; - } - err = -EOPNOTSUPP; if (rdev->ops->testmode_cmd) { rdev->testmode_info = info; @@ -4116,10 +3702,6 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) rdev->testmode_info = NULL; } - cfg80211_unlock_rdev(rdev); - - unlock_rtnl: - rtnl_unlock(); return err; } @@ -4210,8 +3792,8 @@ EXPORT_SYMBOL(cfg80211_testmode_event); static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_connect_params connect; struct wiphy *wiphy; struct cfg80211_cached_keys *connkeys = NULL; @@ -4236,25 +3818,14 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) connect.privacy = info->attrs[NL80211_ATTR_PRIVACY]; - err = nl80211_crypto_settings(info, &connect.crypto, + err = nl80211_crypto_settings(rdev, info, &connect.crypto, NL80211_MAX_NR_CIPHER_SUITES); if (err) return err; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto out; - } - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; wiphy = &rdev->wiphy; @@ -4273,39 +3844,27 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) ieee80211_get_channel(wiphy, nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); if (!connect.channel || - connect.channel->flags & IEEE80211_CHAN_DISABLED) { - err = -EINVAL; - goto out; - } + connect.channel->flags & IEEE80211_CHAN_DISABLED) + return -EINVAL; } if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { connkeys = nl80211_parse_connkeys(rdev, info->attrs[NL80211_ATTR_KEYS]); - if (IS_ERR(connkeys)) { - err = PTR_ERR(connkeys); - connkeys = NULL; - goto out; - } + if (IS_ERR(connkeys)) + return PTR_ERR(connkeys); } err = cfg80211_connect(rdev, dev, &connect, connkeys); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: if (err) kfree(connkeys); - rtnl_unlock(); return err; } static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; - int err; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u16 reason; if (!info->attrs[NL80211_ATTR_REASON_CODE]) @@ -4316,35 +3875,16 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) if (reason == 0) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } - - err = cfg80211_disconnect(rdev, dev, reason, true); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); - return err; + return cfg80211_disconnect(rdev, dev, reason, true); } static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net *net; int err; u32 pid; @@ -4354,43 +3894,26 @@ static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]); - rtnl_lock(); - - rdev = cfg80211_get_dev_from_info(info); - if (IS_ERR(rdev)) { - err = PTR_ERR(rdev); - goto out_rtnl; - } - net = get_net_ns_by_pid(pid); - if (IS_ERR(net)) { - err = PTR_ERR(net); - goto out; - } + if (IS_ERR(net)) + return PTR_ERR(net); err = 0; /* check if anything to do */ - if (net_eq(wiphy_net(&rdev->wiphy), net)) - goto out_put_net; + if (!net_eq(wiphy_net(&rdev->wiphy), net)) + err = cfg80211_switch_netns(rdev, net); - err = cfg80211_switch_netns(rdev, net); - out_put_net: put_net(net); - out: - cfg80211_unlock_rdev(rdev); - out_rtnl: - rtnl_unlock(); return err; } static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_pmksa *pmksa) = NULL; - int err; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct cfg80211_pmksa pmksa; memset(&pmksa, 0, sizeof(struct cfg80211_pmksa)); @@ -4401,19 +3924,12 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) if (!info->attrs[NL80211_ATTR_PMKID]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto out; - } + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; switch (info->genlhdr->cmd) { case NL80211_CMD_SET_PMKSA: @@ -4427,61 +3943,32 @@ static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) break; } - if (!rdev_ops) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev_ops(&rdev->wiphy, dev, &pmksa); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (!rdev_ops) + return -EOPNOTSUPP; - return err; + return rdev_ops(&rdev->wiphy, dev, &pmksa); } static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - int err; - struct net_device *dev; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto out_rtnl; - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto out; - } - - if (!rdev->ops->flush_pmksa) { - err = -EOPNOTSUPP; - goto out; - } - - err = rdev->ops->flush_pmksa(&rdev->wiphy, dev); + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - out_rtnl: - rtnl_unlock(); + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - return err; + if (!rdev->ops->flush_pmksa) + return -EOPNOTSUPP; + return rdev->ops->flush_pmksa(&rdev->wiphy, dev); } static int nl80211_remain_on_channel(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct ieee80211_channel *chan; struct sk_buff *msg; void *hdr; @@ -4503,21 +3990,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, if (!duration || !msecs_to_jiffies(duration) || duration > 5000) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->remain_on_channel) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!rdev->ops->remain_on_channel) + return -EOPNOTSUPP; if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { channel_type = nla_get_u32( @@ -4525,24 +3999,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, if (channel_type != NL80211_CHAN_NO_HT && channel_type != NL80211_CHAN_HT20 && channel_type != NL80211_CHAN_HT40PLUS && - channel_type != NL80211_CHAN_HT40MINUS) { - err = -EINVAL; - goto out; - } + channel_type != NL80211_CHAN_HT40MINUS) + return -EINVAL; } freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); chan = rdev_freq_to_chan(rdev, freq, channel_type); - if (chan == NULL) { - err = -EINVAL; - goto out; - } + if (chan == NULL) + return -EINVAL; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOMEM; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_REMAIN_ON_CHANNEL); @@ -4561,58 +4029,32 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + + return genlmsg_reply(msg, info); nla_put_failure: err = -ENOBUFS; free_msg: nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; u64 cookie; - int err; if (!info->attrs[NL80211_ATTR_COOKIE]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->cancel_remain_on_channel) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + if (!rdev->ops->cancel_remain_on_channel) + return -EOPNOTSUPP; cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); - err = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie); - - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; + return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie); } static u32 rateset_to_mask(struct ieee80211_supported_band *sband, @@ -4648,26 +4090,18 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, struct genl_info *info) { struct nlattr *tb[NL80211_TXRATE_MAX + 1]; - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct cfg80211_bitrate_mask mask; - int err, rem, i; - struct net_device *dev; + int rem, i; + struct net_device *dev = info->user_ptr[1]; struct nlattr *tx_rates; struct ieee80211_supported_band *sband; if (info->attrs[NL80211_ATTR_TX_RATES] == NULL) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->set_bitrate_mask) { - err = -EOPNOTSUPP; - goto unlock; - } + if (!rdev->ops->set_bitrate_mask) + return -EOPNOTSUPP; memset(&mask, 0, sizeof(mask)); /* Default to all rates enabled */ @@ -4684,15 +4118,11 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) { enum ieee80211_band band = nla_type(tx_rates); - if (band < 0 || band >= IEEE80211_NUM_BANDS) { - err = -EINVAL; - goto unlock; - } + if (band < 0 || band >= IEEE80211_NUM_BANDS) + return -EINVAL; sband = rdev->wiphy.bands[band]; - if (sband == NULL) { - err = -EINVAL; - goto unlock; - } + if (sband == NULL) + return -EINVAL; nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), nla_len(tx_rates), nl80211_txattr_policy); if (tb[NL80211_TXRATE_LEGACY]) { @@ -4700,68 +4130,48 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, sband, nla_data(tb[NL80211_TXRATE_LEGACY]), nla_len(tb[NL80211_TXRATE_LEGACY])); - if (mask.control[band].legacy == 0) { - err = -EINVAL; - goto unlock; - } + if (mask.control[band].legacy == 0) + return -EINVAL; } } - err = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask); - - unlock: - dev_put(dev); - cfg80211_unlock_rdev(rdev); - unlock_rtnl: - rtnl_unlock(); - return err; + return rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask); } -static int nl80211_register_action(struct sk_buff *skb, struct genl_info *info) +static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; - int err; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; + u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) return -EINVAL; - if (nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]) < 1) - return -EINVAL; - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; + if (info->attrs[NL80211_ATTR_FRAME_TYPE]) + frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { - err = -EOPNOTSUPP; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; /* not much point in registering if we can't reply */ - if (!rdev->ops->action) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->mgmt_tx) + return -EOPNOTSUPP; - err = cfg80211_mlme_register_action(dev->ieee80211_ptr, info->snd_pid, + return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid, + frame_type, nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - unlock_rtnl: - rtnl_unlock(); - return err; } -static int nl80211_action(struct sk_buff *skb, struct genl_info *info) +static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; - struct net_device *dev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; struct ieee80211_channel *chan; enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; bool channel_type_valid = false; @@ -4775,27 +4185,16 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info) !info->attrs[NL80211_ATTR_WIPHY_FREQ]) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - - if (!rdev->ops->action) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->mgmt_tx) + return -EOPNOTSUPP; if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) { - err = -EOPNOTSUPP; - goto out; - } - - if (!netif_running(dev)) { - err = -ENETDOWN; - goto out; - } + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { channel_type = nla_get_u32( @@ -4803,147 +4202,104 @@ static int nl80211_action(struct sk_buff *skb, struct genl_info *info) if (channel_type != NL80211_CHAN_NO_HT && channel_type != NL80211_CHAN_HT20 && channel_type != NL80211_CHAN_HT40PLUS && - channel_type != NL80211_CHAN_HT40MINUS) { - err = -EINVAL; - goto out; - } + channel_type != NL80211_CHAN_HT40MINUS) + return -EINVAL; channel_type_valid = true; } freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); chan = rdev_freq_to_chan(rdev, freq, channel_type); - if (chan == NULL) { - err = -EINVAL; - goto out; - } + if (chan == NULL) + return -EINVAL; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOMEM; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, - NL80211_CMD_ACTION); + NL80211_CMD_FRAME); if (IS_ERR(hdr)) { err = PTR_ERR(hdr); goto free_msg; } - err = cfg80211_mlme_action(rdev, dev, chan, channel_type, - channel_type_valid, - nla_data(info->attrs[NL80211_ATTR_FRAME]), - nla_len(info->attrs[NL80211_ATTR_FRAME]), - &cookie); + err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, channel_type, + channel_type_valid, + nla_data(info->attrs[NL80211_ATTR_FRAME]), + nla_len(info->attrs[NL80211_ATTR_FRAME]), + &cookie); if (err) goto free_msg; NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie); genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + return genlmsg_reply(msg, info); nla_put_failure: err = -ENOBUFS; free_msg: nlmsg_free(msg); - out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); -unlock_rtnl: - rtnl_unlock(); return err; } static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct wireless_dev *wdev; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; u8 ps_state; bool state; int err; - if (!info->attrs[NL80211_ATTR_PS_STATE]) { - err = -EINVAL; - goto out; - } + if (!info->attrs[NL80211_ATTR_PS_STATE]) + return -EINVAL; ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]); - if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) { - err = -EINVAL; - goto out; - } - - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rdev; + if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) + return -EINVAL; wdev = dev->ieee80211_ptr; - if (!rdev->ops->set_power_mgmt) { - err = -EOPNOTSUPP; - goto unlock_rdev; - } + if (!rdev->ops->set_power_mgmt) + return -EOPNOTSUPP; state = (ps_state == NL80211_PS_ENABLED) ? true : false; if (state == wdev->ps) - goto unlock_rdev; - - wdev->ps = state; - - if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, wdev->ps, - wdev->ps_timeout)) - /* assume this means it's off */ - wdev->ps = false; - -unlock_rdev: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - rtnl_unlock(); + return 0; -out: + err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, state, + wdev->ps_timeout); + if (!err) + wdev->ps = state; return err; } static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; enum nl80211_ps_state ps_state; struct wireless_dev *wdev; - struct net_device *dev; + struct net_device *dev = info->user_ptr[1]; struct sk_buff *msg; void *hdr; int err; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rtnl; - wdev = dev->ieee80211_ptr; - if (!rdev->ops->set_power_mgmt) { - err = -EOPNOTSUPP; - goto out; - } + if (!rdev->ops->set_power_mgmt) + return -EOPNOTSUPP; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); - if (!msg) { - err = -ENOMEM; - goto out; - } + if (!msg) + return -ENOMEM; hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0, NL80211_CMD_GET_POWER_SAVE); if (!hdr) { - err = -ENOMEM; + err = -ENOBUFS; goto free_msg; } @@ -4955,22 +4311,12 @@ static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); genlmsg_end(msg, hdr); - err = genlmsg_reply(msg, info); - goto out; + return genlmsg_reply(msg, info); -nla_put_failure: + nla_put_failure: err = -ENOBUFS; - -free_msg: + free_msg: nlmsg_free(msg); - -out: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - -unlock_rtnl: - rtnl_unlock(); - return err; } @@ -4984,41 +4330,24 @@ nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = { static int nl80211_set_cqm_rssi(struct genl_info *info, s32 threshold, u32 hysteresis) { - struct cfg80211_registered_device *rdev; + struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct wireless_dev *wdev; - struct net_device *dev; - int err; + struct net_device *dev = info->user_ptr[1]; if (threshold > 0) return -EINVAL; - rtnl_lock(); - - err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); - if (err) - goto unlock_rdev; - wdev = dev->ieee80211_ptr; - if (!rdev->ops->set_cqm_rssi_config) { - err = -EOPNOTSUPP; - goto unlock_rdev; - } - - if (wdev->iftype != NL80211_IFTYPE_STATION) { - err = -EOPNOTSUPP; - goto unlock_rdev; - } - - err = rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, - threshold, hysteresis); + if (!rdev->ops->set_cqm_rssi_config) + return -EOPNOTSUPP; -unlock_rdev: - cfg80211_unlock_rdev(rdev); - dev_put(dev); - rtnl_unlock(); + if (wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) + return -EOPNOTSUPP; - return err; + return rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev, + threshold, hysteresis); } static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) @@ -5052,6 +4381,65 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) return err; } +#define NL80211_FLAG_NEED_WIPHY 0x01 +#define NL80211_FLAG_NEED_NETDEV 0x02 +#define NL80211_FLAG_NEED_RTNL 0x04 +#define NL80211_FLAG_CHECK_NETDEV_UP 0x08 +#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ + NL80211_FLAG_CHECK_NETDEV_UP) + +static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info) +{ + struct cfg80211_registered_device *rdev; + struct net_device *dev; + int err; + bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL; + + if (rtnl) + rtnl_lock(); + + if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) { + rdev = cfg80211_get_dev_from_info(info); + if (IS_ERR(rdev)) { + if (rtnl) + rtnl_unlock(); + return PTR_ERR(rdev); + } + info->user_ptr[0] = rdev; + } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { + err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev); + if (err) { + if (rtnl) + rtnl_unlock(); + return err; + } + if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && + !netif_running(dev)) { + cfg80211_unlock_rdev(rdev); + dev_put(dev); + if (rtnl) + rtnl_unlock(); + return -ENETDOWN; + } + info->user_ptr[0] = rdev; + info->user_ptr[1] = dev; + } + + return 0; +} + +static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, + struct genl_info *info) +{ + if (info->user_ptr[0]) + cfg80211_unlock_rdev(info->user_ptr[0]); + if (info->user_ptr[1]) + dev_put(info->user_ptr[1]); + if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) + rtnl_unlock(); +} + static struct genl_ops nl80211_ops[] = { { .cmd = NL80211_CMD_GET_WIPHY, @@ -5059,12 +4447,14 @@ static struct genl_ops nl80211_ops[] = { .dumpit = nl80211_dump_wiphy, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_WIPHY, }, { .cmd = NL80211_CMD_SET_WIPHY, .doit = nl80211_set_wiphy, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_INTERFACE, @@ -5072,90 +4462,119 @@ static struct genl_ops nl80211_ops[] = { .dumpit = nl80211_dump_interface, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_NETDEV, }, { .cmd = NL80211_CMD_SET_INTERFACE, .doit = nl80211_set_interface, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_INTERFACE, .doit = nl80211_new_interface, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_INTERFACE, .doit = nl80211_del_interface, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_KEY, .doit = nl80211_get_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_KEY, .doit = nl80211_set_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_KEY, .doit = nl80211_new_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_KEY, .doit = nl80211_del_key, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_BEACON, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_addset_beacon, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_BEACON, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_addset_beacon, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_BEACON, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, .doit = nl80211_del_beacon, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_STATION, .doit = nl80211_get_station, .dumpit = nl80211_dump_station, .policy = nl80211_policy, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_STATION, .doit = nl80211_set_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_STATION, .doit = nl80211_new_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_STATION, .doit = nl80211_del_station, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_MPATH, @@ -5163,30 +4582,40 @@ static struct genl_ops nl80211_ops[] = { .dumpit = nl80211_dump_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_MPATH, .doit = nl80211_set_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_NEW_MPATH, .doit = nl80211_new_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_MPATH, .doit = nl80211_del_mpath, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_BSS, .doit = nl80211_set_bss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_REG, @@ -5211,18 +4640,24 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_get_mesh_params, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_MESH_PARAMS, .doit = nl80211_set_mesh_params, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_TRIGGER_SCAN, .doit = nl80211_trigger_scan, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_SCAN, @@ -5234,36 +4669,48 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_authenticate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_ASSOCIATE, .doit = nl80211_associate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEAUTHENTICATE, .doit = nl80211_deauthenticate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DISASSOCIATE, .doit = nl80211_disassociate, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_JOIN_IBSS, .doit = nl80211_join_ibss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_LEAVE_IBSS, .doit = nl80211_leave_ibss, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, #ifdef CONFIG_NL80211_TESTMODE { @@ -5271,6 +4718,8 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_testmode_do, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, }, #endif { @@ -5278,18 +4727,24 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_connect, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DISCONNECT, .doit = nl80211_disconnect, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_WIPHY_NETNS, .doit = nl80211_wiphy_netns, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_WIPHY | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_SURVEY, @@ -5301,72 +4756,104 @@ static struct genl_ops nl80211_ops[] = { .doit = nl80211_setdel_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_DEL_PMKSA, .doit = nl80211_setdel_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_FLUSH_PMKSA, .doit = nl80211_flush_pmksa, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_REMAIN_ON_CHANNEL, .doit = nl80211_remain_on_channel, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, .doit = nl80211_cancel_remain_on_channel, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_TX_BITRATE_MASK, .doit = nl80211_set_tx_bitrate_mask, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { - .cmd = NL80211_CMD_REGISTER_ACTION, - .doit = nl80211_register_action, + .cmd = NL80211_CMD_REGISTER_FRAME, + .doit = nl80211_register_mgmt, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { - .cmd = NL80211_CMD_ACTION, - .doit = nl80211_action, + .cmd = NL80211_CMD_FRAME, + .doit = nl80211_tx_mgmt, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_POWER_SAVE, .doit = nl80211_set_power_save, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_GET_POWER_SAVE, .doit = nl80211_get_power_save, .policy = nl80211_policy, /* can be retrieved by unprivileged users */ + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_CQM, .doit = nl80211_set_cqm, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, { .cmd = NL80211_CMD_SET_CHANNEL, .doit = nl80211_set_channel, .policy = nl80211_policy, .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, + }, + { + .cmd = NL80211_CMD_SET_WDS_PEER, + .doit = nl80211_set_wds_peer, + .policy = nl80211_policy, + .flags = GENL_ADMIN_PERM, + .internal_flags = NL80211_FLAG_NEED_NETDEV | + NL80211_FLAG_NEED_RTNL, }, }; @@ -6040,9 +5527,9 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, nl80211_mlme_mcgrp.id, gfp); } -int nl80211_send_action(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u32 nlpid, - int freq, const u8 *buf, size_t len, gfp_t gfp) +int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u32 nlpid, + int freq, const u8 *buf, size_t len, gfp_t gfp) { struct sk_buff *msg; void *hdr; @@ -6052,7 +5539,7 @@ int nl80211_send_action(struct cfg80211_registered_device *rdev, if (!msg) return -ENOMEM; - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ACTION); + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); if (!hdr) { nlmsg_free(msg); return -ENOMEM; @@ -6080,10 +5567,10 @@ int nl80211_send_action(struct cfg80211_registered_device *rdev, return -ENOBUFS; } -void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u64 cookie, - const u8 *buf, size_t len, bool ack, - gfp_t gfp) +void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u64 cookie, + const u8 *buf, size_t len, bool ack, + gfp_t gfp) { struct sk_buff *msg; void *hdr; @@ -6092,7 +5579,7 @@ void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev, if (!msg) return; - hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ACTION_TX_STATUS); + hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS); if (!hdr) { nlmsg_free(msg); return; @@ -6179,7 +5666,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb, list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) - cfg80211_mlme_unregister_actions(wdev, notify->pid); + cfg80211_mlme_unregister_socket(wdev, notify->pid); rcu_read_unlock(); diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 2ad7fbc7d9f1ad907d3ef7638cb3241c93c622d7..30d2f939150d78e3da6529e5e34f9685c96c4283 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h @@ -74,13 +74,13 @@ void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, struct net_device *dev, const u8 *mac_addr, struct station_info *sinfo, gfp_t gfp); -int nl80211_send_action(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u32 nlpid, int freq, - const u8 *buf, size_t len, gfp_t gfp); -void nl80211_send_action_tx_status(struct cfg80211_registered_device *rdev, - struct net_device *netdev, u64 cookie, - const u8 *buf, size_t len, bool ack, - gfp_t gfp); +int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u32 nlpid, int freq, + const u8 *buf, size_t len, gfp_t gfp); +void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, + struct net_device *netdev, u64 cookie, + const u8 *buf, size_t len, bool ack, + gfp_t gfp); void nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index 1332c445d1c78a6f41ba2e6aba13eaf8cade675f..dbe35e138e945f1bfc63aae4fdcb3a0c1e371b0b 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c @@ -14,6 +14,7 @@ * See COPYING for more details. */ +#include #include #include #include @@ -45,7 +46,7 @@ static const struct radiotap_align_size rtap_namespace_sizes[] = { }; static const struct ieee80211_radiotap_namespace radiotap_ns = { - .n_bits = sizeof(rtap_namespace_sizes) / sizeof(rtap_namespace_sizes[0]), + .n_bits = ARRAY_SIZE(rtap_namespace_sizes), .align_size = rtap_namespace_sizes, }; @@ -200,7 +201,7 @@ int ieee80211_radiotap_iterator_next( { while (1) { int hit = 0; - int pad, align, size, subns, vnslen; + int pad, align, size, subns; uint32_t oui; /* if no more EXT bits, that's it */ @@ -260,6 +261,27 @@ int ieee80211_radiotap_iterator_next( if (pad) iterator->_arg += align - pad; + if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) { + int vnslen; + + if ((unsigned long)iterator->_arg + size - + (unsigned long)iterator->_rtheader > + (unsigned long)iterator->_max_length) + return -EINVAL; + + oui = (*iterator->_arg << 16) | + (*(iterator->_arg + 1) << 8) | + *(iterator->_arg + 2); + subns = *(iterator->_arg + 3); + + find_ns(iterator, oui, subns); + + vnslen = get_unaligned_le16(iterator->_arg + 4); + iterator->_next_ns_data = iterator->_arg + size + vnslen; + if (!iterator->current_namespace) + size += vnslen; + } + /* * this is what we will return to user, but we need to * move on first so next call has something fresh to test @@ -286,40 +308,25 @@ int ieee80211_radiotap_iterator_next( /* these special ones are valid in each bitmap word */ switch (iterator->_arg_index % 32) { case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: - iterator->_bitmap_shifter >>= 1; - iterator->_arg_index++; - iterator->_reset_on_ext = 1; - vnslen = get_unaligned_le16(iterator->this_arg + 4); - iterator->_next_ns_data = iterator->_arg + vnslen; - oui = (*iterator->this_arg << 16) | - (*(iterator->this_arg + 1) << 8) | - *(iterator->this_arg + 2); - subns = *(iterator->this_arg + 3); - - find_ns(iterator, oui, subns); - iterator->is_radiotap_ns = 0; - /* allow parsers to show this information */ + /* + * If parser didn't register this vendor + * namespace with us, allow it to show it + * as 'raw. Do do that, set argument index + * to vendor namespace. + */ iterator->this_arg_index = IEEE80211_RADIOTAP_VENDOR_NAMESPACE; - iterator->this_arg_size += vnslen; - if ((unsigned long)iterator->this_arg + - iterator->this_arg_size - - (unsigned long)iterator->_rtheader > - (unsigned long)(unsigned long)iterator->_max_length) - return -EINVAL; - hit = 1; - break; + if (!iterator->current_namespace) + hit = 1; + goto next_entry; case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: - iterator->_bitmap_shifter >>= 1; - iterator->_arg_index++; - iterator->_reset_on_ext = 1; iterator->current_namespace = &radiotap_ns; iterator->is_radiotap_ns = 1; - break; + goto next_entry; case IEEE80211_RADIOTAP_EXT: /* * bit 31 was set, there is more diff --git a/net/wireless/reg.c b/net/wireless/reg.c index f180db0de66cbc2163ce3dab641b46cb647226d2..d14bbf960c18223a5305b4b1cd33cd68ce49be76 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -73,7 +74,11 @@ const struct ieee80211_regdomain *cfg80211_regdomain; * - last_request */ static DEFINE_MUTEX(reg_mutex); -#define assert_reg_lock() WARN_ON(!mutex_is_locked(®_mutex)) + +static inline void assert_reg_lock(void) +{ + lockdep_assert_held(®_mutex); +} /* Used to queue up regulatory hints */ static LIST_HEAD(reg_requests_list); @@ -181,14 +186,6 @@ static bool is_alpha2_set(const char *alpha2) return false; } -static bool is_alpha_upper(char letter) -{ - /* ASCII A - Z */ - if (letter >= 65 && letter <= 90) - return true; - return false; -} - static bool is_unknown_alpha2(const char *alpha2) { if (!alpha2) @@ -220,7 +217,7 @@ static bool is_an_alpha2(const char *alpha2) { if (!alpha2) return false; - if (is_alpha_upper(alpha2[0]) && is_alpha_upper(alpha2[1])) + if (isalpha(alpha2[0]) && isalpha(alpha2[1])) return true; return false; } @@ -1399,6 +1396,11 @@ static DECLARE_WORK(reg_work, reg_todo); static void queue_regulatory_request(struct regulatory_request *request) { + if (isalpha(request->alpha2[0])) + request->alpha2[0] = toupper(request->alpha2[0]); + if (isalpha(request->alpha2[1])) + request->alpha2[1] = toupper(request->alpha2[1]); + spin_lock(®_requests_lock); list_add_tail(&request->list, ®_requests_list); spin_unlock(®_requests_lock); diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 5ca8c7180141d8dc9bc43d607eb26395cd0268bf..503ebb86ba1836f5d2c8709c75bae5eff83c5de6 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -650,14 +650,14 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub) bss = container_of(pub, struct cfg80211_internal_bss, pub); spin_lock_bh(&dev->bss_lock); + if (!list_empty(&bss->list)) { + list_del_init(&bss->list); + dev->bss_generation++; + rb_erase(&bss->rbn, &dev->bss_tree); - list_del(&bss->list); - dev->bss_generation++; - rb_erase(&bss->rbn, &dev->bss_tree); - + kref_put(&bss->ref, bss_release); + } spin_unlock_bh(&dev->bss_lock); - - kref_put(&bss->ref, bss_release); } EXPORT_SYMBOL(cfg80211_unlink_bss); diff --git a/net/wireless/sme.c b/net/wireless/sme.c index a8c2d6b877aeda894cb80328d015bc3494e000c9..e17b0bee6bdc7b8e0b6d74a401ea9df3bdf7e977 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -411,7 +411,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTING) @@ -548,7 +549,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTED) @@ -644,7 +646,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, ASSERT_WDEV_LOCK(wdev); - if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && + wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) return; if (wdev->sme_state != CFG80211_SME_CONNECTED) @@ -695,7 +698,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) - rdev->ops->del_key(wdev->wiphy, dev, i, NULL); + rdev->ops->del_key(wdev->wiphy, dev, i, false, NULL); #ifdef CONFIG_CFG80211_WEXT memset(&wrqu, 0, sizeof(wrqu)); diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 9f2cef3e0ca0cd21640127a27fd72edba88434a5..4294fa22bb2dfc15cbd6d0d2e7c0303a42f7d278 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c @@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx); SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); +static ssize_t name_show(struct device *dev, + struct device_attribute *attr, + char *buf) { + struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy; + return sprintf(buf, "%s\n", dev_name(&wiphy->dev)); +} + + static ssize_t addresses_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = { __ATTR_RO(macaddress), __ATTR_RO(address_mask), __ATTR_RO(addresses), + __ATTR_RO(name), {} }; @@ -110,6 +119,13 @@ static int wiphy_resume(struct device *dev) return ret; } +static const void *wiphy_namespace(struct device *d) +{ + struct wiphy *wiphy = container_of(d, struct wiphy, dev); + + return wiphy_net(wiphy); +} + struct class ieee80211_class = { .name = "ieee80211", .owner = THIS_MODULE, @@ -120,6 +136,8 @@ struct class ieee80211_class = { #endif .suspend = wiphy_suspend, .resume = wiphy_resume, + .ns_type = &net_ns_type_operations, + .namespace = wiphy_namespace, }; int wiphy_sysfs_init(void) diff --git a/net/wireless/util.c b/net/wireless/util.c index 0c8a1e8b76903313ef0c413cc36261ec8af9399b..76120aeda57d3ed311c338cb7e54196000cc937d 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -144,19 +144,25 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy) int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, struct key_params *params, int key_idx, - const u8 *mac_addr) + bool pairwise, const u8 *mac_addr) { int i; if (key_idx > 5) return -EINVAL; + if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + return -EINVAL; + + if (pairwise && !mac_addr) + return -EINVAL; + /* * Disallow pairwise keys with non-zero index unless it's WEP * (because current deployments use pairwise WEP keys with * non-zero indizes but 802.11i clearly specifies to use zero) */ - if (mac_addr && key_idx && + if (pairwise && key_idx && params->cipher != WLAN_CIPHER_SUITE_WEP40 && params->cipher != WLAN_CIPHER_SUITE_WEP104) return -EINVAL; @@ -183,7 +189,14 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, return -EINVAL; break; default: - return -EINVAL; + /* + * We don't know anything about this algorithm, + * allow using it -- but the driver must check + * all parameters! We still check below whether + * or not the driver supports this algorithm, + * of course. + */ + break; } if (params->seq) { @@ -221,7 +234,7 @@ const unsigned char bridge_tunnel_header[] __aligned(2) = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; EXPORT_SYMBOL(bridge_tunnel_header); -unsigned int ieee80211_hdrlen(__le16 fc) +unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc) { unsigned int hdrlen = 24; @@ -319,7 +332,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { case cpu_to_le16(IEEE80211_FCTL_TODS): if (unlikely(iftype != NL80211_IFTYPE_AP && - iftype != NL80211_IFTYPE_AP_VLAN)) + iftype != NL80211_IFTYPE_AP_VLAN && + iftype != NL80211_IFTYPE_P2P_GO)) return -1; break; case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): @@ -347,7 +361,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, break; case cpu_to_le16(IEEE80211_FCTL_FROMDS): if ((iftype != NL80211_IFTYPE_STATION && - iftype != NL80211_IFTYPE_MESH_POINT) || + iftype != NL80211_IFTYPE_P2P_CLIENT && + iftype != NL80211_IFTYPE_MESH_POINT) || (is_multicast_ether_addr(dst) && !compare_ether_addr(src, addr))) return -1; @@ -424,6 +439,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, switch (iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_P2P_GO: fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); /* DA BSSID SA */ memcpy(hdr.addr1, skb->data, ETH_ALEN); @@ -432,6 +448,7 @@ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, hdrlen = 24; break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: fc |= cpu_to_le16(IEEE80211_FCTL_TODS); /* BSSID SA DA */ memcpy(hdr.addr1, bssid, ETH_ALEN); @@ -666,7 +683,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) for (i = 0; i < 6; i++) { if (!wdev->connect_keys->params[i].cipher) continue; - if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL, + if (rdev->ops->add_key(wdev->wiphy, dev, i, false, NULL, &wdev->connect_keys->params[i])) { printk(KERN_ERR "%s: failed to set key %d\n", dev->name, i); @@ -771,7 +788,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, /* if it's part of a bridge, reject changing type to station/ibss */ if ((dev->priv_flags & IFF_BRIDGE_PORT) && - (ntype == NL80211_IFTYPE_ADHOC || ntype == NL80211_IFTYPE_STATION)) + (ntype == NL80211_IFTYPE_ADHOC || + ntype == NL80211_IFTYPE_STATION || + ntype == NL80211_IFTYPE_P2P_CLIENT)) return -EBUSY; if (ntype != otype) { @@ -782,6 +801,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, cfg80211_leave_ibss(rdev, dev, false); break; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: cfg80211_disconnect(rdev, dev, WLAN_REASON_DEAUTH_LEAVING, true); break; @@ -810,9 +830,11 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, if (dev->ieee80211_ptr->use_4addr) break; /* fall through */ + case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_ADHOC: dev->priv_flags |= IFF_DONT_BRIDGE; break; + case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_WDS: @@ -823,7 +845,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, /* monitor can't bridge anyway */ break; case NL80211_IFTYPE_UNSPECIFIED: - case __NL80211_IFTYPE_AFTER_LAST: + case NUM_NL80211_IFTYPES: /* not happening */ break; } diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 7e5c3a45f811d1a951ebee2486cfd8ffa70e5482..12222ee6ebf2f3a5e6a7c1f7782e4979a95b227e 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -432,14 +432,17 @@ int cfg80211_wext_giwretry(struct net_device *dev, EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, - struct net_device *dev, const u8 *addr, - bool remove, bool tx_key, int idx, - struct key_params *params) + struct net_device *dev, bool pairwise, + const u8 *addr, bool remove, bool tx_key, + int idx, struct key_params *params) { struct wireless_dev *wdev = dev->ieee80211_ptr; int err, i; bool rejoin = false; + if (pairwise && !addr) + return -EINVAL; + if (!wdev->wext.keys) { wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), GFP_KERNEL); @@ -478,7 +481,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, __cfg80211_leave_ibss(rdev, wdev->netdev, true); rejoin = true; } - err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); + + if (!pairwise && addr && + !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) + err = -ENOENT; + else + err = rdev->ops->del_key(&rdev->wiphy, dev, idx, + pairwise, addr); } wdev->wext.connect.privacy = false; /* @@ -507,12 +516,13 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, if (addr) tx_key = false; - if (cfg80211_validate_key_settings(rdev, params, idx, addr)) + if (cfg80211_validate_key_settings(rdev, params, idx, pairwise, addr)) return -EINVAL; err = 0; if (wdev->current_bss) - err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params); + err = rdev->ops->add_key(&rdev->wiphy, dev, idx, + pairwise, addr, params); if (err) return err; @@ -563,17 +573,17 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, } static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, - struct net_device *dev, const u8 *addr, - bool remove, bool tx_key, int idx, - struct key_params *params) + struct net_device *dev, bool pairwise, + const u8 *addr, bool remove, bool tx_key, + int idx, struct key_params *params) { int err; /* devlist mutex needed for possible IBSS re-join */ mutex_lock(&rdev->devlist_mtx); wdev_lock(dev->ieee80211_ptr); - err = __cfg80211_set_encryption(rdev, dev, addr, remove, - tx_key, idx, params); + err = __cfg80211_set_encryption(rdev, dev, pairwise, addr, + remove, tx_key, idx, params); wdev_unlock(dev->ieee80211_ptr); mutex_unlock(&rdev->devlist_mtx); @@ -635,7 +645,7 @@ int cfg80211_wext_siwencode(struct net_device *dev, else if (!remove) return -EINVAL; - return cfg80211_set_encryption(rdev, dev, NULL, remove, + return cfg80211_set_encryption(rdev, dev, false, NULL, remove, wdev->wext.default_key == -1, idx, ¶ms); } @@ -725,7 +735,9 @@ int cfg80211_wext_siwencodeext(struct net_device *dev, } return cfg80211_set_encryption( - rdev, dev, addr, remove, + rdev, dev, + !(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY), + addr, remove, ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, idx, ¶ms); } @@ -1354,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) } wstats.qual.updated |= IW_QUAL_NOISE_INVALID; + if (sinfo.filled & STATION_INFO_RX_DROP_MISC) + wstats.discard.misc = sinfo.rx_dropped_misc; + if (sinfo.filled & STATION_INFO_TX_FAILED) + wstats.discard.retries = sinfo.tx_failed; return &wstats; } diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c index 8f5116f5af19988555316eb5b97c7465a0890677..dc675a3daa3de94953fab7c388582b66a921fb85 100644 --- a/net/wireless/wext-core.c +++ b/net/wireless/wext-core.c @@ -611,7 +611,7 @@ struct iw_statistics *get_wireless_stats(struct net_device *dev) #endif #ifdef CONFIG_CFG80211_WEXT - if (dev->ieee80211_ptr && dev->ieee80211_ptr && + if (dev->ieee80211_ptr && dev->ieee80211_ptr->wiphy && dev->ieee80211_ptr->wiphy->wext && dev->ieee80211_ptr->wiphy->wext->get_wireless_stats) diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index 9818198add8a21444ba9183bbb8e4fc2c2199491..6fffe62d7c25b27cc9c6d6bc58635aa91f333e9f 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c @@ -197,6 +197,8 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev, wdev->wext.connect.ssid_len = len; wdev->wext.connect.crypto.control_port = false; + wdev->wext.connect.crypto.control_port_ethertype = + cpu_to_be16(ETH_P_PAE); err = cfg80211_mgd_wext_connect(rdev, wdev); out: diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index 5e86d4e97dceb29f89ae779554b51b3f336705ef..f7af98dff40954705df9a195382435496228df97 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -507,14 +507,14 @@ static int x25_listen(struct socket *sock, int backlog) struct sock *sk = sock->sk; int rc = -EOPNOTSUPP; - lock_kernel(); + lock_sock(sk); if (sk->sk_state != TCP_LISTEN) { memset(&x25_sk(sk)->dest_addr, 0, X25_ADDR_LEN); sk->sk_max_ack_backlog = backlog; sk->sk_state = TCP_LISTEN; rc = 0; } - unlock_kernel(); + release_sock(sk); return rc; } @@ -688,7 +688,6 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) struct sockaddr_x25 *addr = (struct sockaddr_x25 *)uaddr; int len, i, rc = 0; - lock_kernel(); if (!sock_flag(sk, SOCK_ZAPPED) || addr_len != sizeof(struct sockaddr_x25) || addr->sx25_family != AF_X25) { @@ -704,12 +703,13 @@ static int x25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) } } + lock_sock(sk); x25_sk(sk)->source_addr = addr->sx25_addr; x25_insert_socket(sk); sock_reset_flag(sk, SOCK_ZAPPED); + release_sock(sk); SOCK_DEBUG(sk, "x25_bind: socket is bound\n"); out: - unlock_kernel(); return rc; } @@ -751,7 +751,6 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, struct x25_route *rt; int rc = 0; - lock_kernel(); lock_sock(sk); if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { sock->state = SS_CONNECTED; @@ -829,7 +828,6 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, x25_route_put(rt); out: release_sock(sk); - unlock_kernel(); return rc; } @@ -869,8 +867,7 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) struct sk_buff *skb; int rc = -EINVAL; - lock_kernel(); - if (!sk || sk->sk_state != TCP_LISTEN) + if (!sk) goto out; rc = -EOPNOTSUPP; @@ -878,6 +875,10 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) goto out; lock_sock(sk); + rc = -EINVAL; + if (sk->sk_state != TCP_LISTEN) + goto out2; + rc = x25_wait_for_data(sk, sk->sk_rcvtimeo); if (rc) goto out2; @@ -897,7 +898,6 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) out2: release_sock(sk); out: - unlock_kernel(); return rc; } @@ -909,7 +909,6 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, struct x25_sock *x25 = x25_sk(sk); int rc = 0; - lock_kernel(); if (peer) { if (sk->sk_state != TCP_ESTABLISHED) { rc = -ENOTCONN; @@ -923,19 +922,6 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, *uaddr_len = sizeof(*sx25); out: - unlock_kernel(); - return rc; -} - -static unsigned int x25_datagram_poll(struct file *file, struct socket *sock, - poll_table *wait) -{ - int rc; - - lock_kernel(); - rc = datagram_poll(file, sock, wait); - unlock_kernel(); - return rc; } @@ -1746,7 +1732,7 @@ static const struct proto_ops x25_proto_ops = { .socketpair = sock_no_socketpair, .accept = x25_accept, .getname = x25_getname, - .poll = x25_datagram_poll, + .poll = datagram_poll, .ioctl = x25_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_x25_ioctl, diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cbab6e1a8c9c4043fcfdba5bdc17c5e9d5dea45c..044e77898512b43d772f43659388aee51db19012 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -50,6 +50,9 @@ static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); static void xfrm_init_pmtu(struct dst_entry *dst); static int stale_bundle(struct dst_entry *dst); +static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, + struct flowi *fl, int family, int strict); + static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, int dir); @@ -2276,7 +2279,7 @@ static void xfrm_init_pmtu(struct dst_entry *dst) * still valid. */ -int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, +static int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, struct flowi *fl, int family, int strict) { struct dst_entry *dst = &first->u.dst; @@ -2358,8 +2361,6 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, return 1; } -EXPORT_SYMBOL(xfrm_bundle_ok); - int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) { struct net *net;